From ea3e4acd418d6828d2b457c9e342da7fdcb33bb8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 27 Jul 2002 12:56:33 +0000 Subject: [PATCH 0001/4131] Standard project directories initialized by cvs2svn. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@78 From 7d1ca9bdd4255c1d7957426bddea565639b8add0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 27 Jul 2002 12:56:33 +0000 Subject: [PATCH 0002/4131] First file woohoo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@79 --- autogen.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100755 autogen.sh diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 00000000..1c139b8d --- /dev/null +++ b/autogen.sh @@ -0,0 +1,18 @@ +#!/bin/sh +# +echo "Generating build information using aclocal, auotheader, automake and autoconf" +echo "This may take a while ..." + +# Touch the timestamps on all the files since CVS messes them up +directory=`dirname $0` +touch $directory/configure.in + +# Regenerate configuration files + +aclocal +autoheader +automake --gnits --include-deps --add-missing --copy +autoconf + +cp $directory/settings.h.cvs $directory/settings.h +echo "Now you are ready to run ./configure also check settings.h for extra build settings" From 42e5d0b7792a3c911ed46a7a883a33e148d55105 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 27 Jul 2002 13:08:48 +0000 Subject: [PATCH 0003/4131] First CVS upload. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@80 --- AUTHORS | 8 + COPYING | 340 ++ ChangeLog | 3 + INSTALL | 36 + Makefile.am | 7 + NEWS | 23 + README | 93 + THANKS | 8 + VERSION | 1 + acinclude.m4 | 161 + config.guess | 1368 +++++ configure.in | 61 + include/Makefile.am | 29 + include/bios.h | 120 + include/callback.h | 56 + include/cpu.h | 99 + include/cross.h | 54 + include/debug.h | 24 + include/dma.h | 24 + include/dos_inc.h | 275 + include/dos_system.h | 105 + include/dosbox.h | 63 + include/fpu.h | 1 + include/hardware.h | 44 + include/inout.h | 48 + include/joystick.h | 25 + include/keyboard.h | 54 + include/mem.h | 206 + include/mixer.h | 42 + include/modules.h | 180 + include/mouse.h | 28 + include/pic.h | 44 + include/programs.h | 58 + include/regs.h | 114 + include/render.h | 25 + include/setup.h | 43 + include/support.h | 63 + include/timer.h | 53 + include/video.h | 50 + scripts/ega-switch.pl | 32 + scripts/font-switch.pl | 25 + settings.h.cvs | 26 + src/Makefile.am | 10 + src/cpu/Makefile.am | 5 + src/cpu/callback.cpp | 171 + src/cpu/core_16/Makefile.am | 3 + src/cpu/core_16/helpers.h | 76 + src/cpu/core_16/instructions.h | 593 ++ src/cpu/core_16/main.h | 1488 +++++ src/cpu/core_16/prefix_66.h | 469 ++ src/cpu/core_16/prefix_66_of.h | 124 + src/cpu/core_16/prefix_of.h | 188 + src/cpu/core_16/start.h | 20 + src/cpu/core_16/stop.h | 19 + src/cpu/core_16/support.h | 191 + src/cpu/core_16/table_ea.h | 283 + src/cpu/cpu.cpp | 185 + src/cpu/flags.cpp | 582 ++ src/cpu/modrm.cpp | 210 + src/cpu/modrm.h | 76 + src/cpu/slow_16.cpp | 120 + src/debug/Makefile.am | 5 + src/debug/debug.cpp | 257 + src/debug/debug_disasm.cpp | 1112 ++++ src/debug/debug_gui.cpp | 130 + src/debug/debug_inc.h | 52 + src/debug/debug_win32.cpp | 74 + src/debug/disasm_tables.h | 191 + src/dos/Makefile.am | 7 + src/dos/dev_con.h | 105 + src/dos/dos.cpp | 790 +++ src/dos/dos_classes.cpp | 181 + src/dos/dos_devices.cpp | 77 + src/dos/dos_execute.cpp | 439 ++ src/dos/dos_files.cpp | 614 ++ src/dos/dos_ioctl.cpp | 60 + src/dos/dos_memory.cpp | 162 + src/dos/dos_misc.cpp | 69 + src/dos/dos_programs.cpp | 210 + src/dos/dos_tables.cpp | 54 + src/dos/drive_local.cpp | 277 + src/dos/drive_virtual.cpp | 205 + src/dos/drives.cpp | 31 + src/dos/drives.h | 71 + src/dosbox.cpp | 297 + src/dosbox.lang | 75 + src/fpu/Makefile.am | 4 + src/fpu/fpu.cpp | 62 + src/fpu/fpu_load.h | 21 + src/gui/Makefile.am | 5 + src/gui/render.cpp | 160 + src/gui/sdlmain.cpp | 513 ++ src/hardware/Makefile.am | 11 + src/hardware/adlib.cpp | 224 + src/hardware/dma.cpp | 225 + src/hardware/ega-switch.h | 9730 ++++++++++++++++++++++++++++++ src/hardware/fmopl.c | 1878 ++++++ src/hardware/fmopl.h | 191 + src/hardware/font-switch.h | 2562 ++++++++ src/hardware/gameblaster.cpp | 256 + src/hardware/hardware.cpp | 117 + src/hardware/iohandler.cpp | 91 + src/hardware/joystick.cpp | 101 + src/hardware/keyboard.cpp | 260 + src/hardware/memory.cpp | 299 + src/hardware/mixer.cpp | 254 + src/hardware/pcspeaker.cpp | 88 + src/hardware/pic.cpp | 369 ++ src/hardware/sblaster.cpp | 613 ++ src/hardware/tandy_sound.cpp | 143 + src/hardware/timer.cpp | 300 + src/hardware/vga.cpp | 165 + src/hardware/vga.h | 255 + src/hardware/vga_attr.cpp | 165 + src/hardware/vga_crtc.cpp | 332 + src/hardware/vga_dac.cpp | 160 + src/hardware/vga_draw.cpp | 165 + src/hardware/vga_fonts.cpp | 1254 ++++ src/hardware/vga_gfx.cpp | 221 + src/hardware/vga_memory.cpp | 214 + src/hardware/vga_misc.cpp | 70 + src/hardware/vga_seq.cpp | 125 + src/ints/Makefile.am | 6 + src/ints/bios.cpp | 235 + src/ints/bios_disk.cpp | 95 + src/ints/bios_keyboard.cpp | 381 ++ src/ints/ems.cpp | 165 + src/ints/int10.cpp | 278 + src/ints/int10.h | 205 + src/ints/int10_char.cpp | 394 ++ src/ints/int10_memory.cpp | 1302 ++++ src/ints/int10_misc.cpp | 135 + src/ints/int10_modes.cpp | 403 ++ src/ints/int10_pal.cpp | 126 + src/ints/int10_put_pixel.cpp | 91 + src/ints/mouse.cpp | 294 + src/ints/xms.cpp | 185 + src/misc/Makefile.am | 4 + src/misc/messages.cpp | 107 + src/misc/plugins.cpp | 159 + src/misc/programs.cpp | 174 + src/misc/setup.cpp | 29 + src/misc/support.cpp | 224 + src/platform/Makefile.am | 1 + src/platform/visualc/Makefile.am | 1 + src/platform/visualc/config.h | 5 + src/platform/visualc/dirent.c | 93 + src/platform/visualc/dirent.h | 58 + src/platform/visualc/unistd.h | 10 + src/shell/Makefile.am | 4 + src/shell/shell.cpp | 177 + src/shell/shell_batch.cpp | 124 + src/shell/shell_cmds.cpp | 380 ++ src/shell/shell_inc.h | 102 + src/shell/shell_misc.cpp | 248 + visualc/Makefile.am | 1 + visualc/dosbox.dsp | 635 ++ visualc/dosbox.dsw | 29 + 158 files changed, 42940 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100644 THANKS create mode 100644 VERSION create mode 100644 acinclude.m4 create mode 100644 config.guess create mode 100644 configure.in create mode 100644 include/Makefile.am create mode 100644 include/bios.h create mode 100644 include/callback.h create mode 100644 include/cpu.h create mode 100644 include/cross.h create mode 100644 include/debug.h create mode 100644 include/dma.h create mode 100644 include/dos_inc.h create mode 100644 include/dos_system.h create mode 100644 include/dosbox.h create mode 100644 include/fpu.h create mode 100644 include/hardware.h create mode 100644 include/inout.h create mode 100644 include/joystick.h create mode 100644 include/keyboard.h create mode 100644 include/mem.h create mode 100644 include/mixer.h create mode 100644 include/modules.h create mode 100644 include/mouse.h create mode 100644 include/pic.h create mode 100644 include/programs.h create mode 100644 include/regs.h create mode 100644 include/render.h create mode 100644 include/setup.h create mode 100644 include/support.h create mode 100644 include/timer.h create mode 100644 include/video.h create mode 100644 scripts/ega-switch.pl create mode 100644 scripts/font-switch.pl create mode 100644 settings.h.cvs create mode 100644 src/Makefile.am create mode 100644 src/cpu/Makefile.am create mode 100644 src/cpu/callback.cpp create mode 100644 src/cpu/core_16/Makefile.am create mode 100644 src/cpu/core_16/helpers.h create mode 100644 src/cpu/core_16/instructions.h create mode 100644 src/cpu/core_16/main.h create mode 100644 src/cpu/core_16/prefix_66.h create mode 100644 src/cpu/core_16/prefix_66_of.h create mode 100644 src/cpu/core_16/prefix_of.h create mode 100644 src/cpu/core_16/start.h create mode 100644 src/cpu/core_16/stop.h create mode 100644 src/cpu/core_16/support.h create mode 100644 src/cpu/core_16/table_ea.h create mode 100644 src/cpu/cpu.cpp create mode 100644 src/cpu/flags.cpp create mode 100644 src/cpu/modrm.cpp create mode 100644 src/cpu/modrm.h create mode 100644 src/cpu/slow_16.cpp create mode 100644 src/debug/Makefile.am create mode 100644 src/debug/debug.cpp create mode 100644 src/debug/debug_disasm.cpp create mode 100644 src/debug/debug_gui.cpp create mode 100644 src/debug/debug_inc.h create mode 100644 src/debug/debug_win32.cpp create mode 100644 src/debug/disasm_tables.h create mode 100644 src/dos/Makefile.am create mode 100644 src/dos/dev_con.h create mode 100644 src/dos/dos.cpp create mode 100644 src/dos/dos_classes.cpp create mode 100644 src/dos/dos_devices.cpp create mode 100644 src/dos/dos_execute.cpp create mode 100644 src/dos/dos_files.cpp create mode 100644 src/dos/dos_ioctl.cpp create mode 100644 src/dos/dos_memory.cpp create mode 100644 src/dos/dos_misc.cpp create mode 100644 src/dos/dos_programs.cpp create mode 100644 src/dos/dos_tables.cpp create mode 100644 src/dos/drive_local.cpp create mode 100644 src/dos/drive_virtual.cpp create mode 100644 src/dos/drives.cpp create mode 100644 src/dos/drives.h create mode 100644 src/dosbox.cpp create mode 100644 src/dosbox.lang create mode 100644 src/fpu/Makefile.am create mode 100644 src/fpu/fpu.cpp create mode 100644 src/fpu/fpu_load.h create mode 100644 src/gui/Makefile.am create mode 100644 src/gui/render.cpp create mode 100644 src/gui/sdlmain.cpp create mode 100644 src/hardware/Makefile.am create mode 100644 src/hardware/adlib.cpp create mode 100644 src/hardware/dma.cpp create mode 100644 src/hardware/ega-switch.h create mode 100644 src/hardware/fmopl.c create mode 100644 src/hardware/fmopl.h create mode 100644 src/hardware/font-switch.h create mode 100644 src/hardware/gameblaster.cpp create mode 100644 src/hardware/hardware.cpp create mode 100644 src/hardware/iohandler.cpp create mode 100644 src/hardware/joystick.cpp create mode 100644 src/hardware/keyboard.cpp create mode 100644 src/hardware/memory.cpp create mode 100644 src/hardware/mixer.cpp create mode 100644 src/hardware/pcspeaker.cpp create mode 100644 src/hardware/pic.cpp create mode 100644 src/hardware/sblaster.cpp create mode 100644 src/hardware/tandy_sound.cpp create mode 100644 src/hardware/timer.cpp create mode 100644 src/hardware/vga.cpp create mode 100644 src/hardware/vga.h create mode 100644 src/hardware/vga_attr.cpp create mode 100644 src/hardware/vga_crtc.cpp create mode 100644 src/hardware/vga_dac.cpp create mode 100644 src/hardware/vga_draw.cpp create mode 100644 src/hardware/vga_fonts.cpp create mode 100644 src/hardware/vga_gfx.cpp create mode 100644 src/hardware/vga_memory.cpp create mode 100644 src/hardware/vga_misc.cpp create mode 100644 src/hardware/vga_seq.cpp create mode 100644 src/ints/Makefile.am create mode 100644 src/ints/bios.cpp create mode 100644 src/ints/bios_disk.cpp create mode 100644 src/ints/bios_keyboard.cpp create mode 100644 src/ints/ems.cpp create mode 100644 src/ints/int10.cpp create mode 100644 src/ints/int10.h create mode 100644 src/ints/int10_char.cpp create mode 100644 src/ints/int10_memory.cpp create mode 100644 src/ints/int10_misc.cpp create mode 100644 src/ints/int10_modes.cpp create mode 100644 src/ints/int10_pal.cpp create mode 100644 src/ints/int10_put_pixel.cpp create mode 100644 src/ints/mouse.cpp create mode 100644 src/ints/xms.cpp create mode 100644 src/misc/Makefile.am create mode 100644 src/misc/messages.cpp create mode 100644 src/misc/plugins.cpp create mode 100644 src/misc/programs.cpp create mode 100644 src/misc/setup.cpp create mode 100644 src/misc/support.cpp create mode 100644 src/platform/Makefile.am create mode 100644 src/platform/visualc/Makefile.am create mode 100644 src/platform/visualc/config.h create mode 100644 src/platform/visualc/dirent.c create mode 100644 src/platform/visualc/dirent.h create mode 100644 src/platform/visualc/unistd.h create mode 100644 src/shell/Makefile.am create mode 100644 src/shell/shell.cpp create mode 100644 src/shell/shell_batch.cpp create mode 100644 src/shell/shell_cmds.cpp create mode 100644 src/shell/shell_inc.h create mode 100644 src/shell/shell_misc.cpp create mode 100644 visualc/Makefile.am create mode 100644 visualc/dosbox.dsp create mode 100644 visualc/dosbox.dsw diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..9873d586 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,8 @@ +The DOSBox Team +--------------- + +Sjoerd v.d. Berg +Peter Veenstra + + + diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..d60c31a9 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 00000000..051d4d61 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,3 @@ + - fixed the errors/warnings in prefix_66.h and prefix_66_of.h (decimal too large becomming unsigned). + + diff --git a/INSTALL b/INSTALL new file mode 100644 index 00000000..ad94ba93 --- /dev/null +++ b/INSTALL @@ -0,0 +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. + +SDL + The Simple DirectMedia Library available at http://www.libsdl.org + +Curses + If you want to enable the debugger you need a curses library. + ncurses should be installed on just about every unix distro. + For win32 get pdcurses at http://pdcurses.sourceforge.net + +If you want compile from the CVS under a unix system, you'll also need +automake, autoconf. Should be available at http://www.gnu.org + +For building on unix systems. +If you are building from the cvs run ./autogen.sh first before doing the following. + +1. ./configure +2. Check settings.h for some setup options. +3. make + +Check the src subdir for the binary and dosbox.lang file. +These 2 files should be in the same dir if you want to run dosbox. + +Compiling on FreeBSD might be a problem since SDL has no joystick support there. +To get around this edit sdlmain.cpp to enable some #define. +Let's hope someday the sdl people will just report 0 joysticks in freebsd or get it working some other way :) + + +Build instructions for VC++6 + +Open the workspace in the visualc subdir and build from there. +Copy the src/dosbox.lang file to the same dir as your executable. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..2a945916 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,7 @@ +# Main Makefile for DOSBox + +EXTRA_DIST = settings.h autogen.sh +SUBDIRS = src include visualc + + + diff --git a/NEWS b/NEWS new file mode 100644 index 00000000..ba304e25 --- /dev/null +++ b/NEWS @@ -0,0 +1,23 @@ +0.50: + -added F3 to repeat the last typed command. + -made it possible to change the shellmessages(dosshell). so + you can costumize it.(dosbox.lang) + -changed cpu core. + -Fixed a lot of errors with the keyboard: shift-f1 and + alt-f1 now works. + -Fixed some division errors. + -made a plugin system. + -added a lot of real 386 mode instructions. + -made it possible to resize the screen. + -Mayor source cleanup/reorganisation. + -Complete rewrite of the graphics routines. Should make it + possible to implement more fancy things like 2xsai,interpolation. + -changed the sound playback. + -Changed the vga drawing to only draw on memory changes, instead + of drawing an entire frame. + -fixes to the soundblaster/dma code should be able to play 4-bit + adpcm compressed sounds. + -added the correct time to dir. + -bugfixes to batch-file handling. + -Lot's of small bugfixes.(Dune1&2,wolf3d, many more). + -Released the source. \ No newline at end of file diff --git a/README b/README new file mode 100644 index 00000000..a3dd79ac --- /dev/null +++ b/README @@ -0,0 +1,93 @@ +DOSBox v0.50 + +Usage: +====== + +With the new internal shell I've changed the command line a bit, so let's just give some +examples of what you can do now. +dosbox + With nothing on the command line you'll end up on the internal drive and from there you + can mount directories as drives. +dosbox [filename/directory] + If dosbox detects a directory it'll mount that as c:\ and then start the shell. + If dosbox doesn't detect a directory it'll assume you mean an executable this can be + .bat .com .exe. Doesn't need to have extension included. Then it'll strip the directory + from the filename and mount that as c:\ and then run the file. + +You can also add commands to be executed before the main program starts. Or you can use them +to start the program. +To add commands use the -c command line switch. +For example +dosbox c:\atlantis\atlantis.exe -c "MOUNT D C:\SAVES" "SET TEST=blah" + This would mount c:\atlanis as c:\ and run atlantis.exe from that directory but before it + does that it would first mount C:\SAVES as the D drive and set the environment variable test to blah. + +Dragging files or directories onto the DOSBox executable should also work. + + +Internal Programs: +================== + +MOUNT +Program to mount local directories as drives inside DOSBox. + +HWSET +Utility to setup the emulated hardware running inside DOSBox, only working for emulated sound cards. + +UPCASE +Utility to convert all files subdirectories of a local directory into upcase so DOSBox can use that directory +for mounting. This tool can be quite dangerous if used unproperly. You have been warned. + + +To get more information about how to use one these programs use the the /? command line switch. + + +Special Keys: +============= + +ALT-ENTER Go full screen and back. +CTRL-F10 Capture/Release the mouse. +CTRL-F11 Slowdown emulation. +CTRL-F12 Speedup emulation. + +System requirements: +==================== + +Fast machine my guess would be pentium-2 400+ to get decent emulation +of games written for an 286 machine. + +FAQ: +==== + +1.Q: I've got a Z instead of a C at the prompt. + A: In DOSBox you can mount directories as drives + in win32: mount c D:\ would give you an C in DOSBox which points + at D:\ in win32 + in linux: mount c /home/username would give you and C in DOSBox + which points at /home/username in Linux + +2.Q: The window is too small. + A: When you mouse touches the edges of the DOSBox screen you can click and drag it to + the size you prefer. + +3. Check the site/forum. + +Building your own Version DOSBox: +================================= + +Dowload the source. +Check the INSTALL in the source distribution. + +Special Thanks: +=============== + +Vlad R. of the vdmsound project for excellent sound blaster info. +Tatsuyuki Satoh of the Mame Team for making an excellent FM emulator. +The Bochs and DOSemu projects which I used for information. +Freedos for ideas in making my shell. + +Contact: +======== + +Harekiet harekiet@zophar.net +http://dosbox.zophar.net diff --git a/THANKS b/THANKS new file mode 100644 index 00000000..fdc282ee --- /dev/null +++ b/THANKS @@ -0,0 +1,8 @@ +We would like to thank: + + +Vlad R. of the vdmsound project for excellent sound blaster info. +Tatsuyuki Satoh of the Mame Team for making an excellent FM emulator. +The Bochs and DOSemu projects which I used for information. +Freedos for ideas in making my shell. +All the people who submitted a bug. diff --git a/VERSION b/VERSION new file mode 100644 index 00000000..2f20b8fe --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.50 \ No newline at end of file diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 00000000..28772e8e --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,161 @@ +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 +#include +#include +#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 +#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 +]) diff --git a/config.guess b/config.guess new file mode 100644 index 00000000..71de137a --- /dev/null +++ b/config.guess @@ -0,0 +1,1368 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. + +timestamp='2001-03-16' + +# This file 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. +# +# 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. + +# Written by Per Bothner . +# Please send patches to . +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 99, 2000 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int dummy(){}" > $dummy.c + for c in cc gcc c89 ; do + ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 + if test $? = 0 ; then + CC_FOR_BUILD="$c"; break + fi + done + rm -f $dummy.c $dummy.o $dummy.rel + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # Netbsd (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # Determine the machine/vendor (is the vendor relevant). + case "${UNAME_MACHINE}" in + amiga) machine=m68k-unknown ;; + arm32) machine=arm-unknown ;; + atari*) machine=m68k-atari ;; + sun3*) machine=m68k-sun ;; + mac68k) machine=m68k-apple ;; + macppc) machine=powerpc-apple ;; + hp3[0-9][05]) machine=m68k-hp ;; + ibmrt|romp-ibm) machine=romp-ibm ;; + *) machine=${UNAME_MACHINE}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE}" in + i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k) + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + arc64:OpenBSD:*:*) + echo mips64el-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hkmips:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + sun3*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i?86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + case "${HPUX_REV}" in + 11.[0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + esac ;; + esac + fi ;; + esac + if [ "${HP_ARCH}" = "" ]; then + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy + fi ;; + esac + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i?86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + hppa*:OpenBSD:*:*) + echo hppa-unknown-openbsd + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + cat >$dummy.c < /* for printf() prototype */ +int main (int argc, char *argv[]) { +#else +int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __MIPSEB__ + printf ("%s-unknown-linux-gnu\n", argv[1]); +#endif +#ifdef __MIPSEL__ + printf ("%sel-unknown-linux-gnu\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + ;; + ppc:Linux:*:*) + # Determine Lib Version + cat >$dummy.c < +#if defined(__GLIBC__) +extern char __libc_version[]; +extern char __libc_release[]; +#endif +main(argc, argv) + int argc; + char *argv[]; +{ +#if defined(__GLIBC__) + printf("%s %s\n", __libc_version, __libc_release); +#else + printf("unknown\n"); +#endif + return 0; +} +EOF + LIBC="" + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy | grep 1\.99 > /dev/null + if test "$?" = 0 ; then LIBC="libc1" ; fi + fi + rm -f $dummy.c $dummy + echo powerpc-unknown-linux-gnu${LIBC} + exit 0 ;; + alpha:Linux:*:*) + cat <$dummy.s + .data + \$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + .text + .globl main + .align 4 + .ent main + main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + LIBC="" + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) UNAME_MACHINE="alpha" ;; + 1-0) UNAME_MACHINE="alphaev5" ;; + 1-1) UNAME_MACHINE="alphaev56" ;; + 1-101) UNAME_MACHINE="alphapca56" ;; + 2-303) UNAME_MACHINE="alphaev6" ;; + 2-307) UNAME_MACHINE="alphaev67" ;; + esac + objdump --private-headers $dummy | \ + grep ld.so.1 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i?86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + ld_supported_emulations=`cd /; ld --help 2>&1 \ + | sed -ne '/supported emulations:/!d + s/[ ][ ]*/ /g + s/.*supported emulations: *// + s/ .*// + p'` + case "$ld_supported_emulations" in + i?86linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 + ;; + elf_i?86) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + i?86coff) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 + ;; + esac + # Either a pre-BFD a.out linker (linux-gnuoldld) + # or one that does not give us useful --help. + # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. + # If ld does not provide *any* "supported emulations:" + # that means it is gnuoldld. + test -z "$ld_supported_emulations" && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + case "${UNAME_MACHINE}" in + i?86) + VENDOR=pc; + ;; + *) + VENDOR=unknown; + ;; + esac + # Determine whether the default compiler is a.out or elf + cat >$dummy.c < +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __ELF__ +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +#else + printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i?86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i?86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i?86:*:5:7*) + # Fixed at (any) Pentium or better + UNAME_MACHINE=i586 + if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then + echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i?86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i?86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + if test "${UNAME_MACHINE}" = "x86pc"; then + UNAME_MACHINE=pc + fi + echo `uname -p`-${UNAME_MACHINE}-nto-qnx + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[KW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + i?86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure.in b/configure.in new file mode 100644 index 00000000..395ff766 --- /dev/null +++ b/configure.in @@ -0,0 +1,61 @@ +dnl Init. +AC_INIT(dosbox,0.50) +AC_CONFIG_SRCDIR(README) + +dnl Detect the canonical host and target build environment +AC_CANONICAL_HOST +AC_CANONICAL_TARGET + +dnl Setup for automake +AM_INIT_AUTOMAKE +AM_CONFIG_HEADER(config.h) + + +dnl Checks for programs. +AC_PROG_MAKE_SET +AC_PROG_CC +AC_PROG_CPP +AC_PROG_CXX +AC_PROG_INSTALL +AC_PROG_RANLIB + +dnl Check for SDL +SDL_VERSION=1.2.0 +AM_PATH_SDL($SDL_VERSION, + :, + AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!]) +) +LIBS="$LIBS $SDL_LIBS" +CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + +dnl Checks for header files. + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_TYPE_SIZE_T +AC_STRUCT_TM + +dnl Checks for library functions. + + +#Always include the standard include dir in all makefiless + +AC_OUTPUT([ +Makefile +src/Makefile +src/cpu/Makefile +src/cpu/core_16/Makefile +src/debug/Makefile +src/dos/Makefile +src/fpu/Makefile +src/gui/Makefile +src/hardware/Makefile +src/ints/Makefile +src/misc/Makefile +src/shell/Makefile +src/platform/Makefile +src/platform/visualc/Makefile +visualc/Makefile +include/Makefile +]) diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 00000000..4425e6ed --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1,29 @@ +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 + diff --git a/include/bios.h b/include/bios.h new file mode 100644 index 00000000..9d74b591 --- /dev/null +++ b/include/bios.h @@ -0,0 +1,120 @@ +/* + * 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 BIOS_BASE_ADDRESS_COM1 0x400 +#define BIOS_BASE_ADDRESS_COM2 0x402 +#define BIOS_BASE_ADDRESS_COM3 0x404 +#define BIOS_BASE_ADDRESS_COM4 0x406 +#define BIOS_ADDRESS_LPT1 0x408 +#define BIOS_ADDRESS_LPT2 0x40a +#define BIOS_ADDRESS_LPT3 0x40c +/* 0x40e is reserved */ +#define BIOS_CONFIGURATION 0x410 +/* 0x412 is reserved */ +#define BIOS_MEMORY_SIZE 0x413 +/* #define bios_expansion_memory_size (*(unsigned int *) 0x415) */ +#define BIOS_KEYBOARD_STATE 0x417 +#define BIOS_KEYBOARD_FLAGS1 BIOS_KEYBOARD_STATE +#define BIOS_KEYBOARD_FLAGS2 0x418 +#define BIOS_KEYBOARD_TOKEN 0x419 +/* used for keyboard input with Alt-Number */ +#define BIOS_KEYBOARD_BUFFER_HEAD 0x41a +#define BIOS_KEYBOARD_BUFFER_TAIL 0x41c +#define BIOS_KEYBOARD_BUFFER 0x41e +/* #define bios_keyboard_buffer (*(unsigned int *) 0x41e) */ +#define BIOS_DRIVE_ACTIVE 0x43e +#define BIOS_DRIVE_RUNNING 0x43f +#define BIOS_MOTOR_NACHLAUFZEIT 0x440 +#define BIOS_DISK_STATUS 0x441 +/* #define bios_fdc_result_buffer (*(unsigned short *) 0x442) */ +#define BIOS_VIDEO_MODE 0x449 +#define BIOS_SCREEN_COLUMNS 0x44a +#define BIOS_VIDEO_MEMORY_USED 0x44c +#define BIOS_VIDEO_MEMORY_ADDRESS 0x44e +#define BIOS_VIDEO_CURSOR_POS 0x450 + + +#define BIOS_CURSOR_SHAPE 0x460 +#define BIOS_CURSOR_LAST_LINE 0x460 +#define BIOS_CURSOR_FIRST_LINE 0x461 +#define BIOS_CURRENT_SCREEN_PAGE 0x462 +#define BIOS_VIDEO_PORT 0x463 +#define BIOS_VDU_CONTROL 0x465 +#define BIOS_VDU_COLOR_REGISTER 0x466 +/* 0x467-0x468 is reserved */ +#define BIOS_TIMER 0x46c +#define BIOS_24_HOURS_FLAG 0x470 +#define BIOS_KEYBOARD_FLAGS 0x471 +#define BIOS_CTRL_ALT_DEL_FLAG 0x472 +#define BIOS_HARDDISK_COUNT 0x475 +/* 0x474, 0x476, 0x477 is reserved */ +#define BIOS_LPT1_TIMEOUT 0x478 +#define BIOS_LPT2_TIMEOUT 0x479 +#define BIOS_LPT3_TIMEOUT 0x47a +/* 0x47b is reserved */ +#define BIOS_COM1_TIMEOUT 0x47c +#define BIOS_COM2_TIMEOUT 0x47d +/* 0x47e is reserved */ +/* 0x47f-0x4ff is unknow for me */ +#define BIOS_KEYBOARD_BUFFER_START 0x480 +#define BIOS_KEYBOARD_BUFFER_END 0x482 + +#define BIOS_ROWS_ON_SCREEN_MINUS_1 0x484 +#define BIOS_FONT_HEIGHT 0x485 + +#define BIOS_VIDEO_INFO_0 0x487 +#define BIOS_VIDEO_INFO_1 0x488 +#define BIOS_VIDEO_INFO_2 0x489 +#define BIOS_VIDEO_COMBO 0x48a + +#define BIOS_KEYBOARD_FLAGS3 0x496 +#define BIOS_KEYBOARD_LEDS 0x497 +#define BIOS_PRINT_SCREEN_FLAG 0x500 + +#define BIOS_VIDEO_SAVEPTR 0x4a8 + +/* The Section handling Bios Disk Access */ +#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; +}; + + +void char_out(Bit8u chr,Bit32u att,Bit8u page); +void INT10_StartUp(void); +void INT16_StartUp(void); +void INT2A_StartUp(void); +void INT2F_StartUp(void); +void INT33_StartUp(void); +void INT13_StartUp(void); + + diff --git a/include/callback.h b/include/callback.h new file mode 100644 index 00000000..00a67457 --- /dev/null +++ b/include/callback.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __CALLBACK_H +#define __CALLBACK_H + +#include + +typedef Bitu (*CallBack_Handler)(void); +extern CallBack_Handler CallBack_Handlers[]; + +enum { CB_RETF,CB_IRET }; + +#define CB_MAX 1024 +#define CB_SEG 0xC800 + +enum { + CBRET_NONE=0,CBRET_STOP=1 +}; + +extern Bit8u lastint; +INLINE RealPt CALLBACK_RealPointer(Bitu callback) { + return RealMake(CB_SEG,callback << 4); +} + +Bitu CALLBACK_Allocate(); + +void CALLBACK_Idle(void); + + +void CALLBACK_RunRealInt(Bit8u intnum); +void CALLBACK_RunRealFar(Bit16u seg,Bit16u off); + +bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type); + +bool CALLBACK_Free(Bitu callback); + +void CALLBACK_SCF(bool val); +void CALLBACK_SZF(bool val); +#endif + diff --git a/include/cpu.h b/include/cpu.h new file mode 100644 index 00000000..8a753ec5 --- /dev/null +++ b/include/cpu.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __CPU_H +#define __CPU_H + +#include +#include +#include + +/* Some common Defines */ +/* A CPU Handler */ +typedef Bitu (CPU_Decoder)(Bitu count); +extern CPU_Decoder * cpudecoder; +extern Bit32u cpu_cycles; + + +extern Bit32u hoever; + +//CPU Stuff +void SetCPU16bit(); +void SetSegment_16(Bit32u seg,Bit16u val); + + +//Types of Flag changing instructions +enum { + t_ADDb=0,t_ADDw,t_ADDd, + t_ORb,t_ORw,t_ORd, + t_ADCb,t_ADCw,t_ADCd, + 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, + + t_DSHLw,t_DSHLd, + t_DSHRw,t_DSHRd, + t_MUL,t_DIV, + t_UNKNOWN, + t_NOTDONE, +}; + +enum { rep_NONE,rep_Z,rep_NZ }; + + +void Interrupt(Bit8u num); + +//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); + +Bit8u get_Flags8(void); + + + + +#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,PhysPt ea); + +#endif + diff --git a/include/cross.h b/include/cross.h new file mode 100644 index 00000000..20d2d5a9 --- /dev/null +++ b/include/cross.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _CROSS_H +#define _CROSS_H + +#include +#include +#include + +#if defined (_MSC_VER) /* MS Visual C++ */ +#include +#include +#else /* LINUX */ +#include +#include +#endif + +#define CROSS_LEN 512 /* Maximum filename size */ + + +#if defined (_MSC_VER) /* MS Visual C++ */ +#define CROSS_FILENAME(blah) +#define CROSS_FILESPLIT '\\' +#define F_OK 0 +#else +#define CROSS_FILENAME(blah) strreplace(blah,'\\','/') +#define CROSS_FILESPLIT '/' +#endif + +#define CROSS_NONE 0 +#define CROSS_FILE 1 +#define CROSS_DIR 2 + + +extern const char * dosbox_datadir; + +#endif + diff --git a/include/debug.h b/include/debug.h new file mode 100644 index 00000000..20deed7f --- /dev/null +++ b/include/debug.h @@ -0,0 +1,24 @@ +/* + * 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. + */ + +void DEBUG_DrawScreen(void); +bool DEBUG_BreakPoint(void); +void DEBUG_Enable(void); + +extern Bitu cycle_count; + diff --git a/include/dma.h b/include/dma.h new file mode 100644 index 00000000..e6923daa --- /dev/null +++ b/include/dma.h @@ -0,0 +1,24 @@ +/* + * 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. + */ + +void DMA_8_Read(Bit32u channel,Bit8u * buffer,Bit16u count); +void DMA_8_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count); + +void DMA_16_Read(Bit32u channel,Bit8u * buffer,Bit16u count); +void DMA_16_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count); + diff --git a/include/dos_inc.h b/include/dos_inc.h new file mode 100644 index 00000000..32414ca4 --- /dev/null +++ b/include/dos_inc.h @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef DOS_H_ +#define DOS_H_ + +#include +#include + +#pragma pack(1) + +struct CommandTail{ + Bit8u count; /* number of bytes returned */ + char buffer[127]; /* the buffer itself */ +}; + +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() + +struct DOS_Date { + Bit16u year; + Bit8u month; + Bit8u day; +}; + + +struct DOS_Version { + 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; + + bool verify; + bool breakcheck; + struct { + RealPt indosflag; + } tables; + +}; + +enum { MCB_FREE=0x0000,MCB_DOS=0x0008 }; +enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; + +#define DOS_FILES 50 +#define DOS_DRIVES 26 + +/* internal Dos Tables */ +extern DOS_Block dos; +extern DOS_File * Files[DOS_FILES]; +extern DOS_Drive * Drives[DOS_DRIVES]; + + +void DOS_SetError(Bit16u code); + +/* File Handling Routines */ + +enum { STDIN=0,STDOUT=1,STDERR=2,STDAUX=3,STDNUL=4,STDPRN=5}; +enum { HAND_NONE=0,HAND_FILE,HAND_DEVICE}; + + + +/* Routines for File Class */ +void DOS_SetupFiles (void); + +bool DOS_ReadFile(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_CloseFile(Bit16u handle); +bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry); +/* Routines for Drive Class */ +bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry); +bool DOS_CreateFile(char * name,Bit16u attribute,Bit16u * entry); +bool DOS_UnlinkFile(char * name); +bool DOS_FindFirst(char *search,Bit16u attr); +bool DOS_FindNext(void); +bool DOS_Canonicalize(char * small,Bit8u * big); +bool DOS_CreateTempFile(char * name,Bit16u * entry); +bool DOS_FileExists(char * name); +/* Drive Handing Routines */ +Bit8u DOS_GetDefaultDrive(void); +void DOS_SetDefaultDrive(Bit8u drive); +bool DOS_SetDrive(Bit8u drive); +bool DOS_GetCurrentDir(Bit8u drive,Bit8u * buffer); +bool DOS_ChangeDir(char * dir); +bool DOS_MakeDir(char * dir); +bool DOS_RemoveDir(char * dir); +bool DOS_Rename(char * oldname,char * newname); +bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free); +bool DOS_GetFileAttr(char * name,Bit16u * attr); +/* IOCTL Stuff */ +bool DOS_IOCTL(Bit8u call,Bit16u entry); +bool DOS_GetSTDINStatus(); +Bit8u DOS_FindDevice(char * name); +void DOS_SetupDevices(void); +/* Execute and new process creation */ +bool DOS_NewPSP(Bit16u pspseg); +bool DOS_Execute(char * name,ParamBlock * block,Bit8u flags); +bool DOS_Terminate(bool tsr); + +/* Memory Handling Routines */ +void DOS_SetupMemory(void); +bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks); +bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks); +bool DOS_FreeMemory(Bit16u segment); +void DOS_FreeProcessMemory(Bit16u pspseg); +Bit16u DOS_GetMemory(Bit16u pages); + +/* Extra DOS Interrupts */ +void DOS_SetupMisc(void); + +/* The DOS Tables */ +void DOS_SetupTables(void); +/* Internal DOS Setup Programs */ +void DOS_SetupPrograms(void); + + +INLINE Bit16u long2para(Bit32u size) { + if (size>0xFFFF0) return 0xffff; + if (size&0xf) return (Bit16u)((size>>4)+1); + else return (Bit16u)(size>>4); +}; + +INLINE Bit8u RealHandle(Bit16u handle) { + PSP * psp=(PSP *)real_off(dos.psp,0); + if (handle>=psp->max_files) return DOS_FILES; + return mem_readb(Real2Phys(psp->file_table)+handle); +}; + +/* Dos Error Codes */ +#define DOSERR_NONE 0 +#define DOSERR_FUNCTION_NUMBER_INVALID 1 +#define DOSERR_FILE_NOT_FOUND 2 +#define DOSERR_PATH_NOT_FOUND 3 +#define DOSERR_TOO_MANY_OPEN_FILES 4 +#define DOSERR_ACCESS_DENIED 5 +#define DOSERR_INVALID_HANDLE 6 +#define DOSERR_MCB_DESTROYED 7 +#define DOSERR_INSUFFICIENT_MEMORY 8 +#define DOSERR_MB_ADDRESS_INVALID 9 +#define DOSERR_ENVIRONMENT_INVALID 10 +#define DOSERR_FORMAT_INVALID 11 +#define DOSERR_ACCESS_CODE_INVALID 12 +#define DOSERR_DATA_INVALID 13 +#define DOSERR_RESERVED 14 +#define DOSERR_FIXUP_OVERFLOW 14 +#define DOSERR_INVALID_DRIVE 15 +#define DOSERR_REMOVE_CURRENT_DIRECTORY 16 +#define DOSERR_NOT_SAME_DEVICE 17 +#define DOSERR_NO_MORE_FILES 18 + +/* Remains some classes used to access certain things */ +class DOS_FCB { +public: + DOS_FCB(PhysPt pt){ + off=pt; + } + DOS_FCB(Bit16u seg, Bit16u offset){ + off=Real2Phys(RealMake(seg,offset)); + } + void Set_drive(Bit8u a); + void Set_filename(char* a); //writes an the first 8 bytes of a as the filename + void Set_ext(char* a); + void Set_current_block(Bit16u a); + void Set_record_size(Bit16u a); + void Set_filesize(Bit32u a); + void Set_date(Bit16u a); + void Set_time(Bit16u a); + // others nog yet handled + Bit8u Get_drive(void); + void Get_filename(char* a); + void Get_ext(char* a); + Bit16u Get_current_block(void); + Bit16u Get_record_size(void); + Bit32u Get_filesize(void); + Bit16u Get_date(void); + Bit16u Get_time(void); +private: + PhysPt off; +}; + + + + +#endif + diff --git a/include/dos_system.h b/include/dos_system.h new file mode 100644 index 00000000..55f210a8 --- /dev/null +++ b/include/dos_system.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef DOSSYSTEM_H_ +#define DOSSYSTEM_H_ + +#include + +#define DOS_NAMELENGTH 12 +#define DOS_DIRDEPTH 16 +#define DOS_PATHLENGTH (DOS_DIRDEPTH+1)*(DOS_NAMELENGTH+2) +#define DOS_TEMPSIZE 1024 + +enum { + DOS_ATTR_READ_ONLY= 0x01, + DOS_ATTR_HIDDEN= 0x02, + DOS_ATTR_SYSTEM= 0x04, + DOS_ATTR_VOLUME= 0x08, + DOS_ATTR_DIRECTORY= 0x10, + DOS_ATTR_ARCHIVE= 0x20 +}; + +#pragma pack (1) +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 date; + Bit32u size; + char name[DOS_NAMELENGTH]; +}; +#pragma pack () + +class DOS_File { +public: + virtual bool Read(Bit8u * data,Bit16u * size)=0; + virtual bool Write(Bit8u * data,Bit16u * size)=0; + virtual bool Seek(Bit32u * pos,Bit32u type)=0; + virtual bool Close()=0; + virtual Bit16u GetInformation(void)=0; + Bit8u type;Bit32u flags; +/* Some Device Specific Stuff */ +}; + +class DOS_Device : public DOS_File { +public: +/* Some Device Specific Stuff */ + char * name; + Bit8u fhandle; +}; + + + +class DOS_Drive { +public: + DOS_Drive(); + virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags)=0; + virtual bool FileCreate(DOS_File * * file,char * name,Bit16u attributes)=0; + virtual bool FileUnlink(char * name)=0; + virtual bool RemoveDir(char * dir)=0; + virtual bool MakeDir(char * dir)=0; + virtual bool TestDir(char * dir)=0; + virtual bool FindFirst(char * search,DTA_FindBlock * dta)=0; + virtual bool FindNext(DTA_FindBlock * dta)=0; + virtual bool GetFileAttr(char * name,Bit16u * attr)=0; + virtual bool Rename(char * oldname,char * newname)=0; + virtual bool FreeSpace(Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free)=0; + char * GetInfo(void); + char curdir[DOS_PATHLENGTH]; + char info[256]; +}; + +enum { OPEN_READ=0,OPEN_WRITE=1,OPEN_READWRITE=2 }; +enum { DOS_SEEK_SET=0,DOS_SEEK_CUR=1,DOS_SEEK_END=2}; + + +/* + A multiplex handler should read the registers to check what function is being called + If the handler returns false dos will stop checking other handlers +*/ + +typedef bool (MultiplexHandler)(void); +void DOS_AddMultiplexHandler(MultiplexHandler * handler); + +void DOS_AddDevice(DOS_Device * adddev); +void VFILE_Register(char * name,Bit8u * data,Bit32u size); +#endif + diff --git a/include/dosbox.h b/include/dosbox.h new file mode 100644 index 00000000..8b7e26c3 --- /dev/null +++ b/include/dosbox.h @@ -0,0 +1,63 @@ +/* + * 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. + */ + +#if !defined __DOSBOX_H +#define __DOSBOX_H + +typedef unsigned char Bit8u; +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 + +typedef unsigned int Bitu; +typedef signed int Bits; + +#include + +void E_Exit(char * message,...); + +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 + + +typedef Bitu (LoopHandler)(void); + +void DOSBOX_RunMachine(); +void DOSBOX_SetLoop(LoopHandler * handler); + +void DOSBOX_Init(int argc, char* argv[]); +void DOSBOX_StartUp(void); +#endif + diff --git a/include/fpu.h b/include/fpu.h new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/include/fpu.h @@ -0,0 +1 @@ + diff --git a/include/hardware.h b/include/hardware.h new file mode 100644 index 00000000..5edfa4b7 --- /dev/null +++ b/include/hardware.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _HARDWARE_H_ +#define _HARDWARE_H_ + +#include +#include +#include + +typedef void (* HW_OutputHandler)(char * towrite); +typedef void (* HW_InputHandler)(char * line); + +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; +}; + + +void HW_Register(HWBlock * block); + + +#endif + + diff --git a/include/inout.h b/include/inout.h new file mode 100644 index 00000000..91f00a81 --- /dev/null +++ b/include/inout.h @@ -0,0 +1,48 @@ +/* + * 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. + */ + +typedef Bit8u (IO_ReadHandler)(Bit32u port); +typedef void (IO_WriteHandler)(Bit32u port,Bit8u value); + +#define IO_MAX 1024 + +struct IO_ReadBlock{ + IO_ReadHandler * handler; + char * name; +}; + +struct IO_WriteBlock{ + IO_WriteHandler * handler; + char * name; +}; + +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); + + diff --git a/include/joystick.h b/include/joystick.h new file mode 100644 index 00000000..3317db1f --- /dev/null +++ b/include/joystick.h @@ -0,0 +1,25 @@ +/* + * 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. + */ + +void JOYSTICK_Enable(Bitu which,bool enabled); + +void JOYSTICK_Button(Bitu which,Bitu num,bool pressed); + +void JOYSTICK_Move_X(Bitu which,float x); + +void JOYSTICK_Move_Y(Bitu which,float y); \ No newline at end of file diff --git a/include/keyboard.h b/include/keyboard.h new file mode 100644 index 00000000..ec495d07 --- /dev/null +++ b/include/keyboard.h @@ -0,0 +1,54 @@ +/* + * 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. + */ + +typedef void(KEYBOARD_EventHandler)(void); +void KEYBOARD_AddCode(Bit8u code); +void KEYBOARD_AddKey(Bitu keytype,bool pressed); +void KEYBOARD_AddEvent(Bitu keytype,Bitu state,KEYBOARD_EventHandler * handler); + + +#define ALT_PRESSED 0x1 +#define CTRL_PRESSED 0x2 +#define SHIFT_PRESSED 0x4 + +enum { + KBD_1, KBD_2, KBD_3, KBD_4, KBD_5, KBD_6, KBD_7, KBD_8, KBD_9, KBD_0, + KBD_q, KBD_w, KBD_e, KBD_r, KBD_t, KBD_y, KBD_u, KBD_i, KBD_o, KBD_p, + KBD_a, KBD_s, KBD_d, KBD_f, KBD_g, KBD_h, KBD_j, KBD_k, KBD_l, KBD_z, + KBD_x, KBD_c, KBD_v, KBD_b, KBD_n, KBD_m, + KBD_f1, KBD_f2, KBD_f3, KBD_f4, KBD_f5, KBD_f6, KBD_f7, KBD_f8, KBD_f9, KBD_f10,KBD_f11,KBD_f12, + + /*Now the weirder keys */ + + KBD_esc,KBD_tab,KBD_backspace,KBD_enter,KBD_space, + KBD_leftalt,KBD_rightalt,KBD_leftctrl,KBD_rightctrl,KBD_leftshift,KBD_rightshift, + KBD_capslock,KBD_scrolllock,KBD_numlock, + + KBD_grave,KBD_minus,KBD_equals,KBD_backslash,KBD_leftbracket,KBD_rightbracket, + KBD_semicolon,KBD_quote,KBD_period,KBD_comma,KBD_slash, + + KBD_insert,KBD_home,KBD_pageup,KBD_delete,KBD_end,KBD_pagedown, + 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_kpslash,KBD_kpmultiply,KBD_kpminus,KBD_kpplus,KBD_kpenter,KBD_kpperiod, + + KBD_LAST +}; + + diff --git a/include/mem.h b/include/mem.h new file mode 100644 index 00000000..ec231d31 --- /dev/null +++ b/include/mem.h @@ -0,0 +1,206 @@ +/* + * 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. + */ + +#if !defined __MEM_H +#define __MEM_H +#include + +enum { MEMORY_HANDLER=1,MEMORY_RELOCATE=2}; + +#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 PhysPt; +typedef Bit8u * HostPt; +typedef Bit32u RealPt; + +struct PageEntry { + Bit8u type; + PhysPt base; /* Used to calculate relative offset */ + struct { + MEMORY_WriteHandler * write; + MEMORY_ReadHandler * read; + } handler; + HostPt relocate; /* This points to host machine address */ +}; + +struct EMM_Handle { + Bit16u next; + Bit16u size; /* Size in pages */ + PhysPt phys_base; + HostPt host_base; + bool active; + bool free; +}; + +INLINE Bit16u PAGES(Bit32u bytes) { + if ((bytes & 4095) == 0) return (Bit16u)(bytes>>12); + return (Bit16u)(1+(bytes>>12)); +} + +extern Bit8u * memory; +extern EMM_Handle EMM_Handles[]; +extern PageEntry * PageEntries[]; /* Number of pages */ + +bool MEMORY_TestSpecial(PhysPt off); +void MEMORY_SetupHandler(Bit32u page,Bit32u extra,PageEntry * handler); +void MEMORY_ResetHandler(Bit32u page,Bit32u pages); + + +void EMM_GetFree(Bit16u * maxblock,Bit16u * total); +void EMM_Allocate(Bit16u size,Bit16u * handle); +void EMM_Free(Bit16u handle); + + +/* + The folowing six functions are used everywhere in the end so these should be changed for + Working on big or little endian machines +*/ + + +INLINE Bit8u readb(HostPt off) { + return *(Bit8u *)off; +}; +INLINE Bit16u readw(HostPt off) { + return *(Bit16u *)off; +}; +INLINE Bit32u readd(HostPt off) { + return *(Bit32u *)off; +}; +INLINE void writeb(HostPt off,Bit8u val) { + *(Bit8u *)(off)=val; +}; +INLINE void writew(HostPt off,Bit16u val) { + *(Bit16u *)(off)=val; +}; +INLINE void writed(HostPt off,Bit32u val) { + *(Bit32u *)(off)=val; +}; + + +/* 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); +Bit16u mem_readw(PhysPt pt); +Bit32u mem_readd(PhysPt pt); + +void mem_writeb(PhysPt pt,Bit8u val); +void mem_writew(PhysPt pt,Bit16u val); +void mem_writed(PhysPt pt,Bit32u val); + + + + + +void MEM_BlockWrite(PhysPt pt,void * 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); + + + +/* The folowing functions are all shortcuts to the above functions using physical addressing */ + +INLINE HostPt real_off(Bit16u seg,Bit32u off) { + return memory+(seg<<4)+off; +}; + +INLINE HostPt real_host(Bit16u seg,Bit32u off) { + return memory+(seg<<4)+off; +}; +INLINE PhysPt real_phys(Bit16u seg,Bit32u off) { + return (seg<<4)+off; +}; + +INLINE Bit8u real_readb(Bit16u seg,Bit16u off) { + return mem_readb((seg<<4)+off); +} +INLINE Bit16u real_readw(Bit16u seg,Bit16u off) { + return mem_readw((seg<<4)+off); +} +INLINE Bit32u real_readd(Bit16u seg,Bit16u 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)) + +INLINE void real_writeb(Bit16u seg,Bit16u off,Bit8u val) { + mem_writeb(((seg<<4)+off),val); +} +INLINE void real_writew(Bit16u seg,Bit16u off,Bit16u val) { + mem_writew(((seg<<4)+off),val); +} +INLINE void real_writed(Bit16u seg,Bit16u off,Bit32u val) { + mem_writed(((seg<<4)+off),val); +} + + +//#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); +} + +INLINE Bit16u RealOff(RealPt pt) { + return (Bit16u)(pt&0xffff); +} + +INLINE PhysPt Real2Phys(RealPt pt) { + return (RealSeg(pt)<<4) +RealOff(pt); +} + + +INLINE HostPt Real2Host(RealPt pt) { + return memory+(RealSeg(pt)<<4) +RealOff(pt); +} + + +INLINE RealPt RealMake(Bit16u seg,Bit16u off) { + return (seg<<16)+off; +} + + +INLINE void RealSetVec(Bit8u vec,RealPt pt) { + mem_writed(vec<<2,pt); +} + +INLINE RealPt RealGetVec(Bit8u vec) { + return mem_readd(vec<<2); +} + + + + +#endif + diff --git a/include/mixer.h b/include/mixer.h new file mode 100644 index 00000000..e41b1838 --- /dev/null +++ b/include/mixer.h @@ -0,0 +1,42 @@ +/* + * 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. + */ + +typedef void (*MIXER_MixHandler)(Bit8u * sampdate,Bit32u len); + +#define MIXER_8MONO 0 +#define MIXER_8STEREO 1 +#define MIXER_16MONO 2 +#define MIXER_16STEREO 3 + +#define MAX_AUDIO ((1<<(16-1))-1) +#define MIN_AUDIO -(1<<(16-1)) + + + +struct MIXER_Channel; + + +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); + diff --git a/include/modules.h b/include/modules.h new file mode 100644 index 00000000..6bbeffca --- /dev/null +++ b/include/modules.h @@ -0,0 +1,180 @@ +/* Standard data types used */ + +typedef unsigned char Bit8u; +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 + + + +/* Setting up pointers to all subfunctions */ +#ifdef MODULE_WANT_IO_READ +typedef Bit8u (* IO_ReadHandler)(Bit32u port); +static void (* IO_RegisterReadHandler)(Bit32u port,IO_ReadHandler handler,char * name); +static void (* IO_FreeReadHandler)(Bit32u port); +#endif + +#ifdef MODULE_WANT_IO_WRITE +typedef void (* IO_WriteHandler)(Bit32u port,Bit8u value); +static void (* IO_RegisterWriteHandler)(Bit32u port,IO_WriteHandler handler,char * name); +static void (* IO_FreeWriteHandler)(Bit32u port); +#endif + +#ifdef MODULE_WANT_IRQ_EOI +typedef void (* IRQ_EOIHandler)(void); +static void (* IRQ_RegisterEOIHandler)(Bit32u irq,IRQ_EOIHandler handler,char * name); +static void (* IRQ_FreeEOIHandler)(Bit32u irq); +#endif + +#ifdef MODULE_WANT_IRQ +static void (* IRQ_Activate)(Bit32u irq); +static void (* IRQ_Deactivate)(Bit32u irq); +#endif + +#ifdef MODULE_WANT_TIMER +typedef void (* TIMER_MicroHandler)(void); +static void (* TIMER_RegisterMicroHandler)(TIMER_MicroHandler handler,Bit32u micro); +#endif + +#ifdef MODULE_WANT_TIMER_TICK +typedef void (* TIMER_TickHandler)(Bit32u ticks); +static void (* TIMER_RegisterTickHandler)(TIMER_TickHandler handler); +#endif + +/* + 4 8-bit and 4 16-bit channels you can read data from + 16-bit reads are word sized +*/ + +#ifdef MODULE_WANT_DMA_READ +static void (* DMA_8_Read)(Bit32u chan,Bit8u * data,Bit16u size); +static void (* DMA_16_Read)(Bit32u chan,Bit8u * data,Bit16u size); +#endif + +/* + 4 8-bit and 4 16-bit channels you can write data from + 16-bit writes are word sized +*/ + +#ifdef MODULE_WANT_DMA_READ +static void (* DMA_8_Write)(Bit32u chan,Bit8u * data,Bit16u size); +static void (* DMA_16_Write)(Bit32u chan,Bit8u * data,Bit16u size); +#endif + + +#ifdef MODULE_WANT_MIXER +/* The len here means the amount of samples needed not the buffersize it needed to fill */ +typedef void (* MIXER_MixHandler)(Bit8u * sampdate,Bit32u len); + +/* Different types if modes a mixer channel can work in */ +#define MIXER_8MONO 0 +#define MIXER_8STEREO 1 +#define MIXER_16MONO 2 +#define MIXER_16STEREO 3 +struct MIXER_Channel; + +#define MAX_AUDIO ((1<<(16-1))-1) +#define MIN_AUDIO -(1<<(16-1)) + +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); +#endif + +typedef bool (* MODULE_FindHandler)(char * name,void * * function); +typedef char *(* MODULE_StartHandler)(MODULE_FindHandler find_handler); + +#define MODULE_START_PROC "ModuleStart" + +#ifdef MODULE_START_FUNCTION +#include + +#define GET_FUNCTION(a) \ + if (!find_handler(#a ,(void * *) &a)) { \ + return "Can't find requested function"; \ + }; + + +#if defined (WIN32) +#include +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + return TRUE; +} + +extern "C" { +__declspec(dllexport) +#endif +char * ModuleStart (MODULE_FindHandler find_handler) { + +#ifdef MODULE_WANT_IRQ_EOI +GET_FUNCTION(IRQ_RegisterEOIHandler); +GET_FUNCTION(IRQ_FreeEOIHandler); +#endif + +#ifdef MODULE_WANT_IRQ +GET_FUNCTION(IRQ_Activate); +GET_FUNCTION(IRQ_Deactivate); +#endif + +#ifdef MODULE_WANT_IO_READ +GET_FUNCTION(IO_RegisterReadHandler); +GET_FUNCTION(IO_FreeReadHandler); +#endif + +#ifdef MODULE_WANT_IO_WRITE +GET_FUNCTION(IO_RegisterWriteHandler); +GET_FUNCTION(IO_FreeWriteHandler); +#endif + +#ifdef MODULE_WANT_TIMER +GET_FUNCTION(TIMER_RegisterMicroHandler); +#endif + +#ifdef MODULE_WANT_TIMER_TICKS +GET_FUNCTION(TIMER_RegisterTickHandler); +#endif + +#ifdef MODULE_WANT_DMA_READ +GET_FUNCTION(DMA_8_Read); +GET_FUNCTION(DMA_16_Read); +#endif + +#ifdef MODULE_WANT_DMA_WRITE +GET_FUNCTION(DMA_8_Write); +GET_FUNCTION(DMA_16_Write); +#endif + +#ifdef MODULE_WANT_MIXER +GET_FUNCTION(MIXER_AddChannel); +GET_FUNCTION(MIXER_SetVolume); +GET_FUNCTION(MIXER_SetFreq); +GET_FUNCTION(MIXER_SetMode); +GET_FUNCTION(MIXER_Enable); +#endif + +return MODULE_START_FUNCTION; + +} +#if defined (WIN32) +} +#endif + + + +#endif + diff --git a/include/mouse.h b/include/mouse.h new file mode 100644 index 00000000..4d0c932c --- /dev/null +++ b/include/mouse.h @@ -0,0 +1,28 @@ +/* + * 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. + */ + +void Mouse_ShowCursor(void); +void Mouse_HideCursor(void); + + +void Mouse_CursorMoved(float x,float y); +void Mouse_CursorSet(float x,float y); +void Mouse_ButtonPressed(Bit8u button); +void Mouse_ButtonReleased(Bit8u button); + + diff --git a/include/pic.h b/include/pic.h new file mode 100644 index 00000000..44a2f76d --- /dev/null +++ b/include/pic.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __PIC_H +#define __PIC_H + +typedef void (PIC_EOIHandler) (void); +typedef void (PIC_Function)(void); + +extern Bit32u PIC_IRQCheck; + +void PIC_ActivateIRQ(Bit32u irq); + +void PIC_DeActivateIRQ(Bit32u irq); + +void PIC_runIRQs(void); + +void PIC_RegisterIRQ(Bit32u irq,PIC_EOIHandler handler,char * name); +void PIC_FreeIRQ(Bit32u irq); + +bool PIC_IRQActive(Bit32u irq); + +/* A Queued function should never queue itself again this will go horribly wrong */ +void PIC_QueueFunction(PIC_Function * function); + + + +#endif + diff --git a/include/programs.h b/include/programs.h new file mode 100644 index 00000000..d716510c --- /dev/null +++ b/include/programs.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __PROGRAM_H +#define __PROGRAM_H +#include +#include + + +char * MSG_Get(char * msg); + +struct PROGRAM_Info { + Bit16u psp_seg; + PSP psp_copy; + char full_name[32]; //Enough space for programs only on the z:\ drive + char * cmd_line; +}; + +typedef void (PROGRAMS_Main)(PROGRAM_Info * info); +void PROGRAMS_MakeFile(char * name,PROGRAMS_Main * main); + +class Program { +public: + Program(PROGRAM_Info * program_info); + virtual void Run(void)=0; + char * GetEnvStr(char * env_entry); + char * GetEnvNum(Bit32u num); + Bit32u GetEnvCount(void); + bool SetEnv(char * env_entry,char * new_string); + void WriteOut(char * format,...); /* Write to standard output */ + PROGRAM_Info * prog_info; + +}; + +void SHELL_AddAutoexec(char * line,...); + + + + + + +#endif + diff --git a/include/regs.h b/include/regs.h new file mode 100644 index 00000000..bec30b61 --- /dev/null +++ b/include/regs.h @@ -0,0 +1,114 @@ +/* + * 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. + */ + +#if !defined __REGS_H +#define __REGS_H + +#include + +struct Flag_Info { + union { + Bit8u b; + Bit16u w; + Bit32u d; + } var1,var2,result; + Bitu type; + Bitu prev_type; + bool cf,sf,pf,af,zf,of,df,tf,intf; + bool nt; + Bit8u io; + bool oldcf; +}; + + + +struct Segment { + Bit16u value; + bool special; /* Signal for pointing to special memory */ + HostPt host; /* The address of start in host memory */ + PhysPt phys; /* The phyiscal address start in emulated machine */ +}; + + + + +enum { cs=0,ds,es,fs,gs,ss}; + +extern Segment Segs[6]; +extern Flag_Info flags; +//extern Regs regs; + +void SetSegment_16(Bit32u seg,Bit16u val); + + +struct CPU_Regs { + union { + Bit32u d; + Bit16u w; + struct { + Bit8u l,h; + }b; + } ax,bx,cx,dx,si,di,sp,bp,ip; +}; + +extern CPU_Regs cpu_regs; + +#define reg_al cpu_regs.ax.b.l + +//extern Bit8u & reg_al=cpu_regs.ax.b.l; + +#define reg_ah cpu_regs.ax.b.h +#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 + + + + + +#endif + diff --git a/include/render.h b/include/render.h new file mode 100644 index 00000000..74b8aa15 --- /dev/null +++ b/include/render.h @@ -0,0 +1,25 @@ +/* + * 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. + */ + + +typedef void RENDER_Handler(Bit8u * * data); + + +void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu flags, RENDER_Handler * handler); + +void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue); diff --git a/include/setup.h b/include/setup.h new file mode 100644 index 00000000..ec820112 --- /dev/null +++ b/include/setup.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _SETUP_H_ +#define _SETUP_H_ + +#include +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]; + +#endif diff --git a/include/support.h b/include/support.h new file mode 100644 index 00000000..00079ee7 --- /dev/null +++ b/include/support.h @@ -0,0 +1,63 @@ +/* + * 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. + */ + +#if !defined __SUPPORT_H +#define __SUPPORT_H + + +#include +#include +#include + +#if defined (_MSC_VER) /* MS Visual C++ */ +#define strcasecmp(a,b) stricmp(a,b) +#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 + + +void strreplace(char * str,char o,char n); +char *ltrim(char *str); +void rtrim(char * const str); +char *trim(char *str); + +bool wildcmp(char *wild, char *string); + +bool ScanCMDBool(char * cmd,char * check); +char * ScanCMDRemain(char * cmd); +bool ScanCMDHex(char * cmd,char * check,Bits * result); +char * StripWord(char * cmd); + +INLINE char * upcase(char * str) { + 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; +} + + +#endif + diff --git a/include/timer.h b/include/timer.h new file mode 100644 index 00000000..a481d592 --- /dev/null +++ b/include/timer.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _TIMER_H_ +#define _TIMER_H_ +/* underlying clock rate in HZ */ +#include + +extern Bit32u LastTicks; +#define GetTicks() SDL_GetTicks() + +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 */ +TIMER_Block * TIMER_RegisterTickHandler(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); + + +#endif + diff --git a/include/video.h b/include/video.h new file mode 100644 index 00000000..25199495 --- /dev/null +++ b/include/video.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __VIDEO_H +#define __VIDEO_H + +typedef void (GFX_DrawHandler)(Bit8u * vidstart); +/* Used to reply to the renderer what size to set */ +typedef void (GFX_ResizeHandler)(Bitu * width,Bitu * height); + +struct GFX_PalEntry { + Bit8u r; + Bit8u g; + Bit8u b; + Bit8u unused; +}; + +struct GFX_Info { + Bitu width,height,bpp,pitch; +}; + +extern GFX_Info gfx_info; + +void GFX_Events(void); +void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries); +void GFX_SetDrawHandler(GFX_DrawHandler * handler); +void GFX_Resize(Bitu width,Bitu height,Bitu bpp,GFX_ResizeHandler * resize); + +void GFX_Start(void); +void GFX_Stop(void); +void GFX_SwitchFullScreen(void); + + +#endif + diff --git a/scripts/ega-switch.pl b/scripts/ega-switch.pl new file mode 100644 index 00000000..6795b458 --- /dev/null +++ b/scripts/ega-switch.pl @@ -0,0 +1,32 @@ +#!/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); diff --git a/scripts/font-switch.pl b/scripts/font-switch.pl new file mode 100644 index 00000000..72747801 --- /dev/null +++ b/scripts/font-switch.pl @@ -0,0 +1,25 @@ +#!/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); diff --git a/settings.h.cvs b/settings.h.cvs new file mode 100644 index 00000000..f7fefd0f --- /dev/null +++ b/settings.h.cvs @@ -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 \ No newline at end of file diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 00000000..0b960ea8 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,10 @@ +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 \ No newline at end of file diff --git a/src/cpu/Makefile.am b/src/cpu/Makefile.am new file mode 100644 index 00000000..5a8f26af --- /dev/null +++ b/src/cpu/Makefile.am @@ -0,0 +1,5 @@ +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 \ No newline at end of file diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp new file mode 100644 index 00000000..7a66dc7e --- /dev/null +++ b/src/cpu/callback.cpp @@ -0,0 +1,171 @@ +/* + * 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. + */ + +#include +#include + +#include "dosbox.h" +#include "callback.h" +#include "mem.h" +#include "cpu.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 + far return or and IRET +*/ + + +CallBack_Handler CallBack_Handlers[CB_MAX]; +static Bitu call_runint16,call_idle,call_default,call_runfar16; + +static Bitu illegal_handler(void) { + E_Exit("Illegal CallBack Called"); + return 1; +} + +Bitu CALLBACK_Allocate(void) { + for (Bitu i=0;(i=CB_MAX) return false; + switch (type) { + case CB_RETF: + real_writeb((Bit16u)CB_SEG,(callback<<4),(Bit8u)0xFE); //GRP 4 + real_writeb((Bit16u)CB_SEG,(callback<<4)+1,(Bit8u)0x38); //Extra Callback instruction + real_writew((Bit16u)CB_SEG,(callback<<4)+2,callback); //The immediate word + real_writeb((Bit16u)CB_SEG,(callback<<4)+4,(Bit8u)0xCB); //A RETF Instruction + break; + case CB_IRET: + real_writeb((Bit16u)CB_SEG,(callback<<4),(Bit8u)0xFE); //GRP 4 + real_writeb((Bit16u)CB_SEG,(callback<<4)+1,(Bit8u)0x38); //Extra Callback instruction + real_writew((Bit16u)CB_SEG,(callback<<4)+2,callback); //The immediate word + real_writeb((Bit16u)CB_SEG,(callback<<4)+4,(Bit8u)0xCF); //An IRET Instruction + break; + default: + E_Exit("CALLBACK:Setup:Illegal type %d",type); + + } + CallBack_Handlers[callback]=handler; + return true; +} + +void CALLBACK_Init(void) { + Bitu i; + for (i=0;i= 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);} diff --git a/src/cpu/core_16/instructions.h b/src/cpu/core_16/instructions.h new file mode 100644 index 00000000..d0a5fd9a --- /dev/null +++ b/src/cpu/core_16/instructions.h @@ -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; diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h new file mode 100644 index 00000000..2e9dd4b6 --- /dev/null +++ b/src/cpu/core_16/main.h @@ -0,0 +1,1488 @@ +/* + * 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. + */ + +bool repcheck; +restart: + switch(Fetchb()) { + case 0x00: /* ADD Eb,Gb */ + RMEbGb(ADDB);break; + case 0x01: /* ADD Ew,Gw */ + RMEwGw(ADDW);break; + case 0x02: /* ADD Gb,Eb */ + RMGbEb(ADDB);break; + case 0x03: /* ADD Gw,Ew */ + RMGwEw(ADDW);break; + case 0x04: /* ADD AL,Ib */ + ALIb(ADDB);break; + case 0x05: /* ADD AX,Iw */ + AXIw(ADDW);break; + case 0x06: /* PUSH ES */ + Push_16(Segs[es].value);break; + case 0x07: /* POP ES */ + SetSegment_16(es,Pop_16());break; + case 0x08: /* OR Eb,Gb */ + RMEbGb(ORB);break; + case 0x09: /* OR Ew,Gw */ + RMEwGw(ORW);break; + case 0x0a: /* OR Gb,Eb */ + RMGbEb(ORB);break; + case 0x0b: /* OR Gw,Ew */ + RMGwEw(ORW);break; + case 0x0c: /* OR AL,Ib */ + ALIb(ORB);break; + case 0x0d: /* OR AX,Iw */ + AXIw(ORW);break; + case 0x0e: /* PUSH CS */ + Push_16(Segs[cs].value);break; + case 0x0f: /* 2 byte opcodes*/ + #include "prefix_of.h" + break; + case 0x10: /* ADC Eb,Gb */ + RMEbGb(ADCB);break; + case 0x11: /* ADC Ew,Gw */ + RMEwGw(ADCW);break; + case 0x12: /* ADC Gb,Eb */ + RMGbEb(ADCB);break; + case 0x13: /* ADC Gw,Ew */ + RMGwEw(ADCW);break; + case 0x14: /* ADC AL,Ib */ + ALIb(ADCB);break; + case 0x15: /* ADC AX,Iw */ + AXIw(ADCW);break; + case 0x16: /* PUSH SS */ + Push_16(Segs[ss].value);break; + case 0x17: /* POP SS */ + SetSegment_16(ss,Pop_16());break; + case 0x18: /* SBB Eb,Gb */ + RMEbGb(SBBB);break; + case 0x19: /* SBB Ew,Gw */ + RMEwGw(SBBW);break; + case 0x1a: /* SBB Gb,Eb */ + RMGbEb(SBBB);break; + case 0x1b: /* SBB Gw,Ew */ + RMGwEw(SBBW);break; + case 0x1c: /* SBB AL,Ib */ + ALIb(SBBB);break; + case 0x1d: /* SBB AX,Iw */ + AXIw(SBBW);break; + case 0x1e: /* PUSH DS */ + Push_16(Segs[ds].value);break; + case 0x1f: /* POP DS */ + SetSegment_16(ds,Pop_16());break; + case 0x20: /* AND Eb,Gb */ + RMEbGb(ANDB);break; + case 0x21: /* AND Ew,Gw */ + RMEwGw(ANDW);break; + case 0x22: /* AND Gb,Eb */ + RMGbEb(ANDB);break; + case 0x23: /* AND Gw,Ew */ + RMGwEw(ANDW);break; + case 0x24: /* AND AL,Ib */ + ALIb(ANDB);break; + case 0x25: /* AND AX,Iw */ + AXIw(ANDW);break; + case 0x26: /* SEG ES: */ + SegPrefix(es);break; + case 0x27: /* DAA */ + if (((reg_al & 0x0F)>0x09) || get_AF()) { + reg_al+=0x06; + flags.af=true; + } else { + flags.af=false; + } + flags.cf=get_CF(); + if ((reg_al > 0x9F) || flags.cf) { + reg_al+=0x60; + flags.cf=true; + } + flags.sf=(reg_al>>7)>0; + flags.zf=(reg_al==0); + flags.type=t_UNKNOWN; + break; + case 0x28: /* SUB Eb,Gb */ + RMEbGb(SUBB);break; + case 0x29: /* SUB Ew,Gw */ + RMEwGw(SUBW);break; + case 0x2a: /* SUB Gb,Eb */ + RMGbEb(SUBB);break; + case 0x2b: /* SUB Gw,Ew */ + RMGwEw(SUBW);break; + case 0x2c: /* SUB AL,Ib */ + ALIb(SUBB);break; + case 0x2d: /* SUB AX,Iw */ + AXIw(SUBW);break; + case 0x2e: /* SEG CS: */ + SegPrefix(cs);break; + case 0x2f: /* DAS */ + if (((reg_al & 0x0f) > 9) || get_AF()) { + reg_al-=6; + flags.af=true; + } else { + flags.af=false; + } + if ((reg_al>0x9f) || get_CF()) { + reg_al-=0x60; + flags.cf=true; + } else { + flags.cf=false; + } + flags.type=t_UNKNOWN; + break; + case 0x30: /* XOR Eb,Gb */ + RMEbGb(XORB);break; + case 0x31: /* XOR Ew,Gw */ + RMEwGw(XORW);break; + case 0x32: /* XOR Gb,Eb */ + RMGbEb(XORB);break; + case 0x33: /* XOR Gw,Ew */ + RMGwEw(XORW);break; + case 0x34: /* XOR AL,Ib */ + ALIb(XORB);break; + case 0x35: /* XOR AX,Iw */ + AXIw(XORW);break; + case 0x36: /* SEG SS: */ + SegPrefix(ss);break; + case 0x37: /* AAA */ + if (get_AF() || ((reg_al & 0xf) > 9)) + { + reg_al += 6; + reg_ah += 1; + flags.af=true; + flags.cf=true; + } else { + flags.af=false; + flags.cf=false; + } + reg_al &= 0x0F; + flags.type=t_UNKNOWN; + break; + case 0x38: /* CMP Eb,Gb */ + RMEbGb(CMPB);break; + case 0x39: /* CMP Ew,Gw */ + RMEwGw(CMPW);break; + case 0x3a: /* CMP Gb,Eb */ + RMGbEb(CMPB);break; + case 0x3b: /* CMP Gw,Ew */ + RMGwEw(CMPW);break; + case 0x3c: /* CMP AL,Ib */ + ALIb(CMPB);break; + case 0x3d: /* CMP AX,Iw */ + AXIw(CMPW);break; + case 0x3e: /* SEG DS: */ + SegPrefix(ds);break; + case 0x3f: /* AAS */ + if (((reg_al & 0x0f)>9) || get_AF()) { + reg_al=(reg_al-6) & 0xF; + reg_ah--; + flags.af=flags.cf=true; + } else { + flags.af=flags.cf=false; + } + flags.type=t_UNKNOWN; + break; + case 0x40: /* INC AX */ + INCW(reg_ax,LoadRw,SaveRw);break; + case 0x41: /* INC CX */ + INCW(reg_cx,LoadRw,SaveRw);break; + case 0x42: /* INC DX */ + INCW(reg_dx,LoadRw,SaveRw);break; + case 0x43: /* INC BX */ + INCW(reg_bx,LoadRw,SaveRw);break; + case 0x44: /* INC SP */ + INCW(reg_sp,LoadRw,SaveRw);break; + case 0x45: /* INC BP */ + INCW(reg_bp,LoadRw,SaveRw);break; + case 0x46: /* INC SI */ + INCW(reg_si,LoadRw,SaveRw);break; + case 0x47: /* INC DI */ + INCW(reg_di,LoadRw,SaveRw);break; + case 0x48: /* DEC AX */ + DECW(reg_ax,LoadRw,SaveRw);break; + case 0x49: /* DEC CX */ + DECW(reg_cx,LoadRw,SaveRw);break; + case 0x4a: /* DEC DX */ + DECW(reg_dx,LoadRw,SaveRw);break; + case 0x4b: /* DEC BX */ + DECW(reg_bx,LoadRw,SaveRw);break; + case 0x4c: /* DEC SP */ + DECW(reg_sp,LoadRw,SaveRw);break; + case 0x4d: /* DEC BP */ + DECW(reg_bp,LoadRw,SaveRw);break; + case 0x4e: /* DEC SI */ + DECW(reg_si,LoadRw,SaveRw);break; + case 0x4f: /* DEC DI */ + DECW(reg_di,LoadRw,SaveRw);break; + case 0x50: /* PUSH AX */ + Push_16(reg_ax);break; + case 0x51: /* PUSH CX */ + Push_16(reg_cx);break; + case 0x52: /* PUSH DX */ + Push_16(reg_dx);break; + case 0x53: /* PUSH BX */ + Push_16(reg_bx);break; + case 0x54: /* PUSH SP */ +//TODO Check if this is correct i think it's SP+2 or something + Push_16(reg_sp);break; + case 0x55: /* PUSH BP */ + Push_16(reg_bp);break; + case 0x56: /* PUSH SI */ + Push_16(reg_si);break; + case 0x57: /* PUSH DI */ + Push_16(reg_di);break; + case 0x58: /* POP AX */ + reg_ax=Pop_16();break; + case 0x59: /* POP CX */ + reg_cx=Pop_16();break; + case 0x5a: /* POP DX */ + reg_dx=Pop_16();break; + case 0x5b: /* POP BX */ + reg_bx=Pop_16();break; + case 0x5c: /* POP SP */ + reg_sp=Pop_16();break; + case 0x5d: /* POP BP */ + reg_bp=Pop_16();break; + case 0x5e: /* POP SI */ + reg_si=Pop_16();break; + case 0x5f: /* POP DI */ + reg_di=Pop_16();break; + case 0x60: /* PUSHA */ + Push_16(reg_ax);Push_16(reg_cx);Push_16(reg_dx);Push_16(reg_bx); + Push_16(reg_sp);Push_16(reg_bp);Push_16(reg_si);Push_16(reg_di); + break; + case 0x61: /* POPA */ + reg_di=Pop_16();reg_si=Pop_16();reg_bp=Pop_16();Pop_16();//Don't save SP + reg_bx=Pop_16();reg_dx=Pop_16();reg_cx=Pop_16();reg_ax=Pop_16(); + break; + case 0x62: /* BOUND */ + { + Bit16s bound_min, bound_max; + GetRMrw;GetEAa; + bound_min=LoadMw(eaa); + bound_max=LoadMw(eaa+2); + if ( (*rmrw < bound_min) || (*rmrw > bound_max) ) { + INTERRUPT(5); + } + } + break; + case 0x63: /* ARPL */ + NOTDONE;break; +#ifdef CPU_386 + case 0x64: /* SEG FS: */ + SegPrefix(fs);break; + case 0x65: /* SEG GS: */ + SegPrefix(gs);break; + case 0x66: /* Operand Size Prefix */ + #include "prefix_66.h" + break; + case 0x67: /* Address Size Prefix */ + NOTDONE; + break; +#endif + case 0x68: /* PUSH Iw */ + Push_16(Fetchw());break; + case 0x69: /* IMUL Gw,Ew,Iw */ + { + GetRMrw; + Bit32s res; + if (rm >= 0xc0 ) {GetEArw;res=(Bit32s)(*earws) * (Bit32s)Fetchws();} + else {GetEAa;res=(Bit32s)LoadMws(eaa) * (Bit32s)Fetchws();} + *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 0x6a: /* PUSH Ib */ + Push_16(Fetchbs());break; + case 0x6b: /* IMUL Gw,Ew,Ib */ + { + GetRMrw;Bit32s res; + if (rm >= 0xc0 ) {GetEArw;res=(Bit32s)(*earws) * (Bit32s)Fetchbs();} + else {GetEAa;res=(Bit32s)LoadMws(eaa) * (Bit32s)Fetchbs();} + *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 0x6c: /* INSB */ + { + stringDI; + SaveMb(to,IO_Read(reg_dx)); + if (flags.df) reg_di--; else reg_di++; + break; + } + case 0x6d: /* INSW */ + { + stringDI; + SaveMb(to,IO_Read(reg_dx)); + SaveMb((to+1),IO_Read(reg_dx+1)); + if (flags.df) reg_di-=2; else reg_di+=2; + break; + } + case 0x6e: /* OUTSB */ + { + stringSI; + IO_Write(reg_dx,LoadMb(from)); + if (flags.df) reg_si--; else reg_si++; + break; + } + case 0x6f: /* OUTSW */ + { + stringSI; + IO_Write(reg_dx,LoadMb(from)); + IO_Write(reg_dx+1,LoadMb(from+1)); + if (flags.df) reg_si-=2; else reg_si+=2; + break; + } + case 0x70: /* JO */ + JumpSIb(get_OF());break; + case 0x71: /* JNO */ + JumpSIb(!get_OF());break; + case 0x72: /* JB */ + JumpSIb(get_CF());break; + case 0x73: /* JNB */ + JumpSIb(!get_CF());break; + case 0x74: /* JZ */ + JumpSIb(get_ZF());break; + case 0x75: /* JNZ */ + JumpSIb(!get_ZF()); break; + case 0x76: /* JBE */ + JumpSIb(get_CF() || get_ZF());break; + case 0x77: /* JNBE */ + JumpSIb(!get_CF() && !get_ZF());break; + case 0x78: /* JS */ + JumpSIb(get_SF());break; + case 0x79: /* JNS */ + JumpSIb(!get_SF());break; + case 0x7a: /* JP */ + JumpSIb(get_PF());break; + case 0x7b: /* JNP */ + JumpSIb(!get_PF());break; + case 0x7c: /* JL */ + JumpSIb(get_SF() != get_OF());break; + case 0x7d: /* JNL */ + JumpSIb(get_SF() == get_OF());break; + case 0x7e: /* JLE */ + JumpSIb(get_ZF() || (get_SF() != get_OF()));break; + case 0x7f: /* JNLE */ + JumpSIb((get_SF() == get_OF()) && !get_ZF());break; + case 0x80: /* Grpl Eb,Ib */ + case 0x82: /* Grpl Eb,Ib Mirror instruction*/ + { + GetRM; + if (rm>= 0xc0) { + GetEArb;Bit8u ib=Fetchb(); + switch (rm & 0x38) { + case 0x00:ADDB(*earb,ib,LoadRb,SaveRb);break; + case 0x08: ORB(*earb,ib,LoadRb,SaveRb);break; + case 0x10:ADCB(*earb,ib,LoadRb,SaveRb);break; + case 0x18:SBBB(*earb,ib,LoadRb,SaveRb);break; + case 0x20:ANDB(*earb,ib,LoadRb,SaveRb);break; + case 0x28:SUBB(*earb,ib,LoadRb,SaveRb);break; + case 0x30:XORB(*earb,ib,LoadRb,SaveRb);break; + case 0x38:CMPB(*earb,ib,LoadRb,SaveRb);break; + } + } else { + GetEAa;Bit8u ib=Fetchb(); + switch (rm & 0x38) { + case 0x00:ADDB(eaa,ib,LoadMb,SaveMb);break; + case 0x08: ORB(eaa,ib,LoadMb,SaveMb);break; + case 0x10:ADCB(eaa,ib,LoadMb,SaveMb);break; + case 0x18:SBBB(eaa,ib,LoadMb,SaveMb);break; + case 0x20:ANDB(eaa,ib,LoadMb,SaveMb);break; + case 0x28:SUBB(eaa,ib,LoadMb,SaveMb);break; + case 0x30:XORB(eaa,ib,LoadMb,SaveMb);break; + case 0x38:CMPB(eaa,ib,LoadMb,SaveMb);break; + } + } + break; + } + case 0x81: /* Grpl Ew,Iw */ + { + GetRM; + if (rm>= 0xc0) { + GetEArw;Bit16u iw=Fetchw(); + switch (rm & 0x38) { + case 0x00:ADDW(*earw,iw,LoadRw,SaveRw);break; + case 0x08: ORW(*earw,iw,LoadRw,SaveRw);break; + case 0x10:ADCW(*earw,iw,LoadRw,SaveRw);break; + case 0x18:SBBW(*earw,iw,LoadRw,SaveRw);break; + case 0x20:ANDW(*earw,iw,LoadRw,SaveRw);break; + case 0x28:SUBW(*earw,iw,LoadRw,SaveRw);break; + case 0x30:XORW(*earw,iw,LoadRw,SaveRw);break; + case 0x38:CMPW(*earw,iw,LoadRw,SaveRw);break; + } + } else { + GetEAa;Bit16u iw=Fetchw(); + switch (rm & 0x38) { + case 0x00:ADDW(eaa,iw,LoadMw,SaveMw);break; + case 0x08: ORW(eaa,iw,LoadMw,SaveMw);break; + case 0x10:ADCW(eaa,iw,LoadMw,SaveMw);break; + case 0x18:SBBW(eaa,iw,LoadMw,SaveMw);break; + case 0x20:ANDW(eaa,iw,LoadMw,SaveMw);break; + case 0x28:SUBW(eaa,iw,LoadMw,SaveMw);break; + case 0x30:XORW(eaa,iw,LoadMw,SaveMw);break; + case 0x38:CMPW(eaa,iw,LoadMw,SaveMw);break; + } + } + break; + } + case 0x83: /* Grpl Ew,Ix */ + { + GetRM; + if (rm>= 0xc0) { + GetEArw;Bit16u iw=(Bit16s)Fetchbs(); + switch (rm & 0x38) { + case 0x00:ADDW(*earw,iw,LoadRw,SaveRw);break; + case 0x08: ORW(*earw,iw,LoadRw,SaveRw);break; + case 0x10:ADCW(*earw,iw,LoadRw,SaveRw);break; + case 0x18:SBBW(*earw,iw,LoadRw,SaveRw);break; + case 0x20:ANDW(*earw,iw,LoadRw,SaveRw);break; + case 0x28:SUBW(*earw,iw,LoadRw,SaveRw);break; + case 0x30:XORW(*earw,iw,LoadRw,SaveRw);break; + case 0x38:CMPW(*earw,iw,LoadRw,SaveRw);break; + } + } else { + GetEAa;Bit16u iw=(Bit16s)Fetchbs(); + switch (rm & 0x38) { + case 0x00:ADDW(eaa,iw,LoadMw,SaveMw);break; + case 0x08: ORW(eaa,iw,LoadMw,SaveMw);break; + case 0x10:ADCW(eaa,iw,LoadMw,SaveMw);break; + case 0x18:SBBW(eaa,iw,LoadMw,SaveMw);break; + case 0x20:ANDW(eaa,iw,LoadMw,SaveMw);break; + case 0x28:SUBW(eaa,iw,LoadMw,SaveMw);break; + case 0x30:XORW(eaa,iw,LoadMw,SaveMw);break; + case 0x38:CMPW(eaa,iw,LoadMw,SaveMw);break; + } + } + break; + } + case 0x84: /* TEST Eb,Gb */ + RMEbGb(TESTB);break; + case 0x85: /* TEST Ew,Gw */ + RMEwGw(TESTW);break; + case 0x86: /* XCHG Eb,Gb */ + { + GetRMrb;Bit8u oldrmrb=*rmrb; + if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;*earb=oldrmrb;} + else {GetEAa;*rmrb=LoadMb(eaa);SaveMb(eaa,oldrmrb);} + break; + } + case 0x87: /* XCHG Ew,Gw */ + { + GetRMrw;Bit16u oldrmrw=*rmrw; + if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;*earw=oldrmrw;} + else {GetEAa;*rmrw=LoadMw(eaa);SaveMw(eaa,oldrmrw);} + break; + } + case 0x88: /* MOV Eb,Gb */ + { + GetRMrb; + if (rm >= 0xc0 ) {GetEArb;*earb=*rmrb;} + else {GetEAa;SaveMb(eaa,*rmrb);} + break; + } + case 0x89: /* MOV Ew,Gw */ + { + GetRMrw; + if (rm >= 0xc0 ) {GetEArw;*earw=*rmrw;} + else {GetEAa;SaveMw(eaa,*rmrw);} + break; + } + case 0x8a: /* MOV Gb,Eb */ + { + GetRMrb; + if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;} + else {GetEAa;*rmrb=LoadMb(eaa);} + break; + } + case 0x8b: /* MOV Gw,Ew */ + { + GetRMrw; + if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;} + else {GetEAa;*rmrw=LoadMw(eaa);} + break; + } + case 0x8c: /* Mov Ew,Sw */ + { + GetRM;Bit16u val; + switch (rm & 0x38) { + case 0x00: /* MOV Ew,ES */ + val=Segs[es].value;break; + case 0x08: /* MOV Ew,CS */ + val=Segs[cs].value;break; + case 0x10: /* MOV Ew,SS */ + val=Segs[ss].value;break; + case 0x18: /* MOV Ew,DS */ + val=Segs[ds].value;break; + case 0x20: /* MOV Ew,FS */ + val=Segs[fs].value;break; + case 0x28: /* MOV Ew,GS */ + val=Segs[gs].value;break; + default: + val=0; + E_Exit("CPU:8c:Illegal RM Byte"); + } + if (rm >= 0xc0 ) {GetEArw;*earw=val;} + else {GetEAa;SaveMw(eaa,val);} + break; + } + case 0x8d: /* LEA */ + { + GetRMrw; + switch (rm & 0xC7) { + case 0x00:*rmrw=reg_bx+reg_si;break; + case 0x01:*rmrw=reg_bx+reg_di;break; + case 0x02:*rmrw=reg_bp+reg_si;break; + case 0x03:*rmrw=reg_bp+reg_di;break; + case 0x04:*rmrw=reg_si;break; + case 0x05:*rmrw=reg_di;break; + case 0x06:*rmrw=Fetchw();break; + case 0x07:*rmrw=reg_bx;break; + case 0x40:*rmrw=reg_bx+reg_si+Fetchbs();break; + case 0x41:*rmrw=reg_bx+reg_di+Fetchbs();break; + case 0x42:*rmrw=reg_bp+reg_si+Fetchbs();break; + case 0x43:*rmrw=reg_bp+reg_di+Fetchbs();break; + case 0x44:*rmrw=reg_si+Fetchbs();break; + case 0x45:*rmrw=reg_di+Fetchbs();break; + case 0x46:*rmrw=reg_bp+Fetchbs();break; + case 0x47:*rmrw=reg_bx+Fetchbs();break; + case 0x80:*rmrw=reg_bx+reg_si+Fetchw();break; + case 0x81:*rmrw=reg_bx+reg_di+Fetchw();break; + case 0x82:*rmrw=reg_bp+reg_si+Fetchw();break; + case 0x83:*rmrw=reg_bp+reg_di+Fetchw();break; + case 0x84:*rmrw=reg_si+Fetchw();break; + case 0x85:*rmrw=reg_di+Fetchw();break; + case 0x86:*rmrw=reg_bp+Fetchw();break; + case 0x87:*rmrw=reg_bx+Fetchw();break; + default: + E_Exit("CPU:8d:Illegal LEA RM Byte"); + } + break; + } + case 0x8e: /* MOV Sw,Ew */ + { + GetRM;Bit16u val; + if (rm >= 0xc0 ) {GetEArw;val=*earw;} + else {GetEAa;val=LoadMw(eaa);} + switch (rm & 0x38) { + case 0x00: /* MOV ES,Ew */ + SetSegment_16(es,val);break; + case 0x08: /* MOV CS,Ew Illegal*/ + E_Exit("CPU:Illegal MOV CS Call"); + break; + case 0x10: /* MOV SS,Ew */ + SetSegment_16(ss,val);break; + case 0x18: /* MOV DS,Ew */ + SetSegment_16(ds,val);break; + case 0x20: /* MOV FS,Ew */ + SetSegment_16(fs,val);break; + case 0x28: /* MOV GS,Ew */ + SetSegment_16(gs,val);break; + default: + E_Exit("CPU:8e:Illegal RM Byte"); + } + break; + } + case 0x8f: /* POP Ew */ + { + GetRM; + if (rm >= 0xc0 ) {GetEArw;*earw=Pop_16();} + else {GetEAa;SaveMw(eaa,Pop_16());} + break; + } + case 0x90: /* NOP */ + break; + case 0x91: /* XCHG CX,AX */ + { Bit16u temp=reg_ax;reg_ax=reg_cx;reg_cx=temp; } + break; + case 0x92: /* XCHG DX,AX */ + { Bit16u temp=reg_ax;reg_ax=reg_dx;reg_dx=temp; } + break; + case 0x93: /* XCHG BX,AX */ + { Bit16u temp=reg_ax;reg_ax=reg_bx;reg_bx=temp; } + break; + case 0x94: /* XCHG SP,AX */ + { Bit16u temp=reg_ax;reg_ax=reg_sp;reg_sp=temp; } + break; + case 0x95: /* XCHG BP,AX */ + { Bit16u temp=reg_ax;reg_ax=reg_bp;reg_bp=temp; } + break; + case 0x96: /* XCHG SI,AX */ + { Bit16u temp=reg_ax;reg_ax=reg_si;reg_si=temp; } + break; + case 0x97: /* XCHG DI,AX */ + { Bit16u temp=reg_ax;reg_ax=reg_di;reg_di=temp; } + break; + case 0x98: /* CBW */ + reg_ax=(Bit8s)reg_al;break; + case 0x99: /* CWD */ + if (reg_ax & 0x8000) reg_dx=0xffff; + else reg_dx=0; + break; + case 0x9a: /* CALL Ap */ + { + Bit16u newip=Fetchw();Bit16u newcs=Fetchw(); + Push_16(Segs[cs].value);Push_16(GETIP); + SetSegment_16(cs,newcs);SETIP(newip); + break; + } + case 0x9b: /* WAIT */ + break; /* No waiting here */ + case 0x9c: /* PUSHF */ + { + Bit16u 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_16(pflags); + break; + } + case 0x9d: /* POPF */ + { + Bit16u bits=Pop_16(); + Save_Flagsw(bits); + break; + } + case 0x9e: /* SAHF */ + flags.of =get_OF(); + flags.type=t_UNKNOWN; + flags.cf =(reg_ah & 0x001)!=0;flags.pf =(reg_ah & 0x004)!=0; + flags.af =(reg_ah & 0x010)!=0;flags.zf =(reg_ah & 0x040)!=0; + flags.sf =(reg_ah & 0x080)!=0; + break; + case 0x9f: /* LAHF */ + { + reg_ah=(get_CF() << 0) | (get_PF() << 2) | (get_AF() << 4) | + (get_ZF() << 6) | (get_SF() << 7); + break; + } + case 0xa0: /* MOV AL,Ob */ + if (segprefix_on) { + reg_al=LoadMb(segprefix_base+Fetchw()); + SegPrefixReset; + } else { + reg_al=LoadMb(SegBase(ds)+Fetchw()); + } + break; + case 0xa1: /* MOV AX,Ow */ + if (segprefix_on) { + reg_ax=LoadMw(segprefix_base+Fetchw()); + SegPrefixReset; + } else { + reg_ax=LoadMw(SegBase(ds)+Fetchw()); + } + break; + case 0xa2: /* MOV Ob,AL */ + if (segprefix_on) { + SaveMb((segprefix_base+Fetchw()),reg_al); + SegPrefixReset; + } else { + SaveMb((SegBase(ds)+Fetchw()),reg_al); + } + break; + case 0xa3: /* MOV Ow,AX */ + if (segprefix_on) { + SaveMw((segprefix_base+Fetchw()),reg_ax); + SegPrefixReset; + } else { + SaveMw((SegBase(ds)+Fetchw()),reg_ax); + } + break; + case 0xa4: /* MOVSB */ + { + stringSI;stringDI; + SaveMb(to,LoadMb(from));; + if (flags.df) { reg_si--;reg_di--; } + else {reg_si++;reg_di++;} + break; + } + case 0xa5: /* MOVSW */ + { + stringSI;stringDI; + SaveMw(to,LoadMw(from)); + if (flags.df) { reg_si-=2;reg_di-=2; } + else {reg_si+=2;reg_di+=2;} + break; + } + case 0xa6: /* CMPSB */ + { + stringSI;stringDI; + CMPB(from,LoadMb(to),LoadMb,0); + if (flags.df) { reg_si--;reg_di--; } + else {reg_si++;reg_di++;} + break; + } + case 0xa7: /* CMPSW */ + { + stringSI;stringDI; + CMPW(from,LoadMw(to),LoadMw,0); + if (flags.df) { reg_si-=2;reg_di-=2; } + else {reg_si+=2;reg_di+=2;} + break; + } + case 0xa8: /* TEST AL,Ib */ + ALIb(TESTB);break; + case 0xa9: /* TEST AX,Iw */ + AXIw(TESTW);break; + case 0xaa: /* STOSB */ + { + stringDI; + SaveMb(to,reg_al); + if (flags.df) { reg_di--; } + else {reg_di++;} + break; + } + case 0xab: /* STOSW */ + { + stringDI; + SaveMw(to,reg_ax); + if (flags.df) { reg_di-=2; } + else {reg_di+=2;} + break; + } + case 0xac: /* LODSB */ + { + stringSI; + reg_al=LoadMb(from); + if (flags.df) { reg_si--; } + else {reg_si++;} + break; + } + case 0xad: /* LODSW */ + { + stringSI; + reg_ax=LoadMw(from); + if (flags.df) { reg_si-=2;} + else {reg_si+=2;} + break; + } + case 0xae: /* SCASB */ + { + stringDI; + CMPB(reg_al,LoadMb(to),LoadRb,0); + if (flags.df) { reg_di--; } + else {reg_di++;} + break; + } + case 0xaf: /* SCASW */ + { + stringDI; + CMPW(reg_ax,LoadMw(to),LoadRw,0); + if (flags.df) { reg_di-=2; } + else {reg_di+=2;} + break; + } + case 0xb0: /* MOV AL,Ib */ + reg_al=Fetchb();break; + case 0xb1: /* MOV CL,Ib */ + reg_cl=Fetchb();break; + case 0xb2: /* MOV DL,Ib */ + reg_dl=Fetchb();break; + case 0xb3: /* MOV BL,Ib */ + reg_bl=Fetchb();break; + case 0xb4: /* MOV AH,Ib */ + reg_ah=Fetchb();break; + case 0xb5: /* MOV CH,Ib */ + reg_ch=Fetchb();break; + case 0xb6: /* MOV DH,Ib */ + reg_dh=Fetchb();break; + case 0xb7: /* MOV BH,Ib */ + reg_bh=Fetchb();break; + case 0xb8: /* MOV AX,Iw */ + reg_ax=Fetchw();break; + case 0xb9: /* MOV CX,Iw */ + reg_cx=Fetchw();break; + case 0xba: /* MOV DX,Iw */ + reg_dx=Fetchw();break; + case 0xbb: /* MOV BX,Iw */ + reg_bx=Fetchw();break; + case 0xbc: /* MOV SP,Iw */ + reg_sp=Fetchw();break; + case 0xbd: /* MOV BP.Iw */ + reg_bp=Fetchw();break; + case 0xbe: /* MOV SI,Iw */ + reg_si=Fetchw();break; + case 0xbf: /* MOV DI,Iw */ + reg_di=Fetchw();break; + case 0xc0: /* GRP2 Eb,Ib */ + GRP2B(Fetchb());break; + case 0xc1: /* GRP2 Ew,Ib */ + GRP2W(Fetchb());break; + case 0xc2: /* RETN Iw */ + { + Bit16u addsp=Fetchw(); + SETIP(Pop_16());reg_sp+=addsp; + break; + } + case 0xc3: /* RETN */ + SETIP(Pop_16()); + break; + case 0xc4: /* LES */ + { + GetRMrw;GetEAa; + *rmrw=LoadMw(eaa);SetSegment_16(es,LoadMw(eaa+2)); + break; + } + case 0xc5: /* LDS */ + { + GetRMrw;GetEAa; + *rmrw=LoadMw(eaa);SetSegment_16(ds,LoadMw(eaa+2)); + break; + } + case 0xc6: /* MOV Eb,Ib */ + { + GetRM; + if (rm>0xc0) {GetEArb;*earb=Fetchb();} + else {GetEAa;SaveMb(eaa,Fetchb());} + break; + } + case 0xc7: /* MOV EW,Iw */ + { + GetRM; + if (rm>0xc0) {GetEArw;*earw=Fetchw();} + else {GetEAa;SaveMw(eaa,Fetchw());} + break; + } + case 0xc8: /* ENTER Iw,Ib */ + { + Bit16u bytes=Fetchw();Bit8u level=Fetchb(); + Push_16(reg_bp);reg_bp=reg_sp;reg_sp-=bytes; + EAPoint reader=SegBase(ss)+reg_bp; + for (Bit8u i=1;i 0; + flags.zf=(reg_ax == 0); + //TODO PF + flags.pf=0; + } + break; + case 0xd5: /* AAD Ib */ + reg_al=reg_ah*Fetchb()+reg_al; + reg_ah=0; + flags.cf=(reg_al>=0x80); + flags.zf=(reg_al==0); + //TODO PF + flags.type=t_UNKNOWN; + break; + case 0xd6: /* Not in intel specs */ + NOTDONE; + break; + case 0xd7: /* XLAT */ + if (segprefix_on) { + reg_al=LoadMb(segprefix_base+(Bit16u)(reg_bx+reg_al)); + SegPrefixReset; + } else { + reg_al=LoadMb(SegBase(ds)+(Bit16u)(reg_bx+reg_al)); + } + break; + case 0xd8: /* FPU ESC 0 */ + case 0xd9: /* FPU ESC 1 */ + case 0xda: /* FPU ESC 2 */ + case 0xdb: /* FPU ESC 3 */ + case 0xdc: /* FPU ESC 4 */ + case 0xdd: /* FPU ESC 5 */ + case 0xde: /* FPU ESC 6 */ + case 0xdf: /* FPU ESC 7 */ + { + Bit8u rm=Fetchb(); + if (rm>=0xc0) { + FPU_ESC0_Normal(rm); + } else { + GetEAa;FPU_ESC0_EA(rm,eaa); + } + break; + } + + break; + case 0xe0: /* LOOPNZ */ + if ((--reg_cx) && !get_ZF()) ADDIPFAST(Fetchbs()); + else ADDIPFAST(1); + break; + case 0xe1: /* LOOPZ */ + if ((--reg_cx) && get_ZF()) ADDIPFAST(Fetchbs()); + else ADDIPFAST(1); + break; + case 0xe2: /* LOOP */ + if ((--reg_cx)) ADDIPFAST(Fetchbs()); + else ADDIPFAST(1); + break; + case 0xe3: /* JCXZ */ + if (!reg_cx) ADDIPFAST(Fetchbs()); + else ADDIPFAST(1); + break; + case 0xe4: /* IN AL,Ib */ + { Bit16u port=Fetchb();reg_al=IO_Read(port);} + break; + case 0xe5: /* IN AX,Ib */ + { Bit16u port=Fetchb();reg_al=IO_Read(port);reg_ah=IO_Read(port+1);} + break; + case 0xe6: /* OUT Ib,AL */ + { Bit16u port=Fetchb();IO_Write(port,reg_al);} + break; + case 0xe7: /* OUT Ib,AX */ + { Bit16u port=Fetchb();IO_Write(port,reg_al);IO_Write(port+1,reg_ah);} + break; + case 0xe8: /* CALL Jw */ + { + Bit16s newip=Fetchws(); + Push_16(GETIP); + ADDIP(newip); + break; + } + case 0xe9: /* JMP Jw */ + ADDIP(Fetchws()); + break; + case 0xea: /* JMP Ap */ + { + Bit16u newip=Fetchw(); + Bit16u newcs=Fetchw(); + SetSegment_16(cs,newcs); + SETIP(newip); + break; + } + case 0xeb: /* JMP Jb*/ + ADDIPFAST(Fetchbs()); + break; + case 0xec: /* IN AL,DX */ + reg_al=IO_Read(reg_dx); + break; + case 0xed: /* IN AX,DX */ + reg_al=IO_Read(reg_dx); + reg_ah=IO_Read(reg_dx+1); + break; + case 0xee: /* OUT DX,AL */ + IO_Write(reg_dx,reg_al); + break; + case 0xef: /* OUT DX,AX */ + IO_Write(reg_dx,reg_al); + IO_Write(reg_dx+1,reg_ah); + break; + case 0xf0: /* LOCK */ + LOG_ERROR("CPU:LOCK"); + break; + case 0xf1: /* Weird call undocumented */ + E_Exit("CPU:F1:Not Handled"); + break; + case 0xf2: /* REPNZ */ + repcheck=false; + goto repstart; + case 0xf3: /* REPZ */ + repcheck=true; + repstart: + { + EAPoint to=SegBase(es); + EAPoint from; + if (segprefix_on) { + from=(segprefix_base); + SegPrefixReset; + } else { + from=SegBase(ds); + } + Bit16s direct; + if (flags.df) direct=-1; + else direct=1; + reploop: + Bit8u repcode=Fetchb(); + switch (repcode) { + case 0x26: /* ES Prefix */ + from=SegBase(es); + goto reploop; + case 0x2e: /* CS Prefix */ + from=SegBase(cs); + goto reploop; + case 0x36: /* SS Prefix */ + from=SegBase(ss); + goto reploop; + case 0x3e: /* DS Prefix */ + from=SegBase(ds); + goto reploop; +#ifdef CPU_386 + case 0x66: + Rep_66(direct,from,to); + break; +#endif + + case 0x6c: /* REP INSB */ + { + for (Bit32u temp=reg_cx;temp>0;temp--) { + SaveMb(to,IO_Read(reg_dx)); + to+=direct; + }; + reg_di+=Bit16s(reg_cx*direct);reg_cx=0; + break; + } + case 0x6d: /* REP INSW */ + { + for (Bit32u temp=reg_cx;temp>0;temp--) { + SaveMb(to,IO_Read(reg_dx)); + SaveMb((to+1),IO_Read(reg_dx+1)); + to+=direct*2; + } + reg_di+=Bit16s(reg_cx*direct*2);reg_cx=0; + break; + } + case 0x6e: /* REP OUTSB */ + for (;reg_cx>0;reg_cx--) { + IO_Write(reg_dx,LoadMb(from+reg_si)); + reg_si+=direct; + } + break; + case 0x6f: /* REP OUTSW */ + for (;reg_cx>0;reg_cx--) { + IO_Write(reg_dx,LoadMb(from+reg_si)); + IO_Write(reg_dx+1,LoadMb(from+reg_si+1)); + reg_si+=direct*2; + } + break; + case 0xa4: /* REP MOVSB */ + for (;reg_cx>0;reg_cx--) { + SaveMb(to+reg_di,LoadMb(from+reg_si)); + reg_di+=direct; + reg_si+=direct; + } + break; + case 0xa5: /* REP MOVSW */ + for (;reg_cx>0;reg_cx--) { + SaveMw(to+reg_di,LoadMw(from+reg_si)); + reg_di+=direct*2; + reg_si+=direct*2; + } + break; + case 0xa6: /* REP CMPSB */ + if (!reg_cx) break; + for (;reg_cx>0;) { + reg_cx--; + if ((LoadMb(from+reg_si)==LoadMb(to+reg_di))!=repcheck) { + reg_di+=direct; + reg_si+=direct; + break; + } + reg_di+=direct; + reg_si+=direct; + } + CMPB(from+(reg_si-direct),LoadMb(to+(reg_di-direct)),LoadMb,0); + break; + case 0xa7: /* REP CMPSW */ + if (!reg_cx) break; + for (;reg_cx>0;) { + reg_cx--; + if ((LoadMw(from+reg_si)==LoadMw(to+reg_di))!=repcheck) { + reg_di+=direct*2; + reg_si+=direct*2; + break; + } + reg_di+=direct*2; + reg_si+=direct*2; + } + CMPW(from+(reg_si-direct*2),LoadMw(to+(reg_di-direct*2)),LoadMw,0); + break; + case 0xaa: /* REP STOSB */ + for (;reg_cx>0;reg_cx--) { + SaveMb(to+reg_di,reg_al); + reg_di+=direct; + } + break; + case 0xab: /* REP STOSW */ + for (;reg_cx>0;reg_cx--) { + SaveMw(to+reg_di,reg_ax); + reg_di+=direct*2; + } + break; + case 0xac: /* REP LODSB */ + for (;reg_cx>0;reg_cx--) { + reg_al=LoadMb(from+reg_si); + reg_si+=direct; + } + break; + case 0xad: /* REP LODSW */ + for (;reg_cx>0;reg_cx--) { + reg_ax=LoadMw(from+reg_si); + reg_si+=direct*2; + } + break; + case 0xae: /* REP SCASB */ + if (!reg_cx) break; + for (;reg_cx>0;) { + reg_cx--; + if ((reg_al==LoadMb(to+reg_di))!=repcheck) { + reg_di+=direct; + break; + } + reg_di+=direct; + } + CMPB(reg_al,LoadMb(to+(reg_di-direct)),LoadRb,0); + break; + case 0xaf: /* REP SCASW */ + if (!reg_cx) break; + for (;reg_cx>0;) { + reg_cx--; + if ((reg_ax==LoadMw(to+reg_di))!=repcheck) { + reg_di+=direct*2; + break; + } + reg_di+=direct*2; + } + CMPW(reg_ax,LoadMw(to+(reg_di-direct*2)),LoadRw,0); + break; + default: + E_Exit("Illegal REP prefix %2X",repcode); + } + break; + } + case 0xf4: /* HLT */ + break; + case 0xf5: /* CMC */ + flags.cf=!get_CF(); + if (flags.type!=t_CF) flags.prev_type=flags.type; + flags.type=t_CF; + break; + case 0xf6: /* GRP3 Eb(,Ib) */ + { + GetRM; + switch (rm & 0x38) { + case 0x00: /* TEST Eb,Ib */ + case 0x08: /* TEST Eb,Ib Undocumented*/ + { + if (rm >= 0xc0 ) {GetEArb;TESTB(*earb,Fetchb(),LoadRb,0)} + else {GetEAa;TESTB(eaa,Fetchb(),LoadMb,0);} + break; + } + case 0x10: /* NOT Eb */ + { + if (rm >= 0xc0 ) {GetEArb;*earb=~*earb;} + else {GetEAa;SaveMb(eaa,~LoadMb(eaa));} + break; + } + case 0x18: /* NEG Eb */ + { + flags.type=t_NEGb; + if (rm >= 0xc0 ) { + GetEArb;flags.var1.b=*earb;flags.result.b=0-flags.var1.b; + *earb=flags.result.b; + } else { + GetEAa;flags.var1.b=LoadMb(eaa);flags.result.b=0-flags.var1.b; + SaveMb(eaa,flags.result.b); + } + break; + } + case 0x20: /* MUL AL,Eb */ + { + flags.type=t_MUL; + if (rm >= 0xc0 ) {GetEArb;reg_ax=reg_al * (*earb);} + else {GetEAa;reg_ax=reg_al * LoadMb(eaa);} + flags.cf=flags.of=((reg_ax & 0xff00) !=0); + break; + } + case 0x28: /* IMUL AL,Eb */ + { + flags.type=t_MUL; + if (rm >= 0xc0 ) {GetEArb;reg_ax=(Bit8s)reg_al * (*earbs);} + else {GetEAa;reg_ax=((Bit8s)reg_al) * LoadMbs(eaa);} + flags.cf=flags.of=!((reg_ax & 0xff80)==0xff80 || (reg_ax & 0xff80)==0x0000); + break; + } + case 0x30: /* DIV Eb */ + { +// flags.type=t_DIV; + Bit8u val; + if (rm >= 0xc0 ) {GetEArb;val=*earb;} + else {GetEAa;val=LoadMb(eaa);} + if (val==0) {INTERRUPT(0);break;} + Bit16u quotientu=reg_ax / val; + reg_ah=(Bit8u)(reg_ax % val); + reg_al=quotientu & 0xff; + if (quotientu!=reg_al) + INTERRUPT(0); + break; + } + case 0x38: /* IDIV Eb */ + { +// flags.type=t_DIV; + Bit8s val; + if (rm >= 0xc0 ) {GetEArb;val=*earbs;} + else {GetEAa;val=LoadMbs(eaa);} + if (val==0) {INTERRUPT(0);break;} + Bit16s quotients=((Bit16s)reg_ax) / val; + reg_ah=(Bit8s)(((Bit16s)reg_ax) % val); + reg_al=quotients & 0xff; + if (quotients!=(Bit8s)reg_al) + INTERRUPT(0); + break; + } + } + break;} + case 0xf7: /* GRP3 Ew(,Iw) */ + { GetRM; + switch (rm & 0x38) { + case 0x00: /* TEST Ew,Iw */ + case 0x08: /* TEST Ew,Iw Undocumented*/ + { + if (rm >= 0xc0 ) {GetEArw;TESTW(*earw,Fetchw(),LoadRw,SaveRw);} + else {GetEAa;TESTW(eaa,Fetchw(),LoadMw,SaveMw);} + break; + } + case 0x10: /* NOT Ew */ + { + if (rm >= 0xc0 ) {GetEArw;*earw=~*earw;} + else {GetEAa;SaveMw(eaa,~LoadMw(eaa));} + break; + } + case 0x18: /* NEG Ew */ + { + flags.type=t_NEGw; + if (rm >= 0xc0 ) { + GetEArw;flags.var1.w=*earw;flags.result.w=0-flags.var1.w; + *earw=flags.result.w; + } else { + GetEAa;flags.var1.w=LoadMw(eaa);flags.result.w=0-flags.var1.w; + SaveMw(eaa,flags.result.w); + } + break; + } + case 0x20: /* MUL AX,Ew */ + { + flags.type=t_MUL;Bit32u tempu; + if (rm >= 0xc0 ) {GetEArw;tempu=reg_ax * (*earw);} + else {GetEAa;tempu=reg_ax * LoadMw(eaa);} + reg_ax=(Bit16u)(tempu & 0xffff);reg_dx=(Bit16u)(tempu >> 16); + flags.cf=flags.of=(reg_dx !=0); + break; + } + case 0x28: /* IMUL AX,Ew */ + { + flags.type=t_MUL;Bit32s temps; + if (rm >= 0xc0 ) {GetEArw;temps=((Bit16s)reg_ax) * (*earws);} + else {GetEAa;temps=((Bit16s)reg_ax) * LoadMws(eaa);} + reg_ax=Bit16u(temps & 0xffff);reg_dx=(Bit16u)(temps >> 16); + if ( (reg_dx==0xffff) && (reg_ax & 0x8000) ) { + flags.cf=flags.of=false; + } else if ( (reg_dx==0x0000) && (reg_ax<0x8000) ) { + flags.cf=flags.of=false; + } else { + flags.cf=flags.of=true; + } + break; + } + case 0x30: /* DIV Ew */ + { +// flags.type=t_DIV; + Bit16u val; + if (rm >= 0xc0 ) {GetEArw;val=*earw;} + else {GetEAa;val=LoadMw(eaa);} + if (val==0) {INTERRUPT(0);break;} + Bit32u tempu=(reg_dx<<16)|reg_ax; + Bit32u quotientu=tempu/val; + reg_dx=(Bit16u)(tempu % val); + reg_ax=(Bit16u)(quotientu & 0xffff); + if (quotientu>0xffff) + INTERRUPT(0); + break; + } + case 0x38: /* IDIV Ew */ + { +// flags.type=t_DIV; + Bit16s val; + if (rm >= 0xc0 ) {GetEArw;val=*earws;} + else {GetEAa;val=LoadMws(eaa);} + if (val==0) {INTERRUPT(0);break;} + Bit32s temps=(reg_dx<<16)|reg_ax; + Bit32s quotients=temps/val; + reg_dx=(Bit16s)(temps % val); + reg_ax=(Bit16s)quotients; + if (quotients!=(Bit16s)reg_ax) + INTERRUPT(0); + break; + } + + } + break; + } + case 0xf8: /* CLC */ + flags.cf=false; + if (flags.type!=t_CF) flags.prev_type=flags.type; + flags.type=t_CF; + break; + case 0xf9: /* STC */ + flags.cf=true; + if (flags.type!=t_CF) flags.prev_type=flags.type; + flags.type=t_CF; + break; + case 0xfa: /* CLI */ + flags.intf=false; + break; + case 0xfb: /* STI */ + flags.intf=true; + if (flags.intf && PIC_IRQCheck) { + SAVEIP; + PIC_runIRQs(); + LOADIP; + }; + break; + case 0xfc: /* CLD */ + flags.df=false; + break; + case 0xfd: /* STD */ + flags.df=true; + break; + case 0xfe: /* GRP4 Eb */ + { + GetRM; + switch (rm & 0x38) { + case 0x00: /* INC Eb */ + flags.cf=get_CF();flags.type=t_INCb; + if (rm >= 0xc0 ) {GetEArb;flags.result.b=*earb+=1;} + else {GetEAa;flags.result.b=LoadMb(eaa)+1;SaveMb(eaa,flags.result.b);} + break; + case 0x08: /* DEC Eb */ + flags.cf=get_CF();flags.type=t_DECb; + if (rm >= 0xc0 ) {GetEArb;flags.result.b=*earb-=1;} + else {GetEAa;flags.result.b=LoadMb(eaa)-1;SaveMb(eaa,flags.result.b);} + break; + case 0x38: /* CallBack */ + { + Bit32u ret; + Bit16u call=Fetchw(); + SAVEIP; + if (call>3) & 7); + break; + } + break; + } + case 0xff: /* GRP5 Ew */ + { + GetRM; + switch (rm & 0x38) { + case 0x00: /* INC Ew */ + flags.cf=get_CF();flags.type=t_INCw; + if (rm >= 0xc0 ) {GetEArw;flags.result.w=*earw+=1;} + else {GetEAa;flags.result.w=LoadMw(eaa)+1;SaveMw(eaa,flags.result.w);} + break; + case 0x08: /* DEC Ew */ + flags.cf=get_CF();flags.type=t_DECw; + if (rm >= 0xc0 ) {GetEArw;flags.result.w=*earw-=1;} + else {GetEAa;flags.result.w=LoadMw(eaa)-1;SaveMw(eaa,flags.result.w);} + break; + case 0x10: /* CALL Ev */ + if (rm >= 0xc0 ) {GetEArw;Push_16(GETIP);SETIP(*earw);} + else {GetEAa;Push_16(GETIP);SETIP(LoadMw(eaa));} + break; + case 0x18: /* CALL Ep */ + { + Push_16(Segs[cs].value); + GetEAa;Push_16(GETIP); + Bit16u newip=LoadMw(eaa); + Bit16u newcs=LoadMw(eaa+2); + SetSegment_16(cs,newcs); + SETIP(newip); + } + break; + case 0x20: /* JMP Ev */ + if (rm >= 0xc0 ) {GetEArw;SETIP(*earw);} + else {GetEAa;SETIP(LoadMw(eaa));} + break; + case 0x28: /* JMP Ep */ + { + GetEAa; + Bit16u newip=LoadMw(eaa); + Bit16u newcs=LoadMw(eaa+2); + SetSegment_16(cs,newcs); + SETIP(newip); + } + break; + case 0x30: /* PUSH Ev */ + if (rm >= 0xc0 ) {GetEArw;Push_16(*earw);} + else {GetEAa;Push_16(LoadMw(eaa));} + break; + default: + E_Exit("CPU:GRP5:Illegal Call %2X",rm & 0x38); + break; + } + break; + } + } + diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h new file mode 100644 index 00000000..5af2a12f --- /dev/null +++ b/src/cpu/core_16/prefix_66.h @@ -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; + } + + diff --git a/src/cpu/core_16/prefix_66_of.h b/src/cpu/core_16/prefix_66_of.h new file mode 100644 index 00000000..676f0007 --- /dev/null +++ b/src/cpu/core_16/prefix_66_of.h @@ -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()); +} diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h new file mode 100644 index 00000000..f4024994 --- /dev/null +++ b/src/cpu/core_16/prefix_of.h @@ -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()); + } diff --git a/src/cpu/core_16/start.h b/src/cpu/core_16/start.h new file mode 100644 index 00000000..f54a1e22 --- /dev/null +++ b/src/cpu/core_16/start.h @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/* Setup the CS:IP and SS:SP Pointers */ +LOADIP; diff --git a/src/cpu/core_16/stop.h b/src/cpu/core_16/stop.h new file mode 100644 index 00000000..297949e4 --- /dev/null +++ b/src/cpu/core_16/stop.h @@ -0,0 +1,19 @@ +/* + * 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. + */ + +SAVEIP; diff --git a/src/cpu/core_16/support.h b/src/cpu/core_16/support.h new file mode 100644 index 00000000..8ee24827 --- /dev/null +++ b/src/cpu/core_16/support.h @@ -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; \ +// } \ diff --git a/src/cpu/core_16/table_ea.h b/src/cpu/core_16/table_ea.h new file mode 100644 index 00000000..a1d86559 --- /dev/null +++ b/src/cpu/core_16/table_ea.h @@ -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<=8) return false; + else return (flags.var1.b >> (8-flags.var2.b)) & 1; + case t_SHLw: + if (flags.var2.b>=16) return false; + else return (flags.var1.w >> (16-flags.var2.b)) & 1; + case t_SHLd: + return (flags.var1.d >> (32 - flags.var2.b)) & 0x01; + case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */ + return (flags.var1.d >> (32 - flags.var2.b)) & 0x01; + case t_DSHLd: + return (flags.var1.d >> (32 - flags.var2.b)) & 0x01; + + case t_SHRb: + return (flags.var1.b >> (flags.var2.b - 1)) & 0x01; + case t_SHRw: + return (flags.var1.w >> (flags.var2.b - 1)) & 0x01; + case t_SHRd: + return (flags.var1.d >> (flags.var2.b - 1)) & 0x01; + case t_SARb: + return (flags.var1.b >> (flags.var2.b - 1)) & 0x01; + case t_SARw: + return (flags.var1.w >> (flags.var2.b - 1)) & 0x01; + case t_SARd: + return (flags.var1.d >> (flags.var2.b - 1)) & 0x01; + case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ + return (flags.var1.d >> (flags.var2.b - 1)) & 0x01; + case t_DSHRd: + return (flags.var1.d >> (flags.var2.b - 1)) & 0x01; + case t_NEGb: + return (flags.var1.b!=0); + case t_NEGw: + return (flags.var1.w!=0); + case t_NEGd: + return (flags.var1.d!=0); + case t_ROLb: + return (flags.result.b & 1)>0; + case t_ROLw: + return (flags.result.w & 1)>0; + case t_ROLd: + return (flags.result.d & 1)>0; + case t_RORb: + return (flags.result.b & 0x80)>0; + case t_RORw: + return (flags.result.w & 0x8000)>0; + case t_RORd: + return (flags.result.d & 0x80000000)>0; + case t_RCLb: + return ((flags.var1.b >> (8-flags.var2.b))&1)>0; + case t_RCLw: + return ((flags.var1.w >> (16-flags.var2.b))&1)>0; + case t_RCLd: + return ((flags.var1.d >> (32-flags.var2.b))&1)>0; + case t_RCRb: + return ((flags.var1.b >> (flags.var2.b-1))&1)>0; + case t_RCRw: + return ((flags.var1.w >> (flags.var2.b-1))&1)>0; + case t_RCRd: + return ((flags.var1.d >> (flags.var2.b-1))&1)>0; + case t_ORb: + case t_ORw: + case t_ORd: + case t_ANDb: + case t_ANDw: + case t_ANDd: + case t_XORb: + case t_XORw: + case t_XORd: + case t_TESTb: + case t_TESTw: + case t_TESTd: + case t_DIV: + return false; + + + default: + E_Exit("get_CF Unknown %d",flags.type); + } + return 0; +} + +/* AF Adjust flag -- Set on carry from or borrow to the low order + four bits of AL; cleared otherwise. Used for decimal + arithmetic. +*/ +bool get_AF(void) { + Bitu type=flags.type; +again: + switch (type) { + case t_UNKNOWN: + case t_ROLb: + case t_RORb: + case t_RCLb: + case t_RCRb: + case t_ROLw: + case t_RORw: + case t_RCLw: + case t_RCRw: + case t_ROLd: + case t_RORd: + case t_RCLd: + case t_RCRd: + return flags.af; + case t_CF: + type=flags.prev_type; + goto again; + + case t_ADDb: + case t_ADCb: + case t_SBBb: + case t_SUBb: + case t_CMPb: + return (((flags.var1.b ^ flags.var2.b) ^ flags.result.b) & 0x10)>0; + case t_ADDw: + case t_ADCw: + case t_SBBw: + case t_SUBw: + case t_CMPw: + return (((flags.var1.w ^ flags.var2.w) ^ flags.result.w) & 0x10)>0; + case t_ADCd: + case t_ADDd: + case t_SBBd: + case t_SUBd: + case t_CMPd: + return (((flags.var1.d ^ flags.var2.d) ^ flags.result.d) & 0x10)>0; + case t_INCb: + return (flags.result.b & 0x0f) == 0; + case t_INCw: + return (flags.result.w & 0x0f) == 0; + case t_INCd: + return (flags.result.d & 0x0f) == 0; + case t_DECb: + return (flags.result.b & 0x0f) == 0x0f; + case t_DECw: + return (flags.result.w & 0x0f) == 0x0f; + case t_DECd: + return (flags.result.d & 0x0f) == 0x0f; + case t_NEGb: + return (flags.var1.b & 0x0f) > 0; + case t_NEGw: + return (flags.var1.w & 0x0f) > 0; + case t_NEGd: + return (flags.var1.d & 0x0f) > 0; + case t_ORb: + case t_ORw: + case t_ORd: + case t_ANDb: + case t_ANDw: + case t_ANDd: + case t_XORb: + case t_XORw: + case t_XORd: + case t_TESTb: + case t_TESTw: + case t_TESTd: + case t_SHLb: + case t_SHLw: + case t_SHLd: + case t_SHRb: + case t_SHRw: + case t_SHRd: + case t_SARb: + case t_SARw: + case t_DSHLw: + case t_DSHLd: + case t_DSHRw: + case t_DSHRd: + case t_DIV: + case t_MUL: + return false; /* undefined */ + default: + E_Exit("get_AF Unknown %d",flags.type); + } + return 0; +} + +/* ZF Zero Flag -- Set if result is zero; cleared otherwise. +*/ + +bool get_ZF(void) { + Bitu type=flags.type; +again: + switch (type) { + case t_UNKNOWN: + case t_ROLb: + case t_RORb: + case t_RCLb: + case t_RCRb: + case t_ROLw: + case t_RORw: + case t_RCLw: + case t_RCRw: + case t_ROLd: + case t_RORd: + case t_RCLd: + case t_RCRd: + return flags.zf; + case t_CF: + type=flags.prev_type; + goto again; + case t_ADDb: + case t_ORb: + case t_ADCb: + case t_SBBb: + case t_ANDb: + case t_XORb: + case t_SUBb: + case t_CMPb: + case t_INCb: + case t_DECb: + case t_TESTb: + case t_SHLb: + case t_SHRb: + case t_SARb: + case t_NEGb: + return (flags.result.b==0); + case t_ADDw: + case t_ORw: + case t_ADCw: + case t_SBBw: + case t_ANDw: + case t_XORw: + case t_SUBw: + case t_CMPw: + case t_INCw: + case t_DECw: + case t_TESTw: + case t_SHLw: + case t_SHRw: + case t_SARw: + case t_DSHLw: + case t_DSHRw: + case t_NEGw: + return (flags.result.w==0); + case t_ADDd: + case t_ORd: + case t_ADCd: + case t_SBBd: + case t_ANDd: + case t_XORd: + case t_SUBd: + case t_CMPd: + case t_INCd: + case t_DECd: + case t_TESTd: + case t_SHLd: + case t_SHRd: + case t_SARd: + case t_DSHLd: + case t_DSHRd: + case t_NEGd: + return (flags.result.d==0); + case t_DIV: + case t_MUL: + return false; + default: + E_Exit("get_ZF Unknown %d",flags.type); + } + return false; +} +/* SF Sign Flag -- Set equal to high-order bit of result (0 is + positive, 1 if negative). +*/ +bool get_SF(void) { + Bitu type=flags.type; +again: + switch (type) { + case t_UNKNOWN: + case t_ROLb: + case t_RORb: + case t_RCLb: + case t_RCRb: + case t_ROLw: + case t_RORw: + case t_RCLw: + case t_RCRw: + case t_ROLd: + case t_RORd: + case t_RCLd: + case t_RCRd: + return flags.sf; + case t_CF: + type=flags.prev_type; + goto again; + + case t_ADDb: + case t_ORb: + case t_ADCb: + case t_SBBb: + case t_ANDb: + case t_XORb: + case t_SUBb: + case t_CMPb: + case t_INCb: + case t_DECb: + case t_TESTb: + case t_SHLb: + case t_SHRb: + case t_SARb: + case t_NEGb: + return (flags.result.b>=0x80); + case t_ADDw: + case t_ORw: + case t_ADCw: + case t_SBBw: + case t_ANDw: + case t_XORw: + case t_SUBw: + case t_CMPw: + case t_INCw: + case t_DECw: + case t_TESTw: + case t_SHLw: + case t_SHRw: + case t_SARw: + case t_DSHLw: + case t_DSHRw: + case t_NEGw: + return (flags.result.w>=0x8000); + case t_ADDd: + case t_ORd: + case t_ADCd: + case t_SBBd: + case t_ANDd: + case t_XORd: + case t_SUBd: + case t_CMPd: + case t_INCd: + case t_DECd: + case t_TESTd: + case t_SHLd: + case t_SHRd: + case t_SARd: + case t_DSHLd: + case t_DSHRd: + case t_NEGd: + return (flags.result.d>=0x80000000); + case t_DIV: + case t_MUL: + return false; + default: + E_Exit("get_SF Unkown %d",flags.type); + } + return false; + +} +bool get_OF(void) { + Bit8u var1b7, var2b7, resultb7; + Bit16u var1w15, var2w15, resultw15; + Bit32u var1d31, var2d31, resultd31; + + Bitu type=flags.type; +again: + switch (type) { + case t_UNKNOWN: + case t_MUL: + return flags.of; + case t_CF: + type=flags.prev_type; + goto again; + case t_ADDb: + case t_ADCb: +// return (((flags.result.b) ^ (flags.var2.b)) & ((flags.result.b) ^ (flags.var1.b)) & 0x80)>0; + var1b7 = flags.var1.b & 0x80; + var2b7 = flags.var2.b & 0x80; + resultb7 = flags.result.b & 0x80; + return (var1b7 == var2b7) && (resultb7 ^ var2b7); + case t_ADDw: + case t_ADCw: +// return (((flags.result.w) ^ (flags.var2.w)) & ((flags.result.w) ^ (flags.var1.w)) & 0x8000)>0; + var1w15 = flags.var1.w & 0x8000; + var2w15 = flags.var2.w & 0x8000; + resultw15 = flags.result.w & 0x8000; + return (var1w15 == var2w15) && (resultw15 ^ var2w15); + case t_ADDd: + case t_ADCd: +//TODO fix dword Overflow + var1d31 = flags.var1.d & 0x8000; + var2d31 = flags.var2.d & 0x8000; + resultd31 = flags.result.d & 0x8000; + return (var1d31 == var2d31) && (resultd31 ^ var2d31); + case t_SBBb: + case t_SUBb: + case t_CMPb: +// return (((flags.var1.b) ^ (flags.var2.b)) & ((flags.var1.b) ^ (flags.result.b)) & 0x80)>0; + var1b7 = flags.var1.b & 0x80; + var2b7 = flags.var2.b & 0x80; + resultb7 = flags.result.b & 0x80; + return (var1b7 ^ var2b7) && (var1b7 ^ resultb7); + case t_SBBw: + case t_SUBw: + case t_CMPw: +// return (((flags.var1.w) ^ (flags.var2.w)) & ((flags.var1.w) ^ (flags.result.w)) & 0x8000)>0; + var1w15 = flags.var1.w & 0x8000; + var2w15 = flags.var2.w & 0x8000; + resultw15 = flags.result.w & 0x8000; + return (var1w15 ^ var2w15) && (var1w15 ^ resultw15); + case t_SBBd: + case t_SUBd: + case t_CMPd: + var1d31 = flags.var1.d & 0x8000; + var2d31 = flags.var2.d & 0x8000; + resultd31 = flags.result.d & 0x8000; + return (var1d31 ^ var2d31) && (var1d31 ^ resultd31); + case t_INCb: + return (flags.result.b == 0x80); + case t_INCw: + return (flags.result.w == 0x8000); + case t_INCd: + return (flags.result.d == 0x80000000); + case t_DECb: + return (flags.result.b == 0x7f); + case t_DECw: + return (flags.result.w == 0x7fff); + case t_DECd: + return (flags.result.d == 0x7fffffff); + case t_NEGb: + return (flags.var1.b == 0x80); + case t_NEGw: + return (flags.var1.w == 0x8000); + case t_NEGd: + return (flags.var1.d == 0x80000000); + case t_ROLb: + case t_RORb: + case t_RCLb: + case t_RCRb: + case t_SHLb: + if (flags.var2.b==1) return ((flags.var1.b ^ flags.result.b) & 0x80) >0; + break; + case t_ROLw: + case t_RORw: + case t_RCLw: + case t_RCRw: + case t_SHLw: + case t_DSHLw: //TODO This is euhm inccorect i think but let's keep it for now + if (flags.var2.b==1) return ((flags.var1.w ^ flags.result.w) & 0x8000) >0; + break; + case t_ROLd: + case t_RORd: + case t_RCLd: + case t_RCRd: + case t_SHLd: + case t_DSHLd: + if (flags.var2.b==1) return ((flags.var1.d ^ flags.result.d) & 0x80000000) >0; + break; + case t_SHRb: + if (flags.var2.b==1) return (flags.var1.b >= 0x80); + break; + case t_SHRw: + case t_DSHRw: //TODO + if (flags.var2.b==1) return (flags.var1.w >= 0x8000); + break; + case t_SHRd: + case t_DSHRd: //TODO + if (flags.var2.b==1) return (flags.var1.d >= 0x80000000); + break; + case t_SARb: + case t_SARw: + case t_SARd: + case t_ORb: + case t_ORw: + case t_ORd: + case t_ANDb: + case t_ANDw: + case t_ANDd: + case t_XORb: + case t_XORw: + case t_XORd: + case t_TESTb: + case t_TESTw: + case t_TESTd: + case t_DIV: + return false; + default: + E_Exit("get_OF Unkown %d",flags.type); + } + return false; +} + +static bool parity_lookup[256] = { + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 + }; + +bool get_PF(void) { + switch (flags.type) { + case t_UNKNOWN: + return flags.pf; + default: + return (parity_lookup[flags.result.b]);; + }; + return false; +} + + diff --git a/src/cpu/modrm.cpp b/src/cpu/modrm.cpp new file mode 100644 index 00000000..56a695eb --- /dev/null +++ b/src/cpu/modrm.cpp @@ -0,0 +1,210 @@ +/* + * 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. + */ + +#include "cpu.h" + + +Bit8u * lookupRMregb[]= +{ + ®_al,®_al,®_al,®_al,®_al,®_al,®_al,®_al, + ®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl, + ®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl, + ®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl, + ®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah, + ®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch, + ®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh, + ®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh, + + ®_al,®_al,®_al,®_al,®_al,®_al,®_al,®_al, + ®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl, + ®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl, + ®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl, + ®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah, + ®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch, + ®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh, + ®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh, + + ®_al,®_al,®_al,®_al,®_al,®_al,®_al,®_al, + ®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl, + ®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl, + ®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl, + ®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah, + ®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch, + ®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh, + ®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh, + + ®_al,®_al,®_al,®_al,®_al,®_al,®_al,®_al, + ®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl, + ®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl, + ®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl, + ®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah, + ®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch, + ®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh, + ®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh +}; + +Bit16u * lookupRMregw[]={ + ®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax, + ®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx, + ®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx, + ®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx, + ®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp, + ®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp, + ®_si,®_si,®_si,®_si,®_si,®_si,®_si,®_si, + ®_di,®_di,®_di,®_di,®_di,®_di,®_di,®_di, + + ®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax, + ®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx, + ®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx, + ®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx, + ®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp, + ®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp, + ®_si,®_si,®_si,®_si,®_si,®_si,®_si,®_si, + ®_di,®_di,®_di,®_di,®_di,®_di,®_di,®_di, + + ®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax, + ®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx, + ®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx, + ®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx, + ®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp, + ®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp, + ®_si,®_si,®_si,®_si,®_si,®_si,®_si,®_si, + ®_di,®_di,®_di,®_di,®_di,®_di,®_di,®_di, + + ®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax, + ®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx, + ®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx, + ®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx, + ®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp, + ®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp, + ®_si,®_si,®_si,®_si,®_si,®_si,®_si,®_si, + ®_di,®_di,®_di,®_di,®_di,®_di,®_di,®_di +}; + +Bit32u * lookupRMregd[256]={ + ®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax, + ®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx, + ®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx, + ®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx, + ®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp, + ®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp, + ®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi, + ®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi, + + ®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax, + ®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx, + ®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx, + ®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx, + ®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp, + ®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp, + ®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi, + ®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi, + + ®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax, + ®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx, + ®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx, + ®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx, + ®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp, + ®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp, + ®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi, + ®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi, + + ®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax, + ®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx, + ®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx, + ®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx, + ®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp, + ®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp, + ®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi, + ®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi +}; + + +Bit8u * lookupRMEAregb[256]={ +/* 12 lines of 16*0 should give nice errors when used */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, + ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, + ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, + ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, + ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, + ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, + ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, + ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh +}; + +Bit16u * lookupRMEAregw[256]={ +/* 12 lines of 16*0 should give nice errors when used */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, + ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, + ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, + ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, + ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, + ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, + ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, + ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di +}; + +Bit32u * lookupRMEAregd[256]={ +/* 12 lines of 16*0 should give nice errors when used */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, + ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, + ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, + ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, + ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, + ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, + ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, + ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi +}; + + diff --git a/src/cpu/modrm.h b/src/cpu/modrm.h new file mode 100644 index 00000000..ad0da0d4 --- /dev/null +++ b/src/cpu/modrm.h @@ -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. + */ + +extern Bit8u * lookupRMregb[]; +extern Bit16u * lookupRMregw[]; +extern Bit32u * lookupRMregd[]; +extern Bit8u * lookupRMEAregb[256]; +extern Bit16u * lookupRMEAregw[256]; +extern Bit32u * lookupRMEAregd[256]; + +#define GetRM \ + Bit8u rm=Fetchb(); + +#define Getrb \ + Bit8u * rmrb; \ + rmrb=lookupRMregb[rm]; + +#define Getrw \ + Bit16u * rmrw; \ + rmrw=lookupRMregw[rm]; + +#define Getrd \ + Bit32u * rmrd; \ + rmrd=lookupRMregd[rm]; + + +#define GetRMrb \ + GetRM; \ + Getrb; + +#define GetRMrw \ + GetRM; \ + Getrw; + +#define GetRMrd \ + GetRM; \ + Getrd; + + +#define GetEArb \ + union { \ + Bit8u * earb; \ + Bit8s * earbs; \ + }; \ + earb=lookupRMEAregb[rm]; + +#define GetEArw \ + union { \ + Bit16u * earw; \ + Bit16s * earws; \ + }; \ + earw=lookupRMEAregw[rm]; + +#define GetEArd \ + union { \ + Bit32u * eard; \ + Bit32s * eards; \ + }; \ + eard=lookupRMEAregd[rm]; + + diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp new file mode 100644 index 00000000..6d02df7d --- /dev/null +++ b/src/cpu/slow_16.cpp @@ -0,0 +1,120 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "mem.h" +#include "cpu.h" +#include "inout.h" +#include "callback.h" +#include "pic.h" +#include "fpu.h" + + +typedef PhysPt EAPoint; + +#define SegBase(seg) Segs[seg].phys + +#define LoadMb(off) mem_readb(off) +#define LoadMw(off) mem_readw(off) +#define LoadMd(off) mem_readd(off) + +#define LoadMbs(off) (Bit8s)(LoadMb(off)) +#define LoadMws(off) (Bit16s)(LoadMw(off)) +#define LoadMds(off) (Bit32s)(LoadMd(off)) + +#define SaveMb(off,val) mem_writeb(off,val) +#define SaveMw(off,val) mem_writew(off,val) +#define SaveMd(off,val) mem_writed(off,val) + + +/* +typedef HostOff EAPoint; + +#define SegBase(seg) Segs[seg].host + +#define LoadMb(off) readb(off) +#define LoadMw(off) readw(off) +#define LoadMd(off) readd(off) + +#define LoadMbs(off) (Bit8s)(LoadMb(off)) +#define LoadMws(off) (Bit16s)(LoadMw(off)) +#define LoadMds(off) (Bit32s)(LoadMd(off)) + +#define SaveMb(off,val) writeb(off,val) +#define SaveMw(off,val) writew(off,val) +#define SaveMd(off,val) writed(off,val) + +*/ + + +#define LoadRb(reg) reg +#define LoadRw(reg) reg +#define LoadRd(reg) reg + +#define SaveRb(reg,val) reg=val +#define SaveRw(reg,val) reg=val +#define SaveRd(reg,val) reg=val + +extern Bitu cycle_count; + +#define CPU_386 +//TODO Change name +#define FULLFLAGS + + +#include "core_16/support.h" +static Bitu CPU_Real_16_Slow_Decode_Special(Bitu count); +static Bitu CPU_Real_16_Slow_Decode(Bitu count) { +#include "core_16/start.h" + while (count) { +#ifdef C_DEBUG + cycle_count++; +#endif + count--; + #include "core_16/main.h" + } + #include "core_16/stop.h" + return CBRET_NONE; +} + +static Bitu CPU_Real_16_Slow_Decode_Special(Bitu count) { + while (count>0) { + if (flags.tf) { + Interrupt(3); + cpudecoder=&CPU_Real_16_Slow_Decode; + return CBRET_NONE; + } + CPU_Real_16_Slow_Decode(1); + if (!flags.tf) { + cpudecoder=&CPU_Real_16_Slow_Decode; + return CBRET_NONE; + }; + count--; + } + + return CBRET_NONE; +} + +void CPU_Real_16_Slow_Start(void) { + + lookupEATable=&GetEA_16_n; + segprefix_base=0; + segprefix_on=false; + cpudecoder=&CPU_Real_16_Slow_Decode; + +}; diff --git a/src/debug/Makefile.am b/src/debug/Makefile.am new file mode 100644 index 00000000..a939db12 --- /dev/null +++ b/src/debug/Makefile.am @@ -0,0 +1,5 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include + +EXTRA_DIST = debug_win32.cpp +noinst_LIBRARIES = libdebug.a +libdebug_a_SOURCES = debug.cpp debug_gui.cpp debug_disasm.cpp debug_inc.h disasm_tables.h \ No newline at end of file diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp new file mode 100644 index 00000000..332eb722 --- /dev/null +++ b/src/debug/debug.cpp @@ -0,0 +1,257 @@ +/* + * 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. + */ + + +#include +#include + +#include "dosbox.h" +#ifdef C_DEBUG +#include "debug.h" +#include "cpu.h" +#include "video.h" +#include "pic.h" +#include "keyboard.h" +#include "cpu.h" +#include "callback.h" +#include "inout.h" +#include "mixer.h" +#include "debug_inc.h" + + +#ifdef WIN32 +void WIN32_Console(); +#endif + +static struct { + Bit32u eax,ebx,ecx,edx,esi,edi,ebp,esp,eip; +} oldregs; + + +static Segment oldsegs[6]; +static Flag_Info oldflags; +DBGBlock dbg; +static char input_line[256]; +static Bitu input_count; +Bitu cycle_count; +static bool debugging; +static void SetColor(bool test) { + if (test) { + if (has_colors()) { wattrset(dbg.win_reg,COLOR_PAIR(PAIR_BYELLOW_BLACK));} + } else { + if (has_colors()) { wattrset(dbg.win_reg,0);} + } +} + +enum { BKPNT_REALMODE,BKPNT_PHYSICAL }; + +struct BreakPoint { + PhysPt location; + Bit8u olddata; + Bit16u seg; + Bit16u off_16; + Bit32u off_32; + Bit8u type; + bool enabled; + bool active; +}; + +static std::list BPoints; + + +static void DrawRegisters(void) { + /* Main Registers */ + SetColor(reg_eax!=oldregs.eax);oldregs.eax=reg_eax;mvwprintw (dbg.win_reg,0,4,"%08X",reg_eax); + SetColor(reg_ebx!=oldregs.ebx);oldregs.ebx=reg_ebx;mvwprintw (dbg.win_reg,1,4,"%08X",reg_ebx); + SetColor(reg_ecx!=oldregs.ecx);oldregs.ecx=reg_ecx;mvwprintw (dbg.win_reg,2,4,"%08X",reg_ecx); + SetColor(reg_edx!=oldregs.edx);oldregs.edx=reg_edx;mvwprintw (dbg.win_reg,3,4,"%08X",reg_edx); + + SetColor(reg_esi!=oldregs.esi);oldregs.esi=reg_esi;mvwprintw (dbg.win_reg,0,18,"%08X",reg_esi); + SetColor(reg_edi!=oldregs.edi);oldregs.edi=reg_edi;mvwprintw (dbg.win_reg,1,18,"%08X",reg_edi); + SetColor(reg_ebp!=oldregs.ebp);oldregs.ebp=reg_ebp;mvwprintw (dbg.win_reg,2,18,"%08X",reg_ebp); + SetColor(reg_esp!=oldregs.esp);oldregs.esp=reg_esp;mvwprintw (dbg.win_reg,3,18,"%08X",reg_esp); + SetColor(reg_eip!=oldregs.eip);oldregs.eip=reg_eip;mvwprintw (dbg.win_reg,1,42,"%08X",reg_eip); + + SetColor(Segs[ds].value!=oldsegs[ds].value);oldsegs[ds].value=Segs[ds].value;mvwprintw (dbg.win_reg,0,31,"%04X",Segs[ds].value); + SetColor(Segs[es].value!=oldsegs[es].value);oldsegs[es].value=Segs[es].value;mvwprintw (dbg.win_reg,0,41,"%04X",Segs[es].value); + SetColor(Segs[fs].value!=oldsegs[fs].value);oldsegs[fs].value=Segs[fs].value;mvwprintw (dbg.win_reg,0,51,"%04X",Segs[fs].value); + SetColor(Segs[gs].value!=oldsegs[gs].value);oldsegs[gs].value=Segs[gs].value;mvwprintw (dbg.win_reg,0,61,"%04X",Segs[gs].value); + SetColor(Segs[ss].value!=oldsegs[ss].value);oldsegs[ss].value=Segs[ss].value;mvwprintw (dbg.win_reg,0,71,"%04X",Segs[ss].value); + SetColor(Segs[cs].value!=oldsegs[cs].value);oldsegs[cs].value=Segs[cs].value;mvwprintw (dbg.win_reg,1,31,"%04X",Segs[cs].value); + + /*Individual flags*/ + + flags.cf=get_CF();SetColor(flags.cf!=oldflags.cf);oldflags.cf=flags.cf;mvwprintw (dbg.win_reg,1,53,"%01X",flags.cf); + flags.zf=get_ZF();SetColor(flags.zf!=oldflags.zf);oldflags.zf=flags.zf;mvwprintw (dbg.win_reg,1,56,"%01X",flags.zf); + flags.sf=get_SF();SetColor(flags.sf!=oldflags.sf);oldflags.sf=flags.sf;mvwprintw (dbg.win_reg,1,59,"%01X",flags.sf); + flags.of=get_OF();SetColor(flags.of!=oldflags.of);oldflags.of=flags.of;mvwprintw (dbg.win_reg,1,62,"%01X",flags.of); + flags.af=get_AF();SetColor(flags.af!=oldflags.af);oldflags.af=flags.af;mvwprintw (dbg.win_reg,1,65,"%01X",flags.af); + flags.pf=get_PF();SetColor(flags.pf!=oldflags.pf);oldflags.pf=flags.pf;mvwprintw (dbg.win_reg,1,68,"%01X",flags.pf); + + + SetColor(flags.df!=oldflags.df);oldflags.df=flags.df;mvwprintw (dbg.win_reg,1,71,"%01X",flags.df); + SetColor(flags.intf!=oldflags.intf);oldflags.intf=flags.intf;mvwprintw (dbg.win_reg,1,74,"%01X",flags.intf); + SetColor(flags.tf!=oldflags.tf);oldflags.tf=flags.tf;mvwprintw (dbg.win_reg,1,77,"%01X",flags.tf); + + wattrset(dbg.win_reg,0); + mvwprintw(dbg.win_reg,3,60,"%d ",cycle_count); + wrefresh(dbg.win_reg); +}; + + +static void DrawCode(void) { + PhysPt start=Segs[cs].phys+reg_eip; + char dline[200];Bitu size;Bitu c; + for (Bit32u i=0;i<10;i++) { + size=DasmI386(dline, start, reg_eip, false); + mvwprintw(dbg.win_code,i,0,"%02X:%04X ",Segs[cs].value,(start-Segs[cs].phys)); + for (c=0;c=size*2;c--) waddch(dbg.win_code,' '); + waddstr(dbg.win_code,dline); + for (c=30-strlen(dline);c>0;c--) waddch(dbg.win_code,' '); + start+=size; + } + wrefresh(dbg.win_code); +} +/* This clears all breakpoints by replacing their 0xcc by the original byte */ +static void ClearBreakPoints(void) { + +// for (Bit32u i=0;i::iterator i; + for(i=BPoints.begin(); i != BPoints.end(); ++i) { + if ((*i).active && (*i).enabled) { + if ((*i).location==where) { + found=true; + break; + } + } + } + if (!found) return false; + ClearBreakPoints(); + DEBUG_Enable(); + + SetBreakPoints(); + return false; +} + + + + +Bit32u DEBUG_CheckKeys(void) { + int key=getch(); + Bit32u ret=0; + if (key>0) { + switch (key) { + case '1': + ret=(*cpudecoder)(100); + break; + case '2': + ret=(*cpudecoder)(500); + break; + case '3': + ret=(*cpudecoder)(1000); + break; + case '4': + ret=(*cpudecoder)(5000); + break; + case '5': + ret=(*cpudecoder)(10000); + break; + case 'q': + ret=(*cpudecoder)(5); + break; + + default: + ret=(*cpudecoder)(1); + }; + DEBUG_DrawScreen(); + } + return ret; +}; + + +Bitu DEBUG_Loop(void) { +//TODO Disable sound + GFX_Events(); + PIC_runIRQs(); + return DEBUG_CheckKeys(); +} + +void DEBUG_Enable(void) { + DEBUG_DrawScreen(); + debugging=true; + DOSBOX_SetLoop(&DEBUG_Loop); +} + + +void DEBUG_DrawScreen(void) { + DrawRegisters(); + DrawCode(); + +} +static void DEBUG_RaiseTimerIrq(void) { + PIC_ActivateIRQ(0); +} + +void DEBUG_Init(void) { + #ifdef WIN32 + WIN32_Console(); + #endif + memset((void *)&dbg,0,sizeof(dbg)); + debugging=false; + dbg.active_win=3; + input_count=0; + /* Start the Debug Gui */ + DBGUI_StartUp(); + DEBUG_DrawScreen(); + /* Add some keyhandlers */ + KEYBOARD_AddEvent(KBD_kpminus,0,DEBUG_Enable); + KEYBOARD_AddEvent(KBD_kpplus,0,DEBUG_RaiseTimerIrq); + /* Clear the breakpoint list */ + +} + + +#endif diff --git a/src/debug/debug_disasm.cpp b/src/debug/debug_disasm.cpp new file mode 100644 index 00000000..87d35ef0 --- /dev/null +++ b/src/debug/debug_disasm.cpp @@ -0,0 +1,1112 @@ + +/* + Ripped out some stuff from the mame releae to only make it for 386's + Changed some variables to use the standard DOSBox data types + Added my callback opcode + +*/ + +/* + * 2asm: Convert binary files to 80*86 assembler. Version 1.00 + * Adapted by Andrea Mazzoleni for use with MAME + * HJB 990321: + * Changed output of hex values from 0xxxxh to $xxxx format + * Removed "ptr" from "byte ptr", "word ptr" and "dword ptr" +*/ + +/* 2asm comments + +License: + + 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. + + 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. + +Comments: + + The code was originally snaffled from the GNU C++ debugger, as ported + to DOS by DJ Delorie and Kent Williams (williams@herky.cs.uiowa.edu). + Extensively modified by Robin Hilliard in Jan and May 1992. + + This source compiles under Turbo C v2.01. The disassembler is entirely + table driven so it's fairly easy to change to suit your own tastes. + + The instruction table has been modified to correspond with that in + `Programmer's Technical Reference: The Processor and Coprocessor', + Robert L. Hummel, Ziff-Davis Press, 1992. Missing (read "undocumented") + instructions were added and many mistakes and omissions corrected. + + +Health warning: + + When writing and degbugging this code, I didn't have (and still don't have) + a 32-bit disassembler to compare this guy's output with. It's therefore + quite likely that bugs will appear when disassembling instructions which use + the 386 and 486's native 32 bit mode. It seems to work fine in 16 bit mode. + +Any comments/updates/bug reports to: + + Robin Hilliard, Lough Guitane, Killarney, Co. Kerry, Ireland. + Tel: [+353] 64-54014 + Internet: softloft@iruccvax.ucc.ie + Compu$erve: 100042, 1237 + + If you feel like registering, and possibly get notices of updates and + other items of software, then send me a post card of your home town. + + Thanks and enjoy! + +*/ +#include "dosbox.h" +#ifdef C_DEBUG +#include +#include +#include +#include +#include "mem.h" + +typedef Bit8u UINT8; +typedef Bit16u UINT16; +typedef Bit32u UINT32; + +typedef Bit8s INT8; +typedef Bit16s INT16; +typedef Bit32s INT32; + + +/* Little endian uint read */ +#define le_uint8(ptr) (*(UINT8*)ptr) + +INLINE UINT16 le_uint16(const void* ptr) { + const UINT8* ptr8 = (const UINT8*)ptr; + return (UINT16)ptr8[0] | (UINT16)ptr8[1] << 8; +} +INLINE UINT32 le_uint32(const void* ptr) { + const UINT8* ptr8 = (const UINT8*)ptr; + return (UINT32)ptr8[0] | (UINT32)ptr8[1] << 8 | (UINT32)ptr8[2] << 16 | (UINT32)ptr8[3] << 24; +} + +/* Little endian int read */ +#define le_int8(ptr) ((INT8)le_uint8(ptr)) +#define le_int16(ptr) ((INT16)le_uint16(ptr)) +#define le_int32(ptr) ((INT32)le_uint32(ptr)) + +#define fp_segment(dw) ((dw >> 16) & 0xFFFFU) +#define fp_offset(dw) (dw & 0xFFFFU) +#define fp_addr(seg, off) ( (seg<<4)+off ) + +static UINT8 must_do_size; /* used with size of operand */ +static int wordop; /* dealing with word or byte operand */ + +static int instruction_offset; +//static UINT16 instruction_segment; + +static char* ubufs; /* start of buffer */ +static char* ubufp; /* last position of buffer */ +static int invalid_opcode = 0; +static int first_space = 1; + +static int prefix; /* segment override prefix byte */ +static int modrmv; /* flag for getting modrm byte */ +static int sibv; /* flag for getting sib byte */ +static int opsize; /* just like it says ... */ +static int addrsize; +static int addr20bit=0; +static int addr24bit=0; +static int addr32bit=0; + +/* some defines for extracting instruction bit fields from bytes */ + +#define MOD(a) (((a)>>6)&7) +#define REG(a) (((a)>>3)&7) +#define RM(a) ((a)&7) +#define SCALE(a) (((a)>>6)&7) +#define INDEX(a) (((a)>>3)&7) +#define BASE(a) ((a)&7) + +/* Percent tokens in strings: + First char after '%': + A - direct address + C - reg of r/m picks control register + D - reg of r/m picks debug register + E - r/m picks operand + F - flags register + G - reg of r/m picks general register + I - immediate data + J - relative IP offset ++ K - call/jmp distance + M - r/m picks memory + O - no r/m, offset only + R - mod of r/m picks register only + S - reg of r/m picks segment register + T - reg of r/m picks test register + X - DS:ESI + Y - ES:EDI + 2 - prefix of two-byte opcode ++ e - put in 'e' if use32 (second char is part of reg name) ++ put in 'w' for use16 or 'd' for use32 (second char is 'w') ++ j - put in 'e' in jcxz if prefix==0x66 + f - floating point (second char is esc value) + g - do r/m group 'n', n==0..7 + p - prefix + s - size override (second char is a,o) ++ d - put d if double arg, nothing otherwise (pushfd, popfd &c) ++ w - put w if word, d if double arg, nothing otherwise (lodsw/lodsd) ++ P - simple prefix + + Second char after '%': + a - two words in memory (BOUND) + b - byte + c - byte or word + d - dword ++ f - far call/jmp ++ n - near call/jmp + p - 32 or 48 bit pointer ++ q - byte/word thingy + s - six byte pseudo-descriptor + v - word or dword + w - word ++ x - sign extended byte + F - use floating regs in mod/rm + 1-8 - group number, esc value, etc +*/ + +/* watch out for aad && aam with odd operands */ + +static char *(*opmap1)[256]; + +static char *op386map1[256] = { +/* 0 */ + "add %Eb,%Gb", "add %Ev,%Gv", "add %Gb,%Eb", "add %Gv,%Ev", + "add al,%Ib", "add %eax,%Iv", "push es", "pop es", + "or %Eb,%Gb", "or %Ev,%Gv", "or %Gb,%Eb", "or %Gv,%Ev", + "or al,%Ib", "or %eax,%Iv", "push cs", "%2 ", +/* 1 */ + "adc %Eb,%Gb", "adc %Ev,%Gv", "adc %Gb,%Eb", "adc %Gv,%Ev", + "adc al,%Ib", "adc %eax,%Iv", "push ss", "pop ss", + "sbb %Eb,%Gb", "sbb %Ev,%Gv", "sbb %Gb,%Eb", "sbb %Gv,%Ev", + "sbb al,%Ib", "sbb %eax,%Iv", "push ds", "pop ds", +/* 2 */ + "and %Eb,%Gb", "and %Ev,%Gv", "and %Gb,%Eb", "and %Gv,%Ev", + "and al,%Ib", "and %eax,%Iv", "%pe", "daa", + "sub %Eb,%Gb", "sub %Ev,%Gv", "sub %Gb,%Eb", "sub %Gv,%Ev", + "sub al,%Ib", "sub %eax,%Iv", "%pc", "das", +/* 3 */ + "xor %Eb,%Gb", "xor %Ev,%Gv", "xor %Gb,%Eb", "xor %Gv,%Ev", + "xor al,%Ib", "xor %eax,%Iv", "%ps", "aaa", + "cmp %Eb,%Gb", "cmp %Ev,%Gv", "cmp %Gb,%Eb", "cmp %Gv,%Ev", + "cmp al,%Ib", "cmp %eax,%Iv", "%pd", "aas", +/* 4 */ + "inc %eax", "inc %ecx", "inc %edx", "inc %ebx", + "inc %esp", "inc %ebp", "inc %esi", "inc %edi", + "dec %eax", "dec %ecx", "dec %edx", "dec %ebx", + "dec %esp", "dec %ebp", "dec %esi", "dec %edi", +/* 5 */ + "push %eax", "push %ecx", "push %edx", "push %ebx", + "push %esp", "push %ebp", "push %esi", "push %edi", + "pop %eax", "pop %ecx", "pop %edx", "pop %ebx", + "pop %esp", "pop %ebp", "pop %esi", "pop %edi", +/* 6 */ + "pusha%d ", "popa%d ", "bound %Gv,%Ma", "arpl %Ew,%Rw", + "%pf", "%pg", "%so", "%sa", + "push %Iv", "imul %Gv,%Ev,%Iv","push %Ix", "imul %Gv,%Ev,%Ib", + "insb", "ins%ew", "outsb", "outs%ew", +/* 7 */ + "jo %Jb", "jno %Jb", "jc %Jb", "jnc %Jb", + "je %Jb", "jne %Jb", "jbe %Jb", "ja %Jb", + "js %Jb", "jns %Jb", "jpe %Jb", "jpo %Jb", + "jl %Jb", "jge %Jb", "jle %Jb", "jg %Jb", +/* 8 */ +/* "%g0 %Eb,%Ib", "%g0 %Ev,%Iv", "%g0 %Ev,%Ib", "%g0 %Ev,%Ib", */ + "%g0 %Eb,%Ib", "%g0 %Ev,%Iv", "%g0 %Ev,%Ix", "%g0 %Ev,%Ix", + "test %Eb,%Gb", "test %Ev,%Gv", "xchg %Eb,%Gb", "xchg %Ev,%Gv", + "mov %Eb,%Gb", "mov %Ev,%Gv", "mov %Gb,%Eb", "mov %Gv,%Ev", + "mov %Ew,%Sw", "lea %Gv,%M ", "mov %Sw,%Ew", "pop %Ev", +/* 9 */ + "nop", "xchg %ecx,%eax", "xchg %edx,%eax", "xchg %ebx,%eax", + "xchg %esp,%eax", "xchg %ebp,%eax", "xchg %esi,%eax", "xchg %edi,%eax", + "cbw", "cwd", "call %Ap", "fwait", + "pushf%d ", "popf%d ", "sahf", "lahf", +/* a */ + "mov al,%Oc", "mov %eax,%Ov", "mov %Oc,al", "mov %Ov,%eax", + "%P movsb", "%P movs%w", "%P cmpsb", "%P cmps%w ", + "test al,%Ib", "test %eax,%Iv", "%P stosb", "%P stos%w ", + "%P lodsb", "%P lods%w ", "%P scasb", "%P scas%w ", +/* b */ + "mov al,%Ib", "mov cl,%Ib", "mov dl,%Ib", "mov bl,%Ib", + "mov ah,%Ib", "mov ch,%Ib", "mov dh,%Ib", "mov bh,%Ib", + "mov %eax,%Iv", "mov %ecx,%Iv", "mov %edx,%Iv", "mov %ebx,%Iv", + "mov %esp,%Iv", "mov %ebp,%Iv", "mov %esi,%Iv", "mov %edi,%Iv", +/* c */ + "%g1 %Eb,%Ib", "%g1 %Ev,%Ib", "ret %Iw", "ret", + "les %Gv,%Mp", "lds %Gv,%Mp", "mov %Eb,%Ib", "mov %Ev,%Iv", + "enter %Iw,%Ib", "leave", "retf %Iw", "retf", + "int 03", "int %Ib", "into", "iret", +/* d */ + "%g1 %Eb,1", "%g1 %Ev,1", "%g1 %Eb,cl", "%g1 %Ev,cl", + "aam ; %Ib", "aad ; %Ib", "setalc", "xlat", +#if 0 + "esc 0,%Ib", "esc 1,%Ib", "esc 2,%Ib", "esc 3,%Ib", + "esc 4,%Ib", "esc 5,%Ib", "esc 6,%Ib", "esc 7,%Ib", +#else + "%f0", "%f1", "%f2", "%f3", + "%f4", "%f5", "%f6", "%f7", +#endif +/* e */ + "loopne %Jb", "loope %Jb", "loop %Jb", "j%j cxz %Jb", + "in al,%Ib", "in %eax,%Ib", "out %Ib,al", "out %Ib,%eax", + "call %Jv", "jmp %Jv", "jmp %Ap", "jmp %Ks%Jb", + "in al,dx", "in %eax,dx", "out dx,al", "out dx,%eax", +/* f */ + "lock %p ", 0, "repne %p ", "repe %p ", + "hlt", "cmc", "%g2", "%g2", + "clc", "stc", "cli", "sti", + "cld", "std", "%g3", "%g4" +}; + +static char *second[] = { +/* 0 */ + "%g5", "%g6", "lar %Gv,%Ew", "lsl %Gv,%Ew", + 0, "loadall", "clts", "loadall", + "invd", "wbinvd", 0, 0, + 0, 0, 0, 0, +/* 1 */ + "mov %Eb,%Gb", "mov %Ev,%Gv", "mov %Gb,%Eb", "mov %Gv,%Ev", + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, +/* 2 */ + "mov %Rd,%Cd", "mov %Rd,%Dd", "mov %Cd,%Rd", "mov %Dd,%Rd", + "mov %Rd,%Td", 0, "mov %Td,%Rd", 0, + 0, 0, 0, 0, + 0, 0, 0, 0, +/* 3 */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +/* 4 */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +/* 5 */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +/* 6 */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +/* 7 */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +/* 8 */ + "jo %Jv", "jno %Jv", "jb %Jv", "jnb %Jv", + "jz %Jv", "jnz %Jv", "jbe %Jv", "ja %Jv", + "js %Jv", "jns %Jv", "jp %Jv", "jnp %Jv", + "jl %Jv", "jge %Jv", "jle %Jv", "jg %Jv", +/* 9 */ + "seto %Eb", "setno %Eb", "setc %Eb", "setnc %Eb", + "setz %Eb", "setnz %Eb", "setbe %Eb", "setnbe %Eb", + "sets %Eb", "setns %Eb", "setp %Eb", "setnp %Eb", + "setl %Eb", "setge %Eb", "setle %Eb", "setg %Eb", +/* a */ + "push fs", "pop fs", 0, "bt %Ev,%Gv", + "shld %Ev,%Gv,%Ib", "shld %Ev,%Gv,cl", 0, 0, + "push gs", "pop gs", 0, "bts %Ev,%Gv", + "shrd %Ev,%Gv,%Ib", "shrd %Ev,%Gv,cl", 0, "imul %Gv,%Ev", +/* b */ + "cmpxchg %Eb,%Gb", "cmpxchg %Ev,%Gv", "lss %Mp", "btr %Ev,%Gv", + "lfs %Mp", "lgs %Mp", "movzx %Gv,%Eb", "movzx %Gv,%Ew", + 0, 0, "%g7 %Ev,%Ib", "btc %Ev,%Gv", + "bsf %Gv,%Ev", "bsr %Gv,%Ev", "movsx %Gv,%Eb", "movsx %Gv,%Ew", +/* c */ + "xadd %Eb,%Gb", "xadd %Ev,%Gv", 0, 0, + 0, 0, 0, 0, + "bswap eax", "bswap ecx", "bswap edx", "bswap ebx", + "bswap esp", "bswap ebp", "bswap esi", "bswap edi", +/* d */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +/* e */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +/* f */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static char *groups[][8] = { /* group 0 is group 3 for %Ev set */ +/* 0 */ + { "add", "or", "adc", "sbb", + "and", "sub", "xor", "cmp" }, +/* 1 */ + { "rol", "ror", "rcl", "rcr", + "shl", "shr", "shl", "sar" }, +/* 2 */ /* v v*/ + { "test %Eq,%Iq", "test %Eq,%Iq", "not %Ec", "neg %Ev", + "mul %Ec", "imul %Ec", "div %Ec", "idiv %Ec" }, +/* 3 */ + { "inc %Eb", "dec %Eb", 0, 0, + 0, 0, 0, "callback %Iw" }, +/* 4 */ + { "inc %Ev", "dec %Ev", "call %Kn%Ev", "call %Kf%Ep", + "jmp %Kn%Ev", "jmp %Kf%Ep", "push %Ev", 0 }, +/* 5 */ + { "sldt %Ew", "str %Ew", "lldt %Ew", "ltr %Ew", + "verr %Ew", "verw %Ew", 0, 0 }, +/* 6 */ + { "sgdt %Ms", "sidt %Ms", "lgdt %Ms", "lidt %Ms", + "smsw %Ew", 0, "lmsw %Ew", 0 }, +/* 7 */ + { 0, 0, 0, 0, + "bt", "bts", "btr", "btc" } +}; + +/* zero here means invalid. If first entry starts with '*', use st(i) */ +/* no assumed %EFs here. Indexed by RM(modrm()) */ +static char *f0[] = { 0, 0, 0, 0, 0, 0, 0, 0}; +static char *fop_9[] = { "*fxch st,%GF" }; +static char *fop_10[] = { "fnop", 0, 0, 0, 0, 0, 0, 0 }; +static char *fop_12[] = { "fchs", "fabs", 0, 0, "ftst", "fxam", 0, 0 }; +static char *fop_13[] = { "fld1", "fldl2t", "fldl2e", "fldpi", + "fldlg2", "fldln2", "fldz", 0 }; +static char *fop_14[] = { "f2xm1", "fyl2x", "fptan", "fpatan", + "fxtract", "fprem1", "fdecstp", "fincstp" }; +static char *fop_15[] = { "fprem", "fyl2xp1", "fsqrt", "fsincos", + "frndint", "fscale", "fsin", "fcos" }; +static char *fop_21[] = { 0, "fucompp", 0, 0, 0, 0, 0, 0 }; +static char *fop_28[] = { 0, 0, "fclex", "finit", 0, 0, 0, 0 }; +static char *fop_32[] = { "*fadd %GF,st" }; +static char *fop_33[] = { "*fmul %GF,st" }; +static char *fop_36[] = { "*fsubr %GF,st" }; +static char *fop_37[] = { "*fsub %GF,st" }; +static char *fop_38[] = { "*fdivr %GF,st" }; +static char *fop_39[] = { "*fdiv %GF,st" }; +static char *fop_40[] = { "*ffree %GF" }; +static char *fop_42[] = { "*fst %GF" }; +static char *fop_43[] = { "*fstp %GF" }; +static char *fop_44[] = { "*fucom %GF" }; +static char *fop_45[] = { "*fucomp %GF" }; +static char *fop_48[] = { "*faddp %GF,st" }; +static char *fop_49[] = { "*fmulp %GF,st" }; +static char *fop_51[] = { 0, "fcompp", 0, 0, 0, 0, 0, 0 }; +static char *fop_52[] = { "*fsubrp %GF,st" }; +static char *fop_53[] = { "*fsubp %GF,st" }; +static char *fop_54[] = { "*fdivrp %GF,st" }; +static char *fop_55[] = { "*fdivp %GF,st" }; +static char *fop_60[] = { "fstsw ax", 0, 0, 0, 0, 0, 0, 0 }; + +static char **fspecial[] = { /* 0=use st(i), 1=undefined 0 in fop_* means undefined */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, fop_9, fop_10, 0, fop_12, fop_13, fop_14, fop_15, + f0, f0, f0, f0, f0, fop_21, f0, f0, + f0, f0, f0, f0, fop_28, f0, f0, f0, + fop_32, fop_33, f0, f0, fop_36, fop_37, fop_38, fop_39, + fop_40, f0, fop_42, fop_43, fop_44, fop_45, f0, f0, + fop_48, fop_49, f0, fop_51, fop_52, fop_53, fop_54, fop_55, + f0, f0, f0, f0, fop_60, f0, f0, f0, +}; + +static char *floatops[] = { /* assumed " %EF" at end of each. mod != 3 only */ +/*00*/ "fadd", "fmul", "fcom", "fcomp", + "fsub", "fsubr", "fdiv", "fdivr", +/*08*/ "fld", 0, "fst", "fstp", + "fldenv", "fldcw", "fstenv", "fstcw", +/*16*/ "fiadd", "fimul", "ficomw", "ficompw", + "fisub", "fisubr", "fidiv", "fidivr", +/*24*/ "fild", 0, "fist", "fistp", + "frstor", "fldt", 0, "fstpt", +/*32*/ "faddq", "fmulq", "fcomq", "fcompq", + "fsubq", "fsubrq", "fdivq", "fdivrq", +/*40*/ "fldq", 0, "fstq", "fstpq", + 0, 0, "fsave", "fstsw", +/*48*/ "fiaddw", "fimulw", "ficomw", "ficompw", + "fisubw", "fisubrw", "fidivw", "fidivr", +/*56*/ "fildw", 0, "fistw", "fistpw", + "fbldt", "fildq", "fbstpt", "fistpq" +}; + +static char *addr_to_hex(UINT32 addr, int splitup) { + static char buffer[11]; + + if (splitup) { + if (fp_segment(addr)==0 || fp_offset(addr)==0xffff) /* 'coz of wraparound */ + sprintf(buffer, "%04X", (unsigned)fp_offset(addr) ); + else + sprintf(buffer, "%04X:%04X", (unsigned)fp_segment(addr), (unsigned)fp_offset(addr) ); + } else { +#if 0 + /* Pet outcommented, reducing address size to 4 + when segment is 0 or 0xffff */ + if (fp_segment(addr)==0 || fp_segment(addr)==0xffff) /* 'coz of wraparound */ + sprintf(buffer, "%04X", (unsigned)fp_offset(addr) ); + else +#endif + + if (addr20bit) { + sprintf(buffer, "%05X", addr&0xfffff ); + } else if (addr24bit) { + sprintf(buffer, "%06X", addr&0xffffff ); + } else if (addr32bit) { + sprintf(buffer, "%08X", addr ); + } + } + + return buffer; +} + +static PhysPt getbyte_mac; + + +static UINT8 getbyte(void) { + return mem_readb(getbyte_mac++); +} + +/* + only one modrm or sib byte per instruction, tho' they need to be + returned a few times... +*/ + +static int modrm(void) +{ + if (modrmv == -1) + modrmv = getbyte(); + return modrmv; +} + +static int sib(void) +{ + if (sibv == -1) + sibv = getbyte(); + return sibv; +} + +/*------------------------------------------------------------------------*/ + +static void uprintf(char *s, ...) +{ + va_list arg_ptr; + va_start (arg_ptr, s); + vsprintf(ubufp, s, arg_ptr); + while (*ubufp) + ubufp++; +} + +static void uputchar(char c) +{ + *ubufp++ = c; + *ubufp = 0; +} + +/*------------------------------------------------------------------------*/ + +static int bytes(char c) +{ + switch (c) { + case 'b': + return 1; + case 'w': + return 2; + case 'd': + return 4; + case 'v': + if (opsize == 32) + return 4; + else + return 2; + } + return 0; +} + +/*------------------------------------------------------------------------*/ +static void outhex(char subtype, int extend, int optional, int defsize, int sign) +{ + int n=0, s=0, i; + INT32 delta = 0; + unsigned char buff[6]; + char *name; + char signchar; + + switch (subtype) { + case 'q': + if (wordop) { + if (opsize==16) { + n = 2; + } else { + n = 4; + } + } else { + n = 1; + } + break; + + case 'a': + break; + case 'x': + extend = 2; + n = 1; + break; + case 'b': + n = 1; + break; + case 'w': + n = 2; + break; + case 'd': + n = 4; + break; + case 's': + n = 6; + break; + case 'c': + case 'v': + if (defsize == 32) + n = 4; + else + n = 2; + break; + case 'p': + if (defsize == 32) + n = 6; + else + n = 4; + s = 1; + break; + } + for (i=0; i n) { + if (subtype!='x') { + if (delta<0) { + delta = -delta; + signchar = '-'; + } else + signchar = '+'; + if (delta || !optional) + uprintf("%c%0*lX", (char)signchar, (int)(extend), (long)delta); + } else { + if (extend==2) + delta = (UINT16)delta; + uprintf("%0.*lX", (int)(2*extend), (long)delta ); + } + return; + } + if ((n == 4) && !sign) { + name = addr_to_hex(delta, 0); + uprintf("%s", name); + return; + } + switch (n) { + case 1: + if (sign && (char)delta<0) { + delta = -delta; + signchar = '-'; + } else + signchar = '+'; + if (sign) + uprintf("%c%02lX", (char)signchar, delta & 0xFFL); + else + uprintf("%02lX", delta & 0xFFL); + break; + + case 2: + if (sign && delta<0) { + signchar = '-'; + delta = -delta; + } else + signchar = '+'; + if (sign) + uprintf("%c%04lX", (char)signchar, delta & 0xFFFFL); + else + uprintf("%04lX", delta & 0xFFFFL); + break; + + case 4: + if (sign && delta<0) { + delta = -delta; + signchar = '-'; + } else + signchar = '+'; + if (sign) + uprintf("%c%08lX", (char)signchar, delta & 0xFFFFFFFFL); + else + uprintf("%08lX", delta & 0xFFFFFFFFL); + break; + } +} + + +/*------------------------------------------------------------------------*/ + +static void reg_name(int regnum, char size) +{ + if (size == 'F') { /* floating point register? */ + uprintf("st(%d)", regnum); + return; + } + if (((size == 'v') && (opsize == 32)) || (size == 'd')) + uputchar('e'); + if ((size=='q' || size == 'b' || size=='c') && !wordop) { + uputchar("acdbacdb"[regnum]); + uputchar("llllhhhh"[regnum]); + } else { + uputchar("acdbsbsd"[regnum]); + uputchar("xxxxppii"[regnum]); + } +} + + +/*------------------------------------------------------------------------*/ + +static void ua_str(char *str); + +static void do_sib(int m) +{ + int s, i, b; + + s = SCALE(sib()); + i = INDEX(sib()); + b = BASE(sib()); + switch (b) { /* pick base */ + case 0: ua_str("%p:[eax"); break; + case 1: ua_str("%p:[ecx"); break; + case 2: ua_str("%p:[edx"); break; + case 3: ua_str("%p:[ebx"); break; + case 4: ua_str("%p:[esp"); break; + case 5: + if (m == 0) { + ua_str("%p:["); + outhex('d', 4, 0, addrsize, 0); + } else { + ua_str("%p:[ebp"); + } + break; + case 6: ua_str("%p:[esi"); break; + case 7: ua_str("%p:[edi"); break; + } + switch (i) { /* and index */ + case 0: uprintf("+eax"); break; + case 1: uprintf("+ecx"); break; + case 2: uprintf("+edx"); break; + case 3: uprintf("+ebx"); break; + case 4: break; + case 5: uprintf("+ebp"); break; + case 6: uprintf("+esi"); break; + case 7: uprintf("+edi"); break; + } + if (i != 4) { + switch (s) { /* and scale */ + case 0: /*uprintf("");*/ break; + case 1: uprintf("*2"); break; + case 2: uprintf("*4"); break; + case 3: uprintf("*8"); break; + } + } +} + + + +/*------------------------------------------------------------------------*/ +static void do_modrm(char subtype) +{ + int mod = MOD(modrm()); + int rm = RM(modrm()); + int extend = (addrsize == 32) ? 4 : 2; + + if (mod == 3) { /* specifies two registers */ + reg_name(rm, subtype); + return; + } + if (must_do_size) { + if (wordop) { + if (addrsize==32 || opsize==32) { /* then must specify size */ + ua_str("dword "); + } else { + ua_str("word "); + } + } else { + ua_str("byte "); + } + } + if ((mod == 0) && (rm == 5) && (addrsize == 32)) {/* mem operand with 32 bit ofs */ + ua_str("%p:["); + outhex('d', extend, 0, addrsize, 0); + uputchar(']'); + return; + } + if ((mod == 0) && (rm == 6) && (addrsize == 16)) { /* 16 bit dsplcmnt */ + ua_str("%p:["); + outhex('w', extend, 0, addrsize, 0); + uputchar(']'); + return; + } + if ((addrsize != 32) || (rm != 4)) + ua_str("%p:["); + if (addrsize == 16) { + switch (rm) { + case 0: uprintf("bx+si"); break; + case 1: uprintf("bx+di"); break; + case 2: uprintf("bp+si"); break; + case 3: uprintf("bp+di"); break; + case 4: uprintf("si"); break; + case 5: uprintf("di"); break; + case 6: uprintf("bp"); break; + case 7: uprintf("bx"); break; + } + } else { + switch (rm) { + case 0: uprintf("eax"); break; + case 1: uprintf("ecx"); break; + case 2: uprintf("edx"); break; + case 3: uprintf("ebx"); break; + case 4: do_sib(mod); break; + case 5: uprintf("ebp"); break; + case 6: uprintf("esi"); break; + case 7: uprintf("edi"); break; + } + } + switch (mod) { + case 1: + outhex('b', extend, 1, addrsize, 0); + break; + case 2: + outhex('v', extend, 1, addrsize, 1); + break; + } + uputchar(']'); +} + + + +/*------------------------------------------------------------------------*/ +static void floating_point(int e1) +{ + int esc = e1*8 + REG(modrm()); + + if ((MOD(modrm()) == 3)&&fspecial[esc]) { + if (fspecial[esc][0]) { + if (fspecial[esc][0][0] == '*') { + ua_str(fspecial[esc][0]+1); + } else { + ua_str(fspecial[esc][RM(modrm())]); + } + } else { + ua_str(floatops[esc]); + ua_str(" %EF"); + } + } else { + ua_str(floatops[esc]); + ua_str(" %EF"); + } +} + + +/*------------------------------------------------------------------------*/ +/* Main table driver */ + +static void percent(char type, char subtype) +{ + INT32 vofs = 0; + char *name=NULL; + int extend = (addrsize == 32) ? 4 : 2; + UINT8 c; + + switch (type) { + case 'A': /* direct address */ + outhex(subtype, extend, 0, addrsize, 0); + break; + + case 'C': /* reg(r/m) picks control reg */ + uprintf("C%d", REG(modrm())); + must_do_size = 0; + break; + + case 'D': /* reg(r/m) picks debug reg */ + uprintf("D%d", REG(modrm())); + must_do_size = 0; + break; + + case 'E': /* r/m picks operand */ + do_modrm(subtype); + break; + + case 'G': /* reg(r/m) picks register */ + if (subtype == 'F') /* 80*87 operand? */ + reg_name(RM(modrm()), subtype); + else + reg_name(REG(modrm()), subtype); + must_do_size = 0; + break; + + case 'I': /* immed data */ + outhex(subtype, 0, 0, opsize, 0); + break; + + case 'J': /* relative IP offset */ + switch (bytes(subtype)) { /* sizeof offset value */ + case 1: + vofs = (INT8)getbyte(); + name = addr_to_hex(vofs+instruction_offset,0); + break; + case 2: + vofs = getbyte(); + vofs += getbyte()<<8; + vofs = (INT16)vofs; + name = addr_to_hex(vofs+instruction_offset,0); + break; +#if 0 + /* i386 */ + case 4: + vofs = (UINT32)getbyte(); /* yuk! */ + vofs |= (UINT32)getbyte() << 8; + vofs |= (UINT32)getbyte() << 16; + vofs |= (UINT32)getbyte() << 24; + name = addr_to_hex(vofs+instruction_offset,1); + break; +#endif + } + if (vofs<0) + uprintf("%s ($-%x)", name, -vofs); + else + uprintf("%s ($+%x)", name, vofs); + break; + + case 'K': + switch (subtype) { + case 'f': + ua_str("far "); + break; + case 'n': + ua_str("near "); + break; + case 's': + ua_str("short "); + break; + } + break; + + case 'M': /* r/m picks memory */ + do_modrm(subtype); + break; + + case 'O': /* offset only */ + ua_str("%p:["); + outhex(subtype, extend, 0, addrsize, 0); + uputchar(']'); + break; + + case 'P': /* prefix byte (rh) */ + ua_str("%p:"); + break; + + case 'R': /* mod(r/m) picks register */ + reg_name(REG(modrm()), subtype); /* rh */ + must_do_size = 0; + break; + + case 'S': /* reg(r/m) picks segment reg */ + uputchar("ecsdfg"[REG(modrm())]); + uputchar('s'); + must_do_size = 0; + break; + + case 'T': /* reg(r/m) picks T reg */ + uprintf("tr%d", REG(modrm())); + must_do_size = 0; + break; + + case 'X': /* ds:si type operator */ + uprintf("ds:["); + if (addrsize == 32) + uputchar('e'); + uprintf("si]"); + break; + + case 'Y': /* es:di type operator */ + uprintf("es:["); + if (addrsize == 32) + uputchar('e'); + uprintf("di]"); + break; + + case '2': /* old [pop cs]! now indexes */ + ua_str(second[getbyte()]); /* instructions in 386/486 */ + break; + + case 'g': /* modrm group `subtype' (0--7) */ + ua_str(groups[subtype-'0'][REG(modrm())]); + break; + + case 'd': /* sizeof operand==dword? */ + if (opsize == 32) + uputchar('d'); + uputchar(subtype); + break; + + case 'w': /* insert explicit size specifier */ + if (opsize == 32) + uputchar('d'); + else + uputchar('w'); + uputchar(subtype); + break; + + case 'e': /* extended reg name */ + if (opsize == 32) { + if (subtype == 'w') + uputchar('d'); + else { + uputchar('e'); + uputchar(subtype); + } + } else + uputchar(subtype); + break; + + case 'f': /* '87 opcode */ + floating_point(subtype-'0'); + break; + + case 'j': + if (addrsize==32 || opsize==32) /* both of them?! */ + uputchar('e'); + break; + + case 'p': /* prefix byte */ + switch (subtype) { + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 's': + prefix = subtype; + c = getbyte(); + wordop = c & 1; + ua_str((*opmap1)[c]); + break; + case ':': + if (prefix) + uprintf("%cs:", prefix); + break; + case ' ': + c = getbyte(); + wordop = c & 1; + ua_str((*opmap1)[c]); + break; + } + break; + + case 's': /* size override */ + switch (subtype) { + case 'a': + addrsize = 48 - addrsize; + c = getbyte(); + wordop = c & 1; + ua_str((*opmap1)[c]); +/* ua_str(opmap1[getbyte()]); */ + break; + case 'o': + opsize = 48 - opsize; + c = getbyte(); + wordop = c & 1; + ua_str((*opmap1)[c]); +/* ua_str(opmap1[getbyte()]); */ + break; + } + break; + } +} + + +static void ua_str(char *str) +{ + char c; + + if (str == 0) { + invalid_opcode = 1; + uprintf("?"); + return; + } + + if (strpbrk(str, "CDFGRST")) /* specifiers for registers=>no size 2b specified */ + must_do_size = 0; + + while ((c = *str++) != 0) { + if (c == ' ' && first_space) + { + first_space = 0; + do + { + uputchar(' '); + } while ( (int)(ubufp - ubufs) < 5 ); + } + else + if (c == '%') { + c = *str++; + percent(c, *str++); + } else { + uputchar(c); + } + } +} + + +Bitu DasmI386(char* buffer, PhysPt pc, Bitu cur_ip, bool bit32) +{ + Bitu c; + + + instruction_offset = cur_ip; + /* input buffer */ + getbyte_mac = pc; + + /* output buffer */ + ubufs = buffer; + ubufp = buffer; + first_space = 1; + + addr32bit=1;addr20bit=addr24bit=0; + + prefix = 0; + modrmv = sibv = -1; /* set modrm and sib flags */ + if (bit32) opsize = addrsize = 32; + else opsize = addrsize = 16; + c = getbyte(); + wordop = c & 1; + must_do_size = 1; + invalid_opcode = 0; + opmap1=&op386map1; + ua_str(op386map1[c]); + + if (invalid_opcode) { + /* restart output buffer */ + ubufp = buffer; + /* invalid instruction, use db xx */ + uprintf("db %02X", (unsigned)c); + return 1; + } + + return getbyte_mac-pc; +} + + +#endif \ No newline at end of file diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp new file mode 100644 index 00000000..c13f306e --- /dev/null +++ b/src/debug/debug_gui.cpp @@ -0,0 +1,130 @@ +/* + * 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. + */ + + + +#include "dosbox.h" +#ifdef C_DEBUG + +#include +#include +#include +#include +#include + +#include "regs.h" +#include "debug.h" +#include "debug_inc.h" + +void DEBUG_ShowMsg(char * msg) { + char buf[1024]; + strcpy(buf,msg); + strcat(buf,"\n"); + + waddstr(dbg.win_out,buf); + wprintw(dbg.win_out," %d\n",cycle_count); + wrefresh(dbg.win_out); +} + + + +static void Draw_RegisterLayout(void) { + mvwaddstr(dbg.win_reg,0,0,"EAX="); + mvwaddstr(dbg.win_reg,1,0,"EBX="); + mvwaddstr(dbg.win_reg,2,0,"ECX="); + mvwaddstr(dbg.win_reg,3,0,"EDX="); + + mvwaddstr(dbg.win_reg,0,14,"ESI="); + mvwaddstr(dbg.win_reg,1,14,"EDI="); + mvwaddstr(dbg.win_reg,2,14,"EBP="); + mvwaddstr(dbg.win_reg,3,14,"ESP="); + + mvwaddstr(dbg.win_reg,0,28,"DS="); + mvwaddstr(dbg.win_reg,0,38,"ES="); + mvwaddstr(dbg.win_reg,0,48,"FS="); + mvwaddstr(dbg.win_reg,0,58,"GS="); + mvwaddstr(dbg.win_reg,0,68,"SS="); + + mvwaddstr(dbg.win_reg,1,28,"CS="); + mvwaddstr(dbg.win_reg,1,38,"EIP="); + + + mvwaddstr(dbg.win_reg,1,52,"C Z S O A P D I T "); +} + + +static void DrawBars(void) { + if (has_colors()) { + attrset(COLOR_PAIR(PAIR_BLACK_BLUE)); + } + /* Show the Register bar */ + mvaddstr(dbg.win_reg->_begy-1,0,"---[F1](Register Overview)---"); + /* Show the Data Overview bar perhaps with more special stuff in the end */ + mvaddstr(dbg.win_data->_begy-1,0,"---[F2](Data Overview)---"); + /* Show the Code Overview perhaps with special stuff in bar too */ + mvaddstr(dbg.win_code->_begy-1,0,"---[F3](Code Overview)---"); + /* Show the Output OverView */ + mvaddstr(dbg.win_out->_begy-1,0,"---[F4](OutPut/Input)---"); + attrset(0); +} + + + +static void MakeSubWindows(void) { + /* The Std output win should go in bottem */ + /* Make all the subwindows */ + int outy=1; + /* The Register window */ + dbg.win_reg=subwin(dbg.win_main,4,dbg.win_main->_maxx,outy,0); + outy+=5; + /* The Data Window */ + dbg.win_data=subwin(dbg.win_main,10,dbg.win_main->_maxx,outy,0); + outy+=11; + /* The Code Window */ + dbg.win_code=subwin(dbg.win_main,10,dbg.win_main->_maxx,outy,0); + outy+=11; + /* The output Window */ + dbg.win_out=subwin(dbg.win_main,dbg.win_main->_maxy-outy-1,dbg.win_main->_maxx,outy,0); + dbg.input_y=dbg.win_main->_maxy-1; + scrollok(dbg.win_out,TRUE); + DrawBars(); + Draw_RegisterLayout(); + refresh(); +} + +static void MakePairs(void) { + init_pair(PAIR_BLACK_BLUE, COLOR_BLACK, COLOR_CYAN); + init_pair(PAIR_BYELLOW_BLACK, COLOR_YELLOW /*| FOREGROUND_INTENSITY */, COLOR_BLACK); +} + + +void DBGUI_StartUp(void) { + /* Start the main window */ + dbg.win_main=initscr(); + cbreak(); /* take input chars one at a time, no wait for \n */ + noecho(); /* don't echo input */ + nodelay(dbg.win_main,true); + keypad(dbg.win_main,true); + cycle_count=0; + MakePairs(); + MakeSubWindows(); + + +} + +#endif diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h new file mode 100644 index 00000000..f8eebfe1 --- /dev/null +++ b/src/debug/debug_inc.h @@ -0,0 +1,52 @@ +/* + * 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. + */ + +/* Local Debug Function */ +#include +#include "mem.h" + +#define PAIR_BLACK_BLUE 1 +#define PAIR_BYELLOW_BLACK 2 + + +void DBGUI_StartUp(void); + +struct DBGBlock { + WINDOW * win_main; /* The Main Window */ + WINDOW * win_reg; /* Register Window */ + WINDOW * win_data; /* Data Output window */ + WINDOW * win_code; /* Disassembly/Debug point Window */ + WINDOW * win_out; /* Text Output Window */ + Bit32u active_win; /* Current active window */ + Bit32u input_y; +}; + + +struct DASMLine { + Bit32u pc; + char dasm[80]; + PhysPt ea; + Bit16u easeg; + Bit32u eaoff; +}; + +extern DBGBlock dbg; + + +/* Local Debug Stuff */ +Bitu DasmI386(char* buffer, PhysPt pc, Bitu cur_ip, bool bit32); diff --git a/src/debug/debug_win32.cpp b/src/debug/debug_win32.cpp new file mode 100644 index 00000000..28f94711 --- /dev/null +++ b/src/debug/debug_win32.cpp @@ -0,0 +1,74 @@ +/* + * 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. + */ + +#include +#include +#include + +/* + Have to remember where i ripped this code sometime ago. + +*/ +static void ResizeConsole( HANDLE hConsole, SHORT xSize, SHORT ySize ) { + CONSOLE_SCREEN_BUFFER_INFO csbi; // Hold Current Console Buffer Info + BOOL bSuccess; + SMALL_RECT srWindowRect; // Hold the New Console Size + COORD coordScreen; + + bSuccess = GetConsoleScreenBufferInfo( hConsole, &csbi ); + + // Get the Largest Size we can size the Console Window to + coordScreen = GetLargestConsoleWindowSize( hConsole ); + + // Define the New Console Window Size and Scroll Position + srWindowRect.Right = (SHORT)(min(xSize, coordScreen.X) - 1); + srWindowRect.Bottom = (SHORT)(min(ySize, coordScreen.Y) - 1); + srWindowRect.Left = srWindowRect.Top = (SHORT)0; + + // Define the New Console Buffer Size + coordScreen.X = xSize; + coordScreen.Y = ySize; + + // If the Current Buffer is Larger than what we want, Resize the + // Console Window First, then the Buffer + if( (DWORD)csbi.dwSize.X * csbi.dwSize.Y > (DWORD) xSize * ySize) + { + bSuccess = SetConsoleWindowInfo( hConsole, TRUE, &srWindowRect ); + bSuccess = SetConsoleScreenBufferSize( hConsole, coordScreen ); + } + + // If the Current Buffer is Smaller than what we want, Resize the + // Buffer First, then the Console Window + if( (DWORD)csbi.dwSize.X * csbi.dwSize.Y < (DWORD) xSize * ySize ) + { + bSuccess = SetConsoleScreenBufferSize( hConsole, coordScreen ); + bSuccess = SetConsoleWindowInfo( hConsole, TRUE, &srWindowRect ); + } + + // If the Current Buffer *is* the Size we want, Don't do anything! + return; + } + + +void WIN32_Console() { + ResizeConsole(GetStdHandle(STD_OUTPUT_HANDLE),80,50); + + +} + + diff --git a/src/debug/disasm_tables.h b/src/debug/disasm_tables.h new file mode 100644 index 00000000..0ed79e8f --- /dev/null +++ b/src/debug/disasm_tables.h @@ -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. + */ + +char * RegTable_16[8]= {"ax","cx","dx","bx","sp","bp","si","di"}; +char * RegTable_8[8]= {"al","cl","dl","bl","ah","ch","dh","bh"}; +char * SegTable[8]= {"es","cs","ss","ds","fs","gs","iseg","iseg"}; + + +#define MAX_INFO 3 + +enum { + Eb,Ev,Ew,Ep, + Gb,Gv, + Rb,Rw,Rv, + Ob,Ov, + Sw, + Mp, + Ib,Ibs,Iw,Iv,Ap, + Jb,Jv, + Bd,Bw, + XBnd,Xlea, +/* specials */ + b2,p_es,p_ss,p_cs,p_ds,p_fs,p_gs,p_size,p_addr,p_rep, + s_ax,s_cx,s_dx,s_bx,s_sp,s_bp,s_si,s_di, + s_al,s_cl,s_dl,s_bl,s_ah,s_ch,s_dh,s_bh, + s_1, + Cj, + G1,G2,G3b,G3v,G4,G5, + no=0xff +}; + +enum { + s_jo, s_jno, s_jc, s_jnc, s_je, s_jne, s_jbe, s_jnbe, + s_js, s_jns, s_jp, s_jnp, s_jl, s_jnl, s_jle, s_jnle +}; + + +struct Dentry { + char * start; + Bit8u info[MAX_INFO]; +}; + +static char * G1_Table[8]={"add ","or ","adc ","sbb ","and ","sub ","xor ","cmp "}; +static char * G2_Table[8]={"rol ","ror ","rcl ","rcr ","shl ","shr ","sal ","sar "}; + +static Dentry G3b_Table[8]={ + "test ",Eb,Ib,no, + "test ",Eb,Ib,no, + "not ",Eb,no,no, + "neg ",Eb,no,no, + "mul al,",Eb,no,no, + "imul al,",Eb,no,no, + "div ax,",Eb,no,no, + "idiv ax,",Eb,no,no +}; + +static Dentry G3v_Table[8]={ + "test ",Ev,Iv,no, + "test ",Ev,Iv,no, + "not ",Ev,no,no, + "neg ",Ev,no,no, + "mul ax,",Ev,no,no, + "imul ax,",Ev,no,no, + "div dx:ax,",Ev,no,no, + "idiv dx:ax,",Ev,no,no +}; + +static char * G4_Table[8]={ + "inc ", + "dec ", + "illegal", + "illegal", + "illegal", + "illegal", + "illegal", + "illegal" +}; + +static Dentry G5_Table[8]={ + "inc ",Ev,no,no, + "dec ",Ev,no,no, + "call ",Ev,no,no, + "call ",Ep,no,no, + "jmp ",Ev,no,no, + "jmp ",Ep,no,no, + "push ,",Ev,no,no, + "illegal",no,no,no +}; + + + +static Dentry DTable[256]={ +/* 0 */ + "add ",Eb,Gb,no, "add ",Ev,Gv,no, "add ",Gb,Eb,no, "add ",Gv,Ev,no, + "add ",s_al,Ib,no, "add ",s_ax,Iv,no, "push es",no,no,no, "pop es",no,no,no, + "or ",Eb,Gb,no, "or ",Ev,Gv,no, "or ",Gb,Eb,no, "or ",Gv,Ev,no, + "or ",s_al,Ib,no, "or ",s_ax,Iv,no, "push cs",no,no,no, "",b2,no,no, +/* 1 */ + "adc ",Eb,Gb,no, "adc ",Ev,Gv,no, "adc ",Gb,Eb,no, "adc ",Gv,Ev,no, + "adc ",s_al,Ib,no, "adc ",s_ax,Iv,no, "push ss",no,no,no, "pop ss",no,no,no, + "sbb ",Eb,Gb,no, "sbb ",Ev,Gv,no, "sbb ",Gb,Eb,no, "sbb ",Gv,Ev,no, + "sbb ",s_al,Ib,no, "sbb ",s_ax,Iv,no, "push ds",no,no,no, "pop ds",no,no,no, +/* 2 */ + "and ",Eb,Gb,no, "and ",Ev,Gv,no, "and ",Gb,Eb,no, "and ",Gv,Ev,no, + "and ",s_al,Ib,no, "and ",s_ax,Iv,no, "",p_es,no,no, "daa",no,no,no, + "sub ",Eb,Gb,no, "sub ",Ev,Gv,no, "sub ",Gb,Eb,no, "sub ",Gv,Ev,no, + "sub ",s_al,Ib,no, "sub ",s_ax,Iv,no, "",p_ss,no,no, "das",no,no,no, +/* 3 */ + "xor ",Eb,Gb,no, "xor ",Ev,Gv,no, "xor ",Gb,Eb,no, "xor ",Gv,Ev,no, + "xor ",s_al,Ib,no, "xor ",s_ax,Iv,no, "",p_ss,no,no, "aaa",no,no,no, + "cmp ",Eb,Gb,no, "cmp ",Ev,Gv,no, "cmp ",Gb,Eb,no, "cmp ",Gv,Ev,no, + "cmp ",s_al,Ib,no, "cmp ",s_ax,Iv,no, "",p_ds,no,no, "aas",no,no,no, +/* 4 */ + "inc ",s_ax,no,no, "inc ",s_cx,no,no, "inc ",s_dx,no,no, "inc ",s_bx,no,no, + "inc ",s_sp,no,no, "inc ",s_bp,no,no, "inc ",s_si,no,no, "inc ",s_di,no,no, + "dec ",s_ax,no,no, "dec ",s_cx,no,no, "dec ",s_dx,no,no, "dec ",s_bx,no,no, + "dec ",s_sp,no,no, "dec ",s_bp,no,no, "dec ",s_si,no,no, "dec ",s_di,no,no, +/* 5 */ + "push ",s_ax,no,no, "push ",s_cx,no,no, "push ",s_dx,no,no, "push ",s_bx,no,no, + "push ",s_sp,no,no, "push ",s_bp,no,no, "push ",s_si,no,no, "push ",s_di,no,no, + "pop ",s_ax,no,no, "pop ",s_cx,no,no, "pop ",s_dx,no,no, "pop ",s_bx,no,no, + "pop ",s_sp,no,no, "pop ",s_bp,no,no, "pop ",s_si,no,no, "pop ",s_di,no,no, +/* 6 */ + "pusha",Bd,no,no, "popa",Bd,no,no, "bound",XBnd,no,no, "arpl",Ew,Rw,no, + "",p_fs,no,no, "",p_gs,no,no, "",p_size,no,no, "",p_addr,no,no, + "push ",Iv,no,no, "imul ",Gv,Ev,Iv, "push ",Ibs,no,no, "imul ",Gv,Ev,Ib, + "insb",no,no,no, "ins",Bw,no,no, "oustb",no,no,no, "outs",Bw,no,no, +/* 7 */ + "jo ",Cj,s_jo,no, "jno ",Cj,s_jno,no, "jc ",Cj,s_jc,no, "jnc ",Cj,s_jnc,no, + "je ",Cj,s_je,no, "jne ",Cj,s_jne,no, "jbe ",Cj,s_jbe,no, "jnbe ",Cj,s_jnbe,no, + "js ",Cj,s_js,no, "jns ",Cj,s_jns,no, "jp ",Cj,s_jp,no, "jnp ",Cj,s_jnp,no, + "jl ",Cj,s_jl,no, "jnl ",Cj,s_jnl,no, "jle ",Cj,s_jle,no, "jnle ",Cj,s_jnle,no, +/* 8 */ + "",G1,Eb,Ib, "",G1,Ev,Iv, "",G1,Eb,Ib, "",G1,Ev,Ibs, + "test ",Eb,Gb,no, "test ",Ev,Gv,no, "xchg ",Eb,Gb,no, "xchg ",Ev,Gv,no, + "mov ",Eb,Gb,no, "mov ",Ev,Gv,no, "mov ",Gb,Eb,no, "mov ",Gv,Ev,no, + "mov ",Ew,Sw,no, "lea ",Gv,Xlea,no, "mov ",Sw,Ew,no, "pop ",Ev,no,no, +/* 9 */ + "nop",no,no,no, "xchg ",s_ax,s_cx,no,"xchg ",s_ax,s_dx,no,"xchg ",s_ax,s_bx,no, + "xchg ",s_ax,s_sp,no,"xchg ",s_ax,s_bp,no,"xchg ",s_ax,s_si,no,"xchg ",s_ax,s_di,no, + "cbw",no,no,no, "cwd",no,no,no, "call ",Ap,no,no, "fwait",no,no,no, + "pushf",Bd,no,no, "popf",Bd,no,no, "sahf",no,no,no, "lahf",no,no,no, +/* a */ + "mov ",s_al,Ob,no, "mov ",s_ax,Ov,no, "mov ",Ob,s_al,no, "mov ",Ov,s_ax,no, + "movsb",no,no,no, "movs",Bw,no,no, "cmpsb",no,no,no, "cmps",Bw,no,no, + "test ",s_al,Ib,no, "test ",s_ax,Iv,no, "stosb",no,no,no, "stos",Bw,no,no, + "lodsb",no,no,no, "lods",Bw,no,no, "scasb",no,no,no, "scas",Bw,no,no, +/* b */ + "mov ",s_al,Ib,no, "mov ",s_cl,Ib,no, "mov ",s_dl,Ib,no, "mov ",s_bl,Ib,no, + "mov ",s_ah,Ib,no, "mov ",s_ch,Ib,no, "mov ",s_dh,Ib,no, "mov ",s_bh,Ib,no, + "mov ",s_ax,Iv,no, "mov ",s_cx,Iv,no, "mov ",s_dx,Iv,no, "mov ",s_bx,Iv,no, + "mov ",s_sp,Iv,no, "mov ",s_bp,Iv,no, "mov ",s_si,Iv,no, "mov ",s_di,Iv,no, +/* c */ + "",G2,Eb,Ib, "",G2,Ev,Ib, "ret ",Iw,no,no, "ret",no,no,no, + "les ",Gv,Mp,no, "lds ",Gv,Mp,no, "mov ",Eb,Ib,no, "mov ",Ev,Iv,no, + "enter ",Iw,Ib,no, "leave",no,no,no, "retf ",Iw,no,no, "retf",no,no,no, + "int 03",no,no,no, "int ",Ib,no,no, "into",no,no,no, "iret",Bd,no,no, +/* d */ + "",G2,Eb,s_1, "",G2,Ev,s_1, "",G2,Eb,s_cl, "",G2,Ev,s_cl, + "aam",no,no,no, "aad",no,no,no, "setalc",no,no,no, "xlat",no,no,no, + "esc 0",Ib,no,no, "esc 1",Ib,no,no, "esc 2",Ib,no,no, "esc 3",Ib,no,no, + "esc 4",Ib,no,no, "esc 5",Ib,no,no, "esc 6",Ib,no,no, "esc 7",Ib,no,no, +/* e */ + "loopne ",Jb,no,no, "loope ",Jb,no,no, "loop ",Jb,no,no, "jcxz ",Jb,no,no, + "in ",s_al,Ib,no, "in ",s_ax,Ib,no, "out ",Ib,s_al,no, "out ",Ib,s_ax,no, + "call ",Jv,no,no, "jmp ",Jv,no,no, "jmp",Ap,no,no, "jmp ",Jb,no,no, + "in ",s_al,s_dx,no, "in ",s_ax,s_dx,no, "out ",s_dx,s_al,no,"out ",s_dx,s_ax,no, +/* f */ + "lock",no,no,no, "cb ",Iw,no,no, "repne ",p_rep,no,no,"repe ",p_rep,no,no, + "hlt",no,no,no, "cmc",no,no,no, "",G3b,no,no, "",G3v,no,no, + "clc",no,no,no, "stc",no,no,no, "cli",no,no,no, "sti",no,no,no, + "cld",no,no,no, "std",no,no,no, "",G4,Eb,no, "",G5,no,no, +}; + + + diff --git a/src/dos/Makefile.am b/src/dos/Makefile.am new file mode 100644 index 00000000..1a414826 --- /dev/null +++ b/src/dos/Makefile.am @@ -0,0 +1,7 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include + +noinst_LIBRARIES = libdos.a +libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioctl.cpp dos_memory.cpp \ + dos_misc.cpp dos_classes.cpp dos_programs.cpp dos_tables.cpp \ + drives.cpp drives.h drive_virtual.cpp drive_local.cpp \ + dev_con.h diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h new file mode 100644 index 00000000..003c15ef --- /dev/null +++ b/src/dos/dev_con.h @@ -0,0 +1,105 @@ +/* + * 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. + */ + +class device_CON : public DOS_Device { +public: + device_CON(); + bool Read(Bit8u * data,Bit16u * size); + bool Write(Bit8u * data,Bit16u * size); + bool Seek(Bit32u * pos,Bit32u type); + bool Close(); + Bit16u GetInformation(void); +private: + Bit8u cache; +}; + +bool device_CON::Read(Bit8u * data,Bit16u * size) { + Bit16u oldax=reg_ax; + Bit16u count=0; + if ((cache) && (*size)) { + data[count++]=cache; + cache=0; + } + while (*size>count) { + reg_ah=0; + CALLBACK_RunRealInt(0x16); + switch(reg_al) { + case 13: + data[count++]=0x0D; +// if (*size>count) data[count++]=0x0A; +// else cache=0x0A; + *size=count; + reg_ax=oldax; + return true; + default: + data[count++]=reg_al; + break; + case 0: + data[count++]=reg_al; + if (*size>count) data[count++]=reg_ah; + else cache=reg_ah; + break; + } + } + *size=count; + reg_ax=oldax; + return true; +} + +extern void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page); +bool device_CON::Write(Bit8u * data,Bit16u * size) { +//TODO Hack a way to call int 0x10 + Bit16u oldax=reg_ax;Bit16u oldbx=reg_bx; + Bit16u count=0; + while (*size>count) { +/* + reg_al=data[count]; + reg_ah=0x0e; + reg_bx=0x0007; + CALLBACK_RunRealInt(0x10); +*/ + INT10_TeletypeOutput(data[count],7,false,0); + count++; + } + *size=count; +// reg_ax=oldax;reg_bx=oldbx; + return true; +} + +bool device_CON::Seek(Bit32u * pos,Bit32u type) { + return false; +} + +bool device_CON::Close() { + return false; +} + +Bit16u device_CON::GetInformation(void) { + Bit16u head=mem_readw(BIOS_KEYBOARD_BUFFER_HEAD); + Bit16u tail=mem_readw(BIOS_KEYBOARD_BUFFER_TAIL); + + if ((head==tail) && !cache) return 0x80D3; /* No Key Available */ + return 0x8093; /* Key Available */ +}; + + +device_CON::device_CON() { + name="CON"; + cache=0; +} + diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp new file mode 100644 index 00000000..85415ac6 --- /dev/null +++ b/src/dos/dos.cpp @@ -0,0 +1,790 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include "dosbox.h" +#include "bios.h" +#include "mem.h" +#include "callback.h" +#include "regs.h" +#include "dos_inc.h" + +DOS_Block dos; +static Bit8u dos_copybuf[0x10000]; +static Bitu call_20,call_21,call_theend; + +void DOS_SetError(Bit16u code) { + dos.errorcode=code; +}; + + +#define DOSNAMEBUF 256 +static Bitu DOS_21Handler(void) { +//TODO KEYBOARD Check for break + char name1[DOSNAMEBUF+1]; + char name2[DOSNAMEBUF+1]; + switch (reg_ah) { + case 0x00: /* Terminate Program */ + E_Exit("DOS:Unhandled call %02X",reg_ah); + break; + case 0x01: /* Read character from STDIN, with echo */ + { + Bit8u c;Bit16u n=1; + DOS_ReadFile(STDIN,&c,&n); + reg_al=c; + DOS_WriteFile(STDOUT,&c,&n); + } + break; + case 0x02: /* Write character to STDOUT */ + { + Bit8u c=reg_dl;Bit16u n=1; + DOS_WriteFile(STDOUT,&c,&n); + } + break; + case 0x03: /* Read character from STDAUX */ + case 0x04: /* Write Character to STDAUX */ + case 0x05: /* Write Character to PRINTER */ + E_Exit("DOS:Unhandled call %02X",reg_ah); + break; + case 0x06: /* Direct Console Output / Input */ + switch (reg_dl) { + case 0xFF: /* Input */ + { +//TODO Make this better according to standards + if (!DOS_GetSTDINStatus()) { + CALLBACK_SZF(true); + break; + } + Bit8u c;Bit16u n=1; + DOS_ReadFile(STDIN,&c,&n); + reg_al=c; + CALLBACK_SZF(false); + break; + } + default: + { + Bit8u c=reg_dl;Bit16u n=1; + DOS_WriteFile(STDOUT,&c,&n); + } + break; + }; + break; + case 0x07: /* Character Input, without echo */ + { + Bit8u c;Bit16u n=1; + DOS_ReadFile (STDIN,&c,&n); + reg_al=c; + break; + }; + case 0x08: /* Direct Character Input, without echo */ + { + Bit8u c;Bit16u n=1; + DOS_ReadFile (STDIN,&c,&n); + reg_al=c; + break; + }; + case 0x09: /* Write string to STDOUT */ + { + Bit8u c;Bit16u n=1; + PhysPt buf=real_phys(Segs[ds].value,reg_dx); + while ((c=mem_readb(buf++))!='$') { + DOS_WriteFile(STDOUT,&c,&n); + } + } + break; + case 0x0a: /* Buffered Input */ + { + //TODO ADD Break checkin in STDIN but can't care that much for it + PhysPt data=real_phys(Segs[ds].value,reg_dx); + Bit8u free=mem_readb(data); + Bit8u read=0;Bit8u c;Bit16u n=1; + if (!free) break; + while (read12) || (reg_dh==0)) { reg_al=0xff;break;} + if ((reg_dl>31) || (reg_dl==0)) { reg_al=0xff;break;} + dos.date.year=reg_cx; + dos.date.month=reg_dh; + dos.date.day=reg_dl; + reg_al=0; + break; + case 0x2c: /* Get System Time */ +//TODO Get time through bios calls date is fixed + { + Bit32u ticks=mem_readd(BIOS_TIMER); + Bit32u seconds=(ticks*10)/182; + reg_ch=(Bit8u)(seconds/3600); + reg_cl=(Bit8u)(seconds % 3600)/60; + reg_dh=(Bit8u)(seconds % 60); + reg_dl=(Bit8u)(ticks % 19)*5; + } + break; + case 0x2d: /* Set System Time */ + LOG_DEBUG("DOS:Set System Time not supported"); + reg_al=0; /* Noone is changing system time */ + break; + case 0x2e: /* Set Verify flag */ + dos.verify=(reg_al==1); + break; + case 0x2f: /* Get Disk Transfer Area */ + SetSegment_16(es,RealSeg(dos.dta)); + reg_bx=RealOff(dos.dta); + break; + case 0x30: /* Get DOS Version */ + if (reg_al==0) reg_bh=0xFF; /* Fake Microsoft DOS */ + if (reg_al==1) reg_bh=0x10; /* DOS is in HMA */ + reg_al=dos.version.major; + reg_ah=dos.version.minor; + break; + case 0x31: /* Terminate and stay resident */ +//TODO First get normal files executing + DOS_ResizeMemory(dos.psp,®_dx); + if (DOS_Terminate(true)) { + dos.return_code=reg_al; + dos.return_mode=RETURN_TSR; + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + case 0x33: /* Extended Break Checking */ + switch (reg_al) { + case 0:reg_dl=dos.breakcheck;break; /* Get the breakcheck flag */ + case 1:dos.breakcheck=(reg_dl>0);break; /* Set the breakcheck flag */ + case 2:{bool old=dos.breakcheck;dos.breakcheck=(reg_dl>0);reg_dl=old;}break; + case 5:reg_dl=3;break; /* Always boot from c: :) */ + case 6: /* Get true version number */ + reg_bl=dos.version.major; + reg_bh=dos.version.minor; + reg_dl=dos.version.revision; + reg_dh=0x10; /* Dos in HMA */ + break; + default: + E_Exit("DOS:Illegal 0x33 Call %2X",reg_al); + } + break; + case 0x34: /* Get INDos Flag */ + SetSegment_16(es,RealSeg(dos.tables.indosflag)); + reg_bx=RealOff(dos.tables.indosflag); + break; + case 0x35: /* Get interrupt vector */ + reg_bx=real_readw(0,((Bit16u)reg_al)*4); + SetSegment_16(es,real_readw(0,((Bit16u)reg_al)*4+2)); + break; + case 0x36: /* Get Free Disk Space */ + { + Bit16u bytes,sectors,clusters,free; + if (DOS_GetFreeDiskSpace(reg_dl,&bytes,§ors,&clusters,&free)) { + reg_ax=sectors; + reg_bx=free; + reg_cx=bytes; + reg_dx=clusters; + } else { + reg_ax=0xffff; + } + } + break; + case 0x37: /* Get/Set Switch char Get/Set Availdev thing */ +//TODO Give errors for these functions to see if anyone actually uses this shit- + switch (reg_al) { + case 0: + reg_al=0;reg_dl=0x2f;break; /* always return '/' like dos 5.0+ */ + case 1: + reg_al=0;break; + case 2: + reg_al=0;reg_dl=0x2f;break; + case 3: + reg_al=0;break; + }; + LOG_DEBUG("DOS:0x37:Call for not supported switchchar"); + break; + case 0x38: /* Set Country Code */ + LOG_DEBUG("DOS:Setting country code not supported"); + CALLBACK_SCF(true); + break; + if (reg_al==0) { /* Get country specidic information */ + + } else { /* Set country code */ + + + } + break; + case 0x39: /* MKDIR Create directory */ + MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + if (DOS_MakeDir(name1)) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + case 0x3a: /* RMDIR Remove directory */ + MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + if (DOS_RemoveDir(name1)) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + case 0x3b: /* CHDIR Set current directory */ + MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + if (DOS_ChangeDir(name1)) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + case 0x3c: /* CREATE Create of truncate file */ + MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + if (DOS_CreateFile(name1,reg_cx,®_ax)) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + case 0x3d: /* OPEN Open existing file */ + MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + if (DOS_OpenFile(name1,reg_al,®_ax)) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + case 0x3e: /* CLOSE Close file */ + if (DOS_CloseFile(reg_bx)) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + case 0x3f: /* READ Read from file or device */ + { + Bit16u toread=reg_cx; + if (DOS_ReadFile(reg_bx,dos_copybuf,&toread)) { + MEM_BlockWrite(real_phys(Segs[ds].value,reg_dx),dos_copybuf,toread); + reg_ax=toread; + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + } + case 0x40: /* WRITE Write to file or device */ + { + Bit16u towrite=reg_cx; + MEM_BlockRead(real_phys(Segs[ds].value,reg_dx),dos_copybuf,towrite); + if (DOS_WriteFile(reg_bx,dos_copybuf,&towrite)) { + reg_ax=towrite; + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + }; + case 0x41: /* UNLINK Delete file */ + MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + if (DOS_UnlinkFile(name1)) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + case 0x42: /* LSEEK Set current file position */ + { + Bit32u pos=(reg_cx<<16) + reg_dx; + if (DOS_SeekFile(reg_bx,&pos,reg_al)) { + reg_dx=(Bit16u)(pos >> 16); + reg_ax=(Bit16u)(pos & 0xFFFF); + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + } + case 0x43: /* Get/Set file attributes */ +//TODO FIX THIS HACK + MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + switch (reg_al) + case 0x00: /* Get */ + { + if (DOS_GetFileAttr(name1,®_cx)) { + CALLBACK_SCF(false); + } else { + CALLBACK_SCF(true); + reg_ax=dos.errorcode; + } + break; + case 0x01: /* Set */ + LOG_DEBUG("DOS:Set File Attributes for %s not supported",name1); + CALLBACK_SCF(false); + break; + default: + E_Exit("DOS:0x43:Illegal subfunction %2X",reg_al); + } + break; + case 0x44: /* IOCTL Functions */ + if (DOS_IOCTL(reg_al,reg_bx)) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + case 0x45: /* DUP Duplicate file handle */ + if (DOS_DuplicateEntry(reg_bx,®_ax)) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + case 0x46: /* DUP2,FORCEDUP Force duplicate file handle */ + E_Exit("Unhandled Dos 21 call %02X",reg_ah); + break; + case 0x47: /* CWD Get current directory */ + //TODO Memory + if (DOS_GetCurrentDir(reg_dl,real_off(Segs[ds].value,reg_si))) { + reg_ax=0x0100; + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + case 0x48: /* Allocate memory */ + { + Bit16u size=reg_bx;Bit16u seg; + if (DOS_AllocateMemory(&seg,&size)) { + reg_ax=seg; + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + reg_bx=size; + CALLBACK_SCF(true); + } + break; + } + case 0x49: /* Free memory */ + if (DOS_FreeMemory(Segs[es].value)) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + case 0x4a: /* Resize memory block */ + { + Bit16u size=reg_bx; + if (DOS_ResizeMemory(Segs[es].value,&size)) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + reg_bx=size; + CALLBACK_SCF(true); + } + break; + } + case 0x4b: /* EXEC Load and/or execute program */ + { + MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + if (DOS_Execute(name1,(ParamBlock *)real_off(Segs[es].value,reg_bx),reg_al)) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + } + break; +//TODO Check for use of execution state AL=5 + case 0x4c: /* EXIT Terminate with return code */ + { + if (DOS_Terminate(false)) { + dos.return_code=reg_al; + dos.return_mode=RETURN_EXIT; + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + } + case 0x4d: /* Get Return code */ + reg_al=dos.return_code; + reg_ah=dos.return_mode; + break; + case 0x4e: /* FINDFIRST Find first matching file */ + MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + if (DOS_FindFirst(name1,reg_cx)) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + }; + break; + case 0x4f: /* FINDNEXT Find next matching file */ + if (DOS_FindNext()) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + }; + break; + case 0x50: /* Set current PSP */ + dos.psp=reg_bx; + break; + case 0x51: /* Get current PSP */ + reg_bx=dos.psp; + break; + case 0x52: /* Get list of lists */ + SetSegment_16(es,0); + reg_bx=0; + LOG_ERROR("Call is made for list of lists not supported let's hope for the best"); + break; +//TODO Think hard how shit this is gonna be +//And will any game ever use this :) + case 0x53: /* Translate BIOS parameter block to drive parameter block */ +//YEAH RIGHT + case 0x54: /* Get verify flag */ + case 0x55: /* Create Child PSP*/ + E_Exit("Unhandled Dos 21 call %02X",reg_ah); + break; + case 0x56: /* RENAME Rename file */ + MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + MEM_StrCopy(real_phys(Segs[es].value,reg_di),name2,DOSNAMEBUF); + if (DOS_Rename(name1,name2)) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + case 0x57: /* Get/Set File's Date and Time */ + reg_cx=0; + reg_dx=0; + LOG_DEBUG("DOS:57:Getting/Setting File Date is faked",reg_ah); + break; + case 0x58: /* Get/Set Memory allocation strategy */ + LOG_DEBUG("DOS:58:Not Supported Set//Get memory allocation"); + break; + case 0x59: /* Get Extended error information */ + E_Exit("Unhandled Dos 21 call %02X",reg_ah); + break; + case 0x5a: /* Create temporary file */ + { + Bit16u handle; + MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + if (DOS_CreateTempFile(name1,&handle)) { + reg_ax=handle; + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + } + break; + case 0x5b: /* Create new file */ + { + MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + Bit16u handle; + if (DOS_OpenFile(name1,0,&handle)) { + DOS_CloseFile(handle); + DOS_SetError(DOSERR_ACCESS_DENIED); + reg_ax=dos.errorcode; + CALLBACK_SCF(false); + break; + } + if (DOS_CreateFile(name1,reg_cx,&handle)) { + reg_ax=handle; + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + } + case 0x5c: /* FLOCK File region locking */ + case 0x5d: /* Network Functions */ + case 0x5e: /* More Network Functions */ + case 0x5f: /* And Even More Network Functions */ + E_Exit("DOS:Unhandled call %02X",reg_ah); + break; + case 0x60: /* Canonicalize filename or path */ + MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + if (DOS_Canonicalize(name1,real_off(Segs[es].value,reg_di))) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + case 0x62: /* Get Current PSP Address */ + reg_bx=dos.psp; + break; + case 0x63: /* Weirdo double byte stuff */ + reg_al=0xff; + LOG_WARN("DOS:0x63:Doubly byte characters not supported"); + break; + case 0x64: /* Set device driver lookahead flag */ + E_Exit("Unhandled Dos 21 call %02X",reg_ah); + break; + case 0x65: /* Get extented country information and a lot of other useless shit*/ + /* Todo maybe fully support this for now we set it standard for USA */ + { + LOG_DEBUG("DOS:65:Extended country information call"); + Bit8u * data=real_off(Segs[es].value,reg_di); + switch (reg_al) { + case 1: + real_writeb(Segs[es].value,reg_di,reg_al); + real_writew(Segs[es].value,reg_di+1,4); + real_writew(Segs[es].value,reg_di+3,1); + real_writew(Segs[es].value,reg_di+5,37); + reg_cx=4; + CALLBACK_SCF(false); + break; + default: + E_Exit("DOS:0x65:Unhandled country information call %2X",reg_al); + }; + break; + } + case 0x66: /* Get/Set global code page table */ + if (reg_al==1) { + LOG_DEBUG("Getting global code page table"); + reg_bx=reg_dx=437; + CALLBACK_SCF(false); + break; + } + LOG_ERROR("DOS:Setting code page table is not supported"); + break; + case 0x67: /* Set handle countr */ + /* Weird call to increase amount of file handles needs to allocate memory if >20 */ + LOG_DEBUG("DOS:67:Set Handle Count not working"); + CALLBACK_SCF(false); + break; + case 0x68: /* FFLUSH Commit file */ + E_Exit("Unhandled Dos 21 call %02X",reg_ah); + break; + case 0x69: /* Get/Set disk serial number */ + { + Bit8u * temp=real_off(Segs[ds].value,reg_dx); + switch(reg_al) { + case 0x00: /* Get */ + LOG_DEBUG("DOS:Get Disk serial number"); + CALLBACK_SCF(true); + break; + case 0x01: + LOG_DEBUG("DOS:Set Disk serial number"); + default: + E_Exit("DOS:Illegal Get Serial Number call %2X",reg_al); + } + break; + } + case 0x6c: /* Extended Open/Create */ + E_Exit("Unhandled Dos 21 call %02X",reg_ah); + break; + case 0x71: /* Unknown probably 4dos detection */ + reg_ax=0x7100; + CALLBACK_SCF(true); + LOG_WARN("DOS:Windows long file name support call %2X",reg_al); + break; + case 0xE0: + LOG_DEBUG("DOS:E0:Unhandled, what should this call do?"); + break; + default: + E_Exit("DOS:Unhandled call %02X",reg_ah); + break; + }; + return CBRET_NONE; +/* That's it now let's get it working */ +}; + + + +static Bitu DOS_20Handler(void) { + + reg_ax=0x4c00; + DOS_21Handler(); + return CBRET_NONE; +} + + +void DOS_Init(void) { + call_20=CALLBACK_Allocate(); + CALLBACK_Setup(call_20,DOS_20Handler,CB_IRET); + RealSetVec(0x20,CALLBACK_RealPointer(call_20)); + + call_21=CALLBACK_Allocate(); + CALLBACK_Setup(call_21,DOS_21Handler,CB_IRET); + RealSetVec(0x21,CALLBACK_RealPointer(call_21)); + + DOS_SetupFiles(); /* Setup system File tables */ + DOS_SetupDevices(); /* Setup dos devices */ + DOS_SetupMemory(); /* Setup first MCB */ + DOS_SetupTables(); + DOS_SetupPrograms(); + DOS_SetupMisc(); /* Some additional dos interrupts */ + DOS_SetDefaultDrive(25); + /* Execute the file that should be */ + dos.version.major=5; + dos.version.minor=0; +// DOS_RunProgram(startname); +}; diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp new file mode 100644 index 00000000..74098aec --- /dev/null +++ b/src/dos/dos_classes.cpp @@ -0,0 +1,181 @@ +/* + * 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. + */ + +#include +#include +#include "dosbox.h" +#include "mem.h" +#include "dos_inc.h" + +/* + Work in progress, making classes for handling certain internal memory structures in dos + This should make it somewhat easier for porting to other endian machines and make + dos work a bit easier. +*/ + + +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 */ + +/* 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; + +}; + + + +class DOS_PSP { +public: + DOS_PSP(Bit16u segment); + + void MakeNew(Bit16u env,Bit16u memsize); + + + Bit16u base_seg; + +private: + PhysPt off; +}; + +DOS_PSP::DOS_PSP(Bit16u segment) { + base_seg=segment; + off=Real2Phys(RealMake(segment,0)); +}; + +void DOS_PSP::MakeNew(Bit16u env,Bit16u next_para) { + Bitu i; + for (i=0;i<256;i++) mem_writeb(off+i,0); +/* Standard blocks */ + mem_writeb(off+offsetof(sPSP,exit[0]),0xcd); + mem_writeb(off+offsetof(sPSP,exit[1]),0x20); + + mem_writeb(off+offsetof(sPSP,service[0]),0xcd); + mem_writeb(off+offsetof(sPSP,service[1]),0x21); + mem_writeb(off+offsetof(sPSP,service[2]),0xcb); + + mem_writew(off+offsetof(sPSP,next_seg),next_para); + + +// mem_writew(off+offsetof(sPSP,psp_parent),dos.psp->base_seg); + + /* Setup initial file table */ + mem_writed(off+offsetof(sPSP,int_22),RealGetVec(0x22)); + mem_writed(off+offsetof(sPSP,int_23),RealGetVec(0x23)); + mem_writed(off+offsetof(sPSP,int_24),RealGetVec(0x24)); + + +#if 0 + + newpsp->mem_size=prevpsp->mem_size; + newpsp->environment=0; + + newpsp->int_22.full=real_getvec(0x22); + newpsp->int_23.full=real_getvec(0x23); + newpsp->int_24.full=real_getvec(0x24); + + newpsp->psp_parent=dos.psp; + newpsp->prev_psp.full=0xFFFFFFFF; + + Bit32u i; + Bit8u * prevfile=real_off(prevpsp->file_table.seg,prevpsp->file_table.off); + for (i=0;i<20;i++) newpsp->files[i]=prevfile[i]; + + newpsp->max_files=20; + newpsp->file_table.seg=pspseg; + newpsp->file_table.off=offsetof(PSP,files); + /* Save the old DTA in this psp */ + newpsp->dta.seg=dos.dta.seg; + newpsp->dta.off=dos.dta.off; + /* Setup the DTA */ + dos.dta.seg=pspseg; + dos.dta.off=0x80; + return; +#endif + + +} + + +void DOS_FCB::Set_drive(Bit8u a){ + mem_writeb(off+offsetof(FCB,drive),a); +} +void DOS_FCB::Set_filename(char * a){ + MEM_BlockWrite(off+offsetof(FCB,filename),a,8); +} +void DOS_FCB::Set_ext(char * a) { + MEM_BlockWrite(off+offsetof(FCB,ext),a,3); +} +void DOS_FCB::Set_current_block(Bit16u a){ + mem_writew(off+offsetof(FCB,current_block),a); +} +void DOS_FCB::Set_record_size(Bit16u a){ + mem_writew(off+offsetof(FCB,record_size),a); +} +void DOS_FCB::Set_filesize(Bit32u a){ + mem_writed(off+offsetof(FCB,filesize),a); +} +void DOS_FCB::Set_date(Bit16u a){ + mem_writew(off+offsetof(FCB,date),a); +} +void DOS_FCB::Set_time(Bit16u a){ + mem_writew(off+offsetof(FCB,time),a); +} +Bit8u DOS_FCB::Get_drive(void){ + return mem_readb(off+offsetof(FCB,drive)); +} +void DOS_FCB::Get_filename(char * a){ + MEM_BlockRead(off+offsetof(FCB,filename),a,8); +} +void DOS_FCB::Get_ext(char * a){ + MEM_BlockRead(off+offsetof(FCB,ext),a,3); +} +Bit16u DOS_FCB::Get_current_block(void){ + return mem_readw(off+offsetof(FCB,current_block)); +} +Bit16u DOS_FCB::Get_record_size(void){ + return mem_readw(off+offsetof(FCB,record_size)); +} +Bit32u DOS_FCB::Get_filesize(void){ + return mem_readd(off+offsetof(FCB,filesize)); +} +Bit16u DOS_FCB::Get_date(void){ + return mem_readw(off+offsetof(FCB,date)); +} +Bit16u DOS_FCB::Get_time(void){ + return mem_readw(off+offsetof(FCB,time)); +} diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp new file mode 100644 index 00000000..ae2630b5 --- /dev/null +++ b/src/dos/dos_devices.cpp @@ -0,0 +1,77 @@ +/* + * 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. + */ + +#include +#include "dosbox.h" +#include "callback.h" +#include "cpu.h" +#include "mem.h" +#include "bios.h" +#include "dos_inc.h" +#include "support.h" + +#define MAX_DEVICES 10 +/* Include all the devices */ + +#include "dev_con.h" + + +static DOS_Device * devices[MAX_DEVICES]; +static Bit32u device_count; + +Bit8u DOS_FindDevice(char * name) { + /* loop through devices */ + Bit8u index=0; + while (indexname)==0) return index; + } + index++; + } + return 255; +} + + +void DOS_AddDevice(DOS_Device * adddev) { +//TODO Give the Device a real handler in low memory that responds to calls + if (device_countfhandle=handle; + } else { + E_Exit("DOS:Too many devices added"); + } +} + +void DOS_SetupDevices(void) { + device_count=0; + DOS_Device * newdev; + newdev=new device_CON(); + DOS_AddDevice(newdev); +} + diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp new file mode 100644 index 00000000..fd3fb54b --- /dev/null +++ b/src/dos/dos_execute.cpp @@ -0,0 +1,439 @@ +/* + * 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. + */ + +#include +#include "dosbox.h" +#include "mem.h" +#include "dos_inc.h" +#include "cpu.h" +#pragma pack(1) + + +struct EXE_Header { + + Bit16u signature; /* EXE Signature MZ or ZM */ + Bit16u extrabytes; /* Bytes on the last page */ + Bit16u pages; /* Pages in file */ + Bit16u relocations; /* Relocations in file */ + Bit16u headersize; /* Paragraphs in header */ + Bit16u minmemory; /* Minimum amount of memory */ + Bit16u maxmemory; /* Maximum amount of memory */ + Bit16u initSS; + Bit16u initSP; + Bit16u checksum; + Bit16u initIP; + Bit16u initCS; + Bit16u reloctable; + Bit16u overlay; +}; +#pragma pack() + +#define MAGIC1 0x5a4d +#define MAGIC2 0x4d5a +#define MAXENV 32768u +#define ENV_KEEPFREE 83 /* keep unallocated by environment variables */ + /* The '65' added to nEnvSize does not cover the additional stuff: + + 2 bytes: number of strings + + 80 bytes: maximum absolute filename + + 1 byte: '\0' + -- 1999/04/21 ska */ +#define LOADNGO 0 +#define LOAD 1 +#define OVERLAY 3 + + +bool DOS_Terminate(bool tsr) { + PSP * psp=(PSP *)real_off(dos.psp,0); + if (!tsr) { + /* Free Files owned by process */ + for (Bit16u i=0;imax_files;i++) { + DOS_CloseFile(i); + } + DOS_FreeProcessMemory(dos.psp); + }; + dos.psp=psp->psp_parent; + PSP * oldpsp=(PSP *)real_off(dos.psp,0); + /* Restore the DTA */ + dos.dta=psp->dta; + /* Restore the old CS:IP from int 22h */ + RealPt old22; + old22=RealGetVec(0x22); + SetSegment_16(cs,RealSeg(old22)); + reg_ip=RealOff(old22); + /* Restore the SS:SP to the previous one */ + SetSegment_16(ss,RealSeg(oldpsp->stack)); + reg_sp=RealOff(oldpsp->stack); + /* Restore interrupt 22,23,24 */ + RealSetVec(0x22,psp->int_22); + RealSetVec(0x23,psp->int_23); + RealSetVec(0x24,psp->int_24); + + return true; +} + + + +static bool MakeEnv(char * name,Bit16u * segment) { + + /* If segment to copy environment is 0 copy the caller's environment */ + PSP * psp=(PSP *)real_off(dos.psp,0); + Bit8u * envread,*envwrite; + Bit16u envsize=1; + bool parentenv=true; + + if (*segment==0) { + if (!psp->environment) parentenv=false; //environment seg=0 + envread=real_off(psp->environment,0); + } else { + if (!*segment) parentenv=false; //environment seg=0 + envread=real_off(*segment,0); + } + + //TODO Make a good DOS first psp + if (parentenv) { + for (envsize=0; ;envsize++) { + if (envsize>=MAXENV - ENV_KEEPFREE) { + DOS_SetError(DOSERR_ENVIRONMENT_INVALID); + return false; + } + if (readw(envread+envsize)==0) break; + } + envsize += 2; /* account for trailing \0\0 */ + } + Bit16u size=long2para(envsize+ENV_KEEPFREE); + if (!DOS_AllocateMemory(segment,&size)) return false; + envwrite=real_off(*segment,0); + if (parentenv) { + bmemcpy(envwrite,envread,envsize); + envwrite+=envsize; + } else { + *envwrite++=0; + } + *((Bit16u *) envwrite)=1; + envwrite+=2; + //TODO put the filename here + return DOS_Canonicalize(name,envwrite); +}; + +bool DOS_NewPSP(Bit16u pspseg) { + PSP * newpsp=(PSP *)real_off(pspseg,0); + PSP * prevpsp=(PSP *)real_off(dos.psp,0); + + memset((void *)newpsp,0,sizeof(PSP)); + newpsp->exit[0]=0xcd;newpsp->exit[1]=0x20; + newpsp->service[0]=0xcd;newpsp->service[0]=0x21;newpsp->service[0]=0xcb; + + newpsp->mem_size=prevpsp->mem_size; + newpsp->environment=0; + + newpsp->int_22=RealGetVec(0x22); + newpsp->int_23=RealGetVec(0x23); + newpsp->int_24=RealGetVec(0x24); + + newpsp->psp_parent=dos.psp; + newpsp->prev_psp=0xFFFFFFFF; + + Bit32u i; + Bit8u * prevfile=Real2Host(prevpsp->file_table); + for (i=0;i<20;i++) newpsp->files[i]=prevfile[i]; + + newpsp->max_files=20; + newpsp->file_table=RealMake(pspseg,offsetof(PSP,files)); + /* Save the old DTA in this psp */ + newpsp->dta=dos.dta; + /* Setup the DTA */ + dos.dta=RealMake(pspseg,0x80); + return true; +}; + +static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { + + PSP * psp=(PSP *)real_off(pspseg,0); + /* Fix the PSP index of this MCB */ + MCB * pspmcb=(MCB *)real_off(pspseg-1,0); + pspmcb->psp_segment=pspseg; + MCB * envmcb=(MCB *)real_off(envseg-1,0); + envmcb->psp_segment=pspseg; + + memset((void *)psp,0,sizeof(PSP)); + Bit32u i; + + psp->exit[0]=0xcd;psp->exit[1]=0x20; + psp->mem_size=memsize+pspseg; + psp->environment=envseg; + + psp->int_22=RealGetVec(0x22); + psp->int_23=RealGetVec(0x23); + psp->int_24=RealGetVec(0x24); + + psp->service[0]=0xcd;psp->service[0]=0x21;psp->service[0]=0xcb; + + psp->psp_parent=dos.psp; + psp->prev_psp=RealMake(dos.psp,0); + + for (i=0;i<20;i++) psp->files[i]=0xff; + psp->files[STDIN]=DOS_FindDevice("CON"); + psp->files[STDOUT]=DOS_FindDevice("CON"); + psp->files[STDERR]=DOS_FindDevice("CON"); + psp->files[STDAUX]=DOS_FindDevice("CON"); + psp->files[STDNUL]=DOS_FindDevice("CON"); + psp->files[STDPRN]=DOS_FindDevice("CON"); + + psp->max_files=20; + psp->file_table=RealMake(pspseg,offsetof(PSP,files)); + /* Save old DTA in psp */ + psp->dta=dos.dta; + + /* Setup the DTA */ + dos.dta=RealMake(pspseg,0x80); +} + +static void SetupCMDLine(Bit16u pspseg,ParamBlock * block) { + PSP * psp=(PSP *)real_off(pspseg,0); + + if (block->exec.cmdtail) { + memcpy((void *)&psp->cmdtail,(void *)Real2Host(block->exec.cmdtail),128); + } else { + char temp[]=""; + psp->cmdtail.count=strlen(temp); + strcpy((char *)&psp->cmdtail.buffer,temp); + psp->cmdtail.buffer[0]=0x0d; + + } +} + + + + +static bool COM_Load(char * name,ParamBlock * block,Bit8u flag) { + Bit16u fhandle; + Bit16u size;Bit16u readsize; + Bit16u envseg,comseg; + Bit32u pos; + + PSP * callpsp=(PSP *)real_off(dos.psp,0); + + if (!DOS_OpenFile(name,OPEN_READ,&fhandle)) return false; + if (flag!=OVERLAY) { + /* Allocate a new Environment */ + envseg=block->exec.envseg; + if (!MakeEnv(name,&envseg)) return false; + /* Allocate max memory for COM file and PSP */ + size=0xffff; + DOS_AllocateMemory(&comseg,&size); + //TODO Errors check for minimun of 64kb in pages + if (Bit32u(size <<4)<0x1000) { + DOS_SetError(DOSERR_INSUFFICIENT_MEMORY); + DOS_FreeMemory(envseg); + return false; + } + DOS_AllocateMemory(&comseg,&size); + } else { + comseg=block->overlay.loadseg; + } + /* Memory allocated now load the program */ + /* Now copy the File into allocated memory */ + pos=0; + DOS_SeekFile(fhandle,&pos,0); + readsize=0xffff-256; + if (flag==OVERLAY) { + DOS_ReadFile(fhandle,real_host(comseg,0),&readsize); + } else { + DOS_ReadFile(fhandle,real_host(comseg,256),&readsize); + } + DOS_CloseFile(fhandle); + if (flag==OVERLAY) /* Everything what should be done for Overlays */ + return true; + SetupPSP(comseg,size,envseg); + SetupCMDLine(comseg,block); + /* Setup termination Address */ + RealSetVec(0x22,RealMake(Segs[cs].value,reg_ip)); + /* Everything setup somewhat setup CS:IP and SS:SP */ + /* First save the SS:SP of program that called execute */ + callpsp->stack=RealMake(Segs[ss].value,reg_sp); + /* Clear out first Stack entry to point to int 20h at psp:0 */ + real_writew(comseg,0xfffe,0); + dos.psp=comseg; + switch (flag) { + case LOADNGO: + SetSegment_16(cs,comseg); + SetSegment_16(ss,comseg); + SetSegment_16(ds,comseg); + SetSegment_16(es,comseg); + flags.intf=true; + reg_ip=0x100; + reg_sp=0xFFFE; + reg_ax=0; + reg_bx=reg_cx=reg_dx=reg_si=reg_di=reg_bp=0; + return true; + case LOAD: + block->exec.initsssp=RealMake(comseg,0xfffe); + block->exec.initcsip=RealMake(comseg,0x100); + return true; + } + return false; + +} + + +static bool EXE_Load(char * name,ParamBlock * block,Bit8u flag) { + + EXE_Header header; + Bit16u fhandle;Bit32u i; + Bit16u size,minsize,maxsize,freesize;Bit16u readsize; + Bit16u envseg,pspseg,exeseg; + Bit32u imagesize,headersize; + + PSP * callpsp=(PSP *)real_off(dos.psp,0); + + if (!DOS_OpenFile(name,OPEN_READ,&fhandle)) return false; + if (flag!=OVERLAY) { + /* Allocate a new Environment */ + envseg=block->exec.envseg; + if (!MakeEnv(name,&envseg)) return false; + }; + + /* First Read the EXE Header */ + readsize=sizeof(EXE_Header); + DOS_ReadFile(fhandle,(Bit8u*)&header,&readsize); + /* Calculate the size of the image to load */ + headersize=header.headersize*16; + imagesize=header.pages*512-headersize; + if (flag!=OVERLAY) { + minsize=long2para(imagesize+(header.minmemory<<4)+256); + if (header.maxmemory!=0) maxsize=long2para(imagesize+(header.maxmemory<<4)+256); + else maxsize=0xffff; + freesize=0xffff; + /* Check for enough free memory */ + DOS_AllocateMemory(&exeseg,&freesize); + if (minsize>freesize) { + DOS_SetError(DOSERR_INSUFFICIENT_MEMORY); + DOS_FreeMemory(envseg); + return false; + } + if (maxsize>freesize) { + size=freesize; + } else size=maxsize; + if ((header.minmemory|header.maxmemory)==0) { + size=freesize; + E_Exit("Special case exe header max and min=0"); + } + if (!DOS_AllocateMemory(&pspseg,&size)) { + DOS_SetError(DOSERR_INSUFFICIENT_MEMORY); + DOS_FreeMemory(envseg); + return false; + } + SetupPSP(pspseg,size,envseg); + SetupCMDLine(pspseg,block); + exeseg=pspseg+16; + } else { + /* For OVERLAY */ + exeseg=block->overlay.loadseg; + } + /* Load the image in 32k blocks */ + DOS_SeekFile(fhandle,&headersize,0); + Bit8u * imageoff=real_off(exeseg,0); +//TODO File size checking and remove size + // Remove psp size +// imagesize=256; + // Maybe remove final page and add last bytes on page + if (header.extrabytes) { + imagesize-=512; + imagesize+=header.extrabytes; + }; + while (imagesize>0x7FFF) { + readsize=0x8000; + DOS_ReadFile(fhandle,imageoff,&readsize); + if (readsize!=0x8000) { + E_Exit("Illegal header"); + } + imageoff+=0x8000; + imagesize-=0x8000; + } + if (imagesize>0) { + readsize=(Bit16u) imagesize; + DOS_ReadFile(fhandle,imageoff,&readsize); + } + headersize=header.reloctable; + DOS_SeekFile(fhandle,&headersize,0); + RealPt reloc; + for (i=0;ioverlay.relocation; + } else { + change+=exeseg; + }; + mem_writew(address,change); + + }; + DOS_CloseFile(fhandle); + if (flag==OVERLAY) return true; + + /* Setup termination Address */ + RealSetVec(0x22,RealMake(Segs[cs].value,reg_ip)); + /* Start up the actual EXE if we need to */ + //TODO check for load and return + callpsp->stack=RealMake(Segs[ss].value,reg_sp); + dos.psp=pspseg; + SetSegment_16(cs,exeseg+header.initCS); + SetSegment_16(ss,exeseg+header.initSS); + SetSegment_16(ds,pspseg); + SetSegment_16(es,pspseg); + reg_ip=header.initIP; + reg_sp=header.initSP; + reg_ax=0; + reg_bx=reg_cx=reg_dx=reg_si=reg_di=reg_bp=0; + flags.intf=true; + return true; +}; + + +bool DOS_Execute(char * name,ParamBlock * block,Bit8u flags) { + + EXE_Header head; + Bit16u fhandle; + Bit16u size; + bool iscom=false; + if (!DOS_OpenFile(name,OPEN_READ,&fhandle)) return false; + + size=sizeof(EXE_Header); + if (!DOS_ReadFile(fhandle,(Bit8u *)&head,&size)) { + DOS_CloseFile(fhandle); + return false; + } + if (!DOS_CloseFile(fhandle)) return false; + if (size +#include +#include "dosbox.h" +#include "mem.h" +#include "cpu.h" +#include "dos_inc.h" +#include "drives.h" + +#define DOS_FILESTART 4 + + +DOS_File * Files[DOS_FILES]; +DOS_Drive * Drives[DOS_DRIVES]; +static Bit8u CurrentDrive=2; //Init on C: + + +Bit8u DOS_GetDefaultDrive(void) { + return CurrentDrive; +} + +void DOS_SetDefaultDrive(Bit8u drive) { + CurrentDrive=drive; +} + +bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { +//TODO Hope this is ok :) + char upname[DOS_PATHLENGTH]; + Bit32u r=0;Bit32u w=0;Bit32u namestart=0; + bool hasdrive=false; + *drive=CurrentDrive; + char tempdir[DOS_NAMELENGTH]; +//TODO Maybe check for illegal characters + while (name[r]!=0 && (r='a') && (c<='z')) {upname[w++]=c-32;continue;} + if ((c>='A') && (c<='Z')) {upname[w++]=c;continue;} + if ((c>='0') && (c<='9')) {upname[w++]=c;continue;} + switch (c) { + case ':': + if (hasdrive) { DOS_SetError(DOSERR_PATH_NOT_FOUND);return false; } + else hasdrive=true; + if ((upname[0]>='A') && (upname[0]<='Z')) { + *drive=upname[0]-'A'; + w=0; + } else { + DOS_SetError(DOSERR_PATH_NOT_FOUND);return false; + } + break; + case '/': + upname[w++]='\\'; + break; + case ' ': + break; + case '\\': case '$': case '#': case '@': case '(': case ')': + case '!': case '%': case '{': case '}': case '`': case '~': + case '_': case '-': case '.': case '*': case '?': case '&': + upname[w++]=c; + break; + default: + DOS_SetError(DOSERR_PATH_NOT_FOUND);return false; + break; + } + } + upname[w]=0; + /* This should get us an upcase filename and no incorrect chars */ + /* Now parse the new file name to make the final filename */ + if ((*drive>=26)) { + DOS_SetError(DOSERR_INVALID_DRIVE);return false; + }; + if (!Drives[*drive]) { + DOS_SetError(DOSERR_INVALID_DRIVE);return false; + }; + if (upname[0]!='\\') strcpy(fullname,Drives[*drive]->curdir); + else fullname[0]=0; + Bit32u lastdir=0;Bit32u t=0; + while (fullname[t]!=0) { + if ((fullname[t]=='\\') && (fullname[t+1]!=0))lastdir=t; + t++; + }; + r=0;w=0; + tempdir[0]=0; + bool stop=false; + while (!stop) { + if (upname[r]==0) stop=true; + if ((upname[r]=='\\') || (upname[r]==0)){ + tempdir[w]=0; + if (tempdir[0]==0) { w=0;r++;continue;} + if (strcmp(tempdir,".")==0) { + tempdir[0]=0; + w=0;r++; + continue; + } + if (strcmp(tempdir,"..")==0) { + fullname[lastdir]=0; + Bit32u t=0;lastdir=0; + while (fullname[t]!=0) { + if ((fullname[t]=='\\') && (fullname[t+1]!=0))lastdir=t; + t++; + } + tempdir[0]=0; + w=0;r++; + continue; + } + lastdir=strlen(fullname); + //TODO Maybe another check for correct type because of .... stuff + if (lastdir!=0) strcat(fullname,"\\"); + strcat(fullname,tempdir); + + tempdir[0]=0; + w=0;r++; + continue; + } + tempdir[w++]=upname[r++]; + } + return true; +} + +bool DOS_GetCurrentDir(Bit8u drive,Bit8u * buffer) { + if (drive==0) drive=DOS_GetDefaultDrive(); + else drive--; + if ((drive>DOS_DRIVES) || (!Drives[drive])) { + DOS_SetError(DOSERR_INVALID_DRIVE); + return false; + } + strcpy((char *) buffer,Drives[drive]->curdir); + return true; +} + +bool DOS_ChangeDir(char * dir) { + Bit8u drive;char fulldir[DOS_PATHLENGTH]; + if (!DOS_MakeName(dir,fulldir,&drive)) return false; + if (Drives[drive]->TestDir(fulldir)) { + strcpy(Drives[drive]->curdir,fulldir); + return true; + } else { + DOS_SetError(DOSERR_PATH_NOT_FOUND); + } + return false; +} + +bool DOS_MakeDir(char * dir) { + Bit8u drive;char fulldir[DOS_PATHLENGTH]; + if (!DOS_MakeName(dir,fulldir,&drive)) return false; + return Drives[drive]->MakeDir(fulldir); +} + +bool DOS_RemoveDir(char * dir) { + Bit8u drive;char fulldir[DOS_PATHLENGTH]; + if (!DOS_MakeName(dir,fulldir,&drive)) return false; + return Drives[drive]->RemoveDir(fulldir); +} + +bool DOS_Rename(char * oldname,char * newname) { + Bit8u driveold;char fullold[DOS_PATHLENGTH]; + Bit8u drivenew;char fullnew[DOS_PATHLENGTH]; + if (!DOS_MakeName(oldname,fullold,&driveold)) return false; + if (!DOS_MakeName(newname,fullnew,&drivenew)) return false; + //TODO Test for different drives maybe + if (Drives[drivenew]->Rename(fullold,fullnew)) return true; + DOS_SetError(DOSERR_FILE_NOT_FOUND); + return false; +}; + +bool DOS_FindFirst(char * search,Bit16u attr) { + Bit8u drive;char fullsearch[DOS_PATHLENGTH]; + if (!DOS_MakeName(search,fullsearch,&drive)) return false; + DTA_FindBlock * dtablock=(DTA_FindBlock *)Real2Host(dos.dta); + dtablock->sattr=attr | DOS_ATTR_ARCHIVE; + dtablock->sdrive=drive; + return Drives[drive]->FindFirst(fullsearch,dtablock); +}; + +bool DOS_FindNext(void) { + DTA_FindBlock * dtablock=(DTA_FindBlock *)Real2Host(dos.dta); + return Drives[dtablock->sdrive]->FindNext(dtablock); +}; + + +bool DOS_ReadFile(Bit16u entry,Bit8u * data,Bit16u * amount) { + Bit32u handle=RealHandle(entry); + if (handle>=DOS_FILES) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; + if (!Files[handle]) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; +//TODO maybe another code :) +/* + if (!(Files[handle]->flags & OPEN_READ)) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + } +*/ + Bit16u toread=*amount; + bool ret=Files[handle]->Read(data,&toread); + *amount=toread; + return ret; +}; + +bool DOS_WriteFile(Bit16u entry,Bit8u * data,Bit16u * amount) { + Bit32u handle=RealHandle(entry); + if (handle>=DOS_FILES) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; + if (!Files[handle]) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; +//TODO maybe another code :) +/* + if (!(Files[handle]->flags & OPEN_WRITE)) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + } +*/ + Bit16u towrite=*amount; + bool ret=Files[handle]->Write(data,&towrite); + *amount=towrite; + return ret; +}; + +bool DOS_SeekFile(Bit16u entry,Bit32u * pos,Bit32u type) { + Bit32u handle=RealHandle(entry); + if (handle>=DOS_FILES) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; + if (!Files[handle]) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; + return Files[handle]->Seek(pos,type); +}; + +bool DOS_CloseFile(Bit16u entry) { + Bit32u handle=RealHandle(entry); + if (handle>=DOS_FILES) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; + if (!Files[handle]) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; +//TODO Figure this out with devices :) + + PSP * psp=(PSP *)real_off(dos.psp,0); + Bit8u * table=Real2Host(psp->file_table); + table[entry]=0xFF; + /* Devices won't allow themselves to be closed or killed */ + if (Files[handle]->Close()) { + delete Files[handle]; + Files[handle]=0; + } + return true; +} + +bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { + char fullname[DOS_PATHLENGTH];Bit8u drive; + PSP * psp=(PSP *)real_off(dos.psp,0); + if (!DOS_MakeName(name,fullname,&drive)) return false; + /* Check for a free file handle */ + Bit8u handle=DOS_FILES;Bit8u i; + for (i=0;ifile_table); + *entry=0xff; + for (i=0;imax_files;i++) { + if (table[i]==0xFF) { + *entry=i; + break; + } + } + if (*entry==0xff) { + DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); + return false; + } + bool foundit=Drives[drive]->FileCreate(&Files[handle],fullname,attributes); + if (foundit) { + table[*entry]=handle; + return true; + } else { + return false; + } +} + +bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { + /* First check for devices */ + PSP * psp=(PSP *)real_off(dos.psp,0); + Bit8u handle=DOS_FindDevice((char *)name); + bool device=false;char fullname[DOS_PATHLENGTH];Bit8u drive;Bit8u i; + if (handle!=255) { + device=true; + } else { + /* First check if the name is correct */ + if (!DOS_MakeName(name,fullname,&drive)) return false; + /* Check for a free file handle */ + for (i=0;ifile_table); + *entry=0xff; + for (i=0;imax_files;i++) { + if (table[i]==0xFF) { + *entry=i; + break; + } + } + if (*entry==0xff) { + DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); + return false; + } + bool exists=false; + if (!device) exists=Drives[drive]->FileOpen(&Files[handle],fullname,flags); + if (exists || device ) { + table[*entry]=handle; + return true; + } else { + DOS_SetError(DOSERR_FILE_NOT_FOUND); + return false; + } +} + +bool DOS_UnlinkFile(char * name) { + char fullname[DOS_PATHLENGTH];Bit8u drive; + if (!DOS_MakeName(name,fullname,&drive)) return false; + return Drives[drive]->FileUnlink(fullname); +} + +bool DOS_GetFileAttr(char * name,Bit16u * attr) { + char fullname[DOS_PATHLENGTH];Bit8u drive; + if (!DOS_MakeName(name,fullname,&drive)) return false; + if (Drives[drive]->GetFileAttr(fullname,attr)) { + return true; + } else { + DOS_SetError(DOSERR_FILE_NOT_FOUND); + return false; + } +} + +bool DOS_Canonicalize(char * name,Bit8u * big) { +//TODO Add Better support for devices and shit but will it be needed i doubt it :) + Bit8u drive; + char fullname[DOS_PATHLENGTH]; + if (!DOS_MakeName(name,fullname,&drive)) return false; + big[0]=drive+'A'; + big[1]=':'; + big[2]='\\'; + strcpy((char *)&big[3],fullname); + return true; +}; + +bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free) { + if (drive==0) drive=DOS_GetDefaultDrive(); + else drive--; + if ((drive>DOS_DRIVES) || (!Drives[drive])) { + DOS_SetError(DOSERR_INVALID_DRIVE); + return false; + } + return Drives[drive]->FreeSpace(bytes,sectors,clusters,free); +} + +bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry) { + Bit8u handle=RealHandle(entry); + if (handle>=DOS_FILES) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; + if (!Files[handle]) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; + PSP * psp=(PSP *)real_off(dos.psp,0); + Bit8u * table=Real2Host(psp->file_table); + *newentry=0xff; + for (Bit16u i=0;imax_files;i++) { + if (table[i]==0xFF) { + *newentry=i; + break; + } + } + if (*newentry==0xff) { + DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); + return false; + } + table[*newentry]=handle; + return true; +}; + + +bool DOS_CreateTempFile(char * name,Bit16u * entry) { + +/* First add random crap to the end of the name and try to open */ + /* Todo maybe check for euhm existence of the path name */ + char * tempname; + tempname=name+strlen(name); + do { + Bit32u i; + for (i=0;i<8;i++) { + tempname[i]=(rand()%26)+'A'; + } + tempname[8]='.'; + for (i=9;i<12;i++) { + tempname[i]=(rand()%26)+'A'; + } + tempname[13]=0; + } while (!DOS_CreateFile(name,0,entry)); + return true; +} +#if 0 +void FCB_MakeName (DOS_FCB* fcb, char* outname, Bit8u* outdrive){ + char naam[15]; + Bit8u drive=fcb->Get_drive(); + if(drive!=0){ + naam[0]=(drive-1)+'A'; + naam[1]=':'; + naam[2]='\0';} + else{ + naam[0]='\0'; + }; + char temp[9]; + fcb->Get_filename(temp); + temp[9]='.'; + strncat(naam,temp,9); + char ext[3]; + fcb->Get_ext(ext); + if(drive!=0) { + strncat(&naam[11],ext,3); + naam[14]='\0'; + }else{ + strncat(&naam[9],ext,3); + naam[12]='\0'; + }; + DOS_MakeName(naam,outname, outdrive); + return; +} + + +bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { + DOS_FCB fcb(seg,offset); + Bit8u drive; + char fullname[DOS_PATHLENGTH]; + FCB_MakeName (&fcb, fullname, &drive); + if(DOS_FileExists(fullname)==false) return false; + + + struct stat stat_block; + stat(fullname, &stat_block); + fcb.Set_filesize((Bit32u)stat_block.st_size); + Bit16u constant =0; + fcb.Set_current_block(constant); + constant=0x80; + fcb.Set_record_size(constant); + struct tm *time; + time=localtime(&stat_block.st_mtime); + + constant=(time->tm_hour<<11)+(time->tm_min<<5)+(time->tm_sec/2); /* standard way. */ + fcb->Set_time(constant); + constant=((time->tm_year-80)<<9)+((time->tm_mon+1)<<5)+(time->tm_mday); + fcb->Set_date(constant); + fcb->Set_drive(drive +1); + return true; + } + +bool FCB_Close(void) +{ return true;} + +bool FCB_FindFirst(Bit16u seg,Bit16u offset) +{FCB* fcb = new FCB(seg,offset); + Bit8u drive; + Bitu i; + char fullname[DOS_PATHLENGTH]; + FCB_MakeName (fcb, fullname, &drive); + DTA_FindBlock * dtablock=(DTA_FindBlock *)Real2Host(dos.dta); + if(Drives[drive]->FindFirst(fullname,dtablock)==false) return false; + + char naam[8]; + char ext[3]; + char * point=strrchr(dtablock->name,'.'); + if(point==NULL|| *(point+1)=='\0') { + ext[0]=' '; + ext[1]=' '; + ext[2]=' '; + }else + {strcpy(ext,point+1); + Bitu i; + i=strlen(point+1); + while(i!=3) ext[i-1]=' '; + } + + if(point!=NULL) *point='\0'; + + strcpy (naam,dtablock->name); + i=strlen(dtablock->name); + while(i!=8) naam[i-1]=' '; + FCB* fcbout= new FCB((PhysPt)Real2Host(dos.dta)); + fcbout->Set_drive(drive +1); + fcbout->Set_filename(naam); + fcbout->Set_ext(ext); + return true; + } +bool FCB_FindNext(Bit16u seg,Bit16u offset) +{FCB* fcb = new FCB(seg,offset); + Bit8u drive; + Bitu i; + char fullname[DOS_PATHLENGTH]; + FCB_MakeName (fcb, fullname, &drive); + DTA_FindBlock * dtablock=(DTA_FindBlock *)Real2Host(dos.dta); + if(Drives[dtablock->sdrive]->FindNext(dtablock)==false) return false; + char naam[8]; + char ext[3]; + char * point=strrchr(dtablock->name,'.'); + if(point==NULL|| *(point+1)=='\0') { + ext[0]=' '; + ext[1]=' '; + ext[2]=' '; + }else + {strcpy(ext,point+1); + Bitu i; + i=strlen(point+1); + while(i!=3) ext[i-1]=' '; + } + + if(point!=NULL) *point='\0'; + + strcpy (naam,dtablock->name); + i=strlen(dtablock->name); + while(i!=8) naam[i-1]=' '; + FCB* fcbout= new FCB((PhysPt)Real2Host(dos.dta)); + fcbout->Set_drive(drive +1); + fcbout->Set_filename(naam); + fcbout->Set_ext(ext); + return true; + } + +#endif + +bool DOS_FileExists(char * name) { + Bit16u handle; + if (DOS_OpenFile(name,0,&handle)) { + DOS_CloseFile(handle); + return true; + } + return false; +} + + +bool DOS_SetDrive(Bit8u drive) { + if (Drives[drive]) { + DOS_SetDefaultDrive(drive); + return true; + + } else { + return false; + } +}; + + +void DOS_SetupFiles (void) { + /* Setup the File Handles */ + Bit32u i; + for (i=0;i +#include "dosbox.h" +#include "callback.h" +#include "mem.h" +#include "cpu.h" +#include "dos_inc.h" + +#define MAX_DEVICE 20 +static DOS_File * dos_devices[MAX_DEVICE]; + +bool DOS_IOCTL(Bit8u call,Bit16u entry) { + Bit32u handle=RealHandle(entry); + if (handle>=DOS_FILES) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; + if (!Files[handle]) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; + switch(reg_al) { + case 0x00: /* Get Device Information */ + reg_dx=Files[handle]->GetInformation(); + return true; + case 0x07: /* Get Output Status */ + LOG_DEBUG("DOS:IOCTL:07:Fakes output status is ready for handle %d",handle); + reg_al=0xff; + return true; + default: + LOG_ERROR("DOS:IOCTL Call %2X Handle %2X unhandled",reg_al,handle); + return false; + }; + return false; +}; + + +bool DOS_GetSTDINStatus(void) { + Bit32u handle=RealHandle(STDIN); + if (Files[handle]->GetInformation() & 64) return false; + return true; +}; + diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp new file mode 100644 index 00000000..5f1d90cc --- /dev/null +++ b/src/dos/dos_memory.cpp @@ -0,0 +1,162 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "mem.h" +#include "dos_inc.h" + + +#define MEM_START 0x60 //First Segment that DOS can use +//#define MEM_START 4000 //First Segment that DOS can use + + +static void DOS_CompressMemory(void) { + MCB * pmcb;MCB * pmcbnext; + Bit16u mcb_segment; + mcb_segment=dos.firstMCB; + pmcb=(MCB *)real_off(mcb_segment,0); + while (pmcb->type!=0x5a) { + pmcbnext=pmcbnext=(MCB *)real_off(mcb_segment+pmcb->size+1,0); + if ((pmcb->psp_segment==0) && (pmcbnext->psp_segment==0)) { + pmcb->size+=pmcbnext->size+1; + pmcb->type=pmcbnext->type; + } else { + mcb_segment+=pmcb->size+1; + pmcb=(MCB *)real_off(mcb_segment,0); + } + } +} + +void DOS_FreeProcessMemory(Bit16u pspseg) { + MCB * pmcb; + Bit16u mcb_segment=dos.firstMCB; + pmcb=(MCB *)real_off(mcb_segment,0); + while (true) { + if (pmcb->psp_segment==pspseg) { + pmcb->psp_segment=MCB_FREE; + } + mcb_segment+=pmcb->size+1; + if (pmcb->type==0x5a) break; + pmcb=(MCB *)real_off(mcb_segment,0); + } + DOS_CompressMemory(); +}; + + +bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { + MCB * pmcb;MCB * pmcbnext; + Bit16u bigsize=0;Bit16u mcb_segment; + bool stop=false;mcb_segment=dos.firstMCB; + DOS_CompressMemory(); + while(!stop) { + pmcb=(MCB *)real_off(mcb_segment,0); + if (pmcb->psp_segment==0) { + /* Check for enough free memory in current block */ + if (pmcb->size<(*blocks)) { + if (bigsizesize) { + bigsize=pmcb->size; + } + + } else if (pmcb->size==*blocks) { + pmcb->psp_segment=dos.psp; + *segment=mcb_segment+1; + return true; + } else { + /* If so allocate it */ + pmcbnext=(MCB *)real_off(mcb_segment+*blocks+1,0); + pmcbnext->psp_segment=MCB_FREE; + pmcbnext->type=pmcb->type; + pmcbnext->size=pmcb->size-*blocks-1; + pmcb->size=*blocks; + pmcb->type=0x4D; + pmcb->psp_segment=dos.psp; + //TODO Filename + *segment=mcb_segment+1; + return true; + } + } + /* Onward to the next MCB if there is one */ + if (pmcb->type==0x5a) { + *blocks=bigsize; + DOS_SetError(DOSERR_INSUFFICIENT_MEMORY); + return false; + } + mcb_segment+=pmcb->size+1; + } + return false; +}; + + +bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { + DOS_CompressMemory(); + MCB * pmcb,* pmcbnext,* pmcbnew; + pmcb=(MCB *)real_off(segment-1,0); + pmcbnext=(MCB *)real_off(segment+pmcb->size,0); + Bit16u total=pmcb->size; + if (pmcb->type!=0x5a) { + if (pmcbnext->psp_segment==MCB_FREE) { + total+=pmcbnext->size+1; + } + }; + if (*blockstype!=0x5a) { + pmcb->type=pmcbnext->type; + } + pmcb->size=*blocks; + pmcbnew=(MCB *)real_off(segment+*blocks,0); + pmcbnew->size=total-*blocks-1; + pmcbnew->type=pmcb->type; + pmcbnew->psp_segment=MCB_FREE; + pmcb->type=0x4D; + return true; + } + if (*blocks==total) { + if (pmcb->type!=0x5a) { + pmcb->type=pmcbnext->type; + } + pmcb->size=*blocks; + return true; + } + *blocks=total; + DOS_SetError(DOSERR_INSUFFICIENT_MEMORY); + return false; +}; + + +bool DOS_FreeMemory(Bit16u segment) { +//TODO Check if allowed to free this segment + MCB * pmcb; + pmcb=(MCB *)real_off(segment-1,0); + pmcb->psp_segment=MCB_FREE; + DOS_CompressMemory(); + return true; +} + + + + +void DOS_SetupMemory(void) { +//TODO Maybe allocate some memory for dos transfer buffers +//Although i could use bios regions for that for max free low memory + MCB * mcb=(MCB *) real_off(MEM_START,0); + mcb->psp_segment=MCB_FREE; //Free + mcb->size=0x9FFE - MEM_START; + mcb->type=0x5a; //Last Block + dos.firstMCB=MEM_START; +} + diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp new file mode 100644 index 00000000..cce5adad --- /dev/null +++ b/src/dos/dos_misc.cpp @@ -0,0 +1,69 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "callback.h" +#include "mem.h" +#include "regs.h" +#include "dos_inc.h" + + +static Bitu call_int2f,call_int2a; +struct MultiplexBlock { + MultiplexHandler * handler; + MultiplexBlock * next; +}; + +static MultiplexBlock * first_multiplex; + +void DOS_AddMultiplexHandler(MultiplexHandler * handler) { + MultiplexBlock * new_multiplex=new(MultiplexBlock); + new_multiplex->next=first_multiplex; + new_multiplex->handler=handler; + first_multiplex=new_multiplex; +} + +static Bitu INT2F_Handler(void) { + MultiplexBlock * loop_multiplex=first_multiplex; + while (loop_multiplex) { + if ((*loop_multiplex->handler)()) return CBRET_NONE; + loop_multiplex=loop_multiplex->next; + } + LOG_WARN("DOS:Multiplex Unhandled call %4X",reg_ax); + return CBRET_NONE; +}; + + +static Bitu INT2A_Handler(void) { + + return CBRET_NONE; +}; + + +void DOS_SetupMisc(void) { + /* Setup the dos multiplex interrupt */ + first_multiplex=0; + call_int2f=CALLBACK_Allocate(); + CALLBACK_Setup(call_int2f,&INT2F_Handler,CB_IRET); + RealSetVec(0x2f,CALLBACK_RealPointer(call_int2f)); + /* Setup the dos network interrupt */ + call_int2a=CALLBACK_Allocate(); + CALLBACK_Setup(call_int2a,&INT2A_Handler,CB_IRET); + RealSetVec(0x2A<<2,CALLBACK_RealPointer(call_int2a)); +}; + diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp new file mode 100644 index 00000000..f1e3c947 --- /dev/null +++ b/src/dos/dos_programs.cpp @@ -0,0 +1,210 @@ +/* + * 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. + */ + +#include +#include +#include +#include "programs.h" +#include "support.h" +#include "drives.h" +#include "cross.h" + + +class MOUNT : public Program { +public: + MOUNT(PROGRAM_Info * program_info); + void Run(void); +}; + + +MOUNT::MOUNT(PROGRAM_Info * info):Program(info) { + +} + + +void MOUNT::Run(void) { +/* Parse the command line */ + /* if the command line is empty show current mounts */ + + if (!*prog_info->cmd_line) { + WriteOut("Current mounted drives are\n"); + for (int d=0;dGetInfo()); + } + } + return; + } + + char drive; + drive=toupper(*prog_info->cmd_line); + char * dir=strchr(prog_info->cmd_line,' '); + if (dir) { + if (!*dir) dir=0; + else dir=trim(dir); + }; + + if (!isalpha(drive) || !dir) { + WriteOut("Usage MOUNT Drive-Letter Local-Directory\nSo a MOUNT c c:\\windows mounts windows directory as the c: drive in DOSBox\n"); + return; + }; + struct stat test; + if (stat(dir,&test)) { + WriteOut("Directory %s Doesn't exist",dir); + return; + } + /* Not a switch so a normal directory/file */ + if (!(test.st_mode & S_IFDIR)) { + WriteOut("%s isn't a directory",dir); + return; + } + if (Drives[drive-'A']) { + WriteOut("Drive %c already mounted with %s\n",drive,Drives[drive-'A']->GetInfo()); + return; + } + char fulldir[DOS_PATHLENGTH]; + strcpy(fulldir,dir); + static char theend[2]={CROSS_FILESPLIT,0}; + char * last=strrchr(fulldir,CROSS_FILESPLIT); + if (!last || *(++last)) strcat(fulldir,theend); + Drives[drive-'A']=new localDrive(fulldir); + WriteOut("Mounting drive %c as %s\n",drive,fulldir); +} + +static void MOUNT_ProgramStart(PROGRAM_Info * info) { + MOUNT * tempmount=new MOUNT(info); + tempmount->Run(); + delete tempmount; +} + + +class MEM : public Program { +public: + MEM(PROGRAM_Info * program_info); + void Run(void); +}; + + +MEM::MEM(PROGRAM_Info * info):Program(info) { + +} + + +void MEM::Run(void) { + +} + +static void MEM_ProgramStart(PROGRAM_Info * info) { + MEM mem(info); + mem.Run(); + +} + + +#if !defined (WIN32) /* Unix */ +class UPCASE : public Program { +public: + UPCASE(PROGRAM_Info * program_info); + void Run(void); + void upcasedir(char * directory); +}; + + +UPCASE::UPCASE(PROGRAM_Info * info):Program(info) { + +} + + +void UPCASE::upcasedir(char * directory) { + DIR * sdir; + char fullname[512]; + char newname[512]; + struct dirent *tempdata; + struct stat finfo; + + if(!(sdir=opendir(directory))) { + WriteOut("Failed to open directory %s\n",directory); + return; + } + WriteOut("Scanning directory %s\n",fullname); + while (tempdata=readdir(sdir)) { + if (strcmp(tempdata->d_name,".")==0) continue; + if (strcmp(tempdata->d_name,"..")==0) continue; + strcpy(fullname,directory); + strcat(fullname,"/"); + strcat(fullname,tempdata->d_name); + strcpy(newname,directory); + strcat(newname,"/"); + upcase(tempdata->d_name); + strcat(newname,tempdata->d_name); + WriteOut("Renaming %s to %s\n",fullname,newname); + rename(fullname,newname); + stat(fullname,&finfo); + if(S_ISDIR(finfo.st_mode)) { + upcasedir(fullname); + } + } + closedir(sdir); +} + + +void UPCASE::Run(void) { + /* First check if the directory exists */ + struct stat info; + WriteOut("UPCASE 0.1 Directory case convertor.\n"); + if (!strlen(prog_info->cmd_line)) { + WriteOut("Usage UPCASE [local directory]\n"); + WriteOut("This tool will convert all files and subdirectories in a directory.\n"); + WriteOut("Be VERY sure this directory contains only dos related material.\n"); + WriteOut("Otherwise you might horribly screw up your filesystem.\n"); + return; + } + if (stat(prog_info->cmd_line,&info)) { + WriteOut("%s doesn't exist\n",prog_info->cmd_line); + return; + } + if(!S_ISDIR(info.st_mode)) { + WriteOut("%s isn't a directory\n",prog_info->cmd_line); + return; + } + WriteOut("Converting the wrong directories can be very harmfull, please be carefull.\n"); + WriteOut("Are you really really sure you want to convert %s to upcase?Y/N\n",prog_info->cmd_line); + Bit8u key;Bit16u n=1; + DOS_ReadFile(STDIN,&key,&n); + if (toupper(key)=='Y') { + upcasedir(prog_info->cmd_line); + } else { + WriteOut("Okay better not do it.\n"); + } +} + +static void UPCASE_ProgramStart(PROGRAM_Info * info) { + UPCASE * tempUPCASE=new UPCASE(info); + tempUPCASE->Run(); + delete tempUPCASE; +} + +#endif + +void DOS_SetupPrograms(void) { + PROGRAMS_MakeFile("MOUNT.COM",MOUNT_ProgramStart); +// PROGRAMS_MakeFile("MEM.COM",MEM_ProgramStart); /*next release */ +#if !defined (WIN32) /* Unix */ + PROGRAMS_MakeFile("UPCASE.COM",UPCASE_ProgramStart); +#endif +} diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp new file mode 100644 index 00000000..a2b2fced --- /dev/null +++ b/src/dos/dos_tables.cpp @@ -0,0 +1,54 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "mem.h" +#include "dos_inc.h" + +#pragma pack(1) + +struct DOS_TableCase { + Bit16u size; + Bit8u chars[256]; +}; +#pragma pack() + + +RealPt DOS_TableUpCase; +RealPt DOS_TableLowCase; + +static Bit16u dos_memseg=0xd000; +Bit16u DOS_GetMemory(Bit16u pages) { + if (pages+dos_memseg>=0xe000) { + E_Exit("DOS:Not enough memory for internal tables"); + } + Bit16u page=dos_memseg; + dos_memseg+=pages; + return page; +} + + +void DOS_SetupTables(void) { + dos.tables.indosflag=RealMake(DOS_GetMemory(1),0); + mem_writeb(Real2Phys(dos.tables.indosflag),0); +}; + + + + + diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp new file mode 100644 index 00000000..9b7cf0a1 --- /dev/null +++ b/src/dos/drive_local.cpp @@ -0,0 +1,277 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include "dosbox.h" +#include "dos_system.h" +#include "drives.h" +#include "support.h" +#include "cross.h" + + +class localFile : public DOS_File { +public: + localFile(FILE * handle,Bit16u devinfo); + bool Read(Bit8u * data,Bit16u * size); + bool Write(Bit8u * data,Bit16u * size); + bool Seek(Bit32u * pos,Bit32u type); + bool Close(); + Bit16u GetInformation(void); +private: + FILE * fhandle; + Bit16u info; +}; + + +bool localDrive:: FileCreate(DOS_File * * file,char * name,Bit16u attributes) { +//TODO Maybe care for attributes but not likely + char newname[512]; + strcpy(newname,basedir); + strcat(newname,name); + CROSS_FILENAME(newname); + FILE * hand=fopen(newname,"wb+"); + if (!hand) return false; + /* Make the 16 bit device information */ + *file=new localFile(hand,0x202); + return true; +}; + +bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { + char * type; + switch (flags) { + case OPEN_READ:type="rb";break; + case OPEN_WRITE:type="rb+";break; + case OPEN_READWRITE:type="rb+";break; + default: +//TODO FIX IT + type="rb+"; +// return false; + + }; + char newname[512]; + strcpy(newname,basedir); + strcat(newname,name); + CROSS_FILENAME(newname); + FILE * hand=fopen(newname,type); + Bit32u err=errno; + if (!hand) return false; + *file=new localFile(hand,0x202); + return true; +}; + +bool localDrive::FileUnlink(char * name) { + char newname[512]; + strcpy(newname,basedir); + strcat(newname,name); + CROSS_FILENAME(newname); + if (!unlink(newname)) return true; + return false; +}; + + +bool localDrive::FindFirst(char * search,DTA_FindBlock * dta) { + //TODO Find some way for lowcase and highcase drives oneday + char name[512]; + strcpy(name,basedir); + strcat(name,search); + CROSS_FILENAME(name); + char * last=strrchr(name, CROSS_FILESPLIT); + *last=0; + last++; + /* Check the wildcard string for an extension */ + strcpy(wild_name,last); + wild_ext=strrchr(wild_name,'.'); + if (wild_ext) { + *wild_ext++=0; + } + strcpy(directory,name); +/* make sure / is last sign */ + if (pdir) closedir(pdir); + if(directory[(strlen(directory)-1)]!=CROSS_FILESPLIT) strcat(directory, "/"); + if((pdir=opendir(directory))==NULL) return false; + return FindNext(dta); +} + +bool localDrive::FindNext(DTA_FindBlock * dta) { + Bit8u tempattr=0; + struct dirent *tempdata; + struct stat stat_block; + char werkbuffer[512]; + + if(pdir==NULL){ + return false; + }; + start: + if((tempdata=readdir(pdir))==NULL) { + closedir(pdir); + pdir=NULL; + return false; + } + strcpy(werkbuffer,tempdata->d_name); + if (wild_ext) { + char * ext=strrchr(werkbuffer,'.'); + if (!ext) ext="*"; + else *ext++=0; + if(!wildcmp(wild_ext,ext)) goto start; + } + if(!wildcmp(wild_name,werkbuffer)) goto start; + werkbuffer[0]='\0'; + strcpy(werkbuffer,directory); + strcat(werkbuffer,tempdata->d_name); + if(stat(werkbuffer,&stat_block)!=0){ + /*nu is er iets fout!*/ exit(1); + } + if(S_ISDIR(stat_block.st_mode)) tempattr=DOS_ATTR_DIRECTORY; + else tempattr=DOS_ATTR_ARCHIVE; + if(!(dta->sattr & tempattr)) goto start; + /*file is oke so filldtablok */ + if(strlen(tempdata->d_name)<=DOS_NAMELENGTH) strcpy(dta->name,upcase(tempdata->d_name)); + dta->attr=tempattr; + dta->size=(Bit32u) stat_block.st_size; + struct tm *time; + time=localtime(&stat_block.st_mtime); + + dta->time=(time->tm_hour<<11)+(time->tm_min<<5)+(time->tm_sec/2); /* standard way. */ + dta->date=((time->tm_year-80)<<9)+((time->tm_mon+1)<<5)+(time->tm_mday); + return true; +} + +bool localDrive::GetFileAttr(char * name,Bit16u * attr) { + char newname[512]; + strcpy(newname,basedir); + strcat(newname,name); + CROSS_FILENAME(newname); + FILE * hand=fopen(newname,"rb"); + if (hand) { + fclose(hand); + *attr=DOS_ATTR_ARCHIVE; + return true; + } + *attr=0; + return false; +}; + +bool localDrive::MakeDir(char * dir) { + char newdir[512]; + strcpy(newdir,basedir); + strcat(newdir,dir); + CROSS_FILENAME(newdir); +#if defined (WIN32) /* MS Visual C++ */ + int temp=mkdir(newdir); +#else + int temp=mkdir(newdir,0); +#endif + return (temp==0); +} + +bool localDrive::RemoveDir(char * dir) { + char newdir[512]; + strcpy(newdir,basedir); + strcat(newdir,dir); + int temp=rmdir(newdir); + return (temp==0); +} + +bool localDrive::TestDir(char * dir) { + char newdir[512]; + strcpy(newdir,basedir); + strcat(newdir,dir); + int temp=access(newdir,F_OK); + return (temp==0); +} + +bool localDrive::Rename(char * oldname,char * newname) { + char newold[512]; + strcpy(newold,basedir); + strcat(newold,oldname); + CROSS_FILENAME(newold); + char newnew[512]; + strcpy(newnew,basedir); + strcat(newnew,newnew); + CROSS_FILENAME(newname); + int temp=rename(newold,newnew); + return (temp==0); + +}; + +bool localDrive::FreeSpace(Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free) { + /* Always report 100 mb free should be enough */ + /* Total size is always 1 gb */ + *bytes=512; + *sectors=127; + *clusters=16513; + *free=1700; + return true; +}; + + +localDrive::localDrive(char * startdir) { + strcpy(basedir,startdir); + sprintf(info,"local directory %s",startdir); + pdir=NULL; +} + + +bool localFile::Read(Bit8u * data,Bit16u * size) { + *size=fread(data,1,*size,fhandle); + return true; +}; + +bool localFile::Write(Bit8u * data,Bit16u * size) { + *size=fwrite(data,1,*size,fhandle); + return true; +} + +bool localFile::Seek(Bit32u * pos,Bit32u type) { + int seektype; + switch (type) { + case DOS_SEEK_SET:seektype=SEEK_SET;break; + case DOS_SEEK_CUR:seektype=SEEK_CUR;break; + case DOS_SEEK_END:seektype=SEEK_END;break; + default: + //TODO Give some doserrorcode; + return false;//ERROR + } + fpos_t temppos; + int ret=fseek(fhandle,*pos,seektype); + fgetpos(fhandle,&temppos); +//TODO Hope we don't encouter files with 64 bits size + Bit32u * fake_pos=(Bit32u*)&temppos; + *pos=*fake_pos; + + return true; +} + +bool localFile::Close() { + fclose(fhandle); + return true; +} + +Bit16u localFile::GetInformation(void) { + return info; +} + +localFile::localFile(FILE * handle,Bit16u devinfo) { + fhandle=handle; + info=devinfo; +} + diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp new file mode 100644 index 00000000..b8140e1d --- /dev/null +++ b/src/dos/drive_virtual.cpp @@ -0,0 +1,205 @@ +/* + * 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. + */ + +#include +#include +#include +#include "dosbox.h" +#include "dos_system.h" +#include "drives.h" +#include "support.h" + +struct VFILE_Block { + char * name; + Bit8u * data; + Bit32u size; + VFILE_Block * next; +}; + + +static VFILE_Block * first_file; + +void VFILE_Register(char * name,Bit8u * data,Bit32u size) { + VFILE_Block * new_file=new VFILE_Block; + new_file->name=name; + new_file->data=data; + new_file->size=size; + new_file->next=first_file; + first_file=new_file; +} + + +class Virtual_File : public DOS_File { +public: + Virtual_File(Bit8u * in_data,Bit32u in_size); + bool Read(Bit8u * data,Bit16u * size); + bool Write(Bit8u * data,Bit16u * size); + bool Seek(Bit32u * pos,Bit32u type); + bool Close(); + Bit16u GetInformation(void); +private: + Bit32u file_size; + Bit32u file_pos; + Bit8u * file_data; +}; + + +Virtual_File::Virtual_File(Bit8u * in_data,Bit32u in_size) { + file_size=in_size; + file_data=in_data; + file_pos=0; +} + +bool Virtual_File::Read(Bit8u * data,Bit16u * size) { + Bit32u left=file_size-file_pos; + if (left<=*size) { + memcpy(data,&file_data[file_pos],left); + *size=(Bit16u)left; + } else { + memcpy(data,&file_data[file_pos],*size); + } + file_pos+=*size; + return true; +}; + +bool Virtual_File::Write(Bit8u * data,Bit16u * size){ +/* Not really writeable */ + return false; +}; + +bool Virtual_File::Seek(Bit32u * new_pos,Bit32u type){ + switch (type) { + case DOS_SEEK_SET: + if (*new_pos<=file_size) file_pos=*new_pos; + else return false; + break; + case DOS_SEEK_CUR: + if ((*new_pos+file_pos)<=file_size) file_pos=*new_pos+file_pos; + else return false; + break; + case DOS_SEEK_END: + if (*new_pos<=file_size) file_pos=file_size-*new_pos; + else return false; + break; + } + *new_pos=file_pos; + return true; +}; + +bool Virtual_File::Close(){ + return true; +}; + + +Bit16u Virtual_File::GetInformation(void) { + return 0; +} + + +Virtual_Drive::Virtual_Drive() { + strcpy(info,"Internal Virtual Drive"); + search_file=0; +} + + +bool Virtual_Drive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { +/* Scan through the internal list of files */ + VFILE_Block * cur_file=first_file; + while (cur_file) { + if (strcasecmp(name,cur_file->name)==0) { + /* We have a match */ + *file=new Virtual_File(cur_file->data,cur_file->size); + return true; + } + cur_file=cur_file->next; + } + return false; +} + +bool Virtual_Drive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) { + return false; +} + +bool Virtual_Drive::FileUnlink(char * name) { + return false; +} + +bool Virtual_Drive::RemoveDir(char * dir) { + return false; +} + +bool Virtual_Drive::MakeDir(char * dir) { + return false; +} + +bool Virtual_Drive::TestDir(char * dir) { + return false; +} + +static void FillDTABlock(DTA_FindBlock * dta,VFILE_Block * fill_file) { + strcpy(dta->name,fill_file->name); + dta->size=fill_file->size; + dta->attr=DOS_ATTR_ARCHIVE; + dta->time=2; + dta->date=6; +} + +bool Virtual_Drive::FindFirst(char * search,DTA_FindBlock * dta) { + search_file=first_file; + strcpy(search_string,search); + while (search_file) { + if (wildcmp(search_string,search_file->name)) { + FillDTABlock(dta,search_file); + search_file=search_file->next; + return true; + } + search_file=search_file->next; + } + return false; +} + +bool Virtual_Drive::FindNext(DTA_FindBlock * dta) { + while (search_file) { + if (wildcmp(search_string,search_file->name)) { + FillDTABlock(dta,search_file); + search_file=search_file->next; + return true; + } + search_file=search_file->next; + } + return false; +} + +bool Virtual_Drive::GetFileAttr(char * name,Bit16u * attr) { + return false; +} + +bool Virtual_Drive::Rename(char * oldname,char * newname) { + return false; +} + +bool Virtual_Drive::FreeSpace(Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free) { + /* Always report 100 mb free should be enough */ + /* Total size is always 1 gb */ + *bytes=512; + *sectors=127; + *clusters=16513; + *free=00; + return true; +} + diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp new file mode 100644 index 00000000..2a711725 --- /dev/null +++ b/src/dos/drives.cpp @@ -0,0 +1,31 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "dos_system.h" +#include "drives.h" + + +DOS_Drive::DOS_Drive() { + curdir[0]=0; + info[0]=0; +} + +char * DOS_Drive::GetInfo(void) { + return info; +} diff --git a/src/dos/drives.h b/src/dos/drives.h new file mode 100644 index 00000000..a2dcf75e --- /dev/null +++ b/src/dos/drives.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _DRIVES_H__ +#define _DRIVES_H__ + +#include +#include + + +class localDrive : public DOS_Drive { +public: + localDrive(char * startdir); + bool FileOpen(DOS_File * * file,char * name,Bit32u flags); + bool FileCreate(DOS_File * * file,char * name,Bit16u attributes); + bool FileUnlink(char * name); + bool RemoveDir(char * dir); + bool MakeDir(char * dir); + bool TestDir(char * dir); + bool FindFirst(char * search,DTA_FindBlock * dta); + bool FindNext(DTA_FindBlock * dta); + bool GetFileAttr(char * name,Bit16u * attr); + bool Rename(char * oldname,char * newname); + bool FreeSpace(Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free); +private: + bool FillDTABlock(DTA_FindBlock * dta); + char basedir[512]; + char directory[512]; + char wild_name[15]; + char * wild_ext; + DIR *pdir; +}; + +struct VFILE_Block; + + +class Virtual_Drive: public DOS_Drive { +public: + Virtual_Drive(); + bool FileOpen(DOS_File * * file,char * name,Bit32u flags); + bool FileCreate(DOS_File * * file,char * name,Bit16u attributes); + bool FileUnlink(char * name); + bool RemoveDir(char * dir); + bool MakeDir(char * dir); + bool TestDir(char * dir); + bool FindFirst(char * search,DTA_FindBlock * dta); + bool FindNext(DTA_FindBlock * dta); + bool GetFileAttr(char * name,Bit16u * attr); + bool Rename(char * oldname,char * newname); + bool FreeSpace(Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free); +private: + VFILE_Block * search_file; + char search_string[255]; +}; + +#endif diff --git a/src/dosbox.cpp b/src/dosbox.cpp new file mode 100644 index 00000000..ce7dba6f --- /dev/null +++ b/src/dosbox.cpp @@ -0,0 +1,297 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include "dosbox.h" +#include "debug.h" +#include "cpu.h" +#include "video.h" +#include "pic.h" +#include "cpu.h" +#include "callback.h" +#include "inout.h" +#include "mixer.h" +#include "timer.h" +#include "dos_inc.h" +#include "setup.h" +#include "cross.h" +#include "programs.h" + +char dosbox_basedir[CROSS_LEN]; + + +#if 0 + +int main(int argc, char* argv[]) { + + + + /* Strip out the dosbox startup directory */ + + + + /* Handle the command line for new stuff to add to autoexec.bat */ + int argl=1; + if (argc>1) { + if (*argv[1]!='-') { + struct stat test; + if (stat(argv[1],&test)) { + E_Exit("%s Doesn't exist",argv[1]); + } + /* Not a switch so a normal directory/file */ + if (test.st_mode & S_IFDIR) { + SHELL_AddAutoexec("MOUNT C %s",argv[1]); + SHELL_AddAutoexec("C:"); + } else { + char * name=strrchr(argv[1],CROSS_FILESPLIT); + if (!name) E_Exit("This is weird %s",argv[1]); + *name++=0; + if (access(argv[1],F_OK)) E_Exit("Illegal Directory %s",argv[1]); + SHELL_AddAutoexec("MOUNT C %s",argv[1]); + SHELL_AddAutoexec("C:"); + SHELL_AddAutoexec(name); + } + argl++; + } + } + bool sw_c=false; + while (arglLastTicks) { + Bit32u ticks=new_ticks-LastTicks; + if (ticks>20) ticks=20; + LastTicks=new_ticks; + TIMER_AddTicks(ticks); + } + TIMER_CheckPIT(); + GFX_Events(); + PIC_runIRQs(); + return (*cpudecoder)(cpu_cycles); +}; + + +static Bitu Speed_Loop(void) { + Bit32u new_ticks; + new_ticks=GetTicks(); + Bitu ret=0; + Bitu cycles=1; + if (new_ticks>LastTicks) { + Bit32u ticks=new_ticks-LastTicks; + if (ticks>20) ticks=20; +// if (ticks>3) LOG_DEBUG("Ticks %d",ticks); + LastTicks=new_ticks; + TIMER_AddTicks(ticks); + cycles+=cpu_cycles*ticks; + } + TIMER_CheckPIT(); + GFX_Events(); + PIC_runIRQs(); + return (*cpudecoder)(cycles); +} + +void DOSBOX_SetLoop(LoopHandler * handler) { + loop=handler; +} + + +void DOSBOX_RunMachine(void){ + Bitu ret; + do { + ret=(*loop)(); + } while (!ret); +} + + + +static void InitSystems(void) { + MSG_Init(); + MEM_Init(); + IO_Init(); + CALLBACK_Init(); + PROGRAMS_Init(); + HARDWARE_Init(); + TIMER_Init(); + CPU_Init(); + FPU_Init(); + MIXER_Init(); +#ifdef C_DEBUG + DEBUG_Init(); +#endif + //Start up individual hardware + DMA_Init(); + PIC_Init(); + VGA_Init(); + KEYBOARD_Init(); + MOUSE_Init(); + JOYSTICK_Init(); + SBLASTER_Init(); + TANDY_Init(); + PCSPEAKER_Init(); + ADLIB_Init(); + CMS_Init(); + + PLUGIN_Init(); +/* Most of teh interrupt handlers */ + BIOS_Init(); + DOS_Init(); + EMS_Init(); //Needs dos first + XMS_Init(); //Needs dos first + +/* Setup the normal system loop */ + LastTicks=GetTicks(); + DOSBOX_SetLoop(&Normal_Loop); +// DOSBOX_SetLoop(&Speed_Loop); +} + + +void DOSBOX_Init(int argc, char* argv[]) { +/* Find the base directory */ + strcpy(dosbox_basedir,argv[0]); + char * last=strrchr(dosbox_basedir,CROSS_FILESPLIT); //if windowsversion fails: + if (!last) E_Exit("Can't find basedir %s", argv[0]); + *++last=0; + /* Parse the command line with a setup function */ + int argl=1; + if (argc>1) { + if (*argv[1]!='-') { + struct stat test; + if (stat(argv[1],&test)) { + E_Exit("%s Doesn't exist",argv[1]); + } + /* Not a switch so a normal directory/file */ + if (test.st_mode & S_IFDIR) { + SHELL_AddAutoexec("MOUNT C %s",argv[1]); + SHELL_AddAutoexec("C:"); + } else { + char * name=strrchr(argv[1],CROSS_FILESPLIT); + if (!name) E_Exit("This is weird %s",argv[1]); + *name++=0; + if (access(argv[1],F_OK)) E_Exit("Illegal Directory %s",argv[1]); + SHELL_AddAutoexec("MOUNT C %s",argv[1]); + SHELL_AddAutoexec("C:"); + SHELL_AddAutoexec(name); + } + argl++; + } + } + bool sw_c=false; + while (argl +#include +#include "mem.h" +#include "dosbox.h" + +typedef PhysPt EAPoint; + +#define LoadMb(off) mem_readb(off) +#define LoadMw(off) mem_readw(off) +#define LoadMd(off) mem_readd(off) + +#define LoadMbs(off) (Bit8s)(LoadMb(off)) +#define LoadMws(off) (Bit16s)(LoadMw(off)) +#define LoadMds(off) (Bit32s)(LoadMd(off)) + +#define SaveMb(off,val) mem_writeb(off,val) +#define SaveMw(off,val) mem_writew(off,val) +#define SaveMd(off,val) mem_writed(off,val) + +typedef long double FPUREG; + + +#include "fpu_load.h" + + + + + +void FPU_ESC0_EA(Bitu rm,PhysPt addr) { + + +} + +void FPU_ESC0_Normal(Bitu rm) { + + +} + + + + +void FPU_Init(void) { + +} \ No newline at end of file diff --git a/src/fpu/fpu_load.h b/src/fpu/fpu_load.h new file mode 100644 index 00000000..b7f6ee0f --- /dev/null +++ b/src/fpu/fpu_load.h @@ -0,0 +1,21 @@ +/* + * 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. + */ + +INLINE FPUREG Load_Short(EAPoint addr) { + return (Bit16s)mem_readw(addr); +} \ No newline at end of file diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am new file mode 100644 index 00000000..00fc5765 --- /dev/null +++ b/src/gui/Makefile.am @@ -0,0 +1,5 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include + +noinst_LIBRARIES = libgui.a +libgui_a_SOURCES = sdlmain.cpp render.cpp + diff --git a/src/gui/render.cpp b/src/gui/render.cpp new file mode 100644 index 00000000..b6867b03 --- /dev/null +++ b/src/gui/render.cpp @@ -0,0 +1,160 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "video.h" +#include "render.h" + + + +#define MAX_RES 2048 + +struct PalData { + struct { + Bit8u red; + Bit8u green; + Bit8u blue; + Bit8u unused; + } rgb[256]; + Bitu first; + Bitu last; +}; + + +static struct { + struct { + Bitu width; + Bitu height; + Bitu bpp; + Bitu pitch; + float ratio; + } src; + Bitu flags; + RENDER_Handler * handler; + Bitu stretch_x[MAX_RES]; + Bitu stretch_y[MAX_RES]; + PalData pal; + bool remake; + bool enlarge; +} render; + +/* This could go kinda bad with multiple threads */ +static void Check_Palette(void) { + if (render.pal.first>render.pal.last) return; + + GFX_SetPalette(render.pal.first,render.pal.last-render.pal.first+1,(GFX_PalEntry *)&render.pal.rgb[render.pal.first]); + render.pal.first=256; + render.pal.last=0; +} + +static void MakeTables(void) { + //The stretching tables + Bitu i;Bit32u c,a; + c=0;a=(render.src.width<<16)/gfx_info.width; + for (i=0;i> 16; + c=(c&0xffff)+a; + } + c=0;a=(render.src.height<<16)/gfx_info.height; + for (i=0;i> 16)*render.src.pitch; + c=(c&0xffff)+a; + } +} + +static void Draw_8_Normal(Bit8u * src_data,Bit8u * dst_data) { + for (Bitu y=0;yentry) render.pal.first=entry; + if (render.pal.last +#include +#include +#include +#include "dosbox.h" +#include "video.h" +#include "keyboard.h" +#include "mouse.h" +#include "joystick.h" +#include "pic.h" +#include "timer.h" + + +//#define DISABLE_JOYSTICK + + +struct SDL_Block { + bool active; //If this isn't set don't draw + Bitu width; + Bitu height; + Bitu bpp; + GFX_DrawHandler * draw; + GFX_ResizeHandler * resize; + bool mouse_grabbed; + bool full_screen; + SDL_Thread * thread; + SDL_mutex * mutex; + SDL_Surface * surface; + SDL_Joystick * joy; + SDL_Color pal[256]; +}; + +static SDL_Block sdl; + +GFX_Info gfx_info; + +static void RestorePalette(void) { + if (sdl.bpp!=8) return; +/* Use some other way of doing this */ + if (sdl.full_screen) { + if (!SDL_SetPalette(sdl.surface,SDL_PHYSPAL,sdl.pal,0,256)) { + E_Exit("SDL:Can't set palette"); + } + } else { + if (!SDL_SetPalette(sdl.surface,SDL_LOGPAL,sdl.pal,0,256)) { + E_Exit("SDL:Can't set palette"); + } + } + return; +} +/* Reset the screen with current values in the sdl structure */ +static void ResetScreen(void) { + if (sdl.full_screen) { + /* First get the original resolution */ + sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN|SDL_DOUBLEBUF); + } else { + sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_SWSURFACE|SDL_RESIZABLE); + } + if (sdl.surface==0) { + E_Exit("SDL:Would be nice if I could get a surface."); + } + SDL_WM_SetCaption(VERSION,VERSION); +/* also fill up gfx_info structure */ + gfx_info.width=sdl.width; + gfx_info.height=sdl.height; + gfx_info.bpp=sdl.bpp; + gfx_info.pitch=sdl.surface->pitch; + RestorePalette(); +} + + +void GFX_Resize(Bitu width,Bitu height,Bitu bpp,GFX_ResizeHandler * resize) { + GFX_Stop(); + sdl.width=width; + sdl.height=height; + sdl.bpp=bpp; + sdl.resize=resize; + ResetScreen(); + GFX_Start(); +} + +static void CaptureMouse() { + sdl.mouse_grabbed=!sdl.mouse_grabbed; + if (sdl.mouse_grabbed) { + SDL_WM_GrabInput(SDL_GRAB_ON); + SDL_ShowCursor(SDL_DISABLE); + } else { + SDL_WM_GrabInput(SDL_GRAB_OFF); + SDL_ShowCursor(SDL_ENABLE); + } +} + +static void SwitchFullScreen(void) { + GFX_Stop(); + sdl.full_screen=!sdl.full_screen; + if (sdl.full_screen) { + if (sdl.resize) { + sdl.width=0;sdl.height=0; + (*sdl.resize)(&sdl.width,&sdl.height); + } + } + ResetScreen(); + GFX_Start(); +} + +static void GFX_Redraw() { +#ifdef C_THREADED + if (SDL_mutexP(sdl.mutex)) { + E_Exit("Can't Lock Mutex"); + }; +#endif + if (sdl.active) { + SDL_LockSurface(sdl.surface ); + if (sdl.surface->pixels && sdl.draw) (*sdl.draw)((Bit8u *)sdl.surface->pixels); + SDL_UnlockSurface(sdl.surface ); + if (sdl.full_screen) SDL_Flip(sdl.surface); + else SDL_UpdateRect(sdl.surface,0,0,0,0); + }; +#ifdef C_THREADED + if (SDL_mutexV(sdl.mutex)) { + E_Exit("Can't Release Mutex"); + } +#endif +} + +static int SDLGFX_Thread(void * data) { + do { + GFX_Redraw(); + SDL_Delay(1000/70); + } while (true); + return 1; +} + +void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries) { +/* I should probably not change the GFX_PalEntry :) */ +#ifdef C_THREADED + if (SDL_mutexP(sdl.mutex)) { + E_Exit("SDL:Can't Lock Mutex"); + }; +#endif + if (sdl.full_screen) { + if (!SDL_SetPalette(sdl.surface,SDL_PHYSPAL,(SDL_Color *)entries,start,count)) { + E_Exit("SDL:Can't set palette"); + } + } else { + if (!SDL_SetPalette(sdl.surface,SDL_LOGPAL,(SDL_Color *)entries,start,count)) { + E_Exit("SDL:Can't set palette"); + } + } + /* Copy palette entries into some internal back up table */ +#ifdef C_THREADED + if (SDL_mutexV(sdl.mutex)) { + E_Exit("SDL:Can't Release Mutex"); + } +#endif + memcpy(&sdl.pal[start],entries,count*sizeof(SDL_Color)); +} + +void GFX_SetDrawHandler(GFX_DrawHandler * handler) { + sdl.draw=handler; +} + +void GFX_Stop() { +#ifdef C_THREADED + SDL_mutexP(sdl.mutex); +#endif + sdl.active=false; +#ifdef C_THREADED + SDL_mutexV(sdl.mutex); +#endif +} + + +void GFX_Start() { + sdl.active=true; +} + + +void GFX_StartUp() { + sdl.active=false; + sdl.full_screen=false; + sdl.draw=0; +#ifdef C_THREADED + sdl.mutex=SDL_CreateMutex(); + sdl.thread = SDL_CreateThread(&SDLGFX_Thread,0); +#else + TIMER_RegisterMicroHandler(GFX_Redraw,1000000/70); +#endif + GFX_Resize(640,400,8,0); + SDL_EnableKeyRepeat(250,30); + +/* Get some Keybinds */ + KEYBOARD_AddEvent(KBD_f9,CTRL_PRESSED,SwitchFullScreen); + KEYBOARD_AddEvent(KBD_f10,CTRL_PRESSED,CaptureMouse); + KEYBOARD_AddEvent(KBD_enter,ALT_PRESSED,SwitchFullScreen); +} + +void GFX_ShutDown() { + if (sdl.full_screen) SwitchFullScreen(); + if (sdl.mouse_grabbed) CaptureMouse(); + GFX_Stop(); +} + + +static void HandleKey(SDL_KeyboardEvent * key) { + Bit32u code; + switch (key->keysym.sym) { + case SDLK_1:code=KBD_1;break; + case SDLK_2:code=KBD_2;break; + case SDLK_3:code=KBD_3;break; + case SDLK_4:code=KBD_4;break; + case SDLK_5:code=KBD_5;break; + case SDLK_6:code=KBD_6;break; + case SDLK_7:code=KBD_7;break; + case SDLK_8:code=KBD_8;break; + case SDLK_9:code=KBD_9;break; + case SDLK_0:code=KBD_0;break; + + case SDLK_q:code=KBD_q;break; + case SDLK_w:code=KBD_w;break; + case SDLK_e:code=KBD_e;break; + case SDLK_r:code=KBD_r;break; + case SDLK_t:code=KBD_t;break; + case SDLK_y:code=KBD_y;break; + case SDLK_u:code=KBD_u;break; + case SDLK_i:code=KBD_i;break; + case SDLK_o:code=KBD_o;break; + case SDLK_p:code=KBD_p;break; + + case SDLK_a:code=KBD_a;break; + case SDLK_s:code=KBD_s;break; + case SDLK_d:code=KBD_d;break; + case SDLK_f:code=KBD_f;break; + case SDLK_g:code=KBD_g;break; + case SDLK_h:code=KBD_h;break; + case SDLK_j:code=KBD_j;break; + case SDLK_k:code=KBD_k;break; + case SDLK_l:code=KBD_l;break; + + case SDLK_z:code=KBD_z;break; + case SDLK_x:code=KBD_x;break; + case SDLK_c:code=KBD_c;break; + case SDLK_v:code=KBD_v;break; + case SDLK_b:code=KBD_b;break; + case SDLK_n:code=KBD_n;break; + case SDLK_m:code=KBD_m;break; + + + case SDLK_F1:code=KBD_f1;break; + case SDLK_F2:code=KBD_f2;break; + case SDLK_F3:code=KBD_f3;break; + case SDLK_F4:code=KBD_f4;break; + case SDLK_F5:code=KBD_f5;break; + case SDLK_F6:code=KBD_f6;break; + case SDLK_F7:code=KBD_f7;break; + case SDLK_F8:code=KBD_f8;break; + case SDLK_F9:code=KBD_f9;break; + case SDLK_F10:code=KBD_f10;break; + case SDLK_F11:code=KBD_f11;break; + case SDLK_F12:code=KBD_f12;break; + +// KBD_esc,KBD_tab,KBD_backspace,KBD_enter,KBD_space, + + case SDLK_ESCAPE:code=KBD_esc;break; + case SDLK_TAB:code=KBD_tab;break; + case SDLK_BACKSPACE:code=KBD_backspace;break; + case SDLK_RETURN:code=KBD_enter;break; + case SDLK_SPACE:code=KBD_space;break; + + case SDLK_LALT:code=KBD_leftalt;break; + case SDLK_RALT:code=KBD_rightalt;break; + case SDLK_LCTRL:code=KBD_leftctrl;break; + case SDLK_RCTRL:code=KBD_rightctrl;break; + case SDLK_LSHIFT:code=KBD_leftshift;break; + case SDLK_RSHIFT:code=KBD_rightshift;break; + + case SDLK_CAPSLOCK:code=KBD_capslock;break; + case SDLK_SCROLLOCK:code=KBD_scrolllock;break; + case SDLK_NUMLOCK:code=KBD_numlock;break; + + case SDLK_BACKQUOTE:code=KBD_grave;break; + case SDLK_MINUS:code=KBD_minus;break; + case SDLK_EQUALS:code=KBD_equals;break; + case SDLK_BACKSLASH:code=KBD_backslash;break; + case SDLK_LEFTBRACKET:code=KBD_leftbracket;break; + case SDLK_RIGHTBRACKET:code=KBD_rightbracket;break; + + case SDLK_SEMICOLON:code=KBD_semicolon;break; + case SDLK_QUOTE:code=KBD_quote;break; + case SDLK_PERIOD:code=KBD_period;break; + case SDLK_COMMA:code=KBD_comma;break; + case SDLK_SLASH:code=KBD_slash;break; + + case SDLK_INSERT:code=KBD_insert;break; + case SDLK_HOME:code=KBD_home;break; + case SDLK_PAGEUP:code=KBD_pageup;break; + case SDLK_DELETE:code=KBD_delete;break; + case SDLK_END:code=KBD_end;break; + case SDLK_PAGEDOWN:code=KBD_pagedown;break; + case SDLK_LEFT:code=KBD_left;break; + case SDLK_UP:code=KBD_up;break; + case SDLK_DOWN:code=KBD_down;break; + case SDLK_RIGHT:code=KBD_right;break; + + case SDLK_KP1:code=KBD_kp1;break; + case SDLK_KP2:code=KBD_kp2;break; + case SDLK_KP3:code=KBD_kp3;break; + case SDLK_KP4:code=KBD_kp4;break; + case SDLK_KP5:code=KBD_kp5;break; + case SDLK_KP6:code=KBD_kp6;break; + case SDLK_KP7:code=KBD_kp7;break; + case SDLK_KP8:code=KBD_kp8;break; + case SDLK_KP9:code=KBD_kp9;break; + case SDLK_KP0:code=KBD_kp0;break; + + case SDLK_KP_DIVIDE:code=KBD_kpslash;break; + case SDLK_KP_MULTIPLY:code=KBD_kpmultiply;break; + case SDLK_KP_MINUS:code=KBD_kpminus;break; + case SDLK_KP_PLUS:code=KBD_kpplus;break; + case SDLK_KP_ENTER:code=KBD_kpenter;break; + case SDLK_KP_PERIOD:code=KBD_kpperiod;break; + +// case SDLK_:code=key_;break; + /* Special Keys */ + default: +//TODO maybe give warning for keypress unknown + return; + } + KEYBOARD_AddKey(code,(key->state==SDL_PRESSED)); +} + +static void HandleMouseMotion(SDL_MouseMotionEvent * motion) { + if (!sdl.mouse_grabbed) { + Mouse_CursorSet((float)motion->x/(float)sdl.width,(float)motion->y/(float)sdl.height); + } else { + Mouse_CursorMoved((float)motion->xrel/(float)sdl.width,(float)motion->yrel/(float)sdl.height); + } +} + +static void HandleMouseButton(SDL_MouseButtonEvent * button) { + switch (button->state) { + case SDL_PRESSED: + switch (button->button) { + case SDL_BUTTON_LEFT: + Mouse_ButtonPressed(0); + break; + case SDL_BUTTON_RIGHT: + Mouse_ButtonPressed(1); + break; + case SDL_BUTTON_MIDDLE: + Mouse_ButtonPressed(2); + break; + } + break; + case SDL_RELEASED: + switch (button->button) { + case SDL_BUTTON_LEFT: + Mouse_ButtonReleased(0); + break; + case SDL_BUTTON_RIGHT: + Mouse_ButtonReleased(1); + break; + case SDL_BUTTON_MIDDLE: + Mouse_ButtonReleased(2); + break; + } + break; + } +} + +static void HandleJoystickAxis(SDL_JoyAxisEvent * jaxis) { + switch (jaxis->axis) { + case 0: + JOYSTICK_Move_X(0,(float)(jaxis->value/32768.0)); + break; + case 1: + JOYSTICK_Move_Y(0,(float)(jaxis->value/32768.0)); + break; + } +} + +static void HandleJoystickButton(SDL_JoyButtonEvent * jbutton) { + bool state; + state=jbutton->type==SDL_JOYBUTTONDOWN; + if (jbutton->button<2) { + JOYSTICK_Button(0,jbutton->button,state); + } +} + + +static void HandleVideoResize(SDL_ResizeEvent * resize) { + Bitu width,height; + width=resize->w; + height=resize->h; + if (sdl.resize) { + GFX_Stop(); + (*sdl.resize)(&width,&height); + sdl.width=width; + sdl.height=height; + ResetScreen(); + GFX_Start(); + } +} + +void GFX_Events() { + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_KEYDOWN: + case SDL_KEYUP: + HandleKey(&event.key); + break; + case SDL_MOUSEMOTION: + HandleMouseMotion(&event.motion); + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + HandleMouseButton(&event.button); + break; + case SDL_JOYAXISMOTION: + HandleJoystickAxis(&event.jaxis); + break; + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + HandleJoystickButton(&event.jbutton); + break; + case SDL_VIDEORESIZE: + HandleVideoResize(&event.resize); + break; + case SDL_QUIT: + E_Exit("Closed the SDL Window"); + break; + } + } +} +#if 0 + +void E_Exit(char * format,...) { + char buf[1024]; + + va_list msg; + strcpy(buf,"EXIT:"); + va_start(msg,format); + vsprintf(buf+strlen(buf),format,msg); + va_end(msg); + waddstr(dbg.win_out,buf); + wprintw(dbg.win_out," %d\n",cycle_count); + wrefresh(dbg.win_out); + throw ((Bitu)1); +} + +#endif + + +void GFX_ShowMsg(char * msg) { + char buf[1024]; + strcpy(buf,msg); + strcat(buf,"\n"); + printf(buf); +}; + +int main(int argc, char* argv[]) { + try { + if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER +#ifndef DISABLE_JOYSTICK + |SDL_INIT_JOYSTICK + +#endif + ) < 0 ) { + E_Exit("Can't init SDL"); + } + GFX_StartUp(); +/* Init all the dosbox subsystems */ + DOSBOX_Init(argc,argv); +/* Start the systems that SDL should provide */ +#ifndef DISABLE_JOYSTICK + if (SDL_NumJoysticks()>0) { + SDL_JoystickEventState(SDL_ENABLE); + sdl.joy=SDL_JoystickOpen(0); + LOG_MSG("Using joystick %s with %d axes and %d buttons",SDL_JoystickName(0),SDL_JoystickNumAxes(sdl.joy),SDL_JoystickNumButtons(sdl.joy)); + JOYSTICK_Enable(0,true); +#endif + } +/* Start dosbox up */ + DOSBOX_StartUp(); + } + catch (Bitu e) { + LOG_MSG("Exit to error %d",e); + } + GFX_Stop(); + + + + return 0; +}; \ No newline at end of file diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am new file mode 100644 index 00000000..8f6507d4 --- /dev/null +++ b/src/hardware/Makefile.am @@ -0,0 +1,11 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include + +EXTRA_DIST = fmopl.c fmopl.h + +noinst_LIBRARIES = libhardware.a + +libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler.cpp joystick.cpp keyboard.cpp \ + memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ + vga.cpp vga.h vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_fonts.cpp vga_gfx.cpp \ + vga_memory.cpp vga_misc.cpp vga_seq.cpp font-switch.h ega-switch.h + diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp new file mode 100644 index 00000000..171772df --- /dev/null +++ b/src/hardware/adlib.cpp @@ -0,0 +1,224 @@ +/* + * 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. + */ + +#include +#include +#include +#include "dosbox.h" +#include "inout.h" +#include "mixer.h" +#include "timer.h" +#include "hardware.h" + +/* + Thanks to vdmsound for nice simple way to implement this +*/ + +namespace MAME { + /* Defines */ +# define logerror(x) + /* Disable recurring warnings */ +#pragma warning ( disable : 4018 ) +#pragma warning ( disable : 4244 ) + + /* Bring in Tatsuyuki Satoh's OPL emulation */ +#define HAS_YM3812 1 +#include "fmopl.c" +} + +struct OPLTimer_t { + bool isEnabled; + bool isMasked; + bool isOverflowed; + Bit32u count; + Bit32u base; +}; + +static OPLTimer_t timer1,timer2; +static MAME::FM_OPL * myopl; +static Bit8u regsel; +#define OPL_INTERNAL_FREQ 3600000 // The OPL operates at 3.6MHz +static MIXER_Channel * adlib_chan; + +static void ADLIB_CallBack(Bit8u *stream, Bit32u len) { + /* Check for size to update and check for 1 ms updates to the opl registers */ + /* Calculate teh machine ms we are at now */ + + /* update 1 ms of data */ + MAME::YM3812UpdateOne(myopl,(MAME::INT16 *)stream,len); +} + +static Bit8u read_p388(Bit32u port) { + Bit8u ret=0; + Bit32u new_ticks=GetTicks(); + if (timer1.isEnabled) { + if ((new_ticks-timer1.base)>timer1.count) { + timer1.isOverflowed=true; + timer1.base=new_ticks; + } + if (timer1.isOverflowed || !timer1.isMasked) { + ret|=0xc0; + } + } + if (timer2.isEnabled) { + if ((new_ticks-timer2.base)>timer2.count) { + timer2.isOverflowed=true; + timer2.base=new_ticks; + } + if (timer2.isOverflowed || !timer2.isMasked) { + ret|=0xA0; + } + } + return ret; +} + +static void write_p388(Bit32u port,Bit8u val) { + regsel=val; +} + +static void write_p389(Bit32u port,Bit8u val) { + switch (regsel) { + case 0x02: /* Timer 1 */ + timer1.count=(val*80/1000); + return; + case 0x03: /* Timer 2 */ + timer2.count=(val*320/1000); + return; + case 0x04: /* IRQ clear / mask and Timer enable */ + if (val&0x80) { + timer1.isOverflowed=false; + timer2.isOverflowed=false; + return; + } + if (val&0x40) { + timer1.isMasked=true; + } else { + timer1.isMasked=false; + timer1.isEnabled=((val&1)>0); + timer1.base=GetTicks(); + } + if (val&0x20) { + timer2.isMasked=true; + } else { + timer2.isMasked=false; + timer2.isEnabled=((val&2)>0); + timer2.base=GetTicks(); + } + return; + default: /* Normal OPL call queue it */ + MAME::OPLWriteReg(myopl,regsel,val); + } + +} + +static HWBlock hw_adlib; +static bool adlib_enabled; + +static void ADLIB_Enable(bool enable) { + if (enable) { + adlib_enabled=true; + MIXER_Enable(adlib_chan,true); + IO_RegisterWriteHandler(0x388,write_p388,"ADLIB Register select"); + IO_RegisterWriteHandler(0x389,write_p389,"ADLIB Data Write"); + IO_RegisterReadHandler(0x388,read_p388,"ADLIB Status"); + + IO_RegisterWriteHandler(0x220,write_p388,"ADLIB Register select"); + IO_RegisterWriteHandler(0x221,write_p389,"ADLIB Data Write"); + IO_RegisterReadHandler(0x220,read_p388,"ADLIB Status"); + } else { + adlib_enabled=false; + MIXER_Enable(adlib_chan,false); + IO_FreeWriteHandler(0x220); + IO_FreeWriteHandler(0x221); + IO_FreeReadHandler(0x220); + IO_FreeWriteHandler(0x388); + IO_FreeWriteHandler(0x389); + IO_FreeReadHandler(0x388); + } +} + + +static void ADLIB_InputHandler(char * line) { + bool s_off=ScanCMDBool(line,"OFF"); + bool s_on=ScanCMDBool(line,"ON"); + char * rem=ScanCMDRemain(line); + if (rem) { + sprintf(line,"Illegal Switch"); + return; + } + if (s_on && s_off) { + sprintf(line,"Can't use /ON and /OFF at the same time"); + return; + } + if (s_on) { + ADLIB_Enable(true); + sprintf(line,"Adlib has been enabled"); + return; + } + if (s_off) { + ADLIB_Enable(false); + sprintf(line,"Adlib has been disabled"); + return; + } + return; +} + +static void ADLIB_OutputHandler (char * towrite) { + if(adlib_enabled) { + sprintf(towrite,"IO %X",0x388); + } else { + sprintf(towrite,"Disabled"); + } +}; + + + + + + + +void ADLIB_Init(void) { + + timer1.isMasked=true; + timer1.base=0; + timer1.count=0; + timer1.isEnabled=false; + timer1.isOverflowed=false; + + timer2.isMasked=true; + timer2.base=0; + timer2.count=0; + timer2.isEnabled=false; + timer2.isOverflowed=false; + + #define ADLIB_FREQ 22050 + myopl=MAME::OPLCreate(0,OPL_INTERNAL_FREQ,ADLIB_FREQ); + + adlib_chan=MIXER_AddChannel(ADLIB_CallBack,ADLIB_FREQ,"ADLIB"); + MIXER_SetMode(adlib_chan,MIXER_16MONO); + + hw_adlib.dev_name="ADLIB"; + hw_adlib.full_name="Adlib FM Synthesizer"; + hw_adlib.next=0; + hw_adlib.help="/ON Enables Adlib\n/OFF Disables Adlib\n"; + hw_adlib.get_input=ADLIB_InputHandler; + hw_adlib.show_status=ADLIB_OutputHandler; + HW_Register(&hw_adlib); + ADLIB_Enable(true); +}; + diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp new file mode 100644 index 00000000..2ac409b9 --- /dev/null +++ b/src/hardware/dma.cpp @@ -0,0 +1,225 @@ +/* + * 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. + */ + +/* + Based the port handling from the bochs dma code. +*/ + +/* + Still need to implement reads from dma ports :) + Perhaps sometime also implement dma writes. + DMA transfer that get setup with a size 0 are also done wrong should be 0x10000 probably. + +*/ + +#include +#include "dosbox.h" +#include "mem.h" +#include "inout.h" +#include "dma.h" + +#ifdef DEBUG_DMA +#define DMA_DEBUG LOG_DEBUG +#else +#define DMA_DEBUG +#endif + +#define DMA_MODE_DEMAND 0 +#define DMA_MODE_SINGLE 1 +#define DMA_MODE_BLOCK 2 +#define DMA_MODE_CASCADE 3 + +struct DMA_CHANNEL { + struct { + Bit8u mode_type; + Bit8u address_decrement; + Bit8u autoinit_enable; + Bit8u transfer_type; + } mode; + Bit16u base_address; + Bit16u base_count; + Bit16u current_address; + Bit32u current_count; + Bit8u page; + bool masked; + HostPt host_address; + bool addr_changed; +}; + + +struct DMA_CONTROLLER { + bool flipflop; + Bit8u status_reg; + Bit8u command_reg; + DMA_CHANNEL chan[4]; +}; + +static DMA_CONTROLLER dma[2]; + + +static void write_dma(Bit32u port,Bit8u val) { + /* only use first dma for now */ + DMA_CONTROLLER * cont=&dma[0]; + DMA_CHANNEL * chan=&cont->chan[port>>1]; + switch (port) { + case 0x00:case 0x02:case 0x04:case 0x06: + if (cont->flipflop) { + chan->base_address=val; + } else { + chan->base_address|=(val<<8); + } + cont->flipflop=!cont->flipflop; + chan->addr_changed=true; + break; + case 0x01:case 0x03:case 0x05:case 0x07: + if (cont->flipflop) { + chan->base_count=val; + } else { + chan->base_count|=(val<<8); + } + cont->flipflop=!cont->flipflop; + chan->addr_changed=true; + break; + case 0x08: /* Command Register */ + if (val != 4) LOG_WARN("DMA1:Illegal command %2X",val); + cont->command_reg=val; + break; + case 0x09: /* Request Register */ + if (val&4) { + /* Set Request bit */ + } else { + Bitu channel = val & 0x03; + cont->status_reg &= ~(1 << (channel+4)); + } + break; + case 0x0a: /* single mask bit register */ + chan->masked=(val & 4)>0; + break; + case 0x0b: /* mode register */ + chan->mode.mode_type = (val >> 6) & 0x03; + chan->mode.address_decrement = (val >> 5) & 0x01; + chan->mode.autoinit_enable = (val >> 4) & 0x01; + chan->mode.transfer_type = (val >> 2) & 0x03; + if (chan->mode.address_decrement) { + LOG_WARN("DMA:Address Decrease not supported yet"); + } + + break; + case 0x0c: /* Clear Flip/Flip */ + cont->flipflop=true; + break; + }; +}; + + +static Bit8u channelindex[7] = {2, 3, 1, 0, 0, 0, 0}; +void write_dma_page(Bit32u port,Bit8u val) { + + switch (port) { + case 0x81: /* dma0 page register, channel 2 */ + case 0x82: /* dma0 page register, channel 3 */ + case 0x83: /* dma0 page register, channel 1 */ + case 0x87: /* dma0 page register, channel 0 */ + Bitu channel = channelindex[port - 0x81]; + dma[0].chan[channel].page=val; + dma[0].chan[channel].addr_changed=true; + break; + } +} + +void DMA_8_Read(Bit32u dmachan,Bit8u * buffer,Bit16u count) { + DMA_CHANNEL * chan=&dma[0].chan[dmachan]; + +/* DMA always does autoinit should work under normal situations */ + if (chan->addr_changed) { + /* Calculate the new starting position for dma read*/ + chan->addr_changed=false; + chan->host_address=memory+(chan->page << 16)+chan->base_address; + + chan->current_count=chan->base_count+1; + chan->current_address=chan->base_address; + DMA_DEBUG("DMA:Transfer from %d size %d",(chan->page << 16)+chan->base_address,chan->current_count); + } + if (!count) return; + if (chan->current_count>=count) { + memcpy(buffer,chan->host_address,count); + chan->host_address+=count; + chan->current_address+=count; + chan->current_count-=count; + return; + } else { + /* Copy remaining piece of first buffer */ + memcpy(buffer,chan->host_address,chan->current_count); + buffer+=chan->current_count; + count-=(Bit16u)chan->current_count; + /* Autoinit reset the dma channel */ + chan->host_address=memory+(chan->page << 16)+chan->base_address; + chan->current_count=chan->base_count+1; + chan->current_address=chan->base_address; + /* Copy the rest of the buffer */ + memcpy(buffer,chan->host_address,count); + chan->host_address+=count; + chan->current_address+=count; + chan->current_count-=count; + return; + } +}; + +void DMA_8_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count) { + if (dma[0].chan[dmachan].addr_changed) { + /* Calculate the new starting position for dma read*/ + dma[0].chan[dmachan].addr_changed=false; + dma[0].chan[dmachan].host_address=memory+(dma[0].chan[dmachan].page << 16)+dma[0].chan[dmachan].base_address; + dma[0].chan[dmachan].current_count=dma[0].chan[dmachan].base_count; + dma[0].chan[dmachan].current_count=dma[0].chan[dmachan].current_count; + } + if (dma[0].chan[dmachan].current_count>=count) { + memcpy(dma[0].chan[dmachan].host_address,buffer,count); + dma[0].chan[dmachan].host_address+=count; + dma[0].chan[dmachan].current_address+=count; + dma[0].chan[dmachan].current_count-=count; + return; + } else { + + } + return; +}; + + + + +void DMA_16_Read(Bit32u dmachan,Bit8u * buffer,Bit16u count) { + +} + +void DMA_16_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count) { + +} + + + + +void DMA_Init(void) { + for (Bit32u i=0;i<0x10;i++) { + IO_RegisterWriteHandler(i,write_dma,"DMA1"); + } + IO_RegisterWriteHandler(0x81,write_dma_page,"DMA Pages"); + IO_RegisterWriteHandler(0x82,write_dma_page,"DMA Pages"); + IO_RegisterWriteHandler(0x83,write_dma_page,"DMA Pages"); + IO_RegisterWriteHandler(0x87,write_dma_page,"DMA Pages"); +} diff --git a/src/hardware/ega-switch.h b/src/hardware/ega-switch.h new file mode 100644 index 00000000..b4dff453 --- /dev/null +++ b/src/hardware/ega-switch.h @@ -0,0 +1,9730 @@ +switch (bit_mask) { + case 0: + break; + case 1: + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 2: + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 3: + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 4: + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 5: + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 6: + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 7: + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 8: + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + break; + case 9: + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 10: + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 11: + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 12: + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 13: + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 14: + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 15: + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 16: + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + break; + case 17: + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 18: + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 19: + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 20: + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 21: + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 22: + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 23: + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 24: + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + break; + case 25: + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 26: + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 27: + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 28: + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 29: + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 30: + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 31: + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 32: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + break; + case 33: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 34: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 35: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 36: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 37: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 38: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 39: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 40: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + break; + case 41: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 42: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 43: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 44: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 45: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 46: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 47: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 48: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + break; + case 49: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 50: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 51: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 52: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 53: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 54: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 55: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 56: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + break; + case 57: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 58: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 59: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 60: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 61: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 62: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 63: + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 64: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + break; + case 65: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 66: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 67: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 68: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 69: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 70: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 71: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 72: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + break; + case 73: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 74: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 75: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 76: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 77: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 78: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 79: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 80: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + break; + case 81: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 82: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 83: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 84: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 85: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 86: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 87: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 88: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + break; + case 89: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 90: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 91: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 92: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 93: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 94: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 95: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 96: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + break; + case 97: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 98: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 99: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 100: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 101: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 102: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 103: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 104: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + break; + case 105: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 106: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 107: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 108: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 109: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 110: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 111: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 112: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + break; + case 113: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 114: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 115: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 116: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 117: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 118: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 119: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 120: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + break; + case 121: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 122: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 123: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 124: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 125: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 126: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 127: + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 128: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + break; + case 129: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 130: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 131: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 132: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 133: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 134: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 135: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 136: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + break; + case 137: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 138: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 139: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 140: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 141: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 142: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 143: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 144: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + break; + case 145: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 146: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 147: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 148: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 149: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 150: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 151: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 152: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + break; + case 153: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 154: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 155: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 156: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 157: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 158: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 159: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 160: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + break; + case 161: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 162: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 163: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 164: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 165: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 166: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 167: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 168: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + break; + case 169: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 170: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 171: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 172: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 173: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 174: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 175: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 176: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + break; + case 177: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 178: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 179: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 180: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 181: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 182: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 183: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 184: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + break; + case 185: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 186: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 187: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 188: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 189: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 190: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 191: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 192: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + break; + case 193: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 194: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 195: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 196: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 197: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 198: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 199: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 200: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + break; + case 201: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 202: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 203: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 204: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 205: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 206: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 207: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 208: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + break; + case 209: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 210: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 211: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 212: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 213: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 214: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 215: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 216: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + break; + case 217: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 218: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 219: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 220: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 221: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 222: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 223: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 224: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + break; + case 225: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 226: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 227: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 228: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 229: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 230: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 231: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 232: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + break; + case 233: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 234: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 235: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 236: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 237: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 238: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 239: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 240: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + break; + case 241: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 242: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 243: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 244: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 245: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 246: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 247: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 248: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + break; + case 249: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 250: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 251: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 252: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + break; + case 253: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; + case 254: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + break; + case 255: + { + Bit8u color=0; + if (pixels.b[0] & 128) color|=1; + if (pixels.b[1] & 128) color|=2; + if (pixels.b[2] & 128) color|=4; + if (pixels.b[3] & 128) color|=8; + *(write_pixels+0)=color; + *(write_pixels+0+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 64) color|=1; + if (pixels.b[1] & 64) color|=2; + if (pixels.b[2] & 64) color|=4; + if (pixels.b[3] & 64) color|=8; + *(write_pixels+1)=color; + *(write_pixels+1+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 32) color|=1; + if (pixels.b[1] & 32) color|=2; + if (pixels.b[2] & 32) color|=4; + if (pixels.b[3] & 32) color|=8; + *(write_pixels+2)=color; + *(write_pixels+2+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 16) color|=1; + if (pixels.b[1] & 16) color|=2; + if (pixels.b[2] & 16) color|=4; + if (pixels.b[3] & 16) color|=8; + *(write_pixels+3)=color; + *(write_pixels+3+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 8) color|=1; + if (pixels.b[1] & 8) color|=2; + if (pixels.b[2] & 8) color|=4; + if (pixels.b[3] & 8) color|=8; + *(write_pixels+4)=color; + *(write_pixels+4+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 4) color|=1; + if (pixels.b[1] & 4) color|=2; + if (pixels.b[2] & 4) color|=4; + if (pixels.b[3] & 4) color|=8; + *(write_pixels+5)=color; + *(write_pixels+5+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 2) color|=1; + if (pixels.b[1] & 2) color|=2; + if (pixels.b[2] & 2) color|=4; + if (pixels.b[3] & 2) color|=8; + *(write_pixels+6)=color; + *(write_pixels+6+512*1024)=color; + } + { + Bit8u color=0; + if (pixels.b[0] & 1) color|=1; + if (pixels.b[1] & 1) color|=2; + if (pixels.b[2] & 1) color|=4; + if (pixels.b[3] & 1) color|=8; + *(write_pixels+7)=color; + *(write_pixels+7+512*1024)=color; + } + break; +} diff --git a/src/hardware/fmopl.c b/src/hardware/fmopl.c new file mode 100644 index 00000000..2f73d7db --- /dev/null +++ b/src/hardware/fmopl.c @@ -0,0 +1,1878 @@ +/* +** +** File: fmopl.c - software implementation of FM sound generator +** types OPL and OPL2 +** +** Copyright (C) 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmulator development +** (c) 2002 Jarek Burczynski +** +** Version 0.58 +** + +Revision History: + +03-24-2002 Jarek Burczynski (thanks to Dox for the YM3812 chip) + + Complete rewrite (all verified on real YM3812): + + - corrected sin_tab and tl_tab data + - corrected operator output calculations + - corrected waveform_select_enable register; + simply: ignore all writes to waveform_select register when + waveform_select_enable == 0 and do not change the waveform previously selected. + - corrected KSR handling + - corrected Envelope Generator: attack shape, Sustain mode and + Percussive/Non-percussive modes handling + - Envelope Generator rates are two times slower now + - LFO amplitude (tremolo) and phase modulation (vibrato) + - rhythm sounds phase generation + - white noise generator (big thanks to Olivier Galibert for mentioning Berlekamp-Massey algorithm) + - corrected key on/off handling (the 'key' signal is ORed from three sources: FM, rhythm and CSM) + - funky details (like ignoring output of operator 1 in BD rhythm sound when connect == 1) + +12-28-2001 Acho A. Tang + - reflected Delta-T EOS status on Y8950 status port. + - fixed subscription range of attack/decay tables + + + + To do: + add delay before key off in CSM mode (see CSMKeyControll) + verify volume of the FM part on the Y8950 +*/ + +#include +#include +#include +#include +#include +//#include "driver.h" /* use M.A.M.E. */ +#include "fmopl.h" + +#ifndef PI +#define PI 3.14159265358979323846 +#endif + + + + + +/* output final shift */ +#if (OPL_SAMPLE_BITS==16) + #define FINAL_SH (0) + #define MAXOUT (+32767) + #define MINOUT (-32768) +#else + #define FINAL_SH (8) + #define MAXOUT (+127) + #define MINOUT (-128) +#endif + + +#define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */ +#define ENV_SH 16 /* 16.16 fixed point (envelope calculations) */ +#define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */ +#define TIMER_SH 16 /* 16.16 fixed point (timers calculations) */ + +#define FREQ_MASK ((1<>8)&0xff,sample[0]); \ + } + #else /*save to STEREO file */ + #define SAVE_ALL_CHANNELS \ + { signed int pom = lt; \ + fputc((unsigned short)pom&0xff,sample[0]); \ + fputc(((unsigned short)pom>>8)&0xff,sample[0]); \ + pom = rt; \ + fputc((unsigned short)pom&0xff,sample[0]); \ + fputc(((unsigned short)pom>>8)&0xff,sample[0]); \ + } + #endif +#endif + +/* #define LOG_CYM_FILE */ +#ifdef LOG_CYM_FILE + FILE * cymfile = NULL; +#endif + + + +/* mapping of register number (offset) to slot number used by the emulator */ +static const int slot_array[32]= +{ + 0, 2, 4, 1, 3, 5,-1,-1, + 6, 8,10, 7, 9,11,-1,-1, + 12,14,16,13,15,17,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1 +}; + +/* key scale level */ +/* table is 3dB/octave , DV converts this into 6dB/octave */ +/* 0.09375 is bit 0 weight expressed in the 'decibel' scale */ +#define DV (0.09375/2.0) +static const UINT32 ksl_tab[8*16]= +{ + /* OCT 0 */ + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + /* OCT 1 */ + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.750/DV, 1.125/DV, 1.500/DV, + 1.875/DV, 2.250/DV, 2.625/DV, 3.000/DV, + /* OCT 2 */ + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 1.125/DV, 1.875/DV, 2.625/DV, + 3.000/DV, 3.750/DV, 4.125/DV, 4.500/DV, + 4.875/DV, 5.250/DV, 5.625/DV, 6.000/DV, + /* OCT 3 */ + 0.000/DV, 0.000/DV, 0.000/DV, 1.875/DV, + 3.000/DV, 4.125/DV, 4.875/DV, 5.625/DV, + 6.000/DV, 6.750/DV, 7.125/DV, 7.500/DV, + 7.875/DV, 8.250/DV, 8.625/DV, 9.000/DV, + /* OCT 4 */ + 0.000/DV, 0.000/DV, 3.000/DV, 4.875/DV, + 6.000/DV, 7.125/DV, 7.875/DV, 8.625/DV, + 9.000/DV, 9.750/DV,10.125/DV,10.500/DV, + 10.875/DV,11.250/DV,11.625/DV,12.000/DV, + /* OCT 5 */ + 0.000/DV, 3.000/DV, 6.000/DV, 7.875/DV, + 9.000/DV,10.125/DV,10.875/DV,11.625/DV, + 12.000/DV,12.750/DV,13.125/DV,13.500/DV, + 13.875/DV,14.250/DV,14.625/DV,15.000/DV, + /* OCT 6 */ + 0.000/DV, 6.000/DV, 9.000/DV,10.875/DV, + 12.000/DV,13.125/DV,13.875/DV,14.625/DV, + 15.000/DV,15.750/DV,16.125/DV,16.500/DV, + 16.875/DV,17.250/DV,17.625/DV,18.000/DV, + /* OCT 7 */ + 0.000/DV, 9.000/DV,12.000/DV,13.875/DV, + 15.000/DV,16.125/DV,16.875/DV,17.625/DV, + 18.000/DV,18.750/DV,19.125/DV,19.500/DV, + 19.875/DV,20.250/DV,20.625/DV,21.000/DV +}; +#undef DV + +/* sustain lebel table (3dB per step) */ +/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ +#define SC(db) (UINT32) ( db * (4.0/ENV_STEP) * (1<>3) + +/* sin waveform table in 'decibel' scale */ +/* four waveforms on OPL2 type chips */ +static unsigned int sin_tab[SIN_LEN * 4]; + + +/* LFO Amplitude Modulation table (verified on real YM3812) + + Length: 210 elements. + + Each of the elements has to be repeated + exactly 64 times (on 64 consecutive samples). + The whole table takes: 64 * 210 = 13440 samples. + + When AM = 1 data is multiplied by 2 + When AM = 0 data is divided by 4 and then multiplied by 2 (loosing precision is important) +*/ + +#define LFO_AM_TAB_ELEMENTS 210 + +static const UINT8 lfo_am_table[LFO_AM_TAB_ELEMENTS] = { +0,0,0,0,0,0,0, +1,1,1,1, +2,2,2,2, +3,3,3,3, +4,4,4,4, +5,5,5,5, +6,6,6,6, +7,7,7,7, +8,8,8,8, +9,9,9,9, +10,10,10,10, +11,11,11,11, +12,12,12,12, +13,13,13,13, +14,14,14,14, +15,15,15,15, +16,16,16,16, +17,17,17,17, +18,18,18,18, +19,19,19,19, +20,20,20,20, +21,21,21,21, +22,22,22,22, +23,23,23,23, +24,24,24,24, +25,25,25,25, +26,26,26, +25,25,25,25, +24,24,24,24, +23,23,23,23, +22,22,22,22, +21,21,21,21, +20,20,20,20, +19,19,19,19, +18,18,18,18, +17,17,17,17, +16,16,16,16, +15,15,15,15, +14,14,14,14, +13,13,13,13, +12,12,12,12, +11,11,11,11, +10,10,10,10, +9,9,9,9, +8,8,8,8, +7,7,7,7, +6,6,6,6, +5,5,5,5, +4,4,4,4, +3,3,3,3, +2,2,2,2, +1,1,1,1 +}; + +/* LFO Phase Modulation table (verified on real YM3812) */ +static const INT8 lfo_pm_table[8*8*2] = { + +/* FNUM2/FNUM = 00 0xxxxxxx (0x0000) */ +0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/ +0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 00 1xxxxxxx (0x0080) */ +0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/ +1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 01 0xxxxxxx (0x0100) */ +1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/ +2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 01 1xxxxxxx (0x0180) */ +1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/ +3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 10 0xxxxxxx (0x0200) */ +2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/ +4, 2, 0,-2,-4,-2, 0, 2, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 10 1xxxxxxx (0x0280) */ +2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/ +5, 2, 0,-2,-5,-2, 0, 2, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 11 0xxxxxxx (0x0300) */ +3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/ +6, 3, 0,-3,-6,-3, 0, 3, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 11 1xxxxxxx (0x0380) */ +3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/ +7, 3, 0,-3,-7,-3, 0, 3 /*LFO PM depth = 1*/ +}; + + +/* lock level of common table */ +static int num_lock = 0; + +/* work table */ +static void *cur_chip = NULL; /* current chip point */ +OPL_SLOT *SLOT7_1,*SLOT7_2,*SLOT8_1,*SLOT8_2; + +static signed int phase_modulation; /* phase modulation input (SLOT 2) */ +static signed int output[1]; + +#if BUILD_Y8950 +static INT32 output_deltat[4]; /* for Y8950 DELTA-T */ +#endif + +static UINT32 LFO_AM; +static INT32 LFO_PM; + + + +/* log output level */ +#define LOG_ERR 3 /* ERROR */ +#define LOG_WAR 2 /* WARNING */ +#define LOG_INF 1 /* INFORMATION */ + +#define LOG_LEVEL LOG_INF + +#define LOG(n,x) if( (n)>=LOG_LEVEL ) logerror x + + + +INLINE int limit( int val, int max, int min ) { + if ( val > max ) + val = max; + else if ( val < min ) + val = min; + + return val; +} + + + +/* status set and IRQ handling */ +INLINE void OPL_STATUS_SET(FM_OPL *OPL,int flag) +{ + /* set status flag */ + OPL->status |= flag; + if(!(OPL->status & 0x80)) + { + if(OPL->status & OPL->statusmask) + { /* IRQ on */ + OPL->status |= 0x80; + /* callback user interrupt handler (IRQ is OFF to ON) */ + if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1); + } + } +} + +/* status reset and IRQ handling */ +INLINE void OPL_STATUS_RESET(FM_OPL *OPL,int flag) +{ + /* reset status flag */ + OPL->status &=~flag; + if((OPL->status & 0x80)) + { + if (!(OPL->status & OPL->statusmask) ) + { + OPL->status &= 0x7f; + /* callback user interrupt handler (IRQ is ON to OFF) */ + if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0); + } + } +} + +/* IRQ mask set */ +INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag) +{ + OPL->statusmask = flag; + /* IRQ handling check */ + OPL_STATUS_SET(OPL,0); + OPL_STATUS_RESET(OPL,0); +} + + +/* advance LFO to next sample */ +INLINE void advance_lfo(FM_OPL *OPL) +{ + UINT8 tmp; + + /* LFO */ + OPL->lfo_am_cnt += OPL->lfo_am_inc; + if (OPL->lfo_am_cnt >= (LFO_AM_TAB_ELEMENTS<lfo_am_cnt -= (LFO_AM_TAB_ELEMENTS<lfo_am_cnt >> LFO_SH ]; + + if (OPL->lfo_am_depth) + LFO_AM = (tmp) * 2; + else + LFO_AM = (tmp>>2) * 2; + + OPL->lfo_pm_cnt += OPL->lfo_pm_inc; + LFO_PM = ( (OPL->lfo_pm_cnt>>LFO_SH) & 7) | OPL->lfo_pm_depth_range; +} + +/* advance to next sample */ +INLINE void advance(FM_OPL *OPL) +{ + OPL_CH *CH; + OPL_SLOT *SLOT; + int i; + + + for (i=0; i<9*2; i++) + { + CH = &OPL->P_CH[i/2]; + SLOT = &CH->SLOT[i&1]; + + /* Envelope Generator */ + switch(SLOT->state) + { + case EG_ATT: /* attack phase */ + { + INT32 step = SLOT->volume; + + SLOT->volume -= SLOT->delta_ar; + step = (step>>ENV_SH) - (((UINT32)SLOT->volume)>>ENV_SH); /* number of levels passed since last time */ + if (step > 0) + { + INT32 tmp_volume = SLOT->volume + (step<>4) & ~ENV_MASK); + if (tmp_volume <= MIN_ATT_INDEX) + break; + step--; + }while(step); + SLOT->volume = tmp_volume; + } + + if (SLOT->volume <= MIN_ATT_INDEX) + { + if (SLOT->volume < 0) + SLOT->volume = 0; /* this is not quite correct (checked) */ + + SLOT->state = EG_DEC; + } + } + break; + + case EG_DEC: /* decay phase */ + + if ( (SLOT->volume += SLOT->delta_dr) >= SLOT->sl ) + { + SLOT->volume = SLOT->sl; /* this is not quite correct (checked) */ + SLOT->state = EG_SUS; + } + break; + + case EG_SUS: /* sustain phase */ + + /* this is important behaviour: + one can change percusive/non-percussive modes on the fly and + the chip will remain in sustain phase - verified on real YM3812 */ + + if(SLOT->eg_type) /* non-percussive mode */ + { + /* do nothing */ + } + else /* percussive mode */ + { + /* during sustain phase chip adds Release Rate (in percussive mode) */ + + if ( (SLOT->volume += SLOT->delta_rr) > MAX_ATT_INDEX ) + { + SLOT->volume = MAX_ATT_INDEX; + } + /* else do nothing in sustain phase */ + } + break; + + case EG_REL: /* release phase */ + if ( (SLOT->volume += SLOT->delta_rr) > MAX_ATT_INDEX ) + { + SLOT->volume = MAX_ATT_INDEX; + SLOT->state = EG_OFF; + } + break; + + default: + break; + } + + /* Phase Generator */ + if(SLOT->vib) + { + UINT8 block; + unsigned int block_fnum = CH->block_fnum; + + unsigned int fnum_lfo = (block_fnum&0x0380) >> 7; + + signed int lfo_fn_table_index_offset = lfo_pm_table[LFO_PM + 16*fnum_lfo ]; + + if (lfo_fn_table_index_offset) /* LFO phase modulation active */ + { + block_fnum += lfo_fn_table_index_offset; + block = (block_fnum&0x1c00) >> 10; + SLOT->Cnt += (OPL->fn_tab[block_fnum&0x03ff] >> (7-block)) * SLOT->mul;//ok + } + else /* LFO phase modulation = zero */ + { + SLOT->Cnt += SLOT->Incr; + } + } + else /* LFO phase modulation disabled for this operator */ + { + SLOT->Cnt += SLOT->Incr; + } + } + + /* The Noise Generator of the YM3812 is 23-bit shift register. + * Period is equal to 2^23-2 samples. + * Register works at sampling frequency of the chip, so output + * can change on every sample. + * + * Output of the register and input to the bit 22 is: + * bit0 XOR bit14 XOR bit15 XOR bit22 + * + * Simply use bit 22 as the noise output. + */ + + OPL->noise_p += OPL->noise_f; + i = OPL->noise_p >> FREQ_SH; /* number of events (shifts of the shift register) */ + OPL->noise_p &= FREQ_MASK; + while (i) + { + UINT32 j; + j = ( (OPL->noise_rng) ^ (OPL->noise_rng>>14) ^ (OPL->noise_rng>>15) ^ (OPL->noise_rng>>22) ) & 1; + OPL->noise_rng = (j<<22) | (OPL->noise_rng>>1); + i--; + } +} + + +INLINE signed int op_calc(UINT32 phase, unsigned int env, signed int pm) +{ + UINT32 p; + + p = (env<<3) + sin_tab[ ( ((signed int)((phase & ~FREQ_MASK) + (pm<<16))) >> FREQ_SH ) & SIN_MASK ]; + + if (p >= TL_TAB_LEN) + return 0; + return tl_tab[p]; +} + +INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm) +{ + UINT32 p; + INT32 i; + + i = (phase & ~FREQ_MASK) + pm; + +/*logerror("i=%08x (i>>16)&511=%8i phase=%i [pm=%08x] ",i, (i>>16)&511, phase>>FREQ_SH, pm);*/ + + p = (env<<3) + sin_tab[ (i>>FREQ_SH) & SIN_MASK]; + +/*logerror("(p&255=%i p>>8=%i) out= %i\n", p&255,p>>8, tl_tab[p&255]>>(p>>8) );*/ + + if (p >= TL_TAB_LEN) + return 0; + return tl_tab[p]; +} + + +#define volume_calc(OP) ((OP)->TLL + (((UINT32)(OP)->volume)>>ENV_SH) + (LFO_AM & (OP)->AMmask)) + +/* calculate output */ +INLINE void OPL_CALC_CH( OPL_CH *CH ) +{ + OPL_SLOT *SLOT; + unsigned int env; + signed int out; + + phase_modulation = 0; + + /* SLOT 1 */ + SLOT = &CH->SLOT[SLOT1]; + env = volume_calc(SLOT); + out = CH->op1_out[0] + CH->op1_out[1]; + CH->op1_out[0] = CH->op1_out[1]; + *CH->connect1 += CH->op1_out[0]; + CH->op1_out[1] = 0; + if( env < ENV_QUIET ) + CH->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB) ); + + /* SLOT 2 */ + SLOT++; + env = volume_calc(SLOT); + if( env < ENV_QUIET ) + output[0] += op_calc(SLOT->Cnt, env, phase_modulation); +} + +/* + operators used in the rhythm sounds generation process: + + Envelope Generator: + +channel operator register number Bass High Snare Tom Top +/ slot number TL ARDR SLRR Wave Drum Hat Drum Tom Cymbal + 6 / 0 12 50 70 90 f0 + + 6 / 1 15 53 73 93 f3 + + 7 / 0 13 51 71 91 f1 + + 7 / 1 16 54 74 94 f4 + + 8 / 0 14 52 72 92 f2 + + 8 / 1 17 55 75 95 f5 + + + Phase Generator: + +channel operator register number Bass High Snare Tom Top +/ slot number MULTIPLE Drum Hat Drum Tom Cymbal + 6 / 0 12 30 + + 6 / 1 15 33 + + 7 / 0 13 31 + + + + 7 / 1 16 34 ----- n o t u s e d ----- + 8 / 0 14 32 + + 8 / 1 17 35 + + + +channel operator register number Bass High Snare Tom Top +number number BLK/FNUM2 FNUM Drum Hat Drum Tom Cymbal + 6 12,15 B6 A6 + + + 7 13,16 B7 A7 + + + + + 8 14,17 B8 A8 + + + + +*/ + +/* calculate rhythm */ + +INLINE void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) +{ + OPL_SLOT *SLOT; + signed int out; + unsigned int env; + + + /* Bass Drum (verified on real YM3812): + - depends on the channel 6 'connect' register: + when connect = 0 it works the same as in normal (non-rhythm) mode (op1->op2->out) + when connect = 1 _only_ operator 2 is present on output (op2->out), operator 1 is ignored + - output sample always is multiplied by 2 + */ + + phase_modulation = 0; + /* SLOT 1 */ + SLOT = &CH[6].SLOT[SLOT1]; + env = volume_calc(SLOT); + { + out = CH[6].op1_out[0] + CH[6].op1_out[1]; + CH[6].op1_out[0] = CH[6].op1_out[1]; + + if (!CH[6].CON) + phase_modulation = CH[6].op1_out[0]; + //else ignore output of operator 1 + + CH[6].op1_out[1] = 0; + if( env < ENV_QUIET ) + CH[6].op1_out[1] = op_calc1(SLOT->Cnt, env, (out<Cnt, env, phase_modulation) * 2; + + + /* Phase generation is based on: */ + // HH (13) channel 7->slot 1 combined with channel 8->slot 2 (same combination as TOP CYMBAL but different output phases) + // SD (16) channel 7->slot 1 + // TOM (14) channel 8->slot 1 + // TOP (17) channel 7->slot 1 combined with channel 8->slot 2 (same combination as HIGH HAT but different output phases) + + /* Envelope generation based on: */ + // HH channel 7->slot1 + // SD channel 7->slot2 + // TOM channel 8->slot1 + // TOP channel 8->slot2 + + + /* The following formulas can be well optimized. + I leave them in direct form for now (in case I've missed something). + */ + + /* High Hat (verified on real YM3812) */ + env = volume_calc(SLOT7_1); + if( env < ENV_QUIET ) + { + + /* high hat phase generation: + phase = d0 or 234 (based on frequency only) + phase = 34 or 2d0 (based on noise) + */ + + /* base frequency derived from operator 1 in channel 7 */ + unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1; + unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1; + unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1; + + unsigned char res1 = (bit2 ^ bit7) | bit3; + + /* when res1 = 0 phase = 0x000 | 0xd0; */ + /* when res1 = 1 phase = 0x200 | (0xd0>>2); */ + UINT32 phase = res1 ? (0x200|(0xd0>>2)) : 0xd0; + + /* enable gate based on frequency of operator 2 in channel 8 */ + unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1; + unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1; + + unsigned char res2 = (bit3e ^ bit5e); + + /* when res2 = 0 pass the phase from calculation above (res1); */ + /* when res2 = 1 phase = 0x200 | (0xd0>>2); */ + if (res2) + phase = (0x200|(0xd0>>2)); + + + /* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */ + /* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */ + if (phase&0x200) + { + if (noise) + phase = 0x200|0xd0; + } + else + /* when phase & 0x200 is clear and noise=1 then phase = 0xd0>>2 */ + /* when phase & 0x200 is clear and noise=0 then phase = 0xd0, ie no change */ + { + if (noise) + phase = 0xd0>>2; + } + + output[0] += op_calc(phase<Cnt>>FREQ_SH)>>8)&1; + + /* when bit8 = 0 phase = 0x100; */ + /* when bit8 = 1 phase = 0x200; */ + UINT32 phase = bit8 ? 0x200 : 0x100; + + /* Noise bit XOR'es phase by 0x100 */ + /* when noisebit = 0 pass the phase from calculation above */ + /* when noisebit = 1 phase ^= 0x100; */ + /* in other words: phase ^= (noisebit<<8); */ + if (noise) + phase ^= 0x100; + + output[0] += op_calc(phase<Cnt, env, 0) * 2; + + /* Top Cymbal (verified on real YM3812) */ + env = volume_calc(SLOT8_2); + if( env < ENV_QUIET ) + { + /* base frequency derived from operator 1 in channel 7 */ + unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1; + unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1; + unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1; + + unsigned char res1 = (bit2 ^ bit7) | bit3; + + /* when res1 = 0 phase = 0x000 | 0x100; */ + /* when res1 = 1 phase = 0x200 | 0x100; */ + UINT32 phase = res1 ? 0x300 : 0x100; + + /* enable gate based on frequency of operator 2 in channel 8 */ + unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1; + unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1; + + unsigned char res2 = (bit3e ^ bit5e); + /* when res2 = 0 pass the phase from calculation above (res1); */ + /* when res2 = 1 phase = 0x200 | 0x100; */ + if (res2) + phase = 0x300; + + output[0] += op_calc(phase<eg_tab[i] = 0; + + for (i = 4;i < 64;i++) + { + rate = OPL->freqbase; /* frequency rate */ + if( i < 60 ) rate *= 1.0+(i&3)*0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */ + rate *= 1 << (i>>2); /* b2-5 : shift bit */ + rate /= /*576*/ 8 * 1024.0; + rate *= (double)(1<eg_tab[16+i] = rate; +#if 0 + logerror("FMOPL.C: Rate %2i %1i Decay [real %11.4f ms][emul %11.4f ms][d=%08x]\n",i>>2, i&3, + ( ((double)(ENV_LEN<rate), + ( ((double)(ENV_LEN<eg_tab[16+i]) * (1000.0 / (double)OPL->rate), OPL->eg_tab[16+i] ); +#endif + } + + for (i = 0; i < 16; i++) + { + OPL->eg_tab[16+64+i] = OPL->eg_tab[16+63]; + } + +#if 0 + for (i = 4; i < 64 ; i++) /* test */ + { + UINT32 vol = 0; + UINT32 vol_step = OPL->eg_tab[16+i]; + int j=0, change_no=0; + int lastchange=-1; + + logerror("FMOPL.C - EG TEST: Rate %2i %1i [d=%08x]\n",i>>2, i&3, vol_step ); + logerror(" -> changes every samples: "); + + while (change_no<16) + { + UINT32 tmp_vol = vol>>ENV_SH; + vol += vol_step; + if (tmp_vol!=(vol>>ENV_SH)) + { + //display the distance (in number of samples) since last level change + logerror("%i ",j-lastchange); + lastchange = j; + change_no++; + } + j++; + } + logerror("\n"); + } +#endif +} + +/* generic table initialize */ +static int init_tables(void) +{ + signed int i,x; + signed int n; + double o,m; + + + for (x=0; x>= 4; /* 12 bits here */ + if (n&1) /* round to nearest */ + n = (n>>1)+1; + else + n = n>>1; + /* 11 bits here (rounded) */ + n <<= 1; /* 12 bits here (as in real chip) */ + tl_tab[ x*2 + 0 ] = n; + tl_tab[ x*2 + 1 ] = -tl_tab[ x*2 + 0 ]; + + for (i=1; i<12; i++) + { + tl_tab[ x*2+0 + i*2*TL_RES_LEN ] = tl_tab[ x*2+0 ]>>i; + tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = -tl_tab[ x*2+0 + i*2*TL_RES_LEN ]; + } + #if 0 + logerror("tl %04i", x); + for (i=0; i<12; i++) + logerror(", [%02i] %4i", i*2, tl_tab[ x*2 /*+1*/ + i*2*TL_RES_LEN ] ); + logerror("\n"); + #endif + } + /*logerror("FMOPL.C: TL_TAB_LEN = %i elements (%i bytes)\n",TL_TAB_LEN, (int)sizeof(tl_tab));*/ + + + for (i=0; i0.0) + o = 8*log(1.0/m)/log(2); /* convert to 'decibels' */ + else + o = 8*log(-1.0/m)/log(2); /* convert to 'decibels' */ + + o = o / (ENV_STEP/4); + + n = (int)(2.0*o); + if (n&1) /* round to nearest */ + n = (n>>1)+1; + else + n = n>>1; + + sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 ); + + /*logerror("FMOPL.C: sin [%4i (hex=%03x)]= %4i (tl_tab value=%5i)\n", i, i, sin_tab[i], tl_tab[sin_tab[i]] );*/ + } + + for (i=0; i>1) ]; + + /* waveform 3: /- /- /- /- */ + /* abs(output only first quarter of the sinus waveform) */ + if (i & (1<<(SIN_BITS-2)) ) + sin_tab[3*SIN_LEN+i] = TL_TAB_LEN; + else + sin_tab[3*SIN_LEN+i] = sin_tab[i & (SIN_MASK>>2)]; + + /*logerror("FMOPL.C: sin1[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[1*SIN_LEN+i], tl_tab[sin_tab[1*SIN_LEN+i]] ); + logerror("FMOPL.C: sin2[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[2*SIN_LEN+i], tl_tab[sin_tab[2*SIN_LEN+i]] ); + logerror("FMOPL.C: sin3[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[3*SIN_LEN+i], tl_tab[sin_tab[3*SIN_LEN+i]] );*/ + } + /*logerror("FMOPL.C: ENV_QUIET= %08x (dec*8=%i)\n", ENV_QUIET, ENV_QUIET*8 );*/ + + +#ifdef SAVE_SAMPLE + sample[0]=fopen("sampsum.pcm","wb"); +#endif + + return 1; +} + +static void OPLCloseTable( void ) +{ +#ifdef SAVE_SAMPLE + fclose(sample[0]); +#endif +} + + + +static void OPL_initalize(FM_OPL *OPL) +{ + int i; + + /* frequency base */ +#if 1 + OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / 72.0) / OPL->rate : 0; +#else + OPL->rate = (double)OPL->clock / 72.0; + OPL->freqbase = 1.0; +#endif + + /* Timer base time */ + OPL->TimerBase = 1.0 / ((double)OPL->clock / 72.0 ); + + /* make time tables */ + init_timetables( OPL ); + + /* make fnumber -> increment counter table */ + for( i=0 ; i < 1024 ; i++ ) + { + /* opn phase increment counter = 20bit */ + OPL->fn_tab[i] = (UINT32)( (double)i * 64 * OPL->freqbase * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */ +#if 0 + logerror("FMOPL.C: fn_tab[%4i] = %08x (dec=%8i)\n", + i, OPL->fn_tab[i]>>6, OPL->fn_tab[i]>>6 ); +#endif + } + +#if 0 + for( i=0 ; i < 16 ; i++ ) + { + logerror("FMOPL.C: sl_tab[%i] = %08x\n", + i, sl_tab[i] ); + } + for( i=0 ; i < 8 ; i++ ) + { + int j; + logerror("FMOPL.C: ksl_tab[oct=%2i] =",i); + for (j=0; j<16; j++) + { + logerror("%08x ", ksl_tab[i*16+j] ); + } + logerror("\n"); + } +#endif + + + /* Amplitude modulation: 26 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */ + /* In our LFO_AM_TABLE one entry lasts for 64 samples */ + OPL->lfo_am_inc = (1.0 / 64.0 ) * (1<freqbase; + + /* Vibrato: 8 output levels (triangle waveform); 1 level takes 1024 samples */ + OPL->lfo_pm_inc = (1.0 / 1024.0) * (1<freqbase; + + /*logerror ("OPL->lfo_am_inc = %8x ; OPL->lfo_pm_inc = %8x\n", OPL->lfo_am_inc, OPL->lfo_pm_inc);*/ + + /* Noise generator: a step takes 1 sample */ + OPL->noise_f = (1.0 / 1.0) * (1<freqbase; +} + +INLINE void FM_KEYON(OPL_SLOT *SLOT, UINT32 key_set) +{ + if( !SLOT->key ) + { + /* restart Phase Generator */ + SLOT->Cnt = 0; + /* phase -> Attack */ + SLOT->state = EG_ATT; + } + SLOT->key |= key_set; +} + +INLINE void FM_KEYOFF(OPL_SLOT *SLOT, UINT32 key_clr) +{ + if( SLOT->key ) + { + SLOT->key &= key_clr; + + if( !SLOT->key ) + { + /* phase -> Release */ + if (SLOT->state>EG_REL) + SLOT->state = EG_REL; + } + } +} + +/* update phase increment counter of operator (also update the EG rates if necessary) */ +INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT) +{ + int ksr; + + /* (frequency) phase increment counter */ + SLOT->Incr = CH->fc * SLOT->mul; + ksr = CH->kcode >> SLOT->KSR; + + if( SLOT->ksr != ksr ) + { + SLOT->ksr = ksr; + + /* calculate envelope generator rates */ + if ((SLOT->ARval + SLOT->ksr) < 16+60) + SLOT->delta_ar = SLOT->AR[ SLOT->ksr ]; + else + SLOT->delta_ar = MAX_ATT_INDEX+1; + SLOT->delta_dr = SLOT->DR[ SLOT->ksr ]; + SLOT->delta_rr = SLOT->RR[ SLOT->ksr ]; + } +} + +/* set multi,am,vib,EG-TYP,KSR,mul */ +INLINE void set_mul(FM_OPL *OPL,int slot,int v) +{ + OPL_CH *CH = &OPL->P_CH[slot/2]; + OPL_SLOT *SLOT = &CH->SLOT[slot&1]; + + SLOT->mul = mul_tab[v&0x0f]; + SLOT->KSR = (v&0x10) ? 0 : 2; + SLOT->eg_type = (v&0x20); + SLOT->vib = (v&0x40); + SLOT->AMmask = (v&0x80) ? ~0 : 0; + CALC_FCSLOT(CH,SLOT); +} + +/* set ksl & tl */ +INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v) +{ + OPL_CH *CH = &OPL->P_CH[slot/2]; + OPL_SLOT *SLOT = &CH->SLOT[slot&1]; + int ksl = v>>6; /* 0 / 1.5 / 3.0 / 6.0 dB/OCT */ + + SLOT->ksl = ksl ? 3-ksl : 31; + SLOT->TL = (v&0x3f)<<(ENV_BITS-7); /* 7 bits TL (bit 6 = always 0) */ + + SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); +} + +/* set attack rate & decay rate */ +INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v) +{ + OPL_CH *CH = &OPL->P_CH[slot/2]; + OPL_SLOT *SLOT = &CH->SLOT[slot&1]; + int DRval = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; + + SLOT->ARval = (v>>4) ? 16 + ((v>>4) <<2) : 0; + SLOT->AR = &OPL->eg_tab[ SLOT->ARval ]; + + if ((SLOT->ARval + SLOT->ksr) < 16+60) + SLOT->delta_ar = SLOT->AR[ SLOT->ksr ]; + else + SLOT->delta_ar = MAX_ATT_INDEX+1; + SLOT->DR = &OPL->eg_tab[DRval]; + SLOT->delta_dr = SLOT->DR[ SLOT->ksr ]; +} + +/* set sustain level & release rate */ +INLINE void set_sl_rr(FM_OPL *OPL,int slot,int v) +{ + OPL_CH *CH = &OPL->P_CH[slot/2]; + OPL_SLOT *SLOT = &CH->SLOT[slot&1]; + int RRval = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; + + SLOT->sl = sl_tab[ v>>4 ]; + + SLOT->RR = &OPL->eg_tab[RRval]; + SLOT->delta_rr = SLOT->RR[ SLOT->ksr ]; +} + + +/* write a value v to register r on OPL chip */ +static void OPLWriteReg(FM_OPL *OPL, int r, int v) +{ + OPL_CH *CH; + int slot; + int block_fnum; + + + /* adjust bus to 8 bits */ + r &= 0xff; + v &= 0xff; + +#ifdef LOG_CYM_FILE + if ((cymfile) && (r!=0) ) + { + fputc( (unsigned char)r, cymfile ); + fputc( (unsigned char)v, cymfile ); + } +#endif + + + switch(r&0xe0) + { + case 0x00: /* 00-1f:control */ + switch(r&0x1f) + { + case 0x01: /* waveform select enable */ + if(OPL->type&OPL_TYPE_WAVESEL) + { + OPL->wavesel = v&0x20; + /* do not change the waveform previously selected */ + } + break; + case 0x02: /* Timer 1 */ + OPL->T[0] = (256-v)*4; + break; + case 0x03: /* Timer 2 */ + OPL->T[1] = (256-v)*16; + break; + case 0x04: /* IRQ clear / mask and Timer enable */ + if(v&0x80) + { /* IRQ flag clear */ + OPL_STATUS_RESET(OPL,0x7f); + } + else + { /* set IRQ mask ,timer enable*/ + UINT8 st1 = v&1; + UINT8 st2 = (v>>1)&1; + /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */ + OPL_STATUS_RESET(OPL,v&0x78); + OPL_STATUSMASK_SET(OPL,((~v)&0x78)|0x01); + /* timer 2 */ + if(OPL->st[1] != st2) + { + double interval = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0; + OPL->st[1] = st2; + if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval); + } + /* timer 1 */ + if(OPL->st[0] != st1) + { + double interval = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0; + OPL->st[0] = st1; + if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval); + } + } + break; +#if BUILD_Y8950 + case 0x06: /* Key Board OUT */ + if(OPL->type&OPL_TYPE_KEYBOARD) + { + if(OPL->keyboardhandler_w) + OPL->keyboardhandler_w(OPL->keyboard_param,v); + else + LOG(LOG_WAR,("OPL:write unmapped KEYBOARD port\n")); + } + break; + case 0x07: /* DELTA-T controll : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */ + if(OPL->type&OPL_TYPE_ADPCM) + YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v); + break; + case 0x08: /* MODE,DELTA-T : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */ + OPL->mode = v; + v&=0x1f; /* for DELTA-T unit */ + case 0x09: /* START ADD */ + case 0x0a: + case 0x0b: /* STOP ADD */ + case 0x0c: + case 0x0d: /* PRESCALE */ + case 0x0e: + case 0x0f: /* ADPCM data */ + case 0x10: /* DELTA-N */ + case 0x11: /* DELTA-N */ + case 0x12: /* EG-CTRL */ + if(OPL->type&OPL_TYPE_ADPCM) + YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v); + break; +#if 0 + case 0x15: /* DAC data */ + case 0x16: + case 0x17: /* SHIFT */ + break; + case 0x18: /* I/O CTRL (Direction) */ + if(OPL->type&OPL_TYPE_IO) + OPL->portDirection = v&0x0f; + break; + case 0x19: /* I/O DATA */ + if(OPL->type&OPL_TYPE_IO) + { + OPL->portLatch = v; + if(OPL->porthandler_w) + OPL->porthandler_w(OPL->port_param,v&OPL->portDirection); + } + break; + case 0x1a: /* PCM data */ + break; +#endif +#endif + } + break; + case 0x20: /* am ON, vib ON, ksr, eg_type, mul */ + slot = slot_array[r&0x1f]; + if(slot == -1) return; + set_mul(OPL,slot,v); + break; + case 0x40: + slot = slot_array[r&0x1f]; + if(slot == -1) return; + set_ksl_tl(OPL,slot,v); + break; + case 0x60: + slot = slot_array[r&0x1f]; + if(slot == -1) return; + set_ar_dr(OPL,slot,v); + break; + case 0x80: + slot = slot_array[r&0x1f]; + if(slot == -1) return; + set_sl_rr(OPL,slot,v); + break; + case 0xa0: + if (r == 0xbd) /* am depth, vibrato depth, r,bd,sd,tom,tc,hh */ + { + OPL->lfo_am_depth = v & 0x80; + OPL->lfo_pm_depth_range = (v&0x40) ? 8 : 0; + + OPL->rhythm = v&0x3f; + + if(OPL->rhythm&0x20) + { + /* BD key on/off */ + if(v&0x10) + { + FM_KEYON (&OPL->P_CH[6].SLOT[SLOT1], 2); + FM_KEYON (&OPL->P_CH[6].SLOT[SLOT2], 2); + } + else + { + FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1],~2); + FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2],~2); + } + /* HH key on/off */ + if(v&0x01) FM_KEYON (&OPL->P_CH[7].SLOT[SLOT1], 2); + else FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1],~2); + /* SD key on/off */ + if(v&0x08) FM_KEYON (&OPL->P_CH[7].SLOT[SLOT2], 2); + else FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2],~2); + /* TOM key on/off */ + if(v&0x04) FM_KEYON (&OPL->P_CH[8].SLOT[SLOT1], 2); + else FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1],~2); + /* TOP-CY key on/off */ + if(v&0x02) FM_KEYON (&OPL->P_CH[8].SLOT[SLOT2], 2); + else FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2],~2); + } + else + { + /* BD key off */ + FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1],~2); + FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2],~2); + /* HH key off */ + FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1],~2); + /* SD key off */ + FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2],~2); + /* TOM key off */ + FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1],~2); + /* TOP-CY off */ + FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2],~2); + } + return; + } + /* keyon,block,fnum */ + if( (r&0x0f) > 8) return; + CH = &OPL->P_CH[r&0x0f]; + if(!(r&0x10)) + { /* a0-a8 */ + block_fnum = (CH->block_fnum&0x1f00) | v; + } + else + { /* b0-b8 */ + block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff); + + if(v&0x20) + { + FM_KEYON (&CH->SLOT[SLOT1], 1); + FM_KEYON (&CH->SLOT[SLOT2], 1); + } + else + { + FM_KEYOFF(&CH->SLOT[SLOT1],~1); + FM_KEYOFF(&CH->SLOT[SLOT2],~1); + } + } + /* update */ + if(CH->block_fnum != block_fnum) + { + UINT8 block = block_fnum >> 10; + + CH->block_fnum = block_fnum; + + CH->ksl_base = ksl_tab[block_fnum>>6]; + CH->fc = OPL->fn_tab[block_fnum&0x03ff] >> (7-block); + + /* BLK 2,1,0 bits -> bits 3,2,1 of kcode */ + CH->kcode = (CH->block_fnum&0x1c00)>>9; + + /* the info below is actually opposite to what is stated in the Manuals (verifed on real YM3812) */ + /* if notesel == 0 -> lsb of kcode is bit 10 (MSB) of fnum */ + /* if notesel == 1 -> lsb of kcode is bit 9 (MSB-1) of fnum */ + if (OPL->mode&0x40) + CH->kcode |= (CH->block_fnum&0x100)>>8; /* notesel == 1 */ + else + CH->kcode |= (CH->block_fnum&0x200)>>9; /* notesel == 0 */ + + /* refresh Total Level in both SLOTs of this channel */ + CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); + CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); + + /* refresh frequency counter in both SLOTs of this channel */ + CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); + CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); + } + break; + case 0xc0: + /* FB,C */ + if( (r&0x0f) > 8) return; + CH = &OPL->P_CH[r&0x0f]; + CH->FB = (v>>1)&7 ? ((v>>1)&7) + 7 : 0; + CH->CON = v&1; + CH->connect1 = CH->CON ? &output[0] : &phase_modulation; + break; + case 0xe0: /* waveform select */ + /* simply ignore write to the waveform select register if selecting not enabled in test register */ + if(OPL->wavesel) + { + slot = slot_array[r&0x1f]; + if(slot == -1) return; + CH = &OPL->P_CH[slot/2]; + + CH->SLOT[slot&1].wavetable = &sin_tab[(v&0x03)*SIN_LEN]; + } + break; + } +} + +#ifdef LOG_CYM_FILE +static void cymfile_callback (int n) +{ + if (cymfile) + { + fputc( (unsigned char)0, cymfile ); + } +} +#endif + +/* lock/unlock for common table */ +static int OPL_LockTable(void) +{ + num_lock++; + if(num_lock>1) return 0; + + /* first time */ + + cur_chip = NULL; + /* allocate total level table (128kb space) */ + if( !init_tables() ) + { + num_lock--; + return -1; + } + +#ifdef LOG_CYM_FILE + cymfile = fopen("3812_.cym","wb"); + if (cymfile) + timer_pulse ( TIME_IN_HZ(110), 0, cymfile_callback); /*110 Hz pulse timer*/ + else + logerror("Could not create file 3812_.cym\n"); +#endif + + return 0; +} + +static void OPL_UnLockTable(void) +{ + if(num_lock) num_lock--; + if(num_lock) return; + + /* last time */ + + cur_chip = NULL; + OPLCloseTable(); + +#ifdef LOG_CYM_FILE + fclose (cymfile); + cymfile = NULL; +#endif + +} + +#if (BUILD_YM3812 || BUILD_YM3526) +/*******************************************************************************/ +/* YM3812 local section */ +/*******************************************************************************/ + +/* Generate samples for one of the YM3812's +* +* '*OPL' is pointer to the virtual YM3812 +* '*buffer' is pointer to the sample buffer +* 'length' is the number of samples that should be generated +*/ +void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length) +{ + int i; + OPLSAMPLE *buf = buffer; + UINT8 rhythm = OPL->rhythm&0x20; + + if( (void *)OPL != cur_chip ){ + cur_chip = (void *)OPL; + /* rhythm slots */ + SLOT7_1 = &OPL->P_CH[7].SLOT[SLOT1]; + SLOT7_2 = &OPL->P_CH[7].SLOT[SLOT2]; + SLOT8_1 = &OPL->P_CH[8].SLOT[SLOT1]; + SLOT8_2 = &OPL->P_CH[8].SLOT[SLOT2]; + } + for( i=0; i < length ; i++ ) + { + int lt; + + output[0] = 0; + + advance_lfo(OPL); + + /* FM part */ + OPL_CALC_CH(&OPL->P_CH[0]); + OPL_CALC_CH(&OPL->P_CH[1]); + OPL_CALC_CH(&OPL->P_CH[2]); + OPL_CALC_CH(&OPL->P_CH[3]); + OPL_CALC_CH(&OPL->P_CH[4]); + OPL_CALC_CH(&OPL->P_CH[5]); + + if(!rhythm) + { + OPL_CALC_CH(&OPL->P_CH[6]); + OPL_CALC_CH(&OPL->P_CH[7]); + OPL_CALC_CH(&OPL->P_CH[8]); + } + else /* Rhythm part */ + { + OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>22)&1 ); + } + + lt = output[0]; + + lt >>= FINAL_SH; + + /* limit check */ + lt = limit( lt , MAXOUT, MINOUT ); + + #ifdef SAVE_SAMPLE + SAVE_ALL_CHANNELS + #endif + + /* store to sound buffer */ + buf[i] = lt; + + advance(OPL); + + } + +} +#endif /* (BUILD_YM3812 || BUILD_YM3526) */ + +#if BUILD_Y8950 + +void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length) +{ + int i; + OPLSAMPLE *buf = buffer; + UINT8 rhythm = OPL->rhythm&0x20; + YM_DELTAT *DELTAT = OPL->deltat; + + /* setup DELTA-T unit */ + YM_DELTAT_DECODE_PRESET(DELTAT); + + if( (void *)OPL != cur_chip ){ + cur_chip = (void *)OPL; + /* rhythm slots */ + SLOT7_1 = &OPL->P_CH[7].SLOT[SLOT1]; + SLOT7_2 = &OPL->P_CH[7].SLOT[SLOT2]; + SLOT8_1 = &OPL->P_CH[8].SLOT[SLOT1]; + SLOT8_2 = &OPL->P_CH[8].SLOT[SLOT2]; + + } + for( i=0; i < length ; i++ ) + { + int lt; + + output[0] = 0; + output_deltat[0] = 0; + + advance_lfo(OPL); + + /* deltaT ADPCM */ + if( DELTAT->portstate ) + YM_DELTAT_ADPCM_CALC(DELTAT); + + /* FM part */ + OPL_CALC_CH(&OPL->P_CH[0]); + OPL_CALC_CH(&OPL->P_CH[1]); + OPL_CALC_CH(&OPL->P_CH[2]); + OPL_CALC_CH(&OPL->P_CH[3]); + OPL_CALC_CH(&OPL->P_CH[4]); + OPL_CALC_CH(&OPL->P_CH[5]); + + if(!rhythm) + { + OPL_CALC_CH(&OPL->P_CH[6]); + OPL_CALC_CH(&OPL->P_CH[7]); + OPL_CALC_CH(&OPL->P_CH[8]); + } + else /* Rhythm part */ + { + OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>22)&1 ); + } + + lt = output[0] + (output_deltat[0]>>11); + + lt >>= FINAL_SH; + + /* limit check */ + lt = limit( lt , MAXOUT, MINOUT ); + + #ifdef SAVE_SAMPLE + SAVE_ALL_CHANNELS + #endif + + /* store to sound buffer */ + buf[i] = lt; + + advance(OPL); + } + + /* deltaT START flag */ + if( !DELTAT->portstate ) + OPL->status &= 0xfe; + + if( DELTAT->eos ) //AT: set bit 4 of OPL status register on EOS + { + DELTAT->eos = 0; + OPL->status |= 0x10; + } +} +#endif + + +void OPLResetChip(FM_OPL *OPL) +{ + int c,s; + int i; + + OPL->noise_rng = 1; /* noise shift register */ + OPL->mode = 0; /* normal mode */ + OPL_STATUS_RESET(OPL,0x7f); + + /* reset with register write */ + OPLWriteReg(OPL,0x01,0); /* wavesel disable */ + OPLWriteReg(OPL,0x02,0); /* Timer1 */ + OPLWriteReg(OPL,0x03,0); /* Timer2 */ + OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */ + for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0); + + /* reset operator parameters */ + for( c = 0 ; c < 9 ; c++ ) + { + OPL_CH *CH = &OPL->P_CH[c]; + for(s = 0 ; s < 2 ; s++ ) + { + /* wave table */ + CH->SLOT[s].wavetable = &sin_tab[0]; + CH->SLOT[s].state = EG_OFF; + CH->SLOT[s].volume = MAX_ATT_INDEX; + } + } +#if BUILD_Y8950 + if(OPL->type&OPL_TYPE_ADPCM) + { + YM_DELTAT *DELTAT = OPL->deltat; + + DELTAT->freqbase = OPL->freqbase; + DELTAT->output_pointer = &output_deltat[0]; + DELTAT->portshift = 5; + DELTAT->output_range = 1<<23; + YM_DELTAT_ADPCM_Reset(DELTAT,0); + } +#endif +} + +/* Create one of virtual YM3812 */ +/* 'clock' is chip clock in Hz */ +/* 'rate' is sampling rate */ +FM_OPL *OPLCreate(int type, int clock, int rate) +{ + union { + char *ptr; + void *ptr_void; + }; + FM_OPL *OPL; + int state_size; + + if (OPL_LockTable() ==-1) return NULL; + + /* calculate OPL state size */ + state_size = sizeof(FM_OPL); + +#if BUILD_Y8950 + if (type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT); +#endif + + /* allocate memory block */ + ptr_void = malloc(state_size); + + if (ptr==NULL) + return NULL; + + /* clear */ + memset(ptr,0,state_size); + + OPL = (FM_OPL *)ptr; + + ptr += sizeof(FM_OPL); + +#if BUILD_Y8950 + if (type&OPL_TYPE_ADPCM) + OPL->deltat = (YM_DELTAT *)ptr; + ptr += sizeof(YM_DELTAT); +#endif + + OPL->type = type; + OPL->clock = clock; + OPL->rate = rate; + + /* init global tables */ + OPL_initalize(OPL); + + /* reset chip */ + OPLResetChip(OPL); + return OPL; +} + +/* Destroy one of virtual YM3812 */ +void OPLDestroy(FM_OPL *OPL) +{ + OPL_UnLockTable(); + free(OPL); +} + +/* Option handlers */ + +void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset) +{ + OPL->TimerHandler = TimerHandler; + OPL->TimerParam = channelOffset; +} +void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param) +{ + OPL->IRQHandler = IRQHandler; + OPL->IRQParam = param; +} +void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param) +{ + OPL->UpdateHandler = UpdateHandler; + OPL->UpdateParam = param; +} + +#if BUILD_Y8950 +void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param) +{ + OPL->porthandler_w = PortHandler_w; + OPL->porthandler_r = PortHandler_r; + OPL->port_param = param; +} + +void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param) +{ + OPL->keyboardhandler_w = KeyboardHandler_w; + OPL->keyboardhandler_r = KeyboardHandler_r; + OPL->keyboard_param = param; +} +#endif + +/* YM3812 I/O interface */ +int OPLWrite(FM_OPL *OPL,int a,int v) +{ + if( !(a&1) ) + { /* address port */ + OPL->address = v & 0xff; + } + else + { /* data port */ + if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); + OPLWriteReg(OPL,OPL->address,v); + } + return OPL->status>>7; +} + +unsigned char OPLRead(FM_OPL *OPL,int a) +{ + if( !(a&1) ) + { + /* YM3812 returns 0x06 (bit2 and bit1 are HIGH) */ + + /* status port */ + return OPL->status & (OPL->statusmask|0x80); + } + +#if BUILD_Y8950 + /* data port */ + switch(OPL->address) + { + case 0x05: /* KeyBoard IN */ + if(OPL->type&OPL_TYPE_KEYBOARD) + { + if(OPL->keyboardhandler_r) + return OPL->keyboardhandler_r(OPL->keyboard_param); + else + LOG(LOG_WAR,("OPL:read unmapped KEYBOARD port\n")); + } + return 0; +#if 0 + case 0x0f: /* ADPCM-DATA */ + return 0; +#endif + case 0x19: /* I/O DATA */ + if(OPL->type&OPL_TYPE_IO) + { + if(OPL->porthandler_r) + return OPL->porthandler_r(OPL->port_param); + else + LOG(LOG_WAR,("OPL:read unmapped I/O port\n")); + } + return 0; + case 0x1a: /* PCM-DATA */ + return 0; + } +#endif + + return 0xff; +} + +/* CSM Key Controll */ +INLINE void CSMKeyControll(OPL_CH *CH) +{ + FM_KEYON (&CH->SLOT[SLOT1], 4); + FM_KEYON (&CH->SLOT[SLOT2], 4); + + /* The key off should happen exactly one sample later - not implemented correctly yet */ + + FM_KEYOFF(&CH->SLOT[SLOT1], ~4); + FM_KEYOFF(&CH->SLOT[SLOT2], ~4); +} + + +int OPLTimerOver(FM_OPL *OPL,int c) +{ + if( c ) + { /* Timer B */ + OPL_STATUS_SET(OPL,0x20); + } + else + { /* Timer A */ + OPL_STATUS_SET(OPL,0x40); + /* CSM mode key,TL controll */ + if( OPL->mode & 0x80 ) + { /* CSM mode total level latch and auto key on */ + int ch; + if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); + for(ch=0; ch<9; ch++) + CSMKeyControll( &OPL->P_CH[ch] ); + } + } + /* reload timer */ + if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase); + return OPL->status>>7; +} diff --git a/src/hardware/fmopl.h b/src/hardware/fmopl.h new file mode 100644 index 00000000..46c5c15e --- /dev/null +++ b/src/hardware/fmopl.h @@ -0,0 +1,191 @@ +#ifndef __FMOPL_H_ +#define __FMOPL_H_ + +/* --- select emulation chips --- */ +#define BUILD_YM3812 (HAS_YM3812) +#define BUILD_YM3526 (HAS_YM3526) +#define BUILD_Y8950 (HAS_Y8950) + +/* --- system optimize --- */ +/* select bit size of output : 8 or 16 */ +#define OPL_SAMPLE_BITS 16 + +/* compiler dependence */ +#ifndef OSD_CPU_H +#define OSD_CPU_H +typedef unsigned char UINT8; /* unsigned 8bit */ +typedef unsigned short UINT16; /* unsigned 16bit */ +typedef unsigned int UINT32; /* unsigned 32bit */ +typedef signed char INT8; /* signed 8bit */ +typedef signed short INT16; /* signed 16bit */ +typedef signed int INT32; /* signed 32bit */ +#endif + +#if (OPL_SAMPLE_BITS==16) +typedef INT16 OPLSAMPLE; +#endif +#if (OPL_SAMPLE_BITS==8) +typedef unsigned char OPLSAMPLE; +#endif + + +#if BUILD_Y8950 +#include "ymdeltat.h" +#endif + +typedef void (*OPL_TIMERHANDLER)(int channel,double interval_Sec); +typedef void (*OPL_IRQHANDLER)(int param,int irq); +typedef void (*OPL_UPDATEHANDLER)(int param,int min_interval_us); +typedef void (*OPL_PORTHANDLER_W)(int param,unsigned char data); +typedef unsigned char (*OPL_PORTHANDLER_R)(int param); + +/* !!!!! here is private section , do not access there member direct !!!!! */ + +#define OPL_TYPE_WAVESEL 0x01 /* waveform select */ +#define OPL_TYPE_ADPCM 0x02 /* DELTA-T ADPCM unit */ +#define OPL_TYPE_KEYBOARD 0x04 /* keyboard interface */ +#define OPL_TYPE_IO 0x08 /* I/O port */ + +/* Saving is necessary for member of the 'R' mark for suspend/resume */ +/* ---------- OPL slot ---------- */ +typedef struct fm_opl_slot { + const UINT32 *AR; /* attack rate tab :&eg_table[AR<<2]*/ + const UINT32 *DR; /* decay rate tab :&eg_table[DR<<2]*/ + const UINT32 *RR; /* release rate tab:&eg_table[RR<<2]*/ + UINT8 KSR; /* key scale rate */ + UINT8 ARval; /* current AR */ + UINT8 ksl; /* keyscale level */ + UINT8 ksr; /* key scale rate :kcode>>KSR */ + UINT8 mul; /* multiple :ML_TABLE[ML] */ + + /* Phase Generator */ + UINT32 Cnt; /* frequency count */ + UINT32 Incr; /* frequency step */ + + /* Envelope Generator */ + UINT8 eg_type; /* percussive/non-percussive mode */ + UINT8 state; /* phase type */ + UINT32 TL; /* total level :TL << 3 */ + INT32 TLL; /* adjusted now TL */ + INT32 volume; /* envelope counter */ + UINT32 sl; /* sustain level :SL_TABLE[SL] */ + UINT32 delta_ar; /* envelope step for Attack */ + UINT32 delta_dr; /* envelope step for Decay */ + UINT32 delta_rr; /* envelope step for Release */ + + UINT32 key; /* 0 = KEY OFF, >0 = KEY ON */ + + /* LFO */ + UINT32 AMmask; /* LFO Amplitude Modulation enable mask */ + UINT8 vib; /* LFO Phase Modulation enable flag (active high)*/ + + /* waveform select */ + unsigned int *wavetable; +}OPL_SLOT; + +/* ---------- OPL one of channel ---------- */ +typedef struct fm_opl_channel { + OPL_SLOT SLOT[2]; + UINT8 FB; /* feedback shift value */ + INT32 *connect1; /* slot1 output pointer */ + INT32 op1_out[2]; /* slot1 output for feedback */ + + /* phase generator state */ + UINT32 block_fnum; /* block+fnum */ + UINT32 fc; /* Freq. Increment base */ + UINT32 ksl_base; /* KeyScaleLevel Base step */ + UINT8 kcode; /* key code (for key scaling) */ + + UINT8 CON; /* connection (algorithm) type */ +} OPL_CH; + +/* OPL state */ +typedef struct fm_opl_f { + /* FM channel slots */ + OPL_CH P_CH[9]; /* OPL/OPL2 chips have 9 channels */ + + UINT8 rhythm; /* Rhythm mode */ + + UINT32 eg_tab[16+64+16]; /* EG rate table: 16 (dummy) + 64 rates + 16 RKS */ + UINT32 fn_tab[1024]; /* fnumber -> increment counter */ + + /* LFO */ + UINT8 lfo_am_depth; + UINT8 lfo_pm_depth_range; + UINT32 lfo_am_cnt; + UINT32 lfo_am_inc; + UINT32 lfo_pm_cnt; + UINT32 lfo_pm_inc; + + UINT32 noise_rng; /* 23 bit noise shift register */ + UINT32 noise_p; /* current noise 'phase' */ + UINT32 noise_f; /* current noise period */ + + UINT8 wavesel; /* waveform select enable flag */ + + int T[2]; /* timer counters */ + UINT8 st[2]; /* timer enable */ + +#if BUILD_Y8950 + /* Delta-T ADPCM unit (Y8950) */ + + YM_DELTAT *deltat; + + /* Keyboard / I/O interface unit*/ + UINT8 portDirection; + UINT8 portLatch; + OPL_PORTHANDLER_R porthandler_r; + OPL_PORTHANDLER_W porthandler_w; + int port_param; + OPL_PORTHANDLER_R keyboardhandler_r; + OPL_PORTHANDLER_W keyboardhandler_w; + int keyboard_param; +#endif + + /* external event callback handlers */ + OPL_TIMERHANDLER TimerHandler; /* TIMER handler */ + int TimerParam; /* TIMER parameter */ + OPL_IRQHANDLER IRQHandler; /* IRQ handler */ + int IRQParam; /* IRQ parameter */ + OPL_UPDATEHANDLER UpdateHandler; /* stream update handler */ + int UpdateParam; /* stream update parameter */ + + UINT8 type; /* chip type */ + UINT8 address; /* address register */ + UINT8 status; /* status flag */ + UINT8 statusmask; /* status mask */ + UINT8 mode; /* Reg.08 : CSM,notesel,etc. */ + + int clock; /* master clock (Hz) */ + int rate; /* sampling rate (Hz) */ + double freqbase; /* frequency base */ + double TimerBase; /* Timer base time (==sampling time)*/ +} FM_OPL; + + +/* ---------- Generic interface section ---------- */ +#define OPL_TYPE_YM3526 (0) +#define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL) +#define OPL_TYPE_Y8950 (OPL_TYPE_ADPCM|OPL_TYPE_KEYBOARD|OPL_TYPE_IO) + +FM_OPL *OPLCreate(int type, int clock, int rate); +void OPLDestroy(FM_OPL *OPL); +void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset); +void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param); +void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param); +/* Y8950 port handlers */ +void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param); +void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param); + +void OPLResetChip(FM_OPL *OPL); +int OPLWrite(FM_OPL *OPL,int a,int v); +unsigned char OPLRead(FM_OPL *OPL,int a); +int OPLTimerOver(FM_OPL *OPL,int c); + + +/* YM3626/YM3812 local section */ +void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length); + +void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length); + +#endif diff --git a/src/hardware/font-switch.h b/src/hardware/font-switch.h new file mode 100644 index 00000000..80a3adfd --- /dev/null +++ b/src/hardware/font-switch.h @@ -0,0 +1,2562 @@ +switch (bit_mask) { + case 0: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 1: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 2: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 3: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 4: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 5: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 6: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 7: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 8: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 9: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 10: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 11: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 12: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 13: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 14: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 15: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 16: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 17: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 18: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 19: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 20: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 21: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 22: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 23: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 24: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 25: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 26: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 27: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 28: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 29: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 30: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 31: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 32: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 33: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 34: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 35: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 36: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 37: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 38: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 39: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 40: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 41: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 42: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 43: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 44: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 45: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 46: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 47: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 48: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 49: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 50: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 51: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 52: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 53: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 54: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 55: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 56: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 57: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 58: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 59: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 60: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 61: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 62: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 63: + *(draw+0)=bg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 64: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 65: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 66: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 67: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 68: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 69: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 70: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 71: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 72: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 73: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 74: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 75: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 76: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 77: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 78: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 79: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 80: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 81: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 82: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 83: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 84: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 85: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 86: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 87: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 88: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 89: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 90: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 91: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 92: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 93: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 94: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 95: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 96: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 97: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 98: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 99: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 100: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 101: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 102: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 103: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 104: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 105: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 106: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 107: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 108: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 109: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 110: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 111: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 112: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 113: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 114: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 115: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 116: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 117: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 118: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 119: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 120: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 121: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 122: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 123: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 124: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 125: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 126: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 127: + *(draw+0)=bg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 128: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 129: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 130: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 131: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 132: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 133: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 134: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 135: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 136: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 137: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 138: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 139: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 140: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 141: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 142: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 143: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 144: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 145: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 146: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 147: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 148: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 149: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 150: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 151: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 152: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 153: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 154: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 155: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 156: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 157: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 158: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 159: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 160: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 161: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 162: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 163: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 164: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 165: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 166: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 167: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 168: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 169: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 170: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 171: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 172: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 173: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 174: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 175: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 176: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 177: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 178: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 179: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 180: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 181: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 182: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 183: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 184: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 185: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 186: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 187: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 188: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 189: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 190: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 191: + *(draw+0)=fg; + *(draw+1)=bg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 192: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 193: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 194: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 195: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 196: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 197: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 198: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 199: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 200: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 201: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 202: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 203: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 204: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 205: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 206: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 207: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 208: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 209: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 210: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 211: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 212: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 213: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 214: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 215: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 216: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 217: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 218: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 219: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 220: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 221: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 222: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 223: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=bg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 224: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 225: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 226: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 227: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 228: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 229: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 230: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 231: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 232: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 233: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 234: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 235: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 236: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 237: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 238: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 239: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=bg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 240: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 241: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 242: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 243: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 244: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 245: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 246: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 247: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=bg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 248: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 249: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 250: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 251: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=bg; + *(draw+6)=fg; + *(draw+7)=fg; + break; + case 252: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=bg; + break; + case 253: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=bg; + *(draw+7)=fg; + break; + case 254: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=bg; + break; + case 255: + *(draw+0)=fg; + *(draw+1)=fg; + *(draw+2)=fg; + *(draw+3)=fg; + *(draw+4)=fg; + *(draw+5)=fg; + *(draw+6)=fg; + *(draw+7)=fg; + break; +} diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp new file mode 100644 index 00000000..bcddec06 --- /dev/null +++ b/src/hardware/gameblaster.cpp @@ -0,0 +1,256 @@ +/* + * 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. + */ + +#include +#include "dosbox.h" +#include "inout.h" +#include "mixer.h" +#include "mem.h" +#include "hardware.h" + +#define CMS_RATE 22050 +#define CMS_VOLUME 6000 + + +#define FREQ_SHIFT 16 + +#define SIN_ENT 1024 +#define SIN_MAX (SIN_ENT << FREQ_SHIFT) + +#ifndef PI +#define PI 3.14159265358979323846 +#endif + + + +struct CMS { + struct { + Bit32u freq_pos; + Bit32u freq_add; + Bit16s * vol_left; + Bit16s * vol_right; + Bit8u octave; + Bit8u freq; + } chan[6]; + struct { + Bit32u freq_pos; + Bit32u freq_add; + Bit32u random_val; + } noise[2]; + + Bit8u voice_enabled; + Bit8u noise_enabled; + Bit8u reg; +}; + +static Bit32u freq_table[256][8]; +static Bit32u noise_freq[3]; +static Bit16s vol_table[16]; +static Bit16s sin_table[16][SIN_ENT]; + +static MIXER_Channel * cms_chan; +static CMS cms_block[2]; + +static void write_cms(Bit32u port,Bit8u val) { + Bit32u sel=(port>>1)&1; + CMS * cms=&cms_block[sel]; + switch (port & 1) { + case 1: /* Register Select */ + cms->reg=val; + break; + case 0: /* Write Register */ + switch (cms->reg) { + case 0x00: case 0x01: case 0x02: /* Volume Select */ + case 0x03: case 0x04: case 0x05: + cms->chan[cms->reg].vol_left=sin_table[val & 0xf]; + cms->chan[cms->reg].vol_right=sin_table[(val>>4) & 0xf]; + break; + case 0x08: case 0x09: case 0x0a: /* Frequency Select */ + case 0x0b: case 0x0c: case 0x0d: + { + Bit8u chan=cms->reg-0x08; + cms->chan[chan].freq=val; + /* Get a new entry in the freq table */ + cms->chan[chan].freq_add=freq_table[cms->chan[chan].freq][cms->chan[chan].octave]; + break; + } + case 0x10: case 0x11: case 0x12: /* Octave Select */ + { + Bit8u chan=(cms->reg-0x10)*2; + cms->chan[chan].octave=val&7; + cms->chan[chan].freq_add=freq_table[cms->chan[chan].freq][cms->chan[chan].octave]; + chan++; + cms->chan[chan].octave=(val>>4)&7; + cms->chan[chan].freq_add=freq_table[cms->chan[chan].freq][cms->chan[chan].octave]; + } + break; + case 0x14: /* Frequency enable */ + cms->voice_enabled=val; + //TODO Check for enabling of speaker maybe + break; + case 0x15: /* Noise Enable */ + cms->noise_enabled=val; + //TODO Check for enabling of speaker maybe + break; + case 0x16: /* Noise generator setup */ + cms->noise[0].freq_add=noise_freq[val & 3]; + cms->noise[1].freq_add=noise_freq[(val>>4) & 3]; + break; + default: + LOG_ERROR("CMS %d:Illegal register %X2 Selected for write",sel,cms->reg); + break; + }; + break; + } + +}; + +static void CMS_CallBack(Bit8u * stream,Bit32u len) { + /* Generate the CMS wave */ + /* Generate 12 channels of sound data this could be nice */ + for (Bit32u l=0;lnoise_enabled & use_voice) { + + } else if (cms->voice_enabled & use_voice) { + int pos=cms->chan[chan].freq_pos>>FREQ_SHIFT; + left+=cms->chan[chan].vol_left[pos]; + right+=cms->chan[chan].vol_right[pos]; + cms->chan[chan].freq_pos+=cms->chan[chan].freq_add; + if (cms->chan[chan].freq_pos>=SIN_MAX) + cms->chan[chan].freq_pos-=SIN_MAX; + } + use_voice<<=1; + } + } + if (left>MAX_AUDIO) *(Bit16s *)stream=MAX_AUDIO; + else if (leftMAX_AUDIO) *(Bit16s *)stream=MAX_AUDIO; + else if (right=0;i--) { + sin_table[i][s]=(Bit16s)out; +// out /= (float)1.258925412; /* = 10 ^ (2/20) = 2dB */ + out /= 1.1; + } + } + + +} + diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp new file mode 100644 index 00000000..ed738203 --- /dev/null +++ b/src/hardware/hardware.cpp @@ -0,0 +1,117 @@ +/* + * 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. + */ + +/* + This could do with a serious revision :) +*/ + +#include +#include "dosbox.h" +#include "programs.h" +#include "hardware.h" + +static HWBlock * firsthw=0; + + +class HWSET : public Program { +public: + HWSET(PROGRAM_Info * program_info); + void Run(void); + +}; + + +HWSET::HWSET(PROGRAM_Info * info):Program(info) { + +} + +void HW_Register(HWBlock * block) { + block->next=firsthw; + firsthw=block; +} + + +void HWSET::Run(void) { + /* Hopefull enough space */ + char buf[1024]; + + HWBlock * loopblock; + if (!*prog_info->cmd_line) { + /* No command line given give overview of hardware */ + loopblock=firsthw; + WriteOut("ÚÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿"); + WriteOut("³Device ³Full Name ³Status ³"); + WriteOut("ÃÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´"); + while (loopblock) { + if (loopblock->show_status) { + loopblock->show_status(buf); + } else { + strcpy(buf,"No Status Handler"); + } + WriteOut("³%-8s³%-25s³%-43s³",loopblock->dev_name,loopblock->full_name,buf); + loopblock=loopblock->next; + } + WriteOut("ÀÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ"); + WriteOut("If you want to setup specific hardware use \"HWSET Device\" for information.\n"); + return; + } + /* Command line given */ + if (strcmp(prog_info->cmd_line,"/?")==0) { + WriteOut("Hardware setup tool for DOSBox.\n"); + WriteOut("This program can be used to change the settings of internal hardware.\n\n" + "HWSET [device] [switches]\n\n" + "Using an empty command line gives you a list of hardware.\n" + "You can get list of switches for a device with HWSET device.\n" + ); + return; + } + char * rest=strchr(prog_info->cmd_line,' '); + if (rest) *rest++=0; + loopblock=firsthw; + while (loopblock) { + if (strcasecmp(loopblock->dev_name,prog_info->cmd_line)==0) goto founddev; + loopblock=loopblock->next; + } + WriteOut("Device %s not found\n",prog_info->cmd_line); + return; +founddev: +/* Check for rest of line */ + if (rest) { + strcpy(buf,rest); + loopblock->get_input(buf); + WriteOut(buf); + + } else { + WriteOut("Command overview for %s\n%s",loopblock->full_name,loopblock->help); + } + return; +} + +static void HWSET_ProgramStart(PROGRAM_Info * info) { + HWSET * tempHWSET=new HWSET(info); + tempHWSET->Run(); + delete tempHWSET; +} + + + +void HARDWARE_Init(void) { + PROGRAMS_MakeFile("HWSET.COM",HWSET_ProgramStart); + +}; + diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp new file mode 100644 index 00000000..242f6f0b --- /dev/null +++ b/src/hardware/iohandler.cpp @@ -0,0 +1,91 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "inout.h" + +IO_ReadBlock IO_ReadTable[IO_MAX]; +IO_WriteBlock IO_WriteTable[IO_MAX]; + +void IO_Write(Bitu num,Bit8u val) { + if (num +#include "dosbox.h" +#include "keyboard.h" +#include "inout.h" +#include "pic.h" +#include "mixer.h" + + +#define KEYBUFSIZE 32 + + +struct KeyEvent { + Bitu type; + Bitu state; + KEYBOARD_EventHandler * handler; + KeyEvent * next; +}; + +static Bitu shift_state=0; +static Bit8u cur_scancode; +static Bit8u kbuf[KEYBUFSIZE]; +static Bitu kbuf_pos; +static Bitu kbuf_used; +static Bit8u port_61_data; +//TODO Are these initialized at 0 at startup? Hope so :) +static KeyEvent * event_handlers[KBD_LAST]; + + +static Bit8u read_p60(Bit32u port) { + if (kbuf_used>0) { + cur_scancode=kbuf[kbuf_pos]; + }; + return cur_scancode; +} + +static void write_p60(Bit32u port,Bit8u val) { +//TODO Work this out ;) + LOG_DEBUG("Port 60 write with val %d",val); +} + +static Bit8u read_p61(Bit32u port) { + return port_61_data; +}; + +static void write_p61(Bit32u port,Bit8u val) { +//TODO Enable spreaker through here :) + if ((val&128)) { /* Keyboard acknowledge */ + kbuf_used--; + kbuf_pos++; + if (kbuf_pos>=KEYBUFSIZE) kbuf_pos=0; + if (kbuf_used>0) PIC_ActivateIRQ(1); + } + port_61_data=val; + if ((val & 3)==3) { + PCSPEAKER_Enable(true); + } else { + PCSPEAKER_Enable(false); + } +} + + + +void KEYBOARD_AddCode(Bit8u code) { + //Now Raise the keyboard IRQ + //If the buffer is full just drop the scancode :) + if (kbuf_used=KEYBUFSIZE) start-=KEYBUFSIZE; + kbuf[start]=code; + } + PIC_ActivateIRQ(1); +} + + +void KEYBOARD_AddEvent(Bitu keytype,Bitu state,KEYBOARD_EventHandler * handler) { + KeyEvent * newevent=new KeyEvent; +/* Add the event in the correct key structure */ + if (keytype>=KBD_LAST) { + LOG_ERROR("KEYBOARD:Illegal key %d for handler",keytype); + } + newevent->next=event_handlers[keytype]; + event_handlers[keytype]=newevent; + newevent->type=keytype; + newevent->state=state; + newevent->handler=handler; + + +}; + +void KEYBOARD_AddKey(Bitu keytype,bool pressed) { + bool extend=false; + Bit8u ret=0; + switch (keytype) { + case KBD_esc:ret=1;break; + case KBD_1:ret=2;break; + case KBD_2:ret=3;break; + case KBD_3:ret=4;break; + case KBD_4:ret=5;break; + case KBD_5:ret=6;break; + case KBD_6:ret=7;break; + case KBD_7:ret=8;break; + case KBD_8:ret=9;break; + case KBD_9:ret=10;break; + case KBD_0:ret=11;break; + + case KBD_minus:ret=12;break; + case KBD_equals:ret=13;break; + case KBD_backspace:ret=14;break; + case KBD_tab:ret=15;break; + + case KBD_q:ret=16;break; + case KBD_w:ret=17;break; + case KBD_e:ret=18;break; + case KBD_r:ret=19;break; + case KBD_t:ret=20;break; + case KBD_y:ret=21;break; + case KBD_u:ret=22;break; + case KBD_i:ret=23;break; + case KBD_o:ret=24;break; + case KBD_p:ret=25;break; + + case KBD_leftbracket:ret=26;break; + case KBD_rightbracket:ret=27;break; + case KBD_enter:ret=28;break; + case KBD_leftctrl:ret=29; + shift_state=(shift_state&~CTRL_PRESSED)|(pressed ? CTRL_PRESSED:0); + break; + + case KBD_a:ret=30;break; + case KBD_s:ret=31;break; + case KBD_d:ret=32;break; + case KBD_f:ret=33;break; + case KBD_g:ret=34;break; + case KBD_h:ret=35;break; + case KBD_j:ret=36;break; + case KBD_k:ret=37;break; + case KBD_l:ret=38;break; + + case KBD_semicolon:ret=39;break; + case KBD_quote:ret=40;break; + case KBD_grave:ret=41;break; + case KBD_leftshift:ret=42; + shift_state=(shift_state&~SHIFT_PRESSED)|(pressed ? SHIFT_PRESSED:0); + break; + case KBD_backslash:ret=43;break; + case KBD_z:ret=44;break; + case KBD_x:ret=45;break; + case KBD_c:ret=46;break; + case KBD_v:ret=47;break; + case KBD_b:ret=48;break; + case KBD_n:ret=49;break; + case KBD_m:ret=50;break; + + case KBD_comma:ret=51;break; + case KBD_period:ret=52;break; + case KBD_slash:ret=53;break; + case KBD_rightshift:ret=54;break; + case KBD_kpmultiply:ret=55;break; + case KBD_leftalt:ret=56; + shift_state=(shift_state&~ALT_PRESSED)|(pressed ? ALT_PRESSED:0); + break; + case KBD_space:ret=57;break; + case KBD_capslock:ret=58;break; + + case KBD_f1:ret=59;break; + case KBD_f2:ret=60;break; + case KBD_f3:ret=61;break; + case KBD_f4:ret=62;break; + case KBD_f5:ret=63;break; + case KBD_f6:ret=64;break; + case KBD_f7:ret=65;break; + case KBD_f8:ret=66;break; + case KBD_f9:ret=67;break; + case KBD_f10:ret=68;break; + + case KBD_numlock:ret=69;break; + case KBD_scrolllock:ret=70;break; + + case KBD_kp7:ret=71;break; + case KBD_kp8:ret=72;break; + case KBD_kp9:ret=73;break; + case KBD_kpminus:ret=74;break; + case KBD_kp4:ret=75;break; + case KBD_kp5:ret=76;break; + case KBD_kp6:ret=77;break; + case KBD_kpplus:ret=78;break; + case KBD_kp1:ret=79;break; + case KBD_kp2:ret=80;break; + case KBD_kp3:ret=81;break; + case KBD_kp0:ret=82;break; + case KBD_kpperiod:ret=83;break; + + case KBD_f11:ret=87;break; + case KBD_f12:ret=88;break; + + //The Extended keys + + case KBD_kpenter:extend=true;ret=28;break; + case KBD_rightctrl:extend=true;ret=29;break; + case KBD_kpslash:extend=true;ret=53;break; + case KBD_rightalt:extend=true;ret=56;break; + case KBD_home:extend=true;ret=71;break; + case KBD_up:extend=true;ret=72;break; + case KBD_pageup:extend=true;ret=73;break; + case KBD_left:extend=true;ret=75;break; + case KBD_right:extend=true;ret=77;break; + case KBD_end:extend=true;ret=79;break; + case KBD_down:extend=true;ret=80;break; + case KBD_pagedown:extend=true;ret=81;break; + case KBD_insert:extend=true;ret=82;break; + case KBD_delete:extend=true;ret=83;break; + default: + E_Exit("Unsopperted key press"); + break; + }; + /* check for active key events */ + KeyEvent * checkevent=event_handlers[keytype]; + while (checkevent) { + if ((shift_state & checkevent->state)==checkevent->state) { + if (checkevent->type==keytype && pressed) { + (*checkevent->handler)(); + return; + } + if (checkevent->type==keytype) return; + } + checkevent=checkevent->next; + } + if (extend) KEYBOARD_AddCode(224); + if (!pressed) ret+=128; + KEYBOARD_AddCode(ret); +}; + +void KEYBOARD_Init(void) { + kbuf_used=0;kbuf_pos=0; + IO_RegisterWriteHandler(0x60,write_p60,"Keyboard"); + IO_RegisterReadHandler(0x60,read_p60,"Keyboard"); + IO_RegisterWriteHandler(0x61,write_p61,"Keyboard"); + IO_RegisterReadHandler(0x61,read_p61,"Keyboard"); + port_61_data=1; /* Speaker control through PIT and speaker disabled */ +// memset(&event_handlers,0,sizeof(event_handlers)); +}; diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp new file mode 100644 index 00000000..edbc1686 --- /dev/null +++ b/src/hardware/memory.cpp @@ -0,0 +1,299 @@ +/* + * 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. + */ +#include +#include +#include +#include "dosbox.h" +#include "mem.h" + +#define MEM_MAXSIZE 16 /* The Size of memory used to get size of page table */ +#define memsize 8 /* 8 mb of memory */ +#define EMM_HANDLECOUNT 250 + +EMM_Handle EMM_Handles[EMM_HANDLECOUNT]; +PageEntry * PageEntries[MEM_MAXSIZE*1024*16]; /* Number of pages */ +Bit8u * memory=0; + +bool MEMORY_TestSpecial(PhysPt off) { + return (PageEntries[off >> 12]>0); +} + +void MEMORY_SetupHandler(Bit32u page,Bit32u pages,PageEntry * entry) { + for (Bit32u i=page;i>2);c++) { + writed(idata,mem_readd(off)); + idata+=4;off+=4; + } + for (c=1;c<=(size&3);c++) { + writeb(idata,mem_readb(off)); + idata+=1;off+=1; + } +} + +void MEM_BlockWrite(PhysPt off,void * data,Bitu size) { + Bitu c; + Bit8u * idata=(Bit8u *)data; + for (c=1;c<=(size>>2);c++) { + mem_writed(off,readd(idata)); + idata+=4;off+=4; + } + for (c=1;c<=(size&3);c++) { + mem_writeb(off,readb(idata)); + idata+=1;off+=1; + } +} + +void MEM_BlockCopy(PhysPt dest,PhysPt src,Bitu size) { + Bitu c; + for (c=1;c<=(size>>2);c++) { + mem_writed(dest,mem_readd(src)); + dest+=4;src+=4; + } + for (c=1;c<=(size&3);c++) { + mem_writeb(dest,mem_readb(src)); + dest+=1;src+=1; + } + + +}; + +void MEM_StrCopy(PhysPt off,char * data,Bitu size) { + Bit8u c; + while ((c=mem_readb(off)) && size) { + *data=c; + off++;data++;size--; + } + *data='\0'; +} + + + + +/* TODO Maybe check for page boundaries but that would be wasting lot's of time */ +void mem_writeb(PhysPt off,Bit8u val) { + PageEntry * entry=PageEntries[off >> 12]; + if (!entry) { writeb(memory+off,val);return; } + switch (entry->type) { + case MEMORY_RELOCATE: + writeb(entry->relocate+(off-entry->base),val); + break; + case MEMORY_HANDLER: + entry->handler.write(off-entry->base,val); + break; + default: + E_Exit("Write to Illegal Memory Address %4x",off); + } +} + +void mem_writew(PhysPt off,Bit16u val) { + PageEntry * entry=PageEntries[off >> 12]; + if (!entry) { writew(memory+off,val);return; } + switch (entry->type) { + case MEMORY_RELOCATE: + writew(entry->relocate+(off-entry->base),val); + break; + case MEMORY_HANDLER: + entry->handler.write(off-entry->base,(val & 0xFF)); + entry->handler.write(off-entry->base+1,(val >> 8)); + break; + default: + E_Exit("Write to Illegal Memory Address %4x",off); + } +} + +void mem_writed(PhysPt off,Bit32u val) { + PageEntry * entry=PageEntries[off >> 12]; + if (!entry) { writed(memory+off,val);return; } + switch (entry->type) { + case MEMORY_RELOCATE: + writed(entry->relocate+(off-entry->base),val); + break; + case MEMORY_HANDLER: + entry->handler.write(off-entry->base, (Bit8u)(val & 0xFF)); + entry->handler.write(off-entry->base+1,(Bit8u)(val >> 8) & 0xFF); + entry->handler.write(off-entry->base+2,(Bit8u)(val >> 16) & 0xFF); + entry->handler.write(off-entry->base+3,(Bit8u)(val >> 24) & 0xFF); + break; + default: + E_Exit("Write to Illegal Memory Address %4x",off); + } +} + +Bit8u mem_readb(PhysPt off) { + PageEntry * entry=PageEntries[off >> 12]; + if (!entry) { return readb(memory+off);} + switch (entry->type) { + case MEMORY_RELOCATE: + return readb(entry->relocate+(off-entry->base)); + case MEMORY_HANDLER: + return entry->handler.read(off-entry->base); + break; + default: + E_Exit("Read from Illegal Memory Address %4x",off); + } + return 0; /* Keep compiler happy */ +} + +Bit16u mem_readw(PhysPt off) { + PageEntry * entry=PageEntries[off >> 12]; + if (!entry) { return readw(memory+off);} + switch (entry->type) { + case MEMORY_RELOCATE: + return readw(entry->relocate+(off-entry->base)); + case MEMORY_HANDLER: + return entry->handler.read(off-entry->base) | + (entry->handler.read(off-entry->base+1) << 8); + break; + default: + E_Exit("Read from Illegal Memory Address %4x",off); + } + return 0; /* Keep compiler happy */ +} + +Bit32u mem_readd(PhysPt off) { + PageEntry * entry=PageEntries[off >> 12]; + if (!entry) { return readd(memory+off);} + switch (entry->type) { + case MEMORY_RELOCATE: + return readd(entry->relocate+(off-entry->base)); + case MEMORY_HANDLER: + return entry->handler.read(off-entry->base) | + (entry->handler.read(off-entry->base+1) << 8) | + (entry->handler.read(off-entry->base+2) << 16)| + (entry->handler.read(off-entry->base+3) << 24); + break; + default: + E_Exit("Read from Illegal Memory Address %4x",off); + } + return 0; /* Keep compiler happy */ +} + +/* The EMM Allocation Part */ + +/* If this returns 0 we got and error since 0 is always taken */ +static Bit16u EMM_GetFreeHandle(void) { + Bit16u i=0; + while (i*maxblock) *maxblock=EMM_Handles[index].size; + *total+=EMM_Handles[index].size; + } + if (EMM_Handles[index].next) index=EMM_Handles[index].next; + else break; + } +} + +void EMM_Allocate(Bit16u size,Bit16u * handle) { + Bit16u index=0;*handle=0; + while (EMM_Handles[index].active) { + if (EMM_Handles[index].free) { + /* Use entire block */ + if(EMM_Handles[index].size==size) { + EMM_Handles[index].free=false; + *handle=index; + break; + } + /* Split up block */ + if(EMM_Handles[index].size>size) { + Bit16u newindex=EMM_GetFreeHandle(); + EMM_Handles[newindex].active=true; + EMM_Handles[newindex].phys_base=EMM_Handles[newindex].phys_base+size*4096; + EMM_Handles[newindex].size=EMM_Handles[index].size-size; + EMM_Handles[newindex].free=true; + EMM_Handles[newindex].next=EMM_Handles[index].next; + EMM_Handles[index].next=newindex; + EMM_Handles[index].free=false; + EMM_Handles[index].size=size; + *handle=index; + break; + } + } + if (EMM_Handles[index].next) index=EMM_Handles[index].next; + else break; + } +} + +void EMM_Free(Bit16u handle) { + if (!EMM_Handles[handle].active) E_Exit("EMM:Tried to free illegal handle"); + EMM_Handles[handle].free=true; + //TODO join memory blocks +} + + +PageEntry HMA_PageEntry; + +void MEM_Init(void) { + memset((void *)&PageEntries,0,sizeof(PageEntries)); + memory=(Bit8u *)malloc(memsize*1024*1024); + if (!memory) { + E_Exit("Can't allocate memory for memory"); + } + /* Setup the HMA to wrap */ + HMA_PageEntry.type=MEMORY_RELOCATE;; + HMA_PageEntry.base=1024*1024; + HMA_PageEntry.relocate=memory; + Bitu i; + for (i=0;i<16;i++) { + PageEntries[i+256]=&HMA_PageEntry; + } + /* Setup the EMM Structures */ + for (i=0;i1) { + EMM_Handles[1].size=(memsize-1)*256-16; + } else { + EMM_Handles[0].size=0;; + } + EMM_Handles[1].active=true; + EMM_Handles[1].free=true; + EMM_Handles[1].phys_base=0x110000; +}; + + diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp new file mode 100644 index 00000000..8144e39d --- /dev/null +++ b/src/hardware/mixer.cpp @@ -0,0 +1,254 @@ +/* + * 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. + */ + +/* + Remove the sdl code from here and have it handeld in the sdlmain. + That should call the mixer start from there or something. +*/ + +#include +#include +#include "dosbox.h" +#include "mixer.h" +#include "timer.h" + +#define MIXER_MAXCHAN 8 +#define MIXER_BLOCKSIZE 1024 +#define MIXER_BUFSIZE MIXER_BLOCKSIZE*8 +#define MIXER_SSIZE 4 +#define MIXER_SHIFT 16 +#define MIXER_REMAIN ((1<playing=false; + chan->volume=255; + chan->mode=MIXER_16STEREO; + chan->handler=handler; + chan->name=name; + chan->sample_add=(freq<next=first_channel; + first_channel=chan; + return chan; +}; + +void MIXER_SetFreq(MIXER_Channel * chan,Bit32u freq) { + if (chan) { + chan->freq=freq; + /* Calculate the new addition value */ + chan->sample_add=(freq<mode=mode; +}; + +void MIXER_SetVolume(MIXER_Channel * chan,Bit8u vol) { + if (chan) chan->volume=vol; +} + +void MIXER_Enable(MIXER_Channel * chan,bool enable) { + if (chan) chan->playing=enable; +} + + + +/* Mix a certain amount of new samples */ +static void MIXER_MixData(Bit32u samples) { +/* This Should mix the channels */ + if (!samples) return; + if (samples>MIXER_BUFSIZE) samples=MIXER_BUFSIZE; + /* 16-bit stereo is 4 bytes per sample */ + memset((void *)&mix_buftemp,0,samples*MIXER_SSIZE); + MIXER_Channel * chan=first_channel; + while (chan) { + if (chan->playing) { + Bit32u chan_samples=samples*chan->sample_add; + Bit32u real_samples=chan_samples>>MIXER_SHIFT; + if (chan_samples & MIXER_REMAIN) real_samples++; + (chan->handler)((Bit8u*)&temp_m8,real_samples); + switch (chan->mode) { + case MIXER_8MONO: + /* Mix a 8 bit mono stream into the final 16 bit stereo output stream */ + { + /* Mix the data with output buffer */ + Bit32s newsample;Bit32u sample_read=0;Bit32u sample_add=chan->sample_add; + for (Bit32u mix=0;mix> MIXER_SHIFT; + sample_read+=sample_add; + newsample=mix_buftemp[mix][0]+((Bit8s)(temp_m8[pos][0]^0x80) << 8); + if (newsample>MAX_AUDIO) mix_buftemp[mix][0]=MAX_AUDIO; + else if (newsampleMAX_AUDIO) mix_buftemp[mix][1]=MAX_AUDIO; + else if (newsamplesample_add; + for (Bit32u mix=0;mix> MIXER_SHIFT; + sample_read+=sample_add; + newsample=mix_buftemp[mix][0]+temp_m16[pos][0]; + if (newsample>MAX_AUDIO) mix_buftemp[mix][0]=MAX_AUDIO; + else if (newsampleMAX_AUDIO) mix_buftemp[mix][1]=MAX_AUDIO; + else if (newsamplesample_add; + for (Bit32u mix=0;mix> MIXER_SHIFT; + sample_read+=sample_add; + newsample=mix_buftemp[mix][0]+temp_s16[pos][0]; + if (newsample>MAX_AUDIO) mix_buftemp[mix][0]=MAX_AUDIO; + else if (newsampleMAX_AUDIO) mix_buftemp[mix][1]=MAX_AUDIO; + else if (newsamplemode); + } + } + chan=chan->next; + } + Bit32u buf_remain=MIXER_BUFSIZE-mix_writepos; + /* Fill the samples size buffer with 0's */ + if (buf_remain>samples) { + memcpy(&mix_bufout[mix_writepos][0],&mix_buftemp[0][0],samples*MIXER_SSIZE); + mix_writepos+=samples; + } else { + memcpy(&mix_bufout[mix_writepos][0],&mix_buftemp[0][0],buf_remain*MIXER_SSIZE); + memcpy(&mix_bufout[0][0],&mix_buftemp[buf_remain][0],(samples-buf_remain)*MIXER_SSIZE); + mix_writepos=(mix_writepos+samples)-MIXER_BUFSIZE; + } + + +} + +void MIXER_Mix(Bitu ticks) { +/* Check for 1 ms of sound to mix */ + Bitu count=(ticks*mix_add)+mix_remain; + mix_remain=count&((1<<10)-1); + count>>=10; + Bit32u size=MIXER_BUFSIZE+mix_writepos-mix_readpos; + if (size>=MIXER_BUFSIZE) size-=MIXER_BUFSIZE; + if (size>MIXER_BLOCKSIZE+2048) return; + MIXER_MixData(count); + +} + +static Bit32u last_pos; +static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { + /* Copy data from buf_out to the stream */ + + Bit32u remain=MIXER_BUFSIZE-mix_readpos; + if (remain>=len/MIXER_SSIZE) { + memcpy((void *)stream,(void *)&mix_bufout[mix_readpos][0],len); + } else { + memcpy((void *)stream,(void *)&mix_bufout[mix_readpos][0],remain*MIXER_SSIZE); + stream+=remain*MIXER_SSIZE; + memcpy((void *)stream,(void *)&mix_bufout[0][0],(len)-remain*MIXER_SSIZE); + } + mix_readpos+=(len/MIXER_SSIZE); + if (mix_readpos>=MIXER_BUFSIZE) mix_readpos-=MIXER_BUFSIZE; +} + + + +void MIXER_Init(void) { + /* Initialize the internal stuff */ + first_channel=0; + mix_ticks=GetTicks(); + mix_bufextra=0; + mix_writepos=0; + mix_readpos=0; + + /* Start the Mixer using SDL Sound at 22 khz */ + SDL_AudioSpec spec; + SDL_AudioSpec obtained; + mix_add=((MIXER_FREQ) << 10)/1000; + mix_remain=0; + spec.freq=MIXER_FREQ; + spec.format=AUDIO_S16SYS; + spec.channels=2; + spec.callback=MIXER_CallBack; + spec.userdata=NULL; + spec.samples=MIXER_BLOCKSIZE; + + TIMER_RegisterTickHandler(MIXER_Mix); + + if ( SDL_OpenAudio(&spec, &obtained) < 0 ) { + LOG_MSG("No sound output device found, starting in no sound mode"); + } else { + MIXER_MixData(MIXER_BLOCKSIZE/MIXER_SSIZE); + SDL_PauseAudio(0); + } +} diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp new file mode 100644 index 00000000..c8aabb11 --- /dev/null +++ b/src/hardware/pcspeaker.cpp @@ -0,0 +1,88 @@ +/* + * 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. + */ + + +#include +#include +#include + + +#ifndef PI +#define PI 3.14159265358979323846 +#endif + +#define SPKR_RATE 22050 +#define SPKR_VOLUME 5000 + +#define FREQ_SHIFT 16 +#define FREQ_MAX (2 << FREQ_SHIFT) +#define FREQ_HALF (FREQ_MAX >> 1) + + + +struct Speaker { + Bit32u freq_add; + Bit32u freq_pos; + Bit16s volume; + MIXER_Channel * chan; + bool enabled; +}; + + +static Speaker spkr; + + +void PCSPEAKER_SetFreq(Bit32u freq) { + spkr.freq_add=(Bit32u)(FREQ_MAX/((float)SPKR_RATE/(float)freq)); + spkr.freq_pos=0; +} + +void PCSPEAKER_Enable(bool enable) { + spkr.enabled=enable; + MIXER_Enable(spkr.chan,enable); +} + +static void PCSPEAKER_CallBack(Bit8u * stream,Bit32u len) { + /* Generate the speaker wave, TODO Improve :) */ + for (Bit32u c=0;c=FREQ_MAX) spkr.freq_pos-=FREQ_MAX; + if (spkr.freq_pos>=FREQ_HALF) { + *(Bit16s*)(stream)=spkr.volume; + } else { + *(Bit16s*)(stream)=-spkr.volume; + } +/* + if (spkr.freq_pos>=FREQ_HALF) { + spkr.freq_pos-=FREQ_HALF; + spkr.volume=-spkr.volume; + }; + *(Bit16s*)(stream)=spkr.volume; +*/ + stream+=2; + } + +} + +void PCSPEAKER_Init(void) { + spkr.chan=MIXER_AddChannel(&PCSPEAKER_CallBack,SPKR_RATE,"PC-SPEAKER"); + MIXER_Enable(spkr.chan,false); + MIXER_SetMode(spkr.chan,MIXER_16MONO); + spkr.volume=SPKR_VOLUME; + spkr.enabled=false; +} diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp new file mode 100644 index 00000000..b21bd49b --- /dev/null +++ b/src/hardware/pic.cpp @@ -0,0 +1,369 @@ +/* + * 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. + */ + + +#include "dosbox.h" +#include "inout.h" +#include "cpu.h" +#include "pic.h" + +struct IRQ_Block { + bool masked; + bool active; + bool inservice; + Bit8u vector; + char * name; + PIC_EOIHandler * handler; +}; + +Bit32u PIC_IRQCheck; + +static IRQ_Block irqs[16]; +static Bit8u pic0_icws=0; +static Bit8u pic1_icws=0; +static Bit8u pic0_icw_state=0; +static Bit8u pic1_icw_state=0; +static bool pic0_request_iisr=0; +static bool pic1_request_iisr=0; +//TODO Special mask mode in ocw3 +//TODO maybe check for illegal modes that don't work on pc too and exit the emu + +//Pic 0 command port +static void write_p20(Bit32u port,Bit8u val) { + Bit32u i; + switch (val) { + case 0x0A: /* select read interrupt request register */ + pic0_request_iisr=false; + break; + case 0x0B: /* select read interrupt in-service register */ + pic0_request_iisr=true; + break; + case 0x10: /* ICW1 */ + pic0_icws=2; + pic0_icw_state=1; + + break; + case 0x11: /* ICW1 + need for ICW4 */ + pic0_icws=3; + pic0_icw_state=1; + break; + case 0x20: /* end of interrupt command */ + /* clear highest current in service bit */ + for (i=0;i<=7;i++) { + if (irqs[i].inservice) { + irqs[i].inservice=false; + if (irqs[i].handler!=0) irqs[i].handler(); + break; + }; + }; + break; + case 0x60: /* specific EOI 0 */ + case 0x61: /* specific EOI 1 */ + case 0x62: /* specific EOI 2 */ + case 0x63: /* specific EOI 3 */ + case 0x64: /* specific EOI 4 */ + case 0x65: /* specific EOI 5 */ + case 0x66: /* specific EOI 6 */ + case 0x67: /* specific EOI 7 */ + if (irqs[val-0x60].inservice) { + irqs[val-0x60].inservice=false; + if (irqs[val-0x60].handler!=0) irqs[val-0x60].handler(); + }; + break; + // IRQ lowest priority commands + case 0xC0: // 0 7 6 5 4 3 2 1 + case 0xC1: // 1 0 7 6 5 4 3 2 + case 0xC2: // 2 1 0 7 6 5 4 3 + case 0xC3: // 3 2 1 0 7 6 5 4 + case 0xC4: // 4 3 2 1 0 7 6 5 + case 0xC5: // 5 4 3 2 1 0 7 6 + case 0xC6: // 6 5 4 3 2 1 0 7 + case 0xC7: // 7 6 5 4 3 2 1 0 + // ignore for now TODO + break; + default: + E_Exit("PIC0:Unhandled command %02X",val); + } +} + +//Pic 0 Interrupt mask +static void write_p21(Bit32u port,Bit8u val) { + Bit8u i; + switch(pic0_icw_state) { + case 0: /* mask register */ + for (i=0;i<=7;i++) { + irqs[i].masked=(val&(1<0; + if (irqs[i].active && !irqs[i].masked) PIC_IRQCheck|=(1 << 1); + else PIC_IRQCheck&=~(1 << i); + }; + break; + case 1: /* icw2 */ + for (i=0;i<=7;i++) { + irqs[i].vector=(val&0xf8)+i; + }; + default: /* icw2, 3, and 4*/ + if(pic0_icw_state++ >= pic0_icws) pic0_icw_state=0; + } + +} + +static Bit8u read_p20(Bit32u port) { + Bit8u ret=0; + Bit32u i; + Bit8u b=1; + if (pic0_request_iisr) { + for (i=0;i<=7;i++) { + if (irqs[i].inservice) ret|=b; + b <<= 1; + } + } else { + for (i=0;i<=7;i++) { + if (irqs[i].active) ret|=b; + b <<= 1; + } + }; + return ret; +} + +static Bit8u read_p21(Bit32u port) { + Bit8u ret=0; + Bit32u i; + Bit8u b=1; + for (i=0;i<=7;i++) { + if (irqs[i].masked) ret|=b; + b <<= 1; + } + return ret; +} + +static void write_pa0(Bit32u port,Bit8u val) { + Bit32u i; + switch (val) { + case 0x0A: /* select read interrupt request register */ + pic1_request_iisr=false; + break; + case 0x0B: /* select read interrupt in-service register */ + pic1_request_iisr=true; + break; + case 0x10: /* ICW1 */ + /* Clear everything set full mask and clear all inservice */ + for (i=0;i<=7;i++) { + irqs[i].masked=true; + irqs[i].active=false; + irqs[i].inservice=false; + } + pic1_icws=2; + pic1_icw_state=1; + break; + case 0x11: /* ICW1 + need for ICW4 */ + pic1_icws=3; + pic1_icw_state=1; + break; + case 0x20: /* end of interrupt command */ + /* clear highest current in service bit */ + for (i=8;i<=15;i++) { + if (irqs[i].inservice) { + irqs[i].inservice=false; + if (irqs[i].handler!=0) irqs[i].handler(); + break; + }; + }; + break; + case 0x60: /* specific EOI 0 */ + case 0x61: /* specific EOI 1 */ + case 0x62: /* specific EOI 2 */ + case 0x63: /* specific EOI 3 */ + case 0x64: /* specific EOI 4 */ + case 0x65: /* specific EOI 5 */ + case 0x66: /* specific EOI 6 */ + case 0x67: /* specific EOI 7 */ + if (irqs[val-0x60+8].inservice) { + irqs[val-0x60+8].inservice=false; + if (irqs[val-0x60+8].handler!=0) irqs[val-0x60+8].handler(); + }; + break; + // IRQ lowest priority commands + case 0xC0: // 0 7 6 5 4 3 2 1 + case 0xC1: // 1 0 7 6 5 4 3 2 + case 0xC2: // 2 1 0 7 6 5 4 3 + case 0xC3: // 3 2 1 0 7 6 5 4 + case 0xC4: // 4 3 2 1 0 7 6 5 + case 0xC5: // 5 4 3 2 1 0 7 6 + case 0xC6: // 6 5 4 3 2 1 0 7 + case 0xC7: // 7 6 5 4 3 2 1 0 + //TODO Maybe does it even matter? + break; + default: + E_Exit("Unhandled command %04X sent to port A0",val); + } +} + + +static void write_pa1(Bit32u port,Bit8u val) { + Bit8u i; + switch(pic1_icw_state) { + case 0: /* mask register */ + for (i=0;i<=7;i++) { + irqs[i+8].masked=(val&1 <0; + }; + break; + case 1: /* icw2 */ + for (i=0;i<=7;i++) { + irqs[i+8].vector=(val&0xf8)+i; + }; + default: /* icw2, 3, and 4*/ + if(pic1_icw_state++ >= pic1_icws) pic1_icw_state=0; + } +} + +static Bit8u read_pa0(Bit32u port) { + Bit8u ret=0; + Bit32u i; + Bit8u b=1; + if (pic1_request_iisr) { + for (i=0;i<=7;i++) { + if (irqs[i+8].inservice) ret|=b; + b <<= 1; + } + } else { + for (i=0;i<=7;i++) { + if (irqs[i+8].active) ret|=b; + b <<= 1; + } + }; + return ret; +} + + +static Bit8u read_pa1(Bit32u port) { + Bit8u ret=0; + Bit32u i; + Bit8u b=1; + for (i=0;i<=7;i++) { + if (irqs[i+8].masked) ret|=b; + b <<= 1; + } + return ret; +} + +void PIC_RegisterIRQ(Bit32u irq,PIC_EOIHandler handler,char * name) { + if (irq>15) E_Exit("PIC:Illegal IRQ"); + irqs[irq].name=name; + irqs[irq].handler=handler; +} + +void PIC_FreeIRQ(Bit32u irq) { + if (irq>15) E_Exit("PIC:Illegal IRQ"); + irqs[irq].name=0; + irqs[irq].handler=0; + irqs[irq].active=0; + irqs[irq].inservice=0; + PIC_IRQCheck&=~(1 << irq); +} + +void PIC_ActivateIRQ(Bit32u irq) { + if (irq<16) { + irqs[irq].active=true; + if (!irqs[irq].masked) { + PIC_IRQCheck|=(1 << irq); + } + } +} + +void PIC_DeActivateIRQ(Bit32u irq) { + if (irq<16) { + irqs[irq].active=false; + PIC_IRQCheck&=~(1 << irq); + } +} + +bool PIC_IRQActive(Bit32u irq) { + if (irq<16) { + return irqs[irq].active; + } + return true; +} + + +#define PIC_MAXQUEUE 16 +static PIC_Function * pic_queue[PIC_MAXQUEUE]; +static Bit32u pic_queuesize; + +void PIC_QueueFunction(PIC_Function * function) { + if (pic_queuesize0;) { + (*pic_queue[--pic_queuesize])(); + } +}; + + +void PIC_Init(void) { + /* Setup pic0 and pic1 with initial values like DOS has normally */ + PIC_IRQCheck=0; + Bit8u i; + for (i=0;i<=7;i++) { + irqs[i].active=false; + irqs[i].masked=true; + irqs[i].inservice=false; + irqs[i+8].active=false; + irqs[i+8].masked=true; + irqs[i+8].inservice=false; + irqs[i].vector=0x8+i; + irqs[i+8].vector=0x70+i; + }; + irqs[0].masked=false; /* Enable system timer */ + irqs[1].masked=false; /* Enable Keyboard IRQ */ + irqs[2].masked=false; /* Enable 2nd PIC Although i can't care if this is masked */ + irqs[12].masked=false; + IO_RegisterReadHandler(0x20,read_p20,"Master PIC Command"); + IO_RegisterReadHandler(0x21,read_p21,"Master PIC Data"); + IO_RegisterWriteHandler(0x20,write_p20,"Master PIC Command"); + IO_RegisterWriteHandler(0x21,write_p21,"Master PIC Data"); + IO_RegisterReadHandler(0xa0,read_pa0,"Slave PIC Command"); + IO_RegisterReadHandler(0xa1,read_pa1,"Slave PIC Data"); + IO_RegisterWriteHandler(0xa0,write_pa0,"Slave PIC Command"); + IO_RegisterWriteHandler(0xa1,write_pa1,"Slave PIC Data"); +}; + + diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp new file mode 100644 index 00000000..5b1c0f2b --- /dev/null +++ b/src/hardware/sblaster.cpp @@ -0,0 +1,613 @@ +/* + * 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. + */ + +#include +#include "dosbox.h" +#include "inout.h" +#include "mixer.h" +#include "dma.h" +#include "pic.h" +#include "hardware.h" + +#define SB_BASE 0x220 +#define SB_IRQ 5 +#define SB_DMA 1 + +#define DSP_RESET 0x06 +#define DSP_READ_DATA 0x0A +#define DSP_WRITE_DATA 0x0C +#define DSP_WRITE_STATUS 0x0C +#define DSP_READ_STATUS 0x0E + +#define DSP_NO_COMMAND 0 + +#define DSP_MAJOR 2 +#define DSP_MINOR 0 + +#define DSP_BUFSIZE 64 +#define DSP_DACSIZE 4096 + +enum {DSP_S_RESET,DSP_S_NORMAL,DSP_S_HIGHSPEED}; +enum { + MODE_NONE,MODE_DAC, + MODE_PCM_8S,MODE_PCM_8A, + MODE_ADPCM_4S +}; + +#ifdef DEBUG_SBLASTER +#define SB_DEBUG LOG_DEBUG +#else +#define SB_DEBUG +#endif + + +struct SB_INFO { + Bit16u freq; + Bitu samples_total; + Bitu samples_left; + bool speaker; + Bit8u time_constant; + bool use_time_constant; + + Bit8u output_mode; + /* DSP Stuff */ + Bit8u mode; + Bit8u state; + Bit8u cmd; + Bit8u cmd_len; + Bit8u cmd_in_pos; + Bit8u cmd_in[DSP_BUFSIZE]; + Bit8u data_out[DSP_BUFSIZE]; + Bit8u data_out_pos; + Bit8u data_out_used; + Bit8u dac_data[DSP_DACSIZE]; + Bit32u dac_used; + Bit8u test_register; +/*ADPCM Part */ + Bits adpcm_reference; + Bits adpcm_scale; + Bits adpcm_remain; +/* Hardware setup part */ + Bit32u base; + Bit8u irq; + Bit8u dma; + bool enabled; + HWBlock hwblock; + MIXER_Channel * chan; +}; + +static SB_INFO sb; +static Bit8u e2_value; +static Bit8u e2_count; + +static char * copyright_string="COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; + +static Bit8u DSP_cmd_len[256] = { + 0,0,0,0, 0,2,0,0, 0,0,0,0, 0,0,0,0, // 0x00 + 1,0,0,0, 2,0,2,2, 0,0,0,0, 0,0,0,0, // 0x10 + 0,0,0,0, 2,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x30 + + 1,2,2,0, 0,0,0,0, 2,0,0,0, 0,0,0,0, // 0x40 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x50 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x60 + 0,0,0,0, 2,2,2,2, 0,0,0,0, 0,0,0,0, // 0x70 + + 2,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x80 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x90 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0xa0 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xb0 + + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xc0 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0xd0 + 1,0,1,0, 1,0,0,0, 0,0,0,0, 0,0,0,0, // 0xe0 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 // 0xf0 +}; + +static int E2_incr_table[4][9] = { + { 0x01, -0x02, -0x04, 0x08, -0x10, 0x20, 0x40, -0x80, -106 }, + { -0x01, 0x02, -0x04, 0x08, 0x10, -0x20, 0x40, -0x80, 165 }, + { -0x01, 0x02, 0x04, -0x08, 0x10, -0x20, -0x40, 0x80, -151 }, + { 0x01, -0x02, 0x04, -0x08, -0x10, 0x20, -0x40, 0x80, 90 } +}; + +#ifndef max +#define max(a,b) ((a)>(b)?(a):(b)) +#endif +#ifndef min +#define min(a,b) ((a)<(b)?(a):(b)) +#endif + +static void DSP_SetSpeaker(bool how) { +/* This should just set the mixer value */ + MIXER_Enable(sb.chan,how); + sb.speaker=how; +} + +static void DSP_HaltDMA(void) { + +} + +static INLINE void DSP_FlushData(void) { + sb.data_out_used=0; + sb.data_out_pos=0; +} + +static void DSP_SetSampleRate(Bit32u rate) { +/* This directly changes the mixer */ + + +} +static void DSP_StopDMA(void) { + sb.mode=MODE_NONE; +// MIXER_SetMode(sb.chan,MIXER_8MONO); +// MIXER_SetFreq(sb.chan,22050); +} + +static void DSP_StartDMATranfser(Bit8u mode) { + sb.samples_left=sb.samples_total; + if (sb.use_time_constant) { + sb.freq=(1000000 / (256 - sb.time_constant)); + }; + switch (mode) { + case MODE_PCM_8S: + MIXER_SetFreq(sb.chan,sb.freq); + SB_DEBUG("DSP:PCM 8 bit single cycle rate %d size %d",sb.freq,sb.samples_total); + break; + case MODE_PCM_8A: + MIXER_SetFreq(sb.chan,sb.freq); + SB_DEBUG("DSP:PCM 8 bit auto init rate %d size %d",sb.freq,sb.samples_total); + + break; + case MODE_ADPCM_4S: + MIXER_SetFreq(sb.chan,sb.freq*2); + SB_DEBUG("DSP:ADPCM 4 bit single cycle rate %d size %X",sb.freq,sb.samples_total); + break; + + default: + LOG_ERROR("DSP:Illegal transfer mode %d",mode); + return; + } + /* Hack to enable dma transfer when game has speaker disabled */ + DSP_SetSpeaker(true); + sb.mode=mode; +} + +static void DSP_AddData(Bit8u val) { + if (sb.data_out_used=DSP_BUFSIZE) start-=DSP_BUFSIZE; + sb.data_out[start]=val; + sb.data_out_used++; + } else { + LOG_ERROR("SB:DSP:Data Output buffer full this is weird"); + } +} + +static void DSP_Reset(void) { + sb.mode=MODE_NONE; + sb.cmd_len=0; + sb.cmd_in_pos=0; + sb.use_time_constant=false; + sb.dac_used=0; + e2_value=0xaa; + e2_count=0; + DSP_HaltDMA(); + MIXER_SetFreq(sb.chan,22050); + MIXER_SetMode(sb.chan,MIXER_8MONO); + DSP_SetSpeaker(false); +} +static void DSP_DoReset(Bit8u val) { + if (val&1!=0) { +//TODO Get out of highspeed mode + DSP_Reset(); + sb.state=DSP_S_RESET; + } else { + DSP_FlushData(); + DSP_AddData(0xaa); + sb.state=DSP_S_NORMAL; + } +}; + +static bool dac_warn=false; +static void DSP_DoCommand(void) { + switch (sb.cmd) { + case 0x10: /* Direct DAC */ + sb.mode=MODE_DAC; + if (sb.dac_used> i) & 0x01) m_E2Value += E2_incr_table[m_E2Count % 4][i]; + + m_E2Value += E2_incr_table[m_E2Count % 4][8]; + m_E2Count++; +*/ +//TODO Ofcourse :) + } + + break; + case 0xe3: /* DSP Copyright */ + { + DSP_FlushData(); + for (Bit32u i=0;i<=strlen(copyright_string);i++) { + DSP_AddData(copyright_string[i]); + } + } + break; + case 0xe4: /* Write Test Register */ + sb.test_register=sb.cmd_in[0]; + break; + case 0xe8: /* Read Test Register */ + DSP_FlushData(); + DSP_AddData(sb.test_register);; + break; + + case 0xf2: /* Trigger 8bit IRQ */ + DSP_FlushData(); + DSP_AddData(0xaa); + PIC_ActivateIRQ(sb.irq); + break; + default: + LOG_WARN("SB:DSP:Unhandled command %2X",sb.cmd); + } + sb.cmd=DSP_NO_COMMAND; + sb.cmd_len=0; + sb.cmd_in_pos=0; +} + + + +static void DSP_DoWrite(Bit8u val) { + switch (sb.cmd) { + case DSP_NO_COMMAND: + sb.cmd=val; + sb.cmd_len=DSP_cmd_len[val]; + sb.cmd_in_pos=0; + if (!sb.cmd_len) DSP_DoCommand(); + break; + default: + sb.cmd_in[sb.cmd_in_pos]=val; + sb.cmd_in_pos++; + if (sb.cmd_in_pos>=sb.cmd_len) DSP_DoCommand(); + } +} + +static Bit8u DSP_ReadData(void) { + Bit8u data=0; + if (sb.data_out_used) { + data=sb.data_out[sb.data_out_pos]; + sb.data_out_pos++; + if (sb.data_out_pos>=DSP_BUFSIZE) sb.data_out_pos-=DSP_BUFSIZE; + sb.data_out_used--; + } + return data; +} + +static Bit8u read_sb(Bit32u port) { + switch (port-sb.base) { + case DSP_READ_DATA: + return DSP_ReadData(); + case DSP_READ_STATUS: + //TODO Acknowledge 8bit irq + //TODO See for high speed dma :) + if (sb.data_out_used) return 0xff; + else return 0x7f; + case DSP_WRITE_STATUS: + switch (sb.state) { + case DSP_S_NORMAL: + return 0x7f; + case DSP_S_RESET: + return 0xff; + } + return 0xff; +/* For now loop FM Stuff to 0x388 */ + case 0x00: case 0x02: case 0x08: + return IO_Read(0x388); + case DSP_RESET: + return 0xff; + default: + LOG_WARN("SB:Unhandled read from SB Port %4X",port); + break; + } + return 0xff; +} + +static void write_sb(Bit32u port,Bit8u val) { + switch (port-sb.base) { + case DSP_RESET: + DSP_DoReset(val); + break; + case DSP_WRITE_DATA: + DSP_DoWrite(val); + break; +/* For now loop FM Stuff to 0x388 */ + case 0x00: case 0x02: case 0x08: + IO_Write(0x388,val); + break; + case 0x01: case 0x03: case 0x09: + IO_Write(0x389,val); + break; + + default: + LOG_WARN("SB:Unhandled write to SB Port %4X",port); + break; + } +} + + +INLINE Bit8u decode_ADPCM_4_sample( + Bit8u sample, + Bits& reference, + Bits& scale) +{ + static int scaleMap[8] = { -2, -1, 0, 0, 1, 1, 1, 1 }; + + if (sample & 0x08) { + reference = max(0x00, reference - ((sample & 0x07) << scale)); + } else { + reference = min(0xff, reference + ((sample & 0x07) << scale)); + } + + scale = max(2, min(6, scaleMap[sample & 0x07])); + + return (Bit8u)reference; +} + +static void SBLASTER_CallBack(Bit8u * stream,Bit32u len) { + unsigned char tmpbuf[65536]; + if (!len) return; + switch (sb.mode) { + case MODE_NONE: + /* If there isn't a mode it's 8 bit mono mode speaker should be disabled normally */ + memset(stream,0x80,len); + break; + case MODE_DAC: + /* Stretch the inputted dac data over len samples */ + { + Bit32u dac_add=(sb.dac_used<<16)/len; + Bit32u dac_pos=0; + while (len-->0) { + *(stream++)=sb.dac_data[dac_pos>>16]; + dac_pos+=dac_add; + } + } + sb.dac_used=0; + sb.mode=MODE_NONE; + break; + case MODE_PCM_8A: + DMA_8_Read(sb.dma,stream,(Bit16u)len); + if (sb.samples_left>len) { + sb.samples_left-=len; + } else { + if (len>(sb.samples_total+sb.samples_left)) sb.samples_left=sb.samples_total; + else sb.samples_left=sb.samples_total+sb.samples_left-len; + PIC_ActivateIRQ(sb.irq); + } + break; + case MODE_PCM_8S: + if (sb.samples_left>=len) { + DMA_8_Read(sb.dma,stream,(Bit16u)len); + sb.samples_left-=len; + } else if (sb.samples_left && (sb.samples_left=0) { + *stream++=decode_ADPCM_4_sample((Bit8u)sb.adpcm_remain,sb.adpcm_reference,sb.adpcm_scale); + len--; + } + Bitu dma_size=len/2+(len&1); //Amount of bytes that need to be transferred + Bit8u * decode_pos=tmpbuf; + if (sb.adpcm_reference < 0) { + dma_size++; + } + /* Read from the DMA Channel */ + if (sb.samples_left>=dma_size) { + DMA_8_Read(sb.dma,decode_pos,(Bit16u)dma_size); + sb.samples_left-=dma_size; + } else if (sb.samples_left0;i--) { + *stream++=decode_ADPCM_4_sample(*decode_pos >> 4,sb.adpcm_reference,sb.adpcm_scale); + *stream++=decode_ADPCM_4_sample(*decode_pos++ ,sb.adpcm_reference,sb.adpcm_scale); + } + if (len & 1) { + *stream++=decode_ADPCM_4_sample(*decode_pos >> 4,sb.adpcm_reference,sb.adpcm_scale); + sb.adpcm_remain=*decode_pos & 0xf; + } else { + sb.adpcm_remain=-1; + } + } + } +} + + + +static bool SB_enabled; + +static void SB_Enable(bool enable) { + Bitu i; + if (enable) { + sb.enabled=true; + for (i=sb.base+4;i +#include "dosbox.h" +#include "inout.h" +#include "mixer.h" +#include "mem.h" + +#define TANDY_DIV 111860 +#define TANDY_RATE 22050 +#define BIT_SHIFT 16 +#define TANDY_VOLUME 10000 +static MIXER_Channel * tandy_chan; +struct TandyChannel { + Bit32u div; + Bit32u freq_add; + Bit32u freq_pos; +}; + + +struct TandyBlock { + TandyChannel chan[3]; + + Bit32s volume[4]; + Bit8u reg; +}; + +static TandyBlock tandy; + + +#define REG_CHAN0DIV 0 /* 0 0 0 */ +#define REG_CHAN0ATT 1 /* 0 0 1 */ +#define REG_CHAN1DIV 2 /* 0 1 0 */ +#define REG_CHAN1ATT 3 /* 0 1 1 */ +#define REG_CHAN2DIV 4 /* 1 0 0 */ +#define REG_CHAN2ATT 5 /* 1 0 1 */ + +#define REG_NOISEATT 7 /* 1 1 1 */ + +//TODO a db volume table :) +static Bit32s vol_table[16]; + + +static void write_pc0(Bit32u port,Bit8u val) { + /* Test for a command byte */ + if (val & 0x80) { + tandy.reg=(val>>4) & 7; + switch (tandy.reg) { + case REG_CHAN0DIV: + case REG_CHAN1DIV: + case REG_CHAN2DIV: + tandy.chan[tandy.reg>>1].div=val&15; + break; + case REG_CHAN0ATT: + case REG_CHAN1ATT: + case REG_CHAN2ATT: + case REG_NOISEATT: + tandy.volume[tandy.reg>>1]=vol_table[val&15]; + if (tandy.volume[0] || tandy.volume[1] || tandy.volume[2] || tandy.volume[3]) { + MIXER_Enable(tandy_chan,true); + } else { + MIXER_Enable(tandy_chan,false); + } + break; + default: +// LOG_WARN("TANDY:Illegal register %d selected",tandy.reg); + break; + } + } else { +/* Dual byte command */ + switch (tandy.reg) { +#define MAKE_ADD(DIV)(Bit32u)((2 << BIT_SHIFT)/((float)TANDY_RATE/((float)TANDY_DIV/(float)DIV))); + case REG_CHAN0DIV: + case REG_CHAN1DIV: + case REG_CHAN2DIV: + tandy.chan[tandy.reg>>1].div|=(val & 63)<<4; + tandy.chan[tandy.reg>>1].freq_add=MAKE_ADD(tandy.chan[tandy.reg>>1].div); +// tandy.chan[tandy.reg>>1].freq_pos=0; + break; + default: + LOG_WARN("TANDY:Illegal dual byte reg %d",tandy.reg); + }; + } + +} + +static void TANDYSOUND_CallBack(Bit8u * stream,Bit32u len) { + for (Bit32u i=0;i=(2 << BIT_SHIFT)) tandy.chan[c].freq_pos-=(2 << BIT_SHIFT); + } + } + /* Generate the noise channel */ + + if (sample>MAX_AUDIO) *(Bit16s *)stream=MAX_AUDIO; + else if (sample +#include "dosbox.h" +#include "inout.h" +#include "pic.h" +#include "bios.h" +#include "mem.h" +#include "dosbox.h" +#include "mixer.h" +#include "timer.h" + + + +struct PIT_Block { + Bit8u mode; /* Current Counter Mode */ + Bit32s cntr; + Bit8u latch_mode; + Bit8u read_state; + Bit16s read_latch; + Bit8u write_state; + Bit16u write_latch; + Bit32u last_ticks; +}; + + +static PIT_Block pit[3]; +static Bit32u pit_ticks; /* The amount of pit ticks one host tick is bit shifted */ +static Bit32u timer_ticks; /* The amount of pit ticks bitshifted one timer cycle needs */ +static Bit32u timer_buildup; /* The amount of pit ticks waiting */ +#define PIT_TICK_RATE 1193182 +#define PIT_SHIFT 9 +#define MAX_PASSED ((PIT_TICK_RATE/4) << PIT_SHIFT) /* Alow 1/4 second of timer build up */ + + +static void counter_latch(Bitu counter) { + /* Fill the read_latch of the selected counter with current count */ + PIT_Block * p=&pit[counter]; +//TODO Perhaps make it a bit64u for accuracy :) + Bit32u ticks=(((LastTicks - p->last_ticks) * pit_ticks) >> PIT_SHIFT) % p->cntr ; + switch (p->mode) { + case 2: + case 3: + p->read_latch=(Bit16u)ticks; + break; + default: + LOG_ERROR("PIT:Illegal Mode %d for reading counter %d",p->mode,counter); + p->read_latch=(Bit16u)ticks; + break; + } +} + + + +static void write_latch(Bit32u port,Bit8u val) { + Bit32u counter=port-0x40; + PIT_Block * p=&pit[counter]; + switch (p->write_state) { + case 0: + p->write_latch = p->write_latch | ((val & 0xff) << 8); + p->write_state = 3; + break; + case 3: + p->write_latch = val & 0xff; + p->write_state = 0; + break; + case 1: + p->write_latch = val & 0xff; + break; + case 2: + p->write_latch = (val & 0xff) << 8; + break; + } + if (p->write_state != 0) { + if (p->write_latch == 0) p->cntr = 0x10000; + else p->cntr = p->write_latch; + p->last_ticks=LastTicks; + switch (counter) { + case 0x00: /* Timer hooked to IRQ 0 */ + PIC_DeActivateIRQ(0); + timer_ticks=p->cntr << PIT_SHIFT; + timer_buildup=0; + LOG_DEBUG("PIT 0 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode); + break; + case 0x02: /* Timer hooked to PC-Speaker */ + PCSPEAKER_SetFreq(PIT_TICK_RATE/p->cntr); + break; + default: + LOG_ERROR("PIT:Illegal timer selected for writing"); + } + + } +} + +static Bit8u read_latch(Bit32u port) { + Bit32u counter=port-0x40; + if (pit[counter].read_latch == -1) + counter_latch(counter); + Bit8u ret; + switch (pit[counter].read_state) { + case 0: /* read MSB & return to state 3 */ + ret=(pit[counter].read_latch >> 8) & 0xff; + pit[counter].read_state = 3; + pit[counter].read_latch = -1; + break; + case 3: /* read LSB followed by MSB */ + ret = (pit[counter].read_latch & 0xff); + if (pit[counter].mode & 0x80) pit[counter].mode &= 7; /* moved here */ + else + pit[counter].read_state = 0; + break; + case 1: /* read MSB */ + ret = (pit[counter].read_latch >> 8) & 0xff; + pit[counter].read_latch = -1; + break; + case 2: /* read LSB */ + ret = (pit[counter].read_latch & 0xff); + pit[counter].read_latch = -1; + break; + default: + ret=0; + E_Exit("Timer.cpp: error in readlatch"); + break; + } + return ret; +} + + + + + +static void write_p43(Bit32u port,Bit8u val) { + if (val & 1) { + E_Exit("PIT:BCD Counter not supported"); + } + Bitu latch=(val >> 6) & 0x03; + switch (latch) { + case 0: + case 1: + case 2: + if ((val & 0x30) == 0) { + /* Counter latch command */ + counter_latch(latch); + } else { + pit[latch].read_state = (val >> 4) & 0x03; + pit[latch].write_state = (val >> 4) & 0x03; + pit[latch].mode = (val >> 1) & 0x07; + } + break; + case 3: + E_Exit("Special PIT Latch Read out thing"); + } + +} + +/* The TIMER Part */ + +enum { T_TICK,T_MICRO,T_DELAY}; + +struct Timer { + Bitu type; + union { + struct { + TIMER_TickHandler handler; + } tick; + struct{ + Bitu count; + Bitu total; + TIMER_MicroHandler handler; + } micro; + struct { + Bitu end; + TIMER_DelayHandler handler; + } delay; + }; +}; + +static Timer * first_timer=0; +static std::list Timers; + +TIMER_Block * TIMER_RegisterTickHandler(TIMER_TickHandler handler) { + Timer * new_timer=new(Timer); + new_timer->type=T_TICK; + new_timer->tick.handler=handler; + Timers.push_front(new_timer); + return (TIMER_Block *)new_timer; +} + +TIMER_Block * TIMER_RegisterMicroHandler(TIMER_MicroHandler handler,Bitu micro) { + Timer * new_timer=new(Timer); + new_timer->type=T_MICRO; + new_timer->micro.handler=handler; + new_timer->micro.total=micro; + new_timer->micro.count=0; + Timers.push_front(new_timer); + return (TIMER_Block *)new_timer; +} + +TIMER_Block * TIMER_RegisterDelayHandler(TIMER_DelayHandler handler,Bitu delay) { +//Todo maybe check for a too long delay + Timer * new_timer=new(Timer); + new_timer->type=T_DELAY; + new_timer->delay.handler=handler; + new_timer->delay.end=LastTicks+delay; + Timers.push_front(new_timer); + return (TIMER_Block *)new_timer; + +} +void TIMER_SetNewMicro(TIMER_Block * block,Bitu micro) { + Timer * timer=(Timer *)block; + if (timer->type!=T_MICRO) E_Exit("TIMER:Illegal handler type"); + timer->micro.count=0; + timer->micro.total=micro; +} + +void TIMER_AddTicks(Bit32u ticks) { +/* This will run through registered handlers and handle the PIT ticks */ + timer_buildup+=ticks*pit_ticks; + if (timer_buildup>MAX_PASSED) timer_buildup=MAX_PASSED; + Bitu add_micro=ticks*1000; + std::list::iterator i; + for(i=Timers.begin(); i != Timers.end(); ++i) { + Timer * timer=(*i); + switch (timer->type) { + case T_TICK: + timer->tick.handler(ticks); + break; + case T_MICRO: + timer->micro.count+=add_micro; + if (timer->micro.count>=timer->micro.total) { + timer->micro.count-=timer->micro.total; + timer->micro.handler(); + } + break; + case T_DELAY: + /* Also unregister the timer handler from the list */ + if (LastTicks>timer->delay.end) { + std::list::iterator remove; + timer->delay.handler(); + remove=i++; + Timers.erase(remove); + } + break; + default: + E_Exit("TIMER:Illegal handler type"); + }; + + }; +} + + +void TIMER_CheckPIT(void) { + if (timer_buildup>timer_ticks) { + timer_buildup-=timer_ticks; + PIC_ActivateIRQ(0); + return; + } +} + + +void TIMER_Init(void) { + IO_RegisterWriteHandler(0x40,write_latch,"PIT Timer 0"); + IO_RegisterWriteHandler(0x42,write_latch,"PIT Timer 2"); + IO_RegisterWriteHandler(0x43,write_p43,"PIT Mode Control"); + IO_RegisterReadHandler(0x40,read_latch,"PIT Timer 0"); +// IO_RegisterReadHandler(0x41,read_p41,"PIT Timer 1"); + IO_RegisterReadHandler(0x42,read_latch,"PIT Timer 2"); + /* Setup Timer 0 */ + pit[0].cntr=0x10000; + pit[0].write_state = 3; + pit[0].read_state = 3; + pit[0].read_latch=-1; + pit[0].write_latch=0; + pit[0].mode=3; + timer_ticks=pit[0].cntr << PIT_SHIFT; + timer_buildup=0; +// first_timer=0; + pit_ticks=(PIT_TICK_RATE << PIT_SHIFT)/1000; + PIC_RegisterIRQ(0,&TIMER_CheckPIT,"PIT 0 Timer"); +} + diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp new file mode 100644 index 00000000..1d866fcb --- /dev/null +++ b/src/hardware/vga.cpp @@ -0,0 +1,165 @@ +/* + * 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. + */ + +#include +#include + +#include "dosbox.h" +#include "video.h" +#include "pic.h" +#include "render.h" +#include "timer.h" +#include "vga.h" + +VGA_Type vga; +Bit32u CGAWriteTable[256]; +Bit32u ExpandTable[256]; + +Bit32u FillTable[16]={ + 0x00000000,0x000000ff,0x0000ff00,0x0000ffff, + 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff, + 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff, + 0xffff0000,0xffff00ff,0xffffff00,0xffffffff +}; + +static PageEntry VGA_PageEntry; + +void VGA_Render_GFX_4(Bit8u * * data); +void VGA_Render_GFX_16(Bit8u * * data); +void VGA_Render_GFX_256C(Bit8u * * data); +void VGA_Render_GFX_256U(Bit8u * * data); +void VGA_Render_TEXT_16(Bit8u * * data); + +void VGA_FindSettings(void) { + /* Sets up the correct memory handler from the vga.mode setting */ + MEMORY_ResetHandler(0xA0000/4096,128*1024/4096); + VGA_PageEntry.type=MEMORY_HANDLER; + /* Detect the kind of video mode this is */ + if (vga.config.gfxmode) { + if (vga.config.vga_enabled) { + if (vga.config.chained) { + /* 256 color chained vga */ + vga.mode=GFX_256C; + //Doesn't need a memory handler + } else { + /* 256 color unchained vga */ + vga.mode=GFX_256U; + VGA_PageEntry.base=0xA0000; + VGA_PageEntry.handler.read=VGA_NormalReadHandler; + VGA_PageEntry.handler.write=VGA_GFX_256U_WriteHandler; + MEMORY_SetupHandler(0xA0000/4096,16,&VGA_PageEntry); + } + } else if (vga.config.cga_enabled) { + /* 4 color cga */ + //TODO Detect hercules modes, probably set them up in bios too + vga.mode=GFX_4; +// VGA_PageEntry.base=0xB8000; +// VGA_PageEntry.handler.read=VGA_GFX_4_ReadHandler; +// VGA_PageEntry.handler.write=VGA_GFX_4_WriteHandler; +// MEMORY_SetupHandler(0xB8000/4096,8,&VGA_PageEntry); + } else { + /* 16 color ega */ + vga.mode=GFX_16; + VGA_PageEntry.base=0xA0000; + VGA_PageEntry.handler.read=VGA_NormalReadHandler; + VGA_PageEntry.handler.write=VGA_GFX_16_WriteHandler; + MEMORY_SetupHandler(0xA0000/4096,16,&VGA_PageEntry); + } + } else { + vga.mode=TEXT_16; + } + VGA_StartResize(); +} + +static void VGA_DoResize(void) { + vga.draw.resizing=false; + Bitu width,height,pitch; + RENDER_Handler * renderer; + + height=vga.config.vdisplayend+1; + if (vga.config.vline_height>0) { + height/=(vga.config.vline_height+1); + } + if (vga.config.vline_double) height>>=1; + width=vga.config.hdisplayend; + switch (vga.mode) { + case GFX_256C: + renderer=&VGA_Render_GFX_256C; + width<<=2; + pitch=vga.config.scan_len*8; + break; + case GFX_256U: + width<<=2; + pitch=vga.config.scan_len*8; + renderer=&VGA_Render_GFX_256U; + break; + case GFX_16: + width<<=3; + pitch=vga.config.scan_len*16; + renderer=&VGA_Render_GFX_16; + break; + case GFX_4: + width<<=3; + height<<=1; + pitch=width; + renderer=&VGA_Render_GFX_4; + break; + case TEXT_16: + /* probably a 16-color text mode, got to detect mono mode somehow */ + width<<=3; /* 8 bit wide text font */ + height<<=4; /* 16 bit font height */ + if (width>640) width=640; + if (height>480) height=480; + pitch=width; + renderer=&VGA_Render_TEXT_16; + }; + + vga.draw.width=width; + vga.draw.height=height; + RENDER_SetSize(width,height,8,pitch,((float)width/(float)height),0,renderer); + +}; + +void VGA_StartResize(void) { + if (!vga.draw.resizing) { + vga.draw.resizing=true; + /* Start a resize after 50 ms */ + TIMER_RegisterDelayHandler(VGA_DoResize,50); + } +} + + + + +void VGA_Init() { + vga.draw.resizing=false; + VGA_SetupMemory(); + VGA_SetupMisc(); + VGA_SetupDAC(); + VGA_SetupCRTC(); + VGA_SetupGFX(); + VGA_SetupSEQ(); + VGA_SetupAttr(); +/* Generate tables */ + Bit32u i; + for (i=0;i<256;i++) { + ExpandTable[i]=i | (i << 8)| (i <<16) | (i << 24); + CGAWriteTable[i]=((i>>6)&3) | (((i>>4)&3) << 8)| (((i>>2)&3) <<16) | (((i>>0)&3) << 24); + } +} + diff --git a/src/hardware/vga.h b/src/hardware/vga.h new file mode 100644 index 00000000..bd2985a1 --- /dev/null +++ b/src/hardware/vga.h @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef VGA_H_ +#define VGA_H_ + +#include + +enum { TEXT, GRAPH }; +enum { GFX_256C,GFX_256U,GFX_16,GFX_4,GFX_2, TEXT_16 }; + +typedef struct { + + bool attrindex; +} VGA_Internal; + +typedef struct { + +/* Video drawing */ + Bit16u display_start; + Bit16u real_start; + bool retrace; /* A retrace has started */ + Bitu scan_len; + +/* Screen resolution and memory mode */ + Bitu vdisplayend; + Bitu hdisplayend; + + bool chained; /* Enable or Disabled Chain 4 Mode */ + bool gfxmode; /* Yes or No Easy no */ + bool blinking; /* Attribute bit 7 is blinking */ + + bool vga_enabled; + bool cga_enabled; + + bool vline_double; + Bit8u vline_height; + + /* Pixel Scrolling */ + Bit8u pel_panning; /* Amount of pixels to skip when starting horizontal line */ + Bit8u hlines_skip; + Bit8u bytes_skip; + +/* Specific stuff memory write/read handling */ + Bit8u read_mode; + Bit8u write_mode; + Bit8u read_map_select; + Bit8u color_dont_care; + Bit8u color_compare; + Bit8u data_rotate; + Bit8u raster_op; + Bit8u enable_set_reset; + Bit8u set_reset; + + Bit32u full_bit_mask; + Bit32u full_map_mask; + +} VGA_Config; + +typedef struct { + bool resizing; + Bitu width; + Bitu height; + Bit8u font_height; + Bit8u cursor_enable; + Bit8u cursor_row; + Bit8u cursor_col; + Bit8u cursor_count; +} VGA_Draw; + + +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; +} 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_blank; + Bit8u end_vertical_blank; + Bit8u mode_control; + Bit8u line_compare; + + Bit8u index; +} 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; + +struct RGBEntry { + Bit8u red; + Bit8u green; + Bit8u blue; + Bit8u attr_entry; +}; + +typedef struct { + Bit8u bits; /* DAC bits, usually 6 or 8 */ + Bit8u pel_mask; + Bit8u pel_index; + Bit8u state; + Bit8u index; + Bitu first_changed; + RGBEntry rgb[0x100]; +} VGA_Dac; + +union VGA_Latch { + Bit32u d; + Bit8u b[4]; +}; + +union VGA_Memory { + Bit8u linear[64*1024*4]; + Bit8u paged[64*1024][4]; + VGA_Latch latched[64*1024]; +}; + + + +typedef struct { + Bitu mode; /* The mode the vga system is in */ + 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_Memory mem; +//Special little hack to let the memory run over into the buffer + Bit8u buffer[1024*1024]; +} VGA_Type; + + + + + +/* Functions for different resolutions */ +//void VGA_FindSize(void); +void VGA_FindSettings(void); +void VGA_StartResize(void); + +/* The Different Drawing functions */ +void VGA_DrawTEXT(Bit8u * bitdata,Bitu next_line); +void VGA_DrawGFX256_Fast(Bit8u * bitdata,Bitu next_line); +void VGA_DrawGFX256_Full(Bit8u * bitdata,Bitu next_line); +void VGA_DrawGFX16_Full(Bit8u * bitdata,Bitu next_line); +void VGA_DrawGFX4_Full(Bit8u * bitdata,Bitu next_line); +/* The Different Memory Read/Write Handlers */ +Bit8u VGA_NormalReadHandler(Bit32u start); +void VGA_NormalWriteHandler(Bit32u start,Bit8u val); + +void VGA_GFX_256U_WriteHandler(Bit32u start,Bit8u val); +void VGA_GFX_16_WriteHandler(Bit32u start,Bit8u val); +void VGA_GFX_4_WriteHandler(Bit32u start,Bit8u val); + +Bit8u VGA_ChainedReadHandler(Bit32u start); +void VGA_ChainedWriteHandler(Bit32u start,Bit8u val); + +Bit8u VGA_GFX_4_ReadHandler(Bit32u start); + + + +/* Some support functions */ +void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal); + + +/* The VGA Subfunction startups */ +void VGA_SetupAttr(void); +void VGA_SetupMemory(void); +void VGA_SetupDAC(void); +void VGA_SetupCRTC(void); +void VGA_SetupMisc(void); +void VGA_SetupGFX(void); +void VGA_SetupSEQ(void); + +/* Some Support Functions */ +void VGA_DACSetEntirePalette(void); + +extern VGA_Type vga; +extern Bit8u vga_rom_8[256 * 8]; +extern Bit8u vga_rom_14[256 * 14]; +extern Bit8u vga_rom_16[256 * 16]; +//extern Bit8u vga_buffer[1024*1024]; +extern Bit32u ExpandTable[256]; +extern Bit32u FillTable[16]; +extern Bit32u CGAWriteTable[256]; + +#endif + diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp new file mode 100644 index 00000000..4b0473f9 --- /dev/null +++ b/src/hardware/vga_attr.cpp @@ -0,0 +1,165 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "inout.h" +#include "vga.h" + +#define attr(blah) vga.attr.blah + +void write_p3c0(Bit32u port,Bit8u val) { + if (!vga.internal.attrindex) { + attr(index)=val & 0x1F; + vga.internal.attrindex=true; + /* + 0-4 Address of data register to write to port 3C0h or read from port 3C1h + If set screen output is enabled and the palette can not be modified, + if clear screen output is disabled and the palette can be modified. + */ + return; + } else { + vga.internal.attrindex=false; + switch (attr(index)) { + /* Palette */ + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x04: case 0x05: case 0x06: case 0x07: + case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x0c: case 0x0d: case 0x0e: case 0x0f: + attr(palette[attr(index)])=val; + VGA_DAC_CombineColor(attr(index),val); + /* + 0-5 Index into the 256 color DAC table. May be modified by 3C0h index + 10h and 14h. + */ + break; + case 0x10: /* Mode Control Register */ + attr(mode_control)=val; + vga.config.gfxmode=val&1; + vga.config.vga_enabled=(val & 64)>0; + VGA_FindSettings(); + //TODO Monochrome mode + //TODO 9 bit characters + //TODO line wrapping split screen shit see bit 5 + //TODO index 14h weirdo dac switch bits + /* + 0 Graphics mode if set, Alphanumeric mode else. + 1 Monochrome mode if set, color mode else. + 2 9-bit wide characters if set. + The 9th bit of characters C0h-DFh will be the same as + the 8th bit. Otherwise it will be the background color. + 3 If set Attribute bit 7 is blinking, else high intensity. + 5 If set the PEL panning register (3C0h index 13h) is temporarily set + to 0 from when the line compare causes a wrap around until the next + vertical retrace when the register is automatically reloaded with + the old value, else the PEL panning register ignores line compares. + 6 If set pixels are 8 bits wide. Used in 256 color modes. + 7 If set bit 4-5 of the index into the DAC table are taken from port + 3C0h index 14h bit 0-1, else the bits in the palette register are + used. + */ + if (val&128) { + E_Exit("VGA:Special 16 colour DAC Shift"); + } + break; + case 0x11: /* Overscan Color Register */ + attr(overscan_color)=val; + /* 0-5 Color of screen border. Color is defined as in the palette registers. */ + break; + case 0x12: /* Color Plane Enable Register */ + /* Why disable colour planes? */ + attr(color_plane_enable)=val; + /* + 0 Bit plane 0 is enabled if set. + 1 Bit plane 1 is enabled if set. + 2 Bit plane 2 is enabled if set. + 3 Bit plane 3 is enabled if set. + 4-5 Video Status MUX. Diagnostics use only. + Two attribute bits appear on bits 4 and 5 of the Input Status + Register 1 (3dAh). 0: Bit 2/0, 1: Bit 5/4, 2: bit 3/1, 3: bit 7/6 + */ + break; + case 0x13: /* Horizontal PEL Panning Register */ + attr(horizontal_pel_panning)=val & 0xF; + vga.config.pel_panning=val & 0xF; + /* + 0-3 Indicates number of pixels to shift the display left + Value 9bit textmode 256color mode Other modes + 0 1 0 0 + 1 2 n/a 1 + 2 3 1 2 + 3 4 n/a 3 + 4 5 2 4 + 5 6 n/a 5 + 6 7 3 6 + 7 8 n/a 7 + 8 0 n/a n/a + */ + break; + case 0x14: /* Color Select Register */ + attr(color_select)=val; + /* + 0-1 If 3C0h index 10h bit 7 is set these 2 bits are used as bits 4-5 of + the index into the DAC table. + 2-3 These 2 bits are used as bit 6-7 of the index into the DAC table + except in 256 color mode. + Note: this register does not affect 256 color modes. + */ + if (val) LOG_DEBUG("VGA:ATTR:DAC index set to %d",val); + break; + default: + LOG_ERROR("VGA:ATTR:Write to unkown Index %2X",attr(index)); + break; + } + } +} + +Bit8u read_p3c1(Bit32u port) { + switch (attr(index)) { + /* Palette */ + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x04: case 0x05: case 0x06: case 0x07: + case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x0c: case 0x0d: case 0x0e: case 0x0f: + return attr(palette[attr(index)]); + case 0x10: /* Mode Control Register */ + return attr(mode_control); + case 0x11: /* Overscan Color Register */ + return attr(overscan_color); + case 0x12: /* Color Plane Enable Register */ + return attr(color_plane_enable); + case 0x13: /* Horizontal PEL Panning Register */ + return attr(horizontal_pel_panning); + case 0x14: /* Color Select Register */ + return attr(color_select); + default: + LOG_ERROR("VGA:ATTR:Read from unkown Index %2X",attr(index)); + } + return 0; +}; + + + + + + +void VGA_SetupAttr(void) { + IO_RegisterWriteHandler(0x3c0,write_p3c0,"VGA Attribute controller"); + IO_RegisterReadHandler(0x3c1,read_p3c1,"VGA Attribute Read"); +} + + diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp new file mode 100644 index 00000000..99f1ac19 --- /dev/null +++ b/src/hardware/vga_crtc.cpp @@ -0,0 +1,332 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "inout.h" +#include "vga.h" + + + +#define crtc(blah) vga.crtc.blah + +void write_p3d4(Bit32u port,Bit8u val) { + crtc(index)=val; +} + +void write_p3d5(Bit32u port,Bit8u val) { + switch(crtc(index)) { + case 0x00: /* Horizontal Total Register */ + crtc(horizontal_total)=val; + /* 0-7 Horizontal Total Character Clocks-5 */ + break; + case 0x01: /* Horizontal Display End Register */ + crtc(horizontal_display_end)=val; + vga.config.hdisplayend=val+1; + VGA_FindSettings(); + /* 0-7 Number of Character Clocks Displayed -1 */ + break; + case 0x02: /* Start Horizontal Blanking Register */ + crtc(start_horizontal_blanking)=val; + /* 0-7 The count at which Horizontal Blanking starts */ + break; + case 0x03: /* End Horizontal Blanking Register */ + crtc(end_horizontal_blanking)=val; + /* + 0-4 Horizontal Blanking ends when the last 6 bits of the character + counter equals this field. Bit 5 is at 3d4h index 5 bit 7. + 5-6 Number of character clocks to delay start of display after Horizontal + Total has been reached. + 7 Access to Vertical Retrace registers if set. If clear reads to 3d4h + index 10h and 11h access the Lightpen read back registers ?? + */ + break; + case 0x04: /* Start Horizontal Retrace Register */ + crtc(start_horizontal_retrace)=val; + /* 0-7 Horizontal Retrace starts when the Character Counter reaches this value. */ + break; + case 0x05: /* End Horizontal Retrace Register */ + crtc(end_horizontal_retrace)=val; + /* + 0-4 Horizontal Retrace ends when the last 5 bits of the character counter + equals this value. + 5-6 Number of character clocks to delay start of display after Horizontal + Retrace. + 7 bit 5 of the End Horizontal Blanking count (See 3d4h index 3 bit 0-4) + */ + break; + case 0x06: /* Vertical Total Register */ + crtc(vertical_total)=val; + /* 0-7 Lower 8 bits of the Vertical Total. Bit 8 is found in 3d4h index 7 + bit 0. Bit 9 is found in 3d4h index 7 bit 5. + Note: For the VGA this value is the number of scan lines in the display -2. + */ + break; + case 0x07: /* Overflow Register */ + crtc(overflow)=val; + vga.config.vdisplayend=(vga.config.vdisplayend&0xFF)|((val&2)<<7)|((val&64)<<2); + VGA_FindSettings(); + /* + 0 Bit 8 of Vertical Total (3d4h index 6) + 1 Bit 8 of Vertical Display End (3d4h index 12h) + 2 Bit 8 of Vertical Retrace Start (3d4h index 10h) + 3 Bit 8 of Start Vertical Blanking (3d4h index 15h) + 4 Bit 8 of Line Compare Register (3d4h index 18h) + 5 Bit 9 of Vertical Total (3d4h index 6) + 6 Bit 9 of Vertical Display End (3d4h index 12h) + 7 Bit 9 of Vertical Retrace Start (3d4h index 10h) + */ + break; + case 0x08: /* Preset Row Scan Register */ + crtc(preset_row_scan)=val; + vga.config.hlines_skip=val&31; + vga.config.bytes_skip=(val>>5)&3; +// LOG_DEBUG("Skip lines %d bytes %d",vga.config.hlines_skip,vga.config.bytes_skip); + /* + 0-4 Number of lines we have scrolled down in the first character row. + Provides Smooth Vertical Scrolling.b + 5-6 Number of bytes to skip at the start of scanline. Provides Smooth + Horizontal Scrolling together with the Horizontal Panning Register + (3C0h index 13h). + */ + break; + case 0x09: /* Maximum Scan Line Register */ + crtc(maximum_scan_line)=val; + vga.config.vline_double=(val & 128)>1; + vga.config.vline_height=(val & 0xf); + VGA_FindSettings(); + /* + 0-4 Number of scan lines in a character row -1. In graphics modes this is + the number of times (-1) the line is displayed before passing on to + the next line (0: normal, 1: double, 2: triple...). + This is independent of bit 7, except in CGA modes which seems to + require this field to be 1 and bit 7 to be set to work. + 5 Bit 9 of Start Vertical Blanking + 6 Bit 9 of Line Compare Register + 7 Doubles each scan line if set. I.e. displays 200 lines on a 400 display. + */ + break; + case 0x0A: /* Cursor Start Register */ + crtc(cursor_start)=val; + /* + 0-4 First scanline of cursor within character. + 5 Turns Cursor off if set + */ + break; + case 0x0B: /* Cursor End Register */ + crtc(cursor_end)=val; + /* + 0-4 Last scanline of cursor within character + 5-6 Delay of cursor data in character clocks. + */ + break; + case 0x0C: /* Start Address High Register */ + crtc(start_address_high)=val; + vga.config.display_start=(vga.config.display_start & 0x00FF)| (val << 8); + /* 0-7 Upper 8 bits of the start address of the display buffer */ + break; + case 0x0D: /* Start Address Low Register */ + crtc(start_address_low)=val; + vga.config.display_start=(vga.config.display_start & 0xFF00)| val; + /* 0-7 Lower 8 bits of the start address of the display buffer */ + break; + case 0x0E: /*Cursor Location High Register */ + crtc(cursor_location_high)=val; + if (vga.config.scan_len<2) break; + vga.draw.cursor_row=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))/(vga.config.scan_len*2); + vga.draw.cursor_col=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))%(vga.config.scan_len*2); + /* 0-7 Upper 8 bits of the address of the cursor */ + break; + case 0x0F: /* Cursor Location Low Register */ +//TODO update cursor on screen + crtc(cursor_location_low)=val; + if (vga.config.scan_len<2) break; + vga.draw.cursor_row=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))/(vga.config.scan_len*2); + vga.draw.cursor_col=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))%(vga.config.scan_len*2); + /* 0-7 Lower 8 bits of the address of the cursor */ + break; + case 0x10: /* Vertical Retrace Start Register */ + crtc(vertical_retrace_start)=val; + /* + 0-7 Lower 8 bits of Vertical Retrace Start. Vertical Retrace starts when + the line counter reaches this value. Bit 8 is found in 3d4h index 7 + bit 2. Bit 9 is found in 3d4h index 7 bit 7. + */ + break; + case 0x11: /* Vertical Retrace End Register */ + crtc(vertical_retrace_end)=val; + /* + 0-3 Vertical Retrace ends when the last 4 bits of the line counter equals + this value. + 4 if clear Clears pending Vertical Interrupts. + 5 Vertical Interrupts (IRQ 2) disabled if set. Can usually be left + disabled, but some systems (including PS/2) require it to be enabled. + 6 If set selects 5 refresh cycles per scanline rather than 3. + 7 Disables writing to registers 0-7 if set 3d4h index 7 bit 4 is not + affected by this bit. + */ + break; + case 0x12: /* Vertical Display End Register */ + crtc(vertical_display_end)=val; + vga.config.vdisplayend=(vga.config.vdisplayend & 0x300)|val; + VGA_FindSettings(); + /* + 0-7 Lower 8 bits of Vertical Display End. The display ends when the line + counter reaches this value. Bit 8 is found in 3d4h index 7 bit 1. + Bit 9 is found in 3d4h index 7 bit 6. + */ + break; + case 0x13: /* Offset register */ + crtc(offset)=val; + vga.config.scan_len=val; + VGA_FindSettings(); + /* + 0-7 Number of bytes in a scanline / K. Where K is 2 for byte mode, 4 for + word mode and 8 for Double Word mode. + */ + break; + case 0x14: /* Underline Location Register */ + crtc(underline_location)=val; + /* + 0-4 Position of underline within Character cell. + 5 If set memory address is only changed every fourth character clock. + 6 Double Word mode addressing if set + */ + break; + case 0x15: /* Start Vertical Blank Register */ + crtc(start_vertical_blank)=val; + /* + 0-7 Lower 8 bits of Vertical Blank Start. Vertical blanking starts when + the line counter reaches this value. Bit 8 is found in 3d4h index 7 + bit 3. + */ + break; + case 0x16: /* End Vertical Blank Register */ + crtc(end_vertical_blank)=val; + /* + 0-6 Vertical blanking stops when the lower 7 bits of the line counter + equals this field. Some SVGA chips uses all 8 bits! + */ + break; + case 0x17: /* Mode Control Register */ + crtc(mode_control)=val; + vga.config.cga_enabled=!((val&1)>0); + VGA_FindSettings(); + /* + 0 If clear use CGA compatible memory addressing system + by substituting character row scan counter bit 0 for address bit 13, + thus creating 2 banks for even and odd scan lines. + 1 If clear use Hercules compatible memory addressing system by + substituting character row scan counter bit 1 for address bit 14, + thus creating 4 banks. + 2 If set increase scan line counter only every second line. + 3 If set increase memory address counter only every other character clock. + 5 When in Word Mode bit 15 is rotated to bit 0 if this bit is set else + bit 13 is rotated into bit 0. + 6 If clear system is in word mode. Addresses are rotated 1 position up + bringing either bit 13 or 15 into bit 0. + 7 Clearing this bit will reset the display system until the bit is set again. + */ + break; + case 0x18: /* Line Compare Register */ + crtc(line_compare)=val; + /* + 0-7 Lower 8 bits of the Line Compare. When the Line counter reaches this + value, the display address wraps to 0. Provides Split Screen + facilities. Bit 8 is found in 3d4h index 7 bit 4. + Bit 9 is found in 3d4h index 9 bit 6. + */ + + break; + default: + LOG_ERROR("VGA:CRTC:Write to unknown index %2X",val,crtc(index)); + } +} + +Bit8u read_p3d5(Bit32u port) { + switch(crtc(index)) { + case 0x00: /* Horizontal Total Register */ + return crtc(horizontal_total); + case 0x01: /* Horizontal Display End Register */ + return crtc(horizontal_display_end); + case 0x02: /* Start Horizontal Blanking Register */ + return crtc(start_horizontal_blanking); + case 0x03: /* End Horizontal Blanking Register */ + return crtc(end_horizontal_blanking); + case 0x04: /* Start Horizontal Retrace Register */ + return crtc(start_horizontal_retrace); + case 0x05: /* End Horizontal Retrace Register */ + return crtc(end_horizontal_retrace); + case 0x06: /* Vertical Total Register */ + return crtc(vertical_total); + case 0x07: /* Overflow Register */ + return crtc(overflow); + case 0x08: /* Preset Row Scan Register */ + return crtc(preset_row_scan); + case 0x09: /* Maximum Scan Line Register */ + return crtc(maximum_scan_line); + case 0x0A: /* Cursor Start Register */ + return crtc(cursor_start); + case 0x0B: /* Cursor End Register */ + return crtc(cursor_end); + case 0x0C: /* Start Address High Register */ + return crtc(start_address_high); + case 0x0D: /* Start Address Low Register */ + return crtc(start_address_low); + case 0x0E: /*Cursor Location High Register */ + return crtc(cursor_location_high); + case 0x0F: /* Cursor Location Low Register */ + return crtc(cursor_location_low); + case 0x10: /* Vertical Retrace Start Register */ + return crtc(vertical_retrace_start); + case 0x11: /* Vertical Retrace End Register */ + return crtc(vertical_retrace_end); + case 0x12: /* Vertical Display End Register */ + return crtc(vertical_display_end); + case 0x13: /* Offset register */ + return crtc(offset); + case 0x14: /* Underline Location Register */ + return crtc(underline_location); + case 0x15: /* Start Vertical Blank Register */ + return crtc(start_vertical_blank); + case 0x16: /* End Vertical Blank Register */ + return crtc(end_vertical_blank); + case 0x17: /* Mode Control Register */ + return crtc(mode_control); + case 0x18: /* Line Compare Register */ + return crtc(line_compare); + default: + LOG_ERROR("VGA:CRTC:Read from unknown index %X",crtc(index)); + } + return 0; +} + + + +void VGA_SetupCRTC(void) { + IO_RegisterWriteHandler(0x3d4,write_p3d4,"VGA:CRTC Index Select"); + IO_RegisterWriteHandler(0x3d5,write_p3d5,"VGA:CRTC Data Register"); + IO_RegisterReadHandler(0x3d5,read_p3d5,"VGA:CRTC Data Register"); + +// IO_RegisterWriteHandler(0x3b4,write_p3d4,"VGA:CRTC Index Select"); +// IO_RegisterWriteHandler(0x3b5,write_p3d5,"VGA:CRTC Data Register"); +// IO_RegisterReadHandler(0x3b5,read_p3d5,"VGA:CRTC Data Register"); + + + +} + diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp new file mode 100644 index 00000000..b161c86e --- /dev/null +++ b/src/hardware/vga_dac.cpp @@ -0,0 +1,160 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "inout.h" +#include "render.h" +#include "vga.h" + +/* +//TODO PEL Mask Maybe +//TODO Find some way to get palette lookups in groups +3C6h (R/W): PEL Mask +bit 0-7 This register is anded with the palette index sent for each dot. + Should be set to FFh. + +3C7h (R): DAC State Register +bit 0-1 0 indicates the DAC is in Write Mode and 3 indicates Read mode. + +3C7h (W): PEL Address Read Mode +bit 0-7 The PEL data register (0..255) to be read from 3C9h. +Note: After reading the 3 bytes at 3C9h this register will increment, + pointing to the next data register. + +3C8h (R/W): PEL Address Write Mode +bit 0-7 The PEL data register (0..255) to be written to 3C9h. +Note: After writing the 3 bytes at 3C9h this register will increment, pointing + to the next data register. + +3C9h (R/W): PEL Data Register +bit 0-5 Color value +Note: Each read or write of this register will cycle through first the + registers for Red, Blue and Green, then increment the appropriate + address register, thus the entire palette can be loaded by writing 0 to + the PEL Address Write Mode register 3C8h and then writing all 768 bytes + of the palette to this register. +*/ + +enum {DAC_READ,DAC_WRITE}; + + +static void write_p3c6(Bit32u port,Bit8u val) { + if (val!=0xff) LOG_ERROR("VGA:Pel Mask not 0xff"); +} + + +static void write_p3c7(Bit32u port,Bit8u val) { + vga.dac.index=val; + vga.dac.pel_index=0; + vga.dac.state=DAC_READ; +} + +static void write_p3c8(Bit32u port,Bit8u val) { + vga.dac.index=val; + vga.dac.pel_index=0; + vga.dac.state=DAC_WRITE; +} + +static void write_p3c9(Bit32u port,Bit8u val) { + switch (vga.dac.pel_index) { + case 0: + vga.dac.rgb[vga.dac.index].red=val; + vga.dac.pel_index=1; + break; + case 1: + vga.dac.rgb[vga.dac.index].green=val; + vga.dac.pel_index=2; + break; + case 2: + vga.dac.rgb[vga.dac.index].blue=val; + switch (vga.mode) { + case GFX_256C: + case GFX_256U: + RENDER_SetPal(vga.dac.index, + vga.dac.rgb[vga.dac.index].red << 2, + vga.dac.rgb[vga.dac.index].green << 2, + vga.dac.rgb[vga.dac.index].blue << 2 + ); + break; + default: + /* Check for attributes and DAC entry link */ + if (vga.dac.rgb[vga.dac.index].attr_entry>15) return; + if (vga.attr.palette[vga.dac.rgb[vga.dac.index].attr_entry]==vga.dac.index) { + RENDER_SetPal(vga.dac.rgb[vga.dac.index].attr_entry, + vga.dac.rgb[vga.dac.index].red << 2, + vga.dac.rgb[vga.dac.index].green << 2, + vga.dac.rgb[vga.dac.index].blue << 2 + ); + } + } + vga.dac.index++; + vga.dac.pel_index=0; + break; + default: + LOG_ERROR("VGA:DAC:Illegal Pel Index"); //If this can actually happen that will be the day + }; +} + +static Bit8u read_p3c9(Bit32u port) { + Bit8u ret; + switch (vga.dac.pel_index) { + case 0: + ret=vga.dac.rgb[vga.dac.index].red; + vga.dac.pel_index=1; + break; + case 1: + ret=vga.dac.rgb[vga.dac.index].green; + vga.dac.pel_index=2; + break; + case 2: + ret=vga.dac.rgb[vga.dac.index].blue; + vga.dac.index++; + vga.dac.pel_index=0; + break; + default: + LOG_ERROR("VGA:DAC:Illegal Pel Index"); //If this can actually happen that will be the day + } + return ret; +} + +void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal) { + /* Check if this is a new color */ + vga.dac.rgb[pal].attr_entry=attr; + RENDER_SetPal(attr, + vga.dac.rgb[pal].red << 2, + vga.dac.rgb[pal].green << 2, + vga.dac.rgb[pal].blue << 2 + ); +} + +void VGA_SetupDAC(void) { + vga.dac.first_changed=256; + vga.dac.bits=6; + vga.dac.pel_mask=0xff; + vga.dac.pel_index=0; + vga.dac.state=DAC_READ; + + /* Setup the DAC IO port Handlers */ + IO_RegisterWriteHandler(0x3c6,write_p3c6,"PEL Mask"); + IO_RegisterWriteHandler(0x3c7,write_p3c7,"PEL Read Mode"); + IO_RegisterWriteHandler(0x3c8,write_p3c8,"PEL Write Mode"); + IO_RegisterWriteHandler(0x3c9,write_p3c9,"PEL Data"); + IO_RegisterReadHandler(0x3c9,read_p3c9,"PEL Data"); +}; + + diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp new file mode 100644 index 00000000..c8f859f9 --- /dev/null +++ b/src/hardware/vga_draw.cpp @@ -0,0 +1,165 @@ +/* + * 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. + */ + +#include +#include "dosbox.h" +#include "video.h" +#include "vga.h" + + +/* This Should draw a complete 16 colour screen */ + +void VGA_Render_GFX_4(Bit8u * * data) { + *data=vga.buffer; + VGA_DrawGFX4_Full(vga.buffer,vga.draw.width); + vga.config.retrace=true; +} + +void VGA_Render_GFX_16(Bit8u * * data) { + *data=&vga.buffer[vga.config.display_start*8+vga.config.pel_panning]; + vga.config.retrace=true; +} + +void VGA_Render_GFX_256U(Bit8u * * data) { + *data=&vga.mem.linear[vga.config.display_start*4+vga.config.pel_panning]; + vga.config.retrace=true; +} + +void VGA_Render_GFX_256C(Bit8u * * data) { + *data=memory+0xa0000; + vga.config.retrace=true; +} + +void VGA_Render_TEXT_16(Bit8u * * data) { + *data=vga.buffer; + VGA_DrawTEXT(vga.buffer,vga.draw.width); + vga.config.retrace=true; +} + + + + +void VGA_DrawGFX4_Full(Bit8u * bitdata,Bitu next_line) { + //TODO use vga memory handler + Bit8u * reader=real_host(0xB800,0); + Bit8u * draw; + for (Bitu y=0;y>2;x++) { + Bit8u val=*(tempread++); +/* + *(draw+0)=(val>>6)&3; + *(draw+1)=(val>>4)&3; + *(draw+2)=(val>>2)&3; + *(draw+3)=(val)&3; + draw+=4; +*/ + *(Bit32u *)draw=CGAWriteTable[val]; + draw+=4; + } + //TODO use scanline length and dword mode crap + bitdata+=next_line; + }; + vga.config.retrace=true; +} + +void VGA_DrawGFX16_Full(Bit8u * bitdata,Bitu next_line) { + Bit8u * reader=&vga.buffer[vga.config.display_start*8+vga.config.pel_panning]; + for (Bitu y=0;y>2;x++) { + for (Bit32u dx=0;dx<4;dx++) { + (*bitdata++)=vga.mem.paged[xreader][dx]; + } + xreader++; + } + //TODO use scanline length and dword mode crap + yreader+=vga.config.scan_len*2; + bitdata+=next_line; + }; + vga.config.retrace=true; +}; + +void VGA_DrawGFX256_Fast(Bit8u * bitdata,Bitu next_line) { + /* For now just copy 64 kb of memory with pitch support */ + Bit8u * reader=memory+0xa0000; + for (Bitu y=0;y> 4); + Bit8u * draw=draw_char; + for (Bitu y=0;y<16;y++) { + Bit8u bit_mask=*findex++; + #include "font-switch.h" + draw+=+next_line; + }; + draw_char+=8; + }; + draw_start+=16*next_line; + }; + vga.config.retrace=true; + + /* Draw a cursor */ + if ((vga.draw.cursor_col*8)>=vga.draw.width) return; + if ((vga.draw.cursor_row*16)>=vga.draw.height) return; + Bit8u * cursor_draw=bitdata+(vga.draw.cursor_row*16+15)*vga.draw.width+vga.draw.cursor_col*8; + if (vga.draw.cursor_count>8) { + for (Bit8u loop=0;loop<8;loop++) *cursor_draw++=15; + } + vga.draw.cursor_count++; + if (vga.draw.cursor_count>16) vga.draw.cursor_count=0; +}; + diff --git a/src/hardware/vga_fonts.cpp b/src/hardware/vga_fonts.cpp new file mode 100644 index 00000000..bba9b327 --- /dev/null +++ b/src/hardware/vga_fonts.cpp @@ -0,0 +1,1254 @@ +/* + * 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. + */ + +/* + * Bitmap fonts for the VGA emulation; taken from + * ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip + * + * See copyleft_vgafonts.txt for the copyright notice. + */ +#include "dosbox.h" +#include "mem.h" +#include "vga.h" + +Bit8u vga_rom_08[256 * 8] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, + 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, + 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, + 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, + 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c, + 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, + 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, + 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, + 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, + 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, + 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, + 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0, + 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, + 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99, + 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, + 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, + 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, + 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, + 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, + 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff, + 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, + 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, + 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, + 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, + 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, + 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, + 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00, + 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, + 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, + 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, + 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, + 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, + 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, + 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, + 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, + 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, + 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00, + 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, + 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00, + 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, + 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, + 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00, + 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, + 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, + 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, + 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, + 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, + 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, + 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, + 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00, + 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, + 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, + 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, + 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00, + 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, + 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, + 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, + 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, + 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, + 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, + 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, + 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, + 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00, + 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, + 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00, + 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, + 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00, + 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, + 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, + 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, + 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, + 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00, + 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, + 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, + 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, + 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00, + 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, + 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, + 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00, + 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, + 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00, + 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, + 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00, + 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, + 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00, + 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, + 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78, + 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00, + 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, + 0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, + 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, + 0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38, + 0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00, + 0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, + 0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, + 0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00, + 0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00, + 0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00, + 0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00, + 0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00, + 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, + 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18, + 0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00, + 0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30, + 0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7, + 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70, + 0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, + 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00, + 0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00, + 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, + 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, + 0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, + 0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f, + 0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03, + 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00, + 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00, + 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, + 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, + 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00, + 0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0, + 0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, + 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, + 0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00, + 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0, + 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00, + 0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc, + 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00, + 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00, + 0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, + 0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0, + 0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00, + 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, + 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00, + 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00, + 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, + 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00, + 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, + 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, + 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, + 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, + 0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, + 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +Bit8u vga_rom_14[256 * 14] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, + 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, + 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, + 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, + 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, + 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, + 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, + 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, + 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, + 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x70, 0xf0, + 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, + 0x7f, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, + 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, 0xf8, + 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x06, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x06, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, + 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, + 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x7c, + 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, + 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, + 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, + 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, + 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, + 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, + 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, + 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x66, + 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, + 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, + 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, + 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, + 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, + 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, + 0x3c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, + 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x60, + 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x0c, + 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, + 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x0c, + 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, + 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, + 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, + 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, + 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, + 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, + 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, + 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, + 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, + 0xc0, 0xde, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, + 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe6, 0x66, 0x6c, 0x6c, + 0x78, 0x6c, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, + 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, + 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xe6, + 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, + 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, + 0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, + 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, + 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, + 0xd6, 0xd6, 0xfe, 0x7c, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x38, + 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, + 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, + 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, + 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x3c, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, + 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, + 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, + 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, + 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, + 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, + 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, + 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, + 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, + 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, + 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, + 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, + 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, + 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, + 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, + 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, + 0xc6, 0x70, 0x1c, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, + 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, + 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, + 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, + 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x66, 0xfe, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, + 0x70, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, + 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, + 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc2, + 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, 0x00, + 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0x76, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, + 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, + 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x78, 0x0c, 0x7c, + 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, + 0x76, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, + 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, + 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, + 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xcc, 0xcc, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, + 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x38, + 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, + 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, + 0x3c, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x10, + 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, + 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, + 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, + 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, + 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xce, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, + 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, + 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0xcc, + 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, + 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, + 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, 0x00, 0xc6, + 0xc6, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, + 0x38, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x00, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, + 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, + 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, + 0x18, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, 0xcc, + 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xc6, 0x00, + 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, + 0x7e, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, + 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x0c, + 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, + 0x3c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, + 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, + 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x76, 0xdc, + 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, + 0xc6, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, + 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, + 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, + 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, + 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x66, + 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x3c, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, + 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x55, 0xaa, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, + 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, + 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, + 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, + 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, + 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, + 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, + 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xfc, 0xc6, 0xc6, 0xfc, + 0xc0, 0xc0, 0x40, 0x00, 0x00, 0x00, 0xfe, 0xc6, + 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, + 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, + 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, + 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, + 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, + 0x3e, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, + 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, + 0x60, 0x60, 0x7c, 0x60, 0x60, 0x30, 0x1c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, + 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, + 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, + 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, + 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0xec, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +Bit8u vga_rom_16[256 * 16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, + 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, + 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, + 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, + 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, + 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, + 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, + 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, + 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, + 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, + 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, + 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, + 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, + 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, + 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, + 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, + 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, + 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, + 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, + 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, + 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, + 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, + 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, + 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, + 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, + 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, + 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, + 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, + 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, + 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, + 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, + 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, + 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, + 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, + 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, + 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, + 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, + 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, + 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, + 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, + 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, + 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, + 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, + 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, + 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, + 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, + 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, + 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, + 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, + 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, + 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, + 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, + 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, + 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, + 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, + 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, + 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, + 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, + 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, + 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, + 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, + 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, + 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, + 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, + 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, + 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, + 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, + 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, + 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, + 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, + 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, + 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, + 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, + 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, + 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, + 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, + 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, + 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, + 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, + 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, + 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, + 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, + 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, + 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, + 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, + 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, + 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, + 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, + 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, + 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, + 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, + 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, + 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, + 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, + 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, + 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, + 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, + 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, + 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, + 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, + 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, + 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, + 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, + 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, + 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, + 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, + 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, + 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, + 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, + 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, + 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, + 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, + 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, + 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, + 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, + 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, + 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, + 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, + 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, + 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, + 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, + 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, + 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, + 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, + 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, + 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, + 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, + 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + + diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp new file mode 100644 index 00000000..ddbb133b --- /dev/null +++ b/src/hardware/vga_gfx.cpp @@ -0,0 +1,221 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "inout.h" +#include "vga.h" + + +#define gfx(blah) vga.gfx.blah +static bool index9warned=false; + +void write_p3ce(Bit32u port,Bit8u val) { + gfx(index)=val & 0x0f; +} + +Bit8u read_p3ce(Bit32u port) { + return gfx(index); +} + +void write_p3cf(Bit32u port,Bit8u val) { + switch (gfx(index)) { + case 0: /* Set/Reset Register */ + gfx(set_reset)=val & 0x0f; + vga.config.set_reset=val & 0x0f; + /* + 0 If in Write Mode 0 and bit 0 of 3CEh index 1 is set a write to + display memory will set all the bits in plane 0 of the byte to this + bit, if the corresponding bit is set in the Map Mask Register (3CEh + index 8). + 1 Same for plane 1 and bit 1 of 3CEh index 1. + 2 Same for plane 2 and bit 2 of 3CEh index 1. + 3 Same for plane 3 and bit 3 of 3CEh index 1. + */ +// LOG_DEBUG("Set Reset = %2X",val); + break; + case 1: /* Enable Set/Reset Register */ + gfx(enable_set_reset)=val & 0x0f; + vga.config.enable_set_reset=val & 0x0f; + /* + 0 If set enables Set/reset of plane 0 in Write Mode 0. + 1 Same for plane 1. + 2 Same for plane 2. + 3 Same for plane 3. + */ +// LOG_DEBUG("Enable Set Reset = %2X",val); + break; + case 2: /* Color Compare Register */ + gfx(color_compare)=val & 0x0f; + /* + 0-3 In Read Mode 1 each pixel at the address of the byte read is compared + to this color and the corresponding bit in the output set to 1 if + they match, 0 if not. The Color Don't Care Register (3CEh index 7) + can exclude bitplanes from the comparison. + */ + vga.config.color_compare=val & 0xf; +// LOG_DEBUG("Color Compare = %2X",val); + break; + case 3: /* Data Rotate */ + gfx(data_rotate)=val; + vga.config.data_rotate=val & 7; + vga.config.raster_op=(val>>3) & 3; + /* + 0-2 Number of positions to rotate data right before it is written to + display memory. Only active in Write Mode 0. + 3-4 In Write Mode 2 this field controls the relation between the data + written from the CPU, the data latched from the previous read and the + data written to display memory: + 0: CPU Data is written unmodified + 1: CPU data is ANDed with the latched data + 2: CPU data is ORed with the latch data. + 3: CPU data is XORed with the latched data. + */ +// if (vga.config.data_rotate || vga.config.raster_op ) LOG_DEBUG("Data Rotate = %2X Raster op %2X",val & 7,(val>>3) & 3 ); + break; + case 4: /* Read Map Select Register */ + /* 0-1 number of the plane Read Mode 0 will read from */ + gfx(read_map_select)=val & 0x03; + vga.config.read_map_select=val & 0x03; +// LOG_DEBUG("Read Map %2X",val); + break; + case 5: /* Mode Register */ /* Important one very */ + gfx(mode)=val; + vga.config.write_mode=val & 3; + vga.config.read_mode=(val >> 3) & 1; +// LOG_DEBUG("Write Mode %d Read Mode %d val %d",vga.config.write_mode,vga.config.read_mode,val); + /* + 0-1 Write Mode: Controls how data from the CPU is transformed before + being written to display memory: + 0: Mode 0 works as a Read-Modify-Write operation. + First a read access loads the data latches of the VGA with the + value in video memory at the addressed location. Then a write + access will provide the destination address and the CPU data + byte. The data written is modified by the function code in the + Data Rotate register (3CEh index 3) as a function of the CPU + data and the latches, then data is rotated as specified by the + same register. + 1: Mode 1 is used for video to video transfers. + A read access will load the data latches with the contents of + the addressed byte of video memory. A write access will write + the contents of the latches to the addressed byte. Thus a single + MOVSB instruction can copy all pixels in the source address byte + to the destination address. + 2: Mode 2 writes a color to all pixels in the addressed byte of + video memory. Bit 0 of the CPU data is written to plane 0 et + cetera. Individual bits can be enabled or disabled through the + Bit Mask register (3CEh index 8). + 3: Mode 3 can be used to fill an area with a color and pattern. The + CPU data is rotated according to 3CEh index 3 bits 0-2 and anded + with the Bit Mask Register (3CEh index 8). For each bit in the + result the corresponding pixel is set to the color in the + Set/Reset Register (3CEh index 0 bits 0-3) if the bit is set and + to the contents of the processor latch if the bit is clear. + 3 Read Mode + 0: Data is read from one of 4 bit planes depending on the Read Map + Select Register (3CEh index 4). + 1: Data returned is a comparison between the 8 pixels occupying the + read byte and the color in the Color Compare Register (3CEh + index 2). A bit is set if the color of the corresponding pixel + matches the register. + 4 Enables Odd/Even mode if set (See 3C4h index 4 bit 2). + 5 Enables CGA style 4 color pixels using even/odd bit pairs if set. + 6 Enables 256 color mode if set. + + */ + break; + case 6: /* Miscellaneous Register */ + gfx(miscellaneous)=val; + /* + 0 Indicates Graphics Mode if set, Alphanumeric mode else. + 1 Enables Odd/Even mode if set. + 2-3 Memory Mapping: + 0: use A000h-BFFFh + 1: use A000h-AFFFh VGA Graphics modes + 2: use B000h-B7FFh Monochrome modes + 3: use B800h-BFFFh CGA modes + */ + break; + case 7: /* Color Don't Care Register */ + gfx(color_dont_care)=val & 0x0f; + /* + 0 Ignore bit plane 0 in Read mode 1 if clear. + 1 Ignore bit plane 1 in Read mode 1 if clear. + 2 Ignore bit plane 2 in Read mode 1 if clear. + 3 Ignore bit plane 3 in Read mode 1 if clear. + */ + vga.config.color_dont_care=val & 0xf; +// LOG_DEBUG("Color don't care = %2X",val); + break; + case 8: /* Bit Mask Register */ + gfx(bit_mask)=val; + vga.config.full_bit_mask=ExpandTable[val]; +// LOG_DEBUG("Bit mask %2X",val); + /* + 0-7 Each bit if set enables writing to the corresponding bit of a byte in + display memory. + */ + break; + case 9: /* Unknown */ + /* Crystal Dreams seems to like to write tothis register very weird */ + if (!index9warned) { + LOG_WARN("VGA:3CF:Write %2X to illegal index 9",val); + index9warned=true; + } + break; + default: + LOG_WARN("VGA:3CF:Write %2X to illegal index %2X",val,gfx(index)); + break; + } +} + +Bit8u read_p3cf(Bit32u port) { +switch (gfx(index)) { + case 0: /* Set/Reset Register */ + return gfx(set_reset); + case 1: /* Enable Set/Reset Register */ + return gfx(enable_set_reset); + case 2: /* Color Compare Register */ + return gfx(color_compare); + case 3: /* Data Rotate */ + return gfx(data_rotate); + case 4: /* Read Map Select Register */ + return gfx(read_map_select); + case 5: /* Mode Register */ + return gfx(mode); + case 6: /* Miscellaneous Register */ + return gfx(miscellaneous); + case 7: /* Color Don't Care Register */ + return gfx(color_dont_care); + case 8: /* Bit Mask Register */ + return gfx(bit_mask); + default: + LOG_WARN("Reading from illegal index %2X in port %4X",gfx(index),port); + } + return 0; /* Compiler happy */ +} + + + +void VGA_SetupGFX(void) { + IO_RegisterWriteHandler(0x3ce,write_p3ce,"VGA Graphics Index"); + IO_RegisterWriteHandler(0x3cf,write_p3cf,"VGA Graphics Data"); + IO_RegisterReadHandler(0x3ce,read_p3ce,"Vga Graphics Index"); + IO_RegisterReadHandler(0x3cf,read_p3cf,"Vga Graphics Data"); +} + + diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp new file mode 100644 index 00000000..ffd2f0a8 --- /dev/null +++ b/src/hardware/vga_memory.cpp @@ -0,0 +1,214 @@ +/* + * 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. + */ + + + + +#include +#include +#include "dosbox.h" +#include "mem.h" +#include "vga.h" + + +Bit8u VGA_ChainedReadHandler(Bit32u start) { + return vga.mem.linear[start]; +} + +void VGA_ChainedWriteHandler(Bit32u start,Bit8u val) { + vga.mem.linear[start]=val; +}; + + +Bit8u VGA_NormalReadHandler(Bit32u start) { + vga.latch.d=vga.mem.latched[start].d; + switch (vga.config.read_mode) { + case 0: + return(vga.latch.b[vga.config.read_map_select]); + case 1: + VGA_Latch templatch; + templatch.d=(vga.latch.d & FillTable[vga.config.color_dont_care]) ^ FillTable[vga.config.color_compare & vga.config.color_dont_care]; + return ~(templatch.b[0] | templatch.b[1] | templatch.b[2] | templatch.b[3]); + } + return 0; +} + +//Nice one from DosEmu +INLINE Bit32u RasterOp(Bit32u input,Bit32u mask) { + switch (vga.config.raster_op) { + case 0x00: /* None */ + return (input & mask) | (vga.latch.d & ~mask); + case 0x01: /* AND */ + return (input | ~mask) & vga.latch.d; + case 0x02: /* OR */ + return (input & mask) | vga.latch.d; + case 0x03: /* XOR */ + return (input & mask) ^ vga.latch.d; + }; + return 0; +} + +Bit8u VGA_GFX_4_ReadHandler(Bit32u start) { + return vga.mem.linear[start]; +} + +void VGA_GFX_4_WriteHandler(Bit32u start,Bit8u val) { + vga.mem.linear[start]=val; + Bitu line=start / 320; + Bitu x=start % 320; + Bit8u * draw=&vga.buffer[start<<2]; + /* TODO Could also use a Bit32u lookup table for this */ + *(draw+0)=(val>>6)&3; + *(draw+1)=(val>>4)&3; + *(draw+2)=(val>>2)&3; + *(draw+3)=(val)&3; +} + +void VGA_GFX_16_WriteHandler(Bit32u start,Bit8u val) { + VGA_Latch new_latch; + Bitu bit_mask; + switch (vga.config.write_mode) { + case 0x00: + // Write Mode 0: In this mode, the host data is first rotated as per the Rotate Count field, then the Enable Set/Reset mechanism selects data from this or the Set/Reset field. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory. +// val=(val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate)); + //Todo could also include the rotation in the table :) + new_latch.d=ExpandTable[val]; + { + Bit32u resetmask=FillTable[vga.config.enable_set_reset]; + new_latch.d=(new_latch.d & ~resetmask) | ( FillTable[vga.config.set_reset] & resetmask); + }; + new_latch.d=RasterOp(new_latch.d,vga.config.full_bit_mask); + bit_mask=vga.gfx.bit_mask; + break; + case 0x01: + // Write Mode 1: In this mode, data is transferred directly from the 32 bit latch register to display memory, affected only by the Memory Plane Write Enable field. The host data is not used in this mode. + new_latch.d=vga.latch.d; + bit_mask=0xff; + break; + case 0x02: + //Write Mode 2: In this mode, the bits 3-0 of the host data are replicated across all 8 bits of their respective planes. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory. + new_latch.d=RasterOp(FillTable[val&0xF],vga.config.full_bit_mask); + bit_mask=vga.gfx.bit_mask; + break; + case 0x03: + // Write Mode 3: In this mode, the data in the Set/Reset field is used as if the Enable Set/Reset field were set to 1111b. Then the host data is first rotated as per the Rotate Count field, then logical ANDed with the value of the Bit Mask field. The resulting value is used on the data obtained from the Set/Reset field in the same way that the Bit Mask field would ordinarily be used. to select which bits come from the expansion of the Set/Reset field and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory. + new_latch.d=ExpandTable[val]; + new_latch.d&=vga.config.full_bit_mask; //Dunno would anyone use this seems a bit pointless + bit_mask=new_latch.b[0]; + new_latch.d=RasterOp(FillTable[vga.config.set_reset],new_latch.d); + break; + default: + LOG_ERROR("VGA:Unsupported write mode %d",vga.config.write_mode); + } + /* Update video memory and the pixel buffer */ + VGA_Latch pixels; + pixels.d=vga.mem.latched[start].d; + pixels.d&=~vga.config.full_map_mask; + pixels.d|=(new_latch.d & vga.config.full_map_mask); + vga.mem.latched[start].d=pixels.d; + Bit8u * write_pixels=&vga.buffer[start<<3]; +#if 1 + Bit8u sel=128; + do { + if (bit_mask & sel) { + Bitu color; + color=0; + if (pixels.b[0] & sel) color|=1; + if (pixels.b[1] & sel) color|=2; + if (pixels.b[2] & sel) color|=4; + if (pixels.b[3] & sel) color|=8; + *write_pixels=color; + *(write_pixels+512*1024)=color; + + } + write_pixels++; + sel>>=1; + } while (sel); +#else +#include "ega-switch.h" +#endif + +} + + + + +void VGA_GFX_256U_WriteHandler(Bit32u start,Bit8u val) { + VGA_Latch new_latch; + switch (vga.config.write_mode) { + case 0x00: + /* This should be no problem with big or little endian */ + // Write Mode 0: In this mode, the host data is first rotated as per the Rotate Count field, then the Enable Set/Reset mechanism selects data from this or the Set/Reset field. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory. +// val=(val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate)); + //Todo could also include the rotation in the table :) + new_latch.d=ExpandTable[val]; + { + Bit32u resetmask=FillTable[vga.config.enable_set_reset]; + new_latch.d=(new_latch.d & ~resetmask) | ( FillTable[vga.config.set_reset] & resetmask); + }; + new_latch.d=RasterOp(new_latch.d,vga.config.full_bit_mask); + break; + case 0x01: + // Write Mode 1: In this mode, data is transferred directly from the 32 bit latch register to display memory, affected only by the Memory Plane Write Enable field. The host data is not used in this mode. + new_latch.d=vga.latch.d; + break; + case 0x02: + //TODO this mode also has Raster op + //Write Mode 2: In this mode, the bits 3-0 of the host data are replicated across all 8 bits of their respective planes. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory. + new_latch.d=RasterOp(FillTable[val&0xF],vga.config.full_bit_mask); + break; + case 0x03: + // Write Mode 3: In this mode, the data in the Set/Reset field is used as if the Enable Set/Reset field were set to 1111b. Then the host data is first rotated as per the Rotate Count field, then logical ANDed with the value of the Bit Mask field. The resulting value is used on the data obtained from the Set/Reset field in the same way that the Bit Mask field would ordinarily be used. to select which bits come from the expansion of the Set/Reset field and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory. + new_latch.d=ExpandTable[val]; + new_latch.d&=vga.config.full_bit_mask; //Dunno would anyone use this seems a bit pointless + new_latch.d=RasterOp(FillTable[vga.config.set_reset],new_latch.d); + break; + default: + E_Exit("VGA:Unsupported write mode %d",vga.config.write_mode); + } + VGA_Latch pixels; + pixels.d=vga.mem.latched[start].d; + pixels.d&=~vga.config.full_map_mask; + pixels.d|=(new_latch.d & vga.config.full_map_mask); + vga.mem.latched[start].d=pixels.d; + vga.mem.latched[start+64*1024].d=pixels.d; + +}; + + + + + + + + + + + + + + + + +void VGA_SetupMemory() { + memset((void *)&vga.mem,0,256*1024); + /* Alocate Video Memory */ + /* Not needed for VGA memory it gets allocated together with emulator maybe + later for VESA memory */ + +} diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp new file mode 100644 index 00000000..c1d6f19e --- /dev/null +++ b/src/hardware/vga_misc.cpp @@ -0,0 +1,70 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "inout.h" +#include "timer.h" +#include "vga.h" + +static Bit8u flip=0; +static Bit32u keep_vretrace; +static bool keeping=false; +static Bit8u p3c2data; + +static Bit8u read_p3da(Bit32u port) { + vga.internal.attrindex=false; + if (vga.config.retrace) { + vga.config.retrace=false; + vga.config.real_start=vga.config.display_start; + keep_vretrace=LastTicks+1; + keeping=true; + flip=0; + return 9; + } + if (keeping) { + if (LastTicks>(keep_vretrace)) keeping=false; + return 9; + } else { + flip++; + if (flip>10) flip=0; + if (flip>5) return 1; + return 0; + } +}; + + +static void write_p3d8(Bit32u port,Bit8u val) { + return; +} + +static void write_p3c2(Bit32u port,Bit8u val) { + p3c2data=val; +} +static Bit8u read_p3c2(Bit32u port) { + return p3c2data; +} + + +void VGA_SetupMisc(void) { + IO_RegisterReadHandler(0x3da,read_p3da,"VGA Input Status 1"); +// IO_RegisterWriteHandler(0x3d8,write_p3d8,"VGA Mode Control"); + IO_RegisterWriteHandler(0x3c2,write_p3c2,"VGA Misc Output"); + IO_RegisterReadHandler(0x3c2,read_p3c2,"VGA Misc Output"); +} + + diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp new file mode 100644 index 00000000..ce5e0cfd --- /dev/null +++ b/src/hardware/vga_seq.cpp @@ -0,0 +1,125 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "inout.h" +#include "vga.h" + +#define seq(blah) vga.seq.blah + +Bit8u read_p3c4(Bit32u port) { + return seq(index); +} + +void write_p3c4(Bit32u port,Bit8u val) { + seq(index)=val; +}; + +void write_p3c5(Bit32u port,Bit8u val) { + switch(seq(index)) { + case 0: /* Reset */ + seq(reset)=val; + break; + case 1: /* Clocking Mode */ + seq(clocking_mode)=val; + /* TODO Figure this out :) + 0 If set character clocks are 8 dots wide, else 9. + 2 If set loads video serializers every other character + clock cycle, else every one. + 3 If set the Dot Clock is Master Clock/2, else same as Master Clock + (See 3C2h bit 2-3). (Doubles pixels). Note: on some SVGA chipsets + this bit also affects the Sequencer mode. + 4 If set loads video serializers every fourth character clock cycle, + else every one. + 5 if set turns off screen and gives all memory cycles to the CPU + interface. + */ + break; + case 2: /* Map Mask */ + seq(map_mask)=val & 15; + vga.config.full_map_mask=FillTable[val & 15]; + /* + 0 Enable writes to plane 0 if set + 1 Enable writes to plane 1 if set + 2 Enable writes to plane 2 if set + 3 Enable writes to plane 3 if set + */ + break; + case 3: /* Character Map Select */ + seq(character_map_select)=val; + /* + 0,1,4 Selects VGA Character Map (0..7) if bit 3 of the character + attribute is clear. + 2,3,5 Selects VGA Character Map (0..7) if bit 3 of the character + attribute is set. + Note: Character Maps are placed as follows: + Map 0 at 0k, 1 at 16k, 2 at 32k, 3: 48k, 4: 8k, 5: 24k, 6: 40k, 7: 56k + */ + break; + case 4: /* Memory Mode */ + /* + 0 Set if in an alphanumeric mode, clear in graphics modes. + 1 Set if more than 64kbytes on the adapter. + 2 Enables Odd/Even addressing mode if set. Odd/Even mode places all odd + bytes in plane 1&3, and all even bytes in plane 0&2. + 3 If set address bit 0-1 selects video memory planes (256 color mode), + rather than the Map Mask and Read Map Select Registers. + */ + seq(memory_mode)=val; + /* Changing this means changing the VGA Memory Read/Write Handler */ + if (val&0x08) vga.config.chained=true; + else vga.config.chained=false; + VGA_FindSettings(); + break; + default: + LOG_ERROR("VGA:SEQ:Write to illegal index %2X",seq(index)); + }; +}; + + +Bit8u read_p3c5(Bit32u port) { + switch(seq(index)) { + case 0: /* Reset */ + return seq(reset); + break; + case 1: /* Clocking Mode */ + return seq(clocking_mode); + break; + case 2: /* Map Mask */ + return seq(map_mask); + break; + case 3: /* Character Map Select */ + return seq(character_map_select); + break; + case 4: /* Memory Mode */ + return seq(memory_mode); + default: + LOG_ERROR("VGA:SEQ:Read from illegal index %2X",seq(index)); + }; + return 0; +}; + + +void VGA_SetupSEQ(void) { + IO_RegisterWriteHandler(0x3c4,write_p3c4,"VGA:Sequencer Index"); + IO_RegisterWriteHandler(0x3c5,write_p3c5,"VGA:Sequencer Data"); + IO_RegisterReadHandler(0x3c4,read_p3c4,"VGA:Sequencer Index"); + IO_RegisterReadHandler(0x3c5,read_p3c5,"VGA:Sequencer Data"); + +} + diff --git a/src/ints/Makefile.am b/src/ints/Makefile.am new file mode 100644 index 00000000..f5a095ec --- /dev/null +++ b/src/ints/Makefile.am @@ -0,0 +1,6 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include + +noinst_LIBRARIES = libints.a +libints_a_SOURCES = mouse.cpp xms.cpp ems.cpp \ + int10.cpp int10.h int10_char.cpp int10_memory.cpp int10_misc.cpp int10_modes.cpp int10_pal.cpp int10_put_pixel.cpp \ + bios.cpp bios_disk.cpp bios_keyboard.cpp diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp new file mode 100644 index 00000000..963fbb0f --- /dev/null +++ b/src/ints/bios.cpp @@ -0,0 +1,235 @@ +/* + * 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. + */ +#include +#include "dosbox.h" +#include "bios.h" +#include "regs.h" +#include "callback.h" +#include "inout.h" +#include "mem.h" + + +static Bitu call_int1a,call_int11,call_int8,call_int17,call_int12,call_int15,call_int1c; + +static Bitu INT1A_Handler(void) { + switch (reg_ah) { + case 0x00: /* Get System time */ + { + Bit32u ticks=mem_readd(BIOS_TIMER); + reg_al=0; /* Midnight never passes :) */ + reg_cx=(Bit16u)(ticks >> 16); + reg_dx=(Bit16u)(ticks & 0xffff); + break; + } + case 0x01: /* Set System time */ + mem_writed(BIOS_TIMER,(reg_cx<<16)|reg_dx); + break; + case 0x02: /* GET REAL-TIME CLOCK TIME (AT,XT286,PS) */ + reg_dx=reg_cx=0; + CALLBACK_SCF(false); + LOG_WARN("INT1A:02:Faked RTC get time call"); + break; + case 0x04: /* GET REAL-TIME ClOCK DATA (AT,XT286,PS) */ + reg_dx=reg_cx=0; + CALLBACK_SCF(false); + LOG_WARN("INT1A:04:Faked RTC get date call"); + break; + case 0x80: /* Pcjr Setup Sound Multiplexer */ + LOG_WARN("INT1A:80:Setup tandy sound multiplexer to %d",reg_al); + break; + case 0x81: /* Tandy sound system checks */ + LOG_WARN("INT1A:81:Tandy DAC Check failing"); + break; +/* + INT 1A - Tandy 2500, Tandy 1000L series - DIGITAL SOUND - INSTALLATION CHECK + AX = 8100h + Return: AL > 80h if supported + AX = 00C4h if supported (1000SL/TL) + CF set if sound chip is busy + CF clear if sound chip is free + Note: the value of CF is not definitive; call this function until CF is + clear on return, then call AH=84h"Tandy" +*/ + default: + LOG_WARN("INT1A:Undefined call %2X",reg_ah); + } + return CBRET_NONE; +} + +static Bitu INT11_Handler(void) { + /* + AX = BIOS equipment list word + bits + 0 floppy disk(s) installed (see bits 6-7) + 1 80x87 coprocessor installed + 2,3 number of 16K banks of RAM on motherboard (PC only) + number of 64K banks of RAM on motherboard (XT only) + 2 pointing device installed (PS) + 3 unused (PS) + 4-5 initial video mode + 00 EGA, VGA, or PGA + 01 40x25 color + 10 80x25 color + 11 80x25 monochrome + 6-7 number of floppies installed less 1 (if bit 0 set) + 8 DMA support installed (PCjr, some Tandy 1000s, 1400LT) + 9-11 number of serial ports installed + 12 game port installed + 13 serial printer attached (PCjr) + internal modem installed (PC/Convertible) + 14-15 number of parallel ports installed + */ + reg_eax=0x104D; + return CBRET_NONE; +} + +static Bitu INT8_Handler(void) { + /* Increase the bios tick counter */ + mem_writed(BIOS_TIMER,mem_readd(BIOS_TIMER)+1); + CALLBACK_RunRealInt(0x1c); + IO_Write(0x20,0x20); + return CBRET_NONE; +}; + +static Bitu INT1C_Handler(void) { + return CBRET_NONE; +}; + +static Bitu INT12_Handler(void) { + reg_ax=mem_readw(BIOS_MEMORY_SIZE); + return CBRET_NONE; +}; + +static Bitu INT17_Handler(void) { + LOG_ERROR("INT17:Not supported call for bios printer support"); + switch(reg_ah) { + case 0x00: /* PRINTER: Write Character */ + reg_ah=1; /* Report a timeout */ + break; + case 0x01: /* PRINTER: Initialize port */ + break; + case 0x02: /* PRINTER: Get Status */ + reg_ah=0; + break; + default: + E_Exit("Unhandled INT 17 call %2X",reg_ah); + }; + return CBRET_NONE; +}; + +static Bitu INT15_Handler(void) { + switch (reg_ah) { + case 0x06: + LOG_WARN("Calling unkown int15 function 6"); + break; + case 0xC0: /* Get Configuration*/ + LOG_WARN("Request BIOS Configuration INT 15 C0"); + CALLBACK_SCF(true); + break; + case 0x84: /* BIOS - JOYSTICK SUPPORT (XT after 11/8/82,AT,XT286,PS) */ + //Does anyone even use this? + LOG_WARN("INT15:84:Bios Joystick functionality not done"); + reg_ax=reg_bx=reg_cx=reg_dx=0; + break; + case 0x86: /* BIOS - WAIT (AT,PS) */ + { + //TODO Perhaps really wait :) + Bit32u micro=(reg_cx<<16)|reg_dx; + CALLBACK_SCF(false); + } + case 0x88: /* SYSTEM - GET EXTENDED MEMORY SIZE (286+) */ + reg_ax=0; + CALLBACK_SCF(false); + break; + case 0x90: /* OS HOOK - DEVICE BUSY */ + CALLBACK_SCF(true); + reg_ah=0; + break; + case 0xc2: /* BIOS PS2 Pointing Device Support */ + /* + Damn programs should use the mouse drivers + So let's fail these calls + */ + CALLBACK_SCF(true); + break; + case 0xc4: /* BIOS POS Programma option Select */ + LOG_WARN("INT15:C4:Call for POS Function %2x",reg_al); + CALLBACK_SCF(true); + break; + default: + LOG_WARN("INT15:Unknown call %2X",reg_ah); + } + return CBRET_NONE; +}; + +static void INT15_StartUp(void) { +/* TODO Start the time correctly */ +}; + + +void BIOS_SetupKeyboard(void); +void BIOS_SetupDisks(void); + +void BIOS_Init(void) { + /* Clear the Bios Data Area */ + for (Bit16u i=0;i<1024;i++) real_writeb(0x40,i,0); + /* Setup all the interrupt handlers the bios controls */ + /* INT 8 Clock IRQ Handler */ + //TODO Maybe give this a special callback that will also call int 8 instead of starting + //a new system + call_int8=CALLBACK_Allocate(); + CALLBACK_Setup(call_int8,&INT8_Handler,CB_IRET); + mem_writed(BIOS_TIMER,0); //Calculate the correct time + RealSetVec(0x8,CALLBACK_RealPointer(call_int8)); + /* INT10 Video Bios */ + INT10_StartUp(); + /* INT 11 Get equipment list */ + call_int11=CALLBACK_Allocate(); + CALLBACK_Setup(call_int11,&INT11_Handler,CB_IRET); + RealSetVec(0x11,CALLBACK_RealPointer(call_int11)); + /* INT 12 Memory Size default at 640 kb */ + call_int12=CALLBACK_Allocate(); + CALLBACK_Setup(call_int12,&INT12_Handler,CB_IRET); + RealSetVec(0x12,CALLBACK_RealPointer(call_int12)); + mem_writew(BIOS_MEMORY_SIZE,640); + /* INT 13 Bios Disk Support */ + BIOS_SetupDisks(); + /* INT 15 Misc Calls */ + call_int15=CALLBACK_Allocate(); + CALLBACK_Setup(call_int15,&INT15_Handler,CB_IRET); + RealSetVec(0x15,CALLBACK_RealPointer(call_int15)); + /* INT 16 Keyboard handled in another file */ + BIOS_SetupKeyboard(); + /* INT 16 Printer Routines */ + call_int17=CALLBACK_Allocate(); + CALLBACK_Setup(call_int17,&INT17_Handler,CB_IRET); + RealSetVec(0x17,CALLBACK_RealPointer(call_int17)); + /* INT 1A TIME and some other functions */ + call_int1a=CALLBACK_Allocate(); + CALLBACK_Setup(call_int1a,&INT1A_Handler,CB_IRET); + RealSetVec(0x1A,CALLBACK_RealPointer(call_int1a)); + /* INT 1C System Timer tick called from INT 8 */ + call_int1c=CALLBACK_Allocate(); + CALLBACK_Setup(call_int1c,&INT1C_Handler,CB_IRET); + RealSetVec(0x1C,CALLBACK_RealPointer(call_int1c)); + +} + + + + diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp new file mode 100644 index 00000000..3813c5bc --- /dev/null +++ b/src/ints/bios_disk.cpp @@ -0,0 +1,95 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "callback.h" +#include "bios.h" +#include "regs.h" +#include "mem.h" + + +static Bitu call_int13; +static BIOS_Disk * Floppys[2]; +static BIOS_Disk * Harddisks[BIOS_MAX_DISK]; +static Bit8u last_status; + +static Bitu INT13_FullHandler(void) { + /* Check for disk numbers */ + BIOS_Disk * disk=Floppys[0]; + switch (reg_ah) { + case 0x00: + last_status=reg_ah=0; + break; + case 0x01: /* Get Status of last operation */ + reg_ah=last_status; + break; + case 0x02: /* Read Sectors into Memory */ + last_status=reg_ah=disk->Read_Sector(®_al,reg_dh,reg_ch,(reg_cl & 0x3f)-1,real_off(Segs[es].value,reg_bx)); + CALLBACK_SCF(false); + break; + case 0x03: /* Write Sectors from Memory */ + last_status=reg_ah=disk->Write_Sector(®_al,reg_dh,reg_ch,(reg_cl & 0x3f)-1,real_off(Segs[es].value,reg_bx)); + CALLBACK_SCF(false); + break; + default: + LOG_DEBUG("INT13:Illegal call %2X",reg_ah); + reg_ah=0xff; + CALLBACK_SCF(true); + } + return CBRET_NONE; +}; + + +static Bitu INT13_SmallHandler(void) { + switch (reg_ah) { + case 0x02: /* Read Disk Sectors */ + LOG_DEBUG("INT13:02:Read Disk Sectors not supported failing"); + reg_ah=0xff; + CALLBACK_SCF(true); + break; + case 0x08: /* Get Drive Parameters */ + LOG_DEBUG("INT13:08:Get Drive parameters not supported failing"); + reg_ah=0xff; + CALLBACK_SCF(true); + break; + case 0xff: + default: + LOG_WARN("Illegal int 13h call %2X Fail it",reg_ah); + reg_ah=0xff; + CALLBACK_SCF(true); + } + return CBRET_NONE; +} + +void BIOS_SetupDisks(void) { +/* TODO Start the time correctly */ + call_int13=CALLBACK_Allocate(); +#ifdef C_IMAGE + Floppys[0]=new imageDisk("c:\\test.img"); + for (Bit32u i=0;i */ + { 0x352f, 0x353f, none, none }, /* /? */ + { none, none, none, none }, /* R Shift */ + { 0x372a, 0x372a, none, none }, /* * */ + { none, none, none, none }, /* L Alt */ + { 0x3920, 0x3920, 0x3920, 0x3920 }, /* space */ + { none, none, none, none }, /* caps lock */ + { 0x3b00, 0x5400, 0x5e00, 0x6800 }, /* F1 */ + { 0x3c00, 0x5500, 0x5f00, 0x6900 }, /* F2 */ + { 0x3d00, 0x5600, 0x6000, 0x6a00 }, /* F3 */ + { 0x3e00, 0x5700, 0x6100, 0x6b00 }, /* F4 */ + { 0x3f00, 0x5800, 0x6200, 0x6c00 }, /* F5 */ + { 0x4000, 0x5900, 0x6300, 0x6d00 }, /* F6 */ + { 0x4100, 0x5a00, 0x6400, 0x6e00 }, /* F7 */ + { 0x4200, 0x5b00, 0x6500, 0x6f00 }, /* F8 */ + { 0x4300, 0x5c00, 0x6600, 0x7000 }, /* F9 */ + { 0x4400, 0x5d00, 0x6700, 0x7100 }, /* F10 */ + { none, none, none, none }, /* Num Lock */ + { none, none, none, none }, /* Scroll Lock */ + { 0x4700, 0x4737, 0x7700, none }, /* 7 Home */ + { 0x4800, 0x4838, none, none }, /* 8 UP */ + { 0x4900, 0x4939, 0x8400, none }, /* 9 PgUp */ + { 0x4a2d, 0x4a2d, none, none }, /* - */ + { 0x4b00, 0x4b34, 0x7300, none }, /* 4 Left */ + { 0x4c00, 0x4c35, none, none }, /* 5 */ + { 0x4d00, 0x4d36, 0x7400, none }, /* 6 Right */ + { 0x4e2b, 0x4e2b, none, none }, /* + */ + { 0x4f00, 0x4f31, 0x7500, none }, /* 1 End */ + { 0x5000, 0x5032, none, none }, /* 2 Down */ + { 0x5100, 0x5133, 0x7600, none }, /* 3 PgDn */ + { 0x5200, 0x5230, none, none }, /* 0 Ins */ + { 0x5300, 0x532e, none, none } /* Del */ + }; + +/* +Old Stuff not needed after i ripped Bochs :) +static Bit8u KeyNoShift[128]={ + 27,'1','2','3', '4','5','6','7', '8','9','0','-', '=',8,9,'q', + 'w','e','r','t', 'y','u','i','o', 'p','[',']',13, 255,'a','s','d', + 'f','g','h','j', 'k','l',';','\'', '`',255,'\\','z', 'x','c','v','b', + 'n','m',',','.', '/',255,'*',255, ' ',255,0,0, 0,0,0,0, + 0,0,0,0, 255,255,0,0, 0,'-',0,255, 0,'+',0,0, + 0,0,0,0, 0 +}; + +static Bit8u KeyShift[128]={ + 27,'!','@','#', '$','%','^','&', '*','(',')','_', '+',8,9,'Q', + 'W','E','R','T', 'Y','U','I','O', 'P','{','}',13, 255,'A','S','D', + 'F','G','H','J', 'K','L',':','"', '~',255,'|','Z', 'X','C','V','B', + 'N','M','<','>', '?',255,'*',255, ' ',255,0,0, 0,0,0,0, + 0,0,0,0, 255,255,0,0, 0,'-',0,255, 0,'+',0,0, + 0,0,0,0, 0 +}; +*/ + +static void add_key(Bit16u code) { + Bit16u start,end,head,tail,ttail; + start=mem_readw(BIOS_KEYBOARD_BUFFER_START); + end =mem_readw(BIOS_KEYBOARD_BUFFER_END); + head =mem_readw(BIOS_KEYBOARD_BUFFER_HEAD); + tail =mem_readw(BIOS_KEYBOARD_BUFFER_TAIL); + ttail=tail+2; + if (ttail>=end) ttail=start; + /* Check for buffer Full */ + //TODO Maybe beeeeeeep or something although that should happend when internal buffer is full + if (ttail==head) return; + real_writew(0x40,tail,code); + mem_writew(BIOS_KEYBOARD_BUFFER_TAIL,ttail); +} + +static Bit16u get_key(void) { + Bit16u start,end,head,tail,thead; + start=mem_readw(BIOS_KEYBOARD_BUFFER_START); + end =mem_readw(BIOS_KEYBOARD_BUFFER_END); + head =mem_readw(BIOS_KEYBOARD_BUFFER_HEAD); + tail =mem_readw(BIOS_KEYBOARD_BUFFER_TAIL); + + if (head==tail) return 0; + thead=head+2; + if (thead>=end) thead=start; + mem_writew(BIOS_KEYBOARD_BUFFER_HEAD,thead); + return real_readw(0x40,head); +} + +static Bit16u check_key(void) { + Bit16u head,tail; + head =mem_readw(BIOS_KEYBOARD_BUFFER_HEAD); + tail =mem_readw(BIOS_KEYBOARD_BUFFER_TAIL); + if (head==tail) return 0; + return real_readw(0x40,head); +} + + + /* Flag Byte 1 + bit 7 =1 INSert active + bit 6 =1 Caps Lock active + bit 5 =1 Num Lock active + bit 4 =1 Scroll Lock active + bit 3 =1 either Alt pressed + bit 2 =1 either Ctrl pressed + bit 1 =1 Left Shift pressed + bit 0 =1 Right Shift pressed + */ + /* Flag Byte 2 + bit 7 =1 INSert pressed + bit 6 =1 Caps Lock pressed + bit 5 =1 Num Lock pressed + bit 4 =1 Scroll Lock pressed + bit 3 =1 Pause state active + bit 2 =1 Sys Req pressed + bit 1 =1 Left Alt pressed + bit 0 =1 Left Ctrl pressed + */ + /* + Keyboard status byte 3 + bit 7 =1 read-ID in progress + bit 6 =1 last code read was first of two ID codes + bit 5 =1 force Num Lock if read-ID and enhanced keyboard + bit 4 =1 enhanced keyboard installed + bit 3 =1 Right Alt pressed + bit 2 =1 Right Ctrl pressed + bit 1 =1 last code read was E0h + bit 0 =1 last code read was E1h + */ + + +static Bitu IRQ1_Handler(void) { + //TODO CAPSLOCK NUMLOCK SCROLLLOCK maybe :) + Bit8u code=IO_Read(0x60); + //TODO maybe implement the int 0x15 ah=4f scancode lookup hook +/* Changed it so the flag handling takes place in here too */ + Bit8u flags1=mem_readb(BIOS_KEYBOARD_FLAGS1); + Bit8u flags2=mem_readb(BIOS_KEYBOARD_FLAGS2); + Bit8u flags3=mem_readb(BIOS_KEYBOARD_FLAGS3); + switch (code) { + /* First the hard ones */ + case 0xe0: + //TODO Think of something else maybe + flags3|=2; + break; + case 29: /* Ctrl Pressed */ + flags1|=4; + if (flags3 & 2) flags3|=4; + else flags2|=1; + break; + case 157: /* Ctrl Released */ + flags1&=~4; + if (flags3 & 2) flags3&=~4; + else flags2&=~1; + break; + case 42: /* Left Shift Pressed */ + flags1|=2; + break; + case 170: /* Left Shift Released */ + flags1&=~2; + break; + case 54: /* Right Shift Pressed */ + flags1|=1; + break; + case 182: /* Right Shift Released */ + flags1&=~1; + break; + case 56: /* Alt Pressed */ + flags1|=8; + if (flags3 & 2) flags3|=8; + else flags2|=2; + break; + case 184: /* Alt Released */ + flags1&=~8; + if (flags3 & 2) flags3&=~8; + else flags2&=~2; + break; + +#if 0 + case 58:p_capslock=true;break; /* Caps Lock */ + case 186:p_capslock=false;break; + case 69:p_numlock=true;break; /* Num Lock */ + case 197:p_numlock=false;break; + case 70:p_scrolllock=true;break; /* Scroll Lock */ + case 198:p_scrolllock=false;break; + case 82:p_insert=true;break; /* Insert */ + case 210:p_insert=false;a_insert=!a_insert;break; +#endif + default: /* Normal Key */ + Bit16u asciiscan; + /* Now Handle the releasing of keys and see if they match up for a code */ + flags3&=~2; //Reset 0xE0 Flag + /* Handle the actual scancode */ + if (code & 0x80) goto irq1_end; + if (code > MAX_SCAN_CODE) goto irq1_end; + if (flags1 & 8) { /* Alt is being pressed */ + asciiscan=scan_to_scanascii[code].alt; + } else if (flags1 & 4) { /* Ctrl is being pressed */ + asciiscan=scan_to_scanascii[code].control; + } else if (flags1 & 3) { /* Either shift is being pressed */ +//TODO Maybe check for Capslock sometime in some bored way + asciiscan=scan_to_scanascii[code].shift; + } else { + asciiscan=scan_to_scanascii[code].normal; + } + add_key(asciiscan); + }; +irq1_end: + mem_writeb(BIOS_KEYBOARD_FLAGS1,flags1); + mem_writeb(BIOS_KEYBOARD_FLAGS2,flags2); + mem_writeb(BIOS_KEYBOARD_FLAGS3,flags3); + IO_Write(0x20,0x20); + /* Signal the keyboard for next code */ + Bit8u old61=IO_Read(0x61); + IO_Write(0x61,old61 | 128); + IO_Write(0x61,old61 & 127); + return CBRET_NONE; +} + +static Bitu INT16_Handler(void) { + Bit16u temp; + switch (reg_ah) { + case 0x00: /* GET KEYSTROKE */ + case 0x10: + { +//TODO find a more elegant way to do this + do { + temp=get_key(); + if (temp==0) { flags.intf=true;CALLBACK_Idle();}; + } while (temp==0); + reg_ax=temp; + break; + } + case 0x01: /* CHECK FOR KEYSTROKE */ + case 0x11: + temp=check_key(); + if (temp==0) { + CALLBACK_SZF(true); + } else { + CALLBACK_SZF(false); + reg_ax=temp; + } + break; + case 0x02: /* GET SHIFT FlAGS */ + reg_al=mem_readb(BIOS_KEYBOARD_FLAGS1); + break; + case 0x03: /* SET TYPEMATIC RATE AND DELAY */ +//Have to implement this trhough SDL + LOG_DEBUG("INT16:Unhandled Typematic Rate Call %2X",reg_al); + break; + case 0x05: /* STORE KEYSTROKE IN KEYBOARD BUFFER */ +//TODO make add_key bool :) + add_key(reg_ax); + reg_al=0; + break; + case 0x12: /* GET EXTENDED SHIFT STATES */ + reg_al=mem_readb(BIOS_KEYBOARD_FLAGS1); + reg_ah=mem_readb(BIOS_KEYBOARD_FLAGS2); + break; + case 0x55: + /* Weird call used by some dos apps */ + LOG_DEBUG("INT16:55:Word TSR compatible call"); + break; + default: + E_Exit("INT16:Unhandled call %02X",reg_ah); + break; + + }; + + return CBRET_NONE; +} + +static void InitBiosSegment(void) { + /* Setup the variables for keyboard in the bios data segment */ + mem_writew(BIOS_KEYBOARD_BUFFER_START,0x1e); + mem_writew(BIOS_KEYBOARD_BUFFER_END,0x3e); + mem_writew(BIOS_KEYBOARD_BUFFER_HEAD,0x1e); + mem_writew(BIOS_KEYBOARD_BUFFER_TAIL,0x1e); + mem_writeb(BIOS_KEYBOARD_FLAGS1,0); + mem_writeb(BIOS_KEYBOARD_FLAGS2,0); + mem_writeb(BIOS_KEYBOARD_FLAGS3,16); /* Enhanced keyboard installed */ +} + +void BIOS_SetupKeyboard(void) { + /* Init the variables */ + InitBiosSegment(); + /* Allocate a callback for int 0x16 and for standard IRQ 1 handler */ + call_int16=CALLBACK_Allocate(); + call_irq1=CALLBACK_Allocate(); + CALLBACK_Setup(call_int16,&INT16_Handler,CB_IRET); + RealSetVec(0x16,CALLBACK_RealPointer(call_int16)); + CALLBACK_Setup(call_irq1,&IRQ1_Handler,CB_IRET); + RealSetVec(0x9,CALLBACK_RealPointer(call_irq1)); +} + diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp new file mode 100644 index 00000000..705334c8 --- /dev/null +++ b/src/ints/ems.cpp @@ -0,0 +1,165 @@ +/* + * 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. + */ + + +#include +#include "dosbox.h" +#include "callback.h" +#include "mem.h" +#include "bios.h" +#include "keyboard.h" +#include "regs.h" +#include "inout.h" +#include "dos_inc.h" + + +#define PAGEFRAME_SEG 0xe000 + +class device_EMS : public DOS_Device { +public: + device_EMS(); + bool Read(Bit8u * data,Bit16u * size); + bool Write(Bit8u * data,Bit16u * size); + bool Seek(Bit32u * pos,Bit32u type); + bool Close(); + Bit16u GetInformation(void); +private: + Bit8u cache; +}; + +bool device_EMS::Read(Bit8u * data,Bit16u * size) { + return false; +} + +bool device_EMS::Write(Bit8u * data,Bit16u * size) { + return false; +} + +bool device_EMS::Seek(Bit32u * pos,Bit32u type) { + return false; +} + +bool device_EMS::Close() { + return false; +} + +Bit16u device_EMS::GetInformation(void) { + return 0x8093; +}; + +device_EMS::device_EMS() { + name="EMMXXXX0"; +} + + +PageEntry ems_entries[4]; + +Bitu call_int67; +static Bitu INT67_Handler(void) { + switch (reg_ah) { + case 0x40: /* Get Status */ + reg_ah=0; //Status ok :) + break; + case 0x41: /* Get PageFrame Segment */ + reg_bx=PAGEFRAME_SEG; + reg_ah=0; + break; + case 0x42: /* Get number of pages */ + { +//HEHE Hope this works not exactly like the specs but who cares + Bit16u maxfree,total; + EMM_GetFree(&maxfree,&total); + reg_dx=maxfree>>2; + reg_bx=total>>2; + reg_ah=0; + }; + break; + case 0x43: /* Get Handle and Allocate Pages */ + { + if (!reg_bx) { reg_ah=0x89;break; } + Bit16u handle; + EMM_Allocate(reg_bx*4,&handle); + if (handle) { + reg_ah=0; + reg_dx=handle; + } else { reg_ah=0x88; } + break; + } + case 0x44: /* Map Memory */ + { + if (reg_al>3) { reg_ah=0x8b;break; } + HostPt pagestart=memory+EMM_Handles[reg_dx].phys_base+reg_bx*16*1024; + ems_entries[reg_al].relocate=pagestart; + reg_ah=0; + break; + } + case 0x45: /* Release handle and free pages */ + EMM_Free(reg_dx); + reg_ah=0; + break; + case 0x46: /* Get EMM Version */ + reg_ah=0; + reg_al=0x32; //Only 3.2 support for now + break; + case 0x47: /* Save Mapping Context */ + LOG_ERROR("EMS:47:Save Mapping Context not supported"); + reg_ah=0x8c; + break; + case 0xDE: /* VCPI Functions */ + LOG_ERROR("VCPI Functions not supported"); + reg_ah=0x8c; + break; + default: + LOG_ERROR("EMS:Call %2X not supported",reg_ah); + reg_ah=0x8c; + break; + } + return CBRET_NONE; +} + + + +void EMS_Init(void) { + call_int67=CALLBACK_Allocate(); + CALLBACK_Setup(call_int67,&INT67_Handler,CB_IRET); +/* Register the ems device */ + DOS_Device * newdev = new device_EMS(); + DOS_AddDevice(newdev); +/* Setup the page handlers for the page frame */ + for (Bitu i=0;i<4;i++) { + ems_entries[i].base=(PAGEFRAME_SEG<<4)+i*16*1024; + ems_entries[i].type=MEMORY_RELOCATE; + ems_entries[i].relocate=memory+(PAGEFRAME_SEG<<4)+i*16*1024; +/* Place the page handlers in the ems page fram piece of the memory handler*/ + MEMORY_SetupHandler(((PAGEFRAME_SEG<<4)+i*16*1024)>>12,4,&ems_entries[i]); + } + + +/* Add a little hack so it appears that there is an actual ems device installed */ + char * emsname="EMMXXXX0"; + Bit16u seg=DOS_GetMemory(2); //We have 32 bytes + MEM_BlockWrite(real_phys(seg,0xa),emsname,strlen(emsname)+1); +/* Copy the callback piece into the beginning */ + char buf[16]; + MEM_BlockRead(real_phys(CB_SEG,call_int67<<4),buf,0xa); + MEM_BlockWrite(real_phys(seg,0),buf,0xa); + + RealSetVec(0x67,RealMake(seg,0)); + +} + diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp new file mode 100644 index 00000000..b08c0b1e --- /dev/null +++ b/src/ints/int10.cpp @@ -0,0 +1,278 @@ +/* + * 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. + */ + + +#include +#include "dosbox.h" +#include "bios.h" +#include "mem.h" +#include "callback.h" +#include "regs.h" +#include "video.h" +#include "inout.h" +#include "int10.h" + +#define TEXT_SEG 0xb800 + +static Bitu call_10; +static bool warned_ff=false; + + +static Bitu INT10_Handler(void) { + switch (reg_ah) { + case 0x00: /* Set VideoMode */ + INT10_SetVideoMode(reg_al); + break; + case 0x01: /* Set TextMode Cursor Shape */ + LOG_WARN("INT10:01:Set textmode cursor shape not supported"); + break; + case 0x02: /* Set Cursor Pos */ + //TODO Check some shit but not really usefull + INT10_SetCursorPos(reg_dh,reg_dl,reg_bh); + break; + case 0x03: /* get Cursor Pos and Cursor Shape*/ + //TODO the Cursor Shape Stuff + reg_dl=CURSOR_POS_COL(reg_bh); + reg_dh=CURSOR_POS_ROW(reg_bh); + break; + case 0x04: /* read light pen pos YEAH RIGHT */ + LOG_WARN("INT10:04:Ligthpen not supported"); + break; + case 0x05: /* Set Active Page */ + INT10_SetActivePage(reg_al); + break; + case 0x06: /* Scroll Up */ +//TODO Graphics mode scroll + INT10_ScrollUpWindow(reg_ch,reg_cl,reg_dh,reg_dl,reg_al,reg_bh,0xFF); + break; + case 0x07: /* Scroll Down */ + INT10_ScrollDownWindow(reg_ch,reg_cl,reg_dh,reg_dl,reg_al,reg_bh,0xFF); + break; + case 0x08: /* Read character & attribute at cursor */ +//TODO Check for GRAPH and then just return + INT10_ReadCharAttr(®_ax,reg_bh); + break; + case 0x09: /* Write Character & Attribute at cursor CX times */ + INT10_WriteChar(reg_al,reg_bl,reg_bh,reg_cx,true); + break; + case 0x0A: /* Write Character at cursor CX times */ + INT10_WriteChar(reg_al,reg_bl,reg_bh,reg_cx,false); + break; + case 0x0B: /* Set Background/Border Colour & Set Palette*/ + break; + E_Exit("Unsupported int 10 call %02X" ,reg_ah); + break; + case 0x0C: /* Write Graphics Pixel */ + INT10_PutPixel(reg_cx,reg_dx,reg_bh,reg_al); + break; + case 0x0D: /* Read Graphics Pixel */ + INT10_GetPixel(reg_cx,reg_dx,reg_bh,®_al); + break; + case 0x0E: /* Teletype OutPut */ + //TODO FIX + INT10_TeletypeOutput(reg_al,reg_bl,false,0); +// INT10_TeletypeOutput(reg_al,reg_bl,false,reg_bh); + break; + case 0x0F: /* Get videomode */ + reg_bh=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); + reg_al=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); + reg_ah=(Bit8u)real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); + break; + case 0x10: /* EGA/VGA Palette functions */ + switch (reg_al) { + case 0x00: /* SET SINGLE PALETTE REGISTER */ + INT10_SetSinglePaletteRegister(reg_bl,reg_bh); + break; + case 0x01: /* SET BORDER (OVERSCAN) COLOR*/ + INT10_SetOverscanBorderColor(reg_bh); + break; + case 0x02: /* SET ALL PALETTE REGISTERS */ + INT10_SetAllPaletteRegisters(real_phys(Segs[es].value,reg_dx)); + break; + case 0x03: /* TOGGLE INTENSITY/BLINKING BIT */ + INT10_ToggleBlinkingBit(reg_bl); + break; + case 0x07: /* GET SINGLE PALETTE REGISTER */ + INT10_GetSinglePaletteRegister(reg_bl,®_bh); + break; + case 0x08: /* READ OVERSCAN (BORDER COLOR) REGISTER */ + INT10_GetOverscanBorderColor(®_bh); + break; + case 0x09: /* READ ALL PALETTE REGISTERS AND OVERSCAN REGISTER */ + INT10_GetAllPaletteRegisters(real_phys(Segs[es].value,reg_dx)); + break; + case 0x10: /* SET INDIVIDUAL DAC REGISTER */ + INT10_SetSingleDacRegister(reg_bl,reg_dh,reg_ch,reg_cl); + break; + case 0x12: /* SET BLOCK OF DAC REGISTERS */ + INT10_SetDACBlock(reg_bx,reg_cx,real_phys(Segs[es].value,reg_dx)); + break; + case 0x15: /* GET INDIVIDUAL DAC REGISTER */ + INT10_GetSingleDacRegister(reg_bl,®_dh,®_ch,®_cl); + break; + case 0x17: /* GET BLOCK OF DAC REGISTER */ + INT10_GetDACBlock(reg_bx,reg_cx,real_phys(Segs[es].value,reg_dx)); + break; + default: + LOG_WARN("INT10:10:Unhandled EGA/VGA Palette Function %2X",reg_al); + } + break; + case 0x11: /* Character generator functions */ + switch (reg_al) { + case 0x30:/* Get Font Information */ + switch (reg_bh) { + case 0x00: /* interupt 0x1f vector */ + { + RealPt int_1f=RealGetVec(0x1f); + SetSegment_16(es,RealSeg(int_1f)); + reg_bp=RealOff(int_1f); + reg_cx=8; + } + break; + case 0x01: /* interupt 0x43 vector */ + { + RealPt int_43=RealGetVec(0x43); + SetSegment_16(es,RealSeg(int_43)); + reg_bp=RealOff(int_43); + reg_cx=8; + } + break; + case 0x02: /* font 8x14 */ + SetSegment_16(es,RealSeg(int10_romarea.font_14)); + reg_bp=RealOff(int10_romarea.font_14); + reg_cx=14; + break; + case 0x03: /* font 8x8 first 128 */ + SetSegment_16(es,RealSeg(int10_romarea.font_8_first)); + reg_bp=RealOff(int10_romarea.font_8_first); + reg_cx=8; + break; + case 0x04: /* font 8x8 second 128 */ + SetSegment_16(es,RealSeg(int10_romarea.font_8_second)); + reg_bp=RealOff(int10_romarea.font_8_second); + reg_cx=8; + break; + case 0x06: /* font 8x16 */ + SetSegment_16(es,RealSeg(int10_romarea.font_16)); + reg_bp=RealOff(int10_romarea.font_16); + reg_cx=16; + break; + default: + reg_cx=16; + LOG_DEBUG("INT10:11:30 Request for font %2X",reg_bh); + } + reg_dl=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS); + break; + default: + LOG_WARN("INT10:11:Unsupported character generator call %2X",reg_al); + } + break; + case 0x12: /* alternate function select */ + switch (reg_bl) { + case 0x10: /* Get EGA Information */ + { + reg_bh=(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)==0x3B4); + reg_bl=3; //256 kb + reg_cx=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES) & 0x0F; + break; + } + default: + LOG_WARN("Alternate functions select %2X not handled",reg_bl); + } + break; + case 0x13: /* Write String */ + INT10_WriteString(reg_dh,reg_dl,reg_al,reg_bl,real_phys(Segs[es].value,reg_bp),reg_cx,reg_bh); + break; + case 0x1A: /* Display Combination */ + if (reg_al==0) { + reg_bx=real_readb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX); + reg_al=0x1A; + break; + } + if (reg_al==1) { + real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,reg_bl); + reg_al=0x1A; + break; + } + LOG_DEBUG("INT10:1A:Display Combination call %2X",reg_al); + break; + case 0x1B: /* functionality State Information */ + switch (reg_bx) { + case 0x0000: + INT10_GetFuncStateInformation(Segs[es].value,reg_di); + reg_al=0x1B; + break; + default: + LOG_WARN("INT10:1B:Unhandled call BX %2X",reg_bx); + } + break; + case 0xff: + if (!warned_ff) LOG_WARN("INT10:FF:Weird NC call"); + warned_ff=true; + break; + default: + LOG_WARN("Unhandled INT 10 call %2X",reg_ah); + }; + return CBRET_NONE; +} + +static void INT10_Seg40Init(void) { + //This should fill the ega vga structures + // init detected hardware BIOS Area + real_writew(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE,real_readw(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE)&0xFFCF); + // Just for the first int10 find its children + // the default char height + real_writeb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,16); + // Clear the screen + real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,0x60); + // Set the basic screen we have + real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9); + // Set the basic modeset options + real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,0x51); + // Set the default MSR + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x09); + + INT10_SetVideoMode(3); +} + + +static void INT10_InitVGA(void) { +/* switch to color mode and enable CPU access 480 lines */ + + IO_Write(0x3c2,0xc3); + + /* More than 64k */ + IO_Write(0x3c4,0x04); + IO_Write(0x3c5,0x02); +}; + +void INT10_StartUp(void) { + + INT10_InitVGA(); + /* Setup the INT 10 vector */ + call_10=CALLBACK_Allocate(); + //TODO ERRORS ERRORS ERRORS + if (call_10==-1) E_Exit("Error can't allocate Video Int 10 CallBack\n"); + CALLBACK_Setup(call_10,&INT10_Handler,CB_IRET); + RealSetVec(0x10,CALLBACK_RealPointer(call_10)); + //Init the 0x40 segment and init the datastructures in the the video rom area + INT10_SetupRomMemory(); + INT10_Seg40Init(); +}; + + diff --git a/src/ints/int10.h b/src/ints/int10.h new file mode 100644 index 00000000..216c60c1 --- /dev/null +++ b/src/ints/int10.h @@ -0,0 +1,205 @@ +/* + * 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 BIOSMEM_SEG 0x40 + +#define BIOSMEM_INITIAL_MODE 0x10 +#define BIOSMEM_CURRENT_MODE 0x49 +#define BIOSMEM_NB_COLS 0x4A +#define BIOSMEM_PAGE_SIZE 0x4C +#define BIOSMEM_CURRENT_START 0x4E +#define BIOSMEM_CURSOR_POS 0x50 +#define BIOSMEM_CURSOR_TYPE 0x60 +#define BIOSMEM_CURRENT_PAGE 0x62 +#define BIOSMEM_CRTC_ADDRESS 0x63 +#define BIOSMEM_CURRENT_MSR 0x65 +#define BIOSMEM_CURRENT_PAL 0x66 +#define BIOSMEM_NB_ROWS 0x84 +#define BIOSMEM_CHAR_HEIGHT 0x85 +#define BIOSMEM_VIDEO_CTL 0x87 +#define BIOSMEM_SWITCHES 0x88 +#define BIOSMEM_MODESET_CTL 0x89 +#define BIOSMEM_DCC_INDEX 0x8A +#define BIOSMEM_VS_POINTER 0xA8 + + +/* + * + * VGA registers + * + */ +#define VGAREG_ACTL_ADDRESS 0x3c0 +#define VGAREG_ACTL_WRITE_DATA 0x3c0 +#define VGAREG_ACTL_READ_DATA 0x3c1 + +#define VGAREG_INPUT_STATUS 0x3c2 +#define VGAREG_WRITE_MISC_OUTPUT 0x3c2 +#define VGAREG_VIDEO_ENABLE 0x3c3 +#define VGAREG_SEQU_ADDRESS 0x3c4 +#define VGAREG_SEQU_DATA 0x3c5 + +#define VGAREG_PEL_MASK 0x3c6 +#define VGAREG_DAC_STATE 0x3c7 +#define VGAREG_DAC_READ_ADDRESS 0x3c7 +#define VGAREG_DAC_WRITE_ADDRESS 0x3c8 +#define VGAREG_DAC_DATA 0x3c9 + +#define VGAREG_READ_FEATURE_CTL 0x3ca +#define VGAREG_READ_MISC_OUTPUT 0x3cc + +#define VGAREG_GRDC_ADDRESS 0x3ce +#define VGAREG_GRDC_DATA 0x3cf + +#define VGAREG_MDA_CRTC_ADDRESS 0x3b4 +#define VGAREG_MDA_CRTC_DATA 0x3b5 +#define VGAREG_VGA_CRTC_ADDRESS 0x3d4 +#define VGAREG_VGA_CRTC_DATA 0x3d5 + +#define VGAREG_MDA_WRITE_FEATURE_CTL 0x3ba +#define VGAREG_VGA_WRITE_FEATURE_CTL 0x3da +#define VGAREG_ACTL_RESET 0x3da + +#define VGAREG_MDA_MODECTL 0x3b8 +#define VGAREG_CGA_MODECTL 0x3d8 +#define VGAREG_CGA_PALETTE 0x3d9 + +/* Video memory */ +#define VGAMEM_GRAPH 0xA000 +#define VGAMEM_CTEXT 0xB800 +#define VGAMEM_MTEXT 0xB000 + + + +/* + * + * Tables of default values for each mode + * + */ +#define MODE_MAX 0x13 +#define TEXT 0x00 +#define GRAPH 0x01 + +#define CTEXT 0x00 +#define MTEXT 0x01 +#define CGA 0x02 +#define PLANAR1 0x03 +#define PLANAR2 0x04 +#define PLANAR4 0x05 +#define LINEAR8 0x06 + +// for SVGA +#define LINEAR15 0x07 +#define LINEAR16 0x08 +#define LINEAR24 0x09 +#define LINEAR32 0x0 + + +#define SCREEN_SIZE(x,y) (((x*y*2)|0x00ff)+1) +#define SCREEN_MEM_START(x,y,p) ((((x*y*2)|0x00ff)+1)*p) +#define SCREEN_IO_START(x,y,p) ((((x*y)|0x00ff)+1)*p) + + +extern Bit8u int10_font_08[256 * 8]; +extern Bit8u int10_font_14[256 * 14]; +extern Bit8u int10_font_16[256 * 16]; + + + +typedef struct +{Bit8u svgamode; + Bit16u vesamode; + Bit8u type; /* TEXT, GRAPH */ + Bit8u memmodel; /* CTEXT,MTEXT,CGA,PL1,PL2,PL4,P8,P15,P16,P24,P32 */ + Bit8u nbpages; + Bit8u pixbits; + Bit16u swidth, sheight; + Bit16u twidth, theight; + Bit16u cwidth, cheight; + Bit16u sstart; + Bit16u slength; + Bit8u miscreg; + Bit8u pelmask; + Bit8u crtcmodel; + Bit8u actlmodel; + Bit8u grdcmodel; + Bit8u sequmodel; + Bit8u dacmodel; /* 0 1 2 3 */ +} VGAMODES; + +extern VGAMODES vga_modes[MODE_MAX+1]; + + +typedef struct { + RealPt font_8_first; + RealPt font_8_second; + RealPt font_14; + RealPt font_16; + RealPt static_state; +} VGAROMAREA; +extern VGAROMAREA int10_romarea; + +#define BIOS_NCOLS Bit16u ncols=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); +#define BIOS_NROWS Bit16u nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; + +inline Bit8u CURSOR_POS_COL(Bit8u page) { + return real_readb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2); +} + +inline Bit8u CURSOR_POS_ROW(Bit8u page) { + return real_readb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2+1); +} + + +void INT10_SetVideoMode(Bit8u mode); + +void INT10_ScrollUpWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8u nlines,Bit8u attr,Bit8u page); +void INT10_ScrollDownWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8u nlines,Bit8u attr,Bit8u page); + + +void INT10_SetActivePage(Bit8u page); +void INT10_GetFuncStateInformation(Bit16u seg,Bit16u off); + + +void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page); +void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page); +void INT10_ReadCharAttr(Bit16u * result,Bit8u page); +void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr); +void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,Bit16u count,Bit8u page); + +/* Graphics Stuff */ +void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color); +void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color); +VGAMODES * GetCurrentMode(void); + +/* Palette Group */ +void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val); +void INT10_SetOverscanBorderColor(Bit8u val); +void INT10_SetAllPaletteRegisters(PhysPt data); +void INT10_ToggleBlinkingBit(Bit8u state); +void INT10_GetSinglePaletteRegister(Bit8u reg,Bit8u * val); +void INT10_GetOverscanBorderColor(Bit8u * val); +void INT10_GetAllPaletteRegisters(PhysPt data); +void INT10_SetSingleDacRegister(Bit8u index,Bit8u red,Bit8u green,Bit8u blue); +void INT10_GetSingleDacRegister(Bit8u index,Bit8u * red,Bit8u * green,Bit8u * blue); +void INT10_SetDACBlock(Bit16u index,Bit16u count,PhysPt data); +void INT10_GetDACBlock(Bit16u index,Bit16u count,PhysPt data); + + +/* Sup Groups */ +void INT10_SetupRomMemory(void); + diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp new file mode 100644 index 00000000..d0dd415b --- /dev/null +++ b/src/ints/int10_char.cpp @@ -0,0 +1,394 @@ +/* + * 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. + */ + + +/* Character displaying moving functions */ + +#include "dosbox.h" +#include "bios.h" +#include "mem.h" +#include "inout.h" +#include "int10.h" + + +void INT10_ScrollDownWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8u nlines,Bit8u attr,Bit8u page) { + +// Bit8u mode; + Bit16u fill=( (attr << 8) | ' '); + BIOS_NCOLS;BIOS_NROWS; + + if(rul>rlr) return; + if(cul>clr) return; + if(rlr>=nrows) rlr=(Bit8u)nrows-1; + if(clr>=ncols) clr=(Bit8u)ncols-1; + + // Get the current page + if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); + + /* Get this from active video mode */ + Bit16u textseg=0xb800; + PhysPt start=real_phys(textseg,ncols*nrows*2*page); + + Bit32u dcol=clr-cul+1; + Bit32u drow=rlr-rul+1; + + Bit32u tocopy; + PhysPt dest=start+((rlr*ncols)+cul)*2; + PhysPt src = 0;/* for gcc */ + if (nlines==0) { + nlines=(Bit8u)nrows; + } + if (nlines>=drow) { + tocopy=0; + } else { + tocopy=drow-nlines; + src=start+(((rul+tocopy-1)*ncols)+cul)*2; + } + + for (Bit32u y=0;ynrows) rlr=(Bit8u)nrows; + if(clr>ncols) clr=(Bit8u)ncols; + + if(rul>rlr) return; + if(cul>clr) return; + + VGAMODES * curmode=GetCurrentMode(); + switch (curmode->memmodel) { + case CGA: + { + if (nlines==0) { + /* Clear Screen that we can */ + PhysPt dest=real_phys(0xb800,0); + for (Bit32u tel=0;tel<0x4000;tel++) { + mem_writew(dest,0x0000); + dest+=2; + } + return; + } + LOG_WARN("INT10:Scroll in CGA Mode"); + } + case MTEXT: + case CTEXT: + break; + default: + LOG_ERROR("INT10:Scroll on non supported graphics mode"); + } + + // Get the current page + if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); + + /* Get this from active video mode */ + Bit16u textseg=0xb800; + PhysPt start=real_phys(textseg,ncols*nrows*2*page); + + Bit32u dcol=clr-cul+1; + Bit32u drow=rlr-rul+1; + + Bit32u tocopy; + PhysPt dest=start+((rul*ncols)+cul)*2; + PhysPt src; + if (nlines==0) { + nlines=(Bit8u)nrows; + } + + if (nlines>=drow) { + tocopy=0; + } else { + tocopy=drow-nlines; + src=start+(((rul+nlines)*ncols)+cul)*2; + } + for (Bit32u y=0;y7) return; + switch (curmode->memmodel) { + case MTEXT: + case CTEXT:{ + BIOS_NCOLS;BIOS_NROWS; + cur_col=CURSOR_POS_COL(page); + cur_row=CURSOR_POS_ROW(page); + vid_address=SCREEN_IO_START(ncols,nrows,page); + mem_address=SCREEN_MEM_START(ncols,nrows,page); + break; + } + case CGA:{ + vid_address=0; + mem_address=0; + break; + } + case PLANAR4:{ + mem_address=0; + vid_address=((((curmode->sheight*curmode->swidth)>>3)|0xff)+1)*page; + + break; + } + default: + vid_address=0; + mem_address=0; + break; + } + // Calculate the address knowing nbcols nbrows and page num + real_writew(BIOSMEM_SEG,BIOSMEM_CURRENT_START,mem_address); + + // CRTC regs 0x0c and 0x0d + IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0c); + IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(vid_address&0xff00)>>8); + IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0d); + IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,vid_address&0x00ff); + + // And change the BIOS page + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE,page); + + // Display the cursor, now the page is active + INT10_SetCursorPos(cur_row,cur_col,page); +} + + +void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page) { + Bit16u address; + + if(page>7) return; + // Bios cursor pos + real_writeb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2,col); + real_writeb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2+1,row); + // Set the hardware cursor + Bit8u current=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); + if(page==current) { + // Get the dimensions + BIOS_NCOLS;BIOS_NROWS; + // Calculate the address knowing nbcols nbrows and page num + address=SCREEN_IO_START(ncols,nrows,page)+col+row*ncols; + // CRTC regs 0x0e and 0x0f + IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0e); + IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(address&0xff00)>>8); + IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0f); + IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,address&0x00ff); + } +} + + +void INT10_ReadCharAttr(Bit16u * result,Bit8u page) { + + if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); + BIOS_NCOLS;BIOS_NROWS; + Bit8u cur_row=CURSOR_POS_ROW(page); + Bit8u cur_col=CURSOR_POS_COL(page); + + Bit16u address=SCREEN_MEM_START(ncols,nrows,page)+(cur_col+cur_row*ncols)*2; + *result=real_readw(0xb800,address); +} + + + +INLINE static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useattr) { + VGAMODES * curmode=GetCurrentMode(); + switch (curmode->type) { + case TEXT: + { + // Compute the address + Bit16u address=SCREEN_MEM_START(curmode->twidth,curmode->theight,page)+(col+row*curmode->twidth)*2; + // Write the char + real_writeb(0xb800,address,chr); + if (useattr) { + real_writeb(0xb800,address+1,attr); + } + } + break; + case GRAPH: + { + /* Split this up for certain graphics modes, since in PLANAR4 especially this is sooo slow */ + /* Amount of lines */ + Bit8u * fontdata; + Bit16u x,y; + switch (curmode->cheight) { + case 8: +// fontdata=&int10_font_08[chr*8]; + fontdata=Real2Host(RealGetVec(0x43))+chr*8; + break; + case 14: + fontdata=&int10_font_14[chr*14]; + break; + case 16: + fontdata=&int10_font_16[chr*16]; + break; + default: + LOG_ERROR("INT10:Teletype Illegal Font Height"); + return; + } + x=8*col; + y=curmode->cheight*row; + //TODO Check for out of bounds + for (Bit8u h=0;hcheight;h++) { + Bit8u bitsel=128; + Bit8u bitline=*fontdata++; + Bit16u tx=x; + while (bitsel) { + if (bitline&bitsel) INT10_PutPixel(tx,y,page,attr); + else INT10_PutPixel(tx,y,page,0); + tx++; + bitsel>>=1; + } + y++; + } + } + break; + } +} + + + + +void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) { + if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); + Bit8u cur_row=CURSOR_POS_ROW(page); + Bit8u cur_col=CURSOR_POS_COL(page); + while (count>0) { + WriteChar(cur_col,cur_row,page,chr,attr,showattr); + count--; + } +} + + +void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page) { + if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); + BIOS_NCOLS;BIOS_NROWS; + Bit8u cur_row=CURSOR_POS_ROW(page); + Bit8u cur_col=CURSOR_POS_COL(page); + + switch (chr) { + case 7: + //TODO BEEP + break; + case 8: + if(cur_col>0) cur_col--; + break; + case '\r': + cur_col=0; + break; + case '\n': + cur_col=0; + cur_row++; + break; + case '\t': + do { + INT10_TeletypeOutput(' ',attr,showattr,page); + cur_row=CURSOR_POS_ROW(page); + cur_col=CURSOR_POS_COL(page); + } while(cur_col%8==0); + break; + default: + /* Draw the actual Character */ + WriteChar(cur_col,cur_row,page,chr,attr,showattr); + cur_col++; + } + if(cur_col==ncols) { + cur_col=0; + cur_row++; + } + // Do we need to scroll ? + if(cur_row==nrows) { + INT10_ScrollUpWindow(0,0,nrows-1,ncols-1,1,0x07,page); + cur_row--; + } + // Set the cursor for the page + INT10_SetCursorPos(cur_row,cur_col,page); +} + +void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,Bit16u count,Bit8u page) { + + if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); + BIOS_NCOLS;BIOS_NROWS; + Bit8u cur_row=CURSOR_POS_ROW(page); + Bit8u cur_col=CURSOR_POS_COL(page); + + // if row=0xff special case : use current cursor position + if (row==0xff) { + row=cur_row; + col=cur_col; + } + + INT10_SetCursorPos(row,col,page); + while (count>0) { + Bit8u chr=mem_readb(string); + string++; + if (flag&2) { + attr=mem_readb(string); + string++; + } + INT10_TeletypeOutput(chr,attr,true,page); + count--; + } + if (flag & 1) { + INT10_SetCursorPos(cur_row,cur_col,page); + } +} + diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp new file mode 100644 index 00000000..252dfd3b --- /dev/null +++ b/src/ints/int10_memory.cpp @@ -0,0 +1,1302 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "mem.h" +#include "inout.h" +#include "int10.h" + + +VGAROMAREA int10_romarea; +static Bit8u static_functionality[0x10]= +{ + /* 0 */ 0xff, // All modes supported #1 + /* 1 */ 0xff, // All modes supported #2 + /* 2 */ 0x0f, // All modes supported #3 + /* 3 */ 0x00, 0x00, 0x00, 0x00, // reserved + /* 7 */ 0x07, // 200, 350, 400 scan lines + /* 8 */ 0x04, // total number of character blocks available in text modes + /* 9 */ 0x02, // maximum number of active character blocks in text modes + /* a */ 0xff, // Misc Flags Everthing supported + /* b */ 0x0c, // Support for Display combination and intensity/blinking + /* c */ 0x00, // reserved + /* d */ 0x00, // reserved + /* e */ 0x00, // Change to add new functions + /* f */ 0x00 // reserved +}; + + + +void INT10_SetupRomMemory(void) { +/* This should fill up certain structures inside the Video Bios Rom Area */ + Bit32u i; + + Bit16u segoff=0; + int10_romarea.font_8_first=RealMake(0xC000,segoff); + for (i=0;i<128*8;i++) { + real_writeb(0xC000,segoff++,int10_font_08[i]); + } + int10_romarea.font_8_second=RealMake(0xC000,segoff); + for (i=0;i<128*8;i++) { + real_writeb(0xC000,segoff++,int10_font_08[i+128*8]); + } + int10_romarea.font_14=RealMake(0xC000,segoff); + for (i=0;i<256*14;i++) { + real_writeb(0xC000,segoff++,int10_font_14[i]); + } + int10_romarea.font_16=RealMake(0xC000,segoff); + for (i=0;i<256*16;i++) { + real_writeb(0xC000,segoff++,int10_font_16[i]); + } + int10_romarea.static_state=RealMake(0xC000,segoff); + for (i=0;i<0x10;i++) { + real_writeb(0xC000,segoff++,static_functionality[i]); + } + +}; + + + + +Bit8u int10_font_08[256 * 8] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, + 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, + 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, + 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, + 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c, + 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, + 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, + 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, + 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, + 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, + 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, + 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0, + 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, + 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99, + 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, + 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, + 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, + 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, + 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, + 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff, + 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, + 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, + 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, + 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, + 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, + 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, + 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00, + 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, + 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, + 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, + 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, + 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, + 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, + 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, + 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, + 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, + 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00, + 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, + 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00, + 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, + 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, + 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00, + 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, + 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, + 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, + 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, + 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, + 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, + 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, + 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00, + 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, + 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, + 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, + 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00, + 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, + 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, + 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, + 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, + 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, + 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, + 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, + 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, + 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00, + 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, + 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00, + 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, + 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00, + 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, + 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, + 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, + 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, + 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00, + 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, + 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, + 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, + 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00, + 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, + 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, + 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00, + 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, + 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00, + 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, + 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00, + 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, + 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00, + 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, + 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78, + 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00, + 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, + 0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, + 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, + 0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38, + 0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00, + 0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, + 0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, + 0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00, + 0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00, + 0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00, + 0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00, + 0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00, + 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, + 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18, + 0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00, + 0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30, + 0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7, + 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70, + 0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, + 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00, + 0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00, + 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, + 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, + 0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, + 0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f, + 0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03, + 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00, + 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00, + 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, + 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, + 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00, + 0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0, + 0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, + 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, + 0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00, + 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0, + 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00, + 0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc, + 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00, + 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00, + 0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, + 0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0, + 0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00, + 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, + 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00, + 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00, + 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, + 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00, + 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, + 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, + 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, + 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, + 0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, + 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +Bit8u int10_font_14[256 * 14] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, + 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, + 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, + 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, + 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, + 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, + 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, + 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, + 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, + 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x70, 0xf0, + 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, + 0x7f, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, + 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, 0xf8, + 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x06, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x06, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, + 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, + 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x7c, + 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, + 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, + 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, + 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, + 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, + 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, + 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, + 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x66, + 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, + 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, + 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, + 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, + 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, + 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, + 0x3c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, + 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x60, + 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x0c, + 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, + 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x0c, + 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, + 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, + 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, + 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, + 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, + 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, + 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, + 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, + 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, + 0xc0, 0xde, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, + 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe6, 0x66, 0x6c, 0x6c, + 0x78, 0x6c, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, + 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, + 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xe6, + 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, + 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, + 0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, + 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, + 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, + 0xd6, 0xd6, 0xfe, 0x7c, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x38, + 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, + 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, + 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, + 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x3c, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, + 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, + 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, + 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, + 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, + 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, + 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, + 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, + 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, + 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, + 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, + 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, + 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, + 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, + 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, + 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, + 0xc6, 0x70, 0x1c, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, + 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, + 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, + 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, + 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x66, 0xfe, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, + 0x70, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, + 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, + 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc2, + 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, 0x00, + 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0x76, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, + 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, + 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x78, 0x0c, 0x7c, + 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, + 0x76, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, + 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, + 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, + 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xcc, 0xcc, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, + 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x38, + 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, + 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, + 0x3c, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x10, + 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, + 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, + 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, + 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, + 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xce, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, + 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, + 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0xcc, + 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, + 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, + 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, 0x00, 0xc6, + 0xc6, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, + 0x38, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x00, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, + 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, + 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, + 0x18, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, 0xcc, + 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xc6, 0x00, + 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, + 0x7e, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, + 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x0c, + 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, + 0x3c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, + 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, + 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x76, 0xdc, + 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, + 0xc6, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, + 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, + 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, + 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, + 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x66, + 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x3c, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, + 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x55, 0xaa, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, + 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, + 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, + 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, + 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, + 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, + 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, + 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xfc, 0xc6, 0xc6, 0xfc, + 0xc0, 0xc0, 0x40, 0x00, 0x00, 0x00, 0xfe, 0xc6, + 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, + 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, + 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, + 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, + 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, + 0x3e, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, + 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, + 0x60, 0x60, 0x7c, 0x60, 0x60, 0x30, 0x1c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, + 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, + 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, + 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, + 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0xec, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +Bit8u int10_font_16[256 * 16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, + 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, + 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, + 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, + 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, + 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, + 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, + 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, + 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, + 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, + 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, + 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, + 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, + 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, + 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, + 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, + 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, + 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, + 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, + 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, + 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, + 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, + 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, + 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, + 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, + 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, + 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, + 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, + 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, + 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, + 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, + 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, + 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, + 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, + 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, + 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, + 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, + 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, + 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, + 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, + 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, + 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, + 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, + 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, + 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, + 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, + 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, + 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, + 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, + 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, + 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, + 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, + 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, + 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, + 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, + 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, + 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, + 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, + 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, + 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, + 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, + 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, + 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, + 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, + 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, + 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, + 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, + 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, + 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, + 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, + 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, + 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, + 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, + 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, + 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, + 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, + 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, + 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, + 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, + 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, + 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, + 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, + 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, + 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, + 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, + 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, + 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, + 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, + 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, + 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, + 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, + 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, + 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, + 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, + 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, + 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, + 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, + 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, + 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, + 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, + 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, + 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, + 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, + 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, + 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, + 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, + 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, + 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, + 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, + 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, + 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, + 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, + 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, + 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, + 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, + 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, + 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, + 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, + 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, + 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, + 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, + 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, + 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, + 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, + 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, + 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, + 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, + 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + + + diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp new file mode 100644 index 00000000..5dbfd81f --- /dev/null +++ b/src/ints/int10_misc.cpp @@ -0,0 +1,135 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "mem.h" +#include "inout.h" +#include "int10.h" + + + +#pragma pack(1) +struct Dynamic_Functionality { + RealPt static_table; /* 00h DWORD address of static functionality table */ + Bit8u cur_mode; /* 04h BYTE video mode in effect */ + Bit16u num_cols; /* 05h WORD number of columns */ + Bit16u regen_size; /* 07h WORD length of regen buffer in bytes */ + Bit16u regen_start; /* 09h WORD starting address of regen buffer*/ + Bit16u cursor_pos[8]; /* 0Bh WORD cursor position for page 0-7 */ + Bit16u cursor_type; /* 1Bh WORD cursor type */ + Bit8u active_page; /* 1Dh BYTE active display page */ + Bit16u crtc_address; /* 1Eh WORD CRTC port address */ + Bit8u reg_3x8; /* 20h BYTE current setting of register (3?8) */ + Bit8u reg_3x9; /* 21h BYTE current setting of register (3?9) */ + Bit8u num_rows; /* 22h BYTE number of rows */ + Bit16u bytes_per_char; /* 23h WORD bytes/character */ + Bit8u dcc; /* 25h BYTE display combination code of active display */ + Bit8u dcc_alternate; /* 26h BYTE DCC of alternate display */ + Bit16u num_colors; /* 27h WORD number of colors supported in current mode */ + Bit8u num_pages; /* 29h BYTE number of pages supported in current mode */ + Bit8u num_scanlines; /* 2Ah BYTE number of scan lines active mode (0,1,2,3) = (200,350,400,480) */ + Bit8u pri_char_block; /* 2Bh BYTE primary character block */ + Bit8u sec_char_block; /* 2Ch BYTE secondary character block */ + Bit8u misc_flags; /* 2Dh BYTE miscellaneous flags + bit 0 all modes on all displays on + 1 grey summing on + 2 monochrome display attached + 3 default palette loading disabled + 4 cursor emulation enabled + 5 0 = intensity; 1 = blinking + 6 PS/2 P70 plasma display (without 9-dot wide font) active + 7 reserved + */ + Bit8u reserved1[3]; /* 2Eh 3 BYTEs reserved (00h) */ + Bit8u vid_mem; /* 31h BYTE video memory available 00h = 64K, 01h = 128K, 02h = 192K, 03h = 256K */ + Bit8u savep_state_flag; /* 32h BYTE save pointer state flags + bit 0 512 character set active + 1 dynamic save area present + 2 alpha font override active + 3 graphics font override active + 4 palette override active + 5 DCC override active + 6 reserved + 7 reserved + */ + Bit8u reserved2[13]; /* 33h 13 BYTEs reserved (00h) */ +}; +#pragma pack() + + + + +void INT10_GetFuncStateInformation(Bit16u seg,Bit16u off) { + + PhysPt save=Real2Phys(RealMake(seg,off)); + /* set static state pointer */ + mem_writed(save,int10_romarea.static_state); + /* Copy BIOS Segment areas */ + Bit16u i; + + /* First area in Bios Seg */ + for (i=0;i<30;i++) { + mem_writeb(save+0x4+i,real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE+i)); + } + /* Second area */ + for (i=0;i<3;i++) { + mem_writeb(save+0x22+i,real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS+i)); + } + /* Zero out rest of block */ + for (i=0x25;i<0x40;i++) mem_writeb(save+i,0); + /* DCC Index */ + mem_writeb(save+0x25,real_readb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX)); + VGAMODES * curmode=GetCurrentMode(); + if (!curmode) return; + Bit16u col_count=0; + switch (curmode->memmodel) { + case CTEXT: + col_count=2;break; + case MTEXT: + col_count=16;break; + case CGA: + col_count=4;break; + case PLANAR1: + col_count=2;break; + case PLANAR2: + col_count=4;break; + case PLANAR4: + col_count=16;break; + case LINEAR8: + col_count=256;break; + } + /* Colour count */ + mem_writew(save+0x27,col_count); + /* Page count */ + mem_writeb(save+0x29,curmode->nbpages); + /* scan lines */ + switch (curmode->sheight) { + case 200: + mem_writeb(save+0x2a,0);break; + case 350: + mem_writeb(save+0x2a,1);break; + case 400: + mem_writeb(save+0x2a,2);break; + case 480: + mem_writeb(save+0x2a,3);break; + }; + //TODO Maybe misc flags + /* Video Memory available */ + mem_writeb(save+0x31,3); +} + diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp new file mode 100644 index 00000000..100344b2 --- /dev/null +++ b/src/ints/int10_modes.cpp @@ -0,0 +1,403 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "mem.h" +#include "inout.h" +#include "int10.h" + +//TODO Maybe also add PCJR Video Modes could be nice :) +//TODO include some credits to bochs/plex86 bios i used for info/tables + +VGAMODES vga_modes[MODE_MAX+1]= +{//mode vesa class model pg bits sw sh tw th cw ch sstart slength misc pelm crtc actl gdc sequ dac + {0x00, 0xFFFF, TEXT, CTEXT, 8, 4, 360, 400, 40, 25, 9, 16, 0xB800, 0x0800, 0x67, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x01, 0xFFFF, TEXT, CTEXT, 8, 4, 360, 400, 40, 25, 9, 16, 0xB800, 0x0800, 0x67, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x02, 0xFFFF, TEXT, CTEXT, 4, 4, 720, 400, 80, 25, 9, 16, 0xB800, 0x1000, 0x67, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x02}, + {0x03, 0xFFFF, TEXT, CTEXT, 4, 4, 720, 400, 80, 25, 9, 16, 0xB800, 0x1000, 0x67, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x02}, + {0x04, 0xFFFF, GRAPH, CGA, 4, 2, 320, 200, 40, 25, 8, 8, 0xB800, 0x0800, 0x63, 0xFF, 0x02, 0x01, 0x01, 0x02, 0x01}, + {0x05, 0xFFFF, GRAPH, CGA, 1, 2, 320, 200, 40, 25, 8, 8, 0xB800, 0x0800, 0x63, 0xFF, 0x02, 0x01, 0x01, 0x02, 0x01}, + {0x06, 0xFFFF, GRAPH, CGA, 1, 1, 640, 200, 80, 25, 8, 8, 0xB800, 0x1000, 0x63, 0xFF, 0x03, 0x02, 0x02, 0x03, 0x01}, + {0x07, 0xFFFF, TEXT, MTEXT, 4, 4, 720, 400, 80, 25, 9, 16, 0xB000, 0x1000, 0x66, 0xFF, 0x04, 0x03, 0x03, 0x01, 0x00}, + {0x0D, 0xFFFF, GRAPH, PLANAR4, 8, 4, 320, 200, 40, 25, 8, 8, 0xA000, 0x0000, 0x63, 0xFF, 0x05, 0x04, 0x04, 0x04, 0x01}, + {0x0E, 0xFFFF, GRAPH, PLANAR4, 4, 4, 640, 200, 80, 25, 8, 8, 0xA000, 0x0000, 0x63, 0xFF, 0x06, 0x04, 0x04, 0x05, 0x01}, + {0x0F, 0xFFFF, GRAPH, PLANAR2, 2, 2, 640, 350, 80, 25, 8, 14, 0xA000, 0x0000, 0xa2, 0xFF, 0x07, 0x05, 0x04, 0x05, 0x00}, + {0x10, 0xFFFF, GRAPH, PLANAR4, 2, 4, 640, 350, 80, 25, 8, 14, 0xA000, 0x0000, 0xa3, 0xFF, 0x07, 0x06, 0x04, 0x05, 0x02}, + {0x11, 0xFFFF, GRAPH, PLANAR1, 1, 1, 640, 480, 80, 30, 8, 16, 0xA000, 0x0000, 0xe3, 0xFF, 0x08, 0x07, 0x04, 0x05, 0x02}, + {0x12, 0xFFFF, GRAPH, PLANAR4, 1, 4, 640, 480, 80, 30, 8, 16, 0xA000, 0x0000, 0xe3, 0xFF, 0x08, 0x06, 0x04, 0x05, 0x02}, + {0x13, 0xFFFF, GRAPH, LINEAR8, 1, 8, 320, 200, 40, 25, 8, 8, 0xA000, 0x0000, 0x63, 0xFF, 0x09, 0x08, 0x05, 0x06, 0x03} +}; + +/* CRTC */ +#define CRTC_MAX_REG 0x18 +#define CRTC_MAX_MODEL 0x09 +static Bit8u crtc_access[CRTC_MAX_REG+1]= +{ /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; +static Bit8u crtc_regs[CRTC_MAX_MODEL+1][CRTC_MAX_REG+1]= +{/* Model 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 */ + /* 00 */ 0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,0xff, + /* 01 */ 0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,0xff, + /* 02 */ 0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,0xff, + /* 03 */ 0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,0xff, + /* 04 */ 0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,0xff, + /* 05 */ 0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,0xff, + /* 06 */ 0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,0xff, + /* 07 */ 0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3,0xff, + /* 08 */ 0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xe3,0xff, + /* 09 */ 0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,0xff +}; + +/* Attribute Controler 0x3c0 */ +#define ACTL_MAX_REG 0x14 +#define ACTL_MAX_MODEL 0x08 + +static Bit8u actl_access[ACTL_MAX_REG+1]= +{/* 00 01 02 03 04 05 06 07 08 09 0A 0B OC OD OE OF 10 11 12 13 14 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; + +static Bit8u actl_regs[ACTL_MAX_MODEL+1][ACTL_MAX_REG+1]= +{/* Model 00 01 02 03 04 05 06 07 08 09 0A 0B OC OD OE OF 10 11 12 13 14 */ + /* 00 */ 0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x0c,0x00,0x0f,0x08,0x00, + /* 01 */ 0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x01,0x00,0x03,0x00,0x00, + /* 02 */ 0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x01,0x00,0x01,0x00,0x00, + /* 03 */ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x0e,0x00,0x0f,0x08,0x00, + /* 04 */ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x01,0x00,0x0f,0x00,0x00, + /* 05 */ 0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,0x0b,0x00,0x05,0x00,0x00, + /* 06 */ 0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x01,0x00,0x0f,0x00,0x00, + /* 07 */ 0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x01,0x00,0x01,0x00,0x00, + /* 08 */ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x41,0x00,0x0f,0x00,0x00 +}; + +/* Sequencer 0x3c4 */ +#define SEQU_MAX_REG 0x04 +#define SEQU_MAX_MODEL 0x06 + +static Bit8u sequ_access[SEQU_MAX_REG+1]= +{ /* 00 01 02 03 04 */ + 0x00,0x00,0x00,0x00,0x00 +}; + +static Bit8u sequ_regs[SEQU_MAX_MODEL+1][SEQU_MAX_REG+1]= +{/* Model 00 01 02 03 04 */ + /* 00 */ 0x03,0x08,0x03,0x00,0x02, + /* 01 */ 0x03,0x00,0x03,0x00,0x02, + /* 02 */ 0x03,0x09,0x03,0x00,0x02, + /* 03 */ 0x03,0x01,0x01,0x00,0x06, + /* 04 */ 0x03,0x09,0x0f,0x00,0x06, + /* 05 */ 0x03,0x01,0x0f,0x00,0x06, + /* 06 */ 0x03,0x01,0x0f,0x00,0x0e +}; + +/* Graphic ctl 0x3ce */ +#define GRDC_MAX_REG 0x08 +#define GRDC_MAX_MODEL 0x05 + +static Bit8u grdc_access[GRDC_MAX_REG+1]= +{ /* 00 01 02 03 04 05 06 07 08 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; + +static Bit8u grdc_regs[GRDC_MAX_MODEL+1][GRDC_MAX_REG+1]= +{/* Model 00 01 02 03 04 05 06 07 08 */ + /* 00 */ 0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x0f,0xff, + /* 01 */ 0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x0f,0xff, + /* 02 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x0f,0xff, + /* 03 */ 0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x0f,0xff, + /* 04 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,0xff, + /* 05 */ 0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,0xff +}; + +/* Default Palette */ +#define DAC_MAX_MODEL 3 + +static Bit8u dac_regs[DAC_MAX_MODEL+1]= +{0x3f,0x3f,0x3f,0xff}; + +/* Mono */ +static Bit8u palette0[63+1][3]= +{ + 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, + 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, + 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, + 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, + 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, + 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, + 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, + 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f +}; + +static Bit8u palette1[63+1][3]= +{ + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f +}; + +static Bit8u palette2[63+1][3]= +{ + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x2a,0x00, 0x2a,0x2a,0x2a, + 0x00,0x00,0x15, 0x00,0x00,0x3f, 0x00,0x2a,0x15, 0x00,0x2a,0x3f, 0x2a,0x00,0x15, 0x2a,0x00,0x3f, 0x2a,0x2a,0x15, 0x2a,0x2a,0x3f, + 0x00,0x15,0x00, 0x00,0x15,0x2a, 0x00,0x3f,0x00, 0x00,0x3f,0x2a, 0x2a,0x15,0x00, 0x2a,0x15,0x2a, 0x2a,0x3f,0x00, 0x2a,0x3f,0x2a, + 0x00,0x15,0x15, 0x00,0x15,0x3f, 0x00,0x3f,0x15, 0x00,0x3f,0x3f, 0x2a,0x15,0x15, 0x2a,0x15,0x3f, 0x2a,0x3f,0x15, 0x2a,0x3f,0x3f, + 0x15,0x00,0x00, 0x15,0x00,0x2a, 0x15,0x2a,0x00, 0x15,0x2a,0x2a, 0x3f,0x00,0x00, 0x3f,0x00,0x2a, 0x3f,0x2a,0x00, 0x3f,0x2a,0x2a, + 0x15,0x00,0x15, 0x15,0x00,0x3f, 0x15,0x2a,0x15, 0x15,0x2a,0x3f, 0x3f,0x00,0x15, 0x3f,0x00,0x3f, 0x3f,0x2a,0x15, 0x3f,0x2a,0x3f, + 0x15,0x15,0x00, 0x15,0x15,0x2a, 0x15,0x3f,0x00, 0x15,0x3f,0x2a, 0x3f,0x15,0x00, 0x3f,0x15,0x2a, 0x3f,0x3f,0x00, 0x3f,0x3f,0x2a, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f +}; + +static Bit8u palette3[256][3]= +{ + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, + 0x00,0x00,0x00, 0x05,0x05,0x05, 0x08,0x08,0x08, 0x0b,0x0b,0x0b, 0x0e,0x0e,0x0e, 0x11,0x11,0x11, 0x14,0x14,0x14, 0x18,0x18,0x18, + 0x1c,0x1c,0x1c, 0x20,0x20,0x20, 0x24,0x24,0x24, 0x28,0x28,0x28, 0x2d,0x2d,0x2d, 0x32,0x32,0x32, 0x38,0x38,0x38, 0x3f,0x3f,0x3f, + 0x00,0x00,0x3f, 0x10,0x00,0x3f, 0x1f,0x00,0x3f, 0x2f,0x00,0x3f, 0x3f,0x00,0x3f, 0x3f,0x00,0x2f, 0x3f,0x00,0x1f, 0x3f,0x00,0x10, + 0x3f,0x00,0x00, 0x3f,0x10,0x00, 0x3f,0x1f,0x00, 0x3f,0x2f,0x00, 0x3f,0x3f,0x00, 0x2f,0x3f,0x00, 0x1f,0x3f,0x00, 0x10,0x3f,0x00, + 0x00,0x3f,0x00, 0x00,0x3f,0x10, 0x00,0x3f,0x1f, 0x00,0x3f,0x2f, 0x00,0x3f,0x3f, 0x00,0x2f,0x3f, 0x00,0x1f,0x3f, 0x00,0x10,0x3f, + 0x1f,0x1f,0x3f, 0x27,0x1f,0x3f, 0x2f,0x1f,0x3f, 0x37,0x1f,0x3f, 0x3f,0x1f,0x3f, 0x3f,0x1f,0x37, 0x3f,0x1f,0x2f, 0x3f,0x1f,0x27, + + 0x3f,0x1f,0x1f, 0x3f,0x27,0x1f, 0x3f,0x2f,0x1f, 0x3f,0x37,0x1f, 0x3f,0x3f,0x1f, 0x37,0x3f,0x1f, 0x2f,0x3f,0x1f, 0x27,0x3f,0x1f, + 0x1f,0x3f,0x1f, 0x1f,0x3f,0x27, 0x1f,0x3f,0x2f, 0x1f,0x3f,0x37, 0x1f,0x3f,0x3f, 0x1f,0x37,0x3f, 0x1f,0x2f,0x3f, 0x1f,0x27,0x3f, + 0x2d,0x2d,0x3f, 0x31,0x2d,0x3f, 0x36,0x2d,0x3f, 0x3a,0x2d,0x3f, 0x3f,0x2d,0x3f, 0x3f,0x2d,0x3a, 0x3f,0x2d,0x36, 0x3f,0x2d,0x31, + 0x3f,0x2d,0x2d, 0x3f,0x31,0x2d, 0x3f,0x36,0x2d, 0x3f,0x3a,0x2d, 0x3f,0x3f,0x2d, 0x3a,0x3f,0x2d, 0x36,0x3f,0x2d, 0x31,0x3f,0x2d, + 0x2d,0x3f,0x2d, 0x2d,0x3f,0x31, 0x2d,0x3f,0x36, 0x2d,0x3f,0x3a, 0x2d,0x3f,0x3f, 0x2d,0x3a,0x3f, 0x2d,0x36,0x3f, 0x2d,0x31,0x3f, + 0x00,0x00,0x1c, 0x07,0x00,0x1c, 0x0e,0x00,0x1c, 0x15,0x00,0x1c, 0x1c,0x00,0x1c, 0x1c,0x00,0x15, 0x1c,0x00,0x0e, 0x1c,0x00,0x07, + 0x1c,0x00,0x00, 0x1c,0x07,0x00, 0x1c,0x0e,0x00, 0x1c,0x15,0x00, 0x1c,0x1c,0x00, 0x15,0x1c,0x00, 0x0e,0x1c,0x00, 0x07,0x1c,0x00, + 0x00,0x1c,0x00, 0x00,0x1c,0x07, 0x00,0x1c,0x0e, 0x00,0x1c,0x15, 0x00,0x1c,0x1c, 0x00,0x15,0x1c, 0x00,0x0e,0x1c, 0x00,0x07,0x1c, + + 0x0e,0x0e,0x1c, 0x11,0x0e,0x1c, 0x15,0x0e,0x1c, 0x18,0x0e,0x1c, 0x1c,0x0e,0x1c, 0x1c,0x0e,0x18, 0x1c,0x0e,0x15, 0x1c,0x0e,0x11, + 0x1c,0x0e,0x0e, 0x1c,0x11,0x0e, 0x1c,0x15,0x0e, 0x1c,0x18,0x0e, 0x1c,0x1c,0x0e, 0x18,0x1c,0x0e, 0x15,0x1c,0x0e, 0x11,0x1c,0x0e, + 0x0e,0x1c,0x0e, 0x0e,0x1c,0x11, 0x0e,0x1c,0x15, 0x0e,0x1c,0x18, 0x0e,0x1c,0x1c, 0x0e,0x18,0x1c, 0x0e,0x15,0x1c, 0x0e,0x11,0x1c, + 0x14,0x14,0x1c, 0x16,0x14,0x1c, 0x18,0x14,0x1c, 0x1a,0x14,0x1c, 0x1c,0x14,0x1c, 0x1c,0x14,0x1a, 0x1c,0x14,0x18, 0x1c,0x14,0x16, + 0x1c,0x14,0x14, 0x1c,0x16,0x14, 0x1c,0x18,0x14, 0x1c,0x1a,0x14, 0x1c,0x1c,0x14, 0x1a,0x1c,0x14, 0x18,0x1c,0x14, 0x16,0x1c,0x14, + 0x14,0x1c,0x14, 0x14,0x1c,0x16, 0x14,0x1c,0x18, 0x14,0x1c,0x1a, 0x14,0x1c,0x1c, 0x14,0x1a,0x1c, 0x14,0x18,0x1c, 0x14,0x16,0x1c, + 0x00,0x00,0x10, 0x04,0x00,0x10, 0x08,0x00,0x10, 0x0c,0x00,0x10, 0x10,0x00,0x10, 0x10,0x00,0x0c, 0x10,0x00,0x08, 0x10,0x00,0x04, + 0x10,0x00,0x00, 0x10,0x04,0x00, 0x10,0x08,0x00, 0x10,0x0c,0x00, 0x10,0x10,0x00, 0x0c,0x10,0x00, 0x08,0x10,0x00, 0x04,0x10,0x00, + + 0x00,0x10,0x00, 0x00,0x10,0x04, 0x00,0x10,0x08, 0x00,0x10,0x0c, 0x00,0x10,0x10, 0x00,0x0c,0x10, 0x00,0x08,0x10, 0x00,0x04,0x10, + 0x08,0x08,0x10, 0x0a,0x08,0x10, 0x0c,0x08,0x10, 0x0e,0x08,0x10, 0x10,0x08,0x10, 0x10,0x08,0x0e, 0x10,0x08,0x0c, 0x10,0x08,0x0a, + 0x10,0x08,0x08, 0x10,0x0a,0x08, 0x10,0x0c,0x08, 0x10,0x0e,0x08, 0x10,0x10,0x08, 0x0e,0x10,0x08, 0x0c,0x10,0x08, 0x0a,0x10,0x08, + 0x08,0x10,0x08, 0x08,0x10,0x0a, 0x08,0x10,0x0c, 0x08,0x10,0x0e, 0x08,0x10,0x10, 0x08,0x0e,0x10, 0x08,0x0c,0x10, 0x08,0x0a,0x10, + 0x0b,0x0b,0x10, 0x0c,0x0b,0x10, 0x0d,0x0b,0x10, 0x0f,0x0b,0x10, 0x10,0x0b,0x10, 0x10,0x0b,0x0f, 0x10,0x0b,0x0d, 0x10,0x0b,0x0c, + 0x10,0x0b,0x0b, 0x10,0x0c,0x0b, 0x10,0x0d,0x0b, 0x10,0x0f,0x0b, 0x10,0x10,0x0b, 0x0f,0x10,0x0b, 0x0d,0x10,0x0b, 0x0c,0x10,0x0b, + 0x0b,0x10,0x0b, 0x0b,0x10,0x0c, 0x0b,0x10,0x0d, 0x0b,0x10,0x0f, 0x0b,0x10,0x10, 0x0b,0x0f,0x10, 0x0b,0x0d,0x10, 0x0b,0x0c,0x10, + 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00 +}; + +static Bit8u static_functionality[0x10]= +{ + /* 0 */ 0xff, // All modes supported #1 + /* 1 */ 0xff, // All modes supported #2 + /* 2 */ 0x0f, // All modes supported #3 + /* 3 */ 0x00, 0x00, 0x00, 0x00, // reserved + /* 7 */ 0x07, // 200, 350, 400 scan lines + /* 8 */ 0xFF, // FIXME i don't know what this is + /* 9 */ 0xFF, // FIXME i don't know what this is + /* a */ 0xe3, // Change to add new functions + /* b */ 0x0c, // Change to add new functions + /* c */ 0x00, // reserved + /* d */ 0x00, // reserved + /* e */ 0x00, // Change to add new functions + /* f */ 0x00 // reserved +}; + +static Bit8u FindVideoMode(Bit8u mode) { + Bit8u line=0xff; + for(Bit8u i=0;i<=MODE_MAX;i++) { + if(vga_modes[i].svgamode==mode) { + line=i; + break; + } + } + return line; + +} + +VGAMODES * GetCurrentMode(void) { + Bit8u ret=FindVideoMode(real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)&127); + if (ret==0xff) return 0; + return &vga_modes[ret]; +} + + +void INT10_SetVideoMode(Bit8u mode) { + + bool clearmem=(mode & 128)==0; + Bit8u *palette; + Bit16u i,twidth,theight,cheight; + Bit8u modeset_ctl,video_ctl,vga_switches; + Bit16u crtc_addr; + Bit8u line; + + mode&=mode & 127; + line=FindVideoMode(mode); + if (line==0xff) { + LOG_ERROR("INT10:Trying to set non supported video mode %X",mode); + return; + } + + twidth=vga_modes[line].twidth; + theight=vga_modes[line].theight; + cheight=vga_modes[line].cheight; + + // Read the bios vga control + video_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL); + + // Read the bios vga switches + vga_switches=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES); + + // Read the bios mode set control + modeset_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); + + + if((modeset_ctl&0x08)==0) { + // Set the PEL mask + IO_Write(VGAREG_PEL_MASK,vga_modes[line].pelmask); + // Set the whole dac always, from 0 + IO_Write(VGAREG_DAC_WRITE_ADDRESS,0x00); + // From which palette + switch(vga_modes[line].dacmodel) { + case 0: + palette=(Bit8u*)&palette0; + break; + case 1: + palette=(Bit8u*)&palette1; + break; + case 2: + palette=(Bit8u*)&palette2; + break; + case 3: + palette=(Bit8u*)&palette3; + break; + default: + palette=(Bit8u*)&palette0;/*for gcc*/ + E_Exit("INT10: palette error in setvidmode"); + break; + } + // Set the actual palette + for (i=0;i<256;i++) { + if (i<=dac_regs[vga_modes[line].dacmodel]) { + IO_Write(VGAREG_DAC_DATA,palette[(i*3)+0]); + IO_Write(VGAREG_DAC_DATA,palette[(i*3)+1]); + IO_Write(VGAREG_DAC_DATA,palette[(i*3)+2]); + } else { + IO_Write(VGAREG_DAC_DATA,0); + IO_Write(VGAREG_DAC_DATA,0); + IO_Write(VGAREG_DAC_DATA,0); + } + } + } + + /* Reset Attribute ctl into address mode just to be safe */ + + IO_Read(VGAREG_ACTL_RESET); + // Set Attribute Ctl + for(i=0;i<=ACTL_MAX_REG;i++) { + IO_Write(VGAREG_ACTL_ADDRESS,(Bit8u)i); + IO_Write(VGAREG_ACTL_WRITE_DATA,actl_regs[vga_modes[line].actlmodel][i]); + } + // Set Sequencer Ctl + for(i=0;i<=SEQU_MAX_REG;i++) { + IO_Write(VGAREG_SEQU_ADDRESS,(Bit8u)i); + IO_Write(VGAREG_SEQU_DATA,sequ_regs[vga_modes[line].sequmodel][i]); + } + + // Set Grafx Ctl + for(i=0;i<=GRDC_MAX_REG;i++) { + IO_Write(VGAREG_GRDC_ADDRESS,(Bit8u)i); + IO_Write(VGAREG_GRDC_DATA,grdc_regs[vga_modes[line].grdcmodel][i]); + } + + // Set CRTC address VGA or MDA + crtc_addr=vga_modes[line].memmodel==MTEXT?VGAREG_MDA_CRTC_ADDRESS:VGAREG_VGA_CRTC_ADDRESS; + // Set CRTC regs + for(i=0;i<=CRTC_MAX_REG;i++) { + IO_Write(crtc_addr,(Bit8u)i); + IO_Write(crtc_addr+1,crtc_regs[vga_modes[line].crtcmodel][i]); + } + + // Set the misc register + IO_Write(VGAREG_WRITE_MISC_OUTPUT,vga_modes[line].miscreg); + + // Enable video + IO_Write(VGAREG_ACTL_ADDRESS,0x20); + IO_Read(VGAREG_ACTL_RESET); + Bit32u tel; + if(clearmem) { + if(vga_modes[line].type==TEXT) { + PhysPt dest=real_phys(vga_modes[line].sstart,0); + for (tel=0;tel<0x4000;tel++) { + mem_writew(dest,0x0720); + dest+=2; + } + } else { + PhysPt dest=real_phys(0xb800,0); + for (tel=0;tel<0x4000;tel++) { + mem_writew(dest,0x0000); + dest+=2; + } + dest=real_phys(0xa000,0); + for (tel=0;tel<0x8000;tel++) { + mem_writew(dest,0x0000); + dest+=2; + } + // FIXME should handle gfx mode + } + } + // Set the BIOS mem + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode|((!clearmem) << 7)); + real_writew(BIOSMEM_SEG,BIOSMEM_NB_COLS,twidth); + real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,vga_modes[line].slength); + real_writew(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_addr); + real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,theight-1); + real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,cheight); + real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem << 7))); + real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9); + real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); + + // FIXME We nearly have the good tables. to be reworked + real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08); // 8 is VGA should be ok for now + real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER,0x00); + real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2,0x00); + + // FIXME + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x00); // Unavailable on vanilla vga, but... + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x00); // Unavailable on vanilla vga, but... + + // Set cursor shape + if(vga_modes[line].type==TEXT) { +//TODO cursor shape biosfn_set_cursor_shape(0x06,0x07); + } + // Set cursor pos for page 0..7 + for(i=0;i<8;i++) INT10_SetCursorPos(0,0,(Bit8u)i); + // Set active page 0 + INT10_SetActivePage(0); + /* Set some interrupt vectors */ + //TODO set 0x43 to the correct font height font + RealSetVec(0x43,int10_romarea.font_8_first); + RealSetVec(0x1F,int10_romarea.font_8_second); + +}; diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp new file mode 100644 index 00000000..c73553a4 --- /dev/null +++ b/src/ints/int10_pal.cpp @@ -0,0 +1,126 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "mem.h" +#include "inout.h" +#include "int10.h" + +#define ACTL_MAX_REG 0x14 + +void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val) { + if(reg<=ACTL_MAX_REG) { + IO_Read(VGAREG_ACTL_RESET); + IO_Write(VGAREG_ACTL_ADDRESS,reg); + IO_Write(VGAREG_ACTL_WRITE_DATA,val); + } +} + + +void INT10_SetOverscanBorderColor(Bit8u val) { + IO_Read(VGAREG_ACTL_RESET); + IO_Write(VGAREG_ACTL_ADDRESS,0x11); + IO_Write(VGAREG_ACTL_WRITE_DATA,val); +} + +void INT10_SetAllPaletteRegisters(PhysPt data) { + IO_Read(VGAREG_ACTL_RESET); + // First the colors + for(Bit8u i=0;i<0x10;i++) { + IO_Write(VGAREG_ACTL_ADDRESS,i); + IO_Write(VGAREG_ACTL_WRITE_DATA,mem_readb(data)); + data++; + } + // Then the border + IO_Write(VGAREG_ACTL_ADDRESS,0x11); + IO_Write(VGAREG_ACTL_WRITE_DATA,mem_readb(data)); +} + +void INT10_ToggleBlinkingBit(Bit8u state) { + Bit8u value; + state&=0x01; + IO_Read(VGAREG_ACTL_RESET); + + IO_Write(VGAREG_ACTL_ADDRESS,0x10); + value=IO_Read(VGAREG_ACTL_READ_DATA); + value&=0xf7; + value|=state<<3; + + IO_Read(VGAREG_ACTL_RESET); + IO_Write(VGAREG_ACTL_ADDRESS,0x10); + IO_Write(VGAREG_ACTL_WRITE_DATA,value); +} + +void INT10_GetSinglePaletteRegister(Bit8u reg,Bit8u * val) { + if(reg<=ACTL_MAX_REG) { + IO_Read(VGAREG_ACTL_RESET); + IO_Write(VGAREG_ACTL_ADDRESS,reg); + *val=IO_Read(VGAREG_ACTL_READ_DATA); + } +} + +void INT10_GetOverscanBorderColor(Bit8u * val) { + IO_Read(VGAREG_ACTL_RESET); + IO_Write(VGAREG_ACTL_ADDRESS,0x11); + *val=IO_Read(VGAREG_ACTL_READ_DATA); +} + +void INT10_GetAllPaletteRegisters(PhysPt data) { + IO_Read(VGAREG_ACTL_RESET); + // First the colors + for(Bit8u i=0;i<0x10;i++) { + IO_Write(VGAREG_ACTL_ADDRESS,i); + mem_writeb(data,IO_Read(VGAREG_ACTL_READ_DATA)); + data++; + } + // Then the border + IO_Write(VGAREG_ACTL_ADDRESS,0x11); + mem_writeb(data,IO_Read(VGAREG_ACTL_READ_DATA)); +} + +void INT10_SetSingleDacRegister(Bit8u index,Bit8u red,Bit8u green,Bit8u blue) { + IO_Write(VGAREG_DAC_WRITE_ADDRESS,(Bit8u)index); + IO_Write(VGAREG_DAC_DATA,red); + IO_Write(VGAREG_DAC_DATA,green); + IO_Write(VGAREG_DAC_DATA,blue); +} + +void INT10_GetSingleDacRegister(Bit8u index,Bit8u * red,Bit8u * green,Bit8u * blue) { + IO_Write(VGAREG_DAC_READ_ADDRESS,index); + *red=IO_Read(VGAREG_DAC_DATA); + *green=IO_Read(VGAREG_DAC_DATA); + *blue=IO_Read(VGAREG_DAC_DATA); +} + +void INT10_SetDACBlock(Bit16u index,Bit16u count,PhysPt data) { + IO_Write(VGAREG_DAC_WRITE_ADDRESS,(Bit8u)index); + for (;count>0;count--) { + IO_Write(VGAREG_DAC_DATA,mem_readb(data++)); + IO_Write(VGAREG_DAC_DATA,mem_readb(data++)); + IO_Write(VGAREG_DAC_DATA,mem_readb(data++)); + } +} + +void INT10_GetDACBlock(Bit16u index,Bit16u count,PhysPt data) { + IO_Write(VGAREG_DAC_WRITE_ADDRESS,(Bit8u)index); + for (;count>0;count--) { + mem_writeb(data++,IO_Read(VGAREG_DAC_DATA)); + mem_writeb(data++,IO_Read(VGAREG_DAC_DATA)); + mem_writeb(data++,IO_Read(VGAREG_DAC_DATA)); + } +}; diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp new file mode 100644 index 00000000..74fd6fdd --- /dev/null +++ b/src/ints/int10_put_pixel.cpp @@ -0,0 +1,91 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "mem.h" +#include "inout.h" +#include "int10.h" + +union VGA_Memory { + Bit8u linear[64*1024*4]; + Bit8u paged[64*1024][4]; +}; +extern VGA_Memory vga_mem; + +static Bit8u cga_masks[4]={~192,~48,~12,~3}; + +void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { + + VGAMODES * curmode=GetCurrentMode(); + + switch (curmode->memmodel) { + case CGA: + { + Bit16u off=(y>>1)*80+(x>>2); + if (y&1) off+=8*1024; + Bit8u old=real_readb(0xb800,off); + old=old&cga_masks[x&3]|((color&3) << (2*(3-(x&3)))); + real_writeb(0xb800,off,old); + } + break; + case PLANAR4: + { + /* Set the correct bitmask for the pixel position */ + IO_Write(0x3ce,0x8);Bit8u mask=128>>(x&7);IO_Write(0x3cf,mask); + /* Set the color to set/reset register */ + IO_Write(0x3ce,0x0);IO_Write(0x3cf,color); + /* Enable all the set/resets */ + IO_Write(0x3ce,0x1);IO_Write(0x3cf,0xf); + //Perhaps also set mode 1 + /* Calculate where the pixel is in video memory */ + Bit16u base_address=((((curmode->sheight*curmode->swidth)>>3)|0xff)+1)*page; + PhysPt off=0xa0000+base_address+((y*curmode->swidth+x)>>3); + /* Bitmask and set/reset should do the rest */ + mem_readb(off); + mem_writeb(off,0xff); + break; + } + case CTEXT: + case MTEXT: + case PLANAR1: + case PLANAR2: + case LINEAR8: + default: + LOG_WARN("INT10:PutPixel Unhanled memory model"); + break; + } +} + +void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { + + VGAMODES * curmode=GetCurrentMode(); + switch (curmode->memmodel) { + case CGA: + { + Bit16u off=(y>>1)*80+(x>>2); + if (y&1) off+=8*1024; + Bit8u val=real_readb(0xb800,off); + *color=val<<((x&3)*2); + } + break; + default: + LOG_WARN("INT10:GetPixel Unhanled memory model"); + break; + } +} + diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp new file mode 100644 index 00000000..baab5990 --- /dev/null +++ b/src/ints/mouse.cpp @@ -0,0 +1,294 @@ +/* + * 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. + */ + + +#include +#include "dosbox.h" +#include "callback.h" +#include "mem.h" +#include "regs.h" +#include "mouse.h" +#include "pic.h" +#include "inout.h" + + +static Bitu call_int33,call_int74; + +struct button_event { + Bit16u type; + Bit16u buttons; +}; + +#define QUEUE_SIZE 32 +//TODO Maybe use :) +#define MOUSE_IRQ 12 +#define POS_X (Bit16s)(mouse.x*mouse.range_x) +#define POS_Y (Bit16s)(mouse.y*mouse.range_y) + + +static struct { + Bit16u buttons; + Bit16u times_pressed[3]; + Bit16u times_released[3]; + Bit16u last_released_x[3]; + Bit16u last_released_y[3]; + Bit16u last_pressed_x[3]; + Bit16u last_pressed_y[3]; + Bit16s shown; + float add_x,add_y; + Bit16u min_x,max_x,min_y,max_y; + float range_x,range_y; + float mickey_x,mickey_y; + float x,y; + button_event event_queue[QUEUE_SIZE]; + Bit32u events; + Bit16u sub_seg,sub_ofs; + Bit16u sub_mask; +} mouse; + +#define X_MICKEY 500 +#define Y_MICKEY 500 + +#define MOUSE_MOVED 1 +#define MOUSE_LEFT_PRESSED 2 +#define MOUSE_LEFT_RELEASED 4 +#define MOUSE_RIGHT_PRESSED 8 +#define MOUSE_RIGHT_RELEASED 16 +#define MOUSE_MIDDLE_PRESSED 32 +#define MOUSE_MIDDLE_RELEASED 64 + +inline void Mouse_AddEvent(Bit16u type) { + if (mouse.events1) mouse.x=1; + if (mouse.x<0) mouse.x=0; + mouse.y+=y; + if (mouse.y>1) mouse.y=1; + if (mouse.y<0) mouse.y=0; + Mouse_AddEvent(MOUSE_MOVED); +} + +void Mouse_CursorSet(float x,float y) { + + mouse.x=x; + mouse.y=y; +} + +void Mouse_ButtonPressed(Bit8u button) { + switch (button) { + case 0: + mouse.buttons|=1; + Mouse_AddEvent(MOUSE_LEFT_PRESSED); + break; + case 1: + mouse.buttons|=2; + Mouse_AddEvent(MOUSE_RIGHT_PRESSED); + break; + case 2: + mouse.buttons|=4; + Mouse_AddEvent(MOUSE_MIDDLE_PRESSED); + break; + } + mouse.times_pressed[button]++; + mouse.last_pressed_x[button]=POS_X; + mouse.last_pressed_y[button]=POS_Y; +} + +void Mouse_ButtonReleased(Bit8u button) { + switch (button) { + case 0: + mouse.buttons&=~1; + Mouse_AddEvent(MOUSE_LEFT_RELEASED); + break; + case 1: + mouse.buttons&=~2; + Mouse_AddEvent(MOUSE_RIGHT_RELEASED); + break; + case 2: + mouse.buttons&=~4; + Mouse_AddEvent(MOUSE_MIDDLE_RELEASED); + break; + } + mouse.times_released[button]++; + mouse.last_released_x[button]=POS_X; + mouse.last_released_y[button]=POS_Y; +} + + +static void mouse_reset(void) { + real_writed(0,(0x33<<2),CALLBACK_RealPointer(call_int33)); + real_writed(0,(0x74<<2),CALLBACK_RealPointer(call_int74)); + mouse.shown=-1; + mouse.min_x=0; + mouse.max_x=639; + mouse.min_y=0; + mouse.max_y=199; + mouse.range_x=639; + mouse.range_y=199; + mouse.x=320; + mouse.y=100; + mouse.events=0; + mouse.mickey_x=0; + mouse.mickey_y=0; + mouse.sub_mask=0; + mouse.sub_seg=0; + mouse.sub_ofs=0; +}; + + +static Bitu INT33_Handler(void) { + switch (reg_ax) { + case 0x00: /* Reset Driver and Read Status */ + reg_ax=0xffff; + reg_bx=0; + mouse_reset(); + break; + case 0x01: /* Show Mouse */ + mouse.shown++; + if (mouse.shown>0) mouse.shown=0; + break; + case 0x02: /* Hide Mouse */ + mouse.shown--; + break; + case 0x03: /* Return position and Button Status */ + reg_bx=mouse.buttons; + reg_cx=POS_X; + reg_dx=POS_Y; + break; + case 0x04: /* Position Mouse */ + mouse.x=((float)reg_cx)/mouse.range_x; + mouse.y=((float)reg_dx)/mouse.range_y; + break; + case 0x05: /* Return Button Press Data */ + { + Bit16u but=reg_bx; + reg_ax=mouse.buttons; + reg_cx=mouse.last_pressed_x[but]; + mouse.last_pressed_x[but]=0; + reg_dx=mouse.last_pressed_y[but]; + mouse.last_pressed_y[but]=0; + reg_bx=mouse.times_pressed[but]; + mouse.times_pressed[but]=0; + break; + } + case 0x07: /* Define horizontal cursor range */ + mouse.min_x=reg_cx; + mouse.max_x=reg_dx; + mouse.range_x=mouse.max_x-mouse.min_x; +//TODO Check for range start 0 + break; + case 0x08: /* Define vertical cursor range */ + mouse.min_y=reg_cx; + mouse.max_y=reg_dx; + mouse.range_y=mouse.max_y-mouse.min_y; + break; + case 0x09: /* Define GFX Cursor */ + LOG_WARN("MOUSE:Define gfx cursor not supported"); + break; + case 0x0a: /* Define Text Cursor */ + /* Don't see much need for supporting this */ + break; + case 0x0c: /* Define interrupt subroutine parameters */ + mouse.sub_mask=reg_cx; + mouse.sub_seg=Segs[es].value; + mouse.sub_ofs=reg_dx; + break; + case 0x0f: /* Define mickey/pixel rate */ + //TODO Maybe dunno for sure might be possible */ + break; + case 0x0B: /* Read Motion Data */ + reg_cx=(Bit16s)(mouse.mickey_x*X_MICKEY); + reg_dx=(Bit16s)(mouse.mickey_y*Y_MICKEY); + mouse.mickey_x=0; + mouse.mickey_y=0; + break; + case 0x1c: /* Set interrupt rate */ + /* Can't really set a rate this is host determined */ + break; + case 0x21: /* Software Reset */ + //TODO reset internal mouse software variables likes mickeys + reg_ax=0xffff; + reg_bx=2; + break; + case 0x24: /* Get Software version and mouse type */ + reg_bx=0x805; //Version 8.05 woohoo + reg_ch=0xff; /* Unkown type */ + reg_cl=0; /* Hmm ps2 irq dunno */ + break; + default: + LOG_ERROR("Mouse Function %2X",reg_ax); + }; + return CBRET_NONE; +}; + +static Bitu INT74_Handler(void) { + if (mouse.events>0) { + mouse.events--; + /* Check for an active Interrupt Handler that will get called */ + if (mouse.sub_mask & mouse.event_queue[mouse.events].type) { + /* Save lot's of registers */ + Bit16u oldax,oldbx,oldcx,olddx,oldsi,olddi; + oldax=reg_ax;oldbx=reg_bx;oldcx=reg_cx;olddx=reg_dx;oldsi=reg_si;olddi=reg_di; + reg_ax=mouse.event_queue[mouse.events].type; + reg_bx=mouse.event_queue[mouse.events].buttons; + reg_cx=POS_X; + reg_dx=POS_Y; + reg_si=(Bit16s)(mouse.mickey_x*X_MICKEY); + reg_di=(Bit16s)(mouse.mickey_y*Y_MICKEY); + if (mouse.event_queue[mouse.events].type==MOUSE_MOVED) { + mouse.mickey_x=0; + mouse.mickey_y=0; + } + CALLBACK_RunRealFar(mouse.sub_seg,mouse.sub_ofs); + reg_ax=oldax;reg_bx=oldbx;reg_cx=oldcx;reg_dx=olddx;reg_si=oldsi;reg_di=olddi; + } + } + IO_Write(0xa0,0x20); + /* Check for more Events if so reactivate IRQ */ + + if (mouse.events) { + PIC_ActivateIRQ(12); + } + + return CBRET_NONE; +}; + + +void MOUSE_Init(void) { + call_int33=CALLBACK_Allocate(); + CALLBACK_Setup(call_int33,&INT33_Handler,CB_IRET); + real_writed(0,(0x33<<2),CALLBACK_RealPointer(call_int33)); + + call_int74=CALLBACK_Allocate(); + CALLBACK_Setup(call_int74,&INT74_Handler,CB_IRET); + real_writed(0,(0x74<<2),CALLBACK_RealPointer(call_int74)); + + memset((void *)&mouse,0,sizeof(mouse)); + mouse_reset(); +}; + diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp new file mode 100644 index 00000000..433e916c --- /dev/null +++ b/src/ints/xms.cpp @@ -0,0 +1,185 @@ +/* + * 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. + */ + +#include +#include "dosbox.h" +#include "callback.h" +#include "mem.h" +#include "regs.h" +#include "dos_system.h" + + +#define XMS_VERSION 0x0300 /* version 3.00 */ +#define XMS_DRIVER_VERSION 0x0301 /* my driver version 3.01 */ + +#define XMS_GET_VERSION 0x00 +#define XMS_ALLOCATE_HIGH_MEMORY 0x01 +#define XMS_FREE_HIGH_MEMORY 0x02 +#define XMS_GLOBAL_ENABLE_A20 0x03 +#define XMS_GLOBAL_DISABLE_A20 0x04 +#define XMS_LOCAL_ENABLE_A20 0x05 +#define XMS_LOCAL_DISABLE_A20 0x06 +#define XMS_QUERY_A20 0x07 +#define XMS_QUERY_FREE_EXTENDED_MEMORY 0x08 +#define XMS_ALLOCATE_EXTENDED_MEMORY 0x09 +#define XMS_FREE_EXTENDED_MEMORY 0x0a +#define XMS_MOVE_EXTENDED_MEMORY_BLOCK 0x0b +#define XMS_LOCK_EXTENDED_MEMORY_BLOCK 0x0c +#define XMS_UNLOCK_EXTENDED_MEMORY_BLOCK 0x0d +#define XMS_GET_EMB_HANDLE_INFORMATION 0x0e +#define XMS_RESIZE_EXTENDED_MEMORY_BLOCK 0x0f +#define XMS_ALLOCATE_UMB 0x10 +#define XMS_DEALLOCATE_UMB 0x11 + +#define HIGH_MEMORY_IN_USE 0x92 +#define HIGH_MEMORY_NOT_ALLOCATED 0x93 +#define XMS_OUT_OF_SPACE 0xa0 +#define XMS_INVALID_HANDLE 0xa2 + + +static Bit16u call_xms; +static RealPt xms_callback; + + +static bool multiplex_xms(void) { + switch (reg_ax) { + case 0x4300: /* XMS installed check */ + reg_al=0x80; + return true; + case 0x4310: /* XMS handler seg:offset */ + SetSegment_16(es,RealSeg(xms_callback)); + reg_bx=RealOff(xms_callback); + return true; + } + return false; + +}; + +#if defined (_MSC_VER) +#pragma pack(1) +#endif +struct XMS_MemMove{ + Bit32u length; + Bit16u src_handle; + RealPt src_offset; + Bit16u dest_handle; + RealPt dest_offset; +} +#if defined (_MSC_VER) +; +#pragma pack() +#else +__attribute__ ((packed)); +#endif + +static void XMS_MoveBlock(PhysPt block,Bit8u * result) { + XMS_MemMove moveblock; +//TODO Will not work on other endian, probably base it on a class would be nice + MEM_BlockRead(block,(Bit8u *)&moveblock,sizeof(XMS_MemMove)); + HostPt src; + PhysPt dest; + if (moveblock.src_handle) { + src=memory+EMM_Handles[moveblock.src_handle].phys_base+moveblock.src_offset; + } else { + src=Real2Host(moveblock.src_offset); + } + if (moveblock.dest_handle) { + dest=EMM_Handles[moveblock.dest_handle].phys_base+moveblock.dest_offset; + } else { + dest=Real2Phys(moveblock.dest_offset); + } + //memcpy((void *)dest,(void *)src,moveblock.length); + MEM_BlockWrite(dest,src,moveblock.length); + *result=0; +}; + + +Bitu XMS_Handler(void) { + switch (reg_ah) { + case XMS_GET_VERSION: /* 00 */ + reg_ax=XMS_VERSION; + reg_bx=XMS_DRIVER_VERSION; + reg_dx=0; //TODO HMA Maybe + break; + case XMS_ALLOCATE_HIGH_MEMORY: /* 01 */ + case XMS_FREE_HIGH_MEMORY: /* 02 */ + case XMS_GLOBAL_ENABLE_A20: /* 03 */ + case XMS_GLOBAL_DISABLE_A20: /* 04 */ + case XMS_LOCAL_ENABLE_A20: /* 05 */ + case XMS_LOCAL_DISABLE_A20: /* 06 */ + case XMS_QUERY_A20: /* 07 */ + LOG_WARN("XMS:Unhandled call %2X",reg_ah);break; + case XMS_QUERY_FREE_EXTENDED_MEMORY: /* 08 */ + EMM_GetFree(®_ax,®_dx); + reg_ax<<=2;reg_dx<<=2; + reg_bl=0; + break; + case XMS_ALLOCATE_EXTENDED_MEMORY: /* 09 */ + EMM_Allocate(PAGES(reg_dx*1024),®_dx); + if (reg_dx) reg_ax=1; + else { reg_ax=0;reg_bl=0xb0; } + break; + case XMS_FREE_EXTENDED_MEMORY: /* 0a */ + EMM_Free(reg_dx); + reg_ax=1; + break; + + case XMS_MOVE_EXTENDED_MEMORY_BLOCK: /* 0b */ + XMS_MoveBlock(real_phys(Segs[ds].value,reg_si),®_bl); + if (reg_bl) reg_ax=0; + else reg_ax=1; + break; + case XMS_LOCK_EXTENDED_MEMORY_BLOCK: /* 0c */ + if ((!EMM_Handles[reg_dx].active) || (EMM_Handles[reg_dx].free)) { + reg_ax=0; + reg_bl=0xa2; /* Invalid block */ + break; + } + reg_ax=1; + reg_bx=(Bit16u)((EMM_Handles[reg_dx].phys_base) & 0xffff); + reg_dx=(Bit16u)((EMM_Handles[reg_dx].phys_base >> 16) & 0xffff); + break; + case XMS_UNLOCK_EXTENDED_MEMORY_BLOCK: /* 0d */ + reg_ax=1; + break; + case XMS_GET_EMB_HANDLE_INFORMATION: /* 0e */ + LOG_WARN("XMS:Unhandled call %2X",reg_ah);break; + case XMS_RESIZE_EXTENDED_MEMORY_BLOCK: /* 0f */ + LOG_WARN("XMS:Unhandled call %2X",reg_ah);break; + case XMS_ALLOCATE_UMB: /* 10 */ + reg_ax=0; + reg_bl=0xb1; //No UMB Available + reg_dx=0; + break; + case XMS_DEALLOCATE_UMB: /* 11 */ + default: + LOG_WARN("XMS:Unhandled call %2X",reg_ah);break; + + } + return CBRET_NONE; +} + + + +void XMS_Init(void) { + DOS_AddMultiplexHandler(multiplex_xms); + call_xms=CALLBACK_Allocate(); + CALLBACK_Setup(call_xms,&XMS_Handler,CB_RETF); + xms_callback=CALLBACK_RealPointer(call_xms); +} + diff --git a/src/misc/Makefile.am b/src/misc/Makefile.am new file mode 100644 index 00000000..3d9eff2d --- /dev/null +++ b/src/misc/Makefile.am @@ -0,0 +1,4 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include + +noinst_LIBRARIES = libmisc.a +libmisc_a_SOURCES = plugins.cpp programs.cpp messages.cpp support.cpp setup.cpp diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp new file mode 100644 index 00000000..b07a11a3 --- /dev/null +++ b/src/misc/messages.cpp @@ -0,0 +1,107 @@ +/* + * 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. + */ + +#include +#include +#include +#include "dosbox.h" +#include "cross.h" +#include "support.h" +#include "setup.h" + + + +#define LINE_IN_MAXLEN 1024 + +struct MessageBlock +{ + char * name; + char * string; + MessageBlock * next; +}; + +static MessageBlock * first_message; + + +static void LoadMessageFile(char * fname) { + FILE * mfile=fopen(fname,"rb"); +/* This should never happen and since other modules depend on this use a normal printf */ + if (!mfile) { + E_Exit("MSG:Can't load messages",fname); + } + char linein[LINE_IN_MAXLEN]; + char name[LINE_IN_MAXLEN]; + char string[LINE_IN_MAXLEN*10]; + /* Start out with empty strings */ + name[0]=0;string[0]=0; + while(fgets(linein, LINE_IN_MAXLEN, mfile)!=0) { + /* Parse the read line */ + /* First remove characters 10 and 13 from the line */ + char * parser=linein; + char * writer=linein; + while (*parser) { + if (*parser!=10 && *parser!=13) { + *writer++=*parser; + } + *parser++; + } + *writer=0; + /* New string name */ + if (linein[0]==':') { + string[0]=0; + strcpy(name,linein+1); + /* End of string marker */ + } else if (linein[0]=='.') { + /* Save the string internally */ + size_t total=sizeof(MessageBlock)+strlen(name)+1+strlen(string)+1; + MessageBlock * newblock=(MessageBlock *)malloc(total); + newblock->name=((char *)newblock)+sizeof(MessageBlock); + newblock->string=newblock->name+strlen(name)+1; + strcpy(newblock->name,name); + strcpy(newblock->string,string); + newblock->next=first_message; + first_message=newblock; + } else { + /* Normal string to be added */ + strcat(string,linein); + strcat(string,"\n"); + } + } + fclose(mfile); +} + + +char * MSG_Get(char * msg) { + MessageBlock * index=first_message; + while (index) { + if (!strcmp(msg,index->name)) return index->string; + index=index->next; + } + return "Message not found"; +} + + + +void MSG_Init(void) { + /* Load the messages from "dosbox.lang file" */ + first_message=0; + char filein[CROSS_LEN]; + strcpy(filein,dosbox_basedir); + strcat(filein,"dosbox.lang"); + LoadMessageFile(filein); +} diff --git a/src/misc/plugins.cpp b/src/misc/plugins.cpp new file mode 100644 index 00000000..35cfe942 --- /dev/null +++ b/src/misc/plugins.cpp @@ -0,0 +1,159 @@ +/* + * 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. + */ + +#include +#include + +#ifdef WIN32 +#include +#endif + +#include "dosbox.h" +#include "regs.h" +#include "mem.h" +#include "inout.h" +#include "pic.h" +#include "modules.h" +#include "programs.h" +#include "timer.h" +#include "dma.h" +#include "mixer.h" + + +struct PLUGIN_Function { + char * name; + void * function; +}; + +struct PLUGIN_Module { +#ifdef WIN32 + HINSTANCE handle; +#endif + + PLUGIN_Module * next; +}; + + +static PLUGIN_Function functions[]={ +"IO_RegisterReadHandler", (void *)IO_RegisterReadHandler, +"IO_RegisterWriteHandler", (void *)IO_RegisterWriteHandler, +"IO_FreeReadHandler", (void *)IO_FreeReadHandler, +"IO_FreeWriteHandler", (void *)IO_FreeWriteHandler, + +"IRQ_RegisterEOIHandler", (void *)PIC_RegisterIRQ, +"IRQ_FreeEOIHandler", (void *)PIC_FreeIRQ, +"IRQ_Activate", (void *)PIC_ActivateIRQ, +"IRQ_Deactivate", (void *)PIC_DeActivateIRQ, + +"TIMER_RegisterMicroHandler", (void *)TIMER_RegisterMicroHandler, +"TIMER_RegisterTickHandler", (void *)TIMER_RegisterTickHandler, + +"DMA_8_Read", (void *)DMA_8_Read, +"DMA_16_Read", (void *)DMA_16_Read, + +"DMA_8_Write", (void *)DMA_8_Write, +"DMA_16_Write", (void *)DMA_16_Write, + +"MIXER_AddChannel", (void *)MIXER_AddChannel, +"MIXER_SetVolume", (void *)MIXER_SetVolume, +"MIXER_SetFreq", (void *)MIXER_SetFreq, +"MIXER_SetMode", (void *)MIXER_SetMode, +"MIXER_Enable", (void *)MIXER_Enable, + +0,0 +}; + + +class PLUGIN : public Program { +public: + PLUGIN(PROGRAM_Info * program_info); + void Run(void); +}; + +PLUGIN::PLUGIN(PROGRAM_Info * info):Program(info) { + +} + + +void PLUGIN::Run(void) { + +} + + + +static void PLUGIN_ProgramStart(PROGRAM_Info * info) { + PLUGIN * tempPLUGIN=new PLUGIN(info); + tempPLUGIN->Run(); + delete tempPLUGIN; +} + + + +bool PLUGIN_FindFunction(char * name,void * * function) { +/* Run through table and hope to find a match */ + Bitu index=0; + while (functions[index].name) { + if (strcmp(functions[index].name,name)==0) { + *function=functions[index].function; + return true; + }; + index++; + } + return false; +} + + +bool PLUGIN_LoadModule(char * name) { + MODULE_StartHandler starter; + +#ifdef WIN32 + HMODULE module; + module=LoadLibrary(name); + if (!module) return false; +/* Look for the module start functions */ + FARPROC address; + address=GetProcAddress(module,MODULE_START_PROC); + starter=(MODULE_StartHandler)address; +#else +//TODO LINUX + + + + +#endif + starter(PLUGIN_FindFunction); +return false; + +} + + + +void PLUGIN_Init(void) { + PROGRAMS_MakeFile("PLUGIN.COM",PLUGIN_ProgramStart); +// PLUGIN_LoadModule("c:\\dosbox\\testmod.dll"); +}; + + + + + + + + + + diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp new file mode 100644 index 00000000..1e974892 --- /dev/null +++ b/src/misc/programs.cpp @@ -0,0 +1,174 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include "programs.h" +#include "callback.h" +#include "regs.h" +#include "support.h" +#include "cross.h" + +Bitu call_program; + +/* This registers a file on the virtual drive and creates the correct structure for it*/ + +static Bit8u exe_block[]={ + 0xbc,0x00,0x03, //MOV SP,0x300 decrease stack size + 0xbb,0x30,0x00, //MOV BX,0x030 for memory resize + 0xb4,0x4a, //MOV AH,0x4A Resize memory block + 0xcd,0x21, //INT 0x21 +//pos 12 is callback number + 0xFE,0x38,0x00,0x00, //CALLBack number + 0xb8,0x00,0x4c, //Mov ax,4c00 + 0xcd,0x21, //INT 0x21 +}; + +#define CB_POS 12 + +void PROGRAMS_MakeFile(char * name,PROGRAMS_Main * main) { + Bit8u * comdata=(Bit8u *)malloc(128); + memcpy(comdata,&exe_block,sizeof(exe_block)); + comdata[CB_POS]=call_program&0xff; + comdata[CB_POS+1]=(call_program>>8)&0xff; +/* Copy the pointer this should preserve endianes */ + memcpy(&comdata[sizeof(exe_block)],&main,sizeof(main)); + Bit32u size=sizeof(exe_block)+sizeof(main); + VFILE_Register(name,comdata,size); +} + + +static Bitu PROGRAMS_Handler(void) { + /* This sets up everything for a program start up call */ + /* First get the current psp */ + PROGRAM_Info * info=new PROGRAM_Info; + info->psp_seg=dos.psp; + MEM_BlockRead(real_phys(dos.psp,0),&info->psp_copy,sizeof(PSP)); + /* Get the file name cmd_line 0 */ + PhysPt envblock=real_phys(info->psp_copy.environment,0); + do {} while (mem_readw(envblock++)); + envblock+=3; + MEM_StrCopy(envblock,info->full_name,32); + info->psp_copy.cmdtail.buffer[info->psp_copy.cmdtail.count]=0; + info->cmd_line=info->psp_copy.cmdtail.buffer; + /* Find the program handler somewhere reference in the file */ + Bit16u handle; + DOS_OpenFile(info->full_name,0,&handle); + Bit32u pos=sizeof(PROGRAMS_Main *); + DOS_SeekFile(handle,&pos,DOS_SEEK_END); + PROGRAMS_Main * handler; + Bit16u size=sizeof(PROGRAMS_Main *); + DOS_ReadFile(handle,(Bit8u *)&handler,&size); + DOS_CloseFile(handle); + (*handler)(info); + free(info); + return CBRET_NONE; +}; + + +/* Main functions used in all program */ + + +Program::Program(PROGRAM_Info * program_info) { + prog_info=program_info; +} + +void Program::WriteOut(char * format,...) { + char buf[1024]; + va_list msg; + + va_start(msg,format); + vsprintf(buf,format,msg); + va_end(msg); + + Bit16u size=strlen(buf); + DOS_WriteFile(STDOUT,(Bit8u *)buf,&size); +} + + +char * Program::GetEnvStr(char * env_str) { + /* Walk through the internal environment and see for a match */ +/* Taking some short cuts here to not fuck around with memory structure */ + + char * envstart=(char *)real_host(prog_info->psp_copy.environment,0); + size_t len=strlen(env_str); + while (*envstart) { + if (strncasecmp(env_str,envstart,len)==0 && envstart[len]=='=') { + return envstart; + } + envstart+=strlen(envstart)+1; + } + return 0; +}; + +char * Program::GetEnvNum(Bit32u num) { + char * envstart=(char *)real_host(prog_info->psp_copy.environment,0); + while (*envstart) { + if (!num) return envstart; + envstart+=strlen(envstart)+1; + num--; + } + return 0; +} + +Bit32u Program::GetEnvCount(void) { + char * envstart=(char *)real_host(prog_info->psp_copy.environment,0); + Bit32u num=0; + while (*envstart) { + envstart+=strlen(envstart)+1; + num++; + } + return num; +} + +bool Program::SetEnv(char * env_entry,char * new_string) { + MCB * env_mcb=(MCB *)real_host(prog_info->psp_copy.environment-1,0); + upcase(env_entry); + Bit32u env_size=env_mcb->size*16; + if (!env_size) E_Exit("SHELL:Illegal environment size"); + /* First try to find the old entry */ + size_t len=strlen(env_entry); + char * envstart=(char *)real_host(prog_info->psp_copy.environment,0); + while (*envstart) { + if (strncasecmp(env_entry,envstart,len)==0 && envstart[len]=='=') { + /* Now remove this entry */ + memmove(envstart,envstart+strlen(envstart)+1,env_size); + } else { + envstart+=strlen(envstart)+1; + env_size-=(strlen(envstart)+1); + } + } + /* Now add the string if there is space available */ + if (env_size<(strlen(env_entry)+strlen(new_string)+2)) return false; + if (!*new_string) return true; + sprintf(envstart,"%s=%s",env_entry,new_string); + envstart+=strlen(envstart)+1; + *envstart++=0;*envstart++=0;*envstart++=0; + return true; +} + +//TODO Hash table :) + + +void PROGRAMS_Init(void) { + /* Setup a special callback to start virtual programs */ + call_program=CALLBACK_Allocate(); + CALLBACK_Setup(call_program,&PROGRAMS_Handler,CB_RETF); +} diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp new file mode 100644 index 00000000..69d47cb6 --- /dev/null +++ b/src/misc/setup.cpp @@ -0,0 +1,29 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "cross.h" +#include "setup.h" + +void SETUP_AddBoolHandler() { + + +}; + + + diff --git a/src/misc/support.cpp b/src/misc/support.cpp new file mode 100644 index 00000000..1348dc71 --- /dev/null +++ b/src/misc/support.cpp @@ -0,0 +1,224 @@ +/* + * 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. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include "dosbox.h" +#include "support.h" + + +/* + Ripped some source from freedos for this one. + +*/ + + +/* + * replaces all instances of character o with character c + */ + + +void strreplace(char * str,char o,char n) { + while (*str) { + if (*str==o) *str=n; + str++; + } +} +/* + * Name: ltrim() - left trims a string by removing leading spaces + * Input: str - a pointer to a string + * Output: returns a trimmed copy of str + */ +char *ltrim(char *str) { + char c; + assert(str); + + while ((c = *str++) != '\0' && isspace(c)); + return str - 1; +} + +/* + * Name: rtrim() - right trims a string by removing trailing spaces + * Input: str - a pointer to a string + * Output: str will have all spaces removed from the right. + */ +void rtrim(char * const str) { + char *p; + + assert(str); + + p = strchr(str, '\0'); + while (--p >= str && isspace(*p)); + p[1] = '\0'; +} + +/* + * Combines ltrim() & rtrim() + */ +char *trim(char *str) { + assert(str); + rtrim(str); + return ltrim(str); +} + +bool wildcmp(char *wild, char *string) { + char *cp, *mp; + while ((*string) && (*wild != '*')) { + if ((*wild != *string) && (*wild != '?')) { + return false; + } + wild++; + string++; + } + + while (*string) { + if (*wild == '*') { + if (!*++wild) { + return true; + } + mp = wild; + cp = string+1; + } else if ((*wild == *string) || (*wild == '?')) { + wild++; + string++; + } else { + wild = mp; + string = cp++; + } + } + + while (*wild == '*') { + wild++; + } + return !*wild; +} + + +bool ScanCMDBool(char * cmd,char * check) { + char * scan=cmd;size_t c_len=strlen(check); + while (scan=strchr(scan,'/')) { + /* found a / now see behind it */ + scan++; + if (strncasecmp(scan,check,c_len)==0 && (scan[c_len]==' ' || scan[c_len]==0)) { + /* Found a math now remove it from the string */ + memmove(scan-1,scan+c_len,strlen(scan+c_len)+1); + trim(scan-1); + return true; + } + } + return false; +} + + +bool ScanCMDHex(char * cmd,char * check,Bits * result) { + char * scan=cmd;size_t c_len=strlen(check); + while (scan=strchr(scan,'/')) { + /* found a / now see behind it */ + scan++; + if (strncasecmp(scan,check,c_len)==0 && (scan[c_len]==' ' || scan[c_len]==0)) { + /* Found a match now find the number and remove it from the string */ + char * begin=scan-1; + scan=ltrim(scan+c_len); + bool res=true; + *result=-1; + if (!sscanf(scan,"%X",result)) res=false; + scan=strrchr(scan,'/'); + if (scan) memmove(begin,scan,strlen(scan)+1); + else *begin=0; + trim(begin); + return res; + } + } + return false; + +} + +/* This scans the command line for a remaining switch and reports it else returns 0*/ +char * ScanCMDRemain(char * cmd) { + char * scan,*found;; + if (scan=found=strchr(cmd,'/')) { + while (*scan!=' ' && *scan!=0) scan++; + *scan=0; + return found; + } else return 0; +} + +char * StripWord(char * cmd) { + bool quoted=false; + char * begin=cmd; + if (*cmd=='"') { + quoted=true; + cmd++; + } + char * end; + if (quoted) { + end=strchr(cmd,'"'); + } else { + end=strchr(cmd,' '); + } + if (!end) { + return cmd+strlen(cmd); + } + *end=0; + if (quoted) { + memmove(begin,cmd,end-begin+1); + } + return trim(cmd+strlen(begin)+1); +} + +void GFX_ShowMsg(char * msg); +void DEBUG_ShowMsg(char * msg); + +void S_Warn(char * format,...) { + char buf[1024]; + va_list msg; + + va_start(msg,format); + vsprintf(buf,format,msg); + va_end(msg); +#ifdef C_DEBUG + DEBUG_ShowMsg(buf); +#else + GFX_ShowMsg(buf); +#endif +} + +void E_Exit(char * format,...) { + + char buf[1024]; + +// SysShutDown(); + va_list msg; + strcpy(buf,"EXIT:"); + va_start(msg,format); + vsprintf(buf+strlen(buf),format,msg); + va_end(msg); + + strcat(buf,"\n"); + printf(buf); + printf("Press ENTER to stop\n"); + fgetc(stdin); + exit(2); + +}; \ No newline at end of file diff --git a/src/platform/Makefile.am b/src/platform/Makefile.am new file mode 100644 index 00000000..6efd8903 --- /dev/null +++ b/src/platform/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = visualc \ No newline at end of file diff --git a/src/platform/visualc/Makefile.am b/src/platform/visualc/Makefile.am new file mode 100644 index 00000000..605cef90 --- /dev/null +++ b/src/platform/visualc/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST = dirent.c dirent.h unistd.h config.h diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h new file mode 100644 index 00000000..9ad95e12 --- /dev/null +++ b/src/platform/visualc/config.h @@ -0,0 +1,5 @@ +#define INLINE __forceinline + +#define VERSION "0.50" + +/* Euhm */ diff --git a/src/platform/visualc/dirent.c b/src/platform/visualc/dirent.c new file mode 100644 index 00000000..1f8df13e --- /dev/null +++ b/src/platform/visualc/dirent.c @@ -0,0 +1,93 @@ +/* + * Implementation of the standard functions in direct.h + * + * opendir(), readdir(), closedir() and rewinddir(). + * + * 06/17/2000 by Mike Haaland + */ + +#include "dirent.h" + +#ifdef WIN32 + +/** open the current directory and return a structure + * to be used in subsequent readdir() and closedir() + * calls. + * + * returns NULL if one error. + */ +DIR * opendir(const char *dirname) { + + static DIR dir; + + /* Stash the directory name */ + strcpy(dir.pathName,dirname); + + /* set the handle to invalid and set the firstTime flag */ + dir.handle = INVALID_HANDLE_VALUE; + dir.firstTime = TRUE; + + if (strcmp(dirname, ".") == 0) { + return &dir; + } + + /* Change the current directory to the one requested */ + return (SetCurrentDirectory(dir.pathName) != 0) ? &dir : NULL; +} + +/** Close the current directory - return 0 if success */ +int closedir(DIR *dirp) { + /* reset ourselves to the first file in the directory + * + * We just close the current handle and reset for the + * next readdir call + */ + int result = 1; + + if (dirp->handle != INVALID_HANDLE_VALUE) + { + result = FindClose(dirp->handle); + dirp->handle = INVALID_HANDLE_VALUE; + } + + return (result == 0) ? 1 : 0; +} + +/** get the next entry in the directory */ +struct dirent * readdir(DIR *dirp) { + static struct dirent d; + + if (TRUE == dirp->firstTime) + { + /** Get the first entry in the directory */ + dirp->handle = FindFirstFile("*.*", &dirp->findFileData); + dirp->firstTime = FALSE; + if (INVALID_HANDLE_VALUE == dirp->handle) + { + return NULL; + } + } + else + { + int result = FindNextFile(dirp->handle, &dirp->findFileData); + if (0 == result ) + { + return NULL; + } + } + /* we have a valid FIND_FILE_DATA, copy the filename */ + memset(&d,'\0', sizeof(struct dirent)); + + strcpy(d.d_name,dirp->findFileData.cFileName); + d.d_namlen = strlen(d.d_name); + + return &d; +} + +/** reopen the current directory */ +void rewinddir(DIR *dirp) { + closedir(dirp); + dirp->firstTime = TRUE; +} + +#endif diff --git a/src/platform/visualc/dirent.h b/src/platform/visualc/dirent.h new file mode 100644 index 00000000..c37dbb60 --- /dev/null +++ b/src/platform/visualc/dirent.h @@ -0,0 +1,58 @@ + + +/* + * Defines and structures used to implement the + * functionality standard in direct.h for: + * + * opendir(), readdir(), closedir() and rewinddir(). + * + * 06/17/2000 by Mike Haaland + */ +#ifndef _DIRENT_H_ +#define _DIRENT_H_ + +#ifdef _MSC_VER + + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#if !defined(__GNUC__) +/* Convienience macros used with stat structures */ +#define S_ISDIR(x) (x & _S_IFDIR) +#define S_ISREG(x) (x & _S_IFREG) +#endif + + +/* Structure to keep track of the current directory status */ +typedef struct my_dir { + HANDLE handle; + WIN32_FIND_DATA findFileData; + BOOLEAN firstTime; + char pathName[MAX_PATH]; +} DIR; + +/* Standard directory name entry returned by readdir() */ +struct dirent { + char d_namlen; + char d_name[MAX_PATH]; +}; + +/* function prototypes */ +int closedir(DIR *dirp); +DIR * opendir(const char *dirname); +struct dirent * readdir(DIR *dirp); +void rewinddir(DIR *dirp); + +#ifdef __cplusplus +} +#endif + +#endif +#endif + diff --git a/src/platform/visualc/unistd.h b/src/platform/visualc/unistd.h new file mode 100644 index 00000000..8f51f766 --- /dev/null +++ b/src/platform/visualc/unistd.h @@ -0,0 +1,10 @@ +/* + * This file is part of the Mingw32 package. + * + * unistd.h maps (roughly) to io.h + */ + +#ifndef __STRICT_ANSI__ +#include +#endif + diff --git a/src/shell/Makefile.am b/src/shell/Makefile.am new file mode 100644 index 00000000..a9476e9d --- /dev/null +++ b/src/shell/Makefile.am @@ -0,0 +1,4 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include + +noinst_LIBRARIES = libshell.a +libshell_a_SOURCES = shell.cpp shell_batch.cpp shell_cmds.cpp shell_inc.h shell_misc.cpp diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp new file mode 100644 index 00000000..63e4dadd --- /dev/null +++ b/src/shell/shell.cpp @@ -0,0 +1,177 @@ +/* + * 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. + */ + + +#include +#include +#include "shell_inc.h" + +Bitu call_shellstop; + +static Bitu shellstop_handler(void) { + return CBRET_STOP; +} + +static void SHELL_ProgramStart(PROGRAM_Info * info) { + DOS_Shell * tempshell=new DOS_Shell(info); + tempshell->Run(); + delete tempshell; +} + +#define AUTOEXEC_SIZE 4096 +static char autoexec_data[AUTOEXEC_SIZE]={0}; + +void SHELL_AddAutoexec(char * line,...) { + char buf[2048]; + va_list msg; + + va_start(msg,line); + vsprintf(buf,line,msg); + va_end(msg); + + size_t auto_len=strlen(autoexec_data); + if ((auto_len+strlen(line)+3)>AUTOEXEC_SIZE) { + E_Exit("SYSTEM:Autoexec.bat file overlow"); + } + sprintf((autoexec_data+auto_len),"%s\r\n",buf); +} + + +DOS_Shell::DOS_Shell(PROGRAM_Info * info):Program(info) { + input_handle=STDIN; + echo=true; + exit=false; + bf=0; + memset(&old.buffer,0,CMD_OLDSIZE); + old.size=0; +} + + + + +Bit32u DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn) { + + + return 1; +} + + + +void DOS_Shell::ParseLine(char * line) { + + char * in=0; + char * out=0; + char * fname0=0; + char * fname1=0; + + /* Check for a leading @ */ + if (line[0]=='@') line[0]=' '; + line=trim(line); + Bit32u num=0; /* Number of commands in this line */ + + num = GetRedirection(line,&in, &out); + +/* TODO in and out redirection */ + + DoCommand(line); + +} + + + +void DOS_Shell::Run(void) { + /* Check for a direct Command */ + if (strncasecmp(prog_info->cmd_line,"/C ",3)==0) { + ParseLine(prog_info->cmd_line+3); + return; + } + /* Start a normal shell and check for a first command init */ + WriteOut(MSG_Get("SHELL_STARTUP")); + char input_line[CMD_MAXLINE]; + if (strncasecmp(prog_info->cmd_line,"/INIT ",6)==0) { + ParseLine(prog_info->cmd_line+6); + } + do { + if (bf && bf->ReadLine(input_line)) { + if (echo) { + if (input_line[0]!='@') { + ShowPrompt(); + WriteOut(input_line); + WriteOut("\n"); + }; + }; + } else { + if (echo) ShowPrompt(); + InputCommand(input_line); + + } + ParseLine(input_line); + if (echo) WriteOut("\n"); + } while (!exit); +} + +void DOS_Shell::SyntaxError(void) { + WriteOut(MSG_Get("SHELL_SYNTAXERROR")); +} + + + + +void SHELL_Init() { + call_shellstop=CALLBACK_Allocate(); + CALLBACK_Setup(call_shellstop,shellstop_handler,CB_IRET); + PROGRAMS_MakeFile("COMMAND.COM",SHELL_ProgramStart); + /* Now call up the shell for the first time */ + Bit16u psp_seg=DOS_GetMemory(16); + Bit16u env_seg=DOS_GetMemory(1+(4096/16)); + /* Setup a fake MCB for the environment */ + MCB * env_mcb=(MCB *)real_host(env_seg,0); + env_mcb->psp_segment=psp_seg; + env_mcb->size=4096/16; + real_writed(env_seg+1,0,0); + + PSP * psp=(PSP *)real_host(psp_seg,0); + Bit32u i; + for (i=0;i<20;i++) psp->files[i]=0xff; + psp->files[STDIN]=DOS_FindDevice("CON"); + psp->files[STDOUT]=DOS_FindDevice("CON"); + psp->files[STDERR]=DOS_FindDevice("CON"); + psp->files[STDAUX]=DOS_FindDevice("CON"); + psp->files[STDNUL]=DOS_FindDevice("CON"); + psp->files[STDPRN]=DOS_FindDevice("CON"); + psp->max_files=20; + psp->file_table=RealMake(psp_seg,offsetof(PSP,files)); + /* Save old DTA in psp */ + psp->dta=dos.dta; + psp->environment=env_seg+1; + + /* Setup internal DOS Variables */ + dos.dta=RealMake(psp_seg,0x80); + dos.psp=psp_seg; + PROGRAM_Info info; + strcpy(info.full_name,"Z:\\COMMAND.COM"); + info.psp_seg=psp_seg; + MEM_BlockRead(real_phys(dos.psp,0),&info.psp_copy,sizeof(PSP)); + char line[256]; + strcpy(line,"/INIT Z:\\AUTOEXEC.BAT"); + info.cmd_line=line; + +/* Handle the last AUTOEXEC.BAT Setup stuff */ + VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,strlen(autoexec_data)); + SHELL_ProgramStart(&info); +} diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp new file mode 100644 index 00000000..499a8756 --- /dev/null +++ b/src/shell/shell_batch.cpp @@ -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. + */ + +#include +#include + +#include "shell_inc.h" +#include "cpu.h" + + +BatchFile::BatchFile(DOS_Shell * host,char * name, char * cmd_line) { + /* Go through the command line */ + char * cmd_write=cmd_buffer; + prev=host->bf; + echo=host->echo; + shell=host; + cmd_count=0; + while (*cmd_line || (cmd_countbf=prev; + shell->echo=echo; +} + +bool BatchFile::ReadLine(char * line) { + Bit8u c;Bit16u n; + char temp[CMD_MAXLINE]; +emptyline: + char * cmd_write=temp; + do { + n=1; + DOS_ReadFile(file_handle,&c,&n); + if (n>0) { + if (c>31) + *cmd_write++=c; + } + } while (c!='\n' && n); + *cmd_write++=0; + if (!n) { + delete this; + return false; + } + if (!strlen(temp)) goto emptyline; + if (temp[0]==':') goto emptyline; +/* Now parse the line read from the bat file for % stuff */ + cmd_write=line; + char * cmd_read=temp; + char env_name[256];char * env_write; + while (*cmd_read) { + env_write=env_name; + if (*cmd_read=='%') { + cmd_read++; + /* Find the fullstring of this */ + + + continue; + + } else { + *cmd_write++=*cmd_read++; + } + *cmd_write=0; + } + return true; + +} + + +bool BatchFile::Goto(char * where) { + Bit32u pos=0; + char cmd[CMD_MAXLINE]; + char * cmd_write; + DOS_SeekFile(file_handle,&pos,DOS_SEEK_SET); + + /* Scan till we have a match or return false*/ + Bit8u c;Bit16u n; +again: + cmd_write=cmd; + do { + n=1; + DOS_ReadFile(file_handle,&c,&n); + if (n>0) { + if (c>31) + *cmd_write++=c; + } + } while (c!='\n' && n); + *cmd_write++=0; + if (cmd[0]==':') { + if (strcasecmp(cmd+1,where)==0) return true; + } + if (!n) { + delete this; + return false; + } + goto again; + return false; +}; diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp new file mode 100644 index 00000000..c34624b9 --- /dev/null +++ b/src/shell/shell_cmds.cpp @@ -0,0 +1,380 @@ +/* + * 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. + */ +#include + +#include "shell_inc.h" +#include "callback.h" +#include "regs.h" + + + +static SHELL_Cmd cmd_list[]={ + "CD", 0, &DOS_Shell::CMD_CHDIR, "Change Directory.", + "CLS", 0, &DOS_Shell::CMD_CLS, "Clear screen.", +// "COPY", 0, &DOS_Shell::CMD_COPY, "Copy Files.", + "DIR", 0, &DOS_Shell::CMD_DIR, "Directory View.", + "ECHO", 0, &DOS_Shell::CMD_ECHO, "Display messages and enable/disable command echoing.", + "EXIT", 0, &DOS_Shell::CMD_EXIT, "Exit from the shell.", + "HELP", 0, &DOS_Shell::CMD_HELP, "Show help.", + "MD", 0, &DOS_Shell::CMD_MKDIR, "Make Directory.", + "RD", 0, &DOS_Shell::CMD_RMDIR, "Remove Directory.", + "SET", 0, &DOS_Shell::CMD_SET, "Change environment variables.", + "IF", 0, &DOS_Shell::CMD_IF, "Performs conditional processing in batch programs.", + "GOTO", 0, &DOS_Shell::CMD_GOTO, "Jump to a labeled line in a batch script.", + "TYPE", 0, &DOS_Shell::CMD_TYPE, "Display the contents of a text-file.", +/* + "CHDIR", 0, &DOS_Shell::CMD_CHDIR, "Change Directory", + "MKDIR", 0, &DOS_Shell::CMD_MKDIR, "Make Directory", + "RMDIR", 0, &DOS_Shell::CMD_RMDIR, "Remove Directory", +*/ + 0,0,0,0 +}; + +void DOS_Shell::DoCommand(char * line) { +/* First split the line into command and arguments */ + line=trim(line); + char cmd[255]; + char * cmd_write=cmd; + while (*line) { + if (*line==32) break; + if (*line=='/') break; + *cmd_write++=*line++; + } + *cmd_write=0; + if (strlen(cmd)==0) return; + line=trim(line); +/* Check the internal list */ + Bit32u cmd_index=0; + while (cmd_list[cmd_index].name) { + if (strcasecmp(cmd_list[cmd_index].name,cmd)==0) { +//TODO CHECK Flags + (this->*(cmd_list[cmd_index].handler))(line); + return; + } + cmd_index++; + } +/* This isn't an internal command execute it */ + Execute(cmd,line); +} + + +void DOS_Shell::CMD_CLS(char * args) { + reg_ax=0x0003; + CALLBACK_RunRealInt(0x10); +}; + +void DOS_Shell::CMD_HELP(char * args){ + /* Print the help */ + WriteOut(MSG_Get("SHELL_CMD_HELP")); + Bit32u cmd_index=0; + while (cmd_list[cmd_index].name) { + if (!cmd_list[cmd_index].flags) WriteOut("%-8s %s\n",cmd_list[cmd_index].name,cmd_list[cmd_index].help); + cmd_index++; + } + +} + +void DOS_Shell::CMD_ECHO(char * args) { + if (!*args) { + if (echo) { WriteOut(MSG_Get("SHELL_CMD_ECHO_ON"));} + else { WriteOut(MSG_Get("SHELL_CMD_ECHO_OFF"));} + return; + } + if (strcasecmp(args,"OFF")==0) { + echo=false; + return; + } + if (strcasecmp(args,"ON")==0) { + echo=true; + return; + } + WriteOut("%s\n",args); +}; + +void DOS_Shell::CMD_EXIT(char * args) { + exit=true; +}; + +void DOS_Shell::CMD_CHDIR(char * args) { + if (!*args) { + Bit8u drive=DOS_GetDefaultDrive()+'A'; + Bit8u dir[DOS_PATHLENGTH]; + DOS_GetCurrentDir(0,dir); + WriteOut("%c:\\%s\n",drive,dir); + } + if (DOS_ChangeDir(args)) { + + } else { + WriteOut(MSG_Get("SHELL_CMD_CHDIR_ERROR"),args); + } + +}; + +void DOS_Shell::CMD_MKDIR(char * args) { + char * rem=ScanCMDRemain(args); + if (rem) { + WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); + return; + } + if (!DOS_MakeDir(args)) { + WriteOut(MSG_Get("SHELL_CMD_MKDIR_ERROR"),args); + } +}; + +void DOS_Shell::CMD_RMDIR(char * args) { + char * rem=ScanCMDRemain(args); + if (rem) { + WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); + return; + } + if (!DOS_RemoveDir(args)) { + WriteOut(MSG_Get("SHELL_CMD_RMDIR_ERROR"),args); + } +}; + +static void FormatNumber(Bit32u num,char * buf) { + Bit32u numm,numk,numb; + numb=num % 1000; + num/=1000; + numk=num % 1000; + num/=1000; + numm=num; + if (numm) { + sprintf(buf,"%d,%03d,%03d",numm,numk,numb); + return; + }; + if (numk) { + sprintf(buf,"%d,%03d",numk,numb); + return; + }; + sprintf(buf,"%d",numb); +} + +void DOS_Shell::CMD_DIR(char * args) { + char numformat[16]; + char path[DOS_PATHLENGTH]; + + bool optW=ScanCMDBool(args,"W"); + bool optS=ScanCMDBool(args,"S"); + bool optP=ScanCMDBool(args,"P"); + char * rem=ScanCMDRemain(args); + if (rem) { + WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); + return; + } + + Bit32u byte_count,file_count,dir_count; + Bit32u w_count=0; + byte_count=file_count=dir_count=0; + + if (strlen(args)==0) args="*.*"; + + /* Make a full path in the args */ + if (!DOS_Canonicalize(args,(Bit8u*)path)) { + WriteOut(MSG_Get("SHELL_CMD_DIR_PATH_ERROR")); + return; + } + *(strrchr(path,'\\')+1)=0; + WriteOut(MSG_Get("SHELL_CMD_DIR_INTRO"),path); + + DTA_FindBlock * dta; + dta=(DTA_FindBlock *)Real2Host(dos.dta); + bool ret=DOS_FindFirst(args,0xffff); + if (!ret) { + WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); + return; + } + + while (ret) { + +/* File name and extension */ + char * ext=""; + if (!optW && (*dta->name != '.')) { + ext = strrchr(dta->name, '.'); + if (!ext) ext = ""; + else *ext++ = '\0'; + }; + + Bit8u day = dta->date & 0x001f; + Bit8u month = (dta->date >> 5) & 0x000f; + Bit8u hour = dta->time >> 5 >> 6; + Bit8u minute = (dta->time >> 5) & 0x003f; + Bit16u year = (dta->date >> 9) + 1980; + + /* output the file */ + if (dta->attr & DOS_ATTR_DIRECTORY) { + if (optW) { + WriteOut("[%s]",dta->name); + for (Bitu i=14-strlen(dta->name);i>0;i--) WriteOut(" "); + } else { + WriteOut("%-8s %-3s %-16s %02d-%02d-%04d %2d:%02d\n",dta->name,ext,"",day,month,year,hour,minute); + } + dir_count++; + } else { + if (optW) { + WriteOut("%-16s",dta->name); + } else { + FormatNumber(dta->size,numformat); + WriteOut("%-8s %-3s %16s %02d-%02d-%04d %2d:%02d\n",dta->name,ext,numformat,day,month,year,hour,minute); + } + file_count++; + byte_count+=dta->size; + } + if (optW) { + w_count++; + } + ret=DOS_FindNext(); + } + if (optW) { + if (w_count%5) WriteOut("\n"); + } + /* Show the summary of results */ + FormatNumber(byte_count,numformat); + WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_USED"),file_count,numformat); + //TODO Free Space + FormatNumber(1024*1024*100,numformat); + WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_FREE"),dir_count,numformat); +} + +void DOS_Shell::CMD_COPY(char * args) { + char * rem=ScanCMDRemain(args); + if (rem) { + WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); + return; + } + +} + +void DOS_Shell::CMD_SET(char * args) { + if (!*args) { + /* No command line show all environment lines */ + Bit32u count=GetEnvCount(); + for (Bit32u a=0;a=n) ==(!has_not)) DoCommand(args); + return; + } + /* Normal if string compare */ + if (!*args) { SyntaxError();return;}; + char * word2=args; + args=StripWord(word2); + if ((strcmp(word,word2)==0)==(!has_not)) DoCommand(args); +} + +void DOS_Shell::CMD_GOTO(char * args) { + if (!bf) return; + if (*args==':') args++; + if (!*args) { + WriteOut(MSG_Get("SHELL_CMD_GOTO_MISSING_LABEL")); + return; + } + if (!bf->Goto(args)) { + WriteOut(MSG_Get("SHELL_CMD_GOTO_LABEL_NOT_FOUND"),args); + return; + } +} + + +void DOS_Shell::CMD_TYPE(char * args) { + + if (!*args) { + WriteOut(MSG_Get("SHELL_SYNTAXERROR")); + return; + } + Bit16u handle; + char * word; +nextfile: + word=args; + args=StripWord(word); + if (!DOS_OpenFile(word,0,&handle)) { + WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),word); + return; + } + Bit16u n;Bit8u c; + do { + n=1; + DOS_ReadFile(handle,&c,&n); + DOS_WriteFile(STDOUT,&c,&n); + } while (n); + DOS_CloseFile(handle); + if (*args) goto nextfile; +} + + + diff --git a/src/shell/shell_inc.h b/src/shell/shell_inc.h new file mode 100644 index 00000000..d76d4ba9 --- /dev/null +++ b/src/shell/shell_inc.h @@ -0,0 +1,102 @@ +/* + * 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. + */ +#include +#include +#include "dosbox.h" +#include "mem.h" +#include "programs.h" +#include "dos_inc.h" +#include "regs.h" +#include "support.h" +#include "callback.h" + +#define CMD_MAXLINE 4096 +#define CMD_MAXCMDS 20 +#define CMD_OLDSIZE 4096 +extern Bitu call_shellstop; +class DOS_Shell; + + +class BatchFile { +public: + BatchFile(DOS_Shell * host,char * name, char * cmd_line); + ~BatchFile(); + bool ReadLine(char * line); + bool Goto(char * where); + Bit16u file_handle; + Bit32u line_count; + char * cmd_words[CMD_MAXCMDS]; + char cmd_buffer[128]; //Command line can only be 128 chars + Bit32u cmd_count; + bool echo; + DOS_Shell * shell; + BatchFile * prev; +}; + + + +class DOS_Shell : public Program { +public: + DOS_Shell(PROGRAM_Info * program_info); + void Run(void); +/* A load of subfunctions */ + void ParseLine(char * line); + Bit32u GetRedirection(char *s, char **ifn, char **ofn); + void InputCommand(char * line); + void ShowPrompt(); + void DoCommand(char * cmd); + void Execute(char * name,char * args); +/* 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_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 SyntaxError(void); + + /* The shell's variables */ + Bit16u input_handle; + BatchFile * bf; + bool echo; + bool exit; + struct { + char buffer[CMD_OLDSIZE]; + Bitu index; + Bitu size; + } old; + +}; + +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 */ +}; + + diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp new file mode 100644 index 00000000..1d003c35 --- /dev/null +++ b/src/shell/shell_misc.cpp @@ -0,0 +1,248 @@ +/* + * 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. + */ + +#include +#include +#include "shell_inc.h" +#include "cpu.h" + + +void DOS_Shell::ShowPrompt(void) { + Bit8u drive=DOS_GetDefaultDrive()+'A'; + Bit8u dir[DOS_PATHLENGTH]; + DOS_GetCurrentDir(0,dir); + WriteOut("%c:\\%s>",drive,dir); +} + + +static void outc(Bit8u c) { + Bit16u n=1; + DOS_WriteFile(STDOUT,&c,&n); +} + +static void outs(char * str) { + Bit16u n=strlen(str); + DOS_WriteFile(STDOUT,(Bit8u *)str,&n); +} + +void DOS_Shell::InputCommand(char * line) { + char * prev=old.buffer; + char * reader; + Bitu size=CMD_MAXLINE-1; + Bit8u c;Bit16u n=1; + Bitu str_len=0;Bitu str_index=0; + + while (size) { + DOS_ReadFile(input_handle,&c,&n); + if (!n) { + size=0; //Kill the while loop + continue; + } + switch (c) { + case 0x00: /* Extended Keys */ + { + DOS_ReadFile(input_handle,&c,&n); + switch (c) { + case 0x3d: /* F3 */ + if (strlen(old.buffer)>str_len) { + reader=&old.buffer[str_len]; + while (c=*reader++) { + line[str_index]=c; + str_len++; + str_index++; + size--; + DOS_WriteFile(STDOUT,&c,&n); + } + } + break; + default: + break; + + + } + }; + break; + case 0x08: /* BackSpace */ + if (str_index>0) { + Bit32u str_remain=str_len-str_index; + if (str_remain) { + memcpy(&line[str_index-1],&line[str_index],str_remain); + line[str_len]=0; + /* Go back to redraw */ + for (;str_remain>0;str_remain--) { + outc(8); + } + } + str_index--;str_len--; + outc(8); + outc(' '); + outc(8); + + } + break; + case 0x0a: /* New Line not handled */ + /* Don't care */ + break; + case 0x0d: /* Return */ + outc('\n'); + size=0; //Kill the while loop + break; + default: + line[str_index]=c; + str_len++;//This should depend on insert being active + str_index++; + size--; + DOS_WriteFile(STDOUT,&c,&n); + break; + } + } +/* String is inputted now save it in the buffer */ + line[str_len]=0; + if (!str_len) return; + str_len++; + //Not quite perfect last entries can get screwed :) + size_t first_len=strlen(old.buffer)+1; + memmove(&old.buffer[first_len],&old.buffer[0],CMD_OLDSIZE-first_len); + strcpy(old.buffer,line); + + + +} + +void DOS_Shell::Execute(char * name,char * args) { + char * fullname; + + /* check for a drive change */ + if ((strcmp(name + 1, ":") == 0) && isalpha(*name)) + { + if (!DOS_SetDrive(toupper(name[0])-'A')) { + WriteOut(MSG_Get("SHELL_EXECUTE_DRIVE_NOT_FOUND"),toupper(name[0])); + } + return; + } + /* Check for a full name */ + fullname=Which(name); + if (!fullname) { + WriteOut(MSG_Get("SHELL_EXECUTE_ILLEGAL_COMMAND")); + return; + } + if (strcasecmp(strrchr(fullname, '.'), ".bat") == 0) { + /* Run the .bat file */ + bf=new BatchFile(this,fullname,args); + } else { + /* Run the .exe or .com file */ + ParamBlock block; + /* Fill the command line */ + CommandTail cmd; + if (strlen(args)>126) args[126]=0; + cmd.count=strlen(args); + memcpy(cmd.buffer,args,strlen(args)); + cmd.buffer[strlen(args)]=0xd; + + MEM_BlockWrite(real_phys(prog_info->psp_seg,128),&cmd,128); + block.exec.cmdtail=RealMake(prog_info->psp_seg,128); + block.exec.envseg=0; + block.exec.fcb1=0; + block.exec.fcb2=0; + /* Save CS:IP to some point where i can return them from */ + RealPt newcsip; + newcsip=CALLBACK_RealPointer(call_shellstop); + SetSegment_16(cs,RealSeg(newcsip)); + reg_ip=RealOff(newcsip); + + DOS_Execute(fullname,&block,0); + DOSBOX_RunMachine(); + Bit16u blah=0; + } + + +} + + + + +static char * bat_ext=".BAT"; +static char * com_ext=".COM"; +static char * exe_ext=".EXE"; +static char which_ret[DOS_PATHLENGTH]; + +char * DOS_Shell::Which(char * name) { + /* Parse through the Path to find the correct entry */ + +// if (which_result) free(which_result); + /* Check for extension */ + + + + /* Check if name is already ok but just misses an extension */ + char * ext=strrchr(name,'.'); + if (ext) if (strlen(ext)>4) ext=0; + if (ext) { + if (DOS_FileExists(name)) return name; + } else { + /* try to find .exe .com .bat */ + strcpy(which_ret,name); + strcat(which_ret,bat_ext); + if (DOS_FileExists(which_ret)) return which_ret; + strcpy(which_ret,name); + strcat(which_ret,com_ext); + if (DOS_FileExists(which_ret)) return which_ret; + strcpy(which_ret,name); + strcat(which_ret,exe_ext); + if (DOS_FileExists(which_ret)) return which_ret; + } + + /* No Path in filename look through %path% */ + + static char path[DOS_PATHLENGTH]; + char * pathenv=GetEnvStr("PATH"); + if (!pathenv) return 0; + pathenv=strchr(pathenv,'='); + if (!pathenv) return 0; + pathenv++; + char * path_write=path; + while (*pathenv) { + if (*pathenv!=';') { + *path_write++=*pathenv++; + } + if (*pathenv==';' || *(pathenv)==0) { + if (*path_write!='\\') *path_write++='\\'; + *path_write++=0; + strcat(path,name); + strcpy(which_ret,path); + if (ext) { + if (DOS_FileExists(which_ret)) return which_ret; + } else { + strcpy(which_ret,path); + strcat(which_ret,bat_ext); + if (DOS_FileExists(which_ret)) return which_ret; + strcpy(which_ret,path); + strcat(which_ret,com_ext); + if (DOS_FileExists(which_ret)) return which_ret; + strcpy(which_ret,path); + strcat(which_ret,exe_ext); + if (DOS_FileExists(which_ret)) return which_ret; + } + + path_write=path; + if (*pathenv) pathenv++; + } + } + return 0; +} + diff --git a/visualc/Makefile.am b/visualc/Makefile.am new file mode 100644 index 00000000..f484b932 --- /dev/null +++ b/visualc/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST = dosbox.dsw dosbox.dsp \ No newline at end of file diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp new file mode 100644 index 00000000..cd0bae59 --- /dev/null +++ b/visualc/dosbox.dsp @@ -0,0 +1,635 @@ +# Microsoft Developer Studio Project File - Name="dosbox" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=dosbox - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "dosbox.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "dosbox.mak" CFG="dosbox - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "dosbox - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "dosbox - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "dosbox - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /G6 /MD /W3 /GX /O1 /Op /Ob2 /I "../include" /I "../src/platform/visualc" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FAs /FD /QxMi /bQipo /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 sdlmain.lib sdl.lib curses.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "dosbox - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../include" /I "../src/platform/visualc" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c +# SUBTRACT CPP /YX /Yc /Yu +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 sdlmain.lib sdl.lib curses.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "dosbox - Win32 Release" +# Name "dosbox - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Group "cpu" + +# PROP Default_Filter "" +# Begin Group "core_16" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\src\cpu\core_16\helpers.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_16\instructions.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_16\main.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_16\prefix_66.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_16\prefix_66_of.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_16\prefix_of.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_16\start.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_16\stop.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_16\support.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_16\table_ea.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\src\cpu\callback.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\cpu.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\flags.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\modrm.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\modrm.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\slow_16.cpp +# End Source File +# End Group +# Begin Group "debug" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\src\debug\debug.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\debug\debug_disasm.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\debug\debug_gui.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\debug\debug_inc.h +# End Source File +# Begin Source File + +SOURCE=..\src\debug\debug_win32.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\debug\disasm_tables.h +# End Source File +# End Group +# Begin Group "dos" + +# PROP Default_Filter "" +# Begin Group "devices" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\src\dos\dev_con.h +# End Source File +# End Group +# Begin Group "drives" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\src\dos\drive_local.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\dos\drive_virtual.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\dos\drives.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\dos\drives.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\src\dos\dos.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\dos\dos_classes.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\dos\dos_devices.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\dos\dos_execute.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\dos\dos_files.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\dos\dos_ioctl.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\dos\dos_memory.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\dos\dos_misc.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\dos\dos_programs.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\dos\dos_tables.cpp +# End Source File +# End Group +# Begin Group "gui" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\src\gui\render.cpp +# End Source File +# Begin Source File + +SOURCE=..\include\render.h +# End Source File +# Begin Source File + +SOURCE=..\src\gui\sdlmain.cpp +# End Source File +# Begin Source File + +SOURCE=..\include\video.h +# End Source File +# End Group +# Begin Group "hardware" + +# PROP Default_Filter "" +# Begin Group "vga" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\src\hardware\vga.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\vga.h +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\vga_attr.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\vga_crtc.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\vga_dac.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\vga_draw.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\vga_fonts.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\vga_gfx.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\vga_memory.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\vga_misc.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\vga_seq.cpp +# End Source File +# End Group +# Begin Source File + +SOURCE=..\src\hardware\adlib.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\dma.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\gameblaster.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\hardware.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\iohandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\joystick.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\keyboard.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\memory.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\mixer.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\pcspeaker.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\pic.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\sblaster.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\tandy_sound.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\timer.cpp +# End Source File +# End Group +# Begin Group "ints" + +# PROP Default_Filter "" +# Begin Group "int10" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\src\ints\int10.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\ints\int10.h +# End Source File +# Begin Source File + +SOURCE=..\src\ints\int10_char.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\ints\int10_memory.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\ints\int10_misc.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\ints\int10_modes.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\ints\int10_pal.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\ints\int10_put_pixel.cpp +# End Source File +# End Group +# Begin Source File + +SOURCE=..\src\ints\bios.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\ints\bios_disk.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\ints\bios_keyboard.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\ints\ems.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\ints\mouse.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\ints\xms.cpp +# End Source File +# End Group +# Begin Group "misc" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\src\misc\messages.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\misc\plugins.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\misc\programs.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\misc\setup.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\misc\support.cpp +# End Source File +# End Group +# Begin Group "shell" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\src\shell\shell.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\shell\shell_batch.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\shell\shell_cmds.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\shell\shell_inc.h +# End Source File +# Begin Source File + +SOURCE=..\src\shell\shell_misc.cpp +# End Source File +# End Group +# Begin Group "fpu" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\src\fpu\fpu.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\fpu\fpu_load.h +# End Source File +# End Group +# Begin Group "visualc" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\src\platform\visualc\config.h +# End Source File +# Begin Source File + +SOURCE=..\src\platform\visualc\dirent.c +# End Source File +# Begin Source File + +SOURCE=..\src\platform\visualc\dirent.h +# End Source File +# Begin Source File + +SOURCE=..\src\platform\visualc\unistd.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\src\dosbox.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\include\bios.h +# End Source File +# Begin Source File + +SOURCE=..\include\callback.h +# End Source File +# Begin Source File + +SOURCE=..\include\cpu.h +# End Source File +# Begin Source File + +SOURCE=..\include\cross.h +# End Source File +# Begin Source File + +SOURCE=..\include\debug.h +# End Source File +# Begin Source File + +SOURCE=..\include\dma.h +# End Source File +# Begin Source File + +SOURCE=..\include\dos_inc.h +# End Source File +# Begin Source File + +SOURCE=..\include\dos_system.h +# End Source File +# Begin Source File + +SOURCE=..\include\dosbox.h +# End Source File +# Begin Source File + +SOURCE=..\include\hardware.h +# End Source File +# Begin Source File + +SOURCE=..\include\inout.h +# End Source File +# Begin Source File + +SOURCE=..\include\joystick.h +# End Source File +# Begin Source File + +SOURCE=..\include\keyboard.h +# End Source File +# Begin Source File + +SOURCE=..\include\mem.h +# End Source File +# Begin Source File + +SOURCE=..\include\mixer.h +# End Source File +# Begin Source File + +SOURCE=..\include\mouse.h +# End Source File +# Begin Source File + +SOURCE=..\include\pic.h +# End Source File +# Begin Source File + +SOURCE=..\include\programs.h +# End Source File +# Begin Source File + +SOURCE=..\include\regs.h +# End Source File +# Begin Source File + +SOURCE=..\settings.h +# End Source File +# Begin Source File + +SOURCE=..\include\setup.h +# End Source File +# Begin Source File + +SOURCE=..\include\support.h +# End Source File +# Begin Source File + +SOURCE=..\include\timer.h +# End Source File +# End Group +# End Target +# End Project diff --git a/visualc/dosbox.dsw b/visualc/dosbox.dsw new file mode 100644 index 00000000..a17f1ddd --- /dev/null +++ b/visualc/dosbox.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "dosbox"=".\dosbox.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + From 5f69f149622796be751eea44aa4f775f8a0577c1 Mon Sep 17 00:00:00 2001 From: Felix Jakschitsch Date: Sun, 28 Jul 2002 14:51:12 +0000 Subject: [PATCH 0004/4131] some FPU added :) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@81 --- AUTHORS | 4 +- include/dosbox.h | 1 + include/fpu.h | 66 ++++++++++++ include/regs.h | 25 +++++ src/cpu/core_16/main.h | 39 +++++-- src/cpu/slow_16.cpp | 2 + src/fpu/fpu.cpp | 223 +++++++++++++++++++++++++++++++++++++++-- visualc/dosbox.dsp | 26 +++-- 8 files changed, 359 insertions(+), 27 deletions(-) diff --git a/AUTHORS b/AUTHORS index 9873d586..6c649d66 100644 --- a/AUTHORS +++ b/AUTHORS @@ -3,6 +3,4 @@ The DOSBox Team Sjoerd v.d. Berg Peter Veenstra - - - +Felix Jakschitsch \ No newline at end of file diff --git a/include/dosbox.h b/include/dosbox.h index 8b7e26c3..d024ff12 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -25,6 +25,7 @@ typedef unsigned short Bit16u; typedef signed short Bit16s; typedef unsigned long Bit32u; typedef signed long Bit32s; +typedef double Real64; #if defined(_MSC_VER) typedef unsigned __int64 Bit64u; typedef signed __int64 Bit64s; diff --git a/include/fpu.h b/include/fpu.h index 8b137891..9f2d819f 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -1 +1,67 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef __FPU_H +#define __FPU_H + +#include +#include +#include + +enum { FPUREG_VALID=0, FPUREG_ZERO, FPUREG_PNAN, FPUREG_NNAN, FPUREG_EMPTY }; + +enum { + t_FLD=0, t_FLDST, t_FDIV, + t_FDIVP, t_FCHS, t_FCOMP, + + t_FUNKNOWN, + t_FNOTDONE, +}; + +bool FPU_get_C3(); +bool FPU_get_C2(); +bool FPU_get_C1(); +bool FPU_get_C0(); +bool FPU_get_IR(); +bool FPU_get_SF(); +bool FPU_get_PF(); +bool FPU_get_UF(); +bool FPU_get_OF(); +bool FPU_get_ZF(); +bool FPU_get_DF(); +bool FPU_get_IN(); + +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); + + +#endif \ No newline at end of file diff --git a/include/regs.h b/include/regs.h index bec30b61..43b909e4 100644 --- a/include/regs.h +++ b/include/regs.h @@ -35,6 +35,23 @@ struct Flag_Info { bool oldcf; }; +struct FPU_Flag_Info { + struct { + Real64 r; + Bit8u tag; + } var1,var2, result; + struct { + bool bf,c3,c2,c1,c0,ir,sf,pf,uf,of,zf,df,in; + Bit8s tos; + } sw; + struct { + bool ic,ie,sf,pf,uf,of,zf,df,in; + Bit8u rc,pc; + } cw; + Bitu type; + Bitu prev_type; +}; + struct Segment { @@ -51,6 +68,7 @@ enum { cs=0,ds,es,fs,gs,ss}; extern Segment Segs[6]; extern Flag_Info flags; +extern FPU_Flag_Info fpu_flags; //extern Regs regs; void SetSegment_16(Bit32u seg,Bit16u val); @@ -66,6 +84,13 @@ struct CPU_Regs { } ax,bx,cx,dx,si,di,sp,bp,ip; }; +struct FPU_Regs { + struct { + Real64 r; + Bit8u tag; + } st[8]; +}; + extern CPU_Regs cpu_regs; #define reg_al cpu_regs.ax.b.l diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 2e9dd4b6..c6e7a670 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -944,6 +944,33 @@ restart: reg_al=LoadMb(SegBase(ds)+(Bit16u)(reg_bx+reg_al)); } break; +#ifdef USE_FPU +#include "../../fpu/fpu_core_16/support.h" + case 0xd8: /* FPU ESC 0 */ + FPU_ESC_0; + break; + case 0xd9: /* FPU ESC 1 */ + FPU_ESC_1; + break; + case 0xda: /* FPU ESC 2 */ + FPU_ESC_2; + break; + case 0xdb: /* FPU ESC 3 */ + FPU_ESC_3; + break; + case 0xdc: /* FPU ESC 4 */ + FPU_ESC_4; + break; + case 0xdd: /* FPU ESC 5 */ + FPU_ESC_5; + break; + case 0xde: /* FPU ESC 6 */ + FPU_ESC_6; + break; + case 0xdf: /* FPU ESC 7 */ + FPU_ESC_7; + break; +#else case 0xd8: /* FPU ESC 0 */ case 0xd9: /* FPU ESC 1 */ case 0xda: /* FPU ESC 2 */ @@ -953,16 +980,12 @@ restart: case 0xde: /* FPU ESC 6 */ case 0xdf: /* FPU ESC 7 */ { - Bit8u rm=Fetchb(); - if (rm>=0xc0) { - FPU_ESC0_Normal(rm); - } else { - GetEAa;FPU_ESC0_EA(rm,eaa); - } - break; + GetRM; + if( rm < 0xc0 ) + GetEAa; } - break; +#endif case 0xe0: /* LOOPNZ */ if ((--reg_cx) && !get_ZF()) ADDIPFAST(Fetchbs()); else ADDIPFAST(1); diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp index 6d02df7d..e0bf5114 100644 --- a/src/cpu/slow_16.cpp +++ b/src/cpu/slow_16.cpp @@ -73,6 +73,8 @@ typedef HostOff EAPoint; extern Bitu cycle_count; #define CPU_386 +#define USE_FPU +#define FPU_386 //TODO Change name #define FULLFLAGS diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 88a7d6b9..61c68de7 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -20,6 +20,7 @@ #include #include "mem.h" #include "dosbox.h" +#include "fpu.h" typedef PhysPt EAPoint; @@ -35,28 +36,236 @@ typedef PhysPt EAPoint; #define SaveMw(off,val) mem_writew(off,val) #define SaveMd(off,val) mem_writed(off,val) -typedef long double FPUREG; +FPU_Flag_Info fpu_flags; +FPU_Regs fpu_regs; +#define FPU_GetZF fpu_flags.sw.zf = FPU_get_ZF(); -#include "fpu_load.h" +#include "fpu_core_16/instructions.h" +#define FPU_ParseCW(newcw) { \ + fpu_flags.cw.ic = ((bool)((newcw&0x1000)>>12)?true:false); \ + fpu_flags.cw.rc = (Bit8u)((newcw&0x0C00)>>10); \ + fpu_flags.cw.pc = (Bit8u)((newcw&0x0300)>>8); \ + fpu_flags.cw.ie = ((bool)((newcw&0x0080)>>7)?true:false); \ + fpu_flags.cw.sf = ((bool)((newcw&0x0040)>>6)?true:false); \ + fpu_flags.cw.pf = ((bool)((newcw&0x0020)>>5)?true:false); \ + fpu_flags.cw.uf = ((bool)((newcw&0x0010)>>4)?true:false); \ + fpu_flags.cw.of = ((bool)((newcw&0x0008)>>3)?true:false); \ + fpu_flags.cw.zf = ((bool)((newcw&0x0004)>>2)?true:false); \ + fpu_flags.cw.df = ((bool)((newcw&0x0002)>>1)?true:false); \ + fpu_flags.cw.in = ((bool)(newcw&0x0001)?true:false); \ +} +#define FPU_makeCW(newcw) { \ + newcw = (Bit16u)fpu_flags.cw.in; \ + newcw |= (fpu_flags.cw.df<<1); \ + newcw |= (fpu_flags.cw.zf<<2); \ + newcw |= (fpu_flags.cw.of<<3); \ + newcw |= (fpu_flags.cw.uf<<4); \ + newcw |= (fpu_flags.cw.pf<<5); \ + newcw |= (fpu_flags.cw.sf<<6); \ + newcw |= (fpu_flags.cw.ie<<7); \ + newcw |= (fpu_flags.cw.pc<<8); \ + newcw |= (fpu_flags.cw.rc<<10); \ + newcw |= (fpu_flags.cw.ic<<12); \ +} +#define FPU_ParseSW(newsw) { \ + fpu_flags.sw.bf = ((bool)((newsw&0x8000)>>15)?true:false); \ + fpu_flags.sw.c3 = ((bool)((newsw&0x4000)>>14)?true:false); \ + fpu_flags.sw.tos = (Bit8s)((newsw&0x3800)>>11); \ + fpu_flags.sw.c2 = ((bool)((newsw&0x0400)>>10)?true:false); \ + fpu_flags.sw.c1 = ((bool)((newsw&0x0200)>>9)?true:false); \ + fpu_flags.sw.c0 = ((bool)((newsw&0x0100)>>8)?true:false); \ + fpu_flags.sw.ir = ((bool)((newsw&0x0080)>>7)?true:false); \ + fpu_flags.sw.sf = ((bool)((newsw&0x0040)>>6)?true:false); \ + fpu_flags.sw.pf = ((bool)((newsw&0x0020)>>5)?true:false); \ + fpu_flags.sw.uf = ((bool)((newsw&0x0010)>>4)?true:false); \ + fpu_flags.sw.of = ((bool)((newsw&0x0008)>>3)?true:false); \ + fpu_flags.sw.zf = ((bool)((newsw&0x0004)>>2)?true:false); \ + fpu_flags.sw.df = ((bool)((newsw&0x0002)>>1)?true:false); \ + fpu_flags.sw.in = ((bool)(newsw&0x0001)?true:false); \ +} +#define FPU_makeSW(newsw) { \ + newsw = (Bit16u)fpu_flags.sw.in; \ + newsw |= (fpu_flags.sw.df<<1); \ + newsw |= (fpu_flags.sw.zf<<2); \ + newsw |= (fpu_flags.sw.of<<3); \ + newsw |= (fpu_flags.sw.uf<<4); \ + newsw |= (fpu_flags.sw.pf<<5); \ + newsw |= (fpu_flags.sw.sf<<6); \ + newsw |= (fpu_flags.sw.ir<<7); \ + newsw |= (fpu_flags.sw.c0<<8); \ + newsw |= (fpu_flags.sw.c1<<9); \ + newsw |= (fpu_flags.sw.c2<<10); \ + newsw |= (fpu_flags.sw.tos<<11); \ + newsw |= (fpu_flags.sw.c3<<14); \ + newsw |= (fpu_flags.sw.bf<<15); \ +} + +#define FPU_LOADFLAGS { \ + fpu_flags.sw.bf = false; \ + fpu_flags.sw.c3 = FPU_get_C3(); \ + fpu_flags.sw.c2 = FPU_get_C2(); \ + fpu_flags.sw.c1 = FPU_get_C1(); \ + fpu_flags.sw.c0 = FPU_get_C0(); \ + fpu_flags.sw.ir = FPU_get_IR(); \ + fpu_flags.sw.sf = FPU_get_SF(); \ + fpu_flags.sw.pf = FPU_get_PF(); \ + fpu_flags.sw.uf = FPU_get_UF(); \ + fpu_flags.sw.of = FPU_get_OF(); \ + fpu_flags.sw.zf = FPU_get_ZF(); \ + fpu_flags.sw.df = FPU_get_DF(); \ + fpu_flags.sw.in = FPU_get_IN(); \ +} void FPU_ESC0_EA(Bitu rm,PhysPt addr) { - - } void FPU_ESC0_Normal(Bitu rm) { - - } +void FPU_ESC1_EA(Bitu rm,PhysPt addr) { + Bit16u cw; + Bitu opcode = (rm&0x38)>>3; + switch(opcode) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 6: + break; + case 5: + FPU_ParseCW(LoadMw(addr)); /* FLDCW */ + break; + case 7: /* FSTCW */ + FPU_makeCW(cw); + SaveMw(addr,cw); + break; + } +} + +void FPU_ESC1_Normal(Bitu rm) { + Bitu opcode = (rm&0xF0); + + switch(opcode) { + case 0xC0: +// if(rm&8) +// else + FLDST(rm-0xC0); /* FLDST */ + break; + case 0xD0: + break; + } + switch(rm) { + case 0xE0: /* FCHS */ + FCHS; + break; + case 0xE8: /* FLD1 */ + FLD(1); + break; + case 0xEE: /* FLDZ */ + FLD(0); + break; + } +} + + +void FPU_ESC2_EA(Bitu rm,PhysPt addr) { +} + +void FPU_ESC2_Normal(Bitu rm) { +} + + +void FPU_ESC3_EA(Bitu rm,PhysPt addr) { +} + +void FPU_ESC3_Normal(Bitu rm) { + switch( rm ) { + case 0xE3: /* FINIT */ + FPU_ParseCW(0x037F); + for(int i=0;i<8;i++) { + fpu_regs.st[i].r = 0; + fpu_regs.st[i].tag = FPUREG_EMPTY; + } + break; + } +} + + +void FPU_ESC4_EA(Bitu rm,PhysPt addr) { +} + +void FPU_ESC4_Normal(Bitu rm) { +} + + +void FPU_ESC5_EA(Bitu rm,PhysPt addr) { + Bit16u sw; + Bitu opcode = (rm&0x38)>>3; + + switch(opcode) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: /* FSTSW */ + FPU_LOADFLAGS; + FPU_makeSW(sw); + SaveMw(addr,sw); + break; + } +} + +void FPU_ESC5_Normal(Bitu rm) { +} + + +void FPU_ESC6_EA(Bitu rm,PhysPt addr) { +} + +void FPU_ESC6_Normal(Bitu rm) { + Bitu opcode = (rm&0xF0); + + if(rm==0xD9) { /* FCOMPP */ + FCOMPP; + return; + } + switch(opcode) { + case 0xC0: +// if(rm&8) + break; + case 0xD0: +// if(rm&8) + break; + case 0xE0: +// if(rm&8) + break; + case 0xF0: + if(rm&8) + FDIVP(rm-0xF8,0); + break; + } +} + + +void FPU_ESC7_EA(Bitu rm,PhysPt addr) { +} + +void FPU_ESC7_Normal(Bitu rm) { +} void FPU_Init(void) { + fpu_flags.type = t_FUNKNOWN; +} + -} \ No newline at end of file diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index cd0bae59..1e21b1ca 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -223,10 +223,6 @@ SOURCE=..\src\dos\dos.cpp # End Source File # Begin Source File -SOURCE=..\src\dos\dos_classes.cpp -# End Source File -# Begin Source File - SOURCE=..\src\dos\dos_devices.cpp # End Source File # Begin Source File @@ -467,10 +463,6 @@ SOURCE=..\src\misc\programs.cpp # End Source File # Begin Source File -SOURCE=..\src\misc\setup.cpp -# End Source File -# Begin Source File - SOURCE=..\src\misc\support.cpp # End Source File # End Group @@ -501,13 +493,25 @@ SOURCE=..\src\shell\shell_misc.cpp # Begin Group "fpu" # PROP Default_Filter "" +# Begin Group "fpu_core_16" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\src\fpu\fpu_core_16\instructions.h +# End Source File +# Begin Source File + +SOURCE=..\src\fpu\fpu_core_16\support.h +# End Source File +# End Group # Begin Source File SOURCE=..\src\fpu\fpu.cpp # End Source File # Begin Source File -SOURCE=..\src\fpu\fpu_load.h +SOURCE=..\src\fpu\fpu_flags.cpp # End Source File # End Group # Begin Group "visualc" @@ -576,6 +580,10 @@ SOURCE=..\include\dosbox.h # End Source File # Begin Source File +SOURCE=..\include\fpu.h +# End Source File +# Begin Source File + SOURCE=..\include\hardware.h # End Source File # Begin Source File From dda8d374558fa76235a9f8af6cddc2a8e8ac6653 Mon Sep 17 00:00:00 2001 From: Felix Jakschitsch Date: Sun, 28 Jul 2002 15:43:11 +0000 Subject: [PATCH 0005/4131] some FPU emulation added :) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@82 --- src/fpu/fpu_core_16/instructions.h | 158 +++++++++++++++++++ src/fpu/fpu_core_16/support.h | 89 +++++++++++ src/fpu/fpu_flags.cpp | 235 +++++++++++++++++++++++++++++ src/fpu/fpu_load.h | 21 --- 4 files changed, 482 insertions(+), 21 deletions(-) create mode 100644 src/fpu/fpu_core_16/instructions.h create mode 100644 src/fpu/fpu_core_16/support.h create mode 100644 src/fpu/fpu_flags.cpp delete mode 100644 src/fpu/fpu_load.h diff --git a/src/fpu/fpu_core_16/instructions.h b/src/fpu/fpu_core_16/instructions.h new file mode 100644 index 00000000..271f03f8 --- /dev/null +++ b/src/fpu/fpu_core_16/instructions.h @@ -0,0 +1,158 @@ +/* + * 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 FLD(op1) { \ + FPU_GetZF; \ + fpu_flags.type=t_FLD; \ + if(--fpu_flags.sw.tos < 0) \ + fpu_flags.sw.tos = 7; \ + if( fpu_regs.st[fpu_flags.sw.tos].tag != FPUREG_EMPTY ) { \ + fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_NNAN; \ + break; \ + } \ + if(op1) \ + fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_VALID; \ + else \ + fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_ZERO; \ + fpu_flags.result.r = fpu_regs.st[fpu_flags.sw.tos].r = op1; \ +} + +#define FLDST(op1) { \ + FPU_GetZF; \ + fpu_flags.type=t_FLDST; \ + Bit8u reg = fpu_flags.sw.tos+op1; \ + if(reg>7) reg-=8; \ + if(--fpu_flags.sw.tos < 0) \ + fpu_flags.sw.tos = 7; \ + if(fpu_regs.st[fpu_flags.sw.tos].tag!=FPUREG_EMPTY) { \ + fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_NNAN; \ + break; \ + } \ + fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = fpu_regs.st[reg].tag; \ + fpu_flags.result.r = fpu_regs.st[fpu_flags.sw.tos].r = fpu_regs.st[reg].r; \ +} + +#define FPOP { \ + fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_EMPTY; \ + if(++fpu_flags.sw.tos > 7 ) \ + fpu_flags.sw.tos = 0; \ +} +/* FPOP: fpu_flags.result.r = fpu_regs.st[fpu_flags.sw.tos].r = 0; is not really neccessary */ + +#define FDIVP(op1,op2) { \ + Bit8u reg1 = fpu_flags.sw.tos+op1; \ + Bit8u reg2 = fpu_flags.sw.tos+op2; \ + fpu_flags.type=t_FDIVP; \ + if(reg1>7) reg1-=8; \ + if(reg2>7) reg2-=8; \ + if((fpu_regs.st[reg1].tag!=FPUREG_VALID && fpu_regs.st[reg1].tag!=FPUREG_ZERO)||(fpu_regs.st[reg2].tag!=FPUREG_VALID && fpu_regs.st[reg2].tag!=FPUREG_ZERO)) { \ + fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ + FPOP; \ + break; \ + } \ + if(fpu_regs.st[reg2].tag == FPUREG_ZERO) { \ + if(fpu_regs.st[reg1].r > 0) \ + fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_PNAN; \ + else \ + fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ + FPOP; \ + break; \ + } \ + if(fpu_regs.st[reg1].tag == FPUREG_ZERO) { \ + fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_ZERO; \ + FPOP; \ + break; \ + } \ + fpu_flags.result.tag = FPUREG_VALID; \ + fpu_flags.result.r = fpu_regs.st[reg1].r = fpu_regs.st[reg1].r / fpu_regs.st[reg2].r; \ + FPOP; \ +} + +#define FDIV(op1,op2) { \ + Bit8u reg1 = fpu_flags.sw.tos+op1; \ + Bit8u reg2 = fpu_flags.sw.tos+op2; \ + fpu_flags.type=t_FDIV; \ + if(reg1>7) reg1-=7; \ + if(reg2>7) reg2-=7; \ + if((fpu_regs.st[reg1].tag!=FPUREG_VALID && fpu_regs.st[reg1].tag!=FPUREG_ZERO)||(fpu_regs.st[reg2].tag!=FPUREG_VALID && fpu_regs.st[reg2].tag!=FPUREG_ZERO)) { \ + fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ + break; \ + } \ + if(fpu_regs.st[reg2].tag == FPUREG_ZERO) { \ + if(fpu_regs.st[reg1].r > 0) \ + fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_PNAN; \ + else \ + fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ + break; \ + } \ + if(fpu_regs.st[reg1].tag == FPUREG_ZERO) { \ + fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_ZERO; \ + break; \ + } \ + fpu_flags.result.tag = FPUREG_VALID; \ + fpu_flags.result.r = fpu_regs.st[reg1].r = fpu_regs.st[reg1].r / fpu_regs.st[reg2].r; \ +} + +#define FCHS { \ + FPU_GetZF; \ + fpu_flags.type=t_FCHS; \ + if(fpu_regs.st[fpu_flags.sw.tos].tag == FPUREG_PNAN) { \ + fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_NNAN; \ + } else if(fpu_regs.st[fpu_flags.sw.tos].tag == FPUREG_NNAN) { \ + fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_PNAN; \ + } else \ + fpu_regs.st[fpu_flags.sw.tos].r = -fpu_regs.st[fpu_flags.sw.tos].r; \ +} + +#define FCOMPP { \ + Bit8u reg = fpu_flags.sw.tos+1; \ + FPU_GetZF; \ + fpu_flags.type=t_FCOMP; \ + if(reg>7) \ + reg=0; \ + if((fpu_regs.st[reg].tag==FPUREG_VALID||fpu_regs.st[reg].tag==FPUREG_ZERO)&&(fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_VALID||fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_ZERO)) { \ + fpu_flags.result.r = fpu_regs.st[reg].r - fpu_regs.st[fpu_flags.sw.tos].r; \ + if(fpu_flags.result.r==0) \ + fpu_flags.result.tag = FPUREG_ZERO; \ + else \ + fpu_flags.result.tag = FPUREG_VALID; \ + FPOP; \ + FPOP; \ + return; \ + } else if(((fpu_regs.st[reg].tag==FPUREG_EMPTY)||(fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_EMPTY))||((fpu_regs.st[reg].tag==FPUREG_VALID||fpu_regs.st[reg].tag==FPUREG_ZERO)||(fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_VALID||fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_ZERO))) { \ + fpu_flags.result.tag = FPUREG_EMPTY; \ + FPOP; \ + FPOP; \ + return; \ + } \ + Bit8s res = (fpu_regs.st[reg].tag-fpu_regs.st[fpu_flags.sw.tos].tag); \ + if(res==0||fpu_flags.cw.ic==0) { \ + fpu_flags.result.tag = FPUREG_ZERO; \ + FPOP; \ + FPOP; \ + return; \ + } else if(res>0) { \ + fpu_flags.result.tag = FPUREG_NNAN; \ + FPOP; \ + FPOP; \ + return; \ + } \ + fpu_flags.result.tag = FPUREG_PNAN; \ + FPOP; \ + FPOP; \ +} \ No newline at end of file diff --git a/src/fpu/fpu_core_16/support.h b/src/fpu/fpu_core_16/support.h new file mode 100644 index 00000000..dd6434ae --- /dev/null +++ b/src/fpu/fpu_core_16/support.h @@ -0,0 +1,89 @@ +/* + * 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 FPU_ESC_0 { \ + Bit8u rm=Fetchb(); \ + if (rm>=0xc0) { \ + FPU_ESC0_Normal(rm); \ + } else { \ + GetEAa;FPU_ESC0_EA(rm,eaa); \ + } \ + } + +#define FPU_ESC_1 { \ + Bit8u rm=Fetchb(); \ + if (rm>=0xc0) { \ + FPU_ESC1_Normal(rm); \ + } else { \ + GetEAa;FPU_ESC1_EA(rm,eaa); \ + } \ + } + +#define FPU_ESC_2 { \ + Bit8u rm=Fetchb(); \ + if (rm>=0xc0) { \ + FPU_ESC2_Normal(rm); \ + } else { \ + GetEAa;FPU_ESC2_EA(rm,eaa); \ + } \ + } + +#define FPU_ESC_3 { \ + Bit8u rm=Fetchb(); \ + if (rm>=0xc0) { \ + FPU_ESC3_Normal(rm); \ + } else { \ + GetEAa;FPU_ESC3_EA(rm,eaa); \ + } \ + } + +#define FPU_ESC_4 { \ + Bit8u rm=Fetchb(); \ + if (rm>=0xc0) { \ + FPU_ESC4_Normal(rm); \ + } else { \ + GetEAa;FPU_ESC4_EA(rm,eaa); \ + } \ + } + +#define FPU_ESC_5 { \ + Bit8u rm=Fetchb(); \ + if (rm>=0xc0) { \ + FPU_ESC5_Normal(rm); \ + } else { \ + GetEAa;FPU_ESC5_EA(rm,eaa); \ + } \ + } + +#define FPU_ESC_6 { \ + Bit8u rm=Fetchb(); \ + if (rm>=0xc0) { \ + FPU_ESC6_Normal(rm); \ + } else { \ + GetEAa;FPU_ESC6_EA(rm,eaa); \ + } \ + } + +#define FPU_ESC_7 { \ + Bit8u rm=Fetchb(); \ + if (rm>=0xc0) { \ + FPU_ESC7_Normal(rm); \ + } else { \ + GetEAa;FPU_ESC7_EA(rm,eaa); \ + } \ + } \ No newline at end of file diff --git a/src/fpu/fpu_flags.cpp b/src/fpu/fpu_flags.cpp new file mode 100644 index 00000000..be463c0c --- /dev/null +++ b/src/fpu/fpu_flags.cpp @@ -0,0 +1,235 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "fpu.h" +#include "pic.h" + +//extern FPU_Flag_Info fpu_flags; + +bool FPU_get_C3() { + switch(fpu_flags.type) { + case t_FLD: + case t_FLDST: + case t_FDIV: + case t_FDIVP: + case t_FCHS: + case t_FUNKNOWN: + case t_FNOTDONE: + return fpu_flags.sw.c3; + case t_FCOMP: + return (fpu_flags.result.tag==FPUREG_EMPTY||fpu_flags.result.tag==FPUREG_ZERO); + default: + E_Exit("FPU_get_C3 Unknown %d",fpu_flags.type); + } + return 0; +} + +bool FPU_get_C2() { + switch(fpu_flags.type) { + case t_FLD: + case t_FLDST: + case t_FDIV: + case t_FDIVP: + case t_FCHS: + case t_FUNKNOWN: + case t_FNOTDONE: + return fpu_flags.sw.c2; + case t_FCOMP: + return (fpu_flags.result.tag==FPUREG_EMPTY); + default: + E_Exit("FPU_get_C2 Unknown %d",fpu_flags.type); + } + return 0; +} + +bool FPU_get_C1() { + switch(fpu_flags.type) { + case t_FLD: + case t_FLDST: + case t_FDIV: + case t_FDIVP: + case t_FCHS: + case t_FUNKNOWN: + case t_FNOTDONE: + return fpu_flags.sw.c1; + case t_FCOMP: + return false; /* FIXME */ + default: + E_Exit("FPU_get_C1 Unknown %d",fpu_flags.type); + } + return 0; +} + +bool FPU_get_C0() { + switch(fpu_flags.type) { + case t_FLD: + case t_FLDST: + case t_FDIV: + case t_FDIVP: + case t_FCHS: + case t_FUNKNOWN: + case t_FNOTDONE: + return fpu_flags.sw.c0; + case t_FCOMP: + return (fpu_flags.result.tag!=FPUREG_ZERO&&fpu_flags.result.tag!=FPUREG_PNAN); + default: + E_Exit("FPU_get_C0 Unknown %d",fpu_flags.type); + } + return 0; +} + +bool FPU_get_IR() { + switch(fpu_flags.type) { + case t_FLD: + case t_FLDST: + case t_FDIV: + case t_FDIVP: + case t_FCHS: + case t_FUNKNOWN: + case t_FNOTDONE: + case t_FCOMP: + return fpu_flags.sw.ir; + default: + E_Exit("FPU_get_IR Unknown %d",fpu_flags.type); + } + return 0; +} + +bool FPU_get_SF() { + switch(fpu_flags.type) { + case t_FLD: + case t_FLDST: + case t_FDIV: + case t_FDIVP: + case t_FCHS: + case t_FUNKNOWN: + case t_FNOTDONE: + return fpu_flags.sw.sf; + case t_FCOMP: + return false; /* FIXME */ + default: + E_Exit("FPU_get_SF Unknown %d",fpu_flags.type); + } + return 0; +} + +bool FPU_get_PF() { + switch(fpu_flags.type) { + case t_FLD: + case t_FLDST: + case t_FDIV: + case t_FDIVP: + case t_FCHS: + case t_FUNKNOWN: + case t_FNOTDONE: + case t_FCOMP: + return fpu_flags.sw.pf; + default: + E_Exit("FPU_get_PF Unknown %d",fpu_flags.type); + } + return 0; +} + +bool FPU_get_UF() { + switch(fpu_flags.type) { + case t_FLD: + case t_FLDST: + case t_FDIV: + case t_FDIVP: + case t_FCHS: + case t_FUNKNOWN: + case t_FNOTDONE: + case t_FCOMP: + return fpu_flags.sw.uf; + default: + E_Exit("FPU_get_UF Unknown %d",fpu_flags.type); + } + return 0; +} + +bool FPU_get_OF() { + switch(fpu_flags.type) { + case t_FLD: + case t_FLDST: + case t_FDIV: + case t_FDIVP: + case t_FCHS: + case t_FUNKNOWN: + case t_FNOTDONE: + case t_FCOMP: + return fpu_flags.sw.of; + default: + E_Exit("FPU_get_OF Unknown %d",fpu_flags.type); + } + return 0; +} + +bool FPU_get_ZF() { + switch(fpu_flags.type) { + case t_FLD: + case t_FLDST: + case t_FCHS: + case t_FUNKNOWN: + case t_FNOTDONE: + case t_FCOMP: + return fpu_flags.sw.zf; + case t_FDIV: + case t_FDIVP: + return (fpu_flags.result.tag==FPUREG_PNAN||fpu_flags.result.tag==FPUREG_NNAN); + default: + E_Exit("FPU_get_ZF Unknown %d",fpu_flags.type); + } + return 0; +} + +bool FPU_get_DF() { + switch(fpu_flags.type) { + case t_FLD: + case t_FLDST: + case t_FDIV: + case t_FDIVP: + case t_FCHS: + case t_FUNKNOWN: + case t_FNOTDONE: + return fpu_flags.sw.df; + case t_FCOMP: + return false; /* FIXME */ + default: + E_Exit("FPU_get_DF Unknown %d",fpu_flags.type); + } + return 0; +} + +bool FPU_get_IN(){ + switch(fpu_flags.type) { + case t_FLD: + case t_FLDST: + case t_FDIV: + case t_FDIVP: + case t_FCHS: + case t_FUNKNOWN: + case t_FNOTDONE: + return fpu_flags.sw.in; + case t_FCOMP: + return (fpu_flags.result.tag==FPUREG_EMPTY); /* FIXME */ + default: + E_Exit("FPU_get_IN Unknown %d",fpu_flags.type); + } + return 0; +} diff --git a/src/fpu/fpu_load.h b/src/fpu/fpu_load.h deleted file mode 100644 index b7f6ee0f..00000000 --- a/src/fpu/fpu_load.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2002 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -INLINE FPUREG Load_Short(EAPoint addr) { - return (Bit16s)mem_readw(addr); -} \ No newline at end of file From e9ad5eb51e65cb270f23439824396be038a560df Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 28 Jul 2002 16:21:31 +0000 Subject: [PATCH 0006/4131] New C_FPU switch for fpu module Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@83 --- settings.h.cvs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/settings.h.cvs b/settings.h.cvs index f7fefd0f..cf2aa2fd 100644 --- a/settings.h.cvs +++ b/settings.h.cvs @@ -7,6 +7,9 @@ /* Use multi threading to speed up things on multi cpu's, also gives a nice frame-skipping effect :) */ #define C_THREADED +/* Enable the FPU module, still only for beta testing */ +//#define C_FPU + /* Enable debugging for several modules, requires C_LOGGING */ #define DEBUG_SBLASTER /* SoundBlaster Debugging*/ #define DEBUG_DMA /* DMA Debugging */ From 184f57d77e91332bee585b861dcfec0f906e46a3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 28 Jul 2002 16:26:29 +0000 Subject: [PATCH 0007/4131] FPU Support and some clean-up. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@84 --- src/cpu/core_16/main.h | 34 ++++++++++++---------------------- src/cpu/core_16/support.h | 14 -------------- src/cpu/slow_16.cpp | 33 +++++---------------------------- src/dosbox.cpp | 2 ++ 4 files changed, 19 insertions(+), 64 deletions(-) diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index c6e7a670..30944784 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -944,33 +944,24 @@ restart: reg_al=LoadMb(SegBase(ds)+(Bit16u)(reg_bx+reg_al)); } break; -#ifdef USE_FPU -#include "../../fpu/fpu_core_16/support.h" +#ifdef CPU_FPU case 0xd8: /* FPU ESC 0 */ - FPU_ESC_0; - break; + FPU_ESC(0);break; case 0xd9: /* FPU ESC 1 */ - FPU_ESC_1; - break; + FPU_ESC(1);break; case 0xda: /* FPU ESC 2 */ - FPU_ESC_2; - break; + FPU_ESC(2);break; case 0xdb: /* FPU ESC 3 */ - FPU_ESC_3; - break; + FPU_ESC(3);break; case 0xdc: /* FPU ESC 4 */ - FPU_ESC_4; - break; + FPU_ESC(4);break; case 0xdd: /* FPU ESC 5 */ - FPU_ESC_5; - break; + FPU_ESC(5);break; case 0xde: /* FPU ESC 6 */ - FPU_ESC_6; - break; + FPU_ESC(6);break; case 0xdf: /* FPU ESC 7 */ - FPU_ESC_7; - break; -#else + FPU_ESC(7);break; +#else case 0xd8: /* FPU ESC 0 */ case 0xd9: /* FPU ESC 1 */ case 0xda: /* FPU ESC 2 */ @@ -980,9 +971,8 @@ restart: case 0xde: /* FPU ESC 6 */ case 0xdf: /* FPU ESC 7 */ { - GetRM; - if( rm < 0xc0 ) - GetEAa; + Bit8u rm; + if (rm<0xc0) GetEAa; } break; #endif diff --git a/src/cpu/core_16/support.h b/src/cpu/core_16/support.h index 8ee24827..e6008cd9 100644 --- a/src/cpu/core_16/support.h +++ b/src/cpu/core_16/support.h @@ -44,9 +44,6 @@ 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; @@ -75,7 +72,6 @@ static INLINE Bit32s Fetchds() { return Fetchd(); } - static INLINE void Push_16(Bit16u blah) { reg_sp-=2; SaveMw(SegBase(ss)+reg_sp,blah); @@ -98,12 +94,6 @@ static INLINE Bit32u Pop_32() { return temp; }; - - - - - - #define stringDI \ EAPoint to; \ to=SegBase(es)+reg_di @@ -185,7 +175,3 @@ static INLINE void Rep_66(Bit16s direct,EAPoint from,EAPoint to) { } -// if (flags.tf) { \ -// cpudecoder=CPU_Real_16_Slow_Decode_Special; \ -// return CBRET_NONE; \ -// } \ diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp index e0bf5114..aaed2d80 100644 --- a/src/cpu/slow_16.cpp +++ b/src/cpu/slow_16.cpp @@ -24,7 +24,6 @@ #include "pic.h" #include "fpu.h" - typedef PhysPt EAPoint; #define SegBase(seg) Segs[seg].phys @@ -41,27 +40,6 @@ typedef PhysPt EAPoint; #define SaveMw(off,val) mem_writew(off,val) #define SaveMd(off,val) mem_writed(off,val) - -/* -typedef HostOff EAPoint; - -#define SegBase(seg) Segs[seg].host - -#define LoadMb(off) readb(off) -#define LoadMw(off) readw(off) -#define LoadMd(off) readd(off) - -#define LoadMbs(off) (Bit8s)(LoadMb(off)) -#define LoadMws(off) (Bit16s)(LoadMw(off)) -#define LoadMds(off) (Bit32s)(LoadMd(off)) - -#define SaveMb(off,val) writeb(off,val) -#define SaveMw(off,val) writew(off,val) -#define SaveMd(off,val) writed(off,val) - -*/ - - #define LoadRb(reg) reg #define LoadRw(reg) reg #define LoadRd(reg) reg @@ -72,12 +50,11 @@ typedef HostOff EAPoint; extern Bitu cycle_count; -#define CPU_386 -#define USE_FPU -#define FPU_386 -//TODO Change name -#define FULLFLAGS - +/* Enable parts of the cpu emulation */ +#define CPU_386 //Enable 386 instructions +#ifdef C_FPU +#define CPU_FPU //Enable FPU escape instructions +#endif #include "core_16/support.h" static Bitu CPU_Real_16_Slow_Decode_Special(Bitu count); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index ce7dba6f..735491be 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -207,7 +207,9 @@ static void InitSystems(void) { HARDWARE_Init(); TIMER_Init(); CPU_Init(); +#ifdef C_FPU FPU_Init(); +#endif MIXER_Init(); #ifdef C_DEBUG DEBUG_Init(); From 79182b385db0845dba808b2aabe670dfd86226ea Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 28 Jul 2002 16:27:17 +0000 Subject: [PATCH 0008/4131] Changed things a bit. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@85 --- include/fpu.h | 37 +++++++++---------------------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/include/fpu.h b/include/fpu.h index 9f2d819f..b0244bf6 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -19,33 +19,6 @@ #ifndef __FPU_H #define __FPU_H -#include -#include -#include - -enum { FPUREG_VALID=0, FPUREG_ZERO, FPUREG_PNAN, FPUREG_NNAN, FPUREG_EMPTY }; - -enum { - t_FLD=0, t_FLDST, t_FDIV, - t_FDIVP, t_FCHS, t_FCOMP, - - t_FUNKNOWN, - t_FNOTDONE, -}; - -bool FPU_get_C3(); -bool FPU_get_C2(); -bool FPU_get_C1(); -bool FPU_get_C0(); -bool FPU_get_IR(); -bool FPU_get_SF(); -bool FPU_get_PF(); -bool FPU_get_UF(); -bool FPU_get_OF(); -bool FPU_get_ZF(); -bool FPU_get_DF(); -bool FPU_get_IN(); - void FPU_ESC0_Normal(Bitu rm); void FPU_ESC0_EA(Bitu func,PhysPt ea); void FPU_ESC1_Normal(Bitu rm); @@ -63,5 +36,13 @@ void FPU_ESC6_EA(Bitu func,PhysPt ea); void FPU_ESC7_Normal(Bitu rm); void FPU_ESC7_EA(Bitu func,PhysPt ea); +#define FPU_ESC(a) { \ + Bit8u rm=Fetchb(); \ + if (rm>=0xc0) { \ + FPU_ESC0_Normal(rm); \ + } else { \ + GetEAa;FPU_ESC0_EA(rm,eaa); \ + } \ +} -#endif \ No newline at end of file +#endif From 153d381f5d4c1594a1e12e66d3c828d5784486fd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 28 Jul 2002 16:31:54 +0000 Subject: [PATCH 0009/4131] FPU Support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@86 --- src/fpu/fpu.cpp | 16 ++-- src/fpu/fpu_instructions.h | 162 +++++++++++++++++++++++++++++++++++++ src/fpu/fpu_types.h | 32 ++++++++ 3 files changed, 205 insertions(+), 5 deletions(-) create mode 100644 src/fpu/fpu_instructions.h create mode 100644 src/fpu/fpu_types.h diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 61c68de7..ced68606 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -16,10 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "dosbox.h" +#ifdef C_FPU + #include #include #include "mem.h" -#include "dosbox.h" #include "fpu.h" typedef PhysPt EAPoint; @@ -36,13 +38,16 @@ typedef PhysPt EAPoint; #define SaveMw(off,val) mem_writew(off,val) #define SaveMd(off,val) mem_writed(off,val) +typedef double Real; + +#include "fpu_types.h" +#include "fpu_instructions.h" + FPU_Flag_Info fpu_flags; -FPU_Regs fpu_regs; +FPU_Reg fpu_regs[8]; #define FPU_GetZF fpu_flags.sw.zf = FPU_get_ZF(); -#include "fpu_core_16/instructions.h" - #define FPU_ParseCW(newcw) { \ fpu_flags.cw.ic = ((bool)((newcw&0x1000)>>12)?true:false); \ fpu_flags.cw.rc = (Bit8u)((newcw&0x0C00)>>10); \ @@ -264,8 +269,9 @@ void FPU_ESC7_EA(Bitu rm,PhysPt addr) { void FPU_ESC7_Normal(Bitu rm) { } + void FPU_Init(void) { fpu_flags.type = t_FUNKNOWN; } - +#endif diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h new file mode 100644 index 00000000..49de9d00 --- /dev/null +++ b/src/fpu/fpu_instructions.h @@ -0,0 +1,162 @@ +/* + * 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 FLD(op1) { \ + FPU_GetZF; \ + fpu_flags.type=t_FLD; \ + if(--fpu_flags.sw.tos < 0) \ + fpu_flags.sw.tos = 7; \ + if( fpu_regs.st[fpu_flags.sw.tos].tag != FPUREG_EMPTY ) { \ + fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_NNAN; \ + break; \ + } \ + if(op1) \ + fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_VALID; \ + else \ + fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_ZERO; \ + fpu_flags.result.r = fpu_regs.st[fpu_flags.sw.tos].r = op1; \ +} + +#define FLDST(op1) { \ + FPU_GetZF; \ + fpu_flags.type=t_FLDST; \ + Bit8u reg = fpu_flags.sw.tos+op1; \ + if(reg>7) reg-=8; \ + if(--fpu_flags.sw.tos < 0) \ + fpu_flags.sw.tos = 7; \ + if(fpu_regs.st[fpu_flags.sw.tos].tag!=FPUREG_EMPTY) { \ + fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_NNAN; \ + break; \ + } \ + fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = fpu_regs.st[reg].tag; \ + fpu_flags.result.r = fpu_regs.st[fpu_flags.sw.tos].r = fpu_regs.st[reg].r; \ +} + +#define FPOP { \ + fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_EMPTY; \ + if(++fpu_flags.sw.tos > 7 ) \ + fpu_flags.sw.tos = 0; \ +} +/* FPOP: fpu_flags.result.r = fpu_regs.st[fpu_flags.sw.tos].r = 0; is not really neccessary */ + +#define FDIVP(op1,op2) { \ + Bit8u reg1 = fpu_flags.sw.tos+op1; \ + Bit8u reg2 = fpu_flags.sw.tos+op2; \ + fpu_flags.type=t_FDIVP; \ + if(reg1>7) reg1-=8; \ + if(reg2>7) reg2-=8; \ + if((fpu_regs.st[reg1].tag!=FPUREG_VALID && fpu_regs.st[reg1].tag!=FPUREG_ZERO)||(fpu_regs.st[reg2].tag!=FPUREG_VALID && fpu_regs.st[reg2].tag!=FPUREG_ZERO)) { \ + fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ + FPOP; \ + break; \ + } \ + if(fpu_regs.st[reg2].tag == FPUREG_ZERO) { \ + if(fpu_regs.st[reg1].r > 0) \ + fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_PNAN; \ + else \ + fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ + FPOP; \ + break; \ + } \ + if(fpu_regs.st[reg1].tag == FPUREG_ZERO) { \ + fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_ZERO; \ + FPOP; \ + break; \ + } \ + fpu_flags.result.tag = FPUREG_VALID; \ + fpu_flags.result.r = fpu_regs.st[reg1].r = fpu_regs.st[reg1].r / fpu_regs.st[reg2].r; \ + FPOP; \ +} + +#define FDIV(op1,op2) { \ + Bit8u reg1 = fpu_flags.sw.tos+op1; \ + Bit8u reg2 = fpu_flags.sw.tos+op2; \ + fpu_flags.type=t_FDIV; \ + if(reg1>7) reg1-=7; \ + if(reg2>7) reg2-=7; \ + if((fpu_regs.st[reg1].tag!=FPUREG_VALID && fpu_regs.st[reg1].tag!=FPUREG_ZERO)||(fpu_regs.st[reg2].tag!=FPUREG_VALID && fpu_regs.st[reg2].tag!=FPUREG_ZERO)) { \ + fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ + break; \ + } \ + if(fpu_regs.st[reg2].tag == FPUREG_ZERO) { \ + if(fpu_regs.st[reg1].r > 0) \ + fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_PNAN; \ + else \ + fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ + break; \ + } \ + if(fpu_regs.st[reg1].tag == FPUREG_ZERO) { \ + fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_ZERO; \ + break; \ + } \ + fpu_flags.result.tag = FPUREG_VALID; \ + fpu_flags.result.r = fpu_regs.st[reg1].r = fpu_regs.st[reg1].r / fpu_regs.st[reg2].r; \ +} + +#define FCHS { \ + FPU_GetZF; \ + fpu_flags.type=t_FCHS; \ + if(fpu_regs.st[fpu_flags.sw.tos].tag == FPUREG_PNAN) { \ + fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_NNAN; \ + } else if(fpu_regs.st[fpu_flags.sw.tos].tag == FPUREG_NNAN) { \ + fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_PNAN; \ + } else \ + fpu_regs.st[fpu_flags.sw.tos].r = -fpu_regs.st[fpu_flags.sw.tos].r; \ +} + +#define FCOMPP { \ + Bit8u reg = fpu_flags.sw.tos+1; \ + FPU_GetZF; \ + fpu_flags.type=t_FCOMP; \ + if(reg>7) \ + reg=0; \ + if((fpu_regs.st[reg].tag==FPUREG_VALID||fpu_regs.st[reg].tag==FPUREG_ZERO)&&(fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_VALID||fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_ZERO)) { \ + fpu_flags.result.r = fpu_regs.st[reg].r - fpu_regs.st[fpu_flags.sw.tos].r; \ + if(fpu_flags.result.r==0) \ + fpu_flags.result.tag = FPUREG_ZERO; \ + else \ + fpu_flags.result.tag = FPUREG_VALID; \ + FPOP; \ + FPOP; \ + return; \ + } else if(((fpu_regs.st[reg].tag==FPUREG_EMPTY)||(fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_EMPTY))||((fpu_regs.st[reg].tag==FPUREG_VALID||fpu_regs.st[reg].tag==FPUREG_ZERO)||(fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_VALID||fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_ZERO))) { \ + fpu_flags.result.tag = FPUREG_EMPTY; \ + FPOP; \ + FPOP; \ + return; \ + } \ + Bit8s res = (fpu_regs.st[reg].tag-fpu_regs.st[fpu_flags.sw.tos].tag); \ + if(res==0||fpu_flags.cw.ic==0) { \ + fpu_flags.result.tag = FPUREG_ZERO; \ + FPOP; \ + FPOP; \ + return; \ + } else if(res>0) { \ + fpu_flags.result.tag = FPUREG_NNAN; \ + FPOP; \ + FPOP; \ + return; \ + } \ + fpu_flags.result.tag = FPUREG_PNAN; \ + FPOP; \ + FPOP; \ +} + + + + diff --git a/src/fpu/fpu_types.h b/src/fpu/fpu_types.h new file mode 100644 index 00000000..1079dbf8 --- /dev/null +++ b/src/fpu/fpu_types.h @@ -0,0 +1,32 @@ + +enum { FPUREG_VALID=0, FPUREG_ZERO, FPUREG_PNAN, FPUREG_NNAN, FPUREG_EMPTY }; + +enum { + t_FLD=0, t_FLDST, t_FDIV, + t_FDIVP, t_FCHS, t_FCOMP, + + t_FUNKNOWN, + t_FNOTDONE, +}; + +struct FPU_Flag_Info { + struct { + Real r; + Bit8u tag; + } var1,var2, result; + struct { + bool bf,c3,c2,c1,c0,ir,sf,pf,uf,of,zf,df,in; + Bit8s tos; + } sw; + struct { + bool ic,ie,sf,pf,uf,of,zf,df,in; + Bit8u rc,pc; + } cw; + Bitu type; + Bitu prev_type; +}; + +struct FPU_Reg { + Real r; + Bit8u tag; +}; From 96bfd3d47c28a7b5b2f23c175b971cf38e0ef76b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 28 Jul 2002 16:34:29 +0000 Subject: [PATCH 0010/4131] *** empty log message *** Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@87 --- src/fpu/fpu_core_16/instructions.h | 158 ----------------------------- src/fpu/fpu_core_16/support.h | 89 ---------------- visualc/dosbox.dsp | 26 ++--- 3 files changed, 13 insertions(+), 260 deletions(-) delete mode 100644 src/fpu/fpu_core_16/instructions.h delete mode 100644 src/fpu/fpu_core_16/support.h diff --git a/src/fpu/fpu_core_16/instructions.h b/src/fpu/fpu_core_16/instructions.h deleted file mode 100644 index 271f03f8..00000000 --- a/src/fpu/fpu_core_16/instructions.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2002 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#define FLD(op1) { \ - FPU_GetZF; \ - fpu_flags.type=t_FLD; \ - if(--fpu_flags.sw.tos < 0) \ - fpu_flags.sw.tos = 7; \ - if( fpu_regs.st[fpu_flags.sw.tos].tag != FPUREG_EMPTY ) { \ - fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_NNAN; \ - break; \ - } \ - if(op1) \ - fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_VALID; \ - else \ - fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_ZERO; \ - fpu_flags.result.r = fpu_regs.st[fpu_flags.sw.tos].r = op1; \ -} - -#define FLDST(op1) { \ - FPU_GetZF; \ - fpu_flags.type=t_FLDST; \ - Bit8u reg = fpu_flags.sw.tos+op1; \ - if(reg>7) reg-=8; \ - if(--fpu_flags.sw.tos < 0) \ - fpu_flags.sw.tos = 7; \ - if(fpu_regs.st[fpu_flags.sw.tos].tag!=FPUREG_EMPTY) { \ - fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_NNAN; \ - break; \ - } \ - fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = fpu_regs.st[reg].tag; \ - fpu_flags.result.r = fpu_regs.st[fpu_flags.sw.tos].r = fpu_regs.st[reg].r; \ -} - -#define FPOP { \ - fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_EMPTY; \ - if(++fpu_flags.sw.tos > 7 ) \ - fpu_flags.sw.tos = 0; \ -} -/* FPOP: fpu_flags.result.r = fpu_regs.st[fpu_flags.sw.tos].r = 0; is not really neccessary */ - -#define FDIVP(op1,op2) { \ - Bit8u reg1 = fpu_flags.sw.tos+op1; \ - Bit8u reg2 = fpu_flags.sw.tos+op2; \ - fpu_flags.type=t_FDIVP; \ - if(reg1>7) reg1-=8; \ - if(reg2>7) reg2-=8; \ - if((fpu_regs.st[reg1].tag!=FPUREG_VALID && fpu_regs.st[reg1].tag!=FPUREG_ZERO)||(fpu_regs.st[reg2].tag!=FPUREG_VALID && fpu_regs.st[reg2].tag!=FPUREG_ZERO)) { \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ - FPOP; \ - break; \ - } \ - if(fpu_regs.st[reg2].tag == FPUREG_ZERO) { \ - if(fpu_regs.st[reg1].r > 0) \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_PNAN; \ - else \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ - FPOP; \ - break; \ - } \ - if(fpu_regs.st[reg1].tag == FPUREG_ZERO) { \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_ZERO; \ - FPOP; \ - break; \ - } \ - fpu_flags.result.tag = FPUREG_VALID; \ - fpu_flags.result.r = fpu_regs.st[reg1].r = fpu_regs.st[reg1].r / fpu_regs.st[reg2].r; \ - FPOP; \ -} - -#define FDIV(op1,op2) { \ - Bit8u reg1 = fpu_flags.sw.tos+op1; \ - Bit8u reg2 = fpu_flags.sw.tos+op2; \ - fpu_flags.type=t_FDIV; \ - if(reg1>7) reg1-=7; \ - if(reg2>7) reg2-=7; \ - if((fpu_regs.st[reg1].tag!=FPUREG_VALID && fpu_regs.st[reg1].tag!=FPUREG_ZERO)||(fpu_regs.st[reg2].tag!=FPUREG_VALID && fpu_regs.st[reg2].tag!=FPUREG_ZERO)) { \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ - break; \ - } \ - if(fpu_regs.st[reg2].tag == FPUREG_ZERO) { \ - if(fpu_regs.st[reg1].r > 0) \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_PNAN; \ - else \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ - break; \ - } \ - if(fpu_regs.st[reg1].tag == FPUREG_ZERO) { \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_ZERO; \ - break; \ - } \ - fpu_flags.result.tag = FPUREG_VALID; \ - fpu_flags.result.r = fpu_regs.st[reg1].r = fpu_regs.st[reg1].r / fpu_regs.st[reg2].r; \ -} - -#define FCHS { \ - FPU_GetZF; \ - fpu_flags.type=t_FCHS; \ - if(fpu_regs.st[fpu_flags.sw.tos].tag == FPUREG_PNAN) { \ - fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_NNAN; \ - } else if(fpu_regs.st[fpu_flags.sw.tos].tag == FPUREG_NNAN) { \ - fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_PNAN; \ - } else \ - fpu_regs.st[fpu_flags.sw.tos].r = -fpu_regs.st[fpu_flags.sw.tos].r; \ -} - -#define FCOMPP { \ - Bit8u reg = fpu_flags.sw.tos+1; \ - FPU_GetZF; \ - fpu_flags.type=t_FCOMP; \ - if(reg>7) \ - reg=0; \ - if((fpu_regs.st[reg].tag==FPUREG_VALID||fpu_regs.st[reg].tag==FPUREG_ZERO)&&(fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_VALID||fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_ZERO)) { \ - fpu_flags.result.r = fpu_regs.st[reg].r - fpu_regs.st[fpu_flags.sw.tos].r; \ - if(fpu_flags.result.r==0) \ - fpu_flags.result.tag = FPUREG_ZERO; \ - else \ - fpu_flags.result.tag = FPUREG_VALID; \ - FPOP; \ - FPOP; \ - return; \ - } else if(((fpu_regs.st[reg].tag==FPUREG_EMPTY)||(fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_EMPTY))||((fpu_regs.st[reg].tag==FPUREG_VALID||fpu_regs.st[reg].tag==FPUREG_ZERO)||(fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_VALID||fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_ZERO))) { \ - fpu_flags.result.tag = FPUREG_EMPTY; \ - FPOP; \ - FPOP; \ - return; \ - } \ - Bit8s res = (fpu_regs.st[reg].tag-fpu_regs.st[fpu_flags.sw.tos].tag); \ - if(res==0||fpu_flags.cw.ic==0) { \ - fpu_flags.result.tag = FPUREG_ZERO; \ - FPOP; \ - FPOP; \ - return; \ - } else if(res>0) { \ - fpu_flags.result.tag = FPUREG_NNAN; \ - FPOP; \ - FPOP; \ - return; \ - } \ - fpu_flags.result.tag = FPUREG_PNAN; \ - FPOP; \ - FPOP; \ -} \ No newline at end of file diff --git a/src/fpu/fpu_core_16/support.h b/src/fpu/fpu_core_16/support.h deleted file mode 100644 index dd6434ae..00000000 --- a/src/fpu/fpu_core_16/support.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2002 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#define FPU_ESC_0 { \ - Bit8u rm=Fetchb(); \ - if (rm>=0xc0) { \ - FPU_ESC0_Normal(rm); \ - } else { \ - GetEAa;FPU_ESC0_EA(rm,eaa); \ - } \ - } - -#define FPU_ESC_1 { \ - Bit8u rm=Fetchb(); \ - if (rm>=0xc0) { \ - FPU_ESC1_Normal(rm); \ - } else { \ - GetEAa;FPU_ESC1_EA(rm,eaa); \ - } \ - } - -#define FPU_ESC_2 { \ - Bit8u rm=Fetchb(); \ - if (rm>=0xc0) { \ - FPU_ESC2_Normal(rm); \ - } else { \ - GetEAa;FPU_ESC2_EA(rm,eaa); \ - } \ - } - -#define FPU_ESC_3 { \ - Bit8u rm=Fetchb(); \ - if (rm>=0xc0) { \ - FPU_ESC3_Normal(rm); \ - } else { \ - GetEAa;FPU_ESC3_EA(rm,eaa); \ - } \ - } - -#define FPU_ESC_4 { \ - Bit8u rm=Fetchb(); \ - if (rm>=0xc0) { \ - FPU_ESC4_Normal(rm); \ - } else { \ - GetEAa;FPU_ESC4_EA(rm,eaa); \ - } \ - } - -#define FPU_ESC_5 { \ - Bit8u rm=Fetchb(); \ - if (rm>=0xc0) { \ - FPU_ESC5_Normal(rm); \ - } else { \ - GetEAa;FPU_ESC5_EA(rm,eaa); \ - } \ - } - -#define FPU_ESC_6 { \ - Bit8u rm=Fetchb(); \ - if (rm>=0xc0) { \ - FPU_ESC6_Normal(rm); \ - } else { \ - GetEAa;FPU_ESC6_EA(rm,eaa); \ - } \ - } - -#define FPU_ESC_7 { \ - Bit8u rm=Fetchb(); \ - if (rm>=0xc0) { \ - FPU_ESC7_Normal(rm); \ - } else { \ - GetEAa;FPU_ESC7_EA(rm,eaa); \ - } \ - } \ No newline at end of file diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index 1e21b1ca..9428e55e 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -223,6 +223,10 @@ SOURCE=..\src\dos\dos.cpp # End Source File # Begin Source File +SOURCE=..\src\dos\dos_classes.cpp +# End Source File +# Begin Source File + SOURCE=..\src\dos\dos_devices.cpp # End Source File # Begin Source File @@ -463,6 +467,10 @@ SOURCE=..\src\misc\programs.cpp # End Source File # Begin Source File +SOURCE=..\src\misc\setup.cpp +# End Source File +# Begin Source File + SOURCE=..\src\misc\support.cpp # End Source File # End Group @@ -493,25 +501,17 @@ SOURCE=..\src\shell\shell_misc.cpp # Begin Group "fpu" # PROP Default_Filter "" -# Begin Group "fpu_core_16" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\src\fpu\fpu_core_16\instructions.h -# End Source File -# Begin Source File - -SOURCE=..\src\fpu\fpu_core_16\support.h -# End Source File -# End Group # Begin Source File SOURCE=..\src\fpu\fpu.cpp # End Source File # Begin Source File -SOURCE=..\src\fpu\fpu_flags.cpp +SOURCE=..\src\fpu\fpu_instructions.h +# End Source File +# Begin Source File + +SOURCE=..\src\fpu\fpu_types.h # End Source File # End Group # Begin Group "visualc" From 14f0ad85561873ea89fcc56cd233248396f1409f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 28 Jul 2002 21:52:31 +0000 Subject: [PATCH 0011/4131] Fixed FPU_ESC #define Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@88 --- include/fpu.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/include/fpu.h b/include/fpu.h index b0244bf6..d181a2ac 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -19,6 +19,8 @@ #ifndef __FPU_H #define __FPU_H +#include "mem.h" + void FPU_ESC0_Normal(Bitu rm); void FPU_ESC0_EA(Bitu func,PhysPt ea); void FPU_ESC1_Normal(Bitu rm); @@ -36,12 +38,12 @@ void FPU_ESC6_EA(Bitu func,PhysPt ea); void FPU_ESC7_Normal(Bitu rm); void FPU_ESC7_EA(Bitu func,PhysPt ea); -#define FPU_ESC(a) { \ +#define FPU_ESC(code) { \ Bit8u rm=Fetchb(); \ if (rm>=0xc0) { \ - FPU_ESC0_Normal(rm); \ + FPU_ESC ## code ## _Normal(rm); \ } else { \ - GetEAa;FPU_ESC0_EA(rm,eaa); \ + GetEAa;FPU_ESC ## code ## _EA(rm,eaa); \ } \ } From 398c8909cd6c02a0fe72691a3078e7e6ead3e262 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 29 Jul 2002 09:35:02 +0000 Subject: [PATCH 0012/4131] INT10_WriteChar fixed to move the cursor. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@89 --- src/ints/int10_char.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index d0dd415b..af0e7d76 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -311,9 +311,15 @@ void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); + BIOS_NCOLS;BIOS_NROWS; while (count>0) { WriteChar(cur_col,cur_row,page,chr,attr,showattr); count--; + cur_col++; + if(cur_col==ncols) { + cur_col=0; + cur_row++; + } } } From ce98694674852c0a158c2c38ccbf40f8377cbe67 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 29 Jul 2002 10:05:40 +0000 Subject: [PATCH 0013/4131] fixed disable-joystick (for FreeBSD) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@90 --- src/gui/sdlmain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 08e40d33..139f33e4 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -497,8 +497,8 @@ int main(int argc, char* argv[]) { sdl.joy=SDL_JoystickOpen(0); LOG_MSG("Using joystick %s with %d axes and %d buttons",SDL_JoystickName(0),SDL_JoystickNumAxes(sdl.joy),SDL_JoystickNumButtons(sdl.joy)); JOYSTICK_Enable(0,true); + } #endif - } /* Start dosbox up */ DOSBOX_StartUp(); } @@ -510,4 +510,4 @@ int main(int argc, char* argv[]) { return 0; -}; \ No newline at end of file +}; From fe57c713045785de7796f0ec57ec451f78394cf9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 29 Jul 2002 10:48:11 +0000 Subject: [PATCH 0014/4131] Changelog updated with recent changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@91 --- ChangeLog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 051d4d61..6b47515e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ - 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. From 0b0fb71a5e1618e2b0a4423b5ee7f06ce976fbd7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 29 Jul 2002 10:50:51 +0000 Subject: [PATCH 0015/4131] added newline on end of file to keep gcc3 from complaining Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@92 --- settings.h.cvs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/settings.h.cvs b/settings.h.cvs index cf2aa2fd..f61ded61 100644 --- a/settings.h.cvs +++ b/settings.h.cvs @@ -26,4 +26,5 @@ #define LOG_DEBUG #define LOG_WARN #define LOG_ERROR -#endif \ No newline at end of file +#endif + From 9e6f36a09b5a383ec059a38edf0d656c75325d18 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 29 Jul 2002 13:17:06 +0000 Subject: [PATCH 0016/4131] Show SDL Error message Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@93 --- src/gui/sdlmain.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 139f33e4..9b81a650 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -485,7 +485,7 @@ int main(int argc, char* argv[]) { #endif ) < 0 ) { - E_Exit("Can't init SDL"); + E_Exit("Can't init SDL %s",SDL_GetError()); } GFX_StartUp(); /* Init all the dosbox subsystems */ @@ -497,9 +497,9 @@ int main(int argc, char* argv[]) { sdl.joy=SDL_JoystickOpen(0); LOG_MSG("Using joystick %s with %d axes and %d buttons",SDL_JoystickName(0),SDL_JoystickNumAxes(sdl.joy),SDL_JoystickNumButtons(sdl.joy)); JOYSTICK_Enable(0,true); - } + } #endif -/* Start dosbox up */ + /* Start dosbox up */ DOSBOX_StartUp(); } catch (Bitu e) { @@ -510,4 +510,4 @@ int main(int argc, char* argv[]) { return 0; -}; +}; \ No newline at end of file From c603dedc52c4c2acd27218970f4c8f9313132db3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 29 Jul 2002 14:06:51 +0000 Subject: [PATCH 0017/4131] changed the basedir search routine Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@94 --- src/dosbox.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 735491be..72f10c67 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include "dosbox.h" #include "debug.h" #include "cpu.h" @@ -243,10 +244,11 @@ static void InitSystems(void) { void DOSBOX_Init(int argc, char* argv[]) { /* Find the base directory */ - strcpy(dosbox_basedir,argv[0]); - char * last=strrchr(dosbox_basedir,CROSS_FILESPLIT); //if windowsversion fails: - if (!last) E_Exit("Can't find basedir %s", argv[0]); - *++last=0; + getcwd(dosbox_basedir,CROSS_LEN); + char a[2]; + a[0]=CROSS_FILESPLIT; + a[1]='\0'; + strcat(dosbox_basedir,a); /* Parse the command line with a setup function */ int argl=1; if (argc>1) { From cbc226bf9268f94928a6175e7e896db825b3628d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 29 Jul 2002 14:21:36 +0000 Subject: [PATCH 0018/4131] changed basedir handling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@95 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 6b47515e..f7f9bda1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,5 @@ - 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 :) From 20a6b42f1c6728c222960f53c9e4ec74524285fe Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Jul 2002 09:51:26 +0000 Subject: [PATCH 0019/4131] Illegal command displays the command Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@96 --- ChangeLog | 2 +- src/dosbox.lang | 2 +- src/shell/shell_misc.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index f7f9bda1..fe845bdc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,4 +2,4 @@ - 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 diff --git a/src/dosbox.lang b/src/dosbox.lang index 2a68c7ff..783083cd 100644 --- a/src/dosbox.lang +++ b/src/dosbox.lang @@ -71,5 +71,5 @@ The DOSBox Team Drive %c does not exist! . :SHELL_EXECUTE_ILLEGAL_COMMAND -Illegal command +Illegal command: %s . diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 1d003c35..bb939ad9 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -138,7 +138,7 @@ void DOS_Shell::Execute(char * name,char * args) { /* Check for a full name */ fullname=Which(name); if (!fullname) { - WriteOut(MSG_Get("SHELL_EXECUTE_ILLEGAL_COMMAND")); + WriteOut(MSG_Get("SHELL_EXECUTE_ILLEGAL_COMMAND"),name); return; } if (strcasecmp(strrchr(fullname, '.'), ".bat") == 0) { From 487e9392d505762e4c207b0d9a9c2e5921fedc9e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 30 Jul 2002 11:59:35 +0000 Subject: [PATCH 0020/4131] Clean up Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@97 --- include/regs.h | 48 +++++------------------------------------------- 1 file changed, 5 insertions(+), 43 deletions(-) diff --git a/include/regs.h b/include/regs.h index 43b909e4..a86fcbee 100644 --- a/include/regs.h +++ b/include/regs.h @@ -35,25 +35,6 @@ struct Flag_Info { bool oldcf; }; -struct FPU_Flag_Info { - struct { - Real64 r; - Bit8u tag; - } var1,var2, result; - struct { - bool bf,c3,c2,c1,c0,ir,sf,pf,uf,of,zf,df,in; - Bit8s tos; - } sw; - struct { - bool ic,ie,sf,pf,uf,of,zf,df,in; - Bit8u rc,pc; - } cw; - Bitu type; - Bitu prev_type; -}; - - - struct Segment { Bit16u value; bool special; /* Signal for pointing to special memory */ @@ -61,19 +42,8 @@ struct Segment { PhysPt phys; /* The phyiscal address start in emulated machine */ }; - - - enum { cs=0,ds,es,fs,gs,ss}; -extern Segment Segs[6]; -extern Flag_Info flags; -extern FPU_Flag_Info fpu_flags; -//extern Regs regs; - -void SetSegment_16(Bit32u seg,Bit16u val); - - struct CPU_Regs { union { Bit32u d; @@ -84,19 +54,15 @@ struct CPU_Regs { } ax,bx,cx,dx,si,di,sp,bp,ip; }; -struct FPU_Regs { - struct { - Real64 r; - Bit8u tag; - } st[8]; -}; - +extern Segment Segs[6]; +extern Flag_Info flags; extern CPU_Regs cpu_regs; -#define reg_al cpu_regs.ax.b.l +void SetSegment_16(Bit32u seg,Bit16u val); + //extern Bit8u & reg_al=cpu_regs.ax.b.l; - +#define reg_al cpu_regs.ax.b.l #define reg_ah cpu_regs.ax.b.h #define reg_ax cpu_regs.ax.w #define reg_eax cpu_regs.ax.d @@ -131,9 +97,5 @@ extern CPU_Regs cpu_regs; #define reg_ip cpu_regs.ip.w #define reg_eip cpu_regs.ip.d - - - - #endif From 59df83a32c09630ebc465e857d553ed3797f3fa0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Jul 2002 12:07:08 +0000 Subject: [PATCH 0021/4131] wildcmp updated Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@98 --- ChangeLog | 1 + src/misc/support.cpp | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index fe845bdc..15ed52ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,3 +3,4 @@ - 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 diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 1348dc71..ba3124c9 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -85,7 +85,8 @@ char *trim(char *str) { bool wildcmp(char *wild, char *string) { char *cp, *mp; while ((*string) && (*wild != '*')) { - if ((*wild != *string) && (*wild != '?')) { + if ((*upcase(wild) != *upcase(string)) && (*wild != '?')) { + return false; } wild++; @@ -99,7 +100,7 @@ bool wildcmp(char *wild, char *string) { } mp = wild; cp = string+1; - } else if ((*wild == *string) || (*wild == '?')) { + } else if ((*upcase(wild) == *upcase(string)) || (*wild == '?')) { wild++; string++; } else { From e0aba101afbc177d9767bdc40eb4be17784cdb61 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Jul 2002 12:24:55 +0000 Subject: [PATCH 0022/4131] base handling (changed again) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@99 --- src/dosbox.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 72f10c67..c8b99782 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -244,11 +244,18 @@ static void InitSystems(void) { void DOSBOX_Init(int argc, char* argv[]) { /* Find the base directory */ - getcwd(dosbox_basedir,CROSS_LEN); - char a[2]; - a[0]=CROSS_FILESPLIT; - a[1]='\0'; - strcat(dosbox_basedir,a); + strcpy(dosbox_basedir,argv[0]); + char * last=strrchr(dosbox_basedir,CROSS_FILESPLIT); //if windowsversion fails: + if (!last){ + getcwd(dosbox_basedir,CROSS_LEN); + char a[2]; + a[0]=CROSS_FILESPLIT; + a[1]='\0'; + strcat(dosbox_basedir,a); + } else { + *++last=0; + } + /* Parse the command line with a setup function */ int argl=1; if (argc>1) { From aa5c7f77c9a082cd43cac4ee21e4ac9fc29293bc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 30 Jul 2002 12:38:18 +0000 Subject: [PATCH 0023/4131] *** empty log message *** Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@100 --- src/dosbox.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index c8b99782..538d192f 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -244,6 +244,8 @@ static void InitSystems(void) { void DOSBOX_Init(int argc, char* argv[]) { /* Find the base directory */ + SHELL_AddAutoexec("SET PATH=Z:\\"); + SHELL_AddAutoexec("SET COMSPEC=Z:\\COMMAND.COM"); strcpy(dosbox_basedir,argv[0]); char * last=strrchr(dosbox_basedir,CROSS_FILESPLIT); //if windowsversion fails: if (!last){ @@ -255,7 +257,6 @@ void DOSBOX_Init(int argc, char* argv[]) { } else { *++last=0; } - /* Parse the command line with a setup function */ int argl=1; if (argc>1) { @@ -302,7 +303,5 @@ void DOSBOX_Init(int argc, char* argv[]) { void DOSBOX_StartUp(void) { - SHELL_AddAutoexec("SET PATH=Z:\\"); - SHELL_AddAutoexec("SET COMSPEC=Z:\\COMMAND.COM"); SHELL_Init(); }; From 805f78cf16ac68674dcb70cbfbf2e9a7601eea2f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 30 Jul 2002 12:41:55 +0000 Subject: [PATCH 0024/4131] wildcmp, upcase in toupper Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@101 --- src/misc/support.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/misc/support.cpp b/src/misc/support.cpp index ba3124c9..b4f04628 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -85,7 +85,7 @@ char *trim(char *str) { bool wildcmp(char *wild, char *string) { char *cp, *mp; while ((*string) && (*wild != '*')) { - if ((*upcase(wild) != *upcase(string)) && (*wild != '?')) { + if ((toupper(*wild) != toupper(*string)) && (*wild != '?')) { return false; } @@ -100,7 +100,7 @@ bool wildcmp(char *wild, char *string) { } mp = wild; cp = string+1; - } else if ((*upcase(wild) == *upcase(string)) || (*wild == '?')) { + } else if ((toupper(*wild) == toupper(*string)) || (*wild == '?')) { wild++; string++; } else { From 1757db38914a841898981a956b975da30ee901e2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 30 Jul 2002 12:50:57 +0000 Subject: [PATCH 0025/4131] Fix with rm byte not being read Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@102 --- src/cpu/core_16/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 30944784..2a079a61 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -971,7 +971,7 @@ restart: case 0xde: /* FPU ESC 6 */ case 0xdf: /* FPU ESC 7 */ { - Bit8u rm; + Bit8u rm=Fetchb(); if (rm<0xc0) GetEAa; } break; From 9f301d2d6381403ad7486e7d9bc390c72eb226ef Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 30 Jul 2002 12:51:26 +0000 Subject: [PATCH 0026/4131] Setup environment for the shell correctly. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@103 --- src/shell/shell.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 63e4dadd..241e1a5a 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -158,8 +158,9 @@ void SHELL_Init() { psp->file_table=RealMake(psp_seg,offsetof(PSP,files)); /* Save old DTA in psp */ psp->dta=dos.dta; + /* Set the environment and clear it */ psp->environment=env_seg+1; - + mem_writew(Real2Phys(RealMake(env_seg+1,0)),0); /* Setup internal DOS Variables */ dos.dta=RealMake(psp_seg,0x80); dos.psp=psp_seg; From e1a9d3e6162b90746eeef1bb818335ba255da193 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Jul 2002 13:13:10 +0000 Subject: [PATCH 0027/4131] msg_init: shows were it was looking for the messages if it can't find them Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@104 --- src/misc/messages.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index b07a11a3..d7e05b2d 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -42,7 +42,7 @@ static void LoadMessageFile(char * fname) { FILE * mfile=fopen(fname,"rb"); /* This should never happen and since other modules depend on this use a normal printf */ if (!mfile) { - E_Exit("MSG:Can't load messages",fname); + E_Exit("MSG:Can't load messages: %s",fname); } char linein[LINE_IN_MAXLEN]; char name[LINE_IN_MAXLEN]; From 77da18040545963a99764c2d2a38f5f3cc20d3fe Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 30 Jul 2002 13:55:41 +0000 Subject: [PATCH 0028/4131] cd.. is upon us Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@105 --- src/shell/shell_cmds.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index c34624b9..c3869213 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -53,6 +53,7 @@ void DOS_Shell::DoCommand(char * line) { while (*line) { if (*line==32) break; if (*line=='/') break; + if (*line=='.') break; *cmd_write++=*line++; } *cmd_write=0; From 92105f3caf554aa6f010656b3270ca02bc74fd70 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 31 Jul 2002 11:46:27 +0000 Subject: [PATCH 0029/4131] Buffered input fix for dual enter press. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@106 --- src/dos/dos.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 85415ac6..aefbfaf9 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -121,11 +121,9 @@ static Bitu DOS_21Handler(void) { while (read Date: Wed, 31 Jul 2002 12:23:26 +0000 Subject: [PATCH 0030/4131] Error in maketables procuced double lines. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@107 --- src/gui/render.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index b6867b03..04c3b475 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -67,13 +67,13 @@ static void MakeTables(void) { Bitu i;Bit32u c,a; c=0;a=(render.src.width<<16)/gfx_info.width; for (i=0;i> 16; c=(c&0xffff)+a; + render.stretch_x[i]=c>> 16; } c=0;a=(render.src.height<<16)/gfx_info.height; for (i=0;i> 16)*render.src.pitch; c=(c&0xffff)+a; + render.stretch_y[i]=(c>>16)*render.src.pitch; } } From 438ad2b437c18fc9153662eeadc62dc2c71eba2a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 31 Jul 2002 12:26:04 +0000 Subject: [PATCH 0031/4131] cd.. now works and doesn't brake hwset.com anymore Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@108 --- src/shell/shell_cmds.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index c3869213..164b4346 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -53,7 +53,7 @@ void DOS_Shell::DoCommand(char * line) { while (*line) { if (*line==32) break; if (*line=='/') break; - if (*line=='.') break; + if ((*line=='.') && (*(line+1)=='.')) break; *cmd_write++=*line++; } *cmd_write=0; From a4c775bff45d0d122c3b973fad31c0280b571068 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 31 Jul 2002 15:20:12 +0000 Subject: [PATCH 0032/4131] make compiler happy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@109 --- include/dos_inc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 32414ca4..c5df32db 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -163,7 +163,7 @@ bool DOS_CreateFile(char * name,Bit16u attribute,Bit16u * entry); bool DOS_UnlinkFile(char * name); bool DOS_FindFirst(char *search,Bit16u attr); bool DOS_FindNext(void); -bool DOS_Canonicalize(char * small,Bit8u * big); +bool DOS_Canonicalize(char * name,Bit8u * big); bool DOS_CreateTempFile(char * name,Bit16u * entry); bool DOS_FileExists(char * name); /* Drive Handing Routines */ From 1b31218f2bd07e876a070b6a07478a2d55da8bf2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 6 Aug 2002 09:19:56 +0000 Subject: [PATCH 0033/4131] added FileStat and FileExits to the drives Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@110 --- src/dos/drive_local.cpp | 29 +++++++++++++++++++++++++++-- src/dos/drive_virtual.cpp | 28 ++++++++++++++++++++++++++++ src/dos/drives.h | 7 ++++++- 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 9b7cf0a1..59171647 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -187,6 +187,7 @@ bool localDrive::RemoveDir(char * dir) { char newdir[512]; strcpy(newdir,basedir); strcat(newdir,dir); + CROSS_FILENAME(newdir); int temp=rmdir(newdir); return (temp==0); } @@ -195,6 +196,7 @@ bool localDrive::TestDir(char * dir) { char newdir[512]; strcpy(newdir,basedir); strcat(newdir,dir); + CROSS_FILENAME(newdir); int temp=access(newdir,F_OK); return (temp==0); } @@ -206,8 +208,8 @@ bool localDrive::Rename(char * oldname,char * newname) { CROSS_FILENAME(newold); char newnew[512]; strcpy(newnew,basedir); - strcat(newnew,newnew); - CROSS_FILENAME(newname); + strcat(newnew,newname); + CROSS_FILENAME(newnew); int temp=rename(newold,newnew); return (temp==0); @@ -223,6 +225,28 @@ bool localDrive::FreeSpace(Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit return true; }; +bool localDrive::FileExists(const char* name) const { + char newname[512]; + strcpy(newname,basedir); + strcat(newname,name); + CROSS_FILENAME(newname); + FILE* Temp=fopen(newname,"br"); + if(Temp==NULL) return false; + fclose(Temp); + return true; +} + +bool localDrive::FileStat(const char* name, struct stat* const stat_block) const { + char newname[512]; + strcpy(newname,basedir); + strcat(newname,name); + CROSS_FILENAME(newname); + if(stat(newname,stat_block)!=0) return false; + return true; + +} + + localDrive::localDrive(char * startdir) { strcpy(basedir,startdir); @@ -275,3 +299,4 @@ localFile::localFile(FILE * handle,Bit16u devinfo) { info=devinfo; } + diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index b8140e1d..0be5dc6e 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -19,10 +19,12 @@ #include #include #include +#include #include "dosbox.h" #include "dos_system.h" #include "drives.h" #include "support.h" +#include "cross.h" struct VFILE_Block { char * name; @@ -151,6 +153,32 @@ bool Virtual_Drive::TestDir(char * dir) { return false; } +bool Virtual_Drive::FileStat(const char* name, struct stat* const stat_block) const { + VFILE_Block * cur_file=first_file; + while (cur_file) { + if (strcasecmp(name,cur_file->name)==0) { + stat_block->st_size=cur_file->size; + struct tm tijd; + tijd.tm_hour=0;tijd.tm_min=0;tijd.tm_sec=0; + tijd.tm_year=80;tijd.tm_mday=6;tijd.tm_mon=0; + stat_block->st_mtime=mktime(&tijd); + /* more not needed at the moment (fcbopen.....)*/ + return true; + } + cur_file=cur_file->next; + } + return false; +} + +bool Virtual_Drive::FileExists(const char* name) const { + VFILE_Block * cur_file=first_file; + while (cur_file) { + if (strcasecmp(name,cur_file->name)==0) return true; + cur_file=cur_file->next; + } + return false; +} + static void FillDTABlock(DTA_FindBlock * dta,VFILE_Block * fill_file) { strcpy(dta->name,fill_file->name); dta->size=fill_file->size; diff --git a/src/dos/drives.h b/src/dos/drives.h index a2dcf75e..b46e376a 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -21,7 +21,7 @@ #include #include - +#include "dos_system.h" class localDrive : public DOS_Drive { public: @@ -37,6 +37,8 @@ public: bool GetFileAttr(char * name,Bit16u * attr); bool Rename(char * oldname,char * newname); bool FreeSpace(Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free); + bool FileExists(const char* name) const ; + bool FileStat(const char* name, struct stat* const stat_block) const; private: bool FillDTABlock(DTA_FindBlock * dta); char basedir[512]; @@ -63,6 +65,9 @@ public: bool GetFileAttr(char * name,Bit16u * attr); bool Rename(char * oldname,char * newname); bool FreeSpace(Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free); + bool FileExists(const char* name) const ; + bool FileStat(const char* name, struct stat* const stat_block) const; + private: VFILE_Block * search_file; char search_string[255]; From b4f2801c7efe016d712ed712220b09fac4cc8cb1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 6 Aug 2002 09:20:41 +0000 Subject: [PATCH 0034/4131] added fcb-calls:open, close, findfirst,findnext to dos Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@111 --- include/dos_inc.h | 6 ++ include/dos_system.h | 2 + src/dos/dos.cpp | 31 ++++++++- src/dos/dos_files.cpp | 153 +++++++++++++++++++++--------------------- visualc/dosbox.dsp | 2 +- 5 files changed, 117 insertions(+), 77 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index c5df32db..e3e79cf8 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -195,6 +195,12 @@ bool DOS_FreeMemory(Bit16u segment); void DOS_FreeProcessMemory(Bit16u pspseg); Bit16u DOS_GetMemory(Bit16u pages); + +/* FCB stuff */ +bool DOS_FCBOpen(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); /* Extra DOS Interrupts */ void DOS_SetupMisc(void); diff --git a/include/dos_system.h b/include/dos_system.h index 55f210a8..02828782 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -82,6 +82,8 @@ public: virtual bool GetFileAttr(char * name,Bit16u * attr)=0; virtual bool Rename(char * oldname,char * newname)=0; virtual bool FreeSpace(Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free)=0; + virtual bool FileExists(const char* name) const=0; + virtual bool FileStat(const char* name, struct stat* const stat_block) const=0; char * GetInfo(void); char curdir[DOS_PATHLENGTH]; char info[256]; diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index aefbfaf9..1f207caf 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -164,9 +164,38 @@ static Bitu DOS_21Handler(void) { reg_al=26; break; case 0x0f: /* Open File using FCB */ + if(DOS_FCBOpen(Segs[ds].value,reg_dx)){ + reg_al=0; + }else{ + reg_al=0xff; + } + LOG_DEBUG("DOS:0x0f FCB-fileopen used"); + break; + case 0x10: /* Close File using FCB */ + if(DOS_FCBClose(Segs[ds].value,reg_dx)){ + reg_al=0; + }else{ + reg_al=0xff; + } + LOG_DEBUG("DOS:0x0f FCB-fileclose used"); + break; case 0x11: /* Find First Matching File using FCB */ + if(DOS_FCBFindFirst(Segs[ds].value,reg_dx)){ + reg_al=0; + }else{ + reg_al=0xff; + } + LOG_DEBUG("DOS:0x0f FCB-FindFirst used"); + break; case 0x12: /* Find Next Matching File using FCB */ + if(DOS_FCBFindNext(Segs[ds].value,reg_dx)){ + reg_al=0; + }else{ + reg_al=0xff; + } + LOG_DEBUG("DOS:0x0f FCB-FindNext used"); + break; case 0x13: /* Delete File using FCB */ case 0x14: /* Sequential read from FCB */ case 0x15: /* Sequential write to FCB */ @@ -180,7 +209,7 @@ static Bitu DOS_21Handler(void) { case 0x28: /* Random Block read to FCB */ LOG_ERROR("DOS:Unhandled call %02X, FCB Stuff",reg_ah); reg_al=0xff; /* FCB Calls FAIL */ - CALLBACK_SCF(true); + //CALLBACK_SCF(true); not needed. break; case 0x29: /* Parse filename into FCB */ //TODO Give errors for unsupported functions diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 34f3960c..c4936d7b 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -18,11 +18,13 @@ #include #include +#include #include "dosbox.h" #include "mem.h" #include "cpu.h" #include "dos_inc.h" #include "drives.h" +#include "cross.h" #define DOS_FILESTART 4 @@ -446,9 +448,10 @@ bool DOS_CreateTempFile(char * name,Bit16u * entry) { } while (!DOS_CreateFile(name,0,entry)); return true; } -#if 0 -void FCB_MakeName (DOS_FCB* fcb, char* outname, Bit8u* outdrive){ +#if 1 +static bool FCB_MakeName (DOS_FCB* fcb, char* outname, Bit8u* outdrive){ char naam[15]; + Bit8s teller=0; Bit8u drive=fcb->Get_drive(); if(drive!=0){ naam[0]=(drive-1)+'A'; @@ -457,21 +460,16 @@ void FCB_MakeName (DOS_FCB* fcb, char* outname, Bit8u* outdrive){ else{ naam[0]='\0'; }; - char temp[9]; + char temp[10]; fcb->Get_filename(temp); - temp[9]='.'; - strncat(naam,temp,9); - char ext[3]; + temp[8]='.'; + temp[9]='\0'; + strcat(naam,temp); + char ext[4]; fcb->Get_ext(ext); - if(drive!=0) { - strncat(&naam[11],ext,3); - naam[14]='\0'; - }else{ - strncat(&naam[9],ext,3); - naam[12]='\0'; - }; - DOS_MakeName(naam,outname, outdrive); - return; + ext[3]='\0'; + strcat(naam,ext); + return DOS_MakeName(naam,outname, outdrive); } @@ -479,14 +477,13 @@ bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); Bit8u drive; char fullname[DOS_PATHLENGTH]; - FCB_MakeName (&fcb, fullname, &drive); - if(DOS_FileExists(fullname)==false) return false; - + if(!FCB_MakeName (&fcb, fullname, &drive)) return false; + if(!Drives[drive]->FileExists(fullname)) return false; //not really needed as stat will error. - struct stat stat_block; - stat(fullname, &stat_block); + struct stat stat_block; + if(!Drives[drive]->FileStat(fullname, &stat_block)) return false; fcb.Set_filesize((Bit32u)stat_block.st_size); - Bit16u constant =0; + Bit16u constant = 0; fcb.Set_current_block(constant); constant=0x80; fcb.Set_record_size(constant); @@ -494,52 +491,60 @@ bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { time=localtime(&stat_block.st_mtime); constant=(time->tm_hour<<11)+(time->tm_min<<5)+(time->tm_sec/2); /* standard way. */ - fcb->Set_time(constant); + fcb.Set_time(constant); constant=((time->tm_year-80)<<9)+((time->tm_mon+1)<<5)+(time->tm_mday); - fcb->Set_date(constant); - fcb->Set_drive(drive +1); + fcb.Set_date(constant); + fcb.Set_drive(drive +1); return true; } -bool FCB_Close(void) -{ return true;} +bool DOS_FCBClose(Bit16u seg,Bit16u offset) +{ DOS_FCB fcb(seg,offset); + Bit8u drive; + char fullname[DOS_PATHLENGTH]; + if(!FCB_MakeName (&fcb, fullname, &drive)) return false; + if(!Drives[drive]->FileExists(fullname)) return false; + + return true;} -bool FCB_FindFirst(Bit16u seg,Bit16u offset) -{FCB* fcb = new FCB(seg,offset); - Bit8u drive; - Bitu i; - char fullname[DOS_PATHLENGTH]; - FCB_MakeName (fcb, fullname, &drive); - DTA_FindBlock * dtablock=(DTA_FindBlock *)Real2Host(dos.dta); - if(Drives[drive]->FindFirst(fullname,dtablock)==false) return false; +bool DOS_FCBFindFirst(Bit16u seg,Bit16u offset) +{ + DOS_FCB* fcb = new DOS_FCB(seg,offset); + Bit8u drive; + Bitu i; + char fullname[DOS_PATHLENGTH]; + FCB_MakeName (fcb, fullname, &drive); + DTA_FindBlock * dtablock=(DTA_FindBlock *)Real2Host(dos.dta); + if(Drives[drive]->FindFirst(fullname,dtablock)==false) return false; - char naam[8]; - char ext[3]; - char * point=strrchr(dtablock->name,'.'); - if(point==NULL|| *(point+1)=='\0') { - ext[0]=' '; - ext[1]=' '; - ext[2]=' '; - }else - {strcpy(ext,point+1); - Bitu i; - i=strlen(point+1); - while(i!=3) ext[i-1]=' '; - } + char naam[8]; + char ext[3]; + char * point=strrchr(dtablock->name,'.'); + if(point==NULL|| *(point+1)=='\0') { + ext[0]=' '; + ext[1]=' '; + ext[2]=' '; + }else{ + strcpy(ext,(point+1)); + i=strlen((point+1)); + while(i!=3) {ext[i]=' ';i++;} + } - if(point!=NULL) *point='\0'; + if(point!=NULL) *point='\0'; - strcpy (naam,dtablock->name); - i=strlen(dtablock->name); - while(i!=8) naam[i-1]=' '; - FCB* fcbout= new FCB((PhysPt)Real2Host(dos.dta)); - fcbout->Set_drive(drive +1); - fcbout->Set_filename(naam); - fcbout->Set_ext(ext); - return true; - } -bool FCB_FindNext(Bit16u seg,Bit16u offset) -{FCB* fcb = new FCB(seg,offset); + strcpy (naam,dtablock->name); + i=strlen(dtablock->name); + while(i!=8) {naam[i]=' '; i++;} + DOS_FCB* fcbout= new DOS_FCB((PhysPt)Real2Host(dos.dta)); + fcbout->Set_drive(drive +1); + fcbout->Set_filename(naam); + fcbout->Set_ext(ext); + return true; + +} +bool DOS_FCBFindNext(Bit16u seg,Bit16u offset) +{ + DOS_FCB* fcb = new DOS_FCB(seg,offset); Bit8u drive; Bitu i; char fullname[DOS_PATHLENGTH]; @@ -550,22 +555,22 @@ bool FCB_FindNext(Bit16u seg,Bit16u offset) char ext[3]; char * point=strrchr(dtablock->name,'.'); if(point==NULL|| *(point+1)=='\0') { - ext[0]=' '; - ext[1]=' '; - ext[2]=' '; - }else - {strcpy(ext,point+1); - Bitu i; - i=strlen(point+1); - while(i!=3) ext[i-1]=' '; + ext[0]=' '; + ext[1]=' '; + ext[2]=' '; + }else + { + strcpy(ext,point+1); + i=strlen(point+1); + while(i!=3) {ext[i]=' ';i++;} } if(point!=NULL) *point='\0'; strcpy (naam,dtablock->name); i=strlen(dtablock->name); - while(i!=8) naam[i-1]=' '; - FCB* fcbout= new FCB((PhysPt)Real2Host(dos.dta)); + while(i!=8) {naam[i]=' '; i++;} + DOS_FCB* fcbout= new DOS_FCB((PhysPt)Real2Host(dos.dta)); fcbout->Set_drive(drive +1); fcbout->Set_filename(naam); fcbout->Set_ext(ext); @@ -575,12 +580,10 @@ bool FCB_FindNext(Bit16u seg,Bit16u offset) #endif bool DOS_FileExists(char * name) { - Bit16u handle; - if (DOS_OpenFile(name,0,&handle)) { - DOS_CloseFile(handle); - return true; - } - return false; + + char fullname[DOS_PATHLENGTH];Bit8u drive; + if (!DOS_MakeName(name,fullname,&drive)) return false; + return Drives[drive]->FileExists(fullname); } diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index 9428e55e..b9632774 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -42,7 +42,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /G6 /MD /W3 /GX /O1 /Op /Ob2 /I "../include" /I "../src/platform/visualc" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FAs /FD /QxMi /bQipo /c +# ADD CPP /nologo /G6 /MD /W3 /GX /O1 /Op /Ob2 /I "../include" /I "../src/platform/visualc" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FAs /FR /FD /QxMi /bQipo /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe From 9ba9c24c334ab2c52c576c356e940e3d2f6b74eb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 6 Aug 2002 09:21:55 +0000 Subject: [PATCH 0035/4131] updated Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@112 --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index 15ed52ab..ec52db31 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,3 +4,5 @@ - 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 \ No newline at end of file From eb6f19bdf8d9c17ec57aacb3639007f836a84335 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 6 Aug 2002 12:47:36 +0000 Subject: [PATCH 0036/4131] changed fileexists Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@113 --- src/dos/drive_local.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 59171647..87e22bfb 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -230,7 +230,7 @@ bool localDrive::FileExists(const char* name) const { strcpy(newname,basedir); strcat(newname,name); CROSS_FILENAME(newname); - FILE* Temp=fopen(newname,"br"); + FILE* Temp=fopen(newname,"rb"); if(Temp==NULL) return false; fclose(Temp); return true; From 929b9ce3fa537ae7e8f7ee14314fdbfb5228c5f6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 6 Aug 2002 13:06:21 +0000 Subject: [PATCH 0037/4131] fixed date&time for weird files Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@114 --- src/dos/dos_files.cpp | 17 ++++++++++++----- src/dos/drive_local.cpp | 12 ++++++++---- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index c4936d7b..33e6e663 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -488,12 +488,19 @@ bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { constant=0x80; fcb.Set_record_size(constant); struct tm *time; - time=localtime(&stat_block.st_mtime); + if((time=localtime(&stat_block.st_mtime))!=0){ - constant=(time->tm_hour<<11)+(time->tm_min<<5)+(time->tm_sec/2); /* standard way. */ - fcb.Set_time(constant); - constant=((time->tm_year-80)<<9)+((time->tm_mon+1)<<5)+(time->tm_mday); - fcb.Set_date(constant); + constant=(time->tm_hour<<11)+(time->tm_min<<5)+(time->tm_sec/2); /* standard way. */ + fcb.Set_time(constant); + constant=((time->tm_year-80)<<9)+((time->tm_mon+1)<<5)+(time->tm_mday); + fcb.Set_date(constant); + } + else{ + constant=6; + fcb.Set_time(constant); + constant=4; + fcb.Set_date(constant); + } fcb.Set_drive(drive +1); return true; } diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 87e22bfb..670a1651 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -148,10 +148,14 @@ bool localDrive::FindNext(DTA_FindBlock * dta) { dta->attr=tempattr; dta->size=(Bit32u) stat_block.st_size; struct tm *time; - time=localtime(&stat_block.st_mtime); - - dta->time=(time->tm_hour<<11)+(time->tm_min<<5)+(time->tm_sec/2); /* standard way. */ - dta->date=((time->tm_year-80)<<9)+((time->tm_mon+1)<<5)+(time->tm_mday); + if((time=localtime(&stat_block.st_mtime))!=0){ + + dta->time=(time->tm_hour<<11)+(time->tm_min<<5)+(time->tm_sec/2); /* standard way. */ + dta->date=((time->tm_year-80)<<9)+((time->tm_mon+1)<<5)+(time->tm_mday); + }else { + dta->time=6; + dta->date=4; + } return true; } From 5473800c3258375eefcbc01673b812914fceeb11 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 6 Aug 2002 14:21:36 +0000 Subject: [PATCH 0038/4131] fixed/changed permissions for newdirs to rwx------ Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@115 --- src/dos/drive_local.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 670a1651..5b8882f0 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -182,7 +182,7 @@ bool localDrive::MakeDir(char * dir) { #if defined (WIN32) /* MS Visual C++ */ int temp=mkdir(newdir); #else - int temp=mkdir(newdir,0); + int temp=mkdir(newdir,0700); #endif return (temp==0); } From 6931e8fa410da4cfeb7a5e4fbcb95b8ad9541853 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 7 Aug 2002 10:23:35 +0000 Subject: [PATCH 0039/4131] fixed Localfile::write to truncate the file when zero data is written Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@116 --- src/dos/drive_local.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 5b8882f0..a24ad9cc 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -265,10 +265,15 @@ bool localFile::Read(Bit8u * data,Bit16u * size) { }; bool localFile::Write(Bit8u * data,Bit16u * size) { - *size=fwrite(data,1,*size,fhandle); + if(*size==0){ + return (!ftruncate(fileno(fhandle),ftell(fhandle))); + } + else + { + *size=fwrite(data,1,*size,fhandle); return true; + } } - bool localFile::Seek(Bit32u * pos,Bit32u type) { int seektype; switch (type) { From 9e48fbd6b581ec051a72f672441b695a154eca0f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 7 Aug 2002 10:25:30 +0000 Subject: [PATCH 0040/4131] added a define for ftruncate so it works under win32 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@117 --- include/cross.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/cross.h b/include/cross.h index 20d2d5a9..2dc3d2cf 100644 --- a/include/cross.h +++ b/include/cross.h @@ -46,7 +46,9 @@ #define CROSS_NONE 0 #define CROSS_FILE 1 #define CROSS_DIR 2 - +#if defined (_MSC_VER) +#define ftruncate(blah,blah2) chsize(blah,blah2) +#endif extern const char * dosbox_datadir; From 2729764d1f477b3297893810092e7eeabb7dc949 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 7 Aug 2002 18:16:15 +0000 Subject: [PATCH 0041/4131] Small index with attribute index flipflop not being reset on reads Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@118 --- src/hardware/vga_attr.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 4b0473f9..3d4c6b9d 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -129,6 +129,7 @@ void write_p3c0(Bit32u port,Bit8u val) { } Bit8u read_p3c1(Bit32u port) { + vga.internal.attrindex=false; switch (attr(index)) { /* Palette */ case 0x00: case 0x01: case 0x02: case 0x03: From 2f5c031805672a53727aaabda081dae9d5f90d9f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 8 Aug 2002 08:56:58 +0000 Subject: [PATCH 0042/4131] Pel Mask not being saved Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@119 --- src/hardware/vga_dac.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index b161c86e..e6a5dcd1 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -55,6 +55,12 @@ enum {DAC_READ,DAC_WRITE}; static void write_p3c6(Bit32u port,Bit8u val) { if (val!=0xff) LOG_ERROR("VGA:Pel Mask not 0xff"); + vga.dac.pel_mask=val; +} + + +static Bit8u read_p3c6(Bit32u port) { + return vga.dac.pel_mask; } @@ -151,6 +157,7 @@ void VGA_SetupDAC(void) { /* Setup the DAC IO port Handlers */ IO_RegisterWriteHandler(0x3c6,write_p3c6,"PEL Mask"); + IO_RegisterReadHandler(0x3c6,read_p3c6,"PEL Mask"); IO_RegisterWriteHandler(0x3c7,write_p3c7,"PEL Read Mode"); IO_RegisterWriteHandler(0x3c8,write_p3c8,"PEL Write Mode"); IO_RegisterWriteHandler(0x3c9,write_p3c9,"PEL Data"); From bed0f7e8a68d5076abc1304fd8fc44e883d968c5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 8 Aug 2002 08:59:14 +0000 Subject: [PATCH 0043/4131] Crtc startup and changed some entries to use vga_resize. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@120 --- src/hardware/vga_crtc.cpp | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 99f1ac19..020866c9 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -28,6 +28,11 @@ void write_p3d4(Bit32u port,Bit8u val) { crtc(index)=val; } +Bit8u read_p3d4(Bit32u port) { + return crtc(index); +} + + void write_p3d5(Bit32u port,Bit8u val) { switch(crtc(index)) { case 0x00: /* Horizontal Total Register */ @@ -37,7 +42,7 @@ void write_p3d5(Bit32u port,Bit8u val) { case 0x01: /* Horizontal Display End Register */ crtc(horizontal_display_end)=val; vga.config.hdisplayend=val+1; - VGA_FindSettings(); + VGA_StartResize(); /* 0-7 Number of Character Clocks Displayed -1 */ break; case 0x02: /* Start Horizontal Blanking Register */ @@ -78,8 +83,8 @@ void write_p3d5(Bit32u port,Bit8u val) { break; case 0x07: /* Overflow Register */ crtc(overflow)=val; - vga.config.vdisplayend=(vga.config.vdisplayend&0xFF)|((val&2)<<7)|((val&64)<<2); - VGA_FindSettings(); + vga.config.vdisplayend=(vga.config.vdisplayend&0xFF)|(((val>>1) & 1)<<8)|(((val>>6) & 1)<<9); + VGA_StartResize(); /* 0 Bit 8 of Vertical Total (3d4h index 6) 1 Bit 8 of Vertical Display End (3d4h index 12h) @@ -108,7 +113,7 @@ void write_p3d5(Bit32u port,Bit8u val) { crtc(maximum_scan_line)=val; vga.config.vline_double=(val & 128)>1; vga.config.vline_height=(val & 0xf); - VGA_FindSettings(); + VGA_StartResize(); /* 0-4 Number of scan lines in a character row -1. In graphics modes this is the number of times (-1) the line is displayed before passing on to @@ -183,7 +188,7 @@ void write_p3d5(Bit32u port,Bit8u val) { case 0x12: /* Vertical Display End Register */ crtc(vertical_display_end)=val; vga.config.vdisplayend=(vga.config.vdisplayend & 0x300)|val; - VGA_FindSettings(); + VGA_StartResize(); /* 0-7 Lower 8 bits of Vertical Display End. The display ends when the line counter reaches this value. Bit 8 is found in 3d4h index 7 bit 1. @@ -193,7 +198,7 @@ void write_p3d5(Bit32u port,Bit8u val) { case 0x13: /* Offset register */ crtc(offset)=val; vga.config.scan_len=val; - VGA_FindSettings(); + VGA_StartResize(); /* 0-7 Number of bytes in a scanline / K. Where K is 2 for byte mode, 4 for word mode and 8 for Double Word mode. @@ -317,16 +322,4 @@ Bit8u read_p3d5(Bit32u port) { -void VGA_SetupCRTC(void) { - IO_RegisterWriteHandler(0x3d4,write_p3d4,"VGA:CRTC Index Select"); - IO_RegisterWriteHandler(0x3d5,write_p3d5,"VGA:CRTC Data Register"); - IO_RegisterReadHandler(0x3d5,read_p3d5,"VGA:CRTC Data Register"); - -// IO_RegisterWriteHandler(0x3b4,write_p3d4,"VGA:CRTC Index Select"); -// IO_RegisterWriteHandler(0x3b5,write_p3d5,"VGA:CRTC Data Register"); -// IO_RegisterReadHandler(0x3b5,read_p3d5,"VGA:CRTC Data Register"); - - - -} From 882e4752666e48b3b910340fbaafa578e51dae56 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 8 Aug 2002 09:45:04 +0000 Subject: [PATCH 0044/4131] fix for mono input status, added mono/color mode register select. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@121 --- src/hardware/vga_misc.cpp | 65 +++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index c1d6f19e..3ca14fd7 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -24,7 +24,16 @@ static Bit8u flip=0; static Bit32u keep_vretrace; static bool keeping=false; -static Bit8u p3c2data; +static Bit8u p3c2data=0; + + + + +void write_p3d4(Bit32u port,Bit8u val); +Bit8u read_p3d4(Bit32u port); +void write_p3d5(Bit32u port,Bit8u val); +Bit8u read_p3d5(Bit32u port); + static Bit8u read_p3da(Bit32u port) { vga.internal.attrindex=false; @@ -45,26 +54,70 @@ static Bit8u read_p3da(Bit32u port) { if (flip>5) return 1; return 0; } -}; + /* + 0 Either Vertical or Horizontal Retrace active if set + 3 Vertical Retrace in progress if set + */ +} static void write_p3d8(Bit32u port,Bit8u val) { - return; + /* + 3 Vertical Sync Select. If set Vertical Sync to the monitor is the + logical OR of the vertical sync and the vertical display enable. + */ } static void write_p3c2(Bit32u port,Bit8u val) { p3c2data=val; + if (val & 1) { + S_Warn("Color Mode %X",val); + IO_RegisterWriteHandler(0x3d4,write_p3d4,"VGA:CRTC Index Select"); + IO_RegisterReadHandler(0x3d4,read_p3d4,"VGA:CRTC Index Select"); + IO_RegisterWriteHandler(0x3d5,write_p3d5,"VGA:CRTC Data Register"); + IO_RegisterReadHandler(0x3d5,read_p3d5,"VGA:CRTC Data Register"); + IO_FreeWriteHandler(0x3b4); + IO_FreeReadHandler(0x3b4); + IO_FreeWriteHandler(0x3b5); + IO_FreeReadHandler(0x3b5); + + } else { + S_Warn("Mono Mode %X",val); + IO_RegisterWriteHandler(0x3b4,write_p3d4,"VGA:CRTC Index Select"); + IO_RegisterReadHandler(0x3b4,read_p3d4,"VGA:CRTC Index Select"); + IO_RegisterWriteHandler(0x3b5,write_p3d5,"VGA:CRTC Data Register"); + IO_RegisterReadHandler(0x3b5,read_p3d5,"VGA:CRTC Data Register"); + IO_FreeWriteHandler(0x3d4); + IO_FreeReadHandler(0x3d4); + IO_FreeWriteHandler(0x3d5); + IO_FreeReadHandler(0x3d5); + } + /* + 0 If set Color Emulation. Base Address=3Dxh else Mono Emulation. Base Address=3Bxh. + 2-3 Clock Select. 0: 25MHz, 1: 28MHz + 5 When in Odd/Even modes Select High 64k bank if set + 6 Horizontal Sync Polarity. Negative if set + 7 Vertical Sync Polarity. Negative if set + Bit 6-7 indicates the number of lines on the display: + 1: 400, 2: 350, 3: 480 + Note: Set to all zero on a hardware reset. + Note: This register can be read from port 3CCh. + */ } -static Bit8u read_p3c2(Bit32u port) { + + +static Bit8u read_p3cc(Bit32u port) { return p3c2data; } void VGA_SetupMisc(void) { IO_RegisterReadHandler(0x3da,read_p3da,"VGA Input Status 1"); -// IO_RegisterWriteHandler(0x3d8,write_p3d8,"VGA Mode Control"); + IO_RegisterReadHandler(0x3ba,read_p3da,"VGA Input Status 1"); + + IO_RegisterWriteHandler(0x3d8,write_p3d8,"VGA Feature Control Register"); IO_RegisterWriteHandler(0x3c2,write_p3c2,"VGA Misc Output"); - IO_RegisterReadHandler(0x3c2,read_p3c2,"VGA Misc Output"); + IO_RegisterReadHandler(0x3cc,read_p3cc,"VGA Misc Output"); } From 3023a8db889fb99209664ab8534a416c792742bf Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 8 Aug 2002 09:46:07 +0000 Subject: [PATCH 0045/4131] 2 color cga mode entries added Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@122 --- src/hardware/vga.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/hardware/vga.h b/src/hardware/vga.h index bd2985a1..0d3d7c53 100644 --- a/src/hardware/vga.h +++ b/src/hardware/vga.h @@ -51,6 +51,7 @@ typedef struct { bool vline_double; Bit8u vline_height; + bool pixel_double; /* Pixel Scrolling */ Bit8u pel_panning; /* Amount of pixels to skip when starting horizontal line */ Bit8u hlines_skip; @@ -211,6 +212,7 @@ void VGA_DrawGFX256_Fast(Bit8u * bitdata,Bitu next_line); void VGA_DrawGFX256_Full(Bit8u * bitdata,Bitu next_line); void VGA_DrawGFX16_Full(Bit8u * bitdata,Bitu next_line); void VGA_DrawGFX4_Full(Bit8u * bitdata,Bitu next_line); +void VGA_DrawGFX2_Full(Bit8u * bitdata,Bitu next_line); /* The Different Memory Read/Write Handlers */ Bit8u VGA_NormalReadHandler(Bit32u start); void VGA_NormalWriteHandler(Bit32u start,Bit8u val); @@ -251,5 +253,12 @@ extern Bit32u ExpandTable[256]; extern Bit32u FillTable[16]; extern Bit32u CGAWriteTable[256]; +#ifdef DEBUG_VGA +#define LOG_VGA LOG_DEBUG +#else +#define LOG_VGA +#endif + + #endif From b73647f3085bfbdfe7c68f1bd44b6ca4ecaf6e0b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 8 Aug 2002 09:46:47 +0000 Subject: [PATCH 0046/4131] 2 color mode cga detection. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@123 --- src/hardware/vga_seq.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index ce5e0cfd..cbb85349 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -37,6 +37,8 @@ void write_p3c5(Bit32u port,Bit8u val) { break; case 1: /* Clocking Mode */ seq(clocking_mode)=val; + vga.config.pixel_double=(val & 8)>0; + VGA_FindSettings(); /* TODO Figure this out :) 0 If set character clocks are 8 dots wide, else 9. 2 If set loads video serializers every other character From a17e267b624c955398e0ee9a87b00c8b4f681446 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 8 Aug 2002 09:55:49 +0000 Subject: [PATCH 0047/4131] added 2 color cga and some pitch fixes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@124 --- src/hardware/vga_draw.cpp | 67 ++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 22 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index c8f859f9..bc86be2e 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -23,6 +23,11 @@ /* This Should draw a complete 16 colour screen */ +void VGA_Render_GFX_2(Bit8u * * data) { + *data=vga.buffer; + VGA_DrawGFX2_Full(vga.buffer,vga.draw.width); + vga.config.retrace=true; +} void VGA_Render_GFX_4(Bit8u * * data) { *data=vga.buffer; @@ -51,11 +56,38 @@ void VGA_Render_TEXT_16(Bit8u * * data) { vga.config.retrace=true; } +void VGA_DrawGFX2_Full(Bit8u * bitdata,Bitu pitch) { + Bit8u * reader=real_host(0xB800,0); + Bit8u * draw; + for (Bitu y=0;y>3;x++) { + Bit8u val=*(tempread++); + *(draw+0)=(val>>7)&1; + *(draw+1)=(val>>6)&1; + *(draw+2)=(val>>5)&1; + *(draw+3)=(val>>4)&1; + *(draw+4)=(val>>3)&1; + *(draw+5)=(val>>2)&1; + *(draw+6)=(val>>1)&1; + *(draw+7)=(val>>0)&1; + draw+=8; + } + bitdata+=pitch; + }; + vga.config.retrace=true; +} -void VGA_DrawGFX4_Full(Bit8u * bitdata,Bitu next_line) { - //TODO use vga memory handler +void VGA_DrawGFX4_Full(Bit8u * bitdata,Bitu pitch) { Bit8u * reader=real_host(0xB800,0); Bit8u * draw; for (Bitu y=0;y>2;x++) { Bit8u val=*(tempread++); -/* - *(draw+0)=(val>>6)&3; - *(draw+1)=(val>>4)&3; - *(draw+2)=(val>>2)&3; - *(draw+3)=(val)&3; - draw+=4; -*/ *(Bit32u *)draw=CGAWriteTable[val]; draw+=4; } - //TODO use scanline length and dword mode crap - bitdata+=next_line; + bitdata+=pitch; }; vga.config.retrace=true; } -void VGA_DrawGFX16_Full(Bit8u * bitdata,Bitu next_line) { +/* Draw the screen using the lookup buffer */ +//TODO include split screen or something +void VGA_DrawGFX16_Fast(Bit8u * bitdata,Bitu next_line) { Bit8u * reader=&vga.buffer[vga.config.display_start*8+vga.config.pel_panning]; for (Bitu y=0;y>2;x++) { @@ -108,27 +133,25 @@ void VGA_DrawGFX256_Full(Bit8u * bitdata,Bitu next_line) { } xreader++; } - //TODO use scanline length and dword mode crap yreader+=vga.config.scan_len*2; bitdata+=next_line; }; vga.config.retrace=true; }; -void VGA_DrawGFX256_Fast(Bit8u * bitdata,Bitu next_line) { +void VGA_DrawGFX256_Fast(Bit8u * bitdata,Bitu pitch) { /* For now just copy 64 kb of memory with pitch support */ Bit8u * reader=memory+0xa0000; for (Bitu y=0;y=vga.draw.width) return; if ((vga.draw.cursor_row*16)>=vga.draw.height) return; - Bit8u * cursor_draw=bitdata+(vga.draw.cursor_row*16+15)*vga.draw.width+vga.draw.cursor_col*8; + Bit8u * cursor_draw=bitdata+(vga.draw.cursor_row*16+15)*pitch+vga.draw.cursor_col*8; if (vga.draw.cursor_count>8) { for (Bit8u loop=0;loop<8;loop++) *cursor_draw++=15; } From d309cb94a4775dac8128c8a9a0b2cef0ecb3b313 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 8 Aug 2002 09:58:05 +0000 Subject: [PATCH 0048/4131] missed some debug info Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@125 --- src/hardware/vga_misc.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 3ca14fd7..e2fa92e3 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -26,15 +26,11 @@ static Bit32u keep_vretrace; static bool keeping=false; static Bit8u p3c2data=0; - - - void write_p3d4(Bit32u port,Bit8u val); Bit8u read_p3d4(Bit32u port); void write_p3d5(Bit32u port,Bit8u val); Bit8u read_p3d5(Bit32u port); - static Bit8u read_p3da(Bit32u port) { vga.internal.attrindex=false; if (vga.config.retrace) { @@ -71,7 +67,6 @@ static void write_p3d8(Bit32u port,Bit8u val) { static void write_p3c2(Bit32u port,Bit8u val) { p3c2data=val; if (val & 1) { - S_Warn("Color Mode %X",val); IO_RegisterWriteHandler(0x3d4,write_p3d4,"VGA:CRTC Index Select"); IO_RegisterReadHandler(0x3d4,read_p3d4,"VGA:CRTC Index Select"); IO_RegisterWriteHandler(0x3d5,write_p3d5,"VGA:CRTC Data Register"); @@ -82,7 +77,6 @@ static void write_p3c2(Bit32u port,Bit8u val) { IO_FreeReadHandler(0x3b5); } else { - S_Warn("Mono Mode %X",val); IO_RegisterWriteHandler(0x3b4,write_p3d4,"VGA:CRTC Index Select"); IO_RegisterReadHandler(0x3b4,read_p3d4,"VGA:CRTC Index Select"); IO_RegisterWriteHandler(0x3b5,write_p3d5,"VGA:CRTC Data Register"); From 092483b2f98919070443c22362d27449f90372e6 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 8 Aug 2002 15:51:27 +0000 Subject: [PATCH 0049/4131] more compatible wildcmp-function Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@126 --- src/misc/support.cpp | 64 +++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/src/misc/support.cpp b/src/misc/support.cpp index b4f04628..9d9623bb 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -82,39 +82,49 @@ char *trim(char *str) { return ltrim(str); } -bool wildcmp(char *wild, char *string) { - char *cp, *mp; - while ((*string) && (*wild != '*')) { - if ((toupper(*wild) != toupper(*string)) && (*wild != '?')) { - - return false; - } - wild++; - string++; - } - - while (*string) { - if (*wild == '*') { - if (!*++wild) { - return true; +bool wildcmp(char *wild, char *string) +{ + // special case - Everything goes through + if (strcmp(wild,"*")==0) return true; + + while (*wild) { + if (*wild=='*') { + // Any other chars after that ? + if ((wild[1]!=0) && (wild[1]!='.')) { + // search string + while ((*string) && (*string!='.')) { + // thats the char ? then exit + if (toupper(*string)==toupper(wild[1])) break; + string++; + }; + + } else { + // skip to extension or end + while (*string && (*string!='.')) string++; } - mp = wild; - cp = string+1; - } else if ((toupper(*wild) == toupper(*string)) || (*wild == '?')) { + wild++; + + } else if (*string=='.') { + // only valid : '?' & '*' + while (*wild && (*wild!='.')) { + if ((*wild!='?') && (*wild!='*')) return false; + wild++; + } + if (*wild) wild++; + string++; + + } else if ((*wild!='?') && (toupper(*string)!=toupper(*wild))) { + // no match + return false; + + } else { wild++; string++; - } else { - wild = mp; - string = cp++; } } - - while (*wild == '*') { - wild++; - } - return !*wild; -} + return ((*string==0) && (*wild==0)); +}; bool ScanCMDBool(char * cmd,char * check) { char * scan=cmd;size_t c_len=strlen(check); From 1bf741280bc83033908c5371e5e955d8aac7e906 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 8 Aug 2002 15:52:25 +0000 Subject: [PATCH 0050/4131] command >12 chars fix Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@127 --- src/dos/dos_files.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 33e6e663..bcd4c4ff 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -48,7 +48,7 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { Bit32u r=0;Bit32u w=0;Bit32u namestart=0; bool hasdrive=false; *drive=CurrentDrive; - char tempdir[DOS_NAMELENGTH]; + char tempdir[128]; //TODO Maybe check for illegal characters while (name[r]!=0 && (r Date: Thu, 8 Aug 2002 16:18:43 +0000 Subject: [PATCH 0051/4131] vga 2 color mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@128 --- src/hardware/vga.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 1d866fcb..2aa89f2c 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -39,6 +39,7 @@ Bit32u FillTable[16]={ static PageEntry VGA_PageEntry; +void VGA_Render_GFX_2(Bit8u * * data); void VGA_Render_GFX_4(Bit8u * * data); void VGA_Render_GFX_16(Bit8u * * data); void VGA_Render_GFX_256C(Bit8u * * data); @@ -67,7 +68,8 @@ void VGA_FindSettings(void) { } else if (vga.config.cga_enabled) { /* 4 color cga */ //TODO Detect hercules modes, probably set them up in bios too - vga.mode=GFX_4; + if (vga.config.pixel_double) vga.mode=GFX_4; + else vga.mode=GFX_2; // VGA_PageEntry.base=0xB8000; // VGA_PageEntry.handler.read=VGA_GFX_4_ReadHandler; // VGA_PageEntry.handler.write=VGA_GFX_4_WriteHandler; @@ -119,6 +121,12 @@ static void VGA_DoResize(void) { pitch=width; renderer=&VGA_Render_GFX_4; break; + case GFX_2: + width<<=3; + height<<=1; + pitch=width; + renderer=&VGA_Render_GFX_2; + break; case TEXT_16: /* probably a 16-color text mode, got to detect mono mode somehow */ width<<=3; /* 8 bit wide text font */ @@ -144,14 +152,11 @@ void VGA_StartResize(void) { } - - void VGA_Init() { vga.draw.resizing=false; VGA_SetupMemory(); VGA_SetupMisc(); VGA_SetupDAC(); - VGA_SetupCRTC(); VGA_SetupGFX(); VGA_SetupSEQ(); VGA_SetupAttr(); From 7109c7df98fb240fff28b7122192808839236f5a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 9 Aug 2002 10:40:43 +0000 Subject: [PATCH 0052/4131] added fcb_parsename Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@129 --- include/dos_inc.h | 1 + src/dos/dos.cpp | 33 +++++++------ src/dos/dos_files.cpp | 109 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 120 insertions(+), 23 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index e3e79cf8..353ce7c0 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -201,6 +201,7 @@ bool DOS_FCBOpen(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 FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u *change); /* Extra DOS Interrupts */ void DOS_SetupMisc(void); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 1f207caf..b99d2171 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -178,24 +178,27 @@ static Bitu DOS_21Handler(void) { }else{ reg_al=0xff; } - LOG_DEBUG("DOS:0x0f FCB-fileclose used"); + LOG_DEBUG("DOS:0x10 FCB-fileclose used"); break; + case 0x11: /* Find First Matching File using FCB */ if(DOS_FCBFindFirst(Segs[ds].value,reg_dx)){ reg_al=0; }else{ reg_al=0xff; } - LOG_DEBUG("DOS:0x0f FCB-FindFirst used"); + LOG_DEBUG("DOS:0x11 FCB-FindFirst used"); break; + case 0x12: /* Find Next Matching File using FCB */ if(DOS_FCBFindNext(Segs[ds].value,reg_dx)){ reg_al=0; }else{ reg_al=0xff; } - LOG_DEBUG("DOS:0x0f FCB-FindNext used"); + LOG_DEBUG("DOS:0x12 FCB-FindNext used"); break; + case 0x13: /* Delete File using FCB */ case 0x14: /* Sequential read from FCB */ case 0x15: /* Sequential write to FCB */ @@ -211,21 +214,17 @@ static Bitu DOS_21Handler(void) { reg_al=0xff; /* FCB Calls FAIL */ //CALLBACK_SCF(true); not needed. break; + case 0x29: /* Parse filename into FCB */ -//TODO Give errors for unsupported functions - { - MEM_StrCopy(real_phys(Segs[ds].value,reg_si),name1,DOSNAMEBUF); -/* only detect the call program use to detect the existence of a harddisk */ - if ((strlen((char *)name1)==2) && (name1[1]==':')) { - Bit8u drive=toupper(name1[0])-'A'; - if (Drives[drive]) reg_al=0; - else reg_al=0xff; - break; - } - LOG_DEBUG("DOS:29:FCB Parse Filename:%s",name1); - }; - reg_al=0xff; /* FCB Calls FAIL */ - break; + { Bit8u difference; + char string[1024]; + MEM_StrCopy(Real2Phys(RealMake(Segs[ds].value,reg_si)) ,string,1024); + reg_al=FCB_Parsename(Segs[es].value,reg_di,reg_al ,string, &difference); + reg_di+=difference; + } + LOG_DEBUG("DOS:29:FCB Parse Filename result:%d",reg_al); + break; + case 0x18: /* NULL Function for CP/M compatibility or Extended rename FCB */ case 0x1d: /* NULL Function for CP/M compatibility or Extended rename FCB */ case 0x1e: /* NULL Function for CP/M compatibility or Extended rename FCB */ diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index bcd4c4ff..1f28624d 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -471,8 +471,96 @@ static bool FCB_MakeName (DOS_FCB* fcb, char* outname, Bit8u* outdrive){ strcat(naam,ext); return DOS_MakeName(naam,outname, outdrive); } +#define FCB_SEP ":.;,=+" +#define ILLEGAL ":.;,=+ \t/\"[]<>|\0x0\0x1\0x2\0x3\0x4\0x5\0x6\0x7\0x8\0x9\0xA\0xB\0xC\0xD\0xE\0xF\0x10\0x11\0x12\0x13\0x14\0x15\0x16\0x17\0x18x\0x19\0x1A\0x1B\0x1C\0x1D\0x1E\0x1F" + +static bool isvalid(const char* in){ + char ill[]=ILLEGAL; + char a[2]; + a[0]=*in;a[1]='\0'; + if(strcspn(a,ill)==0) return false; + return true; + +} + +static void vullen (char* veld,char* pveld){ + for(Bitu i=(pveld-veld);i'Z') | (drive<'A') ) { + *change=string-backup; + return 0xFF; + } + fcb.Set_drive(drive-'A'+1); + string+=2; + } + //startparsing + char* pnaam=naam; + while(isvalid(string)==true) { + if(*string=='*'){ + vullen(naam,pnaam); //fill with ???? + string++; + retwaarde=1; + break; + } + + *pnaam=*string; + pnaam++; + string++; + } + fcb.Set_filename(naam); + if((*string=='.')==false) { + *change=string-backup; + return retwaarde; + } + //extension exist + string++; + char* pext=ext; + while(isvalid(string)==true) { + if(*string=='*'){ + vullen(ext,pext); //fill with ???? + string++; + retwaarde=1; + break; + } + + *pext=*string; + pext++; + string++; + } + fcb.Set_ext(ext); + *change=string-backup; + return retwaarde; + +} bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); Bit8u drive; @@ -487,6 +575,7 @@ bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { fcb.Set_current_block(constant); constant=0x80; fcb.Set_record_size(constant); + struct tm *time; if((time=localtime(&stat_block.st_mtime))!=0){ @@ -522,10 +611,13 @@ bool DOS_FCBFindFirst(Bit16u seg,Bit16u offset) char fullname[DOS_PATHLENGTH]; FCB_MakeName (fcb, fullname, &drive); DTA_FindBlock * dtablock=(DTA_FindBlock *)Real2Host(dos.dta); + dtablock->sattr=DOS_ATTR_ARCHIVE; + dtablock->sdrive=drive; + if(Drives[drive]->FindFirst(fullname,dtablock)==false) return false; - char naam[8]; - char ext[3]; + char naam[9]; + char ext[4]; char * point=strrchr(dtablock->name,'.'); if(point==NULL|| *(point+1)=='\0') { ext[0]=' '; @@ -542,7 +634,8 @@ bool DOS_FCBFindFirst(Bit16u seg,Bit16u offset) strcpy (naam,dtablock->name); i=strlen(dtablock->name); while(i!=8) {naam[i]=' '; i++;} - DOS_FCB* fcbout= new DOS_FCB((PhysPt)Real2Host(dos.dta)); + delete fcb; + DOS_FCB* fcbout= new DOS_FCB((PhysPt)Real2Phys(dos.dta)); fcbout->Set_drive(drive +1); fcbout->Set_filename(naam); fcbout->Set_ext(ext); @@ -557,9 +650,12 @@ bool DOS_FCBFindNext(Bit16u seg,Bit16u offset) char fullname[DOS_PATHLENGTH]; FCB_MakeName (fcb, fullname, &drive); DTA_FindBlock * dtablock=(DTA_FindBlock *)Real2Host(dos.dta); + dtablock->sattr=DOS_ATTR_ARCHIVE; + dtablock->sdrive=drive; + if(Drives[dtablock->sdrive]->FindNext(dtablock)==false) return false; - char naam[8]; - char ext[3]; + char naam[9]; + char ext[4]; char * point=strrchr(dtablock->name,'.'); if(point==NULL|| *(point+1)=='\0') { ext[0]=' '; @@ -577,7 +673,8 @@ bool DOS_FCBFindNext(Bit16u seg,Bit16u offset) strcpy (naam,dtablock->name); i=strlen(dtablock->name); while(i!=8) {naam[i]=' '; i++;} - DOS_FCB* fcbout= new DOS_FCB((PhysPt)Real2Host(dos.dta)); + delete fcb; + DOS_FCB* fcbout= new DOS_FCB(Real2Phys(dos.dta)); fcbout->Set_drive(drive +1); fcbout->Set_filename(naam); fcbout->Set_ext(ext); From c1488b69836ca55574ab2ad22e8ae8dfec86c9b2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 9 Aug 2002 11:19:07 +0000 Subject: [PATCH 0053/4131] added more debug information and check if drive exists Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@130 --- src/dos/dos.cpp | 12 ++++++------ src/dos/dos_files.cpp | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index b99d2171..9827c072 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -169,7 +169,7 @@ static Bitu DOS_21Handler(void) { }else{ reg_al=0xff; } - LOG_DEBUG("DOS:0x0f FCB-fileopen used"); + LOG_DEBUG("DOS:0x0f FCB-fileopen used, result:al=%d",reg_al); break; case 0x10: /* Close File using FCB */ @@ -178,7 +178,7 @@ static Bitu DOS_21Handler(void) { }else{ reg_al=0xff; } - LOG_DEBUG("DOS:0x10 FCB-fileclose used"); + LOG_DEBUG("DOS:0x10 FCB-fileclose used, result:al=%d",reg_al); break; case 0x11: /* Find First Matching File using FCB */ @@ -187,7 +187,7 @@ static Bitu DOS_21Handler(void) { }else{ reg_al=0xff; } - LOG_DEBUG("DOS:0x11 FCB-FindFirst used"); + LOG_DEBUG("DOS:0x11 FCB-FindFirst used, result:al=%d",reg_al); break; case 0x12: /* Find Next Matching File using FCB */ @@ -196,7 +196,7 @@ static Bitu DOS_21Handler(void) { }else{ reg_al=0xff; } - LOG_DEBUG("DOS:0x12 FCB-FindNext used"); + LOG_DEBUG("DOS:0x12 FCB-FindNext used, result:al=%d",reg_al); break; case 0x13: /* Delete File using FCB */ @@ -222,7 +222,7 @@ static Bitu DOS_21Handler(void) { reg_al=FCB_Parsename(Segs[es].value,reg_di,reg_al ,string, &difference); reg_di+=difference; } - LOG_DEBUG("DOS:29:FCB Parse Filename result:%d",reg_al); + LOG_DEBUG("DOS:29:FCB Parse Filename, result:al=%d",reg_al); break; case 0x18: /* NULL Function for CP/M compatibility or Extended rename FCB */ @@ -237,9 +237,9 @@ static Bitu DOS_21Handler(void) { reg_al=DOS_GetDefaultDrive(); break; case 0x1a: /* Set Disk Transfer Area Address */ -//TODO find out what a DTA does dos.dta=RealMake(Segs[ds].value,reg_dx); break; + case 0x1c: /* Get allocation info for specific drive */ LOG_DEBUG("DOS: Allocation Info call not supported correctly"); SetSegment_16(ds,0xf000); diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 1f28624d..22a18aab 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -513,7 +513,7 @@ Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u * while((*string==' ')||(*string=='\t')) string++; if( *(string+1)==':') { Bit8u drive=toupper(*string); - if( (drive>'Z') | (drive<'A') ) { + if( (drive>'Z') | (drive<'A') | (Drives[drive-'A']==NULL)) { *change=string-backup; return 0xFF; } From 596f88bed8566ff67ab5cbde66cc59d5b78724ab Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 9 Aug 2002 13:18:30 +0000 Subject: [PATCH 0054/4131] added pack statements for gcc Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@131 --- include/dos_inc.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 353ce7c0..e644b505 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -22,8 +22,9 @@ #include #include +#if defined (_MSC_VER) #pragma pack(1) - +#endif# struct CommandTail{ Bit8u count; /* number of bytes returned */ char buffer[127]; /* the buffer itself */ @@ -94,9 +95,13 @@ struct FCB { Bit8u reserved[8]; Bit8u current_relative_record_number; //open doesn't set this Bit32u rel_record; //open does not handle this -}; - +} +#if defined (_MSC_VER) +; #pragma pack() +#else +__attribute__ ((packed)); +#endif struct DOS_Date { Bit16u year; From 9e353cf2d7d7d5787694cd24608dd2cbc049eb86 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 9 Aug 2002 13:24:01 +0000 Subject: [PATCH 0055/4131] added pack statements for gcc Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@132 --- include/dos_inc.h | 2 +- include/dos_system.h | 13 ++++++++++--- src/dos/dos_execute.cpp | 10 ++++++++-- src/dos/dos_tables.cpp | 10 ++++++++-- src/ints/int10_misc.cpp | 10 ++++++++-- 5 files changed, 35 insertions(+), 10 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index e644b505..f042f781 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -24,7 +24,7 @@ #if defined (_MSC_VER) #pragma pack(1) -#endif# +#endif struct CommandTail{ Bit8u count; /* number of bytes returned */ char buffer[127]; /* the buffer itself */ diff --git a/include/dos_system.h b/include/dos_system.h index 02828782..0b240d03 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -35,7 +35,9 @@ enum { DOS_ATTR_ARCHIVE= 0x20 }; -#pragma pack (1) +#if defined (_MSC_VER) +#pragma pack(1) +#endif struct DTA_FindBlock { Bit8u sdrive; /* The Drive the search is taking place */ Bit16u sattr; /* The attributes that need to be found */ @@ -45,8 +47,13 @@ struct DTA_FindBlock { Bit16u date; Bit32u size; char name[DOS_NAMELENGTH]; -}; -#pragma pack () +} +#if defined (_MSC_VER) +; +#pragma pack() +#else +__attribute__ ((packed)); +#endif class DOS_File { public: diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index fd3fb54b..ee315240 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -21,8 +21,9 @@ #include "mem.h" #include "dos_inc.h" #include "cpu.h" +#if defined (_MSC_VER) #pragma pack(1) - +#endif struct EXE_Header { @@ -40,8 +41,13 @@ struct EXE_Header { Bit16u initCS; Bit16u reloctable; Bit16u overlay; -}; +} +#if defined (_MSC_VER) +; #pragma pack() +#else +__attribute__ ((packed)); +#endif #define MAGIC1 0x5a4d #define MAGIC2 0x4d5a diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index a2b2fced..2318655d 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -20,13 +20,19 @@ #include "mem.h" #include "dos_inc.h" +#if defined (_MSC_VER) #pragma pack(1) - +#endif struct DOS_TableCase { Bit16u size; Bit8u chars[256]; -}; +} +#if defined (_MSC_VER) +; #pragma pack() +#else +__attribute__ ((packed)); +#endif RealPt DOS_TableUpCase; diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 5dbfd81f..98e62848 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -23,7 +23,9 @@ +#if defined (_MSC_VER) #pragma pack(1) +#endif struct Dynamic_Functionality { RealPt static_table; /* 00h DWORD address of static functionality table */ Bit8u cur_mode; /* 04h BYTE video mode in effect */ @@ -68,9 +70,13 @@ struct Dynamic_Functionality { 7 reserved */ Bit8u reserved2[13]; /* 33h 13 BYTEs reserved (00h) */ -}; +} +#if defined (_MSC_VER) +; #pragma pack() - +#else +__attribute__ ((packed)); +#endif From b23a83c11a389d1d3d9e4727ec3aa697a3be5db0 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 10 Aug 2002 08:26:55 +0000 Subject: [PATCH 0056/4131] no message Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@133 --- AUTHORS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 6c649d66..e5076c36 100644 --- a/AUTHORS +++ b/AUTHORS @@ -3,4 +3,5 @@ The DOSBox Team Sjoerd v.d. Berg Peter Veenstra -Felix Jakschitsch \ No newline at end of file +Felix Jakschitsch +Ulf Wohlers From 8e8ef7fcb37ce11535e11b5fb1ffe61c8ff90228 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 10 Aug 2002 08:38:24 +0000 Subject: [PATCH 0057/4131] added data overview. new keys : d : view ds:si e : view es:di b : view es:bx x : view ds:dx r : offset -16 f : offset +16 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@134 --- src/debug/debug.cpp | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 332eb722..864fe74d 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -73,6 +73,25 @@ struct BreakPoint { static std::list BPoints; +static Bit16u dataSeg,dataOfs; + +static void DrawData() { + + Bit16u add = 0; + /* Data win */ + for (int y=0; y<8; y++) { + // Adress + mvwprintw (dbg.win_data,1+y,0,"%04X:%04X",dataSeg,dataOfs+add); + for (int x=0; x<16; x++) { + Bit8u ch = real_readb(dataSeg,dataOfs+add); + mvwprintw (dbg.win_data,1+y,11+3*x,"%02X",ch); + if (ch<32) ch='.'; + mvwprintw (dbg.win_data,1+y,60+x,"%c",ch); + add++; + }; + } + wrefresh(dbg.win_data); +}; static void DrawRegisters(void) { /* Main Registers */ @@ -177,8 +196,6 @@ bool DEBUG_BreakPoint(void) { } - - Bit32u DEBUG_CheckKeys(void) { int key=getch(); Bit32u ret=0; @@ -203,6 +220,22 @@ Bit32u DEBUG_CheckKeys(void) { ret=(*cpudecoder)(5); break; + case 'd': dataSeg = Segs[ds].value; + dataOfs = reg_si; + break; + case 'e': dataSeg = Segs[es].value; + dataOfs = reg_di; + break; + case 'x': dataSeg = Segs[ds].value; + dataOfs = reg_dx; + break; + case 'b': dataSeg = Segs[es].value; + dataOfs = reg_bx; + break; + + case 'r' : dataOfs -= 16; break; + case 'f' : dataOfs += 16; break; + default: ret=(*cpudecoder)(1); }; @@ -211,7 +244,6 @@ Bit32u DEBUG_CheckKeys(void) { return ret; }; - Bitu DEBUG_Loop(void) { //TODO Disable sound GFX_Events(); @@ -229,7 +261,7 @@ void DEBUG_Enable(void) { void DEBUG_DrawScreen(void) { DrawRegisters(); DrawCode(); - + DrawData(); } static void DEBUG_RaiseTimerIrq(void) { PIC_ActivateIRQ(0); From ff9d8e75ecea2fceb758eb52fe4bfe7a5eab47eb Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 10 Aug 2002 09:01:42 +0000 Subject: [PATCH 0058/4131] fixed mousehandler-bug. added funcs 0x06 / 0x14. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@135 --- src/ints/mouse.cpp | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index baab5990..0c5d4ed3 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -150,7 +150,7 @@ static void mouse_reset(void) { mouse.max_y=199; mouse.range_x=639; mouse.range_y=199; - mouse.x=320; + mouse.x=0; // civ wont work otherwise mouse.y=100; mouse.events=0; mouse.mickey_x=0; @@ -196,6 +196,18 @@ static Bitu INT33_Handler(void) { mouse.times_pressed[but]=0; break; } + case 0x06: /* Return Button Release Data */ + { + Bit16u but=reg_bx; + reg_ax=mouse.buttons; + reg_cx=mouse.last_released_x[but]; + mouse.last_released_x[but]=0; + reg_dx=mouse.last_released_y[but]; + mouse.last_released_y[but]=0; + reg_bx=mouse.times_released[but]; + mouse.times_released[but]=0; + break; + } case 0x07: /* Define horizontal cursor range */ mouse.min_x=reg_cx; mouse.max_x=reg_dx; @@ -227,6 +239,19 @@ static Bitu INT33_Handler(void) { mouse.mickey_x=0; mouse.mickey_y=0; break; + case 0x14: /* Exchange event-handler */ + { Bit16u oldSeg = mouse.sub_seg; + Bit16u oldOfs = mouse.sub_ofs; + Bit16u oldMask= mouse.sub_mask; + // Set new values + mouse.sub_mask= reg_cx; + mouse.sub_seg = Segs[es].value; + mouse.sub_ofs = reg_dx; + // Return old values + reg_cx = oldMask; + reg_dx = oldOfs; + SetSegment_16(es,oldSeg); + }; break; case 0x1c: /* Set interrupt rate */ /* Can't really set a rate this is host determined */ break; @@ -253,7 +278,10 @@ static Bitu INT74_Handler(void) { if (mouse.sub_mask & mouse.event_queue[mouse.events].type) { /* Save lot's of registers */ Bit16u oldax,oldbx,oldcx,olddx,oldsi,olddi; + Bit16u oldds,oldes,oldss,oldbp,oldsp; oldax=reg_ax;oldbx=reg_bx;oldcx=reg_cx;olddx=reg_dx;oldsi=reg_si;olddi=reg_di; + oldbp=reg_bp;oldsp=reg_sp; + oldds=Segs[ds].value; oldes=Segs[es].value; oldss=Segs[ss].value; // Save segments reg_ax=mouse.event_queue[mouse.events].type; reg_bx=mouse.event_queue[mouse.events].buttons; reg_cx=POS_X; @@ -266,6 +294,8 @@ static Bitu INT74_Handler(void) { } CALLBACK_RunRealFar(mouse.sub_seg,mouse.sub_ofs); reg_ax=oldax;reg_bx=oldbx;reg_cx=oldcx;reg_dx=olddx;reg_si=oldsi;reg_di=olddi; + SetSegment_16(ds,oldds); SetSegment_16(es,oldes); SetSegment_16(ss,oldss); // Save segments + reg_bp=oldbp; reg_sp=oldsp; } } IO_Write(0xa0,0x20); From 0cd64452c06f0071063a6d3d82f6d985f2c3716c Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 10 Aug 2002 10:11:35 +0000 Subject: [PATCH 0059/4131] changed BIOS_MOTOR_NACHLAUFTZEIT -> BIOS_DISK_MOTOR_TIMEOUT Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@136 --- include/bios.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/bios.h b/include/bios.h index 9d74b591..61d940bc 100644 --- a/include/bios.h +++ b/include/bios.h @@ -39,7 +39,7 @@ /* #define bios_keyboard_buffer (*(unsigned int *) 0x41e) */ #define BIOS_DRIVE_ACTIVE 0x43e #define BIOS_DRIVE_RUNNING 0x43f -#define BIOS_MOTOR_NACHLAUFZEIT 0x440 +#define BIOS_DISK_MOTOR_TIMEOUT 0x440 #define BIOS_DISK_STATUS 0x441 /* #define bios_fdc_result_buffer (*(unsigned short *) 0x442) */ #define BIOS_VIDEO_MODE 0x449 From c5296adea12dc8fb5e9b3e8243b2f49a7c418b10 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 10 Aug 2002 10:12:37 +0000 Subject: [PATCH 0060/4131] Added bios int 8 disk motor timeout counter Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@137 --- src/ints/bios.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 963fbb0f..ff8e2fe6 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -101,6 +101,10 @@ static Bitu INT11_Handler(void) { static Bitu INT8_Handler(void) { /* Increase the bios tick counter */ mem_writed(BIOS_TIMER,mem_readd(BIOS_TIMER)+1); + /* decrease floppy motor timer */ + Bit8u val = mem_readb(BIOS_DISK_MOTOR_TIMEOUT); + if (val>0) mem_writeb(BIOS_DISK_MOTOR_TIMEOUT,val-1); + CALLBACK_RunRealInt(0x1c); IO_Write(0x20,0x20); return CBRET_NONE; From 6624636b32c9acc8d1a4d40be2f199b8763d6277 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 10 Aug 2002 15:24:05 +0000 Subject: [PATCH 0061/4131] Removed real_get/set_vec Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@138 --- include/mem.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/include/mem.h b/include/mem.h index ec231d31..dde9d6b3 100644 --- a/include/mem.h +++ b/include/mem.h @@ -158,15 +158,6 @@ INLINE void real_writed(Bit16u seg,Bit16u off,Bit32u 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); From 4651bac31de09459681ff29b83c497869c50f622 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 10 Aug 2002 15:24:52 +0000 Subject: [PATCH 0062/4131] New register layout. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@139 --- include/regs.h | 62 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/include/regs.h b/include/regs.h index a86fcbee..7d8ed5d6 100644 --- a/include/regs.h +++ b/include/regs.h @@ -51,7 +51,7 @@ struct CPU_Regs { struct { Bit8u l,h; }b; - } ax,bx,cx,dx,si,di,sp,bp,ip; + } regs[8],ip; }; extern Segment Segs[6]; @@ -62,37 +62,49 @@ void SetSegment_16(Bit32u seg,Bit16u val); //extern Bit8u & reg_al=cpu_regs.ax.b.l; -#define reg_al cpu_regs.ax.b.l -#define reg_ah cpu_regs.ax.b.h -#define reg_ax cpu_regs.ax.w -#define reg_eax cpu_regs.ax.d +enum REG_NUM { + REG_NUM_AX, REG_NUM_CX, REG_NUM_DX, REG_NUM_BX, + REG_NUM_SP, REG_NUM_BP, REG_NUM_SI, REG_NUM_DI +}; -#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 +//macros to convert a 3-bit register index to the correct register +#define reg_8l(reg) (cpu_regs.regs[(reg)].b.l) +#define reg_8h(reg) (cpu_regs.regs[(reg)].b.h) +#define reg_8(reg) ((reg) & 4 ? reg_8h((reg) & 3) : reg_8l((reg) & 3)) +#define reg_16(reg) (cpu_regs.regs[(reg)].w) +#define reg_32(reg) (cpu_regs.regs[(reg)].d) -#define reg_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_al cpu_regs.regs[REG_NUM_AX].b.l +#define reg_ah cpu_regs.regs[REG_NUM_AX].b.h +#define reg_ax cpu_regs.regs[REG_NUM_AX].w +#define reg_eax cpu_regs.regs[REG_NUM_AX].d -#define reg_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_bl cpu_regs.regs[REG_NUM_BX].b.l +#define reg_bh cpu_regs.regs[REG_NUM_BX].b.h +#define reg_bx cpu_regs.regs[REG_NUM_BX].w +#define reg_ebx cpu_regs.regs[REG_NUM_BX].d -#define reg_si cpu_regs.si.w -#define reg_esi cpu_regs.si.d +#define reg_cl cpu_regs.regs[REG_NUM_CX].b.l +#define reg_ch cpu_regs.regs[REG_NUM_CX].b.h +#define reg_cx cpu_regs.regs[REG_NUM_CX].w +#define reg_ecx cpu_regs.regs[REG_NUM_CX].d -#define reg_di cpu_regs.di.w -#define reg_edi cpu_regs.di.d +#define reg_dl cpu_regs.regs[REG_NUM_DX].b.l +#define reg_dh cpu_regs.regs[REG_NUM_DX].b.h +#define reg_dx cpu_regs.regs[REG_NUM_DX].w +#define reg_edx cpu_regs.regs[REG_NUM_DX].d -#define reg_sp cpu_regs.sp.w -#define reg_esp cpu_regs.sp.d +#define reg_si cpu_regs.regs[REG_NUM_SI].w +#define reg_esi cpu_regs.regs[REG_NUM_SI].d -#define reg_bp cpu_regs.bp.w -#define reg_ebp cpu_regs.bp.d +#define reg_di cpu_regs.regs[REG_NUM_DI].w +#define reg_edi cpu_regs.regs[REG_NUM_DI].d + +#define reg_sp cpu_regs.regs[REG_NUM_SP].w +#define reg_esp cpu_regs.regs[REG_NUM_SP].d + +#define reg_bp cpu_regs.regs[REG_NUM_BP].w +#define reg_ebp cpu_regs.regs[REG_NUM_BP].d #define reg_ip cpu_regs.ip.w #define reg_eip cpu_regs.ip.d From 372fb19c194fdc9a4201d98cde8a9af5c5cfa3cb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 10 Aug 2002 15:27:33 +0000 Subject: [PATCH 0063/4131] Some fixes to the flags of shift instructions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@140 --- src/cpu/flags.cpp | 126 ++++++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 65 deletions(-) diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index fdaca113..02d41694 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -41,6 +41,9 @@ bool get_CF(void) { case t_DECw: case t_DECd: case t_MUL: + case t_RCLb: + case t_RCLw: + case t_RCLd: return flags.cf; break; @@ -72,34 +75,32 @@ bool get_CF(void) { case t_CMPd: return (flags.var1.d=8) return false; + if (flags.var2.b>8) return false; else return (flags.var1.b >> (8-flags.var2.b)) & 1; case t_SHLw: - if (flags.var2.b>=16) return false; + if (flags.var2.b>16) return false; else return (flags.var1.w >> (16-flags.var2.b)) & 1; case t_SHLd: - return (flags.var1.d >> (32 - flags.var2.b)) & 0x01; case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */ - return (flags.var1.d >> (32 - flags.var2.b)) & 0x01; case t_DSHLd: - return (flags.var1.d >> (32 - flags.var2.b)) & 0x01; - + return (flags.var1.d >> (32 - flags.var2.b)) & 1; + case t_RCRb: case t_SHRb: - return (flags.var1.b >> (flags.var2.b - 1)) & 0x01; + return (flags.var1.b >> (flags.var2.b - 1)) & 1; + case t_RCRw: case t_SHRw: - return (flags.var1.w >> (flags.var2.b - 1)) & 0x01; + return (flags.var1.w >> (flags.var2.b - 1)) & 1; + case t_RCRd: case t_SHRd: - return (flags.var1.d >> (flags.var2.b - 1)) & 0x01; - case t_SARb: - return (flags.var1.b >> (flags.var2.b - 1)) & 0x01; - case t_SARw: - return (flags.var1.w >> (flags.var2.b - 1)) & 0x01; - case t_SARd: - return (flags.var1.d >> (flags.var2.b - 1)) & 0x01; case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ - return (flags.var1.d >> (flags.var2.b - 1)) & 0x01; case t_DSHRd: - return (flags.var1.d >> (flags.var2.b - 1)) & 0x01; + return (flags.var1.d >> (flags.var2.b - 1)) & 1; + case t_SARb: + return (((Bit8s) flags.var1.b) >> (flags.var2.b - 1)) & 1; + case t_SARw: + return (((Bit16s) flags.var1.w) >> (flags.var2.b - 1)) & 1; + case t_SARd: + return (((Bit32s) flags.var1.d) >> (flags.var2.b - 1)) & 1; case t_NEGb: return (flags.var1.b!=0); case t_NEGw: @@ -107,29 +108,17 @@ bool get_CF(void) { case t_NEGd: return (flags.var1.d!=0); case t_ROLb: - return (flags.result.b & 1)>0; + return flags.result.b & 1; case t_ROLw: - return (flags.result.w & 1)>0; + return flags.result.w & 1; case t_ROLd: - return (flags.result.d & 1)>0; + return flags.result.d & 1; case t_RORb: return (flags.result.b & 0x80)>0; case t_RORw: return (flags.result.w & 0x8000)>0; case t_RORd: return (flags.result.d & 0x80000000)>0; - case t_RCLb: - return ((flags.var1.b >> (8-flags.var2.b))&1)>0; - case t_RCLw: - return ((flags.var1.w >> (16-flags.var2.b))&1)>0; - case t_RCLd: - return ((flags.var1.d >> (32-flags.var2.b))&1)>0; - case t_RCRb: - return ((flags.var1.b >> (flags.var2.b-1))&1)>0; - case t_RCRw: - return ((flags.var1.w >> (flags.var2.b-1))&1)>0; - case t_RCRd: - return ((flags.var1.d >> (flags.var2.b-1))&1)>0; case t_ORb: case t_ORw: case t_ORd: @@ -427,6 +416,9 @@ again: switch (type) { case t_UNKNOWN: case t_MUL: + case t_RCLb: + case t_RCLw: + case t_RCLd: return flags.of; case t_CF: type=flags.prev_type; @@ -448,9 +440,9 @@ again: case t_ADDd: case t_ADCd: //TODO fix dword Overflow - var1d31 = flags.var1.d & 0x8000; - var2d31 = flags.var2.d & 0x8000; - resultd31 = flags.result.d & 0x8000; + var1d31 = flags.var1.d & 0x80000000; + var2d31 = flags.var2.d & 0x80000000; + resultd31 = flags.result.d & 0x80000000; return (var1d31 == var2d31) && (resultd31 ^ var2d31); case t_SBBb: case t_SUBb: @@ -471,10 +463,10 @@ again: case t_SBBd: case t_SUBd: case t_CMPd: - var1d31 = flags.var1.d & 0x8000; - var2d31 = flags.var2.d & 0x8000; - resultd31 = flags.result.d & 0x8000; - return (var1d31 ^ var2d31) && (var1d31 ^ resultd31); + var1d31 = flags.var1.d & 0x80000000; + var2d31 = flags.var2.d & 0x80000000; + resultd31 = flags.result.d & 0x80000000; + return (var1d31 ^ var2d31) && (var1d31 ^ resultd31); case t_INCb: return (flags.result.b == 0x80); case t_INCw: @@ -494,39 +486,43 @@ again: case t_NEGd: return (flags.var1.d == 0x80000000); case t_ROLb: - case t_RORb: - case t_RCLb: - case t_RCRb: - case t_SHLb: - if (flags.var2.b==1) return ((flags.var1.b ^ flags.result.b) & 0x80) >0; - break; + return ((flags.result.b & 0x80) ^ (flags.result.b & 1 ? 0x80 : 0)) != 0; case t_ROLw: - case t_RORw: - case t_RCLw: - case t_RCRw: - case t_SHLw: - case t_DSHLw: //TODO This is euhm inccorect i think but let's keep it for now - if (flags.var2.b==1) return ((flags.var1.w ^ flags.result.w) & 0x8000) >0; - break; + return ((flags.result.w & 0x8000) ^ (flags.result.w & 1 ? 0x8000 : 0)) != 0; case t_ROLd: - case t_RORd: - case t_RCLd: - case t_RCRd: + return ((flags.result.d & 0x80000000) ^ (flags.result.d & 1 ? 0x80000000 : 0)) != 0; + case t_SHLb: + if (flags.var2.b>9) return false; + return ((flags.result.b & 0x80) ^ + ((flags.var1.b << (flags.var2.b - 1)) & 0x80)) != 0; + case t_SHLw: + if (flags.var2.b>17) return false; + return ((flags.result.w & 0x8000) ^ + ((flags.var1.w << (flags.var2.b - 1)) & 0x8000)) != 0; + case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */ + return ((flags.result.w & 0x8000) ^ + (((flags.var1.d << (flags.var2.b - 1)) >> 16) & 0x8000)) != 0; case t_SHLd: case t_DSHLd: - if (flags.var2.b==1) return ((flags.var1.d ^ flags.result.d) & 0x80000000) >0; - break; + return ((flags.result.d & 0x80000000) ^ + ((flags.var1.d << (flags.var2.b - 1)) & 0x80000000)) != 0; + case t_RORb: + case t_RCRb: + return ((flags.result.b ^ (flags.result.b << 1)) & 0x80) > 0; + case t_RORw: + case t_RCRw: + case t_DSHRw: + return ((flags.result.w ^ (flags.result.w << 1)) & 0x8000) > 0; + case t_RORd: + case t_RCRd: + case t_DSHRd: + return ((flags.result.d ^ (flags.result.d << 1)) & 0x80000000) > 0; case t_SHRb: - if (flags.var2.b==1) return (flags.var1.b >= 0x80); - break; + return (flags.result.b >= 0x40); case t_SHRw: - case t_DSHRw: //TODO - if (flags.var2.b==1) return (flags.var1.w >= 0x8000); - break; + return (flags.result.w >= 0x4000); case t_SHRd: - case t_DSHRd: //TODO - if (flags.var2.b==1) return (flags.var1.d >= 0x80000000); - break; + return (flags.result.d >= 0x40000000); case t_SARb: case t_SARw: case t_SARd: From 383a425fc953aa137e688660d36fcca5b3757b7d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 12 Aug 2002 08:17:03 +0000 Subject: [PATCH 0064/4131] Fixes to just about every shift rotate instruction. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@141 --- src/cpu/core_16/instructions.h | 244 ++++++++++++++++++++------------- 1 file changed, 151 insertions(+), 93 deletions(-) diff --git a/src/cpu/core_16/instructions.h b/src/cpu/core_16/instructions.h index d0a5fd9a..72367b99 100644 --- a/src/cpu/core_16/instructions.h +++ b/src/cpu/core_16/instructions.h @@ -36,6 +36,13 @@ ADDIPFAST(2); \ } +#define SETcc(cc) \ + { \ + GetRM; \ + if (rm >= 0xc0 ) {GetEArb;*earb=(cc) ? 1 : 0;} \ + else {GetEAa;SaveMb(eaa,(cc) ? 1 : 0);} \ + } + #define INTERRUPT(blah) \ { \ Bit8u new_num=blah; \ @@ -257,207 +264,248 @@ //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; \ + if (!(op2&0x1F)) 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.var2.b=op2&0x07;flags.var1.b=load(op1); \ + if (!flags.var2.b) { \ + flags.result.b=flags.var1.b; \ + } else { \ + 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; \ + if (!(op2&0x1F)) 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)); \ + flags.var2.b=op2&0x0F;flags.var1.w=load(op1); \ + if (!flags.var2.b) { \ + flags.result.w=flags.var1.w; \ + } else { \ + 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; \ + if (!(op2&0x1F)) break; \ flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ - flags.var1.d=load(op1);flags.var2.b=op2&0x0F; \ + flags.var2.b=op2&0x1F;flags.var1.d=load(op1); \ flags.result.d=(flags.var1.d << flags.var2.b) | \ - (flags.var1.d >> (32-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; \ + if (!(op2&0x1F)) 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.var2.b=op2&0x07;flags.var1.b=load(op1); \ + if (!flags.var2.b) { \ + flags.result.b=flags.var1.b; \ + } else { \ + 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; \ + if (!(op2&0x1F)) 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)); \ + flags.var2.b=op2&0x0F;flags.var1.w=load(op1); \ + if (!flags.var2.b) { \ + flags.result.w=flags.var1.w; \ + } else { \ + 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; \ + if (!(op2&0x1F)) break; \ flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ - flags.var1.d=load(op1);flags.var2.b=op2&0x0F; \ + flags.var2.b=op2&0x1F;flags.var1.d=load(op1); \ flags.result.d=(flags.var1.d >> flags.var2.b) | \ - (flags.var1.d << (32-flags.var2.b)); \ + (flags.var1.d << (32-flags.var2.b)); \ save(op1,flags.result.d); \ flags.type=t_RORd; + +/* flags.oldcf=get_CF();*/ \ + #define RCLB(op1,op2,load,save) \ - if (!(op2%9)) break; \ + if (!(op2 & 0x1F)) 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.var2.b=(op2 & 0x1F)%9;flags.var1.b=load(op1); \ + if (!flags.var2.b) { \ + flags.result.b=flags.var1.b; \ + } else { \ + 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); + flags.cf=((flags.var1.b >> (8-flags.var2.b)) & 1); \ + } \ + flags.of=((flags.result.b & 0x80) ^ (flags.cf ? 0x80 : 0)) != 0; \ + save(op1,flags.result.b); #define RCLW(op1,op2,load,save) \ - if (!(op2%17)) break; \ + if (!(op2 & 0x1F)) 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)); \ + flags.var2.b=(op2 & 0x1F)%17;flags.var1.w=load(op1); \ + if (!flags.var2.b) { \ + flags.result.w=flags.var1.w; \ + } else { \ + flags.result.w=(flags.var1.w << flags.var2.b) | \ + (flags.cf << (flags.var2.b-1)) | \ + (flags.var1.w >> (17-flags.var2.b)); \ + flags.cf=((flags.var1.w >> (16-flags.var2.b)) & 1); \ + } \ + flags.of=((flags.result.w & 0x8000) ^ (flags.cf ? 0x8000 : 0)) != 0; \ save(op1,flags.result.w); #define RCLD(op1,op2,load,save) \ - if (!op2) break; \ + if (!(op2 & 0x1F)) 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; \ + flags.var2.b=op2 & 0x1F;flags.var1.d=load(op1); \ + 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)); \ + (flags.cf << (flags.var2.b-1)) | \ + (flags.var1.d >> (33-flags.var2.b)); \ } \ + flags.cf=((flags.var1.d >> (32-flags.var2.b)) & 1); \ + flags.of=((flags.result.d & 0x80000000) ^ (flags.cf ? 0x80000000 : 0)) != 0; \ save(op1,flags.result.d); #define RCRB(op1,op2,load,save) \ - if (!(op2%9)) break; \ + if (!(op2 & 0x1F)) 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.var2.b=(op2 & 0x1F)%9;flags.var1.b=load(op1); \ + if (!flags.var2.b) { \ + flags.result.b=flags.var1.b; \ + } else { \ + 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; \ + if (!(op2 & 0x1F)) 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.var2.b=(op2 & 0x1F)%17;flags.var1.w=load(op1); \ + if (!flags.var2.b) { \ + flags.result.w=flags.var1.w; \ + } else { \ + flags.result.w=(flags.var1.w >> flags.var2.b) | \ (flags.cf << (16-flags.var2.b)) | \ - (flags.var1.w << (17-flags.var2.b)); \ + (flags.var1.w << (17-flags.var2.b)); \ + } \ save(op1,flags.result.w); - #define RCRD(op1,op2,load,save) \ - if (!op2) break; \ + if (!(op2 & 0x1F)) 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; \ + flags.var2.b=op2 & 0x1F;flags.var1.d=load(op1); \ 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)); \ + (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; \ + if (!(op2 & 0x1F)) break; \ + flags.var1.b=load(op1);flags.var2.b=op2 & 0x1F; \ + 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; \ + if (!(op2 & 0x1F)) break; \ + flags.var1.w=load(op1);flags.var2.b=op2 & 0x1F; \ + 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; \ + if (!(op2 & 0x1F)) break; \ + flags.var1.d=load(op1);flags.var2.b=op2 & 0x1F; \ + 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; \ + if (!(op2 & 0x1F)) break; \ + flags.var1.b=load(op1);flags.var2.b=op2 & 0x1F; \ + 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; \ + if (!(op2 & 0x1F)) break; \ + flags.var1.w=load(op1);flags.var2.b=op2 & 0x1F; \ + 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; \ + if (!(op2 & 0x1F)) break; \ + flags.var1.d=load(op1);flags.var2.b=op2 & 0x1F; \ + 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 (!(op2 & 0x1F)) break; \ + flags.var1.b=load(op1);flags.var2.b=op2 & 0x1F; \ if (flags.var2.b>8) flags.var2.b=8; \ if (flags.var1.b & 0x80) { \ - flags.result.b=(flags.var1.b >> flags.var2.b)| \ + flags.result.b=(flags.var1.b >> flags.var2.b)| \ (0xff << (8 - flags.var2.b)); \ } else { \ - flags.result.b=flags.var1.b >> flags.var2.b; \ + 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)); \ + if (!(op2 & 0x1F)) break; \ + flags.var1.w=load(op1);flags.var2.b=op2 & 0x1F; \ + 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; \ + 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)); \ + if (!(op2 & 0x1F)) break; \ + flags.var2.b=op2 & 0x1F;flags.var1.d=load(op1); \ + 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; \ + flags.result.d=flags.var1.d >> flags.var2.b; \ } \ save(op1,flags.result.d); \ flags.type=t_SARd; @@ -564,30 +612,40 @@ } /* let's hope bochs has it correct with the higher than 16 shifts */ +/* double-precision shift left has low bits in second argument */ #define DSHLW(op1,op2,op3,load,save) \ - flags.var1.d=(load(op1)<<16)|op2;flags.var2.b=op3; \ + Bit8u val=op3 & 0x1F; \ + if (!val) break; \ + flags.var2.b=val;flags.var1.d=(load(op1)<<16)|op2; \ Bit32u tempd=flags.var1.d << flags.var2.b; \ if (flags.var2.b>16) tempd |= (op2 << (flags.var2.b - 16)); \ flags.result.w=(Bit16u)(tempd >> 16); \ save(op1,flags.result.w); \ flags.type=t_DSHLw; -#define DSHLD(op1,op2,op3,load,save) \ - flags.var1.d=load(op1);flags.var2.b=op3; \ +#define DSHLD(op1,op2,op3,load,save) \ + Bit8u val=op3 & 0x1F; \ + if (!val) break; \ + flags.var2.b=val;flags.var1.d=load(op1); \ flags.result.d=(flags.var1.d << flags.var2.b) | (op2 >> (32-flags.var2.b)); \ - save(op1,flags.result.d); \ + save(op1,flags.result.d); \ flags.type=t_DSHLd; +/* double-precision shift right has high bits in second argument */ #define DSHRW(op1,op2,op3,load,save) \ - flags.var1.d=(load(op1)<<16)|op2;flags.var2.b=op3; \ + Bit8u val=op3 & 0x1F; \ + if (!val) break; \ + flags.var2.b=val;flags.var1.d=(op2<<16)|load(op1); \ Bit32u tempd=flags.var1.d >> flags.var2.b; \ if (flags.var2.b>16) tempd |= (op2 << (32-flags.var2.b )); \ flags.result.w=(Bit16u)(tempd); \ save(op1,flags.result.w); \ flags.type=t_DSHRw; -#define DSHRD(op1,op2,op3,load,save) \ - flags.var1.d=load(op1);flags.var2.b=op3; \ +#define DSHRD(op1,op2,op3,load,save) \ + Bit8u val=op3 & 0x1F; \ + if (!val) break; \ + flags.var2.b=val;flags.var1.d=load(op1); \ flags.result.d=(flags.var1.d >> flags.var2.b) | (op2 << (32-flags.var2.b)); \ - save(op1,flags.result.d); \ + save(op1,flags.result.d); \ flags.type=t_DSHRd; From 0b17367d8dd93ceaa2c7122859d8fe14c3b20b96 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 12 Aug 2002 08:18:04 +0000 Subject: [PATCH 0065/4131] New instructions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@142 --- src/cpu/core_16/prefix_of.h | 218 ++++++++++++++++++++++++++++++++++-- 1 file changed, 208 insertions(+), 10 deletions(-) diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h index f4024994..2010372c 100644 --- a/src/cpu/core_16/prefix_of.h +++ b/src/cpu/core_16/prefix_of.h @@ -31,6 +31,63 @@ switch(Fetchb()) { } } break; + /* 0x02 LAR Gw,Ew (286) */ + /* 0x03 LSL Gw,Ew (286) */ + /* 0x05 LOADALL (286 only?) */ + /* 0x06 CLTS (286) */ + /* 0x07 LOADALL (386 only?) */ + /* 0x08 INVD (486) */ + /* 0x02 WBINVD (486) */ + /* 0x10 UMOV Eb,Gb (386) */ + /* 0x11 UMOV Ew,Gw (386) */ + /* 0x12 UMOV Gb,Eb (386) */ + /* 0x13 UMOV Gw,Ew (386) */ + /* 0x20 MOV Rd,CRx (386) */ + /* 0x21 MOV Rd,DRx (386) */ + /* 0x22 MOV CRx,Rd (386) */ + /* 0x23 MOV DRx,Rd (386) */ + /* 0x24 MOV Rd,TRx (386) */ + /* 0x26 MOV TRx,Rd (386) */ + /* 0x30 WRMSR (P5) */ + /* 0x31 RDTSC (P5) */ + /* 0x32 RDMSR (P5) */ + /* 0x33 RDPMC (P6) */ + /* 0x40-4F CMOVcc Gw,Ew (P6) */ + /* 0x50 PAVEB Rq,Eq (CYRIX MMX) */ + /* 0x51 PADDSIW Rq,Eq (CYRIX MMX) */ + /* 0x52 PMAGW Rq,Eq (CYRIX MMX) */ + /* 0x54 PDISTIB Rq,Eq (CYRIX MMX) */ + /* 0x55 PSUBSIW Rq,Eq (CYRIX MMX) */ + /* 0x58 PMVZB Rq,Eq (CYRIX MMX) */ + /* 0x59 PMULHRW Rq,Eq (CYRIX MMX) */ + /* 0x5A PMVNZB Rq,Eq (CYRIX MMX) */ + /* 0x5B PMVLZB Rq,Eq (CYRIX MMX) */ + /* 0x5C PMVGEZB Rq,Eq (CYRIX MMX) */ + /* 0x5D PMULHRIW Rq,Eq (CYRIX MMX) */ + /* 0x5E PMACHRIW Rq,Eq (CYRIX MMX) */ + /* 0x60 PUNPCKLBW Rq,Eq (MMX) */ + /* 0x61 PUNPCKLWD Rq,Eq (MMX) */ + /* 0x62 PUNPCKLDQ Rq,Eq (MMX) */ + /* 0x63 PACKSSWB Rq,Eq (MMX) */ + /* 0x64 PCMPGTB Rq,Eq (MMX) */ + /* 0x65 PCMPGTW Rq,Eq (MMX) */ + /* 0x66 PCMPGTD Rq,Eq (MMX) */ + /* 0x67 PACKUSWB Rq,Eq (MMX) */ + /* 0x68 PUNPCKHBW Rq,Eq (MMX) */ + /* 0x69 PUNPCKHWD Rq,Eq (MMX) */ + /* 0x6A PUNPCKHDQ Rq,Eq (MMX) */ + /* 0x6B PACKSSDW Rq,Eq (MMX) */ + /* 0x6E MOVD Rq,Ed (MMX) */ + /* 0x6F MOVQ Rq,Eq (MMX) */ + /* 0x71 PSLLW/PSRAW/PSRLW Rq,Ib (MMX) */ + /* 0x72 PSLLD/PSRAD/PSRLD Rq,Ib (MMX) */ + /* 0x73 PSLLQ/PSRLQ Rq,Ib (MMX) */ + /* 0x74 PCMPEQB Rq,Eq (MMX) */ + /* 0x75 PCMPEQW Rq,Eq (MMX) */ + /* 0x76 PCMPEQD Rq,Eq (MMX) */ + /* 0x77 EMMS (MMX) */ + /* 0x7E MOVD Ed,Rq (MMX) */ + /* 0x7F MOVQ Ed,Rq (MMX) */ case 0x80: /* JO */ JumpSIw(get_OF());break; case 0x81: /* JNO */ @@ -63,10 +120,59 @@ switch(Fetchb()) { JumpSIw(get_ZF() || (get_SF() != get_OF()));break; case 0x8f: /* JNLE */ JumpSIw((get_SF() == get_OF()) && !get_ZF());break; + + case 0x90: /* SETO */ + SETcc(get_OF());break; + case 0x91: /* SETNO */ + SETcc(!get_OF());break; + case 0x92: /* SETB */ + SETcc(get_CF());break; + case 0x93: /* SETNB */ + SETcc(!get_CF());break; + case 0x94: /* SETZ */ + SETcc(get_ZF());break; + case 0x95: /* SETNZ */ + SETcc(!get_ZF()); break; + case 0x96: /* SETBE */ + SETcc(get_CF() || get_ZF());break; + case 0x97: /* SETNBE */ + SETcc(!get_CF() && !get_ZF());break; + case 0x98: /* SETS */ + SETcc(get_SF());break; + case 0x99: /* SETNS */ + SETcc(!get_SF());break; + case 0x9a: /* SETP */ + SETcc(get_PF());break; + case 0x9b: /* SETNP */ + SETcc(!get_PF());break; + case 0x9c: /* SETL */ + SETcc(get_SF() != get_OF());break; + case 0x9d: /* SETNL */ + SETcc(get_SF() == get_OF());break; + case 0x9e: /* SETLE */ + SETcc(get_ZF() || (get_SF() != get_OF()));break; + case 0x9f: /* SETNLE */ + SETcc((get_SF() == get_OF()) && !get_ZF());break; + case 0xa0: /* PUSH FS */ Push_16(Segs[fs].value);break; case 0xa1: /* POP FS */ SetSegment_16(fs,Pop_16());break; + /* 0xa2 CPUID */ + case 0xa3: /* BT Ew,Gw */ + { + GetRMrw; + Bit16u mask=1 << (*rmrw & 15); + if (rm >= 0xc0 ) { + GetEArw; + flags.cf=(*earw & mask)>0; + } else { + GetEAa;Bit16u old=LoadMw(eaa); + flags.cf=(old & mask)>0; + } + if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + break; + } case 0xa4: /* SHLD Ew,Gw,Ib */ { GetRMrw; @@ -81,10 +187,29 @@ switch(Fetchb()) { else {GetEAa;DSHLW(eaa,*rmrw,reg_cl,LoadMw,SaveMw);} break; } + /* 0xa6 XBTS (early 386 only) CMPXCHG (early 486 only) */ + /* 0xa7 IBTS (early 386 only) CMPXCHG (early 486 only) */ case 0xa8: /* PUSH GS */ Push_16(Segs[gs].value);break; case 0xa9: /* POP GS */ SetSegment_16(gs,Pop_16());break; + /* 0xaa RSM */ + case 0xab: /* BTS Ew,Gw */ + { + GetRMrw; + Bit16u mask=1 << (*rmrw & 15); + if (rm >= 0xc0 ) { + GetEArw; + flags.cf=(*earw & mask)>0; + *earw|=mask; + } else { + GetEAa;Bit16u old=LoadMw(eaa); + flags.cf=(old & mask)>0; + SaveMw(eaa,old | mask); + } + if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + break; + } case 0xac: /* SHRD Ew,Gw,Ib */ { GetRMrw; @@ -111,6 +236,25 @@ switch(Fetchb()) { else {flags.cf=true;flags.of=true;} break; } + /* 0xb0 CMPXCHG Eb,Gb */ + /* 0xb1 CMPXCHG Ew,Gw */ + /* 0xb2 LSS */ + case 0xb3: /* BTR Ew,Gw */ + { + GetRMrw; + Bit16u mask=1 << (*rmrw & 15); + if (rm >= 0xc0 ) { + GetEArw; + flags.cf=(*earw & mask)>0; + *earw&= ~mask; + } else { + GetEAa;Bit16u old=LoadMw(eaa); + flags.cf=(old & mask)>0; + SaveMw(eaa,old & ~mask); + } + if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + break; + } case 0xb4: /* LFS */ { GetRMrw;GetEAa; @@ -130,12 +274,20 @@ switch(Fetchb()) { else {GetEAa;*rmrw=LoadMb(eaa);} break; } + case 0xb7: /* MOVZX Gw,Ew */ + case 0xbf: /* MOVSX Gw,Ew */ + { + GetRMrw; + if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;} + else {GetEAa;*rmrw=LoadMw(eaa);} + break; + } case 0xba: /* GRP8 Ew,Ib */ { GetRM; + Bit16u mask=1 << (Fetchb() & 15); if (rm >= 0xc0 ) { GetEArw; - Bit16u mask=1 << (Fetchb() & 15); flags.cf=(*earw & mask)>0; switch (rm & 0x38) { case 0x20: /* BT */ @@ -144,16 +296,14 @@ switch(Fetchb()) { *earw|=mask; break; case 0x30: /* BTR */ - *earw&=~mask; + *earw&= ~mask; break; case 0x38: /* BTC */ - if (flags.cf) *earw&=~mask; - else *earw|=mask; + *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 */ @@ -165,16 +315,31 @@ switch(Fetchb()) { SaveMw(eaa,old & ~mask); break; case 0x38: /* BTC */ - if (flags.cf) old&=~mask; - else old|=mask; - SaveMw(eaa,old); + SaveMw(eaa,old ^ mask); break; } } - if (flags.type!=t_CF) flags.prev_type=flags.type; - flags.type=t_CF; + if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } break; } + case 0xbb: /* BTC Ew,Gw */ + { + GetRMrw; + Bit16u mask=1 << (*rmrw & 15); + if (rm >= 0xc0 ) { + GetEArw; + flags.cf=(*earw & mask)>0; + *earw^=mask; + } else { + GetEAa;Bit16u old=LoadMw(eaa); + flags.cf=(old & mask)>0; + SaveMw(eaa,old ^ mask); + } + if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + break; + } + /* 0xbc BSF Gw,Ew */ + /* 0xbd BSR Gw,Ew */ case 0xbe: /* MOVSX Gw,Eb */ { GetRMrw; @@ -182,6 +347,39 @@ switch(Fetchb()) { else {GetEAa;*rmrw=LoadMbs(eaa);} break; } + /* 0xc0 XADD Eb,Gb (486) */ + /* 0xc1 XADD Ew,Gw (486) */ + /* 0xc7 CMPXCHG8B Mq (P5) */ + /* 0xc8-cf BSWAP Rw (odd behavior,486) */ + /* 0xd1 PSRLW Rq,Eq (MMX) */ + /* 0xd2 PSRLD Rq,Eq (MMX) */ + /* 0xd3 PSRLQ Rq,Eq (MMX) */ + /* 0xd5 PMULLW Rq,Eq (MMX) */ + /* 0xd8 PSUBUSB Rq,Eq (MMX) */ + /* 0xd9 PSUBUSW Rq,Eq (MMX) */ + /* 0xdb PAND Rq,Eq (MMX) */ + /* 0xdc PADDUSB Rq,Eq (MMX) */ + /* 0xdd PADDUSW Rq,Eq (MMX) */ + /* 0xdf PANDN Rq,Eq (MMX) */ + /* 0xe1 PSRAW Rq,Eq (MMX) */ + /* 0xe2 PSRAD Rq,Eq (MMX) */ + /* 0xe5 PMULHW Rq,Eq (MMX) */ + /* 0xe8 PSUBSB Rq,Eq (MMX) */ + /* 0xe9 PSUBSW Rq,Eq (MMX) */ + /* 0xeb POR Rq,Eq (MMX) */ + /* 0xec PADDSB Rq,Eq (MMX) */ + /* 0xed PADDSW Rq,Eq (MMX) */ + /* 0xef PXOR Rq,Eq (MMX) */ + /* 0xf1 PSLLW Rq,Eq (MMX) */ + /* 0xf2 PSLLD Rq,Eq (MMX) */ + /* 0xf3 PSLLQ Rq,Eq (MMX) */ + /* 0xf5 PMADDWD Rq,Eq (MMX) */ + /* 0xf8 PSUBB Rq,Eq (MMX) */ + /* 0xf9 PSUBW Rq,Eq (MMX) */ + /* 0xfa PSUBD Rq,Eq (MMX) */ + /* 0xfc PADDB Rq,Eq (MMX) */ + /* 0xfd PADDW Rq,Eq (MMX) */ + /* 0xfe PADDD Rq,Eq (MMX) */ default: SUBIP(1); E_Exit("CPU:Opcode 0F:%2X Unhandled",Fetchb()); From f1235b9a9916a45cd3c67c93d0c7fe9e36f042d8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 12 Aug 2002 08:45:12 +0000 Subject: [PATCH 0066/4131] New instructions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@143 --- src/cpu/core_16/main.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 2a079a61..12e70963 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -235,9 +235,9 @@ restart: Push_16(reg_dx);break; case 0x53: /* PUSH BX */ Push_16(reg_bx);break; - case 0x54: /* PUSH SP */ + case 0x54: /* PUSH SP */ //TODO Check if this is correct i think it's SP+2 or something - Push_16(reg_sp);break; + Push_16(reg_sp);break; case 0x55: /* PUSH BP */ Push_16(reg_bp);break; case 0x56: /* PUSH SI */ @@ -252,8 +252,8 @@ restart: reg_dx=Pop_16();break; case 0x5b: /* POP BX */ reg_bx=Pop_16();break; - case 0x5c: /* POP SP */ - reg_sp=Pop_16();break; + case 0x5c: /* POP SP */ + reg_sp=Pop_16();break; case 0x5d: /* POP BP */ reg_bp=Pop_16();break; case 0x5e: /* POP SI */ @@ -933,8 +933,8 @@ restart: //TODO PF flags.type=t_UNKNOWN; break; - case 0xd6: /* Not in intel specs */ - NOTDONE; + case 0xd6: /* SALC */ + reg_al = get_CF() ? 0xFF : 0; break; case 0xd7: /* XLAT */ if (segprefix_on) { From 2d8f205a71464532c0247ee6f7a5dc1afd0d9591 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 12 Aug 2002 13:42:26 +0000 Subject: [PATCH 0067/4131] Remove some useless bit masking in the shifts Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@144 --- src/cpu/core_16/instructions.h | 76 +++++++++++++++++----------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/src/cpu/core_16/instructions.h b/src/cpu/core_16/instructions.h index 72367b99..9863b2e0 100644 --- a/src/cpu/core_16/instructions.h +++ b/src/cpu/core_16/instructions.h @@ -264,7 +264,7 @@ //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&0x1F)) break; \ + if (!op2) break; \ flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ flags.var2.b=op2&0x07;flags.var1.b=load(op1); \ if (!flags.var2.b) { \ @@ -277,7 +277,7 @@ flags.type=t_ROLb; #define ROLW(op1,op2,load,save) \ - if (!(op2&0x1F)) break; \ + if (!op2) break; \ flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ flags.var2.b=op2&0x0F;flags.var1.w=load(op1); \ if (!flags.var2.b) { \ @@ -290,9 +290,9 @@ flags.type=t_ROLw; #define ROLD(op1,op2,load,save) \ - if (!(op2&0x1F)) break; \ + if (!op2) break; \ flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ - flags.var2.b=op2&0x1F;flags.var1.d=load(op1); \ + flags.var2.b=op2;flags.var1.d=load(op1); \ flags.result.d=(flags.var1.d << flags.var2.b) | \ (flags.var1.d >> (32-flags.var2.b)); \ save(op1,flags.result.d); \ @@ -300,7 +300,7 @@ #define RORB(op1,op2,load,save) \ - if (!(op2&0x1F)) break; \ + if (!op2) break; \ flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ flags.var2.b=op2&0x07;flags.var1.b=load(op1); \ if (!flags.var2.b) { \ @@ -313,7 +313,7 @@ flags.type=t_RORb; #define RORW(op1,op2,load,save) \ - if (!(op2&0x1F)) break; \ + if (!op2) break; \ flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ flags.var2.b=op2&0x0F;flags.var1.w=load(op1); \ if (!flags.var2.b) { \ @@ -326,9 +326,9 @@ flags.type=t_RORw; #define RORD(op1,op2,load,save) \ - if (!(op2&0x1F)) break; \ + if (!op2) break; \ flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ - flags.var2.b=op2&0x1F;flags.var1.d=load(op1); \ + flags.var2.b=op2;flags.var1.d=load(op1); \ flags.result.d=(flags.var1.d >> flags.var2.b) | \ (flags.var1.d << (32-flags.var2.b)); \ save(op1,flags.result.d); \ @@ -338,10 +338,10 @@ /* flags.oldcf=get_CF();*/ \ #define RCLB(op1,op2,load,save) \ - if (!(op2 & 0x1F)) break; \ + if (!op2) break; \ flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ flags.cf=get_CF();flags.type=t_RCLb; \ - flags.var2.b=(op2 & 0x1F)%9;flags.var1.b=load(op1); \ + flags.var2.b=op2%9;flags.var1.b=load(op1); \ if (!flags.var2.b) { \ flags.result.b=flags.var1.b; \ } else { \ @@ -354,10 +354,10 @@ save(op1,flags.result.b); #define RCLW(op1,op2,load,save) \ - if (!(op2 & 0x1F)) break; \ + if (!op2) break; \ flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ flags.cf=get_CF();flags.type=t_RCLw; \ - flags.var2.b=(op2 & 0x1F)%17;flags.var1.w=load(op1); \ + flags.var2.b=op2%17;flags.var1.w=load(op1); \ if (!flags.var2.b) { \ flags.result.w=flags.var1.w; \ } else { \ @@ -370,10 +370,10 @@ save(op1,flags.result.w); #define RCLD(op1,op2,load,save) \ - if (!(op2 & 0x1F)) break; \ + if (!op2) break; \ flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ flags.cf=get_CF();flags.type=t_RCLd; \ - flags.var2.b=op2 & 0x1F;flags.var1.d=load(op1); \ + flags.var2.b=op2;flags.var1.d=load(op1); \ if (flags.var2.b==1) { \ flags.result.d=flags.var1.d << 1 | flags.cf; \ } else { \ @@ -386,10 +386,10 @@ save(op1,flags.result.d); #define RCRB(op1,op2,load,save) \ - if (!(op2 & 0x1F)) break; \ + if (!op2) break; \ flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ flags.cf=get_CF();flags.type=t_RCRb; \ - flags.var2.b=(op2 & 0x1F)%9;flags.var1.b=load(op1); \ + flags.var2.b=op2%9;flags.var1.b=load(op1); \ if (!flags.var2.b) { \ flags.result.b=flags.var1.b; \ } else { \ @@ -400,10 +400,10 @@ save(op1,flags.result.b); #define RCRW(op1,op2,load,save) \ - if (!(op2 & 0x1F)) break; \ + if (!op2) break; \ flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ flags.cf=get_CF();flags.type=t_RCRw; \ - flags.var2.b=(op2 & 0x1F)%17;flags.var1.w=load(op1); \ + flags.var2.b=op2%17;flags.var1.w=load(op1); \ if (!flags.var2.b) { \ flags.result.w=flags.var1.w; \ } else { \ @@ -414,10 +414,10 @@ save(op1,flags.result.w); #define RCRD(op1,op2,load,save) \ - if (!(op2 & 0x1F)) break; \ + if (!op2) break; \ flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ flags.cf=get_CF();flags.type=t_RCRd; \ - flags.var2.b=op2 & 0x1F;flags.var1.d=load(op1); \ + flags.var2.b=op2;flags.var1.d=load(op1); \ if (flags.var2.b==1) { \ flags.result.d=flags.var1.d >> 1 | flags.cf << 31; \ } else { \ @@ -429,52 +429,52 @@ #define SHLB(op1,op2,load,save) \ - if (!(op2 & 0x1F)) break; \ - flags.var1.b=load(op1);flags.var2.b=op2 & 0x1F; \ + 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 & 0x1F)) break; \ - flags.var1.w=load(op1);flags.var2.b=op2 & 0x1F; \ + 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 & 0x1F)) break; \ - flags.var1.d=load(op1);flags.var2.b=op2 & 0x1F; \ + 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 & 0x1F)) break; \ - flags.var1.b=load(op1);flags.var2.b=op2 & 0x1F; \ + 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 & 0x1F)) break; \ - flags.var1.w=load(op1);flags.var2.b=op2 & 0x1F; \ + 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 & 0x1F)) break; \ - flags.var1.d=load(op1);flags.var2.b=op2 & 0x1F; \ + 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 & 0x1F)) break; \ - flags.var1.b=load(op1);flags.var2.b=op2 & 0x1F; \ + 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)| \ @@ -486,8 +486,8 @@ flags.type=t_SARb; #define SARW(op1,op2,load,save) \ - if (!(op2 & 0x1F)) break; \ - flags.var1.w=load(op1);flags.var2.b=op2 & 0x1F; \ + 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)| \ @@ -499,8 +499,8 @@ flags.type=t_SARw; #define SARD(op1,op2,load,save) \ - if (!(op2 & 0x1F)) break; \ - flags.var2.b=op2 & 0x1F;flags.var1.d=load(op1); \ + if (!op2) break; \ + flags.var2.b=op2;flags.var1.d=load(op1); \ if (flags.var1.d & 0x80000000) { \ flags.result.d=(flags.var1.d >> flags.var2.b)| \ (0xffffffff << (32 - flags.var2.b)); \ From 976412ba3bbf88579261addf1a4a437312da9425 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 12 Aug 2002 17:37:16 +0000 Subject: [PATCH 0068/4131] Clean up Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@145 --- src/ints/bios_keyboard.cpp | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 156cdcae..428a5924 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -123,27 +123,6 @@ static struct { { 0x5300, 0x532e, none, none } /* Del */ }; -/* -Old Stuff not needed after i ripped Bochs :) -static Bit8u KeyNoShift[128]={ - 27,'1','2','3', '4','5','6','7', '8','9','0','-', '=',8,9,'q', - 'w','e','r','t', 'y','u','i','o', 'p','[',']',13, 255,'a','s','d', - 'f','g','h','j', 'k','l',';','\'', '`',255,'\\','z', 'x','c','v','b', - 'n','m',',','.', '/',255,'*',255, ' ',255,0,0, 0,0,0,0, - 0,0,0,0, 255,255,0,0, 0,'-',0,255, 0,'+',0,0, - 0,0,0,0, 0 -}; - -static Bit8u KeyShift[128]={ - 27,'!','@','#', '$','%','^','&', '*','(',')','_', '+',8,9,'Q', - 'W','E','R','T', 'Y','U','I','O', 'P','{','}',13, 255,'A','S','D', - 'F','G','H','J', 'K','L',':','"', '~',255,'|','Z', 'X','C','V','B', - 'N','M','<','>', '?',255,'*',255, ' ',255,0,0, 0,0,0,0, - 0,0,0,0, 255,255,0,0, 0,'-',0,255, 0,'+',0,0, - 0,0,0,0, 0 -}; -*/ - static void add_key(Bit16u code) { Bit16u start,end,head,tail,ttail; start=mem_readw(BIOS_KEYBOARD_BUFFER_START); @@ -151,10 +130,12 @@ static void add_key(Bit16u code) { head =mem_readw(BIOS_KEYBOARD_BUFFER_HEAD); tail =mem_readw(BIOS_KEYBOARD_BUFFER_TAIL); ttail=tail+2; - if (ttail>=end) ttail=start; + if (ttail>=end) { + ttail=start; + } /* Check for buffer Full */ //TODO Maybe beeeeeeep or something although that should happend when internal buffer is full - if (ttail==head) return; + if (ttail==head) return; real_writew(0x40,tail,code); mem_writew(BIOS_KEYBOARD_BUFFER_TAIL,ttail); } From d69ae5dd06113aa561681a4d799668573d801645 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 12 Aug 2002 17:38:47 +0000 Subject: [PATCH 0069/4131] Old functions removed Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@146 --- src/ints/int10.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index b08c0b1e..8de625b4 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -84,9 +84,7 @@ static Bitu INT10_Handler(void) { INT10_GetPixel(reg_cx,reg_dx,reg_bh,®_al); break; case 0x0E: /* Teletype OutPut */ - //TODO FIX - INT10_TeletypeOutput(reg_al,reg_bl,false,0); -// INT10_TeletypeOutput(reg_al,reg_bl,false,reg_bh); + INT10_TeletypeOutput(reg_al,reg_bl,false,reg_bh); break; case 0x0F: /* Get videomode */ reg_bh=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); @@ -102,7 +100,7 @@ static Bitu INT10_Handler(void) { INT10_SetOverscanBorderColor(reg_bh); break; case 0x02: /* SET ALL PALETTE REGISTERS */ - INT10_SetAllPaletteRegisters(real_phys(Segs[es].value,reg_dx)); + INT10_SetAllPaletteRegisters(Real2Phys(RealMake(Segs[es].value,reg_dx))); break; case 0x03: /* TOGGLE INTENSITY/BLINKING BIT */ INT10_ToggleBlinkingBit(reg_bl); @@ -114,19 +112,19 @@ static Bitu INT10_Handler(void) { INT10_GetOverscanBorderColor(®_bh); break; case 0x09: /* READ ALL PALETTE REGISTERS AND OVERSCAN REGISTER */ - INT10_GetAllPaletteRegisters(real_phys(Segs[es].value,reg_dx)); + INT10_GetAllPaletteRegisters(Real2Phys(RealMake(Segs[es].value,reg_dx))); break; case 0x10: /* SET INDIVIDUAL DAC REGISTER */ INT10_SetSingleDacRegister(reg_bl,reg_dh,reg_ch,reg_cl); break; case 0x12: /* SET BLOCK OF DAC REGISTERS */ - INT10_SetDACBlock(reg_bx,reg_cx,real_phys(Segs[es].value,reg_dx)); + INT10_SetDACBlock(reg_bx,reg_cx,Real2Phys(RealMake(Segs[es].value,reg_dx))); break; case 0x15: /* GET INDIVIDUAL DAC REGISTER */ INT10_GetSingleDacRegister(reg_bl,®_dh,®_ch,®_cl); break; case 0x17: /* GET BLOCK OF DAC REGISTER */ - INT10_GetDACBlock(reg_bx,reg_cx,real_phys(Segs[es].value,reg_dx)); + INT10_GetDACBlock(reg_bx,reg_cx,Real2Phys(RealMake(Segs[es].value,reg_dx))); break; default: LOG_WARN("INT10:10:Unhandled EGA/VGA Palette Function %2X",reg_al); From 537de8d0f69347b49a11c865e862cdfc21dfc38f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 12 Aug 2002 17:56:00 +0000 Subject: [PATCH 0070/4131] changed fcb-parsename Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@147 --- src/dos/dos_files.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 22a18aab..0bf46a71 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -502,10 +502,10 @@ Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u * a[0]= *string;a[1]='\0'; if (strcspn(a,sep)==0) string++; } - if((!(parser &3)) ==true){ // fill name with spaces if no name + if((!(parser &4)) ==true){ // fill name with spaces if no name fcb.Set_filename(naam); } - if((!(parser &4)) ==true){ // fill ext with spaces if no ext + if((!(parser &8)) ==true){ // fill ext with spaces if no ext fcb.Set_ext(ext); } if((parser & 2)==false) fcb.Set_drive(0); //Set allready the defaultdrive (Will stay set when it's not specified) From 92ea87eef6731f935f89f842d710a7f98d357ea6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 13 Aug 2002 04:51:24 +0000 Subject: [PATCH 0071/4131] Shell now has a stack when it first starts Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@148 --- src/shell/shell.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 241e1a5a..acbb79a3 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -19,6 +19,7 @@ #include #include + #include "shell_inc.h" Bitu call_shellstop; @@ -139,6 +140,9 @@ void SHELL_Init() { /* Now call up the shell for the first time */ Bit16u psp_seg=DOS_GetMemory(16); Bit16u env_seg=DOS_GetMemory(1+(4096/16)); + Bit16u stack_seg=DOS_GetMemory(2048/16); + SetSegment_16(ss,stack_seg); + reg_sp=2046; /* Setup a fake MCB for the environment */ MCB * env_mcb=(MCB *)real_host(env_seg,0); env_mcb->psp_segment=psp_seg; From d0b600b4209390e5252b31761769b39600cdced9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 13 Aug 2002 04:52:41 +0000 Subject: [PATCH 0072/4131] Startup new programs correctly Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@149 --- src/shell/shell_misc.cpp | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index bb939ad9..9a97748d 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -145,29 +145,39 @@ void DOS_Shell::Execute(char * name,char * args) { /* Run the .bat file */ bf=new BatchFile(this,fullname,args); } else { - /* Run the .exe or .com file */ - ParamBlock block; + /* Run the .exe or .com file from the shell */ + /* Allocate some stack space for tables in physical memory */ + reg_sp-=0x200; + //Add Parameter block + DOS_ParamBlock block(Real2Phys(RealMake(Segs[ss].value,reg_sp))); + //Add a filename + RealPt file_name=RealMake(Segs[ss].value,reg_sp+0x20); + MEM_BlockWrite(Real2Phys(file_name),fullname,strlen(fullname)+1); /* Fill the command line */ CommandTail cmd; if (strlen(args)>126) args[126]=0; cmd.count=strlen(args); memcpy(cmd.buffer,args,strlen(args)); cmd.buffer[strlen(args)]=0xd; - MEM_BlockWrite(real_phys(prog_info->psp_seg,128),&cmd,128); - block.exec.cmdtail=RealMake(prog_info->psp_seg,128); - block.exec.envseg=0; - block.exec.fcb1=0; - block.exec.fcb2=0; + + block.InitExec(RealMake(prog_info->psp_seg,128)); /* Save CS:IP to some point where i can return them from */ RealPt newcsip; newcsip=CALLBACK_RealPointer(call_shellstop); SetSegment_16(cs,RealSeg(newcsip)); reg_ip=RealOff(newcsip); - - DOS_Execute(fullname,&block,0); - DOSBOX_RunMachine(); - Bit16u blah=0; + /* Start up a dos execute interrupt */ + reg_ax=0x4b00; + //Filename pointer + SetSegment_16(ds,Segs[ss].value); + reg_dx=RealOff(file_name); + //Paramblock + SetSegment_16(es,Segs[ss].value); + reg_bx=reg_sp; + flags.intf=false; + CALLBACK_RunRealInt(0x21); + reg_sp+=0x200; } From 44c0b660fc044662a71c1fa051e11f2717a544cb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 13 Aug 2002 04:53:31 +0000 Subject: [PATCH 0073/4131] RunRealFar and RunRealInt have been fixed. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@150 --- src/cpu/callback.cpp | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 7a66dc7e..da56c405 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -32,7 +32,7 @@ CallBack_Handler CallBack_Handlers[CB_MAX]; -static Bitu call_runint16,call_idle,call_default,call_runfar16; +static Bitu call_stop,call_idle,call_default; static Bitu illegal_handler(void) { E_Exit("Illegal CallBack Called"); @@ -73,23 +73,24 @@ static Bitu stop_handler(void) { void CALLBACK_RunRealFar(Bit16u seg,Bit16u off) { - real_writew((Bit16u)CB_SEG,(call_runfar16<<4)+1,off); - real_writew((Bit16u)CB_SEG,(call_runfar16<<4)+3,seg); + reg_sp-=4; + real_writew(Segs[es].value,reg_sp,call_stop<<4); + real_writew(Segs[es].value,reg_sp+2,CB_SEG); Bit32u oldeip=reg_eip; Bit16u oldcs=Segs[cs].value; - reg_eip=call_runfar16<<4; - SetSegment_16(cs,CB_SEG); + reg_eip=off; + SetSegment_16(cs,seg); DOSBOX_RunMachine(); reg_eip=oldeip; SetSegment_16(cs,oldcs); } void CALLBACK_RunRealInt(Bit8u intnum) { - real_writeb((Bit16u)CB_SEG,(call_runint16<<4)+1,intnum); Bit32u oldeip=reg_eip; Bit16u oldcs=Segs[cs].value; - reg_eip=call_runint16<<4; + reg_eip=call_stop<<4; SetSegment_16(cs,CB_SEG); + Interrupt(intnum); DOSBOX_RunMachine(); reg_eip=oldeip; SetSegment_16(cs,oldcs); @@ -139,20 +140,12 @@ void CALLBACK_Init(void) { for (i=0;i Date: Wed, 14 Aug 2002 22:13:31 +0000 Subject: [PATCH 0074/4131] Extra empty buffer test. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@151 --- src/hardware/keyboard.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index f29cc65e..cc9c85b3 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -63,10 +63,12 @@ static Bit8u read_p61(Bit32u port) { static void write_p61(Bit32u port,Bit8u val) { //TODO Enable spreaker through here :) if ((val&128)) { /* Keyboard acknowledge */ - kbuf_used--; - kbuf_pos++; - if (kbuf_pos>=KEYBUFSIZE) kbuf_pos=0; - if (kbuf_used>0) PIC_ActivateIRQ(1); + if (kbuf_used) { + kbuf_used--; + kbuf_pos++; + if (kbuf_pos>=KEYBUFSIZE) kbuf_pos=0; + if (kbuf_used) PIC_ActivateIRQ(1); + } } port_61_data=val; if ((val & 3)==3) { From 43f6d48932b03d9a0988c4c9ec5c34d2cd837540 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 10:43:55 +0000 Subject: [PATCH 0075/4131] New attribute checking Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@152 --- configure.in | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/configure.in b/configure.in index 395ff766..b5fb6f03 100644 --- a/configure.in +++ b/configure.in @@ -36,11 +36,12 @@ AC_C_INLINE AC_TYPE_SIZE_T AC_STRUCT_TM -dnl Checks for library functions. +#Check if the compiler support attributes +AC_MSG_CHECKING(if compiler allows __attribute__) +AC_TRY_COMPILE([], [typedef struct { } __attribute__ ((packed)) junk;], + [ AC_MSG_RESULT(yes);AC_DEFINE(C_HAS_ATTRIBUTE)],AC_MSG_RESULT(no)) -#Always include the standard include dir in all makefiless - AC_OUTPUT([ Makefile src/Makefile From 1f86dbe81ec13276a9739b7663dbc798671be7bb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 10:44:33 +0000 Subject: [PATCH 0076/4131] New config file, replaces the old settings.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@153 --- config.h.in | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 config.h.in diff --git a/config.h.in b/config.h.in new file mode 100644 index 00000000..8f38384e --- /dev/null +++ b/config.h.in @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +#define VERSION "0.50" + +/* Enable the debugger, this only seems to work in win32 for now. */ +#define C_DEBUG 0 + +/* Enable the logging of extra information for debugging to the console */ +#define C_LOGGING 0 + +/* Use multi threading to speed up things on multi cpu's, also gives a nice frame-skipping effect :) */ +#define C_THREADED 1 + +/* Enable the FPU module, still only for beta testing */ +#define C_FPU 0 + +/* Maximum amount of memory we can support in megabytes*/ +#define C_MEM_MAXSIZE 16 + +/* Maximum memory available for xms, should be lower than maxsize-1 */ +#define C_MEM_XMS_SIZE 8 + +/* Maximum memory available for ems, should be lower than 32 */ +#define C_MEM_EMS_SIZE 4 + + +/* Enable debug messages for several modules, requires C_LOGGING */ +#define DEBUG_SBLASTER 0 /* SoundBlaster Debugging*/ +#define DEBUG_DMA 0 /* DMA Debugging */ +#define DEBUG_DOS 0 /* DOS Debugging */ + +#define LOG_MSG S_Warn + +#if 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 + +/* The internal types */ +typedef unsigned char Bit8u; +typedef signed char Bit8s; +typedef unsigned short Bit16u; +typedef signed short Bit16s; +typedef unsigned long Bit32u; +typedef signed long Bit32s; +typedef double Real64; +#if defined(_MSC_VER) +typedef unsigned __int64 Bit64u; +typedef signed __int64 Bit64s; +#else +typedef unsigned long long Bit64u; +typedef signed long long Bit64s; +#endif + +typedef unsigned int Bitu; +typedef signed int Bits; + + + +/* Use a special def for function inlining */ +#ifdef _MSC_VER +#define INLINE __forceinline +#else +#define INLINE inline +#endif + + + + +/* Do not edit below this line, should all be handled by configure */ + + +// set if your compiler does not understand __attribute__ after a struct +#define C_HAS_ATTRIBUTE 0 +#if C_HAS_ATTRIBUTE +#define GCC_ATTRIBUTE __attribute__ +#else +#define GCC_ATTRIBUTE(x) /* attribute not supported */ +#endif + + +#endif \ No newline at end of file From 4d7db67896514eaa26def4fc01ccc2f7f781e883 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 10:45:43 +0000 Subject: [PATCH 0077/4131] Clean up and removal of setsegment_16 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@154 --- include/cpu.h | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 8a753ec5..17127132 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -29,12 +29,8 @@ typedef Bitu (CPU_Decoder)(Bitu count); extern CPU_Decoder * cpudecoder; extern Bit32u cpu_cycles; - -extern Bit32u hoever; - //CPU Stuff void SetCPU16bit(); -void SetSegment_16(Bit32u seg,Bit16u val); //Types of Flag changing instructions @@ -80,20 +76,11 @@ bool get_SF(void); bool get_OF(void); bool get_PF(void); -Bit8u get_Flags8(void); - - - - #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,PhysPt ea); - #endif From 3342e8bbc2ca202b3c3940e6e742e3439d10c273 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 10:50:05 +0000 Subject: [PATCH 0078/4131] Removed some tables and using new packed structure stuff. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@155 --- include/dos_inc.h | 64 ++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index f042f781..b666e6b3 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -22,13 +22,12 @@ #include #include -#if defined (_MSC_VER) -#pragma pack(1) -#endif +#pragma pack (push,1) + struct CommandTail{ Bit8u count; /* number of bytes returned */ char buffer[127]; /* the buffer itself */ -}; +} GCC_ATTRIBUTE(packed); struct PSP { Bit8u exit[2]; /* CP/M-like exit poimt */ @@ -56,7 +55,7 @@ struct PSP { CommandTail cmdtail; -}; +} GCC_ATTRIBUTE(packed); struct ParamBlock { union { @@ -73,7 +72,8 @@ struct ParamBlock { RealPt initcsip; } exec; }; -}; +} GCC_ATTRIBUTE(packed); + struct MCB { Bit8u type; @@ -81,27 +81,11 @@ struct MCB { Bit16u size; Bit8u unused[3]; Bit8u filename[8]; -}; +} GCC_ATTRIBUTE(packed); + +#pragma pack (pop) + -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 -} -#if defined (_MSC_VER) -; -#pragma pack() -#else -__attribute__ ((packed)); -#endif struct DOS_Date { Bit16u year; @@ -130,7 +114,6 @@ struct DOS_Block { struct { RealPt indosflag; } tables; - }; enum { MCB_FREE=0x0000,MCB_DOS=0x0008 }; @@ -162,20 +145,21 @@ bool DOS_WriteFile(Bit16u handle,Bit8u * data,Bit16u * amount); bool DOS_SeekFile(Bit16u handle,Bit32u * pos,Bit32u type); bool DOS_CloseFile(Bit16u handle); bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry); +bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry); /* Routines for Drive Class */ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry); bool DOS_CreateFile(char * name,Bit16u attribute,Bit16u * entry); bool DOS_UnlinkFile(char * name); bool DOS_FindFirst(char *search,Bit16u attr); bool DOS_FindNext(void); -bool DOS_Canonicalize(char * name,Bit8u * big); +bool DOS_Canonicalize(char * name,char * big); bool DOS_CreateTempFile(char * name,Bit16u * entry); bool DOS_FileExists(char * name); /* Drive Handing Routines */ Bit8u DOS_GetDefaultDrive(void); void DOS_SetDefaultDrive(Bit8u drive); bool DOS_SetDrive(Bit8u drive); -bool DOS_GetCurrentDir(Bit8u drive,Bit8u * buffer); +bool DOS_GetCurrentDir(Bit8u drive,char * bugger); bool DOS_ChangeDir(char * dir); bool DOS_MakeDir(char * dir); bool DOS_RemoveDir(char * dir); @@ -223,7 +207,7 @@ INLINE Bit16u long2para(Bit32u size) { }; INLINE Bit8u RealHandle(Bit16u handle) { - PSP * psp=(PSP *)real_off(dos.psp,0); + PSP * psp=(PSP *)HostMake(dos.psp,0); if (handle>=psp->max_files) return DOS_FILES; return mem_readb(Real2Phys(psp->file_table)+handle); }; @@ -257,7 +241,7 @@ public: off=pt; } DOS_FCB(Bit16u seg, Bit16u offset){ - off=Real2Phys(RealMake(seg,offset)); + off=PhysMake(seg,offset); } void Set_drive(Bit8u a); void Set_filename(char* a); //writes an the first 8 bytes of a as the filename @@ -282,6 +266,24 @@ private: +class DOS_ParamBlock { +public: + DOS_ParamBlock(PhysPt pt){ + off=pt; + }; + void InitExec(RealPt cmdtail); + Bit16u loadseg(void); + Bit16u relocation(void); + Bit16u envseg(void); + RealPt initsssp(void); + RealPt initcsip(void); + RealPt fcb1(void); + RealPt fcb2(void); + RealPt cmdtail(void); +private: + PhysPt off; +}; + #endif From 26fd35e740233135d495d2e760f6f413bde7855e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 10:50:50 +0000 Subject: [PATCH 0079/4131] Removed settings.h and added config.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@156 --- include/dosbox.h | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/include/dosbox.h b/include/dosbox.h index d024ff12..23ed13b6 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -19,13 +19,13 @@ #if !defined __DOSBOX_H #define __DOSBOX_H -typedef unsigned char Bit8u; -typedef signed char Bit8s; -typedef unsigned short Bit16u; -typedef signed short Bit16s; -typedef unsigned long Bit32u; -typedef signed long Bit32s; -typedef double Real64; +typedef unsigned char Bit8u; +typedef signed char Bit8s; +typedef unsigned short Bit16u; +typedef signed short Bit16s; +typedef unsigned long Bit32u; +typedef signed long Bit32s; +typedef double Real64; #if defined(_MSC_VER) typedef unsigned __int64 Bit64u; typedef signed __int64 Bit64s; @@ -44,14 +44,7 @@ void E_Exit(char * message,...); 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 - typedef Bitu (LoopHandler)(void); From 81b2a872fb7df7c83f413b8780a48e3d093ca6f3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 10:51:35 +0000 Subject: [PATCH 0080/4131] New segment structure and usage. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@157 --- include/regs.h | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/include/regs.h b/include/regs.h index 7d8ed5d6..d4bd3c49 100644 --- a/include/regs.h +++ b/include/regs.h @@ -36,13 +36,12 @@ struct Flag_Info { }; struct Segment { - Bit16u value; - bool special; /* Signal for pointing to special memory */ - HostPt host; /* The address of start in host memory */ - PhysPt phys; /* The phyiscal address start in emulated machine */ + Bit16u val; + PhysPt phys; /* The phyiscal address start in emulated machine */ }; -enum { cs=0,ds,es,fs,gs,ss}; + +enum SegNames { cs=0,ds,es,fs,gs,ss}; struct CPU_Regs { union { @@ -58,10 +57,30 @@ extern Segment Segs[6]; extern Flag_Info flags; extern CPU_Regs cpu_regs; -void SetSegment_16(Bit32u seg,Bit16u val); + +//#define SegPhys(index) Segs[index].phys +//#define SegValue(index) Segs[index].val + +INLINE PhysPt SegPhys(SegNames index) { + return Segs[index].phys; +} + +INLINE Bit16u SegValue(SegNames index) { + return Segs[index].val; +} + + +INLINE RealPt RealMakeSeg(SegNames index,Bit16u off) { + return RealMake(SegValue(index),off); +} + + +INLINE void SegSet16(Bitu index,Bit16u val) { + Segs[index].val=val; + Segs[index].phys=val << 4; +} -//extern Bit8u & reg_al=cpu_regs.ax.b.l; enum REG_NUM { REG_NUM_AX, REG_NUM_CX, REG_NUM_DX, REG_NUM_BX, REG_NUM_SP, REG_NUM_BP, REG_NUM_SI, REG_NUM_DI From 2ae43c7636049cd78d6d5843fa5d4e980cde0a7e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:33:51 +0000 Subject: [PATCH 0081/4131] New segments and no more default interrupt handles. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@158 --- src/cpu/callback.cpp | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index da56c405..d10d5e7f 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -52,13 +52,13 @@ Bitu CALLBACK_Allocate(void) { void CALLBACK_Idle(void) { /* this makes the cpu execute instructions to handle irq's and then come back */ - Bit16u oldcs=Segs[cs].value; + Bit16u oldcs=SegValue(cs); Bit32u oldeip=reg_eip; - SetSegment_16(cs,CB_SEG); + SegSet16(cs,CB_SEG); reg_eip=call_idle<<4; DOSBOX_RunMachine(); reg_eip=oldeip; - SetSegment_16(cs,oldcs); + SegSet16(cs,oldcs); } static Bitu default_handler(void) { @@ -74,40 +74,40 @@ static Bitu stop_handler(void) { void CALLBACK_RunRealFar(Bit16u seg,Bit16u off) { reg_sp-=4; - real_writew(Segs[es].value,reg_sp,call_stop<<4); - real_writew(Segs[es].value,reg_sp+2,CB_SEG); + mem_writew(SegPhys(ss)+reg_sp,call_stop<<4); + mem_writew(SegPhys(ss)+reg_sp+2,CB_SEG); Bit32u oldeip=reg_eip; - Bit16u oldcs=Segs[cs].value; + Bit16u oldcs=SegValue(cs); reg_eip=off; - SetSegment_16(cs,seg); + SegSet16(cs,seg); DOSBOX_RunMachine(); reg_eip=oldeip; - SetSegment_16(cs,oldcs); + SegSet16(cs,oldcs); } void CALLBACK_RunRealInt(Bit8u intnum) { Bit32u oldeip=reg_eip; - Bit16u oldcs=Segs[cs].value; + Bit16u oldcs=SegValue(cs); reg_eip=call_stop<<4; - SetSegment_16(cs,CB_SEG); + SegSet16(cs,CB_SEG); Interrupt(intnum); DOSBOX_RunMachine(); reg_eip=oldeip; - SetSegment_16(cs,oldcs); + SegSet16(cs,oldcs); } void CALLBACK_SZF(bool val) { - Bit16u tempf=real_readw(Segs[ss].value,reg_sp+4) & 0xFFBF; + Bit16u tempf=mem_readw(SegPhys(ss)+reg_sp+4) & 0xFFBF; Bit16u newZF=(val==true) << 6; - real_writew(Segs[ss].value,reg_sp+4,(tempf | newZF)); + mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newZF)); }; void CALLBACK_SCF(bool val) { - Bit16u tempf=real_readw(Segs[ss].value,reg_sp+4) & 0xFFFE; + Bit16u tempf=mem_readw(SegPhys(ss)+reg_sp+4) & 0xFFFE; Bit16u newCF=(val==true); - real_writew(Segs[ss].value,reg_sp+4,(tempf | newCF)); + mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newCF)); }; @@ -153,12 +153,15 @@ void CALLBACK_Init(void) { real_writeb((Bit16u)CB_SEG,(call_idle<<4)+12,0xFE); real_writeb((Bit16u)CB_SEG,(call_idle<<4)+13,0x38); real_writew((Bit16u)CB_SEG,(call_idle<<4)+14,call_idle); + +#if C_DEBUG /* Setup all Interrupt to point to the default handler */ call_default=CALLBACK_Allocate(); CALLBACK_Setup(call_default,&default_handler,CB_IRET); for (i=0;i<256;i++) { real_writed(0,i*4,CALLBACK_RealPointer(call_default)); } +#endif } From 77f4c055defd2d07d74dd69c6c0dbecb751abdc4 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:34:52 +0000 Subject: [PATCH 0082/4131] New segments and removed setsegemnt16 function Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@159 --- src/cpu/cpu.cpp | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 82a94c53..fbebd898 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -86,7 +86,7 @@ void Interrupt(Bit8u num) { case 0xcd: E_Exit("Call to interrupt 0xCD this is BAD"); case 0x03: -#ifdef C_DEBUG +#if C_DEBUG if (DEBUG_BreakPoint()) return; #endif break; @@ -117,15 +117,15 @@ void Interrupt(Bit8u num) { flags.tf=false; /* Save everything on a 16-bit stack */ reg_sp-=2; - mem_writew(Segs[ss].phys+reg_sp,pflags); + mem_writew(SegPhys(ss)+reg_sp,pflags); reg_sp-=2; - mem_writew(Segs[ss].phys+reg_sp,Segs[cs].value); + mem_writew(SegPhys(ss)+reg_sp,SegValue(cs)); reg_sp-=2; - mem_writew(Segs[ss].phys+reg_sp,reg_ip); + mem_writew(SegPhys(ss)+reg_sp,reg_ip); /* Get the new CS:IP from vector table */ Bit16u newip=mem_readw(num << 2); Bit16u newcs=mem_readw((num <<2)+2); - SetSegment_16(cs,newcs); + SegSet16(cs,newcs); reg_ip=newip; } @@ -136,15 +136,6 @@ void SetCPU16bit() CPU_Real_16_Slow_Start(); } -void SetSegment_16(Bit32u seg,Bit16u val) { - Segs[seg].value=val; - Bit32u off=(val << 4); - Segs[seg].host=memory+off; - Segs[seg].phys=off; - //TODO Maybe use this feature one day :) - // Segs[seg].special=MEMORY_TestSpecial(off); -}; - void CPU_Init(void) { reg_eax=0; @@ -156,12 +147,12 @@ void CPU_Init(void) { reg_ebp=0; reg_esp=0; - SetSegment_16(cs,0); - SetSegment_16(ds,0); - SetSegment_16(es,0); - SetSegment_16(fs,0); - SetSegment_16(gs,0); - SetSegment_16(ss,0); + SegSet16(cs,0); + SegSet16(ds,0); + SegSet16(es,0); + SegSet16(fs,0); + SegSet16(gs,0); + SegSet16(ss,0); reg_eip=0; flags.type=t_UNKNOWN; From 8c2ba5ad6362a09377daeb9951b1045efe4312d0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:37:37 +0000 Subject: [PATCH 0083/4131] Cleaned up some old #defines Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@160 --- src/cpu/core_16/support.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/cpu/core_16/support.h b/src/cpu/core_16/support.h index e6008cd9..34c4e73f 100644 --- a/src/cpu/core_16/support.h +++ b/src/cpu/core_16/support.h @@ -18,25 +18,13 @@ 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)); } From d30a5b8a3952cf921580a47cef04dffd3eb02f70 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:37:51 +0000 Subject: [PATCH 0084/4131] New segments. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@161 --- src/cpu/core_16/main.h | 58 ++++++++++++++++++------------------- src/cpu/core_16/prefix_of.h | 12 ++++---- src/cpu/slow_16.cpp | 8 ++--- 3 files changed, 38 insertions(+), 40 deletions(-) diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 12e70963..075e5655 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -32,9 +32,9 @@ restart: case 0x05: /* ADD AX,Iw */ AXIw(ADDW);break; case 0x06: /* PUSH ES */ - Push_16(Segs[es].value);break; + Push_16(SegValue(es));break; case 0x07: /* POP ES */ - SetSegment_16(es,Pop_16());break; + SegSet16(es,Pop_16());break; case 0x08: /* OR Eb,Gb */ RMEbGb(ORB);break; case 0x09: /* OR Ew,Gw */ @@ -48,7 +48,7 @@ restart: case 0x0d: /* OR AX,Iw */ AXIw(ORW);break; case 0x0e: /* PUSH CS */ - Push_16(Segs[cs].value);break; + Push_16(SegValue(cs));break; case 0x0f: /* 2 byte opcodes*/ #include "prefix_of.h" break; @@ -65,9 +65,9 @@ restart: case 0x15: /* ADC AX,Iw */ AXIw(ADCW);break; case 0x16: /* PUSH SS */ - Push_16(Segs[ss].value);break; + Push_16(SegValue(ss));break; case 0x17: /* POP SS */ - SetSegment_16(ss,Pop_16());break; + SegSet16(ss,Pop_16());break; case 0x18: /* SBB Eb,Gb */ RMEbGb(SBBB);break; case 0x19: /* SBB Ew,Gw */ @@ -81,9 +81,9 @@ restart: case 0x1d: /* SBB AX,Iw */ AXIw(SBBW);break; case 0x1e: /* PUSH DS */ - Push_16(Segs[ds].value);break; + Push_16(SegValue(ds));break; case 0x1f: /* POP DS */ - SetSegment_16(ds,Pop_16());break; + SegSet16(ds,Pop_16());break; case 0x20: /* AND Eb,Gb */ RMEbGb(ANDB);break; case 0x21: /* AND Ew,Gw */ @@ -524,17 +524,17 @@ restart: GetRM;Bit16u val; switch (rm & 0x38) { case 0x00: /* MOV Ew,ES */ - val=Segs[es].value;break; + val=SegValue(es);break; case 0x08: /* MOV Ew,CS */ - val=Segs[cs].value;break; + val=SegValue(cs);break; case 0x10: /* MOV Ew,SS */ - val=Segs[ss].value;break; + val=SegValue(ss);break; case 0x18: /* MOV Ew,DS */ - val=Segs[ds].value;break; + val=SegValue(ds);break; case 0x20: /* MOV Ew,FS */ - val=Segs[fs].value;break; + val=SegValue(fs);break; case 0x28: /* MOV Ew,GS */ - val=Segs[gs].value;break; + val=SegValue(gs);break; default: val=0; E_Exit("CPU:8c:Illegal RM Byte"); @@ -583,18 +583,18 @@ restart: else {GetEAa;val=LoadMw(eaa);} switch (rm & 0x38) { case 0x00: /* MOV ES,Ew */ - SetSegment_16(es,val);break; + SegSet16(es,val);break; case 0x08: /* MOV CS,Ew Illegal*/ E_Exit("CPU:Illegal MOV CS Call"); break; case 0x10: /* MOV SS,Ew */ - SetSegment_16(ss,val);break; + SegSet16(ss,val);break; case 0x18: /* MOV DS,Ew */ - SetSegment_16(ds,val);break; + SegSet16(ds,val);break; case 0x20: /* MOV FS,Ew */ - SetSegment_16(fs,val);break; + SegSet16(fs,val);break; case 0x28: /* MOV GS,Ew */ - SetSegment_16(gs,val);break; + SegSet16(gs,val);break; default: E_Exit("CPU:8e:Illegal RM Byte"); } @@ -639,8 +639,8 @@ restart: case 0x9a: /* CALL Ap */ { Bit16u newip=Fetchw();Bit16u newcs=Fetchw(); - Push_16(Segs[cs].value);Push_16(GETIP); - SetSegment_16(cs,newcs);SETIP(newip); + Push_16(SegValue(cs));Push_16(GETIP); + SegSet16(cs,newcs);SETIP(newip); break; } case 0x9b: /* WAIT */ @@ -838,13 +838,13 @@ restart: case 0xc4: /* LES */ { GetRMrw;GetEAa; - *rmrw=LoadMw(eaa);SetSegment_16(es,LoadMw(eaa+2)); + *rmrw=LoadMw(eaa);SegSet16(es,LoadMw(eaa+2)); break; } case 0xc5: /* LDS */ { GetRMrw;GetEAa; - *rmrw=LoadMw(eaa);SetSegment_16(ds,LoadMw(eaa+2)); + *rmrw=LoadMw(eaa);SegSet16(ds,LoadMw(eaa+2)); break; } case 0xc6: /* MOV Eb,Ib */ @@ -876,13 +876,13 @@ restart: { Bit16u addsp=Fetchw(); Bit16u newip=Pop_16();Bit16u newcs=Pop_16(); - reg_sp+=addsp;SetSegment_16(cs,newcs);SETIP(newip); + reg_sp+=addsp;SegSet16(cs,newcs);SETIP(newip); break; } case 0xcb: /* RETF */ { Bit16u newip=Pop_16();Bit16u newcs=Pop_16(); - SetSegment_16(cs,newcs);SETIP(newip); + SegSet16(cs,newcs);SETIP(newip); } break; case 0xcc: /* INT3 */ @@ -900,7 +900,7 @@ restart: case 0xcf: /* IRET */ { Bit16u newip=Pop_16();Bit16u newcs=Pop_16(); - SetSegment_16(cs,newcs);SETIP(newip); + SegSet16(cs,newcs);SETIP(newip); Bit16u pflags=Pop_16();Save_Flagsw(pflags); break; } @@ -1018,7 +1018,7 @@ restart: { Bit16u newip=Fetchw(); Bit16u newcs=Fetchw(); - SetSegment_16(cs,newcs); + SegSet16(cs,newcs); SETIP(newip); break; } @@ -1466,11 +1466,11 @@ restart: break; case 0x18: /* CALL Ep */ { - Push_16(Segs[cs].value); + Push_16(SegValue(cs)); GetEAa;Push_16(GETIP); Bit16u newip=LoadMw(eaa); Bit16u newcs=LoadMw(eaa+2); - SetSegment_16(cs,newcs); + SegSet16(cs,newcs); SETIP(newip); } break; @@ -1483,7 +1483,7 @@ restart: GetEAa; Bit16u newip=LoadMw(eaa); Bit16u newcs=LoadMw(eaa+2); - SetSegment_16(cs,newcs); + SegSet16(cs,newcs); SETIP(newip); } break; diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h index 2010372c..e92594d8 100644 --- a/src/cpu/core_16/prefix_of.h +++ b/src/cpu/core_16/prefix_of.h @@ -155,9 +155,9 @@ switch(Fetchb()) { SETcc((get_SF() == get_OF()) && !get_ZF());break; case 0xa0: /* PUSH FS */ - Push_16(Segs[fs].value);break; + Push_16(SegValue(fs));break; case 0xa1: /* POP FS */ - SetSegment_16(fs,Pop_16());break; + SegSet16(fs,Pop_16());break; /* 0xa2 CPUID */ case 0xa3: /* BT Ew,Gw */ { @@ -190,9 +190,9 @@ switch(Fetchb()) { /* 0xa6 XBTS (early 386 only) CMPXCHG (early 486 only) */ /* 0xa7 IBTS (early 386 only) CMPXCHG (early 486 only) */ case 0xa8: /* PUSH GS */ - Push_16(Segs[gs].value);break; + Push_16(SegValue(gs));break; case 0xa9: /* POP GS */ - SetSegment_16(gs,Pop_16());break; + SegSet16(gs,Pop_16());break; /* 0xaa RSM */ case 0xab: /* BTS Ew,Gw */ { @@ -258,13 +258,13 @@ switch(Fetchb()) { case 0xb4: /* LFS */ { GetRMrw;GetEAa; - *rmrw=LoadMw(eaa);SetSegment_16(fs,LoadMw(eaa+2)); + *rmrw=LoadMw(eaa);SegSet16(fs,LoadMw(eaa+2)); break; } case 0xb5: /* LGS */ { GetRMrw;GetEAa; - *rmrw=LoadMw(eaa);SetSegment_16(gs,LoadMw(eaa+2)); + *rmrw=LoadMw(eaa);SegSet16(gs,LoadMw(eaa+2)); break; } case 0xb6: /* MOVZX Gw,Eb */ diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp index aaed2d80..30df16c0 100644 --- a/src/cpu/slow_16.cpp +++ b/src/cpu/slow_16.cpp @@ -25,9 +25,7 @@ #include "fpu.h" typedef PhysPt EAPoint; - -#define SegBase(seg) Segs[seg].phys - +#define SegBase(c) SegPhys(c) #define LoadMb(off) mem_readb(off) #define LoadMw(off) mem_readw(off) #define LoadMd(off) mem_readd(off) @@ -52,7 +50,7 @@ extern Bitu cycle_count; /* Enable parts of the cpu emulation */ #define CPU_386 //Enable 386 instructions -#ifdef C_FPU +#if C_FPU #define CPU_FPU //Enable FPU escape instructions #endif @@ -61,7 +59,7 @@ static Bitu CPU_Real_16_Slow_Decode_Special(Bitu count); static Bitu CPU_Real_16_Slow_Decode(Bitu count) { #include "core_16/start.h" while (count) { -#ifdef C_DEBUG +#if C_DEBUG cycle_count++; #endif count--; From 59b55b0576badfa68de267c02540c11bbb110a74 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:39:27 +0000 Subject: [PATCH 0085/4131] New paramblock class and the wip of psp. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@162 --- src/dos/dos_classes.cpp | 244 +++++++++++++++++++++++++++------------- 1 file changed, 165 insertions(+), 79 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 74098aec..6d99cef5 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -21,6 +21,7 @@ #include "dosbox.h" #include "mem.h" #include "dos_inc.h" +#include "support.h" /* Work in progress, making classes for handling certain internal memory structures in dos @@ -28,6 +29,7 @@ dos work a bit easier. */ +#pragma pack (push,1) struct sPSP { Bit8u exit[2]; /* CP/M-like exit poimt */ @@ -52,130 +54,214 @@ struct sPSP { 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; - -}; +} GCC_ATTRIBUTE(packed); + +union sParamBlock { + struct { + Bit16u loadseg; + Bit16u relocation; + } overlay; + struct { + Bit16u envseg; + RealPt cmdtail; + RealPt fcb1; + RealPt fcb2; + RealPt initsssp; + RealPt initcsip; + } exec; +} GCC_ATTRIBUTE(packed); + +struct sFCB { + 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 +} GCC_ATTRIBUTE(packed); + +#pragma pack (pop) + +#define sGet(s,m) GetIt(((s *)0)->m,(PhysPt)&(((s *)0)->m)) +#define sSave(s,m,val) SaveIt(((s *)0)->m,(PhysPt)&(((s *)0)->m),val) - -class DOS_PSP { +class MemStruct { public: - DOS_PSP(Bit16u segment); + Bit8u GetIt(Bit8u,PhysPt addr) { + return mem_readb(pt+addr); + }; + Bit16u GetIt(Bit16u,PhysPt addr) { + return mem_readw(pt+addr); + }; + Bit32u GetIt(Bit32u,PhysPt addr) { + return mem_readd(pt+addr); + }; + void SaveIt(Bit8u,PhysPt addr,Bit8u val) { + mem_writeb(pt+addr,val); + }; + void SaveIt(Bit16u,PhysPt addr,Bit16u val) { + mem_writew(pt+addr,val); + }; + void SaveIt(Bit32u,PhysPt addr,Bit32u val) { + mem_writed(pt+addr,val); + }; - void MakeNew(Bit16u env,Bit16u memsize); - - - Bit16u base_seg; private: - PhysPt off; +PhysPt pt; + }; -DOS_PSP::DOS_PSP(Bit16u segment) { - base_seg=segment; - off=Real2Phys(RealMake(segment,0)); + +class DOS_PSP :public MemStruct { +public: + DOS_PSP(Bit16u segment){NewPt(segment);}; + void NewPt(Bit16u segment); + void MakeNew(Bit16u mem_size); + Bit8u GetFileHandle(Bitu index); + +private: + Bit16u seg; + PhysPt pt; }; -void DOS_PSP::MakeNew(Bit16u env,Bit16u next_para) { +void DOS_PSP::NewPt(Bit16u segment) { + seg=segment; + pt=PhysMake(segment,0); +}; + + + +void DOS_PSP::MakeNew(Bit16u mem_size) { Bitu i; - for (i=0;i<256;i++) mem_writeb(off+i,0); -/* Standard blocks */ - mem_writeb(off+offsetof(sPSP,exit[0]),0xcd); - mem_writeb(off+offsetof(sPSP,exit[1]),0x20); - - mem_writeb(off+offsetof(sPSP,service[0]),0xcd); - mem_writeb(off+offsetof(sPSP,service[1]),0x21); - mem_writeb(off+offsetof(sPSP,service[2]),0xcb); - - mem_writew(off+offsetof(sPSP,next_seg),next_para); - - -// mem_writew(off+offsetof(sPSP,psp_parent),dos.psp->base_seg); - - /* Setup initial file table */ - mem_writed(off+offsetof(sPSP,int_22),RealGetVec(0x22)); - mem_writed(off+offsetof(sPSP,int_23),RealGetVec(0x23)); - mem_writed(off+offsetof(sPSP,int_24),RealGetVec(0x24)); - - -#if 0 - - newpsp->mem_size=prevpsp->mem_size; - newpsp->environment=0; - - newpsp->int_22.full=real_getvec(0x22); - newpsp->int_23.full=real_getvec(0x23); - newpsp->int_24.full=real_getvec(0x24); - - newpsp->psp_parent=dos.psp; - newpsp->prev_psp.full=0xFFFFFFFF; - - Bit32u i; - Bit8u * prevfile=real_off(prevpsp->file_table.seg,prevpsp->file_table.off); - for (i=0;i<20;i++) newpsp->files[i]=prevfile[i]; - - newpsp->max_files=20; - newpsp->file_table.seg=pspseg; - newpsp->file_table.off=offsetof(PSP,files); - /* Save the old DTA in this psp */ - newpsp->dta.seg=dos.dta.seg; - newpsp->dta.off=dos.dta.off; - /* Setup the DTA */ - dos.dta.seg=pspseg; - dos.dta.off=0x80; - return; -#endif - + /* Clear it first */ + for (i=0;i<256;i++) mem_writeb(pt+i,0); + /* Standard blocks,int 20 and int21 retf */ + sGet(sPSP,max_files); + sSave(sPSP,exit[0],0xcd); + sSave(sPSP,exit[1],0x20); + sSave(sPSP,service[0],0xcd); + sSave(sPSP,service[1],0x21); + sSave(sPSP,service[2],0xcb); + /* psp and psp-parent */ + sSave(sPSP,psp_parent,dos.psp); + sSave(sPSP,prev_psp,RealMake(dos.psp,0)); + /* terminate 22,break 23,crititcal error 24 address stored */ + sSave(sPSP,int_22,RealGetVec(0x22)); + sSave(sPSP,int_23,RealGetVec(0x23)); + sSave(sPSP,int_24,RealGetVec(0x24)); + /* Memory size */ + sSave(sPSP,next_seg,seg+mem_size); + /* Process DTA */ + sSave(sPSP,dta,RealMake(seg,128)); + /* User Stack pointer */ + //Copy from previous psp + // mem_writed(pt+offsetof(sPSP,stack), + /* Init file pointer and max_files */ + sSave(sPSP,file_table,RealMake(seg,offsetof(sPSP,files[0]))); + sSave(sPSP,max_files,20); + /* Copy file table from calling process */ + for (i=0;i<20;i++) { + Bit8u handle=0; + // Bitu handle=dos.psp.GetFileHandle(i); + sSave(sPSP,files[i],handle); + } } +Bit8u DOS_PSP::GetFileHandle(Bitu index) { + if (index>=sGet(sPSP,max_files)) return 0xff; + PhysPt files=Real2Phys(sGet(sPSP,file_table)); + return mem_readb(files+index); +}; + void DOS_FCB::Set_drive(Bit8u a){ - mem_writeb(off+offsetof(FCB,drive),a); + mem_writeb(off+offsetof(sFCB,drive),a); } void DOS_FCB::Set_filename(char * a){ - MEM_BlockWrite(off+offsetof(FCB,filename),a,8); + MEM_BlockWrite(off+offsetof(sFCB,filename),a,8); } void DOS_FCB::Set_ext(char * a) { - MEM_BlockWrite(off+offsetof(FCB,ext),a,3); + MEM_BlockWrite(off+offsetof(sFCB,ext),a,3); } void DOS_FCB::Set_current_block(Bit16u a){ - mem_writew(off+offsetof(FCB,current_block),a); + mem_writew(off+offsetof(sFCB,current_block),a); } void DOS_FCB::Set_record_size(Bit16u a){ - mem_writew(off+offsetof(FCB,record_size),a); + mem_writew(off+offsetof(sFCB,record_size),a); } void DOS_FCB::Set_filesize(Bit32u a){ - mem_writed(off+offsetof(FCB,filesize),a); + mem_writed(off+offsetof(sFCB,filesize),a); } void DOS_FCB::Set_date(Bit16u a){ - mem_writew(off+offsetof(FCB,date),a); + mem_writew(off+offsetof(sFCB,date),a); } void DOS_FCB::Set_time(Bit16u a){ - mem_writew(off+offsetof(FCB,time),a); + mem_writew(off+offsetof(sFCB,time),a); } Bit8u DOS_FCB::Get_drive(void){ - return mem_readb(off+offsetof(FCB,drive)); + return mem_readb(off+offsetof(sFCB,drive)); } void DOS_FCB::Get_filename(char * a){ - MEM_BlockRead(off+offsetof(FCB,filename),a,8); + MEM_BlockRead(off+offsetof(sFCB,filename),a,8); } void DOS_FCB::Get_ext(char * a){ - MEM_BlockRead(off+offsetof(FCB,ext),a,3); + MEM_BlockRead(off+offsetof(sFCB,ext),a,3); } Bit16u DOS_FCB::Get_current_block(void){ - return mem_readw(off+offsetof(FCB,current_block)); + return mem_readw(off+offsetof(sFCB,current_block)); } Bit16u DOS_FCB::Get_record_size(void){ - return mem_readw(off+offsetof(FCB,record_size)); + return mem_readw(off+offsetof(sFCB,record_size)); } Bit32u DOS_FCB::Get_filesize(void){ - return mem_readd(off+offsetof(FCB,filesize)); + return mem_readd(off+offsetof(sFCB,filesize)); } Bit16u DOS_FCB::Get_date(void){ - return mem_readw(off+offsetof(FCB,date)); + return mem_readw(off+offsetof(sFCB,date)); } Bit16u DOS_FCB::Get_time(void){ - return mem_readw(off+offsetof(FCB,time)); + return mem_readw(off+offsetof(sFCB,time)); } + + +void DOS_ParamBlock::InitExec(RealPt cmdtail) { + mem_writew(off+offsetof(sParamBlock,exec.envseg),0); + mem_writed(off+offsetof(sParamBlock,exec.fcb1),0); + mem_writed(off+offsetof(sParamBlock,exec.fcb2),0); + mem_writed(off+offsetof(sParamBlock,exec.cmdtail),cmdtail); +} + +Bit16u DOS_ParamBlock::loadseg(void) { + return mem_readw(off+offsetof(sParamBlock,overlay.loadseg)); +} +Bit16u DOS_ParamBlock::relocation(void){ + return mem_readw(off+offsetof(sParamBlock,overlay.loadseg)); +} +Bit16u DOS_ParamBlock::envseg(void){ + return mem_readw(off+offsetof(sParamBlock,exec.envseg)); +} +RealPt DOS_ParamBlock::initsssp(void){ + return mem_readd(off+offsetof(sParamBlock,exec.initsssp)); +} +RealPt DOS_ParamBlock::initcsip(void){ + return mem_readd(off+offsetof(sParamBlock,exec.initcsip)); +} +RealPt DOS_ParamBlock::fcb1(void){ + return mem_readd(off+offsetof(sParamBlock,exec.fcb1)); +} +RealPt DOS_ParamBlock::fcb2(void){ + return mem_readd(off+offsetof(sParamBlock,exec.fcb2)); +} +RealPt DOS_ParamBlock::cmdtail(void){ + return mem_readd(off+offsetof(sParamBlock,exec.cmdtail)); +} + From 31cb583329706153f067dcfd5e62fe4ddd861a3c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:40:32 +0000 Subject: [PATCH 0086/4131] New segment and new force duplicate file handle function. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@163 --- src/dos/dos.cpp | 95 ++++++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 44 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 9827c072..33439ad1 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -105,7 +105,7 @@ static Bitu DOS_21Handler(void) { case 0x09: /* Write string to STDOUT */ { Bit8u c;Bit16u n=1; - PhysPt buf=real_phys(Segs[ds].value,reg_dx); + PhysPt buf=SegPhys(ds)+reg_dx; while ((c=mem_readb(buf++))!='$') { DOS_WriteFile(STDOUT,&c,&n); } @@ -114,7 +114,7 @@ static Bitu DOS_21Handler(void) { case 0x0a: /* Buffered Input */ { //TODO ADD Break checkin in STDIN but can't care that much for it - PhysPt data=real_phys(Segs[ds].value,reg_dx); + PhysPt data=SegPhys(ds)+reg_dx; Bit8u free=mem_readb(data); Bit8u read=0;Bit8u c;Bit16u n=1; if (!free) break; @@ -164,7 +164,7 @@ static Bitu DOS_21Handler(void) { reg_al=26; break; case 0x0f: /* Open File using FCB */ - if(DOS_FCBOpen(Segs[ds].value,reg_dx)){ + if(DOS_FCBOpen(SegValue(ds),reg_dx)){ reg_al=0; }else{ reg_al=0xff; @@ -173,7 +173,7 @@ static Bitu DOS_21Handler(void) { break; case 0x10: /* Close File using FCB */ - if(DOS_FCBClose(Segs[ds].value,reg_dx)){ + if(DOS_FCBClose(SegValue(ds),reg_dx)){ reg_al=0; }else{ reg_al=0xff; @@ -182,7 +182,7 @@ static Bitu DOS_21Handler(void) { break; case 0x11: /* Find First Matching File using FCB */ - if(DOS_FCBFindFirst(Segs[ds].value,reg_dx)){ + if(DOS_FCBFindFirst(SegValue(ds),reg_dx)){ reg_al=0; }else{ reg_al=0xff; @@ -191,7 +191,7 @@ static Bitu DOS_21Handler(void) { break; case 0x12: /* Find Next Matching File using FCB */ - if(DOS_FCBFindNext(Segs[ds].value,reg_dx)){ + if(DOS_FCBFindNext(SegValue(ds),reg_dx)){ reg_al=0; }else{ reg_al=0xff; @@ -218,8 +218,8 @@ static Bitu DOS_21Handler(void) { case 0x29: /* Parse filename into FCB */ { Bit8u difference; char string[1024]; - MEM_StrCopy(Real2Phys(RealMake(Segs[ds].value,reg_si)) ,string,1024); - reg_al=FCB_Parsename(Segs[es].value,reg_di,reg_al ,string, &difference); + MEM_StrCopy(SegPhys(ds)+reg_si,string,1024); + reg_al=FCB_Parsename(SegValue(es),reg_di,reg_al ,string, &difference); reg_di+=difference; } LOG_DEBUG("DOS:29:FCB Parse Filename, result:al=%d",reg_al); @@ -237,12 +237,12 @@ static Bitu DOS_21Handler(void) { reg_al=DOS_GetDefaultDrive(); break; case 0x1a: /* Set Disk Transfer Area Address */ - dos.dta=RealMake(Segs[ds].value,reg_dx); + dos.dta=RealMakeSeg(ds,reg_dx); break; case 0x1c: /* Get allocation info for specific drive */ LOG_DEBUG("DOS: Allocation Info call not supported correctly"); - SetSegment_16(ds,0xf000); + SegSet16(ds,0xf000); reg_bx=0; real_writeb(0xf000,0,0); reg_al=0x7f; @@ -251,7 +251,7 @@ static Bitu DOS_21Handler(void) { break; /* TODO maybe but hardly think a game needs this */ case 0x1b: /* Get allocation info for default drive */ LOG_DEBUG("DOS: Allocation Info call not supported correctly"); - SetSegment_16(ds,0xf000); + SegSet16(ds,0xf000); reg_bx=0; real_writeb(0xf000,0,0); reg_al=0x7f; @@ -263,7 +263,7 @@ static Bitu DOS_21Handler(void) { E_Exit("DOS:Unhandled call %02X",reg_ah); break; /* TODO maybe but hardly think a game needs this */ case 0x25: /* Set Interrupt Vector */ - RealSetVec(reg_al,RealMake(Segs[ds].value,reg_dx)); + RealSetVec(reg_al,RealMakeSeg(ds,reg_dx)); break; case 0x26: /* Create new PSP */ DOS_NewPSP(reg_dx); @@ -303,7 +303,7 @@ static Bitu DOS_21Handler(void) { dos.verify=(reg_al==1); break; case 0x2f: /* Get Disk Transfer Area */ - SetSegment_16(es,RealSeg(dos.dta)); + SegSet16(es,RealSeg(dos.dta)); reg_bx=RealOff(dos.dta); break; case 0x30: /* Get DOS Version */ @@ -341,12 +341,12 @@ static Bitu DOS_21Handler(void) { } break; case 0x34: /* Get INDos Flag */ - SetSegment_16(es,RealSeg(dos.tables.indosflag)); + SegSet16(es,RealSeg(dos.tables.indosflag)); reg_bx=RealOff(dos.tables.indosflag); break; case 0x35: /* Get interrupt vector */ reg_bx=real_readw(0,((Bit16u)reg_al)*4); - SetSegment_16(es,real_readw(0,((Bit16u)reg_al)*4+2)); + SegSet16(es,real_readw(0,((Bit16u)reg_al)*4+2)); break; case 0x36: /* Get Free Disk Space */ { @@ -387,7 +387,7 @@ static Bitu DOS_21Handler(void) { } break; case 0x39: /* MKDIR Create directory */ - MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_MakeDir(name1)) { CALLBACK_SCF(false); } else { @@ -396,7 +396,7 @@ static Bitu DOS_21Handler(void) { } break; case 0x3a: /* RMDIR Remove directory */ - MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_RemoveDir(name1)) { CALLBACK_SCF(false); } else { @@ -405,7 +405,7 @@ static Bitu DOS_21Handler(void) { } break; case 0x3b: /* CHDIR Set current directory */ - MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_ChangeDir(name1)) { CALLBACK_SCF(false); } else { @@ -414,7 +414,7 @@ static Bitu DOS_21Handler(void) { } break; case 0x3c: /* CREATE Create of truncate file */ - MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_CreateFile(name1,reg_cx,®_ax)) { CALLBACK_SCF(false); } else { @@ -423,7 +423,7 @@ static Bitu DOS_21Handler(void) { } break; case 0x3d: /* OPEN Open existing file */ - MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_OpenFile(name1,reg_al,®_ax)) { CALLBACK_SCF(false); } else { @@ -443,7 +443,7 @@ static Bitu DOS_21Handler(void) { { Bit16u toread=reg_cx; if (DOS_ReadFile(reg_bx,dos_copybuf,&toread)) { - MEM_BlockWrite(real_phys(Segs[ds].value,reg_dx),dos_copybuf,toread); + MEM_BlockWrite(SegPhys(ds)+reg_dx,dos_copybuf,toread); reg_ax=toread; CALLBACK_SCF(false); } else { @@ -455,7 +455,7 @@ static Bitu DOS_21Handler(void) { case 0x40: /* WRITE Write to file or device */ { Bit16u towrite=reg_cx; - MEM_BlockRead(real_phys(Segs[ds].value,reg_dx),dos_copybuf,towrite); + MEM_BlockRead(SegPhys(ds)+reg_dx,dos_copybuf,towrite); if (DOS_WriteFile(reg_bx,dos_copybuf,&towrite)) { reg_ax=towrite; CALLBACK_SCF(false); @@ -466,7 +466,7 @@ static Bitu DOS_21Handler(void) { break; }; case 0x41: /* UNLINK Delete file */ - MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_UnlinkFile(name1)) { CALLBACK_SCF(false); } else { @@ -489,7 +489,7 @@ static Bitu DOS_21Handler(void) { } case 0x43: /* Get/Set file attributes */ //TODO FIX THIS HACK - MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); switch (reg_al) case 0x00: /* Get */ { @@ -525,11 +525,18 @@ static Bitu DOS_21Handler(void) { } break; case 0x46: /* DUP2,FORCEDUP Force duplicate file handle */ - E_Exit("Unhandled Dos 21 call %02X",reg_ah); + if (DOS_ForceDuplicateEntry(reg_bx,reg_ax)) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; break; case 0x47: /* CWD Get current directory */ //TODO Memory - if (DOS_GetCurrentDir(reg_dl,real_off(Segs[ds].value,reg_si))) { + if (DOS_GetCurrentDir(reg_dl,name1)) { + MEM_BlockWrite(SegPhys(ds)+reg_si,name1,strlen(name1)+1); reg_ax=0x0100; CALLBACK_SCF(false); } else { @@ -551,7 +558,7 @@ static Bitu DOS_21Handler(void) { break; } case 0x49: /* Free memory */ - if (DOS_FreeMemory(Segs[es].value)) { + if (DOS_FreeMemory(SegValue(es))) { CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; @@ -561,7 +568,7 @@ static Bitu DOS_21Handler(void) { case 0x4a: /* Resize memory block */ { Bit16u size=reg_bx; - if (DOS_ResizeMemory(Segs[es].value,&size)) { + if (DOS_ResizeMemory(SegValue(es),&size)) { CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; @@ -572,8 +579,8 @@ static Bitu DOS_21Handler(void) { } case 0x4b: /* EXEC Load and/or execute program */ { - MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); - if (DOS_Execute(name1,(ParamBlock *)real_off(Segs[es].value,reg_bx),reg_al)) { + MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); + if (DOS_Execute(name1,(ParamBlock *)Phys2Host(SegPhys(es)+reg_bx),reg_al)) { CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; @@ -599,7 +606,7 @@ static Bitu DOS_21Handler(void) { reg_ah=dos.return_mode; break; case 0x4e: /* FINDFIRST Find first matching file */ - MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_FindFirst(name1,reg_cx)) { CALLBACK_SCF(false); } else { @@ -622,7 +629,7 @@ static Bitu DOS_21Handler(void) { reg_bx=dos.psp; break; case 0x52: /* Get list of lists */ - SetSegment_16(es,0); + SegSet16(es,0); reg_bx=0; LOG_ERROR("Call is made for list of lists not supported let's hope for the best"); break; @@ -635,8 +642,8 @@ static Bitu DOS_21Handler(void) { E_Exit("Unhandled Dos 21 call %02X",reg_ah); break; case 0x56: /* RENAME Rename file */ - MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); - MEM_StrCopy(real_phys(Segs[es].value,reg_di),name2,DOSNAMEBUF); + MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); + MEM_StrCopy(SegPhys(es)+reg_di,name2,DOSNAMEBUF); if (DOS_Rename(name1,name2)) { CALLBACK_SCF(false); } else { @@ -658,7 +665,7 @@ static Bitu DOS_21Handler(void) { case 0x5a: /* Create temporary file */ { Bit16u handle; - MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_CreateTempFile(name1,&handle)) { reg_ax=handle; CALLBACK_SCF(false); @@ -670,7 +677,7 @@ static Bitu DOS_21Handler(void) { break; case 0x5b: /* Create new file */ { - MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); + MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); Bit16u handle; if (DOS_OpenFile(name1,0,&handle)) { DOS_CloseFile(handle); @@ -695,8 +702,9 @@ static Bitu DOS_21Handler(void) { E_Exit("DOS:Unhandled call %02X",reg_ah); break; case 0x60: /* Canonicalize filename or path */ - MEM_StrCopy(real_phys(Segs[ds].value,reg_dx),name1,DOSNAMEBUF); - if (DOS_Canonicalize(name1,real_off(Segs[es].value,reg_di))) { + MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); + if (DOS_Canonicalize(name1,name2)) { + MEM_BlockWrite(SegPhys(es)+reg_di,name2,strlen(name2)+1); CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; @@ -717,13 +725,13 @@ static Bitu DOS_21Handler(void) { /* Todo maybe fully support this for now we set it standard for USA */ { LOG_DEBUG("DOS:65:Extended country information call"); - Bit8u * data=real_off(Segs[es].value,reg_di); + PhysPt data=SegPhys(es)+reg_di; switch (reg_al) { case 1: - real_writeb(Segs[es].value,reg_di,reg_al); - real_writew(Segs[es].value,reg_di+1,4); - real_writew(Segs[es].value,reg_di+3,1); - real_writew(Segs[es].value,reg_di+5,37); + mem_writeb(data,reg_al); + mem_writew(data+1,4); + mem_writew(data+3,1); + mem_writew(data+5,37); reg_cx=4; CALLBACK_SCF(false); break; @@ -751,7 +759,6 @@ static Bitu DOS_21Handler(void) { break; case 0x69: /* Get/Set disk serial number */ { - Bit8u * temp=real_off(Segs[ds].value,reg_dx); switch(reg_al) { case 0x00: /* Get */ LOG_DEBUG("DOS:Get Disk serial number"); From 151246d909e0088a9871aa6048d4dbd56f030831 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:46:12 +0000 Subject: [PATCH 0087/4131] New memory functions and force dup function added. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@164 --- src/dos/dos_files.cpp | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 0bf46a71..3600b7ce 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -135,14 +135,14 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { return true; } -bool DOS_GetCurrentDir(Bit8u drive,Bit8u * buffer) { +bool DOS_GetCurrentDir(Bit8u drive,char * buffer) { if (drive==0) drive=DOS_GetDefaultDrive(); else drive--; if ((drive>DOS_DRIVES) || (!Drives[drive])) { DOS_SetError(DOSERR_INVALID_DRIVE); return false; } - strcpy((char *) buffer,Drives[drive]->curdir); + strcpy(buffer,Drives[drive]->curdir); return true; } @@ -267,7 +267,7 @@ bool DOS_CloseFile(Bit16u entry) { }; //TODO Figure this out with devices :) - PSP * psp=(PSP *)real_off(dos.psp,0); + PSP * psp=(PSP *)HostMake(dos.psp,0); Bit8u * table=Real2Host(psp->file_table); table[entry]=0xFF; /* Devices won't allow themselves to be closed or killed */ @@ -280,7 +280,7 @@ bool DOS_CloseFile(Bit16u entry) { bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { char fullname[DOS_PATHLENGTH];Bit8u drive; - PSP * psp=(PSP *)real_off(dos.psp,0); + PSP * psp=(PSP *)HostMake(dos.psp,0); if (!DOS_MakeName(name,fullname,&drive)) return false; /* Check for a free file handle */ Bit8u handle=DOS_FILES;Bit8u i; @@ -318,7 +318,7 @@ bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { /* First check for devices */ - PSP * psp=(PSP *)real_off(dos.psp,0); + PSP * psp=(PSP *)HostMake(dos.psp,0); Bit8u handle=DOS_FindDevice((char *)name); bool device=false;char fullname[DOS_PATHLENGTH];Bit8u drive;Bit8u i; if (handle!=255) { @@ -379,7 +379,7 @@ bool DOS_GetFileAttr(char * name,Bit16u * attr) { } } -bool DOS_Canonicalize(char * name,Bit8u * big) { +bool DOS_Canonicalize(char * name,char * big) { //TODO Add Better support for devices and shit but will it be needed i doubt it :) Bit8u drive; char fullname[DOS_PATHLENGTH]; @@ -387,7 +387,7 @@ bool DOS_Canonicalize(char * name,Bit8u * big) { big[0]=drive+'A'; big[1]=':'; big[2]='\\'; - strcpy((char *)&big[3],fullname); + strcpy(&big[3],fullname); return true; }; @@ -411,7 +411,7 @@ bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; - PSP * psp=(PSP *)real_off(dos.psp,0); + PSP * psp=(PSP *)HostMake(dos.psp,0); Bit8u * table=Real2Host(psp->file_table); *newentry=0xff; for (Bit16u i=0;imax_files;i++) { @@ -428,6 +428,32 @@ bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry) { return true; }; +bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry) { + Bit8u orig=RealHandle(entry); + if (orig>=DOS_FILES) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; + if (!Files[orig]) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; + Bit8u newone=RealHandle(newentry); + if (newone>=DOS_FILES) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; + if (Files[newone]) { + DOS_CloseFile(newentry); + return false; + }; + PSP * psp=(PSP *)HostMake(dos.psp,0); + Bit8u * table=Real2Host(psp->file_table); + table[newentry]=(Bit8u)entry; + return true; +}; + + bool DOS_CreateTempFile(char * name,Bit16u * entry) { @@ -448,6 +474,7 @@ bool DOS_CreateTempFile(char * name,Bit16u * entry) { } while (!DOS_CreateFile(name,0,entry)); return true; } + #if 1 static bool FCB_MakeName (DOS_FCB* fcb, char* outname, Bit8u* outdrive){ char naam[15]; From 44c33613876639040610242320cd106c4275bcde Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:47:49 +0000 Subject: [PATCH 0088/4131] New memory and segments Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@165 --- src/dos/dos_execute.cpp | 64 ++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index ee315240..c4f622e0 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -64,7 +64,7 @@ __attribute__ ((packed)); bool DOS_Terminate(bool tsr) { - PSP * psp=(PSP *)real_off(dos.psp,0); + PSP * psp=(PSP *)HostMake(dos.psp,0); if (!tsr) { /* Free Files owned by process */ for (Bit16u i=0;imax_files;i++) { @@ -73,16 +73,16 @@ bool DOS_Terminate(bool tsr) { DOS_FreeProcessMemory(dos.psp); }; dos.psp=psp->psp_parent; - PSP * oldpsp=(PSP *)real_off(dos.psp,0); + PSP * oldpsp=(PSP *)HostMake(dos.psp,0); /* Restore the DTA */ dos.dta=psp->dta; /* Restore the old CS:IP from int 22h */ RealPt old22; old22=RealGetVec(0x22); - SetSegment_16(cs,RealSeg(old22)); + SegSet16(cs,RealSeg(old22)); reg_ip=RealOff(old22); /* Restore the SS:SP to the previous one */ - SetSegment_16(ss,RealSeg(oldpsp->stack)); + SegSet16(ss,RealSeg(oldpsp->stack)); reg_sp=RealOff(oldpsp->stack); /* Restore interrupt 22,23,24 */ RealSetVec(0x22,psp->int_22); @@ -97,17 +97,17 @@ bool DOS_Terminate(bool tsr) { static bool MakeEnv(char * name,Bit16u * segment) { /* If segment to copy environment is 0 copy the caller's environment */ - PSP * psp=(PSP *)real_off(dos.psp,0); + PSP * psp=(PSP *)HostMake(dos.psp,0); Bit8u * envread,*envwrite; Bit16u envsize=1; bool parentenv=true; if (*segment==0) { if (!psp->environment) parentenv=false; //environment seg=0 - envread=real_off(psp->environment,0); + envread=HostMake(psp->environment,0); } else { if (!*segment) parentenv=false; //environment seg=0 - envread=real_off(*segment,0); + envread=HostMake(*segment,0); } //TODO Make a good DOS first psp @@ -123,7 +123,7 @@ static bool MakeEnv(char * name,Bit16u * segment) { } Bit16u size=long2para(envsize+ENV_KEEPFREE); if (!DOS_AllocateMemory(segment,&size)) return false; - envwrite=real_off(*segment,0); + envwrite=HostMake(*segment,0); if (parentenv) { bmemcpy(envwrite,envread,envsize); envwrite+=envsize; @@ -133,12 +133,12 @@ static bool MakeEnv(char * name,Bit16u * segment) { *((Bit16u *) envwrite)=1; envwrite+=2; //TODO put the filename here - return DOS_Canonicalize(name,envwrite); + return DOS_Canonicalize(name,(char *)envwrite); }; bool DOS_NewPSP(Bit16u pspseg) { - PSP * newpsp=(PSP *)real_off(pspseg,0); - PSP * prevpsp=(PSP *)real_off(dos.psp,0); + PSP * newpsp=(PSP *)HostMake(pspseg,0); + PSP * prevpsp=(PSP *)HostMake(dos.psp,0); memset((void *)newpsp,0,sizeof(PSP)); newpsp->exit[0]=0xcd;newpsp->exit[1]=0x20; @@ -169,11 +169,11 @@ bool DOS_NewPSP(Bit16u pspseg) { static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { - PSP * psp=(PSP *)real_off(pspseg,0); + PSP * psp=(PSP *)HostMake(pspseg,0); /* Fix the PSP index of this MCB */ - MCB * pspmcb=(MCB *)real_off(pspseg-1,0); + MCB * pspmcb=(MCB *)HostMake(pspseg-1,0); pspmcb->psp_segment=pspseg; - MCB * envmcb=(MCB *)real_off(envseg-1,0); + MCB * envmcb=(MCB *)HostMake(envseg-1,0); envmcb->psp_segment=pspseg; memset((void *)psp,0,sizeof(PSP)); @@ -210,7 +210,7 @@ static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { } static void SetupCMDLine(Bit16u pspseg,ParamBlock * block) { - PSP * psp=(PSP *)real_off(pspseg,0); + PSP * psp=(PSP *)HostMake(pspseg,0); if (block->exec.cmdtail) { memcpy((void *)&psp->cmdtail,(void *)Real2Host(block->exec.cmdtail),128); @@ -232,7 +232,7 @@ static bool COM_Load(char * name,ParamBlock * block,Bit8u flag) { Bit16u envseg,comseg; Bit32u pos; - PSP * callpsp=(PSP *)real_off(dos.psp,0); + PSP * callpsp=(PSP *)HostMake(dos.psp,0); if (!DOS_OpenFile(name,OPEN_READ,&fhandle)) return false; if (flag!=OVERLAY) { @@ -258,9 +258,9 @@ static bool COM_Load(char * name,ParamBlock * block,Bit8u flag) { DOS_SeekFile(fhandle,&pos,0); readsize=0xffff-256; if (flag==OVERLAY) { - DOS_ReadFile(fhandle,real_host(comseg,0),&readsize); + DOS_ReadFile(fhandle,HostMake(comseg,0),&readsize); } else { - DOS_ReadFile(fhandle,real_host(comseg,256),&readsize); + DOS_ReadFile(fhandle,HostMake(comseg,256),&readsize); } DOS_CloseFile(fhandle); if (flag==OVERLAY) /* Everything what should be done for Overlays */ @@ -268,19 +268,19 @@ static bool COM_Load(char * name,ParamBlock * block,Bit8u flag) { SetupPSP(comseg,size,envseg); SetupCMDLine(comseg,block); /* Setup termination Address */ - RealSetVec(0x22,RealMake(Segs[cs].value,reg_ip)); + RealSetVec(0x22,RealMakeSeg(cs,reg_ip)); /* Everything setup somewhat setup CS:IP and SS:SP */ /* First save the SS:SP of program that called execute */ - callpsp->stack=RealMake(Segs[ss].value,reg_sp); + callpsp->stack=RealMakeSeg(ss,reg_sp); /* Clear out first Stack entry to point to int 20h at psp:0 */ real_writew(comseg,0xfffe,0); dos.psp=comseg; switch (flag) { case LOADNGO: - SetSegment_16(cs,comseg); - SetSegment_16(ss,comseg); - SetSegment_16(ds,comseg); - SetSegment_16(es,comseg); + SegSet16(cs,comseg); + SegSet16(ss,comseg); + SegSet16(ds,comseg); + SegSet16(es,comseg); flags.intf=true; reg_ip=0x100; reg_sp=0xFFFE; @@ -305,7 +305,7 @@ static bool EXE_Load(char * name,ParamBlock * block,Bit8u flag) { Bit16u envseg,pspseg,exeseg; Bit32u imagesize,headersize; - PSP * callpsp=(PSP *)real_off(dos.psp,0); + PSP * callpsp=(PSP *)HostMake(dos.psp,0); if (!DOS_OpenFile(name,OPEN_READ,&fhandle)) return false; if (flag!=OVERLAY) { @@ -353,7 +353,7 @@ static bool EXE_Load(char * name,ParamBlock * block,Bit8u flag) { } /* Load the image in 32k blocks */ DOS_SeekFile(fhandle,&headersize,0); - Bit8u * imageoff=real_off(exeseg,0); + Bit8u * imageoff=HostMake(exeseg,0); //TODO File size checking and remove size // Remove psp size // imagesize=256; @@ -395,15 +395,15 @@ static bool EXE_Load(char * name,ParamBlock * block,Bit8u flag) { if (flag==OVERLAY) return true; /* Setup termination Address */ - RealSetVec(0x22,RealMake(Segs[cs].value,reg_ip)); + RealSetVec(0x22,RealMakeSeg(cs,reg_ip)); /* Start up the actual EXE if we need to */ //TODO check for load and return - callpsp->stack=RealMake(Segs[ss].value,reg_sp); + callpsp->stack=RealMakeSeg(ss,reg_sp); dos.psp=pspseg; - SetSegment_16(cs,exeseg+header.initCS); - SetSegment_16(ss,exeseg+header.initSS); - SetSegment_16(ds,pspseg); - SetSegment_16(es,pspseg); + SegSet16(cs,exeseg+header.initCS); + SegSet16(ss,exeseg+header.initSS); + SegSet16(ds,pspseg); + SegSet16(es,pspseg); reg_ip=header.initIP; reg_sp=header.initSP; reg_ax=0; From e23e1d61ce15e197251b3dab4d12ffc9b24f1dc2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:48:43 +0000 Subject: [PATCH 0089/4131] New memory functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@166 --- src/dos/dos_memory.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 5f1d90cc..2a4bcc14 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -29,15 +29,15 @@ static void DOS_CompressMemory(void) { MCB * pmcb;MCB * pmcbnext; Bit16u mcb_segment; mcb_segment=dos.firstMCB; - pmcb=(MCB *)real_off(mcb_segment,0); + pmcb=(MCB *)HostMake(mcb_segment,0); while (pmcb->type!=0x5a) { - pmcbnext=pmcbnext=(MCB *)real_off(mcb_segment+pmcb->size+1,0); + pmcbnext=pmcbnext=(MCB *)HostMake(mcb_segment+pmcb->size+1,0); if ((pmcb->psp_segment==0) && (pmcbnext->psp_segment==0)) { pmcb->size+=pmcbnext->size+1; pmcb->type=pmcbnext->type; } else { mcb_segment+=pmcb->size+1; - pmcb=(MCB *)real_off(mcb_segment,0); + pmcb=(MCB *)HostMake(mcb_segment,0); } } } @@ -45,14 +45,14 @@ static void DOS_CompressMemory(void) { void DOS_FreeProcessMemory(Bit16u pspseg) { MCB * pmcb; Bit16u mcb_segment=dos.firstMCB; - pmcb=(MCB *)real_off(mcb_segment,0); + pmcb=(MCB *)HostMake(mcb_segment,0); while (true) { if (pmcb->psp_segment==pspseg) { pmcb->psp_segment=MCB_FREE; } mcb_segment+=pmcb->size+1; if (pmcb->type==0x5a) break; - pmcb=(MCB *)real_off(mcb_segment,0); + pmcb=(MCB *)HostMake(mcb_segment,0); } DOS_CompressMemory(); }; @@ -64,7 +64,7 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { bool stop=false;mcb_segment=dos.firstMCB; DOS_CompressMemory(); while(!stop) { - pmcb=(MCB *)real_off(mcb_segment,0); + pmcb=(MCB *)HostMake(mcb_segment,0); if (pmcb->psp_segment==0) { /* Check for enough free memory in current block */ if (pmcb->size<(*blocks)) { @@ -78,7 +78,7 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { return true; } else { /* If so allocate it */ - pmcbnext=(MCB *)real_off(mcb_segment+*blocks+1,0); + pmcbnext=(MCB *)HostMake(mcb_segment+*blocks+1,0); pmcbnext->psp_segment=MCB_FREE; pmcbnext->type=pmcb->type; pmcbnext->size=pmcb->size-*blocks-1; @@ -105,8 +105,8 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { DOS_CompressMemory(); MCB * pmcb,* pmcbnext,* pmcbnew; - pmcb=(MCB *)real_off(segment-1,0); - pmcbnext=(MCB *)real_off(segment+pmcb->size,0); + pmcb=(MCB *)HostMake(segment-1,0); + pmcbnext=(MCB *)HostMake(segment+pmcb->size,0); Bit16u total=pmcb->size; if (pmcb->type!=0x5a) { if (pmcbnext->psp_segment==MCB_FREE) { @@ -118,7 +118,7 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { pmcb->type=pmcbnext->type; } pmcb->size=*blocks; - pmcbnew=(MCB *)real_off(segment+*blocks,0); + pmcbnew=(MCB *)HostMake(segment+*blocks,0); pmcbnew->size=total-*blocks-1; pmcbnew->type=pmcb->type; pmcbnew->psp_segment=MCB_FREE; @@ -141,7 +141,7 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { bool DOS_FreeMemory(Bit16u segment) { //TODO Check if allowed to free this segment MCB * pmcb; - pmcb=(MCB *)real_off(segment-1,0); + pmcb=(MCB *)HostMake(segment-1,0); pmcb->psp_segment=MCB_FREE; DOS_CompressMemory(); return true; @@ -153,7 +153,7 @@ bool DOS_FreeMemory(Bit16u segment) { void DOS_SetupMemory(void) { //TODO Maybe allocate some memory for dos transfer buffers //Although i could use bios regions for that for max free low memory - MCB * mcb=(MCB *) real_off(MEM_START,0); + MCB * mcb=(MCB *) HostMake(MEM_START,0); mcb->psp_segment=MCB_FREE; //Free mcb->size=0x9FFE - MEM_START; mcb->type=0x5a; //Last Block From 0142ca80dea178c0ac913ca9584f4609d5dc3297 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:49:12 +0000 Subject: [PATCH 0090/4131] New config file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@167 --- src/fpu/fpu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index ced68606..79ee2b97 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -17,7 +17,7 @@ */ #include "dosbox.h" -#ifdef C_FPU +#if C_FPU #include #include From 2ab0a70e5e4a988884b7e94b03c19cb4cba4af9c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:50:21 +0000 Subject: [PATCH 0091/4131] New conifig #if's Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@168 --- src/hardware/dma.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 2ac409b9..a9f2ebe0 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -33,7 +33,7 @@ #include "inout.h" #include "dma.h" -#ifdef DEBUG_DMA +#if DEBUG_DMA #define DMA_DEBUG LOG_DEBUG #else #define DMA_DEBUG From 5632f1a4cf084ca0ad2838c1d1203606e6e21603 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:51:33 +0000 Subject: [PATCH 0092/4131] New memory scheme and removed the EMM functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@169 --- src/hardware/memory.cpp | 363 +++++++++++++++++----------------------- 1 file changed, 155 insertions(+), 208 deletions(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index edbc1686..26164941 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -15,36 +15,23 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + + #include #include #include #include "dosbox.h" #include "mem.h" -#define MEM_MAXSIZE 16 /* The Size of memory used to get size of page table */ -#define memsize 8 /* 8 mb of memory */ -#define EMM_HANDLECOUNT 250 +HostPt memory; +HostPt ReadHostTable[MAX_PAGES]; +HostPt WriteHostTable[MAX_PAGES]; +MEMORY_ReadHandler ReadHandlerTable[MAX_PAGES]; +MEMORY_WriteHandler WriteHandlerTable[MAX_PAGES]; -EMM_Handle EMM_Handles[EMM_HANDLECOUNT]; -PageEntry * PageEntries[MEM_MAXSIZE*1024*16]; /* Number of pages */ -Bit8u * memory=0; - -bool MEMORY_TestSpecial(PhysPt off) { - return (PageEntries[off >> 12]>0); -} - -void MEMORY_SetupHandler(Bit32u page,Bit32u pages,PageEntry * entry) { - for (Bit32u i=page;i> 12]; - if (!entry) { writeb(memory+off,val);return; } - switch (entry->type) { - case MEMORY_RELOCATE: - writeb(entry->relocate+(off-entry->base),val); - break; - case MEMORY_HANDLER: - entry->handler.write(off-entry->base,val); - break; - default: - E_Exit("Write to Illegal Memory Address %4x",off); - } -} - -void mem_writew(PhysPt off,Bit16u val) { - PageEntry * entry=PageEntries[off >> 12]; - if (!entry) { writew(memory+off,val);return; } - switch (entry->type) { - case MEMORY_RELOCATE: - writew(entry->relocate+(off-entry->base),val); - break; - case MEMORY_HANDLER: - entry->handler.write(off-entry->base,(val & 0xFF)); - entry->handler.write(off-entry->base+1,(val >> 8)); - break; - default: - E_Exit("Write to Illegal Memory Address %4x",off); - } -} - -void mem_writed(PhysPt off,Bit32u val) { - PageEntry * entry=PageEntries[off >> 12]; - if (!entry) { writed(memory+off,val);return; } - switch (entry->type) { - case MEMORY_RELOCATE: - writed(entry->relocate+(off-entry->base),val); - break; - case MEMORY_HANDLER: - entry->handler.write(off-entry->base, (Bit8u)(val & 0xFF)); - entry->handler.write(off-entry->base+1,(Bit8u)(val >> 8) & 0xFF); - entry->handler.write(off-entry->base+2,(Bit8u)(val >> 16) & 0xFF); - entry->handler.write(off-entry->base+3,(Bit8u)(val >> 24) & 0xFF); - break; - default: - E_Exit("Write to Illegal Memory Address %4x",off); - } -} - -Bit8u mem_readb(PhysPt off) { - PageEntry * entry=PageEntries[off >> 12]; - if (!entry) { return readb(memory+off);} - switch (entry->type) { - case MEMORY_RELOCATE: - return readb(entry->relocate+(off-entry->base)); - case MEMORY_HANDLER: - return entry->handler.read(off-entry->base); - break; - default: - E_Exit("Read from Illegal Memory Address %4x",off); - } - return 0; /* Keep compiler happy */ -} - -Bit16u mem_readw(PhysPt off) { - PageEntry * entry=PageEntries[off >> 12]; - if (!entry) { return readw(memory+off);} - switch (entry->type) { - case MEMORY_RELOCATE: - return readw(entry->relocate+(off-entry->base)); - case MEMORY_HANDLER: - return entry->handler.read(off-entry->base) | - (entry->handler.read(off-entry->base+1) << 8); - break; - default: - E_Exit("Read from Illegal Memory Address %4x",off); - } - return 0; /* Keep compiler happy */ -} - -Bit32u mem_readd(PhysPt off) { - PageEntry * entry=PageEntries[off >> 12]; - if (!entry) { return readd(memory+off);} - switch (entry->type) { - case MEMORY_RELOCATE: - return readd(entry->relocate+(off-entry->base)); - case MEMORY_HANDLER: - return entry->handler.read(off-entry->base) | - (entry->handler.read(off-entry->base+1) << 8) | - (entry->handler.read(off-entry->base+2) << 16)| - (entry->handler.read(off-entry->base+3) << 24); - break; - default: - E_Exit("Read from Illegal Memory Address %4x",off); - } - return 0; /* Keep compiler happy */ -} - -/* The EMM Allocation Part */ - -/* If this returns 0 we got and error since 0 is always taken */ -static Bit16u EMM_GetFreeHandle(void) { - Bit16u i=0; - while (i*maxblock) *maxblock=EMM_Handles[index].size; - *total+=EMM_Handles[index].size; - } - if (EMM_Handles[index].next) index=EMM_Handles[index].next; - else break; +/* Could only be called when the pt host entry is 0 ah well :) */ +static Bit8u Default_ReadHandler(PhysPt pt) { + return readb(WriteHostTable[pt >> PAGE_SHIFT]+pt); +} +static void Default_WriteHandler(PhysPt pt,Bit8u val) { + writeb(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); +} + + +void MEM_SetupPageHandlers(Bitu startpage,Bitu pages,MEMORY_ReadHandler read,MEMORY_WriteHandler write) { + if (startpage+pages>=LOW_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); + for (Bitu i=startpage;isize) { - Bit16u newindex=EMM_GetFreeHandle(); - EMM_Handles[newindex].active=true; - EMM_Handles[newindex].phys_base=EMM_Handles[newindex].phys_base+size*4096; - EMM_Handles[newindex].size=EMM_Handles[index].size-size; - EMM_Handles[newindex].free=true; - EMM_Handles[newindex].next=EMM_Handles[index].next; - EMM_Handles[index].next=newindex; - EMM_Handles[index].free=false; - EMM_Handles[index].size=size; - *handle=index; - break; - } - } - if (EMM_Handles[index].next) index=EMM_Handles[index].next; - else break; + +void MEM_ClearPageHandlers(Bitu startpage,Bitu pages) { + if (startpage+pages>=LOW_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); + for (Bitu i=startpage;i=MAX_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); + HostPt base=(HostPt)(data)-startpage*PAGE_SIZE; + if (!base) LOG_DEBUG("MEMORY:Unlucky memory allocation"); + for (Bitu i=startpage;i=MAX_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); + for (Bitu i=startpage;i> 8) & 0xff) ); +} + +static void HandlerWrited(Bitu page,PhysPt pt,Bit32u val) { + WriteHandlerTable[page](pt+0,(Bit8u)(val & 0xff)); + WriteHandlerTable[page](pt+1,(Bit8u)((val >> 8) & 0xff) ); + WriteHandlerTable[page](pt+2,(Bit8u)((val >> 16) & 0xff) ); + WriteHandlerTable[page](pt+3,(Bit8u)((val >> 24) & 0xff) ); +} + +void mem_writeb(PhysPt pt,Bit8u val) { + if (WriteHostTable[pt >> PAGE_SHIFT]) writeb(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); + else { + WriteHandlerTable[pt >> PAGE_SHIFT](pt,val); + } +} + +void mem_writew(PhysPt pt,Bit16u val) { + if (!WriteHostTable[pt >> PAGE_SHIFT]) { +// HandlerWritew(pt >> PAGE_SHIFT,pt,val); + WriteHandlerTable[pt >> PAGE_SHIFT](pt+0,(Bit8u)(val & 0xff)); + WriteHandlerTable[pt >> PAGE_SHIFT](pt+1,(Bit8u)((val >> 8) & 0xff) ); + } else writew(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); +} + +void mem_writed(PhysPt pt,Bit32u val) { + if (!WriteHostTable[pt >> PAGE_SHIFT]) { +// HandlerWrited(pt >> PAGE_SHIFT,pt,val); + WriteHandlerTable[pt >> PAGE_SHIFT](pt+0,(Bit8u)(val & 0xff)); + WriteHandlerTable[pt >> PAGE_SHIFT](pt+1,(Bit8u)((val >> 8) & 0xff) ); + WriteHandlerTable[pt >> PAGE_SHIFT](pt+2,(Bit8u)((val >> 16) & 0xff) ); + WriteHandlerTable[pt >> PAGE_SHIFT](pt+3,(Bit8u)((val >> 24) & 0xff) ); + } else writed(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); } -PageEntry HMA_PageEntry; +static Bit16u HandlerReadw(Bitu page,PhysPt pt) { + return (ReadHandlerTable[page](pt+0)) | + (ReadHandlerTable[page](pt+1)) << 8; +} + +static Bit32u HandlerReadd(Bitu page,PhysPt pt) { + return (ReadHandlerTable[page](pt+0)) | + (ReadHandlerTable[page](pt+1)) << 8 | + (ReadHandlerTable[page](pt+2)) << 16 | + (ReadHandlerTable[page](pt+3)) << 24; +} + +Bit8u mem_readb(PhysPt pt) { + if (ReadHostTable[pt >> PAGE_SHIFT]) return readb(ReadHostTable[pt >> PAGE_SHIFT]+pt); + else { + return ReadHandlerTable[pt >> PAGE_SHIFT](pt); + } +} + +Bit16u mem_readw(PhysPt pt) { + if (!ReadHostTable[pt >> PAGE_SHIFT]) { +// return HandlerReadw(pt >> PAGE_SHIFT,pt); + return + (ReadHandlerTable[pt >> PAGE_SHIFT](pt+0)) | + (ReadHandlerTable[pt >> PAGE_SHIFT](pt+1)) << 8; + } else return readw(ReadHostTable[pt >> PAGE_SHIFT]+pt); +} + +Bit32u mem_readd(PhysPt pt){ + if (ReadHostTable[pt >> PAGE_SHIFT]) return readd(ReadHostTable[pt >> PAGE_SHIFT]+pt); + else { +// return HandlerReadd(pt >> PAGE_SHIFT,pt); + return + (ReadHandlerTable[pt >> PAGE_SHIFT](pt+0)) | + (ReadHandlerTable[pt >> PAGE_SHIFT](pt+1)) << 8 | + (ReadHandlerTable[pt >> PAGE_SHIFT](pt+2)) << 16 | + (ReadHandlerTable[pt >> PAGE_SHIFT](pt+3)) << 24; + } +} +#endif + + void MEM_Init(void) { - memset((void *)&PageEntries,0,sizeof(PageEntries)); - memory=(Bit8u *)malloc(memsize*1024*1024); + /* Init all tables */ + Bitu i; + i=MAX_PAGES; + for (i=0;i1) { - EMM_Handles[1].size=(memsize-1)*256-16; - } else { - EMM_Handles[0].size=0;; - } - EMM_Handles[1].active=true; - EMM_Handles[1].free=true; - EMM_Handles[1].phys_base=0x110000; -}; + /* Setup tables for first mb */ + MEM_SetupMapping(0,PAGE_COUNT(1024*1024),memory); + /* Setup tables for HMA Area */ + MEM_SetupMapping(PAGE_COUNT(1024*1024),PAGE_COUNT(64*1024),memory); +} From 76ab53be5c6efd2f4e31c0d3ebf605069542ca6a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:51:42 +0000 Subject: [PATCH 0093/4131] New config #if's Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@170 --- src/gui/sdlmain.cpp | 14 +++++++------- src/hardware/sblaster.cpp | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 9b81a650..63810e91 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -122,7 +122,7 @@ static void SwitchFullScreen(void) { } static void GFX_Redraw() { -#ifdef C_THREADED +#if C_THREADED if (SDL_mutexP(sdl.mutex)) { E_Exit("Can't Lock Mutex"); }; @@ -134,7 +134,7 @@ static void GFX_Redraw() { if (sdl.full_screen) SDL_Flip(sdl.surface); else SDL_UpdateRect(sdl.surface,0,0,0,0); }; -#ifdef C_THREADED +#if C_THREADED if (SDL_mutexV(sdl.mutex)) { E_Exit("Can't Release Mutex"); } @@ -151,7 +151,7 @@ static int SDLGFX_Thread(void * data) { void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries) { /* I should probably not change the GFX_PalEntry :) */ -#ifdef C_THREADED +#if C_THREADED if (SDL_mutexP(sdl.mutex)) { E_Exit("SDL:Can't Lock Mutex"); }; @@ -166,7 +166,7 @@ void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries) { } } /* Copy palette entries into some internal back up table */ -#ifdef C_THREADED +#if C_THREADED if (SDL_mutexV(sdl.mutex)) { E_Exit("SDL:Can't Release Mutex"); } @@ -179,11 +179,11 @@ void GFX_SetDrawHandler(GFX_DrawHandler * handler) { } void GFX_Stop() { -#ifdef C_THREADED +#if C_THREADED SDL_mutexP(sdl.mutex); #endif sdl.active=false; -#ifdef C_THREADED +#if C_THREADED SDL_mutexV(sdl.mutex); #endif } @@ -198,7 +198,7 @@ void GFX_StartUp() { sdl.active=false; sdl.full_screen=false; sdl.draw=0; -#ifdef C_THREADED +#if C_THREADED sdl.mutex=SDL_CreateMutex(); sdl.thread = SDL_CreateThread(&SDLGFX_Thread,0); #else diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 5b1c0f2b..10699de6 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -49,7 +49,7 @@ enum { MODE_ADPCM_4S }; -#ifdef DEBUG_SBLASTER +#if DEBUG_SBLASTER #define SB_DEBUG LOG_DEBUG #else #define SB_DEBUG From a1ed02efa36f8352472ea06dc42751362b840b25 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:52:38 +0000 Subject: [PATCH 0094/4131] Use tables for ega modes, new memory handler Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@171 --- src/hardware/vga.cpp | 58 ++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 2aa89f2c..d2af3138 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -29,6 +29,8 @@ VGA_Type vga; Bit32u CGAWriteTable[256]; Bit32u ExpandTable[256]; +Bit32u Expand16Table[4][16]; +Bit32u Expand16BigTable[0x10000]; Bit32u FillTable[16]={ 0x00000000,0x000000ff,0x0000ff00,0x0000ffff, @@ -37,7 +39,7 @@ Bit32u FillTable[16]={ 0xffff0000,0xffff00ff,0xffffff00,0xffffffff }; -static PageEntry VGA_PageEntry; + void VGA_Render_GFX_2(Bit8u * * data); void VGA_Render_GFX_4(Bit8u * * data); @@ -48,8 +50,7 @@ void VGA_Render_TEXT_16(Bit8u * * data); void VGA_FindSettings(void) { /* Sets up the correct memory handler from the vga.mode setting */ - MEMORY_ResetHandler(0xA0000/4096,128*1024/4096); - VGA_PageEntry.type=MEMORY_HANDLER; + MEM_ClearPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x20000)); /* Detect the kind of video mode this is */ if (vga.config.gfxmode) { if (vga.config.vga_enabled) { @@ -60,27 +61,20 @@ void VGA_FindSettings(void) { } else { /* 256 color unchained vga */ vga.mode=GFX_256U; - VGA_PageEntry.base=0xA0000; - VGA_PageEntry.handler.read=VGA_NormalReadHandler; - VGA_PageEntry.handler.write=VGA_GFX_256U_WriteHandler; - MEMORY_SetupHandler(0xA0000/4096,16,&VGA_PageEntry); + MEM_SetupPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000), + &VGA_NormalReadHandler,&VGA_GFX_256U_WriteHandler); } } else if (vga.config.cga_enabled) { /* 4 color cga */ //TODO Detect hercules modes, probably set them up in bios too if (vga.config.pixel_double) vga.mode=GFX_4; else vga.mode=GFX_2; -// VGA_PageEntry.base=0xB8000; -// VGA_PageEntry.handler.read=VGA_GFX_4_ReadHandler; -// VGA_PageEntry.handler.write=VGA_GFX_4_WriteHandler; -// MEMORY_SetupHandler(0xB8000/4096,8,&VGA_PageEntry); + //TODO Maybe also use a page handler for cga mode } else { /* 16 color ega */ vga.mode=GFX_16; - VGA_PageEntry.base=0xA0000; - VGA_PageEntry.handler.read=VGA_NormalReadHandler; - VGA_PageEntry.handler.write=VGA_GFX_16_WriteHandler; - MEMORY_SetupHandler(0xA0000/4096,16,&VGA_PageEntry); + MEM_SetupPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000), + &VGA_NormalReadHandler,&VGA_GFX_16_WriteHandler); } } else { vga.mode=TEXT_16; @@ -161,10 +155,42 @@ void VGA_Init() { VGA_SetupSEQ(); VGA_SetupAttr(); /* Generate tables */ - Bit32u i; + Bitu i,j; for (i=0;i<256;i++) { ExpandTable[i]=i | (i << 8)| (i <<16) | (i << 24); CGAWriteTable[i]=((i>>6)&3) | (((i>>4)&3) << 8)| (((i>>2)&3) <<16) | (((i>>0)&3) << 24); } + for (j=0;j<4;j++) { + for (i=0;i<16;i++) { + Expand16Table[j][i] = + ((i & 1) ? 1 << (24 + j) : 0) | + ((i & 2) ? 1 << (16 + j) : 0) | + ((i & 4) ? 1 << (8 + j) : 0) | + ((i & 8) ? 1 << j : 0); + } + } + for (i=0;i<0x10000;i++) { + Bit32u val=0; + if (i & 0x1) val|=0x1 << 24; + if (i & 0x2) val|=0x1 << 16; + if (i & 0x4) val|=0x1 << 8; + if (i & 0x8) val|=0x1 << 0; + + if (i & 0x10) val|=0x4 << 24; + if (i & 0x20) val|=0x4 << 16; + if (i & 0x40) val|=0x4 << 8; + if (i & 0x80) val|=0x4 << 0; + + if (i & 0x100) val|=0x2 << 24; + if (i & 0x200) val|=0x2 << 16; + if (i & 0x400) val|=0x2 << 8; + if (i & 0x800) val|=0x2 << 0; + + if (i & 0x1000) val|=0x8 << 24; + if (i & 0x2000) val|=0x8 << 16; + if (i & 0x4000) val|=0x8 << 8; + if (i & 0x8000) val|=0x8 << 0; + Expand16BigTable[i]=val; + } } From 193675b0cbc051274cd7b72d406fc134f1b1c8c0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:53:12 +0000 Subject: [PATCH 0095/4131] New ega memory tables, and more lookup variables Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@172 --- src/hardware/vga.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/hardware/vga.h b/src/hardware/vga.h index 0d3d7c53..d43dc8ed 100644 --- a/src/hardware/vga.h +++ b/src/hardware/vga.h @@ -65,11 +65,14 @@ typedef struct { Bit8u color_compare; Bit8u data_rotate; Bit8u raster_op; - Bit8u enable_set_reset; - Bit8u set_reset; 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; @@ -215,15 +218,11 @@ void VGA_DrawGFX4_Full(Bit8u * bitdata,Bitu next_line); void VGA_DrawGFX2_Full(Bit8u * bitdata,Bitu next_line); /* The Different Memory Read/Write Handlers */ Bit8u VGA_NormalReadHandler(Bit32u start); -void VGA_NormalWriteHandler(Bit32u start,Bit8u val); void VGA_GFX_256U_WriteHandler(Bit32u start,Bit8u val); void VGA_GFX_16_WriteHandler(Bit32u start,Bit8u val); void VGA_GFX_4_WriteHandler(Bit32u start,Bit8u val); -Bit8u VGA_ChainedReadHandler(Bit32u start); -void VGA_ChainedWriteHandler(Bit32u start,Bit8u val); - Bit8u VGA_GFX_4_ReadHandler(Bit32u start); @@ -248,12 +247,14 @@ extern VGA_Type vga; extern Bit8u vga_rom_8[256 * 8]; extern Bit8u vga_rom_14[256 * 14]; extern Bit8u vga_rom_16[256 * 16]; -//extern Bit8u vga_buffer[1024*1024]; + extern Bit32u ExpandTable[256]; extern Bit32u FillTable[16]; extern Bit32u CGAWriteTable[256]; +extern Bit32u Expand16Table[4][16]; +extern Bit32u Expand16BigTable[0x10000]; -#ifdef DEBUG_VGA +#if DEBUG_VGA #define LOG_VGA LOG_DEBUG #else #define LOG_VGA From 5b8fdf2b3e1cf03a0ee6a659430d0e0cbd905726 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:53:58 +0000 Subject: [PATCH 0096/4131] New memory functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@173 --- src/hardware/vga_draw.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index bc86be2e..ec2a3295 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -57,7 +57,7 @@ void VGA_Render_TEXT_16(Bit8u * * data) { } void VGA_DrawGFX2_Full(Bit8u * bitdata,Bitu pitch) { - Bit8u * reader=real_host(0xB800,0); + Bit8u * reader=HostMake(0xB800,0); Bit8u * draw; for (Bitu y=0;y Date: Mon, 19 Aug 2002 12:54:38 +0000 Subject: [PATCH 0097/4131] Save lookup values for greater speed. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@174 --- src/hardware/vga_gfx.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index ddbb133b..ff7b6a1c 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -36,7 +36,9 @@ void write_p3cf(Bit32u port,Bit8u val) { switch (gfx(index)) { case 0: /* Set/Reset Register */ gfx(set_reset)=val & 0x0f; - vga.config.set_reset=val & 0x0f; + vga.config.full_set_reset=FillTable[val & 0x0f]; + vga.config.full_enable_and_set_reset=vga.config.full_set_reset & + vga.config.full_enable_set_reset; /* 0 If in Write Mode 0 and bit 0 of 3CEh index 1 is set a write to display memory will set all the bits in plane 0 of the byte to this @@ -50,15 +52,10 @@ void write_p3cf(Bit32u port,Bit8u val) { break; case 1: /* Enable Set/Reset Register */ gfx(enable_set_reset)=val & 0x0f; - vga.config.enable_set_reset=val & 0x0f; - /* - 0 If set enables Set/reset of plane 0 in Write Mode 0. - 1 Same for plane 1. - 2 Same for plane 2. - 3 Same for plane 3. - */ -// LOG_DEBUG("Enable Set Reset = %2X",val); - break; + vga.config.full_enable_set_reset=FillTable[val & 0x0f]; + vga.config.full_not_enable_set_reset=~vga.config.full_enable_set_reset; + vga.config.full_enable_and_set_reset=vga.config.full_set_reset & + vga.config.full_enable_set_reset; case 2: /* Color Compare Register */ gfx(color_compare)=val & 0x0f; /* From bf747fff94f09582c310fda1e61c865fba84e8e6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:55:36 +0000 Subject: [PATCH 0098/4131] Use tables for ega page handler and lookup values. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@175 --- src/hardware/vga_memory.cpp | 152 +++++++++++++----------------------- 1 file changed, 56 insertions(+), 96 deletions(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index ffd2f0a8..c0ed8229 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -35,7 +35,8 @@ void VGA_ChainedWriteHandler(Bit32u start,Bit8u val) { }; -Bit8u VGA_NormalReadHandler(Bit32u start) { +Bit8u VGA_NormalReadHandler(PhysPt start) { + start-=0xa0000; vga.latch.d=vga.mem.latched[start].d; switch (vga.config.read_mode) { case 0: @@ -49,7 +50,7 @@ Bit8u VGA_NormalReadHandler(Bit32u start) { } //Nice one from DosEmu -INLINE Bit32u RasterOp(Bit32u input,Bit32u mask) { +INLINE static Bit32u RasterOp(Bit32u input,Bit32u mask) { switch (vga.config.raster_op) { case 0x00: /* None */ return (input & mask) | (vga.latch.d & ~mask); @@ -63,11 +64,39 @@ INLINE Bit32u RasterOp(Bit32u input,Bit32u mask) { return 0; } +INLINE static Bit32u ModeOperation(Bit8u val) { + Bit32u full; + switch (vga.config.write_mode) { + case 0x00: + // Write Mode 0: In this mode, the host data is first rotated as per the Rotate Count field, then the Enable Set/Reset mechanism selects data from this or the Set/Reset field. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory. + full=ExpandTable[val]; + full=(full & vga.config.full_not_enable_set_reset) | vga.config.full_enable_and_set_reset; + full=RasterOp(full,vga.config.full_bit_mask); + break; + case 0x01: + // Write Mode 1: In this mode, data is transferred directly from the 32 bit latch register to display memory, affected only by the Memory Plane Write Enable field. The host data is not used in this mode. + full=vga.latch.d; + break; + case 0x02: + //Write Mode 2: In this mode, the bits 3-0 of the host data are replicated across all 8 bits of their respective planes. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory. + full=RasterOp(FillTable[val&0xF],vga.config.full_bit_mask); + break; + case 0x03: + // Write Mode 3: In this mode, the data in the Set/Reset field is used as if the Enable Set/Reset field were set to 1111b. Then the host data is first rotated as per the Rotate Count field, then logical ANDed with the value of the Bit Mask field. The resulting value is used on the data obtained from the Set/Reset field in the same way that the Bit Mask field would ordinarily be used. to select which bits come from the expansion of the Set/Reset field and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory. + full=RasterOp(vga.config.full_set_reset,ExpandTable[val] & vga.config.full_bit_mask); + break; + default: + LOG_ERROR("VGA:Unsupported write mode %d",vga.config.write_mode); + } + return full; +} + Bit8u VGA_GFX_4_ReadHandler(Bit32u start) { return vga.mem.linear[start]; } void VGA_GFX_4_WriteHandler(Bit32u start,Bit8u val) { + start-=0xa0000; vga.mem.linear[start]=val; Bitu line=start / 320; Bitu x=start % 320; @@ -80,114 +109,45 @@ void VGA_GFX_4_WriteHandler(Bit32u start,Bit8u val) { } void VGA_GFX_16_WriteHandler(Bit32u start,Bit8u val) { - VGA_Latch new_latch; - Bitu bit_mask; - switch (vga.config.write_mode) { - case 0x00: - // Write Mode 0: In this mode, the host data is first rotated as per the Rotate Count field, then the Enable Set/Reset mechanism selects data from this or the Set/Reset field. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory. -// val=(val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate)); - //Todo could also include the rotation in the table :) - new_latch.d=ExpandTable[val]; - { - Bit32u resetmask=FillTable[vga.config.enable_set_reset]; - new_latch.d=(new_latch.d & ~resetmask) | ( FillTable[vga.config.set_reset] & resetmask); - }; - new_latch.d=RasterOp(new_latch.d,vga.config.full_bit_mask); - bit_mask=vga.gfx.bit_mask; - break; - case 0x01: - // Write Mode 1: In this mode, data is transferred directly from the 32 bit latch register to display memory, affected only by the Memory Plane Write Enable field. The host data is not used in this mode. - new_latch.d=vga.latch.d; - bit_mask=0xff; - break; - case 0x02: - //Write Mode 2: In this mode, the bits 3-0 of the host data are replicated across all 8 bits of their respective planes. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory. - new_latch.d=RasterOp(FillTable[val&0xF],vga.config.full_bit_mask); - bit_mask=vga.gfx.bit_mask; - break; - case 0x03: - // Write Mode 3: In this mode, the data in the Set/Reset field is used as if the Enable Set/Reset field were set to 1111b. Then the host data is first rotated as per the Rotate Count field, then logical ANDed with the value of the Bit Mask field. The resulting value is used on the data obtained from the Set/Reset field in the same way that the Bit Mask field would ordinarily be used. to select which bits come from the expansion of the Set/Reset field and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory. - new_latch.d=ExpandTable[val]; - new_latch.d&=vga.config.full_bit_mask; //Dunno would anyone use this seems a bit pointless - bit_mask=new_latch.b[0]; - new_latch.d=RasterOp(FillTable[vga.config.set_reset],new_latch.d); - break; - default: - LOG_ERROR("VGA:Unsupported write mode %d",vga.config.write_mode); - } + start-=0xa0000; + Bit32u data=ModeOperation(val); /* Update video memory and the pixel buffer */ VGA_Latch pixels; pixels.d=vga.mem.latched[start].d; - pixels.d&=~vga.config.full_map_mask; - pixels.d|=(new_latch.d & vga.config.full_map_mask); + pixels.d&=vga.config.full_not_map_mask; + pixels.d|=(data & vga.config.full_map_mask); vga.mem.latched[start].d=pixels.d; Bit8u * write_pixels=&vga.buffer[start<<3]; -#if 1 - Bit8u sel=128; - do { - if (bit_mask & sel) { - Bitu color; - color=0; - if (pixels.b[0] & sel) color|=1; - if (pixels.b[1] & sel) color|=2; - if (pixels.b[2] & sel) color|=4; - if (pixels.b[3] & sel) color|=8; - *write_pixels=color; - *(write_pixels+512*1024)=color; - } - write_pixels++; - sel>>=1; - } while (sel); -#else -#include "ega-switch.h" -#endif + Bit32u colors0_3, colors4_7; + VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f; + colors0_3 = + Expand16Table[0][temp.b[0]] | + Expand16Table[1][temp.b[1]] | + Expand16Table[2][temp.b[2]] | + Expand16Table[3][temp.b[3]]; + *(Bit32u *)write_pixels=colors0_3; + *(Bit32u *)(write_pixels+512*1024)=colors0_3; + temp.d=pixels.d & 0x0f0f0f0f; + colors4_7 = + Expand16Table[0][temp.b[0]] | + Expand16Table[1][temp.b[1]] | + Expand16Table[2][temp.b[2]] | + Expand16Table[3][temp.b[3]]; + *(Bit32u *)(write_pixels+4)=colors4_7; + *(Bit32u *)(write_pixels+512*1024+4)=colors4_7; } - - - void VGA_GFX_256U_WriteHandler(Bit32u start,Bit8u val) { - VGA_Latch new_latch; - switch (vga.config.write_mode) { - case 0x00: - /* This should be no problem with big or little endian */ - // Write Mode 0: In this mode, the host data is first rotated as per the Rotate Count field, then the Enable Set/Reset mechanism selects data from this or the Set/Reset field. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory. -// val=(val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate)); - //Todo could also include the rotation in the table :) - new_latch.d=ExpandTable[val]; - { - Bit32u resetmask=FillTable[vga.config.enable_set_reset]; - new_latch.d=(new_latch.d & ~resetmask) | ( FillTable[vga.config.set_reset] & resetmask); - }; - new_latch.d=RasterOp(new_latch.d,vga.config.full_bit_mask); - break; - case 0x01: - // Write Mode 1: In this mode, data is transferred directly from the 32 bit latch register to display memory, affected only by the Memory Plane Write Enable field. The host data is not used in this mode. - new_latch.d=vga.latch.d; - break; - case 0x02: - //TODO this mode also has Raster op - //Write Mode 2: In this mode, the bits 3-0 of the host data are replicated across all 8 bits of their respective planes. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory. - new_latch.d=RasterOp(FillTable[val&0xF],vga.config.full_bit_mask); - break; - case 0x03: - // Write Mode 3: In this mode, the data in the Set/Reset field is used as if the Enable Set/Reset field were set to 1111b. Then the host data is first rotated as per the Rotate Count field, then logical ANDed with the value of the Bit Mask field. The resulting value is used on the data obtained from the Set/Reset field in the same way that the Bit Mask field would ordinarily be used. to select which bits come from the expansion of the Set/Reset field and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory. - new_latch.d=ExpandTable[val]; - new_latch.d&=vga.config.full_bit_mask; //Dunno would anyone use this seems a bit pointless - new_latch.d=RasterOp(FillTable[vga.config.set_reset],new_latch.d); - break; - default: - E_Exit("VGA:Unsupported write mode %d",vga.config.write_mode); - } + start-=0xa0000; + Bit32u data=ModeOperation(val); VGA_Latch pixels; pixels.d=vga.mem.latched[start].d; - pixels.d&=~vga.config.full_map_mask; - pixels.d|=(new_latch.d & vga.config.full_map_mask); + pixels.d&=vga.config.full_not_map_mask; + pixels.d|=(data & vga.config.full_map_mask); vga.mem.latched[start].d=pixels.d; vga.mem.latched[start+64*1024].d=pixels.d; - }; From 95849cbc0493e18403193fbded68a56f2a57db29 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:56:02 +0000 Subject: [PATCH 0099/4131] Save the map mask to a lookup value Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@176 --- src/hardware/vga_seq.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index cbb85349..9a7aa0c8 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -55,6 +55,7 @@ void write_p3c5(Bit32u port,Bit8u val) { case 2: /* Map Mask */ seq(map_mask)=val & 15; vga.config.full_map_mask=FillTable[val & 15]; + vga.config.full_not_map_mask=~vga.config.full_map_mask; /* 0 Enable writes to plane 0 if set 1 Enable writes to plane 1 if set From fcfadf7048aa06fc4bd3c92915a86a72e4c7d977 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:56:40 +0000 Subject: [PATCH 0100/4131] New memory/segments and saving 32bit regs now on user mouse handler Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@177 --- src/ints/mouse.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 0c5d4ed3..23c95fe7 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -227,7 +227,7 @@ static Bitu INT33_Handler(void) { break; case 0x0c: /* Define interrupt subroutine parameters */ mouse.sub_mask=reg_cx; - mouse.sub_seg=Segs[es].value; + mouse.sub_seg=SegValue(es); mouse.sub_ofs=reg_dx; break; case 0x0f: /* Define mickey/pixel rate */ @@ -245,12 +245,12 @@ static Bitu INT33_Handler(void) { Bit16u oldMask= mouse.sub_mask; // Set new values mouse.sub_mask= reg_cx; - mouse.sub_seg = Segs[es].value; + mouse.sub_seg = SegValue(es); mouse.sub_ofs = reg_dx; // Return old values reg_cx = oldMask; reg_dx = oldOfs; - SetSegment_16(es,oldSeg); + SegSet16(es,oldSeg); }; break; case 0x1c: /* Set interrupt rate */ /* Can't really set a rate this is host determined */ @@ -277,11 +277,11 @@ static Bitu INT74_Handler(void) { /* Check for an active Interrupt Handler that will get called */ if (mouse.sub_mask & mouse.event_queue[mouse.events].type) { /* Save lot's of registers */ - Bit16u oldax,oldbx,oldcx,olddx,oldsi,olddi; - Bit16u oldds,oldes,oldss,oldbp,oldsp; - oldax=reg_ax;oldbx=reg_bx;oldcx=reg_cx;olddx=reg_dx;oldsi=reg_si;olddi=reg_di; - oldbp=reg_bp;oldsp=reg_sp; - oldds=Segs[ds].value; oldes=Segs[es].value; oldss=Segs[ss].value; // Save segments + Bit32u oldeax,oldebx,oldecx,oldedx,oldesi,oldedi,oldebp,oldesp; + Bit16u oldds,oldes,oldss; + oldeax=reg_eax;oldebx=reg_ebx;oldecx=reg_ecx;oldedx=reg_edx; + oldesi=reg_esi;oldedi=reg_edi;oldebp=reg_ebp;oldesp=reg_esp; + oldds=SegValue(ds); oldes=SegValue(es); oldss=SegValue(ss); // Save segments reg_ax=mouse.event_queue[mouse.events].type; reg_bx=mouse.event_queue[mouse.events].buttons; reg_cx=POS_X; @@ -293,9 +293,10 @@ static Bitu INT74_Handler(void) { mouse.mickey_y=0; } CALLBACK_RunRealFar(mouse.sub_seg,mouse.sub_ofs); - reg_ax=oldax;reg_bx=oldbx;reg_cx=oldcx;reg_dx=olddx;reg_si=oldsi;reg_di=olddi; - SetSegment_16(ds,oldds); SetSegment_16(es,oldes); SetSegment_16(ss,oldss); // Save segments - reg_bp=oldbp; reg_sp=oldsp; + reg_eax=oldeax;reg_ebx=oldebx;reg_ecx=oldecx;reg_edx=oldedx; + reg_esi=oldesi;reg_edi=oldedi;reg_ebp=oldebp;reg_esp=oldesp; + SegSet16(ds,oldds); SegSet16(es,oldes); SegSet16(ss,oldss); // Save segments + } } IO_Write(0xa0,0x20); From ed19eb384d3d6a616e845f4113b22414106509d4 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:58:01 +0000 Subject: [PATCH 0101/4131] Changed getfuncstate function Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@178 --- src/ints/int10.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/int10.h b/src/ints/int10.h index 216c60c1..5c27f537 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -172,7 +172,7 @@ void INT10_ScrollDownWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8u nlines void INT10_SetActivePage(Bit8u page); -void INT10_GetFuncStateInformation(Bit16u seg,Bit16u off); +void INT10_GetFuncStateInformation(PhysPt save); void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page); From 0668b95197e2bae58efb6d41cf933acb5fd5c201 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 12:58:23 +0000 Subject: [PATCH 0102/4131] New segments and revoved the bootdisk support in here. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@179 --- src/ints/bios_disk.cpp | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 3813c5bc..da24f797 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -28,32 +28,6 @@ static BIOS_Disk * Floppys[2]; static BIOS_Disk * Harddisks[BIOS_MAX_DISK]; static Bit8u last_status; -static Bitu INT13_FullHandler(void) { - /* Check for disk numbers */ - BIOS_Disk * disk=Floppys[0]; - switch (reg_ah) { - case 0x00: - last_status=reg_ah=0; - break; - case 0x01: /* Get Status of last operation */ - reg_ah=last_status; - break; - case 0x02: /* Read Sectors into Memory */ - last_status=reg_ah=disk->Read_Sector(®_al,reg_dh,reg_ch,(reg_cl & 0x3f)-1,real_off(Segs[es].value,reg_bx)); - CALLBACK_SCF(false); - break; - case 0x03: /* Write Sectors from Memory */ - last_status=reg_ah=disk->Write_Sector(®_al,reg_dh,reg_ch,(reg_cl & 0x3f)-1,real_off(Segs[es].value,reg_bx)); - CALLBACK_SCF(false); - break; - default: - LOG_DEBUG("INT13:Illegal call %2X",reg_ah); - reg_ah=0xff; - CALLBACK_SCF(true); - } - return CBRET_NONE; -}; - static Bitu INT13_SmallHandler(void) { switch (reg_ah) { @@ -79,13 +53,7 @@ static Bitu INT13_SmallHandler(void) { void BIOS_SetupDisks(void) { /* TODO Start the time correctly */ call_int13=CALLBACK_Allocate(); -#ifdef C_IMAGE - Floppys[0]=new imageDisk("c:\\test.img"); - for (Bit32u i=0;i Date: Mon, 19 Aug 2002 12:59:17 +0000 Subject: [PATCH 0103/4131] New segments Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@180 --- src/ints/int10.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 8de625b4..ad4811c8 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -100,7 +100,7 @@ static Bitu INT10_Handler(void) { INT10_SetOverscanBorderColor(reg_bh); break; case 0x02: /* SET ALL PALETTE REGISTERS */ - INT10_SetAllPaletteRegisters(Real2Phys(RealMake(Segs[es].value,reg_dx))); + INT10_SetAllPaletteRegisters(SegPhys(es)+reg_dx); break; case 0x03: /* TOGGLE INTENSITY/BLINKING BIT */ INT10_ToggleBlinkingBit(reg_bl); @@ -112,19 +112,19 @@ static Bitu INT10_Handler(void) { INT10_GetOverscanBorderColor(®_bh); break; case 0x09: /* READ ALL PALETTE REGISTERS AND OVERSCAN REGISTER */ - INT10_GetAllPaletteRegisters(Real2Phys(RealMake(Segs[es].value,reg_dx))); + INT10_GetAllPaletteRegisters(SegPhys(es)+reg_dx); break; case 0x10: /* SET INDIVIDUAL DAC REGISTER */ INT10_SetSingleDacRegister(reg_bl,reg_dh,reg_ch,reg_cl); break; case 0x12: /* SET BLOCK OF DAC REGISTERS */ - INT10_SetDACBlock(reg_bx,reg_cx,Real2Phys(RealMake(Segs[es].value,reg_dx))); + INT10_SetDACBlock(reg_bx,reg_cx,SegPhys(es)+reg_dx); break; case 0x15: /* GET INDIVIDUAL DAC REGISTER */ INT10_GetSingleDacRegister(reg_bl,®_dh,®_ch,®_cl); break; case 0x17: /* GET BLOCK OF DAC REGISTER */ - INT10_GetDACBlock(reg_bx,reg_cx,Real2Phys(RealMake(Segs[es].value,reg_dx))); + INT10_GetDACBlock(reg_bx,reg_cx,SegPhys(es)+reg_dx); break; default: LOG_WARN("INT10:10:Unhandled EGA/VGA Palette Function %2X",reg_al); @@ -137,7 +137,7 @@ static Bitu INT10_Handler(void) { case 0x00: /* interupt 0x1f vector */ { RealPt int_1f=RealGetVec(0x1f); - SetSegment_16(es,RealSeg(int_1f)); + SegSet16(es,RealSeg(int_1f)); reg_bp=RealOff(int_1f); reg_cx=8; } @@ -145,28 +145,28 @@ static Bitu INT10_Handler(void) { case 0x01: /* interupt 0x43 vector */ { RealPt int_43=RealGetVec(0x43); - SetSegment_16(es,RealSeg(int_43)); + SegSet16(es,RealSeg(int_43)); reg_bp=RealOff(int_43); reg_cx=8; } break; case 0x02: /* font 8x14 */ - SetSegment_16(es,RealSeg(int10_romarea.font_14)); + SegSet16(es,RealSeg(int10_romarea.font_14)); reg_bp=RealOff(int10_romarea.font_14); reg_cx=14; break; case 0x03: /* font 8x8 first 128 */ - SetSegment_16(es,RealSeg(int10_romarea.font_8_first)); + SegSet16(es,RealSeg(int10_romarea.font_8_first)); reg_bp=RealOff(int10_romarea.font_8_first); reg_cx=8; break; case 0x04: /* font 8x8 second 128 */ - SetSegment_16(es,RealSeg(int10_romarea.font_8_second)); + SegSet16(es,RealSeg(int10_romarea.font_8_second)); reg_bp=RealOff(int10_romarea.font_8_second); reg_cx=8; break; case 0x06: /* font 8x16 */ - SetSegment_16(es,RealSeg(int10_romarea.font_16)); + SegSet16(es,RealSeg(int10_romarea.font_16)); reg_bp=RealOff(int10_romarea.font_16); reg_cx=16; break; @@ -194,7 +194,7 @@ static Bitu INT10_Handler(void) { } break; case 0x13: /* Write String */ - INT10_WriteString(reg_dh,reg_dl,reg_al,reg_bl,real_phys(Segs[es].value,reg_bp),reg_cx,reg_bh); + INT10_WriteString(reg_dh,reg_dl,reg_al,reg_bl,SegPhys(es)+reg_bp,reg_cx,reg_bh); break; case 0x1A: /* Display Combination */ if (reg_al==0) { @@ -212,7 +212,7 @@ static Bitu INT10_Handler(void) { case 0x1B: /* functionality State Information */ switch (reg_bx) { case 0x0000: - INT10_GetFuncStateInformation(Segs[es].value,reg_di); + INT10_GetFuncStateInformation(SegPhys(es)+reg_di); reg_al=0x1B; break; default: From 6137947697898c0ae4c0f03d780d0e61a2357b7f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 13:00:23 +0000 Subject: [PATCH 0104/4131] New memory Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@181 --- src/ints/int10_char.cpp | 7 +++---- src/ints/int10_misc.cpp | 4 ++-- src/ints/int10_modes.cpp | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index af0e7d76..f77894e4 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -42,7 +42,7 @@ void INT10_ScrollDownWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8u nlines /* Get this from active video mode */ Bit16u textseg=0xb800; - PhysPt start=real_phys(textseg,ncols*nrows*2*page); + PhysPt start=PhysMake(textseg,ncols*nrows*2*page); Bit32u dcol=clr-cul+1; Bit32u drow=rlr-rul+1; @@ -98,7 +98,7 @@ void INT10_ScrollUpWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8u nlines,B { if (nlines==0) { /* Clear Screen that we can */ - PhysPt dest=real_phys(0xb800,0); + PhysPt dest=PhysMake(0xb800,0); for (Bit32u tel=0;tel<0x4000;tel++) { mem_writew(dest,0x0000); dest+=2; @@ -119,7 +119,7 @@ void INT10_ScrollUpWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8u nlines,B /* Get this from active video mode */ Bit16u textseg=0xb800; - PhysPt start=real_phys(textseg,ncols*nrows*2*page); + PhysPt start=PhysMake(textseg,ncols*nrows*2*page); Bit32u dcol=clr-cul+1; Bit32u drow=rlr-rul+1; @@ -265,7 +265,6 @@ INLINE static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u at break; case GRAPH: { - /* Split this up for certain graphics modes, since in PLANAR4 especially this is sooo slow */ /* Amount of lines */ Bit8u * fontdata; Bit16u x,y; diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 98e62848..953b16bb 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -80,9 +80,9 @@ __attribute__ ((packed)); -void INT10_GetFuncStateInformation(Bit16u seg,Bit16u off) { +void INT10_GetFuncStateInformation(PhysPt save) { - PhysPt save=Real2Phys(RealMake(seg,off)); + /* set static state pointer */ mem_writed(save,int10_romarea.static_state); /* Copy BIOS Segment areas */ diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 100344b2..bd0afb59 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -348,18 +348,18 @@ void INT10_SetVideoMode(Bit8u mode) { Bit32u tel; if(clearmem) { if(vga_modes[line].type==TEXT) { - PhysPt dest=real_phys(vga_modes[line].sstart,0); + PhysPt dest=PhysMake(vga_modes[line].sstart,0); for (tel=0;tel<0x4000;tel++) { mem_writew(dest,0x0720); dest+=2; } } else { - PhysPt dest=real_phys(0xb800,0); + PhysPt dest=PhysMake(0xb800,0); for (tel=0;tel<0x4000;tel++) { mem_writew(dest,0x0000); dest+=2; } - dest=real_phys(0xa000,0); + dest=PhysMake(0xa000,0); for (tel=0;tel<0x8000;tel++) { mem_writew(dest,0x0000); dest+=2; From 20d474d86930b2f11e94c9a645719f491bec107f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 13:01:29 +0000 Subject: [PATCH 0105/4131] Total rewrite for new memory system, now using malloc's for memory allocation on demand. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@182 --- src/ints/xms.cpp | 324 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 236 insertions(+), 88 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 433e916c..357d4d47 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include #include #include "dosbox.h" #include "callback.h" @@ -24,37 +25,49 @@ #include "dos_system.h" -#define XMS_VERSION 0x0300 /* version 3.00 */ -#define XMS_DRIVER_VERSION 0x0301 /* my driver version 3.01 */ +#define XMS_HANDLES 50 /* 50 XMS Memory Blocks */ +#define XMS_VERSION 0x0300 /* version 3.00 */ +#define XMS_DRIVER_VERSION 0x0301 /* my driver version 3.01 */ -#define XMS_GET_VERSION 0x00 -#define XMS_ALLOCATE_HIGH_MEMORY 0x01 -#define XMS_FREE_HIGH_MEMORY 0x02 -#define XMS_GLOBAL_ENABLE_A20 0x03 -#define XMS_GLOBAL_DISABLE_A20 0x04 -#define XMS_LOCAL_ENABLE_A20 0x05 -#define XMS_LOCAL_DISABLE_A20 0x06 -#define XMS_QUERY_A20 0x07 -#define XMS_QUERY_FREE_EXTENDED_MEMORY 0x08 -#define XMS_ALLOCATE_EXTENDED_MEMORY 0x09 -#define XMS_FREE_EXTENDED_MEMORY 0x0a -#define XMS_MOVE_EXTENDED_MEMORY_BLOCK 0x0b -#define XMS_LOCK_EXTENDED_MEMORY_BLOCK 0x0c -#define XMS_UNLOCK_EXTENDED_MEMORY_BLOCK 0x0d -#define XMS_GET_EMB_HANDLE_INFORMATION 0x0e -#define XMS_RESIZE_EXTENDED_MEMORY_BLOCK 0x0f -#define XMS_ALLOCATE_UMB 0x10 -#define XMS_DEALLOCATE_UMB 0x11 +#define XMS_GET_VERSION 0x00 +#define XMS_ALLOCATE_HIGH_MEMORY 0x01 +#define XMS_FREE_HIGH_MEMORY 0x02 +#define XMS_GLOBAL_ENABLE_A20 0x03 +#define XMS_GLOBAL_DISABLE_A20 0x04 +#define XMS_LOCAL_ENABLE_A20 0x05 +#define XMS_LOCAL_DISABLE_A20 0x06 +#define XMS_QUERY_A20 0x07 +#define XMS_QUERY_FREE_EXTENDED_MEMORY 0x08 +#define XMS_ALLOCATE_EXTENDED_MEMORY 0x09 +#define XMS_FREE_EXTENDED_MEMORY 0x0a +#define XMS_MOVE_EXTENDED_MEMORY_BLOCK 0x0b +#define XMS_LOCK_EXTENDED_MEMORY_BLOCK 0x0c +#define XMS_UNLOCK_EXTENDED_MEMORY_BLOCK 0x0d +#define XMS_GET_EMB_HANDLE_INFORMATION 0x0e +#define XMS_RESIZE_EXTENDED_MEMORY_BLOCK 0x0f +#define XMS_ALLOCATE_UMB 0x10 +#define XMS_DEALLOCATE_UMB 0x11 -#define HIGH_MEMORY_IN_USE 0x92 -#define HIGH_MEMORY_NOT_ALLOCATED 0x93 -#define XMS_OUT_OF_SPACE 0xa0 -#define XMS_INVALID_HANDLE 0xa2 +#define HIGH_MEMORY_IN_USE 0x92 +#define HIGH_MEMORY_NOT_ALLOCATED 0x93 +#define XMS_OUT_OF_SPACE 0xa0 +#define XMS_OUT_OF_HANDLES 0xa1 +#define XMS_INVALID_HANDLE 0xa2 +struct XMS_Block { + Bit16u prev,next; + Bit16u size; /* Size in kb's */ + PhysPt phys; + void * data; + bool active; +}; static Bit16u call_xms; static RealPt xms_callback; +static XMS_Block xms_handles[XMS_HANDLES]; + + static bool multiplex_xms(void) { switch (reg_ax) { @@ -62,7 +75,7 @@ static bool multiplex_xms(void) { reg_al=0x80; return true; case 0x4310: /* XMS handler seg:offset */ - SetSegment_16(es,RealSeg(xms_callback)); + SegSet16(es,RealSeg(xms_callback)); reg_bx=RealOff(xms_callback); return true; } @@ -70,51 +83,29 @@ static bool multiplex_xms(void) { }; -#if defined (_MSC_VER) -#pragma pack(1) -#endif +#pragma pack (push,1) struct XMS_MemMove{ Bit32u length; Bit16u src_handle; - RealPt src_offset; + union { + RealPt realpt; + Bit32u offset; + } src; Bit16u dest_handle; - RealPt dest_offset; -} -#if defined (_MSC_VER) -; -#pragma pack() -#else -__attribute__ ((packed)); -#endif - -static void XMS_MoveBlock(PhysPt block,Bit8u * result) { - XMS_MemMove moveblock; -//TODO Will not work on other endian, probably base it on a class would be nice - MEM_BlockRead(block,(Bit8u *)&moveblock,sizeof(XMS_MemMove)); - HostPt src; - PhysPt dest; - if (moveblock.src_handle) { - src=memory+EMM_Handles[moveblock.src_handle].phys_base+moveblock.src_offset; - } else { - src=Real2Host(moveblock.src_offset); - } - if (moveblock.dest_handle) { - dest=EMM_Handles[moveblock.dest_handle].phys_base+moveblock.dest_offset; - } else { - dest=Real2Phys(moveblock.dest_offset); - } - //memcpy((void *)dest,(void *)src,moveblock.length); - MEM_BlockWrite(dest,src,moveblock.length); - *result=0; -}; + union { + RealPt realpt; + Bit32u offset; + } dest; +} GCC_ATTRIBUTE(packed); +#pragma pack (pop) Bitu XMS_Handler(void) { switch (reg_ah) { case XMS_GET_VERSION: /* 00 */ reg_ax=XMS_VERSION; reg_bx=XMS_DRIVER_VERSION; - reg_dx=0; //TODO HMA Maybe + reg_dx=0; /* No we don't have HMA */ break; case XMS_ALLOCATE_HIGH_MEMORY: /* 01 */ case XMS_FREE_HIGH_MEMORY: /* 02 */ @@ -125,42 +116,183 @@ Bitu XMS_Handler(void) { case XMS_QUERY_A20: /* 07 */ LOG_WARN("XMS:Unhandled call %2X",reg_ah);break; case XMS_QUERY_FREE_EXTENDED_MEMORY: /* 08 */ - EMM_GetFree(®_ax,®_dx); - reg_ax<<=2;reg_dx<<=2; - reg_bl=0; - break; - case XMS_ALLOCATE_EXTENDED_MEMORY: /* 09 */ - EMM_Allocate(PAGES(reg_dx*1024),®_dx); - if (reg_dx) reg_ax=1; - else { reg_ax=0;reg_bl=0xb0; } - break; - case XMS_FREE_EXTENDED_MEMORY: /* 0a */ - EMM_Free(reg_dx); - reg_ax=1; - break; - - case XMS_MOVE_EXTENDED_MEMORY_BLOCK: /* 0b */ - XMS_MoveBlock(real_phys(Segs[ds].value,reg_si),®_bl); - if (reg_bl) reg_ax=0; - else reg_ax=1; - break; - case XMS_LOCK_EXTENDED_MEMORY_BLOCK: /* 0c */ - if ((!EMM_Handles[reg_dx].active) || (EMM_Handles[reg_dx].free)) { - reg_ax=0; - reg_bl=0xa2; /* Invalid block */ + /* Scan the tree for free memory and find largest free block */ + { + Bit16u index=1;reg_ax=0;reg_dx=0; + while (xms_handles[index].active) { + if (!xms_handles[index].data) { + if(xms_handles[index].size>reg_ax) reg_ax=xms_handles[index].size; + reg_dx+=xms_handles[index].size; + } + if (xms_handles[index].next> 16) & 0xffff); + case XMS_ALLOCATE_EXTENDED_MEMORY: /* 09 */ + { + Bit16u index=1; + /* First make reg_dx a multiple of PAGE_KB */ + if (reg_dx & (PAGE_KB-1)) reg_dx=(reg_dx&(~(PAGE_KB-1)))+PAGE_KB; + while (xms_handles[index].active) { + /* Find a free block, check if there's enough size */ + if (!xms_handles[index].data && xms_handles[index].size>=reg_dx) { + /* Check if block is bigger than request */ + if (xms_handles[index].size>reg_dx) { + /* Split Block, find new handle and split up memory */ + Bit16u new_index=1; + while (new_index=XMS_HANDLES) || !xms_handles[reg_dx].active || !xms_handles[reg_dx].data ) { + reg_ax=0; + reg_bl=XMS_INVALID_HANDLE; + return CBRET_NONE; + } + /* Remove the mapping to the memory */ + MEM_ClearMapping(PAGE_COUNT(xms_handles[reg_dx].phys),PAGE_COUNT(xms_handles[reg_dx].size*1024)); + /* Free the memory in the block and merge the blocks previous and next block */ + Bit16u prev=xms_handles[reg_dx].prev; + Bit16u next=xms_handles[reg_dx].next; + free(xms_handles[reg_dx].data); + xms_handles[reg_dx].data=0; + if ((next=XMS_HANDLES) || !xms_handles[block.src_handle].active ||!xms_handles[block.src_handle].data) { + reg_ax=0; + reg_bl=0xa3; /* Src Handle invalid */ + return CBRET_NONE; + } + if (block.src.offset>=(xms_handles[block.src_handle].size*1024U)) { + reg_ax=0; + reg_bl=0xa4; /* Src Offset invalid */ + return CBRET_NONE; + } + if (block.length>=xms_handles[block.src_handle].size*1024U-block.src.offset) { + reg_ax=0; + reg_bl=0xa7; /* Length invalid */ + return CBRET_NONE; + + } + src=xms_handles[block.src_handle].phys+block.src.offset; + } else { + src=Real2Phys(block.src.realpt); + } + if (block.dest_handle) { + if ((block.dest_handle>=XMS_HANDLES) || !xms_handles[block.dest_handle].active ||!xms_handles[block.dest_handle].data) { + reg_ax=0; + reg_bl=0xa3; /* Dest Handle invalid */ + return CBRET_NONE; + } + if (block.dest.offset>=(xms_handles[block.dest_handle].size*1024U)) { + reg_ax=0; + reg_bl=0xa4; /* Dest Offset invalid */ + return CBRET_NONE; + } + if (block.length>=xms_handles[block.dest_handle].size*1024U-block.dest.offset) { + reg_ax=0; + reg_bl=0xa7; /* Length invalid */ + return CBRET_NONE; + } + dest=xms_handles[block.dest_handle].phys+block.dest.offset; + } else { + dest=Real2Phys(block.dest.realpt); + } + MEM_BlockCopy(dest,src,block.length); + reg_ax=1;reg_bl=0; + } + break; + case XMS_LOCK_EXTENDED_MEMORY_BLOCK: /* 0c */ + { + /* Check for a valid handle */ + if (!reg_dx || (reg_dx>=XMS_HANDLES) || !xms_handles[reg_dx].active || !xms_handles[reg_dx].data ) { + reg_ax=0; + reg_bl=XMS_INVALID_HANDLE; + return CBRET_NONE; + } + reg_bx=(Bit16u)(xms_handles[reg_dx].phys & 0xFFFF); + reg_dx=(Bit16u)(xms_handles[reg_dx].phys>>16); + reg_ax=1; + break; + } case XMS_UNLOCK_EXTENDED_MEMORY_BLOCK: /* 0d */ - reg_ax=1; + /* Check for a valid handle */ + if (!reg_dx || (reg_dx>=XMS_HANDLES) || !xms_handles[reg_dx].active || !xms_handles[reg_dx].data ) { + reg_ax=0; + reg_bl=XMS_INVALID_HANDLE; + return CBRET_NONE; + } + reg_ax=1;reg_bl=0; break; case XMS_GET_EMB_HANDLE_INFORMATION: /* 0e */ - LOG_WARN("XMS:Unhandled call %2X",reg_ah);break; case XMS_RESIZE_EXTENDED_MEMORY_BLOCK: /* 0f */ - LOG_WARN("XMS:Unhandled call %2X",reg_ah);break; + LOG_WARN("XMS:Unhandled call %2X",reg_ah); + break; case XMS_ALLOCATE_UMB: /* 10 */ reg_ax=0; reg_bl=0xb1; //No UMB Available @@ -181,5 +313,21 @@ void XMS_Init(void) { call_xms=CALLBACK_Allocate(); CALLBACK_Setup(call_xms,&XMS_Handler,CB_RETF); xms_callback=CALLBACK_RealPointer(call_xms); + /* Setup the handler table */ + Bitu i; + for (i=0;i Date: Mon, 19 Aug 2002 13:02:09 +0000 Subject: [PATCH 0106/4131] New memory and segments Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@183 --- src/misc/programs.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 1e974892..6b66f009 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -60,9 +60,9 @@ static Bitu PROGRAMS_Handler(void) { /* First get the current psp */ PROGRAM_Info * info=new PROGRAM_Info; info->psp_seg=dos.psp; - MEM_BlockRead(real_phys(dos.psp,0),&info->psp_copy,sizeof(PSP)); + MEM_BlockRead(PhysMake(dos.psp,0),&info->psp_copy,sizeof(PSP)); /* Get the file name cmd_line 0 */ - PhysPt envblock=real_phys(info->psp_copy.environment,0); + PhysPt envblock=PhysMake(info->psp_copy.environment,0); do {} while (mem_readw(envblock++)); envblock+=3; MEM_StrCopy(envblock,info->full_name,32); @@ -107,7 +107,7 @@ char * Program::GetEnvStr(char * env_str) { /* Walk through the internal environment and see for a match */ /* Taking some short cuts here to not fuck around with memory structure */ - char * envstart=(char *)real_host(prog_info->psp_copy.environment,0); + char * envstart=(char *)HostMake(prog_info->psp_copy.environment,0); size_t len=strlen(env_str); while (*envstart) { if (strncasecmp(env_str,envstart,len)==0 && envstart[len]=='=') { @@ -119,7 +119,7 @@ char * Program::GetEnvStr(char * env_str) { }; char * Program::GetEnvNum(Bit32u num) { - char * envstart=(char *)real_host(prog_info->psp_copy.environment,0); + char * envstart=(char *)HostMake(prog_info->psp_copy.environment,0); while (*envstart) { if (!num) return envstart; envstart+=strlen(envstart)+1; @@ -129,7 +129,7 @@ char * Program::GetEnvNum(Bit32u num) { } Bit32u Program::GetEnvCount(void) { - char * envstart=(char *)real_host(prog_info->psp_copy.environment,0); + char * envstart=(char *)HostMake(prog_info->psp_copy.environment,0); Bit32u num=0; while (*envstart) { envstart+=strlen(envstart)+1; @@ -139,13 +139,13 @@ Bit32u Program::GetEnvCount(void) { } bool Program::SetEnv(char * env_entry,char * new_string) { - MCB * env_mcb=(MCB *)real_host(prog_info->psp_copy.environment-1,0); + MCB * env_mcb=(MCB *)HostMake(prog_info->psp_copy.environment-1,0); upcase(env_entry); Bit32u env_size=env_mcb->size*16; if (!env_size) E_Exit("SHELL:Illegal environment size"); /* First try to find the old entry */ size_t len=strlen(env_entry); - char * envstart=(char *)real_host(prog_info->psp_copy.environment,0); + char * envstart=(char *)HostMake(prog_info->psp_copy.environment,0); while (*envstart) { if (strncasecmp(env_entry,envstart,len)==0 && envstart[len]=='=') { /* Now remove this entry */ From c2f556ca6654277fa554ee46af792d58775e53a9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 13:02:33 +0000 Subject: [PATCH 0107/4131] new config #if's Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@184 --- src/misc/support.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 9d9623bb..0772332f 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -208,7 +208,7 @@ void S_Warn(char * format,...) { va_start(msg,format); vsprintf(buf,format,msg); va_end(msg); -#ifdef C_DEBUG +#if C_DEBUG DEBUG_ShowMsg(buf); #else GFX_ShowMsg(buf); From 908a8a93cfce9c680bcbb32fabb96b04bf068500 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 13:03:23 +0000 Subject: [PATCH 0108/4131] New segments and memory Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@185 --- src/shell/shell.cpp | 8 ++++---- src/shell/shell_cmds.cpp | 4 ++-- src/shell/shell_misc.cpp | 14 +++++++------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index acbb79a3..2020d9b5 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -141,15 +141,15 @@ void SHELL_Init() { Bit16u psp_seg=DOS_GetMemory(16); Bit16u env_seg=DOS_GetMemory(1+(4096/16)); Bit16u stack_seg=DOS_GetMemory(2048/16); - SetSegment_16(ss,stack_seg); + SegSet16(ss,stack_seg); reg_sp=2046; /* Setup a fake MCB for the environment */ - MCB * env_mcb=(MCB *)real_host(env_seg,0); + MCB * env_mcb=(MCB *)HostMake(env_seg,0); env_mcb->psp_segment=psp_seg; env_mcb->size=4096/16; real_writed(env_seg+1,0,0); - PSP * psp=(PSP *)real_host(psp_seg,0); + PSP * psp=(PSP *)HostMake(psp_seg,0); Bit32u i; for (i=0;i<20;i++) psp->files[i]=0xff; psp->files[STDIN]=DOS_FindDevice("CON"); @@ -171,7 +171,7 @@ void SHELL_Init() { PROGRAM_Info info; strcpy(info.full_name,"Z:\\COMMAND.COM"); info.psp_seg=psp_seg; - MEM_BlockRead(real_phys(dos.psp,0),&info.psp_copy,sizeof(PSP)); + MEM_BlockRead(PhysMake(dos.psp,0),&info.psp_copy,sizeof(PSP)); char line[256]; strcpy(line,"/INIT Z:\\AUTOEXEC.BAT"); info.cmd_line=line; diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 164b4346..1dcec3bc 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -114,7 +114,7 @@ void DOS_Shell::CMD_EXIT(char * args) { void DOS_Shell::CMD_CHDIR(char * args) { if (!*args) { Bit8u drive=DOS_GetDefaultDrive()+'A'; - Bit8u dir[DOS_PATHLENGTH]; + char dir[DOS_PATHLENGTH]; DOS_GetCurrentDir(0,dir); WriteOut("%c:\\%s\n",drive,dir); } @@ -186,7 +186,7 @@ void DOS_Shell::CMD_DIR(char * args) { if (strlen(args)==0) args="*.*"; /* Make a full path in the args */ - if (!DOS_Canonicalize(args,(Bit8u*)path)) { + if (!DOS_Canonicalize(args,path)) { WriteOut(MSG_Get("SHELL_CMD_DIR_PATH_ERROR")); return; } diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 9a97748d..df465b18 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -24,7 +24,7 @@ void DOS_Shell::ShowPrompt(void) { Bit8u drive=DOS_GetDefaultDrive()+'A'; - Bit8u dir[DOS_PATHLENGTH]; + char dir[DOS_PATHLENGTH]; DOS_GetCurrentDir(0,dir); WriteOut("%c:\\%s>",drive,dir); } @@ -149,9 +149,9 @@ void DOS_Shell::Execute(char * name,char * args) { /* Allocate some stack space for tables in physical memory */ reg_sp-=0x200; //Add Parameter block - DOS_ParamBlock block(Real2Phys(RealMake(Segs[ss].value,reg_sp))); + DOS_ParamBlock block(SegPhys(ss)+reg_sp); //Add a filename - RealPt file_name=RealMake(Segs[ss].value,reg_sp+0x20); + RealPt file_name=RealMakeSeg(ss,reg_sp+0x20); MEM_BlockWrite(Real2Phys(file_name),fullname,strlen(fullname)+1); /* Fill the command line */ CommandTail cmd; @@ -159,21 +159,21 @@ void DOS_Shell::Execute(char * name,char * args) { cmd.count=strlen(args); memcpy(cmd.buffer,args,strlen(args)); cmd.buffer[strlen(args)]=0xd; - MEM_BlockWrite(real_phys(prog_info->psp_seg,128),&cmd,128); + MEM_BlockWrite(PhysMake(prog_info->psp_seg,128),&cmd,128); block.InitExec(RealMake(prog_info->psp_seg,128)); /* Save CS:IP to some point where i can return them from */ RealPt newcsip; newcsip=CALLBACK_RealPointer(call_shellstop); - SetSegment_16(cs,RealSeg(newcsip)); + SegSet16(cs,RealSeg(newcsip)); reg_ip=RealOff(newcsip); /* Start up a dos execute interrupt */ reg_ax=0x4b00; //Filename pointer - SetSegment_16(ds,Segs[ss].value); + SegSet16(ds,SegValue(ss)); reg_dx=RealOff(file_name); //Paramblock - SetSegment_16(es,Segs[ss].value); + SegSet16(es,SegValue(ss)); reg_bx=reg_sp; flags.intf=false; CALLBACK_RunRealInt(0x21); From da0377dd679a22089dc3da14739200722ac42c0e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 13:04:45 +0000 Subject: [PATCH 0109/4131] New functions for new memory scheme and some cleaning up of old defines and functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@186 --- include/mem.h | 139 +++++++++++++++++++++++++++++--------------------- 1 file changed, 81 insertions(+), 58 deletions(-) diff --git a/include/mem.h b/include/mem.h index dde9d6b3..e891cb41 100644 --- a/include/mem.h +++ b/include/mem.h @@ -20,60 +20,45 @@ #define __MEM_H #include -enum { MEMORY_HANDLER=1,MEMORY_RELOCATE=2}; - #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 PhysPt; typedef Bit8u * HostPt; typedef Bit32u RealPt; -struct PageEntry { - Bit8u type; - PhysPt base; /* Used to calculate relative offset */ - struct { - MEMORY_WriteHandler * write; - MEMORY_ReadHandler * read; - } handler; - HostPt relocate; /* This points to host machine address */ -}; +typedef Bit8u (*MEMORY_ReadHandler)(PhysPt pt); +typedef void (*MEMORY_WriteHandler)(PhysPt pt,Bit8u val); + +#define PAGE_KB 16 +#define PAGE_SIZE PAGE_KB*1024 +#define PAGE_SHIFT 14 +#define PAGE_COUNT(A) (A & ((1 << PAGE_SHIFT)-1) ? 1+(A >> PAGE_SHIFT) : (A >> PAGE_SHIFT) ) +#define MAX_PAGES PAGE_COUNT(C_MEM_MAX_SIZE*1024*1024) + +extern HostPt ReadHostTable[MAX_PAGES]; +extern HostPt WriteHostTable[MAX_PAGES]; +extern MEMORY_ReadHandler ReadHandlerTable[MAX_PAGES]; +extern MEMORY_WriteHandler WriteHandlerTable[MAX_PAGES]; -struct EMM_Handle { - Bit16u next; - Bit16u size; /* Size in pages */ - PhysPt phys_base; - HostPt host_base; - bool active; - bool free; -}; INLINE Bit16u PAGES(Bit32u bytes) { if ((bytes & 4095) == 0) return (Bit16u)(bytes>>12); return (Bit16u)(1+(bytes>>12)); } -extern Bit8u * memory; -extern EMM_Handle EMM_Handles[]; -extern PageEntry * PageEntries[]; /* Number of pages */ -bool MEMORY_TestSpecial(PhysPt off); -void MEMORY_SetupHandler(Bit32u page,Bit32u extra,PageEntry * handler); -void MEMORY_ResetHandler(Bit32u page,Bit32u pages); +void MEM_SetupPageHandlers(Bitu startpage,Bitu pages,MEMORY_ReadHandler read,MEMORY_WriteHandler write); +void MEM_ClearPageHandlers(Bitu startpage,Bitu pages); +void MEM_SetupMapping(Bitu startpage,Bitu pages,void * data); +void MEM_ClearMapping(Bitu startpage,Bitu pages); -void EMM_GetFree(Bit16u * maxblock,Bit16u * total); -void EMM_Allocate(Bit16u size,Bit16u * handle); -void EMM_Free(Bit16u handle); - +extern HostPt memory; /* The folowing six functions are used everywhere in the end so these should be changed for Working on big or little endian machines */ - INLINE Bit8u readb(HostPt off) { return *(Bit8u *)off; @@ -98,6 +83,7 @@ INLINE void writed(HostPt off,Bit32u val) { /* The Folowing six functions are slower but they recognize the paged memory system */ //TODO maybe make em inline to go a bit faster +#if (!C_EXTRAINLINE) Bit8u mem_readb(PhysPt pt); Bit16u mem_readw(PhysPt pt); Bit32u mem_readd(PhysPt pt); @@ -106,30 +92,70 @@ void mem_writeb(PhysPt pt,Bit8u val); void mem_writew(PhysPt pt,Bit16u val); void mem_writed(PhysPt pt,Bit32u val); +#else +INLINE void mem_writeb(PhysPt pt,Bit8u val) { + if (WriteHostTable[pt >> PAGE_SHIFT]) writeb(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); + else { + WriteHandlerTable[pt >> PAGE_SHIFT](pt,val); + } +} +INLINE void mem_writew(PhysPt pt,Bit16u val) { + if (WriteHostTable[pt >> PAGE_SHIFT]) writew(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); + else { + WriteHandlerTable[pt >> PAGE_SHIFT](pt+0,(Bit8u)(val & 0xff)); + WriteHandlerTable[pt >> PAGE_SHIFT](pt+1,(Bit8u)((val >> 8) & 0xff) ); + } +} +INLINE void mem_writed(PhysPt pt,Bit32u val) { + if (WriteHostTable[pt >> PAGE_SHIFT]) writed(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); + else { + WriteHandlerTable[pt >> PAGE_SHIFT](pt+0,(Bit8u)(val & 0xff)); + WriteHandlerTable[pt >> PAGE_SHIFT](pt+1,(Bit8u)((val >> 8) & 0xff) ); + WriteHandlerTable[pt >> PAGE_SHIFT](pt+2,(Bit8u)((val >> 16) & 0xff) ); + WriteHandlerTable[pt >> PAGE_SHIFT](pt+3,(Bit8u)((val >> 24) & 0xff) ); + } +} + +INLINE Bit8u mem_readb(PhysPt pt) { + if (ReadHostTable[pt >> PAGE_SHIFT]) return readb(ReadHostTable[pt >> PAGE_SHIFT]+pt); + else { + return ReadHandlerTable[pt >> PAGE_SHIFT](pt); + } +} + +INLINE Bit16u mem_readw(PhysPt pt) { + if (ReadHostTable[pt >> PAGE_SHIFT]) return readw(ReadHostTable[pt >> PAGE_SHIFT]+pt); + else { + return + (ReadHandlerTable[pt >> PAGE_SHIFT](pt+0)) | + (ReadHandlerTable[pt >> PAGE_SHIFT](pt+1)) << 8; + } + +} + +INLINE Bit32u mem_readd(PhysPt pt){ + if (ReadHostTable[pt >> PAGE_SHIFT]) return readd(ReadHostTable[pt >> PAGE_SHIFT]+pt); + else { + return + (ReadHandlerTable[pt >> PAGE_SHIFT](pt+0)) | + (ReadHandlerTable[pt >> PAGE_SHIFT](pt+1)) << 8 | + (ReadHandlerTable[pt >> PAGE_SHIFT](pt+2)) << 16 | + (ReadHandlerTable[pt >> PAGE_SHIFT](pt+3)) << 24; + } +} + +#endif void MEM_BlockWrite(PhysPt pt,void * 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); - - /* The folowing functions are all shortcuts to the above functions using physical addressing */ -INLINE HostPt real_off(Bit16u seg,Bit32u off) { - return memory+(seg<<4)+off; -}; - -INLINE HostPt real_host(Bit16u seg,Bit32u off) { - return memory+(seg<<4)+off; -}; -INLINE PhysPt real_phys(Bit16u seg,Bit32u off) { - return (seg<<4)+off; -}; - INLINE Bit8u real_readb(Bit16u seg,Bit16u off) { return mem_readb((seg<<4)+off); } @@ -139,9 +165,6 @@ INLINE Bit16u real_readw(Bit16u seg,Bit16u off) { INLINE Bit32u real_readd(Bit16u seg,Bit16u 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)) INLINE void real_writeb(Bit16u seg,Bit16u off,Bit8u val) { mem_writeb(((seg<<4)+off),val); @@ -153,11 +176,13 @@ INLINE void real_writed(Bit16u seg,Bit16u off,Bit32u val) { mem_writed(((seg<<4)+off),val); } +INLINE HostPt HostMake(Bit16u seg,Bit16u off) { + return memory+(seg<<4)+off; +} -//#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 HostPt Phys2Host(PhysPt pt) { + return memory+pt; +} INLINE Bit16u RealSeg(RealPt pt) { return (Bit16u)(pt>>16); @@ -171,17 +196,18 @@ INLINE PhysPt Real2Phys(RealPt pt) { return (RealSeg(pt)<<4) +RealOff(pt); } +INLINE PhysPt PhysMake(Bit16u seg,Bit16u off) { + return (seg<<4)+off; +} INLINE HostPt Real2Host(RealPt pt) { return memory+(RealSeg(pt)<<4) +RealOff(pt); } - INLINE RealPt RealMake(Bit16u seg,Bit16u off) { return (seg<<16)+off; } - INLINE void RealSetVec(Bit8u vec,RealPt pt) { mem_writed(vec<<2,pt); } @@ -190,8 +216,5 @@ INLINE RealPt RealGetVec(Bit8u vec) { return mem_readd(vec<<2); } - - - #endif From daa455e47857699953ee267db17a7788a5c250de Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 13:06:21 +0000 Subject: [PATCH 0110/4131] No need for settings.h anymore with config.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@187 --- settings.h.cvs | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 settings.h.cvs diff --git a/settings.h.cvs b/settings.h.cvs deleted file mode 100644 index f61ded61..00000000 --- a/settings.h.cvs +++ /dev/null @@ -1,30 +0,0 @@ -/* 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 the FPU module, still only for beta testing */ -//#define C_FPU - -/* 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 - From 1cc7e00c5697d90d469a5557ccf6f992d8975f37 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 13:13:47 +0000 Subject: [PATCH 0111/4131] No longer need autoheader. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@188 --- autogen.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/autogen.sh b/autogen.sh index 1c139b8d..7c1b9da5 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,6 +1,6 @@ #!/bin/sh # -echo "Generating build information using aclocal, auotheader, automake and autoconf" +echo "Generating build information using aclocal, automake and autoconf" echo "This may take a while ..." # Touch the timestamps on all the files since CVS messes them up @@ -10,7 +10,6 @@ touch $directory/configure.in # Regenerate configuration files aclocal -autoheader automake --gnits --include-deps --add-missing --copy autoconf From 22b3443e4f63483fa2a03ebab435c751d13aef87 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 19 Aug 2002 15:00:11 +0000 Subject: [PATCH 0112/4131] Updated to new segment handling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@189 --- src/debug/debug.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 864fe74d..c438a3dc 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -106,12 +106,12 @@ static void DrawRegisters(void) { SetColor(reg_esp!=oldregs.esp);oldregs.esp=reg_esp;mvwprintw (dbg.win_reg,3,18,"%08X",reg_esp); SetColor(reg_eip!=oldregs.eip);oldregs.eip=reg_eip;mvwprintw (dbg.win_reg,1,42,"%08X",reg_eip); - SetColor(Segs[ds].value!=oldsegs[ds].value);oldsegs[ds].value=Segs[ds].value;mvwprintw (dbg.win_reg,0,31,"%04X",Segs[ds].value); - SetColor(Segs[es].value!=oldsegs[es].value);oldsegs[es].value=Segs[es].value;mvwprintw (dbg.win_reg,0,41,"%04X",Segs[es].value); - SetColor(Segs[fs].value!=oldsegs[fs].value);oldsegs[fs].value=Segs[fs].value;mvwprintw (dbg.win_reg,0,51,"%04X",Segs[fs].value); - SetColor(Segs[gs].value!=oldsegs[gs].value);oldsegs[gs].value=Segs[gs].value;mvwprintw (dbg.win_reg,0,61,"%04X",Segs[gs].value); - SetColor(Segs[ss].value!=oldsegs[ss].value);oldsegs[ss].value=Segs[ss].value;mvwprintw (dbg.win_reg,0,71,"%04X",Segs[ss].value); - SetColor(Segs[cs].value!=oldsegs[cs].value);oldsegs[cs].value=Segs[cs].value;mvwprintw (dbg.win_reg,1,31,"%04X",Segs[cs].value); + SetColor(SegValue(ds)!=oldsegs[ds].val);oldsegs[ds].val=SegValue(ds);mvwprintw (dbg.win_reg,0,31,"%04X",SegValue(ds)); + SetColor(SegValue(es)!=oldsegs[es].val);oldsegs[es].val=SegValue(es);mvwprintw (dbg.win_reg,0,41,"%04X",SegValue(es)); + SetColor(SegValue(fs)!=oldsegs[fs].val);oldsegs[fs].val=SegValue(fs);mvwprintw (dbg.win_reg,0,51,"%04X",SegValue(fs)); + SetColor(SegValue(gs)!=oldsegs[gs].val);oldsegs[gs].val=SegValue(gs);mvwprintw (dbg.win_reg,0,61,"%04X",SegValue(gs)); + SetColor(SegValue(ss)!=oldsegs[ss].val);oldsegs[ss].val=SegValue(ss);mvwprintw (dbg.win_reg,0,71,"%04X",SegValue(ss)); + SetColor(SegValue(cs)!=oldsegs[cs].val);oldsegs[cs].val=SegValue(cs);mvwprintw (dbg.win_reg,1,31,"%04X",SegValue(cs)); /*Individual flags*/ @@ -134,11 +134,11 @@ static void DrawRegisters(void) { static void DrawCode(void) { - PhysPt start=Segs[cs].phys+reg_eip; + PhysPt start=SegPhys(cs)+reg_eip; char dline[200];Bitu size;Bitu c; for (Bit32u i=0;i<10;i++) { size=DasmI386(dline, start, reg_eip, false); - mvwprintw(dbg.win_code,i,0,"%02X:%04X ",Segs[cs].value,(start-Segs[cs].phys)); + mvwprintw(dbg.win_code,i,0,"%02X:%04X ",SegValue(cs),(start-SegPhys(cs))); for (c=0;c=size*2;c--) waddch(dbg.win_code,' '); waddstr(dbg.win_code,dline); @@ -173,10 +173,9 @@ static void AddBreakPoint(PhysPt off) { } - bool DEBUG_BreakPoint(void) { /* First get the phyiscal address and check for a set breakpoint */ - PhysPt where=real_phys(Segs[cs].value,reg_ip-1); + PhysPt where=SegPhys(cs)+reg_ip-1; bool found=false; std::list::iterator i; for(i=BPoints.begin(); i != BPoints.end(); ++i) { @@ -220,16 +219,16 @@ Bit32u DEBUG_CheckKeys(void) { ret=(*cpudecoder)(5); break; - case 'd': dataSeg = Segs[ds].value; + case 'd': dataSeg = SegValue(ds); dataOfs = reg_si; break; - case 'e': dataSeg = Segs[es].value; + case 'e': dataSeg = SegValue(es); dataOfs = reg_di; break; - case 'x': dataSeg = Segs[ds].value; + case 'x': dataSeg = SegValue(ds); dataOfs = reg_dx; break; - case 'b': dataSeg = Segs[es].value; + case 'b': dataSeg = SegValue(es); dataOfs = reg_bx; break; From 9e93d7d0c3d8404ecdcff665ccc6b7028ffbf5be Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 19 Aug 2002 15:12:00 +0000 Subject: [PATCH 0113/4131] #ifdef C_DEBUG -> #if C_DEBUG Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@190 --- src/debug/debug.cpp | 2 +- src/debug/debug_disasm.cpp | 2 +- src/debug/debug_gui.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index c438a3dc..d9047fc9 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -21,7 +21,7 @@ #include #include "dosbox.h" -#ifdef C_DEBUG +#if C_DEBUG #include "debug.h" #include "cpu.h" #include "video.h" diff --git a/src/debug/debug_disasm.cpp b/src/debug/debug_disasm.cpp index 87d35ef0..42cd96db 100644 --- a/src/debug/debug_disasm.cpp +++ b/src/debug/debug_disasm.cpp @@ -63,7 +63,7 @@ Any comments/updates/bug reports to: */ #include "dosbox.h" -#ifdef C_DEBUG +#if C_DEBUG #include #include #include diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index c13f306e..86ddc92a 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -19,7 +19,7 @@ #include "dosbox.h" -#ifdef C_DEBUG +#if C_DEBUG #include #include From fbc882c0368fa1029dab8a81fff39d5b23be998d Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 19 Aug 2002 15:26:35 +0000 Subject: [PATCH 0114/4131] added simple extended fcb support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@191 --- src/dos/dos_classes.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 6d99cef5..05096322 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -182,54 +182,55 @@ Bit8u DOS_PSP::GetFileHandle(Bitu index) { return mem_readb(files+index); }; +#define FCB_EXTENDED (mem_readb(off)==0xFF ? 7:0) void DOS_FCB::Set_drive(Bit8u a){ - mem_writeb(off+offsetof(sFCB,drive),a); + mem_writeb(off+offsetof(sFCB,drive)+FCB_EXTENDED,a); } void DOS_FCB::Set_filename(char * a){ - MEM_BlockWrite(off+offsetof(sFCB,filename),a,8); + MEM_BlockWrite(off+offsetof(sFCB,filename)+FCB_EXTENDED,a,8); } void DOS_FCB::Set_ext(char * a) { - MEM_BlockWrite(off+offsetof(sFCB,ext),a,3); + MEM_BlockWrite(off+offsetof(sFCB,ext)+FCB_EXTENDED,a,3); } void DOS_FCB::Set_current_block(Bit16u a){ - mem_writew(off+offsetof(sFCB,current_block),a); + mem_writew(off+offsetof(sFCB,current_block)+FCB_EXTENDED,a); } void DOS_FCB::Set_record_size(Bit16u a){ - mem_writew(off+offsetof(sFCB,record_size),a); + mem_writew(off+offsetof(sFCB,record_size)+FCB_EXTENDED,a); } void DOS_FCB::Set_filesize(Bit32u a){ - mem_writed(off+offsetof(sFCB,filesize),a); + mem_writed(off+offsetof(sFCB,filesize)+FCB_EXTENDED,a); } void DOS_FCB::Set_date(Bit16u a){ - mem_writew(off+offsetof(sFCB,date),a); + mem_writew(off+offsetof(sFCB,date)+FCB_EXTENDED,a); } void DOS_FCB::Set_time(Bit16u a){ - mem_writew(off+offsetof(sFCB,time),a); + mem_writew(off+offsetof(sFCB,time)+FCB_EXTENDED,a); } Bit8u DOS_FCB::Get_drive(void){ - return mem_readb(off+offsetof(sFCB,drive)); + return mem_readb(off+offsetof(sFCB,drive)+FCB_EXTENDED); } void DOS_FCB::Get_filename(char * a){ MEM_BlockRead(off+offsetof(sFCB,filename),a,8); } void DOS_FCB::Get_ext(char * a){ - MEM_BlockRead(off+offsetof(sFCB,ext),a,3); + MEM_BlockRead(off+offsetof(sFCB,ext)+FCB_EXTENDED,a,3); } Bit16u DOS_FCB::Get_current_block(void){ - return mem_readw(off+offsetof(sFCB,current_block)); + return mem_readw(off+offsetof(sFCB,current_block)+FCB_EXTENDED); } Bit16u DOS_FCB::Get_record_size(void){ - return mem_readw(off+offsetof(sFCB,record_size)); + return mem_readw(off+offsetof(sFCB,record_size)+FCB_EXTENDED); } Bit32u DOS_FCB::Get_filesize(void){ - return mem_readd(off+offsetof(sFCB,filesize)); + return mem_readd(off+offsetof(sFCB,filesize)+FCB_EXTENDED); } Bit16u DOS_FCB::Get_date(void){ - return mem_readw(off+offsetof(sFCB,date)); + return mem_readw(off+offsetof(sFCB,date)+FCB_EXTENDED); } Bit16u DOS_FCB::Get_time(void){ - return mem_readw(off+offsetof(sFCB,time)); + return mem_readw(off+offsetof(sFCB,time)+FCB_EXTENDED); } From 0eb4d60d4ccbb67a068aad52e373e305314646db Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 19 Aug 2002 15:30:12 +0000 Subject: [PATCH 0115/4131] fixed a bug (extended fcbs) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@192 --- src/dos/dos_classes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 05096322..51748613 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -212,7 +212,7 @@ Bit8u DOS_FCB::Get_drive(void){ return mem_readb(off+offsetof(sFCB,drive)+FCB_EXTENDED); } void DOS_FCB::Get_filename(char * a){ - MEM_BlockRead(off+offsetof(sFCB,filename),a,8); + MEM_BlockRead(off+offsetof(sFCB,filename)+FCB_EXTENDED,a,8); } void DOS_FCB::Get_ext(char * a){ MEM_BlockRead(off+offsetof(sFCB,ext)+FCB_EXTENDED,a,3); From b71b8072d6a9ca05f247afe9945f4ab9a8376e7a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Aug 2002 21:03:16 +0000 Subject: [PATCH 0116/4131] Fixed bug with transfer length being the same size of memory block. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@193 --- src/ints/xms.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 357d4d47..f8b7e1a7 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -233,7 +233,7 @@ foundnew: reg_bl=0xa4; /* Src Offset invalid */ return CBRET_NONE; } - if (block.length>=xms_handles[block.src_handle].size*1024U-block.src.offset) { + if (block.length>xms_handles[block.src_handle].size*1024U-block.src.offset) { reg_ax=0; reg_bl=0xa7; /* Length invalid */ return CBRET_NONE; @@ -254,7 +254,7 @@ foundnew: reg_bl=0xa4; /* Dest Offset invalid */ return CBRET_NONE; } - if (block.length>=xms_handles[block.dest_handle].size*1024U-block.dest.offset) { + if (block.length>xms_handles[block.dest_handle].size*1024U-block.dest.offset) { reg_ax=0; reg_bl=0xa7; /* Length invalid */ return CBRET_NONE; From bd9a864d53d4bc67644ca7388f8983f1ba385795 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 20 Aug 2002 09:49:37 +0000 Subject: [PATCH 0117/4131] debugger changes: breakpoints, command line Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@194 --- src/debug/debug.cpp | 442 ++++++++++++++++++++++++++++++++++------ src/debug/debug_gui.cpp | 7 +- src/debug/debug_inc.h | 3 + 3 files changed, 388 insertions(+), 64 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index d9047fc9..64645566 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -33,7 +33,6 @@ #include "mixer.h" #include "debug_inc.h" - #ifdef WIN32 void WIN32_Console(); #endif @@ -42,6 +41,7 @@ static struct { Bit32u eax,ebx,ecx,edx,esi,edi,ebp,esp,eip; } oldregs; +static void DrawCode(void); static Segment oldsegs[6]; static Flag_Info oldflags; @@ -58,24 +58,206 @@ static void SetColor(bool test) { } } -enum { BKPNT_REALMODE,BKPNT_PHYSICAL }; +struct SCodeViewData { + int cursorPos; + Bit16u firstInstSize; + Bit16u useCS; + Bit32u useEIPlast, useEIPmid; + Bit32u useEIP, cursorAdr; + bool inputMode; + char inputStr[255]; -struct BreakPoint { +} codeViewData; + +static Bit16u dataSeg,dataOfs; + +/********************/ +/* Breakpoint stuff */ +/********************/ + +enum { BKPNT_REALMODE, BKPNT_PHYSICAL, BKPNT_INTERRUPT }; + +typedef struct SBreakPoint { PhysPt location; Bit8u olddata; Bit16u seg; Bit16u off_16; Bit32u off_32; Bit8u type; + bool once; bool enabled; bool active; +} TBreakpoint; + +static std::list BPoints; + +static bool IsBreakpoint(PhysPt off) +{ + // iterate list and remove TBreakpoint + std::list::iterator i; + for(i=BPoints.begin(); i != BPoints.end(); i++) { + if ((*i).location==off) return true; + } + return false; }; -static std::list BPoints; +/* This clears all breakpoints by replacing their 0xcc by the original byte */ +static void ClearBreakpoints(void) +{ + // iterate list and place 0xCC + std::list::iterator i; + for(i=BPoints.begin(); i != BPoints.end(); i++) { + if (((*i).type==BKPNT_PHYSICAL) && (*i).active) { + if (mem_readb((*i).location)==0xCC) mem_writeb((*i).location,(*i).olddata); + (*i).active = false; + }; + } +} -static Bit16u dataSeg,dataOfs; +static void DeleteBreakpoint(PhysPt off) +{ + // iterate list and place 0xCC + std::list::iterator i; + for(i=BPoints.begin(); i != BPoints.end(); i++) { + if (((*i).type==BKPNT_PHYSICAL) && (off==(*i).location)) { + if ((*i).active && (mem_readb((*i).location)==0xCC)) mem_writeb((*i).location,(*i).olddata); + (BPoints.erase)(i); + break; + }; + } +} -static void DrawData() { +static void SetBreakpoints(void) +{ + // iterate list and place 0xCC + std::list::iterator i; + for(i=BPoints.begin(); i != BPoints.end(); i++) { + if (((*i).type==BKPNT_PHYSICAL) && (*i).enabled) { + Bit8u data = mem_readb((*i).location); + if (data!=0xCC) { + (*i).olddata = data; + (*i).active = true; + mem_writeb((*i).location,0xCC); + } + }; + } +} + +static void AddBreakpoint(PhysPt off, bool once) +{ + TBreakpoint bp; + bp.type = BKPNT_PHYSICAL; + bp.enabled = true; + bp.active = false; + bp.location = off; + bp.off_16 = RealOff(off); + bp.seg = RealSeg(off); + bp.once = once; + BPoints.push_front(bp); +} + +static void AddIntBreakpoint(Bit8u intNum, Bit8u ah, bool once) +{ + TBreakpoint bp; + bp.type = BKPNT_INTERRUPT; + bp.olddata = intNum; + bp.location = ah; + bp.enabled = true; + bp.active = true; + bp.once = once; + BPoints.push_front(bp); +}; + +static bool RemoveBreakpoint(PhysPt off) +{ + // iterate list and remove TBreakpoint + std::list::iterator i; + for(i=BPoints.begin(); i != BPoints.end(); i++) { + if (((*i).type==BKPNT_PHYSICAL) && ((*i).location==off)) { + TBreakpoint* bp = &(*i); + if ((*i).active && (mem_readb((*i).location)==0xCC)) mem_writeb((*i).location,(*i).olddata); + (*i).active = false; + if ((*i).once) (BPoints.erase)(i); + + return true; + }; + } + return false; +}; + +static bool StepOver() +{ + PhysPt start=Segs[cs].phys+reg_eip; + char dline[200];Bitu size; + size=DasmI386(dline, start, reg_eip, false); + + if (strstr(dline,"call") || strstr(dline,"int")) { + AddBreakpoint (Real2Phys(RealMake(SegValue(cs),reg_eip+size)), true); + SetBreakpoints(); + debugging=false; + DrawCode(); + DOSBOX_SetNormalLoop(); + return true; + } + return false; +}; + +bool DEBUG_BreakPoint(void) { + /* First get the phyiscal address and check for a set TBreakpoint */ + PhysPt where=SegPhys(cs)+reg_eip-1; + bool found = false; + std::list::iterator i; + for(i=BPoints.begin(); i != BPoints.end(); ++i) { + if ((*i).active && (*i).enabled) { + if ((*i).location==where) { + found=true; + break; + } + } + } + if (!found) return false; + RemoveBreakpoint(where); + reg_eip -= 1; + DEBUG_Enable(); + return true; +} + +bool DEBUG_IntBreakpoint(Bit8u intNum) +{ + PhysPt where=SegPhys(cs)+reg_eip-2; + bool found=false; + std::list::iterator i; + for(i=BPoints.begin(); i != BPoints.end(); ++i) { + if ( ((*i).type==BKPNT_INTERRUPT) && (*i).enabled) { + if (((*i).olddata==intNum) && ((*i).location==reg_ah)) { + if ((*i).active) { + found=true; + (*i).active=false; + //(BPoints.erase)(i); + //break; + } else { + // One step over is ok -> activate for next occurence + (*i).active=true; + //break; + } + } + } + } + if (!found) return false; + + // Remove normal breakpoint here, cos otherwise 0xCC wont be removed here + RemoveBreakpoint(where); + RemoveBreakpoint(where+2); + reg_eip -= 2; + DEBUG_Enable(); + return true; +}; + +/********************/ +/* Draw windows */ +/********************/ + +static void DrawData(void) { Bit16u add = 0; /* Data win */ @@ -132,70 +314,155 @@ static void DrawRegisters(void) { wrefresh(dbg.win_reg); }; - -static void DrawCode(void) { - PhysPt start=SegPhys(cs)+reg_eip; +static void DrawCode(void) +{ + Bit32u disEIP = codeViewData.useEIP; + PhysPt start = Segs[cs].phys + codeViewData.useEIP; char dline[200];Bitu size;Bitu c; for (Bit32u i=0;i<10;i++) { - size=DasmI386(dline, start, reg_eip, false); - mvwprintw(dbg.win_code,i,0,"%02X:%04X ",SegValue(cs),(start-SegPhys(cs))); + + if (has_colors()) { + if (disEIP == reg_eip) { + wattrset(dbg.win_code,COLOR_PAIR(PAIR_GREEN_BLACK)); + if (codeViewData.cursorPos==-1) { + codeViewData.cursorPos = i; // Set Cursor + codeViewData.cursorAdr = start; + } + } else if (i == codeViewData.cursorPos) { + wattrset(dbg.win_code,COLOR_PAIR(PAIR_BLACK_GREY)); + codeViewData.cursorAdr = start; + } else if (IsBreakpoint(start)) { + wattrset(dbg.win_code,COLOR_PAIR(PAIR_GREY_RED)); + } else { + wattrset(dbg.win_code,0); + } + } + + size=DasmI386(dline, start, disEIP, false); + mvwprintw(dbg.win_code,i,0,"%02X:%04X ",SegValue(cs),disEIP); for (c=0;c=size*2;c--) waddch(dbg.win_code,' '); waddstr(dbg.win_code,dline); for (c=30-strlen(dline);c>0;c--) waddch(dbg.win_code,' '); start+=size; + disEIP+=size; + + if (i==0) codeViewData.firstInstSize = size; + if (i==4) codeViewData.useEIPmid = disEIP; } + + codeViewData.useEIPlast = disEIP; + + if (!debugging) { + mvwprintw(dbg.win_code,10,0,"(Running)",codeViewData.inputStr); + } else if (codeViewData.inputMode) { + mvwprintw(dbg.win_code,10,0,"-> %s_ ",codeViewData.inputStr); + } else { + mvwprintw(dbg.win_code,10,0," "); + for (c=0;c<50;c++) waddch(dbg.win_code,' '); + }; + wrefresh(dbg.win_code); } -/* This clears all breakpoints by replacing their 0xcc by the original byte */ -static void ClearBreakPoints(void) { -// for (Bit32u i=0;i::iterator i; - for(i=BPoints.begin(); i != BPoints.end(); ++i) { - if ((*i).active && (*i).enabled) { - if ((*i).location==where) { - found=true; - break; - } - } +static void SetCodeWinStart() +{ + if ((SegValue(cs)==codeViewData.useCS) && (reg_eip>=codeViewData.useEIP) && (reg_eip<=codeViewData.useEIPlast)) { + // in valid window - scroll ? + if (reg_eip>=codeViewData.useEIPmid) codeViewData.useEIP += codeViewData.firstInstSize; + + } else { + // totally out of range. + codeViewData.useCS = SegValue(cs); + codeViewData.useEIP = reg_eip; + } + codeViewData.cursorPos = -1; // Recalc Cursor position +}; + +/********************/ +/* User input */ +/********************/ + +Bit32u GetHexValue(char* str, char*& hex) +{ + Bit32u value = 0; + + hex = str; + while (*hex==' ') hex++; + while (*hex) { + if ((*hex>='0') && (*hex<='9')) value = (value<<4)+*hex-'0'; else + if ((*hex>='A') && (*hex<='F')) value = (value<<4)+*hex-'A'+10; + else break; // No valid char + hex++; + }; + return value; +}; + +bool ParseCommand(char* str) +{ + char* found = str; + while (*found) *found++=toupper(*found); + found = strstr(str,"BP "); + if (found) { // Add new breakpoint + found+=3; + Bit16u seg = GetHexValue(found,found); + found++; // skip ":" + Bit32u ofs = GetHexValue(found,found); + AddBreakpoint((seg<<4)+ofs,false); + LOG_DEBUG("DEBUG: Set breakpoint at %04X:%04X",seg,ofs); + return true; + } + found = strstr(str,"BPINT"); + if (found) { // Add Interrupt Breakpoint + found+=5; + Bit8u intNr = GetHexValue(found,found); + Bit8u valAH = GetHexValue(found,found); + AddIntBreakpoint(intNr,valAH,false); + LOG_DEBUG("DEBUG: Set interrupt breakpoint at INT %02X AH=%02X",intNr,valAH); + return true; + } + found = strstr(str,"BPDEL"); + if (found) { // Add Interrupt Breakpoint + (BPoints.clear)(); + LOG_DEBUG("DEBUG: Breakpoints deleted."); + return true; + } + found = strstr(str,"D "); + if (found) { // Add Interrupt Breakpoint + found++; + dataSeg = GetHexValue(found,found); + dataOfs = GetHexValue(found,found); + LOG_DEBUG("DEBUG: Set data overview to %04X:%04X",dataSeg,dataOfs); + return true; } - if (!found) return false; - ClearBreakPoints(); - DEBUG_Enable(); - SetBreakPoints(); return false; -} - +}; Bit32u DEBUG_CheckKeys(void) { + + if (codeViewData.inputMode) { + int key = getch(); + if (key>0) { + switch (key) { + case 0x0A: codeViewData.inputMode = FALSE; + ParseCommand(codeViewData.inputStr); + break; + case 0x08: // delete + if (strlen(codeViewData.inputStr)>0) codeViewData.inputStr[strlen(codeViewData.inputStr)-1] = 0; + break; + default : if ((key>=32) && (key<=128) && (strlen(codeViewData.inputStr)<253)) { + Bit32u len = strlen(codeViewData.inputStr); + codeViewData.inputStr[len] = char(key); + codeViewData.inputStr[len+1] = 0; + } + break; + } + DEBUG_DrawScreen(); + } + return 0; + }; + int key=getch(); Bit32u ret=0; if (key>0) { @@ -218,7 +485,6 @@ Bit32u DEBUG_CheckKeys(void) { case 'q': ret=(*cpudecoder)(5); break; - case 'd': dataSeg = SegValue(ds); dataOfs = reg_si; break; @@ -231,12 +497,50 @@ Bit32u DEBUG_CheckKeys(void) { case 'b': dataSeg = SegValue(es); dataOfs = reg_bx; break; + case 's': dataSeg = SegValue(ss); + dataOfs = reg_sp; + break; case 'r' : dataOfs -= 16; break; case 'f' : dataOfs += 16; break; - default: - ret=(*cpudecoder)(1); + case 0x0A : // Return : input + codeViewData.inputMode = true; + codeViewData.inputStr[0] = 0; + break; + case KEY_DOWN: // down + if (codeViewData.cursorPos<9) codeViewData.cursorPos++; + else codeViewData.useEIP += codeViewData.firstInstSize; + break; + case KEY_UP: // up + if (codeViewData.cursorPos>0) codeViewData.cursorPos--; + else codeViewData.useEIP -= 1; + break; + case KEY_F(5): // Run Programm + debugging=false; + SetBreakpoints(); + DOSBOX_SetNormalLoop(); + break; + case KEY_F(9): // Set/Remove TBreakpoint + if (IsBreakpoint(codeViewData.cursorAdr)) DeleteBreakpoint(codeViewData.cursorAdr); + else AddBreakpoint(codeViewData.cursorAdr, false); + break; + case KEY_F(10): // Step over inst + if (StepOver()) return 0; + else { + Bitu ret=(*cpudecoder)(1); + SetCodeWinStart(); + } + break; + case KEY_F(11): // trace into + ret = (*cpudecoder)(1); + SetCodeWinStart(); + break; + +// default: +// // FIXME : Is this correct ? +// if (key<0x200) ret=(*cpudecoder)(1); +// break; }; DEBUG_DrawScreen(); } @@ -246,21 +550,34 @@ Bit32u DEBUG_CheckKeys(void) { Bitu DEBUG_Loop(void) { //TODO Disable sound GFX_Events(); + // Interrupt started ? - then skip it + Bit16u oldCS = SegValue(cs); + Bit32u oldEIP = reg_eip; PIC_runIRQs(); + if ((oldCS!=SegValue(cs)) || (oldEIP!=reg_eip)) { + PhysPt intBpAdr = Real2Phys(RealMake(oldCS,oldEIP)); + AddBreakpoint(intBpAdr,true); + SetBreakpoints(); + debugging=false; + DOSBOX_SetNormalLoop(); + return 0; + } + return DEBUG_CheckKeys(); } void DEBUG_Enable(void) { - DEBUG_DrawScreen(); debugging=true; + SetCodeWinStart(); + DEBUG_DrawScreen(); DOSBOX_SetLoop(&DEBUG_Loop); } void DEBUG_DrawScreen(void) { DrawRegisters(); - DrawCode(); DrawData(); + DrawCode(); } static void DEBUG_RaiseTimerIrq(void) { PIC_ActivateIRQ(0); @@ -280,9 +597,10 @@ void DEBUG_Init(void) { /* Add some keyhandlers */ KEYBOARD_AddEvent(KBD_kpminus,0,DEBUG_Enable); KEYBOARD_AddEvent(KBD_kpplus,0,DEBUG_RaiseTimerIrq); - /* Clear the breakpoint list */ - + /* Clear the TBreakpoint list */ + memset((void*)&codeViewData,0,sizeof(codeViewData)); + (BPoints.clear)(); } - #endif + diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 86ddc92a..dadc282d 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -96,8 +96,8 @@ static void MakeSubWindows(void) { dbg.win_data=subwin(dbg.win_main,10,dbg.win_main->_maxx,outy,0); outy+=11; /* The Code Window */ - dbg.win_code=subwin(dbg.win_main,10,dbg.win_main->_maxx,outy,0); - outy+=11; + dbg.win_code=subwin(dbg.win_main,11,dbg.win_main->_maxx,outy,0); + outy+=12; /* The output Window */ dbg.win_out=subwin(dbg.win_main,dbg.win_main->_maxy-outy-1,dbg.win_main->_maxx,outy,0); dbg.input_y=dbg.win_main->_maxy-1; @@ -110,6 +110,9 @@ static void MakeSubWindows(void) { static void MakePairs(void) { init_pair(PAIR_BLACK_BLUE, COLOR_BLACK, COLOR_CYAN); init_pair(PAIR_BYELLOW_BLACK, COLOR_YELLOW /*| FOREGROUND_INTENSITY */, COLOR_BLACK); + init_pair(PAIR_GREEN_BLACK, COLOR_GREEN /*| FOREGROUND_INTENSITY */, COLOR_BLACK); + init_pair(PAIR_BLACK_GREY, COLOR_BLACK /*| FOREGROUND_INTENSITY */, COLOR_WHITE); + init_pair(PAIR_GREY_RED, COLOR_WHITE/*| FOREGROUND_INTENSITY */, COLOR_RED); } diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h index f8eebfe1..e77806d1 100644 --- a/src/debug/debug_inc.h +++ b/src/debug/debug_inc.h @@ -22,6 +22,9 @@ #define PAIR_BLACK_BLUE 1 #define PAIR_BYELLOW_BLACK 2 +#define PAIR_GREEN_BLACK 3 +#define PAIR_BLACK_GREY 4 +#define PAIR_GREY_RED 5 void DBGUI_StartUp(void); From 57bd6890f5f058711ba3d3cd5a32db91b784fd95 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 20 Aug 2002 09:51:06 +0000 Subject: [PATCH 0118/4131] changes for debugger Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@195 --- include/debug.h | 1 + include/dosbox.h | 1 + src/cpu/core_16/main.h | 7 +++++++ src/cpu/slow_16.cpp | 4 ++++ src/dosbox.cpp | 9 ++++++--- 5 files changed, 19 insertions(+), 3 deletions(-) diff --git a/include/debug.h b/include/debug.h index 20deed7f..300fa119 100644 --- a/include/debug.h +++ b/include/debug.h @@ -18,6 +18,7 @@ void DEBUG_DrawScreen(void); bool DEBUG_BreakPoint(void); +bool DEBUG_IntBreakpoint(Bit8u intNum); void DEBUG_Enable(void); extern Bitu cycle_count; diff --git a/include/dosbox.h b/include/dosbox.h index 23ed13b6..c9ddd480 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -50,6 +50,7 @@ typedef Bitu (LoopHandler)(void); void DOSBOX_RunMachine(); void DOSBOX_SetLoop(LoopHandler * handler); +void DOSBOX_SetNormalLoop(); void DOSBOX_Init(int argc, char* argv[]); void DOSBOX_StartUp(void); diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 075e5655..b1cfee22 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -887,10 +887,17 @@ restart: break; case 0xcc: /* INT3 */ INTERRUPT(3); +#if C_DEBUG + return 0; +#endif break; case 0xcd: /* INT Ib */ { Bit8u num=Fetchb(); +#if C_DEBUG + SAVEIP; + if (DEBUG_IntBreakpoint(num)) return 0; +#endif INTERRUPT(num); } break; diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp index 30df16c0..a7e41995 100644 --- a/src/cpu/slow_16.cpp +++ b/src/cpu/slow_16.cpp @@ -24,6 +24,10 @@ #include "pic.h" #include "fpu.h" +#if C_DEBUG +#include "debug.h" +#endif + typedef PhysPt EAPoint; #define SegBase(c) SegPhys(c) #define LoadMb(off) mem_readb(off) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 538d192f..e5ea0c71 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -105,7 +105,7 @@ void DOS_Init(); void RENDER_Init(void); void CPU_Init(); -void FPU_Init(); +//void FPU_Init(); void IO_Init(void); void DMA_Init(void); void MIXER_Init(void); @@ -189,6 +189,9 @@ void DOSBOX_SetLoop(LoopHandler * handler) { loop=handler; } +void DOSBOX_SetNormalLoop() { + loop=Normal_Loop; +} void DOSBOX_RunMachine(void){ Bitu ret; @@ -208,11 +211,11 @@ static void InitSystems(void) { HARDWARE_Init(); TIMER_Init(); CPU_Init(); -#ifdef C_FPU +#if C_FPU FPU_Init(); #endif MIXER_Init(); -#ifdef C_DEBUG +#if C_DEBUG DEBUG_Init(); #endif //Start up individual hardware From 067304c30aedf2df86c71a91280ead52fc7f73f5 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 20 Aug 2002 09:58:31 +0000 Subject: [PATCH 0119/4131] fixed bug in makedir Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@196 --- src/dos/drive_local.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index a24ad9cc..1d787502 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -184,7 +184,8 @@ bool localDrive::MakeDir(char * dir) { #else int temp=mkdir(newdir,0700); #endif - return (temp==0); + // if dir already exists, return success too. + return (temp==0) || ((temp!=0) && (errno==EEXIST)); } bool localDrive::RemoveDir(char * dir) { From 57c02611d7a3c6bb5f13a8b1ae9bd4629478b7a1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 21 Aug 2002 14:20:18 +0000 Subject: [PATCH 0120/4131] EMM completely redone for new memory system, 3.2 EMM Manager support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@197 --- src/ints/ems.cpp | 368 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 283 insertions(+), 85 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 705334c8..3dafc2ef 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -18,6 +18,7 @@ #include +#include #include "dosbox.h" #include "callback.h" #include "mem.h" @@ -28,105 +29,296 @@ #include "dos_inc.h" -#define PAGEFRAME_SEG 0xe000 +#define EMM_PAGEFRAME 0xE000 +#define EMM_MAX_HANDLES 50 /* 255 Max */ +#define EMM_PAGE_SIZE (16*1024) +#define EMM_MAX_PAGES (C_MEM_EMS_SIZE * 1024 / 16 ) +#define EMM_MAX_PHYS 4 /* 4 16kb pages in pageframe */ -class device_EMS : public DOS_Device { +#define EMM_VERSION 0x32 + +#define NULL_HANDLE 0xffff +#define NULL_PAGE 0xffff + +/* EMM errors */ +#define EMM_NO_ERROR 0x00 +#define EMM_SOFT_MAL 0x80 +#define EMM_HARD_MAL 0x81 +#define EMM_INVALID_HANDLE 0x83 +#define EMM_FUNC_NOSUP 0x84 +#define EMM_OUT_OF_HANDLES 0x85 +#define EMM_OUT_OF_PHYS 0x87 +#define EMM_OUT_OF_LOG 0x88 +#define EMM_ZERO_PAGES 0x89 +#define EMM_LOG_OUT_RANGE 0x8a +#define EMM_ILL_PHYS 0x8b +#define EMM_PAGE_MAP_SAVED 0x8d +#define EMM_INVALID_SUB 0x8f +#define EMM_FEAT_NOSUP 0x91 +#define EMM_MOVE_OVLAP 0x92 +#define EMM_MOVE_OVLAPI 0x97 +#define EMM_NOT_FOUND 0xa0 + + +class device_EMM : public DOS_Device { public: - device_EMS(); - bool Read(Bit8u * data,Bit16u * size); - bool Write(Bit8u * data,Bit16u * size); - bool Seek(Bit32u * pos,Bit32u type); - bool Close(); - Bit16u GetInformation(void); + device_EMM(){name="EMMXXXX0";} + bool Read(Bit8u * data,Bit16u * size) { return false;} + bool Write(Bit8u * data,Bit16u * size){ + LOG_DEBUG("Write to ems device"); + return false; + } + bool Seek(Bit32u * pos,Bit32u type){return false;} + bool Close(){return false;} + Bit16u GetInformation(void){return 0x8093;} private: Bit8u cache; }; +device_EMM::device_EMM(); -bool device_EMS::Read(Bit8u * data,Bit16u * size) { - return false; -} - -bool device_EMS::Write(Bit8u * data,Bit16u * size) { - return false; -} - -bool device_EMS::Seek(Bit32u * pos,Bit32u type) { - return false; -} - -bool device_EMS::Close() { - return false; -} - -Bit16u device_EMS::GetInformation(void) { - return 0x8093; +struct EMM_Mapping { + Bit16u handle; + Bit16u page; }; -device_EMS::device_EMS() { - name="EMMXXXX0"; +struct EMM_Page { + void * memory; + Bit16u handle; + Bit16u next; +}; + +struct EMM_Handle { + Bit16u first_page; + Bit16u pages; + char name[9]; + bool saved_page_map; + EMM_Mapping page_map[EMM_MAX_PHYS]; +}; + +static EMM_Handle emm_handles[EMM_MAX_HANDLES]; +static EMM_Page emm_pages[EMM_MAX_PAGES]; +static EMM_Mapping emm_mappings[EMM_MAX_PHYS]; +Bitu call_int67; + +static Bit16u EMM_GetFreePages(void) { + Bit16u count=0; + for (Bitu index=0;index=EMM_MAX_HANDLES) {handle=NULL_HANDLE;return EMM_OUT_OF_HANDLES;} + } + /* Allocate the pages */ + Bit16u page=0;Bit16u last=NULL_PAGE; + emm_handles[handle].pages=pages; + while (pages) { + if (emm_pages[page].handle==NULL_HANDLE) { + emm_pages[page].handle=handle; + emm_pages[page].memory=malloc(EMM_PAGE_SIZE); + if (!emm_pages[page].memory) E_Exit("EMM:Cannont allocate memory"); + if (last!=NULL_PAGE) emm_pages[last].next=page; + else emm_handles[handle].first_page=page; + last=page; + pages--; + } else { + if (++page>=EMM_MAX_PAGES) E_Exit("EMM:Ran out of pages"); + } + } + return EMM_NO_ERROR; +} -PageEntry ems_entries[4]; +static Bit8u EMM_MapPage(Bitu phys_page,Bit16u handle,Bit16u log_page) { + /* Check for too high physical page */ + if (phys_page>=EMM_MAX_PHYS) return EMM_ILL_PHYS; + /* Check for valid handle */ + if (handle>=EMM_MAX_HANDLES || emm_handles[handle].first_page==NULL_PAGE) return EMM_INVALID_HANDLE; + /* Check to do unmapping or mappning */ + if (log_page=EMM_MAX_HANDLES || emm_handles[handle].first_page==NULL_PAGE) return EMM_INVALID_HANDLE; + Bit16u page=emm_handles[handle].first_page; + Bit16u pages=emm_handles[handle].pages; + while (pages) { + free(emm_pages[page].memory); + emm_pages[page].memory=0; + emm_pages[page].handle=NULL_HANDLE; + Bit16u next_page=emm_pages[page].next; + emm_pages[page].next=NULL_PAGE; + page=next_page;pages--; + } + /* Reset handle */ + emm_handles[handle].first_page=NULL_PAGE; + emm_handles[handle].pages=0; + emm_handles[handle].saved_page_map=false; + memset(&emm_handles[handle].name,0,9); + return EMM_NO_ERROR; +} + +static Bit8u EMM_SavePageMap(Bit16u handle) { + /* Check for valid handle */ + if (handle>=EMM_MAX_HANDLES || emm_handles[handle].first_page==NULL_PAGE) return EMM_INVALID_HANDLE; + /* Check for previous save */ + if (emm_handles[handle].saved_page_map) return EMM_PAGE_MAP_SAVED; + /* Copy the mappings over */ + for (Bitu i=0;i=EMM_MAX_HANDLES || emm_handles[handle].first_page==NULL_PAGE) return EMM_INVALID_HANDLE; + /* Check for previous save */ + if (!emm_handles[handle].saved_page_map) return EMM_INVALID_HANDLE; + /* Restore the mappings */ + emm_handles[handle].saved_page_map=false; + for (Bitu i=0;i>2; - reg_bx=total>>2; - reg_ah=0; - }; + reg_dx=EMM_MAX_PAGES; + reg_bx=EMM_GetFreePages(); + reg_ah=EMM_NO_ERROR; break; case 0x43: /* Get Handle and Allocate Pages */ - { - if (!reg_bx) { reg_ah=0x89;break; } - Bit16u handle; - EMM_Allocate(reg_bx*4,&handle); - if (handle) { - reg_ah=0; - reg_dx=handle; - } else { reg_ah=0x88; } - break; - } - case 0x44: /* Map Memory */ - { - if (reg_al>3) { reg_ah=0x8b;break; } - HostPt pagestart=memory+EMM_Handles[reg_dx].phys_base+reg_bx*16*1024; - ems_entries[reg_al].relocate=pagestart; - reg_ah=0; - break; - } - case 0x45: /* Release handle and free pages */ - EMM_Free(reg_dx); - reg_ah=0; - break; - case 0x46: /* Get EMM Version */ - reg_ah=0; - reg_al=0x32; //Only 3.2 support for now + reg_ah=EMM_AllocateMemory(reg_bx,reg_dx); break; - case 0x47: /* Save Mapping Context */ - LOG_ERROR("EMS:47:Save Mapping Context not supported"); - reg_ah=0x8c; + case 0x44: /* Map Expanded Memory Page */ + reg_ah=EMM_MapPage(reg_al,reg_dx,reg_bx); + break; + case 0x45: /* Release handle and free pages */ + reg_ah=EMM_ReleaseMemory(reg_dx); + break; + case 0x46: /* Get EMM Version */ + reg_ah=EMM_NO_ERROR; + reg_al=EMM_VERSION; + break; + case 0x47: /* Save Page Map */ + reg_ah=EMM_SavePageMap(reg_dx); + break; + case 0x48: /* Restore Page Map */ + reg_ah=EMM_RestorePageMap(reg_dx); + break; + case 0x4b: /* Get Handle Count */ + reg_bx=0; + for (i=0;i=EMM_MAX_HANDLES || emm_handles[reg_bx].first_page==NULL_PAGE) {reg_ah=EMM_INVALID_HANDLE;break;} + reg_bx=emm_handles[reg_dx].pages; + reg_ah=EMM_NO_ERROR; + break; + case 0x4d: /* Get Pages for all Handles */ + reg_ah=EMM_GetPagesForAllHandles(SegPhys(es)+reg_di,reg_bx); + break; + case 0x4e: /*Save/Restore Page Map */ + LOG_WARN("Save/resetore %d",reg_al); + switch (reg_al) { + case 0x00: /* Save Page Map */ + MEM_BlockWrite(SegPhys(es)+reg_di,emm_mappings,sizeof(emm_mappings)); + reg_ah=EMM_NO_ERROR; + break; + case 0x01: /* Restore Page Map */ + MEM_BlockRead(SegPhys(ds)+reg_si,emm_mappings,sizeof(emm_mappings)); + reg_ah=EMM_RestoreMappingTable(); + break; + case 0x02: /* Save and Restore Page Map */ + MEM_BlockWrite(SegPhys(es)+reg_di,emm_mappings,sizeof(emm_mappings)); + MEM_BlockRead(SegPhys(ds)+reg_si,emm_mappings,sizeof(emm_mappings)); + reg_ah=EMM_RestoreMappingTable(); + break; + case 0x03: /* Get Page Map Array Size */ + reg_al=sizeof(emm_mappings); + reg_ah=EMM_NO_ERROR; + break; + default: + LOG_ERROR("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); + reg_ah=EMM_FUNC_NOSUP; + break; + } break; case 0xDE: /* VCPI Functions */ LOG_ERROR("VCPI Functions not supported"); - reg_ah=0x8c; + reg_ah=EMM_FUNC_NOSUP; break; default: LOG_ERROR("EMS:Call %2X not supported",reg_ah); - reg_ah=0x8c; + reg_ah=EMM_FUNC_NOSUP; break; } return CBRET_NONE; @@ -138,28 +330,34 @@ void EMS_Init(void) { call_int67=CALLBACK_Allocate(); CALLBACK_Setup(call_int67,&INT67_Handler,CB_IRET); /* Register the ems device */ - DOS_Device * newdev = new device_EMS(); + DOS_Device * newdev = new device_EMM(); DOS_AddDevice(newdev); -/* Setup the page handlers for the page frame */ - for (Bitu i=0;i<4;i++) { - ems_entries[i].base=(PAGEFRAME_SEG<<4)+i*16*1024; - ems_entries[i].type=MEMORY_RELOCATE; - ems_entries[i].relocate=memory+(PAGEFRAME_SEG<<4)+i*16*1024; -/* Place the page handlers in the ems page fram piece of the memory handler*/ - MEMORY_SetupHandler(((PAGEFRAME_SEG<<4)+i*16*1024)>>12,4,&ems_entries[i]); - } /* Add a little hack so it appears that there is an actual ems device installed */ char * emsname="EMMXXXX0"; Bit16u seg=DOS_GetMemory(2); //We have 32 bytes - MEM_BlockWrite(real_phys(seg,0xa),emsname,strlen(emsname)+1); -/* Copy the callback piece into the beginning */ + MEM_BlockWrite(PhysMake(seg,0xa),emsname,strlen(emsname)+1); +/* Copy the callback piece into the beginning, and set the interrupt vector to it*/ char buf[16]; - MEM_BlockRead(real_phys(CB_SEG,call_int67<<4),buf,0xa); - MEM_BlockWrite(real_phys(seg,0),buf,0xa); - + MEM_BlockRead(PhysMake(CB_SEG,call_int67<<4),buf,0xa); + MEM_BlockWrite(PhysMake(seg,0),buf,0xa); RealSetVec(0x67,RealMake(seg,0)); +/* Clear handle and page tables */ + Bitu i; + for (i=0;i Date: Wed, 21 Aug 2002 14:29:08 +0000 Subject: [PATCH 0121/4131] 0x85 Test Ed,GD opcode added Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@198 --- src/cpu/core_16/prefix_66.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index 5af2a12f..344a9d9b 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -230,6 +230,8 @@ switch(Fetchb()) { } } break; + case 0x85: /* TEST Ed,Gd */ + RMEdGd(TESTD);break; case 0x8f: /* POP Ed */ { GetRM; From a26d7e5ea8c68326418dbc799dee77d7f43f3cdc Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 21 Aug 2002 18:15:19 +0000 Subject: [PATCH 0122/4131] Fixed small bug in isvalid. Not all illegal chars were recognized. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@199 --- src/dos/dos_files.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 3600b7ce..e0299d0e 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -499,15 +499,12 @@ static bool FCB_MakeName (DOS_FCB* fcb, char* outname, Bit8u* outdrive){ return DOS_MakeName(naam,outname, outdrive); } #define FCB_SEP ":.;,=+" -#define ILLEGAL ":.;,=+ \t/\"[]<>|\0x0\0x1\0x2\0x3\0x4\0x5\0x6\0x7\0x8\0x9\0xA\0xB\0xC\0xD\0xE\0xF\0x10\0x11\0x12\0x13\0x14\0x15\0x16\0x17\0x18x\0x19\0x1A\0x1B\0x1C\0x1D\0x1E\0x1F" +#define ILLEGAL ":.;,=+ \t/\"[]<>|" static bool isvalid(const char* in){ - char ill[]=ILLEGAL; - char a[2]; - a[0]=*in;a[1]='\0'; - if(strcspn(a,ill)==0) return false; - return true; - + + const char ill[]=ILLEGAL; + return (*in>0x1F) && (strchr(ill,*in)==0); } static void vullen (char* veld,char* pveld){ From c1b9030aaa484cebf8df7e2bb7559d93a9e0700d Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 21 Aug 2002 18:24:50 +0000 Subject: [PATCH 0123/4131] Fixed small bug in isvalid. Not all illegal chars were recognized. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@200 --- src/dos/dos_files.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index e0299d0e..f1484048 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -504,7 +504,7 @@ static bool FCB_MakeName (DOS_FCB* fcb, char* outname, Bit8u* outdrive){ static bool isvalid(const char* in){ const char ill[]=ILLEGAL; - return (*in>0x1F) && (strchr(ill,*in)==0); + return (Bit8u(*in)>0x1F) && (strchr(ill,*in)==0); } static void vullen (char* veld,char* pveld){ From 3650edab856d70c8eae9e37088002fb63e645e0f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 21 Aug 2002 22:23:10 +0000 Subject: [PATCH 0124/4131] Added lock count and get EMB block information call. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@201 --- src/ints/xms.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index f8b7e1a7..d08bd651 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -58,6 +58,7 @@ struct XMS_Block { Bit16u prev,next; Bit16u size; /* Size in kb's */ PhysPt phys; + Bit8u locked; void * data; bool active; }; @@ -155,8 +156,10 @@ foundnew: xms_handles[new_index].next=xms_handles[index].next; xms_handles[new_index].prev=index; xms_handles[index].next=new_index; + xms_handles[index].locked=0; xms_handles[new_index].active=true; xms_handles[new_index].data=0; + xms_handles[new_index].locked=0; xms_handles[new_index].size=xms_handles[index].size-reg_dx; xms_handles[new_index].phys=xms_handles[index].phys+reg_dx*1024; xms_handles[index].size=reg_dx; @@ -275,6 +278,7 @@ foundnew: reg_bl=XMS_INVALID_HANDLE; return CBRET_NONE; } + if (xms_handles[reg_dx].locked<255) xms_handles[reg_dx].locked++; reg_bx=(Bit16u)(xms_handles[reg_dx].phys & 0xFFFF); reg_dx=(Bit16u)(xms_handles[reg_dx].phys>>16); reg_ax=1; @@ -287,9 +291,21 @@ foundnew: reg_bl=XMS_INVALID_HANDLE; return CBRET_NONE; } + if (xms_handles[reg_dx].locked) xms_handles[reg_dx].locked--; reg_ax=1;reg_bl=0; break; case XMS_GET_EMB_HANDLE_INFORMATION: /* 0e */ + /* Check for a valid handle */ + if (!reg_dx || (reg_dx>=XMS_HANDLES) || !xms_handles[reg_dx].active || !xms_handles[reg_dx].data ) { + reg_ax=0; + reg_bl=XMS_INVALID_HANDLE; + return CBRET_NONE; + } + reg_bh=xms_handles[reg_dx].locked; + /* Find available blocks */ + reg_bx=0;{ for (Bitu i=0;i Date: Thu, 22 Aug 2002 10:47:25 +0000 Subject: [PATCH 0125/4131] C_MAX_MEMSIZE - > C_MAX_MEM_SIZE Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@202 --- config.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.h.in b/config.h.in index 8f38384e..c1b900b8 100644 --- a/config.h.in +++ b/config.h.in @@ -34,7 +34,7 @@ #define C_FPU 0 /* Maximum amount of memory we can support in megabytes*/ -#define C_MEM_MAXSIZE 16 +#define C_MEM_MAX_SIZE 16 /* Maximum memory available for xms, should be lower than maxsize-1 */ #define C_MEM_XMS_SIZE 8 From 86f7adfed59119813d8048904991734080a9a24c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 22 Aug 2002 18:09:58 +0000 Subject: [PATCH 0126/4131] settings.h is back Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@203 --- settings.h.cvs | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 settings.h.cvs diff --git a/settings.h.cvs b/settings.h.cvs new file mode 100644 index 00000000..b3933b34 --- /dev/null +++ b/settings.h.cvs @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _SETTINGS_H_ +#define _SETTINSG_H_ + +/* Enable the debugger, this only seems to work in win32 for now. */ +#define C_DEBUG 0 + +/* Enable the logging of extra information for debugging to the console */ +#define C_LOGGING 0 + +/* Use multi threading to speed up things on multi cpu's, also gives a nice frame-skipping effect :) */ +#define C_THREADED 1 + +/* Enable some big compile-time increasing inlines, great for speed though */ +#define C_EXTRAINLINE 0 + +/* Enable the FPU module, still only for beta testing */ +#define C_FPU 0 + +/* Maximum memory range in megabytes */ +#define C_MEM_MAX_SIZE 12 + +/* Maximum memory available for xms, should be lower than maxsize-1 */ +#define C_MEM_XMS_SIZE 8 + +/* Maximum memory available for ems, should be lower than 32 */ +#define C_MEM_EMS_SIZE 4 + +/* Enable debug messages for several modules, requires C_LOGGING */ +#define DEBUG_SBLASTER 0 /* SoundBlaster Debugging*/ +#define DEBUG_DMA 0 /* DMA Debugging */ +#define DEBUG_DOS 0 /* DOS Debugging */ + +#define LOG_MSG S_Warn + +#if 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 + +#endif From f697ef756a28d4e61b33efe36096c0a75df62ec4 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 23 Aug 2002 11:53:24 +0000 Subject: [PATCH 0127/4131] fixed close dosbox crash. Added GFX_Stop in E_Exit. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@204 --- src/misc/support.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 0772332f..42959512 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -26,7 +26,7 @@ #include #include "dosbox.h" #include "support.h" - +#include "video.h" /* Ripped some source from freedos for this one. @@ -230,6 +230,7 @@ void E_Exit(char * format,...) { printf(buf); printf("Press ENTER to stop\n"); fgetc(stdin); - exit(2); + GFX_Stop(); + exit(2); }; \ No newline at end of file From 63589f9e09bb73977d1c855a9b1d141bb94f70a5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 23 Aug 2002 12:35:24 +0000 Subject: [PATCH 0128/4131] preparations for 0.55 release Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@205 --- NEWS | 15 +++++++++++++++ VERSION | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index ba304e25..37cedce4 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,18 @@ +0.55: + - changed basedir handling. (linux/winXP) + - added some FCB-calls + - improved support for user mousehandlers + - fixed EGA graphics + - fixed VGA graphics + - fixed the displaying of text in some graphics modes + - fixed write with size 0 + - changed memory management. + - added full emm 3.2 support. + - fixed and cleaned up the cpu flags. + changed interrupt handler. + - speeded up the graphics. + - speeded up the cpu-core + 0.50: -added F3 to repeat the last typed command. -made it possible to change the shellmessages(dosshell). so diff --git a/VERSION b/VERSION index 2f20b8fe..575fe780 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.50 \ No newline at end of file +0.55 \ No newline at end of file From a320c1d9f619d2d79a358948861e81dcc57c262e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 24 Aug 2002 07:49:58 +0000 Subject: [PATCH 0129/4131] New Autoheader scripts to create a better config.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@206 --- acinclude.m4 | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index 28772e8e..825305ca 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -159,3 +159,31 @@ int main (int argc, char *argv[]) AC_SUBST(SDL_LIBS) rm -f conf.sdltest ]) + +AH_TOP([ +/* + * 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. + */ +]) +AH_BOTTOM([#define INLINE inline]) +AH_BOTTOM([ +#if C_HAS_ATTRIBUTE +#define GCC_ATTRIBUTE __attribute__ +#else +#define GCC_ATTRIBUTE(x) /* attribute not supported */ +#endif +}) \ No newline at end of file From 92aa05ad8ab7c80af3d4e9b9d3fff4e6c231714b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 24 Aug 2002 07:51:05 +0000 Subject: [PATCH 0130/4131] Version 0.55 and disabling attributes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@207 --- src/platform/visualc/config.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 9ad95e12..114b25bd 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -1,5 +1,6 @@ #define INLINE __forceinline -#define VERSION "0.50" +#define VERSION "0.55" + +#define GCC_ATTRIBUTE(x) /* attribute not supported */ -/* Euhm */ From 2df7210adb497477c1e945eb65ce6f8bcef5b379 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 24 Aug 2002 07:52:33 +0000 Subject: [PATCH 0131/4131] Fixed ADPCM and support for the new dma functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@208 --- src/hardware/sblaster.cpp | 106 ++++++++++++++++++++++---------------- 1 file changed, 62 insertions(+), 44 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 10699de6..6962c39b 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -75,8 +75,11 @@ struct SB_INFO { Bit8u data_out[DSP_BUFSIZE]; Bit8u data_out_pos; Bit8u data_out_used; - Bit8u dac_data[DSP_DACSIZE]; - Bit32u dac_used; + struct { + Bit8u data[DSP_DACSIZE]; + Bitu used; + Bit8u last; + } dac; Bit8u test_register; /*ADPCM Part */ Bits adpcm_reference; @@ -175,7 +178,7 @@ static void DSP_StartDMATranfser(Bit8u mode) { break; case MODE_ADPCM_4S: - MIXER_SetFreq(sb.chan,sb.freq*2); + MIXER_SetFreq(sb.chan,sb.freq); SB_DEBUG("DSP:ADPCM 4 bit single cycle rate %d size %X",sb.freq,sb.samples_total); break; @@ -204,7 +207,8 @@ static void DSP_Reset(void) { sb.cmd_len=0; sb.cmd_in_pos=0; sb.use_time_constant=false; - sb.dac_used=0; + sb.dac.used=0; + sb.dac.last=0x80; e2_value=0xaa; e2_count=0; DSP_HaltDMA(); @@ -229,8 +233,8 @@ static void DSP_DoCommand(void) { switch (sb.cmd) { case 0x10: /* Direct DAC */ sb.mode=MODE_DAC; - if (sb.dac_used0) { - *(stream++)=sb.dac_data[dac_pos>>16]; - dac_pos+=dac_add; + if (sb.dac.used) { + Bitu dac_add=(sb.dac.used<<16)/len; + Bitu dac_pos=0; + while (len-->0) { + *(stream++)=sb.dac.data[dac_pos>>16]; + dac_pos+=dac_add; + } + dac_pos-=dac_add; + sb.dac.last=sb.dac.data[dac_pos>>16]; + sb.dac.used=0; + } else { + memset(stream,sb.dac.last,len); } } - sb.dac_used=0; - sb.mode=MODE_NONE; break; case MODE_PCM_8A: - DMA_8_Read(sb.dma,stream,(Bit16u)len); - if (sb.samples_left>len) { - sb.samples_left-=len; - } else { - if (len>(sb.samples_total+sb.samples_left)) sb.samples_left=sb.samples_total; - else sb.samples_left=sb.samples_total+sb.samples_left-len; - PIC_ActivateIRQ(sb.irq); + { + Bit16u read=DMA_8_Read(sb.dma,stream,(Bit16u)len); + if (sb.samples_left>read) { + sb.samples_left-=read; + } else { + if (read>(sb.samples_total+sb.samples_left)) sb.samples_left=sb.samples_total; + else sb.samples_left=sb.samples_total+sb.samples_left-read; + PIC_ActivateIRQ(sb.irq); + } + if (read=len) { - DMA_8_Read(sb.dma,stream,(Bit16u)len); - sb.samples_left-=len; - } else if (sb.samples_left && (sb.samples_left=len) { + read=DMA_8_Read(sb.dma,stream,(Bit16u)len); + sb.samples_left-=read; + } else { + read=DMA_8_Read(sb.dma,stream,(Bit16u)sb.samples_left); + sb.samples_left=0; + } + if (read=dma_size) { - DMA_8_Read(sb.dma,decode_pos,(Bit16u)dma_size); - sb.samples_left-=dma_size; + read=DMA_8_Read(sb.dma,decode_pos,(Bit16u)dma_size); } else if (sb.samples_left0;i--) { *stream++=decode_ADPCM_4_sample(*decode_pos >> 4,sb.adpcm_reference,sb.adpcm_scale); *stream++=decode_ADPCM_4_sample(*decode_pos++ ,sb.adpcm_reference,sb.adpcm_scale); @@ -501,7 +518,8 @@ static void SBLASTER_CallBack(Bit8u * stream,Bit32u len) { sb.adpcm_remain=-1; } } - } + break; + } /* End switch */ } From 2595739e1439944d6f7f3dcd50d3ff98caeb893c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 24 Aug 2002 07:53:37 +0000 Subject: [PATCH 0132/4131] Change to use internal memory and masking bit to disable the channel. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@209 --- src/hardware/dma.cpp | 51 +++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index a9f2ebe0..2a50e178 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -57,7 +57,7 @@ struct DMA_CHANNEL { Bit32u current_count; Bit8u page; bool masked; - HostPt host_address; + PhysPt address; bool addr_changed; }; @@ -142,73 +142,62 @@ void write_dma_page(Bit32u port,Bit8u val) { } } -void DMA_8_Read(Bit32u dmachan,Bit8u * buffer,Bit16u count) { +Bit16u DMA_8_Read(Bit32u dmachan,Bit8u * buffer,Bit16u count) { DMA_CHANNEL * chan=&dma[0].chan[dmachan]; + if (chan->masked) return 0; + if (!count) return 0; /* DMA always does autoinit should work under normal situations */ if (chan->addr_changed) { /* Calculate the new starting position for dma read*/ chan->addr_changed=false; - chan->host_address=memory+(chan->page << 16)+chan->base_address; + chan->address=(chan->page << 16)+chan->base_address; chan->current_count=chan->base_count+1; chan->current_address=chan->base_address; DMA_DEBUG("DMA:Transfer from %d size %d",(chan->page << 16)+chan->base_address,chan->current_count); } - if (!count) return; if (chan->current_count>=count) { - memcpy(buffer,chan->host_address,count); - chan->host_address+=count; + MEM_BlockRead(chan->address,buffer,count); + chan->address+=count; chan->current_address+=count; chan->current_count-=count; - return; + return count; } else { /* Copy remaining piece of first buffer */ - memcpy(buffer,chan->host_address,chan->current_count); + MEM_BlockRead(chan->address,buffer,chan->current_count); buffer+=chan->current_count; count-=(Bit16u)chan->current_count; /* Autoinit reset the dma channel */ - chan->host_address=memory+(chan->page << 16)+chan->base_address; + chan->address=(chan->page << 16)+chan->base_address; chan->current_count=chan->base_count+1; chan->current_address=chan->base_address; /* Copy the rest of the buffer */ - memcpy(buffer,chan->host_address,count); - chan->host_address+=count; + MEM_BlockRead(chan->address,buffer,count); + chan->address+=count; chan->current_address+=count; chan->current_count-=count; - return; + return count; } }; -void DMA_8_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count) { - if (dma[0].chan[dmachan].addr_changed) { - /* Calculate the new starting position for dma read*/ - dma[0].chan[dmachan].addr_changed=false; - dma[0].chan[dmachan].host_address=memory+(dma[0].chan[dmachan].page << 16)+dma[0].chan[dmachan].base_address; - dma[0].chan[dmachan].current_count=dma[0].chan[dmachan].base_count; - dma[0].chan[dmachan].current_count=dma[0].chan[dmachan].current_count; - } - if (dma[0].chan[dmachan].current_count>=count) { - memcpy(dma[0].chan[dmachan].host_address,buffer,count); - dma[0].chan[dmachan].host_address+=count; - dma[0].chan[dmachan].current_address+=count; - dma[0].chan[dmachan].current_count-=count; - return; - } else { +Bit16u DMA_8_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count) { - } - return; + return 0; }; -void DMA_16_Read(Bit32u dmachan,Bit8u * buffer,Bit16u count) { +Bit16u DMA_16_Read(Bit32u dmachan,Bit8u * buffer,Bit16u count) { + return 0; } -void DMA_16_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count) { +Bit16u DMA_16_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count) { + + return 0; } From 3cfd70ef8866bb4d4093e3916ea1616d7d8a4d7f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 24 Aug 2002 07:56:14 +0000 Subject: [PATCH 0133/4131] New dma functions returning amount read/written Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@210 --- include/dma.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/dma.h b/include/dma.h index e6923daa..56a271ba 100644 --- a/include/dma.h +++ b/include/dma.h @@ -16,9 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -void DMA_8_Read(Bit32u channel,Bit8u * buffer,Bit16u count); -void DMA_8_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count); -void DMA_16_Read(Bit32u channel,Bit8u * buffer,Bit16u count); -void DMA_16_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count); +Bit16u DMA_8_Read(Bit32u channel,Bit8u * buffer,Bit16u count); +Bit16u DMA_8_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count); + +Bit16u DMA_16_Read(Bit32u channel,Bit8u * buffer,Bit16u count); +Bit16u DMA_16_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count); From 7d23bccc72639d61d2d060ddc10210bbc1b28bd3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 24 Aug 2002 09:21:38 +0000 Subject: [PATCH 0134/4131] Hopefully final config setting now Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@211 --- include/dosbox.h | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/include/dosbox.h b/include/dosbox.h index c9ddd480..b277391d 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -19,32 +19,33 @@ #if !defined __DOSBOX_H #define __DOSBOX_H -typedef unsigned char Bit8u; -typedef signed char Bit8s; -typedef unsigned short Bit16u; -typedef signed short Bit16s; -typedef unsigned long Bit32u; -typedef signed long Bit32s; -typedef double Real64; + +void E_Exit(char * message,...); + +void S_Warn(char * message,...); + +/* The internal types */ +typedef unsigned char Bit8u; +typedef signed char Bit8s; +typedef unsigned short Bit16u; +typedef signed short Bit16s; +typedef unsigned long Bit32u; +typedef signed long Bit32s; +typedef double Real64; #if defined(_MSC_VER) -typedef unsigned __int64 Bit64u; -typedef signed __int64 Bit64s; +typedef unsigned __int64 Bit64u; +typedef signed __int64 Bit64s; #else -typedef unsigned long long int Bit64u; -typedef signed long long int Bit64s; +typedef unsigned long long Bit64u; +typedef signed long long Bit64s; #endif typedef unsigned int Bitu; typedef signed int Bits; #include - -void E_Exit(char * message,...); - -void S_Warn(char * message,...); - - -#include "../config.h" +#include "config.h" +#include "../settings.h" typedef Bitu (LoopHandler)(void); @@ -54,5 +55,7 @@ void DOSBOX_SetNormalLoop(); void DOSBOX_Init(int argc, char* argv[]); void DOSBOX_StartUp(void); + + #endif From 401169e0b4ef4faff8f6f5416aa46976aa87e7dd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 24 Aug 2002 20:01:55 +0000 Subject: [PATCH 0135/4131] Added autoheader again Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@212 --- autogen.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autogen.sh b/autogen.sh index 7c1b9da5..8b08a7e8 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,17 +1,17 @@ #!/bin/sh -# -echo "Generating build information using aclocal, automake and autoconf" + +echo "Generating build information using aclocal, autoheader, automake and autoconf" echo "This may take a while ..." -# Touch the timestamps on all the files since CVS messes them up -directory=`dirname $0` -touch $directory/configure.in - -# Regenerate configuration files +# Regenerate configuration files. aclocal +autoheader automake --gnits --include-deps --add-missing --copy autoconf +#Copy settings.h.cvs to settings.h and that's it, + +directory=`dirname $0` cp $directory/settings.h.cvs $directory/settings.h echo "Now you are ready to run ./configure also check settings.h for extra build settings" From 8dc6bb35ca42d7498e930b5b6dadddb9481fd946 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 25 Aug 2002 12:03:27 +0000 Subject: [PATCH 0136/4131] Change version to 0.55 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@213 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index b5fb6f03..c0cb9671 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Init. -AC_INIT(dosbox,0.50) +AC_INIT(dosbox,0.55) AC_CONFIG_SRCDIR(README) dnl Detect the canonical host and target build environment From 4e5fe4159fe3b1f0025c17802844bbd6419986a9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 25 Aug 2002 15:36:55 +0000 Subject: [PATCH 0137/4131] Rewrote C_HAS_ATTRIBUTE stuff Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@214 --- acinclude.m4 | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 825305ca..b5306b75 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -179,11 +179,16 @@ AH_TOP([ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ]) + +AH_TEMPLATE([C_HAS_ATTRIBUTE],[Determines if the compilers supports attributes for structures]) + AH_BOTTOM([#define INLINE inline]) -AH_BOTTOM([ -#if C_HAS_ATTRIBUTE + +AH_BOTTOM([#if C_HAS_ATTRIBUTE #define GCC_ATTRIBUTE __attribute__ #else #define GCC_ATTRIBUTE(x) /* attribute not supported */ -#endif -}) \ No newline at end of file +#endif]) + + + From d188ba8f5b845980fbb55c52ff49d8031027ee79 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 25 Aug 2002 16:35:47 +0000 Subject: [PATCH 0138/4131] Removed a faulty constructor line Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@215 --- src/ints/ems.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 3dafc2ef..15038096 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -74,7 +74,6 @@ public: private: Bit8u cache; }; -device_EMM::device_EMM(); struct EMM_Mapping { Bit16u handle; From c80281976f40a3ca7ac0a0c5924d59a0c14aacbc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 25 Aug 2002 16:36:51 +0000 Subject: [PATCH 0139/4131] Test for too high drive setting and included for toupper Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@216 --- src/dos/dos_files.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index f1484048..4ee82a0c 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -19,6 +19,8 @@ #include #include #include +#include + #include "dosbox.h" #include "mem.h" #include "cpu.h" @@ -39,7 +41,7 @@ Bit8u DOS_GetDefaultDrive(void) { } void DOS_SetDefaultDrive(Bit8u drive) { - CurrentDrive=drive; + if (drive<=DOS_DRIVES) CurrentDrive=drive; } bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { From 263d74180f70d9f966a52911cee9d175d3ac8bec Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 25 Aug 2002 16:37:17 +0000 Subject: [PATCH 0140/4131] Added MEM and cleaned up a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@217 --- src/dos/dos_programs.cpp | 141 ++++++++++++++++++++------------------- 1 file changed, 73 insertions(+), 68 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index f1e3c947..5a2857d0 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -23,96 +23,101 @@ #include "support.h" #include "drives.h" #include "cross.h" - +#include "regs.h" +#include "callback.h" class MOUNT : public Program { public: - MOUNT(PROGRAM_Info * program_info); - void Run(void); -}; - - -MOUNT::MOUNT(PROGRAM_Info * info):Program(info) { - -} - - -void MOUNT::Run(void) { -/* Parse the command line */ - /* if the command line is empty show current mounts */ - - if (!*prog_info->cmd_line) { - WriteOut("Current mounted drives are\n"); - for (int d=0;dGetInfo()); + MOUNT(PROGRAM_Info * program_info):Program(program_info){}; + void Run(void){ + /* Parse the command line */ + /* if the command line is empty show current mounts */ + if (!*prog_info->cmd_line) { + WriteOut("Current mounted drives are\n"); + for (int d=0;dGetInfo()); + } } + return; } - return; - } - char drive; - drive=toupper(*prog_info->cmd_line); - char * dir=strchr(prog_info->cmd_line,' '); - if (dir) { - if (!*dir) dir=0; - else dir=trim(dir); - }; + char drive; drive=toupper(*prog_info->cmd_line); - if (!isalpha(drive) || !dir) { - WriteOut("Usage MOUNT Drive-Letter Local-Directory\nSo a MOUNT c c:\\windows mounts windows directory as the c: drive in DOSBox\n"); - return; - }; - struct stat test; - if (stat(dir,&test)) { - WriteOut("Directory %s Doesn't exist",dir); - return; + char * dir=strchr(prog_info->cmd_line,' '); if (dir) { + if (!*dir) dir=0; + else dir=trim(dir); + } + if (!isalpha(drive) || !dir) { + WriteOut("Usage MOUNT Drive-Letter Local-Directory\nSo a MOUNT c c:\\windows mounts windows directory as the c: drive in DOSBox\n"); + return; + }; + struct stat test; + if (stat(dir,&test)) { + WriteOut("Directory %s Doesn't exist",dir); + return; + } + /* Not a switch so a normal directory/file */ + if (!(test.st_mode & S_IFDIR)) { + WriteOut("%s isn't a directory",dir); + return; + } + if (Drives[drive-'A']) { + WriteOut("Drive %c already mounted with %s\n",drive,Drives[drive-'A']->GetInfo()); + return; + } + char fulldir[DOS_PATHLENGTH]; + strcpy(fulldir,dir); + static char theend[2]={CROSS_FILESPLIT,0}; + char * last=strrchr(fulldir,CROSS_FILESPLIT); + if (!last || *(++last)) strcat(fulldir,theend); + Drives[drive-'A']=new localDrive(fulldir); + WriteOut("Mounting drive %c as %s\n",drive,fulldir); } - /* Not a switch so a normal directory/file */ - if (!(test.st_mode & S_IFDIR)) { - WriteOut("%s isn't a directory",dir); - return; - } - if (Drives[drive-'A']) { - WriteOut("Drive %c already mounted with %s\n",drive,Drives[drive-'A']->GetInfo()); - return; - } - char fulldir[DOS_PATHLENGTH]; - strcpy(fulldir,dir); - static char theend[2]={CROSS_FILESPLIT,0}; - char * last=strrchr(fulldir,CROSS_FILESPLIT); - if (!last || *(++last)) strcat(fulldir,theend); - Drives[drive-'A']=new localDrive(fulldir); - WriteOut("Mounting drive %c as %s\n",drive,fulldir); -} +}; static void MOUNT_ProgramStart(PROGRAM_Info * info) { MOUNT * tempmount=new MOUNT(info); - tempmount->Run(); + tempmount->Run() ; delete tempmount; } - class MEM : public Program { public: - MEM(PROGRAM_Info * program_info); - void Run(void); + MEM(PROGRAM_Info * program_info):Program(program_info){}; + void Run(void) { + /* Show conventional Memory */ + WriteOut("\n"); + Bit16u seg,blocks;blocks=0xffff; + DOS_AllocateMemory(&seg,&blocks); + WriteOut("%10d Kb free conventional memory\n",blocks*16/1024); + /* Test for and show free XMS */ + reg_ax=0x4300;CALLBACK_RunRealInt(0x2f); + if (reg_al==0x80) { + reg_ax=0x4310;CALLBACK_RunRealInt(0x2f); + Bit16u xms_seg=SegValue(es);Bit16u xms_off=reg_bx; + reg_ah=8; + CALLBACK_RunRealFar(xms_seg,xms_off); + if (!reg_bl) { + WriteOut("%10d Kb free extended memory\n",reg_dx); + } + } + /* Test for and show free EMS */ + Bit16u handle; + if (DOS_OpenFile("EMMXXXX0",0,&handle)) { + DOS_CloseFile(handle); + reg_ah=0x42; + CALLBACK_RunRealInt(0x67); + WriteOut("%10d Kb free expanded memory\n",reg_bx*16); + } + } }; -MEM::MEM(PROGRAM_Info * info):Program(info) { - -} - - -void MEM::Run(void) { - -} static void MEM_ProgramStart(PROGRAM_Info * info) { MEM mem(info); mem.Run(); - } @@ -203,7 +208,7 @@ static void UPCASE_ProgramStart(PROGRAM_Info * info) { void DOS_SetupPrograms(void) { PROGRAMS_MakeFile("MOUNT.COM",MOUNT_ProgramStart); -// PROGRAMS_MakeFile("MEM.COM",MEM_ProgramStart); /*next release */ + PROGRAMS_MakeFile("MEM.COM",MEM_ProgramStart); #if !defined (WIN32) /* Unix */ PROGRAMS_MakeFile("UPCASE.COM",UPCASE_ProgramStart); #endif From 4ff0164543893511848befa51831a76f716d19b6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 25 Aug 2002 16:38:01 +0000 Subject: [PATCH 0141/4131] removed push/pop from #pragma pack Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@218 --- src/dos/dos_classes.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 51748613..42c14913 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -29,7 +29,7 @@ dos work a bit easier. */ -#pragma pack (push,1) +#pragma pack (1) struct sPSP { Bit8u exit[2]; /* CP/M-like exit poimt */ @@ -86,7 +86,7 @@ struct sFCB { Bit32u rel_record; //open does not handle this } GCC_ATTRIBUTE(packed); -#pragma pack (pop) +#pragma pack () #define sGet(s,m) GetIt(((s *)0)->m,(PhysPt)&(((s *)0)->m)) #define sSave(s,m,val) SaveIt(((s *)0)->m,(PhysPt)&(((s *)0)->m),val) From 2c911b659fdf2a4a3795b4f07fbbcc468ee99324 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 25 Aug 2002 16:38:40 +0000 Subject: [PATCH 0142/4131] Added 0x00 group 7 to generate interrupt 6 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@219 --- src/cpu/core_16/prefix_of.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h index e92594d8..951ef21b 100644 --- a/src/cpu/core_16/prefix_of.h +++ b/src/cpu/core_16/prefix_of.h @@ -17,6 +17,18 @@ */ switch(Fetchb()) { + case 0x00: /* GRP 6 */ + { + INTERRUPT(6); + break; + GetRM; + switch (rm & 0x38) { + default: + E_Exit("CPU:GRP6:Illegal call %2X",(rm>>3) &3); + } + } + break; + case 0x01: /* GRP 7 */ { GetRM; @@ -27,7 +39,7 @@ switch(Fetchb()) { else {GetEAa;SaveMw(eaa,0);} break; default: - E_Exit("CPU:GRP7:Illegal call %2X",rm); + E_Exit("CPU:GRP7:Illegal call %2X",(rm>>3) &3); } } break; From b428e51d3d2a5357e75d6ce41c91b26d98a0bfd7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 25 Aug 2002 16:39:45 +0000 Subject: [PATCH 0143/4131] Fix to GCC_ATTRIBUTE Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@220 --- acinclude.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index b5306b75..2491c4e5 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -185,7 +185,7 @@ AH_TEMPLATE([C_HAS_ATTRIBUTE],[Determines if the compilers supports attributes f AH_BOTTOM([#define INLINE inline]) AH_BOTTOM([#if C_HAS_ATTRIBUTE -#define GCC_ATTRIBUTE __attribute__ +#define GCC_ATTRIBUTE(x) __attribute__ ((x)) #else #define GCC_ATTRIBUTE(x) /* attribute not supported */ #endif]) From 1c7a406c70a81100993757e80d5adb9f8ab9e246 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 25 Aug 2002 16:40:14 +0000 Subject: [PATCH 0144/4131] No longer needed, generated by autoheader Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@221 --- config.h.in | 106 ---------------------------------------------------- 1 file changed, 106 deletions(-) delete mode 100644 config.h.in diff --git a/config.h.in b/config.h.in deleted file mode 100644 index c1b900b8..00000000 --- a/config.h.in +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2002 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _CONFIG_H_ -#define _CONFIG_H_ - -#define VERSION "0.50" - -/* Enable the debugger, this only seems to work in win32 for now. */ -#define C_DEBUG 0 - -/* Enable the logging of extra information for debugging to the console */ -#define C_LOGGING 0 - -/* Use multi threading to speed up things on multi cpu's, also gives a nice frame-skipping effect :) */ -#define C_THREADED 1 - -/* Enable the FPU module, still only for beta testing */ -#define C_FPU 0 - -/* Maximum amount of memory we can support in megabytes*/ -#define C_MEM_MAX_SIZE 16 - -/* Maximum memory available for xms, should be lower than maxsize-1 */ -#define C_MEM_XMS_SIZE 8 - -/* Maximum memory available for ems, should be lower than 32 */ -#define C_MEM_EMS_SIZE 4 - - -/* Enable debug messages for several modules, requires C_LOGGING */ -#define DEBUG_SBLASTER 0 /* SoundBlaster Debugging*/ -#define DEBUG_DMA 0 /* DMA Debugging */ -#define DEBUG_DOS 0 /* DOS Debugging */ - -#define LOG_MSG S_Warn - -#if 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 - -/* The internal types */ -typedef unsigned char Bit8u; -typedef signed char Bit8s; -typedef unsigned short Bit16u; -typedef signed short Bit16s; -typedef unsigned long Bit32u; -typedef signed long Bit32s; -typedef double Real64; -#if defined(_MSC_VER) -typedef unsigned __int64 Bit64u; -typedef signed __int64 Bit64s; -#else -typedef unsigned long long Bit64u; -typedef signed long long Bit64s; -#endif - -typedef unsigned int Bitu; -typedef signed int Bits; - - - -/* Use a special def for function inlining */ -#ifdef _MSC_VER -#define INLINE __forceinline -#else -#define INLINE inline -#endif - - - - -/* Do not edit below this line, should all be handled by configure */ - - -// set if your compiler does not understand __attribute__ after a struct -#define C_HAS_ATTRIBUTE 0 -#if C_HAS_ATTRIBUTE -#define GCC_ATTRIBUTE __attribute__ -#else -#define GCC_ATTRIBUTE(x) /* attribute not supported */ -#endif - - -#endif \ No newline at end of file From 4f7748b8ee3e8fe03c0c560c3b572b6d816feb08 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 25 Aug 2002 19:07:19 +0000 Subject: [PATCH 0145/4131] #pragma pack changed Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@222 --- include/dos_inc.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index b666e6b3..3008b103 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -22,7 +22,7 @@ #include #include -#pragma pack (push,1) +#pragma pack (1) struct CommandTail{ Bit8u count; /* number of bytes returned */ @@ -83,9 +83,7 @@ struct MCB { Bit8u filename[8]; } GCC_ATTRIBUTE(packed); -#pragma pack (pop) - - +#pragma pack () struct DOS_Date { Bit16u year; @@ -208,7 +206,7 @@ INLINE Bit16u long2para(Bit32u size) { INLINE Bit8u RealHandle(Bit16u handle) { PSP * psp=(PSP *)HostMake(dos.psp,0); - if (handle>=psp->max_files) return DOS_FILES; + if (handle>=psp->max_files) return 0xff; return mem_readb(Real2Phys(psp->file_table)+handle); }; From c10a532f8892f807d20e24692676b664ff50239d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 25 Aug 2002 21:35:00 +0000 Subject: [PATCH 0146/4131] Correct tables for characters >127 in graphics mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@223 --- src/ints/int10_char.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index f77894e4..10ee6cd5 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -271,7 +271,8 @@ INLINE static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u at switch (curmode->cheight) { case 8: // fontdata=&int10_font_08[chr*8]; - fontdata=Real2Host(RealGetVec(0x43))+chr*8; + if (chr<128) fontdata=Real2Host(RealGetVec(0x43))+chr*8; + else fontdata=Real2Host(RealGetVec(0x1F))+(chr-128)*8; break; case 14: fontdata=&int10_font_14[chr*14]; From 7e46d9c60fdb2229e3bb07e020f6d7f386e92caf Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 25 Aug 2002 22:40:50 +0000 Subject: [PATCH 0147/4131] Fixed bug in popfd, this should remove some trap flag warnings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@224 --- src/cpu/core_16/prefix_66.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index 344a9d9b..aca48e59 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -273,7 +273,8 @@ switch(Fetchb()) { } case 0x9d: /* POPFD */ { - Save_Flagsw((Bit16u)(Pop_32()&0xffff)); + Bit16u val=(Bit16u)(Pop_32()&0xffff); + Save_Flagsw(val); break; } case 0xa1: /* MOV EAX,Ow */ From 8be833ab6cd5acb98a56808089e7055e0dfe9d46 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 26 Aug 2002 06:57:49 +0000 Subject: [PATCH 0148/4131] Write a charctertable in biossegment, fixes sierra games Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@225 --- src/ints/int10_memory.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 252dfd3b..28a5174e 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -67,6 +67,7 @@ void INT10_SetupRomMemory(void) { for (i=0;i<0x10;i++) { real_writeb(0xC000,segoff++,static_functionality[i]); } + MEM_BlockWrite(PhysMake(0xf000,0xfa6e),int10_font_08,128*8); }; From 7349874d3a57cd52432b6e80b3310f199a25363c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 26 Aug 2002 07:45:19 +0000 Subject: [PATCH 0149/4131] Prevent Text drawing from overwriting the screen during resize Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@226 --- src/hardware/vga_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index ec2a3295..2d07ba31 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -52,7 +52,7 @@ void VGA_Render_GFX_256C(Bit8u * * data) { void VGA_Render_TEXT_16(Bit8u * * data) { *data=vga.buffer; - VGA_DrawTEXT(vga.buffer,vga.draw.width); + if (!vga.draw.resizing) VGA_DrawTEXT(vga.buffer,vga.draw.width); vga.config.retrace=true; } From cb780cd6e6fe6e91f3971a052abb7aa4a09657b2 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 27 Aug 2002 10:15:38 +0000 Subject: [PATCH 0150/4131] Added instructions: BSF,BSR,BSWAP Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@227 --- src/cpu/core_16/instructions.h | 3 +++ src/cpu/core_16/prefix_of.h | 44 +++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_16/instructions.h b/src/cpu/core_16/instructions.h index 9863b2e0..8bd1901c 100644 --- a/src/cpu/core_16/instructions.h +++ b/src/cpu/core_16/instructions.h @@ -649,3 +649,6 @@ flags.result.d=(flags.var1.d >> flags.var2.b) | (op2 << (32-flags.var2.b)); \ save(op1,flags.result.d); \ flags.type=t_DSHRd; + +#define BSWAP(op1) \ + op1 = (op1>>24)|((op1>>8)&0xFF00)|((op1<<8)&0xFF0000)|((op1<<24)&0xFF000000); diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h index 951ef21b..5d845201 100644 --- a/src/cpu/core_16/prefix_of.h +++ b/src/cpu/core_16/prefix_of.h @@ -350,7 +350,40 @@ switch(Fetchb()) { if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } break; } - /* 0xbc BSF Gw,Ew */ + case 0xbc: /* 0xbc BSF Gw,Ew */ + { + GetRMrw; + Bit16u result,value; + if (rm >= 0xc0) { GetEArw; value=*earw; } + else { GetEAa; value=LoadMw(eaa); } + if (value==0) { + flags.zf = true; + } else { + result = 0; + while ((value & 0x01)==0) { result++; value>>=1; } + flags.zf = false; + *rmrw = result; + } + flags.type=t_UNKNOWN; + break; + } + case 0xbd: /* 0xbd BSR Gw,Ew */ + { + GetRMrw; + Bit16u result,value; + if (rm >= 0xc0) { GetEArw; value=*earw; } + else { GetEAa; value=LoadMw(eaa); } + if (value==0) { + flags.zf = true; + } else { + result = 15; // Operandsize-1 + while ((value & 0x8000)==0) { result--; value<<=1; } + flags.zf = false; + *rmrw = result; + } + flags.type=t_UNKNOWN; + break; + } /* 0xbd BSR Gw,Ew */ case 0xbe: /* MOVSX Gw,Eb */ { @@ -363,6 +396,15 @@ switch(Fetchb()) { /* 0xc1 XADD Ew,Gw (486) */ /* 0xc7 CMPXCHG8B Mq (P5) */ /* 0xc8-cf BSWAP Rw (odd behavior,486) */ + case 0xc8: BSWAP(reg_eax); break; + case 0xc9: BSWAP(reg_ecx); break; + case 0xca: BSWAP(reg_edx); break; + case 0xcb: BSWAP(reg_ebx); break; + case 0xcc: BSWAP(reg_esp); break; + case 0xcd: BSWAP(reg_ebp); break; + case 0xce: BSWAP(reg_esi); break; + case 0xcf: BSWAP(reg_edi); break; + /* 0xd1 PSRLW Rq,Eq (MMX) */ /* 0xd2 PSRLD Rq,Eq (MMX) */ /* 0xd3 PSRLQ Rq,Eq (MMX) */ From 29354c13908b5893b88d6d34f990ce0c361e92df Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 27 Aug 2002 10:22:53 +0000 Subject: [PATCH 0151/4131] Added class DOS_InfoBlock Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@228 --- include/dos_inc.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/include/dos_inc.h b/include/dos_inc.h index 3008b103..5edb717f 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -282,6 +282,36 @@ private: PhysPt off; }; +class DOS_InfoBlock { +public: + DOS_InfoBlock (void) { seg=0; dib=0; }; + + void SetLocation (Bit16u segment); + void SetFirstMCB (RealPt pt); + void GetDIBPointer (Bit16u& segment, Bit16u& offset); + +private: + #pragma pack (push,1) + struct SDosInfoBlock { + Bit8u stuff1[22]; // some stuff, hopefully never used.... + RealPt firstMCB; // first memory control block + RealPt firstDPB; // first drive parameter block + RealPt firstFileTable; // first system file table + RealPt activeClock; // active clock device header + RealPt activeCon; // active console device header + Bit16u maxSectorLength; // maximum bytes per sector of any block device; + RealPt discInfoBuffer; // pointer to disc info buffer + RealPt curDirStructure; // pointer to current array of directory structure + RealPt fcbTable; // pointer to system FCB table + // some more stuff, hopefully never used. + } GCC_ATTRIBUTE(packed); + #pragma pack (pop) + + SDosInfoBlock* dib; + Bit16u seg; +}; + +extern DOS_InfoBlock dosInfoBlock; #endif From d60f2f6da066a21bddc6a352e029db39ca5e499d Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 27 Aug 2002 10:30:33 +0000 Subject: [PATCH 0152/4131] Added DOS_InfoBlock - firstMCB support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@229 --- src/dos/dos.cpp | 14 ++++++++------ src/dos/dos_classes.cpp | 20 ++++++++++++++++++++ src/dos/dos_memory.cpp | 4 ++++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 33439ad1..a2f40513 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -29,6 +29,8 @@ #include "dos_inc.h" DOS_Block dos; +DOS_InfoBlock dosInfoBlock; + static Bit8u dos_copybuf[0x10000]; static Bitu call_20,call_21,call_theend; @@ -532,7 +534,6 @@ static Bitu DOS_21Handler(void) { CALLBACK_SCF(true); } break; - break; case 0x47: /* CWD Get current directory */ //TODO Memory if (DOS_GetCurrentDir(reg_dl,name1)) { @@ -628,11 +629,12 @@ static Bitu DOS_21Handler(void) { case 0x51: /* Get current PSP */ reg_bx=dos.psp; break; - case 0x52: /* Get list of lists */ - SegSet16(es,0); - reg_bx=0; - LOG_ERROR("Call is made for list of lists not supported let's hope for the best"); - break; + case 0x52: { /* Get list of lists */ + Bit16u seg; + dosInfoBlock.GetDIBPointer(seg,reg_bx); + SegSet16(es,seg); + LOG_DEBUG("Call is made for list of lists - let's hope for the best"); + break; } //TODO Think hard how shit this is gonna be //And will any game ever use this :) case 0x53: /* Translate BIOS parameter block to drive parameter block */ diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 42c14913..04cd8a33 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -266,3 +266,23 @@ RealPt DOS_ParamBlock::cmdtail(void){ return mem_readd(off+offsetof(sParamBlock,exec.cmdtail)); } +// * Dos Info Block (list of lists) * + +void DOS_InfoBlock::SetLocation(Bit16u segment) +{ + seg = segment; + dib = (SDosInfoBlock*)HostMake(segment,0); + Bit16u size = sizeof(SDosInfoBlock); + memset(dib,0,sizeof(SDosInfoBlock)); +}; + +void DOS_InfoBlock::SetFirstMCB(RealPt pt) +{ + dib->firstMCB = pt; +}; + +void DOS_InfoBlock::GetDIBPointer(Bit16u& segment, Bit16u& offset) +{ + segment = seg; + offset = offsetof(SDosInfoBlock,firstDPB); +}; diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 2a4bcc14..14e8a5d9 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -158,5 +158,9 @@ void DOS_SetupMemory(void) { mcb->size=0x9FFE - MEM_START; mcb->type=0x5a; //Last Block dos.firstMCB=MEM_START; + + // Create Dos Info Block : maximum size 95 Bytes.... + dosInfoBlock.SetLocation(DOS_GetMemory(6)); + dosInfoBlock.SetFirstMCB(RealMake(dos.firstMCB,0)); } From 4ef1d210a4c70ebd93b710a5967f5a94431f4923 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 27 Aug 2002 10:34:23 +0000 Subject: [PATCH 0153/4131] Added IOCTL 0x0D/0x60 Get device parameter Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@230 --- src/dos/dos_ioctl.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 382b0bb7..9b253521 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -44,6 +44,21 @@ bool DOS_IOCTL(Bit8u call,Bit16u entry) { LOG_DEBUG("DOS:IOCTL:07:Fakes output status is ready for handle %d",handle); reg_al=0xff; return true; + case 0x0D: { + PhysPt ptr = SegPhys(ds)+reg_dx; + Bit8u drive = reg_bl ? reg_bl : DOS_GetDefaultDrive()+1; // A=1, B=2, C=3... + switch (reg_cl) { + case 0x60 : mem_writeb(ptr ,0x03); // special function + mem_writeb(ptr+1,(drive>=3)?0x05:0x14); // fixed disc(5), 1.44 floppy(14) + mem_writew(ptr+2,drive>=3); // nonremovable ? + mem_writew(ptr+4,0x0000); // num of cylinders + mem_writeb(ptr+6,0x00); // media type (00=other type) + break; + default : LOG_ERROR("DOS:IOCTL Call 0D:%2X Drive %2X unhandled",reg_cl,drive); + return false; + } + return true; + } default: LOG_ERROR("DOS:IOCTL Call %2X Handle %2X unhandled",reg_al,handle); return false; From 812d7a0bf5dfbf3bd8b95edbaddcd531b01cff85 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 27 Aug 2002 10:46:37 +0000 Subject: [PATCH 0154/4131] Set emm-version to 4.0. Added functions 0x50, 0x53, 0x58. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@231 --- src/ints/ems.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 15038096..52b6d7d0 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -35,7 +35,7 @@ #define EMM_MAX_PAGES (C_MEM_EMS_SIZE * 1024 / 16 ) #define EMM_MAX_PHYS 4 /* 4 16kb pages in pageframe */ -#define EMM_VERSION 0x32 +#define EMM_VERSION 0x40 #define NULL_HANDLE 0xffff #define NULL_PAGE 0xffff @@ -311,6 +311,51 @@ static Bitu INT67_Handler(void) { break; } break; + case 0x50: // Map/Unmap multiple handle pages + reg_ah = EMM_NO_ERROR; + switch (reg_al) { + case 0x00: // use physical page numbers + { PhysPt data = SegPhys(ds)+reg_si; + for (int i=0; i Date: Tue, 27 Aug 2002 12:20:13 +0000 Subject: [PATCH 0155/4131] Added help (press h) and fixed some small bugs. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@232 --- src/debug/debug.cpp | 118 +++++++++++++++++++++++++++++--------------- 1 file changed, 78 insertions(+), 40 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 64645566..1389c450 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -77,16 +77,16 @@ static Bit16u dataSeg,dataOfs; enum { BKPNT_REALMODE, BKPNT_PHYSICAL, BKPNT_INTERRUPT }; +#define BPINT_ALL 0x100 + typedef struct SBreakPoint { - PhysPt location; - Bit8u olddata; - Bit16u seg; - Bit16u off_16; - Bit32u off_32; - Bit8u type; - bool once; - bool enabled; - bool active; + PhysPt location; + Bit8u olddata; + Bit8u type; + Bit16u ahValue; + bool once; + bool enabled; + bool active; } TBreakpoint; static std::list BPoints; @@ -96,7 +96,7 @@ static bool IsBreakpoint(PhysPt off) // iterate list and remove TBreakpoint std::list::iterator i; for(i=BPoints.begin(); i != BPoints.end(); i++) { - if ((*i).location==off) return true; + if (((*i).type==BKPNT_PHYSICAL) && ((*i).location==off)) return true; } return false; }; @@ -150,18 +150,16 @@ static void AddBreakpoint(PhysPt off, bool once) bp.enabled = true; bp.active = false; bp.location = off; - bp.off_16 = RealOff(off); - bp.seg = RealSeg(off); bp.once = once; BPoints.push_front(bp); } -static void AddIntBreakpoint(Bit8u intNum, Bit8u ah, bool once) +static void AddIntBreakpoint(Bit8u intNum, Bit16u ah, bool once) { TBreakpoint bp; bp.type = BKPNT_INTERRUPT; bp.olddata = intNum; - bp.location = ah; + bp.ahValue = ah; bp.enabled = true; bp.active = true; bp.once = once; @@ -229,7 +227,7 @@ bool DEBUG_IntBreakpoint(Bit8u intNum) std::list::iterator i; for(i=BPoints.begin(); i != BPoints.end(); ++i) { if ( ((*i).type==BKPNT_INTERRUPT) && (*i).enabled) { - if (((*i).olddata==intNum) && ((*i).location==reg_ah)) { + if (((*i).olddata==intNum) && ( ((*i).ahValue==(Bit16u)reg_ah) || ((*i).ahValue==BPINT_ALL)) ) { if ((*i).active) { found=true; (*i).active=false; @@ -259,13 +257,13 @@ bool DEBUG_IntBreakpoint(Bit8u intNum) static void DrawData(void) { - Bit16u add = 0; + Bit16u add = dataOfs; /* Data win */ for (int y=0; y<8; y++) { // Adress - mvwprintw (dbg.win_data,1+y,0,"%04X:%04X",dataSeg,dataOfs+add); + mvwprintw (dbg.win_data,1+y,0,"%04X:%04X ",dataSeg,add); for (int x=0; x<16; x++) { - Bit8u ch = real_readb(dataSeg,dataOfs+add); + Bit8u ch = real_readb(dataSeg,add); mvwprintw (dbg.win_data,1+y,11+3*x,"%02X",ch); if (ch<32) ch='.'; mvwprintw (dbg.win_data,1+y,60+x,"%c",ch); @@ -317,12 +315,12 @@ static void DrawRegisters(void) { static void DrawCode(void) { Bit32u disEIP = codeViewData.useEIP; - PhysPt start = Segs[cs].phys + codeViewData.useEIP; + PhysPt start = codeViewData.useCS*16 + codeViewData.useEIP; char dline[200];Bitu size;Bitu c; + for (Bit32u i=0;i<10;i++) { - if (has_colors()) { - if (disEIP == reg_eip) { + if ((codeViewData.useCS==SegValue(cs)) && (disEIP == reg_eip)) { wattrset(dbg.win_code,COLOR_PAIR(PAIR_GREEN_BLACK)); if (codeViewData.cursorPos==-1) { codeViewData.cursorPos = i; // Set Cursor @@ -339,7 +337,7 @@ static void DrawCode(void) } size=DasmI386(dline, start, disEIP, false); - mvwprintw(dbg.win_code,i,0,"%02X:%04X ",SegValue(cs),disEIP); + mvwprintw(dbg.win_code,i,0,"%04X:%04X ",codeViewData.useCS,disEIP); for (c=0;c=size*2;c--) waddch(dbg.win_code,' '); waddstr(dbg.win_code,dline); @@ -353,6 +351,7 @@ static void DrawCode(void) codeViewData.useEIPlast = disEIP; + wattrset(dbg.win_code,0); if (!debugging) { mvwprintw(dbg.win_code,10,0,"(Running)",codeViewData.inputStr); } else if (codeViewData.inputMode) { @@ -405,8 +404,7 @@ bool ParseCommand(char* str) found = strstr(str,"BP "); if (found) { // Add new breakpoint found+=3; - Bit16u seg = GetHexValue(found,found); - found++; // skip ":" + Bit16u seg = GetHexValue(found,found);found++; // skip ":" Bit32u ofs = GetHexValue(found,found); AddBreakpoint((seg<<4)+ofs,false); LOG_DEBUG("DEBUG: Set breakpoint at %04X:%04X",seg,ofs); @@ -415,27 +413,64 @@ bool ParseCommand(char* str) found = strstr(str,"BPINT"); if (found) { // Add Interrupt Breakpoint found+=5; - Bit8u intNr = GetHexValue(found,found); + Bit8u intNr = GetHexValue(found,found); found++; Bit8u valAH = GetHexValue(found,found); - AddIntBreakpoint(intNr,valAH,false); - LOG_DEBUG("DEBUG: Set interrupt breakpoint at INT %02X AH=%02X",intNr,valAH); + if ((valAH==0x00) && (*found=='*')) { + AddIntBreakpoint(intNr,BPINT_ALL,false); + LOG_DEBUG("DEBUG: Set interrupt breakpoint at INT %02X",intNr); + } else { + AddIntBreakpoint(intNr,valAH,false); + LOG_DEBUG("DEBUG: Set interrupt breakpoint at INT %02X AH=%02X",intNr,valAH); + } return true; } found = strstr(str,"BPDEL"); - if (found) { // Add Interrupt Breakpoint + if (found) { // Delete Breakpoints (BPoints.clear)(); LOG_DEBUG("DEBUG: Breakpoints deleted."); return true; } - found = strstr(str,"D "); - if (found) { // Add Interrupt Breakpoint + found = strstr(str,"C "); + if (found) { // Set code overview found++; - dataSeg = GetHexValue(found,found); + Bit16u codeSeg = GetHexValue(found,found); found++; + Bit32u codeOfs = GetHexValue(found,found); + LOG_DEBUG("DEBUG: Set code overview to %04X:%04X",codeSeg,codeOfs); + codeViewData.useCS = codeSeg; + codeViewData.useEIP = codeOfs; + return true; + } + found = strstr(str,"D "); + if (found) { // Set data overview + found++; + dataSeg = GetHexValue(found,found); found++; dataOfs = GetHexValue(found,found); LOG_DEBUG("DEBUG: Set data overview to %04X:%04X",dataSeg,dataOfs); return true; } - + if ((*str=='H') || (*str=='?')) { + wprintw(dbg.win_out,"Debugger keys:\n"); + wprintw(dbg.win_out,"-------------------------------------------------------------------------\n"); + wprintw(dbg.win_out,"F5 - Run\n"); + wprintw(dbg.win_out,"F9 - Set/Remove breakpoint\n"); + wprintw(dbg.win_out,"F10/F11 - Step over / trace into instruction\n"); + wprintw(dbg.win_out,"Up/Down - Move code view cursor\n"); + wprintw(dbg.win_out,"Return - Enable command line input\n"); + wprintw(dbg.win_out,"D/E/S/X/B - Set data view to DS:SI/ES:DI/SS:SP/DS:DX/ES:BX\n"); + wprintw(dbg.win_out,"R/F - Scroll data view\n"); + wprintw(dbg.win_out,"\n"); + wprintw(dbg.win_out,"Debugger commands (enter all values in hex):\n"); + wprintw(dbg.win_out,"-------------------------------------------------------------------------\n"); + wprintw(dbg.win_out,"BP [segment]:[offset] - Set breakpoint\n"); + wprintw(dbg.win_out,"BPINT [intNr] * - Set interrupt breakpoint\n"); + wprintw(dbg.win_out,"BPINT [intNr] [ah] - Set interrupt breakpoint with ah\n"); + wprintw(dbg.win_out,"BPDEL - Delete breakpoints\n"); + wprintw(dbg.win_out,"C [segment]:[offset] - Set code view address\n"); + wprintw(dbg.win_out,"D [segment]:[offset] - Set data view address\n"); + wprintw(dbg.win_out,"H - Help\n"); + wrefresh(dbg.win_out); + return TRUE; + } return false; }; @@ -466,7 +501,7 @@ Bit32u DEBUG_CheckKeys(void) { int key=getch(); Bit32u ret=0; if (key>0) { - switch (key) { + switch (toupper(key)) { case '1': ret=(*cpudecoder)(100); break; @@ -485,24 +520,27 @@ Bit32u DEBUG_CheckKeys(void) { case 'q': ret=(*cpudecoder)(5); break; - case 'd': dataSeg = SegValue(ds); + case 'D': dataSeg = SegValue(ds); dataOfs = reg_si; break; - case 'e': dataSeg = SegValue(es); + case 'E': dataSeg = SegValue(es); dataOfs = reg_di; break; - case 'x': dataSeg = SegValue(ds); + case 'X': dataSeg = SegValue(ds); dataOfs = reg_dx; break; - case 'b': dataSeg = SegValue(es); + case 'B': dataSeg = SegValue(es); dataOfs = reg_bx; break; - case 's': dataSeg = SegValue(ss); + case 'S': dataSeg = SegValue(ss); dataOfs = reg_sp; break; - case 'r' : dataOfs -= 16; break; - case 'f' : dataOfs += 16; break; + case 'R' : dataOfs -= 16; break; + case 'F' : dataOfs += 16; break; + case 'H' : strcpy(codeViewData.inputStr,"H "); + ParseCommand(codeViewData.inputStr); + break; case 0x0A : // Return : input codeViewData.inputMode = true; From b987696b5f1280c124120114ca7bb30ffed63f88 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 27 Aug 2002 12:27:59 +0000 Subject: [PATCH 0156/4131] Interrupt -> INTERRUPT Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@233 --- src/cpu/core_16/prefix_66.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index aca48e59..9f1c141a 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -414,13 +414,13 @@ switch(Fetchb()) { Bit32u val; if (rm >= 0xc0 ) {GetEArd;val=*eard;} else {GetEAa;val=LoadMd(eaa);} - if (val==0) {Interrupt(0);break;} + 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); + INTERRUPT(0); break; } case 0x38: /* IDIV Ed */ @@ -429,13 +429,13 @@ switch(Fetchb()) { Bit32s val; if (rm >= 0xc0 ) {GetEArd;val=*eards;} else {GetEAa;val=LoadMds(eaa);} - if (val==0) {Interrupt(0);break;} + 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); + INTERRUPT(0); break; } } From 276b5ccb49021b751083c50ea7d07ce11dec70f2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 27 Aug 2002 13:48:13 +0000 Subject: [PATCH 0157/4131] cleanup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@234 --- src/dos/dev_con.h | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 003c15ef..77998e24 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -63,21 +63,13 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { extern void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page); bool device_CON::Write(Bit8u * data,Bit16u * size) { -//TODO Hack a way to call int 0x10 - Bit16u oldax=reg_ax;Bit16u oldbx=reg_bx; Bit16u count=0; while (*size>count) { -/* - reg_al=data[count]; - reg_ah=0x0e; - reg_bx=0x0007; - CALLBACK_RunRealInt(0x10); -*/ + INT10_TeletypeOutput(data[count],7,false,0); count++; } *size=count; -// reg_ax=oldax;reg_bx=oldbx; return true; } From db6eb155e15aa28b70d42870cdd7b309e6750472 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 28 Aug 2002 09:03:10 +0000 Subject: [PATCH 0158/4131] StringSI to use new prefix handling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@235 --- src/cpu/core_16/support.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_16/support.h b/src/cpu/core_16/support.h index 34c4e73f..095f585a 100644 --- a/src/cpu/core_16/support.h +++ b/src/cpu/core_16/support.h @@ -88,9 +88,9 @@ static INLINE Bit32u Pop_32() { #define stringSI \ EAPoint from; \ - if (segprefix_on) { \ + if (prefixes & PREFIX_SEG) { \ from=(segprefix_base+reg_si); \ - SegPrefixReset; \ + PrefixReset; \ } else { \ from=SegBase(ds)+reg_si; \ } From 49c27cdc19bcf6406b58acf1974abd1100fad051 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 28 Aug 2002 09:03:34 +0000 Subject: [PATCH 0159/4131] Changed some instructions for new prefix handling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@236 --- src/cpu/core_16/main.h | 42 ++++---- src/cpu/core_16/prefix_66.h | 16 ++- src/cpu/core_16/prefix_of.h | 3 +- src/cpu/core_16/table_ea.h | 197 ++++++++++++++++++++++++++++++------ 4 files changed, 190 insertions(+), 68 deletions(-) diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index b1cfee22..9d72cf2e 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -274,7 +274,7 @@ restart: GetRMrw;GetEAa; bound_min=LoadMw(eaa); bound_max=LoadMw(eaa+2); - if ( (*rmrw < bound_min) || (*rmrw > bound_max) ) { + if ( (((Bit16s)*rmrw) < bound_min) || (((Bit16s)*rmrw) > bound_max) ) { INTERRUPT(5); } } @@ -675,35 +675,27 @@ restart: break; } case 0xa0: /* MOV AL,Ob */ - if (segprefix_on) { - reg_al=LoadMb(segprefix_base+Fetchw()); - SegPrefixReset; - } else { - reg_al=LoadMb(SegBase(ds)+Fetchw()); + { + GetEADirect; + reg_al=LoadMb(eaa); } break; case 0xa1: /* MOV AX,Ow */ - if (segprefix_on) { - reg_ax=LoadMw(segprefix_base+Fetchw()); - SegPrefixReset; - } else { - reg_ax=LoadMw(SegBase(ds)+Fetchw()); + { + GetEADirect; + reg_ax=LoadMw(eaa); } break; case 0xa2: /* MOV Ob,AL */ - if (segprefix_on) { - SaveMb((segprefix_base+Fetchw()),reg_al); - SegPrefixReset; - } else { - SaveMb((SegBase(ds)+Fetchw()),reg_al); + { + GetEADirect; + SaveMb(eaa,reg_al); } break; case 0xa3: /* MOV Ow,AX */ - if (segprefix_on) { - SaveMw((segprefix_base+Fetchw()),reg_ax); - SegPrefixReset; - } else { - SaveMw((SegBase(ds)+Fetchw()),reg_ax); + { + GetEADirect; + SaveMw(eaa,reg_ax); } break; case 0xa4: /* MOVSB */ @@ -944,9 +936,9 @@ restart: reg_al = get_CF() ? 0xFF : 0; break; case 0xd7: /* XLAT */ - if (segprefix_on) { + if (prefixes & PREFIX_SEG) { reg_al=LoadMb(segprefix_base+(Bit16u)(reg_bx+reg_al)); - SegPrefixReset; + PrefixReset; } else { reg_al=LoadMb(SegBase(ds)+(Bit16u)(reg_bx+reg_al)); } @@ -1061,9 +1053,9 @@ restart: { EAPoint to=SegBase(es); EAPoint from; - if (segprefix_on) { + if (prefixes & PREFIX_SEG) { from=(segprefix_base); - SegPrefixReset; + PrefixReset; } else { from=SegBase(ds); } diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index 9f1c141a..d34ad4b4 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -278,19 +278,15 @@ switch(Fetchb()) { break; } case 0xa1: /* MOV EAX,Ow */ - if (segprefix_on) { - reg_eax=LoadMd(segprefix_base+Fetchw()); - SegPrefixReset; - } else { - reg_eax=LoadMd(SegBase(ds)+Fetchw()); + { + GetEADirect; + reg_eax=LoadMd(eaa); } break; case 0xa3: /* MOV Ow,EAX */ - if (segprefix_on) { - SaveMd((segprefix_base+Fetchw()),reg_eax); - SegPrefixReset; - } else { - SaveMd((SegBase(ds)+Fetchw()),reg_eax); + { + GetEADirect; + SaveMd(eaa,reg_eax); } break; case 0xa5: /* MOVSD */ diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h index 5d845201..3decea1f 100644 --- a/src/cpu/core_16/prefix_of.h +++ b/src/cpu/core_16/prefix_of.h @@ -23,6 +23,7 @@ switch(Fetchb()) { break; GetRM; switch (rm & 0x38) { + case 0x00: default: E_Exit("CPU:GRP6:Illegal call %2X",(rm>>3) &3); } @@ -350,7 +351,7 @@ switch(Fetchb()) { if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } break; } - case 0xbc: /* 0xbc BSF Gw,Ew */ + case 0xbc: /* 0xbc BSF Gw,Ew */ { GetRMrw; Bit16u result,value; diff --git a/src/cpu/core_16/table_ea.h b/src/cpu/core_16/table_ea.h index a1d86559..c6972693 100644 --- a/src/cpu/core_16/table_ea.h +++ b/src/cpu/core_16/table_ea.h @@ -21,25 +21,44 @@ typedef EAPoint (*GetEATable[256])(void); static GetEATable * lookupEATable; +#define PREFIX_NONE 0x0 +#define PREFIX_SEG 0x1 +#define PREFIX_ADDR 0x2 +#define PREFIX_SEG_ADDR 0x3 + + +static Bitu prefixes; static EAPoint segprefix_base; -static bool segprefix_on=false; + +/* Gets initialized at the bottem, can't seem to declare forward references */ +static GetEATable * EAPrefixTable[4]; + #define SegPrefix(blah) \ segprefix_base=SegBase(blah); \ - segprefix_on=true; \ - lookupEATable=&GetEA_16_s; \ + prefixes|=PREFIX_SEG; \ + lookupEATable=EAPrefixTable[prefixes]; \ goto restart; \ #define SegPrefix_66(blah) \ segprefix_base=SegBase(blah); \ - segprefix_on=true; \ - lookupEATable=&GetEA_16_s; \ + prefixes|=PREFIX_SEG; \ + lookupEATable=EAPrefixTable[prefixes]; \ goto restart_66; \ +#define PrefixReset \ + prefixes=PREFIX_NONE;lookupEATable=EAPrefixTable[PREFIX_NONE]; + +#define GetEADirect \ +EAPoint eaa;switch (prefixes) { \ +case PREFIX_NONE:eaa=SegBase(ds)+Fetchw();break; \ +case PREFIX_SEG:eaa=segprefix_base+Fetchw();PrefixReset;break; \ +case PREFIX_ADDR:eaa=SegBase(ds)+Fetchd();PrefixReset;break; \ +case PREFIX_SEG_ADDR:eaa=segprefix_base+Fetchd();PrefixReset;break; \ +} + -#define SegPrefixReset \ - segprefix_on=false;lookupEATable=&GetEA_16_n; /* The MOD/RM Decoder for EA for this decoder's addressing modes */ @@ -106,34 +125,34 @@ static GetEATable GetEA_16_n={ }; -#define prefixed(val) EAPoint ret=segprefix_base+val;SegPrefixReset;return ret; +#define segprefixed(val) EAPoint ret=segprefix_base+val;PrefixReset;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_00_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_si)) } +static EAPoint EA_16_01_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_di)) } +static EAPoint EA_16_02_s(void) { segprefixed((Bit16u)(reg_bp+(Bit16s)reg_si)) } +static EAPoint EA_16_03_s(void) { segprefixed((Bit16u)(reg_bp+(Bit16s)reg_di)) } +static EAPoint EA_16_04_s(void) { segprefixed((Bit16u)(reg_si)) } +static EAPoint EA_16_05_s(void) { segprefixed((Bit16u)(reg_di)) } +static EAPoint EA_16_06_s(void) { segprefixed((Bit16u)(Fetchw())) } +static EAPoint EA_16_07_s(void) { segprefixed((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_40_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs())) } +static EAPoint EA_16_41_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs())) } +static EAPoint EA_16_42_s(void) { segprefixed((Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs())) } +static EAPoint EA_16_43_s(void) { segprefixed((Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs())) } +static EAPoint EA_16_44_s(void) { segprefixed((Bit16u)(reg_si+Fetchbs())) } +static EAPoint EA_16_45_s(void) { segprefixed((Bit16u)(reg_di+Fetchbs())) } +static EAPoint EA_16_46_s(void) { segprefixed((Bit16u)(reg_bp+Fetchbs())) } +static EAPoint EA_16_47_s(void) { segprefixed((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 EAPoint EA_16_80_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws())) } +static EAPoint EA_16_81_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws())) } +static EAPoint EA_16_82_s(void) { segprefixed((Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws())) } +static EAPoint EA_16_83_s(void) { segprefixed((Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws())) } +static EAPoint EA_16_84_s(void) { segprefixed((Bit16u)(reg_si+Fetchws())) } +static EAPoint EA_16_85_s(void) { segprefixed((Bit16u)(reg_di+Fetchws())) } +static EAPoint EA_16_86_s(void) { segprefixed((Bit16u)(reg_bp+Fetchws())) } +static EAPoint EA_16_87_s(void) { segprefixed((Bit16u)(reg_bx+Fetchws())) } static GetEATable GetEA_16_s={ /* 00 */ @@ -281,3 +300,117 @@ static GetEATable GetEA_32_n={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +INLINE EAPoint Sib_s(Bitu mode) { + Bit8u sib=Fetchb(); + EAPoint base; + switch (sib&7) { + case 0: /* EAX Base */ + base=segprefix_base+reg_eax;break; + case 1: /* ECX Base */ + base=segprefix_base+reg_ecx;break; + case 2: /* EDX Base */ + base=segprefix_base+reg_edx;break; + case 3: /* EBX Base */ + base=segprefix_base+reg_ebx;break; + case 4: /* ESP Base */ + base=segprefix_base+reg_esp;break; + case 5: /* #1 Base */ + if (!mode) { + base=segprefix_base+Fetchd();break; + } else { + base=segprefix_base+reg_ebp;break; + } + case 6: /* ESI Base */ + base=segprefix_base+reg_esi;break; + case 7: /* EDI Base */ + base=segprefix_base+reg_edi;break; + } + Bitu shift=sib >> 6; + switch ((sib >>3) &7) { + case 0: /* EAX Index */ + base+=(Bit32s)reg_eax< Date: Wed, 28 Aug 2002 09:04:00 +0000 Subject: [PATCH 0160/4131] Changed core startup to make the prefix table Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@237 --- src/cpu/slow_16.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp index a7e41995..c8d9a2d1 100644 --- a/src/cpu/slow_16.cpp +++ b/src/cpu/slow_16.cpp @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + #include "dosbox.h" #include "mem.h" #include "cpu.h" @@ -93,9 +94,10 @@ static Bitu CPU_Real_16_Slow_Decode_Special(Bitu count) { void CPU_Real_16_Slow_Start(void) { - lookupEATable=&GetEA_16_n; - segprefix_base=0; - segprefix_on=false; cpudecoder=&CPU_Real_16_Slow_Decode; - + EAPrefixTable[0]=&GetEA_16_n; + EAPrefixTable[1]=&GetEA_16_s; + EAPrefixTable[2]=&GetEA_32_n; + EAPrefixTable[3]=&GetEA_32_s; + PrefixReset; }; From 69d34db7ec7cc248a500d052d942ccd62f7eaf63 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 28 Aug 2002 09:26:45 +0000 Subject: [PATCH 0161/4131] Added keyboard intercept to int 0x15 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@238 --- src/ints/bios.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index ff8e2fe6..57466e78 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -145,6 +145,10 @@ static Bitu INT15_Handler(void) { LOG_WARN("Request BIOS Configuration INT 15 C0"); CALLBACK_SCF(true); break; + case 0x4f: /* BIOS - Keyboard intercept */ + /* Carry should be set but let's just set it just in case */ + CALLBACK_SCF(true); + break; case 0x84: /* BIOS - JOYSTICK SUPPORT (XT after 11/8/82,AT,XT286,PS) */ //Does anyone even use this? LOG_WARN("INT15:84:Bios Joystick functionality not done"); From 48a3641de1074445355cfaad1e9b1b5f02935f0c Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 28 Aug 2002 14:22:51 +0000 Subject: [PATCH 0162/4131] Added change debug commands: BPLIST, BPDEL. Use of registers in command line enabled. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@239 --- src/debug/debug.cpp | 143 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 112 insertions(+), 31 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 1389c450..fdb66ac9 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -63,7 +63,9 @@ struct SCodeViewData { Bit16u firstInstSize; Bit16u useCS; Bit32u useEIPlast, useEIPmid; - Bit32u useEIP, cursorAdr; + Bit32u useEIP; + Bit16u cursorSeg; + Bit32u cursorOfs; bool inputMode; char inputStr[255]; @@ -84,6 +86,8 @@ typedef struct SBreakPoint { Bit8u olddata; Bit8u type; Bit16u ahValue; + Bit16u segment; + Bit32u offset; bool once; bool enabled; bool active; @@ -143,13 +147,15 @@ static void SetBreakpoints(void) } } -static void AddBreakpoint(PhysPt off, bool once) +static void AddBreakpoint(Bit16u seg, Bit32u ofs, bool once) { TBreakpoint bp; bp.type = BKPNT_PHYSICAL; bp.enabled = true; bp.active = false; - bp.location = off; + bp.location = PhysMake(seg,ofs); + bp.segment = seg; + bp.offset = ofs; bp.once = once; BPoints.push_front(bp); } @@ -190,7 +196,7 @@ static bool StepOver() size=DasmI386(dline, start, reg_eip, false); if (strstr(dline,"call") || strstr(dline,"int")) { - AddBreakpoint (Real2Phys(RealMake(SegValue(cs),reg_eip+size)), true); + AddBreakpoint (SegValue(cs),reg_eip+size, true); SetBreakpoints(); debugging=false; DrawCode(); @@ -215,6 +221,7 @@ bool DEBUG_BreakPoint(void) { } if (!found) return false; RemoveBreakpoint(where); + ClearBreakpoints(); reg_eip -= 1; DEBUG_Enable(); return true; @@ -245,7 +252,7 @@ bool DEBUG_IntBreakpoint(Bit8u intNum) // Remove normal breakpoint here, cos otherwise 0xCC wont be removed here RemoveBreakpoint(where); - RemoveBreakpoint(where+2); + ClearBreakpoints(); reg_eip -= 2; DEBUG_Enable(); return true; @@ -324,11 +331,13 @@ static void DrawCode(void) wattrset(dbg.win_code,COLOR_PAIR(PAIR_GREEN_BLACK)); if (codeViewData.cursorPos==-1) { codeViewData.cursorPos = i; // Set Cursor - codeViewData.cursorAdr = start; + codeViewData.cursorSeg = SegValue(cs); + codeViewData.cursorOfs = disEIP; } } else if (i == codeViewData.cursorPos) { wattrset(dbg.win_code,COLOR_PAIR(PAIR_BLACK_GREY)); - codeViewData.cursorAdr = start; + codeViewData.cursorSeg = codeViewData.useCS; + codeViewData.cursorOfs = disEIP; } else if (IsBreakpoint(start)) { wattrset(dbg.win_code,COLOR_PAIR(PAIR_GREY_RED)); } else { @@ -388,6 +397,31 @@ Bit32u GetHexValue(char* str, char*& hex) hex = str; while (*hex==' ') hex++; + if (strstr(hex,"AX")==hex) { hex+=2; return reg_ax; }; + if (strstr(hex,"BX")==hex) { hex+=2; return reg_bx; }; + if (strstr(hex,"CX")==hex) { hex+=2; return reg_cx; }; + if (strstr(hex,"DX")==hex) { hex+=2; return reg_dx; }; + if (strstr(hex,"SI")==hex) { hex+=2; return reg_si; }; + if (strstr(hex,"DI")==hex) { hex+=2; return reg_di; }; + if (strstr(hex,"BP")==hex) { hex+=2; return reg_bp; }; + if (strstr(hex,"SP")==hex) { hex+=2; return reg_sp; }; + if (strstr(hex,"IP")==hex) { hex+=2; return reg_ip; }; + if (strstr(hex,"CS")==hex) { hex+=2; return SegValue(cs); }; + if (strstr(hex,"DS")==hex) { hex+=2; return SegValue(ds); }; + if (strstr(hex,"ES")==hex) { hex+=2; return SegValue(es); }; + if (strstr(hex,"FS")==hex) { hex+=2; return SegValue(fs); }; + if (strstr(hex,"GS")==hex) { hex+=2; return SegValue(gs); }; + if (strstr(hex,"SS")==hex) { hex+=2; return SegValue(ss); }; + if (strstr(hex,"EAX")==hex) { hex+=3; return reg_eax; }; + if (strstr(hex,"EBX")==hex) { hex+=3; return reg_ebx; }; + if (strstr(hex,"ECX")==hex) { hex+=3; return reg_ecx; }; + if (strstr(hex,"EDX")==hex) { hex+=3; return reg_edx; }; + if (strstr(hex,"ESI")==hex) { hex+=3; return reg_esi; }; + if (strstr(hex,"EDI")==hex) { hex+=3; return reg_edi; }; + if (strstr(hex,"EBP")==hex) { hex+=3; return reg_ebp; }; + if (strstr(hex,"ESP")==hex) { hex+=3; return reg_esp; }; + if (strstr(hex,"EIP")==hex) { hex+=3; return reg_eip; }; + while (*hex) { if ((*hex>='0') && (*hex<='9')) value = (value<<4)+*hex-'0'; else if ((*hex>='A') && (*hex<='F')) value = (value<<4)+*hex-'A'+10; @@ -406,7 +440,7 @@ bool ParseCommand(char* str) found+=3; Bit16u seg = GetHexValue(found,found);found++; // skip ":" Bit32u ofs = GetHexValue(found,found); - AddBreakpoint((seg<<4)+ofs,false); + AddBreakpoint(seg,ofs,false); LOG_DEBUG("DEBUG: Set breakpoint at %04X:%04X",seg,ofs); return true; } @@ -424,10 +458,56 @@ bool ParseCommand(char* str) } return true; } + found = strstr(str,"BPLIST"); + if (found) { + wprintw(dbg.win_out,"Breakpoint list:\n"); + wprintw(dbg.win_out,"-------------------------------------------------------------------------\n"); + Bit32u nr = 0; + // iterate list + std::list::iterator i; + for(i=BPoints.begin(); i != BPoints.end(); i++) { + if ((*i).type==BKPNT_PHYSICAL) { + wprintw(dbg.win_out,"%02X. BP %04X:%04X\n",nr,(*i).segment,(*i).offset); + nr++; + } else if ((*i).type==BKPNT_INTERRUPT) { + if ((*i).ahValue==BPINT_ALL) wprintw(dbg.win_out,"%02X. BPINT %02X\n",nr,(*i).olddata); + else wprintw(dbg.win_out,"%02X. BPINT %02X AH=%02X\n",nr,(*i).olddata,(*i).ahValue); + nr++; + }; + } + wrefresh(dbg.win_out); + return true; + }; + found = strstr(str,"BPDEL"); if (found) { // Delete Breakpoints - (BPoints.clear)(); - LOG_DEBUG("DEBUG: Breakpoints deleted."); + found+=5; + Bit8u bpNr = GetHexValue(found,found); + if ((bpNr==0x00) && (*found=='*')) { // Delete all + (BPoints.clear)(); + LOG_DEBUG("DEBUG: Breakpoints deleted."); + } else { + // delete single breakpoint + Bit16u nr = 0; + std::list::iterator i; + for(i=BPoints.begin(); i != BPoints.end(); i++) { + if ((*i).type==BKPNT_PHYSICAL) { + if (nr==bpNr) { + DeleteBreakpoint((*i).location); + LOG_DEBUG("DEBUG: Breakpoint %02X deleted.",nr); + break; + } + nr++; + } else if ((*i).type==BKPNT_INTERRUPT) { + if (nr==bpNr) { + (BPoints.erase)(i); + LOG_DEBUG("DEBUG: Breakpoint %02X. deleted.",nr); + break;; + } + nr++; + } + } + } return true; } found = strstr(str,"C "); @@ -450,24 +530,24 @@ bool ParseCommand(char* str) } if ((*str=='H') || (*str=='?')) { wprintw(dbg.win_out,"Debugger keys:\n"); - wprintw(dbg.win_out,"-------------------------------------------------------------------------\n"); - wprintw(dbg.win_out,"F5 - Run\n"); - wprintw(dbg.win_out,"F9 - Set/Remove breakpoint\n"); - wprintw(dbg.win_out,"F10/F11 - Step over / trace into instruction\n"); - wprintw(dbg.win_out,"Up/Down - Move code view cursor\n"); - wprintw(dbg.win_out,"Return - Enable command line input\n"); - wprintw(dbg.win_out,"D/E/S/X/B - Set data view to DS:SI/ES:DI/SS:SP/DS:DX/ES:BX\n"); - wprintw(dbg.win_out,"R/F - Scroll data view\n"); + wprintw(dbg.win_out,"--------------------------------------------------------------------------\n"); + wprintw(dbg.win_out,"F5 - Run\n"); + wprintw(dbg.win_out,"F9 - Set/Remove breakpoint\n"); + wprintw(dbg.win_out,"F10/F11 - Step over / trace into instruction\n"); + wprintw(dbg.win_out,"Up/Down - Move code view cursor\n"); + wprintw(dbg.win_out,"Return - Enable command line input\n"); + wprintw(dbg.win_out,"D/E/S/X/B - Set data view to DS:SI/ES:DI/SS:SP/DS:DX/ES:BX\n"); + wprintw(dbg.win_out,"R/F - Scroll data view\n"); wprintw(dbg.win_out,"\n"); - wprintw(dbg.win_out,"Debugger commands (enter all values in hex):\n"); - wprintw(dbg.win_out,"-------------------------------------------------------------------------\n"); - wprintw(dbg.win_out,"BP [segment]:[offset] - Set breakpoint\n"); - wprintw(dbg.win_out,"BPINT [intNr] * - Set interrupt breakpoint\n"); - wprintw(dbg.win_out,"BPINT [intNr] [ah] - Set interrupt breakpoint with ah\n"); - wprintw(dbg.win_out,"BPDEL - Delete breakpoints\n"); - wprintw(dbg.win_out,"C [segment]:[offset] - Set code view address\n"); - wprintw(dbg.win_out,"D [segment]:[offset] - Set data view address\n"); - wprintw(dbg.win_out,"H - Help\n"); + wprintw(dbg.win_out,"Debugger commands (enter all values in hex or as register):\n"); + wprintw(dbg.win_out,"--------------------------------------------------------------------------\n"); + wprintw(dbg.win_out,"BP [segment]:[offset] - Set breakpoint\n"); + wprintw(dbg.win_out,"BPINT [intNr] * - Set interrupt breakpoint\n"); + wprintw(dbg.win_out,"BPINT [intNr] [ah] - Set interrupt breakpoint with ah\n"); + wprintw(dbg.win_out,"BPLIST - List breakpoints\n"); + wprintw(dbg.win_out,"BPDEL [bpNr] / * - Delete breakpoint nr / all\n"); + wprintw(dbg.win_out,"C / D [segment]:[offset] - Set code / data view address\n"); + wprintw(dbg.win_out,"H - Help\n"); wrefresh(dbg.win_out); return TRUE; } @@ -560,8 +640,10 @@ Bit32u DEBUG_CheckKeys(void) { DOSBOX_SetNormalLoop(); break; case KEY_F(9): // Set/Remove TBreakpoint - if (IsBreakpoint(codeViewData.cursorAdr)) DeleteBreakpoint(codeViewData.cursorAdr); - else AddBreakpoint(codeViewData.cursorAdr, false); + { PhysPt ptr = PhysMake(codeViewData.cursorSeg,codeViewData.cursorOfs); + if (IsBreakpoint(ptr)) DeleteBreakpoint(ptr); + else AddBreakpoint(codeViewData.cursorSeg, codeViewData.cursorOfs, false); + } break; case KEY_F(10): // Step over inst if (StepOver()) return 0; @@ -593,8 +675,7 @@ Bitu DEBUG_Loop(void) { Bit32u oldEIP = reg_eip; PIC_runIRQs(); if ((oldCS!=SegValue(cs)) || (oldEIP!=reg_eip)) { - PhysPt intBpAdr = Real2Phys(RealMake(oldCS,oldEIP)); - AddBreakpoint(intBpAdr,true); + AddBreakpoint(oldCS,oldEIP,true); SetBreakpoints(); debugging=false; DOSBOX_SetNormalLoop(); From eb18047ff7a17a264b1b652d44718440065f5dc2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 29 Aug 2002 11:13:56 +0000 Subject: [PATCH 0163/4131] Added function 51, reallocate pages Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@240 --- src/ints/ems.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 52b6d7d0..bf010565 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -136,6 +136,59 @@ static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & handle) { return EMM_NO_ERROR; } +static Bit8u EMM_ReallocatePages(Bit16u handle,Bit16u & pages) { + /* Check for valid handle */ + if (handle>=EMM_MAX_HANDLES || emm_handles[handle].first_page==NULL_PAGE) return EMM_INVALID_HANDLE; + /* Check for enough pages */ + if ((emm_handles[handle].pages+EMM_GetFreePages())0 && page_count>0) { + if (emm_pages[page].handle!=handle) E_Exit("EMM:Error illegal handle reference"); + last=page; + page=emm_pages[page].next; + pages--; + page_count--; + } + /* Free the rest of the handles */ + if (page_count && !pages) { + emm_handles[handle].pages-=page_count; + while (page_count>0) { + free(emm_pages[page].memory); + emm_pages[page].memory=0; + emm_pages[page].handle=NULL_HANDLE; + Bit16u next_page=emm_pages[page].next; + emm_pages[page].next=NULL_PAGE; + page=next_page;page_count--; + } + pages=emm_handles[handle].pages; + return EMM_NO_ERROR; + } + if (!page_count && pages) { + /* Allocate extra pages */ + emm_handles[handle].pages+=pages; + page=0; + while (pages) { + if (emm_pages[page].handle==NULL_HANDLE) { + emm_pages[page].handle=handle; + emm_pages[page].memory=malloc(EMM_PAGE_SIZE); + if (!emm_pages[page].memory) E_Exit("EMM:Cannont allocate memory"); + emm_pages[last].next=page; + last=page; + pages--; + } else { + if (++page>=EMM_MAX_PAGES) E_Exit("EMM:Ran out of pages"); + } + } + pages=emm_handles[handle].pages; + return EMM_NO_ERROR; + } + /* Size exactly the same as the original size */ + pages=emm_handles[handles].pages; + return EMM_NO_ERROR; +} + static Bit8u EMM_MapPage(Bitu phys_page,Bit16u handle,Bit16u log_page) { /* Check for too high physical page */ if (phys_page>=EMM_MAX_PHYS) return EMM_ILL_PHYS; @@ -335,6 +388,9 @@ static Bitu INT67_Handler(void) { break; } break; + case 0x51: /* Reallocate Pages */ + reg_ah=EMM_ReallocatePages(reg_dx,reg_bx); + break; case 0x53: // Set/Get Handlename if (reg_al==0x00) { // Get Name not supported LOG_ERROR("EMS:Get handle name not supported",reg_ah); From 2bfdd0f6d9908199e28927e3492eca67411dfb33 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 29 Aug 2002 11:19:32 +0000 Subject: [PATCH 0164/4131] handles to handle typo :( Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@241 --- src/ints/ems.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index bf010565..c0eb1d51 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -185,7 +185,7 @@ static Bit8u EMM_ReallocatePages(Bit16u handle,Bit16u & pages) { return EMM_NO_ERROR; } /* Size exactly the same as the original size */ - pages=emm_handles[handles].pages; + pages=emm_handles[handle].pages; return EMM_NO_ERROR; } From ea01ca6a8dbb94ea7c8b5ad8871fd2c101ced488 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 29 Aug 2002 11:21:05 +0000 Subject: [PATCH 0165/4131] Correct page lengths for videomode tables Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@242 --- src/ints/int10_modes.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index bd0afb59..015ad115 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -34,13 +34,14 @@ VGAMODES vga_modes[MODE_MAX+1]= {0x05, 0xFFFF, GRAPH, CGA, 1, 2, 320, 200, 40, 25, 8, 8, 0xB800, 0x0800, 0x63, 0xFF, 0x02, 0x01, 0x01, 0x02, 0x01}, {0x06, 0xFFFF, GRAPH, CGA, 1, 1, 640, 200, 80, 25, 8, 8, 0xB800, 0x1000, 0x63, 0xFF, 0x03, 0x02, 0x02, 0x03, 0x01}, {0x07, 0xFFFF, TEXT, MTEXT, 4, 4, 720, 400, 80, 25, 9, 16, 0xB000, 0x1000, 0x66, 0xFF, 0x04, 0x03, 0x03, 0x01, 0x00}, - {0x0D, 0xFFFF, GRAPH, PLANAR4, 8, 4, 320, 200, 40, 25, 8, 8, 0xA000, 0x0000, 0x63, 0xFF, 0x05, 0x04, 0x04, 0x04, 0x01}, - {0x0E, 0xFFFF, GRAPH, PLANAR4, 4, 4, 640, 200, 80, 25, 8, 8, 0xA000, 0x0000, 0x63, 0xFF, 0x06, 0x04, 0x04, 0x05, 0x01}, - {0x0F, 0xFFFF, GRAPH, PLANAR2, 2, 2, 640, 350, 80, 25, 8, 14, 0xA000, 0x0000, 0xa2, 0xFF, 0x07, 0x05, 0x04, 0x05, 0x00}, - {0x10, 0xFFFF, GRAPH, PLANAR4, 2, 4, 640, 350, 80, 25, 8, 14, 0xA000, 0x0000, 0xa3, 0xFF, 0x07, 0x06, 0x04, 0x05, 0x02}, - {0x11, 0xFFFF, GRAPH, PLANAR1, 1, 1, 640, 480, 80, 30, 8, 16, 0xA000, 0x0000, 0xe3, 0xFF, 0x08, 0x07, 0x04, 0x05, 0x02}, - {0x12, 0xFFFF, GRAPH, PLANAR4, 1, 4, 640, 480, 80, 30, 8, 16, 0xA000, 0x0000, 0xe3, 0xFF, 0x08, 0x06, 0x04, 0x05, 0x02}, - {0x13, 0xFFFF, GRAPH, LINEAR8, 1, 8, 320, 200, 40, 25, 8, 8, 0xA000, 0x0000, 0x63, 0xFF, 0x09, 0x08, 0x05, 0x06, 0x03} + + {0x0D, 0xFFFF, GRAPH, PLANAR4, 8, 4, 320, 200, 40, 25, 8, 8, 0xA000, 0x2000, 0x63, 0xFF, 0x05, 0x04, 0x04, 0x04, 0x01}, + {0x0E, 0xFFFF, GRAPH, PLANAR4, 4, 4, 640, 200, 80, 25, 8, 8, 0xA000, 0x4000, 0x63, 0xFF, 0x06, 0x04, 0x04, 0x05, 0x01}, + {0x0F, 0xFFFF, GRAPH, PLANAR2, 2, 2, 640, 350, 80, 25, 8, 14, 0xA000, 0x8000, 0xa2, 0xFF, 0x07, 0x05, 0x04, 0x05, 0x00}, + {0x10, 0xFFFF, GRAPH, PLANAR4, 2, 4, 640, 350, 80, 25, 8, 14, 0xA000, 0x8000, 0xa3, 0xFF, 0x07, 0x06, 0x04, 0x05, 0x02}, + {0x11, 0xFFFF, GRAPH, PLANAR1, 1, 1, 640, 480, 80, 30, 8, 16, 0xA000, 0xA000, 0xe3, 0xFF, 0x08, 0x07, 0x04, 0x05, 0x02}, + {0x12, 0xFFFF, GRAPH, PLANAR4, 1, 4, 640, 480, 80, 30, 8, 16, 0xA000, 0xA000, 0xe3, 0xFF, 0x08, 0x06, 0x04, 0x05, 0x02}, + {0x13, 0xFFFF, GRAPH, LINEAR8, 1, 8, 320, 200, 40, 25, 8, 8, 0xA000, 0xFA00, 0x63, 0xFF, 0x09, 0x08, 0x05, 0x06, 0x03} }; /* CRTC */ @@ -396,8 +397,6 @@ void INT10_SetVideoMode(Bit8u mode) { // Set active page 0 INT10_SetActivePage(0); /* Set some interrupt vectors */ - //TODO set 0x43 to the correct font height font RealSetVec(0x43,int10_romarea.font_8_first); RealSetVec(0x1F,int10_romarea.font_8_second); - }; From 80ac7ce34a4802c8bf4f5ca9c0c24338c51a9074 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 29 Aug 2002 11:41:04 +0000 Subject: [PATCH 0166/4131] added files to Makefile and fixed resulting errors Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@243 --- src/fpu/Makefile.am | 2 +- src/fpu/fpu_flags.cpp | 4 ++-- src/fpu/fpu_types.h | 7 ++++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/fpu/Makefile.am b/src/fpu/Makefile.am index d1890ca6..fb3045f2 100644 --- a/src/fpu/Makefile.am +++ b/src/fpu/Makefile.am @@ -1,4 +1,4 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libfpu.a -libfpu_a_SOURCES = fpu.cpp fpu_load.h \ No newline at end of file +libfpu_a_SOURCES = fpu.cpp fpu_flags.cpp fpu_types.h fpu_instructions.h \ No newline at end of file diff --git a/src/fpu/fpu_flags.cpp b/src/fpu/fpu_flags.cpp index be463c0c..924614fc 100644 --- a/src/fpu/fpu_flags.cpp +++ b/src/fpu/fpu_flags.cpp @@ -19,8 +19,8 @@ #include "dosbox.h" #include "fpu.h" #include "pic.h" - -//extern FPU_Flag_Info fpu_flags; +#include "fpu_types.h" +extern FPU_Flag_Info fpu_flags; bool FPU_get_C3() { switch(fpu_flags.type) { diff --git a/src/fpu/fpu_types.h b/src/fpu/fpu_types.h index 1079dbf8..2d0ced0f 100644 --- a/src/fpu/fpu_types.h +++ b/src/fpu/fpu_types.h @@ -1,4 +1,5 @@ + enum { FPUREG_VALID=0, FPUREG_ZERO, FPUREG_PNAN, FPUREG_NNAN, FPUREG_EMPTY }; enum { @@ -6,12 +7,12 @@ enum { t_FDIVP, t_FCHS, t_FCOMP, t_FUNKNOWN, - t_FNOTDONE, + t_FNOTDONE }; struct FPU_Flag_Info { struct { - Real r; + Real64 r; Bit8u tag; } var1,var2, result; struct { @@ -27,6 +28,6 @@ struct FPU_Flag_Info { }; struct FPU_Reg { - Real r; + Real64 r; Bit8u tag; }; From 0e36af08990331c27ae6b8e9f679340c04af75a2 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 29 Aug 2002 12:36:31 +0000 Subject: [PATCH 0167/4131] fixed possible paramblock memory overwrite in EXE_Load Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@244 --- src/dos/dos_execute.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index c4f622e0..9cb7796e 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -297,7 +297,7 @@ static bool COM_Load(char * name,ParamBlock * block,Bit8u flag) { } -static bool EXE_Load(char * name,ParamBlock * block,Bit8u flag) { +static bool EXE_Load(char * name,ParamBlock* _block,Bit8u flag) { EXE_Header header; Bit16u fhandle;Bit32u i; @@ -305,12 +305,17 @@ static bool EXE_Load(char * name,ParamBlock * block,Bit8u flag) { Bit16u envseg,pspseg,exeseg; Bit32u imagesize,headersize; + // During loading process, th param-block-mem might be overwritten (HostPt!) and + // therefore change the relocation address, so save these values. + ParamBlock block; + memcpy(&block,_block,sizeof(ParamBlock)); + PSP * callpsp=(PSP *)HostMake(dos.psp,0); if (!DOS_OpenFile(name,OPEN_READ,&fhandle)) return false; if (flag!=OVERLAY) { /* Allocate a new Environment */ - envseg=block->exec.envseg; + envseg=block.exec.envseg; if (!MakeEnv(name,&envseg)) return false; }; @@ -345,11 +350,11 @@ static bool EXE_Load(char * name,ParamBlock * block,Bit8u flag) { return false; } SetupPSP(pspseg,size,envseg); - SetupCMDLine(pspseg,block); + SetupCMDLine(pspseg,&block); exeseg=pspseg+16; } else { /* For OVERLAY */ - exeseg=block->overlay.loadseg; + exeseg=block.overlay.loadseg; } /* Load the image in 32k blocks */ DOS_SeekFile(fhandle,&headersize,0); @@ -384,7 +389,7 @@ static bool EXE_Load(char * name,ParamBlock * block,Bit8u flag) { PhysPt address=Real2Phys(RealMake(RealSeg(reloc)+exeseg,RealOff(reloc))); Bit16u change=mem_readw(address); if (flag==OVERLAY) { - change+=block->overlay.relocation; + change+=block.overlay.relocation; } else { change+=exeseg; }; From 71fc0f2cf6a773e971bb87a7920adf8f89774852 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 29 Aug 2002 13:03:13 +0000 Subject: [PATCH 0168/4131] update for upcoming 0.55 release Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@245 --- ChangeLog | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ec52db31..b7862d2b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,5 +4,23 @@ - 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 \ No newline at end of file + - 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 From bd5ef63d38bb95569d2e577f6b117c27e512c4f5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 29 Aug 2002 14:07:27 +0000 Subject: [PATCH 0169/4131] New window scrolling and fix for setting active page Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@246 --- src/ints/int10_char.cpp | 269 +++++++++++++++++----------------------- 1 file changed, 113 insertions(+), 156 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 10ee6cd5..1a0e5d4d 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /* Character displaying moving functions */ #include "dosbox.h" @@ -25,185 +24,143 @@ #include "inout.h" #include "int10.h" +static INLINE void PLANAR4_CopyRow(VGAMODES * curmode,Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { + PhysPt src,dest;Bitu copy; + dest=base+(curmode->twidth*rnew)*curmode->cheight+cleft; + src=base+(curmode->twidth*rold)*curmode->cheight+cleft; + Bitu nextline=curmode->twidth; + /* Setup registers correctly */ + IO_Write(0x3ce,5);IO_Write(0x3cf,1); /* Memory transfer mode */ + IO_Write(0x3c4,2);IO_Write(0x3c5,0xf); /* Enable all Write planes */ + /* Do some copying */ + Bitu rowsize=(cright-cleft); + copy=curmode->cheight; + for (;copy>0;copy--) { + for (Bitu x=0;xtwidth+cleft)*2; + dest=base+(rnew*curmode->twidth+cleft)*2; + MEM_BlockCopy(dest,src,(cright-cleft)*2); +} + +static INLINE void PLANAR4_FillRow(VGAMODES * curmode,Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { + /* Set Bitmask / Color / Full Set Reset */ + IO_Write(0x3ce,0x8);IO_Write(0x3cf,0xff); + IO_Write(0x3ce,0x0);IO_Write(0x3cf,attr); + IO_Write(0x3ce,0x1);IO_Write(0x3cf,0xf); + IO_Write(0x3ce,5);IO_Write(0x3cf,0); /* Normal transfer mode */ + /* Write some bytes */ + PhysPt dest; + dest=base+(curmode->twidth*row)*curmode->cheight+cleft; + Bitu nextline=curmode->twidth; + Bitu copy=curmode->cheight; Bitu rowsize=(cright-cleft); + for (;copy>0;copy--) { + for (Bitu x=0;xtwidth+cleft)*2; + Bit16u fill=(attr<<8)+' '; + for (Bit8u x=0;x<(cright-cleft);x++) { + mem_writew(dest,fill); + dest+=2; + } + +} + + +void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit8u attr,Bit8u page) { + + /* Do some range checking */ BIOS_NCOLS;BIOS_NROWS; - if(rul>rlr) return; if(cul>clr) return; if(rlr>=nrows) rlr=(Bit8u)nrows-1; if(clr>=ncols) clr=(Bit8u)ncols-1; - - // Get the current page + clr++; + /* Get the correct page */ if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); + VGAMODES * curmode=GetCurrentMode(); + PhysPt base=PhysMake(curmode->sstart,curmode->slength*page); - /* Get this from active video mode */ - Bit16u textseg=0xb800; - PhysPt start=PhysMake(textseg,ncols*nrows*2*page); + /* See how much lines need to be copies */ + Bit8u start,end;Bits next; + /* Copy some lines */ + if (nlines>0) { + start=rlr-nlines+1; + end=cul; + next=-1; + } else if (nlines<0) { + start=cul-nlines-1; + end=clr; + next=1; + } else { + nlines=rlr-rul+1; + goto filling; + } + do { + start+=next; + switch (curmode->memmodel) { + case MTEXT: + case CTEXT: + TEXT_CopyRow(curmode,cul,clr,start,start+nlines,base);break; + case PLANAR4: + PLANAR4_CopyRow(curmode,cul,clr,start,start+nlines,base);break; - Bit32u dcol=clr-cul+1; - Bit32u drow=rlr-rul+1; - - Bit32u tocopy; - PhysPt dest=start+((rlr*ncols)+cul)*2; - PhysPt src = 0;/* for gcc */ - if (nlines==0) { - nlines=(Bit8u)nrows; - } - if (nlines>=drow) { - tocopy=0; - } else { - tocopy=drow-nlines; - src=start+(((rul+tocopy-1)*ncols)+cul)*2; - } - - for (Bit32u y=0;y0) { + start=rul; + } else { + nlines-=nlines; + start=rlr-nlines; } + for (;nlines>0;nlines--) { + switch (curmode->memmodel) { + case MTEXT: + case CTEXT: + TEXT_FillRow(curmode,cul,clr,start,base,attr);break; + case PLANAR4: + PLANAR4_FillRow(curmode,cul,clr,start,base,attr);break; + } + start++; + } } -void INT10_ScrollUpWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8u nlines,Bit8u attr,Bit8u page) { - -// Bit8u mode; - Bit16u fill=( (attr << 8) | ' '); - BIOS_NCOLS;BIOS_NROWS; - - if(rlr>nrows) rlr=(Bit8u)nrows; - if(clr>ncols) clr=(Bit8u)ncols; - - if(rul>rlr) return; - if(cul>clr) return; - - VGAMODES * curmode=GetCurrentMode(); - switch (curmode->memmodel) { - case CGA: - { - if (nlines==0) { - /* Clear Screen that we can */ - PhysPt dest=PhysMake(0xb800,0); - for (Bit32u tel=0;tel<0x4000;tel++) { - mem_writew(dest,0x0000); - dest+=2; - } - return; - } - LOG_WARN("INT10:Scroll in CGA Mode"); - } - case MTEXT: - case CTEXT: - break; - default: - LOG_ERROR("INT10:Scroll on non supported graphics mode"); - } - - // Get the current page - if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); - - /* Get this from active video mode */ - Bit16u textseg=0xb800; - PhysPt start=PhysMake(textseg,ncols*nrows*2*page); - - Bit32u dcol=clr-cul+1; - Bit32u drow=rlr-rul+1; - - Bit32u tocopy; - PhysPt dest=start+((rul*ncols)+cul)*2; - PhysPt src; - if (nlines==0) { - nlines=(Bit8u)nrows; - } - - if (nlines>=drow) { - tocopy=0; - } else { - tocopy=drow-nlines; - src=start+(((rul+nlines)*ncols)+cul)*2; - } - for (Bit32u y=0;y7) return; - switch (curmode->memmodel) { - case MTEXT: - case CTEXT:{ - BIOS_NCOLS;BIOS_NROWS; - cur_col=CURSOR_POS_COL(page); - cur_row=CURSOR_POS_ROW(page); - vid_address=SCREEN_IO_START(ncols,nrows,page); - mem_address=SCREEN_MEM_START(ncols,nrows,page); - break; - } - case CGA:{ - vid_address=0; - mem_address=0; - break; - } - case PLANAR4:{ - mem_address=0; - vid_address=((((curmode->sheight*curmode->swidth)>>3)|0xff)+1)*page; - - break; - } - default: - vid_address=0; - mem_address=0; - break; - } - // Calculate the address knowing nbcols nbrows and page num + mem_address=page*curmode->slength; + /* Write the new page start */ real_writew(BIOSMEM_SEG,BIOSMEM_CURRENT_START,mem_address); + if (curmode->svgamode<8) mem_address>>=1; - // CRTC regs 0x0c and 0x0d + + /* Write the new start address in vgahardware */ IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0c); - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(vid_address&0xff00)>>8); + IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(mem_address&0xff00)>>8); IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0d); - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,vid_address&0x00ff); + IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,mem_address&0x00ff); // And change the BIOS page real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE,page); @@ -362,7 +319,7 @@ void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page) { } // Do we need to scroll ? if(cur_row==nrows) { - INT10_ScrollUpWindow(0,0,nrows-1,ncols-1,1,0x07,page); + INT10_ScrollWindow(0,0,nrows-1,ncols-1,-1,0x07,page); cur_row--; } // Set the cursor for the page From 150d9e406cdbe168b6a4f7140c33714c40b175b8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 29 Aug 2002 14:07:55 +0000 Subject: [PATCH 0170/4131] Set interrupt vector 0x1f at startup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@247 --- src/ints/int10_memory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 28a5174e..84b21e05 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -68,7 +68,7 @@ void INT10_SetupRomMemory(void) { real_writeb(0xC000,segoff++,static_functionality[i]); } MEM_BlockWrite(PhysMake(0xf000,0xfa6e),int10_font_08,128*8); - + RealSetVec(0x1F,int10_romarea.font_8_second); }; From 9ee4cbbe764d21cb06bbc3328f4996c8782a33d6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 29 Aug 2002 14:08:10 +0000 Subject: [PATCH 0171/4131] No longer set vector 0x1f on mode set Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@248 --- src/ints/int10_modes.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 015ad115..0419ba99 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -398,5 +398,4 @@ void INT10_SetVideoMode(Bit8u mode) { INT10_SetActivePage(0); /* Set some interrupt vectors */ RealSetVec(0x43,int10_romarea.font_8_first); - RealSetVec(0x1F,int10_romarea.font_8_second); }; From 4245ed0c16e311fb5ddb7129b44920523a24290a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 29 Aug 2002 14:08:25 +0000 Subject: [PATCH 0172/4131] New window scrolling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@249 --- src/ints/int10.cpp | 9 ++++----- src/ints/int10.h | 19 ++++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index ad4811c8..a236e8e9 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - #include #include "dosbox.h" #include "bios.h" @@ -54,14 +53,15 @@ static Bitu INT10_Handler(void) { LOG_WARN("INT10:04:Ligthpen not supported"); break; case 0x05: /* Set Active Page */ - INT10_SetActivePage(reg_al); + if (reg_al & 0x80) LOG_DEBUG("Func %x",reg_al); + else INT10_SetActivePage(reg_al); break; case 0x06: /* Scroll Up */ //TODO Graphics mode scroll - INT10_ScrollUpWindow(reg_ch,reg_cl,reg_dh,reg_dl,reg_al,reg_bh,0xFF); + INT10_ScrollWindow(reg_ch,reg_cl,reg_dh,reg_dl,-reg_al,reg_bh,0xFF); break; case 0x07: /* Scroll Down */ - INT10_ScrollDownWindow(reg_ch,reg_cl,reg_dh,reg_dl,reg_al,reg_bh,0xFF); + INT10_ScrollWindow(reg_ch,reg_cl,reg_dh,reg_dl,reg_al,reg_bh,0xFF); break; case 0x08: /* Read character & attribute at cursor */ //TODO Check for GRAPH and then just return @@ -260,7 +260,6 @@ static void INT10_InitVGA(void) { }; void INT10_StartUp(void) { - INT10_InitVGA(); /* Setup the INT 10 vector */ call_10=CALLBACK_Allocate(); diff --git a/src/ints/int10.h b/src/ints/int10.h index 5c27f537..41ae488c 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -102,11 +102,15 @@ #define PLANAR4 0x05 #define LINEAR8 0x06 -// for SVGA -#define LINEAR15 0x07 -#define LINEAR16 0x08 -#define LINEAR24 0x09 -#define LINEAR32 0x0 +// for Tandy + +#define TANDY16 0x0A + + +#define LINEAR15 0x10 +#define LINEAR16 0x11 +#define LINEAR24 0x12 +#define LINEAR32 0x13 #define SCREEN_SIZE(x,y) (((x*y*2)|0x00ff)+1) @@ -167,14 +171,11 @@ inline Bit8u CURSOR_POS_ROW(Bit8u page) { void INT10_SetVideoMode(Bit8u mode); -void INT10_ScrollUpWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8u nlines,Bit8u attr,Bit8u page); -void INT10_ScrollDownWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8u nlines,Bit8u attr,Bit8u page); - +void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit8u attr,Bit8u page); void INT10_SetActivePage(Bit8u page); void INT10_GetFuncStateInformation(PhysPt save); - void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page); void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page); void INT10_ReadCharAttr(Bit16u * result,Bit8u page); From 4ef165d89418a2bddf2a7697f855b4501ebd53a2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 29 Aug 2002 14:09:00 +0000 Subject: [PATCH 0173/4131] Added 0x59 extended error information Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@250 --- src/dos/dos.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index a2f40513..c334de40 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -662,7 +662,10 @@ static Bitu DOS_21Handler(void) { LOG_DEBUG("DOS:58:Not Supported Set//Get memory allocation"); break; case 0x59: /* Get Extended error information */ - E_Exit("Unhandled Dos 21 call %02X",reg_ah); + reg_ax=dos.errorcode; + reg_bh=0; //Unkown error class + reg_bl=1; //Retry retry retry + reg_ch=0; //Unkown error locus break; case 0x5a: /* Create temporary file */ { From 6b02e3c5afcdcb8d912cb7e2ff5979b5e60b0118 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 29 Aug 2002 14:27:08 +0000 Subject: [PATCH 0174/4131] adjustments for 0.55 release Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@251 --- NEWS | 8 ++++++++ README | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 37cedce4..517fb046 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,14 @@ changed interrupt handler. - speeded up the graphics. - speeded up the cpu-core + - added new features to the debugger: breakpoint support / data view / command line + - partial support of list of lists (dos info block) + - partial emm 4.0 support + - fixes to graphics core fonts (text in sierra games is now correct) + - changed dma + - improved dma streams from emm memory + - added some cga videomodes + - added more funtions to the keyboard handler 0.50: -added F3 to repeat the last typed command. diff --git a/README b/README index a3dd79ac..b6c20dc7 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -DOSBox v0.50 +DOSBox v0.55 Usage: ====== From 7586832b94b1b0a4f745ef64adba7919e8db6bf5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 29 Aug 2002 14:45:50 +0000 Subject: [PATCH 0175/4131] Small fix with last page in reallocate pages Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@252 --- src/ints/ems.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index c0eb1d51..d3b694de 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -142,7 +142,7 @@ static Bit8u EMM_ReallocatePages(Bit16u handle,Bit16u & pages) { /* Check for enough pages */ if ((emm_handles[handle].pages+EMM_GetFreePages())0 && page_count>0) { if (emm_pages[page].handle!=handle) E_Exit("EMM:Error illegal handle reference"); From 98744b3e5114514ea859a966f185e3c92a1ac56c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 31 Aug 2002 20:36:24 +0000 Subject: [PATCH 0176/4131] added checks to see if relative path is used(Bug:600926) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@253 --- src/dosbox.cpp | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index e5ea0c71..403aff13 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -263,21 +263,33 @@ void DOSBOX_Init(int argc, char* argv[]) { /* Parse the command line with a setup function */ int argl=1; if (argc>1) { - if (*argv[1]!='-') { + if (*argv[1]!='-') { + char mount_buffer[CROSS_LEN]; + if( (*argv[1]=='/') || + (*argv[1]=='.') || + (*argv[1]=='~') || + (*(argv[1]+1) ==':') ) { + strcpy(mount_buffer,argv[1]); + } else { + getcwd(mount_buffer,CROSS_LEN); + strcat(mount_buffer,argv[1]); + }; + + struct stat test; - if (stat(argv[1],&test)) { - E_Exit("%s Doesn't exist",argv[1]); + if (stat(mount_buffer,&test)) { + E_Exit("%s Doesn't exist",mount_buffer); } /* Not a switch so a normal directory/file */ if (test.st_mode & S_IFDIR) { - SHELL_AddAutoexec("MOUNT C %s",argv[1]); + SHELL_AddAutoexec("MOUNT C %s",mount_buffer); SHELL_AddAutoexec("C:"); } else { char * name=strrchr(argv[1],CROSS_FILESPLIT); - if (!name) E_Exit("This is weird %s",argv[1]); + if (!name) E_Exit("This is weird %s",mount_buffer); *name++=0; - if (access(argv[1],F_OK)) E_Exit("Illegal Directory %s",argv[1]); - SHELL_AddAutoexec("MOUNT C %s",argv[1]); + if (access(argv[1],F_OK)) E_Exit("Illegal Directory %s",mount_buffer); + SHELL_AddAutoexec("MOUNT C %s",mount_buffer); SHELL_AddAutoexec("C:"); SHELL_AddAutoexec(name); } From 2338468b5bc6fe08bb352b6abc67fbd636c8fb05 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 1 Sep 2002 19:53:47 +0000 Subject: [PATCH 0177/4131] Small fixe for ReadLine stopping too fast when encountering end of file. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@254 --- src/shell/shell_batch.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 499a8756..cec7f45d 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -63,8 +63,8 @@ emptyline: *cmd_write++=c; } } while (c!='\n' && n); - *cmd_write++=0; - if (!n) { + *cmd_write=0; + if (!n && cmd_write==temp) { delete this; return false; } From 4072e141073c03371623d4c1c5fd13a5ad0f2902 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 2 Sep 2002 05:51:14 +0000 Subject: [PATCH 0178/4131] Added REM which does euhm nothing Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@255 --- src/shell/shell_cmds.cpp | 6 ++++-- src/shell/shell_inc.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 1dcec3bc..aeb5a441 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -37,6 +37,8 @@ static SHELL_Cmd cmd_list[]={ "IF", 0, &DOS_Shell::CMD_IF, "Performs conditional processing in batch programs.", "GOTO", 0, &DOS_Shell::CMD_GOTO, "Jump to a labeled line in a batch script.", "TYPE", 0, &DOS_Shell::CMD_TYPE, "Display the contents of a text-file.", + "REM", 0, &DOS_Shell::CMD_REM, "Add comments in a batch file.", + /* "CHDIR", 0, &DOS_Shell::CMD_CHDIR, "Change Directory", "MKDIR", 0, &DOS_Shell::CMD_MKDIR, "Make Directory", @@ -377,5 +379,5 @@ nextfile: if (*args) goto nextfile; } - - +void DOS_Shell::CMD_REM(char * args) { +} \ No newline at end of file diff --git a/src/shell/shell_inc.h b/src/shell/shell_inc.h index d76d4ba9..b44c6134 100644 --- a/src/shell/shell_inc.h +++ b/src/shell/shell_inc.h @@ -77,6 +77,7 @@ public: void CMD_IF(char * args); void CMD_GOTO(char * args); void CMD_TYPE(char * args); + void CMD_REM(char * args); void SyntaxError(void); /* The shell's variables */ From 33c702a8e4db0e240faa319f5ea69de1d5288129 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 3 Sep 2002 12:07:58 +0000 Subject: [PATCH 0179/4131] Added missing FCB-functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@256 --- include/dos_inc.h | 12 +++ src/dos/dos.cpp | 55 +++++++++- src/dos/dos_classes.cpp | 12 +++ src/dos/dos_files.cpp | 218 ++++++++++++++++++++++++++++++++++++---- 4 files changed, 270 insertions(+), 27 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 5edb717f..8de46b2b 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -188,6 +188,14 @@ bool DOS_FCBOpen(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); +bool DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u numBlocks); +bool DOS_FCBCreate(Bit16u seg,Bit16u offset); +Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec); +bool DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u numRec); +bool DOS_FCBGetFileSize(Bit16u seg,Bit16u offset,Bit16u numRec); +bool DOS_FCBDeleteFile(Bit16u seg,Bit16u offset); +bool DOS_FCBRenameFile(Bit16u seg, Bit16u offset); Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u *change); /* Extra DOS Interrupts */ void DOS_SetupMisc(void); @@ -249,6 +257,8 @@ public: void Set_filesize(Bit32u a); void Set_date(Bit16u a); void Set_time(Bit16u a); + void Set_current_record(Bit8u a); + void Set_random_record(Bit32u a); // others nog yet handled Bit8u Get_drive(void); void Get_filename(char* a); @@ -258,6 +268,8 @@ public: Bit32u Get_filesize(void); Bit16u Get_date(void); Bit16u Get_time(void); + Bit8u Get_current_record(void); + Bit32u Get_random_record(void); private: PhysPt off; }; diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index c334de40..f847aced 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -202,19 +202,64 @@ static Bitu DOS_21Handler(void) { break; case 0x13: /* Delete File using FCB */ + if (DOS_FCBDeleteFile(SegValue(ds),reg_dx)) reg_al = 0x00; + else reg_al = 0xFF; + break; case 0x14: /* Sequential read from FCB */ + reg_al = DOS_FCBRead(SegValue(ds),reg_dx,0); + LOG_DEBUG("DOS:0x14 FCB-Read used, result:al=%d",reg_al); + break; case 0x15: /* Sequential write to FCB */ + if (DOS_FCBWrite(SegValue(ds),reg_dx,0)) reg_al = 0x00; + else reg_al = 0x01; + LOG_DEBUG("DOS:0x15 FCB-Write used, result:al=%d",reg_al); + break; case 0x16: /* Create or truncate file using FCB */ - case 0x17: /* Rename file using FCB */ + if (DOS_FCBCreate(SegValue(ds),reg_dx)) reg_al = 0x00; + else reg_al = 0x01; + LOG_DEBUG("DOS:0x16 FCB-Create used, result:al=%d",reg_al); + break; + case 0x17: /* Rename file using FCB */ + if (DOS_FCBRenameFile(SegValue(ds),reg_dx)) reg_al = 0x00; + else reg_al = 0xFF; + break; case 0x21: /* Read random record from FCB */ + { DOS_FCB fcb(SegValue(ds),reg_dx); + Bit8u curRec = fcb.Get_current_record(); + Bit16u curBlock = fcb.Get_current_block(); + reg_al = DOS_FCBRead(SegValue(ds),reg_dx,0); + fcb.Set_current_record(curRec); + fcb.Set_current_block(curBlock); + } + LOG_DEBUG("DOS:0x21 FCB-Random read used, result:al=%d",reg_al); + break; case 0x22: /* Write random record to FCB */ + { DOS_FCB fcb(SegValue(ds),reg_dx); + Bit8u curRec = fcb.Get_current_record(); + Bit16u curBlock = fcb.Get_current_block(); + if (DOS_FCBRandomWrite(SegValue(ds),reg_dx,reg_cx)) reg_al = 0x00; + else reg_al = 0x01; + fcb.Set_current_record(curRec); + fcb.Set_current_block(curBlock); + } + LOG_DEBUG("DOS:0x28 FCB-Random write used, result:al=%d",reg_al); + break; case 0x23: /* Get file size for FCB */ + if (DOS_FCBGetFileSize(SegValue(ds),reg_dx,reg_cx)) reg_al = 0x00; + else reg_al = 0xFF; + break; case 0x24: /* Set Random Record number for FCB */ + { DOS_FCB fcb(SegValue(ds),reg_dx); + fcb.Set_random_record(fcb.Get_current_block()*128+fcb.Get_current_record()); + } break; case 0x27: /* Random block read from FCB */ - case 0x28: /* Random Block read to FCB */ - LOG_ERROR("DOS:Unhandled call %02X, FCB Stuff",reg_ah); - reg_al=0xff; /* FCB Calls FAIL */ - //CALLBACK_SCF(true); not needed. + reg_al = DOS_FCBRandomRead(SegValue(ds),reg_dx,reg_cx); + LOG_DEBUG("DOS:0x27 FCB-Random read used, result:al=%d",reg_al); + break; + case 0x28: /* Random Block write to FCB */ + if (DOS_FCBRandomWrite(SegValue(ds),reg_dx,reg_cx)) reg_al = 0x00; + else reg_al = 0x01; + LOG_DEBUG("DOS:0x28 FCB-Random write used, result:al=%d",reg_al); break; case 0x29: /* Parse filename into FCB */ diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 04cd8a33..f84995ed 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -208,6 +208,12 @@ void DOS_FCB::Set_date(Bit16u a){ void DOS_FCB::Set_time(Bit16u a){ mem_writew(off+offsetof(sFCB,time)+FCB_EXTENDED,a); } +void DOS_FCB::Set_current_record(Bit8u a){ + mem_writeb(off+offsetof(sFCB,current_relative_record_number)+FCB_EXTENDED,a); +} +void DOS_FCB::Set_random_record(Bit32u a){ + mem_writed(off+offsetof(sFCB,rel_record)+FCB_EXTENDED,a); +} Bit8u DOS_FCB::Get_drive(void){ return mem_readb(off+offsetof(sFCB,drive)+FCB_EXTENDED); } @@ -232,6 +238,12 @@ Bit16u DOS_FCB::Get_date(void){ Bit16u DOS_FCB::Get_time(void){ return mem_readw(off+offsetof(sFCB,time)+FCB_EXTENDED); } +Bit8u DOS_FCB::Get_current_record(void){ + return mem_readb(off+offsetof(sFCB,current_relative_record_number)+FCB_EXTENDED); +} +Bit32u DOS_FCB::Get_random_record(void){ + return mem_readd(off+offsetof(sFCB,rel_record)+FCB_EXTENDED); +} void DOS_ParamBlock::InitExec(RealPt cmdtail) { diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 4ee82a0c..dab3a320 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -583,27 +583,13 @@ Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u * fcb.Set_ext(ext); *change=string-backup; return retwaarde; - - - } -bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { - DOS_FCB fcb(seg,offset); - Bit8u drive; - char fullname[DOS_PATHLENGTH]; - if(!FCB_MakeName (&fcb, fullname, &drive)) return false; - if(!Drives[drive]->FileExists(fullname)) return false; //not really needed as stat will error. - struct stat stat_block; - if(!Drives[drive]->FileStat(fullname, &stat_block)) return false; - fcb.Set_filesize((Bit32u)stat_block.st_size); - Bit16u constant = 0; - fcb.Set_current_block(constant); - constant=0x80; - fcb.Set_record_size(constant); - - struct tm *time; - if((time=localtime(&stat_block.st_mtime))!=0){ +void DOS_FCBSetDateTime(DOS_FCB& fcb,struct stat& stat_block) +{ + Bit16u constant; + struct tm *time; + if((time=localtime(&stat_block.st_mtime))!=0){ constant=(time->tm_hour<<11)+(time->tm_min<<5)+(time->tm_sec/2); /* standard way. */ fcb.Set_time(constant); @@ -616,9 +602,28 @@ bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { constant=4; fcb.Set_date(constant); } - fcb.Set_drive(drive +1); - return true; - } +}; + +bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { + DOS_FCB fcb(seg,offset); + Bit8u drive; + char fullname[DOS_PATHLENGTH]; + if(!FCB_MakeName (&fcb, fullname, &drive)) return false; + if(!Drives[drive]->FileExists(fullname)) return false; //not really needed as stat will error. + + struct stat stat_block; + if(!Drives[drive]->FileStat(fullname, &stat_block)) return false; + fcb.Set_filesize((Bit32u)stat_block.st_size); + Bit16u constant = 0; + fcb.Set_current_block(constant); + constant=0x80; + fcb.Set_record_size(constant); + + DOS_FCBSetDateTime(fcb,stat_block); + + fcb.Set_drive(drive +1); + return true; +} bool DOS_FCBClose(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); @@ -707,6 +712,175 @@ bool DOS_FCBFindNext(Bit16u seg,Bit16u offset) return true; } +bool DOS_FCBCreate(Bit16u seg,Bit16u offset) +{ + DOS_FCB fcb(seg,offset); + Bit8u drive; + DOS_File* file; + char fullname[DOS_PATHLENGTH]; + + if (!FCB_MakeName (&fcb, fullname, &drive)) return false; + if (!Drives[drive]->FileCreate(&file,fullname,0)) return false; + // Set Date & time + struct stat stat_block; + Drives[drive]->FileStat(fullname, &stat_block); + DOS_FCBSetDateTime(fcb,stat_block); + file->Close(); + // Clear fcb + fcb.Set_record_size(128); // ? + fcb.Set_current_record(0); + fcb.Set_random_record(0); + fcb.Set_filesize(0); + return true; +}; + +Bit8u DOS_FCBRead(Bit16u seg,Bit16u offset,Bit16u recno) +{ + DOS_FCB fcb(seg,offset); + Bit8u drive; + DOS_File* file; + char fullname[DOS_PATHLENGTH]; + // Open file + if (!FCB_MakeName (&fcb, fullname, &drive)) return 0x01; + if (!Drives[drive]->FileOpen(&file,fullname,OPEN_READ)) return 0x01; + // Position file + Bit32u filePos = (fcb.Get_current_block()*128+fcb.Get_current_record()) * fcb.Get_record_size(); + if (!file->Seek(&filePos,0x00)) { file->Close(); return 0x01; }; // end of file + // Calculate target + Bit8u* target = HostMake(RealSeg(dos.dta),RealOff(dos.dta)+recno*fcb.Get_record_size()); + // Read record + Bit16u toRead = fcb.Get_record_size(); + if (!file->Read(target,&toRead)) { file->Close(); return 0x01; }; + // fill with 0 + memset(target+toRead,0,fcb.Get_record_size()-toRead); + // Update record + Bit8u curRec = fcb.Get_current_record() + 1; + if (curRec>128) { + fcb.Set_current_record(0); + fcb.Set_current_block(fcb.Get_current_block()+1); + } else + fcb.Set_current_record(curRec); + + file->Close(); + // check for error + if (toReadFileOpen(&file,fullname,OPEN_WRITE)) return false; + // Position file + Bit32u filePos = (fcb.Get_current_block()*128+fcb.Get_current_record()) * fcb.Get_record_size(); + if (!file->Seek(&filePos,0x00)) { file->Close(); return false; }; // end of file + // Calculate source + Bit8u* source = HostMake(RealSeg(dos.dta),RealOff(dos.dta)+recno*fcb.Get_record_size()); + // Write record + Bit16u toWrite = fcb.Get_record_size(); + if (!file->Write(source,&toWrite)) { file->Close(); return false; }; + // Update size + Bit32u fsize = fcb.Get_filesize() + toWrite; + fcb.Set_filesize(fsize); + // Update Date & Time + struct stat stat_block; + Drives[drive]->FileStat(fullname, &stat_block); + DOS_FCBSetDateTime(fcb,stat_block); + // Update record + Bit8u curRec = fcb.Get_current_record() + 1; + if (curRec>128) { + fcb.Set_current_record(0); + fcb.Set_current_block(fcb.Get_current_block()+1); + } else + fcb.Set_current_record(curRec); + + file->Close(); + return (toWrite==fcb.Get_record_size()); +}; + +Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec) +{ + DOS_FCB fcb(seg,offset); + Bit16u recno = 0; + Bit8u error; + // Calculate block&rec + fcb.Set_current_block (Bit16u(fcb.Get_random_record() / 128)); + fcb.Set_current_record(Bit8u (fcb.Get_random_record() % 127)); + // Read records + for (int i=0; iFileOpen(&file,fullname,OPEN_WRITE)) return false; + struct stat stat_block; + if(!Drives[drive]->FileStat(fullname, &stat_block)) { file->Close(); return false; }; + Bit32u fsize = (Bit32u)stat_block.st_size; + //compute the size and update the fcb + fcb.Set_random_record(fsize / fcb.Get_record_size()); + if ((fsize % fcb.Get_record_size())!=0) fcb.Set_random_record(fcb.Get_random_record()+1); + fcb.Set_filesize(fsize); + return true; +}; + +bool DOS_FCBDeleteFile(Bit16u seg,Bit16u offset) +{ + DOS_FCB fcb(seg,offset); + Bit8u drive; + char fullname[DOS_PATHLENGTH]; + // Open file + if (!FCB_MakeName (&fcb, fullname, &drive)) return false; + return Drives[drive]->FileUnlink(fullname); +}; + +bool DOS_FCBRenameFile(Bit16u seg, Bit16u offset) +{ + Bit8u olddrive,newdrive; + DOS_FCB fcbold(seg,offset); + DOS_FCB fcbnew(seg,offset+16); + char oldfullname[DOS_PATHLENGTH]; + char newfullname[DOS_PATHLENGTH]; + if (!FCB_MakeName (&fcbold, oldfullname, &olddrive)) return false; + if (!FCB_MakeName (&fcbnew, newfullname, &newdrive)) return false; + //TODO Test for different drives maybe + return (Drives[newdrive]->Rename(oldfullname,newfullname)); +}; + #endif bool DOS_FileExists(char * name) { From b5d4c88ad7c15ad13f7d150123fe514a3744bc94 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 3 Sep 2002 13:43:44 +0000 Subject: [PATCH 0180/4131] added a switch to windowed mode in E_Exit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@257 --- include/video.h | 22 +++++++++++++++++++++- src/gui/sdlmain.cpp | 22 +++++----------------- src/misc/support.cpp | 6 +++++- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/include/video.h b/include/video.h index 25199495..5fd7a8cb 100644 --- a/include/video.h +++ b/include/video.h @@ -18,7 +18,8 @@ #ifndef __VIDEO_H #define __VIDEO_H - +#include +#include typedef void (GFX_DrawHandler)(Bit8u * vidstart); /* Used to reply to the renderer what size to set */ typedef void (GFX_ResizeHandler)(Bitu * width,Bitu * height); @@ -34,8 +35,27 @@ struct GFX_Info { Bitu width,height,bpp,pitch; }; + extern GFX_Info gfx_info; +struct SDL_Block { + bool active; //If this isn't set don't draw + Bitu width; + Bitu height; + Bitu bpp; + GFX_DrawHandler * draw; + GFX_ResizeHandler * resize; + bool mouse_grabbed; + bool full_screen; + SDL_Thread * thread; + SDL_mutex * mutex; + SDL_Surface * surface; + SDL_Joystick * joy; + SDL_Color pal[256]; +}; + +extern SDL_Block sdl; + void GFX_Events(void); void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries); void GFX_SetDrawHandler(GFX_DrawHandler * handler); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 63810e91..3bc5868e 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -32,23 +32,7 @@ //#define DISABLE_JOYSTICK -struct SDL_Block { - bool active; //If this isn't set don't draw - Bitu width; - Bitu height; - Bitu bpp; - GFX_DrawHandler * draw; - GFX_ResizeHandler * resize; - bool mouse_grabbed; - bool full_screen; - SDL_Thread * thread; - SDL_mutex * mutex; - SDL_Surface * surface; - SDL_Joystick * joy; - SDL_Color pal[256]; -}; - -static SDL_Block sdl; +SDL_Block sdl; GFX_Info gfx_info; @@ -120,6 +104,10 @@ static void SwitchFullScreen(void) { ResetScreen(); GFX_Start(); } +//only prototype existed +void GFX_SwitchFullScreen(void) { + SwitchFullScreen(); +} static void GFX_Redraw() { #if C_THREADED diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 42959512..6e5f7cae 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -216,6 +216,10 @@ void S_Warn(char * format,...) { } void E_Exit(char * format,...) { + + if (sdl.full_screen) { + GFX_SwitchFullScreen(); + } char buf[1024]; @@ -225,7 +229,7 @@ void E_Exit(char * format,...) { va_start(msg,format); vsprintf(buf+strlen(buf),format,msg); va_end(msg); - + strcat(buf,"\n"); printf(buf); printf("Press ENTER to stop\n"); From 6470f164475252634f439713d684cd23a7cb67c7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 4 Sep 2002 21:49:22 +0000 Subject: [PATCH 0181/4131] Fixed bug with joystick always going down. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@258 --- src/hardware/joystick.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index 3193d53b..b0c03ef7 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -60,12 +60,12 @@ static Bit8u read_p201(Bit32u port) { static void write_p201(Bit32u port,Bit8u val) { if (stick[0].enabled) { - stick[0].xcount=(Bitu)(stick[0].xpos*RANGE+RANGE*2); - stick[0].ycount=(Bitu)(stick[0].ypos*RANGE+RANGE*2); + stick[0].xcount=(Bitu)((stick[0].xpos*RANGE)+RANGE); + stick[0].ycount=(Bitu)((stick[0].ypos*RANGE)+RANGE); } if (stick[1].enabled) { - stick[1].xcount=(Bitu)(stick[1].xpos*RANGE+RANGE*2); - stick[1].ycount=(Bitu)(stick[1].ypos*RANGE+RANGE*2); + stick[1].xcount=(Bitu)((stick[1].xpos*RANGE)+RANGE); + stick[1].ycount=(Bitu)((stick[1].ypos*RANGE)+RANGE); } } From c5d481d1fd8d85adc844e0c33df8e26bedea68dd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 4 Sep 2002 22:00:35 +0000 Subject: [PATCH 0182/4131] Which now check's .com .exe .bat in that order. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@259 --- src/shell/shell_misc.cpp | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index df465b18..7e63364b 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -193,32 +193,25 @@ static char which_ret[DOS_PATHLENGTH]; char * DOS_Shell::Which(char * name) { /* Parse through the Path to find the correct entry */ - -// if (which_result) free(which_result); - /* Check for extension */ - - - /* Check if name is already ok but just misses an extension */ char * ext=strrchr(name,'.'); if (ext) if (strlen(ext)>4) ext=0; if (ext) { if (DOS_FileExists(name)) return name; } else { - /* try to find .exe .com .bat */ - strcpy(which_ret,name); - strcat(which_ret,bat_ext); - if (DOS_FileExists(which_ret)) return which_ret; + /* try to find .com .exe .bat */ strcpy(which_ret,name); strcat(which_ret,com_ext); if (DOS_FileExists(which_ret)) return which_ret; strcpy(which_ret,name); strcat(which_ret,exe_ext); if (DOS_FileExists(which_ret)) return which_ret; + strcpy(which_ret,name); + strcat(which_ret,bat_ext); + if (DOS_FileExists(which_ret)) return which_ret; } /* No Path in filename look through %path% */ - static char path[DOS_PATHLENGTH]; char * pathenv=GetEnvStr("PATH"); if (!pathenv) return 0; @@ -238,17 +231,16 @@ char * DOS_Shell::Which(char * name) { if (ext) { if (DOS_FileExists(which_ret)) return which_ret; } else { - strcpy(which_ret,path); - strcat(which_ret,bat_ext); - if (DOS_FileExists(which_ret)) return which_ret; strcpy(which_ret,path); strcat(which_ret,com_ext); if (DOS_FileExists(which_ret)) return which_ret; strcpy(which_ret,path); strcat(which_ret,exe_ext); if (DOS_FileExists(which_ret)) return which_ret; + strcpy(which_ret,path); + strcat(which_ret,bat_ext); + if (DOS_FileExists(which_ret)) return which_ret; } - path_write=path; if (*pathenv) pathenv++; } From cbfad16d0a7ac5d34727ee8d3c43ccc2ded86578 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 5 Sep 2002 09:26:27 +0000 Subject: [PATCH 0183/4131] added a section to FAQ: mouse problems Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@260 --- README | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README b/README index b6c20dc7..dc309118 100644 --- a/README +++ b/README @@ -70,7 +70,10 @@ FAQ: A: When you mouse touches the edges of the DOSBox screen you can click and drag it to the size you prefer. -3. Check the site/forum. +3.Q: The mouse(cursor) acts weird. (eg only updated when you press the mousebutton) + A: Lock the mouse with ctrl-F10. It should then behave the way you expect it to do. + +4. Check the site/forum. Building your own Version DOSBox: ================================= From e51de713067043e5de524011d7690b3da838da7f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 6 Sep 2002 19:59:49 +0000 Subject: [PATCH 0184/4131] New timer code and removed some old command line stuff not used anymore. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@261 --- src/dosbox.cpp | 104 +++++++------------------------------------------ 1 file changed, 15 insertions(+), 89 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 403aff13..7aa59c4c 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -38,64 +38,6 @@ char dosbox_basedir[CROSS_LEN]; - -#if 0 - -int main(int argc, char* argv[]) { - - - - /* Strip out the dosbox startup directory */ - - - - /* Handle the command line for new stuff to add to autoexec.bat */ - int argl=1; - if (argc>1) { - if (*argv[1]!='-') { - struct stat test; - if (stat(argv[1],&test)) { - E_Exit("%s Doesn't exist",argv[1]); - } - /* Not a switch so a normal directory/file */ - if (test.st_mode & S_IFDIR) { - SHELL_AddAutoexec("MOUNT C %s",argv[1]); - SHELL_AddAutoexec("C:"); - } else { - char * name=strrchr(argv[1],CROSS_FILESPLIT); - if (!name) E_Exit("This is weird %s",argv[1]); - *name++=0; - if (access(argv[1],F_OK)) E_Exit("Illegal Directory %s",argv[1]); - SHELL_AddAutoexec("MOUNT C %s",argv[1]); - SHELL_AddAutoexec("C:"); - SHELL_AddAutoexec(name); - } - argl++; - } - } - bool sw_c=false; - while (arglLastTicks) { - Bit32u ticks=new_ticks-LastTicks; - if (ticks>20) ticks=20; -// if (ticks>3) LOG_DEBUG("Ticks %d",ticks); - LastTicks=new_ticks; - TIMER_AddTicks(ticks); - cycles+=cpu_cycles*ticks; - } - TIMER_CheckPIT(); - GFX_Events(); - PIC_runIRQs(); - return (*cpudecoder)(cycles); -} - void DOSBOX_SetLoop(LoopHandler * handler) { loop=handler; } @@ -218,6 +145,10 @@ static void InitSystems(void) { #if C_DEBUG DEBUG_Init(); #endif + + LastTicks=GetTicks(); + DOSBOX_SetLoop(&Normal_Loop); + //Start up individual hardware DMA_Init(); PIC_Init(); @@ -226,22 +157,17 @@ static void InitSystems(void) { MOUSE_Init(); JOYSTICK_Init(); SBLASTER_Init(); - TANDY_Init(); - PCSPEAKER_Init(); +// TANDY_Init(); +// PCSPEAKER_Init(); ADLIB_Init(); - CMS_Init(); +// CMS_Init(); PLUGIN_Init(); -/* Most of teh interrupt handlers */ +/* Most of the interrupt handlers */ BIOS_Init(); DOS_Init(); EMS_Init(); //Needs dos first XMS_Init(); //Needs dos first - -/* Setup the normal system loop */ - LastTicks=GetTicks(); - DOSBOX_SetLoop(&Normal_Loop); -// DOSBOX_SetLoop(&Speed_Loop); } From 0809de690d931303754186608e6a32d3f44bb434 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 6 Sep 2002 20:03:37 +0000 Subject: [PATCH 0185/4131] New timer code, now avarages time index requests. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@262 --- src/hardware/timer.cpp | 59 ++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 0b256bf5..560be4ee 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -42,11 +42,22 @@ struct PIT_Block { Bit32u last_ticks; }; - +bool TimerAgain; +Bit32u LastTicks; static PIT_Block pit[3]; static Bit32u pit_ticks; /* The amount of pit ticks one host tick is bit shifted */ static Bit32u timer_ticks; /* The amount of pit ticks bitshifted one timer cycle needs */ -static Bit32u timer_buildup; /* The amount of pit ticks waiting */ +static Bit32u timer_buildup; /* The amount of pit ticks waiting */ + +#define TIMER_AVERAGE 5 +static struct TimerBlock { + float req[TIMER_AVERAGE]; + Bitu req_index; + Bitu req_count; + float req_average; + Bitu ticks; +} timer; + #define PIT_TICK_RATE 1193182 #define PIT_SHIFT 9 #define MAX_PASSED ((PIT_TICK_RATE/4) << PIT_SHIFT) /* Alow 1/4 second of timer build up */ @@ -55,8 +66,9 @@ static Bit32u timer_buildup; /* The amount of pit ticks waiting */ static void counter_latch(Bitu counter) { /* Fill the read_latch of the selected counter with current count */ PIT_Block * p=&pit[counter]; -//TODO Perhaps make it a bit64u for accuracy :) - Bit32u ticks=(((LastTicks - p->last_ticks) * pit_ticks) >> PIT_SHIFT) % p->cntr ; + timer.req_count++; + float pos=timer.req_average*timer.req_count; + Bit16u ticks=pos*p->cntr; switch (p->mode) { case 2: case 3: @@ -233,29 +245,30 @@ void TIMER_SetNewMicro(TIMER_Block * block,Bitu micro) { } void TIMER_AddTicks(Bit32u ticks) { -/* This will run through registered handlers and handle the PIT ticks */ +/* Add pit ticks to the counter */ timer_buildup+=ticks*pit_ticks; if (timer_buildup>MAX_PASSED) timer_buildup=MAX_PASSED; - Bitu add_micro=ticks*1000; + /* Check if there are timer handlers that need to be called */ + Bitu add_micro=timer.ticks*1000; std::list::iterator i; for(i=Timers.begin(); i != Timers.end(); ++i) { - Timer * timer=(*i); - switch (timer->type) { + Timer * timers=(*i); + switch (timers->type) { case T_TICK: - timer->tick.handler(ticks); + if (timer.ticks) timers->tick.handler(timer.ticks); break; case T_MICRO: - timer->micro.count+=add_micro; - if (timer->micro.count>=timer->micro.total) { - timer->micro.count-=timer->micro.total; - timer->micro.handler(); + timers->micro.count+=add_micro; + if (timers->micro.count>=timers->micro.total) { + timers->micro.count-=timers->micro.total; + timers->micro.handler(); } break; case T_DELAY: /* Also unregister the timer handler from the list */ - if (LastTicks>timer->delay.end) { + if (LastTicks>timers->delay.end) { std::list::iterator remove; - timer->delay.handler(); + timers->delay.handler(); remove=i++; Timers.erase(remove); } @@ -265,19 +278,30 @@ void TIMER_AddTicks(Bit32u ticks) { }; }; + timer.ticks=ticks; } void TIMER_CheckPIT(void) { if (timer_buildup>timer_ticks) { timer_buildup-=timer_ticks; + if (timer_buildup>timer_ticks) TimerAgain=true; + else TimerAgain=false; + /* Calculate amount of times the time index was requested */ + timer.req[timer.req_index]=timer.req_count; + timer.req_index++;if (timer.req_index>=TIMER_AVERAGE) timer.req_index=0; + timer.req_count=0; + Bitu l;float total=0; + for (l=0;l Date: Sat, 7 Sep 2002 12:06:43 +0000 Subject: [PATCH 0186/4131] New timer code Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@263 --- include/timer.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/timer.h b/include/timer.h index a481d592..95faaa07 100644 --- a/include/timer.h +++ b/include/timer.h @@ -24,6 +24,8 @@ extern Bit32u LastTicks; #define GetTicks() SDL_GetTicks() +extern bool TimerAgain; + typedef void (*TIMER_TickHandler)(Bitu ticks); typedef void (*TIMER_MicroHandler)(void); typedef void (*TIMER_DelayHandler)(void); From bd35a40c9df39f5ba79c89f3c9bf60f30c0eb6d2 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 8 Sep 2002 09:59:16 +0000 Subject: [PATCH 0187/4131] new psp class used for all psp actions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@264 --- include/dos_inc.h | 129 ++++++++++++++++----- include/programs.h | 2 +- src/dos/dos.cpp | 7 +- src/dos/dos_classes.cpp | 249 +++++++++++++++++++++------------------- src/dos/dos_execute.cpp | 161 ++++++++++---------------- src/dos/dos_files.cpp | 52 +++------ src/misc/programs.cpp | 2 +- src/shell/shell.cpp | 29 ++--- 8 files changed, 319 insertions(+), 312 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 8de46b2b..299e8358 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -29,32 +29,31 @@ struct CommandTail{ char buffer[127]; /* the buffer itself */ } GCC_ATTRIBUTE(packed); -struct PSP { - Bit8u exit[2]; /* CP/M-like exit poimt */ - Bit16u mem_size; /* memory size in paragraphs */ - Bit8u fill_1; /* single char fill */ +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 */ + 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[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; -/* 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; - } GCC_ATTRIBUTE(packed); struct ParamBlock { @@ -114,6 +113,76 @@ struct DOS_Block { } tables; }; +class MemStruct { +public: + Bit8u GetIt(Bit8u,PhysPt addr) { + return mem_readb(pt+addr); + }; + Bit16u GetIt(Bit16u,PhysPt addr) { + return mem_readw(pt+addr); + }; + Bit32u GetIt(Bit32u,PhysPt addr) { + return mem_readd(pt+addr); + }; + void SaveIt(Bit8u,PhysPt addr,Bit8u val) { + mem_writeb(pt+addr,val); + }; + void SaveIt(Bit16u,PhysPt addr,Bit16u val) { + mem_writew(pt+addr,val); + }; + void SaveIt(Bit32u,PhysPt addr,Bit32u val) { + mem_writed(pt+addr,val); + }; + + +protected: +PhysPt pt; + +}; + +#define sGet(s,m) GetIt(((s *)Phys2Host(pt))->m,(PhysPt)&(((s *)0)->m)) +#define sSave(s,m,val) SaveIt(((s *)Phys2Host(pt))->m,(PhysPt)&(((s *)0)->m),val) + +class DOS_PSP :public MemStruct { +public: + DOS_PSP () { seg=0; pt=0; }; + DOS_PSP (Bit16u segment) { NewPt(segment); }; + void NewPt (Bit16u segment); + void MakeNew (Bit16u memSize); + + void CopyFileTable (DOS_PSP* srcpsp); + Bit16u FindFreeFileEntry (void); + void CloseFiles (void); + + void SaveVectors (void); + void RestoreVectors (void); + void SetSize (Bit16u size) { sSave(sPSP,next_seg,size); }; + Bit16u GetSize () { return sGet(sPSP,next_seg); }; + void SetDTA (RealPt ptdta) { sSave(sPSP,dta,ptdta); }; + RealPt GetDTA (void) { return sGet(sPSP,dta); }; + void SetEnvironment (Bit16u envseg) { sSave(sPSP,environment,envseg); }; + Bit16u GetEnvironment (void) { return 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 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); + +private: + Bit16u seg; + sPSP* psp; + +public: + static Bit16u rootpsp; +}; + enum { MCB_FREE=0x0000,MCB_DOS=0x0008 }; enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; @@ -170,7 +239,7 @@ bool DOS_GetSTDINStatus(); Bit8u DOS_FindDevice(char * name); void DOS_SetupDevices(void); /* Execute and new process creation */ -bool DOS_NewPSP(Bit16u pspseg); +bool DOS_NewPSP(Bit16u pspseg,Bit16u size); bool DOS_Execute(char * name,ParamBlock * block,Bit8u flags); bool DOS_Terminate(bool tsr); @@ -213,9 +282,9 @@ INLINE Bit16u long2para(Bit32u size) { }; INLINE Bit8u RealHandle(Bit16u handle) { - PSP * psp=(PSP *)HostMake(dos.psp,0); - if (handle>=psp->max_files) return 0xff; - return mem_readb(Real2Phys(psp->file_table)+handle); + + DOS_PSP psp(dos.psp); + return psp.GetFileHandle((Bit8u)handle); }; /* Dos Error Codes */ @@ -274,8 +343,6 @@ private: PhysPt off; }; - - class DOS_ParamBlock { public: DOS_ParamBlock(PhysPt pt){ diff --git a/include/programs.h b/include/programs.h index d716510c..8151ce5b 100644 --- a/include/programs.h +++ b/include/programs.h @@ -26,7 +26,7 @@ char * MSG_Get(char * msg); struct PROGRAM_Info { Bit16u psp_seg; - PSP psp_copy; + sPSP psp_copy; char full_name[32]; //Enough space for programs only on the z:\ drive char * cmd_line; }; diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index f847aced..bee05a3d 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -313,7 +313,7 @@ static Bitu DOS_21Handler(void) { RealSetVec(reg_al,RealMakeSeg(ds,reg_dx)); break; case 0x26: /* Create new PSP */ - DOS_NewPSP(reg_dx); + DOS_NewPSP(reg_dx,DOS_PSP(dos.psp).GetSize()); break; case 0x2a: /* Get System Date */ reg_al=0; /* It's always sunday TODO find that correct formula */ @@ -685,9 +685,12 @@ static Bitu DOS_21Handler(void) { case 0x53: /* Translate BIOS parameter block to drive parameter block */ //YEAH RIGHT case 0x54: /* Get verify flag */ - case 0x55: /* Create Child PSP*/ E_Exit("Unhandled Dos 21 call %02X",reg_ah); break; + case 0x55: /* Create Child PSP*/ + DOS_NewPSP(reg_dx,reg_si); + dos.psp = reg_dx; + break; case 0x56: /* RENAME Rename file */ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); MEM_StrCopy(SegPhys(es)+reg_di,name2,DOSNAMEBUF); diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index f84995ed..a63e5302 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -31,32 +31,6 @@ #pragma pack (1) -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 */ - -/* 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; -} GCC_ATTRIBUTE(packed); - union sParamBlock { struct { Bit16u loadseg; @@ -88,100 +62,6 @@ struct sFCB { #pragma pack () -#define sGet(s,m) GetIt(((s *)0)->m,(PhysPt)&(((s *)0)->m)) -#define sSave(s,m,val) SaveIt(((s *)0)->m,(PhysPt)&(((s *)0)->m),val) - - -class MemStruct { -public: - Bit8u GetIt(Bit8u,PhysPt addr) { - return mem_readb(pt+addr); - }; - Bit16u GetIt(Bit16u,PhysPt addr) { - return mem_readw(pt+addr); - }; - Bit32u GetIt(Bit32u,PhysPt addr) { - return mem_readd(pt+addr); - }; - void SaveIt(Bit8u,PhysPt addr,Bit8u val) { - mem_writeb(pt+addr,val); - }; - void SaveIt(Bit16u,PhysPt addr,Bit16u val) { - mem_writew(pt+addr,val); - }; - void SaveIt(Bit32u,PhysPt addr,Bit32u val) { - mem_writed(pt+addr,val); - }; - - -private: -PhysPt pt; - -}; - - -class DOS_PSP :public MemStruct { -public: - DOS_PSP(Bit16u segment){NewPt(segment);}; - void NewPt(Bit16u segment); - void MakeNew(Bit16u mem_size); - Bit8u GetFileHandle(Bitu index); - -private: - Bit16u seg; - PhysPt pt; -}; - -void DOS_PSP::NewPt(Bit16u segment) { - seg=segment; - pt=PhysMake(segment,0); -}; - - - -void DOS_PSP::MakeNew(Bit16u mem_size) { - Bitu i; - /* Clear it first */ - for (i=0;i<256;i++) mem_writeb(pt+i,0); - /* Standard blocks,int 20 and int21 retf */ - sGet(sPSP,max_files); - sSave(sPSP,exit[0],0xcd); - sSave(sPSP,exit[1],0x20); - sSave(sPSP,service[0],0xcd); - sSave(sPSP,service[1],0x21); - sSave(sPSP,service[2],0xcb); - /* psp and psp-parent */ - sSave(sPSP,psp_parent,dos.psp); - sSave(sPSP,prev_psp,RealMake(dos.psp,0)); - /* terminate 22,break 23,crititcal error 24 address stored */ - sSave(sPSP,int_22,RealGetVec(0x22)); - sSave(sPSP,int_23,RealGetVec(0x23)); - sSave(sPSP,int_24,RealGetVec(0x24)); - /* Memory size */ - sSave(sPSP,next_seg,seg+mem_size); - /* Process DTA */ - sSave(sPSP,dta,RealMake(seg,128)); - /* User Stack pointer */ - //Copy from previous psp - // mem_writed(pt+offsetof(sPSP,stack), - - /* Init file pointer and max_files */ - sSave(sPSP,file_table,RealMake(seg,offsetof(sPSP,files[0]))); - sSave(sPSP,max_files,20); - /* Copy file table from calling process */ - for (i=0;i<20;i++) { - Bit8u handle=0; - // Bitu handle=dos.psp.GetFileHandle(i); - sSave(sPSP,files[i],handle); - } -} - -Bit8u DOS_PSP::GetFileHandle(Bitu index) { - if (index>=sGet(sPSP,max_files)) return 0xff; - PhysPt files=Real2Phys(sGet(sPSP,file_table)); - return mem_readb(files+index); -}; - #define FCB_EXTENDED (mem_readb(off)==0xFF ? 7:0) void DOS_FCB::Set_drive(Bit8u a){ @@ -298,3 +178,132 @@ void DOS_InfoBlock::GetDIBPointer(Bit16u& segment, Bit16u& offset) segment = seg; offset = offsetof(SDosInfoBlock,firstDPB); }; + + +/* program Segment prefix */ + +Bit16u DOS_PSP::rootpsp = 0; + +void DOS_PSP::NewPt(Bit16u segment) +{ + seg = segment; + pt = PhysMake(segment,0); + // debug + psp = (sPSP*)Phys2Host(pt); +}; + +void DOS_PSP::MakeNew(Bit16u mem_size) +{ + /* get previous */ + DOS_PSP prevpsp(dos.psp); + /* Clear it first */ + for (Bitu i=0;inext_seg,0,mem_size); + sSave(sPSP,next_seg,mem_size); + /* far call opcode */ + sSave(sPSP,far_call,0xea); +// sSave(sPSP,cmp_entry + /* Standard blocks,int 20 and int21 retf */ + sSave(sPSP,exit[0],0xcd); + sSave(sPSP,exit[1],0x20); + sSave(sPSP,service[0],0xcd); + sSave(sPSP,service[1],0x21); + sSave(sPSP,service[2],0xcb); + /* psp and psp-parent */ + sSave(sPSP,psp_parent,dos.psp); + sSave(sPSP,prev_psp,RealMake(dos.psp,0)); + /* terminate 22,break 23,crititcal error 24 address stored */ + SaveVectors(); + /* Memory size */ + sSave(sPSP,next_seg,seg+mem_size); + /* Process DTA */ + sSave(sPSP,dta,RealMake(seg,128)); + /* FCBs are filled with 0 */ + // .... + /* Init file pointer and max_files */ + sSave(sPSP,file_table,RealMake(seg,offsetof(sPSP,files[0]))); + sSave(sPSP,max_files,20); + for (i=0;i<20;i++) SetFileHandle(i,0xff); + + /* User Stack pointer */ + if (prevpsp.GetSegment()!=0) sSave(sPSP,stack,prevpsp.GetStack()); + + if (rootpsp==0) rootpsp = seg; +} + +Bit8u DOS_PSP::GetFileHandle(Bit16u index) +{ + if (index>=sGet(sPSP,max_files)) return 0xff; + PhysPt files=Real2Phys(sGet(sPSP,file_table)); + return mem_readb(files+index); +}; + +void DOS_PSP::SetFileHandle(Bit16u index, Bit8u handle) +{ + if (indexGetFileHandle(i); + SetFileHandle(i,handle); + } +}; + +void DOS_PSP::CloseFiles(void) +{ + for (Bit16u i=0;imax_files;i++) { - DOS_CloseFile(i); - } - DOS_FreeProcessMemory(dos.psp); - }; - dos.psp=psp->psp_parent; - PSP * oldpsp=(PSP *)HostMake(dos.psp,0); - /* Restore the DTA */ - dos.dta=psp->dta; - /* Restore the old CS:IP from int 22h */ - RealPt old22; - old22=RealGetVec(0x22); - SegSet16(cs,RealSeg(old22)); - reg_ip=RealOff(old22); - /* Restore the SS:SP to the previous one */ - SegSet16(ss,RealSeg(oldpsp->stack)); - reg_sp=RealOff(oldpsp->stack); - /* Restore interrupt 22,23,24 */ - RealSetVec(0x22,psp->int_22); - RealSetVec(0x23,psp->int_23); - RealSetVec(0x24,psp->int_24); + Bit16u mempsp = dos.psp; + DOS_PSP curpsp(dos.psp); + if (dos.psp==curpsp.GetParent()) return true; + + /* Free Files owned by process */ + if (!tsr) curpsp.CloseFiles(); + // restore vectors + curpsp.RestoreVectors(); + // Set parent psp + dos.psp = curpsp.GetParent(); + DOS_PSP parentpsp(curpsp.GetParent()); + /* Restore the DTA */ + parentpsp.SetDTA(curpsp.GetDTA()); + /* Restore the SS:SP to the previous one */ + SegSet16(ss,RealSeg(parentpsp.GetStack())); + reg_sp = RealOff(parentpsp.GetStack()); + /* Restore the old CS:IP from int 22h */ + RealPt old22 = curpsp.GetInt22(); + reg_ip = RealOff(old22); + SegSet16 (cs,RealSeg(old22)); + // Free memory owned by process + if (!tsr) DOS_FreeProcessMemory(mempsp); + return true; } @@ -97,14 +96,14 @@ bool DOS_Terminate(bool tsr) { static bool MakeEnv(char * name,Bit16u * segment) { /* If segment to copy environment is 0 copy the caller's environment */ - PSP * psp=(PSP *)HostMake(dos.psp,0); + DOS_PSP psp(dos.psp); Bit8u * envread,*envwrite; Bit16u envsize=1; bool parentenv=true; if (*segment==0) { - if (!psp->environment) parentenv=false; //environment seg=0 - envread=HostMake(psp->environment,0); + if (!psp.GetEnvironment()) parentenv=false; //environment seg=0 + envread=HostMake(psp.GetEnvironment(),0); } else { if (!*segment) parentenv=false; //environment seg=0 envread=HostMake(*segment,0); @@ -136,103 +135,51 @@ static bool MakeEnv(char * name,Bit16u * segment) { return DOS_Canonicalize(name,(char *)envwrite); }; -bool DOS_NewPSP(Bit16u pspseg) { - PSP * newpsp=(PSP *)HostMake(pspseg,0); - PSP * prevpsp=(PSP *)HostMake(dos.psp,0); - - memset((void *)newpsp,0,sizeof(PSP)); - newpsp->exit[0]=0xcd;newpsp->exit[1]=0x20; - newpsp->service[0]=0xcd;newpsp->service[0]=0x21;newpsp->service[0]=0xcb; - - newpsp->mem_size=prevpsp->mem_size; - newpsp->environment=0; - - newpsp->int_22=RealGetVec(0x22); - newpsp->int_23=RealGetVec(0x23); - newpsp->int_24=RealGetVec(0x24); - - newpsp->psp_parent=dos.psp; - newpsp->prev_psp=0xFFFFFFFF; - - Bit32u i; - Bit8u * prevfile=Real2Host(prevpsp->file_table); - for (i=0;i<20;i++) newpsp->files[i]=prevfile[i]; - - newpsp->max_files=20; - newpsp->file_table=RealMake(pspseg,offsetof(PSP,files)); - /* Save the old DTA in this psp */ - newpsp->dta=dos.dta; - /* Setup the DTA */ - dos.dta=RealMake(pspseg,0x80); +bool DOS_NewPSP(Bit16u segment, Bit16u size) +{ + DOS_PSP psp(segment); + psp.MakeNew(size); + psp.CopyFileTable(&DOS_PSP(psp.GetParent())); return true; }; static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { - PSP * psp=(PSP *)HostMake(pspseg,0); /* Fix the PSP index of this MCB */ MCB * pspmcb=(MCB *)HostMake(pspseg-1,0); pspmcb->psp_segment=pspseg; MCB * envmcb=(MCB *)HostMake(envseg-1,0); envmcb->psp_segment=pspseg; - memset((void *)psp,0,sizeof(PSP)); - Bit32u i; - - psp->exit[0]=0xcd;psp->exit[1]=0x20; - psp->mem_size=memsize+pspseg; - psp->environment=envseg; - - psp->int_22=RealGetVec(0x22); - psp->int_23=RealGetVec(0x23); - psp->int_24=RealGetVec(0x24); - - psp->service[0]=0xcd;psp->service[0]=0x21;psp->service[0]=0xcb; - - psp->psp_parent=dos.psp; - psp->prev_psp=RealMake(dos.psp,0); - - for (i=0;i<20;i++) psp->files[i]=0xff; - psp->files[STDIN]=DOS_FindDevice("CON"); - psp->files[STDOUT]=DOS_FindDevice("CON"); - psp->files[STDERR]=DOS_FindDevice("CON"); - psp->files[STDAUX]=DOS_FindDevice("CON"); - psp->files[STDNUL]=DOS_FindDevice("CON"); - psp->files[STDPRN]=DOS_FindDevice("CON"); - - psp->max_files=20; - psp->file_table=RealMake(pspseg,offsetof(PSP,files)); + DOS_PSP psp(pspseg); + psp.MakeNew(memsize+pspseg); + psp.SetEnvironment(envseg); + psp.SetFileHandle(STDIN ,DOS_FindDevice("CON")); + psp.SetFileHandle(STDOUT,DOS_FindDevice("CON")); + psp.SetFileHandle(STDERR,DOS_FindDevice("CON")); + psp.SetFileHandle(STDAUX,DOS_FindDevice("CON")); + psp.SetFileHandle(STDNUL,DOS_FindDevice("CON")); + psp.SetFileHandle(STDPRN,DOS_FindDevice("CON")); /* Save old DTA in psp */ - psp->dta=dos.dta; - + psp.SetDTA(dos.dta); /* Setup the DTA */ dos.dta=RealMake(pspseg,0x80); } -static void SetupCMDLine(Bit16u pspseg,ParamBlock * block) { - PSP * psp=(PSP *)HostMake(pspseg,0); - - if (block->exec.cmdtail) { - memcpy((void *)&psp->cmdtail,(void *)Real2Host(block->exec.cmdtail),128); - } else { - char temp[]=""; - psp->cmdtail.count=strlen(temp); - strcpy((char *)&psp->cmdtail.buffer,temp); - psp->cmdtail.buffer[0]=0x0d; - - } +static void SetupCMDLine(Bit16u pspseg,ParamBlock * block) +{ + DOS_PSP psp(pspseg); + // if cmdtail==0 it will inited as empty in SetCommandTail + psp.SetCommandTail(block->exec.cmdtail); } - - - static bool COM_Load(char * name,ParamBlock * block,Bit8u flag) { Bit16u fhandle; Bit16u size;Bit16u readsize; Bit16u envseg,comseg; Bit32u pos; - PSP * callpsp=(PSP *)HostMake(dos.psp,0); + DOS_PSP callpsp(dos.psp); if (!DOS_OpenFile(name,OPEN_READ,&fhandle)) return false; if (flag!=OVERLAY) { @@ -269,14 +216,20 @@ static bool COM_Load(char * name,ParamBlock * block,Bit8u flag) { SetupCMDLine(comseg,block); /* Setup termination Address */ RealSetVec(0x22,RealMakeSeg(cs,reg_ip)); + DOS_PSP compsp(comseg); + compsp.SetInt22(RealMakeSeg(cs,reg_ip)); /* Everything setup somewhat setup CS:IP and SS:SP */ /* First save the SS:SP of program that called execute */ - callpsp->stack=RealMakeSeg(ss,reg_sp); + callpsp.SetStack(RealMakeSeg(ss,reg_sp)); /* Clear out first Stack entry to point to int 20h at psp:0 */ real_writew(comseg,0xfffe,0); dos.psp=comseg; switch (flag) { case LOADNGO: + /* copy fcbs */ + compsp.SetFCB1(block->exec.fcb1); + compsp.SetFCB2(block->exec.fcb2); + /* setup reg */ SegSet16(cs,comseg); SegSet16(ss,comseg); SegSet16(ds,comseg); @@ -310,7 +263,7 @@ static bool EXE_Load(char * name,ParamBlock* _block,Bit8u flag) { ParamBlock block; memcpy(&block,_block,sizeof(ParamBlock)); - PSP * callpsp=(PSP *)HostMake(dos.psp,0); + DOS_PSP callpsp(dos.psp); if (!DOS_OpenFile(name,OPEN_READ,&fhandle)) return false; if (flag!=OVERLAY) { @@ -401,9 +354,11 @@ static bool EXE_Load(char * name,ParamBlock* _block,Bit8u flag) { /* Setup termination Address */ RealSetVec(0x22,RealMakeSeg(cs,reg_ip)); + DOS_PSP exepsp(pspseg); + exepsp.SetInt22(RealMakeSeg(cs,reg_ip)); /* Start up the actual EXE if we need to */ //TODO check for load and return - callpsp->stack=RealMakeSeg(ss,reg_sp); + callpsp.SetStack(RealMakeSeg(ss,reg_sp)); dos.psp=pspseg; SegSet16(cs,exeseg+header.initCS); SegSet16(ss,exeseg+header.initSS); diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index dab3a320..7a8c5a9d 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -269,9 +269,9 @@ bool DOS_CloseFile(Bit16u entry) { }; //TODO Figure this out with devices :) - PSP * psp=(PSP *)HostMake(dos.psp,0); - Bit8u * table=Real2Host(psp->file_table); - table[entry]=0xFF; + DOS_PSP psp(dos.psp); + psp.SetFileHandle(entry,0xff); + /* Devices won't allow themselves to be closed or killed */ if (Files[handle]->Close()) { delete Files[handle]; @@ -282,7 +282,7 @@ bool DOS_CloseFile(Bit16u entry) { bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { char fullname[DOS_PATHLENGTH];Bit8u drive; - PSP * psp=(PSP *)HostMake(dos.psp,0); + DOS_PSP psp(dos.psp); if (!DOS_MakeName(name,fullname,&drive)) return false; /* Check for a free file handle */ Bit8u handle=DOS_FILES;Bit8u i; @@ -297,21 +297,14 @@ bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { return false; } /* We have a position in the main table now find one in the psp table */ - Bit8u * table=Real2Host(psp->file_table); - *entry=0xff; - for (i=0;imax_files;i++) { - if (table[i]==0xFF) { - *entry=i; - break; - } - } + *entry = psp.FindFreeFileEntry(); if (*entry==0xff) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); return false; } bool foundit=Drives[drive]->FileCreate(&Files[handle],fullname,attributes); if (foundit) { - table[*entry]=handle; + psp.SetFileHandle(*entry,handle); return true; } else { return false; @@ -320,7 +313,7 @@ bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { /* First check for devices */ - PSP * psp=(PSP *)HostMake(dos.psp,0); + DOS_PSP psp(dos.psp); Bit8u handle=DOS_FindDevice((char *)name); bool device=false;char fullname[DOS_PATHLENGTH];Bit8u drive;Bit8u i; if (handle!=255) { @@ -341,14 +334,7 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { } } /* We have a position in the main table now find one in the psp table */ - Bit8u * table=Real2Host(psp->file_table); - *entry=0xff; - for (i=0;imax_files;i++) { - if (table[i]==0xFF) { - *entry=i; - break; - } - } + *entry = psp.FindFreeFileEntry(); if (*entry==0xff) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); return false; @@ -356,7 +342,7 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { bool exists=false; if (!device) exists=Drives[drive]->FileOpen(&Files[handle],fullname,flags); if (exists || device ) { - table[*entry]=handle; + psp.SetFileHandle(*entry,handle); return true; } else { DOS_SetError(DOSERR_FILE_NOT_FOUND); @@ -413,20 +399,13 @@ bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; - PSP * psp=(PSP *)HostMake(dos.psp,0); - Bit8u * table=Real2Host(psp->file_table); - *newentry=0xff; - for (Bit16u i=0;imax_files;i++) { - if (table[i]==0xFF) { - *newentry=i; - break; - } - } + DOS_PSP psp(dos.psp); + *newentry = psp.FindFreeFileEntry(); if (*newentry==0xff) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); return false; } - table[*newentry]=handle; + psp.SetFileHandle(*newentry,handle); return true; }; @@ -449,9 +428,8 @@ bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry) { DOS_CloseFile(newentry); return false; }; - PSP * psp=(PSP *)HostMake(dos.psp,0); - Bit8u * table=Real2Host(psp->file_table); - table[newentry]=(Bit8u)entry; + DOS_PSP psp(dos.psp); + psp.SetFileHandle(newentry,(Bit8u)entry); return true; }; @@ -522,7 +500,7 @@ Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u * Bit8u retwaarde=0; char naam[9]=" "; char ext[4]=" "; - if(parser & 1) { //ignore leading seperator + if((parser & 1) && *string) { //ignore leading seperator char sep[] = FCB_SEP; char a[2]; a[0]= *string;a[1]='\0'; diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 6b66f009..b1f7b490 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -60,7 +60,7 @@ static Bitu PROGRAMS_Handler(void) { /* First get the current psp */ PROGRAM_Info * info=new PROGRAM_Info; info->psp_seg=dos.psp; - MEM_BlockRead(PhysMake(dos.psp,0),&info->psp_copy,sizeof(PSP)); + MEM_BlockRead(PhysMake(dos.psp,0),&info->psp_copy,sizeof(sPSP)); /* Get the file name cmd_line 0 */ PhysPt envblock=PhysMake(info->psp_copy.environment,0); do {} while (mem_readw(envblock++)); diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 2020d9b5..62000851 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -149,29 +149,24 @@ void SHELL_Init() { env_mcb->size=4096/16; real_writed(env_seg+1,0,0); - PSP * psp=(PSP *)HostMake(psp_seg,0); - Bit32u i; - for (i=0;i<20;i++) psp->files[i]=0xff; - psp->files[STDIN]=DOS_FindDevice("CON"); - psp->files[STDOUT]=DOS_FindDevice("CON"); - psp->files[STDERR]=DOS_FindDevice("CON"); - psp->files[STDAUX]=DOS_FindDevice("CON"); - psp->files[STDNUL]=DOS_FindDevice("CON"); - psp->files[STDPRN]=DOS_FindDevice("CON"); - psp->max_files=20; - psp->file_table=RealMake(psp_seg,offsetof(PSP,files)); - /* Save old DTA in psp */ - psp->dta=dos.dta; + DOS_PSP psp(psp_seg); psp.MakeNew(env_mcb->size); + psp.SetFileHandle(STDIN ,DOS_FindDevice("CON")); + psp.SetFileHandle(STDOUT,DOS_FindDevice("CON")); + psp.SetFileHandle(STDERR,DOS_FindDevice("CON")); + psp.SetFileHandle(STDAUX,DOS_FindDevice("CON")); + psp.SetFileHandle(STDNUL,DOS_FindDevice("CON")); + psp.SetFileHandle(STDPRN,DOS_FindDevice("CON")); + psp.SetParent(psp_seg); /* Set the environment and clear it */ - psp->environment=env_seg+1; - mem_writew(Real2Phys(RealMake(env_seg+1,0)),0); + psp.SetEnvironment(env_seg+1); + mem_writew(Real2Phys(RealMake(env_seg+1,0)),0); /* Setup internal DOS Variables */ - dos.dta=RealMake(psp_seg,0x80); + dos.dta=psp.GetDTA(); dos.psp=psp_seg; PROGRAM_Info info; strcpy(info.full_name,"Z:\\COMMAND.COM"); info.psp_seg=psp_seg; - MEM_BlockRead(PhysMake(dos.psp,0),&info.psp_copy,sizeof(PSP)); + MEM_BlockRead(PhysMake(dos.psp,0),&info.psp_copy,sizeof(sPSP)); char line[256]; strcpy(line,"/INIT Z:\\AUTOEXEC.BAT"); info.cmd_line=line; From bbee123fcfb33e67027ca9325e64c4fd9879aac7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 8 Sep 2002 18:10:06 +0000 Subject: [PATCH 0188/4131] New mixer code to fix channels playing to fast Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@265 --- src/hardware/mixer.cpp | 135 +++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 72 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 8144e39d..623a7afd 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -35,35 +35,69 @@ #define MIXER_REMAIN ((1<MAX_AUDIO) ? (Bit16s)MAX_AUDIO : (SAMPhandler)(((Bit8u*)&mix_temp)+sizeof(mix_temp.TYPE[0]),sample_toread); \ + Bitu sample_index=(1 << MIXER_SHIFT) - chan->sample_left; \ + Bit32s newsample; \ + for (Bitu mix=0;mix> MIXER_SHIFT;sample_index+=chan->sample_add; \ + newsample=mix_buftemp[mix][0]+MAKE_##TYPE( LCHAN ); \ + mix_buftemp[mix][0]=MIXER_CLIP(newsample); \ + newsample=mix_buftemp[mix][1]+MAKE_##TYPE( RCHAN ); \ + mix_buftemp[mix][1]=MIXER_CLIP(newsample); \ + } \ + chan->remain.TYPE[LCHAN]=mix_temp.TYPE[sample_index>>MIXER_SHIFT][LCHAN]; \ + if (RCHAN) chan->remain.TYPE[RCHAN]=mix_temp.TYPE[sample_index>>MIXER_SHIFT][RCHAN];\ + chan->sample_left=sample_total-sample_index; \ + break; \ +} + +union Sample { + Bit16s m16[1]; + Bit16s s16[2]; + Bit8u m8[1]; + Bit8u s8[2]; + Bit32u full; +}; struct MIXER_Channel { Bit8u volume; Bit8u mode; - Bit32u freq; + Bitu freq; char * name; MIXER_MixHandler handler; - Bit32u sample_add; - Bit32u sample_remain; - Bit16s sample_data[2]; + Bitu sample_add; + Bitu sample_left; + Sample remain; bool playing; MIXER_Channel * next; }; + static MIXER_Channel * first_channel; static union { - Bit16s temp_m16[MIXER_BUFSIZE][1]; - Bit16s temp_s16[MIXER_BUFSIZE][2]; - Bit8u temp_m8[MIXER_BUFSIZE][1]; - Bit8u temp_s8[MIXER_BUFSIZE][2]; -}; + Bit16s m16[MIXER_BUFSIZE][1]; + Bit16s s16[MIXER_BUFSIZE][2]; + Bit8u m8[MIXER_BUFSIZE][1]; + Bit8u s8[MIXER_BUFSIZE][2]; + Bit32u full[MIXER_BUFSIZE]; +} mix_temp; + static Bit16s mix_bufout[MIXER_BUFSIZE][2]; static Bit16s mix_buftemp[MIXER_BUFSIZE][2]; static Bit32s mix_bufextra; -static Bit32u mix_writepos; -static Bit32u mix_readpos; -static Bit32u mix_ticks; -static Bit32u mix_add; -static Bit32u mix_remain; +static Bitu mix_writepos; +static Bitu mix_readpos; +static Bitu mix_ticks; +static Bitu mix_add; +static Bitu mix_remain; MIXER_Channel * MIXER_AddChannel(MIXER_MixHandler handler,Bit32u freq,char * name) { //TODO Find a free channel @@ -75,6 +109,7 @@ MIXER_Channel * MIXER_AddChannel(MIXER_MixHandler handler,Bit32u freq,char * nam chan->handler=handler; chan->name=name; chan->sample_add=(freq<sample_left=0; chan->next=first_channel; first_channel=chan; return chan; @@ -112,69 +147,25 @@ static void MIXER_MixData(Bit32u samples) { MIXER_Channel * chan=first_channel; while (chan) { if (chan->playing) { - Bit32u chan_samples=samples*chan->sample_add; - Bit32u real_samples=chan_samples>>MIXER_SHIFT; - if (chan_samples & MIXER_REMAIN) real_samples++; - (chan->handler)((Bit8u*)&temp_m8,real_samples); + /* This should always allocate 1 extra sample */ + Bitu sample_total=(samples*chan->sample_add)-chan->sample_left; + Bitu sample_toread=sample_total >> MIXER_SHIFT; + if (sample_total & MIXER_REMAIN) sample_toread++; + sample_total=(sample_toread+1)<remain.full; switch (chan->mode) { case MIXER_8MONO: - /* Mix a 8 bit mono stream into the final 16 bit stereo output stream */ - { - /* Mix the data with output buffer */ - Bit32s newsample;Bit32u sample_read=0;Bit32u sample_add=chan->sample_add; - for (Bit32u mix=0;mix> MIXER_SHIFT; - sample_read+=sample_add; - newsample=mix_buftemp[mix][0]+((Bit8s)(temp_m8[pos][0]^0x80) << 8); - if (newsample>MAX_AUDIO) mix_buftemp[mix][0]=MAX_AUDIO; - else if (newsampleMAX_AUDIO) mix_buftemp[mix][1]=MAX_AUDIO; - else if (newsamplesample_add; - for (Bit32u mix=0;mix> MIXER_SHIFT; - sample_read+=sample_add; - newsample=mix_buftemp[mix][0]+temp_m16[pos][0]; - if (newsample>MAX_AUDIO) mix_buftemp[mix][0]=MAX_AUDIO; - else if (newsampleMAX_AUDIO) mix_buftemp[mix][1]=MAX_AUDIO; - else if (newsamplesample_add; - for (Bit32u mix=0;mix> MIXER_SHIFT; - sample_read+=sample_add; - newsample=mix_buftemp[mix][0]+temp_s16[pos][0]; - if (newsample>MAX_AUDIO) mix_buftemp[mix][0]=MAX_AUDIO; - else if (newsampleMAX_AUDIO) mix_buftemp[mix][1]=MAX_AUDIO; - else if (newsamplemode); + break; } } chan=chan->next; @@ -210,7 +201,7 @@ static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { /* Copy data from buf_out to the stream */ Bit32u remain=MIXER_BUFSIZE-mix_readpos; - if (remain>=len/MIXER_SSIZE) { + if (remain>=(Bit32u)len/MIXER_SSIZE) { memcpy((void *)stream,(void *)&mix_bufout[mix_readpos][0],len); } else { memcpy((void *)stream,(void *)&mix_bufout[mix_readpos][0],remain*MIXER_SSIZE); From 115a948a92291fb4874e14941c13fbbf78d2c162 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 8 Sep 2002 18:32:57 +0000 Subject: [PATCH 0189/4131] Don't reset frequency index on new frequency, clears up pcspeaker music. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@266 --- src/hardware/pcspeaker.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index c8aabb11..a78ab0ba 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -49,7 +49,6 @@ static Speaker spkr; void PCSPEAKER_SetFreq(Bit32u freq) { spkr.freq_add=(Bit32u)(FREQ_MAX/((float)SPKR_RATE/(float)freq)); - spkr.freq_pos=0; } void PCSPEAKER_Enable(bool enable) { From 0c603eab1e00c1fc145815029d25586c8ec5b41b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 9 Sep 2002 07:16:24 +0000 Subject: [PATCH 0190/4131] added ctrl f9 to the readme Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@267 --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index dc309118..10156103 100644 --- a/README +++ b/README @@ -46,6 +46,7 @@ Special Keys: ============= ALT-ENTER Go full screen and back. +CTRL-F9 Go full screen and back. CTRL-F10 Capture/Release the mouse. CTRL-F11 Slowdown emulation. CTRL-F12 Speedup emulation. From bced0324fed55380acfb1afb6819a28cd6956f46 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 10 Sep 2002 11:45:07 +0000 Subject: [PATCH 0191/4131] changed commandline handling for commands run in dosbox Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@268 --- src/dos/dos_programs.cpp | 16 +++++++++------- src/shell/shell_misc.cpp | 18 ++++++++++++------ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 5a2857d0..17c7878f 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -42,9 +42,10 @@ public: return; } - char drive; drive=toupper(*prog_info->cmd_line); + char* line=trim(prog_info->cmd_line); + char drive; drive=toupper(*line); - char * dir=strchr(prog_info->cmd_line,' '); if (dir) { + char * dir=strchr(line,' '); if (dir) { if (!*dir) dir=0; else dir=trim(dir); } @@ -179,20 +180,21 @@ void UPCASE::Run(void) { WriteOut("Otherwise you might horribly screw up your filesystem.\n"); return; } - if (stat(prog_info->cmd_line,&info)) { - WriteOut("%s doesn't exist\n",prog_info->cmd_line); + char* line=trim(prog_info->cmd_line); + if (stat(line,&info)) { + WriteOut("%s doesn't exist\n",line); return; } if(!S_ISDIR(info.st_mode)) { - WriteOut("%s isn't a directory\n",prog_info->cmd_line); + WriteOut("%s isn't a directory\n",line); return; } WriteOut("Converting the wrong directories can be very harmfull, please be carefull.\n"); - WriteOut("Are you really really sure you want to convert %s to upcase?Y/N\n",prog_info->cmd_line); + WriteOut("Are you really really sure you want to convert %s to upcase?Y/N\n",line); Bit8u key;Bit16u n=1; DOS_ReadFile(STDIN,&key,&n); if (toupper(key)=='Y') { - upcasedir(prog_info->cmd_line); + upcasedir(line); } else { WriteOut("Okay better not do it.\n"); } diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 7e63364b..e939b81e 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -126,7 +126,13 @@ void DOS_Shell::InputCommand(char * line) { void DOS_Shell::Execute(char * name,char * args) { char * fullname; - + char line[255]; + if(strlen(args)!=0){ + line[0]=' ';line[1]=0; + strcat(line,args); + }else{ + line[0]=0; + }; /* check for a drive change */ if ((strcmp(name + 1, ":") == 0) && isalpha(*name)) { @@ -143,7 +149,7 @@ void DOS_Shell::Execute(char * name,char * args) { } if (strcasecmp(strrchr(fullname, '.'), ".bat") == 0) { /* Run the .bat file */ - bf=new BatchFile(this,fullname,args); + bf=new BatchFile(this,fullname,line); } else { /* Run the .exe or .com file from the shell */ /* Allocate some stack space for tables in physical memory */ @@ -155,10 +161,10 @@ void DOS_Shell::Execute(char * name,char * args) { MEM_BlockWrite(Real2Phys(file_name),fullname,strlen(fullname)+1); /* Fill the command line */ CommandTail cmd; - if (strlen(args)>126) args[126]=0; - cmd.count=strlen(args); - memcpy(cmd.buffer,args,strlen(args)); - cmd.buffer[strlen(args)]=0xd; + if (strlen(line)>126) line[126]=0; + cmd.count=strlen(line); + memcpy(cmd.buffer,line,strlen(line)); + cmd.buffer[strlen(line)]=0xd; MEM_BlockWrite(PhysMake(prog_info->psp_seg,128),&cmd,128); block.InitExec(RealMake(prog_info->psp_seg,128)); From 5bfa4cb74c98e3a5085838b04deb1e70817e6ceb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 14 Sep 2002 20:51:02 +0000 Subject: [PATCH 0192/4131] Fix 16bit stereo mixing and add 8bit stereo mixing Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@269 --- src/hardware/mixer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 623a7afd..e93eeb76 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -157,11 +157,14 @@ static void MIXER_MixData(Bit32u samples) { case MIXER_8MONO: MIX_NORMAL(m8,0,0); break; + case MIXER_8STEREO: + MIX_NORMAL(m8,0,1); + break; case MIXER_16MONO: MIX_NORMAL(m16,0,0); break; case MIXER_16STEREO: - MIX_NORMAL(s16,0,0); + MIX_NORMAL(s16,0,1); break; default: E_Exit("MIXER:Illegal sound mode %2X",chan->mode); From 3c24c0a2fba23b99e6a85c2515a2e8cdf9b1f60b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 15 Sep 2002 11:46:06 +0000 Subject: [PATCH 0193/4131] Add PIT_TICK_RATE define Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@270 --- include/timer.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/timer.h b/include/timer.h index 95faaa07..58ffdc49 100644 --- a/include/timer.h +++ b/include/timer.h @@ -22,6 +22,9 @@ #include extern Bit32u LastTicks; + +#define PIT_TICK_RATE 1193182 + #define GetTicks() SDL_GetTicks() extern bool TimerAgain; @@ -50,6 +53,5 @@ void TIMER_CheckPIT(void); /* This will add ms ticks to support the timer handlers */ void TIMER_AddTicks(Bit32u ticks); - #endif From 16f6308ef7445c4318d279c76a9f61a1878722a6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 16 Sep 2002 07:26:37 +0000 Subject: [PATCH 0194/4131] Filename shortened to 8 chars and extensions to 3 in dos_makename Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@271 --- src/dos/dos_files.cpp | 45 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 7a8c5a9d..e159aa34 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -45,29 +45,27 @@ void DOS_SetDefaultDrive(Bit8u drive) { } bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { -//TODO Hope this is ok :) + char tempdir[DOS_PATHLENGTH]; char upname[DOS_PATHLENGTH]; - Bit32u r=0;Bit32u w=0;Bit32u namestart=0; - bool hasdrive=false; + Bitu r,w; *drive=CurrentDrive; - char tempdir[128]; -//TODO Maybe check for illegal characters + /* First get the drive */ + if (name[1]==':') { + *drive=(name[0] | 0x20)-'a'; + if (*drive='a') && (c<='z')) {upname[w++]=c-32;continue;} if ((c>='A') && (c<='Z')) {upname[w++]=c;continue;} if ((c>='0') && (c<='9')) {upname[w++]=c;continue;} switch (c) { - case ':': - if (hasdrive) { DOS_SetError(DOSERR_PATH_NOT_FOUND);return false; } - else hasdrive=true; - if ((upname[0]>='A') && (upname[0]<='Z')) { - *drive=upname[0]-'A'; - w=0; - } else { - DOS_SetError(DOSERR_PATH_NOT_FOUND);return false; - } - break; case '/': upname[w++]='\\'; break; @@ -83,15 +81,9 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { break; } } + if (r>=DOS_PATHLENGTH) { DOS_SetError(DOSERR_PATH_NOT_FOUND);return false; } upname[w]=0; - /* This should get us an upcase filename and no incorrect chars */ /* Now parse the new file name to make the final filename */ - if ((*drive>=26)) { - DOS_SetError(DOSERR_INVALID_DRIVE);return false; - }; - if (!Drives[*drive]) { - DOS_SetError(DOSERR_INVALID_DRIVE);return false; - }; if (upname[0]!='\\') strcpy(fullname,Drives[*drive]->curdir); else fullname[0]=0; Bit32u lastdir=0;Bit32u t=0; @@ -126,8 +118,13 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { lastdir=strlen(fullname); //TODO Maybe another check for correct type because of .... stuff if (lastdir!=0) strcat(fullname,"\\"); + char * ext=strchr(tempdir,'.'); + if (ext) { + ext[4]=0; + Bitu blah=strlen(tempdir); + if (strlen(tempdir)>12) memmove(tempdir+8,ext,5); + } else tempdir[8]=0; strcat(fullname,tempdir); - tempdir[0]=0; w=0;r++; continue; @@ -313,6 +310,8 @@ bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { /* First check for devices */ + if (flags>2) LOG_DEBUG("Special file open command %X file %s",flags,name); + flags&=3; DOS_PSP psp(dos.psp); Bit8u handle=DOS_FindDevice((char *)name); bool device=false;char fullname[DOS_PATHLENGTH];Bit8u drive;Bit8u i; From af67029cdca902234083e638e190b76cc121283f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 16 Sep 2002 13:10:48 +0000 Subject: [PATCH 0195/4131] New execute/terminate that saves registers and segments. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@272 --- src/dos/dos_execute.cpp | 402 ++++++++++++++++------------------------ 1 file changed, 163 insertions(+), 239 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 4ee0ec9c..375eb516 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -21,12 +21,10 @@ #include "mem.h" #include "dos_inc.h" #include "cpu.h" -#if defined (_MSC_VER) -#pragma pack(1) -#endif +#include "callback.h" +#pragma pack(1) struct EXE_Header { - Bit16u signature; /* EXE Signature MZ or ZM */ Bit16u extrabytes; /* Bytes on the last page */ Bit16u pages; /* Pages in file */ @@ -41,13 +39,8 @@ struct EXE_Header { Bit16u initCS; Bit16u reloctable; Bit16u overlay; -} -#if defined (_MSC_VER) -; +} GCC_ATTRIBUTE(packed); #pragma pack() -#else -__attribute__ ((packed)); -#endif #define MAGIC1 0x5a4d #define MAGIC2 0x4d5a @@ -63,31 +56,64 @@ __attribute__ ((packed)); #define OVERLAY 3 + +static void SaveRegisters(void) { + reg_sp-=20; + mem_writew(SegPhys(ss)+reg_sp+ 0,reg_ax); + mem_writew(SegPhys(ss)+reg_sp+ 2,reg_cx); + mem_writew(SegPhys(ss)+reg_sp+ 4,reg_dx); + mem_writew(SegPhys(ss)+reg_sp+ 6,reg_bx); + mem_writew(SegPhys(ss)+reg_sp+ 8,reg_si); + mem_writew(SegPhys(ss)+reg_sp+10,reg_di); + mem_writew(SegPhys(ss)+reg_sp+12,reg_bp); + mem_writew(SegPhys(ss)+reg_sp+14,SegValue(ds)); + mem_writew(SegPhys(ss)+reg_sp+16,SegValue(es)); +} + +static void RestoreRegisters(void) { + reg_ax=mem_readw(SegPhys(ss)+reg_sp+ 0); + reg_cx=mem_readw(SegPhys(ss)+reg_sp+ 2); + reg_dx=mem_readw(SegPhys(ss)+reg_sp+ 4); + reg_bx=mem_readw(SegPhys(ss)+reg_sp+ 6); + reg_si=mem_readw(SegPhys(ss)+reg_sp+ 8); + reg_di=mem_readw(SegPhys(ss)+reg_sp+10); + reg_bp=mem_readw(SegPhys(ss)+reg_sp+12); + SegSet16(ds,mem_readw(SegPhys(ss)+reg_sp+14)); + SegSet16(es,mem_readw(SegPhys(ss)+reg_sp+16)); + reg_sp+=20; +} + + bool DOS_Terminate(bool tsr) { + dos.return_code=reg_al; + dos.return_mode=RETURN_EXIT; + Bit16u mempsp = dos.psp; DOS_PSP curpsp(dos.psp); if (dos.psp==curpsp.GetParent()) return true; /* Free Files owned by process */ if (!tsr) curpsp.CloseFiles(); - // restore vectors + /* Get the termination address */ + RealPt old22 = RealGetVec(0x22); + /* Restore vector 22,23,24 */ curpsp.RestoreVectors(); - // Set parent psp + /* Set the parent PSP */ dos.psp = curpsp.GetParent(); DOS_PSP parentpsp(curpsp.GetParent()); - /* Restore the DTA */ - parentpsp.SetDTA(curpsp.GetDTA()); + /* Restore the DTA of the parent psp */ + dos.dta = parentpsp.GetDTA(); /* Restore the SS:SP to the previous one */ SegSet16(ss,RealSeg(parentpsp.GetStack())); reg_sp = RealOff(parentpsp.GetStack()); - /* Restore the old CS:IP from int 22h */ - RealPt old22 = curpsp.GetInt22(); - reg_ip = RealOff(old22); - SegSet16 (cs,RealSeg(old22)); + /* Restore the stored registers */ + RestoreRegisters(); + /* Set the CS:IP stored in int 0x22 back on the stack */ + mem_writew(SegPhys(ss)+reg_sp+0,RealOff(old22)); + mem_writew(SegPhys(ss)+reg_sp+2,RealSeg(old22)); // Free memory owned by process if (!tsr) DOS_FreeProcessMemory(mempsp); - return true; } @@ -109,7 +135,6 @@ static bool MakeEnv(char * name,Bit16u * segment) { envread=HostMake(*segment,0); } - //TODO Make a good DOS first psp if (parentenv) { for (envsize=0; ;envsize++) { if (envsize>=MAXENV - ENV_KEEPFREE) { @@ -131,7 +156,7 @@ static bool MakeEnv(char * name,Bit16u * segment) { } *((Bit16u *) envwrite)=1; envwrite+=2; - //TODO put the filename here + return DOS_Canonicalize(name,(char *)envwrite); }; @@ -145,14 +170,14 @@ bool DOS_NewPSP(Bit16u segment, Bit16u size) static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { - /* Fix the PSP index of this MCB */ + /* Fix the PSP for psp and environment MCB's */ MCB * pspmcb=(MCB *)HostMake(pspseg-1,0); pspmcb->psp_segment=pspseg; MCB * envmcb=(MCB *)HostMake(envseg-1,0); envmcb->psp_segment=pspseg; DOS_PSP psp(pspseg); - psp.MakeNew(memsize+pspseg); + psp.MakeNew(memsize); psp.SetEnvironment(envseg); psp.SetFileHandle(STDIN ,DOS_FindDevice("CON")); psp.SetFileHandle(STDOUT,DOS_FindDevice("CON")); @@ -173,233 +198,132 @@ static void SetupCMDLine(Bit16u pspseg,ParamBlock * block) psp.SetCommandTail(block->exec.cmdtail); } -static bool COM_Load(char * name,ParamBlock * block,Bit8u flag) { - Bit16u fhandle; - Bit16u size;Bit16u readsize; - Bit16u envseg,comseg; - Bit32u pos; - - DOS_PSP callpsp(dos.psp); - - if (!DOS_OpenFile(name,OPEN_READ,&fhandle)) return false; - if (flag!=OVERLAY) { - /* Allocate a new Environment */ - envseg=block->exec.envseg; - if (!MakeEnv(name,&envseg)) return false; - /* Allocate max memory for COM file and PSP */ - size=0xffff; - DOS_AllocateMemory(&comseg,&size); - //TODO Errors check for minimun of 64kb in pages - if (Bit32u(size <<4)<0x1000) { - DOS_SetError(DOSERR_INSUFFICIENT_MEMORY); - DOS_FreeMemory(envseg); - return false; - } - DOS_AllocateMemory(&comseg,&size); - } else { - comseg=block->overlay.loadseg; - } - /* Memory allocated now load the program */ - /* Now copy the File into allocated memory */ - pos=0; - DOS_SeekFile(fhandle,&pos,0); - readsize=0xffff-256; - if (flag==OVERLAY) { - DOS_ReadFile(fhandle,HostMake(comseg,0),&readsize); - } else { - DOS_ReadFile(fhandle,HostMake(comseg,256),&readsize); - } - DOS_CloseFile(fhandle); - if (flag==OVERLAY) /* Everything what should be done for Overlays */ - return true; - SetupPSP(comseg,size,envseg); - SetupCMDLine(comseg,block); - /* Setup termination Address */ - RealSetVec(0x22,RealMakeSeg(cs,reg_ip)); - DOS_PSP compsp(comseg); - compsp.SetInt22(RealMakeSeg(cs,reg_ip)); - /* Everything setup somewhat setup CS:IP and SS:SP */ - /* First save the SS:SP of program that called execute */ - callpsp.SetStack(RealMakeSeg(ss,reg_sp)); - /* Clear out first Stack entry to point to int 20h at psp:0 */ - real_writew(comseg,0xfffe,0); - dos.psp=comseg; - switch (flag) { - case LOADNGO: - /* copy fcbs */ - compsp.SetFCB1(block->exec.fcb1); - compsp.SetFCB2(block->exec.fcb2); - /* setup reg */ - SegSet16(cs,comseg); - SegSet16(ss,comseg); - SegSet16(ds,comseg); - SegSet16(es,comseg); - flags.intf=true; - reg_ip=0x100; - reg_sp=0xFFFE; - reg_ax=0; - reg_bx=reg_cx=reg_dx=reg_si=reg_di=reg_bp=0; - return true; - case LOAD: - block->exec.initsssp=RealMake(comseg,0xfffe); - block->exec.initcsip=RealMake(comseg,0x100); - return true; - } - return false; - -} - - -static bool EXE_Load(char * name,ParamBlock* _block,Bit8u flag) { - - EXE_Header header; - Bit16u fhandle;Bit32u i; - Bit16u size,minsize,maxsize,freesize;Bit16u readsize; - Bit16u envseg,pspseg,exeseg; - Bit32u imagesize,headersize; - - // During loading process, th param-block-mem might be overwritten (HostPt!) and - // therefore change the relocation address, so save these values. - ParamBlock block; - memcpy(&block,_block,sizeof(ParamBlock)); - - DOS_PSP callpsp(dos.psp); - - if (!DOS_OpenFile(name,OPEN_READ,&fhandle)) return false; - if (flag!=OVERLAY) { - /* Allocate a new Environment */ - envseg=block.exec.envseg; - if (!MakeEnv(name,&envseg)) return false; - }; - - /* First Read the EXE Header */ - readsize=sizeof(EXE_Header); - DOS_ReadFile(fhandle,(Bit8u*)&header,&readsize); - /* Calculate the size of the image to load */ - headersize=header.headersize*16; - imagesize=header.pages*512-headersize; - if (flag!=OVERLAY) { - minsize=long2para(imagesize+(header.minmemory<<4)+256); - if (header.maxmemory!=0) maxsize=long2para(imagesize+(header.maxmemory<<4)+256); - else maxsize=0xffff; - freesize=0xffff; - /* Check for enough free memory */ - DOS_AllocateMemory(&exeseg,&freesize); - if (minsize>freesize) { - DOS_SetError(DOSERR_INSUFFICIENT_MEMORY); - DOS_FreeMemory(envseg); - return false; - } - if (maxsize>freesize) { - size=freesize; - } else size=maxsize; - if ((header.minmemory|header.maxmemory)==0) { - size=freesize; - E_Exit("Special case exe header max and min=0"); - } - if (!DOS_AllocateMemory(&pspseg,&size)) { - DOS_SetError(DOSERR_INSUFFICIENT_MEMORY); - DOS_FreeMemory(envseg); - return false; - } - SetupPSP(pspseg,size,envseg); - SetupCMDLine(pspseg,&block); - exeseg=pspseg+16; - } else { - /* For OVERLAY */ - exeseg=block.overlay.loadseg; - } - /* Load the image in 32k blocks */ - DOS_SeekFile(fhandle,&headersize,0); - Bit8u * imageoff=HostMake(exeseg,0); -//TODO File size checking and remove size - // Remove psp size -// imagesize=256; - // Maybe remove final page and add last bytes on page - if (header.extrabytes) { - imagesize-=512; - imagesize+=header.extrabytes; - }; - while (imagesize>0x7FFF) { - readsize=0x8000; - DOS_ReadFile(fhandle,imageoff,&readsize); - if (readsize!=0x8000) { - E_Exit("Illegal header"); - } - imageoff+=0x8000; - imagesize-=0x8000; - } - if (imagesize>0) { - readsize=(Bit16u) imagesize; - DOS_ReadFile(fhandle,imageoff,&readsize); - } - headersize=header.reloctable; - DOS_SeekFile(fhandle,&headersize,0); - RealPt reloc; - for (i=0;iexec.envseg; + if (!MakeEnv(name,&envseg)) { + DOS_CloseFile(fhandle); + return false; + } + /* Get Memory */ + Bit16u minsize,maxsize;Bit16u maxfree=0xffff;DOS_AllocateMemory(&pspseg,&maxfree); + if (iscom) { + minsize=0x1000;maxsize=0xffff; + } else { /* Exe size calculated from header */ + minsize=long2para(imagesize+(head.minmemory<<4)+256); + if (head.maxmemory!=0) maxsize=long2para(imagesize+(head.maxmemory<<4)+256); + else maxsize=0xffff; + } + if (maxfreeoverlay.loadseg,0; + /* Load the executable */ + loadaddress=HostMake(loadseg,0); + if (iscom) { /* COM Load 64k - 256 bytes max */ + pos=0;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET); + readsize=0xffff-256; + DOS_ReadFile(fhandle,loadaddress,&readsize); + } else { /* EXE Load in 32kb blocks and then relocate */ + pos=headersize;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET); + while (imagesize>0x7FFF) { + readsize=0x8000;DOS_ReadFile(fhandle,loadaddress,&readsize); + if (readsize!=0x8000) E_Exit("Illegal header"); + loadaddress+=0x8000;imagesize-=0x8000; + } + if (imagesize>0) { + readsize=(Bit16u)imagesize;DOS_ReadFile(fhandle,loadaddress,&readsize); + if (readsize!=imagesize) E_Exit("Illegal header"); + } + /* Relocate the exe image */ + Bit16u relocate; + if (flags==OVERLAY) relocate=block->overlay.relocation; + else relocate=loadseg; + pos=head.reloctable;DOS_SeekFile(fhandle,&pos,0); + for (i=0;iexec.fcb1); + newpsp.SetFCB2(block->exec.fcb2); + /* Set the stack for new program */ + SegSet16(ss,RealSeg(sssp));reg_sp=RealOff(sssp); + /* Add some flags and CS:IP on the stack for the IRET */ + reg_sp-=6; + mem_writew(SegPhys(ss)+reg_sp+0,RealOff(csip)); + mem_writew(SegPhys(ss)+reg_sp+2,RealSeg(csip)); + mem_writew(SegPhys(ss)+reg_sp+4,0x200); + /* Setup the rest of the registers */ + reg_ax=0; + reg_cx=reg_dx=reg_bx=reg_si=reg_di=reg_bp=0; + SegSet16(ds,pspseg);SegSet16(es,pspseg); + return true; + } + return false; } + From ec35911b9cc194c1b130867f7911336f0a7cdc7d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 16 Sep 2002 13:11:37 +0000 Subject: [PATCH 0196/4131] New execute and saving DTA in psp when settings it. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@273 --- src/dos/dos.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index bee05a3d..0a7b8c18 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -284,9 +284,12 @@ static Bitu DOS_21Handler(void) { reg_al=DOS_GetDefaultDrive(); break; case 0x1a: /* Set Disk Transfer Area Address */ - dos.dta=RealMakeSeg(ds,reg_dx); + { + dos.dta=RealMakeSeg(ds,reg_dx); + DOS_PSP psp(dos.psp); + psp.SetDTA(dos.dta); + } break; - case 0x1c: /* Get allocation info for specific drive */ LOG_DEBUG("DOS: Allocation Info call not supported correctly"); SegSet16(ds,0xf000); @@ -535,7 +538,6 @@ static Bitu DOS_21Handler(void) { break; } case 0x43: /* Get/Set file attributes */ -//TODO FIX THIS HACK MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); switch (reg_al) case 0x00: /* Get */ @@ -580,7 +582,6 @@ static Bitu DOS_21Handler(void) { } break; case 0x47: /* CWD Get current directory */ - //TODO Memory if (DOS_GetCurrentDir(reg_dl,name1)) { MEM_BlockWrite(SegPhys(ds)+reg_si,name1,strlen(name1)+1); reg_ax=0x0100; @@ -626,9 +627,7 @@ static Bitu DOS_21Handler(void) { case 0x4b: /* EXEC Load and/or execute program */ { MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); - if (DOS_Execute(name1,(ParamBlock *)Phys2Host(SegPhys(es)+reg_bx),reg_al)) { - CALLBACK_SCF(false); - } else { + if (!DOS_Execute(name1,(ParamBlock *)Phys2Host(SegPhys(es)+reg_bx),reg_al)) { reg_ax=dos.errorcode; CALLBACK_SCF(true); } @@ -638,9 +637,7 @@ static Bitu DOS_21Handler(void) { case 0x4c: /* EXIT Terminate with return code */ { if (DOS_Terminate(false)) { - dos.return_code=reg_al; - dos.return_mode=RETURN_EXIT; - CALLBACK_SCF(false); + /* This can't ever return false normally */ } else { reg_ax=dos.errorcode; CALLBACK_SCF(true); From 9376ece0e6436994b67208ad7cf2afda3c1bd244 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 16 Sep 2002 13:12:16 +0000 Subject: [PATCH 0197/4131] correct saving of next paragraph in new_psp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@274 --- src/dos/dos_classes.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index a63e5302..2e86014c 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -194,13 +194,13 @@ void DOS_PSP::NewPt(Bit16u segment) void DOS_PSP::MakeNew(Bit16u mem_size) { - /* get previous */ + /* get previous */ DOS_PSP prevpsp(dos.psp); /* Clear it first */ for (Bitu i=0;inext_seg,0,mem_size); - sSave(sPSP,next_seg,mem_size); + sSave(sPSP,next_seg,seg+mem_size); /* far call opcode */ sSave(sPSP,far_call,0xea); // sSave(sPSP,cmp_entry From 7c7e296cb805160fd1faaa497a5efae1e78b09f4 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 16 Sep 2002 13:13:10 +0000 Subject: [PATCH 0198/4131] INT 0x2A vector wasn't set correctly Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@275 --- src/dos/dos_misc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index cce5adad..9072d337 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -64,6 +64,6 @@ void DOS_SetupMisc(void) { /* Setup the dos network interrupt */ call_int2a=CALLBACK_Allocate(); CALLBACK_Setup(call_int2a,&INT2A_Handler,CB_IRET); - RealSetVec(0x2A<<2,CALLBACK_RealPointer(call_int2a)); + RealSetVec(0x2A,CALLBACK_RealPointer(call_int2a)); }; From 3edbb75c02e070c1e9f90b7b413241a6eec6163c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 16 Sep 2002 13:14:13 +0000 Subject: [PATCH 0199/4131] Back to old timer code, removed timeragain variable Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@276 --- src/hardware/timer.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 560be4ee..b245be20 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -58,7 +58,6 @@ static struct TimerBlock { Bitu ticks; } timer; -#define PIT_TICK_RATE 1193182 #define PIT_SHIFT 9 #define MAX_PASSED ((PIT_TICK_RATE/4) << PIT_SHIFT) /* Alow 1/4 second of timer build up */ @@ -114,7 +113,7 @@ static void write_latch(Bit32u port,Bit8u val) { LOG_DEBUG("PIT 0 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode); break; case 0x02: /* Timer hooked to PC-Speaker */ - PCSPEAKER_SetFreq(PIT_TICK_RATE/p->cntr); + PCSPEAKER_SetCounter(p->cntr,p->mode); break; default: LOG_ERROR("PIT:Illegal timer selected for writing"); @@ -285,8 +284,6 @@ void TIMER_AddTicks(Bit32u ticks) { void TIMER_CheckPIT(void) { if (timer_buildup>timer_ticks) { timer_buildup-=timer_ticks; - if (timer_buildup>timer_ticks) TimerAgain=true; - else TimerAgain=false; /* Calculate amount of times the time index was requested */ timer.req[timer.req_index]=timer.req_count; timer.req_index++;if (timer.req_index>=TIMER_AVERAGE) timer.req_index=0; @@ -296,7 +293,7 @@ void TIMER_CheckPIT(void) { timer.req_average=1/(total/TIMER_AVERAGE); PIC_ActivateIRQ(0); return; - } else TimerAgain=false; + } } From b93a294dfa5630c867061a0657e5d0d991719d29 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 16 Sep 2002 13:14:42 +0000 Subject: [PATCH 0200/4131] RealSound support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@277 --- src/hardware/pcspeaker.cpp | 63 +++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index a78ab0ba..b9c2e102 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -16,16 +16,17 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include -#include #include +#include "dosbox.h" +#include "mixer.h" +#include "timer.h" #ifndef PI #define PI 3.14159265358979323846 #endif +#define SPKR_BUF 4096 #define SPKR_RATE 22050 #define SPKR_VOLUME 5000 @@ -41,14 +42,26 @@ struct Speaker { Bit16s volume; MIXER_Channel * chan; bool enabled; + bool realsound; + Bit16u buffer[SPKR_BUF]; + Bitu buf_pos; }; static Speaker spkr; -void PCSPEAKER_SetFreq(Bit32u freq) { - spkr.freq_add=(Bit32u)(FREQ_MAX/((float)SPKR_RATE/(float)freq)); +void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode) { + switch (mode) { + case 0: + if (cntr>72) cntr=72; + spkr.realsound=true; + spkr.buffer[spkr.buf_pos++]=(cntr-36)*600; + break; + case 3: + spkr.freq_add=(Bit32u)(FREQ_MAX/((float)SPKR_RATE/(PIT_TICK_RATE/(float)cntr))); + break; + } } void PCSPEAKER_Enable(bool enable) { @@ -57,25 +70,29 @@ void PCSPEAKER_Enable(bool enable) { } static void PCSPEAKER_CallBack(Bit8u * stream,Bit32u len) { - /* Generate the speaker wave, TODO Improve :) */ - for (Bit32u c=0;c=FREQ_MAX) spkr.freq_pos-=FREQ_MAX; - if (spkr.freq_pos>=FREQ_HALF) { - *(Bit16s*)(stream)=spkr.volume; - } else { - *(Bit16s*)(stream)=-spkr.volume; + if (spkr.realsound) { + /* Generate the "RealSound" */ + Bitu buf_add=(spkr.buf_pos<<16)/len; + Bitu buf_pos=0; + spkr.buf_pos=0;spkr.realsound=0; + while (len-->0) { + *(Bit16s*)(stream)=spkr.buffer[buf_pos >> 16]; + buf_pos+=buf_add; + stream+=2; + } + } else { + /* Generate a square wave */ + while (len-->0) { + spkr.freq_pos+=spkr.freq_add; + if (spkr.freq_pos>=FREQ_MAX) spkr.freq_pos-=FREQ_MAX; + if (spkr.freq_pos>=FREQ_HALF) { + *(Bit16s*)(stream)=spkr.volume; + } else { + *(Bit16s*)(stream)=-spkr.volume; + } + stream+=2; } -/* - if (spkr.freq_pos>=FREQ_HALF) { - spkr.freq_pos-=FREQ_HALF; - spkr.volume=-spkr.volume; - }; - *(Bit16s*)(stream)=spkr.volume; -*/ - stream+=2; } - } void PCSPEAKER_Init(void) { @@ -84,4 +101,6 @@ void PCSPEAKER_Init(void) { MIXER_SetMode(spkr.chan,MIXER_16MONO); spkr.volume=SPKR_VOLUME; spkr.enabled=false; + spkr.realsound=false; + spkr.buf_pos=0; } From a1fcb4b4c34212b2cb7761d148753f86d9361cb4 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 16 Sep 2002 13:21:35 +0000 Subject: [PATCH 0201/4131] New pcspeaker functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@278 --- include/mixer.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/mixer.h b/include/mixer.h index e41b1838..3c02d93a 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -37,6 +37,9 @@ 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); +/* PC Speakers functions, tightly related to the timer functions */ + +void PCSPEAKER_Enable(bool enable); +void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode); + From 69fb6bdbda01b43193feb75a8dd19d93e4523d06 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 16 Sep 2002 13:25:41 +0000 Subject: [PATCH 0202/4131] New IRQ Handling to only allow 1 active irq, and cleaned up some old functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@279 --- src/hardware/pic.cpp | 102 ++++++++++++++++--------------------------- 1 file changed, 38 insertions(+), 64 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index b21bd49b..7357e026 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -31,7 +31,9 @@ struct IRQ_Block { PIC_EOIHandler * handler; }; -Bit32u PIC_IRQCheck; +Bitu PIC_IRQCheck; +Bitu PIC_IRQActive; +bool PIC_IRQAgain; static IRQ_Block irqs[16]; static Bit8u pic0_icws=0; @@ -45,7 +47,6 @@ static bool pic1_request_iisr=0; //Pic 0 command port static void write_p20(Bit32u port,Bit8u val) { - Bit32u i; switch (val) { case 0x0A: /* select read interrupt request register */ pic0_request_iisr=false; @@ -56,7 +57,6 @@ static void write_p20(Bit32u port,Bit8u val) { case 0x10: /* ICW1 */ pic0_icws=2; pic0_icw_state=1; - break; case 0x11: /* ICW1 + need for ICW4 */ pic0_icws=3; @@ -64,13 +64,11 @@ static void write_p20(Bit32u port,Bit8u val) { break; case 0x20: /* end of interrupt command */ /* clear highest current in service bit */ - for (i=0;i<=7;i++) { - if (irqs[i].inservice) { - irqs[i].inservice=false; - if (irqs[i].handler!=0) irqs[i].handler(); - break; - }; - }; + if (PIC_IRQActive<8) { + irqs[PIC_IRQActive].inservice=false; + if (irqs[PIC_IRQActive].handler!=0) irqs[PIC_IRQActive].handler(); + PIC_IRQActive=PIC_NOIRQ; + } break; case 0x60: /* specific EOI 0 */ case 0x61: /* specific EOI 1 */ @@ -80,10 +78,11 @@ static void write_p20(Bit32u port,Bit8u val) { case 0x65: /* specific EOI 5 */ case 0x66: /* specific EOI 6 */ case 0x67: /* specific EOI 7 */ - if (irqs[val-0x60].inservice) { - irqs[val-0x60].inservice=false; - if (irqs[val-0x60].handler!=0) irqs[val-0x60].handler(); - }; + if (PIC_IRQActive==(val-0x60U)) { + irqs[PIC_IRQActive].inservice=false; + if (irqs[PIC_IRQActive].handler!=0) irqs[PIC_IRQActive].handler(); + PIC_IRQActive=PIC_NOIRQ; + } break; // IRQ lowest priority commands case 0xC0: // 0 7 6 5 4 3 2 1 @@ -176,13 +175,11 @@ static void write_pa0(Bit32u port,Bit8u val) { break; case 0x20: /* end of interrupt command */ /* clear highest current in service bit */ - for (i=8;i<=15;i++) { - if (irqs[i].inservice) { - irqs[i].inservice=false; - if (irqs[i].handler!=0) irqs[i].handler(); - break; - }; - }; + if (PIC_IRQActive>7 && PIC_IRQActive <16) { + irqs[PIC_IRQActive].inservice=false; + if (irqs[PIC_IRQActive].handler!=0) irqs[PIC_IRQActive].handler(); + PIC_IRQActive=PIC_NOIRQ; + } break; case 0x60: /* specific EOI 0 */ case 0x61: /* specific EOI 1 */ @@ -192,9 +189,10 @@ static void write_pa0(Bit32u port,Bit8u val) { case 0x65: /* specific EOI 5 */ case 0x66: /* specific EOI 6 */ case 0x67: /* specific EOI 7 */ - if (irqs[val-0x60+8].inservice) { - irqs[val-0x60+8].inservice=false; - if (irqs[val-0x60+8].handler!=0) irqs[val-0x60+8].handler(); + if (PIC_IRQActive==(8+val-0x60U)) { + irqs[PIC_IRQActive].inservice=false; + if (irqs[PIC_IRQActive].handler!=0) irqs[PIC_IRQActive].handler(); + PIC_IRQActive=PIC_NOIRQ; }; break; // IRQ lowest priority commands @@ -220,6 +218,7 @@ static void write_pa1(Bit32u port,Bit8u val) { case 0: /* mask register */ for (i=0;i<=7;i++) { irqs[i+8].masked=(val&1 <0; + if (!irqs[8].masked) LOG_DEBUG("Someone unmasked RTC irq"); }; break; case 1: /* icw2 */ @@ -245,7 +244,7 @@ static Bit8u read_pa0(Bit32u port) { if (irqs[i+8].active) ret|=b; b <<= 1; } - }; + } return ret; } @@ -292,55 +291,31 @@ void PIC_DeActivateIRQ(Bit32u irq) { } } -bool PIC_IRQActive(Bit32u irq) { - if (irq<16) { - return irqs[irq].active; - } - return true; -} - - -#define PIC_MAXQUEUE 16 -static PIC_Function * pic_queue[PIC_MAXQUEUE]; -static Bit32u pic_queuesize; - -void PIC_QueueFunction(PIC_Function * function) { - if (pic_queuesize0;) { - (*pic_queue[--pic_queuesize])(); + PIC_IRQActive=i; + PIC_IRQAgain=true; + return; + } + } } -}; +} void PIC_Init(void) { /* Setup pic0 and pic1 with initial values like DOS has normally */ PIC_IRQCheck=0; + PIC_IRQActive=PIC_NOIRQ; Bit8u i; for (i=0;i<=7;i++) { irqs[i].active=false; @@ -351,11 +326,10 @@ void PIC_Init(void) { irqs[i+8].inservice=false; irqs[i].vector=0x8+i; irqs[i+8].vector=0x70+i; - }; + } irqs[0].masked=false; /* Enable system timer */ irqs[1].masked=false; /* Enable Keyboard IRQ */ - irqs[2].masked=false; /* Enable 2nd PIC Although i can't care if this is masked */ - irqs[12].masked=false; + irqs[12].masked=false; /* Enable Mouse IRQ */ IO_RegisterReadHandler(0x20,read_p20,"Master PIC Command"); IO_RegisterReadHandler(0x21,read_p21,"Master PIC Data"); IO_RegisterWriteHandler(0x20,write_p20,"Master PIC Command"); @@ -364,6 +338,6 @@ void PIC_Init(void) { IO_RegisterReadHandler(0xa1,read_pa1,"Slave PIC Data"); IO_RegisterWriteHandler(0xa0,write_pa0,"Slave PIC Command"); IO_RegisterWriteHandler(0xa1,write_pa1,"Slave PIC Data"); -}; +} From 5252435b7833b634b5c8ec5b564bb56a732d7226 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 16 Sep 2002 13:26:33 +0000 Subject: [PATCH 0203/4131] New IRQ Code to not get stuck in endless loops. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@280 --- src/dosbox.cpp | 48 +++++++++++++++++++++--------------------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 7aa59c4c..938ac837 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -106,8 +106,9 @@ static Bitu Normal_Loop(void) { PIC_runIRQs(); Bitu ret; do { + PIC_IRQAgain=false; ret=(*cpudecoder)(cpu_cycles); - } while (!ret && TimerAgain); + } while (!ret && PIC_IRQAgain); return ret; }; @@ -158,9 +159,9 @@ static void InitSystems(void) { JOYSTICK_Init(); SBLASTER_Init(); // TANDY_Init(); -// PCSPEAKER_Init(); + PCSPEAKER_Init(); ADLIB_Init(); -// CMS_Init(); + CMS_Init(); PLUGIN_Init(); /* Most of the interrupt handlers */ @@ -175,33 +176,29 @@ void DOSBOX_Init(int argc, char* argv[]) { /* Find the base directory */ SHELL_AddAutoexec("SET PATH=Z:\\"); SHELL_AddAutoexec("SET COMSPEC=Z:\\COMMAND.COM"); - strcpy(dosbox_basedir,argv[0]); + strcpy(dosbox_basedir,argv[0]); char * last=strrchr(dosbox_basedir,CROSS_FILESPLIT); //if windowsversion fails: - if (!last){ - getcwd(dosbox_basedir,CROSS_LEN); - char a[2]; - a[0]=CROSS_FILESPLIT; - a[1]='\0'; - strcat(dosbox_basedir,a); + if (!last) { + getcwd(dosbox_basedir,CROSS_LEN); + char a[2]; + a[0]=CROSS_FILESPLIT; + a[1]='\0'; + strcat(dosbox_basedir,a); } else { - *++last=0; + *++last=0; } /* Parse the command line with a setup function */ int argl=1; if (argc>1) { if (*argv[1]!='-') { - char mount_buffer[CROSS_LEN]; - if( (*argv[1]=='/') || - (*argv[1]=='.') || - (*argv[1]=='~') || - (*(argv[1]+1) ==':') ) { - strcpy(mount_buffer,argv[1]); - } else { - getcwd(mount_buffer,CROSS_LEN); - strcat(mount_buffer,argv[1]); - }; - - + char mount_buffer[CROSS_LEN]; + if( (*argv[1]=='/') || (*argv[1]=='.') || (*argv[1]=='~') || (*(argv[1]+1) ==':') ) { + strcpy(mount_buffer,argv[1]); + } else { + getcwd(mount_buffer,CROSS_LEN); + strcat(mount_buffer,argv[1]); + }; + struct stat test; if (stat(mount_buffer,&test)) { E_Exit("%s Doesn't exist",mount_buffer); @@ -231,14 +228,11 @@ void DOSBOX_Init(int argc, char* argv[]) { argl++; continue; } - SHELL_AddAutoexec(argv[argl]); + SHELL_AddAutoexec(argv[argl]); if (sw_c) { } argl++; } - - - InitSystems(); } From b0baa671830a28ca6ff87c975fe4e44bd82bd9e7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 16 Sep 2002 13:36:07 +0000 Subject: [PATCH 0204/4131] New PIC code Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@281 --- include/pic.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/pic.h b/include/pic.h index 44a2f76d..e7b41be2 100644 --- a/include/pic.h +++ b/include/pic.h @@ -20,9 +20,14 @@ #define __PIC_H typedef void (PIC_EOIHandler) (void); -typedef void (PIC_Function)(void); -extern Bit32u PIC_IRQCheck; +#define PIC_MAXIRQ 15 +#define PIC_NOIRQ 0xFF + + +extern Bitu PIC_IRQCheck; +extern Bitu PIC_IRQActive; +extern bool PIC_IRQAgain; void PIC_ActivateIRQ(Bit32u irq); @@ -33,11 +38,6 @@ void PIC_runIRQs(void); void PIC_RegisterIRQ(Bit32u irq,PIC_EOIHandler handler,char * name); void PIC_FreeIRQ(Bit32u irq); -bool PIC_IRQActive(Bit32u irq); - -/* A Queued function should never queue itself again this will go horribly wrong */ -void PIC_QueueFunction(PIC_Function * function); - #endif From bfa82478cb129cdd10431a05a1898b2a0f2ec0fd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 16 Sep 2002 14:15:10 +0000 Subject: [PATCH 0205/4131] Text scrolling used wrong line count. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@282 --- src/ints/int10_char.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 1a0e5d4d..1d6f4a0d 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -57,7 +57,6 @@ static INLINE void PLANAR4_FillRow(VGAMODES * curmode,Bit8u cleft,Bit8u cright,B IO_Write(0x3ce,0x8);IO_Write(0x3cf,0xff); IO_Write(0x3ce,0x0);IO_Write(0x3cf,attr); IO_Write(0x3ce,0x1);IO_Write(0x3cf,0xf); - IO_Write(0x3ce,5);IO_Write(0x3cf,0); /* Normal transfer mode */ /* Write some bytes */ PhysPt dest; dest=base+(curmode->twidth*row)*curmode->cheight+cleft; @@ -104,8 +103,8 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit end=cul; next=-1; } else if (nlines<0) { - start=cul-nlines-1; - end=clr; + start=rul-nlines-1; + end=rlr; next=1; } else { nlines=rlr-rul+1; @@ -127,8 +126,8 @@ filling: if (nlines>0) { start=rul; } else { - nlines-=nlines; - start=rlr-nlines; + nlines=-nlines; + start=rlr-nlines+1; } for (;nlines>0;nlines--) { switch (curmode->memmodel) { From 032402542d36000dd7f88fca70050e9b0712df00 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 16 Sep 2002 14:16:28 +0000 Subject: [PATCH 0206/4131] New ems code to use a handler instead of mapping for the pageframe Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@283 --- src/ints/ems.cpp | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index d3b694de..154c7ce4 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -28,6 +28,7 @@ #include "inout.h" #include "dos_inc.h" +#define EMM_USEHANDLER 1 #define EMM_PAGEFRAME 0xE000 #define EMM_MAX_HANDLES 50 /* 255 Max */ @@ -97,8 +98,23 @@ struct EMM_Handle { static EMM_Handle emm_handles[EMM_MAX_HANDLES]; static EMM_Page emm_pages[EMM_MAX_PAGES]; static EMM_Mapping emm_mappings[EMM_MAX_PHYS]; +static HostPt emm_pagebase[EMM_MAX_PHYS]; Bitu call_int67; +#if EMM_USEHANDLER +Bit8u EMM_ReadHandler(PhysPt start) { + start-=EMM_PAGEFRAME * 16; + Bitu page=start>>14; + return readb(emm_pagebase[page]+(start&0x3fff)); +} + +void EMM_WriteHandler(PhysPt start,Bit8u val) { + start-=EMM_PAGEFRAME * 16; + Bitu page=start>>14; + writeb(emm_pagebase[page]+(start&0x3fff),val); +} +#endif + static Bit16u EMM_GetFreePages(void) { Bit16u count=0; for (Bitu index=0;index Date: Mon, 16 Sep 2002 14:31:35 +0000 Subject: [PATCH 0207/4131] New keyboard routines supporting some commands and better handling of IRQ's Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@284 --- src/hardware/keyboard.cpp | 139 +++++++++++++++++++++++++++++--------- 1 file changed, 108 insertions(+), 31 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index cc9c85b3..f4fc2918 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -23,9 +23,14 @@ #include "pic.h" #include "mixer.h" - #define KEYBUFSIZE 32 +enum KeyCommands { + CMD_NONE, + CMD_SETLEDS, + CMD_SETTYPERATE +}; + struct KeyEvent { Bitu type; @@ -34,43 +39,109 @@ struct KeyEvent { KeyEvent * next; }; +struct KeyBlock { + Bit8u buf[KEYBUFSIZE]; + Bitu buf_pos; + Bitu buf_used; + Bitu write_state; + + KeyCommands command; + bool read_active; + bool enabled; +}; + +static KeyBlock keyb; static Bitu shift_state=0; static Bit8u cur_scancode; -static Bit8u kbuf[KEYBUFSIZE]; -static Bitu kbuf_pos; -static Bitu kbuf_used; static Bit8u port_61_data; //TODO Are these initialized at 0 at startup? Hope so :) static KeyEvent * event_handlers[KBD_LAST]; +void KEYBOARD_ClrBuffer(void) { + keyb.buf_used=0; + keyb.buf_pos=0; + keyb.read_active=false; + PIC_DeActivateIRQ(1); +} + + +void KEYBOARD_ReadBuffer(void) { + if (keyb.read_active) return; + if (keyb.buf_used) { + keyb.buf_used--; + keyb.buf_pos++; + if (keyb.buf_pos>=KEYBUFSIZE) keyb.buf_pos=0; + } + if (keyb.buf_used) { + keyb.read_active=true; + PIC_ActivateIRQ(1); + } +} + +void KEYBOARD_AddCode(Bit8u code) { + if (keyb.buf_used=KEYBUFSIZE) start-=KEYBUFSIZE; + keyb.buf[start]=code; + keyb.read_active=true; + } + if (keyb.buf_used>0) PIC_ActivateIRQ(1); +} + static Bit8u read_p60(Bit32u port) { - if (kbuf_used>0) { - cur_scancode=kbuf[kbuf_pos]; - }; - return cur_scancode; + /* Reading this port signals that IRQ can be lowered */ + Bit8u val=keyb.buf[keyb.buf_pos]; + keyb.read_active=false; + return keyb.buf[keyb.buf_pos]; } static void write_p60(Bit32u port,Bit8u val) { -//TODO Work this out ;) - LOG_DEBUG("Port 60 write with val %d",val); + switch (keyb.command) { + case CMD_NONE: /* None */ + KEYBOARD_ClrBuffer(); + switch (val) { + case 0xed: /* Set Leds */ + keyb.command=CMD_SETLEDS; + KEYBOARD_AddCode(0xfa); /* Acknowledge */ + break; + case 0xee: /* Echo */ + KEYBOARD_AddCode(0xee); + break; + case 0xf2: /* Identify keyboard */ + /* AT's just send acknowledge */ + KEYBOARD_AddCode(0xfa); /* Acknowledge */ + break; + case 0xf3: /* Typematic rate programming */ + keyb.command=CMD_SETTYPERATE; + KEYBOARD_AddCode(0xfa); /* Acknowledge */ + break; + default: + LOG_DEBUG("KEYB:60:Unhandled command %X",val); + } + return; + case CMD_SETTYPERATE: + case CMD_SETLEDS: + keyb.command=CMD_NONE; + KEYBOARD_AddCode(0xfa); /* Acknowledge */ + break; + } } static Bit8u read_p61(Bit32u port) { + port_61_data^=0x20; return port_61_data; + }; +static void KEYBOARD_IRQHandler(void) { + if (!keyb.read_active) KEYBOARD_ReadBuffer(); +} + static void write_p61(Bit32u port,Bit8u val) { -//TODO Enable spreaker through here :) - if ((val&128)) { /* Keyboard acknowledge */ - if (kbuf_used) { - kbuf_used--; - kbuf_pos++; - if (kbuf_pos>=KEYBUFSIZE) kbuf_pos=0; - if (kbuf_used) PIC_ActivateIRQ(1); - } - } port_61_data=val; + if (val & 128) if (!keyb.read_active) KEYBOARD_ReadBuffer(); if ((val & 3)==3) { PCSPEAKER_Enable(true); } else { @@ -78,20 +149,19 @@ static void write_p61(Bit32u port,Bit8u val) { } } - - -void KEYBOARD_AddCode(Bit8u code) { - //Now Raise the keyboard IRQ - //If the buffer is full just drop the scancode :) - if (kbuf_used=KEYBUFSIZE) start-=KEYBUFSIZE; - kbuf[start]=code; +static void write_p64(Bit32u port,Bit8u val) { + switch (val) { + case 0: + default: + LOG_DEBUG("Port 64 write with val %d",val); + break; } - PIC_ActivateIRQ(1); } +static Bit8u read_p64(Bit32u port) { + return 0x1c | (keyb.read_active ? 0x1 : 0x0); +}; + void KEYBOARD_AddEvent(Bitu keytype,Bitu state,KEYBOARD_EventHandler * handler) { KeyEvent * newevent=new KeyEvent; @@ -252,11 +322,18 @@ void KEYBOARD_AddKey(Bitu keytype,bool pressed) { }; void KEYBOARD_Init(void) { - kbuf_used=0;kbuf_pos=0; IO_RegisterWriteHandler(0x60,write_p60,"Keyboard"); IO_RegisterReadHandler(0x60,read_p60,"Keyboard"); IO_RegisterWriteHandler(0x61,write_p61,"Keyboard"); IO_RegisterReadHandler(0x61,read_p61,"Keyboard"); + IO_RegisterWriteHandler(0x64,write_p64,"Keyboard"); + IO_RegisterReadHandler(0x64,read_p64,"Keyboard"); + port_61_data=1; /* Speaker control through PIT and speaker disabled */ // memset(&event_handlers,0,sizeof(event_handlers)); + /* Clear the keyb struct */ + keyb.enabled=true; + keyb.command=CMD_NONE; + KEYBOARD_ClrBuffer(); + PIC_RegisterIRQ(1,KEYBOARD_IRQHandler,"KEYBOARD"); }; From 0277679a170316fa26a7332dd1fe0a33f60c62ea Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 16 Sep 2002 16:04:26 +0000 Subject: [PATCH 0208/4131] added 'rep nop' Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@285 --- src/cpu/core_16/main.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 9d72cf2e..e103276f 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -1205,6 +1205,8 @@ restart: } CMPW(reg_ax,LoadMw(to+(reg_di-direct*2)),LoadRw,0); break; + case 0x90: /* NOP - yes it is really used this way... eternam */ + break; default: E_Exit("Illegal REP prefix %2X",repcode); } From 2f16cccfee505482cb2497fd7f9db52ccc635fea Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 16 Sep 2002 16:05:23 +0000 Subject: [PATCH 0209/4131] cs:ip now restored from int22 vector in psp on termination Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@286 --- src/dos/dos_execute.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 375eb516..909ff03a 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -96,7 +96,7 @@ bool DOS_Terminate(bool tsr) { /* Free Files owned by process */ if (!tsr) curpsp.CloseFiles(); /* Get the termination address */ - RealPt old22 = RealGetVec(0x22); + RealPt old22 = curpsp.GetInt22(); /* Restore vector 22,23,24 */ curpsp.RestoreVectors(); /* Set the parent PSP */ @@ -106,8 +106,8 @@ bool DOS_Terminate(bool tsr) { dos.dta = parentpsp.GetDTA(); /* Restore the SS:SP to the previous one */ SegSet16(ss,RealSeg(parentpsp.GetStack())); - reg_sp = RealOff(parentpsp.GetStack()); - /* Restore the stored registers */ + reg_sp = RealOff(parentpsp.GetStack()); + /* Restore the old CS:IP from int 22h */ RestoreRegisters(); /* Set the CS:IP stored in int 0x22 back on the stack */ mem_writew(SegPhys(ss)+reg_sp+0,RealOff(old22)); @@ -303,6 +303,8 @@ bool DOS_Execute(char * name,ParamBlock * block,Bit8u flags) { dos.psp=pspseg; DOS_PSP newpsp(dos.psp); dos.dta=newpsp.GetDTA(); + /* save vectors */ + newpsp.SaveVectors(); /* copy fcbs */ newpsp.SetFCB1(block->exec.fcb1); newpsp.SetFCB2(block->exec.fcb2); From bc4b24a8bbf2e1e2ae45591ecf5f0eb93857a406 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 16 Sep 2002 16:05:52 +0000 Subject: [PATCH 0210/4131] fixed big in psp, wrong mem_size Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@287 --- src/dos/dos_classes.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 2e86014c..73b2911a 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -199,8 +199,7 @@ void DOS_PSP::MakeNew(Bit16u mem_size) /* Clear it first */ for (Bitu i=0;inext_seg,0,mem_size); - sSave(sPSP,next_seg,seg+mem_size); + sSave(sPSP,next_seg,mem_size); /* far call opcode */ sSave(sPSP,far_call,0xea); // sSave(sPSP,cmp_entry @@ -215,8 +214,6 @@ void DOS_PSP::MakeNew(Bit16u mem_size) sSave(sPSP,prev_psp,RealMake(dos.psp,0)); /* terminate 22,break 23,crititcal error 24 address stored */ SaveVectors(); - /* Memory size */ - sSave(sPSP,next_seg,seg+mem_size); /* Process DTA */ sSave(sPSP,dta,RealMake(seg,128)); /* FCBs are filled with 0 */ From f02d440dc96f35389003ee7ab15bb87f9a65346e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 17 Sep 2002 06:35:04 +0000 Subject: [PATCH 0211/4131] Added opcode 64 65 and 6B Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@288 --- src/cpu/core_16/prefix_66.h | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index d34ad4b4..86e71a25 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -153,6 +153,10 @@ switch(Fetchb()) { break; case 0x68: /* PUSH Id */ Push_32(Fetchd());break; + case 0x64: /* SEG FS: */ + SegPrefix_66(fs);break; + case 0x65: /* SEG GS: */ + SegPrefix_66(gs);break; case 0x69: /* IMUL Gd,Ed,Id */ { GetRMrd; @@ -164,12 +168,21 @@ switch(Fetchb()) { 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 0x6b: /* IMUL Gd,Ed,Ib */ + { + GetRMrd; + Bit64s res; + if (rm >= 0xc0 ) {GetEArd;res=(Bit64s)(*eards) * (Bit64s)Fetchbs();} + else {GetEAa;res=(Bit64s)LoadMds(eaa) * (Bit64s)Fetchbs();} + *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 0x81: /* Grpl Ed,Id */ { GetRM; From d0fc1da99bb64cf4ff6daa7171ff43e96d0ffd5f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 17 Sep 2002 20:07:25 +0000 Subject: [PATCH 0212/4131] added support for a config class/file. System not initialized perfect yet! (env is not fixed) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@289 --- ChangeLog | 4 + include/dosbox.h | 5 + include/setup.h | 124 ++++++++++++++++++- src/cpu/callback.cpp | 2 +- src/cpu/cpu.cpp | 6 +- src/debug/debug.cpp | 2 +- src/dos/dos.cpp | 2 +- src/dosbox.cpp | 228 +++++++++++++++++++++++------------ src/dosbox.lang | 1 - src/hardware/adlib.cpp | 7 +- src/hardware/dma.cpp | 2 +- src/hardware/gameblaster.cpp | 8 +- src/hardware/iohandler.cpp | 2 +- src/hardware/joystick.cpp | 2 +- src/hardware/keyboard.cpp | 2 +- src/hardware/memory.cpp | 4 +- src/hardware/mixer.cpp | 2 +- src/hardware/pcspeaker.cpp | 2 +- src/hardware/pic.cpp | 2 +- src/hardware/sblaster.cpp | 11 +- src/hardware/tandy_sound.cpp | 5 +- src/hardware/timer.cpp | 2 +- src/hardware/vga.cpp | 2 +- src/ints/bios.cpp | 4 +- src/ints/ems.cpp | 5 +- src/ints/int10.cpp | 2 +- src/ints/mouse.cpp | 2 +- src/ints/xms.cpp | 5 +- src/misc/messages.cpp | 9 +- src/misc/programs.cpp | 2 +- src/misc/setup.cpp | 166 ++++++++++++++++++++++++- 31 files changed, 502 insertions(+), 120 deletions(-) diff --git a/ChangeLog b/ChangeLog index b7862d2b..4cf20db9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +0.60 + - added support for a configclass/configfile + +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. diff --git a/include/dosbox.h b/include/dosbox.h index b277391d..c7a9266e 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -47,6 +47,9 @@ typedef signed int Bits; #include "config.h" #include "../settings.h" +class Section; + + typedef Bitu (LoopHandler)(void); void DOSBOX_RunMachine(); @@ -56,6 +59,8 @@ void DOSBOX_SetNormalLoop(); void DOSBOX_Init(int argc, char* argv[]); void DOSBOX_StartUp(void); +class Config; +extern Config * control; #endif diff --git a/include/setup.h b/include/setup.h index ec820112..a729f897 100644 --- a/include/setup.h +++ b/include/setup.h @@ -20,6 +20,127 @@ #define _SETUP_H_ #include +#include +#include + +union Value{ + int _hex; + bool _bool; + int _int; + std::string* _string; +}; + +class Property { +public: + Property(const char* _propname):propname(_propname) { } + virtual void SetValue(char* input)=0; + Value GetValue() { return __value; } + std::string propname; + Value __value; + virtual ~Property(){ } +}; + +class Prop_int:public Property { +public: + Prop_int(const char* _propname, int _value):Property(_propname) { + __value._int=_value; + } + void SetValue(char* input); + ~Prop_int(){ } +}; + +class Prop_bool:public Property { +public: + Prop_bool(const char* _propname, bool _value):Property(_propname) { + __value._bool=_value; + } + void SetValue(char* input); + ~Prop_bool(){ } +}; + +class Prop_string:public Property{ +public: + Prop_string(const char* _propname, char* _value):Property(_propname) { + __value._string=new std::string(_value); + } + ~Prop_string(){ + delete __value._string; + } + void SetValue(char* input); +}; +class Prop_hex:public Property { +public: + Prop_hex(const char* _propname, int _value):Property(_propname) { + __value._hex=_value; + } + void SetValue(char* input); + ~Prop_hex(){ } +}; + +class Section { +public: + Section(const char* _sectionname,void (*_initfunction)(Section*) ):sectionname(_sectionname){ initfunction=_initfunction;} + ~Section(){ } + + void (*initfunction)(Section*); + void ExecuteInit() { initfunction(this);} + + virtual void HandleInputline(char *gegevens){} + + std::string sectionname; +}; + + +class Section_prop:public Section { + public: + Section_prop(const char* _sectionname,void (*_initfunction)(Section*)):Section(_sectionname,_initfunction){ } + ~Section_prop(){} + + void Add_int(const char* _propname, int _value=0); + void Add_string(const char* _propname, char* _value=NULL); + void Add_bool(const char* _propname, bool _value=false); + void Add_hex(const char* _propname, int _value=0); + + int Get_int(const char* _propname); + const char* Get_string(const char* _propname); + bool Get_bool(const char* _propname); + int Get_hex(const char* _propname); + void HandleInputline(char *gegevens); + + std::list properties; + typedef std::list::iterator it; +}; + +class Section_line: public Section{ +public: + Section_line(const char* _sectionname,void (*_initfunction)(Section*)):Section(_sectionname,_initfunction){} + void HandleInputline(char* gegevens); + + std::string data; +}; + +class Config{ +public: + Config(){}; + + Section * AddSection(const char * _name,void (*_initfunction)(Section*)); + Section_line * AddSection_line(const char * _name,void (*_initfunction)(Section*)); + Section_prop * AddSection_prop(const char * _name,void (*_initfunction)(Section*)); + + Section* GetSection(const char* _sectionname); + + void Init(); + void ParseConfigFile(const char* configfilename); + + std::list sectionlist; + typedef std::list::iterator it; +}; + + + + + + enum { S_STRING,S_HEX,S_INT,S_BOOL}; typedef char *(String_Handler)(char * input); @@ -38,6 +159,7 @@ private: -extern char dosbox_basedir[CROSS_LEN]; +extern char dosbox_basedir[CROSS_LEN]; + #endif diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index d10d5e7f..e583dc06 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -135,7 +135,7 @@ bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type) { return true; } -void CALLBACK_Init(void) { +void CALLBACK_Init(Section* sec) { Bitu i; for (i=0;i(sec); reg_eax=0; reg_ebx=0; reg_ecx=0; @@ -166,7 +168,7 @@ void CPU_Init(void) { flags.io=0; SetCPU16bit(); - cpu_cycles=2000; + cpu_cycles=section->Get_int("CYCLES"); KEYBOARD_AddEvent(KBD_f11,CTRL_PRESSED,CPU_CycleDecrease); KEYBOARD_AddEvent(KBD_f12,CTRL_PRESSED,CPU_CycleIncrease); diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index fdb66ac9..24e96674 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -702,7 +702,7 @@ static void DEBUG_RaiseTimerIrq(void) { PIC_ActivateIRQ(0); } -void DEBUG_Init(void) { +void DEBUG_Init(Section* sec) { #ifdef WIN32 WIN32_Console(); #endif diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 0a7b8c18..eca9250c 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -850,7 +850,7 @@ static Bitu DOS_20Handler(void) { } -void DOS_Init(void) { +void DOS_Init(Section* sec) { call_20=CALLBACK_Allocate(); CALLBACK_Setup(call_20,DOS_20Handler,CB_IRET); RealSetVec(0x20,CALLBACK_RealPointer(call_20)); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 938ac837..bac5b217 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -35,57 +35,57 @@ #include "setup.h" #include "cross.h" #include "programs.h" +#include "support.h" + /* NEEDS A CLEANUP */ char dosbox_basedir[CROSS_LEN]; +Config * control; //The whole load of startups for all the subfunctions -void MSG_Init(void); -void MEM_Init(void); -void VGA_Init(void); -void CALLBACK_Init(); -void DOS_Init(); -void RENDER_Init(void); -void CPU_Init(); +void MSG_Init(Section_prop *); +void MEM_Init(Section *); +void IO_Init(Section * ); +void CALLBACK_Init(Section*); +void PROGRAMS_Init(Section*); + + +void VGA_Init(Section*); + +void DOS_Init(Section*); + + +void CPU_Init(Section*); //void FPU_Init(); -void IO_Init(void); -void DMA_Init(void); -void MIXER_Init(void); -void HARDWARE_Init(void); +void DMA_Init(Section*); +void MIXER_Init(Section*); +void HARDWARE_Init(Section*); -void KEYBOARD_Init(void); //TODO This should setup INT 16 too but ok ;) -void JOYSTICK_Init(void); -void MOUSE_Init(void); -void SBLASTER_Init(void); -void ADLIB_Init(void); -void PCSPEAKER_Init(void); -void TANDY_Init(void); -void CMS_Init(void); +void KEYBOARD_Init(Section*); //TODO This should setup INT 16 too but ok ;) +void JOYSTICK_Init(Section*); +void MOUSE_Init(Section*); +void SBLASTER_Init(Section*); +void ADLIB_Init(Section*); +void PCSPEAKER_Init(Section*); +void TANDYSOUND_Init(Section*); +void CMS_Init(Section*); + +void PIC_Init(Section*); +void TIMER_Init(Section*); +void BIOS_Init(Section*); +void DEBUG_Init(Section*); -void PIC_Init(void); -void TIMER_Init(void); -void BIOS_Init(void); -void DEBUG_Init(void); -void PLUGIN_Init(void); /* Dos Internal mostly */ -void EMS_Init(void); -void XMS_Init(void); -void PROGRAMS_Init(void); +void EMS_Init(Section*); +void XMS_Init(Section*); + void SHELL_Init(void); - -void CALLBACK_ShutDown(void); -void PIC_ShutDown(void); -void KEYBOARD_ShutDown(void); -void CPU_ShutDown(void); -void VGA_ShutDown(void); -void BIOS_ShutDown(void); -void MEMORY_ShutDown(void); - +void INT10_Init(Section*); @@ -129,50 +129,124 @@ void DOSBOX_RunMachine(void){ } - -static void InitSystems(void) { - MSG_Init(); - MEM_Init(); - IO_Init(); - CALLBACK_Init(); - PROGRAMS_Init(); - HARDWARE_Init(); - TIMER_Init(); - CPU_Init(); -#if C_FPU - FPU_Init(); -#endif - MIXER_Init(); -#if C_DEBUG - DEBUG_Init(); -#endif - - LastTicks=GetTicks(); - DOSBOX_SetLoop(&Normal_Loop); - - //Start up individual hardware - DMA_Init(); - PIC_Init(); - VGA_Init(); - KEYBOARD_Init(); - MOUSE_Init(); - JOYSTICK_Init(); - SBLASTER_Init(); -// TANDY_Init(); - PCSPEAKER_Init(); - ADLIB_Init(); - CMS_Init(); - - PLUGIN_Init(); -/* Most of the interrupt handlers */ - BIOS_Init(); - DOS_Init(); - EMS_Init(); //Needs dos first - XMS_Init(); //Needs dos first +static void DOSBOX_RealInit(Section * sec) { + Section_prop * section=static_cast(sec); + MSG_Init(section); } void DOSBOX_Init(int argc, char* argv[]) { +/* ADD A GOOD AND CLEAN ENV (see DOSBOX_Init2) */ + + + char base_dir[CROSS_LEN]; + char file_name[CROSS_LEN]; + control=new Config; + + strcpy(base_dir,argv[0]); + char * last=strrchr(base_dir,CROSS_FILESPLIT); //if windowsversion fails: + if (!last) { + getcwd(base_dir,CROSS_LEN); + char a[2]; + a[0]=CROSS_FILESPLIT; + a[1]='\0'; + strcat(base_dir,a); + } else { + *++last=0; + } + + + // Section * sec; + Section_prop * secprop; +// Section_line * secline; + + secprop=control->AddSection_prop("DOSBOX",&DOSBOX_RealInit); + strcpy(file_name,base_dir); + strcat(file_name,"dosbox.lang"); + secprop->Add_string("LANGUAGE",file_name); + secprop->Add_int("WARNINGS",0); + + control->AddSection ("MEMORY",&MEM_Init); + control->AddSection ("IO",&IO_Init); + control->AddSection ("CALLBACK",&CALLBACK_Init); + control->AddSection ("PIC",&PIC_Init); + control->AddSection ("PROGRAMS",&PROGRAMS_Init); + control->AddSection_prop("TIMER",&TIMER_Init); + secprop=control->AddSection_prop("CPU",&CPU_Init); + secprop->Add_int("CYCLES",3000); + secprop=control->AddSection_prop("MIXER",&MIXER_Init); +#if C_DEBUG + secprop=control->AddSection_prop("'DEBUG",&DEBUG_Init); +#endif + control->AddSection ("DMA",&DMA_Init); + control->AddSection ("VGA",&VGA_Init); + control->AddSection ("KEYBOARD",&KEYBOARD_Init); + secprop=control->AddSection_prop("MOUSE",&MOUSE_Init); + control->AddSection ("JOYSTICK",&JOYSTICK_Init); + + secprop=control->AddSection_prop("SBLASTER",&SBLASTER_Init); + secprop->Add_hex("BASE",0x220); + secprop->Add_int("IRQ",5); + secprop->Add_int("DMA",1); + secprop->Add_bool("STATUS",true); + + secprop=control->AddSection_prop("TANDYSOUND",&TANDYSOUND_Init); + secprop->Add_bool("STATUS",false); + + secprop=control->AddSection_prop("PCSPEAKER",&PCSPEAKER_Init); + + secprop=control->AddSection_prop("ADLIB",&ADLIB_Init); + secprop->Add_bool("STATUS",true); + + secprop=control->AddSection_prop("CMS",&CMS_Init); + secprop->Add_bool("STATUS",false); + + secprop=control->AddSection_prop("BIOS",&BIOS_Init); + secprop=control->AddSection_prop("VIDBIOS",&INT10_Init); + secprop=control->AddSection_prop("DOS",&DOS_Init); + secprop=control->AddSection_prop("EMS",&EMS_Init); + secprop->Add_bool("STATUS",true); + secprop->Add_int("SIZE",4); + secprop=control->AddSection_prop("XMS",&XMS_Init); + secprop->Add_bool("STATUS",true); + secprop->Add_int("SIZE",8); + + + strcpy(file_name,base_dir); + strcat(file_name,"dosbox.conf"); + /* Parse the command line to find config file name */ + int i; + i=1; + while (iParseConfigFile(file_name); +/* Parse the command line to find all other options */ + + /*Init all the systems with the acquired settings */ + control->Init(); + +// HARDWARE_Init(); +#if C_FPU + FPU_Init(); +#endif + + + //Start up individual hardware + +/* Most of the interrupt handlers */ + + LastTicks=GetTicks(); + DOSBOX_SetLoop(&Normal_Loop); +} + + +void DOSBOX2_Init(int argc, char* argv[]) { + + /* Find the base directory */ SHELL_AddAutoexec("SET PATH=Z:\\"); SHELL_AddAutoexec("SET COMSPEC=Z:\\COMMAND.COM"); @@ -233,7 +307,7 @@ void DOSBOX_Init(int argc, char* argv[]) { } argl++; } - InitSystems(); + } diff --git a/src/dosbox.lang b/src/dosbox.lang index 783083cd..f2ff667b 100644 --- a/src/dosbox.lang +++ b/src/dosbox.lang @@ -61,7 +61,6 @@ Illegal Path :SHELL_STARTUP DOSBox Shell v0.35 For Help and supported commands type: HELP -For information about the hardware setup manager type: HWSET /? HAVE FUN! The DOSBox Team diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 171772df..83a49cd5 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -24,7 +24,7 @@ #include "mixer.h" #include "timer.h" #include "hardware.h" - +#include "setup.h" /* Thanks to vdmsound for nice simple way to implement this */ @@ -192,8 +192,9 @@ static void ADLIB_OutputHandler (char * towrite) { -void ADLIB_Init(void) { - +void ADLIB_Init(Section* sec) { + Section_prop * section=static_cast(sec); + if(!section->Get_bool("STATUS")) return; timer1.isMasked=true; timer1.base=0; timer1.count=0; diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 2a50e178..beca518d 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -203,7 +203,7 @@ Bit16u DMA_16_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count) { -void DMA_Init(void) { +void DMA_Init(Section* sec) { for (Bit32u i=0;i<0x10;i++) { IO_RegisterWriteHandler(i,write_dma,"DMA1"); } diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index bcddec06..6ddd6969 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -22,11 +22,11 @@ #include "mixer.h" #include "mem.h" #include "hardware.h" +#include "setup.h" #define CMS_RATE 22050 #define CMS_VOLUME 6000 - #define FREQ_SHIFT 16 #define SIN_ENT 1024 @@ -213,7 +213,11 @@ static void CMS_OutputHandler (char * towrite) { }; -void CMS_Init(void) { + + +void CMS_Init(Section* sec) { + Section_prop * section=static_cast(sec); + if(!section->Get_bool("STATUS")) return; Bits i; /* Register the Mixer CallBack */ cms_chan=MIXER_AddChannel(CMS_CallBack,CMS_RATE,"CMS"); diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 242f6f0b..0a499c42 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -80,7 +80,7 @@ void IO_FreeWriteHandler(Bit32u port) { } -void IO_Init(void) { +void IO_Init(Section * sect) { for (Bitu i=0;i(sec); + if(!section->Get_bool("STATUS")) return; sb.chan=MIXER_AddChannel(&SBLASTER_CallBack,22050,"SBLASTER"); MIXER_Enable(sb.chan,false); sb.state=DSP_S_NORMAL; /* Setup the hardware handler part */ - sb.base=SB_BASE; - sb.irq=SB_IRQ; - sb.dma=SB_DMA; + sb.base=section->Get_hex("BASE"); + sb.irq=section->Get_int("IRQ"); + sb.dma=section->Get_int("DMA"); SB_Enable(true); sb.hwblock.dev_name="SB"; diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 357a338a..2ab49b46 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -25,6 +25,7 @@ #include "inout.h" #include "mixer.h" #include "mem.h" +#include "setup.h" #define TANDY_DIV 111860 #define TANDY_RATE 22050 @@ -125,7 +126,9 @@ static void TANDYSOUND_CallBack(Bit8u * stream,Bit32u len) { } }; -void TANDY_Init(void) { +void TANDYSOUND_Init(Section* sec) { + Section_prop * section=static_cast(sec); + if(!section->Get_bool("STATUS")) return; IO_RegisterWriteHandler(0xc0,write_pc0,"Tandy Sound"); tandy_chan=MIXER_AddChannel(&TANDYSOUND_CallBack,TANDY_RATE,"TANDY"); MIXER_Enable(tandy_chan,false); diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index b245be20..758a8a07 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -297,7 +297,7 @@ void TIMER_CheckPIT(void) { } -void TIMER_Init(void) { +void TIMER_Init(Section* sect) { Bitu i; IO_RegisterWriteHandler(0x40,write_latch,"PIT Timer 0"); IO_RegisterWriteHandler(0x42,write_latch,"PIT Timer 2"); diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index d2af3138..310b6d15 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -146,7 +146,7 @@ void VGA_StartResize(void) { } -void VGA_Init() { +void VGA_Init(Section* sec) { vga.draw.resizing=false; VGA_SetupMemory(); VGA_SetupMisc(); diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 57466e78..aa8ac9d5 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -193,7 +193,7 @@ static void INT15_StartUp(void) { void BIOS_SetupKeyboard(void); void BIOS_SetupDisks(void); -void BIOS_Init(void) { +void BIOS_Init(Section* sec) { /* Clear the Bios Data Area */ for (Bit16u i=0;i<1024;i++) real_writeb(0x40,i,0); /* Setup all the interrupt handlers the bios controls */ @@ -205,7 +205,7 @@ void BIOS_Init(void) { mem_writed(BIOS_TIMER,0); //Calculate the correct time RealSetVec(0x8,CALLBACK_RealPointer(call_int8)); /* INT10 Video Bios */ - INT10_StartUp(); + /* INT 11 Get equipment list */ call_int11=CALLBACK_Allocate(); CALLBACK_Setup(call_int11,&INT11_Handler,CB_IRET); diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 154c7ce4..164a7094 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -27,6 +27,7 @@ #include "regs.h" #include "inout.h" #include "dos_inc.h" +#include "setup.h" #define EMM_USEHANDLER 1 @@ -454,7 +455,9 @@ static Bitu INT67_Handler(void) { -void EMS_Init(void) { +void EMS_Init(Section* sec) { + Section_prop * section=static_cast(sec); + if(!section->Get_bool("STATUS")) return; call_int67=CALLBACK_Allocate(); CALLBACK_Setup(call_int67,&INT67_Handler,CB_IRET); /* Register the ems device */ diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index a236e8e9..635de150 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -259,7 +259,7 @@ static void INT10_InitVGA(void) { IO_Write(0x3c5,0x02); }; -void INT10_StartUp(void) { +void INT10_Init(Section* sec) { INT10_InitVGA(); /* Setup the INT 10 vector */ call_10=CALLBACK_Allocate(); diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 23c95fe7..9410e1b8 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -310,7 +310,7 @@ static Bitu INT74_Handler(void) { }; -void MOUSE_Init(void) { +void MOUSE_Init(Section* sec) { call_int33=CALLBACK_Allocate(); CALLBACK_Setup(call_int33,&INT33_Handler,CB_IRET); real_writed(0,(0x33<<2),CALLBACK_RealPointer(call_int33)); diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index d08bd651..026a497d 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -23,6 +23,7 @@ #include "mem.h" #include "regs.h" #include "dos_system.h" +#include "setup.h" #define XMS_HANDLES 50 /* 50 XMS Memory Blocks */ @@ -324,7 +325,9 @@ foundnew: -void XMS_Init(void) { +void XMS_Init(Section* sec) { + Section_prop * section=static_cast(sec); + if(!section->Get_bool("STATUS")) return; DOS_AddMultiplexHandler(multiplex_xms); call_xms=CALLBACK_Allocate(); CALLBACK_Setup(call_xms,&XMS_Handler,CB_RETF); diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index d7e05b2d..33cd4617 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -38,7 +38,7 @@ struct MessageBlock static MessageBlock * first_message; -static void LoadMessageFile(char * fname) { +static void LoadMessageFile(const char * fname) { FILE * mfile=fopen(fname,"rb"); /* This should never happen and since other modules depend on this use a normal printf */ if (!mfile) { @@ -97,11 +97,8 @@ char * MSG_Get(char * msg) { -void MSG_Init(void) { +void MSG_Init(Section_prop * section) { /* Load the messages from "dosbox.lang file" */ first_message=0; - char filein[CROSS_LEN]; - strcpy(filein,dosbox_basedir); - strcat(filein,"dosbox.lang"); - LoadMessageFile(filein); + LoadMessageFile(section->Get_string("LANGUAGE")); } diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index b1f7b490..e170ebbe 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -167,7 +167,7 @@ bool Program::SetEnv(char * env_entry,char * new_string) { //TODO Hash table :) -void PROGRAMS_Init(void) { +void PROGRAMS_Init(Section* sec) { /* Setup a special callback to start virtual programs */ call_program=CALLBACK_Allocate(); CALLBACK_Setup(call_program,&PROGRAMS_Handler,CB_RETF); diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 69d47cb6..1e83a93a 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -19,11 +19,173 @@ #include "dosbox.h" #include "cross.h" #include "setup.h" +#include +#include +#include +#include +#include "support.h" -void SETUP_AddBoolHandler() { +using namespace std; -}; +void Prop_int::SetValue(char* input){ + input=trim(input); + __value._int= atoi(input); +} + +void Prop_string::SetValue(char* input){ + input=trim(input); + __value._string->assign(input); +} + +void Prop_bool::SetValue(char* input){ + input=trim(input); + if((input[0]=='0') ||(input[0]=='D')||( (input[0]=='O') && (input[0]=='F'))){ + __value._bool=false; + }else{ + __value._bool=true; + } +} +void Prop_hex::SetValue(char* input){ + input=trim(input); + if(!sscanf(input,"%X",&(__value._hex))) __value._hex=0; +} + +void Section_prop::Add_int(const char* _propname, int _value) { + Property* test=new Prop_int(_propname,_value); + properties.push_back(test); +} + +void Section_prop::Add_string(const char* _propname, char* _value) { + Property* test=new Prop_string(_propname,_value); + properties.push_back(test); +} + +void Section_prop::Add_bool(const char* _propname, bool _value) { + Property* test=new Prop_bool(_propname,_value); + properties.push_back(test); +} +void Section_prop::Add_hex(const char* _propname, int _value) { + Property* test=new Prop_hex(_propname,_value); + properties.push_back(test); +} +int Section_prop::Get_int(const char* _propname){ + for(it tel=properties.begin();tel!=properties.end();tel++){ + if((*tel)->propname==_propname){ + return ((*tel)->GetValue())._int; + } + } + return 0; +} + +bool Section_prop::Get_bool(const char* _propname){ + for(it tel=properties.begin();tel!=properties.end();tel++){ + if((*tel)->propname==_propname){ + return ((*tel)->GetValue())._bool; + } + } + return false; +} + + +const char* Section_prop::Get_string(const char* _propname){ + for(it tel=properties.begin();tel!=properties.end();tel++){ + if((*tel)->propname==_propname){ + return ((*tel)->GetValue())._string->c_str(); + } + } + return NULL; +} +int Section_prop::Get_hex(const char* _propname){ + for(it tel=properties.begin();tel!=properties.end();tel++){ + if((*tel)->propname==_propname){ + return ((*tel)->GetValue())._hex; + } + } + return 0; +} + +void Section_prop::HandleInputline(char *gegevens){ + char * rest=strrchr(gegevens,'='); + *rest=0; + gegevens=trim(gegevens); + for(it tel=properties.begin();tel!=properties.end();tel++){ + if((*tel)->propname==gegevens){ + (*tel)->SetValue(rest+1); + return; + } + } +} + + +void Section_line::HandleInputline(char* gegevens){ + data+=gegevens; + data+="\n"; +} + +Section* Config::AddSection(const char* _name,void (*_initfunction)(Section*)){ + Section* blah = new Section(_name,_initfunction); + sectionlist.push_back(blah); + return blah; +} + +Section_prop* Config::AddSection_prop(const char* _name,void (*_initfunction)(Section*)){ + Section_prop* blah = new Section_prop(_name,_initfunction); + sectionlist.push_back(blah); + return blah; +} + +Section_line* Config::AddSection_line(const char* _name,void (*_initfunction)(Section*)){ + Section_line* blah = new Section_line(_name,_initfunction); + sectionlist.push_back(blah); + return blah; +} + + +void Config::Init(){ + for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ + (*tel)->ExecuteInit(); + } +} + +Section* Config::GetSection(const char* _sectionname){ + for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ + if ( (*tel)->sectionname==_sectionname) return (*tel); + } + return NULL; +} + +void Config::ParseConfigFile(const char* configfilename){ + ifstream in(configfilename); + if (!in) LOG_MSG("CONFIG:Can't find config file %s, using default settings",configfilename); + char gegevens[150]; + Section* currentsection; + while (in) { + in.getline(gegevens,150); + char* temp; + switch(gegevens[0]){ + case '%': + case '\0': + case '\n': + case ' ': + continue; + break; + case '[': + temp = strrchr(gegevens,']'); + *temp=0; + currentsection=GetSection(&gegevens[1]); + break; + default: + try{ + currentsection->HandleInputline(gegevens); + }catch(const char* message){ + message=0; + //EXIT with message + } + break; + } + } +} From ac538811ebcb2b846ee831b82ba4d9ac4d00dd0e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 18 Sep 2002 15:28:46 +0000 Subject: [PATCH 0213/4131] Made the visual C special #defines for WIN32 to fix some errors with mingw32 compiling. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@290 --- include/cross.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/cross.h b/include/cross.h index 2dc3d2cf..65066cd8 100644 --- a/include/cross.h +++ b/include/cross.h @@ -34,7 +34,7 @@ #define CROSS_LEN 512 /* Maximum filename size */ -#if defined (_MSC_VER) /* MS Visual C++ */ +#if defined (WIN32) /* Win 32 */ #define CROSS_FILENAME(blah) #define CROSS_FILESPLIT '\\' #define F_OK 0 @@ -46,7 +46,7 @@ #define CROSS_NONE 0 #define CROSS_FILE 1 #define CROSS_DIR 2 -#if defined (_MSC_VER) +#if defined (WIN32) #define ftruncate(blah,blah2) chsize(blah,blah2) #endif From 4b4a8dfad334a73a94291a9315b5d1197303d6e5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 18 Sep 2002 15:29:40 +0000 Subject: [PATCH 0214/4131] New DOSBOX_Init which should now register all dosbox speficic Init functions in the main control class. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@291 --- include/dosbox.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/dosbox.h b/include/dosbox.h index c7a9266e..ac7b4f34 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -56,8 +56,7 @@ void DOSBOX_RunMachine(); void DOSBOX_SetLoop(LoopHandler * handler); void DOSBOX_SetNormalLoop(); -void DOSBOX_Init(int argc, char* argv[]); -void DOSBOX_StartUp(void); +void DOSBOX_Init(void); class Config; extern Config * control; From 13bba0357a6c41a7f2416fe110eec6a9d37f0ce1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 18 Sep 2002 15:30:56 +0000 Subject: [PATCH 0215/4131] Added support for Command Line option detection. This includes a new class for that and some additions for the config class to handle it. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@292 --- include/setup.h | 57 ++++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/include/setup.h b/include/setup.h index a729f897..95fa2f03 100644 --- a/include/setup.h +++ b/include/setup.h @@ -19,10 +19,31 @@ #ifndef _SETUP_H_ #define _SETUP_H_ +#pragma warning ( disable : 4786 ) + #include #include #include +class CommandLine { +public: + CommandLine(int argc,char * argv[]); + CommandLine(char * name,char * cmdline); + const char * GetFileName(){ return file_name.c_str();} + + bool FindExist(char * name,bool remove=false); + bool FindHex(char * name,int & value,bool remove=false); + bool FindInt(char * name,int & value,bool remove=false); + bool FindString(char * name,std::string & value,bool remove=false); + + bool FindFirst(std::string & value); +private: + typedef std::list::iterator cmd_it; + std::list cmds; + std::string file_name; + bool FindEntry(char * name,cmd_it & it,bool neednext=false); +}; + union Value{ int _hex; bool _bool; @@ -121,7 +142,9 @@ public: class Config{ public: - Config(){}; + Config(CommandLine * cmd){ cmdline=cmd;} + + CommandLine * cmdline; Section * AddSection(const char * _name,void (*_initfunction)(Section*)); Section_line * AddSection_line(const char * _name,void (*_initfunction)(Section*)); @@ -129,37 +152,17 @@ public: Section* GetSection(const char* _sectionname); + void SetStartUp(void (*_function)(void)); void Init(); - void ParseConfigFile(const char* configfilename); + void ShutDown(); + void StartUp(); + void ParseConfigFile(const char* configfilename); + std::list sectionlist; typedef std::list::iterator it; -}; - - - - - - -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; - + void (* _start_function)(void); }; - - -extern char dosbox_basedir[CROSS_LEN]; - - #endif From b44f5714c52c2553d794507afb6d93da825b51e2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 18 Sep 2002 15:31:48 +0000 Subject: [PATCH 0216/4131] Messages can now be loaded using a command line switch -lang. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@293 --- src/misc/messages.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 33cd4617..38ccb700 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -37,7 +37,6 @@ struct MessageBlock static MessageBlock * first_message; - static void LoadMessageFile(const char * fname) { FILE * mfile=fopen(fname,"rb"); /* This should never happen and since other modules depend on this use a normal printf */ @@ -85,7 +84,6 @@ static void LoadMessageFile(const char * fname) { fclose(mfile); } - char * MSG_Get(char * msg) { MessageBlock * index=first_message; while (index) { @@ -95,10 +93,11 @@ char * MSG_Get(char * msg) { return "Message not found"; } - - void MSG_Init(Section_prop * section) { /* Load the messages from "dosbox.lang file" */ first_message=0; - LoadMessageFile(section->Get_string("LANGUAGE")); + std::string file_name; + if (control->cmdline->FindString("-lang",file_name)) { + LoadMessageFile(file_name.c_str()); + } else LoadMessageFile(section->Get_string("LANGUAGE")); } From f2b173c5de5770d72a10c939a951f32fc44018f8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 18 Sep 2002 15:32:52 +0000 Subject: [PATCH 0217/4131] E_Exit now throws a string containing the error, which will be caught in SDL to create a correct shutdown. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@294 --- src/misc/support.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 6e5f7cae..c9771c65 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -217,13 +217,8 @@ void S_Warn(char * format,...) { void E_Exit(char * format,...) { - if (sdl.full_screen) { - GFX_SwitchFullScreen(); - } - char buf[1024]; -// SysShutDown(); va_list msg; strcpy(buf,"EXIT:"); va_start(msg,format); @@ -232,9 +227,5 @@ void E_Exit(char * format,...) { strcat(buf,"\n"); printf(buf); - printf("Press ENTER to stop\n"); - fgetc(stdin); - GFX_Stop(); - exit(2); - + throw(buf); }; \ No newline at end of file From 17bf8cb01918ebc424383073f74839795dc130bf Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 18 Sep 2002 15:33:49 +0000 Subject: [PATCH 0218/4131] A new CommandLine class and Config Class now has a startup handler to startup once everything has been initialized Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@295 --- src/misc/setup.cpp | 101 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 1e83a93a..c66e9682 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -187,5 +187,106 @@ void Config::ParseConfigFile(const char* configfilename){ } } +void Config::SetStartUp(void (*_function)(void)) { + _start_function=_function; +} +void Config::StartUp(void) { + (*_start_function)(); +} + + + + +bool CommandLine::FindExist(char * name,bool remove) { + cmd_it it; + if (!(FindEntry(name,it,false))) return false; + if (remove) cmds.erase(it); + return true; +} + +bool CommandLine::FindHex(char * name,int & value,bool remove) { + cmd_it it,it_next; + if (!(FindEntry(name,it,true))) return false; + it_next=it;it_next++; + sscanf((*it_next).c_str(),"%X",&value); + if (remove) cmds.erase(it,it_next); + return true; +} + +bool CommandLine::FindInt(char * name,int & value,bool remove) { + cmd_it it,it_next; + if (!(FindEntry(name,it,true))) return false; + it_next=it;it_next++; + value=atoi((*it_next).c_str()); + if (remove) cmds.erase(it,it_next); + return true; +} + +bool CommandLine::FindString(char * name,std::string & value,bool remove) { + cmd_it it,it_next; + if (!(FindEntry(name,it,true))) return false; + it_next=it;it_next++; + value=*it_next; + if (remove) cmds.erase(it,it_next); + return true; +} + +bool CommandLine::FindFirst(std::string & value) { + if (cmds.empty()) return false; + value=*cmds.begin(); + return true; +} + +bool CommandLine::FindEntry(char * name,cmd_it & it,bool neednext) { + for (it=cmds.begin();it!=cmds.end();it++) { + if ((*it)==name) { + cmd_it itnext=it;itnext++; + if (neednext && (itnext==cmds.end())) return false; + return true; + } + } + return false; +} + +CommandLine::CommandLine(int argc,char * argv[]) { + if (argc>0) { + file_name=argv[0]; + } + int i=1; + while (i Date: Wed, 18 Sep 2002 16:30:59 +0000 Subject: [PATCH 0219/4131] Added command line support and moved the command line hanlding for automounting to the shell. Also added a init function for autoexec.bat. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@296 --- src/dosbox.cpp | 136 +++++++------------------------------------------ 1 file changed, 17 insertions(+), 119 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index bac5b217..4df80388 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -82,7 +82,7 @@ void DEBUG_Init(Section*); /* Dos Internal mostly */ void EMS_Init(Section*); void XMS_Init(Section*); - +void AUTOEXEC_Init(Section*); void SHELL_Init(void); void INT10_Init(Section*); @@ -131,39 +131,23 @@ void DOSBOX_RunMachine(void){ static void DOSBOX_RealInit(Section * sec) { Section_prop * section=static_cast(sec); + /* Initialize some dosbox internals */ + LastTicks=GetTicks(); + DOSBOX_SetLoop(&Normal_Loop); MSG_Init(section); } -void DOSBOX_Init(int argc, char* argv[]) { -/* ADD A GOOD AND CLEAN ENV (see DOSBOX_Init2) */ - - - char base_dir[CROSS_LEN]; - char file_name[CROSS_LEN]; - control=new Config; - - strcpy(base_dir,argv[0]); - char * last=strrchr(base_dir,CROSS_FILESPLIT); //if windowsversion fails: - if (!last) { - getcwd(base_dir,CROSS_LEN); - char a[2]; - a[0]=CROSS_FILESPLIT; - a[1]='\0'; - strcat(base_dir,a); - } else { - *++last=0; - } - - - // Section * sec; +void DOSBOX_Init(void) { +// Section * sec; Section_prop * secprop; -// Section_line * secline; - + Section_line * secline; + + /* Setup all the different modules making up DOSBox */ + secprop=control->AddSection_prop("DOSBOX",&DOSBOX_RealInit); - strcpy(file_name,base_dir); - strcat(file_name,"dosbox.lang"); - secprop->Add_string("LANGUAGE",file_name); + + secprop->Add_string("LANGUAGE","dosbox.lang"); secprop->Add_int("WARNINGS",0); control->AddSection ("MEMORY",&MEM_Init); @@ -203,6 +187,9 @@ void DOSBOX_Init(int argc, char* argv[]) { secprop=control->AddSection_prop("BIOS",&BIOS_Init); secprop=control->AddSection_prop("VIDBIOS",&INT10_Init); + + /* All the DOS Related stuff, which will eventually start up in the shell */ + secprop=control->AddSection_prop("DOS",&DOS_Init); secprop=control->AddSection_prop("EMS",&EMS_Init); secprop->Add_bool("STATUS",true); @@ -211,23 +198,9 @@ void DOSBOX_Init(int argc, char* argv[]) { secprop->Add_bool("STATUS",true); secprop->Add_int("SIZE",8); + secline=control->AddSection_line("AUTOEXEC",&AUTOEXEC_Init); - strcpy(file_name,base_dir); - strcat(file_name,"dosbox.conf"); - /* Parse the command line to find config file name */ - int i; - i=1; - while (iParseConfigFile(file_name); -/* Parse the command line to find all other options */ - - /*Init all the systems with the acquired settings */ - control->Init(); + control->SetStartUp(&SHELL_Init); // HARDWARE_Init(); #if C_FPU @@ -235,82 +208,7 @@ void DOSBOX_Init(int argc, char* argv[]) { #endif - //Start up individual hardware -/* Most of the interrupt handlers */ - - LastTicks=GetTicks(); - DOSBOX_SetLoop(&Normal_Loop); } -void DOSBOX2_Init(int argc, char* argv[]) { - - -/* Find the base directory */ - SHELL_AddAutoexec("SET PATH=Z:\\"); - SHELL_AddAutoexec("SET COMSPEC=Z:\\COMMAND.COM"); - strcpy(dosbox_basedir,argv[0]); - char * last=strrchr(dosbox_basedir,CROSS_FILESPLIT); //if windowsversion fails: - if (!last) { - getcwd(dosbox_basedir,CROSS_LEN); - char a[2]; - a[0]=CROSS_FILESPLIT; - a[1]='\0'; - strcat(dosbox_basedir,a); - } else { - *++last=0; - } - /* Parse the command line with a setup function */ - int argl=1; - if (argc>1) { - if (*argv[1]!='-') { - char mount_buffer[CROSS_LEN]; - if( (*argv[1]=='/') || (*argv[1]=='.') || (*argv[1]=='~') || (*(argv[1]+1) ==':') ) { - strcpy(mount_buffer,argv[1]); - } else { - getcwd(mount_buffer,CROSS_LEN); - strcat(mount_buffer,argv[1]); - }; - - struct stat test; - if (stat(mount_buffer,&test)) { - E_Exit("%s Doesn't exist",mount_buffer); - } - /* Not a switch so a normal directory/file */ - if (test.st_mode & S_IFDIR) { - SHELL_AddAutoexec("MOUNT C %s",mount_buffer); - SHELL_AddAutoexec("C:"); - } else { - char * name=strrchr(argv[1],CROSS_FILESPLIT); - if (!name) E_Exit("This is weird %s",mount_buffer); - *name++=0; - if (access(argv[1],F_OK)) E_Exit("Illegal Directory %s",mount_buffer); - SHELL_AddAutoexec("MOUNT C %s",mount_buffer); - SHELL_AddAutoexec("C:"); - SHELL_AddAutoexec(name); - } - argl++; - } - } - bool sw_c=false; - while (argl Date: Wed, 18 Sep 2002 16:33:11 +0000 Subject: [PATCH 0220/4131] SDL now manages the control functions and it sets up the CommandLine class. Also made it possible to have a -fullscreen command line switch. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@297 --- src/gui/sdlmain.cpp | 93 ++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 44 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 3bc5868e..08f4e110 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -27,6 +27,7 @@ #include "joystick.h" #include "pic.h" #include "timer.h" +#include "setup.h" //#define DISABLE_JOYSTICK @@ -182,17 +183,18 @@ void GFX_Start() { } -void GFX_StartUp() { +void GUI_StartUp(Section * sec) { + Section_prop * section=static_cast(sec); sdl.active=false; sdl.full_screen=false; sdl.draw=0; + GFX_Resize(640,400,8,0); #if C_THREADED sdl.mutex=SDL_CreateMutex(); sdl.thread = SDL_CreateThread(&SDLGFX_Thread,0); #else TIMER_RegisterMicroHandler(GFX_Redraw,1000000/70); #endif - GFX_Resize(640,400,8,0); SDL_EnableKeyRepeat(250,30); /* Get some Keybinds */ @@ -439,24 +441,6 @@ void GFX_Events() { } } } -#if 0 - -void E_Exit(char * format,...) { - char buf[1024]; - - va_list msg; - strcpy(buf,"EXIT:"); - va_start(msg,format); - vsprintf(buf+strlen(buf),format,msg); - va_end(msg); - waddstr(dbg.win_out,buf); - wprintw(dbg.win_out," %d\n",cycle_count); - wrefresh(dbg.win_out); - throw ((Bitu)1); -} - -#endif - void GFX_ShowMsg(char * msg) { char buf[1024]; @@ -466,36 +450,57 @@ void GFX_ShowMsg(char * msg) { }; int main(int argc, char* argv[]) { - try { - if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER + try { + CommandLine com_line(argc,argv); + Config myconf(&com_line); + control=&myconf; + + if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER #ifndef DISABLE_JOYSTICK |SDL_INIT_JOYSTICK #endif - ) < 0 ) { - E_Exit("Can't init SDL %s",SDL_GetError()); - } - GFX_StartUp(); -/* Init all the dosbox subsystems */ - DOSBOX_Init(argc,argv); -/* Start the systems that SDL should provide */ + ) < 0 ) E_Exit("Can't init SDL %s",SDL_GetError()); + Section_prop * sdl_sec=control->AddSection_prop("SDL",&GUI_StartUp); + sdl_sec->Add_bool("FULLSCREEN",false); + /* Init all the dosbox subsystems */ + DOSBOX_Init(); + std::string config_file; + if (control->cmdline->FindString("-conf",config_file,true)) { + + } else { + config_file="dosbox.conf"; + } + /* Parse the config file */ + control->ParseConfigFile(config_file.c_str()); + /* Init all the sections */ + control->Init(); + /* Some extra SDL Functions */ #ifndef DISABLE_JOYSTICK - if (SDL_NumJoysticks()>0) { - SDL_JoystickEventState(SDL_ENABLE); - sdl.joy=SDL_JoystickOpen(0); - LOG_MSG("Using joystick %s with %d axes and %d buttons",SDL_JoystickName(0),SDL_JoystickNumAxes(sdl.joy),SDL_JoystickNumButtons(sdl.joy)); - JOYSTICK_Enable(0,true); - } -#endif - /* Start dosbox up */ - DOSBOX_StartUp(); - } - catch (Bitu e) { - LOG_MSG("Exit to error %d",e); + if (SDL_NumJoysticks()>0) { + SDL_JoystickEventState(SDL_ENABLE); + sdl.joy=SDL_JoystickOpen(0); + LOG_MSG("Using joystick %s with %d axes and %d buttons",SDL_JoystickName(0),SDL_JoystickNumAxes(sdl.joy),SDL_JoystickNumButtons(sdl.joy)); + JOYSTICK_Enable(0,true); + } +#endif + if (control->cmdline->FindExist("-fullscreen")) { + sdl.full_screen=true; + } else { + sdl.full_screen=sdl_sec->Get_bool("FULLSCREEN"); + } + if (sdl.full_screen) { + sdl.full_screen=false; + SwitchFullScreen(); + } + + + /* Start up main machine */ + control->StartUp(); + /* Shutdown everything */ + } catch (char * error) { + LOG_ERROR("Exit to error %s",error); } GFX_Stop(); - - - return 0; }; \ No newline at end of file From b778104885fae51ed97769ed2c5c453429c1e0e9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 18 Sep 2002 16:35:34 +0000 Subject: [PATCH 0221/4131] Shell now is the StartUp handler for when dos is active Added Autoexec_init which parses the command line for -c commands and the first command on the command line to automount that. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@298 --- src/shell/shell.cpp | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 62000851..f9247a77 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -19,7 +19,7 @@ #include #include - +#include "setup.h" #include "shell_inc.h" Bitu call_shellstop; @@ -132,6 +132,45 @@ void DOS_Shell::SyntaxError(void) { +void AUTOEXEC_Init(Section * sec) { + /* Register a virtual AUOEXEC.BAT file */ + + Section_line * section=static_cast(sec); + SHELL_AddAutoexec("SET PATH=Z:\\"); + SHELL_AddAutoexec("SET COMSPEC=Z:\\COMMAND.COM"); + char * extra=(char *)section->data.c_str(); + if (extra) SHELL_AddAutoexec(extra); + /* Check to see for extra command line options to be added */ + std::string line; + while (control->cmdline->FindString("-c",line,true)) { + SHELL_AddAutoexec((char *)line.c_str()); + } + /* Check for first command being a directory or file */ + char buffer[CROSS_LEN]; + if (control->cmdline->FindFirst(line)) { + struct stat test; + strcpy(buffer,line.c_str()); + if (stat(buffer,&test)) { + getcwd(buffer,CROSS_LEN); + strcat(buffer,line.c_str()); + if (stat(buffer,&test)) goto nomount; + } + if (test.st_mode & S_IFDIR) { + SHELL_AddAutoexec("MOUNT C %s",buffer); + SHELL_AddAutoexec("C:"); + } else { + char * name=strrchr(buffer,CROSS_FILESPLIT); + if (!name) goto nomount; + *name++=0; + if (access(buffer,F_OK)) goto nomount; + SHELL_AddAutoexec("MOUNT C %s",buffer); + SHELL_AddAutoexec("C:"); + SHELL_AddAutoexec(name); + } + } +nomount: + VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,strlen(autoexec_data)); +} void SHELL_Init() { call_shellstop=CALLBACK_Allocate(); @@ -171,7 +210,5 @@ void SHELL_Init() { strcpy(line,"/INIT Z:\\AUTOEXEC.BAT"); info.cmd_line=line; -/* Handle the last AUTOEXEC.BAT Setup stuff */ - VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,strlen(autoexec_data)); SHELL_ProgramStart(&info); } From 52f4e4a2fbb05f1a15293e5e4130a0ec39dea912 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 21 Sep 2002 11:08:03 +0000 Subject: [PATCH 0222/4131] fixed possible paramblock memory overwrite in DOS_Execute Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@299 --- src/dos/dos_execute.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 909ff03a..b582a37e 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -198,7 +198,7 @@ static void SetupCMDLine(Bit16u pspseg,ParamBlock * block) psp.SetCommandTail(block->exec.cmdtail); } -bool DOS_Execute(char * name,ParamBlock * block,Bit8u flags) { +bool DOS_Execute(char * name,ParamBlock * _block,Bit8u flags) { EXE_Header head;Bitu i; Bit16u fhandle;Bit16u len;Bit32u pos; Bit16u pspseg,envseg,loadseg,memsize,readsize; @@ -208,6 +208,11 @@ bool DOS_Execute(char * name,ParamBlock * block,Bit8u flags) { if (flags!=LOADNGO && flags!=OVERLAY) { E_Exit("DOS:Not supported execute mode %d for file %s",flags,name); } + + // Parameter block may be overwritten on load, so save these values ! + ParamBlock block; + memcpy(&block,_block,sizeof(ParamBlock)); + /* Check for EXE or COM File */ bool iscom=false; if (!DOS_OpenFile(name,OPEN_READ,&fhandle)) return false; @@ -224,7 +229,7 @@ bool DOS_Execute(char * name,ParamBlock * block,Bit8u flags) { } if (flags!=OVERLAY) { /* Create an environment block */ - envseg=block->exec.envseg; + envseg=block.exec.envseg; if (!MakeEnv(name,&envseg)) { DOS_CloseFile(fhandle); return false; @@ -249,8 +254,8 @@ bool DOS_Execute(char * name,ParamBlock * block,Bit8u flags) { loadseg=pspseg+16; /* Setup a psp */ SetupPSP(pspseg,memsize,envseg); - SetupCMDLine(pspseg,block); - } else loadseg=block->overlay.loadseg,0; + SetupCMDLine(pspseg,&block); + } else loadseg=block.overlay.loadseg,0; /* Load the executable */ loadaddress=HostMake(loadseg,0); if (iscom) { /* COM Load 64k - 256 bytes max */ @@ -270,7 +275,7 @@ bool DOS_Execute(char * name,ParamBlock * block,Bit8u flags) { } /* Relocate the exe image */ Bit16u relocate; - if (flags==OVERLAY) relocate=block->overlay.relocation; + if (flags==OVERLAY) relocate=block.overlay.relocation; else relocate=loadseg; pos=head.reloctable;DOS_SeekFile(fhandle,&pos,0); for (i=0;iexec.fcb1); - newpsp.SetFCB2(block->exec.fcb2); + newpsp.SetFCB1(block.exec.fcb1); + newpsp.SetFCB2(block.exec.fcb2); /* Set the stack for new program */ SegSet16(ss,RealSeg(sssp));reg_sp=RealOff(sssp); /* Add some flags and CS:IP on the stack for the IRET */ From c35855909ea49cca05fb471fa805c54960667a7d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 24 Sep 2002 21:48:18 +0000 Subject: [PATCH 0223/4131] Report correct value for people requesting memory allocation strategy. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@300 --- src/dos/dos.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index eca9250c..fae5778c 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -704,7 +704,15 @@ static Bitu DOS_21Handler(void) { LOG_DEBUG("DOS:57:Getting/Setting File Date is faked",reg_ah); break; case 0x58: /* Get/Set Memory allocation strategy */ - LOG_DEBUG("DOS:58:Not Supported Set//Get memory allocation"); + switch (reg_al) { + case 0: /* Get Strategy */ + reg_ax=0; //Low memory first fit + break; + case 1: /* Set Strategy */ + break; + default: + LOG_DEBUG("DOS:58:Not Supported Set//Get memory allocation call %X",reg_al); + } break; case 0x59: /* Get Extended error information */ reg_ax=dos.errorcode; From 3b7889413aebb15fde5f9bd6e8b0541d31303120 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 24 Sep 2002 21:48:51 +0000 Subject: [PATCH 0224/4131] FindFirst and FindNext didn't report an error code when they didn't find a file. Fixed now Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@301 --- src/dos/dos_files.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index e159aa34..9f75672d 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -52,12 +52,11 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { /* First get the drive */ if (name[1]==':') { *drive=(name[0] | 0x20)-'a'; - if (*drive=DOS_DRIVES || !Drives[*drive]) { + DOS_SetError(DOSERR_PATH_NOT_FOUND); + return false; } r=0;w=0; while (name[r]!=0 && (rRename(fullold,fullnew)) return true; DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; -}; +} bool DOS_FindFirst(char * search,Bit16u attr) { Bit8u drive;char fullsearch[DOS_PATHLENGTH]; @@ -186,13 +185,17 @@ bool DOS_FindFirst(char * search,Bit16u attr) { DTA_FindBlock * dtablock=(DTA_FindBlock *)Real2Host(dos.dta); dtablock->sattr=attr | DOS_ATTR_ARCHIVE; dtablock->sdrive=drive; - return Drives[drive]->FindFirst(fullsearch,dtablock); -}; + if (Drives[drive]->FindFirst(fullsearch,dtablock)) return true; + DOS_SetError(DOSERR_FILE_NOT_FOUND); + return false; +} bool DOS_FindNext(void) { DTA_FindBlock * dtablock=(DTA_FindBlock *)Real2Host(dos.dta); - return Drives[dtablock->sdrive]->FindNext(dtablock); -}; + if (Drives[dtablock->sdrive]->FindNext(dtablock)) return true; + DOS_SetError(DOSERR_FILE_NOT_FOUND); + return false; +} bool DOS_ReadFile(Bit16u entry,Bit8u * data,Bit16u * amount) { @@ -376,7 +379,7 @@ bool DOS_Canonicalize(char * name,char * big) { big[2]='\\'; strcpy(&big[3],fullname); return true; -}; +} bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free) { if (drive==0) drive=DOS_GetDefaultDrive(); From 90dc9815bd9fb9147f476cd17921bc85912c8b3a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 25 Sep 2002 12:09:41 +0000 Subject: [PATCH 0225/4131] fixed the scope of Bitu i Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@302 --- src/dos/dos_classes.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 73b2911a..c59045a7 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -196,8 +196,9 @@ void DOS_PSP::MakeNew(Bit16u mem_size) { /* get previous */ DOS_PSP prevpsp(dos.psp); - /* Clear it first */ - for (Bitu i=0;i Date: Thu, 26 Sep 2002 18:20:01 +0000 Subject: [PATCH 0226/4131] fixed a memory leak Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@303 --- src/dos/dos_files.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 9f75672d..2e4bc33b 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -650,6 +650,7 @@ bool DOS_FCBFindFirst(Bit16u seg,Bit16u offset) fcbout->Set_drive(drive +1); fcbout->Set_filename(naam); fcbout->Set_ext(ext); + delete fcbout; return true; } @@ -689,6 +690,7 @@ bool DOS_FCBFindNext(Bit16u seg,Bit16u offset) fcbout->Set_drive(drive +1); fcbout->Set_filename(naam); fcbout->Set_ext(ext); + delete fcbout; return true; } From 6009e11726c0171fc3de8832932266187e1c2860 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 26 Sep 2002 18:22:53 +0000 Subject: [PATCH 0227/4131] made findfirst use CROSS_FILESPLIT instead of "/" Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@304 --- src/dos/drive_local.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 1d787502..9bc8c98e 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -106,7 +106,7 @@ bool localDrive::FindFirst(char * search,DTA_FindBlock * dta) { strcpy(directory,name); /* make sure / is last sign */ if (pdir) closedir(pdir); - if(directory[(strlen(directory)-1)]!=CROSS_FILESPLIT) strcat(directory, "/"); + if(directory[(strlen(directory)-1)]!=CROSS_FILESPLIT) strcat(directory, CROSS_FILESPLIT); if((pdir=opendir(directory))==NULL) return false; return FindNext(dta); } From 2d1ccb90481e3606c92a481a760b7d3696f72211 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 27 Sep 2002 12:36:53 +0000 Subject: [PATCH 0228/4131] fixed a mistake Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@305 --- src/dos/drive_local.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 9bc8c98e..3b904307 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -106,7 +106,8 @@ bool localDrive::FindFirst(char * search,DTA_FindBlock * dta) { strcpy(directory,name); /* make sure / is last sign */ if (pdir) closedir(pdir); - if(directory[(strlen(directory)-1)]!=CROSS_FILESPLIT) strcat(directory, CROSS_FILESPLIT); + char argh=CROSS_FILESPLIT; + if(directory[(strlen(directory)-1)]!=CROSS_FILESPLIT) strcat(directory, &argh); if((pdir=opendir(directory))==NULL) return false; return FindNext(dta); } From 619a6913103c1485e28834b64796a64a0e1b0c2c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 28 Sep 2002 21:29:57 +0000 Subject: [PATCH 0229/4131] Added CGA and EGA putpixel with xorring and VGA putpixel. Also added a getpixel for CGA,EGA and VGA. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@306 --- src/ints/int10_put_pixel.cpp | 55 +++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 74fd6fdd..eb425c04 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -21,12 +21,6 @@ #include "inout.h" #include "int10.h" -union VGA_Memory { - Bit8u linear[64*1024*4]; - Bit8u paged[64*1024][4]; -}; -extern VGA_Memory vga_mem; - static Bit8u cga_masks[4]={~192,~48,~12,~3}; void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { @@ -39,7 +33,12 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { Bit16u off=(y>>1)*80+(x>>2); if (y&1) off+=8*1024; Bit8u old=real_readb(0xb800,off); - old=old&cga_masks[x&3]|((color&3) << (2*(3-(x&3)))); + if (color & 0x80) { + color&=3; + old^=color << (2*(3-(x&3))); + } else { + old=old&cga_masks[x&3]|((color&3) << (2*(3-(x&3)))); + } real_writeb(0xb800,off,old); } break; @@ -51,20 +50,27 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { IO_Write(0x3ce,0x0);IO_Write(0x3cf,color); /* Enable all the set/resets */ IO_Write(0x3ce,0x1);IO_Write(0x3cf,0xf); + /* test for xorring */ + if (color & 0x80) { IO_Write(0x3ce,0x3);IO_Write(0x3cf,0x18); } //Perhaps also set mode 1 /* Calculate where the pixel is in video memory */ - Bit16u base_address=((((curmode->sheight*curmode->swidth)>>3)|0xff)+1)*page; - PhysPt off=0xa0000+base_address+((y*curmode->swidth+x)>>3); + PhysPt off=0xa0000+curmode->slength*page+((y*curmode->swidth+x)>>3); /* Bitmask and set/reset should do the rest */ mem_readb(off); mem_writeb(off,0xff); + /* Restore bitmask */ + IO_Write(0x3ce,0x8);IO_Write(0x3cf,0xff); + /* Restore write operating if changed */ + if (color & 0x80) { IO_Write(0x3ce,0x3);IO_Write(0x3cf,0x0); } break; } - case CTEXT: - case MTEXT: + case LINEAR8: + mem_writeb(Real2Phys(RealMake(0xa000,y*320+x)),color); + break; case PLANAR1: case PLANAR2: - case LINEAR8: + case CTEXT: + case MTEXT: default: LOG_WARN("INT10:PutPixel Unhanled memory model"); break; @@ -72,7 +78,6 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { } void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { - VGAMODES * curmode=GetCurrentMode(); switch (curmode->memmodel) { case CGA: @@ -83,6 +88,30 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { *color=val<<((x&3)*2); } break; + case PLANAR4: + { + /* Calculate where the pixel is in video memory */ + PhysPt off=0xa0000+curmode->slength*page+((y*curmode->swidth+x)>>3); + Bitu shift=7-(x & 7); + /* Set the read map */ + *color=0; + IO_Write(0x3ce,0x4);IO_Write(0x3cf,0); + *color|=((mem_readb(off)>>shift) & 1) << 0; + IO_Write(0x3ce,0x4);IO_Write(0x3cf,1); + *color|=((mem_readb(off)>>shift) & 1) << 1; + IO_Write(0x3ce,0x4);IO_Write(0x3cf,2); + *color|=((mem_readb(off)>>shift) & 1) << 2; + IO_Write(0x3ce,0x4);IO_Write(0x3cf,3); + *color|=((mem_readb(off)>>shift) & 1) << 3; + break; + } + case LINEAR8: + *color=mem_readb(PhysMake(0xa000,320*y+x)); + break; + case PLANAR1: + case PLANAR2: + case CTEXT: + case MTEXT: default: LOG_WARN("INT10:GetPixel Unhanled memory model"); break; From 061aaeaa6c224dae0b13c9a00d43fa6c6402c436 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 28 Sep 2002 21:40:58 +0000 Subject: [PATCH 0230/4131] Updated to use GCC_ATTRIBUTE for packed structure Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@307 --- src/ints/int10_misc.cpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 953b16bb..2ec9f019 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -23,9 +23,7 @@ -#if defined (_MSC_VER) #pragma pack(1) -#endif struct Dynamic_Functionality { RealPt static_table; /* 00h DWORD address of static functionality table */ Bit8u cur_mode; /* 04h BYTE video mode in effect */ @@ -70,19 +68,10 @@ struct Dynamic_Functionality { 7 reserved */ Bit8u reserved2[13]; /* 33h 13 BYTEs reserved (00h) */ -} -#if defined (_MSC_VER) -; +} GCC_ATTRIBUTE(packed); #pragma pack() -#else -__attribute__ ((packed)); -#endif - - void INT10_GetFuncStateInformation(PhysPt save) { - - /* set static state pointer */ mem_writed(save,int10_romarea.static_state); /* Copy BIOS Segment areas */ From 3df0c719f28b58c6ee98aae848f03dd1b6ea3b33 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 29 Sep 2002 13:57:26 +0000 Subject: [PATCH 0231/4131] Changed Program Class, now supports the new command line class. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@308 --- include/programs.h | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/include/programs.h b/include/programs.h index 8151ce5b..80addf11 100644 --- a/include/programs.h +++ b/include/programs.h @@ -18,32 +18,30 @@ #ifndef __PROGRAM_H #define __PROGRAM_H -#include -#include +#include "dosbox.h" +#include "dos_inc.h" +#include "setup.h" char * MSG_Get(char * msg); +class Program; -struct PROGRAM_Info { - Bit16u psp_seg; - sPSP psp_copy; - char full_name[32]; //Enough space for programs only on the z:\ drive - char * cmd_line; -}; - -typedef void (PROGRAMS_Main)(PROGRAM_Info * info); +typedef void (PROGRAMS_Main)(Program * * make); void PROGRAMS_MakeFile(char * name,PROGRAMS_Main * main); class Program { public: - Program(PROGRAM_Info * program_info); + Program(); + virtual ~Program(){} + std::string temp_line; + CommandLine * cmd; + DOS_PSP * psp; virtual void Run(void)=0; char * GetEnvStr(char * env_entry); char * GetEnvNum(Bit32u num); Bit32u GetEnvCount(void); bool SetEnv(char * env_entry,char * new_string); void WriteOut(char * format,...); /* Write to standard output */ - PROGRAM_Info * prog_info; }; From a883462e2275d8cc02b77a630706880b2ce1eb9a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 29 Sep 2002 13:58:39 +0000 Subject: [PATCH 0232/4131] Added some new functions to commandline class Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@309 --- include/setup.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/setup.h b/include/setup.h index 95fa2f03..0925b1de 100644 --- a/include/setup.h +++ b/include/setup.h @@ -35,8 +35,9 @@ public: bool FindHex(char * name,int & value,bool remove=false); bool FindInt(char * name,int & value,bool remove=false); bool FindString(char * name,std::string & value,bool remove=false); - - bool FindFirst(std::string & value); + bool FindCommand(int which,std::string & value); + bool FindStringBegin(char * begin,std::string & value, bool remove=false); + int GetCount(void); private: typedef std::list::iterator cmd_it; std::list cmds; From 765726f755bf6758534720dff30d1a822245cd5d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 29 Sep 2002 13:59:46 +0000 Subject: [PATCH 0233/4131] Addes some new functions to commandline class. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@310 --- src/misc/setup.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index c66e9682..01fa0d1f 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -233,9 +233,12 @@ bool CommandLine::FindString(char * name,std::string & value,bool remove) { return true; } -bool CommandLine::FindFirst(std::string & value) { - if (cmds.empty()) return false; - value=*cmds.begin(); +bool CommandLine::FindCommand(int which,std::string & value) { + if (which<1) return false; + if (which>cmds.size()) return false; + cmd_it it=cmds.begin(); + for (;which>1;which--) it++; + value=(*it); return true; } @@ -250,6 +253,24 @@ bool CommandLine::FindEntry(char * name,cmd_it & it,bool neednext) { return false; } +bool CommandLine::FindStringBegin(char * begin,std::string & value, bool remove) { + cmd_it it; + for (it=cmds.begin();it!=cmds.end();it++) { + if (strncmp(begin,(*it).c_str(),strlen(begin))==0) { + value=((*it).c_str()+strlen(begin)); + return true; + } + } + return false; + + + +} + +int CommandLine::GetCount(void) { + return cmds.size(); +} + CommandLine::CommandLine(int argc,char * argv[]) { if (argc>0) { file_name=argv[0]; From 3ca2bc8d79e7612e7c48fac547e4e81f3d9e8710 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 29 Sep 2002 14:01:11 +0000 Subject: [PATCH 0234/4131] Updated the Program class to support the psp and commandline class. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@311 --- src/misc/programs.cpp | 60 ++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index e170ebbe..85be35a0 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -25,6 +25,7 @@ #include "regs.h" #include "support.h" #include "cross.h" +#include "setup.h" Bitu call_program; @@ -55,30 +56,19 @@ void PROGRAMS_MakeFile(char * name,PROGRAMS_Main * main) { } + static Bitu PROGRAMS_Handler(void) { /* This sets up everything for a program start up call */ - /* First get the current psp */ - PROGRAM_Info * info=new PROGRAM_Info; - info->psp_seg=dos.psp; - MEM_BlockRead(PhysMake(dos.psp,0),&info->psp_copy,sizeof(sPSP)); - /* Get the file name cmd_line 0 */ - PhysPt envblock=PhysMake(info->psp_copy.environment,0); - do {} while (mem_readw(envblock++)); - envblock+=3; - MEM_StrCopy(envblock,info->full_name,32); - info->psp_copy.cmdtail.buffer[info->psp_copy.cmdtail.count]=0; - info->cmd_line=info->psp_copy.cmdtail.buffer; - /* Find the program handler somewhere reference in the file */ - Bit16u handle; - DOS_OpenFile(info->full_name,0,&handle); - Bit32u pos=sizeof(PROGRAMS_Main *); - DOS_SeekFile(handle,&pos,DOS_SEEK_END); - PROGRAMS_Main * handler; - Bit16u size=sizeof(PROGRAMS_Main *); - DOS_ReadFile(handle,(Bit8u *)&handler,&size); - DOS_CloseFile(handle); - (*handler)(info); - free(info); + PROGRAMS_Main * handler=0; //It will get sneakily itinialized + Bitu size=sizeof(PROGRAMS_Main *); + /* Read the handler from program code in memory */ + PhysPt reader=PhysMake(dos.psp,256+sizeof(exe_block)); + HostPt writer=(HostPt)&handler; + for (;size>0;size--) *writer++=mem_readb(reader++); + Program * new_program; + (*handler)(&new_program); + new_program->Run(); + delete new_program; return CBRET_NONE; }; @@ -86,8 +76,20 @@ static Bitu PROGRAMS_Handler(void) { /* Main functions used in all program */ -Program::Program(PROGRAM_Info * program_info) { - prog_info=program_info; +Program::Program() { + /* Find the command line and setup the PSP */ + + + psp = new DOS_PSP(dos.psp); + /* Scan environment for filename */ + char * envscan=(char *)HostMake(psp->GetEnvironment(),0); + while (*envscan) envscan+=strlen(envscan)+1; + envscan+=3; + CommandTail tail; + MEM_BlockRead(PhysMake(dos.psp,128),&tail,128); + if (tail.count<127) tail.buffer[tail.count]=0; + else tail.buffer[126]=0; + cmd = new CommandLine(envscan,tail.buffer); } void Program::WriteOut(char * format,...) { @@ -107,7 +109,7 @@ char * Program::GetEnvStr(char * env_str) { /* Walk through the internal environment and see for a match */ /* Taking some short cuts here to not fuck around with memory structure */ - char * envstart=(char *)HostMake(prog_info->psp_copy.environment,0); + char * envstart=(char *)HostMake(psp->GetEnvironment(),0); size_t len=strlen(env_str); while (*envstart) { if (strncasecmp(env_str,envstart,len)==0 && envstart[len]=='=') { @@ -119,7 +121,7 @@ char * Program::GetEnvStr(char * env_str) { }; char * Program::GetEnvNum(Bit32u num) { - char * envstart=(char *)HostMake(prog_info->psp_copy.environment,0); + char * envstart=(char *)HostMake(psp->GetEnvironment(),0); while (*envstart) { if (!num) return envstart; envstart+=strlen(envstart)+1; @@ -129,7 +131,7 @@ char * Program::GetEnvNum(Bit32u num) { } Bit32u Program::GetEnvCount(void) { - char * envstart=(char *)HostMake(prog_info->psp_copy.environment,0); + char * envstart=(char *)HostMake(psp->GetEnvironment(),0); Bit32u num=0; while (*envstart) { envstart+=strlen(envstart)+1; @@ -139,13 +141,13 @@ Bit32u Program::GetEnvCount(void) { } bool Program::SetEnv(char * env_entry,char * new_string) { - MCB * env_mcb=(MCB *)HostMake(prog_info->psp_copy.environment-1,0); + MCB * env_mcb=(MCB *)HostMake(psp->GetEnvironment()-1,0); upcase(env_entry); Bit32u env_size=env_mcb->size*16; if (!env_size) E_Exit("SHELL:Illegal environment size"); /* First try to find the old entry */ size_t len=strlen(env_entry); - char * envstart=(char *)HostMake(prog_info->psp_copy.environment,0); + char * envstart=(char *)HostMake(psp->GetEnvironment(),0); while (*envstart) { if (strncasecmp(env_entry,envstart,len)==0 && envstart[len]=='=') { /* Now remove this entry */ From 43a846dc11de1a70c4f8a39b7bcc70ca599352ff Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 29 Sep 2002 14:03:05 +0000 Subject: [PATCH 0235/4131] Updated the dos programs to work with the new program class. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@312 --- src/dos/dos_programs.cpp | 97 +++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 55 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 17c7878f..d110b86c 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -28,11 +28,13 @@ class MOUNT : public Program { public: - MOUNT(PROGRAM_Info * program_info):Program(program_info){}; - void Run(void){ + void Run(void) + { + DOS_Drive * newdrive;char drive; + /* Parse the command line */ /* if the command line is empty show current mounts */ - if (!*prog_info->cmd_line) { + if (!cmd->GetCount()) { WriteOut("Current mounted drives are\n"); for (int d=0;dcmd_line); - char drive; drive=toupper(*line); - - char * dir=strchr(line,' '); if (dir) { - if (!*dir) dir=0; - else dir=trim(dir); - } - if (!isalpha(drive) || !dir) { - WriteOut("Usage MOUNT Drive-Letter Local-Directory\nSo a MOUNT c c:\\windows mounts windows directory as the c: drive in DOSBox\n"); - return; - }; + cmd->FindCommand(1,temp_line); + if (temp_line.size()>1) goto showusage; + drive=toupper(temp_line[0]); + if (!isalpha(drive)) goto showusage; + if (!cmd->FindCommand(2,temp_line)) goto showusage; + if (!temp_line.size()) goto showusage; struct stat test; - if (stat(dir,&test)) { - WriteOut("Directory %s Doesn't exist",dir); + if (stat(temp_line.c_str(),&test)) { + WriteOut("Directory %s Doesn't exist",temp_line.c_str()); return; } /* Not a switch so a normal directory/file */ if (!(test.st_mode & S_IFDIR)) { - WriteOut("%s isn't a directory",dir); + WriteOut("%s isn't a directory",temp_line.c_str()); return; } if (Drives[drive-'A']) { WriteOut("Drive %c already mounted with %s\n",drive,Drives[drive-'A']->GetInfo()); return; } - char fulldir[DOS_PATHLENGTH]; - strcpy(fulldir,dir); - static char theend[2]={CROSS_FILESPLIT,0}; - char * last=strrchr(fulldir,CROSS_FILESPLIT); - if (!last || *(++last)) strcat(fulldir,theend); - Drives[drive-'A']=new localDrive(fulldir); - WriteOut("Mounting drive %c as %s\n",drive,fulldir); + if (temp_line[temp_line.size()-1]!=CROSS_FILESPLIT) temp_line+=CROSS_FILESPLIT; + newdrive=new localDrive((char *)temp_line.c_str()); + if (!newdrive) E_Exit("DOS:Can't create drive"); + Drives[drive-'A']=newdrive; + /* Set the correct media byte in the table */ + mem_writeb(Real2Phys(dos.tables.mediaid)+drive-'A',newdrive->GetMediaByte()); + WriteOut("Mounting drive %c as %s\n",drive,temp_line.c_str()); + return; +showusage: + WriteOut("Usage MOUNT Drive-Letter Local-Directory\nSo a MOUNT c c:\\windows mounts windows directory as the c: drive in DOSBox\n"); + return; } }; -static void MOUNT_ProgramStart(PROGRAM_Info * info) { - MOUNT * tempmount=new MOUNT(info); - tempmount->Run() ; - delete tempmount; +static void MOUNT_ProgramStart(Program * * make) { + *make=new MOUNT; } class MEM : public Program { public: - MEM(PROGRAM_Info * program_info):Program(program_info){}; void Run(void) { /* Show conventional Memory */ WriteOut("\n"); @@ -115,28 +112,20 @@ public: }; - -static void MEM_ProgramStart(PROGRAM_Info * info) { - MEM mem(info); - mem.Run(); +static void MEM_ProgramStart(Program * * make) { + *make=new MEM; } #if !defined (WIN32) /* Unix */ + class UPCASE : public Program { public: - UPCASE(PROGRAM_Info * program_info); void Run(void); - void upcasedir(char * directory); + void upcasedir(const char * directory); }; - -UPCASE::UPCASE(PROGRAM_Info * info):Program(info) { - -} - - -void UPCASE::upcasedir(char * directory) { +void UPCASE::upcasedir(const char * directory) { DIR * sdir; char fullname[512]; char newname[512]; @@ -173,42 +162,40 @@ void UPCASE::Run(void) { /* First check if the directory exists */ struct stat info; WriteOut("UPCASE 0.1 Directory case convertor.\n"); - if (!strlen(prog_info->cmd_line)) { + if (!cmd->GetCount()) { WriteOut("Usage UPCASE [local directory]\n"); WriteOut("This tool will convert all files and subdirectories in a directory.\n"); WriteOut("Be VERY sure this directory contains only dos related material.\n"); WriteOut("Otherwise you might horribly screw up your filesystem.\n"); return; } - char* line=trim(prog_info->cmd_line); - if (stat(line,&info)) { - WriteOut("%s doesn't exist\n",line); + cmd->FindCommand(1,temp_line); + if (stat(temp_line.c_str(),&info)) { + WriteOut("%s doesn't exist\n",temp_line.c_str()); return; } if(!S_ISDIR(info.st_mode)) { - WriteOut("%s isn't a directory\n",line); + WriteOut("%s isn't a directory\n",temp_line.c_str()); return; } WriteOut("Converting the wrong directories can be very harmfull, please be carefull.\n"); - WriteOut("Are you really really sure you want to convert %s to upcase?Y/N\n",line); + WriteOut("Are you really really sure you want to convert %s to upcase?Y/N\n",temp_line.c_str()); Bit8u key;Bit16u n=1; DOS_ReadFile(STDIN,&key,&n); if (toupper(key)=='Y') { - upcasedir(line); + upcasedir(temp_line.c_str()); } else { WriteOut("Okay better not do it.\n"); } } -static void UPCASE_ProgramStart(PROGRAM_Info * info) { - UPCASE * tempUPCASE=new UPCASE(info); - tempUPCASE->Run(); - delete tempUPCASE; +static void UPCASE_ProgramStart(Program * * make) { + *make=new UPCASE; } - #endif void DOS_SetupPrograms(void) { + PROGRAMS_MakeFile("MOUNT.COM",MOUNT_ProgramStart); PROGRAMS_MakeFile("MEM.COM",MEM_ProgramStart); #if !defined (WIN32) /* Unix */ From 851ecbe172013d3e40eb9a6f83396834f5425191 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 29 Sep 2002 14:07:38 +0000 Subject: [PATCH 0236/4131] Update Shell to use the new program class. Also use a new way to start up the shell and setting up the environment segment. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@313 --- src/shell/shell.cpp | 77 ++++++++++++++++++++++++---------------- src/shell/shell_cmds.cpp | 7 ++-- src/shell/shell_inc.h | 3 +- src/shell/shell_misc.cpp | 11 ++---- 4 files changed, 53 insertions(+), 45 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index f9247a77..4ae9f881 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -28,10 +28,8 @@ static Bitu shellstop_handler(void) { return CBRET_STOP; } -static void SHELL_ProgramStart(PROGRAM_Info * info) { - DOS_Shell * tempshell=new DOS_Shell(info); - tempshell->Run(); - delete tempshell; +static void SHELL_ProgramStart(Program * * make) { + *make=new DOS_Shell; } #define AUTOEXEC_SIZE 4096 @@ -53,7 +51,7 @@ void SHELL_AddAutoexec(char * line,...) { } -DOS_Shell::DOS_Shell(PROGRAM_Info * info):Program(info) { +DOS_Shell::DOS_Shell():Program(){ input_handle=STDIN; echo=true; exit=false; @@ -96,16 +94,19 @@ void DOS_Shell::ParseLine(char * line) { void DOS_Shell::Run(void) { - /* Check for a direct Command */ - if (strncasecmp(prog_info->cmd_line,"/C ",3)==0) { - ParseLine(prog_info->cmd_line+3); + char input_line[CMD_MAXLINE]; + std::string line; + if (cmd->FindString("/C",line,true)) { + strcpy(input_line,line.c_str()); + line.erase(); return; } /* Start a normal shell and check for a first command init */ WriteOut(MSG_Get("SHELL_STARTUP")); - char input_line[CMD_MAXLINE]; - if (strncasecmp(prog_info->cmd_line,"/INIT ",6)==0) { - ParseLine(prog_info->cmd_line+6); + if (cmd->FindString("/INIT",line,true)) { + strcpy(input_line,line.c_str()); + line.erase(); + ParseLine(input_line); } do { if (bf && bf->ReadLine(input_line)) { @@ -136,8 +137,6 @@ void AUTOEXEC_Init(Section * sec) { /* Register a virtual AUOEXEC.BAT file */ Section_line * section=static_cast(sec); - SHELL_AddAutoexec("SET PATH=Z:\\"); - SHELL_AddAutoexec("SET COMSPEC=Z:\\COMMAND.COM"); char * extra=(char *)section->data.c_str(); if (extra) SHELL_AddAutoexec(extra); /* Check to see for extra command line options to be added */ @@ -147,7 +146,7 @@ void AUTOEXEC_Init(Section * sec) { } /* Check for first command being a directory or file */ char buffer[CROSS_LEN]; - if (control->cmdline->FindFirst(line)) { + if (control->cmdline->FindCommand(1,line)) { struct stat test; strcpy(buffer,line.c_str()); if (stat(buffer,&test)) { @@ -172,23 +171,39 @@ nomount: VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,strlen(autoexec_data)); } +static char * path_string="PATH=Z:\\"; +static char * comspec_string="COMSPEC=Z:\\COMMAND.COM"; +static char * full_name="Z:\\COMMAND.COM"; +static char * init_line="/INIT AUTOEXEC.BAT"; + void SHELL_Init() { + call_shellstop=CALLBACK_Allocate(); CALLBACK_Setup(call_shellstop,shellstop_handler,CB_IRET); PROGRAMS_MakeFile("COMMAND.COM",SHELL_ProgramStart); + /* Now call up the shell for the first time */ - Bit16u psp_seg=DOS_GetMemory(16); - Bit16u env_seg=DOS_GetMemory(1+(4096/16)); + Bit16u psp_seg=DOS_GetMemory(16+1)+1; + Bit16u env_seg=DOS_GetMemory(1+(4096/16))+1; Bit16u stack_seg=DOS_GetMemory(2048/16); SegSet16(ss,stack_seg); reg_sp=2046; - /* Setup a fake MCB for the environment */ - MCB * env_mcb=(MCB *)HostMake(env_seg,0); + /* Setup MCB and the environment */ + MCB * env_mcb=(MCB *)HostMake(env_seg-1,0); env_mcb->psp_segment=psp_seg; env_mcb->size=4096/16; - real_writed(env_seg+1,0,0); + PhysPt env_write=PhysMake(env_seg,0); + MEM_BlockWrite(env_write,path_string,strlen(path_string)+1); + env_write+=strlen(path_string)+1; + MEM_BlockWrite(env_write,comspec_string,strlen(comspec_string)+1); + env_write+=strlen(comspec_string)+1; + mem_writeb(env_write++,0); + mem_writew(env_write,1); + env_write+=2; + MEM_BlockWrite(env_write,full_name,strlen(full_name)+1); - DOS_PSP psp(psp_seg); psp.MakeNew(env_mcb->size); + DOS_PSP psp(psp_seg); + psp.MakeNew(0); psp.SetFileHandle(STDIN ,DOS_FindDevice("CON")); psp.SetFileHandle(STDOUT,DOS_FindDevice("CON")); psp.SetFileHandle(STDERR,DOS_FindDevice("CON")); @@ -196,19 +211,19 @@ void SHELL_Init() { psp.SetFileHandle(STDNUL,DOS_FindDevice("CON")); psp.SetFileHandle(STDPRN,DOS_FindDevice("CON")); psp.SetParent(psp_seg); - /* Set the environment and clear it */ - psp.SetEnvironment(env_seg+1); - mem_writew(Real2Phys(RealMake(env_seg+1,0)),0); + /* Set the environment */ + psp.SetEnvironment(env_seg); + /* Set the command line for the shell start up */ + CommandTail tail; + tail.count=strlen(init_line); + strcpy(tail.buffer,init_line); + MEM_BlockWrite(PhysMake(psp_seg,128),&tail,128); /* Setup internal DOS Variables */ dos.dta=psp.GetDTA(); dos.psp=psp_seg; - PROGRAM_Info info; - strcpy(info.full_name,"Z:\\COMMAND.COM"); - info.psp_seg=psp_seg; - MEM_BlockRead(PhysMake(dos.psp,0),&info.psp_copy,sizeof(sPSP)); - char line[256]; - strcpy(line,"/INIT Z:\\AUTOEXEC.BAT"); - info.cmd_line=line; - SHELL_ProgramStart(&info); + Program * new_program; + SHELL_ProgramStart(&new_program); + new_program->Run(); + delete new_program; } diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index aeb5a441..7e5f39d4 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -65,9 +65,8 @@ void DOS_Shell::DoCommand(char * line) { Bit32u cmd_index=0; while (cmd_list[cmd_index].name) { if (strcasecmp(cmd_list[cmd_index].name,cmd)==0) { -//TODO CHECK Flags (this->*(cmd_list[cmd_index].handler))(line); - return; + return; } cmd_index++; } @@ -202,16 +201,14 @@ void DOS_Shell::CMD_DIR(char * args) { WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); return; } - while (ret) { - /* File name and extension */ char * ext=""; if (!optW && (*dta->name != '.')) { ext = strrchr(dta->name, '.'); if (!ext) ext = ""; else *ext++ = '\0'; - }; + } Bit8u day = dta->date & 0x001f; Bit8u month = (dta->date >> 5) & 0x000f; diff --git a/src/shell/shell_inc.h b/src/shell/shell_inc.h index b44c6134..9f76040d 100644 --- a/src/shell/shell_inc.h +++ b/src/shell/shell_inc.h @@ -24,6 +24,7 @@ #include "regs.h" #include "support.h" #include "callback.h" +#include "setup.h" #define CMD_MAXLINE 4096 #define CMD_MAXCMDS 20 @@ -52,7 +53,7 @@ public: class DOS_Shell : public Program { public: - DOS_Shell(PROGRAM_Info * program_info); + DOS_Shell(); void Run(void); /* A load of subfunctions */ void ParseLine(char * line); diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index e939b81e..dcc0ab18 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -119,9 +119,6 @@ void DOS_Shell::InputCommand(char * line) { size_t first_len=strlen(old.buffer)+1; memmove(&old.buffer[first_len],&old.buffer[0],CMD_OLDSIZE-first_len); strcpy(old.buffer,line); - - - } void DOS_Shell::Execute(char * name,char * args) { @@ -165,9 +162,9 @@ void DOS_Shell::Execute(char * name,char * args) { cmd.count=strlen(line); memcpy(cmd.buffer,line,strlen(line)); cmd.buffer[strlen(line)]=0xd; - MEM_BlockWrite(PhysMake(prog_info->psp_seg,128),&cmd,128); - - block.InitExec(RealMake(prog_info->psp_seg,128)); + /* Copy command line in stack block too */ + MEM_BlockWrite(SegPhys(ss)+reg_sp+0x100,&cmd,128); + block.InitExec(RealMakeSeg(ss,reg_sp+0x100)); /* Save CS:IP to some point where i can return them from */ RealPt newcsip; newcsip=CALLBACK_RealPointer(call_shellstop); @@ -185,8 +182,6 @@ void DOS_Shell::Execute(char * name,char * args) { CALLBACK_RunRealInt(0x21); reg_sp+=0x200; } - - } From fea2b58d8f7c04837c508e0069706c856958c7d7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 29 Sep 2002 14:12:40 +0000 Subject: [PATCH 0237/4131] Disabled HWSET for the moment Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@314 --- src/hardware/hardware.cpp | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index ed738203..6495fd57 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -30,16 +30,9 @@ static HWBlock * firsthw=0; class HWSET : public Program { public: - HWSET(PROGRAM_Info * program_info); void Run(void); - }; - -HWSET::HWSET(PROGRAM_Info * info):Program(info) { - -} - void HW_Register(HWBlock * block) { block->next=firsthw; firsthw=block; @@ -48,8 +41,8 @@ void HW_Register(HWBlock * block) { void HWSET::Run(void) { /* Hopefull enough space */ +#if 0 char buf[1024]; - HWBlock * loopblock; if (!*prog_info->cmd_line) { /* No command line given give overview of hardware */ @@ -100,18 +93,15 @@ founddev: WriteOut("Command overview for %s\n%s",loopblock->full_name,loopblock->help); } return; +#endif } -static void HWSET_ProgramStart(PROGRAM_Info * info) { - HWSET * tempHWSET=new HWSET(info); - tempHWSET->Run(); - delete tempHWSET; +static void HWSET_ProgramStart(Program * * make) { + *make=new HWSET; } - void HARDWARE_Init(void) { PROGRAMS_MakeFile("HWSET.COM",HWSET_ProgramStart); - }; From 4c8ce66c86b29ce837ce78337e10efc71580c2b7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 15 Oct 2002 22:26:57 +0000 Subject: [PATCH 0238/4131] Protection against overflowing the realsound buffer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@315 --- src/hardware/pcspeaker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 9a94a397..34f06b79 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -56,7 +56,7 @@ void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode) { case 0: if (cntr>72) cntr=72; spkr.realsound=true; - spkr.buffer[spkr.buf_pos++]=(cntr-36)*600; + if (spkr.buf_pos Date: Tue, 15 Oct 2002 22:27:58 +0000 Subject: [PATCH 0239/4131] Fixed counters for 2nd joystick movement. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@316 --- src/hardware/joystick.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index 3b6507dc..a5bd7f88 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -50,8 +50,8 @@ static Bit8u read_p201(Bit32u port) { if (stick[0].button[1]) ret&=32; } if (stick[1].enabled) { - if (stick[1].xcount) stick[0].xcount--; else ret&=~4; - if (stick[1].ycount) stick[0].ycount--; else ret&=~8; + if (stick[1].xcount) stick[1].xcount--; else ret&=~4; + if (stick[1].ycount) stick[1].ycount--; else ret&=~8; if (stick[1].button[0]) ret&=64; if (stick[1].button[1]) ret&=128; } From 56faf852a653562070314897cbe0ce36571be4b5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 16 Oct 2002 14:07:52 +0000 Subject: [PATCH 0240/4131] added support for Warninglevel Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@317 --- include/dosbox.h | 98 ++++++++++++++++++++++++++++++++++++++++++++ settings.h.cvs | 12 ------ src/dosbox.cpp | 5 ++- src/gui/sdlmain.cpp | 4 +- src/misc/support.cpp | 17 ++++---- 5 files changed, 113 insertions(+), 23 deletions(-) diff --git a/include/dosbox.h b/include/dosbox.h index ac7b4f34..b4b109ed 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -60,6 +60,104 @@ void DOSBOX_Init(void); class Config; extern Config * control; +extern Bitu errorlevel; + +inline void LOG_MSG(char* message) +{ + + if(errorlevel>=0) S_Warn(message); +} + +template +inline void LOG_MSG(char* message,type1 arg1) +{ + + if(errorlevel>=0) S_Warn(message,arg1); +} + +template +inline void LOG_MSG(char* message,type1 arg1,type2 arg2) +{ + + if(errorlevel>=0) S_Warn(message,arg1,arg2); +} + +template +inline void LOG_MSG(char* message,type1 arg1,type2 arg2,type3 arg3) +{ + + if (errorlevel>=0)S_Warn(message,arg1,arg2,arg3); +} + +#if C_LOGGING +inline void LOG_DEBUG(char * message) +{ + + if(errorlevel>=2) S_Warn(message); +} + +template +inline void LOG_DEBUG(char * message, type type1) +{ + + if(errorlevel>=2) S_Warn(message,type1); +} + +template +inline void LOG_WARN(char * message, type type1) +{ + + if(errorlevel>=1) S_Warn(message,type1); +} + +inline void LOG_WARN(char* message) +{ + + if(errorlevel>=1) S_Warn(message); +} + +inline void LOG_ERROR(char * message) +{ + + if(errorlevel>=0) S_Warn(message); +} + +template +inline void LOG_ERROR(char * message, type type1) +{ + + if(errorlevel>=0) S_Warn(message,type1); +} + +template +inline void LOG_ERROR(char * message, type1 arg1,type2 arg2) +{ + + if(errorlevel>=0) S_Warn(message,arg1,arg2); +} + +template +inline void LOG_WARN(char * message, type1 arg1,type2 arg2) +{ + + if(errorlevel>=1) S_Warn(message,arg1,arg2); +} + +template +inline void LOG_DEBUG(char * message, type1 arg1,type2 arg2) +{ + + if(errorlevel>=2) S_Warn(message,arg1,arg2); +} + +#else +#define LOG_DEBUG +#define LOG_WARN +#define LOG_ERROR +#endif + + + #endif diff --git a/settings.h.cvs b/settings.h.cvs index b3933b34..3eea7705 100644 --- a/settings.h.cvs +++ b/settings.h.cvs @@ -48,16 +48,4 @@ #define DEBUG_DMA 0 /* DMA Debugging */ #define DEBUG_DOS 0 /* DOS Debugging */ -#define LOG_MSG S_Warn - -#if 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 - #endif diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 4df80388..4a31477c 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -40,7 +40,7 @@ /* NEEDS A CLEANUP */ char dosbox_basedir[CROSS_LEN]; Config * control; - +Bitu errorlevel=1; //during startup display reason for Exits //The whole load of startups for all the subfunctions void MSG_Init(Section_prop *); @@ -132,7 +132,8 @@ void DOSBOX_RunMachine(void){ static void DOSBOX_RealInit(Section * sec) { Section_prop * section=static_cast(sec); /* Initialize some dosbox internals */ - LastTicks=GetTicks(); + errorlevel=section->Get_int("WARNINGS"); + LastTicks=GetTicks(); DOSBOX_SetLoop(&Normal_Loop); MSG_Init(section); } diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 08f4e110..272f9f7f 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -499,8 +499,8 @@ int main(int argc, char* argv[]) { control->StartUp(); /* Shutdown everything */ } catch (char * error) { - LOG_ERROR("Exit to error %s",error); + LOG_ERROR("Exit to error: %s",error); } GFX_Stop(); return 0; -}; \ No newline at end of file +}; diff --git a/src/misc/support.cpp b/src/misc/support.cpp index c9771c65..349b151a 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -214,18 +214,21 @@ void S_Warn(char * format,...) { GFX_ShowMsg(buf); #endif } - +char buf[1024]; //global as else it doesn't always gets thrown right (linux/gcc2.95) void E_Exit(char * format,...) { - char buf[1024]; - +// char buf[1024]; //see above + if(errorlevel>=1){ + va_list msg; - strcpy(buf,"EXIT:"); va_start(msg,format); - vsprintf(buf+strlen(buf),format,msg); + vsprintf(buf,format,msg); va_end(msg); strcat(buf,"\n"); - printf(buf); + } else { + strcpy(buf,"an unsupported feature\n"); + } + throw(buf); -}; \ No newline at end of file +}; From 793cc770fdfc75fbab49a99b64728461899994ae Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 16 Oct 2002 18:37:23 +0000 Subject: [PATCH 0241/4131] added newline at end of file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@318 --- src/shell/shell_cmds.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 7e5f39d4..6d29ae58 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -377,4 +377,5 @@ nextfile: } void DOS_Shell::CMD_REM(char * args) { -} \ No newline at end of file +} + From 07efb3af57d7dd6a9cd60e8ffc42b7af79f29a61 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 16 Oct 2002 18:39:20 +0000 Subject: [PATCH 0242/4131] made the language file internal Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@319 --- src/dosbox.cpp | 2 +- src/dosbox.lang | 74 ------------------------------------------- src/misc/messages.cpp | 67 +++++++++++++++++++++++++-------------- src/misc/programs.cpp | 2 +- src/misc/support.cpp | 2 +- src/shell/shell.cpp | 29 +++++++++++++++-- 6 files changed, 73 insertions(+), 103 deletions(-) delete mode 100644 src/dosbox.lang diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 4a31477c..f67995e3 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -148,7 +148,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("DOSBOX",&DOSBOX_RealInit); - secprop->Add_string("LANGUAGE","dosbox.lang"); + secprop->Add_string("LANGUAGE",""); secprop->Add_int("WARNINGS",0); control->AddSection ("MEMORY",&MEM_Init); diff --git a/src/dosbox.lang b/src/dosbox.lang deleted file mode 100644 index f2ff667b..00000000 --- a/src/dosbox.lang +++ /dev/null @@ -1,74 +0,0 @@ -:SHELL_CMD_HELP -supported commands are: -. -:SHELL_ILLEGAL_SWITCH -Illegal switch: %s -. -:SHELL_CMD_ECHO_ON -ECHO is on -. -:SHELL_CMD_ECHO_OFF -ECHO is off -. -:SHELL_CMD_CHDIR_ERROR -Unable to change to: %s -. -:SHELL_CMD_MKDIR_ERROR -Unable to make: %s -. -:SHELL_CMD_RMDIR_ERROR -Unable to remove: %s -. -:SHELL_SYNTAXERROR -The syntax of the command is incorrect -. -:SHELL_CMD_SET_NOT_SET -Environment variable %s not defined -. -:SHELL_CMD_SET_OUT_OF_SPACE -Not enough environment space left -. -:SHELL_CMD_IF_EXIST_MISSING_FILENAME -IF EXIST: Missing filename -. -:SHELL_CMD_IF_ERRORLEVEL_MISSING_NUMBER -IF ERRORLEVEL: Missing number -. -:SHELL_CMD_IF_ERRORLEVEL_INVALID_NUMBER -IF ERRORLEVEL: Invalid number -. -:SHELL_CMD_GOTO_MISSING_LABEL -No label supplied to GOTO command -. -:SHELL_CMD_GOTO_LABEL_NOT_FOUND -Label %s not found -. -:SHELL_CMD_FILE_NOT_FOUND -File %s not found -. -:SHELL_CMD_DIR_INTRO -Directory of %s -. -:SHELL_CMD_DIR_PATH_ERROR -Illegal Path -. -:SHELL_CMD_DIR_BYTES_USED -%16d File(s) %16s Bytes -. -:SHELL_CMD_DIR_BYTES_FREE -%16d Dir(s) %16s Bytes free -. -:SHELL_STARTUP -DOSBox Shell v0.35 -For Help and supported commands type: HELP - -HAVE FUN! -The DOSBox Team - -. -:SHELL_EXECUTE_DRIVE_NOT_FOUND -Drive %c does not exist! -. -:SHELL_EXECUTE_ILLEGAL_COMMAND -Illegal command: %s -. diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 38ccb700..3ec32ef1 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -23,6 +23,9 @@ #include "cross.h" #include "support.h" #include "setup.h" +#include +#include +using namespace std; @@ -30,15 +33,39 @@ struct MessageBlock { - char * name; - char * string; - MessageBlock * next; + string name; + string val; + MessageBlock(const char* _name, const char* _val): + name(_name),val(_val) + {} }; -static MessageBlock * first_message; +static list Lang; +typedef list::iterator itmb; +void AddMessage(const char * _name, const char* _val) +{ + Lang.push_back(MessageBlock(_name,_val)); +} + +void ReplaceMessage(const char * _name, const char* _val) +{ + //find the message + for(itmb tel=Lang.begin();tel!=Lang.end();tel++) + { + if((*tel).name==_name) + { itmb teln=tel; + teln++; + Lang.erase(tel,teln); + break; + } + } + //even if the message doesn't exist add it + AddMessage(_name,_val); +} static void LoadMessageFile(const char * fname) { - FILE * mfile=fopen(fname,"rb"); + if(*fname=='\0') return;//empty string=no languagefile + FILE * mfile=fopen(fname,"rb"); /* This should never happen and since other modules depend on this use a normal printf */ if (!mfile) { E_Exit("MSG:Can't load messages: %s",fname); @@ -66,15 +93,8 @@ static void LoadMessageFile(const char * fname) { strcpy(name,linein+1); /* End of string marker */ } else if (linein[0]=='.') { - /* Save the string internally */ - size_t total=sizeof(MessageBlock)+strlen(name)+1+strlen(string)+1; - MessageBlock * newblock=(MessageBlock *)malloc(total); - newblock->name=((char *)newblock)+sizeof(MessageBlock); - newblock->string=newblock->name+strlen(name)+1; - strcpy(newblock->name,name); - strcpy(newblock->string,string); - newblock->next=first_message; - first_message=newblock; + /* Replace/Add the string to the internal langaugefile */ + ReplaceMessage(name,string); } else { /* Normal string to be added */ strcat(string,linein); @@ -83,19 +103,20 @@ static void LoadMessageFile(const char * fname) { } fclose(mfile); } - -char * MSG_Get(char * msg) { - MessageBlock * index=first_message; - while (index) { - if (!strcmp(msg,index->name)) return index->string; - index=index->next; - } - return "Message not found"; +const char * MSG_Get(char const * msg) { + for(itmb tel=Lang.begin();tel!=Lang.end();tel++) + { + + if((*tel).name==msg) + { + return (*tel).val.c_str(); + } + } + return "Message not Found!"; } void MSG_Init(Section_prop * section) { /* Load the messages from "dosbox.lang file" */ - first_message=0; std::string file_name; if (control->cmdline->FindString("-lang",file_name)) { LoadMessageFile(file_name.c_str()); diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 85be35a0..aea3fdb8 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -92,7 +92,7 @@ Program::Program() { cmd = new CommandLine(envscan,tail.buffer); } -void Program::WriteOut(char * format,...) { +void Program::WriteOut(const char * format,...) { char buf[1024]; va_list msg; diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 349b151a..1aeb55e9 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -214,7 +214,7 @@ void S_Warn(char * format,...) { GFX_ShowMsg(buf); #endif } -char buf[1024]; //global as else it doesn't always gets thrown right (linux/gcc2.95) +static char buf[1024]; //greater scope as else it doesn't always gets thrown right (linux/gcc2.95) void E_Exit(char * format,...) { // char buf[1024]; //see above diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 4ae9f881..3375d388 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -175,10 +175,33 @@ static char * path_string="PATH=Z:\\"; static char * comspec_string="COMSPEC=Z:\\COMMAND.COM"; static char * full_name="Z:\\COMMAND.COM"; static char * init_line="/INIT AUTOEXEC.BAT"; - void SHELL_Init() { - - call_shellstop=CALLBACK_Allocate(); +//add messages: + AddMessage("SHELL_CMD_HELP","supported commands are:\n"); + AddMessage("SHELL_CMD_ECHO_ON","ECHO is on\n"); + AddMessage("SHELL_CMD_ECHO_OFF","ECHO is off\n"); + AddMessage("SHELL_ILLEGAL_SWITCH","Illegal switch: %s"); + AddMessage("SHELL_CMD_CHDIR_ERROR","Unable to change to: %s\n"); + AddMessage("SHELL_CMD_MKDIR_ERROR","Unable to make: %s\n"); + AddMessage("SHELL_CMD_RMDIR_ERROR","Unable to remove: %\n"); + AddMessage("SHELL_SYNTAXERROR","The syntax of the command is incorrect.\n"); + AddMessage("SHELL_CMD_SET_NOT_SET","Environment variable %s not defined\n"); + AddMessage("SHELL_CMD_SET_OUT_OF_SPACE","Not enough environment space left.\n"); + AddMessage("SHELL_CMD_IF_EXIST_MISSING_FILENAME","IF EXIST: Missing filename.\n"); + AddMessage("SHELL_CMD_IF_ERRORLEVEL_MISSING_NUMBER","IF ERRORLEVEL: Missing number.\n"); + AddMessage("SHELL_CMD_IF_ERRORLEVEL_INVALID_NUMBER","IF ERRORLEVEL: Invalid number.\n"); + AddMessage("SHELL_CMD_GOTO_MISSING_LABEL","No label supplied to GOTO command.\n"); + AddMessage("SHELL_CMD_GOTO_LABEL_NOT_FOUND","GOTO: Label %s not found.\n"); + AddMessage("SHELL_CMD_FILE_NOT_FOUND","File %s not found.\n"); + AddMessage("SHELL_CMD_DIR_INTRO","Directory of %s.\n"); + AddMessage("SHELL_CMD_DIR_PATH_ERROR","Illegal Path\n"); + AddMessage("SHELL_CMD_DIR_BYTES_USED","%5d File(s) %17s Bytes\n"); + AddMessage("SHELL_CMD_DIR_BYTES_FREE","%5d Dir(s) %17s Bytes free"); + AddMessage("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\n"); + AddMessage("SHELL_EXECUTE_ILLEGAL_COMMAND","Illegal command: %s.\n"); + AddMessage("SHELL_STARTUP","DOSBox Shell v0.40\nFor Help and supported commands type: HELP\n\nHAVE FUN!\nThe DOSBox Team\n\n"); +//regular startup + call_shellstop=CALLBACK_Allocate(); CALLBACK_Setup(call_shellstop,shellstop_handler,CB_IRET); PROGRAMS_MakeFile("COMMAND.COM",SHELL_ProgramStart); From ed0e6bee75f3fdcc8b81d3dd957d01bf4a2e6953 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 16 Oct 2002 18:41:12 +0000 Subject: [PATCH 0243/4131] moved MSG_Get from programs.h to dosbox.h. added AddMessage to dosbox.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@320 --- include/dosbox.h | 4 +++- include/programs.h | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/dosbox.h b/include/dosbox.h index b4b109ed..6f381dec 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -24,6 +24,9 @@ void E_Exit(char * message,...); void S_Warn(char * message,...); +void AddMessage(const char*,const char*); //add messages to the internal langaugefile +const char* MSG_Get(char const *); //get messages from the internal langaugafile + /* The internal types */ typedef unsigned char Bit8u; typedef signed char Bit8s; @@ -64,7 +67,6 @@ extern Bitu errorlevel; inline void LOG_MSG(char* message) { - if(errorlevel>=0) S_Warn(message); } diff --git a/include/programs.h b/include/programs.h index 80addf11..34875b2c 100644 --- a/include/programs.h +++ b/include/programs.h @@ -23,7 +23,6 @@ #include "setup.h" -char * MSG_Get(char * msg); class Program; typedef void (PROGRAMS_Main)(Program * * make); @@ -41,7 +40,7 @@ public: char * GetEnvNum(Bit32u num); Bit32u GetEnvCount(void); bool SetEnv(char * env_entry,char * new_string); - void WriteOut(char * format,...); /* Write to standard output */ + void WriteOut(const char * format,...); /* Write to standard output */ }; From 6d64c5f21ea84c906f54edde16f2a7983e04dee1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 17 Oct 2002 13:18:00 +0000 Subject: [PATCH 0244/4131] added MSG_Write and renamed ???Message to MSG_???. Fixed some typos Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@321 --- include/dosbox.h | 2 +- src/misc/messages.cpp | 20 +++++++++++++++---- src/shell/shell.cpp | 46 +++++++++++++++++++++---------------------- 3 files changed, 40 insertions(+), 28 deletions(-) diff --git a/include/dosbox.h b/include/dosbox.h index 6f381dec..25606f62 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -24,7 +24,7 @@ void E_Exit(char * message,...); void S_Warn(char * message,...); -void AddMessage(const char*,const char*); //add messages to the internal langaugefile +void MSG_Add(const char*,const char*); //add messages to the internal langaugefile const char* MSG_Get(char const *); //get messages from the internal langaugafile /* The internal types */ diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 3ec32ef1..9ce0fe63 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -42,12 +42,12 @@ struct MessageBlock static list Lang; typedef list::iterator itmb; -void AddMessage(const char * _name, const char* _val) +void MSG_Add(const char * _name, const char* _val) { Lang.push_back(MessageBlock(_name,_val)); } -void ReplaceMessage(const char * _name, const char* _val) +void MSG_Replace(const char * _name, const char* _val) { //find the message for(itmb tel=Lang.begin();tel!=Lang.end();tel++) @@ -60,7 +60,7 @@ void ReplaceMessage(const char * _name, const char* _val) } } //even if the message doesn't exist add it - AddMessage(_name,_val); + MSG_Add(_name,_val); } static void LoadMessageFile(const char * fname) { @@ -94,7 +94,7 @@ static void LoadMessageFile(const char * fname) { /* End of string marker */ } else if (linein[0]=='.') { /* Replace/Add the string to the internal langaugefile */ - ReplaceMessage(name,string); + MSG_Replace(name,string); } else { /* Normal string to be added */ strcat(string,linein); @@ -122,3 +122,15 @@ void MSG_Init(Section_prop * section) { LoadMessageFile(file_name.c_str()); } else LoadMessageFile(section->Get_string("LANGUAGE")); } + +void MSG_Write(const char * location) +{ + FILE* out=fopen(location,"w+b"); + if(out==NULL) return;//maybe an error? + for(itmb tel=Lang.begin();tel!=Lang.end();tel++){ + fprintf(out,":%s\n%s.\n",(*tel).name.c_str(),(*tel).val.c_str()); + } + + fclose(out); +} + diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 3375d388..c88df57f 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -177,29 +177,29 @@ static char * full_name="Z:\\COMMAND.COM"; static char * init_line="/INIT AUTOEXEC.BAT"; void SHELL_Init() { //add messages: - AddMessage("SHELL_CMD_HELP","supported commands are:\n"); - AddMessage("SHELL_CMD_ECHO_ON","ECHO is on\n"); - AddMessage("SHELL_CMD_ECHO_OFF","ECHO is off\n"); - AddMessage("SHELL_ILLEGAL_SWITCH","Illegal switch: %s"); - AddMessage("SHELL_CMD_CHDIR_ERROR","Unable to change to: %s\n"); - AddMessage("SHELL_CMD_MKDIR_ERROR","Unable to make: %s\n"); - AddMessage("SHELL_CMD_RMDIR_ERROR","Unable to remove: %\n"); - AddMessage("SHELL_SYNTAXERROR","The syntax of the command is incorrect.\n"); - AddMessage("SHELL_CMD_SET_NOT_SET","Environment variable %s not defined\n"); - AddMessage("SHELL_CMD_SET_OUT_OF_SPACE","Not enough environment space left.\n"); - AddMessage("SHELL_CMD_IF_EXIST_MISSING_FILENAME","IF EXIST: Missing filename.\n"); - AddMessage("SHELL_CMD_IF_ERRORLEVEL_MISSING_NUMBER","IF ERRORLEVEL: Missing number.\n"); - AddMessage("SHELL_CMD_IF_ERRORLEVEL_INVALID_NUMBER","IF ERRORLEVEL: Invalid number.\n"); - AddMessage("SHELL_CMD_GOTO_MISSING_LABEL","No label supplied to GOTO command.\n"); - AddMessage("SHELL_CMD_GOTO_LABEL_NOT_FOUND","GOTO: Label %s not found.\n"); - AddMessage("SHELL_CMD_FILE_NOT_FOUND","File %s not found.\n"); - AddMessage("SHELL_CMD_DIR_INTRO","Directory of %s.\n"); - AddMessage("SHELL_CMD_DIR_PATH_ERROR","Illegal Path\n"); - AddMessage("SHELL_CMD_DIR_BYTES_USED","%5d File(s) %17s Bytes\n"); - AddMessage("SHELL_CMD_DIR_BYTES_FREE","%5d Dir(s) %17s Bytes free"); - AddMessage("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\n"); - AddMessage("SHELL_EXECUTE_ILLEGAL_COMMAND","Illegal command: %s.\n"); - AddMessage("SHELL_STARTUP","DOSBox Shell v0.40\nFor Help and supported commands type: HELP\n\nHAVE FUN!\nThe DOSBox Team\n\n"); + MSG_Add("SHELL_CMD_HELP","supported commands are:\n"); + MSG_Add("SHELL_CMD_ECHO_ON","ECHO is on\n"); + MSG_Add("SHELL_CMD_ECHO_OFF","ECHO is off\n"); + MSG_Add("SHELL_ILLEGAL_SWITCH","Illegal switch: %s\n"); + MSG_Add("SHELL_CMD_CHDIR_ERROR","Unable to change to: %s\n"); + MSG_Add("SHELL_CMD_MKDIR_ERROR","Unable to make: %s\n"); + MSG_Add("SHELL_CMD_RMDIR_ERROR","Unable to remove: %\n"); + MSG_Add("SHELL_SYNTAXERROR","The syntax of the command is incorrect.\n"); + MSG_Add("SHELL_CMD_SET_NOT_SET","Environment variable %s not defined\n"); + MSG_Add("SHELL_CMD_SET_OUT_OF_SPACE","Not enough environment space left.\n"); + MSG_Add("SHELL_CMD_IF_EXIST_MISSING_FILENAME","IF EXIST: Missing filename.\n"); + MSG_Add("SHELL_CMD_IF_ERRORLEVEL_MISSING_NUMBER","IF ERRORLEVEL: Missing number.\n"); + MSG_Add("SHELL_CMD_IF_ERRORLEVEL_INVALID_NUMBER","IF ERRORLEVEL: Invalid number.\n"); + MSG_Add("SHELL_CMD_GOTO_MISSING_LABEL","No label supplied to GOTO command.\n"); + MSG_Add("SHELL_CMD_GOTO_LABEL_NOT_FOUND","GOTO: Label %s not found.\n"); + MSG_Add("SHELL_CMD_FILE_NOT_FOUND","File %s not found.\n"); + MSG_Add("SHELL_CMD_DIR_INTRO","Directory of %s.\n"); + MSG_Add("SHELL_CMD_DIR_PATH_ERROR","Illegal Path\n"); + MSG_Add("SHELL_CMD_DIR_BYTES_USED","%5d File(s) %17s Bytes\n"); + MSG_Add("SHELL_CMD_DIR_BYTES_FREE","%5d Dir(s) %17s Bytes free\n"); + MSG_Add("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\n"); + MSG_Add("SHELL_EXECUTE_ILLEGAL_COMMAND","Illegal command: %s.\n"); + MSG_Add("SHELL_STARTUP","DOSBox Shell v0.40\nFor Help and supported commands type: HELP\n\nHAVE FUN!\nThe DOSBox Team\n\n"); //regular startup call_shellstop=CALLBACK_Allocate(); CALLBACK_Setup(call_shellstop,shellstop_handler,CB_IRET); From 982ec01bc58243a2c1ede507f90970615de3f4e0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 17 Oct 2002 18:13:59 +0000 Subject: [PATCH 0245/4131] added \n to default MSG Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@322 --- src/misc/messages.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 9ce0fe63..29d916c1 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -112,7 +112,7 @@ const char * MSG_Get(char const * msg) { return (*tel).val.c_str(); } } - return "Message not Found!"; + return "Message not Found!\n"; } void MSG_Init(Section_prop * section) { From 09e339c9b8243ca92dc2933878c94f608c88c96b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 17 Oct 2002 18:21:28 +0000 Subject: [PATCH 0246/4131] add config::printconfig and others to print the configfile Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@323 --- include/setup.h | 15 +++++++++---- src/misc/setup.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 5 deletions(-) diff --git a/include/setup.h b/include/setup.h index 0925b1de..da5c14dc 100644 --- a/include/setup.h +++ b/include/setup.h @@ -56,7 +56,8 @@ class Property { public: Property(const char* _propname):propname(_propname) { } virtual void SetValue(char* input)=0; - Value GetValue() { return __value; } + virtual void GetValuestring(char* str)=0; + Value GetValue() { return __value;} std::string propname; Value __value; virtual ~Property(){ } @@ -68,6 +69,7 @@ public: __value._int=_value; } void SetValue(char* input); + void GetValuestring(char* str); ~Prop_int(){ } }; @@ -77,6 +79,7 @@ public: __value._bool=_value; } void SetValue(char* input); + void GetValuestring(char* str); ~Prop_bool(){ } }; @@ -89,6 +92,7 @@ public: delete __value._string; } void SetValue(char* input); + void GetValuestring(char* str); }; class Prop_hex:public Property { public: @@ -97,6 +101,7 @@ public: } void SetValue(char* input); ~Prop_hex(){ } + void GetValuestring(char* str); }; class Section { @@ -108,6 +113,7 @@ public: void ExecuteInit() { initfunction(this);} virtual void HandleInputline(char *gegevens){} + virtual void Print(FILE* outfile) { /*At this moment empty */ } std::string sectionname; }; @@ -128,7 +134,8 @@ class Section_prop:public Section { bool Get_bool(const char* _propname); int Get_hex(const char* _propname); void HandleInputline(char *gegevens); - + void Print(FILE* outfile); + std::list properties; typedef std::list::iterator it; }; @@ -137,7 +144,7 @@ class Section_line: public Section{ public: Section_line(const char* _sectionname,void (*_initfunction)(Section*)):Section(_sectionname,_initfunction){} void HandleInputline(char* gegevens); - + void Print(FILE* outfile); std::string data; }; @@ -157,7 +164,7 @@ public: void Init(); void ShutDown(); void StartUp(); - + void PrintConfig(const char* configfilename); void ParseConfigFile(const char* configfilename); std::list sectionlist; diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 01fa0d1f..e017d3fc 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -51,6 +51,22 @@ void Prop_hex::SetValue(char* input){ if(!sscanf(input,"%X",&(__value._hex))) __value._hex=0; } +void Prop_int::GetValuestring(char* str){ + sprintf(str,"%d",__value._int); +} + +void Prop_string::GetValuestring(char* str){ + sprintf(str,"%s",__value._string->c_str()); +} + +void Prop_bool::GetValuestring(char* str){ + sprintf(str,"%s",__value._bool?"true":"false"); +} + +void Prop_hex::GetValuestring(char* str){ + sprintf(str,"%X",__value._hex); +} + void Section_prop::Add_int(const char* _propname, int _value) { Property* test=new Prop_int(_propname,_value); properties.push_back(test); @@ -116,13 +132,49 @@ void Section_prop::HandleInputline(char *gegevens){ } } } +#define HELPLENGTH 300 +void Section_prop::Print(FILE* outfile){ + char* val=new char[HELPLENGTH]; + fprintf(outfile,"[%s]\n",sectionname.c_str()); + snprintf(val,HELPLENGTH,"%s_CONFIGFILE_HELP",sectionname.c_str()); + + fprintf(outfile,"%% %s",MSG_Get(val));//entries in langfile end with \n + for(it tel=properties.begin();tel!=properties.end();tel++){ + (*tel)->GetValuestring(val); + fprintf(outfile,"%s=%s\n",(*tel)->propname.c_str(),val); + } + fprintf(outfile,"\n"); + delete val; +} - + void Section_line::HandleInputline(char* gegevens){ data+=gegevens; data+="\n"; } +void Section_line::Print(FILE* outfile) +{ + fprintf(outfile,"[%s]\n",sectionname.c_str()); + char* val=new char[HELPLENGTH]; + snprintf(val,HELPLENGTH,"%s_CONFIGFILE_HELP",sectionname.c_str()); + fprintf(outfile,"%% %s",MSG_Get(val));//entries in langfile end with \n + fprintf(outfile,"%s",data.c_str()); + fprintf(outfile,"\n"); + delete val; +} + +void Config::PrintConfig(const char* configfilename){ + FILE* outfile=fopen(configfilename,"w+b"); + if(outfile==NULL) return; + for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ + (*tel)->Print(outfile); + } + fclose(outfile); +} + + + Section* Config::AddSection(const char* _name,void (*_initfunction)(Section*)){ Section* blah = new Section(_name,_initfunction); sectionlist.push_back(blah); From 08a9eccc1ccbfedd9f795994a19bda37dc3a9407 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 17 Oct 2002 19:11:43 +0000 Subject: [PATCH 0247/4131] updated with config stuff Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@324 --- ChangeLog | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4cf20db9..5a7923eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,9 @@ 0.60 - 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) + 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 From 8fdd7fea4f7b75b21a0bf229a4783aa1eebbe8d6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 08:45:11 +0000 Subject: [PATCH 0248/4131] Support for variables and command line forwarding Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@325 --- src/shell/shell_batch.cpp | 56 ++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index cec7f45d..48c571f7 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -24,19 +24,10 @@ BatchFile::BatchFile(DOS_Shell * host,char * name, char * cmd_line) { - /* Go through the command line */ - char * cmd_write=cmd_buffer; prev=host->bf; echo=host->echo; shell=host; - cmd_count=0; - while (*cmd_line || (cmd_countbf=prev; shell->echo=echo; @@ -77,29 +69,51 @@ emptyline: while (*cmd_read) { env_write=env_name; if (*cmd_read=='%') { - cmd_read++; - /* Find the fullstring of this */ - - - continue; - + cmd_read++; + if (cmd_read[0]=='%') { + cmd_read++; + *cmd_write++='%'; + } + size_t len=strspn(cmd_read,"0123456789"); + if (len) { + memcpy(env_name,cmd_read,len); + env_name[len]=0;cmd_read+=len; + len=atoi(env_name); + if (cmd->GetCount()FindCommand(len,word)) continue; + strcpy(cmd_write,word.c_str()); + cmd_write+=strlen(word.c_str()); + continue; + } else { + /* Not a command line number has to be an environment */ + char * first=strchr(cmd_read,'%'); + if (!first) continue; *first++=0; + std::string temp; + if (shell->GetEnvStr(cmd_read,temp)) { + char * equals=strchr(temp.c_str(),'='); + if (!equals) continue; + equals++; + strcpy(cmd_write,equals); + cmd_write+=strlen(equals); + } + cmd_read=first; + } } else { *cmd_write++=*cmd_read++; } - *cmd_write=0; } - return true; - + *cmd_write=0; + return true; } - bool BatchFile::Goto(char * where) { Bit32u pos=0; char cmd[CMD_MAXLINE]; char * cmd_write; DOS_SeekFile(file_handle,&pos,DOS_SEEK_SET); - /* Scan till we have a match or return false*/ + /* Scan till we have a match or return false */ Bit8u c;Bit16u n; again: cmd_write=cmd; From 7c69076e9e04f7cbc26f162c8ec8c59296e36a8e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 08:45:50 +0000 Subject: [PATCH 0249/4131] Changed the environment functions, changed the shell "SET" command accodingly Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@326 --- src/shell/shell_cmds.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 6d29ae58..1072988e 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -257,23 +257,22 @@ void DOS_Shell::CMD_COPY(char * args) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); return; } - } void DOS_Shell::CMD_SET(char * args) { + std::string line; if (!*args) { /* No command line show all environment lines */ - Bit32u count=GetEnvCount(); - for (Bit32u a=0;a Date: Fri, 18 Oct 2002 08:46:19 +0000 Subject: [PATCH 0250/4131] Batch files also have a command line parser now. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@327 --- src/shell/shell_inc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shell/shell_inc.h b/src/shell/shell_inc.h index 9f76040d..a5f59142 100644 --- a/src/shell/shell_inc.h +++ b/src/shell/shell_inc.h @@ -47,6 +47,7 @@ public: bool echo; DOS_Shell * shell; BatchFile * prev; + CommandLine * cmd; }; From a6b4b4fe3945a9d831baf7fb11a086e5108050bb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 08:46:58 +0000 Subject: [PATCH 0251/4131] Which function required the new environment function for path lookups. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@328 --- src/shell/shell_misc.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index dcc0ab18..42830804 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -29,7 +29,6 @@ void DOS_Shell::ShowPrompt(void) { WriteOut("%c:\\%s>",drive,dir); } - static void outc(Bit8u c) { Bit16u n=1; DOS_WriteFile(STDOUT,&c,&n); @@ -212,9 +211,10 @@ char * DOS_Shell::Which(char * name) { if (DOS_FileExists(which_ret)) return which_ret; } - /* No Path in filename look through %path% */ - static char path[DOS_PATHLENGTH]; - char * pathenv=GetEnvStr("PATH"); + /* No Path in filename look through path environment string */ + static char path[DOS_PATHLENGTH];std::string temp; + if (!GetEnvStr("PATH",temp)) return 0; + const char * pathenv=temp.c_str(); if (!pathenv) return 0; pathenv=strchr(pathenv,'='); if (!pathenv) return 0; From 3ae3e7d258a04727f9213e00d0686f19ec20d110 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 08:47:34 +0000 Subject: [PATCH 0252/4131] Renamed some comments and changed some tabs Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@329 --- src/shell/shell.cpp | 54 +++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index c88df57f..46bc49f8 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -175,33 +175,35 @@ static char * path_string="PATH=Z:\\"; static char * comspec_string="COMSPEC=Z:\\COMMAND.COM"; static char * full_name="Z:\\COMMAND.COM"; static char * init_line="/INIT AUTOEXEC.BAT"; + void SHELL_Init() { -//add messages: - MSG_Add("SHELL_CMD_HELP","supported commands are:\n"); - MSG_Add("SHELL_CMD_ECHO_ON","ECHO is on\n"); - MSG_Add("SHELL_CMD_ECHO_OFF","ECHO is off\n"); - MSG_Add("SHELL_ILLEGAL_SWITCH","Illegal switch: %s\n"); - MSG_Add("SHELL_CMD_CHDIR_ERROR","Unable to change to: %s\n"); - MSG_Add("SHELL_CMD_MKDIR_ERROR","Unable to make: %s\n"); - MSG_Add("SHELL_CMD_RMDIR_ERROR","Unable to remove: %\n"); - MSG_Add("SHELL_SYNTAXERROR","The syntax of the command is incorrect.\n"); - MSG_Add("SHELL_CMD_SET_NOT_SET","Environment variable %s not defined\n"); - MSG_Add("SHELL_CMD_SET_OUT_OF_SPACE","Not enough environment space left.\n"); - MSG_Add("SHELL_CMD_IF_EXIST_MISSING_FILENAME","IF EXIST: Missing filename.\n"); - MSG_Add("SHELL_CMD_IF_ERRORLEVEL_MISSING_NUMBER","IF ERRORLEVEL: Missing number.\n"); - MSG_Add("SHELL_CMD_IF_ERRORLEVEL_INVALID_NUMBER","IF ERRORLEVEL: Invalid number.\n"); - MSG_Add("SHELL_CMD_GOTO_MISSING_LABEL","No label supplied to GOTO command.\n"); - MSG_Add("SHELL_CMD_GOTO_LABEL_NOT_FOUND","GOTO: Label %s not found.\n"); - MSG_Add("SHELL_CMD_FILE_NOT_FOUND","File %s not found.\n"); - MSG_Add("SHELL_CMD_DIR_INTRO","Directory of %s.\n"); - MSG_Add("SHELL_CMD_DIR_PATH_ERROR","Illegal Path\n"); - MSG_Add("SHELL_CMD_DIR_BYTES_USED","%5d File(s) %17s Bytes\n"); - MSG_Add("SHELL_CMD_DIR_BYTES_FREE","%5d Dir(s) %17s Bytes free\n"); - MSG_Add("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\n"); - MSG_Add("SHELL_EXECUTE_ILLEGAL_COMMAND","Illegal command: %s.\n"); - MSG_Add("SHELL_STARTUP","DOSBox Shell v0.40\nFor Help and supported commands type: HELP\n\nHAVE FUN!\nThe DOSBox Team\n\n"); -//regular startup - call_shellstop=CALLBACK_Allocate(); + /* Add messages */ + MSG_Add("SHELL_CMD_HELP","supported commands are:\n"); + MSG_Add("SHELL_CMD_ECHO_ON","ECHO is on\n"); + MSG_Add("SHELL_CMD_ECHO_OFF","ECHO is off\n"); + MSG_Add("SHELL_ILLEGAL_SWITCH","Illegal switch: %s\n"); + MSG_Add("SHELL_CMD_CHDIR_ERROR","Unable to change to: %s\n"); + MSG_Add("SHELL_CMD_MKDIR_ERROR","Unable to make: %s\n"); + MSG_Add("SHELL_CMD_RMDIR_ERROR","Unable to remove: %\n"); + MSG_Add("SHELL_SYNTAXERROR","The syntax of the command is incorrect.\n"); + MSG_Add("SHELL_CMD_SET_NOT_SET","Environment variable %s not defined\n"); + MSG_Add("SHELL_CMD_SET_OUT_OF_SPACE","Not enough environment space left.\n"); + MSG_Add("SHELL_CMD_IF_EXIST_MISSING_FILENAME","IF EXIST: Missing filename.\n"); + MSG_Add("SHELL_CMD_IF_ERRORLEVEL_MISSING_NUMBER","IF ERRORLEVEL: Missing number.\n"); + MSG_Add("SHELL_CMD_IF_ERRORLEVEL_INVALID_NUMBER","IF ERRORLEVEL: Invalid number.\n"); + MSG_Add("SHELL_CMD_GOTO_MISSING_LABEL","No label supplied to GOTO command.\n"); + MSG_Add("SHELL_CMD_GOTO_LABEL_NOT_FOUND","GOTO: Label %s not found.\n"); + MSG_Add("SHELL_CMD_FILE_NOT_FOUND","File %s not found.\n"); + MSG_Add("SHELL_CMD_DIR_INTRO","Directory of %s.\n"); + MSG_Add("SHELL_CMD_DIR_PATH_ERROR","Illegal Path\n"); + MSG_Add("SHELL_CMD_DIR_BYTES_USED","%5d File(s) %17s Bytes\n"); + MSG_Add("SHELL_CMD_DIR_BYTES_FREE","%5d Dir(s) %17s Bytes free\n"); + MSG_Add("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\n"); + MSG_Add("SHELL_EXECUTE_ILLEGAL_COMMAND","Illegal command: %s.\n"); + MSG_Add("SHELL_STARTUP","DOSBox Shell v0.40\nFor Help and supported commands type: HELP\n\nHAVE FUN!\nThe DOSBox Team\n\n"); + /* Regular startup */ + call_shellstop=CALLBACK_Allocate(); + CALLBACK_Setup(call_shellstop,shellstop_handler,CB_IRET); PROGRAMS_MakeFile("COMMAND.COM",SHELL_ProgramStart); From b609fb89a4dd74765c4c6dc84c1ba29d581cf621 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 08:58:46 +0000 Subject: [PATCH 0253/4131] Changed the layout a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@330 --- src/misc/messages.cpp | 87 +++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 48 deletions(-) diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 29d916c1..c2da9d54 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -31,42 +31,36 @@ using namespace std; #define LINE_IN_MAXLEN 1024 -struct MessageBlock -{ - string name; - string val; - MessageBlock(const char* _name, const char* _val): - name(_name),val(_val) - {} +struct MessageBlock { + string name; + string val; + MessageBlock(const char* _name, const char* _val): + name(_name),val(_val){} }; static list Lang; typedef list::iterator itmb; -void MSG_Add(const char * _name, const char* _val) -{ - Lang.push_back(MessageBlock(_name,_val)); +void MSG_Add(const char * _name, const char* _val) { + Lang.push_back(MessageBlock(_name,_val)); } -void MSG_Replace(const char * _name, const char* _val) -{ - //find the message - for(itmb tel=Lang.begin();tel!=Lang.end();tel++) - { - if((*tel).name==_name) - { itmb teln=tel; - teln++; - Lang.erase(tel,teln); - break; - } - } - //even if the message doesn't exist add it - MSG_Add(_name,_val); +void MSG_Replace(const char * _name, const char* _val) { + /* Find the message */ + for(itmb tel=Lang.begin();tel!=Lang.end();tel++) { + if((*tel).name==_name) { + itmb teln=tel; + teln++; + Lang.erase(tel,teln); + break; + } + } + /* Even if the message doesn't exist add it */ + MSG_Add(_name,_val); } - static void LoadMessageFile(const char * fname) { if(*fname=='\0') return;//empty string=no languagefile - FILE * mfile=fopen(fname,"rb"); -/* This should never happen and since other modules depend on this use a normal printf */ + FILE * mfile=fopen(fname,"rb"); + /* This should never happen and since other modules depend on this use a normal printf */ if (!mfile) { E_Exit("MSG:Can't load messages: %s",fname); } @@ -103,16 +97,25 @@ static void LoadMessageFile(const char * fname) { } fclose(mfile); } + const char * MSG_Get(char const * msg) { - for(itmb tel=Lang.begin();tel!=Lang.end();tel++) - { - - if((*tel).name==msg) - { - return (*tel).val.c_str(); - } - } - return "Message not Found!\n"; + for(itmb tel=Lang.begin();tel!=Lang.end();tel++){ + if((*tel).name==msg) + { + return (*tel).val.c_str(); + } + } + return "Message not Found!\n"; +} + + +void MSG_Write(const char * location) { + FILE* out=fopen(location,"w+b"); + if(out==NULL) return;//maybe an error? + for(itmb tel=Lang.begin();tel!=Lang.end();tel++){ + fprintf(out,":%s\n%s.\n",(*tel).name.c_str(),(*tel).val.c_str()); + } + fclose(out); } void MSG_Init(Section_prop * section) { @@ -122,15 +125,3 @@ void MSG_Init(Section_prop * section) { LoadMessageFile(file_name.c_str()); } else LoadMessageFile(section->Get_string("LANGUAGE")); } - -void MSG_Write(const char * location) -{ - FILE* out=fopen(location,"w+b"); - if(out==NULL) return;//maybe an error? - for(itmb tel=Lang.begin();tel!=Lang.end();tel++){ - fprintf(out,":%s\n%s.\n",(*tel).name.c_str(),(*tel).val.c_str()); - } - - fclose(out); -} - From 1f8fcff74edfbbd8fea7c24bf54f9bb132ddff1d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 09:00:51 +0000 Subject: [PATCH 0254/4131] New environment functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@331 --- src/misc/programs.cpp | 101 ++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 48 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index aea3fdb8..e5562713 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -78,8 +78,6 @@ static Bitu PROGRAMS_Handler(void) { Program::Program() { /* Find the command line and setup the PSP */ - - psp = new DOS_PSP(dos.psp); /* Scan environment for filename */ char * envscan=(char *)HostMake(psp->GetEnvironment(),0); @@ -105,64 +103,71 @@ void Program::WriteOut(const char * format,...) { } -char * Program::GetEnvStr(char * env_str) { +bool Program::GetEnvStr(const char * entry,std::string & result) { /* Walk through the internal environment and see for a match */ -/* Taking some short cuts here to not fuck around with memory structure */ - - char * envstart=(char *)HostMake(psp->GetEnvironment(),0); - size_t len=strlen(env_str); - while (*envstart) { - if (strncasecmp(env_str,envstart,len)==0 && envstart[len]=='=') { - return envstart; - } - envstart+=strlen(envstart)+1; - } - return 0; + PhysPt env_read=PhysMake(psp->GetEnvironment(),0); + char env_string[1024]; + result.erase(); + if (!entry[0]) return false; + do { + MEM_StrCopy(env_read,env_string,1024); + if (!env_string[0]) return false; + env_read+=strlen(env_string)+1; + if (!strchr(env_string,'=')) continue; + if (strncasecmp(entry,env_string,strlen(entry))!=0) continue; + result=env_string; + return true; + } while (1); + return false; }; -char * Program::GetEnvNum(Bit32u num) { - char * envstart=(char *)HostMake(psp->GetEnvironment(),0); - while (*envstart) { - if (!num) return envstart; - envstart+=strlen(envstart)+1; +bool Program::GetEnvNum(Bitu num,std::string & result) { + char env_string[1024]; + PhysPt env_read=PhysMake(psp->GetEnvironment(),0); + do { + MEM_StrCopy(env_read,env_string,1024); + if (!env_string[0]) break; + if (!num) { result=env_string;return true;} + env_read+=strlen(env_string)+1; num--; - } - return 0; + } while (1); + return false; } -Bit32u Program::GetEnvCount(void) { - char * envstart=(char *)HostMake(psp->GetEnvironment(),0); - Bit32u num=0; - while (*envstart) { - envstart+=strlen(envstart)+1; +Bitu Program::GetEnvCount(void) { + PhysPt env_read=PhysMake(psp->GetEnvironment(),0); + Bitu num=0; + while (mem_readb(env_read)!=0) { + for (;mem_readb(env_read);env_read++) {}; + env_read++; num++; } return num; } -bool Program::SetEnv(char * env_entry,char * new_string) { - MCB * env_mcb=(MCB *)HostMake(psp->GetEnvironment()-1,0); - upcase(env_entry); - Bit32u env_size=env_mcb->size*16; - if (!env_size) E_Exit("SHELL:Illegal environment size"); - /* First try to find the old entry */ - size_t len=strlen(env_entry); - char * envstart=(char *)HostMake(psp->GetEnvironment(),0); - while (*envstart) { - if (strncasecmp(env_entry,envstart,len)==0 && envstart[len]=='=') { - /* Now remove this entry */ - memmove(envstart,envstart+strlen(envstart)+1,env_size); - } else { - envstart+=strlen(envstart)+1; - env_size-=(strlen(envstart)+1); - } +bool Program::SetEnv(const char * entry,const char * new_string) { + PhysPt env_read=PhysMake(psp->GetEnvironment(),0); + PhysPt env_write=env_read; + char env_string[1024]; + do { + MEM_StrCopy(env_read,env_string,1024); + if (!env_string[0]) break; + env_read+=strlen(env_string)+1; + if (!strchr(env_string,'=')) continue; /* Remove corrupt entry? */ + if ((strncasecmp(entry,env_string,strlen(entry))==0) && + env_string[strlen(entry)]=='=') continue; + MEM_BlockWrite(env_write,env_string,strlen(env_string)+1); + env_write+=strlen(env_string)+1; + } while (1); +/* TODO Maybe save the program name sometime. not really needed though */ + /* Save the new entry */ + if (new_string[0]) { + sprintf(env_string,"%s=%s",entry,new_string); + MEM_BlockWrite(env_write,env_string,strlen(env_string)+1); + env_write+=strlen(env_string)+1; } - /* Now add the string if there is space available */ - if (env_size<(strlen(env_entry)+strlen(new_string)+2)) return false; - if (!*new_string) return true; - sprintf(envstart,"%s=%s",env_entry,new_string); - envstart+=strlen(envstart)+1; - *envstart++=0;*envstart++=0;*envstart++=0; + /* Clear out the final piece of the environment */ + mem_writed(env_write,0); return true; } From 97530e28e08f59f3cf4ad01b2f58ac00a24e32ee Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 09:01:59 +0000 Subject: [PATCH 0255/4131] Removed wildcmp, replaced by new function in drives.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@332 --- src/misc/support.cpp | 43 ------------------------------------------- 1 file changed, 43 deletions(-) diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 1aeb55e9..689d3990 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -82,49 +82,6 @@ char *trim(char *str) { return ltrim(str); } -bool wildcmp(char *wild, char *string) -{ - // special case - Everything goes through - if (strcmp(wild,"*")==0) return true; - - while (*wild) { - if (*wild=='*') { - // Any other chars after that ? - if ((wild[1]!=0) && (wild[1]!='.')) { - // search string - while ((*string) && (*string!='.')) { - // thats the char ? then exit - if (toupper(*string)==toupper(wild[1])) break; - string++; - }; - - } else { - // skip to extension or end - while (*string && (*string!='.')) string++; - } - wild++; - - } else if (*string=='.') { - // only valid : '?' & '*' - while (*wild && (*wild!='.')) { - if ((*wild!='?') && (*wild!='*')) return false; - wild++; - } - if (*wild) wild++; - string++; - - } else if ((*wild!='?') && (toupper(*string)!=toupper(*wild))) { - // no match - return false; - - } else { - wild++; - string++; - } - } - - return ((*string==0) && (*wild==0)); -}; bool ScanCMDBool(char * cmd,char * check) { char * scan=cmd;size_t c_len=strlen(check); From 02e888e0012878eb2513ecfc8f521dde3c1b6b61 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 09:03:23 +0000 Subject: [PATCH 0256/4131] Removed the hardware manager functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@333 --- src/hardware/adlib.cpp | 51 ++-------------------------------- src/hardware/gameblaster.cpp | 54 ++---------------------------------- 2 files changed, 4 insertions(+), 101 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 83a49cd5..87e36302 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -126,7 +126,6 @@ static void write_p389(Bit32u port,Bit8u val) { } -static HWBlock hw_adlib; static bool adlib_enabled; static void ADLIB_Enable(bool enable) { @@ -153,48 +152,10 @@ static void ADLIB_Enable(bool enable) { } -static void ADLIB_InputHandler(char * line) { - bool s_off=ScanCMDBool(line,"OFF"); - bool s_on=ScanCMDBool(line,"ON"); - char * rem=ScanCMDRemain(line); - if (rem) { - sprintf(line,"Illegal Switch"); - return; - } - if (s_on && s_off) { - sprintf(line,"Can't use /ON and /OFF at the same time"); - return; - } - if (s_on) { - ADLIB_Enable(true); - sprintf(line,"Adlib has been enabled"); - return; - } - if (s_off) { - ADLIB_Enable(false); - sprintf(line,"Adlib has been disabled"); - return; - } - return; -} - -static void ADLIB_OutputHandler (char * towrite) { - if(adlib_enabled) { - sprintf(towrite,"IO %X",0x388); - } else { - sprintf(towrite,"Disabled"); - } -}; - - - - - - - void ADLIB_Init(Section* sec) { Section_prop * section=static_cast(sec); - if(!section->Get_bool("STATUS")) return; + if(!section->Get_bool("adlib")) return; + timer1.isMasked=true; timer1.base=0; timer1.count=0; @@ -212,14 +173,6 @@ void ADLIB_Init(Section* sec) { adlib_chan=MIXER_AddChannel(ADLIB_CallBack,ADLIB_FREQ,"ADLIB"); MIXER_SetMode(adlib_chan,MIXER_16MONO); - - hw_adlib.dev_name="ADLIB"; - hw_adlib.full_name="Adlib FM Synthesizer"; - hw_adlib.next=0; - hw_adlib.help="/ON Enables Adlib\n/OFF Disables Adlib\n"; - hw_adlib.get_input=ADLIB_InputHandler; - hw_adlib.show_status=ADLIB_OutputHandler; - HW_Register(&hw_adlib); ADLIB_Enable(true); }; diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index 6ddd6969..c6494f50 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -36,8 +36,6 @@ #define PI 3.14159265358979323846 #endif - - struct CMS { struct { Bit32u freq_pos; @@ -157,7 +155,6 @@ static void CMS_CallBack(Bit8u * stream,Bit32u len) { } -static HWBlock hw_cms; static bool cms_enabled; static void CMS_Enable(bool enable) { @@ -178,60 +175,14 @@ static void CMS_Enable(bool enable) { } } - -static void CMS_InputHandler(char * line) { - bool s_off=ScanCMDBool(line,"OFF"); - bool s_on=ScanCMDBool(line,"ON"); - char * rem=ScanCMDRemain(line); - if (rem) { - sprintf(line,"Illegal Switch"); - return; - } - if (s_on && s_off) { - sprintf(line,"Can't use /ON and /OFF at the same time"); - return; - } - if (s_on) { - CMS_Enable(true); - sprintf(line,"Creative Music System has been enabled"); - return; - } - if (s_off) { - CMS_Enable(false); - sprintf(line,"Creative Music System has been disabled"); - return; - } - return; -} - -static void CMS_OutputHandler (char * towrite) { - if(cms_enabled) { - sprintf(towrite,"IO %X",0x220); - } else { - sprintf(towrite,"Disabled"); - } -}; - - - - void CMS_Init(Section* sec) { Section_prop * section=static_cast(sec); - if(!section->Get_bool("STATUS")) return; + if(!section->Get_bool("cms")) return; Bits i; /* Register the Mixer CallBack */ cms_chan=MIXER_AddChannel(CMS_CallBack,CMS_RATE,"CMS"); MIXER_SetMode(cms_chan,MIXER_16STEREO); MIXER_Enable(cms_chan,false); -/* Register with the hardware setup tool */ - hw_cms.dev_name="CMS"; - hw_cms.full_name="Creative Music System"; - hw_cms.next=0; - hw_cms.help="/ON Enables CMS\n/OFF Disables CMS\n"; - hw_cms.get_input=CMS_InputHandler; - hw_cms.show_status=CMS_OutputHandler; - HW_Register(&hw_cms); - CMS_Enable(false); /* Make the frequency/octave table */ double log_start=log10(27.34375); double log_add=(log10(54.609375)-log10(27.34375))/256; @@ -254,7 +205,6 @@ void CMS_Init(Section* sec) { out /= 1.1; } } - - + CMS_Enable(true); } From c03e0db3a40f8715cefdc7f9b64befd15dc8b05b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 09:04:16 +0000 Subject: [PATCH 0257/4131] New and faster versions of block_read and block_write Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@334 --- src/hardware/memory.cpp | 42 +++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index a666e496..cd0c9296 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -34,28 +34,38 @@ MEMORY_WriteHandler WriteHandlerTable[MAX_PAGES]; #define MAX_PAGE_LIMIT PAGE_COUNT(C_MEM_MAX_SIZE*1024*1024) void MEM_BlockRead(PhysPt off,void * data,Bitu size) { - Bitu c; Bit8u * idata=(Bit8u *)data; - for (c=1;c<=(size>>2);c++) { - writed(idata,mem_readd(off)); - idata+=4;off+=4; - } - for (c=1;c<=(size&3);c++) { - writeb(idata,mem_readb(off)); - idata+=1;off+=1; + while (size>0) { + Bitu page=off >> PAGE_SHIFT; + Bitu start=off & (PAGE_SIZE-1); + Bitu tocopy=PAGE_SIZE-start; + if (tocopy>size) tocopy=size; + if (ReadHostTable[page]) { + memcpy(idata,ReadHostTable[page]+off,tocopy); + idata+=tocopy; + off+=tocopy; + } else { + for (;tocopy>0;tocopy--) *idata++=ReadHandlerTable[page](off++); + } + size-=tocopy; } } void MEM_BlockWrite(PhysPt off,void * data,Bitu size) { - Bitu c; Bit8u * idata=(Bit8u *)data; - for (c=1;c<=(size>>2);c++) { - mem_writed(off,readd(idata)); - idata+=4;off+=4; - } - for (c=1;c<=(size&3);c++) { - mem_writeb(off,readb(idata)); - idata+=1;off+=1; + while (size>0) { + Bitu page=off >> PAGE_SHIFT; + Bitu start=off & (PAGE_SIZE-1); + Bitu tocopy=PAGE_SIZE-start; + if (tocopy>size) tocopy=size; + if (WriteHostTable[page]) { + memcpy(WriteHostTable[page]+off,idata,tocopy); + idata+=tocopy; + off+=tocopy; + } else { + for (;tocopy>0;tocopy--) WriteHandlerTable[page](off++,*idata++); + } + size-=tocopy; } } From fc0c9f0b77662880ef1b79d253382bac1b22635f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 09:05:03 +0000 Subject: [PATCH 0258/4131] Removed the directory in #include Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@335 --- src/hardware/mixer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 3a215168..553abe41 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -22,7 +22,7 @@ */ #include -#include +#include #include "dosbox.h" #include "mixer.h" #include "timer.h" From 7eb6dacc9126878f0ac98977f50b1e363e6fc7b7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 09:06:04 +0000 Subject: [PATCH 0259/4131] Removed the hardware manager functions and added the Silence DAC DSP command Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@336 --- src/hardware/sblaster.cpp | 124 ++++++++++---------------------------- 1 file changed, 31 insertions(+), 93 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 246c98ef..f023ad6d 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -24,6 +24,7 @@ #include "pic.h" #include "hardware.h" #include "setup.h" +#include "programs.h" #define SB_BASE 0x220 #define SB_IRQ 5 @@ -45,7 +46,7 @@ enum {DSP_S_RESET,DSP_S_NORMAL,DSP_S_HIGHSPEED}; enum { - MODE_NONE,MODE_DAC, + MODE_NONE,MODE_DAC,MODE_SILENCE, MODE_PCM_8S,MODE_PCM_8A, MODE_ADPCM_4S }; @@ -91,7 +92,6 @@ struct SB_INFO { Bit8u irq; Bit8u dma; bool enabled; - HWBlock hwblock; MIXER_Channel * chan; }; @@ -144,7 +144,7 @@ static void DSP_SetSpeaker(bool how) { } static void DSP_HaltDMA(void) { - + } static INLINE void DSP_FlushData(void) { @@ -152,15 +152,8 @@ static INLINE void DSP_FlushData(void) { sb.data_out_pos=0; } -static void DSP_SetSampleRate(Bit32u rate) { -/* This directly changes the mixer */ - - -} static void DSP_StopDMA(void) { sb.mode=MODE_NONE; -// MIXER_SetMode(sb.chan,MIXER_8MONO); -// MIXER_SetFreq(sb.chan,22050); } static void DSP_StartDMATranfser(Bit8u mode) { @@ -169,6 +162,10 @@ static void DSP_StartDMATranfser(Bit8u mode) { sb.freq=(1000000 / (256 - sb.time_constant)); }; switch (mode) { + case MODE_SILENCE: + MIXER_SetFreq(sb.chan,sb.freq); + SB_DEBUG("DSP:PCM 8 bit single cycle rate %d size %d",sb.freq,sb.samples_total); + break; case MODE_PCM_8S: MIXER_SetFreq(sb.chan,sb.freq); SB_DEBUG("DSP:PCM 8 bit single cycle rate %d size %d",sb.freq,sb.samples_total); @@ -176,13 +173,11 @@ static void DSP_StartDMATranfser(Bit8u mode) { case MODE_PCM_8A: MIXER_SetFreq(sb.chan,sb.freq); SB_DEBUG("DSP:PCM 8 bit auto init rate %d size %d",sb.freq,sb.samples_total); - break; case MODE_ADPCM_4S: MIXER_SetFreq(sb.chan,sb.freq); SB_DEBUG("DSP:ADPCM 4 bit single cycle rate %d size %X",sb.freq,sb.samples_total); break; - default: LOG_ERROR("DSP:Illegal transfer mode %d",mode); return; @@ -207,6 +202,9 @@ static void DSP_Reset(void) { sb.mode=MODE_NONE; sb.cmd_len=0; sb.cmd_in_pos=0; + sb.samples_left=0; + sb.samples_total=0; + sb.freq=22050; sb.use_time_constant=false; sb.dac.used=0; sb.dac.last=0x80; @@ -261,6 +259,10 @@ static void DSP_DoCommand(void) { sb.samples_total=1+sb.cmd_in[0]+(sb.cmd_in[1] << 8); DSP_StartDMATranfser(MODE_ADPCM_4S); break; + case 0x80: /* Silence DAC */ + sb.samples_total=1+sb.cmd_in[0]+(sb.cmd_in[1] << 8); + DSP_StartDMATranfser(MODE_SILENCE); + break; case 0xd0: /* Halt 8-bit DMA */ DSP_HaltDMA(); break; @@ -290,7 +292,6 @@ static void DSP_DoCommand(void) { */ //TODO Ofcourse :) } - break; case 0xe3: /* DSP Copyright */ { @@ -445,6 +446,16 @@ static void SBLASTER_CallBack(Bit8u * stream,Bit32u len) { } } break; + case MODE_SILENCE: + memset(stream,0x80,len); + if (sb.samples_left>len) { + sb.samples_left-=len; + } else { + sb.samples_left=0; + sb.mode=MODE_NONE; + PIC_ActivateIRQ(sb.irq); + } + break; case MODE_PCM_8A: { Bit16u read=DMA_8_Read(sb.dma,stream,(Bit16u)len); @@ -525,8 +536,6 @@ static void SBLASTER_CallBack(Bit8u * stream,Bit32u len) { -static bool SB_enabled; - static void SB_Enable(bool enable) { Bitu i; if (enable) { @@ -543,92 +552,21 @@ static void SB_Enable(bool enable) { for (i=sb.base+4;i(sec); - if(!section->Get_bool("STATUS")) return; + if(!section->Get_bool("enabled")) return; sb.chan=MIXER_AddChannel(&SBLASTER_CallBack,22050,"SBLASTER"); MIXER_Enable(sb.chan,false); - sb.state=DSP_S_NORMAL; -/* Setup the hardware handler part */ - sb.base=section->Get_hex("BASE"); - sb.irq=section->Get_int("IRQ"); - sb.dma=section->Get_int("DMA"); - SB_Enable(true); - sb.hwblock.dev_name="SB"; - sb.hwblock.full_name="Sound Blaster 1.5"; - sb.hwblock.next=0; - sb.hwblock.help= - "/ON Enables SB\n" - "/OFF Disables SB\n" - "/BASE XXX Set Base Addres 200-260\n" - "/IRQ X Set IRQ 1-9\n" - "/DMA X Set 8-Bit DMA Channel 0-3\n"; - sb.hwblock.get_input=SB_InputHandler; - sb.hwblock.show_status=SB_OutputHandler; - HW_Register(&sb.hwblock); - + sb.state=DSP_S_NORMAL; + sb.base=section->Get_hex("base"); + sb.irq=section->Get_int("irq"); + sb.dma=section->Get_int("dma"); + SB_Enable(true); SHELL_AddAutoexec("SET BLASTER=A%3X I%d D%d T3",sb.base,sb.irq,sb.dma); } From d788b1c81bb561fed4e89254bff7b25cb12f6c5a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 09:06:44 +0000 Subject: [PATCH 0260/4131] Tandy now started from the speaker section. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@337 --- src/hardware/tandy_sound.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 2ab49b46..9e5727d6 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -128,7 +128,7 @@ static void TANDYSOUND_CallBack(Bit8u * stream,Bit32u len) { void TANDYSOUND_Init(Section* sec) { Section_prop * section=static_cast(sec); - if(!section->Get_bool("STATUS")) return; + if(!section->Get_bool("tandy")) return; IO_RegisterWriteHandler(0xc0,write_pc0,"Tandy Sound"); tandy_chan=MIXER_AddChannel(&TANDYSOUND_CallBack,TANDY_RATE,"TANDY"); MIXER_Enable(tandy_chan,false); From 57a8b675d0530c40749f2f228a873f7d434447e7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 09:08:08 +0000 Subject: [PATCH 0261/4131] Sections can now support multiple init functions and rewrote some stuff to the "standard" Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@338 --- src/misc/setup.cpp | 71 ++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 37 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index e017d3fc..33c14ed9 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "support.h" using namespace std; @@ -132,63 +133,62 @@ void Section_prop::HandleInputline(char *gegevens){ } } } -#define HELPLENGTH 300 -void Section_prop::Print(FILE* outfile){ - char* val=new char[HELPLENGTH]; - fprintf(outfile,"[%s]\n",sectionname.c_str()); - snprintf(val,HELPLENGTH,"%s_CONFIGFILE_HELP",sectionname.c_str()); - - fprintf(outfile,"%% %s",MSG_Get(val));//entries in langfile end with \n - for(it tel=properties.begin();tel!=properties.end();tel++){ - (*tel)->GetValuestring(val); - fprintf(outfile,"%s=%s\n",(*tel)->propname.c_str(),val); + + +void Section_prop::PrintData(FILE* outfile){ + char temp[1000]; /* Should be enough for the properties */ + /* Now print out the individual section entries */ + for(it tel=properties.begin();tel!=properties.end();tel++){ + (*tel)->GetValuestring(temp); + fprintf(outfile,"%s=%s\n",(*tel)->propname.c_str(),temp); } - fprintf(outfile,"\n"); - delete val; } -void Section_line::HandleInputline(char* gegevens){ - data+=gegevens; +void Section_line::HandleInputline(char* line){ + data+=line; data+="\n"; } -void Section_line::Print(FILE* outfile) -{ - fprintf(outfile,"[%s]\n",sectionname.c_str()); - char* val=new char[HELPLENGTH]; - snprintf(val,HELPLENGTH,"%s_CONFIGFILE_HELP",sectionname.c_str()); - fprintf(outfile,"%% %s",MSG_Get(val));//entries in langfile end with \n - fprintf(outfile,"%s",data.c_str()); - fprintf(outfile,"\n"); - delete val; +void Section_line::PrintData(FILE* outfile) { + fprintf(outfile,"%s",data.c_str()); } void Config::PrintConfig(const char* configfilename){ - FILE* outfile=fopen(configfilename,"w+b"); - if(outfile==NULL) return; - for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ - (*tel)->Print(outfile); - } - fclose(outfile); + char temp[50]; + FILE* outfile=fopen(configfilename,"w+b"); + if(outfile==NULL) return; + for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ + /* Print out the Section header */ + strcpy(temp,(*tel)->sectionname.c_str()); + lowcase(temp); + fprintf(outfile,"[%s]\n",temp); + upcase(temp); + strcat(temp,"_CONFIGFILE_HELP"); + fprintf(outfile,"# %s",MSG_Get(temp)); + (*tel)->PrintData(outfile); + fprintf(outfile,"\n"); /* Always an empty line between sections */ + } + fclose(outfile); } - - Section* Config::AddSection(const char* _name,void (*_initfunction)(Section*)){ - Section* blah = new Section(_name,_initfunction); + Section* blah = new Section(_name); + blah->AddInitFunction(_initfunction); sectionlist.push_back(blah); return blah; } Section_prop* Config::AddSection_prop(const char* _name,void (*_initfunction)(Section*)){ - Section_prop* blah = new Section_prop(_name,_initfunction); + Section_prop* blah = new Section_prop(_name); + blah->AddInitFunction(_initfunction); sectionlist.push_back(blah); return blah; } Section_line* Config::AddSection_line(const char* _name,void (*_initfunction)(Section*)){ - Section_line* blah = new Section_line(_name,_initfunction); + Section_line* blah = new Section_line(_name); + blah->AddInitFunction(_initfunction); sectionlist.push_back(blah); return blah; } @@ -314,9 +314,6 @@ bool CommandLine::FindStringBegin(char * begin,std::string & value, bool remove) } } return false; - - - } int CommandLine::GetCount(void) { From 10e447ac0828edb9aeb6975ad0ec9236a6f9f034 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 09:08:47 +0000 Subject: [PATCH 0262/4131] New SDL Includes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@339 --- include/timer.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/timer.h b/include/timer.h index 58ffdc49..9c07747c 100644 --- a/include/timer.h +++ b/include/timer.h @@ -19,7 +19,7 @@ #ifndef _TIMER_H_ #define _TIMER_H_ /* underlying clock rate in HZ */ -#include +#include extern Bit32u LastTicks; @@ -27,8 +27,6 @@ extern Bit32u LastTicks; #define GetTicks() SDL_GetTicks() -extern bool TimerAgain; - typedef void (*TIMER_TickHandler)(Bitu ticks); typedef void (*TIMER_MicroHandler)(void); typedef void (*TIMER_DelayHandler)(void); From bf2bf57ffa5725a88d2eee4dd1028a1c58ecb38b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 09:17:56 +0000 Subject: [PATCH 0263/4131] SDL Structures moved into sdlmain.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@340 --- include/video.h | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/include/video.h b/include/video.h index 5fd7a8cb..f59d8ec4 100644 --- a/include/video.h +++ b/include/video.h @@ -18,8 +18,8 @@ #ifndef __VIDEO_H #define __VIDEO_H -#include -#include + + typedef void (GFX_DrawHandler)(Bit8u * vidstart); /* Used to reply to the renderer what size to set */ typedef void (GFX_ResizeHandler)(Bitu * width,Bitu * height); @@ -35,27 +35,8 @@ struct GFX_Info { Bitu width,height,bpp,pitch; }; - extern GFX_Info gfx_info; -struct SDL_Block { - bool active; //If this isn't set don't draw - Bitu width; - Bitu height; - Bitu bpp; - GFX_DrawHandler * draw; - GFX_ResizeHandler * resize; - bool mouse_grabbed; - bool full_screen; - SDL_Thread * thread; - SDL_mutex * mutex; - SDL_Surface * surface; - SDL_Joystick * joy; - SDL_Color pal[256]; -}; - -extern SDL_Block sdl; - void GFX_Events(void); void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries); void GFX_SetDrawHandler(GFX_DrawHandler * handler); @@ -65,6 +46,5 @@ void GFX_Start(void); void GFX_Stop(void); void GFX_SwitchFullScreen(void); - #endif From dd95e35dd370dacdbaace2c08b5a0b9b0358ffee Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 09:18:16 +0000 Subject: [PATCH 0264/4131] Removed wildcmp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@341 --- include/support.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/support.h b/include/support.h index 00079ee7..8857469a 100644 --- a/include/support.h +++ b/include/support.h @@ -39,8 +39,6 @@ char *ltrim(char *str); void rtrim(char * const str); char *trim(char *str); -bool wildcmp(char *wild, char *string); - bool ScanCMDBool(char * cmd,char * check); char * ScanCMDRemain(char * cmd); bool ScanCMDHex(char * cmd,char * check,Bits * result); From 04e582fe0a97fba1c83cccd51d72d9d7cffabc43 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 09:19:26 +0000 Subject: [PATCH 0265/4131] Added some virtual desctructors and added the ability to have multiple init functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@342 --- include/setup.h | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/include/setup.h b/include/setup.h index da5c14dc..538d0e63 100644 --- a/include/setup.h +++ b/include/setup.h @@ -106,23 +106,27 @@ public: class Section { public: - Section(const char* _sectionname,void (*_initfunction)(Section*) ):sectionname(_sectionname){ initfunction=_initfunction;} - ~Section(){ } + Section(const char* _sectionname) { sectionname=_sectionname; } + virtual ~Section(){ } - void (*initfunction)(Section*); - void ExecuteInit() { initfunction(this);} - - virtual void HandleInputline(char *gegevens){} - virtual void Print(FILE* outfile) { /*At this moment empty */ } - + typedef void (*InitFunction)(Section*); + void AddInitFunction(InitFunction func) {initfunctions.push_back(func);} + void ExecuteInit() { + typedef std::list::iterator func_it; + for (func_it tel=initfunctions.begin(); tel!=initfunctions.end(); tel++){ + (*tel)(this); + } + } + std::list initfunctions; + virtual void HandleInputline(char * _line){} + virtual void PrintData(FILE* outfile) {} std::string sectionname; }; class Section_prop:public Section { public: - Section_prop(const char* _sectionname,void (*_initfunction)(Section*)):Section(_sectionname,_initfunction){ } - ~Section_prop(){} + Section_prop(const char* _sectionname):Section(_sectionname){} void Add_int(const char* _propname, int _value=0); void Add_string(const char* _propname, char* _value=NULL); @@ -134,7 +138,7 @@ class Section_prop:public Section { bool Get_bool(const char* _propname); int Get_hex(const char* _propname); void HandleInputline(char *gegevens); - void Print(FILE* outfile); + void PrintData(FILE* outfile); std::list properties; typedef std::list::iterator it; @@ -142,9 +146,9 @@ class Section_prop:public Section { class Section_line: public Section{ public: - Section_line(const char* _sectionname,void (*_initfunction)(Section*)):Section(_sectionname,_initfunction){} + Section_line(const char* _sectionname):Section(_sectionname){} void HandleInputline(char* gegevens); - void Print(FILE* outfile); + void PrintData(FILE* outfile); std::string data; }; @@ -164,7 +168,7 @@ public: void Init(); void ShutDown(); void StartUp(); - void PrintConfig(const char* configfilename); + void PrintConfig(const char* configfilename); void ParseConfigFile(const char* configfilename); std::list sectionlist; From 1591baeb4251a930adf02c74fc250d965ba52ca8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 09:19:53 +0000 Subject: [PATCH 0266/4131] Support for the new environment functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@343 --- include/programs.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/programs.h b/include/programs.h index 34875b2c..8a65ad1c 100644 --- a/include/programs.h +++ b/include/programs.h @@ -23,6 +23,7 @@ #include "setup.h" + class Program; typedef void (PROGRAMS_Main)(Program * * make); @@ -36,10 +37,10 @@ public: CommandLine * cmd; DOS_PSP * psp; virtual void Run(void)=0; - char * GetEnvStr(char * env_entry); - char * GetEnvNum(Bit32u num); - Bit32u GetEnvCount(void); - bool SetEnv(char * env_entry,char * new_string); + bool Program::GetEnvStr(const char * entry,std::string & result); + bool GetEnvNum(Bitu num,std::string & result); + Bitu GetEnvCount(void); + bool SetEnv(const char * entry,const char * new_string); void WriteOut(const char * format,...); /* Write to standard output */ }; From b950a89a3ba23c67ad8da4a75a5821ba1e307fb1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 09:20:24 +0000 Subject: [PATCH 0267/4131] Change the PAGE_SIZE #define to be a bit safer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@344 --- include/mem.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mem.h b/include/mem.h index e891cb41..169e49c0 100644 --- a/include/mem.h +++ b/include/mem.h @@ -30,7 +30,7 @@ typedef Bit8u (*MEMORY_ReadHandler)(PhysPt pt); typedef void (*MEMORY_WriteHandler)(PhysPt pt,Bit8u val); #define PAGE_KB 16 -#define PAGE_SIZE PAGE_KB*1024 +#define PAGE_SIZE (PAGE_KB*1024) #define PAGE_SHIFT 14 #define PAGE_COUNT(A) (A & ((1 << PAGE_SHIFT)-1) ? 1+(A >> PAGE_SHIFT) : (A >> PAGE_SHIFT) ) #define MAX_PAGES PAGE_COUNT(C_MEM_MAX_SIZE*1024*1024) From 97b0714271092b50a5f6567ed71ac26abed3f10c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 09:21:13 +0000 Subject: [PATCH 0268/4131] Added safety #defines to prevent from loading the file twice Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@345 --- include/keyboard.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/keyboard.h b/include/keyboard.h index ec495d07..0ff524e4 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -16,6 +16,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef _KEYBOARD_H_ +#define _KEYBOARD_H_ + typedef void(KEYBOARD_EventHandler)(void); void KEYBOARD_AddCode(Bit8u code); void KEYBOARD_AddKey(Bitu keytype,bool pressed); @@ -51,4 +54,4 @@ enum { KBD_LAST }; - +#endif From baf21dd0ff6f46cd6a6fec786d1c3a59ed8dbd28 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Oct 2002 09:22:41 +0000 Subject: [PATCH 0269/4131] Cleaned out for now Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@346 --- include/hardware.h | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/include/hardware.h b/include/hardware.h index 5edfa4b7..514e13ac 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -19,24 +19,7 @@ #ifndef _HARDWARE_H_ #define _HARDWARE_H_ -#include -#include -#include -typedef void (* HW_OutputHandler)(char * towrite); -typedef void (* HW_InputHandler)(char * line); - -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; -}; - - -void HW_Register(HWBlock * block); #endif From a63687d7bfe30d6c45fd091406bbc530d001fa9b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 15:46:42 +0000 Subject: [PATCH 0270/4131] No E_Exit on unhandled call anymore Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@347 --- src/ints/bios_keyboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 428a5924..3fcc4475 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -329,7 +329,7 @@ static Bitu INT16_Handler(void) { LOG_DEBUG("INT16:55:Word TSR compatible call"); break; default: - E_Exit("INT16:Unhandled call %02X",reg_ah); + LOG_ERROR("INT16:Unhandled call %02X",reg_ah); break; }; From a28f5d4698a4d4ae8b24676949012f555b8f5b64 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 15:46:57 +0000 Subject: [PATCH 0271/4131] Use the xmssize property under the dos section now. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@348 --- src/ints/xms.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 026a497d..d89b3121 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -327,7 +327,9 @@ foundnew: void XMS_Init(Section* sec) { Section_prop * section=static_cast(sec); - if(!section->Get_bool("STATUS")) return; + Bitu size=section->Get_int("xmssize"); + if (!size) return; + if (size>C_MEM_MAX_SIZE-1) size=C_MEM_MAX_SIZE-1; DOS_AddMultiplexHandler(multiplex_xms); call_xms=CALLBACK_Allocate(); CALLBACK_Setup(call_xms,&XMS_Handler,CB_RETF); @@ -348,6 +350,6 @@ void XMS_Init(Section* sec) { /* Setup the 1st handle */ xms_handles[1].active=true; xms_handles[1].phys=1088*1024; /* right behind the hma area */ - xms_handles[1].size=C_MEM_XMS_SIZE*1024-64; + xms_handles[1].size=size*1024-64; } From ee131d244bbe9f5cc5bd561b4f254f2d418689bb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 15:47:14 +0000 Subject: [PATCH 0272/4131] Use the emssize property under dos section now. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@349 --- src/ints/ems.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 164a7094..1175ae95 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -442,7 +442,7 @@ static Bitu INT67_Handler(void) { reg_ah = EMM_NO_ERROR; break; case 0xDE: /* VCPI Functions */ - LOG_ERROR("VCPI Functions not supported"); + LOG_ERROR("VCPI Functions %X not supported",reg_al); reg_ah=EMM_FUNC_NOSUP; break; default: @@ -457,7 +457,8 @@ static Bitu INT67_Handler(void) { void EMS_Init(Section* sec) { Section_prop * section=static_cast(sec); - if(!section->Get_bool("STATUS")) return; + Bitu size=section->Get_int("emssize"); + if (!size) return; call_int67=CALLBACK_Allocate(); CALLBACK_Setup(call_int67,&INT67_Handler,CB_IRET); /* Register the ems device */ From 0b581f1924a6dae96e42b9a15c939c250a421fee Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 15:48:27 +0000 Subject: [PATCH 0273/4131] Low case propery names and extra protection against NULL string for file name Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@350 --- src/misc/messages.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index c2da9d54..9df0ea1e 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -58,6 +58,7 @@ void MSG_Replace(const char * _name, const char* _val) { MSG_Add(_name,_val); } static void LoadMessageFile(const char * fname) { + if (!fname) return; if(*fname=='\0') return;//empty string=no languagefile FILE * mfile=fopen(fname,"rb"); /* This should never happen and since other modules depend on this use a normal printf */ @@ -119,9 +120,8 @@ void MSG_Write(const char * location) { } void MSG_Init(Section_prop * section) { - /* Load the messages from "dosbox.lang file" */ std::string file_name; if (control->cmdline->FindString("-lang",file_name)) { LoadMessageFile(file_name.c_str()); - } else LoadMessageFile(section->Get_string("LANGUAGE")); + } else LoadMessageFile(section->Get_string("language")); } From 9efdfcdf1fb2299798a6c8f81592f6119a82ae96 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 15:49:40 +0000 Subject: [PATCH 0274/4131] Add destroying of sections in the config destructor. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@351 --- src/misc/setup.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 33c14ed9..eadee807 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -196,10 +196,19 @@ Section_line* Config::AddSection_line(const char* _name,void (*_initfunction)(Se void Config::Init(){ for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ + LOG_DEBUG("Init %s",(*tel)->sectionname.c_str()); (*tel)->ExecuteInit(); } } +Config::~Config() { + reverse_it cnt=sectionlist.rbegin(); + while (cnt!=sectionlist.rend()) { + delete (*cnt); + cnt++; + } +} + Section* Config::GetSection(const char* _sectionname){ for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ if ( (*tel)->sectionname==_sectionname) return (*tel); @@ -248,9 +257,6 @@ void Config::StartUp(void) { (*_start_function)(); } - - - bool CommandLine::FindExist(char * name,bool remove) { cmd_it it; if (!(FindEntry(name,it,false))) return false; From 0082ef5eae9991636244fe116706248b4cf22a5e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 15:52:13 +0000 Subject: [PATCH 0275/4131] New classes for DTA,ParamBlock and probably some others. Changes to the names of some of the dos functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@352 --- include/dos_inc.h | 555 ++++++++++++++++++++++++---------------------- 1 file changed, 292 insertions(+), 263 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 299e8358..343147de 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -23,56 +23,11 @@ #include #pragma pack (1) - struct CommandTail{ Bit8u count; /* number of bytes returned */ char buffer[127]; /* the buffer itself */ } GCC_ATTRIBUTE(packed); -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 */ - 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[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); - -struct ParamBlock { - union { - struct { - Bit16u loadseg; - Bit16u relocation; - } overlay; - struct { - Bit16u envseg; - RealPt cmdtail; - RealPt fcb1; - RealPt fcb2; - RealPt initsssp; - RealPt initcsip; - } exec; - }; -} GCC_ATTRIBUTE(packed); - struct MCB { Bit8u type; @@ -90,7 +45,6 @@ struct DOS_Date { Bit8u day; }; - struct DOS_Version { Bit8u major,minor,revision; }; @@ -106,50 +60,183 @@ struct DOS_Block { RealPt dta; Bit8u return_code,return_mode; + Bit8u current_drive; bool verify; bool breakcheck; struct { RealPt indosflag; + RealPt mediaid; + RealPt tempdta; } tables; }; -class MemStruct { -public: - Bit8u GetIt(Bit8u,PhysPt addr) { - return mem_readb(pt+addr); - }; - Bit16u GetIt(Bit16u,PhysPt addr) { - return mem_readw(pt+addr); - }; - Bit32u GetIt(Bit32u,PhysPt addr) { - return mem_readd(pt+addr); - }; - void SaveIt(Bit8u,PhysPt addr,Bit8u val) { - mem_writeb(pt+addr,val); - }; - void SaveIt(Bit16u,PhysPt addr,Bit16u val) { - mem_writew(pt+addr,val); - }; - void SaveIt(Bit32u,PhysPt addr,Bit32u val) { - mem_writed(pt+addr,val); - }; - +enum { MCB_FREE=0x0000,MCB_DOS=0x0008 }; +enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; -protected: -PhysPt pt; +#define DOS_FILES 50 +#define DOS_DRIVES 26 -}; +/* internal Dos Tables */ +extern DOS_Block dos; +extern DOS_File * Files[DOS_FILES]; +extern DOS_Drive * Drives[DOS_DRIVES]; +extern Bit8u dos_copybuf[0x10000]; + + +void DOS_SetError(Bit16u code); + +/* File Handling Routines */ + +enum { STDIN=0,STDOUT=1,STDERR=2,STDAUX=3,STDNUL=4,STDPRN=5}; +enum { HAND_NONE=0,HAND_FILE,HAND_DEVICE}; + +/* Routines for File Class */ +void DOS_SetupFiles (void); +bool DOS_ReadFile(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_CloseFile(Bit16u handle); +bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry); +bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry); + +/* Routines for Drive Class */ +bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry); +bool DOS_CreateFile(char * name,Bit16u attribute,Bit16u * entry); +bool DOS_UnlinkFile(char * name); +bool DOS_FindFirst(char *search,Bit16u attr); +bool DOS_FindNext(void); +bool DOS_Canonicalize(char * name,char * big); +bool DOS_CreateTempFile(char * name,Bit16u * entry); +bool DOS_FileExists(char * name); + +/* Drive Handing Routines */ +Bit8u DOS_GetDefaultDrive(void); +void DOS_SetDefaultDrive(Bit8u drive); +bool DOS_SetDrive(Bit8u drive); +bool DOS_GetCurrentDir(Bit8u drive,char * bugger); +bool DOS_ChangeDir(char * dir); +bool DOS_MakeDir(char * dir); +bool DOS_RemoveDir(char * dir); +bool DOS_Rename(char * oldname,char * newname); +bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free); +bool DOS_GetFileAttr(char * name,Bit16u * attr); + +/* IOCTL Stuff */ +bool DOS_IOCTL(Bit8u call,Bit16u entry); +bool DOS_GetSTDINStatus(); +Bit8u DOS_FindDevice(char * name); +void DOS_SetupDevices(void); + +/* Execute and new process creation */ +bool DOS_NewPSP(Bit16u pspseg,Bit16u size); +bool DOS_Execute(char * name,PhysPt block,Bit8u flags); +bool DOS_Terminate(bool tsr); + +/* Memory Handling Routines */ +void DOS_SetupMemory(void); +bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks); +bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks); +bool DOS_FreeMemory(Bit16u segment); +void DOS_FreeProcessMemory(Bit16u pspseg); +Bit16u DOS_GetMemory(Bit16u pages); + +/* FCB stuff */ +bool DOS_FCBOpenCreate(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); +bool DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u numBlocks); +Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore); +bool DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore); +bool DOS_FCBGetFileSize(Bit16u seg,Bit16u offset,Bit16u numRec); +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); + +/* Extra DOS Interrupts */ +void DOS_SetupMisc(void); + +/* The DOS Tables */ +void DOS_SetupTables(void); + +/* Internal DOS Setup Programs */ +void DOS_SetupPrograms(void); + +INLINE Bit16u long2para(Bit32u size) { + if (size>0xFFFF0) return 0xffff; + if (size&0xf) return (Bit16u)((size>>4)+1); + else return (Bit16u)(size>>4); +} + + +INLINE Bit16u DOS_PackTime(Bit16u hour,Bit16u min,Bit16u sec) { + return (hour&0x1f)<<11 | (min&0x3f) << 5 | ((sec/2)&0x1f); +} + +INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) { + return ((year-1980)&0x7f)<<9 | (mon&0x3f) << 5 | (day&0x1f); +} + +/* Dos Error Codes */ +#define DOSERR_NONE 0 +#define DOSERR_FUNCTION_NUMBER_INVALID 1 +#define DOSERR_FILE_NOT_FOUND 2 +#define DOSERR_PATH_NOT_FOUND 3 +#define DOSERR_TOO_MANY_OPEN_FILES 4 +#define DOSERR_ACCESS_DENIED 5 +#define DOSERR_INVALID_HANDLE 6 +#define DOSERR_MCB_DESTROYED 7 +#define DOSERR_INSUFFICIENT_MEMORY 8 +#define DOSERR_MB_ADDRESS_INVALID 9 +#define DOSERR_ENVIRONMENT_INVALID 10 +#define DOSERR_FORMAT_INVALID 11 +#define DOSERR_ACCESS_CODE_INVALID 12 +#define DOSERR_DATA_INVALID 13 +#define DOSERR_RESERVED 14 +#define DOSERR_FIXUP_OVERFLOW 14 +#define DOSERR_INVALID_DRIVE 15 +#define DOSERR_REMOVE_CURRENT_DIRECTORY 16 +#define DOSERR_NOT_SAME_DEVICE 17 +#define DOSERR_NO_MORE_FILES 18 + +/* Remains some classes used to access certain things */ #define sGet(s,m) GetIt(((s *)Phys2Host(pt))->m,(PhysPt)&(((s *)0)->m)) #define sSave(s,m,val) SaveIt(((s *)Phys2Host(pt))->m,(PhysPt)&(((s *)0)->m),val) +class MemStruct { +public: + INLINE Bit8u GetIt(Bit8u,PhysPt addr) { + return mem_readb(pt+addr); + } + INLINE Bit16u GetIt(Bit16u,PhysPt addr) { + return mem_readw(pt+addr); + } + INLINE Bit32u GetIt(Bit32u,PhysPt addr) { + return mem_readd(pt+addr); + } + INLINE void SaveIt(Bit8u,PhysPt addr,Bit8u val) { + mem_writeb(pt+addr,val); + } + INLINE void SaveIt(Bit16u,PhysPt addr,Bit16u val) { + mem_writew(pt+addr,val); + } + INLINE void SaveIt(Bit32u,PhysPt addr,Bit32u val) { + mem_writed(pt+addr,val); + } + INLINE void SetPt(Bit16u seg) { pt=PhysMake(seg,0);} + INLINE void SetPt(Bit16u seg,Bit16u off) { pt=PhysMake(seg,off);} + INLINE void SetPt(RealPt addr) { pt=Real2Phys(addr);} +protected: + PhysPt pt; +}; + class DOS_PSP :public MemStruct { public: - DOS_PSP () { seg=0; pt=0; }; - DOS_PSP (Bit16u segment) { NewPt(segment); }; - void NewPt (Bit16u segment); + DOS_PSP (Bit16u segment) { SetPt(segment);seg=segment;psp=(sPSP *)HostMake(segment,0);}; void MakeNew (Bit16u memSize); - void CopyFileTable (DOS_PSP* srcpsp); Bit16u FindFreeFileEntry (void); void CloseFiles (void); @@ -176,202 +263,74 @@ public: void SetCommandTail (RealPt src); private: + #pragma pack(1) + 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 */ + 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[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); + #pragma pack() Bit16u seg; sPSP* psp; - public: static Bit16u rootpsp; }; -enum { MCB_FREE=0x0000,MCB_DOS=0x0008 }; -enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; - -#define DOS_FILES 50 -#define DOS_DRIVES 26 - -/* internal Dos Tables */ -extern DOS_Block dos; -extern DOS_File * Files[DOS_FILES]; -extern DOS_Drive * Drives[DOS_DRIVES]; - - -void DOS_SetError(Bit16u code); - -/* File Handling Routines */ - -enum { STDIN=0,STDOUT=1,STDERR=2,STDAUX=3,STDNUL=4,STDPRN=5}; -enum { HAND_NONE=0,HAND_FILE,HAND_DEVICE}; - - - -/* Routines for File Class */ -void DOS_SetupFiles (void); - -bool DOS_ReadFile(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_CloseFile(Bit16u handle); -bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry); -bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry); -/* Routines for Drive Class */ -bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry); -bool DOS_CreateFile(char * name,Bit16u attribute,Bit16u * entry); -bool DOS_UnlinkFile(char * name); -bool DOS_FindFirst(char *search,Bit16u attr); -bool DOS_FindNext(void); -bool DOS_Canonicalize(char * name,char * big); -bool DOS_CreateTempFile(char * name,Bit16u * entry); -bool DOS_FileExists(char * name); -/* Drive Handing Routines */ -Bit8u DOS_GetDefaultDrive(void); -void DOS_SetDefaultDrive(Bit8u drive); -bool DOS_SetDrive(Bit8u drive); -bool DOS_GetCurrentDir(Bit8u drive,char * bugger); -bool DOS_ChangeDir(char * dir); -bool DOS_MakeDir(char * dir); -bool DOS_RemoveDir(char * dir); -bool DOS_Rename(char * oldname,char * newname); -bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free); -bool DOS_GetFileAttr(char * name,Bit16u * attr); -/* IOCTL Stuff */ -bool DOS_IOCTL(Bit8u call,Bit16u entry); -bool DOS_GetSTDINStatus(); -Bit8u DOS_FindDevice(char * name); -void DOS_SetupDevices(void); -/* Execute and new process creation */ -bool DOS_NewPSP(Bit16u pspseg,Bit16u size); -bool DOS_Execute(char * name,ParamBlock * block,Bit8u flags); -bool DOS_Terminate(bool tsr); - -/* Memory Handling Routines */ -void DOS_SetupMemory(void); -bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks); -bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks); -bool DOS_FreeMemory(Bit16u segment); -void DOS_FreeProcessMemory(Bit16u pspseg); -Bit16u DOS_GetMemory(Bit16u pages); - - -/* FCB stuff */ -bool DOS_FCBOpen(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); -bool DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u numBlocks); -bool DOS_FCBCreate(Bit16u seg,Bit16u offset); -Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec); -bool DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u numRec); -bool DOS_FCBGetFileSize(Bit16u seg,Bit16u offset,Bit16u numRec); -bool DOS_FCBDeleteFile(Bit16u seg,Bit16u offset); -bool DOS_FCBRenameFile(Bit16u seg, Bit16u offset); -Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u *change); -/* Extra DOS Interrupts */ -void DOS_SetupMisc(void); - -/* The DOS Tables */ -void DOS_SetupTables(void); -/* Internal DOS Setup Programs */ -void DOS_SetupPrograms(void); - - -INLINE Bit16u long2para(Bit32u size) { - if (size>0xFFFF0) return 0xffff; - if (size&0xf) return (Bit16u)((size>>4)+1); - else return (Bit16u)(size>>4); -}; - -INLINE Bit8u RealHandle(Bit16u handle) { - - DOS_PSP psp(dos.psp); - return psp.GetFileHandle((Bit8u)handle); -}; - -/* Dos Error Codes */ -#define DOSERR_NONE 0 -#define DOSERR_FUNCTION_NUMBER_INVALID 1 -#define DOSERR_FILE_NOT_FOUND 2 -#define DOSERR_PATH_NOT_FOUND 3 -#define DOSERR_TOO_MANY_OPEN_FILES 4 -#define DOSERR_ACCESS_DENIED 5 -#define DOSERR_INVALID_HANDLE 6 -#define DOSERR_MCB_DESTROYED 7 -#define DOSERR_INSUFFICIENT_MEMORY 8 -#define DOSERR_MB_ADDRESS_INVALID 9 -#define DOSERR_ENVIRONMENT_INVALID 10 -#define DOSERR_FORMAT_INVALID 11 -#define DOSERR_ACCESS_CODE_INVALID 12 -#define DOSERR_DATA_INVALID 13 -#define DOSERR_RESERVED 14 -#define DOSERR_FIXUP_OVERFLOW 14 -#define DOSERR_INVALID_DRIVE 15 -#define DOSERR_REMOVE_CURRENT_DIRECTORY 16 -#define DOSERR_NOT_SAME_DEVICE 17 -#define DOSERR_NO_MORE_FILES 18 - -/* Remains some classes used to access certain things */ -class DOS_FCB { +class DOS_ParamBlock:public MemStruct { public: - DOS_FCB(PhysPt pt){ - off=pt; - } - DOS_FCB(Bit16u seg, Bit16u offset){ - off=PhysMake(seg,offset); - } - void Set_drive(Bit8u a); - void Set_filename(char* a); //writes an the first 8 bytes of a as the filename - void Set_ext(char* a); - void Set_current_block(Bit16u a); - void Set_record_size(Bit16u a); - void Set_filesize(Bit32u a); - void Set_date(Bit16u a); - void Set_time(Bit16u a); - void Set_current_record(Bit8u a); - void Set_random_record(Bit32u a); - // others nog yet handled - Bit8u Get_drive(void); - void Get_filename(char* a); - void Get_ext(char* a); - Bit16u Get_current_block(void); - Bit16u Get_record_size(void); - Bit32u Get_filesize(void); - Bit16u Get_date(void); - Bit16u Get_time(void); - Bit8u Get_current_record(void); - Bit32u Get_random_record(void); -private: - PhysPt off; -}; - -class DOS_ParamBlock { -public: - DOS_ParamBlock(PhysPt pt){ - off=pt; + DOS_ParamBlock(PhysPt addr) {pt=addr;} + void Clear(void); + void LoadData(void); + void SaveData(void); + #pragma pack (1) + union sPBlock { + struct { + Bit16u loadseg; + Bit16u relocation; + } overlay GCC_ATTRIBUTE(packed); + struct { + Bit16u envseg; + RealPt cmdtail; + RealPt fcb1; + RealPt fcb2; + RealPt initsssp; + RealPt initcsip; + } exec GCC_ATTRIBUTE(packed); }; - void InitExec(RealPt cmdtail); - Bit16u loadseg(void); - Bit16u relocation(void); - Bit16u envseg(void); - RealPt initsssp(void); - RealPt initcsip(void); - RealPt fcb1(void); - RealPt fcb2(void); - RealPt cmdtail(void); -private: - PhysPt off; + #pragma pack() + sPBlock data; }; -class DOS_InfoBlock { +class DOS_InfoBlock:public MemStruct { public: - DOS_InfoBlock (void) { seg=0; dib=0; }; - - void SetLocation (Bit16u segment); - void SetFirstMCB (RealPt pt); - void GetDIBPointer (Bit16u& segment, Bit16u& offset); - + DOS_InfoBlock () {}; + void SetLocation(Bit16u seg); + void SetFirstMCB(RealPt _first_mcb); + void SetfirstFileTable(RealPt _first_table); + RealPt GetPointer (void); private: - #pragma pack (push,1) - struct SDosInfoBlock { + #pragma pack(1) + struct sDIB { Bit8u stuff1[22]; // some stuff, hopefully never used.... RealPt firstMCB; // first memory control block RealPt firstDPB; // first drive parameter block @@ -384,13 +343,83 @@ private: RealPt fcbTable; // pointer to system FCB table // some more stuff, hopefully never used. } GCC_ATTRIBUTE(packed); - #pragma pack (pop) - - SDosInfoBlock* dib; - Bit16u seg; + #pragma pack () + Bit16u seg; }; -extern DOS_InfoBlock dosInfoBlock; +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); +private: + #pragma pack(1) + struct sDTA { + Bit8u sdrive; /* The Drive the search is taking place */ + Bit8u sattr; /* The Attributes that need to be found */ + Bit8u sname[8]; /* The Search pattern for the filename */ + Bit8u sext[3]; /* The Search pattern for the extenstion */ + Bit8u fill[8]; + Bit8u attr; + Bit16u time; + Bit16u date; + Bit32u size; + char name[DOS_NAMELENGTH_ASCII]; + } GCC_ATTRIBUTE(packed); + #pragma pack() +}; + +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); +private: + bool extended; + PhysPt real_pt; + #pragma pack (1) + 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 file_handle; + Bit8u reserved[7]; + /* end */ + Bit8u cur_rec; /* Current record in current block */ + Bit32u rndm; /* Current relative record number */ + } GCC_ATTRIBUTE(packed); + #pragma pack () +}; + +extern DOS_InfoBlock dos_infoblock;; + +INLINE Bit8u RealHandle(Bit16u handle) { + DOS_PSP psp(dos.psp); + return psp.GetFileHandle((Bit8u)handle); +} #endif From 316b174621a4ddbaebda2621cb8faf8e4f2730f1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 15:53:56 +0000 Subject: [PATCH 0276/4131] Added support to register destroy functions to a section. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@353 --- include/setup.h | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/include/setup.h b/include/setup.h index 538d0e63..865165fc 100644 --- a/include/setup.h +++ b/include/setup.h @@ -107,17 +107,25 @@ public: class Section { public: Section(const char* _sectionname) { sectionname=_sectionname; } - virtual ~Section(){ } + virtual ~Section(){ ExecuteDestroy();} - typedef void (*InitFunction)(Section*); - void AddInitFunction(InitFunction func) {initfunctions.push_back(func);} + typedef void (*SectionFunction)(Section*); + void AddInitFunction(SectionFunction func) {initfunctions.push_back(func);} + void AddDestroyFunction(SectionFunction func) {destroyfunctions.push_front(func);} void ExecuteInit() { - typedef std::list::iterator func_it; + typedef std::list::iterator func_it; for (func_it tel=initfunctions.begin(); tel!=initfunctions.end(); tel++){ (*tel)(this); } } - std::list initfunctions; + void ExecuteDestroy() { + typedef std::list::iterator func_it; + for (func_it tel=destroyfunctions.begin(); tel!=destroyfunctions.end(); tel++){ + (*tel)(this); + } + } + std::list initfunctions; + std::list destroyfunctions; virtual void HandleInputline(char * _line){} virtual void PrintData(FILE* outfile) {} std::string sectionname; @@ -155,7 +163,7 @@ public: class Config{ public: Config(CommandLine * cmd){ cmdline=cmd;} - + ~Config(); CommandLine * cmdline; Section * AddSection(const char * _name,void (*_initfunction)(Section*)); @@ -173,6 +181,7 @@ public: std::list sectionlist; typedef std::list::iterator it; + typedef std::list::reverse_iterator reverse_it; private: void (* _start_function)(void); }; From 77d9ca64aa550e244e52bb3ce2f8a090056e8029 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 16:21:08 +0000 Subject: [PATCH 0277/4131] Added and changed a lot of functions to the file and drive classes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@354 --- include/dos_system.h | 63 +++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 0b240d03..0223a9a6 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -19,11 +19,13 @@ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ -#include +#include "dosbox.h" #define DOS_NAMELENGTH 12 -#define DOS_DIRDEPTH 16 -#define DOS_PATHLENGTH (DOS_DIRDEPTH+1)*(DOS_NAMELENGTH+2) +#define DOS_NAMELENGTH_ASCII (DOS_NAMELENGTH+1) +#define DOS_FCBNAME 15 +#define DOS_DIRDEPTH 8 +#define DOS_PATHLENGTH 80 #define DOS_TEMPSIZE 1024 enum { @@ -35,34 +37,29 @@ enum { DOS_ATTR_ARCHIVE= 0x20 }; -#if defined (_MSC_VER) -#pragma pack(1) -#endif -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; +struct FileStat_Block { + Bit32u size; Bit16u time; Bit16u date; - Bit32u size; - char name[DOS_NAMELENGTH]; -} -#if defined (_MSC_VER) -; -#pragma pack() -#else -__attribute__ ((packed)); -#endif + Bit16u attr; +}; + +class DOS_DTA; class DOS_File { public: + virtual ~DOS_File(){}; virtual bool Read(Bit8u * data,Bit16u * size)=0; virtual bool Write(Bit8u * data,Bit16u * size)=0; virtual bool Seek(Bit32u * pos,Bit32u type)=0; virtual bool Close()=0; virtual Bit16u GetInformation(void)=0; - Bit8u type;Bit32u flags; + Bit8u type; + Bit32u flags; + Bit16u time; + Bit16u date; + Bit16u attr; + Bit32u size; /* Some Device Specific Stuff */ }; @@ -73,24 +70,24 @@ public: Bit8u fhandle; }; - - class DOS_Drive { public: DOS_Drive(); + virtual ~DOS_Drive(){}; virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags)=0; virtual bool FileCreate(DOS_File * * file,char * name,Bit16u attributes)=0; - virtual bool FileUnlink(char * name)=0; - virtual bool RemoveDir(char * dir)=0; - virtual bool MakeDir(char * dir)=0; - virtual bool TestDir(char * dir)=0; - virtual bool FindFirst(char * search,DTA_FindBlock * dta)=0; - virtual bool FindNext(DTA_FindBlock * dta)=0; + virtual bool FileUnlink(char * _name)=0; + virtual bool RemoveDir(char * _dir)=0; + virtual bool MakeDir(char * _dir)=0; + virtual bool TestDir(char * _dir)=0; + virtual bool FindFirst(char * _dir,DOS_DTA & dta)=0; + virtual bool FindNext(DOS_DTA & dta)=0; virtual bool GetFileAttr(char * name,Bit16u * attr)=0; virtual bool Rename(char * oldname,char * newname)=0; - virtual bool FreeSpace(Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free)=0; - virtual bool FileExists(const char* name) const=0; - virtual bool FileStat(const char* name, struct stat* const stat_block) const=0; + virtual bool AllocationInfo(Bit16u * _bytes_sector,Bit16u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters)=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; char * GetInfo(void); char curdir[DOS_PATHLENGTH]; char info[256]; @@ -109,6 +106,6 @@ typedef bool (MultiplexHandler)(void); void DOS_AddMultiplexHandler(MultiplexHandler * handler); void DOS_AddDevice(DOS_Device * adddev); -void VFILE_Register(char * name,Bit8u * data,Bit32u size); +void VFILE_Register(const char * name,Bit8u * data,Bit32u size); #endif From 4070fb15df488b30ba9bfe3c827622bc767b8d19 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 16:21:49 +0000 Subject: [PATCH 0278/4131] Stripped out pretty much everything for later maybe. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@355 --- src/hardware/hardware.cpp | 78 +-------------------------------------- 1 file changed, 2 insertions(+), 76 deletions(-) diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 6495fd57..49cf7226 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -24,84 +24,10 @@ #include "dosbox.h" #include "programs.h" #include "hardware.h" - -static HWBlock * firsthw=0; +#include "setup.h" -class HWSET : public Program { -public: - void Run(void); -}; +void HARDWARE_Init(Section * sec) { -void HW_Register(HWBlock * block) { - block->next=firsthw; - firsthw=block; } - -void HWSET::Run(void) { - /* Hopefull enough space */ -#if 0 - char buf[1024]; - HWBlock * loopblock; - if (!*prog_info->cmd_line) { - /* No command line given give overview of hardware */ - loopblock=firsthw; - WriteOut("ÚÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿"); - WriteOut("³Device ³Full Name ³Status ³"); - WriteOut("ÃÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´"); - while (loopblock) { - if (loopblock->show_status) { - loopblock->show_status(buf); - } else { - strcpy(buf,"No Status Handler"); - } - WriteOut("³%-8s³%-25s³%-43s³",loopblock->dev_name,loopblock->full_name,buf); - loopblock=loopblock->next; - } - WriteOut("ÀÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ"); - WriteOut("If you want to setup specific hardware use \"HWSET Device\" for information.\n"); - return; - } - /* Command line given */ - if (strcmp(prog_info->cmd_line,"/?")==0) { - WriteOut("Hardware setup tool for DOSBox.\n"); - WriteOut("This program can be used to change the settings of internal hardware.\n\n" - "HWSET [device] [switches]\n\n" - "Using an empty command line gives you a list of hardware.\n" - "You can get list of switches for a device with HWSET device.\n" - ); - return; - } - char * rest=strchr(prog_info->cmd_line,' '); - if (rest) *rest++=0; - loopblock=firsthw; - while (loopblock) { - if (strcasecmp(loopblock->dev_name,prog_info->cmd_line)==0) goto founddev; - loopblock=loopblock->next; - } - WriteOut("Device %s not found\n",prog_info->cmd_line); - return; -founddev: -/* Check for rest of line */ - if (rest) { - strcpy(buf,rest); - loopblock->get_input(buf); - WriteOut(buf); - - } else { - WriteOut("Command overview for %s\n%s",loopblock->full_name,loopblock->help); - } - return; -#endif -} - -static void HWSET_ProgramStart(Program * * make) { - *make=new HWSET; -} - - -void HARDWARE_Init(void) { - PROGRAMS_MakeFile("HWSET.COM",HWSET_ProgramStart); -}; - From e71d872095ba32fe9f62037aff8cae2163c1efbc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 16:23:21 +0000 Subject: [PATCH 0279/4131] New drive functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@356 --- src/dos/drives.h | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/src/dos/drives.h b/src/dos/drives.h index b46e376a..910f147d 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -22,30 +22,39 @@ #include #include #include "dos_system.h" +#include "cross.h" + + +bool WildFileCmp(const char * file, const char * wild); class localDrive : public DOS_Drive { public: - localDrive(char * startdir); + localDrive(const char * startdir,Bit16u _bytes_sector,Bit16u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid); bool FileOpen(DOS_File * * file,char * name,Bit32u flags); bool FileCreate(DOS_File * * file,char * name,Bit16u attributes); bool FileUnlink(char * name); bool RemoveDir(char * dir); bool MakeDir(char * dir); bool TestDir(char * dir); - bool FindFirst(char * search,DTA_FindBlock * dta); - bool FindNext(DTA_FindBlock * dta); + bool FindFirst(char * _dir,DOS_DTA & dta); + bool FindNext(DOS_DTA & dta); bool GetFileAttr(char * name,Bit16u * attr); bool Rename(char * oldname,char * newname); - bool FreeSpace(Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free); - bool FileExists(const char* name) const ; - bool FileStat(const char* name, struct stat* const stat_block) const; + bool AllocationInfo(Bit16u * _bytes_sector,Bit16u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters); + bool FileExists(const char* name); + bool FileStat(const char* name, FileStat_Block * const stat_block); + Bit8u GetMediaByte(void); private: - bool FillDTABlock(DTA_FindBlock * dta); - char basedir[512]; - char directory[512]; - char wild_name[15]; - char * wild_ext; - DIR *pdir; + char basedir[CROSS_LEN]; + char srch_dir[CROSS_LEN]; + DIR * srch_opendir; + struct { + Bit16u bytes_sector; + Bit16u sectors_cluster; + Bit16u total_clusters; + Bit16u free_clusters; + Bit8u mediaid; + } allocation; }; struct VFILE_Block; @@ -60,17 +69,16 @@ public: bool RemoveDir(char * dir); bool MakeDir(char * dir); bool TestDir(char * dir); - bool FindFirst(char * search,DTA_FindBlock * dta); - bool FindNext(DTA_FindBlock * dta); + bool FindFirst(char * _dir,DOS_DTA & dta); + bool FindNext(DOS_DTA & dta); bool GetFileAttr(char * name,Bit16u * attr); bool Rename(char * oldname,char * newname); - bool FreeSpace(Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free); - bool FileExists(const char* name) const ; - bool FileStat(const char* name, struct stat* const stat_block) const; - + bool AllocationInfo(Bit16u * _bytes_sector,Bit16u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters); + bool FileExists(const char* name); + bool FileStat(const char* name, FileStat_Block* const stat_block); + Bit8u GetMediaByte(void); private: VFILE_Block * search_file; - char search_string[255]; }; #endif From 5a86454c46a13e9b70f92726a204be5c138c5289 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:18:36 +0000 Subject: [PATCH 0280/4131] Changed some FCB calls and the list of lists call Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@357 --- src/dos/dos.cpp | 81 +++++++++++++++---------------------------------- 1 file changed, 25 insertions(+), 56 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index fae5778c..bd8138f5 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -29,15 +29,14 @@ #include "dos_inc.h" DOS_Block dos; -DOS_InfoBlock dosInfoBlock; +DOS_InfoBlock dos_infoblock; -static Bit8u dos_copybuf[0x10000]; -static Bitu call_20,call_21,call_theend; +Bit8u dos_copybuf[0x10000]; +static Bitu call_20,call_21; void DOS_SetError(Bit16u code) { dos.errorcode=code; -}; - +} #define DOSNAMEBUF 256 static Bitu DOS_21Handler(void) { @@ -151,7 +150,7 @@ static Bitu DOS_21Handler(void) { } break; default: - LOG_ERROR("DOS:0C:Illegal Flush STDIN Buffer call %d",reg_al); +// LOG_ERROR("DOS:0C:Illegal Flush STDIN Buffer call %d",reg_al); break; } } @@ -166,14 +165,13 @@ static Bitu DOS_21Handler(void) { reg_al=26; break; case 0x0f: /* Open File using FCB */ - if(DOS_FCBOpen(SegValue(ds),reg_dx)){ + if(DOS_FCBOpenCreate(SegValue(ds),reg_dx)){ reg_al=0; }else{ reg_al=0xff; } LOG_DEBUG("DOS:0x0f FCB-fileopen used, result:al=%d",reg_al); break; - case 0x10: /* Close File using FCB */ if(DOS_FCBClose(SegValue(ds),reg_dx)){ reg_al=0; @@ -182,7 +180,6 @@ static Bitu DOS_21Handler(void) { } LOG_DEBUG("DOS:0x10 FCB-fileclose used, result:al=%d",reg_al); break; - case 0x11: /* Find First Matching File using FCB */ if(DOS_FCBFindFirst(SegValue(ds),reg_dx)){ reg_al=0; @@ -191,7 +188,6 @@ static Bitu DOS_21Handler(void) { } LOG_DEBUG("DOS:0x11 FCB-FindFirst used, result:al=%d",reg_al); break; - case 0x12: /* Find Next Matching File using FCB */ if(DOS_FCBFindNext(SegValue(ds),reg_dx)){ reg_al=0; @@ -200,7 +196,6 @@ static Bitu DOS_21Handler(void) { } LOG_DEBUG("DOS:0x12 FCB-FindNext used, result:al=%d",reg_al); break; - case 0x13: /* Delete File using FCB */ if (DOS_FCBDeleteFile(SegValue(ds),reg_dx)) reg_al = 0x00; else reg_al = 0xFF; @@ -215,7 +210,7 @@ static Bitu DOS_21Handler(void) { LOG_DEBUG("DOS:0x15 FCB-Write used, result:al=%d",reg_al); break; case 0x16: /* Create or truncate file using FCB */ - if (DOS_FCBCreate(SegValue(ds),reg_dx)) reg_al = 0x00; + if (DOS_FCBOpenCreate(SegValue(ds),reg_dx)) reg_al = 0x00; else reg_al = 0x01; LOG_DEBUG("DOS:0x16 FCB-Create used, result:al=%d",reg_al); break; @@ -223,25 +218,19 @@ static Bitu DOS_21Handler(void) { if (DOS_FCBRenameFile(SegValue(ds),reg_dx)) reg_al = 0x00; else reg_al = 0xFF; break; + case 0x1b: /* Get allocation info for default drive */ + if (!DOS_GetAllocationInfo(0,®_cx,®_ax,®_dx)) reg_al=0xff; + break; + case 0x1c: /* Get allocation info for specific drive */ + if (!DOS_GetAllocationInfo(reg_dl,®_cx,®_ax,®_dx)) reg_al=0xff; + break; case 0x21: /* Read random record from FCB */ - { DOS_FCB fcb(SegValue(ds),reg_dx); - Bit8u curRec = fcb.Get_current_record(); - Bit16u curBlock = fcb.Get_current_block(); - reg_al = DOS_FCBRead(SegValue(ds),reg_dx,0); - fcb.Set_current_record(curRec); - fcb.Set_current_block(curBlock); - } + reg_al = DOS_FCBRandomRead(SegValue(ds),reg_dx,1,true); LOG_DEBUG("DOS:0x21 FCB-Random read used, result:al=%d",reg_al); break; case 0x22: /* Write random record to FCB */ - { DOS_FCB fcb(SegValue(ds),reg_dx); - Bit8u curRec = fcb.Get_current_record(); - Bit16u curBlock = fcb.Get_current_block(); - if (DOS_FCBRandomWrite(SegValue(ds),reg_dx,reg_cx)) reg_al = 0x00; - else reg_al = 0x01; - fcb.Set_current_record(curRec); - fcb.Set_current_block(curBlock); - } + if (DOS_FCBRandomWrite(SegValue(ds),reg_dx,1,true)) reg_al = 0x00; + else reg_al = 0x01; LOG_DEBUG("DOS:0x28 FCB-Random write used, result:al=%d",reg_al); break; case 0x23: /* Get file size for FCB */ @@ -249,19 +238,17 @@ static Bitu DOS_21Handler(void) { else reg_al = 0xFF; break; case 0x24: /* Set Random Record number for FCB */ - { DOS_FCB fcb(SegValue(ds),reg_dx); - fcb.Set_random_record(fcb.Get_current_block()*128+fcb.Get_current_record()); - } break; + DOS_FCBSetRandomRecord(SegValue(ds),reg_dx); + break; case 0x27: /* Random block read from FCB */ - reg_al = DOS_FCBRandomRead(SegValue(ds),reg_dx,reg_cx); + reg_al = DOS_FCBRandomRead(SegValue(ds),reg_dx,reg_cx,false); LOG_DEBUG("DOS:0x27 FCB-Random read used, result:al=%d",reg_al); break; case 0x28: /* Random Block write to FCB */ - if (DOS_FCBRandomWrite(SegValue(ds),reg_dx,reg_cx)) reg_al = 0x00; + if (DOS_FCBRandomWrite(SegValue(ds),reg_dx,reg_cx,false)) reg_al = 0x00; else reg_al = 0x01; LOG_DEBUG("DOS:0x28 FCB-Random write used, result:al=%d",reg_al); break; - case 0x29: /* Parse filename into FCB */ { Bit8u difference; char string[1024]; @@ -271,7 +258,6 @@ static Bitu DOS_21Handler(void) { } LOG_DEBUG("DOS:29:FCB Parse Filename, result:al=%d",reg_al); break; - case 0x18: /* NULL Function for CP/M compatibility or Extended rename FCB */ case 0x1d: /* NULL Function for CP/M compatibility or Extended rename FCB */ case 0x1e: /* NULL Function for CP/M compatibility or Extended rename FCB */ @@ -290,24 +276,6 @@ static Bitu DOS_21Handler(void) { psp.SetDTA(dos.dta); } break; - case 0x1c: /* Get allocation info for specific drive */ - LOG_DEBUG("DOS: Allocation Info call not supported correctly"); - SegSet16(ds,0xf000); - reg_bx=0; - real_writeb(0xf000,0,0); - reg_al=0x7f; - reg_cx=0x200; - reg_dx=0x1000; - break; /* TODO maybe but hardly think a game needs this */ - case 0x1b: /* Get allocation info for default drive */ - LOG_DEBUG("DOS: Allocation Info call not supported correctly"); - SegSet16(ds,0xf000); - reg_bx=0; - real_writeb(0xf000,0,0); - reg_al=0x7f; - reg_cx=0x200; - reg_dx=0x1000; - break; case 0x1f: /* Get drive parameter block for default drive */ case 0x32: /* Get drive parameter block for specific drive */ E_Exit("DOS:Unhandled call %02X",reg_ah); @@ -627,7 +595,8 @@ static Bitu DOS_21Handler(void) { case 0x4b: /* EXEC Load and/or execute program */ { MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); - if (!DOS_Execute(name1,(ParamBlock *)Phys2Host(SegPhys(es)+reg_bx),reg_al)) { + LOG_DEBUG("Execute %s %d",name1,reg_al); + if (!DOS_Execute(name1,SegPhys(es)+reg_bx,reg_al)) { reg_ax=dos.errorcode; CALLBACK_SCF(true); } @@ -672,9 +641,9 @@ static Bitu DOS_21Handler(void) { reg_bx=dos.psp; break; case 0x52: { /* Get list of lists */ - Bit16u seg; - dosInfoBlock.GetDIBPointer(seg,reg_bx); - SegSet16(es,seg); + RealPt addr=dos_infoblock.GetPointer(); + SegSet16(es,RealSeg(addr)); + reg_bx=RealOff(addr); LOG_DEBUG("Call is made for list of lists - let's hope for the best"); break; } //TODO Think hard how shit this is gonna be From 60427e0428c099bf163e908a3c689ba632fbab4c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:20:40 +0000 Subject: [PATCH 0281/4131] New classes for list of lists, parameter block, FCB's and the DTA. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@358 --- src/dos/dos_classes.cpp | 343 +++++++++++++++++++++++----------------- 1 file changed, 198 insertions(+), 145 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index c59045a7..d6f942ea 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -29,175 +29,63 @@ dos work a bit easier. */ -#pragma pack (1) -union sParamBlock { - struct { - Bit16u loadseg; - Bit16u relocation; - } overlay; - struct { - Bit16u envseg; - RealPt cmdtail; - RealPt fcb1; - RealPt fcb2; - RealPt initsssp; - RealPt initcsip; - } exec; -} GCC_ATTRIBUTE(packed); - -struct sFCB { - 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 -} GCC_ATTRIBUTE(packed); - -#pragma pack () - -#define FCB_EXTENDED (mem_readb(off)==0xFF ? 7:0) - -void DOS_FCB::Set_drive(Bit8u a){ - mem_writeb(off+offsetof(sFCB,drive)+FCB_EXTENDED,a); -} -void DOS_FCB::Set_filename(char * a){ - MEM_BlockWrite(off+offsetof(sFCB,filename)+FCB_EXTENDED,a,8); -} -void DOS_FCB::Set_ext(char * a) { - MEM_BlockWrite(off+offsetof(sFCB,ext)+FCB_EXTENDED,a,3); -} -void DOS_FCB::Set_current_block(Bit16u a){ - mem_writew(off+offsetof(sFCB,current_block)+FCB_EXTENDED,a); -} -void DOS_FCB::Set_record_size(Bit16u a){ - mem_writew(off+offsetof(sFCB,record_size)+FCB_EXTENDED,a); -} -void DOS_FCB::Set_filesize(Bit32u a){ - mem_writed(off+offsetof(sFCB,filesize)+FCB_EXTENDED,a); -} -void DOS_FCB::Set_date(Bit16u a){ - mem_writew(off+offsetof(sFCB,date)+FCB_EXTENDED,a); -} -void DOS_FCB::Set_time(Bit16u a){ - mem_writew(off+offsetof(sFCB,time)+FCB_EXTENDED,a); -} -void DOS_FCB::Set_current_record(Bit8u a){ - mem_writeb(off+offsetof(sFCB,current_relative_record_number)+FCB_EXTENDED,a); -} -void DOS_FCB::Set_random_record(Bit32u a){ - mem_writed(off+offsetof(sFCB,rel_record)+FCB_EXTENDED,a); -} -Bit8u DOS_FCB::Get_drive(void){ - return mem_readb(off+offsetof(sFCB,drive)+FCB_EXTENDED); -} -void DOS_FCB::Get_filename(char * a){ - MEM_BlockRead(off+offsetof(sFCB,filename)+FCB_EXTENDED,a,8); -} -void DOS_FCB::Get_ext(char * a){ - MEM_BlockRead(off+offsetof(sFCB,ext)+FCB_EXTENDED,a,3); -} -Bit16u DOS_FCB::Get_current_block(void){ - return mem_readw(off+offsetof(sFCB,current_block)+FCB_EXTENDED); -} -Bit16u DOS_FCB::Get_record_size(void){ - return mem_readw(off+offsetof(sFCB,record_size)+FCB_EXTENDED); -} -Bit32u DOS_FCB::Get_filesize(void){ - return mem_readd(off+offsetof(sFCB,filesize)+FCB_EXTENDED); -} -Bit16u DOS_FCB::Get_date(void){ - return mem_readw(off+offsetof(sFCB,date)+FCB_EXTENDED); -} -Bit16u DOS_FCB::Get_time(void){ - return mem_readw(off+offsetof(sFCB,time)+FCB_EXTENDED); -} -Bit8u DOS_FCB::Get_current_record(void){ - return mem_readb(off+offsetof(sFCB,current_relative_record_number)+FCB_EXTENDED); -} -Bit32u DOS_FCB::Get_random_record(void){ - return mem_readd(off+offsetof(sFCB,rel_record)+FCB_EXTENDED); +void DOS_ParamBlock::Clear(void) { + memset(&data,0,sizeof(data)); } - -void DOS_ParamBlock::InitExec(RealPt cmdtail) { - mem_writew(off+offsetof(sParamBlock,exec.envseg),0); - mem_writed(off+offsetof(sParamBlock,exec.fcb1),0); - mem_writed(off+offsetof(sParamBlock,exec.fcb2),0); - mem_writed(off+offsetof(sParamBlock,exec.cmdtail),cmdtail); +void DOS_ParamBlock::LoadData(void) { + data.exec.envseg=sGet(sPBlock,exec.envseg); + data.exec.cmdtail=sGet(sPBlock,exec.cmdtail); + data.exec.fcb1=sGet(sPBlock,exec.fcb1); + data.exec.fcb2=sGet(sPBlock,exec.fcb2); + data.exec.initsssp=sGet(sPBlock,exec.initsssp); + data.exec.initcsip=sGet(sPBlock,exec.initcsip); } -Bit16u DOS_ParamBlock::loadseg(void) { - return mem_readw(off+offsetof(sParamBlock,overlay.loadseg)); -} -Bit16u DOS_ParamBlock::relocation(void){ - return mem_readw(off+offsetof(sParamBlock,overlay.loadseg)); -} -Bit16u DOS_ParamBlock::envseg(void){ - return mem_readw(off+offsetof(sParamBlock,exec.envseg)); -} -RealPt DOS_ParamBlock::initsssp(void){ - return mem_readd(off+offsetof(sParamBlock,exec.initsssp)); -} -RealPt DOS_ParamBlock::initcsip(void){ - return mem_readd(off+offsetof(sParamBlock,exec.initcsip)); -} -RealPt DOS_ParamBlock::fcb1(void){ - return mem_readd(off+offsetof(sParamBlock,exec.fcb1)); -} -RealPt DOS_ParamBlock::fcb2(void){ - return mem_readd(off+offsetof(sParamBlock,exec.fcb2)); -} -RealPt DOS_ParamBlock::cmdtail(void){ - return mem_readd(off+offsetof(sParamBlock,exec.cmdtail)); +void DOS_ParamBlock::SaveData(void) { + sSave(sPBlock,exec.envseg,data.exec.envseg); + sSave(sPBlock,exec.cmdtail,data.exec.cmdtail); + sSave(sPBlock,exec.fcb1,data.exec.fcb1); + sSave(sPBlock,exec.fcb2,data.exec.fcb2); + sSave(sPBlock,exec.initsssp,data.exec.initsssp); + sSave(sPBlock,exec.initcsip,data.exec.initcsip); } -// * Dos Info Block (list of lists) * void DOS_InfoBlock::SetLocation(Bit16u segment) { seg = segment; - dib = (SDosInfoBlock*)HostMake(segment,0); - Bit16u size = sizeof(SDosInfoBlock); - memset(dib,0,sizeof(SDosInfoBlock)); -}; + pt=PhysMake(seg,0); +/* Clear the initual Block */ + for(Bitu i=0;ifirstMCB = pt; -}; + sSave(sDIB,firstMCB,_firstmcb); +} -void DOS_InfoBlock::GetDIBPointer(Bit16u& segment, Bit16u& offset) +void DOS_InfoBlock::SetfirstFileTable(RealPt _first_table){ + sSave(sDIB,firstFileTable,_first_table); +} + +RealPt DOS_InfoBlock::GetPointer(void) { - segment = seg; - offset = offsetof(SDosInfoBlock,firstDPB); -}; + return RealMake(seg,offsetof(sDIB,firstDPB)); +} /* program Segment prefix */ Bit16u DOS_PSP::rootpsp = 0; -void DOS_PSP::NewPt(Bit16u segment) -{ - seg = segment; - pt = PhysMake(segment,0); - // debug - psp = (sPSP*)Phys2Host(pt); -}; - void DOS_PSP::MakeNew(Bit16u mem_size) { /* get previous */ DOS_PSP prevpsp(dos.psp); /* Clear it first */ - Bitu i; + Bitu i; for (i=0;i8) size=8; + MEM_BlockWrite(pt+offsetof(sDTA,sname),pattern,size); + find_ext++; + MEM_BlockWrite(pt+offsetof(sDTA,sext),find_ext,(strlen(find_ext)>3) ? 3 : strlen(find_ext)); + } else { + MEM_BlockWrite(pt+offsetof(sDTA,sname),pattern,(strlen(pattern) > 8) ? 8 : strlen(pattern)); + } +} + +void DOS_DTA::SetResult(const char * _name,Bit32u _size,Bit16u _date,Bit16u _time,Bit8u _attr) { + MEM_BlockWrite(pt+offsetof(sDTA,name),(void *)_name,DOS_NAMELENGTH_ASCII); + sSave(sDTA,size,_size); + sSave(sDTA,date,_date); + sSave(sDTA,time,_time); + sSave(sDTA,attr,_attr); +} + + +void DOS_DTA::GetResult(char * _name,Bit32u & _size,Bit16u & _date,Bit16u & _time,Bit8u & _attr) { + MEM_BlockRead(pt+offsetof(sDTA,name),_name,DOS_NAMELENGTH_ASCII); + _size=sGet(sDTA,size); + _date=sGet(sDTA,date); + _time=sGet(sDTA,time); + _attr=sGet(sDTA,attr); +} + +Bit8u DOS_DTA::GetSearchDrive(void) { + return sGet(sDTA,sdrive); +} + +void DOS_DTA::GetSearchParams(Bit8u & attr,char * pattern) { + attr=sGet(sDTA,sattr); + char temp[11]; + MEM_BlockRead(pt+offsetof(sDTA,sname),temp,11); + memcpy(pattern,temp,8); + pattern[8]='.'; + memcpy(&pattern[9],&temp[8],3); + pattern[12]=0; + +} + +DOS_FCB::DOS_FCB(Bit16u seg,Bit16u off) { + SetPt(seg,off); + real_pt=pt; + if (sGet(sFCB,drive)==0xff) { + pt+=7; + extended=true; + } else extended=false; +} + +bool DOS_FCB::Extended(void) { + return extended; +} + +void DOS_FCB::Create(bool _extended) { + Bitu fill; + if (_extended) fill=36+7; + else fill=36; + Bitu i; + for (i=0;isize); + sSave(sFCB,time,Files[temp]->time); + sSave(sFCB,date,Files[temp]->date); +} + +void DOS_FCB::FileClose(Bit8u & _fhandle) { + _fhandle=sGet(sFCB,file_handle); + sSave(sFCB,file_handle,0xff); +} + +Bit8u DOS_FCB::GetDrive(void) { + Bit8u drive=sGet(sFCB,drive); + if (!drive) return dos.current_drive; + else return drive-1; +} + +void DOS_FCB::GetName(char * fillname) { + fillname[0]=GetDrive()+'A'; + fillname[1]=':'; + MEM_BlockRead(pt+offsetof(sFCB,filename),&fillname[2],8); + fillname[10]='.'; + MEM_BlockRead(pt+offsetof(sFCB,ext),&fillname[11],3); + fillname[14]=0; +} + +class DOS_MCB : public MemStruct{ +public: + DOS_MCB(Bit16u seg) { SetPt(seg); } +private: + struct sMCB { + Bit8u type; + Bit16u psp_segment; + Bit16u size; + Bit8u unused[3]; + Bit8u filename[8]; + } GCC_ATTRIBUTE(packed); +}; From 044a54d4b77c8f8baea68c337f1d9c5ce8008dfa Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:23:38 +0000 Subject: [PATCH 0282/4131] Updated to use new paramblock class and some endian fixes for the exe header. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@359 --- src/dos/dos_execute.cpp | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index b582a37e..80020c12 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -191,28 +191,24 @@ static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { dos.dta=RealMake(pspseg,0x80); } -static void SetupCMDLine(Bit16u pspseg,ParamBlock * block) +static void SetupCMDLine(Bit16u pspseg,DOS_ParamBlock & block) { DOS_PSP psp(pspseg); // if cmdtail==0 it will inited as empty in SetCommandTail - psp.SetCommandTail(block->exec.cmdtail); + psp.SetCommandTail(block.data.exec.cmdtail); } -bool DOS_Execute(char * name,ParamBlock * _block,Bit8u flags) { +bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { EXE_Header head;Bitu i; Bit16u fhandle;Bit16u len;Bit32u pos; Bit16u pspseg,envseg,loadseg,memsize,readsize; HostPt loadaddress;RealPt relocpt; - Bitu headersize,imagesize; + DOS_ParamBlock block(block_pt); + block.LoadData(); if (flags!=LOADNGO && flags!=OVERLAY) { E_Exit("DOS:Not supported execute mode %d for file %s",flags,name); } - - // Parameter block may be overwritten on load, so save these values ! - ParamBlock block; - memcpy(&block,_block,sizeof(ParamBlock)); - /* Check for EXE or COM File */ bool iscom=false; if (!DOS_OpenFile(name,OPEN_READ,&fhandle)) return false; @@ -221,15 +217,22 @@ bool DOS_Execute(char * name,ParamBlock * _block,Bit8u flags) { DOS_CloseFile(fhandle); return false; } + /* Convert the header to correct endian, i hope this works */ + HostPt endian=(HostPt)&head; + for (i=0;i Date: Sat, 19 Oct 2002 17:25:33 +0000 Subject: [PATCH 0283/4131] Rewrote all FCB calls and changed some other calls to support the new classes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@360 --- src/dos/dos_files.cpp | 653 +++++++++++++++++++----------------------- 1 file changed, 293 insertions(+), 360 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 2e4bc33b..3b9a93cf 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -30,25 +30,30 @@ #define DOS_FILESTART 4 +#define FCB_SUCCESS 0 +#define FCB_READ_NODATA 1 +#define FCB_READ_PARTIAL 3 +#define FCB_ERR_NODATA 1 +#define FCB_ERR_EOF 3 +#define FCB_ERR_WRITE 1 + DOS_File * Files[DOS_FILES]; DOS_Drive * Drives[DOS_DRIVES]; -static Bit8u CurrentDrive=2; //Init on C: - Bit8u DOS_GetDefaultDrive(void) { - return CurrentDrive; + return dos.current_drive; } void DOS_SetDefaultDrive(Bit8u drive) { - if (drive<=DOS_DRIVES) CurrentDrive=drive; + if (drive<=DOS_DRIVES) dos.current_drive=drive; } bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { char tempdir[DOS_PATHLENGTH]; char upname[DOS_PATHLENGTH]; Bitu r,w; - *drive=CurrentDrive; + *drive=dos.current_drive; /* First get the drive */ if (name[1]==':') { *drive=(name[0] | 0x20)-'a'; @@ -180,19 +185,30 @@ bool DOS_Rename(char * oldname,char * newname) { } bool DOS_FindFirst(char * search,Bit16u attr) { + DOS_DTA dta(dos.dta); Bit8u drive;char fullsearch[DOS_PATHLENGTH]; + char dir[DOS_PATHLENGTH];char pattern[DOS_PATHLENGTH]; if (!DOS_MakeName(search,fullsearch,&drive)) return false; - DTA_FindBlock * dtablock=(DTA_FindBlock *)Real2Host(dos.dta); - dtablock->sattr=attr | DOS_ATTR_ARCHIVE; - dtablock->sdrive=drive; - if (Drives[drive]->FindFirst(fullsearch,dtablock)) return true; + /* Split the search in dir and pattern */ + char * find_last; + find_last=strrchr(fullsearch,'\\'); + if (!find_last) { /*No dir */ + strcpy(pattern,fullsearch); + dir[0]=0; + } else { + *find_last=0; + strcpy(pattern,find_last+1); + strcpy(dir,fullsearch); + } + dta.SetupSearch(drive,attr | DOS_ATTR_ARCHIVE,pattern); + if (Drives[drive]->FindFirst(dir,dta)) return true; DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } bool DOS_FindNext(void) { - DTA_FindBlock * dtablock=(DTA_FindBlock *)Real2Host(dos.dta); - if (Drives[dtablock->sdrive]->FindNext(dtablock)) return true; + DOS_DTA dta(dos.dta); + if (Drives[dta.GetSearchDrive()]->FindNext(dta)) return true; DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } @@ -388,7 +404,7 @@ bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit16u * sectors,Bit16u * c DOS_SetError(DOSERR_INVALID_DRIVE); return false; } - return Drives[drive]->FreeSpace(bytes,sectors,clusters,free); + return Drives[drive]->AllocationInfo(bytes,sectors,clusters,free); } bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry) { @@ -457,36 +473,21 @@ bool DOS_CreateTempFile(char * name,Bit16u * entry) { return true; } + #if 1 -static bool FCB_MakeName (DOS_FCB* fcb, char* outname, Bit8u* outdrive){ - char naam[15]; - Bit8s teller=0; - Bit8u drive=fcb->Get_drive(); - if(drive!=0){ - naam[0]=(drive-1)+'A'; - naam[1]=':'; - naam[2]='\0';} - else{ - naam[0]='\0'; - }; - char temp[10]; - fcb->Get_filename(temp); - temp[8]='.'; - temp[9]='\0'; - strcat(naam,temp); - char ext[4]; - fcb->Get_ext(ext); - ext[3]='\0'; - strcat(naam,ext); - return DOS_MakeName(naam,outname, outdrive); + +static bool FCB_MakeName2 (DOS_FCB & fcb, char* outname, Bit8u* outdrive){ + char short_name[DOS_FCBNAME]; + fcb.GetName(short_name); + return DOS_MakeName(short_name,outname, outdrive); } + #define FCB_SEP ":.;,=+" #define ILLEGAL ":.;,=+ \t/\"[]<>|" -static bool isvalid(const char* in){ - +static bool isvalid(const char in){ const char ill[]=ILLEGAL; - return (Bit8u(*in)>0x1F) && (strchr(ill,*in)==0); + return (Bit8u(in)>0x1F) && (!strchr(ill,in)); } static void vullen (char* veld,char* pveld){ @@ -495,389 +496,321 @@ static void vullen (char* veld,char* pveld){ } return; } + +#define PARSE_SEP_STOP 0x01 +#define PARSE_DFLT_DRIVE 0x02 +#define PARSE_BLNK_FNAME 0x04 +#define PARSE_BLNK_FEXT 0x08 + +#define PARSE_RET_NOWILD 0 +#define PARSE_RET_WILD 1 +#define PARSE_RET_BADDRIVE 0xff + Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u *change){ - char* backup; - backup=string; + + char * string_begin=string;Bit8u ret=0; DOS_FCB fcb(seg,offset); - Bit8u retwaarde=0; - char naam[9]=" "; - char ext[4]=" "; - if((parser & 1) && *string) { //ignore leading seperator - char sep[] = FCB_SEP; - char a[2]; - a[0]= *string;a[1]='\0'; - if (strcspn(a,sep)==0) string++; - } - if((!(parser &4)) ==true){ // fill name with spaces if no name - fcb.Set_filename(naam); - } - if((!(parser &8)) ==true){ // fill ext with spaces if no ext - fcb.Set_ext(ext); - } - if((parser & 2)==false) fcb.Set_drive(0); //Set allready the defaultdrive (Will stay set when it's not specified) - // strip leading spaces - while((*string==' ')||(*string=='\t')) string++; - if( *(string+1)==':') { - Bit8u drive=toupper(*string); - if( (drive>'Z') | (drive<'A') | (Drives[drive-'A']==NULL)) { - *change=string-backup; - return 0xFF; - } - fcb.Set_drive(drive-'A'+1); - string+=2; - } - //startparsing - char* pnaam=naam; - while(isvalid(string)==true) { - if(*string=='*'){ - vullen(naam,pnaam); //fill with ???? - string++; - retwaarde=1; - break; - } - - *pnaam=*string; - pnaam++; - string++; - } - fcb.Set_filename(naam); - if((*string=='.')==false) { - *change=string-backup; - return retwaarde; - } - //extension exist - string++; - char* pext=ext; - while(isvalid(string)==true) { - if(*string=='*'){ - vullen(ext,pext); //fill with ???? - string++; - retwaarde=1; - break; - } - - *pext=*string; - pext++; - string++; - } - fcb.Set_ext(ext); - *change=string-backup; - return retwaarde; + bool hasdrive,hasname,hasext; + hasdrive=hasname=hasext=false; + Bitu index;bool finished;Bit8u fill; +/* First get the old data from the fcb */ +#pragma pack (1) + union { + struct { + char drive[2]; + char name[9]; + char ext[4]; + } part GCC_ATTRIBUTE (packed) ; + char full[DOS_FCBNAME]; + } fcb_name; +#pragma pack() + /* Get the old information from the previous fcb */ + fcb.GetName(fcb_name.full);fcb_name.part.drive[1]=0;fcb_name.part.name[8]=0;fcb_name.part.ext[3]=0; + /* Strip of the leading sepetaror */ + if((parser & PARSE_SEP_STOP) && *string) { //ignore leading seperator + char sep[] = FCB_SEP;char a[2]; + a[0]= *string;a[1]='\0'; + if (strcspn(a,sep)==0) string++; + } + /* strip leading spaces */ + while((*string==' ')||(*string=='\t')) string++; + /* Check for a drive */ + if (string[1]==':') { + fcb_name.part.drive[0]=0; + hasdrive=true; + if (isalpha(string[0]) && Drives[toupper(string[0])-'A']) { + fcb_name.part.drive[0]=toupper(string[0])-'A'+1; + } else ret=0xff; + string+=2; + } + /* Special checks for . and .. */ + if (string[0]=='.') { + string++; + if (!string[0]) { + hasname=true; + ret=PARSE_RET_NOWILD; + strcpy(fcb_name.part.name,". "); + goto savefcb; + } + if (string[1]=='.' && !string[1]) { + string++; + hasname=true; + ret=PARSE_RET_NOWILD; + strcpy(fcb_name.part.name,".. "); + goto savefcb; + } + goto checkext; + } + /* Copy the name */ + hasname=true;finished=false;fill=' ';index=0; + while (index<8) { + if (!finished) { + if (string[0]=='*') {fill='?';fcb_name.part.name[index]='?';if (!ret) ret=1;finished=true;} + else if (string[0]=='?') {fcb_name.part.name[index]='?';if (!ret) ret=1;} + else if (isvalid(string[0])) {fcb_name.part.name[index]=toupper(string[0]);} + else { finished=true;continue; } + string++; + } else { + fcb_name.part.name[index]=fill; + } + index++; + } + if (!(string[0]=='.')) goto savefcb; + string++; +checkext: + /* Copy the extension */ + hasext=true;finished=false;fill=' ';index=0; + while (index<3) { + if (!finished) { + if (string[0]=='*') {fill='?';fcb_name.part.ext[index]='?';finished=true;} + else if (string[0]=='?') {fcb_name.part.ext[index]='?';if (!ret) ret=1;} + else if (isvalid(string[0])) {fcb_name.part.ext[index]=toupper(string[0]);} + else { finished=true;continue; } + string++; + } else { + fcb_name.part.ext[index]=fill; + } + index++; + } +savefcb: + if (!hasdrive & !(parser & PARSE_DFLT_DRIVE)) fcb_name.part.drive[0]=dos.current_drive+1; + if (!hasname & !(parser & PARSE_BLNK_FNAME)) strcpy(fcb_name.part.name," "); + if (!hasext & !(parser & PARSE_BLNK_FEXT)) strcpy(fcb_name.part.ext," "); + fcb.SetName(fcb_name.part.drive[0],fcb_name.part.name,fcb_name.part.ext); + *change=(Bit8u)(string-string_begin); + return ret; } -void DOS_FCBSetDateTime(DOS_FCB& fcb,struct stat& stat_block) -{ - Bit16u constant; - struct tm *time; - if((time=localtime(&stat_block.st_mtime))!=0){ +static void DTAExtendName(char * name,char * filename,char * ext) { + char * find=strchr(name,'.'); + if (find) { + strcpy(ext,find+1); + *find=0; + } else ext[0]=0; + strcpy(filename,name); + Bitu i; + for (i=strlen(name);i<8;i++) filename[i]=' ';filename[8]=0; + for (i=strlen(ext);i<3;i++) ext[i]=' ';ext[3]=0; +} - constant=(time->tm_hour<<11)+(time->tm_min<<5)+(time->tm_sec/2); /* standard way. */ - fcb.Set_time(constant); - constant=((time->tm_year-80)<<9)+((time->tm_mon+1)<<5)+(time->tm_mday); - fcb.Set_date(constant); - } - else{ - constant=6; - fcb.Set_time(constant); - constant=4; - fcb.Set_date(constant); - } -}; +static void SaveFindResult(DOS_FCB & find_fcb) { + DOS_DTA find_dta(dos.tables.tempdta); + char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr;Bit8u drive; + char file_name[9];char ext[4]; + find_dta.GetResult(name,size,date,time,attr); + drive=find_fcb.GetDrive(); + /* Create a correct file and extention */ + DTAExtendName(name,file_name,ext); + DOS_FCB fcb(RealSeg(dos.dta),RealOff(dos.dta)); + fcb.Create(find_fcb.Extended()); + fcb.SetName(drive,file_name,ext); + fcb.SetSizeDateTime(size,date,time); +} -bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { +bool DOS_FCBOpenCreate(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); - Bit8u drive; - char fullname[DOS_PATHLENGTH]; - if(!FCB_MakeName (&fcb, fullname, &drive)) return false; - if(!Drives[drive]->FileExists(fullname)) return false; //not really needed as stat will error. - - struct stat stat_block; - if(!Drives[drive]->FileStat(fullname, &stat_block)) return false; - fcb.Set_filesize((Bit32u)stat_block.st_size); - Bit16u constant = 0; - fcb.Set_current_block(constant); - constant=0x80; - fcb.Set_record_size(constant); - - DOS_FCBSetDateTime(fcb,stat_block); - - fcb.Set_drive(drive +1); + char shortname[DOS_FCBNAME];Bit16u handle; + fcb.GetName(shortname); + if (!DOS_OpenFile(shortname,2,&handle)) return false; + fcb.FileOpen((Bit8u)handle); return true; } -bool DOS_FCBClose(Bit16u seg,Bit16u offset) -{ DOS_FCB fcb(seg,offset); - Bit8u drive; - char fullname[DOS_PATHLENGTH]; - if(!FCB_MakeName (&fcb, fullname, &drive)) return false; - if(!Drives[drive]->FileExists(fullname)) return false; - - return true;} +bool DOS_FCBClose(Bit16u seg,Bit16u offset) { + DOS_FCB fcb(seg,offset); + Bit8u fhandle; + fcb.FileClose(fhandle); + DOS_CloseFile(fhandle); + return true; +} bool DOS_FCBFindFirst(Bit16u seg,Bit16u offset) { - DOS_FCB* fcb = new DOS_FCB(seg,offset); - Bit8u drive; - Bitu i; - char fullname[DOS_PATHLENGTH]; - FCB_MakeName (fcb, fullname, &drive); - DTA_FindBlock * dtablock=(DTA_FindBlock *)Real2Host(dos.dta); - dtablock->sattr=DOS_ATTR_ARCHIVE; - dtablock->sdrive=drive; - - if(Drives[drive]->FindFirst(fullname,dtablock)==false) return false; - - char naam[9]; - char ext[4]; - char * point=strrchr(dtablock->name,'.'); - if(point==NULL|| *(point+1)=='\0') { - ext[0]=' '; - ext[1]=' '; - ext[2]=' '; - }else{ - strcpy(ext,(point+1)); - i=strlen((point+1)); - while(i!=3) {ext[i]=' ';i++;} - } - - if(point!=NULL) *point='\0'; - - strcpy (naam,dtablock->name); - i=strlen(dtablock->name); - while(i!=8) {naam[i]=' '; i++;} - delete fcb; - DOS_FCB* fcbout= new DOS_FCB((PhysPt)Real2Phys(dos.dta)); - fcbout->Set_drive(drive +1); - fcbout->Set_filename(naam); - fcbout->Set_ext(ext); - delete fcbout; - return true; - + DOS_FCB fcb(seg,offset); + RealPt old_dta=dos.dta;dos.dta=dos.tables.tempdta; + char name[DOS_FCBNAME];fcb.GetName(name); + bool ret=DOS_FindFirst(name,DOS_ATTR_ARCHIVE); + dos.dta=old_dta; + if (ret) SaveFindResult(fcb); + return ret; } + bool DOS_FCBFindNext(Bit16u seg,Bit16u offset) -{ - DOS_FCB* fcb = new DOS_FCB(seg,offset); - Bit8u drive; - Bitu i; - char fullname[DOS_PATHLENGTH]; - FCB_MakeName (fcb, fullname, &drive); - DTA_FindBlock * dtablock=(DTA_FindBlock *)Real2Host(dos.dta); - dtablock->sattr=DOS_ATTR_ARCHIVE; - dtablock->sdrive=drive; - - if(Drives[dtablock->sdrive]->FindNext(dtablock)==false) return false; - char naam[9]; - char ext[4]; - char * point=strrchr(dtablock->name,'.'); - if(point==NULL|| *(point+1)=='\0') { - ext[0]=' '; - ext[1]=' '; - ext[2]=' '; - }else - { - strcpy(ext,point+1); - i=strlen(point+1); - while(i!=3) {ext[i]=' ';i++;} - } - - if(point!=NULL) *point='\0'; - - strcpy (naam,dtablock->name); - i=strlen(dtablock->name); - while(i!=8) {naam[i]=' '; i++;} - delete fcb; - DOS_FCB* fcbout= new DOS_FCB(Real2Phys(dos.dta)); - fcbout->Set_drive(drive +1); - fcbout->Set_filename(naam); - fcbout->Set_ext(ext); - delete fcbout; - return true; - } - -bool DOS_FCBCreate(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); - Bit8u drive; - DOS_File* file; - char fullname[DOS_PATHLENGTH]; - - if (!FCB_MakeName (&fcb, fullname, &drive)) return false; - if (!Drives[drive]->FileCreate(&file,fullname,0)) return false; - // Set Date & time - struct stat stat_block; - Drives[drive]->FileStat(fullname, &stat_block); - DOS_FCBSetDateTime(fcb,stat_block); - file->Close(); - // Clear fcb - fcb.Set_record_size(128); // ? - fcb.Set_current_record(0); - fcb.Set_random_record(0); - fcb.Set_filesize(0); - return true; -}; + RealPt old_dta=dos.dta;dos.dta=dos.tables.tempdta; + bool ret=DOS_FindNext(); + dos.dta=old_dta; + if (ret) SaveFindResult(fcb); + return ret; +} -Bit8u DOS_FCBRead(Bit16u seg,Bit16u offset,Bit16u recno) -{ +Bit8u DOS_FCBRead(Bit16u seg,Bit16u offset,Bit16u recno) { DOS_FCB fcb(seg,offset); - Bit8u drive; - DOS_File* file; - char fullname[DOS_PATHLENGTH]; - // Open file - if (!FCB_MakeName (&fcb, fullname, &drive)) return 0x01; - if (!Drives[drive]->FileOpen(&file,fullname,OPEN_READ)) return 0x01; - // Position file - Bit32u filePos = (fcb.Get_current_block()*128+fcb.Get_current_record()) * fcb.Get_record_size(); - if (!file->Seek(&filePos,0x00)) { file->Close(); return 0x01; }; // end of file - // Calculate target - Bit8u* target = HostMake(RealSeg(dos.dta),RealOff(dos.dta)+recno*fcb.Get_record_size()); - // Read record - Bit16u toRead = fcb.Get_record_size(); - if (!file->Read(target,&toRead)) { file->Close(); return 0x01; }; - // fill with 0 - memset(target+toRead,0,fcb.Get_record_size()-toRead); - // Update record - Bit8u curRec = fcb.Get_current_record() + 1; - if (curRec>128) { - fcb.Set_current_record(0); - fcb.Set_current_block(fcb.Get_current_block()+1); - } else - fcb.Set_current_record(curRec); - - file->Close(); - // check for error - if (toRead0;i--) mem_writeb(fill++,0); + } + MEM_BlockWrite(Real2Phys(dos.dta)+recno*rec_size,dos_copybuf,rec_size); + if (++cur_rec>127) { cur_block++;cur_rec=0; } + fcb.SetRecord(cur_block,cur_rec); + if (toread==rec_size) return FCB_SUCCESS; + if (toread==0) return FCB_READ_NODATA; + return FCB_READ_PARTIAL; } bool DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u recno) { DOS_FCB fcb(seg,offset); - Bit8u drive; - DOS_File* file; - char fullname[DOS_PATHLENGTH]; - // Open file - if (!FCB_MakeName (&fcb, fullname, &drive)) return false; - if (!Drives[drive]->FileOpen(&file,fullname,OPEN_WRITE)) return false; - // Position file - Bit32u filePos = (fcb.Get_current_block()*128+fcb.Get_current_record()) * fcb.Get_record_size(); - if (!file->Seek(&filePos,0x00)) { file->Close(); return false; }; // end of file - // Calculate source - Bit8u* source = HostMake(RealSeg(dos.dta),RealOff(dos.dta)+recno*fcb.Get_record_size()); - // Write record - Bit16u toWrite = fcb.Get_record_size(); - if (!file->Write(source,&toWrite)) { file->Close(); return false; }; - // Update size - Bit32u fsize = fcb.Get_filesize() + toWrite; - fcb.Set_filesize(fsize); - // Update Date & Time - struct stat stat_block; - Drives[drive]->FileStat(fullname, &stat_block); - DOS_FCBSetDateTime(fcb,stat_block); - // Update record - Bit8u curRec = fcb.Get_current_record() + 1; - if (curRec>128) { - fcb.Set_current_record(0); - fcb.Set_current_block(fcb.Get_current_block()+1); - } else - fcb.Set_current_record(curRec); - - file->Close(); - return (toWrite==fcb.Get_record_size()); -}; + Bit8u fhandle,cur_rec;Bit16u cur_block,rec_size; + fcb.GetSeqData(fhandle,rec_size); + fcb.GetRecord(cur_block,cur_rec); + Bit32u pos=((cur_block*128)+cur_rec)*rec_size; + if (!DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET)) return FCB_ERR_WRITE; + MEM_BlockRead(Real2Phys(dos.dta)+recno*rec_size,dos_copybuf,rec_size); + Bit16u towrite=rec_size; + if (!DOS_WriteFile(fhandle,dos_copybuf,&towrite)) return FCB_ERR_WRITE; + Bit32u size;Bit16u date,time; + fcb.GetSizeDateTime(size,date,time); + if (pos+towrite>size) size=pos+towrite; + //TODO Set time to current time? + fcb.SetSizeDateTime(size,date,time); + if (++cur_rec>127) { cur_block++;cur_rec=0; } + fcb.SetRecord(cur_block,cur_rec); + return FCB_SUCCESS; +} + +Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { -Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec) -{ DOS_FCB fcb(seg,offset); - Bit16u recno = 0; - Bit8u error; - // Calculate block&rec - fcb.Set_current_block (Bit16u(fcb.Get_random_record() / 128)); - fcb.Set_current_record(Bit8u (fcb.Get_random_record() % 127)); + Bit32u random;Bit16u old_block;Bit8u old_rec;Bit8u error; + /* Set the correct record from the random data */ + fcb.GetRandom(random); + if (restore) fcb.GetRecord(old_block,old_rec); + fcb.SetRecord((Bit16u)(random / 128),(Bit8u)(random & 127)); // Read records for (int i=0; iFileOpen(&file,fullname,OPEN_WRITE)) return false; - struct stat stat_block; - if(!Drives[drive]->FileStat(fullname, &stat_block)) { file->Close(); return false; }; - Bit32u fsize = (Bit32u)stat_block.st_size; - //compute the size and update the fcb - fcb.Set_random_record(fsize / fcb.Get_record_size()); - if ((fsize % fcb.Get_record_size())!=0) fcb.Set_random_record(fcb.Get_random_record()+1); - fcb.Set_filesize(fsize); + fcb.GetName(shortname); + if (!DOS_OpenFile(shortname,0,&entry)) return false; + handle=RealHandle(entry); + Bit32u size=Files[handle]->size; + DOS_CloseFile(entry);fcb.GetSeqData(handle,rec_size); + Bit32u random=(size/rec_size); + if (size % rec_size) random++; + fcb.SetRandom(random); return true; -}; +} -bool DOS_FCBDeleteFile(Bit16u seg,Bit16u offset) -{ +bool DOS_FCBDeleteFile(Bit16u seg,Bit16u offset){ DOS_FCB fcb(seg,offset); - Bit8u drive; - char fullname[DOS_PATHLENGTH]; - // Open file - if (!FCB_MakeName (&fcb, fullname, &drive)) return false; - return Drives[drive]->FileUnlink(fullname); -}; + char shortname[DOS_FCBNAME]; + fcb.GetName(shortname); + return DOS_UnlinkFile(shortname); +} -bool DOS_FCBRenameFile(Bit16u seg, Bit16u offset) -{ - Bit8u olddrive,newdrive; +bool DOS_FCBRenameFile(Bit16u seg, Bit16u offset){ DOS_FCB fcbold(seg,offset); DOS_FCB fcbnew(seg,offset+16); - char oldfullname[DOS_PATHLENGTH]; - char newfullname[DOS_PATHLENGTH]; - if (!FCB_MakeName (&fcbold, oldfullname, &olddrive)) return false; - if (!FCB_MakeName (&fcbnew, newfullname, &newdrive)) return false; - //TODO Test for different drives maybe - return (Drives[newdrive]->Rename(oldfullname,newfullname)); -}; + char oldname[DOS_FCBNAME]; + char newname[DOS_FCBNAME]; + fcbold.GetName(oldname);fcbnew.GetName(newname); + return DOS_Rename(oldname,newname); +} + +void DOS_FCBSetRandomRecord(Bit16u seg, Bit16u offset) { + DOS_FCB fcb(seg,offset); + Bit16u block;Bit8u rec; + fcb.GetRecord(block,rec); + fcb.SetRandom(block*128+rec); +} #endif bool DOS_FileExists(char * name) { - char fullname[DOS_PATHLENGTH];Bit8u drive; if (!DOS_MakeName(name,fullname,&drive)) return false; return Drives[drive]->FileExists(fullname); } +bool DOS_GetAllocationInfo(Bit8u drive,Bit16u * _bytes_sector,Bit16u * _sectors_cluster,Bit16u * _total_clusters) { + if (!drive) drive=dos.current_drive; + else drive--; + if (!Drives[drive]) return false; + Bit16u _free_clusters; + Drives[drive]->AllocationInfo(_bytes_sector,_sectors_cluster,_total_clusters,&_free_clusters); + SegSet16(ds,RealSeg(dos.tables.mediaid)); + reg_bx=RealOff(dos.tables.mediaid+drive); + return true; +} bool DOS_SetDrive(Bit8u drive) { if (Drives[drive]) { DOS_SetDefaultDrive(drive); return true; - } else { return false; } From 85f1ac7d9e12afd9781f81cadb7d20ce784d344d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:26:44 +0000 Subject: [PATCH 0284/4131] The firstmcb now gets saved into the dos list of lists structure. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@361 --- src/dos/dos_memory.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 14e8a5d9..47d44f1a 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -99,7 +99,7 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { mcb_segment+=pmcb->size+1; } return false; -}; +} bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { @@ -135,7 +135,7 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { *blocks=total; DOS_SetError(DOSERR_INSUFFICIENT_MEMORY); return false; -}; +} bool DOS_FreeMemory(Bit16u segment) { @@ -151,16 +151,11 @@ bool DOS_FreeMemory(Bit16u segment) { void DOS_SetupMemory(void) { -//TODO Maybe allocate some memory for dos transfer buffers -//Although i could use bios regions for that for max free low memory MCB * mcb=(MCB *) HostMake(MEM_START,0); mcb->psp_segment=MCB_FREE; //Free mcb->size=0x9FFE - MEM_START; mcb->type=0x5a; //Last Block dos.firstMCB=MEM_START; - - // Create Dos Info Block : maximum size 95 Bytes.... - dosInfoBlock.SetLocation(DOS_GetMemory(6)); - dosInfoBlock.SetFirstMCB(RealMake(dos.firstMCB,0)); + dos_infoblock.SetFirstMCB(RealMake(MEM_START,0)); } From 35cfe5d5c759e104803f4756a39e02f46a6829ad Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:27:28 +0000 Subject: [PATCH 0285/4131] Added a multiplex handler for 0x1680 for dos programs to give up their time slice Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@362 --- src/dos/dos_misc.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index 9072d337..5280a529 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -54,6 +54,16 @@ static Bitu INT2A_Handler(void) { return CBRET_NONE; }; +static bool DOS_MultiplexFunctions(void) { + switch (reg_ax) { + case 0x1680: /* RELEASE CURRENT VIRTUAL MACHINE TIME-SLICE */ + //TODO Maybe do some idling but could screw up other systems :) + reg_al=0; + return true; + } + return false; +} + void DOS_SetupMisc(void) { /* Setup the dos multiplex interrupt */ @@ -61,6 +71,7 @@ void DOS_SetupMisc(void) { call_int2f=CALLBACK_Allocate(); CALLBACK_Setup(call_int2f,&INT2F_Handler,CB_IRET); RealSetVec(0x2f,CALLBACK_RealPointer(call_int2f)); + DOS_AddMultiplexHandler(DOS_MultiplexFunctions); /* Setup the dos network interrupt */ call_int2a=CALLBACK_Allocate(); CALLBACK_Setup(call_int2a,&INT2A_Handler,CB_IRET); From 41a4c6ba3f36ca99d2989209f684ee04942c2aaa Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:28:41 +0000 Subject: [PATCH 0286/4131] Rewrote mount to support mounting different types, setting up the media id byte and setting the reported size of the disk. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@363 --- src/dos/dos_programs.cpp | 60 ++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index d110b86c..c2e21b69 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -43,33 +43,63 @@ public: } return; } + std::string type="dir"; + cmd->FindString("-t",type,true); + if (type=="floppy" || type=="dir") { + Bit16u sizes[4]; + Bit8u mediaid; + std::string str_size; + if (type=="floppy") { + str_size="512,1,2847,2847";/* All space free */ + mediaid=0xF0; /* Floppy 1.44 media */ + } + if (type=="dir") { + str_size="512,127,16513,1700"; + mediaid=0xF8; /* Hard Disk */ + } + cmd->FindString("-size",str_size,true); + char number[20];const char * scan=str_size.c_str(); + Bitu index=0;Bitu count=0; + /* Parse the str_size string */ + while (*scan) { + if (*scan==',') { + number[index]=0;sizes[count++]=atoi(number); + index=0; + } else number[index++]=*scan; + scan++; + } + number[index]=0;sizes[count++]=atoi(number); + + + if (!cmd->FindCommand(2,temp_line)) goto showusage; + if (!temp_line.size()) goto showusage; + struct stat test; + if (stat(temp_line.c_str(),&test)) { + WriteOut("Directory %s Doesn't exist",temp_line.c_str()); + return; + } + /* Not a switch so a normal directory/file */ + if (!(test.st_mode & S_IFDIR)) { + WriteOut("%s isn't a directory",temp_line.c_str()); + return; + } + if (temp_line[temp_line.size()-1]!=CROSS_FILESPLIT) temp_line+=CROSS_FILESPLIT; + newdrive=new localDrive(temp_line.c_str(),sizes[0],sizes[1],sizes[2],sizes[3],mediaid); + } cmd->FindCommand(1,temp_line); if (temp_line.size()>1) goto showusage; drive=toupper(temp_line[0]); if (!isalpha(drive)) goto showusage; - if (!cmd->FindCommand(2,temp_line)) goto showusage; - if (!temp_line.size()) goto showusage; - struct stat test; - if (stat(temp_line.c_str(),&test)) { - WriteOut("Directory %s Doesn't exist",temp_line.c_str()); - return; - } - /* Not a switch so a normal directory/file */ - if (!(test.st_mode & S_IFDIR)) { - WriteOut("%s isn't a directory",temp_line.c_str()); - return; - } if (Drives[drive-'A']) { WriteOut("Drive %c already mounted with %s\n",drive,Drives[drive-'A']->GetInfo()); + if (newdrive) delete newdrive; return; } - if (temp_line[temp_line.size()-1]!=CROSS_FILESPLIT) temp_line+=CROSS_FILESPLIT; - newdrive=new localDrive((char *)temp_line.c_str()); if (!newdrive) E_Exit("DOS:Can't create drive"); Drives[drive-'A']=newdrive; /* Set the correct media byte in the table */ mem_writeb(Real2Phys(dos.tables.mediaid)+drive-'A',newdrive->GetMediaByte()); - WriteOut("Mounting drive %c as %s\n",drive,temp_line.c_str()); + WriteOut("Drive %c mounted as %s\n",drive,newdrive->GetInfo()); return; showusage: WriteOut("Usage MOUNT Drive-Letter Local-Directory\nSo a MOUNT c c:\\windows mounts windows directory as the c: drive in DOSBox\n"); From 5f3e49b03f0ab8f91d6569dc87a391f9d31694ea Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:29:25 +0000 Subject: [PATCH 0287/4131] Support for the updated list of lists class, now supporting a fake dos file table. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@364 --- src/dos/dos_tables.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 2318655d..dc94f920 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -20,25 +20,18 @@ #include "mem.h" #include "dos_inc.h" -#if defined (_MSC_VER) #pragma pack(1) -#endif struct DOS_TableCase { Bit16u size; Bit8u chars[256]; } -#if defined (_MSC_VER) -; -#pragma pack() -#else -__attribute__ ((packed)); -#endif - +GCC_ATTRIBUTE (packed); +#pragma pack () RealPt DOS_TableUpCase; RealPt DOS_TableLowCase; -static Bit16u dos_memseg=0xd000; +static Bit16u dos_memseg; Bit16u DOS_GetMemory(Bit16u pages) { if (pages+dos_memseg>=0xe000) { E_Exit("DOS:Not enough memory for internal tables"); @@ -50,9 +43,21 @@ Bit16u DOS_GetMemory(Bit16u pages) { void DOS_SetupTables(void) { + dos_memseg=0xd000; + Bit16u seg;Bitu i; dos.tables.indosflag=RealMake(DOS_GetMemory(1),0); + dos.tables.mediaid=RealMake(DOS_GetMemory(2),0); + dos.tables.tempdta=RealMake(DOS_GetMemory(4),0); + for (i=0;i Date: Sat, 19 Oct 2002 17:30:42 +0000 Subject: [PATCH 0288/4131] Added support for setting the size of the virtual drive. Changed the findfirst/findnext to support the new dta. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@365 --- src/dos/drive_local.cpp | 189 ++++++++++++++++++++++------------------ 1 file changed, 105 insertions(+), 84 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 3b904307..54564901 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -22,7 +22,7 @@ #include #include #include "dosbox.h" -#include "dos_system.h" +#include "dos_inc.h" #include "drives.h" #include "support.h" #include "cross.h" @@ -38,13 +38,14 @@ public: Bit16u GetInformation(void); private: FILE * fhandle; + enum { NONE,READ,WRITE } last_action; Bit16u info; }; bool localDrive:: FileCreate(DOS_File * * file,char * name,Bit16u attributes) { //TODO Maybe care for attributes but not likely - char newname[512]; + char newname[CROSS_LEN]; strcpy(newname,basedir); strcat(newname,name); CROSS_FILENAME(newname); @@ -67,7 +68,7 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { // return false; }; - char newname[512]; + char newname[CROSS_LEN]; strcpy(newname,basedir); strcat(newname,name); CROSS_FILENAME(newname); @@ -79,7 +80,7 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { }; bool localDrive::FileUnlink(char * name) { - char newname[512]; + char newname[CROSS_LEN]; strcpy(newname,basedir); strcat(newname,name); CROSS_FILENAME(newname); @@ -88,80 +89,65 @@ bool localDrive::FileUnlink(char * name) { }; -bool localDrive::FindFirst(char * search,DTA_FindBlock * dta) { - //TODO Find some way for lowcase and highcase drives oneday - char name[512]; - strcpy(name,basedir); - strcat(name,search); - CROSS_FILENAME(name); - char * last=strrchr(name, CROSS_FILESPLIT); - *last=0; - last++; - /* Check the wildcard string for an extension */ - strcpy(wild_name,last); - wild_ext=strrchr(wild_name,'.'); - if (wild_ext) { - *wild_ext++=0; - } - strcpy(directory,name); -/* make sure / is last sign */ - if (pdir) closedir(pdir); - char argh=CROSS_FILESPLIT; - if(directory[(strlen(directory)-1)]!=CROSS_FILESPLIT) strcat(directory, &argh); - if((pdir=opendir(directory))==NULL) return false; +bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { + if (srch_opendir) closedir(srch_opendir); + strcpy(srch_dir,basedir); + strcat(srch_dir,_dir); + CROSS_FILENAME(srch_dir); + + char end[2]={CROSS_FILESPLIT,0}; + if (srch_dir[strlen(srch_dir)]!=CROSS_FILESPLIT) strcat(srch_dir,end); + if((srch_opendir=opendir(srch_dir))==NULL) return false; return FindNext(dta); } -bool localDrive::FindNext(DTA_FindBlock * dta) { - Bit8u tempattr=0; - struct dirent *tempdata; +bool localDrive::FindNext(DOS_DTA & dta) { + struct dirent * dir_ent; struct stat stat_block; - char werkbuffer[512]; + char full_name[CROSS_LEN]; + Bit8u srch_attr;char srch_pattern[DOS_NAMELENGTH]; + Bit8u find_attr; + + if(!srch_opendir) return false; - if(pdir==NULL){ - return false; - }; - start: - if((tempdata=readdir(pdir))==NULL) { - closedir(pdir); - pdir=NULL; + dta.GetSearchParams(srch_attr,srch_pattern); + again: + if((dir_ent=readdir(srch_opendir))==NULL) { + closedir(srch_opendir); + srch_opendir=NULL; return false; } - strcpy(werkbuffer,tempdata->d_name); - if (wild_ext) { - char * ext=strrchr(werkbuffer,'.'); - if (!ext) ext="*"; - else *ext++=0; - if(!wildcmp(wild_ext,ext)) goto start; + if(!WildFileCmp(dir_ent->d_name,srch_pattern)) goto again; + strcpy(full_name,srch_dir); + strcat(full_name,dir_ent->d_name); + if(stat(full_name,&stat_block)!=0){ + exit(1); } - if(!wildcmp(wild_name,werkbuffer)) goto start; - werkbuffer[0]='\0'; - strcpy(werkbuffer,directory); - strcat(werkbuffer,tempdata->d_name); - if(stat(werkbuffer,&stat_block)!=0){ - /*nu is er iets fout!*/ exit(1); - } - if(S_ISDIR(stat_block.st_mode)) tempattr=DOS_ATTR_DIRECTORY; - else tempattr=DOS_ATTR_ARCHIVE; - if(!(dta->sattr & tempattr)) goto start; - /*file is oke so filldtablok */ - if(strlen(tempdata->d_name)<=DOS_NAMELENGTH) strcpy(dta->name,upcase(tempdata->d_name)); - dta->attr=tempattr; - dta->size=(Bit32u) stat_block.st_size; + if(S_ISDIR(stat_block.st_mode)) find_attr=DOS_ATTR_DIRECTORY; + else find_attr=DOS_ATTR_ARCHIVE; + if(!(srch_attr & find_attr)) goto again; + + /*file is okay, setup everything to be copied in DTA Block */ + char find_name[DOS_NAMELENGTH_ASCII];Bit16u find_date,find_time;Bit32u find_size; + if(strlen(dir_ent->d_name)d_name); + upcase(find_name); + } else strcpy(find_name,"LONGNAME.ERR"); + find_size=(Bit32u) stat_block.st_size; struct tm *time; if((time=localtime(&stat_block.st_mtime))!=0){ - - dta->time=(time->tm_hour<<11)+(time->tm_min<<5)+(time->tm_sec/2); /* standard way. */ - dta->date=((time->tm_year-80)<<9)+((time->tm_mon+1)<<5)+(time->tm_mday); + find_date=DOS_PackDate(time->tm_year+1900,time->tm_mon+1,time->tm_mday); + find_time=DOS_PackTime(time->tm_hour,time->tm_min,time->tm_sec); }else { - dta->time=6; - dta->date=4; + find_time=6; + find_date=4; } + dta.SetResult(find_name,find_size,find_date,find_time,find_attr); return true; } bool localDrive::GetFileAttr(char * name,Bit16u * attr) { - char newname[512]; + char newname[CROSS_LEN]; strcpy(newname,basedir); strcat(newname,name); CROSS_FILENAME(newname); @@ -176,7 +162,7 @@ bool localDrive::GetFileAttr(char * name,Bit16u * attr) { }; bool localDrive::MakeDir(char * dir) { - char newdir[512]; + char newdir[CROSS_LEN]; strcpy(newdir,basedir); strcat(newdir,dir); CROSS_FILENAME(newdir); @@ -190,7 +176,7 @@ bool localDrive::MakeDir(char * dir) { } bool localDrive::RemoveDir(char * dir) { - char newdir[512]; + char newdir[CROSS_LEN]; strcpy(newdir,basedir); strcat(newdir,dir); CROSS_FILENAME(newdir); @@ -199,7 +185,7 @@ bool localDrive::RemoveDir(char * dir) { } bool localDrive::TestDir(char * dir) { - char newdir[512]; + char newdir[CROSS_LEN]; strcpy(newdir,basedir); strcat(newdir,dir); CROSS_FILENAME(newdir); @@ -208,11 +194,11 @@ bool localDrive::TestDir(char * dir) { } bool localDrive::Rename(char * oldname,char * newname) { - char newold[512]; + char newold[CROSS_LEN]; strcpy(newold,basedir); strcat(newold,oldname); CROSS_FILENAME(newold); - char newnew[512]; + char newnew[CROSS_LEN]; strcpy(newnew,basedir); strcat(newnew,newname); CROSS_FILENAME(newnew); @@ -221,18 +207,18 @@ bool localDrive::Rename(char * oldname,char * newname) { }; -bool localDrive::FreeSpace(Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free) { +bool localDrive::AllocationInfo(Bit16u * _bytes_sector,Bit16u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters) { /* Always report 100 mb free should be enough */ /* Total size is always 1 gb */ - *bytes=512; - *sectors=127; - *clusters=16513; - *free=1700; + *_bytes_sector=allocation.bytes_sector; + *_sectors_cluster=allocation.sectors_cluster; + *_total_clusters=allocation.total_clusters; + *_free_clusters=allocation.free_clusters; return true; }; -bool localDrive::FileExists(const char* name) const { - char newname[512]; +bool localDrive::FileExists(const char* name) { + char newname[CROSS_LEN]; strcpy(newname,basedir); strcat(newname,name); CROSS_FILENAME(newname); @@ -242,38 +228,60 @@ bool localDrive::FileExists(const char* name) const { return true; } -bool localDrive::FileStat(const char* name, struct stat* const stat_block) const { - char newname[512]; +bool localDrive::FileStat(const char* name, FileStat_Block * const stat_block) { + char newname[CROSS_LEN]; strcpy(newname,basedir); strcat(newname,name); CROSS_FILENAME(newname); - if(stat(newname,stat_block)!=0) return false; - return true; + struct stat temp_stat; + if(stat(newname,&temp_stat)!=0) return false; + /* Convert the stat to a FileStat */ + struct tm *time; + if((time=localtime(&temp_stat.st_mtime))!=0) { + stat_block->time=DOS_PackTime(time->tm_hour,time->tm_min,time->tm_sec); + stat_block->date=DOS_PackDate(time->tm_year,time->tm_mon,time->tm_mday); + } else { + } + stat_block->size=(Bit32u)temp_stat.st_size; + return true; } +Bit8u localDrive::GetMediaByte(void) { + return allocation.mediaid; +} -localDrive::localDrive(char * startdir) { +localDrive::localDrive(const char * startdir,Bit16u _bytes_sector,Bit16u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid) { strcpy(basedir,startdir); sprintf(info,"local directory %s",startdir); - pdir=NULL; + srch_opendir=NULL; + allocation.bytes_sector=_bytes_sector; + allocation.sectors_cluster=_sectors_cluster; + allocation.total_clusters=_total_clusters; + allocation.free_clusters=_free_clusters; + allocation.mediaid=_mediaid; } +//TODO Maybe use fflush, but that seemed to fuck up in visual c bool localFile::Read(Bit8u * data,Bit16u * size) { + if (last_action==WRITE) fseek(fhandle,ftell(fhandle),SEEK_SET); + last_action=READ; *size=fread(data,1,*size,fhandle); return true; }; bool localFile::Write(Bit8u * data,Bit16u * size) { - if(*size==0){ + if (last_action==READ) fseek(fhandle,ftell(fhandle),SEEK_SET); + last_action=WRITE; + if(*size==0){ return (!ftruncate(fileno(fhandle),ftell(fhandle))); } else { - *size=fwrite(data,1,*size,fhandle); - return true; + *size=fwrite(data,1,*size,fhandle); + return true; } } bool localFile::Seek(Bit32u * pos,Bit32u type) { @@ -292,7 +300,7 @@ bool localFile::Seek(Bit32u * pos,Bit32u type) { //TODO Hope we don't encouter files with 64 bits size Bit32u * fake_pos=(Bit32u*)&temppos; *pos=*fake_pos; - + last_action=NONE; return true; } @@ -305,9 +313,22 @@ Bit16u localFile::GetInformation(void) { return info; } + localFile::localFile(FILE * handle,Bit16u devinfo) { fhandle=handle; info=devinfo; + struct stat temp_stat; + fstat(fileno(handle),&temp_stat); + struct tm * ltime; + if((ltime=localtime(&temp_stat.st_mtime))!=0) { + time=DOS_PackTime(ltime->tm_hour,ltime->tm_min,ltime->tm_sec); + date=DOS_PackDate(ltime->tm_year,ltime->tm_mon,ltime->tm_mday); + } else { + time=0;date=0; + } + size=(Bit32u)temp_stat.st_size; + attr=DOS_ATTR_ARCHIVE; + last_action=NONE; } From 4bff708fa38ded997e62e00d8fa39ded0facffa0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:31:38 +0000 Subject: [PATCH 0289/4131] Updated for the new dta class, added support for a new filstat subfunction. Changed the wildcmp to use the new wildcard function. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@366 --- src/dos/drive_virtual.cpp | 65 ++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 39 deletions(-) diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 0be5dc6e..e65eb744 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -21,13 +21,13 @@ #include #include #include "dosbox.h" -#include "dos_system.h" +#include "dos_inc.h" #include "drives.h" #include "support.h" #include "cross.h" struct VFILE_Block { - char * name; + const char * name; Bit8u * data; Bit32u size; VFILE_Block * next; @@ -36,7 +36,7 @@ struct VFILE_Block { static VFILE_Block * first_file; -void VFILE_Register(char * name,Bit8u * data,Bit32u size) { +void VFILE_Register(const char * name,Bit8u * data,Bit32u size) { VFILE_Block * new_file=new VFILE_Block; new_file->name=name; new_file->data=data; @@ -153,16 +153,14 @@ bool Virtual_Drive::TestDir(char * dir) { return false; } -bool Virtual_Drive::FileStat(const char* name, struct stat* const stat_block) const { - VFILE_Block * cur_file=first_file; +bool Virtual_Drive::FileStat(const char* name, FileStat_Block * const stat_block){ + VFILE_Block * cur_file=first_file; while (cur_file) { if (strcasecmp(name,cur_file->name)==0) { - stat_block->st_size=cur_file->size; - struct tm tijd; - tijd.tm_hour=0;tijd.tm_min=0;tijd.tm_sec=0; - tijd.tm_year=80;tijd.tm_mday=6;tijd.tm_mon=0; - stat_block->st_mtime=mktime(&tijd); - /* more not needed at the moment (fcbopen.....)*/ + stat_block->attr=DOS_ATTR_ARCHIVE; + stat_block->size=cur_file->size; + stat_block->date=DOS_PackDate(2002,0,0); + stat_block->time=DOS_PackTime(12,12,12); return true; } cur_file=cur_file->next; @@ -170,7 +168,7 @@ bool Virtual_Drive::FileStat(const char* name, struct stat* const stat_block) co return false; } -bool Virtual_Drive::FileExists(const char* name) const { +bool Virtual_Drive::FileExists(const char* name){ VFILE_Block * cur_file=first_file; while (cur_file) { if (strcasecmp(name,cur_file->name)==0) return true; @@ -179,32 +177,17 @@ bool Virtual_Drive::FileExists(const char* name) const { return false; } -static void FillDTABlock(DTA_FindBlock * dta,VFILE_Block * fill_file) { - strcpy(dta->name,fill_file->name); - dta->size=fill_file->size; - dta->attr=DOS_ATTR_ARCHIVE; - dta->time=2; - dta->date=6; -} - -bool Virtual_Drive::FindFirst(char * search,DTA_FindBlock * dta) { +bool Virtual_Drive::FindFirst(char * _dir,DOS_DTA & dta) { search_file=first_file; - strcpy(search_string,search); - while (search_file) { - if (wildcmp(search_string,search_file->name)) { - FillDTABlock(dta,search_file); - search_file=search_file->next; - return true; - } - search_file=search_file->next; - } - return false; + return FindNext(dta); } -bool Virtual_Drive::FindNext(DTA_FindBlock * dta) { +bool Virtual_Drive::FindNext(DOS_DTA & dta) { + Bit8u attr;char pattern[DOS_NAMELENGTH]; + dta.GetSearchParams(attr,pattern); while (search_file) { - if (wildcmp(search_string,search_file->name)) { - FillDTABlock(dta,search_file); + if (WildFileCmp(search_file->name,pattern)) { + dta.SetResult(search_file->name,search_file->size,6,2,DOS_ATTR_ARCHIVE); search_file=search_file->next; return true; } @@ -221,13 +204,17 @@ bool Virtual_Drive::Rename(char * oldname,char * newname) { return false; } -bool Virtual_Drive::FreeSpace(Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free) { +bool Virtual_Drive::AllocationInfo(Bit16u * _bytes_sector,Bit16u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters) { /* Always report 100 mb free should be enough */ /* Total size is always 1 gb */ - *bytes=512; - *sectors=127; - *clusters=16513; - *free=00; + *_bytes_sector=512; + *_sectors_cluster=127; + *_total_clusters=16513; + *_free_clusters=00; return true; } +Bit8u Virtual_Drive::GetMediaByte(void) { + return 0xF8; +} + From 1b242dcbda41d36d3068b9a5be358b46ca8df4d0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:32:12 +0000 Subject: [PATCH 0290/4131] Added a wildfildcmp function for correct dos like wildcard matching of files. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@367 --- src/dos/drives.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index 2a711725..2785b18d 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -19,6 +19,58 @@ #include "dosbox.h" #include "dos_system.h" #include "drives.h" +#include "support.h" + +bool WildFileCmp(const char * file, const char * wild) +{ + char file_name[9]; + char file_ext[4]; + char wild_name[9]; + char wild_ext[4]; + char * find_ext; + Bitu r; + + strcpy(file_name," "); + strcpy(file_ext," "); + strcpy(wild_name," "); + strcpy(wild_ext," "); + + find_ext=strchr(file,'.'); + if (find_ext) { + Bitu size=find_ext-file;if (size>8) size=8; + memcpy(file_name,file,size); + find_ext++; + memcpy(file_ext,find_ext,(strlen(find_ext)>3) ? 3 : strlen(find_ext)); + } else { + memcpy(file_name,file,(strlen(file) > 8) ? 8 : strlen(file)); + } + upcase(file_name);upcase(file_ext); + find_ext=strchr(wild,'.'); + if (find_ext) { + Bitu size=find_ext-wild;if (size>8) size=8; + memcpy(wild_name,wild,size); + find_ext++; + memcpy(wild_ext,find_ext,(strlen(find_ext)>3) ? 3 : strlen(find_ext)); + } else { + memcpy(wild_name,wild,(strlen(wild) > 8) ? 8 : strlen(wild)); + } + upcase(wild_name);upcase(wild_ext); + /* Names are right do some checking */ + r=0; + while (r<8) { + if (wild_name[r]=='*') goto checkext; + if (wild_name[r]!='?' && wild_name[r]!=file_name[r]) return false; + r++; + } +checkext: + while (r<3) { + if (wild_ext[r]=='*') return true; + if (wild_ext[r]!='?' && wild_ext[r]!=file_ext[r]) return false; + r++; + } + return true; +} + DOS_Drive::DOS_Drive() { From 832f69f4f04040872c0400167a4875dc8b7781bc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:33:08 +0000 Subject: [PATCH 0291/4131] Command line wouldn't erase the 2 command line switches, fixed now. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@368 --- src/misc/setup.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index eadee807..9d0b8b98 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -269,7 +269,7 @@ bool CommandLine::FindHex(char * name,int & value,bool remove) { if (!(FindEntry(name,it,true))) return false; it_next=it;it_next++; sscanf((*it_next).c_str(),"%X",&value); - if (remove) cmds.erase(it,it_next); + if (remove) cmds.erase(it,++it_next); return true; } @@ -278,7 +278,7 @@ bool CommandLine::FindInt(char * name,int & value,bool remove) { if (!(FindEntry(name,it,true))) return false; it_next=it;it_next++; value=atoi((*it_next).c_str()); - if (remove) cmds.erase(it,it_next); + if (remove) cmds.erase(it,++it_next); return true; } @@ -287,7 +287,7 @@ bool CommandLine::FindString(char * name,std::string & value,bool remove) { if (!(FindEntry(name,it,true))) return false; it_next=it;it_next++; value=*it_next; - if (remove) cmds.erase(it,it_next); + if (remove) cmds.erase(it,++it_next); return true; } From 741fccb0fd2dbe596fc83bd7c0ba736290d49993 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:33:46 +0000 Subject: [PATCH 0292/4131] Added screenshot support. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@369 --- src/gui/render.cpp | 122 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 116 insertions(+), 6 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 04c3b475..0edcb9a3 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,14 +16,20 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include +#include + #include "dosbox.h" #include "video.h" #include "render.h" - - +#include "setup.h" +#include "keyboard.h" +#include "cross.h" #define MAX_RES 2048 + + struct PalData { struct { Bit8u red; @@ -51,8 +57,104 @@ static struct { PalData pal; bool remake; bool enlarge; + bool screenshot; } render; +static const char * snapshots_dir; + +/* Take a screenshot of the data that should be rendered */ +static void TakeScreenShot(Bit8u * bitmap) { + Bitu last=0;char file_name[CROSS_LEN]; + DIR * dir;struct dirent * dir_ent; + png_structp png_ptr; + png_infop info_ptr; + png_bytep * row_pointers; + png_color palette[256]; + Bitu i; + +/* First try to alloacte the png structures */ + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL, NULL); + if (!png_ptr) return; + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_write_struct(&png_ptr,(png_infopp)NULL); + return; + } +/* Find a filename to open */ + dir=opendir(snapshots_dir); + if (!dir) { + LOG_WARN("Can't open snapshot dir %s",snapshots_dir); + return; + } + while (dir_ent=readdir(dir)) { + char tempname[CROSS_LEN]; + strcpy(tempname,dir_ent->d_name); + char * test=strstr(tempname,".png"); + if (!test) continue; + *test=0; + if (strlen(tempname)<5) continue; + if (strncmp(tempname,"snap",4)!=0) continue; + Bitu num=atoi(&tempname[4]); + if (num>=last) last=num+1; + } + closedir(dir); + sprintf(file_name,"%s%csnap%05d.png",snapshots_dir,CROSS_FILESPLIT,last); +/* Open the actual file */ + FILE * fp=fopen(file_name,"wb"); + if (!fp) { + LOG_WARN("Can't open snapshot file %s",file_name); + return; + } +/* Finalize the initing of png library */ + png_init_io(png_ptr, fp); + png_set_compression_level(png_ptr,Z_BEST_COMPRESSION); + + /* set other zlib parameters */ + png_set_compression_mem_level(png_ptr, 8); + png_set_compression_strategy(png_ptr,Z_DEFAULT_STRATEGY); + png_set_compression_window_bits(png_ptr, 15); + png_set_compression_method(png_ptr, 8); + png_set_compression_buffer_size(png_ptr, 8192); + + if (render.src.bpp==8) { + png_set_IHDR(png_ptr, info_ptr, render.src.width, render.src.height, + 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + for (i=0;i<256;i++) { + palette[i].red=render.pal.rgb[i].red; + palette[i].green=render.pal.rgb[i].green; + palette[i].blue=render.pal.rgb[i].blue; + } + png_set_PLTE(png_ptr, info_ptr, palette,256); + } else { + png_set_IHDR(png_ptr, info_ptr, render.src.width, render.src.height, + 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + } + /*Allocate an array of scanline pointers*/ + row_pointers=(png_bytep*)malloc(render.src.height*sizeof(png_bytep)); + for (i=0;irender.pal.last) return; @@ -98,8 +200,11 @@ void RENDER_Draw(Bit8u * bitdata) { render.remake=false; } render.handler(&src_data); + if (render.screenshot) { + TakeScreenShot(src_data); + render.screenshot=false; + } Draw_8_Normal(src_data,bitdata); - } @@ -151,10 +256,15 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu } - -void RENDER_Init(void) { +static void EnableScreenShot(void) { + render.screenshot=true; +} +void RENDER_Init(Section * sec) { + Section_prop * section=static_cast(sec); + snapshots_dir=section->Get_string("snapshots"); render.pal.first=256; render.pal.last=0; - render.enlarge=false; + render.enlarge=false; + KEYBOARD_AddEvent(KBD_f5,CTRL_PRESSED,EnableScreenShot); } From e0ced0c1b3883d71b9cf1085e568436585766e23 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:35:02 +0000 Subject: [PATCH 0293/4131] Some primitive frame skipping support and fixed support for the -fullscreen command line option. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@370 --- src/gui/sdlmain.cpp | 69 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 16 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 272f9f7f..b88af150 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -18,8 +18,9 @@ #include #include -#include -#include +#include +#include + #include "dosbox.h" #include "video.h" #include "keyboard.h" @@ -33,7 +34,27 @@ //#define DISABLE_JOYSTICK -SDL_Block sdl; +struct SDL_Block { + bool active; //If this isn't set don't draw + Bitu width; + Bitu height; + Bitu bpp; + GFX_DrawHandler * draw; + GFX_ResizeHandler * resize; + bool mouse_grabbed; + bool full_screen; + SDL_Thread * thread; + SDL_mutex * mutex; + SDL_Surface * surface; + SDL_Joystick * joy; + SDL_Color pal[256]; + struct { + Bitu skip; + Bitu count; + }frames ; +}; + +static SDL_Block sdl; GFX_Info gfx_info; @@ -93,6 +114,17 @@ static void CaptureMouse() { } } +static void DecreaseSkip() { + if (sdl.frames.skip>0) sdl.frames.skip--; + LOG_MSG("Frame Skip %d",sdl.frames.skip); +} + + +static void IncreaseSkip() { + if (sdl.frames.skip<10) sdl.frames.skip++; + LOG_MSG("Frame Skip %d",sdl.frames.skip); +} + static void SwitchFullScreen(void) { GFX_Stop(); sdl.full_screen=!sdl.full_screen; @@ -116,6 +148,9 @@ static void GFX_Redraw() { E_Exit("Can't Lock Mutex"); }; #endif + + if (++sdl.frames.countpixels && sdl.draw) (*sdl.draw)((Bit8u *)sdl.surface->pixels); @@ -183,10 +218,19 @@ void GFX_Start() { } -void GUI_StartUp(Section * sec) { - Section_prop * section=static_cast(sec); +static void GUI_ShutDown(Section * sec) { + GFX_Stop(); + if (sdl.full_screen) SwitchFullScreen(); + +} + +static void GUI_StartUp(Section * sec) { + sec->AddDestroyFunction(&GUI_ShutDown); + Section_prop * section=static_cast(sec); sdl.active=false; sdl.full_screen=false; + sdl.frames.skip=0; + sdl.frames.count=0; sdl.draw=0; GFX_Resize(640,400,8,0); #if C_THREADED @@ -198,8 +242,9 @@ void GUI_StartUp(Section * sec) { SDL_EnableKeyRepeat(250,30); /* Get some Keybinds */ - KEYBOARD_AddEvent(KBD_f9,CTRL_PRESSED,SwitchFullScreen); KEYBOARD_AddEvent(KBD_f10,CTRL_PRESSED,CaptureMouse); + KEYBOARD_AddEvent(KBD_f7,CTRL_PRESSED,DecreaseSkip); + KEYBOARD_AddEvent(KBD_f8,CTRL_PRESSED,IncreaseSkip); KEYBOARD_AddEvent(KBD_enter,ALT_PRESSED,SwitchFullScreen); } @@ -484,23 +529,15 @@ int main(int argc, char* argv[]) { JOYSTICK_Enable(0,true); } #endif - if (control->cmdline->FindExist("-fullscreen")) { - sdl.full_screen=true; - } else { - sdl.full_screen=sdl_sec->Get_bool("FULLSCREEN"); - } - if (sdl.full_screen) { - sdl.full_screen=false; + if (control->cmdline->FindExist("-fullscreen") || sdl_sec->Get_bool("FULLSCREEN")) { SwitchFullScreen(); } - - /* Start up main machine */ control->StartUp(); /* Shutdown everything */ } catch (char * error) { LOG_ERROR("Exit to error: %s",error); + fgetc(stdin); } - GFX_Stop(); return 0; }; From 4a562888f5c145fe3434ce60a107450d3ee0190b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:36:09 +0000 Subject: [PATCH 0294/4131] Fixed the dir command to use the new DTA class and to show the correct free disk space. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@371 --- src/shell/shell_cmds.cpp | 51 +++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 1072988e..2fa7b281 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -149,8 +149,8 @@ void DOS_Shell::CMD_RMDIR(char * args) { } }; -static void FormatNumber(Bit32u num,char * buf) { - Bit32u numm,numk,numb; +static void FormatNumber(Bitu num,char * buf) { + Bitu numm,numk,numb; numb=num % 1000; num/=1000; numk=num % 1000; @@ -179,7 +179,6 @@ void DOS_Shell::CMD_DIR(char * args) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); return; } - Bit32u byte_count,file_count,dir_count; Bit32u w_count=0; byte_count=file_count=dir_count=0; @@ -194,8 +193,7 @@ void DOS_Shell::CMD_DIR(char * args) { *(strrchr(path,'\\')+1)=0; WriteOut(MSG_Get("SHELL_CMD_DIR_INTRO"),path); - DTA_FindBlock * dta; - dta=(DTA_FindBlock *)Real2Host(dos.dta); + DOS_DTA dta(dos.dta); bool ret=DOS_FindFirst(args,0xffff); if (!ret) { WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); @@ -203,37 +201,39 @@ void DOS_Shell::CMD_DIR(char * args) { } while (ret) { /* File name and extension */ + char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr; + dta.GetResult(name,size,date,time,attr); + char * ext=""; - if (!optW && (*dta->name != '.')) { - ext = strrchr(dta->name, '.'); + if (!optW && (name[0] != '.')) { + ext = strrchr(name, '.'); if (!ext) ext = ""; else *ext++ = '\0'; } - - Bit8u day = dta->date & 0x001f; - Bit8u month = (dta->date >> 5) & 0x000f; - Bit8u hour = dta->time >> 5 >> 6; - Bit8u minute = (dta->time >> 5) & 0x003f; - Bit16u year = (dta->date >> 9) + 1980; + Bit8u day = date & 0x001f; + Bit8u month = (date >> 5) & 0x000f; + Bit16u year = (date >> 9) + 1980; + Bit8u hour = (time >> 5 ) >> 6; + Bit8u minute = (time >> 5) & 0x003f; /* output the file */ - if (dta->attr & DOS_ATTR_DIRECTORY) { + if (attr & DOS_ATTR_DIRECTORY) { if (optW) { - WriteOut("[%s]",dta->name); - for (Bitu i=14-strlen(dta->name);i>0;i--) WriteOut(" "); + WriteOut("[%s]",name); + for (Bitu i=14-strlen(name);i>0;i--) WriteOut(" "); } else { - WriteOut("%-8s %-3s %-16s %02d-%02d-%04d %2d:%02d\n",dta->name,ext,"",day,month,year,hour,minute); + WriteOut("%-8s %-3s %-16s %02d-%02d-%04d %2d:%02d\n",name,ext,"",day,month,year,hour,minute); } dir_count++; } else { if (optW) { - WriteOut("%-16s",dta->name); + WriteOut("%-16s",name); } else { - FormatNumber(dta->size,numformat); - WriteOut("%-8s %-3s %16s %02d-%02d-%04d %2d:%02d\n",dta->name,ext,numformat,day,month,year,hour,minute); + FormatNumber(size,numformat); + WriteOut("%-8s %-3s %16s %02d-%02d-%04d %2d:%02d\n",name,ext,numformat,day,month,year,hour,minute); } file_count++; - byte_count+=dta->size; + byte_count+=size; } if (optW) { w_count++; @@ -246,8 +246,15 @@ void DOS_Shell::CMD_DIR(char * args) { /* Show the summary of results */ FormatNumber(byte_count,numformat); WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_USED"),file_count,numformat); + Bit8u drive=dta.GetSearchDrive(); //TODO Free Space - FormatNumber(1024*1024*100,numformat); + Bitu free_space=1024*1024*100; + if (Drives[drive]) { + Bit16u bytes_sector;Bit16u sectors_cluster;Bit16u total_clusters;Bit16u free_clusters; + Drives[drive]->AllocationInfo(&bytes_sector,§ors_cluster,&total_clusters,&free_clusters); + free_space=bytes_sector*sectors_cluster*free_clusters; + } + FormatNumber(free_space,numformat); WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_FREE"),dir_count,numformat); } From 8f740ac0341eb210c3492649df972d42131e7686 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:37:37 +0000 Subject: [PATCH 0295/4131] Support the new paramblock class when starting programs from the shell. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@372 --- src/shell/shell_misc.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 42830804..53289223 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -152,6 +152,7 @@ void DOS_Shell::Execute(char * name,char * args) { reg_sp-=0x200; //Add Parameter block DOS_ParamBlock block(SegPhys(ss)+reg_sp); + block.Clear(); //Add a filename RealPt file_name=RealMakeSeg(ss,reg_sp+0x20); MEM_BlockWrite(Real2Phys(file_name),fullname,strlen(fullname)+1); @@ -163,10 +164,11 @@ void DOS_Shell::Execute(char * name,char * args) { cmd.buffer[strlen(line)]=0xd; /* Copy command line in stack block too */ MEM_BlockWrite(SegPhys(ss)+reg_sp+0x100,&cmd,128); - block.InitExec(RealMakeSeg(ss,reg_sp+0x100)); + /* Set the command line in the block and save it */ + block.data.exec.cmdtail=RealMakeSeg(ss,reg_sp+0x100); + block.SaveData(); /* Save CS:IP to some point where i can return them from */ - RealPt newcsip; - newcsip=CALLBACK_RealPointer(call_shellstop); + RealPt newcsip=CALLBACK_RealPointer(call_shellstop); SegSet16(cs,RealSeg(newcsip)); reg_ip=RealOff(newcsip); /* Start up a dos execute interrupt */ From a9c9b35efe499b27183d45acea5fac226ee1078a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:38:59 +0000 Subject: [PATCH 0296/4131] Joined a lot of init's under one section, added a render_init. Made all entry names lowcase. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@373 --- src/dosbox.cpp | 115 ++++++++++++++++++++++--------------------------- 1 file changed, 51 insertions(+), 64 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index f67995e3..7cc8d219 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -37,19 +37,17 @@ #include "programs.h" #include "support.h" - /* NEEDS A CLEANUP */ -char dosbox_basedir[CROSS_LEN]; Config * control; -Bitu errorlevel=1; //during startup display reason for Exits -//The whole load of startups for all the subfunctions +Bitu errorlevel; +/* The whole load of startups for all the subfunctions */ void MSG_Init(Section_prop *); void MEM_Init(Section *); void IO_Init(Section * ); void CALLBACK_Init(Section*); void PROGRAMS_Init(Section*); - +void RENDER_Init(Section*); void VGA_Init(Section*); void DOS_Init(Section*); @@ -76,9 +74,6 @@ void TIMER_Init(Section*); void BIOS_Init(Section*); void DEBUG_Init(Section*); - - - /* Dos Internal mostly */ void EMS_Init(Section*); void XMS_Init(Section*); @@ -87,9 +82,6 @@ void SHELL_Init(void); void INT10_Init(Section*); - - - static LoopHandler * loop; static Bitu Normal_Loop(void) { @@ -110,8 +102,7 @@ static Bitu Normal_Loop(void) { ret=(*cpudecoder)(cpu_cycles); } while (!ret && PIC_IRQAgain); return ret; -}; - +} void DOSBOX_SetLoop(LoopHandler * handler) { loop=handler; @@ -128,12 +119,11 @@ void DOSBOX_RunMachine(void){ } while (!ret); } - static void DOSBOX_RealInit(Section * sec) { Section_prop * section=static_cast(sec); /* Initialize some dosbox internals */ - errorlevel=section->Get_int("WARNINGS"); - LastTicks=GetTicks(); + errorlevel=section->Get_int("warnings"); + LastTicks=GetTicks(); DOSBOX_SetLoop(&Normal_Loop); MSG_Init(section); } @@ -146,70 +136,67 @@ void DOSBOX_Init(void) { /* Setup all the different modules making up DOSBox */ - secprop=control->AddSection_prop("DOSBOX",&DOSBOX_RealInit); + secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit); + secprop->Add_string("language",""); + secprop->Add_int("warnings",4); - secprop->Add_string("LANGUAGE",""); - secprop->Add_int("WARNINGS",0); + secprop->AddInitFunction(&MEM_Init); + secprop->AddInitFunction(&IO_Init); + secprop->AddInitFunction(&CALLBACK_Init); + secprop->AddInitFunction(&PIC_Init); + secprop->AddInitFunction(&PROGRAMS_Init); + secprop->AddInitFunction(&TIMER_Init); + secprop->AddInitFunction(&RENDER_Init); + secprop->Add_string("snapshots","snapshots"); - control->AddSection ("MEMORY",&MEM_Init); - control->AddSection ("IO",&IO_Init); - control->AddSection ("CALLBACK",&CALLBACK_Init); - control->AddSection ("PIC",&PIC_Init); - control->AddSection ("PROGRAMS",&PROGRAMS_Init); - control->AddSection_prop("TIMER",&TIMER_Init); - secprop=control->AddSection_prop("CPU",&CPU_Init); - secprop->Add_int("CYCLES",3000); - secprop=control->AddSection_prop("MIXER",&MIXER_Init); + secprop=control->AddSection_prop("cpu",&CPU_Init); + secprop->Add_int("cycles",4000); + + secprop->AddInitFunction(&DMA_Init); + secprop->AddInitFunction(&VGA_Init); + secprop->AddInitFunction(&KEYBOARD_Init); + secprop->AddInitFunction(&MOUSE_Init); + secprop->AddInitFunction(&JOYSTICK_Init); + + secprop=control->AddSection_prop("mixer",&MIXER_Init); #if C_DEBUG - secprop=control->AddSection_prop("'DEBUG",&DEBUG_Init); + secprop=control->AddSection_prop("debug",&DEBUG_Init); #endif - control->AddSection ("DMA",&DMA_Init); - control->AddSection ("VGA",&VGA_Init); - control->AddSection ("KEYBOARD",&KEYBOARD_Init); - secprop=control->AddSection_prop("MOUSE",&MOUSE_Init); - control->AddSection ("JOYSTICK",&JOYSTICK_Init); - - secprop=control->AddSection_prop("SBLASTER",&SBLASTER_Init); - secprop->Add_hex("BASE",0x220); - secprop->Add_int("IRQ",5); - secprop->Add_int("DMA",1); - secprop->Add_bool("STATUS",true); + secprop=control->AddSection_prop("sblaster",&SBLASTER_Init); + secprop->Add_hex("base",0x220); + secprop->Add_int("irq",7); + secprop->Add_int("dma",1); + secprop->Add_int("hdma",5); + secprop->Add_bool("enabled",true); - secprop=control->AddSection_prop("TANDYSOUND",&TANDYSOUND_Init); - secprop->Add_bool("STATUS",false); + secprop->AddInitFunction(&ADLIB_Init); + secprop->Add_bool("adlib",true); + secprop->AddInitFunction(&CMS_Init); + secprop->Add_bool("cms",false); - secprop=control->AddSection_prop("PCSPEAKER",&PCSPEAKER_Init); + secprop=control->AddSection_prop("speaker",&PCSPEAKER_Init); + secprop->Add_bool("sinewave",false); + secprop->AddInitFunction(&TANDYSOUND_Init); + secprop->Add_bool("tandy",false); - secprop=control->AddSection_prop("ADLIB",&ADLIB_Init); - secprop->Add_bool("STATUS",true); - - secprop=control->AddSection_prop("CMS",&CMS_Init); - secprop->Add_bool("STATUS",false); - - secprop=control->AddSection_prop("BIOS",&BIOS_Init); - secprop=control->AddSection_prop("VIDBIOS",&INT10_Init); + secprop=control->AddSection_prop("bios",&BIOS_Init); + secprop->AddInitFunction(&INT10_Init); /* All the DOS Related stuff, which will eventually start up in the shell */ - - secprop=control->AddSection_prop("DOS",&DOS_Init); - secprop=control->AddSection_prop("EMS",&EMS_Init); - secprop->Add_bool("STATUS",true); - secprop->Add_int("SIZE",4); - secprop=control->AddSection_prop("XMS",&XMS_Init); - secprop->Add_bool("STATUS",true); - secprop->Add_int("SIZE",8); + //TODO Maybe combine most of the dos stuff in one section like ems,xms + secprop=control->AddSection_prop("dos",&DOS_Init); + secprop->AddInitFunction(&EMS_Init); + secprop->Add_int("emssize",4); + secprop->AddInitFunction(&XMS_Init); + secprop->Add_int("xmssize",8); - secline=control->AddSection_line("AUTOEXEC",&AUTOEXEC_Init); + secline=control->AddSection_line("autoexec",&AUTOEXEC_Init); control->SetStartUp(&SHELL_Init); -// HARDWARE_Init(); #if C_FPU FPU_Init(); #endif - - - } From 6dbe7ee6d2d8d693b4ca4bbddf989d294dbbf0e7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:39:11 +0000 Subject: [PATCH 0297/4131] DOS_AllocationInfo call added Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@374 --- include/dos_inc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dos_inc.h b/include/dos_inc.h index 343147de..f89e4cf8 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -154,6 +154,7 @@ 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,Bit16u * _sectors_cluster,Bit16u * _total_clusters); /* Extra DOS Interrupts */ void DOS_SetupMisc(void); From 726aabde05b8152a1cf9abcb5ceb6bd80b4718ba Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:46:13 +0000 Subject: [PATCH 0298/4131] Protection against setting 0 cycles in the config file and reading out from the low case cycles property Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@375 --- src/cpu/cpu.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 160bb573..6ab41391 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -29,27 +29,22 @@ Flag_Info flags; CPU_Regs cpu_regs; - - Segment Segs[6]; -Bit32u cpu_cycles; +Bitu cpu_cycles; CPU_Decoder * cpudecoder; - static void CPU_CycleIncrease(void) { - Bit32u old_cycles=cpu_cycles; - cpu_cycles=(Bit32u)(cpu_cycles*1.2); + Bitu old_cycles=cpu_cycles; + cpu_cycles=(Bitu)(cpu_cycles*1.2); if (cpu_cycles==old_cycles) cpu_cycles++; LOG_MSG("CPU:%d cycles",cpu_cycles); - } static void CPU_CycleDecrease(void) { - cpu_cycles=(Bit32u)(cpu_cycles/1.2); + cpu_cycles=(Bitu)(cpu_cycles/1.2); if (!cpu_cycles) cpu_cycles=1; LOG_MSG("CPU:%d cycles",cpu_cycles); - } Bit8u lastint; @@ -168,7 +163,8 @@ void CPU_Init(Section* sec) { flags.io=0; SetCPU16bit(); - cpu_cycles=section->Get_int("CYCLES"); + cpu_cycles=section->Get_int("cycles"); + if (!cpu_cycles) cpu_cycles=300; KEYBOARD_AddEvent(KBD_f11,CTRL_PRESSED,CPU_CycleDecrease); KEYBOARD_AddEvent(KBD_f12,CTRL_PRESSED,CPU_CycleIncrease); From 10434b4ce24213a948577cd775cfaa46b0eb4de6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:47:15 +0000 Subject: [PATCH 0299/4131] Removed plugings.cpp and setup linker to include zlib and libpng Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@376 --- visualc/dosbox.dsp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index b9632774..f274ef58 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -50,7 +50,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 sdlmain.lib sdl.lib curses.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 libpng.lib sdlmain.lib sdl.lib curses.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 !ELSEIF "$(CFG)" == "dosbox - Win32 Debug" @@ -75,7 +75,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 sdlmain.lib sdl.lib curses.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 zlib.lib libpng.lib sdlmain.lib sdl.lib curses.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept !ENDIF @@ -459,10 +459,6 @@ SOURCE=..\src\misc\messages.cpp # End Source File # Begin Source File -SOURCE=..\src\misc\plugins.cpp -# End Source File -# Begin Source File - SOURCE=..\src\misc\programs.cpp # End Source File # Begin Source File From fb3b0711bb92984e369a99dab187cb668b537747 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Oct 2002 17:48:16 +0000 Subject: [PATCH 0300/4131] plugins.cpp removed Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@377 --- src/misc/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/Makefile.am b/src/misc/Makefile.am index 3d9eff2d..2cea9df3 100644 --- a/src/misc/Makefile.am +++ b/src/misc/Makefile.am @@ -1,4 +1,4 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libmisc.a -libmisc_a_SOURCES = plugins.cpp programs.cpp messages.cpp support.cpp setup.cpp +libmisc_a_SOURCES = programs.cpp messages.cpp support.cpp setup.cpp From f25dbb22dd66b138685a1b243798cde4c1d7dd7c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Oct 2002 01:17:07 +0000 Subject: [PATCH 0301/4131] Fixed error in blockread/write Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@378 --- src/hardware/memory.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index cd0c9296..783cc6d3 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -40,14 +40,13 @@ void MEM_BlockRead(PhysPt off,void * data,Bitu size) { Bitu start=off & (PAGE_SIZE-1); Bitu tocopy=PAGE_SIZE-start; if (tocopy>size) tocopy=size; + size-=tocopy; if (ReadHostTable[page]) { memcpy(idata,ReadHostTable[page]+off,tocopy); - idata+=tocopy; - off+=tocopy; + idata+=tocopy;off+=tocopy; } else { for (;tocopy>0;tocopy--) *idata++=ReadHandlerTable[page](off++); } - size-=tocopy; } } @@ -58,14 +57,13 @@ void MEM_BlockWrite(PhysPt off,void * data,Bitu size) { Bitu start=off & (PAGE_SIZE-1); Bitu tocopy=PAGE_SIZE-start; if (tocopy>size) tocopy=size; + size-=tocopy; if (WriteHostTable[page]) { memcpy(WriteHostTable[page]+off,idata,tocopy); - idata+=tocopy; - off+=tocopy; + idata+=tocopy;off+=tocopy; } else { for (;tocopy>0;tocopy--) WriteHandlerTable[page](off++,*idata++); } - size-=tocopy; } } From 282ccd8c94e78007dc5e2c21ac7300e20123730f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Oct 2002 01:18:29 +0000 Subject: [PATCH 0302/4131] Added some logging for things that will hopefully never occur and changed the order of memory and table init to fix problems with list of lists. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@379 --- src/dos/dos.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index bd8138f5..af57714d 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -460,6 +460,7 @@ static Bitu DOS_21Handler(void) { case 0x3f: /* READ Read from file or device */ { Bit16u toread=reg_cx; + if (reg_cx+reg_dx>0xffff) LOG_DEBUG("DOS:READ:Buffer overflow"); if (DOS_ReadFile(reg_bx,dos_copybuf,&toread)) { MEM_BlockWrite(SegPhys(ds)+reg_dx,dos_copybuf,toread); reg_ax=toread; @@ -473,6 +474,7 @@ static Bitu DOS_21Handler(void) { case 0x40: /* WRITE Write to file or device */ { Bit16u towrite=reg_cx; + if (reg_cx+reg_dx>0xffff) LOG_DEBUG("DOS:WRITE:Buffer overflow"); MEM_BlockRead(SegPhys(ds)+reg_dx,dos_copybuf,towrite); if (DOS_WriteFile(reg_bx,dos_copybuf,&towrite)) { reg_ax=towrite; @@ -838,8 +840,8 @@ void DOS_Init(Section* sec) { DOS_SetupFiles(); /* Setup system File tables */ DOS_SetupDevices(); /* Setup dos devices */ - DOS_SetupMemory(); /* Setup first MCB */ DOS_SetupTables(); + DOS_SetupMemory(); /* Setup first MCB */ DOS_SetupPrograms(); DOS_SetupMisc(); /* Some additional dos interrupts */ DOS_SetDefaultDrive(25); From 2b5d3d4f0ae1765b816320e416bab017e6a2b204 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Oct 2002 01:19:01 +0000 Subject: [PATCH 0303/4131] Firstmcb is a Bit16u fixed. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@380 --- src/dos/dos_memory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 47d44f1a..0140655b 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -156,6 +156,6 @@ void DOS_SetupMemory(void) { mcb->size=0x9FFE - MEM_START; mcb->type=0x5a; //Last Block dos.firstMCB=MEM_START; - dos_infoblock.SetFirstMCB(RealMake(MEM_START,0)); + dos_infoblock.SetFirstMCB(MEM_START); } From f77cd3b9f8cd7042a7480bc8492f8e2ba1ba9708 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Oct 2002 01:20:03 +0000 Subject: [PATCH 0304/4131] Changed parameter block class was bugged with overlays. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@381 --- src/dos/dos_execute.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 80020c12..21748dc2 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -195,7 +195,7 @@ static void SetupCMDLine(Bit16u pspseg,DOS_ParamBlock & block) { DOS_PSP psp(pspseg); // if cmdtail==0 it will inited as empty in SetCommandTail - psp.SetCommandTail(block.data.exec.cmdtail); + psp.SetCommandTail(block.exec.cmdtail); } bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { @@ -232,7 +232,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { } if (flags!=OVERLAY) { /* Create an environment block */ - envseg=block.data.exec.envseg; + envseg=block.exec.envseg; if (!MakeEnv(name,&envseg)) { DOS_CloseFile(fhandle); return false; @@ -258,7 +258,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { /* Setup a psp */ SetupPSP(pspseg,memsize,envseg); SetupCMDLine(pspseg,block); - } else loadseg=block.data.overlay.loadseg; + } else loadseg=block.overlay.loadseg; /* Load the executable */ loadaddress=HostMake(loadseg,0); if (iscom) { /* COM Load 64k - 256 bytes max */ @@ -278,7 +278,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { } /* Relocate the exe image */ Bit16u relocate; - if (flags==OVERLAY) relocate=block.data.overlay.relocation; + if (flags==OVERLAY) relocate=block.overlay.relocation; else relocate=loadseg; pos=head.reloctable;DOS_SeekFile(fhandle,&pos,0); for (i=0;i Date: Sun, 20 Oct 2002 01:20:47 +0000 Subject: [PATCH 0305/4131] Fixes to infoblock and paramblock classes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@382 --- src/dos/dos_classes.cpp | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index d6f942ea..d3a9f684 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -31,25 +31,28 @@ void DOS_ParamBlock::Clear(void) { - memset(&data,0,sizeof(data)); + memset(&exec,0,sizeof(exec)); + memset(&overlay,0,sizeof(overlay)); } void DOS_ParamBlock::LoadData(void) { - data.exec.envseg=sGet(sPBlock,exec.envseg); - data.exec.cmdtail=sGet(sPBlock,exec.cmdtail); - data.exec.fcb1=sGet(sPBlock,exec.fcb1); - data.exec.fcb2=sGet(sPBlock,exec.fcb2); - data.exec.initsssp=sGet(sPBlock,exec.initsssp); - data.exec.initcsip=sGet(sPBlock,exec.initcsip); + exec.envseg=sGet(sExec,envseg); + exec.cmdtail=sGet(sExec,cmdtail); + exec.fcb1=sGet(sExec,fcb1); + exec.fcb2=sGet(sExec,fcb2); + exec.initsssp=sGet(sExec,initsssp); + exec.initcsip=sGet(sExec,initcsip); + overlay.loadseg=sGet(sOverlay,loadseg); + overlay.relocation=sGet(sOverlay,relocation); } void DOS_ParamBlock::SaveData(void) { - sSave(sPBlock,exec.envseg,data.exec.envseg); - sSave(sPBlock,exec.cmdtail,data.exec.cmdtail); - sSave(sPBlock,exec.fcb1,data.exec.fcb1); - sSave(sPBlock,exec.fcb2,data.exec.fcb2); - sSave(sPBlock,exec.initsssp,data.exec.initsssp); - sSave(sPBlock,exec.initcsip,data.exec.initcsip); + sSave(sExec,envseg,exec.envseg); + sSave(sExec,cmdtail,exec.cmdtail); + sSave(sExec,fcb1,exec.fcb1); + sSave(sExec,fcb2,exec.fcb2); + sSave(sExec,initsssp,exec.initsssp); + sSave(sExec,initcsip,exec.initcsip); } @@ -61,7 +64,7 @@ void DOS_InfoBlock::SetLocation(Bit16u segment) for(Bitu i=0;i Date: Sun, 20 Oct 2002 01:21:29 +0000 Subject: [PATCH 0306/4131] Fixes to parameter and infoblock classes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@383 --- include/dos_inc.h | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index f89e4cf8..1fb88330 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -302,38 +302,37 @@ public: DOS_ParamBlock(PhysPt addr) {pt=addr;} void Clear(void); void LoadData(void); - void SaveData(void); + void SaveData(void); /* Save it as an exec block */ #pragma pack (1) - union sPBlock { - struct { - Bit16u loadseg; - Bit16u relocation; - } overlay GCC_ATTRIBUTE(packed); - struct { - Bit16u envseg; - RealPt cmdtail; - RealPt fcb1; - RealPt fcb2; - RealPt initsssp; - RealPt initcsip; - } exec GCC_ATTRIBUTE(packed); - }; + 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); #pragma pack() - sPBlock data; + sExec exec; + sOverlay overlay; }; class DOS_InfoBlock:public MemStruct { public: DOS_InfoBlock () {}; void SetLocation(Bit16u seg); - void SetFirstMCB(RealPt _first_mcb); + void SetFirstMCB(Bit16u _first_mcb); void SetfirstFileTable(RealPt _first_table); RealPt GetPointer (void); private: #pragma pack(1) struct sDIB { Bit8u stuff1[22]; // some stuff, hopefully never used.... - RealPt firstMCB; // first memory control block + Bit16u firstMCB; // first memory control block RealPt firstDPB; // first drive parameter block RealPt firstFileTable; // first system file table RealPt activeClock; // active clock device header From 209b450062df1c72fdf86ef43efc57273a471735 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Oct 2002 10:42:37 +0000 Subject: [PATCH 0307/4131] Added some safety defaults in switches Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@384 --- src/cpu/core_16/prefix_66_of.h | 4 ++++ src/cpu/core_16/prefix_of.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/cpu/core_16/prefix_66_of.h b/src/cpu/core_16/prefix_66_of.h index 676f0007..c7b0f81f 100644 --- a/src/cpu/core_16/prefix_66_of.h +++ b/src/cpu/core_16/prefix_66_of.h @@ -79,6 +79,8 @@ switch (Fetchb()) { if (flags.cf) *eard&=~mask; else *eard|=mask; break; + default: + E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38); } } else { GetEAa;Bit32u old=LoadMd(eaa); @@ -98,6 +100,8 @@ switch (Fetchb()) { else old|=mask; SaveMd(eaa,old); break; + default: + E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38); } } if (flags.type!=t_CF) flags.prev_type=flags.type; diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h index 3decea1f..3e3a4b4b 100644 --- a/src/cpu/core_16/prefix_of.h +++ b/src/cpu/core_16/prefix_of.h @@ -314,6 +314,8 @@ switch(Fetchb()) { case 0x38: /* BTC */ *earw^=mask; break; + default: + E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38); } } else { GetEAa;Bit16u old=LoadMw(eaa); @@ -330,6 +332,8 @@ switch(Fetchb()) { case 0x38: /* BTC */ SaveMw(eaa,old ^ mask); break; + default: + E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38); } } if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } From 1d9ec59b071d87df5b36f7319944408998039023 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Oct 2002 10:43:56 +0000 Subject: [PATCH 0308/4131] Changed the counter for the cpu decoder to a signed integer. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@385 --- src/cpu/slow_16.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp index c8d9a2d1..1f4a613d 100644 --- a/src/cpu/slow_16.cpp +++ b/src/cpu/slow_16.cpp @@ -61,20 +61,20 @@ extern Bitu cycle_count; #include "core_16/support.h" static Bitu CPU_Real_16_Slow_Decode_Special(Bitu count); -static Bitu CPU_Real_16_Slow_Decode(Bitu count) { + +static Bitu CPU_Real_16_Slow_Decode(Bits count) { #include "core_16/start.h" - while (count) { + do { #if C_DEBUG cycle_count++; #endif - count--; #include "core_16/main.h" - } + } while (--count>0); #include "core_16/stop.h" return CBRET_NONE; } -static Bitu CPU_Real_16_Slow_Decode_Special(Bitu count) { +static Bitu CPU_Real_16_Slow_Decode_Special(Bits count) { while (count>0) { if (flags.tf) { Interrupt(3); From 311f87dcb459529c57429853a484adc27cfdb524 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Oct 2002 10:44:31 +0000 Subject: [PATCH 0309/4131] Changed the counter for the cpu decoder to a signed integer and changed the cpu_cycle counter Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@386 --- include/cpu.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 17127132..ca649584 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -25,9 +25,9 @@ /* Some common Defines */ /* A CPU Handler */ -typedef Bitu (CPU_Decoder)(Bitu count); +typedef Bitu (CPU_Decoder)(Bits count); extern CPU_Decoder * cpudecoder; -extern Bit32u cpu_cycles; +extern Bitu cpu_cycles; //CPU Stuff void SetCPU16bit(); From c197b1e6eb076ba819d7901f6025a0970b3add35 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Oct 2002 14:05:23 +0000 Subject: [PATCH 0310/4131] Fix to use the new parameterblock Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@387 --- src/shell/shell_misc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 53289223..c300d8ba 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -165,7 +165,7 @@ void DOS_Shell::Execute(char * name,char * args) { /* Copy command line in stack block too */ MEM_BlockWrite(SegPhys(ss)+reg_sp+0x100,&cmd,128); /* Set the command line in the block and save it */ - block.data.exec.cmdtail=RealMakeSeg(ss,reg_sp+0x100); + block.exec.cmdtail=RealMakeSeg(ss,reg_sp+0x100); block.SaveData(); /* Save CS:IP to some point where i can return them from */ RealPt newcsip=CALLBACK_RealPointer(call_shellstop); From 24c5e436be08b8ee26bad8f0673c1274be17cfa7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 21 Oct 2002 08:56:04 +0000 Subject: [PATCH 0311/4131] added linking against libpng Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@388 --- src/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 0b960ea8..98140498 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,5 +6,5 @@ bin_PROGRAMS = dosbox dosbox_SOURCES = dosbox.cpp dosbox_LDADD = cpu/libcpu.a debug/libdebug.a dos/libdos.a fpu/libfpu.a hardware/libhardware.a gui/libgui.a \ - ints/libints.a misc/libmisc.a shell/libshell.a -lcurses -EXTRA_DIST = dosbox.lang \ No newline at end of file + ints/libints.a misc/libmisc.a shell/libshell.a -lcurses -lpng +EXTRA_DIST = dosbox.lang From 328814cf227dd1e0731e58c90e30af87a19c44a1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 21 Oct 2002 21:58:45 +0000 Subject: [PATCH 0312/4131] Fixed unlocking handles, to report error when not locked. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@389 --- src/ints/xms.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index d89b3121..d369d350 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -54,6 +54,8 @@ #define XMS_OUT_OF_SPACE 0xa0 #define XMS_OUT_OF_HANDLES 0xa1 #define XMS_INVALID_HANDLE 0xa2 +#define XMS_BLOCK_NOT_LOCKED 0xaa +#define XMS_BLOCK_LOCKED 0xab struct XMS_Block { Bit16u prev,next; @@ -292,8 +294,13 @@ foundnew: reg_bl=XMS_INVALID_HANDLE; return CBRET_NONE; } - if (xms_handles[reg_dx].locked) xms_handles[reg_dx].locked--; - reg_ax=1;reg_bl=0; + if (xms_handles[reg_dx].locked) { + xms_handles[reg_dx].locked--; + reg_ax=1;reg_bl=0; + } else { + reg_ax=0; + reg_bl=XMS_BLOCK_NOT_LOCKED; + } break; case XMS_GET_EMB_HANDLE_INFORMATION: /* 0e */ /* Check for a valid handle */ From 9a4a06ff30e20e4b75ac03f3e333382d608c2cf3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 21 Oct 2002 21:59:33 +0000 Subject: [PATCH 0313/4131] Added faked support for set event wait flag int 15 call. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@390 --- src/ints/bios.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index aa8ac9d5..a02c2454 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -22,7 +22,7 @@ #include "callback.h" #include "inout.h" #include "mem.h" - +#include "timer.h" static Bitu call_int1a,call_int11,call_int8,call_int17,call_int12,call_int15,call_int1c; @@ -136,6 +136,12 @@ static Bitu INT17_Handler(void) { return CBRET_NONE; }; +static void WaitFlagEvent(void) { + PhysPt where=Real2Phys(mem_readd(BIOS_WAIT_FLAG_POINTER)); + mem_writeb(where,mem_readb(where)|0x80); + mem_writeb(BIOS_WAIT_FLAG_ACTIVE,0); +} + static Bitu INT15_Handler(void) { switch (reg_ah) { case 0x06: @@ -149,6 +155,12 @@ static Bitu INT15_Handler(void) { /* Carry should be set but let's just set it just in case */ CALLBACK_SCF(true); break; + case 0x83: /* BIOS - SET EVENT WAIT INTERVAL */ + mem_writed(BIOS_WAIT_FLAG_POINTER,RealMake(SegValue(es),reg_bx)); + mem_writed(BIOS_WAIT_FLAG_COUNT,reg_cx<<16|reg_dx); + mem_writeb(BIOS_WAIT_FLAG_ACTIVE,1); + TIMER_RegisterDelayHandler(&WaitFlagEvent,reg_cx<<16|reg_dx); + break; case 0x84: /* BIOS - JOYSTICK SUPPORT (XT after 11/8/82,AT,XT286,PS) */ //Does anyone even use this? LOG_WARN("INT15:84:Bios Joystick functionality not done"); @@ -181,6 +193,8 @@ static Bitu INT15_Handler(void) { break; default: LOG_WARN("INT15:Unknown call %2X",reg_ah); + reg_ah=0x86; + CALLBACK_SCF(false); } return CBRET_NONE; }; From 633bd5c058468ce2f047655aad77297a5a304cd8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 21 Oct 2002 21:59:54 +0000 Subject: [PATCH 0314/4131] Some entries for the wait flag support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@391 --- include/bios.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/bios.h b/include/bios.h index 61d940bc..ef37fa88 100644 --- a/include/bios.h +++ b/include/bios.h @@ -84,6 +84,11 @@ #define BIOS_KEYBOARD_FLAGS3 0x496 #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_PRINT_SCREEN_FLAG 0x500 #define BIOS_VIDEO_SAVEPTR 0x4a8 From a835e6e3282ddc30273271a2e2bebc2c998a1138 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 21 Oct 2002 22:07:54 +0000 Subject: [PATCH 0315/4131] case insensitive compares used now. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@392 --- src/misc/setup.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 9d0b8b98..2dce0ee3 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -127,7 +127,7 @@ void Section_prop::HandleInputline(char *gegevens){ *rest=0; gegevens=trim(gegevens); for(it tel=properties.begin();tel!=properties.end();tel++){ - if((*tel)->propname==gegevens){ + if(!strcasecmp((*tel)->propname.c_str(),gegevens)){ (*tel)->SetValue(rest+1); return; } @@ -211,14 +211,17 @@ Config::~Config() { Section* Config::GetSection(const char* _sectionname){ for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ - if ( (*tel)->sectionname==_sectionname) return (*tel); + if (!strcasecmp((*tel)->sectionname.c_str(),_sectionname)) return (*tel); } return NULL; } void Config::ParseConfigFile(const char* configfilename){ ifstream in(configfilename); - if (!in) LOG_MSG("CONFIG:Can't find config file %s, using default settings",configfilename); + if (!in) { + LOG_MSG("CONFIG:Can't find config file %s, using default settings",configfilename); + return; + } char gegevens[150]; Section* currentsection; while (in) { @@ -302,7 +305,7 @@ bool CommandLine::FindCommand(int which,std::string & value) { bool CommandLine::FindEntry(char * name,cmd_it & it,bool neednext) { for (it=cmds.begin();it!=cmds.end();it++) { - if ((*it)==name) { + if (!strcasecmp((*it).c_str(),name)) { cmd_it itnext=it;itnext++; if (neednext && (itnext==cmds.end())) return false; return true; From 973be7b16f0e80b1d13237db48403f70905b5c80 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 21 Oct 2002 22:09:19 +0000 Subject: [PATCH 0316/4131] Added some instructions and fixed a very annoying bug with wrong fetched byte size. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@393 --- src/cpu/core_16/prefix_66.h | 63 ++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index 86e71a25..a22c79ce 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -24,7 +24,7 @@ switch(Fetchb()) { RMGdEd(ADDD);break; case 0x05: /* ADD EAX,Id */ EAXId(ADDD);break; - case 0x09: /* OR Ew,Gw */ + case 0x09: /* OR Ed,Gd */ RMEdGd(ORD);break; case 0x0b: /* OR Gd,Ed */ RMGdEd(ORD);break; @@ -199,7 +199,7 @@ switch(Fetchb()) { case 0x38:CMPD(*eard,id,LoadRd,SaveRd);break; } } else { - GetEAa;Bit32u id=Fetchb(); + GetEAa;Bit32u id=Fetchd(); switch (rm & 0x38) { case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break; case 0x08: ORD(eaa,id,LoadMd,SaveMd);break; @@ -245,14 +245,13 @@ switch(Fetchb()) { break; case 0x85: /* TEST Ed,Gd */ RMEdGd(TESTD);break; - case 0x8f: /* POP Ed */ - { - GetRM; - if (rm >= 0xc0 ) {GetEArd;*eard=Pop_32();} - else {GetEAa;SaveMd(eaa,Pop_32());} + case 0x87: /* XCHG Ev,Gv */ + { + GetRMrd;Bit32u oldrmrd=*rmrd; + if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;*eard=oldrmrd;} + else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,oldrmrd);} break; } - case 0x89: /* MOV Ed,Gd */ { GetRMrd; @@ -260,10 +259,6 @@ switch(Fetchb()) { 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; @@ -274,6 +269,42 @@ switch(Fetchb()) { case 0x8c: LOG_WARN("CPU:66:8c looped back"); break; + case 0x8f: /* POP Ed */ + { + GetRM; + if (rm >= 0xc0 ) {GetEArd;*eard=Pop_32();} + else {GetEAa;SaveMd(eaa,Pop_32());} + break; + } + case 0x90: /* NOP */ + break; + case 0x91: /* XCHG CX,AX */ + { Bit32u temp=reg_eax;reg_eax=reg_ecx;reg_ecx=temp; } + break; + case 0x92: /* XCHG DX,AX */ + { Bit32u temp=reg_eax;reg_eax=reg_edx;reg_edx=temp; } + break; + case 0x93: /* XCHG BX,AX */ + { Bit32u temp=reg_eax;reg_eax=reg_ebx;reg_ebx=temp; } + break; + case 0x94: /* XCHG SP,AX */ + { Bit32u temp=reg_eax;reg_eax=reg_esp;reg_esp=temp; } + break; + case 0x95: /* XCHG BP,AX */ + { Bit32u temp=reg_eax;reg_eax=reg_ebp;reg_ebp=temp; } + break; + case 0x96: /* XCHG SI,AX */ + { Bit32u temp=reg_eax;reg_eax=reg_esi;reg_esi=temp; } + break; + case 0x97: /* XCHG DI,AX */ + { Bit32u temp=reg_eax;reg_eax=reg_edi;reg_edi=temp; } + break; + case 0x98: /* CWD */ + reg_eax=(Bit16s)reg_ax;break; + case 0x99: /* CDQ */ + if (reg_eax & 0x80000000) reg_edx=0xffffffff; + else reg_edx=0; + break; case 0x9c: /* PUSHFD */ { Bit32u pflags= @@ -309,6 +340,9 @@ switch(Fetchb()) { else { reg_si+=4;reg_di+=4;} } break; + case 0xa9: /* TEST EAX,Id */ + EAXId(TESTD); + break; case 0xab: /* STOSD */ { stringDI; @@ -362,6 +396,7 @@ switch(Fetchb()) { GRP2D(1);break; case 0xd3: /* GRP2 Ed,CL */ GRP2D(reg_cl);break; + case 0xf7: /* GRP3 Ed(,Id) */ { union { Bit64u u;Bit64s s;} temp; @@ -454,12 +489,12 @@ switch(Fetchb()) { { GetRM; switch (rm & 0x38) { - case 0x00: /* INC Ew */ + case 0x00: /* INC Ed */ 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 */ + case 0x08: /* DEC Ed */ 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);} From 5df512bcc084ef5d1791e37809463438ad7525ef Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 22 Oct 2002 11:12:07 +0000 Subject: [PATCH 0317/4131] fixed small bug (files were not shown using dir command) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@394 --- src/dos/dos_classes.cpp | 2 +- src/dos/drive_local.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index d3a9f684..c6fc680f 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -244,7 +244,7 @@ void DOS_DTA::GetSearchParams(Bit8u & attr,char * pattern) { memcpy(pattern,temp,8); pattern[8]='.'; memcpy(&pattern[9],&temp[8],3); - pattern[12]=0; +// pattern[12]=0; } diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 54564901..d4b1b046 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -96,7 +96,7 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { CROSS_FILENAME(srch_dir); char end[2]={CROSS_FILESPLIT,0}; - if (srch_dir[strlen(srch_dir)]!=CROSS_FILESPLIT) strcat(srch_dir,end); + if (srch_dir[strlen(srch_dir)-1]!=CROSS_FILESPLIT) strcat(srch_dir,end); if((srch_opendir=opendir(srch_dir))==NULL) return false; return FindNext(dta); } From 2f528432fc5696ff8a4dcaedb04cb535a53c3150 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 22 Oct 2002 11:25:23 +0000 Subject: [PATCH 0318/4131] fixed small bug (files were not shown using dir command) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@395 --- src/dos/dos_classes.cpp | 2 +- src/dos/drive_local.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index c6fc680f..d3a9f684 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -244,7 +244,7 @@ void DOS_DTA::GetSearchParams(Bit8u & attr,char * pattern) { memcpy(pattern,temp,8); pattern[8]='.'; memcpy(&pattern[9],&temp[8],3); -// pattern[12]=0; + pattern[12]=0; } diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index d4b1b046..9da20569 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -105,7 +105,7 @@ bool localDrive::FindNext(DOS_DTA & dta) { struct dirent * dir_ent; struct stat stat_block; char full_name[CROSS_LEN]; - Bit8u srch_attr;char srch_pattern[DOS_NAMELENGTH]; + Bit8u srch_attr;char srch_pattern[DOS_NAMELENGTH_ASCII]; Bit8u find_attr; if(!srch_opendir) return false; From 18ae21e86648f5c76f702a781d426fc1402a2142 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 22 Oct 2002 17:52:38 +0000 Subject: [PATCH 0319/4131] added help messages for the configfile and updated the readme and install to reflect libpng and zlib Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@396 --- INSTALL | 15 +++++++++++---- README | 8 +++++++- src/cpu/cpu.cpp | 1 + src/debug/debug.cpp | 1 + src/dos/dos.cpp | 1 + src/dosbox.cpp | 7 ++++--- src/gui/sdlmain.cpp | 5 +++-- src/hardware/mixer.cpp | 1 + src/hardware/pcspeaker.cpp | 1 + src/hardware/sblaster.cpp | 1 + src/ints/bios.cpp | 1 + src/misc/setup.cpp | 3 ++- src/shell/shell.cpp | 1 + 13 files changed, 35 insertions(+), 11 deletions(-) diff --git a/INSTALL b/INSTALL index ad94ba93..53dfc974 100644 --- a/INSTALL +++ b/INSTALL @@ -11,8 +11,17 @@ Curses ncurses should be installed on just about every unix distro. For win32 get pdcurses at http://pdcurses.sourceforge.net +Libpng + Needed for the screenshots. + For win32 get libpng from http://www.sourceforge.net/projects/gnuwin32 + +Zlib + Needed by libpng. + For win32 get libz (rename to zlib) from http://www.sourceforge.net/projects/gnuwin32 + + If you want compile from the CVS under a unix system, you'll also need -automake, autoconf. Should be available at http://www.gnu.org +automake (>=1.6), autoconf(>=2.50). Should be available at http://www.gnu.org For building on unix systems. If you are building from the cvs run ./autogen.sh first before doing the following. @@ -21,8 +30,7 @@ If you are building from the cvs run ./autogen.sh first before doing the followi 2. Check settings.h for some setup options. 3. make -Check the src subdir for the binary and dosbox.lang file. -These 2 files should be in the same dir if you want to run dosbox. +Check the src subdir for the binary. Compiling on FreeBSD might be a problem since SDL has no joystick support there. To get around this edit sdlmain.cpp to enable some #define. @@ -32,5 +40,4 @@ Let's hope someday the sdl people will just report 0 joysticks in freebsd or get Build instructions for VC++6 Open the workspace in the visualc subdir and build from there. -Copy the src/dosbox.lang file to the same dir as your executable. diff --git a/README b/README index 10156103..16f1a7d7 100644 --- a/README +++ b/README @@ -1,10 +1,11 @@ -DOSBox v0.55 +DOSBox v0.56 Usage: ====== With the new internal shell I've changed the command line a bit, so let's just give some examples of what you can do now. + dosbox With nothing on the command line you'll end up on the internal drive and from there you can mount directories as drives. @@ -14,6 +15,11 @@ dosbox [filename/directory] .bat .com .exe. Doesn't need to have extension included. Then it'll strip the directory from the filename and mount that as c:\ and then run the file. +dosbox -fullscreen + starts dosbox in fullscreen mode. +dosbox -conf file + loads file as a configfile. + You can also add commands to be executed before the main program starts. Or you can use them to start the program. To add commands use the -c command line switch. diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 6ab41391..96e00840 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -170,5 +170,6 @@ void CPU_Init(Section* sec) { reg_al=0; reg_ah=0; + MSG_Add("CPU_CONFIGFILE_HELP","The amount of cycles to execute each loop. Lowering this setting will slowdown dosbox\n"); } diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 24e96674..f111318c 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -706,6 +706,7 @@ void DEBUG_Init(Section* sec) { #ifdef WIN32 WIN32_Console(); #endif + MSG_Add("DEBUG_CONFIGFILE_HELP","Nothing to setup yet!\n"); memset((void *)&dbg,0,sizeof(dbg)); debugging=false; dbg.active_win=3; diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index af57714d..13c66fd7 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -830,6 +830,7 @@ static Bitu DOS_20Handler(void) { void DOS_Init(Section* sec) { + MSG_Add("DOS_CONFIGFILE_HELP","Setting a memory size to 0 will disable it.\n"); call_20=CALLBACK_Allocate(); CALLBACK_Setup(call_20,DOS_20Handler,CB_IRET); RealSetVec(0x20,CALLBACK_RealPointer(call_20)); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 7cc8d219..deed99d2 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -123,7 +123,8 @@ static void DOSBOX_RealInit(Section * sec) { Section_prop * section=static_cast(sec); /* Initialize some dosbox internals */ errorlevel=section->Get_int("warnings"); - LastTicks=GetTicks(); + MSG_Add("DOSBOX_CONFIGFILE_HELP","General Dosbox settings\n"); + LastTicks=GetTicks(); DOSBOX_SetLoop(&Normal_Loop); MSG_Init(section); } @@ -137,7 +138,7 @@ void DOSBOX_Init(void) { /* Setup all the different modules making up DOSBox */ secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit); - secprop->Add_string("language",""); + secprop->Add_string("language",""); secprop->Add_int("warnings",4); secprop->AddInitFunction(&MEM_Init); @@ -191,7 +192,7 @@ void DOSBOX_Init(void) { secprop->Add_int("xmssize",8); secline=control->AddSection_line("autoexec",&AUTOEXEC_Init); - + control->SetStartUp(&SHELL_Init); #if C_FPU diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index b88af150..6178b325 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -225,6 +225,7 @@ static void GUI_ShutDown(Section * sec) { } static void GUI_StartUp(Section * sec) { + MSG_Add("SDL_CONFIGFILE_HELP","SDL related options.\n"); sec->AddDestroyFunction(&GUI_ShutDown); Section_prop * section=static_cast(sec); sdl.active=false; @@ -507,7 +508,7 @@ int main(int argc, char* argv[]) { #endif ) < 0 ) E_Exit("Can't init SDL %s",SDL_GetError()); Section_prop * sdl_sec=control->AddSection_prop("SDL",&GUI_StartUp); - sdl_sec->Add_bool("FULLSCREEN",false); + sdl_sec->Add_bool("fullscreen",false); /* Init all the dosbox subsystems */ DOSBOX_Init(); std::string config_file; @@ -529,7 +530,7 @@ int main(int argc, char* argv[]) { JOYSTICK_Enable(0,true); } #endif - if (control->cmdline->FindExist("-fullscreen") || sdl_sec->Get_bool("FULLSCREEN")) { + if (control->cmdline->FindExist("-fullscreen") || sdl_sec->Get_bool("fullscreen")) { SwitchFullScreen(); } /* Start up main machine */ diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 553abe41..bbf00b33 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -218,6 +218,7 @@ static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { void MIXER_Init(Section* sec) { + MSG_Add("MIXER_CONFIGFILE_HELP","Nothing to setup yet!\n"); /* Initialize the internal stuff */ first_channel=0; mix_ticks=GetTicks(); diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 34f06b79..5043df46 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -96,6 +96,7 @@ static void PCSPEAKER_CallBack(Bit8u * stream,Bit32u len) { } void PCSPEAKER_Init(Section* sec) { + MSG_Add("SPEAKER_CONFIGFILE_HELP","pcspeaker related options.\n"); spkr.chan=MIXER_AddChannel(&PCSPEAKER_CallBack,SPKR_RATE,"PC-SPEAKER"); MIXER_Enable(spkr.chan,false); MIXER_SetMode(spkr.chan,MIXER_16MONO); diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index f023ad6d..fd9564f7 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -557,6 +557,7 @@ static void SB_Enable(bool enable) { } void SBLASTER_Init(Section* sec) { + MSG_Add("SBLASTER_CONFIGFILE_HELP","Sound Blaster related options.\n"); Section_prop * section=static_cast(sec); if(!section->Get_bool("enabled")) return; sb.chan=MIXER_AddChannel(&SBLASTER_CallBack,22050,"SBLASTER"); diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index a02c2454..64c80207 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -208,6 +208,7 @@ void BIOS_SetupKeyboard(void); void BIOS_SetupDisks(void); void BIOS_Init(Section* sec) { + MSG_Add("BIOS_CONFIGFILE_HELP","Nothing to setup yet!\n"); /* Clear the Bios Data Area */ for (Bit16u i=0;i<1024;i++) real_writeb(0x40,i,0); /* Setup all the interrupt handlers the bios controls */ diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 2dce0ee3..09cfa7a4 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -41,7 +41,7 @@ void Prop_string::SetValue(char* input){ void Prop_bool::SetValue(char* input){ input=trim(input); - if((input[0]=='0') ||(input[0]=='D')||( (input[0]=='O') && (input[0]=='F'))){ + if((input[0]=='0') ||(input[0]=='D')||( (input[0]=='O') && (input[0]=='F'))||(input[0]=='f')){ __value._bool=false; }else{ __value._bool=true; @@ -231,6 +231,7 @@ void Config::ParseConfigFile(const char* configfilename){ case '%': case '\0': case '\n': + case '#': case ' ': continue; break; diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 46bc49f8..730a00dd 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -134,6 +134,7 @@ void DOS_Shell::SyntaxError(void) { void AUTOEXEC_Init(Section * sec) { + MSG_Add("AUTOEXEC_CONFIGFILE_HELP","Add here the lines you want to execute on startup.\n"); /* Register a virtual AUOEXEC.BAT file */ Section_line * section=static_cast(sec); From 668fd3df0340fc459803c851564d123aadc41070 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 23 Oct 2002 21:50:51 +0000 Subject: [PATCH 0320/4131] New mouse automatic locking scheme and some cleaning up. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@397 --- src/ints/mouse.cpp | 77 +++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 9410e1b8..1501d7f8 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -25,7 +25,7 @@ #include "mouse.h" #include "pic.h" #include "inout.h" - +#include "int10.h" static Bitu call_int33,call_int74; @@ -35,24 +35,22 @@ struct button_event { }; #define QUEUE_SIZE 32 -//TODO Maybe use :) +#define MOUSE_BUTTONS 3 #define MOUSE_IRQ 12 -#define POS_X (Bit16s)(mouse.x*mouse.range_x) -#define POS_Y (Bit16s)(mouse.y*mouse.range_y) - +#define POS_X (Bit16s)(mouse.x) +#define POS_Y (Bit16s)(mouse.y) static struct { Bit16u buttons; - Bit16u times_pressed[3]; - Bit16u times_released[3]; - Bit16u last_released_x[3]; - Bit16u last_released_y[3]; - Bit16u last_pressed_x[3]; - Bit16u last_pressed_y[3]; + Bit16u times_pressed[MOUSE_BUTTONS]; + Bit16u times_released[MOUSE_BUTTONS]; + Bit16u last_released_x[MOUSE_BUTTONS]; + Bit16u last_released_y[MOUSE_BUTTONS]; + Bit16u last_pressed_x[MOUSE_BUTTONS]; + Bit16u last_pressed_y[MOUSE_BUTTONS]; Bit16s shown; float add_x,add_y; Bit16u min_x,max_x,min_y,max_y; - float range_x,range_y; float mickey_x,mickey_y; float x,y; button_event event_queue[QUEUE_SIZE]; @@ -61,8 +59,8 @@ static struct { Bit16u sub_mask; } mouse; -#define X_MICKEY 500 -#define Y_MICKEY 500 +#define X_MICKEY 8 +#define Y_MICKEY 8 #define MOUSE_MOVED 1 #define MOUSE_LEFT_PRESSED 2 @@ -72,7 +70,7 @@ static struct { #define MOUSE_MIDDLE_PRESSED 32 #define MOUSE_MIDDLE_RELEASED 64 -inline void Mouse_AddEvent(Bit16u type) { +INLINE void Mouse_AddEvent(Bit16u type) { if (mouse.events1) mouse.x=1; - if (mouse.x<0) mouse.x=0; + if (mouse.x>mouse.max_x) mouse.x=mouse.max_x;; + if (mouse.x1) mouse.y=1; - if (mouse.y<0) mouse.y=0; + if (mouse.y>mouse.max_y) mouse.y=mouse.max_y;; + if (mouse.y=MOUSE_BUTTONS) break; reg_ax=mouse.buttons; reg_cx=mouse.last_pressed_x[but]; mouse.last_pressed_x[but]=0; @@ -199,6 +201,7 @@ static Bitu INT33_Handler(void) { case 0x06: /* Return Button Release Data */ { Bit16u but=reg_bx; + if (but>=MOUSE_BUTTONS) break; reg_ax=mouse.buttons; reg_cx=mouse.last_released_x[but]; mouse.last_released_x[but]=0; @@ -211,13 +214,10 @@ static Bitu INT33_Handler(void) { case 0x07: /* Define horizontal cursor range */ mouse.min_x=reg_cx; mouse.max_x=reg_dx; - mouse.range_x=mouse.max_x-mouse.min_x; -//TODO Check for range start 0 break; case 0x08: /* Define vertical cursor range */ mouse.min_y=reg_cx; mouse.max_y=reg_dx; - mouse.range_y=mouse.max_y-mouse.min_y; break; case 0x09: /* Define GFX Cursor */ LOG_WARN("MOUSE:Define gfx cursor not supported"); @@ -240,7 +240,8 @@ static Bitu INT33_Handler(void) { mouse.mickey_y=0; break; case 0x14: /* Exchange event-handler */ - { Bit16u oldSeg = mouse.sub_seg; + { + Bit16u oldSeg = mouse.sub_seg; Bit16u oldOfs = mouse.sub_ofs; Bit16u oldMask= mouse.sub_mask; // Set new values @@ -251,7 +252,8 @@ static Bitu INT33_Handler(void) { reg_cx = oldMask; reg_dx = oldOfs; SegSet16(es,oldSeg); - }; break; + } + break; case 0x1c: /* Set interrupt rate */ /* Can't really set a rate this is host determined */ break; @@ -267,9 +269,9 @@ static Bitu INT33_Handler(void) { break; default: LOG_ERROR("Mouse Function %2X",reg_ax); - }; + } return CBRET_NONE; -}; +} static Bitu INT74_Handler(void) { if (mouse.events>0) { @@ -301,14 +303,11 @@ static Bitu INT74_Handler(void) { } IO_Write(0xa0,0x20); /* Check for more Events if so reactivate IRQ */ - if (mouse.events) { PIC_ActivateIRQ(12); } - return CBRET_NONE; -}; - +} void MOUSE_Init(Section* sec) { call_int33=CALLBACK_Allocate(); @@ -319,7 +318,7 @@ void MOUSE_Init(Section* sec) { CALLBACK_Setup(call_int74,&INT74_Handler,CB_IRET); real_writed(0,(0x74<<2),CALLBACK_RealPointer(call_int74)); - memset((void *)&mouse,0,sizeof(mouse)); + memset(&mouse,0,sizeof(mouse)); mouse_reset(); -}; +} From 7d764b2077bab7fd8cdaa9f349a5eb2fa4650e49 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 23 Oct 2002 21:51:15 +0000 Subject: [PATCH 0321/4131] New mouse automatic locking scheme Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@398 --- include/mouse.h | 1 + src/gui/sdlmain.cpp | 47 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/include/mouse.h b/include/mouse.h index 4d0c932c..764d5504 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -25,4 +25,5 @@ void Mouse_CursorSet(float x,float y); void Mouse_ButtonPressed(Bit8u button); void Mouse_ButtonReleased(Bit8u button); +void Mouse_AutoLock(bool enable); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 6178b325..b9b75098 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -41,17 +41,23 @@ struct SDL_Block { Bitu bpp; GFX_DrawHandler * draw; GFX_ResizeHandler * resize; - bool mouse_grabbed; bool full_screen; SDL_Thread * thread; SDL_mutex * mutex; SDL_Surface * surface; SDL_Joystick * joy; SDL_Color pal[256]; + struct { + bool autolock; + bool autoenable; + bool requestlock; + bool locked; + Bitu sensitivity; + } mouse; struct { Bitu skip; Bitu count; - }frames ; + } frames ; }; static SDL_Block sdl; @@ -104,8 +110,8 @@ void GFX_Resize(Bitu width,Bitu height,Bitu bpp,GFX_ResizeHandler * resize) { } static void CaptureMouse() { - sdl.mouse_grabbed=!sdl.mouse_grabbed; - if (sdl.mouse_grabbed) { + sdl.mouse.locked=!sdl.mouse.locked; + if (sdl.mouse.locked) { SDL_WM_GrabInput(SDL_GRAB_ON); SDL_ShowCursor(SDL_DISABLE); } else { @@ -119,7 +125,6 @@ static void DecreaseSkip() { LOG_MSG("Frame Skip %d",sdl.frames.skip); } - static void IncreaseSkip() { if (sdl.frames.skip<10) sdl.frames.skip++; LOG_MSG("Frame Skip %d",sdl.frames.skip); @@ -233,6 +238,12 @@ static void GUI_StartUp(Section * sec) { sdl.frames.skip=0; sdl.frames.count=0; sdl.draw=0; + + sdl.mouse.locked=false; + sdl.mouse.requestlock=false; + sdl.mouse.autoenable=section->Get_bool("autolock"); + sdl.mouse.autolock=false; + sdl.mouse.sensitivity=section->Get_int("sensitivity"); GFX_Resize(640,400,8,0); #if C_THREADED sdl.mutex=SDL_CreateMutex(); @@ -251,10 +262,15 @@ static void GUI_StartUp(Section * sec) { void GFX_ShutDown() { if (sdl.full_screen) SwitchFullScreen(); - if (sdl.mouse_grabbed) CaptureMouse(); + if (sdl.mouse.locked) CaptureMouse(); GFX_Stop(); } +void Mouse_AutoLock(bool enable) { + sdl.mouse.autolock=enable; + if (enable && sdl.mouse.autoenable) sdl.mouse.requestlock=true; + else sdl.mouse.requestlock=false; +} static void HandleKey(SDL_KeyboardEvent * key) { Bit32u code; @@ -384,16 +400,17 @@ static void HandleKey(SDL_KeyboardEvent * key) { } static void HandleMouseMotion(SDL_MouseMotionEvent * motion) { - if (!sdl.mouse_grabbed) { - Mouse_CursorSet((float)motion->x/(float)sdl.width,(float)motion->y/(float)sdl.height); + if (sdl.mouse.locked) { + Mouse_CursorMoved((float)motion->xrel*sdl.mouse.sensitivity/100,(float)motion->yrel*sdl.mouse.sensitivity/100); } else { - Mouse_CursorMoved((float)motion->xrel/(float)sdl.width,(float)motion->yrel/(float)sdl.height); +// Mouse_CursorSet((float)motion->x/(float)sdl.width,(float)motion->y/(float)sdl.height); } } static void HandleMouseButton(SDL_MouseButtonEvent * button) { switch (button->state) { case SDL_PRESSED: + if (sdl.mouse.requestlock && !sdl.mouse.locked) CaptureMouse(); switch (button->button) { case SDL_BUTTON_LEFT: Mouse_ButtonPressed(0); @@ -460,6 +477,13 @@ void GFX_Events() { SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { + case SDL_ACTIVEEVENT: + if (event.active.state & SDL_APPINPUTFOCUS) { + if (!event.active.gain && sdl.mouse.locked) { + CaptureMouse(); + } + } + break; case SDL_KEYDOWN: case SDL_KEYUP: HandleKey(&event.key); @@ -507,8 +531,11 @@ int main(int argc, char* argv[]) { #endif ) < 0 ) E_Exit("Can't init SDL %s",SDL_GetError()); - Section_prop * sdl_sec=control->AddSection_prop("SDL",&GUI_StartUp); + Section_prop * sdl_sec=control->AddSection_prop("sdl",&GUI_StartUp); sdl_sec->Add_bool("fullscreen",false); + sdl_sec->Add_bool("autolock",true); + sdl_sec->Add_int("sensitivity",100); + /* Init all the dosbox subsystems */ DOSBOX_Init(); std::string config_file; From b6ee1caa6d6267b2cc99353bbd0dda887c613f03 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 23 Oct 2002 23:08:41 +0000 Subject: [PATCH 0322/4131] Added partial page map save and restore Rewrote detecion of valid handles to use page!=0xffff and allowed reallocation to 0 pages. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@399 --- src/ints/ems.cpp | 72 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 16 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 1175ae95..0a8cb525 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -131,7 +131,7 @@ static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & handle) { if (EMM_GetFreePages()=EMM_MAX_HANDLES) {handle=NULL_HANDLE;return EMM_OUT_OF_HANDLES;} } /* Allocate the pages */ @@ -155,7 +155,7 @@ static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & handle) { static Bit8u EMM_ReallocatePages(Bit16u handle,Bit16u & pages) { /* Check for valid handle */ - if (handle>=EMM_MAX_HANDLES || emm_handles[handle].first_page==NULL_PAGE) return EMM_INVALID_HANDLE; + if (handle>=EMM_MAX_HANDLES || emm_handles[handle].pages==NULL_HANDLE) return EMM_INVALID_HANDLE; /* Check for enough pages */ if ((emm_handles[handle].pages+EMM_GetFreePages())=EMM_MAX_PHYS) return EMM_ILL_PHYS; /* Check for valid handle */ - if (handle>=EMM_MAX_HANDLES || emm_handles[handle].first_page==NULL_PAGE) return EMM_INVALID_HANDLE; + if (handle>=EMM_MAX_HANDLES || emm_handles[handle].pages==NULL_HANDLE) return EMM_INVALID_HANDLE; /* Check to do unmapping or mappning */ if (log_page=EMM_MAX_HANDLES || emm_handles[handle].first_page==NULL_PAGE) return EMM_INVALID_HANDLE; + if (handle>=EMM_MAX_HANDLES || emm_handles[handle].pages==NULL_HANDLE) return EMM_INVALID_HANDLE; Bit16u page=emm_handles[handle].first_page; Bit16u pages=emm_handles[handle].pages; while (pages) { @@ -260,7 +262,7 @@ static Bit8u EMM_ReleaseMemory(Bit16u handle) { } /* Reset handle */ emm_handles[handle].first_page=NULL_PAGE; - emm_handles[handle].pages=0; + emm_handles[handle].pages=NULL_HANDLE; emm_handles[handle].saved_page_map=false; memset(&emm_handles[handle].name,0,9); return EMM_NO_ERROR; @@ -268,7 +270,7 @@ static Bit8u EMM_ReleaseMemory(Bit16u handle) { static Bit8u EMM_SavePageMap(Bit16u handle) { /* Check for valid handle */ - if (handle>=EMM_MAX_HANDLES || emm_handles[handle].first_page==NULL_PAGE) return EMM_INVALID_HANDLE; + if (handle>=EMM_MAX_HANDLES || emm_handles[handle].pages==NULL_HANDLE) return EMM_INVALID_HANDLE; /* Check for previous save */ if (emm_handles[handle].saved_page_map) return EMM_PAGE_MAP_SAVED; /* Copy the mappings over */ @@ -280,7 +282,7 @@ static Bit8u EMM_SavePageMap(Bit16u handle) { return EMM_NO_ERROR; } -static Bitu EMM_RestoreMappingTable(void) { +static Bit8u EMM_RestoreMappingTable(void) { Bit8u result; /* Move through the mappings table and setup mapping accordingly */ for (Bitu i=0;i=EMM_MAX_HANDLES || emm_handles[handle].first_page==NULL_PAGE) return EMM_INVALID_HANDLE; + if (handle>=EMM_MAX_HANDLES || emm_handles[handle].pages==NULL_HANDLE) return EMM_INVALID_HANDLE; /* Check for previous save */ if (!emm_handles[handle].saved_page_map) return EMM_INVALID_HANDLE; /* Restore the mappings */ @@ -305,7 +307,7 @@ static Bit8u EMM_RestorePageMap(Bit16u handle) { static Bit8u EMM_GetPagesForAllHandles(PhysPt table,Bit16u & handles) { handles=0; for (Bit16u i=0;i0;count--) { + Bit16u page=mem_readw(list);list+=2; + if (page>=EMM_MAX_PHYS) return EMM_ILL_PHYS; + mem_writew(data,page);data+=2; + MEM_BlockWrite(data,&emm_mappings[page],sizeof(EMM_Mapping)); + data+=sizeof(EMM_Mapping); + } + break; + case 0x01: /* Restore Partial Page Map */ + data = SegPhys(ds)+reg_si; + count= mem_readw(data);data+=2; + for (;count>0;count--) { + Bit16u page=mem_readw(data);data+=2; + if (page>=EMM_MAX_PHYS) return EMM_ILL_PHYS; + MEM_BlockRead(data,&emm_mappings[page],sizeof(EMM_Mapping)); + data+=sizeof(EMM_Mapping); + } + return EMM_RestoreMappingTable(); + break; + case 0x02: /* Get Partial Page Map Array Size */ + reg_al=2+reg_bx*(2+sizeof(EMM_Mapping)); + break; + default: + LOG_ERROR("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); + return EMM_FUNC_NOSUP; + } + return 0; +} + + static Bitu INT67_Handler(void) { Bitu i; switch (reg_ah) { @@ -351,12 +391,12 @@ static Bitu INT67_Handler(void) { break; case 0x4b: /* Get Handle Count */ reg_bx=0; - for (i=0;i=EMM_MAX_HANDLES || emm_handles[reg_bx].first_page==NULL_PAGE) {reg_ah=EMM_INVALID_HANDLE;break;} + if (reg_bx>=EMM_MAX_HANDLES || emm_handles[reg_bx].pages==NULL_HANDLE) {reg_ah=EMM_INVALID_HANDLE;break;} reg_bx=emm_handles[reg_dx].pages; reg_ah=EMM_NO_ERROR; break; @@ -364,7 +404,6 @@ static Bitu INT67_Handler(void) { reg_ah=EMM_GetPagesForAllHandles(SegPhys(es)+reg_di,reg_bx); break; case 0x4e: /*Save/Restore Page Map */ - LOG_WARN("Save/resetore %d",reg_al); switch (reg_al) { case 0x00: /* Save Page Map */ MEM_BlockWrite(SegPhys(es)+reg_di,emm_mappings,sizeof(emm_mappings)); @@ -389,10 +428,10 @@ static Bitu INT67_Handler(void) { break; } break; - case 0x4f: /* Save Partial Page Map */ - LOG_ERROR("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); - reg_ah=EMM_FUNC_NOSUP; + case 0x4f: /* Save/Restore Partial Page Map */ + reg_ah=EMM_PartialPageMapping(); break; + case 0x50: /* Map/Unmap multiple handle pages */ reg_ah = EMM_NO_ERROR; switch (reg_al) { @@ -483,6 +522,7 @@ void EMS_Init(Section* sec) { } for (i=0;i Date: Thu, 24 Oct 2002 08:44:25 +0000 Subject: [PATCH 0323/4131] added more internal strings to the language file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@400 --- src/dos/dos_programs.cpp | 65 ++++++++++++++++++++++++++-------------- src/dos/drive_local.cpp | 2 +- src/shell/shell.cpp | 16 +++++++++- src/shell/shell_cmds.cpp | 28 ++++++++--------- 4 files changed, 72 insertions(+), 39 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index c2e21b69..1046e124 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -35,10 +35,10 @@ public: /* Parse the command line */ /* if the command line is empty show current mounts */ if (!cmd->GetCount()) { - WriteOut("Current mounted drives are\n"); + WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_1")); for (int d=0;dGetInfo()); + WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),d+'A',Drives[d]->GetInfo()); } } return; @@ -75,12 +75,12 @@ public: if (!temp_line.size()) goto showusage; struct stat test; if (stat(temp_line.c_str(),&test)) { - WriteOut("Directory %s Doesn't exist",temp_line.c_str()); + WriteOut(MSG_Get("PROGRAM_MOUNT_ERROR_1"),temp_line.c_str()); return; } /* Not a switch so a normal directory/file */ if (!(test.st_mode & S_IFDIR)) { - WriteOut("%s isn't a directory",temp_line.c_str()); + WriteOut(MSG_Get("PROGRAM_MOUNT_ERROR_2"),temp_line.c_str()); return; } if (temp_line[temp_line.size()-1]!=CROSS_FILESPLIT) temp_line+=CROSS_FILESPLIT; @@ -91,7 +91,7 @@ public: drive=toupper(temp_line[0]); if (!isalpha(drive)) goto showusage; if (Drives[drive-'A']) { - WriteOut("Drive %c already mounted with %s\n",drive,Drives[drive-'A']->GetInfo()); + WriteOut(MSG_Get("PROGRAM_MOUNT_ALLREADY_MOUNDTED"),drive,Drives[drive-'A']->GetInfo()); if (newdrive) delete newdrive; return; } @@ -102,7 +102,7 @@ public: WriteOut("Drive %c mounted as %s\n",drive,newdrive->GetInfo()); return; showusage: - WriteOut("Usage MOUNT Drive-Letter Local-Directory\nSo a MOUNT c c:\\windows mounts windows directory as the c: drive in DOSBox\n"); + WriteOut(MSG_Get("PROGRAM_MOUNT_USAGE")); return; } }; @@ -118,7 +118,7 @@ public: WriteOut("\n"); Bit16u seg,blocks;blocks=0xffff; DOS_AllocateMemory(&seg,&blocks); - WriteOut("%10d Kb free conventional memory\n",blocks*16/1024); + WriteOut(MSG_Get("PROGRAM_MEM_CONVEN"),blocks*16/1024); /* Test for and show free XMS */ reg_ax=0x4300;CALLBACK_RunRealInt(0x2f); if (reg_al==0x80) { @@ -127,7 +127,7 @@ public: reg_ah=8; CALLBACK_RunRealFar(xms_seg,xms_off); if (!reg_bl) { - WriteOut("%10d Kb free extended memory\n",reg_dx); + WriteOut(MSG_Get("PROGRAM_MEM_EXTEND"),reg_dx); } } /* Test for and show free EMS */ @@ -136,7 +136,7 @@ public: DOS_CloseFile(handle); reg_ah=0x42; CALLBACK_RunRealInt(0x67); - WriteOut("%10d Kb free expanded memory\n",reg_bx*16); + WriteOut(MSG_Get("PROGRAM_MEM_EXPAND"),reg_bx*16); } } }; @@ -163,10 +163,10 @@ void UPCASE::upcasedir(const char * directory) { struct stat finfo; if(!(sdir=opendir(directory))) { - WriteOut("Failed to open directory %s\n",directory); + WriteOut(MSG_Get("PROGRAM_UPCASE_ERROR_DIR"),directory); return; } - WriteOut("Scanning directory %s\n",fullname); + WriteOut(MSG_Get("PROGRAM_UPCASE_SCANNING_DIR"),fullname); while (tempdata=readdir(sdir)) { if (strcmp(tempdata->d_name,".")==0) continue; if (strcmp(tempdata->d_name,"..")==0) continue; @@ -177,7 +177,7 @@ void UPCASE::upcasedir(const char * directory) { strcat(newname,"/"); upcase(tempdata->d_name); strcat(newname,tempdata->d_name); - WriteOut("Renaming %s to %s\n",fullname,newname); + WriteOut(MSG_Get("PROGRAM_UPCASE_RENAME"),fullname,newname); rename(fullname,newname); stat(fullname,&finfo); if(S_ISDIR(finfo.st_mode)) { @@ -191,31 +191,27 @@ void UPCASE::upcasedir(const char * directory) { void UPCASE::Run(void) { /* First check if the directory exists */ struct stat info; - WriteOut("UPCASE 0.1 Directory case convertor.\n"); + WriteOut(MSG_Get("PROGRAM_UPCASE_RUN_1")); if (!cmd->GetCount()) { - WriteOut("Usage UPCASE [local directory]\n"); - WriteOut("This tool will convert all files and subdirectories in a directory.\n"); - WriteOut("Be VERY sure this directory contains only dos related material.\n"); - WriteOut("Otherwise you might horribly screw up your filesystem.\n"); + WriteOut(MSG_Get("PROGRAM_UPCASE_USAGE")); return; } cmd->FindCommand(1,temp_line); if (stat(temp_line.c_str(),&info)) { - WriteOut("%s doesn't exist\n",temp_line.c_str()); + WriteOut(MSG_Get("PROGRAM_UPCASE_RUN_ERROR_1"),temp_line.c_str()); return; } if(!S_ISDIR(info.st_mode)) { - WriteOut("%s isn't a directory\n",temp_line.c_str()); + WriteOut(MSG_Get("PROGRAM_UPCASE_RUN_ERROR_2"),temp_line.c_str()); return; } - WriteOut("Converting the wrong directories can be very harmfull, please be carefull.\n"); - WriteOut("Are you really really sure you want to convert %s to upcase?Y/N\n",temp_line.c_str()); + WriteOut(MSG_Get("PROGRAM_UPCASE_RUN_CHOICE"),temp_line.c_str()); Bit8u key;Bit16u n=1; DOS_ReadFile(STDIN,&key,&n); if (toupper(key)=='Y') { upcasedir(temp_line.c_str()); } else { - WriteOut("Okay better not do it.\n"); + WriteOut(MSG_Get("PROGRAM_UPCASE_RUN_NO")); } } @@ -225,7 +221,30 @@ static void UPCASE_ProgramStart(Program * * make) { #endif void DOS_SetupPrograms(void) { - + /*Add Messages */ + MSG_Add("PROGRAM_MOUNT_STATUS_2","Drive %c is mounted as %s\n"); + MSG_Add("PROGRAM_MOUNT_STATUS_1","Current mounted drives are:\n"); + MSG_Add("PROGRAM_MOUNT_ERROR_1","Directory %s doesn't exist.\n"); + MSG_Add("PROGRAM_MOUNT_ERROR_2","%s isn't a directory\n"); + MSG_Add("PROGRAM_MOUNT_ALLREADY_MOUNTED","Drive %c already mounted with %s\n"); + MSG_Add("PROGRAM_MOUNT_USAGE","Usage MOUNT Drive-Letter Local-Directory\nSo a MOUNT c c:\\windows mounts windows directory as the c: drive in DOSBox\n"); + + MSG_Add("PROGRAM_MEM_CONVEN","%10d Kb free conventional memory\n"); + MSG_Add("PROGRAM_MEM_EXTEND","%10d Kb free extended memory\n"); + MSG_Add("PROGRAM_MEM_EXPAND","%10d Kb free expanded memory\n"); + +#if !defined (WIN32) /* Unix */ + MSG_Add("PROGRAM_UPCASE_ERROR_DIR","Failed to open directory %s\n"); + MSG_Add("PROGRAM_UPCASE_SCANNING_DIR","Scanning directory %s\n"); + MSG_Add("PROGRAM_UPCASE_RENAME","Renaming %s to %s\n"); + MSG_Add("PROGRAM_UPCASE_RUN_1","UPCASE 0.1 Directory case convertor.\n"); + MSG_Add("PROGRAM_UPCASE_USAGE","Usage UPCASE [local directory]\nThis tool will convert all files and subdirectories in a directory.\nBe VERY sure this directory contains only dos related material.\nOtherwise you might horribly screw up your filesystem.\n"); + MSG_Add("PROGRAM_UPCASE_RUN_ERROR_1","%s doesn't exist\n"); + MSG_Add("PROGRAM_UPCASE_RUN_ERROR_2","%s isn't a directory\n"); + MSG_Add("PROGRAM_UPCASE_RUN_CHOICE","Converting the wrong directories can be very harmfull, please be carefull.\nAre you really really sure you want to convert %s to upcase?Y/N\n"); + MSG_Add("PROGRAM_UPCASE_RUN_NO","Okay better not do it.\n"); +#endif + /*regular setup*/ PROGRAMS_MakeFile("MOUNT.COM",MOUNT_ProgramStart); PROGRAMS_MakeFile("MEM.COM",MEM_ProgramStart); #if !defined (WIN32) /* Unix */ diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 9da20569..228a6548 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -121,7 +121,7 @@ bool localDrive::FindNext(DOS_DTA & dta) { strcpy(full_name,srch_dir); strcat(full_name,dir_ent->d_name); if(stat(full_name,&stat_block)!=0){ - exit(1); + goto again; } if(S_ISDIR(stat_block.st_mode)) find_attr=DOS_ATTR_DIRECTORY; else find_attr=DOS_ATTR_ARCHIVE; diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 730a00dd..c785790f 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -202,7 +202,21 @@ void SHELL_Init() { MSG_Add("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\n"); MSG_Add("SHELL_EXECUTE_ILLEGAL_COMMAND","Illegal command: %s.\n"); MSG_Add("SHELL_STARTUP","DOSBox Shell v0.40\nFor Help and supported commands type: HELP\n\nHAVE FUN!\nThe DOSBox Team\n\n"); - /* Regular startup */ + MSG_Add("SHELL_CMD_CHDIR_HELP","Change Directory.\n"); + MSG_Add("SHELL_CMD_CLS_HELP","Clear screen.\n"); + MSG_Add("SHELL_CMD_DIR_HELP","Directory View.\n"); + MSG_Add("SHELL_CMD_ECHO_HELP","Display messages and enable/disable command echoing.\n"); + MSG_Add("SHELL_CMD_EXIT_HELP","Exit from the shell.\n"); + MSG_Add("SHELL_CMD_HELP_HELP","Show help.\n"); + MSG_Add("SHELL_CMD_MKDIR_HELP","Make Directory.\n"); + MSG_Add("SHELL_CMD_RMDIR_HELP","Remove Directory.\n"); + MSG_Add("SHELL_CMD_SET_HELP","Change environment variables.\n"); + MSG_Add("SHELL_CMD_IF_HELP","Performs conditional processing in batch programs.\n"); + MSG_Add("SHELL_CMD_GOTO_HELP","Jump to a labeled line in a batch script.\n"); + MSG_Add("SHELL_CMD_TYPE_HELP","Display the contents of a text-file.\n"); + MSG_Add("SHELL_CMD_REM_HELP","Add comments in a batch file.\n"); + + /* Regular startup */ call_shellstop=CALLBACK_Allocate(); CALLBACK_Setup(call_shellstop,shellstop_handler,CB_IRET); diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 2fa7b281..fee0e18c 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -24,20 +24,20 @@ static SHELL_Cmd cmd_list[]={ - "CD", 0, &DOS_Shell::CMD_CHDIR, "Change Directory.", - "CLS", 0, &DOS_Shell::CMD_CLS, "Clear screen.", + "CD", 0, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP", + "CLS", 0, &DOS_Shell::CMD_CLS, "SHELL_CMD_CLS_HELP", // "COPY", 0, &DOS_Shell::CMD_COPY, "Copy Files.", - "DIR", 0, &DOS_Shell::CMD_DIR, "Directory View.", - "ECHO", 0, &DOS_Shell::CMD_ECHO, "Display messages and enable/disable command echoing.", - "EXIT", 0, &DOS_Shell::CMD_EXIT, "Exit from the shell.", - "HELP", 0, &DOS_Shell::CMD_HELP, "Show help.", - "MD", 0, &DOS_Shell::CMD_MKDIR, "Make Directory.", - "RD", 0, &DOS_Shell::CMD_RMDIR, "Remove Directory.", - "SET", 0, &DOS_Shell::CMD_SET, "Change environment variables.", - "IF", 0, &DOS_Shell::CMD_IF, "Performs conditional processing in batch programs.", - "GOTO", 0, &DOS_Shell::CMD_GOTO, "Jump to a labeled line in a batch script.", - "TYPE", 0, &DOS_Shell::CMD_TYPE, "Display the contents of a text-file.", - "REM", 0, &DOS_Shell::CMD_REM, "Add comments in a batch file.", + "DIR", 0, &DOS_Shell::CMD_DIR, "SHELL_CMD_DIR_HELP", + "ECHO", 0, &DOS_Shell::CMD_ECHO, "SHELL_CMD_ECHO_HELP", + "EXIT", 0, &DOS_Shell::CMD_EXIT, "SHELL_CMD_EXIT_HELP", + "HELP", 0, &DOS_Shell::CMD_HELP, "SHELL_CMD_HELP_HELP", + "MD", 0, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP", + "RD", 0, &DOS_Shell::CMD_RMDIR, "SHELL_CMD_RMDIR_HELP", + "SET", 0, &DOS_Shell::CMD_SET, "SHELL_CMD_SET_HELP", + "IF", 0, &DOS_Shell::CMD_IF, "SHELL_CMD_IF_HELP", + "GOTO", 0, &DOS_Shell::CMD_GOTO, "SHELL_CMD_GOTO_HELP", + "TYPE", 0, &DOS_Shell::CMD_TYPE, "SHELL_CMD_TYPE_HELP", + "REM", 0, &DOS_Shell::CMD_REM, "SHELL_CMD_REM_HELP", /* "CHDIR", 0, &DOS_Shell::CMD_CHDIR, "Change Directory", @@ -85,7 +85,7 @@ void DOS_Shell::CMD_HELP(char * args){ WriteOut(MSG_Get("SHELL_CMD_HELP")); Bit32u cmd_index=0; while (cmd_list[cmd_index].name) { - if (!cmd_list[cmd_index].flags) WriteOut("%-8s %s\n",cmd_list[cmd_index].name,cmd_list[cmd_index].help); + if (!cmd_list[cmd_index].flags) WriteOut("%-8s %s",cmd_list[cmd_index].name,MSG_Get(cmd_list[cmd_index].help)); cmd_index++; } From 8cbb3cef0fb87a735128f83f45b4cb5ac36fad6f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Oct 2002 12:26:29 +0000 Subject: [PATCH 0324/4131] fixed a very annoying bug that caused dosbox to crash when dir was done on a virtual drive under linux Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@401 --- src/dos/drive_virtual.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index e65eb744..84235e3b 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -183,7 +183,7 @@ bool Virtual_Drive::FindFirst(char * _dir,DOS_DTA & dta) { } bool Virtual_Drive::FindNext(DOS_DTA & dta) { - Bit8u attr;char pattern[DOS_NAMELENGTH]; + Bit8u attr;char pattern[DOS_NAMELENGTH_ASCII]; dta.GetSearchParams(attr,pattern); while (search_file) { if (WildFileCmp(search_file->name,pattern)) { From e4f90123ff0753717f9f345e41a002b7a5748bb5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Oct 2002 12:27:02 +0000 Subject: [PATCH 0325/4131] Set Version to 0.56 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@402 --- src/platform/visualc/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 114b25bd..043d02bf 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -1,6 +1,6 @@ #define INLINE __forceinline -#define VERSION "0.55" +#define VERSION "0.56" #define GCC_ATTRIBUTE(x) /* attribute not supported */ From e8ce6d4628a94af45fabc7893b1f39f8b42cb7f2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Oct 2002 12:27:59 +0000 Subject: [PATCH 0326/4131] Removed some warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@403 --- src/hardware/vga_draw.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 2d07ba31..49d1a845 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -176,8 +176,8 @@ void VGA_DrawTEXT(Bit8u * bitdata,Bitu pitch) { vga.config.retrace=true; /* Draw a cursor */ - if ((vga.draw.cursor_col*8)>=vga.draw.width) return; - if ((vga.draw.cursor_row*16)>=vga.draw.height) return; + if (((Bitu)vga.draw.cursor_col*8)>=vga.draw.width) return; + if (((Bitu)vga.draw.cursor_row*16)>=vga.draw.height) return; Bit8u * cursor_draw=bitdata+(vga.draw.cursor_row*16+15)*pitch+vga.draw.cursor_col*8; if (vga.draw.cursor_count>8) { for (Bit8u loop=0;loop<8;loop++) *cursor_draw++=15; From dedc199628d4c40365101e7ad52e0a7497f16322 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Oct 2002 12:28:46 +0000 Subject: [PATCH 0327/4131] Documentation update and 0.56 preparations Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@404 --- ChangeLog | 12 +++++++++++- README | 29 ++++++++++++++++++++++++++--- VERSION | 2 +- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5a7923eb..51dbfd18 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,18 @@ -0.60 +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 + - VGA fixes + - new wildcompare + - support for size and disktype at mount. 0.55 - fixed the errors/warnings in prefix_66.h and prefix_66_of.h (decimal too large becomming unsigned). diff --git a/README b/README index 16f1a7d7..cf4d8cbf 100644 --- a/README +++ b/README @@ -19,6 +19,8 @@ dosbox -fullscreen starts dosbox in fullscreen mode. dosbox -conf file loads file as a configfile. +dosbox -lang file + loads file as a languagefile. You can also add commands to be executed before the main program starts. Or you can use them to start the program. @@ -35,10 +37,16 @@ Internal Programs: ================== MOUNT -Program to mount local directories as drives inside DOSBox. +Program to mount local directories as drives inside DOSBox. +The option -t specifies the media: dir = harddisk, floppy = floppy drive. +The option -size specifies the size. +For example to mount c:\floppy as a floppy : mount -t floppy a c:\floppy -HWSET -Utility to setup the emulated hardware running inside DOSBox, only working for emulated sound cards. +MEM +Program to display the amount of free memory + +CONFIG +Utility for generating a configfile with the current settings and for generating the languagefile. UPCASE Utility to convert all files subdirectories of a local directory into upcase so DOSBox can use that directory @@ -47,6 +55,21 @@ for mounting. This tool can be quite dangerous if used unproperly. You have been To get more information about how to use one these programs use the the /? command line switch. +The Configfile: +=============== +A configfile can be generated by CONFIG.COM. If you can edit it (it's plain text) to costumize DOSBox. +The file is devided in several sections (the names got [] around it). Some sections have options which you can set. +# and % indicate commentlines. +The generated configfile contains the current settings. You can alter them and +start dosbox with the -conf switch to load the file and use these settings. +For example in the section sblaster you can change the irq of the soundblaster and disable/enable the +adlib emulation. + +The Languagefile: +================= +A languagefile can be generated by CONFIG.COM. If you read it you will understand how to change it. +Start Dosbox with -lang switch to use your language file or enter the location of the languagefile +in the configfile.(section:[dosbox] language=path/to/langaugefile/languagefile) Special Keys: ============= diff --git a/VERSION b/VERSION index 575fe780..3fb437d8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.55 \ No newline at end of file +0.56 \ No newline at end of file From e3a5b55666a50495b803de808e0fcb6b5f920cdc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 24 Oct 2002 22:08:52 +0000 Subject: [PATCH 0328/4131] Small fix to psp class to set correct value for next segment Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@405 --- src/dos/dos_classes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index d3a9f684..3f1c7291 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -91,7 +91,7 @@ void DOS_PSP::MakeNew(Bit16u mem_size) Bitu i; for (i=0;i Date: Thu, 24 Oct 2002 22:28:33 +0000 Subject: [PATCH 0329/4131] Clean up of the batch file class Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@406 --- src/shell/shell_batch.cpp | 1 - src/shell/shell_inc.h | 4 ---- 2 files changed, 5 deletions(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 48c571f7..fdec91ba 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -32,7 +32,6 @@ BatchFile::BatchFile(DOS_Shell * host,char * name, char * cmd_line) { //TODO Come up with something better E_Exit("SHELL:Can't open BatchFile"); } - line_count=0; }; BatchFile::~BatchFile() { diff --git a/src/shell/shell_inc.h b/src/shell/shell_inc.h index a5f59142..2396b013 100644 --- a/src/shell/shell_inc.h +++ b/src/shell/shell_inc.h @@ -40,10 +40,6 @@ public: bool ReadLine(char * line); bool Goto(char * where); Bit16u file_handle; - Bit32u line_count; - char * cmd_words[CMD_MAXCMDS]; - char cmd_buffer[128]; //Command line can only be 128 chars - Bit32u cmd_count; bool echo; DOS_Shell * shell; BatchFile * prev; From bbebcd02b9c5a1d0d06aaa95c5562e1ec8dae343 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 24 Oct 2002 22:29:59 +0000 Subject: [PATCH 0330/4131] Report correct number of mouse_buttons on status return in bx. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@407 --- src/ints/mouse.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 1501d7f8..ad3a084b 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -165,7 +165,7 @@ static Bitu INT33_Handler(void) { switch (reg_ax) { case 0x00: /* Reset Driver and Read Status */ reg_ax=0xffff; - reg_bx=0; + reg_bx=MOUSE_BUTTONS; mouse_reset(); Mouse_AutoLock(true); break; From 9ed0094a0e3b002a6770d831386a2ed4e963ee17 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 08:59:43 +0000 Subject: [PATCH 0331/4131] Allow reading from dma ports to get the current count. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@408 --- src/hardware/dma.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index beca518d..eb317d42 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -70,6 +70,32 @@ struct DMA_CONTROLLER { }; static DMA_CONTROLLER dma[2]; +static Bit8u read_dma(Bit32u port) { + /* only use first dma for now */ + DMA_CONTROLLER * cont=&dma[0]; + DMA_CHANNEL * chan=&cont->chan[port>>1]; + Bit8u ret; + switch (port) { + case 0x00:case 0x02:case 0x04:case 0x06: + if (cont->flipflop) { + ret=chan->current_address & 0xff; + } else { + ret=(chan->current_address>>8)&0xff; + } + cont->flipflop=!cont->flipflop; + case 0x01:case 0x03:case 0x05:case 0x07: + if (cont->flipflop) { + ret=(chan->current_count-1) & 0xff; + } else { + ret=((chan->current_count-1)>>8)&0xff; + } + cont->flipflop=!cont->flipflop; + break; + default: + LOG_WARN("DMA:Unhandled read from %d",port); + } + return ret; +} static void write_dma(Bit32u port,Bit8u val) { @@ -206,6 +232,7 @@ Bit16u DMA_16_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count) { void DMA_Init(Section* sec) { for (Bit32u i=0;i<0x10;i++) { IO_RegisterWriteHandler(i,write_dma,"DMA1"); + IO_RegisterReadHandler(i,read_dma,"DMA1"); } IO_RegisterWriteHandler(0x81,write_dma_page,"DMA Pages"); IO_RegisterWriteHandler(0x82,write_dma_page,"DMA Pages"); From 7d6603d275d052c2e85d894c1ffd8eabbe0e6903 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 10:48:08 +0000 Subject: [PATCH 0332/4131] Delete the commandline and psp opbject in destructor. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@409 --- include/programs.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/programs.h b/include/programs.h index 8a65ad1c..3ce261a7 100644 --- a/include/programs.h +++ b/include/programs.h @@ -32,7 +32,10 @@ void PROGRAMS_MakeFile(char * name,PROGRAMS_Main * main); class Program { public: Program(); - virtual ~Program(){} + virtual ~Program(){ + delete cmd; + delete psp; + } std::string temp_line; CommandLine * cmd; DOS_PSP * psp; From 174ed12a92c43ad4aca6d8da7e307622dc1ed298 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 25 Oct 2002 15:15:17 +0000 Subject: [PATCH 0333/4131] Added ShutDown call for debugger Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@410 --- src/gui/sdlmain.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index b9b75098..0cab3716 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -29,7 +29,7 @@ #include "pic.h" #include "timer.h" #include "setup.h" - +#include "debug.h" //#define DISABLE_JOYSTICK @@ -567,5 +567,9 @@ int main(int argc, char* argv[]) { LOG_ERROR("Exit to error: %s",error); fgetc(stdin); } +#if C_DEBUG + DEBUG_ShutDown(); +#endif + return 0; }; From ac29b409193a4cbbd6cd5c779417ef347549a11b Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 25 Oct 2002 15:15:42 +0000 Subject: [PATCH 0334/4131] Changes for new debugger functionalities: starting/stepping into INTs. processor status log, step over rep instr., debug.com, heavy debugging switch Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@411 --- include/debug.h | 8 +- src/cpu/core_16/main.h | 6 +- src/cpu/cpu.cpp | 2 +- src/cpu/slow_16.cpp | 4 + src/debug/debug.cpp | 657 ++++++++++++++++++++++++++++------------ src/dos/dos_execute.cpp | 5 + src/dosbox.cpp | 3 + 7 files changed, 487 insertions(+), 198 deletions(-) diff --git a/include/debug.h b/include/debug.h index 300fa119..69438fa4 100644 --- a/include/debug.h +++ b/include/debug.h @@ -17,9 +17,15 @@ */ void DEBUG_DrawScreen(void); -bool DEBUG_BreakPoint(void); +bool DEBUG_Breakpoint(void); bool DEBUG_IntBreakpoint(Bit8u intNum); void DEBUG_Enable(void); +void DEBUG_CheckExecuteBreakpoint(Bit16u seg, Bit32u off); +bool DEBUG_ExitLoop(void); +void DEBUG_ShutDown(void); extern Bitu cycle_count; +#ifdef C_HEAVY_DEBUG +bool DEBUG_HeavyIsBreakpoint(); +#endif diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index e103276f..9ce64162 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -880,7 +880,7 @@ restart: case 0xcc: /* INT3 */ INTERRUPT(3); #if C_DEBUG - return 0; + return 1; #endif break; case 0xcd: /* INT Ib */ @@ -888,7 +888,7 @@ restart: Bit8u num=Fetchb(); #if C_DEBUG SAVEIP; - if (DEBUG_IntBreakpoint(num)) return 0; + if (DEBUG_IntBreakpoint(num)) return 1; #endif INTERRUPT(num); } @@ -1079,7 +1079,7 @@ restart: goto reploop; #ifdef CPU_386 case 0x66: - Rep_66(direct,from,to); + Rep_66(direct,from,to,repcheck); break; #endif diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 96e00840..51090e1c 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -83,7 +83,7 @@ void Interrupt(Bit8u num) { E_Exit("Call to interrupt 0xCD this is BAD"); case 0x03: #if C_DEBUG - if (DEBUG_BreakPoint()) return; + if (DEBUG_Breakpoint()) return; #endif break; case 0x05: diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp index 1f4a613d..0bf3d76d 100644 --- a/src/cpu/slow_16.cpp +++ b/src/cpu/slow_16.cpp @@ -67,6 +67,10 @@ static Bitu CPU_Real_16_Slow_Decode(Bits count) { do { #if C_DEBUG cycle_count++; +#endif +#if C_HEAVY_DEBUG + SAVEIP; + if (DEBUG_HeavyIsBreakpoint()) return CBRET_NONE; #endif #include "core_16/main.h" } while (--count>0); diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index f111318c..e94e5cdb 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,9 +16,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "programs.h" #include #include +#include #include "dosbox.h" #if C_DEBUG @@ -32,16 +34,27 @@ #include "inout.h" #include "mixer.h" #include "debug_inc.h" +#include "timer.h" +#include "..\shell\shell_inc.h" #ifdef WIN32 void WIN32_Console(); #endif +// Forwards +static void DrawCode(void); +static bool DEBUG_Log_Loop(int count); +static void DEBUG_RaiseTimerIrq(void); +class DEBUG; + +DEBUG* pDebugcom = 0; +bool exitLoop = false; + static struct { Bit32u eax,ebx,ecx,edx,esi,edi,ebp,esp,eip; } oldregs; -static void DrawCode(void); + static Segment oldsegs[6]; static Flag_Info oldflags; @@ -77,127 +90,313 @@ static Bit16u dataSeg,dataOfs; /* Breakpoint stuff */ /********************/ -enum { BKPNT_REALMODE, BKPNT_PHYSICAL, BKPNT_INTERRUPT }; +bool skipFirstInstruction = false; + +enum EBreakpoint { BKPNT_UNKNOWN, BKPNT_PHYSICAL, BKPNT_INTERRUPT }; #define BPINT_ALL 0x100 -typedef struct SBreakPoint { - PhysPt location; - Bit8u olddata; - Bit8u type; - Bit16u ahValue; - Bit16u segment; - Bit32u offset; - bool once; - bool enabled; - bool active; -} TBreakpoint; - -static std::list BPoints; - -static bool IsBreakpoint(PhysPt off) +class CBreakpoint { - // iterate list and remove TBreakpoint - std::list::iterator i; - for(i=BPoints.begin(); i != BPoints.end(); i++) { - if (((*i).type==BKPNT_PHYSICAL) && ((*i).location==off)) return true; - } - return false; +public: + CBreakpoint (void) { location = 0; active = once = false; segment = 0; offset = 0; intNr = 0; ahValue = 0; type = BKPNT_UNKNOWN; }; + + void SetAddress (Bit16u seg, Bit32u off) { location = PhysMake(seg,off); type = BKPNT_PHYSICAL; segment = seg; offset = off; }; + void SetAddress (PhysPt adr) { location = adr; type = BKPNT_PHYSICAL; }; + void SetInt (Bit8u _intNr, Bit16u ah) { intNr = _intNr, ahValue = ah; type = BKPNT_INTERRUPT; }; + void SetOnce (bool _once) { once = _once; }; + + bool IsActive (void) { return active; }; + void Activate (bool _active); + + EBreakpoint GetType (void) { return type; }; + bool GetOnce (void) { return once; }; + PhysPt GetLocation (void) { if (GetType()==BKPNT_PHYSICAL) return location; else return 0; }; + Bit16u GetSegment (void) { return segment; }; + Bit32u GetOffset (void) { return offset; }; + Bit8u GetIntNr (void) { if (GetType()==BKPNT_INTERRUPT) return intNr; else return 0; }; + Bit16u GetValue (void) { if (GetType()==BKPNT_INTERRUPT) return ahValue; else return 0; }; + + // statics + static CBreakpoint* AddBreakpoint (Bit16u seg, Bit32u off, bool once); + static CBreakpoint* AddIntBreakpoint (Bit8u intNum, Bit16u ah, bool once); + static void ActivateBreakpoints (PhysPt adr, bool activate); + static bool CheckBreakpoint (PhysPt adr); + static bool CheckIntBreakpoint (PhysPt adr, Bit8u intNr, Bit16u ahValue); + static bool IsBreakpoint (PhysPt where); + static bool IsBreakpointDrawn (PhysPt where); + static bool DeleteBreakpoint (PhysPt where); + static bool DeleteByIndex (Bit16u index); + static void DeleteAll (void); + static void ShowList (void); + + +private: + EBreakpoint type; + // Physical + PhysPt location; + Bit8u oldData; + Bit16u segment; + Bit32u offset; + // Int + Bit8u intNr; + Bit16u ahValue; + // Shared + bool active; + bool once; + + static std::list BPoints; + static CBreakpoint* ignoreOnce; }; -/* This clears all breakpoints by replacing their 0xcc by the original byte */ -static void ClearBreakpoints(void) +void CBreakpoint::Activate(bool _active) { - // iterate list and place 0xCC - std::list::iterator i; - for(i=BPoints.begin(); i != BPoints.end(); i++) { - if (((*i).type==BKPNT_PHYSICAL) && (*i).active) { - if (mem_readb((*i).location)==0xCC) mem_writeb((*i).location,(*i).olddata); - (*i).active = false; - }; - } -} - -static void DeleteBreakpoint(PhysPt off) -{ - // iterate list and place 0xCC - std::list::iterator i; - for(i=BPoints.begin(); i != BPoints.end(); i++) { - if (((*i).type==BKPNT_PHYSICAL) && (off==(*i).location)) { - if ((*i).active && (mem_readb((*i).location)==0xCC)) mem_writeb((*i).location,(*i).olddata); - (BPoints.erase)(i); - break; - }; - } -} - -static void SetBreakpoints(void) -{ - // iterate list and place 0xCC - std::list::iterator i; - for(i=BPoints.begin(); i != BPoints.end(); i++) { - if (((*i).type==BKPNT_PHYSICAL) && (*i).enabled) { - Bit8u data = mem_readb((*i).location); + if (GetType()==BKPNT_PHYSICAL) { +#if !C_HEAVY_DEBUG + if (_active) { + // Set 0xCC and save old value + Bit8u data = mem_readb(location); if (data!=0xCC) { - (*i).olddata = data; - (*i).active = true; - mem_writeb((*i).location,0xCC); - } - }; + oldData = data; + mem_writeb(location,0xCC); + }; + } else { + // Remove 0xCC and set old value + if (mem_readb (location)==0xCC) { + mem_writeb(location,oldData); + }; + } +#endif } -} - -static void AddBreakpoint(Bit16u seg, Bit32u ofs, bool once) -{ - TBreakpoint bp; - bp.type = BKPNT_PHYSICAL; - bp.enabled = true; - bp.active = false; - bp.location = PhysMake(seg,ofs); - bp.segment = seg; - bp.offset = ofs; - bp.once = once; - BPoints.push_front(bp); -} - -static void AddIntBreakpoint(Bit8u intNum, Bit16u ah, bool once) -{ - TBreakpoint bp; - bp.type = BKPNT_INTERRUPT; - bp.olddata = intNum; - bp.ahValue = ah; - bp.enabled = true; - bp.active = true; - bp.once = once; - BPoints.push_front(bp); + active = _active; }; -static bool RemoveBreakpoint(PhysPt off) +// Statics +std::list CBreakpoint::BPoints; +CBreakpoint* CBreakpoint::ignoreOnce = 0; + +CBreakpoint* CBreakpoint::AddBreakpoint(Bit16u seg, Bit32u off, bool once) { - // iterate list and remove TBreakpoint - std::list::iterator i; + CBreakpoint* bp = new CBreakpoint(); + bp->SetAddress (seg,off); + bp->SetOnce (once); + BPoints.push_front (bp); + return bp; +}; + +CBreakpoint* CBreakpoint::AddIntBreakpoint(Bit8u intNum, Bit16u ah, bool once) +{ + CBreakpoint* bp = new CBreakpoint(); + bp->SetInt (intNum,ah); + bp->SetOnce (once); + BPoints.push_front (bp); + return bp; +}; + +void CBreakpoint::ActivateBreakpoints(PhysPt adr, bool activate) +{ + ignoreOnce = 0; + // activate all breakpoints + std::list::iterator i; + CBreakpoint* bp; for(i=BPoints.begin(); i != BPoints.end(); i++) { - if (((*i).type==BKPNT_PHYSICAL) && ((*i).location==off)) { - TBreakpoint* bp = &(*i); - if ((*i).active && (mem_readb((*i).location)==0xCC)) mem_writeb((*i).location,(*i).olddata); - (*i).active = false; - if ((*i).once) (BPoints.erase)(i); - + bp = static_cast(*i); + // Do not activate, when bp is an actual adress + if (activate && (bp->GetType()==BKPNT_PHYSICAL) && (bp->GetLocation()==adr)) { + ignoreOnce = bp; + continue; + } + bp->Activate(activate); + }; +}; + +bool CBreakpoint::CheckBreakpoint(PhysPt adr) +// Checks if breakpoint is valid an should stop execution +{ + // if breakpoint is same address as started, it's not valid... + if (ignoreOnce) { + ignoreOnce->Activate(true); + ignoreOnce = 0; + } + // Search matching breakpoint + std::list::iterator i; + CBreakpoint* bp; + for(i=BPoints.begin(); i != BPoints.end(); i++) { + bp = static_cast(*i); + if ((bp->GetType()==BKPNT_PHYSICAL) && bp->IsActive() && (bp->GetLocation()==adr)) { + // Found, + if (bp->GetOnce()) { + // delete it, if it should only be used once + (BPoints.erase)(i); + bp->Activate(false); + delete bp; + } return true; }; - } + }; return false; }; +bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue) +// Checks if interrupt breakpoint is valid an should stop execution +{ + // if breakpoint is same address as started, it's not valid... + if (ignoreOnce) { + ignoreOnce->Activate(true); + ignoreOnce = 0; + } + // Search matching breakpoint + std::list::iterator i; + CBreakpoint* bp; + for(i=BPoints.begin(); i != BPoints.end(); i++) { + bp = static_cast(*i); + if ((bp->GetType()==BKPNT_INTERRUPT) && bp->IsActive() && (bp->GetIntNr()==intNr)) { + if ((bp->GetValue()==BPINT_ALL) || (bp->GetValue()==ahValue)) { + // Found + if (bp->GetOnce()) { + // delete it, if it should only be used once + (BPoints.erase)(i); + bp->Activate(false); + delete bp; + } + return true; + } + }; + }; + return false; +}; + +void CBreakpoint::DeleteAll() +{ + // Search matching breakpoint + CBreakpoint::ActivateBreakpoints(0,false); + (BPoints.clear)(); +}; + + +bool CBreakpoint::DeleteByIndex(Bit16u index) +{ + // Search matching breakpoint + int nr = 0; + std::list::iterator i; + CBreakpoint* bp; + for(i=BPoints.begin(); i != BPoints.end(); i++) { + if (nr==index) { + bp = static_cast(*i); + (BPoints.erase)(i); + bp->Activate(false); + delete bp; + return true; + } + }; + return false; +}; + +bool CBreakpoint::DeleteBreakpoint(PhysPt where) +{ + // Search matching breakpoint + int nr = 0; + std::list::iterator i; + CBreakpoint* bp; + for(i=BPoints.begin(); i != BPoints.end(); i++) { + bp = static_cast(*i); + if ((bp->GetType()==BKPNT_PHYSICAL) && (bp->GetLocation()==where)) { + (BPoints.erase)(i); + bp->Activate(false); + delete bp; + return true; + } + }; + return false; +}; + +bool CBreakpoint::IsBreakpoint(PhysPt adr) +// is there a breakpoint at address ? +{ + // Search matching breakpoint + std::list::iterator i; + CBreakpoint* bp; + for(i=BPoints.begin(); i != BPoints.end(); i++) { + bp = static_cast(*i); + if ((bp->GetType()==BKPNT_PHYSICAL) && (bp->GetLocation()==adr)) { + return true; + }; + }; + return false; +}; + +bool CBreakpoint::IsBreakpointDrawn(PhysPt adr) +// valid breakpoint, that should be drawn ? +{ + // Search matching breakpoint + std::list::iterator i; + CBreakpoint* bp; + for(i=BPoints.begin(); i != BPoints.end(); i++) { + bp = static_cast(*i); + if ((bp->GetType()==BKPNT_PHYSICAL) && (bp->GetLocation()==adr)) { + // Only draw, if breakpoint is not only once, + return !bp->GetOnce(); + }; + }; + return false; +}; + +void CBreakpoint::ShowList(void) +{ + // iterate list + int nr = 0; + std::list::iterator i; + for(i=BPoints.begin(); i != BPoints.end(); i++) { + CBreakpoint* bp = static_cast(*i); + if (bp->GetType()==BKPNT_PHYSICAL) { + PhysPt adr = bp->GetLocation(); + + wprintw(dbg.win_out,"%02X. BP %04X:%04X\n",nr,bp->GetSegment(),bp->GetOffset); + nr++; + } else if (bp->GetType()==BKPNT_INTERRUPT) { + if (bp->GetValue()==BPINT_ALL) wprintw(dbg.win_out,"%02X. BPINT %02X\n",nr,bp->GetIntNr()); + else wprintw(dbg.win_out,"%02X. BPINT %02X AH=%02X\n",nr,bp->GetIntNr(),bp->GetValue()); + nr++; + }; + } + wrefresh(dbg.win_out); +}; + +bool DEBUG_Breakpoint(void) +{ + /* First get the phyiscal address and check for a set Breakpoint */ + PhysPt where=SegPhys(cs)+reg_eip-1; + if (!CBreakpoint::CheckBreakpoint(where)) return false; + // Found. Breakpoint is valid + reg_eip -= 1; + CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,false); // Deactivate all breakpoints + exitLoop = true; + DEBUG_Enable(); + return true; +}; + +bool DEBUG_IntBreakpoint(Bit8u intNum) +{ + /* First get the phyiscal address and check for a set Breakpoint */ + PhysPt where=SegPhys(cs)+reg_eip-2; + if (!CBreakpoint::CheckIntBreakpoint(where,intNum,reg_ah)) return false; + // Found. Breakpoint is valid + reg_eip -= 2; + CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,false); // Deactivate all breakpoints + exitLoop = true; + DEBUG_Enable(); + return true; +}; + static bool StepOver() { PhysPt start=Segs[cs].phys+reg_eip; char dline[200];Bitu size; size=DasmI386(dline, start, reg_eip, false); - if (strstr(dline,"call") || strstr(dline,"int")) { - AddBreakpoint (SegValue(cs),reg_eip+size, true); - SetBreakpoints(); + if (strstr(dline,"call") || strstr(dline,"int") || strstr(dline,"loop") || strstr(dline,"rep")) { + CBreakpoint::AddBreakpoint (SegValue(cs),reg_eip+size, true); + CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip, true); debugging=false; DrawCode(); DOSBOX_SetNormalLoop(); @@ -206,56 +405,13 @@ static bool StepOver() return false; }; -bool DEBUG_BreakPoint(void) { - /* First get the phyiscal address and check for a set TBreakpoint */ - PhysPt where=SegPhys(cs)+reg_eip-1; - bool found = false; - std::list::iterator i; - for(i=BPoints.begin(); i != BPoints.end(); ++i) { - if ((*i).active && (*i).enabled) { - if ((*i).location==where) { - found=true; - break; - } - } - } - if (!found) return false; - RemoveBreakpoint(where); - ClearBreakpoints(); - reg_eip -= 1; - DEBUG_Enable(); - return true; -} - -bool DEBUG_IntBreakpoint(Bit8u intNum) +bool DEBUG_ExitLoop(void) { - PhysPt where=SegPhys(cs)+reg_eip-2; - bool found=false; - std::list::iterator i; - for(i=BPoints.begin(); i != BPoints.end(); ++i) { - if ( ((*i).type==BKPNT_INTERRUPT) && (*i).enabled) { - if (((*i).olddata==intNum) && ( ((*i).ahValue==(Bit16u)reg_ah) || ((*i).ahValue==BPINT_ALL)) ) { - if ((*i).active) { - found=true; - (*i).active=false; - //(BPoints.erase)(i); - //break; - } else { - // One step over is ok -> activate for next occurence - (*i).active=true; - //break; - } - } - } + if (exitLoop) { + exitLoop = false; + return true; } - if (!found) return false; - - // Remove normal breakpoint here, cos otherwise 0xCC wont be removed here - RemoveBreakpoint(where); - ClearBreakpoints(); - reg_eip -= 2; - DEBUG_Enable(); - return true; + return false; }; /********************/ @@ -338,7 +494,7 @@ static void DrawCode(void) wattrset(dbg.win_code,COLOR_PAIR(PAIR_BLACK_GREY)); codeViewData.cursorSeg = codeViewData.useCS; codeViewData.cursorOfs = disEIP; - } else if (IsBreakpoint(start)) { + } else if (CBreakpoint::IsBreakpointDrawn(start)) { wattrset(dbg.win_code,COLOR_PAIR(PAIR_GREY_RED)); } else { wattrset(dbg.win_code,0); @@ -440,7 +596,7 @@ bool ParseCommand(char* str) found+=3; Bit16u seg = GetHexValue(found,found);found++; // skip ":" Bit32u ofs = GetHexValue(found,found); - AddBreakpoint(seg,ofs,false); + CBreakpoint::AddBreakpoint(seg,ofs,false); LOG_DEBUG("DEBUG: Set breakpoint at %04X:%04X",seg,ofs); return true; } @@ -450,10 +606,10 @@ bool ParseCommand(char* str) Bit8u intNr = GetHexValue(found,found); found++; Bit8u valAH = GetHexValue(found,found); if ((valAH==0x00) && (*found=='*')) { - AddIntBreakpoint(intNr,BPINT_ALL,false); + CBreakpoint::AddIntBreakpoint(intNr,BPINT_ALL,false); LOG_DEBUG("DEBUG: Set interrupt breakpoint at INT %02X",intNr); } else { - AddIntBreakpoint(intNr,valAH,false); + CBreakpoint::AddIntBreakpoint(intNr,valAH,false); LOG_DEBUG("DEBUG: Set interrupt breakpoint at INT %02X AH=%02X",intNr,valAH); } return true; @@ -463,19 +619,7 @@ bool ParseCommand(char* str) wprintw(dbg.win_out,"Breakpoint list:\n"); wprintw(dbg.win_out,"-------------------------------------------------------------------------\n"); Bit32u nr = 0; - // iterate list - std::list::iterator i; - for(i=BPoints.begin(); i != BPoints.end(); i++) { - if ((*i).type==BKPNT_PHYSICAL) { - wprintw(dbg.win_out,"%02X. BP %04X:%04X\n",nr,(*i).segment,(*i).offset); - nr++; - } else if ((*i).type==BKPNT_INTERRUPT) { - if ((*i).ahValue==BPINT_ALL) wprintw(dbg.win_out,"%02X. BPINT %02X\n",nr,(*i).olddata); - else wprintw(dbg.win_out,"%02X. BPINT %02X AH=%02X\n",nr,(*i).olddata,(*i).ahValue); - nr++; - }; - } - wrefresh(dbg.win_out); + CBreakpoint::ShowList(); return true; }; @@ -484,29 +628,11 @@ bool ParseCommand(char* str) found+=5; Bit8u bpNr = GetHexValue(found,found); if ((bpNr==0x00) && (*found=='*')) { // Delete all - (BPoints.clear)(); + CBreakpoint::DeleteAll(); LOG_DEBUG("DEBUG: Breakpoints deleted."); } else { // delete single breakpoint - Bit16u nr = 0; - std::list::iterator i; - for(i=BPoints.begin(); i != BPoints.end(); i++) { - if ((*i).type==BKPNT_PHYSICAL) { - if (nr==bpNr) { - DeleteBreakpoint((*i).location); - LOG_DEBUG("DEBUG: Breakpoint %02X deleted.",nr); - break; - } - nr++; - } else if ((*i).type==BKPNT_INTERRUPT) { - if (nr==bpNr) { - (BPoints.erase)(i); - LOG_DEBUG("DEBUG: Breakpoint %02X. deleted.",nr); - break;; - } - nr++; - } - } + CBreakpoint::DeleteByIndex(bpNr); } return true; } @@ -528,6 +654,36 @@ bool ParseCommand(char* str) LOG_DEBUG("DEBUG: Set data overview to %04X:%04X",dataSeg,dataOfs); return true; } + found = strstr(str,"LOG "); + if (found) { // Create Cpu log file + found+=4; + LOG_DEBUG("DEBUG: Starting log"); + DEBUG_Log_Loop(GetHexValue(found,found)); + LOG_DEBUG("DEBUG: Logfile LOGCPU.TXT created."); + return true; + } + found = strstr(str,"INTT "); + if (found) { // Create Cpu log file + found+=4; + Bit8u intNr = GetHexValue(found,found); + LOG_DEBUG("DEBUG: Tracing INT %02X",intNr); + Interrupt(intNr); + SetCodeWinStart(); + return true; + } + found = strstr(str,"INT "); + if (found) { // Create Cpu log file + found+=4; + Bit8u intNr = GetHexValue(found,found); + LOG_DEBUG("DEBUG: Starting INT %02X",intNr); + CBreakpoint::AddBreakpoint (SegValue(cs),reg_eip, true); + CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip-1,true); + debugging=false; + DrawCode(); + DOSBOX_SetNormalLoop(); + Interrupt(intNr); + return true; + } if ((*str=='H') || (*str=='?')) { wprintw(dbg.win_out,"Debugger keys:\n"); wprintw(dbg.win_out,"--------------------------------------------------------------------------\n"); @@ -538,7 +694,6 @@ bool ParseCommand(char* str) wprintw(dbg.win_out,"Return - Enable command line input\n"); wprintw(dbg.win_out,"D/E/S/X/B - Set data view to DS:SI/ES:DI/SS:SP/DS:DX/ES:BX\n"); wprintw(dbg.win_out,"R/F - Scroll data view\n"); - wprintw(dbg.win_out,"\n"); wprintw(dbg.win_out,"Debugger commands (enter all values in hex or as register):\n"); wprintw(dbg.win_out,"--------------------------------------------------------------------------\n"); wprintw(dbg.win_out,"BP [segment]:[offset] - Set breakpoint\n"); @@ -547,6 +702,8 @@ bool ParseCommand(char* str) wprintw(dbg.win_out,"BPLIST - List breakpoints\n"); wprintw(dbg.win_out,"BPDEL [bpNr] / * - Delete breakpoint nr / all\n"); wprintw(dbg.win_out,"C / D [segment]:[offset] - Set code / data view address\n"); + wprintw(dbg.win_out,"INT [nr] / INTT [nr] - Execute / Trace into Iinterrupt\n"); + wprintw(dbg.win_out,"LOG [num] - Write cpu log file\n"); wprintw(dbg.win_out,"H - Help\n"); wrefresh(dbg.win_out); return TRUE; @@ -621,6 +778,9 @@ Bit32u DEBUG_CheckKeys(void) { case 'H' : strcpy(codeViewData.inputStr,"H "); ParseCommand(codeViewData.inputStr); break; + case 'T' : DEBUG_RaiseTimerIrq(); + LOG_DEBUG("Debug: Timer Int started."); + break; case 0x0A : // Return : input codeViewData.inputMode = true; @@ -636,23 +796,25 @@ Bit32u DEBUG_CheckKeys(void) { break; case KEY_F(5): // Run Programm debugging=false; - SetBreakpoints(); + CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); DOSBOX_SetNormalLoop(); break; case KEY_F(9): // Set/Remove TBreakpoint { PhysPt ptr = PhysMake(codeViewData.cursorSeg,codeViewData.cursorOfs); - if (IsBreakpoint(ptr)) DeleteBreakpoint(ptr); - else AddBreakpoint(codeViewData.cursorSeg, codeViewData.cursorOfs, false); + if (CBreakpoint::IsBreakpoint(ptr)) CBreakpoint::DeleteBreakpoint(ptr); + else CBreakpoint::AddBreakpoint(codeViewData.cursorSeg, codeViewData.cursorOfs, false); } break; case KEY_F(10): // Step over inst if (StepOver()) return 0; else { + skipFirstInstruction = true; // for heavy debugger Bitu ret=(*cpudecoder)(1); SetCodeWinStart(); } break; case KEY_F(11): // trace into + skipFirstInstruction = true; // for heavy debugger ret = (*cpudecoder)(1); SetCodeWinStart(); break; @@ -675,8 +837,8 @@ Bitu DEBUG_Loop(void) { Bit32u oldEIP = reg_eip; PIC_runIRQs(); if ((oldCS!=SegValue(cs)) || (oldEIP!=reg_eip)) { - AddBreakpoint(oldCS,oldEIP,true); - SetBreakpoints(); + CBreakpoint::AddBreakpoint(oldCS,oldEIP,true); + CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); debugging=false; DOSBOX_SetNormalLoop(); return 0; @@ -686,13 +848,13 @@ Bitu DEBUG_Loop(void) { } void DEBUG_Enable(void) { + debugging=true; SetCodeWinStart(); DEBUG_DrawScreen(); DOSBOX_SetLoop(&DEBUG_Loop); } - void DEBUG_DrawScreen(void) { DrawRegisters(); DrawData(); @@ -702,11 +864,92 @@ static void DEBUG_RaiseTimerIrq(void) { PIC_ActivateIRQ(0); } +static bool DEBUG_Log_Loop(int count) { + + char buffer[512]; + getcwd(buffer,512); + + FILE* f = fopen("LOGCPU.TXT","wt"); + if (!f) return false; + + do { +// PIC_runIRQs(); + + Bitu ret; + do { + // Get disasm + Bit16u csValue = SegValue(cs); + Bit32u eipValue = reg_eip; + PhysPt start=Segs[cs].phys+reg_eip; + char dline[200];Bitu size; + size = DasmI386(dline, start, reg_eip, false); + Bitu len = strlen(dline); + if (len<30) for (Bitu i=0; i<30-len; i++) strcat(dline," "); + + PIC_IRQAgain=false; + ret=(*cpudecoder)(1); + + // Get register values + char buffer[512]; + sprintf(buffer,"%04X:%08X %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X\n",csValue,eipValue,dline,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss),get_CF(),get_ZF(),get_SF(),get_OF(),get_AF(),get_PF()); + fprintf(f,"%s",buffer); + count--; + if (count==0) break; + + } while (!ret && PIC_IRQAgain); + if (ret) break; + } while (count>0); + + fclose(f); + return true; +} + +// DEBUG.COM stuff + +class DEBUG : public Program { +public: + DEBUG() { pDebugcom = this; active = false; }; + ~DEBUG() { pDebugcom = 0; }; + + bool IsActive() { return active; }; + + void Run(void) + { + char filename[128]; + char args[128]; + cmd->FindCommand(1,temp_line); + strncpy(filename,temp_line.c_str(),128); + cmd->FindCommand(2,temp_line); + strncpy(args,temp_line.c_str(),128); + // Start new shell and execute prog + active = true; + DOS_Shell shell; + shell.Execute(filename,args); + }; + +private: + bool active; +}; + +void DEBUG_CheckExecuteBreakpoint(Bit16u seg, Bit32u off) +{ + if (pDebugcom && pDebugcom->IsActive()) { + CBreakpoint::AddBreakpoint(seg,off,true); + CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); + pDebugcom = 0; + }; +}; + +static void DEBUG_ProgramStart(Program * * make) { + *make=new DEBUG; +} + +// INIT + void DEBUG_Init(Section* sec) { #ifdef WIN32 WIN32_Console(); #endif - MSG_Add("DEBUG_CONFIGFILE_HELP","Nothing to setup yet!\n"); memset((void *)&dbg,0,sizeof(dbg)); debugging=false; dbg.active_win=3; @@ -719,8 +962,36 @@ void DEBUG_Init(Section* sec) { KEYBOARD_AddEvent(KBD_kpplus,0,DEBUG_RaiseTimerIrq); /* Clear the TBreakpoint list */ memset((void*)&codeViewData,0,sizeof(codeViewData)); - (BPoints.clear)(); + /* setup debug.com */ + PROGRAMS_MakeFile("DEBUG.COM",DEBUG_ProgramStart); } -#endif +void DEBUG_ShutDown() +{ + CBreakpoint::DeleteAll(); +}; + +// HEAVY DEBUGGING STUFF + +#if C_HEAVY_DEBUG + +bool DEBUG_HeavyIsBreakpoint(void) +{ + if (skipFirstInstruction) { + skipFirstInstruction = false; + return false; + } + + PhysPt where = SegPhys(cs)+reg_eip; + if (CBreakpoint::CheckBreakpoint(where)) { + exitLoop = true; + DEBUG_Enable(); + return true; + }; + return false; +}; + +#endif // HEAVY DEBUG + +#endif // DEBUG diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 21748dc2..5f51e248 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -22,6 +22,7 @@ #include "dos_inc.h" #include "cpu.h" #include "callback.h" +#include "debug.h" #pragma pack(1) struct EXE_Header { @@ -327,6 +328,10 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { reg_ax=0; reg_cx=reg_dx=reg_bx=reg_si=reg_di=reg_bp=0; SegSet16(ds,pspseg);SegSet16(es,pspseg); +#if C_DEBUG + /* Started from debug.com, then set breakpoint at start */ + DEBUG_CheckExecuteBreakpoint(RealSeg(csip),RealOff(csip)); +#endif return true; } return false; diff --git a/src/dosbox.cpp b/src/dosbox.cpp index deed99d2..73950cc3 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -101,6 +101,9 @@ static Bitu Normal_Loop(void) { PIC_IRQAgain=false; ret=(*cpudecoder)(cpu_cycles); } while (!ret && PIC_IRQAgain); +#if C_DEBUG + if (DEBUG_ExitLoop()) return 0; +#endif return ret; } From 9f1a42a3b92b57a024964dbbd32829fe96a1b573 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 25 Oct 2002 15:17:19 +0000 Subject: [PATCH 0335/4131] Support for INT 21 function 0x57 - DOS_GetFileDate Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@412 --- include/dos_inc.h | 1 + src/dos/dos.cpp | 14 +++++++++++--- src/dos/dos_files.cpp | 26 ++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 1fb88330..be86aea8 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -98,6 +98,7 @@ bool DOS_SeekFile(Bit16u handle,Bit32u * pos,Bit32u type); bool DOS_CloseFile(Bit16u handle); 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 */ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 13c66fd7..a1895934 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -670,9 +670,17 @@ static Bitu DOS_21Handler(void) { } break; case 0x57: /* Get/Set File's Date and Time */ - reg_cx=0; - reg_dx=0; - LOG_DEBUG("DOS:57:Getting/Setting File Date is faked",reg_ah); + if (reg_al==0x00) { + if (DOS_GetFileDate(reg_bx,®_cx,®_dx)) { + CALLBACK_SCF(false); + } else { + CALLBACK_SCF(true); + }; + } else { + reg_cx=0; + reg_dx=0; + LOG_DEBUG("DOS:57:Setting File Date is faked",reg_ah); + } break; case 0x58: /* Get/Set Memory allocation strategy */ switch (reg_al) { diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 3b9a93cf..4949fa45 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -816,6 +816,32 @@ bool DOS_SetDrive(Bit8u drive) { } }; +bool DOS_GetFileDate(Bit16u entry, Bit16u* otime, Bit16u* odate) +{ + Bit32u handle=RealHandle(entry); + if (handle>=DOS_FILES) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; + if (!Files[handle]) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; + struct stat stat_block; + if (fstat(handle, &stat_block)!=0) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + } + struct tm *time; + if ((time=localtime(&stat_block.st_mtime))!=0) { + *otime = (time->tm_hour<<11)+(time->tm_min<<5)+(time->tm_sec/2); /* standard way. */ + *odate = ((time->tm_year-80)<<9)+((time->tm_mon+1)<<5)+(time->tm_mday); + } else { + *otime = 6; + *odate = 4; + } + return true; +}; void DOS_SetupFiles (void) { /* Setup the File Handles */ From c92a62421203c3ac5ba8384e4c0dbbbf92af9e0b Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 25 Oct 2002 15:19:27 +0000 Subject: [PATCH 0336/4131] Heavy Debug switch for debugger added Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@413 --- settings.h.cvs | 1 + 1 file changed, 1 insertion(+) diff --git a/settings.h.cvs b/settings.h.cvs index 3eea7705..81f3ec27 100644 --- a/settings.h.cvs +++ b/settings.h.cvs @@ -21,6 +21,7 @@ /* Enable the debugger, this only seems to work in win32 for now. */ #define C_DEBUG 0 +#define C_HEAVY_DEBUG 0 /* Enable the logging of extra information for debugging to the console */ #define C_LOGGING 0 From 17a1974f6a500288091e684cf70629d8c350a442 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 25 Oct 2002 15:25:13 +0000 Subject: [PATCH 0337/4131] debugger changes/additions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@414 --- ChangeLog | 2 ++ src/cpu/core_16/main.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 51dbfd18..62de4472 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,8 @@ - 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) 0.55 - fixed the errors/warnings in prefix_66.h and prefix_66_of.h (decimal too large becomming unsigned). diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 9ce64162..e4133b21 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -1079,7 +1079,7 @@ restart: goto reploop; #ifdef CPU_386 case 0x66: - Rep_66(direct,from,to,repcheck); + Rep_66(direct,from,to); break; #endif From a18cdd138722f2fd9d5e3bec9dc1fd3d2c806399 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 15:38:45 +0000 Subject: [PATCH 0338/4131] Some undocumented features for findfirst/findnext and new dos_ioctl call. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@415 --- src/dos/dos.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index a1895934..35533f65 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -40,7 +40,6 @@ void DOS_SetError(Bit16u code) { #define DOSNAMEBUF 256 static Bitu DOS_21Handler(void) { -//TODO KEYBOARD Check for break char name1[DOSNAMEBUF+1]; char name2[DOSNAMEBUF+1]; switch (reg_ah) { @@ -460,7 +459,7 @@ static Bitu DOS_21Handler(void) { case 0x3f: /* READ Read from file or device */ { Bit16u toread=reg_cx; - if (reg_cx+reg_dx>0xffff) LOG_DEBUG("DOS:READ:Buffer overflow"); + if (reg_cx+reg_dx>0xffff) LOG_DEBUG("DOS:READ:Buffer overflow %d",reg_cx+reg_dx); if (DOS_ReadFile(reg_bx,dos_copybuf,&toread)) { MEM_BlockWrite(SegPhys(ds)+reg_dx,dos_copybuf,toread); reg_ax=toread; @@ -474,7 +473,7 @@ static Bitu DOS_21Handler(void) { case 0x40: /* WRITE Write to file or device */ { Bit16u towrite=reg_cx; - if (reg_cx+reg_dx>0xffff) LOG_DEBUG("DOS:WRITE:Buffer overflow"); + if (reg_cx+reg_dx>0xffff) LOG_DEBUG("DOS:WRITE:Buffer overflow %d",reg_cx+reg_dx); MEM_BlockRead(SegPhys(ds)+reg_dx,dos_copybuf,towrite); if (DOS_WriteFile(reg_bx,dos_copybuf,&towrite)) { reg_ax=towrite; @@ -528,7 +527,7 @@ static Bitu DOS_21Handler(void) { } break; case 0x44: /* IOCTL Functions */ - if (DOS_IOCTL(reg_al,reg_bx)) { + if (DOS_IOCTL()) { CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; @@ -622,7 +621,8 @@ static Bitu DOS_21Handler(void) { case 0x4e: /* FINDFIRST Find first matching file */ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_FindFirst(name1,reg_cx)) { - CALLBACK_SCF(false); + CALLBACK_SCF(false); + reg_ax=0; /* Undocumented */ } else { reg_ax=dos.errorcode; CALLBACK_SCF(true); @@ -630,7 +630,8 @@ static Bitu DOS_21Handler(void) { break; case 0x4f: /* FINDNEXT Find next matching file */ if (DOS_FindNext()) { - CALLBACK_SCF(false); + CALLBACK_SCF(false); + reg_ax=0xffff; /* Undocumented */ } else { reg_ax=dos.errorcode; CALLBACK_SCF(true); From e6a9638b74d62a58e36a5dcedc8f2df19ad99453 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 15:39:34 +0000 Subject: [PATCH 0339/4131] Create temp file fixed and a little fix with a warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@416 --- src/dos/dos_files.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 4949fa45..99217e38 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -200,7 +200,7 @@ bool DOS_FindFirst(char * search,Bit16u attr) { strcpy(pattern,find_last+1); strcpy(dir,fullsearch); } - dta.SetupSearch(drive,attr | DOS_ATTR_ARCHIVE,pattern); + dta.SetupSearch(drive,(Bit8u)attr,pattern); if (Drives[drive]->FindFirst(dir,dta)) return true; DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; @@ -454,8 +454,7 @@ bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry) { bool DOS_CreateTempFile(char * name,Bit16u * entry) { - -/* First add random crap to the end of the name and try to open */ + /* First add random crap to the end of the name and try to open */ /* Todo maybe check for euhm existence of the path name */ char * tempname; tempname=name+strlen(name); @@ -468,7 +467,7 @@ bool DOS_CreateTempFile(char * name,Bit16u * entry) { for (i=9;i<12;i++) { tempname[i]=(rand()%26)+'A'; } - tempname[13]=0; + tempname[12]=0; } while (!DOS_CreateFile(name,0,entry)); return true; } From 8dd0a0f8cca76e70d649c467a520650fb0360cfc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 15:40:17 +0000 Subject: [PATCH 0340/4131] Added some logical drive map ioctl functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@417 --- src/dos/dos_ioctl.cpp | 75 +++++++++++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 24 deletions(-) diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 9b253521..f01b181b 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -26,16 +26,20 @@ #define MAX_DEVICE 20 static DOS_File * dos_devices[MAX_DEVICE]; -bool DOS_IOCTL(Bit8u call,Bit16u entry) { - Bit32u handle=RealHandle(entry); - if (handle>=DOS_FILES) { - DOS_SetError(DOSERR_INVALID_HANDLE); - return false; - }; - if (!Files[handle]) { - DOS_SetError(DOSERR_INVALID_HANDLE); - return false; - }; + +bool DOS_IOCTL(void) { + Bitu handle;Bit8u drive; + if (reg_al<8) { /* call 0-7 use a file handle */ + handle=RealHandle(reg_bx); + if (handle>=DOS_FILES) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + } + if (!Files[handle]) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + } + } switch(reg_al) { case 0x00: /* Get Device Information */ reg_dx=Files[handle]->GetInformation(); @@ -44,23 +48,46 @@ bool DOS_IOCTL(Bit8u call,Bit16u entry) { LOG_DEBUG("DOS:IOCTL:07:Fakes output status is ready for handle %d",handle); reg_al=0xff; return true; - case 0x0D: { - PhysPt ptr = SegPhys(ds)+reg_dx; - Bit8u drive = reg_bl ? reg_bl : DOS_GetDefaultDrive()+1; // A=1, B=2, C=3... - switch (reg_cl) { - case 0x60 : mem_writeb(ptr ,0x03); // special function - mem_writeb(ptr+1,(drive>=3)?0x05:0x14); // fixed disc(5), 1.44 floppy(14) - mem_writew(ptr+2,drive>=3); // nonremovable ? - mem_writew(ptr+4,0x0000); // num of cylinders - mem_writeb(ptr+6,0x00); // media type (00=other type) - break; - default : LOG_ERROR("DOS:IOCTL Call 0D:%2X Drive %2X unhandled",reg_cl,drive); - return false; + case 0x08: /* Check if block device removable */ + drive=reg_bl;if (!drive) drive=dos.current_drive;else drive--; + if (Drives[drive]) { + if (drive<2) reg_ax=0; /* Drive a,b are removable if mounted */ + else reg_ax=1; + return true; + } else { + DOS_SetError(DOSERR_INVALID_DRIVE); + return false; } - return true; + case 0x0D: /* Generic block device request */ + { + PhysPt ptr = SegPhys(ds)+reg_dx; + drive=reg_bl;if (!drive) drive=dos.current_drive;else drive--; + switch (reg_cl) { + case 0x60: /* Get Device parameters */ + mem_writeb(ptr ,0x03); // special function + mem_writeb(ptr+1,(drive>=2)?0x05:0x14); // fixed disc(5), 1.44 floppy(14) + mem_writew(ptr+2,drive>=2); // nonremovable ? + mem_writew(ptr+4,0x0000); // num of cylinders + mem_writeb(ptr+6,0x00); // media type (00=other type) + break; + default : + LOG_ERROR("DOS:IOCTL Call 0D:%2X Drive %2X unhandled",reg_cl,drive); + return false; + } + return true; } + case 0xE: /* Get Logical Drive Map */ + drive=reg_bl;if (!drive) drive=dos.current_drive;else drive--; + if (Drives[drive]) { + reg_al=0; /* Only 1 logical drive assigned */ + return true; + } else { + DOS_SetError(DOSERR_INVALID_DRIVE); + return false; + } + break; default: - LOG_ERROR("DOS:IOCTL Call %2X Handle %2X unhandled",reg_al,handle); + LOG_ERROR("DOS:IOCTL Call %2X unhandled",reg_al); return false; }; return false; From f5103f9c94144195892f27cd8807fbe8a6f90f67 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 15:40:55 +0000 Subject: [PATCH 0341/4131] New IOCTL Call. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@418 --- include/dos_inc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index be86aea8..48bc6aba 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -123,7 +123,7 @@ bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit16u * sectors,Bit16u * c bool DOS_GetFileAttr(char * name,Bit16u * attr); /* IOCTL Stuff */ -bool DOS_IOCTL(Bit8u call,Bit16u entry); +bool DOS_IOCTL(void); bool DOS_GetSTDINStatus(); Bit8u DOS_FindDevice(char * name); void DOS_SetupDevices(void); From 14577b3324edb1b451da37edd942e9835b37afee Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 15:47:55 +0000 Subject: [PATCH 0342/4131] Auto unlocking of the mouse on exit. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@419 --- src/gui/sdlmain.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 0cab3716..0f864025 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -222,11 +222,10 @@ void GFX_Start() { sdl.active=true; } - static void GUI_ShutDown(Section * sec) { GFX_Stop(); + if (sdl.mouse.locked) CaptureMouse(); if (sdl.full_screen) SwitchFullScreen(); - } static void GUI_StartUp(Section * sec) { @@ -238,7 +237,6 @@ static void GUI_StartUp(Section * sec) { sdl.frames.skip=0; sdl.frames.count=0; sdl.draw=0; - sdl.mouse.locked=false; sdl.mouse.requestlock=false; sdl.mouse.autoenable=section->Get_bool("autolock"); From b4dd2c93ca2ae2fc6b3a6f13849f6c993f7a6dd2 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 25 Oct 2002 16:02:55 +0000 Subject: [PATCH 0343/4131] seperate debugger console setup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@420 --- include/debug.h | 1 + src/debug/debug.cpp | 9 +++++++-- src/gui/sdlmain.cpp | 5 +++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/include/debug.h b/include/debug.h index 69438fa4..d18259bb 100644 --- a/include/debug.h +++ b/include/debug.h @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +void DEBUG_SetupConsole(void); void DEBUG_DrawScreen(void); bool DEBUG_Breakpoint(void); bool DEBUG_IntBreakpoint(Bit8u intNum); diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index e94e5cdb..3379bc9b 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -946,16 +946,21 @@ static void DEBUG_ProgramStart(Program * * make) { // INIT -void DEBUG_Init(Section* sec) { +void DEBUG_SetupConsole(void) +{ #ifdef WIN32 WIN32_Console(); - #endif + #endif memset((void *)&dbg,0,sizeof(dbg)); debugging=false; dbg.active_win=3; input_count=0; /* Start the Debug Gui */ DBGUI_StartUp(); +}; + +void DEBUG_Init(Section* sec) { + DEBUG_DrawScreen(); /* Add some keyhandlers */ KEYBOARD_AddEvent(KBD_kpminus,0,DEBUG_Enable); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 0f864025..c44e380f 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -518,6 +518,11 @@ void GFX_ShowMsg(char * msg) { }; int main(int argc, char* argv[]) { + +#if C_DEBUG + DEBUG_SetupConsole(); +#endif + try { CommandLine com_line(argc,argv); Config myconf(&com_line); From 2d6d76fb42333ba67add8146784df2031fd30441 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 25 Oct 2002 16:42:21 +0000 Subject: [PATCH 0344/4131] debug_shutdown method now registered in section and fixed a memleak. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@421 --- src/debug/debug.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 3379bc9b..998d2bac 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -268,8 +268,13 @@ bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue) void CBreakpoint::DeleteAll() { - // Search matching breakpoint - CBreakpoint::ActivateBreakpoints(0,false); + std::list::iterator i; + CBreakpoint* bp; + for(i=BPoints.begin(); i != BPoints.end(); i++) { + bp = static_cast(*i); + bp->Activate(false); + delete bp; + }; (BPoints.clear)(); }; @@ -959,6 +964,11 @@ void DEBUG_SetupConsole(void) DBGUI_StartUp(); }; +static void DEBUG_ShutDown(Section * sec) +{ + CBreakpoint::DeleteAll(); +}; + void DEBUG_Init(Section* sec) { DEBUG_DrawScreen(); @@ -969,13 +979,10 @@ void DEBUG_Init(Section* sec) { memset((void*)&codeViewData,0,sizeof(codeViewData)); /* setup debug.com */ PROGRAMS_MakeFile("DEBUG.COM",DEBUG_ProgramStart); + /* shutdown function */ + sec->AddDestroyFunction(&DEBUG_ShutDown); } -void DEBUG_ShutDown() -{ - CBreakpoint::DeleteAll(); -}; - // HEAVY DEBUGGING STUFF #if C_HEAVY_DEBUG From 26582bf90d364c0216fe4b71841c51b146d6b628 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 25 Oct 2002 16:42:43 +0000 Subject: [PATCH 0345/4131] debug_shutdown method now registered in section. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@422 --- include/debug.h | 1 - src/gui/sdlmain.cpp | 4 ---- 2 files changed, 5 deletions(-) diff --git a/include/debug.h b/include/debug.h index d18259bb..2dfa9c6d 100644 --- a/include/debug.h +++ b/include/debug.h @@ -23,7 +23,6 @@ bool DEBUG_IntBreakpoint(Bit8u intNum); void DEBUG_Enable(void); void DEBUG_CheckExecuteBreakpoint(Bit16u seg, Bit32u off); bool DEBUG_ExitLoop(void); -void DEBUG_ShutDown(void); extern Bitu cycle_count; diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index c44e380f..a7353328 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -570,9 +570,5 @@ int main(int argc, char* argv[]) { LOG_ERROR("Exit to error: %s",error); fgetc(stdin); } -#if C_DEBUG - DEBUG_ShutDown(); -#endif - return 0; }; From d7c9982f441ea53b2d0f21217c6a75cee4409776 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 19:53:32 +0000 Subject: [PATCH 0346/4131] Plugin support removed. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@423 --- src/misc/plugins.cpp | 159 ------------------------------------------- 1 file changed, 159 deletions(-) delete mode 100644 src/misc/plugins.cpp diff --git a/src/misc/plugins.cpp b/src/misc/plugins.cpp deleted file mode 100644 index 35cfe942..00000000 --- a/src/misc/plugins.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2002 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include - -#ifdef WIN32 -#include -#endif - -#include "dosbox.h" -#include "regs.h" -#include "mem.h" -#include "inout.h" -#include "pic.h" -#include "modules.h" -#include "programs.h" -#include "timer.h" -#include "dma.h" -#include "mixer.h" - - -struct PLUGIN_Function { - char * name; - void * function; -}; - -struct PLUGIN_Module { -#ifdef WIN32 - HINSTANCE handle; -#endif - - PLUGIN_Module * next; -}; - - -static PLUGIN_Function functions[]={ -"IO_RegisterReadHandler", (void *)IO_RegisterReadHandler, -"IO_RegisterWriteHandler", (void *)IO_RegisterWriteHandler, -"IO_FreeReadHandler", (void *)IO_FreeReadHandler, -"IO_FreeWriteHandler", (void *)IO_FreeWriteHandler, - -"IRQ_RegisterEOIHandler", (void *)PIC_RegisterIRQ, -"IRQ_FreeEOIHandler", (void *)PIC_FreeIRQ, -"IRQ_Activate", (void *)PIC_ActivateIRQ, -"IRQ_Deactivate", (void *)PIC_DeActivateIRQ, - -"TIMER_RegisterMicroHandler", (void *)TIMER_RegisterMicroHandler, -"TIMER_RegisterTickHandler", (void *)TIMER_RegisterTickHandler, - -"DMA_8_Read", (void *)DMA_8_Read, -"DMA_16_Read", (void *)DMA_16_Read, - -"DMA_8_Write", (void *)DMA_8_Write, -"DMA_16_Write", (void *)DMA_16_Write, - -"MIXER_AddChannel", (void *)MIXER_AddChannel, -"MIXER_SetVolume", (void *)MIXER_SetVolume, -"MIXER_SetFreq", (void *)MIXER_SetFreq, -"MIXER_SetMode", (void *)MIXER_SetMode, -"MIXER_Enable", (void *)MIXER_Enable, - -0,0 -}; - - -class PLUGIN : public Program { -public: - PLUGIN(PROGRAM_Info * program_info); - void Run(void); -}; - -PLUGIN::PLUGIN(PROGRAM_Info * info):Program(info) { - -} - - -void PLUGIN::Run(void) { - -} - - - -static void PLUGIN_ProgramStart(PROGRAM_Info * info) { - PLUGIN * tempPLUGIN=new PLUGIN(info); - tempPLUGIN->Run(); - delete tempPLUGIN; -} - - - -bool PLUGIN_FindFunction(char * name,void * * function) { -/* Run through table and hope to find a match */ - Bitu index=0; - while (functions[index].name) { - if (strcmp(functions[index].name,name)==0) { - *function=functions[index].function; - return true; - }; - index++; - } - return false; -} - - -bool PLUGIN_LoadModule(char * name) { - MODULE_StartHandler starter; - -#ifdef WIN32 - HMODULE module; - module=LoadLibrary(name); - if (!module) return false; -/* Look for the module start functions */ - FARPROC address; - address=GetProcAddress(module,MODULE_START_PROC); - starter=(MODULE_StartHandler)address; -#else -//TODO LINUX - - - - -#endif - starter(PLUGIN_FindFunction); -return false; - -} - - - -void PLUGIN_Init(void) { - PROGRAMS_MakeFile("PLUGIN.COM",PLUGIN_ProgramStart); -// PLUGIN_LoadModule("c:\\dosbox\\testmod.dll"); -}; - - - - - - - - - - From 89cff4d1d8b98a557f0e926f89c7eecd73db6afb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:20:35 +0000 Subject: [PATCH 0347/4131] Added some information for config Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@424 --- README | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README b/README index cf4d8cbf..7dbc7cc5 100644 --- a/README +++ b/README @@ -47,18 +47,19 @@ Program to display the amount of free memory CONFIG Utility for generating a configfile with the current settings and for generating the languagefile. +The option -writeconf filename is used to write the current config settings. +The option -writelang filename is used to write the current language strings. UPCASE Utility to convert all files subdirectories of a local directory into upcase so DOSBox can use that directory for mounting. This tool can be quite dangerous if used unproperly. You have been warned. - To get more information about how to use one these programs use the the /? command line switch. The Configfile: =============== -A configfile can be generated by CONFIG.COM. If you can edit it (it's plain text) to costumize DOSBox. -The file is devided in several sections (the names got [] around it). Some sections have options which you can set. +A configfile can be generated by CONFIG.COM. You can edit it to customize DOSBox. +The file is divided in several sections (the names got [] around it). Some sections have options which you can set. # and % indicate commentlines. The generated configfile contains the current settings. You can alter them and start dosbox with the -conf switch to load the file and use these settings. @@ -69,12 +70,15 @@ The Languagefile: ================= A languagefile can be generated by CONFIG.COM. If you read it you will understand how to change it. Start Dosbox with -lang switch to use your language file or enter the location of the languagefile -in the configfile.(section:[dosbox] language=path/to/langaugefile/languagefile) +in the configfile.(section:[dosbox] language=full path to languagefile.) Special Keys: ============= ALT-ENTER Go full screen and back. +CTRL-F5 Save a screenshot +CTRL-F7 Decrease frameskip +CTRL-F8 Increase frameskip CTRL-F9 Go full screen and back. CTRL-F10 Capture/Release the mouse. CTRL-F11 Slowdown emulation. From f1d25a588f3b62d2b7f1d967f1cfc86a0d1046b6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:22:37 +0000 Subject: [PATCH 0348/4131] New repeat code Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@425 --- src/cpu/core_16/main.h | 217 ++++------------------------------------- 1 file changed, 19 insertions(+), 198 deletions(-) diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index e4133b21..1495e42b 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -bool repcheck; restart: switch(Fetchb()) { case 0x00: /* ADD Eb,Gb */ @@ -109,9 +108,12 @@ restart: if ((reg_al > 0x9F) || flags.cf) { reg_al+=0x60; flags.cf=true; + } else { + flags.cf=false; } flags.sf=(reg_al>>7)>0; flags.zf=(reg_al==0); + //TODO Maybe parity flags.type=t_UNKNOWN; break; case 0x28: /* SUB Eb,Gb */ @@ -545,35 +547,11 @@ restart: } case 0x8d: /* LEA */ { - GetRMrw; - switch (rm & 0xC7) { - case 0x00:*rmrw=reg_bx+reg_si;break; - case 0x01:*rmrw=reg_bx+reg_di;break; - case 0x02:*rmrw=reg_bp+reg_si;break; - case 0x03:*rmrw=reg_bp+reg_di;break; - case 0x04:*rmrw=reg_si;break; - case 0x05:*rmrw=reg_di;break; - case 0x06:*rmrw=Fetchw();break; - case 0x07:*rmrw=reg_bx;break; - case 0x40:*rmrw=reg_bx+reg_si+Fetchbs();break; - case 0x41:*rmrw=reg_bx+reg_di+Fetchbs();break; - case 0x42:*rmrw=reg_bp+reg_si+Fetchbs();break; - case 0x43:*rmrw=reg_bp+reg_di+Fetchbs();break; - case 0x44:*rmrw=reg_si+Fetchbs();break; - case 0x45:*rmrw=reg_di+Fetchbs();break; - case 0x46:*rmrw=reg_bp+Fetchbs();break; - case 0x47:*rmrw=reg_bx+Fetchbs();break; - case 0x80:*rmrw=reg_bx+reg_si+Fetchw();break; - case 0x81:*rmrw=reg_bx+reg_di+Fetchw();break; - case 0x82:*rmrw=reg_bp+reg_si+Fetchw();break; - case 0x83:*rmrw=reg_bp+reg_di+Fetchw();break; - case 0x84:*rmrw=reg_si+Fetchw();break; - case 0x85:*rmrw=reg_di+Fetchw();break; - case 0x86:*rmrw=reg_bp+Fetchw();break; - case 0x87:*rmrw=reg_bx+Fetchw();break; - default: - E_Exit("CPU:8d:Illegal LEA RM Byte"); - } + prefix.segbase=0; + prefix.mark|=PREFIX_SEG; + lookupEATable=EAPrefixTable[prefix.mark]; + GetRMrw;GetEAa; + *rmrw=(Bit16u)eaa; break; } case 0x8e: /* MOV Sw,Ew */ @@ -936,8 +914,8 @@ restart: reg_al = get_CF() ? 0xFF : 0; break; case 0xd7: /* XLAT */ - if (prefixes & PREFIX_SEG) { - reg_al=LoadMb(segprefix_base+(Bit16u)(reg_bx+reg_al)); + if (prefix.mark & PREFIX_SEG) { + reg_al=LoadMb(prefix.segbase+(Bit16u)(reg_bx+reg_al)); PrefixReset; } else { reg_al=LoadMb(SegBase(ds)+(Bit16u)(reg_bx+reg_al)); @@ -1042,176 +1020,15 @@ restart: LOG_ERROR("CPU:LOCK"); break; case 0xf1: /* Weird call undocumented */ +// INTERRUPT(1); E_Exit("CPU:F1:Not Handled"); break; case 0xf2: /* REPNZ */ - repcheck=false; - goto repstart; + count-=Repeat_Normal(false,false,count); + break; case 0xf3: /* REPZ */ - repcheck=true; - repstart: - { - EAPoint to=SegBase(es); - EAPoint from; - if (prefixes & PREFIX_SEG) { - from=(segprefix_base); - PrefixReset; - } else { - from=SegBase(ds); - } - Bit16s direct; - if (flags.df) direct=-1; - else direct=1; - reploop: - Bit8u repcode=Fetchb(); - switch (repcode) { - case 0x26: /* ES Prefix */ - from=SegBase(es); - goto reploop; - case 0x2e: /* CS Prefix */ - from=SegBase(cs); - goto reploop; - case 0x36: /* SS Prefix */ - from=SegBase(ss); - goto reploop; - case 0x3e: /* DS Prefix */ - from=SegBase(ds); - goto reploop; -#ifdef CPU_386 - case 0x66: - Rep_66(direct,from,to); - break; -#endif - - case 0x6c: /* REP INSB */ - { - for (Bit32u temp=reg_cx;temp>0;temp--) { - SaveMb(to,IO_Read(reg_dx)); - to+=direct; - }; - reg_di+=Bit16s(reg_cx*direct);reg_cx=0; - break; - } - case 0x6d: /* REP INSW */ - { - for (Bit32u temp=reg_cx;temp>0;temp--) { - SaveMb(to,IO_Read(reg_dx)); - SaveMb((to+1),IO_Read(reg_dx+1)); - to+=direct*2; - } - reg_di+=Bit16s(reg_cx*direct*2);reg_cx=0; - break; - } - case 0x6e: /* REP OUTSB */ - for (;reg_cx>0;reg_cx--) { - IO_Write(reg_dx,LoadMb(from+reg_si)); - reg_si+=direct; - } - break; - case 0x6f: /* REP OUTSW */ - for (;reg_cx>0;reg_cx--) { - IO_Write(reg_dx,LoadMb(from+reg_si)); - IO_Write(reg_dx+1,LoadMb(from+reg_si+1)); - reg_si+=direct*2; - } - break; - case 0xa4: /* REP MOVSB */ - for (;reg_cx>0;reg_cx--) { - SaveMb(to+reg_di,LoadMb(from+reg_si)); - reg_di+=direct; - reg_si+=direct; - } - break; - case 0xa5: /* REP MOVSW */ - for (;reg_cx>0;reg_cx--) { - SaveMw(to+reg_di,LoadMw(from+reg_si)); - reg_di+=direct*2; - reg_si+=direct*2; - } - break; - case 0xa6: /* REP CMPSB */ - if (!reg_cx) break; - for (;reg_cx>0;) { - reg_cx--; - if ((LoadMb(from+reg_si)==LoadMb(to+reg_di))!=repcheck) { - reg_di+=direct; - reg_si+=direct; - break; - } - reg_di+=direct; - reg_si+=direct; - } - CMPB(from+(reg_si-direct),LoadMb(to+(reg_di-direct)),LoadMb,0); - break; - case 0xa7: /* REP CMPSW */ - if (!reg_cx) break; - for (;reg_cx>0;) { - reg_cx--; - if ((LoadMw(from+reg_si)==LoadMw(to+reg_di))!=repcheck) { - reg_di+=direct*2; - reg_si+=direct*2; - break; - } - reg_di+=direct*2; - reg_si+=direct*2; - } - CMPW(from+(reg_si-direct*2),LoadMw(to+(reg_di-direct*2)),LoadMw,0); - break; - case 0xaa: /* REP STOSB */ - for (;reg_cx>0;reg_cx--) { - SaveMb(to+reg_di,reg_al); - reg_di+=direct; - } - break; - case 0xab: /* REP STOSW */ - for (;reg_cx>0;reg_cx--) { - SaveMw(to+reg_di,reg_ax); - reg_di+=direct*2; - } - break; - case 0xac: /* REP LODSB */ - for (;reg_cx>0;reg_cx--) { - reg_al=LoadMb(from+reg_si); - reg_si+=direct; - } - break; - case 0xad: /* REP LODSW */ - for (;reg_cx>0;reg_cx--) { - reg_ax=LoadMw(from+reg_si); - reg_si+=direct*2; - } - break; - case 0xae: /* REP SCASB */ - if (!reg_cx) break; - for (;reg_cx>0;) { - reg_cx--; - if ((reg_al==LoadMb(to+reg_di))!=repcheck) { - reg_di+=direct; - break; - } - reg_di+=direct; - } - CMPB(reg_al,LoadMb(to+(reg_di-direct)),LoadRb,0); - break; - case 0xaf: /* REP SCASW */ - if (!reg_cx) break; - for (;reg_cx>0;) { - reg_cx--; - if ((reg_ax==LoadMw(to+reg_di))!=repcheck) { - reg_di+=direct*2; - break; - } - reg_di+=direct*2; - } - CMPW(reg_ax,LoadMw(to+(reg_di-direct*2)),LoadRw,0); - break; - case 0x90: /* NOP - yes it is really used this way... eternam */ - break; - default: - E_Exit("Illegal REP prefix %2X",repcode); - } - break; - } + count-=Repeat_Normal(true,false,count); + break; case 0xf4: /* HLT */ break; case 0xf5: /* CMC */ @@ -1498,5 +1315,9 @@ restart: } break; } + default: + NOTDONE; + break; + } From 5b84e7c805ffcf93cabfed2749622a34fb3ccdc2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:23:59 +0000 Subject: [PATCH 0349/4131] String repeat instructions added Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@426 --- src/cpu/core_16/prefix_66.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index a22c79ce..33c2aa51 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -69,8 +69,6 @@ switch(Fetchb()) { RMGdEd(CMPD);break; case 0x3d: /* CMP EAX,Id */ EAXId(CMPD);break; - - case 0x26: /* SEG ES: */ SegPrefix_66(es);break; case 0x2e: /* SEG CS: */ @@ -396,7 +394,14 @@ switch(Fetchb()) { GRP2D(1);break; case 0xd3: /* GRP2 Ed,CL */ GRP2D(reg_cl);break; - + case 0xf2: /* REPNZ */ + prefix.count++; + count-=Repeat_Normal(false,true,count); + break; + case 0xf3: /* REPZ */ + prefix.count++; + count-=Repeat_Normal(true,true,count); + break; case 0xf7: /* GRP3 Ed(,Id) */ { union { Bit64u u;Bit64s s;} temp; From 15033b27a4926212305e00513bc98c5d18d55074 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:25:35 +0000 Subject: [PATCH 0350/4131] New prefix variables and a new string repeat function. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@427 --- src/cpu/core_16/support.h | 317 +++++++++++++++++++++++++++++++++----- 1 file changed, 276 insertions(+), 41 deletions(-) diff --git a/src/cpu/core_16/support.h b/src/cpu/core_16/support.h index 095f585a..ace3a10f 100644 --- a/src/cpu/core_16/support.h +++ b/src/cpu/core_16/support.h @@ -88,8 +88,8 @@ static INLINE Bit32u Pop_32() { #define stringSI \ EAPoint from; \ - if (prefixes & PREFIX_SEG) { \ - from=(segprefix_base+reg_si); \ + if (prefix.mark & PREFIX_SEG) { \ + from=(prefix.segbase+reg_si); \ PrefixReset; \ } else { \ from=SegBase(ds)+reg_si; \ @@ -102,48 +102,265 @@ static INLINE Bit32u Pop_32() { #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); +static Bits Repeat_Normal(bool testz,bool prefix_66,Bits count_remain) { + + Bits count=count_remain; + PhysPt base_si,base_di; + + Bit16s direct; + if (flags.df) direct=-1; + else direct=1; + base_di=SegBase(es); +rep_again: + if (prefix.mark & PREFIX_SEG) { + base_si=(prefix.segbase); + } else { + base_si=SegBase(ds); + } + switch (Fetchb()) { + case 0x26: /* ES Prefix */ + prefix.segbase=SegBase(es); + prefix.mark|=PREFIX_SEG; + prefix.count++; + goto rep_again; + case 0x2e: /* CS Prefix */ + prefix.segbase=SegBase(cs); + prefix.mark|=PREFIX_SEG; + prefix.count++; + goto rep_again; + case 0x36: /* SS Prefix */ + prefix.segbase=SegBase(ss); + prefix.mark|=PREFIX_SEG; + prefix.count++; + goto rep_again; + case 0x3e: /* DS Prefix */ + prefix.segbase=SegBase(ds); + prefix.mark|=PREFIX_SEG; + prefix.count++; + goto rep_again; + case 0x66: /* Size Prefix */ + prefix.count++; + prefix_66=!prefix_66; + goto rep_again; + case 0x6c: /* REP INSB */ + for (;(reg_cx && count>0);reg_cx--,count--) { + SaveMb(base_di+reg_di,IO_Read(reg_dx)); + reg_di+=direct; } - } while (again); + if (reg_cx && count<=0) goto countzero; + break; + case 0x6d: /* REP INSW/D */ + if (prefix_66) { + direct*=4; + for (;(reg_cx && count>0);reg_cx--,count--) { + SaveMb(base_di+reg_di+0,IO_Read(reg_dx+0)); + SaveMb(base_di+reg_di+1,IO_Read(reg_dx+1)); + SaveMb(base_di+reg_di+2,IO_Read(reg_dx+2)); + SaveMb(base_di+reg_di+3,IO_Read(reg_dx+3)); + reg_di+=direct; + } + } else { + direct*=2; + for (;(reg_cx && count>0);reg_cx--,count--) { + SaveMb(base_di+reg_di+0,IO_Read(reg_dx+0)); + SaveMb(base_di+reg_di+1,IO_Read(reg_dx+1)); + reg_di+=direct; + } + } + if (reg_cx && count<=0) goto countzero; + break; + case 0x6e: /* REP OUTSB */ + for (;(reg_cx && count>0);reg_cx--,count--) { + IO_Write(reg_dx,LoadMb(base_si+reg_si)); + reg_si+=direct; + } + if (reg_cx && count<=0) goto countzero; + break; + case 0x6f: /* REP OUTSW/D */ + if (prefix_66) { + direct*=4; + for (;(reg_cx && count>0);reg_cx--,count--) { + IO_Write(reg_dx+0,LoadMb(base_si+reg_si+0)); + IO_Write(reg_dx+1,LoadMb(base_si+reg_si+1)); + IO_Write(reg_dx+2,LoadMb(base_si+reg_si+2)); + IO_Write(reg_dx+3,LoadMb(base_si+reg_si+3)); + reg_si+=direct; + } + } else { + direct*=2; + for (;(reg_cx && count>0);reg_cx--,count--) { + IO_Write(reg_dx+0,LoadMb(base_si+reg_si+0)); + IO_Write(reg_dx+1,LoadMb(base_si+reg_si+1)); + reg_si+=direct; + } + } + if (reg_cx && count<=0) goto countzero; + break; + case 0xa4: /* REP MOVSB */ + for (;(reg_cx && count>0);reg_cx--,count--) { + SaveMb(base_di+reg_di,LoadMb(base_si+reg_si)); + reg_si+=direct;reg_di+=direct; + } + if (reg_cx && count<=0) goto countzero; + break; + case 0xa5: /* REP MOVSW/D */ + if (prefix_66) { + direct*=4; + for (;(reg_cx && count>0);reg_cx--,count--) { + SaveMd(base_di+reg_di,LoadMd(base_si+reg_si)); + reg_si+=direct;reg_di+=direct; + } + } else { + direct*=2; + for (;(reg_cx && count>0);reg_cx--,count--) { + SaveMw(base_di+reg_di,LoadMw(base_si+reg_si)); + reg_si+=direct;reg_di+=direct; + } + } + if (reg_cx && count<=0) goto countzero; + break; + case 0xa6: /* REP CMPSB */ + { + if (!reg_cx) goto stopit;Bit8u op1,op2; + for (;(reg_cx && count>0);) { + op1=LoadMb(base_si+reg_si);op2=LoadMb(base_di+reg_di); + reg_cx--,count--;reg_si+=direct;reg_di+=direct; + if ((op1==op2)!=testz) break; + } + CMPB(op1,op2,LoadRb,0); + if ((op1==op2)!=testz) goto stopit; + if (reg_cx && count<=0) goto countzero; + } + break; + case 0xa7: /* REP CMPSW */ + { + if (!reg_cx) goto stopit; + if (prefix_66) { + direct*=4; + Bit32u op1,op2; + for (;(reg_cx && count>0);) { + op1=LoadMd(base_si+reg_si);op2=LoadMd(base_di+reg_di); + reg_cx--,count--;reg_si+=direct;reg_di+=direct; + if ((op1==op2)!=testz) break; + } + CMPD(op1,op2,LoadRd,0); + if ((op1==op2)!=testz) goto stopit; + } else { + direct*=2; + Bit16u op1,op2; + for (;(reg_cx && count>0);) { + op1=LoadMw(base_si+reg_si);op2=LoadMw(base_di+reg_di); + reg_cx--,count--;reg_si+=direct;reg_di+=direct; + if ((op1==op2)!=testz) break; + } + CMPW(op1,op2,LoadRw,0); + if ((op1==op2)!=testz) goto stopit; + } + if (reg_cx && count<=0) goto countzero; + } + break; + case 0xaa: /* REP STOSB */ + for (;(reg_cx && count>0);reg_cx--,count--) { + SaveMb(base_di+reg_di,reg_al); + reg_di+=direct; + } + if (reg_cx && count<=0) goto countzero; + break; + case 0xab: /* REP STOSW */ + if (prefix_66) { + direct*=4; + for (;(reg_cx && count>0);reg_cx--,count--) { + SaveMd(base_di+reg_di,reg_eax); + reg_di+=direct; + } + } else { + direct*=2; + for (;(reg_cx && count>0);reg_cx--,count--) { + SaveMw(base_di+reg_di,reg_ax); + reg_di+=direct; + } + } + if (reg_cx && count<=0) goto countzero; + break; + case 0xac: /* REP LODSB */ + for (;(reg_cx && count>0);reg_cx--,count--) { + reg_al=LoadMb(base_si+reg_si); + reg_si+=direct; + } + if (reg_cx && count<=0) goto countzero; + break; + case 0xad: /* REP LODSW */ + if (prefix_66) { + direct*=4; + for (;(reg_cx && count>0);reg_cx--,count--) { + reg_eax=LoadMd(base_si+reg_si); + reg_si+=direct; + } + } else { + direct*=2; + for (;(reg_cx && count>0);reg_cx--,count--) { + reg_ax=LoadMw(base_si+reg_si); + reg_si+=direct; + } + } + if (reg_cx && count<=0) goto countzero; + break; + case 0xae: /* REP SCASB */ + { + if (!reg_cx) goto stopit;Bit8u op2; + for (;(reg_cx && count>0);) { + op2=LoadMb(base_di+reg_di); + reg_cx--,count--;reg_di+=direct; + if ((reg_al==op2)!=testz) break; + } + CMPB(reg_al,op2,LoadRb,0); + if ((reg_al==op2)!=testz) goto stopit; + if (reg_cx && count<=0) goto countzero; + } + break; + case 0xaf: /* REP SCASW */ + { + if (!reg_cx) goto stopit; + if (prefix_66) { + direct*=4; + Bit32u op2; + for (;(reg_cx && count>0);) { + op2=LoadMd(base_di+reg_di); + reg_cx--,count--;reg_di+=direct; + if ((reg_eax==op2)!=testz) break; + } + CMPD(reg_eax,op2,LoadRd,0); + if ((reg_eax==op2)!=testz) goto stopit; + } else { + direct*=2; + Bit16u op2; + for (;(reg_cx && count>0);) { + op2=LoadMw(base_di+reg_di); + reg_cx--,count--;reg_di+=direct; + if ((reg_ax==op2)!=testz) break; + } + CMPW(reg_ax,op2,LoadRw,0); + if ((reg_ax==op2)!=testz) goto stopit; + } + if (reg_cx && count<=0) goto countzero; + } + break; + default: + IPPoint--; + LOG_DEBUG("Unhandled REP Prefix %X",Fetchb()); + + } +stopit: + PrefixReset; + return count_remain-count; +countzero: + IPPoint-=(prefix.count+2); /* Rep instruction and whatever string instruction */ + PrefixReset; + return count_remain; } //flags.io and nt shouldn't be compiled for 386 +#ifdef CPU_386 #define Save_Flagsw(FLAGW) \ { \ flags.type=t_UNKNOWN; \ @@ -159,7 +376,25 @@ static INLINE void Rep_66(Bit16s direct,EAPoint from,EAPoint to) { PIC_runIRQs(); \ LOADIP; \ } \ - if (flags.tf) E_Exit("CPU:Trap Flag not supported"); \ + if (flags.tf) LOG_DEBUG("CPU:Trap Flag not supported"); \ } +#else +#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; \ + if (flags.intf && PIC_IRQCheck) { \ + SAVEIP; \ + PIC_runIRQs(); \ + LOADIP; \ + } \ + if (flags.tf) LOG_DEBUG("CPU:Trap Flag not supported"); \ +} + +#endif From dfb34f80a5a478724913324b2c0555f7de9a2e13 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:26:09 +0000 Subject: [PATCH 0351/4131] New prefix variables. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@428 --- src/cpu/core_16/table_ea.h | 119 ++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 68 deletions(-) diff --git a/src/cpu/core_16/table_ea.h b/src/cpu/core_16/table_ea.h index c6972693..48fd12a0 100644 --- a/src/cpu/core_16/table_ea.h +++ b/src/cpu/core_16/table_ea.h @@ -26,38 +26,56 @@ static GetEATable * lookupEATable; #define PREFIX_ADDR 0x2 #define PREFIX_SEG_ADDR 0x3 - -static Bitu prefixes; -static EAPoint segprefix_base; +static struct { + Bitu mark; + Bitu count; + EAPoint segbase; +} prefix; /* Gets initialized at the bottem, can't seem to declare forward references */ static GetEATable * EAPrefixTable[4]; - #define SegPrefix(blah) \ - segprefix_base=SegBase(blah); \ - prefixes|=PREFIX_SEG; \ - lookupEATable=EAPrefixTable[prefixes]; \ - goto restart; \ + prefix.segbase=SegBase(blah); \ + prefix.mark|=PREFIX_SEG; \ + prefix.count++; \ + lookupEATable=EAPrefixTable[prefix.mark]; \ + goto restart; #define SegPrefix_66(blah) \ - segprefix_base=SegBase(blah); \ - prefixes|=PREFIX_SEG; \ - lookupEATable=EAPrefixTable[prefixes]; \ - goto restart_66; \ + prefix.segbase=SegBase(blah); \ + prefix.mark|=PREFIX_SEG; \ + prefix.count++; \ + lookupEATable=EAPrefixTable[prefix.mark]; \ + goto restart_66; -#define PrefixReset \ - prefixes=PREFIX_NONE;lookupEATable=EAPrefixTable[PREFIX_NONE]; +#define PrefixReset \ + prefix.mark=PREFIX_NONE; \ + prefix.count=0; \ + lookupEATable=EAPrefixTable[PREFIX_NONE]; + +#if 1 #define GetEADirect \ -EAPoint eaa;switch (prefixes) { \ +EAPoint eaa;switch (prefix.mark) { \ case PREFIX_NONE:eaa=SegBase(ds)+Fetchw();break; \ -case PREFIX_SEG:eaa=segprefix_base+Fetchw();PrefixReset;break; \ +case PREFIX_SEG:eaa=prefix.segbase+Fetchw();PrefixReset;break; \ case PREFIX_ADDR:eaa=SegBase(ds)+Fetchd();PrefixReset;break; \ -case PREFIX_SEG_ADDR:eaa=segprefix_base+Fetchd();PrefixReset;break; \ +case PREFIX_SEG_ADDR:eaa=prefix.segbase+Fetchd();PrefixReset;break; \ } +#else + +#define GetEADirect \ +EAPoint eaa; \ +if (!prefix.mark) { eaa=SegBase(ds)+Fetchw();} \ +else if (prefix.mark == PREFIX_SEG) { eaa=prefix.segbase+Fetchw();PrefixReset;} \ +else if (prefix.mark == PREFIX_ADDR) { eaa=SegBase(ds)+Fetchd();PrefixReset;} \ +else if (prefix.mark == PREFIX_SEG_ADDR) { eaa=prefix.segbase+Fetchd();PrefixReset;} + +#endif + @@ -125,7 +143,7 @@ static GetEATable GetEA_16_n={ }; -#define segprefixed(val) EAPoint ret=segprefix_base+val;PrefixReset;return ret; +#define segprefixed(val) EAPoint ret=prefix.segbase+val;PrefixReset;return ret; static EAPoint EA_16_00_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_si)) } static EAPoint EA_16_01_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_di)) } @@ -189,6 +207,8 @@ static GetEATable GetEA_16_s={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +static Bit32u SIBZero=0; +static Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi }; INLINE EAPoint Sib(Bitu mode) { Bit8u sib=Fetchb(); @@ -203,7 +223,7 @@ INLINE EAPoint Sib(Bitu mode) { case 3: /* EBX Base */ base=SegBase(ds)+reg_ebx;break; case 4: /* ESP Base */ - base=SegBase(ds)+reg_esp;break; + base=SegBase(ss)+reg_esp;break; case 5: /* #1 Base */ if (!mode) { base=SegBase(ds)+Fetchd();break; @@ -215,25 +235,7 @@ INLINE EAPoint Sib(Bitu mode) { 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<> 3) &7] << (sib >> 6); return base; }; @@ -305,50 +307,31 @@ INLINE EAPoint Sib_s(Bitu mode) { EAPoint base; switch (sib&7) { case 0: /* EAX Base */ - base=segprefix_base+reg_eax;break; + base=prefix.segbase+reg_eax;break; case 1: /* ECX Base */ - base=segprefix_base+reg_ecx;break; + base=prefix.segbase+reg_ecx;break; case 2: /* EDX Base */ - base=segprefix_base+reg_edx;break; + base=prefix.segbase+reg_edx;break; case 3: /* EBX Base */ - base=segprefix_base+reg_ebx;break; + base=prefix.segbase+reg_ebx;break; case 4: /* ESP Base */ - base=segprefix_base+reg_esp;break; + base=prefix.segbase+reg_esp;break; case 5: /* #1 Base */ if (!mode) { - base=segprefix_base+Fetchd();break; + base=prefix.segbase+Fetchd();break; } else { - base=segprefix_base+reg_ebp;break; + base=prefix.segbase+reg_ebp;break; } case 6: /* ESI Base */ - base=segprefix_base+reg_esi;break; + base=prefix.segbase+reg_esi;break; case 7: /* EDI Base */ - base=segprefix_base+reg_edi;break; + base=prefix.segbase+reg_edi;break; } - Bitu shift=sib >> 6; - switch ((sib >>3) &7) { - case 0: /* EAX Index */ - base+=(Bit32s)reg_eax<> 3) &7] << (sib >> 6); PrefixReset; return base; }; -#define segprefixed_32(val) EAPoint ret=segprefix_base+(Bit32u)(val);PrefixReset;return ret; +#define segprefixed_32(val) EAPoint ret=prefix.segbase+(Bit32u)(val);PrefixReset;return ret; static EAPoint EA_32_00_s(void) { segprefixed_32(reg_eax); } static EAPoint EA_32_01_s(void) { segprefixed_32(reg_ecx); } From 0dcbf5f638ec7a04dfaa7dffdc3ffd5c1ea05817 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:26:46 +0000 Subject: [PATCH 0352/4131] Removed a new line from debug_msg Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@429 --- src/debug/debug_gui.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index dadc282d..43d8d305 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -34,7 +34,6 @@ void DEBUG_ShowMsg(char * msg) { char buf[1024]; strcpy(buf,msg); - strcat(buf,"\n"); waddstr(dbg.win_out,buf); wprintw(dbg.win_out," %d\n",cycle_count); From 46cbb48f3f3c62a42a67c503ed233f8fac961750 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:27:24 +0000 Subject: [PATCH 0353/4131] Removed #include Added a config file help string. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@430 --- src/debug/debug.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 998d2bac..29c0dbe5 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -20,7 +20,6 @@ #include #include -#include #include "dosbox.h" #if C_DEBUG @@ -971,6 +970,7 @@ static void DEBUG_ShutDown(Section * sec) void DEBUG_Init(Section* sec) { + MSG_Add("DEBUG_CONFIGFILE_HELP","Nothing to setup yet!\n"); DEBUG_DrawScreen(); /* Add some keyhandlers */ KEYBOARD_AddEvent(KBD_kpminus,0,DEBUG_Enable); From 5003c981eecda92819eb5958696eb1e1f8442577 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:27:52 +0000 Subject: [PATCH 0354/4131] Some changes to errorlevel Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@431 --- src/dosbox.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 73950cc3..83ed464a 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -38,7 +38,7 @@ #include "support.h" Config * control; -Bitu errorlevel; +Bitu errorlevel=1; /* The whole load of startups for all the subfunctions */ void MSG_Init(Section_prop *); @@ -142,7 +142,11 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit); secprop->Add_string("language",""); +#if C_DEBUG secprop->Add_int("warnings",4); +#else + secprop->Add_int("warnings",0); +#endif secprop->AddInitFunction(&MEM_Init); secprop->AddInitFunction(&IO_Init); From 273279db4bc189bf0c6272d2cf730bef1d2a6cc1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:29:08 +0000 Subject: [PATCH 0355/4131] Correct version in the shell startup message Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@432 --- src/shell/shell.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index c785790f..1f7bed15 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -195,13 +195,14 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_GOTO_MISSING_LABEL","No label supplied to GOTO command.\n"); MSG_Add("SHELL_CMD_GOTO_LABEL_NOT_FOUND","GOTO: Label %s not found.\n"); MSG_Add("SHELL_CMD_FILE_NOT_FOUND","File %s not found.\n"); + MSG_Add("SHELL_CMD_FILE_EXISTS","File %s already exists.\n"); MSG_Add("SHELL_CMD_DIR_INTRO","Directory of %s.\n"); MSG_Add("SHELL_CMD_DIR_PATH_ERROR","Illegal Path\n"); MSG_Add("SHELL_CMD_DIR_BYTES_USED","%5d File(s) %17s Bytes\n"); MSG_Add("SHELL_CMD_DIR_BYTES_FREE","%5d Dir(s) %17s Bytes free\n"); MSG_Add("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\n"); MSG_Add("SHELL_EXECUTE_ILLEGAL_COMMAND","Illegal command: %s.\n"); - MSG_Add("SHELL_STARTUP","DOSBox Shell v0.40\nFor Help and supported commands type: HELP\n\nHAVE FUN!\nThe DOSBox Team\n\n"); + MSG_Add("SHELL_STARTUP","DOSBox Shell v" VERSION "\nFor Help and supported commands type: HELP\n\nHAVE FUN!\nThe DOSBox Team\n\n"); MSG_Add("SHELL_CMD_CHDIR_HELP","Change Directory.\n"); MSG_Add("SHELL_CMD_CLS_HELP","Clear screen.\n"); MSG_Add("SHELL_CMD_DIR_HELP","Directory View.\n"); From d5d60cdba52d52b95b5ea2d6e9940a834383c6dc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:32:23 +0000 Subject: [PATCH 0356/4131] Fixed frame skipping mutex. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@433 --- src/gui/sdlmain.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index a7353328..7da7a2df 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -154,7 +154,7 @@ static void GFX_Redraw() { }; #endif - if (++sdl.frames.countStartUp(); /* Shutdown everything */ } catch (char * error) { - LOG_ERROR("Exit to error: %s",error); + LOG_MSG("Exit to error: %sPress enter to continue.",error); fgetc(stdin); } return 0; From 57510618cf695053e571992f7cb34ad3c974d889 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:32:58 +0000 Subject: [PATCH 0357/4131] Fixed a warning in gcc. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@434 --- src/dos/dos_execute.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 5f51e248..bb3c6232 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -165,7 +165,8 @@ bool DOS_NewPSP(Bit16u segment, Bit16u size) { DOS_PSP psp(segment); psp.MakeNew(size); - psp.CopyFileTable(&DOS_PSP(psp.GetParent())); + DOS_PSP psp_parent(psp.GetParent()); + psp.CopyFileTable(&psp_parent); return true; }; From a865ac6c6a5071db41e2020e4ddd63527e2e5a64 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:34:00 +0000 Subject: [PATCH 0358/4131] Fixed keyevents with right alt and ctrl. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@435 --- src/hardware/keyboard.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index a0a596df..f65f4526 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -160,7 +160,7 @@ static void write_p64(Bit32u port,Bit8u val) { static Bit8u read_p64(Bit32u port) { return 0x1c | (keyb.read_active ? 0x1 : 0x0); -}; +} void KEYBOARD_AddEvent(Bitu keytype,Bitu state,KEYBOARD_EventHandler * handler) { @@ -174,9 +174,7 @@ void KEYBOARD_AddEvent(Bitu keytype,Bitu state,KEYBOARD_EventHandler * handler) newevent->type=keytype; newevent->state=state; newevent->handler=handler; - - -}; +} void KEYBOARD_AddKey(Bitu keytype,bool pressed) { bool extend=false; @@ -287,9 +285,13 @@ void KEYBOARD_AddKey(Bitu keytype,bool pressed) { //The Extended keys case KBD_kpenter:extend=true;ret=28;break; - case KBD_rightctrl:extend=true;ret=29;break; + case KBD_rightctrl:extend=true;ret=29; + shift_state=(shift_state&~CTRL_PRESSED)|(pressed ? CTRL_PRESSED:0); + break; case KBD_kpslash:extend=true;ret=53;break; - case KBD_rightalt:extend=true;ret=56;break; + case KBD_rightalt:extend=true;ret=56; + shift_state=(shift_state&~ALT_PRESSED)|(pressed ? ALT_PRESSED:0); + break; case KBD_home:extend=true;ret=71;break; case KBD_up:extend=true;ret=72;break; case KBD_pageup:extend=true;ret=73;break; @@ -303,7 +305,7 @@ void KEYBOARD_AddKey(Bitu keytype,bool pressed) { default: E_Exit("Unsopperted key press"); break; - }; + } /* check for active key events */ KeyEvent * checkevent=event_handlers[keytype]; while (checkevent) { @@ -319,7 +321,7 @@ void KEYBOARD_AddKey(Bitu keytype,bool pressed) { if (extend) KEYBOARD_AddCode(224); if (!pressed) ret+=128; KEYBOARD_AddCode(ret); -}; +} void KEYBOARD_Init(Section* sec) { IO_RegisterWriteHandler(0x60,write_p60,"Keyboard"); @@ -336,4 +338,4 @@ void KEYBOARD_Init(Section* sec) { keyb.command=CMD_NONE; KEYBOARD_ClrBuffer(); PIC_RegisterIRQ(1,KEYBOARD_IRQHandler,"KEYBOARD"); -}; +} From 1233570442d7da3f9027d78af803900626640426 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:39:05 +0000 Subject: [PATCH 0359/4131] Changed the order of writing to the vga registers to fix some palette errors. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@436 --- src/ints/int10_modes.cpp | 72 +++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 0419ba99..7932d2b4 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -274,6 +274,44 @@ void INT10_SetVideoMode(Bit8u mode) { modeset_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); + + /* Reset Attribute ctl into address mode just to be safe */ + + IO_Read(VGAREG_ACTL_RESET); + // Set the High Attribute Ctl + for(i=0x10;i<=ACTL_MAX_REG;i++) { + IO_Write(VGAREG_ACTL_ADDRESS,(Bit8u)i); + IO_Write(VGAREG_ACTL_WRITE_DATA,actl_regs[vga_modes[line].actlmodel][i]); + } + // Set Sequencer Ctl + for(i=0;i<=SEQU_MAX_REG;i++) { + IO_Write(VGAREG_SEQU_ADDRESS,(Bit8u)i); + IO_Write(VGAREG_SEQU_DATA,sequ_regs[vga_modes[line].sequmodel][i]); + } + + // Set Grafx Ctl + for(i=0;i<=GRDC_MAX_REG;i++) { + IO_Write(VGAREG_GRDC_ADDRESS,(Bit8u)i); + IO_Write(VGAREG_GRDC_DATA,grdc_regs[vga_modes[line].grdcmodel][i]); + } + + // Set CRTC address VGA or MDA + crtc_addr=vga_modes[line].memmodel==MTEXT?VGAREG_MDA_CRTC_ADDRESS:VGAREG_VGA_CRTC_ADDRESS; + // Set CRTC regs + for(i=0;i<=CRTC_MAX_REG;i++) { + IO_Write(crtc_addr,(Bit8u)i); + IO_Write(crtc_addr+1,crtc_regs[vga_modes[line].crtcmodel][i]); + } + + // Set the misc register + IO_Write(VGAREG_WRITE_MISC_OUTPUT,vga_modes[line].miscreg); + + // Enable video + IO_Write(VGAREG_ACTL_ADDRESS,0x20); + IO_Read(VGAREG_ACTL_RESET); + + //Set the palette + if ((modeset_ctl&0x08)==0x8) LOG_DEBUG("INT10:Mode set without palette"); if((modeset_ctl&0x08)==0) { // Set the PEL mask IO_Write(VGAREG_PEL_MASK,vga_modes[line].pelmask); @@ -312,40 +350,13 @@ void INT10_SetVideoMode(Bit8u mode) { } } - /* Reset Attribute ctl into address mode just to be safe */ - IO_Read(VGAREG_ACTL_RESET); - // Set Attribute Ctl - for(i=0;i<=ACTL_MAX_REG;i++) { + // Set the Low Attribute Ctl + for(i=0;i<=0xf;i++) { IO_Write(VGAREG_ACTL_ADDRESS,(Bit8u)i); IO_Write(VGAREG_ACTL_WRITE_DATA,actl_regs[vga_modes[line].actlmodel][i]); } - // Set Sequencer Ctl - for(i=0;i<=SEQU_MAX_REG;i++) { - IO_Write(VGAREG_SEQU_ADDRESS,(Bit8u)i); - IO_Write(VGAREG_SEQU_DATA,sequ_regs[vga_modes[line].sequmodel][i]); - } - - // Set Grafx Ctl - for(i=0;i<=GRDC_MAX_REG;i++) { - IO_Write(VGAREG_GRDC_ADDRESS,(Bit8u)i); - IO_Write(VGAREG_GRDC_DATA,grdc_regs[vga_modes[line].grdcmodel][i]); - } - - // Set CRTC address VGA or MDA - crtc_addr=vga_modes[line].memmodel==MTEXT?VGAREG_MDA_CRTC_ADDRESS:VGAREG_VGA_CRTC_ADDRESS; - // Set CRTC regs - for(i=0;i<=CRTC_MAX_REG;i++) { - IO_Write(crtc_addr,(Bit8u)i); - IO_Write(crtc_addr+1,crtc_regs[vga_modes[line].crtcmodel][i]); - } - - // Set the misc register - IO_Write(VGAREG_WRITE_MISC_OUTPUT,vga_modes[line].miscreg); - - // Enable video - IO_Write(VGAREG_ACTL_ADDRESS,0x20); - IO_Read(VGAREG_ACTL_RESET); + Bit32u tel; if(clearmem) { if(vga_modes[line].type==TEXT) { @@ -377,6 +388,7 @@ void INT10_SetVideoMode(Bit8u mode) { real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,cheight); real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem << 7))); real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9); + real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0); real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); // FIXME We nearly have the good tables. to be reworked From d26cccdc81fa6ce0f529c68f6a6eeb3d58e5822d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:40:10 +0000 Subject: [PATCH 0360/4131] Clean up. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@437 --- src/misc/support.cpp | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 689d3990..fb16f52a 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -171,21 +171,18 @@ void S_Warn(char * format,...) { GFX_ShowMsg(buf); #endif } + static char buf[1024]; //greater scope as else it doesn't always gets thrown right (linux/gcc2.95) void E_Exit(char * format,...) { - -// char buf[1024]; //see above - if(errorlevel>=1){ - - va_list msg; - va_start(msg,format); - vsprintf(buf,format,msg); - va_end(msg); - - strcat(buf,"\n"); + if(errorlevel>=1) { + va_list msg; + va_start(msg,format); + vsprintf(buf,format,msg); + va_end(msg); + + strcat(buf,"\n"); } else { - strcpy(buf,"an unsupported feature\n"); + strcpy(buf,"an unsupported feature\n"); } - throw(buf); -}; +} From de23d6017218c0188ec76c04c5561abeebadb0bc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:40:19 +0000 Subject: [PATCH 0361/4131] Removed some debug warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@438 --- src/misc/setup.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 09cfa7a4..8846a6c0 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -196,7 +196,6 @@ Section_line* Config::AddSection_line(const char* _name,void (*_initfunction)(Se void Config::Init(){ for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ - LOG_DEBUG("Init %s",(*tel)->sectionname.c_str()); (*tel)->ExecuteInit(); } } From 70d5be8ddbe5dacb075763d011aac44347ce3932 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:40:31 +0000 Subject: [PATCH 0362/4131] Added a config program to write config and language file. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@439 --- src/misc/programs.cpp | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index e5562713..4b495ca2 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -171,11 +171,44 @@ bool Program::SetEnv(const char * entry,const char * new_string) { return true; } -//TODO Hash table :) +class CONFIG : public Program { +public: + void Run(void); +}; + +void MSG_Write(const char *); + +void CONFIG::Run(void) { + FILE * f; + if (cmd->FindString("-writeconf",temp_line,true)) { + f=fopen(temp_line.c_str(),"wb+"); + if (!f) WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str()); + fclose(f); + control->PrintConfig(temp_line.c_str()); + return; + } + if (cmd->FindString("-writelang",temp_line,true)) { + f=fopen(temp_line.c_str(),"wb+"); + if (!f) WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str()); + fclose(f); + MSG_Write(temp_line.c_str()); + return; + } + WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE")); +} + + +static void CONFIG_ProgramStart(Program * * make) { + *make=new CONFIG; +} void PROGRAMS_Init(Section* sec) { /* Setup a special callback to start virtual programs */ call_program=CALLBACK_Allocate(); CALLBACK_Setup(call_program,&PROGRAMS_Handler,CB_RETF); + PROGRAMS_MakeFile("CONFIG.COM",CONFIG_ProgramStart); + + MSG_Add("PROGRAM_CONFIG_FILE_ERROR","Can't open file %s\n"); + MSG_Add("PROGRAM_CONFIG_USAGE","Config tool:\nUse -writeconf filename to write the current config.\nUse -writelang filename to write the current language strings.\n"); } From 7149f0611b67998568e07bb70f62b2001b6cc125 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:40:56 +0000 Subject: [PATCH 0363/4131] Internal messages are overwritten by the language file now. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@440 --- src/misc/messages.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 9df0ea1e..4b5e5aff 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -40,7 +40,15 @@ struct MessageBlock { static list Lang; typedef list::iterator itmb; + void MSG_Add(const char * _name, const char* _val) { + /* Find the message */ + for(itmb tel=Lang.begin();tel!=Lang.end();tel++) { + if((*tel).name==_name) { + return; + } + } + /* Even if the message doesn't exist add it */ Lang.push_back(MessageBlock(_name,_val)); } @@ -55,8 +63,9 @@ void MSG_Replace(const char * _name, const char* _val) { } } /* Even if the message doesn't exist add it */ - MSG_Add(_name,_val); + Lang.push_back(MessageBlock(_name,_val)); } + static void LoadMessageFile(const char * fname) { if (!fname) return; if(*fname=='\0') return;//empty string=no languagefile From acd82b39a72b5f64d6e0e335a03947bb0d6e6767 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:41:48 +0000 Subject: [PATCH 0364/4131] zlib.lib wasn't linked with release version. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@441 --- visualc/dosbox.dsp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index f274ef58..e4d31a78 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -50,7 +50,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 libpng.lib sdlmain.lib sdl.lib curses.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 zlib.lib libpng.lib sdlmain.lib sdl.lib curses.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 !ELSEIF "$(CFG)" == "dosbox - Win32 Debug" From ee69b4e211f6cd8e36f2a3c3d2ebc002eeb683fb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 21:47:22 +0000 Subject: [PATCH 0365/4131] More changes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@442 --- ChangeLog | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 62de4472..d91901cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,12 +9,15 @@ - some cpu-bug fixes - dma changes - Real Sound support - - EMM fixes + - 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). From 8710865d53b0e7b5f7d597e197d13cfb0d4e4bbd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 22:14:40 +0000 Subject: [PATCH 0366/4131] Check for libpng. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@443 --- configure.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure.in b/configure.in index c0cb9671..c05b1488 100644 --- a/configure.in +++ b/configure.in @@ -36,6 +36,9 @@ AC_C_INLINE AC_TYPE_SIZE_T AC_STRUCT_TM +dnl Checks for libraries. +AC_CHECK_LIB(png, png_check_sig, , AC_MSG_ERROR([*** libpng not found!]), -lz) + #Check if the compiler support attributes AC_MSG_CHECKING(if compiler allows __attribute__) AC_TRY_COMPILE([], [typedef struct { } __attribute__ ((packed)) junk;], From 778a243f8da253c48c9000f3f83e8e40c65d31e6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 22:15:22 +0000 Subject: [PATCH 0367/4131] Version 0.56 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@444 --- configure.in | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/configure.in b/configure.in index c05b1488..4fa3482d 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Init. -AC_INIT(dosbox,0.55) +AC_INIT(dosbox,0.56) AC_CONFIG_SRCDIR(README) dnl Detect the canonical host and target build environment @@ -10,7 +10,6 @@ dnl Setup for automake AM_INIT_AUTOMAKE AM_CONFIG_HEADER(config.h) - dnl Checks for programs. AC_PROG_MAKE_SET AC_PROG_CC From 845e239eba2773d39d5a7c03763fbfd8dfb70ee5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Oct 2002 22:49:42 +0000 Subject: [PATCH 0368/4131] Fixed crash when file can't be opened Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@445 --- src/misc/programs.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 4b495ca2..2a9c93df 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -182,14 +182,20 @@ void CONFIG::Run(void) { FILE * f; if (cmd->FindString("-writeconf",temp_line,true)) { f=fopen(temp_line.c_str(),"wb+"); - if (!f) WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str()); + if (!f) { + WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str()); + return; + } fclose(f); control->PrintConfig(temp_line.c_str()); return; } if (cmd->FindString("-writelang",temp_line,true)) { f=fopen(temp_line.c_str(),"wb+"); - if (!f) WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str()); + if (!f) { + WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str()); + return; + } fclose(f); MSG_Write(temp_line.c_str()); return; From 388885b0fe610329d3d5df5b4b9e7751e44884ee Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 26 Oct 2002 09:30:15 +0000 Subject: [PATCH 0369/4131] Fill new allocated memory with 0xcd's Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@446 --- src/hardware/memory.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 783cc6d3..9ce74ac5 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -245,6 +245,7 @@ void MEM_Init(Section * sect) { if (!memory) { throw("Can't allocate memory for memory"); } + memset(memory,0xcd,1024*1024); /* Setup tables for first mb */ MEM_SetupMapping(0,PAGE_COUNT(1024*1024),memory); /* Setup tables for HMA Area */ From accaa93ca9f57d398cd46ccbe61ea0be7d777d50 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 26 Oct 2002 10:00:50 +0000 Subject: [PATCH 0370/4131] Fixed findfirst/next attribute matching. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@447 --- src/dos/drive_local.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 228a6548..7dfd868d 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -125,8 +125,7 @@ bool localDrive::FindNext(DOS_DTA & dta) { } if(S_ISDIR(stat_block.st_mode)) find_attr=DOS_ATTR_DIRECTORY; else find_attr=DOS_ATTR_ARCHIVE; - if(!(srch_attr & find_attr)) goto again; - + if (~srch_attr & find_attr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM)) goto again; /*file is okay, setup everything to be copied in DTA Block */ char find_name[DOS_NAMELENGTH_ASCII];Bit16u find_date,find_time;Bit32u find_size; if(strlen(dir_ent->d_name) Date: Sat, 26 Oct 2002 11:49:29 +0000 Subject: [PATCH 0371/4131] updated the News of 0.56 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@448 --- NEWS | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 517fb046..c39c56cb 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,26 @@ +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: - changed basedir handling. (linux/winXP) - added some FCB-calls @@ -43,4 +66,4 @@ -added the correct time to dir. -bugfixes to batch-file handling. -Lot's of small bugfixes.(Dune1&2,wolf3d, many more). - -Released the source. \ No newline at end of file + -Released the source. From 75a3747a3c52af161638f2b92d866de3f21a29aa Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 26 Oct 2002 12:44:47 +0000 Subject: [PATCH 0372/4131] removed dosbox.lang Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@450 --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 98140498..151e5e04 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,4 +7,4 @@ bin_PROGRAMS = dosbox dosbox_SOURCES = dosbox.cpp dosbox_LDADD = cpu/libcpu.a debug/libdebug.a dos/libdos.a fpu/libfpu.a hardware/libhardware.a gui/libgui.a \ ints/libints.a misc/libmisc.a shell/libshell.a -lcurses -lpng -EXTRA_DIST = dosbox.lang + From 34c9a28c3ee373d66e357cd64c43bb50bf0b8858 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 26 Oct 2002 15:43:26 +0000 Subject: [PATCH 0373/4131] Idle a bit while checking for a keystroke. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@451 --- src/ints/bios_keyboard.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 3fcc4475..1d17a9e7 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -302,6 +302,7 @@ static Bitu INT16_Handler(void) { case 0x11: temp=check_key(); if (temp==0) { + flags.intf=true;CALLBACK_Idle(); CALLBACK_SZF(true); } else { CALLBACK_SZF(false); From c2b1f89fa2e6804bd7f16e608f5245f9a55a8431 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 27 Oct 2002 10:48:47 +0000 Subject: [PATCH 0374/4131] int 8 is now saving ds,dx,ax before calling int 1c Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@452 --- src/ints/bios.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 64c80207..a3c5db35 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -104,9 +104,19 @@ static Bitu INT8_Handler(void) { /* decrease floppy motor timer */ Bit8u val = mem_readb(BIOS_DISK_MOTOR_TIMEOUT); if (val>0) mem_writeb(BIOS_DISK_MOTOR_TIMEOUT,val-1); - + /* and running drive */ + mem_writeb(BIOS_DRIVE_RUNNING,mem_readb(BIOS_DRIVE_RUNNING) & 0xF0); + // Save ds,dx,ax + Bit16u oldds = SegValue(ds); + Bit16u olddx = reg_dx; + Bit16u oldax = reg_ax; + // run int 1c CALLBACK_RunRealInt(0x1c); IO_Write(0x20,0x20); + // restore old values + SegSet16(ds,oldds); + reg_dx = olddx; + reg_ax = oldax; return CBRET_NONE; }; From dfb87ec9e3750357cbab277e173456d5bbe3c9ec Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 27 Oct 2002 21:31:43 +0000 Subject: [PATCH 0375/4131] Added 0xb2, LSS instruction. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@453 --- src/cpu/core_16/prefix_of.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h index 3e3a4b4b..dc99459c 100644 --- a/src/cpu/core_16/prefix_of.h +++ b/src/cpu/core_16/prefix_of.h @@ -251,7 +251,12 @@ switch(Fetchb()) { } /* 0xb0 CMPXCHG Eb,Gb */ /* 0xb1 CMPXCHG Ew,Gw */ - /* 0xb2 LSS */ + case 0xb2: /* LSS */ + { + GetRMrw;GetEAa; + *rmrw=LoadMw(eaa);SegSet16(ss,LoadMw(eaa+2)); + break; + } case 0xb3: /* BTR Ew,Gw */ { GetRMrw; From 69ad2dee2dc2ee628889a2da18051c7e891b079a Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 28 Oct 2002 14:30:11 +0000 Subject: [PATCH 0376/4131] + draw mouse pointer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@454 --- src/ints/int10.h | 2 + src/ints/int10_modes.cpp | 12 +++ src/ints/mouse.cpp | 181 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 193 insertions(+), 2 deletions(-) diff --git a/src/ints/int10.h b/src/ints/int10.h index 41ae488c..9ccc3a65 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -200,6 +200,8 @@ void INT10_GetSingleDacRegister(Bit8u index,Bit8u * red,Bit8u * green,Bit8u * bl void INT10_SetDACBlock(Bit16u index,Bit16u count,PhysPt data); void INT10_GetDACBlock(Bit16u index,Bit16u count,PhysPt data); +/* Mouse pointer */ +void INT10_SetGfxControllerToDefault(void); /* Sup Groups */ void INT10_SetupRomMemory(void); diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 7932d2b4..d34155f0 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -411,3 +411,15 @@ void INT10_SetVideoMode(Bit8u mode) { /* Set some interrupt vectors */ RealSetVec(0x43,int10_romarea.font_8_first); }; + +void INT10_SetGfxControllerToDefault() +// reset gfx controller to default values +// needed for drawing mouse pointer +{ + Bit8u line=FindVideoMode(real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)&127); + // Set Grafx Ctl + for(Bit8u i=0;i<=GRDC_MAX_REG;i++) { + IO_Write(VGAREG_GRDC_ADDRESS,(Bit8u)i); + IO_Write(VGAREG_GRDC_DATA,grdc_regs[vga_modes[line].grdcmodel][i]); + } +}; \ No newline at end of file diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index ad3a084b..8b68ff1f 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -40,6 +40,27 @@ struct button_event { #define POS_X (Bit16s)(mouse.x) #define POS_Y (Bit16s)(mouse.y) +#define CURSORX 16 +#define CURSORY 16 +#define HIGHESTBIT (1<<(CURSORX-1)) + +static Bit16u defaultScreenMask[CURSORY] = { + 0x3FFF, 0x1FFF, 0x0FFF, 0x07FF, + 0x03FF, 0x01FF, 0x00FF, 0x007F, + 0x003F, 0x001F, 0x01FF, 0x00FF, + 0x30FF, 0xF87F, 0xF87F, 0xFCFF +}; + +static Bit16u defaultCursorMask[CURSORY] = { + 0x0000, 0x4000, 0x6000, 0x7000, + 0x7800, 0x7C00, 0x7E00, 0x7F00, + 0x7F80, 0x7C00, 0x6C00, 0x4600, + 0x0600, 0x0300, 0x0300, 0x0000 +}; + +static Bit16u userdefScreenMask[CURSORY]; +static Bit16u userdefCursorMask[CURSORY]; + static struct { Bit16u buttons; Bit16u times_pressed[MOUSE_BUTTONS]; @@ -57,6 +78,14 @@ static struct { Bit32u events; Bit16u sub_seg,sub_ofs; Bit16u sub_mask; + + bool background; + Bit16s backposx, backposy; + Bit8u backData[CURSORX*CURSORY]; + Bit16u* screenMask; + Bit16u* cursorMask; + Bit16s clipx,clipy; + Bit16s hotx,hoty; } mouse; #define X_MICKEY 8 @@ -79,8 +108,138 @@ INLINE void Mouse_AddEvent(Bit16u type) { PIC_ActivateIRQ(12); } -static void DrawCursor() { +static gfxReg[9]; + +void SaveVgaRegisters() +{ + for (int i=0; i<9; i++) { + IO_Write (0x3CE,i); + gfxReg[i] = IO_Read(0x3CF); + }; + // Set default + INT10_SetGfxControllerToDefault(); +}; + +void RestoreVgaRegisters() +{ + for (int i=0; i<9; i++) { + IO_Write(0x3CE,i); + IO_Write(0x3CF,gfxReg[i]); + }; +}; + +void ClipCursorArea(Bit16s& x1, Bit16s& x2, Bit16s& y1, Bit16s& y2, Bit16u& addx1, Bit16u& addx2, Bit16u& addy) +{ + addx1 = addx2 = addy = 0; + // Clip up + if (y1<0) { + addy += (-y1); + y1 = 0; + } + // Clip down + if (y2>mouse.clipy) { + y2 = mouse.clipy; + }; + // Clip left + if (x1<0) { + addx1 += (-x1); + x1 = 0; + }; + // Clip right + if (x2>mouse.clipx) { + addx2 = x2 - mouse.clipx; + x2 = mouse.clipx; + }; +}; + +void RestoreCursorBackground() +{ if (mouse.shown<0) return; + + SaveVgaRegisters(); + if (mouse.background) { + // Restore background + Bit16s x,y; + Bit16u addx1,addx2,addy; + Bit16u dataPos = 0; + Bit16s x1 = mouse.backposx; + Bit16s y1 = mouse.backposy; + Bit16s x2 = x1 + CURSORX - 1; + Bit16s y2 = y1 + CURSORY - 1; + + ClipCursorArea(x1, x2, y1, y2, addx1, addx2, addy); + + dataPos = addy * CURSORX; + for (y=y1; y<=y2; y++) { + dataPos += addx1; + for (x=x1; x<=x2; x++) { + INT10_PutPixel(x,y,0,mouse.backData[dataPos++]); + }; + dataPos += addx2; + }; + mouse.background = false; + }; + RestoreVgaRegisters(); +}; + +void DrawCursor() { + + if (mouse.shown<0) return; + + // Get Clipping ranges + VGAMODES * curmode=GetCurrentMode(); + if (!curmode) return; + mouse.clipx = curmode->swidth-1; + mouse.clipy = curmode->sheight-1; + + RestoreCursorBackground(); + + SaveVgaRegisters(); + + // Save Background + Bit16s x,y; + Bit16u addx1,addx2,addy; + Bit16u dataPos = 0; + Bit16s x1 = POS_X - mouse.hotx; + Bit16s y1 = POS_Y - mouse.hoty; + Bit16s x2 = x1 + CURSORX - 1; + Bit16s y2 = y1 + CURSORY - 1; + + ClipCursorArea(x1,x2,y1,y2, addx1, addx2, addy); + + dataPos = addy * CURSORX; + for (y=y1; y<=y2; y++) { + dataPos += addx1; + for (x=x1; x<=x2; x++) { + INT10_GetPixel(x,y,0,&mouse.backData[dataPos++]); + }; + dataPos += addx2; + }; + mouse.background= true; + mouse.backposx = POS_X - mouse.hotx; + mouse.backposy = POS_Y - mouse.hoty; + + // Draw Mousecursor + dataPos = addy * CURSORX; + for (y=y1; y<=y2; y++) { + Bit16u scMask = mouse.screenMask[addy+y-y1]; + Bit16u cuMask = mouse.cursorMask[addy+y-y1]; + if (addx1>0) { scMask<<=addx1; cuMask<<=addx1; dataPos += addx1; }; + for (x=x1; x<=x2; x++) { + Bit8u pixel = 0; + // ScreenMask + if (scMask & HIGHESTBIT) pixel = mouse.backData[dataPos]; + scMask<<=1; + // CursorMask + if (cuMask & HIGHESTBIT) pixel = pixel ^ 0x0F; + cuMask<<=1; + // Set Pixel + INT10_PutPixel(x,y,0,pixel); + dataPos++; + }; + dataPos += addx2; + }; + RestoreVgaRegisters(); } void Mouse_CursorMoved(float x,float y) { @@ -158,6 +317,12 @@ static void mouse_reset(void) { mouse.sub_mask=0; mouse.sub_seg=0; mouse.sub_ofs=0; + + mouse.hotx = 0; + mouse.hoty = 0; + mouse.background = false; + mouse.screenMask = defaultScreenMask; + mouse.cursorMask = defaultCursorMask; } @@ -172,8 +337,10 @@ static Bitu INT33_Handler(void) { case 0x01: /* Show Mouse */ mouse.shown++; if (mouse.shown>0) mouse.shown=0; + DrawCursor(); break; case 0x02: /* Hide Mouse */ + RestoreCursorBackground(); mouse.shown--; break; case 0x03: /* Return position and Button Status */ @@ -184,6 +351,7 @@ static Bitu INT33_Handler(void) { case 0x04: /* Position Mouse */ mouse.x=(float)reg_cx; mouse.y=(float)reg_dx; + DrawCursor(); break; case 0x05: /* Return Button Press Data */ { @@ -220,7 +388,16 @@ static Bitu INT33_Handler(void) { mouse.max_y=reg_dx; break; case 0x09: /* Define GFX Cursor */ - LOG_WARN("MOUSE:Define gfx cursor not supported"); + { + PhysPt src = SegPhys(es)+reg_dx; + MEM_BlockRead(src ,userdefScreenMask,CURSORY*2); + MEM_BlockRead(src+CURSORY*2,userdefCursorMask,CURSORY*2); + mouse.screenMask = userdefScreenMask; + mouse.cursorMask = userdefCursorMask; + mouse.hotx = reg_bx; + mouse.hoty = reg_cx; + DrawCursor(); + } break; case 0x0a: /* Define Text Cursor */ /* Don't see much need for supporting this */ From 3dfafb6dde7fdb734c4f8b3a321795504613e22c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 28 Oct 2002 14:37:51 +0000 Subject: [PATCH 0377/4131] Changed vga attribute handling to vga dac registers. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@455 --- src/hardware/vga.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/vga.h b/src/hardware/vga.h index d43dc8ed..1ebc643f 100644 --- a/src/hardware/vga.h +++ b/src/hardware/vga.h @@ -80,6 +80,7 @@ typedef struct { bool resizing; Bitu width; Bitu height; + Bit8u * font; Bit8u font_height; Bit8u cursor_enable; Bit8u cursor_row; @@ -157,7 +158,6 @@ struct RGBEntry { Bit8u red; Bit8u green; Bit8u blue; - Bit8u attr_entry; }; typedef struct { @@ -168,6 +168,7 @@ typedef struct { Bit8u index; Bitu first_changed; RGBEntry rgb[0x100]; + Bit8u attr[16]; } VGA_Dac; union VGA_Latch { @@ -244,7 +245,7 @@ void VGA_SetupSEQ(void); void VGA_DACSetEntirePalette(void); extern VGA_Type vga; -extern Bit8u vga_rom_8[256 * 8]; +extern Bit8u vga_rom_08[256 * 8]; extern Bit8u vga_rom_14[256 * 14]; extern Bit8u vga_rom_16[256 * 16]; @@ -260,6 +261,5 @@ extern Bit32u Expand16BigTable[0x10000]; #define LOG_VGA #endif - #endif From 2bc9299c3b917a0719b72f7c573f99e080c7e962 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 28 Oct 2002 14:38:23 +0000 Subject: [PATCH 0378/4131] Fixed attribtes to only use the lower 6 bits. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@456 --- src/hardware/vga_attr.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 3d4c6b9d..953b4521 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -40,6 +40,7 @@ void write_p3c0(Bit32u port,Bit8u val) { case 0x04: case 0x05: case 0x06: case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: + val&=0x3f; attr(palette[attr(index)])=val; VGA_DAC_CombineColor(attr(index),val); /* From 3c26bb94da32cadd996099a5bce1d6da4afc8976 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 28 Oct 2002 14:39:50 +0000 Subject: [PATCH 0379/4131] Changed attribute and dac color checking. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@457 --- src/hardware/vga_dac.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index e6a5dcd1..d8e0ae2a 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -99,13 +99,13 @@ static void write_p3c9(Bit32u port,Bit8u val) { break; default: /* Check for attributes and DAC entry link */ - if (vga.dac.rgb[vga.dac.index].attr_entry>15) return; - if (vga.attr.palette[vga.dac.rgb[vga.dac.index].attr_entry]==vga.dac.index) { - RENDER_SetPal(vga.dac.rgb[vga.dac.index].attr_entry, + for (Bitu i=0;i<16;i++) { + if (vga.dac.attr[i]==vga.dac.index) { + RENDER_SetPal(i, vga.dac.rgb[vga.dac.index].red << 2, vga.dac.rgb[vga.dac.index].green << 2, - vga.dac.rgb[vga.dac.index].blue << 2 - ); + vga.dac.rgb[vga.dac.index].blue << 2); + } } } vga.dac.index++; @@ -140,7 +140,8 @@ static Bit8u read_p3c9(Bit32u port) { void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal) { /* Check if this is a new color */ - vga.dac.rgb[pal].attr_entry=attr; + vga.dac.attr[attr]=pal; + if (vga.mode != GFX_256U && vga.mode != GFX_256C) RENDER_SetPal(attr, vga.dac.rgb[pal].red << 2, vga.dac.rgb[pal].green << 2, From 4bc7a382fa884d005f26bf465696535fa5a0a19c Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 28 Oct 2002 16:37:08 +0000 Subject: [PATCH 0380/4131] + textmode mouse cursor Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@458 --- src/ints/mouse.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 3 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 8b68ff1f..27bda07e 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -44,6 +44,9 @@ struct button_event { #define CURSORY 16 #define HIGHESTBIT (1<<(CURSORX-1)) +static Bit16u defaultTextAndMask = 0x77FF; +static Bit16u defaultTextXorMask = 0x7700; + static Bit16u defaultScreenMask[CURSORY] = { 0x3FFF, 0x1FFF, 0x0FFF, 0x07FF, 0x03FF, 0x01FF, 0x00FF, 0x007F, @@ -86,6 +89,7 @@ static struct { Bit16u* cursorMask; Bit16s clipx,clipy; Bit16s hotx,hoty; + Bit16u textAndMask, textXorMask; } mouse; #define X_MICKEY 8 @@ -108,6 +112,58 @@ INLINE void Mouse_AddEvent(Bit16u type) { PIC_ActivateIRQ(12); } +// *************************************************************************** +// Mouse cursor - text mode +// *************************************************************************** + +void RestoreCursorBackgroundText() +{ + if (mouse.shown<0) return; + + if (mouse.background) { + // Save old Cursorposition + Bit8u oldx = CURSOR_POS_ROW(0); + Bit8u oldy = CURSOR_POS_COL(0); + // Restore background + INT10_SetCursorPos ((Bit8u)mouse.backposy,(Bit8u)mouse.backposx,0); + INT10_WriteChar (mouse.backData[0],mouse.backData[1],0,1,true); + // Restore old cursor position + INT10_SetCursorPos (oldx,oldy,0); + mouse.background = false; + } +}; + +void DrawCursorText() +{ + // Restore Background + RestoreCursorBackgroundText(); + + // Save old Cursorposition + Bit8u oldx = CURSOR_POS_ROW(0); + Bit8u oldy = CURSOR_POS_COL(0); + + // Save Background + Bit16u result; + INT10_SetCursorPos (POS_Y>>3,POS_X>>3,0); + INT10_ReadCharAttr (&result,0); + mouse.backData[0] = result & 0xFF; + mouse.backData[1] = result>>8; + mouse.backposx = POS_X>>3; + mouse.backposy = POS_Y>>3; + mouse.background = true; + + // Write Cursor + result = (result & mouse.textAndMask) ^ mouse.textXorMask; + INT10_WriteChar (result&0xFF,result>>8,0,1,true); + + // Restore old cursor position + INT10_SetCursorPos (oldx,oldy,0); +}; + +// *************************************************************************** +// Mouse cursor - graphic mode +// *************************************************************************** + static gfxReg[9]; void SaveVgaRegisters() @@ -189,6 +245,13 @@ void DrawCursor() { // Get Clipping ranges VGAMODES * curmode=GetCurrentMode(); if (!curmode) return; + + // In Textmode ? + if (curmode->type==TEXT) { + DrawCursorText(); + return; + } + mouse.clipx = curmode->swidth-1; mouse.clipy = curmode->sheight-1; @@ -323,6 +386,8 @@ static void mouse_reset(void) { mouse.background = false; mouse.screenMask = defaultScreenMask; mouse.cursorMask = defaultCursorMask; + mouse.textAndMask= defaultTextAndMask; + mouse.textXorMask= defaultTextXorMask; } @@ -340,8 +405,12 @@ static Bitu INT33_Handler(void) { DrawCursor(); break; case 0x02: /* Hide Mouse */ - RestoreCursorBackground(); - mouse.shown--; + { + VGAMODES * curmode=GetCurrentMode(); + if (curmode && curmode->type==GRAPH) RestoreCursorBackground(); + else RestoreCursorBackgroundText(); + mouse.shown--; + } break; case 0x03: /* Return position and Button Status */ reg_bx=mouse.buttons; @@ -400,7 +469,8 @@ static Bitu INT33_Handler(void) { } break; case 0x0a: /* Define Text Cursor */ - /* Don't see much need for supporting this */ + mouse.textAndMask = reg_cx; + mouse.textXorMask = reg_dx; break; case 0x0c: /* Define interrupt subroutine parameters */ mouse.sub_mask=reg_cx; From 63cd877bab3f9f529f792a4afa0912e9db55cc5f Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 28 Oct 2002 20:32:47 +0000 Subject: [PATCH 0381/4131] fixed a bug in DOS_ChangeDir: if dir is a file - return false Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@459 --- src/dos/dos_files.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 99217e38..5c3be2d7 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -150,8 +150,16 @@ bool DOS_GetCurrentDir(Bit8u drive,char * buffer) { } bool DOS_ChangeDir(char * dir) { + + // Be sure its not a file (Eye of the beholder 3) + char* str; + if (str=strchr(dir,'.')) { + if (isalpha(str[1]) || isdigit(str[1])) return false; + }; + Bit8u drive;char fulldir[DOS_PATHLENGTH]; if (!DOS_MakeName(dir,fulldir,&drive)) return false; + if (Drives[drive]->TestDir(fulldir)) { strcpy(Drives[drive]->curdir,fulldir); return true; From 7cdf73a07ee5735351146ae9f5531123a08c2048 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 28 Oct 2002 22:15:02 +0000 Subject: [PATCH 0382/4131] Add 4 color cga mode scrolling. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@460 --- src/ints/int10_char.cpp | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 1d6f4a0d..82449517 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -24,6 +24,17 @@ #include "inout.h" #include "int10.h" +static INLINE void CGA_CopyRow(VGAMODES * curmode,Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { + PhysPt dest=base+((curmode->twidth*rnew)*(curmode->cheight/2)+cleft)*2; + PhysPt src=base+((curmode->twidth*rold)*(curmode->cheight/2)+cleft)*2; + Bitu copy=(cright-cleft)*2;Bitu nextline=curmode->twidth*2; + for (Bits i=0;icheight/2;i++) { + MEM_BlockCopy(dest,src,copy); + MEM_BlockCopy(dest+8*1024,src+8*1024,copy); + dest+=nextline;src+=nextline; + } +} + static INLINE void PLANAR4_CopyRow(VGAMODES * curmode,Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { PhysPt src,dest;Bitu copy; dest=base+(curmode->twidth*rnew)*curmode->cheight+cleft; @@ -38,7 +49,6 @@ static INLINE void PLANAR4_CopyRow(VGAMODES * curmode,Bit8u cleft,Bit8u cright,B for (;copy>0;copy--) { for (Bitu x=0;xtwidth*row)*(curmode->cheight/2)+cleft)*2; + Bitu copy=(cright-cleft)*2;Bitu nextline=curmode->twidth*2; + for (Bits i=0;icheight/2;i++) { + for (Bitu x=0;xrlr) return; @@ -116,9 +137,10 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit case MTEXT: case CTEXT: TEXT_CopyRow(curmode,cul,clr,start,start+nlines,base);break; + case CGA: + CGA_CopyRow(curmode,cul,clr,start,start+nlines,base);break; case PLANAR4: PLANAR4_CopyRow(curmode,cul,clr,start,start+nlines,base);break; - } } while (start!=end); /* Fill some lines */ @@ -134,6 +156,8 @@ filling: case MTEXT: case CTEXT: TEXT_FillRow(curmode,cul,clr,start,base,attr);break; + case CGA: + CGA_FillRow(curmode,cul,clr,start,base,attr);break; case PLANAR4: PLANAR4_FillRow(curmode,cul,clr,start,base,attr);break; } @@ -260,9 +284,6 @@ INLINE static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u at } } - - - void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) { if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); Bit8u cur_row=CURSOR_POS_ROW(page); From d565b8c5260a4f04aceefa1bc9362531830e6731 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 28 Oct 2002 23:45:55 +0000 Subject: [PATCH 0383/4131] Added t_SHARd in the get_AF group, changed the fatal errors to warnings and regrouped some flags into unknown groups. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@461 --- src/cpu/flags.cpp | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 02d41694..6e78c3e6 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -46,7 +46,6 @@ bool get_CF(void) { case t_RCLd: return flags.cf; break; - case t_ADDb: return (flags.result.b=0x80000000); case t_DIV: case t_MUL: - return false; + return false; /* Unkown */ default: - E_Exit("get_SF Unkown %d",flags.type); + LOG_WARN("get_SF Unkown %d",flags.type); } return false; @@ -419,6 +416,9 @@ again: case t_RCLb: case t_RCLw: case t_RCLd: + case t_SARb: + case t_SARw: + case t_SARd: return flags.of; case t_CF: type=flags.prev_type; @@ -523,9 +523,6 @@ again: return (flags.result.w >= 0x4000); case t_SHRd: return (flags.result.d >= 0x40000000); - case t_SARb: - case t_SARw: - case t_SARd: case t_ORb: case t_ORw: case t_ORd: @@ -538,10 +535,11 @@ again: case t_TESTb: case t_TESTw: case t_TESTd: + return false; /* Return false */ case t_DIV: - return false; + return false; /* Unkown */ default: - E_Exit("get_OF Unkown %d",flags.type); + LOG_WARN("get_OF Unkown %d",flags.type); } return false; } From 63210c1d64bd63005ef9ed0b613abcb0346a9dd8 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 29 Oct 2002 14:40:54 +0000 Subject: [PATCH 0384/4131] Added new debug commands : set register/memory. Fixed a problem with relative jump addresses Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@462 --- src/debug/debug.cpp | 66 ++++++++++++++++++++++++++++++++++++++ src/debug/debug_disasm.cpp | 11 ++++--- 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 29c0dbe5..f73bac69 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -591,6 +591,46 @@ Bit32u GetHexValue(char* str, char*& hex) return value; }; +bool ChangeRegister(char* str) +{ + Bit32u value = 0; + + char* hex = str; + while (*hex==' ') hex++; + if (strstr(hex,"AX")==hex) { hex+=2; reg_ax = GetHexValue(hex,hex); } else + if (strstr(hex,"BX")==hex) { hex+=2; reg_bx = GetHexValue(hex,hex); } else + if (strstr(hex,"CX")==hex) { hex+=2; reg_cx = GetHexValue(hex,hex); } else + if (strstr(hex,"DX")==hex) { hex+=2; reg_dx = GetHexValue(hex,hex); } else + if (strstr(hex,"SI")==hex) { hex+=2; reg_si = GetHexValue(hex,hex); } else + if (strstr(hex,"DI")==hex) { hex+=2; reg_di = GetHexValue(hex,hex); } else + if (strstr(hex,"BP")==hex) { hex+=2; reg_bp = GetHexValue(hex,hex); } else + if (strstr(hex,"SP")==hex) { hex+=2; reg_sp = GetHexValue(hex,hex); } else + if (strstr(hex,"IP")==hex) { hex+=2; reg_ip = GetHexValue(hex,hex); } else + if (strstr(hex,"CS")==hex) { hex+=2; SegSet16(cs,GetHexValue(hex,hex)); } else + if (strstr(hex,"DS")==hex) { hex+=2; SegSet16(ds,GetHexValue(hex,hex)); } else + if (strstr(hex,"ES")==hex) { hex+=2; SegSet16(es,GetHexValue(hex,hex)); } else + if (strstr(hex,"FS")==hex) { hex+=2; SegSet16(fs,GetHexValue(hex,hex)); } else + if (strstr(hex,"GS")==hex) { hex+=2; SegSet16(gs,GetHexValue(hex,hex)); } else + if (strstr(hex,"SS")==hex) { hex+=2; SegSet16(ss,GetHexValue(hex,hex)); } else + if (strstr(hex,"EAX")==hex) { hex+=3; reg_eax = GetHexValue(hex,hex); } else + if (strstr(hex,"EBX")==hex) { hex+=3; reg_ebx = GetHexValue(hex,hex); } else + if (strstr(hex,"ECX")==hex) { hex+=3; reg_ecx = GetHexValue(hex,hex); } else + if (strstr(hex,"EDX")==hex) { hex+=3; reg_edx = GetHexValue(hex,hex); } else + if (strstr(hex,"ESI")==hex) { hex+=3; reg_esi = GetHexValue(hex,hex); } else + if (strstr(hex,"EDI")==hex) { hex+=3; reg_edi = GetHexValue(hex,hex); } else + if (strstr(hex,"EBP")==hex) { hex+=3; reg_ebp = GetHexValue(hex,hex); } else + if (strstr(hex,"ESP")==hex) { hex+=3; reg_esp = GetHexValue(hex,hex); } else + if (strstr(hex,"EIP")==hex) { hex+=3; reg_eip = GetHexValue(hex,hex); } else + if (strstr(hex,"AF")==hex) { hex+=2; flags.af = (GetHexValue(hex,hex)!=0); } else + if (strstr(hex,"CF")==hex) { hex+=2; flags.cf = (GetHexValue(hex,hex)!=0); } else + if (strstr(hex,"DF")==hex) { hex+=2; flags.df = (GetHexValue(hex,hex)!=0); } else + if (strstr(hex,"IF")==hex) { hex+=2; flags.intf = (GetHexValue(hex,hex)!=0); } else + if (strstr(hex,"OF")==hex) { hex+=3; flags.of = (GetHexValue(hex,hex)!=0); } else + if (strstr(hex,"PF")==hex) { hex+=3; flags.pf = (GetHexValue(hex,hex)!=0); } else + { return false; }; + return true; +}; + bool ParseCommand(char* str) { char* found = str; @@ -666,6 +706,30 @@ bool ParseCommand(char* str) LOG_DEBUG("DEBUG: Logfile LOGCPU.TXT created."); return true; } + found = strstr(str,"SR "); + if (found) { // Set register value + found+=2; + if (ChangeRegister(found)) LOG_DEBUG("DEBUG: Set Register success."); + else LOG_DEBUG("DEBUG: Set Register failure."); + return true; + } + found = strstr(str,"SM "); + if (found) { // Set memory with following values + found+=3; + Bit16u seg = GetHexValue(found,found); found++; + Bit32u ofs = GetHexValue(found,found); found++; + Bit16u count = 0; + while (*found) { + while (*found==' ') found++; + if (*found) { + Bit8u value = GetHexValue(found,found); found++; + mem_writeb(PhysMake(seg,ofs+count),value); + count++; + } + }; + LOG_DEBUG("DEBUG: Memory changed."); + return true; + } found = strstr(str,"INTT "); if (found) { // Create Cpu log file found+=4; @@ -708,6 +772,8 @@ bool ParseCommand(char* str) wprintw(dbg.win_out,"C / D [segment]:[offset] - Set code / data view address\n"); wprintw(dbg.win_out,"INT [nr] / INTT [nr] - Execute / Trace into Iinterrupt\n"); wprintw(dbg.win_out,"LOG [num] - Write cpu log file\n"); + wprintw(dbg.win_out,"SR [reg] [value] - Set register value\n"); + wprintw(dbg.win_out,"SM [seg]:[off] [val] [.]..- Set memory with following values\n"); wprintw(dbg.win_out,"H - Help\n"); wrefresh(dbg.win_out); return TRUE; diff --git a/src/debug/debug_disasm.cpp b/src/debug/debug_disasm.cpp index 42cd96db..00076d1a 100644 --- a/src/debug/debug_disasm.cpp +++ b/src/debug/debug_disasm.cpp @@ -457,7 +457,7 @@ static char *addr_to_hex(UINT32 addr, int splitup) { } static PhysPt getbyte_mac; - +static PhysPt startPtr; static UINT8 getbyte(void) { return mem_readb(getbyte_mac++); @@ -822,6 +822,8 @@ static void floating_point(int e1) /*------------------------------------------------------------------------*/ /* Main table driver */ +#define INSTRUCTION_SIZE (int)getbyte_mac - (int)startPtr + static void percent(char type, char subtype) { INT32 vofs = 0; @@ -864,13 +866,13 @@ static void percent(char type, char subtype) switch (bytes(subtype)) { /* sizeof offset value */ case 1: vofs = (INT8)getbyte(); - name = addr_to_hex(vofs+instruction_offset,0); + name = addr_to_hex(vofs+instruction_offset+INSTRUCTION_SIZE,0); break; case 2: vofs = getbyte(); vofs += getbyte()<<8; vofs = (INT16)vofs; - name = addr_to_hex(vofs+instruction_offset,0); + name = addr_to_hex(vofs+instruction_offset+INSTRUCTION_SIZE,0); break; #if 0 /* i386 */ @@ -879,7 +881,7 @@ static void percent(char type, char subtype) vofs |= (UINT32)getbyte() << 8; vofs |= (UINT32)getbyte() << 16; vofs |= (UINT32)getbyte() << 24; - name = addr_to_hex(vofs+instruction_offset,1); + name = addr_to_hex(vofs+instruction_offset+INSTRUCTION_SIZE,1); break; #endif } @@ -1077,6 +1079,7 @@ Bitu DasmI386(char* buffer, PhysPt pc, Bitu cur_ip, bool bit32) instruction_offset = cur_ip; /* input buffer */ + startPtr = pc; getbyte_mac = pc; /* output buffer */ From 48750dfa8ff0a87292f3cd8bd2a1815fa713261b Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 30 Oct 2002 14:41:50 +0000 Subject: [PATCH 0385/4131] fixed bugs with bplist and debug.com (allocate stack space) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@463 --- src/debug/debug.cpp | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index f73bac69..e89a66b1 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -355,7 +355,7 @@ void CBreakpoint::ShowList(void) if (bp->GetType()==BKPNT_PHYSICAL) { PhysPt adr = bp->GetLocation(); - wprintw(dbg.win_out,"%02X. BP %04X:%04X\n",nr,bp->GetSegment(),bp->GetOffset); + wprintw(dbg.win_out,"%02X. BP %04X:%04X\n",nr,bp->GetSegment(),bp->GetOffset()); nr++; } else if (bp->GetType()==BKPNT_INTERRUPT) { if (bp->GetValue()==BPINT_ALL) wprintw(dbg.win_out,"%02X. BPINT %02X\n",nr,bp->GetIntNr()); @@ -993,8 +993,28 @@ public: strncpy(args,temp_line.c_str(),128); // Start new shell and execute prog active = true; - DOS_Shell shell; - shell.Execute(filename,args); + // Save cpu state.... + Bit16u oldcs = SegValue(cs); + Bit32u oldeip = reg_eip; + Bit16u oldss = SegValue(ss); + Bit32u oldesp = reg_esp; + + // Workaround : Allocate Stack Space + Bit16u segment; + Bit16u size = 0x200 / 0x10; + if (DOS_AllocateMemory(&segment,&size)) { + SegSet16(ss,segment); + reg_sp = 0x200; + // Start shell + DOS_Shell shell; + shell.Execute(filename,args); + DOS_FreeMemory(segment); + } + // set old reg values + SegSet16(ss,oldss); + reg_esp = oldesp; + SegSet16(cs,oldcs); + reg_eip = oldeip; }; private: From 25692864a98d99b1d01ac4a78531adb3e3d715b6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 30 Oct 2002 18:47:40 +0000 Subject: [PATCH 0386/4131] chanded fcb-parsename to update si in stead of di Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@464 --- src/dos/dos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 35533f65..d289ce14 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -253,7 +253,7 @@ static Bitu DOS_21Handler(void) { char string[1024]; MEM_StrCopy(SegPhys(ds)+reg_si,string,1024); reg_al=FCB_Parsename(SegValue(es),reg_di,reg_al ,string, &difference); - reg_di+=difference; + reg_si+=difference; } LOG_DEBUG("DOS:29:FCB Parse Filename, result:al=%d",reg_al); break; From 46a1e79f94e4bd381a28f59ebaf8d2495f8b3499 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 30 Oct 2002 18:49:44 +0000 Subject: [PATCH 0387/4131] added full line support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@465 --- include/setup.h | 3 ++- src/misc/setup.cpp | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/setup.h b/include/setup.h index 865165fc..868fb1a7 100644 --- a/include/setup.h +++ b/include/setup.h @@ -30,7 +30,7 @@ public: CommandLine(int argc,char * argv[]); CommandLine(char * name,char * cmdline); const char * GetFileName(){ return file_name.c_str();} - + bool FindExist(char * name,bool remove=false); bool FindHex(char * name,int & value,bool remove=false); bool FindInt(char * name,int & value,bool remove=false); @@ -38,6 +38,7 @@ public: bool FindCommand(int which,std::string & value); bool FindStringBegin(char * begin,std::string & value, bool remove=false); int GetCount(void); + void CommandLine::GetFullLine( char * in); private: typedef std::list::iterator cmd_it; std::list cmds; diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 8846a6c0..b4b56c43 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -369,3 +369,13 @@ CommandLine::CommandLine(char * name,char * cmdline) { } if (inword || inquote) cmds.push_back(str); } + +void CommandLine::GetFullLine(char * in) { + cmd_it it; + *in=0; + char spatie[2]={' ',0}; + for (it=cmds.begin();it!=cmds.end();it++) { + strcat(in,spatie); + strcat(in,(*it).c_str()); + } +} From 3fa47d681314e7dbac2f1cd77101175b9c3b7c34 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 30 Oct 2002 18:54:59 +0000 Subject: [PATCH 0388/4131] added rename Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@466 --- src/shell/shell_cmds.cpp | 12 ++++++++++++ src/shell/shell_inc.h | 1 + 2 files changed, 13 insertions(+) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index fee0e18c..7481e163 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -38,6 +38,7 @@ static SHELL_Cmd cmd_list[]={ "GOTO", 0, &DOS_Shell::CMD_GOTO, "SHELL_CMD_GOTO_HELP", "TYPE", 0, &DOS_Shell::CMD_TYPE, "SHELL_CMD_TYPE_HELP", "REM", 0, &DOS_Shell::CMD_REM, "SHELL_CMD_REM_HELP", + "RENAME", 0, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP", /* "CHDIR", 0, &DOS_Shell::CMD_CHDIR, "Change Directory", @@ -91,6 +92,17 @@ void DOS_Shell::CMD_HELP(char * args){ } +void DOS_Shell::CMD_RENAME(char * args){ + if(!*args) {SyntaxError();return;} + if((strchr(args,'*')!=NULL) || (strchr(args,'?')!=NULL) ) { WriteOut(MSG_Get("SHELL_CMD_RENAME_WILD"));} + char * arg2 =StripWord(args); + DOS_Rename(args,arg2); +} + + + + + void DOS_Shell::CMD_ECHO(char * args) { if (!*args) { if (echo) { WriteOut(MSG_Get("SHELL_CMD_ECHO_ON"));} diff --git a/src/shell/shell_inc.h b/src/shell/shell_inc.h index 2396b013..fefd0d0b 100644 --- a/src/shell/shell_inc.h +++ b/src/shell/shell_inc.h @@ -76,6 +76,7 @@ public: void CMD_GOTO(char * args); void CMD_TYPE(char * args); void CMD_REM(char * args); + void CMD_RENAME(char * args); void SyntaxError(void); /* The shell's variables */ From 860ab63aee869472b24a27949515ced67ded88eb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 30 Oct 2002 19:02:15 +0000 Subject: [PATCH 0389/4131] added rename Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@467 --- src/shell/shell.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 1f7bed15..b99e3424 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -96,11 +96,15 @@ void DOS_Shell::ParseLine(char * line) { void DOS_Shell::Run(void) { char input_line[CMD_MAXLINE]; std::string line; - if (cmd->FindString("/C",line,true)) { - strcpy(input_line,line.c_str()); - line.erase(); - return; - } + + if (cmd->FindString("/C",line,false)) { + char command[256]; + cmd->GetFullLine(command); + char * blah=strstr(command, "/C"); + blah+=2; //add the size of "/C" + ParseLine(blah); + return; + } /* Start a normal shell and check for a first command init */ WriteOut(MSG_Get("SHELL_STARTUP")); if (cmd->FindString("/INIT",line,true)) { @@ -216,7 +220,8 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_GOTO_HELP","Jump to a labeled line in a batch script.\n"); MSG_Add("SHELL_CMD_TYPE_HELP","Display the contents of a text-file.\n"); MSG_Add("SHELL_CMD_REM_HELP","Add comments in a batch file.\n"); - + MSG_Add("SHELL_CMD_RENAME_WILD","This is a simple Rename, no wildcards allowed!\n"); + MSG_Add("SHELL_CMD_RENAME_HELP","Renames files.\n"); /* Regular startup */ call_shellstop=CALLBACK_Allocate(); From 98f3407fc473b1e593b1abd99f693ca3c22c5d39 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 31 Oct 2002 08:17:05 +0000 Subject: [PATCH 0390/4131] Fixed a variable without a type. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@468 --- src/ints/mouse.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 27bda07e..77556157 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -164,7 +164,7 @@ void DrawCursorText() // Mouse cursor - graphic mode // *************************************************************************** -static gfxReg[9]; +static Bit8u gfxReg[9]; void SaveVgaRegisters() { From 4543cc2d8f11796feb903c2dde69b6f04c5fce8b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 31 Oct 2002 15:16:27 +0000 Subject: [PATCH 0391/4131] Fixes to shell to correctly support /c command Fixed not saving cs:ip when executing a program Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@469 --- src/shell/shell.cpp | 23 ++++++++++++----------- src/shell/shell_cmds.cpp | 5 +++-- src/shell/shell_misc.cpp | 5 +++++ 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index b99e3424..8b405f23 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -79,7 +79,7 @@ void DOS_Shell::ParseLine(char * line) { char * fname1=0; /* Check for a leading @ */ - if (line[0]=='@') line[0]=' '; + if (line[0]=='@') line[0]=' '; line=trim(line); Bit32u num=0; /* Number of commands in this line */ @@ -97,14 +97,11 @@ void DOS_Shell::Run(void) { char input_line[CMD_MAXLINE]; std::string line; - if (cmd->FindString("/C",line,false)) { - char command[256]; - cmd->GetFullLine(command); - char * blah=strstr(command, "/C"); - blah+=2; //add the size of "/C" - ParseLine(blah); - return; - } + if (cmd->FindStringRemain("/C",line)) { + strcpy(input_line,line.c_str()); + ParseLine(input_line); + return; + } /* Start a normal shell and check for a first command init */ WriteOut(MSG_Get("SHELL_STARTUP")); if (cmd->FindString("/INIT",line,true)) { @@ -220,10 +217,14 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_GOTO_HELP","Jump to a labeled line in a batch script.\n"); MSG_Add("SHELL_CMD_TYPE_HELP","Display the contents of a text-file.\n"); MSG_Add("SHELL_CMD_REM_HELP","Add comments in a batch file.\n"); - MSG_Add("SHELL_CMD_RENAME_WILD","This is a simple Rename, no wildcards allowed!\n"); - MSG_Add("SHELL_CMD_RENAME_HELP","Renames files.\n"); + MSG_Add("SHELL_CMD_RENAME_WILD","This is a simple Rename, no wildcards allowed!\n"); + MSG_Add("SHELL_CMD_RENAME_HELP","Renames files.\n"); /* Regular startup */ call_shellstop=CALLBACK_Allocate(); + /* Setup the startup CS:IP to kill the last running machine when exitted */ + RealPt newcsip=CALLBACK_RealPointer(call_shellstop); + SegSet16(cs,RealSeg(newcsip)); + reg_ip=RealOff(newcsip); CALLBACK_Setup(call_shellstop,shellstop_handler,CB_IRET); PROGRAMS_MakeFile("COMMAND.COM",SHELL_ProgramStart); diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 7481e163..1604d4cb 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -38,8 +38,8 @@ static SHELL_Cmd cmd_list[]={ "GOTO", 0, &DOS_Shell::CMD_GOTO, "SHELL_CMD_GOTO_HELP", "TYPE", 0, &DOS_Shell::CMD_TYPE, "SHELL_CMD_TYPE_HELP", "REM", 0, &DOS_Shell::CMD_REM, "SHELL_CMD_REM_HELP", - "RENAME", 0, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP", - + "RENAME", 0, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP", + "REN", 0, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP", /* "CHDIR", 0, &DOS_Shell::CMD_CHDIR, "Change Directory", "MKDIR", 0, &DOS_Shell::CMD_MKDIR, "Make Directory", @@ -397,3 +397,4 @@ nextfile: void DOS_Shell::CMD_REM(char * args) { } + diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index c300d8ba..f245e7bc 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -168,6 +168,8 @@ void DOS_Shell::Execute(char * name,char * args) { block.exec.cmdtail=RealMakeSeg(ss,reg_sp+0x100); block.SaveData(); /* Save CS:IP to some point where i can return them from */ + Bit32u oldeip=reg_eip; + Bit16u oldcs=SegValue(cs); RealPt newcsip=CALLBACK_RealPointer(call_shellstop); SegSet16(cs,RealSeg(newcsip)); reg_ip=RealOff(newcsip); @@ -181,7 +183,10 @@ void DOS_Shell::Execute(char * name,char * args) { reg_bx=reg_sp; flags.intf=false; CALLBACK_RunRealInt(0x21); + /* Restore CS:IP and the stack */ reg_sp+=0x200; + reg_eip=oldeip; + SegSet16(cs,oldcs); } } From b226986fc39eff2b14adbc028831f9764b18da1d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 31 Oct 2002 15:17:51 +0000 Subject: [PATCH 0392/4131] Give internal programs 0x100 more stack space. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@470 --- src/misc/programs.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 2a9c93df..2fcaedb2 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -32,8 +32,8 @@ Bitu call_program; /* This registers a file on the virtual drive and creates the correct structure for it*/ static Bit8u exe_block[]={ - 0xbc,0x00,0x03, //MOV SP,0x300 decrease stack size - 0xbb,0x30,0x00, //MOV BX,0x030 for memory resize + 0xbc,0x00,0x04, //MOV SP,0x400 decrease stack size + 0xbb,0x40,0x00, //MOV BX,0x040 for memory resize 0xb4,0x4a, //MOV AH,0x4A Resize memory block 0xcd,0x21, //INT 0x21 //pos 12 is callback number @@ -70,7 +70,7 @@ static Bitu PROGRAMS_Handler(void) { new_program->Run(); delete new_program; return CBRET_NONE; -}; +} /* Main functions used in all program */ From 0485d33490a49e91b1efc7f23e95b347c60ef5b3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 31 Oct 2002 15:18:39 +0000 Subject: [PATCH 0393/4131] Added findstring remain function to shell and removed fullstring Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@471 --- include/setup.h | 2 +- src/misc/setup.cpp | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/include/setup.h b/include/setup.h index 868fb1a7..248acf7c 100644 --- a/include/setup.h +++ b/include/setup.h @@ -37,8 +37,8 @@ public: bool FindString(char * name,std::string & value,bool remove=false); bool FindCommand(int which,std::string & value); bool FindStringBegin(char * begin,std::string & value, bool remove=false); + bool FindStringRemain(char * name,std::string & value); int GetCount(void); - void CommandLine::GetFullLine( char * in); private: typedef std::list::iterator cmd_it; std::list cmds; diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index b4b56c43..fd69e7c8 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -325,6 +325,18 @@ bool CommandLine::FindStringBegin(char * begin,std::string & value, bool remove) return false; } +bool CommandLine::FindStringRemain(char * name,std::string & value) { + cmd_it it;value=""; + if (!FindEntry(name,it)) return false; + it++; + for (;it!=cmds.end();it++) { + value+=" "; + value+=(*it); + } + return true; +} + + int CommandLine::GetCount(void) { return cmds.size(); } @@ -370,12 +382,3 @@ CommandLine::CommandLine(char * name,char * cmdline) { if (inword || inquote) cmds.push_back(str); } -void CommandLine::GetFullLine(char * in) { - cmd_it it; - *in=0; - char spatie[2]={' ',0}; - for (it=cmds.begin();it!=cmds.end();it++) { - strcat(in,spatie); - strcat(in,(*it).c_str()); - } -} From 108e6efd323ede3791379bb663523a89c7344c01 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 1 Nov 2002 10:06:04 +0000 Subject: [PATCH 0394/4131] fixed a problem (stepping over breakpoints) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@472 --- src/debug/debug.cpp | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index e89a66b1..a4c92d43 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -145,6 +145,7 @@ private: bool once; static std::list BPoints; +public: static CBreakpoint* ignoreOnce; }; @@ -194,7 +195,6 @@ CBreakpoint* CBreakpoint::AddIntBreakpoint(Bit8u intNum, Bit16u ah, bool once) void CBreakpoint::ActivateBreakpoints(PhysPt adr, bool activate) { - ignoreOnce = 0; // activate all breakpoints std::list::iterator i; CBreakpoint* bp; @@ -202,7 +202,7 @@ void CBreakpoint::ActivateBreakpoints(PhysPt adr, bool activate) bp = static_cast(*i); // Do not activate, when bp is an actual adress if (activate && (bp->GetType()==BKPNT_PHYSICAL) && (bp->GetLocation()==adr)) { - ignoreOnce = bp; + // Do not activate :) continue; } bp->Activate(activate); @@ -212,24 +212,27 @@ void CBreakpoint::ActivateBreakpoints(PhysPt adr, bool activate) bool CBreakpoint::CheckBreakpoint(PhysPt adr) // Checks if breakpoint is valid an should stop execution { - // if breakpoint is same address as started, it's not valid... - if (ignoreOnce) { - ignoreOnce->Activate(true); - ignoreOnce = 0; - } // Search matching breakpoint std::list::iterator i; CBreakpoint* bp; for(i=BPoints.begin(); i != BPoints.end(); i++) { bp = static_cast(*i); if ((bp->GetType()==BKPNT_PHYSICAL) && bp->IsActive() && (bp->GetLocation()==adr)) { + // Ignore Once ? + if (ignoreOnce==bp) { + ignoreOnce=0; + bp->Activate(true); + return false; + }; // Found, if (bp->GetOnce()) { // delete it, if it should only be used once (BPoints.erase)(i); bp->Activate(false); delete bp; - } + } else { + ignoreOnce = bp; + }; return true; }; }; @@ -239,11 +242,6 @@ bool CBreakpoint::CheckBreakpoint(PhysPt adr) bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue) // Checks if interrupt breakpoint is valid an should stop execution { - // if breakpoint is same address as started, it's not valid... - if (ignoreOnce) { - ignoreOnce->Activate(true); - ignoreOnce = 0; - } // Search matching breakpoint std::list::iterator i; CBreakpoint* bp; @@ -251,13 +249,21 @@ bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue) bp = static_cast(*i); if ((bp->GetType()==BKPNT_INTERRUPT) && bp->IsActive() && (bp->GetIntNr()==intNr)) { if ((bp->GetValue()==BPINT_ALL) || (bp->GetValue()==ahValue)) { + // Ignoie it once ? + if (ignoreOnce==bp) { + ignoreOnce=0; + bp->Activate(true); + return false; + }; // Found if (bp->GetOnce()) { // delete it, if it should only be used once (BPoints.erase)(i); bp->Activate(false); delete bp; - } + } else { + ignoreOnce = bp; + } return true; } }; @@ -881,12 +887,14 @@ Bit32u DEBUG_CheckKeys(void) { skipFirstInstruction = true; // for heavy debugger Bitu ret=(*cpudecoder)(1); SetCodeWinStart(); + CBreakpoint::ignoreOnce = 0; } break; case KEY_F(11): // trace into skipFirstInstruction = true; // for heavy debugger ret = (*cpudecoder)(1); SetCodeWinStart(); + CBreakpoint::ignoreOnce = 0; break; // default: From 664583a3c31a908c14a8a2f07f144af064725fc5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 3 Nov 2002 11:15:46 +0000 Subject: [PATCH 0395/4131] Fixed error codes for findfirst/findnext and a charactor for makename Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@473 --- src/dos/dos_files.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 5c3be2d7..5aa9b002 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -78,6 +78,7 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { case '\\': case '$': case '#': case '@': case '(': case ')': case '!': case '%': case '{': case '}': case '`': case '~': case '_': case '-': case '.': case '*': case '?': case '&': + case '\'': upname[w++]=c; break; default: @@ -210,14 +211,14 @@ bool DOS_FindFirst(char * search,Bit16u attr) { } dta.SetupSearch(drive,(Bit8u)attr,pattern); if (Drives[drive]->FindFirst(dir,dta)) return true; - DOS_SetError(DOSERR_FILE_NOT_FOUND); + DOS_SetError(DOSERR_NO_MORE_FILES); return false; } bool DOS_FindNext(void) { DOS_DTA dta(dos.dta); if (Drives[dta.GetSearchDrive()]->FindNext(dta)) return true; - DOS_SetError(DOSERR_FILE_NOT_FOUND); + DOS_SetError(DOSERR_NO_MORE_FILES); return false; } From c18094c9196f89e3db99dabae89d955c328c0d5d Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 4 Nov 2002 13:31:59 +0000 Subject: [PATCH 0396/4131] Fixed bug in RealHandle. it lost the highbyte of the file handle, which may lead to wrong file access. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@474 --- include/dos_inc.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/dos_inc.h b/include/dos_inc.h index 48bc6aba..fbc98df4 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -418,6 +418,9 @@ private: extern DOS_InfoBlock dos_infoblock;; INLINE Bit8u RealHandle(Bit16u handle) { + + // test out of range + if (handle>0xFF) return 0xff; DOS_PSP psp(dos.psp); return psp.GetFileHandle((Bit8u)handle); } From 4f86bdfe26a7bd40a3e5b1fc1849a23dd914bb81 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 4 Nov 2002 14:08:39 +0000 Subject: [PATCH 0397/4131] Fixed bug in RealHandle. it lost the highbyte of the file handle, which may lead to wrong file access. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@475 --- include/dos_inc.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index fbc98df4..6b99e6c0 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -419,10 +419,8 @@ extern DOS_InfoBlock dos_infoblock;; INLINE Bit8u RealHandle(Bit16u handle) { - // test out of range - if (handle>0xFF) return 0xff; DOS_PSP psp(dos.psp); - return psp.GetFileHandle((Bit8u)handle); + return psp.GetFileHandle(handle); } #endif From a3c48a130315241412bd2653a7cbafc9fee81351 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 4 Nov 2002 19:04:13 +0000 Subject: [PATCH 0398/4131] fixed a bug. the return code of dos_fcbwrite was misinterpretted Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@476 --- include/dos_inc.h | 2 +- src/dos/dos.cpp | 3 +-- src/dos/dos_files.cpp | 10 +++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 6b99e6c0..3944d7e1 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -149,7 +149,7 @@ bool DOS_FCBFindNext(Bit16u seg,Bit16u offset); Bit8u DOS_FCBRead(Bit16u seg,Bit16u offset, Bit16u numBlocks); bool DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u numBlocks); Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore); -bool DOS_FCBRandomWrite(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,Bit16u numRec); bool DOS_FCBDeleteFile(Bit16u seg,Bit16u offset); bool DOS_FCBRenameFile(Bit16u seg, Bit16u offset); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index d289ce14..b6447aef 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -244,8 +244,7 @@ static Bitu DOS_21Handler(void) { LOG_DEBUG("DOS:0x27 FCB-Random read used, result:al=%d",reg_al); break; case 0x28: /* Random Block write to FCB */ - if (DOS_FCBRandomWrite(SegValue(ds),reg_dx,reg_cx,false)) reg_al = 0x00; - else reg_al = 0x01; + reg_al=DOS_FCBRandomWrite(SegValue(ds),reg_dx,reg_cx,false); LOG_DEBUG("DOS:0x28 FCB-Random write used, result:al=%d",reg_al); break; case 0x29: /* Parse filename into FCB */ diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 5aa9b002..e4166a6d 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -738,9 +738,9 @@ Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { return error; } -bool DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { +Bit8u DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { DOS_FCB fcb(seg,offset); - Bit32u random;Bit16u old_block;Bit8u old_rec;bool noerror; + Bit32u random;Bit16u old_block;Bit8u old_rec;Bit8u error; /* Set the correct record from the random data */ fcb.GetRandom(random); @@ -748,15 +748,15 @@ bool DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { fcb.SetRecord((Bit16u)(random / 128),(Bit8u)(random & 127)); /* Write records */ for (int i=0; i Date: Mon, 4 Nov 2002 19:24:25 +0000 Subject: [PATCH 0399/4131] fcb normal write went also wrong Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@477 --- src/dos/dos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index b6447aef..acc756ee 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -204,7 +204,7 @@ static Bitu DOS_21Handler(void) { LOG_DEBUG("DOS:0x14 FCB-Read used, result:al=%d",reg_al); break; case 0x15: /* Sequential write to FCB */ - if (DOS_FCBWrite(SegValue(ds),reg_dx,0)) reg_al = 0x00; + if (DOS_FCBWrite(SegValue(ds),reg_dx,0)==true) reg_al = 0x00; else reg_al = 0x01; LOG_DEBUG("DOS:0x15 FCB-Write used, result:al=%d",reg_al); break; From 1f69ee249e86dc0e879fddaca6d82877ceb2ff3e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 4 Nov 2002 20:52:23 +0000 Subject: [PATCH 0400/4131] hmm evenmore fcb functions can do a write ;) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@478 --- include/dos_inc.h | 2 +- src/dos/dos.cpp | 6 ++---- src/dos/dos_files.cpp | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 3944d7e1..26a1c047 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -147,7 +147,7 @@ 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); -bool DOS_FCBWrite(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,Bit16u numRec); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index acc756ee..0ff1b2bf 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -204,8 +204,7 @@ static Bitu DOS_21Handler(void) { LOG_DEBUG("DOS:0x14 FCB-Read used, result:al=%d",reg_al); break; case 0x15: /* Sequential write to FCB */ - if (DOS_FCBWrite(SegValue(ds),reg_dx,0)==true) reg_al = 0x00; - else reg_al = 0x01; + reg_al=DOS_FCBWrite(SegValue(ds),reg_dx,0); LOG_DEBUG("DOS:0x15 FCB-Write used, result:al=%d",reg_al); break; case 0x16: /* Create or truncate file using FCB */ @@ -228,8 +227,7 @@ static Bitu DOS_21Handler(void) { LOG_DEBUG("DOS:0x21 FCB-Random read used, result:al=%d",reg_al); break; case 0x22: /* Write random record to FCB */ - if (DOS_FCBRandomWrite(SegValue(ds),reg_dx,1,true)) reg_al = 0x00; - else reg_al = 0x01; + reg_al=DOS_FCBRandomWrite(SegValue(ds),reg_dx,1,true); LOG_DEBUG("DOS:0x28 FCB-Random write used, result:al=%d",reg_al); break; case 0x23: /* Get file size for FCB */ diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index e4166a6d..4af8f71a 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -696,7 +696,7 @@ Bit8u DOS_FCBRead(Bit16u seg,Bit16u offset,Bit16u recno) { return FCB_READ_PARTIAL; } -bool DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u recno) +Bit8u DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u recno) { DOS_FCB fcb(seg,offset); Bit8u fhandle,cur_rec;Bit16u cur_block,rec_size; From 8dc5a523de4e0d582e99c629d56fcb3622cbf8e1 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 4 Nov 2002 21:27:03 +0000 Subject: [PATCH 0401/4131] support for cpu trap flag Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@479 --- src/cpu/core_16/main.h | 11 ++++++++--- src/cpu/core_16/support.h | 10 ++++++++-- src/cpu/slow_16.cpp | 14 +++++++++++++- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 1495e42b..2ba5b34a 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -856,10 +856,15 @@ restart: } break; case 0xcc: /* INT3 */ +#if C_DEBUG + SAVEIP; + if (DEBUG_Breakpoint()) { + LOADIP; + return 1; + } + LOADIP; +#endif INTERRUPT(3); -#if C_DEBUG - return 1; -#endif break; case 0xcd: /* INT Ib */ { diff --git a/src/cpu/core_16/support.h b/src/cpu/core_16/support.h index ace3a10f..5201b75c 100644 --- a/src/cpu/core_16/support.h +++ b/src/cpu/core_16/support.h @@ -376,7 +376,10 @@ countzero: PIC_runIRQs(); \ LOADIP; \ } \ - if (flags.tf) LOG_DEBUG("CPU:Trap Flag not supported"); \ + if (flags.tf) { \ + cpudecoder=&CPU_Real_16_Slow_Decode_Trap; \ + count=0; \ + } \ } #else @@ -394,7 +397,10 @@ countzero: PIC_runIRQs(); \ LOADIP; \ } \ - if (flags.tf) LOG_DEBUG("CPU:Trap Flag not supported"); \ + if (flags.tf) { \ + cpudecoder=&CPU_Real_16_Slow_Decode_Trap; \ + count=0; \ + } \ } #endif diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp index 0bf3d76d..5a1aa242 100644 --- a/src/cpu/slow_16.cpp +++ b/src/cpu/slow_16.cpp @@ -60,7 +60,8 @@ extern Bitu cycle_count; #endif #include "core_16/support.h" -static Bitu CPU_Real_16_Slow_Decode_Special(Bitu count); +static Bitu CPU_Real_16_Slow_Decode_Special(Bits count); +static Bitu CPU_Real_16_Slow_Decode_Trap(Bits count); static Bitu CPU_Real_16_Slow_Decode(Bits count) { #include "core_16/start.h" @@ -78,6 +79,17 @@ static Bitu CPU_Real_16_Slow_Decode(Bits count) { return CBRET_NONE; } +static Bitu CPU_Real_16_Slow_Decode_Trap(Bits count) +{ + CPU_Real_16_Slow_Decode(1); + + LOG_DEBUG("TRAP: Trap Flag executed"); + INTERRUPT(1); + cpudecoder=&CPU_Real_16_Slow_Decode; + + return CBRET_NONE; +}; + static Bitu CPU_Real_16_Slow_Decode_Special(Bits count) { while (count>0) { if (flags.tf) { From c341f405979a61807ecbf6e5183179c7280b5663 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 5 Nov 2002 18:39:19 +0000 Subject: [PATCH 0402/4131] fixed bug #629841 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@480 --- src/misc/messages.cpp | 4 ++-- src/misc/setup.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 4b5e5aff..073f2efb 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -69,7 +69,7 @@ void MSG_Replace(const char * _name, const char* _val) { static void LoadMessageFile(const char * fname) { if (!fname) return; if(*fname=='\0') return;//empty string=no languagefile - FILE * mfile=fopen(fname,"rb"); + FILE * mfile=fopen(fname,"rt"); /* This should never happen and since other modules depend on this use a normal printf */ if (!mfile) { E_Exit("MSG:Can't load messages: %s",fname); @@ -120,7 +120,7 @@ const char * MSG_Get(char const * msg) { void MSG_Write(const char * location) { - FILE* out=fopen(location,"w+b"); + FILE* out=fopen(location,"w+t"); if(out==NULL) return;//maybe an error? for(itmb tel=Lang.begin();tel!=Lang.end();tel++){ fprintf(out,":%s\n%s.\n",(*tel).name.c_str(),(*tel).val.c_str()); diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index fd69e7c8..76f64269 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -156,7 +156,7 @@ void Section_line::PrintData(FILE* outfile) { void Config::PrintConfig(const char* configfilename){ char temp[50]; - FILE* outfile=fopen(configfilename,"w+b"); + FILE* outfile=fopen(configfilename,"w+t"); if(outfile==NULL) return; for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ /* Print out the Section header */ From 7da067b040994887940072f16ddd4d5efbd0ab6e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 6 Nov 2002 09:39:43 +0000 Subject: [PATCH 0403/4131] Changed the timer and date functions to startup correctly and allow for irq updates in get system time call. Also removed the read/write boundary cross warnings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@481 --- src/dos/dos.cpp | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 0ff1b2bf..a7e24bc0 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -283,13 +283,18 @@ static Bitu DOS_21Handler(void) { DOS_NewPSP(reg_dx,DOS_PSP(dos.psp).GetSize()); break; case 0x2a: /* Get System Date */ - reg_al=0; /* It's always sunday TODO find that correct formula */ - reg_cx=dos.date.year; - reg_dh=dos.date.month; - reg_dl=dos.date.day; + { + CALLBACK_Idle(); + int a = (14 - dos.date.month)/12; + int y = dos.date.year - a; + int m = dos.date.month + 12*a - 2; + reg_al=(dos.date.day+y+(y/4)-(y/100)+(y/400)+(31*m)/12) % 7; + reg_cx=dos.date.year; + reg_dh=dos.date.month; + reg_dl=dos.date.day; + } break; case 0x2b: /* Set System Date */ -//TODO Check for months with less then 31 days if (reg_cx<1980) { reg_al=0xff;break;} if ((reg_dh>12) || (reg_dh==0)) { reg_al=0xff;break;} if ((reg_dl>31) || (reg_dl==0)) { reg_al=0xff;break;} @@ -301,12 +306,13 @@ static Bitu DOS_21Handler(void) { case 0x2c: /* Get System Time */ //TODO Get time through bios calls date is fixed { + CALLBACK_Idle(); Bit32u ticks=mem_readd(BIOS_TIMER); Bit32u seconds=(ticks*10)/182; reg_ch=(Bit8u)(seconds/3600); - reg_cl=(Bit8u)(seconds % 3600)/60; + reg_cl=(Bit8u)((seconds % 3600)/60); reg_dh=(Bit8u)(seconds % 60); - reg_dl=(Bit8u)(ticks % 19)*5; + reg_dl=(Bit8u)((ticks % 19)*5); } break; case 0x2d: /* Set System Time */ @@ -456,7 +462,6 @@ static Bitu DOS_21Handler(void) { case 0x3f: /* READ Read from file or device */ { Bit16u toread=reg_cx; - if (reg_cx+reg_dx>0xffff) LOG_DEBUG("DOS:READ:Buffer overflow %d",reg_cx+reg_dx); if (DOS_ReadFile(reg_bx,dos_copybuf,&toread)) { MEM_BlockWrite(SegPhys(ds)+reg_dx,dos_copybuf,toread); reg_ax=toread; @@ -470,7 +475,6 @@ static Bitu DOS_21Handler(void) { case 0x40: /* WRITE Write to file or device */ { Bit16u towrite=reg_cx; - if (reg_cx+reg_dx>0xffff) LOG_DEBUG("DOS:WRITE:Buffer overflow %d",reg_cx+reg_dx); MEM_BlockRead(SegPhys(ds)+reg_dx,dos_copybuf,towrite); if (DOS_WriteFile(reg_bx,dos_copybuf,&towrite)) { reg_ax=towrite; @@ -730,8 +734,10 @@ static Bitu DOS_21Handler(void) { } break; } - case 0x5c: /* FLOCK File region locking */ case 0x5d: /* Network Functions */ + LOG_WARN("DOS:5D:Unhandled call %X",reg_al); + break; + case 0x5c: /* FLOCK File region locking */ case 0x5e: /* More Network Functions */ case 0x5f: /* And Even More Network Functions */ E_Exit("DOS:Unhandled call %02X",reg_ah); @@ -852,8 +858,16 @@ void DOS_Init(Section* sec) { DOS_SetupPrograms(); DOS_SetupMisc(); /* Some additional dos interrupts */ DOS_SetDefaultDrive(25); - /* Execute the file that should be */ + dos.version.major=5; dos.version.minor=0; -// DOS_RunProgram(startname); -}; + /* Setup time and date */ + time_t curtime;struct tm *loctime; + curtime = time (NULL);loctime = localtime (&curtime); + + dos.date.day=(Bit8u)loctime->tm_mday; + dos.date.month=(Bit8u)loctime->tm_mon+1; + dos.date.year=(Bit16u)loctime->tm_year+1900; + Bit32u ticks=(Bit32u)((loctime->tm_hour*3600+loctime->tm_min*60+loctime->tm_sec)*18.2); + mem_writed(BIOS_TIMER,ticks); +} From 09005620bba2e40e333b518e205e26d3b5ce00e9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 6 Nov 2002 09:41:09 +0000 Subject: [PATCH 0404/4131] CALLBACK_Idle() automatically sets the interrupt flag now. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@482 --- src/cpu/callback.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index e583dc06..e2793592 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -52,6 +52,8 @@ Bitu CALLBACK_Allocate(void) { void CALLBACK_Idle(void) { /* this makes the cpu execute instructions to handle irq's and then come back */ + bool oldintf=flags.intf; + flags.intf=true; Bit16u oldcs=SegValue(cs); Bit32u oldeip=reg_eip; SegSet16(cs,CB_SEG); @@ -59,6 +61,7 @@ void CALLBACK_Idle(void) { DOSBOX_RunMachine(); reg_eip=oldeip; SegSet16(cs,oldcs); + flags.intf=oldintf; } static Bitu default_handler(void) { From f1d0fac4ef16997844997207f26d365eab757763 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 6 Nov 2002 11:11:47 +0000 Subject: [PATCH 0405/4131] fixed bug #629219 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@483 --- src/gui/sdlmain.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 7da7a2df..0644ce7c 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -568,8 +568,10 @@ int main(int argc, char* argv[]) { control->StartUp(); /* Shutdown everything */ } catch (char * error) { + if (sdl.full_screen) SwitchFullScreen(); LOG_MSG("Exit to error: %sPress enter to continue.",error); fgetc(stdin); } + GFX_ShutDown(); return 0; }; From 9a3ccda025a22eb4a39aec3c9f06aeb95723161c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 6 Nov 2002 14:26:10 +0000 Subject: [PATCH 0406/4131] friendlier when an E_Exit is done Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@484 --- src/gui/sdlmain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 0644ce7c..fc73a858 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -569,6 +569,7 @@ int main(int argc, char* argv[]) { /* Shutdown everything */ } catch (char * error) { if (sdl.full_screen) SwitchFullScreen(); + if (sdl.mouse.locked) CaptureMouse(); LOG_MSG("Exit to error: %sPress enter to continue.",error); fgetc(stdin); } From ca4c7db06596c1257fb8ad97edc8d3b852842755 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 6 Nov 2002 14:27:29 +0000 Subject: [PATCH 0407/4131] added support for debugger under non-windows systems! no colors yet/ and afterwards your term is messed up :) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@485 --- ChangeLog | 6 ++++++ settings.h.cvs | 2 +- src/debug/debug.cpp | 5 ++++- src/debug/debug_gui.cpp | 4 ++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d91901cb..7b47ffb9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ + - added support for command /C + - fixed all fcb-write functions + - fixed fcb-parseline + - added debugger under linux/freebsd + + 0.56 - added support for a configclass/configfile - added support for writing out the configclass into a configfile diff --git a/settings.h.cvs b/settings.h.cvs index 81f3ec27..af5707b7 100644 --- a/settings.h.cvs +++ b/settings.h.cvs @@ -19,7 +19,7 @@ #ifndef _SETTINGS_H_ #define _SETTINSG_H_ -/* Enable the debugger, this only seems to work in win32 for now. */ +/* Enable the debugger, under linux/freebsd dosbox must be started in an xterm under X */ #define C_DEBUG 0 #define C_HEAVY_DEBUG 0 diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index a4c92d43..92f2e33a 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -34,7 +34,7 @@ #include "mixer.h" #include "debug_inc.h" #include "timer.h" -#include "..\shell\shell_inc.h" +#include "../shell/shell_inc.h" #ifdef WIN32 void WIN32_Console(); @@ -1048,6 +1048,9 @@ void DEBUG_SetupConsole(void) { #ifdef WIN32 WIN32_Console(); + #else + printf("\e[8;50;80t"); //resize terminal + fflush(NULL); #endif memset((void *)&dbg,0,sizeof(dbg)); debugging=false; diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 43d8d305..64eb95fb 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -122,6 +122,10 @@ void DBGUI_StartUp(void) { noecho(); /* don't echo input */ nodelay(dbg.win_main,true); keypad(dbg.win_main,true); + #ifndef WIN32 + resizeterm(50,80); + touchwin(dbg.win_main); + #endif cycle_count=0; MakePairs(); MakeSubWindows(); From 00d4feeb1617c776146910ee0f1e0493a9c54c27 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 6 Nov 2002 20:52:28 +0000 Subject: [PATCH 0408/4131] Fixed crash in DOS_GetSTDINStatus Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@486 --- src/dos/dos_ioctl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index f01b181b..3676a8dc 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -96,7 +96,8 @@ bool DOS_IOCTL(void) { bool DOS_GetSTDINStatus(void) { Bit32u handle=RealHandle(STDIN); - if (Files[handle]->GetInformation() & 64) return false; + if (handle==0xFF) return false; + if (Files[handle] && (Files[handle]->GetInformation() & 64)) return false; return true; }; From 81f2bdf67137ff1603548e1fa91b62fb7785ba48 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 6 Nov 2002 22:37:17 +0000 Subject: [PATCH 0409/4131] enabled seek for devices Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@487 --- src/dos/dev_con.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 77998e24..f60c0412 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -74,7 +74,9 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { } bool device_CON::Seek(Bit32u * pos,Bit32u type) { - return false; + // seek is valid + *pos = 0; + return true; } bool device_CON::Close() { From cc838f907ec2174c48cb32765155b7c566384c39 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 8 Nov 2002 14:12:42 +0000 Subject: [PATCH 0410/4131] Added Idle Callback in Int 1a, get systen time Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@488 --- src/ints/bios.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index a3c5db35..e206f103 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -30,6 +30,7 @@ static Bitu INT1A_Handler(void) { switch (reg_ah) { case 0x00: /* Get System time */ { + CALLBACK_Idle(); Bit32u ticks=mem_readd(BIOS_TIMER); reg_al=0; /* Midnight never passes :) */ reg_cx=(Bit16u)(ticks >> 16); From 5a4c1e320a5148a5859cf38c21a0cbf2cea2088c Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 8 Nov 2002 14:13:31 +0000 Subject: [PATCH 0411/4131] Added mode "load" in dos_execute Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@489 --- src/dos/dos_execute.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index bb3c6232..56414bd7 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -208,7 +208,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { Bitu headersize,imagesize; DOS_ParamBlock block(block_pt); block.LoadData(); - if (flags!=LOADNGO && flags!=OVERLAY) { + if (flags!=LOADNGO && flags!=OVERLAY && flags!=LOAD) { E_Exit("DOS:Not supported execute mode %d for file %s",flags,name); } /* Check for EXE or COM File */ @@ -302,6 +302,20 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { csip=RealMake(loadseg+head.initCS,head.initIP); sssp=RealMake(loadseg+head.initSS,head.initSP); } + + if (flags==LOAD) { + DOS_PSP callpsp(dos.psp); + /* Save the SS:SP on the PSP of calling program */ + callpsp.SetStack(RealMakeSeg(ss,reg_sp)); + /* Switch the psp's */ + dos.psp=pspseg; + + block.exec.initsssp = sssp; + block.exec.initcsip = csip; + block.SaveData(); + return true; + } + if (flags==LOADNGO) { /* Get Caller's program CS:IP of the stack and set termination address to that */ RealSetVec(0x22,RealMake(mem_readw(SegPhys(ss)+reg_sp+2),mem_readw(SegPhys(ss)+reg_sp))); From 38117780b50f291b5d099ea9edc35c2d52f8fc2e Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 8 Nov 2002 14:13:54 +0000 Subject: [PATCH 0412/4131] Added int 27 handler (tsr) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@490 --- src/dos/dos.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index a7e24bc0..07ae0e9a 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -32,7 +32,7 @@ DOS_Block dos; DOS_InfoBlock dos_infoblock; Bit8u dos_copybuf[0x10000]; -static Bitu call_20,call_21; +static Bitu call_20,call_21,call_27; void DOS_SetError(Bit16u code) { dos.errorcode=code; @@ -840,6 +840,13 @@ static Bitu DOS_20Handler(void) { return CBRET_NONE; } +static Bitu DOS_27Handler(void) +{ + // Terminate & stay resident + Bit16u para = (reg_dx/16)+((reg_dx % 16)>0); + if (DOS_ResizeMemory(dos.psp,¶)) DOS_Terminate(true); + return CBRET_NONE; +} void DOS_Init(Section* sec) { MSG_Add("DOS_CONFIGFILE_HELP","Setting a memory size to 0 will disable it.\n"); @@ -851,6 +858,10 @@ void DOS_Init(Section* sec) { CALLBACK_Setup(call_21,DOS_21Handler,CB_IRET); RealSetVec(0x21,CALLBACK_RealPointer(call_21)); + call_27=CALLBACK_Allocate(); + CALLBACK_Setup(call_27,DOS_27Handler,CB_IRET); + RealSetVec(0x27,CALLBACK_RealPointer(call_27)); + DOS_SetupFiles(); /* Setup system File tables */ DOS_SetupDevices(); /* Setup dos devices */ DOS_SetupTables(); From 055e02bb411060b9560a5466820bfb141b3ab120 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 10 Nov 2002 00:16:34 +0000 Subject: [PATCH 0413/4131] Added status bit. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@491 --- src/hardware/dma.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index eb317d42..1dba7e3d 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -91,6 +91,11 @@ static Bit8u read_dma(Bit32u port) { } cont->flipflop=!cont->flipflop; break; + case 0x08: /* Read Status */ + ret=cont->status_reg; + cont->status_reg&=0xf; /* Clear lower 4 bits on read */ + break; + default: LOG_WARN("DMA:Unhandled read from %d",port); } @@ -128,6 +133,8 @@ static void write_dma(Bit32u port,Bit8u val) { case 0x09: /* Request Register */ if (val&4) { /* Set Request bit */ + Bitu channel = val & 0x03; + cont->status_reg |= (1 << (channel+4)); } else { Bitu channel = val & 0x03; cont->status_reg &= ~(1 << (channel+4)); @@ -183,13 +190,15 @@ Bit16u DMA_8_Read(Bit32u dmachan,Bit8u * buffer,Bit16u count) { chan->current_address=chan->base_address; DMA_DEBUG("DMA:Transfer from %d size %d",(chan->page << 16)+chan->base_address,chan->current_count); } - if (chan->current_count>=count) { + if (chan->current_count>count) { MEM_BlockRead(chan->address,buffer,count); chan->address+=count; chan->current_address+=count; chan->current_count-=count; return count; } else { + /* Set the end of counter bit */ + dma[0].status_reg|=(1 << dmachan); /* Copy remaining piece of first buffer */ MEM_BlockRead(chan->address,buffer,chan->current_count); buffer+=chan->current_count; From 764dc5c5435c4a702b7b76e167ca890d949e150f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Nov 2002 18:40:43 +0000 Subject: [PATCH 0414/4131] fixed some fcb errors: fcb-open and fcb-create created. fixed return values. fixed wildcmp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@492 --- include/dos_inc.h | 3 ++- src/dos/dos.cpp | 6 +++--- src/dos/dos_classes.cpp | 2 +- src/dos/dos_files.cpp | 11 ++++++++++- src/dos/drive_local.cpp | 2 +- src/dos/drives.cpp | 1 + 6 files changed, 18 insertions(+), 7 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 26a1c047..ff3d7595 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -142,7 +142,8 @@ void DOS_FreeProcessMemory(Bit16u pspseg); Bit16u DOS_GetMemory(Bit16u pages); /* FCB stuff */ -bool DOS_FCBOpenCreate(Bit16u seg,Bit16u offset); +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); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 07ae0e9a..2093fb90 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -164,7 +164,7 @@ static Bitu DOS_21Handler(void) { reg_al=26; break; case 0x0f: /* Open File using FCB */ - if(DOS_FCBOpenCreate(SegValue(ds),reg_dx)){ + if(DOS_FCBOpen(SegValue(ds),reg_dx)){ reg_al=0; }else{ reg_al=0xff; @@ -208,8 +208,8 @@ static Bitu DOS_21Handler(void) { LOG_DEBUG("DOS:0x15 FCB-Write used, result:al=%d",reg_al); break; case 0x16: /* Create or truncate file using FCB */ - if (DOS_FCBOpenCreate(SegValue(ds),reg_dx)) reg_al = 0x00; - else reg_al = 0x01; + if (DOS_FCBCreate(SegValue(ds),reg_dx)) reg_al = 0x00; + else reg_al = 0xFF; LOG_DEBUG("DOS:0x16 FCB-Create used, result:al=%d",reg_al); break; case 0x17: /* Rename file using FCB */ diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 3f1c7291..6025b28b 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -318,7 +318,7 @@ void DOS_FCB::SetRandom(Bit32u _random) { } void DOS_FCB::FileOpen(Bit8u _fhandle) { - sSave(sFCB,drive,GetDrive()); + sSave(sFCB,drive,GetDrive()+1); sSave(sFCB,file_handle,_fhandle); sSave(sFCB,cur_block,0); sSave(sFCB,rec_size,128); diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 4af8f71a..42a0c08e 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -635,7 +635,16 @@ static void SaveFindResult(DOS_FCB & find_fcb) { fcb.SetSizeDateTime(size,date,time); } -bool DOS_FCBOpenCreate(Bit16u seg,Bit16u offset) { +bool DOS_FCBCreate(Bit16u seg,Bit16u offset) { + DOS_FCB fcb(seg,offset); + char shortname[DOS_FCBNAME];Bit16u handle; + fcb.GetName(shortname); + if (!DOS_CreateFile(shortname,2,&handle)) return false; + fcb.FileOpen((Bit8u)handle); + return true; +} + +bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); char shortname[DOS_FCBNAME];Bit16u handle; fcb.GetName(shortname); diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 7dfd868d..28bf7c12 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -43,7 +43,7 @@ private: }; -bool localDrive:: FileCreate(DOS_File * * file,char * name,Bit16u attributes) { +bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) { //TODO Maybe care for attributes but not likely char newname[CROSS_LEN]; strcpy(newname,basedir); diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index 2785b18d..65d6483f 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -63,6 +63,7 @@ bool WildFileCmp(const char * file, const char * wild) r++; } checkext: + r=0; while (r<3) { if (wild_ext[r]=='*') return true; if (wild_ext[r]!='?' && wild_ext[r]!=file_ext[r]) return false; From acb36050b3a868d940e6e6de706b0be44c5d1c1a Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 12 Nov 2002 15:34:39 +0000 Subject: [PATCH 0415/4131] fixed:parameter passing for debug.com fixed:changing zero flag now possible, too. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@493 --- src/debug/debug.cpp | 55 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 92f2e33a..c6b70e58 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -633,6 +633,7 @@ bool ChangeRegister(char* str) if (strstr(hex,"IF")==hex) { hex+=2; flags.intf = (GetHexValue(hex,hex)!=0); } else if (strstr(hex,"OF")==hex) { hex+=3; flags.of = (GetHexValue(hex,hex)!=0); } else if (strstr(hex,"PF")==hex) { hex+=3; flags.pf = (GetHexValue(hex,hex)!=0); } else + if (strstr(hex,"ZF")==hex) { hex+=3; flags.zf = (GetHexValue(hex,hex)!=0); } else { return false; }; return true; }; @@ -945,7 +946,6 @@ static void DEBUG_RaiseTimerIrq(void) { static bool DEBUG_Log_Loop(int count) { char buffer[512]; - getcwd(buffer,512); FILE* f = fopen("LOGCPU.TXT","wt"); if (!f) return false; @@ -994,11 +994,18 @@ public: void Run(void) { char filename[128]; - char args[128]; + char args[256]; cmd->FindCommand(1,temp_line); strncpy(filename,temp_line.c_str(),128); - cmd->FindCommand(2,temp_line); - strncpy(args,temp_line.c_str(),128); + // Read commandline + Bit16u i =2; + bool ok = false; + args[0] = 0; + do { + ok = cmd->FindCommand(i++,temp_line); + strncat(args,temp_line.c_str(),256); + strncat(args," ",256); + } while (ok); // Start new shell and execute prog active = true; // Save cpu state.... @@ -1084,6 +1091,46 @@ void DEBUG_Init(Section* sec) { #if C_HEAVY_DEBUG +#define LOGCPUMAX 200 + +static Bit16u logCpuCS [LOGCPUMAX]; +static Bit32u logCpuEIP[LOGCPUMAX]; +static Bit32u logCount = 0; + +typedef struct SLogInst { + char buffer[256]; +} TLogInst; + +TLogInst logInst[LOGCPUMAX]; + +void DEBUG_HeavyLogInstruction(void) +{ + LogInstruction(SegValue(cs),reg_eip,logInst[logCount++].buffer); + if (logCount>=LOGCPUMAX) logCount = 0; +}; + +void DEBUG_HeavyWriteLogInstruction(void) +{ + LOG_DEBUG("DEBUG: Creating cpu log LOGCPU_INT_CD.TXT"); + + FILE* f = fopen("LOGCPU_INT_CD.TXT","wt"); + if (!f) { + LOG_DEBUG("DEBUG: Failed."); + return; + } + + Bit16u startLog = logCount; + do { + // Write Intructions + fprintf(f,"%s",logInst[startLog++].buffer); + if (startLog>=LOGCPUMAX) logCount = 0; + } while (startLog!=logCount); + + fclose(f); + + LOG_DEBUG("DEBUG: Done."); +}; + bool DEBUG_HeavyIsBreakpoint(void) { if (skipFirstInstruction) { From f4b5658765c56fb3cc8840c330bdb521d1150784 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 12 Nov 2002 19:08:23 +0000 Subject: [PATCH 0416/4131] enabled the cr lf translation again Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@494 --- src/dos/dev_con.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index f60c0412..0e077e67 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -41,8 +41,8 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { switch(reg_al) { case 13: data[count++]=0x0D; -// if (*size>count) data[count++]=0x0A; -// else cache=0x0A; + if (*size>count) data[count++]=0x0A; + else cache=0x0A; *size=count; reg_ax=oldax; return true; From 6906625545dcac3bdf22971aa4cb6e1953965d04 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 12 Nov 2002 19:09:00 +0000 Subject: [PATCH 0417/4131] added support for int 13 04 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@495 --- src/ints/bios_disk.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index da24f797..234debc8 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -21,7 +21,7 @@ #include "bios.h" #include "regs.h" #include "mem.h" - +#include "dos_inc.h" /* for Drives[] */ static Bitu call_int13; static BIOS_Disk * Floppys[2]; @@ -36,6 +36,18 @@ static Bitu INT13_SmallHandler(void) { reg_ah=0xff; CALLBACK_SCF(true); break; + case 0x04: + if(Drives[reg_dl]!=NULL) { + reg_ah=0; + CALLBACK_SCF(false); + } + else{ + reg_ah=0x80; + CALLBACK_SCF(true); + } + LOG_WARN("INT 13:04 Verify sector used on %d, with result %d",reg_dl,reg_ah); + break; + case 0x08: /* Get Drive Parameters */ LOG_DEBUG("INT13:08:Get Drive parameters not supported failing"); reg_ah=0xff; From 7dba8a97b89743654303bfa80cce87f846548eaa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 13 Nov 2002 11:39:31 +0000 Subject: [PATCH 0418/4131] made dos more compatible and fixed aaowcga Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@496 --- src/dos/dos.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 2093fb90..43376cbf 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -43,9 +43,6 @@ static Bitu DOS_21Handler(void) { char name1[DOSNAMEBUF+1]; char name2[DOSNAMEBUF+1]; switch (reg_ah) { - case 0x00: /* Terminate Program */ - E_Exit("DOS:Unhandled call %02X",reg_ah); - break; case 0x01: /* Read character from STDIN, with echo */ { Bit8u c;Bit16u n=1; @@ -161,7 +158,7 @@ static Bitu DOS_21Handler(void) { break; case 0x0e: /* Select Default Drive */ DOS_SetDefaultDrive(reg_dl); - reg_al=26; + reg_al=DOS_DRIVES; break; case 0x0f: /* Open File using FCB */ if(DOS_FCBOpen(SegValue(ds),reg_dx)){ @@ -605,8 +602,11 @@ static Bitu DOS_21Handler(void) { } break; //TODO Check for use of execution state AL=5 + case 0x00: + reg_ax=0x4c00; /* Terminate Program */ case 0x4c: /* EXIT Terminate with return code */ - { + + { if (DOS_Terminate(false)) { /* This can't ever return false normally */ } else { @@ -653,9 +653,10 @@ static Bitu DOS_21Handler(void) { //TODO Think hard how shit this is gonna be //And will any game ever use this :) case 0x53: /* Translate BIOS parameter block to drive parameter block */ -//YEAH RIGHT + E_Exit("Unhandled Dos 21 call %02X",reg_ah); + break; case 0x54: /* Get verify flag */ - E_Exit("Unhandled Dos 21 call %02X",reg_ah); + reg_al=dos.verify?1:0; break; case 0x55: /* Create Child PSP*/ DOS_NewPSP(reg_dx,reg_si); @@ -821,10 +822,10 @@ static Bitu DOS_21Handler(void) { LOG_WARN("DOS:Windows long file name support call %2X",reg_al); break; case 0xE0: - LOG_DEBUG("DOS:E0:Unhandled, what should this call do?"); - break; + case 0xEF: default: - E_Exit("DOS:Unhandled call %02X",reg_ah); + reg_al=0x00; /* default value */ + LOG_DEBUG("DOS:Unhandled call %02X. Set al to default of 0 no carry",reg_ah); break; }; return CBRET_NONE; From ef0654b332d2e5f8e579c539501817b5efb16165 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 13 Nov 2002 20:47:01 +0000 Subject: [PATCH 0419/4131] fixed a bug in mul. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@497 --- src/cpu/core_16/prefix_66.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index 33c2aa51..8122692e 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -438,7 +438,7 @@ switch(Fetchb()) { 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); + reg_eax=(Bit32u)(temp.u & 0xffffffff);reg_edx=(Bit32u)(temp.u >> 32); flags.cf=flags.of=(reg_edx !=0); break; } From 6a3fa5949f0ee5829ce94239144bb1c35c67c8c2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 13 Nov 2002 20:48:54 +0000 Subject: [PATCH 0420/4131] added support for int 21 ax=4406 bx=0000 grouped non-working functions updated int 21 ah=2c to be able to display 95 hunderd as well Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@498 --- src/dos/dos.cpp | 36 +++++++++++++++--------------------- src/dos/dos_ioctl.cpp | 7 +++++++ 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 43376cbf..9d5e7c0c 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -92,7 +92,7 @@ static Bitu DOS_21Handler(void) { reg_al=c; break; }; - case 0x08: /* Direct Character Input, without echo */ + case 0x08: /* Direct Character Input, without echo (checks for breaks officially :)*/ { Bit8u c;Bit16u n=1; DOS_ReadFile (STDIN,&c,&n); @@ -251,14 +251,6 @@ static Bitu DOS_21Handler(void) { } LOG_DEBUG("DOS:29:FCB Parse Filename, result:al=%d",reg_al); break; - case 0x18: /* NULL Function for CP/M compatibility or Extended rename FCB */ - case 0x1d: /* NULL Function for CP/M compatibility or Extended rename FCB */ - case 0x1e: /* NULL Function for CP/M compatibility or Extended rename FCB */ - case 0x20: /* NULL Function for CP/M compatibility or Extended rename FCB */ - case 0x6b: /* NULL Function */ - case 0x61: /* UNUSED */ - reg_al=0; - break; case 0x19: /* Get current default drive */ reg_al=DOS_GetDefaultDrive(); break; @@ -281,7 +273,7 @@ static Bitu DOS_21Handler(void) { break; case 0x2a: /* Get System Date */ { - CALLBACK_Idle(); + CALLBACK_Idle(); /* sure ? */ int a = (14 - dos.date.month)/12; int y = dos.date.year - a; int m = dos.date.month + 12*a - 2; @@ -309,7 +301,7 @@ static Bitu DOS_21Handler(void) { reg_ch=(Bit8u)(seconds/3600); reg_cl=(Bit8u)((seconds % 3600)/60); reg_dh=(Bit8u)(seconds % 60); - reg_dl=(Bit8u)((ticks % 19)*5); + reg_dl=(Bit8u)((ticks % 20)*5); /* 0-19 ->0-95 */ } break; case 0x2d: /* Set System Time */ @@ -603,7 +595,7 @@ static Bitu DOS_21Handler(void) { break; //TODO Check for use of execution state AL=5 case 0x00: - reg_ax=0x4c00; /* Terminate Program */ + reg_ax=0x4c00; /* Terminate Program */ case 0x4c: /* EXIT Terminate with return code */ { @@ -735,9 +727,7 @@ static Bitu DOS_21Handler(void) { } break; } - case 0x5d: /* Network Functions */ - LOG_WARN("DOS:5D:Unhandled call %X",reg_al); - break; + case 0x5c: /* FLOCK File region locking */ case 0x5e: /* More Network Functions */ case 0x5f: /* And Even More Network Functions */ @@ -756,10 +746,6 @@ static Bitu DOS_21Handler(void) { case 0x62: /* Get Current PSP Address */ reg_bx=dos.psp; break; - case 0x63: /* Weirdo double byte stuff */ - reg_al=0xff; - LOG_WARN("DOS:0x63:Doubly byte characters not supported"); - break; case 0x64: /* Set device driver lookahead flag */ E_Exit("Unhandled Dos 21 call %02X",reg_ah); break; @@ -822,10 +808,18 @@ static Bitu DOS_21Handler(void) { LOG_WARN("DOS:Windows long file name support call %2X",reg_al); break; case 0xE0: - case 0xEF: + case 0x18: /* NULL Function for CP/M compatibility or Extended rename FCB */ + case 0x1d: /* NULL Function for CP/M compatibility or Extended rename FCB */ + case 0x1e: /* NULL Function for CP/M compatibility or Extended rename FCB */ + case 0x20: /* NULL Function for CP/M compatibility or Extended rename FCB */ + case 0x6b: /* NULL Function */ + case 0x61: /* UNUSED */ + case 0x63: /* Weirdo double byte stuff (fails but say it succeeded) */ + case 0xEF: /* Used in Ancient Art Of War CGA */ + case 0x5d: /* Network Functions */ default: + LOG_DEBUG("DOS:Unhandled call %02X al=%02X. Set al to default of 0 no carry",reg_ah,reg_al); reg_al=0x00; /* default value */ - LOG_DEBUG("DOS:Unhandled call %02X. Set al to default of 0 no carry",reg_ah); break; }; return CBRET_NONE; diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 3676a8dc..2a4a50aa 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -86,6 +86,13 @@ bool DOS_IOCTL(void) { return false; } break; + case 0x06: /* Get Input Status */ + if(reg_bx==0x00) { /* might work for other handles, but tested it only for STDIN */ + if(Files[handle]->GetInformation() & 0x40) reg_al=0x00; else + reg_al=0xFF; + return true; + break; + } default: LOG_ERROR("DOS:IOCTL Call %2X unhandled",reg_al); return false; From 97793a59251f3d2198628aa7c5f03f19b584889b Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 14 Nov 2002 17:30:50 +0000 Subject: [PATCH 0421/4131] Add memory breakpoints (BPM) for the HEAVY debugger. Add automated log if INT CD occurs, also HEAVY debug and has to be enabled with the HEAVYLOG command. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@499 --- include/debug.h | 3 +- src/debug/debug.cpp | 106 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 89 insertions(+), 20 deletions(-) diff --git a/include/debug.h b/include/debug.h index 2dfa9c6d..de1d460e 100644 --- a/include/debug.h +++ b/include/debug.h @@ -27,5 +27,6 @@ bool DEBUG_ExitLoop(void); extern Bitu cycle_count; #ifdef C_HEAVY_DEBUG -bool DEBUG_HeavyIsBreakpoint(); +bool DEBUG_HeavyIsBreakpoint(void); +void DEBUG_HeavyWriteLogInstruction(void); #endif diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index c6b70e58..6addcf17 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -48,6 +48,7 @@ class DEBUG; DEBUG* pDebugcom = 0; bool exitLoop = false; +bool logHeavy = false; static struct { Bit32u eax,ebx,ecx,edx,esi,edi,ebp,esp,eip; @@ -91,7 +92,7 @@ static Bit16u dataSeg,dataOfs; bool skipFirstInstruction = false; -enum EBreakpoint { BKPNT_UNKNOWN, BKPNT_PHYSICAL, BKPNT_INTERRUPT }; +enum EBreakpoint { BKPNT_UNKNOWN, BKPNT_PHYSICAL, BKPNT_INTERRUPT, BKPNT_MEMORY }; #define BPINT_ALL 0x100 @@ -104,21 +105,24 @@ public: void SetAddress (PhysPt adr) { location = adr; type = BKPNT_PHYSICAL; }; void SetInt (Bit8u _intNr, Bit16u ah) { intNr = _intNr, ahValue = ah; type = BKPNT_INTERRUPT; }; void SetOnce (bool _once) { once = _once; }; - + void SetType (EBreakpoint _type) { type = _type; }; + void SetValue (Bit8u value) { ahValue = value; }; + bool IsActive (void) { return active; }; void Activate (bool _active); EBreakpoint GetType (void) { return type; }; bool GetOnce (void) { return once; }; - PhysPt GetLocation (void) { if (GetType()==BKPNT_PHYSICAL) return location; else return 0; }; + PhysPt GetLocation (void) { if (GetType()!=BKPNT_INTERRUPT) return location; else return 0; }; Bit16u GetSegment (void) { return segment; }; Bit32u GetOffset (void) { return offset; }; - Bit8u GetIntNr (void) { if (GetType()==BKPNT_INTERRUPT) return intNr; else return 0; }; - Bit16u GetValue (void) { if (GetType()==BKPNT_INTERRUPT) return ahValue; else return 0; }; + Bit8u GetIntNr (void) { if (GetType()==BKPNT_INTERRUPT) return intNr; else return 0; }; + Bit16u GetValue (void) { if (GetType()!=BKPNT_PHYSICAL) return ahValue; else return 0; }; // statics static CBreakpoint* AddBreakpoint (Bit16u seg, Bit32u off, bool once); static CBreakpoint* AddIntBreakpoint (Bit8u intNum, Bit16u ah, bool once); + static CBreakpoint* AddMemBreakpoint (Bit16u seg, Bit32u off); static void ActivateBreakpoints (PhysPt adr, bool activate); static bool CheckBreakpoint (PhysPt adr); static bool CheckIntBreakpoint (PhysPt adr, Bit8u intNr, Bit16u ahValue); @@ -193,6 +197,16 @@ CBreakpoint* CBreakpoint::AddIntBreakpoint(Bit8u intNum, Bit16u ah, bool once) return bp; }; +CBreakpoint* CBreakpoint::AddMemBreakpoint(Bit16u seg, Bit32u off) +{ + CBreakpoint* bp = new CBreakpoint(); + bp->SetAddress (seg,off); + bp->SetOnce (false); + bp->SetType (BKPNT_MEMORY); + BPoints.push_front (bp); + return bp; +}; + void CBreakpoint::ActivateBreakpoints(PhysPt adr, bool activate) { // activate all breakpoints @@ -234,7 +248,23 @@ bool CBreakpoint::CheckBreakpoint(PhysPt adr) ignoreOnce = bp; }; return true; + } +#if C_HEAVY_DEBUG + // Memory breakpoint support + else if ((bp->GetType()==BKPNT_MEMORY) && bp->IsActive()) { + + Bit8u value = mem_readb(bp->GetLocation()); + if (bp->GetValue() != value) { + // Yup, memory value changed + char buffer[200]; + sprintf(buffer,"DEBUG: Memory breakpoint: %04X:%04X - %02X -> %02X",bp->GetSegment(),bp->GetOffset(),bp->GetValue(),value); + LOG_DEBUG(buffer); + bp->SetValue(value); + return true; + }; + }; +#endif }; return false; }; @@ -298,6 +328,7 @@ bool CBreakpoint::DeleteByIndex(Bit16u index) delete bp; return true; } + nr++; }; return false; }; @@ -359,14 +390,15 @@ void CBreakpoint::ShowList(void) for(i=BPoints.begin(); i != BPoints.end(); i++) { CBreakpoint* bp = static_cast(*i); if (bp->GetType()==BKPNT_PHYSICAL) { - PhysPt adr = bp->GetLocation(); - wprintw(dbg.win_out,"%02X. BP %04X:%04X\n",nr,bp->GetSegment(),bp->GetOffset()); nr++; } else if (bp->GetType()==BKPNT_INTERRUPT) { if (bp->GetValue()==BPINT_ALL) wprintw(dbg.win_out,"%02X. BPINT %02X\n",nr,bp->GetIntNr()); else wprintw(dbg.win_out,"%02X. BPINT %02X AH=%02X\n",nr,bp->GetIntNr(),bp->GetValue()); nr++; + } else if (bp->GetType()==BKPNT_MEMORY) { + wprintw(dbg.win_out,"%02X. BPMEM %04X:%04X (%02X)\n",nr,bp->GetSegment(),bp->GetOffset(),bp->GetValue()); + nr++; }; } wrefresh(dbg.win_out); @@ -632,8 +664,8 @@ bool ChangeRegister(char* str) if (strstr(hex,"DF")==hex) { hex+=2; flags.df = (GetHexValue(hex,hex)!=0); } else if (strstr(hex,"IF")==hex) { hex+=2; flags.intf = (GetHexValue(hex,hex)!=0); } else if (strstr(hex,"OF")==hex) { hex+=3; flags.of = (GetHexValue(hex,hex)!=0); } else - if (strstr(hex,"PF")==hex) { hex+=3; flags.pf = (GetHexValue(hex,hex)!=0); } else if (strstr(hex,"ZF")==hex) { hex+=3; flags.zf = (GetHexValue(hex,hex)!=0); } else + if (strstr(hex,"PF")==hex) { hex+=3; flags.pf = (GetHexValue(hex,hex)!=0); } else { return false; }; return true; }; @@ -651,6 +683,17 @@ bool ParseCommand(char* str) LOG_DEBUG("DEBUG: Set breakpoint at %04X:%04X",seg,ofs); return true; } +#if C_HEAVY_DEBUG + found = strstr(str,"BPM "); + if (found) { // Add new breakpoint + found+=3; + Bit16u seg = GetHexValue(found,found);found++; // skip ":" + Bit32u ofs = GetHexValue(found,found); + CBreakpoint::AddMemBreakpoint(seg,ofs); + LOG_DEBUG("DEBUG: Set memory breakpoint at %04X:%04X",seg,ofs); + return true; + } +#endif found = strstr(str,"BPINT"); if (found) { // Add Interrupt Breakpoint found+=5; @@ -759,6 +802,15 @@ bool ParseCommand(char* str) Interrupt(intNr); return true; } +#if C_HEAVY_DEBUG + found = strstr(str,"HEAVYLOG"); + if (found) { // Create Cpu log file + logHeavy = !logHeavy; + if (logHeavy) LOG_DEBUG("DEBUG: Heavy cpu logging on."); + else LOG_DEBUG("DEBUG: Heavy cpu logging off."); + return true; + } +#endif if ((*str=='H') || (*str=='?')) { wprintw(dbg.win_out,"Debugger keys:\n"); wprintw(dbg.win_out,"--------------------------------------------------------------------------\n"); @@ -774,11 +826,17 @@ bool ParseCommand(char* str) wprintw(dbg.win_out,"BP [segment]:[offset] - Set breakpoint\n"); wprintw(dbg.win_out,"BPINT [intNr] * - Set interrupt breakpoint\n"); wprintw(dbg.win_out,"BPINT [intNr] [ah] - Set interrupt breakpoint with ah\n"); +#if C_HEAVY_DEBUG + wprintw(dbg.win_out,"BPM [segment]:[offset] - Set memory breakpoint (memory change)\n"); +#endif wprintw(dbg.win_out,"BPLIST - List breakpoints\n"); wprintw(dbg.win_out,"BPDEL [bpNr] / * - Delete breakpoint nr / all\n"); wprintw(dbg.win_out,"C / D [segment]:[offset] - Set code / data view address\n"); wprintw(dbg.win_out,"INT [nr] / INTT [nr] - Execute / Trace into Iinterrupt\n"); wprintw(dbg.win_out,"LOG [num] - Write cpu log file\n"); +#if C_HEAVY_DEBUG + wprintw(dbg.win_out,"HEAVYLOG - Enable/Disable automatic cpu log for INT CD\n"); +#endif wprintw(dbg.win_out,"SR [reg] [value] - Set register value\n"); wprintw(dbg.win_out,"SM [seg]:[off] [val] [.]..- Set memory with following values\n"); wprintw(dbg.win_out,"H - Help\n"); @@ -943,6 +1001,17 @@ static void DEBUG_RaiseTimerIrq(void) { PIC_ActivateIRQ(0); } +static void LogInstruction(Bit16u segValue, Bit32u eipValue, char* buffer) +{ + PhysPt start = PhysMake(segValue,eipValue); + char dline[200];Bitu size; + size = DasmI386(dline, start, reg_eip, false); + Bitu len = strlen(dline); + if (len<30) for (Bitu i=0; i<30-len; i++) strcat(dline," "); + // Get register values + sprintf(buffer,"%04X:%08X %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X\n",segValue,eipValue,dline,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss),get_CF(),get_ZF(),get_SF(),get_OF(),get_AF(),get_PF()); +}; + static bool DEBUG_Log_Loop(int count) { char buffer[512]; @@ -958,19 +1027,13 @@ static bool DEBUG_Log_Loop(int count) { // Get disasm Bit16u csValue = SegValue(cs); Bit32u eipValue = reg_eip; - PhysPt start=Segs[cs].phys+reg_eip; - char dline[200];Bitu size; - size = DasmI386(dline, start, reg_eip, false); - Bitu len = strlen(dline); - if (len<30) for (Bitu i=0; i<30-len; i++) strcat(dline," "); + LogInstruction(csValue,eipValue,buffer); + fprintf(f,"%s",buffer); + PIC_IRQAgain=false; ret=(*cpudecoder)(1); - // Get register values - char buffer[512]; - sprintf(buffer,"%04X:%08X %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X\n",csValue,eipValue,dline,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss),get_CF(),get_ZF(),get_SF(),get_OF(),get_AF(),get_PF()); - fprintf(f,"%s",buffer); count--; if (count==0) break; @@ -1091,7 +1154,7 @@ void DEBUG_Init(Section* sec) { #if C_HEAVY_DEBUG -#define LOGCPUMAX 200 +const Bit16u LOGCPUMAX = 200; static Bit16u logCpuCS [LOGCPUMAX]; static Bit32u logCpuEIP[LOGCPUMAX]; @@ -1111,6 +1174,8 @@ void DEBUG_HeavyLogInstruction(void) void DEBUG_HeavyWriteLogInstruction(void) { + if (!logHeavy) return; + LOG_DEBUG("DEBUG: Creating cpu log LOGCPU_INT_CD.TXT"); FILE* f = fopen("LOGCPU_INT_CD.TXT","wt"); @@ -1123,7 +1188,7 @@ void DEBUG_HeavyWriteLogInstruction(void) do { // Write Intructions fprintf(f,"%s",logInst[startLog++].buffer); - if (startLog>=LOGCPUMAX) logCount = 0; + if (startLog>=LOGCPUMAX) startLog = 0; } while (startLog!=logCount); fclose(f); @@ -1133,6 +1198,9 @@ void DEBUG_HeavyWriteLogInstruction(void) bool DEBUG_HeavyIsBreakpoint(void) { + // LogInstruction + if (logHeavy) DEBUG_HeavyLogInstruction(); + if (skipFirstInstruction) { skipFirstInstruction = false; return false; From 66512e643e8cf77601008c6951e35d969a457072 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 14 Nov 2002 17:31:55 +0000 Subject: [PATCH 0422/4131] Added automatic cpu log call, if an "INT CD" occurs. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@500 --- src/cpu/cpu.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 51090e1c..62704f92 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -80,6 +80,10 @@ void Interrupt(Bit8u num) { case 0x74: break; case 0xcd: +#if C_HEAVY_DEBUG + LOG_DEBUG("Call to interrupt 0xCD this is BAD"); + DEBUG_HeavyWriteLogInstruction(); +#endif E_Exit("Call to interrupt 0xCD this is BAD"); case 0x03: #if C_DEBUG From 27bc85d9c15e4f96d9323fe42edccf01a5592a25 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 08:30:51 +0000 Subject: [PATCH 0423/4131] Removed ems/xms memory settings and removed the multithreading video updates. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@501 --- settings.h.cvs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/settings.h.cvs b/settings.h.cvs index af5707b7..f0580eb2 100644 --- a/settings.h.cvs +++ b/settings.h.cvs @@ -17,7 +17,7 @@ */ #ifndef _SETTINGS_H_ -#define _SETTINSG_H_ +#define _SETTINGS_H_ /* Enable the debugger, under linux/freebsd dosbox must be started in an xterm under X */ #define C_DEBUG 0 @@ -26,9 +26,6 @@ /* Enable the logging of extra information for debugging to the console */ #define C_LOGGING 0 -/* Use multi threading to speed up things on multi cpu's, also gives a nice frame-skipping effect :) */ -#define C_THREADED 1 - /* Enable some big compile-time increasing inlines, great for speed though */ #define C_EXTRAINLINE 0 @@ -38,12 +35,6 @@ /* Maximum memory range in megabytes */ #define C_MEM_MAX_SIZE 12 -/* Maximum memory available for xms, should be lower than maxsize-1 */ -#define C_MEM_XMS_SIZE 8 - -/* Maximum memory available for ems, should be lower than 32 */ -#define C_MEM_EMS_SIZE 4 - /* Enable debug messages for several modules, requires C_LOGGING */ #define DEBUG_SBLASTER 0 /* SoundBlaster Debugging*/ #define DEBUG_DMA 0 /* DMA Debugging */ From cf8a6f1afcc4c5a1aaf114947e98923fd2990efa Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 08:31:44 +0000 Subject: [PATCH 0424/4131] Added a new callback type with a sti instruction. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@502 --- include/callback.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/callback.h b/include/callback.h index 00a67457..065dd9b5 100644 --- a/include/callback.h +++ b/include/callback.h @@ -24,7 +24,7 @@ typedef Bitu (*CallBack_Handler)(void); extern CallBack_Handler CallBack_Handlers[]; -enum { CB_RETF,CB_IRET }; +enum { CB_RETF,CB_IRET,CB_IRET_STI }; #define CB_MAX 1024 #define CB_SEG 0xC800 From f5b3b79c95996dac2d219439583d1e4e49533861 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 08:32:32 +0000 Subject: [PATCH 0425/4131] New cpu decoder type. Added the new cpu timing variables for cycles. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@503 --- include/cpu.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index ca649584..f6f22814 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -19,20 +19,23 @@ #ifndef __CPU_H #define __CPU_H -#include -#include -#include +#include "dosbox.h" +#include "regs.h" +#include "mem.h" /* Some common Defines */ /* A CPU Handler */ -typedef Bitu (CPU_Decoder)(Bits count); +typedef Bitu (CPU_Decoder)(void); extern CPU_Decoder * cpudecoder; -extern Bitu cpu_cycles; + +/* CPU Cycle Timing */ +extern Bits CPU_Cycles; +extern Bits CPU_CycleLeft; +extern Bits CPU_CycleMax; //CPU Stuff void SetCPU16bit(); - //Types of Flag changing instructions enum { t_ADDb=0,t_ADDw,t_ADDd, @@ -63,9 +66,6 @@ enum { t_NOTDONE, }; -enum { rep_NONE,rep_Z,rep_NZ }; - - void Interrupt(Bit8u num); //Flag Handling From 30284bfaa42d972feb5af35828b9c25fe318dd72 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 08:33:33 +0000 Subject: [PATCH 0426/4131] New timing scheme lot's of new functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@504 --- include/pic.h | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/include/pic.h b/include/pic.h index e7b41be2..947166bb 100644 --- a/include/pic.h +++ b/include/pic.h @@ -19,7 +19,12 @@ #ifndef __PIC_H #define __PIC_H + +#include "cpu.h" + typedef void (PIC_EOIHandler) (void); +typedef void (* PIC_EventHandler)(void); + #define PIC_MAXIRQ 15 #define PIC_NOIRQ 0xFF @@ -27,7 +32,20 @@ typedef void (PIC_EOIHandler) (void); extern Bitu PIC_IRQCheck; extern Bitu PIC_IRQActive; -extern bool PIC_IRQAgain; + +extern Bitu PIC_Ticks; + +INLINE Bitu PIC_Index(void) { + return ((CPU_CycleMax-CPU_CycleLeft-CPU_Cycles)*1000)/CPU_CycleMax; +} + +INLINE Bits PIC_MakeCycles(Bitu amount) { + return (CPU_CycleMax*amount)/1000; +} + +INLINE Bit64u PIC_MicroCount(void) { + return PIC_Ticks*1000+PIC_Index(); +} void PIC_ActivateIRQ(Bit32u irq); @@ -37,8 +55,12 @@ void PIC_runIRQs(void); void PIC_RegisterIRQ(Bit32u irq,PIC_EOIHandler handler,char * name); void PIC_FreeIRQ(Bit32u irq); +Bitu PIC_RunQueue(void); +void PIC_AddIRQ(Bitu irq,Bitu delay); +void PIC_AddEvent(PIC_EventHandler handler,Bitu delay); +void PIC_RemoveEvents(PIC_EventHandler handler); #endif From b3a766a2fb334861c63de97937dee1ebbd508053 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 08:38:49 +0000 Subject: [PATCH 0427/4131] Cleaned up with new timing code replacing a lot of stuff here. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@505 --- include/timer.h | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/include/timer.h b/include/timer.h index 9c07747c..6511f932 100644 --- a/include/timer.h +++ b/include/timer.h @@ -21,15 +21,12 @@ /* underlying clock rate in HZ */ #include -extern Bit32u LastTicks; - #define PIT_TICK_RATE 1193182 #define GetTicks() SDL_GetTicks() typedef void (*TIMER_TickHandler)(Bitu ticks); typedef void (*TIMER_MicroHandler)(void); -typedef void (*TIMER_DelayHandler)(void); typedef void TIMER_Block; @@ -38,18 +35,12 @@ typedef void TIMER_Block; TIMER_Block * TIMER_RegisterTickHandler(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 From 6a16c109af9a0012f8af980015075d9d7be3ce09 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 08:39:57 +0000 Subject: [PATCH 0428/4131] New variables for the timing code and some general clean up. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@506 --- src/cpu/cpu.cpp | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 62704f92..18f2a313 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -30,21 +30,24 @@ Flag_Info flags; CPU_Regs cpu_regs; Segment Segs[6]; -Bitu cpu_cycles; + +Bits CPU_Cycles=0; +Bits CPU_CycleLeft=0; +Bits CPU_CycleMax=1500; CPU_Decoder * cpudecoder; static void CPU_CycleIncrease(void) { - Bitu old_cycles=cpu_cycles; - cpu_cycles=(Bitu)(cpu_cycles*1.2); - if (cpu_cycles==old_cycles) cpu_cycles++; - LOG_MSG("CPU:%d cycles",cpu_cycles); + Bitu old_cycles=CPU_CycleMax; + CPU_CycleMax=(Bitu)(CPU_CycleMax*1.2); + if (CPU_CycleMax==old_cycles) CPU_CycleMax++; + LOG_MSG("CPU:%d cycles",CPU_CycleMax); } static void CPU_CycleDecrease(void) { - cpu_cycles=(Bitu)(cpu_cycles/1.2); - if (!cpu_cycles) cpu_cycles=1; - LOG_MSG("CPU:%d cycles",cpu_cycles); + CPU_CycleMax=(Bitu)(CPU_CycleMax/1.2); + if (!CPU_CycleMax) CPU_CycleMax=1; + LOG_MSG("CPU:%d cycles",CPU_CycleMax); } Bit8u lastint; @@ -67,10 +70,10 @@ void Interrupt(Bit8u num) { case 0x11: case 0x12: case 0x13: - case 0x16: case 0x15: - case 0x1A: + case 0x16: case 0x17: + case 0x1A: case 0x1C: case 0x21: case 0x2a: @@ -167,13 +170,15 @@ void CPU_Init(Section* sec) { flags.io=0; SetCPU16bit(); - cpu_cycles=section->Get_int("cycles"); - if (!cpu_cycles) cpu_cycles=300; + KEYBOARD_AddEvent(KBD_f11,CTRL_PRESSED,CPU_CycleDecrease); KEYBOARD_AddEvent(KBD_f12,CTRL_PRESSED,CPU_CycleIncrease); - reg_al=0; - reg_ah=0; - MSG_Add("CPU_CONFIGFILE_HELP","The amount of cycles to execute each loop. Lowering this setting will slowdown dosbox\n"); + CPU_Cycles=0; + CPU_CycleMax=section->Get_int("cycles");; + if (!CPU_CycleMax) CPU_CycleMax=1500; + CPU_CycleLeft=0; + + MSG_Add("CPU_CONFIGFILE_HELP","The amount of cycles to execute each loop. Lowering this setting will slowdown dosbox\n"); } From 0dbbf37f9567800ce203f1ecd0776ed89b284404 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 08:40:43 +0000 Subject: [PATCH 0429/4131] New callback type with STI and the idle call steals some cycles to speed things up. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@507 --- src/cpu/callback.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index e2793592..7f52ce78 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -23,7 +23,7 @@ #include "callback.h" #include "mem.h" #include "cpu.h" - +#include "pic.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 @@ -62,6 +62,8 @@ void CALLBACK_Idle(void) { reg_eip=oldeip; SegSet16(cs,oldcs); flags.intf=oldintf; + if (CPU_CycleLeft<300) CPU_CycleLeft=1; + else CPU_CycleLeft-=300; } static Bitu default_handler(void) { @@ -119,17 +121,25 @@ bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type) { if (callback>=CB_MAX) return false; switch (type) { case CB_RETF: - real_writeb((Bit16u)CB_SEG,(callback<<4),(Bit8u)0xFE); //GRP 4 + real_writeb((Bit16u)CB_SEG,(callback<<4)+0,(Bit8u)0xFE); //GRP 4 real_writeb((Bit16u)CB_SEG,(callback<<4)+1,(Bit8u)0x38); //Extra Callback instruction real_writew((Bit16u)CB_SEG,(callback<<4)+2,callback); //The immediate word real_writeb((Bit16u)CB_SEG,(callback<<4)+4,(Bit8u)0xCB); //A RETF Instruction break; case CB_IRET: - real_writeb((Bit16u)CB_SEG,(callback<<4),(Bit8u)0xFE); //GRP 4 + real_writeb((Bit16u)CB_SEG,(callback<<4)+0,(Bit8u)0xFE); //GRP 4 real_writeb((Bit16u)CB_SEG,(callback<<4)+1,(Bit8u)0x38); //Extra Callback instruction real_writew((Bit16u)CB_SEG,(callback<<4)+2,callback); //The immediate word real_writeb((Bit16u)CB_SEG,(callback<<4)+4,(Bit8u)0xCF); //An IRET Instruction break; + case CB_IRET_STI: + real_writeb((Bit16u)CB_SEG,(callback<<4)+0,(Bit8u)0xFB); //STI + real_writeb((Bit16u)CB_SEG,(callback<<4)+1,(Bit8u)0xFE); //GRP 4 + real_writeb((Bit16u)CB_SEG,(callback<<4)+2,(Bit8u)0x38); //Extra Callback instruction + real_writew((Bit16u)CB_SEG,(callback<<4)+3,callback); //The immediate word + real_writeb((Bit16u)CB_SEG,(callback<<4)+5,(Bit8u)0xCF); //An IRET Instruction + break; + default: E_Exit("CALLBACK:Setup:Illegal type %d",type); From 3885bee68bfc6e2e98cd9e70082881a1f57681d2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 08:41:33 +0000 Subject: [PATCH 0430/4131] Changed main cpu core to use the new timing variables and removed some old stuff. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@508 --- src/cpu/slow_16.cpp | 39 +++++++++++---------------------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp index 5a1aa242..57edf9be 100644 --- a/src/cpu/slow_16.cpp +++ b/src/cpu/slow_16.cpp @@ -60,12 +60,11 @@ extern Bitu cycle_count; #endif #include "core_16/support.h" -static Bitu CPU_Real_16_Slow_Decode_Special(Bits count); -static Bitu CPU_Real_16_Slow_Decode_Trap(Bits count); +static Bitu CPU_Real_16_Slow_Decode_Trap(void); -static Bitu CPU_Real_16_Slow_Decode(Bits count) { +static Bitu CPU_Real_16_Slow_Decode(void) { #include "core_16/start.h" - do { + while (CPU_Cycles>0) { #if C_DEBUG cycle_count++; #endif @@ -73,43 +72,27 @@ static Bitu CPU_Real_16_Slow_Decode(Bits count) { SAVEIP; if (DEBUG_HeavyIsBreakpoint()) return CBRET_NONE; #endif - #include "core_16/main.h" - } while (--count>0); + #include "core_16/main.h" +// if (prefix.count) LOG_DEBUG("Prefix for non prefixed instruction"); + CPU_Cycles--; + } #include "core_16/stop.h" return CBRET_NONE; } -static Bitu CPU_Real_16_Slow_Decode_Trap(Bits count) -{ - CPU_Real_16_Slow_Decode(1); +static Bitu CPU_Real_16_Slow_Decode_Trap(void) { + + CPU_Real_16_Slow_Decode(); LOG_DEBUG("TRAP: Trap Flag executed"); INTERRUPT(1); cpudecoder=&CPU_Real_16_Slow_Decode; - return CBRET_NONE; -}; - -static Bitu CPU_Real_16_Slow_Decode_Special(Bits count) { - while (count>0) { - if (flags.tf) { - Interrupt(3); - cpudecoder=&CPU_Real_16_Slow_Decode; - return CBRET_NONE; - } - CPU_Real_16_Slow_Decode(1); - if (!flags.tf) { - cpudecoder=&CPU_Real_16_Slow_Decode; - return CBRET_NONE; - }; - count--; - } - return CBRET_NONE; } -void CPU_Real_16_Slow_Start(void) { +void CPU_Real_16_Slow_Start(void) { cpudecoder=&CPU_Real_16_Slow_Decode; EAPrefixTable[0]=&GetEA_16_n; EAPrefixTable[1]=&GetEA_16_s; From 41d41fd6960887498e651b8bd63df062e53a91ec Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 08:45:30 +0000 Subject: [PATCH 0431/4131] Added safety to inhibit interrupt with mov ss and pop ss. Changes to support the new repeat functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@509 --- src/cpu/core_16/main.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 2ba5b34a..fc03e3d5 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -66,7 +66,8 @@ restart: case 0x16: /* PUSH SS */ Push_16(SegValue(ss));break; case 0x17: /* POP SS */ - SegSet16(ss,Pop_16());break; + SegSet16(ss,Pop_16()); + goto restart; case 0x18: /* SBB Eb,Gb */ RMEbGb(SBBB);break; case 0x19: /* SBB Ew,Gw */ @@ -538,7 +539,7 @@ restart: case 0x28: /* MOV Ew,GS */ val=SegValue(gs);break; default: - val=0; + val=0; E_Exit("CPU:8c:Illegal RM Byte"); } if (rm >= 0xc0 ) {GetEArw;*earw=val;} @@ -566,7 +567,9 @@ restart: E_Exit("CPU:Illegal MOV CS Call"); break; case 0x10: /* MOV SS,Ew */ - SegSet16(ss,val);break; + SegSet16(ss,val); + goto restart; + break; case 0x18: /* MOV DS,Ew */ SegSet16(ds,val);break; case 0x20: /* MOV FS,Ew */ @@ -1029,11 +1032,11 @@ restart: E_Exit("CPU:F1:Not Handled"); break; case 0xf2: /* REPNZ */ - count-=Repeat_Normal(false,false,count); - break; + Repeat_Normal(false,false); + continue; case 0xf3: /* REPZ */ - count-=Repeat_Normal(true,false,count); - break; + Repeat_Normal(true,false); + continue; case 0xf4: /* HLT */ break; case 0xf5: /* CMC */ @@ -1323,6 +1326,5 @@ restart: default: NOTDONE; break; - } - + From 15c4369c3414413e123c3a9e81a076f9c29454d3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 08:46:10 +0000 Subject: [PATCH 0432/4131] Renamed some comments and changes to support new repeat. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@510 --- src/cpu/core_16/prefix_66.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index 8122692e..636a8f99 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -276,25 +276,25 @@ switch(Fetchb()) { } case 0x90: /* NOP */ break; - case 0x91: /* XCHG CX,AX */ + case 0x91: /* XCHG ECX,EAX */ { Bit32u temp=reg_eax;reg_eax=reg_ecx;reg_ecx=temp; } break; - case 0x92: /* XCHG DX,AX */ + case 0x92: /* XCHG EDX,EAX */ { Bit32u temp=reg_eax;reg_eax=reg_edx;reg_edx=temp; } break; - case 0x93: /* XCHG BX,AX */ + case 0x93: /* XCHG EBX,EAX */ { Bit32u temp=reg_eax;reg_eax=reg_ebx;reg_ebx=temp; } break; - case 0x94: /* XCHG SP,AX */ + case 0x94: /* XCHG ESP,EAX */ { Bit32u temp=reg_eax;reg_eax=reg_esp;reg_esp=temp; } break; - case 0x95: /* XCHG BP,AX */ + case 0x95: /* XCHG EBP,EAX */ { Bit32u temp=reg_eax;reg_eax=reg_ebp;reg_ebp=temp; } break; - case 0x96: /* XCHG SI,AX */ + case 0x96: /* XCHG ESI,EAX */ { Bit32u temp=reg_eax;reg_eax=reg_esi;reg_esi=temp; } break; - case 0x97: /* XCHG DI,AX */ + case 0x97: /* XCHG EDI,EAX */ { Bit32u temp=reg_eax;reg_eax=reg_edi;reg_edi=temp; } break; case 0x98: /* CWD */ @@ -396,12 +396,12 @@ switch(Fetchb()) { GRP2D(reg_cl);break; case 0xf2: /* REPNZ */ prefix.count++; - count-=Repeat_Normal(false,true,count); - break; + Repeat_Normal(false,true); + continue; case 0xf3: /* REPZ */ prefix.count++; - count-=Repeat_Normal(true,true,count); - break; + Repeat_Normal(true,true); + continue; case 0xf7: /* GRP3 Ed(,Id) */ { union { Bit64u u;Bit64s s;} temp; From fb4c46f187a6355291683dec0271365ddead235e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 08:47:00 +0000 Subject: [PATCH 0433/4131] added goto target to get out of the main loop. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@511 --- src/cpu/core_16/stop.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cpu/core_16/stop.h b/src/cpu/core_16/stop.h index 297949e4..68145d75 100644 --- a/src/cpu/core_16/stop.h +++ b/src/cpu/core_16/stop.h @@ -16,4 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +decode_end: + SAVEIP; From db94196bd4ec47663653709705b71698a0f37edc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 08:48:02 +0000 Subject: [PATCH 0434/4131] Changes to the repeat function to support new timing and handling of trap flag. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@512 --- src/cpu/core_16/support.h | 136 +++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 74 deletions(-) diff --git a/src/cpu/core_16/support.h b/src/cpu/core_16/support.h index 5201b75c..f288849d 100644 --- a/src/cpu/core_16/support.h +++ b/src/cpu/core_16/support.h @@ -102,9 +102,8 @@ static INLINE Bit32u Pop_32() { #include "instructions.h" -static Bits Repeat_Normal(bool testz,bool prefix_66,Bits count_remain) { +static void Repeat_Normal(bool testz,bool prefix_66) { - Bits count=count_remain; PhysPt base_si,base_di; Bit16s direct; @@ -143,16 +142,17 @@ rep_again: prefix_66=!prefix_66; goto rep_again; case 0x6c: /* REP INSB */ - for (;(reg_cx && count>0);reg_cx--,count--) { + for (;CPU_Cycles>0;CPU_Cycles--) { + if (!reg_cx) return; reg_cx--; SaveMb(base_di+reg_di,IO_Read(reg_dx)); reg_di+=direct; } - if (reg_cx && count<=0) goto countzero; break; case 0x6d: /* REP INSW/D */ if (prefix_66) { direct*=4; - for (;(reg_cx && count>0);reg_cx--,count--) { + for (;CPU_Cycles>0;CPU_Cycles--) { + if (!reg_cx) return; reg_cx--; SaveMb(base_di+reg_di+0,IO_Read(reg_dx+0)); SaveMb(base_di+reg_di+1,IO_Read(reg_dx+1)); SaveMb(base_di+reg_di+2,IO_Read(reg_dx+2)); @@ -161,25 +161,26 @@ rep_again: } } else { direct*=2; - for (;(reg_cx && count>0);reg_cx--,count--) { + for (;CPU_Cycles>0;CPU_Cycles--) { + if (!reg_cx) return; reg_cx--; SaveMb(base_di+reg_di+0,IO_Read(reg_dx+0)); SaveMb(base_di+reg_di+1,IO_Read(reg_dx+1)); reg_di+=direct; } } - if (reg_cx && count<=0) goto countzero; break; case 0x6e: /* REP OUTSB */ - for (;(reg_cx && count>0);reg_cx--,count--) { + for (;CPU_Cycles>0;CPU_Cycles--) { + if (!reg_cx) return; reg_cx--; IO_Write(reg_dx,LoadMb(base_si+reg_si)); reg_si+=direct; } - if (reg_cx && count<=0) goto countzero; break; case 0x6f: /* REP OUTSW/D */ if (prefix_66) { direct*=4; - for (;(reg_cx && count>0);reg_cx--,count--) { + for (;CPU_Cycles>0;CPU_Cycles--) { + if (!reg_cx) return; reg_cx--; IO_Write(reg_dx+0,LoadMb(base_si+reg_si+0)); IO_Write(reg_dx+1,LoadMb(base_si+reg_si+1)); IO_Write(reg_dx+2,LoadMb(base_si+reg_si+2)); @@ -188,161 +189,152 @@ rep_again: } } else { direct*=2; - for (;(reg_cx && count>0);reg_cx--,count--) { + for (;CPU_Cycles>0;CPU_Cycles--) { + if (!reg_cx) return; reg_cx--; IO_Write(reg_dx+0,LoadMb(base_si+reg_si+0)); IO_Write(reg_dx+1,LoadMb(base_si+reg_si+1)); reg_si+=direct; } } - if (reg_cx && count<=0) goto countzero; break; case 0xa4: /* REP MOVSB */ - for (;(reg_cx && count>0);reg_cx--,count--) { + for (;CPU_Cycles>0;CPU_Cycles--) { + if (!reg_cx) return; reg_cx--; SaveMb(base_di+reg_di,LoadMb(base_si+reg_si)); reg_si+=direct;reg_di+=direct; } - if (reg_cx && count<=0) goto countzero; break; case 0xa5: /* REP MOVSW/D */ if (prefix_66) { direct*=4; - for (;(reg_cx && count>0);reg_cx--,count--) { + for (;CPU_Cycles>0;CPU_Cycles--) { + if (!reg_cx) return; reg_cx--; SaveMd(base_di+reg_di,LoadMd(base_si+reg_si)); reg_si+=direct;reg_di+=direct; } } else { direct*=2; - for (;(reg_cx && count>0);reg_cx--,count--) { + for (;CPU_Cycles>0;CPU_Cycles--) { + if (!reg_cx) return; reg_cx--; SaveMw(base_di+reg_di,LoadMw(base_si+reg_si)); reg_si+=direct;reg_di+=direct; } } - if (reg_cx && count<=0) goto countzero; break; case 0xa6: /* REP CMPSB */ { - if (!reg_cx) goto stopit;Bit8u op1,op2; - for (;(reg_cx && count>0);) { + Bit8u op1,op2; + if (!reg_cx) { CPU_Cycles--;return; } + for (;CPU_Cycles>0;CPU_Cycles--) { op1=LoadMb(base_si+reg_si);op2=LoadMb(base_di+reg_di); - reg_cx--,count--;reg_si+=direct;reg_di+=direct; - if ((op1==op2)!=testz) break; + reg_cx--;reg_si+=direct;reg_di+=direct; + if ((op1==op2)!=testz || !reg_cx) { CMPB(op1,op2,LoadRb,0);return; } } CMPB(op1,op2,LoadRb,0); - if ((op1==op2)!=testz) goto stopit; - if (reg_cx && count<=0) goto countzero; } break; case 0xa7: /* REP CMPSW */ { - if (!reg_cx) goto stopit; + if (!reg_cx) { CPU_Cycles--;return; } if (prefix_66) { - direct*=4; - Bit32u op1,op2; - for (;(reg_cx && count>0);) { + direct*=4;Bit32u op1,op2; + for (;CPU_Cycles>0;CPU_Cycles--) { op1=LoadMd(base_si+reg_si);op2=LoadMd(base_di+reg_di); - reg_cx--,count--;reg_si+=direct;reg_di+=direct; - if ((op1==op2)!=testz) break; + reg_cx--;reg_si+=direct;reg_di+=direct; + if ((op1==op2)!=testz || !reg_cx) { CMPD(op1,op2,LoadRd,0);return; } } CMPD(op1,op2,LoadRd,0); - if ((op1==op2)!=testz) goto stopit; } else { - direct*=2; - Bit16u op1,op2; - for (;(reg_cx && count>0);) { + direct*=2;Bit16u op1,op2; + for (;CPU_Cycles>0;CPU_Cycles--) { op1=LoadMw(base_si+reg_si);op2=LoadMw(base_di+reg_di); - reg_cx--,count--;reg_si+=direct;reg_di+=direct; - if ((op1==op2)!=testz) break; + reg_cx--,reg_si+=direct;reg_di+=direct; + if ((op1==op2)!=testz || !reg_cx) { CMPW(op1,op2,LoadRw,0);return; } } CMPW(op1,op2,LoadRw,0); - if ((op1==op2)!=testz) goto stopit; } - if (reg_cx && count<=0) goto countzero; } break; case 0xaa: /* REP STOSB */ - for (;(reg_cx && count>0);reg_cx--,count--) { + for (;CPU_Cycles>0;CPU_Cycles--) { + if (!reg_cx) return; reg_cx--; SaveMb(base_di+reg_di,reg_al); reg_di+=direct; } - if (reg_cx && count<=0) goto countzero; break; case 0xab: /* REP STOSW */ if (prefix_66) { direct*=4; - for (;(reg_cx && count>0);reg_cx--,count--) { + for (;CPU_Cycles>0;CPU_Cycles--) { + if (!reg_cx) return; reg_cx--; SaveMd(base_di+reg_di,reg_eax); reg_di+=direct; } } else { direct*=2; - for (;(reg_cx && count>0);reg_cx--,count--) { + for (;CPU_Cycles>0;CPU_Cycles--) { + if (!reg_cx) return; reg_cx--; SaveMw(base_di+reg_di,reg_ax); reg_di+=direct; } } - if (reg_cx && count<=0) goto countzero; break; case 0xac: /* REP LODSB */ - for (;(reg_cx && count>0);reg_cx--,count--) { + for (;CPU_Cycles>0;CPU_Cycles--) { + if (!reg_cx) return; reg_cx--; reg_al=LoadMb(base_si+reg_si); reg_si+=direct; } - if (reg_cx && count<=0) goto countzero; break; case 0xad: /* REP LODSW */ if (prefix_66) { direct*=4; - for (;(reg_cx && count>0);reg_cx--,count--) { + for (;CPU_Cycles>0;CPU_Cycles--) { + if (!reg_cx) return; reg_cx--; reg_eax=LoadMd(base_si+reg_si); reg_si+=direct; } } else { direct*=2; - for (;(reg_cx && count>0);reg_cx--,count--) { + for (;CPU_Cycles>0;CPU_Cycles--) { + if (!reg_cx) return; reg_cx--; reg_ax=LoadMw(base_si+reg_si); reg_si+=direct; } } - if (reg_cx && count<=0) goto countzero; break; case 0xae: /* REP SCASB */ { - if (!reg_cx) goto stopit;Bit8u op2; - for (;(reg_cx && count>0);) { + Bit8u op2; + if (!reg_cx) { CPU_Cycles--;return; } + for (;CPU_Cycles>0;CPU_Cycles--) { op2=LoadMb(base_di+reg_di); - reg_cx--,count--;reg_di+=direct; - if ((reg_al==op2)!=testz) break; + reg_cx--;reg_di+=direct; + if ((reg_al==op2)!=testz || !reg_cx) { CMPB(reg_al,op2,LoadRb,0);return; } } CMPB(reg_al,op2,LoadRb,0); - if ((reg_al==op2)!=testz) goto stopit; - if (reg_cx && count<=0) goto countzero; } break; case 0xaf: /* REP SCASW */ { - if (!reg_cx) goto stopit; + if (!reg_cx) { CPU_Cycles--;return; } if (prefix_66) { - direct*=4; - Bit32u op2; - for (;(reg_cx && count>0);) { + direct*=4;Bit32u op2; + for (;CPU_Cycles>0;CPU_Cycles--) { op2=LoadMd(base_di+reg_di); - reg_cx--,count--;reg_di+=direct; - if ((reg_eax==op2)!=testz) break; + reg_cx--;reg_di+=direct; + if ((reg_eax==op2)!=testz || !reg_cx) { CMPD(reg_eax,op2,LoadRd,0);return; } } CMPD(reg_eax,op2,LoadRd,0); - if ((reg_eax==op2)!=testz) goto stopit; } else { - direct*=2; - Bit16u op2; - for (;(reg_cx && count>0);) { + direct*=2;Bit16u op2; + for (;CPU_Cycles>0;CPU_Cycles--) { op2=LoadMw(base_di+reg_di); - reg_cx--,count--;reg_di+=direct; - if ((reg_ax==op2)!=testz) break; + reg_cx--;reg_di+=direct; + if ((reg_ax==op2)!=testz || !reg_cx) { CMPW(reg_ax,op2,LoadRw,0);return; } } CMPW(reg_ax,op2,LoadRw,0); - if ((reg_ax==op2)!=testz) goto stopit; } - if (reg_cx && count<=0) goto countzero; } break; default: @@ -350,13 +342,9 @@ rep_again: LOG_DEBUG("Unhandled REP Prefix %X",Fetchb()); } -stopit: - PrefixReset; - return count_remain-count; -countzero: + /* If we end up here it's because the CPU_Cycles counter is 0, so restart instruction */ IPPoint-=(prefix.count+2); /* Rep instruction and whatever string instruction */ PrefixReset; - return count_remain; } //flags.io and nt shouldn't be compiled for 386 @@ -378,7 +366,7 @@ countzero: } \ if (flags.tf) { \ cpudecoder=&CPU_Real_16_Slow_Decode_Trap; \ - count=0; \ + goto decode_end; \ } \ } @@ -399,7 +387,7 @@ countzero: } \ if (flags.tf) { \ cpudecoder=&CPU_Real_16_Slow_Decode_Trap; \ - count=0; \ + goto decode_end; \ } \ } From d02e40e5fb4b00f142b4de8285731124f19726b0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 08:48:58 +0000 Subject: [PATCH 0435/4131] Some fixes to 32bit ea look ups. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@513 --- src/cpu/core_16/table_ea.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_16/table_ea.h b/src/cpu/core_16/table_ea.h index 48fd12a0..e5aef7e7 100644 --- a/src/cpu/core_16/table_ea.h +++ b/src/cpu/core_16/table_ea.h @@ -246,7 +246,7 @@ 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_06_n(void) { return SegBase(ds)+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(); } @@ -346,7 +346,7 @@ static EAPoint EA_32_40_s(void) { segprefixed_32(reg_eax+Fetchbs()); } static EAPoint EA_32_41_s(void) { segprefixed_32(reg_ecx+Fetchbs()); } static EAPoint EA_32_42_s(void) { segprefixed_32(reg_edx+Fetchbs()); } static EAPoint EA_32_43_s(void) { segprefixed_32(reg_ebx+Fetchbs()); } -static EAPoint EA_32_44_s(void) { return Sib(1)+Fetchbs();} +static EAPoint EA_32_44_s(void) { return Sib_s(1)+Fetchbs();} static EAPoint EA_32_45_s(void) { segprefixed_32(reg_ebp+Fetchbs()); } static EAPoint EA_32_46_s(void) { segprefixed_32(reg_esi+Fetchbs()); } static EAPoint EA_32_47_s(void) { segprefixed_32(reg_edi+Fetchbs()); } @@ -355,7 +355,7 @@ static EAPoint EA_32_80_s(void) { segprefixed_32(reg_eax+Fetchds()); } static EAPoint EA_32_81_s(void) { segprefixed_32(reg_ecx+Fetchds()); } static EAPoint EA_32_82_s(void) { segprefixed_32(reg_edx+Fetchds()); } static EAPoint EA_32_83_s(void) { segprefixed_32(reg_ebx+Fetchds()); } -static EAPoint EA_32_84_s(void) { return Sib(2)+Fetchds();} +static EAPoint EA_32_84_s(void) { return Sib_s(2)+Fetchds();} static EAPoint EA_32_85_s(void) { segprefixed_32(reg_ebp+Fetchds()); } static EAPoint EA_32_86_s(void) { segprefixed_32(reg_esi+Fetchds()); } static EAPoint EA_32_87_s(void) { segprefixed_32(reg_edi+Fetchds()); } From 0909acf08549e609faedf06ef3561b528da55b3a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 08:50:30 +0000 Subject: [PATCH 0436/4131] Removed the callback idle calls, no longer needed with new callback type. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@514 --- src/dos/dos.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 9d5e7c0c..75d0a798 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -262,6 +262,7 @@ static Bitu DOS_21Handler(void) { } break; case 0x1f: /* Get drive parameter block for default drive */ + case 0x32: /* Get drive parameter block for specific drive */ E_Exit("DOS:Unhandled call %02X",reg_ah); break; /* TODO maybe but hardly think a game needs this */ @@ -273,7 +274,6 @@ static Bitu DOS_21Handler(void) { break; case 0x2a: /* Get System Date */ { - CALLBACK_Idle(); /* sure ? */ int a = (14 - dos.date.month)/12; int y = dos.date.year - a; int m = dos.date.month + 12*a - 2; @@ -295,7 +295,6 @@ static Bitu DOS_21Handler(void) { case 0x2c: /* Get System Time */ //TODO Get time through bios calls date is fixed { - CALLBACK_Idle(); Bit32u ticks=mem_readd(BIOS_TIMER); Bit32u seconds=(ticks*10)/182; reg_ch=(Bit8u)(seconds/3600); @@ -850,7 +849,7 @@ void DOS_Init(Section* sec) { RealSetVec(0x20,CALLBACK_RealPointer(call_20)); call_21=CALLBACK_Allocate(); - CALLBACK_Setup(call_21,DOS_21Handler,CB_IRET); + CALLBACK_Setup(call_21,DOS_21Handler,CB_IRET_STI); RealSetVec(0x21,CALLBACK_RealPointer(call_21)); call_27=CALLBACK_Allocate(); From 5229f349f05d49cac33b487333d0ad30f7ff2dba Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 08:51:15 +0000 Subject: [PATCH 0437/4131] Removed multithreaded video updates. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@515 --- src/gui/sdlmain.cpp | 48 ++------------------------------------------- 1 file changed, 2 insertions(+), 46 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index fc73a858..c0d9222a 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include "dosbox.h" #include "video.h" @@ -33,7 +32,6 @@ //#define DISABLE_JOYSTICK - struct SDL_Block { bool active; //If this isn't set don't draw Bitu width; @@ -42,8 +40,6 @@ struct SDL_Block { GFX_DrawHandler * draw; GFX_ResizeHandler * resize; bool full_screen; - SDL_Thread * thread; - SDL_mutex * mutex; SDL_Surface * surface; SDL_Joystick * joy; SDL_Color pal[256]; @@ -82,7 +78,7 @@ static void RestorePalette(void) { static void ResetScreen(void) { if (sdl.full_screen) { /* First get the original resolution */ - sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN|SDL_DOUBLEBUF); + sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_SWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN); } else { sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_SWSURFACE|SDL_RESIZABLE); } @@ -148,12 +144,6 @@ void GFX_SwitchFullScreen(void) { } static void GFX_Redraw() { -#if C_THREADED - if (SDL_mutexP(sdl.mutex)) { - E_Exit("Can't Lock Mutex"); - }; -#endif - if (++sdl.frames.countGet_int("sensitivity"); GFX_Resize(640,400,8,0); -#if C_THREADED - sdl.mutex=SDL_CreateMutex(); - sdl.thread = SDL_CreateThread(&SDLGFX_Thread,0); -#else TIMER_RegisterMicroHandler(GFX_Redraw,1000000/70); -#endif SDL_EnableKeyRepeat(250,30); /* Get some Keybinds */ From e0fc0b6971f78470814d5e4b9a777afef7bb5554 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 08:56:27 +0000 Subject: [PATCH 0438/4131] New PIC timing code to support microsecond events. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@516 --- src/hardware/pic.cpp | 212 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 201 insertions(+), 11 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 68ad22da..971fd029 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -22,6 +22,8 @@ #include "cpu.h" #include "pic.h" +#define PIC_QUEUESIZE 128 + struct IRQ_Block { bool masked; bool active; @@ -31,9 +33,10 @@ struct IRQ_Block { PIC_EOIHandler * handler; }; +Bitu PIC_Ticks=0; + Bitu PIC_IRQCheck; Bitu PIC_IRQActive; -bool PIC_IRQAgain; static IRQ_Block irqs[16]; static Bit8u pic0_icws=0; @@ -42,10 +45,29 @@ static Bit8u pic0_icw_state=0; static Bit8u pic1_icw_state=0; static bool pic0_request_iisr=0; static bool pic1_request_iisr=0; -//TODO Special mask mode in ocw3 -//TODO maybe check for illegal modes that don't work on pc too and exit the emu -//Pic 0 command port +enum QUEUE_TYPE { + IRQ,EVENT +}; + + + + +struct PICEntry { + QUEUE_TYPE type; + Bitu irq; + Bitu index; + PIC_EventHandler event; + PICEntry * next; +}; + + +static struct { + PICEntry entries[PIC_QUEUESIZE]; + PICEntry * free_entry; + PICEntry * next_entry; +} pic; + static void write_p20(Bit32u port,Bit8u val) { switch (val) { case 0x0A: /* select read interrupt request register */ @@ -63,7 +85,14 @@ static void write_p20(Bit32u port,Bit8u val) { pic0_icw_state=1; break; case 0x20: /* end of interrupt command */ - /* clear highest current in service bit */ + case 0x21: /* end of interrupt command */ + case 0x22: /* end of interrupt command */ + case 0x23: /* end of interrupt command */ + case 0x24: /* end of interrupt command */ + case 0x25: /* end of interrupt command */ + case 0x26: /* end of interrupt command */ + case 0x27: /* end of interrupt command */ + /* clear highest current in service bit */ if (PIC_IRQActive<8) { irqs[PIC_IRQActive].inservice=false; if (irqs[PIC_IRQActive].handler!=0) irqs[PIC_IRQActive].handler(); @@ -111,14 +140,14 @@ static void write_p21(Bit32u port,Bit8u val) { else PIC_IRQCheck&=~(1 << i); }; break; - case 1: /* icw2 */ + case 1: /* icw2 */ + LOG_DEBUG("PIC0:Base vector %X",val); for (i=0;i<=7;i++) { irqs[i].vector=(val&0xf8)+i; }; default: /* icw2, 3, and 4*/ if(pic0_icw_state++ >= pic0_icws) pic0_icw_state=0; } - } static Bit8u read_p20(Bit32u port) { @@ -174,6 +203,13 @@ static void write_pa0(Bit32u port,Bit8u val) { pic1_icw_state=1; break; case 0x20: /* end of interrupt command */ + case 0x21: /* end of interrupt command */ + case 0x22: /* end of interrupt command */ + case 0x23: /* end of interrupt command */ + case 0x24: /* end of interrupt command */ + case 0x25: /* end of interrupt command */ + case 0x26: /* end of interrupt command */ + case 0x27: /* end of interrupt command */ /* clear highest current in service bit */ if (PIC_IRQActive>7 && PIC_IRQActive <16) { irqs[PIC_IRQActive].inservice=false; @@ -218,7 +254,6 @@ static void write_pa1(Bit32u port,Bit8u val) { case 0: /* mask register */ for (i=0;i<=7;i++) { irqs[i+8].masked=(val&1 <0; - if (!irqs[8].masked) LOG_DEBUG("Someone unmasked RTC irq"); }; break; case 1: /* icw2 */ @@ -292,7 +327,7 @@ void PIC_DeActivateIRQ(Bit32u irq) { } void PIC_runIRQs(void) { - Bit32u i; + Bitu i; if (!flags.intf) return; if (PIC_IRQActive!=PIC_NOIRQ) return; if (!PIC_IRQCheck) return; @@ -304,19 +339,166 @@ void PIC_runIRQs(void) { PIC_IRQCheck&=~(1 << i); Interrupt(irqs[i].vector); PIC_IRQActive=i; - PIC_IRQAgain=true; return; } } } } +static void AddEntry(PICEntry * entry) { + PICEntry * find_entry=pic.next_entry; + if (!find_entry) { + entry->next=0; + pic.next_entry=entry; + return; + } + if (find_entry->index>entry->index) { + pic.next_entry=entry; + entry->next=find_entry; + return; + } + while (find_entry) { + if (find_entry->next) { + /* See if the next index comes later than this one */ + if (find_entry->next->index>entry->index) { + entry->next=find_entry->next; + find_entry->next=entry; + return; + } else { + find_entry=find_entry->next; + } + } else { + entry->next=find_entry->next; + find_entry->next=entry; + return; + } + } +} + +void PIC_AddEvent(PIC_EventHandler handler,Bitu delay) { + if (!pic.free_entry) { + LOG_WARN("PIC:No free queue entries"); + return; + } + PICEntry * entry=pic.free_entry; + Bitu index=delay+PIC_Index(); + entry->index=index; + entry->event=handler; + entry->type=EVENT; + pic.free_entry=pic.free_entry->next; + AddEntry(entry); +} + +void PIC_AddIRQ(Bitu irq,Bitu delay) { + if (irq>15) E_Exit("PIC:Illegal IRQ"); + if (!pic.free_entry) { + LOG_WARN("PIC:No free queue entries"); + return; + } + PICEntry * entry=pic.free_entry; + Bitu index=delay+PIC_Index(); + entry->index=index; + entry->irq=irq; + entry->type=IRQ; + pic.free_entry=pic.free_entry->next; + AddEntry(entry); +} + + +void PIC_RemoveEvents(PIC_EventHandler handler) { + PICEntry * entry=pic.next_entry; + PICEntry * prev_entry; + prev_entry=0; + while (entry) { + switch (entry->type) { + case EVENT: + if (entry->event==handler) { + if (prev_entry) { + prev_entry->next=entry->next; + entry->next=pic.free_entry; + pic.free_entry=entry; + entry=prev_entry->next; + continue; + } else { + pic.next_entry=entry->next; + entry->next=pic.free_entry; + pic.free_entry=entry; + entry=pic.next_entry; + continue; + } + } + break; + } + prev_entry=entry; + entry=entry->next; + } +} + +Bitu PIC_RunQueue(void) { + Bitu ret; + /* Check to see if a new milisecond needs to be started */ + if (CPU_Cycles>0) { + CPU_CycleLeft+=CPU_Cycles; + CPU_Cycles=0; + } + if (CPU_CycleLeft<=0) { + CPU_CycleLeft=CPU_CycleMax; + } + while (CPU_CycleLeft>0) { + /* Check the queue for an entry */ + Bitu index=PIC_Index(); + while (pic.next_entry && pic.next_entry->index<=index) { + PICEntry * entry=pic.next_entry; + pic.next_entry=entry->next; + switch (entry->type) { + case EVENT: + (entry->event)(); + break; + case IRQ: + PIC_ActivateIRQ(entry->irq); + break; + } + /* Put the entry in the free list */ + entry->next=pic.free_entry; + pic.free_entry=entry; + } + /* Check when to set the new cycle end */ + if (pic.next_entry) { + Bits cycles=PIC_MakeCycles(pic.next_entry->index-index); + if (!cycles) cycles=1; + if (cycles0) { + CPU_CycleLeft+=CPU_Cycles; + CPU_Cycles=0; + } + if (ret) return ret; + } + /* Go through the list of scheduled irq's and lower their index with 1000 */ + PIC_Ticks++; + PICEntry * entry=pic.next_entry; + while (entry) { + if (entry->index>1000) entry->index-=1000; + else entry->index=0; + entry=entry->next; + } + return 0; +} void PIC_Init(Section* sec) { /* Setup pic0 and pic1 with initial values like DOS has normally */ PIC_IRQCheck=0; PIC_IRQActive=PIC_NOIRQ; - Bit8u i; + PIC_Ticks=0; + Bitu i; for (i=0;i<=7;i++) { irqs[i].active=false; irqs[i].masked=true; @@ -338,6 +520,14 @@ void PIC_Init(Section* sec) { IO_RegisterReadHandler(0xa1,read_pa1,"Slave PIC Data"); IO_RegisterWriteHandler(0xa0,write_pa0,"Slave PIC Command"); IO_RegisterWriteHandler(0xa1,write_pa1,"Slave PIC Data"); + /* Initialize the pic queue */ + for (i=0;i Date: Sun, 17 Nov 2002 11:17:30 +0000 Subject: [PATCH 0439/4131] New timer code and timer event handling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@517 --- src/hardware/timer.cpp | 138 ++++++++++++++--------------------------- 1 file changed, 45 insertions(+), 93 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 758a8a07..56d31ea3 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -33,44 +33,38 @@ struct PIT_Block { Bit8u mode; /* Current Counter Mode */ - Bit32s cntr; + + Bitu cntr; + Bits micro; + Bit64u start; + Bit8u latch_mode; Bit8u read_state; Bit16s read_latch; Bit8u write_state; Bit16u write_latch; - Bit32u last_ticks; }; -bool TimerAgain; -Bit32u LastTicks; static PIT_Block pit[3]; -static Bit32u pit_ticks; /* The amount of pit ticks one host tick is bit shifted */ -static Bit32u timer_ticks; /* The amount of pit ticks bitshifted one timer cycle needs */ -static Bit32u timer_buildup; /* The amount of pit ticks waiting */ - -#define TIMER_AVERAGE 5 -static struct TimerBlock { - float req[TIMER_AVERAGE]; - Bitu req_index; - Bitu req_count; - float req_average; - Bitu ticks; -} timer; - -#define PIT_SHIFT 9 -#define MAX_PASSED ((PIT_TICK_RATE/4) << PIT_SHIFT) /* Alow 1/4 second of timer build up */ +static void PIT0_Event(void) { + PIC_ActivateIRQ(0); + PIC_AddEvent(PIT0_Event,pit[0].micro); +} static void counter_latch(Bitu counter) { /* Fill the read_latch of the selected counter with current count */ PIT_Block * p=&pit[counter]; - timer.req_count++; - float pos=timer.req_average*timer.req_count; - Bit16u ticks=pos*p->cntr; + + Bit64u micro=PIC_MicroCount(); + micro-=p->start; + micro%=p->micro; + Bit16u ticks=(Bit16u)(((float)micro/(float)p->micro)*(float)p->cntr); + switch (p->mode) { case 2: case 3: + case 4: p->read_latch=(Bit16u)ticks; break; default: @@ -81,9 +75,8 @@ static void counter_latch(Bitu counter) { } - static void write_latch(Bit32u port,Bit8u val) { - Bit32u counter=port-0x40; + Bitu counter=port-0x40; PIT_Block * p=&pit[counter]; switch (p->write_state) { case 0: @@ -104,12 +97,12 @@ static void write_latch(Bit32u port,Bit8u val) { if (p->write_state != 0) { if (p->write_latch == 0) p->cntr = 0x10000; else p->cntr = p->write_latch; - p->last_ticks=LastTicks; + p->start=PIC_MicroCount(); + p->micro=1000000/((float)PIT_TICK_RATE/(float)p->cntr); switch (counter) { case 0x00: /* Timer hooked to IRQ 0 */ - PIC_DeActivateIRQ(0); - timer_ticks=p->cntr << PIT_SHIFT; - timer_buildup=0; + PIC_RemoveEvents(PIT0_Event); + PIC_AddEvent(PIT0_Event,p->micro); LOG_DEBUG("PIT 0 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode); break; case 0x02: /* Timer hooked to PC-Speaker */ @@ -118,7 +111,6 @@ static void write_latch(Bit32u port,Bit8u val) { default: LOG_ERROR("PIT:Illegal timer selected for writing"); } - } } @@ -194,14 +186,10 @@ struct Timer { TIMER_TickHandler handler; } tick; struct{ - Bitu count; - Bitu total; + Bits left; + Bits total; TIMER_MicroHandler handler; } micro; - struct { - Bitu end; - TIMER_DelayHandler handler; - } delay; }; }; @@ -220,85 +208,51 @@ TIMER_Block * TIMER_RegisterMicroHandler(TIMER_MicroHandler handler,Bitu micro) Timer * new_timer=new(Timer); new_timer->type=T_MICRO; new_timer->micro.handler=handler; - new_timer->micro.total=micro; - new_timer->micro.count=0; Timers.push_front(new_timer); + TIMER_SetNewMicro(new_timer,micro); return (TIMER_Block *)new_timer; } -TIMER_Block * TIMER_RegisterDelayHandler(TIMER_DelayHandler handler,Bitu delay) { -//Todo maybe check for a too long delay - Timer * new_timer=new(Timer); - new_timer->type=T_DELAY; - new_timer->delay.handler=handler; - new_timer->delay.end=LastTicks+delay; - Timers.push_front(new_timer); - return (TIMER_Block *)new_timer; - -} void TIMER_SetNewMicro(TIMER_Block * block,Bitu micro) { Timer * timer=(Timer *)block; if (timer->type!=T_MICRO) E_Exit("TIMER:Illegal handler type"); - timer->micro.count=0; timer->micro.total=micro; + Bitu index=PIC_Index(); + while ((1000-index)>micro) { + PIC_AddEvent(timer->micro.handler,micro); + micro+=micro; + index+=micro; + } + timer->micro.left=timer->micro.total-(1000-index); } -void TIMER_AddTicks(Bit32u ticks) { -/* Add pit ticks to the counter */ - timer_buildup+=ticks*pit_ticks; - if (timer_buildup>MAX_PASSED) timer_buildup=MAX_PASSED; +void TIMER_AddTick(void) { + Bits index; /* Check if there are timer handlers that need to be called */ - Bitu add_micro=timer.ticks*1000; std::list::iterator i; for(i=Timers.begin(); i != Timers.end(); ++i) { Timer * timers=(*i); switch (timers->type) { case T_TICK: - if (timer.ticks) timers->tick.handler(timer.ticks); + timers->tick.handler(1); break; case T_MICRO: - timers->micro.count+=add_micro; - if (timers->micro.count>=timers->micro.total) { - timers->micro.count-=timers->micro.total; - timers->micro.handler(); - } - break; - case T_DELAY: - /* Also unregister the timer handler from the list */ - if (LastTicks>timers->delay.end) { - std::list::iterator remove; - timers->delay.handler(); - remove=i++; - Timers.erase(remove); + index=1000; + while (index>=timers->micro.left) { + PIC_AddEvent(timers->micro.handler,timers->micro.left); + index-=timers->micro.left; + timers->micro.left=timers->micro.total; } + timers->micro.left-=index; break; default: E_Exit("TIMER:Illegal handler type"); - }; + } - }; - timer.ticks=ticks; -} - - -void TIMER_CheckPIT(void) { - if (timer_buildup>timer_ticks) { - timer_buildup-=timer_ticks; - /* Calculate amount of times the time index was requested */ - timer.req[timer.req_index]=timer.req_count; - timer.req_index++;if (timer.req_index>=TIMER_AVERAGE) timer.req_index=0; - timer.req_count=0; - Bitu l;float total=0; - for (l=0;l Date: Sun, 17 Nov 2002 11:18:18 +0000 Subject: [PATCH 0440/4131] new event code for resize. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@518 --- src/hardware/vga.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 310b6d15..dac94628 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -124,7 +124,8 @@ static void VGA_DoResize(void) { case TEXT_16: /* probably a 16-color text mode, got to detect mono mode somehow */ width<<=3; /* 8 bit wide text font */ - height<<=4; /* 16 bit font height */ + vga.draw.font_height=vga.config.vline_height+1; + height<<=4; if (width>640) width=640; if (height>480) height=480; pitch=width; @@ -141,7 +142,7 @@ void VGA_StartResize(void) { if (!vga.draw.resizing) { vga.draw.resizing=true; /* Start a resize after 50 ms */ - TIMER_RegisterDelayHandler(VGA_DoResize,50); + PIC_AddEvent(VGA_DoResize,500); } } From 04a152a74380e636caf26ba270dc928ed2fd342b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 11:18:25 +0000 Subject: [PATCH 0441/4131] Added a retrace function. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@519 --- src/hardware/vga.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/vga.h b/src/hardware/vga.h index 1ebc643f..88e9ce4d 100644 --- a/src/hardware/vga.h +++ b/src/hardware/vga.h @@ -243,6 +243,7 @@ void VGA_SetupSEQ(void); /* Some Support Functions */ void VGA_DACSetEntirePalette(void); +void VGA_StartRetrace(void); extern VGA_Type vga; extern Bit8u vga_rom_08[256 * 8]; From 073f2bcfe35f04243630e68f3924210ad369dd12 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 11:19:07 +0000 Subject: [PATCH 0442/4131] Changed retrace handling to be exact. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@520 --- src/hardware/vga_misc.cpp | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index e2fa92e3..f8ed0c79 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -18,9 +18,10 @@ #include "dosbox.h" #include "inout.h" -#include "timer.h" +#include "pic.h" #include "vga.h" + static Bit8u flip=0; static Bit32u keep_vretrace; static bool keeping=false; @@ -34,22 +35,12 @@ Bit8u read_p3d5(Bit32u port); static Bit8u read_p3da(Bit32u port) { vga.internal.attrindex=false; if (vga.config.retrace) { - vga.config.retrace=false; - vga.config.real_start=vga.config.display_start; - keep_vretrace=LastTicks+1; - keeping=true; - flip=0; return 9; } - if (keeping) { - if (LastTicks>(keep_vretrace)) keeping=false; - return 9; - } else { - flip++; - if (flip>10) flip=0; - if (flip>5) return 1; - return 0; - } + flip++; + if (flip>10) flip=0; + if (flip>5) return 1; + return 0; /* 0 Either Vertical or Horizontal Retrace active if set 3 Vertical Retrace in progress if set @@ -58,6 +49,7 @@ static Bit8u read_p3da(Bit32u port) { static void write_p3d8(Bit32u port,Bit8u val) { + LOG_DEBUG("Write %2X to 3da",val); /* 3 Vertical Sync Select. If set Vertical Sync to the monitor is the logical OR of the vertical sync and the vertical display enable. @@ -75,7 +67,6 @@ static void write_p3c2(Bit32u port,Bit8u val) { IO_FreeReadHandler(0x3b4); IO_FreeWriteHandler(0x3b5); IO_FreeReadHandler(0x3b5); - } else { IO_RegisterWriteHandler(0x3b4,write_p3d4,"VGA:CRTC Index Select"); IO_RegisterReadHandler(0x3b4,read_p3d4,"VGA:CRTC Index Select"); @@ -105,6 +96,17 @@ static Bit8u read_p3cc(Bit32u port) { } +static void EndRetrace(void) { + vga.config.retrace=false; +} + +void VGA_StartRetrace(void) { + /* Setup a timer to destroy the vertical retrace bit in a few microseconds */ + vga.config.real_start=vga.config.display_start; + vga.config.retrace=true; + PIC_AddEvent(EndRetrace,667); +} + void VGA_SetupMisc(void) { IO_RegisterReadHandler(0x3da,read_p3da,"VGA Input Status 1"); IO_RegisterReadHandler(0x3ba,read_p3da,"VGA Input Status 1"); From 8cd9f4a3a66aff951cb4f40a5d042d5c691cdeff Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 11:21:12 +0000 Subject: [PATCH 0443/4131] New retrace code and fixed the display start Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@521 --- src/hardware/vga_draw.cpp | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 49d1a845..9a173da1 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -26,34 +26,36 @@ void VGA_Render_GFX_2(Bit8u * * data) { *data=vga.buffer; VGA_DrawGFX2_Full(vga.buffer,vga.draw.width); - vga.config.retrace=true; + VGA_StartRetrace(); } void VGA_Render_GFX_4(Bit8u * * data) { *data=vga.buffer; VGA_DrawGFX4_Full(vga.buffer,vga.draw.width); - vga.config.retrace=true; + VGA_StartRetrace(); } void VGA_Render_GFX_16(Bit8u * * data) { - *data=&vga.buffer[vga.config.display_start*8+vga.config.pel_panning]; - vga.config.retrace=true; +// *data=&vga.buffer[vga.config.display_start*8+vga.config.pel_panning]; + *data=&vga.buffer[vga.config.real_start*8+vga.config.pel_panning]; + VGA_StartRetrace(); } void VGA_Render_GFX_256U(Bit8u * * data) { - *data=&vga.mem.linear[vga.config.display_start*4+vga.config.pel_panning]; - vga.config.retrace=true; +// *data=&vga.mem.linear[vga.config.display_start*4+vga.config.pel_panning]; + *data=&vga.mem.linear[vga.config.real_start*4+vga.config.pel_panning]; + VGA_StartRetrace(); } void VGA_Render_GFX_256C(Bit8u * * data) { *data=memory+0xa0000; - vga.config.retrace=true; + VGA_StartRetrace(); } void VGA_Render_TEXT_16(Bit8u * * data) { *data=vga.buffer; - if (!vga.draw.resizing) VGA_DrawTEXT(vga.buffer,vga.draw.width); - vga.config.retrace=true; + if (data && !vga.draw.resizing) VGA_DrawTEXT(vga.buffer,vga.draw.width); + VGA_StartRetrace(); } void VGA_DrawGFX2_Full(Bit8u * bitdata,Bitu pitch) { @@ -82,7 +84,7 @@ void VGA_DrawGFX2_Full(Bit8u * bitdata,Bitu pitch) { } bitdata+=pitch; }; - vga.config.retrace=true; + VGA_StartRetrace(); } @@ -105,7 +107,7 @@ void VGA_DrawGFX4_Full(Bit8u * bitdata,Bitu pitch) { } bitdata+=pitch; }; - vga.config.retrace=true; + VGA_StartRetrace(); } /* Draw the screen using the lookup buffer */ @@ -117,7 +119,7 @@ void VGA_DrawGFX16_Fast(Bit8u * bitdata,Bitu next_line) { bitdata+=vga.draw.width+next_line; reader+=vga.config.scan_len*16; } - vga.config.retrace=true; + VGA_StartRetrace(); }; @@ -136,7 +138,7 @@ void VGA_DrawGFX256_Full(Bit8u * bitdata,Bitu next_line) { yreader+=vga.config.scan_len*2; bitdata+=next_line; }; - vga.config.retrace=true; + VGA_StartRetrace(); }; void VGA_DrawGFX256_Fast(Bit8u * bitdata,Bitu pitch) { @@ -147,13 +149,13 @@ void VGA_DrawGFX256_Fast(Bit8u * bitdata,Bitu pitch) { bitdata+=pitch; reader+=vga.draw.width; } - vga.config.retrace=true; + VGA_StartRetrace(); }; void VGA_DrawTEXT(Bit8u * bitdata,Bitu pitch) { Bit8u * reader=HostMake(0xB800,0); - Bit8u * draw_start=bitdata;; + Bit8u * draw_start=bitdata; /* Todo Blinking and high intensity colors */ for (Bitu cy=0;cy<(vga.draw.height/16);cy++) { Bit8u * draw_char=draw_start; @@ -173,7 +175,7 @@ void VGA_DrawTEXT(Bit8u * bitdata,Bitu pitch) { }; draw_start+=16*pitch; }; - vga.config.retrace=true; + VGA_StartRetrace(); /* Draw a cursor */ if (((Bitu)vga.draw.cursor_col*8)>=vga.draw.width) return; From 002314db89119d8e0704bf0c9035f3524058ea2c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 11:23:51 +0000 Subject: [PATCH 0444/4131] Added some int15 functions, using new pic events and changed int 1a to use sti callback. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@522 --- src/ints/bios.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index e206f103..fcd08405 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -22,7 +22,7 @@ #include "callback.h" #include "inout.h" #include "mem.h" -#include "timer.h" +#include "pic.h" static Bitu call_int1a,call_int11,call_int8,call_int17,call_int12,call_int15,call_int1c; @@ -30,7 +30,6 @@ static Bitu INT1A_Handler(void) { switch (reg_ah) { case 0x00: /* Get System time */ { - CALLBACK_Idle(); Bit32u ticks=mem_readd(BIOS_TIMER); reg_al=0; /* Midnight never passes :) */ reg_cx=(Bit16u)(ticks >> 16); @@ -170,7 +169,7 @@ static Bitu INT15_Handler(void) { mem_writed(BIOS_WAIT_FLAG_POINTER,RealMake(SegValue(es),reg_bx)); mem_writed(BIOS_WAIT_FLAG_COUNT,reg_cx<<16|reg_dx); mem_writeb(BIOS_WAIT_FLAG_ACTIVE,1); - TIMER_RegisterDelayHandler(&WaitFlagEvent,reg_cx<<16|reg_dx); + PIC_AddEvent(&WaitFlagEvent,reg_cx<<16|reg_dx); break; case 0x84: /* BIOS - JOYSTICK SUPPORT (XT after 11/8/82,AT,XT286,PS) */ //Does anyone even use this? @@ -188,7 +187,11 @@ static Bitu INT15_Handler(void) { CALLBACK_SCF(false); break; case 0x90: /* OS HOOK - DEVICE BUSY */ - CALLBACK_SCF(true); + CALLBACK_SCF(false); + reg_ah=0; + break; + case 0x91: /* OS HOOK - DEVICE POST */ + CALLBACK_SCF(false); reg_ah=0; break; case 0xc2: /* BIOS PS2 Pointing Device Support */ @@ -255,7 +258,7 @@ void BIOS_Init(Section* sec) { RealSetVec(0x17,CALLBACK_RealPointer(call_int17)); /* INT 1A TIME and some other functions */ call_int1a=CALLBACK_Allocate(); - CALLBACK_Setup(call_int1a,&INT1A_Handler,CB_IRET); + CALLBACK_Setup(call_int1a,&INT1A_Handler,CB_IRET_STI); RealSetVec(0x1A,CALLBACK_RealPointer(call_int1a)); /* INT 1C System Timer tick called from INT 8 */ call_int1c=CALLBACK_Allocate(); From eef522b25830fb90d81ce4e88e0e82b24d8656dc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 11:24:37 +0000 Subject: [PATCH 0445/4131] INT 16 uses iret_sti callback now. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@523 --- src/ints/bios_keyboard.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 1d17a9e7..afeaafc7 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -293,7 +293,7 @@ static Bitu INT16_Handler(void) { //TODO find a more elegant way to do this do { temp=get_key(); - if (temp==0) { flags.intf=true;CALLBACK_Idle();}; + if (temp==0) { CALLBACK_Idle();}; } while (temp==0); reg_ax=temp; break; @@ -302,7 +302,6 @@ static Bitu INT16_Handler(void) { case 0x11: temp=check_key(); if (temp==0) { - flags.intf=true;CALLBACK_Idle(); CALLBACK_SZF(true); } else { CALLBACK_SZF(false); @@ -355,7 +354,7 @@ void BIOS_SetupKeyboard(void) { /* Allocate a callback for int 0x16 and for standard IRQ 1 handler */ call_int16=CALLBACK_Allocate(); call_irq1=CALLBACK_Allocate(); - CALLBACK_Setup(call_int16,&INT16_Handler,CB_IRET); + CALLBACK_Setup(call_int16,&INT16_Handler,CB_IRET_STI); RealSetVec(0x16,CALLBACK_RealPointer(call_int16)); CALLBACK_Setup(call_irq1,&IRQ1_Handler,CB_IRET); RealSetVec(0x9,CALLBACK_RealPointer(call_irq1)); From 9c5c2198aa4d65c8bdf313ca23fb38545d1e3a27 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Nov 2002 11:25:59 +0000 Subject: [PATCH 0446/4131] Changed main loop to support new timing and added support to disable the pc speaker. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@524 --- src/dosbox.cpp | 52 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 83ed464a..48a4f86c 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -84,27 +84,36 @@ void INT10_Init(Section*); static LoopHandler * loop; +Bitu RemainTicks;; +Bitu LastTicks; + static Bitu Normal_Loop(void) { - Bit32u new_ticks; - new_ticks=GetTicks(); - if (new_ticks>LastTicks) { - Bit32u ticks=new_ticks-LastTicks; - if (ticks>20) ticks=20; - LastTicks=new_ticks; - TIMER_AddTicks(ticks); + Bitu ret,NewTicks; + while (RemainTicks) { + ret=PIC_RunQueue(); + if (ret) return ret; + RemainTicks--; + TIMER_AddTick(); + GFX_Events(); + #if C_DEBUG + if (DEBUG_ExitLoop()) return 0; + #endif } - GFX_Events(); - TIMER_CheckPIT(); - PIC_runIRQs(); - Bitu ret; - do { - PIC_IRQAgain=false; - ret=(*cpudecoder)(cpu_cycles); - } while (!ret && PIC_IRQAgain); -#if C_DEBUG - if (DEBUG_ExitLoop()) return 0; -#endif - return ret; + NewTicks=GetTicks(); + if (NewTicks>LastTicks) { + RemainTicks+=NewTicks-LastTicks; + if (RemainTicks>20) { +// LOG_DEBUG("Ticks to handle overflow %d",RemainTicks); + RemainTicks=20; + } + LastTicks=NewTicks; + } + //TODO Make this selectable in the config file, since it gives some lag */ + if (!RemainTicks) { + SDL_Delay(1); + return 0; + } + return 0; } void DOSBOX_SetLoop(LoopHandler * handler) { @@ -127,7 +136,7 @@ static void DOSBOX_RealInit(Section * sec) { /* Initialize some dosbox internals */ errorlevel=section->Get_int("warnings"); MSG_Add("DOSBOX_CONFIGFILE_HELP","General Dosbox settings\n"); - LastTicks=GetTicks(); + RemainTicks=0;LastTicks=GetTicks(); DOSBOX_SetLoop(&Normal_Loop); MSG_Init(section); } @@ -158,7 +167,7 @@ void DOSBOX_Init(void) { secprop->Add_string("snapshots","snapshots"); secprop=control->AddSection_prop("cpu",&CPU_Init); - secprop->Add_int("cycles",4000); + secprop->Add_int("cycles",1800); secprop->AddInitFunction(&DMA_Init); secprop->AddInitFunction(&VGA_Init); @@ -183,6 +192,7 @@ void DOSBOX_Init(void) { secprop->Add_bool("cms",false); secprop=control->AddSection_prop("speaker",&PCSPEAKER_Init); + secprop->Add_bool("enabled",true); secprop->Add_bool("sinewave",false); secprop->AddInitFunction(&TANDYSOUND_Init); secprop->Add_bool("tandy",false); From b677b59c7fb15bef4772525e683f643bee21583e Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 17 Nov 2002 12:26:52 +0000 Subject: [PATCH 0447/4131] Changes for debugger and trapflag support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@525 --- src/dosbox.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 48a4f86c..8a826caf 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -91,13 +91,13 @@ static Bitu Normal_Loop(void) { Bitu ret,NewTicks; while (RemainTicks) { ret=PIC_RunQueue(); + #if C_DEBUG + if (DEBUG_ExitLoop()) return 0; + #endif if (ret) return ret; RemainTicks--; TIMER_AddTick(); GFX_Events(); - #if C_DEBUG - if (DEBUG_ExitLoop()) return 0; - #endif } NewTicks=GetTicks(); if (NewTicks>LastTicks) { From 813c012c4f4623dd508248a57a74c62b0aeae60d Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 17 Nov 2002 12:27:17 +0000 Subject: [PATCH 0448/4131] Changes for debugger Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@526 --- src/cpu/slow_16.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp index 57edf9be..5f997f98 100644 --- a/src/cpu/slow_16.cpp +++ b/src/cpu/slow_16.cpp @@ -70,7 +70,7 @@ static Bitu CPU_Real_16_Slow_Decode(void) { #endif #if C_HEAVY_DEBUG SAVEIP; - if (DEBUG_HeavyIsBreakpoint()) return CBRET_NONE; + if (DEBUG_HeavyIsBreakpoint()) return 1; #endif #include "core_16/main.h" // if (prefix.count) LOG_DEBUG("Prefix for non prefixed instruction"); @@ -82,16 +82,19 @@ static Bitu CPU_Real_16_Slow_Decode(void) { static Bitu CPU_Real_16_Slow_Decode_Trap(void) { + Bits oldCycles = CPU_Cycles; + CPU_Cycles = 1; CPU_Real_16_Slow_Decode(); - - LOG_DEBUG("TRAP: Trap Flag executed"); + +// LOG_DEBUG("TRAP: Trap Flag executed"); INTERRUPT(1); - cpudecoder=&CPU_Real_16_Slow_Decode; + + CPU_Cycles = oldCycles-1; + cpudecoder = &CPU_Real_16_Slow_Decode; return CBRET_NONE; } - void CPU_Real_16_Slow_Start(void) { cpudecoder=&CPU_Real_16_Slow_Decode; EAPrefixTable[0]=&GetEA_16_n; From 6ef306730fad9a1ab1f1e985d778630bd01240d8 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 17 Nov 2002 12:27:56 +0000 Subject: [PATCH 0449/4131] Changes for debugger (using new CPU_Cycles) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@527 --- src/debug/debug.cpp | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 6addcf17..3c3d1bd3 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -875,22 +875,28 @@ Bit32u DEBUG_CheckKeys(void) { if (key>0) { switch (toupper(key)) { case '1': - ret=(*cpudecoder)(100); + CPU_Cycles = 100; + ret=(*cpudecoder)(); break; case '2': - ret=(*cpudecoder)(500); + CPU_Cycles = 500; + ret=(*cpudecoder)(); break; case '3': - ret=(*cpudecoder)(1000); + CPU_Cycles = 1000; + ret=(*cpudecoder)(); break; case '4': - ret=(*cpudecoder)(5000); + CPU_Cycles = 5000; + ret=(*cpudecoder)(); break; case '5': - ret=(*cpudecoder)(10000); + CPU_Cycles = 10000; + ret=(*cpudecoder)(); break; case 'q': - ret=(*cpudecoder)(5); + CPU_Cycles = 5; + ret=(*cpudecoder)(); break; case 'D': dataSeg = SegValue(ds); dataOfs = reg_si; @@ -944,14 +950,16 @@ Bit32u DEBUG_CheckKeys(void) { if (StepOver()) return 0; else { skipFirstInstruction = true; // for heavy debugger - Bitu ret=(*cpudecoder)(1); + CPU_Cycles = 1; + Bitu ret=(*cpudecoder)(); SetCodeWinStart(); CBreakpoint::ignoreOnce = 0; } break; case KEY_F(11): // trace into skipFirstInstruction = true; // for heavy debugger - ret = (*cpudecoder)(1); + CPU_Cycles = 1; + ret = (*cpudecoder)(); SetCodeWinStart(); CBreakpoint::ignoreOnce = 0; break; @@ -1031,13 +1039,13 @@ static bool DEBUG_Log_Loop(int count) { LogInstruction(csValue,eipValue,buffer); fprintf(f,"%s",buffer); - PIC_IRQAgain=false; - ret=(*cpudecoder)(1); + CPU_Cycles = 1; + ret=(*cpudecoder)(); count--; if (count==0) break; - } while (!ret && PIC_IRQAgain); + } while (!ret); if (ret) break; } while (count>0); From 53bd61bf03d2ce4a179c40e3cb47498c4d5cd3e4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 17 Nov 2002 13:11:28 +0000 Subject: [PATCH 0450/4131] changed illegal interrupt reporiting to use hex instead of dec Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@528 --- src/cpu/callback.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 7f52ce78..7d5efa55 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -67,7 +67,7 @@ void CALLBACK_Idle(void) { } static Bitu default_handler(void) { - LOG_WARN("Illegal Unhandled Interrupt Called %d",lastint); + LOG_WARN("Illegal Unhandled Interrupt Called %X",lastint); return CBRET_NONE; }; From 67edbc99ca7b28d8c52005a098220b7c76fba4d9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 18 Nov 2002 00:16:31 +0000 Subject: [PATCH 0451/4131] Fix a problem with ega detection. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@529 --- src/ints/int10_modes.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index d34155f0..d7a05802 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -387,8 +387,7 @@ void INT10_SetVideoMode(Bit8u mode) { real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,theight-1); real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,cheight); real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem << 7))); - real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9); - real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0); + real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0x09); real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); // FIXME We nearly have the good tables. to be reworked From 4b45c7dc5f8513ec4784fd301a5b74694308050a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 18 Nov 2002 00:17:12 +0000 Subject: [PATCH 0452/4131] Major bug with prefixes not getting reset with string operations. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@530 --- src/cpu/core_16/support.h | 51 ++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/src/cpu/core_16/support.h b/src/cpu/core_16/support.h index f288849d..4468693f 100644 --- a/src/cpu/core_16/support.h +++ b/src/cpu/core_16/support.h @@ -143,7 +143,7 @@ rep_again: goto rep_again; case 0x6c: /* REP INSB */ for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) return; reg_cx--; + if (!reg_cx) goto normalexit; reg_cx--; SaveMb(base_di+reg_di,IO_Read(reg_dx)); reg_di+=direct; } @@ -152,7 +152,7 @@ rep_again: if (prefix_66) { direct*=4; for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) return; reg_cx--; + if (!reg_cx) goto normalexit; reg_cx--; SaveMb(base_di+reg_di+0,IO_Read(reg_dx+0)); SaveMb(base_di+reg_di+1,IO_Read(reg_dx+1)); SaveMb(base_di+reg_di+2,IO_Read(reg_dx+2)); @@ -162,7 +162,7 @@ rep_again: } else { direct*=2; for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) return; reg_cx--; + if (!reg_cx) goto normalexit; reg_cx--; SaveMb(base_di+reg_di+0,IO_Read(reg_dx+0)); SaveMb(base_di+reg_di+1,IO_Read(reg_dx+1)); reg_di+=direct; @@ -171,7 +171,7 @@ rep_again: break; case 0x6e: /* REP OUTSB */ for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) return; reg_cx--; + if (!reg_cx) goto normalexit; reg_cx--; IO_Write(reg_dx,LoadMb(base_si+reg_si)); reg_si+=direct; } @@ -180,7 +180,7 @@ rep_again: if (prefix_66) { direct*=4; for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) return; reg_cx--; + if (!reg_cx) goto normalexit; reg_cx--; IO_Write(reg_dx+0,LoadMb(base_si+reg_si+0)); IO_Write(reg_dx+1,LoadMb(base_si+reg_si+1)); IO_Write(reg_dx+2,LoadMb(base_si+reg_si+2)); @@ -190,7 +190,7 @@ rep_again: } else { direct*=2; for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) return; reg_cx--; + if (!reg_cx) goto normalexit; reg_cx--; IO_Write(reg_dx+0,LoadMb(base_si+reg_si+0)); IO_Write(reg_dx+1,LoadMb(base_si+reg_si+1)); reg_si+=direct; @@ -199,7 +199,7 @@ rep_again: break; case 0xa4: /* REP MOVSB */ for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) return; reg_cx--; + if (!reg_cx) goto normalexit; reg_cx--; SaveMb(base_di+reg_di,LoadMb(base_si+reg_si)); reg_si+=direct;reg_di+=direct; } @@ -208,14 +208,14 @@ rep_again: if (prefix_66) { direct*=4; for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) return; reg_cx--; + if (!reg_cx) goto normalexit; reg_cx--; SaveMd(base_di+reg_di,LoadMd(base_si+reg_si)); reg_si+=direct;reg_di+=direct; } } else { direct*=2; for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) return; reg_cx--; + if (!reg_cx) goto normalexit; reg_cx--; SaveMw(base_di+reg_di,LoadMw(base_si+reg_si)); reg_si+=direct;reg_di+=direct; } @@ -224,24 +224,24 @@ rep_again: case 0xa6: /* REP CMPSB */ { Bit8u op1,op2; - if (!reg_cx) { CPU_Cycles--;return; } + if (!reg_cx) { CPU_Cycles--;goto normalexit; } for (;CPU_Cycles>0;CPU_Cycles--) { op1=LoadMb(base_si+reg_si);op2=LoadMb(base_di+reg_di); reg_cx--;reg_si+=direct;reg_di+=direct; - if ((op1==op2)!=testz || !reg_cx) { CMPB(op1,op2,LoadRb,0);return; } + if ((op1==op2)!=testz || !reg_cx) { CMPB(op1,op2,LoadRb,0);goto normalexit; } } CMPB(op1,op2,LoadRb,0); } break; case 0xa7: /* REP CMPSW */ { - if (!reg_cx) { CPU_Cycles--;return; } + if (!reg_cx) { CPU_Cycles--;goto normalexit; } if (prefix_66) { direct*=4;Bit32u op1,op2; for (;CPU_Cycles>0;CPU_Cycles--) { op1=LoadMd(base_si+reg_si);op2=LoadMd(base_di+reg_di); reg_cx--;reg_si+=direct;reg_di+=direct; - if ((op1==op2)!=testz || !reg_cx) { CMPD(op1,op2,LoadRd,0);return; } + if ((op1==op2)!=testz || !reg_cx) { CMPD(op1,op2,LoadRd,0);goto normalexit; } } CMPD(op1,op2,LoadRd,0); } else { @@ -249,7 +249,7 @@ rep_again: for (;CPU_Cycles>0;CPU_Cycles--) { op1=LoadMw(base_si+reg_si);op2=LoadMw(base_di+reg_di); reg_cx--,reg_si+=direct;reg_di+=direct; - if ((op1==op2)!=testz || !reg_cx) { CMPW(op1,op2,LoadRw,0);return; } + if ((op1==op2)!=testz || !reg_cx) { CMPW(op1,op2,LoadRw,0);goto normalexit; } } CMPW(op1,op2,LoadRw,0); } @@ -257,7 +257,7 @@ rep_again: break; case 0xaa: /* REP STOSB */ for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) return; reg_cx--; + if (!reg_cx) goto normalexit; reg_cx--; SaveMb(base_di+reg_di,reg_al); reg_di+=direct; } @@ -266,14 +266,14 @@ rep_again: if (prefix_66) { direct*=4; for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) return; reg_cx--; + if (!reg_cx) goto normalexit; reg_cx--; SaveMd(base_di+reg_di,reg_eax); reg_di+=direct; } } else { direct*=2; for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) return; reg_cx--; + if (!reg_cx) goto normalexit; reg_cx--; SaveMw(base_di+reg_di,reg_ax); reg_di+=direct; } @@ -281,7 +281,7 @@ rep_again: break; case 0xac: /* REP LODSB */ for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) return; reg_cx--; + if (!reg_cx) goto normalexit; reg_cx--; reg_al=LoadMb(base_si+reg_si); reg_si+=direct; } @@ -290,14 +290,14 @@ rep_again: if (prefix_66) { direct*=4; for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) return; reg_cx--; + if (!reg_cx) goto normalexit; reg_cx--; reg_eax=LoadMd(base_si+reg_si); reg_si+=direct; } } else { direct*=2; for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) return; reg_cx--; + if (!reg_cx) goto normalexit; reg_cx--; reg_ax=LoadMw(base_si+reg_si); reg_si+=direct; } @@ -306,24 +306,24 @@ rep_again: case 0xae: /* REP SCASB */ { Bit8u op2; - if (!reg_cx) { CPU_Cycles--;return; } + if (!reg_cx) { CPU_Cycles--;goto normalexit; } for (;CPU_Cycles>0;CPU_Cycles--) { op2=LoadMb(base_di+reg_di); reg_cx--;reg_di+=direct; - if ((reg_al==op2)!=testz || !reg_cx) { CMPB(reg_al,op2,LoadRb,0);return; } + if ((reg_al==op2)!=testz || !reg_cx) { CMPB(reg_al,op2,LoadRb,0);goto normalexit; } } CMPB(reg_al,op2,LoadRb,0); } break; case 0xaf: /* REP SCASW */ { - if (!reg_cx) { CPU_Cycles--;return; } + if (!reg_cx) { CPU_Cycles--;goto normalexit; } if (prefix_66) { direct*=4;Bit32u op2; for (;CPU_Cycles>0;CPU_Cycles--) { op2=LoadMd(base_di+reg_di); reg_cx--;reg_di+=direct; - if ((reg_eax==op2)!=testz || !reg_cx) { CMPD(reg_eax,op2,LoadRd,0);return; } + if ((reg_eax==op2)!=testz || !reg_cx) { CMPD(reg_eax,op2,LoadRd,0);goto normalexit; } } CMPD(reg_eax,op2,LoadRd,0); } else { @@ -331,7 +331,7 @@ rep_again: for (;CPU_Cycles>0;CPU_Cycles--) { op2=LoadMw(base_di+reg_di); reg_cx--;reg_di+=direct; - if ((reg_ax==op2)!=testz || !reg_cx) { CMPW(reg_ax,op2,LoadRw,0);return; } + if ((reg_ax==op2)!=testz || !reg_cx) { CMPW(reg_ax,op2,LoadRw,0);goto normalexit; } } CMPW(reg_ax,op2,LoadRw,0); } @@ -344,6 +344,7 @@ rep_again: } /* If we end up here it's because the CPU_Cycles counter is 0, so restart instruction */ IPPoint-=(prefix.count+2); /* Rep instruction and whatever string instruction */ +normalexit: PrefixReset; } From 52df9c4493fc526daec05aca4289fbafb734742e Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 19 Nov 2002 17:23:16 +0000 Subject: [PATCH 0453/4131] loadfix Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@531 --- ChangeLog | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7b47ffb9..cfa511d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,7 +2,13 @@ - 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) 0.56 - added support for a configclass/configfile From cdabc9b9311b9f5fac9bb3152575a701b79a4f30 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 19 Nov 2002 17:23:57 +0000 Subject: [PATCH 0454/4131] - added loadfix.com program that allocates 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) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@532 --- src/dos/dos_programs.cpp | 70 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 1046e124..11d01b3f 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -25,6 +25,7 @@ #include "cross.h" #include "regs.h" #include "callback.h" +#include "..\shell\shell_inc.h" class MOUNT : public Program { public: @@ -220,6 +221,69 @@ static void UPCASE_ProgramStart(Program * * make) { } #endif +// LOADFIX + +class LOADFIX : public Program { +public: + void Run(void); +}; + +void LOADFIX::Run(void) +{ + Bit16u commandNr = 1; + Bit16u kb = 64; + if (cmd->FindCommand(commandNr,temp_line)) { + if (temp_line[0]=='-') { + char ch = temp_line[1]; + if ((*upcase(&ch)=='D') || (*upcase(&ch)=='F')) { + // Deallocate all + DOS_FreeProcessMemory(0x40); + WriteOut(MSG_Get("PROGRAM_LOADFIX_DEALLOCALL"),kb); + return; + } else { + // Set mem amount to allocate + kb = atoi(temp_line.c_str()+1); + if (kb==0) kb=64; + commandNr++; + } + } + } + // Allocate Memory + Bit16u segment; + Bit16u blocks = kb*1024/16; + if (DOS_AllocateMemory(&segment,&blocks)) { + MCB* pmcb = (MCB*)HostMake(segment-1,0); + pmcb->psp_segment = 0x40; // use fake segment + WriteOut(MSG_Get("PROGRAM_LOADFIX_ALLOC"),kb); + // Prepare commandline... + if (cmd->FindCommand(commandNr++,temp_line)) { + // get Filename + char filename[128]; + strncpy(filename,temp_line.c_str(),128); + // Setup commandline + bool ok; + char args[256]; + args[0] = 0; + do { + ok = cmd->FindCommand(commandNr++,temp_line); + strncat(args,temp_line.c_str(),256); + strncat(args," ",256); + } while (ok); + // Use shell to start program + DOS_Shell shell; + shell.Execute(filename,args); + DOS_FreeMemory(segment); + WriteOut(MSG_Get("PROGRAM_LOADFIX_DEALLOC"),kb); + } + } else { + WriteOut(MSG_Get("PROGRAM_LOADFIX_ERROR"),kb); + } +}; + +static void LOADFIX_ProgramStart(Program * * make) { + *make=new LOADFIX; +} + void DOS_SetupPrograms(void) { /*Add Messages */ MSG_Add("PROGRAM_MOUNT_STATUS_2","Drive %c is mounted as %s\n"); @@ -233,6 +297,11 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_MEM_EXTEND","%10d Kb free extended memory\n"); MSG_Add("PROGRAM_MEM_EXPAND","%10d Kb free expanded memory\n"); + MSG_Add("PROGRAM_LOADFIX_ALLOC","%d kb allocated.\n"); + MSG_Add("PROGRAM_LOADFIX_DEALLOC","%d kb freed.\n"); + MSG_Add("PROGRAM_LOADFIX_DEALLOCALL","Used memory freed.\n"); + MSG_Add("PROGRAM_LOADFIX_ERROR","Memory allocation error.\n"); + #if !defined (WIN32) /* Unix */ MSG_Add("PROGRAM_UPCASE_ERROR_DIR","Failed to open directory %s\n"); MSG_Add("PROGRAM_UPCASE_SCANNING_DIR","Scanning directory %s\n"); @@ -247,6 +316,7 @@ void DOS_SetupPrograms(void) { /*regular setup*/ PROGRAMS_MakeFile("MOUNT.COM",MOUNT_ProgramStart); PROGRAMS_MakeFile("MEM.COM",MEM_ProgramStart); + PROGRAMS_MakeFile("LOADFIX.COM",LOADFIX_ProgramStart); #if !defined (WIN32) /* Unix */ PROGRAMS_MakeFile("UPCASE.COM",UPCASE_ProgramStart); #endif From 510449e8060fc237a138d827b34b565ac3b0849b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 19 Nov 2002 19:44:48 +0000 Subject: [PATCH 0455/4131] changed log_warn to log_debug in int 13 04 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@533 --- src/ints/bios_disk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 234debc8..14f10e0b 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -45,7 +45,7 @@ static Bitu INT13_SmallHandler(void) { reg_ah=0x80; CALLBACK_SCF(true); } - LOG_WARN("INT 13:04 Verify sector used on %d, with result %d",reg_dl,reg_ah); + LOG_DEBUG("INT 13:04 Verify sector used on %d, with result %d",reg_dl,reg_ah); break; case 0x08: /* Get Drive Parameters */ From 5d874b4efb49661e9c1d71e0c96b0828ddb4abba Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 19 Nov 2002 20:33:23 +0000 Subject: [PATCH 0456/4131] fcbs will now be created in execute. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@534 --- src/shell/shell_misc.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index f245e7bc..6328a642 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -164,6 +164,12 @@ void DOS_Shell::Execute(char * name,char * args) { cmd.buffer[strlen(line)]=0xd; /* Copy command line in stack block too */ MEM_BlockWrite(SegPhys(ss)+reg_sp+0x100,&cmd,128); + /* Parse FCB (first two parameters) and put them into the current DOS_PSP */ + Bit8u add; + FCB_Parsename(dos.psp,0x5C,0x00,cmd.buffer,&add); + FCB_Parsename(dos.psp,0x6C,0x00,&cmd.buffer[add],&add); + block.exec.fcb1=RealMake(dos.psp,0x5C); + block.exec.fcb2=RealMake(dos.psp,0x6C); /* Set the command line in the block and save it */ block.exec.cmdtail=RealMakeSeg(ss,reg_sp+0x100); block.SaveData(); From 87f990907d1e9a6cc24ca2955f2c2ae324470af1 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 25 Nov 2002 11:37:04 +0000 Subject: [PATCH 0457/4131] Support for memory allocation strategy: last matching block Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@535 --- include/dos_inc.h | 2 ++ src/dos/dos.cpp | 3 ++- src/dos/dos_memory.cpp | 46 +++++++++++++++++++++++++++++++++--------- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index ff3d7595..346c5a26 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -140,6 +140,8 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks); bool DOS_FreeMemory(Bit16u segment); void DOS_FreeProcessMemory(Bit16u pspseg); Bit16u DOS_GetMemory(Bit16u pages); +void DOS_SetMemAllocStrategy(Bit16u strat); +Bit16u DOS_GetMemAllocStrategy(void); /* FCB stuff */ bool DOS_FCBOpen(Bit16u seg,Bit16u offset); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 75d0a798..5df2a3ab 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -679,9 +679,10 @@ static Bitu DOS_21Handler(void) { case 0x58: /* Get/Set Memory allocation strategy */ switch (reg_al) { case 0: /* Get Strategy */ - reg_ax=0; //Low memory first fit + reg_ax=DOS_GetMemAllocStrategy(); break; case 1: /* Set Strategy */ + DOS_SetMemAllocStrategy(reg_bx); break; default: LOG_DEBUG("DOS:58:Not Supported Set//Get memory allocation call %X",reg_al); diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 0140655b..0fb72a38 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -24,6 +24,7 @@ #define MEM_START 0x60 //First Segment that DOS can use //#define MEM_START 4000 //First Segment that DOS can use +static Bit16u memAllocStrategy = 0x00; static void DOS_CompressMemory(void) { MCB * pmcb;MCB * pmcbnext; @@ -57,6 +58,15 @@ void DOS_FreeProcessMemory(Bit16u pspseg) { DOS_CompressMemory(); }; +Bit16u DOS_GetMemAllocStrategy() +{ + return memAllocStrategy; +}; + +void DOS_SetMemAllocStrategy(Bit16u strat) +{ + memAllocStrategy = strat; +}; bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { MCB * pmcb;MCB * pmcbnext; @@ -77,17 +87,33 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { *segment=mcb_segment+1; return true; } else { + // TODO: Strategy "1": Best matching block /* If so allocate it */ - pmcbnext=(MCB *)HostMake(mcb_segment+*blocks+1,0); - pmcbnext->psp_segment=MCB_FREE; - pmcbnext->type=pmcb->type; - pmcbnext->size=pmcb->size-*blocks-1; - pmcb->size=*blocks; - pmcb->type=0x4D; - pmcb->psp_segment=dos.psp; - //TODO Filename - *segment=mcb_segment+1; - return true; + if ((memAllocStrategy & 0x03)==0) { + pmcbnext=(MCB *)HostMake(mcb_segment+*blocks+1,0); + pmcbnext->psp_segment=MCB_FREE; + pmcbnext->type=pmcb->type; + pmcbnext->size=pmcb->size-*blocks-1; + pmcb->size=*blocks; + pmcb->type=0x4D; + pmcb->psp_segment=dos.psp; + //TODO Filename + *segment=mcb_segment+1; + return true; + } else { + // * Last Block * + // New created block + *segment = mcb_segment+1+pmcb->size-*blocks; + pmcbnext=(MCB *)HostMake(*segment-1,0); + pmcbnext->size = *blocks; + pmcbnext->type = pmcb->type; + pmcbnext->psp_segment = dos.psp; + // Old Block + pmcb->size = pmcb->size-*blocks-1; + pmcb->psp_segment = MCB_FREE; + pmcb->type = 0x4D; + return true; + }; } } /* Onward to the next MCB if there is one */ From 439523860c5ad6e565968e04444ca35a28f64d91 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 Nov 2002 12:16:41 +0000 Subject: [PATCH 0458/4131] back to forward slash Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@536 --- src/dos/dos_programs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 11d01b3f..2a811abc 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -25,7 +25,7 @@ #include "cross.h" #include "regs.h" #include "callback.h" -#include "..\shell\shell_inc.h" +#include "../shell/shell_inc.h" class MOUNT : public Program { public: From 0953ce3b59e1fcde00490e4c0401ca78d617d3ff Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 Nov 2002 15:03:23 +0000 Subject: [PATCH 0459/4131] cr lf only gets expanded if there is room for it. and int 21: 06 return al=0 if no key Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@537 --- src/dos/dev_con.h | 2 +- src/dos/dos.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 0e077e67..90f4d0f4 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -42,7 +42,7 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { case 13: data[count++]=0x0D; if (*size>count) data[count++]=0x0A; - else cache=0x0A; + //else cache=0x0A; // it's only expanded if there is room for it. *size=count; reg_ax=oldax; return true; diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 5df2a3ab..b65ad676 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -68,6 +68,7 @@ static Bitu DOS_21Handler(void) { { //TODO Make this better according to standards if (!DOS_GetSTDINStatus()) { + reg_al=0; CALLBACK_SZF(true); break; } From 8011e1ac0a57249a0112609a79ec69a59d5518f3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 25 Nov 2002 21:54:47 +0000 Subject: [PATCH 0460/4131] changes to support emssize in config file support for function 0x57 moving blocks Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@538 --- src/ints/ems.cpp | 196 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 180 insertions(+), 16 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 0a8cb525..24329d11 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -34,7 +34,7 @@ #define EMM_PAGEFRAME 0xE000 #define EMM_MAX_HANDLES 50 /* 255 Max */ #define EMM_PAGE_SIZE (16*1024) -#define EMM_MAX_PAGES (C_MEM_EMS_SIZE * 1024 / 16 ) +#define EMM_MAX_PAGES (32 * 1024 / 16 ) #define EMM_MAX_PHYS 4 /* 4 16kb pages in pageframe */ #define EMM_VERSION 0x40 @@ -83,7 +83,7 @@ struct EMM_Mapping { }; struct EMM_Page { - void * memory; + HostPt * memory; Bit16u handle; Bit16u next; }; @@ -91,7 +91,7 @@ struct EMM_Page { struct EMM_Handle { Bit16u first_page; Bit16u pages; - char name[9]; + char name[8]; bool saved_page_map; EMM_Mapping page_map[EMM_MAX_PHYS]; }; @@ -100,8 +100,21 @@ static EMM_Handle emm_handles[EMM_MAX_HANDLES]; static EMM_Page emm_pages[EMM_MAX_PAGES]; static EMM_Mapping emm_mappings[EMM_MAX_PHYS]; static HostPt emm_pagebase[EMM_MAX_PHYS]; +static Bitu emm_page_count; Bitu call_int67; +struct MoveRegion { + Bit32u bytes; + Bit8u src_type; + Bit16u src_handle; + Bit16u src_offset; + Bit16u src_page_seg; + Bit8u dest_type; + Bit16u dest_handle; + Bit16u dest_offset; + Bit16u dest_page_seg; +}; + #if EMM_USEHANDLER Bit8u EMM_ReadHandler(PhysPt start) { start-=EMM_PAGEFRAME * 16; @@ -118,12 +131,18 @@ void EMM_WriteHandler(PhysPt start,Bit8u val) { static Bit16u EMM_GetFreePages(void) { Bit16u count=0; - for (Bitu index=0;index=EMM_MAX_HANDLES) return false; + if (emm_handles[handle].pages==NULL_HANDLE) return false; + return true; +} + static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & handle) { /* Check for 0 page allocation */ if (!pages) return EMM_ZERO_PAGES; @@ -140,14 +159,14 @@ static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & handle) { while (pages) { if (emm_pages[page].handle==NULL_HANDLE) { emm_pages[page].handle=handle; - emm_pages[page].memory=malloc(EMM_PAGE_SIZE); + emm_pages[page].memory=(HostPt *)malloc(EMM_PAGE_SIZE); if (!emm_pages[page].memory) E_Exit("EMM:Cannont allocate memory"); if (last!=NULL_PAGE) emm_pages[last].next=page; else emm_handles[handle].first_page=page; last=page; pages--; } else { - if (++page>=EMM_MAX_PAGES) E_Exit("EMM:Ran out of pages"); + if (++page>=emm_page_count) E_Exit("EMM:Ran out of pages"); } } return EMM_NO_ERROR; @@ -190,14 +209,14 @@ static Bit8u EMM_ReallocatePages(Bit16u handle,Bit16u & pages) { while (pages) { if (emm_pages[page].handle==NULL_HANDLE) { emm_pages[page].handle=handle; - emm_pages[page].memory=malloc(EMM_PAGE_SIZE); + emm_pages[page].memory=(HostPt *)malloc(EMM_PAGE_SIZE); if (!emm_pages[page].memory) E_Exit("EMM:Cannont allocate memory"); if (last!=NULL_PAGE) emm_pages[last].next=page; else emm_handles[handle].first_page=page; last=page; pages--; } else { - if (++page>=EMM_MAX_PAGES) E_Exit("EMM:Ran out of pages"); + if (++page>=emm_page_count) E_Exit("EMM:Ran out of pages"); } } pages=emm_handles[handle].pages; @@ -264,7 +283,7 @@ static Bit8u EMM_ReleaseMemory(Bit16u handle) { emm_handles[handle].first_page=NULL_PAGE; emm_handles[handle].pages=NULL_HANDLE; emm_handles[handle].saved_page_map=false; - memset(&emm_handles[handle].name,0,9); + memset(&emm_handles[handle].name,0,8); return EMM_NO_ERROR; } @@ -351,9 +370,143 @@ static Bit8u EMM_PartialPageMapping(void) { LOG_ERROR("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); return EMM_FUNC_NOSUP; } - return 0; + return EMM_NO_ERROR; } +static Bit8u HandleNameSearch(void) { + Bit16u handle=0;PhysPt data; + switch (reg_al) { + case 0x00: /* Get all handle names */ + reg_al=0;data=SegPhys(es)+reg_di; + for (handle=0;handle1) { + LOG_ERROR("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); + return EMM_FUNC_NOSUP; + } + LoadMoveRegion(SegPhys(ds)+reg_si,region); +/* Parse the region for information */ + PhysPt src_mem,dest_mem; + Bit16u src_page,dest_page;Bitu src_off,dest_off;Bitu src_remain,dest_remain; + if (!region.src_type) { + src_mem=region.src_page_seg*16+region.src_offset; + } else { + if (!ValidHandle(region.src_handle)) return EMM_INVALID_HANDLE; + if (emm_handles[region.src_handle].pages*EMM_PAGE_SIZE < (region.src_page_seg*EMM_PAGE_SIZE)+region.src_offset+region.bytes) return EMM_LOG_OUT_RANGE; + src_page=emm_handles[region.src_handle].first_page; + while (region.src_page_seg>0) { + src_page=emm_pages[src_page].next; + region.src_page_seg--; + } + src_off=region.src_offset; + src_remain=EMM_PAGE_SIZE-src_off; + } + if (!region.dest_type) { + dest_mem=region.dest_page_seg*16+region.dest_offset; + } else { + if (!ValidHandle(region.dest_handle)) return EMM_INVALID_HANDLE; + if (emm_handles[region.dest_handle].pages*EMM_PAGE_SIZE < (region.dest_page_seg*EMM_PAGE_SIZE)+region.dest_offset+region.bytes) return EMM_LOG_OUT_RANGE; + dest_page=emm_handles[region.dest_handle].first_page; + while (region.dest_page_seg>0) { + dest_page=emm_pages[dest_page].next; + region.dest_page_seg--; + } + dest_off=region.dest_offset; + dest_remain=EMM_PAGE_SIZE-dest_off; + } + Bitu toread; + while (region.bytes>0) { + if (region.bytes>EMM_PAGE_SIZE) toread=EMM_PAGE_SIZE; + else toread=region.bytes; + /* Read from the source */ + if (!region.src_type) { + MEM_BlockRead(src_mem,buf_src,toread); + } else { + if (toread=EMM_MAX_HANDLES || emm_handles[reg_bx].pages==NULL_HANDLE) {reg_ah=EMM_INVALID_HANDLE;break;} + if (!ValidHandle(reg_bx)) {reg_ah=EMM_INVALID_HANDLE;break;} reg_bx=emm_handles[reg_dx].pages; reg_ah=EMM_NO_ERROR; break; @@ -431,7 +583,6 @@ static Bitu INT67_Handler(void) { case 0x4f: /* Save/Restore Partial Page Map */ reg_ah=EMM_PartialPageMapping(); break; - case 0x50: /* Map/Unmap multiple handle pages */ reg_ah = EMM_NO_ERROR; switch (reg_al) { @@ -467,6 +618,13 @@ static Bitu INT67_Handler(void) { reg_ah=EMM_NO_ERROR; } break; + case 0x54: /* Handle Functions */ + reg_ah=HandleNameSearch(); + break; + case 0x57: /* Memory region */ + reg_ah=MemoryRegion(); + if (reg_ah) LOG_WARN("ems 57 move failed"); + break; case 0x58: // Get mappable physical array address array if (reg_al==0x00) { PhysPt data = SegPhys(es)+reg_di; @@ -498,6 +656,12 @@ void EMS_Init(Section* sec) { Section_prop * section=static_cast(sec); Bitu size=section->Get_int("emssize"); if (!size) return; + if ((size*(1024/16))>EMM_MAX_PAGES) { + LOG_DEBUG("EMS Max size is %d",EMM_MAX_PAGES/(1024/16)); + emm_page_count=EMM_MAX_PAGES; + } else { + emm_page_count=size*(1024/16); + } call_int67=CALLBACK_Allocate(); CALLBACK_Setup(call_int67,&INT67_Handler,CB_IRET); /* Register the ems device */ @@ -515,7 +679,7 @@ void EMS_Init(Section* sec) { RealSetVec(0x67,RealMake(seg,0)); /* Clear handle and page tables */ Bitu i; - for (i=0;i Date: Mon, 25 Nov 2002 21:56:11 +0000 Subject: [PATCH 0461/4131] Support for multiplex call for close awareness of win9x Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@539 --- src/dos/dos_misc.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index 5280a529..cabfd2ae 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -60,11 +60,13 @@ static bool DOS_MultiplexFunctions(void) { //TODO Maybe do some idling but could screw up other systems :) reg_al=0; return true; + case 0x168f: /* Close awareness crap */ + return true; } + return false; } - void DOS_SetupMisc(void) { /* Setup the dos multiplex interrupt */ first_multiplex=0; From 88a72bd20ec58953824be7989b413a660b5dd690 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 26 Nov 2002 22:06:25 +0000 Subject: [PATCH 0462/4131] cmos support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@540 --- src/dosbox.cpp | 2 + src/hardware/cmos.cpp | 118 ++++++++++++++++++++++++++++++++++++++++++ visualc/dosbox.dsp | 4 ++ 3 files changed, 124 insertions(+) create mode 100644 src/hardware/cmos.cpp diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 8a826caf..c1e82ad0 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -73,6 +73,7 @@ void PIC_Init(Section*); void TIMER_Init(Section*); void BIOS_Init(Section*); void DEBUG_Init(Section*); +void CMOS_Init(Section*); /* Dos Internal mostly */ void EMS_Init(Section*); @@ -163,6 +164,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&PIC_Init); secprop->AddInitFunction(&PROGRAMS_Init); secprop->AddInitFunction(&TIMER_Init); + secprop->AddInitFunction(&CMOS_Init); secprop->AddInitFunction(&RENDER_Init); secprop->Add_string("snapshots","snapshots"); diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp new file mode 100644 index 00000000..9c20f9ec --- /dev/null +++ b/src/hardware/cmos.cpp @@ -0,0 +1,118 @@ +/* + * 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. + */ + +#include "dosbox.h" +#include "timer.h" +#include "pic.h" +#include "inout.h" +#include "config.h" + +static struct { + + Bit8u regs[0x40]; + bool nmi; + Bit8u reg; + struct { + bool enabled; + Bit8u div; + Bitu micro; + } timer; + Bit8u status_c; + bool ack; + bool update_ended; + +} cmos; + +static void cmos_timerevent(void) { + PIC_ActivateIRQ(8); + if (cmos.ack) { + PIC_AddEvent(cmos_timerevent,cmos.timer.micro); + cmos.status_c=0x20; + cmos.ack=false; + } +} + +static void cmos_checktimer(void) { + PIC_RemoveEvents(cmos_timerevent); + if (!cmos.timer.div && !cmos.timer.enabled) return; + if (cmos.timer.div<=2) cmos.timer.div+=7; + cmos.timer.micro=(Bitu) (10000000.0/(32768.0 / (1 << (cmos.timer.div - 1)))); + LOG_DEBUG("RTC Timer at %f hz",1000000.0/cmos.timer.micro); + PIC_AddEvent(cmos_timerevent,cmos.timer.micro); +} + +void cmos_selreg(Bit32u port,Bit8u val) { + cmos.reg=val & 0x3f; + cmos.nmi=(val & 0x80)>0; +} + +static void cmos_writereg(Bit32u port,Bit8u val) { + switch (cmos.reg) { + case 0x00: /* Seconds */ + case 0x01: /* Seconds Alarm */ + case 0x02: /* Minutes */ + case 0x03: /* Minutes Alarm */ + case 0x04: /* Hours */ + case 0x05: /* Hours Alarm */ + case 0x06: /* Day of week */ + case 0x07: /* Date of month */ + case 0x08: /* Month */ + case 0x09: /* Year */ + cmos.regs[cmos.reg]=val; + break; + case 0x0a: /* Status reg A */ + cmos.regs[cmos.reg]=val & 0x7f; + if (val & 0x70!=0x20) LOG_DEBUG("CMOS Illegal 22 stage divider value"); + cmos.timer.div=(val & 0xf); + cmos_checktimer(); + break; + case 0x0b: /* Status reg B */ + cmos.regs[cmos.reg]=val & 0x7f; + cmos.timer.enabled=(val & 0x40)>0; + if (val&0x10) LOG_DEBUG("CMOS:Updated ended interrupt not supported yet"); + cmos_checktimer(); + break; + default: + cmos.regs[cmos.reg]=val & 0x7f; + LOG_DEBUG("CMOS:Unhandled register %x",cmos.reg); + } +} + +static Bit8u cmos_readreg(Bit32u port) { + if (cmos.reg>0x3f) { + LOG_DEBUG("CMOS:Read from illegal register %x",cmos.reg); + return 0xff; + } + switch (cmos.reg) { + case 0x0c: + if (cmos.ack) return 0; + else { + cmos.ack=true; + return 0x80|cmos.status_c; + } + default: + return cmos.regs[cmos.reg]; + } +} + +void CMOS_Init(Section* sec) { + IO_RegisterWriteHandler(0x70,cmos_selreg,"CMOS"); + IO_RegisterWriteHandler(0x71,cmos_writereg,"CMOS"); + IO_RegisterReadHandler(0x71,cmos_readreg,"CMOS"); + cmos.timer.enabled=false; +} \ No newline at end of file diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index e4d31a78..f1b25592 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -335,6 +335,10 @@ SOURCE=..\src\hardware\adlib.cpp # End Source File # Begin Source File +SOURCE=..\src\hardware\cmos.cpp +# End Source File +# Begin Source File + SOURCE=..\src\hardware\dma.cpp # End Source File # Begin Source File From 079ea0f1cd27706229af3734a610db5266612090 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 27 Nov 2002 00:03:47 +0000 Subject: [PATCH 0463/4131] New keyboard irq activating with pic Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@541 --- src/hardware/keyboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index f65f4526..5191cf37 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -87,7 +87,7 @@ void KEYBOARD_AddCode(Bit8u code) { keyb.buf[start]=code; keyb.read_active=true; } - if (keyb.buf_used>0) PIC_ActivateIRQ(1); + if (keyb.buf_used==1) PIC_AddIRQ(1,0); } static Bit8u read_p60(Bit32u port) { From 943b4e81d329c8f9acfcfa59003d7713c026d924 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 28 Nov 2002 00:42:34 +0000 Subject: [PATCH 0464/4131] No longer change dir when doing directory searches. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@542 --- src/platform/visualc/dirent.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/platform/visualc/dirent.c b/src/platform/visualc/dirent.c index 1f8df13e..f6be7922 100644 --- a/src/platform/visualc/dirent.c +++ b/src/platform/visualc/dirent.c @@ -7,6 +7,7 @@ */ #include "dirent.h" +#include "io.h" #ifdef WIN32 @@ -22,17 +23,14 @@ DIR * opendir(const char *dirname) { /* Stash the directory name */ strcpy(dir.pathName,dirname); + strcat(dir.pathName,"*.*"); /* set the handle to invalid and set the firstTime flag */ dir.handle = INVALID_HANDLE_VALUE; dir.firstTime = TRUE; - if (strcmp(dirname, ".") == 0) { - return &dir; - } - /* Change the current directory to the one requested */ - return (SetCurrentDirectory(dir.pathName) != 0) ? &dir : NULL; + return (access(dirname,0) ? NULL : &dir); } /** Close the current directory - return 0 if success */ @@ -60,7 +58,7 @@ struct dirent * readdir(DIR *dirp) { if (TRUE == dirp->firstTime) { /** Get the first entry in the directory */ - dirp->handle = FindFirstFile("*.*", &dirp->findFileData); + dirp->handle = FindFirstFile(dirp->pathName, &dirp->findFileData); dirp->firstTime = FALSE; if (INVALID_HANDLE_VALUE == dirp->handle) { From f768cce58727e9b4419899c7c81338e7108fbe92 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 28 Nov 2002 17:52:34 +0000 Subject: [PATCH 0465/4131] Small bug with not showing correct 32bit regname with %Ec Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@543 --- src/debug/debug_disasm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debug/debug_disasm.cpp b/src/debug/debug_disasm.cpp index 00076d1a..e444a5ff 100644 --- a/src/debug/debug_disasm.cpp +++ b/src/debug/debug_disasm.cpp @@ -662,7 +662,7 @@ static void reg_name(int regnum, char size) uprintf("st(%d)", regnum); return; } - if (((size == 'v') && (opsize == 32)) || (size == 'd')) + if ((((size == 'c') || (size == 'v')) && (opsize == 32)) || (size == 'd')) uputchar('e'); if ((size=='q' || size == 'b' || size=='c') && !wordop) { uputchar("acdbacdb"[regnum]); From 7e0be98e8cb407b79ade0d2b544d7740ccf0e210 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 28 Nov 2002 18:22:12 +0000 Subject: [PATCH 0466/4131] VSC doesn't all the casts Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@544 --- src/hardware/timer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 56d31ea3..24083f56 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -56,7 +56,7 @@ static void counter_latch(Bitu counter) { /* Fill the read_latch of the selected counter with current count */ PIT_Block * p=&pit[counter]; - Bit64u micro=PIC_MicroCount(); + Bit64s micro=PIC_MicroCount(); micro-=p->start; micro%=p->micro; Bit16u ticks=(Bit16u)(((float)micro/(float)p->micro)*(float)p->cntr); From cfb007c9cfda53069024b23d56ce3212d2e22f09 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 28 Nov 2002 19:47:36 +0000 Subject: [PATCH 0467/4131] changed int 13 00 and 02 a bit hopefully this will fix things Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@545 --- src/ints/bios_disk.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 14f10e0b..cb53cb28 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -31,9 +31,14 @@ static Bit8u last_status; static Bitu INT13_SmallHandler(void) { switch (reg_ah) { + case 0x0: + reg_ah=0x00; + CALLBACK_SCF(false); + LOG_DEBUG("reset disk return succesfull"); + break; case 0x02: /* Read Disk Sectors */ LOG_DEBUG("INT13:02:Read Disk Sectors not supported failing"); - reg_ah=0xff; + reg_ah=0x80; CALLBACK_SCF(true); break; case 0x04: From 75db2a53f96d642e05e40019e75755e6a578320d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 29 Nov 2002 08:41:28 +0000 Subject: [PATCH 0468/4131] Set the correct values when the dma transfer ends in single cycle mode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@546 --- src/hardware/dma.cpp | 61 +++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 1dba7e3d..c2e9aea2 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -83,11 +83,12 @@ static Bit8u read_dma(Bit32u port) { ret=(chan->current_address>>8)&0xff; } cont->flipflop=!cont->flipflop; + break; case 0x01:case 0x03:case 0x05:case 0x07: if (cont->flipflop) { - ret=(chan->current_count-1) & 0xff; + ret=(Bit8u)((chan->current_count-1) & 0xff); } else { - ret=((chan->current_count-1)>>8)&0xff; + ret=(Bit8u)(((chan->current_count-1)>>8)&0xff); } cont->flipflop=!cont->flipflop; break; @@ -110,18 +111,18 @@ static void write_dma(Bit32u port,Bit8u val) { switch (port) { case 0x00:case 0x02:case 0x04:case 0x06: if (cont->flipflop) { - chan->base_address=val; + chan->base_address=(chan->base_address & 0xff00) | val; } else { - chan->base_address|=(val<<8); + chan->base_address=(chan->base_address & 0x00ff) | (val<<8); } cont->flipflop=!cont->flipflop; chan->addr_changed=true; break; case 0x01:case 0x03:case 0x05:case 0x07: if (cont->flipflop) { - chan->base_count=val; + chan->base_count=(chan->base_count & 0xff00) | val; } else { - chan->base_count|=(val<<8); + chan->base_count=(chan->base_count & 0x00ff) | (val<<8); } cont->flipflop=!cont->flipflop; chan->addr_changed=true; @@ -160,19 +161,20 @@ static void write_dma(Bit32u port,Bit8u val) { }; -static Bit8u channelindex[7] = {2, 3, 1, 0, 0, 0, 0}; void write_dma_page(Bit32u port,Bit8u val) { - + Bitu channel; switch (port) { case 0x81: /* dma0 page register, channel 2 */ + channel=2;break; case 0x82: /* dma0 page register, channel 3 */ + channel=3;break; case 0x83: /* dma0 page register, channel 1 */ + channel=1;break; case 0x87: /* dma0 page register, channel 0 */ - Bitu channel = channelindex[port - 0x81]; - dma[0].chan[channel].page=val; - dma[0].chan[channel].addr_changed=true; - break; + channel=0;break; } + dma[0].chan[channel].page=val; + dma[0].chan[channel].addr_changed=true; } Bit16u DMA_8_Read(Bit32u dmachan,Bit8u * buffer,Bit16u count) { @@ -197,22 +199,29 @@ Bit16u DMA_8_Read(Bit32u dmachan,Bit8u * buffer,Bit16u count) { chan->current_count-=count; return count; } else { - /* Set the end of counter bit */ - dma[0].status_reg|=(1 << dmachan); /* Copy remaining piece of first buffer */ MEM_BlockRead(chan->address,buffer,chan->current_count); - buffer+=chan->current_count; - count-=(Bit16u)chan->current_count; - /* Autoinit reset the dma channel */ - chan->address=(chan->page << 16)+chan->base_address; - chan->current_count=chan->base_count+1; - chan->current_address=chan->base_address; - /* Copy the rest of the buffer */ - MEM_BlockRead(chan->address,buffer,count); - chan->address+=count; - chan->current_address+=count; - chan->current_count-=count; - return count; + if (!chan->mode.autoinit_enable) { + /* Set the end of counter bit */ + dma[0].status_reg|=(1 << dmachan); + count=(Bit16u)chan->current_count; + chan->current_address+=count;; + chan->current_count=0; + return count; + } else { + buffer+=chan->current_count; + Bit16u left=count-(Bit16u)chan->current_count; + /* Autoinit reset the dma channel */ + chan->address=(chan->page << 16)+chan->base_address; + chan->current_count=chan->base_count+1; + chan->current_address=chan->base_address; + /* Copy the rest of the buffer */ + MEM_BlockRead(chan->address,buffer,left); + chan->address+=left; + chan->current_address+=left; + chan->current_count-=left; + return count; + } } }; From f2ee392b0e4b1709d08d2f15efde09f3e4c0d60f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 30 Nov 2002 11:34:43 +0000 Subject: [PATCH 0469/4131] hmm Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@547 --- src/cpu/core_16/instructions.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_16/instructions.h b/src/cpu/core_16/instructions.h index 8bd1901c..b43405d2 100644 --- a/src/cpu/core_16/instructions.h +++ b/src/cpu/core_16/instructions.h @@ -375,10 +375,10 @@ flags.cf=get_CF();flags.type=t_RCLd; \ flags.var2.b=op2;flags.var1.d=load(op1); \ if (flags.var2.b==1) { \ - flags.result.d=flags.var1.d << 1 | flags.cf; \ + 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.cf << (flags.var2.b-1)) | \ (flags.var1.d >> (33-flags.var2.b)); \ } \ flags.cf=((flags.var1.d >> (32-flags.var2.b)) & 1); \ From 43801a39c2ba5eaf8ed21c655eb237b6479b880f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 30 Nov 2002 11:46:08 +0000 Subject: [PATCH 0470/4131] Fix to imul not being correct with sign extension Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@548 --- src/cpu/core_16/prefix_66.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index 636a8f99..0379490f 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -436,7 +436,7 @@ switch(Fetchb()) { case 0x20: /* MUL EAX,Ed */ { flags.type=t_MUL; - if (rm >= 0xc0 ) {GetEArd;temp.u=(Bit64s)reg_eax * (Bit64u)(*eard);} + if (rm >= 0xc0 ) {GetEArd;temp.u=(Bit64u)reg_eax * (Bit64u)(*eard);} else {GetEAa;temp.u=(Bit64u)reg_eax * (Bit64u)LoadMd(eaa);} reg_eax=(Bit32u)(temp.u & 0xffffffff);reg_edx=(Bit32u)(temp.u >> 32); flags.cf=flags.of=(reg_edx !=0); @@ -445,9 +445,9 @@ switch(Fetchb()) { 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 (rm >= 0xc0 ) {GetEArd;temp.s=((Bit64s)((Bit32s)reg_eax) * (Bit64s)(*eards));} + else {GetEAa;temp.s=((Bit64s)((Bit32s)reg_eax) * (Bit64s)(LoadMds(eaa)));} + reg_eax=Bit32u(temp.s & 0xffffffff);reg_edx=(Bit32u)(temp.s >> 32); if ( (reg_edx==0xffffffff) && (reg_eax & 0x80000000) ) { flags.cf=flags.of=false; } else if ( (reg_edx==0x00000000) && (reg_eax<0x80000000) ) { From 3a88d6f1f6e659c7e1eeff5da208ccac3acc09cb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 30 Nov 2002 11:52:56 +0000 Subject: [PATCH 0471/4131] Remove the previous wait event before starting a new one. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@549 --- src/ints/bios.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index fcd08405..206c34b6 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -169,6 +169,7 @@ static Bitu INT15_Handler(void) { mem_writed(BIOS_WAIT_FLAG_POINTER,RealMake(SegValue(es),reg_bx)); mem_writed(BIOS_WAIT_FLAG_COUNT,reg_cx<<16|reg_dx); mem_writeb(BIOS_WAIT_FLAG_ACTIVE,1); + PIC_RemoveEvents(&WaitFlagEvent); PIC_AddEvent(&WaitFlagEvent,reg_cx<<16|reg_dx); break; case 0x84: /* BIOS - JOYSTICK SUPPORT (XT after 11/8/82,AT,XT286,PS) */ From a49847e0e19a2eaeacfdb1116c8a67a6959f07d0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 30 Nov 2002 11:54:10 +0000 Subject: [PATCH 0472/4131] New adlib timer counter using the new pic timing. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@550 --- src/hardware/adlib.cpp | 47 +++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 87e36302..8552a0ba 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -22,7 +22,7 @@ #include "dosbox.h" #include "inout.h" #include "mixer.h" -#include "timer.h" +#include "pic.h" #include "hardware.h" #include "setup.h" /* @@ -45,8 +45,8 @@ struct OPLTimer_t { bool isEnabled; bool isMasked; bool isOverflowed; - Bit32u count; - Bit32u base; + Bit64u count; + Bit64u base; }; static OPLTimer_t timer1,timer2; @@ -65,20 +65,20 @@ static void ADLIB_CallBack(Bit8u *stream, Bit32u len) { static Bit8u read_p388(Bit32u port) { Bit8u ret=0; - Bit32u new_ticks=GetTicks(); + Bit64u micro=PIC_MicroCount(); if (timer1.isEnabled) { - if ((new_ticks-timer1.base)>timer1.count) { + if ((micro-timer1.base)>timer1.count) { timer1.isOverflowed=true; - timer1.base=new_ticks; + timer1.base=micro; } if (timer1.isOverflowed || !timer1.isMasked) { ret|=0xc0; } } if (timer2.isEnabled) { - if ((new_ticks-timer2.base)>timer2.count) { + if ((micro-timer2.base)>timer2.count) { timer2.isOverflowed=true; - timer2.base=new_ticks; + timer2.base=micro; } if (timer2.isOverflowed || !timer2.isMasked) { ret|=0xA0; @@ -94,10 +94,10 @@ static void write_p388(Bit32u port,Bit8u val) { static void write_p389(Bit32u port,Bit8u val) { switch (regsel) { case 0x02: /* Timer 1 */ - timer1.count=(val*80/1000); + timer1.count=val*80; return; case 0x03: /* Timer 2 */ - timer2.count=(val*320/1000); + timer2.count=val*320; return; case 0x04: /* IRQ clear / mask and Timer enable */ if (val&0x80) { @@ -105,20 +105,19 @@ static void write_p389(Bit32u port,Bit8u val) { timer2.isOverflowed=false; return; } - if (val&0x40) { - timer1.isMasked=true; - } else { - timer1.isMasked=false; - timer1.isEnabled=((val&1)>0); - timer1.base=GetTicks(); - } - if (val&0x20) { - timer2.isMasked=true; - } else { - timer2.isMasked=false; - timer2.isEnabled=((val&2)>0); - timer2.base=GetTicks(); - } + if (val&0x40) timer1.isMasked=true; + else timer1.isMasked=false; + + if (val&1) { + timer1.isEnabled=true; + timer1.base=PIC_MicroCount(); + } else timer1.isEnabled=false; + if (val&0x20) timer2.isMasked=true; + else timer2.isMasked=false; + if (val&2) { + timer2.isEnabled=true; + timer2.base=PIC_MicroCount(); + } else timer2.isEnabled=false; return; default: /* Normal OPL call queue it */ MAME::OPLWriteReg(myopl,regsel,val); From 96edd67bb7e93df34e61ed835827819e7445f2da Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 30 Nov 2002 11:54:54 +0000 Subject: [PATCH 0473/4131] Sinewave and disabling support, although sine is buggy. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@551 --- src/hardware/pcspeaker.cpp | 78 ++++++++++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 19 deletions(-) diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 5043df46..f85f2891 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -20,6 +20,7 @@ #include "dosbox.h" #include "mixer.h" #include "timer.h" +#include "setup.h" #ifndef PI @@ -30,20 +31,25 @@ #define SPKR_RATE 22050 #define SPKR_VOLUME 5000 -#define FREQ_SHIFT 16 -#define FREQ_MAX (2 << FREQ_SHIFT) +#define SPKR_SHIFT 16 + +#define SIN_ENT 1024 +#define SIN_MAX (SIN_ENT << SPKR_SHIFT) + +#define FREQ_MAX (2 << SPKR_SHIFT) #define FREQ_HALF (FREQ_MAX >> 1) - - struct Speaker { - Bit32u freq_add; - Bit32u freq_pos; + Bitu freq_add; + Bitu freq_pos; Bit16s volume; MIXER_Channel * chan; bool enabled; bool realsound; + bool sinewave; + Bitu mode; Bit16u buffer[SPKR_BUF]; + Bit16s table[SIN_ENT]; Bitu buf_pos; }; @@ -52,6 +58,7 @@ static Speaker spkr; void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode) { + spkr.mode=mode; switch (mode) { case 0: if (cntr>72) cntr=72; @@ -59,8 +66,14 @@ void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode) { if (spkr.buf_pos0) { - *(Bit16s*)(stream)=spkr.buffer[buf_pos >> 16]; - buf_pos+=buf_add; - stream+=2; + switch (spkr.mode) { + case 0: + /* Generate the "RealSound" */ + { + Bitu buf_add=(spkr.buf_pos<<16)/len; + Bitu buf_pos=0; + spkr.buf_pos=0;spkr.realsound=0; + while (len-->0) { + *(Bit16s*)(stream)=spkr.buffer[buf_pos >> 16]; + buf_pos+=buf_add; + stream+=2; + } + break; } - } else { - /* Generate a square wave */ - while (len-->0) { + case 3: + if (spkr.sinewave) while (len-->0) { + spkr.freq_pos+=spkr.freq_add; + spkr.freq_pos&=(SIN_MAX-1); + *(Bit16s*)(stream)=spkr.table[spkr.freq_pos>>SPKR_SHIFT]; + stream+=2; + } else while (len-->0) { spkr.freq_pos+=spkr.freq_add; if (spkr.freq_pos>=FREQ_MAX) spkr.freq_pos-=FREQ_MAX; if (spkr.freq_pos>=FREQ_HALF) { @@ -92,11 +113,26 @@ static void PCSPEAKER_CallBack(Bit8u * stream,Bit32u len) { } stream+=2; } + break; + case 4: + while (len-->0) { + if (spkr.freq_pos) { + *(Bit16s*)(stream)=spkr.volume; + spkr.freq_pos--; + } else { + *(Bit16s*)(stream)=-spkr.volume; + } + stream+=2; + } + break; } } void PCSPEAKER_Init(Section* sec) { MSG_Add("SPEAKER_CONFIGFILE_HELP","pcspeaker related options.\n"); + Section_prop * section=static_cast(sec); + if(!section->Get_bool("enabled")) return; + spkr.sinewave=section->Get_bool("sinewave"); spkr.chan=MIXER_AddChannel(&PCSPEAKER_CallBack,SPKR_RATE,"PC-SPEAKER"); MIXER_Enable(spkr.chan,false); MIXER_SetMode(spkr.chan,MIXER_16MONO); @@ -104,4 +140,8 @@ void PCSPEAKER_Init(Section* sec) { spkr.enabled=false; spkr.realsound=false; spkr.buf_pos=0; + /* Generate the sine wave */ + for (Bitu i=0;i Date: Sat, 30 Nov 2002 12:15:16 +0000 Subject: [PATCH 0474/4131] Default handler for int 1 single stepping. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@552 --- src/ints/bios.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 206c34b6..f9872d7f 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -25,6 +25,7 @@ #include "pic.h" static Bitu call_int1a,call_int11,call_int8,call_int17,call_int12,call_int15,call_int1c; +static Bitu call_int1; static Bitu INT1A_Handler(void) { switch (reg_ah) { @@ -212,12 +213,16 @@ static Bitu INT15_Handler(void) { CALLBACK_SCF(false); } return CBRET_NONE; -}; - -static void INT15_StartUp(void) { -/* TODO Start the time correctly */ -}; +} +static Bitu INT1_Single_Step(void) { + static bool warned=false; + if (!warned) { + warned=true; + LOG_WARN("INT 1:Single Step called"); + } + return CBRET_NONE; +} void BIOS_SetupKeyboard(void); void BIOS_SetupDisks(void); @@ -262,10 +267,15 @@ void BIOS_Init(Section* sec) { CALLBACK_Setup(call_int1a,&INT1A_Handler,CB_IRET_STI); RealSetVec(0x1A,CALLBACK_RealPointer(call_int1a)); /* INT 1C System Timer tick called from INT 8 */ - call_int1c=CALLBACK_Allocate(); + call_int1c=CALLBACK_Allocate(); CALLBACK_Setup(call_int1c,&INT1C_Handler,CB_IRET); RealSetVec(0x1C,CALLBACK_RealPointer(call_int1c)); + /* Some defeault CPU error interrupt handlers */ + call_int1=CALLBACK_Allocate(); + CALLBACK_Setup(call_int1,&INT1_Single_Step,CB_IRET); + RealSetVec(0x1,CALLBACK_RealPointer(call_int1)); + } From 406c78e2cc73f12ec4981c03cb3186c56691a46a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 30 Nov 2002 12:32:07 +0000 Subject: [PATCH 0475/4131] Some case entries in port 64 for active/deactivate keyboard commands. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@553 --- src/hardware/keyboard.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 5191cf37..f408ac93 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -48,6 +48,7 @@ struct KeyBlock { KeyCommands command; bool read_active; bool enabled; + bool active; }; static KeyBlock keyb; @@ -151,7 +152,12 @@ static void write_p61(Bit32u port,Bit8u val) { static void write_p64(Bit32u port,Bit8u val) { switch (val) { - case 0: + case 0xad: /* Activate keyboard */ + keyb.active=true; + break; + case 0xae: /* Deactivate keyboard */ + keyb.active=false; + break; default: LOG_DEBUG("Port 64 write with val %d",val); break; From 845d5c172fa6ada66c191f30b88fbfc5b0ce5f7b Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 30 Nov 2002 14:41:21 +0000 Subject: [PATCH 0476/4131] Fixed change dir command. TestDir returns false now if target is not a directory. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@554 --- src/dos/dos_files.cpp | 8 +------- src/dos/drive_local.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 42a0c08e..42b64502 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -151,13 +151,7 @@ bool DOS_GetCurrentDir(Bit8u drive,char * buffer) { } bool DOS_ChangeDir(char * dir) { - - // Be sure its not a file (Eye of the beholder 3) - char* str; - if (str=strchr(dir,'.')) { - if (isalpha(str[1]) || isdigit(str[1])) return false; - }; - + Bit8u drive;char fulldir[DOS_PATHLENGTH]; if (!DOS_MakeName(dir,fulldir,&drive)) return false; diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 28bf7c12..7e79cd2e 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -188,6 +188,14 @@ bool localDrive::TestDir(char * dir) { strcpy(newdir,basedir); strcat(newdir,dir); CROSS_FILENAME(newdir); + // Skip directory test, if "\" + Bit16u len = strlen(newdir); + if ((len>0) && (newdir[len-1]!='\\')) { + // It has to be a directory ! + struct stat test; + if (stat(newdir,&test)==-1) return false; + if ((test.st_mode & S_IFDIR)==0) return false; + }; int temp=access(newdir,F_OK); return (temp==0); } From 8f4eaf16a2fb0a5b85cc97e84726a6fade629ad8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 2 Dec 2002 18:56:53 +0000 Subject: [PATCH 0477/4131] fixed int 21 1c and changed sectors allocation to bit8 instead of bit16 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@555 --- include/dos_inc.h | 4 ++-- include/dos_system.h | 2 +- src/dos/dos.cpp | 21 ++++++++++++++------- src/dos/dos_files.cpp | 4 ++-- src/dos/dos_programs.cpp | 3 ++- src/dos/drive_local.cpp | 4 ++-- src/dos/drive_virtual.cpp | 2 +- src/dos/drives.h | 8 ++++---- 8 files changed, 28 insertions(+), 20 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 346c5a26..b5f31a81 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -119,7 +119,7 @@ bool DOS_ChangeDir(char * dir); bool DOS_MakeDir(char * dir); bool DOS_RemoveDir(char * dir); bool DOS_Rename(char * oldname,char * newname); -bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free); +bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit8u * sectors,Bit16u * clusters,Bit16u * free); bool DOS_GetFileAttr(char * name,Bit16u * attr); /* IOCTL Stuff */ @@ -158,7 +158,7 @@ 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,Bit16u * _sectors_cluster,Bit16u * _total_clusters); +bool DOS_GetAllocationInfo(Bit8u drive,Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters); /* Extra DOS Interrupts */ void DOS_SetupMisc(void); diff --git a/include/dos_system.h b/include/dos_system.h index 0223a9a6..545f6612 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -84,7 +84,7 @@ public: virtual bool FindNext(DOS_DTA & dta)=0; virtual bool GetFileAttr(char * name,Bit16u * attr)=0; virtual bool Rename(char * oldname,char * newname)=0; - virtual bool AllocationInfo(Bit16u * _bytes_sector,Bit16u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters)=0; + virtual bool AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters)=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; diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index b65ad676..36d58f0c 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -32,7 +32,7 @@ DOS_Block dos; DOS_InfoBlock dos_infoblock; Bit8u dos_copybuf[0x10000]; -static Bitu call_20,call_21,call_27; +static Bitu call_20,call_21,call_27,call_28; void DOS_SetError(Bit16u code) { dos.errorcode=code; @@ -215,10 +215,10 @@ static Bitu DOS_21Handler(void) { else reg_al = 0xFF; break; case 0x1b: /* Get allocation info for default drive */ - if (!DOS_GetAllocationInfo(0,®_cx,®_ax,®_dx)) reg_al=0xff; + if (!DOS_GetAllocationInfo(0,®_cx,®_al,®_dx)) reg_al=0xff; break; case 0x1c: /* Get allocation info for specific drive */ - if (!DOS_GetAllocationInfo(reg_dl,®_cx,®_ax,®_dx)) reg_al=0xff; + if (!DOS_GetAllocationInfo(reg_dl,®_cx,®_al,®_dx)) reg_al=0xff; break; case 0x21: /* Read random record from FCB */ reg_al = DOS_FCBRandomRead(SegValue(ds),reg_dx,1,true); @@ -359,7 +359,8 @@ static Bitu DOS_21Handler(void) { break; case 0x36: /* Get Free Disk Space */ { - Bit16u bytes,sectors,clusters,free; + Bit16u bytes,clusters,free; + Bit8u sectors; if (DOS_GetFreeDiskSpace(reg_dl,&bytes,§ors,&clusters,&free)) { reg_ax=sectors; reg_bx=free; @@ -783,9 +784,6 @@ static Bitu DOS_21Handler(void) { LOG_DEBUG("DOS:67:Set Handle Count not working"); CALLBACK_SCF(false); break; - case 0x68: /* FFLUSH Commit file */ - E_Exit("Unhandled Dos 21 call %02X",reg_ah); - break; case 0x69: /* Get/Set disk serial number */ { switch(reg_al) { @@ -808,6 +806,7 @@ static Bitu DOS_21Handler(void) { CALLBACK_SCF(true); LOG_WARN("DOS:Windows long file name support call %2X",reg_al); break; + case 0x68: /* FFLUSH Commit file */ case 0xE0: case 0x18: /* NULL Function for CP/M compatibility or Extended rename FCB */ case 0x1d: /* NULL Function for CP/M compatibility or Extended rename FCB */ @@ -844,6 +843,10 @@ static Bitu DOS_27Handler(void) return CBRET_NONE; } +static Bitu DOS_28Handler(void) { + return CBRET_NONE; +} + void DOS_Init(Section* sec) { MSG_Add("DOS_CONFIGFILE_HELP","Setting a memory size to 0 will disable it.\n"); call_20=CALLBACK_Allocate(); @@ -858,6 +861,10 @@ void DOS_Init(Section* sec) { CALLBACK_Setup(call_27,DOS_27Handler,CB_IRET); RealSetVec(0x27,CALLBACK_RealPointer(call_27)); + call_28=CALLBACK_Allocate(); + CALLBACK_Setup(call_28,DOS_28Handler,CB_IRET); + RealSetVec(0x28,CALLBACK_RealPointer(call_28)); + DOS_SetupFiles(); /* Setup system File tables */ DOS_SetupDevices(); /* Setup dos devices */ DOS_SetupTables(); diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 42b64502..eb4ba80b 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -400,7 +400,7 @@ bool DOS_Canonicalize(char * name,char * big) { return true; } -bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free) { +bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit8u * sectors,Bit16u * clusters,Bit16u * free) { if (drive==0) drive=DOS_GetDefaultDrive(); else drive--; if ((drive>DOS_DRIVES) || (!Drives[drive])) { @@ -807,7 +807,7 @@ bool DOS_FileExists(char * name) { return Drives[drive]->FileExists(fullname); } -bool DOS_GetAllocationInfo(Bit8u drive,Bit16u * _bytes_sector,Bit16u * _sectors_cluster,Bit16u * _total_clusters) { +bool DOS_GetAllocationInfo(Bit8u drive,Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters) { if (!drive) drive=dos.current_drive; else drive--; if (!Drives[drive]) return false; diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 2a811abc..24b1ce81 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -85,7 +85,8 @@ public: return; } if (temp_line[temp_line.size()-1]!=CROSS_FILESPLIT) temp_line+=CROSS_FILESPLIT; - newdrive=new localDrive(temp_line.c_str(),sizes[0],sizes[1],sizes[2],sizes[3],mediaid); + Bit8u bit8size=(Bit8u) sizes[1]; + newdrive=new localDrive(temp_line.c_str(),sizes[0],bit8size,sizes[2],sizes[3],mediaid); } cmd->FindCommand(1,temp_line); if (temp_line.size()>1) goto showusage; diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 7e79cd2e..a12c504b 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -214,7 +214,7 @@ bool localDrive::Rename(char * oldname,char * newname) { }; -bool localDrive::AllocationInfo(Bit16u * _bytes_sector,Bit16u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters) { +bool localDrive::AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters) { /* Always report 100 mb free should be enough */ /* Total size is always 1 gb */ *_bytes_sector=allocation.bytes_sector; @@ -259,7 +259,7 @@ Bit8u localDrive::GetMediaByte(void) { return allocation.mediaid; } -localDrive::localDrive(const char * startdir,Bit16u _bytes_sector,Bit16u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid) { +localDrive::localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid) { strcpy(basedir,startdir); sprintf(info,"local directory %s",startdir); srch_opendir=NULL; diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 84235e3b..f697c598 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -204,7 +204,7 @@ bool Virtual_Drive::Rename(char * oldname,char * newname) { return false; } -bool Virtual_Drive::AllocationInfo(Bit16u * _bytes_sector,Bit16u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters) { +bool Virtual_Drive::AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters) { /* Always report 100 mb free should be enough */ /* Total size is always 1 gb */ *_bytes_sector=512; diff --git a/src/dos/drives.h b/src/dos/drives.h index 910f147d..90c8fce6 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -29,7 +29,7 @@ bool WildFileCmp(const char * file, const char * wild); class localDrive : public DOS_Drive { public: - localDrive(const char * startdir,Bit16u _bytes_sector,Bit16u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid); + localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid); bool FileOpen(DOS_File * * file,char * name,Bit32u flags); bool FileCreate(DOS_File * * file,char * name,Bit16u attributes); bool FileUnlink(char * name); @@ -40,7 +40,7 @@ public: bool FindNext(DOS_DTA & dta); bool GetFileAttr(char * name,Bit16u * attr); bool Rename(char * oldname,char * newname); - bool AllocationInfo(Bit16u * _bytes_sector,Bit16u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters); + bool AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters); bool FileExists(const char* name); bool FileStat(const char* name, FileStat_Block * const stat_block); Bit8u GetMediaByte(void); @@ -50,7 +50,7 @@ private: DIR * srch_opendir; struct { Bit16u bytes_sector; - Bit16u sectors_cluster; + Bit8u sectors_cluster; Bit16u total_clusters; Bit16u free_clusters; Bit8u mediaid; @@ -73,7 +73,7 @@ public: bool FindNext(DOS_DTA & dta); bool GetFileAttr(char * name,Bit16u * attr); bool Rename(char * oldname,char * newname); - bool AllocationInfo(Bit16u * _bytes_sector,Bit16u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters); + bool AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters); bool FileExists(const char* name); bool FileStat(const char* name, FileStat_Block* const stat_block); Bit8u GetMediaByte(void); From 84e09e2a65c9abf32ccc5d22d3921ac4372645d7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 3 Dec 2002 11:05:17 +0000 Subject: [PATCH 0478/4131] forgot to check in. Another allocationinfo fix Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@556 --- src/shell/shell_cmds.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 1604d4cb..24934ece 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -262,7 +262,7 @@ void DOS_Shell::CMD_DIR(char * args) { //TODO Free Space Bitu free_space=1024*1024*100; if (Drives[drive]) { - Bit16u bytes_sector;Bit16u sectors_cluster;Bit16u total_clusters;Bit16u free_clusters; + Bit16u bytes_sector;Bit8u sectors_cluster;Bit16u total_clusters;Bit16u free_clusters; Drives[drive]->AllocationInfo(&bytes_sector,§ors_cluster,&total_clusters,&free_clusters); free_space=bytes_sector*sectors_cluster*free_clusters; } From 581774e9bcdb5654b6e839d10a9a363c01e0e80b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 3 Dec 2002 17:27:59 +0000 Subject: [PATCH 0479/4131] added support for echoing characters Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@557 --- src/dos/dev_con.h | 34 ++++++++++++++++++++++++++++------ src/dos/dos.cpp | 27 ++++++++++++++++----------- src/shell/shell_misc.cpp | 1 + 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 90f4d0f4..d96b4524 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "dos_inc.h" + class device_CON : public DOS_Device { public: device_CON(); @@ -27,13 +29,18 @@ public: private: Bit8u cache; }; +void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page); bool device_CON::Read(Bit8u * data,Bit16u * size) { Bit16u oldax=reg_ax; Bit16u count=0; if ((cache) && (*size)) { data[count++]=cache; - cache=0; + if(dos.echo) { + INT10_TeletypeOutput(cache,7,false,0); + } + cache=0; + } while (*size>count) { reg_ah=0; @@ -41,11 +48,22 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { switch(reg_al) { case 13: data[count++]=0x0D; - if (*size>count) data[count++]=0x0A; - //else cache=0x0A; // it's only expanded if there is room for it. - *size=count; + if (*size>count) data[count++]=0x0A; // it's only expanded if there is room for it. (NO cache) + *size=count; reg_ax=oldax; return true; + break; + case 8: + if(*size==1) data[count++]=reg_al; //one char at the time so give back that BS + else if(count) { //Remove data if it exists (extended keys don't go right) + data[count--]=0; + INT10_TeletypeOutput(8,7,false,0); + INT10_TeletypeOutput(' ',7,false,0); + } else { + continue; //no data read yet so restart whileloop. + } + + break; default: data[count++]=reg_al; break; @@ -54,14 +72,18 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { if (*size>count) data[count++]=reg_ah; else cache=reg_ah; break; - } + + } + if(dos.echo) { //what to do if *size==1 and character is BS ????? + INT10_TeletypeOutput(reg_al,7,false,0); + } } *size=count; reg_ax=oldax; return true; } -extern void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page); + bool device_CON::Write(Bit8u * data,Bit16u * size) { Bit16u count=0; while (*size>count) { diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 36d58f0c..1e3dcb18 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -46,9 +46,11 @@ static Bitu DOS_21Handler(void) { case 0x01: /* Read character from STDIN, with echo */ { Bit8u c;Bit16u n=1; + dos.echo=true; DOS_ReadFile(STDIN,&c,&n); reg_al=c; - DOS_WriteFile(STDOUT,&c,&n); + dos.echo=false; + } break; case 0x02: /* Write character to STDOUT */ @@ -452,6 +454,7 @@ static Bitu DOS_21Handler(void) { case 0x3f: /* READ Read from file or device */ { Bit16u toread=reg_cx; + dos.echo=true; if (DOS_ReadFile(reg_bx,dos_copybuf,&toread)) { MEM_BlockWrite(SegPhys(ds)+reg_dx,dos_copybuf,toread); reg_ax=toread; @@ -460,6 +463,7 @@ static Bitu DOS_21Handler(void) { reg_ax=dos.errorcode; CALLBACK_SCF(true); } + dos.echo=false; break; } case 0x40: /* WRITE Write to file or device */ @@ -806,19 +810,20 @@ static Bitu DOS_21Handler(void) { CALLBACK_SCF(true); LOG_WARN("DOS:Windows long file name support call %2X",reg_al); break; - case 0x68: /* FFLUSH Commit file */ - case 0xE0: - case 0x18: /* NULL Function for CP/M compatibility or Extended rename FCB */ - case 0x1d: /* NULL Function for CP/M compatibility or Extended rename FCB */ - case 0x1e: /* NULL Function for CP/M compatibility or Extended rename FCB */ - case 0x20: /* NULL Function for CP/M compatibility or Extended rename FCB */ - case 0x6b: /* NULL Function */ - case 0x61: /* UNUSED */ - case 0x63: /* Weirdo double byte stuff (fails but say it succeeded) */ + case 0x68: /* FFLUSH Commit file */ + case 0x63: /* Weirdo double byte stuff (fails but say it succeeded) available only in MSDOS 2.25 */ + CALLBACK_SCF(false); //mirek + case 0xE0: + case 0x18: /* NULL Function for CP/M compatibility or Extended rename FCB */ + case 0x1d: /* NULL Function for CP/M compatibility or Extended rename FCB */ + case 0x1e: /* NULL Function for CP/M compatibility or Extended rename FCB */ + case 0x20: /* NULL Function for CP/M compatibility or Extended rename FCB */ + case 0x6b: /* NULL Function */ + case 0x61: /* UNUSED */ case 0xEF: /* Used in Ancient Art Of War CGA */ case 0x5d: /* Network Functions */ default: - LOG_DEBUG("DOS:Unhandled call %02X al=%02X. Set al to default of 0 no carry",reg_ah,reg_al); + LOG_DEBUG("DOS:Unhandled call %02X al=%02X. Set al to default of 0",reg_ah,reg_al); reg_al=0x00; /* default value */ break; }; diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 6328a642..63a4516d 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -47,6 +47,7 @@ void DOS_Shell::InputCommand(char * line) { Bitu str_len=0;Bitu str_index=0; while (size) { + dos.echo=false; DOS_ReadFile(input_handle,&c,&n); if (!n) { size=0; //Kill the while loop From 21a81276b427c940ffc6fed171bddf6425a3d1c5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 3 Dec 2002 17:30:07 +0000 Subject: [PATCH 0480/4131] added support for int 10:01 set cursortype Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@558 --- src/hardware/vga.h | 5 +++++ src/hardware/vga_draw.cpp | 4 +++- src/ints/int10.cpp | 4 +++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga.h b/src/hardware/vga.h index 88e9ce4d..4d3427d5 100644 --- a/src/hardware/vga.h +++ b/src/hardware/vga.h @@ -20,13 +20,18 @@ #define VGA_H_ #include +#include "dosbox.h" +#undef TEXT +#undef GRAPH +/* conflicts with int10.h */ enum { TEXT, GRAPH }; enum { GFX_256C,GFX_256U,GFX_16,GFX_4,GFX_2, TEXT_16 }; typedef struct { bool attrindex; + Bit16u cursor; } VGA_Internal; typedef struct { diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 9a173da1..1a120999 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -176,7 +176,8 @@ void VGA_DrawTEXT(Bit8u * bitdata,Bitu pitch) { draw_start+=16*pitch; }; VGA_StartRetrace(); - + + if(!(vga.internal.cursor & 0x2000)){ /* Draw a cursor */ if (((Bitu)vga.draw.cursor_col*8)>=vga.draw.width) return; if (((Bitu)vga.draw.cursor_row*16)>=vga.draw.height) return; @@ -186,5 +187,6 @@ void VGA_DrawTEXT(Bit8u * bitdata,Bitu pitch) { } vga.draw.cursor_count++; if (vga.draw.cursor_count>16) vga.draw.cursor_count=0; + } }; diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 635de150..bef20fe2 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -25,6 +25,7 @@ #include "video.h" #include "inout.h" #include "int10.h" +#include "../hardware/vga.h" /* Maybe move this thing */ #define TEXT_SEG 0xb800 @@ -38,7 +39,8 @@ static Bitu INT10_Handler(void) { INT10_SetVideoMode(reg_al); break; case 0x01: /* Set TextMode Cursor Shape */ - LOG_WARN("INT10:01:Set textmode cursor shape not supported"); + vga.internal.cursor=reg_cx; // maybe write some memory somewhere + LOG_DEBUG("INT10:01:Set textmode cursor shape partially supported: %X",reg_cx); break; case 0x02: /* Set Cursor Pos */ //TODO Check some shit but not really usefull From df70497b5481023f292f67905006bad02406f911 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 3 Dec 2002 17:31:32 +0000 Subject: [PATCH 0481/4131] added support echoing in inputfunctions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@559 --- include/dos_inc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dos_inc.h b/include/dos_inc.h index b5f31a81..2a039bd1 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -63,6 +63,7 @@ struct DOS_Block { Bit8u current_drive; bool verify; bool breakcheck; + bool echo; // if set to true dev_con::read will echo input struct { RealPt indosflag; RealPt mediaid; From ca712c0043f97302bde463bd9c2f8d6c7dac239e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 3 Dec 2002 17:32:03 +0000 Subject: [PATCH 0482/4131] added support echoing in inputfunctions added support int10:01 set cursor type Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@560 --- ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index cfa511d9..a5716f69 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,13 @@ 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 + 0.56 - added support for a configclass/configfile From 0db8c2700ffafc66191a153a989c03c933b4d6b9 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 5 Dec 2002 15:58:01 +0000 Subject: [PATCH 0483/4131] Define mouse cursor range : detect and handle 'wrong' parameters Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@561 --- src/ints/mouse.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 77556157..912bd469 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -449,12 +449,22 @@ static Bitu INT33_Handler(void) { break; } case 0x07: /* Define horizontal cursor range */ - mouse.min_x=reg_cx; - mouse.max_x=reg_dx; + if (reg_cx Date: Sun, 8 Dec 2002 15:26:30 +0000 Subject: [PATCH 0484/4131] Added cmos.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@562 --- src/hardware/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index 8f6507d4..8430e7f9 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -7,5 +7,5 @@ noinst_LIBRARIES = libhardware.a libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler.cpp joystick.cpp keyboard.cpp \ memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ vga.cpp vga.h vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_fonts.cpp vga_gfx.cpp \ - vga_memory.cpp vga_misc.cpp vga_seq.cpp font-switch.h ega-switch.h + vga_memory.cpp vga_misc.cpp vga_seq.cpp font-switch.h ega-switch.h cmos.cpp From 6f9f410ecf7552ccb77eb5a03e5adf259ca3ff1f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 9 Dec 2002 18:24:53 +0000 Subject: [PATCH 0485/4131] fixed bushido. Don't understand fcbs anymore Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@563 --- src/dos/dos_files.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index eb4ba80b..d8e2a3af 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -476,7 +476,6 @@ bool DOS_CreateTempFile(char * name,Bit16u * entry) { } -#if 1 static bool FCB_MakeName2 (DOS_FCB & fcb, char* outname, Bit8u* outdrive){ char short_name[DOS_FCBNAME]; @@ -737,7 +736,7 @@ Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { fcb.GetRecord(new_block,new_rec); if (restore) fcb.SetRecord(old_block,old_rec); /* Update the random record pointer with new position */ - fcb.SetRandom(new_block*128+new_rec); + fcb.SetRandom(new_block*128+new_rec - (restore ? 1 : 0) ); //seems to be this way.. why ??? return error; } @@ -758,7 +757,7 @@ Bit8u DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { fcb.GetRecord(new_block,new_rec); if (restore) fcb.SetRecord(old_block,old_rec); /* Update the random record pointer with new position */ - fcb.SetRandom(new_block*128+new_rec); + fcb.SetRandom(new_block*128+new_rec - (restore ? 1 : 0) ); //seems to be this way.. need more games to test it. return error; } @@ -799,7 +798,6 @@ void DOS_FCBSetRandomRecord(Bit16u seg, Bit16u offset) { fcb.SetRandom(block*128+rec); } -#endif bool DOS_FileExists(char * name) { char fullname[DOS_PATHLENGTH];Bit8u drive; From fcb74411a9807ebb3922d895e3b199ee55281a91 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 11 Dec 2002 19:50:40 +0000 Subject: [PATCH 0486/4131] readline considers 0x1b (esc) as a valid char now Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@564 --- src/shell/shell_batch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index fdec91ba..769dccea 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -50,7 +50,7 @@ emptyline: n=1; DOS_ReadFile(file_handle,&c,&n); if (n>0) { - if (c>31) + if (c>31 || c==0x1b) *cmd_write++=c; } } while (c!='\n' && n); From fecc2a4a8ac26e4dda8b6ccdf7280fc5833b475f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 11 Dec 2002 19:52:37 +0000 Subject: [PATCH 0487/4131] int 10:0b now gives 1 warning. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@565 --- src/ints/int10.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index bef20fe2..34d40cf7 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -31,7 +31,7 @@ static Bitu call_10; static bool warned_ff=false; - +static bool warned_int10_0b=false; static Bitu INT10_Handler(void) { switch (reg_ah) { @@ -76,6 +76,10 @@ static Bitu INT10_Handler(void) { INT10_WriteChar(reg_al,reg_bl,reg_bh,reg_cx,false); break; case 0x0B: /* Set Background/Border Colour & Set Palette*/ + if(!warned_int10_0b) { + LOG_WARN("INT 10:0B Unsupported: Set Background/border colour & Set Pallete"); + warned_int10_0b=true; + } break; E_Exit("Unsupported int 10 call %02X" ,reg_ah); break; From 9aafc9ae6fd38a05bb699026b73fe4e4fb0a6a62 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 11 Dec 2002 19:54:45 +0000 Subject: [PATCH 0488/4131] fixed fcb random block read/write. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@566 --- src/dos/dos_files.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index d8e2a3af..3dc25faf 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -720,13 +720,19 @@ Bit8u DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u recno) } Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { +/* if restore is true :random read else random blok read. + * random read updates old block and old record to reflect the random data + * before the read!!!!!!!!! and the random data is not updated! (user must do this) + * Random block read updates these fields to reflect the state after the read! + */ DOS_FCB fcb(seg,offset); Bit32u random;Bit16u old_block;Bit8u old_rec;Bit8u error; + /* Set the correct record from the random data */ fcb.GetRandom(random); - if (restore) fcb.GetRecord(old_block,old_rec); fcb.SetRecord((Bit16u)(random / 128),(Bit8u)(random & 127)); + if (restore) fcb.GetRecord(old_block,old_rec);//store this for after the read. // Read records for (int i=0; i Date: Wed, 11 Dec 2002 19:56:04 +0000 Subject: [PATCH 0489/4131] fixed fcb random block read/write. added minimal int 29 handler(detector) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@567 --- src/dos/dos.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 1e3dcb18..4b804a54 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -32,7 +32,7 @@ DOS_Block dos; DOS_InfoBlock dos_infoblock; Bit8u dos_copybuf[0x10000]; -static Bitu call_20,call_21,call_27,call_28; +static Bitu call_20,call_21,call_27,call_28,call_29; void DOS_SetError(Bit16u code) { dos.errorcode=code; @@ -239,11 +239,11 @@ static Bitu DOS_21Handler(void) { break; case 0x27: /* Random block read from FCB */ reg_al = DOS_FCBRandomRead(SegValue(ds),reg_dx,reg_cx,false); - LOG_DEBUG("DOS:0x27 FCB-Random read used, result:al=%d",reg_al); + LOG_DEBUG("DOS:0x27 FCB-Random(block) read used, result:al=%d",reg_al); break; case 0x28: /* Random Block write to FCB */ reg_al=DOS_FCBRandomWrite(SegValue(ds),reg_dx,reg_cx,false); - LOG_DEBUG("DOS:0x28 FCB-Random write used, result:al=%d",reg_al); + LOG_DEBUG("DOS:0x28 FCB-Random(block) write used, result:al=%d",reg_al); break; case 0x29: /* Parse filename into FCB */ { Bit8u difference; @@ -852,6 +852,11 @@ static Bitu DOS_28Handler(void) { return CBRET_NONE; } +static Bitu DOS_29Handler(void) { + LOG_DEBUG("int 29 called"); + return CBRET_NONE; +} + void DOS_Init(Section* sec) { MSG_Add("DOS_CONFIGFILE_HELP","Setting a memory size to 0 will disable it.\n"); call_20=CALLBACK_Allocate(); @@ -870,6 +875,10 @@ void DOS_Init(Section* sec) { CALLBACK_Setup(call_28,DOS_28Handler,CB_IRET); RealSetVec(0x28,CALLBACK_RealPointer(call_28)); + call_29=CALLBACK_Allocate(); + CALLBACK_Setup(call_29,DOS_29Handler,CB_IRET); + RealSetVec(0x29,CALLBACK_RealPointer(call_29)); + DOS_SetupFiles(); /* Setup system File tables */ DOS_SetupDevices(); /* Setup dos devices */ DOS_SetupTables(); From 8ae271bf1985171d6d3b2ddb8dd141e6b2641bf6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 11 Dec 2002 19:57:21 +0000 Subject: [PATCH 0490/4131] added support for ansi terminal graphics. outputted the 0xD 0xA when they appear in the Read function Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@568 --- src/dos/dev_con.h | 256 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 252 insertions(+), 4 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index d96b4524..ccae558e 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -17,6 +17,9 @@ */ #include "dos_inc.h" +#include "../ints/int10.h" + +#define NUMBER_ANSI_DATA 10 class device_CON : public DOS_Device { public: @@ -25,11 +28,25 @@ public: bool Write(Bit8u * data,Bit16u * size); bool Seek(Bit32u * pos,Bit32u type); bool Close(); + void ClearAnsi(void); Bit16u GetInformation(void); private: Bit8u cache; + struct ansi { /* should create a constructor which fills them with the appriorate values */ + bool esc; + bool sci; + Bit8u attr; + Bit8u data[NUMBER_ANSI_DATA]; + Bit8u numberofarg; + Bit16u nrows; + Bit16u ncols; + Bit8s savecol; + Bit8s saverow; + } ansi; + }; void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page); +void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page); bool device_CON::Read(Bit8u * data,Bit16u * size) { Bit16u oldax=reg_ax; @@ -51,6 +68,10 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { if (*size>count) data[count++]=0x0A; // it's only expanded if there is room for it. (NO cache) *size=count; reg_ax=oldax; + if(dos.echo) { + INT10_TeletypeOutput(13,7,false,0); //maybe don't do this ( no need for it actually ) (but it's compatible) + INT10_TeletypeOutput(10,7,false,0); + } return true; break; case 8: @@ -86,10 +107,223 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { bool device_CON::Write(Bit8u * data,Bit16u * size) { Bit16u count=0; - while (*size>count) { + Bitu i; + Bit8s col,row; + static bool ansiwarned=false; - INT10_TeletypeOutput(data[count],7,false,0); - count++; + while (*size>count) { + if (!ansi.esc){ + if(data[count]=='\033') { + /*clear the datastructure */ + ClearAnsi(); + /* start the sequence */ + ansi.esc=true; + count++; + if(!ansiwarned) { + LOG_WARN("ANSI sequences detected. enabling ansi support"); /* maybe LOG_MSG */ + ansiwarned=true; + } + continue; + + } else { + INT10_TeletypeOutput(data[count],ansi.attr,true,0); + count++; + continue; + }; + }; + /* ansi.esc=true */ + if(!ansi.sci){ + + switch(data[count]){ + case '[': + ansi.sci=true; + break; + case '7': /* save cursor pos +attr */ + case '8': /* restore this (Wonder if this is actually used) */ + case 'D':/* scrolling DOWN*/ + case 'M':/* scrolling UP*/ + default: + LOG_DEBUG("ANSI: unknown char %c after a esc",data[count]); /*prob () */ + break; + } + count++; + continue; + + } + /*ansi.esc and ansi.sci are true */ + switch(data[count]){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + ansi.data[ansi.numberofarg]=10*ansi.data[ansi.numberofarg]+(data[count]-'0'); + break; + case ';': /* till a max of NUMBER_ANSI_DATA */ + ansi.numberofarg++; + break; + case 'm': /* SGR */ + for(i=0;i<=ansi.numberofarg;i++){ + + switch(ansi.data[i]){ + case 0: /* normal */ + ansi.attr=0x7; + break; + case 1: /* bold mode on*/ + ansi.attr|=0x8; + break; + case 4: /* underline */ + LOG_DEBUG("ANSI:no support for underline yet"); + break; + case 5: /* blinking */ + LOG_DEBUG("ANSI:no support for blinking yet"); + break; + case 7: /* reverse */ + LOG_DEBUG("ANSI:no support for reverse yet"); + break; + case 30: /* fg color black */ + ansi.attr&=0xf8; + ansi.attr|=0x0; + break; + case 31: /* fg color red */ + ansi.attr&=0xf8; + ansi.attr|=0x4; + break; + case 32: /* fg color green */ + ansi.attr&=0xf8; + ansi.attr|=0x2; + break; + case 33: /* fg color yellow */ + ansi.attr&=0xf8; + ansi.attr|=0x6; + break; + case 34: /* fg color blue */ + ansi.attr&=0xf8; + ansi.attr|=0x1; + break; + case 35: /* fg color magenta */ + ansi.attr&=0xf8; + ansi.attr|=0x5; + break; + case 36: /* fg color cyan */ + ansi.attr&=0xf8; + ansi.attr|=0x3; + break; + case 37: /* fg color white */ + ansi.attr&=0xf8; + ansi.attr|=0x7; + break; + case 40: + ansi.attr&=0x8f; + ansi.attr|=0x0; + break; + case 41: + ansi.attr&=0x8f; + ansi.attr|=0x40; + break; + case 42: + ansi.attr&=0x8f; + ansi.attr|=0x20; + break; + case 43: + ansi.attr&=0x8f; + ansi.attr|=0x60; + break; + case 44: + ansi.attr&=0x8f; + ansi.attr|=0x10; + break; + case 45: + ansi.attr&=0x8f; + ansi.attr|=0x50; + break; + case 46: + ansi.attr&=0x8f; + ansi.attr|=0x30; + break; + case 47: + ansi.attr&=0x8f; + ansi.attr|=0x70; + break; + default: + break; + + } + } + ClearAnsi(); + break; + case 'f': + case 'H':/* Cursor Pos*/ + if(ansi.data[0]==0) ansi.data[0]=1; + if(ansi.data[1]==0) ansi.data[1]=1; + INT10_SetCursorPos(--(ansi.data[0]),--(ansi.data[1]),0); /*ansi=1 based, int10 is 0 based */ + ClearAnsi(); + break; + case 'A': /* cursor up*/ + col=CURSOR_POS_COL(0) ; + row=CURSOR_POS_ROW(0) - (ansi.data[0]? ansi.data[0] : 1); + INT10_SetCursorPos(row,col,0); + ClearAnsi(); + break; + case 'C': /*cursor forward */ + col=CURSOR_POS_COL(0) + (ansi.data[0]? ansi.data[0] : 1); + row=CURSOR_POS_ROW(0); + while(col>=ansi.ncols) { + row++; + col = col - ansi.ncols; // should depend on linebrake mode + } + INT10_SetCursorPos(row,col,0); + ClearAnsi(); + break; + case 'J': /*erase screen and move cursor home*/ + if(ansi.data[0]==0) ansi.data[0]=2; + if(ansi.data[0]!=2) {/* only number 2 (the standard one supported) */ + LOG_DEBUG("ANSI: esc[%dJ called : not supported",ansi.data[0]); + break; + } + for(i=0;i<(Bitu)ansi.ncols*ansi.nrows;i++) INT10_TeletypeOutput(' ',ansi.attr,true,0); + ClearAnsi(); + INT10_SetCursorPos(0,0,0); + break; + case 'h': /* set MODE (if code =7 enable linewrap) */ + case 'I': /*RESET MODE */ + LOG_DEBUG("ANSI: set/reset mode called(not supported)"); + ClearAnsi(); + break; + case 'D': /*Cursor Backward */ + col=CURSOR_POS_COL(0) - (ansi.data[0]? ansi.data[0] : 1); + row=CURSOR_POS_ROW(0); + while(col<0) { + row--; + col = col + ansi.ncols ; // should depend on linebrake mode + } + INT10_SetCursorPos(row,col,0); + ClearAnsi(); + break; + case 'u': /* Restore Cursor Pos */ + INT10_SetCursorPos(ansi.saverow,ansi.savecol,0); + ClearAnsi(); + break; + case 's': /* SAVE CURSOR POS */ + ansi.savecol=CURSOR_POS_COL(0); + ansi.saverow=CURSOR_POS_ROW(0); + ClearAnsi(); + break; + case 'K':/* erase till end of line */ + case 'l':/* (if code =7) disable linewrap */ + case 'p':/* reassign keys (needs strings) */ + case 'i':/* printer stuff */ + default: + LOG_DEBUG("ANSI: unhandled char %c in esc[",data[count]); + ClearAnsi(); + break; + } + count++; } *size=count; return true; @@ -113,9 +347,23 @@ Bit16u device_CON::GetInformation(void) { return 0x8093; /* Key Available */ }; - device_CON::device_CON() { name="CON"; cache=0; + ansi.esc=false; + ansi.sci=false; + ansi.attr=0x7; + ansi.numberofarg=0; + for(Bit8u i=0; i Date: Wed, 11 Dec 2002 22:05:15 +0000 Subject: [PATCH 0491/4131] Updated to version 0.60 of fmopl by Jarek Burczynski Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@569 --- src/hardware/adlib.cpp | 43 +- src/hardware/fmopl.c | 1499 +++++++++++++++++++++++++++------------- src/hardware/fmopl.h | 196 ++---- 3 files changed, 1112 insertions(+), 626 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 8552a0ba..dc8bb48c 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -32,15 +32,30 @@ namespace MAME { /* Defines */ # define logerror(x) - /* Disable recurring warnings */ -#pragma warning ( disable : 4018 ) -#pragma warning ( disable : 4244 ) - /* Bring in Tatsuyuki Satoh's OPL emulation */ -#define HAS_YM3812 1 -#include "fmopl.c" + /* Disable recurring warnings */ +# pragma warning ( disable : 4018 ) +# pragma warning ( disable : 4244 ) + + /* Work around ANSI compliance problem (see driver.h) */ + struct __MALLOCPTR { + void* m_ptr; + + __MALLOCPTR(void) : m_ptr(NULL) { } + __MALLOCPTR(void* src) : m_ptr(src) { } + void* operator=(void* rhs) { return (m_ptr = rhs); } + operator int*() const { return (int*)m_ptr; } + operator int**() const { return (int**)m_ptr; } + operator char*() const { return (char*)m_ptr; } + }; + + /* Bring in the MAME OPL emulation */ +# define HAS_YM3812 1 +# include "fmopl.c" + } + struct OPLTimer_t { bool isEnabled; bool isMasked; @@ -50,9 +65,12 @@ struct OPLTimer_t { }; static OPLTimer_t timer1,timer2; -static MAME::FM_OPL * myopl; static Bit8u regsel; + #define OPL_INTERNAL_FREQ 3600000 // The OPL operates at 3.6MHz +#define OPL_NUM_CHIPS 1 // Number of OPL chips +#define OPL_CHIP0 0 + static MIXER_Channel * adlib_chan; static void ADLIB_CallBack(Bit8u *stream, Bit32u len) { @@ -60,7 +78,7 @@ static void ADLIB_CallBack(Bit8u *stream, Bit32u len) { /* Calculate teh machine ms we are at now */ /* update 1 ms of data */ - MAME::YM3812UpdateOne(myopl,(MAME::INT16 *)stream,len); + MAME::YM3812UpdateOne(0,(MAME::INT16 *)stream,len); } static Bit8u read_p388(Bit32u port) { @@ -120,9 +138,9 @@ static void write_p389(Bit32u port,Bit8u val) { } else timer2.isEnabled=false; return; default: /* Normal OPL call queue it */ - MAME::OPLWriteReg(myopl,regsel,val); + /* Use a little hack to directly write to the register */ + MAME::OPLWriteReg(MAME::OPL_YM3812[0],regsel,val); } - } static bool adlib_enabled; @@ -168,7 +186,10 @@ void ADLIB_Init(Section* sec) { timer2.isOverflowed=false; #define ADLIB_FREQ 22050 - myopl=MAME::OPLCreate(0,OPL_INTERNAL_FREQ,ADLIB_FREQ); + if (MAME::YM3812Init(OPL_NUM_CHIPS,OPL_INTERNAL_FREQ,ADLIB_FREQ)) { + E_Exit("Can't create adlib OPL Emulator"); + }; + adlib_chan=MIXER_AddChannel(ADLIB_CallBack,ADLIB_FREQ,"ADLIB"); MIXER_SetMode(adlib_chan,MIXER_16MONO); diff --git a/src/hardware/fmopl.c b/src/hardware/fmopl.c index 2f73d7db..ebc97920 100644 --- a/src/hardware/fmopl.c +++ b/src/hardware/fmopl.c @@ -4,17 +4,26 @@ ** types OPL and OPL2 ** ** Copyright (C) 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmulator development -** (c) 2002 Jarek Burczynski +** Copyright (C) 2002 Jarek Burczynski ** -** Version 0.58 +** Version 0.60 ** Revision History: +04-28-2002 Jarek Burczynski: + - binary exact Envelope Generator (verified on real YM3812); + compared to YM2151: the EG clock is equal to internal_clock, + rates are 2 times slower and volume resolution is one bit less + - modified interface functions (they no longer return pointer - + that's internal to the emulator now): + - new wrapper functions for OPLCreate: YM3526Init(), YM3812Init() and Y8950Init() + - corrected 'off by one' error in feedback calculations (when feedback is off) + - enabled waveform usage (credit goes to Vlad Romascanu and zazzal22) + - speeded up noise generator calculations (Nicola Salmoria) + 03-24-2002 Jarek Burczynski (thanks to Dox for the YM3812 chip) - Complete rewrite (all verified on real YM3812): - - corrected sin_tab and tl_tab data - corrected operator output calculations - corrected waveform_select_enable register; @@ -35,7 +44,6 @@ Revision History: - fixed subscription range of attack/decay tables - To do: add delay before key off in CSM mode (see CSMKeyControll) verify volume of the FM part on the Y8950 @@ -55,8 +63,6 @@ Revision History: - - /* output final shift */ #if (OPL_SAMPLE_BITS==16) #define FINAL_SH (0) @@ -70,20 +76,19 @@ Revision History: #define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */ -#define ENV_SH 16 /* 16.16 fixed point (envelope calculations) */ +#define EG_SH 16 /* 16.16 fixed point (EG timing) */ #define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */ #define TIMER_SH 16 /* 16.16 fixed point (timers calculations) */ #define FREQ_MASK ((1<>KSR */ + UINT8 mul; /* multiple: mul_tab[ML] */ + + /* Phase Generator */ + UINT32 Cnt; /* frequency counter */ + UINT32 Incr; /* frequency counter step */ + UINT8 FB; /* feedback shift value */ + INT32 *connect1; /* slot1 output pointer */ + INT32 op1_out[2]; /* slot1 output for feedback */ + UINT8 CON; /* connection (algorithm) type */ + + /* Envelope Generator */ + UINT8 eg_type; /* percussive/non-percussive mode */ + UINT8 state; /* phase type */ + UINT32 TL; /* total level: TL << 2 */ + INT32 TLL; /* adjusted now TL */ + INT32 volume; /* envelope counter */ + UINT32 sl; /* sustain level: sl_tab[SL] */ + + UINT8 eg_sh_ar; /* (attack state) */ + UINT8 eg_sel_ar; /* (attack state) */ + UINT8 eg_sh_dr; /* (decay state) */ + UINT8 eg_sel_dr; /* (decay state) */ + UINT8 eg_sh_rr; /* (release state) */ + UINT8 eg_sel_rr; /* (release state) */ + + UINT32 key; /* 0 = KEY OFF, >0 = KEY ON */ + + /* LFO */ + UINT32 AMmask; /* LFO Amplitude Modulation enable mask */ + UINT8 vib; /* LFO Phase Modulation enable flag (active high)*/ + + /* waveform select */ + unsigned int wavetable; +} OPL_SLOT; + +typedef struct{ + OPL_SLOT SLOT[2]; + /* phase generator state */ + UINT32 block_fnum; /* block+fnum */ + UINT32 fc; /* Freq. Increment base */ + UINT32 ksl_base; /* KeyScaleLevel Base step */ + UINT8 kcode; /* key code (for key scaling) */ +} OPL_CH; + +/* OPL state */ +typedef struct fm_opl_f { + /* FM channel slots */ + OPL_CH P_CH[9]; /* OPL/OPL2 chips have 9 channels*/ + + UINT32 eg_cnt; /* global envelope generator counter */ + UINT32 eg_timer; /* global envelope generator counter works at frequency = chipclock/72 */ + UINT32 eg_timer_add; /* step of eg_timer */ + UINT32 eg_timer_overflow; /* envelope generator timer overlfows every 1 sample (on real chip) */ + + UINT8 rhythm; /* Rhythm mode */ + + UINT32 fn_tab[1024]; /* fnumber->increment counter */ + + /* LFO */ + UINT8 lfo_am_depth; + UINT8 lfo_pm_depth_range; + UINT32 lfo_am_cnt; + UINT32 lfo_am_inc; + UINT32 lfo_pm_cnt; + UINT32 lfo_pm_inc; + + UINT32 noise_rng; /* 23 bit noise shift register */ + UINT32 noise_p; /* current noise 'phase' */ + UINT32 noise_f; /* current noise period */ + + UINT8 wavesel; /* waveform select enable flag */ + + int T[2]; /* timer counters */ + UINT8 st[2]; /* timer enable */ + +#if BUILD_Y8950 + /* Delta-T ADPCM unit (Y8950) */ + + YM_DELTAT *deltat; + + /* Keyboard / I/O interface unit*/ + UINT8 portDirection; + UINT8 portLatch; + OPL_PORTHANDLER_R porthandler_r; + OPL_PORTHANDLER_W porthandler_w; + int port_param; + OPL_PORTHANDLER_R keyboardhandler_r; + OPL_PORTHANDLER_W keyboardhandler_w; + int keyboard_param; +#endif + + /* external event callback handlers */ + OPL_TIMERHANDLER TimerHandler; /* TIMER handler */ + int TimerParam; /* TIMER parameter */ + OPL_IRQHANDLER IRQHandler; /* IRQ handler */ + int IRQParam; /* IRQ parameter */ + OPL_UPDATEHANDLER UpdateHandler;/* stream update handler */ + int UpdateParam; /* stream update parameter */ + + UINT8 type; /* chip type */ + UINT8 address; /* address register */ + UINT8 status; /* status flag */ + UINT8 statusmask; /* status mask */ + UINT8 mode; /* Reg.08 : CSM,notesel,etc. */ + + int clock; /* master clock (Hz) */ + int rate; /* sampling rate (Hz) */ + double freqbase; /* frequency base */ + double TimerBase; /* Timer base time (==sampling time)*/ +} FM_OPL; + + + /* mapping of register number (offset) to slot number used by the emulator */ static const int slot_array[32]= { @@ -149,8 +288,8 @@ static const int slot_array[32]= /* key scale level */ /* table is 3dB/octave , DV converts this into 6dB/octave */ -/* 0.09375 is bit 0 weight expressed in the 'decibel' scale */ -#define DV (0.09375/2.0) +/* 0.1875 is bit 0 weight of the envelope counter (volume) expressed in the 'decibel' scale */ +#define DV (0.1875/2.0) static const UINT32 ksl_tab[8*16]= { /* OCT 0 */ @@ -196,15 +335,123 @@ static const UINT32 ksl_tab[8*16]= }; #undef DV -/* sustain lebel table (3dB per step) */ +/* sustain level table (3dB per step) */ /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ -#define SC(db) (UINT32) ( db * (4.0/ENV_STEP) * (1<>3) +#define ENV_QUIET (TL_TAB_LEN>>4) /* sin waveform table in 'decibel' scale */ /* four waveforms on OPL2 type chips */ @@ -230,6 +477,7 @@ static unsigned int sin_tab[SIN_LEN * 4]; /* LFO Amplitude Modulation table (verified on real YM3812) + 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples Length: 210 elements. @@ -237,8 +485,8 @@ static unsigned int sin_tab[SIN_LEN * 4]; exactly 64 times (on 64 consecutive samples). The whole table takes: 64 * 210 = 13440 samples. - When AM = 1 data is multiplied by 2 - When AM = 0 data is divided by 4 and then multiplied by 2 (loosing precision is important) + When AM = 1 data is used directly + When AM = 0 data is divided by 4 before being used (loosing precision is important) */ #define LFO_AM_TAB_ELEMENTS 210 @@ -354,17 +602,6 @@ static INT32 LFO_PM; -/* log output level */ -#define LOG_ERR 3 /* ERROR */ -#define LOG_WAR 2 /* WARNING */ -#define LOG_INF 1 /* INFORMATION */ - -#define LOG_LEVEL LOG_INF - -#define LOG(n,x) if( (n)>=LOG_LEVEL ) logerror x - - - INLINE int limit( int val, int max, int min ) { if ( val > max ) val = max; @@ -375,7 +612,6 @@ INLINE int limit( int val, int max, int min ) { } - /* status set and IRQ handling */ INLINE void OPL_STATUS_SET(FM_OPL *OPL,int flag) { @@ -431,104 +667,119 @@ INLINE void advance_lfo(FM_OPL *OPL) tmp = lfo_am_table[ OPL->lfo_am_cnt >> LFO_SH ]; if (OPL->lfo_am_depth) - LFO_AM = (tmp) * 2; + LFO_AM = tmp; else - LFO_AM = (tmp>>2) * 2; + LFO_AM = tmp>>2; OPL->lfo_pm_cnt += OPL->lfo_pm_inc; - LFO_PM = ( (OPL->lfo_pm_cnt>>LFO_SH) & 7) | OPL->lfo_pm_depth_range; + LFO_PM = ((OPL->lfo_pm_cnt>>LFO_SH) & 7) | OPL->lfo_pm_depth_range; } /* advance to next sample */ INLINE void advance(FM_OPL *OPL) { OPL_CH *CH; - OPL_SLOT *SLOT; + OPL_SLOT *op; int i; + OPL->eg_timer += OPL->eg_timer_add; + + while (OPL->eg_timer >= OPL->eg_timer_overflow) + { + OPL->eg_timer -= OPL->eg_timer_overflow; + + OPL->eg_cnt++; + + for (i=0; i<9*2; i++) + { + CH = &OPL->P_CH[i/2]; + op = &CH->SLOT[i&1]; + + /* Envelope Generator */ + switch(op->state) + { + case EG_ATT: /* attack phase */ + { + + if ( !(OPL->eg_cnt & ((1<eg_sh_ar)-1) ) ) + { + op->volume += (~op->volume * + (eg_inc[op->eg_sel_ar + ((OPL->eg_cnt>>op->eg_sh_ar)&7)]) + ) >>3; + + if (op->volume <= MIN_ATT_INDEX) + { + op->volume = MIN_ATT_INDEX; + op->state = EG_DEC; + } + + } + + } + break; + + case EG_DEC: /* decay phase */ + if ( !(OPL->eg_cnt & ((1<eg_sh_dr)-1) ) ) + { + op->volume += eg_inc[op->eg_sel_dr + ((OPL->eg_cnt>>op->eg_sh_dr)&7)]; + + if ( op->volume >= op->sl ) + op->state = EG_SUS; + + } + break; + + case EG_SUS: /* sustain phase */ + + /* this is important behaviour: + one can change percusive/non-percussive modes on the fly and + the chip will remain in sustain phase - verified on real YM3812 */ + + if(op->eg_type) /* non-percussive mode */ + { + /* do nothing */ + } + else /* percussive mode */ + { + /* during sustain phase chip adds Release Rate (in percussive mode) */ + if ( !(OPL->eg_cnt & ((1<eg_sh_rr)-1) ) ) + { + op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt>>op->eg_sh_rr)&7)]; + + if ( op->volume >= MAX_ATT_INDEX ) + op->volume = MAX_ATT_INDEX; + } + /* else do nothing in sustain phase */ + } + break; + + case EG_REL: /* release phase */ + if ( !(OPL->eg_cnt & ((1<eg_sh_rr)-1) ) ) + { + op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt>>op->eg_sh_rr)&7)]; + + if ( op->volume >= MAX_ATT_INDEX ) + { + op->volume = MAX_ATT_INDEX; + op->state = EG_OFF; + } + + } + break; + + default: + break; + } + } + } for (i=0; i<9*2; i++) { - CH = &OPL->P_CH[i/2]; - SLOT = &CH->SLOT[i&1]; - - /* Envelope Generator */ - switch(SLOT->state) - { - case EG_ATT: /* attack phase */ - { - INT32 step = SLOT->volume; - - SLOT->volume -= SLOT->delta_ar; - step = (step>>ENV_SH) - (((UINT32)SLOT->volume)>>ENV_SH); /* number of levels passed since last time */ - if (step > 0) - { - INT32 tmp_volume = SLOT->volume + (step<>4) & ~ENV_MASK); - if (tmp_volume <= MIN_ATT_INDEX) - break; - step--; - }while(step); - SLOT->volume = tmp_volume; - } - - if (SLOT->volume <= MIN_ATT_INDEX) - { - if (SLOT->volume < 0) - SLOT->volume = 0; /* this is not quite correct (checked) */ - - SLOT->state = EG_DEC; - } - } - break; - - case EG_DEC: /* decay phase */ - - if ( (SLOT->volume += SLOT->delta_dr) >= SLOT->sl ) - { - SLOT->volume = SLOT->sl; /* this is not quite correct (checked) */ - SLOT->state = EG_SUS; - } - break; - - case EG_SUS: /* sustain phase */ - - /* this is important behaviour: - one can change percusive/non-percussive modes on the fly and - the chip will remain in sustain phase - verified on real YM3812 */ - - if(SLOT->eg_type) /* non-percussive mode */ - { - /* do nothing */ - } - else /* percussive mode */ - { - /* during sustain phase chip adds Release Rate (in percussive mode) */ - - if ( (SLOT->volume += SLOT->delta_rr) > MAX_ATT_INDEX ) - { - SLOT->volume = MAX_ATT_INDEX; - } - /* else do nothing in sustain phase */ - } - break; - - case EG_REL: /* release phase */ - if ( (SLOT->volume += SLOT->delta_rr) > MAX_ATT_INDEX ) - { - SLOT->volume = MAX_ATT_INDEX; - SLOT->state = EG_OFF; - } - break; - - default: - break; - } + CH = &OPL->P_CH[i/2]; + op = &CH->SLOT[i&1]; /* Phase Generator */ - if(SLOT->vib) + if(op->vib) { UINT8 block; unsigned int block_fnum = CH->block_fnum; @@ -541,16 +792,16 @@ INLINE void advance(FM_OPL *OPL) { block_fnum += lfo_fn_table_index_offset; block = (block_fnum&0x1c00) >> 10; - SLOT->Cnt += (OPL->fn_tab[block_fnum&0x03ff] >> (7-block)) * SLOT->mul;//ok + op->Cnt += (OPL->fn_tab[block_fnum&0x03ff] >> (7-block)) * op->mul;//ok } else /* LFO phase modulation = zero */ { - SLOT->Cnt += SLOT->Incr; + op->Cnt += op->Incr; } } else /* LFO phase modulation disabled for this operator */ { - SLOT->Cnt += SLOT->Incr; + op->Cnt += op->Incr; } } @@ -570,26 +821,40 @@ INLINE void advance(FM_OPL *OPL) OPL->noise_p &= FREQ_MASK; while (i) { + /* UINT32 j; j = ( (OPL->noise_rng) ^ (OPL->noise_rng>>14) ^ (OPL->noise_rng>>15) ^ (OPL->noise_rng>>22) ) & 1; OPL->noise_rng = (j<<22) | (OPL->noise_rng>>1); + */ + + /* + Instead of doing all the logic operations above, we + use a trick here (and use bit 0 as the noise output). + The difference is only that the noise bit changes one + step ahead. This doesn't matter since we don't know + what is real state of the noise_rng after the reset. + */ + + if (OPL->noise_rng & 1) OPL->noise_rng ^= 0x800302; + OPL->noise_rng >>= 1; + i--; } } -INLINE signed int op_calc(UINT32 phase, unsigned int env, signed int pm) +INLINE signed int op_calc(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab) { UINT32 p; - p = (env<<3) + sin_tab[ ( ((signed int)((phase & ~FREQ_MASK) + (pm<<16))) >> FREQ_SH ) & SIN_MASK ]; + p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + (pm<<16))) >> FREQ_SH ) & SIN_MASK) ]; if (p >= TL_TAB_LEN) return 0; return tl_tab[p]; } -INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm) +INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab) { UINT32 p; INT32 i; @@ -598,7 +863,7 @@ INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm) /*logerror("i=%08x (i>>16)&511=%8i phase=%i [pm=%08x] ",i, (i>>16)&511, phase>>FREQ_SH, pm);*/ - p = (env<<3) + sin_tab[ (i>>FREQ_SH) & SIN_MASK]; + p = (env<<4) + sin_tab[ wave_tab + ((i>>FREQ_SH) & SIN_MASK)]; /*logerror("(p&255=%i p>>8=%i) out= %i\n", p&255,p>>8, tl_tab[p&255]>>(p>>8) );*/ @@ -608,7 +873,7 @@ INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm) } -#define volume_calc(OP) ((OP)->TLL + (((UINT32)(OP)->volume)>>ENV_SH) + (LFO_AM & (OP)->AMmask)) +#define volume_calc(OP) ((OP)->TLL + ((UINT32)(OP)->volume) + (LFO_AM & (OP)->AMmask)) /* calculate output */ INLINE void OPL_CALC_CH( OPL_CH *CH ) @@ -622,18 +887,22 @@ INLINE void OPL_CALC_CH( OPL_CH *CH ) /* SLOT 1 */ SLOT = &CH->SLOT[SLOT1]; env = volume_calc(SLOT); - out = CH->op1_out[0] + CH->op1_out[1]; - CH->op1_out[0] = CH->op1_out[1]; - *CH->connect1 += CH->op1_out[0]; - CH->op1_out[1] = 0; + out = SLOT->op1_out[0] + SLOT->op1_out[1]; + SLOT->op1_out[0] = SLOT->op1_out[1]; + *SLOT->connect1 += SLOT->op1_out[0]; + SLOT->op1_out[1] = 0; if( env < ENV_QUIET ) - CH->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB) ); + { + if (!SLOT->FB) + out = 0; + SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB), SLOT->wavetable ); + } /* SLOT 2 */ SLOT++; env = volume_calc(SLOT); if( env < ENV_QUIET ) - output[0] += op_calc(SLOT->Cnt, env, phase_modulation); + output[0] += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable); } /* @@ -691,23 +960,27 @@ INLINE void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) /* SLOT 1 */ SLOT = &CH[6].SLOT[SLOT1]; env = volume_calc(SLOT); + + out = SLOT->op1_out[0] + SLOT->op1_out[1]; + SLOT->op1_out[0] = SLOT->op1_out[1]; + + if (!SLOT->CON) + phase_modulation = SLOT->op1_out[0]; + //else ignore output of operator 1 + + SLOT->op1_out[1] = 0; + if( env < ENV_QUIET ) { - out = CH[6].op1_out[0] + CH[6].op1_out[1]; - CH[6].op1_out[0] = CH[6].op1_out[1]; - - if (!CH[6].CON) - phase_modulation = CH[6].op1_out[0]; - //else ignore output of operator 1 - - CH[6].op1_out[1] = 0; - if( env < ENV_QUIET ) - CH[6].op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB) + out = 0; + SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB), SLOT->wavetable ); } + /* SLOT 2 */ SLOT++; env = volume_calc(SLOT); if( env < ENV_QUIET ) - output[0] += op_calc(SLOT->Cnt, env, phase_modulation) * 2; + output[0] += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable) * 2; /* Phase generation is based on: */ @@ -775,7 +1048,7 @@ INLINE void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) phase = 0xd0>>2; } - output[0] += op_calc(phase<wavetable) * 2; } /* Snare Drum (verified on real YM3812) */ @@ -796,13 +1069,13 @@ INLINE void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) if (noise) phase ^= 0x100; - output[0] += op_calc(phase<wavetable) * 2; } /* Tom Tom (verified on real YM3812) */ env = volume_calc(SLOT8_1); if( env < ENV_QUIET ) - output[0] += op_calc(SLOT8_1->Cnt, env, 0) * 2; + output[0] += op_calc(SLOT8_1->Cnt, env, 0, SLOT->wavetable) * 2; /* Top Cymbal (verified on real YM3812) */ env = volume_calc(SLOT8_2); @@ -829,69 +1102,11 @@ INLINE void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) if (res2) phase = 0x300; - output[0] += op_calc(phase<wavetable) * 2; } } -/* initialize time tables */ -static void init_timetables( FM_OPL *OPL ) -{ - int i; - double rate; - - /* make attack rate & decay rate tables */ - for (i = 0;i < 16+4;i++) - OPL->eg_tab[i] = 0; - - for (i = 4;i < 64;i++) - { - rate = OPL->freqbase; /* frequency rate */ - if( i < 60 ) rate *= 1.0+(i&3)*0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */ - rate *= 1 << (i>>2); /* b2-5 : shift bit */ - rate /= /*576*/ 8 * 1024.0; - rate *= (double)(1<eg_tab[16+i] = rate; -#if 0 - logerror("FMOPL.C: Rate %2i %1i Decay [real %11.4f ms][emul %11.4f ms][d=%08x]\n",i>>2, i&3, - ( ((double)(ENV_LEN<rate), - ( ((double)(ENV_LEN<eg_tab[16+i]) * (1000.0 / (double)OPL->rate), OPL->eg_tab[16+i] ); -#endif - } - - for (i = 0; i < 16; i++) - { - OPL->eg_tab[16+64+i] = OPL->eg_tab[16+63]; - } - -#if 0 - for (i = 4; i < 64 ; i++) /* test */ - { - UINT32 vol = 0; - UINT32 vol_step = OPL->eg_tab[16+i]; - int j=0, change_no=0; - int lastchange=-1; - - logerror("FMOPL.C - EG TEST: Rate %2i %1i [d=%08x]\n",i>>2, i&3, vol_step ); - logerror(" -> changes every samples: "); - - while (change_no<16) - { - UINT32 tmp_vol = vol>>ENV_SH; - vol += vol_step; - if (tmp_vol!=(vol>>ENV_SH)) - { - //display the distance (in number of samples) since last level change - logerror("%i ",j-lastchange); - lastchange = j; - change_no++; - } - j++; - } - logerror("\n"); - } -#endif -} /* generic table initialize */ static int init_tables(void) @@ -926,9 +1141,9 @@ static int init_tables(void) tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = -tl_tab[ x*2+0 + i*2*TL_RES_LEN ]; } #if 0 - logerror("tl %04i", x); + logerror("tl %04i", x*2); for (i=0; i<12; i++) - logerror(", [%02i] %4i", i*2, tl_tab[ x*2 /*+1*/ + i*2*TL_RES_LEN ] ); + logerror(", [%02i] %5i", i*2, tl_tab[ x*2 /*+1*/ + i*2*TL_RES_LEN ] ); logerror("\n"); #endif } @@ -962,19 +1177,25 @@ static int init_tables(void) for (i=0; i>1) ]; - /* waveform 3: /- /- /- /- */ + /* waveform 3: _ _ _ _ */ + /* / |_/ |_/ |_/ |_*/ /* abs(output only first quarter of the sinus waveform) */ + if (i & (1<<(SIN_BITS-2)) ) sin_tab[3*SIN_LEN+i] = TL_TAB_LEN; else @@ -1018,9 +1239,6 @@ static void OPL_initalize(FM_OPL *OPL) /* Timer base time */ OPL->TimerBase = 1.0 / ((double)OPL->clock / 72.0 ); - /* make time tables */ - init_timetables( OPL ); - /* make fnumber -> increment counter table */ for( i=0 ; i < 1024 ; i++ ) { @@ -1051,8 +1269,8 @@ static void OPL_initalize(FM_OPL *OPL) #endif - /* Amplitude modulation: 26 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */ - /* In our LFO_AM_TABLE one entry lasts for 64 samples */ + /* Amplitude modulation: 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */ + /* One entry from LFO_AM_TABLE lasts for 64 samples */ OPL->lfo_am_inc = (1.0 / 64.0 ) * (1<freqbase; /* Vibrato: 8 output levels (triangle waveform); 1 level takes 1024 samples */ @@ -1062,6 +1280,11 @@ static void OPL_initalize(FM_OPL *OPL) /* Noise generator: a step takes 1 sample */ OPL->noise_f = (1.0 / 1.0) * (1<freqbase; + + OPL->eg_timer_add = (1<freqbase; + OPL->eg_timer_overflow = ( 1 ) * (1<eg_timer_add, OPL->eg_timer_overflow);*/ + } INLINE void FM_KEYON(OPL_SLOT *SLOT, UINT32 key_set) @@ -1105,12 +1328,20 @@ INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT) SLOT->ksr = ksr; /* calculate envelope generator rates */ - if ((SLOT->ARval + SLOT->ksr) < 16+60) - SLOT->delta_ar = SLOT->AR[ SLOT->ksr ]; + if ((SLOT->ar + SLOT->ksr) < 16+62) + { + SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; + SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; + } else - SLOT->delta_ar = MAX_ATT_INDEX+1; - SLOT->delta_dr = SLOT->DR[ SLOT->ksr ]; - SLOT->delta_rr = SLOT->RR[ SLOT->ksr ]; + { + SLOT->eg_sh_ar = 0; + SLOT->eg_sel_ar = 13*RATE_STEPS; + } + SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; + SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; + SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; + SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; } } @@ -1136,7 +1367,7 @@ INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v) int ksl = v>>6; /* 0 / 1.5 / 3.0 / 6.0 dB/OCT */ SLOT->ksl = ksl ? 3-ksl : 31; - SLOT->TL = (v&0x3f)<<(ENV_BITS-7); /* 7 bits TL (bit 6 = always 0) */ + SLOT->TL = (v&0x3f)<<(ENV_BITS-1-7); /* 7 bits TL (bit 6 = always 0) */ SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); } @@ -1146,17 +1377,23 @@ INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v) { OPL_CH *CH = &OPL->P_CH[slot/2]; OPL_SLOT *SLOT = &CH->SLOT[slot&1]; - int DRval = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; - SLOT->ARval = (v>>4) ? 16 + ((v>>4) <<2) : 0; - SLOT->AR = &OPL->eg_tab[ SLOT->ARval ]; + SLOT->ar = (v>>4) ? 16 + ((v>>4) <<2) : 0; - if ((SLOT->ARval + SLOT->ksr) < 16+60) - SLOT->delta_ar = SLOT->AR[ SLOT->ksr ]; + if ((SLOT->ar + SLOT->ksr) < 16+62) + { + SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; + SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; + } else - SLOT->delta_ar = MAX_ATT_INDEX+1; - SLOT->DR = &OPL->eg_tab[DRval]; - SLOT->delta_dr = SLOT->DR[ SLOT->ksr ]; + { + SLOT->eg_sh_ar = 0; + SLOT->eg_sel_ar = 13*RATE_STEPS; + } + + SLOT->dr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; + SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; + SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; } /* set sustain level & release rate */ @@ -1164,12 +1401,12 @@ INLINE void set_sl_rr(FM_OPL *OPL,int slot,int v) { OPL_CH *CH = &OPL->P_CH[slot/2]; OPL_SLOT *SLOT = &CH->SLOT[slot&1]; - int RRval = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; SLOT->sl = sl_tab[ v>>4 ]; - SLOT->RR = &OPL->eg_tab[RRval]; - SLOT->delta_rr = SLOT->RR[ SLOT->ksr ]; + SLOT->rr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; + SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; + SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; } @@ -1247,7 +1484,7 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v) if(OPL->keyboardhandler_w) OPL->keyboardhandler_w(OPL->keyboard_param,v); else - LOG(LOG_WAR,("OPL:write unmapped KEYBOARD port\n")); + logerror("OPL:write unmapped KEYBOARD port\n"); } break; case 0x07: /* DELTA-T controll : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */ @@ -1295,22 +1532,22 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v) break; case 0x20: /* am ON, vib ON, ksr, eg_type, mul */ slot = slot_array[r&0x1f]; - if(slot == -1) return; + if(slot < 0) return; set_mul(OPL,slot,v); break; case 0x40: slot = slot_array[r&0x1f]; - if(slot == -1) return; + if(slot < 0) return; set_ksl_tl(OPL,slot,v); break; case 0x60: slot = slot_array[r&0x1f]; - if(slot == -1) return; + if(slot < 0) return; set_ar_dr(OPL,slot,v); break; case 0x80: slot = slot_array[r&0x1f]; - if(slot == -1) return; + if(slot < 0) return; set_sl_rr(OPL,slot,v); break; case 0xa0: @@ -1402,7 +1639,7 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v) /* if notesel == 0 -> lsb of kcode is bit 10 (MSB) of fnum */ /* if notesel == 1 -> lsb of kcode is bit 9 (MSB-1) of fnum */ if (OPL->mode&0x40) - CH->kcode |= (CH->block_fnum&0x100)>>8; /* notesel == 1 */ + CH->kcode |= (CH->block_fnum&0x100)>>8; /* notesel == 1 */ else CH->kcode |= (CH->block_fnum&0x200)>>9; /* notesel == 0 */ @@ -1419,19 +1656,19 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v) /* FB,C */ if( (r&0x0f) > 8) return; CH = &OPL->P_CH[r&0x0f]; - CH->FB = (v>>1)&7 ? ((v>>1)&7) + 7 : 0; - CH->CON = v&1; - CH->connect1 = CH->CON ? &output[0] : &phase_modulation; + CH->SLOT[SLOT1].FB = (v>>1)&7 ? ((v>>1)&7) + 7 : 0; + CH->SLOT[SLOT1].CON = v&1; + CH->SLOT[SLOT1].connect1 = CH->SLOT[SLOT1].CON ? &output[0] : &phase_modulation; break; case 0xe0: /* waveform select */ /* simply ignore write to the waveform select register if selecting not enabled in test register */ if(OPL->wavesel) { slot = slot_array[r&0x1f]; - if(slot == -1) return; + if(slot < 0) return; CH = &OPL->P_CH[slot/2]; - CH->SLOT[slot&1].wavetable = &sin_tab[(v&0x03)*SIN_LEN]; + CH->SLOT[slot&1].wavetable = (v&0x03)*SIN_LEN; } break; } @@ -1491,22 +1728,310 @@ static void OPL_UnLockTable(void) } -#if (BUILD_YM3812 || BUILD_YM3526) -/*******************************************************************************/ -/* YM3812 local section */ -/*******************************************************************************/ +static void OPLResetChip(FM_OPL *OPL) +{ + int c,s; + int i; -/* Generate samples for one of the YM3812's -* -* '*OPL' is pointer to the virtual YM3812 -* '*buffer' is pointer to the sample buffer -* 'length' is the number of samples that should be generated -*/ -void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length) + OPL->eg_timer = 0; + OPL->eg_cnt = 0; + + OPL->noise_rng = 1; /* noise shift register */ + OPL->mode = 0; /* normal mode */ + OPL_STATUS_RESET(OPL,0x7f); + + /* reset with register write */ + OPLWriteReg(OPL,0x01,0); /* wavesel disable */ + OPLWriteReg(OPL,0x02,0); /* Timer1 */ + OPLWriteReg(OPL,0x03,0); /* Timer2 */ + OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */ + for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0); + + /* reset operator parameters */ + for( c = 0 ; c < 9 ; c++ ) + { + OPL_CH *CH = &OPL->P_CH[c]; + for(s = 0 ; s < 2 ; s++ ) + { + /* wave table */ + CH->SLOT[s].wavetable = 0; + CH->SLOT[s].state = EG_OFF; + CH->SLOT[s].volume = MAX_ATT_INDEX; + } + } +#if BUILD_Y8950 + if(OPL->type&OPL_TYPE_ADPCM) + { + YM_DELTAT *DELTAT = OPL->deltat; + + DELTAT->freqbase = OPL->freqbase; + DELTAT->output_pointer = &output_deltat[0]; + DELTAT->portshift = 5; + DELTAT->output_range = 1<<23; + YM_DELTAT_ADPCM_Reset(DELTAT,0); + } +#endif +} + +/* Create one of virtual YM3812 */ +/* 'clock' is chip clock in Hz */ +/* 'rate' is sampling rate */ +static FM_OPL *OPLCreate(int type, int clock, int rate) +{ + char *ptr; + FM_OPL *OPL; + int state_size; + + if (OPL_LockTable() ==-1) return NULL; + + /* calculate OPL state size */ + state_size = sizeof(FM_OPL); + +#if BUILD_Y8950 + if (type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT); +#endif + + /* allocate memory block */ + ptr = (char *)malloc(state_size); + + if (ptr==NULL) + return NULL; + + /* clear */ + memset(ptr,0,state_size); + + OPL = (FM_OPL *)ptr; + + ptr += sizeof(FM_OPL); + +#if BUILD_Y8950 + if (type&OPL_TYPE_ADPCM) + OPL->deltat = (YM_DELTAT *)ptr; + ptr += sizeof(YM_DELTAT); +#endif + + OPL->type = type; + OPL->clock = clock; + OPL->rate = rate; + + /* init global tables */ + OPL_initalize(OPL); + + /* reset chip */ + OPLResetChip(OPL); + return OPL; +} + +/* Destroy one of virtual YM3812 */ +static void OPLDestroy(FM_OPL *OPL) +{ + OPL_UnLockTable(); + free(OPL); +} + +/* Option handlers */ + +static void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset) +{ + OPL->TimerHandler = TimerHandler; + OPL->TimerParam = channelOffset; +} +static void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param) +{ + OPL->IRQHandler = IRQHandler; + OPL->IRQParam = param; +} +static void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param) +{ + OPL->UpdateHandler = UpdateHandler; + OPL->UpdateParam = param; +} + +/* YM3812 I/O interface */ +static int OPLWrite(FM_OPL *OPL,int a,int v) +{ + if( !(a&1) ) + { /* address port */ + OPL->address = v & 0xff; + } + else + { /* data port */ + if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); + OPLWriteReg(OPL,OPL->address,v); + } + return OPL->status>>7; +} + +static unsigned char OPLRead(FM_OPL *OPL,int a) +{ + if( !(a&1) ) + { + /* status port */ + return OPL->status & (OPL->statusmask|0x80); + } + +#if BUILD_Y8950 + /* data port */ + switch(OPL->address) + { + case 0x05: /* KeyBoard IN */ + if(OPL->type&OPL_TYPE_KEYBOARD) + { + if(OPL->keyboardhandler_r) + return OPL->keyboardhandler_r(OPL->keyboard_param); + else + logerror("OPL:read unmapped KEYBOARD port\n"); + } + return 0; +#if 0 + case 0x0f: /* ADPCM-DATA */ + return 0; +#endif + case 0x19: /* I/O DATA */ + if(OPL->type&OPL_TYPE_IO) + { + if(OPL->porthandler_r) + return OPL->porthandler_r(OPL->port_param); + else + logerror("OPL:read unmapped I/O port\n"); + } + return 0; + case 0x1a: /* PCM-DATA */ + return 0; + } +#endif + + return 0xff; +} + +/* CSM Key Controll */ +INLINE void CSMKeyControll(OPL_CH *CH) +{ + FM_KEYON (&CH->SLOT[SLOT1], 4); + FM_KEYON (&CH->SLOT[SLOT2], 4); + + /* The key off should happen exactly one sample later - not implemented correctly yet */ + + FM_KEYOFF(&CH->SLOT[SLOT1], ~4); + FM_KEYOFF(&CH->SLOT[SLOT2], ~4); +} + + +static int OPLTimerOver(FM_OPL *OPL,int c) +{ + if( c ) + { /* Timer B */ + OPL_STATUS_SET(OPL,0x20); + } + else + { /* Timer A */ + OPL_STATUS_SET(OPL,0x40); + /* CSM mode key,TL controll */ + if( OPL->mode & 0x80 ) + { /* CSM mode total level latch and auto key on */ + int ch; + if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); + for(ch=0; ch<9; ch++) + CSMKeyControll( &OPL->P_CH[ch] ); + } + } + /* reload timer */ + if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase); + return OPL->status>>7; +} + + +#define MAX_OPL_CHIPS 2 + + +#if (BUILD_YM3812) + +static FM_OPL *OPL_YM3812[MAX_OPL_CHIPS]; /* array of pointers to the YM3812's */ +static int YM3812NumChips = 0; /* number of chips */ + +int YM3812Init(int num, int clock, int rate) { int i; - OPLSAMPLE *buf = buffer; - UINT8 rhythm = OPL->rhythm&0x20; + + if (YM3812NumChips) + return -1; /* duplicate init. */ + + YM3812NumChips = num; + + for (i = 0;i < YM3812NumChips; i++) + { + /* emulator create */ + OPL_YM3812[i] = OPLCreate(OPL_TYPE_YM3812,clock,rate); + if(OPL_YM3812[i] == NULL) + { + /* it's really bad - we run out of memeory */ + YM3812NumChips = 0; + return -1; + } + } + + return 0; +} + +void YM3812Shutdown(void) +{ + int i; + + for (i = 0;i < YM3812NumChips; i++) + { + /* emulator shutdown */ + OPLDestroy(OPL_YM3812[i]); + OPL_YM3812[i] = NULL; + } + YM3812NumChips = 0; +} +void YM3812ResetChip(int which) +{ + OPLResetChip(OPL_YM3812[which]); +} + +int YM3812Write(int which, int a, int v) +{ + return OPLWrite(OPL_YM3812[which], a, v); +} + +unsigned char YM3812Read(int which, int a) +{ + /* YM3812 always returns bit2 and bit1 in HIGH state */ + return OPLRead(OPL_YM3812[which], a) | 0x06 ; +} +int YM3812TimerOver(int which, int c) +{ + return OPLTimerOver(OPL_YM3812[which], c); +} + +void YM3812SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset) +{ + OPLSetTimerHandler(OPL_YM3812[which], TimerHandler, channelOffset); +} +void YM3812SetIRQHandler(int which,OPL_IRQHANDLER IRQHandler,int param) +{ + OPLSetIRQHandler(OPL_YM3812[which], IRQHandler, param); +} +void YM3812SetUpdateHandler(int which,OPL_UPDATEHANDLER UpdateHandler,int param) +{ + OPLSetUpdateHandler(OPL_YM3812[which], UpdateHandler, param); +} + + +/* +** Generate samples for one of the YM3812's +** +** 'which' is the virtual YM3812 number +** '*buffer' is the output buffer pointer +** 'length' is the number of samples that should be generated +*/ +void YM3812UpdateOne(int which, INT16 *buffer, int length) +{ + FM_OPL *OPL = OPL_YM3812[which]; + UINT8 rhythm = OPL->rhythm&0x20; + OPLSAMPLE *buf = buffer; + int i; if( (void *)OPL != cur_chip ){ cur_chip = (void *)OPL; @@ -1540,7 +2065,7 @@ void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length) } else /* Rhythm part */ { - OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>22)&1 ); + OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>0)&1 ); } lt = output[0]; @@ -1558,20 +2083,253 @@ void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length) buf[i] = lt; advance(OPL); - } } -#endif /* (BUILD_YM3812 || BUILD_YM3526) */ +#endif /* BUILD_YM3812 */ + + + +#if (BUILD_YM3526) + +static FM_OPL *OPL_YM3526[MAX_OPL_CHIPS]; /* array of pointers to the YM3526's */ +static int YM3526NumChips = 0; /* number of chips */ + +int YM3526Init(int num, int clock, int rate) +{ + int i; + + if (YM3526NumChips) + return -1; /* duplicate init. */ + + YM3526NumChips = num; + + for (i = 0;i < YM3526NumChips; i++) + { + /* emulator create */ + OPL_YM3526[i] = OPLCreate(OPL_TYPE_YM3526,clock,rate); + if(OPL_YM3526[i] == NULL) + { + /* it's really bad - we run out of memeory */ + YM3526NumChips = 0; + return -1; + } + } + + return 0; +} + +void YM3526Shutdown(void) +{ + int i; + + for (i = 0;i < YM3526NumChips; i++) + { + /* emulator shutdown */ + OPLDestroy(OPL_YM3526[i]); + OPL_YM3526[i] = NULL; + } + YM3526NumChips = 0; +} +void YM3526ResetChip(int which) +{ + OPLResetChip(OPL_YM3526[which]); +} + +int YM3526Write(int which, int a, int v) +{ + return OPLWrite(OPL_YM3526[which], a, v); +} + +unsigned char YM3526Read(int which, int a) +{ + return OPLRead(OPL_YM3526[which], a); +} +int YM3526TimerOver(int which, int c) +{ + return OPLTimerOver(OPL_YM3526[which], c); +} + +void YM3526SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset) +{ + OPLSetTimerHandler(OPL_YM3526[which], TimerHandler, channelOffset); +} +void YM3526SetIRQHandler(int which,OPL_IRQHANDLER IRQHandler,int param) +{ + OPLSetIRQHandler(OPL_YM3526[which], IRQHandler, param); +} +void YM3526SetUpdateHandler(int which,OPL_UPDATEHANDLER UpdateHandler,int param) +{ + OPLSetUpdateHandler(OPL_YM3526[which], UpdateHandler, param); +} + + +/* +** Generate samples for one of the YM3526's +** +** 'which' is the virtual YM3526 number +** '*buffer' is the output buffer pointer +** 'length' is the number of samples that should be generated +*/ +void YM3526UpdateOne(int which, INT16 *buffer, int length) +{ + FM_OPL *OPL = OPL_YM3526[which]; + UINT8 rhythm = OPL->rhythm&0x20; + OPLSAMPLE *buf = buffer; + int i; + + if( (void *)OPL != cur_chip ){ + cur_chip = (void *)OPL; + /* rhythm slots */ + SLOT7_1 = &OPL->P_CH[7].SLOT[SLOT1]; + SLOT7_2 = &OPL->P_CH[7].SLOT[SLOT2]; + SLOT8_1 = &OPL->P_CH[8].SLOT[SLOT1]; + SLOT8_2 = &OPL->P_CH[8].SLOT[SLOT2]; + } + for( i=0; i < length ; i++ ) + { + int lt; + + output[0] = 0; + + advance_lfo(OPL); + + /* FM part */ + OPL_CALC_CH(&OPL->P_CH[0]); + OPL_CALC_CH(&OPL->P_CH[1]); + OPL_CALC_CH(&OPL->P_CH[2]); + OPL_CALC_CH(&OPL->P_CH[3]); + OPL_CALC_CH(&OPL->P_CH[4]); + OPL_CALC_CH(&OPL->P_CH[5]); + + if(!rhythm) + { + OPL_CALC_CH(&OPL->P_CH[6]); + OPL_CALC_CH(&OPL->P_CH[7]); + OPL_CALC_CH(&OPL->P_CH[8]); + } + else /* Rhythm part */ + { + OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>0)&1 ); + } + + lt = output[0]; + + lt >>= FINAL_SH; + + /* limit check */ + lt = limit( lt , MAXOUT, MINOUT ); + + #ifdef SAVE_SAMPLE + SAVE_ALL_CHANNELS + #endif + + /* store to sound buffer */ + buf[i] = lt; + + advance(OPL); + } + +} +#endif /* BUILD_YM3526 */ + + + #if BUILD_Y8950 -void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length) +static FM_OPL *OPL_Y8950[MAX_OPL_CHIPS]; /* array of pointers to the Y8950's */ +static int Y8950NumChips = 0; /* number of chips */ + +int Y8950Init(int num, int clock, int rate) { int i; - OPLSAMPLE *buf = buffer; - UINT8 rhythm = OPL->rhythm&0x20; - YM_DELTAT *DELTAT = OPL->deltat; + + if (Y8950NumChips) + return -1; /* duplicate init. */ + + Y8950NumChips = num; + + for (i = 0;i < Y8950NumChips; i++) + { + /* emulator create */ + OPL_Y8950[i] = OPLCreate(OPL_TYPE_Y8950,clock,rate); + if(OPL_Y8950[i] == NULL) + { + /* it's really bad - we run out of memeory */ + Y8950NumChips = 0; + return -1; + } + } + + return 0; +} + +void Y8950Shutdown(void) +{ + int i; + + for (i = 0;i < Y8950NumChips; i++) + { + /* emulator shutdown */ + OPLDestroy(OPL_Y8950[i]); + OPL_Y8950[i] = NULL; + } + Y8950NumChips = 0; +} +void Y8950ResetChip(int which) +{ + OPLResetChip(OPL_Y8950[which]); +} + +int Y8950Write(int which, int a, int v) +{ + return OPLWrite(OPL_Y8950[which], a, v); +} + +unsigned char Y8950Read(int which, int a) +{ + return OPLRead(OPL_Y8950[which], a); +} +int Y8950TimerOver(int which, int c) +{ + return OPLTimerOver(OPL_Y8950[which], c); +} + +void Y8950SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset) +{ + OPLSetTimerHandler(OPL_Y8950[which], TimerHandler, channelOffset); +} +void Y8950SetIRQHandler(int which,OPL_IRQHANDLER IRQHandler,int param) +{ + OPLSetIRQHandler(OPL_Y8950[which], IRQHandler, param); +} +void Y8950SetUpdateHandler(int which,OPL_UPDATEHANDLER UpdateHandler,int param) +{ + OPLSetUpdateHandler(OPL_Y8950[which], UpdateHandler, param); +} + +void Y8950SetDeltaTMemory(int which, void * deltat_rom, int deltat_rom_size ) +{ + FM_OPL *OPL = OPL_Y8950[which]; + OPL->deltat->memory = (UINT8 *)(deltat_rom); + OPL->deltat->memory_size = deltat_rom_size; +} + +/* +** Generate samples for one of the Y8950's +** +** 'which' is the virtual Y8950 number +** '*buffer' is the output buffer pointer +** 'length' is the number of samples that should be generated +*/ +void Y8950UpdateOne(int which, INT16 *buffer, int length) +{ + int i; + FM_OPL *OPL = OPL_Y8950[which]; + UINT8 rhythm = OPL->rhythm&0x20; + YM_DELTAT *DELTAT = OPL->deltat; + OPLSAMPLE *buf = buffer; /* setup DELTA-T unit */ YM_DELTAT_DECODE_PRESET(DELTAT); @@ -1614,7 +2372,7 @@ void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length) } else /* Rhythm part */ { - OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>22)&1 ); + OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>0)&1 ); } lt = output[0] + (output_deltat[0]>>11); @@ -1644,235 +2402,22 @@ void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length) OPL->status |= 0x10; } } -#endif - -void OPLResetChip(FM_OPL *OPL) -{ - int c,s; - int i; - - OPL->noise_rng = 1; /* noise shift register */ - OPL->mode = 0; /* normal mode */ - OPL_STATUS_RESET(OPL,0x7f); - - /* reset with register write */ - OPLWriteReg(OPL,0x01,0); /* wavesel disable */ - OPLWriteReg(OPL,0x02,0); /* Timer1 */ - OPLWriteReg(OPL,0x03,0); /* Timer2 */ - OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */ - for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0); - - /* reset operator parameters */ - for( c = 0 ; c < 9 ; c++ ) - { - OPL_CH *CH = &OPL->P_CH[c]; - for(s = 0 ; s < 2 ; s++ ) - { - /* wave table */ - CH->SLOT[s].wavetable = &sin_tab[0]; - CH->SLOT[s].state = EG_OFF; - CH->SLOT[s].volume = MAX_ATT_INDEX; - } - } -#if BUILD_Y8950 - if(OPL->type&OPL_TYPE_ADPCM) - { - YM_DELTAT *DELTAT = OPL->deltat; - - DELTAT->freqbase = OPL->freqbase; - DELTAT->output_pointer = &output_deltat[0]; - DELTAT->portshift = 5; - DELTAT->output_range = 1<<23; - YM_DELTAT_ADPCM_Reset(DELTAT,0); - } -#endif -} - -/* Create one of virtual YM3812 */ -/* 'clock' is chip clock in Hz */ -/* 'rate' is sampling rate */ -FM_OPL *OPLCreate(int type, int clock, int rate) -{ - union { - char *ptr; - void *ptr_void; - }; - FM_OPL *OPL; - int state_size; - - if (OPL_LockTable() ==-1) return NULL; - - /* calculate OPL state size */ - state_size = sizeof(FM_OPL); - -#if BUILD_Y8950 - if (type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT); -#endif - - /* allocate memory block */ - ptr_void = malloc(state_size); - - if (ptr==NULL) - return NULL; - - /* clear */ - memset(ptr,0,state_size); - - OPL = (FM_OPL *)ptr; - - ptr += sizeof(FM_OPL); - -#if BUILD_Y8950 - if (type&OPL_TYPE_ADPCM) - OPL->deltat = (YM_DELTAT *)ptr; - ptr += sizeof(YM_DELTAT); -#endif - - OPL->type = type; - OPL->clock = clock; - OPL->rate = rate; - - /* init global tables */ - OPL_initalize(OPL); - - /* reset chip */ - OPLResetChip(OPL); - return OPL; -} - -/* Destroy one of virtual YM3812 */ -void OPLDestroy(FM_OPL *OPL) -{ - OPL_UnLockTable(); - free(OPL); -} - -/* Option handlers */ - -void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset) -{ - OPL->TimerHandler = TimerHandler; - OPL->TimerParam = channelOffset; -} -void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param) -{ - OPL->IRQHandler = IRQHandler; - OPL->IRQParam = param; -} -void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param) -{ - OPL->UpdateHandler = UpdateHandler; - OPL->UpdateParam = param; -} - -#if BUILD_Y8950 -void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param) +void Y8950SetPortHandler(int which,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param) { + FM_OPL *OPL = OPL_Y8950[which]; OPL->porthandler_w = PortHandler_w; OPL->porthandler_r = PortHandler_r; OPL->port_param = param; } -void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param) +void Y8950SetKeyboardHandler(int which,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param) { + FM_OPL *OPL = OPL_Y8950[which]; OPL->keyboardhandler_w = KeyboardHandler_w; OPL->keyboardhandler_r = KeyboardHandler_r; OPL->keyboard_param = param; } + #endif -/* YM3812 I/O interface */ -int OPLWrite(FM_OPL *OPL,int a,int v) -{ - if( !(a&1) ) - { /* address port */ - OPL->address = v & 0xff; - } - else - { /* data port */ - if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); - OPLWriteReg(OPL,OPL->address,v); - } - return OPL->status>>7; -} - -unsigned char OPLRead(FM_OPL *OPL,int a) -{ - if( !(a&1) ) - { - /* YM3812 returns 0x06 (bit2 and bit1 are HIGH) */ - - /* status port */ - return OPL->status & (OPL->statusmask|0x80); - } - -#if BUILD_Y8950 - /* data port */ - switch(OPL->address) - { - case 0x05: /* KeyBoard IN */ - if(OPL->type&OPL_TYPE_KEYBOARD) - { - if(OPL->keyboardhandler_r) - return OPL->keyboardhandler_r(OPL->keyboard_param); - else - LOG(LOG_WAR,("OPL:read unmapped KEYBOARD port\n")); - } - return 0; -#if 0 - case 0x0f: /* ADPCM-DATA */ - return 0; -#endif - case 0x19: /* I/O DATA */ - if(OPL->type&OPL_TYPE_IO) - { - if(OPL->porthandler_r) - return OPL->porthandler_r(OPL->port_param); - else - LOG(LOG_WAR,("OPL:read unmapped I/O port\n")); - } - return 0; - case 0x1a: /* PCM-DATA */ - return 0; - } -#endif - - return 0xff; -} - -/* CSM Key Controll */ -INLINE void CSMKeyControll(OPL_CH *CH) -{ - FM_KEYON (&CH->SLOT[SLOT1], 4); - FM_KEYON (&CH->SLOT[SLOT2], 4); - - /* The key off should happen exactly one sample later - not implemented correctly yet */ - - FM_KEYOFF(&CH->SLOT[SLOT1], ~4); - FM_KEYOFF(&CH->SLOT[SLOT2], ~4); -} - - -int OPLTimerOver(FM_OPL *OPL,int c) -{ - if( c ) - { /* Timer B */ - OPL_STATUS_SET(OPL,0x20); - } - else - { /* Timer A */ - OPL_STATUS_SET(OPL,0x40); - /* CSM mode key,TL controll */ - if( OPL->mode & 0x80 ) - { /* CSM mode total level latch and auto key on */ - int ch; - if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); - for(ch=0; ch<9; ch++) - CSMKeyControll( &OPL->P_CH[ch] ); - } - } - /* reload timer */ - if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase); - return OPL->status>>7; -} diff --git a/src/hardware/fmopl.h b/src/hardware/fmopl.h index 46c5c15e..4ba2b6b8 100644 --- a/src/hardware/fmopl.h +++ b/src/hardware/fmopl.h @@ -6,8 +6,7 @@ #define BUILD_YM3526 (HAS_YM3526) #define BUILD_Y8950 (HAS_Y8950) -/* --- system optimize --- */ -/* select bit size of output : 8 or 16 */ +/* select output bits size of output : 8 or 16 */ #define OPL_SAMPLE_BITS 16 /* compiler dependence */ @@ -25,167 +24,88 @@ typedef signed int INT32; /* signed 32bit */ typedef INT16 OPLSAMPLE; #endif #if (OPL_SAMPLE_BITS==8) -typedef unsigned char OPLSAMPLE; +typedef INT8 OPLSAMPLE; #endif -#if BUILD_Y8950 -#include "ymdeltat.h" -#endif - typedef void (*OPL_TIMERHANDLER)(int channel,double interval_Sec); typedef void (*OPL_IRQHANDLER)(int param,int irq); typedef void (*OPL_UPDATEHANDLER)(int param,int min_interval_us); typedef void (*OPL_PORTHANDLER_W)(int param,unsigned char data); typedef unsigned char (*OPL_PORTHANDLER_R)(int param); -/* !!!!! here is private section , do not access there member direct !!!!! */ -#define OPL_TYPE_WAVESEL 0x01 /* waveform select */ -#define OPL_TYPE_ADPCM 0x02 /* DELTA-T ADPCM unit */ -#define OPL_TYPE_KEYBOARD 0x04 /* keyboard interface */ -#define OPL_TYPE_IO 0x08 /* I/O port */ +#if BUILD_YM3812 -/* Saving is necessary for member of the 'R' mark for suspend/resume */ -/* ---------- OPL slot ---------- */ -typedef struct fm_opl_slot { - const UINT32 *AR; /* attack rate tab :&eg_table[AR<<2]*/ - const UINT32 *DR; /* decay rate tab :&eg_table[DR<<2]*/ - const UINT32 *RR; /* release rate tab:&eg_table[RR<<2]*/ - UINT8 KSR; /* key scale rate */ - UINT8 ARval; /* current AR */ - UINT8 ksl; /* keyscale level */ - UINT8 ksr; /* key scale rate :kcode>>KSR */ - UINT8 mul; /* multiple :ML_TABLE[ML] */ +int YM3812Init(int num, int clock, int rate); +void YM3812Shutdown(void); +void YM3812ResetChip(int which); +int YM3812Write(int which, int a, int v); +unsigned char YM3812Read(int which, int a); +int YM3812TimerOver(int which, int c); +void YM3812UpdateOne(int which, INT16 *buffer, int length); - /* Phase Generator */ - UINT32 Cnt; /* frequency count */ - UINT32 Incr; /* frequency step */ +void YM3812SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset); +void YM3812SetIRQHandler(int which, OPL_IRQHANDLER IRQHandler, int param); +void YM3812SetUpdateHandler(int which, OPL_UPDATEHANDLER UpdateHandler, int param); - /* Envelope Generator */ - UINT8 eg_type; /* percussive/non-percussive mode */ - UINT8 state; /* phase type */ - UINT32 TL; /* total level :TL << 3 */ - INT32 TLL; /* adjusted now TL */ - INT32 volume; /* envelope counter */ - UINT32 sl; /* sustain level :SL_TABLE[SL] */ - UINT32 delta_ar; /* envelope step for Attack */ - UINT32 delta_dr; /* envelope step for Decay */ - UINT32 delta_rr; /* envelope step for Release */ +#endif - UINT32 key; /* 0 = KEY OFF, >0 = KEY ON */ - /* LFO */ - UINT32 AMmask; /* LFO Amplitude Modulation enable mask */ - UINT8 vib; /* LFO Phase Modulation enable flag (active high)*/ +#if BUILD_YM3526 - /* waveform select */ - unsigned int *wavetable; -}OPL_SLOT; +/* +** Initialize YM3526 emulator(s). +** +** 'num' is the number of virtual YM3526's to allocate +** 'clock' is the chip clock in Hz +** 'rate' is sampling rate +*/ +int YM3526Init(int num, int clock, int rate); +/* shutdown the YM3526 emulators*/ +void YM3526Shutdown(void); +void YM3526ResetChip(int which); +int YM3526Write(int which, int a, int v); +unsigned char YM3526Read(int which, int a); +int YM3526TimerOver(int which, int c); +/* +** Generate samples for one of the YM3526's +** +** 'which' is the virtual YM3526 number +** '*buffer' is the output buffer pointer +** 'length' is the number of samples that should be generated +*/ +void YM3526UpdateOne(int which, INT16 *buffer, int length); -/* ---------- OPL one of channel ---------- */ -typedef struct fm_opl_channel { - OPL_SLOT SLOT[2]; - UINT8 FB; /* feedback shift value */ - INT32 *connect1; /* slot1 output pointer */ - INT32 op1_out[2]; /* slot1 output for feedback */ +void YM3526SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset); +void YM3526SetIRQHandler(int which, OPL_IRQHANDLER IRQHandler, int param); +void YM3526SetUpdateHandler(int which, OPL_UPDATEHANDLER UpdateHandler, int param); - /* phase generator state */ - UINT32 block_fnum; /* block+fnum */ - UINT32 fc; /* Freq. Increment base */ - UINT32 ksl_base; /* KeyScaleLevel Base step */ - UINT8 kcode; /* key code (for key scaling) */ +#endif - UINT8 CON; /* connection (algorithm) type */ -} OPL_CH; - -/* OPL state */ -typedef struct fm_opl_f { - /* FM channel slots */ - OPL_CH P_CH[9]; /* OPL/OPL2 chips have 9 channels */ - - UINT8 rhythm; /* Rhythm mode */ - - UINT32 eg_tab[16+64+16]; /* EG rate table: 16 (dummy) + 64 rates + 16 RKS */ - UINT32 fn_tab[1024]; /* fnumber -> increment counter */ - - /* LFO */ - UINT8 lfo_am_depth; - UINT8 lfo_pm_depth_range; - UINT32 lfo_am_cnt; - UINT32 lfo_am_inc; - UINT32 lfo_pm_cnt; - UINT32 lfo_pm_inc; - - UINT32 noise_rng; /* 23 bit noise shift register */ - UINT32 noise_p; /* current noise 'phase' */ - UINT32 noise_f; /* current noise period */ - - UINT8 wavesel; /* waveform select enable flag */ - - int T[2]; /* timer counters */ - UINT8 st[2]; /* timer enable */ #if BUILD_Y8950 - /* Delta-T ADPCM unit (Y8950) */ - YM_DELTAT *deltat; +#include "ymdeltat.h" - /* Keyboard / I/O interface unit*/ - UINT8 portDirection; - UINT8 portLatch; - OPL_PORTHANDLER_R porthandler_r; - OPL_PORTHANDLER_W porthandler_w; - int port_param; - OPL_PORTHANDLER_R keyboardhandler_r; - OPL_PORTHANDLER_W keyboardhandler_w; - int keyboard_param; -#endif - - /* external event callback handlers */ - OPL_TIMERHANDLER TimerHandler; /* TIMER handler */ - int TimerParam; /* TIMER parameter */ - OPL_IRQHANDLER IRQHandler; /* IRQ handler */ - int IRQParam; /* IRQ parameter */ - OPL_UPDATEHANDLER UpdateHandler; /* stream update handler */ - int UpdateParam; /* stream update parameter */ - - UINT8 type; /* chip type */ - UINT8 address; /* address register */ - UINT8 status; /* status flag */ - UINT8 statusmask; /* status mask */ - UINT8 mode; /* Reg.08 : CSM,notesel,etc. */ - - int clock; /* master clock (Hz) */ - int rate; /* sampling rate (Hz) */ - double freqbase; /* frequency base */ - double TimerBase; /* Timer base time (==sampling time)*/ -} FM_OPL; - - -/* ---------- Generic interface section ---------- */ -#define OPL_TYPE_YM3526 (0) -#define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL) -#define OPL_TYPE_Y8950 (OPL_TYPE_ADPCM|OPL_TYPE_KEYBOARD|OPL_TYPE_IO) - -FM_OPL *OPLCreate(int type, int clock, int rate); -void OPLDestroy(FM_OPL *OPL); -void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset); -void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param); -void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param); /* Y8950 port handlers */ -void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param); -void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param); +void Y8950SetPortHandler(int which, OPL_PORTHANDLER_W PortHandler_w, OPL_PORTHANDLER_R PortHandler_r, int param); +void Y8950SetKeyboardHandler(int which, OPL_PORTHANDLER_W KeyboardHandler_w, OPL_PORTHANDLER_R KeyboardHandler_r, int param); +void Y8950SetDeltaTMemory(int which, void * deltat_rom, int deltat_rom_size ); -void OPLResetChip(FM_OPL *OPL); -int OPLWrite(FM_OPL *OPL,int a,int v); -unsigned char OPLRead(FM_OPL *OPL,int a); -int OPLTimerOver(FM_OPL *OPL,int c); +int Y8950Init (int num, int clock, int rate); +void Y8950Shutdown (void); +void Y8950ResetChip (int which); +int Y8950Write (int which, int a, int v); +unsigned char Y8950Read (int which, int a); +int Y8950TimerOver (int which, int c); +void Y8950UpdateOne (int which, INT16 *buffer, int length); + +void Y8950SetTimerHandler (int which, OPL_TIMERHANDLER TimerHandler, int channelOffset); +void Y8950SetIRQHandler (int which, OPL_IRQHANDLER IRQHandler, int param); +void Y8950SetUpdateHandler (int which, OPL_UPDATEHANDLER UpdateHandler, int param); + +#endif - -/* YM3626/YM3812 local section */ -void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length); - -void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length); #endif From cb84cb12cd98704421d47530bfce83a05f691498 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 12 Dec 2002 08:59:23 +0000 Subject: [PATCH 0492/4131] Neg didn't show 8bit regs. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@570 --- src/debug/debug_disasm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debug/debug_disasm.cpp b/src/debug/debug_disasm.cpp index e444a5ff..67559cd2 100644 --- a/src/debug/debug_disasm.cpp +++ b/src/debug/debug_disasm.cpp @@ -344,7 +344,7 @@ static char *groups[][8] = { /* group 0 is group 3 for %Ev set */ { "rol", "ror", "rcl", "rcr", "shl", "shr", "shl", "sar" }, /* 2 */ /* v v*/ - { "test %Eq,%Iq", "test %Eq,%Iq", "not %Ec", "neg %Ev", + { "test %Eq,%Iq", "test %Eq,%Iq", "not %Ec", "neg %Ec", "mul %Ec", "imul %Ec", "div %Ec", "idiv %Ec" }, /* 3 */ { "inc %Eb", "dec %Eb", 0, 0, From 93ebf23a18be09f19263791c6b65633cf287e47b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 13 Dec 2002 15:31:31 +0000 Subject: [PATCH 0493/4131] forgot to clear the ansi.esc if an error occured Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@571 --- src/dos/dev_con.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index ccae558e..c2627367 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -144,6 +144,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { case 'M':/* scrolling UP*/ default: LOG_DEBUG("ANSI: unknown char %c after a esc",data[count]); /*prob () */ + ClearAnsi(); break; } count++; From 6e61c2621a2c8fe91612d98d15667f3ecb635acb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 16 Dec 2002 09:31:38 +0000 Subject: [PATCH 0494/4131] Changed it so pit counters count down and correct latching of mode 3 timers. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@572 --- src/hardware/timer.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 24083f56..69cb7d36 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -56,20 +56,26 @@ static void counter_latch(Bitu counter) { /* Fill the read_latch of the selected counter with current count */ PIT_Block * p=&pit[counter]; - Bit64s micro=PIC_MicroCount(); - micro-=p->start; - micro%=p->micro; - Bit16u ticks=(Bit16u)(((float)micro/(float)p->micro)*(float)p->cntr); - + Bit64s micro=PIC_MicroCount()-p->start; switch (p->mode) { + case 0: + if (micro>p->micro) p->read_latch=p->write_latch; + else p->read_latch=(Bit16u)(p->cntr-(((float)micro/(float)p->micro)*(float)p->cntr)); + break; case 2: + micro%=p->micro; + p->read_latch=(Bit16u)(p->cntr-(((float)micro/(float)p->micro)*(float)p->cntr)); + break; case 3: - case 4: - p->read_latch=(Bit16u)ticks; + micro%=p->micro; + micro*=2; + if (micro>p->micro) micro-=p->micro; + p->read_latch=(Bit16u)(p->cntr-(((float)micro/(float)p->micro)*(float)p->cntr)); break; default: LOG_ERROR("PIT:Illegal Mode %d for reading counter %d",p->mode,counter); - p->read_latch=(Bit16u)ticks; + micro%=p->micro; + p->read_latch=(Bit16u)(p->cntr-(((float)micro/(float)p->micro)*(float)p->cntr)); break; } } @@ -106,6 +112,7 @@ static void write_latch(Bit32u port,Bit8u val) { LOG_DEBUG("PIT 0 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode); break; case 0x02: /* Timer hooked to PC-Speaker */ +// LOG_DEBUG("PIT 2 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode); PCSPEAKER_SetCounter(p->cntr,p->mode); break; default: From 4f04dd2b8ad72acc716065ac83e9b78c9136a2f2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 16 Dec 2002 14:43:54 +0000 Subject: [PATCH 0495/4131] Support for 0x67 prefix and some new 0x66 prefixed instructions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@573 --- src/cpu/core_16/main.h | 34 ++++++++---- src/cpu/core_16/prefix_66.h | 42 ++++++++++++--- src/cpu/core_16/prefix_66_of.h | 62 +++++++++++++++++++++- src/cpu/core_16/prefix_of.h | 7 ++- src/cpu/core_16/support.h | 17 +++++- src/cpu/core_16/table_ea.h | 94 +++++++++++++++++----------------- src/cpu/slow_16.cpp | 10 +++- 7 files changed, 196 insertions(+), 70 deletions(-) diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index fc03e3d5..4926826e 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -293,7 +293,16 @@ restart: #include "prefix_66.h" break; case 0x67: /* Address Size Prefix */ +#ifdef CPU_PREFIX_67 + prefix.mark|=PREFIX_ADDR; +#ifdef CPU_PREFIX_COUNT + prefix.count++; +#endif + lookupEATable=EAPrefixTable[prefix.mark]; + goto restart; +#else NOTDONE; +#endif break; #endif case 0x68: /* PUSH Iw */ @@ -657,26 +666,22 @@ restart: } case 0xa0: /* MOV AL,Ob */ { - GetEADirect; - reg_al=LoadMb(eaa); + reg_al=LoadMb(GetEADirect[prefix.mark]()); } break; case 0xa1: /* MOV AX,Ow */ { - GetEADirect; - reg_ax=LoadMw(eaa); + reg_ax=LoadMw(GetEADirect[prefix.mark]()); } break; case 0xa2: /* MOV Ob,AL */ { - GetEADirect; - SaveMb(eaa,reg_al); + SaveMb(GetEADirect[prefix.mark](),reg_al); } break; case 0xa3: /* MOV Ow,AX */ { - GetEADirect; - SaveMw(eaa,reg_ax); + SaveMw(GetEADirect[prefix.mark](),reg_ax); } break; case 0xa4: /* MOVSB */ @@ -956,6 +961,7 @@ restart: case 0xde: /* FPU ESC 6 */ case 0xdf: /* FPU ESC 7 */ { + LOG_WARN("FPU used"); Bit8u rm=Fetchb(); if (rm<0xc0) GetEAa; } @@ -974,9 +980,15 @@ restart: else ADDIPFAST(1); break; case 0xe3: /* JCXZ */ - if (!reg_cx) ADDIPFAST(Fetchbs()); - else ADDIPFAST(1); - break; + { + Bitu test; + if (prefix.mark & PREFIX_ADDR) { + test=reg_ecx;PrefixReset; + } else test=reg_cx; + if (!test) ADDIPFAST(Fetchbs()); + else ADDIPFAST(1); + break; + } case 0xe4: /* IN AL,Ib */ { Bit16u port=Fetchb();reg_al=IO_Read(port);} break; diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index 0379490f..340be2db 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -149,12 +149,23 @@ switch(Fetchb()) { 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 0x64: /* SEG FS: */ SegPrefix_66(fs);break; case 0x65: /* SEG GS: */ SegPrefix_66(gs);break; + case 0x67: /* Address Size Prefix */ +#ifdef CPU_PREFIX_67 + prefix.mark|=PREFIX_ADDR; +#ifdef CPU_PREFIX_COUNT + prefix.count++; +#endif + lookupEATable=EAPrefixTable[prefix.mark]; + goto restart_66; +#else + NOTDONE; +#endif + case 0x68: /* PUSH Id */ + Push_32(Fetchd());break; case 0x69: /* IMUL Gd,Ed,Id */ { GetRMrd; @@ -267,6 +278,15 @@ switch(Fetchb()) { case 0x8c: LOG_WARN("CPU:66:8c looped back"); break; + case 0x8d: /* LEA */ + { + prefix.segbase=0; + prefix.mark|=PREFIX_SEG; + lookupEATable=EAPrefixTable[prefix.mark]; + GetRMrd;GetEAa; + *rmrd=(Bit32u)eaa; + break; + } case 0x8f: /* POP Ed */ { GetRM; @@ -321,14 +341,12 @@ switch(Fetchb()) { } case 0xa1: /* MOV EAX,Ow */ { - GetEADirect; - reg_eax=LoadMd(eaa); + reg_eax=LoadMd(GetEADirect[prefix.mark]()); } break; case 0xa3: /* MOV Ow,EAX */ { - GetEADirect; - SaveMd(eaa,reg_eax); + SaveMd(GetEADirect[prefix.mark](),reg_eax); } break; case 0xa5: /* MOVSD */ @@ -383,6 +401,18 @@ switch(Fetchb()) { reg_edi=Fetchd();break; case 0xc1: /* GRP2 Ed,Ib */ GRP2D(Fetchb());break; + case 0xc4: /* LES */ + { + GetRMrd;GetEAa; + *rmrd=LoadMd(eaa);SegSet16(es,LoadMw(eaa+4)); + break; + } + case 0xc5: /* LDS */ + { + GetRMrd;GetEAa; + *rmrd=LoadMd(eaa);SegSet16(ds,LoadMw(eaa+4)); + break; + } case 0xc7: /* MOV Ed,Id */ { GetRM; diff --git a/src/cpu/core_16/prefix_66_of.h b/src/cpu/core_16/prefix_66_of.h index c7b0f81f..fa972dca 100644 --- a/src/cpu/core_16/prefix_66_of.h +++ b/src/cpu/core_16/prefix_66_of.h @@ -33,6 +33,14 @@ switch (Fetchb()) { else {GetEAa;DSHRD(eaa,*rmrd,Fetchb(),LoadMd,SaveMd);} break; } + case 0xad: /* SHRD Ed,Gd,Cl */ + { + GetRMrd; + if (rm >= 0xc0 ) {GetEArd;DSHRD(*eard,*rmrd,reg_cl,LoadRd,SaveRd);} + else {GetEAa;DSHRD(eaa,*rmrd,reg_cl,LoadMd,SaveMd);} + break; + } + case 0xb6: /* MOVZX Gd,Eb */ { GetRMrd; @@ -44,8 +52,8 @@ switch (Fetchb()) { { GetRMrd; Bit64s res; - if (rm >= 0xc0 ) {GetEArd;res=(Bit64s)(*rmrd) * (Bit64s)(*eards);} - else {GetEAa;res=(Bit64s)(*rmrd) * (Bit64s)LoadMds(eaa);} + if (rm >= 0xc0 ) {GetEArd;res=((Bit64s)((Bit32s)*rmrd) * (Bit64s)((Bit32s)*eards));} + else {GetEAa;res=((Bit64s)((Bit32s)*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;} @@ -108,6 +116,56 @@ switch (Fetchb()) { flags.type=t_CF; break; } + case 0xbb: /* BTC Ed,Gd */ + { + GetRMrd; + Bit32u mask=1 << (*rmrd & 31); + if (rm >= 0xc0 ) { + GetEArd; + flags.cf=(*eard & mask)>0; + *eard^=mask; + } else { + GetEAa;Bit32u old=LoadMd(eaa); + flags.cf=(old & mask)>0; + SaveMd(eaa,old ^ mask); + } + if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + break; + } + case 0xbc: /* BSF Gd,Ed */ + { + GetRMrd; + Bit32u result,value; + if (rm >= 0xc0) { GetEArd; value=*eard; } + else { GetEAa; value=LoadMd(eaa); } + if (value==0) { + flags.zf = true; + } else { + result = 0; + while ((value & 0x01)==0) { result++; value>>=1; } + flags.zf = false; + *rmrd = result; + } + flags.type=t_UNKNOWN; + break; + } + case 0xbd: /* BSR Gd,Ed */ + { + GetRMrd; + Bit32u result,value; + if (rm >= 0xc0) { GetEArd; value=*eard; } + else { GetEAa; value=LoadMd(eaa); } + if (value==0) { + flags.zf = true; + } else { + result = 35; // Operandsize-1 + while ((value & 0x80000000)==0) { result--; value<<=1; } + flags.zf = false; + *rmrd = result; + } + flags.type=t_UNKNOWN; + break; + } case 0xbe: /* MOVSX Gd,Eb */ { GetRMrd; diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h index dc99459c..ebac6f2a 100644 --- a/src/cpu/core_16/prefix_of.h +++ b/src/cpu/core_16/prefix_of.h @@ -59,6 +59,12 @@ switch(Fetchb()) { /* 0x21 MOV Rd,DRx (386) */ /* 0x22 MOV CRx,Rd (386) */ /* 0x23 MOV DRx,Rd (386) */ + case 0x23: /* MOV DRx,Rd */ + { + GetRM; + LOG_DEBUG("CPU:0F:23 does nothing"); + } + break; /* 0x24 MOV Rd,TRx (386) */ /* 0x26 MOV TRx,Rd (386) */ /* 0x30 WRMSR (P5) */ @@ -394,7 +400,6 @@ switch(Fetchb()) { flags.type=t_UNKNOWN; break; } - /* 0xbd BSR Gw,Ew */ case 0xbe: /* MOVSX Gw,Eb */ { GetRMrw; diff --git a/src/cpu/core_16/support.h b/src/cpu/core_16/support.h index 4468693f..5f540a0a 100644 --- a/src/cpu/core_16/support.h +++ b/src/cpu/core_16/support.h @@ -95,13 +95,17 @@ static INLINE Bit32u Pop_32() { from=SegBase(ds)+reg_si; \ } - #include "helpers.h" #include "table_ea.h" #include "../modrm.h" #include "instructions.h" +static Bit8s table_df_8[2]={1,-1}; +static Bit16s table_df_16[2]={2,-2}; +static Bit32s table_df_32[2]={4,-4}; + + static void Repeat_Normal(bool testz,bool prefix_66) { PhysPt base_si,base_di; @@ -110,6 +114,7 @@ static void Repeat_Normal(bool testz,bool prefix_66) { if (flags.df) direct=-1; else direct=1; base_di=SegBase(es); + if (prefix.mark & PREFIX_ADDR) E_Exit("Unhandled 0x67 prefixed string op"); rep_again: if (prefix.mark & PREFIX_SEG) { base_si=(prefix.segbase); @@ -137,6 +142,16 @@ rep_again: prefix.mark|=PREFIX_SEG; prefix.count++; goto rep_again; + case 0x64: /* FS Prefix */ + prefix.segbase=SegBase(fs); + prefix.mark|=PREFIX_SEG; + prefix.count++; + goto rep_again; + case 0x65: /* GS Prefix */ + prefix.segbase=SegBase(gs); + prefix.mark|=PREFIX_SEG; + prefix.count++; + goto rep_again; case 0x66: /* Size Prefix */ prefix.count++; prefix_66=!prefix_66; diff --git a/src/cpu/core_16/table_ea.h b/src/cpu/core_16/table_ea.h index e5aef7e7..d702fe1a 100644 --- a/src/cpu/core_16/table_ea.h +++ b/src/cpu/core_16/table_ea.h @@ -19,6 +19,8 @@ /* Some variables for EA Loolkup */ typedef EAPoint (*GetEATable[256])(void); +typedef EAPoint (*EA_LookupHandler)(void); + static GetEATable * lookupEATable; #define PREFIX_NONE 0x0 @@ -35,6 +37,7 @@ static struct { /* Gets initialized at the bottem, can't seem to declare forward references */ static GetEATable * EAPrefixTable[4]; + #define SegPrefix(blah) \ prefix.segbase=SegBase(blah); \ prefix.mark|=PREFIX_SEG; \ @@ -55,29 +58,6 @@ static GetEATable * EAPrefixTable[4]; prefix.count=0; \ lookupEATable=EAPrefixTable[PREFIX_NONE]; -#if 1 - -#define GetEADirect \ -EAPoint eaa;switch (prefix.mark) { \ -case PREFIX_NONE:eaa=SegBase(ds)+Fetchw();break; \ -case PREFIX_SEG:eaa=prefix.segbase+Fetchw();PrefixReset;break; \ -case PREFIX_ADDR:eaa=SegBase(ds)+Fetchd();PrefixReset;break; \ -case PREFIX_SEG_ADDR:eaa=prefix.segbase+Fetchd();PrefixReset;break; \ -} - -#else - -#define GetEADirect \ -EAPoint eaa; \ -if (!prefix.mark) { eaa=SegBase(ds)+Fetchw();} \ -else if (prefix.mark == PREFIX_SEG) { eaa=prefix.segbase+Fetchw();PrefixReset;} \ -else if (prefix.mark == PREFIX_ADDR) { eaa=SegBase(ds)+Fetchd();PrefixReset;} \ -else if (prefix.mark == PREFIX_SEG_ADDR) { eaa=prefix.segbase+Fetchd();PrefixReset;} - -#endif - - - /* 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); } @@ -240,32 +220,32 @@ INLINE EAPoint Sib(Bitu mode) { }; -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(ds)+reg_esi; } -static EAPoint EA_32_07_n(void) { return SegBase(ds)+reg_edi; } +static EAPoint EA_32_00_n(void) { PrefixReset;return SegBase(ds)+reg_eax; } +static EAPoint EA_32_01_n(void) { PrefixReset;return SegBase(ds)+reg_ecx; } +static EAPoint EA_32_02_n(void) { PrefixReset;return SegBase(ds)+reg_edx; } +static EAPoint EA_32_03_n(void) { PrefixReset;return SegBase(ds)+reg_ebx; } +static EAPoint EA_32_04_n(void) { PrefixReset;return Sib(0);} +static EAPoint EA_32_05_n(void) { PrefixReset;return SegBase(ds)+Fetchd(); } +static EAPoint EA_32_06_n(void) { PrefixReset;return SegBase(ds)+reg_esi; } +static EAPoint EA_32_07_n(void) { PrefixReset;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_40_n(void) { PrefixReset;return SegBase(ds)+reg_eax+Fetchbs(); } +static EAPoint EA_32_41_n(void) { PrefixReset;return SegBase(ds)+reg_ecx+Fetchbs(); } +static EAPoint EA_32_42_n(void) { PrefixReset;return SegBase(ds)+reg_edx+Fetchbs(); } +static EAPoint EA_32_43_n(void) { PrefixReset;return SegBase(ds)+reg_ebx+Fetchbs(); } +static EAPoint EA_32_44_n(void) { PrefixReset;return Sib(1)+Fetchbs();} +static EAPoint EA_32_45_n(void) { PrefixReset;return SegBase(ss)+reg_ebp+Fetchbs(); } +static EAPoint EA_32_46_n(void) { PrefixReset;return SegBase(ds)+reg_esi+Fetchbs(); } +static EAPoint EA_32_47_n(void) { PrefixReset;return SegBase(ds)+reg_edi+Fetchbs(); } -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 EAPoint EA_32_80_n(void) { PrefixReset;return SegBase(ds)+reg_eax+Fetchds(); } +static EAPoint EA_32_81_n(void) { PrefixReset;return SegBase(ds)+reg_ecx+Fetchds(); } +static EAPoint EA_32_82_n(void) { PrefixReset;return SegBase(ds)+reg_edx+Fetchds(); } +static EAPoint EA_32_83_n(void) { PrefixReset;return SegBase(ds)+reg_ebx+Fetchds(); } +static EAPoint EA_32_84_n(void) { PrefixReset;return Sib(2)+Fetchds();} +static EAPoint EA_32_85_n(void) { PrefixReset;return SegBase(ss)+reg_ebp+Fetchds(); } +static EAPoint EA_32_86_n(void) { PrefixReset;return SegBase(ds)+reg_esi+Fetchds(); } +static EAPoint EA_32_87_n(void) { PrefixReset;return SegBase(ds)+reg_edi+Fetchds(); } static GetEATable GetEA_32_n={ /* 00 */ @@ -327,7 +307,8 @@ INLINE EAPoint Sib_s(Bitu mode) { case 7: /* EDI Base */ base=prefix.segbase+reg_edi;break; } - base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6); PrefixReset; + base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6); + PrefixReset; return base; }; @@ -396,4 +377,21 @@ static GetEATable GetEA_32_s={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +static EAPoint GetEADirect_NONE(void) { + EAPoint result=SegBase(ds)+Fetchw(); + return result; +} +static EAPoint GetEADirect_SEG(void) { + EAPoint result=prefix.segbase+Fetchw();PrefixReset; + return result; +} +static EAPoint GetEADirect_ADDR(void) { + EAPoint result=SegBase(ds)+Fetchd();PrefixReset; + return result; +} +static EAPoint GetEADirect_SEG_ADDR(void) { + EAPoint result=prefix.segbase+Fetchd();PrefixReset; + return result; +} +static EA_LookupHandler GetEADirect[4]={GetEADirect_NONE,GetEADirect_SEG,GetEADirect_ADDR,GetEADirect_SEG_ADDR}; diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp index 5f997f98..40146a3b 100644 --- a/src/cpu/slow_16.cpp +++ b/src/cpu/slow_16.cpp @@ -55,10 +55,14 @@ extern Bitu cycle_count; /* Enable parts of the cpu emulation */ #define CPU_386 //Enable 386 instructions +#define CPU_PREFIX_67 //Enable the 0x67 prefix +#define CPU_PREFIX_COUNT //Enable counting of prefixes + #if C_FPU #define CPU_FPU //Enable FPU escape instructions #endif + #include "core_16/support.h" static Bitu CPU_Real_16_Slow_Decode_Trap(void); @@ -73,7 +77,11 @@ static Bitu CPU_Real_16_Slow_Decode(void) { if (DEBUG_HeavyIsBreakpoint()) return 1; #endif #include "core_16/main.h" -// if (prefix.count) LOG_DEBUG("Prefix for non prefixed instruction"); + if (prefix.count) { + PrefixReset; + //DEBUG_HeavyWriteLogInstruction(); + LOG_DEBUG("Prefix for non prefixed instruction"); + } CPU_Cycles--; } #include "core_16/stop.h" From 4b95cf5b97a3d49805127ff9ddb4322d75202d25 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 17 Dec 2002 08:54:01 +0000 Subject: [PATCH 0496/4131] Support for loading gus and disney sound source. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@574 --- src/dosbox.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index c1e82ad0..d4ab1454 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -64,10 +64,14 @@ void KEYBOARD_Init(Section*); //TODO This should setup INT 16 too but ok ;) void JOYSTICK_Init(Section*); void MOUSE_Init(Section*); void SBLASTER_Init(Section*); +void GUS_Init(Section*); void ADLIB_Init(Section*); void PCSPEAKER_Init(Section*); void TANDYSOUND_Init(Section*); void CMS_Init(Section*); +void DISNEY_Init(Section*); + + void PIC_Init(Section*); void TIMER_Init(Section*); @@ -192,7 +196,11 @@ void DOSBOX_Init(void) { secprop->Add_bool("adlib",true); secprop->AddInitFunction(&CMS_Init); secprop->Add_bool("cms",false); + + secprop=control->AddSection_prop("gus",&GUS_Init); + secprop=control->AddSection_prop("disney",&DISNEY_Init); + secprop=control->AddSection_prop("speaker",&PCSPEAKER_Init); secprop->Add_bool("enabled",true); secprop->Add_bool("sinewave",false); From fc07c6466d39e4c53f7be236a6f6106e0e2bb2bc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 17 Dec 2002 08:54:36 +0000 Subject: [PATCH 0497/4131] Gravis UltraSound Someday Disney Sound Source Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@575 --- src/hardware/disney.cpp | 102 ++++++++++++++++++++++++++++++++++++++++ src/hardware/gus.cpp | 23 +++++++++ 2 files changed, 125 insertions(+) create mode 100644 src/hardware/disney.cpp create mode 100644 src/hardware/gus.cpp diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp new file mode 100644 index 00000000..0e2291c8 --- /dev/null +++ b/src/hardware/disney.cpp @@ -0,0 +1,102 @@ +#include +#include "dosbox.h" +#include "inout.h" +#include "mixer.h" +#include "dma.h" +#include "pic.h" +#include "hardware.h" +#include "setup.h" +#include "programs.h" + + + +#define DISNEY_BASE 0x0378 + +#define DISNEY_SIZE 32 + +static struct { + Bit8u data; + Bit8u status; + Bit8u control; + Bit8u buffer[DISNEY_SIZE]; + Bitu used; + bool enabled; + Bit8u delay; + MIXER_Channel * chan; +} disney; + +static void disney_write(Bit32u port,Bit8u val) { + switch (port-DISNEY_BASE) { + case 0: /* Data Port */ + disney.data=val; + break; + case 1: /* Status Port */ + LOG_WARN("DISNEY:Status write %x",val); + break; + case 2: /* Control Port */ +// LOG_WARN("DISNEY:Control write %x",val); + if (val&0x8) { + if (disney.used=16) return 0x40; + else return 0x0; + break; + case 2: /* Control Port */ + LOG_WARN("DISNEY:Read from control port"); + return disney.control; + break; + } + return 0xff; +} + + +static void DISNEY_CallBack(Bit8u * stream,Bit32u len) { + if (!len) return; + if (disney.used>len) { + memcpy(stream,disney.buffer,len); + memmove(disney.buffer,&disney.buffer[len],disney.used-len); + disney.used-=len; + return; + } else { + memcpy(stream,disney.buffer,disney.used); + memset(stream+disney.used,0x80,len-disney.used); + disney.used=0; + } +} + + +void DISNEY_Init(Section* sec) { + IO_RegisterWriteHandler(DISNEY_BASE,disney_write,"DISNEY"); + IO_RegisterWriteHandler(DISNEY_BASE+1,disney_write,"DISNEY"); + IO_RegisterWriteHandler(DISNEY_BASE+2,disney_write,"DISNEY"); + + IO_RegisterReadHandler(DISNEY_BASE,disney_read,"DISNEY"); + IO_RegisterReadHandler(DISNEY_BASE+1,disney_read,"DISNEY"); + IO_RegisterReadHandler(DISNEY_BASE+2,disney_read,"DISNEY"); + + disney.chan=MIXER_AddChannel(&DISNEY_CallBack,7000,"DISNEY"); + MIXER_SetMode(disney.chan,MIXER_8MONO); + MIXER_Enable(disney.chan,true); + + disney.status=0x84; + disney.control=0; + disney.used=0; +} + diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp new file mode 100644 index 00000000..160feac5 --- /dev/null +++ b/src/hardware/gus.cpp @@ -0,0 +1,23 @@ +#include +#include "dosbox.h" +#include "inout.h" +#include "mixer.h" +#include "dma.h" +#include "pic.h" +#include "hardware.h" +#include "setup.h" +#include "programs.h" + + + + + + +void GUS_Init(Section* sec) { + + + + +} + + From 4efaf1c46c185084165a44271526c17bc05e233b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 17 Dec 2002 08:55:12 +0000 Subject: [PATCH 0498/4131] gus.cpp and disney.cpp added. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@576 --- src/hardware/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index 8430e7f9..737c3ebe 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -7,5 +7,6 @@ noinst_LIBRARIES = libhardware.a libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler.cpp joystick.cpp keyboard.cpp \ memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ vga.cpp vga.h vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_fonts.cpp vga_gfx.cpp \ - vga_memory.cpp vga_misc.cpp vga_seq.cpp font-switch.h ega-switch.h cmos.cpp + vga_memory.cpp vga_misc.cpp vga_seq.cpp font-switch.h ega-switch.h cmos.cpp disney.cpp \ + gus.cpp From aa633a7e8191cc28021afc9411dc6366f4dce9a6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 17 Dec 2002 08:57:27 +0000 Subject: [PATCH 0499/4131] Test for parallel port and setup bios segment for it. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@577 --- src/ints/bios.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index f9872d7f..83697864 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -276,6 +276,8 @@ void BIOS_Init(Section* sec) { CALLBACK_Setup(call_int1,&INT1_Single_Step,CB_IRET); RealSetVec(0x1,CALLBACK_RealPointer(call_int1)); + /* Test for some hardware */ + if (IO_Read(0x378)!=0xff) real_writed(0x40,0x08,0x378); } From daf54354568cb03f7f216e674a5932bc79bac12b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 17 Dec 2002 09:06:17 +0000 Subject: [PATCH 0500/4131] No longer E_exit on illegal headers, just a warning,. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@578 --- src/dos/dos_execute.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 56414bd7..65621482 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -271,12 +271,12 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { pos=headersize;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET); while (imagesize>0x7FFF) { readsize=0x8000;DOS_ReadFile(fhandle,loadaddress,&readsize); - if (readsize!=0x8000) E_Exit("Illegal header"); + if (readsize!=0x8000) LOG_WARN("Illegal header"); loadaddress+=0x8000;imagesize-=0x8000; } if (imagesize>0) { readsize=(Bit16u)imagesize;DOS_ReadFile(fhandle,loadaddress,&readsize); - if (readsize!=imagesize) E_Exit("Illegal header"); + if (readsize!=imagesize) LOG_WARN("Illegal header"); } /* Relocate the exe image */ Bit16u relocate; From fd1591a4a21b9ca969f6365f446d884dd30b27fc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 17 Dec 2002 09:54:14 +0000 Subject: [PATCH 0501/4131] disney and gus added Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@579 --- visualc/dosbox.dsp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index f1b25592..9fd8aed8 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -271,6 +271,10 @@ SOURCE=..\include\render.h # End Source File # Begin Source File +SOURCE=..\src\gui\render_support.h +# End Source File +# Begin Source File + SOURCE=..\src\gui\sdlmain.cpp # End Source File # Begin Source File @@ -339,6 +343,10 @@ SOURCE=..\src\hardware\cmos.cpp # End Source File # Begin Source File +SOURCE=..\src\hardware\disney.cpp +# End Source File +# Begin Source File + SOURCE=..\src\hardware\dma.cpp # End Source File # Begin Source File @@ -347,6 +355,10 @@ SOURCE=..\src\hardware\gameblaster.cpp # End Source File # Begin Source File +SOURCE=..\src\hardware\gus.cpp +# End Source File +# Begin Source File + SOURCE=..\src\hardware\hardware.cpp # End Source File # Begin Source File From 22f9949b9da43c1ca0679ab29a108de972a203db Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 17 Dec 2002 14:13:01 +0000 Subject: [PATCH 0502/4131] Be sure not to draw sdl mouse pointer in fullscreen Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@580 --- src/gui/sdlmain.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index c0d9222a..943ab9da 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -134,6 +134,8 @@ static void SwitchFullScreen(void) { sdl.width=0;sdl.height=0; (*sdl.resize)(&sdl.width,&sdl.height); } + // be sure not to dont draw sdl mouse + SDL_ShowCursor(SDL_DISABLE); } ResetScreen(); GFX_Start(); From a8cacc5c633465b436525ce8a9037e0f6e2635ac Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 17 Dec 2002 18:31:08 +0000 Subject: [PATCH 0503/4131] added delete removed a strange include Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@581 --- src/shell/shell.cpp | 6 ++++-- src/shell/shell_batch.cpp | 1 - src/shell/shell_cmds.cpp | 21 +++++++++++++++++++-- src/shell/shell_inc.h | 1 + 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 8b405f23..3c6e9e5a 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -186,7 +186,8 @@ void SHELL_Init() { MSG_Add("SHELL_ILLEGAL_SWITCH","Illegal switch: %s\n"); MSG_Add("SHELL_CMD_CHDIR_ERROR","Unable to change to: %s\n"); MSG_Add("SHELL_CMD_MKDIR_ERROR","Unable to make: %s\n"); - MSG_Add("SHELL_CMD_RMDIR_ERROR","Unable to remove: %\n"); + MSG_Add("SHELL_CMD_RMDIR_ERROR","Unable to remove: %s\n"); + MSG_Add("SHELL_CMD_DEL_ERROR","Unable to delete: %s\n"); MSG_Add("SHELL_SYNTAXERROR","The syntax of the command is incorrect.\n"); MSG_Add("SHELL_CMD_SET_NOT_SET","Environment variable %s not defined\n"); MSG_Add("SHELL_CMD_SET_OUT_OF_SPACE","Not enough environment space left.\n"); @@ -217,8 +218,9 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_GOTO_HELP","Jump to a labeled line in a batch script.\n"); MSG_Add("SHELL_CMD_TYPE_HELP","Display the contents of a text-file.\n"); MSG_Add("SHELL_CMD_REM_HELP","Add comments in a batch file.\n"); - MSG_Add("SHELL_CMD_RENAME_WILD","This is a simple Rename, no wildcards allowed!\n"); + MSG_Add("SHELL_CMD_NO_WILD","This is a simple version of the command, no wildcards allowed!\n"); MSG_Add("SHELL_CMD_RENAME_HELP","Renames files.\n"); + MSG_Add("SHELL_CMD_DELETE_HELP","Removes files.\n"); /* Regular startup */ call_shellstop=CALLBACK_Allocate(); /* Setup the startup CS:IP to kill the last running machine when exitted */ diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 769dccea..304f5987 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -20,7 +20,6 @@ #include #include "shell_inc.h" -#include "cpu.h" BatchFile::BatchFile(DOS_Shell * host,char * name, char * cmd_line) { diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 24934ece..9a05d530 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -28,6 +28,8 @@ static SHELL_Cmd cmd_list[]={ "CLS", 0, &DOS_Shell::CMD_CLS, "SHELL_CMD_CLS_HELP", // "COPY", 0, &DOS_Shell::CMD_COPY, "Copy Files.", "DIR", 0, &DOS_Shell::CMD_DIR, "SHELL_CMD_DIR_HELP", + "DEL", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP", + "DELETE", 0, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP", "ECHO", 0, &DOS_Shell::CMD_ECHO, "SHELL_CMD_ECHO_HELP", "EXIT", 0, &DOS_Shell::CMD_EXIT, "SHELL_CMD_EXIT_HELP", "HELP", 0, &DOS_Shell::CMD_HELP, "SHELL_CMD_HELP_HELP", @@ -39,7 +41,7 @@ static SHELL_Cmd cmd_list[]={ "TYPE", 0, &DOS_Shell::CMD_TYPE, "SHELL_CMD_TYPE_HELP", "REM", 0, &DOS_Shell::CMD_REM, "SHELL_CMD_REM_HELP", "RENAME", 0, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP", - "REN", 0, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP", + "REN", 1, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP", /* "CHDIR", 0, &DOS_Shell::CMD_CHDIR, "Change Directory", "MKDIR", 0, &DOS_Shell::CMD_MKDIR, "Make Directory", @@ -57,6 +59,7 @@ void DOS_Shell::DoCommand(char * line) { if (*line==32) break; if (*line=='/') break; if ((*line=='.') && (*(line+1)=='.')) break; +// if ((*line=='.') && (*(line+1)==0)) break; *cmd_write++=*line++; } *cmd_write=0; @@ -81,6 +84,20 @@ void DOS_Shell::CMD_CLS(char * args) { CALLBACK_RunRealInt(0x10); }; +void DOS_Shell::CMD_DELETE(char * args) { + char * rem=ScanCMDRemain(args); + if (rem) { + WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); + return; + } + if((strchr(args,'*')!=NULL) || (strchr(args,'?')!=NULL) ) { WriteOut(MSG_Get("SHELL_CMD_NO_WILD"));return;} + + if (!DOS_UnlinkFile(args)) { + WriteOut(MSG_Get("SHELL_CMD_DEL_ERROR"),args); + } + +}; + void DOS_Shell::CMD_HELP(char * args){ /* Print the help */ WriteOut(MSG_Get("SHELL_CMD_HELP")); @@ -94,7 +111,7 @@ void DOS_Shell::CMD_HELP(char * args){ void DOS_Shell::CMD_RENAME(char * args){ if(!*args) {SyntaxError();return;} - if((strchr(args,'*')!=NULL) || (strchr(args,'?')!=NULL) ) { WriteOut(MSG_Get("SHELL_CMD_RENAME_WILD"));} + if((strchr(args,'*')!=NULL) || (strchr(args,'?')!=NULL) ) { WriteOut(MSG_Get("SHELL_CMD_NO_WILD"));return;} char * arg2 =StripWord(args); DOS_Rename(args,arg2); } diff --git a/src/shell/shell_inc.h b/src/shell/shell_inc.h index fefd0d0b..e21f323d 100644 --- a/src/shell/shell_inc.h +++ b/src/shell/shell_inc.h @@ -66,6 +66,7 @@ public: 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); From 4ff5924eb17cde3474d3c87fb4d707feb96f9c2c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 17 Dec 2002 18:32:02 +0000 Subject: [PATCH 0504/4131] changed upcase and lowercase code. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@582 --- include/support.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/include/support.h b/include/support.h index 8857469a..8e260588 100644 --- a/include/support.h +++ b/include/support.h @@ -45,15 +45,13 @@ bool ScanCMDHex(char * cmd,char * check,Bits * result); char * StripWord(char * cmd); INLINE char * upcase(char * str) { - char * oldstr=str; - while (*str) *str++=toupper(*str); - return oldstr; + for (char* idx = str; *idx ; idx++) *idx = toupper(*idx); + return str; } INLINE char * lowcase(char * str) { - char * oldstr=str; - while (*str) *str++=tolower(*str); - return oldstr; + for(char* idx = str; *idx ; idx++) *idx = tolower(*idx); + return str; } From 8a7b36aaeec851e8fae3ffef2161f789ac0c7751 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 18 Dec 2002 09:30:55 +0000 Subject: [PATCH 0505/4131] If we're gonna support delete why not add some wildcard support too. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@583 --- src/shell/shell.cpp | 2 +- src/shell/shell_cmds.cpp | 27 ++++++++++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 3c6e9e5a..a59454aa 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -180,6 +180,7 @@ static char * init_line="/INIT AUTOEXEC.BAT"; void SHELL_Init() { /* Add messages */ + MSG_Add("SHELL_ILLEGAL_PATH","Illegal Path\n"); MSG_Add("SHELL_CMD_HELP","supported commands are:\n"); MSG_Add("SHELL_CMD_ECHO_ON","ECHO is on\n"); MSG_Add("SHELL_CMD_ECHO_OFF","ECHO is off\n"); @@ -199,7 +200,6 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_FILE_NOT_FOUND","File %s not found.\n"); MSG_Add("SHELL_CMD_FILE_EXISTS","File %s already exists.\n"); MSG_Add("SHELL_CMD_DIR_INTRO","Directory of %s.\n"); - MSG_Add("SHELL_CMD_DIR_PATH_ERROR","Illegal Path\n"); MSG_Add("SHELL_CMD_DIR_BYTES_USED","%5d File(s) %17s Bytes\n"); MSG_Add("SHELL_CMD_DIR_BYTES_FREE","%5d Dir(s) %17s Bytes free\n"); MSG_Add("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\n"); diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 9a05d530..5b0004b5 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -90,13 +90,26 @@ void DOS_Shell::CMD_DELETE(char * args) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); return; } - if((strchr(args,'*')!=NULL) || (strchr(args,'?')!=NULL) ) { WriteOut(MSG_Get("SHELL_CMD_NO_WILD"));return;} - - if (!DOS_UnlinkFile(args)) { - WriteOut(MSG_Get("SHELL_CMD_DEL_ERROR"),args); + char full[DOS_PATHLENGTH]; + if (!DOS_Canonicalize(args,full)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH"));return; } +//TODO Maybe support confirmation for *.* like dos does. + bool res=DOS_FindFirst(args,0xff); + if (!res) { + WriteOut(MSG_Get("SHELL_CMD_DEL_ERROR"),args);return; } - -}; + //end can't be 0, but if it is we'll get a nice crash, who cares :) + char * end=strrchr(full,'\\')+1;*end=0; + char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u time,date;Bit8u attr; + DOS_DTA dta(dos.dta); + while (res) { + dta.GetResult(name,size,date,time,attr); + if (!(attr & (DOS_ATTR_DIRECTORY|DOS_ATTR_READ_ONLY))) { + strcpy(end,name); + if (!DOS_UnlinkFile(full)) WriteOut(MSG_Get("SHELL_CMD_DEL_ERROR"),full); + } + res=DOS_FindNext(); + } +} void DOS_Shell::CMD_HELP(char * args){ /* Print the help */ @@ -216,7 +229,7 @@ void DOS_Shell::CMD_DIR(char * args) { /* Make a full path in the args */ if (!DOS_Canonicalize(args,path)) { - WriteOut(MSG_Get("SHELL_CMD_DIR_PATH_ERROR")); + WriteOut(MSG_Get("SHELL_CMD_ILLEGAL_PATH")); return; } *(strrchr(path,'\\')+1)=0; From 6966af57acd61b995aded89c8011fa4f05535a2f Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 19 Dec 2002 13:59:40 +0000 Subject: [PATCH 0506/4131] Added mickey/pixel rate New mouse int vector for weird mouse detection routines in some games Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@584 --- src/ints/mouse.cpp | 92 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 77 insertions(+), 15 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 912bd469..0a962314 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -29,6 +29,9 @@ static Bitu call_int33,call_int74; +// forward +void WriteMouseIntVector(void); + struct button_event { Bit16u type; Bit16u buttons; @@ -90,6 +93,12 @@ static struct { Bit16s clipx,clipy; Bit16s hotx,hoty; Bit16u textAndMask, textXorMask; + + float mickeysPerPixel_x; + float mickeysPerPixel_y; + float pixelPerMickey_x; + float pixelPerMickey_y; + } mouse; #define X_MICKEY 8 @@ -306,12 +315,17 @@ void DrawCursor() { } void Mouse_CursorMoved(float x,float y) { - mouse.mickey_x+=x; - mouse.mickey_y+=y; - mouse.x+=x; + + float dx = x * mouse.pixelPerMickey_x; + float dy = y * mouse.pixelPerMickey_y; + + mouse.mickey_x += dx; + mouse.mickey_y += dy; + + mouse.x += dx; if (mouse.x>mouse.max_x) mouse.x=mouse.max_x;; if (mouse.xmouse.max_y) mouse.y=mouse.max_y;; if (mouse.y Date: Thu, 19 Dec 2002 14:03:44 +0000 Subject: [PATCH 0507/4131] if mouse is autolocked, ignore first button click Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@585 --- src/gui/sdlmain.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 943ab9da..746b43b4 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -367,7 +367,11 @@ static void HandleMouseMotion(SDL_MouseMotionEvent * motion) { static void HandleMouseButton(SDL_MouseButtonEvent * button) { switch (button->state) { case SDL_PRESSED: - if (sdl.mouse.requestlock && !sdl.mouse.locked) CaptureMouse(); + if (sdl.mouse.requestlock && !sdl.mouse.locked) { + CaptureMouse(); + // Dont pass klick to mouse handler + break; + } switch (button->button) { case SDL_BUTTON_LEFT: Mouse_ButtonPressed(0); From c0ae71729ea880e4b10f3f642b6346ce77244fea Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 21 Dec 2002 15:49:05 +0000 Subject: [PATCH 0508/4131] 0.57 mayor update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@586 --- ChangeLog | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a5716f69..f8d47e27 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ +0.57 - added support for command /C - fixed all fcb-write functions - fixed fcb-parseline @@ -15,8 +16,29 @@ - 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) + - 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 + - support for screenshots + - 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 From 0d2c7f7016e3e965de86bb286252d7bda88d9ca4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 21 Dec 2002 15:58:40 +0000 Subject: [PATCH 0509/4131] 0.57 preparations Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@587 --- README | 3 ++- THANKS | 1 + VERSION | 2 +- configure.in | 2 +- src/platform/visualc/config.h | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/README b/README index 7dbc7cc5..391b1d52 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -DOSBox v0.56 +DOSBox v0.57 Usage: ====== @@ -122,6 +122,7 @@ Vlad R. of the vdmsound project for excellent sound blaster info. Tatsuyuki Satoh of the Mame Team for making an excellent FM emulator. The Bochs and DOSemu projects which I used for information. Freedos for ideas in making my shell. +The Beta Testers. Contact: ======== diff --git a/THANKS b/THANKS index fdc282ee..6e7ae900 100644 --- a/THANKS +++ b/THANKS @@ -6,3 +6,4 @@ Tatsuyuki Satoh of the Mame Team for making an excellent FM emulator. The Bochs and DOSemu projects which I used for information. Freedos for ideas in making my shell. All the people who submitted a bug. +The Beta Testers. diff --git a/VERSION b/VERSION index 3fb437d8..96ca7699 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.56 \ No newline at end of file +0.57 diff --git a/configure.in b/configure.in index 4fa3482d..9417a9d6 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Init. -AC_INIT(dosbox,0.56) +AC_INIT(dosbox,0.57) AC_CONFIG_SRCDIR(README) dnl Detect the canonical host and target build environment diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 043d02bf..83fa3b12 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -1,6 +1,6 @@ #define INLINE __forceinline -#define VERSION "0.56" +#define VERSION "0.57" #define GCC_ATTRIBUTE(x) /* attribute not supported */ From 5991ee0c949c065769a17bfd956f02b4b68d5d11 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 22 Dec 2002 11:53:04 +0000 Subject: [PATCH 0510/4131] mouse improvements Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@588 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index f8d47e27..485705c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21,6 +21,7 @@ - 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 From 4665b9b268278e695cd17a97300e0420fa52c55f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 22 Dec 2002 13:04:10 +0000 Subject: [PATCH 0511/4131] Fixed button pressed masks Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@589 --- src/hardware/joystick.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index a5bd7f88..f99aea0b 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -46,14 +46,14 @@ static Bit8u read_p201(Bit32u port) { if (stick[0].enabled) { if (stick[0].xcount) stick[0].xcount--; else ret&=~1; if (stick[0].ycount) stick[0].ycount--; else ret&=~2; - if (stick[0].button[0]) ret&=16; - if (stick[0].button[1]) ret&=32; + if (stick[0].button[0]) ret&=~16; + if (stick[0].button[1]) ret&=~32; } if (stick[1].enabled) { if (stick[1].xcount) stick[1].xcount--; else ret&=~4; if (stick[1].ycount) stick[1].ycount--; else ret&=~8; - if (stick[1].button[0]) ret&=64; - if (stick[1].button[1]) ret&=128; + if (stick[1].button[0]) ret&=~64; + if (stick[1].button[1]) ret&=~128; } return ret; } From f1fd4ae6961eb20b05c61fb934b67c14c9c3a102 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 22 Dec 2002 13:13:51 +0000 Subject: [PATCH 0512/4131] Fix for memory allocate to not run outside the range of xms handles. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@590 --- src/ints/xms.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index d369d350..875baa2f 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -118,7 +118,8 @@ Bitu XMS_Handler(void) { case XMS_LOCAL_ENABLE_A20: /* 05 */ case XMS_LOCAL_DISABLE_A20: /* 06 */ case XMS_QUERY_A20: /* 07 */ - LOG_WARN("XMS:Unhandled call %2X",reg_ah);break; + LOG_WARN("XMS:Unhandled call %2X",reg_ah); + break; case XMS_QUERY_FREE_EXTENDED_MEMORY: /* 08 */ /* Scan the tree for free memory and find largest free block */ { @@ -177,7 +178,7 @@ foundnew: return CBRET_NONE; } /* Not a free block or too small advance to next one if possible */ - if (xms_handles[index].next) index=xms_handles[index].next; + if (xms_handles[index].next < XMS_HANDLES ) index=xms_handles[index].next; else break; } /* Found no good blocks give some errors */ @@ -311,7 +312,7 @@ foundnew: } reg_bh=xms_handles[reg_dx].locked; /* Find available blocks */ - reg_bx=0;{ for (Bitu i=0;i Date: Sun, 22 Dec 2002 15:11:29 +0000 Subject: [PATCH 0513/4131] Updated vga screen updates routines. correct frame per second, corrected dac read/write index added support for split screen. Some more fixes i forgot Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@591 --- src/hardware/vga.cpp | 161 +++++++++++++++++++++++++++--------- src/hardware/vga.h | 39 +++++---- src/hardware/vga_attr.cpp | 10 ++- src/hardware/vga_crtc.cpp | 58 ++++++++----- src/hardware/vga_dac.cpp | 38 +++++---- src/hardware/vga_draw.cpp | 103 ++++++----------------- src/hardware/vga_gfx.cpp | 1 + src/hardware/vga_memory.cpp | 19 +++-- src/hardware/vga_misc.cpp | 8 +- src/hardware/vga_seq.cpp | 7 +- 10 files changed, 255 insertions(+), 189 deletions(-) diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index dac94628..b62dd7e3 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -40,13 +40,72 @@ Bit32u FillTable[16]={ }; +static void VGA_BlankTimer(void) { + PIC_AddEvent(&VGA_BlankTimer,vga.draw.blank); + Bit8u * buf,* bufsplit; + /* Draw the current frame */ + if (!vga.draw.resizing && RENDER_StartUpdate()) { + if (vga.config.line_compare=vga.draw.height){ + LOG_VGA("Split at %d",stop); + goto drawnormal; + } + switch (vga.mode) { + case GFX_16: + buf=&vga.buffer[vga.config.real_start*8+vga.config.pel_panning]; + bufsplit=vga.buffer; + break; + case GFX_256U: + buf=&vga.mem.linear[vga.config.real_start*4+vga.config.pel_panning/2]; + bufsplit=vga.mem.linear; + break; + case GFX_256C: + buf=memory+0xa0000; + bufsplit=memory+0xa0000; + break; + default: + LOG_WARN("VGA:Unhandled split screen mode %d",vga.mode); + goto norender; + } + RENDER_Part(buf,0,0,vga.draw.width,stop); + RENDER_Part(bufsplit,0,stop,vga.draw.width,vga.draw.height-stop); + } else { +drawnormal: + switch (vga.mode) { + case GFX_2: + VGA_DrawGFX2_Fast(vga.buffer,vga.draw.width); + buf=vga.buffer; + break; + case GFX_4: + VGA_DrawGFX4_Fast(vga.buffer,vga.draw.width); + buf=vga.buffer; + break; + case TEXT_16: + VGA_DrawTEXT(vga.buffer,vga.draw.width); + buf=vga.buffer; + break; + case GFX_16: + buf=&vga.buffer[vga.config.real_start*8+vga.config.pel_panning]; + break; + case GFX_256C: + buf=memory+0xa0000; + break; + case GFX_256U: + buf=&vga.mem.linear[vga.config.real_start*4+vga.config.pel_panning/2]; + break; + } + RENDER_Part(buf,0,0,vga.draw.width,vga.draw.height); -void VGA_Render_GFX_2(Bit8u * * data); -void VGA_Render_GFX_4(Bit8u * * data); -void VGA_Render_GFX_16(Bit8u * * data); -void VGA_Render_GFX_256C(Bit8u * * data); -void VGA_Render_GFX_256U(Bit8u * * data); -void VGA_Render_TEXT_16(Bit8u * * data); + + } +norender: + RENDER_EndUpdate(); + + } + VGA_StartRetrace(); +} void VGA_FindSettings(void) { /* Sets up the correct memory handler from the vga.mode setting */ @@ -67,8 +126,10 @@ void VGA_FindSettings(void) { } else if (vga.config.cga_enabled) { /* 4 color cga */ //TODO Detect hercules modes, probably set them up in bios too - if (vga.config.pixel_double) vga.mode=GFX_4; - else vga.mode=GFX_2; + if (vga.seq.clocking_mode & 0x8) { + vga.mode=GFX_4; +// MEM_SetupPageHandlers(PAGE_COUNT(0x0b8000),PAGE_COUNT(0x10000),&VGA_GFX_4_ReadHandler,&VGA_GFX_4_WriteHandler); + } else vga.mode=GFX_2; //TODO Maybe also use a page handler for cga mode } else { /* 16 color ega */ @@ -83,70 +144,96 @@ void VGA_FindSettings(void) { } static void VGA_DoResize(void) { - vga.draw.resizing=false; - Bitu width,height,pitch; - RENDER_Handler * renderer; + /* Calculate the FPS for this screen */ + double fps; + Bitu vtotal=2 + (vga.crtc.vertical_total | ((vga.crtc.overflow & 1) << 8) | ((vga.crtc.overflow & 0x20) << 4) ); + Bitu htotal=5 + vga.crtc.horizontal_total; + Bitu vdispend = 1 + (vga.crtc.vertical_display_end | ((vga.crtc.overflow & 2)<<7) | ((vga.crtc.overflow & 0x40) << 3) ); + Bitu hdispend = 1 + (vga.crtc.horizontal_display_end); + //TODO Maybe check if blanking comes before display_end - height=vga.config.vdisplayend+1; - if (vga.config.vline_height>0) { - height/=(vga.config.vline_height+1); - } - if (vga.config.vline_double) height>>=1; - width=vga.config.hdisplayend; + double clock=(double)vga.config.clock; + /* Check for 8 for 9 character clock mode */ + if (vga.seq.clocking_mode & 1 ) clock/=8; else clock/=9; + /* Check for pixel doubling, master clock/2 */ + if (vga.seq.clocking_mode & 0x8) clock/=2; + + LOG_VGA("H total %d, V Total %d",htotal,vtotal); + LOG_VGA("H D End %d, V D End %d",hdispend,vdispend); + fps=clock/(vtotal*htotal); + + vga.draw.resizing=false; + Bitu width,height,pitch,flags; + + flags=0; + vga.draw.lines=height=vdispend; + width=hdispend; + vga.draw.double_height=vga.config.vline_double; + vga.draw.double_width=(vga.seq.clocking_mode & 0x8)>0; + vga.draw.font_height=vga.config.vline_height+1; switch (vga.mode) { case GFX_256C: - renderer=&VGA_Render_GFX_256C; - width<<=2; - pitch=vga.config.scan_len*8; - break; case GFX_256U: + vga.draw.double_width=true; //Hack since 256 color modes use 2 clocks for a pixel + /* Don't know might do this different sometime, will have to do for now */ + if (!vga.draw.double_height) { + if (vga.config.vline_height&1) { + vga.draw.double_height=true; + vga.draw.font_height/=2; + } + } width<<=2; pitch=vga.config.scan_len*8; - renderer=&VGA_Render_GFX_256U; break; case GFX_16: width<<=3; pitch=vga.config.scan_len*16; - renderer=&VGA_Render_GFX_16; break; case GFX_4: width<<=3; - height<<=1; pitch=width; - renderer=&VGA_Render_GFX_4; break; case GFX_2: width<<=3; - height<<=1; pitch=width; - renderer=&VGA_Render_GFX_2; break; case TEXT_16: /* probably a 16-color text mode, got to detect mono mode somehow */ - width<<=3; /* 8 bit wide text font */ - vga.draw.font_height=vga.config.vline_height+1; - height<<=4; + width<<=3; /* 8 bit wide text font */ if (width>640) width=640; if (height>480) height=480; pitch=width; - renderer=&VGA_Render_TEXT_16; }; + if (vga.draw.double_height) { + flags|=DoubleHeight; + height/=2; + } + if (vga.draw.double_width) { + flags|=DoubleWidth; + /* Double width is dividing main clock, the width should be correct already for this */ + } + if (( width != vga.draw.width) || (height != vga.draw.height) || (pitch != vga.draw.pitch)) { + PIC_RemoveEvents(VGA_BlankTimer); + vga.draw.width=width; + vga.draw.height=height; + vga.draw.pitch=pitch; - vga.draw.width=width; - vga.draw.height=height; - RENDER_SetSize(width,height,8,pitch,((float)width/(float)height),0,renderer); - + LOG_VGA("Width %d, Height %d",width,height); + LOG_VGA("Flags %X, fps %f",flags,fps); + RENDER_SetSize(width,height,8,pitch,((float)width/(float)height),flags); + vga.draw.blank=(Bitu)(1000000/fps); + PIC_AddEvent(VGA_BlankTimer,vga.draw.blank); + } }; void VGA_StartResize(void) { if (!vga.draw.resizing) { vga.draw.resizing=true; /* Start a resize after 50 ms */ - PIC_AddEvent(VGA_DoResize,500); + PIC_AddEvent(VGA_DoResize,50000); } } - void VGA_Init(Section* sec) { vga.draw.resizing=false; VGA_SetupMemory(); diff --git a/src/hardware/vga.h b/src/hardware/vga.h index 4d3427d5..24537a4d 100644 --- a/src/hardware/vga.h +++ b/src/hardware/vga.h @@ -1,4 +1,4 @@ -/* + /* * Copyright (C) 2002 The DOSBox Team * * This program is free software; you can redistribute it and/or modify @@ -42,9 +42,11 @@ typedef struct { bool retrace; /* A retrace has started */ Bitu scan_len; -/* Screen resolution and memory mode */ - Bitu vdisplayend; - Bitu hdisplayend; +/* Some other screen related variables */ + Bitu line_compare; + + Bitu clock; + bool clock_half; bool chained; /* Enable or Disabled Chain 4 Mode */ bool gfxmode; /* Yes or No Easy no */ @@ -56,7 +58,6 @@ typedef struct { bool vline_double; Bit8u vline_height; - bool pixel_double; /* Pixel Scrolling */ Bit8u pel_panning; /* Amount of pixels to skip when starting horizontal line */ Bit8u hlines_skip; @@ -85,12 +86,16 @@ typedef struct { bool resizing; Bitu width; Bitu height; + Bitu pitch; + Bitu blank; + bool double_width; + bool double_height; + Bitu lines; Bit8u * font; Bit8u font_height; - Bit8u cursor_enable; - Bit8u cursor_row; - Bit8u cursor_col; - Bit8u cursor_count; + struct { + Bitu row,col,sline,eline,count; + } cursor; } VGA_Draw; @@ -170,7 +175,8 @@ typedef struct { Bit8u pel_mask; Bit8u pel_index; Bit8u state; - Bit8u index; + Bit8u write_index; + Bit8u read_index; Bitu first_changed; RGBEntry rgb[0x100]; Bit8u attr[16]; @@ -202,8 +208,8 @@ typedef struct { VGA_Dac dac; VGA_Latch latch; VGA_Memory mem; -//Special little hack to let the memory run over into the buffer - Bit8u buffer[1024*1024]; +/* Extra buffer following main video ram with double data for overflowing of addresses */ + Bit8u buffer[1024*1024]; /* 256 kb vid ram with 16 colors and double addresses */ } VGA_Type; @@ -217,11 +223,10 @@ void VGA_StartResize(void); /* The Different Drawing functions */ void VGA_DrawTEXT(Bit8u * bitdata,Bitu next_line); -void VGA_DrawGFX256_Fast(Bit8u * bitdata,Bitu next_line); -void VGA_DrawGFX256_Full(Bit8u * bitdata,Bitu next_line); -void VGA_DrawGFX16_Full(Bit8u * bitdata,Bitu next_line); -void VGA_DrawGFX4_Full(Bit8u * bitdata,Bitu next_line); -void VGA_DrawGFX2_Full(Bit8u * bitdata,Bitu next_line); +void VGA_DrawGFX256U_Full(Bit8u * bitdata,Bitu next_line); +void VGA_DrawGFX16_Fast(Bit8u * bitdata,Bitu next_line); +void VGA_DrawGFX4_Fast(Bit8u * bitdata,Bitu next_line); +void VGA_DrawGFX2_Fast(Bit8u * bitdata,Bitu next_line); /* The Different Memory Read/Write Handlers */ Bit8u VGA_NormalReadHandler(Bit32u start); diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 953b4521..4bd43051 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -49,10 +49,12 @@ void write_p3c0(Bit32u port,Bit8u val) { */ break; case 0x10: /* Mode Control Register */ - attr(mode_control)=val; - vga.config.gfxmode=val&1; - vga.config.vga_enabled=(val & 64)>0; - VGA_FindSettings(); + if (val != attr(mode_control)) { + attr(mode_control)=val; + vga.config.gfxmode=val&1; + vga.config.vga_enabled=(val & 0x40)>0; + VGA_FindSettings(); + } //TODO Monochrome mode //TODO 9 bit characters //TODO line wrapping split screen shit see bit 5 diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 020866c9..588f900b 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -40,9 +40,10 @@ void write_p3d5(Bit32u port,Bit8u val) { /* 0-7 Horizontal Total Character Clocks-5 */ break; case 0x01: /* Horizontal Display End Register */ - crtc(horizontal_display_end)=val; - vga.config.hdisplayend=val+1; - VGA_StartResize(); + if (val != crtc(horizontal_display_end)) { + crtc(horizontal_display_end)=val; + VGA_StartResize(); + } /* 0-7 Number of Character Clocks Displayed -1 */ break; case 0x02: /* Start Horizontal Blanking Register */ @@ -75,7 +76,10 @@ void write_p3d5(Bit32u port,Bit8u val) { */ break; case 0x06: /* Vertical Total Register */ - crtc(vertical_total)=val; + if (val != crtc(vertical_total)) { + crtc(vertical_total)=val; + VGA_StartResize(); + } /* 0-7 Lower 8 bits of the Vertical Total. Bit 8 is found in 3d4h index 7 bit 0. Bit 9 is found in 3d4h index 7 bit 5. Note: For the VGA this value is the number of scan lines in the display -2. @@ -83,8 +87,11 @@ void write_p3d5(Bit32u port,Bit8u val) { break; case 0x07: /* Overflow Register */ crtc(overflow)=val; - vga.config.vdisplayend=(vga.config.vdisplayend&0xFF)|(((val>>1) & 1)<<8)|(((val>>6) & 1)<<9); - VGA_StartResize(); + vga.config.line_compare=(vga.config.line_compare & 0x2ff) | (val & 0x10) << 4; + if ((vga.crtc.overflow ^ val) & 0xef) { + crtc(overflow)=val; + VGA_StartResize(); + } else crtc(overflow)=val; /* 0 Bit 8 of Vertical Total (3d4h index 6) 1 Bit 8 of Vertical Display End (3d4h index 12h) @@ -110,10 +117,13 @@ void write_p3d5(Bit32u port,Bit8u val) { */ break; case 0x09: /* Maximum Scan Line Register */ - crtc(maximum_scan_line)=val; vga.config.vline_double=(val & 128)>1; vga.config.vline_height=(val & 0xf); - VGA_StartResize(); + vga.config.line_compare=(vga.config.line_compare & 0x1ff)|(val&0x40)<<3; + if ((vga.crtc.maximum_scan_line ^ val) & 0xbf) { + crtc(maximum_scan_line)=val; + VGA_StartResize(); + } else crtc(maximum_scan_line)=val; /* 0-4 Number of scan lines in a character row -1. In graphics modes this is the number of times (-1) the line is displayed before passing on to @@ -152,16 +162,16 @@ void write_p3d5(Bit32u port,Bit8u val) { case 0x0E: /*Cursor Location High Register */ crtc(cursor_location_high)=val; if (vga.config.scan_len<2) break; - vga.draw.cursor_row=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))/(vga.config.scan_len*2); - vga.draw.cursor_col=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))%(vga.config.scan_len*2); + vga.draw.cursor.row=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))/(vga.config.scan_len*2); + vga.draw.cursor.col=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))%(vga.config.scan_len*2); /* 0-7 Upper 8 bits of the address of the cursor */ break; case 0x0F: /* Cursor Location Low Register */ //TODO update cursor on screen crtc(cursor_location_low)=val; if (vga.config.scan_len<2) break; - vga.draw.cursor_row=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))/(vga.config.scan_len*2); - vga.draw.cursor_col=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))%(vga.config.scan_len*2); + vga.draw.cursor.row=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))/(vga.config.scan_len*2); + vga.draw.cursor.col=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))%(vga.config.scan_len*2); /* 0-7 Lower 8 bits of the address of the cursor */ break; case 0x10: /* Vertical Retrace Start Register */ @@ -186,9 +196,10 @@ void write_p3d5(Bit32u port,Bit8u val) { */ break; case 0x12: /* Vertical Display End Register */ - crtc(vertical_display_end)=val; - vga.config.vdisplayend=(vga.config.vdisplayend & 0x300)|val; - VGA_StartResize(); + if (val!=crtc(vertical_display_end)) { + crtc(vertical_display_end)=val; + VGA_StartResize(); + } /* 0-7 Lower 8 bits of Vertical Display End. The display ends when the line counter reaches this value. Bit 8 is found in 3d4h index 7 bit 1. @@ -196,9 +207,11 @@ void write_p3d5(Bit32u port,Bit8u val) { */ break; case 0x13: /* Offset register */ - crtc(offset)=val; - vga.config.scan_len=val; - VGA_StartResize(); + if (val!=crtc(offset)) { + crtc(offset)=val; + vga.config.scan_len=val; + VGA_StartResize(); + } /* 0-7 Number of bytes in a scanline / K. Where K is 2 for byte mode, 4 for word mode and 8 for Double Word mode. @@ -228,9 +241,11 @@ void write_p3d5(Bit32u port,Bit8u val) { */ break; case 0x17: /* Mode Control Register */ - crtc(mode_control)=val; - vga.config.cga_enabled=!((val&1)>0); - VGA_FindSettings(); + if (val!=crtc(mode_control)) { + crtc(mode_control)=val; + vga.config.cga_enabled=!((val&1)>0); + VGA_FindSettings(); + } /* 0 If clear use CGA compatible memory addressing system by substituting character row scan counter bit 0 for address bit 13, @@ -249,6 +264,7 @@ void write_p3d5(Bit32u port,Bit8u val) { break; case 0x18: /* Line Compare Register */ crtc(line_compare)=val; + vga.config.line_compare=(vga.config.line_compare & 0x300) | val; /* 0-7 Lower 8 bits of the Line Compare. When the Line counter reaches this value, the display address wraps to 0. Provides Split Screen diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index d8e0ae2a..a4b400c5 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -65,13 +65,13 @@ static Bit8u read_p3c6(Bit32u port) { static void write_p3c7(Bit32u port,Bit8u val) { - vga.dac.index=val; + vga.dac.read_index=val; vga.dac.pel_index=0; vga.dac.state=DAC_READ; } static void write_p3c8(Bit32u port,Bit8u val) { - vga.dac.index=val; + vga.dac.write_index=val; vga.dac.pel_index=0; vga.dac.state=DAC_WRITE; } @@ -79,36 +79,36 @@ static void write_p3c8(Bit32u port,Bit8u val) { static void write_p3c9(Bit32u port,Bit8u val) { switch (vga.dac.pel_index) { case 0: - vga.dac.rgb[vga.dac.index].red=val; + vga.dac.rgb[vga.dac.write_index].red=val; vga.dac.pel_index=1; break; case 1: - vga.dac.rgb[vga.dac.index].green=val; + vga.dac.rgb[vga.dac.write_index].green=val; vga.dac.pel_index=2; break; case 2: - vga.dac.rgb[vga.dac.index].blue=val; + vga.dac.rgb[vga.dac.write_index].blue=val; switch (vga.mode) { case GFX_256C: case GFX_256U: - RENDER_SetPal(vga.dac.index, - vga.dac.rgb[vga.dac.index].red << 2, - vga.dac.rgb[vga.dac.index].green << 2, - vga.dac.rgb[vga.dac.index].blue << 2 + RENDER_SetPal(vga.dac.write_index, + vga.dac.rgb[vga.dac.write_index].red << 2, + vga.dac.rgb[vga.dac.write_index].green << 2, + vga.dac.rgb[vga.dac.write_index].blue << 2 ); break; default: /* Check for attributes and DAC entry link */ for (Bitu i=0;i<16;i++) { - if (vga.dac.attr[i]==vga.dac.index) { + if (vga.dac.attr[i]==vga.dac.write_index) { RENDER_SetPal(i, - vga.dac.rgb[vga.dac.index].red << 2, - vga.dac.rgb[vga.dac.index].green << 2, - vga.dac.rgb[vga.dac.index].blue << 2); + vga.dac.rgb[vga.dac.write_index].red << 2, + vga.dac.rgb[vga.dac.write_index].green << 2, + vga.dac.rgb[vga.dac.write_index].blue << 2); } } } - vga.dac.index++; + vga.dac.write_index++; vga.dac.pel_index=0; break; default: @@ -120,16 +120,16 @@ static Bit8u read_p3c9(Bit32u port) { Bit8u ret; switch (vga.dac.pel_index) { case 0: - ret=vga.dac.rgb[vga.dac.index].red; + ret=vga.dac.rgb[vga.dac.read_index].red; vga.dac.pel_index=1; break; case 1: - ret=vga.dac.rgb[vga.dac.index].green; + ret=vga.dac.rgb[vga.dac.read_index].green; vga.dac.pel_index=2; break; case 2: - ret=vga.dac.rgb[vga.dac.index].blue; - vga.dac.index++; + ret=vga.dac.rgb[vga.dac.read_index].blue; + vga.dac.read_index++; vga.dac.pel_index=0; break; default: @@ -155,6 +155,8 @@ void VGA_SetupDAC(void) { vga.dac.pel_mask=0xff; vga.dac.pel_index=0; vga.dac.state=DAC_READ; + vga.dac.read_index=0; + vga.dac.write_index=0; /* Setup the DAC IO port Handlers */ IO_RegisterWriteHandler(0x3c6,write_p3c6,"PEL Mask"); diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 1a120999..006b1e13 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -21,45 +21,11 @@ #include "video.h" #include "vga.h" +//TODO Make the full draw like the vga really does from video memory. -/* This Should draw a complete 16 colour screen */ -void VGA_Render_GFX_2(Bit8u * * data) { - *data=vga.buffer; - VGA_DrawGFX2_Full(vga.buffer,vga.draw.width); - VGA_StartRetrace(); -} - -void VGA_Render_GFX_4(Bit8u * * data) { - *data=vga.buffer; - VGA_DrawGFX4_Full(vga.buffer,vga.draw.width); - VGA_StartRetrace(); -} - -void VGA_Render_GFX_16(Bit8u * * data) { -// *data=&vga.buffer[vga.config.display_start*8+vga.config.pel_panning]; - *data=&vga.buffer[vga.config.real_start*8+vga.config.pel_panning]; - VGA_StartRetrace(); -} - -void VGA_Render_GFX_256U(Bit8u * * data) { -// *data=&vga.mem.linear[vga.config.display_start*4+vga.config.pel_panning]; - *data=&vga.mem.linear[vga.config.real_start*4+vga.config.pel_panning]; - VGA_StartRetrace(); -} - -void VGA_Render_GFX_256C(Bit8u * * data) { - *data=memory+0xa0000; - VGA_StartRetrace(); -} - -void VGA_Render_TEXT_16(Bit8u * * data) { - *data=vga.buffer; - if (data && !vga.draw.resizing) VGA_DrawTEXT(vga.buffer,vga.draw.width); - VGA_StartRetrace(); -} - -void VGA_DrawGFX2_Full(Bit8u * bitdata,Bitu pitch) { +void VGA_DrawGFX2_Fast(Bit8u * bitdata,Bitu pitch) { Bit8u * reader=HostMake(0xB800,0); + Bit8u * flip=HostMake(0xB800,8*1024); Bit8u * draw; for (Bitu y=0;y>3;x++) { + for (Bit32u x=vga.draw.width>>3;x>0;x--) { Bit8u val=*(tempread++); *(draw+0)=(val>>7)&1; *(draw+1)=(val>>6)&1; @@ -83,14 +49,12 @@ void VGA_DrawGFX2_Full(Bit8u * bitdata,Bitu pitch) { draw+=8; } bitdata+=pitch; - }; - VGA_StartRetrace(); + } } - - -void VGA_DrawGFX4_Full(Bit8u * bitdata,Bitu pitch) { - Bit8u * reader=HostMake(0xB800,0); +void VGA_DrawGFX4_Fast(Bit8u * bitdata,Bitu pitch) { + Bit8u * reader=HostMake(0xB800,vga.config.display_start*2); + Bit8u * flip=HostMake(0xB800,8*1024); Bit8u * draw; for (Bitu y=0;y=flip) reader-=8*1024; + } draw=bitdata; for (Bit32u x=0;x>2;x++) { Bit8u val=*(tempread++); @@ -106,12 +71,10 @@ void VGA_DrawGFX4_Full(Bit8u * bitdata,Bitu pitch) { draw+=4; } bitdata+=pitch; - }; - VGA_StartRetrace(); + } } /* Draw the screen using the lookup buffer */ -//TODO include split screen or something void VGA_DrawGFX16_Fast(Bit8u * bitdata,Bitu next_line) { Bit8u * reader=&vga.buffer[vga.config.display_start*8+vga.config.pel_panning]; for (Bitu y=0;y=vga.draw.width) return; - if (((Bitu)vga.draw.cursor_row*16)>=vga.draw.height) return; - Bit8u * cursor_draw=bitdata+(vga.draw.cursor_row*16+15)*pitch+vga.draw.cursor_col*8; - if (vga.draw.cursor_count>8) { - for (Bit8u loop=0;loop<8;loop++) *cursor_draw++=15; - } - vga.draw.cursor_count++; - if (vga.draw.cursor_count>16) vga.draw.cursor_count=0; + if(!(vga.internal.cursor & 0x2000)) { + /* Draw a cursor */ + if (((Bitu)vga.draw.cursor.col*8)>=vga.draw.width) return; + if (((Bitu)vga.draw.cursor.row*16)>=vga.draw.height) return; + Bit8u * cursor_draw=bitdata+(vga.draw.cursor.row*16+15)*pitch+vga.draw.cursor.col*8; + if (vga.draw.cursor.count>8) { + for (Bit8u loop=0;loop<8;loop++) *cursor_draw++=15; + } + vga.draw.cursor.count++; + if (vga.draw.cursor.count>16) vga.draw.cursor.count=0; } }; diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index ff7b6a1c..a6e00d23 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -70,6 +70,7 @@ void write_p3cf(Bit32u port,Bit8u val) { case 3: /* Data Rotate */ gfx(data_rotate)=val; vga.config.data_rotate=val & 7; + if (vga.config.data_rotate) LOG_WARN("VGA:Data Rotate used %d",val &7); vga.config.raster_op=(val>>3) & 3; /* 0-2 Number of positions to rotate data right before it is written to diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index c0ed8229..32af55b0 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -92,20 +92,21 @@ INLINE static Bit32u ModeOperation(Bit8u val) { } Bit8u VGA_GFX_4_ReadHandler(Bit32u start) { - return vga.mem.linear[start]; + return vga.mem.linear[start-0xb8000]; } void VGA_GFX_4_WriteHandler(Bit32u start,Bit8u val) { - start-=0xa0000; + start-=0xb8000; vga.mem.linear[start]=val; - Bitu line=start / 320; - Bitu x=start % 320; - Bit8u * draw=&vga.buffer[start<<2]; + Bitu off; + if (start>0x2000) off=320*(((start-0x2000)/80)*2+1)+((start-0x2000) % 80)*4; + else off=320*(((start)/80)*2)+(start % 80)*4; + Bit32u * draw=(Bit32u *)&vga.buffer[off]; /* TODO Could also use a Bit32u lookup table for this */ - *(draw+0)=(val>>6)&3; - *(draw+1)=(val>>4)&3; - *(draw+2)=(val>>2)&3; - *(draw+3)=(val)&3; + *draw=CGAWriteTable[val]; + draw=(Bit32u *)&vga.buffer[off+0x4000*4]; + *draw=CGAWriteTable[val]; + } void VGA_GFX_16_WriteHandler(Bit32u start,Bit8u val) { diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index f8ed0c79..9202e913 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -58,7 +58,8 @@ static void write_p3d8(Bit32u port,Bit8u val) { static void write_p3c2(Bit32u port,Bit8u val) { p3c2data=val; - if (val & 1) { + + if (val & 0x1) { IO_RegisterWriteHandler(0x3d4,write_p3d4,"VGA:CRTC Index Select"); IO_RegisterReadHandler(0x3d4,read_p3d4,"VGA:CRTC Index Select"); IO_RegisterWriteHandler(0x3d5,write_p3d5,"VGA:CRTC Data Register"); @@ -77,6 +78,11 @@ static void write_p3c2(Bit32u port,Bit8u val) { IO_FreeWriteHandler(0x3d5); IO_FreeReadHandler(0x3d5); } + if (val & 0x4) vga.config.clock=28322000; + else vga.config.clock=25175000; + + VGA_StartResize(); + /* 0 If set Color Emulation. Base Address=3Dxh else Mono Emulation. Base Address=3Bxh. 2-3 Clock Select. 0: 25MHz, 1: 28MHz diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 9a7aa0c8..15f0aa46 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -36,9 +36,10 @@ void write_p3c5(Bit32u port,Bit8u val) { seq(reset)=val; break; case 1: /* Clocking Mode */ - seq(clocking_mode)=val; - vga.config.pixel_double=(val & 8)>0; - VGA_FindSettings(); + if (val!=seq(clocking_mode)) { + seq(clocking_mode)=val; + VGA_StartResize(); + } /* TODO Figure this out :) 0 If set character clocks are 8 dots wide, else 9. 2 If set loads video serializers every other character From 565b8119e4c83432e3916c6b838d6bcc346ad472 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 22 Dec 2002 15:22:22 +0000 Subject: [PATCH 0514/4131] Support for doubling of width/height/both. Moved frame skipping in here. Support for direct rendering to display depth. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@592 --- src/gui/render.cpp | 211 +++++++++++++++++++++++------------- src/gui/render_support.h | 226 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 365 insertions(+), 72 deletions(-) create mode 100644 src/gui/render_support.h diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 0edcb9a3..42235c18 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -26,9 +26,10 @@ #include "keyboard.h" #include "cross.h" + #define MAX_RES 2048 - +typedef void (* RENDER_Part_Handler)(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy); struct PalData { struct { @@ -39,6 +40,10 @@ struct PalData { } rgb[256]; Bitu first; Bitu last; + union { + Bit32u bpp32[256]; + Bit16u bpp16[256]; + } lookup; }; @@ -48,18 +53,40 @@ static struct { Bitu height; Bitu bpp; Bitu pitch; + Bitu flags; float ratio; + RENDER_Part_Handler part_handler; } src; + struct { + Bitu width; + Bitu height; + Bitu pitch; + Bitu next_line; + Bitu next_pixel; + Bitu bpp; /* The type of BPP the operation requires for input */ + RENDER_Operation want_type; + RENDER_Operation type; + void * dest; + void * buffer; + void * pixels; + } op; + struct { + Bitu count; + Bitu max; + } frameskip; Bitu flags; - RENDER_Handler * handler; - Bitu stretch_x[MAX_RES]; - Bitu stretch_y[MAX_RES]; PalData pal; - bool remake; - bool enlarge; + bool keep_small; bool screenshot; + bool active; } render; +/* Forward declerations */ +static void RENDER_ResetPal(void); + +/* Include the different rendering routines */ +#include "render_support.h" + static const char * snapshots_dir; /* Take a screenshot of the data that should be rendered */ @@ -150,7 +177,6 @@ static void TakeScreenShot(Bit8u * bitmap) { /*clean up dynamically allocated RAM.*/ free(row_pointers); - } @@ -158,56 +184,38 @@ static void TakeScreenShot(Bit8u * bitmap) { /* This could go kinda bad with multiple threads */ static void Check_Palette(void) { if (render.pal.first>render.pal.last) return; - - GFX_SetPalette(render.pal.first,render.pal.last-render.pal.first+1,(GFX_PalEntry *)&render.pal.rgb[render.pal.first]); + switch (render.op.bpp) { + case 8: + GFX_SetPalette(render.pal.first,render.pal.last-render.pal.first+1,(GFX_PalEntry *)&render.pal.rgb[render.pal.first]); + break; + case 16: + for (;render.pal.first<=render.pal.last;render.pal.first++) { + render.pal.lookup.bpp16[render.pal.first]=GFX_GetRGB( + render.pal.rgb[render.pal.first].red, + render.pal.rgb[render.pal.first].green, + render.pal.rgb[render.pal.first].blue); + } + break; + case 32: + for (;render.pal.first<=render.pal.last;render.pal.first++) { + render.pal.lookup.bpp32[render.pal.first]= + GFX_GetRGB( + render.pal.rgb[render.pal.first].red, + render.pal.rgb[render.pal.first].green, + render.pal.rgb[render.pal.first].blue); + } + break; + }; + /* Setup pal index to startup values */ render.pal.first=256; render.pal.last=0; } -static void MakeTables(void) { - //The stretching tables - Bitu i;Bit32u c,a; - c=0;a=(render.src.width<<16)/gfx_info.width; - for (i=0;i> 16; - } - c=0;a=(render.src.height<<16)/gfx_info.height; - for (i=0;i>16)*render.src.pitch; - } +static void RENDER_ResetPal(void) { + render.pal.first=0; + render.pal.last=255; } -static void Draw_8_Normal(Bit8u * src_data,Bit8u * dst_data) { - for (Bitu y=0;y0) render.frameskip.max--; + LOG_MSG("Frame Skip at %d",render.frameskip.max); +} + + void RENDER_Init(Section * sec) { Section_prop * section=static_cast(sec); snapshots_dir=section->Get_string("snapshots"); + render.pal.first=256; render.pal.last=0; - render.enlarge=false; + render.keep_small=section->Get_bool("keepsmall"); + render.frameskip.max=section->Get_int("frameskip"); + render.frameskip.count=0; KEYBOARD_AddEvent(KBD_f5,CTRL_PRESSED,EnableScreenShot); + KEYBOARD_AddEvent(KBD_f7,CTRL_PRESSED,DecreaseFrameSkip); + KEYBOARD_AddEvent(KBD_f8,CTRL_PRESSED,IncreaseFrameSkip); } diff --git a/src/gui/render_support.h b/src/gui/render_support.h new file mode 100644 index 00000000..89a99645 --- /dev/null +++ b/src/gui/render_support.h @@ -0,0 +1,226 @@ +static void Render_Normal_8_None(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=render.op.pitch-dx; + Bitu rem=dx&3;dx>>=2; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit32u temp=*(Bit32u *)src;src+=4; + *(Bit32u *)dest=temp; + dest+=4; + } + for (tempx=rem;tempx>0;tempx--) { + *dest++=*src++; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_8_DoubleWidth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x*2; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=render.op.pitch-dx*2; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + *dest=*src;*(dest+1)=*src; + src++;dest+=2; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_8_DoubleHeight(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=(2*render.op.pitch)-dx; + Bitu rem=dx&3;dx>>=2; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit32u temp=*(Bit32u *)src;src+=4; + *(Bit32u *)dest=temp; + *(Bit32u *)(dest+render.op.pitch)=temp; + dest+=4; + } + for (tempx=rem;tempx>0;tempx--) { + *dest=*src; + *(dest+render.op.pitch)=*src; + dest++; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_8_DoubleBoth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=(2*render.op.pitch)-dx*2; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit8u val=src[0];src++; + dest[0]=val;dest[1]=val; + dest[render.op.pitch]=val;dest[render.op.pitch+1]=val; + dest+=2; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_16_None(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=render.op.pitch-dx*2; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit16u val=render.pal.lookup.bpp16[src[0]];src++; + *(Bit16u *)dest=val; + dest+=2; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_16_DoubleWidth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x*4; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=render.op.pitch-dx*4; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit16u val=render.pal.lookup.bpp16[src[0]];src++; + *(Bit16u *)dest=val; + *(Bit16u *)(dest+2)=val; + dest+=4; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_16_DoubleHeight(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x*2; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=(2*render.op.pitch)-dx*2; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit16u val=render.pal.lookup.bpp16[src[0]];src++; + *(Bit16u *)dest=val; + *(Bit16u *)(dest+render.op.pitch)=val; + dest+=2; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_16_DoubleBoth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x*4; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=(2*render.op.pitch)-dx*4; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit16u val=render.pal.lookup.bpp16[src[0]];src++; + *(Bit16u *)(dest+0)=val; + *(Bit16u *)(dest+2)=val; + *(Bit16u *)(dest+render.op.pitch)=val; + *(Bit16u *)(dest+render.op.pitch+2)=val; + dest+=4; + } + src+=next_src;dest+=next_dest; + } +} + + +static void Render_Normal_32_None(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x*4; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=render.op.pitch-dx*4; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit32u val=render.pal.lookup.bpp32[src[0]];src++; + *(Bit32u *)dest=val; + dest+=4; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_32_DoubleWidth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x*8; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=render.op.pitch-dx*8; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit32u val=render.pal.lookup.bpp32[src[0]];src++; + *(Bit32u *)dest=val; + *(Bit32u *)(dest+4)=val; + dest+=8; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_32_DoubleHeight(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x*4; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=(2*render.op.pitch)-dx*4; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit32u val=render.pal.lookup.bpp32[src[0]];src++; + *(Bit32u *)dest=val; + *(Bit32u *)(dest+render.op.pitch)=val; + dest+=4; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_32_DoubleBoth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x*8; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=(2*render.op.pitch)-dx*8; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit32u val=render.pal.lookup.bpp32[src[0]];src++; + *(Bit32u *)(dest+0)=val; + *(Bit32u *)(dest+4)=val; + *(Bit32u *)(dest+render.op.pitch)=val; + *(Bit32u *)(dest+render.op.pitch+4)=val; + dest+=8; + } + src+=next_src;dest+=next_dest; + } +} + + +static RENDER_Part_Handler Render_Normal_8_Table[4]= { + Render_Normal_8_None,Render_Normal_8_DoubleWidth,Render_Normal_8_DoubleHeight,Render_Normal_8_DoubleBoth +}; + +static RENDER_Part_Handler Render_Normal_16_Table[4]= { + Render_Normal_16_None,Render_Normal_16_DoubleWidth,Render_Normal_16_DoubleHeight,Render_Normal_16_DoubleBoth +}; + +static RENDER_Part_Handler Render_Normal_32_Table[4]= { + Render_Normal_32_None,Render_Normal_32_DoubleWidth,Render_Normal_32_DoubleHeight,Render_Normal_32_DoubleBoth +}; + + +static void Render_Normal_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags) { + if (!(flags & MODE_SET)) return; + render.op.width=width; + render.op.height=height; + render.op.bpp=bpp; + render.op.pitch=pitch; + switch (bpp) { + case 8: + render.src.part_handler=Render_Normal_8_Table[render.src.flags]; + break; + case 16: + render.src.part_handler=Render_Normal_16_Table[render.src.flags]; + break; + case 32: + render.src.part_handler=Render_Normal_32_Table[render.src.flags]; + break; + default: + E_Exit("RENDER:Unsupported display depth of %d",bpp); + break; + } + RENDER_ResetPal(); +} \ No newline at end of file From 3442926a797fdc117ad52935b8c25a27fd71770c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 22 Dec 2002 15:22:59 +0000 Subject: [PATCH 0515/4131] Removed frame skipping support. Added support for special flags when setting up resolution, to support the new rendering operations. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@593 --- src/gui/sdlmain.cpp | 127 +++++++++++++++----------------------------- 1 file changed, 44 insertions(+), 83 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 746b43b4..41b81fad 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -37,12 +37,11 @@ struct SDL_Block { Bitu width; Bitu height; Bitu bpp; - GFX_DrawHandler * draw; - GFX_ResizeHandler * resize; + Bitu flags; + GFX_ModeCallBack mode_callback; bool full_screen; SDL_Surface * surface; SDL_Joystick * joy; - SDL_Color pal[256]; struct { bool autolock; bool autoenable; @@ -50,62 +49,48 @@ struct SDL_Block { bool locked; Bitu sensitivity; } mouse; - struct { - Bitu skip; - Bitu count; - } frames ; }; static SDL_Block sdl; +static void CaptureMouse(void); -GFX_Info gfx_info; - -static void RestorePalette(void) { - if (sdl.bpp!=8) return; -/* Use some other way of doing this */ - if (sdl.full_screen) { - if (!SDL_SetPalette(sdl.surface,SDL_PHYSPAL,sdl.pal,0,256)) { - E_Exit("SDL:Can't set palette"); - } - } else { - if (!SDL_SetPalette(sdl.surface,SDL_LOGPAL,sdl.pal,0,256)) { - E_Exit("SDL:Can't set palette"); - } - } - return; -} /* Reset the screen with current values in the sdl structure */ static void ResetScreen(void) { + GFX_Stop(); if (sdl.full_screen) { /* First get the original resolution */ - sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_SWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN); + sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN); } else { - sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_SWSURFACE|SDL_RESIZABLE); + if (sdl.flags & GFX_FIXED_BPP) sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE); + else sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,0,SDL_HWSURFACE); } if (sdl.surface==0) { E_Exit("SDL:Would be nice if I could get a surface."); } SDL_WM_SetCaption(VERSION,VERSION); /* also fill up gfx_info structure */ - gfx_info.width=sdl.width; - gfx_info.height=sdl.height; - gfx_info.bpp=sdl.bpp; - gfx_info.pitch=sdl.surface->pitch; - RestorePalette(); + Bitu flags=MODE_SET; + if (sdl.full_screen) flags|=MODE_FULLSCREEN; + if (sdl.mode_callback) sdl.mode_callback(sdl.surface->w,sdl.surface->h,sdl.surface->format->BitsPerPixel,sdl.surface->pitch,flags); + GFX_Start(); } -void GFX_Resize(Bitu width,Bitu height,Bitu bpp,GFX_ResizeHandler * resize) { +void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu flags,GFX_ModeCallBack callback) { GFX_Stop(); sdl.width=width; sdl.height=height; sdl.bpp=bpp; - sdl.resize=resize; + sdl.flags=flags; + sdl.mode_callback=callback; ResetScreen(); GFX_Start(); } -static void CaptureMouse() { + + + +static void CaptureMouse(void) { sdl.mouse.locked=!sdl.mouse.locked; if (sdl.mouse.locked) { SDL_WM_GrabInput(SDL_GRAB_ON); @@ -116,48 +101,38 @@ static void CaptureMouse() { } } -static void DecreaseSkip() { - if (sdl.frames.skip>0) sdl.frames.skip--; - LOG_MSG("Frame Skip %d",sdl.frames.skip); -} - -static void IncreaseSkip() { - if (sdl.frames.skip<10) sdl.frames.skip++; - LOG_MSG("Frame Skip %d",sdl.frames.skip); -} - static void SwitchFullScreen(void) { - GFX_Stop(); sdl.full_screen=!sdl.full_screen; if (sdl.full_screen) { - if (sdl.resize) { - sdl.width=0;sdl.height=0; - (*sdl.resize)(&sdl.width,&sdl.height); - } - // be sure not to dont draw sdl mouse - SDL_ShowCursor(SDL_DISABLE); +//TODO Give an resize event + if (!sdl.mouse.locked) CaptureMouse(); + } else { + if (sdl.mouse.locked) CaptureMouse(); } + ResetScreen(); - GFX_Start(); } //only prototype existed void GFX_SwitchFullScreen(void) { SwitchFullScreen(); } -static void GFX_Redraw() { - if (++sdl.frames.countpixels && sdl.draw) (*sdl.draw)((Bit8u *)sdl.surface->pixels); - SDL_UnlockSurface(sdl.surface ); - if (sdl.full_screen) SDL_Flip(sdl.surface); - else SDL_UpdateRect(sdl.surface,0,0,0,0); - }; -skipframe:; + if (SDL_MUSTLOCK(sdl.surface)) if (SDL_LockSurface(sdl.surface)) return 0; + return sdl.surface->pixels; + } else { + return 0; + } } +void GFX_EndUpdate(void) { + if (SDL_MUSTLOCK(sdl.surface)) SDL_UnlockSurface(sdl.surface ); + if (sdl.full_screen) SDL_Flip(sdl.surface); + else SDL_UpdateRect(sdl.surface,0,0,0,0); +} + + void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries) { /* I should probably not change the GFX_PalEntry :) */ if (sdl.full_screen) { @@ -169,12 +144,10 @@ void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries) { E_Exit("SDL:Can't set palette"); } } - /* Copy palette entries into some internal back up table */ - memcpy(&sdl.pal[start],entries,count*sizeof(SDL_Color)); } -void GFX_SetDrawHandler(GFX_DrawHandler * handler) { - sdl.draw=handler; +Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue) { + return SDL_MapRGB(sdl.surface->format,red,green,blue); } void GFX_Stop() { @@ -198,22 +171,16 @@ static void GUI_StartUp(Section * sec) { Section_prop * section=static_cast(sec); sdl.active=false; sdl.full_screen=false; - sdl.frames.skip=0; - sdl.frames.count=0; - sdl.draw=0; sdl.mouse.locked=false; sdl.mouse.requestlock=false; sdl.mouse.autoenable=section->Get_bool("autolock"); sdl.mouse.autolock=false; sdl.mouse.sensitivity=section->Get_int("sensitivity"); - GFX_Resize(640,400,8,0); - TIMER_RegisterMicroHandler(GFX_Redraw,1000000/70); + GFX_SetSize(640,400,8,0,0); SDL_EnableKeyRepeat(250,30); /* Get some Keybinds */ KEYBOARD_AddEvent(KBD_f10,CTRL_PRESSED,CaptureMouse); - KEYBOARD_AddEvent(KBD_f7,CTRL_PRESSED,DecreaseSkip); - KEYBOARD_AddEvent(KBD_f8,CTRL_PRESSED,IncreaseSkip); KEYBOARD_AddEvent(KBD_enter,ALT_PRESSED,SwitchFullScreen); } @@ -421,17 +388,11 @@ static void HandleJoystickButton(SDL_JoyButtonEvent * jbutton) { static void HandleVideoResize(SDL_ResizeEvent * resize) { - Bitu width,height; - width=resize->w; - height=resize->h; - if (sdl.resize) { - GFX_Stop(); - (*sdl.resize)(&width,&height); - sdl.width=width; - sdl.height=height; - ResetScreen(); - GFX_Start(); - } + + + + + } void GFX_Events() { From 0f28c80907ea5c5960fa29c9044987b0a1e56dbf Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 22 Dec 2002 15:23:08 +0000 Subject: [PATCH 0516/4131] Added render_support.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@594 --- src/gui/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 00fc5765..ec0a145a 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -1,5 +1,5 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libgui.a -libgui_a_SOURCES = sdlmain.cpp render.cpp +libgui_a_SOURCES = sdlmain.cpp render.cpp render_support.h From 700d1c6e36e56f5a8cc3c3b17fce7160748646e4 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 22 Dec 2002 15:23:30 +0000 Subject: [PATCH 0517/4131] New rendering and video mode setup functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@595 --- include/render.h | 19 +++++++++++++++++-- include/video.h | 21 ++++++++++++--------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/include/render.h b/include/render.h index 74b8aa15..e7a0b840 100644 --- a/include/render.h +++ b/include/render.h @@ -17,9 +17,24 @@ */ -typedef void RENDER_Handler(Bit8u * * data); +enum RENDER_Operation { + OP_None,OP_2xSai,OP_Scale2x +}; -void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu flags, RENDER_Handler * handler); +enum { + DoubleNone= 0x00, + DoubleWidth= 0x01, + DoubleHeight= 0x02, + DoubleBoth= 0x03 +}; + +bool RENDER_StartUpdate(void); + +void RENDER_EndUpdate(void); + +void RENDER_Part(Bit8u * data,Bitu x,Bitu y,Bitu dx,Bitu dy); + +void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu flags); void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue); diff --git a/include/video.h b/include/video.h index f59d8ec4..d6424129 100644 --- a/include/video.h +++ b/include/video.h @@ -20,9 +20,7 @@ #define __VIDEO_H -typedef void (GFX_DrawHandler)(Bit8u * vidstart); -/* Used to reply to the renderer what size to set */ -typedef void (GFX_ResizeHandler)(Bitu * width,Bitu * height); +typedef void (* GFX_ModeCallBack)(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags); struct GFX_PalEntry { Bit8u r; @@ -31,20 +29,25 @@ struct GFX_PalEntry { Bit8u unused; }; -struct GFX_Info { - Bitu width,height,bpp,pitch; -}; +#define GFX_FIXED_BPP 0x01 +#define GFX_RESIZEABLE 0x02 -extern GFX_Info gfx_info; +#define MODE_SET 0x01 +#define MODE_FULLSCREEN 0x02 +#define MODE_RESIZE 0x04 void GFX_Events(void); void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries); -void GFX_SetDrawHandler(GFX_DrawHandler * handler); -void GFX_Resize(Bitu width,Bitu height,Bitu bpp,GFX_ResizeHandler * resize); + +Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue); +void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu flags,GFX_ModeCallBack callback); void GFX_Start(void); void GFX_Stop(void); void GFX_SwitchFullScreen(void); +void * GFX_StartUpdate(void); +void GFX_EndUpdate(void); + #endif From 4e421529c7a48a55360c941dabf6fa16079e6ae8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 22 Dec 2002 15:24:02 +0000 Subject: [PATCH 0518/4131] render section Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@596 --- src/dosbox.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index d4ab1454..71275e5d 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -169,7 +169,9 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&PROGRAMS_Init); secprop->AddInitFunction(&TIMER_Init); secprop->AddInitFunction(&CMOS_Init); - secprop->AddInitFunction(&RENDER_Init); + secprop=control->AddSection_prop("render",&RENDER_Init); + secprop->Add_int("frameskip",0); + secprop->Add_bool("keepsmall",false); secprop->Add_string("snapshots","snapshots"); secprop=control->AddSection_prop("cpu",&CPU_Init); From 0ee8335de9cd15b96d2bab56e7fb64ae0ab299f3 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 22 Dec 2002 17:02:41 +0000 Subject: [PATCH 0519/4131] Mouse_SetResolution Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@597 --- include/mouse.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/mouse.h b/include/mouse.h index 764d5504..0123ecbe 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -26,4 +26,5 @@ void Mouse_ButtonPressed(Bit8u button); void Mouse_ButtonReleased(Bit8u button); void Mouse_AutoLock(bool enable); +void Mouse_SetResolution(Bit16u width, Bit16u height); From ebc95ab27e5833a51e64cb98cd0b45a2e849ac38 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 22 Dec 2002 17:03:29 +0000 Subject: [PATCH 0520/4131] INT10 tells mouse about resolution change Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@598 --- src/ints/int10_modes.cpp | 3 +++ src/ints/mouse.cpp | 12 +++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index d7a05802..1f578972 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -20,6 +20,7 @@ #include "mem.h" #include "inout.h" #include "int10.h" +#include "mouse.h" //TODO Maybe also add PCJR Video Modes could be nice :) //TODO include some credits to bochs/plex86 bios i used for info/tables @@ -409,6 +410,8 @@ void INT10_SetVideoMode(Bit8u mode) { INT10_SetActivePage(0); /* Set some interrupt vectors */ RealSetVec(0x43,int10_romarea.font_8_first); + /* Tell mouse resolution change */ + Mouse_SetResolution(vga_modes[line].swidth,vga_modes[line].sheight); }; void INT10_SetGfxControllerToDefault() diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 0a962314..8d88ec49 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -388,14 +388,20 @@ static void SetMickeyPixelRate(Bit16s px, Bit16s py) } }; -static void mouse_reset(void) { +void Mouse_SetResolution(Bit16u width, Bit16u height) +{ + mouse.max_x = width-1; + mouse.max_y = height-1; +}; + +static void mouse_reset(void) +{ WriteMouseIntVector(); real_writed(0,(0x74<<2),CALLBACK_RealPointer(call_int74)); mouse.shown=-1; mouse.min_x=0; - mouse.max_x=639; mouse.min_y=0; - mouse.max_y=199; + // Dont set max coordinates here. it is done by SetResolution! mouse.x=0; // civ wont work otherwise mouse.y=100; mouse.events=0; From 3b304c78f37a562005c7854e6a4b2d0468649b32 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 22 Dec 2002 17:20:18 +0000 Subject: [PATCH 0521/4131] removed screenshots update (was in there in 0.56) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@599 --- ChangeLog | 1 - 1 file changed, 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 485705c3..dc4db429 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,7 +27,6 @@ - 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 - - support for screenshots - fixed various bugs when exiting dosbox - fixed a bug in XMS - fixed a bug with the joystick when pressing a button From eb27ac8bbac9c9679a76a9c87c15793d5d183234 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 22 Dec 2002 18:27:40 +0000 Subject: [PATCH 0522/4131] gcc warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@600 --- src/gui/render_support.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/gui/render_support.h b/src/gui/render_support.h index 89a99645..3d91cb0f 100644 --- a/src/gui/render_support.h +++ b/src/gui/render_support.h @@ -4,7 +4,8 @@ static void Render_Normal_8_None(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { Bitu next_dest=render.op.pitch-dx; Bitu rem=dx&3;dx>>=2; for (;dy>0;dy--) { - for (Bitu tempx=dx;tempx>0;tempx--) { + Bitu tempx; + for (tempx=dx;tempx>0;tempx--) { Bit32u temp=*(Bit32u *)src;src+=4; *(Bit32u *)dest=temp; dest+=4; @@ -35,7 +36,8 @@ static void Render_Normal_8_DoubleHeight(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu Bitu next_dest=(2*render.op.pitch)-dx; Bitu rem=dx&3;dx>>=2; for (;dy>0;dy--) { - for (Bitu tempx=dx;tempx>0;tempx--) { + Bitu tempx; + for (tempx=dx;tempx>0;tempx--) { Bit32u temp=*(Bit32u *)src;src+=4; *(Bit32u *)dest=temp; *(Bit32u *)(dest+render.op.pitch)=temp; @@ -223,4 +225,4 @@ static void Render_Normal_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bi break; } RENDER_ResetPal(); -} \ No newline at end of file +} From c8ce5d060518c8304e0aabf9cb4a462a6fb60c19 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 22 Dec 2002 18:35:16 +0000 Subject: [PATCH 0523/4131] smarter startup message Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@601 --- src/shell/shell.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index a59454aa..a27fee09 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -204,7 +204,11 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_DIR_BYTES_FREE","%5d Dir(s) %17s Bytes free\n"); MSG_Add("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\n"); MSG_Add("SHELL_EXECUTE_ILLEGAL_COMMAND","Illegal command: %s.\n"); - MSG_Add("SHELL_STARTUP","DOSBox Shell v" VERSION "\nFor Help and supported commands type: HELP\n\nHAVE FUN!\nThe DOSBox Team\n\n"); +#if defined (WIN32) + MSG_Add("SHELL_STARTUP","DOSBox Shell v" VERSION "\nDOSBox doesn't not run protected mode games!\nFor Help and supported commands type: HELP\n\nHAVE FUN!\nThe DOSBox Team\n\n"); +#else + MSG_Add("SHELL_STARTUP","DOSBox Shell v0.57\nDOSBox doesn't run protected mode games!\nDOSBox only works with upcase filenames as dos is case-insensitive.\nSee the UPCASE command and the README for details\nFor Help and supported commands: HELP\n\nHAVE FUN!\nThe DOSBox Team\n\n"); +#endif MSG_Add("SHELL_CMD_CHDIR_HELP","Change Directory.\n"); MSG_Add("SHELL_CMD_CLS_HELP","Clear screen.\n"); MSG_Add("SHELL_CMD_DIR_HELP","Directory View.\n"); From 80265b0172d0d0dc89f7810c99afd764680bfca6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 22 Dec 2002 18:42:13 +0000 Subject: [PATCH 0524/4131] 0.57 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@602 --- NEWS | 96 ++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 26 deletions(-) diff --git a/NEWS b/NEWS index c39c56cb..037b0609 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,45 @@ -0.56: +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 @@ -18,31 +59,34 @@ - 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: - - changed basedir handling. (linux/winXP) - - added some FCB-calls - - improved support for user mousehandlers - - fixed EGA graphics - - fixed VGA graphics - - fixed the displaying of text in some graphics modes - - fixed write with size 0 - - changed memory management. - - added full emm 3.2 support. - - fixed and cleaned up the cpu flags. - changed interrupt handler. - - speeded up the graphics. - - speeded up the cpu-core - - added new features to the debugger: breakpoint support / data view / command line - - partial support of list of lists (dos info block) - - partial emm 4.0 support - - fixes to graphics core fonts (text in sierra games is now correct) - - changed dma - - improved dma streams from emm memory - - added some cga videomodes - - added more funtions to the keyboard handler + +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: -added F3 to repeat the last typed command. From 4e3869fcb10ff9cef60eb23dde948d85e49c219d Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 22 Dec 2002 20:14:45 +0000 Subject: [PATCH 0525/4131] fixed a problem with mouse resolution Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@603 --- src/ints/mouse.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 8d88ec49..50bcf6ae 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -93,6 +93,7 @@ static struct { Bit16s clipx,clipy; Bit16s hotx,hoty; Bit16u textAndMask, textXorMask; + Bit16u resy; float mickeysPerPixel_x; float mickeysPerPixel_y; @@ -390,8 +391,8 @@ static void SetMickeyPixelRate(Bit16s px, Bit16s py) void Mouse_SetResolution(Bit16u width, Bit16u height) { - mouse.max_x = width-1; - mouse.max_y = height-1; + mouse.resy = height-1; + mouse.shown = -1; // hide cursor }; static void mouse_reset(void) @@ -401,6 +402,8 @@ static void mouse_reset(void) mouse.shown=-1; mouse.min_x=0; mouse.min_y=0; + mouse.max_x=639; + mouse.max_y=mouse.resy; // Dont set max coordinates here. it is done by SetResolution! mouse.x=0; // civ wont work otherwise mouse.y=100; @@ -644,6 +647,7 @@ void MOUSE_Init(Section* sec) { real_writed(0,(0x74<<2),CALLBACK_RealPointer(call_int74)); memset(&mouse,0,sizeof(mouse)); + mouse.resy = 199; // Init with startup value mouse_reset(); } From ab44001619aa0af3d0327c592e26243675f4c963 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 22 Dec 2002 20:42:11 +0000 Subject: [PATCH 0526/4131] New startup message Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@604 --- src/shell/shell.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index a27fee09..323a79b0 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -204,11 +204,18 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_DIR_BYTES_FREE","%5d Dir(s) %17s Bytes free\n"); MSG_Add("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\n"); MSG_Add("SHELL_EXECUTE_ILLEGAL_COMMAND","Illegal command: %s.\n"); -#if defined (WIN32) - MSG_Add("SHELL_STARTUP","DOSBox Shell v" VERSION "\nDOSBox doesn't not run protected mode games!\nFor Help and supported commands type: HELP\n\nHAVE FUN!\nThe DOSBox Team\n\n"); -#else - MSG_Add("SHELL_STARTUP","DOSBox Shell v0.57\nDOSBox doesn't run protected mode games!\nDOSBox only works with upcase filenames as dos is case-insensitive.\nSee the UPCASE command and the README for details\nFor Help and supported commands: HELP\n\nHAVE FUN!\nThe DOSBox Team\n\n"); + + MSG_Add("SHELL_STARTUP","DOSBox Shell v" VERSION "\n" + "DOSBox doesn't not run protected mode games!\n" + "For supported shell commands type: HELP\n" +#if! defined (WIN32) + "DOSBox only works with upcase filenames as dos is case-insensitive.\n" + "You can use the UPCASE command for this, but please be careful.\n" #endif + "For more information read the README file in DOSBox directory.\n" + "\nHAVE FUN!\nThe DOSBox Team\n\n" + ); + MSG_Add("SHELL_CMD_CHDIR_HELP","Change Directory.\n"); MSG_Add("SHELL_CMD_CLS_HELP","Clear screen.\n"); MSG_Add("SHELL_CMD_DIR_HELP","Directory View.\n"); From 26940f77ad6f4e33ae61d2dcae9eadc34aa78ce7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 22 Dec 2002 20:42:43 +0000 Subject: [PATCH 0527/4131] Disable GUS startup for now. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@605 --- src/dosbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 71275e5d..56087e71 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -199,7 +199,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&CMS_Init); secprop->Add_bool("cms",false); - secprop=control->AddSection_prop("gus",&GUS_Init); +// secprop=control->AddSection_prop("gus",&GUS_Init); secprop=control->AddSection_prop("disney",&DISNEY_Init); From 2df4ad3de201d23b85023571b4d1028b3b5be6f3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 28 Dec 2002 13:24:23 +0000 Subject: [PATCH 0528/4131] Fix bug with sierra installer's using scroll to clear areas of the screen. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@607 --- src/ints/int10_char.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 82449517..a6842874 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -111,6 +111,7 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit if(rlr>=nrows) rlr=(Bit8u)nrows-1; if(clr>=ncols) clr=(Bit8u)ncols-1; clr++; + /* Get the correct page */ if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); VGAMODES * curmode=GetCurrentMode(); @@ -131,7 +132,7 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit nlines=rlr-rul+1; goto filling; } - do { + while (start!=end) { start+=next; switch (curmode->memmodel) { case MTEXT: @@ -142,7 +143,7 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit case PLANAR4: PLANAR4_CopyRow(curmode,cul,clr,start,start+nlines,base);break; } - } while (start!=end); + } /* Fill some lines */ filling: if (nlines>0) { From 1bd011d74b8261de15b0eae1f393a2b05fdd671b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 29 Dec 2002 00:16:44 +0000 Subject: [PATCH 0529/4131] Force " " around path's giiven in the command line to support path's with spaces. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@608 --- src/shell/shell.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 323a79b0..7334fc5a 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -157,14 +157,14 @@ void AUTOEXEC_Init(Section * sec) { if (stat(buffer,&test)) goto nomount; } if (test.st_mode & S_IFDIR) { - SHELL_AddAutoexec("MOUNT C %s",buffer); + SHELL_AddAutoexec("MOUNT C \"%s\"",buffer); SHELL_AddAutoexec("C:"); } else { char * name=strrchr(buffer,CROSS_FILESPLIT); if (!name) goto nomount; *name++=0; if (access(buffer,F_OK)) goto nomount; - SHELL_AddAutoexec("MOUNT C %s",buffer); + SHELL_AddAutoexec("MOUNT C \"%s\"",buffer); SHELL_AddAutoexec("C:"); SHELL_AddAutoexec(name); } From a70ff185dd0c7d4c1b9dbb144029c2b58959ca56 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Dec 2002 21:52:26 +0000 Subject: [PATCH 0530/4131] Endian detection. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@609 --- configure.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure.in b/configure.in index 9417a9d6..22562502 100644 --- a/configure.in +++ b/configure.in @@ -43,6 +43,8 @@ AC_MSG_CHECKING(if compiler allows __attribute__) AC_TRY_COMPILE([], [typedef struct { } __attribute__ ((packed)) junk;], [ AC_MSG_RESULT(yes);AC_DEFINE(C_HAS_ATTRIBUTE)],AC_MSG_RESULT(no)) +#Check for big endian machine, should #define WORD_BIGENDIAN if so +AC_C_BIGENDIAN AC_OUTPUT([ Makefile From dccb4e4e73620a0142d6dda24d769450b95e4554 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Dec 2002 21:53:44 +0000 Subject: [PATCH 0531/4131] Support reading/writing memory on bigendian machines. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@610 --- include/mem.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/include/mem.h b/include/mem.h index 169e49c0..19e3d301 100644 --- a/include/mem.h +++ b/include/mem.h @@ -60,6 +60,33 @@ extern HostPt memory; Working on big or little endian machines */ +#ifdef WORDS_BIGENDIAN + +INLINE Bit8u readb(HostPt off) { + return off[0]; +}; +INLINE Bit16u readw(HostPt off) { + return off[0] | (off[1] << 8); +}; +INLINE Bit32u readd(HostPt off) { + return off[0] | (off[1] << 8) | (off[2] << 16) | (off[3] << 24); +}; +INLINE void writeb(HostPt off,Bit8u val) { + off[0]=val; +}; +INLINE void writew(HostPt off,Bit16u val) { + off[0]=(Bit8u)((val & 0x00ff)); + off[1]=(Bit8u)((val & 0xff00) >> 8); +}; +INLINE void writed(HostPt off,Bit32u val) { + off[0]=(Bit8u)((val & 0x000000ff)); + off[1]=(Bit8u)((val & 0x0000ff00) >> 8); + off[2]=(Bit8u)((val & 0x00ff0000) >> 16); + off[3]=(Bit8u)((val & 0xff000000) >> 24); +}; + +#else + INLINE Bit8u readb(HostPt off) { return *(Bit8u *)off; }; @@ -79,6 +106,7 @@ INLINE void writed(HostPt off,Bit32u val) { *(Bit32u *)(off)=val; }; +#endif /* The Folowing six functions are slower but they recognize the paged memory system */ //TODO maybe make em inline to go a bit faster From 930f07c55a017b09d328aca161b206a12ac0a485 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Dec 2002 21:54:36 +0000 Subject: [PATCH 0532/4131] Endian safe register structures. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@611 --- include/regs.h | 91 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 37 deletions(-) diff --git a/include/regs.h b/include/regs.h index d4bd3c49..2c3954f9 100644 --- a/include/regs.h +++ b/include/regs.h @@ -43,14 +43,30 @@ struct Segment { enum SegNames { cs=0,ds,es,fs,gs,ss}; +union GenReg32 { + Bit32u dword[1]; + Bit16u word[2]; + Bit8u byte[4]; +}; + +#ifdef WORDS_BIGENDIAN + +#define DW_INDEX 0 +#define W_INDEX 1 +#define BH_INDEX 2 +#define BL_INDEX 3 + +#else + +#define DW_INDEX 0 +#define W_INDEX 0 +#define BH_INDEX 1 +#define BL_INDEX 0 + +#endif + struct CPU_Regs { - union { - Bit32u d; - Bit16u w; - struct { - Bit8u l,h; - }b; - } regs[8],ip; + GenReg32 regs[8],ip; }; extern Segment Segs[6]; @@ -87,46 +103,47 @@ enum REG_NUM { }; //macros to convert a 3-bit register index to the correct register -#define reg_8l(reg) (cpu_regs.regs[(reg)].b.l) -#define reg_8h(reg) (cpu_regs.regs[(reg)].b.h) +#define reg_8l(reg) (cpu_regs.regs[(reg)].byte[BL_INDEX]) +#define reg_8h(reg) (cpu_regs.regs[(reg)].byte[BH_INDEX]) #define reg_8(reg) ((reg) & 4 ? reg_8h((reg) & 3) : reg_8l((reg) & 3)) -#define reg_16(reg) (cpu_regs.regs[(reg)].w) -#define reg_32(reg) (cpu_regs.regs[(reg)].d) +#define reg_16(reg) (cpu_regs.regs[(reg)].word[W_INDEX]) +#define reg_32(reg) (cpu_regs.regs[(reg)].dword[DW_INDEX]) -#define reg_al cpu_regs.regs[REG_NUM_AX].b.l -#define reg_ah cpu_regs.regs[REG_NUM_AX].b.h -#define reg_ax cpu_regs.regs[REG_NUM_AX].w -#define reg_eax cpu_regs.regs[REG_NUM_AX].d -#define reg_bl cpu_regs.regs[REG_NUM_BX].b.l -#define reg_bh cpu_regs.regs[REG_NUM_BX].b.h -#define reg_bx cpu_regs.regs[REG_NUM_BX].w -#define reg_ebx cpu_regs.regs[REG_NUM_BX].d +#define reg_al cpu_regs.regs[REG_NUM_AX].byte[BL_INDEX] +#define reg_ah cpu_regs.regs[REG_NUM_AX].byte[BH_INDEX] +#define reg_ax cpu_regs.regs[REG_NUM_AX].word[W_INDEX] +#define reg_eax cpu_regs.regs[REG_NUM_AX].dword[DW_INDEX] -#define reg_cl cpu_regs.regs[REG_NUM_CX].b.l -#define reg_ch cpu_regs.regs[REG_NUM_CX].b.h -#define reg_cx cpu_regs.regs[REG_NUM_CX].w -#define reg_ecx cpu_regs.regs[REG_NUM_CX].d +#define reg_bl cpu_regs.regs[REG_NUM_BX].byte[BL_INDEX] +#define reg_bh cpu_regs.regs[REG_NUM_BX].byte[BH_INDEX] +#define reg_bx cpu_regs.regs[REG_NUM_BX].word[W_INDEX] +#define reg_ebx cpu_regs.regs[REG_NUM_BX].dword[DW_INDEX] -#define reg_dl cpu_regs.regs[REG_NUM_DX].b.l -#define reg_dh cpu_regs.regs[REG_NUM_DX].b.h -#define reg_dx cpu_regs.regs[REG_NUM_DX].w -#define reg_edx cpu_regs.regs[REG_NUM_DX].d +#define reg_cl cpu_regs.regs[REG_NUM_CX].byte[BL_INDEX] +#define reg_ch cpu_regs.regs[REG_NUM_CX].byte[BH_INDEX] +#define reg_cx cpu_regs.regs[REG_NUM_CX].word[W_INDEX] +#define reg_ecx cpu_regs.regs[REG_NUM_CX].dword[DW_INDEX] -#define reg_si cpu_regs.regs[REG_NUM_SI].w -#define reg_esi cpu_regs.regs[REG_NUM_SI].d +#define reg_dl cpu_regs.regs[REG_NUM_DX].byte[BL_INDEX] +#define reg_dh cpu_regs.regs[REG_NUM_DX].byte[BH_INDEX] +#define reg_dx cpu_regs.regs[REG_NUM_DX].word[W_INDEX] +#define reg_edx cpu_regs.regs[REG_NUM_DX].dword[DW_INDEX] -#define reg_di cpu_regs.regs[REG_NUM_DI].w -#define reg_edi cpu_regs.regs[REG_NUM_DI].d +#define reg_si cpu_regs.regs[REG_NUM_SI].word[W_INDEX] +#define reg_esi cpu_regs.regs[REG_NUM_SI].dword[DW_INDEX] -#define reg_sp cpu_regs.regs[REG_NUM_SP].w -#define reg_esp cpu_regs.regs[REG_NUM_SP].d +#define reg_di cpu_regs.regs[REG_NUM_DI].word[W_INDEX] +#define reg_edi cpu_regs.regs[REG_NUM_DI].dword[DW_INDEX] -#define reg_bp cpu_regs.regs[REG_NUM_BP].w -#define reg_ebp cpu_regs.regs[REG_NUM_BP].d +#define reg_sp cpu_regs.regs[REG_NUM_SP].word[W_INDEX] +#define reg_esp cpu_regs.regs[REG_NUM_SP].dword[DW_INDEX] -#define reg_ip cpu_regs.ip.w -#define reg_eip cpu_regs.ip.d +#define reg_bp cpu_regs.regs[REG_NUM_BP].word[W_INDEX] +#define reg_ebp cpu_regs.regs[REG_NUM_BP].dword[DW_INDEX] + +#define reg_ip cpu_regs.ip.word[W_INDEX] +#define reg_eip cpu_regs.ip.dword[DW_INDEX] #endif From 4376052e998bf9b9c1e4cc3894aeff3c9b3fda3b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 31 Dec 2002 01:28:27 +0000 Subject: [PATCH 0533/4131] Don't reset last pressed/released location and always give back button status. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@612 --- src/ints/mouse.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 50bcf6ae..8b35bc5c 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -461,12 +461,10 @@ static Bitu INT33_Handler(void) { case 0x05: /* Return Button Press Data */ { Bit16u but=reg_bx; - if (but>=MOUSE_BUTTONS) break; reg_ax=mouse.buttons; + if (but>=MOUSE_BUTTONS) break; reg_cx=mouse.last_pressed_x[but]; - mouse.last_pressed_x[but]=0; reg_dx=mouse.last_pressed_y[but]; - mouse.last_pressed_y[but]=0; reg_bx=mouse.times_pressed[but]; mouse.times_pressed[but]=0; break; @@ -474,12 +472,10 @@ static Bitu INT33_Handler(void) { case 0x06: /* Return Button Release Data */ { Bit16u but=reg_bx; - if (but>=MOUSE_BUTTONS) break; reg_ax=mouse.buttons; + if (but>=MOUSE_BUTTONS) break; reg_cx=mouse.last_released_x[but]; - mouse.last_released_x[but]=0; reg_dx=mouse.last_released_y[but]; - mouse.last_released_y[but]=0; reg_bx=mouse.times_released[but]; mouse.times_released[but]=0; break; From ec8b4e3ec24692680c98f072fc18df3e700d3e9e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 31 Dec 2002 13:26:23 +0000 Subject: [PATCH 0534/4131] MCB structure now endian safe Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@613 --- include/dos_inc.h | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 2a039bd1..ba1c6561 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -29,14 +29,6 @@ struct CommandTail{ } GCC_ATTRIBUTE(packed); -struct MCB { - Bit8u type; - Bit16u psp_segment; - Bit16u size; - Bit8u unused[3]; - Bit8u filename[8]; -} GCC_ATTRIBUTE(packed); - #pragma pack () struct DOS_Date { @@ -419,10 +411,32 @@ private: #pragma pack () }; +class DOS_MCB : public MemStruct{ +public: + DOS_MCB(Bit16u seg) { SetPt(seg); } + void SetFileName(char * _name) { MEM_BlockWrite(pt+offsetof(sMCB,filename),_name,8); } + void GetFileName(char * _name) { MEM_BlockRead(pt+offsetof(sMCB,filename),_name,8);_name[8]=0;} + void SetType(Bit8u _type) { sSave(sMCB,type,_type);} + void SetSize(Bit16u _size) { sSave(sMCB,size,_size);} + void SetPSPSeg(Bit16u _pspseg) { sSave(sMCB,psp_segment,_pspseg);} + Bit8u GetType(void) { return sGet(sMCB,type);} + Bit16u GetSize(void) { return sGet(sMCB,size);} + Bit16u GetPSPSeg(void) { return sGet(sMCB,psp_segment);} +private: + #pragma pack (1) + struct sMCB { + Bit8u type; + Bit16u psp_segment; + Bit16u size; + Bit8u unused[3]; + Bit8u filename[8]; + } GCC_ATTRIBUTE(packed); + #pragma pack () +}; + extern DOS_InfoBlock dos_infoblock;; INLINE Bit8u RealHandle(Bit16u handle) { - DOS_PSP psp(dos.psp); return psp.GetFileHandle(handle); } From 080bcf28d4af94488042bdb4e63cb0f6878f4f5e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 31 Dec 2002 13:26:59 +0000 Subject: [PATCH 0535/4131] Removed dos_mcb class from here. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@614 --- src/dos/dos_classes.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 6025b28b..386688ff 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -349,15 +349,3 @@ void DOS_FCB::GetName(char * fillname) { fillname[14]=0; } -class DOS_MCB : public MemStruct{ -public: - DOS_MCB(Bit16u seg) { SetPt(seg); } -private: - struct sMCB { - Bit8u type; - Bit16u psp_segment; - Bit16u size; - Bit8u unused[3]; - Bit8u filename[8]; - } GCC_ATTRIBUTE(packed); -}; From 92858fee039fc7b74427b5cce1aec61ebc36526b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 31 Dec 2002 13:27:38 +0000 Subject: [PATCH 0536/4131] Use the new MCB class Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@615 --- src/dos/dos_execute.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 65621482..dd6ab205 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -173,10 +173,10 @@ bool DOS_NewPSP(Bit16u segment, Bit16u size) static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { /* Fix the PSP for psp and environment MCB's */ - MCB * pspmcb=(MCB *)HostMake(pspseg-1,0); - pspmcb->psp_segment=pspseg; - MCB * envmcb=(MCB *)HostMake(envseg-1,0); - envmcb->psp_segment=pspseg; + DOS_MCB mcb((Bit16u)(pspseg-1)); + mcb.SetPSPSeg(pspseg); + mcb.SetPt((Bit16u)(envseg-1)); + mcb.SetPSPSeg(pspseg); DOS_PSP psp(pspseg); psp.MakeNew(memsize); From 29a781ff18efde14e32288463591176f5b240f06 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 31 Dec 2002 13:31:53 +0000 Subject: [PATCH 0537/4131] Use the new MCB class. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@616 --- src/dos/dos_memory.cpp | 144 ++++++++++++++++++++--------------------- 1 file changed, 71 insertions(+), 73 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 0fb72a38..2feba966 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -27,33 +27,32 @@ static Bit16u memAllocStrategy = 0x00; static void DOS_CompressMemory(void) { - MCB * pmcb;MCB * pmcbnext; - Bit16u mcb_segment; - mcb_segment=dos.firstMCB; - pmcb=(MCB *)HostMake(mcb_segment,0); - while (pmcb->type!=0x5a) { - pmcbnext=pmcbnext=(MCB *)HostMake(mcb_segment+pmcb->size+1,0); - if ((pmcb->psp_segment==0) && (pmcbnext->psp_segment==0)) { - pmcb->size+=pmcbnext->size+1; - pmcb->type=pmcbnext->type; + Bit16u mcb_segment=dos.firstMCB; + DOS_MCB mcb(mcb_segment); + DOS_MCB mcb_next(0); + + while (mcb.GetType()!=0x5a) { + mcb_next.SetPt((Bit16u)(mcb_segment+mcb.GetSize()+1)); + if ((mcb.GetPSPSeg()==0) && (mcb_next.GetPSPSeg()==0)) { + mcb.SetSize(mcb.GetSize()+mcb_next.GetSize()+1); + mcb.SetType(mcb_next.GetType()); } else { - mcb_segment+=pmcb->size+1; - pmcb=(MCB *)HostMake(mcb_segment,0); + mcb_segment+=mcb.GetSize()+1; + mcb.SetPt(mcb_segment); } } } void DOS_FreeProcessMemory(Bit16u pspseg) { - MCB * pmcb; Bit16u mcb_segment=dos.firstMCB; - pmcb=(MCB *)HostMake(mcb_segment,0); + DOS_MCB mcb(mcb_segment); while (true) { - if (pmcb->psp_segment==pspseg) { - pmcb->psp_segment=MCB_FREE; + if (mcb.GetPSPSeg()==pspseg) { + mcb.SetPSPSeg(MCB_FREE); } - mcb_segment+=pmcb->size+1; - if (pmcb->type==0x5a) break; - pmcb=(MCB *)HostMake(mcb_segment,0); + if (mcb.GetType()==0x5a) break; + mcb_segment+=mcb.GetSize()+1; + mcb.SetPt(mcb_segment); } DOS_CompressMemory(); }; @@ -69,60 +68,61 @@ void DOS_SetMemAllocStrategy(Bit16u strat) }; bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { - MCB * pmcb;MCB * pmcbnext; - Bit16u bigsize=0;Bit16u mcb_segment; - bool stop=false;mcb_segment=dos.firstMCB; DOS_CompressMemory(); + Bit16u bigsize=0;Bit16u mcb_segment=dos.firstMCB; + DOS_MCB mcb(0); + DOS_MCB mcb_next(0); + bool stop=false; while(!stop) { - pmcb=(MCB *)HostMake(mcb_segment,0); - if (pmcb->psp_segment==0) { + mcb.SetPt(mcb_segment); + if (mcb.GetPSPSeg()==0) { /* Check for enough free memory in current block */ - if (pmcb->size<(*blocks)) { - if (bigsizesize) { - bigsize=pmcb->size; + Bit16u block_size=mcb.GetSize(); + if (block_size<(*blocks)) { + if (bigsizesize==*blocks) { - pmcb->psp_segment=dos.psp; + } else if (block_size==*blocks) { + mcb.SetPSPSeg(dos.psp); *segment=mcb_segment+1; return true; } else { // TODO: Strategy "1": Best matching block /* If so allocate it */ - if ((memAllocStrategy & 0x03)==0) { - pmcbnext=(MCB *)HostMake(mcb_segment+*blocks+1,0); - pmcbnext->psp_segment=MCB_FREE; - pmcbnext->type=pmcb->type; - pmcbnext->size=pmcb->size-*blocks-1; - pmcb->size=*blocks; - pmcb->type=0x4D; - pmcb->psp_segment=dos.psp; + if ((memAllocStrategy & 0x03)==0) { + mcb_next.SetPt((Bit16u)(mcb_segment+*blocks+1)); + mcb_next.SetPSPSeg(MCB_FREE); + mcb_next.SetType(mcb.GetType()); + mcb_next.SetSize(block_size-*blocks-1); + mcb.SetSize(*blocks); + mcb.SetType(0x4d); + mcb.SetPSPSeg(dos.psp); //TODO Filename *segment=mcb_segment+1; return true; } else { // * Last Block * // New created block - *segment = mcb_segment+1+pmcb->size-*blocks; - pmcbnext=(MCB *)HostMake(*segment-1,0); - pmcbnext->size = *blocks; - pmcbnext->type = pmcb->type; - pmcbnext->psp_segment = dos.psp; + *segment = mcb_segment+1+block_size - *blocks; + mcb_next.SetPt((Bit16u)(*segment-1)); + mcb_next.SetSize(*blocks); + mcb_next.SetType(mcb.GetType()); + mcb_next.SetPSPSeg(dos.psp); // Old Block - pmcb->size = pmcb->size-*blocks-1; - pmcb->psp_segment = MCB_FREE; - pmcb->type = 0x4D; + mcb.SetSize(block_size-*blocks-1); + mcb.SetPSPSeg(MCB_FREE); + mcb.SetType(0x4D); return true; }; } } /* Onward to the next MCB if there is one */ - if (pmcb->type==0x5a) { + if (mcb.GetType()==0x5a) { *blocks=bigsize; DOS_SetError(DOSERR_INSUFFICIENT_MEMORY); return false; } - mcb_segment+=pmcb->size+1; + mcb_segment+=mcb.GetSize()+1; } return false; } @@ -130,32 +130,31 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { DOS_CompressMemory(); - MCB * pmcb,* pmcbnext,* pmcbnew; - pmcb=(MCB *)HostMake(segment-1,0); - pmcbnext=(MCB *)HostMake(segment+pmcb->size,0); - Bit16u total=pmcb->size; - if (pmcb->type!=0x5a) { - if (pmcbnext->psp_segment==MCB_FREE) { - total+=pmcbnext->size+1; + DOS_MCB mcb(segment-1); + Bit16u total=mcb.GetSize(); + DOS_MCB mcb_next(segment+total); + if (mcb.GetType()!=0x5a) { + if (mcb_next.GetPSPSeg()==MCB_FREE) { + total+=mcb_next.GetSize()+1; } - }; + } if (*blockstype!=0x5a) { - pmcb->type=pmcbnext->type; + if (mcb.GetType()!=0x5a) { + mcb.SetType(mcb_next.GetType()); } - pmcb->size=*blocks; - pmcbnew=(MCB *)HostMake(segment+*blocks,0); - pmcbnew->size=total-*blocks-1; - pmcbnew->type=pmcb->type; - pmcbnew->psp_segment=MCB_FREE; - pmcb->type=0x4D; + mcb.SetSize(*blocks); + mcb_next.SetPt((Bit16u)(segment+*blocks)); + mcb_next.SetSize(total-*blocks-1); + mcb_next.SetType(mcb.GetType()); + mcb_next.SetPSPSeg(MCB_FREE); + mcb.SetType(0x4d); return true; } if (*blocks==total) { - if (pmcb->type!=0x5a) { - pmcb->type=pmcbnext->type; + if (mcb.GetType()!=0x5a) { + mcb.SetType(mcb_next.GetType()); } - pmcb->size=*blocks; + mcb.SetSize(*blocks); return true; } *blocks=total; @@ -166,9 +165,8 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { bool DOS_FreeMemory(Bit16u segment) { //TODO Check if allowed to free this segment - MCB * pmcb; - pmcb=(MCB *)HostMake(segment-1,0); - pmcb->psp_segment=MCB_FREE; + DOS_MCB mcb(segment-1); + mcb.SetPSPSeg(MCB_FREE); DOS_CompressMemory(); return true; } @@ -177,10 +175,10 @@ bool DOS_FreeMemory(Bit16u segment) { void DOS_SetupMemory(void) { - MCB * mcb=(MCB *) HostMake(MEM_START,0); - mcb->psp_segment=MCB_FREE; //Free - mcb->size=0x9FFE - MEM_START; - mcb->type=0x5a; //Last Block + DOS_MCB mcb((Bit16u)MEM_START); + mcb.SetPSPSeg(MCB_FREE); //Free + mcb.SetSize(0x9FFE - MEM_START); + mcb.SetType(0x5a); //Last Block dos.firstMCB=MEM_START; dos_infoblock.SetFirstMCB(MEM_START); } From bba62a21b41fda6babec5b1070ac7375e9b20c60 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 31 Dec 2002 13:32:53 +0000 Subject: [PATCH 0538/4131] Use new MCB Class Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@617 --- src/dos/dos_programs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 24b1ce81..0a50b12a 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -253,8 +253,8 @@ void LOADFIX::Run(void) Bit16u segment; Bit16u blocks = kb*1024/16; if (DOS_AllocateMemory(&segment,&blocks)) { - MCB* pmcb = (MCB*)HostMake(segment-1,0); - pmcb->psp_segment = 0x40; // use fake segment + DOS_MCB mcb((Bit16u)(segment-1)); + mcb.SetPSPSeg(0x40); // use fake segment WriteOut(MSG_Get("PROGRAM_LOADFIX_ALLOC"),kb); // Prepare commandline... if (cmd->FindCommand(commandNr++,temp_line)) { From 6a3be16d002e1a16f4362058d3cc295979f03b84 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 31 Dec 2002 13:33:38 +0000 Subject: [PATCH 0539/4131] Use new MCB class Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@618 --- src/shell/shell.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 7334fc5a..237a545f 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -249,9 +249,10 @@ void SHELL_Init() { SegSet16(ss,stack_seg); reg_sp=2046; /* Setup MCB and the environment */ - MCB * env_mcb=(MCB *)HostMake(env_seg-1,0); - env_mcb->psp_segment=psp_seg; - env_mcb->size=4096/16; + DOS_MCB envmcb((Bit16u)(env_seg-1)); + envmcb.SetPSPSeg(psp_seg); + envmcb.SetSize(4096/16); + PhysPt env_write=PhysMake(env_seg,0); MEM_BlockWrite(env_write,path_string,strlen(path_string)+1); env_write+=strlen(path_string)+1; From 4bcf247a00447f05fa83cb3772937d07875af1de Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 5 Jan 2003 12:08:12 +0000 Subject: [PATCH 0540/4131] Moved vga retrace handling. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@619 --- src/hardware/vga_misc.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 9202e913..cc40e120 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -21,7 +21,6 @@ #include "pic.h" #include "vga.h" - static Bit8u flip=0; static Bit32u keep_vretrace; static bool keeping=false; @@ -101,18 +100,6 @@ static Bit8u read_p3cc(Bit32u port) { return p3c2data; } - -static void EndRetrace(void) { - vga.config.retrace=false; -} - -void VGA_StartRetrace(void) { - /* Setup a timer to destroy the vertical retrace bit in a few microseconds */ - vga.config.real_start=vga.config.display_start; - vga.config.retrace=true; - PIC_AddEvent(EndRetrace,667); -} - void VGA_SetupMisc(void) { IO_RegisterReadHandler(0x3da,read_p3da,"VGA Input Status 1"); IO_RegisterReadHandler(0x3ba,read_p3da,"VGA Input Status 1"); From af01668b344d7bc27987c788f3fe7cd18bd6ea88 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 5 Jan 2003 12:08:49 +0000 Subject: [PATCH 0541/4131] New async rendering. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@620 --- src/hardware/vga.cpp | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index b62dd7e3..1bf84581 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -39,12 +39,24 @@ Bit32u FillTable[16]={ 0xffff0000,0xffff00ff,0xffffff00,0xffffffff }; +static void EndRetrace(void) { + /* start the actual display update now */ + RENDER_DoUpdate(); + vga.config.retrace=false; +} -static void VGA_BlankTimer(void) { - PIC_AddEvent(&VGA_BlankTimer,vga.draw.blank); +static void VGA_BlankTimer() { + PIC_AddEvent(VGA_BlankTimer,vga.draw.blank); + PIC_AddEvent(EndRetrace,667); + /* Setup a timer to destroy the vertical retrace bit in a few microseconds */ + vga.config.real_start=vga.config.display_start; + vga.config.retrace=true; +} + +static void VGA_DrawHandler(RENDER_Part_Handler part_handler) { Bit8u * buf,* bufsplit; /* Draw the current frame */ - if (!vga.draw.resizing && RENDER_StartUpdate()) { + if (!vga.draw.resizing) { if (vga.config.line_compare Date: Sun, 5 Jan 2003 12:32:37 +0000 Subject: [PATCH 0542/4131] Async graphics updates. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@621 --- src/gui/render.cpp | 42 +++++++----------- src/gui/sdlmain.cpp | 105 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 98 insertions(+), 49 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 42235c18..20b7a0f9 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -29,7 +29,7 @@ #define MAX_RES 2048 -typedef void (* RENDER_Part_Handler)(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy); + struct PalData { struct { @@ -56,6 +56,7 @@ static struct { Bitu flags; float ratio; RENDER_Part_Handler part_handler; + RENDER_Draw_Handler draw_handler; } src; struct { Bitu width; @@ -224,36 +225,23 @@ void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue) { if (render.pal.last(sec); snapshots_dir=section->Get_string("snapshots"); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 41b81fad..5ef50cc7 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -18,7 +18,8 @@ #include #include -#include +#include "SDL.h" +#include "SDL_Thread.h" #include "dosbox.h" #include "video.h" @@ -31,9 +32,11 @@ #include "debug.h" //#define DISABLE_JOYSTICK +#define C_GFXTHREADED 1 //Enabled by default struct SDL_Block { bool active; //If this isn't set don't draw + bool drawing; Bitu width; Bitu height; Bitu bpp; @@ -42,6 +45,11 @@ struct SDL_Block { bool full_screen; SDL_Surface * surface; SDL_Joystick * joy; + SDL_cond *cond; + SDL_mutex *mutex; + SDL_Thread *thread; + SDL_sem *sem; + GFX_DrawCallBack draw_callback; struct { bool autolock; bool autoenable; @@ -58,17 +66,17 @@ static void CaptureMouse(void); static void ResetScreen(void) { GFX_Stop(); if (sdl.full_screen) { - /* First get the original resolution */ sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN); } else { if (sdl.flags & GFX_FIXED_BPP) sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE); else sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,0,SDL_HWSURFACE); } if (sdl.surface==0) { - E_Exit("SDL:Would be nice if I could get a surface."); + E_Exit("SDL:Can't get a surface."); } + SDL_WM_SetCaption(VERSION,VERSION); -/* also fill up gfx_info structure */ + Bitu flags=MODE_SET; if (sdl.full_screen) flags|=MODE_FULLSCREEN; if (sdl.mode_callback) sdl.mode_callback(sdl.surface->w,sdl.surface->h,sdl.surface->format->BitsPerPixel,sdl.surface->pitch,flags); @@ -76,20 +84,18 @@ static void ResetScreen(void) { } -void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu flags,GFX_ModeCallBack callback) { +void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu flags,GFX_ModeCallBack mode_callback, GFX_DrawCallBack draw_callback){ GFX_Stop(); sdl.width=width; sdl.height=height; sdl.bpp=bpp; sdl.flags=flags; - sdl.mode_callback=callback; + sdl.mode_callback=mode_callback; + sdl.draw_callback=draw_callback; ResetScreen(); - GFX_Start(); } - - static void CaptureMouse(void) { sdl.mouse.locked=!sdl.mouse.locked; if (sdl.mouse.locked) { @@ -112,29 +118,57 @@ static void SwitchFullScreen(void) { ResetScreen(); } -//only prototype existed + void GFX_SwitchFullScreen(void) { SwitchFullScreen(); } -void * GFX_StartUpdate(void) { - if (sdl.active) { - if (SDL_MUSTLOCK(sdl.surface)) if (SDL_LockSurface(sdl.surface)) return 0; - return sdl.surface->pixels; - } else { - return 0; - } +static void SDL_DrawScreen(void) { + sdl.drawing=true; + + if (SDL_MUSTLOCK(sdl.surface)) { + if (SDL_LockSurface(sdl.surface)) E_Exit("SDL:Can't lock surface"); + } + sdl.draw_callback(sdl.surface->pixels); + + if (SDL_MUSTLOCK(sdl.surface)) { + SDL_UnlockSurface(sdl.surface); + } + SDL_Flip(sdl.surface); + sdl.drawing=false; } -void GFX_EndUpdate(void) { - if (SDL_MUSTLOCK(sdl.surface)) SDL_UnlockSurface(sdl.surface ); - if (sdl.full_screen) SDL_Flip(sdl.surface); - else SDL_UpdateRect(sdl.surface,0,0,0,0); + +int SDL_DisplayThread(void * data) { + while (!SDL_SemWait(sdl.sem)) { + if (!sdl.active) continue; + SDL_mutexP(sdl.mutex); + SDL_DrawScreen(); + SDL_mutexV(sdl.mutex); + } + return 0; +} + + +void GFX_DoUpdate(void) { + if (!sdl.active) return; + if (sdl.drawing) return; +#if C_GFXTHREADED + SDL_SemPost(sdl.sem); +#else + SDL_DrawScreen(); +#endif + } void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries) { -/* I should probably not change the GFX_PalEntry :) */ +#if C_GFXTHREADED + if (SDL_mutexP(sdl.mutex)) { + E_Exit("SDL:Can't lock Mutex"); + }; +#endif + /* I should probably not change the GFX_PalEntry :) */ if (sdl.full_screen) { if (!SDL_SetPalette(sdl.surface,SDL_PHYSPAL,(SDL_Color *)entries,start,count)) { E_Exit("SDL:Can't set palette"); @@ -144,6 +178,11 @@ void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries) { E_Exit("SDL:Can't set palette"); } } +#if C_GFXTHREADED + if (SDL_mutexV(sdl.mutex)) { + E_Exit("SDL:Can't release Mutex"); + }; +#endif } Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue) { @@ -151,9 +190,15 @@ Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue) { } void GFX_Stop() { +#if C_GFXTHREADED + SDL_mutexP(sdl.mutex); +#endif sdl.active=false; -} +#if C_GFXTHREADED + SDL_mutexV(sdl.mutex); +#endif +} void GFX_Start() { sdl.active=true; @@ -163,6 +208,12 @@ static void GUI_ShutDown(Section * sec) { GFX_Stop(); if (sdl.mouse.locked) CaptureMouse(); if (sdl.full_screen) SwitchFullScreen(); +#if C_GFXTHREADED + SDL_KillThread(sdl.thread); + SDL_DestroyMutex(sdl.mutex); + SDL_DestroySemaphore(sdl.sem); +#endif + } static void GUI_StartUp(Section * sec) { @@ -176,7 +227,13 @@ static void GUI_StartUp(Section * sec) { sdl.mouse.autoenable=section->Get_bool("autolock"); sdl.mouse.autolock=false; sdl.mouse.sensitivity=section->Get_int("sensitivity"); - GFX_SetSize(640,400,8,0,0); +#if C_GFXTHREADED + sdl.mutex=SDL_CreateMutex(); + sdl.sem=SDL_CreateSemaphore(0); + sdl.thread=SDL_CreateThread(&SDL_DisplayThread,0); +#endif + /* Initialize screen for first time */ + GFX_SetSize(640,400,8,0,0,0); SDL_EnableKeyRepeat(250,30); /* Get some Keybinds */ From 9d8a3b6020daa9fe03884f71f0cb1b73dfe72c87 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 5 Jan 2003 12:33:22 +0000 Subject: [PATCH 0543/4131] Support for async display udpates. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@622 --- include/render.h | 9 +++++---- include/video.h | 7 ++++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/render.h b/include/render.h index e7a0b840..7dd2d226 100644 --- a/include/render.h +++ b/include/render.h @@ -29,12 +29,13 @@ enum { DoubleBoth= 0x03 }; -bool RENDER_StartUpdate(void); -void RENDER_EndUpdate(void); -void RENDER_Part(Bit8u * data,Bitu x,Bitu y,Bitu dx,Bitu dy); +typedef void (* RENDER_Part_Handler)(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy); +typedef void (* RENDER_Draw_Handler)(RENDER_Part_Handler part_handler); -void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu flags); +void RENDER_DoUpdate(void); + +void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu flags,RENDER_Draw_Handler draw_handler); void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue); diff --git a/include/video.h b/include/video.h index d6424129..63d952ec 100644 --- a/include/video.h +++ b/include/video.h @@ -22,6 +22,8 @@ typedef void (* GFX_ModeCallBack)(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags); +typedef void (* GFX_DrawCallBack)(void * data); + struct GFX_PalEntry { Bit8u r; Bit8u g; @@ -40,14 +42,13 @@ void GFX_Events(void); void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries); Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue); -void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu flags,GFX_ModeCallBack callback); +void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu flags,GFX_ModeCallBack mode_callback, GFX_DrawCallBack draw_callback); void GFX_Start(void); void GFX_Stop(void); void GFX_SwitchFullScreen(void); -void * GFX_StartUpdate(void); -void GFX_EndUpdate(void); +void GFX_DoUpdate(void); #endif From 036ac5a2985c1060240faab1aa820f5dac4ab12d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 6 Jan 2003 10:40:58 +0000 Subject: [PATCH 0544/4131] fixed a typo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@623 --- src/shell/shell.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 237a545f..5d9dba50 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -188,7 +188,7 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_CHDIR_ERROR","Unable to change to: %s\n"); MSG_Add("SHELL_CMD_MKDIR_ERROR","Unable to make: %s\n"); MSG_Add("SHELL_CMD_RMDIR_ERROR","Unable to remove: %s\n"); - MSG_Add("SHELL_CMD_DEL_ERROR","Unable to delete: %s\n"); + MSG_Add("SHELL_CMD_DEL_ERROR","Unable to delete: %s\n"); MSG_Add("SHELL_SYNTAXERROR","The syntax of the command is incorrect.\n"); MSG_Add("SHELL_CMD_SET_NOT_SET","Environment variable %s not defined\n"); MSG_Add("SHELL_CMD_SET_OUT_OF_SPACE","Not enough environment space left.\n"); @@ -206,7 +206,7 @@ void SHELL_Init() { MSG_Add("SHELL_EXECUTE_ILLEGAL_COMMAND","Illegal command: %s.\n"); MSG_Add("SHELL_STARTUP","DOSBox Shell v" VERSION "\n" - "DOSBox doesn't not run protected mode games!\n" + "DOSBox does not run protected mode games!\n" "For supported shell commands type: HELP\n" #if! defined (WIN32) "DOSBox only works with upcase filenames as dos is case-insensitive.\n" From 364205668684c691fe4d379a6bd799854b8a7902 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 7 Jan 2003 18:03:39 +0000 Subject: [PATCH 0545/4131] debugger fixes under linux Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@624 --- src/debug/debug.cpp | 16 ++++++++++++---- src/debug/debug_gui.cpp | 13 +++++++------ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 3c3d1bd3..720613fd 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -38,8 +38,11 @@ #ifdef WIN32 void WIN32_Console(); +#else +#include +#include +static struct termios consolesettings; #endif - // Forwards static void DrawCode(void); static bool DEBUG_Log_Loop(int count); @@ -855,6 +858,7 @@ Bit32u DEBUG_CheckKeys(void) { case 0x0A: codeViewData.inputMode = FALSE; ParseCommand(codeViewData.inputStr); break; + case 0x107: //backspace (linux) case 0x08: // delete if (strlen(codeViewData.inputStr)>0) codeViewData.inputStr[strlen(codeViewData.inputStr)-1] = 0; break; @@ -1126,9 +1130,10 @@ void DEBUG_SetupConsole(void) { #ifdef WIN32 WIN32_Console(); - #else - printf("\e[8;50;80t"); //resize terminal - fflush(NULL); + #else + tcgetattr(0,&consolesettings); + printf("\e[8;50;80t"); //resize terminal + fflush(NULL); #endif memset((void *)&dbg,0,sizeof(dbg)); debugging=false; @@ -1141,6 +1146,9 @@ void DEBUG_SetupConsole(void) static void DEBUG_ShutDown(Section * sec) { CBreakpoint::DeleteAll(); + #ifndef WIN32 + tcsetattr(0, TCSANOW,&consolesettings); + #endif }; void DEBUG_Init(Section* sec) { diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 64eb95fb..a89b2d87 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -118,14 +118,15 @@ static void MakePairs(void) { void DBGUI_StartUp(void) { /* Start the main window */ dbg.win_main=initscr(); - cbreak(); /* take input chars one at a time, no wait for \n */ - noecho(); /* don't echo input */ + cbreak(); /* take input chars one at a time, no wait for \n */ + noecho(); /* don't echo input */ nodelay(dbg.win_main,true); keypad(dbg.win_main,true); - #ifndef WIN32 - resizeterm(50,80); - touchwin(dbg.win_main); - #endif + #ifndef WIN32 + resizeterm(50,80); + touchwin(dbg.win_main); + #endif + start_color(); cycle_count=0; MakePairs(); MakeSubWindows(); From 34188f9e14a720a990d22355abd7bb83e4574ae9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 7 Jan 2003 18:11:11 +0000 Subject: [PATCH 0546/4131] renamed Thread to thread as else the linux filesystem couldn't find it Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@625 --- src/gui/sdlmain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 5ef50cc7..f9387e87 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -19,7 +19,7 @@ #include #include #include "SDL.h" -#include "SDL_Thread.h" +#include "SDL_thread.h" #include "dosbox.h" #include "video.h" From b52e4e5f082c1d860bb33bdf8a90306fda202315 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 7 Jan 2003 18:12:41 +0000 Subject: [PATCH 0547/4131] made gcc3.2 happy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@626 --- include/joystick.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/joystick.h b/include/joystick.h index 3317db1f..aec0b477 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -22,4 +22,5 @@ void JOYSTICK_Button(Bitu which,Bitu num,bool pressed); void JOYSTICK_Move_X(Bitu which,float x); -void JOYSTICK_Move_Y(Bitu which,float y); \ No newline at end of file +void JOYSTICK_Move_Y(Bitu which,float y); + From 43dd0e358e205b69dccbdcd7a19dabd8ab813032 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 7 Jan 2003 18:17:42 +0000 Subject: [PATCH 0548/4131] made gcc happy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@627 --- src/hardware/cmos.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 9c20f9ec..83ba7838 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -115,4 +115,5 @@ void CMOS_Init(Section* sec) { IO_RegisterWriteHandler(0x71,cmos_writereg,"CMOS"); IO_RegisterReadHandler(0x71,cmos_readreg,"CMOS"); cmos.timer.enabled=false; -} \ No newline at end of file +} + From 66996ec88238ad1428dbf2c5347b425784d436f9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 14 Jan 2003 11:13:18 +0000 Subject: [PATCH 0549/4131] fixed a bug in parsecommand for gcc3.2 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@628 --- src/debug/debug.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 720613fd..204eacb9 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -676,7 +676,8 @@ bool ChangeRegister(char* str) bool ParseCommand(char* str) { char* found = str; - while (*found) *found++=toupper(*found); + for(char* idx = found;*idx != 0; idx++) + *idx = toupper(*idx); found = strstr(str,"BP "); if (found) { // Add new breakpoint found+=3; From a1f52fbd1df527d97c221e542ebe5abf905aa58d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 15 Jan 2003 18:35:07 +0000 Subject: [PATCH 0550/4131] fixes for black on white terminals Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@629 --- src/debug/debug.cpp | 8 ++++++-- src/debug/debug_disasm.cpp | 3 ++- src/debug/debug_gui.cpp | 4 +++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 204eacb9..42968860 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002 - 2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,6 +42,7 @@ void WIN32_Console(); #include #include static struct termios consolesettings; +int old_cursor_state; #endif // Forwards static void DrawCode(void); @@ -1147,8 +1148,11 @@ void DEBUG_SetupConsole(void) static void DEBUG_ShutDown(Section * sec) { CBreakpoint::DeleteAll(); - #ifndef WIN32 + #ifndef WIN32 + curs_set(old_cursor_state); tcsetattr(0, TCSANOW,&consolesettings); + printf("\e[0m\e[2J"); + fflush(NULL); #endif }; diff --git a/src/debug/debug_disasm.cpp b/src/debug/debug_disasm.cpp index 67559cd2..dea4b057 100644 --- a/src/debug/debug_disasm.cpp +++ b/src/debug/debug_disasm.cpp @@ -1112,4 +1112,5 @@ Bitu DasmI386(char* buffer, PhysPt pc, Bitu cur_ip, bool bit32) } -#endif \ No newline at end of file +#endif + diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index a89b2d87..1c7a6ee6 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002 - 2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,6 +31,7 @@ #include "debug.h" #include "debug_inc.h" +extern int old_cursor_state; void DEBUG_ShowMsg(char * msg) { char buf[1024]; strcpy(buf,msg); @@ -125,6 +126,7 @@ void DBGUI_StartUp(void) { #ifndef WIN32 resizeterm(50,80); touchwin(dbg.win_main); + old_cursor_state = curs_set(0); #endif start_color(); cycle_count=0; From fb2896a6531055ca66ae315c2f9c236d0a89a833 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 15 Jan 2003 20:07:57 +0000 Subject: [PATCH 0551/4131] added directory cache Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@630 --- src/dos/drive_cache.cpp | 462 ++++++++++++++++++++++++++++++++++++++++ src/dos/drive_local.cpp | 81 ++++--- src/dos/drives.h | 66 ++++++ 3 files changed, 578 insertions(+), 31 deletions(-) create mode 100644 src/dos/drive_cache.cpp diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp new file mode 100644 index 00000000..d6a71aec --- /dev/null +++ b/src/dos/drive_cache.cpp @@ -0,0 +1,462 @@ + +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "drives.h" +#include "dos_inc.h" +#include "dirent.h" +#include "support.h" + +// STL stuff +#include +#include +#include + + +bool SortByName(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b) +{ + return strcmp(a->shortname,b->shortname)<0; +}; + +bool SortByNameRev(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b) +{ + return strcmp(a->shortname,b->shortname)>0; +}; + +bool SortByDirName(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b) +{ + // Directories first... + if (a->isDir!=b->isDir) return (a->isDir>b->isDir); + return strcmp(a->shortname,b->shortname)<0; +}; + +bool SortByDirNameRev(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b) +{ + // Directories first... + if (a->isDir!=b->isDir) return (a->isDir>b->isDir); + return strcmp(a->shortname,b->shortname)>0; +}; + +DOS_Drive_Cache::DOS_Drive_Cache(void) +{ + dirBase = new CFileInfo; + dirSearch = 0; + save_dir = 0; + SetDirSort(DIRALPHABETICAL); +}; + +DOS_Drive_Cache::DOS_Drive_Cache(const char* path) +{ + dirBase = new CFileInfo; + dirSearch = 0; + save_dir = 0; + SetDirSort(DIRALPHABETICAL); + SetBaseDir(path); +}; + +DOS_Drive_Cache::~DOS_Drive_Cache(void) +{ + delete dirBase; dirBase = 0; +}; + +void DOS_Drive_Cache::SetBaseDir(const char* baseDir) +{ + strcpy(dirBase->fullname,baseDir); + if (OpenDir(baseDir)) { + struct dirent result; + struct stat status; + ReadDir(&result,&status); + }; +}; + +void DOS_Drive_Cache::ExpandName(char* path) +{ + strcpy(path,GetExpandName(path)); +}; + +char* DOS_Drive_Cache::GetExpandName(const char* path) +{ + static char work [CROSS_LEN]; + char dir [CROSS_LEN]; + + work[0] = 0; + strcpy (dir,path); + + char* pos = strrchr(path,CROSS_FILESPLIT); + + if (pos) dir[pos-path+1] = 0; + CFileInfo* dirInfo = FindDirInfo(dir, work); + + if (pos) { + // Last Entry = File + strcpy(dir,pos+1); + if (strchr(dir,'~')) GetLongName(dirInfo, dir); + strcat(work,dir); + } + return work; +}; + +void DOS_Drive_Cache::AddEntry(const char* path) +{ + // Get Last part... + char file [CROSS_LEN]; + char expand [CROSS_LEN]; + + CFileInfo* dir = FindDirInfo(path,expand); + char* pos = strrchr(path,CROSS_FILESPLIT); + + if (pos) { + strcpy(file,pos+1); + CreateEntry(dir,file); + // Sort Lists - filelist has to be alphabetically sorted + std::sort(dir->fileList.begin(), dir->fileList.end(), SortByName); + // Output list - user defined + switch (sortDirType) { + case ALPHABETICAL : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByName); break; + case DIRALPHABETICAL : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByDirName); break; + case ALPHABETICALREV : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByNameRev); break; + case DIRALPHABETICALREV : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByDirNameRev); break; + }; + } +}; + +void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) +{ + char expand[CROSS_LEN] = { 0 }; + CFileInfo* dir; + + if (ignoreLastDir) { + char tmp[CROSS_LEN] = { 0 }; + Bit32s len = strrchr(path,CROSS_FILESPLIT) - path; + if (len>0) { + strncpy(tmp,path,len); + tmp[len] = 0; + } else { + strcpy(tmp,path); + } + dir = FindDirInfo(tmp,expand); + } else { + dir = FindDirInfo(path,expand); + } +// LOG_DEBUG("DIR: Caching out %s : dir %s",expand,dir->fullname); + // delete file objects... + for(Bit32u i=0; ifileList.size(); i++) delete dir->fileList[i]; + // clear lists + dir->fileList.clear(); + dir->longNameList.clear(); + dir->outputList.clear(); + dir->shortNr = 0; + save_dir = 0; + nextEntry = 0; +}; + +bool DOS_Drive_Cache::IsCachedIn(CFileInfo* curDir) +{ + return (curDir->fileList.size()>0); +}; + +Bit16u DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name) +{ + Bit16s foundNr = 0; + Bit16s low = 0; + Bit16s high = curDir->longNameList.size()-1; + Bit16s mid, res; + + CFileInfo* test; + + while (low<=high) { + mid = (low+high)/2; + test = curDir->longNameList[mid]; + res = strncmp(name,curDir->longNameList[mid]->shortname,curDir->longNameList[mid]->compareCount); + if (res>0) low = mid+1; else + if (res<0) high = mid-1; + else { + // any more same x chars in next entries ? + do { + foundNr = curDir->longNameList[mid]->shortNr; + mid++; + } while(midlongNameList.size() && (strncmp(name,curDir->longNameList[mid]->shortname,curDir->longNameList[mid]->compareCount)==0)); + break; + }; + } + return foundNr+1; +}; + +Bit16s DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) +{ + // Search long name and return array number of element + Bit16s low = 0; + Bit16s high = curDir->fileList.size()-1; + Bit16s mid,res; + while (low<=high) { + mid = (low+high)/2; + CFileInfo* test = curDir->fileList[mid]; + res = strcmp(shortName,curDir->fileList[mid]->shortname); + if (res>0) low = mid+1; else + if (res<0) high = mid-1; else + { // Found +// strcpy(shortName,curDir->fileList[mid]->fullname); + strcpy(shortName,curDir->fileList[mid]->orgname); + return mid; + }; + } + // not available + return -1; +}; + +Bit16s DOS_Drive_Cache::RemoveSpaces(char* str) +// Removes all spaces +// return length of string upto first '.' +{ + char* curpos = str; + char* chkpos = str; + Bit16s len = -1; + while (*chkpos!=0) { + if (*chkpos=='.') { if (len<0) len = curpos - str; }; + if (*chkpos==' ') chkpos++; else *curpos++ = *chkpos++; + } + *curpos = 0; + if (len<0) len = curpos - str; + return len; +}; + +void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) +{ + Bit16s len = 0; + Bit16s lenExt = 0; + char tmpName[CROSS_LEN]; + + // Remove Spaces + strcpy(tmpName,info->fullname); + len = RemoveSpaces(tmpName); + + // Get Length of filename + char* pos = strchr(tmpName,'.'); + if (pos) { + len = (Bit16u)(pos - tmpName); + // Get Length of extension + lenExt = strlen(pos)-1; + } else + len = strlen(tmpName); + + // Should shortname version be created ? + bool createShort = (len>8) || (lenExt>3); +// if (!createShort) { +// char buffer[CROSS_LEN]; +// strcpy(buffer,tmpName); +// createShort = (GetLongName(curDir,buffer)>=0); +// } + + if (createShort) { + // Create number + char buffer[8]; + info->shortNr = CreateShortNameID(curDir,tmpName); + sprintf(buffer,"%d",info->shortNr); + // Copy first letters + Bit16u tocopy; + if (len+strlen(buffer)>8) tocopy = 8 - strlen(buffer) - 1; + else tocopy = len; + strncpy(info->shortname,tmpName,tocopy); + info->shortname[tocopy] = 0; + // Copy number + strcat(info->shortname,"~"); + strcat(info->shortname,buffer); + // Create compare Count + info->compareCount = tocopy; + // Add (and cut) Extension, if available + if (pos) { + // Step to last extension... + pos = strrchr(tmpName, '.'); + // add extension + strncat(info->shortname,pos,4); + info->shortname[DOS_NAMELENGTH] = 0; + }; + // Put it in longname list... + curDir->longNameList.push_back(info); + std::sort(curDir->longNameList.begin(), curDir->longNameList.end(), SortByName); + } else { + strcpy(info->shortname,tmpName); + } +}; + +DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* expandedPath) +{ + // statics + static char split[2] = { CROSS_FILESPLIT,0 }; + + char dir [CROSS_LEN]; + char work [CROSS_LEN]; + char* start = (char*)path; + char* pos; + CFileInfo* curDir = dirBase; + + if (save_dir && (strcmp(path,save_path)==0)) { + strcpy(expandedPath,save_expanded); + return save_dir; + }; + +// LOG_DEBUG("DIR: Find %s",path); + + // Remove base dir path + start += strlen(dirBase->fullname); + strcpy(expandedPath,dirBase->fullname); + + do { +// bool errorcheck = false; + pos = strchr(start,CROSS_FILESPLIT); + if (pos) { strncpy(dir,start,pos-start); dir[pos-start] = 0; /*errorcheck = true;*/ } + else { strcpy(dir,start); }; + + // Path found + Bit16s nextDir = GetLongName(curDir,dir); + strcat(expandedPath,dir); + + // Error check +// if ((errorcheck) && (nextDir<0)) { +// LOG_DEBUG("DIR: Error: %s not found.",expandedPath); +// }; + + // Follow Directory + if ((nextDir>=0) && curDir->fileList[nextDir]->isDir) { + curDir = curDir->fileList[nextDir]; + strcpy (curDir->fullname,dir); + strcpy (work,path); + // Cut Directory, if its only part of whole path + if (pos) work[(Bit32u)pos-(Bit32u)path] = 0; + if (!IsCachedIn(curDir)) { + if (OpenDir(curDir,work)) { + struct dirent result; + struct stat status; + ReadDir(&result,&status); + }; + } + }; + if (pos) { + strcat(expandedPath,split); + start = pos+1; + } + } while (pos); + + // Save last result for faster access next time + strcpy(save_path,path); + strcpy(save_expanded,expandedPath); + save_dir = curDir; + + return curDir; +}; + +bool DOS_Drive_Cache::OpenDir(const char* path) +{ + char expand[CROSS_LEN] = {0}; + CFileInfo* dir = FindDirInfo(path,expand); + return OpenDir(dir,expand); +}; + +bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, char* expand) +{ + dirSearch = dir; + // Add "/" + char end[2]={CROSS_FILESPLIT,0}; + if (expand[strlen(expand)-1]!=CROSS_FILESPLIT) strcat(expand,end); + // open dir + if (dirSearch) { + // open dir + DIR* dirp = opendir(expand); + if (dirp) { + dirFirstTime = true; + closedir(dirp); + strcpy(dirPath,expand); + return true; + } + }; + return false; +}; + +void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name) +{ + struct stat status; + CFileInfo* info = new CFileInfo; + strcpy(info->fullname,name); + strcpy(info->orgname ,name); + // always upcase + upcase(info->fullname); + info->shortNr = 0; + // Read and copy file stats + char buffer[CROSS_LEN]; + strcpy(buffer,dirPath); + strcat(buffer,info->fullname); + stat (buffer,&status); + memcpy(&info->status,&status,sizeof(status)); + info->isDir = (S_ISDIR(status.st_mode)>0); + // Check for long filenames... + CreateShortName(dir, info); + // Put file in lists + dir->fileList.push_back(info); + dir->outputList.push_back(info); +}; + +bool DOS_Drive_Cache::ReadDir(struct dirent* result, struct stat *status) +{ + if (dirFirstTime) { + if (!IsCachedIn(dirSearch)) { + // Try to open directory + DIR* dirp = opendir(dirPath); + if (!dirp) { +// LOG_DEBUG("DIR: Error Caching in %s",dirPath); + return false; + } else { +// LOG_DEBUG("DIR: Caching in %s",dirPath); + }; + // Read complete directory + struct dirent* tmpres; + while (tmpres = readdir(dirp)) { + CreateEntry(dirSearch,tmpres->d_name); + } + // close dir + closedir(dirp); + // Sort Lists - filelist has to be alphabetically sorted + std::sort(dirSearch->fileList.begin(), dirSearch->fileList.end(), SortByName); + // Output list - user defined + switch (sortDirType) { + case ALPHABETICAL : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByName); break; + case DIRALPHABETICAL : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByDirName); break; + case ALPHABETICALREV : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByNameRev); break; + case DIRALPHABETICALREV : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByDirNameRev); break; + }; + } else { + dirFirstTime=false; + } + // Reset it.. + nextEntry = 0; + }; + return SetResult(dirSearch, result, status, nextEntry); +}; + +bool DOS_Drive_Cache::SetResult(CFileInfo* dir, struct dirent* result, struct stat* status, Bit16u entryNr) +{ + if (entryNr>=dir->outputList.size()) return false; + CFileInfo* info = dir->outputList[entryNr]; + // copy filename, short version + strcpy(result->d_name,info->shortname); + // copy file status + memcpy(status,&info->status,sizeof(info->status)); + // Set to next Entry + nextEntry = entryNr+1; + return true; +}; + diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index a12c504b..c32e9e64 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -49,8 +49,9 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) { strcpy(newname,basedir); strcat(newname,name); CROSS_FILENAME(newname); - FILE * hand=fopen(newname,"wb+"); + FILE * hand=fopen(dirCache.GetExpandName(newname),"wb+"); if (!hand) return false; + dirCache.AddEntry(newname); /* Make the 16 bit device information */ *file=new localFile(hand,0x202); return true; @@ -59,9 +60,9 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) { bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { char * type; switch (flags) { - case OPEN_READ:type="rb";break; - case OPEN_WRITE:type="rb+";break; - case OPEN_READWRITE:type="rb+";break; + case OPEN_READ:type="rb"; break; + case OPEN_WRITE:type="rb+"; break; + case OPEN_READWRITE:type="rb+"; break; default: //TODO FIX IT type="rb+"; @@ -72,10 +73,13 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { strcpy(newname,basedir); strcat(newname,name); CROSS_FILENAME(newname); + dirCache.ExpandName(newname); + FILE * hand=fopen(newname,type); Bit32u err=errno; if (!hand) return false; *file=new localFile(hand,0x202); +// (*file)->SetFileName(newname); return true; }; @@ -84,54 +88,59 @@ bool localDrive::FileUnlink(char * name) { strcpy(newname,basedir); strcat(newname,name); CROSS_FILENAME(newname); - if (!unlink(newname)) return true; + if (!unlink(dirCache.GetExpandName(newname))) { + dirCache.CacheOut(newname); + return true; + }; return false; }; bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { - if (srch_opendir) closedir(srch_opendir); + strcpy(srch_dir,basedir); strcat(srch_dir,_dir); CROSS_FILENAME(srch_dir); char end[2]={CROSS_FILESPLIT,0}; if (srch_dir[strlen(srch_dir)-1]!=CROSS_FILESPLIT) strcat(srch_dir,end); - if((srch_opendir=opendir(srch_dir))==NULL) return false; + + if (!dirCache.OpenDir(srch_dir)) return false; return FindNext(dta); } + bool localDrive::FindNext(DOS_DTA & dta) { - struct dirent * dir_ent; + + struct dirent dir_ent; struct stat stat_block; - char full_name[CROSS_LEN]; + Bit8u srch_attr;char srch_pattern[DOS_NAMELENGTH_ASCII]; Bit8u find_attr; - if(!srch_opendir) return false; - dta.GetSearchParams(srch_attr,srch_pattern); - again: - if((dir_ent=readdir(srch_opendir))==NULL) { - closedir(srch_opendir); - srch_opendir=NULL; - return false; - } - if(!WildFileCmp(dir_ent->d_name,srch_pattern)) goto again; - strcpy(full_name,srch_dir); - strcat(full_name,dir_ent->d_name); - if(stat(full_name,&stat_block)!=0){ - goto again; - } + +again: + if (!dirCache.ReadDir(&dir_ent,&stat_block)) return false; + + if(!WildFileCmp(dir_ent.d_name,srch_pattern)) goto again; + if(S_ISDIR(stat_block.st_mode)) find_attr=DOS_ATTR_DIRECTORY; else find_attr=DOS_ATTR_ARCHIVE; if (~srch_attr & find_attr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM)) goto again; + + if(S_ISDIR(stat_block.st_mode)) find_attr=DOS_ATTR_DIRECTORY; + else find_attr=DOS_ATTR_ARCHIVE; + if (~srch_attr & find_attr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM)) goto again; + /*file is okay, setup everything to be copied in DTA Block */ char find_name[DOS_NAMELENGTH_ASCII];Bit16u find_date,find_time;Bit32u find_size; - if(strlen(dir_ent->d_name)d_name); + + if(strlen(dir_ent.d_name)0) && (newdir[len-1]!='\\')) { @@ -209,7 +222,8 @@ bool localDrive::Rename(char * oldname,char * newname) { strcpy(newnew,basedir); strcat(newnew,newname); CROSS_FILENAME(newnew); - int temp=rename(newold,newnew); + int temp=rename(dirCache.GetExpandName(newold),dirCache.GetExpandName(newnew)); + if (temp==0) dirCache.CacheOut(newnew); return (temp==0); }; @@ -229,6 +243,7 @@ bool localDrive::FileExists(const char* name) { strcpy(newname,basedir); strcat(newname,name); CROSS_FILENAME(newname); + dirCache.ExpandName(newname); FILE* Temp=fopen(newname,"rb"); if(Temp==NULL) return false; fclose(Temp); @@ -240,6 +255,7 @@ bool localDrive::FileStat(const char* name, FileStat_Block * const stat_block) { strcpy(newname,basedir); strcat(newname,name); CROSS_FILENAME(newname); + dirCache.ExpandName(newname); struct stat temp_stat; if(stat(newname,&temp_stat)!=0) return false; /* Convert the stat to a FileStat */ @@ -268,6 +284,8 @@ localDrive::localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors allocation.total_clusters=_total_clusters; allocation.free_clusters=_free_clusters; allocation.mediaid=_mediaid; + + dirCache.SetBaseDir(basedir); } @@ -312,6 +330,7 @@ bool localFile::Seek(Bit32u * pos,Bit32u type) { } bool localFile::Close() { + fclose(fhandle); return true; } @@ -319,7 +338,7 @@ bool localFile::Close() { Bit16u localFile::GetInformation(void) { return info; } - + localFile::localFile(FILE * handle,Bit16u devinfo) { fhandle=handle; diff --git a/src/dos/drives.h b/src/dos/drives.h index 90c8fce6..893d64dc 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -21,12 +21,77 @@ #include #include +#include #include "dos_system.h" #include "cross.h" bool WildFileCmp(const char * file, const char * wild); +class DOS_Drive_Cache { +public: + DOS_Drive_Cache (void); + DOS_Drive_Cache (const char* path); + ~DOS_Drive_Cache (void); + + typedef enum TDirSort { NOSORT, ALPHABETICAL, DIRALPHABETICAL, ALPHABETICALREV, DIRALPHABETICALREV }; + + void SetBaseDir (const char* path); + void SetDirSort (TDirSort sort) { sortDirType = sort; }; + bool OpenDir (const char* path); + bool ReadDir (struct dirent* result,struct stat* status); + + void ExpandName (char* path); + char* GetExpandName (const char* path); + + void CacheOut (const char* path, bool ignoreLastDir = false); + void AddEntry (const char* path); + + class CFileInfo { + public: + ~CFileInfo(void) { + for (Bit32u i=0; i fileList; + std::vector longNameList; + std::vector outputList; + }; + +private: + + Bit16s GetLongName (CFileInfo* info, char* shortname); + void CreateShortName (CFileInfo* dir, CFileInfo* info); + Bit16u CreateShortNameID (CFileInfo* dir, const char* name); + bool SetResult (CFileInfo* dir, struct dirent* result, struct stat* status, Bit16u entryNr); + bool IsCachedIn (CFileInfo* dir); + CFileInfo* FindDirInfo (const char* path, char* expandedPath); + Bit16s RemoveSpaces (char* str); + bool OpenDir (CFileInfo* dir, char* path); + void CreateEntry (CFileInfo* dir, const char* name); + + Bit32u nextEntry; + CFileInfo* dirBase; + CFileInfo* dirSearch; + char dirPath [CROSS_LEN]; + bool dirFirstTime; + TDirSort sortDirType; + CFileInfo* save_dir; + char save_path [CROSS_LEN]; + char save_expanded [CROSS_LEN]; + +}; + class localDrive : public DOS_Drive { public: localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid); @@ -55,6 +120,7 @@ private: Bit16u free_clusters; Bit8u mediaid; } allocation; + DOS_Drive_Cache dirCache; }; struct VFILE_Block; From 0a1f52e0f865f3c9973200e5e38071ea72d43360 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 15 Jan 2003 20:08:35 +0000 Subject: [PATCH 0552/4131] new file drive_cache.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@631 --- visualc/dosbox.dsp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index 9fd8aed8..476fd9d5 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -1,24 +1,24 @@ # Microsoft Developer Studio Project File - Name="dosbox" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** +# ** NICHT BEARBEITEN ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 CFG=dosbox - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run +!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE +!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl !MESSAGE !MESSAGE NMAKE /f "dosbox.mak". !MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben +!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: !MESSAGE !MESSAGE NMAKE /f "dosbox.mak" CFG="dosbox - Win32 Debug" !MESSAGE -!MESSAGE Possible choices for configuration are: +!MESSAGE Für die Konfiguration stehen zur Auswahl: !MESSAGE -!MESSAGE "dosbox - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "dosbox - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "dosbox - Win32 Release" (basierend auf "Win32 (x86) Console Application") +!MESSAGE "dosbox - Win32 Debug" (basierend auf "Win32 (x86) Console Application") !MESSAGE # Begin Project @@ -202,6 +202,10 @@ SOURCE=..\src\dos\dev_con.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\src\dos\drive_cache.cpp +# End Source File +# Begin Source File + SOURCE=..\src\dos\drive_local.cpp # End Source File # Begin Source File From 43d965ec60fd6f9014c0b275df29816112449cef Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 15 Jan 2003 20:10:39 +0000 Subject: [PATCH 0553/4131] added shutdown function, fixed memleak. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@632 --- src/dos/dos.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 4b804a54..15cc5b5a 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -27,6 +27,7 @@ #include "callback.h" #include "regs.h" #include "dos_inc.h" +#include "setup.h" DOS_Block dos; DOS_InfoBlock dos_infoblock; @@ -857,6 +858,11 @@ static Bitu DOS_29Handler(void) { return CBRET_NONE; } +void DOS_ShutDown(Section* sec) +{ + for (Bit16u i=0;itm_year+1900; Bit32u ticks=(Bit32u)((loctime->tm_hour*3600+loctime->tm_min*60+loctime->tm_sec)*18.2); mem_writed(BIOS_TIMER,ticks); + + /* shutdown function */ + sec->AddDestroyFunction(&DOS_ShutDown); } + From da6cf16ae942916e4e81ff6da3dc84a3f2b4f93c Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 15 Jan 2003 23:04:54 +0000 Subject: [PATCH 0554/4131] fixed a few dircache issues, removed saving of file status in cache Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@633 --- src/dos/drive_cache.cpp | 55 +++++++++++++++++++++++------------------ src/dos/drive_local.cpp | 9 ++++++- src/dos/drives.h | 5 ++-- 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index d6a71aec..22c26164 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -79,8 +79,7 @@ void DOS_Drive_Cache::SetBaseDir(const char* baseDir) strcpy(dirBase->fullname,baseDir); if (OpenDir(baseDir)) { struct dirent result; - struct stat status; - ReadDir(&result,&status); + ReadDir(&result); }; }; @@ -122,6 +121,13 @@ void DOS_Drive_Cache::AddEntry(const char* path) if (pos) { strcpy(file,pos+1); + + // already in ? + if (GetLongName(dir,file)>=0) { + int brk = 0; + return; + }; + CreateEntry(dir,file); // Sort Lists - filelist has to be alphabetically sorted std::sort(dir->fileList.begin(), dir->fileList.end(), SortByName); @@ -132,14 +138,17 @@ void DOS_Drive_Cache::AddEntry(const char* path) case ALPHABETICALREV : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByNameRev); break; case DIRALPHABETICALREV : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByDirNameRev); break; }; - } +// LOG_DEBUG("DIR: Added Entry %s",path); + } else { +// LOG_DEBUG("DIR: Error: Failed to add %s",path); + }; }; void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) { char expand[CROSS_LEN] = { 0 }; CFileInfo* dir; - + if (ignoreLastDir) { char tmp[CROSS_LEN] = { 0 }; Bit32s len = strrchr(path,CROSS_FILESPLIT) - path; @@ -205,7 +214,6 @@ Bit16s DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) Bit16s mid,res; while (low<=high) { mid = (low+high)/2; - CFileInfo* test = curDir->fileList[mid]; res = strcmp(shortName,curDir->fileList[mid]->shortname); if (res>0) low = mid+1; else if (res<0) high = mid-1; else @@ -256,11 +264,11 @@ void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) // Should shortname version be created ? bool createShort = (len>8) || (lenExt>3); -// if (!createShort) { -// char buffer[CROSS_LEN]; -// strcpy(buffer,tmpName); -// createShort = (GetLongName(curDir,buffer)>=0); -// } + if (!createShort) { + char buffer[CROSS_LEN]; + strcpy(buffer,tmpName); + createShort = (GetLongName(curDir,buffer)>=0); + } if (createShort) { // Create number @@ -341,8 +349,7 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* if (!IsCachedIn(curDir)) { if (OpenDir(curDir,work)) { struct dirent result; - struct stat status; - ReadDir(&result,&status); + ReadDir(&result); }; } }; @@ -401,7 +408,6 @@ void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name) strcpy(buffer,dirPath); strcat(buffer,info->fullname); stat (buffer,&status); - memcpy(&info->status,&status,sizeof(status)); info->isDir = (S_ISDIR(status.st_mode)>0); // Check for long filenames... CreateShortName(dir, info); @@ -410,18 +416,12 @@ void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name) dir->outputList.push_back(info); }; -bool DOS_Drive_Cache::ReadDir(struct dirent* result, struct stat *status) +bool DOS_Drive_Cache::ReadDir(struct dirent* result) { if (dirFirstTime) { if (!IsCachedIn(dirSearch)) { // Try to open directory DIR* dirp = opendir(dirPath); - if (!dirp) { -// LOG_DEBUG("DIR: Error Caching in %s",dirPath); - return false; - } else { -// LOG_DEBUG("DIR: Caching in %s",dirPath); - }; // Read complete directory struct dirent* tmpres; while (tmpres = readdir(dirp)) { @@ -438,23 +438,30 @@ bool DOS_Drive_Cache::ReadDir(struct dirent* result, struct stat *status) case ALPHABETICALREV : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByNameRev); break; case DIRALPHABETICALREV : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByDirNameRev); break; }; + // Info +/* if (!dirp) { + LOG_DEBUG("DIR: Error Caching in %s",dirPath); + return false; + } else { + char buffer[128]; + sprintf(buffer,"DIR: Caching in %s (%d Files)",dirPath,dirSearch->fileList.size()); + LOG_DEBUG(buffer); + };*/ } else { dirFirstTime=false; } // Reset it.. nextEntry = 0; }; - return SetResult(dirSearch, result, status, nextEntry); + return SetResult(dirSearch, result, nextEntry); }; -bool DOS_Drive_Cache::SetResult(CFileInfo* dir, struct dirent* result, struct stat* status, Bit16u entryNr) +bool DOS_Drive_Cache::SetResult(CFileInfo* dir, struct dirent* result, Bit16u entryNr) { if (entryNr>=dir->outputList.size()) return false; CFileInfo* info = dir->outputList[entryNr]; // copy filename, short version strcpy(result->d_name,info->shortname); - // copy file status - memcpy(status,&info->status,sizeof(info->status)); // Set to next Entry nextEntry = entryNr+1; return true; diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index c32e9e64..72e9f7fd 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -114,6 +114,7 @@ bool localDrive::FindNext(DOS_DTA & dta) { struct dirent dir_ent; struct stat stat_block; + char full_name[CROSS_LEN]; Bit8u srch_attr;char srch_pattern[DOS_NAMELENGTH_ASCII]; Bit8u find_attr; @@ -121,10 +122,16 @@ bool localDrive::FindNext(DOS_DTA & dta) { dta.GetSearchParams(srch_attr,srch_pattern); again: - if (!dirCache.ReadDir(&dir_ent,&stat_block)) return false; + if (!dirCache.ReadDir(&dir_ent)) return false; if(!WildFileCmp(dir_ent.d_name,srch_pattern)) goto again; + strcpy(full_name,srch_dir); + strcat(full_name,dir_ent.d_name); + if (stat(dirCache.GetExpandName(full_name),&stat_block)!=0) { + goto again; + } + if(S_ISDIR(stat_block.st_mode)) find_attr=DOS_ATTR_DIRECTORY; else find_attr=DOS_ATTR_ARCHIVE; if (~srch_attr & find_attr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM)) goto again; diff --git a/src/dos/drives.h b/src/dos/drives.h index 893d64dc..22425214 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -39,7 +39,7 @@ public: void SetBaseDir (const char* path); void SetDirSort (TDirSort sort) { sortDirType = sort; }; bool OpenDir (const char* path); - bool ReadDir (struct dirent* result,struct stat* status); + bool ReadDir (struct dirent* result); void ExpandName (char* path); char* GetExpandName (const char* path); @@ -61,7 +61,6 @@ public: bool isDir; Bit16u shortNr; Bit16u compareCount; - struct stat status; // contents std::vector fileList; std::vector longNameList; @@ -73,7 +72,7 @@ private: Bit16s GetLongName (CFileInfo* info, char* shortname); void CreateShortName (CFileInfo* dir, CFileInfo* info); Bit16u CreateShortNameID (CFileInfo* dir, const char* name); - bool SetResult (CFileInfo* dir, struct dirent* result, struct stat* status, Bit16u entryNr); + bool SetResult (CFileInfo* dir, struct dirent* result, Bit16u entryNr); bool IsCachedIn (CFileInfo* dir); CFileInfo* FindDirInfo (const char* path, char* expandedPath); Bit16s RemoveSpaces (char* str); From adcb4012716474b8f9465a735189af5208a323f9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 16 Jan 2003 10:32:23 +0000 Subject: [PATCH 0555/4131] added drive_cache.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@634 --- src/dos/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/Makefile.am b/src/dos/Makefile.am index 1a414826..8bc84fc8 100644 --- a/src/dos/Makefile.am +++ b/src/dos/Makefile.am @@ -4,4 +4,4 @@ noinst_LIBRARIES = libdos.a libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioctl.cpp dos_memory.cpp \ dos_misc.cpp dos_classes.cpp dos_programs.cpp dos_tables.cpp \ drives.cpp drives.h drive_virtual.cpp drive_local.cpp \ - dev_con.h + dev_con.h drive_cache.cpp From 496640572a83d14263094aac7c5c29d2642993c6 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 16 Jan 2003 12:53:05 +0000 Subject: [PATCH 0556/4131] ignore precding '.' in filenames, fixed: GetLongname wasnt always used. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@635 --- src/dos/drive_cache.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 22c26164..124b9b45 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -104,7 +104,7 @@ char* DOS_Drive_Cache::GetExpandName(const char* path) if (pos) { // Last Entry = File strcpy(dir,pos+1); - if (strchr(dir,'~')) GetLongName(dirInfo, dir); + GetLongName(dirInfo, dir); strcat(work,dir); } return work; @@ -122,12 +122,6 @@ void DOS_Drive_Cache::AddEntry(const char* path) if (pos) { strcpy(file,pos+1); - // already in ? - if (GetLongName(dir,file)>=0) { - int brk = 0; - return; - }; - CreateEntry(dir,file); // Sort Lists - filelist has to be alphabetically sorted std::sort(dir->fileList.begin(), dir->fileList.end(), SortByName); @@ -245,25 +239,37 @@ Bit16s DOS_Drive_Cache::RemoveSpaces(char* str) void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) { - Bit16s len = 0; - Bit16s lenExt = 0; - char tmpName[CROSS_LEN]; + Bit16s len = 0; + Bit16s lenExt = 0; + bool createShort = 0; + + char tmpNameBuffer[CROSS_LEN]; + + char* tmpName = tmpNameBuffer; // Remove Spaces strcpy(tmpName,info->fullname); - len = RemoveSpaces(tmpName); + len = RemoveSpaces(tmpName); // Get Length of filename char* pos = strchr(tmpName,'.'); if (pos) { - len = (Bit16u)(pos - tmpName); // Get Length of extension lenExt = strlen(pos)-1; + // ignore preceding '.' if extension is longer than "3" + if (lenExt>3) { + while (*tmpName=='.') tmpName++; + createShort = true; + }; + pos = strchr(tmpName,'.'); + if (pos) len = (Bit16u)(pos - tmpName); + else len = strlen(tmpName); + } else len = strlen(tmpName); // Should shortname version be created ? - bool createShort = (len>8) || (lenExt>3); + if (!createShort) createShort = (len>8); if (!createShort) { char buffer[CROSS_LEN]; strcpy(buffer,tmpName); From e907697244c48a1c19c39009c977566032573710 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 16 Jan 2003 15:13:18 +0000 Subject: [PATCH 0557/4131] fixed bug in rename file <-> Dircache Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@636 --- src/dos/drive_cache.cpp | 2 +- src/dos/drive_local.cpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 124b9b45..a604aecc 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -412,7 +412,7 @@ void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name) // Read and copy file stats char buffer[CROSS_LEN]; strcpy(buffer,dirPath); - strcat(buffer,info->fullname); + strcat(buffer,info->orgname); stat (buffer,&status); info->isDir = (S_ISDIR(status.st_mode)>0); // Check for long filenames... diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 72e9f7fd..831a1f7c 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -225,11 +225,13 @@ bool localDrive::Rename(char * oldname,char * newname) { strcpy(newold,basedir); strcat(newold,oldname); CROSS_FILENAME(newold); + dirCache.ExpandName(newold); + char newnew[CROSS_LEN]; strcpy(newnew,basedir); strcat(newnew,newname); CROSS_FILENAME(newnew); - int temp=rename(dirCache.GetExpandName(newold),dirCache.GetExpandName(newnew)); + int temp=rename(newold,dirCache.GetExpandName(newnew)); if (temp==0) dirCache.CacheOut(newnew); return (temp==0); From d74635f15c2c5950c4546cc7c0f335236769793c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 18 Jan 2003 11:29:23 +0000 Subject: [PATCH 0558/4131] Changed location of instructions.h Only enable heavy_debug if normal debug is enabled. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@637 --- src/cpu/core_16/support.h | 3 +-- src/cpu/{core_16 => }/instructions.h | 0 src/cpu/slow_16.cpp | 4 +++- 3 files changed, 4 insertions(+), 3 deletions(-) rename src/cpu/{core_16 => }/instructions.h (100%) diff --git a/src/cpu/core_16/support.h b/src/cpu/core_16/support.h index 5f540a0a..085f03f5 100644 --- a/src/cpu/core_16/support.h +++ b/src/cpu/core_16/support.h @@ -98,7 +98,6 @@ static INLINE Bit32u Pop_32() { #include "helpers.h" #include "table_ea.h" #include "../modrm.h" -#include "instructions.h" static Bit8s table_df_8[2]={1,-1}; @@ -355,7 +354,7 @@ rep_again: default: IPPoint--; LOG_DEBUG("Unhandled REP Prefix %X",Fetchb()); - + goto normalexit; } /* If we end up here it's because the CPU_Cycles counter is 0, so restart instruction */ IPPoint-=(prefix.count+2); /* Rep instruction and whatever string instruction */ diff --git a/src/cpu/core_16/instructions.h b/src/cpu/instructions.h similarity index 100% rename from src/cpu/core_16/instructions.h rename to src/cpu/instructions.h diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp index 40146a3b..299895ec 100644 --- a/src/cpu/slow_16.cpp +++ b/src/cpu/slow_16.cpp @@ -63,6 +63,7 @@ extern Bitu cycle_count; #endif +#include "instructions.h" #include "core_16/support.h" static Bitu CPU_Real_16_Slow_Decode_Trap(void); @@ -71,10 +72,10 @@ static Bitu CPU_Real_16_Slow_Decode(void) { while (CPU_Cycles>0) { #if C_DEBUG cycle_count++; -#endif #if C_HEAVY_DEBUG SAVEIP; if (DEBUG_HeavyIsBreakpoint()) return 1; +#endif #endif #include "core_16/main.h" if (prefix.count) { @@ -103,6 +104,7 @@ static Bitu CPU_Real_16_Slow_Decode_Trap(void) { return CBRET_NONE; } + void CPU_Real_16_Slow_Start(void) { cpudecoder=&CPU_Real_16_Slow_Decode; EAPrefixTable[0]=&GetEA_16_n; From 5f7c53654c7e9c3517e4e4c70f751e69e5e88a46 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 18 Jan 2003 11:30:05 +0000 Subject: [PATCH 0559/4131] Only setup default interrupt handlers for first 128 interrupts. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@638 --- src/cpu/callback.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 7d5efa55..33fe6f65 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -171,7 +171,8 @@ void CALLBACK_Init(Section* sec) { /* Setup all Interrupt to point to the default handler */ call_default=CALLBACK_Allocate(); CALLBACK_Setup(call_default,&default_handler,CB_IRET); - for (i=0;i<256;i++) { + /* Only setup default handler for first half of interrupt table */ + for (i=0;i<128;i++) { real_writed(0,i*4,CALLBACK_RealPointer(call_default)); } #endif From aaf24b65e5d12c87a0c515bcc6acbf74f00b1809 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 18 Jan 2003 11:32:18 +0000 Subject: [PATCH 0560/4131] Support to enable/disable the disney. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@639 --- src/hardware/disney.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 0e2291c8..3631f25a 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -20,8 +20,6 @@ static struct { Bit8u control; Bit8u buffer[DISNEY_SIZE]; Bitu used; - bool enabled; - Bit8u delay; MIXER_Channel * chan; } disney; @@ -40,7 +38,7 @@ static void disney_write(Bit32u port,Bit8u val) { disney.buffer[disney.used++]=disney.data; } } - if (val&0x10) LOG_DEBUG("IRQ Enabled"); + if (val&0x10) LOG_DEBUG("DISNEY:Parallel IRQ Enabled"); disney.control=val; break; } @@ -83,6 +81,10 @@ static void DISNEY_CallBack(Bit8u * stream,Bit32u len) { void DISNEY_Init(Section* sec) { + + Section_prop * section=static_cast(sec); + if(!section->Get_bool("enabled")) return; + IO_RegisterWriteHandler(DISNEY_BASE,disney_write,"DISNEY"); IO_RegisterWriteHandler(DISNEY_BASE+1,disney_write,"DISNEY"); IO_RegisterWriteHandler(DISNEY_BASE+2,disney_write,"DISNEY"); From 83724b66f22b02e998af9def6eb662b6263cc125 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 19 Jan 2003 09:01:10 +0000 Subject: [PATCH 0561/4131] instructions.h moved in makefiles. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@640 --- src/cpu/Makefile.am | 2 +- src/cpu/core_16/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/Makefile.am b/src/cpu/Makefile.am index 5a8f26af..97ef51e2 100644 --- a/src/cpu/Makefile.am +++ b/src/cpu/Makefile.am @@ -2,4 +2,4 @@ SUBDIRS = core_16 AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libcpu.a -libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h slow_16.cpp \ No newline at end of file +libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h slow_16.cpp instructions.h \ No newline at end of file diff --git a/src/cpu/core_16/Makefile.am b/src/cpu/core_16/Makefile.am index f2f2d54f..27aa2848 100644 --- a/src/cpu/core_16/Makefile.am +++ b/src/cpu/core_16/Makefile.am @@ -1,3 +1,3 @@ -noinst_HEADERS = helpers.h instructions.h main.h prefix_66.h prefix_of.h start.h stop.h support.h table_ea.h \ +noinst_HEADERS = helpers.h main.h prefix_66.h prefix_of.h start.h stop.h support.h table_ea.h \ prefix_66_of.h From c5d18b9d983c645f43281fe00335953cd9fee6fa Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 19 Jan 2003 09:04:38 +0000 Subject: [PATCH 0562/4131] Moved instructions.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@641 --- visualc/dosbox.dsp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index 476fd9d5..f441b904 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -98,10 +98,6 @@ SOURCE=..\src\cpu\core_16\helpers.h # End Source File # Begin Source File -SOURCE=..\src\cpu\core_16\instructions.h -# End Source File -# Begin Source File - SOURCE=..\src\cpu\core_16\main.h # End Source File # Begin Source File @@ -147,6 +143,10 @@ SOURCE=..\src\cpu\flags.cpp # End Source File # Begin Source File +SOURCE=..\src\cpu\instructions.h +# End Source File +# Begin Source File + SOURCE=..\src\cpu\modrm.cpp # End Source File # Begin Source File From bb1d5b2f2f5f4e3e77175be0d6da98e245618df6 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 19 Jan 2003 14:08:22 +0000 Subject: [PATCH 0563/4131] fixed some filenames not being mangled, due to unsorted list access Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@642 --- src/dos/drive_cache.cpp | 19 +++++++++---------- src/dos/drives.h | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index a604aecc..c1b8181e 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -208,6 +208,7 @@ Bit16s DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) Bit16s mid,res; while (low<=high) { mid = (low+high)/2; + CFileInfo* test = curDir->fileList[mid]; res = strcmp(shortName,curDir->fileList[mid]->shortname); if (res>0) low = mid+1; else if (res<0) high = mid-1; else @@ -221,27 +222,24 @@ Bit16s DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) return -1; }; -Bit16s DOS_Drive_Cache::RemoveSpaces(char* str) +bool DOS_Drive_Cache::RemoveSpaces(char* str) // Removes all spaces -// return length of string upto first '.' { char* curpos = str; char* chkpos = str; Bit16s len = -1; while (*chkpos!=0) { - if (*chkpos=='.') { if (len<0) len = curpos - str; }; if (*chkpos==' ') chkpos++; else *curpos++ = *chkpos++; } *curpos = 0; - if (len<0) len = curpos - str; - return len; + return (curpos!=chkpos); }; void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) { Bit16s len = 0; Bit16s lenExt = 0; - bool createShort = 0; + bool createShort = false; char tmpNameBuffer[CROSS_LEN]; @@ -249,7 +247,7 @@ void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) // Remove Spaces strcpy(tmpName,info->fullname); - len = RemoveSpaces(tmpName); + createShort = RemoveSpaces(tmpName); // Get Length of filename char* pos = strchr(tmpName,'.'); @@ -269,7 +267,7 @@ void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) len = strlen(tmpName); // Should shortname version be created ? - if (!createShort) createShort = (len>8); + createShort = createShort || (len>8); if (!createShort) { char buffer[CROSS_LEN]; strcpy(buffer,tmpName); @@ -432,11 +430,12 @@ bool DOS_Drive_Cache::ReadDir(struct dirent* result) struct dirent* tmpres; while (tmpres = readdir(dirp)) { CreateEntry(dirSearch,tmpres->d_name); + // Sort Lists - filelist has to be alphabetically sorted, even in between (for finding double file names) + // hmpf.. bit slow probably... + std::sort(dirSearch->fileList.begin(), dirSearch->fileList.end(), SortByName); } // close dir closedir(dirp); - // Sort Lists - filelist has to be alphabetically sorted - std::sort(dirSearch->fileList.begin(), dirSearch->fileList.end(), SortByName); // Output list - user defined switch (sortDirType) { case ALPHABETICAL : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByName); break; diff --git a/src/dos/drives.h b/src/dos/drives.h index 22425214..c3743b79 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -75,7 +75,7 @@ private: bool SetResult (CFileInfo* dir, struct dirent* result, Bit16u entryNr); bool IsCachedIn (CFileInfo* dir); CFileInfo* FindDirInfo (const char* path, char* expandedPath); - Bit16s RemoveSpaces (char* str); + bool RemoveSpaces (char* str); bool OpenDir (CFileInfo* dir, char* path); void CreateEntry (CFileInfo* dir, const char* name); From 75072258ec05b7d7be390d59ae7022dabc3d9567 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 19 Jan 2003 16:51:25 +0000 Subject: [PATCH 0564/4131] disabled AddEntry (Arena prob) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@643 --- src/dos/drive_cache.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index c1b8181e..ef3346f6 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -112,6 +112,11 @@ char* DOS_Drive_Cache::GetExpandName(const char* path) void DOS_Drive_Cache::AddEntry(const char* path) { + + CacheOut(path); + return; + + // FIXME: Code doesnt seem to work with arena ??? Why is that ? // Get Last part... char file [CROSS_LEN]; char expand [CROSS_LEN]; From b9434bbf8bca2d590f9632f832003cbc548e0172 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 19 Jan 2003 17:55:05 +0000 Subject: [PATCH 0565/4131] Added Class to deactivate cache, for debugging purposes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@644 --- src/dos/drive_cache.cpp | 61 ++++++++++++++++++++++++++++++++--------- src/dos/drive_local.cpp | 12 ++++---- src/dos/drives.h | 28 +++++++++++++++++-- 3 files changed, 80 insertions(+), 21 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index ef3346f6..67bcd7d6 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -78,8 +78,8 @@ void DOS_Drive_Cache::SetBaseDir(const char* baseDir) { strcpy(dirBase->fullname,baseDir); if (OpenDir(baseDir)) { - struct dirent result; - ReadDir(&result); + struct dirent* result; + ReadDir(result); }; }; @@ -112,10 +112,6 @@ char* DOS_Drive_Cache::GetExpandName(const char* path) void DOS_Drive_Cache::AddEntry(const char* path) { - - CacheOut(path); - return; - // FIXME: Code doesnt seem to work with arena ??? Why is that ? // Get Last part... char file [CROSS_LEN]; @@ -124,6 +120,11 @@ void DOS_Drive_Cache::AddEntry(const char* path) CFileInfo* dir = FindDirInfo(path,expand); char* pos = strrchr(path,CROSS_FILESPLIT); + char* name = pos+1; + if (GetLongName(dir,name)<0) { + int brk = 0; + }; + if (pos) { strcpy(file,pos+1); @@ -131,12 +132,13 @@ void DOS_Drive_Cache::AddEntry(const char* path) // Sort Lists - filelist has to be alphabetically sorted std::sort(dir->fileList.begin(), dir->fileList.end(), SortByName); // Output list - user defined - switch (sortDirType) { +/* switch (sortDirType) { case ALPHABETICAL : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByName); break; case DIRALPHABETICAL : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByDirName); break; case ALPHABETICALREV : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByNameRev); break; case DIRALPHABETICALREV : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByDirNameRev); break; - }; + };*/ +// nextEntry++; // LOG_DEBUG("DIR: Added Entry %s",path); } else { // LOG_DEBUG("DIR: Error: Failed to add %s",path); @@ -170,7 +172,7 @@ void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) dir->outputList.clear(); dir->shortNr = 0; save_dir = 0; - nextEntry = 0; +// nextEntry = 0; }; bool DOS_Drive_Cache::IsCachedIn(CFileInfo* curDir) @@ -357,8 +359,8 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* if (pos) work[(Bit32u)pos-(Bit32u)path] = 0; if (!IsCachedIn(curDir)) { if (OpenDir(curDir,work)) { - struct dirent result; - ReadDir(&result); + struct dirent* result; + ReadDir(result); }; } }; @@ -425,7 +427,7 @@ void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name) dir->outputList.push_back(info); }; -bool DOS_Drive_Cache::ReadDir(struct dirent* result) +bool DOS_Drive_Cache::ReadDir(struct dirent* &result) { if (dirFirstTime) { if (!IsCachedIn(dirSearch)) { @@ -466,8 +468,11 @@ bool DOS_Drive_Cache::ReadDir(struct dirent* result) return SetResult(dirSearch, result, nextEntry); }; -bool DOS_Drive_Cache::SetResult(CFileInfo* dir, struct dirent* result, Bit16u entryNr) +bool DOS_Drive_Cache::SetResult(CFileInfo* dir, struct dirent* &result, Bit16u entryNr) { + static struct dirent res; + + result = &res; if (entryNr>=dir->outputList.size()) return false; CFileInfo* info = dir->outputList[entryNr]; // copy filename, short version @@ -477,3 +482,33 @@ bool DOS_Drive_Cache::SetResult(CFileInfo* dir, struct dirent* result, Bit16u en return true; }; +// **************************************************************************** +// No Dir Cache, +// **************************************************************************** + +DOS_No_Drive_Cache::DOS_No_Drive_Cache(const char* path) +{ + SetBaseDir(path); +}; + +void DOS_No_Drive_Cache::SetBaseDir(const char* path) +{ + strcpy(basePath,path); +} + +bool DOS_No_Drive_Cache::OpenDir(const char* path) +{ + strcpy(dirPath,path); + if((srch_opendir=opendir(dirPath))==NULL) return false; + return true; +}; + +bool DOS_No_Drive_Cache::ReadDir(struct dirent* &result) +{ + if((result=readdir(srch_opendir))==NULL) { + closedir(srch_opendir); + srch_opendir=NULL; + return false; + } + return true; +}; \ No newline at end of file diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 831a1f7c..f3b7fcae 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -112,7 +112,7 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { bool localDrive::FindNext(DOS_DTA & dta) { - struct dirent dir_ent; + struct dirent* dir_ent; struct stat stat_block; char full_name[CROSS_LEN]; @@ -122,12 +122,12 @@ bool localDrive::FindNext(DOS_DTA & dta) { dta.GetSearchParams(srch_attr,srch_pattern); again: - if (!dirCache.ReadDir(&dir_ent)) return false; + if (!dirCache.ReadDir(dir_ent)) return false; - if(!WildFileCmp(dir_ent.d_name,srch_pattern)) goto again; + if(!WildFileCmp(dir_ent->d_name,srch_pattern)) goto again; strcpy(full_name,srch_dir); - strcat(full_name,dir_ent.d_name); + strcat(full_name,dir_ent->d_name); if (stat(dirCache.GetExpandName(full_name),&stat_block)!=0) { goto again; } @@ -143,8 +143,8 @@ again: /*file is okay, setup everything to be copied in DTA Block */ char find_name[DOS_NAMELENGTH_ASCII];Bit16u find_date,find_time;Bit32u find_size; - if(strlen(dir_ent.d_name)d_name)d_name); upcase(find_name); } diff --git a/src/dos/drives.h b/src/dos/drives.h index c3743b79..1d62e97a 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -39,7 +39,7 @@ public: void SetBaseDir (const char* path); void SetDirSort (TDirSort sort) { sortDirType = sort; }; bool OpenDir (const char* path); - bool ReadDir (struct dirent* result); + bool ReadDir (struct dirent* &result); void ExpandName (char* path); char* GetExpandName (const char* path); @@ -72,7 +72,7 @@ private: Bit16s GetLongName (CFileInfo* info, char* shortname); void CreateShortName (CFileInfo* dir, CFileInfo* info); Bit16u CreateShortNameID (CFileInfo* dir, const char* name); - bool SetResult (CFileInfo* dir, struct dirent* result, Bit16u entryNr); + bool SetResult (CFileInfo* dir, struct dirent* &result, Bit16u entryNr); bool IsCachedIn (CFileInfo* dir); CFileInfo* FindDirInfo (const char* path, char* expandedPath); bool RemoveSpaces (char* str); @@ -91,6 +91,30 @@ private: }; +class DOS_No_Drive_Cache { +public: + DOS_No_Drive_Cache (void) {}; + DOS_No_Drive_Cache (const char* path); + ~DOS_No_Drive_Cache (void) {}; + + typedef enum TDirSort { NOSORT, ALPHABETICAL, DIRALPHABETICAL, ALPHABETICALREV, DIRALPHABETICALREV }; + + void SetBaseDir (const char* path); + void SetDirSort (TDirSort sort) {}; + bool OpenDir (const char* path); + bool ReadDir (struct dirent* &result); + + void ExpandName (char* path) {}; + char* GetExpandName (const char* path) { return (char*)path; }; + + void CacheOut (const char* path, bool ignoreLastDir = false) {}; + void AddEntry (const char* path) {}; +public: + char basePath [CROSS_LEN]; + char dirPath [CROSS_LEN]; + DIR* srch_opendir; +}; + class localDrive : public DOS_Drive { public: localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid); From 516251e648e12bdb6d4334154b06cf45050792d3 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 19 Jan 2003 23:07:14 +0000 Subject: [PATCH 0566/4131] Dont reset findnext counter if recaching directoy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@645 --- src/dos/drive_cache.cpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 67bcd7d6..2a0c56b6 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -57,6 +57,7 @@ DOS_Drive_Cache::DOS_Drive_Cache(void) dirBase = new CFileInfo; dirSearch = 0; save_dir = 0; + nextEntry = 0; SetDirSort(DIRALPHABETICAL); }; @@ -65,6 +66,7 @@ DOS_Drive_Cache::DOS_Drive_Cache(const char* path) dirBase = new CFileInfo; dirSearch = 0; save_dir = 0; + nextEntry = 0; SetDirSort(DIRALPHABETICAL); SetBaseDir(path); }; @@ -120,11 +122,6 @@ void DOS_Drive_Cache::AddEntry(const char* path) CFileInfo* dir = FindDirInfo(path,expand); char* pos = strrchr(path,CROSS_FILESPLIT); - char* name = pos+1; - if (GetLongName(dir,name)<0) { - int brk = 0; - }; - if (pos) { strcpy(file,pos+1); @@ -132,13 +129,12 @@ void DOS_Drive_Cache::AddEntry(const char* path) // Sort Lists - filelist has to be alphabetically sorted std::sort(dir->fileList.begin(), dir->fileList.end(), SortByName); // Output list - user defined -/* switch (sortDirType) { + switch (sortDirType) { case ALPHABETICAL : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByName); break; case DIRALPHABETICAL : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByDirName); break; case ALPHABETICALREV : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByNameRev); break; case DIRALPHABETICALREV : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByDirNameRev); break; - };*/ -// nextEntry++; + }; // LOG_DEBUG("DIR: Added Entry %s",path); } else { // LOG_DEBUG("DIR: Error: Failed to add %s",path); @@ -163,6 +159,7 @@ void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) } else { dir = FindDirInfo(path,expand); } + // LOG_DEBUG("DIR: Caching out %s : dir %s",expand,dir->fullname); // delete file objects... for(Bit32u i=0; ifileList.size(); i++) delete dir->fileList[i]; @@ -172,7 +169,6 @@ void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) dir->outputList.clear(); dir->shortNr = 0; save_dir = 0; -// nextEntry = 0; }; bool DOS_Drive_Cache::IsCachedIn(CFileInfo* curDir) @@ -382,7 +378,11 @@ bool DOS_Drive_Cache::OpenDir(const char* path) { char expand[CROSS_LEN] = {0}; CFileInfo* dir = FindDirInfo(path,expand); - return OpenDir(dir,expand); + if (OpenDir(dir,expand)) { + nextEntry = 0; + return true; + } + return false; }; bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, char* expand) @@ -396,6 +396,7 @@ bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, char* expand) // open dir DIR* dirp = opendir(expand); if (dirp) { + // Reset it.. dirFirstTime = true; closedir(dirp); strcpy(dirPath,expand); @@ -462,8 +463,6 @@ bool DOS_Drive_Cache::ReadDir(struct dirent* &result) } else { dirFirstTime=false; } - // Reset it.. - nextEntry = 0; }; return SetResult(dirSearch, result, nextEntry); }; From 02040d708685ca82436084caa46c027baa1b8ad2 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 20 Jan 2003 10:54:26 +0000 Subject: [PATCH 0567/4131] fixed handling of adding/deleting files in dircache Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@646 --- src/dos/drive_cache.cpp | 105 +++++++++++++++++++--------------------- src/dos/drive_local.cpp | 4 +- src/dos/drives.h | 4 ++ 3 files changed, 56 insertions(+), 57 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 2a0c56b6..47408460 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -57,7 +57,6 @@ DOS_Drive_Cache::DOS_Drive_Cache(void) dirBase = new CFileInfo; dirSearch = 0; save_dir = 0; - nextEntry = 0; SetDirSort(DIRALPHABETICAL); }; @@ -66,7 +65,6 @@ DOS_Drive_Cache::DOS_Drive_Cache(const char* path) dirBase = new CFileInfo; dirSearch = 0; save_dir = 0; - nextEntry = 0; SetDirSort(DIRALPHABETICAL); SetBaseDir(path); }; @@ -78,7 +76,7 @@ DOS_Drive_Cache::~DOS_Drive_Cache(void) void DOS_Drive_Cache::SetBaseDir(const char* baseDir) { - strcpy(dirBase->fullname,baseDir); + strcpy(basePath,baseDir); if (OpenDir(baseDir)) { struct dirent* result; ReadDir(result); @@ -141,6 +139,12 @@ void DOS_Drive_Cache::AddEntry(const char* path) }; }; +void DOS_Drive_Cache::DeleteEntry(const char* path, bool ignoreLastDir) +{ + CacheOut(path,ignoreLastDir); + if (nextEntry>0) nextEntry--; +}; + void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) { char expand[CROSS_LEN] = { 0 }; @@ -160,7 +164,7 @@ void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) dir = FindDirInfo(path,expand); } -// LOG_DEBUG("DIR: Caching out %s : dir %s",expand,dir->fullname); +// LOG_DEBUG("DIR: Caching out %s : dir %s",expand,dir->orgname); // delete file objects... for(Bit32u i=0; ifileList.size(); i++) delete dir->fileList[i]; // clear lists @@ -183,11 +187,8 @@ Bit16u DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name) Bit16s high = curDir->longNameList.size()-1; Bit16s mid, res; - CFileInfo* test; - while (low<=high) { mid = (low+high)/2; - test = curDir->longNameList[mid]; res = strncmp(name,curDir->longNameList[mid]->shortname,curDir->longNameList[mid]->compareCount); if (res>0) low = mid+1; else if (res<0) high = mid-1; @@ -211,12 +212,10 @@ Bit16s DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) Bit16s mid,res; while (low<=high) { mid = (low+high)/2; - CFileInfo* test = curDir->fileList[mid]; res = strcmp(shortName,curDir->fileList[mid]->shortname); if (res>0) low = mid+1; else if (res<0) high = mid-1; else { // Found -// strcpy(shortName,curDir->fileList[mid]->fullname); strcpy(shortName,curDir->fileList[mid]->orgname); return mid; }; @@ -249,7 +248,8 @@ void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) char* tmpName = tmpNameBuffer; // Remove Spaces - strcpy(tmpName,info->fullname); + strcpy(tmpName,info->orgname); + upcase(tmpName); createShort = RemoveSpaces(tmpName); // Get Length of filename @@ -328,8 +328,8 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* // LOG_DEBUG("DIR: Find %s",path); // Remove base dir path - start += strlen(dirBase->fullname); - strcpy(expandedPath,dirBase->fullname); + start += strlen(basePath); + strcpy(expandedPath,basePath); do { // bool errorcheck = false; @@ -342,21 +342,24 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* strcat(expandedPath,dir); // Error check -// if ((errorcheck) && (nextDir<0)) { -// LOG_DEBUG("DIR: Error: %s not found.",expandedPath); -// }; - +/* if ((errorcheck) && (nextDir<0)) { + LOG_DEBUG("DIR: Error: %s not found.",expandedPath); + }; +*/ // Follow Directory if ((nextDir>=0) && curDir->fileList[nextDir]->isDir) { curDir = curDir->fileList[nextDir]; - strcpy (curDir->fullname,dir); + strcpy (curDir->orgname,dir); strcpy (work,path); // Cut Directory, if its only part of whole path if (pos) work[(Bit32u)pos-(Bit32u)path] = 0; if (!IsCachedIn(curDir)) { if (OpenDir(curDir,work)) { + char buffer[CROSS_LEN]; struct dirent* result; + strcpy(buffer,dirPath); ReadDir(result); + strcpy(dirPath,buffer); }; } }; @@ -397,7 +400,6 @@ bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, char* expand) DIR* dirp = opendir(expand); if (dirp) { // Reset it.. - dirFirstTime = true; closedir(dirp); strcpy(dirPath,expand); return true; @@ -410,17 +412,14 @@ void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name) { struct stat status; CFileInfo* info = new CFileInfo; - strcpy(info->fullname,name); strcpy(info->orgname ,name); - // always upcase - upcase(info->fullname); info->shortNr = 0; // Read and copy file stats char buffer[CROSS_LEN]; strcpy(buffer,dirPath); strcat(buffer,info->orgname); - stat (buffer,&status); - info->isDir = (S_ISDIR(status.st_mode)>0); + if (stat(buffer,&status)==0) info->isDir = (S_ISDIR(status.st_mode)>0); + else info->isDir = false; // Check for long filenames... CreateShortName(dir, info); // Put file in lists @@ -430,39 +429,35 @@ void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name) bool DOS_Drive_Cache::ReadDir(struct dirent* &result) { - if (dirFirstTime) { - if (!IsCachedIn(dirSearch)) { - // Try to open directory - DIR* dirp = opendir(dirPath); - // Read complete directory - struct dirent* tmpres; - while (tmpres = readdir(dirp)) { - CreateEntry(dirSearch,tmpres->d_name); - // Sort Lists - filelist has to be alphabetically sorted, even in between (for finding double file names) - // hmpf.. bit slow probably... - std::sort(dirSearch->fileList.begin(), dirSearch->fileList.end(), SortByName); - } - // close dir - closedir(dirp); - // Output list - user defined - switch (sortDirType) { - case ALPHABETICAL : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByName); break; - case DIRALPHABETICAL : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByDirName); break; - case ALPHABETICALREV : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByNameRev); break; - case DIRALPHABETICALREV : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByDirNameRev); break; - }; - // Info -/* if (!dirp) { - LOG_DEBUG("DIR: Error Caching in %s",dirPath); - return false; - } else { - char buffer[128]; - sprintf(buffer,"DIR: Caching in %s (%d Files)",dirPath,dirSearch->fileList.size()); - LOG_DEBUG(buffer); - };*/ - } else { - dirFirstTime=false; + if (!IsCachedIn(dirSearch)) { + // Try to open directory + DIR* dirp = opendir(dirPath); + // Read complete directory + struct dirent* tmpres; + while (tmpres = readdir(dirp)) { + CreateEntry(dirSearch,tmpres->d_name); + // Sort Lists - filelist has to be alphabetically sorted, even in between (for finding double file names) + // hmpf.. bit slow probably... + std::sort(dirSearch->fileList.begin(), dirSearch->fileList.end(), SortByName); } + // close dir + closedir(dirp); + // Output list - user defined + switch (sortDirType) { + case ALPHABETICAL : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByName); break; + case DIRALPHABETICAL : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByDirName); break; + case ALPHABETICALREV : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByNameRev); break; + case DIRALPHABETICALREV : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByDirNameRev); break; + }; + // Info +/* if (!dirp) { + LOG_DEBUG("DIR: Error Caching in %s",dirPath); + return false; + } else { + char buffer[128]; + sprintf(buffer,"DIR: Caching in %s (%d Files)",dirPath,dirSearch->fileList.size()); + LOG_DEBUG(buffer); + };*/ }; return SetResult(dirSearch, result, nextEntry); }; diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index f3b7fcae..36d38ac5 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -89,7 +89,7 @@ bool localDrive::FileUnlink(char * name) { strcat(newname,name); CROSS_FILENAME(newname); if (!unlink(dirCache.GetExpandName(newname))) { - dirCache.CacheOut(newname); + dirCache.DeleteEntry(newname); return true; }; return false; @@ -198,7 +198,7 @@ bool localDrive::RemoveDir(char * dir) { strcat(newdir,dir); CROSS_FILENAME(newdir); int temp=rmdir(dirCache.GetExpandName(newdir)); - if (temp==0) dirCache.CacheOut(newdir,true); + if (temp==0) dirCache.DeleteEntry(newdir,true); return (temp==0); } diff --git a/src/dos/drives.h b/src/dos/drives.h index 1d62e97a..e058b978 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -46,6 +46,7 @@ public: void CacheOut (const char* path, bool ignoreLastDir = false); void AddEntry (const char* path); + void DeleteEntry (const char* path, bool ignoreLastDir = false); class CFileInfo { public: @@ -83,6 +84,7 @@ private: CFileInfo* dirBase; CFileInfo* dirSearch; char dirPath [CROSS_LEN]; + char basePath [CROSS_LEN]; bool dirFirstTime; TDirSort sortDirType; CFileInfo* save_dir; @@ -109,6 +111,8 @@ public: void CacheOut (const char* path, bool ignoreLastDir = false) {}; void AddEntry (const char* path) {}; + void DeleteEntry (const char* path, bool ignoreLastDir = false); + public: char basePath [CROSS_LEN]; char dirPath [CROSS_LEN]; From 7cd315de479da3c91c8a7e8275b96e69518ab05e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 20 Jan 2003 18:54:52 +0000 Subject: [PATCH 0568/4131] added ems 054:02 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@647 --- src/ints/ems.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 24329d11..295a874d 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -387,6 +387,9 @@ static Bit8u HandleNameSearch(void) { } } break; + case 0x02: /* Get Total number of handles */ + reg_bx=EMM_MAX_HANDLES; + break; default: LOG_ERROR("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); return EMM_FUNC_NOSUP; From b2af34aa58d1888a330f15a2671ca1e227966481 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 20 Jan 2003 19:03:37 +0000 Subject: [PATCH 0569/4131] some changes for locking screen in fullscreen Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@648 --- src/gui/sdlmain.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index f9387e87..20561a6b 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -35,8 +35,8 @@ #define C_GFXTHREADED 1 //Enabled by default struct SDL_Block { - bool active; //If this isn't set don't draw - bool drawing; + volatile bool active; //If this isn't set don't draw + volatile bool drawing; Bitu width; Bitu height; Bitu bpp; @@ -46,9 +46,11 @@ struct SDL_Block { SDL_Surface * surface; SDL_Joystick * joy; SDL_cond *cond; +#if C_GFXTHREADED SDL_mutex *mutex; SDL_Thread *thread; SDL_sem *sem; +#endif GFX_DrawCallBack draw_callback; struct { bool autolock; @@ -127,18 +129,23 @@ static void SDL_DrawScreen(void) { sdl.drawing=true; if (SDL_MUSTLOCK(sdl.surface)) { - if (SDL_LockSurface(sdl.surface)) E_Exit("SDL:Can't lock surface"); + if (SDL_LockSurface(sdl.surface)) { + sdl.drawing=false; + return; + } } sdl.draw_callback(sdl.surface->pixels); if (SDL_MUSTLOCK(sdl.surface)) { SDL_UnlockSurface(sdl.surface); } - SDL_Flip(sdl.surface); + SDL_UpdateRect(sdl.surface,0,0,0,0); +// SDL_Flip(sdl.surface); sdl.drawing=false; } +#if C_GFXTHREADED int SDL_DisplayThread(void * data) { while (!SDL_SemWait(sdl.sem)) { if (!sdl.active) continue; @@ -148,11 +155,12 @@ int SDL_DisplayThread(void * data) { } return 0; } - +#endif void GFX_DoUpdate(void) { - if (!sdl.active) return; - if (sdl.drawing) return; + if (!sdl.active) + return; + if (sdl.drawing)return; #if C_GFXTHREADED SDL_SemPost(sdl.sem); #else @@ -310,8 +318,6 @@ static void HandleKey(SDL_KeyboardEvent * key) { case SDLK_F11:code=KBD_f11;break; case SDLK_F12:code=KBD_f12;break; -// KBD_esc,KBD_tab,KBD_backspace,KBD_enter,KBD_space, - case SDLK_ESCAPE:code=KBD_esc;break; case SDLK_TAB:code=KBD_tab;break; case SDLK_BACKSPACE:code=KBD_backspace;break; @@ -553,6 +559,5 @@ int main(int argc, char* argv[]) { LOG_MSG("Exit to error: %sPress enter to continue.",error); fgetc(stdin); } - GFX_ShutDown(); - return 0; + return 0; }; From 1dc03e1a4c7d81dd44409f0f84778b1eb0c40d70 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 20 Jan 2003 20:00:28 +0000 Subject: [PATCH 0570/4131] added property for disney Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@649 --- src/dosbox.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 56087e71..1535114d 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -202,6 +202,7 @@ void DOSBOX_Init(void) { // secprop=control->AddSection_prop("gus",&GUS_Init); secprop=control->AddSection_prop("disney",&DISNEY_Init); + secprop->Add_bool("enabled",true); secprop=control->AddSection_prop("speaker",&PCSPEAKER_Init); secprop->Add_bool("enabled",true); From b7088bb6e6f1a18b209df27ab3cfee0b2241a630 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 20 Jan 2003 20:01:49 +0000 Subject: [PATCH 0571/4131] doesn't crash on old configfiles anymore Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@650 --- src/misc/setup.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 76f64269..544ad6d9 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -222,7 +222,8 @@ void Config::ParseConfigFile(const char* configfilename){ return; } char gegevens[150]; - Section* currentsection; + Section* currentsection = NULL; + Section* testsec = NULL; while (in) { in.getline(gegevens,150); char* temp; @@ -237,7 +238,9 @@ void Config::ParseConfigFile(const char* configfilename){ case '[': temp = strrchr(gegevens,']'); *temp=0; - currentsection=GetSection(&gegevens[1]); + testsec = GetSection(&gegevens[1]); + if(testsec != NULL ) currentsection = testsec; + testsec = NULL; break; default: try{ From 4b9c02ea282de6af692e189f2231f4930f90ad8f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 25 Jan 2003 00:01:40 +0000 Subject: [PATCH 0572/4131] Endian support for vga tables. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@651 --- src/hardware/vga.cpp | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 1bf84581..5a1cdb67 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -27,17 +27,12 @@ #include "vga.h" VGA_Type vga; + Bit32u CGAWriteTable[256]; Bit32u ExpandTable[256]; Bit32u Expand16Table[4][16]; Bit32u Expand16BigTable[0x10000]; - -Bit32u FillTable[16]={ - 0x00000000,0x000000ff,0x0000ff00,0x0000ffff, - 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff, - 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff, - 0xffff0000,0xffff00ff,0xffffff00,0xffffffff -}; +Bit32u FillTable[16]; static void EndRetrace(void) { /* start the actual display update now */ @@ -254,15 +249,40 @@ void VGA_Init(Section* sec) { Bitu i,j; for (i=0;i<256;i++) { ExpandTable[i]=i | (i << 8)| (i <<16) | (i << 24); +#ifdef WORDS_BIGENDIAN + CGAWriteTable[i]=((i>>0)&3) | (((i>>2)&3) << 8)| (((i>>4)&3) <<16) | (((i>>6)&3) << 24); +#else CGAWriteTable[i]=((i>>6)&3) | (((i>>4)&3) << 8)| (((i>>2)&3) <<16) | (((i>>0)&3) << 24); +#endif + } + for (i=0;i<16;i++) { +#ifdef WORDS_BIGENDIAN + FillTable[i]= ((i & 1) ? 0xff000000 : 0) | + ((i & 2) ? 0x00ff0000 : 0) | + ((i & 4) ? 0x0000ff00 : 0) | + ((i & 8) ? 0x000000ff : 0) ; +#else + FillTable[i]= ((i & 1) ? 0x000000ff : 0) | + ((i & 2) ? 0x0000ff00 : 0) | + ((i & 4) ? 0x00ff0000 : 0) | + ((i & 8) ? 0xff000000 : 0) ; +#endif } for (j=0;j<4;j++) { for (i=0;i<16;i++) { +#ifdef WORDS_BIGENDIAN + Expand16Table[j][i] = + ((i & 1) ? 1 << j : 0) | + ((i & 2) ? 1 << (8 + j) : 0) | + ((i & 4) ? 1 << (16 + j) : 0) | + ((i & 8) ? 1 << (24 + j) : 0); +#else Expand16Table[j][i] = ((i & 1) ? 1 << (24 + j) : 0) | ((i & 2) ? 1 << (16 + j) : 0) | ((i & 4) ? 1 << (8 + j) : 0) | ((i & 8) ? 1 << j : 0); +#endif } } for (i=0;i<0x10000;i++) { From 6c2c23fd1397c1c3664018c82195834519c95bfc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Jan 2003 12:23:28 +0000 Subject: [PATCH 0573/4131] removed UPCASE Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@652 --- README | 6 +-- src/dos/dos_programs.cpp | 88 +--------------------------------------- src/shell/shell.cpp | 4 -- 3 files changed, 3 insertions(+), 95 deletions(-) diff --git a/README b/README index 391b1d52..06b5c37c 100644 --- a/README +++ b/README @@ -3,7 +3,7 @@ DOSBox v0.57 Usage: ====== -With the new internal shell I've changed the command line a bit, so let's just give some +With the new internal shell We've changed the command line a bit, so let's just give some examples of what you can do now. dosbox @@ -50,10 +50,6 @@ Utility for generating a configfile with the current settings and for generating The option -writeconf filename is used to write the current config settings. The option -writelang filename is used to write the current language strings. -UPCASE -Utility to convert all files subdirectories of a local directory into upcase so DOSBox can use that directory -for mounting. This tool can be quite dangerous if used unproperly. You have been warned. - To get more information about how to use one these programs use the the /? command line switch. The Configfile: diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 0a50b12a..567fd78d 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -149,78 +149,6 @@ static void MEM_ProgramStart(Program * * make) { } -#if !defined (WIN32) /* Unix */ - -class UPCASE : public Program { -public: - void Run(void); - void upcasedir(const char * directory); -}; - -void UPCASE::upcasedir(const char * directory) { - DIR * sdir; - char fullname[512]; - char newname[512]; - struct dirent *tempdata; - struct stat finfo; - - if(!(sdir=opendir(directory))) { - WriteOut(MSG_Get("PROGRAM_UPCASE_ERROR_DIR"),directory); - return; - } - WriteOut(MSG_Get("PROGRAM_UPCASE_SCANNING_DIR"),fullname); - while (tempdata=readdir(sdir)) { - if (strcmp(tempdata->d_name,".")==0) continue; - if (strcmp(tempdata->d_name,"..")==0) continue; - strcpy(fullname,directory); - strcat(fullname,"/"); - strcat(fullname,tempdata->d_name); - strcpy(newname,directory); - strcat(newname,"/"); - upcase(tempdata->d_name); - strcat(newname,tempdata->d_name); - WriteOut(MSG_Get("PROGRAM_UPCASE_RENAME"),fullname,newname); - rename(fullname,newname); - stat(fullname,&finfo); - if(S_ISDIR(finfo.st_mode)) { - upcasedir(fullname); - } - } - closedir(sdir); -} - - -void UPCASE::Run(void) { - /* First check if the directory exists */ - struct stat info; - WriteOut(MSG_Get("PROGRAM_UPCASE_RUN_1")); - if (!cmd->GetCount()) { - WriteOut(MSG_Get("PROGRAM_UPCASE_USAGE")); - return; - } - cmd->FindCommand(1,temp_line); - if (stat(temp_line.c_str(),&info)) { - WriteOut(MSG_Get("PROGRAM_UPCASE_RUN_ERROR_1"),temp_line.c_str()); - return; - } - if(!S_ISDIR(info.st_mode)) { - WriteOut(MSG_Get("PROGRAM_UPCASE_RUN_ERROR_2"),temp_line.c_str()); - return; - } - WriteOut(MSG_Get("PROGRAM_UPCASE_RUN_CHOICE"),temp_line.c_str()); - Bit8u key;Bit16u n=1; - DOS_ReadFile(STDIN,&key,&n); - if (toupper(key)=='Y') { - upcasedir(temp_line.c_str()); - } else { - WriteOut(MSG_Get("PROGRAM_UPCASE_RUN_NO")); - } -} - -static void UPCASE_ProgramStart(Program * * make) { - *make=new UPCASE; -} -#endif // LOADFIX @@ -303,22 +231,10 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_LOADFIX_DEALLOCALL","Used memory freed.\n"); MSG_Add("PROGRAM_LOADFIX_ERROR","Memory allocation error.\n"); -#if !defined (WIN32) /* Unix */ - MSG_Add("PROGRAM_UPCASE_ERROR_DIR","Failed to open directory %s\n"); - MSG_Add("PROGRAM_UPCASE_SCANNING_DIR","Scanning directory %s\n"); - MSG_Add("PROGRAM_UPCASE_RENAME","Renaming %s to %s\n"); - MSG_Add("PROGRAM_UPCASE_RUN_1","UPCASE 0.1 Directory case convertor.\n"); - MSG_Add("PROGRAM_UPCASE_USAGE","Usage UPCASE [local directory]\nThis tool will convert all files and subdirectories in a directory.\nBe VERY sure this directory contains only dos related material.\nOtherwise you might horribly screw up your filesystem.\n"); - MSG_Add("PROGRAM_UPCASE_RUN_ERROR_1","%s doesn't exist\n"); - MSG_Add("PROGRAM_UPCASE_RUN_ERROR_2","%s isn't a directory\n"); - MSG_Add("PROGRAM_UPCASE_RUN_CHOICE","Converting the wrong directories can be very harmfull, please be carefull.\nAre you really really sure you want to convert %s to upcase?Y/N\n"); - MSG_Add("PROGRAM_UPCASE_RUN_NO","Okay better not do it.\n"); -#endif + /*regular setup*/ PROGRAMS_MakeFile("MOUNT.COM",MOUNT_ProgramStart); PROGRAMS_MakeFile("MEM.COM",MEM_ProgramStart); PROGRAMS_MakeFile("LOADFIX.COM",LOADFIX_ProgramStart); -#if !defined (WIN32) /* Unix */ - PROGRAMS_MakeFile("UPCASE.COM",UPCASE_ProgramStart); -#endif + } diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 5d9dba50..b912446e 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -208,10 +208,6 @@ void SHELL_Init() { MSG_Add("SHELL_STARTUP","DOSBox Shell v" VERSION "\n" "DOSBox does not run protected mode games!\n" "For supported shell commands type: HELP\n" -#if! defined (WIN32) - "DOSBox only works with upcase filenames as dos is case-insensitive.\n" - "You can use the UPCASE command for this, but please be careful.\n" -#endif "For more information read the README file in DOSBox directory.\n" "\nHAVE FUN!\nThe DOSBox Team\n\n" ); From e9f1f898d75bf14737406d02d61a89a9202540fb Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 28 Jan 2003 21:18:20 +0000 Subject: [PATCH 0574/4131] DOS_CloseFile: dont close devices Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@653 --- src/dos/dos_files.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 3dc25faf..4f3f4ab1 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -289,7 +289,7 @@ bool DOS_CloseFile(Bit16u entry) { //TODO Figure this out with devices :) DOS_PSP psp(dos.psp); - psp.SetFileHandle(entry,0xff); + if (entry>STDPRN) psp.SetFileHandle(entry,0xff); /* Devices won't allow themselves to be closed or killed */ if (Files[handle]->Close()) { From 5debecf40f09942e0ec87adc2c961c1f7eb6994c Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 28 Jan 2003 21:18:55 +0000 Subject: [PATCH 0575/4131] GetFileAttr works now with dirs too. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@654 --- src/dos/drive_local.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 36d38ac5..51b0420d 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -167,9 +167,9 @@ bool localDrive::GetFileAttr(char * name,Bit16u * attr) { strcat(newname,name); CROSS_FILENAME(newname); dirCache.ExpandName(newname); - FILE * hand=fopen(newname,"rb"); - if (hand) { - fclose(hand); + + struct stat status; + if (stat(newname,&status)==0) { *attr=DOS_ATTR_ARCHIVE; return true; } From 6c0fc8f3e379fcf1b06257d6dcb6bd883ddf423d Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 28 Jan 2003 21:19:29 +0000 Subject: [PATCH 0576/4131] fixed bug in POPAD Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@655 --- src/cpu/core_16/prefix_66.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index 340be2db..08b0064f 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -146,7 +146,7 @@ switch(Fetchb()) { Push_32(reg_esp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi); break; case 0x61: /* POPAD */ - reg_edi=Pop_32();reg_edi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP + reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32(); break; case 0x64: /* SEG FS: */ From 22b81376d447943b0d90a08a9c96ebac4c3a3f75 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 30 Jan 2003 15:37:15 +0000 Subject: [PATCH 0577/4131] changed HostPt* memory -> HostPt memory Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@656 --- src/ints/ems.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 295a874d..060f6a3d 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -83,7 +83,7 @@ struct EMM_Mapping { }; struct EMM_Page { - HostPt * memory; + HostPt memory; Bit16u handle; Bit16u next; }; @@ -159,7 +159,7 @@ static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & handle) { while (pages) { if (emm_pages[page].handle==NULL_HANDLE) { emm_pages[page].handle=handle; - emm_pages[page].memory=(HostPt *)malloc(EMM_PAGE_SIZE); + emm_pages[page].memory=(HostPt)malloc(EMM_PAGE_SIZE); if (!emm_pages[page].memory) E_Exit("EMM:Cannont allocate memory"); if (last!=NULL_PAGE) emm_pages[last].next=page; else emm_handles[handle].first_page=page; @@ -209,7 +209,7 @@ static Bit8u EMM_ReallocatePages(Bit16u handle,Bit16u & pages) { while (pages) { if (emm_pages[page].handle==NULL_HANDLE) { emm_pages[page].handle=handle; - emm_pages[page].memory=(HostPt *)malloc(EMM_PAGE_SIZE); + emm_pages[page].memory=(HostPt)malloc(EMM_PAGE_SIZE); if (!emm_pages[page].memory) E_Exit("EMM:Cannont allocate memory"); if (last!=NULL_PAGE) emm_pages[last].next=page; else emm_handles[handle].first_page=page; From f662453ba84c0a7fe926087e899afc536bbae5e6 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 30 Jan 2003 15:37:54 +0000 Subject: [PATCH 0578/4131] fixed bug in mouse position clipping Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@657 --- src/ints/mouse.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 8b35bc5c..07eec7e0 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -324,11 +324,11 @@ void Mouse_CursorMoved(float x,float y) { mouse.mickey_y += dy; mouse.x += dx; - if (mouse.x>mouse.max_x) mouse.x=mouse.max_x;; - if (mouse.x=mouse.max_x) mouse.x=mouse.max_x-1.0f; + if (mouse.x< mouse.min_x) mouse.x=mouse.min_x; mouse.y += dy; - if (mouse.y>mouse.max_y) mouse.y=mouse.max_y;; - if (mouse.y=mouse.max_y) mouse.y=mouse.max_y-1.0f; + if (mouse.y< mouse.min_y) mouse.y=mouse.min_y; Mouse_AddEvent(MOUSE_MOVED); DrawCursor(); } From ade6f33cd797e4a3ff801633812957521e38e960 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 30 Jan 2003 15:40:57 +0000 Subject: [PATCH 0579/4131] fixed tab key stuck when switching tasks (no keyboard response) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@658 --- src/gui/sdlmain.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 20561a6b..8851f8f7 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -458,7 +458,10 @@ static void HandleVideoResize(SDL_ResizeEvent * resize) { } +static Bit8u laltstate = SDL_KEYUP; + void GFX_Events() { + SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { @@ -471,6 +474,9 @@ void GFX_Events() { break; case SDL_KEYDOWN: case SDL_KEYUP: + // ignore event lalt+tab + if (event.key.keysym.sym==SDLK_LALT) laltstate = event.key.type; + if ((event.key.keysym.sym==SDLK_TAB) && (laltstate==SDL_KEYDOWN)) break; HandleKey(&event.key); break; case SDL_MOUSEMOTION: From 5d8568a3ccb91a138f4d4c6ef8c58eec12042eb5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 5 Feb 2003 19:12:20 +0000 Subject: [PATCH 0580/4131] Pause Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@659 --- src/shell/shell.cpp | 4 +++- src/shell/shell_cmds.cpp | 7 ++++++- src/shell/shell_inc.h | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index b912446e..aefe64c5 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -188,7 +188,7 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_CHDIR_ERROR","Unable to change to: %s\n"); MSG_Add("SHELL_CMD_MKDIR_ERROR","Unable to make: %s\n"); MSG_Add("SHELL_CMD_RMDIR_ERROR","Unable to remove: %s\n"); - MSG_Add("SHELL_CMD_DEL_ERROR","Unable to delete: %s\n"); + MSG_Add("SHELL_CMD_DEL_ERROR","Unable to delete: %s\n"); MSG_Add("SHELL_SYNTAXERROR","The syntax of the command is incorrect.\n"); MSG_Add("SHELL_CMD_SET_NOT_SET","Environment variable %s not defined\n"); MSG_Add("SHELL_CMD_SET_OUT_OF_SPACE","Not enough environment space left.\n"); @@ -204,6 +204,8 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_DIR_BYTES_FREE","%5d Dir(s) %17s Bytes free\n"); MSG_Add("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\n"); MSG_Add("SHELL_EXECUTE_ILLEGAL_COMMAND","Illegal command: %s.\n"); + MSG_Add("SHELL_CMD_PAUSE","Press any key to continue.\n"); + MSG_Add("SHELL_CMD_PAUSE_HELP","Waits for 1 keystroke to continue.\n"); MSG_Add("SHELL_STARTUP","DOSBox Shell v" VERSION "\n" "DOSBox does not run protected mode games!\n" diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 5b0004b5..d5a081c6 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -42,6 +42,7 @@ static SHELL_Cmd cmd_list[]={ "REM", 0, &DOS_Shell::CMD_REM, "SHELL_CMD_REM_HELP", "RENAME", 0, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP", "REN", 1, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP", + "PAUSE", 0, &DOS_Shell::CMD_PAUSE, "SHELL_CMD_PAUSE_HELP", /* "CHDIR", 0, &DOS_Shell::CMD_CHDIR, "Change Directory", "MKDIR", 0, &DOS_Shell::CMD_MKDIR, "Make Directory", @@ -427,4 +428,8 @@ nextfile: void DOS_Shell::CMD_REM(char * args) { } - +void DOS_Shell::CMD_PAUSE(char * args){ + WriteOut(MSG_Get("SHELL_CMD_PAUSE")); + Bit8u c;Bit16u n=1; + DOS_ReadFile (STDIN,&c,&n); +} \ No newline at end of file diff --git a/src/shell/shell_inc.h b/src/shell/shell_inc.h index e21f323d..59ee1b9d 100644 --- a/src/shell/shell_inc.h +++ b/src/shell/shell_inc.h @@ -79,7 +79,7 @@ public: void CMD_REM(char * args); void CMD_RENAME(char * args); void SyntaxError(void); - + void CMD_PAUSE(char * args); /* The shell's variables */ Bit16u input_handle; BatchFile * bf; From 9be6cee6aca37a32fcfcbdfa9cb47c627124cef1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 5 Feb 2003 19:21:53 +0000 Subject: [PATCH 0581/4131] fixed ultima 1, added 2 color cga putpixel, fixed cga getpixel. speeded up findsettings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@660 --- src/ints/int10.cpp | 6 ++++- src/ints/int10.h | 8 +++++- src/ints/int10_char.cpp | 18 ++++++++++--- src/ints/int10_modes.cpp | 10 +++++--- src/ints/int10_put_pixel.cpp | 50 ++++++++++++++++++++++++++---------- 5 files changed, 68 insertions(+), 24 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 34d40cf7..055c6ec7 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -32,6 +32,8 @@ static Bitu call_10; static bool warned_ff=false; static bool warned_int10_0b=false; +Int10Data int10; + static Bitu INT10_Handler(void) { switch (reg_ah) { @@ -53,6 +55,7 @@ static Bitu INT10_Handler(void) { break; case 0x04: /* read light pen pos YEAH RIGHT */ LOG_WARN("INT10:04:Ligthpen not supported"); + reg_ah=0; break; case 0x05: /* Set Active Page */ if (reg_al & 0x80) LOG_DEBUG("Func %x",reg_al); @@ -62,7 +65,8 @@ static Bitu INT10_Handler(void) { //TODO Graphics mode scroll INT10_ScrollWindow(reg_ch,reg_cl,reg_dh,reg_dl,-reg_al,reg_bh,0xFF); break; - case 0x07: /* Scroll Down */ + case 0x07: + /* Scroll Down */ INT10_ScrollWindow(reg_ch,reg_cl,reg_dh,reg_dl,reg_al,reg_bh,0xFF); break; case 0x08: /* Read character & attribute at cursor */ diff --git a/src/ints/int10.h b/src/ints/int10.h index 9ccc3a65..15439f53 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -101,7 +101,7 @@ #define PLANAR2 0x04 #define PLANAR4 0x05 #define LINEAR8 0x06 - +#define CGA2 0x07 // for Tandy #define TANDY16 0x0A @@ -206,3 +206,9 @@ void INT10_SetGfxControllerToDefault(void); /* Sup Groups */ void INT10_SetupRomMemory(void); +struct Int10Data { + Bit8u mode; + VGAMODES * entry; +}; + +extern Int10Data int10; \ No newline at end of file diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index a6842874..c1b298cd 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -89,6 +89,8 @@ static INLINE void PLANAR4_FillRow(VGAMODES * curmode,Bit8u cleft,Bit8u cright,B for (Bitu x=0;xtype==GRAPH) page=0xff; BIOS_NCOLS;BIOS_NROWS; if(rul>rlr) return; if(cul>clr) return; @@ -114,7 +118,6 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit /* Get the correct page */ if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); - VGAMODES * curmode=GetCurrentMode(); PhysPt base=PhysMake(curmode->sstart,curmode->slength*page); /* See how much lines need to be copies */ @@ -138,6 +141,7 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit case MTEXT: case CTEXT: TEXT_CopyRow(curmode,cul,clr,start,start+nlines,base);break; + case CGA2: case CGA: CGA_CopyRow(curmode,cul,clr,start,start+nlines,base);break; case PLANAR4: @@ -245,7 +249,7 @@ INLINE static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u at } break; case GRAPH: - { + { /* Amount of lines */ Bit8u * fontdata; Bit16u x,y; @@ -274,7 +278,7 @@ INLINE static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u at Bit16u tx=x; while (bitsel) { if (bitline&bitsel) INT10_PutPixel(tx,y,page,attr); - else INT10_PutPixel(tx,y,page,0); + else INT10_PutPixel(tx,y,page,attr & 0x80); tx++; bitsel>>=1; } @@ -286,6 +290,8 @@ INLINE static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u at } void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) { + VGAMODES * curmode=GetCurrentMode(); + if (curmode->type==GRAPH) page=0xff; if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); @@ -303,6 +309,8 @@ void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page) { + VGAMODES * curmode=GetCurrentMode(); + if (curmode->type==GRAPH) page=0xff; if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); BIOS_NCOLS;BIOS_NROWS; Bit8u cur_row=CURSOR_POS_ROW(page); @@ -348,6 +356,8 @@ void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page) { } void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,Bit16u count,Bit8u page) { + VGAMODES * curmode=GetCurrentMode(); + if (curmode->type==GRAPH) page=0xff; if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); BIOS_NCOLS;BIOS_NROWS; diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 1f578972..15731bd8 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -33,7 +33,7 @@ VGAMODES vga_modes[MODE_MAX+1]= {0x03, 0xFFFF, TEXT, CTEXT, 4, 4, 720, 400, 80, 25, 9, 16, 0xB800, 0x1000, 0x67, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x02}, {0x04, 0xFFFF, GRAPH, CGA, 4, 2, 320, 200, 40, 25, 8, 8, 0xB800, 0x0800, 0x63, 0xFF, 0x02, 0x01, 0x01, 0x02, 0x01}, {0x05, 0xFFFF, GRAPH, CGA, 1, 2, 320, 200, 40, 25, 8, 8, 0xB800, 0x0800, 0x63, 0xFF, 0x02, 0x01, 0x01, 0x02, 0x01}, - {0x06, 0xFFFF, GRAPH, CGA, 1, 1, 640, 200, 80, 25, 8, 8, 0xB800, 0x1000, 0x63, 0xFF, 0x03, 0x02, 0x02, 0x03, 0x01}, + {0x06, 0xFFFF, GRAPH, CGA2, 1, 1, 640, 200, 80, 25, 8, 8, 0xB800, 0x1000, 0x63, 0xFF, 0x03, 0x02, 0x02, 0x03, 0x01}, {0x07, 0xFFFF, TEXT, MTEXT, 4, 4, 720, 400, 80, 25, 9, 16, 0xB000, 0x1000, 0x66, 0xFF, 0x04, 0x03, 0x03, 0x01, 0x00}, {0x0D, 0xFFFF, GRAPH, PLANAR4, 8, 4, 320, 200, 40, 25, 8, 8, 0xA000, 0x2000, 0x63, 0xFF, 0x05, 0x04, 0x04, 0x04, 0x01}, @@ -239,9 +239,11 @@ static Bit8u FindVideoMode(Bit8u mode) { } VGAMODES * GetCurrentMode(void) { - Bit8u ret=FindVideoMode(real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)&127); - if (ret==0xff) return 0; - return &vga_modes[ret]; + Bit8u mode=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)&127; + if (mode==int10.mode) return int10.entry; + int10.mode=mode; + int10.entry=&vga_modes[FindVideoMode(mode)]; + return int10.entry; } diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index eb425c04..60831dc3 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -22,24 +22,37 @@ #include "int10.h" static Bit8u cga_masks[4]={~192,~48,~12,~3}; - +static Bit8u cga_masks2[8]={~128,~64,~32,~16,~8,~4,~2,~1}; void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { VGAMODES * curmode=GetCurrentMode(); - switch (curmode->memmodel) { case CGA: { - Bit16u off=(y>>1)*80+(x>>2); - if (y&1) off+=8*1024; - Bit8u old=real_readb(0xb800,off); - if (color & 0x80) { - color&=3; - old^=color << (2*(3-(x&3))); - } else { - old=old&cga_masks[x&3]|((color&3) << (2*(3-(x&3)))); - } - real_writeb(0xb800,off,old); + Bit16u off=(y>>1)*80+(x>>2); + if (y&1) off+=8*1024; + Bit8u old=real_readb(0xb800,off); + if (color & 0x80) { + color&=3; + old^=color << (2*(3-(x&3))); + } else { + old=old&cga_masks[x&3]|((color&3) << (2*(3-(x&3)))); + } + real_writeb(0xb800,off,old); + } + break; + case CGA2: + { + Bit16u off=(y>>1)*80+(x>>3); + if (y&1) off+=8*1024; + Bit8u old=real_readb(0xb800,off); + if (color & 0x80) { + color&=1; + old^=color << ((7-(x&7))); + } else { + old=old&cga_masks2[x&7]|((color&1) << ((7-(x&7)))); + } + real_writeb(0xb800,off,old); } break; case PLANAR4: @@ -60,6 +73,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { mem_writeb(off,0xff); /* Restore bitmask */ IO_Write(0x3ce,0x8);IO_Write(0x3cf,0xff); + IO_Write(0x3ce,0x1);IO_Write(0x3cf,0); /* Restore write operating if changed */ if (color & 0x80) { IO_Write(0x3ce,0x3);IO_Write(0x3cf,0x0); } break; @@ -72,7 +86,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { case CTEXT: case MTEXT: default: - LOG_WARN("INT10:PutPixel Unhanled memory model"); + LOG_WARN("INT10:PutPixel Unhandled memory model %d",curmode->memmodel); break; } } @@ -85,7 +99,15 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { Bit16u off=(y>>1)*80+(x>>2); if (y&1) off+=8*1024; Bit8u val=real_readb(0xb800,off); - *color=val<<((x&3)*2); + *color=(val>>(((3-x&3))*2)) & 3 ; + } + break; + case CGA2: + { + Bit16u off=(y>>1)*80+(x>>3); + if (y&1) off+=8*1024; + Bit8u val=real_readb(0xb800,off); + *color=(val>>(((7-x&7)))) & 1 ; } break; case PLANAR4: From 00080a4d9d03bbccef09e4fa4549e8517dfa7f51 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 6 Feb 2003 22:21:58 +0000 Subject: [PATCH 0582/4131] MakeEnv: added hack to allow creation from envblock in unused mem (0xCD) Dos_Execute: extrabytes now added to the imagesize Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@661 --- src/dos/dos_execute.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index dd6ab205..d435d574 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -137,6 +137,9 @@ static bool MakeEnv(char * name,Bit16u * segment) { } if (parentenv) { + // hack to allow creation from envblock in unused mem (0xCD) + if (readw(envread)==0xCDCD) writew(envread,0x0000); + for (envsize=0; ;envsize++) { if (envsize>=MAXENV - ENV_KEEPFREE) { DOS_SetError(DOSERR_ENVIRONMENT_INVALID); @@ -230,7 +233,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { else { headersize=head.headersize*16; imagesize=(head.pages)*512-headersize; - if (head.extrabytes) imagesize-=(512-head.extrabytes); + if (head.extrabytes) imagesize += head.extrabytes % 512; } if (flags!=OVERLAY) { /* Create an environment block */ From 0684c1784fa80b264b6f63371af2315f8e5b57be Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 10 Feb 2003 12:38:44 +0000 Subject: [PATCH 0583/4131] Fixed bug (caching baseDir) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@662 --- src/dos/drive_cache.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 47408460..44565bb8 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -327,6 +327,18 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* // LOG_DEBUG("DIR: Find %s",path); + // hehe, baseDir should be cached in... + if (!IsCachedIn(curDir)) { + strcpy(work,basePath); + if (OpenDir(curDir,work)) { + char buffer[CROSS_LEN]; + struct dirent* result; + strcpy(buffer,dirPath); + ReadDir(result); + strcpy(dirPath,buffer); + }; + }; + // Remove base dir path start += strlen(basePath); strcpy(expandedPath,basePath); From 50385d3c0508394c707c5f76caa8c43493e5b035 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 13 Feb 2003 23:32:00 +0000 Subject: [PATCH 0584/4131] Added custom DTA member dirID for multiple findfirst/findnext functionality. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@663 --- include/dos_inc.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index ba1c6561..575bb79c 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -354,6 +354,9 @@ public: Bit8u GetSearchDrive(void); void GetSearchParams(Bit8u & _sattr,char * _spattern); void GetResult(char * _name,Bit32u & _size,Bit16u & _date,Bit16u & _time,Bit8u & _attr); + + void SetDirID(Bit16u entry) { sSave(sDTA,dirID,entry); }; + Bit16u GetDirID(void) { return sGet(sDTA,dirID); }; private: #pragma pack(1) struct sDTA { @@ -361,7 +364,8 @@ private: Bit8u sattr; /* The Attributes that need to be found */ Bit8u sname[8]; /* The Search pattern for the filename */ Bit8u sext[3]; /* The Search pattern for the extenstion */ - Bit8u fill[8]; + Bit16u dirID; /* custom: dir-search ID for multiple searches at the same time */ + Bit8u fill[6]; Bit8u attr; Bit16u time; Bit16u date; From e727664414dfc09252275d5198b002eb1a638223 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 13 Feb 2003 23:33:43 +0000 Subject: [PATCH 0585/4131] Added support for multiple findfirst/findnext at the same time. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@664 --- src/dos/drive_cache.cpp | 137 +++++++++++++++++++++++++++------------- src/dos/drive_local.cpp | 26 +++++--- src/dos/drives.h | 44 ++++++++----- 3 files changed, 139 insertions(+), 68 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 44565bb8..b3ef37d7 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -55,16 +55,19 @@ bool SortByDirNameRev(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFi DOS_Drive_Cache::DOS_Drive_Cache(void) { dirBase = new CFileInfo; - dirSearch = 0; save_dir = 0; + srchNr = 0; + for (Bit32u i=0; i=0)) return; + CreateEntry(dir,file); // Sort Lists - filelist has to be alphabetically sorted std::sort(dir->fileList.begin(), dir->fileList.end(), SortByName); @@ -142,7 +155,7 @@ void DOS_Drive_Cache::AddEntry(const char* path) void DOS_Drive_Cache::DeleteEntry(const char* path, bool ignoreLastDir) { CacheOut(path,ignoreLastDir); - if (nextEntry>0) nextEntry--; + if (dirSearch[srchNr]->nextEntry>0) dirSearch[srchNr]->nextEntry--; }; void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) @@ -180,6 +193,31 @@ bool DOS_Drive_Cache::IsCachedIn(CFileInfo* curDir) return (curDir->fileList.size()>0); }; + +bool DOS_Drive_Cache::GetShortName(const char* fullname, char* shortname) +{ + // Get Dir Info + char expand[CROSS_LEN] = {0}; + CFileInfo* curDir = FindDirInfo(fullname,expand); + + Bit16s foundNr = 0; + Bit16s low = 0; + Bit16s high = curDir->longNameList.size()-1; + Bit16s mid, res; + + while (low<=high) { + mid = (low+high)/2; + res = strcmp(fullname,curDir->longNameList[mid]->orgname); + if (res>0) low = mid+1; else + if (res<0) high = mid-1; + else { + strcpy(shortname,curDir->longNameList[mid]->shortname); + return true; + }; + } + return false; +}; + Bit16u DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name) { Bit16s foundNr = 0; @@ -319,6 +357,7 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* char* start = (char*)path; char* pos; CFileInfo* curDir = dirBase; + Bit16u id; if (save_dir && (strcmp(path,save_path)==0)) { strcpy(expandedPath,save_expanded); @@ -327,22 +366,23 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* // LOG_DEBUG("DIR: Find %s",path); - // hehe, baseDir should be cached in... - if (!IsCachedIn(curDir)) { - strcpy(work,basePath); - if (OpenDir(curDir,work)) { - char buffer[CROSS_LEN]; - struct dirent* result; - strcpy(buffer,dirPath); - ReadDir(result); - strcpy(dirPath,buffer); - }; - }; - // Remove base dir path start += strlen(basePath); strcpy(expandedPath,basePath); + // hehe, baseDir should be cached in... + if (!IsCachedIn(curDir)) { + strcpy(work,basePath); + if (OpenDir(curDir,work,id)) { + char buffer[CROSS_LEN]; + struct dirent* result; + strcpy(buffer,dirPath); + ReadDir(id,result); + strcpy(dirPath,buffer); + free[id] = true; + }; + }; + do { // bool errorcheck = false; pos = strchr(start,CROSS_FILESPLIT); @@ -366,12 +406,13 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* // Cut Directory, if its only part of whole path if (pos) work[(Bit32u)pos-(Bit32u)path] = 0; if (!IsCachedIn(curDir)) { - if (OpenDir(curDir,work)) { + if (OpenDir(curDir,work,id)) { char buffer[CROSS_LEN]; struct dirent* result; strcpy(buffer,dirPath); - ReadDir(result); + ReadDir(id,result); strcpy(dirPath,buffer); + free[id] = true; }; } }; @@ -389,31 +430,33 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* return curDir; }; -bool DOS_Drive_Cache::OpenDir(const char* path) +bool DOS_Drive_Cache::OpenDir(const char* path, Bit16u& id) { char expand[CROSS_LEN] = {0}; CFileInfo* dir = FindDirInfo(path,expand); - if (OpenDir(dir,expand)) { - nextEntry = 0; + if (OpenDir(dir,expand,id)) { + dirSearch[id]->nextEntry = 0; return true; } return false; }; -bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, char* expand) +bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, char* expand, Bit16u& id) { - dirSearch = dir; + id = GetFreeID(); + dirSearch[id] = dir; // Add "/" char end[2]={CROSS_FILESPLIT,0}; if (expand[strlen(expand)-1]!=CROSS_FILESPLIT) strcat(expand,end); // open dir - if (dirSearch) { + if (dirSearch[id]) { // open dir DIR* dirp = opendir(expand); if (dirp) { // Reset it.. closedir(dirp); strcpy(dirPath,expand); + free[id] = false; return true; } }; @@ -439,27 +482,31 @@ void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name) dir->outputList.push_back(info); }; -bool DOS_Drive_Cache::ReadDir(struct dirent* &result) +bool DOS_Drive_Cache::ReadDir(Bit16u id, struct dirent* &result) { - if (!IsCachedIn(dirSearch)) { + // shouldnt happen... + if (id>MAX_OPENDIRS) return false; + + if (!IsCachedIn(dirSearch[id])) { // Try to open directory DIR* dirp = opendir(dirPath); + if (!dirp) return false; // Read complete directory struct dirent* tmpres; while (tmpres = readdir(dirp)) { - CreateEntry(dirSearch,tmpres->d_name); + CreateEntry(dirSearch[id],tmpres->d_name); // Sort Lists - filelist has to be alphabetically sorted, even in between (for finding double file names) // hmpf.. bit slow probably... - std::sort(dirSearch->fileList.begin(), dirSearch->fileList.end(), SortByName); + std::sort(dirSearch[id]->fileList.begin(), dirSearch[id]->fileList.end(), SortByName); } // close dir closedir(dirp); // Output list - user defined switch (sortDirType) { - case ALPHABETICAL : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByName); break; - case DIRALPHABETICAL : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByDirName); break; - case ALPHABETICALREV : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByNameRev); break; - case DIRALPHABETICALREV : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByDirNameRev); break; + case ALPHABETICAL : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByName); break; + case DIRALPHABETICAL : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByDirName); break; + case ALPHABETICALREV : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByNameRev); break; + case DIRALPHABETICALREV : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByDirNameRev); break; }; // Info /* if (!dirp) { @@ -467,11 +514,13 @@ bool DOS_Drive_Cache::ReadDir(struct dirent* &result) return false; } else { char buffer[128]; - sprintf(buffer,"DIR: Caching in %s (%d Files)",dirPath,dirSearch->fileList.size()); + sprintf(buffer,"DIR: Caching in %s (%d Files)",dirPath,dirSearch[srchNr]->fileList.size()); LOG_DEBUG(buffer); };*/ }; - return SetResult(dirSearch, result, nextEntry); + if (SetResult(dirSearch[id], result, dirSearch[id]->nextEntry)) return true; + free[id] = true; + return false; }; bool DOS_Drive_Cache::SetResult(CFileInfo* dir, struct dirent* &result, Bit16u entryNr) @@ -484,7 +533,7 @@ bool DOS_Drive_Cache::SetResult(CFileInfo* dir, struct dirent* &result, Bit16u e // copy filename, short version strcpy(result->d_name,info->shortname); // Set to next Entry - nextEntry = entryNr+1; + dir->nextEntry = entryNr+1; return true; }; @@ -502,19 +551,21 @@ void DOS_No_Drive_Cache::SetBaseDir(const char* path) strcpy(basePath,path); } -bool DOS_No_Drive_Cache::OpenDir(const char* path) +bool DOS_No_Drive_Cache::OpenDir(const char* path, Bit16u& id) { + id = 0; strcpy(dirPath,path); if((srch_opendir=opendir(dirPath))==NULL) return false; return true; }; -bool DOS_No_Drive_Cache::ReadDir(struct dirent* &result) +bool DOS_No_Drive_Cache::ReadDir(Bit16u id, struct dirent* &result) { - if((result=readdir(srch_opendir))==NULL) { + if (!srch_opendir) return false; + if ((result=readdir(srch_opendir))==NULL) { closedir(srch_opendir); srch_opendir=NULL; return false; } return true; -}; \ No newline at end of file +}; diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 51b0420d..88f59f5e 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -51,7 +51,7 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) { CROSS_FILENAME(newname); FILE * hand=fopen(dirCache.GetExpandName(newname),"wb+"); if (!hand) return false; - dirCache.AddEntry(newname); + dirCache.AddEntry(newname, true); /* Make the 16 bit device information */ *file=new localFile(hand,0x202); return true; @@ -98,18 +98,21 @@ bool localDrive::FileUnlink(char * name) { bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { - strcpy(srch_dir,basedir); - strcat(srch_dir,_dir); - CROSS_FILENAME(srch_dir); + char tempDir[CROSS_LEN]; + strcpy(tempDir,basedir); + strcat(tempDir,_dir); + CROSS_FILENAME(tempDir); char end[2]={CROSS_FILESPLIT,0}; - if (srch_dir[strlen(srch_dir)-1]!=CROSS_FILESPLIT) strcat(srch_dir,end); + if (tempDir[strlen(tempDir)-1]!=CROSS_FILESPLIT) strcat(tempDir,end); - if (!dirCache.OpenDir(srch_dir)) return false; + Bit16u id; + if (!dirCache.OpenDir(tempDir,id)) return false; + strcpy(srchInfo[id].srch_dir,tempDir); + dta.SetDirID(id); return FindNext(dta); } - bool localDrive::FindNext(DOS_DTA & dta) { struct dirent* dir_ent; @@ -121,12 +124,16 @@ bool localDrive::FindNext(DOS_DTA & dta) { dta.GetSearchParams(srch_attr,srch_pattern); + Bit16u id = dta.GetDirID(); + again: - if (!dirCache.ReadDir(dir_ent)) return false; + if (!dirCache.ReadDir(id,dir_ent)) { + return false; + } if(!WildFileCmp(dir_ent->d_name,srch_pattern)) goto again; - strcpy(full_name,srch_dir); + strcpy(full_name,srchInfo[id].srch_dir); strcat(full_name,dir_ent->d_name); if (stat(dirCache.GetExpandName(full_name),&stat_block)!=0) { goto again; @@ -287,7 +294,6 @@ Bit8u localDrive::GetMediaByte(void) { localDrive::localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid) { strcpy(basedir,startdir); sprintf(info,"local directory %s",startdir); - srch_opendir=NULL; allocation.bytes_sector=_bytes_sector; allocation.sectors_cluster=_sectors_cluster; allocation.total_clusters=_total_clusters; diff --git a/src/dos/drives.h b/src/dos/drives.h index e058b978..92d5f034 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -24,7 +24,8 @@ #include #include "dos_system.h" #include "cross.h" - + +#define MAX_OPENDIRS 16 bool WildFileCmp(const char * file, const char * wild); @@ -38,14 +39,15 @@ public: void SetBaseDir (const char* path); void SetDirSort (TDirSort sort) { sortDirType = sort; }; - bool OpenDir (const char* path); - bool ReadDir (struct dirent* &result); + bool OpenDir (const char* path, Bit16u& id); + bool ReadDir (Bit16u id, struct dirent* &result); void ExpandName (char* path); char* GetExpandName (const char* path); + bool GetShortName (const char* fullname, char* shortname); void CacheOut (const char* path, bool ignoreLastDir = false); - void AddEntry (const char* path); + void AddEntry (const char* path, bool checkExist = false); void DeleteEntry (const char* path, bool ignoreLastDir = false); class CFileInfo { @@ -56,10 +58,10 @@ public: longNameList.clear(); outputList.clear(); }; - char fullname [CROSS_LEN]; char orgname [CROSS_LEN]; char shortname [DOS_NAMELENGTH_ASCII]; bool isDir; + Bit16u nextEntry; Bit16u shortNr; Bit16u compareCount; // contents @@ -77,12 +79,11 @@ private: bool IsCachedIn (CFileInfo* dir); CFileInfo* FindDirInfo (const char* path, char* expandedPath); bool RemoveSpaces (char* str); - bool OpenDir (CFileInfo* dir, char* path); + bool OpenDir (CFileInfo* dir, char* path, Bit16u& id); void CreateEntry (CFileInfo* dir, const char* name); + Bit16u GetFreeID (void); - Bit32u nextEntry; CFileInfo* dirBase; - CFileInfo* dirSearch; char dirPath [CROSS_LEN]; char basePath [CROSS_LEN]; bool dirFirstTime; @@ -91,6 +92,11 @@ private: char save_path [CROSS_LEN]; char save_expanded [CROSS_LEN]; + Bit16u srchNr; + CFileInfo* dirSearch [MAX_OPENDIRS]; + char dirSearchName [MAX_OPENDIRS]; + bool free [MAX_OPENDIRS]; + }; class DOS_No_Drive_Cache { @@ -103,15 +109,19 @@ public: void SetBaseDir (const char* path); void SetDirSort (TDirSort sort) {}; - bool OpenDir (const char* path); - bool ReadDir (struct dirent* &result); + bool OpenDir (const char* path, Bit16u& id); + bool ReadDir (Bit16u id, struct dirent* &result); void ExpandName (char* path) {}; char* GetExpandName (const char* path) { return (char*)path; }; + bool GetShortName (const char* fullname, char* shortname) { return false; }; void CacheOut (const char* path, bool ignoreLastDir = false) {}; - void AddEntry (const char* path) {}; - void DeleteEntry (const char* path, bool ignoreLastDir = false); + void AddEntry (const char* path, bool checkExists = false) {}; + void DeleteEntry (const char* path, bool ignoreLastDir = false) {}; + + void SetCurrentEntry (Bit16u entry) {}; + Bit16u GetCurrentEntry (void) { return 0; }; public: char basePath [CROSS_LEN]; @@ -136,10 +146,14 @@ public: bool FileExists(const char* name); bool FileStat(const char* name, FileStat_Block * const stat_block); Bit8u GetMediaByte(void); + bool GetShortName(const char* fullname, char* shortname) { return dirCache.GetShortName(fullname, shortname); }; private: char basedir[CROSS_LEN]; - char srch_dir[CROSS_LEN]; - DIR * srch_opendir; + + struct { + char srch_dir[CROSS_LEN]; + } srchInfo[MAX_OPENDIRS]; + struct { Bit16u bytes_sector; Bit8u sectors_cluster; @@ -147,7 +161,7 @@ private: Bit16u free_clusters; Bit8u mediaid; } allocation; - DOS_Drive_Cache dirCache; + DOS_Drive_Cache dirCache; }; struct VFILE_Block; From 44e7e65ab5ec609fe5993f8f32a06c23f31be868 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 14 Feb 2003 22:16:19 +0000 Subject: [PATCH 0586/4131] Added Int 21/67: Set file handle count Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@665 --- include/dos_inc.h | 3 ++- src/dos/dos.cpp | 11 +++++++---- src/dos/dos_classes.cpp | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 575bb79c..af5abcf7 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -259,7 +259,8 @@ public: void SetFCB1 (RealPt src); void SetFCB2 (RealPt src); void SetCommandTail (RealPt src); - + bool SetNumFiles (Bit16u fileNum); + private: #pragma pack(1) struct sPSP { diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 15cc5b5a..83f14cf6 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -784,11 +784,14 @@ static Bitu DOS_21Handler(void) { } LOG_ERROR("DOS:Setting code page table is not supported"); break; - case 0x67: /* Set handle countr */ + case 0x67: /* Set handle count */ /* Weird call to increase amount of file handles needs to allocate memory if >20 */ - LOG_DEBUG("DOS:67:Set Handle Count not working"); - CALLBACK_SCF(false); - break; + { + DOS_PSP psp(dos.psp); + psp.SetNumFiles(reg_bx); + CALLBACK_SCF(false); + break; + }; case 0x69: /* Get/Set disk serial number */ { switch(reg_al) { diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 386688ff..f03bf19c 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -197,6 +197,20 @@ void DOS_PSP::SetFCB2(RealPt src) if (src) MEM_BlockCopy(PhysMake(seg,offsetof(sPSP,fcb2)),Real2Phys(src),16); }; +bool DOS_PSP::SetNumFiles(Bit16u fileNum) +{ + // Allocate needed paragraphs + Bit16u para = (fileNum/16)+((fileNum%16)>0); + RealPt data = RealMake(DOS_GetMemory(para),0); + sSave(sPSP,file_table,data); + sSave(sPSP,max_files,fileNum); + if (fileNum>20) { + for (Bit16u i=0; i<20; i++) SetFileHandle(i,sGet(sPSP,files[i])); + for (i=20; i Date: Sun, 16 Feb 2003 14:48:01 +0000 Subject: [PATCH 0587/4131] DOS_PSP::FindEntryByHandle Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@666 --- src/dos/dos_classes.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index f03bf19c..79f374ab 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -145,6 +145,16 @@ Bit16u DOS_PSP::FindFreeFileEntry(void) return 0xff; }; +Bit16u DOS_PSP::FindEntryByHandle(Bit8u handle) +{ + PhysPt files=Real2Phys(sGet(sPSP,file_table)); + Bit16u max = sGet(sPSP,max_files); + for (Bit16u i=0;i Date: Sun, 16 Feb 2003 14:49:11 +0000 Subject: [PATCH 0588/4131] Added check, if file is already opened Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@667 --- src/dos/dos_files.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 4f3f4ab1..ec7b5010 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -342,6 +342,20 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { } else { /* First check if the name is correct */ if (!DOS_MakeName(name,fullname,&drive)) return false; + + /* Check, if file is already opened */ + for (i=0;iIsOpen() && Files[i]->IsName(fullname)) { + *entry = psp.FindEntryByHandle(i); + if (*entry==0xFF) { + // This shouldnt happen + LOG_ERROR("DOS: File %s is opened but has no psp entry.",name); + return false; + } + return true; + } + } + /* Check for a free file handle */ for (i=0;i Date: Sun, 16 Feb 2003 14:50:42 +0000 Subject: [PATCH 0589/4131] Save name and state in DOS_FILE and derived classes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@668 --- include/dos_system.h | 20 ++++++++++++++------ src/dos/drive_local.cpp | 13 +++++++++---- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 545f6612..c7012ecf 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -19,6 +19,7 @@ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ +#include #include "dosbox.h" #define DOS_NAMELENGTH 12 @@ -48,18 +49,25 @@ class DOS_DTA; class DOS_File { public: - virtual ~DOS_File(){}; - virtual bool Read(Bit8u * data,Bit16u * size)=0; - virtual bool Write(Bit8u * data,Bit16u * size)=0; - virtual bool Seek(Bit32u * pos,Bit32u type)=0; - virtual bool Close()=0; - virtual Bit16u GetInformation(void)=0; + DOS_File() { name=0; }; + virtual ~DOS_File(){}; + virtual bool Read(Bit8u * data,Bit16u * size)=0; + virtual bool Write(Bit8u * data,Bit16u * size)=0; + virtual bool Seek(Bit32u * pos,Bit32u type)=0; + virtual bool Close()=0; + virtual Bit16u GetInformation(void)=0; + virtual void SetName(const char* _name) { if (name) delete[] name; name = new char[strlen(_name)+1]; strcpy(name,_name); } + virtual char* GetName(void) { return name; }; + virtual bool IsOpen() { return open; }; + virtual bool IsName(const char* _name) { if (!name) return false; return strcmp(name,_name)==0; }; Bit8u type; Bit32u flags; Bit16u time; Bit16u date; Bit16u attr; Bit32u size; + bool open; + char* name; /* Some Device Specific Stuff */ }; diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 88f59f5e..f5afa6ee 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -30,7 +30,7 @@ class localFile : public DOS_File { public: - localFile(FILE * handle,Bit16u devinfo); + localFile(const char* name, FILE * handle,Bit16u devinfo); bool Read(Bit8u * data,Bit16u * size); bool Write(Bit8u * data,Bit16u * size); bool Seek(Bit32u * pos,Bit32u type); @@ -53,7 +53,7 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) { if (!hand) return false; dirCache.AddEntry(newname, true); /* Make the 16 bit device information */ - *file=new localFile(hand,0x202); + *file=new localFile(name,hand,0x202); return true; }; @@ -78,7 +78,7 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { FILE * hand=fopen(newname,type); Bit32u err=errno; if (!hand) return false; - *file=new localFile(hand,0x202); + *file=new localFile(name,hand,0x202); // (*file)->SetFileName(newname); return true; }; @@ -346,6 +346,7 @@ bool localFile::Seek(Bit32u * pos,Bit32u type) { bool localFile::Close() { + open=false; fclose(fhandle); return true; } @@ -355,7 +356,7 @@ Bit16u localFile::GetInformation(void) { } -localFile::localFile(FILE * handle,Bit16u devinfo) { +localFile::localFile(const char* _name, FILE * handle,Bit16u devinfo) { fhandle=handle; info=devinfo; struct stat temp_stat; @@ -370,6 +371,10 @@ localFile::localFile(FILE * handle,Bit16u devinfo) { size=(Bit32u)temp_stat.st_size; attr=DOS_ATTR_ARCHIVE; last_action=NONE; + + open=true; + name=0; + SetName(_name); } From 412d91902adc9734f1c2b004c3527c850eb37707 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 16 Feb 2003 14:51:17 +0000 Subject: [PATCH 0590/4131] Added DOS_PSP::FindEntryByHandle Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@669 --- include/dos_inc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dos_inc.h b/include/dos_inc.h index af5abcf7..1c4036bd 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -260,6 +260,7 @@ public: void SetFCB2 (RealPt src); void SetCommandTail (RealPt src); bool SetNumFiles (Bit16u fileNum); + Bit16u FindEntryByHandle (Bit8u handle); private: #pragma pack(1) From f89fca8d245c523b70b87511c8caed791653d5fe Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 17 Feb 2003 15:19:45 +0000 Subject: [PATCH 0591/4131] fixed small bug (shortname > 8 char) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@670 --- src/dos/drive_cache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index b3ef37d7..41551c9f 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -322,7 +322,7 @@ void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) sprintf(buffer,"%d",info->shortNr); // Copy first letters Bit16u tocopy; - if (len+strlen(buffer)>8) tocopy = 8 - strlen(buffer) - 1; + if (len+strlen(buffer)+1>8) tocopy = 8 - strlen(buffer) - 1; else tocopy = len; strncpy(info->shortname,tmpName,tocopy); info->shortname[tocopy] = 0; From b7e523d522ad1c461ef90179af6bf7fee683bb65 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 20 Feb 2003 10:39:03 +0000 Subject: [PATCH 0592/4131] removed "file already open"-check for debian release Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@671 --- src/dos/dos_files.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index ec7b5010..ea2b7f88 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -344,7 +344,7 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { if (!DOS_MakeName(name,fullname,&drive)) return false; /* Check, if file is already opened */ - for (i=0;iIsOpen() && Files[i]->IsName(fullname)) { *entry = psp.FindEntryByHandle(i); if (*entry==0xFF) { @@ -355,7 +355,7 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { return true; } } - +*/ /* Check for a free file handle */ for (i=0;i Date: Thu, 20 Feb 2003 11:28:36 +0000 Subject: [PATCH 0593/4131] changed scope of i Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@672 --- src/dos/dos_classes.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 79f374ab..9bace66c 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -215,7 +215,8 @@ bool DOS_PSP::SetNumFiles(Bit16u fileNum) sSave(sPSP,file_table,data); sSave(sPSP,max_files,fileNum); if (fileNum>20) { - for (Bit16u i=0; i<20; i++) SetFileHandle(i,sGet(sPSP,files[i])); + Bit16u i; + for (i=0; i<20; i++) SetFileHandle(i,sGet(sPSP,files[i])); for (i=20; i Date: Fri, 21 Feb 2003 17:00:31 +0000 Subject: [PATCH 0594/4131] Lot's date and time fixes. Made Gcc3.2 happier Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@673 --- src/dos/dos.cpp | 2 +- src/dos/dos_classes.cpp | 3 ++- src/dos/dos_files.cpp | 13 ++++++++++++- src/dos/drive_local.cpp | 6 +++--- src/ints/int10.h | 3 ++- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 83f14cf6..de47fc6d 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -229,7 +229,7 @@ static Bitu DOS_21Handler(void) { break; case 0x22: /* Write random record to FCB */ reg_al=DOS_FCBRandomWrite(SegValue(ds),reg_dx,1,true); - LOG_DEBUG("DOS:0x28 FCB-Random write used, result:al=%d",reg_al); + LOG_DEBUG("DOS:0x22 FCB-Random write used, result:al=%d",reg_al); break; case 0x23: /* Get file size for FCB */ if (DOS_FCBGetFileSize(SegValue(ds),reg_dx,reg_cx)) reg_al = 0x00; diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 9bace66c..97ee3ca3 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -314,7 +314,8 @@ void DOS_FCB::SetSizeDateTime(Bit32u _size,Bit16u _date,Bit16u _time) { void DOS_FCB::GetSizeDateTime(Bit32u & _size,Bit16u & _date,Bit16u & _time) { _size=sGet(sFCB,filesize); - + _date=sGet(sFCB,date); + _time=sGet(sFCB,time); } void DOS_FCB::GetRecord(Bit16u & _cur_block,Bit8u & _cur_rec) { diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index ea2b7f88..491d8cf2 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -22,6 +22,7 @@ #include #include "dosbox.h" +#include "bios.h" #include "mem.h" #include "cpu.h" #include "dos_inc.h" @@ -726,7 +727,17 @@ Bit8u DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u recno) Bit32u size;Bit16u date,time; fcb.GetSizeDateTime(size,date,time); if (pos+towrite>size) size=pos+towrite; - //TODO Set time to current time? + //time doesn't keep track of endofday + date = DOS_PackDate(dos.date.year,dos.date.month,dos.date.day); + Bit32u ticks = mem_readd(BIOS_TIMER); + Bit32u seconds = (ticks*10)/182; + Bit16u hour = (Bit16u)(seconds/3600); + Bit16u min = (Bit16u)((seconds % 3600)/60); + Bit16u sec = (Bit16u)(seconds % 60); + time = DOS_PackTime(hour,min,sec); + Bit8u temp=RealHandle(fhandle); + Files[temp]->time=time; + Files[temp]->date=date; fcb.SetSizeDateTime(size,date,time); if (++cur_rec>127) { cur_block++;cur_rec=0; } fcb.SetRecord(cur_block,cur_rec); diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index f5afa6ee..446db74f 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -278,7 +278,7 @@ bool localDrive::FileStat(const char* name, FileStat_Block * const stat_block) { struct tm *time; if((time=localtime(&temp_stat.st_mtime))!=0) { stat_block->time=DOS_PackTime(time->tm_hour,time->tm_min,time->tm_sec); - stat_block->date=DOS_PackDate(time->tm_year,time->tm_mon,time->tm_mday); + stat_block->date=DOS_PackDate(time->tm_year+1900,time->tm_mon+1,time->tm_mday); } else { } @@ -364,9 +364,9 @@ localFile::localFile(const char* _name, FILE * handle,Bit16u devinfo) { struct tm * ltime; if((ltime=localtime(&temp_stat.st_mtime))!=0) { time=DOS_PackTime(ltime->tm_hour,ltime->tm_min,ltime->tm_sec); - date=DOS_PackDate(ltime->tm_year,ltime->tm_mon,ltime->tm_mday); + date=DOS_PackDate(ltime->tm_year+1900,ltime->tm_mon+1,ltime->tm_mday); } else { - time=0;date=0; + time=1;date=1; } size=(Bit32u)temp_stat.st_size; attr=DOS_ATTR_ARCHIVE; diff --git a/src/ints/int10.h b/src/ints/int10.h index 15439f53..1e634b54 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -211,4 +211,5 @@ struct Int10Data { VGAMODES * entry; }; -extern Int10Data int10; \ No newline at end of file +extern Int10Data int10; + From 4b7d20886e4a4032d0b4ccae82145ae6118541da Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 21 Feb 2003 20:19:27 +0000 Subject: [PATCH 0595/4131] Improved AddEntry/DeleteEntry for multiple open directories Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@674 --- src/dos/drive_cache.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 41551c9f..73b4d9c9 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -146,7 +146,17 @@ void DOS_Drive_Cache::AddEntry(const char* path, bool checkExists) case ALPHABETICALREV : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByNameRev); break; case DIRALPHABETICALREV : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByDirNameRev); break; }; -// LOG_DEBUG("DIR: Added Entry %s",path); + + Bit16s index = GetLongName(dir,file); + if (index>=0) { + Bit32u i; + // Check if there are any open search dir that are affected by this... + if (dir) for (i=0; inextEntry)) + dirSearch[i]->nextEntry++; + } + }; + // LOG_DEBUG("DIR: Added Entry %s",path); } else { // LOG_DEBUG("DIR: Error: Failed to add %s",path); }; @@ -156,6 +166,17 @@ void DOS_Drive_Cache::DeleteEntry(const char* path, bool ignoreLastDir) { CacheOut(path,ignoreLastDir); if (dirSearch[srchNr]->nextEntry>0) dirSearch[srchNr]->nextEntry--; + + if (!ignoreLastDir) { + // Check if there are any open search dir that are affected by this... + Bit32u i; + char expand [CROSS_LEN]; + CFileInfo* dir = FindDirInfo(path,expand); + if (dir) for (i=0; inextEntry>0)) + dirSearch[i]->nextEntry--; + } + } }; void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) From 4ec9803c4ff8295784649be89df2fe25c47d21da Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 21 Feb 2003 20:20:19 +0000 Subject: [PATCH 0596/4131] FCB Open : check if files are already open. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@675 --- src/dos/dos_files.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 491d8cf2..bade7461 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -656,6 +656,27 @@ bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); char shortname[DOS_FCBNAME];Bit16u handle; fcb.GetName(shortname); + + /* First check if the name is correct */ + Bit8u drive; + char fullname[DOS_PATHLENGTH]; + if (!DOS_MakeName(shortname,fullname,&drive)) return false; + + /* Check, if file is already opened */ + for (Bit16u i=0;iIsOpen() && Files[i]->IsName(fullname)) { + handle = psp.FindEntryByHandle(i); + if (handle==0xFF) { + // This shouldnt happen + LOG_ERROR("DOS: File %s is opened but has no psp entry.",shortname); + return false; + } + fcb.FileOpen((Bit8u)handle); + return true; + } + } + if (!DOS_OpenFile(shortname,2,&handle)) return false; fcb.FileOpen((Bit8u)handle); return true; From d0cf2829c3bf8e7a86123a302309dc4c0fbff8b7 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 21 Feb 2003 20:21:01 +0000 Subject: [PATCH 0597/4131] Added copy command Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@676 --- src/shell/shell.cpp | 4 ++ src/shell/shell_cmds.cpp | 88 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index aefe64c5..49696168 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -206,6 +206,8 @@ void SHELL_Init() { MSG_Add("SHELL_EXECUTE_ILLEGAL_COMMAND","Illegal command: %s.\n"); MSG_Add("SHELL_CMD_PAUSE","Press any key to continue.\n"); MSG_Add("SHELL_CMD_PAUSE_HELP","Waits for 1 keystroke to continue.\n"); + MSG_Add("SHELL_CMD_COPY_FAILURE","Copy failure : %s.\n"); + MSG_Add("SHELL_CMD_COPY_SUCCESS"," %d File(s) copied.\n"); MSG_Add("SHELL_STARTUP","DOSBox Shell v" VERSION "\n" "DOSBox does not run protected mode games!\n" @@ -230,6 +232,8 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_NO_WILD","This is a simple version of the command, no wildcards allowed!\n"); MSG_Add("SHELL_CMD_RENAME_HELP","Renames files.\n"); MSG_Add("SHELL_CMD_DELETE_HELP","Removes files.\n"); + MSG_Add("SHELL_CMD_COPY_HELP","Copy files.\n"); + /* Regular startup */ call_shellstop=CALLBACK_Allocate(); /* Setup the startup CS:IP to kill the last running machine when exitted */ diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index d5a081c6..818689ae 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -26,7 +26,7 @@ static SHELL_Cmd cmd_list[]={ "CD", 0, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP", "CLS", 0, &DOS_Shell::CMD_CLS, "SHELL_CMD_CLS_HELP", -// "COPY", 0, &DOS_Shell::CMD_COPY, "Copy Files.", + "COPY", 0, &DOS_Shell::CMD_COPY, "SHELL_CMD_COPY_HELP", "DIR", 0, &DOS_Shell::CMD_DIR, "SHELL_CMD_DIR_HELP", "DEL", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP", "DELETE", 0, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP", @@ -302,11 +302,97 @@ void DOS_Shell::CMD_DIR(char * args) { } void DOS_Shell::CMD_COPY(char * args) { + + DOS_DTA dta(dos.dta); + Bit32u size;Bit16u date;Bit16u time;Bit8u attr; + char name[DOS_NAMELENGTH_ASCII]; + char * rem=ScanCMDRemain(args); if (rem) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); return; } + // source/target + char* source = args; + char* target = StripWord(source); + + // Target and Source have to be there + if (!source || !strlen(source)) { + WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); + return; + }; + + /* Make a full path in the args */ + char pathSource[DOS_PATHLENGTH]; + char pathTarget[DOS_PATHLENGTH]; + + if (!DOS_Canonicalize(source,pathSource)) { + WriteOut(MSG_Get("SHELL_CMD_ILLEGAL_PATH")); + return; + } + // cut search pattern + char* pos = strrchr(pathSource,'\\'); + if (pos) *(pos+1) = 0; + + if (!DOS_Canonicalize(target,pathTarget)) { + WriteOut(MSG_Get("SHELL_CMD_ILLEGAL_PATH")); + return; + } + // add '\\' if target is a directoy + if (pathTarget[strlen(pathTarget)-1]!='\\') { + if (DOS_FindFirst(pathTarget,0xffff)) { + dta.GetResult(name,size,date,time,attr); + if (attr & DOS_ATTR_DIRECTORY) + strcat(pathTarget,"\\"); + } + }; + + bool ret=DOS_FindFirst(args,0xffff); + if (!ret) { + WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); + return; + } + + Bit32u count = 0; + + Bit16u sourceHandle,targetHandle; + char nameTarget[DOS_PATHLENGTH]; + char nameSource[DOS_PATHLENGTH]; + + while (ret) { + dta.GetResult(name,size,date,time,attr); + + if ((attr & DOS_ATTR_DIRECTORY)==0) { + strcpy(nameSource,pathSource); + strcat(nameSource,name); + // Open Source + if (DOS_OpenFile(nameSource,0,&sourceHandle)) { + // Create Target + strcpy(nameTarget,pathTarget); + if (nameTarget[strlen(nameTarget)-1]=='\\') strcat(nameTarget,name); + + if (DOS_CreateFile(nameTarget,0,&targetHandle)) { + // Copy + Bit8u buffer[0x8000]; + bool failed = false; + Bit16u toread = 0x8000; + do { + failed |= DOS_ReadFile(sourceHandle,buffer,&toread); + failed |= DOS_WriteFile(targetHandle,buffer,&toread); + } while (toread==0x8000); + failed |= DOS_CloseFile(sourceHandle); + failed |= DOS_CloseFile(targetHandle); + WriteOut(" %s\n",name); + count++; + } else { + DOS_CloseFile(sourceHandle); + WriteOut(MSG_Get("SHELL_CMD_COPY_FAILURE"),target); + } + } else WriteOut(MSG_Get("SHELL_CMD_COPY_FAILURE"),source); + }; + ret=DOS_FindNext(); + }; + WriteOut(MSG_Get("SHELL_CMD_COPY_SUCCESS"),count); } void DOS_Shell::CMD_SET(char * args) { From d3d19f1039a7dbc412bee5ad6a9b2912d1c7918e Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 21 Feb 2003 20:36:02 +0000 Subject: [PATCH 0598/4131] Added get operand size for debugger Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@677 --- src/debug/debug_disasm.cpp | 5 +++++ src/debug/debug_inc.h | 1 + 2 files changed, 6 insertions(+) diff --git a/src/debug/debug_disasm.cpp b/src/debug/debug_disasm.cpp index dea4b057..897a4c65 100644 --- a/src/debug/debug_disasm.cpp +++ b/src/debug/debug_disasm.cpp @@ -1111,6 +1111,11 @@ Bitu DasmI386(char* buffer, PhysPt pc, Bitu cur_ip, bool bit32) return getbyte_mac-pc; } +int DasmLastOperandSize() +{ + return opsize; +}; + #endif diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h index e77806d1..65fb7d85 100644 --- a/src/debug/debug_inc.h +++ b/src/debug/debug_inc.h @@ -53,3 +53,4 @@ extern DBGBlock dbg; /* Local Debug Stuff */ Bitu DasmI386(char* buffer, PhysPt pc, Bitu cur_ip, bool bit32); +int DasmLastOperandSize(void); \ No newline at end of file From 80cc08d45db32d7eb5573c81098ef101894fa6c9 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 21 Feb 2003 20:36:45 +0000 Subject: [PATCH 0599/4131] additional debug info / memory dump / create variable names Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@678 --- src/debug/debug.cpp | 324 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 313 insertions(+), 11 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 42968860..c1fa56e6 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -48,6 +48,8 @@ int old_cursor_state; static void DrawCode(void); static bool DEBUG_Log_Loop(int count); static void DEBUG_RaiseTimerIrq(void); +char* AnalyzeInstruction(char* inst); +void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num); class DEBUG; DEBUG* pDebugcom = 0; @@ -88,7 +90,37 @@ struct SCodeViewData { } codeViewData; -static Bit16u dataSeg,dataOfs; +static Bit16u dataSeg,dataOfs; +static bool showExtend = true; + +/********************/ +/* DebugVar stuff */ +/********************/ + +class CDebugVar +{ +public: + CDebugVar(char* _name, PhysPt _adr) { adr=_adr; (strlen(name)<15)?strcpy(name,_name):strncpy(name,_name,15); name[15]=0; }; + + char* GetName(void) { return name; }; + PhysPt GetAdr (void) { return adr; }; + +private: + PhysPt adr; + char name[16]; + +public: + static void InsertVariable (char* name, PhysPt adr); + static CDebugVar* FindVar (PhysPt adr); + static void DeleteAll (); + static bool SaveVars (char* name); + static bool LoadVars (char* name); + + static std::list varList; +}; + +std::list CDebugVar::varList; + /********************/ /* Breakpoint stuff */ @@ -551,8 +583,17 @@ static void DrawCode(void) mvwprintw(dbg.win_code,i,0,"%04X:%04X ",codeViewData.useCS,disEIP); for (c=0;c=size*2;c--) waddch(dbg.win_code,' '); + + char* res = 0; + if (showExtend) res = AnalyzeInstruction(dline); waddstr(dbg.win_code,dline); - for (c=30-strlen(dline);c>0;c--) waddch(dbg.win_code,' '); + for (c=28-strlen(dline);c>0;c--) waddch(dbg.win_code,' '); + if (showExtend) { + waddstr(dbg.win_code,res); + for (c=strlen(res);c<20;c++) waddch(dbg.win_code,' '); + } else { + for (c=0;c<20;c++) waddch(dbg.win_code,' '); + } start+=size; disEIP+=size; @@ -679,6 +720,66 @@ bool ParseCommand(char* str) char* found = str; for(char* idx = found;*idx != 0; idx++) *idx = toupper(*idx); + + found = trim(found); + + found = strstr(str,"MEMDUMP "); + if (found) { // Insert variable + found+=8; + Bit16u seg = GetHexValue(found,found); found++; + Bit32u ofs = GetHexValue(found,found); found++; + Bit32u num = GetHexValue(found,found); found++; + SaveMemory(seg,ofs,num); + return true; + }; + + found = strstr(str,"IV "); + if (found) { // Insert variable + found+=3; + Bit16u seg = GetHexValue(found,found); found++; + Bit32u ofs = GetHexValue(found,found); found++; + char name[16]; + for (int i=0; i<16; i++) { + if ((found[i]!=' ') && (found[i]!=0)) name[i] = found[i]; + else { name[i] = 0; break; }; + }; + name[15] = 0; + + char buffer[128]; + sprintf(buffer,"DEBUG: Created debug var %s at %04X:%04X",name,seg,ofs); + LOG_DEBUG(buffer); + CDebugVar::InsertVariable(name,PhysMake(seg,ofs)); + return true; + } + + found = strstr(str,"SV "); + if (found) { // Save variables + found+=3; + char name[13]; + for (int i=0; i<12; i++) { + if ((found[i]!=' ') && (found[i]!=0)) name[i] = found[i]; + else { name[i] = 0; break; }; + }; + name[12] = 0; + if (CDebugVar::SaveVars(name)) LOG_DEBUG("DEBUG: Variable list save (%s) : ok.",name); + else LOG_DEBUG("DEBUG: Variable list save (%s) : failure",name); + return true; + } + + found = strstr(str,"LV "); + if (found) { // Save variables + found+=3; + char name[13]; + for (int i=0; i<12; i++) { + if ((found[i]!=' ') && (found[i]!=0)) name[i] = found[i]; + else { name[i] = 0; break; }; + }; + name[12] = 0; + if (CDebugVar::LoadVars(name)) LOG_DEBUG("DEBUG: Variable list load (%s) : ok.",name); + else LOG_DEBUG("DEBUG: Variable list load (%s) : failure",name); + return true; + } + found = strstr(str,"BP "); if (found) { // Add new breakpoint found+=3; @@ -736,7 +837,7 @@ bool ParseCommand(char* str) return true; } found = strstr(str,"C "); - if (found) { // Set code overview + if (found==(char*)str) { // Set code overview found++; Bit16u codeSeg = GetHexValue(found,found); found++; Bit32u codeOfs = GetHexValue(found,found); @@ -746,7 +847,7 @@ bool ParseCommand(char* str) return true; } found = strstr(str,"D "); - if (found) { // Set data overview + if (found==(char*)str) { // Set data overview found++; dataSeg = GetHexValue(found,found); found++; dataOfs = GetHexValue(found,found); @@ -806,7 +907,8 @@ bool ParseCommand(char* str) DOSBOX_SetNormalLoop(); Interrupt(intNr); return true; - } + } + #if C_HEAVY_DEBUG found = strstr(str,"HEAVYLOG"); if (found) { // Create Cpu log file @@ -826,6 +928,7 @@ bool ParseCommand(char* str) wprintw(dbg.win_out,"Return - Enable command line input\n"); wprintw(dbg.win_out,"D/E/S/X/B - Set data view to DS:SI/ES:DI/SS:SP/DS:DX/ES:BX\n"); wprintw(dbg.win_out,"R/F - Scroll data view\n"); + wprintw(dbg.win_out,"V - Toggle additional info\n"); wprintw(dbg.win_out,"Debugger commands (enter all values in hex or as register):\n"); wprintw(dbg.win_out,"--------------------------------------------------------------------------\n"); wprintw(dbg.win_out,"BP [segment]:[offset] - Set breakpoint\n"); @@ -844,13 +947,93 @@ bool ParseCommand(char* str) #endif wprintw(dbg.win_out,"SR [reg] [value] - Set register value\n"); wprintw(dbg.win_out,"SM [seg]:[off] [val] [.]..- Set memory with following values\n"); + + wprintw(dbg.win_out,"IV [seg]:[off] [name] - Create var name for memory address\n"); + wprintw(dbg.win_out,"SV [filename] - Save var list in file\n"); + wprintw(dbg.win_out,"LV [seg]:[off] [name] - Load var list from file\n"); + + wprintw(dbg.win_out,"MEMDUMP [seg]:[off] [len] - Write memory to file memdump.txt\n"); wprintw(dbg.win_out,"H - Help\n"); + wrefresh(dbg.win_out); return TRUE; } return false; }; +char* AnalyzeInstruction(char* inst) +{ + static char result[256]; + + char instu[256]; + char prefix[3]; + Bit16u seg; + + strcpy(instu,inst); + upcase(instu); + + result[0] = 0; + char* pos = strchr(instu,'['); + if (pos) { + // Segment prefix ? + if (*(pos-1)==':') { + char* segpos = pos-3; + prefix[0] = tolower(*segpos); + prefix[1] = tolower(*(segpos+1)); + prefix[2] = 0; + seg = GetHexValue(segpos,segpos); + } else { + if (strstr(pos,"SP") || strstr(pos,"BP")) { + seg = SegValue(ss); + strcpy(prefix,"ss"); + } else { + seg = SegValue(ds); + strcpy(prefix,"ds"); + }; + }; + + pos++; + Bit32u adr = GetHexValue(pos,pos); + while (*pos!=']') { + if (*pos=='+') { + pos++; + adr += GetHexValue(pos,pos); + } else if (*pos=='-') { + pos++; + adr -= GetHexValue(pos,pos); + } else + pos++; + }; + switch (DasmLastOperandSize()) { + case 8 : { Bit8u val = mem_readb( PhysMake (seg,adr) ); + sprintf(result,"%s:[%04X]=%02X",prefix,adr,val); + } break; + case 16: { Bit16u val = mem_readw( PhysMake (seg,adr) ); + sprintf(result,"%s:[%04X]=%04X",prefix,adr,val); + } break; + case 32: { Bit32u val = mem_readd( PhysMake (seg,adr) ); + sprintf(result,"%s:[%04X]=%08X",prefix,adr,val); + } break; + } + // Variable found ? + CDebugVar* var = CDebugVar::FindVar(PhysMake(seg,adr)); + if (var) { + // Replace occurance + char* pos1 = strchr(inst,'['); + char* pos2 = strchr(inst,']'); + if (pos1 && pos2) { + char temp[256]; + strcpy(temp,pos2); // save end + pos1++; *pos1 = 0; // cut after '[' + strcat(inst,var->GetName()); // add var name + strcat(inst,temp); // add end + }; + }; + }; + return result; +}; + + Bit32u DEBUG_CheckKeys(void) { if (codeViewData.inputMode) { @@ -928,6 +1111,8 @@ Bit32u DEBUG_CheckKeys(void) { case 'T' : DEBUG_RaiseTimerIrq(); LOG_DEBUG("Debug: Timer Int started."); break; + case 'V' : showExtend = !showExtend; + break; case 0x0A : // Return : input codeViewData.inputMode = true; @@ -1017,13 +1202,21 @@ static void DEBUG_RaiseTimerIrq(void) { static void LogInstruction(Bit16u segValue, Bit32u eipValue, char* buffer) { + static char empty[15] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,0 }; + PhysPt start = PhysMake(segValue,eipValue); char dline[200];Bitu size; size = DasmI386(dline, start, reg_eip, false); Bitu len = strlen(dline); + char* res = empty; + if (showExtend) { + res = AnalyzeInstruction(dline); + if (!res || (strlen(res)==0)) res = empty; + }; + if (len<30) for (Bitu i=0; i<30-len; i++) strcat(dline," "); // Get register values - sprintf(buffer,"%04X:%08X %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X\n",segValue,eipValue,dline,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss),get_CF(),get_ZF(),get_SF(),get_OF(),get_AF(),get_PF()); + sprintf(buffer,"%04X:%08X %s %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X\n",segValue,eipValue,dline,res,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss),get_CF(),get_ZF(),get_SF(),get_OF(),get_AF(),get_PF()); }; static bool DEBUG_Log_Loop(int count) { @@ -1148,6 +1341,7 @@ void DEBUG_SetupConsole(void) static void DEBUG_ShutDown(Section * sec) { CBreakpoint::DeleteAll(); + CDebugVar::DeleteAll(); #ifndef WIN32 curs_set(old_cursor_state); tcsetattr(0, TCSANOW,&consolesettings); @@ -1171,18 +1365,120 @@ void DEBUG_Init(Section* sec) { sec->AddDestroyFunction(&DEBUG_ShutDown); } +// DEBUGGING VAR STUFF + +void CDebugVar::InsertVariable(char* name, PhysPt adr) +{ + varList.push_back(new CDebugVar(name,adr)); +}; + +void CDebugVar::DeleteAll(void) +{ + std::list::iterator i; + CDebugVar* bp; + for(i=varList.begin(); i != varList.end(); i++) { + bp = static_cast(*i); + delete bp; + }; + (varList.clear)(); +}; + +CDebugVar* CDebugVar::FindVar(PhysPt pt) +{ + std::list::iterator i; + CDebugVar* bp; + for(i=varList.begin(); i != varList.end(); i++) { + bp = static_cast(*i); + if (bp->GetAdr()==pt) return bp; + }; + return 0; +}; + +bool CDebugVar::SaveVars(char* name) +{ + FILE* f = fopen(name,"wb+"); + if (!f) return false; + + // write number of vars + Bit16u num = varList.size(); + fwrite(&num,1,sizeof(num),f); + + std::list::iterator i; + CDebugVar* bp; + for(i=varList.begin(); i != varList.end(); i++) { + bp = static_cast(*i); + // name + fwrite(bp->GetName(),1,16,f); + // adr + PhysPt adr = bp->GetAdr(); + fwrite(&adr,1,sizeof(adr),f); + }; + fclose(f); + return true; +}; + +bool CDebugVar::LoadVars(char* name) +{ + FILE* f = fopen(name,"rb"); + if (!f) return false; + + // read number of vars + Bit16u num; + fread(&num,1,sizeof(num),f); + + for (Bit16u i=0; i0) { + + sprintf(buffer,"%04X:%04X ",seg,ofs1); + for (Bit16u x=0; x<16; x++) { + sprintf (temp,"%02X ",mem_readb(PhysMake(seg,ofs1+x))); + strcat (buffer,temp); + }; + ofs1+=16; + num-=16; + + fprintf(f,"%s\n",buffer); + }; + fclose(f); + LOG_DEBUG("DEBUG: Memory dump success."); +}; + // HEAVY DEBUGGING STUFF #if C_HEAVY_DEBUG -const Bit16u LOGCPUMAX = 200; +const Bit32u LOGCPUMAX = 200; static Bit16u logCpuCS [LOGCPUMAX]; static Bit32u logCpuEIP[LOGCPUMAX]; static Bit32u logCount = 0; typedef struct SLogInst { - char buffer[256]; + char buffer[512]; } TLogInst; TLogInst logInst[LOGCPUMAX]; @@ -1190,12 +1486,16 @@ TLogInst logInst[LOGCPUMAX]; void DEBUG_HeavyLogInstruction(void) { LogInstruction(SegValue(cs),reg_eip,logInst[logCount++].buffer); - if (logCount>=LOGCPUMAX) logCount = 0; + if (logCount>=LOGCPUMAX) { + logCount = 0; + }; }; void DEBUG_HeavyWriteLogInstruction(void) { if (!logHeavy) return; + + logHeavy = false; LOG_DEBUG("DEBUG: Creating cpu log LOGCPU_INT_CD.TXT"); @@ -1205,7 +1505,7 @@ void DEBUG_HeavyWriteLogInstruction(void) return; } - Bit16u startLog = logCount; + Bit32u startLog = logCount; do { // Write Intructions fprintf(f,"%s",logInst[startLog++].buffer); @@ -1226,8 +1526,9 @@ bool DEBUG_HeavyIsBreakpoint(void) skipFirstInstruction = false; return false; } - + PhysPt where = SegPhys(cs)+reg_eip; + if (CBreakpoint::CheckBreakpoint(where)) { exitLoop = true; DEBUG_Enable(); @@ -1240,3 +1541,4 @@ bool DEBUG_HeavyIsBreakpoint(void) #endif // DEBUG + From 1c0611c1b077ead769e9c418ae2866bd7b291d63 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 22 Feb 2003 12:00:14 +0000 Subject: [PATCH 0600/4131] Signal the thread to kill itself, to fix some bugs with pthreads in SDL. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@679 --- src/gui/sdlmain.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 8851f8f7..8ac7b7ee 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -50,6 +50,7 @@ struct SDL_Block { SDL_mutex *mutex; SDL_Thread *thread; SDL_sem *sem; + volatile bool kill_thread; #endif GFX_DrawCallBack draw_callback; struct { @@ -74,7 +75,7 @@ static void ResetScreen(void) { else sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,0,SDL_HWSURFACE); } if (sdl.surface==0) { - E_Exit("SDL:Can't get a surface."); + E_Exit("SDL:Can't get a surface error:%s.",SDL_GetError()); } SDL_WM_SetCaption(VERSION,VERSION); @@ -148,6 +149,7 @@ static void SDL_DrawScreen(void) { #if C_GFXTHREADED int SDL_DisplayThread(void * data) { while (!SDL_SemWait(sdl.sem)) { + if (sdl.kill_thread) return 0; if (!sdl.active) continue; SDL_mutexP(sdl.mutex); SDL_DrawScreen(); @@ -217,7 +219,9 @@ static void GUI_ShutDown(Section * sec) { if (sdl.mouse.locked) CaptureMouse(); if (sdl.full_screen) SwitchFullScreen(); #if C_GFXTHREADED - SDL_KillThread(sdl.thread); + sdl.kill_thread=true; + SDL_SemPost(sdl.sem); + SDL_WaitThread(sdl.thread,0); SDL_DestroyMutex(sdl.mutex); SDL_DestroySemaphore(sdl.sem); #endif @@ -236,6 +240,7 @@ static void GUI_StartUp(Section * sec) { sdl.mouse.autolock=false; sdl.mouse.sensitivity=section->Get_int("sensitivity"); #if C_GFXTHREADED + sdl.kill_thread=false; sdl.mutex=SDL_CreateMutex(); sdl.sem=SDL_CreateSemaphore(0); sdl.thread=SDL_CreateThread(&SDL_DisplayThread,0); @@ -249,11 +254,7 @@ static void GUI_StartUp(Section * sec) { KEYBOARD_AddEvent(KBD_enter,ALT_PRESSED,SwitchFullScreen); } -void GFX_ShutDown() { - if (sdl.full_screen) SwitchFullScreen(); - if (sdl.mouse.locked) CaptureMouse(); - GFX_Stop(); -} + void Mouse_AutoLock(bool enable) { sdl.mouse.autolock=enable; From a92071747ef2af52d63cee62c7950663f9765221 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 22 Feb 2003 12:11:04 +0000 Subject: [PATCH 0601/4131] Total rewrite of soundblaster sound generation. Added support for command 0xe2. Started work on mixer registers. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@680 --- src/hardware/sblaster.cpp | 750 +++++++++++++++++++++++--------------- 1 file changed, 455 insertions(+), 295 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index fd9564f7..aead78a7 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -26,9 +26,20 @@ #include "setup.h" #include "programs.h" -#define SB_BASE 0x220 -#define SB_IRQ 5 -#define SB_DMA 1 + +#define SB_PIC_EVENTS 0 + +#if DEBUG_SBLASTER +#define SB_DEBUG S_Warn +#else +#define SB_DEBUG +#endif + +#define DSP_MAJOR 2 +#define DSP_MINOR 0 + +#define MIXER_INDEX 0x04 +#define MIXER_DATA 0x05 #define DSP_RESET 0x06 #define DSP_READ_DATA 0x0A @@ -38,66 +49,103 @@ #define DSP_NO_COMMAND 0 -#define DSP_MAJOR 2 -#define DSP_MINOR 0 - +#define DMA_BUFSIZE 4096 #define DSP_BUFSIZE 64 #define DSP_DACSIZE 4096 +//Should be enough for sound generated in millisecond blocks +#define SB_BUF_SIZE 8096 + enum {DSP_S_RESET,DSP_S_NORMAL,DSP_S_HIGHSPEED}; -enum { - MODE_NONE,MODE_DAC,MODE_SILENCE, - MODE_PCM_8S,MODE_PCM_8A, - MODE_ADPCM_4S + +enum DSP_MODES { + MODE_NONE,MODE_DAC, + MODE_SILENCE, + MODE_DMA,MODE_DMA_PAUSE,MODE_DMA_WAIT, }; -#if DEBUG_SBLASTER -#define SB_DEBUG LOG_DEBUG -#else -#define SB_DEBUG -#endif +enum DMA_MODES { + DMA_NONE, + DMA_8_SILENCE, + DMA_4_SINGLE, + DMA_8_SINGLE,DMA_8_AUTO, +}; +enum { + PLAY_MONO,PLAY_STEREO, +}; struct SB_INFO { Bit16u freq; - Bitu samples_total; - Bitu samples_left; + struct { + bool active,stereo; + DMA_MODES mode; + Bitu total,left; + Bitu rate,rate_mul; + Bitu index,add_index; + Bit64u start; + union { + Bit8u b8[DMA_BUFSIZE]; + Bit16s b16[DMA_BUFSIZE]; + } buf; + } dma; bool speaker; Bit8u time_constant; bool use_time_constant; - - Bit8u output_mode; - /* DSP Stuff */ - Bit8u mode; - Bit8u state; - Bit8u cmd; - Bit8u cmd_len; - Bit8u cmd_in_pos; - Bit8u cmd_in[DSP_BUFSIZE]; - Bit8u data_out[DSP_BUFSIZE]; - Bit8u data_out_pos; - Bit8u data_out_used; + DSP_MODES mode; struct { - Bit8u data[DSP_DACSIZE]; + Bit8u state; + Bit8u cmd; + Bit8u cmd_len; + Bit8u cmd_in_pos; + Bit8u cmd_in[DSP_BUFSIZE]; + struct { + Bit8u data[DSP_BUFSIZE]; + Bitu pos,used; + } in,out; + Bit8u test_register; + } dsp; + struct { + Bit16s data[DSP_DACSIZE]; Bitu used; - Bit8u last; + Bit16s last; } dac; - Bit8u test_register; -/*ADPCM Part */ - Bits adpcm_reference; - Bits adpcm_scale; - Bits adpcm_remain; -/* Hardware setup part */ - Bit32u base; - Bit8u irq; - Bit8u dma; - bool enabled; + struct { + Bit8u index; + Bit8u master; + Bit8u mic,voice,fm; + } mixer; + struct { + Bits reference,scale; + } adpcm; + struct { + Bitu base; + Bit8u irq; + Bit8u dma8; + Bitu rate; + Bitu rate_conv; + } hw; + struct { + Bit16s buf[SB_BUF_SIZE][2]; + Bitu pos; + } out; + struct { + union { + Bit16s m[DMA_BUFSIZE]; + Bit16s s[DMA_BUFSIZE][2]; + } buf; + Bitu index,add_index; + } tmp; + struct { + Bits value; + Bitu count; + } e2; MIXER_Channel * chan; }; + + static SB_INFO sb; -static Bit8u e2_value; -static Bit8u e2_count; static char * copyright_string="COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; @@ -137,131 +185,336 @@ static int E2_incr_table[4][9] = { #define min(a,b) ((a)<(b)?(a):(b)) #endif +static void DSP_ChangeMode(DSP_MODES mode); +static void CheckDMAEnd(void); +static void END_DMA_Event(void); + static void DSP_SetSpeaker(bool how) { -/* This should just set the mixer value */ MIXER_Enable(sb.chan,how); sb.speaker=how; } -static void DSP_HaltDMA(void) { - -} - static INLINE void DSP_FlushData(void) { - sb.data_out_used=0; - sb.data_out_pos=0; + sb.dsp.out.used=0; + sb.dsp.out.pos=0; } static void DSP_StopDMA(void) { - sb.mode=MODE_NONE; + DSP_ChangeMode(MODE_NONE); + sb.dma.left=0; } -static void DSP_StartDMATranfser(Bit8u mode) { - sb.samples_left=sb.samples_total; +static void DMA_Enable(bool enable) { + sb.dma.active=enable; + if (sb.mode==MODE_DMA_WAIT && enable) { + DSP_ChangeMode(MODE_DMA); + CheckDMAEnd(); + } + if (sb.mode==MODE_DMA && !enable) { + DSP_ChangeMode(MODE_DMA_WAIT); + } +} + +INLINE Bit8u decode_ADPCM_4_sample(Bit8u sample,Bits& reference,Bits& scale) { + static Bits scaleMap[8] = { -2, -1, 0, 0, 1, 1, 1, 1 }; + + if (sample & 0x08) { + reference = max(0x00, reference - ((sample & 0x07) << scale)); + } else { + reference = min(0xff, reference + ((sample & 0x07) << scale)); + } + scale = max(2, min(6, scaleMap[sample & 0x07])); + return (Bit8u)reference; +} + +static void GenerateDMASound(Bitu size) { + //TODO For stereo make sure it's multiple of 2 + if (!size) return; + Bitu read,i; + switch (sb.dma.mode) { + case DMA_4_SINGLE: + if (sb.adpcm.reference<0 && sb.dma.left) { + Bit8u ref; + read=DMA_8_Read(sb.hw.dma8,&ref,1); + if (!read) { sb.mode=MODE_NONE;return; } //TODO warnings? + sb.dma.left--; + sb.adpcm.reference=ref; + } + if (sb.dma.left> 4,sb.adpcm.reference,sb.adpcm.scale)^0x80))<<8; + sb.tmp.buf.m[i*2+1]=((Bit8s)(decode_ADPCM_4_sample(sb.dma.buf.b8[i] & 0xf,sb.adpcm.reference,sb.adpcm.scale)^0x80))<<8; + } + read*=2; + break; + case DMA_8_SINGLE: + if (sb.dma.leftread) { + sb.dma.left-=read; + } else { + sb.dma.left=(sb.dma.total+sb.dma.left)-read; + PIC_AddIRQ(sb.hw.irq,0); + } + for (i=0;i(pos=sb.tmp.index>>16)) { + (*stream++)=sb.tmp.buf.m[pos]; + (*stream++)=sb.tmp.buf.m[pos]; + sb.tmp.index+=sb.tmp.add_index; + sb.out.pos++; + } + sb.tmp.index&=0xffff; + } else { + Bitu pos;read<<=1; + while (read>(pos=sb.tmp.index>>16)) { + (*stream++)=sb.tmp.buf.s[pos][0]; + (*stream++)=sb.tmp.buf.s[pos][1]; + sb.tmp.index+=sb.tmp.add_index; + sb.out.pos++; + } + sb.tmp.index&=0xffff; + } +} + +static void GenerateSound(Bitu size) { + while (sb.out.pos0) { + *(stream++)=sb.dac.data[dac_pos>>16]; + *(stream++)=sb.dac.data[dac_pos>>16]; + dac_pos+=dac_add; + } + dac_pos-=dac_add; + sb.dac.last=sb.dac.data[dac_pos>>16]; + sb.dac.used=0; + } else { + memset(stream,sb.dac.last,samples); + sb.mode=MODE_NONE; + } + sb.out.pos+=samples; + break; + } + case MODE_DMA: + { + Bitu len=size*sb.dma.rate_mul; + if (len & 0xffff) len=1+(len>>16); + else len>>=16; + GenerateDMASound(len); + break; + } + + } + } + if (sb.out.pos>SB_BUF_SIZE) { + LOG_WARN("Buffer full?"); + sb.out.pos=0; + + } +} + +static void END_DMA_Event(void) { + GenerateDMASound(sb.dma.left); + sb.dma.left=0; + DSP_ChangeMode(MODE_NONE); +} + +static void CheckDMAEnd(void) { + if (!sb.dma.rate) return; + Bitu index=(Bitu)(((float)sb.dma.left*(float)1000000)/(float)sb.dma.rate); + if (index<(1000-PIC_Index())) { +#if SB_PIC_EVENTS + PIC_AddEvent(END_DMA_Event,index); +#else + GenerateDMASound(sb.dma.left); +#endif + } +} + +static void DSP_ChangeMode(DSP_MODES mode) { + if (!sb.speaker) DSP_SetSpeaker(true); + if (mode==sb.mode) return; + /* Generate sound until now */ + Bitu index=PIC_Index(); + GenerateSound((sb.hw.rate_conv*index)>>16); + sb.mode=mode; +} + +static void DSP_StartDMATranfser(DMA_MODES mode) { + char * type; + /* First fill with current whatever is playing */ + DSP_ChangeMode(MODE_NONE); + sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); + sb.dma.left=sb.dma.total; if (sb.use_time_constant) { - sb.freq=(1000000 / (256 - sb.time_constant)); + sb.dma.rate=(1000000 / (256 - sb.time_constant)); }; + sb.dma.rate_mul=(sb.dma.rate<<16)/sb.hw.rate; + + sb.dma.mode=mode; + sb.tmp.index=0; switch (mode) { - case MODE_SILENCE: - MIXER_SetFreq(sb.chan,sb.freq); - SB_DEBUG("DSP:PCM 8 bit single cycle rate %d size %d",sb.freq,sb.samples_total); + case DMA_8_SILENCE: + PIC_AddIRQ(sb.hw.irq,((1000000*sb.dma.left)/sb.dma.rate)); + sb.dma.mode=DMA_NONE; + return; break; - case MODE_PCM_8S: - MIXER_SetFreq(sb.chan,sb.freq); - SB_DEBUG("DSP:PCM 8 bit single cycle rate %d size %d",sb.freq,sb.samples_total); + case DMA_8_SINGLE: + type="8-Bit Single Cycle"; + sb.tmp.add_index=(sb.dma.rate<<16)/sb.hw.rate; break; - case MODE_PCM_8A: - MIXER_SetFreq(sb.chan,sb.freq); - SB_DEBUG("DSP:PCM 8 bit auto init rate %d size %d",sb.freq,sb.samples_total); + case DMA_8_AUTO: + type="8-Bit Auto Init"; + sb.tmp.add_index=(sb.dma.rate<<16)/sb.hw.rate; break; - case MODE_ADPCM_4S: - MIXER_SetFreq(sb.chan,sb.freq); - SB_DEBUG("DSP:ADPCM 4 bit single cycle rate %d size %X",sb.freq,sb.samples_total); + case DMA_4_SINGLE: + type="4-Bit ADPCM Single Cycle"; + sb.tmp.add_index=(sb.dma.rate<<16)/sb.hw.rate; break; default: LOG_ERROR("DSP:Illegal transfer mode %d",mode); return; } - /* Hack to enable dma transfer when game has speaker disabled */ - DSP_SetSpeaker(true); - sb.mode=mode; + //TODO Use the 16-bit dma for 16-bit transfers + DSP_ChangeMode(MODE_DMA_WAIT); + sb.dma.mode=mode; + DMA_SetEnableCallBack(sb.hw.dma8,DMA_Enable); + //TODO with stereo divide add_index + SB_DEBUG("SB:DMA Transfer:%s rate %d size %d",type,sb.dma.rate,sb.dma.total); } static void DSP_AddData(Bit8u val) { - if (sb.data_out_used=DSP_BUFSIZE) start-=DSP_BUFSIZE; - sb.data_out[start]=val; - sb.data_out_used++; + sb.dsp.out.data[start]=val; + sb.dsp.out.used++; } else { LOG_ERROR("SB:DSP:Data Output buffer full this is weird"); } } +static void DSP_HaltDMA(void) { + DSP_ChangeMode(MODE_NONE); + sb.dma.mode=DMA_NONE; + PIC_RemoveEvents(END_DMA_Event); +} + static void DSP_Reset(void) { - sb.mode=MODE_NONE; - sb.cmd_len=0; - sb.cmd_in_pos=0; - sb.samples_left=0; - sb.samples_total=0; + DSP_ChangeMode(MODE_NONE); + sb.dsp.cmd_len=0; + sb.dsp.in.pos=0; + sb.dma.left=0; + sb.dma.total=0; sb.freq=22050; - sb.use_time_constant=false; + sb.use_time_constant=true; + sb.time_constant=45; sb.dac.used=0; - sb.dac.last=0x80; - e2_value=0xaa; - e2_count=0; - DSP_HaltDMA(); - MIXER_SetFreq(sb.chan,22050); - MIXER_SetMode(sb.chan,MIXER_8MONO); + sb.dac.last=0; + sb.e2.value=0xaa; + sb.e2.count=0; DSP_SetSpeaker(false); } + + static void DSP_DoReset(Bit8u val) { if (val&1!=0) { //TODO Get out of highspeed mode DSP_Reset(); - sb.state=DSP_S_RESET; + sb.dsp.state=DSP_S_RESET; } else { DSP_FlushData(); DSP_AddData(0xaa); - sb.state=DSP_S_NORMAL; + sb.dsp.state=DSP_S_NORMAL; } -}; +} + + +static void DMA_E2_Enable(bool enable) { + if (enable) { + Bit8u val=sb.e2.value; + DMA_8_Write(sb.hw.dma8,&val,1); + DMA_SetEnableCallBack(sb.hw.dma8,0); +// PIC_AddIRQ(sb.hw.irq,0); + } +} -static bool dac_warn=false; static void DSP_DoCommand(void) { - switch (sb.cmd) { + switch (sb.dsp.cmd) { case 0x10: /* Direct DAC */ - sb.mode=MODE_DAC; + DSP_ChangeMode(MODE_DAC); if (sb.dac.used> i) & 0x01) m_E2Value += E2_incr_table[m_E2Count % 4][i]; - - m_E2Value += E2_incr_table[m_E2Count % 4][8]; - m_E2Count++; -*/ -//TODO Ofcourse :) + LOG_WARN("Call 0xe2"); + for (Bitu i = 0; i < 8; i++) + if ((sb.dsp.in.data[0] >> i) & 0x01) sb.e2.value += E2_incr_table[sb.e2.count % 4][i]; + sb.e2.value += E2_incr_table[sb.e2.count % 4][8]; + sb.e2.count++; + DMA_SetEnableCallBack(sb.hw.dma8,DMA_E2_Enable); } break; case 0xe3: /* DSP Copyright */ @@ -302,65 +553,97 @@ static void DSP_DoCommand(void) { } break; case 0xe4: /* Write Test Register */ - sb.test_register=sb.cmd_in[0]; + sb.dsp.test_register=sb.dsp.in.data[0]; break; case 0xe8: /* Read Test Register */ DSP_FlushData(); - DSP_AddData(sb.test_register);; + DSP_AddData(sb.dsp.test_register);; break; case 0xf2: /* Trigger 8bit IRQ */ DSP_FlushData(); DSP_AddData(0xaa); - PIC_ActivateIRQ(sb.irq); + PIC_AddIRQ(sb.hw.irq,0); break; default: - LOG_WARN("SB:DSP:Unhandled command %2X",sb.cmd); + LOG_WARN("SB:DSP:Unhandled command %2X",sb.dsp.cmd); + break; } - sb.cmd=DSP_NO_COMMAND; - sb.cmd_len=0; - sb.cmd_in_pos=0; + sb.dsp.cmd=DSP_NO_COMMAND; + sb.dsp.cmd_len=0; + sb.dsp.in.pos=0; } - - static void DSP_DoWrite(Bit8u val) { - switch (sb.cmd) { + switch (sb.dsp.cmd) { case DSP_NO_COMMAND: - sb.cmd=val; - sb.cmd_len=DSP_cmd_len[val]; - sb.cmd_in_pos=0; - if (!sb.cmd_len) DSP_DoCommand(); + sb.dsp.cmd=val; + sb.dsp.cmd_len=DSP_cmd_len[val]; + sb.dsp.in.pos=0; + if (!sb.dsp.cmd_len) DSP_DoCommand(); break; default: - sb.cmd_in[sb.cmd_in_pos]=val; - sb.cmd_in_pos++; - if (sb.cmd_in_pos>=sb.cmd_len) DSP_DoCommand(); + sb.dsp.in.data[sb.dsp.in.pos]=val; + sb.dsp.in.pos++; + if (sb.dsp.in.pos>=sb.dsp.cmd_len) DSP_DoCommand(); } } static Bit8u DSP_ReadData(void) { Bit8u data=0; - if (sb.data_out_used) { - data=sb.data_out[sb.data_out_pos]; - sb.data_out_pos++; - if (sb.data_out_pos>=DSP_BUFSIZE) sb.data_out_pos-=DSP_BUFSIZE; - sb.data_out_used--; + if (sb.dsp.out.used) { + data=sb.dsp.out.data[sb.dsp.out.pos]; + sb.dsp.out.pos++; + if (sb.dsp.out.pos>=DSP_BUFSIZE) sb.dsp.out.pos-=DSP_BUFSIZE; + sb.dsp.out.used--; } return data; } +static void MIXER_Write(Bit8u val) { + switch (sb.mixer.index) { + case 0x0a: /* Mic Level */ + sb.mixer.mic=val; + break; + case 0x22: /* Master Volume */ + sb.mixer.master=val; + break; + default: + LOG_WARN("SB:MIXER:Write to unhandled index %X",sb.mixer.index); + } +} + +static Bit8u MIXER_Read(void) { + Bit8u ret; + switch (sb.mixer.index) { + case 0x0a: /* Mic Level */ + ret=sb.mixer.mic; + case 0x22: /* Master Volume */ + ret=sb.mixer.master; + break; + default: + LOG_WARN("SB:MIXER:Read from unhandled index %X",sb.mixer.index); + ret=0xff; + } + return ret; +} + + static Bit8u read_sb(Bit32u port) { - switch (port-sb.base) { + switch (port-sb.hw.base) { + case MIXER_INDEX: + return sb.mixer.index; + case MIXER_DATA: + return MIXER_Read(); case DSP_READ_DATA: return DSP_ReadData(); case DSP_READ_STATUS: //TODO Acknowledge 8bit irq //TODO See for high speed dma :) - if (sb.data_out_used) return 0xff; + if (sb.dsp.out.used) return 0xff; else return 0x7f; case DSP_WRITE_STATUS: - switch (sb.state) { + switch (sb.dsp.state) { case DSP_S_NORMAL: return 0x7f; case DSP_S_RESET: @@ -380,13 +663,19 @@ static Bit8u read_sb(Bit32u port) { } static void write_sb(Bit32u port,Bit8u val) { - switch (port-sb.base) { + switch (port-sb.hw.base) { case DSP_RESET: DSP_DoReset(val); break; case DSP_WRITE_DATA: DSP_DoWrite(val); break; + case MIXER_INDEX: + sb.mixer.index=val; + break; + case MIXER_DATA: + MIXER_Write(val); + break; /* For now loop FM Stuff to 0x388 */ case 0x00: case 0x02: case 0x08: IO_Write(0x388,val); @@ -401,173 +690,44 @@ static void write_sb(Bit32u port,Bit8u val) { } } - -INLINE Bit8u decode_ADPCM_4_sample( - Bit8u sample, - Bits& reference, - Bits& scale) -{ - static int scaleMap[8] = { -2, -1, 0, 0, 1, 1, 1, 1 }; - - if (sample & 0x08) { - reference = max(0x00, reference - ((sample & 0x07) << scale)); - } else { - reference = min(0xff, reference + ((sample & 0x07) << scale)); - } - - scale = max(2, min(6, scaleMap[sample & 0x07])); - - return (Bit8u)reference; -} - static void SBLASTER_CallBack(Bit8u * stream,Bit32u len) { unsigned char tmpbuf[65536]; if (!len) return; - switch (sb.mode) { - case MODE_NONE: - /* If there isn't a mode it's 8 bit mono mode speaker should be disabled normally */ - memset(stream,0x80,len); - break; - case MODE_DAC: - /* Stretch the inputted dac data over len samples */ - { - if (sb.dac.used) { - Bitu dac_add=(sb.dac.used<<16)/len; - Bitu dac_pos=0; - while (len-->0) { - *(stream++)=sb.dac.data[dac_pos>>16]; - dac_pos+=dac_add; - } - dac_pos-=dac_add; - sb.dac.last=sb.dac.data[dac_pos>>16]; - sb.dac.used=0; - } else { - memset(stream,sb.dac.last,len); - } - } - break; - case MODE_SILENCE: - memset(stream,0x80,len); - if (sb.samples_left>len) { - sb.samples_left-=len; - } else { - sb.samples_left=0; - sb.mode=MODE_NONE; - PIC_ActivateIRQ(sb.irq); - } - break; - case MODE_PCM_8A: - { - Bit16u read=DMA_8_Read(sb.dma,stream,(Bit16u)len); - if (sb.samples_left>read) { - sb.samples_left-=read; - } else { - if (read>(sb.samples_total+sb.samples_left)) sb.samples_left=sb.samples_total; - else sb.samples_left=sb.samples_total+sb.samples_left-read; - PIC_ActivateIRQ(sb.irq); - } - if (read=len) { - read=DMA_8_Read(sb.dma,stream,(Bit16u)len); - sb.samples_left-=read; - } else { - read=DMA_8_Read(sb.dma,stream,(Bit16u)sb.samples_left); - sb.samples_left=0; - } - if (read=0) { - *stream++=decode_ADPCM_4_sample((Bit8u)sb.adpcm_remain,sb.adpcm_reference,sb.adpcm_scale); - len--; - } - Bitu dma_size=len/2+(len&1); //Amount of bytes that need to be transferred - Bit8u * decode_pos=tmpbuf; - if (sb.adpcm_reference < 0) { - dma_size++; - } - Bit16u read; - /* Read from the DMA Channel */ - if (sb.samples_left>=dma_size) { - read=DMA_8_Read(sb.dma,decode_pos,(Bit16u)dma_size); - } else if (sb.samples_left0;i--) { - *stream++=decode_ADPCM_4_sample(*decode_pos >> 4,sb.adpcm_reference,sb.adpcm_scale); - *stream++=decode_ADPCM_4_sample(*decode_pos++ ,sb.adpcm_reference,sb.adpcm_scale); - } - if (len & 1) { - *stream++=decode_ADPCM_4_sample(*decode_pos >> 4,sb.adpcm_reference,sb.adpcm_scale); - sb.adpcm_remain=*decode_pos & 0xf; - } else { - sb.adpcm_remain=-1; - } - } - break; - } /* End switch */ -} - - - -static void SB_Enable(bool enable) { - Bitu i; - if (enable) { - sb.enabled=true; - for (i=sb.base+4;i=len) { + memcpy(sb.out.buf,&sb.out.buf[len],(sb.out.pos-len)*4); + sb.out.pos-=len; } + else sb.out.pos=0; + //TODO Copy remainder + if (sb.mode==MODE_NONE) DSP_SetSpeaker(false); + return; } + void SBLASTER_Init(Section* sec) { + Bitu i; MSG_Add("SBLASTER_CONFIGFILE_HELP","Sound Blaster related options.\n"); Section_prop * section=static_cast(sec); if(!section->Get_bool("enabled")) return; sb.chan=MIXER_AddChannel(&SBLASTER_CallBack,22050,"SBLASTER"); MIXER_Enable(sb.chan,false); + sb.dsp.state=DSP_S_NORMAL; + sb.hw.base=section->Get_hex("base"); + sb.hw.irq=section->Get_int("irq"); + sb.hw.dma8=section->Get_int("dma"); + sb.hw.rate=section->Get_int("sbrate"); + sb.hw.rate_conv=(sb.hw.rate<<16)/1000000; + MIXER_SetFreq(sb.chan,sb.hw.rate); + MIXER_SetMode(sb.chan,MIXER_16STEREO); - sb.state=DSP_S_NORMAL; + for (i=sb.hw.base+4;iGet_hex("base"); - sb.irq=section->Get_int("irq"); - sb.dma=section->Get_int("dma"); - SB_Enable(true); - SHELL_AddAutoexec("SET BLASTER=A%3X I%d D%d T3",sb.base,sb.irq,sb.dma); + SHELL_AddAutoexec("SET BLASTER=A%3X I%d D%d T3",sb.hw.base,sb.hw.irq,sb.hw.dma8); } From 7f0dfa4da3fcd0305dc1e7939a3df65a5535f4cf Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 22 Feb 2003 12:12:16 +0000 Subject: [PATCH 0602/4131] Fix bugs in setting channel modes and added callback for detection of masking/unmasking of dma channel. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@681 --- src/hardware/dma.cpp | 114 ++++++++++++++++++++++++++++++------------- 1 file changed, 79 insertions(+), 35 deletions(-) diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index c2e9aea2..afbe8fa3 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -21,10 +21,8 @@ */ /* - Still need to implement reads from dma ports :) - Perhaps sometime also implement dma writes. - DMA transfer that get setup with a size 0 are also done wrong should be 0x10000 probably. - + TODO + Implement 16-bit dma */ #include @@ -32,6 +30,7 @@ #include "mem.h" #include "inout.h" #include "dma.h" +#include "pic.h" #if DEBUG_DMA #define DMA_DEBUG LOG_DEBUG @@ -47,8 +46,8 @@ struct DMA_CHANNEL { struct { Bit8u mode_type; - Bit8u address_decrement; - Bit8u autoinit_enable; + bool address_decrement; + bool autoinit_enable; Bit8u transfer_type; } mode; Bit16u base_address; @@ -59,6 +58,7 @@ struct DMA_CHANNEL { bool masked; PhysPt address; bool addr_changed; + DMA_EnableCallBack enable_callback; }; @@ -107,9 +107,10 @@ static Bit8u read_dma(Bit32u port) { static void write_dma(Bit32u port,Bit8u val) { /* only use first dma for now */ DMA_CONTROLLER * cont=&dma[0]; - DMA_CHANNEL * chan=&cont->chan[port>>1]; + DMA_CHANNEL * chan; switch (port) { case 0x00:case 0x02:case 0x04:case 0x06: + chan=&cont->chan[port>>1]; if (cont->flipflop) { chan->base_address=(chan->base_address & 0xff00) | val; } else { @@ -119,6 +120,7 @@ static void write_dma(Bit32u port,Bit8u val) { chan->addr_changed=true; break; case 0x01:case 0x03:case 0x05:case 0x07: + chan=&cont->chan[port>>1]; if (cont->flipflop) { chan->base_count=(chan->base_count & 0xff00) | val; } else { @@ -142,12 +144,15 @@ static void write_dma(Bit32u port,Bit8u val) { } break; case 0x0a: /* single mask bit register */ + chan=&cont->chan[val & 0x3]; chan->masked=(val & 4)>0; + if (chan->enable_callback) chan->enable_callback(!chan->masked); break; case 0x0b: /* mode register */ + chan=&cont->chan[val & 0x3]; chan->mode.mode_type = (val >> 6) & 0x03; - chan->mode.address_decrement = (val >> 5) & 0x01; - chan->mode.autoinit_enable = (val >> 4) & 0x01; + chan->mode.address_decrement = (val & 0x20) > 0; + chan->mode.autoinit_enable = (val & 0x10) > 0; chan->mode.transfer_type = (val >> 2) & 0x03; if (chan->mode.address_decrement) { LOG_WARN("DMA:Address Decrease not supported yet"); @@ -177,21 +182,20 @@ void write_dma_page(Bit32u port,Bit8u val) { dma[0].chan[channel].addr_changed=true; } -Bit16u DMA_8_Read(Bit32u dmachan,Bit8u * buffer,Bit16u count) { + +INLINE void ResetDMA8(DMA_CHANNEL * chan) { + chan->addr_changed=false; + chan->address=(chan->page << 16)+chan->base_address; + chan->current_count=chan->base_count+1; + chan->current_address=chan->base_address; +} + + + +Bitu DMA_8_Read(Bitu dmachan,Bit8u * buffer,Bitu count) { DMA_CHANNEL * chan=&dma[0].chan[dmachan]; - - if (chan->masked) return 0; - if (!count) return 0; -/* DMA always does autoinit should work under normal situations */ - if (chan->addr_changed) { - /* Calculate the new starting position for dma read*/ - chan->addr_changed=false; - chan->address=(chan->page << 16)+chan->base_address; - - chan->current_count=chan->base_count+1; - chan->current_address=chan->base_address; - DMA_DEBUG("DMA:Transfer from %d size %d",(chan->page << 16)+chan->base_address,chan->current_count); - } + if (chan->masked || !count) return 0; + if (chan->addr_changed) ResetDMA8(chan); if (chan->current_count>count) { MEM_BlockRead(chan->address,buffer,count); chan->address+=count; @@ -204,17 +208,15 @@ Bit16u DMA_8_Read(Bit32u dmachan,Bit8u * buffer,Bit16u count) { if (!chan->mode.autoinit_enable) { /* Set the end of counter bit */ dma[0].status_reg|=(1 << dmachan); - count=(Bit16u)chan->current_count; + count=chan->current_count; chan->current_address+=count;; chan->current_count=0; return count; } else { buffer+=chan->current_count; - Bit16u left=count-(Bit16u)chan->current_count; + Bitu left=count-(Bit16u)chan->current_count; /* Autoinit reset the dma channel */ - chan->address=(chan->page << 16)+chan->base_address; - chan->current_count=chan->base_count+1; - chan->current_address=chan->base_address; + ResetDMA8(chan); /* Copy the rest of the buffer */ MEM_BlockRead(chan->address,buffer,left); chan->address+=left; @@ -223,22 +225,52 @@ Bit16u DMA_8_Read(Bit32u dmachan,Bit8u * buffer,Bit16u count) { return count; } } -}; +} -Bit16u DMA_8_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count) { - - return 0; -}; +Bitu DMA_8_Write(Bitu dmachan,Bit8u * buffer,Bitu count) { + DMA_CHANNEL * chan=&dma[0].chan[dmachan]; + if (chan->masked || !count) return 0; + if (chan->addr_changed) ResetDMA8(chan); + if (chan->current_count>count) { + MEM_BlockWrite(chan->address,buffer,count); + chan->address+=count; + chan->current_address+=count; + chan->current_count-=count; + return count; + } else { + /* Copy remaining piece of first buffer */ + MEM_BlockWrite(chan->address,buffer,chan->current_count); + if (!chan->mode.autoinit_enable) { + /* Set the end of counter bit */ + dma[0].status_reg|=(1 << dmachan); + count=chan->current_count; + chan->current_address+=count;; + chan->current_count=0; + return count; + } else { + buffer+=chan->current_count; + Bitu left=count-(Bit16u)chan->current_count; + /* Autoinit reset the dma channel */ + ResetDMA8(chan); + /* Copy the rest of the buffer */ + MEM_BlockWrite(chan->address,buffer,left); + chan->address+=left; + chan->current_address+=left; + chan->current_count-=left; + return count; + } + } +} -Bit16u DMA_16_Read(Bit32u dmachan,Bit8u * buffer,Bit16u count) { +Bitu DMA_16_Read(Bitu dmachan,Bit8u * buffer,Bitu count) { return 0; } -Bit16u DMA_16_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count) { +Bitu DMA_16_Write(Bitu dmachan,Bit8u * buffer,Bitu count) { return 0; @@ -247,6 +279,18 @@ Bit16u DMA_16_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count) { +void DMA_SetEnableCallBack(Bitu channel,DMA_EnableCallBack callback) { + if (channel<4) { + dma[0].chan[channel].enable_callback=callback; + if (callback) callback(!dma[0].chan[channel].masked); + return; + } + if (channel<8) { + dma[1].chan[channel-4].enable_callback=callback; + if (callback) callback(!dma[1].chan[channel-4].masked); + } +} + void DMA_Init(Section* sec) { for (Bit32u i=0;i<0x10;i++) { IO_RegisterWriteHandler(i,write_dma,"DMA1"); From 100f50715436006476d012395a416cbefcee7e17 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 22 Feb 2003 12:12:52 +0000 Subject: [PATCH 0603/4131] New dma function parameters and callback function. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@682 --- include/dma.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/include/dma.h b/include/dma.h index 56a271ba..58f78c69 100644 --- a/include/dma.h +++ b/include/dma.h @@ -16,10 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +typedef void (* DMA_EnableCallBack)(bool enable); -Bit16u DMA_8_Read(Bit32u channel,Bit8u * buffer,Bit16u count); -Bit16u DMA_8_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count); -Bit16u DMA_16_Read(Bit32u channel,Bit8u * buffer,Bit16u count); -Bit16u DMA_16_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count); +void DMA_SetEnableCallBack(Bitu channel,DMA_EnableCallBack callback); + +Bitu DMA_8_Read(Bitu channel,Bit8u * buffer,Bitu count); +Bitu DMA_8_Write(Bitu dmachan,Bit8u * buffer,Bitu count); + +Bitu DMA_16_Read(Bitu channel,Bit8u * buffer,Bitu count); +Bitu DMA_16_Write(Bitu dmachan,Bit8u * buffer,Bitu count); From 733c4a51cab1b058e960c6e9df14dd2eb99b6b80 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 22 Feb 2003 12:14:22 +0000 Subject: [PATCH 0604/4131] Soundblaster rate option added. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@683 --- src/dosbox.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 1535114d..d8bf6346 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -192,6 +192,7 @@ void DOSBOX_Init(void) { secprop->Add_int("irq",7); secprop->Add_int("dma",1); secprop->Add_int("hdma",5); + secprop->Add_int("sbrate",22050); secprop->Add_bool("enabled",true); secprop->AddInitFunction(&ADLIB_Init); From 3e9e80ea133ae2eefff4ca2ea3cf12b945180fd7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 22 Feb 2003 12:16:20 +0000 Subject: [PATCH 0605/4131] Protection against PIC index overflowing when changing cycles. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@684 --- src/cpu/cpu.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 18f2a313..10246f3c 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -40,12 +40,14 @@ CPU_Decoder * cpudecoder; static void CPU_CycleIncrease(void) { Bitu old_cycles=CPU_CycleMax; CPU_CycleMax=(Bitu)(CPU_CycleMax*1.2); + CPU_CycleLeft=0;CPU_Cycles=0; if (CPU_CycleMax==old_cycles) CPU_CycleMax++; LOG_MSG("CPU:%d cycles",CPU_CycleMax); } static void CPU_CycleDecrease(void) { CPU_CycleMax=(Bitu)(CPU_CycleMax/1.2); + CPU_CycleLeft=0;CPU_Cycles=0; if (!CPU_CycleMax) CPU_CycleMax=1; LOG_MSG("CPU:%d cycles",CPU_CycleMax); } From 836602a4a64b2f12bdb0d3fa60c9252d9403d568 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 22 Feb 2003 12:46:10 +0000 Subject: [PATCH 0606/4131] Setup for next round before ending the queue. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@685 --- src/hardware/pic.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 971fd029..8620fc94 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -441,9 +441,6 @@ Bitu PIC_RunQueue(void) { CPU_CycleLeft+=CPU_Cycles; CPU_Cycles=0; } - if (CPU_CycleLeft<=0) { - CPU_CycleLeft=CPU_CycleMax; - } while (CPU_CycleLeft>0) { /* Check the queue for an entry */ Bitu index=PIC_Index(); @@ -482,8 +479,10 @@ Bitu PIC_RunQueue(void) { } if (ret) return ret; } - /* Go through the list of scheduled irq's and lower their index with 1000 */ + /* Prepare everything for next round */ + CPU_CycleLeft=CPU_CycleMax; PIC_Ticks++; + /* Go through the list of scheduled irq's and lower their index with 1000 */ PICEntry * entry=pic.next_entry; while (entry) { if (entry->index>1000) entry->index-=1000; From 8d71179417e57bff660aebd9a9c435374fe6ad68 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 22 Feb 2003 14:09:41 +0000 Subject: [PATCH 0607/4131] Fixed bug in 67 4c Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@686 --- src/ints/ems.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 060f6a3d..5df61c6e 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -551,7 +551,7 @@ static Bitu INT67_Handler(void) { reg_ah=EMM_NO_ERROR; break; case 0x4c: /* Get Pages for one Handle */ - if (!ValidHandle(reg_bx)) {reg_ah=EMM_INVALID_HANDLE;break;} + if (!ValidHandle(reg_dx)) {reg_ah=EMM_INVALID_HANDLE;break;} reg_bx=emm_handles[reg_dx].pages; reg_ah=EMM_NO_ERROR; break; From e3a3634669ca89ca32bedb7bfa88c212ae85dffc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 23 Feb 2003 10:48:50 +0000 Subject: [PATCH 0608/4131] Add halt/resume 8-bit dma calls and fix the static noise when generating silenec. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@687 --- src/hardware/sblaster.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index aead78a7..94ad2330 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -310,7 +310,7 @@ static void GenerateSound(Bitu size) { case MODE_DMA_WAIT: case MODE_DMA_PAUSE: case MODE_NONE: - memset(&sb.out.buf[sb.out.pos],0,samples*2); + memset(&sb.out.buf[sb.out.pos],0,samples*4); sb.out.pos+=samples; break; case MODE_DAC: @@ -436,11 +436,6 @@ static void DSP_AddData(Bit8u val) { } } -static void DSP_HaltDMA(void) { - DSP_ChangeMode(MODE_NONE); - sb.dma.mode=DMA_NONE; - PIC_RemoveEvents(END_DMA_Event); -} static void DSP_Reset(void) { DSP_ChangeMode(MODE_NONE); @@ -492,7 +487,6 @@ static void DSP_DoCommand(void) { case 0x24: /* Singe Cycle 8-Bit DMA ADC */ case 0x14: /* Singe Cycle 8-Bit DMA DAC */ case 0x91: /* Singe Cycle 8-Bit DMA High speed DAC */ - /* Set the length of the transfer */ DSP_StartDMATranfser(DMA_8_SINGLE); break; case 0x90: /* Auto Init 8-bit DMA High Speed */ @@ -517,7 +511,12 @@ static void DSP_DoCommand(void) { DSP_StartDMATranfser(DMA_8_SILENCE); break; case 0xd0: /* Halt 8-bit DMA */ - DSP_HaltDMA(); + if (sb.dma.left) { + DSP_ChangeMode(MODE_DMA_PAUSE); +#if SB_PIC_EVENTS + PIC_RemoveEvents(END_DMA_Event); +#endif + } else DSP_ChangeMode(MODE_NONE); break; case 0xd1: /* Enable Speaker */ DSP_SetSpeaker(true); @@ -525,6 +524,10 @@ static void DSP_DoCommand(void) { case 0xd3: /* Disable Speaker */ DSP_SetSpeaker(false); break; + case 0xd4: + DSP_ChangeMode(MODE_DMA_WAIT); + DMA_SetEnableCallBack(sb.hw.dma8,DMA_Enable); + break; case 0xe0: /* DSP Identification - SB2.0+ */ DSP_FlushData(); DSP_AddData(~sb.dsp.in.data[0]); @@ -559,7 +562,6 @@ static void DSP_DoCommand(void) { DSP_FlushData(); DSP_AddData(sb.dsp.test_register);; break; - case 0xf2: /* Trigger 8bit IRQ */ DSP_FlushData(); DSP_AddData(0xaa); From deb328f3196db7282ec14bdbadaf26ef94e4382b Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 24 Feb 2003 15:42:21 +0000 Subject: [PATCH 0609/4131] copy psp file table to child processes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@688 --- src/dos/dos_execute.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index d435d574..c7339972 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -232,8 +232,10 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { if ((head.signature!=MAGIC1) && (head.signature!=MAGIC2)) iscom=true; else { headersize=head.headersize*16; - imagesize=(head.pages)*512-headersize; + imagesize=(head.pages-1)*512-headersize; if (head.extrabytes) imagesize += head.extrabytes % 512; + // always load st least 512 Bytes (dos cache/dos bug?) + if (imagesize+headersize<512) imagesize = 512-headersize; } if (flags!=OVERLAY) { /* Create an environment block */ From 30819de412f30d4aea33015e034a69674421d332 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 24 Feb 2003 15:43:13 +0000 Subject: [PATCH 0610/4131] copy psp file table to child processes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@689 --- src/dos/dos_execute.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index c7339972..ac5c01a8 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -184,12 +184,20 @@ static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { DOS_PSP psp(pspseg); psp.MakeNew(memsize); psp.SetEnvironment(envseg); - psp.SetFileHandle(STDIN ,DOS_FindDevice("CON")); - psp.SetFileHandle(STDOUT,DOS_FindDevice("CON")); - psp.SetFileHandle(STDERR,DOS_FindDevice("CON")); - psp.SetFileHandle(STDAUX,DOS_FindDevice("CON")); - psp.SetFileHandle(STDNUL,DOS_FindDevice("CON")); - psp.SetFileHandle(STDPRN,DOS_FindDevice("CON")); + /* Copy file handles */ + if (DOS_PSP::rootpsp!=dos.psp) { + // TODO: Improve this + // If prog wasnt started from commandline copy file table (California Games 2) + DOS_PSP oldpsp(dos.psp); + psp.CopyFileTable(&oldpsp); + } else { + psp.SetFileHandle(STDIN ,DOS_FindDevice("CON")); + psp.SetFileHandle(STDOUT,DOS_FindDevice("CON")); + psp.SetFileHandle(STDERR,DOS_FindDevice("CON")); + psp.SetFileHandle(STDAUX,DOS_FindDevice("CON")); + psp.SetFileHandle(STDNUL,DOS_FindDevice("CON")); + psp.SetFileHandle(STDPRN,DOS_FindDevice("CON")); + } /* Save old DTA in psp */ psp.SetDTA(dos.dta); /* Setup the DTA */ From 8e1c9a736b381f95b4f6ec04aabf830d1e257855 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 24 Feb 2003 16:29:10 +0000 Subject: [PATCH 0611/4131] Added funcs to get joystick values Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@690 --- include/joystick.h | 7 +++++++ src/hardware/joystick.cpp | 23 +++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/include/joystick.h b/include/joystick.h index aec0b477..6c14091c 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -24,3 +24,10 @@ void JOYSTICK_Move_X(Bitu which,float x); 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); diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index f99aea0b..23536ff0 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -90,6 +90,29 @@ void JOYSTICK_Move_Y(Bitu which,float y) { } } +bool JOYSTICK_IsEnabled(Bitu which) +{ + if (which<2) return stick[which].enabled; + return false; +}; + +bool JOYSTICK_GetButton(Bitu which, Bitu num) +{ + if ((which<2) && (num<2)) return stick[which].button[num]; + return false; +} + +float JOYSTICK_GetMove_X(Bitu which) +{ + if (which<2) return stick[which].xpos; + return 0.0f; +} + +float JOYSTICK_GetMove_Y(Bitu which) +{ + if (which<2) return stick[which].ypos; + return 0.0f; +}; void JOYSTICK_Init(Section* sec) { IO_RegisterReadHandler(0x201,read_p201,"JOYSTICK"); From aa50a90a95f5c61d1a34931b145dfb59943138f5 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 24 Feb 2003 16:30:26 +0000 Subject: [PATCH 0612/4131] Added INT 15 84 - Joystick support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@691 --- src/ints/bios.cpp | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 83697864..44e9f407 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -23,6 +23,7 @@ #include "inout.h" #include "mem.h" #include "pic.h" +#include "joystick.h" static Bitu call_int1a,call_int11,call_int8,call_int17,call_int12,call_int15,call_int1c; static Bitu call_int1; @@ -174,9 +175,31 @@ static Bitu INT15_Handler(void) { PIC_AddEvent(&WaitFlagEvent,reg_cx<<16|reg_dx); break; case 0x84: /* BIOS - JOYSTICK SUPPORT (XT after 11/8/82,AT,XT286,PS) */ - //Does anyone even use this? - LOG_WARN("INT15:84:Bios Joystick functionality not done"); - reg_ax=reg_bx=reg_cx=reg_dx=0; + if (reg_dx==0x0000) { + // Get Joystick button status + if (JOYSTICK_IsEnabled(0) || JOYSTICK_IsEnabled(1)) { + reg_al = (JOYSTICK_GetButton(0,0)<<7)|(JOYSTICK_GetButton(0,1)<<6); + reg_al |= (JOYSTICK_GetButton(1,0)<<5)|(JOYSTICK_GetButton(1,1)<<4); + CALLBACK_SCF(false); + } else { + // dos values + reg_ax = 0x00f0; reg_dx = 0x0201; + CALLBACK_SCF(true); + } + } else if (reg_dx==0x0001) { + if (JOYSTICK_IsEnabled(0) || JOYSTICK_IsEnabled(1)) { + reg_ax = (Bit16u)JOYSTICK_GetMove_X(0); + reg_bx = (Bit16u)JOYSTICK_GetMove_Y(0); + reg_cx = (Bit16u)JOYSTICK_GetMove_X(1); + reg_dx = (Bit16u)JOYSTICK_GetMove_Y(1); + CALLBACK_SCF(false); + } else { + reg_ax=reg_bx=reg_cx=reg_dx=0; + CALLBACK_SCF(true); + } + } else { + LOG_WARN("INT15:84: Unknown Bios Joystick functionality."); + } break; case 0x86: /* BIOS - WAIT (AT,PS) */ { From 75626ee0c3b0bd1d15eee1983c77d6b69dfffbd6 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 24 Feb 2003 17:59:38 +0000 Subject: [PATCH 0613/4131] File seek out of range: move filepointer to end of file. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@692 --- src/dos/drive_local.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 446db74f..d02e39c7 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -336,6 +336,11 @@ bool localFile::Seek(Bit32u * pos,Bit32u type) { } fpos_t temppos; int ret=fseek(fhandle,*pos,seektype); + if (ret!=0) { + // Out of file range, pretend everythings ok + // and move file pointer top end of file... ?! (Black Thorne) + fseek(fhandle,0,SEEK_END); + }; fgetpos(fhandle,&temppos); //TODO Hope we don't encouter files with 64 bits size Bit32u * fake_pos=(Bit32u*)&temppos; From cffa206680a850a0518914cb193f5f908f13d854 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 25 Feb 2003 13:28:42 +0000 Subject: [PATCH 0614/4131] Improved search for free dir id Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@693 --- src/dos/drive_cache.cpp | 11 +++++++---- src/dos/drives.h | 3 ++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 73b4d9c9..f277f6ba 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -78,9 +78,9 @@ DOS_Drive_Cache::~DOS_Drive_Cache(void) for (Bit32u i=0; i Date: Tue, 25 Feb 2003 13:29:35 +0000 Subject: [PATCH 0615/4131] INT 21/58 : UMB Link State not available Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@694 --- src/dos/dos.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index de47fc6d..8c95b13a 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -691,6 +691,14 @@ static Bitu DOS_21Handler(void) { case 1: /* Set Strategy */ DOS_SetMemAllocStrategy(reg_bx); break; + case 2: /* Get UMB Link Status */ + reg_ax=1; /* no UMB support */ + CALLBACK_SCF(true); + break; + case 3: /* Set UMB Link Status */ + reg_ax=1; /* failure, no support */ + CALLBACK_SCF(true); + break; default: LOG_DEBUG("DOS:58:Not Supported Set//Get memory allocation call %X",reg_al); } From f79eaaba759f44b64ae68bc652d0c1f31b02a6f8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 27 Feb 2003 19:56:22 +0000 Subject: [PATCH 0616/4131] updates for new logging system Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@695 --- include/dosbox.h | 113 ++++++----------------------------- settings.h.cvs | 10 +--- src/cpu/callback.cpp | 4 +- src/cpu/core_16/main.h | 4 +- src/cpu/core_16/prefix_66.h | 2 +- src/cpu/core_16/prefix_of.h | 2 +- src/cpu/core_16/support.h | 2 +- src/cpu/cpu.cpp | 10 ++-- src/cpu/flags.cpp | 12 ++-- src/cpu/slow_16.cpp | 4 +- src/debug/debug.cpp | 63 ++++++++++--------- src/debug/debug_gui.cpp | 97 +++++++++++++++++++++++++++--- src/debug/debug_inc.h | 1 + src/dos/dev_con.h | 18 +++--- src/dos/dos.cpp | 67 +++++++++++---------- src/dos/dos_execute.cpp | 6 +- src/dos/dos_files.cpp | 20 ++----- src/dos/dos_ioctl.cpp | 8 +-- src/dos/dos_misc.cpp | 4 +- src/dos/drive_cache.cpp | 2 +- src/dosbox.cpp | 2 + src/gui/render.cpp | 6 +- src/gui/sdlmain.cpp | 24 +++++--- src/hardware/cmos.cpp | 12 ++-- src/hardware/disney.cpp | 28 +++++++-- src/hardware/dma.cpp | 8 +-- src/hardware/gameblaster.cpp | 4 +- src/hardware/iohandler.cpp | 10 ++-- src/hardware/keyboard.cpp | 8 +-- src/hardware/memory.cpp | 6 +- src/hardware/pic.cpp | 8 +-- src/hardware/sblaster.cpp | 31 ++++------ src/hardware/tandy_sound.cpp | 4 +- src/hardware/timer.cpp | 6 +- src/hardware/vga.cpp | 14 ++--- src/hardware/vga.h | 7 +-- src/hardware/vga_attr.cpp | 8 +-- src/hardware/vga_crtc.cpp | 6 +- src/hardware/vga_dac.cpp | 8 +-- src/hardware/vga_draw.cpp | 2 +- src/hardware/vga_fonts.cpp | 2 +- src/hardware/vga_gfx.cpp | 10 ++-- src/hardware/vga_memory.cpp | 4 +- src/hardware/vga_misc.cpp | 4 +- src/hardware/vga_seq.cpp | 6 +- src/ints/bios.cpp | 35 ++++++----- src/ints/bios_disk.cpp | 12 ++-- src/ints/bios_keyboard.cpp | 9 ++- src/ints/ems.cpp | 23 +++---- src/ints/int10.cpp | 29 ++++----- src/ints/int10.h | 2 +- src/ints/int10_char.cpp | 4 +- src/ints/int10_modes.cpp | 6 +- src/ints/int10_put_pixel.cpp | 6 +- src/ints/mouse.cpp | 4 +- src/ints/xms.cpp | 9 +-- src/misc/support.cpp | 5 +- 57 files changed, 405 insertions(+), 416 deletions(-) diff --git a/include/dosbox.h b/include/dosbox.h index 25606f62..12648595 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -52,7 +52,6 @@ typedef signed int Bits; class Section; - typedef Bitu (LoopHandler)(void); void DOSBOX_RunMachine(); @@ -65,101 +64,25 @@ class Config; extern Config * control; extern Bitu errorlevel; -inline void LOG_MSG(char* message) -{ - if(errorlevel>=0) S_Warn(message); -} +#define LOG_MSG S_Warn -template -inline void LOG_MSG(char* message,type1 arg1) -{ - - if(errorlevel>=0) S_Warn(message,arg1); -} - -template -inline void LOG_MSG(char* message,type1 arg1,type2 arg2) -{ - - if(errorlevel>=0) S_Warn(message,arg1,arg2); -} - -template -inline void LOG_MSG(char* message,type1 arg1,type2 arg2,type3 arg3) -{ - - if (errorlevel>=0)S_Warn(message,arg1,arg2,arg3); -} - -#if C_LOGGING -inline void LOG_DEBUG(char * message) -{ - - if(errorlevel>=2) S_Warn(message); -} - -template -inline void LOG_DEBUG(char * message, type type1) -{ - - if(errorlevel>=2) S_Warn(message,type1); -} - -template -inline void LOG_WARN(char * message, type type1) -{ - - if(errorlevel>=1) S_Warn(message,type1); -} - -inline void LOG_WARN(char* message) -{ - - if(errorlevel>=1) S_Warn(message); -} - -inline void LOG_ERROR(char * message) -{ - - if(errorlevel>=0) S_Warn(message); -} - -template -inline void LOG_ERROR(char * message, type type1) -{ - - if(errorlevel>=0) S_Warn(message,type1); -} - -template -inline void LOG_ERROR(char * message, type1 arg1,type2 arg2) -{ - - if(errorlevel>=0) S_Warn(message,arg1,arg2); -} - -template -inline void LOG_WARN(char * message, type1 arg1,type2 arg2) -{ - - if(errorlevel>=1) S_Warn(message,arg1,arg2); -} - -template -inline void LOG_DEBUG(char * message, type1 arg1,type2 arg2) -{ - - if(errorlevel>=2) S_Warn(message,arg1,arg2); -} +enum LOG_TYPES { + LOG_ALL, + LOG_VGA, LOG_VGAGFX,LOG_VGAMISC,LOG_INT10, + LOG_SB,LOG_DMA, + LOG_FPU,LOG_CPU, + LOG_FCB,LOG_FILES,LOG_IOCTL,LOG_EXEC,LOG_DOSMISC, + LOG_PIT,LOG_KEYBOARD,LOG_PIC, + LOG_MOUSE,LOG_BIOS,LOG_GUI,LOG_MISC, + LOG_MAX,LOG_ERROR=0x80 +}; +#if C_DEBUG +extern void DEBUG_ShowMsg(Bit32u msgmask, char * msg,...); +#define LOG DEBUG_ShowMsg #else -#define LOG_DEBUG -#define LOG_WARN -#define LOG_ERROR -#endif +#define LOG +#endif /* C_DEBUG */ - - - -#endif +#endif /* __DOSBOX_H */ diff --git a/settings.h.cvs b/settings.h.cvs index f0580eb2..9f54aada 100644 --- a/settings.h.cvs +++ b/settings.h.cvs @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,9 +23,6 @@ #define C_DEBUG 0 #define C_HEAVY_DEBUG 0 -/* Enable the logging of extra information for debugging to the console */ -#define C_LOGGING 0 - /* Enable some big compile-time increasing inlines, great for speed though */ #define C_EXTRAINLINE 0 @@ -35,9 +32,4 @@ /* Maximum memory range in megabytes */ #define C_MEM_MAX_SIZE 12 -/* Enable debug messages for several modules, requires C_LOGGING */ -#define DEBUG_SBLASTER 0 /* SoundBlaster Debugging*/ -#define DEBUG_DMA 0 /* DMA Debugging */ -#define DEBUG_DOS 0 /* DOS Debugging */ - #endif diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 33fe6f65..f4bc04de 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -67,7 +67,7 @@ void CALLBACK_Idle(void) { } static Bitu default_handler(void) { - LOG_WARN("Illegal Unhandled Interrupt Called %X",lastint); + LOG(LOG_ERROR|LOG_CPU,"Illegal Unhandled Interrupt Called %X",lastint); return CBRET_NONE; }; diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 4926826e..5bfe47c7 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -961,7 +961,7 @@ restart: case 0xde: /* FPU ESC 6 */ case 0xdf: /* FPU ESC 7 */ { - LOG_WARN("FPU used"); + LOG(LOG_CPU,"FPU used"); Bit8u rm=Fetchb(); if (rm<0xc0) GetEAa; } @@ -1037,7 +1037,7 @@ restart: IO_Write(reg_dx+1,reg_ah); break; case 0xf0: /* LOCK */ - LOG_ERROR("CPU:LOCK"); + LOG(LOG_CPU,"CPU:LOCK"); break; case 0xf1: /* Weird call undocumented */ // INTERRUPT(1); diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index 08b0064f..60cb9666 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -276,7 +276,7 @@ switch(Fetchb()) { break; } case 0x8c: - LOG_WARN("CPU:66:8c looped back"); + LOG(LOG_CPU,"CPU:66:8c looped back"); break; case 0x8d: /* LEA */ { diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h index ebac6f2a..039f6608 100644 --- a/src/cpu/core_16/prefix_of.h +++ b/src/cpu/core_16/prefix_of.h @@ -62,7 +62,7 @@ switch(Fetchb()) { case 0x23: /* MOV DRx,Rd */ { GetRM; - LOG_DEBUG("CPU:0F:23 does nothing"); + LOG(LOG_CPU,"CPU:0F:23 does nothing"); } break; /* 0x24 MOV Rd,TRx (386) */ diff --git a/src/cpu/core_16/support.h b/src/cpu/core_16/support.h index 085f03f5..93d48c6c 100644 --- a/src/cpu/core_16/support.h +++ b/src/cpu/core_16/support.h @@ -353,7 +353,7 @@ rep_again: break; default: IPPoint--; - LOG_DEBUG("Unhandled REP Prefix %X",Fetchb()); + LOG(LOG_CPU|LOG_ERROR,"Unhandled REP Prefix %X",Fetchb()); goto normalexit; } /* If we end up here it's because the CPU_Cycles counter is 0, so restart instruction */ diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 10246f3c..65eac27f 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -59,12 +59,12 @@ void Interrupt(Bit8u num) { switch (num) { case 0x00: - LOG_WARN("Divide Error"); + LOG(LOG_CPU,"Divide Error"); break; case 0x06: break; case 0x07: - LOG_WARN("Co Processor Exception"); + LOG(LOG_FPU,"Co Processor Exception"); break; case 0x08: case 0x09: @@ -86,7 +86,7 @@ void Interrupt(Bit8u num) { break; case 0xcd: #if C_HEAVY_DEBUG - LOG_DEBUG("Call to interrupt 0xCD this is BAD"); + LOG(LOG_CPU|LOG_ERROR,"Call to interrupt 0xCD this is BAD"); DEBUG_HeavyWriteLogInstruction(); #endif E_Exit("Call to interrupt 0xCD this is BAD"); @@ -96,7 +96,7 @@ void Interrupt(Bit8u num) { #endif break; case 0x05: - LOG_MSG("CPU:Out Of Bounds interrupt"); + LOG(LOG_CPU,"CPU:Out Of Bounds interrupt"); break; default: // LOG_WARN("Call to unsupported INT %02X call %02X",num,reg_ah); diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 6e78c3e6..33c3224b 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -134,7 +134,7 @@ bool get_CF(void) { case t_DIV: return false; /* Unkown */ default: - LOG_WARN("get_CF Unknown %d",flags.type); + LOG(LOG_ERROR|LOG_CPU,"get_CF Unknown %d",flags.type); } return 0; } @@ -229,7 +229,7 @@ again: case t_MUL: return false; /* Unkown */ default: - LOG_WARN("get_AF Unknown %d",flags.type); + LOG(LOG_ERROR|LOG_CPU,"get_AF Unknown %d",flags.type); } return 0; } @@ -314,7 +314,7 @@ again: case t_MUL: return false; /* Unkown */ default: - LOG_WARN("get_ZF Unknown %d",flags.type); + LOG(LOG_ERROR|LOG_CPU,"get_ZF Unknown %d",flags.type); } return false; } @@ -398,7 +398,7 @@ again: case t_MUL: return false; /* Unkown */ default: - LOG_WARN("get_SF Unkown %d",flags.type); + LOG(LOG_ERROR|LOG_CPU,"get_SF Unkown %d",flags.type); } return false; @@ -539,7 +539,7 @@ again: case t_DIV: return false; /* Unkown */ default: - LOG_WARN("get_OF Unkown %d",flags.type); + LOG(LOG_ERROR|LOG_CPU,"get_OF Unkown %d",flags.type); } return false; } diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp index 299895ec..5ee529ed 100644 --- a/src/cpu/slow_16.cpp +++ b/src/cpu/slow_16.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -81,7 +81,7 @@ static Bitu CPU_Real_16_Slow_Decode(void) { if (prefix.count) { PrefixReset; //DEBUG_HeavyWriteLogInstruction(); - LOG_DEBUG("Prefix for non prefixed instruction"); + LOG(LOG_CPU,"Prefix for non prefixed instruction"); } CPU_Cycles--; } diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index c1fa56e6..5a849e6d 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 - 2003 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -292,9 +292,8 @@ bool CBreakpoint::CheckBreakpoint(PhysPt adr) Bit8u value = mem_readb(bp->GetLocation()); if (bp->GetValue() != value) { // Yup, memory value changed - char buffer[200]; - sprintf(buffer,"DEBUG: Memory breakpoint: %04X:%04X - %02X -> %02X",bp->GetSegment(),bp->GetOffset(),bp->GetValue(),value); - LOG_DEBUG(buffer); + + DEBUG_ShowMsg(0,"DEBUG: Memory breakpoint: %04X:%04X - %02X -> %02X",bp->GetSegment(),bp->GetOffset(),bp->GetValue(),value); bp->SetValue(value); return true; }; @@ -745,9 +744,7 @@ bool ParseCommand(char* str) }; name[15] = 0; - char buffer[128]; - sprintf(buffer,"DEBUG: Created debug var %s at %04X:%04X",name,seg,ofs); - LOG_DEBUG(buffer); + DEBUG_ShowMsg(0,"DEBUG: Created debug var %s at %04X:%04X",name,seg,ofs); CDebugVar::InsertVariable(name,PhysMake(seg,ofs)); return true; } @@ -761,8 +758,8 @@ bool ParseCommand(char* str) else { name[i] = 0; break; }; }; name[12] = 0; - if (CDebugVar::SaveVars(name)) LOG_DEBUG("DEBUG: Variable list save (%s) : ok.",name); - else LOG_DEBUG("DEBUG: Variable list save (%s) : failure",name); + if (CDebugVar::SaveVars(name)) DEBUG_ShowMsg(0,"DEBUG: Variable list save (%s) : ok.",name); + else DEBUG_ShowMsg(0,"DEBUG: Variable list save (%s) : failure",name); return true; } @@ -775,8 +772,8 @@ bool ParseCommand(char* str) else { name[i] = 0; break; }; }; name[12] = 0; - if (CDebugVar::LoadVars(name)) LOG_DEBUG("DEBUG: Variable list load (%s) : ok.",name); - else LOG_DEBUG("DEBUG: Variable list load (%s) : failure",name); + if (CDebugVar::LoadVars(name)) DEBUG_ShowMsg(0,"DEBUG: Variable list load (%s) : ok.",name); + else DEBUG_ShowMsg(0,"DEBUG: Variable list load (%s) : failure",name); return true; } @@ -786,7 +783,7 @@ bool ParseCommand(char* str) Bit16u seg = GetHexValue(found,found);found++; // skip ":" Bit32u ofs = GetHexValue(found,found); CBreakpoint::AddBreakpoint(seg,ofs,false); - LOG_DEBUG("DEBUG: Set breakpoint at %04X:%04X",seg,ofs); + DEBUG_ShowMsg(0,"DEBUG: Set breakpoint at %04X:%04X",seg,ofs); return true; } #if C_HEAVY_DEBUG @@ -796,7 +793,7 @@ bool ParseCommand(char* str) Bit16u seg = GetHexValue(found,found);found++; // skip ":" Bit32u ofs = GetHexValue(found,found); CBreakpoint::AddMemBreakpoint(seg,ofs); - LOG_DEBUG("DEBUG: Set memory breakpoint at %04X:%04X",seg,ofs); + DEBUG_ShowMsg(0,"DEBUG: Set memory breakpoint at %04X:%04X",seg,ofs); return true; } #endif @@ -807,10 +804,10 @@ bool ParseCommand(char* str) Bit8u valAH = GetHexValue(found,found); if ((valAH==0x00) && (*found=='*')) { CBreakpoint::AddIntBreakpoint(intNr,BPINT_ALL,false); - LOG_DEBUG("DEBUG: Set interrupt breakpoint at INT %02X",intNr); + DEBUG_ShowMsg(0,"DEBUG: Set interrupt breakpoint at INT %02X",intNr); } else { CBreakpoint::AddIntBreakpoint(intNr,valAH,false); - LOG_DEBUG("DEBUG: Set interrupt breakpoint at INT %02X AH=%02X",intNr,valAH); + DEBUG_ShowMsg(0,"DEBUG: Set interrupt breakpoint at INT %02X AH=%02X",intNr,valAH); } return true; } @@ -829,7 +826,7 @@ bool ParseCommand(char* str) Bit8u bpNr = GetHexValue(found,found); if ((bpNr==0x00) && (*found=='*')) { // Delete all CBreakpoint::DeleteAll(); - LOG_DEBUG("DEBUG: Breakpoints deleted."); + DEBUG_ShowMsg(0,"DEBUG: Breakpoints deleted."); } else { // delete single breakpoint CBreakpoint::DeleteByIndex(bpNr); @@ -841,7 +838,7 @@ bool ParseCommand(char* str) found++; Bit16u codeSeg = GetHexValue(found,found); found++; Bit32u codeOfs = GetHexValue(found,found); - LOG_DEBUG("DEBUG: Set code overview to %04X:%04X",codeSeg,codeOfs); + DEBUG_ShowMsg(0,"DEBUG: Set code overview to %04X:%04X",codeSeg,codeOfs); codeViewData.useCS = codeSeg; codeViewData.useEIP = codeOfs; return true; @@ -851,22 +848,22 @@ bool ParseCommand(char* str) found++; dataSeg = GetHexValue(found,found); found++; dataOfs = GetHexValue(found,found); - LOG_DEBUG("DEBUG: Set data overview to %04X:%04X",dataSeg,dataOfs); + DEBUG_ShowMsg(0,"DEBUG: Set data overview to %04X:%04X",dataSeg,dataOfs); return true; } found = strstr(str,"LOG "); if (found) { // Create Cpu log file found+=4; - LOG_DEBUG("DEBUG: Starting log"); + DEBUG_ShowMsg(0,"DEBUG: Starting log"); DEBUG_Log_Loop(GetHexValue(found,found)); - LOG_DEBUG("DEBUG: Logfile LOGCPU.TXT created."); + DEBUG_ShowMsg(0,"DEBUG: Logfile LOGCPU.TXT created."); return true; } found = strstr(str,"SR "); if (found) { // Set register value found+=2; - if (ChangeRegister(found)) LOG_DEBUG("DEBUG: Set Register success."); - else LOG_DEBUG("DEBUG: Set Register failure."); + if (ChangeRegister(found)) DEBUG_ShowMsg(0,"DEBUG: Set Register success."); + else DEBUG_ShowMsg(0,"DEBUG: Set Register failure."); return true; } found = strstr(str,"SM "); @@ -883,14 +880,14 @@ bool ParseCommand(char* str) count++; } }; - LOG_DEBUG("DEBUG: Memory changed."); + DEBUG_ShowMsg(0,"DEBUG: Memory changed."); return true; } found = strstr(str,"INTT "); if (found) { // Create Cpu log file found+=4; Bit8u intNr = GetHexValue(found,found); - LOG_DEBUG("DEBUG: Tracing INT %02X",intNr); + DEBUG_ShowMsg(0,"DEBUG: Tracing INT %02X",intNr); Interrupt(intNr); SetCodeWinStart(); return true; @@ -899,7 +896,7 @@ bool ParseCommand(char* str) if (found) { // Create Cpu log file found+=4; Bit8u intNr = GetHexValue(found,found); - LOG_DEBUG("DEBUG: Starting INT %02X",intNr); + DEBUG_ShowMsg(0,"DEBUG: Starting INT %02X",intNr); CBreakpoint::AddBreakpoint (SegValue(cs),reg_eip, true); CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip-1,true); debugging=false; @@ -913,8 +910,8 @@ bool ParseCommand(char* str) found = strstr(str,"HEAVYLOG"); if (found) { // Create Cpu log file logHeavy = !logHeavy; - if (logHeavy) LOG_DEBUG("DEBUG: Heavy cpu logging on."); - else LOG_DEBUG("DEBUG: Heavy cpu logging off."); + if (logHeavy) DEBUG_ShowMsg(0,"DEBUG: Heavy cpu logging on."); + else DEBUG_ShowMsg(0,"DEBUG: Heavy cpu logging off."); return true; } #endif @@ -1109,7 +1106,7 @@ Bit32u DEBUG_CheckKeys(void) { ParseCommand(codeViewData.inputStr); break; case 'T' : DEBUG_RaiseTimerIrq(); - LOG_DEBUG("Debug: Timer Int started."); + DEBUG_ShowMsg(0,"Debug: Timer Int started."); break; case 'V' : showExtend = !showExtend; break; @@ -1444,7 +1441,7 @@ void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num) { FILE* f = fopen("MEMDUMP.TXT","wt"); if (!f) { - LOG_DEBUG("DEBUG: Memory dump failed."); + DEBUG_ShowMsg(0,"DEBUG: Memory dump failed."); return; } @@ -1464,7 +1461,7 @@ void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num) fprintf(f,"%s\n",buffer); }; fclose(f); - LOG_DEBUG("DEBUG: Memory dump success."); + DEBUG_ShowMsg(0,"DEBUG: Memory dump success."); }; // HEAVY DEBUGGING STUFF @@ -1497,11 +1494,11 @@ void DEBUG_HeavyWriteLogInstruction(void) logHeavy = false; - LOG_DEBUG("DEBUG: Creating cpu log LOGCPU_INT_CD.TXT"); + DEBUG_ShowMsg(0,"DEBUG: Creating cpu log LOGCPU_INT_CD.TXT"); FILE* f = fopen("LOGCPU_INT_CD.TXT","wt"); if (!f) { - LOG_DEBUG("DEBUG: Failed."); + DEBUG_ShowMsg(0,"DEBUG: Failed."); return; } @@ -1514,7 +1511,7 @@ void DEBUG_HeavyWriteLogInstruction(void) fclose(f); - LOG_DEBUG("DEBUG: Done."); + DEBUG_ShowMsg(0,"DEBUG: Done."); }; bool DEBUG_HeavyIsBreakpoint(void) diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 1c7a6ee6..3b718556 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 - 2003 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,25 +20,43 @@ #include "dosbox.h" #if C_DEBUG - +#include "setup.h" #include #include #include #include #include +#include "support.h" #include "regs.h" #include "debug.h" #include "debug_inc.h" -extern int old_cursor_state; -void DEBUG_ShowMsg(char * msg) { - char buf[1024]; - strcpy(buf,msg); +struct _LogGroup { + char * front; + bool enabled; +}; - waddstr(dbg.win_out,buf); - wprintw(dbg.win_out," %d\n",cycle_count); +namespace { + _LogGroup loggrp[LOG_MAX]={"",true,0}; + + FILE* debuglog; +}; + +extern int old_cursor_state; +void DEBUG_ShowMsg(Bit32u entry, char * format,...) { + + if (!(entry & LOG_ERROR) && entry && !loggrp[entry].enabled) return; + + char buf[1024]; + strcpy(buf,loggrp[entry&127].front); + va_list msg; + va_start(msg,format); + vsprintf(&buf[strlen(buf)],format,msg); + va_end(msg); + wprintw(dbg.win_out,"%10d: %s\n",cycle_count,buf); wrefresh(dbg.win_out); + if(debuglog) fprintf(debuglog,"%10d: %s\n",cycle_count,buf); } @@ -114,6 +132,68 @@ static void MakePairs(void) { init_pair(PAIR_BLACK_GREY, COLOR_BLACK /*| FOREGROUND_INTENSITY */, COLOR_WHITE); init_pair(PAIR_GREY_RED, COLOR_WHITE/*| FOREGROUND_INTENSITY */, COLOR_RED); } +static void LOG_Destroy(Section* sec) { + + if(debuglog) fclose(debuglog); +} + +static void LOG_Init(Section * sec) { + Section_prop * sect=static_cast(sec); + const char * blah=sect->Get_string("logfile"); + if(blah && (debuglog = fopen(blah,"wt+"))){ + }else{ + debuglog=0; + } + sect->AddDestroyFunction(LOG_Destroy); + char buf[1024]; + for (Bitu i=1;iGet_bool(buf); + } +} + + +void LOG_StartUp(void) { + /* Setup logging groups */ + loggrp[LOG_VGA].front="VGA:"; + loggrp[LOG_VGAGFX].front="VGAGFX:"; + loggrp[LOG_VGAMISC].front="VGAMISC:"; + loggrp[LOG_INT10].front="INT10:"; + loggrp[LOG_SB].front="SBLASTER:"; + loggrp[LOG_DMA].front="DMA:"; + + loggrp[LOG_FPU].front="FPU:"; + loggrp[LOG_CPU].front="CPU:"; + + loggrp[LOG_FCB].front="FCB:"; + loggrp[LOG_FILES].front="FILES:"; + loggrp[LOG_IOCTL].front="IOCTL:"; + loggrp[LOG_EXEC].front="EXEC"; + loggrp[LOG_DOSMISC].front="DOSMISC:"; + + loggrp[LOG_PIT].front="PIT:"; + loggrp[LOG_KEYBOARD].front="KEYBOARD:"; + loggrp[LOG_PIC].front="PIC:"; + + loggrp[LOG_MOUSE].front="MOUSE:"; + loggrp[LOG_BIOS].front="BIOS:"; + loggrp[LOG_GUI].front="GUI:"; + loggrp[LOG_MISC].front="MISC:"; + + /* Register the log section */ + Section_prop * sect=control->AddSection_prop("log",LOG_Init); + sect->Add_string("logfile",""); + char buf[1024]; + for (Bitu i=1;iAdd_bool(buf,true); + } +} + + void DBGUI_StartUp(void) { @@ -133,7 +213,6 @@ void DBGUI_StartUp(void) { MakePairs(); MakeSubWindows(); - } #endif diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h index 65fb7d85..880f7ea2 100644 --- a/src/debug/debug_inc.h +++ b/src/debug/debug_inc.h @@ -37,6 +37,7 @@ struct DBGBlock { WINDOW * win_out; /* Text Output Window */ Bit32u active_win; /* Current active window */ Bit32u input_y; + Bit32u global_mask; /* Current msgmask */ }; diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index c2627367..6059a861 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -120,7 +120,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { ansi.esc=true; count++; if(!ansiwarned) { - LOG_WARN("ANSI sequences detected. enabling ansi support"); /* maybe LOG_MSG */ + LOG(LOG_IOCTL,"ANSI sequences detected. enabling ansi support"); /* maybe LOG_MSG */ ansiwarned=true; } continue; @@ -143,7 +143,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { case 'D':/* scrolling DOWN*/ case 'M':/* scrolling UP*/ default: - LOG_DEBUG("ANSI: unknown char %c after a esc",data[count]); /*prob () */ + LOG(LOG_IOCTL,"ANSI: unknown char %c after a esc",data[count]); /*prob () */ ClearAnsi(); break; } @@ -179,13 +179,13 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { ansi.attr|=0x8; break; case 4: /* underline */ - LOG_DEBUG("ANSI:no support for underline yet"); + LOG(LOG_IOCTL,"ANSI:no support for underline yet"); break; case 5: /* blinking */ - LOG_DEBUG("ANSI:no support for blinking yet"); + LOG(LOG_IOCTL,"ANSI:no support for blinking yet"); break; case 7: /* reverse */ - LOG_DEBUG("ANSI:no support for reverse yet"); + LOG(LOG_IOCTL,"ANSI:no support for reverse yet"); break; case 30: /* fg color black */ ansi.attr&=0xf8; @@ -284,7 +284,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { case 'J': /*erase screen and move cursor home*/ if(ansi.data[0]==0) ansi.data[0]=2; if(ansi.data[0]!=2) {/* only number 2 (the standard one supported) */ - LOG_DEBUG("ANSI: esc[%dJ called : not supported",ansi.data[0]); + LOG(LOG_IOCTL,"ANSI: esc[%dJ called : not supported",ansi.data[0]); break; } for(i=0;i<(Bitu)ansi.ncols*ansi.nrows;i++) INT10_TeletypeOutput(' ',ansi.attr,true,0); @@ -293,7 +293,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { break; case 'h': /* set MODE (if code =7 enable linewrap) */ case 'I': /*RESET MODE */ - LOG_DEBUG("ANSI: set/reset mode called(not supported)"); + LOG(LOG_IOCTL,"ANSI: set/reset mode called(not supported)"); ClearAnsi(); break; case 'D': /*Cursor Backward */ @@ -320,7 +320,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { case 'p':/* reassign keys (needs strings) */ case 'i':/* printer stuff */ default: - LOG_DEBUG("ANSI: unhandled char %c in esc[",data[count]); + LOG(LOG_IOCTL,"ANSI: unhandled char %c in esc[",data[count]); ClearAnsi(); break; } diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 8c95b13a..abc087a1 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -131,8 +131,8 @@ static Bitu DOS_21Handler(void) { break; }; case 0x0b: /* Get STDIN Status */ - if (DOS_GetSTDINStatus()) reg_al=0xff; - else reg_al=0; + if (!DOS_GetSTDINStatus()) {reg_al=0x00;} + else {reg_al=0xFF;} break; case 0x0c: /* Flush Buffer and read STDIN call */ { @@ -170,7 +170,7 @@ static Bitu DOS_21Handler(void) { }else{ reg_al=0xff; } - LOG_DEBUG("DOS:0x0f FCB-fileopen used, result:al=%d",reg_al); + LOG(LOG_FCB,"DOS:0x0f FCB-fileopen used, result:al=%d",reg_al); break; case 0x10: /* Close File using FCB */ if(DOS_FCBClose(SegValue(ds),reg_dx)){ @@ -178,7 +178,7 @@ static Bitu DOS_21Handler(void) { }else{ reg_al=0xff; } - LOG_DEBUG("DOS:0x10 FCB-fileclose used, result:al=%d",reg_al); + LOG(LOG_FCB,"DOS:0x10 FCB-fileclose used, result:al=%d",reg_al); break; case 0x11: /* Find First Matching File using FCB */ if(DOS_FCBFindFirst(SegValue(ds),reg_dx)){ @@ -186,7 +186,7 @@ static Bitu DOS_21Handler(void) { }else{ reg_al=0xff; } - LOG_DEBUG("DOS:0x11 FCB-FindFirst used, result:al=%d",reg_al); + LOG(LOG_FCB,"DOS:0x11 FCB-FindFirst used, result:al=%d",reg_al); break; case 0x12: /* Find Next Matching File using FCB */ if(DOS_FCBFindNext(SegValue(ds),reg_dx)){ @@ -194,7 +194,7 @@ static Bitu DOS_21Handler(void) { }else{ reg_al=0xff; } - LOG_DEBUG("DOS:0x12 FCB-FindNext used, result:al=%d",reg_al); + LOG(LOG_FCB,"DOS:0x12 FCB-FindNext used, result:al=%d",reg_al); break; case 0x13: /* Delete File using FCB */ if (DOS_FCBDeleteFile(SegValue(ds),reg_dx)) reg_al = 0x00; @@ -202,16 +202,16 @@ static Bitu DOS_21Handler(void) { break; case 0x14: /* Sequential read from FCB */ reg_al = DOS_FCBRead(SegValue(ds),reg_dx,0); - LOG_DEBUG("DOS:0x14 FCB-Read used, result:al=%d",reg_al); + LOG(LOG_FCB,"DOS:0x14 FCB-Read used, result:al=%d",reg_al); break; case 0x15: /* Sequential write to FCB */ reg_al=DOS_FCBWrite(SegValue(ds),reg_dx,0); - LOG_DEBUG("DOS:0x15 FCB-Write used, result:al=%d",reg_al); + LOG(LOG_FCB,"DOS:0x15 FCB-Write used, result:al=%d",reg_al); break; case 0x16: /* Create or truncate file using FCB */ if (DOS_FCBCreate(SegValue(ds),reg_dx)) reg_al = 0x00; else reg_al = 0xFF; - LOG_DEBUG("DOS:0x16 FCB-Create used, result:al=%d",reg_al); + LOG(LOG_FCB,"DOS:0x16 FCB-Create used, result:al=%d",reg_al); break; case 0x17: /* Rename file using FCB */ if (DOS_FCBRenameFile(SegValue(ds),reg_dx)) reg_al = 0x00; @@ -225,11 +225,11 @@ static Bitu DOS_21Handler(void) { break; case 0x21: /* Read random record from FCB */ reg_al = DOS_FCBRandomRead(SegValue(ds),reg_dx,1,true); - LOG_DEBUG("DOS:0x21 FCB-Random read used, result:al=%d",reg_al); + LOG(LOG_FCB,"DOS:0x21 FCB-Random read used, result:al=%d",reg_al); break; case 0x22: /* Write random record to FCB */ reg_al=DOS_FCBRandomWrite(SegValue(ds),reg_dx,1,true); - LOG_DEBUG("DOS:0x22 FCB-Random write used, result:al=%d",reg_al); + LOG(LOG_FCB,"DOS:0x22 FCB-Random write used, result:al=%d",reg_al); break; case 0x23: /* Get file size for FCB */ if (DOS_FCBGetFileSize(SegValue(ds),reg_dx,reg_cx)) reg_al = 0x00; @@ -240,11 +240,11 @@ static Bitu DOS_21Handler(void) { break; case 0x27: /* Random block read from FCB */ reg_al = DOS_FCBRandomRead(SegValue(ds),reg_dx,reg_cx,false); - LOG_DEBUG("DOS:0x27 FCB-Random(block) read used, result:al=%d",reg_al); + LOG(LOG_FCB,"DOS:0x27 FCB-Random(block) read used, result:al=%d",reg_al); break; case 0x28: /* Random Block write to FCB */ reg_al=DOS_FCBRandomWrite(SegValue(ds),reg_dx,reg_cx,false); - LOG_DEBUG("DOS:0x28 FCB-Random(block) write used, result:al=%d",reg_al); + LOG(LOG_FCB,"DOS:0x28 FCB-Random(block) write used, result:al=%d",reg_al); break; case 0x29: /* Parse filename into FCB */ { Bit8u difference; @@ -253,7 +253,7 @@ static Bitu DOS_21Handler(void) { reg_al=FCB_Parsename(SegValue(es),reg_di,reg_al ,string, &difference); reg_si+=difference; } - LOG_DEBUG("DOS:29:FCB Parse Filename, result:al=%d",reg_al); + LOG(LOG_FCB,"DOS:29:FCB Parse Filename, result:al=%d",reg_al); break; case 0x19: /* Get current default drive */ reg_al=DOS_GetDefaultDrive(); @@ -308,7 +308,7 @@ static Bitu DOS_21Handler(void) { } break; case 0x2d: /* Set System Time */ - LOG_DEBUG("DOS:Set System Time not supported"); + LOG(LOG_ERROR,"DOS:Set System Time not supported"); reg_al=0; /* Noone is changing system time */ break; case 0x2e: /* Set Verify flag */ @@ -386,10 +386,10 @@ static Bitu DOS_21Handler(void) { case 3: reg_al=0;break; }; - LOG_DEBUG("DOS:0x37:Call for not supported switchchar"); + LOG(LOG_ERROR|LOG_MISC,"DOS:0x37:Call for not supported switchchar"); break; case 0x38: /* Set Country Code */ - LOG_DEBUG("DOS:Setting country code not supported"); + LOG(LOG_ERROR|LOG_MISC,"DOS:Setting country code not supported"); CALLBACK_SCF(true); break; if (reg_al==0) { /* Get country specidic information */ @@ -515,7 +515,7 @@ static Bitu DOS_21Handler(void) { } break; case 0x01: /* Set */ - LOG_DEBUG("DOS:Set File Attributes for %s not supported",name1); + LOG(LOG_ERROR|LOG_MISC,"DOS:Set File Attributes for %s not supported",name1); CALLBACK_SCF(false); break; default: @@ -592,7 +592,7 @@ static Bitu DOS_21Handler(void) { case 0x4b: /* EXEC Load and/or execute program */ { MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); - LOG_DEBUG("Execute %s %d",name1,reg_al); + LOG(LOG_ERROR|LOG_MISC,"Execute %s %d",name1,reg_al); if (!DOS_Execute(name1,SegPhys(es)+reg_bx,reg_al)) { reg_ax=dos.errorcode; CALLBACK_SCF(true); @@ -646,7 +646,7 @@ static Bitu DOS_21Handler(void) { RealPt addr=dos_infoblock.GetPointer(); SegSet16(es,RealSeg(addr)); reg_bx=RealOff(addr); - LOG_DEBUG("Call is made for list of lists - let's hope for the best"); + LOG(LOG_MISC,"Call is made for list of lists - let's hope for the best"); break; } //TODO Think hard how shit this is gonna be //And will any game ever use this :) @@ -680,7 +680,7 @@ static Bitu DOS_21Handler(void) { } else { reg_cx=0; reg_dx=0; - LOG_DEBUG("DOS:57:Setting File Date is faked",reg_ah); + LOG(LOG_ERROR|LOG_MISC,"DOS:57:Setting File Date is faked",reg_ah); } break; case 0x58: /* Get/Set Memory allocation strategy */ @@ -700,7 +700,7 @@ static Bitu DOS_21Handler(void) { CALLBACK_SCF(true); break; default: - LOG_DEBUG("DOS:58:Not Supported Set//Get memory allocation call %X",reg_al); + LOG(LOG_ERROR|LOG_MISC,"DOS:58:Not Supported Set//Get memory allocation call %X",reg_al); } break; case 0x59: /* Get Extended error information */ @@ -767,7 +767,7 @@ static Bitu DOS_21Handler(void) { case 0x65: /* Get extented country information and a lot of other useless shit*/ /* Todo maybe fully support this for now we set it standard for USA */ { - LOG_DEBUG("DOS:65:Extended country information call"); + LOG(LOG_ERROR|LOG_MISC,"DOS:65:Extended country information call"); PhysPt data=SegPhys(es)+reg_di; switch (reg_al) { case 1: @@ -785,12 +785,12 @@ static Bitu DOS_21Handler(void) { } case 0x66: /* Get/Set global code page table */ if (reg_al==1) { - LOG_DEBUG("Getting global code page table"); + LOG(LOG_ERROR|LOG_MISC,"Getting global code page table"); reg_bx=reg_dx=437; CALLBACK_SCF(false); break; } - LOG_ERROR("DOS:Setting code page table is not supported"); + LOG(LOG_DOSMISC,"DOS:Setting code page table is not supported"); break; case 0x67: /* Set handle count */ /* Weird call to increase amount of file handles needs to allocate memory if >20 */ @@ -804,11 +804,11 @@ static Bitu DOS_21Handler(void) { { switch(reg_al) { case 0x00: /* Get */ - LOG_DEBUG("DOS:Get Disk serial number"); + LOG(LOG_ERROR|LOG_MISC,"DOS:Get Disk serial number"); CALLBACK_SCF(true); break; case 0x01: - LOG_DEBUG("DOS:Set Disk serial number"); + LOG(LOG_ERROR|LOG_MISC,"DOS:Set Disk serial number"); default: E_Exit("DOS:Illegal Get Serial Number call %2X",reg_al); } @@ -820,7 +820,7 @@ static Bitu DOS_21Handler(void) { case 0x71: /* Unknown probably 4dos detection */ reg_ax=0x7100; CALLBACK_SCF(true); - LOG_WARN("DOS:Windows long file name support call %2X",reg_al); + LOG(LOG_DOSMISC,"DOS:Windows long file name support call %2X",reg_al); break; case 0x68: /* FFLUSH Commit file */ case 0x63: /* Weirdo double byte stuff (fails but say it succeeded) available only in MSDOS 2.25 */ @@ -833,9 +833,10 @@ static Bitu DOS_21Handler(void) { case 0x6b: /* NULL Function */ case 0x61: /* UNUSED */ case 0xEF: /* Used in Ancient Art Of War CGA */ - case 0x5d: /* Network Functions */ - default: - LOG_DEBUG("DOS:Unhandled call %02X al=%02X. Set al to default of 0",reg_ah,reg_al); + case 0x5d: /* Network Functions ||HMMM seems to critical error info and return 1!! Maybe implement it.??*/ + /* al=06 clears cf and leaves al=6 and returns crit error flag location*/ + default: + LOG(LOG_ERROR|LOG_MISC,"DOS:Unhandled call %02X al=%02X. Set al to default of 0",reg_ah,reg_al); reg_al=0x00; /* default value */ break; }; @@ -865,7 +866,7 @@ static Bitu DOS_28Handler(void) { } static Bitu DOS_29Handler(void) { - LOG_DEBUG("int 29 called"); + LOG(LOG_ERROR|LOG_MISC,"int 29 called"); return CBRET_NONE; } diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index ac5c01a8..56d8ca38 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -284,12 +284,12 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { pos=headersize;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET); while (imagesize>0x7FFF) { readsize=0x8000;DOS_ReadFile(fhandle,loadaddress,&readsize); - if (readsize!=0x8000) LOG_WARN("Illegal header"); + if (readsize!=0x8000) LOG(LOG_EXEC,"Illegal header"); loadaddress+=0x8000;imagesize-=0x8000; } if (imagesize>0) { readsize=(Bit16u)imagesize;DOS_ReadFile(fhandle,loadaddress,&readsize); - if (readsize!=imagesize) LOG_WARN("Illegal header"); + if (readsize!=imagesize) LOG(LOG_EXEC,"Illegal header"); } /* Relocate the exe image */ Bit16u relocate; diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index bade7461..512f0bcf 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -333,7 +333,8 @@ bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { /* First check for devices */ - if (flags>2) LOG_DEBUG("Special file open command %X file %s",flags,name); + if (flags>2) LOG(LOG_FILES|LOG_ERROR,"Special file open command %X file %s",flags,name); + else LOG(LOG_FILES,"file open command %X file %s",flags,name); flags&=3; DOS_PSP psp(dos.psp); Bit8u handle=DOS_FindDevice((char *)name); @@ -344,19 +345,6 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { /* First check if the name is correct */ if (!DOS_MakeName(name,fullname,&drive)) return false; - /* Check, if file is already opened */ -/* for (i=0;iIsOpen() && Files[i]->IsName(fullname)) { - *entry = psp.FindEntryByHandle(i); - if (*entry==0xFF) { - // This shouldnt happen - LOG_ERROR("DOS: File %s is opened but has no psp entry.",name); - return false; - } - return true; - } - } -*/ /* Check for a free file handle */ for (i=0;iGetInformation(); return true; case 0x07: /* Get Output Status */ - LOG_DEBUG("DOS:IOCTL:07:Fakes output status is ready for handle %d",handle); + LOG(LOG_IOCTL,"DOS:IOCTL:07:Fakes output status is ready for handle %d",handle); reg_al=0xff; return true; case 0x08: /* Check if block device removable */ @@ -71,7 +71,7 @@ bool DOS_IOCTL(void) { mem_writeb(ptr+6,0x00); // media type (00=other type) break; default : - LOG_ERROR("DOS:IOCTL Call 0D:%2X Drive %2X unhandled",reg_cl,drive); + LOG(LOG_IOCTL|LOG_ERROR,"DOS:IOCTL Call 0D:%2X Drive %2X unhandled",reg_cl,drive); return false; } return true; @@ -94,7 +94,7 @@ bool DOS_IOCTL(void) { break; } default: - LOG_ERROR("DOS:IOCTL Call %2X unhandled",reg_al); + LOG(LOG_DOSMISC|LOG_ERROR,"DOS:IOCTL Call %2X unhandled",reg_al); return false; }; return false; diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index cabfd2ae..e0542159 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,7 +44,7 @@ static Bitu INT2F_Handler(void) { if ((*loop_multiplex->handler)()) return CBRET_NONE; loop_multiplex=loop_multiplex->next; } - LOG_WARN("DOS:Multiplex Unhandled call %4X",reg_ax); + LOG(LOG_ERROR,"DOS:Multiplex Unhandled call %4X",reg_ax); return CBRET_NONE; }; diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index f277f6ba..b9f86dfb 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -81,7 +81,7 @@ DOS_Drive_Cache::~DOS_Drive_Cache(void) Bit16u DOS_Drive_Cache::GetFreeID(CFileInfo* dir) { for (Bit32u i=0; iAdd_string("language",""); #if C_DEBUG secprop->Add_int("warnings",4); + LOG_StartUp(); #else secprop->Add_int("warnings",0); #endif diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 20b7a0f9..dc9edd29 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -111,7 +111,7 @@ static void TakeScreenShot(Bit8u * bitmap) { /* Find a filename to open */ dir=opendir(snapshots_dir); if (!dir) { - LOG_WARN("Can't open snapshot dir %s",snapshots_dir); + LOG_MSG("Can't open snapshot dir %s",snapshots_dir); return; } while (dir_ent=readdir(dir)) { @@ -130,7 +130,7 @@ static void TakeScreenShot(Bit8u * bitmap) { /* Open the actual file */ FILE * fp=fopen(file_name,"wb"); if (!fp) { - LOG_WARN("Can't open snapshot file %s",file_name); + LOG_MSG("Can't open snapshot file %s",file_name); return; } /* Finalize the initing of png library */ diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 8ac7b7ee..b59538e2 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -43,6 +43,7 @@ struct SDL_Block { Bitu flags; GFX_ModeCallBack mode_callback; bool full_screen; + bool nowait; SDL_Surface * surface; SDL_Joystick * joy; SDL_cond *cond; @@ -234,6 +235,7 @@ static void GUI_StartUp(Section * sec) { Section_prop * section=static_cast(sec); sdl.active=false; sdl.full_screen=false; + sdl.nowait=section->Get_bool("nowait"); sdl.mouse.locked=false; sdl.mouse.requestlock=false; sdl.mouse.autoenable=section->Get_bool("autolock"); @@ -498,7 +500,7 @@ void GFX_Events() { HandleVideoResize(&event.resize); break; case SDL_QUIT: - E_Exit("Closed the SDL Window"); + throw(true); break; } } @@ -512,15 +514,17 @@ void GFX_ShowMsg(char * msg) { }; int main(int argc, char* argv[]) { - -#if C_DEBUG - DEBUG_SetupConsole(); -#endif + + try { CommandLine com_line(argc,argv); Config myconf(&com_line); control=&myconf; + +#if C_DEBUG + DEBUG_SetupConsole(); +#endif if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER #ifndef DISABLE_JOYSTICK @@ -532,7 +536,7 @@ int main(int argc, char* argv[]) { sdl_sec->Add_bool("fullscreen",false); sdl_sec->Add_bool("autolock",true); sdl_sec->Add_int("sensitivity",100); - + sdl_sec->Add_bool("nowait",false); /* Init all the dosbox subsystems */ DOSBOX_Init(); std::string config_file; @@ -564,7 +568,11 @@ int main(int argc, char* argv[]) { if (sdl.full_screen) SwitchFullScreen(); if (sdl.mouse.locked) CaptureMouse(); LOG_MSG("Exit to error: %sPress enter to continue.",error); - fgetc(stdin); + if(!sdl.nowait) fgetc(stdin); + } + catch (...){ + if (sdl.full_screen) SwitchFullScreen(); + if (sdl.mouse.locked) CaptureMouse(); } return 0; }; diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 83ba7838..4ce97dc1 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -52,7 +52,7 @@ static void cmos_checktimer(void) { if (!cmos.timer.div && !cmos.timer.enabled) return; if (cmos.timer.div<=2) cmos.timer.div+=7; cmos.timer.micro=(Bitu) (10000000.0/(32768.0 / (1 << (cmos.timer.div - 1)))); - LOG_DEBUG("RTC Timer at %f hz",1000000.0/cmos.timer.micro); + LOG(LOG_PIT,"RTC Timer at %f hz",1000000.0/cmos.timer.micro); PIC_AddEvent(cmos_timerevent,cmos.timer.micro); } @@ -77,25 +77,25 @@ static void cmos_writereg(Bit32u port,Bit8u val) { break; case 0x0a: /* Status reg A */ cmos.regs[cmos.reg]=val & 0x7f; - if (val & 0x70!=0x20) LOG_DEBUG("CMOS Illegal 22 stage divider value"); + if (val & 0x70!=0x20) LOG(LOG_ERROR|LOG_BIOS,"CMOS Illegal 22 stage divider value"); cmos.timer.div=(val & 0xf); cmos_checktimer(); break; case 0x0b: /* Status reg B */ cmos.regs[cmos.reg]=val & 0x7f; cmos.timer.enabled=(val & 0x40)>0; - if (val&0x10) LOG_DEBUG("CMOS:Updated ended interrupt not supported yet"); + if (val&0x10) LOG(LOG_ERROR|LOG_BIOS,"CMOS:Updated ended interrupt not supported yet"); cmos_checktimer(); break; default: cmos.regs[cmos.reg]=val & 0x7f; - LOG_DEBUG("CMOS:Unhandled register %x",cmos.reg); + LOG(LOG_ERROR|LOG_BIOS,"CMOS:Unhandled register %x",cmos.reg); } } static Bit8u cmos_readreg(Bit32u port) { if (cmos.reg>0x3f) { - LOG_DEBUG("CMOS:Read from illegal register %x",cmos.reg); + LOG(LOG_ERROR|LOG_BIOS,"CMOS:Read from illegal register %x",cmos.reg); return 0xff; } switch (cmos.reg) { diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 3631f25a..4ad4581a 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + #include #include "dosbox.h" #include "inout.h" @@ -29,7 +47,7 @@ static void disney_write(Bit32u port,Bit8u val) { disney.data=val; break; case 1: /* Status Port */ - LOG_WARN("DISNEY:Status write %x",val); + LOG(LOG_MISC,"DISNEY:Status write %x",val); break; case 2: /* Control Port */ // LOG_WARN("DISNEY:Control write %x",val); @@ -38,7 +56,7 @@ static void disney_write(Bit32u port,Bit8u val) { disney.buffer[disney.used++]=disney.data; } } - if (val&0x10) LOG_DEBUG("DISNEY:Parallel IRQ Enabled"); + if (val&0x10) LOG(LOG_ERROR,"DISNEY:Parallel IRQ Enabled"); disney.control=val; break; } @@ -48,16 +66,16 @@ static Bit8u disney_read(Bit32u port) { switch (port-DISNEY_BASE) { case 0: /* Data Port */ - LOG_WARN("DISNEY:Read from data port"); +// LOG(LOG_MISC,"DISNEY:Read from data port"); return disney.data; break; case 1: /* Status Port */ -// LOG_WARN("DISNEY:Read from status port %X",disney.status); +// LOG(LOG_MISC,"DISNEY:Read from status port %X",disney.status); if (disney.used>=16) return 0x40; else return 0x0; break; case 2: /* Control Port */ - LOG_WARN("DISNEY:Read from control port"); + LOG(LOG_MISC,"DISNEY:Read from control port"); return disney.control; break; } diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index afbe8fa3..c102116e 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -98,7 +98,7 @@ static Bit8u read_dma(Bit32u port) { break; default: - LOG_WARN("DMA:Unhandled read from %d",port); + LOG(LOG_ERROR,"DMA:Unhandled read from %d",port); } return ret; } @@ -130,7 +130,7 @@ static void write_dma(Bit32u port,Bit8u val) { chan->addr_changed=true; break; case 0x08: /* Command Register */ - if (val != 4) LOG_WARN("DMA1:Illegal command %2X",val); + if (val != 4) LOG(LOG_ERROR,"DMA1:Illegal command %2X",val); cont->command_reg=val; break; case 0x09: /* Request Register */ @@ -155,7 +155,7 @@ static void write_dma(Bit32u port,Bit8u val) { chan->mode.autoinit_enable = (val & 0x10) > 0; chan->mode.transfer_type = (val >> 2) & 0x03; if (chan->mode.address_decrement) { - LOG_WARN("DMA:Address Decrease not supported yet"); + LOG(LOG_ERROR,"DMA:Address Decrease not supported yet"); } break; diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index c6494f50..5916d374 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -110,7 +110,7 @@ static void write_cms(Bit32u port,Bit8u val) { cms->noise[1].freq_add=noise_freq[(val>>4) & 3]; break; default: - LOG_ERROR("CMS %d:Illegal register %X2 Selected for write",sel,cms->reg); + LOG(LOG_ERROR,"CMS %d:Illegal register %X2 Selected for write",sel,cms->reg); break; }; break; diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 0a499c42..13138f8b 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,12 +24,12 @@ IO_WriteBlock IO_WriteTable[IO_MAX]; void IO_Write(Bitu num,Bit8u val) { if (num=KBD_LAST) { - LOG_ERROR("KEYBOARD:Illegal key %d for handler",keytype); + LOG(LOG_ERROR|LOG_KEYBOARD,"Illegal key %d for handler",keytype); } newevent->next=event_handlers[keytype]; event_handlers[keytype]=newevent; diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 9ce74ac5..cec5c270 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -89,11 +89,11 @@ void MEM_StrCopy(PhysPt off,char * data,Bitu size) { } static Bit8u Illegal_ReadHandler(PhysPt pt) { - LOG_ERROR("Illegal read from address %4X",pt); + LOG(LOG_ERROR,"MEM:Illegal read from address %4X",pt); return 0; } static void Illegal_WriteHandler(PhysPt pt,Bit8u val) { - LOG_ERROR("Illegal write val %2X to address %4X",val,pt); + LOG(LOG_ERROR,"Illegal write val %2X to address %4X",val,pt); } /* Could only be called when the pt host entry is 0 ah well :) */ @@ -129,7 +129,7 @@ void MEM_ClearPageHandlers(Bitu startpage,Bitu pages) { void MEM_SetupMapping(Bitu startpage,Bitu pages,void * data) { if (startpage+pages>=MAX_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); HostPt base=(HostPt)(data)-startpage*PAGE_SIZE; - if (!base) LOG_DEBUG("MEMORY:Unlucky memory allocation"); + if (!base) LOG_MSG("MEMORY:Unlucky memory allocation"); for (Bitu i=startpage;i15) E_Exit("PIC:Illegal IRQ"); if (!pic.free_entry) { - LOG_WARN("PIC:No free queue entries"); + LOG(LOG_ERROR|LOG_PIC,"Event queue full"); return; } PICEntry * entry=pic.free_entry; diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 94ad2330..368fad74 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,12 +29,6 @@ #define SB_PIC_EVENTS 0 -#if DEBUG_SBLASTER -#define SB_DEBUG S_Warn -#else -#define SB_DEBUG -#endif - #define DSP_MAJOR 2 #define DSP_MINOR 0 @@ -349,9 +343,8 @@ static void GenerateSound(Bitu size) { } } if (sb.out.pos>SB_BUF_SIZE) { - LOG_WARN("Buffer full?"); + LOG(LOG_ERROR|LOG_SB,"Generation Buffer Full!!!!"); sb.out.pos=0; - } } @@ -414,7 +407,7 @@ static void DSP_StartDMATranfser(DMA_MODES mode) { sb.tmp.add_index=(sb.dma.rate<<16)/sb.hw.rate; break; default: - LOG_ERROR("DSP:Illegal transfer mode %d",mode); + LOG(LOG_ERROR|LOG_SB,"DSP:Illegal transfer mode %d",mode); return; } //TODO Use the 16-bit dma for 16-bit transfers @@ -422,7 +415,7 @@ static void DSP_StartDMATranfser(DMA_MODES mode) { sb.dma.mode=mode; DMA_SetEnableCallBack(sb.hw.dma8,DMA_Enable); //TODO with stereo divide add_index - SB_DEBUG("SB:DMA Transfer:%s rate %d size %d",type,sb.dma.rate,sb.dma.total); + LOG(LOG_SB,"DMA Transfer:%s rate %d size %d",type,sb.dma.rate,sb.dma.total); } static void DSP_AddData(Bit8u val) { @@ -432,7 +425,7 @@ static void DSP_AddData(Bit8u val) { sb.dsp.out.data[start]=val; sb.dsp.out.used++; } else { - LOG_ERROR("SB:DSP:Data Output buffer full this is weird"); + LOG(LOG_ERROR|LOG_SB,"DSP:Data Output buffer full"); } } @@ -539,7 +532,7 @@ static void DSP_DoCommand(void) { break; case 0xe2: /* Weird DMA identification write routine */ { - LOG_WARN("Call 0xe2"); + LOG(LOG_SB,"DSP Function 0xe2"); for (Bitu i = 0; i < 8; i++) if ((sb.dsp.in.data[0] >> i) & 0x01) sb.e2.value += E2_incr_table[sb.e2.count % 4][i]; sb.e2.value += E2_incr_table[sb.e2.count % 4][8]; @@ -568,7 +561,7 @@ static void DSP_DoCommand(void) { PIC_AddIRQ(sb.hw.irq,0); break; default: - LOG_WARN("SB:DSP:Unhandled command %2X",sb.dsp.cmd); + LOG(LOG_ERROR|LOG_SB,"DSP:Unhandled command %2X",sb.dsp.cmd); break; } sb.dsp.cmd=DSP_NO_COMMAND; @@ -611,7 +604,7 @@ static void MIXER_Write(Bit8u val) { sb.mixer.master=val; break; default: - LOG_WARN("SB:MIXER:Write to unhandled index %X",sb.mixer.index); + LOG(LOG_ERROR|LOG_SB,"MIXER:Write to unhandled index %X",sb.mixer.index); } } @@ -624,7 +617,7 @@ static Bit8u MIXER_Read(void) { ret=sb.mixer.master; break; default: - LOG_WARN("SB:MIXER:Read from unhandled index %X",sb.mixer.index); + LOG(LOG_ERROR|LOG_SB,"MIXER:Read from unhandled index %X",sb.mixer.index); ret=0xff; } return ret; @@ -658,7 +651,7 @@ static Bit8u read_sb(Bit32u port) { case DSP_RESET: return 0xff; default: - LOG_WARN("SB:Unhandled read from SB Port %4X",port); + LOG(LOG_SB,"Unhandled read from SB Port %4X",port); break; } return 0xff; @@ -687,13 +680,12 @@ static void write_sb(Bit32u port,Bit8u val) { break; default: - LOG_WARN("SB:Unhandled write to SB Port %4X",port); + LOG(LOG_SB,"Unhandled write to SB Port %4X",port); break; } } static void SBLASTER_CallBack(Bit8u * stream,Bit32u len) { - unsigned char tmpbuf[65536]; if (!len) return; GenerateSound(len); memcpy(stream,sb.out.buf,len*4); @@ -702,7 +694,6 @@ static void SBLASTER_CallBack(Bit8u * stream,Bit32u len) { sb.out.pos-=len; } else sb.out.pos=0; - //TODO Copy remainder if (sb.mode==MODE_NONE) DSP_SetSpeaker(false); return; } diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 9e5727d6..c71c1dbd 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -99,7 +99,7 @@ static void write_pc0(Bit32u port,Bit8u val) { // tandy.chan[tandy.reg>>1].freq_pos=0; break; default: - LOG_WARN("TANDY:Illegal dual byte reg %d",tandy.reg); + LOG(0,"TANDY:Illegal dual byte reg %d",tandy.reg); }; } diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 69cb7d36..8a66555a 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -73,7 +73,7 @@ static void counter_latch(Bitu counter) { p->read_latch=(Bit16u)(p->cntr-(((float)micro/(float)p->micro)*(float)p->cntr)); break; default: - LOG_ERROR("PIT:Illegal Mode %d for reading counter %d",p->mode,counter); + LOG(LOG_ERROR|LOG_PIT,"Illegal Mode %d for reading counter %d",p->mode,counter); micro%=p->micro; p->read_latch=(Bit16u)(p->cntr-(((float)micro/(float)p->micro)*(float)p->cntr)); break; @@ -109,14 +109,14 @@ static void write_latch(Bit32u port,Bit8u val) { case 0x00: /* Timer hooked to IRQ 0 */ PIC_RemoveEvents(PIT0_Event); PIC_AddEvent(PIT0_Event,p->micro); - LOG_DEBUG("PIT 0 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode); + LOG(LOG_PIT,"PIT 0 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode); break; case 0x02: /* Timer hooked to PC-Speaker */ // LOG_DEBUG("PIT 2 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode); PCSPEAKER_SetCounter(p->cntr,p->mode); break; default: - LOG_ERROR("PIT:Illegal timer selected for writing"); + LOG(LOG_ERROR|LOG_PIT,"PIT:Illegal timer selected for writing"); } } } diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 5a1cdb67..f07c5aae 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -56,7 +56,7 @@ static void VGA_DrawHandler(RENDER_Part_Handler part_handler) { Bitu stop=vga.config.line_compare; if (vga.draw.double_height) stop/=2; if (stop>=vga.draw.height){ - LOG_VGA("Split at %d",stop); + LOG(LOG_VGAGFX,"Split at %d",stop); goto drawnormal; } switch (vga.mode) { @@ -73,7 +73,7 @@ static void VGA_DrawHandler(RENDER_Part_Handler part_handler) { bufsplit=memory+0xa0000; break; default: - LOG_WARN("VGA:Unhandled split screen mode %d",vga.mode); + LOG(LOG_VGAGFX,"VGA:Unhandled split screen mode %d",vga.mode); goto norender; } part_handler(buf,0,0,vga.draw.width,stop); @@ -161,8 +161,8 @@ static void VGA_DoResize(void) { /* Check for pixel doubling, master clock/2 */ if (vga.seq.clocking_mode & 0x8) clock/=2; - LOG_VGA("H total %d, V Total %d",htotal,vtotal); - LOG_VGA("H D End %d, V D End %d",hdispend,vdispend); + LOG(LOG_VGA,"H total %d, V Total %d",htotal,vtotal); + LOG(LOG_VGA,"H D End %d, V D End %d",hdispend,vdispend); fps=clock/(vtotal*htotal); vga.draw.resizing=false; @@ -221,8 +221,8 @@ static void VGA_DoResize(void) { vga.draw.height=height; vga.draw.pitch=pitch; - LOG_VGA("Width %d, Height %d",width,height); - LOG_VGA("Flags %X, fps %f",flags,fps); + LOG(LOG_VGA,"Width %d, Height %d",width,height); + LOG(LOG_VGA,"Flags %X, fps %f",flags,fps); RENDER_SetSize(width,height,8,pitch,((float)width/(float)height),flags,&VGA_DrawHandler); vga.draw.blank=(Bitu)(1000000/fps); PIC_AddEvent(VGA_BlankTimer,vga.draw.blank); diff --git a/src/hardware/vga.h b/src/hardware/vga.h index 24537a4d..9ce4b993 100644 --- a/src/hardware/vga.h +++ b/src/hardware/vga.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -266,11 +266,6 @@ extern Bit32u CGAWriteTable[256]; extern Bit32u Expand16Table[4][16]; extern Bit32u Expand16BigTable[0x10000]; -#if DEBUG_VGA -#define LOG_VGA LOG_DEBUG -#else -#define LOG_VGA -#endif #endif diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 4bd43051..8c5d06a7 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -122,10 +122,10 @@ void write_p3c0(Bit32u port,Bit8u val) { except in 256 color mode. Note: this register does not affect 256 color modes. */ - if (val) LOG_DEBUG("VGA:ATTR:DAC index set to %d",val); + if (val) LOG(LOG_VGAGFX,"VGA:ATTR:DAC index set to %d",val); break; default: - LOG_ERROR("VGA:ATTR:Write to unkown Index %2X",attr(index)); + LOG(LOG_VGAMISC,"VGA:ATTR:Write to unkown Index %2X",attr(index)); break; } } @@ -151,7 +151,7 @@ Bit8u read_p3c1(Bit32u port) { case 0x14: /* Color Select Register */ return attr(color_select); default: - LOG_ERROR("VGA:ATTR:Read from unkown Index %2X",attr(index)); + LOG(LOG_VGAMISC,"VGA:ATTR:Read from unkown Index %2X",attr(index)); } return 0; }; diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 588f900b..56b558b7 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -274,7 +274,7 @@ void write_p3d5(Bit32u port,Bit8u val) { break; default: - LOG_ERROR("VGA:CRTC:Write to unknown index %2X",val,crtc(index)); + LOG(LOG_VGAMISC,"VGA:CRTC:Write to unknown index %2X",val,crtc(index)); } } @@ -331,7 +331,7 @@ Bit8u read_p3d5(Bit32u port) { case 0x18: /* Line Compare Register */ return crtc(line_compare); default: - LOG_ERROR("VGA:CRTC:Read from unknown index %X",crtc(index)); + LOG(LOG_VGAMISC,"VGA:CRTC:Read from unknown index %X",crtc(index)); } return 0; } diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index a4b400c5..f03db347 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -54,7 +54,7 @@ enum {DAC_READ,DAC_WRITE}; static void write_p3c6(Bit32u port,Bit8u val) { - if (val!=0xff) LOG_ERROR("VGA:Pel Mask not 0xff"); + if (val!=0xff) LOG(LOG_VGAGFX,"VGA:Pel Mask not 0xff"); vga.dac.pel_mask=val; } @@ -112,7 +112,7 @@ static void write_p3c9(Bit32u port,Bit8u val) { vga.dac.pel_index=0; break; default: - LOG_ERROR("VGA:DAC:Illegal Pel Index"); //If this can actually happen that will be the day + LOG(LOG_VGAGFX,"VGA:DAC:Illegal Pel Index"); //If this can actually happen that will be the day }; } @@ -133,7 +133,7 @@ static Bit8u read_p3c9(Bit32u port) { vga.dac.pel_index=0; break; default: - LOG_ERROR("VGA:DAC:Illegal Pel Index"); //If this can actually happen that will be the day + LOG(LOG_VGAMISC,"VGA:DAC:Illegal Pel Index"); //If this can actually happen that will be the day } return ret; } diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 006b1e13..055cefdb 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/vga_fonts.cpp b/src/hardware/vga_fonts.cpp index bba9b327..f5e75640 100644 --- a/src/hardware/vga_fonts.cpp +++ b/src/hardware/vga_fonts.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index a6e00d23..89fdf02d 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -70,7 +70,7 @@ void write_p3cf(Bit32u port,Bit8u val) { case 3: /* Data Rotate */ gfx(data_rotate)=val; vga.config.data_rotate=val & 7; - if (vga.config.data_rotate) LOG_WARN("VGA:Data Rotate used %d",val &7); + if (vga.config.data_rotate) LOG(LOG_VGAGFX,"VGA:Data Rotate used %d",val &7); vga.config.raster_op=(val>>3) & 3; /* 0-2 Number of positions to rotate data right before it is written to @@ -171,12 +171,12 @@ void write_p3cf(Bit32u port,Bit8u val) { case 9: /* Unknown */ /* Crystal Dreams seems to like to write tothis register very weird */ if (!index9warned) { - LOG_WARN("VGA:3CF:Write %2X to illegal index 9",val); + LOG(LOG_VGAMISC,"VGA:3CF:Write %2X to illegal index 9",val); index9warned=true; } break; default: - LOG_WARN("VGA:3CF:Write %2X to illegal index %2X",val,gfx(index)); + LOG(LOG_VGAMISC,"VGA:3CF:Write %2X to illegal index %2X",val,gfx(index)); break; } } @@ -202,7 +202,7 @@ switch (gfx(index)) { case 8: /* Bit Mask Register */ return gfx(bit_mask); default: - LOG_WARN("Reading from illegal index %2X in port %4X",gfx(index),port); + LOG(LOG_VGAMISC,"Reading from illegal index %2X in port %4X",gfx(index),port); } return 0; /* Compiler happy */ } diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 32af55b0..693d4a36 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -86,7 +86,7 @@ INLINE static Bit32u ModeOperation(Bit8u val) { full=RasterOp(vga.config.full_set_reset,ExpandTable[val] & vga.config.full_bit_mask); break; default: - LOG_ERROR("VGA:Unsupported write mode %d",vga.config.write_mode); + LOG(LOG_VGAMISC,"VGA:Unsupported write mode %d",vga.config.write_mode); } return full; } diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index cc40e120..1f4fcf40 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -48,7 +48,7 @@ static Bit8u read_p3da(Bit32u port) { static void write_p3d8(Bit32u port,Bit8u val) { - LOG_DEBUG("Write %2X to 3da",val); + LOG(LOG_VGAMISC,"Write %2X to 3da",val); /* 3 Vertical Sync Select. If set Vertical Sync to the monitor is the logical OR of the vertical sync and the vertical display enable. diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 15f0aa46..2fdaa178 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -91,7 +91,7 @@ void write_p3c5(Bit32u port,Bit8u val) { VGA_FindSettings(); break; default: - LOG_ERROR("VGA:SEQ:Write to illegal index %2X",seq(index)); + LOG(LOG_VGAMISC,"VGA:SEQ:Write to illegal index %2X",seq(index)); }; }; @@ -113,7 +113,7 @@ Bit8u read_p3c5(Bit32u port) { case 4: /* Memory Mode */ return seq(memory_mode); default: - LOG_ERROR("VGA:SEQ:Read from illegal index %2X",seq(index)); + LOG(LOG_VGAMISC,"VGA:SEQ:Read from illegal index %2X",seq(index)); }; return 0; }; diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 44e9f407..5f5fa259 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,18 +44,18 @@ static Bitu INT1A_Handler(void) { case 0x02: /* GET REAL-TIME CLOCK TIME (AT,XT286,PS) */ reg_dx=reg_cx=0; CALLBACK_SCF(false); - LOG_WARN("INT1A:02:Faked RTC get time call"); + LOG(LOG_BIOS,"INT1A:02:Faked RTC get time call"); break; case 0x04: /* GET REAL-TIME ClOCK DATA (AT,XT286,PS) */ reg_dx=reg_cx=0; CALLBACK_SCF(false); - LOG_WARN("INT1A:04:Faked RTC get date call"); + LOG(LOG_ERROR|LOG_BIOS,"INT1A:04:Faked RTC get date call"); break; case 0x80: /* Pcjr Setup Sound Multiplexer */ - LOG_WARN("INT1A:80:Setup tandy sound multiplexer to %d",reg_al); + LOG(LOG_ERROR|LOG_BIOS,"INT1A:80:Setup tandy sound multiplexer to %d",reg_al); break; case 0x81: /* Tandy sound system checks */ - LOG_WARN("INT1A:81:Tandy DAC Check failing"); + LOG(LOG_ERROR|LOG_BIOS,"INT1A:81:Tandy DAC Check failing"); break; /* INT 1A - Tandy 2500, Tandy 1000L series - DIGITAL SOUND - INSTALLATION CHECK @@ -68,7 +68,7 @@ static Bitu INT1A_Handler(void) { clear on return, then call AH=84h"Tandy" */ default: - LOG_WARN("INT1A:Undefined call %2X",reg_ah); + LOG(LOG_ERROR|LOG_BIOS,"INT1A:Undefined call %2X",reg_ah); } return CBRET_NONE; } @@ -96,7 +96,8 @@ static Bitu INT11_Handler(void) { internal modem installed (PC/Convertible) 14-15 number of parallel ports installed */ - reg_eax=0x104D; + reg_ax=0x104D; + LOG(LOG_BIOS,"INT11:Equipment list returned %X",reg_ax); return CBRET_NONE; } @@ -132,7 +133,7 @@ static Bitu INT12_Handler(void) { }; static Bitu INT17_Handler(void) { - LOG_ERROR("INT17:Not supported call for bios printer support"); + LOG(LOG_BIOS,"INT17:Function %X",reg_ah); switch(reg_ah) { case 0x00: /* PRINTER: Write Character */ reg_ah=1; /* Report a timeout */ @@ -146,7 +147,7 @@ static Bitu INT17_Handler(void) { E_Exit("Unhandled INT 17 call %2X",reg_ah); }; return CBRET_NONE; -}; +} static void WaitFlagEvent(void) { PhysPt where=Real2Phys(mem_readd(BIOS_WAIT_FLAG_POINTER)); @@ -157,10 +158,10 @@ static void WaitFlagEvent(void) { static Bitu INT15_Handler(void) { switch (reg_ah) { case 0x06: - LOG_WARN("Calling unkown int15 function 6"); + LOG(LOG_BIOS,"INT15 Unkown Function 6"); break; case 0xC0: /* Get Configuration*/ - LOG_WARN("Request BIOS Configuration INT 15 C0"); + LOG(LOG_ERROR|LOG_BIOS,"Request BIOS Configuration INT 15 C0"); CALLBACK_SCF(true); break; case 0x4f: /* BIOS - Keyboard intercept */ @@ -198,7 +199,7 @@ static Bitu INT15_Handler(void) { CALLBACK_SCF(true); } } else { - LOG_WARN("INT15:84: Unknown Bios Joystick functionality."); + LOG(LOG_ERROR|LOG_BIOS,"INT15:84:Unknown Bios Joystick functionality."); } break; case 0x86: /* BIOS - WAIT (AT,PS) */ @@ -220,18 +221,16 @@ static Bitu INT15_Handler(void) { reg_ah=0; break; case 0xc2: /* BIOS PS2 Pointing Device Support */ + case 0xc4: /* BIOS POS Programma option Select */ /* Damn programs should use the mouse drivers So let's fail these calls */ - CALLBACK_SCF(true); - break; - case 0xc4: /* BIOS POS Programma option Select */ - LOG_WARN("INT15:C4:Call for POS Function %2x",reg_al); + LOG(LOG_BIOS,"INT15:Function %X called,bios mouse not supported",reg_ah); CALLBACK_SCF(true); break; default: - LOG_WARN("INT15:Unknown call %2X",reg_ah); + LOG(LOG_ERROR|LOG_BIOS,"INT15:Unknown call %2X",reg_ah); reg_ah=0x86; CALLBACK_SCF(false); } @@ -242,7 +241,7 @@ static Bitu INT1_Single_Step(void) { static bool warned=false; if (!warned) { warned=true; - LOG_WARN("INT 1:Single Step called"); + LOG(LOG_CPU,"INT 1:Single Step called"); } return CBRET_NONE; } diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index cb53cb28..298ad39f 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,10 +34,10 @@ static Bitu INT13_SmallHandler(void) { case 0x0: reg_ah=0x00; CALLBACK_SCF(false); - LOG_DEBUG("reset disk return succesfull"); + LOG(LOG_BIOS,"reset disk return succesfull"); break; case 0x02: /* Read Disk Sectors */ - LOG_DEBUG("INT13:02:Read Disk Sectors not supported failing"); + LOG(LOG_BIOS,"INT13:02:Read Disk Sectors not supported failing"); reg_ah=0x80; CALLBACK_SCF(true); break; @@ -50,17 +50,17 @@ static Bitu INT13_SmallHandler(void) { reg_ah=0x80; CALLBACK_SCF(true); } - LOG_DEBUG("INT 13:04 Verify sector used on %d, with result %d",reg_dl,reg_ah); + LOG(LOG_BIOS,"INT 13:04 Verify sector used on %d, with result %d",reg_dl,reg_ah); break; case 0x08: /* Get Drive Parameters */ - LOG_DEBUG("INT13:08:Get Drive parameters not supported failing"); + LOG(LOG_BIOS,"INT13:08:Get Drive parameters not supported failing"); reg_ah=0xff; CALLBACK_SCF(true); break; case 0xff: default: - LOG_WARN("Illegal int 13h call %2X Fail it",reg_ah); + LOG(LOG_ERROR|LOG_BIOS,"Illegal int 13h call %2X Fail it",reg_ah); reg_ah=0xff; CALLBACK_SCF(true); } diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index afeaafc7..cfd3fef0 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -312,8 +312,7 @@ static Bitu INT16_Handler(void) { reg_al=mem_readb(BIOS_KEYBOARD_FLAGS1); break; case 0x03: /* SET TYPEMATIC RATE AND DELAY */ -//Have to implement this trhough SDL - LOG_DEBUG("INT16:Unhandled Typematic Rate Call %2X",reg_al); + LOG(LOG_ERROR|LOG_BIOS,"INT16:Unhandled Typematic Rate Call %2X",reg_al); break; case 0x05: /* STORE KEYSTROKE IN KEYBOARD BUFFER */ //TODO make add_key bool :) @@ -326,10 +325,10 @@ static Bitu INT16_Handler(void) { break; case 0x55: /* Weird call used by some dos apps */ - LOG_DEBUG("INT16:55:Word TSR compatible call"); + LOG(LOG_BIOS,"INT16:55:Word TSR compatible call"); break; default: - LOG_ERROR("INT16:Unhandled call %02X",reg_ah); + LOG(LOG_ERROR|LOG_BIOS,"INT16:Unhandled call %02X",reg_ah); break; }; diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 5df61c6e..2a6e4673 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -67,7 +67,7 @@ public: device_EMM(){name="EMMXXXX0";} bool Read(Bit8u * data,Bit16u * size) { return false;} bool Write(Bit8u * data,Bit16u * size){ - LOG_DEBUG("Write to ems device"); + LOG(LOG_IOCTL,"EMS:Write to device"); return false; } bool Seek(Bit32u * pos,Bit32u type){return false;} @@ -367,7 +367,7 @@ static Bit8u EMM_PartialPageMapping(void) { reg_al=2+reg_bx*(2+sizeof(EMM_Mapping)); break; default: - LOG_ERROR("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); + LOG(LOG_ERROR|LOG_MISC,"EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); return EMM_FUNC_NOSUP; } return EMM_NO_ERROR; @@ -391,7 +391,7 @@ static Bit8u HandleNameSearch(void) { reg_bx=EMM_MAX_HANDLES; break; default: - LOG_ERROR("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); + LOG(LOG_ERROR|LOG_MISC,"EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); return EMM_FUNC_NOSUP; } return EMM_NO_ERROR; @@ -417,7 +417,7 @@ static Bit8u MemoryRegion(void) { Bit8u buf_src[EMM_PAGE_SIZE]; Bit8u buf_dest[EMM_PAGE_SIZE]; if (reg_al>1) { - LOG_ERROR("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); + LOG(LOG_ERROR|LOG_MISC,"EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); return EMM_FUNC_NOSUP; } LoadMoveRegion(SegPhys(ds)+reg_si,region); @@ -578,7 +578,7 @@ static Bitu INT67_Handler(void) { reg_ah=EMM_NO_ERROR; break; default: - LOG_ERROR("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); + LOG(LOG_ERROR|LOG_MISC,"EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); reg_ah=EMM_FUNC_NOSUP; break; } @@ -615,7 +615,7 @@ static Bitu INT67_Handler(void) { break; case 0x53: // Set/Get Handlename if (reg_al==0x00) { // Get Name not supported - LOG_ERROR("EMS:Get handle name not supported",reg_ah); + LOG(LOG_ERROR|LOG_MISC,"EMS:Get handle name not supported",reg_ah); reg_ah=EMM_FUNC_NOSUP; } else { // Set name, not supported but faked reg_ah=EMM_NO_ERROR; @@ -626,7 +626,7 @@ static Bitu INT67_Handler(void) { break; case 0x57: /* Memory region */ reg_ah=MemoryRegion(); - if (reg_ah) LOG_WARN("ems 57 move failed"); + if (reg_ah) LOG(LOG_ERROR,"EMS:Function 57 move failed"); break; case 0x58: // Get mappable physical array address array if (reg_al==0x00) { @@ -642,11 +642,12 @@ static Bitu INT67_Handler(void) { reg_ah = EMM_NO_ERROR; break; case 0xDE: /* VCPI Functions */ - LOG_ERROR("VCPI Functions %X not supported",reg_al); + errorlevel=1; + E_Exit("Protected mode not supported"); reg_ah=EMM_FUNC_NOSUP; break; default: - LOG_ERROR("EMS:Call %2X not supported",reg_ah); + LOG(LOG_ERROR|LOG_MISC,"EMS:Call %2X not supported",reg_ah); reg_ah=EMM_FUNC_NOSUP; break; } @@ -660,7 +661,7 @@ void EMS_Init(Section* sec) { Bitu size=section->Get_int("emssize"); if (!size) return; if ((size*(1024/16))>EMM_MAX_PAGES) { - LOG_DEBUG("EMS Max size is %d",EMM_MAX_PAGES/(1024/16)); + LOG_MSG("EMS Max size is %d",EMM_MAX_PAGES/(1024/16)); emm_page_count=EMM_MAX_PAGES; } else { emm_page_count=size*(1024/16); diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 055c6ec7..571af946 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,7 +42,7 @@ static Bitu INT10_Handler(void) { break; case 0x01: /* Set TextMode Cursor Shape */ vga.internal.cursor=reg_cx; // maybe write some memory somewhere - LOG_DEBUG("INT10:01:Set textmode cursor shape partially supported: %X",reg_cx); + LOG(LOG_INT10,"INT10:01:Set textmode cursor shape partially supported: %X",reg_cx); break; case 0x02: /* Set Cursor Pos */ //TODO Check some shit but not really usefull @@ -54,11 +54,11 @@ static Bitu INT10_Handler(void) { reg_dh=CURSOR_POS_ROW(reg_bh); break; case 0x04: /* read light pen pos YEAH RIGHT */ - LOG_WARN("INT10:04:Ligthpen not supported"); + /* Light pen is not supported */ reg_ah=0; break; case 0x05: /* Set Active Page */ - if (reg_al & 0x80) LOG_DEBUG("Func %x",reg_al); + if (reg_al & 0x80) LOG(LOG_INT10,"Func %x",reg_al); else INT10_SetActivePage(reg_al); break; case 0x06: /* Scroll Up */ @@ -81,12 +81,10 @@ static Bitu INT10_Handler(void) { break; case 0x0B: /* Set Background/Border Colour & Set Palette*/ if(!warned_int10_0b) { - LOG_WARN("INT 10:0B Unsupported: Set Background/border colour & Set Pallete"); + LOG(LOG_ERROR|LOG_INT10,"Function 0B Unsupported: Set Background/border colour & Set Pallete"); warned_int10_0b=true; } break; - E_Exit("Unsupported int 10 call %02X" ,reg_ah); - break; case 0x0C: /* Write Graphics Pixel */ INT10_PutPixel(reg_cx,reg_dx,reg_bh,reg_al); break; @@ -137,7 +135,7 @@ static Bitu INT10_Handler(void) { INT10_GetDACBlock(reg_bx,reg_cx,SegPhys(es)+reg_dx); break; default: - LOG_WARN("INT10:10:Unhandled EGA/VGA Palette Function %2X",reg_al); + LOG(LOG_ERROR|LOG_INT10,"Function 10:Unhandled EGA/VGA Palette Function %2X",reg_al); } break; case 0x11: /* Character generator functions */ @@ -182,12 +180,12 @@ static Bitu INT10_Handler(void) { break; default: reg_cx=16; - LOG_DEBUG("INT10:11:30 Request for font %2X",reg_bh); + LOG(LOG_ERROR|LOG_INT10,"Fucntion 11:30 Request for font %2X",reg_bh); } reg_dl=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS); break; default: - LOG_WARN("INT10:11:Unsupported character generator call %2X",reg_al); + LOG(LOG_ERROR|LOG_INT10,"Function 11:Unsupported character generator call %2X",reg_al); } break; case 0x12: /* alternate function select */ @@ -200,7 +198,7 @@ static Bitu INT10_Handler(void) { break; } default: - LOG_WARN("Alternate functions select %2X not handled",reg_bl); + LOG(LOG_ERROR|LOG_INT10,"Function 12:Call %2X not handled",reg_bl); } break; case 0x13: /* Write String */ @@ -217,7 +215,6 @@ static Bitu INT10_Handler(void) { reg_al=0x1A; break; } - LOG_DEBUG("INT10:1A:Display Combination call %2X",reg_al); break; case 0x1B: /* functionality State Information */ switch (reg_bx) { @@ -226,15 +223,15 @@ static Bitu INT10_Handler(void) { reg_al=0x1B; break; default: - LOG_WARN("INT10:1B:Unhandled call BX %2X",reg_bx); + LOG(LOG_ERROR|LOG_INT10,"Function 1B:Unhandled call BX %2X",reg_bx); } break; case 0xff: - if (!warned_ff) LOG_WARN("INT10:FF:Weird NC call"); + if (!warned_ff) LOG(LOG_INT10,"INT10:FF:Weird NC call"); warned_ff=true; break; default: - LOG_WARN("Unhandled INT 10 call %2X",reg_ah); + LOG(LOG_ERROR|LOG_INT10,"Function %2X not supported",reg_ah); }; return CBRET_NONE; } @@ -273,8 +270,6 @@ void INT10_Init(Section* sec) { INT10_InitVGA(); /* Setup the INT 10 vector */ call_10=CALLBACK_Allocate(); - //TODO ERRORS ERRORS ERRORS - if (call_10==-1) E_Exit("Error can't allocate Video Int 10 CallBack\n"); CALLBACK_Setup(call_10,&INT10_Handler,CB_IRET); RealSetVec(0x10,CALLBACK_RealPointer(call_10)); //Init the 0x40 segment and init the datastructures in the the video rom area diff --git a/src/ints/int10.h b/src/ints/int10.h index 1e634b54..de9c92ce 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index c1b298cd..abb7d0d7 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -266,7 +266,7 @@ INLINE static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u at fontdata=&int10_font_16[chr*16]; break; default: - LOG_ERROR("INT10:Teletype Illegal Font Height"); + LOG(LOG_ERROR|LOG_INT10,"Teletype Illegal Font Height"); return; } x=8*col; diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 15731bd8..9674f99f 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -259,7 +259,7 @@ void INT10_SetVideoMode(Bit8u mode) { mode&=mode & 127; line=FindVideoMode(mode); if (line==0xff) { - LOG_ERROR("INT10:Trying to set non supported video mode %X",mode); + LOG(LOG_ERROR|LOG_INT10,"INT10:Trying to set non supported video mode %X",mode); return; } @@ -314,7 +314,7 @@ void INT10_SetVideoMode(Bit8u mode) { IO_Read(VGAREG_ACTL_RESET); //Set the palette - if ((modeset_ctl&0x08)==0x8) LOG_DEBUG("INT10:Mode set without palette"); + if ((modeset_ctl&0x08)==0x8) LOG(LOG_INT10,"Mode set without palette"); if((modeset_ctl&0x08)==0) { // Set the PEL mask IO_Write(VGAREG_PEL_MASK,vga_modes[line].pelmask); diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 60831dc3..934b7279 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -86,7 +86,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { case CTEXT: case MTEXT: default: - LOG_WARN("INT10:PutPixel Unhandled memory model %d",curmode->memmodel); + LOG(LOG_ERROR|LOG_INT10,"PutPixel Unhandled memory model %d",curmode->memmodel); break; } } @@ -135,7 +135,7 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { case CTEXT: case MTEXT: default: - LOG_WARN("INT10:GetPixel Unhanled memory model"); + LOG(LOG_ERROR|LOG_INT10,"GetPixel Unhandled memory model %d",curmode->memmodel); break; } } diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 07eec7e0..3a78c19d 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -567,7 +567,7 @@ static Bitu INT33_Handler(void) { reg_cl=0; /* Hmm ps2 irq dunno */ break; default: - LOG_ERROR("Mouse Function %2X",reg_ax); + LOG(LOG_ERROR|LOG_MOUSE,"Mouse Function %2X",reg_ax); } return CBRET_NONE; } diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 875baa2f..be28a19b 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -118,7 +118,7 @@ Bitu XMS_Handler(void) { case XMS_LOCAL_ENABLE_A20: /* 05 */ case XMS_LOCAL_DISABLE_A20: /* 06 */ case XMS_QUERY_A20: /* 07 */ - LOG_WARN("XMS:Unhandled call %2X",reg_ah); + LOG(LOG_ERROR|LOG_MISC,"XMS:Unhandled call %2X",reg_ah); break; case XMS_QUERY_FREE_EXTENDED_MEMORY: /* 08 */ /* Scan the tree for free memory and find largest free block */ @@ -316,7 +316,7 @@ foundnew: reg_dx=xms_handles[reg_dx].size; break; case XMS_RESIZE_EXTENDED_MEMORY_BLOCK: /* 0f */ - LOG_WARN("XMS:Unhandled call %2X",reg_ah); + LOG(LOG_ERROR|LOG_MISC,"XMS:Unhandled call %2X",reg_ah); break; case XMS_ALLOCATE_UMB: /* 10 */ reg_ax=0; @@ -325,7 +325,8 @@ foundnew: break; case XMS_DEALLOCATE_UMB: /* 11 */ default: - LOG_WARN("XMS:Unhandled call %2X",reg_ah);break; + LOG(LOG_ERROR|LOG_MISC,"XMS:Unhandled call %2X",reg_ah); + break; } return CBRET_NONE; diff --git a/src/misc/support.cpp b/src/misc/support.cpp index fb16f52a..f9509eb3 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -156,7 +156,6 @@ char * StripWord(char * cmd) { } void GFX_ShowMsg(char * msg); -void DEBUG_ShowMsg(char * msg); void S_Warn(char * format,...) { char buf[1024]; @@ -166,7 +165,7 @@ void S_Warn(char * format,...) { vsprintf(buf,format,msg); va_end(msg); #if C_DEBUG - DEBUG_ShowMsg(buf); + DEBUG_ShowMsg(0,buf); #else GFX_ShowMsg(buf); #endif From 8c0507b066dbaffd934bf721a11da6c7472b43b3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 2 Mar 2003 20:13:05 +0000 Subject: [PATCH 0617/4131] MPU-401 support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@696 --- src/hardware/mpu401.cpp | 93 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/hardware/mpu401.cpp diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp new file mode 100644 index 00000000..6a3022ea --- /dev/null +++ b/src/hardware/mpu401.cpp @@ -0,0 +1,93 @@ +#include +#include "dosbox.h" +#include "inout.h" +#include "mixer.h" +#include "dma.h" +#include "pic.h" +#include "hardware.h" +#include "setup.h" +#include "programs.h" + +void MIDI_RawOutByte(Bit8u data); +bool MIDI_Available(void); + +#define MPU_QUEUE 32 +enum MpuMode { M_UART,M_INTELLIGENT } ; + +#define CMD_RET_ACK 0xfe + +static struct { + MpuMode mode; + Bit8u queue[MPU_QUEUE]; + Bitu queue_pos,queue_used; + +} mpu; + +static void QueueByte(Bit8u data) { + if (mpu.queue_used=MPU_QUEUE) pos-=MPU_QUEUE; + mpu.queue_used++; + mpu.queue[pos]=data; + } else LOG(LOG_MISC,"MPU401:Data queue full"); +} + +static void ClrQueue(void) { + mpu.queue_used=0; + mpu.queue_pos=0; +} + +static void MPU401_WriteCommand(Bit32u port,Bit8u val) { + switch (val) { + case 0x3f: /* Switch to UART Mode */ + mpu.mode=M_UART; + QueueByte(CMD_RET_ACK); + break; + case 0xff: /* Reset Commmand */ + ClrQueue(); + QueueByte(CMD_RET_ACK); + break; + default: + LOG(LOG_MISC,"MPU401:Unhandled command %X",val); + break; + } + +} + +static Bit8u MPU401_ReadStatus(Bit32u port) { + + Bit8u ret=0x3f; /* Bith 6 and 7 clear */ + if (!mpu.queue_used) ret|=0x80; + return ret; +} + + +static void MPU401_WriteData(Bit32u port,Bit8u val) { + MIDI_RawOutByte(val); +} + +static Bit8u MPU401_ReadData(Bit32u port) { + Bit8u ret=CMD_RET_ACK; + if (mpu.queue_used) { + ret=mpu.queue[mpu.queue_pos]; + mpu.queue_pos++; + if (mpu.queue_pos>=MPU_QUEUE) mpu.queue_pos-=MPU_QUEUE; + mpu.queue_used--; + } + return ret; +} + + +void MPU401_Init(Section* sec) { + if (!MIDI_Available()) return; + + IO_RegisterWriteHandler(0x330,&MPU401_WriteData,"MPU401"); + IO_RegisterWriteHandler(0x331,&MPU401_WriteCommand,"MPU401"); + IO_RegisterReadHandler(0x330,&MPU401_ReadData,"MPU401"); + IO_RegisterReadHandler(0x331,&MPU401_ReadStatus,"MPU401"); + + mpu.queue_used=0; + mpu.queue_pos=0; +} + + From fb460d28a557a23663df4a9557fc910643119f07 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 2 Mar 2003 20:19:26 +0000 Subject: [PATCH 0618/4131] Support for the midi and mpu401 init functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@697 --- src/dosbox.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 804de4e1..005e6768 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -58,6 +58,7 @@ void CPU_Init(Section*); //void FPU_Init(); void DMA_Init(Section*); void MIXER_Init(Section*); +void MIDI_Init(Section*); void HARDWARE_Init(Section*); @@ -66,6 +67,7 @@ void JOYSTICK_Init(Section*); void MOUSE_Init(Section*); void SBLASTER_Init(Section*); void GUS_Init(Section*); +void MPU401_Init(Section*); void ADLIB_Init(Section*); void PCSPEAKER_Init(Section*); void TANDYSOUND_Init(Section*); @@ -186,6 +188,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&JOYSTICK_Init); secprop=control->AddSection_prop("mixer",&MIXER_Init); + secprop=control->AddSection_prop("midi",&MIDI_Init); #if C_DEBUG secprop=control->AddSection_prop("debug",&DEBUG_Init); #endif @@ -202,7 +205,9 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&CMS_Init); secprop->Add_bool("cms",false); -// secprop=control->AddSection_prop("gus",&GUS_Init); + secprop=control->AddSection_prop("gus",&GUS_Init); + + secprop=control->AddSection_prop("gus",&MPU401_Init); secprop=control->AddSection_prop("disney",&DISNEY_Init); secprop->Add_bool("enabled",true); From 732856e2f6a065bcd59e543fc219f568de99caa2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 2 Mar 2003 20:21:41 +0000 Subject: [PATCH 0619/4131] Midi support for win32 and linux oss Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@698 --- src/gui/Makefile.am | 3 +- src/gui/midi.cpp | 122 +++++++++++++++++++++++++++++++++++++++++++ src/gui/midi_oss.h | 60 +++++++++++++++++++++ src/gui/midi_win32.h | 67 ++++++++++++++++++++++++ 4 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 src/gui/midi.cpp create mode 100644 src/gui/midi_oss.h create mode 100644 src/gui/midi_win32.h diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index ec0a145a..1ae12e70 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -1,5 +1,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libgui.a -libgui_a_SOURCES = sdlmain.cpp render.cpp render_support.h +libgui_a_SOURCES = sdlmain.cpp render.cpp render_support.h \ + midi.cpp midi_win32.h midi_oss.h diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp new file mode 100644 index 00000000..7360faa5 --- /dev/null +++ b/src/gui/midi.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "dosbox.h" +#include "setup.h" + +Bit8u MIDI_evt_len[256] = { + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x10 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x30 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x40 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x50 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x60 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x70 + + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x80 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x90 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xa0 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xb0 + + 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xc0 + 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xd0 + + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xe0 + + 0,2,3,2, 0,0,1,1, 1,0,1,1, 1,0,1,1 // 0xf0 +}; + + +#if defined (WIN32) + +#include "midi_win32.h" + +#elif defined (UNIX) && !defined(__BEOS__) + +#include "midi_oss.h" + +#else /* Fall back to no device playing */ + +static void MIDI_PlayMsg(Bit32u msg) {} +static void MIDI_PlaySysex(Bit8u * sysex,Bitu len) {}; +static bool MIDI_StartUp(void) { return false;} + +#endif + + +static struct { + Bitu status; + Bitu cmd_len; + Bitu cmd_pos; + + Bit32u cmd_msg; + Bit8u data[4]; + struct { + Bit8u buf[256]; + Bitu used; + bool active; + } sysex; + bool available; +} midi; + + +void MIDI_RawOutByte(Bit8u data) { + /* Test for a new status byte */ + if (midi.sysex.active && !(data&0x80)) { + if (midi.sysex.used<256) midi.sysex.buf[midi.sysex.used++]=data; + return; + } else if (data&0x80) { + if (midi.sysex.active) { + /* Play a sysex message */ + midi.sysex.buf[midi.sysex.used++]=0xf7; + MIDI_PlaySysex(midi.sysex.buf,midi.sysex.used); + LOG(0,"Sysex message size %d",midi.sysex.used); + midi.sysex.active=false; + if (data==0xf7) return; + } + midi.status=data; + midi.cmd_pos=0; + midi.cmd_msg=0; + if (midi.status==0xf0) { + midi.sysex.active=true; + midi.sysex.buf[0]=0xf0; + midi.sysex.used=1; + return; + } + midi.cmd_len=MIDI_evt_len[data]; + } + midi.cmd_msg|=data << (8 * midi.cmd_pos); + midi.cmd_pos++; + if (midi.cmd_pos >= midi.cmd_len) { + MIDI_PlayMsg(midi.cmd_msg); + midi.cmd_msg=midi.status; + midi.cmd_pos=1; + } +} + +bool MIDI_Available(void) { + return midi.available; +} + + +void MIDI_Init(Section * sect) { + midi.available=MIDI_StartUp(); +} + diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h new file mode 100644 index 00000000..2141392d --- /dev/null +++ b/src/gui/midi_oss.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include + +static int m_device; + +#define SEQ_MIDIPUTC 5 + +static void MIDI_PlaySysex(Bit8u * sysex,Bitu len) { + Bit8u buf[1024];Bitu pos=0; + for (;len>0;len--) { + buf[pos++] = SEQ_MIDIPUTC; + buf[pos++] = *sysex++; + buf[pos++] = 0; //Device 0? + buf[pos++] = 0; + } + write(m_device,buf,pos); +} + +static void MIDI_PlayMsg(Bit32u msg) { + Bit8u buf[128];Bitu pos=0; + + Bitu len=MIDI_evt_len[msg & 0xff]; + for (;len>0;len--) { + buf[pos++] = SEQ_MIDIPUTC; + buf[pos++] = msg & 0xff; + buf[pos++] = 0; //Device 0? + buf[pos++] = 0; + msg >>=8; + } + write(m_device,buf,pos); +} + +static void MIDI_ShutDown(void) { + if (m_device>0) close(m_device); +} + +static bool MIDI_StartUp(void) { + m_device=open("/dev/midi", O_WRONLY, 0); + if (m_device<0) return false; + return true; +} + + diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h new file mode 100644 index 00000000..5501e53c --- /dev/null +++ b/src/gui/midi_win32.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + +static HMIDIOUT m_out; +static MIDIHDR m_hdr; +static HANDLE m_event; + +static Bit8u m_msg[300]; + +static void MIDI_PlaySysex(Bit8u * sysex,Bitu len) { + + if (WaitForSingleObject (m_event, 2000) == WAIT_TIMEOUT) { + LOG(LOG_MISC|LOG_ERROR,"Can't send midi message"); + return; + } + midiOutUnprepareHeader (m_out, &m_hdr, sizeof (m_hdr)); + memcpy (&m_msg, sysex, len); + + m_hdr.lpData = (char *) m_msg; + m_hdr.dwBufferLength = len ; + m_hdr.dwBytesRecorded = len ; + m_hdr.dwUser = 0; + + MMRESULT result = midiOutPrepareHeader (m_out, &m_hdr, sizeof (m_hdr)); + if (result != MMSYSERR_NOERROR) return; + ResetEvent (m_event); + result = midiOutLongMsg (m_out,&m_hdr,sizeof(m_hdr)); + if (result != MMSYSERR_NOERROR) { + SetEvent (m_event); + return; + } +} + +static void MIDI_PlayMsg(Bit32u msg) { + MMRESULT ret=midiOutShortMsg(m_out, msg); +} + + + +static bool MIDI_StartUp(void) { + m_event = CreateEvent (NULL, true, true, NULL); + MMRESULT res = midiOutOpen(&m_out, MIDI_MAPPER, (DWORD)m_event, 0, CALLBACK_EVENT); + if (res != MMSYSERR_NOERROR) return false; + return true; +} + + + From 4913f1ea136ca212ff77122c45ee8694920f8e67 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 2 Mar 2003 20:30:08 +0000 Subject: [PATCH 0620/4131] Back to the english version Added mpu401 and midi and winmm.lib in linking Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@699 --- visualc/dosbox.dsp | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index f441b904..e6fa1064 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -1,24 +1,24 @@ # Microsoft Developer Studio Project File - Name="dosbox" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** NICHT BEARBEITEN ** +# ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 CFG=dosbox - Win32 Debug -!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE -!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "dosbox.mak". !MESSAGE -!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben -!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "dosbox.mak" CFG="dosbox - Win32 Debug" !MESSAGE -!MESSAGE Für die Konfiguration stehen zur Auswahl: +!MESSAGE Possible choices for configuration are: !MESSAGE -!MESSAGE "dosbox - Win32 Release" (basierend auf "Win32 (x86) Console Application") -!MESSAGE "dosbox - Win32 Debug" (basierend auf "Win32 (x86) Console Application") +!MESSAGE "dosbox - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "dosbox - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project @@ -50,7 +50,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 zlib.lib libpng.lib sdlmain.lib sdl.lib curses.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 winmm.lib zlib.lib libpng.lib sdlmain.lib sdl.lib curses.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 !ELSEIF "$(CFG)" == "dosbox - Win32 Debug" @@ -75,7 +75,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 zlib.lib libpng.lib sdlmain.lib sdl.lib curses.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 winmm.lib zlib.lib libpng.lib sdlmain.lib sdl.lib curses.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept !ENDIF @@ -267,6 +267,14 @@ SOURCE=..\src\dos\dos_tables.cpp # PROP Default_Filter "" # Begin Source File +SOURCE=..\src\gui\midi.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\gui\midi_win32.h +# End Source File +# Begin Source File + SOURCE=..\src\gui\render.cpp # End Source File # Begin Source File @@ -387,6 +395,10 @@ SOURCE=..\src\hardware\mixer.cpp # End Source File # Begin Source File +SOURCE=..\src\hardware\mpu401.cpp +# End Source File +# Begin Source File + SOURCE=..\src\hardware\pcspeaker.cpp # End Source File # Begin Source File From 673d83519d1a6edc36112a340a89fba1d3c5c06a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 2 Mar 2003 20:35:33 +0000 Subject: [PATCH 0621/4131] Moved the mpu401 init function under the soundblaster. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@700 --- src/dosbox.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 005e6768..f6870d91 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -204,11 +204,10 @@ void DOSBOX_Init(void) { secprop->Add_bool("adlib",true); secprop->AddInitFunction(&CMS_Init); secprop->Add_bool("cms",false); + secprop->AddInitFunction(&MPU401_Init); secprop=control->AddSection_prop("gus",&GUS_Init); - secprop=control->AddSection_prop("gus",&MPU401_Init); - secprop=control->AddSection_prop("disney",&DISNEY_Init); secprop->Add_bool("enabled",true); From 4753d75cbf3a759c7d057888f5e81985d6f5c899 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 2 Mar 2003 20:36:58 +0000 Subject: [PATCH 0622/4131] added mpu401.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@701 --- src/hardware/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index 737c3ebe..6fca05e8 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -8,5 +8,5 @@ libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ vga.cpp vga.h vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_fonts.cpp vga_gfx.cpp \ vga_memory.cpp vga_misc.cpp vga_seq.cpp font-switch.h ega-switch.h cmos.cpp disney.cpp \ - gus.cpp + gus.cpp mpu401.cpp From 5fb73510fe73cac31c9e1f8827b1c89c4992ab71 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 2 Mar 2003 21:08:27 +0000 Subject: [PATCH 0623/4131] Check for an empty string for debug logging file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@702 --- src/debug/debug_gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 3b718556..e5b06b1c 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -140,7 +140,7 @@ static void LOG_Destroy(Section* sec) { static void LOG_Init(Section * sec) { Section_prop * sect=static_cast(sec); const char * blah=sect->Get_string("logfile"); - if(blah && (debuglog = fopen(blah,"wt+"))){ + if(blah && blah[0] &&(debuglog = fopen(blah,"wt+"))){ }else{ debuglog=0; } From 60c35559f970676771aa0199fc5dff825a11c0b8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 2 Mar 2003 21:42:43 +0000 Subject: [PATCH 0624/4131] Ascii foreign keyboard support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@703 --- include/keyboard.h | 24 +++++++++++++----------- src/gui/sdlmain.cpp | 18 +++++++++++------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/include/keyboard.h b/include/keyboard.h index 0ff524e4..db7b0c13 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -19,17 +19,7 @@ #ifndef _KEYBOARD_H_ #define _KEYBOARD_H_ -typedef void(KEYBOARD_EventHandler)(void); -void KEYBOARD_AddCode(Bit8u code); -void KEYBOARD_AddKey(Bitu keytype,bool pressed); -void KEYBOARD_AddEvent(Bitu keytype,Bitu state,KEYBOARD_EventHandler * handler); - - -#define ALT_PRESSED 0x1 -#define CTRL_PRESSED 0x2 -#define SHIFT_PRESSED 0x4 - -enum { +enum KBD_KEYS { KBD_1, KBD_2, KBD_3, KBD_4, KBD_5, KBD_6, KBD_7, KBD_8, KBD_9, KBD_0, KBD_q, KBD_w, KBD_e, KBD_r, KBD_t, KBD_y, KBD_u, KBD_i, KBD_o, KBD_p, KBD_a, KBD_s, KBD_d, KBD_f, KBD_g, KBD_h, KBD_j, KBD_k, KBD_l, KBD_z, @@ -54,4 +44,16 @@ enum { KBD_LAST }; +typedef void(KEYBOARD_EventHandler)(void); + +void KEYBOARD_AddEvent(Bitu keytype,Bitu state,KEYBOARD_EventHandler * handler); +void KEYBOARD_AddKey(KBD_KEYS key,Bitu ascii,Bitu mod,bool pressed); +void KEYBOARD_ReadKey(Bitu & scancode,Bitu & ascii,Bitu & mod); + + +#define KBD_MOD_ALT 0x1 +#define KBD_MOD_CTRL 0x2 +#define KBD_MOD_SHIFT 0x4 + + #endif diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index b59538e2..7f32f2d2 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -250,14 +250,12 @@ static void GUI_StartUp(Section * sec) { /* Initialize screen for first time */ GFX_SetSize(640,400,8,0,0,0); SDL_EnableKeyRepeat(250,30); - + SDL_EnableUNICODE(1); /* Get some Keybinds */ - KEYBOARD_AddEvent(KBD_f10,CTRL_PRESSED,CaptureMouse); - KEYBOARD_AddEvent(KBD_enter,ALT_PRESSED,SwitchFullScreen); + KEYBOARD_AddEvent(KBD_f10,KBD_MOD_CTRL,CaptureMouse); + KEYBOARD_AddEvent(KBD_enter,KBD_MOD_ALT,SwitchFullScreen); } - - void Mouse_AutoLock(bool enable) { sdl.mouse.autolock=enable; if (enable && sdl.mouse.autoenable) sdl.mouse.requestlock=true; @@ -265,7 +263,7 @@ void Mouse_AutoLock(bool enable) { } static void HandleKey(SDL_KeyboardEvent * key) { - Bit32u code; + KBD_KEYS code; switch (key->keysym.sym) { case SDLK_1:code=KBD_1;break; case SDLK_2:code=KBD_2;break; @@ -386,7 +384,13 @@ static void HandleKey(SDL_KeyboardEvent * key) { //TODO maybe give warning for keypress unknown return; } - KEYBOARD_AddKey(code,(key->state==SDL_PRESSED)); + /* Check the modifiers */ + Bitu mod= + ((key->keysym.mod & KMOD_CTRL) ? KBD_MOD_CTRL : 0) | + ((key->keysym.mod & KMOD_ALT) ? KBD_MOD_ALT : 0) | + ((key->keysym.mod & KMOD_SHIFT) ? KBD_MOD_SHIFT : 0); + Bitu ascii=key->keysym.unicode<128 ? key->keysym.unicode : 0; + KEYBOARD_AddKey(code,ascii,mod,(key->state==SDL_PRESSED)); } static void HandleMouseMotion(SDL_MouseMotionEvent * motion) { From 5c8b61d6243a01a70237d1d7e2ea6ecf4bd6849b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 2 Mar 2003 21:45:30 +0000 Subject: [PATCH 0625/4131] Foreign keyboard support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@704 --- src/hardware/keyboard.cpp | 175 ++++++++++++++++++++++++-------------- 1 file changed, 109 insertions(+), 66 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index bc558299..f389360c 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -24,6 +24,7 @@ #include "mixer.h" #define KEYBUFSIZE 32 +#define KEYDELAY 250 enum KeyCommands { CMD_NONE, @@ -31,6 +32,17 @@ enum KeyCommands { CMD_SETTYPERATE }; +enum KeyStates { + STATE_NORMAL, + STATE_EXTEND, +}; + +struct KeyCode { + Bit8u scancode; + Bit8u ascii; + KeyStates state; + Bitu mod; +}; struct KeyEvent { Bitu type; @@ -40,63 +52,104 @@ struct KeyEvent { }; struct KeyBlock { - Bit8u buf[KEYBUFSIZE]; - Bitu buf_pos; - Bitu buf_used; + struct { + KeyCode code[KEYBUFSIZE]; + Bitu used; + Bitu pos; + KeyStates state; + } buf; Bitu write_state; - + Bit64u last_index; KeyCommands command; - bool read_active; bool enabled; bool active; + bool scheduled; + bool read_active; }; static KeyBlock keyb; -static Bitu shift_state=0; static Bit8u cur_scancode; static Bit8u port_61_data; //TODO Are these initialized at 0 at startup? Hope so :) static KeyEvent * event_handlers[KBD_LAST]; - void KEYBOARD_ClrBuffer(void) { - keyb.buf_used=0; - keyb.buf_pos=0; + keyb.buf.used=0; + keyb.buf.pos=0; keyb.read_active=false; PIC_DeActivateIRQ(1); } - -void KEYBOARD_ReadBuffer(void) { - if (keyb.read_active) return; - if (keyb.buf_used) { - keyb.buf_used--; - keyb.buf_pos++; - if (keyb.buf_pos>=KEYBUFSIZE) keyb.buf_pos=0; +/* Read an entry from the keycode buffer */ +void KEYBOARD_GetCode(void) { + keyb.scheduled=false; + switch (keyb.buf.state) { + case STATE_NORMAL: + /* Check for a next key */ + if (!keyb.buf.used) return; + keyb.buf.used--; + keyb.buf.pos++; + if (keyb.buf.pos>=KEYBUFSIZE) keyb.buf.pos-=KEYBUFSIZE; + keyb.buf.state=keyb.buf.code[keyb.buf.pos].state; + break; + case STATE_EXTEND: + keyb.buf.state=STATE_NORMAL; + break; } - if (keyb.buf_used) { - keyb.read_active=true; - PIC_ActivateIRQ(1); + PIC_ActivateIRQ(1); +} + +void KEYBOARD_AddCode(Bit8u scancode,Bit8u ascii,Bitu mod,KeyStates state) { + if (keyb.buf.used=KEYBUFSIZE) start-=KEYBUFSIZE; + keyb.buf.code[start].scancode=scancode; + keyb.buf.code[start].ascii=ascii; + keyb.buf.code[start].state=state; + keyb.buf.code[start].mod=mod; + } + /* Start up an event to start the first IRQ */ + if (!keyb.scheduled) { + keyb.scheduled=true; + PIC_AddEvent(KEYBOARD_GetCode,KEYDELAY); } } -void KEYBOARD_AddCode(Bit8u code) { - if (keyb.buf_used=KEYBUFSIZE) start-=KEYBUFSIZE; - keyb.buf[start]=code; - keyb.read_active=true; +void KEYBOARD_ReadKey(Bitu & scancode,Bitu & ascii,Bitu & mod) { + switch (keyb.buf.state) { + case STATE_NORMAL: + scancode=keyb.buf.code[keyb.buf.pos].scancode; + ascii=keyb.buf.code[keyb.buf.pos].ascii; + mod=keyb.buf.code[keyb.buf.pos].mod; + if (keyb.buf.used && !keyb.scheduled) { + keyb.scheduled=true; + PIC_AddEvent(KEYBOARD_GetCode,KEYDELAY); + } + break; + case STATE_EXTEND: + KEYBOARD_GetCode(); + scancode=224; + mod=0; + ascii=0; + break; } - if (keyb.buf_used==1) PIC_AddIRQ(1,0); } static Bit8u read_p60(Bit32u port) { - /* Reading this port signals that IRQ can be lowered */ - Bit8u val=keyb.buf[keyb.buf_pos]; - keyb.read_active=false; - return keyb.buf[keyb.buf_pos]; -} + switch (keyb.buf.state) { + case STATE_NORMAL: + if (keyb.buf.used && !keyb.scheduled) { + keyb.scheduled=true; + PIC_AddEvent(KEYBOARD_GetCode,KEYDELAY); + } + return keyb.buf.code[keyb.buf.pos].scancode; + case STATE_EXTEND: + KEYBOARD_GetCode(); + return 224; + } + return 0; +} static void write_p60(Bit32u port,Bit8u val) { switch (keyb.command) { @@ -105,18 +158,18 @@ static void write_p60(Bit32u port,Bit8u val) { switch (val) { case 0xed: /* Set Leds */ keyb.command=CMD_SETLEDS; - KEYBOARD_AddCode(0xfa); /* Acknowledge */ + KEYBOARD_AddCode(0xfa,0,0,STATE_NORMAL); /* Acknowledge */ break; case 0xee: /* Echo */ - KEYBOARD_AddCode(0xee); + KEYBOARD_AddCode(0xee,0,0,STATE_NORMAL); break; case 0xf2: /* Identify keyboard */ /* AT's just send acknowledge */ - KEYBOARD_AddCode(0xfa); /* Acknowledge */ + KEYBOARD_AddCode(0xfa,0,0,STATE_NORMAL); /* Acknowledge */ break; case 0xf3: /* Typematic rate programming */ keyb.command=CMD_SETTYPERATE; - KEYBOARD_AddCode(0xfa); /* Acknowledge */ + KEYBOARD_AddCode(0xfa,0,0,STATE_NORMAL); /* Acknowledge */ break; default: LOG(LOG_ERROR|LOG_KEYBOARD,"60:Unhandled command %X",val); @@ -125,7 +178,7 @@ static void write_p60(Bit32u port,Bit8u val) { case CMD_SETTYPERATE: case CMD_SETLEDS: keyb.command=CMD_NONE; - KEYBOARD_AddCode(0xfa); /* Acknowledge */ + KEYBOARD_AddCode(0xfa,0,0,STATE_NORMAL); /* Acknowledge */ break; } } @@ -133,16 +186,15 @@ static void write_p60(Bit32u port,Bit8u val) { static Bit8u read_p61(Bit32u port) { port_61_data^=0x20; return port_61_data; - -}; - -static void KEYBOARD_IRQHandler(void) { - if (!keyb.read_active) KEYBOARD_ReadBuffer(); } static void write_p61(Bit32u port,Bit8u val) { port_61_data=val; +/* if (val & 128) if (!keyb.read_active) KEYBOARD_ReadBuffer(); + Keys should get acknowledged just by reading 0x60. + Perhaps disable controller when bit 7=1 +*/ if ((val & 3)==3) { PCSPEAKER_Enable(true); } else { @@ -168,7 +220,6 @@ static Bit8u read_p64(Bit32u port) { return 0x1c | (keyb.read_active ? 0x1 : 0x0); } - void KEYBOARD_AddEvent(Bitu keytype,Bitu state,KEYBOARD_EventHandler * handler) { KeyEvent * newevent=new KeyEvent; /* Add the event in the correct key structure */ @@ -182,9 +233,9 @@ void KEYBOARD_AddEvent(Bitu keytype,Bitu state,KEYBOARD_EventHandler * handler) newevent->handler=handler; } -void KEYBOARD_AddKey(Bitu keytype,bool pressed) { - bool extend=false; - Bit8u ret=0; + +void KEYBOARD_AddKey(KBD_KEYS keytype,Bitu unicode,Bitu mod,bool pressed) { + Bit8u ret=0;bool extend=false; switch (keytype) { case KBD_esc:ret=1;break; case KBD_1:ret=2;break; @@ -217,9 +268,7 @@ void KEYBOARD_AddKey(Bitu keytype,bool pressed) { case KBD_leftbracket:ret=26;break; case KBD_rightbracket:ret=27;break; case KBD_enter:ret=28;break; - case KBD_leftctrl:ret=29; - shift_state=(shift_state&~CTRL_PRESSED)|(pressed ? CTRL_PRESSED:0); - break; + case KBD_leftctrl:ret=29;break; case KBD_a:ret=30;break; case KBD_s:ret=31;break; @@ -234,9 +283,7 @@ void KEYBOARD_AddKey(Bitu keytype,bool pressed) { case KBD_semicolon:ret=39;break; case KBD_quote:ret=40;break; case KBD_grave:ret=41;break; - case KBD_leftshift:ret=42; - shift_state=(shift_state&~SHIFT_PRESSED)|(pressed ? SHIFT_PRESSED:0); - break; + case KBD_leftshift:ret=42;break; case KBD_backslash:ret=43;break; case KBD_z:ret=44;break; case KBD_x:ret=45;break; @@ -251,9 +298,7 @@ void KEYBOARD_AddKey(Bitu keytype,bool pressed) { case KBD_slash:ret=53;break; case KBD_rightshift:ret=54;break; case KBD_kpmultiply:ret=55;break; - case KBD_leftalt:ret=56; - shift_state=(shift_state&~ALT_PRESSED)|(pressed ? ALT_PRESSED:0); - break; + case KBD_leftalt:ret=56;break; case KBD_space:ret=57;break; case KBD_capslock:ret=58;break; @@ -291,13 +336,9 @@ void KEYBOARD_AddKey(Bitu keytype,bool pressed) { //The Extended keys case KBD_kpenter:extend=true;ret=28;break; - case KBD_rightctrl:extend=true;ret=29; - shift_state=(shift_state&~CTRL_PRESSED)|(pressed ? CTRL_PRESSED:0); - break; + case KBD_rightctrl:extend=true;ret=29;break; case KBD_kpslash:extend=true;ret=53;break; - case KBD_rightalt:extend=true;ret=56; - shift_state=(shift_state&~ALT_PRESSED)|(pressed ? ALT_PRESSED:0); - break; + case KBD_rightalt:extend=true;ret=56;break; case KBD_home:extend=true;ret=71;break; case KBD_up:extend=true;ret=72;break; case KBD_pageup:extend=true;ret=73;break; @@ -315,7 +356,7 @@ void KEYBOARD_AddKey(Bitu keytype,bool pressed) { /* check for active key events */ KeyEvent * checkevent=event_handlers[keytype]; while (checkevent) { - if ((shift_state & checkevent->state)==checkevent->state) { + if ((mod & checkevent->state)==checkevent->state) { if (checkevent->type==keytype && pressed) { (*checkevent->handler)(); return; @@ -324,9 +365,9 @@ void KEYBOARD_AddKey(Bitu keytype,bool pressed) { } checkevent=checkevent->next; } - if (extend) KEYBOARD_AddCode(224); + /* Add the actual key in the keyboard queue */ if (!pressed) ret+=128; - KEYBOARD_AddCode(ret); + KEYBOARD_AddCode(ret,(Bit8u)unicode,mod,extend ? STATE_EXTEND : STATE_NORMAL); } void KEYBOARD_Init(Section* sec) { @@ -337,11 +378,13 @@ void KEYBOARD_Init(Section* sec) { IO_RegisterWriteHandler(0x64,write_p64,"Keyboard"); IO_RegisterReadHandler(0x64,read_p64,"Keyboard"); - port_61_data=1; /* Speaker control through PIT and speaker disabled */ + port_61_data=0; /* Direct Speaker control and output disabled */ // memset(&event_handlers,0,sizeof(event_handlers)); /* Clear the keyb struct */ keyb.enabled=true; keyb.command=CMD_NONE; + keyb.last_index=0; + keyb.buf.pos=0; + keyb.buf.used=0; KEYBOARD_ClrBuffer(); - PIC_RegisterIRQ(1,KEYBOARD_IRQHandler,"KEYBOARD"); } From fe1b5109f571482b97fbabfe5a7e29732b1ccf68 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 2 Mar 2003 21:46:25 +0000 Subject: [PATCH 0626/4131] foreign keyboard support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@705 --- src/ints/bios_keyboard.cpp | 42 +++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index cfd3fef0..f84a9b5e 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -197,17 +197,24 @@ static Bit16u check_key(void) { static Bitu IRQ1_Handler(void) { - //TODO CAPSLOCK NUMLOCK SCROLLLOCK maybe :) - Bit8u code=IO_Read(0x60); + /* Read the code */ + Bitu scancode,ascii,mod; +#if 0 + scancode=IO_Read(0x60); + ascii=0; + mod=0; +#else + KEYBOARD_ReadKey(scancode,ascii,mod); +// LOG(0,"Got code %X ascii %C mod %X",scancode,ascii,mod); +#endif + //TODO maybe implement the int 0x15 ah=4f scancode lookup hook -/* Changed it so the flag handling takes place in here too */ Bit8u flags1=mem_readb(BIOS_KEYBOARD_FLAGS1); Bit8u flags2=mem_readb(BIOS_KEYBOARD_FLAGS2); Bit8u flags3=mem_readb(BIOS_KEYBOARD_FLAGS3); - switch (code) { + switch (scancode) { /* First the hard ones */ - case 0xe0: - //TODO Think of something else maybe + case 0xe0: /* Extended key */ flags3|=2; break; case 29: /* Ctrl Pressed */ @@ -258,17 +265,18 @@ static Bitu IRQ1_Handler(void) { /* Now Handle the releasing of keys and see if they match up for a code */ flags3&=~2; //Reset 0xE0 Flag /* Handle the actual scancode */ - if (code & 0x80) goto irq1_end; - if (code > MAX_SCAN_CODE) goto irq1_end; - if (flags1 & 8) { /* Alt is being pressed */ - asciiscan=scan_to_scanascii[code].alt; - } else if (flags1 & 4) { /* Ctrl is being pressed */ - asciiscan=scan_to_scanascii[code].control; - } else if (flags1 & 3) { /* Either shift is being pressed */ -//TODO Maybe check for Capslock sometime in some bored way - asciiscan=scan_to_scanascii[code].shift; + if (scancode & 0x80) goto irq1_end; + if (scancode > MAX_SCAN_CODE) goto irq1_end; + if (mod & KBD_MOD_ALT) { /* Alt is being pressed */ + asciiscan=scan_to_scanascii[scancode].alt; + } else if (ascii) { + asciiscan=(scancode << 8) | ascii; + } else if (mod & KBD_MOD_CTRL) { /* Ctrl is being pressed */ + asciiscan=scan_to_scanascii[scancode].control; + } else if (mod & KBD_MOD_SHIFT) { /* Either shift is being pressed */ + asciiscan=scan_to_scanascii[scancode].shift; } else { - asciiscan=scan_to_scanascii[code].normal; + asciiscan=scan_to_scanascii[scancode].normal; } add_key(asciiscan); }; @@ -277,10 +285,12 @@ irq1_end: mem_writeb(BIOS_KEYBOARD_FLAGS2,flags2); mem_writeb(BIOS_KEYBOARD_FLAGS3,flags3); IO_Write(0x20,0x20); +#if 0 /* Signal the keyboard for next code */ Bit8u old61=IO_Read(0x61); IO_Write(0x61,old61 | 128); IO_Write(0x61,old61 & 127); +#endif return CBRET_NONE; } From b36c835664f07ab140d75e32d68d6d893ea96957 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 2 Mar 2003 21:50:42 +0000 Subject: [PATCH 0627/4131] Changed keyboard modifiers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@706 --- src/cpu/cpu.cpp | 4 ++-- src/gui/render.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 65eac27f..854d3834 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -173,8 +173,8 @@ void CPU_Init(Section* sec) { SetCPU16bit(); - KEYBOARD_AddEvent(KBD_f11,CTRL_PRESSED,CPU_CycleDecrease); - KEYBOARD_AddEvent(KBD_f12,CTRL_PRESSED,CPU_CycleIncrease); + KEYBOARD_AddEvent(KBD_f11,KBD_MOD_CTRL,CPU_CycleDecrease); + KEYBOARD_AddEvent(KBD_f12,KBD_MOD_CTRL,CPU_CycleIncrease); CPU_Cycles=0; CPU_CycleMax=section->Get_int("cycles");; diff --git a/src/gui/render.cpp b/src/gui/render.cpp index dc9edd29..6341bf0a 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -322,8 +322,8 @@ void RENDER_Init(Section * sec) { render.keep_small=section->Get_bool("keepsmall"); render.frameskip.max=section->Get_int("frameskip"); render.frameskip.count=0; - KEYBOARD_AddEvent(KBD_f5,CTRL_PRESSED,EnableScreenShot); - KEYBOARD_AddEvent(KBD_f7,CTRL_PRESSED,DecreaseFrameSkip); - KEYBOARD_AddEvent(KBD_f8,CTRL_PRESSED,IncreaseFrameSkip); + KEYBOARD_AddEvent(KBD_f5,KBD_MOD_CTRL,EnableScreenShot); + KEYBOARD_AddEvent(KBD_f7,KBD_MOD_CTRL,DecreaseFrameSkip); + KEYBOARD_AddEvent(KBD_f8,KBD_MOD_CTRL,IncreaseFrameSkip); } From 712de9cd789b37998b7613823298c10bdde031d5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 2 Mar 2003 23:34:15 +0000 Subject: [PATCH 0628/4131] sysex message size now 1024 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@707 --- src/gui/midi.cpp | 7 ++++--- src/gui/midi_oss.h | 2 +- src/gui/midi_win32.h | 4 +--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 7360faa5..a3a29823 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -42,8 +42,9 @@ Bit8u MIDI_evt_len[256] = { 0,2,3,2, 0,0,1,1, 1,0,1,1, 1,0,1,1 // 0xf0 }; - +#define SYSEX_SIZE 1024 + #if defined (WIN32) #include "midi_win32.h" @@ -69,7 +70,7 @@ static struct { Bit32u cmd_msg; Bit8u data[4]; struct { - Bit8u buf[256]; + Bit8u buf[SYSEX_SIZE]; Bitu used; bool active; } sysex; @@ -80,7 +81,7 @@ static struct { void MIDI_RawOutByte(Bit8u data) { /* Test for a new status byte */ if (midi.sysex.active && !(data&0x80)) { - if (midi.sysex.used<256) midi.sysex.buf[midi.sysex.used++]=data; + if (midi.sysex.used<(SYSEX_SIZE-1)) midi.sysex.buf[midi.sysex.used++]=data; return; } else if (data&0x80) { if (midi.sysex.active) { diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index 2141392d..a45e25bc 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -23,7 +23,7 @@ static int m_device; #define SEQ_MIDIPUTC 5 static void MIDI_PlaySysex(Bit8u * sysex,Bitu len) { - Bit8u buf[1024];Bitu pos=0; + Bit8u buf[SYSEX_SIZE*4];Bitu pos=0; for (;len>0;len--) { buf[pos++] = SEQ_MIDIPUTC; buf[pos++] = *sysex++; diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index 5501e53c..5f30c293 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -24,7 +24,6 @@ static HMIDIOUT m_out; static MIDIHDR m_hdr; static HANDLE m_event; -static Bit8u m_msg[300]; static void MIDI_PlaySysex(Bit8u * sysex,Bitu len) { @@ -33,9 +32,8 @@ static void MIDI_PlaySysex(Bit8u * sysex,Bitu len) { return; } midiOutUnprepareHeader (m_out, &m_hdr, sizeof (m_hdr)); - memcpy (&m_msg, sysex, len); - m_hdr.lpData = (char *) m_msg; + m_hdr.lpData = (char *) sysex; m_hdr.dwBufferLength = len ; m_hdr.dwBytesRecorded = len ; m_hdr.dwUser = 0; From 24c3854149a55998825d2bacd53d8c51c561c4ea Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 3 Mar 2003 20:34:05 +0000 Subject: [PATCH 0629/4131] added basic handlers for int 25 and int 26 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@708 --- src/dos/dos.cpp | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index abc087a1..710a7f92 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -33,7 +33,7 @@ DOS_Block dos; DOS_InfoBlock dos_infoblock; Bit8u dos_copybuf[0x10000]; -static Bitu call_20,call_21,call_27,call_28,call_29; +static Bitu call_20,call_21,call_25,call_26,call_27,call_28,call_29; void DOS_SetError(Bit16u code) { dos.errorcode=code; @@ -860,7 +860,29 @@ static Bitu DOS_27Handler(void) if (DOS_ResizeMemory(dos.psp,¶)) DOS_Terminate(true); return CBRET_NONE; } - +static Bitu DOS_25Handler(void) { + if(Drives[reg_al]==0){ + reg_ax=0x8002; + CALLBACK_SCF(true); + }else{ + CALLBACK_SCF(false); + reg_ax=0; + if((reg_cx != 1) ||(reg_dx != 1)) + LOG(LOG_DOSMISC,"int 25 called but not as diskdetection"); + } + return CBRET_NONE; +} +static Bitu DOS_26Handler(void) { + LOG(LOG_DOSMISC,"int 26 called: hope for the best!"); + if(Drives[reg_al]==0){ + reg_ax=0x8002; + CALLBACK_SCF(true); + }else{ + CALLBACK_SCF(false); + reg_ax=0; + } + return CBRET_NONE; +} static Bitu DOS_28Handler(void) { return CBRET_NONE; } @@ -885,6 +907,14 @@ void DOS_Init(Section* sec) { CALLBACK_Setup(call_21,DOS_21Handler,CB_IRET_STI); RealSetVec(0x21,CALLBACK_RealPointer(call_21)); + call_25=CALLBACK_Allocate(); + CALLBACK_Setup(call_25,DOS_25Handler,CB_RETF); + RealSetVec(0x25,CALLBACK_RealPointer(call_25)); + + call_26=CALLBACK_Allocate(); + CALLBACK_Setup(call_26,DOS_21Handler,CB_RETF); + RealSetVec(0x26,CALLBACK_RealPointer(call_26)); + call_27=CALLBACK_Allocate(); CALLBACK_Setup(call_27,DOS_27Handler,CB_IRET); RealSetVec(0x27,CALLBACK_RealPointer(call_27)); @@ -919,5 +949,7 @@ void DOS_Init(Section* sec) { /* shutdown function */ sec->AddDestroyFunction(&DOS_ShutDown); + + } From 86e2edd0ff25fe75e2e5743cb940c865a5f4e30d Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 5 Mar 2003 09:24:21 +0000 Subject: [PATCH 0630/4131] fixed bug in DOS_PSP::SetNumFiles Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@709 --- src/dos/dos_classes.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 97ee3ca3..00b7cc71 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -209,15 +209,17 @@ void DOS_PSP::SetFCB2(RealPt src) bool DOS_PSP::SetNumFiles(Bit16u fileNum) { - // Allocate needed paragraphs - Bit16u para = (fileNum/16)+((fileNum%16)>0); - RealPt data = RealMake(DOS_GetMemory(para),0); - sSave(sPSP,file_table,data); - sSave(sPSP,max_files,fileNum); if (fileNum>20) { + // Allocate needed paragraphs + Bit16u para = (fileNum/16)+((fileNum%16)>0); + RealPt data = RealMake(DOS_GetMemory(para),0); + sSave(sPSP,file_table,data); + sSave(sPSP,max_files,fileNum); Bit16u i; - for (i=0; i<20; i++) SetFileHandle(i,sGet(sPSP,files[i])); + for (i=0; i<20; i++) SetFileHandle(i,sGet(sPSP,files[i])); for (i=20; i Date: Thu, 6 Mar 2003 12:03:41 +0000 Subject: [PATCH 0631/4131] added .cvsignore from patch from Max Horn Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@710 From 8a9867ef928da79aec05bd6dae4577000c6a184a Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 6 Mar 2003 13:18:49 +0000 Subject: [PATCH 0632/4131] Startup function for mscdex Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@711 --- src/dosbox.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index f6870d91..b6108374 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -74,14 +74,14 @@ void TANDYSOUND_Init(Section*); void CMS_Init(Section*); void DISNEY_Init(Section*); - - void PIC_Init(Section*); void TIMER_Init(Section*); void BIOS_Init(Section*); void DEBUG_Init(Section*); void CMOS_Init(Section*); +void MSCDEX_Init(Section*); + /* Dos Internal mostly */ void EMS_Init(Section*); void XMS_Init(Section*); @@ -228,6 +228,9 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&XMS_Init); secprop->Add_int("xmssize",8); + // Mscdex + secprop->AddInitFunction(&MSCDEX_Init); + secline=control->AddSection_line("autoexec",&AUTOEXEC_Init); control->SetStartUp(&SHELL_Init); From d70b9f3c68a8736d1e589fae83f0bb18e650088d Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 6 Mar 2003 13:20:09 +0000 Subject: [PATCH 0633/4131] Add mount command for cdroms : mount [drive[ [cdrom]:\ -t cdrom [-aspi] Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@712 --- src/dos/dos_programs.cpp | 50 ++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 567fd78d..a3a5f366 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -27,6 +27,9 @@ #include "callback.h" #include "../shell/shell_inc.h" +void MSCDEX_SetUseASPI(bool use); +bool MSCDEX_GetUseASPI(void); + class MOUNT : public Program { public: void Run(void) @@ -45,8 +48,15 @@ public: return; } std::string type="dir"; + + // get the drive letter + cmd->FindCommand(1,temp_line); + if (temp_line.size()>1) goto showusage; + drive=toupper(temp_line[0]); + if (!isalpha(drive)) goto showusage; + cmd->FindString("-t",type,true); - if (type=="floppy" || type=="dir") { + if (type=="floppy" || type=="dir" || type=="cdrom") { Bit16u sizes[4]; Bit8u mediaid; std::string str_size; @@ -58,6 +68,10 @@ public: str_size="512,127,16513,1700"; mediaid=0xF8; /* Hard Disk */ } + if (type=="cdrom") { + str_size="650,127,16513,1700"; + mediaid=0xF8; /* Hard Disk */ + } cmd->FindString("-size",str_size,true); char number[20];const char * scan=str_size.c_str(); Bitu index=0;Bitu count=0; @@ -86,14 +100,29 @@ public: } if (temp_line[temp_line.size()-1]!=CROSS_FILESPLIT) temp_line+=CROSS_FILESPLIT; Bit8u bit8size=(Bit8u) sizes[1]; - newdrive=new localDrive(temp_line.c_str(),sizes[0],bit8size,sizes[2],sizes[3],mediaid); + if (type=="cdrom") { + bool oldaspi = MSCDEX_GetUseASPI();; + int error; + if (cmd->FindExist("-aspi",false)) MSCDEX_SetUseASPI(true); + newdrive = new cdromDrive(drive,temp_line.c_str(),sizes[0],bit8size,sizes[2],sizes[3],mediaid,error); + // Check Mscdex, if it worked out... + switch (error) { + case 0 : WriteOut(MSG_Get("MSCDEX_SUCCESS")); break; + case 1 : WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS")); break; + case 2 : WriteOut(MSG_Get("MSCDEX_ERROR_NOT_SUPPORTED")); break; + case 3 : WriteOut(MSG_Get("MSCDEX_ERROR_PATH")); break; + case 4 : WriteOut(MSG_Get("MSCDEX_TOO_MANY_DRIVES")); break; + case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break; + default : WriteOut(MSG_Get("MSCDEX_UNKNOWN_ERROR")); break; + }; + MSCDEX_SetUseASPI(oldaspi); + + } else { + newdrive=new localDrive(temp_line.c_str(),sizes[0],bit8size,sizes[2],sizes[3],mediaid); + } } - cmd->FindCommand(1,temp_line); - if (temp_line.size()>1) goto showusage; - drive=toupper(temp_line[0]); - if (!isalpha(drive)) goto showusage; if (Drives[drive-'A']) { - WriteOut(MSG_Get("PROGRAM_MOUNT_ALLREADY_MOUNDTED"),drive,Drives[drive-'A']->GetInfo()); + WriteOut(MSG_Get("PROGRAM_MOUNT_ALLREADY_MOUNTED"),drive,Drives[drive-'A']->GetInfo()); if (newdrive) delete newdrive; return; } @@ -231,6 +260,13 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_LOADFIX_DEALLOCALL","Used memory freed.\n"); MSG_Add("PROGRAM_LOADFIX_ERROR","Memory allocation error.\n"); + MSG_Add("MSCDEX_SUCCESS","MSCDEX installed.\n"); + MSG_Add("MSCDEX_ERROR_MULTIPLE_CDROMS","MSCDEX: Failure: Drive-letters of multiple CDRom-drives have to be continuous.\n"); + MSG_Add("MSCDEX_ERROR_NOT_SUPPORTED","MSCDEX: Failure: Not yet supported.\n"); + MSG_Add("MSCDEX_ERROR_PATH","MSCDEX: Failure: Path not valid (WIN32: Check if ASPI Driver is installed).\n"); + MSG_Add("MSCDEX_TOO_MANY_DRIVES","MSCDEX: Failure: Too many CDRom-drives (max: 5). MSCDEX Installation failed.\n"); + MSG_Add("MSCDEX_LIMITED_SUPPORT","MSCDEX: Mounted subdirectory: limited support.\n"); + MSG_Add("MSCDEX_UNKNOWN_ERROR","MSCDEX: Failure: Unknown error.\n"); /*regular setup*/ PROGRAMS_MakeFile("MOUNT.COM",MOUNT_ProgramStart); From c2f4f360ca108ae9bbf3d5a7f04ffac9bbd393d4 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 6 Mar 2003 13:20:31 +0000 Subject: [PATCH 0634/4131] Added EmptyCache, removed some warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@713 --- src/dos/drive_cache.cpp | 22 ++++++++++-- src/dos/drive_local.cpp | 75 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 4 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index b9f86dfb..820e6925 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -73,11 +73,27 @@ DOS_Drive_Cache::DOS_Drive_Cache(const char* path) }; DOS_Drive_Cache::~DOS_Drive_Cache(void) +{ + Clear(); +}; + +void DOS_Drive_Cache::Clear(void) { delete dirBase; dirBase = 0; for (Bit32u i=0; ioutputList.begin(), dir->outputList.end(), SortByDirName); break; case ALPHABETICALREV : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByNameRev); break; case DIRALPHABETICALREV : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByDirNameRev); break; + case NOSORT : break; }; Bit16s index = GetLongName(dir,file); @@ -221,7 +238,6 @@ bool DOS_Drive_Cache::GetShortName(const char* fullname, char* shortname) char expand[CROSS_LEN] = {0}; CFileInfo* curDir = FindDirInfo(fullname,expand); - Bit16s foundNr = 0; Bit16s low = 0; Bit16s high = curDir->longNameList.size()-1; Bit16s mid, res; @@ -288,7 +304,6 @@ bool DOS_Drive_Cache::RemoveSpaces(char* str) { char* curpos = str; char* chkpos = str; - Bit16s len = -1; while (*chkpos!=0) { if (*chkpos==' ') chkpos++; else *curpos++ = *chkpos++; } @@ -517,7 +532,7 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, struct dirent* &result) } // Read complete directory struct dirent* tmpres; - while (tmpres = readdir(dirp)) { + while ((tmpres = readdir(dirp))!=NULL) { CreateEntry(dirSearch[id],tmpres->d_name); // Sort Lists - filelist has to be alphabetically sorted, even in between (for finding double file names) // hmpf.. bit slow probably... @@ -531,6 +546,7 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, struct dirent* &result) case DIRALPHABETICAL : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByDirName); break; case ALPHABETICALREV : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByNameRev); break; case DIRALPHABETICALREV : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByDirNameRev); break; + case NOSORT : break; }; // Info /* if (!dirp) { diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index d02e39c7..65d18d5b 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -76,7 +76,7 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { dirCache.ExpandName(newname); FILE * hand=fopen(newname,type); - Bit32u err=errno; +// Bit32u err=errno; if (!hand) return false; *file=new localFile(name,hand,0x202); // (*file)->SetFileName(newname); @@ -382,4 +382,77 @@ localFile::localFile(const char* _name, FILE * handle,Bit16u devinfo) { SetName(_name); } +// ******************************************** +// CDROM DRIVE +// ******************************************** +int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit); +bool MSCDEX_HasMediaChanged(Bit8u subUnit); + +cdromDrive::cdromDrive(const char driveLetter, const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid, int& error) + :localDrive(startdir,_bytes_sector,_sectors_cluster,_total_clusters,_free_clusters,_mediaid) +{ + // Init mscdex + error = MSCDEX_AddDrive(driveLetter,startdir,subUnit); + strcpy(info,"CDRom."); +}; + +bool cdromDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) +{ + if ((flags==OPEN_READWRITE) || (flags==OPEN_WRITE)) { + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; + } + return localDrive::FileOpen(file,name,flags); +}; + +bool cdromDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) +{ + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; +}; + +bool cdromDrive::FileUnlink(char * name) +{ + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; +}; + +bool cdromDrive::RemoveDir(char * dir) +{ + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; +}; + +bool cdromDrive::MakeDir(char * dir) +{ + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; +}; + +bool cdromDrive::Rename(char * oldname,char * newname) +{ + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; +}; + +bool cdromDrive::GetFileAttr(char * name,Bit16u * attr) +{ + bool result = localDrive::GetFileAttr(name,attr); + if (result) *attr |= DOS_ATTR_READ_ONLY; + return result; +}; + +bool cdromDrive::FindFirst(char * _dir,DOS_DTA & dta) +{ + // If media has changed, reInit drivecache. + if (MSCDEX_HasMediaChanged(subUnit)) dirCache.EmptyCache(); + return localDrive::FindFirst(_dir,dta); +}; + +void cdromDrive::SetDir(const char* path) +{ + // If media has changed, reInit drivecache. + if (MSCDEX_HasMediaChanged(subUnit)) dirCache.EmptyCache(); + localDrive::SetDir(path); +}; From e304c3262b633de19398a53066c2931731f0f653 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 6 Mar 2003 13:21:04 +0000 Subject: [PATCH 0635/4131] new class cdromDrive Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@714 --- src/dos/drives.h | 56 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/src/dos/drives.h b/src/dos/drives.h index cdadcc9e..375e789e 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -50,6 +50,8 @@ public: void AddEntry (const char* path, bool checkExist = false); void DeleteEntry (const char* path, bool ignoreLastDir = false); + void EmptyCache (void); + class CFileInfo { public: ~CFileInfo(void) { @@ -82,6 +84,7 @@ private: bool OpenDir (CFileInfo* dir, char* path, Bit16u& id); void CreateEntry (CFileInfo* dir, const char* name); Bit16u GetFreeID (CFileInfo* dir); + void Clear (void); CFileInfo* dirBase; @@ -124,6 +127,8 @@ public: void SetCurrentEntry (Bit16u entry) {}; Bit16u GetCurrentEntry (void) { return 0; }; + void EmptyCache (void) {}; + public: char basePath [CROSS_LEN]; char dirPath [CROSS_LEN]; @@ -133,21 +138,23 @@ public: class localDrive : public DOS_Drive { public: localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid); - bool FileOpen(DOS_File * * file,char * name,Bit32u flags); - bool FileCreate(DOS_File * * file,char * name,Bit16u attributes); - bool FileUnlink(char * name); - bool RemoveDir(char * dir); - bool MakeDir(char * dir); - bool TestDir(char * dir); - bool FindFirst(char * _dir,DOS_DTA & dta); - bool FindNext(DOS_DTA & dta); - bool GetFileAttr(char * name,Bit16u * attr); - bool Rename(char * oldname,char * newname); - bool AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters); - bool FileExists(const char* name); - bool FileStat(const char* name, FileStat_Block * const stat_block); - Bit8u GetMediaByte(void); - bool GetShortName(const char* fullname, char* shortname) { return dirCache.GetShortName(fullname, shortname); }; + virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags); + virtual bool FileCreate(DOS_File * * file,char * name,Bit16u attributes); + virtual bool FileUnlink(char * name); + virtual bool RemoveDir(char * dir); + virtual bool MakeDir(char * dir); + virtual bool TestDir(char * dir); + virtual bool FindFirst(char * _dir,DOS_DTA & dta); + virtual bool FindNext(DOS_DTA & dta); + virtual bool GetFileAttr(char * name,Bit16u * attr); + virtual bool Rename(char * oldname,char * newname); + virtual bool AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters); + virtual bool FileExists(const char* name); + virtual bool FileStat(const char* name, FileStat_Block * const stat_block); + virtual Bit8u GetMediaByte(void); + + DOS_Drive_Cache dirCache; + private: char basedir[CROSS_LEN]; @@ -162,12 +169,27 @@ private: Bit16u free_clusters; Bit8u mediaid; } allocation; - DOS_Drive_Cache dirCache; +}; + +class cdromDrive : public localDrive +{ +public: + cdromDrive(const char driveLetter, const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid, int& error); + virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags); + virtual bool FileCreate(DOS_File * * file,char * name,Bit16u attributes); + virtual bool FileUnlink(char * name); + virtual bool RemoveDir(char * dir); + virtual bool MakeDir(char * dir); + virtual bool Rename(char * oldname,char * newname); + virtual bool GetFileAttr(char * name,Bit16u * attr); + virtual bool FindFirst(char * _dir,DOS_DTA & dta); + virtual void SetDir(const char* path); +private: + Bit8u subUnit; }; struct VFILE_Block; - class Virtual_Drive: public DOS_Drive { public: Virtual_Drive(); From b7b02ce8a4bd6b30b3fa3b0dd2e729fac6b62fae Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 6 Mar 2003 13:27:24 +0000 Subject: [PATCH 0636/4131] fixed a warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@715 --- src/shell/shell_misc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 63a4516d..2712a5fb 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -61,7 +61,7 @@ void DOS_Shell::InputCommand(char * line) { case 0x3d: /* F3 */ if (strlen(old.buffer)>str_len) { reader=&old.buffer[str_len]; - while (c=*reader++) { + while ((c=*reader++)) { line[str_index]=c; str_len++; str_index++; From d4af8d888921ff02dabbc590e5ffac6b9329e3d0 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 6 Mar 2003 13:33:07 +0000 Subject: [PATCH 0637/4131] added cdrom.h/cpp + mscdex.cpp + special win headers aspi + ioctl Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@716 --- visualc/dosbox.dsp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index e6fa1064..31e450aa 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -20,7 +20,6 @@ CFG=dosbox - Win32 Debug !MESSAGE "dosbox - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "dosbox - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE - # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" @@ -223,6 +222,18 @@ SOURCE=..\src\dos\drives.h # End Group # Begin Source File +SOURCE=..\src\dos\cdrom.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\dos\cdrom.h +# End Source File +# Begin Source File + +SOURCE=..\src\dos\cdrom_ioctl.cpp +# End Source File +# Begin Source File + SOURCE=..\src\dos\dos.cpp # End Source File # Begin Source File @@ -255,12 +266,24 @@ SOURCE=..\src\dos\dos_misc.cpp # End Source File # Begin Source File +SOURCE=..\src\dos\dos_mscdex.cpp +# End Source File +# Begin Source File + SOURCE=..\src\dos\dos_programs.cpp # End Source File # Begin Source File SOURCE=..\src\dos\dos_tables.cpp # End Source File +# Begin Source File + +SOURCE=..\src\dos\scsidefs.h +# End Source File +# Begin Source File + +SOURCE=..\src\dos\wnaspi32.h +# End Source File # End Group # Begin Group "gui" From cfd4de316eadd1e4ee496af7d588dd9459bb2aad Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 6 Mar 2003 13:34:27 +0000 Subject: [PATCH 0638/4131] cdrom interfaces Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@717 --- src/dos/cdrom.cpp | 773 ++++++++++++++++++++++++++++++++++++++++ src/dos/cdrom.h | 179 ++++++++++ src/dos/cdrom_ioctl.cpp | 431 ++++++++++++++++++++++ 3 files changed, 1383 insertions(+) create mode 100644 src/dos/cdrom.cpp create mode 100644 src/dos/cdrom.h create mode 100644 src/dos/cdrom_ioctl.cpp diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp new file mode 100644 index 00000000..6e1ba761 --- /dev/null +++ b/src/dos/cdrom.cpp @@ -0,0 +1,773 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +// ASPI support for WIN32 CDROM + +#ifdef WIN32 + +#include +#include "cdrom.h" +#include "scsidefs.h" // Aspi stuff + +#include "dosbox.h" + +CDROM_Interface_Aspi::CDROM_Interface_Aspi(void) +{ + hASPI = NULL; + hEvent = NULL; + pGetASPI32SupportInfo = NULL; + pSendASPI32Command = NULL; +}; + +CDROM_Interface_Aspi::~CDROM_Interface_Aspi(void) +{ + // Stop Audio + StopAudio(); + + pGetASPI32SupportInfo = NULL; // clear funcs + pSendASPI32Command = NULL; + + if (hASPI) { // free aspi + FreeLibrary(hASPI); + hASPI=NULL; + } +}; + +bool GetRegistryValue(HKEY& hKey,char* valueName, char* buffer, ULONG bufferSize) +// hKey has to be open +{ + // Read subkey + ULONG valType; + ULONG result; + result = RegQueryValueEx(hKey,valueName,NULL,&valType,(unsigned char*)&buffer[0],&bufferSize); + return (result == ERROR_SUCCESS); +}; + +BYTE CDROM_Interface_Aspi::GetHostAdapter(void) +{ + SRB_ExecSCSICmd s;DWORD dwStatus; + BYTE buffer[40]; + + for (int i=0; i<255; i++) { + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + memset(&s,0,sizeof(s)); + // Check Media test... + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = i; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_SenseLen = SENSE_LEN; + s.SRB_BufLen = 40; + s.SRB_BufPointer = (BYTE FAR*)buffer; + s.SRB_CDBLen = 14; + s.SRB_PostProc = (LPVOID)hEvent; + s.CDBByte[0] = 0x4A; + s.CDBByte[1] = (lun<<5)|1; // lun & immediate + s.CDBByte[4] = 0x10; // media + s.CDBByte[8] = 40; + ResetEvent(hEvent); + dwStatus = pSendASPI32Command((LPSRB)&s); + if ((dwStatus==0) && (s.SRB_Status!=SS_INVALID_CMD)) { + DEBUG_ShowMsg(0,"SCSI: Host Adapter found: %d",i); + return i; + }; + }; + DEBUG_ShowMsg(0,"SCSI: Host Adapter not found."); + return 0; +}; + +bool CDROM_Interface_Aspi::ScanRegistryFindKey(HKEY& hKeyBase) +// hKey has to be open +{ + FILETIME time; + ULONG result,newKeyResult; + char subKey[256]; + char buffer[256]; + ULONG bufferSize = 256; + ULONG subKeySize = 256; + HKEY hNewKey; + + ULONG index = 0; + do { + result = RegEnumKeyEx (hKeyBase,index,&subKey[0],&subKeySize,NULL,NULL,0,&time); + if (result==ERROR_SUCCESS) { + // Open Key... + newKeyResult = RegOpenKeyEx (hKeyBase,subKey,0,KEY_READ,&hNewKey); + if (newKeyResult==ERROR_SUCCESS) { + if (GetRegistryValue(hNewKey,"CurrentDriveLetterAssignment",buffer,256)) { + DEBUG_ShowMsg(0,"SCSI: Drive Letter found: %s",buffer); + // aha, something suspicious... + if (buffer[0]==letter) { + // found it... lets see if we can get the scsi values + bool v1 = GetRegistryValue(hNewKey,"SCSILUN",buffer,256); + DEBUG_ShowMsg(0,"SCSI: SCSILUN found: %s",buffer); + lun = buffer[0]-'0'; + bool v2 = GetRegistryValue(hNewKey,"SCSITargetID",buffer,256); + DEBUG_ShowMsg(0,"SCSI: SCSITargetID found: %s",buffer); + target = buffer[0]-'0'; + RegCloseKey(hNewKey); + if (v1 && v2) { + haId = GetHostAdapter(); + return true; + }; + } + }; + }; + RegCloseKey(hNewKey); + }; + index++; + } while ((result==ERROR_SUCCESS) || (result==ERROR_MORE_DATA)); + return false; +}; + +bool CDROM_Interface_Aspi::ScanRegistry(HKEY& hKeyBase) +// hKey has to be open +{ + FILETIME time; + ULONG result,newKeyResult; + char subKey[256]; + ULONG subKeySize= 256; + HKEY hNewKey; + + ULONG index = 0; + do { + result = RegEnumKeyEx (hKeyBase,index,&subKey[0],&subKeySize,NULL,NULL,0,&time); + if ((result==ERROR_SUCCESS) || (result==ERROR_MORE_DATA)) { + // Open Key... + newKeyResult = RegOpenKeyEx (hKeyBase,subKey,0,KEY_READ,&hNewKey); + if (newKeyResult==ERROR_SUCCESS) { + bool found = ScanRegistryFindKey(hNewKey); + RegCloseKey(hNewKey); + if (found) return true; + }; + RegCloseKey(hNewKey); + }; + index++; + } while ((result==ERROR_SUCCESS) || (result==ERROR_MORE_DATA)); + return false; +}; + +bool CDROM_Interface_Aspi::SetDevice(char* path) +{ + // load WNASPI32.DLL + hASPI = LoadLibrary ( "WNASPI32.DLL" ); + if (!hASPI) return false; + // Get Pointer to ASPI funcs + pGetASPI32SupportInfo = (DWORD(*)(void))GetProcAddress(hASPI,"GetASPI32SupportInfo"); + pSendASPI32Command = (DWORD(*)(LPSRB))GetProcAddress(hASPI,"SendASPI32Command"); + if (!pGetASPI32SupportInfo || !pSendASPI32Command) return false; + // Letter + letter = toupper(path[0]); + + // Check OS + OSVERSIONINFO osi; + osi.dwOSVersionInfoSize = sizeof(osi); + GetVersionEx(&osi); + if ((osi.dwPlatformId==VER_PLATFORM_WIN32_NT) && (osi.dwMajorVersion>4)) { + if (GetDriveType(path)==DRIVE_CDROM) { + // WIN XP/NT/2000 + int iDA,iDT,iDL; + letter = path[0]; + HANDLE hF = OpenIOCTLFile(letter,FALSE); + GetIOCTLAdapter(hF,&iDA,&iDT,&iDL); + CloseHandle(hF); + // Set SCSI IDs + haId = iDA; + target = iDT; + lun = iDL; + return true; + } + } else { + // win 95/98/ME have to scan the registry... + // lets hope the layout is always the same... i dunno... + char key[2048]; + HKEY hKeyBase; + bool found = false; + strcpy(key,"ENUM\\SCSI"); + if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,key,0,KEY_READ,&hKeyBase)==ERROR_SUCCESS) { + found = ScanRegistry(hKeyBase); + }; + RegCloseKey(hKeyBase); + return found; + } + return false; +}; + +bool CDROM_Interface_Aspi::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut) +{ + TOC toc; + if (GetTOC((LPTOC)&toc) == SS_COMP) { + stTrack = toc.cFirstTrack; + endTrack = toc.cLastTrack; + leadOut.min = (unsigned char)(toc.tracks[endTrack].lAddr >> 8) &0xFF; + leadOut.sec = (unsigned char)(toc.tracks[endTrack].lAddr >> 16) &0xFF; + leadOut.fr = (unsigned char)(toc.tracks[endTrack].lAddr >> 24) &0xFF; + return true; + } + return false; +}; + +bool CDROM_Interface_Aspi::GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr) +{ + TOC toc; + if (GetTOC((LPTOC)&toc) == SS_COMP) { + start.min = (unsigned char)(toc.tracks[track-1].lAddr >> 8) &0xFF; + start.sec = (unsigned char)(toc.tracks[track-1].lAddr >> 16) &0xFF; + start.fr = (unsigned char)(toc.tracks[track-1].lAddr >> 24) &0xFF; + attr = toc.tracks[track-1].cAdrCtrl; + return true; + }; + return false; +}; + +HANDLE CDROM_Interface_Aspi::OpenIOCTLFile(char cLetter,BOOL bAsync) +{ + HANDLE hF; + char szFName[16]; + OSVERSIONINFO ov; + DWORD dwFlags; + DWORD dwIOCTLAttr; +// if(bAsync) dwIOCTLAttr=FILE_FLAG_OVERLAPPED; +// else + dwIOCTLAttr=0; + + memset(&ov,0,sizeof(OSVERSIONINFO)); + ov.dwOSVersionInfoSize=sizeof(OSVERSIONINFO); + GetVersionEx(&ov); + + if ((ov.dwPlatformId==VER_PLATFORM_WIN32_NT) && (ov.dwMajorVersion>4)) + dwFlags = GENERIC_READ|GENERIC_WRITE; // add gen write on W2k/XP + else + dwFlags = GENERIC_READ; + + wsprintf(szFName, "\\\\.\\%c:",cLetter); + + hF=CreateFile(szFName,dwFlags,FILE_SHARE_READ, // open drive + NULL,OPEN_EXISTING,dwIOCTLAttr,NULL); + + if (hF==INVALID_HANDLE_VALUE) { + dwFlags^=GENERIC_WRITE; // mmm... no success + hF=CreateFile(szFName,dwFlags,FILE_SHARE_READ, // -> open drive again + NULL,OPEN_EXISTING,dwIOCTLAttr,NULL); + if (hF==INVALID_HANDLE_VALUE) return NULL; + } + return hF; +} + +void CDROM_Interface_Aspi::GetIOCTLAdapter(HANDLE hF,int * iDA,int * iDT,int * iDL) +{ + char szBuf[1024]; + PSCSI_ADDRESS pSA; + DWORD dwRet; + + *iDA=*iDT=*iDL=-1; + if(hF==NULL) return; + + memset(szBuf,0,1024); + + pSA=(PSCSI_ADDRESS)szBuf; + pSA->Length=sizeof(SCSI_ADDRESS); + + if(!DeviceIoControl(hF,IOCTL_SCSI_GET_ADDRESS,NULL, + 0,pSA,sizeof(SCSI_ADDRESS), + &dwRet,NULL)) + return; + + *iDA = pSA->PortNumber; + *iDT = pSA->TargetId; + *iDL = pSA->Lun; +} + +DWORD CDROM_Interface_Aspi::GetTOC(LPTOC toc) +{ + SRB_ExecSCSICmd s;DWORD dwStatus; + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + memset(&s,0,sizeof(s)); + + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = haId; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_BufLen = sizeof(*toc); + s.SRB_BufPointer = (BYTE FAR *)toc; + s.SRB_SenseLen = SENSE_LEN; + s.SRB_CDBLen = 0x0A; + s.SRB_PostProc = (LPVOID)hEvent; + s.CDBByte[0] = 0x43; + s.CDBByte[1] = 0x02; // 0x02 for MSF + s.CDBByte[7] = 0x03; + s.CDBByte[8] = 0x24; + + ResetEvent(hEvent); + dwStatus=pSendASPI32Command((LPSRB)&s); + + if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,30000); + + return (s.SRB_Status==SS_COMP); +} + +bool CDROM_Interface_Aspi::PlayAudioSector(unsigned long start,unsigned long len) +{ + SRB_ExecSCSICmd s;DWORD dwStatus; + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + memset(&s,0,sizeof(s)); + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = haId; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_BufLen = 0; + s.SRB_BufPointer = 0; + s.SRB_SenseLen = SENSE_LEN; + s.SRB_CDBLen = 12; + s.SRB_PostProc = (LPVOID)hEvent; + + s.CDBByte[0] = 0xa5; + s.CDBByte[1] = lun << 5; + s.CDBByte[2] = (unsigned char)((start >> 24) & 0xFF); + s.CDBByte[3] = (unsigned char)((start >> 16) & 0xFF); + s.CDBByte[4] = (unsigned char)((start >> 8) & 0xFF); + s.CDBByte[5] = (unsigned char)((start & 0xFF)); + s.CDBByte[6] = (unsigned char)((len >> 24) & 0xFF); + s.CDBByte[7] = (unsigned char)((len >> 16) & 0xFF); + s.CDBByte[8] = (unsigned char)((len >> 8) & 0xFF); + s.CDBByte[9] = (unsigned char)(len & 0xFF); + + ResetEvent(hEvent); + + dwStatus = pSendASPI32Command((LPSRB)&s); + + if(dwStatus==SS_PENDING) WaitForSingleObject(hEvent,10000); + + return s.SRB_Status==SS_COMP; +} + +bool CDROM_Interface_Aspi::StopAudio(void) +{ + SRB_ExecSCSICmd s;DWORD dwStatus; + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + memset(&s,0,sizeof(s)); + + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = haId; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_BufLen = 0x00; + s.SRB_SenseLen = 0x0E; + s.SRB_CDBLen = 0x0A; + s.SRB_PostProc = (LPVOID)hEvent; + s.CDBByte[0] = 0x4E; + + ResetEvent(hEvent); + dwStatus=pSendASPI32Command((LPSRB)&s); + + if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,30000); + + if (s.SRB_Status!=SS_COMP) return false; + + return true; +}; + +bool CDROM_Interface_Aspi::PauseAudio(bool resume) +{ + SRB_ExecSCSICmd s;DWORD dwStatus; + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + memset(&s,0,sizeof(s)); + + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = haId; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_BufLen = 0x00; + s.SRB_SenseLen = SENSE_LEN; + s.SRB_CDBLen = 0x0A; + s.SRB_PostProc = (LPVOID)hEvent; + s.CDBByte[0] = 0x4B; + s.CDBByte[8] = (unsigned char)resume; // Pause + + ResetEvent(hEvent); + dwStatus=pSendASPI32Command((LPSRB)&s); + + if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,30000); + + if (s.SRB_Status!=SS_COMP) return false; + + return true; +}; + +bool CDROM_Interface_Aspi::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) +{ + SUB_Q_CURRENT_POSITION pos; + SRB_ExecSCSICmd s;DWORD dwStatus; + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + memset(&s,0,sizeof(s)); + + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = haId; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_SenseLen = SENSE_LEN; + + s.SRB_BufLen = sizeof(pos); + s.SRB_BufPointer = (BYTE FAR *)&pos; + s.SRB_CDBLen = 10; + s.SRB_PostProc = (LPVOID)hEvent; + + s.CDBByte[0] = 0x42; + s.CDBByte[1] = (lun<<5)|2; // lun & msf + s.CDBByte[2] = 0x40; // subq + s.CDBByte[3] = 0x01; // curr pos info + s.CDBByte[6] = 0; // track number (only in isrc mode, ignored) + s.CDBByte[7] = 0; // alloc len + s.CDBByte[8] = sizeof(pos); + + ResetEvent(hEvent); + + dwStatus = pSendASPI32Command((LPSRB)&s); + + if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); + + if (s.SRB_Status!=SS_COMP) return false; + + attr = (pos.ADR<<4) | pos.Control; + track = pos.TrackNumber; + index = pos.IndexNumber; + absPos.min = pos.AbsoluteAddress[1]; + absPos.sec = pos.AbsoluteAddress[2]; + absPos.fr = pos.AbsoluteAddress[3]; + relPos.min = pos.TrackRelativeAddress[1]; + relPos.sec = pos.TrackRelativeAddress[2]; + relPos.fr = pos.TrackRelativeAddress[3]; + + return true; +}; + +bool CDROM_Interface_Aspi::GetUPC(unsigned char& attr, char* upcdata) +{ + SUB_Q_MEDIA_CATALOG_NUMBER upc; + SRB_ExecSCSICmd s;DWORD dwStatus; + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + memset(&s,0,sizeof(s)); + + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = haId; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_SenseLen = SENSE_LEN; + + s.SRB_BufLen = sizeof(upc); + s.SRB_BufPointer = (BYTE FAR *)&upc; + s.SRB_CDBLen = 10; + s.SRB_PostProc = (LPVOID)hEvent; + + s.CDBByte[0] = 0x42; + s.CDBByte[1] = (lun<<5)|2; // lun & msf + s.CDBByte[2] = 0x40; // subq + s.CDBByte[3] = 0x02; // get upc + s.CDBByte[6] = 0; // track number (only in isrc mode, ignored) + s.CDBByte[7] = 0; // alloc len + s.CDBByte[8] = sizeof(upc); + + ResetEvent(hEvent); + + dwStatus = pSendASPI32Command((LPSRB)&s); + + if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); + + if (s.SRB_Status!=SS_COMP) return false; + +// attr = (upc.ADR<<4) | upc.Control; + attr = 0; + int pos = 0; + // Convert to mscdex format +// for (int i=0; i<6; i++) upcdata[i] = (upc.MediaCatalog[pos++]<<4)+(upc.MediaCatalog[pos++]&0x0F); +// upcdata[6] = (upc.MediaCatalog[pos++]<<4); + for (int i=0; i<7; i++) upcdata[i] = upc.MediaCatalog[i]; + + return true; +}; + +bool CDROM_Interface_Aspi::GetAudioStatus(bool& playing, bool& pause) +{ + playing = pause = false; + + SUB_Q_HEADER sub; + SRB_ExecSCSICmd s;DWORD dwStatus; + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + memset(&s,0,sizeof(s)); + + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = haId; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_SenseLen = SENSE_LEN; + + s.SRB_BufLen = sizeof(sub); + s.SRB_BufPointer = (BYTE FAR *)⊂ + s.SRB_CDBLen = 10; + s.SRB_PostProc = (LPVOID)hEvent; + + s.CDBByte[0] = 0x42; + s.CDBByte[1] = (lun<<5)|2; // lun & msf + s.CDBByte[2] = 0x00; // no subq + s.CDBByte[3] = 0x00; // dont care + s.CDBByte[6] = 0; // track number (only in isrc mode, ignored) + s.CDBByte[7] = 0; // alloc len + s.CDBByte[8] = sizeof(sub); + + ResetEvent(hEvent); + + dwStatus = pSendASPI32Command((LPSRB)&s); + + if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); + + if (s.SRB_Status!=SS_COMP) return false; + + playing = (sub.AudioStatus==0x11); + pause = (sub.AudioStatus==0x12); + + return true; +}; + +bool CDROM_Interface_Aspi::LoadUnloadMedia(bool unload) +{ + SRB_ExecSCSICmd s;DWORD dwStatus; + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + memset(&s,0,sizeof(s)); + + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = haId; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_SenseLen = SENSE_LEN; + + s.SRB_BufLen = 0; + s.SRB_BufPointer = 0; + s.SRB_CDBLen = 14; + s.SRB_PostProc = (LPVOID)hEvent; + + s.CDBByte[0] = 0x1B; + s.CDBByte[1] = (lun<<5)|1; // lun & immediate + s.CDBByte[4] = (unload ? 0x02:0x03); // unload/load media + + ResetEvent(hEvent); + + dwStatus = pSendASPI32Command((LPSRB)&s); + + if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); + + if (s.SRB_Status!=SS_COMP) return false; + + return true; +}; + +bool CDROM_Interface_Aspi::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) +{ + mediaPresent = mediaChanged = trayOpen = false; + + SRB_ExecSCSICmd s;DWORD dwStatus; + BYTE buffer[40]; + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + memset(&s,0,sizeof(s)); + + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = haId; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_SenseLen = SENSE_LEN; + + s.SRB_BufLen = 40; + s.SRB_BufPointer = (BYTE FAR*)buffer; + s.SRB_CDBLen = 14; + s.SRB_PostProc = (LPVOID)hEvent; + + s.CDBByte[0] = 0x4A; + s.CDBByte[1] = (lun<<5)|1; // lun & immediate + s.CDBByte[4] = 0x10; // media + s.CDBByte[8] = 40; + + ResetEvent(hEvent); + + dwStatus = pSendASPI32Command((LPSRB)&s); + + if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); + + if (s.SRB_Status!=SS_COMP) return false; + + mediaChanged = (buffer[0x04]== 0x04); + mediaPresent = (buffer[0x05] & 0x02)>0; + trayOpen = (buffer[0x05] & 0x01)>0; + + return true; +}; + +bool CDROM_Interface_Aspi::ReadSectors(void* buffer, bool raw, unsigned long sector, unsigned long num) +{ + SRB_ExecSCSICmd s;DWORD dwStatus; + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + memset(&s,0,sizeof(s)); + + // FIXME : Is there a method to get cooked sectors with aspi ??? + // all combination i tried were failing. + // so we have to allocate extra mem and copy data to buffer if in cooked mode + char* inPtr = (char*)buffer; + if (!raw) inPtr = new char[num*2352]; + if (!inPtr) return false; + + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = haId; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_SenseLen = SENSE_LEN; + + s.SRB_BufLen = 2352*num; //num*(raw?2352:2048); + s.SRB_BufPointer = (BYTE FAR*)inPtr; + s.SRB_CDBLen = 12; + s.SRB_PostProc = (LPVOID)hEvent; + + s.CDBByte[0] = 0xBE; + s.CDBByte[2] = (unsigned char)((sector >> 24) & 0xFF); + s.CDBByte[3] = (unsigned char)((sector >> 16) & 0xFF); + s.CDBByte[4] = (unsigned char)((sector >> 8) & 0xFF); + s.CDBByte[5] = (unsigned char)((sector & 0xFF)); + s.CDBByte[6] = (unsigned char)((num >> 16) & 0xFF); + s.CDBByte[7] = (unsigned char)((num >> 8) & 0xFF); + s.CDBByte[8] = (unsigned char) (num & 0xFF); + s.CDBByte[9] = (raw?0xF0:0x10); + + ResetEvent(hEvent); + + dwStatus = pSendASPI32Command((LPSRB)&s); + + if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); + + if (s.SRB_Status!=SS_COMP) { + if (!raw) delete[] inPtr; + return false; + } + + if (!raw) { + // copy user data to buffer + char* source = inPtr; + source+=16; // jump 16 bytes + char* outPtr = (char*)buffer; + for (unsigned long i=0; i1) return false; + start.min = start.fr = 0; + start.sec = 2; + attr = 0x60; // data / permitted + return true; +}; + +bool CDROM_Interface_Fake :: GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) +{ + attr = 0; + track = index = 1; + relPos.min = relPos.fr = 0; relPos.sec = 2; + absPos.min = absPos.fr = 0; absPos.sec = 2; + return true; +} + +bool CDROM_Interface_Fake :: GetAudioStatus (bool& playing, bool& pause) +{ + playing = pause = false; + return true; +} + +bool CDROM_Interface_Fake :: GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) +{ + mediaPresent = true; + mediaChanged = false; + trayOpen = false; + return true; +}; + + diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h new file mode 100644 index 00000000..306dad7d --- /dev/null +++ b/src/dos/cdrom.h @@ -0,0 +1,179 @@ + +#ifndef __CDROM_INTERFACE__ +#define __CDROM_INTERFACE__ + +#define MAX_ASPI_CDROM 5 + +#include + +#define RAW_SECTOR_SIZE 2352 +#define COOKED_SECTOR_SIZE 2048 + +typedef struct SMSF { + unsigned char min; + unsigned char sec; + unsigned char fr; +} TMSF; + +extern int CDROM_GetMountType(char* path); + +class CDROM_Interface +{ +public: +// CDROM_Interface (void); + virtual ~CDROM_Interface (void) {}; + + virtual bool SetDevice (char* path) = 0; + + virtual bool GetUPC (unsigned char& attr, char* upc) = 0; + + virtual bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) = 0; + virtual bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr) = 0; + virtual bool GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) = 0; + virtual bool GetAudioStatus (bool& playing, bool& pause) = 0; + virtual bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) = 0; + + virtual bool PlayAudioSector (unsigned long start,unsigned long len) = 0; + virtual bool PauseAudio (bool resume) = 0; + virtual bool StopAudio (void) = 0; + + virtual bool ReadSectors (void* buffer, bool raw, unsigned long sector, unsigned long num) = 0; + + virtual bool LoadUnloadMedia (bool unload) = 0; +}; + +class CDROM_Interface_Fake : public CDROM_Interface +{ +public: + bool SetDevice (char* path) { return true; }; + bool GetUPC (unsigned char& attr, char* upc) { attr = 0; strcpy(upc,"UPC"); return true; }; + bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); + bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr); + bool GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); + bool GetAudioStatus (bool& playing, bool& pause); + bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); + bool PlayAudioSector (unsigned long start,unsigned long len) { return true; }; + bool PauseAudio (bool resume) { return true; }; + bool StopAudio (void) { return true; }; + bool ReadSectors (void* buffer, bool raw, unsigned long sector, unsigned long num) { return true; }; + bool LoadUnloadMedia (bool unload) { return true; }; +}; + + +#if defined (WIN32) /* Win 32 */ + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include +#include "wnaspi32.h" // Aspi stuff + +class CDROM_Interface_Aspi : public CDROM_Interface +{ +public: + CDROM_Interface_Aspi (void); + ~CDROM_Interface_Aspi (void); + + bool SetDevice (char* path); + + bool GetUPC (unsigned char& attr, char* upc); + + bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); + bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr); + bool GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); + bool GetAudioStatus (bool& playing, bool& pause); + bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); + + bool PlayAudioSector (unsigned long start,unsigned long len); + bool PauseAudio (bool resume); + bool StopAudio (void); + + bool ReadSectors (void* buffer, bool raw, unsigned long sector, unsigned long num); + + bool LoadUnloadMedia (bool unload); + +private: + DWORD GetTOC (LPTOC toc); + HANDLE OpenIOCTLFile (char cLetter, BOOL bAsync); + void GetIOCTLAdapter (HANDLE hF,int * iDA,int * iDT,int * iDL); + bool ScanRegistryFindKey (HKEY& hKeyBase); + bool ScanRegistry (HKEY& hKeyBase); + BYTE GetHostAdapter (void); + + // ASPI stuff + BYTE haId; + BYTE target; + BYTE lun; + char letter; + + // Windows stuff + HINSTANCE hASPI; + HANDLE hEvent; // global event + DWORD (*pGetASPI32SupportInfo) (void); // ptrs to aspi funcs + DWORD (*pSendASPI32Command) (LPSRB); +}; + +class CDROM_Interface_Ioctl : public CDROM_Interface +{ +public: + CDROM_Interface_Ioctl (void); + ~CDROM_Interface_Ioctl (void); + + bool SetDevice (char* path); + + bool GetUPC (unsigned char& attr, char* upc); + + bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); + bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr); + bool GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); + bool GetAudioStatus (bool& playing, bool& pause); + bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); + + bool PlayAudioSector (unsigned long start,unsigned long len); + bool PauseAudio (bool resume); + bool StopAudio (void); + + bool ReadSectors (void* buffer, bool raw, unsigned long sector, unsigned long num); + + bool LoadUnloadMedia (bool unload); + +private: + + HANDLE hIOCTL; + TMSF oldLeadOut; +}; + +#else /* Linux */ + +class CDROM_Interface_Linux : public CDROM_Interface +{ +public: + CDROM_Interface_Linux (void); + ~CDROM_Interface_Linux (void); + + bool SetDevice (char* path); + + bool GetUPC (unsigned char& attr, char* upc); + + bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); + bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr); + bool GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); + bool GetAudioStatus (bool& playing, bool& pause); + bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); + + bool PlayAudioSector (unsigned long start,unsigned long len); + bool PauseAudio (bool resume); + bool StopAudio (void); + + bool ReadSectors (void* buffer, bool raw, unsigned long sector, unsigned long num); + + bool LoadUnloadMedia (bool unload); + +private: + + int dhandle; + TMSF oldLeadOut; +}; + +#endif /* linux */ + +#endif /* __CDROM_INTERFACE__ */ \ No newline at end of file diff --git a/src/dos/cdrom_ioctl.cpp b/src/dos/cdrom_ioctl.cpp new file mode 100644 index 00000000..942dc9a7 --- /dev/null +++ b/src/dos/cdrom_ioctl.cpp @@ -0,0 +1,431 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +// IOCTL support for linux CDROM + +#if __linux__ + +#include +#include +#include +#include +#include + +#include "cdrom.h" + +CDROM_Interface_Linux::CDROM_Interface_Linux(void) +{ + memset(&oldLeadOut,0,sizeof(oldLeadOut)); +}; + +CDROM_Interface_Linux::~CDROM_Interface_Linux(void) +{ + // Stop Audio, if neccessary + StopAudio(); + close(dhandle); +}; + +bool CDROM_Interface_Linux::SetDevice(char* path) +{ + dhandle = open(path,O_RDONLY|O_NONBLOCK); + return (dhandle>=0); +}; + +bool CDROM_Interface_Linux::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut) +{ + struct cdrom_tochdr header; + + /* read the header information */ + if (ioctl(dhandle, CDROMREADTOCHDR, &header) != 0) return false; + + /* store the resulting information */ + stTrack = header.cdth_trk0; /* you can assume this to be zero */ + endTrack = header.cdth_trk1; + + /* Get the leadout track */ + struct cdrom_tocentry entry; + + entry.cdte_track = CDROM_LEADOUT; /* find the address of the leadout track */ + entry.cdte_format = CDROM_MSF; /* choose MSF addressing */ + + if (ioctl(dhandle, CDROMREADTOCENTRY,&entry)!=0) return false; + + leadOut.min = entry.cdte_addr.msf.minute; + leadOut.sec = entry.cdte_addr.msf.second; + leadOut.fr = entry.cdte_addr.msf.frame; + + return false; +}; + +bool CDROM_Interface_Linux::GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr) +{ + struct cdrom_tocentry entry; + + entry.cdte_track = track; /* find the address of the first track */ + entry.cdte_format = CDROM_MSF; /* choose MSF addressing */ + + if (ioctl(dhandle, CDROMREADTOCENTRY,&entry)!=0) return false; + + /* attribtute */ + attr = (entry.cdte_adr<<4) | entry.cdte_ctrl; + /* store the address information */ + start.min = entry.cdte_addr.msf.minute; + start.sec = entry.cdte_addr.msf.second; + start.fr = entry.cdte_addr.msf.frame; + return true; +}; + +bool CDROM_Interface_Linux::PlayAudioSector(unsigned long start,unsigned long len) +{ + struct cdrom_blk addr; + addr.from = start; + addr.len = len; + return (ioctl(dhandle, CDROMPLAYBLK, &addr)==0); +} + +bool CDROM_Interface_Linux::StopAudio(void) +{ + return (ioctl(dhandle,CDROMSTOP,0)==0); +}; + +bool CDROM_Interface_Linux::PauseAudio(bool resume) +{ + if (resume) return (ioctl(dhandle, CDROMRESUME,0)==0); + else return (ioctl(dhandle, CDROMPAUSE,0)==0); +}; + +bool CDROM_Interface_Linux::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) +{ + struct cdrom_subchnl sub; + + sub.cdsc_format = CDROM_MSF; + if (ioctl(dhandle, CDROMSUBCHNL, &sub)!=0) return false; + + /* attribute */ + attr = (sub.cdsc_adr<<4) | sub.cdsc_ctrl; + track = sub.cdsc_trk; + index = sub.cdsc_ind; + relPos.fr = sub.cdsc_absaddr.msf.frame; + relPos.sec = sub.cdsc_absaddr.msf.second; + relPos.min = sub.cdsc_absaddr.msf.minute; + absPos.fr = sub.cdsc_reladdr.msf.frame; + absPos.sec = sub.cdsc_reladdr.msf.second; + absPos.min = sub.cdsc_reladdr.msf.minute; + return true; +}; + +bool CDROM_Interface_Linux::GetUPC(unsigned char& attr, char* upcdata) +{ + return (ioctl(dhandle, CDROM_GET_UPC, (void*)upcdata)==0); +}; + +bool CDROM_Interface_Linux::GetAudioStatus(bool& playing, bool& pause) +{ + struct cdrom_subchnl sub; + + sub.cdsc_format = CDROM_MSF; + if (ioctl(dhandle, CDROMSUBCHNL, &sub)!=0) return false; + + playing = (sub.cdsc_audiostatus==CDROM_AUDIO_PLAY); + pause = (sub.cdsc_audiostatus==CDROM_AUDIO_PAUSED); + + return true; +}; + +bool CDROM_Interface_Linux::LoadUnloadMedia(bool unload) +{ + return (ioctl(dhandle, CDROMEJECT,0)==0); +}; + +bool CDROM_Interface_Linux::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) +{ + // Seems not possible to get this values using ioctl... + int track1,track2; + TMSF leadOut; + // If we can read, there's a media + mediaPresent = GetAudioTracks(track1, track2, leadOut); + trayOpen = !mediaPresent; + mediaChanged = (oldLeadOut.min!=leadOut.min) || (oldLeadOut.sec!=leadOut.sec) || (oldLeadOut.fr!=leadOut.fr); + // Save old values + oldLeadOut.min = leadOut.min; + oldLeadOut.sec = leadOut.sec; + oldLeadOut.fr = leadOut.fr; + // always success + return true; +}; + +bool CDROM_Interface_Linux::ReadSectors(void* buffer, bool raw, unsigned long sector, unsigned long num) +{ + // FIXME: ToDo + return false; +}; + +int CDROM_GetMountType(char* path) +// 0 - physical CDROM +// 1 - Iso file +// 2 - subdirectory +{ + // 1. Smells like a real cdrom + // FIXME: Better check if drive is a cdrom + if ((strchr(path,'/')==strrchr(path,'/')) && strstr(path,"cdrom")) return 0; + // 2. Iso file ? + // FIXME : How to detect them ? + // return 1; + // 3. bah, ordinary directory + return 2; +}; + +#else + +// ***************************************************************** +// Windows IOCTL functions (not suitable for 95/98/Me) +// ***************************************************************** + +#include "cdrom.h" +#include // Ioctl stuff +#include "ntddcdrm.h" // Ioctl stuff + +CDROM_Interface_Ioctl::CDROM_Interface_Ioctl() +{ + hIOCTL = INVALID_HANDLE_VALUE; + memset(&oldLeadOut,0,sizeof(oldLeadOut)); +}; + +CDROM_Interface_Ioctl::~CDROM_Interface_Ioctl() +{ + StopAudio(); + CloseHandle(hIOCTL); +}; + +bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc) +{ + // FIXME : To Do + return true; +} + +bool CDROM_Interface_Ioctl::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut) +{ + CDROM_TOC toc; + DWORD byteCount; + BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, + &toc, sizeof(toc), &byteCount,NULL); + if (!bStat) return false; + + stTrack = toc.FirstTrack; + endTrack = toc.LastTrack; + leadOut.min = toc.TrackData[endTrack].Address[1]; + leadOut.sec = toc.TrackData[endTrack].Address[2]; + leadOut.fr = toc.TrackData[endTrack].Address[3]; + return true; +}; + +bool CDROM_Interface_Ioctl::GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr) +{ + CDROM_TOC toc; + DWORD byteCount; + BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, + &toc, sizeof(toc), &byteCount,NULL); + if (!bStat) return false; + + attr = (toc.TrackData[track-1].Adr << 4) | toc.TrackData[track].Control; + start.min = toc.TrackData[track-1].Address[1]; + start.sec = toc.TrackData[track-1].Address[2]; + start.fr = toc.TrackData[track-1].Address[3]; + return true; +}; + +bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) +{ + CDROM_SUB_Q_DATA_FORMAT insub; + SUB_Q_CHANNEL_DATA sub; + DWORD byteCount; + + insub.Format = IOCTL_CDROM_CURRENT_POSITION; + + BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), + &sub, sizeof(sub), &byteCount,NULL); + if (!bStat) return false; + + attr = (sub.CurrentPosition.ADR << 4) | sub.CurrentPosition.Control; + track = sub.CurrentPosition.TrackNumber; + index = sub.CurrentPosition.IndexNumber; + relPos.min = sub.CurrentPosition.TrackRelativeAddress[1]; + relPos.sec = sub.CurrentPosition.TrackRelativeAddress[2]; + relPos.fr = sub.CurrentPosition.TrackRelativeAddress[3]; + absPos.min = sub.CurrentPosition.AbsoluteAddress[1]; + absPos.sec = sub.CurrentPosition.AbsoluteAddress[2]; + absPos.fr = sub.CurrentPosition.AbsoluteAddress[3]; + return true; +}; + +bool CDROM_Interface_Ioctl::GetAudioStatus(bool& playing, bool& pause) +{ + CDROM_SUB_Q_DATA_FORMAT insub; + SUB_Q_CHANNEL_DATA sub; + DWORD byteCount; + + insub.Format = IOCTL_CDROM_CURRENT_POSITION; + + BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), + &sub, sizeof(sub), &byteCount,NULL); + if (!bStat) return false; + + playing = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_IN_PROGRESS); + pause = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_PAUSED); + + return true; +}; + +bool CDROM_Interface_Ioctl::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) +{ + // Seems not possible to get this values using ioctl... + int track1,track2; + TMSF leadOut; + // If we can read, there's a media + mediaPresent = GetAudioTracks(track1, track2, leadOut), + trayOpen = !mediaPresent; + mediaChanged = (oldLeadOut.min!=leadOut.min) || (oldLeadOut.sec!=leadOut.sec) || (oldLeadOut.fr!=leadOut.fr); + // Save old values + oldLeadOut.min = leadOut.min; + oldLeadOut.sec = leadOut.sec; + oldLeadOut.fr = leadOut.fr; + // always success + return true; +}; + +bool CDROM_Interface_Ioctl::PlayAudioSector (unsigned long start,unsigned long len) +{ + CDROM_PLAY_AUDIO_MSF audio; + DWORD byteCount; + // Start + unsigned long addr = start + 150; + audio.StartingF = (UCHAR)(addr%75); addr/=75; + audio.StartingS = (UCHAR)(addr%60); + audio.StartingM = (UCHAR)(addr/60); + // End + addr = start + len + 150; + audio.EndingF = (UCHAR)(addr%75); addr/=75; + audio.EndingS = (UCHAR)(addr%60); + audio.EndingM = (UCHAR)(addr/60); + + BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PLAY_AUDIO_MSF, &audio, sizeof(audio), + NULL, 0, &byteCount,NULL); + return bStat>0; +}; + +bool CDROM_Interface_Ioctl::PauseAudio(bool resume) +{ + BOOL bStat; + DWORD byteCount; + if (resume) bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RESUME_AUDIO, NULL, 0, + NULL, 0, &byteCount,NULL); + else bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PAUSE_AUDIO, NULL, 0, + NULL, 0, &byteCount,NULL); + return bStat>0; +}; + +bool CDROM_Interface_Ioctl::StopAudio(void) +{ + BOOL bStat; + DWORD byteCount; + bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_STOP_AUDIO, NULL, 0, + NULL, 0, &byteCount,NULL); + return bStat>0; +}; + +bool CDROM_Interface_Ioctl::LoadUnloadMedia(bool unload) +{ + BOOL bStat; + DWORD byteCount; + if (unload) bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, + NULL, 0, &byteCount,NULL); + else bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, + NULL, 0, &byteCount,NULL); + return bStat>0; +}; + +bool CDROM_Interface_Ioctl::ReadSectors(void* buffer, bool raw, unsigned long sector, unsigned long num) +{ + // TODO : How to copy cooked without current overhead ? + BOOL bStat; + DWORD byteCount; + RAW_READ_INFO in; + char* inPtr; + + in.DiskOffset.LowPart = sector; + in.DiskOffset.HighPart = 0; + in.SectorCount = num; + in.TrackMode = CDDA; + + if (!raw) inPtr = new char[num*RAW_SECTOR_SIZE]; + else inPtr = (char*)buffer; + + bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RAW_READ, &in, sizeof(in), + inPtr, num*RAW_SECTOR_SIZE, &byteCount,NULL); + + if (!raw) { + char* source = inPtr; + source+=16; // jump 16 bytes + char* outPtr = (char*)buffer; + for (unsigned long i=0; i0); +} + +bool CDROM_Interface_Ioctl::SetDevice(char* path) +{ + if (GetDriveType(path)==DRIVE_CDROM) { + char buffer [256]; + char letter [3] = { 0, ':', 0 }; + letter[0] = path[0]; + strcpy(buffer,"\\\\.\\"); + strcat(buffer,letter); + hIOCTL = CreateFile(buffer, // drive to open + GENERIC_READ, // read access + FILE_SHARE_READ | // share mode + FILE_SHARE_WRITE, + NULL, // default security attributes + OPEN_EXISTING, // disposition + 0, // file attributes + NULL); // do not copy file attributes + return (hIOCTL!=INVALID_HANDLE_VALUE); + } + return false; +}; +/* +int CDROM_GetMountType(char* path) +// 0 - physical CDROM +// 1 - Iso file +// 2 - subdirectory +{ + // 1. Smells like a real cdrom + if ((strlen(path)<=3) && (path[2]=='\\') && (strchr(path,'\\')==strrchr(path,'\\')) && (GetDriveType(path)==DRIVE_CDROM)) return 0; + // 2. Iso file ? + // FIXME : How to detect them ? + // return 1; + // 3. bah, ordinary directory + return 2; +}; +*/ +#endif \ No newline at end of file From 1ffb7800fb88228686e64449a98e78d0eda4e31d Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 6 Mar 2003 13:35:14 +0000 Subject: [PATCH 0639/4131] Win32 files for cdrom aspi and ioctl Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@718 --- src/dos/Ntddcdrm.h | 548 +++++++++++++++++++++++++++++++++ src/dos/Ntddscsi.h | 313 +++++++++++++++++++ src/dos/Ntddstor.h | 745 +++++++++++++++++++++++++++++++++++++++++++++ src/dos/scsidefs.h | 579 +++++++++++++++++++++++++++++++++++ src/dos/wnaspi32.h | 354 +++++++++++++++++++++ 5 files changed, 2539 insertions(+) create mode 100644 src/dos/Ntddcdrm.h create mode 100644 src/dos/Ntddscsi.h create mode 100644 src/dos/Ntddstor.h create mode 100644 src/dos/scsidefs.h create mode 100644 src/dos/wnaspi32.h diff --git a/src/dos/Ntddcdrm.h b/src/dos/Ntddcdrm.h new file mode 100644 index 00000000..6590a4ee --- /dev/null +++ b/src/dos/Ntddcdrm.h @@ -0,0 +1,548 @@ +/*++ BUILD Version: 0001 // Increment this if a change has global effects + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + ntddcdrm.h + +Abstract: + + This module contains structures and definitions + associated with CDROM IOCTls. + +Author: + + Mike Glass + +Revision History: + +--*/ + +// begin_winioctl + +#ifndef _NTDDCDRM_ +#define _NTDDCDRM_ + +#if _MSC_VER >= 1200 +#pragma warning(push) +#endif + +#if _MSC_VER > 1000 +#pragma once +#endif + +// +// remove some level 4 warnings for this header file: +#pragma warning(disable:4200) // array[0] +#pragma warning(disable:4201) // nameless struct/unions +#pragma warning(disable:4214) // bit fields other than int + +#ifdef __cplusplus +extern "C" { +#endif + +// +// NtDeviceIoControlFile IoControlCode values for this device. +// +// Warning: Remember that the low two bits of the code specify how the +// buffers are passed to the driver! +// + +#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM + +#define IOCTL_CDROM_UNLOAD_DRIVER CTL_CODE(IOCTL_CDROM_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS) + +// +// CDROM Audio Device Control Functions +// + +#define IOCTL_CDROM_READ_TOC CTL_CODE(IOCTL_CDROM_BASE, 0x0000, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_SEEK_AUDIO_MSF CTL_CODE(IOCTL_CDROM_BASE, 0x0001, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_STOP_AUDIO CTL_CODE(IOCTL_CDROM_BASE, 0x0002, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_PAUSE_AUDIO CTL_CODE(IOCTL_CDROM_BASE, 0x0003, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_RESUME_AUDIO CTL_CODE(IOCTL_CDROM_BASE, 0x0004, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_GET_VOLUME CTL_CODE(IOCTL_CDROM_BASE, 0x0005, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_PLAY_AUDIO_MSF CTL_CODE(IOCTL_CDROM_BASE, 0x0006, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_SET_VOLUME CTL_CODE(IOCTL_CDROM_BASE, 0x000A, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_READ_Q_CHANNEL CTL_CODE(IOCTL_CDROM_BASE, 0x000B, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_GET_CONTROL CTL_CODE(IOCTL_CDROM_BASE, 0x000D, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_GET_LAST_SESSION CTL_CODE(IOCTL_CDROM_BASE, 0x000E, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_RAW_READ CTL_CODE(IOCTL_CDROM_BASE, 0x000F, METHOD_OUT_DIRECT, FILE_READ_ACCESS) +#define IOCTL_CDROM_DISK_TYPE CTL_CODE(IOCTL_CDROM_BASE, 0x0010, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_CDROM_GET_DRIVE_GEOMETRY CTL_CODE(IOCTL_CDROM_BASE, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX CTL_CODE(IOCTL_CDROM_BASE, 0x0014, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_CDROM_READ_TOC_EX CTL_CODE(IOCTL_CDROM_BASE, 0x0015, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_GET_CONFIGURATION CTL_CODE(IOCTL_CDROM_BASE, 0x0016, METHOD_BUFFERED, FILE_READ_ACCESS) + +// end_winioctl + +// +// The following device control codes are common for all class drivers. The +// functions codes defined here must match all of the other class drivers. +// +// Warning: these codes will be replaced in the future with the IOCTL_STORAGE +// codes included below +// + +#define IOCTL_CDROM_CHECK_VERIFY CTL_CODE(IOCTL_CDROM_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_MEDIA_REMOVAL CTL_CODE(IOCTL_CDROM_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_EJECT_MEDIA CTL_CODE(IOCTL_CDROM_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_LOAD_MEDIA CTL_CODE(IOCTL_CDROM_BASE, 0x0203, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_RESERVE CTL_CODE(IOCTL_CDROM_BASE, 0x0204, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_RELEASE CTL_CODE(IOCTL_CDROM_BASE, 0x0205, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_FIND_NEW_DEVICES CTL_CODE(IOCTL_CDROM_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS) + +// +// The following file contains the IOCTL_STORAGE class ioctl definitions +// + +#include "ntddstor.h" + +// begin_winioctl + +// +// The following device control code is for the SIMBAD simulated bad +// sector facility. See SIMBAD.H in this directory for related structures. +// + +#define IOCTL_CDROM_SIMBAD CTL_CODE(IOCTL_CDROM_BASE, 0x1003, METHOD_BUFFERED, FILE_READ_ACCESS) + +// +// Maximum CD Rom size +// + +#define MAXIMUM_NUMBER_TRACKS 100 +#define MAXIMUM_CDROM_SIZE 804 +#define MINIMUM_CDROM_READ_TOC_EX_SIZE 2 // two bytes min transferred + +// +// READ_TOC_EX structure +// +typedef struct _CDROM_READ_TOC_EX { + UCHAR Format : 4; + UCHAR Reserved1 : 3; // future expansion + UCHAR Msf : 1; + UCHAR SessionTrack; + UCHAR Reserved2; // future expansion + UCHAR Reserved3; // future expansion +} CDROM_READ_TOC_EX, *PCDROM_READ_TOC_EX; + +#define CDROM_READ_TOC_EX_FORMAT_TOC 0x00 +#define CDROM_READ_TOC_EX_FORMAT_SESSION 0x01 +#define CDROM_READ_TOC_EX_FORMAT_FULL_TOC 0x02 +#define CDROM_READ_TOC_EX_FORMAT_PMA 0x03 +#define CDROM_READ_TOC_EX_FORMAT_ATIP 0x04 +#define CDROM_READ_TOC_EX_FORMAT_CDTEXT 0x05 + +// +// CD ROM Table OF Contents (TOC) +// Format 0 - Get table of contents +// + +typedef struct _TRACK_DATA { + UCHAR Reserved; + UCHAR Control : 4; + UCHAR Adr : 4; + UCHAR TrackNumber; + UCHAR Reserved1; + UCHAR Address[4]; +} TRACK_DATA, *PTRACK_DATA; + +typedef struct _CDROM_TOC { + + // + // Header + // + + UCHAR Length[2]; // add two bytes for this field + UCHAR FirstTrack; + UCHAR LastTrack; + + // + // Track data + // + + TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS]; +} CDROM_TOC, *PCDROM_TOC; + +#define CDROM_TOC_SIZE sizeof(CDROM_TOC) + +// +// CD ROM Table OF Contents +// Format 1 - Session Information +// + +typedef struct _CDROM_TOC_SESSION_DATA { + + // + // Header + // + + UCHAR Length[2]; // add two bytes for this field + UCHAR FirstCompleteSession; + UCHAR LastCompleteSession; + + // + // One track, representing the first track + // of the last finished session + // + + TRACK_DATA TrackData[1]; + +} CDROM_TOC_SESSION_DATA, *PCDROM_TOC_SESSION_DATA; + + +// +// CD ROM Table OF Contents +// Format 2 - Full TOC +// + +typedef struct _CDROM_TOC_FULL_TOC_DATA_BLOCK { + UCHAR SessionNumber; + UCHAR Control : 4; + UCHAR Adr : 4; + UCHAR Reserved1; + UCHAR Point; + UCHAR MsfExtra[3]; + UCHAR Zero; + UCHAR Msf[3]; +} CDROM_TOC_FULL_TOC_DATA_BLOCK, *PCDROM_TOC_FULL_TOC_DATA_BLOCK; + +typedef struct _CDROM_TOC_FULL_TOC_DATA { + + // + // Header + // + + UCHAR Length[2]; // add two bytes for this field + UCHAR FirstCompleteSession; + UCHAR LastCompleteSession; + + // + // one to N descriptors included + // + + CDROM_TOC_FULL_TOC_DATA_BLOCK Descriptors[0]; + +} CDROM_TOC_FULL_TOC_DATA, *PCDROM_TOC_FULL_TOC_DATA; + +// +// CD ROM Table OF Contents +// Format 3 - Program Memory Area +// +typedef struct _CDROM_TOC_PMA_DATA { + + // + // Header + // + + UCHAR Length[2]; // add two bytes for this field + UCHAR Reserved1; + UCHAR Reserved2; + + // + // one to N descriptors included + // + + CDROM_TOC_FULL_TOC_DATA_BLOCK Descriptors[0]; + +} CDROM_TOC_PMA_DATA, *PCDROM_TOC_PMA_DATA; + +// +// CD ROM Table OF Contents +// Format 4 - Absolute Time In Pregroove +// + +typedef struct _CDROM_TOC_ATIP_DATA_BLOCK { + + UCHAR CdrwReferenceSpeed : 3; + UCHAR Reserved3 : 1; + UCHAR WritePower : 3; + UCHAR True1 : 1; + UCHAR Reserved4 : 6; + UCHAR UnrestrictedUse : 1; + UCHAR Reserved5 : 1; + UCHAR A3Valid : 1; + UCHAR A2Valid : 1; + UCHAR A1Valid : 1; + UCHAR DiscSubType : 3; + UCHAR IsCdrw : 1; + UCHAR True2 : 1; + UCHAR Reserved7; + + UCHAR LeadInMsf[3]; + UCHAR Reserved8; + + UCHAR LeadOutMsf[3]; + UCHAR Reserved9; + + UCHAR A1Values[3]; + UCHAR Reserved10; + + UCHAR A2Values[3]; + UCHAR Reserved11; + + UCHAR A3Values[3]; + UCHAR Reserved12; + +} CDROM_TOC_ATIP_DATA_BLOCK, *PCDROM_TOC_ATIP_DATA_BLOCK; + +typedef struct _CDROM_TOC_ATIP_DATA { + + // + // Header + // + + UCHAR Length[2]; // add two bytes for this field + UCHAR Reserved1; + UCHAR Reserved2; + + // + // zero? to N descriptors included. + // + + CDROM_TOC_ATIP_DATA_BLOCK Descriptors[0]; + +} CDROM_TOC_ATIP_DATA, *PCDROM_TOC_ATIP_DATA; + +// +// CD ROM Table OF Contents +// Format 5 - CD Text Info +// +typedef struct _CDROM_TOC_CD_TEXT_DATA_BLOCK { + UCHAR PackType; + UCHAR TrackNumber : 7; + UCHAR ExtensionFlag : 1; // should be zero! + UCHAR SequenceNumber; + UCHAR CharacterPosition : 4; + UCHAR BlockNumber : 3; + UCHAR Unicode : 1; + union { + UCHAR Text[12]; + WCHAR WText[6]; + }; + UCHAR CRC[2]; +} CDROM_TOC_CD_TEXT_DATA_BLOCK, *PCDROM_TOC_CD_TEXT_DATA_BLOCK; + +typedef struct _CDROM_TOC_CD_TEXT_DATA { + + // + // Header + // + + UCHAR Length[2]; // add two bytes for this field + UCHAR Reserved1; + UCHAR Reserved2; + + // + // the text info comes in discrete blocks of + // a heavily-overloaded structure + // + + CDROM_TOC_CD_TEXT_DATA_BLOCK Descriptors[0]; + +} CDROM_TOC_CD_TEXT_DATA, *PCDROM_TOC_CD_TEXT_DATA; + +// +// These are the types used for PackType field in CDROM_TOC_CD_TEXT_DATA_BLOCK +// and also for requesting specific info from IOCTL_CDROM_READ_CD_TEXT +// +#define CDROM_CD_TEXT_PACK_ALBUM_NAME 0x80 +#define CDROM_CD_TEXT_PACK_PERFORMER 0x81 +#define CDROM_CD_TEXT_PACK_SONGWRITER 0x82 +#define CDROM_CD_TEXT_PACK_COMPOSER 0x83 +#define CDROM_CD_TEXT_PACK_ARRANGER 0x84 +#define CDROM_CD_TEXT_PACK_MESSAGES 0x85 +#define CDROM_CD_TEXT_PACK_DISC_ID 0x86 +#define CDROM_CD_TEXT_PACK_GENRE 0x87 +#define CDROM_CD_TEXT_PACK_TOC_INFO 0x88 +#define CDROM_CD_TEXT_PACK_TOC_INFO2 0x89 +// 0x8a - 0x8d are reserved.... +#define CDROM_CD_TEXT_PACK_UPC_EAN 0x8e +#define CDROM_CD_TEXT_PACK_SIZE_INFO 0x8f + +// +// Play audio starting at MSF and ending at MSF +// + +typedef struct _CDROM_PLAY_AUDIO_MSF { + UCHAR StartingM; + UCHAR StartingS; + UCHAR StartingF; + UCHAR EndingM; + UCHAR EndingS; + UCHAR EndingF; +} CDROM_PLAY_AUDIO_MSF, *PCDROM_PLAY_AUDIO_MSF; + +// +// Seek to MSF +// + +typedef struct _CDROM_SEEK_AUDIO_MSF { + UCHAR M; + UCHAR S; + UCHAR F; +} CDROM_SEEK_AUDIO_MSF, *PCDROM_SEEK_AUDIO_MSF; + + +// +// Flags for the disk type +// + +typedef struct _CDROM_DISK_DATA { + + ULONG DiskData; + +} CDROM_DISK_DATA, *PCDROM_DISK_DATA; + +#define CDROM_DISK_AUDIO_TRACK (0x00000001) +#define CDROM_DISK_DATA_TRACK (0x00000002) + +// +// CD ROM Data Mode Codes, used with IOCTL_CDROM_READ_Q_CHANNEL +// + +#define IOCTL_CDROM_SUB_Q_CHANNEL 0x00 +#define IOCTL_CDROM_CURRENT_POSITION 0x01 +#define IOCTL_CDROM_MEDIA_CATALOG 0x02 +#define IOCTL_CDROM_TRACK_ISRC 0x03 + +typedef struct _CDROM_SUB_Q_DATA_FORMAT { + UCHAR Format; + UCHAR Track; +} CDROM_SUB_Q_DATA_FORMAT, *PCDROM_SUB_Q_DATA_FORMAT; + + +// +// CD ROM Sub-Q Channel Data Format +// + +typedef struct _SUB_Q_HEADER { + UCHAR Reserved; + UCHAR AudioStatus; + UCHAR DataLength[2]; +} SUB_Q_HEADER, *PSUB_Q_HEADER; + +typedef struct _SUB_Q_CURRENT_POSITION { + SUB_Q_HEADER Header; + UCHAR FormatCode; + UCHAR Control : 4; + UCHAR ADR : 4; + UCHAR TrackNumber; + UCHAR IndexNumber; + UCHAR AbsoluteAddress[4]; + UCHAR TrackRelativeAddress[4]; +} SUB_Q_CURRENT_POSITION, *PSUB_Q_CURRENT_POSITION; + +typedef struct _SUB_Q_MEDIA_CATALOG_NUMBER { + SUB_Q_HEADER Header; + UCHAR FormatCode; + UCHAR Reserved[3]; + UCHAR Reserved1 : 7; + UCHAR Mcval : 1; + UCHAR MediaCatalog[15]; +} SUB_Q_MEDIA_CATALOG_NUMBER, *PSUB_Q_MEDIA_CATALOG_NUMBER; + +typedef struct _SUB_Q_TRACK_ISRC { + SUB_Q_HEADER Header; + UCHAR FormatCode; + UCHAR Reserved0; + UCHAR Track; + UCHAR Reserved1; + UCHAR Reserved2 : 7; + UCHAR Tcval : 1; + UCHAR TrackIsrc[15]; +} SUB_Q_TRACK_ISRC, *PSUB_Q_TRACK_ISRC; + +typedef union _SUB_Q_CHANNEL_DATA { + SUB_Q_CURRENT_POSITION CurrentPosition; + SUB_Q_MEDIA_CATALOG_NUMBER MediaCatalog; + SUB_Q_TRACK_ISRC TrackIsrc; +} SUB_Q_CHANNEL_DATA, *PSUB_Q_CHANNEL_DATA; + +// +// Audio Status Codes +// + +#define AUDIO_STATUS_NOT_SUPPORTED 0x00 +#define AUDIO_STATUS_IN_PROGRESS 0x11 +#define AUDIO_STATUS_PAUSED 0x12 +#define AUDIO_STATUS_PLAY_COMPLETE 0x13 +#define AUDIO_STATUS_PLAY_ERROR 0x14 +#define AUDIO_STATUS_NO_STATUS 0x15 + +// +// ADR Sub-channel Q Field +// + +#define ADR_NO_MODE_INFORMATION 0x0 +#define ADR_ENCODES_CURRENT_POSITION 0x1 +#define ADR_ENCODES_MEDIA_CATALOG 0x2 +#define ADR_ENCODES_ISRC 0x3 + +// +// Sub-channel Q Control Bits +// + +#define AUDIO_WITH_PREEMPHASIS 0x1 +#define DIGITAL_COPY_PERMITTED 0x2 +#define AUDIO_DATA_TRACK 0x4 +#define TWO_FOUR_CHANNEL_AUDIO 0x8 + +// +// Get Audio control parameters +// + +typedef struct _CDROM_AUDIO_CONTROL { + UCHAR LbaFormat; + USHORT LogicalBlocksPerSecond; +} CDROM_AUDIO_CONTROL, *PCDROM_AUDIO_CONTROL; + +// +// Volume control - Volume takes a value between 1 and 0xFF. +// SCSI-II CDROM audio suppports up to 4 audio ports with +// Independent volume control. +// + +typedef struct _VOLUME_CONTROL { + UCHAR PortVolume[4]; +} VOLUME_CONTROL, *PVOLUME_CONTROL; + +typedef enum _TRACK_MODE_TYPE { + YellowMode2, + XAForm2, + CDDA +} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE; + +// +// Passed to cdrom to describe the raw read, ie. Mode 2, Form 2, CDDA... +// + +typedef struct __RAW_READ_INFO { + LARGE_INTEGER DiskOffset; + ULONG SectorCount; + TRACK_MODE_TYPE TrackMode; +} RAW_READ_INFO, *PRAW_READ_INFO; + +#ifdef __cplusplus +} +#endif + + +#if _MSC_VER >= 1200 +#pragma warning(pop) // un-sets any local warning changes +#else +#pragma warning(default:4200) // array[0] is not a warning for this file +#pragma warning(default:4201) // nameless struct/unions +#pragma warning(default:4214) // bit fields other than int +#endif + + +#endif // _NTDDCDRM_ + +// end_winioctl + + diff --git a/src/dos/Ntddscsi.h b/src/dos/Ntddscsi.h new file mode 100644 index 00000000..61f5b250 --- /dev/null +++ b/src/dos/Ntddscsi.h @@ -0,0 +1,313 @@ +/*++ BUILD Version: 0001 // Increment this if a change has global effects + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + ntddscsi.h + +Abstract: + + This is the include file that defines all constants and types for + accessing the SCSI port adapters. + +Author: + + Jeff Havens + +Revision History: + +--*/ + + +// +// Interface GUIDs +// +// need these GUIDs outside conditional includes so that user can +// #include in precompiled header +// #include in a single source file +// #include in that source file a second time to instantiate the GUIDs +// +#ifdef DEFINE_GUID +// +// Make sure FAR is defined... +// +#ifndef FAR +#ifdef _WIN32 +#define FAR +#else +#define FAR _far +#endif +#endif + +DEFINE_GUID(ScsiRawInterfaceGuid, 0x53f56309L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); +DEFINE_GUID(WmiScsiAddressGuid, 0x53f5630fL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); +#endif + +#ifndef _NTDDSCSIH_ +#define _NTDDSCSIH_ + +#ifdef __cplusplus +extern "C" { +#endif + +// +// Device Name - this string is the name of the device. It is the name +// that should be passed to NtOpenFile when accessing the device. +// +// Note: For devices that support multiple units, it should be suffixed +// with the Ascii representation of the unit number. +// + +#define IOCTL_SCSI_BASE FILE_DEVICE_CONTROLLER + +#define DD_SCSI_DEVICE_NAME "\\Device\\ScsiPort" + + +// +// NtDeviceIoControlFile IoControlCode values for this device. +// +// Warning: Remember that the low two bits of the code specify how the +// buffers are passed to the driver! +// + +#define IOCTL_SCSI_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_SCSI_MINIPORT CTL_CODE(IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_SCSI_GET_INQUIRY_DATA CTL_CODE(IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE(IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_SCSI_GET_ADDRESS CTL_CODE(IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_RESCAN_BUS CTL_CODE(IOCTL_SCSI_BASE, 0x0407, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_GET_DUMP_POINTERS CTL_CODE(IOCTL_SCSI_BASE, 0x0408, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_FREE_DUMP_POINTERS CTL_CODE(IOCTL_SCSI_BASE, 0x0409, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_IDE_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x040a, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) + +// +// Define the SCSI pass through structure. +// + +typedef struct _SCSI_PASS_THROUGH { + USHORT Length; + UCHAR ScsiStatus; + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; + UCHAR CdbLength; + UCHAR SenseInfoLength; + UCHAR DataIn; + ULONG DataTransferLength; + ULONG TimeOutValue; + ULONG DataBufferOffset; //ULONG_PTR DataBufferOffset; + ULONG SenseInfoOffset; + UCHAR Cdb[16]; +}SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH; + +// +// Define the SCSI pass through direct structure. +// + +typedef struct _SCSI_PASS_THROUGH_DIRECT { + USHORT Length; + UCHAR ScsiStatus; + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; + UCHAR CdbLength; + UCHAR SenseInfoLength; + UCHAR DataIn; + ULONG DataTransferLength; + ULONG TimeOutValue; + PVOID DataBuffer; + ULONG SenseInfoOffset; + UCHAR Cdb[16]; +}SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT; + + +// +// Define the SCSI pass through direct structure for Win64 (thunking). +// +#if defined(_WIN64) +typedef struct _SCSI_PASS_THROUGH32 { + USHORT Length; + UCHAR ScsiStatus; + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; + UCHAR CdbLength; + UCHAR SenseInfoLength; + UCHAR DataIn; + ULONG DataTransferLength; + ULONG TimeOutValue; + ULONG32 DataBufferOffset; + ULONG SenseInfoOffset; + UCHAR Cdb[16]; +}SCSI_PASS_THROUGH32, *PSCSI_PASS_THROUGH32; + +// +// Define the SCSI pass through direct structure. +// + +typedef struct _SCSI_PASS_THROUGH_DIRECT32 { + USHORT Length; + UCHAR ScsiStatus; + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; + UCHAR CdbLength; + UCHAR SenseInfoLength; + UCHAR DataIn; + ULONG DataTransferLength; + ULONG TimeOutValue; + VOID * POINTER_32 DataBuffer; + ULONG SenseInfoOffset; + UCHAR Cdb[16]; +}SCSI_PASS_THROUGH_DIRECT32, *PSCSI_PASS_THROUGH_DIRECT32; + +#endif + +// +// Define SCSI information. +// Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL. +// + +typedef struct _SCSI_BUS_DATA { + UCHAR NumberOfLogicalUnits; + UCHAR InitiatorBusId; + ULONG InquiryDataOffset; +}SCSI_BUS_DATA, *PSCSI_BUS_DATA; + +// +// Define SCSI adapter bus information structure.. +// Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL. +// + +typedef struct _SCSI_ADAPTER_BUS_INFO { + UCHAR NumberOfBuses; + SCSI_BUS_DATA BusData[1]; +} SCSI_ADAPTER_BUS_INFO, *PSCSI_ADAPTER_BUS_INFO; + +// +// Define SCSI adapter bus information. +// Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL. +// + +typedef struct _SCSI_INQUIRY_DATA { + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; + BOOLEAN DeviceClaimed; + ULONG InquiryDataLength; + ULONG NextInquiryDataOffset; + UCHAR InquiryData[1]; +}SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA; + +// +// Define header for I/O control SRB. +// + +typedef struct _SRB_IO_CONTROL { + ULONG HeaderLength; + UCHAR Signature[8]; + ULONG Timeout; + ULONG ControlCode; + ULONG ReturnCode; + ULONG Length; +} SRB_IO_CONTROL, *PSRB_IO_CONTROL; + +// +// SCSI port driver capabilities structure. +// + +typedef struct _IO_SCSI_CAPABILITIES { + + // + // Length of this structure + // + + ULONG Length; + + // + // Maximum transfer size in single SRB + // + + ULONG MaximumTransferLength; + + // + // Maximum number of physical pages per data buffer + // + + ULONG MaximumPhysicalPages; + + // + // Async calls from port to class + // + + ULONG SupportedAsynchronousEvents; + + // + // Alignment mask for data transfers. + // + + ULONG AlignmentMask; + + // + // Supports tagged queuing + // + + BOOLEAN TaggedQueuing; + + // + // Host adapter scans down for bios devices. + // + + BOOLEAN AdapterScansDown; + + // + // The host adapter uses programmed I/O. + // + + BOOLEAN AdapterUsesPio; + +} IO_SCSI_CAPABILITIES, *PIO_SCSI_CAPABILITIES; + +typedef struct _SCSI_ADDRESS { + ULONG Length; + UCHAR PortNumber; + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; +}SCSI_ADDRESS, *PSCSI_ADDRESS; + +// +// Define structure for returning crash dump pointers. +// + +struct _ADAPTER_OBJECT; + +typedef struct _DUMP_POINTERS { + struct _ADAPTER_OBJECT *AdapterObject; + PVOID MappedRegisterBase; + PVOID DumpData; + PVOID CommonBufferVa; + LARGE_INTEGER CommonBufferPa; + ULONG CommonBufferSize; + BOOLEAN AllocateCommonBuffers; + BOOLEAN UseDiskDump; + UCHAR Spare1[2]; + PVOID DeviceObject; +} DUMP_POINTERS, *PDUMP_POINTERS; + +// +// Define values for pass-through DataIn field. +// + +#define SCSI_IOCTL_DATA_OUT 0 +#define SCSI_IOCTL_DATA_IN 1 +#define SCSI_IOCTL_DATA_UNSPECIFIED 2 + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/dos/Ntddstor.h b/src/dos/Ntddstor.h new file mode 100644 index 00000000..b6b2e528 --- /dev/null +++ b/src/dos/Ntddstor.h @@ -0,0 +1,745 @@ +/*++ BUILD Version: 0001 // Increment this if a change has global effects + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + ntddstor.h + +Abstract: + + This is the include file that defines all common constants and types + accessing the storage class drivers + +Author: + + Peter Wieland 19-Jun-1996 + +Revision History: + +--*/ + + +// +// Interface GUIDs +// +// need these GUIDs outside conditional includes so that user can +// #include in precompiled header +// #include in a single source file +// #include in that source file a second time to instantiate the GUIDs +// +#ifdef DEFINE_GUID +// +// Make sure FAR is defined... +// +#ifndef FAR +#ifdef _WIN32 +#define FAR +#else +#define FAR _far +#endif +#endif + +// begin_wioctlguids +DEFINE_GUID(GUID_DEVINTERFACE_DISK, 0x53f56307L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); +DEFINE_GUID(GUID_DEVINTERFACE_CDROM, 0x53f56308L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); +DEFINE_GUID(GUID_DEVINTERFACE_PARTITION, 0x53f5630aL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); +DEFINE_GUID(GUID_DEVINTERFACE_TAPE, 0x53f5630bL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); +DEFINE_GUID(GUID_DEVINTERFACE_WRITEONCEDISK, 0x53f5630cL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); +DEFINE_GUID(GUID_DEVINTERFACE_VOLUME, 0x53f5630dL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); +DEFINE_GUID(GUID_DEVINTERFACE_MEDIUMCHANGER, 0x53f56310L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); +DEFINE_GUID(GUID_DEVINTERFACE_FLOPPY, 0x53f56311L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); +DEFINE_GUID(GUID_DEVINTERFACE_CDCHANGER, 0x53f56312L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); +DEFINE_GUID(GUID_DEVINTERFACE_STORAGEPORT, 0x2accfe60L, 0xc130, 0x11d2, 0xb0, 0x82, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); +// end_wioctlguids + +// begin_wioctlobsoleteguids +#define DiskClassGuid GUID_DEVINTERFACE_DISK +#define CdRomClassGuid GUID_DEVINTERFACE_CDROM +#define PartitionClassGuid GUID_DEVINTERFACE_PARTITION +#define TapeClassGuid GUID_DEVINTERFACE_TAPE +#define WriteOnceDiskClassGuid GUID_DEVINTERFACE_WRITEONCEDISK +#define VolumeClassGuid GUID_DEVINTERFACE_VOLUME +#define MediumChangerClassGuid GUID_DEVINTERFACE_MEDIUMCHANGER +#define FloppyClassGuid GUID_DEVINTERFACE_FLOPPY +#define CdChangerClassGuid GUID_DEVINTERFACE_CDCHANGER +#define StoragePortClassGuid GUID_DEVINTERFACE_STORAGEPORT +// end_wioctlobsoleteguids +#endif + +// begin_winioctl + +#ifndef _NTDDSTOR_H_ +#define _NTDDSTOR_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// +// IoControlCode values for storage devices +// + +#define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE + +// +// The following device control codes are common for all class drivers. They +// should be used in place of the older IOCTL_DISK, IOCTL_CDROM and IOCTL_TAPE +// common codes +// + +#define IOCTL_STORAGE_CHECK_VERIFY CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_STORAGE_CHECK_VERIFY2 CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_STORAGE_MEDIA_REMOVAL CTL_CODE(IOCTL_STORAGE_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_STORAGE_EJECT_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_STORAGE_LOAD_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_STORAGE_LOAD_MEDIA2 CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_STORAGE_RESERVE CTL_CODE(IOCTL_STORAGE_BASE, 0x0204, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_STORAGE_RELEASE CTL_CODE(IOCTL_STORAGE_BASE, 0x0205, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_STORAGE_FIND_NEW_DEVICES CTL_CODE(IOCTL_STORAGE_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_STORAGE_EJECTION_CONTROL CTL_CODE(IOCTL_STORAGE_BASE, 0x0250, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_STORAGE_MCN_CONTROL CTL_CODE(IOCTL_STORAGE_BASE, 0x0251, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_STORAGE_GET_MEDIA_TYPES CTL_CODE(IOCTL_STORAGE_BASE, 0x0300, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_STORAGE_GET_MEDIA_TYPES_EX CTL_CODE(IOCTL_STORAGE_BASE, 0x0301, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER CTL_CODE(IOCTL_STORAGE_BASE, 0x0304, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_STORAGE_GET_HOTPLUG_INFO CTL_CODE(IOCTL_STORAGE_BASE, 0x0305, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_STORAGE_SET_HOTPLUG_INFO CTL_CODE(IOCTL_STORAGE_BASE, 0x0306, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) + +#define IOCTL_STORAGE_RESET_BUS CTL_CODE(IOCTL_STORAGE_BASE, 0x0400, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_STORAGE_RESET_DEVICE CTL_CODE(IOCTL_STORAGE_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_STORAGE_BREAK_RESERVATION CTL_CODE(IOCTL_STORAGE_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_STORAGE_GET_DEVICE_NUMBER CTL_CODE(IOCTL_STORAGE_BASE, 0x0420, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_STORAGE_PREDICT_FAILURE CTL_CODE(IOCTL_STORAGE_BASE, 0x0440, METHOD_BUFFERED, FILE_ANY_ACCESS) + +// end_winioctl + + +#define IOCTL_STORAGE_QUERY_PROPERTY CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS) + + +// begin_winioctl + +// +// These ioctl codes are obsolete. They are defined here to avoid resuing them +// and to allow class drivers to respond to them more easily. +// + +#define OBSOLETE_IOCTL_STORAGE_RESET_BUS CTL_CODE(IOCTL_STORAGE_BASE, 0x0400, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define OBSOLETE_IOCTL_STORAGE_RESET_DEVICE CTL_CODE(IOCTL_STORAGE_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) + + +// +// IOCTL_STORAGE_GET_HOTPLUG_INFO +// + +typedef struct _STORAGE_HOTPLUG_INFO { + ULONG Size; // version + BOOLEAN MediaRemovable; // ie. zip, jaz, cdrom, mo, etc. vs hdd + BOOLEAN MediaHotplug; // ie. does the device succeed a lock even though its not lockable media? + BOOLEAN DeviceHotplug; // ie. 1394, USB, etc. + BOOLEAN WriteCacheEnableOverride; // This field should not be relied upon because it is no longer used +} STORAGE_HOTPLUG_INFO, *PSTORAGE_HOTPLUG_INFO; + +// +// IOCTL_STORAGE_GET_DEVICE_NUMBER +// +// input - none +// +// output - STORAGE_DEVICE_NUMBER structure +// The values in the STORAGE_DEVICE_NUMBER structure are guaranteed +// to remain unchanged until the system is rebooted. They are not +// guaranteed to be persistant across boots. +// + +typedef struct _STORAGE_DEVICE_NUMBER { + + // + // The FILE_DEVICE_XXX type for this device. + // + + DEVICE_TYPE DeviceType; + + // + // The number of this device + // + + ULONG DeviceNumber; + + // + // If the device is partitionable, the partition number of the device. + // Otherwise -1 + // + + ULONG PartitionNumber; +} STORAGE_DEVICE_NUMBER, *PSTORAGE_DEVICE_NUMBER; + +// +// Define the structures for scsi resets +// + +typedef struct _STORAGE_BUS_RESET_REQUEST { + UCHAR PathId; +} STORAGE_BUS_RESET_REQUEST, *PSTORAGE_BUS_RESET_REQUEST; + +// +// IOCTL_STORAGE_MEDIA_REMOVAL disables the mechanism +// on a storage device that ejects media. This function +// may or may not be supported on storage devices that +// support removable media. +// +// TRUE means prevent media from being removed. +// FALSE means allow media removal. +// + +typedef struct _PREVENT_MEDIA_REMOVAL { + BOOLEAN PreventMediaRemoval; +} PREVENT_MEDIA_REMOVAL, *PPREVENT_MEDIA_REMOVAL; + +// begin_ntminitape + + +typedef struct _TAPE_STATISTICS { + ULONG Version; + ULONG Flags; + LARGE_INTEGER RecoveredWrites; + LARGE_INTEGER UnrecoveredWrites; + LARGE_INTEGER RecoveredReads; + LARGE_INTEGER UnrecoveredReads; + UCHAR CompressionRatioReads; + UCHAR CompressionRatioWrites; +} TAPE_STATISTICS, *PTAPE_STATISTICS; + +#define RECOVERED_WRITES_VALID 0x00000001 +#define UNRECOVERED_WRITES_VALID 0x00000002 +#define RECOVERED_READS_VALID 0x00000004 +#define UNRECOVERED_READS_VALID 0x00000008 +#define WRITE_COMPRESSION_INFO_VALID 0x00000010 +#define READ_COMPRESSION_INFO_VALID 0x00000020 + +typedef struct _TAPE_GET_STATISTICS { + ULONG Operation; +} TAPE_GET_STATISTICS, *PTAPE_GET_STATISTICS; + +#define TAPE_RETURN_STATISTICS 0L +#define TAPE_RETURN_ENV_INFO 1L +#define TAPE_RESET_STATISTICS 2L + +// +// IOCTL_STORAGE_GET_MEDIA_TYPES_EX will return an array of DEVICE_MEDIA_INFO +// structures, one per supported type, embedded in the GET_MEDIA_TYPES struct. +// + +typedef enum _STORAGE_MEDIA_TYPE { + // + // Following are defined in ntdddisk.h in the MEDIA_TYPE enum + // + // Unknown, // Format is unknown + // F5_1Pt2_512, // 5.25", 1.2MB, 512 bytes/sector + // F3_1Pt44_512, // 3.5", 1.44MB, 512 bytes/sector + // F3_2Pt88_512, // 3.5", 2.88MB, 512 bytes/sector + // F3_20Pt8_512, // 3.5", 20.8MB, 512 bytes/sector + // F3_720_512, // 3.5", 720KB, 512 bytes/sector + // F5_360_512, // 5.25", 360KB, 512 bytes/sector + // F5_320_512, // 5.25", 320KB, 512 bytes/sector + // F5_320_1024, // 5.25", 320KB, 1024 bytes/sector + // F5_180_512, // 5.25", 180KB, 512 bytes/sector + // F5_160_512, // 5.25", 160KB, 512 bytes/sector + // RemovableMedia, // Removable media other than floppy + // FixedMedia, // Fixed hard disk media + // F3_120M_512, // 3.5", 120M Floppy + // F3_640_512, // 3.5" , 640KB, 512 bytes/sector + // F5_640_512, // 5.25", 640KB, 512 bytes/sector + // F5_720_512, // 5.25", 720KB, 512 bytes/sector + // F3_1Pt2_512, // 3.5" , 1.2Mb, 512 bytes/sector + // F3_1Pt23_1024, // 3.5" , 1.23Mb, 1024 bytes/sector + // F5_1Pt23_1024, // 5.25", 1.23MB, 1024 bytes/sector + // F3_128Mb_512, // 3.5" MO 128Mb 512 bytes/sector + // F3_230Mb_512, // 3.5" MO 230Mb 512 bytes/sector + // F8_256_128, // 8", 256KB, 128 bytes/sector + // F3_200Mb_512, // 3.5", 200M Floppy (HiFD) + // + + DDS_4mm = 0x20, // Tape - DAT DDS1,2,... (all vendors) + MiniQic, // Tape - miniQIC Tape + Travan, // Tape - Travan TR-1,2,3,... + QIC, // Tape - QIC + MP_8mm, // Tape - 8mm Exabyte Metal Particle + AME_8mm, // Tape - 8mm Exabyte Advanced Metal Evap + AIT1_8mm, // Tape - 8mm Sony AIT + DLT, // Tape - DLT Compact IIIxt, IV + NCTP, // Tape - Philips NCTP + IBM_3480, // Tape - IBM 3480 + IBM_3490E, // Tape - IBM 3490E + IBM_Magstar_3590, // Tape - IBM Magstar 3590 + IBM_Magstar_MP, // Tape - IBM Magstar MP + STK_DATA_D3, // Tape - STK Data D3 + SONY_DTF, // Tape - Sony DTF + DV_6mm, // Tape - 6mm Digital Video + DMI, // Tape - Exabyte DMI and compatibles + SONY_D2, // Tape - Sony D2S and D2L + CLEANER_CARTRIDGE, // Cleaner - All Drive types that support Drive Cleaners + CD_ROM, // Opt_Disk - CD + CD_R, // Opt_Disk - CD-Recordable (Write Once) + CD_RW, // Opt_Disk - CD-Rewriteable + DVD_ROM, // Opt_Disk - DVD-ROM + DVD_R, // Opt_Disk - DVD-Recordable (Write Once) + DVD_RW, // Opt_Disk - DVD-Rewriteable + MO_3_RW, // Opt_Disk - 3.5" Rewriteable MO Disk + MO_5_WO, // Opt_Disk - MO 5.25" Write Once + MO_5_RW, // Opt_Disk - MO 5.25" Rewriteable (not LIMDOW) + MO_5_LIMDOW, // Opt_Disk - MO 5.25" Rewriteable (LIMDOW) + PC_5_WO, // Opt_Disk - Phase Change 5.25" Write Once Optical + PC_5_RW, // Opt_Disk - Phase Change 5.25" Rewriteable + PD_5_RW, // Opt_Disk - PhaseChange Dual Rewriteable + ABL_5_WO, // Opt_Disk - Ablative 5.25" Write Once Optical + PINNACLE_APEX_5_RW, // Opt_Disk - Pinnacle Apex 4.6GB Rewriteable Optical + SONY_12_WO, // Opt_Disk - Sony 12" Write Once + PHILIPS_12_WO, // Opt_Disk - Philips/LMS 12" Write Once + HITACHI_12_WO, // Opt_Disk - Hitachi 12" Write Once + CYGNET_12_WO, // Opt_Disk - Cygnet/ATG 12" Write Once + KODAK_14_WO, // Opt_Disk - Kodak 14" Write Once + MO_NFR_525, // Opt_Disk - Near Field Recording (Terastor) + NIKON_12_RW, // Opt_Disk - Nikon 12" Rewriteable + IOMEGA_ZIP, // Mag_Disk - Iomega Zip + IOMEGA_JAZ, // Mag_Disk - Iomega Jaz + SYQUEST_EZ135, // Mag_Disk - Syquest EZ135 + SYQUEST_EZFLYER, // Mag_Disk - Syquest EzFlyer + SYQUEST_SYJET, // Mag_Disk - Syquest SyJet + AVATAR_F2, // Mag_Disk - 2.5" Floppy + MP2_8mm, // Tape - 8mm Hitachi + DST_S, // Ampex DST Small Tapes + DST_M, // Ampex DST Medium Tapes + DST_L, // Ampex DST Large Tapes + VXATape_1, // Ecrix 8mm Tape + VXATape_2, // Ecrix 8mm Tape + STK_9840, // STK 9840 + LTO_Ultrium, // IBM, HP, Seagate LTO Ultrium + LTO_Accelis, // IBM, HP, Seagate LTO Accelis + DVD_RAM, // Opt_Disk - DVD-RAM + AIT_8mm, // AIT2 or higher + ADR_1, // OnStream ADR Mediatypes + ADR_2 +} STORAGE_MEDIA_TYPE, *PSTORAGE_MEDIA_TYPE; + +#define MEDIA_ERASEABLE 0x00000001 +#define MEDIA_WRITE_ONCE 0x00000002 +#define MEDIA_READ_ONLY 0x00000004 +#define MEDIA_READ_WRITE 0x00000008 + +#define MEDIA_WRITE_PROTECTED 0x00000100 +#define MEDIA_CURRENTLY_MOUNTED 0x80000000 + +// +// Define the different storage bus types +// Bus types below 128 (0x80) are reserved for Microsoft use +// + +typedef enum _STORAGE_BUS_TYPE { + BusTypeUnknown = 0x00, + BusTypeScsi, + BusTypeAtapi, + BusTypeAta, + BusType1394, + BusTypeSsa, + BusTypeFibre, + BusTypeUsb, + BusTypeRAID, + BusTypeMaxReserved = 0x7F +} STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE; + +typedef struct _DEVICE_MEDIA_INFO { + union { + struct { + LARGE_INTEGER Cylinders; + STORAGE_MEDIA_TYPE MediaType; + ULONG TracksPerCylinder; + ULONG SectorsPerTrack; + ULONG BytesPerSector; + ULONG NumberMediaSides; + ULONG MediaCharacteristics; // Bitmask of MEDIA_XXX values. + } DiskInfo; + + struct { + LARGE_INTEGER Cylinders; + STORAGE_MEDIA_TYPE MediaType; + ULONG TracksPerCylinder; + ULONG SectorsPerTrack; + ULONG BytesPerSector; + ULONG NumberMediaSides; + ULONG MediaCharacteristics; // Bitmask of MEDIA_XXX values. + } RemovableDiskInfo; + + struct { + STORAGE_MEDIA_TYPE MediaType; + ULONG MediaCharacteristics; // Bitmask of MEDIA_XXX values. + ULONG CurrentBlockSize; + STORAGE_BUS_TYPE BusType; + + // + // Bus specific information describing the medium supported. + // + + union { + struct { + UCHAR MediumType; + UCHAR DensityCode; + } ScsiInformation; + } BusSpecificData; + + } TapeInfo; + } DeviceSpecific; +} DEVICE_MEDIA_INFO, *PDEVICE_MEDIA_INFO; + +typedef struct _GET_MEDIA_TYPES { + ULONG DeviceType; // FILE_DEVICE_XXX values + ULONG MediaInfoCount; + DEVICE_MEDIA_INFO MediaInfo[1]; +} GET_MEDIA_TYPES, *PGET_MEDIA_TYPES; + + +// +// IOCTL_STORAGE_PREDICT_FAILURE +// +// input - none +// +// output - STORAGE_PREDICT_FAILURE structure +// PredictFailure returns zero if no failure predicted and non zero +// if a failure is predicted. +// +// VendorSpecific returns 512 bytes of vendor specific information +// if a failure is predicted +// +typedef struct _STORAGE_PREDICT_FAILURE +{ + ULONG PredictFailure; + UCHAR VendorSpecific[512]; +} STORAGE_PREDICT_FAILURE, *PSTORAGE_PREDICT_FAILURE; + +// end_ntminitape +// end_winioctl + +// +// Property Query Structures +// + +// +// IOCTL_STORAGE_QUERY_PROPERTY +// +// Input Buffer: +// a STORAGE_PROPERTY_QUERY structure which describes what type of query +// is being done, what property is being queried for, and any additional +// parameters which a particular property query requires. +// +// Output Buffer: +// Contains a buffer to place the results of the query into. Since all +// property descriptors can be cast into a STORAGE_DESCRIPTOR_HEADER, +// the IOCTL can be called once with a small buffer then again using +// a buffer as large as the header reports is necessary. +// + + +// +// Types of queries +// + +typedef enum _STORAGE_QUERY_TYPE { + PropertyStandardQuery = 0, // Retrieves the descriptor + PropertyExistsQuery, // Used to test whether the descriptor is supported + PropertyMaskQuery, // Used to retrieve a mask of writeable fields in the descriptor + PropertyQueryMaxDefined // use to validate the value +} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE; + +// +// define some initial property id's +// + +typedef enum _STORAGE_PROPERTY_ID { + StorageDeviceProperty = 0, + StorageAdapterProperty, + StorageDeviceIdProperty +} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID; + +// +// Query structure - additional parameters for specific queries can follow +// the header +// + +typedef struct _STORAGE_PROPERTY_QUERY { + + // + // ID of the property being retrieved + // + + STORAGE_PROPERTY_ID PropertyId; + + // + // Flags indicating the type of query being performed + // + + STORAGE_QUERY_TYPE QueryType; + + // + // Space for additional parameters if necessary + // + + UCHAR AdditionalParameters[1]; + +} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY; + +// +// Standard property descriptor header. All property pages should use this +// as their first element or should contain these two elements +// + +typedef struct _STORAGE_DESCRIPTOR_HEADER { + + ULONG Version; + + ULONG Size; + +} STORAGE_DESCRIPTOR_HEADER, *PSTORAGE_DESCRIPTOR_HEADER; + +// +// Device property descriptor - this is really just a rehash of the inquiry +// data retrieved from a scsi device +// +// This may only be retrieved from a target device. Sending this to the bus +// will result in an error +// + +typedef struct _STORAGE_DEVICE_DESCRIPTOR { + + // + // Sizeof(STORAGE_DEVICE_DESCRIPTOR) + // + + ULONG Version; + + // + // Total size of the descriptor, including the space for additional + // data and id strings + // + + ULONG Size; + + // + // The SCSI-2 device type + // + + UCHAR DeviceType; + + // + // The SCSI-2 device type modifier (if any) - this may be zero + // + + UCHAR DeviceTypeModifier; + + // + // Flag indicating whether the device's media (if any) is removable. This + // field should be ignored for media-less devices + // + + BOOLEAN RemovableMedia; + + // + // Flag indicating whether the device can support mulitple outstanding + // commands. The actual synchronization in this case is the responsibility + // of the port driver. + // + + BOOLEAN CommandQueueing; + + // + // Byte offset to the zero-terminated ascii string containing the device's + // vendor id string. For devices with no such ID this will be zero + // + + ULONG VendorIdOffset; + + // + // Byte offset to the zero-terminated ascii string containing the device's + // product id string. For devices with no such ID this will be zero + // + + ULONG ProductIdOffset; + + // + // Byte offset to the zero-terminated ascii string containing the device's + // product revision string. For devices with no such string this will be + // zero + // + + ULONG ProductRevisionOffset; + + // + // Byte offset to the zero-terminated ascii string containing the device's + // serial number. For devices with no serial number this will be zero + // + + ULONG SerialNumberOffset; + + // + // Contains the bus type (as defined above) of the device. It should be + // used to interpret the raw device properties at the end of this structure + // (if any) + // + + STORAGE_BUS_TYPE BusType; + + // + // The number of bytes of bus-specific data which have been appended to + // this descriptor + // + + ULONG RawPropertiesLength; + + // + // Place holder for the first byte of the bus specific property data + // + + UCHAR RawDeviceProperties[1]; + +} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR; + + +// +// Adapter properties +// +// This descriptor can be retrieved from a target device object of from the +// device object for the bus. Retrieving from the target device object will +// forward the request to the underlying bus +// + +typedef struct _STORAGE_ADAPTER_DESCRIPTOR { + + ULONG Version; + + ULONG Size; + + ULONG MaximumTransferLength; + + ULONG MaximumPhysicalPages; + + ULONG AlignmentMask; + + BOOLEAN AdapterUsesPio; + + BOOLEAN AdapterScansDown; + + BOOLEAN CommandQueueing; + + BOOLEAN AcceleratedTransfer; + + UCHAR BusType; + + USHORT BusMajorVersion; + + USHORT BusMinorVersion; + +} STORAGE_ADAPTER_DESCRIPTOR, *PSTORAGE_ADAPTER_DESCRIPTOR; + +// +// Storage identification descriptor. +// The definitions here are based on the SCSI/SBP vital product data +// device identifier page. +// + +typedef enum _STORAGE_IDENTIFIER_CODE_SET { + StorageIdCodeSetReserved = 0, + StorageIdCodeSetBinary = 1, + StorageIdCodeSetAscii = 2 +} STORAGE_IDENTIFIER_CODE_SET, *PSTORAGE_IDENTIFIER_CODE_SET; + +typedef enum _STORAGE_IDENTIFIER_TYPE { + StorageIdTypeVendorSpecific = 0, + StorageIdTypeVendorId = 1, + StorageIdTypeEUI64 = 2, + StorageIdTypeFCPHName = 3, + StorageIdTypePortRelative = 4 +} STORAGE_IDENTIFIER_TYPE, *PSTORAGE_IDENTIFIER_TYPE; + +typedef enum _STORAGE_ASSOCIATION_TYPE { + StorageIdAssocDevice = 0, + StorageIdAssocPort = 1 +} STORAGE_ASSOCIATION_TYPE, *PSTORAGE_ASSOCIATION_TYPE; + +typedef struct _STORAGE_IDENTIFIER { + STORAGE_IDENTIFIER_CODE_SET CodeSet; + STORAGE_IDENTIFIER_TYPE Type; + USHORT IdentifierSize; + USHORT NextOffset; + + // + // Add new fields here since existing code depends on + // the above layout not changing. + // + + STORAGE_ASSOCIATION_TYPE Association; + + // + // The identifier is a variable length array of bytes. + // + + UCHAR Identifier[1]; +} STORAGE_IDENTIFIER, *PSTORAGE_IDENTIFIER; + +typedef struct _STORAGE_DEVICE_ID_DESCRIPTOR { + + ULONG Version; + + ULONG Size; + + // + // The number of identifiers reported by the device. + // + + ULONG NumberOfIdentifiers; + + // + // The following field is actually a variable length array of identification + // descriptors. Unfortunately there's no C notation for an array of + // variable length structures so we're forced to just pretend. + // + + UCHAR Identifiers[1]; +} STORAGE_DEVICE_ID_DESCRIPTOR, *PSTORAGE_DEVICE_ID_DESCRIPTOR; + + +#pragma warning(push) +#pragma warning(disable:4200) +typedef struct _STORAGE_MEDIA_SERIAL_NUMBER_DATA { + + USHORT Reserved; + + // + // the SerialNumberLength will be set to zero + // if the command is supported and the media + // does not have a valid serial number. + // + + USHORT SerialNumberLength; + + // + // the following data is binary, and is not guaranteed + // to be NULL terminated. this is an excercise for the + // caller. + // + + UCHAR SerialNumber[0]; + +} STORAGE_MEDIA_SERIAL_NUMBER_DATA, *PSTORAGE_MEDIA_SERIAL_NUMBER_DATA; +#pragma warning(push) + + +// begin_winioctl + +#ifdef __cplusplus +} +#endif + +#endif // _NTDDSTOR_H_ +// end_winioctl + diff --git a/src/dos/scsidefs.h b/src/dos/scsidefs.h new file mode 100644 index 00000000..7db5c9e6 --- /dev/null +++ b/src/dos/scsidefs.h @@ -0,0 +1,579 @@ +//*************************************************************************** +// +// Name: SCSIDEFS.H +// +// Description: SCSI definitions ('C' Language) +// +//*************************************************************************** + +//*************************************************************************** +// %%% TARGET STATUS VALUES %%% +//*************************************************************************** +#define STATUS_GOOD 0x00 // Status Good +#define STATUS_CHKCOND 0x02 // Check Condition +#define STATUS_CONDMET 0x04 // Condition Met +#define STATUS_BUSY 0x08 // Busy +#define STATUS_INTERM 0x10 // Intermediate +#define STATUS_INTCDMET 0x14 // Intermediate-condition met +#define STATUS_RESCONF 0x18 // Reservation conflict +#define STATUS_COMTERM 0x22 // Command Terminated +#define STATUS_QFULL 0x28 // Queue full + +//*************************************************************************** +// %%% SCSI MISCELLANEOUS EQUATES %%% +//*************************************************************************** +#define MAXLUN 7 // Maximum Logical Unit Id +#define MAXTARG 7 // Maximum Target Id +#define MAX_SCSI_LUNS 64 // Maximum Number of SCSI LUNs +#define MAX_NUM_HA 8 // Maximum Number of SCSI HA's + +//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ +// +// %%% SCSI COMMAND OPCODES %%% +// +///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ + +//*************************************************************************** +// %%% Commands for all Device Types %%% +//*************************************************************************** +#define SCSI_CHANGE_DEF 0x40 // Change Definition (Optional) +#define SCSI_COMPARE 0x39 // Compare (O) +#define SCSI_COPY 0x18 // Copy (O) +#define SCSI_COP_VERIFY 0x3A // Copy and Verify (O) +#define SCSI_INQUIRY 0x12 // Inquiry (MANDATORY) +#define SCSI_LOG_SELECT 0x4C // Log Select (O) +#define SCSI_LOG_SENSE 0x4D // Log Sense (O) +#define SCSI_MODE_SEL6 0x15 // Mode Select 6-byte (Device Specific) +#define SCSI_MODE_SEL10 0x55 // Mode Select 10-byte (Device Specific) +#define SCSI_MODE_SEN6 0x1A // Mode Sense 6-byte (Device Specific) +#define SCSI_MODE_SEN10 0x5A // Mode Sense 10-byte (Device Specific) +#define SCSI_READ_BUFF 0x3C // Read Buffer (O) +#define SCSI_REQ_SENSE 0x03 // Request Sense (MANDATORY) +#define SCSI_SEND_DIAG 0x1D // Send Diagnostic (O) +#define SCSI_TST_U_RDY 0x00 // Test Unit Ready (MANDATORY) +#define SCSI_WRITE_BUFF 0x3B // Write Buffer (O) + +//*************************************************************************** +// %%% Commands Unique to Direct Access Devices %%% +//*************************************************************************** +#define SCSI_COMPARE 0x39 // Compare (O) +#define SCSI_FORMAT 0x04 // Format Unit (MANDATORY) +#define SCSI_LCK_UN_CAC 0x36 // Lock Unlock Cache (O) +#define SCSI_PREFETCH 0x34 // Prefetch (O) +#define SCSI_MED_REMOVL 0x1E // Prevent/Allow medium Removal (O) +#define SCSI_READ6 0x08 // Read 6-byte (MANDATORY) +#define SCSI_READ10 0x28 // Read 10-byte (MANDATORY) +#define SCSI_RD_CAPAC 0x25 // Read Capacity (MANDATORY) +#define SCSI_RD_DEFECT 0x37 // Read Defect Data (O) +#define SCSI_READ_LONG 0x3E // Read Long (O) +#define SCSI_REASS_BLK 0x07 // Reassign Blocks (O) +#define SCSI_RCV_DIAG 0x1C // Receive Diagnostic Results (O) +#define SCSI_RELEASE 0x17 // Release Unit (MANDATORY) +#define SCSI_REZERO 0x01 // Rezero Unit (O) +#define SCSI_SRCH_DAT_E 0x31 // Search Data Equal (O) +#define SCSI_SRCH_DAT_H 0x30 // Search Data High (O) +#define SCSI_SRCH_DAT_L 0x32 // Search Data Low (O) +#define SCSI_SEEK6 0x0B // Seek 6-Byte (O) +#define SCSI_SEEK10 0x2B // Seek 10-Byte (O) +#define SCSI_SEND_DIAG 0x1D // Send Diagnostics (MANDATORY) +#define SCSI_SET_LIMIT 0x33 // Set Limits (O) +#define SCSI_START_STP 0x1B // Start/Stop Unit (O) +#define SCSI_SYNC_CACHE 0x35 // Synchronize Cache (O) +#define SCSI_VERIFY 0x2F // Verify (O) +#define SCSI_WRITE6 0x0A // Write 6-Byte (MANDATORY) +#define SCSI_WRITE10 0x2A // Write 10-Byte (MANDATORY) +#define SCSI_WRT_VERIFY 0x2E // Write and Verify (O) +#define SCSI_WRITE_LONG 0x3F // Write Long (O) +#define SCSI_WRITE_SAME 0x41 // Write Same (O) + +//*************************************************************************** +// %%% Commands Unique to Sequential Access Devices %%% +//*************************************************************************** +#define SCSI_ERASE 0x19 // Erase (MANDATORY) +#define SCSI_LOAD_UN 0x1B // Load/Unload (O) +#define SCSI_LOCATE 0x2B // Locate (O) +#define SCSI_RD_BLK_LIM 0x05 // Read Block Limits (MANDATORY) +#define SCSI_READ_POS 0x34 // Read Position (O) +#define SCSI_READ_REV 0x0F // Read Reverse (O) +#define SCSI_REC_BF_DAT 0x14 // Recover Buffer Data (O) +#define SCSI_RESERVE 0x16 // Reserve Unit (MANDATORY) +#define SCSI_REWIND 0x01 // Rewind (MANDATORY) +#define SCSI_SPACE 0x11 // Space (MANDATORY) +#define SCSI_VERIFY_T 0x13 // Verify (Tape) (O) +#define SCSI_WRT_FILE 0x10 // Write Filemarks (MANDATORY) + +//*************************************************************************** +// %%% Commands Unique to Printer Devices %%% +//*************************************************************************** +#define SCSI_PRINT 0x0A // Print (MANDATORY) +#define SCSI_SLEW_PNT 0x0B // Slew and Print (O) +#define SCSI_STOP_PNT 0x1B // Stop Print (O) +#define SCSI_SYNC_BUFF 0x10 // Synchronize Buffer (O) + +//*************************************************************************** +// %%% Commands Unique to Processor Devices %%% +//*************************************************************************** +#define SCSI_RECEIVE 0x08 // Receive (O) +#define SCSI_SEND 0x0A // Send (O) + +//*************************************************************************** +// %%% Commands Unique to Write-Once Devices %%% +//*************************************************************************** +#define SCSI_MEDIUM_SCN 0x38 // Medium Scan (O) +#define SCSI_SRCHDATE10 0x31 // Search Data Equal 10-Byte (O) +#define SCSI_SRCHDATE12 0xB1 // Search Data Equal 12-Byte (O) +#define SCSI_SRCHDATH10 0x30 // Search Data High 10-Byte (O) +#define SCSI_SRCHDATH12 0xB0 // Search Data High 12-Byte (O) +#define SCSI_SRCHDATL10 0x32 // Search Data Low 10-Byte (O) +#define SCSI_SRCHDATL12 0xB2 // Search Data Low 12-Byte (O) +#define SCSI_SET_LIM_10 0x33 // Set Limits 10-Byte (O) +#define SCSI_SET_LIM_12 0xB3 // Set Limits 10-Byte (O) +#define SCSI_VERIFY10 0x2F // Verify 10-Byte (O) +#define SCSI_VERIFY12 0xAF // Verify 12-Byte (O) +#define SCSI_WRITE12 0xAA // Write 12-Byte (O) +#define SCSI_WRT_VER10 0x2E // Write and Verify 10-Byte (O) +#define SCSI_WRT_VER12 0xAE // Write and Verify 12-Byte (O) + +//*************************************************************************** +// %%% Commands Unique to CD-ROM Devices %%% +//*************************************************************************** +#define SCSI_PLAYAUD_10 0x45 // Play Audio 10-Byte (O) +#define SCSI_PLAYAUD_12 0xA5 // Play Audio 12-Byte 12-Byte (O) +#define SCSI_PLAYAUDMSF 0x47 // Play Audio MSF (O) +#define SCSI_PLAYA_TKIN 0x48 // Play Audio Track/Index (O) +#define SCSI_PLYTKREL10 0x49 // Play Track Relative 10-Byte (O) +#define SCSI_PLYTKREL12 0xA9 // Play Track Relative 12-Byte (O) +#define SCSI_READCDCAP 0x25 // Read CD-ROM Capacity (MANDATORY) +#define SCSI_READHEADER 0x44 // Read Header (O) +#define SCSI_SUBCHANNEL 0x42 // Read Subchannel (O) +#define SCSI_READ_TOC 0x43 // Read TOC (O) + +//*************************************************************************** +// %%% Commands Unique to Scanner Devices %%% +//*************************************************************************** +#define SCSI_GETDBSTAT 0x34 // Get Data Buffer Status (O) +#define SCSI_GETWINDOW 0x25 // Get Window (O) +#define SCSI_OBJECTPOS 0x31 // Object Postion (O) +#define SCSI_SCAN 0x1B // Scan (O) +#define SCSI_SETWINDOW 0x24 // Set Window (MANDATORY) + +//*************************************************************************** +// %%% Commands Unique to Optical Memory Devices %%% +//*************************************************************************** +#define SCSI_UpdateBlk 0x3D // Update Block (O) + +//*************************************************************************** +// %%% Commands Unique to Medium Changer Devices %%% +//*************************************************************************** +#define SCSI_EXCHMEDIUM 0xA6 // Exchange Medium (O) +#define SCSI_INITELSTAT 0x07 // Initialize Element Status (O) +#define SCSI_POSTOELEM 0x2B // Position to Element (O) +#define SCSI_REQ_VE_ADD 0xB5 // Request Volume Element Address (O) +#define SCSI_SENDVOLTAG 0xB6 // Send Volume Tag (O) + +//*************************************************************************** +// %%% Commands Unique to Communication Devices %%% +//*************************************************************************** +#define SCSI_GET_MSG_6 0x08 // Get Message 6-Byte (MANDATORY) +#define SCSI_GET_MSG_10 0x28 // Get Message 10-Byte (O) +#define SCSI_GET_MSG_12 0xA8 // Get Message 12-Byte (O) +#define SCSI_SND_MSG_6 0x0A // Send Message 6-Byte (MANDATORY) +#define SCSI_SND_MSG_10 0x2A // Send Message 10-Byte (O) +#define SCSI_SND_MSG_12 0xAA // Send Message 12-Byte (O) + +//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ +// +// %%% END OF SCSI COMMAND OPCODES %%% +// +///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ + +//*************************************************************************** +// %%% Request Sense Data Format %%% +//*************************************************************************** +typedef struct { + + BYTE ErrorCode; // Error Code (70H or 71H) + BYTE SegmentNum; // Number of current segment descriptor + BYTE SenseKey; // Sense Key(See bit definitions too) + BYTE InfoByte0; // Information MSB + BYTE InfoByte1; // Information MID + BYTE InfoByte2; // Information MID + BYTE InfoByte3; // Information LSB + BYTE AddSenLen; // Additional Sense Length + BYTE ComSpecInf0; // Command Specific Information MSB + BYTE ComSpecInf1; // Command Specific Information MID + BYTE ComSpecInf2; // Command Specific Information MID + BYTE ComSpecInf3; // Command Specific Information LSB + BYTE AddSenseCode; // Additional Sense Code + BYTE AddSenQual; // Additional Sense Code Qualifier + BYTE FieldRepUCode; // Field Replaceable Unit Code + BYTE SenKeySpec15; // Sense Key Specific 15th byte + BYTE SenKeySpec16; // Sense Key Specific 16th byte + BYTE SenKeySpec17; // Sense Key Specific 17th byte + BYTE AddSenseBytes; // Additional Sense Bytes + +} SENSE_DATA_FMT; + +//*************************************************************************** +// %%% REQUEST SENSE ERROR CODE %%% +//*************************************************************************** +#define SERROR_CURRENT 0x70 // Current Errors +#define SERROR_DEFERED 0x71 // Deferred Errors + +//*************************************************************************** +// %%% REQUEST SENSE BIT DEFINITIONS %%% +//*************************************************************************** +#define SENSE_VALID 0x80 // Byte 0 Bit 7 +#define SENSE_FILEMRK 0x80 // Byte 2 Bit 7 +#define SENSE_EOM 0x40 // Byte 2 Bit 6 +#define SENSE_ILI 0x20 // Byte 2 Bit 5 + +//*************************************************************************** +// %%% REQUEST SENSE SENSE KEY DEFINITIONS %%% +//*************************************************************************** +#define KEY_NOSENSE 0x00 // No Sense +#define KEY_RECERROR 0x01 // Recovered Error +#define KEY_NOTREADY 0x02 // Not Ready +#define KEY_MEDIUMERR 0x03 // Medium Error +#define KEY_HARDERROR 0x04 // Hardware Error +#define KEY_ILLGLREQ 0x05 // Illegal Request +#define KEY_UNITATT 0x06 // Unit Attention +#define KEY_DATAPROT 0x07 // Data Protect +#define KEY_BLANKCHK 0x08 // Blank Check +#define KEY_VENDSPEC 0x09 // Vendor Specific +#define KEY_COPYABORT 0x0A // Copy Abort +#define KEY_EQUAL 0x0C // Equal (Search) +#define KEY_VOLOVRFLW 0x0D // Volume Overflow +#define KEY_MISCOMP 0x0E // Miscompare (Search) +#define KEY_RESERVED 0x0F // Reserved + +//*************************************************************************** +// %%% PERIPHERAL DEVICE TYPE DEFINITIONS %%% +//*************************************************************************** +#define DTYPE_DASD 0x00 // Disk Device +#define DTYPE_SEQD 0x01 // Tape Device +#define DTYPE_PRNT 0x02 // Printer +#define DTYPE_PROC 0x03 // Processor +#define DTYPE_WORM 0x04 // Write-once read-multiple +#define DTYPE_CROM 0x05 // CD-ROM device +#define DTYPE_CDROM 0x05 // CD-ROM device +#define DTYPE_SCAN 0x06 // Scanner device +#define DTYPE_OPTI 0x07 // Optical memory device +#define DTYPE_JUKE 0x08 // Medium Changer device +#define DTYPE_COMM 0x09 // Communications device +#define DTYPE_RESL 0x0A // Reserved (low) +#define DTYPE_RESH 0x1E // Reserved (high) +#define DTYPE_UNKNOWN 0x1F // Unknown or no device type + +//*************************************************************************** +// %%% ANSI APPROVED VERSION DEFINITIONS %%% +//*************************************************************************** +#define ANSI_MAYBE 0x0 // Device may or may not be ANSI approved stand +#define ANSI_SCSI1 0x1 // Device complies to ANSI X3.131-1986 (SCSI-1) +#define ANSI_SCSI2 0x2 // Device complies to SCSI-2 +#define ANSI_RESLO 0x3 // Reserved (low) +#define ANSI_RESHI 0x7 // Reserved (high) + + +//////////////////////////////////////////////////////////////// + +typedef struct { + USHORT Length; + UCHAR ScsiStatus; + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; + UCHAR CdbLength; + UCHAR SenseInfoLength; + UCHAR DataIn; + ULONG DataTransferLength; + ULONG TimeOutValue; + ULONG DataBufferOffset; + ULONG SenseInfoOffset; + UCHAR Cdb[16]; +} SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH; + + +typedef struct { + USHORT Length; + UCHAR ScsiStatus; + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; + UCHAR CdbLength; + UCHAR SenseInfoLength; + UCHAR DataIn; + ULONG DataTransferLength; + ULONG TimeOutValue; + PVOID DataBuffer; + ULONG SenseInfoOffset; + UCHAR Cdb[16]; +} SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT; + + +typedef struct { + SCSI_PASS_THROUGH spt; + ULONG Filler; + UCHAR ucSenseBuf[32]; + UCHAR ucDataBuf[512]; +} SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS; + + +typedef struct { + SCSI_PASS_THROUGH_DIRECT spt; + ULONG Filler; + UCHAR ucSenseBuf[32]; +} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER; + + + +typedef struct { + UCHAR NumberOfLogicalUnits; + UCHAR InitiatorBusId; + ULONG InquiryDataOffset; +} SCSI_BUS_DATA, *PSCSI_BUS_DATA; + + +typedef struct { + UCHAR NumberOfBusses; + SCSI_BUS_DATA BusData[1]; +} SCSI_ADAPTER_BUS_INFO, *PSCSI_ADAPTER_BUS_INFO; + + +typedef struct { + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; + BOOLEAN DeviceClaimed; + ULONG InquiryDataLength; + ULONG NextInquiryDataOffset; + UCHAR InquiryData[1]; +} SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA; + + +typedef struct { + ULONG Length; + UCHAR PortNumber; + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; +} SCSI_ADDRESS, *PSCSI_ADDRESS; + + +/* + * method codes + */ +#define METHOD_BUFFERED 0 +#define METHOD_IN_DIRECT 1 +#define METHOD_OUT_DIRECT 2 +#define METHOD_NEITHER 3 + +/* + * file access values + */ +#define FILE_ANY_ACCESS 0 +#define FILE_READ_ACCESS (0x0001) +#define FILE_WRITE_ACCESS (0x0002) + + +#define IOCTL_SCSI_BASE 0x00000004 + +/* + * constants for DataIn member of SCSI_PASS_THROUGH* structures + */ +#define SCSI_IOCTL_DATA_OUT 0 +#define SCSI_IOCTL_DATA_IN 1 +#define SCSI_IOCTL_DATA_UNSPECIFIED 2 + +/* + * Standard IOCTL define + */ +#define CTL_CODE( DevType, Function, Method, Access ) ( \ + ((DevType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ +) + +#define IOCTL_SCSI_PASS_THROUGH CTL_CODE( IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS ) +#define IOCTL_SCSI_MINIPORT CTL_CODE( IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS ) +#define IOCTL_SCSI_GET_INQUIRY_DATA CTL_CODE( IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE( IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE( IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS ) +#define IOCTL_SCSI_GET_ADDRESS CTL_CODE( IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS ) + +#define FILE_DEVICE_MASS_STORAGE 0x0000002d +#define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE + +#define IOCTL_STORAGE_CHECK_VERIFY CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_STORAGE_CHECK_VERIFY2 CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_STORAGE_MEDIA_REMOVAL CTL_CODE(IOCTL_STORAGE_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_STORAGE_EJECT_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_STORAGE_LOAD_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_STORAGE_LOAD_MEDIA2 CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_STORAGE_RESERVE CTL_CODE(IOCTL_STORAGE_BASE, 0x0204, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_STORAGE_RELEASE CTL_CODE(IOCTL_STORAGE_BASE, 0x0205, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_STORAGE_FIND_NEW_DEVICES CTL_CODE(IOCTL_STORAGE_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define FILE_DEVICE_CD_ROM 0x00000002 +#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM +#define IOCTL_CDROM_RAW_READ CTL_CODE(IOCTL_CDROM_BASE, 0x000F, METHOD_OUT_DIRECT, FILE_READ_ACCESS) +#define IOCTL_CDROM_READ_Q_CHANNEL CTL_CODE(IOCTL_CDROM_BASE, 0x000B, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_SEEK_AUDIO_MSF CTL_CODE(IOCTL_CDROM_BASE, 0x0001, METHOD_BUFFERED, FILE_READ_ACCESS) + +typedef struct _CDROM_SEEK_AUDIO_MSF { + UCHAR M; + UCHAR S; + UCHAR F; +} CDROM_SEEK_AUDIO_MSF, *PCDROM_SEEK_AUDIO_MSF; + +// +// CD ROM Sub-Q Channel Data Format +// + +#define IOCTL_CDROM_SUB_Q_CHANNEL 0x00 +#define IOCTL_CDROM_CURRENT_POSITION 0x01 +#define IOCTL_CDROM_MEDIA_CATALOG 0x02 +#define IOCTL_CDROM_TRACK_ISRC 0x03 + +typedef struct _CDROM_SUB_Q_DATA_FORMAT { + UCHAR Format; + UCHAR Track; +} CDROM_SUB_Q_DATA_FORMAT, *PCDROM_SUB_Q_DATA_FORMAT; + +typedef struct _SUB_Q_HEADER { + UCHAR Reserved; + UCHAR AudioStatus; + UCHAR DataLength[2]; +} SUB_Q_HEADER, *PSUB_Q_HEADER; + +typedef struct _SUB_Q_CURRENT_POSITION { + SUB_Q_HEADER Header; + UCHAR FormatCode; + UCHAR Control : 4; + UCHAR ADR : 4; + UCHAR TrackNumber; + UCHAR IndexNumber; + UCHAR AbsoluteAddress[4]; + UCHAR TrackRelativeAddress[4]; +} SUB_Q_CURRENT_POSITION, *PSUB_Q_CURRENT_POSITION; + +typedef struct _SUB_Q_MEDIA_CATALOG_NUMBER { + SUB_Q_HEADER Header; + UCHAR FormatCode; + UCHAR Reserved[3]; + UCHAR Reserved1 : 7; + UCHAR Mcval : 1; + UCHAR MediaCatalog[15]; +} SUB_Q_MEDIA_CATALOG_NUMBER, *PSUB_Q_MEDIA_CATALOG_NUMBER; + +typedef struct _SUB_Q_TRACK_ISRC { + SUB_Q_HEADER Header; + UCHAR FormatCode; + UCHAR Reserved0; + UCHAR Track; + UCHAR Reserved1; + UCHAR Reserved2 : 7; + UCHAR Tcval : 1; + UCHAR TrackIsrc[15]; +} SUB_Q_TRACK_ISRC, *PSUB_Q_TRACK_ISRC; + +typedef union _SUB_Q_CHANNEL_DATA { + SUB_Q_CURRENT_POSITION CurrentPosition; + SUB_Q_MEDIA_CATALOG_NUMBER MediaCatalog; + SUB_Q_TRACK_ISRC TrackIsrc; +} SUB_Q_CHANNEL_DATA, *PSUB_Q_CHANNEL_DATA; + + +// IOCTL_DISK_SET_CACHE allows the caller to get or set the state of the disk +// read/write caches. +// +// If the structure is provided as the input buffer for the ioctl the read & +// write caches will be enabled or disabled depending on the parameters +// provided. +// +// If the structure is provided as an output buffer for the ioctl the state +// of the read & write caches will be returned. If both input and outut buffers +// are provided the output buffer will contain the cache state BEFORE any +// changes are made + + +typedef enum { + EqualPriority, + KeepPrefetchedData, + KeepReadData +} DISK_CACHE_RETENTION_PRIORITY; + +#define FILE_DEVICE_DISK 0x00000007 +#define IOCTL_DISK_BASE FILE_DEVICE_DISK +#define IOCTL_DISK_GET_CACHE_INFORMATION CTL_CODE(IOCTL_DISK_BASE, 0x0035, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_DISK_SET_CACHE_INFORMATION CTL_CODE(IOCTL_DISK_BASE, 0x0036, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) + +typedef struct _DISK_CACHE_INFORMATION { + + // + // on return indicates that the device is capable of saving any parameters + // in non-volatile storage. On send indicates that the device should + // save the state in non-volatile storage. + // + + BOOLEAN ParametersSavable; + + // + // Indicates whether the write and read caches are enabled. + // + + BOOLEAN ReadCacheEnabled; + BOOLEAN WriteCacheEnabled; + + // + // Controls the likelyhood of data remaining in the cache depending on how + // it got there. Data cached from a READ or WRITE operation may be given + // higher, lower or equal priority to data entered into the cache for other + // means (like prefetch) + // + + DISK_CACHE_RETENTION_PRIORITY ReadRetentionPriority; + DISK_CACHE_RETENTION_PRIORITY WriteRetentionPriority; + + // + // Requests for a larger number of blocks than this may have prefetching + // disabled. If this value is set to 0 prefetch will be disabled. + // + + USHORT DisablePrefetchTransferLength; + + // + // If TRUE then ScalarPrefetch (below) will be valid. If FALSE then + // the minimum and maximum values should be treated as a block count + // (BlockPrefetch) + // + + BOOLEAN PrefetchScalar; + + // + // Contains the minimum and maximum amount of data which will be + // will be prefetched into the cache on a disk operation. This value + // may either be a scalar multiplier of the transfer length of the request, + // or an abolute number of disk blocks. PrefetchScalar (above) indicates + // which interpretation is used. + // + + union { + struct { + USHORT Minimum; + USHORT Maximum; + + // + // The maximum number of blocks which will be prefetched - useful + // with the scalar limits to set definite upper limits. + // + + USHORT MaximumBlocks; + } ScalarPrefetch; + + struct { + USHORT Minimum; + USHORT Maximum; + } BlockPrefetch; + }; + +} DISK_CACHE_INFORMATION, *PDISK_CACHE_INFORMATION; + diff --git a/src/dos/wnaspi32.h b/src/dos/wnaspi32.h new file mode 100644 index 00000000..92b9921b --- /dev/null +++ b/src/dos/wnaspi32.h @@ -0,0 +1,354 @@ +/****************************************************************************** +** +** Module Name: wnaspi32.h +** +** Description: Header file for ASPI for Win32. This header includes +** macro and type declarations, and can be included without +** modification when using Borland C++ or Microsoft Visual +** C++ with 32-bit compilation. If you are using a different +** compiler then you MUST ensure that structures are packed +** onto byte alignments, and that C++ name mangling is turned +** off. +** +** Notes: This file created using 4 spaces per tab. +** +******************************************************************************/ + +#ifndef __WNASPI32_H__ +#define __WNASPI32_H__ + +/* +** Make sure structures are packed and undecorated. +*/ + +#ifdef __BORLANDC__ +#pragma option -a1 +#endif //__BORLANDC__ + +#ifdef _MSC_VER +#pragma pack(1) +#endif //__MSC_VER + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +//***************************************************************************** +// %%% SCSI MISCELLANEOUS EQUATES %%% +//***************************************************************************** + +#define SENSE_LEN 14 // Default sense buffer length +#define SRB_DIR_SCSI 0x00 // Direction determined by SCSI +#define SRB_POSTING 0x01 // Enable ASPI posting +#define SRB_ENABLE_RESIDUAL_COUNT 0x04 // Enable residual byte count reporting +#define SRB_DIR_IN 0x08 // Transfer from SCSI target to host +#define SRB_DIR_OUT 0x10 // Transfer from host to SCSI target +#define SRB_EVENT_NOTIFY 0x40 // Enable ASPI event notification + +#define RESIDUAL_COUNT_SUPPORTED 0x02 // Extended buffer flag +#define MAX_SRB_TIMEOUT 108000lu // 30 hour maximum timeout in s +#define DEFAULT_SRB_TIMEOUT 108000lu // Max timeout by default + + +//***************************************************************************** +// %%% ASPI Command Definitions %%% +//***************************************************************************** + +#define SC_HA_INQUIRY 0x00 // Host adapter inquiry +#define SC_GET_DEV_TYPE 0x01 // Get device type +#define SC_EXEC_SCSI_CMD 0x02 // Execute SCSI command +#define SC_ABORT_SRB 0x03 // Abort an SRB +#define SC_RESET_DEV 0x04 // SCSI bus device reset +#define SC_SET_HA_PARMS 0x05 // Set HA parameters +#define SC_GET_DISK_INFO 0x06 // Get Disk information +#define SC_RESCAN_SCSI_BUS 0x07 // ReBuild SCSI device map +#define SC_GETSET_TIMEOUTS 0x08 // Get/Set target timeouts + +//***************************************************************************** +// %%% SRB Status %%% +//***************************************************************************** + +#define SS_PENDING 0x00 // SRB being processed +#define SS_COMP 0x01 // SRB completed without error +#define SS_ABORTED 0x02 // SRB aborted +#define SS_ABORT_FAIL 0x03 // Unable to abort SRB +#define SS_ERR 0x04 // SRB completed with error + +#define SS_INVALID_CMD 0x80 // Invalid ASPI command +#define SS_INVALID_HA 0x81 // Invalid host adapter number +#define SS_NO_DEVICE 0x82 // SCSI device not installed + +#define SS_INVALID_SRB 0xE0 // Invalid parameter set in SRB +#define SS_OLD_MANAGER 0xE1 // ASPI manager doesn't support Windows +#define SS_BUFFER_ALIGN 0xE1 // Buffer not aligned (replaces OLD_MANAGER in Win32) +#define SS_ILLEGAL_MODE 0xE2 // Unsupported Windows mode +#define SS_NO_ASPI 0xE3 // No ASPI managers resident +#define SS_FAILED_INIT 0xE4 // ASPI for windows failed init +#define SS_ASPI_IS_BUSY 0xE5 // No resources available to execute cmd +#define SS_BUFFER_TO_BIG 0xE6 // Buffer size to big to handle! +#define SS_MISMATCHED_COMPONENTS 0xE7 // The DLLs/EXEs of ASPI don't version check +#define SS_NO_ADAPTERS 0xE8 // No host adapters to manage +#define SS_INSUFFICIENT_RESOURCES 0xE9 // Couldn't allocate resources needed to init +#define SS_ASPI_IS_SHUTDOWN 0xEA // Call came to ASPI after PROCESS_DETACH +#define SS_BAD_INSTALL 0xEB // The DLL or other components are installed wrong + +//***************************************************************************** +// %%% Host Adapter Status %%% +//***************************************************************************** + +#define HASTAT_OK 0x00 // Host adapter did not detect an // error +#define HASTAT_SEL_TO 0x11 // Selection Timeout +#define HASTAT_DO_DU 0x12 // Data overrun data underrun +#define HASTAT_BUS_FREE 0x13 // Unexpected bus free +#define HASTAT_PHASE_ERR 0x14 // Target bus phase sequence // failure +#define HASTAT_TIMEOUT 0x09 // Timed out while SRB was waiting to beprocessed. +#define HASTAT_COMMAND_TIMEOUT 0x0B // Adapter timed out processing SRB. +#define HASTAT_MESSAGE_REJECT 0x0D // While processing SRB, the // adapter received a MESSAGE +#define HASTAT_BUS_RESET 0x0E // A bus reset was detected. +#define HASTAT_PARITY_ERROR 0x0F // A parity error was detected. +#define HASTAT_REQUEST_SENSE_FAILED 0x10 // The adapter failed in issuing + +//***************************************************************************** +// %%% SRB - HOST ADAPTER INQUIRY - SC_HA_INQUIRY (0) %%% +//***************************************************************************** + +typedef struct // Offset +{ // HX/DEC + BYTE SRB_Cmd; // 00/000 ASPI command code = SC_HA_INQUIRY + BYTE SRB_Status; // 01/001 ASPI command status byte + BYTE SRB_HaId; // 02/002 ASPI host adapter number + BYTE SRB_Flags; // 03/003 ASPI request flags + DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0 + BYTE HA_Count; // 08/008 Number of host adapters present + BYTE HA_SCSI_ID; // 09/009 SCSI ID of host adapter + BYTE HA_ManagerId[16]; // 0A/010 String describing the manager + BYTE HA_Identifier[16]; // 1A/026 String describing the host adapter + BYTE HA_Unique[16]; // 2A/042 Host Adapter Unique parameters + WORD HA_Rsvd1; // 3A/058 Reserved, MUST = 0 +} +SRB_HAInquiry, *PSRB_HAInquiry, FAR *LPSRB_HAInquiry; + +//***************************************************************************** +// %%% SRB - GET DEVICE TYPE - SC_GET_DEV_TYPE (1) %%% +//***************************************************************************** + +typedef struct // Offset +{ // HX/DEC + BYTE SRB_Cmd; // 00/000 ASPI command code = SC_GET_DEV_TYPE + BYTE SRB_Status; // 01/001 ASPI command status byte + BYTE SRB_HaId; // 02/002 ASPI host adapter number + BYTE SRB_Flags; // 03/003 Reserved, MUST = 0 + DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0 + BYTE SRB_Target; // 08/008 Target's SCSI ID + BYTE SRB_Lun; // 09/009 Target's LUN number + BYTE SRB_DeviceType; // 0A/010 Target's peripheral device type + BYTE SRB_Rsvd1; // 0B/011 Reserved, MUST = 0 +} +SRB_GDEVBlock, *PSRB_GDEVBlock, FAR *LPSRB_GDEVBlock; + +//***************************************************************************** +// %%% SRB - EXECUTE SCSI COMMAND - SC_EXEC_SCSI_CMD (2) %%% +//***************************************************************************** + +typedef struct // Offset +{ // HX/DEC + BYTE SRB_Cmd; // 00/000 ASPI command code = SC_EXEC_SCSI_CMD + BYTE SRB_Status; // 01/001 ASPI command status byte + BYTE SRB_HaId; // 02/002 ASPI host adapter number + BYTE SRB_Flags; // 03/003 ASPI request flags + DWORD SRB_Hdr_Rsvd; // 04/004 Reserved + BYTE SRB_Target; // 08/008 Target's SCSI ID + BYTE SRB_Lun; // 09/009 Target's LUN number + WORD SRB_Rsvd1; // 0A/010 Reserved for Alignment + DWORD SRB_BufLen; // 0C/012 Data Allocation Length + BYTE FAR *SRB_BufPointer; // 10/016 Data Buffer Pointer + BYTE SRB_SenseLen; // 14/020 Sense Allocation Length + BYTE SRB_CDBLen; // 15/021 CDB Length + BYTE SRB_HaStat; // 16/022 Host Adapter Status + BYTE SRB_TargStat; // 17/023 Target Status + VOID FAR *SRB_PostProc; // 18/024 Post routine + BYTE SRB_Rsvd2[20]; // 1C/028 Reserved, MUST = 0 + BYTE CDBByte[16]; // 30/048 SCSI CDB + BYTE SenseArea[SENSE_LEN+2]; // 50/064 Request Sense buffer +} +SRB_ExecSCSICmd, *PSRB_ExecSCSICmd, FAR *LPSRB_ExecSCSICmd; + +//***************************************************************************** +// %%% SRB - ABORT AN SRB - SC_ABORT_SRB (3) %%% +//***************************************************************************** + +typedef struct // Offset +{ // HX/DEC + BYTE SRB_Cmd; // 00/000 ASPI command code = SC_ABORT_SRB + BYTE SRB_Status; // 01/001 ASPI command status byte + BYTE SRB_HaId; // 02/002 ASPI host adapter number + BYTE SRB_Flags; // 03/003 Reserved + DWORD SRB_Hdr_Rsvd; // 04/004 Reserved + VOID FAR *SRB_ToAbort; // 08/008 Pointer to SRB to abort +} +SRB_Abort, *PSRB_Abort, FAR *LPSRB_Abort; + +//***************************************************************************** +// %%% SRB - BUS DEVICE RESET - SC_RESET_DEV (4) %%% +//***************************************************************************** + +typedef struct // Offset +{ // HX/DEC + BYTE SRB_Cmd; // 00/000 ASPI command code = SC_RESET_DEV + BYTE SRB_Status; // 01/001 ASPI command status byte + BYTE SRB_HaId; // 02/002 ASPI host adapter number + BYTE SRB_Flags; // 03/003 ASPI request flags + DWORD SRB_Hdr_Rsvd; // 04/004 Reserved + BYTE SRB_Target; // 08/008 Target's SCSI ID + BYTE SRB_Lun; // 09/009 Target's LUN number + BYTE SRB_Rsvd1[12]; // 0A/010 Reserved for Alignment + BYTE SRB_HaStat; // 16/022 Host Adapter Status + BYTE SRB_TargStat; // 17/023 Target Status + VOID FAR *SRB_PostProc; // 18/024 Post routine + BYTE SRB_Rsvd2[36]; // 1C/028 Reserved, MUST = 0 +} +SRB_BusDeviceReset, *PSRB_BusDeviceReset, FAR *LPSRB_BusDeviceReset; + +//***************************************************************************** +// %%% SRB - GET DISK INFORMATION - SC_GET_DISK_INFO %%% +//***************************************************************************** + +typedef struct // Offset +{ // HX/DEC + BYTE SRB_Cmd; // 00/000 ASPI command code = SC_GET_DISK_INFO + BYTE SRB_Status; // 01/001 ASPI command status byte + BYTE SRB_HaId; // 02/002 ASPI host adapter number + BYTE SRB_Flags; // 03/003 Reserved, MUST = 0 + DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0 + BYTE SRB_Target; // 08/008 Target's SCSI ID + BYTE SRB_Lun; // 09/009 Target's LUN number + BYTE SRB_DriveFlags; // 0A/010 Driver flags + BYTE SRB_Int13HDriveInfo; // 0B/011 Host Adapter Status + BYTE SRB_Heads; // 0C/012 Preferred number of heads translation + BYTE SRB_Sectors; // 0D/013 Preferred number of sectors translation + BYTE SRB_Rsvd1[10]; // 0E/014 Reserved, MUST = 0 +} +SRB_GetDiskInfo, *PSRB_GetDiskInfo, FAR *LPSRB_GetDiskInfo; + +//***************************************************************************** +// %%% SRB - RESCAN SCSI BUS(ES) ON SCSIPORT %%% +//***************************************************************************** + +typedef struct // Offset +{ // HX/DEC + BYTE SRB_Cmd; // 00/000 ASPI command code = SC_RESCAN_SCSI_BUS + BYTE SRB_Status; // 01/001 ASPI command status byte + BYTE SRB_HaId; // 02/002 ASPI host adapter number + BYTE SRB_Flags; // 03/003 Reserved, MUST = 0 + DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0 +} +SRB_RescanPort, *PSRB_RescanPort, FAR *LPSRB_RescanPort; + +//***************************************************************************** +// %%% SRB - GET/SET TARGET TIMEOUTS %%% +//***************************************************************************** + +typedef struct // Offset +{ // HX/DEC + BYTE SRB_Cmd; // 00/000 ASPI command code = SC_GETSET_TIMEOUTS + BYTE SRB_Status; // 01/001 ASPI command status byte + BYTE SRB_HaId; // 02/002 ASPI host adapter number + BYTE SRB_Flags; // 03/003 ASPI request flags + DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0 + BYTE SRB_Target; // 08/008 Target's SCSI ID + BYTE SRB_Lun; // 09/009 Target's LUN number + DWORD SRB_Timeout; // 0A/010 Timeout in half seconds +} +SRB_GetSetTimeouts, *PSRB_GetSetTimeouts, FAR *LPSRB_GetSetTimeouts; + +//***************************************************************************** +// %%% ASPIBUFF - Structure For Controllng I/O Buffers %%% +//***************************************************************************** + +typedef struct tag_ASPI32BUFF // Offset +{ // HX/DEC + PBYTE AB_BufPointer; // 00/000 Pointer to the ASPI allocated buffer + DWORD AB_BufLen; // 04/004 Length in bytes of the buffer + DWORD AB_ZeroFill; // 08/008 Flag set to 1 if buffer should be zeroed + DWORD AB_Reserved; // 0C/012 Reserved +} +ASPI32BUFF, *PASPI32BUFF, FAR *LPASPI32BUFF; + +//***************************************************************************** +// %%% TOC structures %%% +//***************************************************************************** + +typedef struct +{ + unsigned char reserved1; + unsigned char cAdrCtrl; + unsigned char cTrackNum; + unsigned char reserved2; + unsigned long lAddr; +} TOC_TRACK; + +typedef struct +{ + unsigned short usTocDataLen; + unsigned char cFirstTrack; + unsigned char cLastTrack; + TOC_TRACK tracks[100]; +} TOC, *PTOC, FAR *LPTOC; + +//***************************************************************************** +// %%% PROTOTYPES - User Callable ASPI for Win32 Functions %%% +//***************************************************************************** + +typedef struct +{ + BYTE SRB_Cmd; + BYTE SRB_Status; + BYTE SRB_HaId; + BYTE SRB_Flags; + DWORD SRB_Hdr_Rsvd; +} SRB, *PSRB, FAR *LPSRB; + + +#if defined(__BORLANDC__) + +DWORD _import GetASPI32SupportInfo( void ); +DWORD _import SendASPI32Command( LPSRB ); +BOOL _import GetASPI32Buffer( PASPI32BUFF ); +BOOL _import FreeASPI32Buffer( PASPI32BUFF ); +BOOL _import TranslateASPI32Address( PDWORD, PDWORD ); + +#elif defined(_MSC_VER) + +__declspec(dllimport) DWORD GetASPI32SupportInfo( void ); +__declspec(dllimport) DWORD SendASPI32Command( LPSRB ); +__declspec(dllimport) BOOL GetASPI32Buffer( PASPI32BUFF ); +__declspec(dllimport) BOOL FreeASPI32Buffer( PASPI32BUFF ); +__declspec(dllimport) BOOL TranslateASPI32Address( PDWORD, PDWORD ); + +#else + +extern DWORD GetASPI32SupportInfo( void ); +extern DWORD GetASPI32Command( LPSRB ); +extern BOOL GetASPI32Buffer( PASPI32BUFF ); +extern BOOL FreeASPI32Buffer( PASPI32BUFF ); +extern BOOL TranslateASPI32Address( PDWORD, PDWORD ); + +#endif + +/* +** Restore compiler default packing and close off the C declarations. +*/ + +#ifdef __BORLANDC__ +#pragma option -a. +#endif //__BORLANDC__ + +#ifdef _MSC_VER +#pragma pack() +#endif //_MSC_VER + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__WNASPI32_H__ From 98659bac76ebe73ee6fd011caa8a7a24ee9711c9 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 6 Mar 2003 13:36:23 +0000 Subject: [PATCH 0640/4131] Mscdex driver Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@719 --- src/dos/dos_mscdex.cpp | 842 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 842 insertions(+) create mode 100644 src/dos/dos_mscdex.cpp diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp new file mode 100644 index 00000000..5986751a --- /dev/null +++ b/src/dos/dos_mscdex.cpp @@ -0,0 +1,842 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include "cpu.h" +#include "callback.h" +#include "dos_system.h" +#include "dos_inc.h" +#include "setup.h" + +#include "cdrom.h" + +#define MSCDEX_VERSION_HIGH 2 +#define MSCDEX_VERSION_LOW 23 +#define MSCDEX_MAX_DRIVES 5 + +// Error Codes +#define MSCDEX_ERROR_UNKNOWN_DRIVE 15 +#define MSCDEX_ERROR_DRIVE_NOT_READY 21 + +// Request Status +#define REQUEST_STATUS_DONE 0x0100 +#define REQUEST_STATUS_ERROR 0x8000 + +static Bitu MSCDEX_Strategy_Handler(void); +static Bitu MSCDEX_Interrupt_Handler(void); + +bool gUseASPI = false; + +class DOS_DeviceHeader:public MemStruct +{ +public: + DOS_DeviceHeader(PhysPt ptr) { pt = ptr; }; + + void SetNextDeviceHeader (RealPt ptr) { sSave(sDeviceHeader,nextDeviceHeader,ptr); }; + RealPt GetNextDeviceHeader (void) { return sGet(sDeviceHeader,nextDeviceHeader); }; + void SetAttribute (Bit16u atr) { sSave(sDeviceHeader,devAttributes,atr); }; + void SetDriveLetter (Bit8u letter) { sSave(sDeviceHeader,driveLetter,letter); }; + void SetNumSubUnits (Bit8u num) { sSave(sDeviceHeader,numSubUnits,num); }; + Bit8u GetNumSubUnits (void) { return sGet(sDeviceHeader,numSubUnits); }; + void SetName (char* _name) { MEM_BlockWrite(pt+offsetof(sDeviceHeader,name),_name,8); }; + void SetInterrupt (Bit16u ofs) { sSave(sDeviceHeader,interrupt,ofs); }; + void SetStrategy (Bit16u ofs) { sSave(sDeviceHeader,strategy,ofs); }; + +public: + #pragma pack(1) + struct sDeviceHeader{ + RealPt nextDeviceHeader; + Bit16u devAttributes; + Bit16u strategy; + Bit16u interrupt; + Bit8u name[8]; + Bit16u wReserved; + Bit8u driveLetter; + Bit8u numSubUnits; + } TDeviceHeader; + #pragma pack() +}; + +class CMscdex +{ +public: + CMscdex (void); + ~CMscdex (void); + + Bit16u GetVersion (void) { return (MSCDEX_VERSION_HIGH<<8)+MSCDEX_VERSION_LOW; }; + Bit16u GetNumDrives (void) { return numDrives; }; + Bit16u GetFirstDrive (void) { return dinfo[0].drive; }; + Bit8u GetSubUnit (Bit16u _drive); + bool GetUPC (Bit8u subUnit, Bit8u& attr, char* upc); + + bool PlayAudioSector (Bit8u subUnit, Bit32u start, Bit32u length); + bool PlayAudioMSF (Bit8u subUnit, Bit32u start, Bit32u length); + bool StopAudio (Bit8u subUnit); + bool GetAudioStatus (Bit8u subUnit, bool& playing, bool& pause, TMSF& start, TMSF& end); + + bool GetSubChannelData (Bit8u subUnit, Bit8u& attr, Bit8u& track, Bit8u &index, TMSF& rel, TMSF& abs); + + int AddDrive (Bit16u _drive, char* physicalPath, Bit8u& subUnit); + void GetDrives (PhysPt data); + void GetDriverInfo (PhysPt data); + bool GetCopyrightName (Bit16u drive, PhysPt data) { return false; }; + bool GetAbstractName (Bit16u drive, PhysPt data) { return false; }; + bool GetDocumentationName(Bit16u drive, PhysPt data) { return false; }; + bool ReadVTOC (Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error) { return false; }; + bool ReadSectors (Bit16u drive, Bit32u sector, Bit16u num, PhysPt data); + bool ReadSectors (Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data); + bool ReadSectorsMSF (Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data); + bool SendDriverRequest (Bit16u drive, PhysPt data); + bool IsValidDrive (Bit16u drive); + bool GetCDInfo (Bit8u subUnit, Bit8u& tr1, Bit8u& tr2, TMSF& leadOut); + Bit32u GetVolumeSize (Bit8u subUnit); + bool GetTrackInfo (Bit8u subUnit, Bit8u track, Bit8u& attr, TMSF& start); + Bit16u GetStatusWord (Bit8u subUnit); + bool GetCurrentPos (Bit8u subUnit, TMSF& pos); + Bit32u GetDeviceStatus (Bit8u subUnit); + bool GetMediaStatus (Bit8u subUnit, Bit8u& status); + bool LoadUnloadMedia (Bit8u subUnit, bool unload); + bool ResumeAudio (Bit8u subUnit); + bool GetMediaStatus (Bit8u subUnit, bool& media, bool& changed, bool& trayOpen); + +private: + + Bit16u numDrives; + + typedef struct SDriveInfo { + Bit8u drive; // drive letter in dosbox + Bit8u physDrive; // drive letter in system + bool audioPlay; // audio playing active + bool audioPaused; // audio playing paused + Bit32u audioStart; // StartLoc for resume + Bit32u audioEnd; // EndLoc for resume + bool locked; // drive locked ? + bool lastResult; // last operation success ? + Bit32u volumeSize; // for media change + } TDriveInfo; + + TDriveInfo dinfo[MSCDEX_MAX_DRIVES]; + CDROM_Interface* cdrom[MSCDEX_MAX_DRIVES]; + +public: + Bit16u rootDriverHeaderSeg; +}; + +CMscdex::CMscdex(void) +{ + numDrives = 0; + rootDriverHeaderSeg = 0; + + memset(dinfo,0,sizeof(dinfo)); + for (Bit32u i=0; i0)); + DOS_DeviceHeader devHeader(PhysMake(seg,0)); + devHeader.SetNextDeviceHeader (0xFFFFFFFF); + devHeader.SetDriveLetter ('A'+_drive); + devHeader.SetNumSubUnits (1); + devHeader.SetName ("MSCD001 "); + + // Create Callback Strategy + Bit16u off = sizeof(DOS_DeviceHeader::sDeviceHeader); + Bitu call_strategy=CALLBACK_Allocate(); + CallBack_Handlers[call_strategy]=MSCDEX_Strategy_Handler; + real_writeb(seg,off+0,(Bit8u)0xFE); //GRP 4 + real_writeb(seg,off+1,(Bit8u)0x38); //Extra Callback instruction + real_writew(seg,off+2,call_strategy); //The immediate word + real_writeb(seg,off+4,(Bit8u)0xCB); //A RETF Instruction + devHeader.SetStrategy(off); + + // Create Callback Interrupt + off += 5; + Bitu call_interrupt=CALLBACK_Allocate(); + CallBack_Handlers[call_interrupt]=MSCDEX_Interrupt_Handler; + real_writeb(seg,off+0,(Bit8u)0xFE); //GRP 4 + real_writeb(seg,off+1,(Bit8u)0x38); //Extra Callback instruction + real_writew(seg,off+2,call_interrupt); //The immediate word + real_writeb(seg,off+4,(Bit8u)0xCB); //A RETF Instruction + devHeader.SetInterrupt(off); + + rootDriverHeaderSeg = seg; + + } else { + // Error check, driveletter have to be in a row + if (dinfo[numDrives-1].drive+1!=_drive) return 1; + }; + + if (GetNumDrives()+14)) { + // WIN NT/200/XP + if (gUseASPI) { + cdrom[numDrives] = new CDROM_Interface_Aspi(); + DEBUG_ShowMsg(0,"MSCDEX: ASPI Interface."); + } else { + cdrom[numDrives] = new CDROM_Interface_Ioctl(); + DEBUG_ShowMsg(0,"MSCDEX: IOCTL Interface."); + } + } else { + // Win 95/98/ME - always use ASPI + cdrom[numDrives] = new CDROM_Interface_Aspi(); + DEBUG_ShowMsg(0,"MSCDEX: ASPI Interface."); + } + #else + cdrom[numDrives] = new CDROM_Interface_Linux(); + #endif + DEBUG_ShowMsg(0,"MSCDEX: Mounting physical cdrom: %s" ,physicalPath); + } break; + case 0x01 : // iso cdrom interface + // FIXME: Not yet supported + DEBUG_ShowMsg(0,"MSCDEX: Mounting iso file as cdrom: %s" ,physicalPath); + cdrom[numDrives] = new CDROM_Interface_Fake; + return 2; + break; + case 0x02 : // fake cdrom interface (directories) + cdrom[numDrives] = new CDROM_Interface_Fake; + DEBUG_ShowMsg(0,"MSCDEX: Mounting directory as cdrom: %s",physicalPath); + DEBUG_ShowMsg(0,"MSCDEX: You wont have full MSCDEX support !"); + result = 5; + break; + default : // weird result + return 6; + }; + if (!cdrom[numDrives]->SetDevice(physicalPath)) return 3; + subUnit = numDrives; + // Set drive + DOS_DeviceHeader devHeader(PhysMake(rootDriverHeaderSeg,0)); + devHeader.SetNumSubUnits(devHeader.GetNumSubUnits()+1); + dinfo[numDrives].drive = (Bit8u)_drive; + dinfo[numDrives].physDrive = toupper(physicalPath[0]); + numDrives++; + return result; + } + return 4; +}; + +void CMscdex::GetDriverInfo (PhysPt data) +{ + for (Bit16u i=0; iGetAudioTracks(tr1i,tr2i,leadOut); + if (!dinfo[subUnit].lastResult) { + tr1 = tr2 = 0; + memset(&leadOut,0,sizeof(leadOut)); + } else { + tr1 = (Bit8u) tr1i; + tr2 = (Bit8u) tr2i; + } + return dinfo[subUnit].lastResult; +} + +bool CMscdex::GetTrackInfo(Bit8u subUnit, Bit8u track, Bit8u& attr, TMSF& start) +{ + dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioTrackInfo(track,start,attr); + if (!dinfo[subUnit].lastResult) { + attr = 0; + memset(&start,0,sizeof(start)); + }; + return dinfo[subUnit].lastResult; +}; + +bool CMscdex::PlayAudioSector(Bit8u subUnit, Bit32u sector, Bit32u length) +{ + // If value from last stop is used, this is meant as a resume + // better start using resume command + if (dinfo[subUnit].audioPaused && (sector==dinfo[subUnit].audioStart)) { + dinfo[subUnit].lastResult = cdrom[subUnit]->PauseAudio(true); + } else + dinfo[subUnit].lastResult = cdrom[subUnit]->PlayAudioSector(sector,length); + + if (dinfo[subUnit].lastResult) { + dinfo[subUnit].audioPlay = true; + dinfo[subUnit].audioPaused = false; + dinfo[subUnit].audioStart = sector; + dinfo[subUnit].audioEnd = length; + }; + return dinfo[subUnit].lastResult; +}; + +bool CMscdex::PlayAudioMSF(Bit8u subUnit, Bit32u start, Bit32u length) +{ + Bit8u min = (start>>16) & 0xFF; + Bit8u sec = (start>> 8) & 0xFF; + Bit8u fr = (start>> 0) & 0xFF; + Bit32u sector = min*60*76+sec*75+fr - 150; + min = (length>>16) & 0xFF; + sec = (length>> 8) & 0xFF; + fr = (length>> 0) & 0xFF; + Bit32u seclen = min*60*76+sec*75+fr - 150; + return dinfo[subUnit].lastResult = PlayAudioSector(subUnit,sector,seclen); +}; + +bool CMscdex::GetSubChannelData(Bit8u subUnit, Bit8u& attr, Bit8u& track, Bit8u &index, TMSF& rel, TMSF& abs) +{ + dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioSub(attr,track,index,rel,abs); + if (!dinfo[subUnit].lastResult) { + attr = track = index = 0; + memset(&rel,0,sizeof(rel)); + memset(&abs,0,sizeof(abs)); + }; + return dinfo[subUnit].lastResult; +}; + +bool CMscdex::GetAudioStatus(Bit8u subUnit, bool& playing, bool& pause, TMSF& start, TMSF& end) +{ + dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioStatus(playing,pause); + if (dinfo[subUnit].lastResult) { + // Start + Bit32u addr = dinfo[subUnit].audioStart + 150; + start.fr = (Bit8u)(addr%75); addr/=75; + start.sec = (Bit8u)(addr%60); + start.min = (Bit8u)(addr/60); + // End + addr = dinfo[subUnit].audioEnd + 150; + end.fr = (Bit8u)(addr%75); addr/=75; + end.sec = (Bit8u)(addr%60); + end.min = (Bit8u)(addr/60); + } else { + playing = false; + pause = false; + memset(&start,0,sizeof(start)); + memset(&end,0,sizeof(end)); + }; + + return dinfo[subUnit].lastResult; +}; + +bool CMscdex::StopAudio(Bit8u subUnit) +{ + if (dinfo[subUnit].audioPlay) dinfo[subUnit].lastResult = cdrom[subUnit]->PauseAudio(false); + else dinfo[subUnit].lastResult = cdrom[subUnit]->StopAudio(); + + if (dinfo[subUnit].lastResult) { + if (dinfo[subUnit].audioPlay) { + TMSF pos; + GetCurrentPos(subUnit,pos); + dinfo[subUnit].audioStart = pos.min*60*76+pos.sec*75+pos.fr - 150; + dinfo[subUnit].audioPaused = true; + } else { + dinfo[subUnit].audioPaused = false; + dinfo[subUnit].audioStart = 0; + dinfo[subUnit].audioEnd = 0; + }; + dinfo[subUnit].audioPlay = false; + }; + return dinfo[subUnit].lastResult; +}; + +bool CMscdex::ResumeAudio(Bit8u subUnit) +{ + return dinfo[subUnit].lastResult = PlayAudioSector(subUnit,dinfo[subUnit].audioStart,dinfo[subUnit].audioEnd); +}; + +Bit32u CMscdex::GetVolumeSize(Bit8u subUnit) +{ + Bit8u tr1,tr2; + TMSF leadOut; + dinfo[subUnit].lastResult = GetCDInfo(subUnit,tr1,tr2,leadOut); + if (dinfo[subUnit].lastResult) return (leadOut.min*60*75)+(leadOut.sec*75)+leadOut.fr; + return 0; +}; + +bool CMscdex::GetUPC(Bit8u subUnit, Bit8u& attr, char* upc) +{ + return dinfo[subUnit].lastResult = cdrom[subUnit]->GetUPC(attr,&upc[0]); +}; + +bool CMscdex::ReadSectors(Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data) +{ + void* buffer = (void*)Phys2Host(data); + dinfo[subUnit].lastResult = cdrom[subUnit]->ReadSectors(buffer,raw,sector,num); + return dinfo[subUnit].lastResult; +}; + +bool CMscdex::ReadSectorsMSF(Bit8u subUnit, bool raw, Bit32u start, Bit16u num, PhysPt data) +{ + Bit8u min = (start>>16) & 0xFF; + Bit8u sec = (start>> 8) & 0xFF; + Bit8u fr = (start>> 0) & 0xFF; + Bit32u sector = min*60*76+sec*75+fr - 150; + // TODO: Check, if num has to be converted too ?! + return ReadSectors(subUnit,raw,sector,num,data); +}; + +bool CMscdex::ReadSectors(Bit16u drive, Bit32u sector, Bit16u num, PhysPt data) +// Called from INT 2F +{ + return ReadSectors(GetSubUnit(drive),false,sector,num,data); +}; + +bool CMscdex::GetCurrentPos(Bit8u subUnit, TMSF& pos) +{ + TMSF rel; + Bit8u attr,track,index; + dinfo[subUnit].lastResult = GetSubChannelData(subUnit, attr, track, index, rel, pos); + if (!dinfo[subUnit].lastResult) memset(&pos,0,sizeof(pos)); + return dinfo[subUnit].lastResult; +}; + +bool CMscdex::GetMediaStatus(Bit8u subUnit, bool& media, bool& changed, bool& trayOpen) +{ + dinfo[subUnit].lastResult = cdrom[subUnit]->GetMediaTrayStatus(media,changed,trayOpen); + return dinfo[subUnit].lastResult; +}; + +Bit32u CMscdex::GetDeviceStatus(Bit8u subUnit) +{ + bool media,changed,trayOpen; + + dinfo[subUnit].lastResult = GetMediaStatus(subUnit,media,changed,trayOpen); + Bit32u status = (trayOpen << 0) | // Drive is open ? + (dinfo[subUnit].locked << 1) | // Drive is locked ? + (1<<2) | // raw + cooked sectors + (1<<4) | // Can read sudio + (1<<9) | // Red book & HSG + ((!media) << 11); // Drive is empty ? + return status; +}; + +bool CMscdex::GetMediaStatus(Bit8u subUnit, Bit8u& status) +{ + bool media,changed,open,result; + result = GetMediaStatus(subUnit,media,changed,open); + status = changed ? 0xFF : 0x01; + return result; +}; + +bool CMscdex::LoadUnloadMedia(Bit8u subUnit, bool unload) +{ + dinfo[subUnit].lastResult = cdrom[subUnit]->LoadUnloadMedia(unload); + return dinfo[subUnit].lastResult; +}; + +bool CMscdex::SendDriverRequest(Bit16u drive, PhysPt data) +{ + // Get SubUnit + mem_writeb(data+1,GetSubUnit(drive)); + // Call Strategy / Interrupt + MSCDEX_Strategy_Handler(); + MSCDEX_Interrupt_Handler(); + return true; +}; + +Bit16u CMscdex::GetStatusWord(Bit8u subUnit) +{ + Bit16u status ; + if (dinfo[subUnit].lastResult) status = REQUEST_STATUS_DONE; // ok + else { + status = REQUEST_STATUS_ERROR | 0x02; // error : Drive not ready + } + + if (dinfo[subUnit].audioPlay) { + // Check if audio is still playing.... + TMSF start,end; + bool playing,pause; + if (GetAudioStatus(subUnit,playing,pause,start,end)) { + dinfo[subUnit].audioPlay = playing; + } else + dinfo[subUnit].audioPlay = false; + + status |= (dinfo[subUnit].audioPlay<<9); + } + dinfo[subUnit].lastResult = true; + return status; +}; + +static CMscdex* mscdex = 0; + +static Bitu MSCDEX_Strategy_Handler(void) +{ +// DEBUG_ShowMsg("MSCDEX: Device Strategy Routine called."); + return CBRET_NONE; +} + +static Bitu MSCDEX_Interrupt_Handler(void) +{ +// DEBUG_ShowMsg("MSCDEX: Device Interrupt Routine called."); + + Bit8u subFuncNr = 0xFF; + PhysPt data = PhysMake(SegValue(es),reg_bx); + Bit8u subUnit = mem_readb(data+1); + Bit8u funcNr = mem_readb(data+2); + +// if (funcNr!=0x03) DEBUG_ShowMsg("MSCDEX: Driver Function %02X",funcNr); + + switch (funcNr) { + + case 0x03 : { /* IOCTL INPUT */ + PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); + subFuncNr = mem_readb(buffer); + //if (subFuncNr!=0x0B) DEBUG_ShowMsg("MSCDEX: IOCTL INPUT Subfunction %02X",subFuncNr); + switch (subFuncNr) { + case 0x00 : /* Get Device Header address */ + mem_writed(buffer+1,RealMake(mscdex->rootDriverHeaderSeg,0)); + break; + case 0x01 :{/* Get current position */ + TMSF pos; + mscdex->GetCurrentPos(subUnit,pos); + mem_writeb(buffer+1,0x01); // Red book + mem_writeb(buffer+2,pos.fr); + mem_writeb(buffer+3,pos.sec); + mem_writeb(buffer+4,pos.min); + mem_writeb(buffer+5,0x00); + }break; + case 0x06 : /* Get Device status */ + mem_writed(buffer+1,mscdex->GetDeviceStatus(subUnit)); + break; + case 0x07 : /* Get sector size */ + if (mem_readb(buffer+1)==0x01) mem_writed(buffer+2,2352); + else mem_writed(buffer+2,2048); + break; + case 0x08 : /* Get size of current volume */ + mem_writed(buffer+1,mscdex->GetVolumeSize(subUnit)); + break; + case 0x09 : /* Media change ? */ + Bit8u status; + mscdex->GetMediaStatus(subUnit,status); + mem_writeb(buffer+1,status); + break; + case 0x0A : /* Get Audio Disk info */ + Bit8u tr1,tr2; TMSF leadOut; + mscdex->GetCDInfo(subUnit,tr1,tr2,leadOut); + mem_writeb(buffer+1,tr1); + mem_writeb(buffer+2,tr2); + mem_writeb(buffer+3,leadOut.fr); + mem_writeb(buffer+4,leadOut.sec); + mem_writeb(buffer+5,leadOut.min); + mem_writeb(buffer+6,0x00); + break; + case 0x0B :{/* Audio Track Info */ + Bit8u attr; TMSF start; + Bit8u track = mem_readb(buffer+1); + mscdex->GetTrackInfo(subUnit,track,attr,start); + mem_writeb(buffer+2,start.fr); + mem_writeb(buffer+3,start.sec); + mem_writeb(buffer+4,start.min); + mem_writeb(buffer+5,0x00); + mem_writeb(buffer+6,attr); + break; }; + case 0x0C :{/* Get Audio Sub Channel data */ + Bit8u attr,track,index; + TMSF abs,rel; + mscdex->GetSubChannelData(subUnit,attr,track,index,rel,abs); + mem_writeb(buffer+1,attr); + mem_writeb(buffer+2,track); + mem_writeb(buffer+3,index); + mem_writeb(buffer+4,rel.min); + mem_writeb(buffer+5,rel.sec); + mem_writeb(buffer+6,rel.fr); + mem_writeb(buffer+7,0x00); + mem_writeb(buffer+8,abs.min); + mem_writeb(buffer+9,abs.sec); + mem_writeb(buffer+10,abs.fr); + break; + }; + case 0x0E :{ /* Get UPC */ + Bit8u attr; char upc[8]; + mscdex->GetUPC(subUnit,attr,&upc[0]); + mem_writeb(buffer+1,attr); + for (int i=0; i<7; i++) mem_writeb(buffer+2+i,upc[i]); + mem_writeb(buffer+9,0x00); + break; + }; + case 0x0F :{ /* Get Audio Status */ + bool playing,pause; + TMSF resStart,resEnd; + mscdex->GetAudioStatus(subUnit,playing,pause,resStart,resEnd); + mem_writeb(buffer+1,pause); + mem_writeb(buffer+3,resStart.min); + mem_writeb(buffer+4,resStart.sec); + mem_writeb(buffer+5,resStart.fr); + mem_writeb(buffer+6,0x00); + mem_writeb(buffer+7,resEnd.min); + mem_writeb(buffer+8,resEnd.sec); + mem_writeb(buffer+9,resEnd.fr); + mem_writeb(buffer+10,0x00); + break; + }; + default : LOG(LOG_ERROR|LOG_MISC,"MSCDEX: Unsupported IOCTL INPUT Subfunction %02X",subFuncNr); + break; + } + break; + }; + case 0x0C : { /* IOCTL OUTPUT */ + PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); + subFuncNr = mem_readb(buffer); + // if (subFuncNr!=0x0B) DEBUG_ShowMsg("MSCDEX: IOCTL OUTPUT Subfunction %02X",subFuncNr); + switch (subFuncNr) { + case 0x00 : // Unload /eject) media + mscdex->LoadUnloadMedia(subUnit,true); + break; + case 0x01 : // (un)Lock door + // do nothing -> report as success + break; + case 0x05 : // load media + mscdex->LoadUnloadMedia(subUnit,false); + break; + default : LOG(LOG_ERROR|LOG_MISC,"MSCDEX: Unsupported IOCTL OUTPUT Subfunction %02X",subFuncNr); + break; + }; + break; + }; + case 0x0D : // device open + case 0x0E : // device close - dont care :) + break; + case 0x80 : // Read long + case 0x82 : { // Read long prefetch -> both the same here :) + PhysPt buff = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); + Bit32u start = mem_readd(data+0x14); + Bit16u len = mem_readw(data+0x12); + bool raw = (mem_readb(data+0x18)==1); + if (mem_readb(data+0x0D)==0x00) // HSG + mscdex->ReadSectors(subUnit,raw,start,len,buff); + else + mscdex->ReadSectorsMSF(subUnit,raw,start,len,buff); + break; + }; + case 0x83 : // Seek - dont care :) + break; + case 0x84 : { /* Play Audio Sectors */ + Bit32u start = mem_readd(data+0x0E); + Bit32u len = mem_readd(data+0x12); + if (mem_readb(data+0x0D)==0x00) // HSG + mscdex->PlayAudioSector(subUnit,start,len); + else // RED BOOK + mscdex->PlayAudioMSF(subUnit,start,len); + break; + }; + case 0x85 : /* Stop Audio */ + mscdex->StopAudio(subUnit); + break; + case 0x88 : /* Resume Audio */ + mscdex->ResumeAudio(subUnit); + break; + default : LOG(LOG_ERROR|LOG_MISC,"MSCDEX: Unsupported Driver Request %02X",funcNr); + break; + + }; + + // Set Statusword + mem_writew(data+3,mscdex->GetStatusWord(subUnit)); + return CBRET_NONE; +} + +static bool MSCDEX_Handler(void) +{ + if (reg_ah!=0x15) return false; + + PhysPt data = PhysMake(SegValue(es),reg_bx); +// if (reg_ax!=0x1510) DEBUG_ShowMsg("MSCEEX: INT 2F %04X",reg_ax); + switch (reg_ax) { + + case 0x1500: /* Install check */ + reg_bx = mscdex->GetNumDrives(); + if (reg_bx>0) reg_cx = mscdex->GetFirstDrive(); + return true; + case 0x1501: /* Get cdrom driver info */ + mscdex->GetDriverInfo(data); + return true; + case 0x1502: /* Get Copyright filename */ + if (mscdex->GetCopyrightName(reg_cx,data)) { + CALLBACK_SCF(false); + } else { + reg_al = MSCDEX_ERROR_UNKNOWN_DRIVE; + CALLBACK_SCF(true); + }; + return true; + case 0x1503: /* Get Abstract filename */ + if (mscdex->GetAbstractName(reg_cx,data)) { + CALLBACK_SCF(false); + } else { + reg_al = MSCDEX_ERROR_UNKNOWN_DRIVE; + CALLBACK_SCF(true); + }; + return true; + case 0x1504: /* Get Documentation filename */ + if (mscdex->GetDocumentationName(reg_cx,data)) { + CALLBACK_SCF(false); + } else { + reg_al = MSCDEX_ERROR_UNKNOWN_DRIVE; + CALLBACK_SCF(true); + }; + return true; +/* case 0x1505: { // read vtoc + Bit16u error = 0; + if (mscdex->ReadVTOC(reg_cx,reg_dx,data,error)) { + CALLBACK_SCF(false); + } else { + reg_ax = error; + CALLBACK_SCF(true); + }; + }; + return true;*/ + case 0x1508: { // read sectors + Bit32u sector = (reg_si<<16)+reg_di; + if (mscdex->ReadSectors(reg_cx,sector,reg_dx,data)) { + CALLBACK_SCF(false); + } else { + reg_al = MSCDEX_ERROR_UNKNOWN_DRIVE; + CALLBACK_SCF(true); + }; + return true; + }; + case 0x1509: // write sectors - not supported + reg_al = MSCDEX_ERROR_DRIVE_NOT_READY; + CALLBACK_SCF(true); + return true; + case 0x150B: /* Valid CDROM drive ? */ + reg_ax = mscdex->IsValidDrive(reg_cx); + reg_bx = 0xADAD; + return true; + case 0x150C: /* Get MSCDEX Version */ + reg_bx = mscdex->GetVersion(); + return true; + case 0x150D: /* Get drives */ + mscdex->GetDrives(data); + return true; + case 0x1510: /* Device driver request */ + mscdex->SendDriverRequest(reg_cx,data); + return true; + default : LOG(LOG_ERROR|LOG_MISC,"MSCDEX: Unknwon call : %04X",reg_ax); + return true; + + }; + return false; +}; + +class device_MSCDEX : public DOS_Device { +public: + device_MSCDEX() { name="MSCD001"; } + bool Read (Bit8u * data,Bit16u * size) { return false;} + bool Write(Bit8u * data,Bit16u * size) { + DEBUG_ShowMsg(0,"Write to mscdex device"); + return false; + } + bool Seek(Bit32u * pos,Bit32u type){return false;} + bool Close(){return false;} + Bit16u GetInformation(void){return 0x8093;} +private: + Bit8u cache; +}; + +int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit) +{ + int result = mscdex->AddDrive(driveLetter-'A',(char*)physicalPath,subUnit); + return result; +}; + +bool MSCDEX_HasMediaChanged(Bit8u subUnit) +{ + static TMSF leadOut[MSCDEX_MAX_DRIVES]; + + TMSF leadnew; + Bit8u tr1,tr2; + if (mscdex->GetCDInfo(subUnit,tr1,tr2,leadnew)) { + bool changed = (leadOut[subUnit].min!=leadnew.min) || (leadOut[subUnit].sec!=leadnew.sec) || (leadOut[subUnit].fr!=leadnew.fr); + leadOut[subUnit].min = leadnew.min; + leadOut[subUnit].sec = leadnew.sec; + leadOut[subUnit].fr = leadnew.fr; + return changed; + }; + if (subUnitAddDestroyFunction(&MSCDEX_ShutDown); + /* Register the mscdex device */ + DOS_Device * newdev = new device_MSCDEX(); + DOS_AddDevice(newdev); + /* Add Multiplexer */ + DOS_AddMultiplexHandler(MSCDEX_Handler); + /* Create MSCDEX */ + mscdex = new CMscdex; +}; + From 8b2daec2b884dec9f9c105702d224dd15268b149 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 6 Mar 2003 13:38:13 +0000 Subject: [PATCH 0641/4131] Added virtual func SetDir in class DOS_Drive Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@720 --- include/dos_system.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dos_system.h b/include/dos_system.h index c7012ecf..c7bc88bd 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -96,6 +96,7 @@ public: virtual bool FileExists(const char* name)=0; virtual bool FileStat(const char* name, FileStat_Block * const stat_block)=0; virtual Bit8u GetMediaByte(void)=0; + virtual void SetDir(const char* path) { strcpy(curdir,path); }; char * GetInfo(void); char curdir[DOS_PATHLENGTH]; char info[256]; From 43736fe92d24e25d8d56719fc0f973cd0ad3d557 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 6 Mar 2003 13:40:20 +0000 Subject: [PATCH 0642/4131] fixed a few warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@721 --- src/misc/support.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/misc/support.cpp b/src/misc/support.cpp index f9509eb3..dd9a9bf2 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -85,7 +85,7 @@ char *trim(char *str) { bool ScanCMDBool(char * cmd,char * check) { char * scan=cmd;size_t c_len=strlen(check); - while (scan=strchr(scan,'/')) { + while ((scan=strchr(scan,'/'))) { /* found a / now see behind it */ scan++; if (strncasecmp(scan,check,c_len)==0 && (scan[c_len]==' ' || scan[c_len]==0)) { @@ -101,7 +101,7 @@ bool ScanCMDBool(char * cmd,char * check) { bool ScanCMDHex(char * cmd,char * check,Bits * result) { char * scan=cmd;size_t c_len=strlen(check); - while (scan=strchr(scan,'/')) { + while ((scan=strchr(scan,'/'))) { /* found a / now see behind it */ scan++; if (strncasecmp(scan,check,c_len)==0 && (scan[c_len]==' ' || scan[c_len]==0)) { @@ -125,7 +125,7 @@ bool ScanCMDHex(char * cmd,char * check,Bits * result) { /* This scans the command line for a remaining switch and reports it else returns 0*/ char * ScanCMDRemain(char * cmd) { char * scan,*found;; - if (scan=found=strchr(cmd,'/')) { + if ((scan=found=strchr(cmd,'/'))) { while (*scan!=' ' && *scan!=0) scan++; *scan=0; return found; From e2b62d23d0ab7d1973b168383bbda4848f5d5390 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 6 Mar 2003 13:49:07 +0000 Subject: [PATCH 0643/4131] Added cdrom.h cdrom.cpp cdrom_ioctl.cpp dos_mscdex.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@722 --- src/dos/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/Makefile.am b/src/dos/Makefile.am index 8bc84fc8..ea8f9ad6 100644 --- a/src/dos/Makefile.am +++ b/src/dos/Makefile.am @@ -4,4 +4,4 @@ noinst_LIBRARIES = libdos.a libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioctl.cpp dos_memory.cpp \ dos_misc.cpp dos_classes.cpp dos_programs.cpp dos_tables.cpp \ drives.cpp drives.h drive_virtual.cpp drive_local.cpp \ - dev_con.h drive_cache.cpp + dev_con.h drive_cache.cpp cdrom.h cdrom.cpp cdrom_ioctl.cpp dos_mscdex.cpp From 6558efe97efe3e527e3ca7e2475a14297df772b5 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 6 Mar 2003 14:29:43 +0000 Subject: [PATCH 0644/4131] Improved ioctl support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@723 --- src/dos/cdrom.h | 9 ++- src/dos/cdrom_ioctl.cpp | 140 ++++++++++++++++++++++++++++++++-------- 2 files changed, 122 insertions(+), 27 deletions(-) diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index 306dad7d..463945ac 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -138,6 +138,10 @@ public: private: + bool Open (void); + void Close (void); + + char pathname[32]; HANDLE hIOCTL; TMSF oldLeadOut; }; @@ -169,11 +173,14 @@ public: bool LoadUnloadMedia (bool unload); private: + bool Open (void); + void Close (void); + char pathname[64]; int dhandle; TMSF oldLeadOut; }; #endif /* linux */ -#endif /* __CDROM_INTERFACE__ */ \ No newline at end of file +#endif /* __CDROM_INTERFACE__ */ diff --git a/src/dos/cdrom_ioctl.cpp b/src/dos/cdrom_ioctl.cpp index 942dc9a7..92459800 100644 --- a/src/dos/cdrom_ioctl.cpp +++ b/src/dos/cdrom_ioctl.cpp @@ -24,12 +24,14 @@ #include #include #include +#include #include #include "cdrom.h" CDROM_Interface_Linux::CDROM_Interface_Linux(void) { + pathname[0] = 0; memset(&oldLeadOut,0,sizeof(oldLeadOut)); }; @@ -37,21 +39,39 @@ CDROM_Interface_Linux::~CDROM_Interface_Linux(void) { // Stop Audio, if neccessary StopAudio(); - close(dhandle); }; bool CDROM_Interface_Linux::SetDevice(char* path) { - dhandle = open(path,O_RDONLY|O_NONBLOCK); + strcpy(pathname,path); + if (Open()) { + Close(); + return true; + }; + return false; +}; + +bool CDROM_Interface_Linux::Open(void) +{ + dhandle = open(pathname,O_RDONLY|O_NONBLOCK); return (dhandle>=0); }; +void CDROM_Interface_Ioctl::Close(void) +{ + close (dhandle); +}; + bool CDROM_Interface_Linux::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut) { struct cdrom_tochdr header; + Open(); /* read the header information */ - if (ioctl(dhandle, CDROMREADTOCHDR, &header) != 0) return false; + if (ioctl(dhandle, CDROMREADTOCHDR, &header) != 0) { + Close(); + return false; + } /* store the resulting information */ stTrack = header.cdth_trk0; /* you can assume this to be zero */ @@ -63,23 +83,31 @@ bool CDROM_Interface_Linux::GetAudioTracks(int& stTrack, int& endTrack, TMSF& le entry.cdte_track = CDROM_LEADOUT; /* find the address of the leadout track */ entry.cdte_format = CDROM_MSF; /* choose MSF addressing */ - if (ioctl(dhandle, CDROMREADTOCENTRY,&entry)!=0) return false; + if (ioctl(dhandle, CDROMREADTOCENTRY,&entry)!=0) { + Close(); + return false; + } leadOut.min = entry.cdte_addr.msf.minute; leadOut.sec = entry.cdte_addr.msf.second; leadOut.fr = entry.cdte_addr.msf.frame; + Close(); return false; }; bool CDROM_Interface_Linux::GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr) { + Open(); struct cdrom_tocentry entry; entry.cdte_track = track; /* find the address of the first track */ entry.cdte_format = CDROM_MSF; /* choose MSF addressing */ - if (ioctl(dhandle, CDROMREADTOCENTRY,&entry)!=0) return false; + if (ioctl(dhandle, CDROMREADTOCENTRY,&entry)!=0) { + Close(); + return false; + } /* attribtute */ attr = (entry.cdte_adr<<4) | entry.cdte_ctrl; @@ -87,6 +115,8 @@ bool CDROM_Interface_Linux::GetAudioTrackInfo (int track, TMSF& start, unsigned start.min = entry.cdte_addr.msf.minute; start.sec = entry.cdte_addr.msf.second; start.fr = entry.cdte_addr.msf.frame; + + Close(); return true; }; @@ -95,26 +125,40 @@ bool CDROM_Interface_Linux::PlayAudioSector(unsigned long start,unsigned long le struct cdrom_blk addr; addr.from = start; addr.len = len; - return (ioctl(dhandle, CDROMPLAYBLK, &addr)==0); + Open(); + bool res = (ioctl(dhandle, CDROMPLAYBLK, &addr)==0); + Close(); + return res; } bool CDROM_Interface_Linux::StopAudio(void) { - return (ioctl(dhandle,CDROMSTOP,0)==0); + Open(); + bool res = (ioctl(dhandle,CDROMSTOP,0)==0); + Close(); + return res; }; bool CDROM_Interface_Linux::PauseAudio(bool resume) { - if (resume) return (ioctl(dhandle, CDROMRESUME,0)==0); - else return (ioctl(dhandle, CDROMPAUSE,0)==0); + Open(); + bool res = false; + if (resume) res = (ioctl(dhandle, CDROMRESUME,0)==0); + else res = (ioctl(dhandle, CDROMPAUSE,0)==0); + Close(); + return res; }; bool CDROM_Interface_Linux::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) { struct cdrom_subchnl sub; + Open(); sub.cdsc_format = CDROM_MSF; - if (ioctl(dhandle, CDROMSUBCHNL, &sub)!=0) return false; + if (ioctl(dhandle, CDROMSUBCHNL, &sub)!=0) { + Close(); + return false; + } /* attribute */ attr = (sub.cdsc_adr<<4) | sub.cdsc_ctrl; @@ -126,30 +170,42 @@ bool CDROM_Interface_Linux::GetAudioSub(unsigned char& attr, unsigned char& trac absPos.fr = sub.cdsc_reladdr.msf.frame; absPos.sec = sub.cdsc_reladdr.msf.second; absPos.min = sub.cdsc_reladdr.msf.minute; + Close(); return true; }; bool CDROM_Interface_Linux::GetUPC(unsigned char& attr, char* upcdata) { - return (ioctl(dhandle, CDROM_GET_UPC, (void*)upcdata)==0); + Open(); + bool res = (ioctl(dhandle, CDROM_GET_UPC, (void*)upcdata)==0); + Close(); + return res; }; bool CDROM_Interface_Linux::GetAudioStatus(bool& playing, bool& pause) { + Open(); struct cdrom_subchnl sub; sub.cdsc_format = CDROM_MSF; - if (ioctl(dhandle, CDROMSUBCHNL, &sub)!=0) return false; + if (ioctl(dhandle, CDROMSUBCHNL, &sub)!=0) { + Close(); + return false; + }; playing = (sub.cdsc_audiostatus==CDROM_AUDIO_PLAY); pause = (sub.cdsc_audiostatus==CDROM_AUDIO_PAUSED); + Close(); return true; }; bool CDROM_Interface_Linux::LoadUnloadMedia(bool unload) { - return (ioctl(dhandle, CDROMEJECT,0)==0); + Open(); + bool res = (ioctl(dhandle, CDROMEJECT,0)==0); + Close(); + return res; }; bool CDROM_Interface_Linux::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) @@ -202,6 +258,7 @@ int CDROM_GetMountType(char* path) CDROM_Interface_Ioctl::CDROM_Interface_Ioctl() { + pathname[0] = 0; hIOCTL = INVALID_HANDLE_VALUE; memset(&oldLeadOut,0,sizeof(oldLeadOut)); }; @@ -209,7 +266,6 @@ CDROM_Interface_Ioctl::CDROM_Interface_Ioctl() CDROM_Interface_Ioctl::~CDROM_Interface_Ioctl() { StopAudio(); - CloseHandle(hIOCTL); }; bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc) @@ -220,10 +276,12 @@ bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc) bool CDROM_Interface_Ioctl::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut) { + Open(); CDROM_TOC toc; DWORD byteCount; BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), &byteCount,NULL); + Close(); if (!bStat) return false; stTrack = toc.FirstTrack; @@ -236,10 +294,12 @@ bool CDROM_Interface_Ioctl::GetAudioTracks(int& stTrack, int& endTrack, TMSF& le bool CDROM_Interface_Ioctl::GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr) { + Open(); CDROM_TOC toc; DWORD byteCount; BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), &byteCount,NULL); + Close(); if (!bStat) return false; attr = (toc.TrackData[track-1].Adr << 4) | toc.TrackData[track].Control; @@ -251,6 +311,8 @@ bool CDROM_Interface_Ioctl::GetAudioTrackInfo(int track, TMSF& start, unsigned c bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) { + Open(); + CDROM_SUB_Q_DATA_FORMAT insub; SUB_Q_CHANNEL_DATA sub; DWORD byteCount; @@ -259,6 +321,7 @@ bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& trac BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), &byteCount,NULL); + Close(); if (!bStat) return false; attr = (sub.CurrentPosition.ADR << 4) | sub.CurrentPosition.Control; @@ -270,11 +333,14 @@ bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& trac absPos.min = sub.CurrentPosition.AbsoluteAddress[1]; absPos.sec = sub.CurrentPosition.AbsoluteAddress[2]; absPos.fr = sub.CurrentPosition.AbsoluteAddress[3]; + return true; }; bool CDROM_Interface_Ioctl::GetAudioStatus(bool& playing, bool& pause) { + Open(); + CDROM_SUB_Q_DATA_FORMAT insub; SUB_Q_CHANNEL_DATA sub; DWORD byteCount; @@ -283,6 +349,7 @@ bool CDROM_Interface_Ioctl::GetAudioStatus(bool& playing, bool& pause) BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), &byteCount,NULL); + Close(); if (!bStat) return false; playing = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_IN_PROGRESS); @@ -310,6 +377,7 @@ bool CDROM_Interface_Ioctl::GetMediaTrayStatus(bool& mediaPresent, bool& mediaCh bool CDROM_Interface_Ioctl::PlayAudioSector (unsigned long start,unsigned long len) { + Open(); CDROM_PLAY_AUDIO_MSF audio; DWORD byteCount; // Start @@ -325,37 +393,44 @@ bool CDROM_Interface_Ioctl::PlayAudioSector (unsigned long start,unsigned long l BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PLAY_AUDIO_MSF, &audio, sizeof(audio), NULL, 0, &byteCount,NULL); + Close(); return bStat>0; }; bool CDROM_Interface_Ioctl::PauseAudio(bool resume) { + Open(); BOOL bStat; DWORD byteCount; if (resume) bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RESUME_AUDIO, NULL, 0, NULL, 0, &byteCount,NULL); else bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PAUSE_AUDIO, NULL, 0, NULL, 0, &byteCount,NULL); + Close(); return bStat>0; }; bool CDROM_Interface_Ioctl::StopAudio(void) { + Open(); BOOL bStat; DWORD byteCount; bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_STOP_AUDIO, NULL, 0, NULL, 0, &byteCount,NULL); + Close(); return bStat>0; }; bool CDROM_Interface_Ioctl::LoadUnloadMedia(bool unload) { + Open(); BOOL bStat; DWORD byteCount; if (unload) bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &byteCount,NULL); else bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, &byteCount,NULL); + Close(); return bStat>0; }; @@ -396,23 +471,36 @@ bool CDROM_Interface_Ioctl::ReadSectors(void* buffer, bool raw, unsigned long se bool CDROM_Interface_Ioctl::SetDevice(char* path) { if (GetDriveType(path)==DRIVE_CDROM) { - char buffer [256]; char letter [3] = { 0, ':', 0 }; letter[0] = path[0]; - strcpy(buffer,"\\\\.\\"); - strcat(buffer,letter); - hIOCTL = CreateFile(buffer, // drive to open - GENERIC_READ, // read access - FILE_SHARE_READ | // share mode - FILE_SHARE_WRITE, - NULL, // default security attributes - OPEN_EXISTING, // disposition - 0, // file attributes - NULL); // do not copy file attributes - return (hIOCTL!=INVALID_HANDLE_VALUE); + strcpy(pathname,"\\\\.\\"); + strcat(pathname,letter); + if (Open()) { + Close(); + return true; + }; } return false; +} + +bool CDROM_Interface_Ioctl::Open(void) +{ + hIOCTL = CreateFile(pathname, // drive to open + GENERIC_READ, // read access + FILE_SHARE_READ | // share mode + FILE_SHARE_WRITE, + NULL, // default security attributes + OPEN_EXISTING, // disposition + 0, // file attributes + NULL); // do not copy file attributes + return (hIOCTL!=INVALID_HANDLE_VALUE); }; + +void CDROM_Interface_Ioctl::Close(void) +{ + CloseHandle(hIOCTL); +}; + /* int CDROM_GetMountType(char* path) // 0 - physical CDROM From 14dbc00591753e5c29485ce242e5c598ed2101cf Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 6 Mar 2003 14:52:43 +0000 Subject: [PATCH 0645/4131] fixed a typo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@724 --- src/dos/cdrom_ioctl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/cdrom_ioctl.cpp b/src/dos/cdrom_ioctl.cpp index 92459800..cbbbfa10 100644 --- a/src/dos/cdrom_ioctl.cpp +++ b/src/dos/cdrom_ioctl.cpp @@ -57,7 +57,7 @@ bool CDROM_Interface_Linux::Open(void) return (dhandle>=0); }; -void CDROM_Interface_Ioctl::Close(void) +void CDROM_Interface_Linux::Close(void) { close (dhandle); }; @@ -516,4 +516,4 @@ int CDROM_GetMountType(char* path) return 2; }; */ -#endif \ No newline at end of file +#endif From 542d0739c935748a76bbb72a60ae84ad51bcbd6f Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 7 Mar 2003 11:20:47 +0000 Subject: [PATCH 0646/4131] replaced Debug_Msg with LOG Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@725 --- src/dos/cdrom.cpp | 10 +++++----- src/dos/cdrom_ioctl.cpp | 3 ++- src/dos/dos_mscdex.cpp | 29 +++++++++++++++-------------- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 6e1ba761..9a4725b3 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -84,11 +84,11 @@ BYTE CDROM_Interface_Aspi::GetHostAdapter(void) ResetEvent(hEvent); dwStatus = pSendASPI32Command((LPSRB)&s); if ((dwStatus==0) && (s.SRB_Status!=SS_INVALID_CMD)) { - DEBUG_ShowMsg(0,"SCSI: Host Adapter found: %d",i); + LOG(LOG_MISC,"SCSI: Host Adapter found: %d",i); return i; }; }; - DEBUG_ShowMsg(0,"SCSI: Host Adapter not found."); + LOG(LOG_MISC|LOG_ERROR,"SCSI: Host Adapter not found."); return 0; }; @@ -111,15 +111,15 @@ bool CDROM_Interface_Aspi::ScanRegistryFindKey(HKEY& hKeyBase) newKeyResult = RegOpenKeyEx (hKeyBase,subKey,0,KEY_READ,&hNewKey); if (newKeyResult==ERROR_SUCCESS) { if (GetRegistryValue(hNewKey,"CurrentDriveLetterAssignment",buffer,256)) { - DEBUG_ShowMsg(0,"SCSI: Drive Letter found: %s",buffer); + LOG(LOG_MISC,"SCSI: Drive Letter found: %s",buffer); // aha, something suspicious... if (buffer[0]==letter) { // found it... lets see if we can get the scsi values bool v1 = GetRegistryValue(hNewKey,"SCSILUN",buffer,256); - DEBUG_ShowMsg(0,"SCSI: SCSILUN found: %s",buffer); + LOG(LOG_MISC,"SCSI: SCSILUN found: %s",buffer); lun = buffer[0]-'0'; bool v2 = GetRegistryValue(hNewKey,"SCSITargetID",buffer,256); - DEBUG_ShowMsg(0,"SCSI: SCSITargetID found: %s",buffer); + LOG(LOG_MISC,"SCSI: SCSITargetID found: %s",buffer); target = buffer[0]-'0'; RegCloseKey(hNewKey); if (v1 && v2) { diff --git a/src/dos/cdrom_ioctl.cpp b/src/dos/cdrom_ioctl.cpp index cbbbfa10..4b9fb535 100644 --- a/src/dos/cdrom_ioctl.cpp +++ b/src/dos/cdrom_ioctl.cpp @@ -246,7 +246,8 @@ int CDROM_GetMountType(char* path) return 2; }; -#else +#else #if defined (WIN32) + // ***************************************************************** // Windows IOCTL functions (not suitable for 95/98/Me) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 5986751a..702fe9e8 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -17,6 +17,7 @@ */ #include +#include #include "cpu.h" #include "callback.h" #include "dos_system.h" @@ -228,31 +229,31 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) // WIN NT/200/XP if (gUseASPI) { cdrom[numDrives] = new CDROM_Interface_Aspi(); - DEBUG_ShowMsg(0,"MSCDEX: ASPI Interface."); + LOG(LOG_MISC,"MSCDEX: ASPI Interface."); } else { cdrom[numDrives] = new CDROM_Interface_Ioctl(); - DEBUG_ShowMsg(0,"MSCDEX: IOCTL Interface."); + LOG(LOG_MISC,"MSCDEX: IOCTL Interface."); } } else { // Win 95/98/ME - always use ASPI cdrom[numDrives] = new CDROM_Interface_Aspi(); - DEBUG_ShowMsg(0,"MSCDEX: ASPI Interface."); + LOG(LOG_MISC,"MSCDEX: ASPI Interface."); } #else cdrom[numDrives] = new CDROM_Interface_Linux(); #endif - DEBUG_ShowMsg(0,"MSCDEX: Mounting physical cdrom: %s" ,physicalPath); + LOG(LOG_MISC,"MSCDEX: Mounting physical cdrom: %s" ,physicalPath); } break; case 0x01 : // iso cdrom interface // FIXME: Not yet supported - DEBUG_ShowMsg(0,"MSCDEX: Mounting iso file as cdrom: %s" ,physicalPath); + LOG(LOG_MISC|LOG_ERROR,"MSCDEX: Mounting iso file as cdrom: %s" ,physicalPath); cdrom[numDrives] = new CDROM_Interface_Fake; return 2; break; case 0x02 : // fake cdrom interface (directories) cdrom[numDrives] = new CDROM_Interface_Fake; - DEBUG_ShowMsg(0,"MSCDEX: Mounting directory as cdrom: %s",physicalPath); - DEBUG_ShowMsg(0,"MSCDEX: You wont have full MSCDEX support !"); + LOG(LOG_MISC,"MSCDEX: Mounting directory as cdrom: %s",physicalPath); + LOG(LOG_MISC,"MSCDEX: You wont have full MSCDEX support !"); result = 5; break; default : // weird result @@ -513,27 +514,27 @@ static CMscdex* mscdex = 0; static Bitu MSCDEX_Strategy_Handler(void) { -// DEBUG_ShowMsg("MSCDEX: Device Strategy Routine called."); +// LOG("MSCDEX: Device Strategy Routine called."); return CBRET_NONE; } static Bitu MSCDEX_Interrupt_Handler(void) { -// DEBUG_ShowMsg("MSCDEX: Device Interrupt Routine called."); +// LOG("MSCDEX: Device Interrupt Routine called."); Bit8u subFuncNr = 0xFF; PhysPt data = PhysMake(SegValue(es),reg_bx); Bit8u subUnit = mem_readb(data+1); Bit8u funcNr = mem_readb(data+2); -// if (funcNr!=0x03) DEBUG_ShowMsg("MSCDEX: Driver Function %02X",funcNr); +// if (funcNr!=0x03) LOG("MSCDEX: Driver Function %02X",funcNr); switch (funcNr) { case 0x03 : { /* IOCTL INPUT */ PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); subFuncNr = mem_readb(buffer); - //if (subFuncNr!=0x0B) DEBUG_ShowMsg("MSCDEX: IOCTL INPUT Subfunction %02X",subFuncNr); + //if (subFuncNr!=0x0B) LOG("MSCDEX: IOCTL INPUT Subfunction %02X",subFuncNr); switch (subFuncNr) { case 0x00 : /* Get Device Header address */ mem_writed(buffer+1,RealMake(mscdex->rootDriverHeaderSeg,0)); @@ -629,7 +630,7 @@ static Bitu MSCDEX_Interrupt_Handler(void) case 0x0C : { /* IOCTL OUTPUT */ PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); subFuncNr = mem_readb(buffer); - // if (subFuncNr!=0x0B) DEBUG_ShowMsg("MSCDEX: IOCTL OUTPUT Subfunction %02X",subFuncNr); + // if (subFuncNr!=0x0B) LOG("MSCDEX: IOCTL OUTPUT Subfunction %02X",subFuncNr); switch (subFuncNr) { case 0x00 : // Unload /eject) media mscdex->LoadUnloadMedia(subUnit,true); @@ -692,7 +693,7 @@ static bool MSCDEX_Handler(void) if (reg_ah!=0x15) return false; PhysPt data = PhysMake(SegValue(es),reg_bx); -// if (reg_ax!=0x1510) DEBUG_ShowMsg("MSCEEX: INT 2F %04X",reg_ax); +// if (reg_ax!=0x1510) LOG("MSCEEX: INT 2F %04X",reg_ax); switch (reg_ax) { case 0x1500: /* Install check */ @@ -775,7 +776,7 @@ public: device_MSCDEX() { name="MSCD001"; } bool Read (Bit8u * data,Bit16u * size) { return false;} bool Write(Bit8u * data,Bit16u * size) { - DEBUG_ShowMsg(0,"Write to mscdex device"); + LOG(0,"Write to mscdex device"); return false; } bool Seek(Bit32u * pos,Bit32u type){return false;} From 3cff24c4a70f69e6418505be058001b74b82dad8 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 7 Mar 2003 11:31:13 +0000 Subject: [PATCH 0647/4131] fixed buf if extrabytes are zero. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@726 --- src/dos/dos_execute.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 56d8ca38..789ce2e7 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -240,8 +240,12 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { if ((head.signature!=MAGIC1) && (head.signature!=MAGIC2)) iscom=true; else { headersize=head.headersize*16; - imagesize=(head.pages-1)*512-headersize; - if (head.extrabytes) imagesize += head.extrabytes % 512; + if (head.extrabytes) { + imagesize = (head.pages-1)*512-headersize; + imagesize += head.extrabytes % 512; + } else + imagesize = head.pages*512-headersize; + // always load st least 512 Bytes (dos cache/dos bug?) if (imagesize+headersize<512) imagesize = 512-headersize; } From 3adae7c555afe8f05ef400e5a42f86a4e2109c9a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 9 Mar 2003 18:17:19 +0000 Subject: [PATCH 0648/4131] Added Scale2x rendering. Enabled screenshot support again. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@727 --- src/gui/render.cpp | 94 +++++-- src/gui/render_normal.h | 182 +++++++++++++ src/gui/render_scale2x.h | 545 +++++++++++++++++++++++++++++++++++++++ src/gui/render_support.h | 228 ---------------- 4 files changed, 798 insertions(+), 251 deletions(-) create mode 100644 src/gui/render_normal.h create mode 100644 src/gui/render_scale2x.h delete mode 100644 src/gui/render_support.h diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 6341bf0a..094078bb 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include #include #include "dosbox.h" @@ -26,11 +25,8 @@ #include "keyboard.h" #include "cross.h" - #define MAX_RES 2048 - - struct PalData { struct { Bit8u red; @@ -55,18 +51,16 @@ static struct { Bitu pitch; Bitu flags; float ratio; - RENDER_Part_Handler part_handler; RENDER_Draw_Handler draw_handler; } src; struct { Bitu width; Bitu height; Bitu pitch; - Bitu next_line; - Bitu next_pixel; Bitu bpp; /* The type of BPP the operation requires for input */ - RENDER_Operation want_type; RENDER_Operation type; + RENDER_Operation want_type; + RENDER_Part_Handler part_handler; void * dest; void * buffer; void * pixels; @@ -77,6 +71,13 @@ static struct { } frameskip; Bitu flags; PalData pal; +#if (C_SSHOT) + struct { + RENDER_Operation type; + Bitu pitch; + const char * dir; + } shot; +#endif bool keep_small; bool screenshot; bool active; @@ -86,9 +87,13 @@ static struct { static void RENDER_ResetPal(void); /* Include the different rendering routines */ -#include "render_support.h" +#include "render_normal.h" +#include "render_scale2x.h" + + +#if (C_SSHOT) +#include -static const char * snapshots_dir; /* Take a screenshot of the data that should be rendered */ static void TakeScreenShot(Bit8u * bitmap) { @@ -109,9 +114,9 @@ static void TakeScreenShot(Bit8u * bitmap) { return; } /* Find a filename to open */ - dir=opendir(snapshots_dir); + dir=opendir(render.shot.dir); if (!dir) { - LOG_MSG("Can't open snapshot dir %s",snapshots_dir); + LOG_MSG("Can't open snapshot dir %s",render.shot.dir); return; } while (dir_ent=readdir(dir)) { @@ -126,7 +131,7 @@ static void TakeScreenShot(Bit8u * bitmap) { if (num>=last) last=num+1; } closedir(dir); - sprintf(file_name,"%s%csnap%05d.png",snapshots_dir,CROSS_FILESPLIT,last); + sprintf(file_name,"%s%csnap%05d.png",render.shot.dir,CROSS_FILESPLIT,last); /* Open the actual file */ FILE * fp=fopen(file_name,"wb"); if (!fp) { @@ -162,7 +167,7 @@ static void TakeScreenShot(Bit8u * bitmap) { /*Allocate an array of scanline pointers*/ row_pointers=(png_bytep*)malloc(render.src.height*sizeof(png_bytep)); for (i=0;i(sec); - snapshots_dir=section->Get_string("snapshots"); render.pal.first=256; render.pal.last=0; render.keep_small=section->Get_bool("keepsmall"); render.frameskip.max=section->Get_int("frameskip"); render.frameskip.count=0; +#if (C_SSHOT) + render.shot.dir=section->Get_string("snapshots"); KEYBOARD_AddEvent(KBD_f5,KBD_MOD_CTRL,EnableScreenShot); +#endif + const char * scaler=section->Get_string("scaler"); + if (!stricmp(scaler,"none")) render.op.want_type=OP_None; + else if (!stricmp(scaler,"scale2x")) render.op.want_type=OP_Scale2x; + else { + render.op.want_type=OP_None; + LOG_MSG("Illegal scaler type %s,falling back to none.",scaler); + } KEYBOARD_AddEvent(KBD_f7,KBD_MOD_CTRL,DecreaseFrameSkip); KEYBOARD_AddEvent(KBD_f8,KBD_MOD_CTRL,IncreaseFrameSkip); } diff --git a/src/gui/render_normal.h b/src/gui/render_normal.h new file mode 100644 index 00000000..5d4beeee --- /dev/null +++ b/src/gui/render_normal.h @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define LOOPSIZE 4 + +#define SIZE_8 1 +#define SIZE_16 2 +#define SIZE_32 4 + +#define MAKE_8(FROM) Bit8u val=*(Bit8u *)(FROM); +#define MAKE_16(FROM) Bit16u val=render.pal.lookup.bpp16[*(Bit8u *)(FROM)]; +#define MAKE_32(FROM) Bit32u val=render.pal.lookup.bpp32[*(Bit8u *)(FROM)]; + +#define SAVE_8(WHERE) *(Bit8u *)(WHERE)=val; +#define SAVE_16(WHERE) *(Bit16u *)(WHERE)=val; +#define SAVE_32(WHERE) *(Bit32u *)(WHERE)=val; + +#define LINES_DN 1 +#define LINES_DW 1 +#define LINES_DH 2 +#define LINES_DB 2 + +#define PIXELS_DN 1 +#define PIXELS_DW 2 +#define PIXELS_DH 1 +#define PIXELS_DB 2 + +#define NORMAL_DN(BPP,FROM,DEST) \ + MAKE_ ## BPP(FROM); \ + SAVE_ ## BPP(DEST); \ + +#define NORMAL_DW(BPP,FROM,DEST) \ + MAKE_ ## BPP (FROM); \ + SAVE_ ## BPP (DEST); \ + SAVE_ ## BPP (DEST + SIZE_ ## BPP); \ + +#define NORMAL_DH(BPP,FROM,DEST) \ + MAKE_ ## BPP (FROM); \ + SAVE_ ## BPP (DEST); \ + SAVE_ ## BPP ((DEST) + render.op.pitch); \ + + +#define NORMAL_DB(BPP,FROM,DEST) \ + MAKE_ ## BPP (FROM); \ + SAVE_ ## BPP (DEST); \ + SAVE_ ## BPP ((DEST)+SIZE_ ## BPP ); \ + SAVE_ ## BPP ((DEST)+render.op.pitch ); \ + SAVE_ ## BPP ((DEST)+render.op.pitch+SIZE_ ## BPP ); \ + + +#define NORMAL_LOOP(COUNT,FUNC,BPP) \ + if (COUNT>0) {NORMAL_ ## FUNC (BPP,(src+0),(dest+0 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ + if (COUNT>1) {NORMAL_ ## FUNC (BPP,(src+1),(dest+1 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ + if (COUNT>2) {NORMAL_ ## FUNC (BPP,(src+2),(dest+2 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ + if (COUNT>3) {NORMAL_ ## FUNC (BPP,(src+3),(dest+3 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ + if (COUNT>4) {NORMAL_ ## FUNC (BPP,(src+4),(dest+4 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ + if (COUNT>5) {NORMAL_ ## FUNC (BPP,(src+5),(dest+5 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ + if (COUNT>6) {NORMAL_ ## FUNC (BPP,(src+6),(dest+6 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ + if (COUNT>7) {NORMAL_ ## FUNC (BPP,(src+7),(dest+7 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ + +#define MAKENORMAL(FUNC,BPP) \ +static void Normal_ ## FUNC ## _ ##BPP(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { \ + Bit8u * dest=(Bit8u *)render.op.pixels+y*LINES_ ## FUNC*render.op.pitch+x*PIXELS_ ## FUNC * SIZE_ ## BPP; \ + Bitu next_src=render.src.pitch-dx; \ + Bitu next_dest=(LINES_ ## FUNC*render.op.pitch) - (dx*PIXELS_ ## FUNC * SIZE_ ## BPP); \ + dx/=LOOPSIZE; \ + dy--; \ + for (;dy>0;dy--) { \ + for (Bitu tempx=dx;tempx>0;tempx--) { \ + NORMAL_LOOP(LOOPSIZE,FUNC,BPP); \ + src+=LOOPSIZE;dest+=LOOPSIZE*PIXELS_ ## FUNC * SIZE_ ## BPP; \ + } \ + src+=next_src;dest+=next_dest; \ + } \ +} + +MAKENORMAL(DW,8); +MAKENORMAL(DB,8); + +MAKENORMAL(DN,16); +MAKENORMAL(DW,16); +MAKENORMAL(DH,16); +MAKENORMAL(DB,16); + +MAKENORMAL(DN,32); +MAKENORMAL(DW,32); +MAKENORMAL(DH,32); +MAKENORMAL(DB,32); + +/* Special versions for the 8-bit ones that can do direct line copying */ + +static void Normal_DN_8(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=render.op.pitch-dx; + Bitu rem=dx&3;dx>>=2; + for (;dy>0;dy--) { + Bitu tempx; + for (tempx=dx;tempx>0;tempx--) { + Bit32u temp=*(Bit32u *)src;src+=4; + *(Bit32u *)dest=temp; + dest+=4; + } + for (tempx=rem;tempx>0;tempx--) { + *dest++=*src++; + } + src+=next_src;dest+=next_dest; + } +} + +static void Normal_DH_8(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=(2*render.op.pitch)-dx; + Bitu rem=dx&3;dx>>=2; + for (;dy>0;dy--) { + Bitu tempx; + for (tempx=dx;tempx>0;tempx--) { + Bit32u temp=*(Bit32u *)src;src+=4; + *(Bit32u *)dest=temp; + *(Bit32u *)(dest+render.op.pitch)=temp; + dest+=4; + } + for (tempx=rem;tempx>0;tempx--) { + *dest=*src; + *(dest+render.op.pitch)=*src; + dest++; + } + src+=next_src;dest+=next_dest; + } +} + +static RENDER_Part_Handler Render_Normal_8_Table[4]= { + Normal_DN_8,Normal_DW_8,Normal_DH_8,Normal_DB_8, +}; + +static RENDER_Part_Handler Render_Normal_16_Table[4]= { + Normal_DN_16,Normal_DW_16,Normal_DH_16,Normal_DB_16, +}; + +static RENDER_Part_Handler Render_Normal_32_Table[4]= { + Normal_DN_32,Normal_DW_32,Normal_DH_32,Normal_DB_32, +}; + +static void Render_Normal_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags) { + if (!(flags & MODE_SET)) return; + render.op.width=width; + render.op.height=height; + render.op.bpp=bpp; + render.op.pitch=pitch; + render.op.type=OP_None; + switch (bpp) { + case 8: + render.op.part_handler=Render_Normal_8_Table[render.src.flags]; + break; + case 16: + render.op.part_handler=Render_Normal_16_Table[render.src.flags]; + break; + case 32: + render.op.part_handler=Render_Normal_32_Table[render.src.flags]; + break; + default: + E_Exit("RENDER:Unsupported display depth of %d",bpp); + break; + } + RENDER_ResetPal(); +} diff --git a/src/gui/render_scale2x.h b/src/gui/render_scale2x.h new file mode 100644 index 00000000..e439bd11 --- /dev/null +++ b/src/gui/render_scale2x.h @@ -0,0 +1,545 @@ +/* + * This file is part of the Scale2x project. + * + * Copyright (C) 2001-2002 Andrea Mazzoleni + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * In addition, as a special exception, Andrea Mazzoleni + * gives permission to link the code of this program with + * the MAME library (or with modified versions of MAME that use the + * same license as MAME), and distribute linked combinations including + * the two. You must obey the GNU General Public License in all + * respects for all of the code used other than MAME. If you modify + * this file, you may extend this exception to your version of the + * file, but you are not obligated to do so. If you do not wish to + * do so, delete this exception statement from your version. + */ + +/* + * This file contains a C and MMX implentation of the Scale2x effect. + * + * You can found an high level description of the effect at : + * + * http://scale2x.sourceforge.net/scale2x.html + * + * Alternatively at the previous license terms, you are allowed to use this + * code in your program with these conditions: + * - the program is not used in commercial activities. + * - the whole source code of the program is released with the binary. + * - derivative works of the program are allowed. + */ + +/* + * Made some changes to only support the 8-bit version. + * Also added mulitple destination bpp targets. + */ + +#ifndef __SCALE2X_H +#define __SCALE2X_H + +#include + +/***************************************************************************/ +/* basic types */ + +typedef Bit8u scale2x_uint8; +typedef Bit16u scale2x_uint16; +typedef Bit32u scale2x_uint32; + +#if !defined(__GNUC__) && !defined(__i386__) + +#define SCALE2X_NORMAL 1 + +static void scale2x_line_8(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count) +{ + assert(count >= 2); + + /* first pixel */ + dst0[0] = src1[0]; + dst1[0] = src1[0]; + if (src1[1] == src0[0] && src2[0] != src0[0]) + dst0[1] = src0[0]; + else + dst0[1] = src1[0]; + if (src1[1] == src2[0] && src0[0] != src2[0]) + dst1[1] = src2[0]; + else + dst1[1] = src1[0]; + ++src0; + ++src1; + ++src2; + dst0 += 2; + dst1 += 2; + + /* central pixels */ + count -= 2; + while (count) { + if (src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0]) + dst0[0] = src0[0]; + else + dst0[0] = src1[0]; + if (src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0]) + dst0[1] = src0[0]; + else + dst0[1] = src1[0]; + + if (src1[-1] == src2[0] && src0[0] != src2[0] && src1[1] != src2[0]) + dst1[0] = src2[0]; + else + dst1[0] = src1[0]; + if (src1[1] == src2[0] && src0[0] != src2[0] && src1[-1] != src2[0]) + dst1[1] = src2[0]; + else + dst1[1] = src1[0]; + + ++src0; + ++src1; + ++src2; + dst0 += 2; + dst1 += 2; + --count; + } + + /* last pixel */ + if (src1[-1] == src0[0] && src2[0] != src0[0]) + dst0[0] = src0[0]; + else + dst0[0] = src1[0]; + if (src1[-1] == src2[0] && src0[0] != src2[0]) + dst1[0] = src2[0]; + else + dst1[0] = src1[0]; + dst0[1] = src1[0]; + dst1[1] = src1[0]; +} + +static void scale2x_line_16(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count) +{ + assert(count >= 2); + + /* first pixel */ + dst0[0] = render.pal.lookup.bpp16[src1[0]]; + dst1[0] = render.pal.lookup.bpp16[src1[0]]; + if (src1[1] == src0[0] && src2[0] != src0[0]) + dst0[1] = render.pal.lookup.bpp16[src0[0]]; + else + dst0[1] = render.pal.lookup.bpp16[src1[0]]; + if (src1[1] == src2[0] && src0[0] != src2[0]) + dst1[1] = render.pal.lookup.bpp16[src2[0]]; + else + dst1[1] = render.pal.lookup.bpp16[src1[0]]; + ++src0; + ++src1; + ++src2; + dst0 += 2; + dst1 += 2; + + /* central pixels */ + count -= 2; + while (count) { + if (src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0]) + dst0[0] = render.pal.lookup.bpp16[src0[0]]; + else + dst0[0] = render.pal.lookup.bpp16[src1[0]]; + if (src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0]) + dst0[1] = render.pal.lookup.bpp16[src0[0]]; + else + dst0[1] = render.pal.lookup.bpp16[src1[0]]; + + if (src1[-1] == src2[0] && src0[0] != src2[0] && src1[1] != src2[0]) + dst1[0] = render.pal.lookup.bpp16[src2[0]]; + else + dst1[0] = render.pal.lookup.bpp16[src1[0]]; + if (src1[1] == src2[0] && src0[0] != src2[0] && src1[-1] != src2[0]) + dst1[1] = render.pal.lookup.bpp16[src2[0]]; + else + dst1[1] = render.pal.lookup.bpp16[src1[0]]; + + ++src0; + ++src1; + ++src2; + dst0 += 2; + dst1 += 2; + --count; + } + + /* last pixel */ + if (src1[-1] == src0[0] && src2[0] != src0[0]) + dst0[0] = render.pal.lookup.bpp16[src0[0]]; + else + dst0[0] = render.pal.lookup.bpp16[src1[0]]; + if (src1[-1] == src2[0] && src0[0] != src2[0]) + dst1[0] = render.pal.lookup.bpp16[src2[0]]; + else + dst1[0] = render.pal.lookup.bpp16[src1[0]]; + dst0[1] = render.pal.lookup.bpp16[src1[0]]; + dst1[1] = render.pal.lookup.bpp16[src1[0]]; +} + +static void scale2x_line_32(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count) +{ + assert(count >= 2); + + /* first pixel */ + dst0[0] = render.pal.lookup.bpp32[src1[0]]; + dst1[0] = render.pal.lookup.bpp32[src1[0]]; + if (src1[1] == src0[0] && src2[0] != src0[0]) + dst0[1] = render.pal.lookup.bpp32[src0[0]]; + else + dst0[1] = render.pal.lookup.bpp32[src1[0]]; + if (src1[1] == src2[0] && src0[0] != src2[0]) + dst1[1] = render.pal.lookup.bpp32[src2[0]]; + else + dst1[1] = render.pal.lookup.bpp32[src1[0]]; + ++src0; + ++src1; + ++src2; + dst0 += 2; + dst1 += 2; + + /* central pixels */ + count -= 2; + while (count) { + if (src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0]) + dst0[0] = render.pal.lookup.bpp32[src0[0]]; + else + dst0[0] = render.pal.lookup.bpp32[src1[0]]; + if (src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0]) + dst0[1] = render.pal.lookup.bpp32[src0[0]]; + else + dst0[1] = render.pal.lookup.bpp32[src1[0]]; + + if (src1[-1] == src2[0] && src0[0] != src2[0] && src1[1] != src2[0]) + dst1[0] = render.pal.lookup.bpp32[src2[0]]; + else + dst1[0] = render.pal.lookup.bpp32[src1[0]]; + if (src1[1] == src2[0] && src0[0] != src2[0] && src1[-1] != src2[0]) + dst1[1] = render.pal.lookup.bpp32[src2[0]]; + else + dst1[1] = render.pal.lookup.bpp32[src1[0]]; + + ++src0; + ++src1; + ++src2; + dst0 += 2; + dst1 += 2; + --count; + } + + /* last pixel */ + if (src1[-1] == src0[0] && src2[0] != src0[0]) + dst0[0] = render.pal.lookup.bpp32[src0[0]]; + else + dst0[0] = render.pal.lookup.bpp32[src1[0]]; + if (src1[-1] == src2[0] && src0[0] != src2[0]) + dst1[0] = render.pal.lookup.bpp32[src2[0]]; + else + dst1[0] = render.pal.lookup.bpp32[src1[0]]; + dst0[1] = render.pal.lookup.bpp32[src1[0]]; + dst1[1] = render.pal.lookup.bpp32[src1[0]]; +} + +static void Scale2x_8(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + if (dy<3) return; + Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch; + /* First line */ + scale2x_line_8(dest,dest+render.op.pitch,src,src,src+render.src.pitch,dx); + dest+=render.op.pitch*2; + src+=render.src.pitch; + dy-=2; + /* Middle part */ + for (;dy>0;dy--) { + scale2x_line_8(dest,dest+render.op.pitch,src,src+render.src.pitch,src+2*render.src.pitch,dx); + dest+=render.op.pitch*2; + src+=render.src.pitch; + } + /* Last Line */ + scale2x_line_8(dest,dest+render.op.pitch,src,src+render.src.pitch,src+render.src.pitch,dx); +} + +static void Scale2x_16(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + if (dy<3) return; + Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch; + /* First line */ + scale2x_line_16((Bit16u *)dest,(Bit16u *)(dest+render.op.pitch),src,src,src+render.src.pitch,dx); + dest+=render.op.pitch*2; + src+=render.src.pitch; + dy-=2; + /* Middle part */ + for (;dy>0;dy--) { + scale2x_line_16((Bit16u *)dest,(Bit16u *)(dest+render.op.pitch),src,src+render.src.pitch,src+2*render.src.pitch,dx); + dest+=render.op.pitch*2; + src+=render.src.pitch; + } + /* Last Line */ + scale2x_line_16((Bit16u *)dest,(Bit16u *)(dest+render.op.pitch),src,src+render.src.pitch,src+render.src.pitch,dx); +} + +static void Scale2x_32(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + if (dy<3) return; + Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch; + /* First line */ + scale2x_line_32((Bit32u *)dest,(Bit32u *)(dest+render.op.pitch),src,src,src+render.src.pitch,dx); + dest+=render.op.pitch*2; + src+=render.src.pitch; + dy-=2; + /* Middle part */ + for (;dy>0;dy--) { + scale2x_line_32((Bit32u *)dest,(Bit32u *)(dest+render.op.pitch),src,src+render.src.pitch,src+2*render.src.pitch,dx); + dest+=render.op.pitch*2; + src+=render.src.pitch; + } + /* Last Line */ + scale2x_line_32((Bit32u *)dest,(Bit32u *)(dest+render.op.pitch),src,src+render.src.pitch,src+render.src.pitch,dx); +} + +#else + +#define SCALE2X_MMX 1 + +static __inline__ void scale2x_8_mmx_single(scale2x_uint8* dst, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count) +{ + assert(count >= 16); + assert(count % 8 == 0); + + /* always do the first and last run */ + count -= 2*8; + + __asm__ __volatile__( +/* first run */ + /* set the current, current_pre, current_next registers */ + "movq 0(%1),%%mm0\n" + "movq 0(%1),%%mm7\n" + "movq 8(%1),%%mm1\n" + "psllq $56,%%mm0\n" + "psllq $56,%%mm1\n" + "psrlq $56,%%mm0\n" + "movq %%mm7,%%mm2\n" + "movq %%mm7,%%mm3\n" + "psllq $8,%%mm2\n" + "psrlq $8,%%mm3\n" + "por %%mm2,%%mm0\n" + "por %%mm3,%%mm1\n" + + /* current_upper */ + "movq (%0),%%mm6\n" + + /* compute the upper-left pixel for dst on %%mm2 */ + /* compute the upper-right pixel for dst on %%mm4 */ + "movq %%mm0,%%mm2\n" + "movq %%mm1,%%mm4\n" + "movq %%mm0,%%mm3\n" + "movq %%mm1,%%mm5\n" + "pcmpeqb %%mm6,%%mm2\n" + "pcmpeqb %%mm6,%%mm4\n" + "pcmpeqb (%2),%%mm3\n" + "pcmpeqb (%2),%%mm5\n" + "pandn %%mm2,%%mm3\n" + "pandn %%mm4,%%mm5\n" + "movq %%mm0,%%mm2\n" + "movq %%mm1,%%mm4\n" + "pcmpeqb %%mm1,%%mm2\n" + "pcmpeqb %%mm0,%%mm4\n" + "pandn %%mm3,%%mm2\n" + "pandn %%mm5,%%mm4\n" + "movq %%mm2,%%mm3\n" + "movq %%mm4,%%mm5\n" + "pand %%mm6,%%mm2\n" + "pand %%mm6,%%mm4\n" + "pandn %%mm7,%%mm3\n" + "pandn %%mm7,%%mm5\n" + "por %%mm3,%%mm2\n" + "por %%mm5,%%mm4\n" + + /* set *dst */ + "movq %%mm2,%%mm3\n" + "punpcklbw %%mm4,%%mm2\n" + "punpckhbw %%mm4,%%mm3\n" + "movq %%mm2,(%3)\n" + "movq %%mm3,8(%3)\n" + + /* next */ + "addl $8,%0\n" + "addl $8,%1\n" + "addl $8,%2\n" + "addl $16,%3\n" + +/* central runs */ + "shrl $3,%4\n" + "jz 1f\n" + + "0:\n" + + /* set the current, current_pre, current_next registers */ + "movq -8(%1),%%mm0\n" + "movq (%1),%%mm7\n" + "movq 8(%1),%%mm1\n" + "psrlq $56,%%mm0\n" + "psllq $56,%%mm1\n" + "movq %%mm7,%%mm2\n" + "movq %%mm7,%%mm3\n" + "psllq $8,%%mm2\n" + "psrlq $8,%%mm3\n" + "por %%mm2,%%mm0\n" + "por %%mm3,%%mm1\n" + + /* current_upper */ + "movq (%0),%%mm6\n" + + /* compute the upper-left pixel for dst on %%mm2 */ + /* compute the upper-right pixel for dst on %%mm4 */ + "movq %%mm0,%%mm2\n" + "movq %%mm1,%%mm4\n" + "movq %%mm0,%%mm3\n" + "movq %%mm1,%%mm5\n" + "pcmpeqb %%mm6,%%mm2\n" + "pcmpeqb %%mm6,%%mm4\n" + "pcmpeqb (%2),%%mm3\n" + "pcmpeqb (%2),%%mm5\n" + "pandn %%mm2,%%mm3\n" + "pandn %%mm4,%%mm5\n" + "movq %%mm0,%%mm2\n" + "movq %%mm1,%%mm4\n" + "pcmpeqb %%mm1,%%mm2\n" + "pcmpeqb %%mm0,%%mm4\n" + "pandn %%mm3,%%mm2\n" + "pandn %%mm5,%%mm4\n" + "movq %%mm2,%%mm3\n" + "movq %%mm4,%%mm5\n" + "pand %%mm6,%%mm2\n" + "pand %%mm6,%%mm4\n" + "pandn %%mm7,%%mm3\n" + "pandn %%mm7,%%mm5\n" + "por %%mm3,%%mm2\n" + "por %%mm5,%%mm4\n" + + /* set *dst */ + "movq %%mm2,%%mm3\n" + "punpcklbw %%mm4,%%mm2\n" + "punpckhbw %%mm4,%%mm3\n" + "movq %%mm2,(%3)\n" + "movq %%mm3,8(%3)\n" + + /* next */ + "addl $8,%0\n" + "addl $8,%1\n" + "addl $8,%2\n" + "addl $16,%3\n" + + "decl %4\n" + "jnz 0b\n" + "1:\n" + +/* final run */ + /* set the current, current_pre, current_next registers */ + "movq (%1),%%mm1\n" + "movq (%1),%%mm7\n" + "movq -8(%1),%%mm0\n" + "psrlq $56,%%mm1\n" + "psrlq $56,%%mm0\n" + "psllq $56,%%mm1\n" + "movq %%mm7,%%mm2\n" + "movq %%mm7,%%mm3\n" + "psllq $8,%%mm2\n" + "psrlq $8,%%mm3\n" + "por %%mm2,%%mm0\n" + "por %%mm3,%%mm1\n" + + /* current_upper */ + "movq (%0),%%mm6\n" + + /* compute the upper-left pixel for dst on %%mm2 */ + /* compute the upper-right pixel for dst on %%mm4 */ + "movq %%mm0,%%mm2\n" + "movq %%mm1,%%mm4\n" + "movq %%mm0,%%mm3\n" + "movq %%mm1,%%mm5\n" + "pcmpeqb %%mm6,%%mm2\n" + "pcmpeqb %%mm6,%%mm4\n" + "pcmpeqb (%2),%%mm3\n" + "pcmpeqb (%2),%%mm5\n" + "pandn %%mm2,%%mm3\n" + "pandn %%mm4,%%mm5\n" + "movq %%mm0,%%mm2\n" + "movq %%mm1,%%mm4\n" + "pcmpeqb %%mm1,%%mm2\n" + "pcmpeqb %%mm0,%%mm4\n" + "pandn %%mm3,%%mm2\n" + "pandn %%mm5,%%mm4\n" + "movq %%mm2,%%mm3\n" + "movq %%mm4,%%mm5\n" + "pand %%mm6,%%mm2\n" + "pand %%mm6,%%mm4\n" + "pandn %%mm7,%%mm3\n" + "pandn %%mm7,%%mm5\n" + "por %%mm3,%%mm2\n" + "por %%mm5,%%mm4\n" + + /* set *dst */ + "movq %%mm2,%%mm3\n" + "punpcklbw %%mm4,%%mm2\n" + "punpckhbw %%mm4,%%mm3\n" + "movq %%mm2,(%3)\n" + "movq %%mm3,8(%3)\n" + + : "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count) + : + : "cc" + ); +} + +static void scale2x_line_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count) +{ + assert(count >= 16); + assert(count % 8 == 0); + + scale2x_8_mmx_single(dst0, src0, src1, src2, count); + scale2x_8_mmx_single(dst1, src2, src1, src0, count); +} + +#endif + +static void Render_Scale2x_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags) { + if (!(flags & MODE_SET)) return; + render.op.width=width; + render.op.height=height; + render.op.bpp=bpp; + render.op.pitch=pitch; + render.op.type=OP_Scale2x; + render.op.part_handler=Scale2x_8; +#if defined(SCALE2X_NORMAL) + switch (bpp) { + case 8: + render.op.part_handler=Scale2x_8; + break; + case 16: + render.op.part_handler=Scale2x_16;; + break; + case 32: + render.op.part_handler=Scale2x_32; + break; + default: + E_Exit("RENDER:Unsupported display depth of %d",bpp); + break; + } +#elif defined(SCALE2X_MMX) + assert (bpp==8); + render.op.part_handler=Scale2x_8_mmx; +#endif + RENDER_ResetPal(); +} + +#endif diff --git a/src/gui/render_support.h b/src/gui/render_support.h deleted file mode 100644 index 3d91cb0f..00000000 --- a/src/gui/render_support.h +++ /dev/null @@ -1,228 +0,0 @@ -static void Render_Normal_8_None(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x; - Bitu next_src=render.src.pitch-dx; - Bitu next_dest=render.op.pitch-dx; - Bitu rem=dx&3;dx>>=2; - for (;dy>0;dy--) { - Bitu tempx; - for (tempx=dx;tempx>0;tempx--) { - Bit32u temp=*(Bit32u *)src;src+=4; - *(Bit32u *)dest=temp; - dest+=4; - } - for (tempx=rem;tempx>0;tempx--) { - *dest++=*src++; - } - src+=next_src;dest+=next_dest; - } -} - -static void Render_Normal_8_DoubleWidth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x*2; - Bitu next_src=render.src.pitch-dx; - Bitu next_dest=render.op.pitch-dx*2; - for (;dy>0;dy--) { - for (Bitu tempx=dx;tempx>0;tempx--) { - *dest=*src;*(dest+1)=*src; - src++;dest+=2; - } - src+=next_src;dest+=next_dest; - } -} - -static void Render_Normal_8_DoubleHeight(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x; - Bitu next_src=render.src.pitch-dx; - Bitu next_dest=(2*render.op.pitch)-dx; - Bitu rem=dx&3;dx>>=2; - for (;dy>0;dy--) { - Bitu tempx; - for (tempx=dx;tempx>0;tempx--) { - Bit32u temp=*(Bit32u *)src;src+=4; - *(Bit32u *)dest=temp; - *(Bit32u *)(dest+render.op.pitch)=temp; - dest+=4; - } - for (tempx=rem;tempx>0;tempx--) { - *dest=*src; - *(dest+render.op.pitch)=*src; - dest++; - } - src+=next_src;dest+=next_dest; - } -} - -static void Render_Normal_8_DoubleBoth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x; - Bitu next_src=render.src.pitch-dx; - Bitu next_dest=(2*render.op.pitch)-dx*2; - for (;dy>0;dy--) { - for (Bitu tempx=dx;tempx>0;tempx--) { - Bit8u val=src[0];src++; - dest[0]=val;dest[1]=val; - dest[render.op.pitch]=val;dest[render.op.pitch+1]=val; - dest+=2; - } - src+=next_src;dest+=next_dest; - } -} - -static void Render_Normal_16_None(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x; - Bitu next_src=render.src.pitch-dx; - Bitu next_dest=render.op.pitch-dx*2; - for (;dy>0;dy--) { - for (Bitu tempx=dx;tempx>0;tempx--) { - Bit16u val=render.pal.lookup.bpp16[src[0]];src++; - *(Bit16u *)dest=val; - dest+=2; - } - src+=next_src;dest+=next_dest; - } -} - -static void Render_Normal_16_DoubleWidth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x*4; - Bitu next_src=render.src.pitch-dx; - Bitu next_dest=render.op.pitch-dx*4; - for (;dy>0;dy--) { - for (Bitu tempx=dx;tempx>0;tempx--) { - Bit16u val=render.pal.lookup.bpp16[src[0]];src++; - *(Bit16u *)dest=val; - *(Bit16u *)(dest+2)=val; - dest+=4; - } - src+=next_src;dest+=next_dest; - } -} - -static void Render_Normal_16_DoubleHeight(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x*2; - Bitu next_src=render.src.pitch-dx; - Bitu next_dest=(2*render.op.pitch)-dx*2; - for (;dy>0;dy--) { - for (Bitu tempx=dx;tempx>0;tempx--) { - Bit16u val=render.pal.lookup.bpp16[src[0]];src++; - *(Bit16u *)dest=val; - *(Bit16u *)(dest+render.op.pitch)=val; - dest+=2; - } - src+=next_src;dest+=next_dest; - } -} - -static void Render_Normal_16_DoubleBoth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x*4; - Bitu next_src=render.src.pitch-dx; - Bitu next_dest=(2*render.op.pitch)-dx*4; - for (;dy>0;dy--) { - for (Bitu tempx=dx;tempx>0;tempx--) { - Bit16u val=render.pal.lookup.bpp16[src[0]];src++; - *(Bit16u *)(dest+0)=val; - *(Bit16u *)(dest+2)=val; - *(Bit16u *)(dest+render.op.pitch)=val; - *(Bit16u *)(dest+render.op.pitch+2)=val; - dest+=4; - } - src+=next_src;dest+=next_dest; - } -} - - -static void Render_Normal_32_None(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x*4; - Bitu next_src=render.src.pitch-dx; - Bitu next_dest=render.op.pitch-dx*4; - for (;dy>0;dy--) { - for (Bitu tempx=dx;tempx>0;tempx--) { - Bit32u val=render.pal.lookup.bpp32[src[0]];src++; - *(Bit32u *)dest=val; - dest+=4; - } - src+=next_src;dest+=next_dest; - } -} - -static void Render_Normal_32_DoubleWidth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x*8; - Bitu next_src=render.src.pitch-dx; - Bitu next_dest=render.op.pitch-dx*8; - for (;dy>0;dy--) { - for (Bitu tempx=dx;tempx>0;tempx--) { - Bit32u val=render.pal.lookup.bpp32[src[0]];src++; - *(Bit32u *)dest=val; - *(Bit32u *)(dest+4)=val; - dest+=8; - } - src+=next_src;dest+=next_dest; - } -} - -static void Render_Normal_32_DoubleHeight(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x*4; - Bitu next_src=render.src.pitch-dx; - Bitu next_dest=(2*render.op.pitch)-dx*4; - for (;dy>0;dy--) { - for (Bitu tempx=dx;tempx>0;tempx--) { - Bit32u val=render.pal.lookup.bpp32[src[0]];src++; - *(Bit32u *)dest=val; - *(Bit32u *)(dest+render.op.pitch)=val; - dest+=4; - } - src+=next_src;dest+=next_dest; - } -} - -static void Render_Normal_32_DoubleBoth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x*8; - Bitu next_src=render.src.pitch-dx; - Bitu next_dest=(2*render.op.pitch)-dx*8; - for (;dy>0;dy--) { - for (Bitu tempx=dx;tempx>0;tempx--) { - Bit32u val=render.pal.lookup.bpp32[src[0]];src++; - *(Bit32u *)(dest+0)=val; - *(Bit32u *)(dest+4)=val; - *(Bit32u *)(dest+render.op.pitch)=val; - *(Bit32u *)(dest+render.op.pitch+4)=val; - dest+=8; - } - src+=next_src;dest+=next_dest; - } -} - - -static RENDER_Part_Handler Render_Normal_8_Table[4]= { - Render_Normal_8_None,Render_Normal_8_DoubleWidth,Render_Normal_8_DoubleHeight,Render_Normal_8_DoubleBoth -}; - -static RENDER_Part_Handler Render_Normal_16_Table[4]= { - Render_Normal_16_None,Render_Normal_16_DoubleWidth,Render_Normal_16_DoubleHeight,Render_Normal_16_DoubleBoth -}; - -static RENDER_Part_Handler Render_Normal_32_Table[4]= { - Render_Normal_32_None,Render_Normal_32_DoubleWidth,Render_Normal_32_DoubleHeight,Render_Normal_32_DoubleBoth -}; - - -static void Render_Normal_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags) { - if (!(flags & MODE_SET)) return; - render.op.width=width; - render.op.height=height; - render.op.bpp=bpp; - render.op.pitch=pitch; - switch (bpp) { - case 8: - render.src.part_handler=Render_Normal_8_Table[render.src.flags]; - break; - case 16: - render.src.part_handler=Render_Normal_16_Table[render.src.flags]; - break; - case 32: - render.src.part_handler=Render_Normal_32_Table[render.src.flags]; - break; - default: - E_Exit("RENDER:Unsupported display depth of %d",bpp); - break; - } - RENDER_ResetPal(); -} From 46f8426d76588e1d7286e74d5a3dc1f2ab60971f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 9 Mar 2003 18:18:51 +0000 Subject: [PATCH 0649/4131] scaler option added in config file. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@728 --- src/dosbox.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index b6108374..740be7ea 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -177,7 +177,8 @@ void DOSBOX_Init(void) { secprop->Add_int("frameskip",0); secprop->Add_bool("keepsmall",false); secprop->Add_string("snapshots","snapshots"); - + secprop->Add_string("scaler","none"); + secprop=control->AddSection_prop("cpu",&CPU_Init); secprop->Add_int("cycles",1800); @@ -232,7 +233,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&MSCDEX_Init); secline=control->AddSection_line("autoexec",&AUTOEXEC_Init); - + control->SetStartUp(&SHELL_Init); #if C_FPU From be041e7296589508162a10cd477ffc7b401933f9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 9 Mar 2003 18:23:57 +0000 Subject: [PATCH 0650/4131] New render operation for screenshots. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@729 --- include/render.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/render.h b/include/render.h index 7dd2d226..054941c8 100644 --- a/include/render.h +++ b/include/render.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,8 @@ enum RENDER_Operation { - OP_None,OP_2xSai,OP_Scale2x + OP_None,OP_Shot, + OP_2xSai,OP_Scale2x, }; enum { From d768369be9d6509eb42c6fa39ea8113a42088ba5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 9 Mar 2003 20:58:54 +0000 Subject: [PATCH 0651/4131] Fixes drawing of last and first line. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@730 --- src/gui/render_scale2x.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gui/render_scale2x.h b/src/gui/render_scale2x.h index e439bd11..8d74d16f 100644 --- a/src/gui/render_scale2x.h +++ b/src/gui/render_scale2x.h @@ -262,12 +262,12 @@ static void Scale2x_8(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { dy-=2; /* Middle part */ for (;dy>0;dy--) { - scale2x_line_8(dest,dest+render.op.pitch,src,src+render.src.pitch,src+2*render.src.pitch,dx); + scale2x_line_8((Bit8u *)dest,(Bit8u *)(dest+render.op.pitch),src-render.src.pitch,src,src+render.src.pitch,dx); dest+=render.op.pitch*2; src+=render.src.pitch; } /* Last Line */ - scale2x_line_8(dest,dest+render.op.pitch,src,src+render.src.pitch,src+render.src.pitch,dx); + scale2x_line_8((Bit8u *)dest,(Bit8u *)(dest+render.op.pitch),src-render.src.pitch,src,src,dx); } static void Scale2x_16(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { @@ -280,12 +280,12 @@ static void Scale2x_16(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { dy-=2; /* Middle part */ for (;dy>0;dy--) { - scale2x_line_16((Bit16u *)dest,(Bit16u *)(dest+render.op.pitch),src,src+render.src.pitch,src+2*render.src.pitch,dx); + scale2x_line_16((Bit16u *)dest,(Bit16u *)(dest+render.op.pitch),src-render.src.pitch,src,src+render.src.pitch,dx); dest+=render.op.pitch*2; src+=render.src.pitch; } /* Last Line */ - scale2x_line_16((Bit16u *)dest,(Bit16u *)(dest+render.op.pitch),src,src+render.src.pitch,src+render.src.pitch,dx); + scale2x_line_16((Bit16u *)dest,(Bit16u *)(dest+render.op.pitch),src-render.src.pitch,src,src,dx); } static void Scale2x_32(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { @@ -298,12 +298,12 @@ static void Scale2x_32(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { dy-=2; /* Middle part */ for (;dy>0;dy--) { - scale2x_line_32((Bit32u *)dest,(Bit32u *)(dest+render.op.pitch),src,src+render.src.pitch,src+2*render.src.pitch,dx); + scale2x_line_32((Bit32u *)dest,(Bit32u *)(dest+render.op.pitch),src-render.src.pitch,src,src+render.src.pitch,dx); dest+=render.op.pitch*2; src+=render.src.pitch; } /* Last Line */ - scale2x_line_32((Bit32u *)dest,(Bit32u *)(dest+render.op.pitch),src,src+render.src.pitch,src+render.src.pitch,dx); + scale2x_line_32((Bit32u *)dest,(Bit32u *)(dest+render.op.pitch),src-render.src.pitch,src,src,dx); } #else From 84daa51d7e7f4143e3ae913c9a3aa3ed27164076 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 10 Mar 2003 10:19:00 +0000 Subject: [PATCH 0652/4131] enable opening directories with a trailing backslash Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@731 --- src/platform/visualc/dirent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/visualc/dirent.c b/src/platform/visualc/dirent.c index f6be7922..6c1c4b78 100644 --- a/src/platform/visualc/dirent.c +++ b/src/platform/visualc/dirent.c @@ -23,7 +23,7 @@ DIR * opendir(const char *dirname) { /* Stash the directory name */ strcpy(dir.pathName,dirname); - strcat(dir.pathName,"*.*"); + strcat(dir.pathName,"\\*.*"); /* set the handle to invalid and set the firstTime flag */ dir.handle = INVALID_HANDLE_VALUE; From 359aca11f3de2e227aca70157d3af0c423041c1e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 10 Mar 2003 10:19:45 +0000 Subject: [PATCH 0653/4131] add scale2x and normal headers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@732 --- src/gui/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 1ae12e70..4ae4731d 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -1,6 +1,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libgui.a -libgui_a_SOURCES = sdlmain.cpp render.cpp render_support.h \ +libgui_a_SOURCES = sdlmain.cpp render.cpp render_normal.h render_scale2x.h \ midi.cpp midi_win32.h midi_oss.h From 8de6c90eb3544822e82ac7b672453cdccc78b6e5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 10 Mar 2003 14:30:27 +0000 Subject: [PATCH 0654/4131] Enable/Disable support for debugger and screenshots Bettter checks for libpng and libcurses Removal of settings.h file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@733 --- acinclude.m4 | 17 ++++++++++++++++- autogen.sh | 6 +----- configure.in | 28 +++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 2491c4e5..97aed8aa 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -180,7 +180,9 @@ AH_TOP([ */ ]) -AH_TEMPLATE([C_HAS_ATTRIBUTE],[Determines if the compilers supports attributes for structures]) +AH_TEMPLATE([C_HAS_ATTRIBUTE],[Determines if the compilers supports attributes for structures.]) +AH_TEMPLATE([C_DEBUG],[Enable the internal debugger.]) +AH_TEMPLATE([C_SSHOT],[Enable the screenshot support.]) AH_BOTTOM([#define INLINE inline]) @@ -190,5 +192,18 @@ AH_BOTTOM([#if C_HAS_ATTRIBUTE #define GCC_ATTRIBUTE(x) /* attribute not supported */ #endif]) +AH_BOTTOM([ +/* Enable some heavy debugging options */ +#define C_HEAVY_DEBUG 0 + +/* Enable some big compile-time increasing inlines */ +#define C_EXTRAINLINE 0 + +/* Enable the FPU module, still only for beta testing */ +#define C_FPU 0 + +/* Maximum memory address range in megabytes */ +#define C_MEM_MAX_SIZE 12 +]) diff --git a/autogen.sh b/autogen.sh index 8b08a7e8..9126bca9 100755 --- a/autogen.sh +++ b/autogen.sh @@ -10,8 +10,4 @@ autoheader automake --gnits --include-deps --add-missing --copy autoconf -#Copy settings.h.cvs to settings.h and that's it, - -directory=`dirname $0` -cp $directory/settings.h.cvs $directory/settings.h -echo "Now you are ready to run ./configure also check settings.h for extra build settings" +echo "Now you are ready to run ./configure, afterwards check config.h for extra build settings" diff --git a/configure.in b/configure.in index 22562502..2a03de91 100644 --- a/configure.in +++ b/configure.in @@ -36,7 +36,6 @@ AC_TYPE_SIZE_T AC_STRUCT_TM dnl Checks for libraries. -AC_CHECK_LIB(png, png_check_sig, , AC_MSG_ERROR([*** libpng not found!]), -lz) #Check if the compiler support attributes AC_MSG_CHECKING(if compiler allows __attribute__) @@ -46,6 +45,33 @@ AC_TRY_COMPILE([], [typedef struct { } __attribute__ ((packed)) junk;], #Check for big endian machine, should #define WORD_BIGENDIAN if so AC_C_BIGENDIAN +#Features to enable/disable +AH_TEMPLATE(C_DEBUG,[Define to 1 to enable internal debugger, requires libcurses]) +AC_ARG_ENABLE(debug,[ --enable-debug Enable debug mode],[ + AC_CHECK_HEADER(curses.h,have_curses_h=yes,) + AC_CHECK_LIB(curses, initscr, have_curses_lib=yes, , ) + + if test x$have_curses_lib = xyes -a x$have_curses_h = xyes ; then + AC_DEFINE(C_DEBUG,1) + else + AC_MSG_WARN([Can't enable debug mode without libcurses]) + fi +],) + +AH_TEMPLATE(C_SSHOTS,[Define to 1 to enable screenshots, requires libpng]) +AC_ARG_ENABLE(shots,[ --enable-shots Enable screenshot support],[ + AC_CHECK_HEADER(png.h,have_png_h=yes,) + AC_CHECK_LIB(png, png_check_sig, have_png_lib=yes, , -lz) + + if test x$have_curses_lib = xyes -a x$have_curses_h = xyes ; then + AC_DEFINE(C_SSHOTS,1) + else + AC_MSG_WARN([Can't enable screenshots without libpng]) + fi +],) + + + AC_OUTPUT([ Makefile src/Makefile From 95dda663a0703d37b1aeaf513dbdefd71442c112 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 10 Mar 2003 15:02:58 +0000 Subject: [PATCH 0655/4131] Some fixes to allow autoconf to run Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@734 --- acinclude.m4 | 2 -- configure.in | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 97aed8aa..6974c0c1 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -181,8 +181,6 @@ AH_TOP([ ]) AH_TEMPLATE([C_HAS_ATTRIBUTE],[Determines if the compilers supports attributes for structures.]) -AH_TEMPLATE([C_DEBUG],[Enable the internal debugger.]) -AH_TEMPLATE([C_SSHOT],[Enable the screenshot support.]) AH_BOTTOM([#define INLINE inline]) diff --git a/configure.in b/configure.in index 2a03de91..a048585c 100644 --- a/configure.in +++ b/configure.in @@ -1,6 +1,7 @@ dnl Init. AC_INIT(dosbox,0.57) AC_CONFIG_SRCDIR(README) +AC_RREREQ(2.50) dnl Detect the canonical host and target build environment AC_CANONICAL_HOST From 4d7e42103d1d6b9b8b4ee54087bed0e98bfd61e4 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 10 Mar 2003 15:06:57 +0000 Subject: [PATCH 0656/4131] fixed a spelling error Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@735 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index a048585c..a9fce574 100644 --- a/configure.in +++ b/configure.in @@ -1,7 +1,7 @@ dnl Init. AC_INIT(dosbox,0.57) +AC_PREREQ(2.50) AC_CONFIG_SRCDIR(README) -AC_RREREQ(2.50) dnl Detect the canonical host and target build environment AC_CANONICAL_HOST From fbfd081260c315729f93b257e9fa953c7994654c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 10 Mar 2003 15:17:37 +0000 Subject: [PATCH 0657/4131] Removal of settings.h, settings moved in here. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@736 --- src/platform/visualc/config.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 83fa3b12..74efab36 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -2,5 +2,22 @@ #define VERSION "0.57" -#define GCC_ATTRIBUTE(x) /* attribute not supported */ +/* Define to 1 to enable internal debugger, requires libcurses */ +#define C_DEBUG 1 +/* Define to 1 to enable screenshots, requires libpng */ +#define C_SSHOTS 1 + +/* Enable some heavy debugging options */ +#define C_HEAVY_DEBUG 0 + +/* Enable some big compile-time increasing inlines */ +#define C_EXTRAINLINE 0 + +/* Enable the FPU module, still only for beta testing */ +#define C_FPU 0 + +/* Maximum memory address range in megabytes */ +#define C_MEM_MAX_SIZE 12 + +#define GCC_ATTRIBUTE(x) /* attribute not supported */ From 33bbeee6e2c4f95df4d6b3dd515f067bea624c28 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 10 Mar 2003 15:22:24 +0000 Subject: [PATCH 0658/4131] Settings now in config.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@737 --- settings.h.cvs | 35 ----------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 settings.h.cvs diff --git a/settings.h.cvs b/settings.h.cvs deleted file mode 100644 index 9f54aada..00000000 --- a/settings.h.cvs +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2002-2003 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _SETTINGS_H_ -#define _SETTINGS_H_ - -/* Enable the debugger, under linux/freebsd dosbox must be started in an xterm under X */ -#define C_DEBUG 0 -#define C_HEAVY_DEBUG 0 - -/* Enable some big compile-time increasing inlines, great for speed though */ -#define C_EXTRAINLINE 0 - -/* Enable the FPU module, still only for beta testing */ -#define C_FPU 0 - -/* Maximum memory range in megabytes */ -#define C_MEM_MAX_SIZE 12 - -#endif From 4c5ec02038f4c043e6d9234770fcaf7df49957b8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 10 Mar 2003 16:24:21 +0000 Subject: [PATCH 0659/4131] Able to disable mpu401 Added some intelligent mode commands. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@738 --- src/hardware/mpu401.cpp | 152 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 146 insertions(+), 6 deletions(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 6a3022ea..ff9e9bb1 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -14,12 +14,141 @@ bool MIDI_Available(void); #define MPU_QUEUE 32 enum MpuMode { M_UART,M_INTELLIGENT } ; -#define CMD_RET_ACK 0xfe + +///////////////////////////////////////////////////////////////////////////// +// I/O +///////////////////////////////////////////////////////////////////////////// + +#define MPU_STATUS_DSR (1 << 7) +#define MPU_STATUS_DRR (1 << 6) +#define MPU_STATUS_PAD (0xff & (~(MPU_STATUS_DRR | MPU_STATUS_DSR))) + +#define MK_MPU_STATUS(dsr, drr)\ + (((dsr) ? 0 : MPU_STATUS_DSR) | ((drr) ? 0 : MPU_STATUS_DRR) | MPU_STATUS_PAD) + + +///////////////////////////////////////////////////////////////////////////// +// Commands +///////////////////////////////////////////////////////////////////////////// + +/** Copyright notice for MPU-401 intelligent-mode command constants ********* + + MPU-401 MIDI Interface Module v1.0 + Copyright (c) 1991, Robin Davies. All Rights Reserved. + + Robin Davies + 224 3rd Avenue + Ottawa, Ontario + Canada. K1S 2K3. + + updated by: + + Larry Troxler, Compuserve 73520,1736 + +****************************************************************************/ + +// Start/Stop Commands + +#define CMD_MIDI_STOP 0x01 +#define CMD_MIDI_START 0x02 +#define CMD_MIDI_CONTINUE 0x03 + +#define CMD_PLAY_STOP 0x04 +#define CMD_PLAY_START 0x08 +#define CMD_PLAY_CONTINUE 0x0c + +#define CMD_RECORD_STOP 0x10 +#define CMD_RECORD_START 0x20 + +// Commands + +#define CMD_DISABLE_ALL_NOTES_OFF 0x30 +#define CMD_DISABLE_REAL_TIME_OUT 0x32 +#define CMD_TIMING_BYTE_ALWAYS 0x34 +#define CMD_MODE_MESS_ON 0x35 +#define CMD_EXCLUSIVE_THRU_ON 0x37 +#define CMD_COMMON_TO_HOST_ON 0x38 +#define CMD_REAL_TIME_TO_HOST_ON 0x39 +#define CMD_UART_MODE 0x3f + +#define CMD_INT_CLOCK 0x80 +#define CMD_FSK_CLOCK 0x81 +#define CMD_MIDI_CLOCK 0x82 +#define CMD_METRONOME_ON 0x83 +#define CMD_METRONOME_OFF 0x84 +#define CMD_METRONOME_W_ACCENTS 0x85 +#define CMD_BENDER_OFF 0x86 +#define CMD_BENDER_ON 0x87 +#define CMD_MIDI_THRU_OFF 0x88 +#define CMD_MIDI_THRU_ON 0x89 +#define CMD_DATA_IN_STOP_MODE_OFF 0x8a +#define CMD_DATA_IN_STOP_MODE_ON 0x8b +#define CMD_SEND_MEASURE_END_OFF 0x8c +#define CMD_SEND_MEASURE_END_ON 0x8d +#define CMD_CONDUCTOR_OFF 0x8e +#define CMD_CONDUCTOR_ON 0x8f +#define CMD_REAL_TIME_AFFECTION_OFF 0x90 +#define CMD_REAL_TIME_AFFECTION_ON 0x91 +#define CMD_FSK_TO_INTERNAL 0x92 +#define CMD_FSK_TO_MIDI 0x93 +#define CMD_CLOCK_TO_HOST_OFF 0x94 +#define CMD_CLOCK_TO_HOST_ON 0x95 +#define CMD_EXCLUSIVE_TO_HOST_OFF 0x96 +#define CMD_EXCLUSIVE_TO_HOST_ON 0x97 + +#define CMD_RESET_RELATIVE_TEMPO 0xb1 +#define CMD_CLEAR_PLAY_COUNTERS 0xb8 +#define CMD_CLEAR_PLAY_MAP 0xb9 +#define CMD_CLEAR_RECORD_COUNTER 0xba +#define CMD_TIMEBASE_48 0xc2 +#define CMD_TIMEBASE_72 0xc3 +#define CMD_TIMEBASE_96 0xc4 +#define CMD_TIMEBASE_120 0xc5 +#define CMD_TIMEBASE_144 0xc6 +#define CMD_TIMEBASE_168 0xc7 +#define CMD_TIMEBASE_192 0xc8 + +#define CMD_REQUEST_TO_SEND_DATA 0xd0 /* + track #! */ +#define CMD_REQUEST_TO_SEND_SYSTEM_MSG 0xdf + +#define CMD_SET_TEMPO 0xe0 +#define CMD_RELATIVE_TEMPO 0xe1 +#define CMD_RELATIVE_TEMPO_GRADUATION 0xe2 +#define CMD_MIDI_METRONOME 0xe4 +#define CMD_MEASURE_LENGTH 0xe6 +#define CMD_INTERNAL_CLOCK_LENGTH_TO_HOST /* ? */ +#define CMD_ACTIVE_TRACK_MASK 0xec +#define CMD_SEND_PLAY_COUNTER_MASK 0xed +#define CMD_MIDI_CHANNEL_MASK_LO 0xee +#define CMD_MIDI_CHANNEL_MASK_HI 0xef + +#define CMD_EOX 0xf7 +#define CMD_TIMING_OVERFLOW 0xf8 +#define CMD_MPU_MARK 0xfc +#define CMD_RESET 0xff + +// Commands that return data + +#define CMD_REQUEST_PLAY_COUNTER 0xa0 +#define CMD_REQUEST_AND_CLEAR_PLAY_COUNTER 0xab +#define CMD_REQUEST_VERSION 0xac +#define CMD_REQUEST_REVISION 0xad +#define CMD_REQUEST_TEMPO 0xaf + + +///////////////////////////////////////////////////////////////////////////// +// Messages +///////////////////////////////////////////////////////////////////////////// + +#define MSG_CMD_ACK 0xfe + + static struct { MpuMode mode; Bit8u queue[MPU_QUEUE]; Bitu queue_pos,queue_used; + Bitu cmd; } mpu; @@ -39,16 +168,24 @@ static void ClrQueue(void) { static void MPU401_WriteCommand(Bit32u port,Bit8u val) { switch (val) { - case 0x3f: /* Switch to UART Mode */ + case CMD_UART_MODE: /* Switch to UART Mode */ mpu.mode=M_UART; - QueueByte(CMD_RET_ACK); + QueueByte(MSG_CMD_ACK); break; - case 0xff: /* Reset Commmand */ + case CMD_RESET: /* Reset Commmand */ + mpu.mode=M_INTELLIGENT; ClrQueue(); - QueueByte(CMD_RET_ACK); + QueueByte(MSG_CMD_ACK); break; + + case CMD_REQUEST_TO_SEND_DATA: + case CMD_REQUEST_TO_SEND_SYSTEM_MSG: + QueueByte(MSG_CMD_ACK); + break; + default: LOG(LOG_MISC,"MPU401:Unhandled command %X",val); + QueueByte(MSG_CMD_ACK); break; } @@ -67,7 +204,7 @@ static void MPU401_WriteData(Bit32u port,Bit8u val) { } static Bit8u MPU401_ReadData(Bit32u port) { - Bit8u ret=CMD_RET_ACK; + Bit8u ret=MSG_CMD_ACK; if (mpu.queue_used) { ret=mpu.queue[mpu.queue_pos]; mpu.queue_pos++; @@ -79,6 +216,9 @@ static Bit8u MPU401_ReadData(Bit32u port) { void MPU401_Init(Section* sec) { + Section_prop * section=static_cast(sec); + if(!section->Get_bool("mpu401")) return; + if (!MIDI_Available()) return; IO_RegisterWriteHandler(0x330,&MPU401_WriteData,"MPU401"); From 4fd112b3f3f0d321e354735aeae200cc83fb81f7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 10 Mar 2003 16:25:05 +0000 Subject: [PATCH 0660/4131] Enable/Disable mpu-401 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@739 --- src/dosbox.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 740be7ea..7fc29e0a 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -206,6 +206,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&CMS_Init); secprop->Add_bool("cms",false); secprop->AddInitFunction(&MPU401_Init); + secprop->Add_bool("mpu401",true); secprop=control->AddSection_prop("gus",&GUS_Init); From 86bcde167ec5be8f0752c39b3572ce82cdf2b9d6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 10 Mar 2003 16:38:49 +0000 Subject: [PATCH 0661/4131] settings.h be gone Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@740 --- include/dosbox.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/dosbox.h b/include/dosbox.h index 12648595..03205ec0 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -48,7 +48,6 @@ typedef signed int Bits; #include #include "config.h" -#include "../settings.h" class Section; From 21a758ddcf16d0cce6d0f7bc308d2c91a9abd90d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 10 Mar 2003 16:50:06 +0000 Subject: [PATCH 0662/4131] Add new scale headers and remove settings.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@741 --- visualc/dosbox.dsp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index 31e450aa..c80543ae 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -306,7 +306,11 @@ SOURCE=..\include\render.h # End Source File # Begin Source File -SOURCE=..\src\gui\render_support.h +SOURCE=..\src\gui\render_normal.h +# End Source File +# Begin Source File + +SOURCE=..\src\gui\render_scale2x.h # End Source File # Begin Source File @@ -675,10 +679,6 @@ SOURCE=..\include\regs.h # End Source File # Begin Source File -SOURCE=..\settings.h -# End Source File -# Begin Source File - SOURCE=..\include\setup.h # End Source File # Begin Source File From fbda2d52aa8e44b38ac8d62bfc658ba971c87f70 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 10 Mar 2003 23:42:44 +0000 Subject: [PATCH 0663/4131] Use strcasecmp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@742 --- src/gui/render.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 094078bb..3ad0756b 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -24,6 +24,7 @@ #include "setup.h" #include "keyboard.h" #include "cross.h" +#include "support.h" #define MAX_RES 2048 @@ -365,8 +366,8 @@ void RENDER_Init(Section * sec) { KEYBOARD_AddEvent(KBD_f5,KBD_MOD_CTRL,EnableScreenShot); #endif const char * scaler=section->Get_string("scaler"); - if (!stricmp(scaler,"none")) render.op.want_type=OP_None; - else if (!stricmp(scaler,"scale2x")) render.op.want_type=OP_Scale2x; + if (!strcasecmp(scaler,"none")) render.op.want_type=OP_None; + else if (!strcasecmp(scaler,"scale2x")) render.op.want_type=OP_Scale2x; else { render.op.want_type=OP_None; LOG_MSG("Illegal scaler type %s,falling back to none.",scaler); From d24b927f52df501750bf456a72507c18d8cbd16e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 11 Mar 2003 00:03:56 +0000 Subject: [PATCH 0664/4131] Fixes to correctly load mmx version of scale2x Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@743 --- src/gui/render_scale2x.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/gui/render_scale2x.h b/src/gui/render_scale2x.h index 8d74d16f..78e27b0c 100644 --- a/src/gui/render_scale2x.h +++ b/src/gui/render_scale2x.h @@ -510,6 +510,24 @@ static void scale2x_line_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, const s scale2x_8_mmx_single(dst1, src2, src1, src0, count); } +static void Scale2x_8_mmx(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + if (dy<3) return; + Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch; + /* First line */ + scale2x_line_8_mmx(dest,dest+render.op.pitch,src,src,src+render.src.pitch,dx); + dest+=render.op.pitch*2; + src+=render.src.pitch; + dy-=2; + /* Middle part */ + for (;dy>0;dy--) { + scale2x_line_8_mmx((Bit8u *)dest,(Bit8u *)(dest+render.op.pitch),src-render.src.pitch,src,src+render.src.pitch,dx); + dest+=render.op.pitch*2; + src+=render.src.pitch; + } + /* Last Line */ + scale2x_line_8_mmx((Bit8u *)dest,(Bit8u *)(dest+render.op.pitch),src-render.src.pitch,src,src,dx); +} + #endif static void Render_Scale2x_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags) { @@ -519,7 +537,6 @@ static void Render_Scale2x_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,B render.op.bpp=bpp; render.op.pitch=pitch; render.op.type=OP_Scale2x; - render.op.part_handler=Scale2x_8; #if defined(SCALE2X_NORMAL) switch (bpp) { case 8: From 08706fc6452765d82a830448285e6706a23648f7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 11 Mar 2003 07:10:50 +0000 Subject: [PATCH 0665/4131] new mixer settings and changed default dir for screenshots Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@744 --- src/dosbox.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 7fc29e0a..f492c407 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -176,7 +176,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("render",&RENDER_Init); secprop->Add_int("frameskip",0); secprop->Add_bool("keepsmall",false); - secprop->Add_string("snapshots","snapshots"); + secprop->Add_string("snapshots","snaps"); secprop->Add_string("scaler","none"); secprop=control->AddSection_prop("cpu",&CPU_Init); @@ -189,6 +189,11 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&JOYSTICK_Init); secprop=control->AddSection_prop("mixer",&MIXER_Init); + secprop->Add_bool("nosound",false); + secprop->Add_int("freq",22050); + secprop->Add_int("blocksize",2048); + secprop->Add_string("wavedir","waves"); + secprop=control->AddSection_prop("midi",&MIDI_Init); #if C_DEBUG secprop=control->AddSection_prop("debug",&DEBUG_Init); From be88be2eaf8c1d4908e8ee3910b25457042703f2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 11 Mar 2003 08:56:57 +0000 Subject: [PATCH 0666/4131] add curses and png to $LIBS when selected. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@745 --- configure.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure.in b/configure.in index a9fce574..8a09aa90 100644 --- a/configure.in +++ b/configure.in @@ -53,6 +53,7 @@ AC_ARG_ENABLE(debug,[ --enable-debug Enable debug mode],[ AC_CHECK_LIB(curses, initscr, have_curses_lib=yes, , ) if test x$have_curses_lib = xyes -a x$have_curses_h = xyes ; then + LIBS="$LIBS -lcurses" AC_DEFINE(C_DEBUG,1) else AC_MSG_WARN([Can't enable debug mode without libcurses]) @@ -65,6 +66,7 @@ AC_ARG_ENABLE(shots,[ --enable-shots Enable screenshot support],[ AC_CHECK_LIB(png, png_check_sig, have_png_lib=yes, , -lz) if test x$have_curses_lib = xyes -a x$have_curses_h = xyes ; then + LIBS="$LIBS -lpng" AC_DEFINE(C_SSHOTS,1) else AC_MSG_WARN([Can't enable screenshots without libpng]) From 309571b32e0aa5372e874988a8e77d70645ec1f9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 11 Mar 2003 08:57:31 +0000 Subject: [PATCH 0667/4131] curses and png get linked through $LIBS Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@746 --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 151e5e04..24279b30 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,5 +6,5 @@ bin_PROGRAMS = dosbox dosbox_SOURCES = dosbox.cpp dosbox_LDADD = cpu/libcpu.a debug/libdebug.a dos/libdos.a fpu/libfpu.a hardware/libhardware.a gui/libgui.a \ - ints/libints.a misc/libmisc.a shell/libshell.a -lcurses -lpng + ints/libints.a misc/libmisc.a shell/libshell.a From bf97b03c0b7040bd3ee6e40adbb7b9768b1d33f9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 11 Mar 2003 09:17:10 +0000 Subject: [PATCH 0668/4131] Rewrote structures of mixer. Added support for writing wav files Added support for nosound mode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@747 --- src/hardware/mixer.cpp | 281 +++++++++++++++++++++++++++-------------- 1 file changed, 189 insertions(+), 92 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index bbf00b33..512c5676 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -22,51 +22,48 @@ */ #include -#include +#include + +#include "SDL.h" +#include "mem.h" #include "dosbox.h" #include "mixer.h" #include "timer.h" +#include "setup.h" +#include "cross.h" +#include "support.h" +#include "keyboard.h" #define MIXER_MAXCHAN 8 -#define MIXER_BLOCKSIZE 1024 -#define MIXER_BUFSIZE MIXER_BLOCKSIZE*8 +#define MIXER_BUFSIZE (16*1024) #define MIXER_SSIZE 4 #define MIXER_SHIFT 16 #define MIXER_REMAIN ((1<MAX_AUDIO) ? (Bit16s)MAX_AUDIO : (SAMPhandler)(((Bit8u*)&mix_temp)+sizeof(mix_temp.TYPE[0]),sample_toread); \ + (chan->handler)(((Bit8u*)&mixer.temp)+sizeof(mixer.temp.TYPE[0]),sample_toread); \ Bitu sample_index=(1 << MIXER_SHIFT) - chan->sample_left; \ Bit32s newsample; \ for (Bitu mix=0;mix> MIXER_SHIFT;sample_index+=chan->sample_add; \ - newsample=mix_buftemp[mix][0]+MAKE_##TYPE( LCHAN ); \ - mix_buftemp[mix][0]=MIXER_CLIP(newsample); \ - newsample=mix_buftemp[mix][1]+MAKE_##TYPE( RCHAN ); \ - mix_buftemp[mix][1]=MIXER_CLIP(newsample); \ + newsample=mixer.work[mix][0]+MAKE_##TYPE( LCHAN ); \ + mixer.work[mix][0]=MIXER_CLIP(newsample); \ + newsample=mixer.work[mix][1]+MAKE_##TYPE( RCHAN ); \ + mixer.work[mix][1]=MIXER_CLIP(newsample); \ } \ - chan->remain.TYPE[LCHAN]=mix_temp.TYPE[sample_index>>MIXER_SHIFT][LCHAN]; \ - if (RCHAN) chan->remain.TYPE[RCHAN]=mix_temp.TYPE[sample_index>>MIXER_SHIFT][RCHAN];\ + chan->remain=*(Bitu *)&mixer.temp.TYPE[sample_index>>MIXER_SHIFT]; \ chan->sample_left=sample_total-sample_index; \ break; \ } -union Sample { - Bit16s m16[1]; - Bit16s s16[2]; - Bit8u m8[1]; - Bit8u s8[2]; - Bit32u full; -}; - struct MIXER_Channel { Bit8u volume; Bit8u mode; @@ -75,29 +72,45 @@ struct MIXER_Channel { MIXER_MixHandler handler; Bitu sample_add; Bitu sample_left; - Sample remain; + Bitu remain; bool playing; MIXER_Channel * next; }; +static Bit8u wavheader[]={ + 'R','I','F','F', 0x0,0x0,0x0,0x0, /* Bit32u Riff Chunk ID / Bit32u riff size */ + 'W','A','V','E', 'f','m','t',' ', /* Bit32u Riff Format / Bit32u fmt chunk id */ + 0x10,0x0,0x0,0x0, 0x1,0x0,0x2,0x0, /* Bit32u fmt size / Bit16u encoding/ Bit16u channels */ + 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, /* Bit32u freq / Bit32u byterate */ + 0x4,0x0,0x10,0x0, 'd','a','t','a', /* Bit16u byte-block / Bit16u bits / Bit16u data chunk id */ + 0x0,0x0,0x0,0x0, /* Bit32u data size */ +}; -static MIXER_Channel * first_channel; -static union { - Bit16s m16[MIXER_BUFSIZE][1]; - Bit16s s16[MIXER_BUFSIZE][2]; - Bit8u m8[MIXER_BUFSIZE][1]; - Bit8u s8[MIXER_BUFSIZE][2]; - Bit32u full[MIXER_BUFSIZE]; -} mix_temp; - -static Bit16s mix_bufout[MIXER_BUFSIZE][2]; -static Bit16s mix_buftemp[MIXER_BUFSIZE][2]; -static Bit32s mix_bufextra; -static Bitu mix_writepos; -static Bitu mix_readpos; -static Bitu mix_ticks; -static Bitu mix_add; -static Bitu mix_remain; +static struct { + struct { + Bit16s data[MIXER_BUFSIZE][2]; + Bitu read,write; + } out; + Bit16s work[MIXER_BUFSIZE][2]; + union { + Bit16s m16[MIXER_BUFSIZE][1]; + Bit16s s16[MIXER_BUFSIZE][2]; + Bit8u m8[MIXER_BUFSIZE][1]; + Bit8u s8[MIXER_BUFSIZE][2]; + } temp; + MIXER_Channel * channels; + bool nosound; + Bitu freq; + Bitu blocksize; + Bitu tick_add,tick_remain; + struct { + FILE * handle; + const char * dir; + Bit8u buf[MIXER_WAVESIZE]; + Bitu used; + Bit32u length; + } wave; +} mixer; MIXER_Channel * MIXER_AddChannel(MIXER_MixHandler handler,Bit32u freq,char * name) { //TODO Find a free channel @@ -108,10 +121,10 @@ MIXER_Channel * MIXER_AddChannel(MIXER_MixHandler handler,Bit32u freq,char * nam chan->mode=MIXER_16STEREO; chan->handler=handler; chan->name=name; - chan->sample_add=(freq<sample_add=(freq<sample_left=0; - chan->next=first_channel; - first_channel=chan; + chan->next=mixer.channels; + mixer.channels=chan; return chan; }; @@ -119,7 +132,7 @@ void MIXER_SetFreq(MIXER_Channel * chan,Bit32u freq) { if (chan) { chan->freq=freq; /* Calculate the new addition value */ - chan->sample_add=(freq<sample_add=(freq<MIXER_BUFSIZE) samples=MIXER_BUFSIZE; - /* 16-bit stereo is 4 bytes per sample */ - memset((void *)&mix_buftemp,0,samples*MIXER_SSIZE); - MIXER_Channel * chan=first_channel; + /* Clear work buffer */ + memset(mixer.work,0,samples*MIXER_SSIZE); + MIXER_Channel * chan=mixer.channels; while (chan) { if (chan->playing) { /* This should always allocate 1 extra sample */ @@ -152,7 +165,7 @@ static void MIXER_MixData(Bit32u samples) { Bitu sample_toread=sample_total >> MIXER_SHIFT; if (sample_total & MIXER_REMAIN) sample_toread++; sample_total=(sample_toread+1)<remain.full; + *(Bitu *)&mixer.temp=chan->remain; switch (chan->mode) { case MIXER_8MONO: MIX_NORMAL(m8,0,0); @@ -173,77 +186,161 @@ static void MIXER_MixData(Bit32u samples) { } chan=chan->next; } - Bit32u buf_remain=MIXER_BUFSIZE-mix_writepos; + Bitu buf_remain=MIXER_BUFSIZE-mixer.out.write; /* Fill the samples size buffer with 0's */ if (buf_remain>samples) { - memcpy(&mix_bufout[mix_writepos][0],&mix_buftemp[0][0],samples*MIXER_SSIZE); - mix_writepos+=samples; + memcpy(&mixer.out.data[mixer.out.write][0],&mixer.work[0][0],samples*MIXER_SSIZE); + mixer.out.write+=samples; } else { - memcpy(&mix_bufout[mix_writepos][0],&mix_buftemp[0][0],buf_remain*MIXER_SSIZE); - memcpy(&mix_bufout[0][0],&mix_buftemp[buf_remain][0],(samples-buf_remain)*MIXER_SSIZE); - mix_writepos=(mix_writepos+samples)-MIXER_BUFSIZE; + memcpy(&mixer.out.data[mixer.out.write][0],&mixer.work[0][0],buf_remain*MIXER_SSIZE); + memcpy(&mixer.out.data[0][0],&mixer.work[buf_remain][0],(samples-buf_remain)*MIXER_SSIZE); + mixer.out.write=(mixer.out.write+samples)-MIXER_BUFSIZE; + } + if (mixer.wave.handle) { + memcpy(&mixer.wave.buf[mixer.wave.used],&mixer.work[0][0],samples*MIXER_SSIZE); + mixer.wave.length+=samples*MIXER_SSIZE; + mixer.wave.used+=samples*MIXER_SSIZE; + if (mixer.wave.used>(MIXER_WAVESIZE-1024)){ + fwrite(mixer.wave.buf,1,mixer.wave.used,mixer.wave.handle); + mixer.wave.used=0; + } } - - } -void MIXER_Mix(Bitu ticks) { -/* Check for 1 ms of sound to mix */ - Bitu count=(ticks*mix_add)+mix_remain; - mix_remain=count&((1<<10)-1); - count>>=10; - Bit32u size=MIXER_BUFSIZE+mix_writepos-mix_readpos; +static void MIXER_Mix(Bitu ticks) { + mixer.tick_remain+=mixer.tick_add; + Bitu count=mixer.tick_remain>>MIXER_SHIFT; + mixer.tick_remain&=((1<=MIXER_BUFSIZE) size-=MIXER_BUFSIZE; - if (size>MIXER_BLOCKSIZE+2048) return; + if (size>mixer.blocksize*2) return; MIXER_MixData(count); - } -static Bit32u last_pos; +static void MIXER_Mix_NoSound(Bitu ticks) { + mixer.tick_remain+=mixer.tick_add; + Bitu count=mixer.tick_remain>>MIXER_SHIFT; + mixer.tick_remain&=((1<=(Bit32u)len/MIXER_SSIZE) { - memcpy((void *)stream,(void *)&mix_bufout[mix_readpos][0],len); - } else { - memcpy((void *)stream,(void *)&mix_bufout[mix_readpos][0],remain*MIXER_SSIZE); - stream+=remain*MIXER_SSIZE; - memcpy((void *)stream,(void *)&mix_bufout[0][0],(len)-remain*MIXER_SSIZE); + /* Copy data from out buffer to the stream */ + Bitu size=MIXER_BUFSIZE+mixer.out.write-mixer.out.read; + if (size>=MIXER_BUFSIZE) size-=MIXER_BUFSIZE; + if (size*MIXER_SSIZE=MIXER_BUFSIZE) mix_readpos-=MIXER_BUFSIZE; + Bitu remain=MIXER_BUFSIZE-mixer.out.read; + if (remain>=(Bitu)len/MIXER_SSIZE) { + memcpy((void *)stream,(void *)&mixer.out.data[mixer.out.read][0],len); + } else { + memcpy((void *)stream,(void *)&mixer.out.data[mixer.out.read][0],remain*MIXER_SSIZE); + stream+=remain*MIXER_SSIZE; + memcpy((void *)stream,(void *)&mixer.out.data[0][0],(len)-remain*MIXER_SSIZE); + } + mixer.out.read+=(len/MIXER_SSIZE); + if (mixer.out.read>=MIXER_BUFSIZE) mixer.out.read-=MIXER_BUFSIZE; } +static void MIXER_WaveEvent(void) { + Bitu last=0;char file_name[CROSS_LEN]; + DIR * dir;struct dirent * dir_ent; + /* Check for previously opened wave file */ + if (mixer.wave.handle) { + LOG_MSG("Stopped recording"); + /* Write last piece of audio in buffer */ + fwrite(mixer.wave.buf,1,mixer.wave.used,mixer.wave.handle); + /* Fill in the header with useful information */ + writed(&wavheader[4],mixer.wave.length+sizeof(wavheader)-8); + writed(&wavheader[0x18],mixer.freq); + writed(&wavheader[0x1C],mixer.freq*4); + writed(&wavheader[0x28],mixer.wave.length); + + fseek(mixer.wave.handle,0,0); + fwrite(wavheader,1,sizeof(wavheader),mixer.wave.handle); + fclose(mixer.wave.handle); + mixer.wave.handle=0; + return; + } + /* Find a filename to open */ + dir=opendir(mixer.wave.dir); + if (!dir) { + LOG_MSG("Can't open waveout dir %s",mixer.wave.dir); + return; + } + while (dir_ent=readdir(dir)) { + char tempname[CROSS_LEN]; + strcpy(tempname,dir_ent->d_name); + char * test=strstr(tempname,".wav"); + if (!test) continue; + *test=0; + if (strlen(tempname)<5) continue; + if (strncmp(tempname,"wave",4)!=0) continue; + Bitu num=atoi(&tempname[4]); + if (num>=last) last=num+1; + } + closedir(dir); + sprintf(file_name,"%s%cwave%04d.wav",mixer.wave.dir,CROSS_FILESPLIT,last); + /* Open the actual file */ + mixer.wave.handle=fopen(file_name,"wb"); + if (!mixer.wave.handle) { + LOG_MSG("Can't open file %s for waveout",file_name); + return; + } + mixer.wave.length=0; + LOG_MSG("Started recording to file %s",file_name); + fwrite(wavheader,1,sizeof(wavheader),mixer.wave.handle); +} + +static void MIXER_Stop(Section* sec) { + if (mixer.wave.handle) MIXER_WaveEvent(); +} void MIXER_Init(Section* sec) { - MSG_Add("MIXER_CONFIGFILE_HELP","Nothing to setup yet!\n"); + sec->AddDestroyFunction(&MIXER_Stop); + MSG_Add("MIXER_CONFIGFILE_HELP","Nothing to setup yet!\n"); + Section_prop * section=static_cast(sec); + /* Read out config section */ + mixer.freq=section->Get_int("freq"); + mixer.nosound=section->Get_bool("nosound"); + mixer.blocksize=section->Get_int("blocksize"); + mixer.wave.dir=section->Get_string("wavedir"); + /* Initialize the internal stuff */ - first_channel=0; - mix_ticks=GetTicks(); - mix_bufextra=0; - mix_writepos=0; - mix_readpos=0; + mixer.channels=0; + mixer.out.write=0; + mixer.out.read=0; + memset(mixer.out.data,0,sizeof(mixer.out.data)); + mixer.wave.handle=0; + mixer.wave.used=0; /* Start the Mixer using SDL Sound at 22 khz */ SDL_AudioSpec spec; SDL_AudioSpec obtained; - mix_add=((MIXER_FREQ) << 10)/1000; - mix_remain=0; - spec.freq=MIXER_FREQ; + + spec.freq=mixer.freq; spec.format=AUDIO_S16SYS; spec.channels=2; spec.callback=MIXER_CallBack; spec.userdata=NULL; - spec.samples=MIXER_BLOCKSIZE; - - TIMER_RegisterTickHandler(MIXER_Mix); + spec.samples=mixer.blocksize; - if ( SDL_OpenAudio(&spec, &obtained) < 0 ) { - LOG_MSG("No sound output device found, starting in no sound mode"); + mixer.tick_remain=0; + if (mixer.nosound || (SDL_OpenAudio(&spec, &obtained) < 0 )) { + mixer.tick_add=((mixer.freq) << MIXER_SHIFT)/1000; + TIMER_RegisterTickHandler(MIXER_Mix_NoSound); + LOG_MSG("MIXER:Running in nosound mode."); } else { - MIXER_MixData(MIXER_BLOCKSIZE/MIXER_SSIZE); + mixer.freq=obtained.freq; + mixer.blocksize=obtained.samples; + mixer.tick_add=((mixer.freq+100) << MIXER_SHIFT)/1000; + TIMER_RegisterTickHandler(MIXER_Mix); SDL_PauseAudio(0); } + KEYBOARD_AddEvent(KBD_f6,KBD_MOD_CTRL,MIXER_WaveEvent); } From 4bfdc29caa4d9391dace8a2b1b315926985e2dc1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 11 Mar 2003 09:20:46 +0000 Subject: [PATCH 0669/4131] Corrected detection op png Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@748 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 8a09aa90..40a08010 100644 --- a/configure.in +++ b/configure.in @@ -65,7 +65,7 @@ AC_ARG_ENABLE(shots,[ --enable-shots Enable screenshot support],[ AC_CHECK_HEADER(png.h,have_png_h=yes,) AC_CHECK_LIB(png, png_check_sig, have_png_lib=yes, , -lz) - if test x$have_curses_lib = xyes -a x$have_curses_h = xyes ; then + if test x$have_png_lib = xyes -a x$have_png_h = xyes ; then LIBS="$LIBS -lpng" AC_DEFINE(C_SSHOTS,1) else From 2d1f80ab1d0bbc1e564c5dd4ff9051732037aed5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 11 Mar 2003 09:55:56 +0000 Subject: [PATCH 0670/4131] preparations 0.58 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@749 --- NEWS | 20 ++++++++++++++++++++ README | 2 +- VERSION | 2 +- configure.in | 2 +- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 037b0609..915d0916 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,23 @@ +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 + + 0.57 - added support for command /C - fixed all fcb-write functions diff --git a/README b/README index 06b5c37c..49009c8d 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -DOSBox v0.57 +DOSBox v0.58 Usage: ====== diff --git a/VERSION b/VERSION index 96ca7699..f2c6f753 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.57 +0.58 diff --git a/configure.in b/configure.in index 40a08010..214eff05 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Init. -AC_INIT(dosbox,0.57) +AC_INIT(dosbox,0.58) AC_PREREQ(2.50) AC_CONFIG_SRCDIR(README) From d7066655bc51d1c4253643adf68aea5b2ac1825e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 12 Mar 2003 12:50:17 +0000 Subject: [PATCH 0671/4131] #else if -> #elif Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@750 --- src/dos/cdrom_ioctl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/cdrom_ioctl.cpp b/src/dos/cdrom_ioctl.cpp index 4b9fb535..f3a0df2f 100644 --- a/src/dos/cdrom_ioctl.cpp +++ b/src/dos/cdrom_ioctl.cpp @@ -246,7 +246,7 @@ int CDROM_GetMountType(char* path) return 2; }; -#else #if defined (WIN32) +#elif defined (WIN32) // ***************************************************************** From c131ab0320d90fcddc36341bc75a8acb39cf5b7f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 12 Mar 2003 12:53:55 +0000 Subject: [PATCH 0672/4131] changed defines Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@751 --- src/gui/render_scale2x.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/render_scale2x.h b/src/gui/render_scale2x.h index 78e27b0c..2cc1547b 100644 --- a/src/gui/render_scale2x.h +++ b/src/gui/render_scale2x.h @@ -59,7 +59,7 @@ typedef Bit8u scale2x_uint8; typedef Bit16u scale2x_uint16; typedef Bit32u scale2x_uint32; -#if !defined(__GNUC__) && !defined(__i386__) +#if !defined(__GNUC__) || !defined(__i386__) #define SCALE2X_NORMAL 1 From 0e35a7dfe21371bef11e43e65a341e1df107b9fc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 12 Mar 2003 12:58:15 +0000 Subject: [PATCH 0673/4131] added sys/types.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@752 --- src/gui/render.cpp | 1 + src/hardware/mixer.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 3ad0756b..89e02f32 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include #include #include "dosbox.h" diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 512c5676..f92ab004 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -22,6 +22,7 @@ */ #include +#include #include #include "SDL.h" From 90b535d377bceccb4ad31a9e96d2447ba7c11757 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 12 Mar 2003 13:15:30 +0000 Subject: [PATCH 0674/4131] added ctype.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@753 --- src/dos/cdrom.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 9a4725b3..fffcd18f 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -21,6 +21,7 @@ #ifdef WIN32 #include +#include #include "cdrom.h" #include "scsidefs.h" // Aspi stuff From f9c6a97f5ed9a13dee78ea3bea27934da76bb2da Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 12 Mar 2003 13:20:43 +0000 Subject: [PATCH 0675/4131] always use cdrom fake interface if not win or linux. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@754 --- src/dos/dos_mscdex.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 702fe9e8..af48208b 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -239,8 +239,11 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) cdrom[numDrives] = new CDROM_Interface_Aspi(); LOG(LOG_MISC,"MSCDEX: ASPI Interface."); } - #else + #elif __linux__ cdrom[numDrives] = new CDROM_Interface_Linux(); + #else // No support on this machine... + cdrom[numDrives] = new CDROM_Interface_Fake(); + LOG(LOG_MISC|LOG_ERROR,"MSCDEX: No MSCDEX support on this machine."); #endif LOG(LOG_MISC,"MSCDEX: Mounting physical cdrom: %s" ,physicalPath); } break; From 352f47bd463b337c0ae7128b6ab85f88062f4476 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 12 Mar 2003 13:24:47 +0000 Subject: [PATCH 0676/4131] Detection of gcc win32 and macos hosts. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@755 --- configure.in | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/configure.in b/configure.in index 214eff05..37e4dfc2 100644 --- a/configure.in +++ b/configure.in @@ -73,6 +73,20 @@ AC_ARG_ENABLE(shots,[ --enable-shots Enable screenshot support],[ fi ],) +dnl Some host detection and actions for them +case "$target" in + *-*-cygwin* | *-*-mingw32*) + LIBS="$LIBS -lwinmm" + ;; + darwin*) + dnl We have a problem here: both MacOS X and Darwin report + dnl the same signature "powerpc-apple-darwin*" - so we have + dnl to do more to distinguish them. + dnl For now I am lazy and do not add proper detection code. + AC_DEFINE(MACOSX, 1, [Compiling on Mac OS X]) + LIBS="$LIBS -framework AudioUnit" + ;; +esac AC_OUTPUT([ From c2a123dc37141b2299e7ac92d05b2e8e62638e4d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 12 Mar 2003 13:25:04 +0000 Subject: [PATCH 0677/4131] don't need Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@756 --- src/gui/midi_win32.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index 5f30c293..5f6e1d1d 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -18,7 +18,6 @@ #include #include -#include static HMIDIOUT m_out; static MIDIHDR m_hdr; From 7ea6fa09f95a671096de8219b6cdfd1814f25796 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 12 Mar 2003 13:28:36 +0000 Subject: [PATCH 0678/4131] CDROM_GetMountType func for unsupported systems Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@757 --- src/dos/cdrom_ioctl.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/dos/cdrom_ioctl.cpp b/src/dos/cdrom_ioctl.cpp index f3a0df2f..51356562 100644 --- a/src/dos/cdrom_ioctl.cpp +++ b/src/dos/cdrom_ioctl.cpp @@ -517,4 +517,15 @@ int CDROM_GetMountType(char* path) return 2; }; */ -#endif +#else + +// Get Mounttype function for unsupported systems +// always return 0 - physical cdrom + +int CDROM_GetMountType(char* path) +// Always return 0; +{ + return 0; +}; + +#endif \ No newline at end of file From 469013e618a82496df124fee97ff2b945c5d12ef Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 13 Mar 2003 10:16:59 +0000 Subject: [PATCH 0679/4131] drivecache removes trailing dot, if no extension is available (linux compatibility) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@758 --- src/dos/drive_cache.cpp | 16 ++++++++++++++++ src/dos/drives.h | 7 ++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 820e6925..3241cc3d 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -279,8 +279,23 @@ Bit16u DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name) return foundNr+1; }; +bool DOS_Drive_Cache::RemoveTrailingDot(char* shortname) +// remove trailing '.' if no extension is available (Linux compatibility) +{ + Bitu len = strlen(shortname); + if (len && (shortname[len-1]=='.')) { + if (len==1) return false; + if ((len==2) && (shortname[0]=='.')) return false; + shortname[len-1] = 0; + return true; + } + return false; +}; + Bit16s DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) { + // Remove dot, if no extension... + RemoveTrailingDot(shortName); // Search long name and return array number of element Bit16s low = 0; Bit16s high = curDir->fileList.size()-1; @@ -381,6 +396,7 @@ void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) } else { strcpy(info->shortname,tmpName); } + RemoveTrailingDot(info->shortname); }; DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* expandedPath) diff --git a/src/dos/drives.h b/src/dos/drives.h index 375e789e..8c8f6887 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -63,9 +63,9 @@ public: char orgname [CROSS_LEN]; char shortname [DOS_NAMELENGTH_ASCII]; bool isDir; - Bit16u nextEntry; - Bit16u shortNr; - Bit16u compareCount; + Bitu nextEntry; + Bitu shortNr; + Bitu compareCount; // contents std::vector fileList; std::vector longNameList; @@ -74,6 +74,7 @@ public: private: + bool RemoveTrailingDot (char* shortname); Bit16s GetLongName (CFileInfo* info, char* shortname); void CreateShortName (CFileInfo* dir, CFileInfo* info); Bit16u CreateShortNameID (CFileInfo* dir, const char* name); From 499faf568e2a706cf380e7c151a8b148a5d0ade3 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 13 Mar 2003 10:29:43 +0000 Subject: [PATCH 0680/4131] reset a few mouse parameter on mouse software reset. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@759 --- src/ints/mouse.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 3a78c19d..511e0ad9 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -558,6 +558,10 @@ static Bitu INT33_Handler(void) { break; case 0x21: /* Software Reset */ //TODO reset internal mouse software variables likes mickeys + mouse.events = 0; + mouse.sub_mask = 0; + mouse.sub_seg = 0; + mouse.sub_ofs = 0; reg_ax=0xffff; reg_bx=2; break; From 1e853d8dc621d4f502b3d63cea4d223a40057100 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 13 Mar 2003 21:20:22 +0000 Subject: [PATCH 0681/4131] Some support for special latch command. Fix to mode 0 timers. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@760 --- src/hardware/timer.cpp | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 8a66555a..75f6d3dd 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -58,20 +58,25 @@ static void counter_latch(Bitu counter) { Bit64s micro=PIC_MicroCount()-p->start; switch (p->mode) { - case 0: - if (micro>p->micro) p->read_latch=p->write_latch; - else p->read_latch=(Bit16u)(p->cntr-(((float)micro/(float)p->micro)*(float)p->cntr)); - break; - case 2: + case 0: /* Interrupt on Terminal Count */ + /* Counter keeps on counting after passing terminal count */ micro%=p->micro; p->read_latch=(Bit16u)(p->cntr-(((float)micro/(float)p->micro)*(float)p->cntr)); break; - case 3: + case 2: /* Rate Generator */ + micro%=p->micro; + p->read_latch=(Bit16u)(p->cntr-(((float)micro/(float)p->micro)*(float)p->cntr)); + break; + case 3: /* Square Wave Rate Generator */ micro%=p->micro; micro*=2; if (micro>p->micro) micro-=p->micro; p->read_latch=(Bit16u)(p->cntr-(((float)micro/(float)p->micro)*(float)p->cntr)); break; + case 4: /* Software Triggered Strobe */ + if (micro>p->micro) p->read_latch=p->write_latch; + else p->read_latch=(Bit16u)(p->cntr-(((float)micro/(float)p->micro)*(float)p->cntr)); + break; default: LOG(LOG_ERROR|LOG_PIT,"Illegal Mode %d for reading counter %d",p->mode,counter); micro%=p->micro; @@ -112,7 +117,7 @@ static void write_latch(Bit32u port,Bit8u val) { LOG(LOG_PIT,"PIT 0 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode); break; case 0x02: /* Timer hooked to PC-Speaker */ -// LOG_DEBUG("PIT 2 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode); +// LOG(LOG_PIT,"PIT 2 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode); PCSPEAKER_SetCounter(p->cntr,p->mode); break; default: @@ -159,14 +164,12 @@ static Bit8u read_latch(Bit32u port) { static void write_p43(Bit32u port,Bit8u val) { - if (val & 1) { - E_Exit("PIT:BCD Counter not supported"); - } Bitu latch=(val >> 6) & 0x03; switch (latch) { case 0: case 1: case 2: + if (val & 1) E_Exit("PIT:Timer %d set to unsupported bcd mode",latch); if ((val & 0x30) == 0) { /* Counter latch command */ counter_latch(latch); @@ -177,9 +180,13 @@ static void write_p43(Bit32u port,Bit8u val) { } break; case 3: - E_Exit("Special PIT Latch Read out thing"); + if ((val & 0x20)==0) { /* Latch multiple pit counters */ + if (val & 0x02) counter_latch(0); + if (val & 0x04) counter_latch(1); + if (val & 0x08) counter_latch(2); + } else E_Exit("PIT:Latch Timer Status %X",val); + break; } - } /* The TIMER Part */ From f462528afb4d4ed1f48b18ac773ca246126d16b7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 13 Mar 2003 21:21:36 +0000 Subject: [PATCH 0682/4131] Some extra ports in the dma range return values. Added a warning for illegal ports written to. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@761 --- src/hardware/dma.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index c102116e..9f9e61b0 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -96,9 +96,13 @@ static Bit8u read_dma(Bit32u port) { ret=cont->status_reg; cont->status_reg&=0xf; /* Clear lower 4 bits on read */ break; - + case 0x0a: + case 0x0e: + /* Seem to return 0 on a real controller */ + ret=0x0; + break; default: - LOG(LOG_ERROR,"DMA:Unhandled read from %d",port); + LOG(LOG_ERROR,"DMA:Unhandled read from %X",port); } return ret; } @@ -162,7 +166,9 @@ static void write_dma(Bit32u port,Bit8u val) { case 0x0c: /* Clear Flip/Flip */ cont->flipflop=true; break; - }; + default: + LOG(LOG_ERROR,"DMA:Unhandled write %X to %X",val,port); + }; }; From 5bf4faa8285c526a322b37f9a01410ad5868a519 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 13 Mar 2003 21:22:55 +0000 Subject: [PATCH 0683/4131] fix for vc optimization bug in EA_32_44_n and EA_32_84_n Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@762 --- src/cpu/core_16/table_ea.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_16/table_ea.h b/src/cpu/core_16/table_ea.h index d702fe1a..9393a25d 100644 --- a/src/cpu/core_16/table_ea.h +++ b/src/cpu/core_16/table_ea.h @@ -233,7 +233,7 @@ static EAPoint EA_32_40_n(void) { PrefixReset;return SegBase(ds)+reg_eax+Fetchbs static EAPoint EA_32_41_n(void) { PrefixReset;return SegBase(ds)+reg_ecx+Fetchbs(); } static EAPoint EA_32_42_n(void) { PrefixReset;return SegBase(ds)+reg_edx+Fetchbs(); } static EAPoint EA_32_43_n(void) { PrefixReset;return SegBase(ds)+reg_ebx+Fetchbs(); } -static EAPoint EA_32_44_n(void) { PrefixReset;return Sib(1)+Fetchbs();} +static EAPoint EA_32_44_n(void) { PrefixReset;EAPoint temp=Sib(1);return temp+Fetchbs();} static EAPoint EA_32_45_n(void) { PrefixReset;return SegBase(ss)+reg_ebp+Fetchbs(); } static EAPoint EA_32_46_n(void) { PrefixReset;return SegBase(ds)+reg_esi+Fetchbs(); } static EAPoint EA_32_47_n(void) { PrefixReset;return SegBase(ds)+reg_edi+Fetchbs(); } @@ -242,7 +242,7 @@ static EAPoint EA_32_80_n(void) { PrefixReset;return SegBase(ds)+reg_eax+Fetchds static EAPoint EA_32_81_n(void) { PrefixReset;return SegBase(ds)+reg_ecx+Fetchds(); } static EAPoint EA_32_82_n(void) { PrefixReset;return SegBase(ds)+reg_edx+Fetchds(); } static EAPoint EA_32_83_n(void) { PrefixReset;return SegBase(ds)+reg_ebx+Fetchds(); } -static EAPoint EA_32_84_n(void) { PrefixReset;return Sib(2)+Fetchds();} +static EAPoint EA_32_84_n(void) { PrefixReset;EAPoint temp=Sib(2);return temp+Fetchbs();} static EAPoint EA_32_85_n(void) { PrefixReset;return SegBase(ss)+reg_ebp+Fetchds(); } static EAPoint EA_32_86_n(void) { PrefixReset;return SegBase(ds)+reg_esi+Fetchds(); } static EAPoint EA_32_87_n(void) { PrefixReset;return SegBase(ds)+reg_edi+Fetchds(); } From 02784e988b4082f6fb7c60080cd672c1c2f42a58 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 13 Mar 2003 21:50:27 +0000 Subject: [PATCH 0684/4131] Added random busy signal on dsp write port Added command 0xda, exit autoinitialize 8-bit. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@763 --- src/hardware/sblaster.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 368fad74..f5af8d9a 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -98,6 +98,7 @@ struct SB_INFO { Bitu pos,used; } in,out; Bit8u test_register; + Bitu write_busy; } dsp; struct { Bit16s data[DSP_DACSIZE]; @@ -434,6 +435,7 @@ static void DSP_Reset(void) { DSP_ChangeMode(MODE_NONE); sb.dsp.cmd_len=0; sb.dsp.in.pos=0; + sb.dsp.write_busy=0; sb.dma.left=0; sb.dma.total=0; sb.freq=22050; @@ -521,6 +523,10 @@ static void DSP_DoCommand(void) { DSP_ChangeMode(MODE_DMA_WAIT); DMA_SetEnableCallBack(sb.hw.dma8,DMA_Enable); break; + case 0xda: /* Exit Autoinitialize 8-bit */ + /* Set mode to single transfer so it ends with current block */ + if (sb.dma.mode==DMA_8_AUTO) sb.dma.mode=DMA_8_SINGLE; + break; case 0xe0: /* DSP Identification - SB2.0+ */ DSP_FlushData(); DSP_AddData(~sb.dsp.in.data[0]); @@ -640,6 +646,8 @@ static Bit8u read_sb(Bit32u port) { case DSP_WRITE_STATUS: switch (sb.dsp.state) { case DSP_S_NORMAL: + sb.dsp.write_busy++; + if (sb.dsp.write_busy & 8) return 0xff; return 0x7f; case DSP_S_RESET: return 0xff; From 91d4209ca8eb33b7a4393f2827c78ae4ce354506 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 14 Mar 2003 09:01:21 +0000 Subject: [PATCH 0685/4131] Added get/set/search handle name functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@764 --- src/ints/ems.cpp | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 2a6e4673..78ba1777 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -374,6 +374,7 @@ static Bit8u EMM_PartialPageMapping(void) { } static Bit8u HandleNameSearch(void) { + char name[9]; Bit16u handle=0;PhysPt data; switch (reg_al) { case 0x00: /* Get all handle names */ @@ -387,6 +388,18 @@ static Bit8u HandleNameSearch(void) { } } break; + case 0x01: /* Search for a handle name */ + MEM_StrCopy(SegPhys(ds)+reg_si,name,8);name[8]=0; + for (handle=0;handle=EMM_MAX_HANDLES || emm_handles[handle].pages==NULL_HANDLE) return EMM_INVALID_HANDLE; + MEM_BlockWrite(SegPhys(es)+reg_di,emm_handles[handle].name,8); + break; + case 0x01: /* Set Handle Name */ + if (handle>=EMM_MAX_HANDLES || emm_handles[handle].pages==NULL_HANDLE) return EMM_INVALID_HANDLE; + MEM_BlockRead(SegPhys(es)+reg_di,emm_handles[handle].name,8); + break; + default: + LOG(LOG_ERROR|LOG_MISC,"EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); + return EMM_FUNC_NOSUP; + } + return EMM_NO_ERROR; + +} + static void LoadMoveRegion(PhysPt data,MoveRegion & region) { region.bytes=mem_readd(data+0x0); @@ -614,12 +646,7 @@ static Bitu INT67_Handler(void) { reg_ah=EMM_ReallocatePages(reg_dx,reg_bx); break; case 0x53: // Set/Get Handlename - if (reg_al==0x00) { // Get Name not supported - LOG(LOG_ERROR|LOG_MISC,"EMS:Get handle name not supported",reg_ah); - reg_ah=EMM_FUNC_NOSUP; - } else { // Set name, not supported but faked - reg_ah=EMM_NO_ERROR; - } + reg_ah=GetSetHandleName(); break; case 0x54: /* Handle Functions */ reg_ah=HandleNameSearch(); From eada72c94ccf8978682f2c860ebf673ef8a8a9fc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 14 Mar 2003 10:30:53 +0000 Subject: [PATCH 0686/4131] Updated the linux build part a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@765 --- INSTALL | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/INSTALL b/INSTALL index 53dfc974..fae00576 100644 --- a/INSTALL +++ b/INSTALL @@ -1,6 +1,3 @@ -First of all if you are running a non-x86 machine this will not work, -code only works for big-endian machines for now :) - Things needed for compilation. SDL @@ -12,7 +9,7 @@ Curses For win32 get pdcurses at http://pdcurses.sourceforge.net Libpng - Needed for the screenshots. + Needed for the screenshots. (--enable-shots when configuring dosbox) For win32 get libpng from http://www.sourceforge.net/projects/gnuwin32 Zlib @@ -27,8 +24,12 @@ For building on unix systems. If you are building from the cvs run ./autogen.sh first before doing the following. 1. ./configure -2. Check settings.h for some setup options. -3. make +2. make + +In step 1 you could add the following switches --enable-shots this will +enable the screenshot facility, also --enable-debug is a valid switch. This +will enable the internal debugger. (It can be started by pressing - on the +numeric keyboard) Check the src subdir for the binary. From 4e2d7d8681fc98fb8c8cb97200570827dd1d6535 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 14 Mar 2003 11:17:58 +0000 Subject: [PATCH 0687/4131] added cdrom stuff Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@766 --- README | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README b/README index 49009c8d..2a07ff7b 100644 --- a/README +++ b/README @@ -38,9 +38,15 @@ Internal Programs: MOUNT Program to mount local directories as drives inside DOSBox. -The option -t specifies the media: dir = harddisk, floppy = floppy drive. +The option -t specifies the media: dir = harddisk, floppy = floppy drive, cdrom = cdrom drive. The option -size specifies the size. -For example to mount c:\floppy as a floppy : mount -t floppy a c:\floppy +The option -aspi forces to use aspi driver (only valid if mounting a cdrom and on Win2000/XP/NT systems). +For example to mount c:\floppy as a floppy : mount a c:\floppy -t floppy +For example to mount system cdrom drive e as cdrom drive d in dosbox : mount d e:\ -t cdrom +- In Win 95/98/ME you need latest ASPI driver to get cdrom audio support. +- In Win 2000/XP/NT you have the option to use an ASPI driver (add -aspi) at the end of the mount command. +It is even possible to mount a directory as cdrom, but you have some limited support for it then. + MEM Program to display the amount of free memory From 0022117efc14cdedda5629c4e99a8c2dced7104b Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 14 Mar 2003 11:35:07 +0000 Subject: [PATCH 0688/4131] added changes for 0.58 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@767 --- ChangeLog | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/ChangeLog b/ChangeLog index dc4db429..6f389ab0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +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 From 46df600f27cc3a99ab49489e612088a9b4d27a21 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 14 Mar 2003 11:35:44 +0000 Subject: [PATCH 0689/4131] added changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@768 --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 915d0916..6afcd458 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,8 @@ - joystick support fixes - mouse improvements - support for writing wavefiles + - added directory cache and longfilename support (longfilenames will be mangled) + - mouse fixes 0.57 From 2dd84fb446237c32b6a2324075a343ccca2f95e4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 14 Mar 2003 11:41:12 +0000 Subject: [PATCH 0690/4131] removed settings.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@769 --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 2a945916..48f9f473 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ # Main Makefile for DOSBox -EXTRA_DIST = settings.h autogen.sh +EXTRA_DIST = autogen.sh SUBDIRS = src include visualc From 86c91d55419bdd6c7c373d4810d750bf48731e73 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 14 Mar 2003 12:10:21 +0000 Subject: [PATCH 0691/4131] C_SSHOTS -> C_SSHOT Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@770 --- src/platform/visualc/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 74efab36..ac9a9863 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -6,7 +6,7 @@ #define C_DEBUG 1 /* Define to 1 to enable screenshots, requires libpng */ -#define C_SSHOTS 1 +#define C_SSHOT 1 /* Enable some heavy debugging options */ #define C_HEAVY_DEBUG 0 From 73e1a474f9af56a860c4ac4b24532099ae84dae3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 14 Mar 2003 12:37:05 +0000 Subject: [PATCH 0692/4131] changed C_SSHOTS to C_SSHOT Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@771 --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 37e4dfc2..6a099c2b 100644 --- a/configure.in +++ b/configure.in @@ -60,14 +60,14 @@ AC_ARG_ENABLE(debug,[ --enable-debug Enable debug mode],[ fi ],) -AH_TEMPLATE(C_SSHOTS,[Define to 1 to enable screenshots, requires libpng]) +AH_TEMPLATE(C_SSHOT,[Define to 1 to enable screenshots, requires libpng]) AC_ARG_ENABLE(shots,[ --enable-shots Enable screenshot support],[ AC_CHECK_HEADER(png.h,have_png_h=yes,) AC_CHECK_LIB(png, png_check_sig, have_png_lib=yes, , -lz) if test x$have_png_lib = xyes -a x$have_png_h = xyes ; then LIBS="$LIBS -lpng" - AC_DEFINE(C_SSHOTS,1) + AC_DEFINE(C_SSHOT,1) else AC_MSG_WARN([Can't enable screenshots without libpng]) fi From c0d66800cb9df0bf08194460cea53e6f385bdad0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 14 Mar 2003 12:37:46 +0000 Subject: [PATCH 0693/4131] added some h files Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@772 --- src/dos/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dos/Makefile.am b/src/dos/Makefile.am index ea8f9ad6..00ae5fa2 100644 --- a/src/dos/Makefile.am +++ b/src/dos/Makefile.am @@ -1,6 +1,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libdos.a +EXTRA_DIST = Ntddcdrm.h Ntddscsi.h Ntddstor.h scsidefs.h wnaspi32.h libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioctl.cpp dos_memory.cpp \ dos_misc.cpp dos_classes.cpp dos_programs.cpp dos_tables.cpp \ drives.cpp drives.h drive_virtual.cpp drive_local.cpp \ From 255cb814f02c2f7aa827ebeacdbebbf49a4a3087 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 16 Mar 2003 15:46:45 +0000 Subject: [PATCH 0694/4131] Updated gameblaster to use mame saa1099 emulation. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@773 --- src/hardware/gameblaster.cpp | 526 +++++++++++++++++++++++++---------- 1 file changed, 381 insertions(+), 145 deletions(-) diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index 5916d374..3deb6748 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -23,124 +23,389 @@ #include "mem.h" #include "hardware.h" #include "setup.h" +#include "pic.h" +#define LEFT 0x00 +#define RIGHT 0x01 +#define CMS_BUFFER_SIZE 128 #define CMS_RATE 22050 -#define CMS_VOLUME 6000 -#define FREQ_SHIFT 16 -#define SIN_ENT 1024 -#define SIN_MAX (SIN_ENT << FREQ_SHIFT) +typedef Bit8u UINT8; +typedef Bit16s INT16; -#ifndef PI -#define PI 3.14159265358979323846 -#endif +/* this structure defines a channel */ +struct saa1099_channel +{ + int frequency; /* frequency (0x00..0xff) */ + int freq_enable; /* frequency enable */ + int noise_enable; /* noise enable */ + int octave; /* octave (0x00..0x07) */ + int amplitude[2]; /* amplitude (0x00..0x0f) */ + int envelope[2]; /* envelope (0x00..0x0f or 0x10 == off) */ -struct CMS { - struct { - Bit32u freq_pos; - Bit32u freq_add; - Bit16s * vol_left; - Bit16s * vol_right; - Bit8u octave; - Bit8u freq; - } chan[6]; - struct { - Bit32u freq_pos; - Bit32u freq_add; - Bit32u random_val; - } noise[2]; - - Bit8u voice_enabled; - Bit8u noise_enabled; - Bit8u reg; + /* vars to simulate the square wave */ + double counter; + double freq; + int level; }; -static Bit32u freq_table[256][8]; -static Bit32u noise_freq[3]; -static Bit16s vol_table[16]; -static Bit16s sin_table[16][SIN_ENT]; +/* this structure defines a noise channel */ +struct saa1099_noise +{ + /* vars to simulate the noise generator output */ + double counter; + double freq; + int level; /* noise polynomal shifter */ +}; +/* this structure defines a SAA1099 chip */ +struct SAA1099 +{ + int stream; /* our stream */ + int noise_params[2]; /* noise generators parameters */ + int env_enable[2]; /* envelope generators enable */ + int env_reverse_right[2]; /* envelope reversed for right channel */ + int env_mode[2]; /* envelope generators mode */ + int env_bits[2]; /* non zero = 3 bits resolution */ + int env_clock[2]; /* envelope clock mode (non-zero external) */ + int env_step[2]; /* current envelope step */ + int all_ch_enable; /* all channels enable */ + int sync_state; /* sync all channels */ + int selected_reg; /* selected register */ + struct saa1099_channel channels[6]; /* channels */ + struct saa1099_noise noise[2]; /* noise generators */ +}; + +static UINT8 envelope[8][64] = { + /* zero amplitude */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* maximum amplitude */ + {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, }, + /* single decay */ + {15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* repetitive decay */ + {15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, + 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, + 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, + 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, + /* single triangular */ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* repetitive triangular */ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, + /* single attack */ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* repetitive attack */ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 } +}; + + +static int amplitude_lookup[16] = { + 0*32767/16, 1*32767/16, 2*32767/16, 3*32767/16, + 4*32767/16, 5*32767/16, 6*32767/16, 7*32767/16, + 8*32767/16, 9*32767/16, 10*32767/16, 11*32767/16, + 12*32767/16, 13*32767/16, 14*32767/16, 15*32767/16 +}; + +/* global parameters */ +static double sample_rate; +static SAA1099 saa1099[2]; static MIXER_Channel * cms_chan; -static CMS cms_block[2]; +static Bit16s cms_buffer[2][2][CMS_BUFFER_SIZE]; +static Bit16s * cms_buf_point[4] = { + cms_buffer[0][0],cms_buffer[0][1],cms_buffer[1][0],cms_buffer[1][1] }; -static void write_cms(Bit32u port,Bit8u val) { - Bit32u sel=(port>>1)&1; - CMS * cms=&cms_block[sel]; - switch (port & 1) { - case 1: /* Register Select */ - cms->reg=val; - break; - case 0: /* Write Register */ - switch (cms->reg) { - case 0x00: case 0x01: case 0x02: /* Volume Select */ - case 0x03: case 0x04: case 0x05: - cms->chan[cms->reg].vol_left=sin_table[val & 0xf]; - cms->chan[cms->reg].vol_right=sin_table[(val>>4) & 0xf]; - break; - case 0x08: case 0x09: case 0x0a: /* Frequency Select */ - case 0x0b: case 0x0c: case 0x0d: - { - Bit8u chan=cms->reg-0x08; - cms->chan[chan].freq=val; - /* Get a new entry in the freq table */ - cms->chan[chan].freq_add=freq_table[cms->chan[chan].freq][cms->chan[chan].octave]; - break; - } - case 0x10: case 0x11: case 0x12: /* Octave Select */ - { - Bit8u chan=(cms->reg-0x10)*2; - cms->chan[chan].octave=val&7; - cms->chan[chan].freq_add=freq_table[cms->chan[chan].freq][cms->chan[chan].octave]; - chan++; - cms->chan[chan].octave=(val>>4)&7; - cms->chan[chan].freq_add=freq_table[cms->chan[chan].freq][cms->chan[chan].octave]; - } - break; - case 0x14: /* Frequency enable */ - cms->voice_enabled=val; - //TODO Check for enabling of speaker maybe - break; - case 0x15: /* Noise Enable */ - cms->noise_enabled=val; - //TODO Check for enabling of speaker maybe - break; - case 0x16: /* Noise generator setup */ - cms->noise[0].freq_add=noise_freq[val & 3]; - cms->noise[1].freq_add=noise_freq[(val>>4) & 3]; - break; - default: - LOG(LOG_ERROR,"CMS %d:Illegal register %X2 Selected for write",sel,cms->reg); - break; - }; - break; +static Bitu last_command; + + +static void saa1099_envelope(int chip, int ch) +{ + struct SAA1099 *saa = &saa1099[chip]; + if (saa->env_enable[ch]) + { + int step, mode, mask; + mode = saa->env_mode[ch]; + /* step from 0..63 and then loop in steps 32..63 */ + step = saa->env_step[ch] = + ((saa->env_step[ch] + 1) & 0x3f) | (saa->env_step[ch] & 0x20); + + mask = 15; + if (saa->env_bits[ch]) + mask &= ~1; /* 3 bit resolution, mask LSB */ + + saa->channels[ch*3+0].envelope[ LEFT] = + saa->channels[ch*3+1].envelope[ LEFT] = + saa->channels[ch*3+2].envelope[ LEFT] = envelope[mode][step] & mask; + if (saa->env_reverse_right[ch] & 0x01) + { + saa->channels[ch*3+0].envelope[RIGHT] = + saa->channels[ch*3+1].envelope[RIGHT] = + saa->channels[ch*3+2].envelope[RIGHT] = (15 - envelope[mode][step]) & mask; + } + else + { + saa->channels[ch*3+0].envelope[RIGHT] = + saa->channels[ch*3+1].envelope[RIGHT] = + saa->channels[ch*3+2].envelope[RIGHT] = envelope[mode][step] & mask; + } + } + else + { + /* envelope mode off, set all envelope factors to 16 */ + saa->channels[ch*3+0].envelope[ LEFT] = + saa->channels[ch*3+1].envelope[ LEFT] = + saa->channels[ch*3+2].envelope[ LEFT] = + saa->channels[ch*3+0].envelope[RIGHT] = + saa->channels[ch*3+1].envelope[RIGHT] = + saa->channels[ch*3+2].envelope[RIGHT] = 16; + } +} + + +static void saa1099_update(int chip, INT16 **buffer, int length) +{ + struct SAA1099 *saa = &saa1099[chip]; + int j, ch; + + /* if the channels are disabled we're done */ + if (!saa->all_ch_enable) + { + /* init output data */ + memset(buffer[LEFT],0,length*sizeof(INT16)); + memset(buffer[RIGHT],0,length*sizeof(INT16)); + return; } -}; + for (ch = 0; ch < 2; ch++) + { + switch (saa->noise_params[ch]) + { + case 0: saa->noise[ch].freq = 31250.0 * 2; break; + case 1: saa->noise[ch].freq = 15625.0 * 2; break; + case 2: saa->noise[ch].freq = 7812.5 * 2; break; + case 3: saa->noise[ch].freq = saa->channels[ch * 3].freq; break; + } + } -static void CMS_CallBack(Bit8u * stream,Bit32u len) { - /* Generate the CMS wave */ - /* Generate 12 channels of sound data this could be nice */ - for (Bit32u l=0;lnoise_enabled & use_voice) { + /* fill all data needed */ + for( j = 0; j < length; j++ ) + { + int output_l = 0, output_r = 0; - } else if (cms->voice_enabled & use_voice) { - int pos=cms->chan[chan].freq_pos>>FREQ_SHIFT; - left+=cms->chan[chan].vol_left[pos]; - right+=cms->chan[chan].vol_right[pos]; - cms->chan[chan].freq_pos+=cms->chan[chan].freq_add; - if (cms->chan[chan].freq_pos>=SIN_MAX) - cms->chan[chan].freq_pos-=SIN_MAX; + /* for each channel */ + for (ch = 0; ch < 6; ch++) + { + if (saa->channels[ch].freq == 0.0) + saa->channels[ch].freq = (double)((2 * 15625) << saa->channels[ch].octave) / + (511.0 - (double)saa->channels[ch].frequency); + + /* check the actual position in the square wave */ + saa->channels[ch].counter -= saa->channels[ch].freq; + while (saa->channels[ch].counter < 0) + { + /* calculate new frequency now after the half wave is updated */ + saa->channels[ch].freq = (double)((2 * 15625) << saa->channels[ch].octave) / + (511.0 - (double)saa->channels[ch].frequency); + + saa->channels[ch].counter += sample_rate; + saa->channels[ch].level ^= 1; + + /* eventually clock the envelope counters */ + if (ch == 1 && saa->env_clock[0] == 0) + saa1099_envelope(chip, 0); + if (ch == 4 && saa->env_clock[1] == 0) + saa1099_envelope(chip, 1); + } + + /* if the noise is enabled */ + if (saa->channels[ch].noise_enable) + { + /* if the noise level is high (noise 0: chan 0-2, noise 1: chan 3-5) */ + if (saa->noise[ch/3].level & 1) + { + /* subtract to avoid overflows, also use only half amplitude */ + output_l -= saa->channels[ch].amplitude[ LEFT] * saa->channels[ch].envelope[ LEFT] / 16 / 2; + output_r -= saa->channels[ch].amplitude[RIGHT] * saa->channels[ch].envelope[RIGHT] / 16 / 2; + } + } + + /* if the square wave is enabled */ + if (saa->channels[ch].freq_enable) + { + /* if the channel level is high */ + if (saa->channels[ch].level & 1) + { + output_l += saa->channels[ch].amplitude[ LEFT] * saa->channels[ch].envelope[ LEFT] / 16; + output_r += saa->channels[ch].amplitude[RIGHT] * saa->channels[ch].envelope[RIGHT] / 16; } - use_voice<<=1; } } + + for (ch = 0; ch < 2; ch++) + { + /* check the actual position in noise generator */ + saa->noise[ch].counter -= saa->noise[ch].freq; + while (saa->noise[ch].counter < 0) + { + saa->noise[ch].counter += sample_rate; + if( ((saa->noise[ch].level & 0x4000) == 0) == ((saa->noise[ch].level & 0x0040) == 0) ) + saa->noise[ch].level = (saa->noise[ch].level << 1) | 1; + else + saa->noise[ch].level <<= 1; + } + } + /* write sound data to the buffer */ + buffer[LEFT][j] = output_l / 6; + buffer[RIGHT][j] = output_r / 6; + } +} + +static void saa1099_write_port_w( int chip, int offset, int data ) +{ + struct SAA1099 *saa = &saa1099[chip]; + int reg = saa->selected_reg; + int ch; + + switch (reg) + { + /* channel i amplitude */ + case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: + ch = reg & 7; + saa->channels[ch].amplitude[LEFT] = amplitude_lookup[data & 0x0f]; + saa->channels[ch].amplitude[RIGHT] = amplitude_lookup[(data >> 4) & 0x0f]; + break; + /* channel i frequency */ + case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: + ch = reg & 7; + saa->channels[ch].frequency = data & 0xff; + break; + /* channel i octave */ + case 0x10: case 0x11: case 0x12: + ch = (reg - 0x10) << 1; + saa->channels[ch + 0].octave = data & 0x07; + saa->channels[ch + 1].octave = (data >> 4) & 0x07; + break; + /* channel i frequency enable */ + case 0x14: + saa->channels[0].freq_enable = data & 0x01; + saa->channels[1].freq_enable = data & 0x02; + saa->channels[2].freq_enable = data & 0x04; + saa->channels[3].freq_enable = data & 0x08; + saa->channels[4].freq_enable = data & 0x10; + saa->channels[5].freq_enable = data & 0x20; + break; + /* channel i noise enable */ + case 0x15: + saa->channels[0].noise_enable = data & 0x01; + saa->channels[1].noise_enable = data & 0x02; + saa->channels[2].noise_enable = data & 0x04; + saa->channels[3].noise_enable = data & 0x08; + saa->channels[4].noise_enable = data & 0x10; + saa->channels[5].noise_enable = data & 0x20; + break; + /* noise generators parameters */ + case 0x16: + saa->noise_params[0] = data & 0x03; + saa->noise_params[1] = (data >> 4) & 0x03; + break; + /* envelope generators parameters */ + case 0x18: case 0x19: + ch = reg - 0x18; + saa->env_reverse_right[ch] = data & 0x01; + saa->env_mode[ch] = (data >> 1) & 0x07; + saa->env_bits[ch] = data & 0x10; + saa->env_clock[ch] = data & 0x20; + saa->env_enable[ch] = data & 0x80; + /* reset the envelope */ + saa->env_step[ch] = 0; + break; + /* channels enable & reset generators */ + case 0x1c: + saa->all_ch_enable = data & 0x01; + saa->sync_state = data & 0x02; + if (data & 0x02) + { + int i; +// logerror("%04x: (SAA1099 #%d) -reg 0x1c- Chip reset\n",activecpu_get_pc(), chip); + /* Synch & Reset generators */ + for (i = 0; i < 6; i++) + { + saa->channels[i].level = 0; + saa->channels[i].counter = 0.0; + } + } + break; + default: /* Error! */ +// logerror("%04x: (SAA1099 #%d) Unknown operation (reg:%02x, data:%02x)\n",activecpu_get_pc(), chip, reg, data); + LOG(0|LOG_ERROR,"CMS Unkown write to reg %x with %x",reg, data); + } +} + + +static void write_cms(Bit32u port,Bit8u val) { + if (last_command + 100 < PIC_Ticks) MIXER_Enable(cms_chan,true); + last_command = PIC_Ticks; + switch (port) { + case 0x0220: + saa1099_write_port_w(0,1,val); + break; + case 0x221: + saa1099[0].selected_reg = val & 0x1f; + if (saa1099[0].selected_reg == 0x18 || saa1099[0].selected_reg == 0x19) { + /* clock the envelope channels */ + if (saa1099[0].env_clock[0]) saa1099_envelope(0,0); + if (saa1099[0].env_clock[1]) saa1099_envelope(0,1); + } + break; + case 0x0222: + saa1099_write_port_w(1,1,val); + break; + case 0x223: + saa1099[1].selected_reg = val & 0x1f; + + if (saa1099[1].selected_reg == 0x18 || saa1099[1].selected_reg == 0x19) { + /* clock the envelope channels */ + if (saa1099[1].env_clock[0]) saa1099_envelope(1,0); + if (saa1099[1].env_clock[1]) saa1099_envelope(1,1); + } + break; + } + if (last_command > PIC_Ticks+1000) MIXER_Enable(cms_chan,true); +} + + static void CMS_CallBack(Bit8u * stream,Bit32u len) { + if (len > CMS_BUFFER_SIZE) return; + + saa1099_update(0, &cms_buf_point[0], (int)len); + saa1099_update(1, &cms_buf_point[2], (int)len); + + /* Mix chip outputs */ + for (Bitu l=0;lMAX_AUDIO) *(Bit16s *)stream=MAX_AUDIO; else if (left(sec); if(!section->Get_bool("cms")) return; - Bits i; + sample_rate=section->Get_int("cmsrate"); + + IO_RegisterWriteHandler(0x220,write_cms,"CMS"); + IO_RegisterWriteHandler(0x221,write_cms,"CMS"); + IO_RegisterWriteHandler(0x222,write_cms,"CMS"); + IO_RegisterWriteHandler(0x223,write_cms,"CMS"); + /* Register the Mixer CallBack */ + cms_chan=MIXER_AddChannel(CMS_CallBack,CMS_RATE,"CMS"); MIXER_SetMode(cms_chan,MIXER_16STEREO); - MIXER_Enable(cms_chan,false); -/* Make the frequency/octave table */ - double log_start=log10(27.34375); - double log_add=(log10(54.609375)-log10(27.34375))/256; - for (i=0;i<256;i++) { - double freq=pow(10,log_start); - for (int k=0;k<8;k++) { - freq_table[i][k]=(Bit32u)((double)SIN_MAX/(CMS_RATE/freq)); - freq*=2; - } - log_start+=log_add; + MIXER_Enable(cms_chan,true); + last_command=PIC_Ticks; + + for (int s=0;s<2;s++) { + struct SAA1099 *saa = &saa1099[s]; + + memset(saa, 0, sizeof(struct SAA1099)); } -// noise_freq[0]=(Bit32u)(FREQ_MAX/((float)CMS_RATE/(float)28000)); -// noise_freq[1]=(Bit32u)(FREQ_MAX/((float)CMS_RATE/(float)14000)); -// noise_freq[2]=(Bit32u)(FREQ_MAX/((float)CMS_RATE/(float)6800)); - for (int s=0;s=0;i--) { - sin_table[i][s]=(Bit16s)out; -// out /= (float)1.258925412; /* = 10 ^ (2/20) = 2dB */ - out /= 1.1; - } - } - CMS_Enable(true); } From 8ac92dff2c85b7a54631af90c78b60a06fb0bff2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 16 Mar 2003 15:48:05 +0000 Subject: [PATCH 0695/4131] CMS/Gameblaster sound rate option Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@774 --- src/dosbox.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index f492c407..718d1070 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -209,7 +209,8 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&ADLIB_Init); secprop->Add_bool("adlib",true); secprop->AddInitFunction(&CMS_Init); - secprop->Add_bool("cms",false); + secprop->Add_bool("cms",false); + secprop->Add_int("cmsrate",22050); secprop->AddInitFunction(&MPU401_Init); secprop->Add_bool("mpu401",true); From 27e4690c4281f714be46f9893c2727fc10fd60b9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 17 Mar 2003 09:49:31 +0000 Subject: [PATCH 0696/4131] prepare for release Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@775 --- src/platform/visualc/config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index ac9a9863..811ebc70 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -1,9 +1,9 @@ #define INLINE __forceinline -#define VERSION "0.57" +#define VERSION "0.58" /* Define to 1 to enable internal debugger, requires libcurses */ -#define C_DEBUG 1 +#define C_DEBUG 0 /* Define to 1 to enable screenshots, requires libpng */ #define C_SSHOT 1 From 367b446067f6ab9554ef6e995e4c3ce939a134a9 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 18 Mar 2003 20:02:27 +0000 Subject: [PATCH 0697/4131] Changed the scsi detection routine GetHostAdapter Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@776 --- src/dos/cdrom.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index fffcd18f..08027ecf 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -59,6 +59,50 @@ bool GetRegistryValue(HKEY& hKey,char* valueName, char* buffer, ULONG bufferSize return (result == ERROR_SUCCESS); }; +BYTE CDROM_Interface_Aspi::GetHostAdapter(void) +{ + SRB_HAInquiry sh; + SRB_GDEVBlock sd; + DWORD d = pGetASPI32SupportInfo(); + int cnt = LOBYTE(LOWORD(d)); + int i,j,k,max; + + for(i=0; i Date: Tue, 18 Mar 2003 20:39:08 +0000 Subject: [PATCH 0698/4131] fixed opendir problem in win98 (trailing backslash check) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@777 --- src/platform/visualc/dirent.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/platform/visualc/dirent.c b/src/platform/visualc/dirent.c index 6c1c4b78..cc536bf3 100644 --- a/src/platform/visualc/dirent.c +++ b/src/platform/visualc/dirent.c @@ -20,10 +20,14 @@ DIR * opendir(const char *dirname) { static DIR dir; + int len; /* Stash the directory name */ strcpy(dir.pathName,dirname); - strcat(dir.pathName,"\\*.*"); + + len = strlen(dirname); + if ((len>0) && (dirname[len-1]=='\\')) strcat(dir.pathName,"*.*"); + else strcat(dir.pathName,"\\*.*"); /* set the handle to invalid and set the firstTime flag */ dir.handle = INVALID_HANDLE_VALUE; From 860af6c52f5931c390f8615a6cd1efa484371e56 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 19 Mar 2003 22:37:19 +0000 Subject: [PATCH 0699/4131] Add new render screen flag for screen shadowing for unaligned renders. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@778 --- include/video.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/video.h b/include/video.h index 63d952ec..a7304ffa 100644 --- a/include/video.h +++ b/include/video.h @@ -33,6 +33,8 @@ struct GFX_PalEntry { #define GFX_FIXED_BPP 0x01 #define GFX_RESIZEABLE 0x02 +#define GFX_SHADOW 0x04 + #define MODE_SET 0x01 #define MODE_FULLSCREEN 0x02 From e60ffa00e40ee601bb78d79b1a5dc07db2596630 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 19 Mar 2003 22:41:30 +0000 Subject: [PATCH 0700/4131] Set certain render types to use shadow surfaces Add some more support for screenshot messages and fix a bug with pngl structures getting allocated before testing if screenshot file can be made. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@779 --- src/gui/render.cpp | 49 ++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 89e02f32..61003fef 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -96,7 +96,6 @@ static void RENDER_ResetPal(void); #if (C_SSHOT) #include - /* Take a screenshot of the data that should be rendered */ static void TakeScreenShot(Bit8u * bitmap) { Bitu last=0;char file_name[CROSS_LEN]; @@ -107,18 +106,10 @@ static void TakeScreenShot(Bit8u * bitmap) { png_color palette[256]; Bitu i; -/* First try to alloacte the png structures */ - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL, NULL); - if (!png_ptr) return; - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_write_struct(&png_ptr,(png_infopp)NULL); - return; - } /* Find a filename to open */ dir=opendir(render.shot.dir); if (!dir) { - LOG_MSG("Can't open snapshot dir %s",render.shot.dir); + LOG_MSG("Can't open snapshot directory %s",render.shot.dir); return; } while (dir_ent=readdir(dir)) { @@ -133,14 +124,24 @@ static void TakeScreenShot(Bit8u * bitmap) { if (num>=last) last=num+1; } closedir(dir); - sprintf(file_name,"%s%csnap%05d.png",render.shot.dir,CROSS_FILESPLIT,last); -/* Open the actual file */ + sprintf(file_name,"%s%csnap%04d.png",render.shot.dir,CROSS_FILESPLIT,last); + /* Open the actual file */ FILE * fp=fopen(file_name,"wb"); if (!fp) { - LOG_MSG("Can't open snapshot file %s",file_name); + LOG_MSG("Can't open file %s for snapshot",file_name); return; } -/* Finalize the initing of png library */ + + /* First try to alloacte the png structures */ + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL, NULL); + if (!png_ptr) return; + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_write_struct(&png_ptr,(png_infopp)NULL); + return; + } + + /* Finalize the initing of png library */ png_init_io(png_ptr, fp); png_set_compression_level(png_ptr,Z_BEST_COMPRESSION); @@ -185,6 +186,7 @@ static void TakeScreenShot(Bit8u * bitmap) { /*clean up dynamically allocated RAM.*/ free(row_pointers); + LOG_MSG("Took snapshot in file %s",file_name); } static void EnableScreenShot(void) { @@ -305,18 +307,27 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu case OP_None: normalop: switch (render.src.flags) { - case DoubleNone:break; - case DoubleWidth:width*=2;break; - case DoubleHeight:height*=2;break; + case DoubleNone: + flags=0; + break; + case DoubleWidth: + width*=2; + flags=GFX_SHADOW; + break; + case DoubleHeight: + height*=2; + flags=0; + break; case DoubleBoth: if (render.keep_small) { render.src.flags=0; + flags=0; } else { width*=2;height*=2; + flags=GFX_SHADOW; } break; } - flags=0; mode_callback=Render_Normal_CallBack; break; case OP_Scale2x: @@ -326,7 +337,7 @@ normalop: mode_callback=Render_Scale2x_CallBack; width*=2;height*=2; #if defined (SCALE2X_NORMAL) - flags=0; + flags=GFX_SHADOW; #elif defined (SCALE2X_MMX) flags=GFX_FIXED_BPP; #endif From a209676ec6ae9184877f61717f7024b738336aea Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 19 Mar 2003 22:42:29 +0000 Subject: [PATCH 0701/4131] Support for shadow surface flag when setting screen size.. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@780 --- src/gui/sdlmain.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 7f32f2d2..a2e736ec 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -45,6 +45,7 @@ struct SDL_Block { bool full_screen; bool nowait; SDL_Surface * surface; + SDL_Surface * shadow_surface; SDL_Joystick * joy; SDL_cond *cond; #if C_GFXTHREADED @@ -70,7 +71,12 @@ static void CaptureMouse(void); static void ResetScreen(void) { GFX_Stop(); if (sdl.full_screen) { - sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN); + if (sdl.flags & GFX_SHADOW) { + /* TODO Maybe allocate a shadow surface and blit yourself and do real double buffering too */ + sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_SWSURFACE|SDL_FULLSCREEN); + } else { + sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN|SDL_DOUBLEBUF); + } } else { if (sdl.flags & GFX_FIXED_BPP) sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE); else sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,0,SDL_HWSURFACE); @@ -119,7 +125,6 @@ static void SwitchFullScreen(void) { } else { if (sdl.mouse.locked) CaptureMouse(); } - ResetScreen(); } @@ -129,7 +134,6 @@ void GFX_SwitchFullScreen(void) { static void SDL_DrawScreen(void) { sdl.drawing=true; - if (SDL_MUSTLOCK(sdl.surface)) { if (SDL_LockSurface(sdl.surface)) { sdl.drawing=false; @@ -137,21 +141,19 @@ static void SDL_DrawScreen(void) { } } sdl.draw_callback(sdl.surface->pixels); - if (SDL_MUSTLOCK(sdl.surface)) { SDL_UnlockSurface(sdl.surface); } - SDL_UpdateRect(sdl.surface,0,0,0,0); -// SDL_Flip(sdl.surface); + SDL_Flip(sdl.surface); sdl.drawing=false; } - #if C_GFXTHREADED int SDL_DisplayThread(void * data) { while (!SDL_SemWait(sdl.sem)) { if (sdl.kill_thread) return 0; if (!sdl.active) continue; + if (sdl.drawing) continue; SDL_mutexP(sdl.mutex); SDL_DrawScreen(); SDL_mutexV(sdl.mutex); @@ -519,8 +521,6 @@ void GFX_ShowMsg(char * msg) { int main(int argc, char* argv[]) { - - try { CommandLine com_line(argc,argv); Config myconf(&com_line); From a7104cb358d5a8fd84899ba91ce88f4179b7ffb3 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 20 Mar 2003 17:56:54 +0000 Subject: [PATCH 0702/4131] fixed wrong audio cd selection (multiple cdroms) set the GetMediaTrayStatus parameters to more common values. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@781 --- src/dos/cdrom.cpp | 131 +++++++++++++++++++++++++--------------------- src/dos/cdrom.h | 3 +- 2 files changed, 73 insertions(+), 61 deletions(-) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 08027ecf..dfc0d6dd 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -59,7 +59,7 @@ bool GetRegistryValue(HKEY& hKey,char* valueName, char* buffer, ULONG bufferSize return (result == ERROR_SUCCESS); }; -BYTE CDROM_Interface_Aspi::GetHostAdapter(void) +BYTE CDROM_Interface_Aspi::GetHostAdapter(char* hardwareID) { SRB_HAInquiry sh; SRB_GDEVBlock sd; @@ -87,12 +87,17 @@ BYTE CDROM_Interface_Aspi::GetHostAdapter(void) if (sd.SRB_Status == SS_COMP) { if (sd.SRB_DeviceType == DTYPE_CDROM) { if ((target==j) && (lun==k)) { - LOG(LOG_MISC|LOG_ERROR,"SCSI: Host Adapter found: %d",i); - return i; + LOG(LOG_MISC|LOG_ERROR,"SCSI: Getting Hardware vendor."); + // "Hardware ID = vendor" match ? + char vendor[64]; + if (GetVendor(i,target,lun,vendor)) { + LOG(LOG_MISC|LOG_ERROR,"SCSI: Vendor : %s",vendor); + if (strstr(hardwareID,vendor)) { + LOG(LOG_MISC|LOG_ERROR,"SCSI: Host Adapter found: %d",i); + return i; + } + }; } -// hid = i; -// tid = j; -// lun = k; } } } @@ -102,41 +107,6 @@ BYTE CDROM_Interface_Aspi::GetHostAdapter(void) return 0; }; -/* -BYTE CDROM_Interface_Aspi::GetHostAdapter(void) -{ - SRB_ExecSCSICmd s;DWORD dwStatus; - BYTE buffer[40]; - - for (int i=0; i<255; i++) { - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - memset(&s,0,sizeof(s)); - // Check Media test... - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = i; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_SenseLen = SENSE_LEN; - s.SRB_BufLen = 40; - s.SRB_BufPointer = (BYTE FAR*)buffer; - s.SRB_CDBLen = 14; - s.SRB_PostProc = (LPVOID)hEvent; - s.CDBByte[0] = 0x4A; - s.CDBByte[1] = (lun<<5)|1; // lun & immediate - s.CDBByte[4] = 0x10; // media - s.CDBByte[8] = 40; - ResetEvent(hEvent); - dwStatus = pSendASPI32Command((LPSRB)&s); - if ((dwStatus==0) && (s.SRB_Status!=SS_INVALID_CMD)) { - LOG(LOG_MISC,"SCSI: Host Adapter found: %d",i); - return i; - }; - }; - LOG(LOG_MISC|LOG_ERROR,"SCSI: Host Adapter not found."); - return 0; -}; -*/ bool CDROM_Interface_Aspi::ScanRegistryFindKey(HKEY& hKeyBase) // hKey has to be open { @@ -156,19 +126,21 @@ bool CDROM_Interface_Aspi::ScanRegistryFindKey(HKEY& hKeyBase) newKeyResult = RegOpenKeyEx (hKeyBase,subKey,0,KEY_READ,&hNewKey); if (newKeyResult==ERROR_SUCCESS) { if (GetRegistryValue(hNewKey,"CurrentDriveLetterAssignment",buffer,256)) { - LOG(LOG_MISC,"SCSI: Drive Letter found: %s",buffer); + LOG(LOG_MISC|LOG_ERROR,"SCSI: Drive Letter found: %s",buffer); // aha, something suspicious... if (buffer[0]==letter) { + char hardwareID[256]; // found it... lets see if we can get the scsi values bool v1 = GetRegistryValue(hNewKey,"SCSILUN",buffer,256); - LOG(LOG_MISC,"SCSI: SCSILUN found: %s",buffer); + LOG(LOG_MISC|LOG_ERROR,"SCSI: SCSILUN found: %s",buffer); lun = buffer[0]-'0'; bool v2 = GetRegistryValue(hNewKey,"SCSITargetID",buffer,256); - LOG(LOG_MISC,"SCSI: SCSITargetID found: %s",buffer); + LOG(LOG_MISC|LOG_ERROR,"SCSI: SCSITargetID found: %s",buffer); target = buffer[0]-'0'; + bool v3 = GetRegistryValue(hNewKey,"HardwareID",hardwareID,256); RegCloseKey(hNewKey); - if (v1 && v2) { - haId = GetHostAdapter(); + if (v1 && v2 && v3) { + haId = GetHostAdapter(hardwareID); return true; }; } @@ -181,6 +153,45 @@ bool CDROM_Interface_Aspi::ScanRegistryFindKey(HKEY& hKeyBase) return false; }; +bool CDROM_Interface_Aspi::GetVendor(BYTE HA_num, BYTE SCSI_Id, BYTE SCSI_Lun, char* szBuffer) +{ + SRB_ExecSCSICmd srbExec; + memset ( &srbExec, 0, sizeof ( SRB_ExecSCSICmd ) ); + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + srbExec.SRB_Cmd = SC_EXEC_SCSI_CMD ; + srbExec.SRB_HaId = HA_num; + srbExec.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + srbExec.SRB_Target = SCSI_Id; + srbExec.SRB_Lun = SCSI_Lun; + srbExec.SRB_BufLen = 36; + srbExec.SRB_BufPointer = (unsigned char*)szBuffer; + srbExec.SRB_SenseLen = SENSE_LEN; + srbExec.SRB_CDBLen = 6; + srbExec.SRB_PostProc = (LPVOID)hEvent; + srbExec.CDBByte [ 0 ] = SCSI_INQUIRY; + srbExec.CDBByte [ 4 ] = 36; // allocation length per szBuffer [ ] + + ResetEvent(hEvent); + int dwStatus = pSendASPI32Command ((LPSRB)&srbExec); + LOG(LOG_MISC|LOG_ERROR,"SCSI: Get vendor command send"); + + if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,30000); + LOG(LOG_MISC|LOG_ERROR,"SCSI: Pending done."); + + if (srbExec.SRB_Status != SS_COMP) { + strcpy (szBuffer, "error" ); + return false; + } else { + strncpy(szBuffer,szBuffer+8,25); + szBuffer[25] = 0; + int len = strlen(szBuffer); + for (int i=0; i> 24) & 0xFF); s.CDBByte[3] = (unsigned char)((start >> 16) & 0xFF); @@ -488,7 +499,7 @@ bool CDROM_Interface_Aspi::GetAudioSub(unsigned char& attr, unsigned char& track s.SRB_CDBLen = 10; s.SRB_PostProc = (LPVOID)hEvent; - s.CDBByte[0] = 0x42; + s.CDBByte[0] = SCSI_SUBCHANNEL; s.CDBByte[1] = (lun<<5)|2; // lun & msf s.CDBByte[2] = 0x40; // subq s.CDBByte[3] = 0x01; // curr pos info @@ -538,7 +549,7 @@ bool CDROM_Interface_Aspi::GetUPC(unsigned char& attr, char* upcdata) s.SRB_CDBLen = 10; s.SRB_PostProc = (LPVOID)hEvent; - s.CDBByte[0] = 0x42; + s.CDBByte[0] = SCSI_SUBCHANNEL; s.CDBByte[1] = (lun<<5)|2; // lun & msf s.CDBByte[2] = 0x40; // subq s.CDBByte[3] = 0x02; // get upc @@ -588,7 +599,7 @@ bool CDROM_Interface_Aspi::GetAudioStatus(bool& playing, bool& pause) s.SRB_CDBLen = 10; s.SRB_PostProc = (LPVOID)hEvent; - s.CDBByte[0] = 0x42; + s.CDBByte[0] = SCSI_SUBCHANNEL; s.CDBByte[1] = (lun<<5)|2; // lun & msf s.CDBByte[2] = 0x00; // no subq s.CDBByte[3] = 0x00; // dont care @@ -630,7 +641,7 @@ bool CDROM_Interface_Aspi::LoadUnloadMedia(bool unload) s.SRB_CDBLen = 14; s.SRB_PostProc = (LPVOID)hEvent; - s.CDBByte[0] = 0x1B; + s.CDBByte[0] = SCSI_LOAD_UN; s.CDBByte[1] = (lun<<5)|1; // lun & immediate s.CDBByte[4] = (unload ? 0x02:0x03); // unload/load media @@ -650,11 +661,12 @@ bool CDROM_Interface_Aspi::GetMediaTrayStatus(bool& mediaPresent, bool& mediaCha mediaPresent = mediaChanged = trayOpen = false; SRB_ExecSCSICmd s;DWORD dwStatus; - BYTE buffer[40]; + BYTE buffer[12]; hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); memset(&s,0,sizeof(s)); + memset(&buffer,0,sizeof(buffer)); s.SRB_Cmd = SC_EXEC_SCSI_CMD; s.SRB_HaId = haId; @@ -663,21 +675,20 @@ bool CDROM_Interface_Aspi::GetMediaTrayStatus(bool& mediaPresent, bool& mediaCha s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; s.SRB_SenseLen = SENSE_LEN; - s.SRB_BufLen = 40; + s.SRB_BufLen = 12; s.SRB_BufPointer = (BYTE FAR*)buffer; - s.SRB_CDBLen = 14; + s.SRB_CDBLen = 12; s.SRB_PostProc = (LPVOID)hEvent; s.CDBByte[0] = 0x4A; - s.CDBByte[1] = (lun<<5)|1; // lun & immediate - s.CDBByte[4] = 0x10; // media - s.CDBByte[8] = 40; + s.CDBByte[1] = 1; // lun & immediate + s.CDBByte[4] = 0x10; // media + *(Bit16u*)&s.CDBByte[7] = 12; ResetEvent(hEvent); - dwStatus = pSendASPI32Command((LPSRB)&s); - if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); + if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent, 0x5000); if (s.SRB_Status!=SS_COMP) return false; diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index 463945ac..448c53d2 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -97,7 +97,8 @@ private: void GetIOCTLAdapter (HANDLE hF,int * iDA,int * iDT,int * iDL); bool ScanRegistryFindKey (HKEY& hKeyBase); bool ScanRegistry (HKEY& hKeyBase); - BYTE GetHostAdapter (void); + BYTE GetHostAdapter (char* hardwareID); + bool GetVendor (BYTE HA_num, BYTE SCSI_Id, BYTE SCSI_Lun, char* szBuffer); // ASPI stuff BYTE haId; From 02934f96766b39ae2b839ab204743b785b334754 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 21 Mar 2003 14:25:32 +0000 Subject: [PATCH 0703/4131] Removed scsi-3 commands Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@782 --- src/dos/cdrom.cpp | 77 +++++++++-------------------------------------- src/dos/cdrom.h | 1 + 2 files changed, 15 insertions(+), 63 deletions(-) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index dfc0d6dd..6bb181f7 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -33,6 +33,7 @@ CDROM_Interface_Aspi::CDROM_Interface_Aspi(void) hEvent = NULL; pGetASPI32SupportInfo = NULL; pSendASPI32Command = NULL; + memset(&oldLeadOut,0,sizeof(oldLeadOut)); }; CDROM_Interface_Aspi::~CDROM_Interface_Aspi(void) @@ -421,31 +422,7 @@ bool CDROM_Interface_Aspi::PlayAudioSector(unsigned long start,unsigned long len bool CDROM_Interface_Aspi::StopAudio(void) { - SRB_ExecSCSICmd s;DWORD dwStatus; - - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - memset(&s,0,sizeof(s)); - - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = 0x00; - s.SRB_SenseLen = 0x0E; - s.SRB_CDBLen = 0x0A; - s.SRB_PostProc = (LPVOID)hEvent; - s.CDBByte[0] = 0x4E; - - ResetEvent(hEvent); - dwStatus=pSendASPI32Command((LPSRB)&s); - - if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,30000); - - if (s.SRB_Status!=SS_COMP) return false; - - return true; + return PauseAudio(false); }; bool CDROM_Interface_Aspi::PauseAudio(bool resume) @@ -658,44 +635,18 @@ bool CDROM_Interface_Aspi::LoadUnloadMedia(bool unload) bool CDROM_Interface_Aspi::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) { - mediaPresent = mediaChanged = trayOpen = false; - - SRB_ExecSCSICmd s;DWORD dwStatus; - BYTE buffer[12]; - - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - memset(&s,0,sizeof(s)); - memset(&buffer,0,sizeof(buffer)); - - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_SenseLen = SENSE_LEN; - - s.SRB_BufLen = 12; - s.SRB_BufPointer = (BYTE FAR*)buffer; - s.SRB_CDBLen = 12; - s.SRB_PostProc = (LPVOID)hEvent; - - s.CDBByte[0] = 0x4A; - s.CDBByte[1] = 1; // lun & immediate - s.CDBByte[4] = 0x10; // media - *(Bit16u*)&s.CDBByte[7] = 12; - - ResetEvent(hEvent); - dwStatus = pSendASPI32Command((LPSRB)&s); - - if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent, 0x5000); - - if (s.SRB_Status!=SS_COMP) return false; - - mediaChanged = (buffer[0x04]== 0x04); - mediaPresent = (buffer[0x05] & 0x02)>0; - trayOpen = (buffer[0x05] & 0x01)>0; - + // Seems not possible to get this values using ioctl... + int track1,track2; + TMSF leadOut; + // If we can read, there's a media + mediaPresent = GetAudioTracks(track1, track2, leadOut), + trayOpen = !mediaPresent; + mediaChanged = (oldLeadOut.min!=leadOut.min) || (oldLeadOut.sec!=leadOut.sec) || (oldLeadOut.fr!=leadOut.fr); + // Save old values + oldLeadOut.min = leadOut.min; + oldLeadOut.sec = leadOut.sec; + oldLeadOut.fr = leadOut.fr; + // always success return true; }; diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index 448c53d2..c57c4d99 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -111,6 +111,7 @@ private: HANDLE hEvent; // global event DWORD (*pGetASPI32SupportInfo) (void); // ptrs to aspi funcs DWORD (*pSendASPI32Command) (LPSRB); + TMSF oldLeadOut; }; class CDROM_Interface_Ioctl : public CDROM_Interface From 9a34d7bd322255b71477dc76f242a2841ae23b2c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 22 Mar 2003 08:52:20 +0000 Subject: [PATCH 0704/4131] Fixes to pit timer mode 0 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@783 --- src/hardware/timer.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 75f6d3dd..4194f53c 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -49,38 +49,44 @@ static PIT_Block pit[3]; static void PIT0_Event(void) { PIC_ActivateIRQ(0); - PIC_AddEvent(PIT0_Event,pit[0].micro); + if (pit[0].mode!=0) PIC_AddEvent(PIT0_Event,pit[0].micro); } static void counter_latch(Bitu counter) { /* Fill the read_latch of the selected counter with current count */ PIT_Block * p=&pit[counter]; - + Bit64s micro=PIC_MicroCount()-p->start; + switch (p->mode) { case 0: /* Interrupt on Terminal Count */ /* Counter keeps on counting after passing terminal count */ - micro%=p->micro; - p->read_latch=(Bit16u)(p->cntr-(((float)micro/(float)p->micro)*(float)p->cntr)); + if (micro>p->micro) { + micro-=p->micro; + micro%=(Bit64u)(1000000/((float)PIT_TICK_RATE/(float)0x10000)); + p->read_latch=(Bit16u)(0x10000-(((double)micro/(double)p->micro)*(double)0x10000)); + } else { + p->read_latch=(Bit16u)(p->cntr-(((double)micro/(double)p->micro)*(double)p->cntr)); + } break; case 2: /* Rate Generator */ micro%=p->micro; - p->read_latch=(Bit16u)(p->cntr-(((float)micro/(float)p->micro)*(float)p->cntr)); + p->read_latch=(Bit16u)(p->cntr-(((double)micro/(double)p->micro)*(double)p->cntr)); break; case 3: /* Square Wave Rate Generator */ micro%=p->micro; micro*=2; if (micro>p->micro) micro-=p->micro; - p->read_latch=(Bit16u)(p->cntr-(((float)micro/(float)p->micro)*(float)p->cntr)); + p->read_latch=(Bit16u)(p->cntr-(((double)micro/(double)p->micro)*(double)p->cntr)); break; case 4: /* Software Triggered Strobe */ if (micro>p->micro) p->read_latch=p->write_latch; - else p->read_latch=(Bit16u)(p->cntr-(((float)micro/(float)p->micro)*(float)p->cntr)); + else p->read_latch=(Bit16u)(p->cntr-(((double)micro/(double)p->micro)*(double)p->cntr)); break; default: LOG(LOG_ERROR|LOG_PIT,"Illegal Mode %d for reading counter %d",p->mode,counter); micro%=p->micro; - p->read_latch=(Bit16u)(p->cntr-(((float)micro/(float)p->micro)*(float)p->cntr)); + p->read_latch=(Bit16u)(p->cntr-(((double)micro/(double)p->micro)*(double)p->cntr)); break; } } From 89051332ef81b66c56cc0246a6aa26911b9eda52 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 23 Mar 2003 19:51:54 +0000 Subject: [PATCH 0705/4131] autoclose on error Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@784 --- src/gui/sdlmain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index a2e736ec..59017ec6 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -540,7 +540,7 @@ int main(int argc, char* argv[]) { sdl_sec->Add_bool("fullscreen",false); sdl_sec->Add_bool("autolock",true); sdl_sec->Add_int("sensitivity",100); - sdl_sec->Add_bool("nowait",false); + sdl_sec->Add_bool("nowait",true); /* Init all the dosbox subsystems */ DOSBOX_Init(); std::string config_file; From fd1e05cb2587e5a353e68b92943fbdcefdd0bf9c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 23 Mar 2003 19:54:00 +0000 Subject: [PATCH 0706/4131] Documentation update added command intro Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@785 --- src/gui/midi.cpp | 1 + src/gui/render.cpp | 1 + src/hardware/disney.cpp | 2 +- src/hardware/gus.cpp | 2 +- src/shell/shell.cpp | 28 +++++++++++++++++++++++++++- src/shell/shell_cmds.cpp | 10 +++++++++- src/shell/shell_inc.h | 7 ++++--- 7 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index a3a29823..241f688e 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -118,6 +118,7 @@ bool MIDI_Available(void) { void MIDI_Init(Section * sect) { + MSG_Add("MIDI_CONFIGFILE_HELP","Nothing to setup yet!\n"); midi.available=MIDI_StartUp(); } diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 61003fef..9cd8bad1 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -366,6 +366,7 @@ static void DecreaseFrameSkip(void) { } void RENDER_Init(Section * sec) { + MSG_Add("RENDER_CONFIGFILE_HELP","Available renderers:scale2x, none\n"); Section_prop * section=static_cast(sec); render.pal.first=256; diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 4ad4581a..b03fe524 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -99,7 +99,7 @@ static void DISNEY_CallBack(Bit8u * stream,Bit32u len) { void DISNEY_Init(Section* sec) { - + MSG_Add("DISNEY_CONFIGFILE_HELP","Nothing to setup yet!\n"); Section_prop * section=static_cast(sec); if(!section->Get_bool("enabled")) return; diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 160feac5..bb716391 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -14,7 +14,7 @@ void GUS_Init(Section* sec) { - + MSG_Add("GUS_CONFIGFILE_HELP","Nothing to setup yet!\n"); diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 49696168..570c122f 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -212,6 +212,7 @@ void SHELL_Init() { MSG_Add("SHELL_STARTUP","DOSBox Shell v" VERSION "\n" "DOSBox does not run protected mode games!\n" "For supported shell commands type: HELP\n" + "For a short introduction type: INTRO\n\n" "For more information read the README file in DOSBox directory.\n" "\nHAVE FUN!\nThe DOSBox Team\n\n" ); @@ -233,7 +234,32 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_RENAME_HELP","Renames files.\n"); MSG_Add("SHELL_CMD_DELETE_HELP","Removes files.\n"); MSG_Add("SHELL_CMD_COPY_HELP","Copy files.\n"); - + MSG_Add("SHELL_CMD_INTRO_HELP","Gives an introduction into dosbox\n"); + MSG_Add("SHELL_CMD_INTRO", +"Welcome to DOSBox, a x86 emulator with sound and graphics\n" +"DOSBox creates a shell for you which looks like old plain DOS\n" +"\n" +"Here are some commands to get you started:\n" +"Before you can use the files located on your own filesystem,\n" +"You have to mount the directory containing the files.\n" +"For MS Windows users:\n" +"mount c c:\\dosprog will create a C drive in dosbox with c:\\dosprog as contents.\n" +"\n" +"For linux users:\n" +"mount c /home/user/dosprog will do the same.\n" +"\n" +"Mac OS and others:\n" +"\n" +"I have no idea\n" +"\n" +"When the mount has succesfully completed you can type c: to go to your freshly\n" +"mounted C-drive. Typing dir there will show its contents. cd will allow you to\n" +"enter a directory (recognised by the [] in a directory listing).\n" +"You can run programs/files which end at .exe .bat and .com .\n" +"\n" +"DOSBox will stop/exit without a warning if an error occured!\n" + ); + /* Regular startup */ call_shellstop=CALLBACK_Allocate(); /* Setup the startup CS:IP to kill the last running machine when exitted */ diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 818689ae..248f4c38 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -43,6 +43,7 @@ static SHELL_Cmd cmd_list[]={ "RENAME", 0, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP", "REN", 1, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP", "PAUSE", 0, &DOS_Shell::CMD_PAUSE, "SHELL_CMD_PAUSE_HELP", + "INTRO", 0, &DOS_Shell::CMD_INTRO, "SHELL_CMD_INTRO_HELP", /* "CHDIR", 0, &DOS_Shell::CMD_CHDIR, "Change Directory", "MKDIR", 0, &DOS_Shell::CMD_MKDIR, "Make Directory", @@ -518,4 +519,11 @@ void DOS_Shell::CMD_PAUSE(char * args){ WriteOut(MSG_Get("SHELL_CMD_PAUSE")); Bit8u c;Bit16u n=1; DOS_ReadFile (STDIN,&c,&n); -} \ No newline at end of file +} + +void DOS_Shell::CMD_INTRO(char* args) +{ + WriteOut(MSG_Get("SHELL_CMD_INTRO")); +// Bit8u c;Bit16u n=1; +// DOS_ReadFile (STDIN,&c,&n); +} diff --git a/src/shell/shell_inc.h b/src/shell/shell_inc.h index 59ee1b9d..703d5b04 100644 --- a/src/shell/shell_inc.h +++ b/src/shell/shell_inc.h @@ -66,7 +66,7 @@ public: void CMD_CLS(char * args); void CMD_COPY(char * args); void CMD_DIR(char * args); - void CMD_DELETE(char * args); + void CMD_DELETE(char * args); void CMD_ECHO(char * args); void CMD_EXIT(char * args); void CMD_MKDIR(char * args); @@ -77,9 +77,10 @@ public: void CMD_GOTO(char * args); void CMD_TYPE(char * args); void CMD_REM(char * args); - void CMD_RENAME(char * args); + void CMD_RENAME(char * args); void SyntaxError(void); - void CMD_PAUSE(char * args); + void CMD_PAUSE(char * args); + void CMD_INTRO(char * args); /* The shell's variables */ Bit16u input_handle; BatchFile * bf; From 39ac002795f54b0a3a456fa1bedf231a5542fa81 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 23 Mar 2003 20:23:25 +0000 Subject: [PATCH 0707/4131] Fix for 64-bit file pointers big endian machines. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@786 --- src/dos/drive_local.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 65d18d5b..60cfadff 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -334,17 +334,19 @@ bool localFile::Seek(Bit32u * pos,Bit32u type) { //TODO Give some doserrorcode; return false;//ERROR } - fpos_t temppos; int ret=fseek(fhandle,*pos,seektype); if (ret!=0) { // Out of file range, pretend everythings ok // and move file pointer top end of file... ?! (Black Thorne) fseek(fhandle,0,SEEK_END); }; +#if 0 + fpos_t temppos; fgetpos(fhandle,&temppos); -//TODO Hope we don't encouter files with 64 bits size Bit32u * fake_pos=(Bit32u*)&temppos; *pos=*fake_pos; +#endif + *pos=(Bit32u)ftell(fhandle); last_action=NONE; return true; } From 2f759c00505a14453d1727b0bfba205dea2d46ad Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 24 Mar 2003 09:50:52 +0000 Subject: [PATCH 0708/4131] Double typedef Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@787 --- src/dos/Ntddstor.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/Ntddstor.h b/src/dos/Ntddstor.h index b6b2e528..766f19ce 100644 --- a/src/dos/Ntddstor.h +++ b/src/dos/Ntddstor.h @@ -193,10 +193,11 @@ typedef struct _STORAGE_BUS_RESET_REQUEST { // TRUE means prevent media from being removed. // FALSE means allow media removal. // - +#if defined (_MSC_VER) /* MS Visual C++ */ typedef struct _PREVENT_MEDIA_REMOVAL { BOOLEAN PreventMediaRemoval; } PREVENT_MEDIA_REMOVAL, *PPREVENT_MEDIA_REMOVAL; +#endif // begin_ntminitape From d4b640d29ecd893e48602dece689a822807a6ea5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 24 Mar 2003 09:54:50 +0000 Subject: [PATCH 0709/4131] Fixes for not using dirent structure as a result Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@788 --- src/dos/drive_cache.cpp | 26 ++++++++++++++++---------- src/dos/drive_local.cpp | 10 +++++----- src/dos/drives.h | 8 +++++--- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 3241cc3d..22059186 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -106,7 +106,7 @@ void DOS_Drive_Cache::SetBaseDir(const char* baseDir) Bit16u id; strcpy(basePath,baseDir); if (OpenDir(baseDir,id)) { - struct dirent* result; + char * result; ReadDir(id,result); }; }; @@ -427,7 +427,7 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* strcpy(work,basePath); if (OpenDir(curDir,work,id)) { char buffer[CROSS_LEN]; - struct dirent* result; + char * result; strcpy(buffer,dirPath); ReadDir(id,result); strcpy(dirPath,buffer); @@ -460,7 +460,7 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* if (!IsCachedIn(curDir)) { if (OpenDir(curDir,work,id)) { char buffer[CROSS_LEN]; - struct dirent* result; + char * result; strcpy(buffer,dirPath); ReadDir(id,result); strcpy(dirPath,buffer); @@ -534,7 +534,7 @@ void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name) dir->outputList.push_back(info); }; -bool DOS_Drive_Cache::ReadDir(Bit16u id, struct dirent* &result) +bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) { // shouldnt happen... if (id>MAX_OPENDIRS) return false; @@ -579,15 +579,15 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, struct dirent* &result) return false; }; -bool DOS_Drive_Cache::SetResult(CFileInfo* dir, struct dirent* &result, Bit16u entryNr) +bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bit16u entryNr) { - static struct dirent res; + static char res[CROSS_LEN]; - result = &res; + result = res; if (entryNr>=dir->outputList.size()) return false; CFileInfo* info = dir->outputList[entryNr]; // copy filename, short version - strcpy(result->d_name,info->shortname); + strcpy(res,info->shortname); // Set to next Entry dir->nextEntry = entryNr+1; return true; @@ -615,10 +615,16 @@ bool DOS_No_Drive_Cache::OpenDir(const char* path, Bit16u& id) return true; }; -bool DOS_No_Drive_Cache::ReadDir(Bit16u id, struct dirent* &result) +bool DOS_No_Drive_Cache::ReadDir(Bit16u id, char* &result) { + + static char res[CROSS_LEN]; + dirent * ent; + if (!srch_opendir) return false; - if ((result=readdir(srch_opendir))==NULL) { + if ((ent=readdir(srch_opendir))==NULL) { + strcpy(res,ent->d_name); + result=res; closedir(srch_opendir); srch_opendir=NULL; return false; diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 60cfadff..2f4eb07e 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -115,7 +115,7 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { bool localDrive::FindNext(DOS_DTA & dta) { - struct dirent* dir_ent; + char * dir_ent; struct stat stat_block; char full_name[CROSS_LEN]; @@ -131,10 +131,10 @@ again: return false; } - if(!WildFileCmp(dir_ent->d_name,srch_pattern)) goto again; + if(!WildFileCmp(dir_ent,srch_pattern)) goto again; strcpy(full_name,srchInfo[id].srch_dir); - strcat(full_name,dir_ent->d_name); + strcat(full_name,dir_ent); if (stat(dirCache.GetExpandName(full_name),&stat_block)!=0) { goto again; } @@ -150,8 +150,8 @@ again: /*file is okay, setup everything to be copied in DTA Block */ char find_name[DOS_NAMELENGTH_ASCII];Bit16u find_date,find_time;Bit32u find_size; - if(strlen(dir_ent->d_name)d_name); + if(strlen(dir_ent) Date: Mon, 24 Mar 2003 11:25:13 +0000 Subject: [PATCH 0710/4131] Allow environment strings to change config settings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@789 --- include/setup.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/setup.h b/include/setup.h index 248acf7c..21ea765b 100644 --- a/include/setup.h +++ b/include/setup.h @@ -179,7 +179,8 @@ public: void StartUp(); void PrintConfig(const char* configfilename); void ParseConfigFile(const char* configfilename); - + void ParseEnv(char ** envp); + std::list sectionlist; typedef std::list::iterator it; typedef std::list::reverse_iterator reverse_it; From aea4169ddbfc8287304c52fc4b4f073036972af8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 24 Mar 2003 11:28:26 +0000 Subject: [PATCH 0711/4131] Support for using environment strings to change config Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@790 --- src/misc/setup.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 544ad6d9..52091726 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -111,7 +111,7 @@ const char* Section_prop::Get_string(const char* _propname){ return ((*tel)->GetValue())._string->c_str(); } } - return NULL; + return ""; } int Section_prop::Get_hex(const char* _propname){ for(it tel=properties.begin();tel!=properties.end();tel++){ @@ -254,6 +254,22 @@ void Config::ParseConfigFile(const char* configfilename){ } } +void Config::ParseEnv(char ** envp) { + for(char** env=envp; *env;env++) { + char copy[1024]; + strncpy(copy,*env,1024); + if(strncasecmp(copy,"DOSBOX_",7)) + continue; + char* sec_name = ©[7]; + char* prop_name = strrchr(sec_name,'_'); + *prop_name++=0; + Section* sect = GetSection(sec_name); + if(!sect) + continue; + sect->HandleInputline(prop_name); + } +} + void Config::SetStartUp(void (*_function)(void)) { _start_function=_function; } From ebaa08a204b09964f6dfbec63f16947365231160 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 24 Mar 2003 11:29:26 +0000 Subject: [PATCH 0712/4131] Use environment strings for settings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@791 --- src/gui/sdlmain.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 59017ec6..536d23b6 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -18,6 +18,8 @@ #include #include +#include + #include "SDL.h" #include "SDL_thread.h" @@ -551,6 +553,7 @@ int main(int argc, char* argv[]) { } /* Parse the config file */ control->ParseConfigFile(config_file.c_str()); + control->ParseEnv(environ); /* Init all the sections */ control->Init(); /* Some extra SDL Functions */ From 33dea6cf403f5064d3df02d2704f00659dd0c3ce Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 24 Mar 2003 11:37:31 +0000 Subject: [PATCH 0713/4131] added info about frameskip Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@792 --- README | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README b/README index 2a07ff7b..8709654d 100644 --- a/README +++ b/README @@ -111,6 +111,36 @@ FAQ: 4. Check the site/forum. + +To run resource-demanding games: +=============================== + +DOSBox emulates at the CPU, the sound and graphic cards, and some other +stuff, all at the same time. You can overclock DOSBox by using CTRL+F12, but +you'll be limited by the power of your actual CPU. You can see how much free +time your true CPU has by looking at the Task Manager in Windows 2000/XP and +the System Monitor in Windows 95/98/ME. Once 100% of your real CPU time is +used there is no further way to speed up DOSBox unless you reduce the load +generated by the non-CPU parts of DOSBox. + +So: + +Close every program but DOSBox + +Overclock DOSBox until 100% of your CPU is used (use the utilities above to +check) + +Since VGA emulation is the most demanding part of DOSBox in terms of actual +CPU usage, we'll start here. Increase the number of frames skipped (in +increments of one) by pressing CRTL+F8. Your CPU usage should decrease. +Go back to step 2 and repeat this until the game runs fast enough for you. +Please note that this is a trade off: you lose in fluidity of video what you +gain in speed + +You can also try to disable the sound through the setup utility of the game +to further reduce load on your CPU. + + Building your own Version DOSBox: ================================= From e9a2e7db4d9ba58e756218257a49a45d56ae72e8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 24 Mar 2003 11:39:34 +0000 Subject: [PATCH 0714/4131] typo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@793 --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 8709654d..61c28428 100644 --- a/README +++ b/README @@ -133,7 +133,7 @@ check) Since VGA emulation is the most demanding part of DOSBox in terms of actual CPU usage, we'll start here. Increase the number of frames skipped (in increments of one) by pressing CRTL+F8. Your CPU usage should decrease. -Go back to step 2 and repeat this until the game runs fast enough for you. +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 From b0fa953b28ee968b47dfe17ba71be6ba200ad782 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 24 Mar 2003 12:31:27 +0000 Subject: [PATCH 0715/4131] Fixed scsi target id problem, handware id compare no longer case sensitive Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@794 --- src/dos/cdrom.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 6bb181f7..4de630c0 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -74,8 +74,11 @@ BYTE CDROM_Interface_Aspi::GetHostAdapter(char* hardwareID) sh.SRB_HaId = i; pSendASPI32Command((LPSRB)&sh); if (sh.SRB_Status!=SS_COMP) continue; - + + // Indicates the maximum number of targets the adapter supports + // If the value is not 8 or 16, then it should be assumed max target is 8 max = (int)sh.HA_Unique[3]; + if ((max!=8) && (max!=16)) max = 8; for(j=0; j Date: Mon, 24 Mar 2003 14:35:30 +0000 Subject: [PATCH 0716/4131] Rewrite for maximum of 80 colums. Added some entries to FAQ Added some new key combinations. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@795 --- README | 120 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 69 insertions(+), 51 deletions(-) diff --git a/README b/README index 61c28428..54820a01 100644 --- a/README +++ b/README @@ -3,17 +3,21 @@ DOSBox v0.58 Usage: ====== -With the new internal shell We've changed the command line a bit, so let's just give some -examples of what you can do now. +With the new internal shell,we've changed the command line a bit, +so let's just give some examples of what you can do now. dosbox - With nothing on the command line you'll end up on the internal drive and from there you - can mount directories as drives. + With nothing on the command line you'll end up on the internal drive and + from there you can mount directories as drives. dosbox [filename/directory] - If dosbox detects a directory it'll mount that as c:\ and then start the shell. - If dosbox doesn't detect a directory it'll assume you mean an executable this can be - .bat .com .exe. Doesn't need to have extension included. Then it'll strip the directory - from the filename and mount that as c:\ and then run the file. + If dosbox detects a directory it'll mount that as the C: drive + and then start the shell from c:\. + If dosbox doesn't detect a directory it'll assume you mean an executable. + This can be .bat .com .exe. Doesn't need to have extension included. + It will mount the directory the file is in as the C: drive. + Then start up the shell which will start the file. + +There also are a couple of command line switches. dosbox -fullscreen starts dosbox in fullscreen mode. @@ -22,66 +26,76 @@ dosbox -conf file dosbox -lang file loads file as a languagefile. -You can also add commands to be executed before the main program starts. Or you can use them -to start the program. +You can also add commands to be executed before the main program starts. +Or you can use them to start the program. To add commands use the -c command line switch. -For example -dosbox c:\atlantis\atlantis.exe -c "MOUNT D C:\SAVES" "SET TEST=blah" - This would mount c:\atlanis as c:\ and run atlantis.exe from that directory but before it - does that it would first mount C:\SAVES as the D drive and set the environment variable test to blah. -Dragging files or directories onto the DOSBox executable should also work. +For example: +dosbox c:\atlantis\atlantis.exe -c "MOUNT D C:\SAVES" + This would mount c:\atlanis as c:\ and run atlantis.exe. + Before it does that it would first mount C:\SAVES as the D drive. + +In Windows you can also drag directories/files on the dosbox executable. Internal Programs: ================== MOUNT Program to mount local directories as drives inside DOSBox. -The option -t specifies the media: dir = harddisk, floppy = floppy drive, cdrom = cdrom drive. -The option -size specifies the size. -The option -aspi forces to use aspi driver (only valid if mounting a cdrom and on Win2000/XP/NT systems). -For example to mount c:\floppy as a floppy : mount a c:\floppy -t floppy -For example to mount system cdrom drive e as cdrom drive d in dosbox : mount d e:\ -t cdrom -- In Win 95/98/ME you need latest ASPI driver to get cdrom audio support. -- In Win 2000/XP/NT you have the option to use an ASPI driver (add -aspi) at the end of the mount command. -It is even possible to mount a directory as cdrom, but you have some limited support for it then. +The option -t specifies the media: Where can be. + dir = harddisk + floppy = floppy drive + cdrom = cdrom drive +The option -aspi forces to use aspi driver + (only valid if mounting a cdrom and on Win2000/XP/NT systems). + +For example to mount c:\floppy as a floppy : mount a c:\floppy -t floppy +For example to mount system cdrom drive e as cdrom drive d in dosbox + mount d e:\ -t cdrom +- In Win 95/98/ME you need latest ASPI driver to get cdrom audio support. +- In Win 2000/XP/NT you have the option to use an ASPI driver (add -aspi) + at the end of the mount command. + +It is also possible to mount a directory as cdrom, but it's limited. MEM Program to display the amount of free memory CONFIG -Utility for generating a configfile with the current settings and for generating the languagefile. +Utility for generating a config file and language file. The option -writeconf filename is used to write the current config settings. The option -writelang filename is used to write the current language strings. -To get more information about how to use one these programs use the the /? command line switch. +For more information use the the /? command line switch with the programs. -The Configfile: +The Config File: =============== -A configfile can be generated by CONFIG.COM. You can edit it to customize DOSBox. -The file is divided in several sections (the names got [] around it). Some sections have options which you can set. +A config file can be generated by CONFIG.COM, edit it to customize DOSBox. +The file is divided in several sections (the names got [] around it). +Some sections have options which you can set. # and % indicate commentlines. The generated configfile contains the current settings. You can alter them and start dosbox with the -conf switch to load the file and use these settings. -For example in the section sblaster you can change the irq of the soundblaster and disable/enable the -adlib emulation. -The Languagefile: +The Language File: ================= -A languagefile can be generated by CONFIG.COM. If you read it you will understand how to change it. -Start Dosbox with -lang switch to use your language file or enter the location of the languagefile -in the configfile.(section:[dosbox] language=full path to languagefile.) +A language file can be generated by CONFIG.COM. +Read it and you will hopefuly understand how to change it. +Start Dosbox with -lang switch to use your new language file +Or you can setup the filename in the config file in the [dosbox] section. +There's a language= entry that can be changed with the filename. Special Keys: ============= ALT-ENTER Go full screen and back. -CTRL-F5 Save a screenshot -CTRL-F7 Decrease frameskip -CTRL-F8 Increase frameskip -CTRL-F9 Go full screen and back. +CTRL-F5 Save a screenshot. +CTRL-F6 Start/Stop recording sound output to a wave file. +CTRL-F7 Decrease frameskip. +CTRL-F8 Increase frameskip. +CTRL-F9 Kill dosbox. CTRL-F10 Capture/Release the mouse. CTRL-F11 Slowdown emulation. CTRL-F12 Speedup emulation. @@ -95,27 +109,31 @@ of games written for an 286 machine. FAQ: ==== -1.Q: I've got a Z instead of a C at the prompt. - A: In DOSBox you can mount directories as drives - in win32: mount c D:\ would give you an C in DOSBox which points - at D:\ in win32 - in linux: mount c /home/username would give you and C in DOSBox - which points at /home/username in Linux +Q: I've got a Z instead of a C at the prompt. +A: In DOSBox you can mount directories as drives + in win32: mount c D:\ would give you an C in DOSBox which points + at D:\ in win32 + in linux: mount c /home/username would give you and C in DOSBox + which points at /home/username in Linux -2.Q: The window is too small. - A: When you mouse touches the edges of the DOSBox screen you can click and drag it to - the size you prefer. +Q: The mouse doesn't work. +A: Normally dosbox detects the mouse being used by a game, if you click on + the screen then it should get locked and work. + Sometimes the dosbox mouse detection doesn't work with certain games, you + might have to force to lock the mouse then with ctrl-f10. -3.Q: The mouse(cursor) acts weird. (eg only updated when you press the mousebutton) - A: Lock the mouse with ctrl-F10. It should then behave the way you expect it to do. +Q: The sound stutters. +A: Your using too much cpu power to keep dosbox running at the current speed. + You can either lower the cycles or skip frames or get a faster machine. -4. Check the site/forum. + +For more questions check the site/forum. To run resource-demanding games: =============================== -DOSBox emulates at the CPU, the sound and graphic cards, and some other +DOSBox emulates the CPU, the sound and graphic cards, and some other stuff, all at the same time. You can overclock DOSBox by using CTRL+F12, but you'll be limited by the power of your actual CPU. You can see how much free time your true CPU has by looking at the Task Manager in Windows 2000/XP and From d97fa68f0654913748225a3351018fb560aab80d Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 25 Mar 2003 12:53:39 +0000 Subject: [PATCH 0717/4131] fixed resource leak (CloseHandle) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@796 --- src/dos/cdrom.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 4de630c0..b84f1510 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -184,6 +184,7 @@ bool CDROM_Interface_Aspi::GetVendor(BYTE HA_num, BYTE SCSI_Id, BYTE SCSI_Lun, c if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,30000); // LOG(LOG_MISC|LOG_ERROR,"SCSI: Pending done."); + CloseHandle(hEvent); if (srbExec.SRB_Status != SS_COMP) { strcpy (szBuffer, "error" ); return false; @@ -382,6 +383,8 @@ DWORD CDROM_Interface_Aspi::GetTOC(LPTOC toc) if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,30000); + CloseHandle(hEvent); + return (s.SRB_Status==SS_COMP); } @@ -420,6 +423,8 @@ bool CDROM_Interface_Aspi::PlayAudioSector(unsigned long start,unsigned long len if(dwStatus==SS_PENDING) WaitForSingleObject(hEvent,10000); + CloseHandle(hEvent); + return s.SRB_Status==SS_COMP; } @@ -453,9 +458,9 @@ bool CDROM_Interface_Aspi::PauseAudio(bool resume) if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,30000); - if (s.SRB_Status!=SS_COMP) return false; + CloseHandle(hEvent); - return true; + return (s.SRB_Status==SS_COMP); }; bool CDROM_Interface_Aspi::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) @@ -493,6 +498,8 @@ bool CDROM_Interface_Aspi::GetAudioSub(unsigned char& attr, unsigned char& track if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); + CloseHandle(hEvent); + if (s.SRB_Status!=SS_COMP) return false; attr = (pos.ADR<<4) | pos.Control; @@ -543,6 +550,8 @@ bool CDROM_Interface_Aspi::GetUPC(unsigned char& attr, char* upcdata) if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); + CloseHandle(hEvent); + if (s.SRB_Status!=SS_COMP) return false; // attr = (upc.ADR<<4) | upc.Control; @@ -593,6 +602,8 @@ bool CDROM_Interface_Aspi::GetAudioStatus(bool& playing, bool& pause) if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); + CloseHandle(hEvent); + if (s.SRB_Status!=SS_COMP) return false; playing = (sub.AudioStatus==0x11); @@ -631,6 +642,8 @@ bool CDROM_Interface_Aspi::LoadUnloadMedia(bool unload) if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); + CloseHandle(hEvent); + if (s.SRB_Status!=SS_COMP) return false; return true; @@ -696,6 +709,8 @@ bool CDROM_Interface_Aspi::ReadSectors(void* buffer, bool raw, unsigned long sec if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); + CloseHandle(hEvent); + if (s.SRB_Status!=SS_COMP) { if (!raw) delete[] inPtr; return false; From c3b07fe35af0e87083e3478ca76cfa10a61d654c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 26 Mar 2003 11:56:01 +0000 Subject: [PATCH 0718/4131] *-*- added before darwin* Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@797 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 6a099c2b..1da5fe0a 100644 --- a/configure.in +++ b/configure.in @@ -78,7 +78,7 @@ case "$target" in *-*-cygwin* | *-*-mingw32*) LIBS="$LIBS -lwinmm" ;; - darwin*) + *-*-darwin*) dnl We have a problem here: both MacOS X and Darwin report dnl the same signature "powerpc-apple-darwin*" - so we have dnl to do more to distinguish them. From a9b1941599fb37a17466199733d9b8489e675b2f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 26 Mar 2003 11:56:48 +0000 Subject: [PATCH 0719/4131] removed settings.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@798 From 1193b4ef50402ed4fd42cf7e51714935a0df090e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 26 Mar 2003 12:29:04 +0000 Subject: [PATCH 0720/4131] hack for macOSX environ Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@799 --- src/gui/sdlmain.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 536d23b6..f7b2f6b3 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -20,6 +20,10 @@ #include #include +#ifdef MACOSX +extern char** environ; +#endif + #include "SDL.h" #include "SDL_thread.h" From 9ac71b742055546caae85753e4c267b5ffbdf1d0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 26 Mar 2003 14:31:31 +0000 Subject: [PATCH 0721/4131] Fixes to mouse limit ranges Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@800 --- src/ints/mouse.cpp | 91 +++++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 34 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 511e0ad9..949dc7f9 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -26,6 +26,7 @@ #include "pic.h" #include "inout.h" #include "int10.h" +#include "bios.h" static Bitu call_int33,call_int74; @@ -93,7 +94,6 @@ static struct { Bit16s clipx,clipy; Bit16s hotx,hoty; Bit16u textAndMask, textXorMask; - Bit16u resy; float mickeysPerPixel_x; float mickeysPerPixel_y; @@ -324,11 +324,11 @@ void Mouse_CursorMoved(float x,float y) { mouse.mickey_y += dy; mouse.x += dx; - if (mouse.x>=mouse.max_x) mouse.x=mouse.max_x-1.0f; - if (mouse.x< mouse.min_x) mouse.x=mouse.min_x; + if (mouse.x>mouse.max_x) mouse.x=mouse.max_x; + if (mouse.x=mouse.max_y) mouse.y=mouse.max_y-1.0f; - if (mouse.y< mouse.min_y) mouse.y=mouse.min_y; + if (mouse.y>mouse.max_y) mouse.y=mouse.max_y; + if (mouse.y0) mouse.shown=0; DrawCursor(); break; @@ -481,22 +510,26 @@ static Bitu INT33_Handler(void) { break; } case 0x07: /* Define horizontal cursor range */ - if (reg_cx Date: Wed, 26 Mar 2003 20:06:59 +0000 Subject: [PATCH 0722/4131] made mount more flexible Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@801 --- src/dos/dos_programs.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index a3a5f366..be6cbe90 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -47,14 +47,8 @@ public: } return; } - std::string type="dir"; - - // get the drive letter - cmd->FindCommand(1,temp_line); - if (temp_line.size()>1) goto showusage; - drive=toupper(temp_line[0]); - if (!isalpha(drive)) goto showusage; + std::string type="dir"; cmd->FindString("-t",type,true); if (type=="floppy" || type=="dir" || type=="cdrom") { Bit16u sizes[4]; @@ -84,7 +78,12 @@ public: scan++; } number[index]=0;sizes[count++]=atoi(number); - + + // get the drive letter + cmd->FindCommand(1,temp_line); + if ((temp_line.size() > 2) || ((temp_line.size()>1) && (temp_line[1]!=':'))) goto showusage; + drive=toupper(temp_line[0]); + if (!isalpha(drive)) goto showusage; if (!cmd->FindCommand(2,temp_line)) goto showusage; if (!temp_line.size()) goto showusage; From e7f3e596de2f235c37e3aeabe31b34c557b60673 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 26 Mar 2003 20:27:01 +0000 Subject: [PATCH 0723/4131] added killswitch Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@802 --- src/gui/sdlmain.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index f7b2f6b3..bc8ad5ae 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -237,6 +237,10 @@ static void GUI_ShutDown(Section * sec) { } +static void KillSwitch(void){ + throw 1; +} + static void GUI_StartUp(Section * sec) { MSG_Add("SDL_CONFIGFILE_HELP","SDL related options.\n"); sec->AddDestroyFunction(&GUI_ShutDown); @@ -260,6 +264,7 @@ static void GUI_StartUp(Section * sec) { SDL_EnableKeyRepeat(250,30); SDL_EnableUNICODE(1); /* Get some Keybinds */ + KEYBOARD_AddEvent(KBD_f9,KBD_MOD_CTRL,KillSwitch); KEYBOARD_AddEvent(KBD_f10,KBD_MOD_CTRL,CaptureMouse); KEYBOARD_AddEvent(KBD_enter,KBD_MOD_ALT,SwitchFullScreen); } From d9959431481bd83c0076e7272a38efcebf2ef306 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 27 Mar 2003 19:46:05 +0000 Subject: [PATCH 0724/4131] changed int 25 and int 26 to act like real int 25. Hopefully not all is broken Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@803 --- src/dos/dos.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 710a7f92..c08ae71f 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -28,6 +28,7 @@ #include "regs.h" #include "dos_inc.h" #include "setup.h" +#include "cpu.h" DOS_Block dos; DOS_InfoBlock dos_infoblock; @@ -861,11 +862,12 @@ static Bitu DOS_27Handler(void) return CBRET_NONE; } static Bitu DOS_25Handler(void) { + flags.type=t_UNKNOWN; if(Drives[reg_al]==0){ reg_ax=0x8002; - CALLBACK_SCF(true); + flags.cf=true; }else{ - CALLBACK_SCF(false); + flags.cf=false; reg_ax=0; if((reg_cx != 1) ||(reg_dx != 1)) LOG(LOG_DOSMISC,"int 25 called but not as diskdetection"); @@ -874,11 +876,13 @@ static Bitu DOS_25Handler(void) { } static Bitu DOS_26Handler(void) { LOG(LOG_DOSMISC,"int 26 called: hope for the best!"); + flags.type=t_UNKNOWN; if(Drives[reg_al]==0){ + reg_ax=0x8002; - CALLBACK_SCF(true); + flags.cf=true; }else{ - CALLBACK_SCF(false); + flags.cf=false; reg_ax=0; } return CBRET_NONE; @@ -912,7 +916,7 @@ void DOS_Init(Section* sec) { RealSetVec(0x25,CALLBACK_RealPointer(call_25)); call_26=CALLBACK_Allocate(); - CALLBACK_Setup(call_26,DOS_21Handler,CB_RETF); + CALLBACK_Setup(call_26,DOS_26Handler,CB_RETF); RealSetVec(0x26,CALLBACK_RealPointer(call_26)); call_27=CALLBACK_Allocate(); From 9a6d2549433f1b64ed58623d308dc274049c089b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 27 Mar 2003 19:48:33 +0000 Subject: [PATCH 0725/4131] changed the help string in the configfile Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@804 --- src/gui/render.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 9cd8bad1..a6176408 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -366,7 +366,7 @@ static void DecreaseFrameSkip(void) { } void RENDER_Init(Section * sec) { - MSG_Add("RENDER_CONFIGFILE_HELP","Available renderers:scale2x, none\n"); + MSG_Add("RENDER_CONFIGFILE_HELP","Available scalers: scale2x, none\n"); Section_prop * section=static_cast(sec); render.pal.first=256; From 96bcd602afb0b27df6fd3f3bb96e3da9e7c2f304 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 27 Mar 2003 20:02:30 +0000 Subject: [PATCH 0726/4131] Check for ALSA Better checking if libpng needs zlib to link. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@805 --- configure.in | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 1da5fe0a..74312477 100644 --- a/configure.in +++ b/configure.in @@ -43,6 +43,8 @@ AC_MSG_CHECKING(if compiler allows __attribute__) AC_TRY_COMPILE([], [typedef struct { } __attribute__ ((packed)) junk;], [ AC_MSG_RESULT(yes);AC_DEFINE(C_HAS_ATTRIBUTE)],AC_MSG_RESULT(no)) +AM_PATH_ALSA(0.9.0, [AC_DEFINE(HAVE_ALSA, 1, [Define to use ALSA for MIDI])]) + #Check for big endian machine, should #define WORD_BIGENDIAN if so AC_C_BIGENDIAN @@ -63,12 +65,16 @@ AC_ARG_ENABLE(debug,[ --enable-debug Enable debug mode],[ AH_TEMPLATE(C_SSHOT,[Define to 1 to enable screenshots, requires libpng]) AC_ARG_ENABLE(shots,[ --enable-shots Enable screenshot support],[ AC_CHECK_HEADER(png.h,have_png_h=yes,) - AC_CHECK_LIB(png, png_check_sig, have_png_lib=yes, , -lz) + AC_CHECK_LIB(png, png_check_sig, have_png_lib=yes, ,) + AC_CHECK_LIB(png, png_check_sig, have_png_lib_z=yes, , -lz) if test x$have_png_lib = xyes -a x$have_png_h = xyes ; then LIBS="$LIBS -lpng" AC_DEFINE(C_SSHOT,1) - else + else if test x$have_png_lib_z = xyes -a x$have_png_h = xyes ; then + LIBS="$LIBS -lpng -lz" + AC_DEFINE(C_SSHOT,1) + else AC_MSG_WARN([Can't enable screenshots without libpng]) fi ],) From 065ef2207e310a92201132333abd887e11d34875 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 27 Mar 2003 20:14:14 +0000 Subject: [PATCH 0727/4131] updated Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@806 --- ChangeLog | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6f389ab0..3745cf8b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,7 +18,10 @@ - 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 From cf27af6f8b30f7a548a183f14499874502f75a95 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 27 Mar 2003 20:16:11 +0000 Subject: [PATCH 0728/4131] made date and time of virtual files more consistent. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@807 --- src/dos/drive_virtual.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index f697c598..5243d477 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,6 +30,8 @@ struct VFILE_Block { const char * name; Bit8u * data; Bit32u size; + Bit16u date; + Bit16u time; VFILE_Block * next; }; @@ -41,6 +43,8 @@ void VFILE_Register(const char * name,Bit8u * data,Bit32u size) { new_file->name=name; new_file->data=data; new_file->size=size; + new_file->date=DOS_PackDate(2002,10,1); + new_file->time=DOS_PackTime(12,34,56); new_file->next=first_file; first_file=new_file; } @@ -65,6 +69,8 @@ Virtual_File::Virtual_File(Bit8u * in_data,Bit32u in_size) { file_size=in_size; file_data=in_data; file_pos=0; + date=DOS_PackDate(2002,10,1); + time=DOS_PackTime(12,34,56); } bool Virtual_File::Read(Bit8u * data,Bit16u * size) { @@ -159,8 +165,8 @@ bool Virtual_Drive::FileStat(const char* name, FileStat_Block * const stat_block if (strcasecmp(name,cur_file->name)==0) { stat_block->attr=DOS_ATTR_ARCHIVE; stat_block->size=cur_file->size; - stat_block->date=DOS_PackDate(2002,0,0); - stat_block->time=DOS_PackTime(12,12,12); + stat_block->date=DOS_PackDate(2002,10,1); + stat_block->time=DOS_PackTime(12,34,56); return true; } cur_file=cur_file->next; @@ -187,7 +193,7 @@ bool Virtual_Drive::FindNext(DOS_DTA & dta) { dta.GetSearchParams(attr,pattern); while (search_file) { if (WildFileCmp(search_file->name,pattern)) { - dta.SetResult(search_file->name,search_file->size,6,2,DOS_ATTR_ARCHIVE); + dta.SetResult(search_file->name,search_file->size,search_file->date,search_file->time,DOS_ATTR_ARCHIVE); search_file=search_file->next; return true; } From bd50a564f0a4eaa03700d6cefa63848422547c8b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 27 Mar 2003 20:19:31 +0000 Subject: [PATCH 0729/4131] Midi now uses midi device classes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@808 --- src/gui/midi.cpp | 92 +++++++++++++++++++++++++++++++++++--------- src/gui/midi_oss.h | 86 ++++++++++++++++++++++++----------------- src/gui/midi_win32.h | 85 ++++++++++++++++++++++------------------ 3 files changed, 172 insertions(+), 91 deletions(-) diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 241f688e..692784ec 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -16,10 +16,17 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include +#include +#include #include "dosbox.h" +#include "cross.h" +#include "support.h" #include "setup.h" +#define SYSEX_SIZE 1024 + Bit8u MIDI_evt_len[256] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x10 @@ -43,25 +50,42 @@ Bit8u MIDI_evt_len[256] = { 0,2,3,2, 0,0,1,1, 1,0,1,1, 1,0,1,1 // 0xf0 }; -#define SYSEX_SIZE 1024 - -#if defined (WIN32) +class MidiHandler; + +MidiHandler * handler_list=0; + +class MidiHandler { +public: + MidiHandler() { + next=handler_list; + handler_list=this; + }; + virtual bool Open(const char * conf) { return true; }; + virtual void Close(void) {}; + virtual void PlayMsg(Bit32u msg) {}; + virtual void PlaySysex(Bit8u * sysex,Bitu len) {}; + virtual char * GetName(void) { return "none"; }; + MidiHandler * next; +}; + +MidiHandler Midi_none; + +/* Include different midi drivers, lowest ones get checked first for default */ + +#if defined(MACOSX) + +#include "midi_coreaudio.h" + +#elif defined (WIN32) #include "midi_win32.h" -#elif defined (UNIX) && !defined(__BEOS__) +#elif #include "midi_oss.h" -#else /* Fall back to no device playing */ - -static void MIDI_PlayMsg(Bit32u msg) {} -static void MIDI_PlaySysex(Bit8u * sysex,Bitu len) {}; -static bool MIDI_StartUp(void) { return false;} - #endif - static struct { Bitu status; Bitu cmd_len; @@ -75,9 +99,9 @@ static struct { bool active; } sysex; bool available; + MidiHandler * handler; } midi; - void MIDI_RawOutByte(Bit8u data) { /* Test for a new status byte */ if (midi.sysex.active && !(data&0x80)) { @@ -87,7 +111,7 @@ void MIDI_RawOutByte(Bit8u data) { if (midi.sysex.active) { /* Play a sysex message */ midi.sysex.buf[midi.sysex.used++]=0xf7; - MIDI_PlaySysex(midi.sysex.buf,midi.sysex.used); + midi.handler->PlaySysex(midi.sysex.buf,midi.sysex.used); LOG(0,"Sysex message size %d",midi.sysex.used); midi.sysex.active=false; if (data==0xf7) return; @@ -106,7 +130,7 @@ void MIDI_RawOutByte(Bit8u data) { midi.cmd_msg|=data << (8 * midi.cmd_pos); midi.cmd_pos++; if (midi.cmd_pos >= midi.cmd_len) { - MIDI_PlayMsg(midi.cmd_msg); + midi.handler->PlayMsg(midi.cmd_msg); midi.cmd_msg=midi.status; midi.cmd_pos=1; } @@ -116,9 +140,41 @@ bool MIDI_Available(void) { return midi.available; } - -void MIDI_Init(Section * sect) { - MSG_Add("MIDI_CONFIGFILE_HELP","Nothing to setup yet!\n"); - midi.available=MIDI_StartUp(); +void MIDI_Init(Section * sec) { + Section_prop * section=static_cast(sec); + MSG_Add("MIDI_CONFIGFILE_HELP","Set midi output device,alsa,oss,win32,coreaudio,none\n"); + const char * dev=section->Get_string("device"); + const char * conf=section->Get_string("config"); + /* If device = "default" go for first handler that works */ + MidiHandler * handler; + if (!strcasecmp(dev,"default")) goto getdefault; + handler=handler_list; + while (handler) { + if (!strcasecmp(dev,handler->GetName())) { + if (!handler->Open(conf)) { + LOG_MSG("MIDI:Can't open device:%s with config:%s.",dev,conf); + goto getdefault; + } + midi.handler=handler; + midi.available=true; + LOG_MSG("MIDI:Opened device:%s",handler->GetName()); + return; + } + handler=handler->next; + } + LOG_MSG("MIDI:Can't find device:%s, finding default handler.",dev); +getdefault: + handler=handler_list; + while (handler) { + if (handler->Open(conf)) { + midi.available=true; + midi.handler=handler; + LOG_MSG("MIDI:Opened device:%s",handler->GetName()); + return; + } + handler=handler->next; + } + /* This shouldn't be possible */ + midi.available=false; } diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index a45e25bc..d4a1c8a5 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -17,44 +17,60 @@ */ #include - -static int m_device; - #define SEQ_MIDIPUTC 5 -static void MIDI_PlaySysex(Bit8u * sysex,Bitu len) { - Bit8u buf[SYSEX_SIZE*4];Bitu pos=0; - for (;len>0;len--) { - buf[pos++] = SEQ_MIDIPUTC; - buf[pos++] = *sysex++; - buf[pos++] = 0; //Device 0? - buf[pos++] = 0; +class MidiHandler_oss: public MidiHandler { +private: + int device; + Bit8u device_num; + bool isOpen; +public: + MidiHandler_oss() : isOpen(false),MidiHandler() {}; + char * GetName(void) { return "oss";}; + bool Open(const char * conf) { + char devname[512]; + if (conf && conf[0]) strncpy(devname,conf,512); + else strcpy(devname,"/dev/midi"); + char * devfind=(strrchr(devname,',')); + if (devfind) { + *devfind++=0; + device_num=atoi(devfind); + } else device_num=0; + if (isOpen) return false; + device=open(devname, O_WRONLY, 0); + if (device<0) return false; + return true; + }; + void Close(void) { + if (!isOpen) return; + if (device>0) close(device); + }; + void PlayMsg(Bit32u msg) { + Bit8u buf[128];Bitu pos=0; + Bitu len=MIDI_evt_len[msg & 0xff]; + for (;len>0;len--) { + buf[pos++] = SEQ_MIDIPUTC; + buf[pos++] = msg & 0xff; + buf[pos++] = device_num; + buf[pos++] = 0; + msg >>=8; + } + write(device,buf,pos); + }; + void PlaySysex(Bit8u * sysex,Bitu len) { + Bit8u buf[SYSEX_SIZE*4];Bitu pos=0; + for (;len>0;len--) { + buf[pos++] = SEQ_MIDIPUTC; + buf[pos++] = *sysex++; + buf[pos++] = device_num; + buf[pos++] = 0; + } + write(device,buf,pos); } - write(m_device,buf,pos); -} +}; + +MidiHandler_oss Midi_oss; + -static void MIDI_PlayMsg(Bit32u msg) { - Bit8u buf[128];Bitu pos=0; - - Bitu len=MIDI_evt_len[msg & 0xff]; - for (;len>0;len--) { - buf[pos++] = SEQ_MIDIPUTC; - buf[pos++] = msg & 0xff; - buf[pos++] = 0; //Device 0? - buf[pos++] = 0; - msg >>=8; - } - write(m_device,buf,pos); -} - -static void MIDI_ShutDown(void) { - if (m_device>0) close(m_device); -} - -static bool MIDI_StartUp(void) { - m_device=open("/dev/midi", O_WRONLY, 0); - if (m_device<0) return false; - return true; -} diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index 5f6e1d1d..54d33179 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -19,46 +19,55 @@ #include #include -static HMIDIOUT m_out; -static MIDIHDR m_hdr; -static HANDLE m_event; +class MidiHandler_win32: public MidiHandler { +private: + HMIDIOUT m_out; + MIDIHDR m_hdr; + HANDLE m_event; + bool isOpen; +public: + MidiHandler_win32() : isOpen(false),MidiHandler() {}; + char * GetName(void) { return "win32";}; + bool Open(const char * conf) { + if (isOpen) return false; + m_event = CreateEvent (NULL, true, true, NULL); + MMRESULT res = midiOutOpen(&m_out, MIDI_MAPPER, (DWORD)m_event, 0, CALLBACK_EVENT); + if (res != MMSYSERR_NOERROR) return false; + isOpen=true; + return true; + }; + void Close(void) { + if (!isOpen) return; + isOpen=false; + midiOutClose(m_out); + CloseHandle (m_event); + }; + void PlayMsg(Bit32u msg) { + midiOutShortMsg(m_out, msg); + }; + void PlaySysex(Bit8u * sysex,Bitu len) { + if (WaitForSingleObject (m_event, 2000) == WAIT_TIMEOUT) { + LOG(LOG_MISC|LOG_ERROR,"Can't send midi message"); + return; + } + midiOutUnprepareHeader (m_out, &m_hdr, sizeof (m_hdr)); + + m_hdr.lpData = (char *) sysex; + m_hdr.dwBufferLength = len ; + m_hdr.dwBytesRecorded = len ; + m_hdr.dwUser = 0; - -static void MIDI_PlaySysex(Bit8u * sysex,Bitu len) { - - if (WaitForSingleObject (m_event, 2000) == WAIT_TIMEOUT) { - LOG(LOG_MISC|LOG_ERROR,"Can't send midi message"); - return; - } - midiOutUnprepareHeader (m_out, &m_hdr, sizeof (m_hdr)); - - m_hdr.lpData = (char *) sysex; - m_hdr.dwBufferLength = len ; - m_hdr.dwBytesRecorded = len ; - m_hdr.dwUser = 0; - - MMRESULT result = midiOutPrepareHeader (m_out, &m_hdr, sizeof (m_hdr)); - if (result != MMSYSERR_NOERROR) return; - ResetEvent (m_event); - result = midiOutLongMsg (m_out,&m_hdr,sizeof(m_hdr)); - if (result != MMSYSERR_NOERROR) { - SetEvent (m_event); - return; + MMRESULT result = midiOutPrepareHeader (m_out, &m_hdr, sizeof (m_hdr)); + if (result != MMSYSERR_NOERROR) return; + ResetEvent (m_event); + result = midiOutLongMsg (m_out,&m_hdr,sizeof(m_hdr)); + if (result != MMSYSERR_NOERROR) { + SetEvent (m_event); + return; + } } -} - -static void MIDI_PlayMsg(Bit32u msg) { - MMRESULT ret=midiOutShortMsg(m_out, msg); -} - - - -static bool MIDI_StartUp(void) { - m_event = CreateEvent (NULL, true, true, NULL); - MMRESULT res = midiOutOpen(&m_out, MIDI_MAPPER, (DWORD)m_event, 0, CALLBACK_EVENT); - if (res != MMSYSERR_NOERROR) return false; - return true; -} +}; +MidiHandler_win32 Midi_win32; From dc80ccc6225e4b16a703c70e046d5304cd94a9ba Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 27 Mar 2003 20:20:31 +0000 Subject: [PATCH 0730/4131] Settings for midi and moved mpu401 settings under midi section too. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@809 --- src/dosbox.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 718d1070..452de4a4 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -195,6 +195,11 @@ void DOSBOX_Init(void) { secprop->Add_string("wavedir","waves"); secprop=control->AddSection_prop("midi",&MIDI_Init); + secprop->AddInitFunction(&MPU401_Init); + secprop->Add_bool("mpu401",true); + secprop->Add_string("device","default"); + secprop->Add_string("config",""); + #if C_DEBUG secprop=control->AddSection_prop("debug",&DEBUG_Init); #endif @@ -211,8 +216,6 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&CMS_Init); secprop->Add_bool("cms",false); secprop->Add_int("cmsrate",22050); - secprop->AddInitFunction(&MPU401_Init); - secprop->Add_bool("mpu401",true); secprop=control->AddSection_prop("gus",&GUS_Init); From 90752ae2495bcd69d80074d894d984b3a5e53c43 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 27 Mar 2003 21:13:58 +0000 Subject: [PATCH 0731/4131] removed cdrom_ioctl.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@810 --- src/dos/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/Makefile.am b/src/dos/Makefile.am index 00ae5fa2..e2d02436 100644 --- a/src/dos/Makefile.am +++ b/src/dos/Makefile.am @@ -5,4 +5,4 @@ EXTRA_DIST = Ntddcdrm.h Ntddscsi.h Ntddstor.h scsidefs.h wnaspi32.h libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioctl.cpp dos_memory.cpp \ dos_misc.cpp dos_classes.cpp dos_programs.cpp dos_tables.cpp \ drives.cpp drives.h drive_virtual.cpp drive_local.cpp \ - dev_con.h drive_cache.cpp cdrom.h cdrom.cpp cdrom_ioctl.cpp dos_mscdex.cpp + dev_con.h drive_cache.cpp cdrom.h cdrom.cpp dos_mscdex.cpp From e78dc0067d3bb35686e7958175d07389db9392b2 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 27 Mar 2003 21:15:04 +0000 Subject: [PATCH 0732/4131] new mount switches -cd : show list of cdrom drives -usecd [x]: force usage of cdrom drive x Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@811 --- src/dos/dos_programs.cpp | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index be6cbe90..d47f90b0 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -19,16 +19,17 @@ #include #include #include +#include "sdl.h" #include "programs.h" #include "support.h" #include "drives.h" #include "cross.h" #include "regs.h" #include "callback.h" +#include "cdrom.h" #include "../shell/shell_inc.h" -void MSCDEX_SetUseASPI(bool use); -bool MSCDEX_GetUseASPI(void); +void MSCDEX_SetCDInterface(int intNr, int forceCD); class MOUNT : public Program { public: @@ -36,6 +37,16 @@ public: { DOS_Drive * newdrive;char drive; + // Show list of cdroms + if (cmd->FindExist("-cd",false)) { + int num = SDL_CDNumDrives(); + WriteOut("CDROMs found: %d\n",num); + for (int i=0; iGetCount()) { @@ -100,10 +111,13 @@ public: if (temp_line[temp_line.size()-1]!=CROSS_FILESPLIT) temp_line+=CROSS_FILESPLIT; Bit8u bit8size=(Bit8u) sizes[1]; if (type=="cdrom") { - bool oldaspi = MSCDEX_GetUseASPI();; + int num = -1; + cmd->FindInt("-usecd",num,true); int error; - if (cmd->FindExist("-aspi",false)) MSCDEX_SetUseASPI(true); - newdrive = new cdromDrive(drive,temp_line.c_str(),sizes[0],bit8size,sizes[2],sizes[3],mediaid,error); + if (cmd->FindExist("-aspi",false)) MSCDEX_SetCDInterface(CDROM_USE_ASPI, num); else + if (cmd->FindExist("-ioctl",false)) MSCDEX_SetCDInterface(CDROM_USE_IOCTL, num); + else MSCDEX_SetCDInterface(CDROM_USE_SDL, num); + newdrive = new cdromDrive(drive,temp_line.c_str(),sizes[0],bit8size,sizes[2],0,mediaid,error); // Check Mscdex, if it worked out... switch (error) { case 0 : WriteOut(MSG_Get("MSCDEX_SUCCESS")); break; @@ -114,8 +128,6 @@ public: case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break; default : WriteOut(MSG_Get("MSCDEX_UNKNOWN_ERROR")); break; }; - MSCDEX_SetUseASPI(oldaspi); - } else { newdrive=new localDrive(temp_line.c_str(),sizes[0],bit8size,sizes[2],sizes[3],mediaid); } @@ -262,7 +274,7 @@ void DOS_SetupPrograms(void) { MSG_Add("MSCDEX_SUCCESS","MSCDEX installed.\n"); MSG_Add("MSCDEX_ERROR_MULTIPLE_CDROMS","MSCDEX: Failure: Drive-letters of multiple CDRom-drives have to be continuous.\n"); MSG_Add("MSCDEX_ERROR_NOT_SUPPORTED","MSCDEX: Failure: Not yet supported.\n"); - MSG_Add("MSCDEX_ERROR_PATH","MSCDEX: Failure: Path not valid (WIN32: Check if ASPI Driver is installed).\n"); + MSG_Add("MSCDEX_ERROR_PATH","MSCDEX: Failure: Path not valid.\n"); MSG_Add("MSCDEX_TOO_MANY_DRIVES","MSCDEX: Failure: Too many CDRom-drives (max: 5). MSCDEX Installation failed.\n"); MSG_Add("MSCDEX_LIMITED_SUPPORT","MSCDEX: Mounted subdirectory: limited support.\n"); MSG_Add("MSCDEX_UNKNOWN_ERROR","MSCDEX: Failure: Unknown error.\n"); From 57d5d97852ce8e28f1017ce63e17deda90c674e9 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 27 Mar 2003 21:15:53 +0000 Subject: [PATCH 0733/4131] default cdrom interface now sdl Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@812 --- src/dos/cdrom.cpp | 851 +++++++---------------------------------- src/dos/cdrom.h | 79 ++-- src/dos/dos_mscdex.cpp | 38 +- 3 files changed, 196 insertions(+), 772 deletions(-) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index b84f1510..a94cfd6f 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -16,741 +16,172 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// ASPI support for WIN32 CDROM -#ifdef WIN32 +// ****************************************************** +// SDL CDROM +// ****************************************************** -#include -#include +#include "sdl.h" +#include "support.h" #include "cdrom.h" -#include "scsidefs.h" // Aspi stuff -#include "dosbox.h" - -CDROM_Interface_Aspi::CDROM_Interface_Aspi(void) +CDROM_Interface_SDL::CDROM_Interface_SDL(void) { - hASPI = NULL; - hEvent = NULL; - pGetASPI32SupportInfo = NULL; - pSendASPI32Command = NULL; - memset(&oldLeadOut,0,sizeof(oldLeadOut)); + driveID = 0; + oldLeadOut = 0; + cd = 0; }; -CDROM_Interface_Aspi::~CDROM_Interface_Aspi(void) +CDROM_Interface_SDL::~CDROM_Interface_SDL(void) { - // Stop Audio StopAudio(); - - pGetASPI32SupportInfo = NULL; // clear funcs - pSendASPI32Command = NULL; - - if (hASPI) { // free aspi - FreeLibrary(hASPI); - hASPI=NULL; - } + SDL_CDClose(cd); + cd = 0; }; -bool GetRegistryValue(HKEY& hKey,char* valueName, char* buffer, ULONG bufferSize) -// hKey has to be open -{ - // Read subkey - ULONG valType; - ULONG result; - result = RegQueryValueEx(hKey,valueName,NULL,&valType,(unsigned char*)&buffer[0],&bufferSize); - return (result == ERROR_SUCCESS); -}; +bool CDROM_Interface_SDL::SetDevice (char* path, int forceCD) +{ + char buffer[512]; + strcpy(buffer,path); + upcase(buffer); -BYTE CDROM_Interface_Aspi::GetHostAdapter(char* hardwareID) -{ - SRB_HAInquiry sh; - SRB_GDEVBlock sd; - DWORD d = pGetASPI32SupportInfo(); - int cnt = LOBYTE(LOWORD(d)); - int i,j,k,max; - - for(i=0; i4)) { - if (GetDriveType(path)==DRIVE_CDROM) { - // WIN XP/NT/2000 - int iDA,iDT,iDL; - letter = path[0]; - HANDLE hF = OpenIOCTLFile(letter,FALSE); - GetIOCTLAdapter(hF,&iDA,&iDT,&iDL); - CloseHandle(hF); - // Set SCSI IDs - haId = iDA; - target = iDT; - lun = iDL; - return true; - } - } else { - // win 95/98/ME have to scan the registry... - // lets hope the layout is always the same... i dunno... - char key[2048]; - HKEY hKeyBase; - bool found = false; - strcpy(key,"ENUM\\SCSI"); - if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,key,0,KEY_READ,&hKeyBase)==ERROR_SUCCESS) { - found = ScanRegistry(hKeyBase); - }; - RegCloseKey(hKeyBase); - return found; - } - return false; -}; - -bool CDROM_Interface_Aspi::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut) -{ - TOC toc; - if (GetTOC((LPTOC)&toc) == SS_COMP) { - stTrack = toc.cFirstTrack; - endTrack = toc.cLastTrack; - leadOut.min = (unsigned char)(toc.tracks[endTrack].lAddr >> 8) &0xFF; - leadOut.sec = (unsigned char)(toc.tracks[endTrack].lAddr >> 16) &0xFF; - leadOut.fr = (unsigned char)(toc.tracks[endTrack].lAddr >> 24) &0xFF; + int num = SDL_CDNumDrives(); + if ((forceCD>=0) && (forceCD> 8) &0xFF; - start.sec = (unsigned char)(toc.tracks[track-1].lAddr >> 16) &0xFF; - start.fr = (unsigned char)(toc.tracks[track-1].lAddr >> 24) &0xFF; - attr = toc.tracks[track-1].cAdrCtrl; - return true; - }; - return false; -}; - -HANDLE CDROM_Interface_Aspi::OpenIOCTLFile(char cLetter,BOOL bAsync) -{ - HANDLE hF; - char szFName[16]; - OSVERSIONINFO ov; - DWORD dwFlags; - DWORD dwIOCTLAttr; -// if(bAsync) dwIOCTLAttr=FILE_FLAG_OVERLAPPED; -// else - dwIOCTLAttr=0; - - memset(&ov,0,sizeof(OSVERSIONINFO)); - ov.dwOSVersionInfoSize=sizeof(OSVERSIONINFO); - GetVersionEx(&ov); - - if ((ov.dwPlatformId==VER_PLATFORM_WIN32_NT) && (ov.dwMajorVersion>4)) - dwFlags = GENERIC_READ|GENERIC_WRITE; // add gen write on W2k/XP - else - dwFlags = GENERIC_READ; - - wsprintf(szFName, "\\\\.\\%c:",cLetter); - - hF=CreateFile(szFName,dwFlags,FILE_SHARE_READ, // open drive - NULL,OPEN_EXISTING,dwIOCTLAttr,NULL); - - if (hF==INVALID_HANDLE_VALUE) { - dwFlags^=GENERIC_WRITE; // mmm... no success - hF=CreateFile(szFName,dwFlags,FILE_SHARE_READ, // -> open drive again - NULL,OPEN_EXISTING,dwIOCTLAttr,NULL); - if (hF==INVALID_HANDLE_VALUE) return NULL; - } - return hF; -} - -void CDROM_Interface_Aspi::GetIOCTLAdapter(HANDLE hF,int * iDA,int * iDT,int * iDL) -{ - char szBuf[1024]; - PSCSI_ADDRESS pSA; - DWORD dwRet; - - *iDA=*iDT=*iDL=-1; - if(hF==NULL) return; - - memset(szBuf,0,1024); - - pSA=(PSCSI_ADDRESS)szBuf; - pSA->Length=sizeof(SCSI_ADDRESS); - - if(!DeviceIoControl(hF,IOCTL_SCSI_GET_ADDRESS,NULL, - 0,pSA,sizeof(SCSI_ADDRESS), - &dwRet,NULL)) - return; - - *iDA = pSA->PortNumber; - *iDT = pSA->TargetId; - *iDL = pSA->Lun; -} - -DWORD CDROM_Interface_Aspi::GetTOC(LPTOC toc) -{ - SRB_ExecSCSICmd s;DWORD dwStatus; - - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - memset(&s,0,sizeof(s)); - - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = sizeof(*toc); - s.SRB_BufPointer = (BYTE FAR *)toc; - s.SRB_SenseLen = SENSE_LEN; - s.SRB_CDBLen = 0x0A; - s.SRB_PostProc = (LPVOID)hEvent; - s.CDBByte[0] = SCSI_READ_TOC; - s.CDBByte[1] = 0x02; // 0x02 for MSF - s.CDBByte[7] = 0x03; - s.CDBByte[8] = 0x24; - - ResetEvent(hEvent); - dwStatus=pSendASPI32Command((LPSRB)&s); - - if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,30000); - - CloseHandle(hEvent); - - return (s.SRB_Status==SS_COMP); -} - -bool CDROM_Interface_Aspi::PlayAudioSector(unsigned long start,unsigned long len) -{ - SRB_ExecSCSICmd s;DWORD dwStatus; - - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - memset(&s,0,sizeof(s)); - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = 0; - s.SRB_BufPointer = 0; - s.SRB_SenseLen = SENSE_LEN; - s.SRB_CDBLen = 12; - s.SRB_PostProc = (LPVOID)hEvent; - - s.CDBByte[0] = SCSI_PLAYAUD_12; - s.CDBByte[1] = lun << 5; - s.CDBByte[2] = (unsigned char)((start >> 24) & 0xFF); - s.CDBByte[3] = (unsigned char)((start >> 16) & 0xFF); - s.CDBByte[4] = (unsigned char)((start >> 8) & 0xFF); - s.CDBByte[5] = (unsigned char)((start & 0xFF)); - s.CDBByte[6] = (unsigned char)((len >> 24) & 0xFF); - s.CDBByte[7] = (unsigned char)((len >> 16) & 0xFF); - s.CDBByte[8] = (unsigned char)((len >> 8) & 0xFF); - s.CDBByte[9] = (unsigned char)(len & 0xFF); - - ResetEvent(hEvent); - - dwStatus = pSendASPI32Command((LPSRB)&s); - - if(dwStatus==SS_PENDING) WaitForSingleObject(hEvent,10000); - - CloseHandle(hEvent); - - return s.SRB_Status==SS_COMP; -} - -bool CDROM_Interface_Aspi::StopAudio(void) -{ - return PauseAudio(false); -}; - -bool CDROM_Interface_Aspi::PauseAudio(bool resume) -{ - SRB_ExecSCSICmd s;DWORD dwStatus; - - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - memset(&s,0,sizeof(s)); - - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = 0x00; - s.SRB_SenseLen = SENSE_LEN; - s.SRB_CDBLen = 0x0A; - s.SRB_PostProc = (LPVOID)hEvent; - s.CDBByte[0] = 0x4B; - s.CDBByte[8] = (unsigned char)resume; // Pause - - ResetEvent(hEvent); - dwStatus=pSendASPI32Command((LPSRB)&s); - - if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,30000); - - CloseHandle(hEvent); - - return (s.SRB_Status==SS_COMP); -}; - -bool CDROM_Interface_Aspi::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) -{ - SUB_Q_CURRENT_POSITION pos; - SRB_ExecSCSICmd s;DWORD dwStatus; - - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - memset(&s,0,sizeof(s)); - - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_SenseLen = SENSE_LEN; - - s.SRB_BufLen = sizeof(pos); - s.SRB_BufPointer = (BYTE FAR *)&pos; - s.SRB_CDBLen = 10; - s.SRB_PostProc = (LPVOID)hEvent; - - s.CDBByte[0] = SCSI_SUBCHANNEL; - s.CDBByte[1] = (lun<<5)|2; // lun & msf - s.CDBByte[2] = 0x40; // subq - s.CDBByte[3] = 0x01; // curr pos info - s.CDBByte[6] = 0; // track number (only in isrc mode, ignored) - s.CDBByte[7] = 0; // alloc len - s.CDBByte[8] = sizeof(pos); - - ResetEvent(hEvent); - - dwStatus = pSendASPI32Command((LPSRB)&s); - - if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); - - CloseHandle(hEvent); - - if (s.SRB_Status!=SS_COMP) return false; - - attr = (pos.ADR<<4) | pos.Control; - track = pos.TrackNumber; - index = pos.IndexNumber; - absPos.min = pos.AbsoluteAddress[1]; - absPos.sec = pos.AbsoluteAddress[2]; - absPos.fr = pos.AbsoluteAddress[3]; - relPos.min = pos.TrackRelativeAddress[1]; - relPos.sec = pos.TrackRelativeAddress[2]; - relPos.fr = pos.TrackRelativeAddress[3]; - - return true; -}; - -bool CDROM_Interface_Aspi::GetUPC(unsigned char& attr, char* upcdata) -{ - SUB_Q_MEDIA_CATALOG_NUMBER upc; - SRB_ExecSCSICmd s;DWORD dwStatus; - - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - memset(&s,0,sizeof(s)); - - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_SenseLen = SENSE_LEN; - - s.SRB_BufLen = sizeof(upc); - s.SRB_BufPointer = (BYTE FAR *)&upc; - s.SRB_CDBLen = 10; - s.SRB_PostProc = (LPVOID)hEvent; - - s.CDBByte[0] = SCSI_SUBCHANNEL; - s.CDBByte[1] = (lun<<5)|2; // lun & msf - s.CDBByte[2] = 0x40; // subq - s.CDBByte[3] = 0x02; // get upc - s.CDBByte[6] = 0; // track number (only in isrc mode, ignored) - s.CDBByte[7] = 0; // alloc len - s.CDBByte[8] = sizeof(upc); - - ResetEvent(hEvent); - - dwStatus = pSendASPI32Command((LPSRB)&s); - - if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); - - CloseHandle(hEvent); - - if (s.SRB_Status!=SS_COMP) return false; - -// attr = (upc.ADR<<4) | upc.Control; - attr = 0; - int pos = 0; - // Convert to mscdex format -// for (int i=0; i<6; i++) upcdata[i] = (upc.MediaCatalog[pos++]<<4)+(upc.MediaCatalog[pos++]&0x0F); -// upcdata[6] = (upc.MediaCatalog[pos++]<<4); - for (int i=0; i<7; i++) upcdata[i] = upc.MediaCatalog[i]; - - return true; -}; - -bool CDROM_Interface_Aspi::GetAudioStatus(bool& playing, bool& pause) -{ - playing = pause = false; - - SUB_Q_HEADER sub; - SRB_ExecSCSICmd s;DWORD dwStatus; - - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - memset(&s,0,sizeof(s)); - - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_SenseLen = SENSE_LEN; - - s.SRB_BufLen = sizeof(sub); - s.SRB_BufPointer = (BYTE FAR *)⊂ - s.SRB_CDBLen = 10; - s.SRB_PostProc = (LPVOID)hEvent; - - s.CDBByte[0] = SCSI_SUBCHANNEL; - s.CDBByte[1] = (lun<<5)|2; // lun & msf - s.CDBByte[2] = 0x00; // no subq - s.CDBByte[3] = 0x00; // dont care - s.CDBByte[6] = 0; // track number (only in isrc mode, ignored) - s.CDBByte[7] = 0; // alloc len - s.CDBByte[8] = sizeof(sub); - - ResetEvent(hEvent); - - dwStatus = pSendASPI32Command((LPSRB)&s); - - if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); - - CloseHandle(hEvent); - - if (s.SRB_Status!=SS_COMP) return false; - - playing = (sub.AudioStatus==0x11); - pause = (sub.AudioStatus==0x12); - - return true; -}; - -bool CDROM_Interface_Aspi::LoadUnloadMedia(bool unload) -{ - SRB_ExecSCSICmd s;DWORD dwStatus; - - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - memset(&s,0,sizeof(s)); - - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_SenseLen = SENSE_LEN; - - s.SRB_BufLen = 0; - s.SRB_BufPointer = 0; - s.SRB_CDBLen = 14; - s.SRB_PostProc = (LPVOID)hEvent; - - s.CDBByte[0] = SCSI_LOAD_UN; - s.CDBByte[1] = (lun<<5)|1; // lun & immediate - s.CDBByte[4] = (unload ? 0x02:0x03); // unload/load media - - ResetEvent(hEvent); - - dwStatus = pSendASPI32Command((LPSRB)&s); - - if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); - - CloseHandle(hEvent); - - if (s.SRB_Status!=SS_COMP) return false; - - return true; -}; - -bool CDROM_Interface_Aspi::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) -{ - // Seems not possible to get this values using ioctl... - int track1,track2; - TMSF leadOut; - // If we can read, there's a media - mediaPresent = GetAudioTracks(track1, track2, leadOut), - trayOpen = !mediaPresent; - mediaChanged = (oldLeadOut.min!=leadOut.min) || (oldLeadOut.sec!=leadOut.sec) || (oldLeadOut.fr!=leadOut.fr); - // Save old values - oldLeadOut.min = leadOut.min; - oldLeadOut.sec = leadOut.sec; - oldLeadOut.fr = leadOut.fr; - // always success - return true; -}; - -bool CDROM_Interface_Aspi::ReadSectors(void* buffer, bool raw, unsigned long sector, unsigned long num) -{ - SRB_ExecSCSICmd s;DWORD dwStatus; - - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - memset(&s,0,sizeof(s)); - - // FIXME : Is there a method to get cooked sectors with aspi ??? - // all combination i tried were failing. - // so we have to allocate extra mem and copy data to buffer if in cooked mode - char* inPtr = (char*)buffer; - if (!raw) inPtr = new char[num*2352]; - if (!inPtr) return false; - - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_SenseLen = SENSE_LEN; - - s.SRB_BufLen = 2352*num; //num*(raw?2352:2048); - s.SRB_BufPointer = (BYTE FAR*)inPtr; - s.SRB_CDBLen = 12; - s.SRB_PostProc = (LPVOID)hEvent; - - s.CDBByte[0] = 0xBE; - s.CDBByte[2] = (unsigned char)((sector >> 24) & 0xFF); - s.CDBByte[3] = (unsigned char)((sector >> 16) & 0xFF); - s.CDBByte[4] = (unsigned char)((sector >> 8) & 0xFF); - s.CDBByte[5] = (unsigned char)((sector & 0xFF)); - s.CDBByte[6] = (unsigned char)((num >> 16) & 0xFF); - s.CDBByte[7] = (unsigned char)((num >> 8) & 0xFF); - s.CDBByte[8] = (unsigned char) (num & 0xFF); - s.CDBByte[9] = (raw?0xF0:0x10); - - ResetEvent(hEvent); - - dwStatus = pSendASPI32Command((LPSRB)&s); - - if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); - - CloseHandle(hEvent); - - if (s.SRB_Status!=SS_COMP) { - if (!raw) delete[] inPtr; - return false; - } - - if (!raw) { - // copy user data to buffer - char* source = inPtr; - source+=16; // jump 16 bytes - char* outPtr = (char*)buffer; - for (unsigned long i=0; istatus)) { + stTrack = 1; + end = cd->numtracks; + FRAMES_TO_MSF(cd->track[cd->numtracks].offset,&leadOut.min,&leadOut.sec,&leadOut.fr); + } + return CD_INDRIVE(cd->status); +}; + +bool CDROM_Interface_SDL::GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr) +{ + SDL_CDStatus(cd); + if (CD_INDRIVE(cd->status)) { + FRAMES_TO_MSF(cd->track[track-1].offset+150,&start.min,&start.sec,&start.fr); + attr = cd->track[track-1].type; + } + return CD_INDRIVE(cd->status); +}; + +bool CDROM_Interface_SDL::GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) +{ + SDL_CDStatus(cd); + if (CD_INDRIVE(cd->status)) { + track = cd->cur_track; + index = cd->cur_track; + attr = cd->track[track].type; + FRAMES_TO_MSF(cd->cur_frame,&relPos.min,&relPos.sec,&relPos.fr); + FRAMES_TO_MSF(cd->cur_frame+cd->track[track].offset,&absPos.min,&absPos.sec,&absPos.fr); + } + return CD_INDRIVE(cd->status); +}; + +bool CDROM_Interface_SDL::GetAudioStatus (bool& playing, bool& pause) +{ + SDL_CDStatus(cd); + if (CD_INDRIVE(cd->status)) { + playing = (cd->status==CD_PLAYING); + pause = (cd->status==CD_PAUSED); + } + return CD_INDRIVE(cd->status); +}; + +bool CDROM_Interface_SDL::GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) +{ + SDL_CDStatus(cd); + mediaPresent = (cd->status!=CD_TRAYEMPTY) && (cd->status!=CD_ERROR); + mediaChanged = (oldLeadOut!=cd->track[cd->numtracks].offset); + trayOpen = !mediaPresent; + oldLeadOut = cd->track[cd->numtracks].offset; + if (mediaChanged) SDL_CDStatus(cd); return true; }; -int CDROM_GetMountType(char* path) +bool CDROM_Interface_SDL::PlayAudioSector (unsigned long start,unsigned long len) +{ + // Has to be there, otherwise wrong cd status report (dunno why, sdl bug ?) + SDL_CDClose(cd); + cd = SDL_CDOpen(driveID); + bool success = (SDL_CDPlay(cd,start,len)==0); + return success; +}; + +bool CDROM_Interface_SDL::PauseAudio (bool resume) +{ + bool success; + if (resume) success = (SDL_CDResume(cd)==0); + else success = (SDL_CDPause (cd)==0); + return success; +}; + +bool CDROM_Interface_SDL::StopAudio (void) +{ + // Has to be there, otherwise wrong cd status report (dunno why, sdl bug ?) + SDL_CDClose(cd); + cd = SDL_CDOpen(driveID); + bool success = (SDL_CDStop(cd)==0); + return success; +}; + +bool CDROM_Interface_SDL::LoadUnloadMedia(bool unload) +{ + bool success = (SDL_CDEject(cd)==0); + return success; +}; + +int CDROM_GetMountType(char* path, int forceCD) // 0 - physical CDROM // 1 - Iso file // 2 - subdirectory { // 1. Smells like a real cdrom - if ((strlen(path)<=3) && (path[2]=='\\') && (strchr(path,'\\')==strrchr(path,'\\')) && (GetDriveType(path)==DRIVE_CDROM)) return 0; - // 2. Iso file ? - // FIXME : How to detect them ? - // return 1; - // 3. bah, ordinary directory + // if ((strlen(path)<=3) && (path[2]=='\\') && (strchr(path,'\\')==strrchr(path,'\\')) && (GetDriveType(path)==DRIVE_CDROM)) return 0; + + const char* cdName; + char buffer[512]; + strcpy(buffer,path); +#if defined (WIN32) + upcase(buffer); +#endif + + int num = SDL_CDNumDrives(); + // If cd drive is forced then check if its in range and return 0 + if ((forceCD>=0) && (forceCD +#include "sdl.h" #define RAW_SECTOR_SIZE 2352 #define COOKED_SECTOR_SIZE 2048 +enum { CDROM_USE_SDL, CDROM_USE_ASPI, CDROM_USE_IOCTL }; + typedef struct SMSF { unsigned char min; unsigned char sec; unsigned char fr; } TMSF; -extern int CDROM_GetMountType(char* path); +extern int CDROM_GetMountType(char* path, int force); class CDROM_Interface { @@ -23,7 +26,7 @@ public: // CDROM_Interface (void); virtual ~CDROM_Interface (void) {}; - virtual bool SetDevice (char* path) = 0; + virtual bool SetDevice (char* path, int forceCD) = 0; virtual bool GetUPC (unsigned char& attr, char* upc) = 0; @@ -42,10 +45,38 @@ public: virtual bool LoadUnloadMedia (bool unload) = 0; }; +class CDROM_Interface_SDL : public CDROM_Interface +{ +public: + CDROM_Interface_SDL (void); + ~CDROM_Interface_SDL (void); + + bool SetDevice (char* path, int forceCD); + bool GetUPC (unsigned char& attr, char* upc) { attr = 0; strcpy(upc,"UPC"); return true; }; + bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); + bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr); + bool GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); + bool GetAudioStatus (bool& playing, bool& pause); + bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); + bool PlayAudioSector (unsigned long start,unsigned long len); + bool PauseAudio (bool resume); + bool StopAudio (void); + bool ReadSectors (void* buffer, bool raw, unsigned long sector, unsigned long num) { return true; }; + bool LoadUnloadMedia (bool unload); + +private: + bool Open (void); + void Close (void); + + SDL_CD* cd; + int driveID; + Uint32 oldLeadOut; +}; + class CDROM_Interface_Fake : public CDROM_Interface { public: - bool SetDevice (char* path) { return true; }; + bool SetDevice (char* path, int forceCD) { return true; }; bool GetUPC (unsigned char& attr, char* upc) { attr = 0; strcpy(upc,"UPC"); return true; }; bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr); @@ -59,7 +90,6 @@ public: bool LoadUnloadMedia (bool unload) { return true; }; }; - #if defined (WIN32) /* Win 32 */ #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers @@ -73,7 +103,7 @@ public: CDROM_Interface_Aspi (void); ~CDROM_Interface_Aspi (void); - bool SetDevice (char* path); + bool SetDevice (char* path, int forceCD); bool GetUPC (unsigned char& attr, char* upc); @@ -120,7 +150,7 @@ public: CDROM_Interface_Ioctl (void); ~CDROM_Interface_Ioctl (void); - bool SetDevice (char* path); + bool SetDevice (char* path, int forceCD); bool GetUPC (unsigned char& attr, char* upc); @@ -148,41 +178,6 @@ private: TMSF oldLeadOut; }; -#else /* Linux */ - -class CDROM_Interface_Linux : public CDROM_Interface -{ -public: - CDROM_Interface_Linux (void); - ~CDROM_Interface_Linux (void); - - bool SetDevice (char* path); - - bool GetUPC (unsigned char& attr, char* upc); - - bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); - bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr); - bool GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); - bool GetAudioStatus (bool& playing, bool& pause); - bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); - - bool PlayAudioSector (unsigned long start,unsigned long len); - bool PauseAudio (bool resume); - bool StopAudio (void); - - bool ReadSectors (void* buffer, bool raw, unsigned long sector, unsigned long num); - - bool LoadUnloadMedia (bool unload); - -private: - bool Open (void); - void Close (void); - - char pathname[64]; - int dhandle; - TMSF oldLeadOut; -}; - -#endif /* linux */ +#endif /* WIN 32 */ #endif /* __CDROM_INTERFACE__ */ diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index af48208b..e4e13832 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -38,11 +38,13 @@ #define REQUEST_STATUS_DONE 0x0100 #define REQUEST_STATUS_ERROR 0x8000 +// Use cdrom Interface +int useCdromInterface = CDROM_USE_SDL; +int forceCD = -1; + static Bitu MSCDEX_Strategy_Handler(void); static Bitu MSCDEX_Interrupt_Handler(void); -bool gUseASPI = false; - class DOS_DeviceHeader:public MemStruct { public: @@ -218,8 +220,9 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) // Set return type to ok int result = 0; // Get Mounttype and init needed cdrom interface - switch (CDROM_GetMountType(physicalPath)) { - case 0x00 : { // physical drive + switch (CDROM_GetMountType(physicalPath,forceCD)) { + case 0x00 : { + LOG(LOG_MISC,"MSCDEX: Mounting physical cdrom: %s" ,physicalPath); #if defined (WIN32) // Check OS OSVERSIONINFO osi; @@ -227,25 +230,24 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) GetVersionEx(&osi); if ((osi.dwPlatformId==VER_PLATFORM_WIN32_NT) && (osi.dwMajorVersion>4)) { // WIN NT/200/XP - if (gUseASPI) { + if (useCdromInterface==CDROM_USE_ASPI) { cdrom[numDrives] = new CDROM_Interface_Aspi(); LOG(LOG_MISC,"MSCDEX: ASPI Interface."); - } else { + break; + } else if (useCdromInterface==CDROM_USE_IOCTL) { cdrom[numDrives] = new CDROM_Interface_Ioctl(); LOG(LOG_MISC,"MSCDEX: IOCTL Interface."); + break; } } else { // Win 95/98/ME - always use ASPI cdrom[numDrives] = new CDROM_Interface_Aspi(); LOG(LOG_MISC,"MSCDEX: ASPI Interface."); + break; } - #elif __linux__ - cdrom[numDrives] = new CDROM_Interface_Linux(); - #else // No support on this machine... - cdrom[numDrives] = new CDROM_Interface_Fake(); - LOG(LOG_MISC|LOG_ERROR,"MSCDEX: No MSCDEX support on this machine."); #endif - LOG(LOG_MISC,"MSCDEX: Mounting physical cdrom: %s" ,physicalPath); + cdrom[numDrives] = new CDROM_Interface_SDL(); + LOG(LOG_MISC,"MSCDEX: SDL Interface."); } break; case 0x01 : // iso cdrom interface // FIXME: Not yet supported @@ -262,7 +264,7 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) default : // weird result return 6; }; - if (!cdrom[numDrives]->SetDevice(physicalPath)) return 3; + if (!cdrom[numDrives]->SetDevice(physicalPath,forceCD)) return 3; subUnit = numDrives; // Set drive DOS_DeviceHeader devHeader(PhysMake(rootDriverHeaderSeg,0)); @@ -816,14 +818,10 @@ bool MSCDEX_HasMediaChanged(Bit8u subUnit) return true; }; -void MSCDEX_SetUseASPI(bool use) +void MSCDEX_SetCDInterface(int intNr, int numCD) { - gUseASPI = use; -}; - -bool MSCDEX_GetUseASPI(void) -{ - return gUseASPI; + useCdromInterface = intNr; + forceCD = numCD; }; void MSCDEX_ShutDown(Section* sec) From a3bd5c5a7e3edb13981e3ac77f02ba66e5a17830 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 27 Mar 2003 21:16:33 +0000 Subject: [PATCH 0734/4131] cdrom interface aspi win32 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@813 --- src/dos/cdrom_aspi_win32.cpp | 733 +++++++++++++++++++++++++++++++++++ 1 file changed, 733 insertions(+) create mode 100644 src/dos/cdrom_aspi_win32.cpp diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp new file mode 100644 index 00000000..cd63999b --- /dev/null +++ b/src/dos/cdrom_aspi_win32.cpp @@ -0,0 +1,733 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#if defined (WIN32) + +#include "cdrom.h" +#include "scsidefs.h" // Aspi stuff +#include "dosbox.h" + +// ***************************************************************** +// Windows ASPI functions (should work for all WIN with ASPI layer) +// ***************************************************************** + +CDROM_Interface_Aspi::CDROM_Interface_Aspi(void) +{ + hASPI = NULL; + hEvent = NULL; + pGetASPI32SupportInfo = NULL; + pSendASPI32Command = NULL; + memset(&oldLeadOut,0,sizeof(oldLeadOut)); +}; + +CDROM_Interface_Aspi::~CDROM_Interface_Aspi(void) +{ + // Stop Audio + StopAudio(); + + pGetASPI32SupportInfo = NULL; // clear funcs + pSendASPI32Command = NULL; + + if (hASPI) { // free aspi + FreeLibrary(hASPI); + hASPI=NULL; + } +}; + +bool GetRegistryValue(HKEY& hKey,char* valueName, char* buffer, ULONG bufferSize) +// hKey has to be open +{ + // Read subkey + ULONG valType; + ULONG result; + result = RegQueryValueEx(hKey,valueName,NULL,&valType,(unsigned char*)&buffer[0],&bufferSize); + return (result == ERROR_SUCCESS); +}; + +BYTE CDROM_Interface_Aspi::GetHostAdapter(char* hardwareID) +{ + SRB_HAInquiry sh; + SRB_GDEVBlock sd; + DWORD d = pGetASPI32SupportInfo(); + int cnt = LOBYTE(LOWORD(d)); + int i,j,k,max; + + for(i=0; i4)) { + if (GetDriveType(path)==DRIVE_CDROM) { + // WIN XP/NT/2000 + int iDA,iDT,iDL; + letter = path[0]; + HANDLE hF = OpenIOCTLFile(letter,FALSE); + GetIOCTLAdapter(hF,&iDA,&iDT,&iDL); + CloseHandle(hF); + // Set SCSI IDs + haId = iDA; + target = iDT; + lun = iDL; + return true; + } + } else { + // win 95/98/ME have to scan the registry... + // lets hope the layout is always the same... i dunno... + char key[2048]; + HKEY hKeyBase; + bool found = false; + strcpy(key,"ENUM\\SCSI"); + if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,key,0,KEY_READ,&hKeyBase)==ERROR_SUCCESS) { + found = ScanRegistry(hKeyBase); + }; + RegCloseKey(hKeyBase); + return found; + } + return false; +}; + +bool CDROM_Interface_Aspi::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut) +{ + TOC toc; + if (GetTOC((LPTOC)&toc) == SS_COMP) { + stTrack = toc.cFirstTrack; + endTrack = toc.cLastTrack; + leadOut.min = (unsigned char)(toc.tracks[endTrack].lAddr >> 8) &0xFF; + leadOut.sec = (unsigned char)(toc.tracks[endTrack].lAddr >> 16) &0xFF; + leadOut.fr = (unsigned char)(toc.tracks[endTrack].lAddr >> 24) &0xFF; + return true; + } + return false; +}; + +bool CDROM_Interface_Aspi::GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr) +{ + TOC toc; + if (GetTOC((LPTOC)&toc) == SS_COMP) { + start.min = (unsigned char)(toc.tracks[track-1].lAddr >> 8) &0xFF; + start.sec = (unsigned char)(toc.tracks[track-1].lAddr >> 16) &0xFF; + start.fr = (unsigned char)(toc.tracks[track-1].lAddr >> 24) &0xFF; + attr = toc.tracks[track-1].cAdrCtrl; + return true; + }; + return false; +}; + +HANDLE CDROM_Interface_Aspi::OpenIOCTLFile(char cLetter,BOOL bAsync) +{ + HANDLE hF; + char szFName[16]; + OSVERSIONINFO ov; + DWORD dwFlags; + DWORD dwIOCTLAttr; +// if(bAsync) dwIOCTLAttr=FILE_FLAG_OVERLAPPED; +// else + dwIOCTLAttr=0; + + memset(&ov,0,sizeof(OSVERSIONINFO)); + ov.dwOSVersionInfoSize=sizeof(OSVERSIONINFO); + GetVersionEx(&ov); + + if ((ov.dwPlatformId==VER_PLATFORM_WIN32_NT) && (ov.dwMajorVersion>4)) + dwFlags = GENERIC_READ|GENERIC_WRITE; // add gen write on W2k/XP + else + dwFlags = GENERIC_READ; + + wsprintf(szFName, "\\\\.\\%c:",cLetter); + + hF=CreateFile(szFName,dwFlags,FILE_SHARE_READ, // open drive + NULL,OPEN_EXISTING,dwIOCTLAttr,NULL); + + if (hF==INVALID_HANDLE_VALUE) { + dwFlags^=GENERIC_WRITE; // mmm... no success + hF=CreateFile(szFName,dwFlags,FILE_SHARE_READ, // -> open drive again + NULL,OPEN_EXISTING,dwIOCTLAttr,NULL); + if (hF==INVALID_HANDLE_VALUE) return NULL; + } + return hF; +} + +void CDROM_Interface_Aspi::GetIOCTLAdapter(HANDLE hF,int * iDA,int * iDT,int * iDL) +{ + char szBuf[1024]; + PSCSI_ADDRESS pSA; + DWORD dwRet; + + *iDA=*iDT=*iDL=-1; + if(hF==NULL) return; + + memset(szBuf,0,1024); + + pSA=(PSCSI_ADDRESS)szBuf; + pSA->Length=sizeof(SCSI_ADDRESS); + + if(!DeviceIoControl(hF,IOCTL_SCSI_GET_ADDRESS,NULL, + 0,pSA,sizeof(SCSI_ADDRESS), + &dwRet,NULL)) + return; + + *iDA = pSA->PortNumber; + *iDT = pSA->TargetId; + *iDL = pSA->Lun; +} + +DWORD CDROM_Interface_Aspi::GetTOC(LPTOC toc) +{ + SRB_ExecSCSICmd s;DWORD dwStatus; + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + memset(&s,0,sizeof(s)); + + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = haId; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_BufLen = sizeof(*toc); + s.SRB_BufPointer = (BYTE FAR *)toc; + s.SRB_SenseLen = SENSE_LEN; + s.SRB_CDBLen = 0x0A; + s.SRB_PostProc = (LPVOID)hEvent; + s.CDBByte[0] = SCSI_READ_TOC; + s.CDBByte[1] = 0x02; // 0x02 for MSF + s.CDBByte[7] = 0x03; + s.CDBByte[8] = 0x24; + + ResetEvent(hEvent); + dwStatus=pSendASPI32Command((LPSRB)&s); + + if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,30000); + + CloseHandle(hEvent); + + return (s.SRB_Status==SS_COMP); +} + +bool CDROM_Interface_Aspi::PlayAudioSector(unsigned long start,unsigned long len) +{ + SRB_ExecSCSICmd s;DWORD dwStatus; + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + memset(&s,0,sizeof(s)); + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = haId; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_BufLen = 0; + s.SRB_BufPointer = 0; + s.SRB_SenseLen = SENSE_LEN; + s.SRB_CDBLen = 12; + s.SRB_PostProc = (LPVOID)hEvent; + + s.CDBByte[0] = SCSI_PLAYAUD_12; + s.CDBByte[1] = lun << 5; + s.CDBByte[2] = (unsigned char)((start >> 24) & 0xFF); + s.CDBByte[3] = (unsigned char)((start >> 16) & 0xFF); + s.CDBByte[4] = (unsigned char)((start >> 8) & 0xFF); + s.CDBByte[5] = (unsigned char)((start & 0xFF)); + s.CDBByte[6] = (unsigned char)((len >> 24) & 0xFF); + s.CDBByte[7] = (unsigned char)((len >> 16) & 0xFF); + s.CDBByte[8] = (unsigned char)((len >> 8) & 0xFF); + s.CDBByte[9] = (unsigned char)(len & 0xFF); + + ResetEvent(hEvent); + + dwStatus = pSendASPI32Command((LPSRB)&s); + + if(dwStatus==SS_PENDING) WaitForSingleObject(hEvent,10000); + + CloseHandle(hEvent); + + return s.SRB_Status==SS_COMP; +} + +bool CDROM_Interface_Aspi::StopAudio(void) +{ + return PauseAudio(false); +}; + +bool CDROM_Interface_Aspi::PauseAudio(bool resume) +{ + SRB_ExecSCSICmd s;DWORD dwStatus; + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + memset(&s,0,sizeof(s)); + + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = haId; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_BufLen = 0x00; + s.SRB_SenseLen = SENSE_LEN; + s.SRB_CDBLen = 0x0A; + s.SRB_PostProc = (LPVOID)hEvent; + s.CDBByte[0] = 0x4B; + s.CDBByte[8] = (unsigned char)resume; // Pause + + ResetEvent(hEvent); + dwStatus=pSendASPI32Command((LPSRB)&s); + + if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,30000); + + CloseHandle(hEvent); + + return (s.SRB_Status==SS_COMP); +}; + +bool CDROM_Interface_Aspi::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) +{ + SUB_Q_CURRENT_POSITION pos; + SRB_ExecSCSICmd s;DWORD dwStatus; + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + memset(&s,0,sizeof(s)); + + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = haId; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_SenseLen = SENSE_LEN; + + s.SRB_BufLen = sizeof(pos); + s.SRB_BufPointer = (BYTE FAR *)&pos; + s.SRB_CDBLen = 10; + s.SRB_PostProc = (LPVOID)hEvent; + + s.CDBByte[0] = SCSI_SUBCHANNEL; + s.CDBByte[1] = (lun<<5)|2; // lun & msf + s.CDBByte[2] = 0x40; // subq + s.CDBByte[3] = 0x01; // curr pos info + s.CDBByte[6] = 0; // track number (only in isrc mode, ignored) + s.CDBByte[7] = 0; // alloc len + s.CDBByte[8] = sizeof(pos); + + ResetEvent(hEvent); + + dwStatus = pSendASPI32Command((LPSRB)&s); + + if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); + + CloseHandle(hEvent); + + if (s.SRB_Status!=SS_COMP) return false; + + attr = (pos.ADR<<4) | pos.Control; + track = pos.TrackNumber; + index = pos.IndexNumber; + absPos.min = pos.AbsoluteAddress[1]; + absPos.sec = pos.AbsoluteAddress[2]; + absPos.fr = pos.AbsoluteAddress[3]; + relPos.min = pos.TrackRelativeAddress[1]; + relPos.sec = pos.TrackRelativeAddress[2]; + relPos.fr = pos.TrackRelativeAddress[3]; + + return true; +}; + +bool CDROM_Interface_Aspi::GetUPC(unsigned char& attr, char* upcdata) +{ + SUB_Q_MEDIA_CATALOG_NUMBER upc; + SRB_ExecSCSICmd s;DWORD dwStatus; + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + memset(&s,0,sizeof(s)); + + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = haId; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_SenseLen = SENSE_LEN; + + s.SRB_BufLen = sizeof(upc); + s.SRB_BufPointer = (BYTE FAR *)&upc; + s.SRB_CDBLen = 10; + s.SRB_PostProc = (LPVOID)hEvent; + + s.CDBByte[0] = SCSI_SUBCHANNEL; + s.CDBByte[1] = (lun<<5)|2; // lun & msf + s.CDBByte[2] = 0x40; // subq + s.CDBByte[3] = 0x02; // get upc + s.CDBByte[6] = 0; // track number (only in isrc mode, ignored) + s.CDBByte[7] = 0; // alloc len + s.CDBByte[8] = sizeof(upc); + + ResetEvent(hEvent); + + dwStatus = pSendASPI32Command((LPSRB)&s); + + if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); + + CloseHandle(hEvent); + + if (s.SRB_Status!=SS_COMP) return false; + +// attr = (upc.ADR<<4) | upc.Control; + attr = 0; + int pos = 0; + // Convert to mscdex format +// for (int i=0; i<6; i++) upcdata[i] = (upc.MediaCatalog[pos++]<<4)+(upc.MediaCatalog[pos++]&0x0F); +// upcdata[6] = (upc.MediaCatalog[pos++]<<4); + for (int i=0; i<7; i++) upcdata[i] = upc.MediaCatalog[i]; + + return true; +}; + +bool CDROM_Interface_Aspi::GetAudioStatus(bool& playing, bool& pause) +{ + playing = pause = false; + + SUB_Q_HEADER sub; + SRB_ExecSCSICmd s;DWORD dwStatus; + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + memset(&s,0,sizeof(s)); + + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = haId; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_SenseLen = SENSE_LEN; + + s.SRB_BufLen = sizeof(sub); + s.SRB_BufPointer = (BYTE FAR *)⊂ + s.SRB_CDBLen = 10; + s.SRB_PostProc = (LPVOID)hEvent; + + s.CDBByte[0] = SCSI_SUBCHANNEL; + s.CDBByte[1] = (lun<<5)|2; // lun & msf + s.CDBByte[2] = 0x00; // no subq + s.CDBByte[3] = 0x00; // dont care + s.CDBByte[6] = 0; // track number (only in isrc mode, ignored) + s.CDBByte[7] = 0; // alloc len + s.CDBByte[8] = sizeof(sub); + + ResetEvent(hEvent); + + dwStatus = pSendASPI32Command((LPSRB)&s); + + if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); + + CloseHandle(hEvent); + + if (s.SRB_Status!=SS_COMP) return false; + + playing = (sub.AudioStatus==0x11); + pause = (sub.AudioStatus==0x12); + + return true; +}; + +bool CDROM_Interface_Aspi::LoadUnloadMedia(bool unload) +{ + SRB_ExecSCSICmd s;DWORD dwStatus; + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + memset(&s,0,sizeof(s)); + + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = haId; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_SenseLen = SENSE_LEN; + + s.SRB_BufLen = 0; + s.SRB_BufPointer = 0; + s.SRB_CDBLen = 14; + s.SRB_PostProc = (LPVOID)hEvent; + + s.CDBByte[0] = SCSI_LOAD_UN; + s.CDBByte[1] = (lun<<5)|1; // lun & immediate + s.CDBByte[4] = (unload ? 0x02:0x03); // unload/load media + + ResetEvent(hEvent); + + dwStatus = pSendASPI32Command((LPSRB)&s); + + if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); + + CloseHandle(hEvent); + + if (s.SRB_Status!=SS_COMP) return false; + + return true; +}; + +bool CDROM_Interface_Aspi::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) +{ + // Seems not possible to get this values using ioctl... + int track1,track2; + TMSF leadOut; + // If we can read, there's a media + mediaPresent = GetAudioTracks(track1, track2, leadOut), + trayOpen = !mediaPresent; + mediaChanged = (oldLeadOut.min!=leadOut.min) || (oldLeadOut.sec!=leadOut.sec) || (oldLeadOut.fr!=leadOut.fr); + // Save old values + oldLeadOut.min = leadOut.min; + oldLeadOut.sec = leadOut.sec; + oldLeadOut.fr = leadOut.fr; + // always success + return true; +}; + +bool CDROM_Interface_Aspi::ReadSectors(void* buffer, bool raw, unsigned long sector, unsigned long num) +{ + SRB_ExecSCSICmd s;DWORD dwStatus; + + hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + memset(&s,0,sizeof(s)); + + // FIXME : Is there a method to get cooked sectors with aspi ??? + // all combination i tried were failing. + // so we have to allocate extra mem and copy data to buffer if in cooked mode + char* inPtr = (char*)buffer; + if (!raw) inPtr = new char[num*2352]; + if (!inPtr) return false; + + s.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.SRB_HaId = haId; + s.SRB_Target = target; + s.SRB_Lun = lun; + s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.SRB_SenseLen = SENSE_LEN; + + s.SRB_BufLen = 2352*num; //num*(raw?2352:2048); + s.SRB_BufPointer = (BYTE FAR*)inPtr; + s.SRB_CDBLen = 12; + s.SRB_PostProc = (LPVOID)hEvent; + + s.CDBByte[0] = 0xBE; + s.CDBByte[2] = (unsigned char)((sector >> 24) & 0xFF); + s.CDBByte[3] = (unsigned char)((sector >> 16) & 0xFF); + s.CDBByte[4] = (unsigned char)((sector >> 8) & 0xFF); + s.CDBByte[5] = (unsigned char)((sector & 0xFF)); + s.CDBByte[6] = (unsigned char)((num >> 16) & 0xFF); + s.CDBByte[7] = (unsigned char)((num >> 8) & 0xFF); + s.CDBByte[8] = (unsigned char) (num & 0xFF); + s.CDBByte[9] = (raw?0xF0:0x10); + + ResetEvent(hEvent); + + dwStatus = pSendASPI32Command((LPSRB)&s); + + if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); + + CloseHandle(hEvent); + + if (s.SRB_Status!=SS_COMP) { + if (!raw) delete[] inPtr; + return false; + } + + if (!raw) { + // copy user data to buffer + char* source = inPtr; + source+=16; // jump 16 bytes + char* outPtr = (char*)buffer; + for (unsigned long i=0; i Date: Thu, 27 Mar 2003 21:16:48 +0000 Subject: [PATCH 0735/4131] cdrom interface ioctl win32 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@814 --- src/dos/cdrom_ioctl_win32.cpp | 275 ++++++++++++++++++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 src/dos/cdrom_ioctl_win32.cpp diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp new file mode 100644 index 00000000..8426121a --- /dev/null +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#if defined (WIN32) + +// ***************************************************************** +// Windows IOCTL functions (not suitable for 95/98/Me) +// ***************************************************************** + +#include +#include // Ioctl stuff +#include "ntddcdrm.h" // Ioctl stuff +#include "cdrom.h" + +CDROM_Interface_Ioctl::CDROM_Interface_Ioctl() +{ + pathname[0] = 0; + hIOCTL = INVALID_HANDLE_VALUE; + memset(&oldLeadOut,0,sizeof(oldLeadOut)); +}; + +CDROM_Interface_Ioctl::~CDROM_Interface_Ioctl() +{ + StopAudio(); +}; + +bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc) +{ + // FIXME : To Do + return true; +} + +bool CDROM_Interface_Ioctl::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut) +{ + Open(); + CDROM_TOC toc; + DWORD byteCount; + BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, + &toc, sizeof(toc), &byteCount,NULL); + Close(); + if (!bStat) return false; + + stTrack = toc.FirstTrack; + endTrack = toc.LastTrack; + leadOut.min = toc.TrackData[endTrack].Address[1]; + leadOut.sec = toc.TrackData[endTrack].Address[2]; + leadOut.fr = toc.TrackData[endTrack].Address[3]; + return true; +}; + +bool CDROM_Interface_Ioctl::GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr) +{ + Open(); + CDROM_TOC toc; + DWORD byteCount; + BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, + &toc, sizeof(toc), &byteCount,NULL); + Close(); + if (!bStat) return false; + + attr = (toc.TrackData[track-1].Adr << 4) | toc.TrackData[track].Control; + start.min = toc.TrackData[track-1].Address[1]; + start.sec = toc.TrackData[track-1].Address[2]; + start.fr = toc.TrackData[track-1].Address[3]; + return true; +}; + +bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) +{ + Open(); + + CDROM_SUB_Q_DATA_FORMAT insub; + SUB_Q_CHANNEL_DATA sub; + DWORD byteCount; + + insub.Format = IOCTL_CDROM_CURRENT_POSITION; + + BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), + &sub, sizeof(sub), &byteCount,NULL); + Close(); + if (!bStat) return false; + + attr = (sub.CurrentPosition.ADR << 4) | sub.CurrentPosition.Control; + track = sub.CurrentPosition.TrackNumber; + index = sub.CurrentPosition.IndexNumber; + relPos.min = sub.CurrentPosition.TrackRelativeAddress[1]; + relPos.sec = sub.CurrentPosition.TrackRelativeAddress[2]; + relPos.fr = sub.CurrentPosition.TrackRelativeAddress[3]; + absPos.min = sub.CurrentPosition.AbsoluteAddress[1]; + absPos.sec = sub.CurrentPosition.AbsoluteAddress[2]; + absPos.fr = sub.CurrentPosition.AbsoluteAddress[3]; + + return true; +}; + +bool CDROM_Interface_Ioctl::GetAudioStatus(bool& playing, bool& pause) +{ + Open(); + + CDROM_SUB_Q_DATA_FORMAT insub; + SUB_Q_CHANNEL_DATA sub; + DWORD byteCount; + + insub.Format = IOCTL_CDROM_CURRENT_POSITION; + + BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), + &sub, sizeof(sub), &byteCount,NULL); + Close(); + if (!bStat) return false; + + playing = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_IN_PROGRESS); + pause = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_PAUSED); + + return true; +}; + +bool CDROM_Interface_Ioctl::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) +{ + // Seems not possible to get this values using ioctl... + int track1,track2; + TMSF leadOut; + // If we can read, there's a media + mediaPresent = GetAudioTracks(track1, track2, leadOut), + trayOpen = !mediaPresent; + mediaChanged = (oldLeadOut.min!=leadOut.min) || (oldLeadOut.sec!=leadOut.sec) || (oldLeadOut.fr!=leadOut.fr); + // Save old values + oldLeadOut.min = leadOut.min; + oldLeadOut.sec = leadOut.sec; + oldLeadOut.fr = leadOut.fr; + // always success + return true; +}; + +bool CDROM_Interface_Ioctl::PlayAudioSector (unsigned long start,unsigned long len) +{ + Open(); + CDROM_PLAY_AUDIO_MSF audio; + DWORD byteCount; + // Start + unsigned long addr = start + 150; + audio.StartingF = (UCHAR)(addr%75); addr/=75; + audio.StartingS = (UCHAR)(addr%60); + audio.StartingM = (UCHAR)(addr/60); + // End + addr = start + len + 150; + audio.EndingF = (UCHAR)(addr%75); addr/=75; + audio.EndingS = (UCHAR)(addr%60); + audio.EndingM = (UCHAR)(addr/60); + + BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PLAY_AUDIO_MSF, &audio, sizeof(audio), + NULL, 0, &byteCount,NULL); + Close(); + return bStat>0; +}; + +bool CDROM_Interface_Ioctl::PauseAudio(bool resume) +{ + Open(); + BOOL bStat; + DWORD byteCount; + if (resume) bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RESUME_AUDIO, NULL, 0, + NULL, 0, &byteCount,NULL); + else bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PAUSE_AUDIO, NULL, 0, + NULL, 0, &byteCount,NULL); + Close(); + return bStat>0; +}; + +bool CDROM_Interface_Ioctl::StopAudio(void) +{ + Open(); + BOOL bStat; + DWORD byteCount; + bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_STOP_AUDIO, NULL, 0, + NULL, 0, &byteCount,NULL); + Close(); + return bStat>0; +}; + +bool CDROM_Interface_Ioctl::LoadUnloadMedia(bool unload) +{ + Open(); + BOOL bStat; + DWORD byteCount; + if (unload) bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, + NULL, 0, &byteCount,NULL); + else bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, + NULL, 0, &byteCount,NULL); + Close(); + return bStat>0; +}; + +bool CDROM_Interface_Ioctl::ReadSectors(void* buffer, bool raw, unsigned long sector, unsigned long num) +{ + // TODO : How to copy cooked without current overhead ? + BOOL bStat; + DWORD byteCount; + RAW_READ_INFO in; + char* inPtr; + + in.DiskOffset.LowPart = sector; + in.DiskOffset.HighPart = 0; + in.SectorCount = num; + in.TrackMode = CDDA; + + if (!raw) inPtr = new char[num*RAW_SECTOR_SIZE]; + else inPtr = (char*)buffer; + + bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RAW_READ, &in, sizeof(in), + inPtr, num*RAW_SECTOR_SIZE, &byteCount,NULL); + + if (!raw) { + char* source = inPtr; + source+=16; // jump 16 bytes + char* outPtr = (char*)buffer; + for (unsigned long i=0; i0); +} + +bool CDROM_Interface_Ioctl::SetDevice(char* path, int forceCD) +{ + if (GetDriveType(path)==DRIVE_CDROM) { + char letter [3] = { 0, ':', 0 }; + letter[0] = path[0]; + strcpy(pathname,"\\\\.\\"); + strcat(pathname,letter); + if (Open()) { + Close(); + return true; + }; + } + return false; +} + +bool CDROM_Interface_Ioctl::Open(void) +{ + hIOCTL = CreateFile(pathname, // drive to open + GENERIC_READ, // read access + FILE_SHARE_READ | // share mode + FILE_SHARE_WRITE, + NULL, // default security attributes + OPEN_EXISTING, // disposition + 0, // file attributes + NULL); // do not copy file attributes + return (hIOCTL!=INVALID_HANDLE_VALUE); +}; + +void CDROM_Interface_Ioctl::Close(void) +{ + CloseHandle(hIOCTL); +}; + +#endif From 75b0c0fe54d6fe70e6810b817a86dd351fefcd1e Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 27 Mar 2003 21:18:42 +0000 Subject: [PATCH 0736/4131] Added SDL_INIT_CDROM Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@815 --- src/gui/sdlmain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index bc8ad5ae..1a17203b 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -541,7 +541,7 @@ int main(int argc, char* argv[]) { DEBUG_SetupConsole(); #endif - if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER + if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM #ifndef DISABLE_JOYSTICK |SDL_INIT_JOYSTICK From 8031e441746d1fa37eebbc3713d0e5c887ef4cd5 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 27 Mar 2003 21:20:54 +0000 Subject: [PATCH 0737/4131] added cdrom_aspi_win32, cdrom_aspi_win32. remove cdrom_ioctl Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@816 --- visualc/dosbox.dsp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index c80543ae..cb541c3c 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -230,7 +230,11 @@ SOURCE=..\src\dos\cdrom.h # End Source File # Begin Source File -SOURCE=..\src\dos\cdrom_ioctl.cpp +SOURCE=..\src\dos\cdrom_aspi_win32.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\dos\cdrom_ioctl_win32.cpp # End Source File # Begin Source File From 78ad1527b4e82ef69e4395169c0039224c651108 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 27 Mar 2003 21:43:43 +0000 Subject: [PATCH 0738/4131] Aways link zlib with libpng. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@817 --- configure.in | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/configure.in b/configure.in index 74312477..808f88ea 100644 --- a/configure.in +++ b/configure.in @@ -65,13 +65,8 @@ AC_ARG_ENABLE(debug,[ --enable-debug Enable debug mode],[ AH_TEMPLATE(C_SSHOT,[Define to 1 to enable screenshots, requires libpng]) AC_ARG_ENABLE(shots,[ --enable-shots Enable screenshot support],[ AC_CHECK_HEADER(png.h,have_png_h=yes,) - AC_CHECK_LIB(png, png_check_sig, have_png_lib=yes, ,) - AC_CHECK_LIB(png, png_check_sig, have_png_lib_z=yes, , -lz) - + 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" - AC_DEFINE(C_SSHOT,1) - else if test x$have_png_lib_z = xyes -a x$have_png_h = xyes ; then LIBS="$LIBS -lpng -lz" AC_DEFINE(C_SSHOT,1) else From a1f0a5e82b10ae0f3af22a7f3cd068822685348c Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 27 Mar 2003 21:56:46 +0000 Subject: [PATCH 0739/4131] added description for new mount commands and switches Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@818 --- README | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README b/README index 54820a01..1369451f 100644 --- a/README +++ b/README @@ -48,15 +48,20 @@ The option -t specifies the media: Where can be. floppy = floppy drive cdrom = cdrom drive +The option -cd lists all found cdrom drives and their id. +The option -usecd [x] forces to use the cdrom number x (id as shown in list -cd) + The option -aspi forces to use aspi driver + (only valid if mounting a cdrom and on Windows systems with ASPI-Layer). +The option -ioctl forces to use ioctl functions (only valid if mounting a cdrom and on Win2000/XP/NT systems). For example to mount c:\floppy as a floppy : mount a c:\floppy -t floppy For example to mount system cdrom drive e as cdrom drive d in dosbox mount d e:\ -t cdrom -- In Win 95/98/ME you need latest ASPI driver to get cdrom audio support. -- In Win 2000/XP/NT you have the option to use an ASPI driver (add -aspi) - at the end of the mount command. +For example to mount system cdrom drive at mountpoint /media/cdrom as cdrom +drive d in dosbox + mount d /media/cdrom -t cdrom -usecd 0 It is also possible to mount a directory as cdrom, but it's limited. From eee39b3127af51e4f337b701442d5bfa0576a073 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 27 Mar 2003 22:02:47 +0000 Subject: [PATCH 0740/4131] sdl.h ->SDL.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@819 --- src/dos/cdrom.cpp | 2 +- src/dos/cdrom.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index a94cfd6f..86cf831d 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -21,7 +21,7 @@ // SDL CDROM // ****************************************************** -#include "sdl.h" +#include "SDL.h" #include "support.h" #include "cdrom.h" diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index a1ff4271..8dfc97a0 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -5,7 +5,7 @@ #define MAX_ASPI_CDROM 5 #include -#include "sdl.h" +#include "SDL.h" #define RAW_SECTOR_SIZE 2352 #define COOKED_SECTOR_SIZE 2048 From 26442d5cf0008684571a5cab4e592322bd13c37e Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 27 Mar 2003 22:03:30 +0000 Subject: [PATCH 0741/4131] removed #include "sdl.h" Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@820 --- src/dos/dos_programs.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index d47f90b0..23ae5bb7 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -19,7 +19,6 @@ #include #include #include -#include "sdl.h" #include "programs.h" #include "support.h" #include "drives.h" From da94184eda84d71b7b52b4f1f1420deabadceff5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 27 Mar 2003 23:25:44 +0000 Subject: [PATCH 0742/4131] Alsa m4 macros Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@821 --- acinclude.m4 | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 147 insertions(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index 6974c0c1..bdf27631 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -160,9 +160,155 @@ int main (int argc, char *argv[]) rm -f conf.sdltest ]) +dnl Configure Paths for Alsa +dnl Some modifications by Richard Boulton +dnl Christopher Lansdown +dnl Jaroslav Kysela +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 +], [ +/* ensure backward compatibility */ +#if !defined(SND_LIB_MAJOR) && defined(SOUNDLIB_VERSION_MAJOR) +#define SND_LIB_MAJOR SOUNDLIB_VERSION_MAJOR +#endif +#if !defined(SND_LIB_MINOR) && defined(SOUNDLIB_VERSION_MINOR) +#define SND_LIB_MINOR SOUNDLIB_VERSION_MINOR +#endif +#if !defined(SND_LIB_SUBMINOR) && defined(SOUNDLIB_VERSION_SUBMINOR) +#define SND_LIB_SUBMINOR SOUNDLIB_VERSION_SUBMINOR +#endif + +# if(SND_LIB_MAJOR > $alsa_min_major_version) + exit(0); +# else +# if(SND_LIB_MAJOR < $alsa_min_major_version) +# error not present +# endif + +# if(SND_LIB_MINOR > $alsa_min_minor_version) + exit(0); +# else +# if(SND_LIB_MINOR < $alsa_min_minor_version) +# error not present +# endif + +# if(SND_LIB_SUBMINOR < $alsa_min_micro_version) +# error not present +# endif +# endif +# endif +exit(0); +], + [AC_MSG_RESULT(found.)], + [AC_MSG_RESULT(not present.) + ifelse([$3], , [AC_MSG_ERROR(Sufficiently new version of libasound not found.)]) + alsa_found=no] +) +AC_LANG_RESTORE + +dnl Now that we know that we have the right version, let's see if we have the library and not just the headers. +AC_CHECK_LIB([asound], [snd_ctl_open],, + [ifelse([$3], , [AC_MSG_ERROR(No linkable libasound was found.)]) + alsa_found=no] +) + +if test "x$alsa_found" = "xyes" ; then + ifelse([$2], , :, [$2]) + LIBS=`echo $LIBS | sed 's/-lasound//g'` + LIBS=`echo $LIBS | sed 's/ //'` + LIBS="-lasound $LIBS" +fi +if test "x$alsa_found" = "xno" ; then + ifelse([$3], , :, [$3]) + CFLAGS="$alsa_save_CFLAGS" + LDFLAGS="$alsa_save_LDFLAGS" + LIBS="$alsa_save_LIBS" + ALSA_CFLAGS="" + ALSA_LIBS="" +fi + +dnl That should be it. Now just export out symbols: +AC_SUBST(ALSA_CFLAGS) +AC_SUBST(ALSA_LIBS) +]) + + + + AH_TOP([ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by From bf14047e3c150f293571fb710e0bf291122a94ac Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 27 Mar 2003 23:46:03 +0000 Subject: [PATCH 0743/4131] Correct handling of failture to detect alsa. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@822 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 808f88ea..af0872fb 100644 --- a/configure.in +++ b/configure.in @@ -43,7 +43,7 @@ AC_MSG_CHECKING(if compiler allows __attribute__) AC_TRY_COMPILE([], [typedef struct { } __attribute__ ((packed)) junk;], [ AC_MSG_RESULT(yes);AC_DEFINE(C_HAS_ATTRIBUTE)],AC_MSG_RESULT(no)) -AM_PATH_ALSA(0.9.0, [AC_DEFINE(HAVE_ALSA, 1, [Define to use ALSA for MIDI])]) +AM_PATH_ALSA(0.9.0, AC_DEFINE(HAVE_ALSA,1,[Define to 1 to use ALSA for MIDI]) , : ) #Check for big endian machine, should #define WORD_BIGENDIAN if so AC_C_BIGENDIAN From 5f45f5ec909bd90222eaed3b8e33e4ab3974bb48 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 28 Mar 2003 00:28:44 +0000 Subject: [PATCH 0744/4131] Moved the MACOSX check below the header includes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@823 --- src/gui/sdlmain.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 1a17203b..e0c549e2 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -20,10 +20,6 @@ #include #include -#ifdef MACOSX -extern char** environ; -#endif - #include "SDL.h" #include "SDL_thread.h" @@ -40,6 +36,10 @@ extern char** environ; //#define DISABLE_JOYSTICK #define C_GFXTHREADED 1 //Enabled by default +#if defined(MACOSX) +extern char** environ; +#endif + struct SDL_Block { volatile bool active; //If this isn't set don't draw volatile bool drawing; From 98b32db971856143c753581e3af1829124ee280b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 28 Mar 2003 07:57:30 +0000 Subject: [PATCH 0745/4131] CoreAudio midi support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@824 --- src/gui/midi_coreaudio.h | 92 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/gui/midi_coreaudio.h diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h new file mode 100644 index 00000000..8b95418c --- /dev/null +++ b/src/gui/midi_coreaudio.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include + +class MidiHandler_coreaudio : public MidiHandler { +private: + AudioUnit m_musicDevice; + AudioUnit m_outputUnit; +public: + MidiHandler_coreaudio() : m_musicDevice(0), m_outputUnit(0) {} + char * GetName(void) { return "coreaudio"; } + bool Open(const char * conf) { + int err; + AudioUnitConnection auconnect; + ComponentDescription compdesc; + Component compid; + + if (m_outputUnit) + return false; + + // Open the Music Device + compdesc.componentType = kAudioUnitComponentType; + compdesc.componentSubType = kAudioUnitSubType_MusicDevice; + compdesc.componentManufacturer = kAudioUnitID_DLSSynth; + compdesc.componentFlags = 0; + compdesc.componentFlagsMask = 0; + compid = FindNextComponent(NULL, &compdesc); + m_musicDevice = (AudioUnit) OpenComponent(compid); + + // open the output unit + m_outputUnit = (AudioUnit) OpenDefaultComponent(kAudioUnitComponentType, kAudioUnitSubType_Output); + + // connect the units + auconnect.sourceAudioUnit = m_musicDevice; + auconnect.sourceOutputNumber = 0; + auconnect.destInputNumber = 0; + err = + AudioUnitSetProperty(m_outputUnit, kAudioUnitProperty_MakeConnection, kAudioUnitScope_Input, 0, + (void *)&auconnect, sizeof(AudioUnitConnection)); + + // initialize the units + AudioUnitInitialize(m_musicDevice); + AudioUnitInitialize(m_outputUnit); + + // start the output + AudioOutputUnitStart(m_outputUnit); + + return true; + } + + void Close(void) { + if (m_outputUnit) { + AudioOutputUnitStop(m_outputUnit); + CloseComponent(m_outputUnit); + m_outputUnit = 0; + } + if (m_musicDevice) { + CloseComponent(m_musicDevice); + m_musicDevice = 0; + } + } + + void PlayMsg(Bit32u msg) { + MusicDeviceMIDIEvent(m_musicDevice, + (msg & 0x000000FF), + (msg & 0x0000FF00) >> 8, + (msg & 0x00FF0000) >> 16, + 0); + } + + void PlaySysex(Bit8u * sysex, Bitu len) { + MusicDeviceSysEx(m_musicDevice, sysex, len); + } +}; + +MidiHandler_coreaudio Midi_coreaudio; From 1cc96da5a4582ba950caa5e43673f36b3b200952 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 28 Mar 2003 15:47:42 +0000 Subject: [PATCH 0746/4131] Slight modification and added entry for new opl2 emulator Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@825 --- THANKS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/THANKS b/THANKS index 6e7ae900..9a46546f 100644 --- a/THANKS +++ b/THANKS @@ -3,7 +3,10 @@ We would like to thank: Vlad R. of the vdmsound project for excellent sound blaster info. Tatsuyuki Satoh of the Mame Team for making an excellent FM emulator. +Jarek Burczynski for the new OPL emulator. + The Bochs and DOSemu projects which I used for information. Freedos for ideas in making my shell. + All the people who submitted a bug. The Beta Testers. From e365dc5d5b1832d48b18181fa473490ab233bf99 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 28 Mar 2003 20:35:12 +0000 Subject: [PATCH 0747/4131] Lower next key delay a bit. Fixes with extended keys getting pressed twice. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@826 --- src/hardware/keyboard.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index f389360c..7c4e927d 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -24,7 +24,7 @@ #include "mixer.h" #define KEYBUFSIZE 32 -#define KEYDELAY 250 +#define KEYDELAY 150 enum KeyCommands { CMD_NONE, @@ -77,6 +77,7 @@ void KEYBOARD_ClrBuffer(void) { keyb.buf.used=0; keyb.buf.pos=0; keyb.read_active=false; + keyb.scheduled=false; PIC_DeActivateIRQ(1); } @@ -100,6 +101,7 @@ void KEYBOARD_GetCode(void) { } void KEYBOARD_AddCode(Bit8u scancode,Bit8u ascii,Bitu mod,KeyStates state) { +// LOG_MSG("Add key scan %d ascii %c",scancode,ascii); if (keyb.buf.used Date: Fri, 28 Mar 2003 21:04:19 +0000 Subject: [PATCH 0748/4131] Removed the E_Exit's of unhandled calls and grouped them all together. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@827 --- src/dos/dos.cpp | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index c08ae71f..2ccbe9bc 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -266,11 +266,6 @@ static Bitu DOS_21Handler(void) { psp.SetDTA(dos.dta); } break; - case 0x1f: /* Get drive parameter block for default drive */ - - case 0x32: /* Get drive parameter block for specific drive */ - E_Exit("DOS:Unhandled call %02X",reg_ah); - break; /* TODO maybe but hardly think a game needs this */ case 0x25: /* Set Interrupt Vector */ RealSetVec(reg_al,RealMakeSeg(ds,reg_dx)); break; @@ -686,18 +681,18 @@ static Bitu DOS_21Handler(void) { break; case 0x58: /* Get/Set Memory allocation strategy */ switch (reg_al) { - case 0: /* Get Strategy */ + case 0: /* Get Strategy */ reg_ax=DOS_GetMemAllocStrategy(); break; - case 1: /* Set Strategy */ + case 1: /* Set Strategy */ DOS_SetMemAllocStrategy(reg_bx); break; - case 2: /* Get UMB Link Status */ - reg_ax=1; /* no UMB support */ + case 2: /* Get UMB Link Status */ + reg_ax=1; // no UMB support CALLBACK_SCF(true); break; - case 3: /* Set UMB Link Status */ - reg_ax=1; /* failure, no support */ + case 3: /* Set UMB Link Status */ + reg_ax=1; // failure, no support CALLBACK_SCF(true); break; default: @@ -743,12 +738,6 @@ static Bitu DOS_21Handler(void) { } break; } - - case 0x5c: /* FLOCK File region locking */ - case 0x5e: /* More Network Functions */ - case 0x5f: /* And Even More Network Functions */ - E_Exit("DOS:Unhandled call %02X",reg_ah); - break; case 0x60: /* Canonicalize filename or path */ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_Canonicalize(name1,name2)) { @@ -836,6 +825,11 @@ static Bitu DOS_21Handler(void) { case 0xEF: /* Used in Ancient Art Of War CGA */ case 0x5d: /* Network Functions ||HMMM seems to critical error info and return 1!! Maybe implement it.??*/ /* al=06 clears cf and leaves al=6 and returns crit error flag location*/ + case 0x1f: /* Get drive parameter block for default drive */ + case 0x32: /* Get drive parameter block for specific drive */ + case 0x5c: /* FLOCK File region locking */ + case 0x5e: /* More Network Functions */ + case 0x5f: /* And Even More Network Functions */ default: LOG(LOG_ERROR|LOG_MISC,"DOS:Unhandled call %02X al=%02X. Set al to default of 0",reg_ah,reg_al); reg_al=0x00; /* default value */ From 5db04ccbbe0258abcb97caddaaa8e7240a2bcfa3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 28 Mar 2003 21:05:13 +0000 Subject: [PATCH 0749/4131] Register seems to be 0x100 on program's startup. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@828 --- src/dos/dos_execute.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 789ce2e7..fa4e4ca1 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -357,8 +357,8 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { mem_writew(SegPhys(ss)+reg_sp+2,RealSeg(csip)); mem_writew(SegPhys(ss)+reg_sp+4,0x200); /* Setup the rest of the registers */ - reg_ax=0; - reg_cx=reg_dx=reg_bx=reg_si=reg_di=reg_bp=0; + reg_ax=0;reg_si=0x100; + reg_cx=reg_dx=reg_bx=reg_di=reg_bp=0; SegSet16(ds,pspseg);SegSet16(es,pspseg); #if C_DEBUG /* Started from debug.com, then set breakpoint at start */ From c0ddbe1da394e7a5d5b23127982490c5a8a39a91 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 28 Mar 2003 23:38:48 +0000 Subject: [PATCH 0750/4131] -scaler command line option. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@829 --- src/gui/render.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index a6176408..356c6283 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -378,7 +378,12 @@ void RENDER_Init(Section * sec) { render.shot.dir=section->Get_string("snapshots"); KEYBOARD_AddEvent(KBD_f5,KBD_MOD_CTRL,EnableScreenShot); #endif - const char * scaler=section->Get_string("scaler"); + const char * scaler;std::string cline; + if (control->cmdline->FindString("-scaler",cline,false)) { + scaler=cline.c_str(); + } else { + scaler=section->Get_string("scaler"); + } if (!strcasecmp(scaler,"none")) render.op.want_type=OP_None; else if (!strcasecmp(scaler,"scale2x")) render.op.want_type=OP_Scale2x; else { From 21306420c0b418f0effbd34c9f664f21ee31a9ff Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 28 Mar 2003 23:41:34 +0000 Subject: [PATCH 0751/4131] Removed dosbox_datadir. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@830 --- include/cross.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/cross.h b/include/cross.h index 65066cd8..813ff256 100644 --- a/include/cross.h +++ b/include/cross.h @@ -50,7 +50,5 @@ #define ftruncate(blah,blah2) chsize(blah,blah2) #endif -extern const char * dosbox_datadir; - #endif From 74cdd9bfeddda5ca5adbede002a2c7cf0b5140a2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 29 Mar 2003 00:32:48 +0000 Subject: [PATCH 0752/4131] Add cdrom_ioctl_win32.cpp and cdrom_aspi_win32.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@831 --- src/dos/Makefile.am | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dos/Makefile.am b/src/dos/Makefile.am index e2d02436..821a71b1 100644 --- a/src/dos/Makefile.am +++ b/src/dos/Makefile.am @@ -4,5 +4,6 @@ noinst_LIBRARIES = libdos.a EXTRA_DIST = Ntddcdrm.h Ntddscsi.h Ntddstor.h scsidefs.h wnaspi32.h libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioctl.cpp dos_memory.cpp \ dos_misc.cpp dos_classes.cpp dos_programs.cpp dos_tables.cpp \ - drives.cpp drives.h drive_virtual.cpp drive_local.cpp \ - dev_con.h drive_cache.cpp cdrom.h cdrom.cpp dos_mscdex.cpp + drives.cpp drives.h drive_virtual.cpp drive_local.cpp drive_cache.cpp \ + dev_con.h dos_mscdex.cpp \ + cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp From cbeca815e5216d3c239c23d3a00ee81b1de2b4bd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 29 Mar 2003 00:34:30 +0000 Subject: [PATCH 0753/4131] include ctype.h for toupper function Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@832 --- src/dos/cdrom_aspi_win32.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index cd63999b..33d8c2a2 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -18,6 +18,8 @@ #if defined (WIN32) +#include + #include "cdrom.h" #include "scsidefs.h" // Aspi stuff #include "dosbox.h" From 0f2cb26064bbb831550dd4c9f72bb5a462250fb4 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 29 Mar 2003 10:28:20 +0000 Subject: [PATCH 0754/4131] Fixed keyboard data in buffer bit. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@833 --- src/hardware/keyboard.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 7c4e927d..b0f053c9 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -64,7 +64,6 @@ struct KeyBlock { bool enabled; bool active; bool scheduled; - bool read_active; }; static KeyBlock keyb; @@ -76,7 +75,6 @@ static KeyEvent * event_handlers[KBD_LAST]; void KEYBOARD_ClrBuffer(void) { keyb.buf.used=0; keyb.buf.pos=0; - keyb.read_active=false; keyb.scheduled=false; PIC_DeActivateIRQ(1); } @@ -225,7 +223,7 @@ static void write_p64(Bit32u port,Bit8u val) { } static Bit8u read_p64(Bit32u port) { - return 0x1c | (keyb.read_active ? 0x1 : 0x0); + return 0x1c | (keyb.buf.used ? 0x1 : 0x0); } void KEYBOARD_AddEvent(Bitu keytype,Bitu state,KEYBOARD_EventHandler * handler) { From e78c836cb0eed89fd79d23b0dcc74ad6e1afd213 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 29 Mar 2003 16:36:12 +0000 Subject: [PATCH 0755/4131] Improved int 21 38/65 : Get (extended) country information Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@834 --- src/dos/dos.cpp | 48 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 2ccbe9bc..8f969a8c 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -35,6 +35,7 @@ DOS_InfoBlock dos_infoblock; Bit8u dos_copybuf[0x10000]; static Bitu call_20,call_21,call_25,call_26,call_27,call_28,call_29; +static Bitu call_casemap; void DOS_SetError(Bit16u code) { dos.errorcode=code; @@ -385,15 +386,26 @@ static Bitu DOS_21Handler(void) { LOG(LOG_ERROR|LOG_MISC,"DOS:0x37:Call for not supported switchchar"); break; case 0x38: /* Set Country Code */ - LOG(LOG_ERROR|LOG_MISC,"DOS:Setting country code not supported"); - CALLBACK_SCF(true); - break; if (reg_al==0) { /* Get country specidic information */ - + PhysPt pt = SegPhys(ds)+reg_dx; + mem_writew(pt ,0x00); // USA + mem_writeb(pt+ 2, '$'); mem_writeb(pt+ 3,0x00); + mem_writeb(pt+ 7, '.'); mem_writeb(pt+ 8,0x00); + mem_writeb(pt+ 9, '.'); mem_writeb(pt+10,0x00); + mem_writeb(pt+11, '.'); mem_writeb(pt+12,0x00); + mem_writeb(pt+13, '.'); mem_writeb(pt+14,0x00); + mem_writeb(pt+15,0x01); // currency format + mem_writeb(pt+16,0x02); // num digits + mem_writeb(pt+17,0x00); // time format + mem_writed(pt+18,CALLBACK_RealPointer(call_casemap)); + mem_writew(pt+22,0x00); // data list seperator + reg_bx = 0x01; + CALLBACK_SCF(false); + break; } else { /* Set country code */ - - + LOG(LOG_ERROR|LOG_MISC,"DOS:Setting country code not supported"); } + CALLBACK_SCF(true); break; case 0x39: /* MKDIR Create directory */ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); @@ -768,7 +780,18 @@ static Bitu DOS_21Handler(void) { reg_cx=4; CALLBACK_SCF(false); break; - default: + case 2: // Get pointer to uppercase table + case 3: // Get pointer to lowercase table + case 4: // Get pointer to filename uppercase table + case 5: // Get pointer to filename terminator table + case 6: // Get pointer to collating sequence table + case 7: // Get pointer to double byte char set table + mem_writew(data ,0x0000); // We dont have this table... + mem_writew(data+2,0x0000); // End of table + reg_cx=4; + CALLBACK_SCF(false); + break; + default: E_Exit("DOS:0x65:Unhandled country information call %2X",reg_al); }; break; @@ -890,11 +913,17 @@ static Bitu DOS_29Handler(void) { return CBRET_NONE; } +static Bitu DOS_CaseMapFunc(void) { + //LOG(LOG_ERROR|LOG_MISC,"Case map routine called : %c",reg_al); + return CBRET_NONE; +}; + void DOS_ShutDown(Section* sec) { for (Bit16u i=0;iAddDestroyFunction(&DOS_ShutDown); - + /* case map routine INT 0x21 0x38 */ + call_casemap = CALLBACK_Allocate(); + CALLBACK_Setup(call_casemap,DOS_CaseMapFunc,CB_RETF); } From 470f4937fd77316a0df7b0c861d024854dfb30c5 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 29 Mar 2003 17:13:58 +0000 Subject: [PATCH 0756/4131] Added rescan command (clear drive cache) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@835 --- src/dos/dos_programs.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 23ae5bb7..92fa71b2 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -252,6 +252,29 @@ static void LOADFIX_ProgramStart(Program * * make) { *make=new LOADFIX; } +// RESCAN + +class RESCAN : public Program { +public: + void Run(void); +}; + +void RESCAN::Run(void) +{ + // Get current drive + Bit8u drive = DOS_GetDefaultDrive(); + if (Drives[drive]) { + Drives[drive]->EmptyCache(); + WriteOut(MSG_Get("RESCAN_SUCCESS")); + } +}; + +static void RESCAN_ProgramStart(Program * * make) { + *make=new RESCAN; +} + + + void DOS_SetupPrograms(void) { /*Add Messages */ MSG_Add("PROGRAM_MOUNT_STATUS_2","Drive %c is mounted as %s\n"); @@ -278,9 +301,11 @@ void DOS_SetupPrograms(void) { MSG_Add("MSCDEX_LIMITED_SUPPORT","MSCDEX: Mounted subdirectory: limited support.\n"); MSG_Add("MSCDEX_UNKNOWN_ERROR","MSCDEX: Failure: Unknown error.\n"); + MSG_Add("RESCAN_SUCCESS","Drive cache cleared.\n"); + /*regular setup*/ PROGRAMS_MakeFile("MOUNT.COM",MOUNT_ProgramStart); PROGRAMS_MakeFile("MEM.COM",MEM_ProgramStart); PROGRAMS_MakeFile("LOADFIX.COM",LOADFIX_ProgramStart); - + PROGRAMS_MakeFile("RESCAN.COM",RESCAN_ProgramStart); } From f1227be1790cd9939fe644c6f0b813e7f25bd076 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 29 Mar 2003 17:14:59 +0000 Subject: [PATCH 0757/4131] moved drive cache to dos_system.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@836 --- include/dos_system.h | 117 ++++++++++++++++++++++++++++++++++++++++++- src/dos/drives.h | 114 ----------------------------------------- 2 files changed, 116 insertions(+), 115 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index c7bc88bd..dc0a3604 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -19,8 +19,11 @@ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ -#include #include "dosbox.h" +#include "cross.h" +#include +#include +#include #define DOS_NAMELENGTH 12 #define DOS_NAMELENGTH_ASCII (DOS_NAMELENGTH+1) @@ -78,6 +81,115 @@ public: Bit8u fhandle; }; +#define MAX_OPENDIRS 16 + +class DOS_Drive_Cache { +public: + DOS_Drive_Cache (void); + DOS_Drive_Cache (const char* path); + ~DOS_Drive_Cache (void); + + typedef enum TDirSort { NOSORT, ALPHABETICAL, DIRALPHABETICAL, ALPHABETICALREV, DIRALPHABETICALREV }; + + void SetBaseDir (const char* path); + void SetDirSort (TDirSort sort) { sortDirType = sort; }; + bool OpenDir (const char* path, Bit16u& id); + bool ReadDir (Bit16u id, char* &result); + + void ExpandName (char* path); + char* GetExpandName (const char* path); + bool GetShortName (const char* fullname, char* shortname); + + void CacheOut (const char* path, bool ignoreLastDir = false); + void AddEntry (const char* path, bool checkExist = false); + void DeleteEntry (const char* path, bool ignoreLastDir = false); + + void EmptyCache (void); + + class CFileInfo { + public: + ~CFileInfo(void) { + for (Bit32u i=0; i fileList; + std::vector longNameList; + std::vector outputList; + }; + +private: + + bool RemoveTrailingDot (char* shortname); + Bit16s GetLongName (CFileInfo* info, char* shortname); + void CreateShortName (CFileInfo* dir, CFileInfo* info); + Bit16u CreateShortNameID (CFileInfo* dir, const char* name); + bool SetResult (CFileInfo* dir, char * &result, Bit16u entryNr); + bool IsCachedIn (CFileInfo* dir); + CFileInfo* FindDirInfo (const char* path, char* expandedPath); + bool RemoveSpaces (char* str); + bool OpenDir (CFileInfo* dir, char* path, Bit16u& id); + void CreateEntry (CFileInfo* dir, const char* name); + Bit16u GetFreeID (CFileInfo* dir); + void Clear (void); + + + CFileInfo* dirBase; + char dirPath [CROSS_LEN]; + char basePath [CROSS_LEN]; + bool dirFirstTime; + TDirSort sortDirType; + CFileInfo* save_dir; + char save_path [CROSS_LEN]; + char save_expanded [CROSS_LEN]; + + Bit16u srchNr; + CFileInfo* dirSearch [MAX_OPENDIRS]; + char dirSearchName [MAX_OPENDIRS]; + bool free [MAX_OPENDIRS]; + +}; + +class DOS_No_Drive_Cache { +public: + DOS_No_Drive_Cache (void) {}; + DOS_No_Drive_Cache (const char* path); + ~DOS_No_Drive_Cache (void) {}; + + typedef enum TDirSort { NOSORT, ALPHABETICAL, DIRALPHABETICAL, ALPHABETICALREV, DIRALPHABETICALREV }; + + void SetBaseDir (const char* path); + void SetDirSort (TDirSort sort) {}; + bool OpenDir (const char* path, Bit16u& id); + bool ReadDir (Bit16u id, char * &result); + + void ExpandName (char* path) {}; + char* GetExpandName (const char* path) { return (char*)path; }; + bool GetShortName (const char* fullname, char* shortname) { return false; }; + + void CacheOut (const char* path, bool ignoreLastDir = false) {}; + void AddEntry (const char* path, bool checkExists = false) {}; + void DeleteEntry (const char* path, bool ignoreLastDir = false) {}; + + void SetCurrentEntry (Bit16u entry) {}; + Bit16u GetCurrentEntry (void) { return 0; }; + + void EmptyCache (void) {}; + +public: + char basePath [CROSS_LEN]; + char dirPath [CROSS_LEN]; + DIR* srch_opendir; +}; + class DOS_Drive { public: DOS_Drive(); @@ -97,9 +209,12 @@ public: virtual bool FileStat(const char* name, FileStat_Block * const stat_block)=0; virtual Bit8u GetMediaByte(void)=0; virtual void SetDir(const char* path) { strcpy(curdir,path); }; + virtual void EmptyCache(void) { dirCache.EmptyCache(); }; char * GetInfo(void); char curdir[DOS_PATHLENGTH]; char info[256]; + + DOS_Drive_Cache dirCache; }; enum { OPEN_READ=0,OPEN_WRITE=1,OPEN_READWRITE=2 }; diff --git a/src/dos/drives.h b/src/dos/drives.h index 23ba9b7c..db882261 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -20,122 +20,10 @@ #define _DRIVES_H__ #include -#include -#include #include "dos_system.h" -#include "cross.h" - -#define MAX_OPENDIRS 16 bool WildFileCmp(const char * file, const char * wild); -class DOS_Drive_Cache { -public: - DOS_Drive_Cache (void); - DOS_Drive_Cache (const char* path); - ~DOS_Drive_Cache (void); - - typedef enum TDirSort { NOSORT, ALPHABETICAL, DIRALPHABETICAL, ALPHABETICALREV, DIRALPHABETICALREV }; - - void SetBaseDir (const char* path); - void SetDirSort (TDirSort sort) { sortDirType = sort; }; - bool OpenDir (const char* path, Bit16u& id); - bool ReadDir (Bit16u id, char* &result); - - void ExpandName (char* path); - char* GetExpandName (const char* path); - bool GetShortName (const char* fullname, char* shortname); - - void CacheOut (const char* path, bool ignoreLastDir = false); - void AddEntry (const char* path, bool checkExist = false); - void DeleteEntry (const char* path, bool ignoreLastDir = false); - - void EmptyCache (void); - - class CFileInfo { - public: - ~CFileInfo(void) { - for (Bit32u i=0; i fileList; - std::vector longNameList; - std::vector outputList; - }; - -private: - - bool RemoveTrailingDot (char* shortname); - Bit16s GetLongName (CFileInfo* info, char* shortname); - void CreateShortName (CFileInfo* dir, CFileInfo* info); - Bit16u CreateShortNameID (CFileInfo* dir, const char* name); - bool SetResult (CFileInfo* dir, char * &result, Bit16u entryNr); - bool IsCachedIn (CFileInfo* dir); - CFileInfo* FindDirInfo (const char* path, char* expandedPath); - bool RemoveSpaces (char* str); - bool OpenDir (CFileInfo* dir, char* path, Bit16u& id); - void CreateEntry (CFileInfo* dir, const char* name); - Bit16u GetFreeID (CFileInfo* dir); - void Clear (void); - - - CFileInfo* dirBase; - char dirPath [CROSS_LEN]; - char basePath [CROSS_LEN]; - bool dirFirstTime; - TDirSort sortDirType; - CFileInfo* save_dir; - char save_path [CROSS_LEN]; - char save_expanded [CROSS_LEN]; - - Bit16u srchNr; - CFileInfo* dirSearch [MAX_OPENDIRS]; - char dirSearchName [MAX_OPENDIRS]; - bool free [MAX_OPENDIRS]; - -}; - -class DOS_No_Drive_Cache { -public: - DOS_No_Drive_Cache (void) {}; - DOS_No_Drive_Cache (const char* path); - ~DOS_No_Drive_Cache (void) {}; - - typedef enum TDirSort { NOSORT, ALPHABETICAL, DIRALPHABETICAL, ALPHABETICALREV, DIRALPHABETICALREV }; - - void SetBaseDir (const char* path); - void SetDirSort (TDirSort sort) {}; - bool OpenDir (const char* path, Bit16u& id); - bool ReadDir (Bit16u id, char * &result); - - void ExpandName (char* path) {}; - char* GetExpandName (const char* path) { return (char*)path; }; - bool GetShortName (const char* fullname, char* shortname) { return false; }; - - void CacheOut (const char* path, bool ignoreLastDir = false) {}; - void AddEntry (const char* path, bool checkExists = false) {}; - void DeleteEntry (const char* path, bool ignoreLastDir = false) {}; - - void SetCurrentEntry (Bit16u entry) {}; - Bit16u GetCurrentEntry (void) { return 0; }; - - void EmptyCache (void) {}; - -public: - char basePath [CROSS_LEN]; - char dirPath [CROSS_LEN]; - DIR* srch_opendir; -}; - class localDrive : public DOS_Drive { public: localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid); @@ -154,8 +42,6 @@ public: virtual bool FileStat(const char* name, FileStat_Block * const stat_block); virtual Bit8u GetMediaByte(void); - DOS_Drive_Cache dirCache; - private: char basedir[CROSS_LEN]; From 20e5d26f6eababc9b9e55dc4a3984412ab662977 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 29 Mar 2003 20:16:28 +0000 Subject: [PATCH 0758/4131] changed includes to avoid macro redefinition Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@837 --- src/dos/drive_cache.cpp | 2 ++ src/dos/drive_local.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 22059186..01b55306 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -597,6 +597,8 @@ bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bit16u entryNr) // No Dir Cache, // **************************************************************************** +static DIR* srch_opendir = 0; + DOS_No_Drive_Cache::DOS_No_Drive_Cache(const char* path) { SetBaseDir(path); diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 2f4eb07e..bf84f433 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include "dosbox.h" #include "dos_inc.h" #include "drives.h" From c6bedc3bdf81a74c6ff5487718a4964e0a8f5b17 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 29 Mar 2003 20:17:24 +0000 Subject: [PATCH 0759/4131] remove DIR* from No_Drive_Cache to avoid macro redefinitions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@838 --- include/dos_system.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index dc0a3604..0ea54efe 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -19,11 +19,10 @@ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ -#include "dosbox.h" -#include "cross.h" #include #include -#include +#include "dosbox.h" +#include "cross.h" #define DOS_NAMELENGTH 12 #define DOS_NAMELENGTH_ASCII (DOS_NAMELENGTH+1) @@ -187,7 +186,6 @@ public: public: char basePath [CROSS_LEN]; char dirPath [CROSS_LEN]; - DIR* srch_opendir; }; class DOS_Drive { From 0988c1e4dc00fb297fa0767733d8b6685b070f74 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 30 Mar 2003 08:24:27 +0000 Subject: [PATCH 0760/4131] Fix calculation of milliseconds from the bios ticks value. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@839 --- src/dos/dos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 8f969a8c..97db2f76 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -301,7 +301,7 @@ static Bitu DOS_21Handler(void) { reg_ch=(Bit8u)(seconds/3600); reg_cl=(Bit8u)((seconds % 3600)/60); reg_dh=(Bit8u)(seconds % 60); - reg_dl=(Bit8u)((ticks % 20)*5); /* 0-19 ->0-95 */ + reg_dl=(Bit8u)(((ticks * 10) % 182)*100)/182; } break; case 0x2d: /* Set System Time */ From c7f8376088ccc8729f0b547ff4608ef32e20837d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 30 Mar 2003 10:50:20 +0000 Subject: [PATCH 0761/4131] Show error information when unable to open audio device. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@840 --- src/hardware/mixer.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index f92ab004..6bb6bc99 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -332,10 +332,14 @@ void MIXER_Init(Section* sec) { spec.samples=mixer.blocksize; mixer.tick_remain=0; - if (mixer.nosound || (SDL_OpenAudio(&spec, &obtained) < 0 )) { + if (mixer.nosound) { + LOG_MSG("MIXER:No Sound Mode Selected."); + mixer.tick_add=((mixer.freq) << MIXER_SHIFT)/1000; + TIMER_RegisterTickHandler(MIXER_Mix_NoSound); + } else if (SDL_OpenAudio(&spec, &obtained) <0 ) { + LOG_MSG("MIXER:Can't open audio: %s , running in nosound mode.",SDL_GetError()); mixer.tick_add=((mixer.freq) << MIXER_SHIFT)/1000; TIMER_RegisterTickHandler(MIXER_Mix_NoSound); - LOG_MSG("MIXER:Running in nosound mode."); } else { mixer.freq=obtained.freq; mixer.blocksize=obtained.samples; From f83ff4ea6e2f33e934ad04eb1e5ac17d01fe8f0b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 30 Mar 2003 10:51:01 +0000 Subject: [PATCH 0762/4131] Changed faulty #elif into #else Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@841 --- src/gui/midi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 692784ec..589a2416 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -80,7 +80,7 @@ MidiHandler Midi_none; #include "midi_win32.h" -#elif +#else #include "midi_oss.h" From 447094cfb3b45cc0acf566c27b2516e69f4d9348 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 30 Mar 2003 11:03:44 +0000 Subject: [PATCH 0763/4131] Default to using /dev/sequencer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@842 --- src/gui/midi_oss.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index d4a1c8a5..65500a6a 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -30,7 +30,7 @@ public: bool Open(const char * conf) { char devname[512]; if (conf && conf[0]) strncpy(devname,conf,512); - else strcpy(devname,"/dev/midi"); + else strcpy(devname,"/dev/sequencer"); char * devfind=(strrchr(devname,',')); if (devfind) { *devfind++=0; From c7f8e95cdb2841fe8fef132c6d83b156122888fc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 30 Mar 2003 12:37:33 +0000 Subject: [PATCH 0764/4131] midi_coreaudio.h added Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@843 --- src/gui/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 4ae4731d..83664b6d 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -2,5 +2,5 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libgui.a libgui_a_SOURCES = sdlmain.cpp render.cpp render_normal.h render_scale2x.h \ - midi.cpp midi_win32.h midi_oss.h + midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h From 09b7167fcf448351a8c665e1d9c9c0549147706a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 30 Mar 2003 20:59:42 +0000 Subject: [PATCH 0765/4131] Removal of intro command from shell Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@844 --- src/shell/shell.cpp | 27 +-------------------------- src/shell/shell_cmds.cpp | 7 ------- src/shell/shell_inc.h | 1 - 3 files changed, 1 insertion(+), 34 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 570c122f..455f528d 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -67,7 +67,7 @@ Bit32u DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn) { return 1; -} +} @@ -235,31 +235,6 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_DELETE_HELP","Removes files.\n"); MSG_Add("SHELL_CMD_COPY_HELP","Copy files.\n"); MSG_Add("SHELL_CMD_INTRO_HELP","Gives an introduction into dosbox\n"); - MSG_Add("SHELL_CMD_INTRO", -"Welcome to DOSBox, a x86 emulator with sound and graphics\n" -"DOSBox creates a shell for you which looks like old plain DOS\n" -"\n" -"Here are some commands to get you started:\n" -"Before you can use the files located on your own filesystem,\n" -"You have to mount the directory containing the files.\n" -"For MS Windows users:\n" -"mount c c:\\dosprog will create a C drive in dosbox with c:\\dosprog as contents.\n" -"\n" -"For linux users:\n" -"mount c /home/user/dosprog will do the same.\n" -"\n" -"Mac OS and others:\n" -"\n" -"I have no idea\n" -"\n" -"When the mount has succesfully completed you can type c: to go to your freshly\n" -"mounted C-drive. Typing dir there will show its contents. cd will allow you to\n" -"enter a directory (recognised by the [] in a directory listing).\n" -"You can run programs/files which end at .exe .bat and .com .\n" -"\n" -"DOSBox will stop/exit without a warning if an error occured!\n" - ); - /* Regular startup */ call_shellstop=CALLBACK_Allocate(); /* Setup the startup CS:IP to kill the last running machine when exitted */ diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 248f4c38..7d3fe73d 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -43,7 +43,6 @@ static SHELL_Cmd cmd_list[]={ "RENAME", 0, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP", "REN", 1, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP", "PAUSE", 0, &DOS_Shell::CMD_PAUSE, "SHELL_CMD_PAUSE_HELP", - "INTRO", 0, &DOS_Shell::CMD_INTRO, "SHELL_CMD_INTRO_HELP", /* "CHDIR", 0, &DOS_Shell::CMD_CHDIR, "Change Directory", "MKDIR", 0, &DOS_Shell::CMD_MKDIR, "Make Directory", @@ -521,9 +520,3 @@ void DOS_Shell::CMD_PAUSE(char * args){ DOS_ReadFile (STDIN,&c,&n); } -void DOS_Shell::CMD_INTRO(char* args) -{ - WriteOut(MSG_Get("SHELL_CMD_INTRO")); -// Bit8u c;Bit16u n=1; -// DOS_ReadFile (STDIN,&c,&n); -} diff --git a/src/shell/shell_inc.h b/src/shell/shell_inc.h index 703d5b04..21947803 100644 --- a/src/shell/shell_inc.h +++ b/src/shell/shell_inc.h @@ -80,7 +80,6 @@ public: void CMD_RENAME(char * args); void SyntaxError(void); void CMD_PAUSE(char * args); - void CMD_INTRO(char * args); /* The shell's variables */ Bit16u input_handle; BatchFile * bf; From 10be655e33cbf0a7ae882af906bb2efd5e7b0225 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 30 Mar 2003 21:00:35 +0000 Subject: [PATCH 0766/4131] Added intro.com on virtual drive Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@845 --- src/dos/dos_programs.cpp | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 92fa71b2..29d57d63 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -265,7 +265,7 @@ void RESCAN::Run(void) Bit8u drive = DOS_GetDefaultDrive(); if (Drives[drive]) { Drives[drive]->EmptyCache(); - WriteOut(MSG_Get("RESCAN_SUCCESS")); + WriteOut(MSG_Get("PROGRAM_RESCAN_SUCCESS")); } }; @@ -273,7 +273,16 @@ static void RESCAN_ProgramStart(Program * * make) { *make=new RESCAN; } +class INTRO : public Program { +public: + void Run(void) { + WriteOut(MSG_Get("PROGRAM_INTRO")); + } +}; +static void INTRO_ProgramStart(Program * * make) { + *make=new INTRO; +} void DOS_SetupPrograms(void) { /*Add Messages */ @@ -301,11 +310,34 @@ void DOS_SetupPrograms(void) { MSG_Add("MSCDEX_LIMITED_SUPPORT","MSCDEX: Mounted subdirectory: limited support.\n"); MSG_Add("MSCDEX_UNKNOWN_ERROR","MSCDEX: Failure: Unknown error.\n"); - MSG_Add("RESCAN_SUCCESS","Drive cache cleared.\n"); + MSG_Add("PROGRAM_RESCAN_SUCCESS","Drive cache cleared.\n"); + + MSG_Add("PROGRAM_INTRO", + "Welcome to DOSBox, an x86 emulator with sound and graphics.\n" + "DOSBox creates a shell for you which looks like old plain DOS.\n" + "\n" + "Here are some commands to get you started:\n" + "Before you can use the files located on your own filesystem,\n" + "You have to mount the directory containing the files.\n" + "For Windows:\n" + "mount c c:\\dosprog will create a C drive in dosbox with c:\\dosprog as contents.\n" + "\n" + "For other platfroms:\n" + "mount c /home/user/dosprog will do the same.\n" + "\n" + "When the mount has succesfully completed you can type c: to go to your freshly\n" + "mounted C-drive. Typing dir there will show its contents. cd will allow you to\n" + "enter a directory (recognised by the [] in a directory listing).\n" + "You can run programs/files which end with .exe .bat and .com .\n" + + "\n" + "DOSBox will stop/exit without a warning if an error occured!\n" + ); /*regular setup*/ PROGRAMS_MakeFile("MOUNT.COM",MOUNT_ProgramStart); PROGRAMS_MakeFile("MEM.COM",MEM_ProgramStart); PROGRAMS_MakeFile("LOADFIX.COM",LOADFIX_ProgramStart); PROGRAMS_MakeFile("RESCAN.COM",RESCAN_ProgramStart); + PROGRAMS_MakeFile("INTRO.COM",INTRO_ProgramStart); } From 32dff6253f51f423765fd3bb55acb4f950d02909 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 30 Mar 2003 21:12:15 +0000 Subject: [PATCH 0767/4131] Always set first 0x40 interrupts to default handler at startup. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@846 --- src/cpu/callback.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index f4bc04de..ce79268f 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -167,15 +167,13 @@ void CALLBACK_Init(Section* sec) { real_writeb((Bit16u)CB_SEG,(call_idle<<4)+13,0x38); real_writew((Bit16u)CB_SEG,(call_idle<<4)+14,call_idle); -#if C_DEBUG /* Setup all Interrupt to point to the default handler */ call_default=CALLBACK_Allocate(); CALLBACK_Setup(call_default,&default_handler,CB_IRET); /* Only setup default handler for first half of interrupt table */ - for (i=0;i<128;i++) { + for (i=0;i<0x40;i++) { real_writed(0,i*4,CALLBACK_RealPointer(call_default)); } -#endif } From fde8f9cf8e4e7651dc99141176b26a4fd59fffc2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 30 Mar 2003 22:41:27 +0000 Subject: [PATCH 0768/4131] Option for pcspeak generation rate Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@847 --- src/dosbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 452de4a4..47e63ac6 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -224,7 +224,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("speaker",&PCSPEAKER_Init); secprop->Add_bool("enabled",true); - secprop->Add_bool("sinewave",false); + secprop->Add_int("pcrate",22050); secprop->AddInitFunction(&TANDYSOUND_Init); secprop->Add_bool("tandy",false); From adf1c689e30335d3018049592a7517805179f67d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 30 Mar 2003 22:52:13 +0000 Subject: [PATCH 0769/4131] New pc-speaker code Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@848 --- src/hardware/pcspeaker.cpp | 259 +++++++++++++++++++++++-------------- 1 file changed, 165 insertions(+), 94 deletions(-) diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index f85f2891..44ebfc65 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -21,6 +21,7 @@ #include "mixer.h" #include "timer.h" #include "setup.h" +#include "pic.h" #ifndef PI @@ -31,117 +32,187 @@ #define SPKR_RATE 22050 #define SPKR_VOLUME 5000 -#define SPKR_SHIFT 16 +#define SPKR_SHIFT 10 -#define SIN_ENT 1024 -#define SIN_MAX (SIN_ENT << SPKR_SHIFT) - -#define FREQ_MAX (2 << SPKR_SHIFT) -#define FREQ_HALF (FREQ_MAX >> 1) - -struct Speaker { - Bitu freq_add; - Bitu freq_pos; - Bit16s volume; - MIXER_Channel * chan; - bool enabled; - bool realsound; - bool sinewave; - Bitu mode; - Bit16u buffer[SPKR_BUF]; - Bit16s table[SIN_ENT]; - Bitu buf_pos; +enum SPKR_MODE { + MODE_NONE,MODE_WAVE,MODE_DELAY,MODE_ONOFF,MODE_REAL, }; -static Speaker spkr; +static struct { + Bit16s volume; + MIXER_Channel * chan; + Bit16u buffer[SPKR_BUF]; + SPKR_MODE mode,old_mode; + struct { + Bit16s buf[SPKR_BUF]; + Bitu used; + } real; + struct { + Bitu index; + struct { + Bitu max,half; + } count,new_count; + } wave; + struct { + Bit16s buf[SPKR_BUF]; + Bitu pos; + } out; + struct { + Bitu index; + Bitu max; + } delay; + struct { + Bitu vol; + Bitu rate; + Bitu rate_conv; + Bitu tick_add; + } hw; + bool onoff; + Bitu buf_pos; +} spkr; - -void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode) { - spkr.mode=mode; - switch (mode) { - case 0: - if (cntr>72) cntr=72; - spkr.realsound=true; - if (spkr.buf_pos=spkr.wave.count.max) { + *stream++=+spkr.volume; + spkr.wave.index-=spkr.wave.count.max; + spkr.wave.count.max=spkr.wave.new_count.max; + spkr.wave.count.half=spkr.wave.new_count.half; + } else if (spkr.wave.index>spkr.wave.count.half) { + *stream++=-spkr.volume; + } else { + *stream++=+spkr.volume; + } + } + spkr.out.pos+=samples; + } + break; + case MODE_ONOFF: + { + Bit16s val=spkr.onoff ? spkr.volume : -spkr.volume; + for (Bitu i=0;i> 16]; + buf_pos+=buf_add; + } + spkr.out.pos+=samples; + break; + } + case MODE_DELAY: + { + for (Bitu i=0;i>16; + if (spkr.mode==MODE_NONE) MIXER_Enable(spkr.chan,true); + switch (mode) { + case 0: /* Mode 0 one shot, used with realsound */ + if (cntr>72) cntr=72; + if (spkr.mode!=MODE_REAL) GenerateSound(len); + spkr.mode=MODE_REAL; + if (spkr.real.used>16; + GenerateSound(len); + if (spkr.mode==MODE_NONE) MIXER_Enable(spkr.chan,true); + switch (mode) { + case 0: + if (spkr.mode==MODE_ONOFF && spkr.onoff) spkr.onoff=false; + else spkr.mode=MODE_NONE; + break; + case 1: + if (spkr.mode!=MODE_ONOFF) spkr.old_mode=spkr.mode; + spkr.mode=MODE_ONOFF; + spkr.onoff=false; + break; + case 2: + spkr.onoff=true; + if (spkr.mode!=MODE_ONOFF) spkr.old_mode=spkr.mode; + spkr.mode=MODE_ONOFF; + break; + case 3: + if (spkr.mode==MODE_ONOFF) spkr.mode=spkr.old_mode; + break; + }; } static void PCSPEAKER_CallBack(Bit8u * stream,Bit32u len) { - switch (spkr.mode) { - case 0: - /* Generate the "RealSound" */ - { - Bitu buf_add=(spkr.buf_pos<<16)/len; - Bitu buf_pos=0; - spkr.buf_pos=0;spkr.realsound=0; - while (len-->0) { - *(Bit16s*)(stream)=spkr.buffer[buf_pos >> 16]; - buf_pos+=buf_add; - stream+=2; - } - break; - } - case 3: - if (spkr.sinewave) while (len-->0) { - spkr.freq_pos+=spkr.freq_add; - spkr.freq_pos&=(SIN_MAX-1); - *(Bit16s*)(stream)=spkr.table[spkr.freq_pos>>SPKR_SHIFT]; - stream+=2; - } else while (len-->0) { - spkr.freq_pos+=spkr.freq_add; - if (spkr.freq_pos>=FREQ_MAX) spkr.freq_pos-=FREQ_MAX; - if (spkr.freq_pos>=FREQ_HALF) { - *(Bit16s*)(stream)=spkr.volume; - } else { - *(Bit16s*)(stream)=-spkr.volume; - } - stream+=2; - } - break; - case 4: - while (len-->0) { - if (spkr.freq_pos) { - *(Bit16s*)(stream)=spkr.volume; - spkr.freq_pos--; - } else { - *(Bit16s*)(stream)=-spkr.volume; - } - stream+=2; - } - break; - } + if (spkr.out.pos(sec); if(!section->Get_bool("enabled")) return; - spkr.sinewave=section->Get_bool("sinewave"); - spkr.chan=MIXER_AddChannel(&PCSPEAKER_CallBack,SPKR_RATE,"PC-SPEAKER"); + spkr.volume=SPKR_VOLUME; + spkr.old_mode=spkr.mode=MODE_NONE; + spkr.real.used=0; + spkr.out.pos=0; +// spkr.hw.vol=section->Get_int("volume"); + spkr.hw.rate=section->Get_int("pcrate"); + spkr.hw.rate_conv=(spkr.hw.rate<<16)/1000000; + spkr.hw.tick_add=(Bitu)((double)PIT_TICK_RATE*(double)(1 << SPKR_SHIFT)/(double)spkr.hw.rate); + spkr.wave.index=0; + spkr.wave.count.max=spkr.wave.new_count.max=0x10000 << SPKR_SHIFT; + spkr.wave.count.half=spkr.wave.new_count.half=(0x10000 << SPKR_SHIFT)/2; + + /* Register the sound channel */ + spkr.chan=MIXER_AddChannel(&PCSPEAKER_CallBack,spkr.hw.rate,"PC-SPEAKER"); MIXER_Enable(spkr.chan,false); MIXER_SetMode(spkr.chan,MIXER_16MONO); - spkr.volume=SPKR_VOLUME; - spkr.enabled=false; - spkr.realsound=false; - spkr.buf_pos=0; - /* Generate the sine wave */ - for (Bitu i=0;i Date: Sun, 30 Mar 2003 22:53:08 +0000 Subject: [PATCH 0770/4131] Changes for new pc-speaker effects. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@849 --- include/mixer.h | 3 +-- src/hardware/keyboard.cpp | 8 ++------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/include/mixer.h b/include/mixer.h index 3c02d93a..3144a8be 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -39,7 +39,6 @@ void MIXER_Enable(MIXER_Channel * chan,bool enable); /* PC Speakers functions, tightly related to the timer functions */ -void PCSPEAKER_Enable(bool enable); void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode); - +void PCSPEAKER_SetType(Bitu mode); diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index b0f053c9..373483c6 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -195,17 +195,13 @@ static Bit8u read_p61(Bit32u port) { } static void write_p61(Bit32u port,Bit8u val) { - port_61_data=val; /* if (val & 128) if (!keyb.read_active) KEYBOARD_ReadBuffer(); Keys should get acknowledged just by reading 0x60. Perhaps disable controller when bit 7=1 */ - if ((val & 3)==3) { - PCSPEAKER_Enable(true); - } else { - PCSPEAKER_Enable(false); - } + if ((port_61_data ^val) & 3) PCSPEAKER_SetType(val & 3); + port_61_data=val; } static void write_p64(Bit32u port,Bit8u val) { From ae7a6f81edcae1de65f70275c93bcb7c321f67fc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 30 Mar 2003 23:00:14 +0000 Subject: [PATCH 0771/4131] Handle unmapped SDL keys as a known key, best we can do. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@850 --- src/gui/sdlmain.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index e0c549e2..56edcc2d 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -391,11 +391,11 @@ static void HandleKey(SDL_KeyboardEvent * key) { case SDLK_KP_ENTER:code=KBD_kpenter;break; case SDLK_KP_PERIOD:code=KBD_kpperiod;break; -// case SDLK_:code=key_;break; /* Special Keys */ default: -//TODO maybe give warning for keypress unknown - return; + code=KBD_1; + LOG(LOG_ERROR|LOG_KEYBOARD,"Unhandled SDL keysym %d",key->keysym.sym); + break; } /* Check the modifiers */ Bitu mod= From b859a063c022246afaf9b22d47f0c0f745bf8cf6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 31 Mar 2003 08:06:57 +0000 Subject: [PATCH 0772/4131] Saving of pit modes for better switching Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@851 --- src/hardware/pcspeaker.cpp | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 44ebfc65..85a255af 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -38,12 +38,17 @@ enum SPKR_MODE { MODE_NONE,MODE_WAVE,MODE_DELAY,MODE_ONOFF,MODE_REAL, }; +/* TODO + Maybe interpolate at the moment we switch between on/off + Keep track of postion of speaker conus in ONOFF mode +*/ static struct { Bit16s volume; MIXER_Channel * chan; Bit16u buffer[SPKR_BUF]; - SPKR_MODE mode,old_mode; + SPKR_MODE mode; + SPKR_MODE pit_mode; struct { Bit16s buf[SPKR_BUF]; Bitu used; @@ -68,11 +73,10 @@ static struct { Bitu rate_conv; Bitu tick_add; } hw; - bool onoff; + bool onoff,enabled; Bitu buf_pos; } spkr; -/* TODO Maybe interpolate at the moment we switch between on/off */ static void GenerateSound(Bitu size) { while (spkr.out.pos72) cntr=72; if (spkr.mode!=MODE_REAL) GenerateSound(len); - spkr.mode=MODE_REAL; + spkr.pit_mode=MODE_REAL; if (spkr.real.used(sec); if(!section->Get_bool("enabled")) return; spkr.volume=SPKR_VOLUME; - spkr.old_mode=spkr.mode=MODE_NONE; + spkr.mode=MODE_NONE; + spkr.pit_mode=MODE_WAVE; spkr.real.used=0; spkr.out.pos=0; + spkr.onoff=false; // spkr.hw.vol=section->Get_int("volume"); spkr.hw.rate=section->Get_int("pcrate"); spkr.hw.rate_conv=(spkr.hw.rate<<16)/1000000; From 9192bc4561f09ae50362513439e88ae379b0a271 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 31 Mar 2003 08:30:10 +0000 Subject: [PATCH 0773/4131] No support for GUS Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@852 --- src/dosbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 47e63ac6..5426aa97 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -217,7 +217,7 @@ void DOSBOX_Init(void) { secprop->Add_bool("cms",false); secprop->Add_int("cmsrate",22050); - secprop=control->AddSection_prop("gus",&GUS_Init); +// secprop=control->AddSection_prop("gus",&GUS_Init); secprop=control->AddSection_prop("disney",&DISNEY_Init); secprop->Add_bool("enabled",true); From 92a9a74ff28a1aaf7700add332cd3d73e9293967 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 31 Mar 2003 08:38:52 +0000 Subject: [PATCH 0774/4131] added manpage Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@853 --- dosbox.1 | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 dosbox.1 diff --git a/dosbox.1 b/dosbox.1 new file mode 100644 index 00000000..805b8539 --- /dev/null +++ b/dosbox.1 @@ -0,0 +1,60 @@ +.\" Hey, EMACS: -*- nroff -*- +.TH DOSBOX 1 "March 31, 2003" +.\" Please adjust this date whenever revising the manpage. +.SH NAME +dosbox \- an x86/DOS emulator with sound/graphics primarily for games +.SH SYNOPSIS +.B dosbox +[\fB-fullscreen\fR] +[\fB-conf\fR \fIconfigfile\fR] +[\fB-lang\fR \fIlangfile\fR] +[\fBfile\fR] +[\fB-c\fR \fIcommand1\fR <\fIcommand2\fR>...] +.br +.SH DESCRIPTION +This manual page briefly documents +\fBdosbox\fR, an x86/DOS emulator capable of running many games. +.TP +The optional \fBfile\fR argument should be a DOS executable or a directory. If it is a dos executable (.com .exe .bat) the program will run automatically. If it is a directory, a DOS session will run with the directory mounted as C:. +.SH OPTIONS +A summary of options is included below. +.TP +\fB-fullscreen\fR +Start DOSBox in fullscreen mode +.TP +\fB-c\fR \fIcommand 1\fR [\fIcommand 2\fR] ... +Run one or more DOS commands after starting \fBdosbox\fR. If an executable is +also specified, these commands will be executed before running the program. +.TP +\fB-conf\fR \fIconfigfile\fR +Start \fBdosbox\fR with the options specified in \fIconfigfile\fR +.TP +\fB-lang\fR \fIlangfile\fR +Start \fBdosbox\fR with the language specified in \fIlangfile\fR +.SH INTERNAL COMMANDS +.B dosbox +supports most of the DOS commands found in command.com. In addition, the +following extra commands are available: +.TP +\fBMOUNT\fR [\fB-t\fR \fItype\fR] [\fB-size\fR \fIsize\fR] \fBdriveletter\fR \fBsourcedirectory\fR [\fB-aspi\fR] +Map \fBsourcedirectory\fR to \fBdriveletter\fR. +\fItype\fR may be \fIdir\fR for a hard drive, \fIfloppy\fR for a floppy +drive or \fIcdrom\fR for a cdrom. \fIsize\fR specifies the size of the volume. +You can force ASPI mode for a cdrom with \fB-aspi\fR. +.TP +\fBMEM\fR +Display the amount of free memory +.TP +\fBCONFIG\fR [\fB-writeconf\fR] [\fB-writelang\fR] \fBfile\fR +Write the current configuration or language settings to \fBfile\fR +.SH FILES +Configuration and language files use a format similar to Windows .ini files. If a file named +\fBdosbox.conf\fR is found in the current directory, it will be automatically loaded. +.SH BUGS +Not all DOS programs work properly. Notably, any program that uses protected mode will not work at all. +DOSBox will exit without warning if an error occured. +.SH SEE ALSO +The README in /usr/share/doc/dosbox +.SH AUTHOR +This manual page was written by Peter Veenstra and James Oakley , +for the Debian system (but may be used by others). From 3af5e9ad2d0afcc03a5c35658bb452cb42b1be32 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 31 Mar 2003 08:54:30 +0000 Subject: [PATCH 0775/4131] Moved dosbox manpage in docs subdir and added that in automake file. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@854 --- Makefile.am | 2 +- dosbox.1 | 60 ----------------------------------------------------- 2 files changed, 1 insertion(+), 61 deletions(-) delete mode 100644 dosbox.1 diff --git a/Makefile.am b/Makefile.am index 48f9f473..cb2acfbb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ # Main Makefile for DOSBox EXTRA_DIST = autogen.sh -SUBDIRS = src include visualc +SUBDIRS = src include visualc docs diff --git a/dosbox.1 b/dosbox.1 deleted file mode 100644 index 805b8539..00000000 --- a/dosbox.1 +++ /dev/null @@ -1,60 +0,0 @@ -.\" Hey, EMACS: -*- nroff -*- -.TH DOSBOX 1 "March 31, 2003" -.\" Please adjust this date whenever revising the manpage. -.SH NAME -dosbox \- an x86/DOS emulator with sound/graphics primarily for games -.SH SYNOPSIS -.B dosbox -[\fB-fullscreen\fR] -[\fB-conf\fR \fIconfigfile\fR] -[\fB-lang\fR \fIlangfile\fR] -[\fBfile\fR] -[\fB-c\fR \fIcommand1\fR <\fIcommand2\fR>...] -.br -.SH DESCRIPTION -This manual page briefly documents -\fBdosbox\fR, an x86/DOS emulator capable of running many games. -.TP -The optional \fBfile\fR argument should be a DOS executable or a directory. If it is a dos executable (.com .exe .bat) the program will run automatically. If it is a directory, a DOS session will run with the directory mounted as C:. -.SH OPTIONS -A summary of options is included below. -.TP -\fB-fullscreen\fR -Start DOSBox in fullscreen mode -.TP -\fB-c\fR \fIcommand 1\fR [\fIcommand 2\fR] ... -Run one or more DOS commands after starting \fBdosbox\fR. If an executable is -also specified, these commands will be executed before running the program. -.TP -\fB-conf\fR \fIconfigfile\fR -Start \fBdosbox\fR with the options specified in \fIconfigfile\fR -.TP -\fB-lang\fR \fIlangfile\fR -Start \fBdosbox\fR with the language specified in \fIlangfile\fR -.SH INTERNAL COMMANDS -.B dosbox -supports most of the DOS commands found in command.com. In addition, the -following extra commands are available: -.TP -\fBMOUNT\fR [\fB-t\fR \fItype\fR] [\fB-size\fR \fIsize\fR] \fBdriveletter\fR \fBsourcedirectory\fR [\fB-aspi\fR] -Map \fBsourcedirectory\fR to \fBdriveletter\fR. -\fItype\fR may be \fIdir\fR for a hard drive, \fIfloppy\fR for a floppy -drive or \fIcdrom\fR for a cdrom. \fIsize\fR specifies the size of the volume. -You can force ASPI mode for a cdrom with \fB-aspi\fR. -.TP -\fBMEM\fR -Display the amount of free memory -.TP -\fBCONFIG\fR [\fB-writeconf\fR] [\fB-writelang\fR] \fBfile\fR -Write the current configuration or language settings to \fBfile\fR -.SH FILES -Configuration and language files use a format similar to Windows .ini files. If a file named -\fBdosbox.conf\fR is found in the current directory, it will be automatically loaded. -.SH BUGS -Not all DOS programs work properly. Notably, any program that uses protected mode will not work at all. -DOSBox will exit without warning if an error occured. -.SH SEE ALSO -The README in /usr/share/doc/dosbox -.SH AUTHOR -This manual page was written by Peter Veenstra and James Oakley , -for the Debian system (but may be used by others). From 732df657f41efafef36d0e460551f842b4e202a3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 31 Mar 2003 08:57:49 +0000 Subject: [PATCH 0776/4131] Manpages Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@855 --- docs/Makefile.am | 8 +++++++ docs/dosbox.1 | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 docs/Makefile.am create mode 100644 docs/dosbox.1 diff --git a/docs/Makefile.am b/docs/Makefile.am new file mode 100644 index 00000000..17738546 --- /dev/null +++ b/docs/Makefile.am @@ -0,0 +1,8 @@ +# Main Makefile for DOSBox + +man_MANS = dosbox.1 +EXTRA_DIST = $(man_MANS) + + + + diff --git a/docs/dosbox.1 b/docs/dosbox.1 new file mode 100644 index 00000000..805b8539 --- /dev/null +++ b/docs/dosbox.1 @@ -0,0 +1,60 @@ +.\" Hey, EMACS: -*- nroff -*- +.TH DOSBOX 1 "March 31, 2003" +.\" Please adjust this date whenever revising the manpage. +.SH NAME +dosbox \- an x86/DOS emulator with sound/graphics primarily for games +.SH SYNOPSIS +.B dosbox +[\fB-fullscreen\fR] +[\fB-conf\fR \fIconfigfile\fR] +[\fB-lang\fR \fIlangfile\fR] +[\fBfile\fR] +[\fB-c\fR \fIcommand1\fR <\fIcommand2\fR>...] +.br +.SH DESCRIPTION +This manual page briefly documents +\fBdosbox\fR, an x86/DOS emulator capable of running many games. +.TP +The optional \fBfile\fR argument should be a DOS executable or a directory. If it is a dos executable (.com .exe .bat) the program will run automatically. If it is a directory, a DOS session will run with the directory mounted as C:. +.SH OPTIONS +A summary of options is included below. +.TP +\fB-fullscreen\fR +Start DOSBox in fullscreen mode +.TP +\fB-c\fR \fIcommand 1\fR [\fIcommand 2\fR] ... +Run one or more DOS commands after starting \fBdosbox\fR. If an executable is +also specified, these commands will be executed before running the program. +.TP +\fB-conf\fR \fIconfigfile\fR +Start \fBdosbox\fR with the options specified in \fIconfigfile\fR +.TP +\fB-lang\fR \fIlangfile\fR +Start \fBdosbox\fR with the language specified in \fIlangfile\fR +.SH INTERNAL COMMANDS +.B dosbox +supports most of the DOS commands found in command.com. In addition, the +following extra commands are available: +.TP +\fBMOUNT\fR [\fB-t\fR \fItype\fR] [\fB-size\fR \fIsize\fR] \fBdriveletter\fR \fBsourcedirectory\fR [\fB-aspi\fR] +Map \fBsourcedirectory\fR to \fBdriveletter\fR. +\fItype\fR may be \fIdir\fR for a hard drive, \fIfloppy\fR for a floppy +drive or \fIcdrom\fR for a cdrom. \fIsize\fR specifies the size of the volume. +You can force ASPI mode for a cdrom with \fB-aspi\fR. +.TP +\fBMEM\fR +Display the amount of free memory +.TP +\fBCONFIG\fR [\fB-writeconf\fR] [\fB-writelang\fR] \fBfile\fR +Write the current configuration or language settings to \fBfile\fR +.SH FILES +Configuration and language files use a format similar to Windows .ini files. If a file named +\fBdosbox.conf\fR is found in the current directory, it will be automatically loaded. +.SH BUGS +Not all DOS programs work properly. Notably, any program that uses protected mode will not work at all. +DOSBox will exit without warning if an error occured. +.SH SEE ALSO +The README in /usr/share/doc/dosbox +.SH AUTHOR +This manual page was written by Peter Veenstra and James Oakley , +for the Debian system (but may be used by others). From 58b16c1aa29b7d0a2999ebf9f9bf9c0301bc6b3d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 31 Mar 2003 09:08:20 +0000 Subject: [PATCH 0777/4131] create the docs/makefile Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@856 --- configure.in | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.in b/configure.in index af0872fb..adb4ad8c 100644 --- a/configure.in +++ b/configure.in @@ -107,4 +107,5 @@ src/platform/Makefile src/platform/visualc/Makefile visualc/Makefile include/Makefile +docs/Makefile ]) From 1d510b4a243b058de748ae7a2896e1d76f1c8854 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 31 Mar 2003 10:10:13 +0000 Subject: [PATCH 0778/4131] fixed compilation under gcc2.95 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@857 --- src/gui/sdlmain.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 56edcc2d..7aeda676 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -15,6 +15,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include #include From 302cf8e94a995b615fcce74b4820a96a81aef027 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 1 Apr 2003 22:16:19 +0000 Subject: [PATCH 0779/4131] New cpu core for some testing. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@859 --- src/cpu/core_full.cpp | 75 ++++ src/cpu/core_full/ea_lookup.h | 115 ++++++ src/cpu/core_full/load.h | 397 +++++++++++++++++++++ src/cpu/core_full/loadwrite.h | 72 ++++ src/cpu/core_full/main.h | 0 src/cpu/core_full/op.h | 403 +++++++++++++++++++++ src/cpu/core_full/optable.h | 637 ++++++++++++++++++++++++++++++++++ src/cpu/core_full/save.h | 106 ++++++ src/cpu/core_full/string.h | 169 +++++++++ src/cpu/core_full/support.h | 159 +++++++++ src/cpu/cpu.cpp | 33 +- 11 files changed, 2165 insertions(+), 1 deletion(-) create mode 100644 src/cpu/core_full.cpp create mode 100644 src/cpu/core_full/ea_lookup.h create mode 100644 src/cpu/core_full/load.h create mode 100644 src/cpu/core_full/loadwrite.h create mode 100644 src/cpu/core_full/main.h create mode 100644 src/cpu/core_full/op.h create mode 100644 src/cpu/core_full/optable.h create mode 100644 src/cpu/core_full/save.h create mode 100644 src/cpu/core_full/string.h create mode 100644 src/cpu/core_full/support.h diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp new file mode 100644 index 00000000..b4a0146b --- /dev/null +++ b/src/cpu/core_full.cpp @@ -0,0 +1,75 @@ +#include "dosbox.h" + +#include "pic.h" +#include "regs.h" +#include "cpu.h" +#include "debug.h" +#include "inout.h" +#include "callback.h" + +typedef PhysPt EAPoint; +#define SegBase(c) SegPhys(c) +#define LoadMb(off) mem_readb(off) +#define LoadMw(off) mem_readw(off) +#define LoadMd(off) mem_readd(off) + +#define LoadMbs(off) (Bit8s)(LoadMb(off)) +#define LoadMws(off) (Bit16s)(LoadMw(off)) +#define LoadMds(off) (Bit32s)(LoadMd(off)) + +#define SaveMb(off,val) mem_writeb(off,val) +#define SaveMw(off,val) mem_writew(off,val) +#define SaveMd(off,val) mem_writed(off,val) + +#define LoadD(reg) reg +#define SaveD(reg,val) reg=val + +static EAPoint IPPoint; + +#include "core_full/loadwrite.h" +#include "core_full/support.h" +#include "core_full/optable.h" +#include "core_full/ea_lookup.h" +#include "instructions.h" + +static bool had_code[16][16]; + +static INLINE void DecodeModRM(void) { + inst.rm=Fetchb(); + inst.rm_index=(inst.rm >> 3) & 7; + inst.rm_eai=inst.rm&07; + inst.rm_mod=inst.rm>>6; + /* Decode address of mod/rm if needed */ + if (inst.rm<0xc0) inst.rm_eaa=RMAddress(); +} + + +Bitu Full_DeCode(void) { + LoadIP(); + while (CPU_Cycles>0) { +#if C_DEBUG + cycle_count++; +#endif + CPU_Cycles--; +restartopcode: + inst.entry=(inst.entry & 0xffffff00) | Fetchb(); + if (inst.entry<0x100) { + *(bool *)(&had_code[0][0]+inst.entry)=true; + } + + inst.code=OpCodeTable[inst.entry]; + #include "core_full/load.h" + #include "core_full/op.h" + #include "core_full/save.h" +nextopcode: + inst.prefix=0; + inst.entry=0; + } + SaveIP(); + return 0; +} + + +void CPU_Core_Full_Start(void) { + cpudecoder=&Full_DeCode; +} \ No newline at end of file diff --git a/src/cpu/core_full/ea_lookup.h b/src/cpu/core_full/ea_lookup.h new file mode 100644 index 00000000..c9b8d62c --- /dev/null +++ b/src/cpu/core_full/ea_lookup.h @@ -0,0 +1,115 @@ + + + +static EAPoint RMAddress(void) { + EAPoint seg_base; + Bit16u off; + switch ((inst.rm_mod<<3)|inst.rm_eai) { + case 0x00: + off=reg_bx+reg_si; + seg_base=SegBase(ds); + break; + case 0x01: + off=reg_bx+reg_di; + seg_base=SegBase(ds); + break; + case 0x02: + off=reg_bp+reg_si; + seg_base=SegBase(ss); + break; + case 0x03: + off=reg_bp+reg_di; + seg_base=SegBase(ss); + break; + case 0x04: + off=reg_si; + seg_base=SegBase(ds); + break; + case 0x05: + off=reg_di; + seg_base=SegBase(ds); + break; + case 0x06: + off=Fetchw(); + seg_base=SegBase(ds); + break; + case 0x07: + off=reg_bx; + seg_base=SegBase(ds); + break; + + case 0x08: + off=reg_bx+reg_si+Fetchbs(); + seg_base=SegBase(ds); + break; + case 0x09: + off=reg_bx+reg_di+Fetchbs(); + seg_base=SegBase(ds); + break; + case 0x0a: + off=reg_bp+reg_si+Fetchbs(); + seg_base=SegBase(ss); + break; + case 0x0b: + off=reg_bp+reg_di+Fetchbs(); + seg_base=SegBase(ss); + break; + case 0x0c: + off=reg_si+Fetchbs(); + seg_base=SegBase(ds); + break; + case 0x0d: + off=reg_di+Fetchbs(); + seg_base=SegBase(ds); + break; + case 0x0e: + off=reg_bp+Fetchbs(); + seg_base=SegBase(ss); + break; + case 0x0f: + off=reg_bx+Fetchbs(); + seg_base=SegBase(ds); + break; + + case 0x10: + off=reg_bx+reg_si+Fetchws(); + seg_base=SegBase(ds); + break; + case 0x11: + off=reg_bx+reg_di+Fetchws(); + seg_base=SegBase(ds); + break; + case 0x12: + off=reg_bp+reg_si+Fetchws(); + seg_base=SegBase(ss); + break; + case 0x13: + off=reg_bp+reg_di+Fetchws(); + seg_base=SegBase(ss); + break; + case 0x14: + off=reg_si+Fetchws(); + seg_base=SegBase(ds); + break; + case 0x15: + off=reg_di+Fetchws(); + seg_base=SegBase(ds); + break; + case 0x16: + off=reg_bp+Fetchws(); + seg_base=SegBase(ss); + break; + case 0x17: + off=reg_bx+Fetchws(); + seg_base=SegBase(ds); + break; + } + inst.rm_off=off; + if (inst.prefix & PREFIX_SEG) { + return inst.seg.base+off; + }else return seg_base+off; +} + + + + diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h new file mode 100644 index 00000000..c3c8a23a --- /dev/null +++ b/src/cpu/core_full/load.h @@ -0,0 +1,397 @@ +switch (inst.code.load) { +/* General loading */ + case L_MODRM: + DecodeModRM(); +l_MODRMswitch: + switch (inst.code.extra) { +/* Byte */ + case M_Ib: + inst.op1.d=Fetchb(); + break; + case M_EbIb: + inst.op2.d=Fetchb(); + case M_Eb: + if (inst.rm<0xc0) inst.op1.d=LoadMb(inst.rm_eaa); + else inst.op1.d=reg_8(inst.rm_eai); + break; + case M_EbGb: + if (inst.rm<0xc0) inst.op1.d=LoadMb(inst.rm_eaa); + else inst.op1.d=reg_8(inst.rm_eai); + inst.op2.d=reg_8(inst.rm_index); + break; + case M_GbEb: + if (inst.rm<0xc0) inst.op2.d=LoadMb(inst.rm_eaa); + else inst.op2.d=reg_8(inst.rm_eai); + case M_Gb: + inst.op1.d=reg_8(inst.rm_index);; + break; +/* Word */ + case M_Iw: + inst.op1.d=Fetchw(); + break; + case M_EwxGwx: + inst.op2.ds=(Bit16s)reg_16(inst.rm_index); + goto l_M_Ewx; + case M_EwxIbx: + inst.op2.ds=Fetchbs(); + goto l_M_Ewx; + case M_EwxIwx: + inst.op2.ds=Fetchws(); +l_M_Ewx: + if (inst.rm<0xc0) inst.op1.ds=(Bit16s)LoadMw(inst.rm_eaa); + else inst.op1.ds=(Bit16s)reg_16(inst.rm_eai); + break; + case M_EwIbx: + inst.op2.ds=Fetchbs(); + goto l_M_Ew; + case M_EwIw: + inst.op2.d=Fetchw(); + goto l_M_Ew; + case M_EwGw: + inst.op2.d=reg_16(inst.rm_index); +l_M_Ew: + case M_Ew: + if (inst.rm<0xc0) inst.op1.d=LoadMw(inst.rm_eaa); + else inst.op1.d=reg_16(inst.rm_eai); + break; + case M_GwEw: + if (inst.rm<0xc0) inst.op2.d=LoadMw(inst.rm_eaa); + else inst.op2.d=reg_16(inst.rm_eai); + case M_Gw: + inst.op1.d=reg_16(inst.rm_index);; + break; +/* DWord */ + case M_Id: + inst.op1.d=Fetchd(); + break; + case M_EdIbx: + inst.op2.ds=Fetchbs(); + goto l_M_Ed; + case M_EdId: + inst.op2.d=Fetchd(); + goto l_M_Ed; + case M_EdGd: + inst.op2.d=reg_32(inst.rm_index); +l_M_Ed: + case M_Ed: + if (inst.rm<0xc0) inst.op1.d=LoadMd(inst.rm_eaa); + else inst.op1.d=reg_32(inst.rm_eai); + break; + case M_GdEd: + if (inst.rm<0xc0) inst.op2.d=LoadMd(inst.rm_eaa); + else inst.op2.d=reg_32(inst.rm_eai); + case M_Gd: + inst.op1.d=reg_32(inst.rm_index); + break; +/* Others */ + + case M_SEG: + //TODO Check for limit + inst.op1.d=SegValue((SegNames)inst.rm_index); + break; + case M_Efw: + if (inst.rm>=0xC0) { + LOG(LOG_CPU|LOG_ERROR,"MODRM:Illegal M_Efw "); + goto nextopcode; + } + inst.op1.d=LoadMw(inst.rm_eaa); + inst.op2.d=LoadMw(inst.rm_eaa+2); + break; + case M_Efd: + if (inst.rm>=0xc0) { + LOG(LOG_CPU|LOG_ERROR,"MODRM:Illegal M_Efw "); + goto nextopcode; + } + inst.op1.d=LoadMd(inst.rm_eaa); + inst.op2.d=LoadMw(inst.rm_eaa+4); + break; + case M_EA: + inst.op1.d=inst.rm_off; + break; + case M_POPw: + inst.op1.d = Pop_16(); + break; + case M_POPd: + inst.op1.d = Pop_32(); + break; + case M_GRP: + inst.code=Groups[inst.code.op][inst.rm_index]; + goto l_MODRMswitch; + case M_GRP_Ib: + inst.op2.d=Fetchb(); + inst.code=Groups[inst.code.op][inst.rm_index]; + goto l_MODRMswitch; + case M_GRP_CL: + inst.op2.d=reg_cl; + inst.code=Groups[inst.code.op][inst.rm_index]; + goto l_MODRMswitch; + case M_GRP_1: + inst.op2.d=1; + inst.code=Groups[inst.code.op][inst.rm_index]; + goto l_MODRMswitch; + + /* Should continue with normal handler afterwards */ + case 0: + LOG(LOG_CPU|LOG_ERROR,"MODRM:Unhandled load %d entry %x",inst.code.extra,inst.entry); + break; + default: + LOG(LOG_CPU|LOG_ERROR,"MODRM:Unhandled load %d entry %x",inst.code.extra,inst.entry); + break; + } + break; + case L_POPw: + inst.op1.d = Pop_16(); + break; + case L_POPd: + inst.op1.d = Pop_32(); + break; + case L_POPfw: + inst.op1.d = Pop_16(); + inst.op2.d = Pop_16(); + break; + case L_POPfd: + inst.op1.d = Pop_32(); + inst.op2.d = Pop_16(); + break; + case L_Ib: + inst.op1.d=Fetchb(); + break; + case L_Ibx: + inst.op1.ds=Fetchbs(); + break; + case L_Iw: + inst.op1.d=Fetchw(); + break; + case L_Iwx: + inst.op1.ds=Fetchws(); + break; + case L_Idx: + case L_Id: + inst.op1.d=Fetchd(); + break; + case L_Ifw: + inst.op1.d=Fetchw(); + inst.op2.d=Fetchw(); + break; + +/* Direct load of registers */ + case L_REGbIb: + inst.op2.d=Fetchb(); + case L_REGb: + inst.op1.d=reg_8(inst.code.extra); + break; + case L_REGwIw: + inst.op2.d=Fetchw(); + case L_REGw: + inst.op1.d=reg_16(inst.code.extra); + break; + case L_REGdId: + inst.op2.d=Fetchd(); + case L_REGd: + inst.op1.d=reg_32(inst.code.extra); + break; + case L_FLG: + inst.op1.d= (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); + break; + case L_SEG: + inst.op1.d=SegValue((SegNames)inst.code.extra); + break; +/* Depending on addressize */ + case L_OP: + if (inst.prefix & PREFIX_ADDR) { + inst.rm_eaa=Fetchd(); + } else { + inst.rm_eaa=Fetchw(); + } + if (inst.prefix & PREFIX_SEG) { + inst.rm_eaa+=inst.seg.base; + } else { + inst.rm_eaa+=SegBase(ds); + } + break; + /* Special cases */ + case L_DOUBLE: + inst.entry|=0x100; + goto restartopcode; + case L_PRESEG: + inst.prefix|=PREFIX_SEG; + inst.seg.base=SegBase((SegNames)inst.code.extra); + goto restartopcode; + case L_PREREPNE: + inst.prefix|=PREFIX_REP; + inst.repz=false; + goto restartopcode; + case L_PREREP: + inst.prefix|=PREFIX_REP; + inst.repz=true; + goto restartopcode; + case L_PREOP: + inst.entry|=0x200; + goto restartopcode; + case L_VAL: + inst.op1.d=inst.code.extra; + break; + case L_INTO: + if (!get_OF()) goto nextopcode; + inst.op1.d=4; + break; + case L_IRETw: + inst.op1.d=Pop_16(); + inst.op2.d=Pop_16(); + { + Bitu temp=Pop_16(); + Save_Flagsw(temp); + } + break; +/* Direct operations */ + case L_STRING: + #include "string.h" + goto nextopcode; + case D_PUSHAw: + Push_16(reg_ax);Push_16(reg_cx);Push_16(reg_dx);Push_16(reg_bx); + Push_16(reg_sp);Push_16(reg_bp);Push_16(reg_si);Push_16(reg_di); + goto nextopcode; + case D_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); + goto nextopcode; + case D_POPAw: + reg_di=Pop_16();reg_si=Pop_16();reg_bp=Pop_16();Pop_16();//Don't save SP + reg_bx=Pop_16();reg_dx=Pop_16();reg_cx=Pop_16();reg_ax=Pop_16(); + goto nextopcode; + case D_POPAd: + reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP + reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32(); + goto nextopcode; + case D_SETALC: + reg_al = get_CF() ? 0xFF : 0; + goto nextopcode; + case D_XLAT: + if (inst.prefix & PREFIX_SEG) reg_al=LoadMb(inst.seg.base+reg_bx+reg_al); + else reg_al=LoadMb(SegBase(ds)+reg_bx+reg_al); + goto nextopcode; + case D_CBW: + reg_ax=(Bit8s)reg_al; + goto nextopcode; + case D_CWD: + if (reg_ax & 0x8000) reg_dx=0xffff; + else reg_dx=0; + goto nextopcode; + case D_CDQ: + if (reg_eax & 0x80000000) reg_edx=0xffffffff; + else reg_edx=0; + goto nextopcode; + case D_CLI: + flags.intf=false; + goto nextopcode; + case D_STI: + flags.intf=true; + if (flags.intf && PIC_IRQCheck) { + SaveIP(); + PIC_runIRQs(); + LoadIP(); + } + goto nextopcode; + case D_STC: + flags.cf=true; + if (flags.type!=t_CF) flags.prev_type=flags.type; + flags.type=t_CF; + goto nextopcode; + case D_CLC: + flags.cf=false; + if (flags.type!=t_CF) flags.prev_type=flags.type; + flags.type=t_CF; + goto nextopcode; + case D_CMC: + flags.cf=!get_CF(); + if (flags.type!=t_CF) flags.prev_type=flags.type; + flags.type=t_CF; + goto nextopcode; + case D_CLD: + flags.df=false; + goto nextopcode; + case D_STD: + flags.df=true; + goto nextopcode; + case D_NOP: + goto nextopcode; + case D_ENTERw: + { + Bit16u bytes=Fetchw();Bit8u level=Fetchb(); + Push_16(reg_bp);reg_bp=reg_sp;reg_sp-=bytes; + EAPoint reader=SegBase(ss)+reg_bp; + for (Bit8u i=1;i0x09) || get_AF()) { + reg_al+=0x06; + flags.af=true; + } else { + flags.af=false; + } + flags.cf=get_CF(); + if ((reg_al > 0x9F) || flags.cf) { + reg_al+=0x60; + flags.cf=true; + } else { + flags.cf=false; + } + flags.sf=(reg_al&0x80)>0; + flags.zf=(reg_al==0); + flags.type=t_UNKNOWN; + goto nextopcode; + case D_DAS: + if (((reg_al & 0x0f) > 9) || get_AF()) { + reg_al-=6; + flags.af=true; + } else { + flags.af=false; + } + if ((reg_al>0x9f) || get_CF()) { + reg_al-=0x60; + flags.cf=true; + } else { + flags.cf=false; + } + flags.type=t_UNKNOWN; + goto nextopcode; + case D_AAA: + if (get_AF() || ((reg_al & 0xf) > 9)) + { + reg_al += 6; + reg_ah += 1; + flags.af=true; + flags.cf=true; + } else { + flags.af=false; + flags.cf=false; + } + reg_al &= 0x0F; + flags.type=t_UNKNOWN; + goto nextopcode; + case D_AAS: + if (((reg_al & 0x0f)>9) || get_AF()) { + reg_ah--; + if (reg_al < 6) reg_ah--; + reg_al=(reg_al-6) & 0xF; + flags.af=flags.cf=true; + } else { + flags.af=flags.cf=false; + } + reg_al&=0xf; + flags.type=t_UNKNOWN; + goto nextopcode; + default: + LOG(LOG_CPU|LOG_ERROR,"LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry); + break; +} + diff --git a/src/cpu/core_full/loadwrite.h b/src/cpu/core_full/loadwrite.h new file mode 100644 index 00000000..1b165da8 --- /dev/null +++ b/src/cpu/core_full/loadwrite.h @@ -0,0 +1,72 @@ +static INLINE void SaveIP(void) { + Bitu left=IPPoint-SegBase(cs); + reg_eip=left; +} + +static INLINE void LoadIP(void) { + IPPoint=SegBase(cs)+reg_eip; +} + + +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 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; \ + \ +} + diff --git a/src/cpu/core_full/main.h b/src/cpu/core_full/main.h new file mode 100644 index 00000000..e69de29b diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h new file mode 100644 index 00000000..b2800dcf --- /dev/null +++ b/src/cpu/core_full/op.h @@ -0,0 +1,403 @@ +/* Do the actual opcode */ +switch (inst.code.op) { + case t_ADDb: case t_ADDw: case t_ADDd: + flags.var1.d=inst.op1.d; + flags.var2.d=inst.op2.d; + inst.op1.d=flags.result.d=flags.var1.d + flags.var2.d; + flags.type=inst.code.op; + break; + case t_CMPb: case t_CMPw: case t_CMPd: + case t_SUBb: case t_SUBw: case t_SUBd: + flags.var1.d=inst.op1.d; + flags.var2.d=inst.op2.d; + inst.op1.d=flags.result.d=flags.var1.d - flags.var2.d; + flags.type=inst.code.op; + break; + case t_ORb: case t_ORw: case t_ORd: + flags.var1.d=inst.op1.d; + flags.var2.d=inst.op2.d; + inst.op1.d=flags.result.d=flags.var1.d | flags.var2.d; + flags.type=inst.code.op; + break; + case t_XORb: case t_XORw: case t_XORd: + flags.var1.d=inst.op1.d; + flags.var2.d=inst.op2.d; + inst.op1.d=flags.result.d=flags.var1.d ^ flags.var2.d; + flags.type=inst.code.op; + break; + case t_TESTb: case t_TESTw: case t_TESTd: + case t_ANDb: case t_ANDw: case t_ANDd: + flags.var1.d=inst.op1.d; + flags.var2.d=inst.op2.d; + inst.op1.d=flags.result.d=flags.var1.d & flags.var2.d; + flags.type=inst.code.op; + break; + case t_ADCb: case t_ADCw: case t_ADCd: + flags.oldcf=get_CF(); + flags.var1.d=inst.op1.d; + flags.var2.d=inst.op2.d; + inst.op1.d=flags.result.d=flags.var1.d + flags.var2.d + flags.oldcf; + flags.type=inst.code.op; + break; + case t_SBBb: case t_SBBw: case t_SBBd: + flags.oldcf=get_CF(); + flags.var1.d=inst.op1.d; + flags.var2.d=inst.op2.d; + inst.op1.d=flags.result.d=flags.var1.d - flags.var2.d - flags.oldcf; + flags.type=inst.code.op; + break; + case t_INCb: case t_INCw: case t_INCd: + flags.cf=get_CF(); + inst.op1.d=flags.result.d=inst.op1.d+1; + flags.type=inst.code.op; + break; + case t_DECb: case t_DECw: case t_DECd: + flags.cf=get_CF(); + inst.op1.d=flags.result.d=inst.op1.d-1; + flags.type=inst.code.op; + break; +/* Using the instructions.h defines */ + case t_ROLb: + ROLB(inst.op1.b,inst.op2.b,LoadD,SaveD); + break; + case t_ROLw: + ROLW(inst.op1.w,inst.op2.b,LoadD,SaveD); + break; + case t_ROLd: + ROLD(inst.op1.d,inst.op2.b,LoadD,SaveD); + break; + + case t_RORb: + RORB(inst.op1.b,inst.op2.b,LoadD,SaveD); + break; + case t_RORw: + RORW(inst.op1.w,inst.op2.b,LoadD,SaveD); + break; + case t_RORd: + RORD(inst.op1.d,inst.op2.b,LoadD,SaveD); + break; + + case t_RCLb: + RCLB(inst.op1.b,inst.op2.b,LoadD,SaveD); + break; + case t_RCLw: + RCLW(inst.op1.w,inst.op2.b,LoadD,SaveD); + break; + case t_RCLd: + RCLD(inst.op1.d,inst.op2.b,LoadD,SaveD); + break; + + case t_RCRb: + RCRB(inst.op1.b,inst.op2.b,LoadD,SaveD); + break; + case t_RCRw: + RCRW(inst.op1.w,inst.op2.b,LoadD,SaveD); + break; + case t_RCRd: + RCRD(inst.op1.d,inst.op2.b,LoadD,SaveD); + break; + + case t_SHLb: + SHLB(inst.op1.b,inst.op2.b,LoadD,SaveD); + break; + case t_SHLw: + SHLW(inst.op1.w,inst.op2.b,LoadD,SaveD); + break; + case t_SHLd: + SHLD(inst.op1.d,inst.op2.b,LoadD,SaveD); + break; + + case t_SHRb: + SHRB(inst.op1.b,inst.op2.b,LoadD,SaveD); + break; + case t_SHRw: + SHRW(inst.op1.w,inst.op2.b,LoadD,SaveD); + break; + case t_SHRd: + SHRD(inst.op1.d,inst.op2.b,LoadD,SaveD); + break; + + case t_SARb: + SARB(inst.op1.b,inst.op2.b,LoadD,SaveD); + break; + case t_SARw: + SARW(inst.op1.w,inst.op2.b,LoadD,SaveD); + break; + case t_SARd: + SARD(inst.op1.d,inst.op2.b,LoadD,SaveD); + break; + + case t_NEGb: + flags.var1.b=inst.op1.b; + inst.op1.b=flags.result.b=0-inst.op1.b; + flags.type=t_NEGb; + break; + case t_NEGw: + flags.var1.w=inst.op1.w; + inst.op1.w=flags.result.w=0-inst.op1.w; + flags.type=t_NEGw; + break; + case t_NEGd: + flags.var1.d=inst.op1.d; + inst.op1.d=flags.result.d=0-inst.op1.d; + flags.type=t_NEGd; + break; + + case O_NOT: + inst.op1.d=~inst.op1.d; + break; + + /* Special instructions */ + case O_IMULRw: + inst.op1.ds=inst.op1.ds*inst.op2.ds; + flags.type=t_MUL; + if ((inst.op1.ds> -32768) && (inst.op1.ds<32767)) { + flags.cf=false;flags.of=false; + } else { + flags.cf=true;flags.of=true; + } + break; + case O_MULb: + flags.type=t_MUL; + reg_ax=reg_al*inst.op1.b; + flags.cf=flags.of=((reg_ax & 0xff00) !=0); + goto nextopcode; + case O_MULw: + { + Bit32u tempu=(Bit32u)reg_ax*(Bit32u)inst.op1.w; + reg_ax=(Bit16u)(tempu); + reg_dx=(Bit16u)(tempu >> 16); + flags.type=t_MUL; + flags.cf=flags.of=(reg_dx !=0); + goto nextopcode; + } + case O_MULd: + { + Bit64u tempu=(Bit64u)reg_eax*(Bit64u)inst.op1.d; + reg_eax=(Bit32u)(tempu); + reg_edx=(Bit32u)(tempu >> 32); + flags.type=t_MUL; + flags.cf=flags.of=(reg_edx !=0); + goto nextopcode; + } + case O_IMULb: + flags.type=t_MUL; + reg_ax=((Bit8s)reg_al)*inst.op1.bs; + flags.cf=flags.of=!((reg_ax & 0xff80)==0xff80 || (reg_ax & 0xff80)==0x0000); + goto nextopcode; + case O_IMULw: + { + Bit32s temps=(Bit16s)reg_ax*inst.op1.ws; + reg_ax=(Bit16s)(temps); + reg_dx=(Bit16s)(temps >> 16); + flags.type=t_MUL; + flags.cf=flags.of=!((temps & 0xffffff80)==0xffffff80 || (temps & 0xffffff80)==0x0000); + goto nextopcode; + } + case O_IMULd: + { + Bit64s temps=(Bit64s)reg_eax*(Bit64s)inst.op1.ds; + reg_eax=(Bit32s)(temps); + reg_edx=(Bit32s)(temps >> 32); + flags.type=t_MUL; + 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; + } + goto nextopcode; + } + case O_DIVb: + { + if (!inst.op1.b) goto doint; + Bitu val=reg_ax;Bitu quo=val/inst.op1.b; + reg_ah=(Bit8u)(val % inst.op1.b); + reg_al=(Bit8u)quo; + if (quo!=reg_al) { inst.op1.b=0;goto doint;} + goto nextopcode; + } + case O_DIVw: + { + if (!inst.op1.w) goto doint; + Bitu val=(reg_dx<<16)|reg_ax;Bitu quo=val/inst.op1.w; + reg_dx=(Bit16u)(val % inst.op1.w); + reg_ax=(Bit16u)quo; + if (quo!=reg_ax) { inst.op1.b=0;goto doint;} + goto nextopcode; + } + case O_IDIVb: + { + if (!inst.op1.b) goto doint; + Bits val=(Bit16s)reg_ax;Bits quo=val/inst.op1.bs; + reg_ah=(Bit8s)(val % inst.op1.bs); + reg_al=(Bit8s)quo; + if (quo!=(Bit8s)reg_al) { inst.op1.b=0;goto doint;} + goto nextopcode; + } + case O_IDIVw: + { + if (!inst.op1.w) goto doint; + Bits val=(Bit32s)((reg_dx<<16)|reg_ax);Bits quo=val/inst.op1.ws; + reg_dx=(Bit16u)(val % inst.op1.ws); + reg_ax=(Bit16s)quo; + if (quo!=(Bit16s)reg_ax) { inst.op1.b=0;goto doint;} + goto nextopcode; + } + case O_AAM: + reg_ah=reg_al / inst.op1.b; + reg_al=reg_al % inst.op1.b; + flags.type=t_UNKNOWN; + flags.sf=(reg_ah & 0x80) > 0; + flags.zf=(reg_ax == 0); + //TODO PF + flags.pf=0; + goto nextopcode; + case O_AAD: + reg_al=reg_ah*inst.op1.b+reg_al; + reg_ah=0; + flags.cf=(reg_al>=0x80); + flags.zf=(reg_al==0); + //TODO PF + flags.type=t_UNKNOWN; + goto nextopcode; + + case O_C_O: inst.cond=get_OF(); break; + case O_C_NO: inst.cond=!get_OF(); break; + case O_C_B: inst.cond=get_CF(); break; + case O_C_NB: inst.cond=!get_CF(); break; + case O_C_Z: inst.cond=get_ZF(); break; + case O_C_NZ: inst.cond=!get_ZF(); break; + case O_C_BE: inst.cond=get_CF() || get_ZF(); break; + case O_C_NBE: inst.cond=!get_CF() && !get_ZF(); break; + case O_C_S: inst.cond=get_SF(); break; + case O_C_NS: inst.cond=!get_SF(); break; + case O_C_P: inst.cond=get_PF(); break; + case O_C_NP: inst.cond=!get_PF(); break; + case O_C_L: inst.cond=get_SF() != get_OF(); break; + case O_C_NL: inst.cond=get_SF() == get_OF(); break; + case O_C_LE: inst.cond=get_ZF() || (get_SF() != get_OF()); break; + case O_C_NLE: inst.cond=(get_SF() == get_OF()) && !get_ZF(); break; + + case O_ALOP: + reg_al=LoadMb(inst.rm_eaa); + goto nextopcode; + case O_AXOP: + reg_ax=LoadMw(inst.rm_eaa); + goto nextopcode; + case O_EAXOP: + reg_eax=LoadMd(inst.rm_eaa); + goto nextopcode; + case O_OPAL: + SaveMb(inst.rm_eaa,reg_al); + goto nextopcode; + case O_OPAX: + SaveMw(inst.rm_eaa,reg_ax); + goto nextopcode; + case O_OPEAX: + SaveMd(inst.rm_eaa,reg_eax); + goto nextopcode; + case O_SEGDS: + inst.code.extra=ds; + break; + case O_SEGES: + inst.code.extra=es; + break; + case O_SEGFS: + inst.code.extra=fs; + break; + case O_SEGGS: + inst.code.extra=gs; + break; + + + case O_LOOP: + if (--reg_cx) break; + goto nextopcode; + case O_LOOPZ: + if (--reg_cx && !get_ZF()) break; + goto nextopcode; + case O_LOOPNZ: + if (--reg_cx && get_ZF()) break; + goto nextopcode; + case O_JCXZ: + if (reg_cx) goto nextopcode; + break; + case O_XCHG_AX: + { + Bit16u temp=reg_ax; + reg_ax=inst.op1.w; + inst.op1.w=temp; + break; + } + case O_XCHG_EAX: + { + Bit32u temp=reg_eax; + reg_eax=inst.op1.d; + inst.op1.d=temp; + break; + } + case O_CALL_N: + SaveIP(); + Push_16(reg_ip); + break; + case O_CALL_F: + Push_16(SegValue(cs)); + SaveIP(); + Push_16(reg_ip); + break; +doint: + case O_INT: + SaveIP(); +#if C_DEBUG + if (inst.entry==0xcc) if (DEBUG_Breakpoint()) return 1; + else if (DEBUG_IntBreakpoint(inst.op1.b)) return 1; +#endif + Interrupt(inst.op1.b); + LoadIP(); + break; + case O_INb: + reg_al=IO_Read(inst.op1.d); + goto nextopcode; + case O_INw: + reg_ax=IO_Read(inst.op1.d) | (IO_Read(inst.op1.d+1) << 8); + goto nextopcode; + case O_INd: + reg_eax=IO_Read(inst.op1.d) | (IO_Read(inst.op1.d+1) << 8) | (IO_Read(inst.op1.d+2) << 16) | (IO_Read(inst.op1.d+3) << 24); + goto nextopcode; + case O_OUTb: + IO_Write(inst.op1.d,reg_al); + goto nextopcode; + case O_OUTw: + IO_Write(inst.op1.d+0,(Bit8u)reg_ax); + IO_Write(inst.op1.d+1,(Bit8u)(reg_ax >> 8)); + goto nextopcode; + case O_OUTd: + IO_Write(inst.op1.d+0,(Bit8u)reg_eax); + IO_Write(inst.op1.d+1,(Bit8u)(reg_eax >> 8)); + IO_Write(inst.op1.d+2,(Bit8u)(reg_eax >> 16)); + IO_Write(inst.op1.d+3,(Bit8u)(reg_eax >> 24)); + goto nextopcode; + case O_CBACK: + if (inst.op1.d0;flags.pf =(inst.op1.d & 0x004)>0; \ + flags.af =(inst.op1.d & 0x010)>0;flags.zf =(inst.op1.d & 0x040)>0; \ + flags.sf =(inst.op1.d & 0x080)>0; + break; + case S_FLGw: + Save_Flagsw(inst.op1.w); + break; + case 0: + break; + default: + LOG(LOG_ERROR|LOG_CPU,"SAVE:Unhandled code %d entry %X",inst.code.save,inst.entry); +} diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h new file mode 100644 index 00000000..8c42542e --- /dev/null +++ b/src/cpu/core_full/string.h @@ -0,0 +1,169 @@ +{ + EAPoint si_base,di_base; + Bitu si_index,di_index; + Bitu add_mask; + Bitu count,count_max; + Bits add_index; + bool restart=false; + + if (inst.prefix & PREFIX_SEG) si_base=inst.seg.base; + else si_base=SegBase(ds); + di_base=SegBase(es); + if (inst.prefix & PREFIX_ADDR) { + add_mask=0; + si_index=reg_esi;di_index=reg_edi; + count=reg_ecx; + } else { + add_mask=0xFFFF; + si_index=reg_si; + di_index=reg_di; + count=reg_cx; + } + if (!(inst.prefix & PREFIX_REP)) { + count=1; + } + + add_index=flags.df ? -1 : 1; + if (count) switch (inst.code.op) { + case R_OUTSB: + for (;count>0;count--) { + IO_Write(reg_dx,LoadMb(si_base+si_index)); + si_index=(si_index+add_index) & add_mask; + } + break; + case R_OUTSW: + add_index<<=1; + for (;count>0;count--) { + IO_Write(reg_dx,LoadMb(si_base+si_index)); + IO_Write(reg_dx+1,LoadMb(si_base+si_index+1)); + si_index=(si_index+add_index) & add_mask; + } + break; + case R_STOSB: + for (;count>0;count--) { + SaveMb(di_base+di_index,reg_al); + di_index=(di_index+add_index) & add_mask; + } + break; + case R_STOSW: + add_index<<=1; + for (;count>0;count--) { + SaveMw(di_base+di_index,reg_ax); + di_index=(di_index+add_index) & add_mask; + } + break; + case R_STOSD: + add_index<<=2; + for (;count>0;count--) { + SaveMd(di_base+di_index,reg_eax); + di_index=(di_index+add_index) & add_mask; + } + break; + case R_MOVSB: + for (;count>0;count--) { + SaveMb(di_base+di_index,LoadMb(si_base+si_index)); + di_index=(di_index+add_index) & add_mask; + si_index=(si_index+add_index) & add_mask; + } + break; + case R_MOVSW: + add_index<<=1; + for (;count>0;count--) { + SaveMw(di_base+di_index,LoadMw(si_base+si_index)); + di_index=(di_index+add_index) & add_mask; + si_index=(si_index+add_index) & add_mask; + } + break; + case R_MOVSD: + add_index<<=2; + for (;count>0;count--) { + SaveMd(di_base+di_index,LoadMd(si_base+si_index)); + di_index=(di_index+add_index) & add_mask; + si_index=(si_index+add_index) & add_mask; + } + break; + case R_LODSB: + for (;count>0;count--) { + reg_al=LoadMb(si_base+si_index); + si_index=(si_index+add_index) & add_mask; + } + break; + case R_LODSW: + add_index<<=1; + for (;count>0;count--) { + reg_ax=LoadMw(si_base+si_index); + si_index=(si_index+add_index) & add_mask; + } + break; + case R_LODSD: + add_index<<=2; + for (;count>0;count--) { + reg_eax=LoadMd(si_base+si_index); + si_index=(si_index+add_index) & add_mask; + } + break; + case R_SCASB: + { + Bit8u val2; + for (;count>0;) { + count--; + val2=LoadMb(di_base+di_index); + di_index=(di_index+add_index) & add_mask; + if ((reg_al==val2)!=inst.repz) break; + } + CMPB(reg_al,val2,LoadD,0); + } + break; + case R_SCASW: + { + add_index<<=1;Bit16u val2; + for (;count>0;) { + count--; + val2=LoadMw(di_base+di_index); + di_index=(di_index+add_index) & add_mask; + if ((reg_ax==val2)!=inst.repz) break; + } + CMPW(reg_ax,val2,LoadD,0); + } + break; + case R_CMPSB: + { + Bit8u val1,val2; + for (;count>0;) { + count--; + val1=LoadMb(si_base+si_index); + val2=LoadMb(di_base+di_index); + si_index=(si_index+add_index) & add_mask; + di_index=(di_index+add_index) & add_mask; + if ((val1==val2)!=inst.repz) break; + } + CMPB(val1,val2,LoadD,0); + } + break; + case R_CMPSW: + { + add_index<<=1;Bit16u val1,val2; + for (;count>0;) { + count--; + val1=LoadMw(si_base+si_index); + val2=LoadMw(di_base+di_index); + si_index=(si_index+add_index) & add_mask; + di_index=(di_index+add_index) & add_mask; + if ((val1==val2)!=inst.repz) break; + } + CMPW(val1,val2,LoadD,0); + } + break; + default: + LOG(LOG_CPU|LOG_ERROR,"Unhandled string %d entry %X",inst.code.op,inst.entry); + } + /* Clean up after certain amount of instructions */ + reg_esi&=(~add_mask); + reg_esi|=(si_index & add_mask); + reg_edi&=(~add_mask); + reg_edi|=(di_index & add_mask); + if (inst.prefix & PREFIX_REP) { + reg_ecx&=(~add_mask); + reg_ecx|=(count & add_mask); + } +} diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h new file mode 100644 index 00000000..7dcee792 --- /dev/null +++ b/src/cpu/core_full/support.h @@ -0,0 +1,159 @@ +enum { + L_N=0, + L_SKIP, + /* Grouped ones using MOD/RM */ + L_MODRM, + + L_Ib,L_Iw,L_Id, + L_Ibx,L_Iwx,L_Idx, //Sign extend + L_Ifw,L_Ifd, + L_OP, + + L_REGb,L_REGw,L_REGd, + L_REGbIb,L_REGwIw,L_REGdId, + L_POPw,L_POPd, + L_POPfw,L_POPfd, + L_SEG, + + + + L_FLG,L_INTO, + + L_VAL, + L_PRESEG, + L_DOUBLE, + L_PREOP,L_PREADD,L_PREREP,L_PREREPNE, + L_STRING, + + L_IRETw,L_IRETd, +/* Direct ones */ + D_PUSHAw,D_PUSHAd, + D_POPAw,D_POPAd, + D_DAA,D_DAS, + D_AAA,D_AAS, + D_CBW,D_CWD,D_CDQ, + D_SETALC, + D_XLAT, + D_CLI,D_STI,D_STC,D_CLC,D_CMC,D_CLD,D_STD, + D_NOP, + D_ENTERw,D_ENTERd, + D_LEAVEw,D_LEAVEd, + L_ERROR, +}; + + +enum { + O_N=t_LASTFLAG, + O_COND, + O_XCHG_AX,O_XCHG_EAX, + O_IMULRw,O_IMULRd, + O_BOUNDw,O_BOUNDd, + O_CALL_N,O_CALL_F, + O_OPAL,O_ALOP, + O_OPAX,O_AXOP, + O_OPEAX,O_EAXOP, + O_INT, + O_SEGDS,O_SEGES,O_SEGFS,O_SEGGS, + O_LOOP,O_LOOPZ,O_LOOPNZ,O_JCXZ, + O_INb,O_INw,O_INd, + O_OUTb,O_OUTw,O_OUTd, + + O_NOT,O_AAM,O_AAD, + O_MULb,O_MULw,O_MULd, + O_IMULb,O_IMULw,O_IMULd, + O_DIVb,O_DIVw,O_DIVd, + O_IDIVb,O_IDIVw,O_IDIVd, + O_CBACK, + + O_C_O ,O_C_NO ,O_C_B ,O_C_NB ,O_C_Z ,O_C_NZ ,O_C_BE ,O_C_NBE, + O_C_S ,O_C_NS ,O_C_P ,O_C_NP ,O_C_L ,O_C_NL ,O_C_LE ,O_C_NLE, +}; + +enum { + S_N=0, + S_C_Eb, + S_Eb,S_Gb,S_EbGb, + S_Ew,S_Gw,S_EwGw, + S_Ed,S_Gd,S_EdGd, + + + S_REGb,S_REGw,S_REGd, + S_PUSHw,S_PUSHd, + S_SEGI, + S_SEGm, + S_SEGGw,S_SEGGd, + + + S_ADDIP,S_C_ADDIP, + + S_FLGb,S_FLGw,S_FLGd, + S_IP,S_IPIw, + S_CSIP,S_CSIPIw, + +}; + +enum { + R_OUTSB,R_OUTSW,R_OUTSD, + R_INSB,R_INSW,R_INSD, + R_MOVSB,R_MOVSW,R_MOVSD, + R_LODSB,R_LODSW,R_LODSD, + R_STOSB,R_STOSW,R_STOSD, + R_SCASB,R_SCASW,R_SCASD, + R_CMPSB,R_CMPSW,R_CMPSD, +}; + +enum { + M_None=0, + M_Eb,M_Gb,M_EbGb,M_GbEb, + M_Ew,M_Gw,M_EwGw,M_GwEw,M_EwxGwx, + M_Ed,M_Gd,M_EdGd,M_GdEd, + M_EbIb, + M_EwIw,M_EwIbx,M_EwxIbx,M_EwxIwx, + M_EdId,M_EdIbx, + + M_Efw,M_Efd, + + M_Ib,M_Iw,M_Id, + + + M_SEG,M_EA, + M_GRP, + M_GRP_Ib,M_GRP_CL,M_GRP_1, + + M_POPw,M_POPd, +}; + +struct OpCode { + Bit8u load,op,save,extra; +}; + +static struct { + Bitu entry; + Bitu entry_default; + Bit8u rm; + EAPoint rm_eaa; + Bitu rm_off; + Bitu rm_eai; + Bitu rm_index; + Bitu rm_mod; + OpCode code; + union { + Bit8u b;Bit8s bs; + Bit16u w;Bit16s ws; + Bit32u d;Bit32s ds; + } op1,op2; + Bitu new_flags; + struct { + EAPoint base; + } seg; + bool cond; + bool repz; + Bitu prefix; +} inst; + + +#define PREFIX_NONE 0x0 +#define PREFIX_SEG 0x1 +#define PREFIX_ADDR 0x2 +#define PREFIX_REP 0x4 + diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 854d3834..2a44b651 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -23,7 +23,34 @@ #include "keyboard.h" #include "setup.h" -//Regs regs; +#pragma pack(1) +struct Descriptor { + 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 d :1; + Bit32u g :1; + Bit32u base_24_31 :8; +}; +#pragma pack() + +struct CPUBlock { + + + struct { + PhysPt phys_base; + Bit32u base; + Bit16u limit; + } gdt,idt; +}; + + Flag_Info flags; @@ -136,9 +163,13 @@ void Interrupt(Bit8u num) { void CPU_Real_16_Slow_Start(void); +void CPU_Core_Full_Start(void); + + void SetCPU16bit() { CPU_Real_16_Slow_Start(); +// CPU_Core_Full_Start(); } From 4a441be91fef0edee5e82f5e5113c8a5183e0436 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 1 Apr 2003 22:20:00 +0000 Subject: [PATCH 0780/4131] Add files for other core Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@860 --- visualc/dosbox.dsp | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index cb541c3c..a05f882a 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -128,12 +128,56 @@ SOURCE=..\src\cpu\core_16\support.h SOURCE=..\src\cpu\core_16\table_ea.h # End Source File # End Group +# Begin Group "core_full" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\src\cpu\core_full\ea_lookup.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_full\load.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_full\loadwrite.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_full\main.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_full\op.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_full\optable.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_full\save.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_full\string.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_full\support.h +# End Source File +# End Group # Begin Source File SOURCE=..\src\cpu\callback.cpp # End Source File # Begin Source File +SOURCE=..\src\cpu\core_full.cpp +# End Source File +# Begin Source File + SOURCE=..\src\cpu\cpu.cpp # End Source File # Begin Source File From 2f3689cd7ea92702af4dcec57489c896d7f6dd33 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 2 Apr 2003 15:31:06 +0000 Subject: [PATCH 0781/4131] Change Segment order Some new defines for register indexes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@861 --- include/regs.h | 62 +++++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/include/regs.h b/include/regs.h index 2c3954f9..cc7e601b 100644 --- a/include/regs.h +++ b/include/regs.h @@ -41,7 +41,7 @@ struct Segment { }; -enum SegNames { cs=0,ds,es,fs,gs,ss}; +enum SegNames { es=0,cs,ss,ds,fs,gs}; union GenReg32 { Bit32u dword[1]; @@ -97,11 +97,17 @@ INLINE void SegSet16(Bitu index,Bit16u val) { } -enum REG_NUM { - REG_NUM_AX, REG_NUM_CX, REG_NUM_DX, REG_NUM_BX, - REG_NUM_SP, REG_NUM_BP, REG_NUM_SI, REG_NUM_DI +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]) @@ -110,37 +116,37 @@ enum REG_NUM { #define reg_32(reg) (cpu_regs.regs[(reg)].dword[DW_INDEX]) -#define reg_al cpu_regs.regs[REG_NUM_AX].byte[BL_INDEX] -#define reg_ah cpu_regs.regs[REG_NUM_AX].byte[BH_INDEX] -#define reg_ax cpu_regs.regs[REG_NUM_AX].word[W_INDEX] -#define reg_eax cpu_regs.regs[REG_NUM_AX].dword[DW_INDEX] +#define reg_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[REG_NUM_BX].byte[BL_INDEX] -#define reg_bh cpu_regs.regs[REG_NUM_BX].byte[BH_INDEX] -#define reg_bx cpu_regs.regs[REG_NUM_BX].word[W_INDEX] -#define reg_ebx cpu_regs.regs[REG_NUM_BX].dword[DW_INDEX] +#define reg_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[REG_NUM_CX].byte[BL_INDEX] -#define reg_ch cpu_regs.regs[REG_NUM_CX].byte[BH_INDEX] -#define reg_cx cpu_regs.regs[REG_NUM_CX].word[W_INDEX] -#define reg_ecx cpu_regs.regs[REG_NUM_CX].dword[DW_INDEX] +#define reg_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[REG_NUM_DX].byte[BL_INDEX] -#define reg_dh cpu_regs.regs[REG_NUM_DX].byte[BH_INDEX] -#define reg_dx cpu_regs.regs[REG_NUM_DX].word[W_INDEX] -#define reg_edx cpu_regs.regs[REG_NUM_DX].dword[DW_INDEX] +#define reg_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[REG_NUM_SI].word[W_INDEX] -#define reg_esi cpu_regs.regs[REG_NUM_SI].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[REG_NUM_DI].word[W_INDEX] -#define reg_edi cpu_regs.regs[REG_NUM_DI].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[REG_NUM_SP].word[W_INDEX] -#define reg_esp cpu_regs.regs[REG_NUM_SP].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[REG_NUM_BP].word[W_INDEX] -#define reg_ebp cpu_regs.regs[REG_NUM_BP].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] From 6fcd5cc659755105959bc98043c12fb20faabd4b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 2 Apr 2003 15:33:47 +0000 Subject: [PATCH 0782/4131] Changes for flag layout and some new support #defines Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@862 --- include/cpu.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index f6f22814..9209b525 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -38,7 +38,8 @@ void SetCPU16bit(); //Types of Flag changing instructions enum { - t_ADDb=0,t_ADDw,t_ADDd, + t_UNKNOWN=0, + t_ADDb,t_ADDw,t_ADDd, t_ORb,t_ORw,t_ORd, t_ADCb,t_ADCw,t_ADCd, t_SBBb,t_SBBw,t_SBBd, @@ -62,8 +63,8 @@ enum { t_DSHLw,t_DSHLd, t_DSHRw,t_DSHRd, t_MUL,t_DIV, - t_UNKNOWN, t_NOTDONE, + t_LASTFLAG }; void Interrupt(Bit8u num); @@ -76,6 +77,19 @@ bool get_SF(void); bool get_OF(void); bool get_PF(void); + +#define FLAG_CF 0x0001 +#define FLAG_PF 0x0004 +#define FLAG_AF 0x0010 +#define FLAG_ZF 0x0040 +#define FLAG_SF 0x0080 +#define FLAG_TF 0x0100 +#define FLAG_IF 0x0200 +#define FLAG_DF 0x0400 +#define FLAG_OF 0x0800 + + + #define LoadCF flags.cf=get_CF(); #define LoadZF flags.zf=get_ZF(); #define LoadSF flags.sf=get_SF(); From 2bada3655d7c7645e0876b6a138ebabb0d13eaa7 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 3 Apr 2003 11:02:43 +0000 Subject: [PATCH 0783/4131] Fixed bug in dev_Con::write - use background attribute only if ansi is enabled. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@863 --- src/dos/dev_con.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 6059a861..1a0fb976 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -109,7 +109,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { Bit16u count=0; Bitu i; Bit8s col,row; - static bool ansiwarned=false; + static bool ansi_enabled=false; while (*size>count) { if (!ansi.esc){ @@ -119,16 +119,17 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { /* start the sequence */ ansi.esc=true; count++; - if(!ansiwarned) { + if(!ansi_enabled) { LOG(LOG_IOCTL,"ANSI sequences detected. enabling ansi support"); /* maybe LOG_MSG */ - ansiwarned=true; + ansi_enabled=true; } continue; } else { - INT10_TeletypeOutput(data[count],ansi.attr,true,0); - count++; - continue; + // pass attribute only if ansi is enabled + INT10_TeletypeOutput(data[count],ansi.attr,ansi_enabled,0); + count++; + continue; }; }; /* ansi.esc=true */ From 8a3d68cbaa119632565a1b0887439112a8cafa88 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 3 Apr 2003 11:03:58 +0000 Subject: [PATCH 0784/4131] Added ClearAnsi in Constructor Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@864 --- src/dos/dev_con.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 1a0fb976..9e838043 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -361,6 +361,7 @@ device_CON::device_CON() { ansi.nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS); ansi.saverow=0; ansi.savecol=0; + ClearAnsi(); } void device_CON::ClearAnsi(void){ From d8c23d9b98237fa72d0d1564fde080744caea622 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 4 Apr 2003 16:32:03 +0000 Subject: [PATCH 0785/4131] Fix LOOPZ and LOOPNZ Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@865 --- src/cpu/core_full/op.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index b2800dcf..e2c7426e 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -316,10 +316,10 @@ switch (inst.code.op) { if (--reg_cx) break; goto nextopcode; case O_LOOPZ: - if (--reg_cx && !get_ZF()) break; + if (--reg_cx && get_ZF()) break; goto nextopcode; case O_LOOPNZ: - if (--reg_cx && get_ZF()) break; + if (--reg_cx && !get_ZF()) break; goto nextopcode; case O_JCXZ: if (reg_cx) goto nextopcode; From d9410982d016122cbf8edcdbaab400c715cc778e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 4 Apr 2003 16:33:43 +0000 Subject: [PATCH 0786/4131] Added LFS and LGS Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@866 --- src/cpu/core_full/optable.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index b57efb41..6bd42016 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -71,7 +71,6 @@ static OpCode OpCodeTable[1024]={ {D_PUSHAw ,0 ,0 ,0 },{D_POPAw ,0 ,0 ,0 }, {L_MODRM ,O_BOUNDw ,0 ,0 },{0 ,0 ,0 ,0 }, {L_PRESEG ,0 ,0 ,fs },{L_PRESEG ,0 ,0 ,gs }, -//{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {L_PREOP ,0 ,0 ,0 },{L_PREADD ,0 ,0 ,0 }, /* 0x68 - 0x6f */ {L_Iw ,0 ,S_PUSHw,0 },{L_MODRM ,O_IMULRw ,S_Gw ,M_EwxIwx}, @@ -307,8 +306,8 @@ static OpCode OpCodeTable[1024]={ /* 0x1b0 - 0x1b7 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,0 ,S_Gw ,M_Eb },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_SEGFS ,S_SEGGw,M_Efw },{L_MODRM ,O_SEGGS ,S_SEGGw,M_Efw }, +{L_MODRM ,0 ,S_Gw ,M_Eb },{L_MODRM ,0 ,S_Gw ,M_Ew }, /* 0x1b8 - 0x1bf */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, From fe77e30d777fa79183c9f9a344f45ab40b455c0b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 4 Apr 2003 21:05:54 +0000 Subject: [PATCH 0787/4131] Fix LAHF and SAHF Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@867 --- src/cpu/core_full/optable.h | 4 ++-- src/cpu/core_full/save.h | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 6bd42016..01f72660 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -111,7 +111,7 @@ static OpCode OpCodeTable[1024]={ {D_CBW ,0 ,0 ,0 },{D_CWD ,0 ,0 ,0 }, {L_Ifw ,O_CALL_F ,S_CSIP ,0 },{L_ERROR ,0 ,0 ,0 }, {L_FLG ,0 ,S_PUSHw,0 },{L_POPw ,0 ,S_FLGw ,0 }, -{L_FLG ,0 ,S_REGb ,REGI_AH},{L_REGb ,0 ,S_FLGb ,REGI_AH}, +{L_REGb ,0 ,S_FLGb ,REGI_AH},{L_FLG ,0 ,S_REGb ,REGI_AH}, /* 0xa0 - 0xa7 */ {L_OP ,O_ALOP ,0 ,0 },{L_OP ,O_AXOP ,0 ,0 }, @@ -469,7 +469,7 @@ static OpCode OpCodeTable[1024]={ {D_CBW ,0 ,0 ,0 },{D_CDQ ,0 ,0 ,0 }, {L_Ifd ,O_CALL_F ,S_CSIP ,0 },{L_ERROR ,0 ,0 ,0 }, {L_FLG ,0 ,S_PUSHd,0 },{L_POPd ,0 ,S_FLGd ,0 }, -{L_FLG ,0 ,S_REGb ,REGI_AH},{L_REGb ,0 ,S_FLGb ,REGI_AH}, +{L_REGb ,0 ,S_FLGb ,REGI_AH},{L_FLG ,0 ,S_REGb ,REGI_AH}, /* 0x2a0 - 0x2a7 */ {L_OP ,O_ALOP ,0 ,0 },{L_OP ,O_EAXOP ,0 ,0 }, diff --git a/src/cpu/core_full/save.h b/src/cpu/core_full/save.h index e1747df5..c8322502 100644 --- a/src/cpu/core_full/save.h +++ b/src/cpu/core_full/save.h @@ -91,9 +91,10 @@ switch (inst.code.save) { LoadIP(); break; case S_FLGb: - flags.type=t_UNKNOWN; \ - flags.cf =(inst.op1.d & 0x001)>0;flags.pf =(inst.op1.d & 0x004)>0; \ - flags.af =(inst.op1.d & 0x010)>0;flags.zf =(inst.op1.d & 0x040)>0; \ + flags.of =get_OF(); + flags.type=t_UNKNOWN; + flags.cf =(inst.op1.d & 0x001)>0;flags.pf =(inst.op1.d & 0x004)>0; + flags.af =(inst.op1.d & 0x010)>0;flags.zf =(inst.op1.d & 0x040)>0; flags.sf =(inst.op1.d & 0x080)>0; break; case S_FLGw: From 54edb9922b9bd2e5eefcdef9e4ed2792edf42bc0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 4 Apr 2003 21:59:38 +0000 Subject: [PATCH 0788/4131] Correct calculation for function 0x2c get time. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@868 --- src/dos/dos.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 97db2f76..2288dbce 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -296,12 +296,14 @@ static Bitu DOS_21Handler(void) { case 0x2c: /* Get System Time */ //TODO Get time through bios calls date is fixed { - Bit32u ticks=mem_readd(BIOS_TIMER); - Bit32u seconds=(ticks*10)/182; +/* Calculate how many miliseconds have passed */ + Bitu ticks=5*mem_readd(BIOS_TIMER); + ticks = ((ticks / 59659u) << 16) + ((ticks % 59659u) << 16) / 59659u; + Bitu seconds=(ticks/100); reg_ch=(Bit8u)(seconds/3600); reg_cl=(Bit8u)((seconds % 3600)/60); reg_dh=(Bit8u)(seconds % 60); - reg_dl=(Bit8u)(((ticks * 10) % 182)*100)/182; + reg_dl=(Bit8u)(ticks % 100); } break; case 0x2d: /* Set System Time */ From d89a9e1fc1764be135343cad3c1d2029d737ccbd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 4 Apr 2003 22:17:54 +0000 Subject: [PATCH 0789/4131] Small bug in one of the 32-bit r/m address lookups Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@869 --- src/cpu/core_16/table_ea.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_16/table_ea.h b/src/cpu/core_16/table_ea.h index 9393a25d..8cecfee7 100644 --- a/src/cpu/core_16/table_ea.h +++ b/src/cpu/core_16/table_ea.h @@ -242,7 +242,7 @@ static EAPoint EA_32_80_n(void) { PrefixReset;return SegBase(ds)+reg_eax+Fetchds static EAPoint EA_32_81_n(void) { PrefixReset;return SegBase(ds)+reg_ecx+Fetchds(); } static EAPoint EA_32_82_n(void) { PrefixReset;return SegBase(ds)+reg_edx+Fetchds(); } static EAPoint EA_32_83_n(void) { PrefixReset;return SegBase(ds)+reg_ebx+Fetchds(); } -static EAPoint EA_32_84_n(void) { PrefixReset;EAPoint temp=Sib(2);return temp+Fetchbs();} +static EAPoint EA_32_84_n(void) { PrefixReset;EAPoint temp=Sib(2);return temp+Fetchds();} static EAPoint EA_32_85_n(void) { PrefixReset;return SegBase(ss)+reg_ebp+Fetchds(); } static EAPoint EA_32_86_n(void) { PrefixReset;return SegBase(ds)+reg_esi+Fetchds(); } static EAPoint EA_32_87_n(void) { PrefixReset;return SegBase(ds)+reg_edi+Fetchds(); } From 4c13a9d897285c735c827c00166609312cbc4dfb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Apr 2003 06:31:54 +0000 Subject: [PATCH 0790/4131] ALSA Midi Support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@870 --- src/gui/Makefile.am | 2 +- src/gui/midi.cpp | 6 ++ src/gui/midi_alsa.h | 178 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 src/gui/midi_alsa.h diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 83664b6d..fafd8e72 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -2,5 +2,5 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libgui.a libgui_a_SOURCES = sdlmain.cpp render.cpp render_normal.h render_scale2x.h \ - midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h + midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h midi_alsa.h diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 589a2416..6f6ca663 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -86,6 +86,12 @@ MidiHandler Midi_none; #endif +#if defined (HAVE_ALSA) + +#include "midi_alsa.h" + +#endif + static struct { Bitu status; Bitu cmd_len; diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h new file mode 100644 index 00000000..0f2ae276 --- /dev/null +++ b/src/gui/midi_alsa.h @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include + +#define ADDR_DELIM ".:" + +#if SND_LIB_MINOR >= 6 +#define snd_seq_flush_output(x) snd_seq_drain_output(x) +#define snd_seq_set_client_group(x,name) /*nop */ +#define my_snd_seq_open(seqp) snd_seq_open(seqp, "hw", SND_SEQ_OPEN_OUTPUT, 0) +#else +/* SND_SEQ_OPEN_OUT causes oops on early version of ALSA */ +#define my_snd_seq_open(seqp) snd_seq_open(seqp, SND_SEQ_OPEN) +#endif + +class MidiHandler_alsa : public MidiHandler { +private: + snd_seq_event_t ev; + snd_seq_t *seq_handle; + int seq_client, seq_port; + int my_client, my_port; + void send_event(int do_flush) { + snd_seq_ev_set_direct(&ev); + snd_seq_ev_set_source(&ev, my_port); + snd_seq_ev_set_dest(&ev, seq_client, seq_port); + + snd_seq_event_output(seq_handle, &ev); + if (do_flush) + snd_seq_flush_output(seq_handle); + } + + int parse_addr(char *arg, int *client, int *port) { + char *p; + + if (isdigit(*arg)) { + if ((p = strpbrk(arg, ADDR_DELIM)) == NULL) + return -1; + *client = atoi(arg); + *port = atoi(p + 1); + } else { + if (*arg == 's' || *arg == 'S') { + *client = SND_SEQ_ADDRESS_SUBSCRIBERS; + *port = 0; + } else + return -1; + } + return 0; + } +public: + MidiHandler_alsa() : MidiHandler() {}; + char* GetName(void) { return "alsa"; } + void PlaySysex(Bit8u * sysex,Bitu len) { + snd_seq_ev_set_sysex(&ev, len, sysex); + } + + void PlayMsg(Bit32u msg) { + unsigned int midiCmd[4]; + ev.type = SND_SEQ_EVENT_OSS; + + if (msg == 247) // to accomadate lure of the temptress + return; + + midiCmd[3] = (msg & 0xFF000000) >> 24; + midiCmd[2] = (msg & 0x00FF0000) >> 16; + midiCmd[1] = (msg & 0x0000FF00) >> 8; + midiCmd[0] = (msg & 0x000000FF); + ev.data.raw32.d[0] = midiCmd[0]; + ev.data.raw32.d[1] = midiCmd[1]; + ev.data.raw32.d[2] = midiCmd[2]; + + unsigned char chanID = midiCmd[0] & 0x0F; + switch (midiCmd[0] & 0xF0) { + case 0x80: + snd_seq_ev_set_noteoff(&ev, chanID, midiCmd[1], midiCmd[2]); + send_event(1); + break; + case 0x90: + snd_seq_ev_set_noteon(&ev, chanID, midiCmd[1], midiCmd[2]); + send_event(1); + break; + case 0xB0: + snd_seq_ev_set_controller(&ev, chanID, midiCmd[1], midiCmd[2]); + send_event(1); + break; + case 0xC0: + snd_seq_ev_set_pgmchange(&ev, chanID, midiCmd[1]); + send_event(0); + break; + case 0xE0:{ + long theBend = ((long)midiCmd[1] + (long)(midiCmd[2] << 7)) - 0x2000; + snd_seq_ev_set_pitchbend(&ev, chanID, theBend); + send_event(1); + } + break; + default: + LOG(LOG_MISC,"ALSA:Unknown Command: %08x", (int)msg); + send_event(1); + break; + } + } + + void Close(void) { + if (seq_handle) + snd_seq_close(seq_handle); + } + + bool Open(const char * conf) { + char var[10]; + unsigned int caps; + + // try to use port specified in config file + if (conf && conf[0]) { + strncpy(var, conf, 10); + if (parse_addr(var, &seq_client, &seq_port) < 0) { + LOG_MSG("ALSA:Invalid alsa port %s", var); + return false; + } + } + // default port if none specified + else if (parse_addr("65:0", &seq_client, &seq_port) < 0) { + LOG_MSG("ALSA:Invalid alsa port 65:0"); + return false; + } + + if (my_snd_seq_open(&seq_handle)) { + LOG_MSG("ALSA:Can't open sequencer"); + return false; + } + + my_client = snd_seq_client_id(seq_handle); + snd_seq_set_client_name(seq_handle, "DOSBOX"); + snd_seq_set_client_group(seq_handle, "input"); + + caps = SND_SEQ_PORT_CAP_READ; + if (seq_client == SND_SEQ_ADDRESS_SUBSCRIBERS) + caps = ~SND_SEQ_PORT_CAP_SUBS_READ; + my_port = + snd_seq_create_simple_port(seq_handle, "DOSBOX", caps, + SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); + if (my_port < 0) { + snd_seq_close(seq_handle); + LOG_MSG("ALSA:Can't create ALSA port"); + return false; + } + + if (seq_client != SND_SEQ_ADDRESS_SUBSCRIBERS) { + /* subscribe to MIDI port */ + if (snd_seq_connect_to(seq_handle, my_port, seq_client, seq_port) < 0) { + snd_seq_close(seq_handle); + LOG_MSG("ALSA:Can't subscribe to MIDI port (%d:%d)", seq_client, seq_port); + return false; + } + } + + LOG_MSG("ALSA:Client initialised [%d:%d]", seq_client, seq_port); + return true; + } + +}; + +MidiHandler_alsa Midi_alsa; From b7040481ab7770b69cdf24f0e0d7660c1b38db8b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Apr 2003 08:36:37 +0000 Subject: [PATCH 0791/4131] Support for 0x0f prefixed 386 opcodes and added some new instructions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@871 --- src/cpu/core_full/load.h | 29 +++++- src/cpu/core_full/op.h | 53 ++++++++++ src/cpu/core_full/optable.h | 191 +++++++++++++++++++++++++++++++++--- src/cpu/core_full/support.h | 16 +-- 4 files changed, 269 insertions(+), 20 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index c3c8a23a..328540ba 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -8,6 +8,10 @@ l_MODRMswitch: case M_Ib: inst.op1.d=Fetchb(); break; + case M_Ebx: + if (inst.rm<0xc0) inst.op1.ds=(Bit8s)LoadMb(inst.rm_eaa); + else inst.op1.ds=(Bit8s)reg_8(inst.rm_eai); + break; case M_EbIb: inst.op2.d=Fetchb(); case M_Eb: @@ -38,6 +42,7 @@ l_MODRMswitch: case M_EwxIwx: inst.op2.ds=Fetchws(); l_M_Ewx: + case M_Ewx: if (inst.rm<0xc0) inst.op1.ds=(Bit16s)LoadMw(inst.rm_eaa); else inst.op1.ds=(Bit16s)reg_16(inst.rm_eai); break; @@ -46,10 +51,16 @@ l_M_Ewx: goto l_M_Ew; case M_EwIw: inst.op2.d=Fetchw(); - goto l_M_Ew; + goto l_M_Ew; + case M_EwGwCL: + inst.imm.d=reg_cl; + goto l_M_EwGw; + case M_EwGwIb: + inst.imm.d=Fetchb(); +l_M_EwGw: case M_EwGw: inst.op2.d=reg_16(inst.rm_index); -l_M_Ew: +l_M_Ew: case M_Ew: if (inst.rm<0xc0) inst.op1.d=LoadMw(inst.rm_eaa); else inst.op1.d=reg_16(inst.rm_eai); @@ -64,15 +75,27 @@ l_M_Ew: case M_Id: inst.op1.d=Fetchd(); break; + case M_EdxGdx: + inst.op2.ds=(Bit32s)reg_32(inst.rm_index); + case M_Edx: + if (inst.rm<0xc0) inst.op1.d=(Bit32s)LoadMd(inst.rm_eaa); + else inst.op1.d=(Bit32s)reg_32(inst.rm_eai); + break; case M_EdIbx: inst.op2.ds=Fetchbs(); goto l_M_Ed; case M_EdId: inst.op2.d=Fetchd(); goto l_M_Ed; + case M_EdGdCL: + inst.imm.d=reg_cl; + goto l_M_EdGd; + case M_EdGdIb: + inst.imm.d=Fetchb(); +l_M_EdGd: case M_EdGd: inst.op2.d=reg_32(inst.rm_index); -l_M_Ed: +l_M_Ed: case M_Ed: if (inst.rm<0xc0) inst.op1.d=LoadMd(inst.rm_eaa); else inst.op1.d=reg_32(inst.rm_eai); diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index e2c7426e..80179bad 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -127,6 +127,27 @@ switch (inst.code.op) { SARD(inst.op1.d,inst.op2.b,LoadD,SaveD); break; + case O_DSHLw: + { + DSHLW(inst.op1.w,inst.op2.w,inst.imm.b,,LoadD,SaveD); + break; + } + case O_DSHRw: + { + DSHRW(inst.op1.w,inst.op2.w,inst.imm.b,,LoadD,SaveD); + break; + } + case O_DSHLd: + { + DSHLD(inst.op1.d,inst.op2.d,inst.imm.b,,LoadD,SaveD); + break; + } + case O_DSHRd: + { + DSHRD(inst.op1.d,inst.op2.d,inst.imm.b,,LoadD,SaveD); + break; + } + case t_NEGb: flags.var1.b=inst.op1.b; inst.op1.b=flags.result.b=0-inst.op1.b; @@ -157,6 +178,18 @@ switch (inst.code.op) { flags.cf=true;flags.of=true; } break; + case O_IMULRd: + { + Bit64s res=(Bit64s)inst.op1.ds*(Bit64s)inst.op2.ds; + inst.op1.ds=(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 O_MULb: flags.type=t_MUL; reg_ax=reg_al*inst.op1.b; @@ -227,6 +260,16 @@ switch (inst.code.op) { if (quo!=reg_ax) { inst.op1.b=0;goto doint;} goto nextopcode; } + case O_DIVd: + { + if (!inst.op1.d) goto doint; + Bit64u val=(((Bit64u)reg_edx)<<32)|reg_eax; + Bit64u quo=val/inst.op1.d; + reg_edx=(Bit32u)(val % inst.op1.d); + reg_eax=(Bit32u)quo; + if (quo!=reg_eax) { inst.op1.b=0;goto doint;} + goto nextopcode; + } case O_IDIVb: { if (!inst.op1.b) goto doint; @@ -245,6 +288,16 @@ switch (inst.code.op) { if (quo!=(Bit16s)reg_ax) { inst.op1.b=0;goto doint;} goto nextopcode; } + case O_IDIVd: + { + if (!inst.op1.d) goto doint; + Bit64s val=(((Bit64u)reg_edx)<<32)|reg_eax; + Bit64s quo=val/inst.op1.ds; + reg_edx=(Bit32s)(val % inst.op1.ds); + reg_eax=(Bit32s)(quo); + if (quo!=(Bit32s)reg_eax) { inst.op1.b=0;goto doint;} + goto nextopcode; + } case O_AAM: reg_ah=reg_al / inst.op1.b; reg_al=reg_al % inst.op1.b; diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 01f72660..032d392d 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -295,12 +295,12 @@ static OpCode OpCodeTable[1024]={ /* 0x1a0 - 0x1a7 */ {L_SEG ,0 ,S_PUSHw ,fs },{L_POPw ,0 ,S_SEGI ,fs }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_DSHLw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHLw ,S_Ew ,M_EwGwCL }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x1a8 - 0x1af */ {L_SEG ,0 ,S_PUSHw ,gs },{L_POPw ,0 ,S_SEGI ,gs }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_DSHRw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHRw ,S_Ew ,M_EwGwCL }, {0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRw ,S_Gw ,M_EwxGwx }, /* 0x1b0 - 0x1b7 */ @@ -312,7 +312,7 @@ static OpCode OpCodeTable[1024]={ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,0 ,S_Gw ,M_Ebx },{L_MODRM ,0 ,S_Gw ,M_Ewx }, /* 0x1c0 - 0x1cc */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, @@ -363,23 +363,23 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,t_ADDb ,S_Eb ,M_EbGb },{L_MODRM ,t_ADDd ,S_Ed ,M_EdGd }, {L_MODRM ,t_ADDb ,S_Gb ,M_GbEb },{L_MODRM ,t_ADDd ,S_Gd ,M_GdEd }, {L_REGbIb ,t_ADDb ,S_REGb ,REGI_AL },{L_REGdId ,t_ADDd ,S_REGd ,REGI_AX }, -{L_SEG ,0 ,S_PUSHw,es },{L_POPw ,0 ,S_SEGI ,es }, +{L_SEG ,0 ,S_PUSHd,es },{L_POPd ,0 ,S_SEGI ,es }, /* 0x208 - 0x20f */ {L_MODRM ,t_ORb ,S_Eb ,M_EbGb },{L_MODRM ,t_ORd ,S_Ed ,M_EdGd }, {L_MODRM ,t_ORb ,S_Gb ,M_GbEb },{L_MODRM ,t_ORd ,S_Gd ,M_GdEd }, {L_REGbIb ,t_ORb ,S_REGb ,REGI_AL },{L_REGdId ,t_ORd ,S_REGd ,REGI_AX }, -{L_SEG ,0 ,S_PUSHw,cs },{L_DOUBLE ,0 ,0 ,0 }, +{L_SEG ,0 ,S_PUSHd,cs },{L_DOUBLE ,0 ,0 ,0 }, /* 0x210 - 0x217 */ {L_MODRM ,t_ADCb ,S_Eb ,M_EbGb },{L_MODRM ,t_ADCd ,S_Ed ,M_EdGd }, {L_MODRM ,t_ADCb ,S_Gb ,M_GbEb },{L_MODRM ,t_ADCd ,S_Gd ,M_GdEd }, {L_REGbIb ,t_ADCb ,S_REGb ,REGI_AL },{L_REGdId ,t_ADCd ,S_REGd ,REGI_AX }, -{L_SEG ,0 ,S_PUSHw,ss },{L_POPw ,0 ,S_SEGI ,ss }, +{L_SEG ,0 ,S_PUSHd,ss },{L_POPd ,0 ,S_SEGI ,ss }, /* 0x218 - 0x21f */ {L_MODRM ,t_SBBb ,S_Eb ,M_EbGb },{L_MODRM ,t_SBBd ,S_Ed ,M_EdGd }, {L_MODRM ,t_SBBb ,S_Gb ,M_GbEb },{L_MODRM ,t_SBBd ,S_Gd ,M_GdEd }, {L_REGbIb ,t_SBBb ,S_REGb ,REGI_AL },{L_REGdId ,t_SBBd ,S_REGd ,REGI_AX }, -{L_SEG ,0 ,S_PUSHw,ds },{L_POPw ,0 ,S_SEGI ,ds }, +{L_SEG ,0 ,S_PUSHd,ds },{L_POPd ,0 ,S_SEGI ,ds }, /* 0x220 - 0x227 */ {L_MODRM ,t_ANDb ,S_Eb ,M_EbGb },{L_MODRM ,t_ANDd ,S_Ed ,M_EdGd }, @@ -461,7 +461,7 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,0 ,S_SEGm ,M_Ew },{L_MODRM ,0 ,S_Ed ,M_POPd }, /* 0x290 - 0x297 */ -{D_NOP ,0 ,0 ,0 },{L_REGw ,O_XCHG_EAX ,S_REGw ,REGI_CX}, +{D_NOP ,0 ,0 ,0 },{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_CX}, {L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_DX},{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_BX}, {L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_SP},{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_BP}, {L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_SI},{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_DI}, @@ -538,14 +538,183 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,0xb ,0 ,M_GRP },{L_MODRM ,0xd ,0 ,M_GRP }, - +/* 0x200 - 0x207 */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +/* 0x208 - 0x20f */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x100 - 0x107 */ +/* 0x210 - 0x217 */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +/* 0x218 - 0x21f */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, + +/* 0x220 - 0x227 */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, + +/* 0x228 - 0x22f */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, + +/* 0x230 - 0x237 */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +/* 0x238 - 0x23f */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, + +/* 0x240 - 0x247 */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +/* 0x248 - 0x24f */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, + +/* 0x250 - 0x257 */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +/* 0x258 - 0x25f */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, + +/* 0x260 - 0x267 */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +/* 0x268 - 0x26f */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x108 - 0x10f */ +/* 0x270 - 0x277 */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +/* 0x278 - 0x27f */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, + +/* 0x280 - 0x287 */ +{L_Idx ,O_C_O ,S_C_ADDIP,0 },{L_Idx ,O_C_NO ,S_C_ADDIP,0 }, +{L_Idx ,O_C_B ,S_C_ADDIP,0 },{L_Idx ,O_C_NB ,S_C_ADDIP,0 }, +{L_Idx ,O_C_Z ,S_C_ADDIP,0 },{L_Idx ,O_C_NZ ,S_C_ADDIP,0 }, +{L_Idx ,O_C_BE ,S_C_ADDIP,0 },{L_Idx ,O_C_NBE ,S_C_ADDIP,0 }, +/* 0x288 - 0x28f */ +{L_Idx ,O_C_S ,S_C_ADDIP,0 },{L_Idx ,O_C_NS ,S_C_ADDIP,0 }, +{L_Idx ,O_C_P ,S_C_ADDIP,0 },{L_Idx ,O_C_NP ,S_C_ADDIP,0 }, +{L_Idx ,O_C_L ,S_C_ADDIP,0 },{L_Idx ,O_C_NL ,S_C_ADDIP,0 }, +{L_Idx ,O_C_LE ,S_C_ADDIP,0 },{L_Idx ,O_C_NLE ,S_C_ADDIP,0 }, + +/* 0x290 - 0x297 */ +{L_MODRM ,O_C_O ,S_C_Eb,0 },{L_MODRM ,O_C_NO ,S_C_Eb,0 }, +{L_MODRM ,O_C_B ,S_C_Eb,0 },{L_MODRM ,O_C_NB ,S_C_Eb,0 }, +{L_MODRM ,O_C_Z ,S_C_Eb,0 },{L_MODRM ,O_C_NZ ,S_C_Eb,0 }, +{L_MODRM ,O_C_BE ,S_C_Eb,0 },{L_MODRM ,O_C_NBE ,S_C_Eb,0 }, +/* 0x298 - 0x29f */ +{L_MODRM ,O_C_S ,S_C_Eb,0 },{L_MODRM ,O_C_NS ,S_C_Eb,0 }, +{L_MODRM ,O_C_P ,S_C_Eb,0 },{L_MODRM ,O_C_NP ,S_C_Eb,0 }, +{L_MODRM ,O_C_L ,S_C_Eb,0 },{L_MODRM ,O_C_NL ,S_C_Eb,0 }, +{L_MODRM ,O_C_LE ,S_C_Eb,0 },{L_MODRM ,O_C_NLE ,S_C_Eb,0 }, + +/* 0x2a0 - 0x2a7 */ +{L_SEG ,0 ,S_PUSHd ,fs },{L_POPd ,0 ,S_SEGI ,fs }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_DSHLd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHLd ,S_Ed ,M_EdGdCL }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +/* 0x2a8 - 0x2af */ +{L_SEG ,0 ,S_PUSHd ,gs },{L_POPd ,0 ,S_SEGI ,gs }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_DSHRd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHRd ,S_Ed ,M_EdGdCL }, +{0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdxGdx }, + +/* 0x2b0 - 0x2b7 */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_SEGFS ,S_SEGGd,M_Efd },{L_MODRM ,O_SEGGS ,S_SEGGd,M_Efd }, +{L_MODRM ,0 ,S_Gd ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ew }, +/* 0x2b8 - 0x2bf */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,0 ,S_Gd ,M_Ebx },{L_MODRM ,0 ,S_Gd ,M_Ewx }, + +/* 0x2c0 - 0x2cc */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +/* 0x2c8 - 0x2cf */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, + +/* 0x2d0 - 0x2d7 */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +/* 0x2d8 - 0x2df */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, + +/* 0x2e0 - 0x2ee */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +/* 0x2e8 - 0x2ef */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, + +/* 0x2f0 - 0x2fc */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +/* 0x2f8 - 0x2ff */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, }; diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 7dcee792..6df98558 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -65,6 +65,9 @@ enum { O_IDIVb,O_IDIVw,O_IDIVd, O_CBACK, + + O_DSHLw,O_DSHLd, + O_DSHRw,O_DSHRd, O_C_O ,O_C_NO ,O_C_B ,O_C_NB ,O_C_Z ,O_C_NZ ,O_C_BE ,O_C_NBE, O_C_S ,O_C_NS ,O_C_P ,O_C_NP ,O_C_L ,O_C_NL ,O_C_LE ,O_C_NLE, }; @@ -104,12 +107,13 @@ enum { enum { M_None=0, - M_Eb,M_Gb,M_EbGb,M_GbEb, - M_Ew,M_Gw,M_EwGw,M_GwEw,M_EwxGwx, - M_Ed,M_Gd,M_EdGd,M_GdEd, + M_Ebx,M_Eb,M_Gb,M_EbGb,M_GbEb, + M_Ewx,M_Ew,M_Gw,M_EwGw,M_GwEw,M_EwxGwx, + M_Edx,M_Ed,M_Gd,M_EdGd,M_GdEd,M_EdxGdx, + M_EbIb, - M_EwIw,M_EwIbx,M_EwxIbx,M_EwxIwx, - M_EdId,M_EdIbx, + M_EwIw,M_EwIbx,M_EwxIbx,M_EwxIwx,M_EwGwIb,M_EwGwCL, + M_EdId,M_EdIbx,M_EdGdIb,M_EdGdCL, M_Efw,M_Efd, @@ -141,7 +145,7 @@ static struct { Bit8u b;Bit8s bs; Bit16u w;Bit16s ws; Bit32u d;Bit32s ds; - } op1,op2; + } op1,op2,imm; Bitu new_flags; struct { EAPoint base; From e2e143a8463e8dd2287281efd0550c6c10d0ce24 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 6 Apr 2003 10:25:07 +0000 Subject: [PATCH 0792/4131] Added Descriptor/table classes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@872 --- include/cpu.h | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/include/cpu.h b/include/cpu.h index 9209b525..ad377657 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -96,5 +96,69 @@ bool get_PF(void); #define LoadOF flags.of=get_OF(); +// ********************************************************************* +// Descriptor +// ********************************************************************* + +class Descriptor +{ +public: + void LoadValues (Bit32u address) { + Bit32u* data = (Bit32u*)&desc; + *data = mem_readd(address); + *(data+1) = mem_readd(address+1); + } + void SaveValues (Bit32u address) { + Bit32u* data = (Bit32u*)&desc; + mem_writed(address,*data); + mem_writed(address+1,*(data+1)); + } + Bit32u GetBase (void) { return (desc.base_24_31<<24) | (desc.base_16_23<<16) | desc.base_0_15; }; + Bit32u GetLimit (void) { + Bit32u limit = (desc.limit_16_19<<16) | desc.limit_0_15; + if (desc.g) return (limit<<12) | 0xFFF; + return limit; + } + +public: +#pragma pack(1) + typedef struct SDescriptor { + 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 d :1; + Bit32u g :1; + Bit32u base_24_31 :8; + } TDescriptor; +#pragma pack() + + TDescriptor desc; +}; + +class DescriptorTable +{ + Bit32u GetBase (void) { return baseAddress; }; + Bit16u GetLimit (void) { return limit; }; + void SetBase (Bit32u base) { baseAddress = base; }; + void SetLimit (Bit16u size) { limit = size; }; + + bool GetDescriptor (Bit16u selector, Descriptor& desc) { + // selector = the plain index + if (selector>=limit>>3) return false; + desc.LoadValues(baseAddress+(selector<<3)); + return true; + }; + +private: + Bit32u baseAddress; + Bit16u limit; +}; + #endif From 140a8d3238929ae82a789af1183833ca0e616b91 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 6 Apr 2003 10:41:52 +0000 Subject: [PATCH 0793/4131] fixed bug in Descriptor::Load/SaveValues Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@873 --- include/cpu.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index ad377657..f0195944 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -106,12 +106,12 @@ public: void LoadValues (Bit32u address) { Bit32u* data = (Bit32u*)&desc; *data = mem_readd(address); - *(data+1) = mem_readd(address+1); + *(data+1) = mem_readd(address+4); } void SaveValues (Bit32u address) { Bit32u* data = (Bit32u*)&desc; mem_writed(address,*data); - mem_writed(address+1,*(data+1)); + mem_writed(address+4,*(data+1)); } Bit32u GetBase (void) { return (desc.base_24_31<<24) | (desc.base_16_23<<16) | desc.base_0_15; }; Bit32u GetLimit (void) { From a75a39a550bcb687f0e9915014f0150b78719f11 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Apr 2003 11:05:43 +0000 Subject: [PATCH 0794/4131] Full 32-bit flags support for detecting 386 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@874 --- src/cpu/core_full/loadwrite.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_full/loadwrite.h b/src/cpu/core_full/loadwrite.h index 1b165da8..3a752932 100644 --- a/src/cpu/core_full/loadwrite.h +++ b/src/cpu/core_full/loadwrite.h @@ -67,6 +67,12 @@ static INLINE Bit32u Pop_32() { 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(); \ + } \ } From 34004ce67699ab65ce9488d89cac090b76b37e89 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Apr 2003 11:06:13 +0000 Subject: [PATCH 0795/4131] Support 0x67 prefix Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@875 --- src/cpu/core_full/ea_lookup.h | 138 ++++++++++++++++++++++++++++++++-- src/cpu/core_full/load.h | 6 +- 2 files changed, 137 insertions(+), 7 deletions(-) diff --git a/src/cpu/core_full/ea_lookup.h b/src/cpu/core_full/ea_lookup.h index c9b8d62c..0c19b04e 100644 --- a/src/cpu/core_full/ea_lookup.h +++ b/src/cpu/core_full/ea_lookup.h @@ -1,7 +1,4 @@ - - - -static EAPoint RMAddress(void) { +static EAPoint RMAddress_16(void) { EAPoint seg_base; Bit16u off; switch ((inst.rm_mod<<3)|inst.rm_eai) { @@ -107,9 +104,140 @@ static EAPoint RMAddress(void) { inst.rm_off=off; if (inst.prefix & PREFIX_SEG) { return inst.seg.base+off; - }else return seg_base+off; + } else { + return seg_base+off; + } } +static Bit32u SIBZero=0; +static Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi }; + +#define SIB(MODE) { \ + Bitu sib=Fetchb(); \ + switch (sib&7) { \ + case 0:seg_base=SegBase(ds);off=reg_eax;break; \ + case 1:seg_base=SegBase(ds);off=reg_ecx;break; \ + case 2:seg_base=SegBase(ds);off=reg_edx;break; \ + case 3:seg_base=SegBase(ds);off=reg_ebx;break; \ + case 4:seg_base=SegBase(ss);off=reg_esp;break; \ + case 5:if (!MODE) { seg_base=SegBase(ds);off=Fetchd();break; \ + } else { seg_base=SegBase(ss);off=reg_ebp;break;} \ + case 6:seg_base=SegBase(ds);off=reg_esi;break; \ + case 7:seg_base=SegBase(ds);off=reg_edi;break; \ + } \ + off+=*SIBIndex[(sib >> 3) &7] << (sib >> 6); \ +}; +static EAPoint RMAddress_32(void) { + EAPoint seg_base; + Bit32u off; + switch ((inst.rm_mod<<3)|inst.rm_eai) { + case 0x00: + off=reg_eax; + seg_base=SegBase(ds); + break; + case 0x01: + off=reg_ecx; + seg_base=SegBase(ds); + break; + case 0x02: + off=reg_edx; + seg_base=SegBase(ds); + break; + case 0x03: + off=reg_ebx; + seg_base=SegBase(ds); + break; + case 0x04: + SIB(0); + break; + case 0x05: + off=Fetchd(); + seg_base=SegBase(ds); + break; + case 0x06: + off=reg_esi; + seg_base=SegBase(ds); + break; + case 0x07: + off=reg_edi; + seg_base=SegBase(ds); + break; + + case 0x08: + off=reg_eax+Fetchbs(); + seg_base=SegBase(ds); + break; + case 0x09: + off=reg_ecx+Fetchbs(); + seg_base=SegBase(ds); + break; + case 0x0a: + off=reg_edx+Fetchbs(); + seg_base=SegBase(ds); + break; + case 0x0b: + off=reg_ebx+Fetchbs(); + seg_base=SegBase(ds); + break; + case 0x0c: + SIB(1); + off+=Fetchbs(); + break; + case 0x0d: + off=reg_ebp+Fetchbs(); + seg_base=SegBase(ss); + break; + case 0x0e: + off=reg_esi+Fetchbs(); + seg_base=SegBase(ds); + break; + case 0x0f: + off=reg_edi+Fetchbs(); + seg_base=SegBase(ds); + break; + + case 0x10: + off=reg_eax+Fetchds(); + seg_base=SegBase(ds); + break; + case 0x11: + off=reg_ecx+Fetchds(); + seg_base=SegBase(ds); + break; + case 0x12: + off=reg_edx+Fetchds(); + seg_base=SegBase(ds); + break; + case 0x13: + off=reg_ebx+Fetchds(); + seg_base=SegBase(ds); + break; + case 0x14: + SIB(1); + off+=Fetchds(); + break; + case 0x15: + off=reg_ebp+Fetchds(); + seg_base=SegBase(ss); + break; + case 0x16: + off=reg_esi+Fetchds(); + seg_base=SegBase(ds); + break; + case 0x17: + off=reg_edi+Fetchds(); + seg_base=SegBase(ds); + break; + + + } + inst.rm_off=off; + if (inst.prefix & PREFIX_SEG) { + return inst.seg.base+off; + } else { + return seg_base+off; + } +} diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 328540ba..f547a012 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -155,7 +155,6 @@ l_M_Ed: /* Should continue with normal handler afterwards */ case 0: - LOG(LOG_CPU|LOG_ERROR,"MODRM:Unhandled load %d entry %x",inst.code.extra,inst.entry); break; default: LOG(LOG_CPU|LOG_ERROR,"MODRM:Unhandled load %d entry %x",inst.code.extra,inst.entry); @@ -252,7 +251,10 @@ l_M_Ed: inst.repz=true; goto restartopcode; case L_PREOP: - inst.entry|=0x200; + inst.entry^=0x200; + goto restartopcode; + case L_PREADD: + inst.prefix^=PREFIX_ADDR; goto restartopcode; case L_VAL: inst.op1.d=inst.code.extra; From 6ae8549b9e21b286a91182893b9feefb74dfa1a1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Apr 2003 11:07:19 +0000 Subject: [PATCH 0796/4131] Special inline memory read/write handlers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@876 --- include/mem.h | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/include/mem.h b/include/mem.h index 19e3d301..a41cc885 100644 --- a/include/mem.h +++ b/include/mem.h @@ -111,7 +111,7 @@ INLINE void writed(HostPt off,Bit32u val) { /* The Folowing six functions are slower but they recognize the paged memory system */ //TODO maybe make em inline to go a bit faster -#if (!C_EXTRAINLINE) + Bit8u mem_readb(PhysPt pt); Bit16u mem_readw(PhysPt pt); Bit32u mem_readd(PhysPt pt); @@ -120,16 +120,14 @@ void mem_writeb(PhysPt pt,Bit8u val); void mem_writew(PhysPt pt,Bit16u val); void mem_writed(PhysPt pt,Bit32u val); -#else - -INLINE void mem_writeb(PhysPt pt,Bit8u val) { +INLINE void mem_writeb_inline(PhysPt pt,Bit8u val) { if (WriteHostTable[pt >> PAGE_SHIFT]) writeb(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); else { WriteHandlerTable[pt >> PAGE_SHIFT](pt,val); } } -INLINE void mem_writew(PhysPt pt,Bit16u val) { +INLINE void mem_writew_inline(PhysPt pt,Bit16u val) { if (WriteHostTable[pt >> PAGE_SHIFT]) writew(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); else { WriteHandlerTable[pt >> PAGE_SHIFT](pt+0,(Bit8u)(val & 0xff)); @@ -137,7 +135,7 @@ INLINE void mem_writew(PhysPt pt,Bit16u val) { } } -INLINE void mem_writed(PhysPt pt,Bit32u val) { +INLINE void mem_writed_inline(PhysPt pt,Bit32u val) { if (WriteHostTable[pt >> PAGE_SHIFT]) writed(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); else { WriteHandlerTable[pt >> PAGE_SHIFT](pt+0,(Bit8u)(val & 0xff)); @@ -147,24 +145,23 @@ INLINE void mem_writed(PhysPt pt,Bit32u val) { } } -INLINE Bit8u mem_readb(PhysPt pt) { +INLINE Bit8u mem_readb_inline(PhysPt pt) { if (ReadHostTable[pt >> PAGE_SHIFT]) return readb(ReadHostTable[pt >> PAGE_SHIFT]+pt); else { return ReadHandlerTable[pt >> PAGE_SHIFT](pt); } } -INLINE Bit16u mem_readw(PhysPt pt) { +INLINE Bit16u mem_readw_inline(PhysPt pt) { if (ReadHostTable[pt >> PAGE_SHIFT]) return readw(ReadHostTable[pt >> PAGE_SHIFT]+pt); else { return (ReadHandlerTable[pt >> PAGE_SHIFT](pt+0)) | (ReadHandlerTable[pt >> PAGE_SHIFT](pt+1)) << 8; } - } -INLINE Bit32u mem_readd(PhysPt pt){ +INLINE Bit32u mem_readd_inline(PhysPt pt){ if (ReadHostTable[pt >> PAGE_SHIFT]) return readd(ReadHostTable[pt >> PAGE_SHIFT]+pt); else { return @@ -175,8 +172,6 @@ INLINE Bit32u mem_readd(PhysPt pt){ } } -#endif - void MEM_BlockWrite(PhysPt pt,void * data,Bitu size); void MEM_BlockRead(PhysPt pt,void * data,Bitu size); void MEM_BlockCopy(PhysPt dest,PhysPt src,Bitu size); From b3dcf45c8a7180fdcb6f4ff6a2cbf6c61c9eb2a0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Apr 2003 11:08:07 +0000 Subject: [PATCH 0797/4131] Always use inline memory read/writes Support for 0x67 prefix Removed some old debugging code Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@877 --- src/cpu/core_full.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index b4a0146b..98aeb613 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -9,17 +9,17 @@ typedef PhysPt EAPoint; #define SegBase(c) SegPhys(c) -#define LoadMb(off) mem_readb(off) -#define LoadMw(off) mem_readw(off) -#define LoadMd(off) mem_readd(off) +#define LoadMb(off) mem_readb_inline(off) +#define LoadMw(off) mem_readw_inline(off) +#define LoadMd(off) mem_readd_inline(off) #define LoadMbs(off) (Bit8s)(LoadMb(off)) #define LoadMws(off) (Bit16s)(LoadMw(off)) #define LoadMds(off) (Bit32s)(LoadMd(off)) -#define SaveMb(off,val) mem_writeb(off,val) -#define SaveMw(off,val) mem_writew(off,val) -#define SaveMd(off,val) mem_writed(off,val) +#define SaveMb(off,val) mem_writeb_inline(off,val) +#define SaveMw(off,val) mem_writew_inline(off,val) +#define SaveMd(off,val) mem_writed_inline(off,val) #define LoadD(reg) reg #define SaveD(reg,val) reg=val @@ -32,15 +32,13 @@ static EAPoint IPPoint; #include "core_full/ea_lookup.h" #include "instructions.h" -static bool had_code[16][16]; - static INLINE void DecodeModRM(void) { inst.rm=Fetchb(); inst.rm_index=(inst.rm >> 3) & 7; inst.rm_eai=inst.rm&07; inst.rm_mod=inst.rm>>6; /* Decode address of mod/rm if needed */ - if (inst.rm<0xc0) inst.rm_eaa=RMAddress(); + if (inst.rm<0xc0) inst.rm_eaa=(inst.prefix & PREFIX_ADDR) ? RMAddress_32() : RMAddress_16(); } @@ -53,9 +51,6 @@ Bitu Full_DeCode(void) { CPU_Cycles--; restartopcode: inst.entry=(inst.entry & 0xffffff00) | Fetchb(); - if (inst.entry<0x100) { - *(bool *)(&had_code[0][0]+inst.entry)=true; - } inst.code=OpCodeTable[inst.entry]; #include "core_full/load.h" From ee247fc7d2209602f336fcd6a705f7e108f9bb4c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Apr 2003 11:56:38 +0000 Subject: [PATCH 0798/4131] Running irq's when saving flags disabled for now. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@878 --- src/cpu/core_full/loadwrite.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cpu/core_full/loadwrite.h b/src/cpu/core_full/loadwrite.h index 3a752932..914ff2eb 100644 --- a/src/cpu/core_full/loadwrite.h +++ b/src/cpu/core_full/loadwrite.h @@ -69,6 +69,8 @@ static INLINE Bit32u Pop_32() { flags.df =(FLAGW & 0x400)>0;flags.of =(FLAGW & 0x800)>0; \ flags.io =(FLAGW >> 12) & 0x03; \ flags.nt =(FLAGW & 0x4000)>0; \ +} +#if 0 if (flags.intf && PIC_IRQCheck) { \ SaveIP(); \ PIC_runIRQs(); \ @@ -76,3 +78,4 @@ static INLINE Bit32u Pop_32() { } \ } +#endif \ No newline at end of file From adb8268359d121f85a426819006a6d23c8083dcf Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Apr 2003 12:09:43 +0000 Subject: [PATCH 0799/4131] Add INSB,INSW,CMPSD Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@879 --- src/cpu/core_full/string.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index 8c42542e..f70a39f4 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -39,6 +39,20 @@ si_index=(si_index+add_index) & add_mask; } break; + case R_INSB: + for (;count>0;count--) { + reg_dx,SaveMb(di_base+di_index,IO_Read(reg_dx)); + di_index=(di_index+add_index) & add_mask; + } + break; + case R_INSW: + add_index<<=1; + for (;count>0;count--) { + SaveMb(di_base+di_index,IO_Read(reg_dx)); + SaveMb(di_base+di_index+1,IO_Read(reg_dx+1)); + di_index=(di_index+add_index) & add_mask; + } + break; case R_STOSB: for (;count>0;count--) { SaveMb(di_base+di_index,reg_al); @@ -154,6 +168,20 @@ CMPW(val1,val2,LoadD,0); } break; + case R_CMPSD: + { + add_index<<=2;Bit32u val1,val2; + for (;count>0;) { + count--; + val1=LoadMd(si_base+si_index); + val2=LoadMd(di_base+di_index); + si_index=(si_index+add_index) & add_mask; + di_index=(di_index+add_index) & add_mask; + if ((val1==val2)!=inst.repz) break; + } + CMPD(val1,val2,LoadD,0); + } + break; default: LOG(LOG_CPU|LOG_ERROR,"Unhandled string %d entry %X",inst.code.op,inst.entry); } From a49cad547d5773acb21b304971e128d7432e625e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Apr 2003 13:34:19 +0000 Subject: [PATCH 0800/4131] Fixed to 32-bit IDIV and IMUL Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@880 --- src/cpu/core_full/op.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 80179bad..1464bbdc 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -229,9 +229,9 @@ switch (inst.code.op) { } case O_IMULd: { - Bit64s temps=(Bit64s)reg_eax*(Bit64s)inst.op1.ds; - reg_eax=(Bit32s)(temps); - reg_edx=(Bit32s)(temps >> 32); + Bit64s temps=(Bit64s)((Bit32s)reg_eax)*(Bit64s)inst.op1.ds; + reg_eax=(Bit32u)(temps); + reg_edx=(Bit32u)(temps >> 32); flags.type=t_MUL; if ( (reg_edx==0xffffffff) && (reg_eax & 0x80000000) ) { flags.cf=flags.of=false; @@ -267,7 +267,7 @@ switch (inst.code.op) { Bit64u quo=val/inst.op1.d; reg_edx=(Bit32u)(val % inst.op1.d); reg_eax=(Bit32u)quo; - if (quo!=reg_eax) { inst.op1.b=0;goto doint;} + if (quo!=(Bit64u)reg_eax) { inst.op1.b=0;goto doint;} goto nextopcode; } case O_IDIVb: @@ -295,7 +295,7 @@ switch (inst.code.op) { Bit64s quo=val/inst.op1.ds; reg_edx=(Bit32s)(val % inst.op1.ds); reg_eax=(Bit32s)(quo); - if (quo!=(Bit32s)reg_eax) { inst.op1.b=0;goto doint;} + if (quo!=(Bit64s)((Bit32s)reg_eax)) { inst.op1.b=0;goto doint;} goto nextopcode; } case O_AAM: From b0cb5d2b0bfa2f9075473ca14888a47fcd9e608d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Apr 2003 13:34:39 +0000 Subject: [PATCH 0801/4131] Save lower 16-bits when saving 32-bit flags Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@881 --- src/cpu/core_full/save.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu/core_full/save.h b/src/cpu/core_full/save.h index c8322502..a7c4b2b8 100644 --- a/src/cpu/core_full/save.h +++ b/src/cpu/core_full/save.h @@ -98,6 +98,7 @@ switch (inst.code.save) { flags.sf =(inst.op1.d & 0x080)>0; break; case S_FLGw: + case S_FLGd: //TODO Check full 32bit flags one day Save_Flagsw(inst.op1.w); break; case 0: From 58622a1de967235f125962d73f5daaf3e4b8d6ff Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Apr 2003 20:00:19 +0000 Subject: [PATCH 0802/4131] Clean up some old structure Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@882 --- src/cpu/cpu.cpp | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 2a44b651..9ccb2d47 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -23,35 +23,10 @@ #include "keyboard.h" #include "setup.h" -#pragma pack(1) -struct Descriptor { - 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 d :1; - Bit32u g :1; - Bit32u base_24_31 :8; -}; -#pragma pack() - struct CPUBlock { - - struct { - PhysPt phys_base; - Bit32u base; - Bit16u limit; - } gdt,idt; }; - - Flag_Info flags; CPU_Regs cpu_regs; From 4960a9201b383c5353819c4201a88da0b9ae9379 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Apr 2003 21:23:18 +0000 Subject: [PATCH 0803/4131] changes for new c_extra_inline handling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@883 --- src/hardware/memory.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index cec5c270..425cab93 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -148,7 +148,6 @@ void MEM_ClearMapping(Bitu startpage,Bitu pages) { } } -#if (!C_EXTRAINLINE) static void HandlerWritew(Bitu page,PhysPt pt,Bit16u val) { WriteHandlerTable[page](pt+0,(Bit8u)(val & 0xff)); WriteHandlerTable[page](pt+1,(Bit8u)((val >> 8) & 0xff) ); @@ -170,7 +169,6 @@ void mem_writeb(PhysPt pt,Bit8u val) { void mem_writew(PhysPt pt,Bit16u val) { if (!WriteHostTable[pt >> PAGE_SHIFT]) { -// HandlerWritew(pt >> PAGE_SHIFT,pt,val); WriteHandlerTable[pt >> PAGE_SHIFT](pt+0,(Bit8u)(val & 0xff)); WriteHandlerTable[pt >> PAGE_SHIFT](pt+1,(Bit8u)((val >> 8) & 0xff) ); } else writew(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); @@ -178,7 +176,6 @@ void mem_writew(PhysPt pt,Bit16u val) { void mem_writed(PhysPt pt,Bit32u val) { if (!WriteHostTable[pt >> PAGE_SHIFT]) { -// HandlerWrited(pt >> PAGE_SHIFT,pt,val); WriteHandlerTable[pt >> PAGE_SHIFT](pt+0,(Bit8u)(val & 0xff)); WriteHandlerTable[pt >> PAGE_SHIFT](pt+1,(Bit8u)((val >> 8) & 0xff) ); WriteHandlerTable[pt >> PAGE_SHIFT](pt+2,(Bit8u)((val >> 16) & 0xff) ); @@ -208,7 +205,6 @@ Bit8u mem_readb(PhysPt pt) { Bit16u mem_readw(PhysPt pt) { if (!ReadHostTable[pt >> PAGE_SHIFT]) { -// return HandlerReadw(pt >> PAGE_SHIFT,pt); return (ReadHandlerTable[pt >> PAGE_SHIFT](pt+0)) | (ReadHandlerTable[pt >> PAGE_SHIFT](pt+1)) << 8; @@ -218,7 +214,6 @@ Bit16u mem_readw(PhysPt pt) { Bit32u mem_readd(PhysPt pt){ if (ReadHostTable[pt >> PAGE_SHIFT]) return readd(ReadHostTable[pt >> PAGE_SHIFT]+pt); else { -// return HandlerReadd(pt >> PAGE_SHIFT,pt); return (ReadHandlerTable[pt >> PAGE_SHIFT](pt+0)) | (ReadHandlerTable[pt >> PAGE_SHIFT](pt+1)) << 8 | @@ -226,9 +221,6 @@ Bit32u mem_readd(PhysPt pt){ (ReadHandlerTable[pt >> PAGE_SHIFT](pt+3)) << 24; } } -#endif - - void MEM_Init(Section * sect) { /* Init all tables */ From 923ca7281a9a618c9c752fee280340e871d9e7fa Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 7 Apr 2003 10:48:53 +0000 Subject: [PATCH 0804/4131] put xms in functions and added resize block Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@884 --- src/ints/xms.cpp | 517 +++++++++++++++++++++++++++++------------------ 1 file changed, 323 insertions(+), 194 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index be28a19b..243f9ff8 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -24,7 +24,7 @@ #include "regs.h" #include "dos_system.h" #include "setup.h" - +#include "inout.h" #define XMS_HANDLES 50 /* 50 XMS Memory Blocks */ #define XMS_VERSION 0x0300 /* version 3.00 */ @@ -87,6 +87,28 @@ static bool multiplex_xms(void) { }; +// A20 Line Handlers +static Bit8u controlport_data = 0; +#define A20ENABLED (controlport_data & 2)>0 + +static void write_p92(Bit32u port,Bit8u val) { + // Bit 0 = system reset (switch back to real mode) + if (val & 1) E_Exit("XMS: CPU reset via port 0x92 not supported."); + controlport_data = val; +}; + +static Bit8u read_p92(Bit32u port) { + return controlport_data; +}; + +static Bit8u XMS_EnableA20(bool enable) +{ + Bit8u val = IO_Read (0x92); + if (enable) IO_Write(0x92,val | 2); + else IO_Write(0x92,val & ~2); + return 0; +}; + #pragma pack (push,1) struct XMS_MemMove{ Bit32u length; @@ -104,227 +126,330 @@ struct XMS_MemMove{ } GCC_ATTRIBUTE(packed); #pragma pack (pop) +static Bit8u XMS_QueryFreeMemory(Bit16u& largestFree, Bit16u& totalFree) { + /* Scan the tree for free memory and find largest free block */ + Bit16u index=1; + largestFree=totalFree=0; + while (xms_handles[index].active) { + if (!xms_handles[index].data) { + if (xms_handles[index].size>largestFree) largestFree=xms_handles[index].size; + totalFree+=xms_handles[index].size; + } + if (xms_handles[index].next=size) { + /* Check if block is bigger than request */ + if (xms_handles[index].size>size) { + /* Split Block, find new handle and split up memory */ + Bit16u new_index=1; + while (new_index=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].data ) { + return XMS_INVALID_HANDLE; + } + /* Remove the mapping to the memory */ + MEM_ClearMapping(PAGE_COUNT(xms_handles[handle].phys),PAGE_COUNT(xms_handles[handle].size*1024)); + /* Free the memory in the block and merge the blocks previous and next block */ + Bit16u prev=xms_handles[handle].prev; + Bit16u next=xms_handles[handle].next; + free(xms_handles[handle].data); + xms_handles[handle].data=0; + if ((next=XMS_HANDLES) || !xms_handles[block.src_handle].active ||!xms_handles[block.src_handle].data) { + return 0xa3; /* Src Handle invalid */ + } + if (block.src.offset>=(xms_handles[block.src_handle].size*1024U)) { + return 0xa4; /* Src Offset invalid */ + } + if (block.length>xms_handles[block.src_handle].size*1024U-block.src.offset) { + return 0xa7; /* Length invalid */ + } + src=xms_handles[block.src_handle].phys+block.src.offset; + } else { + src=Real2Phys(block.src.realpt); + } + if (block.dest_handle) { + if ((block.dest_handle>=XMS_HANDLES) || !xms_handles[block.dest_handle].active ||!xms_handles[block.dest_handle].data) { + return 0xa3; /* Dest Handle invalid */ + } + if (block.dest.offset>=(xms_handles[block.dest_handle].size*1024U)) { + return 0xa4; /* Dest Offset invalid */ + } + if (block.length>xms_handles[block.dest_handle].size*1024U-block.dest.offset) { + return 0xa7; /* Length invalid */ + } + dest=xms_handles[block.dest_handle].phys+block.dest.offset; + } else { + dest=Real2Phys(block.dest.realpt); + } + MEM_BlockCopy(dest,src,block.length); + return 0; +} + +static Bit8u XMS_LockMemory(Bitu handle, Bit32u& address) +{ + /* Check for a valid handle */ + if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].data ) { + return XMS_INVALID_HANDLE; + } + if (xms_handles[handle].locked<255) xms_handles[handle].locked++; + address = xms_handles[handle].phys; + return 0; +}; + +static Bit8u XMS_UnlockMemory(Bitu handle) +{ + /* Check for a valid handle */ + if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].data ) { + return XMS_INVALID_HANDLE; + } + if (xms_handles[handle].locked) { + xms_handles[handle].locked--; + return 0; + } + return XMS_BLOCK_NOT_LOCKED; +}; + +static Bit8u XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFree, Bit16u& size) +{ + /* Check for a valid handle */ + if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].data ) { + return XMS_INVALID_HANDLE; + } + lockCount = xms_handles[handle].locked; + /* Find available blocks */ + numFree=0;{ for (Bitu i=1;i=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].data ) { + return XMS_INVALID_HANDLE; + } + // Block has to be unlocked + if (xms_handles[handle].locked>0) return XMS_BLOCK_LOCKED; + + if (newSize=XMS_HANDLES) return XMS_OUT_OF_HANDLES; + xms_handles[newindex].active = true; + xms_handles[newindex].data = 0; + xms_handles[newindex].locked = 0; + xms_handles[newindex].prev = handle; + xms_handles[newindex].next = next; + xms_handles[newindex].phys = xms_handles[handle].phys+newSize*1024; + xms_handles[newindex].size = sizeDelta; + } + } + /* Remove the mapping from the memory */ + MEM_ClearMapping(PAGE_COUNT(xms_handles[handle].phys),PAGE_COUNT(xms_handles[handle].size*1024)); + // Resize and allocate new mem + xms_handles[handle].size = newSize; + xms_handles[handle].data = malloc(xms_handles[handle].size*1024); + if (!xms_handles[handle].data) E_Exit("XMS:Resize:Out of memory???"); + /* Now Setup the memory mapping for this range */ + MEM_SetupMapping(PAGE_COUNT(xms_handles[handle].phys),PAGE_COUNT(xms_handles[handle].size*1024),xms_handles[handle].data); + // Copy old contents to new mem + memcpy(xms_handles[handle].data,oldmem,newSize*1024); + // finally free old mem + free(oldmem); + + } else if (newSize>xms_handles[handle].size) { + // Lets see if successor has enough free space to do that + void* oldmem = xms_handles[handle].data; + Bit16u oldSize = xms_handles[handle].size; + Bit16u next = xms_handles[handle].next; + Bit16u sizeDelta = newSize - xms_handles[handle].size; + if (nextsizeDelta) { + // remove size from it + xms_handles[next].size-=sizeDelta; + } else { + // exact match, skip it + xms_handles[handle].next = xms_handles[next].next; + xms_handles[handle].active = false; + }; + /* Remove the mapping from the memory */ + MEM_ClearMapping(PAGE_COUNT(xms_handles[handle].phys),PAGE_COUNT(xms_handles[handle].size*1024)); + // Resize and allocate new mem + xms_handles[handle].size = newSize; + xms_handles[handle].data = malloc(xms_handles[handle].size*1024); + if (!xms_handles[handle].data) E_Exit("XMS:Resize:Out of memory???"); + /* Now Setup the memory mapping for this range */ + MEM_SetupMapping(PAGE_COUNT(xms_handles[handle].phys),PAGE_COUNT(xms_handles[handle].size*1024),xms_handles[handle].data); + // Copy old contents to new mem + memcpy(xms_handles[handle].data,oldmem,oldSize*1024); + // finally free old mem + free(oldmem); + } else { + // No more free mem ? + return XMS_OUT_OF_SPACE; + }; + }; + return 0; +}; + + Bitu XMS_Handler(void) { switch (reg_ah) { + case XMS_GET_VERSION: /* 00 */ reg_ax=XMS_VERSION; reg_bx=XMS_DRIVER_VERSION; reg_dx=0; /* No we don't have HMA */ break; - case XMS_ALLOCATE_HIGH_MEMORY: /* 01 */ - case XMS_FREE_HIGH_MEMORY: /* 02 */ case XMS_GLOBAL_ENABLE_A20: /* 03 */ - case XMS_GLOBAL_DISABLE_A20: /* 04 */ case XMS_LOCAL_ENABLE_A20: /* 05 */ + reg_bl = XMS_EnableA20(true); + reg_ax = (reg_bl==0); + break; + case XMS_GLOBAL_DISABLE_A20: /* 04 */ case XMS_LOCAL_DISABLE_A20: /* 06 */ - case XMS_QUERY_A20: /* 07 */ - LOG(LOG_ERROR|LOG_MISC,"XMS:Unhandled call %2X",reg_ah); + reg_bl = XMS_EnableA20(false); + reg_ax = (reg_bl==0); break; + case XMS_QUERY_A20: /* 07 */ + reg_ax = A20ENABLED; + reg_bl = 0; + break; case XMS_QUERY_FREE_EXTENDED_MEMORY: /* 08 */ - /* Scan the tree for free memory and find largest free block */ - { - Bit16u index=1;reg_ax=0;reg_dx=0; - while (xms_handles[index].active) { - if (!xms_handles[index].data) { - if(xms_handles[index].size>reg_ax) reg_ax=xms_handles[index].size; - reg_dx+=xms_handles[index].size; - } - if (xms_handles[index].next=reg_dx) { - /* Check if block is bigger than request */ - if (xms_handles[index].size>reg_dx) { - /* Split Block, find new handle and split up memory */ - Bit16u new_index=1; - while (new_index=XMS_HANDLES) || !xms_handles[reg_dx].active || !xms_handles[reg_dx].data ) { - reg_ax=0; - reg_bl=XMS_INVALID_HANDLE; - return CBRET_NONE; - } - /* Remove the mapping to the memory */ - MEM_ClearMapping(PAGE_COUNT(xms_handles[reg_dx].phys),PAGE_COUNT(xms_handles[reg_dx].size*1024)); - /* Free the memory in the block and merge the blocks previous and next block */ - Bit16u prev=xms_handles[reg_dx].prev; - Bit16u next=xms_handles[reg_dx].next; - free(xms_handles[reg_dx].data); - xms_handles[reg_dx].data=0; - if ((next=XMS_HANDLES) || !xms_handles[block.src_handle].active ||!xms_handles[block.src_handle].data) { - reg_ax=0; - reg_bl=0xa3; /* Src Handle invalid */ - return CBRET_NONE; - } - if (block.src.offset>=(xms_handles[block.src_handle].size*1024U)) { - reg_ax=0; - reg_bl=0xa4; /* Src Offset invalid */ - return CBRET_NONE; - } - if (block.length>xms_handles[block.src_handle].size*1024U-block.src.offset) { - reg_ax=0; - reg_bl=0xa7; /* Length invalid */ - return CBRET_NONE; - - } - src=xms_handles[block.src_handle].phys+block.src.offset; - } else { - src=Real2Phys(block.src.realpt); - } - if (block.dest_handle) { - if ((block.dest_handle>=XMS_HANDLES) || !xms_handles[block.dest_handle].active ||!xms_handles[block.dest_handle].data) { - reg_ax=0; - reg_bl=0xa3; /* Dest Handle invalid */ - return CBRET_NONE; - } - if (block.dest.offset>=(xms_handles[block.dest_handle].size*1024U)) { - reg_ax=0; - reg_bl=0xa4; /* Dest Offset invalid */ - return CBRET_NONE; - } - if (block.length>xms_handles[block.dest_handle].size*1024U-block.dest.offset) { - reg_ax=0; - reg_bl=0xa7; /* Length invalid */ - return CBRET_NONE; - } - dest=xms_handles[block.dest_handle].phys+block.dest.offset; - } else { - dest=Real2Phys(block.dest.realpt); - } - MEM_BlockCopy(dest,src,block.length); - reg_ax=1;reg_bl=0; - } + reg_bl = XMS_MoveMemory(SegPhys(ds)+reg_si); + reg_ax = (reg_bl==0); break; - case XMS_LOCK_EXTENDED_MEMORY_BLOCK: /* 0c */ - { - /* Check for a valid handle */ - if (!reg_dx || (reg_dx>=XMS_HANDLES) || !xms_handles[reg_dx].active || !xms_handles[reg_dx].data ) { - reg_ax=0; - reg_bl=XMS_INVALID_HANDLE; - return CBRET_NONE; - } - if (xms_handles[reg_dx].locked<255) xms_handles[reg_dx].locked++; - reg_bx=(Bit16u)(xms_handles[reg_dx].phys & 0xFFFF); - reg_dx=(Bit16u)(xms_handles[reg_dx].phys>>16); - reg_ax=1; - break; - } + case XMS_LOCK_EXTENDED_MEMORY_BLOCK: { /* 0c */ + Bit32u address; + reg_bl = XMS_LockMemory(reg_dx, address); + if (reg_bl==0) { // success + reg_bx=(Bit16u)(address & 0xFFFF); + reg_dx=(Bit16u)(address >> 16); + }; + reg_ax = (reg_bl==0); + }; break; case XMS_UNLOCK_EXTENDED_MEMORY_BLOCK: /* 0d */ - /* Check for a valid handle */ - if (!reg_dx || (reg_dx>=XMS_HANDLES) || !xms_handles[reg_dx].active || !xms_handles[reg_dx].data ) { - reg_ax=0; - reg_bl=XMS_INVALID_HANDLE; - return CBRET_NONE; - } - if (xms_handles[reg_dx].locked) { - xms_handles[reg_dx].locked--; - reg_ax=1;reg_bl=0; - } else { - reg_ax=0; - reg_bl=XMS_BLOCK_NOT_LOCKED; - } + reg_bl = XMS_UnlockMemory(reg_dx); + reg_ax = (reg_bl==0); break; case XMS_GET_EMB_HANDLE_INFORMATION: /* 0e */ - /* Check for a valid handle */ - if (!reg_dx || (reg_dx>=XMS_HANDLES) || !xms_handles[reg_dx].active || !xms_handles[reg_dx].data ) { - reg_ax=0; - reg_bl=XMS_INVALID_HANDLE; - return CBRET_NONE; - } - reg_bh=xms_handles[reg_dx].locked; - /* Find available blocks */ - reg_bx=0;{ for (Bitu i=1;i(sec); Bitu size=section->Get_int("xmssize"); @@ -360,5 +484,10 @@ void XMS_Init(Section* sec) { xms_handles[1].active=true; xms_handles[1].phys=1088*1024; /* right behind the hma area */ xms_handles[1].size=size*1024-64; + + // A20 Line - PS/2 system control port A + IO_RegisterWriteHandler(0x92,write_p92,"Control Port"); + IO_RegisterReadHandler(0x92,read_p92,"Control Port"); + } From 18ef6fdf508af160cc270958d9c0d31d77074314 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 7 Apr 2003 14:45:18 +0000 Subject: [PATCH 0805/4131] changed xms allocation strategy (big block allocation) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@885 --- src/ints/xms.cpp | 305 +++++++++++++++++++++++++++++------------------ 1 file changed, 191 insertions(+), 114 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 243f9ff8..61a2f9fe 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -58,55 +58,12 @@ #define XMS_BLOCK_LOCKED 0xab struct XMS_Block { - Bit16u prev,next; - Bit16u size; /* Size in kb's */ - PhysPt phys; - Bit8u locked; - void * data; - bool active; -}; - -static Bit16u call_xms; -static RealPt xms_callback; - -static XMS_Block xms_handles[XMS_HANDLES]; - - - -static bool multiplex_xms(void) { - switch (reg_ax) { - case 0x4300: /* XMS installed check */ - reg_al=0x80; - return true; - case 0x4310: /* XMS handler seg:offset */ - SegSet16(es,RealSeg(xms_callback)); - reg_bx=RealOff(xms_callback); - return true; - } - return false; - -}; - -// A20 Line Handlers -static Bit8u controlport_data = 0; -#define A20ENABLED (controlport_data & 2)>0 - -static void write_p92(Bit32u port,Bit8u val) { - // Bit 0 = system reset (switch back to real mode) - if (val & 1) E_Exit("XMS: CPU reset via port 0x92 not supported."); - controlport_data = val; -}; - -static Bit8u read_p92(Bit32u port) { - return controlport_data; -}; - -static Bit8u XMS_EnableA20(bool enable) -{ - Bit8u val = IO_Read (0x92); - if (enable) IO_Write(0x92,val | 2); - else IO_Write(0x92,val & ~2); - return 0; + Bit16u prev,next; + Bit16u size; /* Size in kb's */ + PhysPt phys; + Bit8u locked; + bool allocated; + bool active; }; #pragma pack (push,1) @@ -126,12 +83,109 @@ struct XMS_MemMove{ } GCC_ATTRIBUTE(packed); #pragma pack (pop) +static Bit8u XMS_EnableA20(bool enable) +{ + Bit8u val = IO_Read (0x92); + if (enable) IO_Write(0x92,val | 2); + else IO_Write(0x92,val & ~2); + return 0; +}; + +static Bit8u XMS_GetEnabledA20(void) +{ + return (IO_Read(0x92)&2)>0; +}; + +static Bitu xms_size; +static void* xms_block[C_MEM_MAX_SIZE]; + +static Bit16u call_xms; +static RealPt xms_callback; + +static XMS_Block xms_handles[XMS_HANDLES]; + +#define GETBIGBLOCKNR(nr) nr/(1024*1024) + +static bool AllocateBigBlock(Bitu block1, Bitu block2) +{ + Bitu size,phys; + + if ((block1<1) || (block1>xms_size)) return false; + if ((block2<1) || (block2>xms_size)) return false; + if (block2largestFree) largestFree=xms_handles[index].size; totalFree+=xms_handles[index].size; } @@ -150,7 +204,7 @@ static Bit8u XMS_AllocateMemory(Bitu size, Bit16u& handle) if (size & (PAGE_KB-1)) size=(size&(~(PAGE_KB-1)))+PAGE_KB; while (xms_handles[index].active) { /* Find a free block, check if there's enough size */ - if (!xms_handles[index].data && xms_handles[index].size>=size) { + if (!xms_handles[index].allocated && xms_handles[index].size>=size) { /* Check if block is bigger than request */ if (xms_handles[index].size>size) { /* Split Block, find new handle and split up memory */ @@ -167,7 +221,7 @@ static Bit8u XMS_AllocateMemory(Bitu size, Bit16u& handle) xms_handles[index].next=new_index; xms_handles[index].locked=0; xms_handles[new_index].active=true; - xms_handles[new_index].data=0; + xms_handles[new_index].allocated=0; xms_handles[new_index].locked=0; xms_handles[new_index].size=xms_handles[index].size-size; xms_handles[new_index].phys=xms_handles[index].phys+size*1024; @@ -175,10 +229,7 @@ static Bit8u XMS_AllocateMemory(Bitu size, Bit16u& handle) } /* Use the data from handle index to allocate the actual memory */ handle = index; - xms_handles[index].data=malloc(xms_handles[index].size*1024); - if (!xms_handles[index].data) E_Exit("XMS:Out of memory???"); - /* Now Setup the memory mapping for this range */ - MEM_SetupMapping(PAGE_COUNT(xms_handles[index].phys),PAGE_COUNT(xms_handles[index].size*1024),xms_handles[index].data); + xms_handles[index].allocated = CheckAllocationArea(xms_handles[index].phys,xms_handles[index].size*1024); return 0; } /* Not a free block or too small advance to next one if possible */ @@ -192,7 +243,7 @@ static Bit8u XMS_AllocateMemory(Bitu size, Bit16u& handle) static Bit8u XMS_FreeMemory(Bitu handle) { /* Check for a valid handle */ - if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].data ) { + if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { return XMS_INVALID_HANDLE; } /* Remove the mapping to the memory */ @@ -200,16 +251,15 @@ static Bit8u XMS_FreeMemory(Bitu handle) /* Free the memory in the block and merge the blocks previous and next block */ Bit16u prev=xms_handles[handle].prev; Bit16u next=xms_handles[handle].next; - free(xms_handles[handle].data); - xms_handles[handle].data=0; - if ((next=XMS_HANDLES) || !xms_handles[block.src_handle].active ||!xms_handles[block.src_handle].data) { + if ((block.src_handle>=XMS_HANDLES) || !xms_handles[block.src_handle].active ||!xms_handles[block.src_handle].allocated) { return 0xa3; /* Src Handle invalid */ } if (block.src.offset>=(xms_handles[block.src_handle].size*1024U)) { @@ -244,7 +294,7 @@ static Bit8u XMS_MoveMemory(PhysPt bpt) src=Real2Phys(block.src.realpt); } if (block.dest_handle) { - if ((block.dest_handle>=XMS_HANDLES) || !xms_handles[block.dest_handle].active ||!xms_handles[block.dest_handle].data) { + if ((block.dest_handle>=XMS_HANDLES) || !xms_handles[block.dest_handle].active ||!xms_handles[block.dest_handle].allocated) { return 0xa3; /* Dest Handle invalid */ } if (block.dest.offset>=(xms_handles[block.dest_handle].size*1024U)) { @@ -264,7 +314,7 @@ static Bit8u XMS_MoveMemory(PhysPt bpt) static Bit8u XMS_LockMemory(Bitu handle, Bit32u& address) { /* Check for a valid handle */ - if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].data ) { + if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { return XMS_INVALID_HANDLE; } if (xms_handles[handle].locked<255) xms_handles[handle].locked++; @@ -275,7 +325,7 @@ static Bit8u XMS_LockMemory(Bitu handle, Bit32u& address) static Bit8u XMS_UnlockMemory(Bitu handle) { /* Check for a valid handle */ - if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].data ) { + if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { return XMS_INVALID_HANDLE; } if (xms_handles[handle].locked) { @@ -288,12 +338,12 @@ static Bit8u XMS_UnlockMemory(Bitu handle) static Bit8u XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFree, Bit16u& size) { /* Check for a valid handle */ - if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].data ) { + if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { return XMS_INVALID_HANDLE; } lockCount = xms_handles[handle].locked; /* Find available blocks */ - numFree=0;{ for (Bitu i=1;i=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].data ) { + if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { return XMS_INVALID_HANDLE; } // Block has to be unlocked @@ -309,12 +359,11 @@ static Bit8u XMS_ResizeMemory(Bitu handle, Bitu newSize) if (newSize=XMS_HANDLES) return XMS_OUT_OF_HANDLES; - xms_handles[newindex].active = true; - xms_handles[newindex].data = 0; - xms_handles[newindex].locked = 0; - xms_handles[newindex].prev = handle; - xms_handles[newindex].next = next; - xms_handles[newindex].phys = xms_handles[handle].phys+newSize*1024; - xms_handles[newindex].size = sizeDelta; + xms_handles[newindex].active = true; + xms_handles[newindex].allocated = false; + xms_handles[newindex].locked = 0; + xms_handles[newindex].prev = handle; + xms_handles[newindex].next = next; + xms_handles[newindex].phys = xms_handles[handle].phys+newSize*1024; + xms_handles[newindex].size = sizeDelta; + + xms_handles[handle] .next = newindex; + xms_handles[next] .prev = newindex; } } - /* Remove the mapping from the memory */ - MEM_ClearMapping(PAGE_COUNT(xms_handles[handle].phys),PAGE_COUNT(xms_handles[handle].size*1024)); // Resize and allocate new mem - xms_handles[handle].size = newSize; - xms_handles[handle].data = malloc(xms_handles[handle].size*1024); - if (!xms_handles[handle].data) E_Exit("XMS:Resize:Out of memory???"); - /* Now Setup the memory mapping for this range */ - MEM_SetupMapping(PAGE_COUNT(xms_handles[handle].phys),PAGE_COUNT(xms_handles[handle].size*1024),xms_handles[handle].data); - // Copy old contents to new mem - memcpy(xms_handles[handle].data,oldmem,newSize*1024); - // finally free old mem - free(oldmem); - + xms_handles[handle].size = newSize; + xms_handles[handle].allocated = CheckAllocationArea(xms_handles[handle].phys,xms_handles[handle].size*1024); + } else if (newSize>xms_handles[handle].size) { // Lets see if successor has enough free space to do that - void* oldmem = xms_handles[handle].data; Bit16u oldSize = xms_handles[handle].size; Bit16u next = xms_handles[handle].next; Bit16u sizeDelta = newSize - xms_handles[handle].size; - if (nextsizeDelta) { // remove size from it xms_handles[next].size-=sizeDelta; - } else { + xms_handles[next].phys+=sizeDelta*1024; + } else if (xms_handles[next].size==sizeDelta) { // exact match, skip it xms_handles[handle].next = xms_handles[next].next; - xms_handles[handle].active = false; - }; - /* Remove the mapping from the memory */ - MEM_ClearMapping(PAGE_COUNT(xms_handles[handle].phys),PAGE_COUNT(xms_handles[handle].size*1024)); + xms_handles[next].active = false; + } else { + // Not enough mem available + LOG(LOG_ERROR,"XMS: Resize failure: out of mem 1"); + return XMS_OUT_OF_SPACE; + }; // Resize and allocate new mem - xms_handles[handle].size = newSize; - xms_handles[handle].data = malloc(xms_handles[handle].size*1024); - if (!xms_handles[handle].data) E_Exit("XMS:Resize:Out of memory???"); - /* Now Setup the memory mapping for this range */ - MEM_SetupMapping(PAGE_COUNT(xms_handles[handle].phys),PAGE_COUNT(xms_handles[handle].size*1024),xms_handles[handle].data); - // Copy old contents to new mem - memcpy(xms_handles[handle].data,oldmem,oldSize*1024); - // finally free old mem - free(oldmem); + xms_handles[handle].size = newSize; + xms_handles[handle].allocated = CheckAllocationArea(xms_handles[handle].phys,xms_handles[handle].size*1024); } else { // No more free mem ? + LOG(LOG_ERROR,"XMS: Resize failure: out of mem 2"); return XMS_OUT_OF_SPACE; }; }; @@ -384,6 +423,20 @@ static Bit8u XMS_ResizeMemory(Bitu handle, Bitu newSize) }; +static bool multiplex_xms(void) { + switch (reg_ax) { + case 0x4300: /* XMS installed check */ + reg_al=0x80; + return true; + case 0x4310: /* XMS handler seg:offset */ + SegSet16(es,RealSeg(xms_callback)); + reg_bx=RealOff(xms_callback); + return true; + } + return false; + +}; + Bitu XMS_Handler(void) { switch (reg_ah) { @@ -403,7 +456,7 @@ Bitu XMS_Handler(void) { reg_ax = (reg_bl==0); break; case XMS_QUERY_A20: /* 07 */ - reg_ax = A20ENABLED; + reg_ax = XMS_GetEnabledA20(); reg_bl = 0; break; case XMS_QUERY_FREE_EXTENDED_MEMORY: /* 08 */ @@ -457,10 +510,16 @@ Bitu XMS_Handler(void) { return CBRET_NONE; } +static void XMS_ShutDown(Section * sec) { + for (Bitu i=0; i(sec); - Bitu size=section->Get_int("xmssize"); + Bitu size=xms_size=section->Get_int("xmssize"); if (!size) return; if (size>C_MEM_MAX_SIZE-1) size=C_MEM_MAX_SIZE-1; DOS_AddMultiplexHandler(multiplex_xms); @@ -471,23 +530,41 @@ void XMS_Init(Section* sec) { Bitu i; for (i=0;iAddDestroyFunction(&XMS_ShutDown); } From a34fb7ce608aaf0d24fd3936ed8b2108bd14c8fb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 8 Apr 2003 10:32:22 +0000 Subject: [PATCH 0806/4131] fixed crashes under linux with cdrom Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@886 --- src/dos/cdrom.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 86cf831d..1cb924e7 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -66,46 +66,43 @@ bool CDROM_Interface_SDL::SetDevice (char* path, int forceCD) bool CDROM_Interface_SDL::GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) { - SDL_CDStatus(cd); - if (CD_INDRIVE(cd->status)) { + + if (CD_INDRIVE(SDL_CDStatus(cd))) { stTrack = 1; end = cd->numtracks; FRAMES_TO_MSF(cd->track[cd->numtracks].offset,&leadOut.min,&leadOut.sec,&leadOut.fr); } - return CD_INDRIVE(cd->status); + return CD_INDRIVE(SDL_CDStatus(cd)); }; bool CDROM_Interface_SDL::GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr) { - SDL_CDStatus(cd); - if (CD_INDRIVE(cd->status)) { + if (CD_INDRIVE(SDL_CDStatus(cd))) { FRAMES_TO_MSF(cd->track[track-1].offset+150,&start.min,&start.sec,&start.fr); attr = cd->track[track-1].type; } - return CD_INDRIVE(cd->status); + return CD_INDRIVE(SDL_CDStatus(cd)); }; bool CDROM_Interface_SDL::GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) { - SDL_CDStatus(cd); - if (CD_INDRIVE(cd->status)) { + if (CD_INDRIVE(SDL_CDStatus(cd))) { track = cd->cur_track; index = cd->cur_track; attr = cd->track[track].type; FRAMES_TO_MSF(cd->cur_frame,&relPos.min,&relPos.sec,&relPos.fr); FRAMES_TO_MSF(cd->cur_frame+cd->track[track].offset,&absPos.min,&absPos.sec,&absPos.fr); } - return CD_INDRIVE(cd->status); + return CD_INDRIVE(SDL_CDStatus(cd)); }; bool CDROM_Interface_SDL::GetAudioStatus (bool& playing, bool& pause) { - SDL_CDStatus(cd); - if (CD_INDRIVE(cd->status)) { + if (CD_INDRIVE(SDL_CDStatus(cd))) { playing = (cd->status==CD_PLAYING); pause = (cd->status==CD_PAUSED); } - return CD_INDRIVE(cd->status); + return CD_INDRIVE(SDL_CDStatus(cd)); }; bool CDROM_Interface_SDL::GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) From b4ebb348dfcdfa954f64d3410b5247f6afc63345 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 8 Apr 2003 16:25:02 +0000 Subject: [PATCH 0807/4131] added big block allocation, a20 status and hma mapping Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@887 --- src/hardware/memory.cpp | 97 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 425cab93..041b89e6 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,6 +22,8 @@ #include #include "dosbox.h" #include "mem.h" +#include "inout.h" +#include "setup.h" HostPt memory; HostPt ReadHostTable[MAX_PAGES]; @@ -148,6 +150,7 @@ void MEM_ClearMapping(Bitu startpage,Bitu pages) { } } +#if (!C_EXTRAINLINE) static void HandlerWritew(Bitu page,PhysPt pt,Bit16u val) { WriteHandlerTable[page](pt+0,(Bit8u)(val & 0xff)); WriteHandlerTable[page](pt+1,(Bit8u)((val >> 8) & 0xff) ); @@ -169,6 +172,7 @@ void mem_writeb(PhysPt pt,Bit8u val) { void mem_writew(PhysPt pt,Bit16u val) { if (!WriteHostTable[pt >> PAGE_SHIFT]) { +// HandlerWritew(pt >> PAGE_SHIFT,pt,val); WriteHandlerTable[pt >> PAGE_SHIFT](pt+0,(Bit8u)(val & 0xff)); WriteHandlerTable[pt >> PAGE_SHIFT](pt+1,(Bit8u)((val >> 8) & 0xff) ); } else writew(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); @@ -176,6 +180,7 @@ void mem_writew(PhysPt pt,Bit16u val) { void mem_writed(PhysPt pt,Bit32u val) { if (!WriteHostTable[pt >> PAGE_SHIFT]) { +// HandlerWrited(pt >> PAGE_SHIFT,pt,val); WriteHandlerTable[pt >> PAGE_SHIFT](pt+0,(Bit8u)(val & 0xff)); WriteHandlerTable[pt >> PAGE_SHIFT](pt+1,(Bit8u)((val >> 8) & 0xff) ); WriteHandlerTable[pt >> PAGE_SHIFT](pt+2,(Bit8u)((val >> 16) & 0xff) ); @@ -205,6 +210,7 @@ Bit8u mem_readb(PhysPt pt) { Bit16u mem_readw(PhysPt pt) { if (!ReadHostTable[pt >> PAGE_SHIFT]) { +// return HandlerReadw(pt >> PAGE_SHIFT,pt); return (ReadHandlerTable[pt >> PAGE_SHIFT](pt+0)) | (ReadHandlerTable[pt >> PAGE_SHIFT](pt+1)) << 8; @@ -214,6 +220,7 @@ Bit16u mem_readw(PhysPt pt) { Bit32u mem_readd(PhysPt pt){ if (ReadHostTable[pt >> PAGE_SHIFT]) return readd(ReadHostTable[pt >> PAGE_SHIFT]+pt); else { +// return HandlerReadd(pt >> PAGE_SHIFT,pt); return (ReadHandlerTable[pt >> PAGE_SHIFT](pt+0)) | (ReadHandlerTable[pt >> PAGE_SHIFT](pt+1)) << 8 | @@ -221,6 +228,80 @@ Bit32u mem_readd(PhysPt pt){ (ReadHandlerTable[pt >> PAGE_SHIFT](pt+3)) << 24; } } +#endif + +// Big block memory alloction + +#define GETBIGBLOCKNR(nr) nr/(1024*1024) + +static void* mem_block[C_MEM_MAX_SIZE]; + +static bool AllocateBigBlock(Bitu block) +{ + if ((block<1) || (block>C_MEM_MAX_SIZE)) return false; + if (!mem_block[block]) { + // Allocate it + mem_block[block] = malloc(1024*1024); + if (!mem_block[block]) E_Exit("XMS: Failed to allocate XMS block."); + else LOG(LOG_ERROR,"XMS: Allocated big block %d.",block); + // Map it with default handler + MEM_SetupMapping(PAGE_COUNT(1024*1024*block),PAGE_COUNT(1024*1024),mem_block[block]); + } + return true; +}; + +static Bit8u AllocateMem_ReadHandler(PhysPt pt) +{ + // Allocate mem, set deafult handler + if (AllocateBigBlock(GETBIGBLOCKNR(pt))) { + // Pass request to new handler + return mem_readb(pt); + } + return 0; +} + +static void AllocateMem_WriteHandler(PhysPt pt,Bit8u val) +{ + // Allocate mem, if needed + if (AllocateBigBlock(GETBIGBLOCKNR(pt))) { + // Pass request to new handler + mem_writeb(pt,val); + } +} + +// A20 Line Handlers +static Bit8u controlport_data = 0; + +static void write_p92(Bit32u port,Bit8u val) { + // Bit 0 = system reset (switch back to real mode) + if (val&1) E_Exit("XMS: CPU reset via port 0x92 not supported."); + if ((val&2) & !(controlport_data&2)) { + // ensable HMA + for (Bitu p=PAGE_COUNT(1024*1024);pAddDestroyFunction(&MEM_ShutDown); } From e5d49d2072d740d6ebc6570a68c9288b3744324a Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 8 Apr 2003 16:25:31 +0000 Subject: [PATCH 0808/4131] added xms.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@888 --- src/ints/xms.cpp | 141 ++++++--------------------------------------- src/ints/xms.h | 34 +++++++++++ visualc/dosbox.dsp | 4 ++ 3 files changed, 56 insertions(+), 123 deletions(-) create mode 100644 src/ints/xms.h diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 61a2f9fe..02948fd7 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -25,6 +25,7 @@ #include "dos_system.h" #include "setup.h" #include "inout.h" +#include "xms.h" #define XMS_HANDLES 50 /* 50 XMS Memory Blocks */ #define XMS_VERSION 0x0300 /* version 3.00 */ @@ -83,7 +84,7 @@ struct XMS_MemMove{ } GCC_ATTRIBUTE(packed); #pragma pack (pop) -static Bit8u XMS_EnableA20(bool enable) +static Bitu XMS_EnableA20(bool enable) { Bit8u val = IO_Read (0x92); if (enable) IO_Write(0x92,val | 2); @@ -91,96 +92,17 @@ static Bit8u XMS_EnableA20(bool enable) return 0; }; -static Bit8u XMS_GetEnabledA20(void) +static Bitu XMS_GetEnabledA20(void) { return (IO_Read(0x92)&2)>0; }; -static Bitu xms_size; -static void* xms_block[C_MEM_MAX_SIZE]; - static Bit16u call_xms; static RealPt xms_callback; static XMS_Block xms_handles[XMS_HANDLES]; -#define GETBIGBLOCKNR(nr) nr/(1024*1024) - -static bool AllocateBigBlock(Bitu block1, Bitu block2) -{ - Bitu size,phys; - - if ((block1<1) || (block1>xms_size)) return false; - if ((block2<1) || (block2>xms_size)) return false; - if (block2=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { @@ -269,7 +192,7 @@ static Bit8u XMS_FreeMemory(Bitu handle) return 0; }; -static Bit8u XMS_MoveMemory(PhysPt bpt) +static Bitu XMS_MoveMemory(PhysPt bpt) { XMS_MemMove block; /* Fill the block with mem_read's and shit */ @@ -311,7 +234,7 @@ static Bit8u XMS_MoveMemory(PhysPt bpt) return 0; } -static Bit8u XMS_LockMemory(Bitu handle, Bit32u& address) +static Bitu XMS_LockMemory(Bitu handle, Bit32u& address) { /* Check for a valid handle */ if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { @@ -322,7 +245,7 @@ static Bit8u XMS_LockMemory(Bitu handle, Bit32u& address) return 0; }; -static Bit8u XMS_UnlockMemory(Bitu handle) +static Bitu XMS_UnlockMemory(Bitu handle) { /* Check for a valid handle */ if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { @@ -335,7 +258,7 @@ static Bit8u XMS_UnlockMemory(Bitu handle) return XMS_BLOCK_NOT_LOCKED; }; -static Bit8u XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFree, Bit16u& size) +static Bitu XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFree, Bit16u& size) { /* Check for a valid handle */ if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { @@ -348,7 +271,7 @@ static Bit8u XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numF return 0; }; -static Bit8u XMS_ResizeMemory(Bitu handle, Bitu newSize) +static Bitu XMS_ResizeMemory(Bitu handle, Bitu newSize) { /* Check for a valid handle */ if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { @@ -389,7 +312,8 @@ static Bit8u XMS_ResizeMemory(Bitu handle, Bitu newSize) } // Resize and allocate new mem xms_handles[handle].size = newSize; - xms_handles[handle].allocated = CheckAllocationArea(xms_handles[handle].phys,xms_handles[handle].size*1024); + xms_handles[handle].allocated = 1; + //CheckAllocationArea(xms_handles[handle].phys,xms_handles[handle].size*1024); } else if (newSize>xms_handles[handle].size) { // Lets see if successor has enough free space to do that @@ -412,7 +336,8 @@ static Bit8u XMS_ResizeMemory(Bitu handle, Bitu newSize) }; // Resize and allocate new mem xms_handles[handle].size = newSize; - xms_handles[handle].allocated = CheckAllocationArea(xms_handles[handle].phys,xms_handles[handle].size*1024); + xms_handles[handle].allocated = 1; + //CheckAllocationArea(xms_handles[handle].phys,xms_handles[handle].size*1024); } else { // No more free mem ? LOG(LOG_ERROR,"XMS: Resize failure: out of mem 2"); @@ -510,16 +435,9 @@ Bitu XMS_Handler(void) { return CBRET_NONE; } -static void XMS_ShutDown(Section * sec) { - for (Bitu i=0; i(sec); - Bitu size=xms_size=section->Get_int("xmssize"); + Bitu size=section->Get_int("xmssize"); if (!size) return; if (size>C_MEM_MAX_SIZE-1) size=C_MEM_MAX_SIZE-1; DOS_AddMultiplexHandler(multiplex_xms); @@ -543,28 +461,5 @@ void XMS_Init(Section* sec) { xms_handles[1].active=true; xms_handles[1].phys=1088*1024; /* right behind the hma area */ xms_handles[1].size=size*1024-64; - - // Setup default handlers for unallocated xms - Bitu start = xms_handles[1].phys; - Bitu end = start + xms_handles[1].size*1024; - for (Bitu p=PAGE_COUNT(start);pAddDestroyFunction(&XMS_ShutDown); } diff --git a/src/ints/xms.h b/src/ints/xms.h new file mode 100644 index 00000000..976dcde1 --- /dev/null +++ b/src/ints/xms.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __XMS_H__ +#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 \ No newline at end of file diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index a05f882a..58c2e78a 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -556,6 +556,10 @@ SOURCE=..\src\ints\mouse.cpp SOURCE=..\src\ints\xms.cpp # End Source File +# Begin Source File + +SOURCE=..\src\ints\xms.h +# End Source File # End Group # Begin Group "misc" From 24e82f2d331b823abd7c1eadb5ae1e72e4401855 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 8 Apr 2003 18:24:38 +0000 Subject: [PATCH 0809/4131] command /c works with batch files as well :) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@889 --- src/shell/shell.cpp | 24 +++++++++++++++++++++++- src/shell/shell_inc.h | 3 ++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 455f528d..b5e000d3 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -93,13 +93,35 @@ void DOS_Shell::ParseLine(char * line) { +void DOS_Shell::RunInternal(void) +{ + char input_line[CMD_MAXLINE]; + std::string line; + while(bf && bf->ReadLine(input_line)) + { + if (echo) { + if (input_line[0]!='@') { + ShowPrompt(); + WriteOut(input_line); + WriteOut("\n"); + }; + }; + ParseLine(input_line); + } + return; +} + + void DOS_Shell::Run(void) { char input_line[CMD_MAXLINE]; std::string line; if (cmd->FindStringRemain("/C",line)) { strcpy(input_line,line.c_str()); - ParseLine(input_line); + DOS_Shell temp; + temp.echo = echo; + temp.ParseLine(input_line); //for *.exe *.com |*.bat creates the bf needed by runinternal; + temp.RunInternal(); // exits when no bf is found. return; } /* Start a normal shell and check for a first command init */ diff --git a/src/shell/shell_inc.h b/src/shell/shell_inc.h index 21947803..a3057e31 100644 --- a/src/shell/shell_inc.h +++ b/src/shell/shell_inc.h @@ -52,6 +52,7 @@ class DOS_Shell : public Program { public: DOS_Shell(); void Run(void); + void RunInternal(void); //for command /C /* A load of subfunctions */ void ParseLine(char * line); Bit32u GetRedirection(char *s, char **ifn, char **ofn); @@ -90,7 +91,7 @@ public: Bitu index; Bitu size; } old; - + }; struct SHELL_Cmd { From ddd427f40fbe5ff6e36a78726f9a49fafe71dc03 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 8 Apr 2003 18:48:16 +0000 Subject: [PATCH 0810/4131] Updates for new Segment structure Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@890 --- include/regs.h | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/include/regs.h b/include/regs.h index cc7e601b..a7bf99bc 100644 --- a/include/regs.h +++ b/include/regs.h @@ -40,9 +40,13 @@ struct Segment { PhysPt 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]; @@ -69,7 +73,7 @@ struct CPU_Regs { GenReg32 regs[8],ip; }; -extern Segment Segs[6]; +extern Segments Segs; extern Flag_Info flags; extern CPU_Regs cpu_regs; @@ -78,11 +82,11 @@ extern CPU_Regs cpu_regs; //#define SegValue(index) Segs[index].val INLINE PhysPt SegPhys(SegNames index) { - return Segs[index].phys; + return Segs.phys[index]; } INLINE Bit16u SegValue(SegNames index) { - return Segs[index].val; + return Segs.val[index]; } @@ -92,8 +96,8 @@ INLINE RealPt RealMakeSeg(SegNames index,Bit16u off) { INLINE void SegSet16(Bitu index,Bit16u val) { - Segs[index].val=val; - Segs[index].phys=val << 4; + Segs.val[index]=val; + Segs.phys[index]=val << 4; } From 9fbf3c7b60952048633edad428a9cae6aff36985 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 8 Apr 2003 18:50:26 +0000 Subject: [PATCH 0811/4131] Remove dependency for cpu.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@891 --- include/pic.h | 6 ++++-- src/dos/dos_devices.cpp | 2 +- src/dos/dos_execute.cpp | 2 +- src/dos/dos_ioctl.cpp | 2 +- src/dos/dos_mscdex.cpp | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/include/pic.h b/include/pic.h index 947166bb..af16996e 100644 --- a/include/pic.h +++ b/include/pic.h @@ -20,7 +20,10 @@ #define __PIC_H -#include "cpu.h" +/* CPU Cycle Timing */ +extern Bits CPU_Cycles; +extern Bits CPU_CycleLeft; +extern Bits CPU_CycleMax; typedef void (PIC_EOIHandler) (void); typedef void (* PIC_EventHandler)(void); @@ -32,7 +35,6 @@ typedef void (* PIC_EventHandler)(void); extern Bitu PIC_IRQCheck; extern Bitu PIC_IRQActive; - extern Bitu PIC_Ticks; INLINE Bitu PIC_Index(void) { diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index ae2630b5..3cab0a7d 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -19,7 +19,7 @@ #include #include "dosbox.h" #include "callback.h" -#include "cpu.h" +#include "regs.h" #include "mem.h" #include "bios.h" #include "dos_inc.h" diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index fa4e4ca1..e863ddd8 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -20,7 +20,7 @@ #include "dosbox.h" #include "mem.h" #include "dos_inc.h" -#include "cpu.h" +#include "regs.h" #include "callback.h" #include "debug.h" diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 57d44941..2bcda42b 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -20,7 +20,7 @@ #include "dosbox.h" #include "callback.h" #include "mem.h" -#include "cpu.h" +#include "regs.h" #include "dos_inc.h" #define MAX_DEVICE 20 diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index e4e13832..6803b964 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -18,7 +18,7 @@ #include #include -#include "cpu.h" +#include "regs.h" #include "callback.h" #include "dos_system.h" #include "dos_inc.h" From d4d1d72f6a0cdee46a1419c1903fe745ccf5d892 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 8 Apr 2003 18:54:17 +0000 Subject: [PATCH 0812/4131] Some prelimenary changes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@892 --- include/cpu.h | 182 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 143 insertions(+), 39 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index f0195944..cfa16740 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -23,18 +23,19 @@ #include "regs.h" #include "mem.h" -/* Some common Defines */ -/* A CPU Handler */ -typedef Bitu (CPU_Decoder)(void); -extern CPU_Decoder * cpudecoder; - /* CPU Cycle Timing */ extern Bits CPU_Cycles; extern Bits CPU_CycleLeft; extern Bits CPU_CycleMax; +/* Some common Defines */ +/* A CPU Handler */ +typedef Bitu (CPU_Decoder)(void); +extern CPU_Decoder * cpudecoder; + + //CPU Stuff -void SetCPU16bit(); +void SetCPU16bit( ); //Types of Flag changing instructions enum { @@ -100,65 +101,168 @@ bool get_PF(void); // Descriptor // ********************************************************************* +#define CR0_PROTECTION 0x00000001 +#define CR0_FPUENABLED 0x00000002 +#define CR0_FPUMONITOR 0x00000004 +#define CR0_TASKSWITCH 0x00000008 +#define CR0_FPUPRESENT 0x00000010 +#define CR0_PAGING 0x80000000 + + +#define DESC_INVALID 0x0 +#define DESC_286_TSS_A 0x1 +#define DESC_LDT 0x2 +#define DESC_286_TSS_B 0x3 +#define DESC_286_CALL_GATE 0x4 +#define DESC_TASK_GATE 0x5 +#define DESC_286_INT_GATE 0x6 +#define DESC_286_TRAP_GATE 0x7 + +#define DESC_386_TSS_A 0x9 +#define DESC_386_TSS_B 0xb +#define DESC_386_CALL_GATE 0xc +#define DESC_386_INT_GATE 0xe +#define DESC_386_TRAP_GATE 0xf + + class Descriptor { public: - void LoadValues (Bit32u address) { - Bit32u* data = (Bit32u*)&desc; + Descriptor() { saved.fill[0]=saved.fill[1]=0; } + + void Load(PhysPt address) { + Bit32u* data = (Bit32u*)&saved; *data = mem_readd(address); *(data+1) = mem_readd(address+4); } - void SaveValues (Bit32u address) { - Bit32u* data = (Bit32u*)&desc; + void Save(PhysPt address) { + Bit32u* data = (Bit32u*)&saved; mem_writed(address,*data); mem_writed(address+4,*(data+1)); } - Bit32u GetBase (void) { return (desc.base_24_31<<24) | (desc.base_16_23<<16) | desc.base_0_15; }; - Bit32u GetLimit (void) { - Bit32u limit = (desc.limit_16_19<<16) | desc.limit_0_15; - if (desc.g) return (limit<<12) | 0xFFF; + 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 GetType(void) { + return saved.seg.type; + } + Bitu GetOffset(void) { + return (saved.gate.offset_16_31 << 16) | saved.gate.offset_0_15; + } + Bitu Conforming(void) { + return saved.seg.type & 8; + } + Bitu GetDPL(void) { + return saved.seg.dpl; + } public: #pragma pack(1) - typedef struct SDescriptor { + struct S_Descriptor { Bit32u limit_0_15 :16; Bit32u base_0_15 :16; Bit32u base_16_23 :8; - Bit32u type :5; + Bit32u type :4; + Bit32u s :1; Bit32u dpl :2; Bit32u p :1; Bit32u limit_16_19 :4; Bit32u avl :1; Bit32u r :1; - Bit32u d :1; + Bit32u big :1; Bit32u g :1; Bit32u base_24_31 :8; - } TDescriptor; -#pragma pack() - - TDescriptor desc; -}; - -class DescriptorTable -{ - Bit32u GetBase (void) { return baseAddress; }; - Bit16u GetLimit (void) { return limit; }; - void SetBase (Bit32u base) { baseAddress = base; }; - void SetLimit (Bit16u size) { limit = size; }; - - bool GetDescriptor (Bit16u selector, Descriptor& desc) { - // selector = the plain index - if (selector>=limit>>3) return false; - desc.LoadValues(baseAddress+(selector<<3)); - return true; }; + struct G_Descriptor { + Bit32u offset_0_15 :16; + Bit32u selector :16; + Bit32u paramcount :5; + Bit32u reserved :3; + Bit32u type :4; + Bit32u s :1; + Bit32u dpl :2; + Bit32u p :1; + Bit32u offset_16_31 :16; + }; +#pragma pack() -private: - Bit32u baseAddress; - Bit16u limit; + union { + S_Descriptor seg; + G_Descriptor gate; + Bit32u fill[2]; + } saved; }; +class DescriptorTable { +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; + } + } + + Bitu SLDT(void) { + return ldt_value; + } + bool LLDT(Bitu value) { +//TODO checking + Descriptor desc; + GetDescriptor(value,desc); + ldt_base=desc.GetBase(); + ldt_limit=desc.GetLimit(); + ldt_value=value; + return true; + } +private: + PhysPt ldt_base; + Bitu ldt_limit; + Bitu ldt_value; +}; + +struct CPUBlock { + Bitu protmode; /* Are we in protected mode */ + Bitu cpl; /* Current Privilege */ + Bitu conforming; /* Current descriptor is conforming */ + Bitu big; /* Current descriptor is USE32 */ + Bitu state; + Bitu cr0; + GDTDescriptorTable gdt; + DescriptorTable idt; + struct { + Bitu prefix,entry; + } full; +}; + +extern CPUBlock cpu; + #endif From 109bd9958f6884a70ac632ac2b40df69e8ffee6d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 8 Apr 2003 19:01:30 +0000 Subject: [PATCH 0813/4131] Small clean up and fix with new cpu.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@893 --- src/cpu/cpu.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 9ccb2d47..08f55805 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -23,15 +23,11 @@ #include "keyboard.h" #include "setup.h" -struct CPUBlock { - -}; - Flag_Info flags; CPU_Regs cpu_regs; -Segment Segs[6]; +Segments Segs; Bits CPU_Cycles=0; Bits CPU_CycleLeft=0; From 0063eb982dde3348d29ce47ee6ce17eadbbf684b Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 8 Apr 2003 19:11:36 +0000 Subject: [PATCH 0814/4131] fixed error (SegPhys) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@894 --- src/debug/debug.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 5a849e6d..5b5fa313 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -467,7 +467,7 @@ bool DEBUG_IntBreakpoint(Bit8u intNum) static bool StepOver() { - PhysPt start=Segs[cs].phys+reg_eip; + PhysPt start=SegPhys(cs)+reg_eip; char dline[200];Bitu size; size=DasmI386(dline, start, reg_eip, false); From d43d304911cc0516f5e93ba3cb921f85ace9bc7c Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 9 Apr 2003 08:51:57 +0000 Subject: [PATCH 0815/4131] fixed bug (xms mapping destroyed hma) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@895 --- src/hardware/memory.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 041b89e6..d5ebd87a 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -234,18 +234,21 @@ Bit32u mem_readd(PhysPt pt){ #define GETBIGBLOCKNR(nr) nr/(1024*1024) -static void* mem_block[C_MEM_MAX_SIZE]; +static Bit8u* mem_block[C_MEM_MAX_SIZE]; static bool AllocateBigBlock(Bitu block) { if ((block<1) || (block>C_MEM_MAX_SIZE)) return false; if (!mem_block[block]) { // Allocate it - mem_block[block] = malloc(1024*1024); + Bitu start = (block==1)? (1024+64)*1024:1024*1024*block; + Bitu size = (block==1)? (1024-64)*1024:1024*1024; + mem_block[block] = (Bit8u*)malloc(size); if (!mem_block[block]) E_Exit("XMS: Failed to allocate XMS block."); - else LOG(LOG_ERROR,"XMS: Allocated big block %d.",block); +// else LOG(LOG_ERROR,"XMS: Allocated big block %d.",block); // Map it with default handler - MEM_SetupMapping(PAGE_COUNT(1024*1024*block),PAGE_COUNT(1024*1024),mem_block[block]); + MEM_SetupMapping(PAGE_COUNT(start),PAGE_COUNT(size),mem_block[block]); + memset(mem_block[block],0,size); } return true; }; @@ -313,8 +316,8 @@ void MEM_Init(Section * sect) { ReadHandlerTable[i]=&Default_ReadHandler; WriteHandlerTable[i]=&Default_WriteHandler; } - /* Allocate the first mb of memory */ - memory=(Bit8u *)malloc(1024*1024); + /* Allocate the first mb of memory + hma */ + memory=(Bit8u *)malloc(1024*1024+64*1024); if (!memory) { throw("Can't allocate memory for memory"); } @@ -324,7 +327,7 @@ void MEM_Init(Section * sect) { /* Setup tables for HMA Area */ MEM_SetupMapping(PAGE_COUNT(1024*1024),PAGE_COUNT(64*1024),memory); // Setup default handlers for unallocated xms - for (Bitu p=PAGE_COUNT(1024*1024);p Date: Wed, 9 Apr 2003 09:01:30 +0000 Subject: [PATCH 0816/4131] delete -> free Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@896 --- src/hardware/memory.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index d5ebd87a..25c65f45 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -279,13 +279,8 @@ static void write_p92(Bit32u port,Bit8u val) { // Bit 0 = system reset (switch back to real mode) if (val&1) E_Exit("XMS: CPU reset via port 0x92 not supported."); if ((val&2) & !(controlport_data&2)) { - // ensable HMA - for (Bitu p=PAGE_COUNT(1024*1024);p Date: Wed, 9 Apr 2003 09:23:31 +0000 Subject: [PATCH 0817/4131] remove static from xms-funcs Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@897 --- src/ints/xms.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 02948fd7..9adbd282 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -84,7 +84,7 @@ struct XMS_MemMove{ } GCC_ATTRIBUTE(packed); #pragma pack (pop) -static Bitu XMS_EnableA20(bool enable) +Bitu XMS_EnableA20(bool enable) { Bit8u val = IO_Read (0x92); if (enable) IO_Write(0x92,val | 2); @@ -92,7 +92,7 @@ static Bitu XMS_EnableA20(bool enable) return 0; }; -static Bitu XMS_GetEnabledA20(void) +Bitu XMS_GetEnabledA20(void) { return (IO_Read(0x92)&2)>0; }; @@ -102,7 +102,7 @@ static RealPt xms_callback; static XMS_Block xms_handles[XMS_HANDLES]; -static Bitu XMS_QueryFreeMemory(Bit16u& largestFree, Bit16u& totalFree) { +Bitu XMS_QueryFreeMemory(Bit16u& largestFree, Bit16u& totalFree) { /* Scan the tree for free memory and find largest free block */ Bit16u index=1; largestFree=totalFree=0; @@ -118,7 +118,7 @@ static Bitu XMS_QueryFreeMemory(Bit16u& largestFree, Bit16u& totalFree) { return 0; }; -static Bitu XMS_AllocateMemory(Bitu size, Bit16u& handle) +Bitu XMS_AllocateMemory(Bitu size, Bit16u& handle) // size = kb { Bit16u index=1; @@ -163,7 +163,7 @@ static Bitu XMS_AllocateMemory(Bitu size, Bit16u& handle) return XMS_OUT_OF_SPACE; }; -static Bitu XMS_FreeMemory(Bitu handle) +Bitu XMS_FreeMemory(Bitu handle) { /* Check for a valid handle */ if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { @@ -192,7 +192,7 @@ static Bitu XMS_FreeMemory(Bitu handle) return 0; }; -static Bitu XMS_MoveMemory(PhysPt bpt) +Bitu XMS_MoveMemory(PhysPt bpt) { XMS_MemMove block; /* Fill the block with mem_read's and shit */ @@ -234,7 +234,7 @@ static Bitu XMS_MoveMemory(PhysPt bpt) return 0; } -static Bitu XMS_LockMemory(Bitu handle, Bit32u& address) +Bitu XMS_LockMemory(Bitu handle, Bit32u& address) { /* Check for a valid handle */ if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { @@ -245,7 +245,7 @@ static Bitu XMS_LockMemory(Bitu handle, Bit32u& address) return 0; }; -static Bitu XMS_UnlockMemory(Bitu handle) +Bitu XMS_UnlockMemory(Bitu handle) { /* Check for a valid handle */ if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { @@ -258,7 +258,7 @@ static Bitu XMS_UnlockMemory(Bitu handle) return XMS_BLOCK_NOT_LOCKED; }; -static Bitu XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFree, Bit16u& size) +Bitu XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFree, Bit16u& size) { /* Check for a valid handle */ if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { @@ -271,7 +271,7 @@ static Bitu XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFr return 0; }; -static Bitu XMS_ResizeMemory(Bitu handle, Bitu newSize) +Bitu XMS_ResizeMemory(Bitu handle, Bitu newSize) { /* Check for a valid handle */ if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { From 5e968ab24cc5570839fb4dda5ae8c65a9c04f65b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 9 Apr 2003 11:48:09 +0000 Subject: [PATCH 0818/4131] added xms.h to extra dist Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@898 --- src/ints/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ints/Makefile.am b/src/ints/Makefile.am index f5a095ec..3a677e22 100644 --- a/src/ints/Makefile.am +++ b/src/ints/Makefile.am @@ -1,6 +1,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libints.a +EXTRA_DIST = xms.h libints_a_SOURCES = mouse.cpp xms.cpp ems.cpp \ int10.cpp int10.h int10_char.cpp int10_memory.cpp int10_misc.cpp int10_modes.cpp int10_pal.cpp int10_put_pixel.cpp \ bios.cpp bios_disk.cpp bios_keyboard.cpp From 517cde1b3c3408bcbf0e539a33a38a8ae3ae5780 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 10 Apr 2003 10:32:59 +0000 Subject: [PATCH 0819/4131] cleanup patch from Max Horn Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@899 --- src/dos/dos_classes.cpp | 1 - src/ints/int10_modes.cpp | 219 ++++++++++++++++----------------------- src/shell/shell.cpp | 2 - src/shell/shell_cmds.cpp | 40 +++---- 4 files changed, 112 insertions(+), 150 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 00b7cc71..0618c108 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -148,7 +148,6 @@ Bit16u DOS_PSP::FindFreeFileEntry(void) Bit16u DOS_PSP::FindEntryByHandle(Bit8u handle) { PhysPt files=Real2Phys(sGet(sPSP,file_table)); - Bit16u max = sGet(sPSP,max_files); for (Bit16u i=0;i Date: Thu, 10 Apr 2003 10:35:50 +0000 Subject: [PATCH 0820/4131] removed clear mapping on free xms Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@900 --- src/ints/xms.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 9adbd282..6905a710 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -169,8 +169,6 @@ Bitu XMS_FreeMemory(Bitu handle) if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { return XMS_INVALID_HANDLE; } - /* Remove the mapping to the memory */ - MEM_ClearMapping(PAGE_COUNT(xms_handles[handle].phys),PAGE_COUNT(xms_handles[handle].size*1024)); /* Free the memory in the block and merge the blocks previous and next block */ Bit16u prev=xms_handles[handle].prev; Bit16u next=xms_handles[handle].next; From 3091207f6a45ef249d532808fabfe1aaaadf964b Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 10 Apr 2003 15:42:46 +0000 Subject: [PATCH 0821/4131] made it safer if accessing non existant subunit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@901 --- src/dos/dos_mscdex.cpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 6803b964..8c545b9e 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -288,6 +288,7 @@ void CMscdex::GetDriverInfo (PhysPt data) bool CMscdex::GetCDInfo(Bit8u subUnit, Bit8u& tr1, Bit8u& tr2, TMSF& leadOut) { + if (subUnit>=numDrives) return false; int tr1i,tr2i; dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioTracks(tr1i,tr2i,leadOut); if (!dinfo[subUnit].lastResult) { @@ -302,6 +303,7 @@ bool CMscdex::GetCDInfo(Bit8u subUnit, Bit8u& tr1, Bit8u& tr2, TMSF& leadOut) bool CMscdex::GetTrackInfo(Bit8u subUnit, Bit8u track, Bit8u& attr, TMSF& start) { + if (subUnit>=numDrives) return false; dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioTrackInfo(track,start,attr); if (!dinfo[subUnit].lastResult) { attr = 0; @@ -312,6 +314,7 @@ bool CMscdex::GetTrackInfo(Bit8u subUnit, Bit8u track, Bit8u& attr, TMSF& start) bool CMscdex::PlayAudioSector(Bit8u subUnit, Bit32u sector, Bit32u length) { + if (subUnit>=numDrives) return false; // If value from last stop is used, this is meant as a resume // better start using resume command if (dinfo[subUnit].audioPaused && (sector==dinfo[subUnit].audioStart)) { @@ -330,6 +333,7 @@ bool CMscdex::PlayAudioSector(Bit8u subUnit, Bit32u sector, Bit32u length) bool CMscdex::PlayAudioMSF(Bit8u subUnit, Bit32u start, Bit32u length) { + if (subUnit>=numDrives) return false; Bit8u min = (start>>16) & 0xFF; Bit8u sec = (start>> 8) & 0xFF; Bit8u fr = (start>> 0) & 0xFF; @@ -343,6 +347,7 @@ bool CMscdex::PlayAudioMSF(Bit8u subUnit, Bit32u start, Bit32u length) bool CMscdex::GetSubChannelData(Bit8u subUnit, Bit8u& attr, Bit8u& track, Bit8u &index, TMSF& rel, TMSF& abs) { + if (subUnit>=numDrives) return false; dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioSub(attr,track,index,rel,abs); if (!dinfo[subUnit].lastResult) { attr = track = index = 0; @@ -354,6 +359,7 @@ bool CMscdex::GetSubChannelData(Bit8u subUnit, Bit8u& attr, Bit8u& track, Bit8u bool CMscdex::GetAudioStatus(Bit8u subUnit, bool& playing, bool& pause, TMSF& start, TMSF& end) { + if (subUnit>=numDrives) return false; dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioStatus(playing,pause); if (dinfo[subUnit].lastResult) { // Start @@ -378,6 +384,7 @@ bool CMscdex::GetAudioStatus(Bit8u subUnit, bool& playing, bool& pause, TMSF& st bool CMscdex::StopAudio(Bit8u subUnit) { + if (subUnit>=numDrives) return false; if (dinfo[subUnit].audioPlay) dinfo[subUnit].lastResult = cdrom[subUnit]->PauseAudio(false); else dinfo[subUnit].lastResult = cdrom[subUnit]->StopAudio(); @@ -399,11 +406,13 @@ bool CMscdex::StopAudio(Bit8u subUnit) bool CMscdex::ResumeAudio(Bit8u subUnit) { + if (subUnit>=numDrives) return false; return dinfo[subUnit].lastResult = PlayAudioSector(subUnit,dinfo[subUnit].audioStart,dinfo[subUnit].audioEnd); }; Bit32u CMscdex::GetVolumeSize(Bit8u subUnit) { + if (subUnit>=numDrives) return false; Bit8u tr1,tr2; TMSF leadOut; dinfo[subUnit].lastResult = GetCDInfo(subUnit,tr1,tr2,leadOut); @@ -413,11 +422,13 @@ Bit32u CMscdex::GetVolumeSize(Bit8u subUnit) bool CMscdex::GetUPC(Bit8u subUnit, Bit8u& attr, char* upc) { + if (subUnit>=numDrives) return false; return dinfo[subUnit].lastResult = cdrom[subUnit]->GetUPC(attr,&upc[0]); }; bool CMscdex::ReadSectors(Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data) { + if (subUnit>=numDrives) return false; void* buffer = (void*)Phys2Host(data); dinfo[subUnit].lastResult = cdrom[subUnit]->ReadSectors(buffer,raw,sector,num); return dinfo[subUnit].lastResult; @@ -425,6 +436,7 @@ bool CMscdex::ReadSectors(Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, Ph bool CMscdex::ReadSectorsMSF(Bit8u subUnit, bool raw, Bit32u start, Bit16u num, PhysPt data) { + if (subUnit>=numDrives) return false; Bit8u min = (start>>16) & 0xFF; Bit8u sec = (start>> 8) & 0xFF; Bit8u fr = (start>> 0) & 0xFF; @@ -441,6 +453,7 @@ bool CMscdex::ReadSectors(Bit16u drive, Bit32u sector, Bit16u num, PhysPt data) bool CMscdex::GetCurrentPos(Bit8u subUnit, TMSF& pos) { + if (subUnit>=numDrives) return false; TMSF rel; Bit8u attr,track,index; dinfo[subUnit].lastResult = GetSubChannelData(subUnit, attr, track, index, rel, pos); @@ -450,12 +463,14 @@ bool CMscdex::GetCurrentPos(Bit8u subUnit, TMSF& pos) bool CMscdex::GetMediaStatus(Bit8u subUnit, bool& media, bool& changed, bool& trayOpen) { + if (subUnit>=numDrives) return false; dinfo[subUnit].lastResult = cdrom[subUnit]->GetMediaTrayStatus(media,changed,trayOpen); return dinfo[subUnit].lastResult; }; Bit32u CMscdex::GetDeviceStatus(Bit8u subUnit) { + if (subUnit>=numDrives) return false; bool media,changed,trayOpen; dinfo[subUnit].lastResult = GetMediaStatus(subUnit,media,changed,trayOpen); @@ -470,6 +485,7 @@ Bit32u CMscdex::GetDeviceStatus(Bit8u subUnit) bool CMscdex::GetMediaStatus(Bit8u subUnit, Bit8u& status) { + if (subUnit>=numDrives) return false; bool media,changed,open,result; result = GetMediaStatus(subUnit,media,changed,open); status = changed ? 0xFF : 0x01; @@ -478,14 +494,18 @@ bool CMscdex::GetMediaStatus(Bit8u subUnit, Bit8u& status) bool CMscdex::LoadUnloadMedia(Bit8u subUnit, bool unload) { + if (subUnit>=numDrives) return false; dinfo[subUnit].lastResult = cdrom[subUnit]->LoadUnloadMedia(unload); return dinfo[subUnit].lastResult; }; bool CMscdex::SendDriverRequest(Bit16u drive, PhysPt data) { + Bit8u subUnit = GetSubUnit(drive); + if (subUnit>=numDrives) return false; + // Get SubUnit - mem_writeb(data+1,GetSubUnit(drive)); + mem_writeb(data+1,subUnit); // Call Strategy / Interrupt MSCDEX_Strategy_Handler(); MSCDEX_Interrupt_Handler(); @@ -494,6 +514,8 @@ bool CMscdex::SendDriverRequest(Bit16u drive, PhysPt data) Bit16u CMscdex::GetStatusWord(Bit8u subUnit) { + if (subUnit>=numDrives) return false; + Bit16u status ; if (dinfo[subUnit].lastResult) status = REQUEST_STATUS_DONE; // ok else { From f7b841d05a6a249df1f36a2a3ddec7c89fe65142 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 10 Apr 2003 15:43:19 +0000 Subject: [PATCH 0822/4131] fixed bug in bt group Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@902 --- src/cpu/core_16/prefix_of.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h index 039f6608..67324dd0 100644 --- a/src/cpu/core_16/prefix_of.h +++ b/src/cpu/core_16/prefix_of.h @@ -309,9 +309,9 @@ switch(Fetchb()) { case 0xba: /* GRP8 Ew,Ib */ { GetRM; - Bit16u mask=1 << (Fetchb() & 15); if (rm >= 0xc0 ) { GetEArw; + Bit16u mask=1 << (Fetchb() & 15); flags.cf=(*earw & mask)>0; switch (rm & 0x38) { case 0x20: /* BT */ @@ -330,6 +330,7 @@ switch(Fetchb()) { } } else { GetEAa;Bit16u old=LoadMw(eaa); + Bit16u mask=1 << (Fetchb() & 15); flags.cf=(old & mask)>0; switch (rm & 0x38) { case 0x20: /* BT */ From 6d2e025aef671399579c6045019fecd2b78558ae Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 12 Apr 2003 10:44:37 +0000 Subject: [PATCH 0823/4131] Preparations for protected mode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@903 --- src/debug/debug.cpp | 138 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 111 insertions(+), 27 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 5b5fa313..3482e12b 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -36,6 +36,9 @@ #include "timer.h" #include "../shell/shell_inc.h" +// TEMP +CPUBlock cpu; + #ifdef WIN32 void WIN32_Console(); #else @@ -48,7 +51,7 @@ int old_cursor_state; static void DrawCode(void); static bool DEBUG_Log_Loop(int count); static void DEBUG_RaiseTimerIrq(void); -char* AnalyzeInstruction(char* inst); +char* AnalyzeInstruction(char* inst, bool saveSelector); void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num); class DEBUG; @@ -60,7 +63,7 @@ static struct { Bit32u eax,ebx,ecx,edx,esi,edi,ebp,esp,eip; } oldregs; - +static char curSelectorName[3] = { 0,0,0 }; static Segment oldsegs[6]; static Flag_Info oldflags; @@ -93,6 +96,44 @@ struct SCodeViewData { static Bit16u dataSeg,dataOfs; static bool showExtend = true; +/***********/ +/* Helpers */ +/***********/ + +Bit32u PhysMakeProt(Bit16u selector, Bit32u offset) +{ + Descriptor desc; + if (cpu.gdt.GetDescriptor(selector,desc)) return desc.GetBase()+offset; + return 0; +}; + +Bit32u GetAddress(Bit16u seg, Bit32u offset) +{ + if (cpu.protmode) return PhysMakeProt(seg,offset); + return PhysMake(seg,offset); +}; + +bool GetDescriptorInfo(char* selname, char* out1, char* out2) +{ + Bit16u sel; + Descriptor desc; + + if (strstr(selname,"cs") || strstr(selname,"CS")) sel = SegValue(cs); else + if (strstr(selname,"ds") || strstr(selname,"DS")) sel = SegValue(ds); else + if (strstr(selname,"es") || strstr(selname,"ES")) sel = SegValue(es); else + if (strstr(selname,"fs") || strstr(selname,"FS")) sel = SegValue(fs); else + if (strstr(selname,"gs") || strstr(selname,"GS")) sel = SegValue(gs); else + if (strstr(selname,"ss") || strstr(selname,"SS")) sel = SegValue(ss); + // FIXME: Call Gate Descriptors + if (cpu.gdt.GetDescriptor(sel,desc)) { + sprintf(out1,"%s: b:%08X type:%01X sparg",selname,desc.GetBase(),desc.saved.seg.type); + sprintf(out2," l:%08X dpl :%01X %1X%1X%1X%1X%1X",desc.GetLimit(),desc.saved.seg.dpl,desc.saved.seg.s,desc.saved.seg.p,desc.saved.seg.avl,desc.saved.seg.r,desc.saved.seg.g); + return true; + } + out1[0] = out2[0] = 0; + return false; +}; + /********************/ /* DebugVar stuff */ /********************/ @@ -137,7 +178,7 @@ class CBreakpoint public: CBreakpoint (void) { location = 0; active = once = false; segment = 0; offset = 0; intNr = 0; ahValue = 0; type = BKPNT_UNKNOWN; }; - void SetAddress (Bit16u seg, Bit32u off) { location = PhysMake(seg,off); type = BKPNT_PHYSICAL; segment = seg; offset = off; }; + void SetAddress (Bit16u seg, Bit32u off) { location = GetAddress(seg,off); type = BKPNT_PHYSICAL; segment = seg; offset = off; }; void SetAddress (PhysPt adr) { location = adr; type = BKPNT_PHYSICAL; }; void SetInt (Bit8u _intNr, Bit16u ah) { intNr = _intNr, ahValue = ah; type = BKPNT_INTERRUPT; }; void SetOnce (bool _once) { once = _once; }; @@ -498,12 +539,14 @@ bool DEBUG_ExitLoop(void) static void DrawData(void) { Bit16u add = dataOfs; + Bit32u address; /* Data win */ for (int y=0; y<8; y++) { // Adress mvwprintw (dbg.win_data,1+y,0,"%04X:%04X ",dataSeg,add); for (int x=0; x<16; x++) { - Bit8u ch = real_readb(dataSeg,add); + address = GetAddress(dataSeg,add); + Bit8u ch = mem_readb(address); mvwprintw (dbg.win_data,1+y,11+3*x,"%02X",ch); if (ch<32) ch='.'; mvwprintw (dbg.win_data,1+y,60+x,"%c",ch); @@ -534,7 +577,6 @@ static void DrawRegisters(void) { SetColor(SegValue(cs)!=oldsegs[cs].val);oldsegs[cs].val=SegValue(cs);mvwprintw (dbg.win_reg,1,31,"%04X",SegValue(cs)); /*Individual flags*/ - flags.cf=get_CF();SetColor(flags.cf!=oldflags.cf);oldflags.cf=flags.cf;mvwprintw (dbg.win_reg,1,53,"%01X",flags.cf); flags.zf=get_ZF();SetColor(flags.zf!=oldflags.zf);oldflags.zf=flags.zf;mvwprintw (dbg.win_reg,1,56,"%01X",flags.zf); flags.sf=get_SF();SetColor(flags.sf!=oldflags.sf);oldflags.sf=flags.sf;mvwprintw (dbg.win_reg,1,59,"%01X",flags.sf); @@ -542,11 +584,18 @@ static void DrawRegisters(void) { flags.af=get_AF();SetColor(flags.af!=oldflags.af);oldflags.af=flags.af;mvwprintw (dbg.win_reg,1,65,"%01X",flags.af); flags.pf=get_PF();SetColor(flags.pf!=oldflags.pf);oldflags.pf=flags.pf;mvwprintw (dbg.win_reg,1,68,"%01X",flags.pf); - SetColor(flags.df!=oldflags.df);oldflags.df=flags.df;mvwprintw (dbg.win_reg,1,71,"%01X",flags.df); SetColor(flags.intf!=oldflags.intf);oldflags.intf=flags.intf;mvwprintw (dbg.win_reg,1,74,"%01X",flags.intf); SetColor(flags.tf!=oldflags.tf);oldflags.tf=flags.tf;mvwprintw (dbg.win_reg,1,77,"%01X",flags.tf); + // Selector info, if available + if (cpu.protmode && curSelectorName[0]) { + char out1[200], out2[200]; + GetDescriptorInfo(curSelectorName,out1,out2); + mvwprintw(dbg.win_reg,2,28,out1); + mvwprintw(dbg.win_reg,3,28,out2); + } + wattrset(dbg.win_reg,0); mvwprintw(dbg.win_reg,3,60,"%d ",cycle_count); wrefresh(dbg.win_reg); @@ -554,11 +603,13 @@ static void DrawRegisters(void) { static void DrawCode(void) { + bool saveSel; Bit32u disEIP = codeViewData.useEIP; - PhysPt start = codeViewData.useCS*16 + codeViewData.useEIP; + PhysPt start = GetAddress(codeViewData.useCS,codeViewData.useEIP); char dline[200];Bitu size;Bitu c; for (Bit32u i=0;i<10;i++) { + saveSel = false; if (has_colors()) { if ((codeViewData.useCS==SegValue(cs)) && (disEIP == reg_eip)) { wattrset(dbg.win_code,COLOR_PAIR(PAIR_GREEN_BLACK)); @@ -567,10 +618,12 @@ static void DrawCode(void) codeViewData.cursorSeg = SegValue(cs); codeViewData.cursorOfs = disEIP; } + saveSel = (i == codeViewData.cursorPos); } else if (i == codeViewData.cursorPos) { wattrset(dbg.win_code,COLOR_PAIR(PAIR_BLACK_GREY)); codeViewData.cursorSeg = codeViewData.useCS; codeViewData.cursorOfs = disEIP; + saveSel = true; } else if (CBreakpoint::IsBreakpointDrawn(start)) { wattrset(dbg.win_code,COLOR_PAIR(PAIR_GREY_RED)); } else { @@ -578,13 +631,17 @@ static void DrawCode(void) } } - size=DasmI386(dline, start, disEIP, false); + bool toolarge = false; + Bitu drawsize = size = DasmI386(dline, start, disEIP, false); mvwprintw(dbg.win_code,i,0,"%04X:%04X ",codeViewData.useCS,disEIP); - for (c=0;c=size*2;c--) waddch(dbg.win_code,' '); + + if (drawsize>10) { toolarge = true; drawsize = 9; }; + for (c=0;c=drawsize*2;c--) waddch(dbg.win_code,' '); char* res = 0; - if (showExtend) res = AnalyzeInstruction(dline); + if (showExtend) res = AnalyzeInstruction(dline, saveSel); waddstr(dbg.win_code,dline); for (c=28-strlen(dline);c>0;c--) waddch(dbg.win_code,' '); if (showExtend) { @@ -745,7 +802,7 @@ bool ParseCommand(char* str) name[15] = 0; DEBUG_ShowMsg(0,"DEBUG: Created debug var %s at %04X:%04X",name,seg,ofs); - CDebugVar::InsertVariable(name,PhysMake(seg,ofs)); + CDebugVar::InsertVariable(name,GetAddress(seg,ofs)); return true; } @@ -764,7 +821,7 @@ bool ParseCommand(char* str) } found = strstr(str,"LV "); - if (found) { // Save variables + if (found) { // load variables found+=3; char name[13]; for (int i=0; i<12; i++) { @@ -876,7 +933,7 @@ bool ParseCommand(char* str) while (*found==' ') found++; if (*found) { Bit8u value = GetHexValue(found,found); found++; - mem_writeb(PhysMake(seg,ofs+count),value); + mem_writeb(GetAddress(seg,ofs+count),value); count++; } }; @@ -905,6 +962,16 @@ bool ParseCommand(char* str) Interrupt(intNr); return true; } + found = strstr(str,"SELINFO "); + if (found) { + found += 8; + while (found[0]==' ') found++; + char out1[200],out2[200]; + GetDescriptorInfo(found,out1,out2); + DEBUG_ShowMsg(0,"SelectorInfo %s:",found); + DEBUG_ShowMsg(0,"%s",out1); + DEBUG_ShowMsg(0,"%s",out2); + }; #if C_HEAVY_DEBUG found = strstr(str,"HEAVYLOG"); @@ -950,6 +1017,7 @@ bool ParseCommand(char* str) wprintw(dbg.win_out,"LV [seg]:[off] [name] - Load var list from file\n"); wprintw(dbg.win_out,"MEMDUMP [seg]:[off] [len] - Write memory to file memdump.txt\n"); + wprintw(dbg.win_out,"SELINFO [segName] - Show selector info\n"); wprintw(dbg.win_out,"H - Help\n"); wrefresh(dbg.win_out); @@ -958,7 +1026,7 @@ bool ParseCommand(char* str) return false; }; -char* AnalyzeInstruction(char* inst) +char* AnalyzeInstruction(char* inst, bool saveSelector) { static char result[256]; @@ -1001,19 +1069,28 @@ char* AnalyzeInstruction(char* inst) } else pos++; }; + Bit32u address = GetAddress(seg,adr); + + static char outmask[] = "%s:[%04X]=%02X"; + + if (cpu.protmode) outmask[6] = '8'; + switch (DasmLastOperandSize()) { - case 8 : { Bit8u val = mem_readb( PhysMake (seg,adr) ); - sprintf(result,"%s:[%04X]=%02X",prefix,adr,val); + case 8 : { Bit8u val = mem_readb(address); + outmask[12] = '2'; + sprintf(result,outmask,prefix,adr,val); } break; - case 16: { Bit16u val = mem_readw( PhysMake (seg,adr) ); - sprintf(result,"%s:[%04X]=%04X",prefix,adr,val); + case 16: { Bit16u val = mem_readw(address); + outmask[12] = '4'; + sprintf(result,outmask,prefix,adr,val); } break; - case 32: { Bit32u val = mem_readd( PhysMake (seg,adr) ); - sprintf(result,"%s:[%04X]=%08X",prefix,adr,val); + case 32: { Bit32u val = mem_readd(address); + outmask[12] = '8'; + sprintf(result,outmask,prefix,adr,val); } break; } // Variable found ? - CDebugVar* var = CDebugVar::FindVar(PhysMake(seg,adr)); + CDebugVar* var = CDebugVar::FindVar(address); if (var) { // Replace occurance char* pos1 = strchr(inst,'['); @@ -1026,6 +1103,10 @@ char* AnalyzeInstruction(char* inst) strcat(inst,temp); // add end }; }; + // show descriptor info, if available + if (cpu.protmode && saveSelector) { + strcpy(curSelectorName,prefix); + }; }; return result; }; @@ -1129,7 +1210,7 @@ Bit32u DEBUG_CheckKeys(void) { DOSBOX_SetNormalLoop(); break; case KEY_F(9): // Set/Remove TBreakpoint - { PhysPt ptr = PhysMake(codeViewData.cursorSeg,codeViewData.cursorOfs); + { PhysPt ptr = GetAddress(codeViewData.cursorSeg,codeViewData.cursorOfs); if (CBreakpoint::IsBreakpoint(ptr)) CBreakpoint::DeleteBreakpoint(ptr); else CBreakpoint::AddBreakpoint(codeViewData.cursorSeg, codeViewData.cursorOfs, false); } @@ -1189,9 +1270,9 @@ void DEBUG_Enable(void) { } void DEBUG_DrawScreen(void) { - DrawRegisters(); DrawData(); DrawCode(); + DrawRegisters(); } static void DEBUG_RaiseTimerIrq(void) { PIC_ActivateIRQ(0); @@ -1201,13 +1282,13 @@ static void LogInstruction(Bit16u segValue, Bit32u eipValue, char* buffer) { static char empty[15] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,0 }; - PhysPt start = PhysMake(segValue,eipValue); + PhysPt start = GetAddress(segValue,eipValue); char dline[200];Bitu size; size = DasmI386(dline, start, reg_eip, false); Bitu len = strlen(dline); char* res = empty; if (showExtend) { - res = AnalyzeInstruction(dline); + res = AnalyzeInstruction(dline,false); if (!res || (strlen(res)==0)) res = empty; }; @@ -1360,6 +1441,9 @@ void DEBUG_Init(Section* sec) { PROGRAMS_MakeFile("DEBUG.COM",DEBUG_ProgramStart); /* shutdown function */ sec->AddDestroyFunction(&DEBUG_ShutDown); + + // TEMP + cpu.protmode = 0; } // DEBUGGING VAR STUFF @@ -1452,7 +1536,7 @@ void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num) sprintf(buffer,"%04X:%04X ",seg,ofs1); for (Bit16u x=0; x<16; x++) { - sprintf (temp,"%02X ",mem_readb(PhysMake(seg,ofs1+x))); + sprintf (temp,"%02X ",mem_readb(GetAddress(seg,ofs1+x))); strcat (buffer,temp); }; ofs1+=16; From 7cbbca92f42d6edd5f920eed1b5ea12cf9304d0d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:21:09 +0000 Subject: [PATCH 0824/4131] Support for activating a20 line through keyboard controller Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@904 --- src/hardware/keyboard.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 373483c6..d03bedc9 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -21,6 +21,7 @@ #include "keyboard.h" #include "inout.h" #include "pic.h" +#include "mem.h" #include "mixer.h" #define KEYBUFSIZE 32 @@ -29,7 +30,8 @@ enum KeyCommands { CMD_NONE, CMD_SETLEDS, - CMD_SETTYPERATE + CMD_SETTYPERATE, + CMD_SETOUTPORT }; enum KeyStates { @@ -95,7 +97,7 @@ void KEYBOARD_GetCode(void) { keyb.buf.state=STATE_NORMAL; break; } - PIC_ActivateIRQ(1); + if (keyb.enabled) PIC_ActivateIRQ(1); } void KEYBOARD_AddCode(Bit8u scancode,Bit8u ascii,Bitu mod,KeyStates state) { @@ -181,6 +183,10 @@ static void write_p60(Bit32u port,Bit8u val) { LOG(LOG_ERROR|LOG_KEYBOARD,"60:Unhandled command %X",val); } return; + case CMD_SETOUTPORT: + MEM_A20_Enable((val & 2)>0); + break; + case CMD_SETTYPERATE: case CMD_SETLEDS: keyb.command=CMD_NONE; @@ -208,9 +214,23 @@ static void write_p64(Bit32u port,Bit8u val) { switch (val) { case 0xad: /* Activate keyboard */ keyb.active=true; + if (keyb.buf.used && !keyb.scheduled) { + keyb.scheduled=true; + PIC_AddEvent(KEYBOARD_GetCode,KEYDELAY); + } + LOG(LOG_KEYBOARD,"Activated"); break; case 0xae: /* Deactivate keyboard */ keyb.active=false; + PIC_DeActivateIRQ(1); + PIC_RemoveEvents(KEYBOARD_GetCode); + LOG(LOG_KEYBOARD,"De-Activated"); + break; + case 0xd0: /* Outport on buffer */ + KEYBOARD_AddCode(MEM_A20_Enabled() ? 0x02 : 0,0,0,STATE_NORMAL); + break; + case 0xd1: /* Write to outport */ + keyb.command=CMD_SETOUTPORT; break; default: LOG(LOG_ERROR|LOG_KEYBOARD,"Port 64 write with val %d",val); @@ -383,6 +403,7 @@ void KEYBOARD_Init(Section* sec) { port_61_data=0; /* Direct Speaker control and output disabled */ // memset(&event_handlers,0,sizeof(event_handlers)); /* Clear the keyb struct */ + keyb.active=true; keyb.enabled=true; keyb.command=CMD_NONE; keyb.last_index=0; From ae0b157a7b1f43b2f17ca3bb75a4b1c9bf8988eb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:21:49 +0000 Subject: [PATCH 0825/4131] Some changes to a20 line handling and some cleaning up. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@905 --- src/hardware/memory.cpp | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 25c65f45..8d0a3beb 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -274,24 +274,33 @@ static void AllocateMem_WriteHandler(PhysPt pt,Bit8u val) // A20 Line Handlers static Bit8u controlport_data = 0; +static bool a20_enabled; + +bool MEM_A20_Enabled(void) { + return a20_enabled; +} + +void MEM_A20_Enable(bool enable) { + if (a20_enabled==enable) return; + a20_enabled=enable; + if (enable) { + MEM_SetupMapping(PAGE_COUNT(1024*1024),PAGE_COUNT(64*1024),((Bit8u*)memory)+1024*1024); + } else { + MEM_SetupMapping(PAGE_COUNT(1024*1024),PAGE_COUNT(64*1024),memory); + } + LOG(LOG_MISC,"A20 Line is %s",enable ? "Enabled" : "Disabled"); +} static void write_p92(Bit32u port,Bit8u val) { // Bit 0 = system reset (switch back to real mode) if (val&1) E_Exit("XMS: CPU reset via port 0x92 not supported."); - if ((val&2) & !(controlport_data&2)) { - // ensable HMA - MEM_SetupMapping(PAGE_COUNT(1024*1024),PAGE_COUNT(64*1024),((Bit8u*)memory)+1024*1024); - }; - if (!(val&2) && (controlport_data&2)) { - // disable HMA - MEM_SetupMapping(PAGE_COUNT(1024*1024),PAGE_COUNT(64*1024),memory); - }; - controlport_data = val; -}; + controlport_data = val & ~2; + MEM_A20_Enable((val & 2)>0); +} static Bit8u read_p92(Bit32u port) { - return controlport_data; -}; + return controlport_data | a20_enabled ? 0x02 : 0; +} static void MEM_ShutDown(Section * sec) { for (Bitu i=0; i Date: Sun, 13 Apr 2003 18:23:00 +0000 Subject: [PATCH 0826/4131] Support HMA functions by giving correct errors codes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@906 --- src/ints/xms.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 6905a710..fcfe0f9b 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -50,7 +50,8 @@ #define XMS_ALLOCATE_UMB 0x10 #define XMS_DEALLOCATE_UMB 0x11 -#define HIGH_MEMORY_IN_USE 0x92 +#define HIGH_MEMORY_NOT_EXIST 0x90 +#define HIGH_MEMORY_IN_USE 0x91 #define HIGH_MEMORY_NOT_ALLOCATED 0x93 #define XMS_OUT_OF_SPACE 0xa0 #define XMS_OUT_OF_HANDLES 0xa1 @@ -368,6 +369,15 @@ Bitu XMS_Handler(void) { reg_bx=XMS_DRIVER_VERSION; reg_dx=0; /* No we don't have HMA */ break; + case XMS_ALLOCATE_HIGH_MEMORY: /* 01 */ + reg_ax=0; + reg_bl=HIGH_MEMORY_NOT_EXIST; + break; + case XMS_FREE_HIGH_MEMORY: /* 02 */ + reg_ax=0; + reg_bl=HIGH_MEMORY_NOT_EXIST; + break; + case XMS_GLOBAL_ENABLE_A20: /* 03 */ case XMS_LOCAL_ENABLE_A20: /* 05 */ reg_bl = XMS_EnableA20(true); @@ -423,8 +433,6 @@ Bitu XMS_Handler(void) { reg_bl=0xb1; //No UMB Available reg_dx=0; break; - case XMS_ALLOCATE_HIGH_MEMORY: /* 01 */ - case XMS_FREE_HIGH_MEMORY: /* 02 */ case XMS_DEALLOCATE_UMB: /* 11 */ LOG(LOG_ERROR|LOG_MISC,"XMS:Unhandled call %2X",reg_ah); break; From 4ce762ab9a57a6931467a890cd6b14e917220f61 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:24:08 +0000 Subject: [PATCH 0827/4131] Fix to microsecond wait function. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@907 --- src/ints/bios.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 5f5fa259..46e7c269 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -169,11 +169,16 @@ static Bitu INT15_Handler(void) { CALLBACK_SCF(true); break; case 0x83: /* BIOS - SET EVENT WAIT INTERVAL */ - mem_writed(BIOS_WAIT_FLAG_POINTER,RealMake(SegValue(es),reg_bx)); - mem_writed(BIOS_WAIT_FLAG_COUNT,reg_cx<<16|reg_dx); - mem_writeb(BIOS_WAIT_FLAG_ACTIVE,1); - PIC_RemoveEvents(&WaitFlagEvent); - PIC_AddEvent(&WaitFlagEvent,reg_cx<<16|reg_dx); + { + if (mem_readb(BIOS_WAIT_FLAG_ACTIVE)) break; + Bit32s count=(reg_cx<<16)|reg_dx; + if (count<1000) count=1000; + mem_writed(BIOS_WAIT_FLAG_POINTER,RealMake(SegValue(es),reg_bx)); + mem_writed(BIOS_WAIT_FLAG_COUNT,count); + mem_writeb(BIOS_WAIT_FLAG_ACTIVE,1); + PIC_RemoveEvents(&WaitFlagEvent); + PIC_AddEvent(&WaitFlagEvent,count); + } break; case 0x84: /* BIOS - JOYSTICK SUPPORT (XT after 11/8/82,AT,XT286,PS) */ if (reg_dx==0x0000) { From 25716c8829f985729a228aa1563e2f12c941b983 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:25:10 +0000 Subject: [PATCH 0828/4131] Added DPMI Init Changed order of MEM and IO Init for dependancy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@908 --- src/dosbox.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 5426aa97..6b3eae9b 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -85,6 +85,8 @@ void MSCDEX_Init(Section*); /* Dos Internal mostly */ void EMS_Init(Section*); void XMS_Init(Section*); +void DPMI_Init(Section*); + void AUTOEXEC_Init(Section*); void SHELL_Init(void); @@ -166,8 +168,8 @@ void DOSBOX_Init(void) { secprop->Add_int("warnings",0); #endif - secprop->AddInitFunction(&MEM_Init); secprop->AddInitFunction(&IO_Init); + secprop->AddInitFunction(&MEM_Init); secprop->AddInitFunction(&CALLBACK_Init); secprop->AddInitFunction(&PIC_Init); secprop->AddInitFunction(&PROGRAMS_Init); @@ -234,10 +236,12 @@ void DOSBOX_Init(void) { /* All the DOS Related stuff, which will eventually start up in the shell */ //TODO Maybe combine most of the dos stuff in one section like ems,xms secprop=control->AddSection_prop("dos",&DOS_Init); - secprop->AddInitFunction(&EMS_Init); - secprop->Add_int("emssize",4); secprop->AddInitFunction(&XMS_Init); secprop->Add_int("xmssize",8); + secprop->AddInitFunction(&EMS_Init); + secprop->Add_int("emssize",4); + secprop->AddInitFunction(&DPMI_Init); + // Mscdex secprop->AddInitFunction(&MSCDEX_Init); From db025c7aaaabf6eddf1db472f7e5541bd3cb3b3a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:26:21 +0000 Subject: [PATCH 0829/4131] Very early beta version Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@909 --- src/ints/dpmi.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/ints/dpmi.cpp diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp new file mode 100644 index 00000000..5c8d7f61 --- /dev/null +++ b/src/ints/dpmi.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include "dosbox.h" +#include "callback.h" +#include "mem.h" +#include "regs.h" +#include "dos_system.h" +#include "setup.h" +#include "inout.h" +#include "xms.h" +#include "cpu.h" + + +static bool DPMI_Multiplex(void) { + switch (reg_ax) { + case 0x1686: /* Get CPU Mode */ + reg_ax=1; /* Not protected */ + return true; + break; + case 0x1687: /* Get Mode switch entry point */ + reg_ax=0; /* supported */ + reg_bx=1; /* Support 32-bit */ + reg_cl=4; /* 486 */ + reg_dh=0; /* dpmi 0.9 */ + reg_dl=9; + reg_si=0; /* No need for private data */ + + + + break; + } + return false; + +} + +void DPMI_Init(Section* sec) { + DOS_AddMultiplexHandler(DPMI_Multiplex); + + +} \ No newline at end of file From 0dcd085c0a8c6d1279c3fbc92c35229569330c38 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:27:08 +0000 Subject: [PATCH 0830/4131] Changes for new flags. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@910 --- src/dos/dos.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 2288dbce..b351b32c 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -28,7 +28,6 @@ #include "regs.h" #include "dos_inc.h" #include "setup.h" -#include "cpu.h" DOS_Block dos; DOS_InfoBlock dos_infoblock; @@ -881,12 +880,12 @@ static Bitu DOS_27Handler(void) return CBRET_NONE; } static Bitu DOS_25Handler(void) { - flags.type=t_UNKNOWN; + flags.type=0; if(Drives[reg_al]==0){ reg_ax=0x8002; - flags.cf=true; + SETFLAGBIT(CF,true); }else{ - flags.cf=false; + SETFLAGBIT(CF,false); reg_ax=0; if((reg_cx != 1) ||(reg_dx != 1)) LOG(LOG_DOSMISC,"int 25 called but not as diskdetection"); @@ -895,13 +894,12 @@ static Bitu DOS_25Handler(void) { } static Bitu DOS_26Handler(void) { LOG(LOG_DOSMISC,"int 26 called: hope for the best!"); - flags.type=t_UNKNOWN; + flags.type=0; if(Drives[reg_al]==0){ - reg_ax=0x8002; - flags.cf=true; + SETFLAGBIT(CF,true); }else{ - flags.cf=false; + SETFLAGBIT(CF,false); reg_ax=0; } return CBRET_NONE; From 25457dc4f07687c763e1a9261d4019c176cdbf02 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:27:53 +0000 Subject: [PATCH 0831/4131] Changed cpu.h include to regs.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@911 --- src/dos/dos_files.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 512f0bcf..e9e4f537 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -24,7 +24,7 @@ #include "dosbox.h" #include "bios.h" #include "mem.h" -#include "cpu.h" +#include "regs.h" #include "dos_inc.h" #include "drives.h" #include "cross.h" From 2821b22b1e1182fa879e571e4bd7a11d1cce21f1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:29:15 +0000 Subject: [PATCH 0832/4131] Changes for protected support someday. Changes to flag handling Changes to some structures and classes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@912 --- include/cpu.h | 255 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 186 insertions(+), 69 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index cfa16740..6af03bba 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -68,34 +68,79 @@ enum { t_LASTFLAG }; -void Interrupt(Bit8u num); + +void CPU_LLDT(Bitu selector); +void CPU_LIDT(Bitu limit,Bitu base); +void CPU_LGDT(Bitu limit,Bitu base); + +void CPU_SLDT(Bitu & selector); +void CPU_SIDT(Bitu & limit,Bitu & base); +void CPU_SGDT(Bitu & limit,Bitu & base); + +void CPU_SLDT(Bitu & limit,Bitu & base); + + +void CPU_LAR(Bitu selector,Bitu & ar); + +bool CPU_SET_CRX(Bitu cr,Bitu value); +Bitu CPU_GET_CRX(Bitu cr); + +void CPU_SMSW(Bitu & word); +bool CPU_LMSW(Bitu word); + +bool CPU_JMP(bool use32,Bitu selector,Bitu offset); +bool CPU_CALL(bool use32,Bitu selector,Bitu offset); +bool CPU_RET(bool use32,Bitu bytes); + +bool Interrupt(Bitu num); +bool CPU_IRET(bool use32); +bool CPU_SetSegGeneral(SegNames seg,Bitu value); //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); +Bitu get_CF(void); +Bitu get_AF(void); +Bitu get_ZF(void); +Bitu get_SF(void); +Bitu get_OF(void); +Bitu get_PF(void); -#define FLAG_CF 0x0001 -#define FLAG_PF 0x0004 -#define FLAG_AF 0x0010 -#define FLAG_ZF 0x0040 -#define FLAG_SF 0x0080 -#define FLAG_TF 0x0100 -#define FLAG_IF 0x0200 -#define FLAG_DF 0x0400 -#define FLAG_OF 0x0800 +#define SETFLAGSb(FLAGB) \ +{ \ + SETFLAGBIT(OF,get_OF()); \ + flags.type=t_UNKNOWN; \ + flags.word&=0xffffff00;flags.word|=(FLAGB&0xff); \ +} +#define SETFLAGSw(FLAGW) \ +{ \ + flags.type=t_UNKNOWN; \ + flags.word&=0xffff0000;flags.word|=(FLAGW&0xffff); \ +} +#define SETFLAGSd(FLAGD) \ +{ \ + flags.type=t_UNKNOWN; \ + flags.word=FLAGD; \ +} -#define LoadCF flags.cf=get_CF(); -#define LoadZF flags.zf=get_ZF(); -#define LoadSF flags.sf=get_SF(); -#define LoadOF flags.of=get_OF(); +#define FILLFLAGS \ +{ \ + flags.word=(flags.word & ~FLAG_MASK) | \ + (get_CF() ? FLAG_CF : 0 ) | \ + (get_PF() ? FLAG_PF : 0 ) | \ + (get_AF() ? FLAG_AF : 0 ) | \ + (get_ZF() ? FLAG_ZF : 0 ) | \ + (get_SF() ? FLAG_SF : 0 ) | \ + (get_OF() ? FLAG_OF : 0 ); \ + flags.type=t_UNKNOWN; \ +} +#define LoadCF SETFLAGBIT(CF,get_CF()); +#define LoadZF SETFLAGBIT(ZF,get_ZF()); +#define LoadSF SETFLAGBIT(SF,get_SF()); +#define LoadOF SETFLAGBIT(OF,get_OF()); +#define LoadAF SETFLAGBIT(AF,get_AF()); // ********************************************************************* // Descriptor @@ -109,20 +154,114 @@ bool get_PF(void); #define CR0_PAGING 0x80000000 -#define DESC_INVALID 0x0 -#define DESC_286_TSS_A 0x1 -#define DESC_LDT 0x2 -#define DESC_286_TSS_B 0x3 -#define DESC_286_CALL_GATE 0x4 -#define DESC_TASK_GATE 0x5 -#define DESC_286_INT_GATE 0x6 -#define DESC_286_TRAP_GATE 0x7 +#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 0x9 -#define DESC_386_TSS_B 0xb -#define DESC_386_CALL_GATE 0xc -#define DESC_386_INT_GATE 0xe -#define DESC_386_TRAP_GATE 0xf +#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 + +#pragma pack(1) +/* TSS Struct from Bochs - http://bochs.sf.net */ +struct TSS_386 { + Bit16u back, RESERVED0; /* Backlink */ + Bit32u esp0; /* The CK stack pointer */ + Bit16u ss0, RESERVED1; /* The CK stack selector */ + Bit32u esp1; /* The parent KL stack pointer */ + Bit16u ss1, RESERVED2; /* The parent KL stack selector */ + Bit32u esp2; /* Unused */ + Bit16u ss2, RESERVED3; /* Unused */ + Bit32u cr3; /* The page directory pointer */ + Bit32u eip; /* The instruction pointer */ + Bit32u eflags; /* The flags */ + Bit32u eax, ecx, edx, ebx; /* The general purpose registers */ + Bit32u esp, ebp, esi, edi; /* The special purpose registers */ + Bit16u es, RESERVED4; /* The extra selector */ + Bit16u cs, RESERVED5; /* The code selector */ + Bit16u ss, RESERVED6; /* The application stack selector */ + Bit16u ds, RESERVED7; /* The data selector */ + Bit16u fs, RESERVED8; /* And another extra selector */ + Bit16u gs, RESERVED9; /* ... and another one */ + Bit16u ldt, RESERVED10; /* The local descriptor table */ + Bit16u trap; /* The trap flag (for debugging) */ + Bit16u io; /* The I/O Map base address */ +} GCC_ATTRIBUTE(packed);; + +struct S_Descriptor { + 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; +}GCC_ATTRIBUTE(packed); + +struct G_Descriptor { + 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; +} GCC_ATTRIBUTE(packed); + +#pragma pack() + +class TaskStateSegment +{ +public: + bool Get_ss_esp(Bitu which,Bitu & _ss,Bitu & _esp) { + PhysPt reader=seg_base+offsetof(TSS_386,esp0)+which*8; + _esp=mem_readd(reader); + _ss=mem_readw(reader+4); + return true; + } + bool Get_cr3(Bitu which,Bitu & _cr3) { + _cr3=mem_readd(seg_base+offsetof(TSS_386,cr3));; + return true; + } + +private: + PhysPt seg_base; + Bitu seg_limit; + Bitu seg_value; +}; class Descriptor @@ -148,48 +287,25 @@ public: if (saved.seg.g) return (limit<<12) | 0xFFF; return limit; } - Bitu GetType(void) { - return saved.seg.type; - } 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 GetDPL(void) { + Bitu DPL(void) { return saved.seg.dpl; } + Bitu Big(void) { + return saved.seg.big; + } public: -#pragma pack(1) - struct S_Descriptor { - Bit32u limit_0_15 :16; - Bit32u base_0_15 :16; - Bit32u base_16_23 :8; - Bit32u type :4; - Bit32u s :1; - 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; - }; - struct G_Descriptor { - Bit32u offset_0_15 :16; - Bit32u selector :16; - Bit32u paramcount :5; - Bit32u reserved :3; - Bit32u type :4; - Bit32u s :1; - Bit32u dpl :2; - Bit32u p :1; - Bit32u offset_16_31 :16; - }; -#pragma pack() - union { S_Descriptor seg; G_Descriptor gate; @@ -248,11 +364,12 @@ private: Bitu ldt_value; }; +#define STATE_PROTECTED 0x0001 +#define STATE_USE32 0x0002 +#define STATE_STACK32 0x0004 + struct CPUBlock { - Bitu protmode; /* Are we in protected mode */ Bitu cpl; /* Current Privilege */ - Bitu conforming; /* Current descriptor is conforming */ - Bitu big; /* Current descriptor is USE32 */ Bitu state; Bitu cr0; GDTDescriptorTable gdt; From 16904a20b37b25b34e26a964edb9752fae7fa589 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:29:42 +0000 Subject: [PATCH 0833/4131] A20 line enabling and status functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@913 --- include/mem.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/mem.h b/include/mem.h index a41cc885..b3d5a5b2 100644 --- a/include/mem.h +++ b/include/mem.h @@ -53,6 +53,9 @@ void MEM_ClearPageHandlers(Bitu startpage,Bitu pages); void MEM_SetupMapping(Bitu startpage,Bitu pages,void * data); void MEM_ClearMapping(Bitu startpage,Bitu pages); +bool MEM_A20_Enabled(void); +void MEM_A20_Enable(bool enable); + extern HostPt memory; /* From 407b886a3b18ed51fdd4bee77247ae3b0652b7db Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:30:58 +0000 Subject: [PATCH 0834/4131] Changes for new flags Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@914 --- include/regs.h | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/include/regs.h b/include/regs.h index a7bf99bc..d1b8db0f 100644 --- a/include/regs.h +++ b/include/regs.h @@ -29,12 +29,32 @@ struct Flag_Info { } var1,var2,result; Bitu type; Bitu prev_type; - bool cf,sf,pf,af,zf,of,df,tf,intf; - bool nt; - Bit8u io; - bool oldcf; + Bitu oldcf; + Bitu word; }; + +#define FLAG_CF 0x00000001 +#define FLAG_PF 0x00000004 +#define FLAG_AF 0x00000010 +#define FLAG_ZF 0x00000040 +#define FLAG_SF 0x00000080 +#define FLAG_TF 0x00000100 +#define FLAG_IF 0x00000200 +#define FLAG_DF 0x00000400 +#define FLAG_OF 0x00000800 + +#define FLAG_MASK (FLAG_CF | FLAG_PF | FLAG_AF | FLAG_ZF | FLAG_SF | FLAG_OF) + +#define FLAG_IOPL 0x00003000 +#define FLAG_NT 0x00004000 +#define FLAG_VM 0x00040000 + + +#define SETFLAGBIT(TYPE,TEST) if (TEST) flags.word|=FLAG_ ## TYPE; else flags.word&=~FLAG_ ## TYPE + +#define GETFLAG(TYPE) (flags.word & FLAG_ ## TYPE) + struct Segment { Bit16u val; PhysPt phys; /* The phyiscal address start in emulated machine */ @@ -43,6 +63,7 @@ struct Segment { enum SegNames { es=0,cs,ss,ds,fs,gs}; struct Segments { + Bitu big[8]; Bitu val[8]; PhysPt phys[8]; }; From 72b321a4cfccbd20949eeda6ef511cfd601e8dda Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:32:41 +0000 Subject: [PATCH 0835/4131] Changes for new flags Added a load of support functions for protected mode operations. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@915 --- src/cpu/cpu.cpp | 561 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 505 insertions(+), 56 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 08f55805..69595542 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + #include "dosbox.h" #include "cpu.h" #include "memory.h" @@ -23,10 +24,10 @@ #include "keyboard.h" #include "setup.h" + Flag_Info flags; - CPU_Regs cpu_regs; - +CPUBlock cpu; Segments Segs; Bits CPU_Cycles=0; @@ -35,26 +36,85 @@ Bits CPU_CycleMax=1500; CPU_Decoder * cpudecoder; -static void CPU_CycleIncrease(void) { - Bitu old_cycles=CPU_CycleMax; - CPU_CycleMax=(Bitu)(CPU_CycleMax*1.2); - CPU_CycleLeft=0;CPU_Cycles=0; - if (CPU_CycleMax==old_cycles) CPU_CycleMax++; - LOG_MSG("CPU:%d cycles",CPU_CycleMax); +INLINE void CPU_Push16(Bitu value) { + if (cpu.state & STATE_STACK32) { + reg_esp-=2; + mem_writew(SegPhys(ss)+reg_esp,value); + } else { + reg_sp-=2; + mem_writew(SegPhys(ss)+reg_sp,value); + } } -static void CPU_CycleDecrease(void) { - CPU_CycleMax=(Bitu)(CPU_CycleMax/1.2); - CPU_CycleLeft=0;CPU_Cycles=0; - if (!CPU_CycleMax) CPU_CycleMax=1; - LOG_MSG("CPU:%d cycles",CPU_CycleMax); +INLINE void CPU_Push32(Bitu value) { + if (cpu.state & STATE_STACK32) { + reg_esp-=4; + mem_writed(SegPhys(ss)+reg_esp,value); + } else { + reg_sp-=4; + mem_writed(SegPhys(ss)+reg_sp,value); + } } +INLINE Bitu CPU_Pop16(void) { + if (cpu.state & STATE_STACK32) { + Bitu val=mem_readw(SegPhys(ss)+reg_esp); + reg_esp+=2; + return val; + } else { + Bitu val=mem_readw(SegPhys(ss)+reg_sp); + reg_sp+=2; + return val; + } +} + +INLINE Bitu CPU_Pop32(void) { + if (cpu.state & STATE_STACK32) { + Bitu val=mem_readd(SegPhys(ss)+reg_esp); + reg_esp+=4; + return val; + } else { + Bitu val=mem_readd(SegPhys(ss)+reg_sp); + reg_sp+=4; + return val; + } +} + +PhysPt SelBase(Bitu sel) { + if (cpu.cr0 & CR0_PROTECTION) { + Descriptor desc; + cpu.gdt.GetDescriptor(sel,desc); + return desc.GetBase(); + } else { + return sel<<4; + } +} + +bool CPU_CheckState(void) { + cpu.state=0; + if (!cpu.cr0 & CR0_PROTECTION) { + cpu.full.entry=cpu.full.prefix=0; + return true; + } else { + cpu.state|=STATE_PROTECTED; + if (Segs.big[cs]) { + cpu.state|=STATE_USE32; + cpu.full.entry=0x200; + cpu.full.prefix=0x02; /* PREFIX_ADDR */ + } else { + cpu.full.entry=cpu.full.prefix=0; + } + if (Segs.big[ss]) cpu.state|=STATE_STACK32; + LOG_MSG("CPL Level %x",cpu.cpl); + } + return true; +} Bit8u lastint; -void Interrupt(Bit8u num) { +bool Interrupt(Bitu num) { lastint=num; //DEBUG THINGIE to check fucked ints +#if C_DEBUG switch (num) { case 0x00: LOG(LOG_CPU,"Divide Error"); @@ -89,47 +149,424 @@ void Interrupt(Bit8u num) { #endif E_Exit("Call to interrupt 0xCD this is BAD"); case 0x03: -#if C_DEBUG - if (DEBUG_Breakpoint()) return; -#endif + if (DEBUG_Breakpoint()) return true; break; case 0x05: LOG(LOG_CPU,"CPU:Out Of Bounds interrupt"); break; default: // LOG_WARN("Call to unsupported INT %02X call %02X",num,reg_ah); - break; }; -/* Check for 16-bit or 32-bit and then setup everything for the interrupt to start */ - Bit16u pflags; - 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); - - flags.intf=false; - flags.tf=false; -/* Save everything on a 16-bit stack */ - reg_sp-=2; - mem_writew(SegPhys(ss)+reg_sp,pflags); - reg_sp-=2; - mem_writew(SegPhys(ss)+reg_sp,SegValue(cs)); - reg_sp-=2; - mem_writew(SegPhys(ss)+reg_sp,reg_ip); -/* Get the new CS:IP from vector table */ - Bit16u newip=mem_readw(num << 2); - Bit16u newcs=mem_readw((num <<2)+2); - SegSet16(cs,newcs); - reg_ip=newip; +#endif + FILLFLAGS; + + if (!(cpu.state & STATE_PROTECTED)) { /* RealMode Interrupt */ + /* Save everything on a 16-bit stack */ + CPU_Push16(flags.word & 0xffff); + CPU_Push16(SegValue(cs)); + CPU_Push16(reg_ip); + SETFLAGBIT(IF,false); + SETFLAGBIT(TF,false); + /* Get the new CS:IP from vector table */ + reg_eip=mem_readw(num << 2); + Segs.val[cs]=mem_readw((num << 2)+2); + Segs.phys[cs]=Segs.val[cs]<<4; + return true; + } else { /* Protected Mode Interrupt */ + Descriptor gate; + cpu.idt.GetDescriptor(num<<3,gate); + switch (gate.Type()) { + case DESC_286_INT_GATE: + case DESC_386_INT_GATE: + SETFLAGBIT(IF,false); + case DESC_286_TRAP_GATE: + case DESC_386_TRAP_GATE: + { + Descriptor desc; + Bitu selector=gate.GetSelector(); + Bitu offset=gate.GetOffset(); + cpu.gdt.GetDescriptor(selector,desc); + Bitu dpl=desc.DPL(); + if (dpl>cpu.cpl) E_Exit("Interrupt to higher privilege"); + switch (desc.Type()) { + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: + case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (dpl=cpu.cpl)) E_Exit("IRET to C segment of higher privilege"); + break; + default: + E_Exit("IRET from illegal descriptor type %X",desc.Type()); + } +IRET_same_level: + Segs.phys[cs]=desc.GetBase(); + Segs.big[cs]=desc.Big(); + Segs.val[cs]=selector; + reg_eip=offset; + SETFLAGSw(old_flags); + LOG_MSG("IRET:Same level return to %X:%X",selector,offset); + } else { + E_Exit("IRET to other privilege"); + /* Return to higher level */ + } + return CPU_CheckState(); + + + + + + + return true; + } + return false; +} + +bool CPU_JMP(bool use32,Bitu selector,Bitu offset) { + if (!(cpu.state & STATE_PROTECTED)) { + if (!use32) { + reg_eip=offset&0xffff; + } else { + reg_eip=offset; + } + SegSet16(cs,selector); + return true; + } else { + Descriptor desc; + cpu.gdt.GetDescriptor(selector,desc); + switch (desc.Type()) { + case DESC_CODE_N_NC_A: + case DESC_CODE_N_NC_NA: + case DESC_CODE_R_NC_A: + case DESC_CODE_R_NC_NA: + if (cpu.cpl=cpu.cpl)) E_Exit("RET to C segment of higher privilege"); + break; + default: + E_Exit("RET from illegal descriptor type %X",desc.Type()); + } +RET_same_level: + Segs.phys[cs]=desc.GetBase(); + Segs.big[cs]=desc.Big(); + Segs.val[cs]=selector; + reg_eip=offset; + LOG(LOG_CPU,"RET - Same level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL()); + return CPU_CheckState(); + } else { + /* Return to higher level */ + E_Exit("REturn to higher priviledge"); + } + LOG_MSG("Prot ret %X:%X",selector,offset); + return CPU_CheckState(); + } + return false; +} + + +void CPU_SLDT(Bitu selector) { + selector=cpu.gdt.SLDT(); +} + +void CPU_LLDT(Bitu selector) { + cpu.gdt.LLDT(selector); + LOG_MSG("LDT Set to %X",selector); +} + +void CPU_LGDT(Bitu limit,Bitu base) { + LOG_MSG("GDT Set to base:%X limit:%X",base,limit); + cpu.gdt.SetLimit(limit); + cpu.gdt.SetBase(base); +} + +void CPU_LIDT(Bitu limit,Bitu base) { + LOG_MSG("IDT Set to base:%X limit:%X",base,limit); + cpu.idt.SetLimit(limit); + cpu.idt.SetBase(base); +} + +void CPU_SGDT(Bitu & limit,Bitu & base) { + limit=cpu.gdt.GetLimit(); + base=cpu.gdt.GetBase(); +} + +void CPU_SIDT(Bitu & limit,Bitu & base) { + limit=cpu.idt.GetLimit(); + base=cpu.idt.GetBase(); +} + + +bool CPU_SET_CRX(Bitu cr,Bitu value) { + switch (cr) { + case 0: + { + Bitu changed=cpu.cr0 ^ value; + if (!changed) return true; + cpu.cr0=value; + if (value & CR0_PAGING) LOG_MSG("Paging enabled"); + if (value & CR0_PROTECTION) { + LOG_MSG("Protected mode"); + } else { + LOG_MSG("Real mode"); + } + return CPU_CheckState(); + } + default: + LOG(LOG_CPU|LOG_ERROR,"Unhandled MOV CR%d,%X",cr,value); + break; + } + return false; +} + +Bitu CPU_GET_CRX(Bitu cr) { + switch (cr) { + case 0: + return cpu.cr0; + default: + LOG(LOG_CPU|LOG_ERROR,"Unhandled MOV XXX, CR%d",cr); + break; + } + return 0; +} + + +void CPU_SMSW(Bitu & word) { + word=cpu.cr0 & 0xffff; +} + +bool CPU_LMSW(Bitu word) { + word&=0xffff; + word|=cpu.cr0&0xffff0000; + return CPU_SET_CRX(0,word); +} + +void CPU_LAR(Bitu selector,Bitu & ar) { + Descriptor desc;Bitu rpl=selector & 3; + flags.type=t_UNKNOWN; + if (!cpu.gdt.GetDescriptor(selector,desc)){ + SETFLAGBIT(ZF,false); + return; + } + if (!desc.saved.seg.p) { + SETFLAGBIT(ZF,false); + return; + } + switch (desc.Type()){ + case DESC_CODE_N_C_A: + case DESC_CODE_N_C_NA: + case DESC_CODE_R_C_A: + case DESC_CODE_R_C_NA: + break; + case DESC_INVALID: + case DESC_286_TSS_A: + case DESC_LDT: + case DESC_286_TSS_B: + case DESC_286_CALL_GATE: + case DESC_TASK_GATE: + case DESC_286_INT_GATE: + case DESC_286_TRAP_GATE: + case DESC_386_TSS_A: + case DESC_386_TSS_B: + case DESC_386_CALL_GATE: + case DESC_386_INT_GATE: + case DESC_386_TRAP_GATE: + case DESC_DATA_EU_RO_NA: + case DESC_DATA_EU_RO_A: + case DESC_DATA_EU_RW_NA: + case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RO_NA: + case DESC_DATA_ED_RO_A: + case DESC_DATA_ED_RW_NA: + case DESC_DATA_ED_RW_A: + case DESC_CODE_N_NC_A: + case DESC_CODE_N_NC_NA: + case DESC_CODE_R_NC_A: + case DESC_CODE_R_NC_NA: + if (desc.DPL()(sec); @@ -163,16 +617,10 @@ void CPU_Init(Section* sec) { SegSet16(ss,0); reg_eip=0; + flags.word=FLAG_IF; flags.type=t_UNKNOWN; - flags.af=0; - flags.cf=0; - flags.cf=0; - flags.sf=0; - flags.zf=0; - flags.intf=true; - flags.nt=0; - flags.io=0; + cpu.full.entry=cpu.full.prefix=0; SetCPU16bit(); KEYBOARD_AddEvent(KBD_f11,KBD_MOD_CTRL,CPU_CycleDecrease); @@ -184,5 +632,6 @@ void CPU_Init(Section* sec) { CPU_CycleLeft=0; MSG_Add("CPU_CONFIGFILE_HELP","The amount of cycles to execute each loop. Lowering this setting will slowdown dosbox\n"); + } From 3874c2056343ad2d3cc1c46df7851a0aad9566e6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:33:43 +0000 Subject: [PATCH 0836/4131] Rewrites for new flags Moved functions into instructions.h Added some new opcodes Removed start.h and stop.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@916 --- src/cpu/core_16/helpers.h | 57 +++++ src/cpu/core_16/main.h | 365 +++++++++------------------------ src/cpu/core_16/prefix_66.h | 153 ++++---------- src/cpu/core_16/prefix_66_of.h | 35 ++-- src/cpu/core_16/prefix_of.h | 79 +++---- src/cpu/core_16/start.h | 20 -- src/cpu/core_16/stop.h | 21 -- src/cpu/core_16/support.h | 101 +++++---- src/cpu/slow_16.cpp | 13 +- 9 files changed, 298 insertions(+), 546 deletions(-) delete mode 100644 src/cpu/core_16/start.h delete mode 100644 src/cpu/core_16/stop.h diff --git a/src/cpu/core_16/helpers.h b/src/cpu/core_16/helpers.h index 7aadd83d..252ab178 100644 --- a/src/cpu/core_16/helpers.h +++ b/src/cpu/core_16/helpers.h @@ -24,6 +24,7 @@ GetRM; \ GetEAa; + #define RMEbGb(inst) \ { \ GetRMrb; \ @@ -38,6 +39,12 @@ else {GetEAa;inst(*rmrb,LoadMb(eaa),LoadRb,SaveRb);} \ } +#define RMEb(inst) \ + { \ + if (rm >= 0xc0 ) {GetEArb;inst(*earb,LoadRb,SaveRb);} \ + else {GetEAa;inst(eaa,LoadMb,SaveMb);} \ + } + #define RMEwGw(inst) \ { \ GetRMrw; \ @@ -45,6 +52,13 @@ else {GetEAa;inst(eaa,*rmrw,LoadMw,SaveMw);} \ } +#define RMEwGwOp3(inst,op3) \ + { \ + GetRMrw; \ + if (rm >= 0xc0 ) {GetEArw;inst(*earw,*rmrw,op3,LoadRw,SaveRw);} \ + else {GetEAa;inst(eaa,*rmrw,op3,LoadMw,SaveMw);} \ + } + #define RMGwEw(inst) \ { \ GetRMrw; \ @@ -52,6 +66,19 @@ else {GetEAa;inst(*rmrw,LoadMw(eaa),LoadRw,SaveRw);} \ } +#define RMGwEwOp3(inst,op3) \ + { \ + GetRMrw; \ + if (rm >= 0xc0 ) {GetEArw;inst(*rmrw,*earw,op3,LoadRw,SaveRw);} \ + else {GetEAa;inst(*rmrw,LoadMw(eaa),op3,LoadRw,SaveRw);} \ + } + +#define RMEw(inst) \ + { \ + if (rm >= 0xc0 ) {GetEArw;inst(*earw,LoadRw,SaveRw);} \ + else {GetEAa;inst(eaa,LoadMw,SaveMw);} \ + } + #define RMEdGd(inst) \ { \ GetRMrd; \ @@ -59,6 +86,14 @@ else {GetEAa;inst(eaa,*rmrd,LoadMd,SaveMd);} \ } +#define RMEdGdOp3(inst,op3) \ + { \ + GetRMrd; \ + if (rm >= 0xc0 ) {GetEArd;inst(*eard,*rmrd,op3,LoadRd,SaveRd);} \ + else {GetEAa;inst(eaa,*rmrd,op3,LoadMd,SaveMd);} \ + } + + #define RMGdEd(inst) \ { \ GetRMrd; \ @@ -66,6 +101,28 @@ else {GetEAa;inst(*rmrd,LoadMd(eaa),LoadRd,SaveRd);} \ } +#define RMGdEdOp3(inst,op3) \ + { \ + GetRMrd; \ + if (rm >= 0xc0 ) {GetEArd;inst(*rmrd,*eard,op3,LoadRd,SaveRd);} \ + else {GetEAa;inst(*rmrd,LoadMd(eaa),op3,LoadRd,SaveRd);} \ + } + + + + +#define RMEw(inst) \ + { \ + if (rm >= 0xc0 ) {GetEArw;inst(*earw,LoadRw,SaveRw);} \ + else {GetEAa;inst(eaa,LoadMw,SaveMw);} \ + } + +#define RMEd(inst) \ + { \ + if (rm >= 0xc0 ) {GetEArd;inst(*eard,LoadRd,SaveRd);} \ + else {GetEAa;inst(eaa,LoadMd,SaveMd);} \ + } + #define ALIb(inst) \ { inst(reg_al,Fetchb(),LoadRb,SaveRb)} diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 5bfe47c7..381c0e81 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -99,23 +99,7 @@ restart: case 0x26: /* SEG ES: */ SegPrefix(es);break; case 0x27: /* DAA */ - if (((reg_al & 0x0F)>0x09) || get_AF()) { - reg_al+=0x06; - flags.af=true; - } else { - flags.af=false; - } - flags.cf=get_CF(); - if ((reg_al > 0x9F) || flags.cf) { - reg_al+=0x60; - flags.cf=true; - } else { - flags.cf=false; - } - flags.sf=(reg_al>>7)>0; - flags.zf=(reg_al==0); - //TODO Maybe parity - flags.type=t_UNKNOWN; + DAA(); break; case 0x28: /* SUB Eb,Gb */ RMEbGb(SUBB);break; @@ -132,19 +116,7 @@ restart: case 0x2e: /* SEG CS: */ SegPrefix(cs);break; case 0x2f: /* DAS */ - if (((reg_al & 0x0f) > 9) || get_AF()) { - reg_al-=6; - flags.af=true; - } else { - flags.af=false; - } - if ((reg_al>0x9f) || get_CF()) { - reg_al-=0x60; - flags.cf=true; - } else { - flags.cf=false; - } - flags.type=t_UNKNOWN; + DAS(); break; case 0x30: /* XOR Eb,Gb */ RMEbGb(XORB);break; @@ -161,18 +133,7 @@ restart: case 0x36: /* SEG SS: */ SegPrefix(ss);break; case 0x37: /* AAA */ - if (get_AF() || ((reg_al & 0xf) > 9)) - { - reg_al += 6; - reg_ah += 1; - flags.af=true; - flags.cf=true; - } else { - flags.af=false; - flags.cf=false; - } - reg_al &= 0x0F; - flags.type=t_UNKNOWN; + AAA(); break; case 0x38: /* CMP Eb,Gb */ RMEbGb(CMPB);break; @@ -189,14 +150,7 @@ restart: case 0x3e: /* SEG DS: */ SegPrefix(ds);break; case 0x3f: /* AAS */ - if (((reg_al & 0x0f)>9) || get_AF()) { - reg_al=(reg_al-6) & 0xF; - reg_ah--; - flags.af=flags.cf=true; - } else { - flags.af=flags.cf=false; - } - flags.type=t_UNKNOWN; + AAS(); break; case 0x40: /* INC AX */ INCW(reg_ax,LoadRw,SaveRw);break; @@ -240,7 +194,7 @@ restart: Push_16(reg_bx);break; case 0x54: /* PUSH SP */ //TODO Check if this is correct i think it's SP+2 or something - Push_16(reg_sp);break; + Push_16(reg_sp);break; case 0x55: /* PUSH BP */ Push_16(reg_bp);break; case 0x56: /* PUSH SI */ @@ -255,8 +209,8 @@ restart: reg_dx=Pop_16();break; case 0x5b: /* POP BX */ reg_bx=Pop_16();break; - case 0x5c: /* POP SP */ - reg_sp=Pop_16();break; + case 0x5c: /* POP SP */ + reg_sp=Pop_16();break; case 0x5d: /* POP BP */ reg_bp=Pop_16();break; case 0x5e: /* POP SI */ @@ -264,8 +218,11 @@ restart: case 0x5f: /* POP DI */ reg_di=Pop_16();break; case 0x60: /* PUSHA */ - Push_16(reg_ax);Push_16(reg_cx);Push_16(reg_dx);Push_16(reg_bx); - Push_16(reg_sp);Push_16(reg_bp);Push_16(reg_si);Push_16(reg_di); + { + Bit16u old_sp=reg_sp; + Push_16(reg_ax);Push_16(reg_cx);Push_16(reg_dx);Push_16(reg_bx); + Push_16(old_sp);Push_16(reg_bp);Push_16(reg_si);Push_16(reg_di); + } break; case 0x61: /* POPA */ reg_di=Pop_16();reg_si=Pop_16();reg_bp=Pop_16();Pop_16();//Don't save SP @@ -278,7 +235,7 @@ restart: bound_min=LoadMw(eaa); bound_max=LoadMw(eaa+2); if ( (((Bit16s)*rmrw) < bound_min) || (((Bit16s)*rmrw) > bound_max) ) { - INTERRUPT(5); + EXCEPTION(5); } } break; @@ -308,35 +265,19 @@ restart: case 0x68: /* PUSH Iw */ Push_16(Fetchw());break; case 0x69: /* IMUL Gw,Ew,Iw */ - { - GetRMrw; - Bit32s res; - if (rm >= 0xc0 ) {GetEArw;res=(Bit32s)(*earws) * (Bit32s)Fetchws();} - else {GetEAa;res=(Bit32s)LoadMws(eaa) * (Bit32s)Fetchws();} - *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; - }; + RMGwEwOp3(DIMULW,Fetchws()); + break; case 0x6a: /* PUSH Ib */ - Push_16(Fetchbs());break; + Push_16(Fetchbs()); + break; case 0x6b: /* IMUL Gw,Ew,Ib */ - { - GetRMrw;Bit32s res; - if (rm >= 0xc0 ) {GetEArw;res=(Bit32s)(*earws) * (Bit32s)Fetchbs();} - else {GetEAa;res=(Bit32s)LoadMws(eaa) * (Bit32s)Fetchbs();} - *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; - } + RMGwEwOp3(DIMULW,Fetchbs()); + break; case 0x6c: /* INSB */ { stringDI; SaveMb(to,IO_Read(reg_dx)); - if (flags.df) reg_di--; else reg_di++; + if (GETFLAG(DF)) reg_di--; else reg_di++; break; } case 0x6d: /* INSW */ @@ -344,14 +285,14 @@ restart: stringDI; SaveMb(to,IO_Read(reg_dx)); SaveMb((to+1),IO_Read(reg_dx+1)); - if (flags.df) reg_di-=2; else reg_di+=2; + if (GETFLAG(DF)) reg_di-=2; else reg_di+=2; break; } case 0x6e: /* OUTSB */ { stringSI; IO_Write(reg_dx,LoadMb(from)); - if (flags.df) reg_si--; else reg_si++; + if (GETFLAG(DF)) reg_si--; else reg_si++; break; } case 0x6f: /* OUTSW */ @@ -359,7 +300,7 @@ restart: stringSI; IO_Write(reg_dx,LoadMb(from)); IO_Write(reg_dx+1,LoadMb(from+1)); - if (flags.df) reg_si-=2; else reg_si+=2; + if (GETFLAG(DF)) reg_si-=2; else reg_si+=2; break; } case 0x70: /* JO */ @@ -486,9 +427,11 @@ restart: break; } case 0x84: /* TEST Eb,Gb */ - RMEbGb(TESTB);break; + RMEbGb(TESTB); + break; case 0x85: /* TEST Ew,Gw */ - RMEwGw(TESTW);break; + RMEwGw(TESTW); + break; case 0x86: /* XCHG Eb,Gb */ { GetRMrb;Bit8u oldrmrb=*rmrb; @@ -636,27 +579,15 @@ restart: case 0x9b: /* WAIT */ break; /* No waiting here */ case 0x9c: /* PUSHF */ - { - Bit16u 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_16(pflags); - break; - } + FILLFLAGS; + Push_16(flags.word); + break; case 0x9d: /* POPF */ - { - Bit16u bits=Pop_16(); - Save_Flagsw(bits); - break; - } + SETFLAGSw(Pop_16()); + CheckTF(); + break; case 0x9e: /* SAHF */ - flags.of =get_OF(); - flags.type=t_UNKNOWN; - flags.cf =(reg_ah & 0x001)!=0;flags.pf =(reg_ah & 0x004)!=0; - flags.af =(reg_ah & 0x010)!=0;flags.zf =(reg_ah & 0x040)!=0; - flags.sf =(reg_ah & 0x080)!=0; + SETFLAGSb(reg_ah); break; case 0x9f: /* LAHF */ { @@ -688,7 +619,7 @@ restart: { stringSI;stringDI; SaveMb(to,LoadMb(from));; - if (flags.df) { reg_si--;reg_di--; } + if (GETFLAG(DF)) { reg_si--;reg_di--; } else {reg_si++;reg_di++;} break; } @@ -696,7 +627,7 @@ restart: { stringSI;stringDI; SaveMw(to,LoadMw(from)); - if (flags.df) { reg_si-=2;reg_di-=2; } + if (GETFLAG(DF)) { reg_si-=2;reg_di-=2; } else {reg_si+=2;reg_di+=2;} break; } @@ -704,7 +635,7 @@ restart: { stringSI;stringDI; CMPB(from,LoadMb(to),LoadMb,0); - if (flags.df) { reg_si--;reg_di--; } + if (GETFLAG(DF)) { reg_si--;reg_di--; } else {reg_si++;reg_di++;} break; } @@ -712,7 +643,7 @@ restart: { stringSI;stringDI; CMPW(from,LoadMw(to),LoadMw,0); - if (flags.df) { reg_si-=2;reg_di-=2; } + if (GETFLAG(DF)) { reg_si-=2;reg_di-=2; } else {reg_si+=2;reg_di+=2;} break; } @@ -724,7 +655,7 @@ restart: { stringDI; SaveMb(to,reg_al); - if (flags.df) { reg_di--; } + if (GETFLAG(DF)) { reg_di--; } else {reg_di++;} break; } @@ -732,7 +663,7 @@ restart: { stringDI; SaveMw(to,reg_ax); - if (flags.df) { reg_di-=2; } + if (GETFLAG(DF)) { reg_di-=2; } else {reg_di+=2;} break; } @@ -740,7 +671,7 @@ restart: { stringSI; reg_al=LoadMb(from); - if (flags.df) { reg_si--; } + if (GETFLAG(DF)) { reg_si--; } else {reg_si++;} break; } @@ -748,7 +679,7 @@ restart: { stringSI; reg_ax=LoadMw(from); - if (flags.df) { reg_si-=2;} + if (GETFLAG(DF)) { reg_si-=2;} else {reg_si+=2;} break; } @@ -756,7 +687,7 @@ restart: { stringDI; CMPB(reg_al,LoadMb(to),LoadRb,0); - if (flags.df) { reg_di--; } + if (GETFLAG(DF)) { reg_di--; } else {reg_di++;} break; } @@ -764,7 +695,7 @@ restart: { stringDI; CMPW(reg_ax,LoadMw(to),LoadRw,0); - if (flags.df) { reg_di-=2; } + if (GETFLAG(DF)) { reg_di-=2; } else {reg_di+=2;} break; } @@ -872,7 +803,7 @@ restart: } LOADIP; #endif - INTERRUPT(3); + EXCEPTION(3); break; case 0xcd: /* INT Ib */ { @@ -881,17 +812,19 @@ restart: SAVEIP; if (DEBUG_IntBreakpoint(num)) return 1; #endif - INTERRUPT(num); + EXCEPTION(num); } break; case 0xce: /* INTO */ - if (get_OF()) INTERRUPT(4); + if (get_OF()) EXCEPTION(4); break; case 0xcf: /* IRET */ { Bit16u newip=Pop_16();Bit16u newcs=Pop_16(); SegSet16(cs,newcs);SETIP(newip); - Bit16u pflags=Pop_16();Save_Flagsw(pflags); + Bit16u pflags=Pop_16(); + SETFLAGSw(pflags); + CheckTF(); break; } case 0xd0: /* GRP2 Eb,1 */ @@ -903,26 +836,12 @@ restart: case 0xd3: /* GRP2 Ew,CL */ GRP2W(reg_cl);break; case 0xd4: /* AAM Ib */ - { - Bit8u ib=Fetchb(); - - reg_ah=reg_al / ib; - reg_al=reg_al % ib; - flags.type=t_UNKNOWN; - flags.sf=(reg_ah & 0x80) > 0; - flags.zf=(reg_ax == 0); - //TODO PF - flags.pf=0; - } + AAM(Fetchb()); break; case 0xd5: /* AAD Ib */ - reg_al=reg_ah*Fetchb()+reg_al; - reg_ah=0; - flags.cf=(reg_al>=0x80); - flags.zf=(reg_al==0); - //TODO PF - flags.type=t_UNKNOWN; + AAD(Fetchb()); break; + case 0xd6: /* SALC */ reg_al = get_CF() ? 0xFF : 0; break; @@ -1052,28 +971,28 @@ restart: case 0xf4: /* HLT */ break; case 0xf5: /* CMC */ - flags.cf=!get_CF(); + SETFLAGBIT(CF,!get_CF()); if (flags.type!=t_CF) flags.prev_type=flags.type; flags.type=t_CF; break; case 0xf6: /* GRP3 Eb(,Ib) */ - { + { GetRM; - switch (rm & 0x38) { + switch ((rm & 0x38)>>3) { case 0x00: /* TEST Eb,Ib */ - case 0x08: /* TEST Eb,Ib Undocumented*/ + case 0x01: /* TEST Eb,Ib Undocumented*/ { if (rm >= 0xc0 ) {GetEArb;TESTB(*earb,Fetchb(),LoadRb,0)} else {GetEAa;TESTB(eaa,Fetchb(),LoadMb,0);} break; } - case 0x10: /* NOT Eb */ + case 0x02: /* NOT Eb */ { if (rm >= 0xc0 ) {GetEArb;*earb=~*earb;} else {GetEAa;SaveMb(eaa,~LoadMb(eaa));} break; } - case 0x18: /* NEG Eb */ + case 0x03: /* NEG Eb */ { flags.type=t_NEGb; if (rm >= 0xc0 ) { @@ -1085,69 +1004,38 @@ restart: } break; } - case 0x20: /* MUL AL,Eb */ - { - flags.type=t_MUL; - if (rm >= 0xc0 ) {GetEArb;reg_ax=reg_al * (*earb);} - else {GetEAa;reg_ax=reg_al * LoadMb(eaa);} - flags.cf=flags.of=((reg_ax & 0xff00) !=0); - break; - } - case 0x28: /* IMUL AL,Eb */ - { - flags.type=t_MUL; - if (rm >= 0xc0 ) {GetEArb;reg_ax=(Bit8s)reg_al * (*earbs);} - else {GetEAa;reg_ax=((Bit8s)reg_al) * LoadMbs(eaa);} - flags.cf=flags.of=!((reg_ax & 0xff80)==0xff80 || (reg_ax & 0xff80)==0x0000); - break; - } - case 0x30: /* DIV Eb */ - { -// flags.type=t_DIV; - Bit8u val; - if (rm >= 0xc0 ) {GetEArb;val=*earb;} - else {GetEAa;val=LoadMb(eaa);} - if (val==0) {INTERRUPT(0);break;} - Bit16u quotientu=reg_ax / val; - reg_ah=(Bit8u)(reg_ax % val); - reg_al=quotientu & 0xff; - if (quotientu!=reg_al) - INTERRUPT(0); - break; - } - case 0x38: /* IDIV Eb */ - { -// flags.type=t_DIV; - Bit8s val; - if (rm >= 0xc0 ) {GetEArb;val=*earbs;} - else {GetEAa;val=LoadMbs(eaa);} - if (val==0) {INTERRUPT(0);break;} - Bit16s quotients=((Bit16s)reg_ax) / val; - reg_ah=(Bit8s)(((Bit16s)reg_ax) % val); - reg_al=quotients & 0xff; - if (quotients!=(Bit8s)reg_al) - INTERRUPT(0); - break; - } + case 0x04: /* MUL AL,Eb */ + RMEb(MULB); + break; + case 0x05: /* IMUL AL,Eb */ + RMEb(IMULB); + break; + case 0x06: /* DIV Eb */ + RMEb(DIVB); + break; + case 0x07: /* IDIV Eb */ + RMEb(IDIVB); + break; } - break;} + break; + } case 0xf7: /* GRP3 Ew(,Iw) */ { GetRM; - switch (rm & 0x38) { + switch ((rm & 0x38)>>3) { case 0x00: /* TEST Ew,Iw */ - case 0x08: /* TEST Ew,Iw Undocumented*/ + case 0x01: /* TEST Ew,Iw Undocumented*/ { if (rm >= 0xc0 ) {GetEArw;TESTW(*earw,Fetchw(),LoadRw,SaveRw);} else {GetEAa;TESTW(eaa,Fetchw(),LoadMw,SaveMw);} break; } - case 0x10: /* NOT Ew */ + case 0x02: /* NOT Ew */ { if (rm >= 0xc0 ) {GetEArw;*earw=~*earw;} else {GetEAa;SaveMw(eaa,~LoadMw(eaa));} break; } - case 0x18: /* NEG Ew */ + case 0x03: /* NEG Ew */ { flags.type=t_NEGw; if (rm >= 0xc0 ) { @@ -1159,104 +1047,57 @@ restart: } break; } - case 0x20: /* MUL AX,Ew */ - { - flags.type=t_MUL;Bit32u tempu; - if (rm >= 0xc0 ) {GetEArw;tempu=reg_ax * (*earw);} - else {GetEAa;tempu=reg_ax * LoadMw(eaa);} - reg_ax=(Bit16u)(tempu & 0xffff);reg_dx=(Bit16u)(tempu >> 16); - flags.cf=flags.of=(reg_dx !=0); - break; - } - case 0x28: /* IMUL AX,Ew */ - { - flags.type=t_MUL;Bit32s temps; - if (rm >= 0xc0 ) {GetEArw;temps=((Bit16s)reg_ax) * (*earws);} - else {GetEAa;temps=((Bit16s)reg_ax) * LoadMws(eaa);} - reg_ax=Bit16u(temps & 0xffff);reg_dx=(Bit16u)(temps >> 16); - if ( (reg_dx==0xffff) && (reg_ax & 0x8000) ) { - flags.cf=flags.of=false; - } else if ( (reg_dx==0x0000) && (reg_ax<0x8000) ) { - flags.cf=flags.of=false; - } else { - flags.cf=flags.of=true; - } - break; - } - case 0x30: /* DIV Ew */ - { -// flags.type=t_DIV; - Bit16u val; - if (rm >= 0xc0 ) {GetEArw;val=*earw;} - else {GetEAa;val=LoadMw(eaa);} - if (val==0) {INTERRUPT(0);break;} - Bit32u tempu=(reg_dx<<16)|reg_ax; - Bit32u quotientu=tempu/val; - reg_dx=(Bit16u)(tempu % val); - reg_ax=(Bit16u)(quotientu & 0xffff); - if (quotientu>0xffff) - INTERRUPT(0); - break; - } - case 0x38: /* IDIV Ew */ - { -// flags.type=t_DIV; - Bit16s val; - if (rm >= 0xc0 ) {GetEArw;val=*earws;} - else {GetEAa;val=LoadMws(eaa);} - if (val==0) {INTERRUPT(0);break;} - Bit32s temps=(reg_dx<<16)|reg_ax; - Bit32s quotients=temps/val; - reg_dx=(Bit16s)(temps % val); - reg_ax=(Bit16s)quotients; - if (quotients!=(Bit16s)reg_ax) - INTERRUPT(0); - break; - } - + case 0x04: /* MUL AX,Ew */ + RMEw(MULW); + break; + case 0x05: /* IMUL AX,Ew */ + RMEw(IMULW) + break; + case 0x06: /* DIV Ew */ + RMEw(DIVW) + break; + case 0x07: /* IDIV Ew */ + RMEw(IDIVW) + break; } break; } case 0xf8: /* CLC */ - flags.cf=false; + SETFLAGBIT(CF,false); if (flags.type!=t_CF) flags.prev_type=flags.type; flags.type=t_CF; break; case 0xf9: /* STC */ - flags.cf=true; + SETFLAGBIT(CF,true); if (flags.type!=t_CF) flags.prev_type=flags.type; flags.type=t_CF; break; case 0xfa: /* CLI */ - flags.intf=false; + SETFLAGBIT(IF,false); break; case 0xfb: /* STI */ - flags.intf=true; - if (flags.intf && PIC_IRQCheck) { + SETFLAGBIT(IF,true); + if (PIC_IRQCheck) { SAVEIP; PIC_runIRQs(); LOADIP; }; break; case 0xfc: /* CLD */ - flags.df=false; + SETFLAGBIT(DF,false); break; case 0xfd: /* STD */ - flags.df=true; + SETFLAGBIT(DF,true); break; case 0xfe: /* GRP4 Eb */ { GetRM; switch (rm & 0x38) { case 0x00: /* INC Eb */ - flags.cf=get_CF();flags.type=t_INCb; - if (rm >= 0xc0 ) {GetEArb;flags.result.b=*earb+=1;} - else {GetEAa;flags.result.b=LoadMb(eaa)+1;SaveMb(eaa,flags.result.b);} + RMEb(INCB); break; case 0x08: /* DEC Eb */ - flags.cf=get_CF();flags.type=t_DECb; - if (rm >= 0xc0 ) {GetEArb;flags.result.b=*earb-=1;} - else {GetEAa;flags.result.b=LoadMb(eaa)-1;SaveMb(eaa,flags.result.b);} + RMEb(DECB); break; case 0x38: /* CallBack */ { @@ -1289,15 +1130,11 @@ restart: GetRM; switch (rm & 0x38) { case 0x00: /* INC Ew */ - flags.cf=get_CF();flags.type=t_INCw; - if (rm >= 0xc0 ) {GetEArw;flags.result.w=*earw+=1;} - else {GetEAa;flags.result.w=LoadMw(eaa)+1;SaveMw(eaa,flags.result.w);} + RMEw(INCW); break; case 0x08: /* DEC Ew */ - flags.cf=get_CF();flags.type=t_DECw; - if (rm >= 0xc0 ) {GetEArw;flags.result.w=*earw-=1;} - else {GetEAa;flags.result.w=LoadMw(eaa)-1;SaveMw(eaa,flags.result.w);} - break; + RMEw(DECW); + break; case 0x10: /* CALL Ev */ if (rm >= 0xc0 ) {GetEArw;Push_16(GETIP);SETIP(*earw);} else {GetEAa;Push_16(GETIP);SETIP(LoadMw(eaa));} diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index 60cb9666..7174ac20 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -167,31 +167,13 @@ switch(Fetchb()) { 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; - } + RMGdEdOp3(DIMULD,Fetchds()); + break; case 0x6a: /* PUSH Ib */ Push_32(Fetchbs());break; case 0x6b: /* IMUL Gd,Ed,Ib */ - { - GetRMrd; - Bit64s res; - if (rm >= 0xc0 ) {GetEArd;res=(Bit64s)(*eards) * (Bit64s)Fetchbs();} - else {GetEAa;res=(Bit64s)LoadMds(eaa) * (Bit64s)Fetchbs();} - *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; - } + RMGdEdOp3(DIMULD,Fetchbs()); + break; case 0x81: /* Grpl Ed,Id */ { GetRM; @@ -324,35 +306,23 @@ switch(Fetchb()) { else reg_edx=0; 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; - } + FILLFLAGS; + Push_32(flags.word); + break; case 0x9d: /* POPFD */ - { - Bit16u val=(Bit16u)(Pop_32()&0xffff); - Save_Flagsw(val); - break; - } + SETFLAGSd(Pop_32()) + CheckTF(); + break; case 0xa1: /* MOV EAX,Ow */ - { - reg_eax=LoadMd(GetEADirect[prefix.mark]()); - } + reg_eax=LoadMd(GetEADirect[prefix.mark]()); break; case 0xa3: /* MOV Ow,EAX */ - { - SaveMd(GetEADirect[prefix.mark](),reg_eax); - } + SaveMd(GetEADirect[prefix.mark](),reg_eax); break; case 0xa5: /* MOVSD */ { stringSI;stringDI;SaveMd(to,LoadMd(from)); - if (flags.df) { reg_si-=4;reg_di-=4; } + if (GETFLAG(DF)) { reg_si-=4;reg_di-=4; } else { reg_si+=4;reg_di+=4;} } break; @@ -363,7 +333,7 @@ switch(Fetchb()) { { stringDI; SaveMd(to,reg_eax); - if (flags.df) { reg_di-=4; } + if (GETFLAG(DF)) { reg_di-=4; } else {reg_di+=4;} break; } @@ -371,7 +341,7 @@ switch(Fetchb()) { { stringSI; reg_eax=LoadMd(from); - if (flags.df) { reg_si-=4;} + if (GETFLAG(DF)) { reg_si-=4;} else {reg_si+=4;} break; } @@ -379,7 +349,7 @@ switch(Fetchb()) { { stringDI; CMPD(reg_eax,LoadMd(to),LoadRd,0); - if (flags.df) { reg_di-=4; } + if (GETFLAG(DF)) { reg_di-=4; } else {reg_di+=4;} break; } @@ -424,6 +394,13 @@ switch(Fetchb()) { GRP2D(1);break; case 0xd3: /* GRP2 Ed,CL */ GRP2D(reg_cl);break; + case 0xef: /* OUT DX,EAX */ + IO_Write(reg_dx,(Bit8u)(reg_eax>>0)); + IO_Write(reg_dx+1,(Bit8u)(reg_eax>>8)); + IO_Write(reg_dx+2,(Bit8u)(reg_eax>>16)); + IO_Write(reg_dx+3,(Bit8u)(reg_eax>>24)); + break; + case 0xf2: /* REPNZ */ prefix.count++; Repeat_Normal(false,true); @@ -434,24 +411,22 @@ switch(Fetchb()) { continue; case 0xf7: /* GRP3 Ed(,Id) */ { - union { Bit64u u;Bit64s s;} temp; - union {Bit64u u;Bit64s s;} quotient; GetRM; - switch (rm & 0x38) { + switch ((rm & 0x38)>>3) { case 0x00: /* TEST Ed,Id */ - case 0x08: /* TEST Ed,Id Undocumented*/ + case 0x01: /* 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 */ + case 0x02: /* NOT Ed */ { if (rm >= 0xc0 ) {GetEArd;*eard=~*eard;} else {GetEAa;SaveMd(eaa,~LoadMd(eaa));} break; } - case 0x18: /* NEG Ed */ + case 0x03: /* NEG Ed */ { flags.type=t_NEGd; if (rm >= 0xc0 ) { @@ -463,60 +438,18 @@ switch(Fetchb()) { } break; } - case 0x20: /* MUL EAX,Ed */ - { - flags.type=t_MUL; - if (rm >= 0xc0 ) {GetEArd;temp.u=(Bit64u)reg_eax * (Bit64u)(*eard);} - else {GetEAa;temp.u=(Bit64u)reg_eax * (Bit64u)LoadMd(eaa);} - reg_eax=(Bit32u)(temp.u & 0xffffffff);reg_edx=(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)((Bit32s)reg_eax) * (Bit64s)(*eards));} - else {GetEAa;temp.s=((Bit64s)((Bit32s)reg_eax) * (Bit64s)(LoadMds(eaa)));} - reg_eax=Bit32u(temp.s & 0xffffffff);reg_edx=(Bit32u)(temp.s >> 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; - } + case 0x04: /* MUL EAX,Ed */ + RMEd(MULD); + break; + case 0x05: /* IMUL EAX,Ed */ + RMEd(IMULD); + break; + case 0x06: /* DIV Ed */ + RMEd(DIVD); + break; + case 0x07: /* IDIV Ed */ + RMEd(IDIVD); + break; } break; } @@ -525,14 +458,10 @@ switch(Fetchb()) { GetRM; switch (rm & 0x38) { case 0x00: /* INC Ed */ - 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);} + RMEd(INCD); break; case 0x08: /* DEC Ed */ - 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);} + RMEd(DECD); break; case 0x30: /* Push Ed */ if (rm >= 0xc0 ) {GetEArd;Push_32(*eard);} diff --git a/src/cpu/core_16/prefix_66_of.h b/src/cpu/core_16/prefix_66_of.h index fa972dca..2ddb607e 100644 --- a/src/cpu/core_16/prefix_66_of.h +++ b/src/cpu/core_16/prefix_66_of.h @@ -41,26 +41,19 @@ switch (Fetchb()) { break; } - case 0xb6: /* MOVZX Gd,Eb */ + case 0xb6: /* MOVZX Gd,Eb */ { GetRMrd; if (rm >= 0xc0 ) {GetEArb;*rmrd=*earb;} else {GetEAa;*rmrd=LoadMb(eaa);} break; } - case 0xaf: /* IMUL Gd,Ed */ + case 0xaf: /* IMUL Gd,Ed */ { - GetRMrd; - Bit64s res; - if (rm >= 0xc0 ) {GetEArd;res=((Bit64s)((Bit32s)*rmrd) * (Bit64s)((Bit32s)*eards));} - else {GetEAa;res=((Bit64s)((Bit32s)*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;} + RMGdEdOp3(DIMULD,*rmrd); break; }; - case 0xb7: /* MOVXZ Gd,Ew */ + case 0xb7: /* MOVXZ Gd,Ew */ { GetRMrd; if (rm >= 0xc0 ) {GetEArw;*rmrd=*earw;} @@ -73,7 +66,7 @@ switch (Fetchb()) { if (rm >= 0xc0 ) { GetEArd; Bit32u mask=1 << (Fetchb() & 31); - flags.cf=(*eard & mask)>0; + SETFLAGBIT(CF,(*eard & mask)); switch (rm & 0x38) { case 0x20: /* BT */ break; @@ -84,7 +77,7 @@ switch (Fetchb()) { *eard&=~mask; break; case 0x38: /* BTC */ - if (flags.cf) *eard&=~mask; + if (GETFLAG(CF)) *eard&=~mask; else *eard|=mask; break; default: @@ -93,7 +86,7 @@ switch (Fetchb()) { } else { GetEAa;Bit32u old=LoadMd(eaa); Bit32u mask=1 << (Fetchb() & 31); - flags.cf=(old & mask)>0; + SETFLAGBIT(CF,(old & mask)); switch (rm & 0x38) { case 0x20: /* BT */ break; @@ -104,7 +97,7 @@ switch (Fetchb()) { SaveMd(eaa,old & ~mask); break; case 0x38: /* BTC */ - if (flags.cf) old&=~mask; + if (GETFLAG(CF)) old&=~mask; else old|=mask; SaveMd(eaa,old); break; @@ -122,11 +115,11 @@ switch (Fetchb()) { Bit32u mask=1 << (*rmrd & 31); if (rm >= 0xc0 ) { GetEArd; - flags.cf=(*eard & mask)>0; + SETFLAGBIT(CF,(*eard & mask)); *eard^=mask; } else { GetEAa;Bit32u old=LoadMd(eaa); - flags.cf=(old & mask)>0; + SETFLAGBIT(CF,(old & mask)); SaveMd(eaa,old ^ mask); } if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } @@ -139,11 +132,11 @@ switch (Fetchb()) { if (rm >= 0xc0) { GetEArd; value=*eard; } else { GetEAa; value=LoadMd(eaa); } if (value==0) { - flags.zf = true; + SETFLAGBIT(ZF,true); } else { result = 0; while ((value & 0x01)==0) { result++; value>>=1; } - flags.zf = false; + SETFLAGBIT(ZF,false); *rmrd = result; } flags.type=t_UNKNOWN; @@ -156,11 +149,11 @@ switch (Fetchb()) { if (rm >= 0xc0) { GetEArd; value=*eard; } else { GetEAa; value=LoadMd(eaa); } if (value==0) { - flags.zf = true; + SETFLAGBIT(ZF,true); } else { result = 35; // Operandsize-1 while ((value & 0x80000000)==0) { result--; value<<=1; } - flags.zf = false; + SETFLAGBIT(ZF,false); *rmrd = result; } flags.type=t_UNKNOWN; diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h index 67324dd0..b8a5376f 100644 --- a/src/cpu/core_16/prefix_of.h +++ b/src/cpu/core_16/prefix_of.h @@ -19,7 +19,7 @@ switch(Fetchb()) { case 0x00: /* GRP 6 */ { - INTERRUPT(6); + EXCEPTION(6); break; GetRM; switch (rm & 0x38) { @@ -40,7 +40,8 @@ switch(Fetchb()) { else {GetEAa;SaveMw(eaa,0);} break; default: - E_Exit("CPU:GRP7:Illegal call %2X",(rm>>3) &3); + GetEAa; + LOG(LOG_CPU|LOG_ERROR,"GRP7:Illegal call %2X",(rm>>3) &3); } } break; @@ -184,28 +185,20 @@ switch(Fetchb()) { Bit16u mask=1 << (*rmrw & 15); if (rm >= 0xc0 ) { GetEArw; - flags.cf=(*earw & mask)>0; + SETFLAGBIT(CF,(*earw & mask)); } else { GetEAa;Bit16u old=LoadMw(eaa); - flags.cf=(old & mask)>0; + SETFLAGBIT(CF,(old & mask)); } if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } break; } case 0xa4: /* SHLD Ew,Gw,Ib */ - { - GetRMrw; - if (rm >= 0xc0 ) {GetEArw;DSHLW(*earw,*rmrw,Fetchb(),LoadRw,SaveRw);} - else {GetEAa;DSHLW(eaa,*rmrw,Fetchb(),LoadMw,SaveMw);} - break; - } + RMEwGwOp3(DSHLW,Fetchb()); + 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; - } + RMEwGwOp3(DSHLW,reg_cl); + break; /* 0xa6 XBTS (early 386 only) CMPXCHG (early 486 only) */ /* 0xa7 IBTS (early 386 only) CMPXCHG (early 486 only) */ case 0xa8: /* PUSH GS */ @@ -219,42 +212,26 @@ switch(Fetchb()) { Bit16u mask=1 << (*rmrw & 15); if (rm >= 0xc0 ) { GetEArw; - flags.cf=(*earw & mask)>0; + SETFLAGBIT(CF,(*earw & mask)); *earw|=mask; } else { GetEAa;Bit16u old=LoadMw(eaa); - flags.cf=(old & mask)>0; + SETFLAGBIT(CF,(old & mask)); SaveMw(eaa,old | mask); } if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } break; } case 0xac: /* SHRD Ew,Gw,Ib */ - { - GetRMrw; - if (rm >= 0xc0 ) {GetEArw;DSHRW(*earw,*rmrw,Fetchb(),LoadRw,SaveRw);} - else {GetEAa;DSHRW(eaa,*rmrw,Fetchb(),LoadMw,SaveMw);} - break; - } + RMEwGwOp3(DSHRW,Fetchb()); + 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; - } + RMEwGwOp3(DSHRW,reg_cl); + 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; - } + RMGwEwOp3(DIMULW,*rmrw); + break; + /* 0xb0 CMPXCHG Eb,Gb */ /* 0xb1 CMPXCHG Ew,Gw */ case 0xb2: /* LSS */ @@ -269,11 +246,11 @@ switch(Fetchb()) { Bit16u mask=1 << (*rmrw & 15); if (rm >= 0xc0 ) { GetEArw; - flags.cf=(*earw & mask)>0; + SETFLAGBIT(CF,(*earw & mask)); *earw&= ~mask; } else { GetEAa;Bit16u old=LoadMw(eaa); - flags.cf=(old & mask)>0; + SETFLAGBIT(CF,(old & mask)); SaveMw(eaa,old & ~mask); } if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } @@ -312,7 +289,7 @@ switch(Fetchb()) { if (rm >= 0xc0 ) { GetEArw; Bit16u mask=1 << (Fetchb() & 15); - flags.cf=(*earw & mask)>0; + SETFLAGBIT(CF,(*earw & mask)); switch (rm & 0x38) { case 0x20: /* BT */ break; @@ -331,7 +308,7 @@ switch(Fetchb()) { } else { GetEAa;Bit16u old=LoadMw(eaa); Bit16u mask=1 << (Fetchb() & 15); - flags.cf=(old & mask)>0; + SETFLAGBIT(CF,(old & mask)); switch (rm & 0x38) { case 0x20: /* BT */ break; @@ -357,11 +334,11 @@ switch(Fetchb()) { Bit16u mask=1 << (*rmrw & 15); if (rm >= 0xc0 ) { GetEArw; - flags.cf=(*earw & mask)>0; + SETFLAGBIT(CF,(*earw & mask)); *earw^=mask; } else { GetEAa;Bit16u old=LoadMw(eaa); - flags.cf=(old & mask)>0; + SETFLAGBIT(CF,(old & mask)); SaveMw(eaa,old ^ mask); } if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } @@ -374,11 +351,11 @@ switch(Fetchb()) { if (rm >= 0xc0) { GetEArw; value=*earw; } else { GetEAa; value=LoadMw(eaa); } if (value==0) { - flags.zf = true; + SETFLAGBIT(ZF,true); } else { result = 0; while ((value & 0x01)==0) { result++; value>>=1; } - flags.zf = false; + SETFLAGBIT(ZF,false); *rmrw = result; } flags.type=t_UNKNOWN; @@ -391,11 +368,11 @@ switch(Fetchb()) { if (rm >= 0xc0) { GetEArw; value=*earw; } else { GetEAa; value=LoadMw(eaa); } if (value==0) { - flags.zf = true; + SETFLAGBIT(ZF,true); } else { result = 15; // Operandsize-1 while ((value & 0x8000)==0) { result--; value<<=1; } - flags.zf = false; + SETFLAGBIT(ZF,false); *rmrw = result; } flags.type=t_UNKNOWN; diff --git a/src/cpu/core_16/start.h b/src/cpu/core_16/start.h deleted file mode 100644 index f54a1e22..00000000 --- a/src/cpu/core_16/start.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2002 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* Setup the CS:IP and SS:SP Pointers */ -LOADIP; diff --git a/src/cpu/core_16/stop.h b/src/cpu/core_16/stop.h deleted file mode 100644 index 68145d75..00000000 --- a/src/cpu/core_16/stop.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2002 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -decode_end: - -SAVEIP; diff --git a/src/cpu/core_16/support.h b/src/cpu/core_16/support.h index 93d48c6c..2ec79b49 100644 --- a/src/cpu/core_16/support.h +++ b/src/cpu/core_16/support.h @@ -32,6 +32,26 @@ static INLINE void ADDIPFAST(Bit16s blah) { IPPoint+=blah; } +#define CheckTF() \ + if (GETFLAG(TF)) { \ + cpudecoder=CPU_Real_16_Slow_Decode_Trap; \ + goto decode_end; \ + } + + +#define EXCEPTION(blah) \ + { \ + Bit8u new_num=blah; \ + SAVEIP; \ + if (Interrupt(new_num)) { \ + if (GETFLAG(TF)) { \ + cpudecoder=CPU_Real_16_Slow_Decode_Trap; \ + return 0; \ + } \ + goto decode_start; \ + } else return 0; \ + } + static INLINE Bit8u Fetchb() { Bit8u temp=LoadMb(IPPoint); IPPoint+=1; @@ -82,6 +102,34 @@ static INLINE Bit32u Pop_32() { return temp; }; +#define JumpSIb(blah) \ + if (blah) { \ + ADDIPFAST(Fetchbs()); \ + } else { \ + ADDIPFAST(1); \ + } + +#define JumpSIw(blah) \ + if (blah) { \ + ADDIPFAST(Fetchws()); \ + } else { \ + ADDIPFAST(2); \ + } + +#define SETcc(cc) \ + { \ + GetRM; \ + if (rm >= 0xc0 ) {GetEArb;*earb=(cc) ? 1 : 0;} \ + else {GetEAa;SaveMb(eaa,(cc) ? 1 : 0);} \ + } + +#define NOTDONE \ + SUBIP(1);E_Exit("CPU:Opcode %2X Unhandled",Fetchb()); + +#define NOTDONE66 \ + SUBIP(1);E_Exit("CPU:Opcode 66:%2X Unhandled",Fetchb()); + + #define stringDI \ EAPoint to; \ to=SegBase(es)+reg_di @@ -99,18 +147,12 @@ static INLINE Bit32u Pop_32() { #include "table_ea.h" #include "../modrm.h" - -static Bit8s table_df_8[2]={1,-1}; -static Bit16s table_df_16[2]={2,-2}; -static Bit32s table_df_32[2]={4,-4}; - - static void Repeat_Normal(bool testz,bool prefix_66) { PhysPt base_si,base_di; Bit16s direct; - if (flags.df) direct=-1; + if (GETFLAG(DF)) direct=-1; else direct=1; base_di=SegBase(es); if (prefix.mark & PREFIX_ADDR) E_Exit("Unhandled 0x67 prefixed string op"); @@ -362,48 +404,3 @@ normalexit: PrefixReset; } -//flags.io and nt shouldn't be compiled for 386 -#ifdef CPU_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) { \ - cpudecoder=&CPU_Real_16_Slow_Decode_Trap; \ - goto decode_end; \ - } \ -} - -#else - -#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; \ - if (flags.intf && PIC_IRQCheck) { \ - SAVEIP; \ - PIC_runIRQs(); \ - LOADIP; \ - } \ - if (flags.tf) { \ - cpudecoder=&CPU_Real_16_Slow_Decode_Trap; \ - goto decode_end; \ - } \ -} - -#endif diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp index 5ee529ed..a8db93b1 100644 --- a/src/cpu/slow_16.cpp +++ b/src/cpu/slow_16.cpp @@ -63,12 +63,14 @@ extern Bitu cycle_count; #endif + #include "instructions.h" #include "core_16/support.h" static Bitu CPU_Real_16_Slow_Decode_Trap(void); static Bitu CPU_Real_16_Slow_Decode(void) { -#include "core_16/start.h" +decode_start: + LOADIP; while (CPU_Cycles>0) { #if C_DEBUG cycle_count++; @@ -85,7 +87,8 @@ static Bitu CPU_Real_16_Slow_Decode(void) { } CPU_Cycles--; } - #include "core_16/stop.h" +decode_end: + SAVEIP; return CBRET_NONE; } @@ -96,7 +99,7 @@ static Bitu CPU_Real_16_Slow_Decode_Trap(void) { CPU_Real_16_Slow_Decode(); // LOG_DEBUG("TRAP: Trap Flag executed"); - INTERRUPT(1); + Interrupt(1); CPU_Cycles = oldCycles-1; cpudecoder = &CPU_Real_16_Slow_Decode; @@ -107,9 +110,9 @@ static Bitu CPU_Real_16_Slow_Decode_Trap(void) { void CPU_Real_16_Slow_Start(void) { cpudecoder=&CPU_Real_16_Slow_Decode; - EAPrefixTable[0]=&GetEA_16_n; - EAPrefixTable[1]=&GetEA_16_s; EAPrefixTable[2]=&GetEA_32_n; EAPrefixTable[3]=&GetEA_32_s; + EAPrefixTable[0]=&GetEA_16_n; + EAPrefixTable[1]=&GetEA_16_s; PrefixReset; }; From 53758386373d9060280117412525be5ecb750a2b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:34:21 +0000 Subject: [PATCH 0837/4131] Changes for new flags Always add a 0x67 handler incase ems is not loaded. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@917 --- src/cpu/callback.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index ce79268f..fcdd049a 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -52,8 +52,8 @@ Bitu CALLBACK_Allocate(void) { void CALLBACK_Idle(void) { /* this makes the cpu execute instructions to handle irq's and then come back */ - bool oldintf=flags.intf; - flags.intf=true; + Bitu oldIF=GETFLAG(IF); + SETFLAGBIT(IF,true); Bit16u oldcs=SegValue(cs); Bit32u oldeip=reg_eip; SegSet16(cs,CB_SEG); @@ -61,7 +61,7 @@ void CALLBACK_Idle(void) { DOSBOX_RunMachine(); reg_eip=oldeip; SegSet16(cs,oldcs); - flags.intf=oldintf; + SETFLAGBIT(IF,oldIF); if (CPU_CycleLeft<300) CPU_CycleLeft=1; else CPU_CycleLeft-=300; } @@ -174,6 +174,8 @@ void CALLBACK_Init(Section* sec) { for (i=0;i<0x40;i++) { real_writed(0,i*4,CALLBACK_RealPointer(call_default)); } + real_writed(0,0x67*4,CALLBACK_RealPointer(call_default)); + } From b77dea601ec70bdc06cbddf0a45c2e6f81089cdf Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:34:43 +0000 Subject: [PATCH 0838/4131] Changes for new flags. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@918 --- src/cpu/flags.cpp | 258 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 246 insertions(+), 12 deletions(-) diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 33c3224b..c7adc6ed 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -29,7 +29,7 @@ /* CF Carry Flag -- Set on high-order bit carry or borrow; cleared otherwise. */ -bool get_CF(void) { +Bitu get_CF(void) { switch (flags.type) { case t_UNKNOWN: @@ -44,7 +44,7 @@ bool get_CF(void) { case t_RCLb: case t_RCLw: case t_RCLd: - return flags.cf; + return GETFLAG(CF); break; case t_ADDb: return (flags.result.b0); + break; + case t_ADDw: + SET_FLAG(FLAG_CF,(flags.result.w0); + break; + case t_ADDd: + SET_FLAG(FLAG_CF,(flags.result.d0); + break; + + + case t_ADCb: + SET_FLAG(FLAG_CF,(flags.result.b < flags.var1.b) || (flags.oldcf && (flags.result.b == flags.var1.b))); + SET_FLAG(FLAG_AF,(((flags.var1.b ^ flags.var2.b) ^ flags.result.b) & 0x10)>0); + break; + case t_ADCw: + SET_FLAG(FLAG_CF,(flags.result.w < flags.var1.w) || (flags.oldcf && (flags.result.w == flags.var1.w))); + SET_FLAG(FLAG_AF,(((flags.var1.w ^ flags.var2.w) ^ flags.result.w) & 0x10)>0); + break; + case t_ADCd: + SET_FLAG(FLAG_CF,(flags.result.d < flags.var1.d) || (flags.oldcf && (flags.result.d == flags.var1.d))); + SET_FLAG(FLAG_AF,(((flags.var1.d ^ flags.var2.d) ^ flags.result.d) & 0x10)>0); + break; + + + case t_SBBb: + SET_FLAG(FLAG_CF,(flags.var1.b < flags.result.b) || (flags.oldcf && (flags.var2.b==0xff))); + SET_FLAG(FLAG_AF,(((flags.var1.b ^ flags.var2.b) ^ flags.result.b) & 0x10)>0); + break; + case t_SBBw: + SET_FLAG(FLAG_CF,(flags.var1.w < flags.result.w) || (flags.oldcf && (flags.var2.w==0xffff))); + SET_FLAG(FLAG_AF,(((flags.var1.w ^ flags.var2.w) ^ flags.result.w) & 0x10)>0); + break; + case t_SBBd: + SET_FLAG(FLAG_CF,(flags.var1.d < flags.result.d) || (flags.oldcf && (flags.var2.d==0xffffffff))); + SET_FLAG(FLAG_AF,(((flags.var1.d ^ flags.var2.d) ^ flags.result.d) & 0x10)>0); + break; + + + case t_SUBb: + case t_CMPb: + SET_FLAG(FLAG_CF,(flags.var1.b0); + break; + case t_SUBw: + case t_CMPw: + SET_FLAG(FLAG_CF,(flags.var1.w0); + break; + case t_SUBd: + case t_CMPd: + SET_FLAG(FLAG_CF,(flags.var1.d0); + break; + + + case t_ORb: + SET_FLAG(FLAG_CF,false); + break; + case t_ORw: + SET_FLAG(FLAG_CF,false); + break; + case t_ORd: + SET_FLAG(FLAG_CF,false); + break; + + + case t_TESTb: + case t_ANDb: + SET_FLAG(FLAG_CF,false); + break; + case t_TESTw: + case t_ANDw: + SET_FLAG(FLAG_CF,false); + break; + case t_TESTd: + case t_ANDd: + SET_FLAG(FLAG_CF,false); + break; + + + case t_XORb: + SET_FLAG(FLAG_CF,false); + break; + case t_XORw: + SET_FLAG(FLAG_CF,false); + break; + case t_XORd: + SET_FLAG(FLAG_CF,false); + break; + + + case t_SHLb: + if (flags.var2.b>8) SET_FLAG(FLAG_CF,false); + else SET_FLAG(FLAG_CF,(flags.var1.b >> (8-flags.var2.b)) & 1); + break; + case t_SHLw: + if (flags.var2.b>16) SET_FLAG(FLAG_CF,false); + else SET_FLAG(FLAG_CF,(flags.var1.w >> (16-flags.var2.b)) & 1); + break; + case t_SHLd: + SET_FLAG(FLAG_CF,(flags.var1.d >> (32 - flags.var2.b)) & 1); + break; + + + case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */ + SET_FLAG(FLAG_CF,(flags.var1.d >> (32 - flags.var2.b)) & 1); + break; + case t_DSHLd: + SET_FLAG(FLAG_CF,(flags.var1.d >> (32 - flags.var2.b)) & 1); + break; + + + case t_SHRb: + SET_FLAG(FLAG_CF,(flags.var1.b >> (flags.var2.b - 1)) & 1); + break; + case t_SHRw: + SET_FLAG(FLAG_CF,(flags.var1.w >> (flags.var2.b - 1)) & 1); + break; + case t_SHRd: + SET_FLAG(FLAG_CF,(flags.var1.d >> (flags.var2.b - 1)) & 1); + break; + + + case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ + SET_FLAG(FLAG_CF,(flags.var1.d >> (flags.var2.b - 1)) & 1); + break; + case t_DSHRd: + SET_FLAG(FLAG_CF,(flags.var1.d >> (flags.var2.b - 1)) & 1); + break; + + + case t_SARb: + SET_FLAG(FLAG_CF,(((Bit8s) flags.var1.b) >> (flags.var2.b - 1)) & 1); + break; + case t_SARw: + SET_FLAG(FLAG_CF,(((Bit16s) flags.var1.w) >> (flags.var2.b - 1)) & 1); + break; + case t_SARd: + SET_FLAG(FLAG_CF,(((Bit32s) flags.var1.d) >> (flags.var2.b - 1)) & 1); + break; + + + case t_ROLb: + SET_FLAG(FLAG_CF,flags.result.b & 1); + break; + case t_ROLw: + SET_FLAG(FLAG_CF,flags.result.w & 1); + break; + case t_ROLd: + SET_FLAG(FLAG_CF,flags.result.d & 1); + break; + + + case t_RORb: + SET_FLAG(FLAG_CF,(flags.result.b & 0x80)>0); + break; + case t_RORw: + SET_FLAG(FLAG_CF,(flags.result.w & 0x8000)>0); + break; + case t_RORd: + SET_FLAG(FLAG_CF,(flags.result.d & 0x80000000)>0); + break; + + + case t_RCRb: + SET_FLAG(FLAG_CF,(flags.var1.b >> (flags.var2.b - 1)) & 1); + break; + case t_RCRw: + SET_FLAG(FLAG_CF,(flags.var1.w >> (flags.var2.b - 1)) & 1); + break; + case t_RCRd: + SET_FLAG(FLAG_CF,(flags.var1.d >> (flags.var2.b - 1)) & 1); + break; + + + case t_INCb: + SET_FLAG(FLAG_OF,(flags.result.b == 0x80)); + SET_FLAG(FLAG_AF,((flags.result.b & 0x0f) == 0)); + break; + case t_INCw: + SET_FLAG(FLAG_OF,(flags.result.w == 0x8000)); + SET_FLAG(FLAG_AF,((flags.result.w & 0x0f) == 0)); + break; + case t_INCd: + SET_FLAG(FLAG_OF,(flags.result.d == 0x80000000)); + SET_FLAG(FLAG_AF,((flags.result.d & 0x0f) == 0)); + break; + + + case t_DECb: + SET_FLAG(FLAG_OF,(flags.result.b == 0x7f)); + break; + case t_DECw: + SET_FLAG(FLAG_OF,(flags.result.w == 0x7fff)); + break; + case t_DECd: + SET_FLAG(FLAG_OF,(flags.result.d == 0x7fffffff)); + break; + + + case t_NEGb: + SET_FLAG(FLAG_CF,(flags.var1.b!=0)); + break; + case t_NEGw: + SET_FLAG(FLAG_CF,(flags.var1.w!=0)); + break; + case t_NEGd: + SET_FLAG(FLAG_CF,(flags.var1.d!=0)); + break; + + + case t_DIV: + SET_FLAG(FLAG_CF,false); /* Unkown */ + break; + default: + LOG(LOG_ERROR|LOG_CPU,"Unhandled flag type %d",flags.type); + return 0; + } + flags.word=new_flags; + return 0; +} + +Bit8u * blah=(Bit8u *)&get_Flags; From 4826bf78e0c5f5ad96ca71e88ab84464f49ce2ca Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:35:09 +0000 Subject: [PATCH 0839/4131] Added lot's of new opcodes Moved some core_16 specific functions out. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@919 --- src/cpu/instructions.h | 537 ++++++++++++++++++++++++++++------------- 1 file changed, 374 insertions(+), 163 deletions(-) diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index b43405d2..ed6b9a35 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -18,41 +18,6 @@ /* 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 SETcc(cc) \ - { \ - GetRM; \ - if (rm >= 0xc0 ) {GetEArb;*earb=(cc) ? 1 : 0;} \ - else {GetEAa;SaveMb(eaa,(cc) ? 1 : 0);} \ - } - -#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; \ @@ -254,178 +219,164 @@ 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) break; \ - flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ - flags.var2.b=op2&0x07;flags.var1.b=load(op1); \ - if (!flags.var2.b) { \ - flags.result.b=flags.var1.b; \ - } else { \ + if (op2&0x07) { \ + LoadZF;LoadSF;LoadAF; \ + flags.var1.b=load(op1); \ + flags.var2.b=op2&0x07; \ flags.result.b=(flags.var1.b << flags.var2.b) | \ (flags.var1.b >> (8-flags.var2.b)); \ - } \ - save(op1,flags.result.b); \ - flags.type=t_ROLb; + save(op1,flags.result.b); \ + flags.type=t_ROLb; \ + } #define ROLW(op1,op2,load,save) \ - if (!op2) break; \ - flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ - flags.var2.b=op2&0x0F;flags.var1.w=load(op1); \ - if (!flags.var2.b) { \ - flags.result.w=flags.var1.w; \ - } else { \ + if (op2&0x0F) { \ + LoadZF;LoadSF;LoadAF; \ + flags.var1.w=load(op1); \ + flags.var2.b=op2&0x0F; \ flags.result.w=(flags.var1.w << flags.var2.b) | \ (flags.var1.w >> (16-flags.var2.b)); \ - } \ - save(op1,flags.result.w); \ - flags.type=t_ROLw; + save(op1,flags.result.w); \ + flags.type=t_ROLw; \ + } #define ROLD(op1,op2,load,save) \ - if (!op2) break; \ - flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ - flags.var2.b=op2;flags.var1.d=load(op1); \ - flags.result.d=(flags.var1.d << flags.var2.b) | \ + if (op2) { \ + LoadZF;LoadSF;LoadAF; \ + flags.var1.d=load(op1); \ + flags.var2.b=op2; \ + flags.result.d=(flags.var1.d << flags.var2.b) | \ (flags.var1.d >> (32-flags.var2.b)); \ - save(op1,flags.result.d); \ - flags.type=t_ROLd; - + save(op1,flags.result.d); \ + flags.type=t_ROLd; \ + } #define RORB(op1,op2,load,save) \ - if (!op2) break; \ - flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ - flags.var2.b=op2&0x07;flags.var1.b=load(op1); \ - if (!flags.var2.b) { \ - flags.result.b=flags.var1.b; \ - } else { \ + if (op2&0x07) { \ + LoadZF;LoadSF;LoadAF; \ + flags.var1.b=load(op1); \ + flags.var2.b=op2&0x07; \ flags.result.b=(flags.var1.b >> flags.var2.b) | \ (flags.var1.b << (8-flags.var2.b)); \ + save(op1,flags.result.b); \ + flags.type=t_RORb; \ } \ - save(op1,flags.result.b); \ - flags.type=t_RORb; #define RORW(op1,op2,load,save) \ - if (!op2) break; \ - flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ - flags.var2.b=op2&0x0F;flags.var1.w=load(op1); \ - if (!flags.var2.b) { \ - flags.result.w=flags.var1.w; \ - } else { \ + if (op2&0x0F) { \ + LoadZF;LoadSF;LoadAF; \ + flags.var1.w=load(op1); \ + flags.var2.b=op2&0x0F; \ flags.result.w=(flags.var1.w >> flags.var2.b) | \ (flags.var1.w << (16-flags.var2.b)); \ - } \ - save(op1,flags.result.w); \ - flags.type=t_RORw; + save(op1,flags.result.w); \ + flags.type=t_RORw; \ + } #define RORD(op1,op2,load,save) \ - if (!op2) break; \ - flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \ - flags.var2.b=op2;flags.var1.d=load(op1); \ - flags.result.d=(flags.var1.d >> flags.var2.b) | \ + if (op2) { \ + LoadZF;LoadSF;LoadAF; \ + flags.var1.d=load(op1); \ + flags.var2.b=op2; \ + flags.result.d=(flags.var1.d >> flags.var2.b) | \ (flags.var1.d << (32-flags.var2.b)); \ - save(op1,flags.result.d); \ - flags.type=t_RORd; + save(op1,flags.result.d); \ + flags.type=t_RORd; \ + } -/* flags.oldcf=get_CF();*/ \ - #define RCLB(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_RCLb; \ - flags.var2.b=op2%9;flags.var1.b=load(op1); \ - if (!flags.var2.b) { \ - flags.result.b=flags.var1.b; \ - } else { \ + if (op2%9) { \ + LoadZF;LoadSF;LoadAF; \ + Bit8u cf=get_CF(); \ + flags.var1.b=load(op1); \ + flags.var2.b=op2%9; \ + flags.type=t_RCLb; \ flags.result.b=(flags.var1.b << flags.var2.b) | \ - (flags.cf << (flags.var2.b-1)) | \ + (cf << (flags.var2.b-1)) | \ (flags.var1.b >> (9-flags.var2.b)); \ - flags.cf=((flags.var1.b >> (8-flags.var2.b)) & 1); \ - } \ - flags.of=((flags.result.b & 0x80) ^ (flags.cf ? 0x80 : 0)) != 0; \ - save(op1,flags.result.b); + SETFLAGBIT(CF,((flags.var1.b >> (8-flags.var2.b)) & 1)); \ + SETFLAGBIT(OF,((flags.result.b & 0x80) ^ (cf ? 0x80 : 0)) != 0); \ + save(op1,flags.result.b); \ + } #define RCLW(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_RCLw; \ - flags.var2.b=op2%17;flags.var1.w=load(op1); \ - if (!flags.var2.b) { \ - flags.result.w=flags.var1.w; \ - } else { \ + if (op2%17) { \ + LoadZF;LoadSF;LoadAF; \ + Bit16u cf=get_CF(); \ + flags.var1.w=load(op1); \ + flags.var2.b=op2%17; \ + flags.type=t_RCLw; \ flags.result.w=(flags.var1.w << flags.var2.b) | \ - (flags.cf << (flags.var2.b-1)) | \ + (cf << (flags.var2.b-1)) | \ (flags.var1.w >> (17-flags.var2.b)); \ - flags.cf=((flags.var1.w >> (16-flags.var2.b)) & 1); \ - } \ - flags.of=((flags.result.w & 0x8000) ^ (flags.cf ? 0x8000 : 0)) != 0; \ - save(op1,flags.result.w); + SETFLAGBIT(CF,((flags.var1.w >> (16-flags.var2.b)) & 1)); \ + SETFLAGBIT(OF,((flags.result.w & 0x8000) ^ (cf ? 0x8000 : 0)) != 0); \ + 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.var2.b=op2;flags.var1.d=load(op1); \ - 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)); \ - } \ - flags.cf=((flags.var1.d >> (32-flags.var2.b)) & 1); \ - flags.of=((flags.result.d & 0x80000000) ^ (flags.cf ? 0x80000000 : 0)) != 0; \ - save(op1,flags.result.d); + if (op2) { \ + LoadZF;LoadSF;LoadAF; \ + Bit32u cf=get_CF(); \ + flags.var1.d=load(op1); \ + flags.var2.b=op2; \ + flags.type=t_RCLd; \ + if (flags.var2.b==1) { \ + flags.result.d=(flags.var1.d << 1) | cf; \ + } else { \ + flags.result.d=(flags.var1.d << flags.var2.b) | \ + (cf << (flags.var2.b-1)) | \ + (flags.var1.d >> (33-flags.var2.b)); \ + } \ + SETFLAGBIT(CF,((flags.var1.d >> (32-flags.var2.b)) & 1)); \ + SETFLAGBIT(OF,((flags.result.d & 0x80000000) ^ (cf ? 0x80000000 : 0)) != 0); \ + save(op1,flags.result.d); \ + } #define RCRB(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_RCRb; \ - flags.var2.b=op2%9;flags.var1.b=load(op1); \ - if (!flags.var2.b) { \ - flags.result.b=flags.var1.b; \ - } else { \ + if (op2%9) { \ + LoadZF;LoadSF;LoadAF; \ + Bit8u cf=get_CF(); \ + flags.var1.b=load(op1); \ + flags.var2.b=op2%9; \ + flags.type=t_RCRb; \ flags.result.b=(flags.var1.b >> flags.var2.b) | \ - (flags.cf << (8-flags.var2.b)) | \ + (cf << (8-flags.var2.b)) | \ (flags.var1.b << (9-flags.var2.b)); \ - } \ - save(op1,flags.result.b); + save(op1,flags.result.b); \ + } #define RCRW(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_RCRw; \ - flags.var2.b=op2%17;flags.var1.w=load(op1); \ - if (!flags.var2.b) { \ - flags.result.w=flags.var1.w; \ - } else { \ + if (op2%17) { \ + LoadZF;LoadSF;LoadAF; \ + Bit16u cf=get_CF(); \ + flags.var1.w=load(op1); \ + flags.var2.b=op2%17; \ + flags.type=t_RCRw; \ flags.result.w=(flags.var1.w >> flags.var2.b) | \ - (flags.cf << (16-flags.var2.b)) | \ + (cf << (16-flags.var2.b)) | \ (flags.var1.w << (17-flags.var2.b)); \ - } \ - save(op1,flags.result.w); + 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.var2.b=op2;flags.var1.d=load(op1); \ - 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)) | \ + if (op2) { \ + LoadZF;LoadSF;LoadAF; \ + Bit32u cf=get_CF(); \ + flags.var1.d=load(op1); \ + flags.var2.b=op2; \ + flags.type=t_RCRd; \ + if (flags.var2.b==1) { \ + flags.result.d=flags.var1.d >> 1 | cf << 31; \ + } else { \ + flags.result.d=(flags.var1.d >> flags.var2.b) | \ + (cf << (32-flags.var2.b)) | \ (flags.var1.d << (33-flags.var2.b)); \ - } \ - save(op1,flags.result.d); + } \ + save(op1,flags.result.d); \ + } #define SHLB(op1,op2,load,save) \ @@ -512,6 +463,266 @@ +#define DAA() \ + if (((reg_al & 0x0F)>0x09) || get_AF()) { \ + reg_al+=0x06; \ + SETFLAGBIT(AF,true); \ + } else { \ + SETFLAGBIT(AF,false); \ + } \ + if ((reg_al > 0x9F) || get_CF()) { \ + reg_al+=0x60; \ + SETFLAGBIT(CF,true); \ + } else { \ + SETFLAGBIT(CF,false); \ + } \ + SETFLAGBIT(SF,(reg_al&0x80)); \ + SETFLAGBIT(ZF,(reg_al==0)); \ + flags.type=t_UNKNOWN; + + +#define DAS() \ + if (((reg_al & 0x0f) > 9) || get_AF()) { \ + reg_al-=6; \ + SETFLAGBIT(AF,true); \ + } else { \ + SETFLAGBIT(AF,false); \ + } \ + if ((reg_al>0x9f) || get_CF()) { \ + reg_al-=0x60; \ + SETFLAGBIT(CF,true); \ + } else { \ + SETFLAGBIT(CF,false); \ + } \ + flags.type=t_UNKNOWN; + + +#define AAA() \ + if (get_AF() || ((reg_al & 0xf) > 9)) \ + { \ + reg_al += 6; \ + reg_ah += 1; \ + SETFLAGBIT(AF,true); \ + SETFLAGBIT(CF,true); \ + } else { \ + SETFLAGBIT(AF,false); \ + SETFLAGBIT(CF,false); \ + } \ + reg_al &= 0x0F; \ + flags.type=t_UNKNOWN; + +#define AAS() \ + if (((reg_al & 0x0f)>9) || get_AF()) { \ + reg_ah--; \ + if (reg_al < 6) reg_ah--; \ + reg_al=(reg_al-6) & 0xF; \ + SETFLAGBIT(AF,true); \ + SETFLAGBIT(CF,true); \ + } else { \ + SETFLAGBIT(AF,false); \ + SETFLAGBIT(CF,false); \ + } \ + reg_al &= 0x0F; \ + flags.type=t_UNKNOWN; + +#define AAM(op1) \ + { \ + Bit8u BLAH=op1; \ + reg_ah=reg_al / BLAH; \ + reg_al=reg_al % BLAH; \ + flags.type=t_UNKNOWN; \ + SETFLAGBIT(SF,(reg_ah & 0x80)); \ + SETFLAGBIT(ZF,(reg_ax == 0)); \ + SETFLAGBIT(PF,false); \ + } + + +#define AAD(op1) \ + { \ + Bit8u BLAH=op1; \ + reg_al=reg_ah*BLAH+reg_al; \ + reg_ah=0; \ + SETFLAGBIT(CF,(reg_al>=0x80)); \ + SETFLAGBIT(ZF,(reg_al==0)); \ + SETFLAGBIT(PF,false); \ + flags.type=t_UNKNOWN; \ + } + + + +#define MULB(op1,load,save) \ + flags.type=t_MUL; \ + reg_ax=reg_al*load(op1); \ + if (reg_ax & 0xff00) { \ + SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ + } else { \ + SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ + } + +#define MULW(op1,load,save) \ +{ \ + Bitu tempu=(Bitu)reg_ax*(Bitu)(load(op1)); \ + reg_ax=(Bit16u)(tempu); \ + reg_dx=(Bit16u)(tempu >> 16); \ + flags.type=t_MUL; \ + if (reg_dx) { \ + SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ + } else { \ + SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ + } \ +} + +#define MULD(op1,load,save) \ +{ \ + Bit64u tempu=(Bit64u)reg_eax*(Bit64u)(load(op1)); \ + reg_eax=(Bit32u)(tempu); \ + reg_edx=(Bit32u)(tempu >> 32); \ + flags.type=t_MUL; \ + if (reg_edx) { \ + SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ + } else { \ + SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ + } \ +} + +#define DIVB(op1,load,save) \ +{ \ + Bitu val=load(op1); \ + if (val==0) EXCEPTION(0); \ + Bitu quo=reg_ax / val; \ + reg_ah=(Bit8u)(reg_ax % val); \ + reg_al=(Bit8u)quo; \ + if (quo>0xff) EXCEPTION(0); \ +} + + +#define DIVW(op1,load,save) \ +{ \ + Bitu val=load(op1); \ + if (val==0) EXCEPTION(0); \ + Bitu num=(reg_dx<<16)|reg_ax; \ + Bitu quo=num/val; \ + reg_dx=(Bit16u)(num % val); \ + reg_ax=(Bit16u)quo; \ + if (quo>0xffff) EXCEPTION(0); \ +} + +#define DIVD(op1,load,save) \ +{ \ + Bitu val=load(op1); \ + if (!val) EXCEPTION(0); \ + Bit64u num=(((Bit64u)reg_edx)<<32)|reg_eax; \ + Bit64u quo=num/val; \ + reg_edx=(Bit32u)(num % val); \ + reg_eax=(Bit32u)quo; \ + if (quo!=(Bit64u)reg_eax) EXCEPTION(0); \ +} + + +#define IDIVB(op1,load,save) \ +{ \ + Bits val=(Bit8s)(load(op1)); \ + if (val==0) EXCEPTION(0); \ + Bits quo=((Bit16s)reg_ax) / val; \ + reg_ah=(Bit8s)(((Bit16s)reg_ax) % val); \ + reg_al=(Bit8s)quo; \ + if (quo!=(Bit8s)reg_al) EXCEPTION(0); \ +} + + +#define IDIVW(op1,load,save) \ +{ \ + Bits val=(Bit16s)(load(op1)); \ + if (!val) EXCEPTION(0); \ + Bits num=(Bit32s)((reg_dx<<16)|reg_ax); \ + Bits quo=num/val; \ + reg_dx=(Bit16u)(num % val); \ + reg_ax=(Bit16s)quo; \ + if (quo!=(Bit16s)reg_ax) EXCEPTION(0); \ +} + +#define IDIVD(op1,load,save) \ +{ \ + Bits val=(Bit32s)(load(op1)); \ + if (!val) EXCEPTION(0); \ + Bit64s num=(((Bit64u)reg_edx)<<32)|reg_eax; \ + Bit64s quo=num/val; \ + reg_edx=(Bit32s)(num % val); \ + reg_eax=(Bit32s)(quo); \ + if (quo!=(Bit64s)((Bit32s)reg_eax)) EXCEPTION(0); \ +} + +#define IMULB(op1,load,save) \ +{ \ + flags.type=t_MUL; \ + reg_ax=((Bit8s)reg_al) * ((Bit8s)(load(op1))); \ + if ((reg_ax & 0xff80)==0xff80 || \ + (reg_ax & 0xff80)==0x0000) { \ + SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ + } else { \ + SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ + } \ +} + + +#define IMULW(op1,load,save) \ +{ \ + Bits temps=((Bit16s)reg_ax)*((Bit16s)(load(op1))); \ + reg_ax=(Bit16s)(temps); \ + reg_dx=(Bit16s)(temps >> 16); \ + flags.type=t_MUL; \ + if (((temps & 0xffff8000)==0xffff8000 || \ + (temps & 0xffff8000)==0x0000)) { \ + SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ + } else { \ + SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ + } \ +} + +#define IMULD(op1,load,save) \ +{ \ + Bit64s temps=((Bit64s)((Bit32s)reg_eax))* \ + ((Bit64s)((Bit32s)(load(op1)))); \ + reg_eax=(Bit32u)(temps); \ + reg_edx=(Bit32u)(temps >> 32); \ + flags.type=t_MUL; \ + if ((reg_edx==0xffffffff) && \ + (reg_eax & 0x80000000) ) { \ + SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ + } else if ( (reg_edx==0x00000000) && \ + (reg_eax< 0x80000000) ) { \ + SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ + } else { \ + SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ + } \ +} + +#define DIMULW(op1,op2,op3,load,save) \ +{ \ + Bits res; \ + res=((Bit16s)op2) * ((Bit16s)op3); \ + save(op1,res & 0xffff); \ + flags.type=t_MUL; \ + if ((res> -32768) && (res<32767)) { \ + SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ + } else { \ + SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ + } \ +} + +#define DIMULD(op1,op2,op3,load,save) \ +{ \ + Bit64s res=((Bit64s)((Bit32s)op2))*((Bit64s)((Bit32s)op3)); \ + save(op1,(Bit32s)res); \ + flags.type=t_MUL; \ + if ((res>-((Bit64s)(2147483647)+1)) && \ + (res<(Bit64s)2147483647)) { \ + SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ + } else { \ + SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ + } \ +} + #define GRP2B(blah) \ { \ GetRM; \ From bb7bd6c3be314c7ae3f5ad0aa5046c244fbc6b0c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:36:20 +0000 Subject: [PATCH 0840/4131] Changes for new flags Opcodes moved into instructions.h Added support for a load of protected mode related opcodes. Fixed some opcodes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@920 --- src/cpu/core_full.cpp | 18 ++- src/cpu/core_full/load.h | 125 ++++++-------- src/cpu/core_full/loadwrite.h | 73 +++++---- src/cpu/core_full/main.h | 0 src/cpu/core_full/op.h | 297 ++++++++++++++++++---------------- src/cpu/core_full/optable.h | 221 +++++++++++++------------ src/cpu/core_full/save.h | 32 ++-- src/cpu/core_full/string.h | 7 +- src/cpu/core_full/support.h | 33 +++- 9 files changed, 423 insertions(+), 383 deletions(-) delete mode 100644 src/cpu/core_full/main.h diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 98aeb613..ec305518 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -32,6 +32,7 @@ static EAPoint IPPoint; #include "core_full/ea_lookup.h" #include "instructions.h" + static INLINE void DecodeModRM(void) { inst.rm=Fetchb(); inst.rm_index=(inst.rm >> 3) & 7; @@ -41,14 +42,25 @@ static INLINE void DecodeModRM(void) { if (inst.rm<0xc0) inst.rm_eaa=(inst.prefix & PREFIX_ADDR) ? RMAddress_32() : RMAddress_16(); } +#define EXCEPTION(blah) \ + { \ + Bit8u new_num=blah; \ + SaveIP(); \ + Interrupt(new_num); \ + LoadIP(); \ + goto nextopcode; \ + } Bitu Full_DeCode(void) { + LoadIP(); while (CPU_Cycles>0) { #if C_DEBUG cycle_count++; #endif CPU_Cycles--; + inst.entry=cpu.full.entry; + inst.prefix=cpu.full.prefix; restartopcode: inst.entry=(inst.entry & 0xffffff00) | Fetchb(); @@ -56,9 +68,7 @@ restartopcode: #include "core_full/load.h" #include "core_full/op.h" #include "core_full/save.h" -nextopcode: - inst.prefix=0; - inst.entry=0; +nextopcode:; } SaveIP(); return 0; @@ -67,4 +77,4 @@ nextopcode: void CPU_Core_Full_Start(void) { cpudecoder=&Full_DeCode; -} \ No newline at end of file +} diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index f547a012..cb2a0347 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -213,10 +213,8 @@ l_M_Ed: inst.op1.d=reg_32(inst.code.extra); break; case L_FLG: - inst.op1.d= (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); + FILLFLAGS; + inst.op1.d = flags.word; break; case L_SEG: inst.op1.d=SegValue((SegNames)inst.code.extra); @@ -263,25 +261,47 @@ l_M_Ed: if (!get_OF()) goto nextopcode; inst.op1.d=4; break; - case L_IRETw: - inst.op1.d=Pop_16(); - inst.op2.d=Pop_16(); - { - Bitu temp=Pop_16(); - Save_Flagsw(temp); - } - break; + case D_IRETw: + CPU_IRET(false); + LoadIP(); + goto nextopcode; + case D_IRETd: + CPU_IRET(true); + LoadIP(); + goto nextopcode; + case D_RETFwIw: + CPU_RET(false,Fetchw()); + LoadIP(); + goto nextopcode; + case D_RETFw: + CPU_RET(false,0); + LoadIP(); + goto nextopcode; + case D_RETFdIw: + CPU_RET(true,Fetchw()); + LoadIP(); + goto nextopcode; + case D_RETFd: + CPU_RET(true,0); + LoadIP(); + goto nextopcode; /* Direct operations */ case L_STRING: #include "string.h" - goto nextopcode; + goto nextopcode; case D_PUSHAw: - Push_16(reg_ax);Push_16(reg_cx);Push_16(reg_dx);Push_16(reg_bx); - Push_16(reg_sp);Push_16(reg_bp);Push_16(reg_si);Push_16(reg_di); + { + Bit16u old_sp=reg_sp; + Push_16(reg_ax);Push_16(reg_cx);Push_16(reg_dx);Push_16(reg_bx); + Push_16(old_sp);Push_16(reg_bp);Push_16(reg_si);Push_16(reg_di); + } goto nextopcode; case D_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); + { + Bit32u old_esp=reg_esp; + Push_32(reg_eax);Push_32(reg_ecx);Push_32(reg_edx);Push_32(reg_ebx); + Push_32(old_esp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi); + } goto nextopcode; case D_POPAw: reg_di=Pop_16();reg_si=Pop_16();reg_bp=Pop_16();Pop_16();//Don't save SP @@ -310,36 +330,36 @@ l_M_Ed: else reg_edx=0; goto nextopcode; case D_CLI: - flags.intf=false; + SETFLAGBIT(IF,false); goto nextopcode; case D_STI: - flags.intf=true; - if (flags.intf && PIC_IRQCheck) { + SETFLAGBIT(IF,true); + if (PIC_IRQCheck) { SaveIP(); PIC_runIRQs(); LoadIP(); } goto nextopcode; case D_STC: - flags.cf=true; + SETFLAGBIT(CF,true); if (flags.type!=t_CF) flags.prev_type=flags.type; flags.type=t_CF; goto nextopcode; case D_CLC: - flags.cf=false; + SETFLAGBIT(CF,false); if (flags.type!=t_CF) flags.prev_type=flags.type; flags.type=t_CF; goto nextopcode; case D_CMC: - flags.cf=!get_CF(); + SETFLAGBIT(CF,!get_CF()); if (flags.type!=t_CF) flags.prev_type=flags.type; flags.type=t_CF; goto nextopcode; case D_CLD: - flags.df=false; + SETFLAGBIT(DF,false); goto nextopcode; case D_STD: - flags.df=true; + SETFLAGBIT(DF,true); goto nextopcode; case D_NOP: goto nextopcode; @@ -357,63 +377,16 @@ l_M_Ed: reg_bp=Pop_16(); goto nextopcode; case D_DAA: - if (((reg_al & 0x0F)>0x09) || get_AF()) { - reg_al+=0x06; - flags.af=true; - } else { - flags.af=false; - } - flags.cf=get_CF(); - if ((reg_al > 0x9F) || flags.cf) { - reg_al+=0x60; - flags.cf=true; - } else { - flags.cf=false; - } - flags.sf=(reg_al&0x80)>0; - flags.zf=(reg_al==0); - flags.type=t_UNKNOWN; + DAA(); goto nextopcode; case D_DAS: - if (((reg_al & 0x0f) > 9) || get_AF()) { - reg_al-=6; - flags.af=true; - } else { - flags.af=false; - } - if ((reg_al>0x9f) || get_CF()) { - reg_al-=0x60; - flags.cf=true; - } else { - flags.cf=false; - } - flags.type=t_UNKNOWN; + DAS(); goto nextopcode; case D_AAA: - if (get_AF() || ((reg_al & 0xf) > 9)) - { - reg_al += 6; - reg_ah += 1; - flags.af=true; - flags.cf=true; - } else { - flags.af=false; - flags.cf=false; - } - reg_al &= 0x0F; - flags.type=t_UNKNOWN; + AAA(); goto nextopcode; case D_AAS: - if (((reg_al & 0x0f)>9) || get_AF()) { - reg_ah--; - if (reg_al < 6) reg_ah--; - reg_al=(reg_al-6) & 0xF; - flags.af=flags.cf=true; - } else { - flags.af=flags.cf=false; - } - reg_al&=0xf; - flags.type=t_UNKNOWN; + AAS(); goto nextopcode; default: LOG(LOG_CPU|LOG_ERROR,"LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry); diff --git a/src/cpu/core_full/loadwrite.h b/src/cpu/core_full/loadwrite.h index 914ff2eb..c1e192fb 100644 --- a/src/cpu/core_full/loadwrite.h +++ b/src/cpu/core_full/loadwrite.h @@ -13,7 +13,7 @@ static INLINE Bit8u Fetchb() { IPPoint+=1; return temp; } - + static INLINE Bit16u Fetchw() { Bit16u temp=LoadMw(IPPoint); IPPoint+=2; @@ -37,39 +37,50 @@ static INLINE Bit32s Fetchds() { } static INLINE void Push_16(Bit16u blah) { - reg_sp-=2; - SaveMw(SegBase(ss)+reg_sp,blah); -}; + if (cpu.state & STATE_STACK32) { + reg_esp-=2; + SaveMw(SegBase(ss)+reg_esp,blah); + } else { + 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 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 (cpu.state & STATE_STACK32) { + reg_esp-=4; + SaveMd(SegBase(ss)+reg_esp,blah); + } else { + reg_sp-=4; + SaveMd(SegBase(ss)+reg_sp,blah); + } } + +static INLINE Bit16u Pop_16(void) { + if (cpu.state & STATE_STACK32) { + Bit16u temp=LoadMw(SegBase(ss)+reg_esp); + reg_esp+=2; + return temp; + } else { + Bit16u temp=LoadMw(SegBase(ss)+reg_sp); + reg_sp+=2; + return temp; + } +} + +static INLINE Bit32u Pop_32(void) { + if (cpu.state & STATE_STACK32) { + Bit32u temp=LoadMd(SegBase(ss)+reg_esp); + reg_esp+=4; + return temp; + } else { + Bit32u temp=LoadMd(SegBase(ss)+reg_sp); + reg_sp+=4; + return temp; + } +} + + #if 0 if (flags.intf && PIC_IRQCheck) { \ SaveIP(); \ diff --git a/src/cpu/core_full/main.h b/src/cpu/core_full/main.h deleted file mode 100644 index e69de29b..00000000 diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 1464bbdc..2c2f24bf 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -47,12 +47,12 @@ switch (inst.code.op) { flags.type=inst.code.op; break; case t_INCb: case t_INCw: case t_INCd: - flags.cf=get_CF(); + SETFLAGBIT(CF,get_CF()); inst.op1.d=flags.result.d=inst.op1.d+1; flags.type=inst.code.op; break; case t_DECb: case t_DECw: case t_DECd: - flags.cf=get_CF(); + SETFLAGBIT(CF,get_CF()); inst.op1.d=flags.result.d=inst.op1.d-1; flags.type=inst.code.op; break; @@ -170,150 +170,52 @@ switch (inst.code.op) { /* Special instructions */ case O_IMULRw: - inst.op1.ds=inst.op1.ds*inst.op2.ds; - flags.type=t_MUL; - if ((inst.op1.ds> -32768) && (inst.op1.ds<32767)) { - flags.cf=false;flags.of=false; - } else { - flags.cf=true;flags.of=true; - } + DIMULW(inst.op1.ws,inst.op1.ws,inst.op2.ws,LoadD,SaveD); break; case O_IMULRd: - { - Bit64s res=(Bit64s)inst.op1.ds*(Bit64s)inst.op2.ds; - inst.op1.ds=(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; - } + DIMULD(inst.op1.ds,inst.op1.ds,inst.op2.ds,LoadD,SaveD); + break; case O_MULb: - flags.type=t_MUL; - reg_ax=reg_al*inst.op1.b; - flags.cf=flags.of=((reg_ax & 0xff00) !=0); + MULB(inst.op1.b,LoadD,0); goto nextopcode; case O_MULw: - { - Bit32u tempu=(Bit32u)reg_ax*(Bit32u)inst.op1.w; - reg_ax=(Bit16u)(tempu); - reg_dx=(Bit16u)(tempu >> 16); - flags.type=t_MUL; - flags.cf=flags.of=(reg_dx !=0); - goto nextopcode; - } + MULW(inst.op1.w,LoadD,0); + goto nextopcode; case O_MULd: - { - Bit64u tempu=(Bit64u)reg_eax*(Bit64u)inst.op1.d; - reg_eax=(Bit32u)(tempu); - reg_edx=(Bit32u)(tempu >> 32); - flags.type=t_MUL; - flags.cf=flags.of=(reg_edx !=0); - goto nextopcode; - } + MULD(inst.op1.d,LoadD,0); + goto nextopcode; case O_IMULb: - flags.type=t_MUL; - reg_ax=((Bit8s)reg_al)*inst.op1.bs; - flags.cf=flags.of=!((reg_ax & 0xff80)==0xff80 || (reg_ax & 0xff80)==0x0000); + IMULB(inst.op1.b,LoadD,0); goto nextopcode; case O_IMULw: - { - Bit32s temps=(Bit16s)reg_ax*inst.op1.ws; - reg_ax=(Bit16s)(temps); - reg_dx=(Bit16s)(temps >> 16); - flags.type=t_MUL; - flags.cf=flags.of=!((temps & 0xffffff80)==0xffffff80 || (temps & 0xffffff80)==0x0000); - goto nextopcode; - } + IMULW(inst.op1.w,LoadD,0); + goto nextopcode; case O_IMULd: - { - Bit64s temps=(Bit64s)((Bit32s)reg_eax)*(Bit64s)inst.op1.ds; - reg_eax=(Bit32u)(temps); - reg_edx=(Bit32u)(temps >> 32); - flags.type=t_MUL; - 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; - } - goto nextopcode; - } + IMULD(inst.op1.d,LoadD,0); + goto nextopcode; case O_DIVb: - { - if (!inst.op1.b) goto doint; - Bitu val=reg_ax;Bitu quo=val/inst.op1.b; - reg_ah=(Bit8u)(val % inst.op1.b); - reg_al=(Bit8u)quo; - if (quo!=reg_al) { inst.op1.b=0;goto doint;} - goto nextopcode; - } + DIVB(inst.op1.b,LoadD,0); + goto nextopcode; case O_DIVw: - { - if (!inst.op1.w) goto doint; - Bitu val=(reg_dx<<16)|reg_ax;Bitu quo=val/inst.op1.w; - reg_dx=(Bit16u)(val % inst.op1.w); - reg_ax=(Bit16u)quo; - if (quo!=reg_ax) { inst.op1.b=0;goto doint;} - goto nextopcode; - } + DIVW(inst.op1.w,LoadD,0); + goto nextopcode; case O_DIVd: - { - if (!inst.op1.d) goto doint; - Bit64u val=(((Bit64u)reg_edx)<<32)|reg_eax; - Bit64u quo=val/inst.op1.d; - reg_edx=(Bit32u)(val % inst.op1.d); - reg_eax=(Bit32u)quo; - if (quo!=(Bit64u)reg_eax) { inst.op1.b=0;goto doint;} - goto nextopcode; - } + DIVD(inst.op1.d,LoadD,0); + goto nextopcode; case O_IDIVb: - { - if (!inst.op1.b) goto doint; - Bits val=(Bit16s)reg_ax;Bits quo=val/inst.op1.bs; - reg_ah=(Bit8s)(val % inst.op1.bs); - reg_al=(Bit8s)quo; - if (quo!=(Bit8s)reg_al) { inst.op1.b=0;goto doint;} - goto nextopcode; - } + IDIVB(inst.op1.b,LoadD,0); + goto nextopcode; case O_IDIVw: - { - if (!inst.op1.w) goto doint; - Bits val=(Bit32s)((reg_dx<<16)|reg_ax);Bits quo=val/inst.op1.ws; - reg_dx=(Bit16u)(val % inst.op1.ws); - reg_ax=(Bit16s)quo; - if (quo!=(Bit16s)reg_ax) { inst.op1.b=0;goto doint;} - goto nextopcode; - } + IDIVW(inst.op1.w,LoadD,0); + goto nextopcode; case O_IDIVd: - { - if (!inst.op1.d) goto doint; - Bit64s val=(((Bit64u)reg_edx)<<32)|reg_eax; - Bit64s quo=val/inst.op1.ds; - reg_edx=(Bit32s)(val % inst.op1.ds); - reg_eax=(Bit32s)(quo); - if (quo!=(Bit64s)((Bit32s)reg_eax)) { inst.op1.b=0;goto doint;} - goto nextopcode; - } + IDIVD(inst.op1.d,LoadD,0); + goto nextopcode; case O_AAM: - reg_ah=reg_al / inst.op1.b; - reg_al=reg_al % inst.op1.b; - flags.type=t_UNKNOWN; - flags.sf=(reg_ah & 0x80) > 0; - flags.zf=(reg_ax == 0); - //TODO PF - flags.pf=0; + AAM(inst.op1.b); goto nextopcode; case O_AAD: - reg_al=reg_ah*inst.op1.b+reg_al; - reg_ah=0; - flags.cf=(reg_al>=0x80); - flags.zf=(reg_al==0); - //TODO PF - flags.type=t_UNKNOWN; + AAD(inst.op1.b); goto nextopcode; case O_C_O: inst.cond=get_OF(); break; @@ -363,19 +265,37 @@ switch (inst.code.op) { case O_SEGGS: inst.code.extra=gs; break; - - + case O_SEGSS: + inst.code.extra=ss; + break; + case O_LOOP: - if (--reg_cx) break; + if (inst.prefix & PREFIX_ADDR) { + if (--reg_ecx) break; + } else { + if (--reg_cx) break; + } goto nextopcode; case O_LOOPZ: - if (--reg_cx && get_ZF()) break; + if (inst.prefix & PREFIX_ADDR) { + if (--reg_ecx && get_ZF()) break; + } else { + if (--reg_cx && get_ZF()) break; + } goto nextopcode; case O_LOOPNZ: - if (--reg_cx && !get_ZF()) break; + if (inst.prefix & PREFIX_ADDR) { + if (--reg_ecx && !get_ZF()) break; + } else { + if (--reg_cx && !get_ZF()) break; + } goto nextopcode; case O_JCXZ: - if (reg_cx) goto nextopcode; + if (inst.prefix & PREFIX_ADDR) { + if (reg_ecx) goto nextopcode; + } else { + if (reg_cx) goto nextopcode; + } break; case O_XCHG_AX: { @@ -391,16 +311,28 @@ switch (inst.code.op) { inst.op1.d=temp; break; } - case O_CALL_N: + case O_CALLNw: SaveIP(); Push_16(reg_ip); break; - case O_CALL_F: - Push_16(SegValue(cs)); + case O_CALLNd: SaveIP(); - Push_16(reg_ip); + Push_32(reg_eip); break; -doint: + case O_CALLFw: + SaveIP(); + CPU_CALL(false,inst.op2.d,inst.op1.d); + LoadIP(); + goto nextopcode; + case O_CALLFd: + SaveIP(); + CPU_CALL(true,inst.op2.d,inst.op1.d); + LoadIP(); + goto nextopcode; + case O_JMPFw: + CPU_JMP(false,inst.op2.d,inst.op1.d); + LoadIP(); + goto nextopcode; case O_INT: SaveIP(); #if C_DEBUG @@ -448,6 +380,95 @@ doint: } else { E_Exit("Too high CallBack Number %d called",inst.op1.d); } + case O_GRP6w: + case O_GRP6d: + switch (inst.rm_index) { + case 0x02: /* LLDT */ + CPU_LLDT(inst.op1.d); + goto nextopcode; /* Else value will saved */ + default: + LOG(LOG_ERROR|LOG_CPU,"Group 6 Illegal subfunction %X",inst.rm_index); + } + break; + case O_GRP7w: + case O_GRP7d: + switch (inst.rm_index) { + case 0: /* SGDT */ + { + Bitu limit,base; + CPU_SGDT(limit,base); + SaveMw(inst.rm_eaa,limit); + SaveMd(inst.rm_eaa+2,base); + break; + } + case 1: /* SIDT */ + { + Bitu limit,base; + CPU_SIDT(limit,base); + SaveMw(inst.rm_eaa,limit); + SaveMd(inst.rm_eaa+2,base); + break; + } + case 2: /* LGDT */ + CPU_LGDT(LoadMw(inst.rm_eaa),LoadMd(inst.rm_eaa+2)&((inst.code.op == O_GRP7w) ? 0xFFFFFF : 0xFFFFFFFF)); + break; + case 3: /* LIDT */ + CPU_LIDT(LoadMw(inst.rm_eaa),LoadMd(inst.rm_eaa+2)&((inst.code.op == O_GRP7w) ? 0xFFFFFF : 0xFFFFFFFF)); + break; + case 4: /* SMSW */ + { + Bitu word;CPU_SMSW(word); + SaveMw(inst.rm_eaa,word); + break; + } + case 6: /* LMSW */ + { + Bitu word=LoadMw(inst.rm_eaa); + CPU_LMSW(word); + break; + } + default: + LOG(LOG_ERROR|LOG_CPU,"Group 7 Illegal subfunction %X",inst.rm_index); + } + break; + case O_M_Cd_Rd: + CPU_SET_CRX(inst.rm_index,inst.op1.d); + break; + case O_M_Rd_Cd: + inst.op1.d=CPU_GET_CRX(inst.rm_index); + break; + case O_LAR: + { + Bitu ar;CPU_LAR(inst.op1.d,ar); + inst.op2.d=ar; + } + break; + case O_BTd: + case O_BTSd: + case O_BTCd: + case O_BTRd: + { + Bitu val;PhysPt read; + Bitu mask=1 << (inst.op1.d & 31); + FILLFLAGS; + if (inst.rm<0xc0) { + read=inst.rm_eaa+4*(inst.op1.d / 32); + val=mem_readd(read); + } else { + val=reg_32(inst.rm_eai); + } + SETFLAGBIT(CF,(val&mask)>0); + if (inst.code.op==O_BTSd) val|=mask; + if (inst.code.op==O_BTRd) val&=~mask; + if (inst.code.op==O_BTCd) val^=mask; + if (inst.code.op==O_BTd) break; + if (inst.rm<0xc0) { + mem_writed(read,val); + } else { + reg_32(inst.rm_eai)=val; + } + } + break; case 0: break; default: diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 032d392d..ad76da33 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -80,15 +80,15 @@ static OpCode OpCodeTable[1024]={ /* 0x70 - 0x77 */ -{L_Ibx ,O_C_O ,S_C_ADDIP,0 },{L_Ibx ,O_C_NO ,S_C_ADDIP,0 }, -{L_Ibx ,O_C_B ,S_C_ADDIP,0 },{L_Ibx ,O_C_NB ,S_C_ADDIP,0 }, -{L_Ibx ,O_C_Z ,S_C_ADDIP,0 },{L_Ibx ,O_C_NZ ,S_C_ADDIP,0 }, -{L_Ibx ,O_C_BE ,S_C_ADDIP,0 },{L_Ibx ,O_C_NBE ,S_C_ADDIP,0 }, +{L_Ibx ,O_C_O ,S_C_AIPw,0 },{L_Ibx ,O_C_NO ,S_C_AIPw,0 }, +{L_Ibx ,O_C_B ,S_C_AIPw,0 },{L_Ibx ,O_C_NB ,S_C_AIPw,0 }, +{L_Ibx ,O_C_Z ,S_C_AIPw,0 },{L_Ibx ,O_C_NZ ,S_C_AIPw,0 }, +{L_Ibx ,O_C_BE ,S_C_AIPw,0 },{L_Ibx ,O_C_NBE ,S_C_AIPw,0 }, /* 0x78 - 0x7f */ -{L_Ibx ,O_C_S ,S_C_ADDIP,0 },{L_Ibx ,O_C_NS ,S_C_ADDIP,0 }, -{L_Ibx ,O_C_P ,S_C_ADDIP,0 },{L_Ibx ,O_C_NP ,S_C_ADDIP,0 }, -{L_Ibx ,O_C_L ,S_C_ADDIP,0 },{L_Ibx ,O_C_NL ,S_C_ADDIP,0 }, -{L_Ibx ,O_C_LE ,S_C_ADDIP,0 },{L_Ibx ,O_C_NLE ,S_C_ADDIP,0 }, +{L_Ibx ,O_C_S ,S_C_AIPw,0 },{L_Ibx ,O_C_NS ,S_C_AIPw,0 }, +{L_Ibx ,O_C_P ,S_C_AIPw,0 },{L_Ibx ,O_C_NP ,S_C_AIPw,0 }, +{L_Ibx ,O_C_L ,S_C_AIPw,0 },{L_Ibx ,O_C_NL ,S_C_AIPw,0 }, +{L_Ibx ,O_C_LE ,S_C_AIPw,0 },{L_Ibx ,O_C_NLE ,S_C_AIPw,0 }, /* 0x80 - 0x87 */ @@ -109,7 +109,7 @@ static OpCode OpCodeTable[1024]={ {L_REGw ,O_XCHG_AX ,S_REGw ,REGI_SI},{L_REGw ,O_XCHG_AX ,S_REGw ,REGI_DI}, /* 0x98 - 0x9f */ {D_CBW ,0 ,0 ,0 },{D_CWD ,0 ,0 ,0 }, -{L_Ifw ,O_CALL_F ,S_CSIP ,0 },{L_ERROR ,0 ,0 ,0 }, +{L_Ifw ,O_CALLFw ,0 ,0 },{L_ERROR ,0 ,0 ,0 }, {L_FLG ,0 ,S_PUSHw,0 },{L_POPw ,0 ,S_FLGw ,0 }, {L_REGb ,0 ,S_FLGb ,REGI_AH},{L_FLG ,0 ,S_REGb ,REGI_AH}, @@ -142,9 +142,9 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,0 ,S_Eb ,M_Ib },{L_MODRM ,0 ,S_Ew ,M_Iw }, /* 0xc8 - 0xcf */ {D_ENTERw ,0 ,0 ,0 },{D_LEAVEw ,0 ,0 ,0 }, -{L_POPfw ,0 ,S_CSIPIw,0 },{L_POPfw ,0 ,S_CSIP ,0 }, +{D_RETFwIw ,0 ,0 ,0 },{D_RETFw ,0 ,0 ,0 }, {L_VAL ,O_INT ,0 ,3 },{L_Ib ,O_INT ,0 ,0 }, -{L_INTO ,O_INT ,0 ,0 },{L_IRETw ,0 ,S_CSIP ,0 }, +{L_INTO ,O_INT ,0 ,0 },{D_IRETw ,0 ,0 ,0 }, /* 0xd0 - 0xd7 */ {L_MODRM ,5 ,0 ,M_GRP_1 },{L_MODRM ,6 ,0 ,M_GRP_1 }, @@ -159,13 +159,13 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,0 ,0 ,0 },{L_MODRM ,0 ,0 ,0 }, /* 0xe0 - 0xe7 */ -{L_Ibx ,O_LOOPNZ ,S_ADDIP,0 },{L_Ibx ,O_LOOPZ ,S_ADDIP,0 }, -{L_Ibx ,O_LOOP ,S_ADDIP,0 },{L_Ibx ,O_JCXZ ,S_ADDIP,0 }, +{L_Ibx ,O_LOOPNZ ,S_AIPw ,0 },{L_Ibx ,O_LOOPZ ,S_AIPw ,0 }, +{L_Ibx ,O_LOOP ,S_AIPw ,0 },{L_Ibx ,O_JCXZ ,S_AIPw ,0 }, {L_Ib ,O_INb ,0 ,0 },{L_Ib ,O_INw ,0 ,0 }, {L_Ib ,O_OUTb ,0 ,0 },{L_Ib ,O_OUTw ,0 ,0 }, /* 0xe8 - 0xef */ -{L_Iw ,O_CALL_N ,S_ADDIP,0 },{L_Iwx ,0 ,S_ADDIP,0 }, -{L_Ifw ,0 ,S_CSIP ,0 },{L_Ibx ,0 ,S_ADDIP,0 }, +{L_Iw ,O_CALLNw ,S_AIPw ,0 },{L_Iwx ,0 ,S_AIPw ,0 }, +{L_Ifw ,O_JMPFw ,0 ,0 },{L_Ibx ,0 ,S_AIPw ,0 }, {L_REGw ,O_INb ,0 ,REGI_DX},{L_REGw ,O_INw ,0 ,REGI_DX}, {L_REGw ,O_OUTb ,0 ,REGI_DX},{L_REGw ,O_OUTw ,0 ,REGI_DX}, @@ -181,7 +181,7 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,0xb ,0 ,M_GRP },{L_MODRM ,0xc ,0 ,M_GRP }, /* 0x100 - 0x107 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_GRP6w ,0 ,0 },{L_MODRM ,O_GRP7w ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, @@ -203,8 +203,8 @@ static OpCode OpCodeTable[1024]={ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x120 - 0x127 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_M_Rd_Cd ,S_Ed ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_M_Cd_Rd ,0 ,M_Ed },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, @@ -271,15 +271,15 @@ static OpCode OpCodeTable[1024]={ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x180 - 0x187 */ -{L_Iwx ,O_C_O ,S_C_ADDIP,0 },{L_Iwx ,O_C_NO ,S_C_ADDIP,0 }, -{L_Iwx ,O_C_B ,S_C_ADDIP,0 },{L_Iwx ,O_C_NB ,S_C_ADDIP,0 }, -{L_Iwx ,O_C_Z ,S_C_ADDIP,0 },{L_Iwx ,O_C_NZ ,S_C_ADDIP,0 }, -{L_Iwx ,O_C_BE ,S_C_ADDIP,0 },{L_Iwx ,O_C_NBE ,S_C_ADDIP,0 }, +{L_Iwx ,O_C_O ,S_C_AIPw,0 },{L_Iwx ,O_C_NO ,S_C_AIPw,0 }, +{L_Iwx ,O_C_B ,S_C_AIPw,0 },{L_Iwx ,O_C_NB ,S_C_AIPw,0 }, +{L_Iwx ,O_C_Z ,S_C_AIPw,0 },{L_Iwx ,O_C_NZ ,S_C_AIPw,0 }, +{L_Iwx ,O_C_BE ,S_C_AIPw,0 },{L_Iwx ,O_C_NBE ,S_C_AIPw,0 }, /* 0x188 - 0x18f */ -{L_Iwx ,O_C_S ,S_C_ADDIP,0 },{L_Iwx ,O_C_NS ,S_C_ADDIP,0 }, -{L_Iwx ,O_C_P ,S_C_ADDIP,0 },{L_Iwx ,O_C_NP ,S_C_ADDIP,0 }, -{L_Iwx ,O_C_L ,S_C_ADDIP,0 },{L_Iwx ,O_C_NL ,S_C_ADDIP,0 }, -{L_Iwx ,O_C_LE ,S_C_ADDIP,0 },{L_Iwx ,O_C_NLE ,S_C_ADDIP,0 }, +{L_Iwx ,O_C_S ,S_C_AIPw,0 },{L_Iwx ,O_C_NS ,S_C_AIPw,0 }, +{L_Iwx ,O_C_P ,S_C_AIPw,0 },{L_Iwx ,O_C_NP ,S_C_AIPw,0 }, +{L_Iwx ,O_C_L ,S_C_AIPw,0 },{L_Iwx ,O_C_NL ,S_C_AIPw,0 }, +{L_Iwx ,O_C_LE ,S_C_AIPw,0 },{L_Iwx ,O_C_NLE ,S_C_AIPw,0 }, /* 0x190 - 0x197 */ {L_MODRM ,O_C_O ,S_C_Eb,0 },{L_MODRM ,O_C_NO ,S_C_Eb,0 }, @@ -294,23 +294,23 @@ static OpCode OpCodeTable[1024]={ /* 0x1a0 - 0x1a7 */ {L_SEG ,0 ,S_PUSHw ,fs },{L_POPw ,0 ,S_SEGI ,fs }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{L_MODRM ,O_BTw ,0 ,0 }, {L_MODRM ,O_DSHLw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHLw ,S_Ew ,M_EwGwCL }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x1a8 - 0x1af */ {L_SEG ,0 ,S_PUSHw ,gs },{L_POPw ,0 ,S_SEGI ,gs }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSw ,0 ,0 }, {L_MODRM ,O_DSHRw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHRw ,S_Ew ,M_EwGwCL }, {0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRw ,S_Gw ,M_EwxGwx }, /* 0x1b0 - 0x1b7 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_SEGSS ,S_SEGGw,M_Efw },{L_MODRM ,O_BTRw ,0 ,0 }, {L_MODRM ,O_SEGFS ,S_SEGGw,M_Efw },{L_MODRM ,O_SEGGS ,S_SEGGw,M_Efw }, {L_MODRM ,0 ,S_Gw ,M_Eb },{L_MODRM ,0 ,S_Gw ,M_Ew }, /* 0x1b8 - 0x1bf */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,0xe ,0 ,M_GRP },{L_MODRM ,O_BTCw ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {L_MODRM ,0 ,S_Gw ,M_Ebx },{L_MODRM ,0 ,S_Gw ,M_Ewx }, @@ -429,8 +429,7 @@ static OpCode OpCodeTable[1024]={ {D_PUSHAd ,0 ,0 ,0 },{D_POPAd ,0 ,0 ,0 }, {L_MODRM ,O_BOUNDd ,0 ,0 },{0 ,0 ,0 ,0 }, {L_PRESEG ,0 ,0 ,fs },{L_PRESEG ,0 ,0 ,gs }, -//TODO check ox66 0x66 prefix -{0 ,0 ,0 ,0 },{L_PREADD ,0 ,0 ,0 }, +{L_PREOP ,0 ,0 ,0 },{L_PREADD ,0 ,0 ,0 }, /* 0x268 - 0x26f */ {L_Id ,0 ,S_PUSHd,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdId}, {L_Ibx ,0 ,S_PUSHd,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdIbx}, @@ -438,15 +437,15 @@ static OpCode OpCodeTable[1024]={ {L_STRING ,R_OUTSB ,0 ,0 },{L_STRING ,R_OUTSD ,0 ,0 }, /* 0x270 - 0x277 */ -{L_Ibx ,O_C_O ,S_C_ADDIP,0 },{L_Ibx ,O_C_NO ,S_C_ADDIP,0 }, -{L_Ibx ,O_C_B ,S_C_ADDIP,0 },{L_Ibx ,O_C_NB ,S_C_ADDIP,0 }, -{L_Ibx ,O_C_Z ,S_C_ADDIP,0 },{L_Ibx ,O_C_NZ ,S_C_ADDIP,0 }, -{L_Ibx ,O_C_BE ,S_C_ADDIP,0 },{L_Ibx ,O_C_NBE ,S_C_ADDIP,0 }, +{L_Ibx ,O_C_O ,S_C_AIPd,0 },{L_Ibx ,O_C_NO ,S_C_AIPd,0 }, +{L_Ibx ,O_C_B ,S_C_AIPd,0 },{L_Ibx ,O_C_NB ,S_C_AIPd,0 }, +{L_Ibx ,O_C_Z ,S_C_AIPd,0 },{L_Ibx ,O_C_NZ ,S_C_AIPd,0 }, +{L_Ibx ,O_C_BE ,S_C_AIPd,0 },{L_Ibx ,O_C_NBE ,S_C_AIPd,0 }, /* 0x278 - 0x27f */ -{L_Ibx ,O_C_S ,S_C_ADDIP,0 },{L_Ibx ,O_C_NS ,S_C_ADDIP,0 }, -{L_Ibx ,O_C_P ,S_C_ADDIP,0 },{L_Ibx ,O_C_NP ,S_C_ADDIP,0 }, -{L_Ibx ,O_C_L ,S_C_ADDIP,0 },{L_Ibx ,O_C_NL ,S_C_ADDIP,0 }, -{L_Ibx ,O_C_LE ,S_C_ADDIP,0 },{L_Ibx ,O_C_NLE ,S_C_ADDIP,0 }, +{L_Ibx ,O_C_S ,S_C_AIPd,0 },{L_Ibx ,O_C_NS ,S_C_AIPd,0 }, +{L_Ibx ,O_C_P ,S_C_AIPd,0 },{L_Ibx ,O_C_NP ,S_C_AIPd,0 }, +{L_Ibx ,O_C_L ,S_C_AIPd,0 },{L_Ibx ,O_C_NL ,S_C_AIPd,0 }, +{L_Ibx ,O_C_LE ,S_C_AIPd,0 },{L_Ibx ,O_C_NLE ,S_C_AIPd,0 }, /* 0x280 - 0x287 */ {L_MODRM ,0 ,0 ,M_GRP },{L_MODRM ,2 ,0 ,M_GRP }, @@ -467,7 +466,7 @@ static OpCode OpCodeTable[1024]={ {L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_SI},{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_DI}, /* 0x298 - 0x29f */ {D_CBW ,0 ,0 ,0 },{D_CDQ ,0 ,0 ,0 }, -{L_Ifd ,O_CALL_F ,S_CSIP ,0 },{L_ERROR ,0 ,0 ,0 }, +{L_Ifd ,O_CALLFd ,0 ,0 },{L_ERROR ,0 ,0 ,0 }, {L_FLG ,0 ,S_PUSHd,0 },{L_POPd ,0 ,S_FLGd ,0 }, {L_REGb ,0 ,S_FLGb ,REGI_AH},{L_FLG ,0 ,S_REGb ,REGI_AH}, @@ -500,9 +499,9 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,0 ,S_Eb ,M_Ib },{L_MODRM ,0 ,S_Ed ,M_Id }, /* 0x2c8 - 0x2cf */ {D_ENTERd ,0 ,0 ,0 },{D_LEAVEd ,0 ,0 ,0 }, -{L_POPfd ,0 ,S_CSIPIw,0 },{L_POPfd ,0 ,S_CSIP ,0 }, +{D_RETFdIw ,0 ,0 ,0 },{D_RETFd ,0 ,0 ,0 }, {L_VAL ,O_INT ,0 ,3 },{L_Ib ,O_INT ,0 ,0 }, -{L_INTO ,O_INT ,0 ,0 },{L_IRETd ,0 ,S_CSIP ,0 }, +{L_INTO ,O_INT ,0 ,0 },{D_IRETd ,0 ,0 ,0 }, /* 0x2d0 - 0x2d7 */ {L_MODRM ,5 ,0 ,M_GRP_1 },{L_MODRM ,7 ,0 ,M_GRP_1 }, @@ -516,13 +515,13 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,0 ,0 ,0 },{L_MODRM ,0 ,0 ,0 }, /* 0x2e0 - 0x2e7 */ -{L_Ibx ,O_LOOPNZ ,S_ADDIP,0 },{L_Ibx ,O_LOOPZ ,S_ADDIP,0 }, -{L_Ibx ,O_LOOP ,S_ADDIP,0 },{L_Ibx ,O_JCXZ ,S_ADDIP,0 }, +{L_Ibx ,O_LOOPNZ ,S_AIPd ,0 },{L_Ibx ,O_LOOPZ ,S_AIPd ,0 }, +{L_Ibx ,O_LOOP ,S_AIPd ,0 },{L_Ibx ,O_JCXZ ,S_AIPd ,0 }, {L_Ib ,O_INb ,0 ,0 },{L_Ib ,O_INd ,0 ,0 }, {L_Ib ,O_OUTb ,0 ,0 },{L_Ib ,O_OUTd ,0 ,0 }, /* 0x2e8 - 0x2ef */ -{L_Id ,O_CALL_N ,S_ADDIP,0 },{L_Idx ,0 ,S_ADDIP,0 }, -{L_Ifd ,0 ,S_CSIP ,0 },{L_Ibx ,0 ,S_ADDIP,0 }, +{L_Id ,O_CALLNd ,S_AIPd ,0 },{L_Idx ,0 ,S_AIPd ,0 }, +{L_Ifd ,O_JMPFd ,0 ,0 },{L_Ibx ,0 ,S_AIPd ,0 }, {L_REGw ,O_INb ,0 ,REGI_DX},{L_REGw ,O_INd ,0 ,REGI_DX}, {L_REGw ,O_OUTb ,0 ,REGI_DX},{L_REGw ,O_OUTd ,0 ,REGI_DX}, @@ -538,179 +537,179 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,0xb ,0 ,M_GRP },{L_MODRM ,0xd ,0 ,M_GRP }, -/* 0x200 - 0x207 */ +/* 0x300 - 0x307 */ +{L_MODRM ,O_GRP6d ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7d ,0 ,0 }, +{L_MODRM ,O_LAR ,S_Gw ,M_Ew },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x208 - 0x20f */ +/* 0x308 - 0x30f */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x210 - 0x217 */ +/* 0x310 - 0x317 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x218 - 0x21f */ +/* 0x318 - 0x31f */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x220 - 0x227 */ +/* 0x320 - 0x327 */ +{L_MODRM ,O_M_Rd_Cd ,S_Ed ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_M_Cd_Rd ,0 ,M_Ed },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, + +/* 0x328 - 0x32f */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x228 - 0x22f */ +/* 0x330 - 0x337 */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +/* 0x338 - 0x33f */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x230 - 0x237 */ +/* 0x340 - 0x347 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x238 - 0x23f */ +/* 0x348 - 0x34f */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x240 - 0x247 */ +/* 0x350 - 0x357 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x248 - 0x24f */ +/* 0x358 - 0x35f */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x250 - 0x257 */ +/* 0x360 - 0x367 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x258 - 0x25f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x260 - 0x267 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x268 - 0x26f */ +/* 0x368 - 0x36f */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x270 - 0x277 */ +/* 0x370 - 0x377 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x278 - 0x27f */ +/* 0x378 - 0x37f */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x280 - 0x287 */ -{L_Idx ,O_C_O ,S_C_ADDIP,0 },{L_Idx ,O_C_NO ,S_C_ADDIP,0 }, -{L_Idx ,O_C_B ,S_C_ADDIP,0 },{L_Idx ,O_C_NB ,S_C_ADDIP,0 }, -{L_Idx ,O_C_Z ,S_C_ADDIP,0 },{L_Idx ,O_C_NZ ,S_C_ADDIP,0 }, -{L_Idx ,O_C_BE ,S_C_ADDIP,0 },{L_Idx ,O_C_NBE ,S_C_ADDIP,0 }, -/* 0x288 - 0x28f */ -{L_Idx ,O_C_S ,S_C_ADDIP,0 },{L_Idx ,O_C_NS ,S_C_ADDIP,0 }, -{L_Idx ,O_C_P ,S_C_ADDIP,0 },{L_Idx ,O_C_NP ,S_C_ADDIP,0 }, -{L_Idx ,O_C_L ,S_C_ADDIP,0 },{L_Idx ,O_C_NL ,S_C_ADDIP,0 }, -{L_Idx ,O_C_LE ,S_C_ADDIP,0 },{L_Idx ,O_C_NLE ,S_C_ADDIP,0 }, +/* 0x380 - 0x387 */ +{L_Idx ,O_C_O ,S_C_AIPd,0 },{L_Idx ,O_C_NO ,S_C_AIPd,0 }, +{L_Idx ,O_C_B ,S_C_AIPd,0 },{L_Idx ,O_C_NB ,S_C_AIPd,0 }, +{L_Idx ,O_C_Z ,S_C_AIPd,0 },{L_Idx ,O_C_NZ ,S_C_AIPd,0 }, +{L_Idx ,O_C_BE ,S_C_AIPd,0 },{L_Idx ,O_C_NBE ,S_C_AIPd,0 }, +/* 0x388 - 0x38f */ +{L_Idx ,O_C_S ,S_C_AIPd,0 },{L_Idx ,O_C_NS ,S_C_AIPd,0 }, +{L_Idx ,O_C_P ,S_C_AIPd,0 },{L_Idx ,O_C_NP ,S_C_AIPd,0 }, +{L_Idx ,O_C_L ,S_C_AIPd,0 },{L_Idx ,O_C_NL ,S_C_AIPd,0 }, +{L_Idx ,O_C_LE ,S_C_AIPd,0 },{L_Idx ,O_C_NLE ,S_C_AIPd,0 }, -/* 0x290 - 0x297 */ +/* 0x390 - 0x397 */ {L_MODRM ,O_C_O ,S_C_Eb,0 },{L_MODRM ,O_C_NO ,S_C_Eb,0 }, {L_MODRM ,O_C_B ,S_C_Eb,0 },{L_MODRM ,O_C_NB ,S_C_Eb,0 }, {L_MODRM ,O_C_Z ,S_C_Eb,0 },{L_MODRM ,O_C_NZ ,S_C_Eb,0 }, {L_MODRM ,O_C_BE ,S_C_Eb,0 },{L_MODRM ,O_C_NBE ,S_C_Eb,0 }, -/* 0x298 - 0x29f */ +/* 0x398 - 0x39f */ {L_MODRM ,O_C_S ,S_C_Eb,0 },{L_MODRM ,O_C_NS ,S_C_Eb,0 }, {L_MODRM ,O_C_P ,S_C_Eb,0 },{L_MODRM ,O_C_NP ,S_C_Eb,0 }, {L_MODRM ,O_C_L ,S_C_Eb,0 },{L_MODRM ,O_C_NL ,S_C_Eb,0 }, {L_MODRM ,O_C_LE ,S_C_Eb,0 },{L_MODRM ,O_C_NLE ,S_C_Eb,0 }, -/* 0x2a0 - 0x2a7 */ +/* 0x3a0 - 0x3a7 */ {L_SEG ,0 ,S_PUSHd ,fs },{L_POPd ,0 ,S_SEGI ,fs }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{L_MODRM ,O_BTd ,0 ,0 }, {L_MODRM ,O_DSHLd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHLd ,S_Ed ,M_EdGdCL }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x2a8 - 0x2af */ +/* 0x3a8 - 0x3af */ {L_SEG ,0 ,S_PUSHd ,gs },{L_POPd ,0 ,S_SEGI ,gs }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSd ,0 ,0 }, {L_MODRM ,O_DSHRd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHRd ,S_Ed ,M_EdGdCL }, {0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdxGdx }, -/* 0x2b0 - 0x2b7 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +/* 0x3b0 - 0x3b7 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{L_MODRM ,O_BTRd ,0 ,0 }, {L_MODRM ,O_SEGFS ,S_SEGGd,M_Efd },{L_MODRM ,O_SEGGS ,S_SEGGd,M_Efd }, {L_MODRM ,0 ,S_Gd ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ew }, -/* 0x2b8 - 0x2bf */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +/* 0x3b8 - 0x3bf */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,0xf ,0 ,M_GRP },{L_MODRM ,O_BTCd ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {L_MODRM ,0 ,S_Gd ,M_Ebx },{L_MODRM ,0 ,S_Gd ,M_Ewx }, -/* 0x2c0 - 0x2cc */ +/* 0x3c0 - 0x3cc */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x2c8 - 0x2cf */ +/* 0x3c8 - 0x3cf */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x2d0 - 0x2d7 */ +/* 0x3d0 - 0x3d7 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x2d8 - 0x2df */ +/* 0x3d8 - 0x3df */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x2e0 - 0x2ee */ +/* 0x3e0 - 0x3ee */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x2e8 - 0x2ef */ +/* 0x3e8 - 0x3ef */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x2f0 - 0x2fc */ +/* 0x3f0 - 0x3fc */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x2f8 - 0x2ff */ +/* 0x3f8 - 0x3ff */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, @@ -785,16 +784,26 @@ static OpCode Groups[16][8]={ {0 ,0 ,0 ,0 },{0 ,O_CBACK ,0 ,M_Iw }, },{ /* 0x0c Group 5 Ew */ {0 ,t_INCw ,S_Ew ,M_Ew },{0 ,t_DECw ,S_Ew ,M_Ew }, -{0 ,O_CALL_N ,S_IP ,M_Ew },{0 ,O_CALL_F ,S_CSIP ,M_Efw }, -{0 ,0 ,S_IP ,M_Ew },{0 ,0 ,S_CSIP ,M_Efw }, +{0 ,O_CALLNw ,S_IP ,M_Ew },{0 ,O_CALLFw ,0 ,M_Efw }, +{0 ,0 ,S_IP ,M_Ew },{0 ,O_JMPFw ,0 ,M_Efw }, {0 ,0 ,S_PUSHw,M_Ew },{0 ,0 ,0 ,0 }, },{ /* 0x0d Group 5 Ed */ {0 ,t_INCd ,S_Ed ,M_Ed },{0 ,t_DECd ,S_Ed ,M_Ed }, -{0 ,O_CALL_N ,S_IP ,M_Ed },{0 ,O_CALL_F ,S_CSIP ,M_Efd }, -{0 ,0 ,S_IP ,M_Ed },{0 ,0 ,S_CSIP ,M_Efd }, +{0 ,O_CALLNd ,S_IP ,M_Ed },{0 ,O_CALLFd ,0 ,M_Efd }, +{0 ,0 ,S_IP ,M_Ed },{0 ,O_JMPFd ,0 ,M_Efd }, {0 ,0 ,S_PUSHd,M_Ed },{0 ,0 ,0 ,0 }, +},{ /* 0x0e Group 8 Ew */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,O_BTw ,0 ,M_Ib },{0 ,O_BTSw ,0 ,M_Ib }, +{0 ,O_BTRw ,0 ,M_Ib },{0 ,O_BTCw ,0 ,M_Ib }, +},{ /* 0x0f Group 8 Ed */ +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,O_BTd ,0 ,M_Ib },{0 ,O_BTSd ,0 ,M_Ib }, +{0 ,O_BTRd ,0 ,M_Ib },{0 ,O_BTCd ,0 ,M_Ib }, diff --git a/src/cpu/core_full/save.h b/src/cpu/core_full/save.h index a7c4b2b8..fba9ed5f 100644 --- a/src/cpu/core_full/save.h +++ b/src/cpu/core_full/save.h @@ -52,14 +52,14 @@ switch (inst.code.save) { reg_32(inst.code.extra)=inst.op1.d; break; case S_SEGI: - SegSet16(inst.code.extra,inst.op1.w); + CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op1.w); break; case S_SEGm: - SegSet16(inst.rm_index,inst.op1.w); + CPU_SetSegGeneral((SegNames)inst.rm_index,inst.op1.w); break; case S_SEGGw: reg_16(inst.rm_index)=inst.op1.w; - SegSet16(inst.code.extra,inst.op2.w); + CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w); break; case S_PUSHw: Push_16(inst.op1.w); @@ -68,19 +68,19 @@ switch (inst.code.save) { Push_32(inst.op1.d); break; - case S_C_ADDIP: + case S_C_AIPw: if (!inst.cond) goto nextopcode; - case S_ADDIP: + case S_AIPw: SaveIP(); reg_eip+=inst.op1.d; reg_eip&=0xffff; LoadIP(); break; - case S_CSIPIw: - reg_esp+=Fetchw(); - case S_CSIP: - reg_eip=inst.op1.d; - SegSet16(cs,inst.op2.w); + case S_C_AIPd: + if (!inst.cond) goto nextopcode; + case S_AIPd: + SaveIP(); + reg_eip+=inst.op1.d; LoadIP(); break; case S_IPIw: @@ -91,15 +91,13 @@ switch (inst.code.save) { LoadIP(); break; case S_FLGb: - flags.of =get_OF(); - flags.type=t_UNKNOWN; - flags.cf =(inst.op1.d & 0x001)>0;flags.pf =(inst.op1.d & 0x004)>0; - flags.af =(inst.op1.d & 0x010)>0;flags.zf =(inst.op1.d & 0x040)>0; - flags.sf =(inst.op1.d & 0x080)>0; + SETFLAGSb(inst.op1.d); break; case S_FLGw: - case S_FLGd: //TODO Check full 32bit flags one day - Save_Flagsw(inst.op1.w); + SETFLAGSw(inst.op1.d); + break; + case S_FLGd: + SETFLAGSd(inst.op1.d); break; case 0: break; diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index f70a39f4..b1079e85 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -10,8 +10,9 @@ else si_base=SegBase(ds); di_base=SegBase(es); if (inst.prefix & PREFIX_ADDR) { - add_mask=0; - si_index=reg_esi;di_index=reg_edi; + add_mask=0xFFFFFFFF; + si_index=reg_esi; + di_index=reg_edi; count=reg_ecx; } else { add_mask=0xFFFF; @@ -23,7 +24,7 @@ count=1; } - add_index=flags.df ? -1 : 1; + add_index=GETFLAG(DF) ? -1 : 1; if (count) switch (inst.code.op) { case R_OUTSB: for (;count>0;count--) { diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 6df98558..166f90e7 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -25,8 +25,8 @@ enum { L_PREOP,L_PREADD,L_PREREP,L_PREREPNE, L_STRING, - L_IRETw,L_IRETd, /* Direct ones */ + D_IRETw,D_IRETd, D_PUSHAw,D_PUSHAd, D_POPAw,D_POPAd, D_DAA,D_DAS, @@ -39,6 +39,9 @@ enum { D_ENTERw,D_ENTERd, D_LEAVEw,D_LEAVEd, L_ERROR, + + D_RETFw,D_RETFd, + D_RETFwIw,D_RETFdIw, }; @@ -48,12 +51,15 @@ enum { O_XCHG_AX,O_XCHG_EAX, O_IMULRw,O_IMULRd, O_BOUNDw,O_BOUNDd, - O_CALL_N,O_CALL_F, + O_CALLNw,O_CALLNd, + O_CALLFw,O_CALLFd, + O_JMPFw,O_JMPFd, + O_OPAL,O_ALOP, O_OPAX,O_AXOP, O_OPEAX,O_EAXOP, O_INT, - O_SEGDS,O_SEGES,O_SEGFS,O_SEGGS, + O_SEGDS,O_SEGES,O_SEGFS,O_SEGGS,O_SEGSS, O_LOOP,O_LOOPZ,O_LOOPNZ,O_JCXZ, O_INb,O_INw,O_INd, O_OUTb,O_OUTw,O_OUTd, @@ -70,6 +76,18 @@ enum { O_DSHRw,O_DSHRd, O_C_O ,O_C_NO ,O_C_B ,O_C_NB ,O_C_Z ,O_C_NZ ,O_C_BE ,O_C_NBE, O_C_S ,O_C_NS ,O_C_P ,O_C_NP ,O_C_L ,O_C_NL ,O_C_LE ,O_C_NLE, + + O_GRP6w,O_GRP6d, + O_GRP7w,O_GRP7d, + O_M_Cd_Rd,O_M_Rd_Cd, + O_LAR, + + O_BTw,O_BTSw,O_BTRw,O_BTCw, + O_BTd,O_BTSd,O_BTRd,O_BTCd, + O_BSFw,O_BSRw, + + + }; enum { @@ -87,12 +105,11 @@ enum { S_SEGGw,S_SEGGd, - S_ADDIP,S_C_ADDIP, + S_AIPw,S_C_AIPw, + S_AIPd,S_C_AIPd, S_FLGb,S_FLGw,S_FLGd, S_IP,S_IPIw, - S_CSIP,S_CSIPIw, - }; enum { @@ -134,7 +151,7 @@ struct OpCode { static struct { Bitu entry; Bitu entry_default; - Bit8u rm; + Bitu rm; EAPoint rm_eaa; Bitu rm_off; Bitu rm_eai; @@ -150,7 +167,7 @@ static struct { struct { EAPoint base; } seg; - bool cond; + Bitu cond; bool repz; Bitu prefix; } inst; From 69060ae217f446809e826740d9f8868ceae176e8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:38:03 +0000 Subject: [PATCH 0841/4131] Clean up some test code. Changes for new flag handling Changes for protected mode handling. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@921 --- src/debug/debug.cpp | 72 ++++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 3482e12b..1495c013 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -36,9 +36,6 @@ #include "timer.h" #include "../shell/shell_inc.h" -// TEMP -CPUBlock cpu; - #ifdef WIN32 void WIN32_Console(); #else @@ -66,13 +63,13 @@ static struct { static char curSelectorName[3] = { 0,0,0 }; static Segment oldsegs[6]; -static Flag_Info oldflags; +static Bitu oldflags; DBGBlock dbg; static char input_line[256]; static Bitu input_count; Bitu cycle_count; static bool debugging; -static void SetColor(bool test) { +static void SetColor(Bitu test) { if (test) { if (has_colors()) { wattrset(dbg.win_reg,COLOR_PAIR(PAIR_BYELLOW_BLACK));} } else { @@ -109,7 +106,7 @@ Bit32u PhysMakeProt(Bit16u selector, Bit32u offset) Bit32u GetAddress(Bit16u seg, Bit32u offset) { - if (cpu.protmode) return PhysMakeProt(seg,offset); + if (cpu.state & STATE_PROTECTED) return PhysMakeProt(seg,offset); return PhysMake(seg,offset); }; @@ -127,7 +124,7 @@ bool GetDescriptorInfo(char* selname, char* out1, char* out2) // FIXME: Call Gate Descriptors if (cpu.gdt.GetDescriptor(sel,desc)) { sprintf(out1,"%s: b:%08X type:%01X sparg",selname,desc.GetBase(),desc.saved.seg.type); - sprintf(out2," l:%08X dpl :%01X %1X%1X%1X%1X%1X",desc.GetLimit(),desc.saved.seg.dpl,desc.saved.seg.s,desc.saved.seg.p,desc.saved.seg.avl,desc.saved.seg.r,desc.saved.seg.g); + sprintf(out2," l:%08X dpl :%01X %1X%1X%1X%1X",desc.GetLimit(),desc.saved.seg.dpl,desc.saved.seg.p,desc.saved.seg.avl,desc.saved.seg.r,desc.saved.seg.g); return true; } out1[0] = out2[0] = 0; @@ -510,7 +507,7 @@ static bool StepOver() { PhysPt start=SegPhys(cs)+reg_eip; char dline[200];Bitu size; - size=DasmI386(dline, start, reg_eip, false); + size=DasmI386(dline, start, reg_eip, (cpu.state & STATE_USE32>0)); if (strstr(dline,"call") || strstr(dline,"int") || strstr(dline,"loop") || strstr(dline,"rep")) { CBreakpoint::AddBreakpoint (SegValue(cs),reg_eip+size, true); @@ -577,19 +574,34 @@ static void DrawRegisters(void) { SetColor(SegValue(cs)!=oldsegs[cs].val);oldsegs[cs].val=SegValue(cs);mvwprintw (dbg.win_reg,1,31,"%04X",SegValue(cs)); /*Individual flags*/ - flags.cf=get_CF();SetColor(flags.cf!=oldflags.cf);oldflags.cf=flags.cf;mvwprintw (dbg.win_reg,1,53,"%01X",flags.cf); - flags.zf=get_ZF();SetColor(flags.zf!=oldflags.zf);oldflags.zf=flags.zf;mvwprintw (dbg.win_reg,1,56,"%01X",flags.zf); - flags.sf=get_SF();SetColor(flags.sf!=oldflags.sf);oldflags.sf=flags.sf;mvwprintw (dbg.win_reg,1,59,"%01X",flags.sf); - flags.of=get_OF();SetColor(flags.of!=oldflags.of);oldflags.of=flags.of;mvwprintw (dbg.win_reg,1,62,"%01X",flags.of); - flags.af=get_AF();SetColor(flags.af!=oldflags.af);oldflags.af=flags.af;mvwprintw (dbg.win_reg,1,65,"%01X",flags.af); - flags.pf=get_PF();SetColor(flags.pf!=oldflags.pf);oldflags.pf=flags.pf;mvwprintw (dbg.win_reg,1,68,"%01X",flags.pf); - SetColor(flags.df!=oldflags.df);oldflags.df=flags.df;mvwprintw (dbg.win_reg,1,71,"%01X",flags.df); - SetColor(flags.intf!=oldflags.intf);oldflags.intf=flags.intf;mvwprintw (dbg.win_reg,1,74,"%01X",flags.intf); - SetColor(flags.tf!=oldflags.tf);oldflags.tf=flags.tf;mvwprintw (dbg.win_reg,1,77,"%01X",flags.tf); + FILLFLAGS; + + SetColor((flags.word ^ oldflags)&FLAG_CF); + mvwprintw (dbg.win_reg,1,53,"%01X",GETFLAG(CF) ? 1:0); + SetColor((flags.word ^ oldflags)&FLAG_ZF); + mvwprintw (dbg.win_reg,1,56,"%01X",GETFLAG(ZF) ? 1:0); + SetColor((flags.word ^ oldflags)&FLAG_SF); + mvwprintw (dbg.win_reg,1,59,"%01X",GETFLAG(SF) ? 1:0); + SetColor((flags.word ^ oldflags)&FLAG_OF); + mvwprintw (dbg.win_reg,1,62,"%01X",GETFLAG(OF) ? 1:0); + SetColor((flags.word ^ oldflags)&FLAG_AF); + mvwprintw (dbg.win_reg,1,65,"%01X",GETFLAG(AF) ? 1:0); + SetColor((flags.word ^ oldflags)&FLAG_PF); + mvwprintw (dbg.win_reg,1,68,"%01X",GETFLAG(PF) ? 1:0); + + + SetColor((flags.word ^ oldflags)&FLAG_DF); + mvwprintw (dbg.win_reg,1,71,"%01X",GETFLAG(DF) ? 1:0); + SetColor((flags.word ^ oldflags)&FLAG_IF); + mvwprintw (dbg.win_reg,1,74,"%01X",GETFLAG(IF) ? 1:0); + SetColor((flags.word ^ oldflags)&FLAG_TF); + mvwprintw (dbg.win_reg,1,77,"%01X",GETFLAG(TF) ? 1:0); + + oldflags=flags.word; // Selector info, if available - if (cpu.protmode && curSelectorName[0]) { + if ((cpu.state & STATE_PROTECTED) && curSelectorName[0]) { char out1[200], out2[200]; GetDescriptorInfo(curSelectorName,out1,out2); mvwprintw(dbg.win_reg,2,28,out1); @@ -631,8 +643,9 @@ static void DrawCode(void) } } + + Bitu drawsize=size=DasmI386(dline, start, disEIP, (cpu.state & STATE_USE32)>0); bool toolarge = false; - Bitu drawsize = size = DasmI386(dline, start, disEIP, false); mvwprintw(dbg.win_code,i,0,"%04X:%04X ",codeViewData.useCS,disEIP); if (drawsize>10) { toolarge = true; drawsize = 9; }; @@ -760,13 +773,13 @@ bool ChangeRegister(char* str) if (strstr(hex,"EBP")==hex) { hex+=3; reg_ebp = GetHexValue(hex,hex); } else if (strstr(hex,"ESP")==hex) { hex+=3; reg_esp = GetHexValue(hex,hex); } else if (strstr(hex,"EIP")==hex) { hex+=3; reg_eip = GetHexValue(hex,hex); } else - if (strstr(hex,"AF")==hex) { hex+=2; flags.af = (GetHexValue(hex,hex)!=0); } else - if (strstr(hex,"CF")==hex) { hex+=2; flags.cf = (GetHexValue(hex,hex)!=0); } else - if (strstr(hex,"DF")==hex) { hex+=2; flags.df = (GetHexValue(hex,hex)!=0); } else - if (strstr(hex,"IF")==hex) { hex+=2; flags.intf = (GetHexValue(hex,hex)!=0); } else - if (strstr(hex,"OF")==hex) { hex+=3; flags.of = (GetHexValue(hex,hex)!=0); } else - if (strstr(hex,"ZF")==hex) { hex+=3; flags.zf = (GetHexValue(hex,hex)!=0); } else - if (strstr(hex,"PF")==hex) { hex+=3; flags.pf = (GetHexValue(hex,hex)!=0); } else + if (strstr(hex,"AF")==hex) { hex+=2; SETFLAGBIT(AF,GetHexValue(hex,hex)); } else + if (strstr(hex,"CF")==hex) { hex+=2; SETFLAGBIT(CF,GetHexValue(hex,hex)); } else + if (strstr(hex,"DF")==hex) { hex+=2; SETFLAGBIT(PF,GetHexValue(hex,hex)); } else + if (strstr(hex,"IF")==hex) { hex+=2; SETFLAGBIT(IF,GetHexValue(hex,hex)); } else + if (strstr(hex,"OF")==hex) { hex+=3; SETFLAGBIT(OF,GetHexValue(hex,hex)); } else + if (strstr(hex,"ZF")==hex) { hex+=3; SETFLAGBIT(ZF,GetHexValue(hex,hex)); } else + if (strstr(hex,"PF")==hex) { hex+=3; SETFLAGBIT(PF,GetHexValue(hex,hex)); } else { return false; }; return true; }; @@ -1073,7 +1086,7 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) static char outmask[] = "%s:[%04X]=%02X"; - if (cpu.protmode) outmask[6] = '8'; + if (cpu.state & STATE_PROTECTED) outmask[6] = '8'; switch (DasmLastOperandSize()) { case 8 : { Bit8u val = mem_readb(address); @@ -1104,7 +1117,7 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) }; }; // show descriptor info, if available - if (cpu.protmode && saveSelector) { + if ((cpu.state & STATE_PROTECTED) && saveSelector) { strcpy(curSelectorName,prefix); }; }; @@ -1441,9 +1454,6 @@ void DEBUG_Init(Section* sec) { PROGRAMS_MakeFile("DEBUG.COM",DEBUG_ProgramStart); /* shutdown function */ sec->AddDestroyFunction(&DEBUG_ShutDown); - - // TEMP - cpu.protmode = 0; } // DEBUGGING VAR STUFF From bc209bd1b8dec7454588c9ff4b1fb51bf0af26ed Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:39:10 +0000 Subject: [PATCH 0842/4131] Removed fatal exit for VCPI functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@922 --- src/ints/ems.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 78ba1777..cb6621b3 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -669,8 +669,7 @@ static Bitu INT67_Handler(void) { reg_ah = EMM_NO_ERROR; break; case 0xDE: /* VCPI Functions */ - errorlevel=1; - E_Exit("Protected mode not supported"); + LOG(LOG_ERROR|LOG_MISC,"EMS:VCPI Call %2X not supported",reg_al); reg_ah=EMM_FUNC_NOSUP; break; default: From 5e688529f26b5492b9d33365999eb2a08e66f4b3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:46:50 +0000 Subject: [PATCH 0843/4131] Added dpmi.cpp to makefiles and project. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@923 --- src/ints/Makefile.am | 3 +-- src/platform/visualc/config.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ints/Makefile.am b/src/ints/Makefile.am index 3a677e22..4a35bac5 100644 --- a/src/ints/Makefile.am +++ b/src/ints/Makefile.am @@ -1,7 +1,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libints.a -EXTRA_DIST = xms.h -libints_a_SOURCES = mouse.cpp xms.cpp ems.cpp \ +libints_a_SOURCES = mouse.cpp xms.cpp xms.h ems.cpp dpmi.cpp \ int10.cpp int10.h int10_char.cpp int10_memory.cpp int10_misc.cpp int10_modes.cpp int10_pal.cpp int10_put_pixel.cpp \ bios.cpp bios_disk.cpp bios_keyboard.cpp diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 811ebc70..ca9fb168 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -3,7 +3,7 @@ #define VERSION "0.58" /* Define to 1 to enable internal debugger, requires libcurses */ -#define C_DEBUG 0 +#define C_DEBUG 1 /* Define to 1 to enable screenshots, requires libpng */ #define C_SSHOT 1 From 24e396fc0c131cc2602e97d84eee1fcb86be3178 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 18:47:57 +0000 Subject: [PATCH 0844/4131] Added dpmi.cpp to project file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@924 --- visualc/dosbox.dsp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index 58c2e78a..a901901d 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -546,6 +546,10 @@ SOURCE=..\src\ints\bios_keyboard.cpp # End Source File # Begin Source File +SOURCE=..\src\ints\dpmi.cpp +# End Source File +# Begin Source File + SOURCE=..\src\ints\ems.cpp # End Source File # Begin Source File From 192a32e3b263c30ea2a0359ea1091e531961d36b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 20:26:52 +0000 Subject: [PATCH 0845/4131] Updated PIC Controller handling. New flag support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@925 --- src/hardware/pic.cpp | 306 +++++++++++++++---------------------------- 1 file changed, 104 insertions(+), 202 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 98ec2f3d..814d3bfe 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -28,31 +28,36 @@ struct IRQ_Block { bool masked; bool active; bool inservice; - Bit8u vector; + Bitu vector; char * name; PIC_EOIHandler * handler; }; -Bitu PIC_Ticks=0; +struct PIC_Controller { + Bitu icw_words; + Bitu icw_index; + Bitu masked; + Bitu active; + Bitu inservice; + bool auto_eoi; + bool request_issr; + Bit8u vector_base; +}; + +Bitu PIC_Ticks=0; Bitu PIC_IRQCheck; Bitu PIC_IRQActive; + static IRQ_Block irqs[16]; -static Bit8u pic0_icws=0; -static Bit8u pic1_icws=0; -static Bit8u pic0_icw_state=0; -static Bit8u pic1_icw_state=0; -static bool pic0_request_iisr=0; -static bool pic1_request_iisr=0; +static PIC_Controller pics[2]; + enum QUEUE_TYPE { IRQ,EVENT }; - - - struct PICEntry { QUEUE_TYPE type; Bitu irq; @@ -61,240 +66,125 @@ struct PICEntry { PICEntry * next; }; - static struct { PICEntry entries[PIC_QUEUESIZE]; PICEntry * free_entry; PICEntry * next_entry; } pic; -static void write_p20(Bit32u port,Bit8u val) { +static void write_command(Bit32u port,Bit8u val) { + PIC_Controller * pic=&pics[port==0x20 ? 0 : 1]; + Bitu irq_base=port==0x20 ? 0 : 8; switch (val) { case 0x0A: /* select read interrupt request register */ - pic0_request_iisr=false; + pic->request_issr=false; break; case 0x0B: /* select read interrupt in-service register */ - pic0_request_iisr=true; + pic->request_issr=true; break; case 0x10: /* ICW1 */ - pic0_icws=2; - pic0_icw_state=1; + pic->icw_index=1; + pic->icw_words=2; break; case 0x11: /* ICW1 + need for ICW4 */ - pic0_icws=3; - pic0_icw_state=1; + pic->icw_index=1; + pic->icw_words=3; break; - case 0x20: /* end of interrupt command */ - case 0x21: /* end of interrupt command */ - case 0x22: /* end of interrupt command */ - case 0x23: /* end of interrupt command */ - case 0x24: /* end of interrupt command */ - case 0x25: /* end of interrupt command */ - case 0x26: /* end of interrupt command */ - case 0x27: /* end of interrupt command */ - /* clear highest current in service bit */ - if (PIC_IRQActive<8) { + case 0x20:case 0x21:case 0x22:case 0x23:case 0x24:case 0x25:case 0x26:case 0x27: + if (PIC_IRQActive<(irq_base+8)) { irqs[PIC_IRQActive].inservice=false; if (irqs[PIC_IRQActive].handler!=0) irqs[PIC_IRQActive].handler(); PIC_IRQActive=PIC_NOIRQ; - } + }//TODO Warnings? break; - case 0x60: /* specific EOI 0 */ - case 0x61: /* specific EOI 1 */ - case 0x62: /* specific EOI 2 */ - case 0x63: /* specific EOI 3 */ - case 0x64: /* specific EOI 4 */ - case 0x65: /* specific EOI 5 */ - case 0x66: /* specific EOI 6 */ - case 0x67: /* specific EOI 7 */ - if (PIC_IRQActive==(val-0x60U)) { + case 0x60:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:case 0x67: + /* Spefific EOI 0-7 */ + if (PIC_IRQActive==(irq_base+val-0x60U)) { irqs[PIC_IRQActive].inservice=false; if (irqs[PIC_IRQActive].handler!=0) irqs[PIC_IRQActive].handler(); PIC_IRQActive=PIC_NOIRQ; - } + }//TODO Warnings? break; - // IRQ lowest priority commands - case 0xC0: // 0 7 6 5 4 3 2 1 - case 0xC1: // 1 0 7 6 5 4 3 2 - case 0xC2: // 2 1 0 7 6 5 4 3 - case 0xC3: // 3 2 1 0 7 6 5 4 - case 0xC4: // 4 3 2 1 0 7 6 5 - case 0xC5: // 5 4 3 2 1 0 7 6 - case 0xC6: // 6 5 4 3 2 1 0 7 - case 0xC7: // 7 6 5 4 3 2 1 0 - // ignore for now TODO + case 0xC0:case 0xC1:case 0xC2:case 0xC3:case 0xC4:case 0xC5:case 0xC6:case 0xC7: + /* Priority order, no need for it */ break; default: - E_Exit("PIC0:Unhandled command %02X",val); + E_Exit("PIC:Unhandled command %02X",val); } } -//Pic 0 Interrupt mask -static void write_p21(Bit32u port,Bit8u val) { - Bit8u i; - switch(pic0_icw_state) { +static void write_data(Bit32u port,Bit8u val) { + PIC_Controller * pic=&pics[port==0x21 ? 0 : 1]; + Bitu irq_base=(port==0x21) ? 0 : 8; + Bitu i; + switch(pic->icw_index) { case 0: /* mask register */ for (i=0;i<=7;i++) { - irqs[i].masked=(val&(1<0; - if (irqs[i].active && !irqs[i].masked) PIC_IRQCheck|=(1 << 1); - else PIC_IRQCheck&=~(1 << i); + irqs[i+irq_base].masked=(val&(1<0; + if (irqs[i+irq_base].active && !irqs[i+irq_base].masked) PIC_IRQCheck|=(1 << (i+irq_base)); + else PIC_IRQCheck&=~(1 << (i+irq_base)); }; break; case 1: /* icw2 */ - LOG(LOG_PIC,"PIC0:Base vector %X",val); + LOG(LOG_PIC,"%d:Base vector %X",port==0x21 ? 0 : 1,val); for (i=0;i<=7;i++) { - irqs[i].vector=(val&0xf8)+i; + irqs[i+irq_base].vector=(val&0xf8)+i; }; - default: /* icw2, 3, and 4*/ - if(pic0_icw_state++ >= pic0_icws) pic0_icw_state=0; + if(pic->icw_index++ >= pic->icw_words) pic->icw_index=0; + break; + case 2: /* icw 3 */ + LOG(LOG_PIC,"%d:ICW 3 %X",port==0x21 ? 0 : 1,val); + if(pic->icw_index++ >= pic->icw_words) pic->icw_index=0; + break; + case 3: /* icw 4 */ + /* + 0 1 8086/8080 0 mcs-8085 mode + 1 1 Auto EOI 1 Normal EOI + 2-3 0x Non buffer Mode + 10 Buffer Mode Slave + 11 Buffer mode Master + 4 Special/Not Special nested mode + */ + pic->auto_eoi=(val & 0x2)>0; + + LOG(LOG_PIC,"%d:ICW 4 %X",port==0x21 ? 0 : 1,val); + if(pic->icw_index++ >= pic->icw_words) pic->icw_index=0; + break; + default: /* icw 3, and 4*/ + LOG(LOG_PIC,"ICW HUH? %X",val); } } -static Bit8u read_p20(Bit32u port) { - Bit8u ret=0; - Bit32u i; - Bit8u b=1; - if (pic0_request_iisr) { - for (i=0;i<=7;i++) { + +static Bit8u read_command(Bit32u port) { + PIC_Controller * pic=&pics[port==0x20 ? 0 : 1]; + Bitu irq_base=(port==0x20) ? 0 : 8; + Bitu i;Bit8u ret=0;Bit8u b=1; + if (pic->request_issr) { + for (i=irq_base;i7 && PIC_IRQActive <16) { - irqs[PIC_IRQActive].inservice=false; - if (irqs[PIC_IRQActive].handler!=0) irqs[PIC_IRQActive].handler(); - PIC_IRQActive=PIC_NOIRQ; - } - break; - case 0x60: /* specific EOI 0 */ - case 0x61: /* specific EOI 1 */ - case 0x62: /* specific EOI 2 */ - case 0x63: /* specific EOI 3 */ - case 0x64: /* specific EOI 4 */ - case 0x65: /* specific EOI 5 */ - case 0x66: /* specific EOI 6 */ - case 0x67: /* specific EOI 7 */ - if (PIC_IRQActive==(8+val-0x60U)) { - irqs[PIC_IRQActive].inservice=false; - if (irqs[PIC_IRQActive].handler!=0) irqs[PIC_IRQActive].handler(); - PIC_IRQActive=PIC_NOIRQ; - }; - break; - // IRQ lowest priority commands - case 0xC0: // 0 7 6 5 4 3 2 1 - case 0xC1: // 1 0 7 6 5 4 3 2 - case 0xC2: // 2 1 0 7 6 5 4 3 - case 0xC3: // 3 2 1 0 7 6 5 4 - case 0xC4: // 4 3 2 1 0 7 6 5 - case 0xC5: // 5 4 3 2 1 0 7 6 - case 0xC6: // 6 5 4 3 2 1 0 7 - case 0xC7: // 7 6 5 4 3 2 1 0 - //TODO Maybe does it even matter? - break; - default: - E_Exit("Unhandled command %04X sent to port A0",val); - } -} - - -static void write_pa1(Bit32u port,Bit8u val) { - Bit8u i; - switch(pic1_icw_state) { - case 0: /* mask register */ - for (i=0;i<=7;i++) { - irqs[i+8].masked=(val&1 <0; - }; - break; - case 1: /* icw2 */ - for (i=0;i<=7;i++) { - irqs[i+8].vector=(val&0xf8)+i; - }; - default: /* icw2, 3, and 4*/ - if(pic1_icw_state++ >= pic1_icws) pic1_icw_state=0; - } -} - -static Bit8u read_pa0(Bit32u port) { - Bit8u ret=0; - Bit32u i; - Bit8u b=1; - if (pic1_request_iisr) { - for (i=0;i<=7;i++) { - if (irqs[i+8].inservice) ret|=b; - b <<= 1; - } - } else { - for (i=0;i<=7;i++) { - if (irqs[i+8].active) ret|=b; - b <<= 1; - } - } - return ret; -} - - -static Bit8u read_pa1(Bit32u port) { - Bit8u ret=0; - Bit32u i; - Bit8u b=1; - for (i=0;i<=7;i++) { - if (irqs[i+8].masked) ret|=b; - b <<= 1; - } - return ret; -} - void PIC_RegisterIRQ(Bit32u irq,PIC_EOIHandler handler,char * name) { if (irq>15) E_Exit("PIC:Illegal IRQ"); irqs[irq].name=name; @@ -328,17 +218,19 @@ void PIC_DeActivateIRQ(Bit32u irq) { void PIC_runIRQs(void) { Bitu i; - if (!flags.intf) return; + if (!GETFLAG(IF)) return; if (PIC_IRQActive!=PIC_NOIRQ) return; if (!PIC_IRQCheck) return; for (i=0;i<=15;i++) { if (i!=2) { if (!irqs[i].masked && irqs[i].active) { - irqs[i].inservice=true; irqs[i].active=false; PIC_IRQCheck&=~(1 << i); Interrupt(irqs[i].vector); - PIC_IRQActive=i; + if (!pics[0].auto_eoi) { + PIC_IRQActive=i; + irqs[i].inservice=true; + } return; } } @@ -498,6 +390,16 @@ void PIC_Init(Section* sec) { PIC_IRQActive=PIC_NOIRQ; PIC_Ticks=0; Bitu i; + for (i=0;i<2;i++) { + pics[i].masked=0xff; + pics[i].active=0; + pics[i].inservice=0; + pics[i].auto_eoi=false; + pics[i].auto_eoi=false; + pics[i].request_issr=false; + pics[i].icw_index=0; + pics[i].icw_words=0; + } for (i=0;i<=7;i++) { irqs[i].active=false; irqs[i].masked=true; @@ -511,14 +413,14 @@ void PIC_Init(Section* sec) { irqs[0].masked=false; /* Enable system timer */ irqs[1].masked=false; /* Enable Keyboard IRQ */ irqs[12].masked=false; /* Enable Mouse IRQ */ - IO_RegisterReadHandler(0x20,read_p20,"Master PIC Command"); - IO_RegisterReadHandler(0x21,read_p21,"Master PIC Data"); - IO_RegisterWriteHandler(0x20,write_p20,"Master PIC Command"); - IO_RegisterWriteHandler(0x21,write_p21,"Master PIC Data"); - IO_RegisterReadHandler(0xa0,read_pa0,"Slave PIC Command"); - IO_RegisterReadHandler(0xa1,read_pa1,"Slave PIC Data"); - IO_RegisterWriteHandler(0xa0,write_pa0,"Slave PIC Command"); - IO_RegisterWriteHandler(0xa1,write_pa1,"Slave PIC Data"); + IO_RegisterReadHandler(0x20,read_command,"Master PIC Command"); + IO_RegisterReadHandler(0x21,read_data,"Master PIC Data"); + IO_RegisterWriteHandler(0x20,write_command,"Master PIC Command"); + IO_RegisterWriteHandler(0x21,write_data,"Master PIC Data"); + IO_RegisterReadHandler(0xa0,read_command,"Slave PIC Command"); + IO_RegisterReadHandler(0xa1,read_data,"Slave PIC Data"); + IO_RegisterWriteHandler(0xa0,write_command,"Slave PIC Command"); + IO_RegisterWriteHandler(0xa1,write_data,"Slave PIC Data"); /* Initialize the pic queue */ for (i=0;i Date: Sun, 13 Apr 2003 20:28:47 +0000 Subject: [PATCH 0846/4131] New Flag handling Starting programs from shell shouldn't require saving CS:IP Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@926 --- src/shell/shell_misc.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 2712a5fb..9152bc4c 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -19,7 +19,7 @@ #include #include #include "shell_inc.h" -#include "cpu.h" +#include "regs.h" void DOS_Shell::ShowPrompt(void) { @@ -174,12 +174,14 @@ void DOS_Shell::Execute(char * name,char * args) { /* Set the command line in the block and save it */ block.exec.cmdtail=RealMakeSeg(ss,reg_sp+0x100); block.SaveData(); +#if 0 /* Save CS:IP to some point where i can return them from */ Bit32u oldeip=reg_eip; Bit16u oldcs=SegValue(cs); RealPt newcsip=CALLBACK_RealPointer(call_shellstop); SegSet16(cs,RealSeg(newcsip)); reg_ip=RealOff(newcsip); +#endif /* Start up a dos execute interrupt */ reg_ax=0x4b00; //Filename pointer @@ -188,12 +190,14 @@ void DOS_Shell::Execute(char * name,char * args) { //Paramblock SegSet16(es,SegValue(ss)); reg_bx=reg_sp; - flags.intf=false; + SETFLAGBIT(IF,false); CALLBACK_RunRealInt(0x21); /* Restore CS:IP and the stack */ reg_sp+=0x200; +#if 0 reg_eip=oldeip; SegSet16(cs,oldcs); +#endif } } From 4f9387f1ce8928ef2683995a4bc64d99799ffdbf Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Apr 2003 22:32:32 +0000 Subject: [PATCH 0847/4131] Removed start.h and stop.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@927 --- src/cpu/core_16/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_16/Makefile.am b/src/cpu/core_16/Makefile.am index 27aa2848..2971ca9c 100644 --- a/src/cpu/core_16/Makefile.am +++ b/src/cpu/core_16/Makefile.am @@ -1,3 +1,3 @@ -noinst_HEADERS = helpers.h main.h prefix_66.h prefix_of.h start.h stop.h support.h table_ea.h \ +noinst_HEADERS = helpers.h main.h prefix_66.h prefix_of.h support.h table_ea.h \ prefix_66_of.h From 7b45220ec3e9b0ab3a9b9897099443da147de6ce Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 14 Apr 2003 10:43:56 +0000 Subject: [PATCH 0848/4131] fixed breakpoint handling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@928 --- src/cpu/core_full/op.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 2c2f24bf..5d18605e 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -336,7 +336,7 @@ switch (inst.code.op) { case O_INT: SaveIP(); #if C_DEBUG - if (inst.entry==0xcc) if (DEBUG_Breakpoint()) return 1; + if ((inst.entry==0xcc) && DEBUG_Breakpoint()) return 1; else if (DEBUG_IntBreakpoint(inst.op1.b)) return 1; #endif Interrupt(inst.op1.b); From 65d4bbf28c42cf6eacdef4d4079b5c52b248affb Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 14 Apr 2003 10:44:39 +0000 Subject: [PATCH 0849/4131] Added heavy breakpoint handling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@929 --- src/cpu/core_full.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index ec305518..7b4d9753 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -57,6 +57,10 @@ Bitu Full_DeCode(void) { while (CPU_Cycles>0) { #if C_DEBUG cycle_count++; +#if C_HEAVY_DEBUG + SaveIP(); + if (DEBUG_HeavyIsBreakpoint()) return 1; +#endif #endif CPU_Cycles--; inst.entry=cpu.full.entry; From dd32f041fb680e69e2d02be8b42bf9ff2ed9eafb Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 14 Apr 2003 10:45:23 +0000 Subject: [PATCH 0850/4131] fixed breakpoint handling for protected mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@930 --- src/debug/debug.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 1495c013..0d6d7d4d 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -123,11 +123,14 @@ bool GetDescriptorInfo(char* selname, char* out1, char* out2) if (strstr(selname,"ss") || strstr(selname,"SS")) sel = SegValue(ss); // FIXME: Call Gate Descriptors if (cpu.gdt.GetDescriptor(sel,desc)) { - sprintf(out1,"%s: b:%08X type:%01X sparg",selname,desc.GetBase(),desc.saved.seg.type); - sprintf(out2," l:%08X dpl :%01X %1X%1X%1X%1X",desc.GetLimit(),desc.saved.seg.dpl,desc.saved.seg.p,desc.saved.seg.avl,desc.saved.seg.r,desc.saved.seg.g); + sprintf(out1,"%s: b:%08X type:%02X parbg",selname,desc.GetBase(),desc.saved.seg.type); + sprintf(out2," l:%08X dpl : %01X %1X%1X%1X%1X%1X",desc.GetLimit(),desc.saved.seg.dpl,desc.saved.seg.p,desc.saved.seg.avl,desc.saved.seg.r,desc.saved.seg.big,desc.saved.seg.g); return true; + } else { + strcpy(out1," "); + strcpy(out2," "); } - out1[0] = out2[0] = 0; + //out1[0] = out2[0] = 0; return false; }; @@ -480,11 +483,12 @@ void CBreakpoint::ShowList(void) bool DEBUG_Breakpoint(void) { /* First get the phyiscal address and check for a set Breakpoint */ - PhysPt where=SegPhys(cs)+reg_eip-1; +// PhysPt where=SegPhys(cs)+reg_eip-1; + PhysPt where=GetAddress(SegValue(cs),reg_eip-1); if (!CBreakpoint::CheckBreakpoint(where)) return false; // Found. Breakpoint is valid reg_eip -= 1; - CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,false); // Deactivate all breakpoints + CBreakpoint::ActivateBreakpoints(where,false); // Deactivate all breakpoints exitLoop = true; DEBUG_Enable(); return true; @@ -493,11 +497,12 @@ bool DEBUG_Breakpoint(void) bool DEBUG_IntBreakpoint(Bit8u intNum) { /* First get the phyiscal address and check for a set Breakpoint */ - PhysPt where=SegPhys(cs)+reg_eip-2; +// PhysPt where=SegPhys(cs)+reg_eip-2; + PhysPt where=GetAddress(SegValue(cs),reg_eip-2); if (!CBreakpoint::CheckIntBreakpoint(where,intNum,reg_ah)) return false; // Found. Breakpoint is valid reg_eip -= 2; - CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,false); // Deactivate all breakpoints + CBreakpoint::ActivateBreakpoints(where,false); // Deactivate all breakpoints exitLoop = true; DEBUG_Enable(); return true; @@ -505,13 +510,14 @@ bool DEBUG_IntBreakpoint(Bit8u intNum) static bool StepOver() { - PhysPt start=SegPhys(cs)+reg_eip; +// PhysPt start=SegPhys(cs)+reg_eip; + PhysPt start=GetAddress(SegValue(cs),reg_eip); char dline[200];Bitu size; size=DasmI386(dline, start, reg_eip, (cpu.state & STATE_USE32>0)); if (strstr(dline,"call") || strstr(dline,"int") || strstr(dline,"loop") || strstr(dline,"rep")) { CBreakpoint::AddBreakpoint (SegValue(cs),reg_eip+size, true); - CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip, true); + CBreakpoint::ActivateBreakpoints(start, true); debugging=false; DrawCode(); DOSBOX_SetNormalLoop(); From 43fc38c1dec1f941778dafc79b1e03a6303fdbea Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 14 Apr 2003 11:21:48 +0000 Subject: [PATCH 0851/4131] added CMPSD Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@931 --- src/cpu/core_16/prefix_66.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index 7174ac20..b24339fa 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -326,6 +326,13 @@ switch(Fetchb()) { else { reg_si+=4;reg_di+=4;} } break; + case 0xa7: /* CMPSD */ + { + stringSI;stringDI; CMPD(to,LoadMd(from),LoadMd,0); + if (GETFLAG(DF)) { reg_si-=4;reg_di-=4; } + else { reg_si+=4;reg_di+=4;} + } + break; case 0xa9: /* TEST EAX,Id */ EAXId(TESTD); break; From 99fa64e36c269d10b2f117f24078066429a8ee6f Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 14 Apr 2003 17:03:16 +0000 Subject: [PATCH 0852/4131] fixed bug when allocating xms Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@932 --- src/ints/xms.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index fcfe0f9b..2189903d 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -396,7 +396,7 @@ Bitu XMS_Handler(void) { reg_bl = XMS_QueryFreeMemory(reg_ax,reg_dx); break; case XMS_ALLOCATE_EXTENDED_MEMORY: /* 09 */ - reg_bl = XMS_AllocateMemory(reg_ax,reg_dx); + reg_bl = XMS_AllocateMemory(reg_dx,reg_dx); reg_ax = (reg_bl==0); // set ax to success/failure break; case XMS_FREE_EXTENDED_MEMORY: /* 0a */ From 1ba388b35ca92c6e53ebcadfb7aec4f333a719ed Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 15 Apr 2003 15:59:57 +0000 Subject: [PATCH 0853/4131] Fixes overflow of RCL instructions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@933 --- src/cpu/instructions.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index ed6b9a35..2f45ae43 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -297,7 +297,7 @@ (cf << (flags.var2.b-1)) | \ (flags.var1.b >> (9-flags.var2.b)); \ SETFLAGBIT(CF,((flags.var1.b >> (8-flags.var2.b)) & 1)); \ - SETFLAGBIT(OF,((flags.result.b & 0x80) ^ (cf ? 0x80 : 0)) != 0); \ + SETFLAGBIT(OF,(flags.var1.b ^ flags.result.b) & 0x80); \ save(op1,flags.result.b); \ } @@ -312,7 +312,7 @@ (cf << (flags.var2.b-1)) | \ (flags.var1.w >> (17-flags.var2.b)); \ SETFLAGBIT(CF,((flags.var1.w >> (16-flags.var2.b)) & 1)); \ - SETFLAGBIT(OF,((flags.result.w & 0x8000) ^ (cf ? 0x8000 : 0)) != 0); \ + SETFLAGBIT(OF,(flags.var1.w ^ flags.result.w) & 0x8000); \ save(op1,flags.result.w); \ } @@ -330,8 +330,8 @@ (cf << (flags.var2.b-1)) | \ (flags.var1.d >> (33-flags.var2.b)); \ } \ - SETFLAGBIT(CF,((flags.var1.d >> (32-flags.var2.b)) & 1)); \ - SETFLAGBIT(OF,((flags.result.d & 0x80000000) ^ (cf ? 0x80000000 : 0)) != 0); \ + SETFLAGBIT(CF,((flags.var1.d >> (32-flags.var2.b)) & 1)); \ + SETFLAGBIT(OF,(flags.var1.d ^ flags.result.d) & 0x80000000); \ save(op1,flags.result.d); \ } From 948d4a65af820acf6149794e211ed5cb0ea6138d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 15 Apr 2003 17:49:58 +0000 Subject: [PATCH 0854/4131] Updated echo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@934 --- src/shell/shell_cmds.cpp | 5 +++++ src/shell/shell_inc.h | 1 + src/shell/shell_misc.cpp | 13 +++++++++++++ 3 files changed, 19 insertions(+) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 2b829f8e..f53e56f7 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -31,6 +31,7 @@ static SHELL_Cmd cmd_list[]={ { "DEL", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, { "DELETE", 0, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, { "ECHO", 0, &DOS_Shell::CMD_ECHO, "SHELL_CMD_ECHO_HELP"}, +{ "ECHO.", 1, &DOS_Shell::CMD_EHCODOT, "SHELL_CMD_ECHO_HELP"}, { "EXIT", 0, &DOS_Shell::CMD_EXIT, "SHELL_CMD_EXIT_HELP"}, { "HELP", 0, &DOS_Shell::CMD_HELP, "SHELL_CMD_HELP_HELP"}, { "MD", 0, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP"}, @@ -151,6 +152,10 @@ void DOS_Shell::CMD_ECHO(char * args) { WriteOut("%s\n",args); }; +void DOS_Shell::CMD_EHCODOT(char* args) { + WriteOut("\n"); +} + void DOS_Shell::CMD_EXIT(char * args) { exit=true; }; diff --git a/src/shell/shell_inc.h b/src/shell/shell_inc.h index a3057e31..2896ff92 100644 --- a/src/shell/shell_inc.h +++ b/src/shell/shell_inc.h @@ -81,6 +81,7 @@ public: void CMD_RENAME(char * args); void SyntaxError(void); void CMD_PAUSE(char * args); + void CMD_EHCODOT(char* args); /* The shell's variables */ Bit16u input_handle; BatchFile * bf; diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 9152bc4c..e586caf9 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -102,6 +102,19 @@ void DOS_Shell::InputCommand(char * line) { outc('\n'); size=0; //Kill the while loop break; + case'\t': + { + Bit8u c=' ';Bit16u n=1; + for(Bitu i=0; i !=4 ;i++) + { + line[str_index]=c; + str_len++;//This should depend on insert being active + str_index++; + size--; + DOS_WriteFile(STDOUT,&c,&n); + } + } + break; default: line[str_index]=c; str_len++;//This should depend on insert being active From df814b12ce3ed1e585f61bf5ffa0efa7873fd97e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 16 Apr 2003 08:10:18 +0000 Subject: [PATCH 0855/4131] Fixes to disable a channel once count has reached 0 in single cycle mode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@935 --- src/hardware/dma.cpp | 49 +++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 9f9e61b0..13dd2577 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -53,11 +53,12 @@ struct DMA_CHANNEL { Bit16u base_address; Bit16u base_count; Bit16u current_address; - Bit32u current_count; + Bitu current_count; Bit8u page; bool masked; PhysPt address; bool addr_changed; + bool enabled; DMA_EnableCallBack enable_callback; }; @@ -70,6 +71,8 @@ struct DMA_CONTROLLER { }; static DMA_CONTROLLER dma[2]; +void DMA_TestChannel(DMA_CHANNEL * chan); + static Bit8u read_dma(Bit32u port) { /* only use first dma for now */ DMA_CONTROLLER * cont=&dma[0]; @@ -120,6 +123,7 @@ static void write_dma(Bit32u port,Bit8u val) { } else { chan->base_address=(chan->base_address & 0x00ff) | (val<<8); } +// LOG_MSG("DMA:Address %X",chan->base_address); cont->flipflop=!cont->flipflop; chan->addr_changed=true; break; @@ -130,8 +134,10 @@ static void write_dma(Bit32u port,Bit8u val) { } else { chan->base_count=(chan->base_count & 0x00ff) | (val<<8); } +// LOG_MSG("DMA:count %X",chan->base_count); cont->flipflop=!cont->flipflop; chan->addr_changed=true; + DMA_TestChannel(chan); break; case 0x08: /* Command Register */ if (val != 4) LOG(LOG_ERROR,"DMA1:Illegal command %2X",val); @@ -150,7 +156,7 @@ static void write_dma(Bit32u port,Bit8u val) { case 0x0a: /* single mask bit register */ chan=&cont->chan[val & 0x3]; chan->masked=(val & 4)>0; - if (chan->enable_callback) chan->enable_callback(!chan->masked); + DMA_TestChannel(chan); break; case 0x0b: /* mode register */ chan=&cont->chan[val & 0x3]; @@ -161,7 +167,7 @@ static void write_dma(Bit32u port,Bit8u val) { if (chan->mode.address_decrement) { LOG(LOG_ERROR,"DMA:Address Decrease not supported yet"); } - + DMA_TestChannel(chan); break; case 0x0c: /* Clear Flip/Flip */ cont->flipflop=true; @@ -194,6 +200,7 @@ INLINE void ResetDMA8(DMA_CHANNEL * chan) { chan->address=(chan->page << 16)+chan->base_address; chan->current_count=chan->base_count+1; chan->current_address=chan->base_address; +// LOG_MSG("DMA8:Setup at address %X:%X count %X",chan->page<<12,chan->base_address,chan->current_count); } @@ -217,6 +224,8 @@ Bitu DMA_8_Read(Bitu dmachan,Bit8u * buffer,Bitu count) { count=chan->current_count; chan->current_address+=count;; chan->current_count=0; + if (chan->enable_callback) chan->enable_callback(false); + chan->enabled=false; return count; } else { buffer+=chan->current_count; @@ -269,8 +278,6 @@ Bitu DMA_8_Write(Bitu dmachan,Bit8u * buffer,Bitu count) { } - - Bitu DMA_16_Read(Bitu dmachan,Bit8u * buffer,Bitu count) { return 0; @@ -282,23 +289,37 @@ Bitu DMA_16_Write(Bitu dmachan,Bit8u * buffer,Bitu count) { return 0; } +void DMA_TestChannel(DMA_CHANNEL * chan) { + if (!chan->enable_callback) return; + bool enabled; + if (chan->masked) enabled=false; + else { + if (chan->mode.autoinit_enable) enabled=true; + else if (chan->current_count || chan->addr_changed) enabled=true; + else enabled=false; + } + if (enabled == chan->enabled) return; + chan->enabled=enabled; + chan->enable_callback(enabled); +} void DMA_SetEnableCallBack(Bitu channel,DMA_EnableCallBack callback) { + DMA_CHANNEL * chan; if (channel<4) { - dma[0].chan[channel].enable_callback=callback; - if (callback) callback(!dma[0].chan[channel].masked); - return; - } - if (channel<8) { - dma[1].chan[channel-4].enable_callback=callback; - if (callback) callback(!dma[1].chan[channel-4].masked); - } + chan=&dma[0].chan[channel]; + } else if (channel<8) { + chan=&dma[1].chan[channel-4]; + } else return; + chan->enabled=false; + chan->enable_callback=callback; + DMA_TestChannel(chan); } void DMA_Init(Section* sec) { - for (Bit32u i=0;i<0x10;i++) { + Bitu i; + for (i=0;i<0x10;i++) { IO_RegisterWriteHandler(i,write_dma,"DMA1"); IO_RegisterReadHandler(i,read_dma,"DMA1"); } From 2639d29db8807b2625af497784fbd2188908694b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 16 Apr 2003 16:34:37 +0000 Subject: [PATCH 0856/4131] CPUID Instruction Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@936 --- include/cpu.h | 3 +++ src/cpu/core_full/load.h | 3 +++ src/cpu/core_full/optable.h | 4 ++-- src/cpu/core_full/support.h | 1 + src/cpu/cpu.cpp | 23 +++++++++++++++++++++-- 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 6af03bba..190032b5 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -96,6 +96,9 @@ bool Interrupt(Bitu num); bool CPU_IRET(bool use32); bool CPU_SetSegGeneral(SegNames seg,Bitu value); +void CPU_CPUID(void); + + //Flag Handling Bitu get_CF(void); Bitu get_AF(void); diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index cb2a0347..25ccd258 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -388,6 +388,9 @@ l_M_Ed: case D_AAS: AAS(); goto nextopcode; + case D_CPUID: + CPU_CPUID(); + goto nextopcode; default: LOG(LOG_CPU|LOG_ERROR,"LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry); break; diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index ad76da33..fb5b2877 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -294,7 +294,7 @@ static OpCode OpCodeTable[1024]={ /* 0x1a0 - 0x1a7 */ {L_SEG ,0 ,S_PUSHw ,fs },{L_POPw ,0 ,S_SEGI ,fs }, -{0 ,0 ,0 ,0 },{L_MODRM ,O_BTw ,0 ,0 }, +{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTw ,0 ,0 }, {L_MODRM ,O_DSHLw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHLw ,S_Ew ,M_EwGwCL }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x1a8 - 0x1af */ @@ -651,7 +651,7 @@ static OpCode OpCodeTable[1024]={ /* 0x3a0 - 0x3a7 */ {L_SEG ,0 ,S_PUSHd ,fs },{L_POPd ,0 ,S_SEGI ,fs }, -{0 ,0 ,0 ,0 },{L_MODRM ,O_BTd ,0 ,0 }, +{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTd ,0 ,0 }, {L_MODRM ,O_DSHLd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHLd ,S_Ed ,M_EdGdCL }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x3a8 - 0x3af */ diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 166f90e7..965316ff 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -42,6 +42,7 @@ enum { D_RETFw,D_RETFd, D_RETFwIw,D_RETFdIw, + D_CPUID, }; diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 69595542..19370e42 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -569,11 +569,30 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) { return false; } +void CPU_CPUID(void) { + switch (reg_eax) { + case 0: /* Vendor ID String and maximum level? */ + reg_eax=0; + reg_ebx=('G'<< 24) || ('e' << 16) || ('n' << 8) || 'u'; + reg_edx=('i'<< 24) || ('n' << 16) || ('e' << 8) || 'T'; + reg_ecx=('n'<< 24) || ('t' << 16) || ('e' << 8) || 'l'; + break; + case 1: /* get processor type/family/model/stepping and feature flags */ + reg_eax=0x402; /* intel 486 sx? */ + reg_ebx=0; /* Not Supported */ + reg_ecx=0; /* No features */ + reg_edx=0; /* Nothing either */ + break; + default: + LOG(LOG_CPU|LOG_ERROR,"Unhandled CPUID Function %x",reg_eax); + break; + } + +} + void CPU_Real_16_Slow_Start(void); - void CPU_Core_Full_Start(void); - void SetCPU16bit() { cpu.state=0; From 2abe0736f6798b4ceb1dde7e555df26d70d3c510 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 16 Apr 2003 20:14:35 +0000 Subject: [PATCH 0857/4131] Fixed 32-bit CBW. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@937 --- src/cpu/core_full/load.h | 3 +++ src/cpu/core_full/optable.h | 2 +- src/cpu/core_full/support.h | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 25ccd258..1b33fe4c 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -321,6 +321,9 @@ l_M_Ed: case D_CBW: reg_ax=(Bit8s)reg_al; goto nextopcode; + case D_CWDE: + reg_eax=(Bit16s)reg_ax; + goto nextopcode; case D_CWD: if (reg_ax & 0x8000) reg_dx=0xffff; else reg_dx=0; diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index fb5b2877..011f41ab 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -465,7 +465,7 @@ static OpCode OpCodeTable[1024]={ {L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_SP},{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_BP}, {L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_SI},{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_DI}, /* 0x298 - 0x29f */ -{D_CBW ,0 ,0 ,0 },{D_CDQ ,0 ,0 ,0 }, +{D_CWDE ,0 ,0 ,0 },{D_CDQ ,0 ,0 ,0 }, {L_Ifd ,O_CALLFd ,0 ,0 },{L_ERROR ,0 ,0 ,0 }, {L_FLG ,0 ,S_PUSHd,0 },{L_POPd ,0 ,S_FLGd ,0 }, {L_REGb ,0 ,S_FLGb ,REGI_AH},{L_FLG ,0 ,S_REGb ,REGI_AH}, diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 965316ff..23afd1db 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -31,7 +31,8 @@ enum { D_POPAw,D_POPAd, D_DAA,D_DAS, D_AAA,D_AAS, - D_CBW,D_CWD,D_CDQ, + D_CBW,D_CWDE, + D_CWD,D_CDQ, D_SETALC, D_XLAT, D_CLI,D_STI,D_STC,D_CLC,D_CMC,D_CLD,D_STD, From 53c514eb2ecff4126a824cc9b1763a175307a873 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 17 Apr 2003 18:31:16 +0000 Subject: [PATCH 0858/4131] Fixes to SMSW/LMSW and LAR Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@938 --- src/cpu/core_full/op.h | 17 +++++++---------- src/cpu/core_full/optable.h | 8 ++++---- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 5d18605e..5c5ed872 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -399,7 +399,7 @@ switch (inst.code.op) { CPU_SGDT(limit,base); SaveMw(inst.rm_eaa,limit); SaveMd(inst.rm_eaa+2,base); - break; + goto nextopcode; } case 1: /* SIDT */ { @@ -407,26 +407,23 @@ switch (inst.code.op) { CPU_SIDT(limit,base); SaveMw(inst.rm_eaa,limit); SaveMd(inst.rm_eaa+2,base); - break; + goto nextopcode; } case 2: /* LGDT */ CPU_LGDT(LoadMw(inst.rm_eaa),LoadMd(inst.rm_eaa+2)&((inst.code.op == O_GRP7w) ? 0xFFFFFF : 0xFFFFFFFF)); - break; + goto nextopcode; case 3: /* LIDT */ CPU_LIDT(LoadMw(inst.rm_eaa),LoadMd(inst.rm_eaa+2)&((inst.code.op == O_GRP7w) ? 0xFFFFFF : 0xFFFFFFFF)); - break; + goto nextopcode; case 4: /* SMSW */ { Bitu word;CPU_SMSW(word); - SaveMw(inst.rm_eaa,word); + inst.op1.d=word; break; } case 6: /* LMSW */ - { - Bitu word=LoadMw(inst.rm_eaa); - CPU_LMSW(word); - break; - } + CPU_LMSW(inst.op1.w); + goto nextopcode; default: LOG(LOG_ERROR|LOG_CPU,"Group 7 Illegal subfunction %X",inst.rm_index); } diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 011f41ab..08054c04 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -181,8 +181,8 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,0xb ,0 ,M_GRP },{L_MODRM ,0xc ,0 ,M_GRP }, /* 0x100 - 0x107 */ -{L_MODRM ,O_GRP6w ,0 ,0 },{L_MODRM ,O_GRP7w ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_GRP6w ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7w ,S_Ew ,M_Ew }, +{L_MODRM ,O_LAR ,S_Gw ,M_Ew },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x108 - 0x10f */ @@ -538,8 +538,8 @@ static OpCode OpCodeTable[1024]={ /* 0x300 - 0x307 */ -{L_MODRM ,O_GRP6d ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7d ,0 ,0 }, -{L_MODRM ,O_LAR ,S_Gw ,M_Ew },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_GRP6d ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7d ,S_Ew ,M_Ew }, +{L_MODRM ,O_LAR ,S_Gd ,M_Ed },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x308 - 0x30f */ From 1c1548e598e88b4834f905540326a6be3be8547e Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 18 Apr 2003 08:19:31 +0000 Subject: [PATCH 0859/4131] few bugfixes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@939 --- src/debug/debug.cpp | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 0d6d7d4d..dc670772 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -90,7 +90,8 @@ struct SCodeViewData { } codeViewData; -static Bit16u dataSeg,dataOfs; +static Bit16u dataSeg; +static Bit32u dataOfs; static bool showExtend = true; /***********/ @@ -107,7 +108,7 @@ Bit32u PhysMakeProt(Bit16u selector, Bit32u offset) Bit32u GetAddress(Bit16u seg, Bit32u offset) { if (cpu.state & STATE_PROTECTED) return PhysMakeProt(seg,offset); - return PhysMake(seg,offset); + return (seg<<4)+offset; }; bool GetDescriptorInfo(char* selname, char* out1, char* out2) @@ -541,7 +542,7 @@ bool DEBUG_ExitLoop(void) static void DrawData(void) { - Bit16u add = dataOfs; + Bit32u add = dataOfs; Bit32u address; /* Data win */ for (int y=0; y<8; y++) { @@ -662,7 +663,7 @@ static void DrawCode(void) char* res = 0; if (showExtend) res = AnalyzeInstruction(dline, saveSel); waddstr(dbg.win_code,dline); - for (c=28-strlen(dline);c>0;c--) waddch(dbg.win_code,' '); + if (strlen(dline)<28) for (c=28-strlen(dline);c>0;c--) waddch(dbg.win_code,' '); if (showExtend) { waddstr(dbg.win_code,res); for (c=strlen(res);c<20;c++) waddch(dbg.win_code,' '); @@ -715,6 +716,15 @@ Bit32u GetHexValue(char* str, char*& hex) hex = str; while (*hex==' ') hex++; + if (strstr(hex,"EAX")==hex) { hex+=3; return reg_eax; }; + if (strstr(hex,"EBX")==hex) { hex+=3; return reg_ebx; }; + if (strstr(hex,"ECX")==hex) { hex+=3; return reg_ecx; }; + if (strstr(hex,"EDX")==hex) { hex+=3; return reg_edx; }; + if (strstr(hex,"ESI")==hex) { hex+=3; return reg_esi; }; + if (strstr(hex,"EDI")==hex) { hex+=3; return reg_edi; }; + if (strstr(hex,"EBP")==hex) { hex+=3; return reg_ebp; }; + if (strstr(hex,"ESP")==hex) { hex+=3; return reg_esp; }; + if (strstr(hex,"EIP")==hex) { hex+=3; return reg_eip; }; if (strstr(hex,"AX")==hex) { hex+=2; return reg_ax; }; if (strstr(hex,"BX")==hex) { hex+=2; return reg_bx; }; if (strstr(hex,"CX")==hex) { hex+=2; return reg_cx; }; @@ -730,15 +740,6 @@ Bit32u GetHexValue(char* str, char*& hex) if (strstr(hex,"FS")==hex) { hex+=2; return SegValue(fs); }; if (strstr(hex,"GS")==hex) { hex+=2; return SegValue(gs); }; if (strstr(hex,"SS")==hex) { hex+=2; return SegValue(ss); }; - if (strstr(hex,"EAX")==hex) { hex+=3; return reg_eax; }; - if (strstr(hex,"EBX")==hex) { hex+=3; return reg_ebx; }; - if (strstr(hex,"ECX")==hex) { hex+=3; return reg_ecx; }; - if (strstr(hex,"EDX")==hex) { hex+=3; return reg_edx; }; - if (strstr(hex,"ESI")==hex) { hex+=3; return reg_esi; }; - if (strstr(hex,"EDI")==hex) { hex+=3; return reg_edi; }; - if (strstr(hex,"EBP")==hex) { hex+=3; return reg_ebp; }; - if (strstr(hex,"ESP")==hex) { hex+=3; return reg_esp; }; - if (strstr(hex,"EIP")==hex) { hex+=3; return reg_eip; }; while (*hex) { if ((*hex>='0') && (*hex<='9')) value = (value<<4)+*hex-'0'; else @@ -755,6 +756,15 @@ bool ChangeRegister(char* str) char* hex = str; while (*hex==' ') hex++; + if (strstr(hex,"EAX")==hex) { hex+=3; reg_eax = GetHexValue(hex,hex); } else + if (strstr(hex,"EBX")==hex) { hex+=3; reg_ebx = GetHexValue(hex,hex); } else + if (strstr(hex,"ECX")==hex) { hex+=3; reg_ecx = GetHexValue(hex,hex); } else + if (strstr(hex,"EDX")==hex) { hex+=3; reg_edx = GetHexValue(hex,hex); } else + if (strstr(hex,"ESI")==hex) { hex+=3; reg_esi = GetHexValue(hex,hex); } else + if (strstr(hex,"EDI")==hex) { hex+=3; reg_edi = GetHexValue(hex,hex); } else + if (strstr(hex,"EBP")==hex) { hex+=3; reg_ebp = GetHexValue(hex,hex); } else + if (strstr(hex,"ESP")==hex) { hex+=3; reg_esp = GetHexValue(hex,hex); } else + if (strstr(hex,"EIP")==hex) { hex+=3; reg_eip = GetHexValue(hex,hex); } else if (strstr(hex,"AX")==hex) { hex+=2; reg_ax = GetHexValue(hex,hex); } else if (strstr(hex,"BX")==hex) { hex+=2; reg_bx = GetHexValue(hex,hex); } else if (strstr(hex,"CX")==hex) { hex+=2; reg_cx = GetHexValue(hex,hex); } else @@ -770,15 +780,6 @@ bool ChangeRegister(char* str) if (strstr(hex,"FS")==hex) { hex+=2; SegSet16(fs,GetHexValue(hex,hex)); } else if (strstr(hex,"GS")==hex) { hex+=2; SegSet16(gs,GetHexValue(hex,hex)); } else if (strstr(hex,"SS")==hex) { hex+=2; SegSet16(ss,GetHexValue(hex,hex)); } else - if (strstr(hex,"EAX")==hex) { hex+=3; reg_eax = GetHexValue(hex,hex); } else - if (strstr(hex,"EBX")==hex) { hex+=3; reg_ebx = GetHexValue(hex,hex); } else - if (strstr(hex,"ECX")==hex) { hex+=3; reg_ecx = GetHexValue(hex,hex); } else - if (strstr(hex,"EDX")==hex) { hex+=3; reg_edx = GetHexValue(hex,hex); } else - if (strstr(hex,"ESI")==hex) { hex+=3; reg_esi = GetHexValue(hex,hex); } else - if (strstr(hex,"EDI")==hex) { hex+=3; reg_edi = GetHexValue(hex,hex); } else - if (strstr(hex,"EBP")==hex) { hex+=3; reg_ebp = GetHexValue(hex,hex); } else - if (strstr(hex,"ESP")==hex) { hex+=3; reg_esp = GetHexValue(hex,hex); } else - if (strstr(hex,"EIP")==hex) { hex+=3; reg_eip = GetHexValue(hex,hex); } else if (strstr(hex,"AF")==hex) { hex+=2; SETFLAGBIT(AF,GetHexValue(hex,hex)); } else if (strstr(hex,"CF")==hex) { hex+=2; SETFLAGBIT(CF,GetHexValue(hex,hex)); } else if (strstr(hex,"DF")==hex) { hex+=2; SETFLAGBIT(PF,GetHexValue(hex,hex)); } else From a085299cd3c80cd42c37d2fb829b2dac40761788 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 18 Apr 2003 13:36:55 +0000 Subject: [PATCH 0860/4131] failed allocating xms-call now safer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@940 --- src/ints/xms.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 2189903d..65f23832 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -395,10 +395,12 @@ Bitu XMS_Handler(void) { case XMS_QUERY_FREE_EXTENDED_MEMORY: /* 08 */ reg_bl = XMS_QueryFreeMemory(reg_ax,reg_dx); break; - case XMS_ALLOCATE_EXTENDED_MEMORY: /* 09 */ - reg_bl = XMS_AllocateMemory(reg_dx,reg_dx); + case XMS_ALLOCATE_EXTENDED_MEMORY: { /* 09 */ + Bit16u handle = 0; + reg_bl = XMS_AllocateMemory(reg_dx,handle); + reg_dx = handle; reg_ax = (reg_bl==0); // set ax to success/failure - break; + }; break; case XMS_FREE_EXTENDED_MEMORY: /* 0a */ reg_bl = XMS_FreeMemory(reg_dx); reg_ax = (reg_bl==0); From 38bc54fbd9ae4a4001652b774732c7e55fdeedc5 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 18 Apr 2003 13:37:37 +0000 Subject: [PATCH 0861/4131] added reading of cooked sectors Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@941 --- src/dos/cdrom_aspi_win32.cpp | 30 +++------------------- src/dos/cdrom_ioctl_win32.cpp | 47 +++++++++++++++-------------------- 2 files changed, 23 insertions(+), 54 deletions(-) diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index 33d8c2a2..9a9e69c2 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -675,13 +675,6 @@ bool CDROM_Interface_Aspi::ReadSectors(void* buffer, bool raw, unsigned long sec memset(&s,0,sizeof(s)); - // FIXME : Is there a method to get cooked sectors with aspi ??? - // all combination i tried were failing. - // so we have to allocate extra mem and copy data to buffer if in cooked mode - char* inPtr = (char*)buffer; - if (!raw) inPtr = new char[num*2352]; - if (!inPtr) return false; - s.SRB_Cmd = SC_EXEC_SCSI_CMD; s.SRB_HaId = haId; s.SRB_Target = target; @@ -689,8 +682,8 @@ bool CDROM_Interface_Aspi::ReadSectors(void* buffer, bool raw, unsigned long sec s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; s.SRB_SenseLen = SENSE_LEN; - s.SRB_BufLen = 2352*num; //num*(raw?2352:2048); - s.SRB_BufPointer = (BYTE FAR*)inPtr; + s.SRB_BufLen = raw?2352*num:2048*num; + s.SRB_BufPointer = (BYTE FAR*)buffer; s.SRB_CDBLen = 12; s.SRB_PostProc = (LPVOID)hEvent; @@ -712,24 +705,7 @@ bool CDROM_Interface_Aspi::ReadSectors(void* buffer, bool raw, unsigned long sec CloseHandle(hEvent); - if (s.SRB_Status!=SS_COMP) { - if (!raw) delete[] inPtr; - return false; - } - - if (!raw) { - // copy user data to buffer - char* source = inPtr; - source+=16; // jump 16 bytes - char* outPtr = (char*)buffer; - for (unsigned long i=0; i #include // Ioctl stuff +#include #include "ntddcdrm.h" // Ioctl stuff #include "cdrom.h" @@ -207,35 +208,27 @@ bool CDROM_Interface_Ioctl::LoadUnloadMedia(bool unload) bool CDROM_Interface_Ioctl::ReadSectors(void* buffer, bool raw, unsigned long sector, unsigned long num) { - // TODO : How to copy cooked without current overhead ? - BOOL bStat; - DWORD byteCount; - RAW_READ_INFO in; - char* inPtr; - - in.DiskOffset.LowPart = sector; - in.DiskOffset.HighPart = 0; - in.SectorCount = num; - in.TrackMode = CDDA; - - if (!raw) inPtr = new char[num*RAW_SECTOR_SIZE]; - else inPtr = (char*)buffer; - - bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RAW_READ, &in, sizeof(in), - inPtr, num*RAW_SECTOR_SIZE, &byteCount,NULL); + BOOL bStat; + DWORD byteCount = 0; + Open(); if (!raw) { - char* source = inPtr; - source+=16; // jump 16 bytes - char* outPtr = (char*)buffer; - for (unsigned long i=0; i0); } From 619c351959ec12f2a11dd06d5ac502cb8604d9d1 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 18 Apr 2003 13:38:10 +0000 Subject: [PATCH 0862/4131] added reading of cd table of contents/volume descriptor Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@942 --- src/dos/dos_mscdex.cpp | 74 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 9 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 8c545b9e..a2f96ddf 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -97,10 +97,10 @@ public: int AddDrive (Bit16u _drive, char* physicalPath, Bit8u& subUnit); void GetDrives (PhysPt data); void GetDriverInfo (PhysPt data); - bool GetCopyrightName (Bit16u drive, PhysPt data) { return false; }; - bool GetAbstractName (Bit16u drive, PhysPt data) { return false; }; - bool GetDocumentationName(Bit16u drive, PhysPt data) { return false; }; - bool ReadVTOC (Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error) { return false; }; + bool GetCopyrightName (Bit16u drive, PhysPt data); + bool GetAbstractName (Bit16u drive, PhysPt data); + bool GetDocumentationName(Bit16u drive, PhysPt data); + bool ReadVTOC (Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error); bool ReadSectors (Bit16u drive, Bit32u sector, Bit16u num, PhysPt data); bool ReadSectors (Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data); bool ReadSectorsMSF (Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data); @@ -271,7 +271,9 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) devHeader.SetNumSubUnits(devHeader.GetNumSubUnits()+1); dinfo[numDrives].drive = (Bit8u)_drive; dinfo[numDrives].physDrive = toupper(physicalPath[0]); - numDrives++; + numDrives++; + // stop audio + StopAudio(subUnit); return result; } return 4; @@ -420,6 +422,60 @@ Bit32u CMscdex::GetVolumeSize(Bit8u subUnit) return 0; }; +bool CMscdex::ReadVTOC(Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error) +{ + ReadSectors(GetSubUnit(drive),false,/*150+*/16,1,data) ? error=0:error=MSCDEX_ERROR_DRIVE_NOT_READY; + return (error==0); +}; + +bool CMscdex::GetCopyrightName(Bit16u drive, PhysPt data) +{ + Bit16u error,seg,size = 128; + bool success = false; + if (DOS_AllocateMemory(&seg,&size)) { + PhysPt ptoc = PhysMake(seg,0); + success = ReadVTOC(drive,0x00,ptoc,error); + if (success) { + MEM_BlockCopy(data,ptoc+702,37); + mem_writeb(data+37,0); + }; + DOS_FreeMemory(seg); + } + return success; +}; + +bool CMscdex::GetAbstractName(Bit16u drive, PhysPt data) +{ + Bit16u error,seg,size = 128; + bool success = false; + if (DOS_AllocateMemory(&seg,&size)) { + PhysPt ptoc = PhysMake(seg,0); + success = ReadVTOC(drive,0x00,ptoc,error); + if (success) { + MEM_BlockCopy(data,ptoc+739,37); + mem_writeb(data+37,0); + }; + DOS_FreeMemory(seg); + } + return success; +}; + +bool CMscdex::GetDocumentationName(Bit16u drive, PhysPt data) +{ + Bit16u error,seg,size = 128; + bool success = false; + if (DOS_AllocateMemory(&seg,&size)) { + PhysPt ptoc = PhysMake(seg,0); + success = ReadVTOC(drive,0x00,ptoc,error); + if (success) { + MEM_BlockCopy(data,ptoc+776,37); + mem_writeb(data+37,0); + }; + DOS_FreeMemory(seg); + } + return success; +}; + bool CMscdex::GetUPC(Bit8u subUnit, Bit8u& attr, char* upc) { if (subUnit>=numDrives) return false; @@ -554,7 +610,7 @@ static Bitu MSCDEX_Interrupt_Handler(void) Bit8u subUnit = mem_readb(data+1); Bit8u funcNr = mem_readb(data+2); -// if (funcNr!=0x03) LOG("MSCDEX: Driver Function %02X",funcNr); +// LOG(LOG_ERROR,"MSCDEX: Driver Function %02X",funcNr); switch (funcNr) { @@ -720,7 +776,7 @@ static bool MSCDEX_Handler(void) if (reg_ah!=0x15) return false; PhysPt data = PhysMake(SegValue(es),reg_bx); -// if (reg_ax!=0x1510) LOG("MSCEEX: INT 2F %04X",reg_ax); +// LOG(LOG_ERROR,"MSCDEX: INT 2F %04X",reg_ax); switch (reg_ax) { case 0x1500: /* Install check */ @@ -754,7 +810,7 @@ static bool MSCDEX_Handler(void) CALLBACK_SCF(true); }; return true; -/* case 0x1505: { // read vtoc + case 0x1505: { // read vtoc Bit16u error = 0; if (mscdex->ReadVTOC(reg_cx,reg_dx,data,error)) { CALLBACK_SCF(false); @@ -763,7 +819,7 @@ static bool MSCDEX_Handler(void) CALLBACK_SCF(true); }; }; - return true;*/ + return true; case 0x1508: { // read sectors Bit32u sector = (reg_si<<16)+reg_di; if (mscdex->ReadSectors(reg_cx,sector,reg_dx,data)) { From 74574ecc81eac50794ce0d5318a32513187fd24e Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 19 Apr 2003 11:59:22 +0000 Subject: [PATCH 0863/4131] fixed bug in xms resize mem Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@943 --- src/ints/xms.cpp | 49 ++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 65f23832..0714b209 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -284,30 +284,28 @@ Bitu XMS_ResizeMemory(Bitu handle, Bitu newSize) Bit16u sizeDelta = xms_handles[handle].size - newSize; Bit16u next = xms_handles[handle].next; - if (next=XMS_HANDLES) return XMS_OUT_OF_HANDLES; - xms_handles[newindex].active = true; - xms_handles[newindex].allocated = false; - xms_handles[newindex].locked = 0; - xms_handles[newindex].prev = handle; - xms_handles[newindex].next = next; - xms_handles[newindex].phys = xms_handles[handle].phys+newSize*1024; - xms_handles[newindex].size = sizeDelta; - - xms_handles[handle] .next = newindex; - xms_handles[next] .prev = newindex; + if ((next=XMS_HANDLES) return XMS_OUT_OF_HANDLES; + xms_handles[newindex].active = true; + xms_handles[newindex].allocated = false; + xms_handles[newindex].locked = 0; + xms_handles[newindex].prev = handle; + xms_handles[newindex].next = next; + xms_handles[newindex].phys = xms_handles[handle].phys+newSize*1024; + xms_handles[newindex].size = sizeDelta; + + xms_handles[handle] .next = newindex; + if (next Date: Sat, 19 Apr 2003 15:41:43 +0000 Subject: [PATCH 0864/4131] Allocate all memory in big block at startup. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@944 --- src/hardware/memory.cpp | 103 +++++++++++----------------------------- 1 file changed, 29 insertions(+), 74 deletions(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 8d0a3beb..208b6ca2 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -31,6 +31,7 @@ HostPt WriteHostTable[MAX_PAGES]; MEMORY_ReadHandler ReadHandlerTable[MAX_PAGES]; MEMORY_WriteHandler WriteHandlerTable[MAX_PAGES]; + /* Page handlers only work in lower memory */ #define LOW_PAGE_LIMIT PAGE_COUNT(1024*1024) #define MAX_PAGE_LIMIT PAGE_COUNT(C_MEM_MAX_SIZE*1024*1024) @@ -92,7 +93,7 @@ void MEM_StrCopy(PhysPt off,char * data,Bitu size) { static Bit8u Illegal_ReadHandler(PhysPt pt) { LOG(LOG_ERROR,"MEM:Illegal read from address %4X",pt); - return 0; + return 0xff; } static void Illegal_WriteHandler(PhysPt pt,Bit8u val) { LOG(LOG_ERROR,"Illegal write val %2X to address %4X",val,pt); @@ -108,7 +109,7 @@ static void Default_WriteHandler(PhysPt pt,Bit8u val) { void MEM_SetupPageHandlers(Bitu startpage,Bitu pages,MEMORY_ReadHandler read,MEMORY_WriteHandler write) { - if (startpage+pages>=LOW_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); + if (startpage+pages>MAX_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); for (Bitu i=startpage;i=LOW_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); + if (startpage+pages>MAX_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); for (Bitu i=startpage;i=MAX_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); + if (startpage+pages>MAX_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); HostPt base=(HostPt)(data)-startpage*PAGE_SIZE; if (!base) LOG_MSG("MEMORY:Unlucky memory allocation"); for (Bitu i=startpage;i=MAX_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); + if (startpage+pages>MAX_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); for (Bitu i=startpage;i> 8) & 0xff) ); @@ -172,7 +172,6 @@ void mem_writeb(PhysPt pt,Bit8u val) { void mem_writew(PhysPt pt,Bit16u val) { if (!WriteHostTable[pt >> PAGE_SHIFT]) { -// HandlerWritew(pt >> PAGE_SHIFT,pt,val); WriteHandlerTable[pt >> PAGE_SHIFT](pt+0,(Bit8u)(val & 0xff)); WriteHandlerTable[pt >> PAGE_SHIFT](pt+1,(Bit8u)((val >> 8) & 0xff) ); } else writew(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); @@ -180,7 +179,6 @@ void mem_writew(PhysPt pt,Bit16u val) { void mem_writed(PhysPt pt,Bit32u val) { if (!WriteHostTable[pt >> PAGE_SHIFT]) { -// HandlerWrited(pt >> PAGE_SHIFT,pt,val); WriteHandlerTable[pt >> PAGE_SHIFT](pt+0,(Bit8u)(val & 0xff)); WriteHandlerTable[pt >> PAGE_SHIFT](pt+1,(Bit8u)((val >> 8) & 0xff) ); WriteHandlerTable[pt >> PAGE_SHIFT](pt+2,(Bit8u)((val >> 16) & 0xff) ); @@ -210,7 +208,6 @@ Bit8u mem_readb(PhysPt pt) { Bit16u mem_readw(PhysPt pt) { if (!ReadHostTable[pt >> PAGE_SHIFT]) { -// return HandlerReadw(pt >> PAGE_SHIFT,pt); return (ReadHandlerTable[pt >> PAGE_SHIFT](pt+0)) | (ReadHandlerTable[pt >> PAGE_SHIFT](pt+1)) << 8; @@ -220,7 +217,6 @@ Bit16u mem_readw(PhysPt pt) { Bit32u mem_readd(PhysPt pt){ if (ReadHostTable[pt >> PAGE_SHIFT]) return readd(ReadHostTable[pt >> PAGE_SHIFT]+pt); else { -// return HandlerReadd(pt >> PAGE_SHIFT,pt); return (ReadHandlerTable[pt >> PAGE_SHIFT](pt+0)) | (ReadHandlerTable[pt >> PAGE_SHIFT](pt+1)) << 8 | @@ -228,51 +224,9 @@ Bit32u mem_readd(PhysPt pt){ (ReadHandlerTable[pt >> PAGE_SHIFT](pt+3)) << 24; } } -#endif -// Big block memory alloction -#define GETBIGBLOCKNR(nr) nr/(1024*1024) - -static Bit8u* mem_block[C_MEM_MAX_SIZE]; - -static bool AllocateBigBlock(Bitu block) -{ - if ((block<1) || (block>C_MEM_MAX_SIZE)) return false; - if (!mem_block[block]) { - // Allocate it - Bitu start = (block==1)? (1024+64)*1024:1024*1024*block; - Bitu size = (block==1)? (1024-64)*1024:1024*1024; - mem_block[block] = (Bit8u*)malloc(size); - if (!mem_block[block]) E_Exit("XMS: Failed to allocate XMS block."); -// else LOG(LOG_ERROR,"XMS: Allocated big block %d.",block); - // Map it with default handler - MEM_SetupMapping(PAGE_COUNT(start),PAGE_COUNT(size),mem_block[block]); - memset(mem_block[block],0,size); - } - return true; -}; - -static Bit8u AllocateMem_ReadHandler(PhysPt pt) -{ - // Allocate mem, set deafult handler - if (AllocateBigBlock(GETBIGBLOCKNR(pt))) { - // Pass request to new handler - return mem_readb(pt); - } - return 0; -} - -static void AllocateMem_WriteHandler(PhysPt pt,Bit8u val) -{ - // Allocate mem, if needed - if (AllocateBigBlock(GETBIGBLOCKNR(pt))) { - // Pass request to new handler - mem_writeb(pt,val); - } -} - -// A20 Line Handlers +/* A20 Line Handling */ static Bit8u controlport_data = 0; static bool a20_enabled; @@ -299,45 +253,46 @@ static void write_p92(Bit32u port,Bit8u val) { } static Bit8u read_p92(Bit32u port) { - return controlport_data | a20_enabled ? 0x02 : 0; + return controlport_data | (a20_enabled ? 0x02 : 0); } static void MEM_ShutDown(Section * sec) { - for (Bitu i=0; i(sec); + + /* Clear paging tables */ + MEM_SetupPageHandlers(0,MAX_PAGE_LIMIT,Illegal_ReadHandler,Illegal_WriteHandler); + /* Allocate memory and setup tables */ + Bitu memsize=section->Get_int("memsize"); + if (memsize<1) memsize=1; + if (memsize>(C_MEM_MAX_SIZE-1)) { + LOG_MSG("Maximum memory size is %d MB",C_MEM_MAX_SIZE-1); + memsize=C_MEM_MAX_SIZE-1; + } + memory=(Bit8u *)malloc(memsize*1024*1024+64*1024); if (!memory) { throw("Can't allocate memory for memory"); } - memset(memory,0xcd,1024*1024); + /* Clear memory*/ + memset(memory,0xcd,memsize*1024*1024+64*1024); /* Setup tables for first mb */ MEM_SetupMapping(0,PAGE_COUNT(1024*1024),memory); /* Setup tables for HMA Area */ a20_enabled=false; MEM_SetupMapping(PAGE_COUNT(1024*1024),PAGE_COUNT(64*1024),memory); - // Setup default handlers for unallocated xms - for (Bitu p=PAGE_COUNT((1024+64)*1024);p1) { + MEM_SetupMapping(PAGE_COUNT((1024+64)*1024),PAGE_COUNT((((memsize-1)*1024)-64)*1024),memory+(1024+64)*1024); } - // clear unallocated memory blocks - for (i=0; iAddDestroyFunction(&MEM_ShutDown); + sec->AddDestroyFunction(&MEM_ShutDown); } From c1248eca4302d5a39e7b9ead646a9950e7e3af7a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 19 Apr 2003 15:42:10 +0000 Subject: [PATCH 0865/4131] memsize option in config file added. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@945 --- src/dosbox.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 6b3eae9b..34e4629e 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -170,6 +170,8 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&IO_Init); secprop->AddInitFunction(&MEM_Init); + /* Keep 1 mb free for video memory some day */ + secprop->Add_int("memsize",C_MEM_MAX_SIZE-1); secprop->AddInitFunction(&CALLBACK_Init); secprop->AddInitFunction(&PIC_Init); secprop->AddInitFunction(&PROGRAMS_Init); From 60e058ca768e1b58f5e5f2dc25dd9de2468fb6b7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Apr 2003 10:40:13 +0000 Subject: [PATCH 0866/4131] Some more protected mode opcodes added. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@946 --- include/cpu.h | 6 +- src/cpu/cpu.cpp | 237 ++++++++++++++++++++++++++++++++++++------------ 2 files changed, 181 insertions(+), 62 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 190032b5..74957aca 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -70,17 +70,19 @@ enum { void CPU_LLDT(Bitu selector); +void CPU_LTR(Bitu selector); void CPU_LIDT(Bitu limit,Bitu base); void CPU_LGDT(Bitu limit,Bitu base); +void CPU_STR(Bitu & selector); void CPU_SLDT(Bitu & selector); void CPU_SIDT(Bitu & limit,Bitu & base); void CPU_SGDT(Bitu & limit,Bitu & base); -void CPU_SLDT(Bitu & limit,Bitu & base); - +void CPU_ARPL(Bitu & dest_sel,Bitu src_sel); void CPU_LAR(Bitu selector,Bitu & ar); +void CPU_LSL(Bitu selector,Bitu & limit); bool CPU_SET_CRX(Bitu cr,Bitu value); Bitu CPU_GET_CRX(Bitu cr); diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 19370e42..0dc34471 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -105,7 +105,7 @@ bool CPU_CheckState(void) { cpu.full.entry=cpu.full.prefix=0; } if (Segs.big[ss]) cpu.state|=STATE_STACK32; - LOG_MSG("CPL Level %x",cpu.cpl); + LOG_MSG("CPL Level %x at %X:%X",cpu.cpl,SegValue(cs),reg_eip); } return true; } @@ -175,7 +175,9 @@ bool Interrupt(Bitu num) { return true; } else { /* Protected Mode Interrupt */ Descriptor gate; +//TODO Check for software interrupt and check gate's dpl=cpu.cpl)) E_Exit("IRET to C segment of higher privilege"); + if (!(desc.DPL()>=cpu.cpl)) E_Exit("IRET:Same level:C:DPLcpu.cpl)) E_Exit("IRET:Outer level:C:DPL <= CPL"); + break; + default: + E_Exit("IRET from illegal descriptor type %X",desc.Type()); + } + Segs.phys[cs]=desc.GetBase(); + Segs.big[cs]=desc.Big(); + Segs.val[cs]=selector; + cpu.cpl=rpl; + reg_eip=offset; + Bitu new_ss,new_esp; + if (use32) { + new_esp=CPU_Pop32(); + new_ss=CPU_Pop32() & 0xffff; + } else { + new_esp=CPU_Pop16(); + new_ss=CPU_Pop16(); + } + reg_esp=new_esp; + CPU_SetSegGeneral(ss,new_ss); + //TODO Maybe validate other segments, but why would anyone use them? + LOG_MSG("IRET:Outer level return to %X:%X",selector,offset); } return CPU_CheckState(); - - - - - - - return true; } return false; } @@ -306,26 +327,25 @@ bool CPU_JMP(bool use32,Bitu selector,Bitu offset) { SegSet16(cs,selector); return true; } else { + Bitu rpl=selector & 3; Descriptor desc; cpu.gdt.GetDescriptor(selector,desc); switch (desc.Type()) { - case DESC_CODE_N_NC_A: - case DESC_CODE_N_NC_NA: - case DESC_CODE_R_NC_A: - case DESC_CODE_R_NC_NA: - if (cpu.cplcpu.cpl) E_Exit("JMP:NC:RPL>CPL"); + if (rpl!=desc.DPL()) E_Exit("JMP:NC:RPL != DPL"); cpu.cpl=desc.DPL(); + LOG_MSG("JMP:Code:NC to %X:%X",selector,offset); goto CODE_jmp; - case DESC_CODE_N_C_A: - case DESC_CODE_N_C_NA: - case DESC_CODE_R_C_A: - case DESC_CODE_R_C_NA: + case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: + case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: + LOG_MSG("JMP:Code:C to %X:%X",selector,offset); CODE_jmp: /* Normal jump to another selector:offset */ - LOG_MSG("CODE JMP to %X:%X DPL %X",selector,offset,desc.DPL()); Segs.phys[cs]=desc.GetBase(); Segs.big[cs]=desc.Big(); - Segs.val[cs]=selector; + Segs.val[cs]=(selector & 0xfffc) | cpu.cpl; reg_eip=offset; return CPU_CheckState(); default: @@ -352,7 +372,40 @@ bool CPU_CALL(bool use32,Bitu selector,Bitu offset) { SegSet16(cs,selector); return true; } else { - E_Exit("Prot call"); + Descriptor call; + Bitu rpl=selector & 3; + cpu.gdt.GetDescriptor(selector,call); + /* Check for type of far call */ + switch (call.Type()) { + case DESC_CODE_N_NC_A:case DESC_CODE_N_NC_NA: + case DESC_CODE_R_NC_A:case DESC_CODE_R_NC_NA: + if (rpl>cpu.cpl) E_Exit("CALL:CODE:NC:RPL>CPL"); + if (call.DPL()!=cpu.cpl) E_Exit("CALL:CODE:NC:DPL!=CPL"); + LOG_MSG("CALL:CODE:NC to %X:%X",selector,offset); + goto call_code; + case DESC_CODE_N_C_A:case DESC_CODE_N_C_NA: + case DESC_CODE_R_C_A:case DESC_CODE_R_C_NA: + if (call.DPL()>cpu.cpl) E_Exit("CALL:CODE:C:DPL>CPL"); + LOG_MSG("CALL:CODE:C to %X:%X",selector,offset); +call_code: + if (!use32) { + CPU_Push16(SegValue(cs)); + CPU_Push16(reg_ip); + reg_eip=offset&0xffff; + } else { + CPU_Push32(SegValue(cs)); + CPU_Push32(reg_eip); + reg_eip=offset; + } + Segs.phys[cs]=call.GetBase(); + Segs.big[cs]=call.Big(); + Segs.val[cs]=(selector & 0xfffc) | cpu.cpl; + reg_eip=offset; + return CPU_CheckState(); + default: + E_Exit("CALL:Descriptor type %x unsupported",call.Type()); + + }; return CPU_CheckState(); } return false; @@ -382,6 +435,11 @@ bool CPU_RET(bool use32,Bitu bytes) { offset=CPU_Pop32(); selector=CPU_Pop32() & 0xffff; } + if (cpu.state & STATE_STACK32) { + reg_esp+=bytes; + } else { + reg_sp+=bytes; + } Descriptor desc; Bitu rpl=selector & 3; if (rpl Date: Sun, 20 Apr 2003 10:40:46 +0000 Subject: [PATCH 0867/4131] Some more protected mode opcodes added. Added 16-bit bit testing operations. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@947 --- src/cpu/core_full/load.h | 19 +++++++++-- src/cpu/core_full/op.h | 64 ++++++++++++++++++++++++++++++++++++- src/cpu/core_full/optable.h | 6 ++-- src/cpu/core_full/support.h | 3 +- 4 files changed, 85 insertions(+), 7 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 1b33fe4c..8c9764f1 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -195,7 +195,10 @@ l_M_Ed: inst.op1.d=Fetchw(); inst.op2.d=Fetchw(); break; - + case L_Ifd: + inst.op1.d=Fetchd(); + inst.op2.d=Fetchw(); + break; /* Direct load of registers */ case L_REGbIb: inst.op2.d=Fetchb(); @@ -376,9 +379,21 @@ l_M_Ed: goto nextopcode; } case D_LEAVEw: - reg_sp=reg_bp; + if (cpu.state & STATE_STACK32) { + reg_esp=reg_ebp; + } else { + reg_sp=reg_bp; + } reg_bp=Pop_16(); goto nextopcode; + case D_LEAVEd: + if (cpu.state & STATE_STACK32) { + reg_esp=reg_ebp; + } else { + reg_sp=reg_bp; + } + reg_ebp=Pop_32(); + goto nextopcode; case D_DAA: DAA(); goto nextopcode; diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 5c5ed872..62f285d7 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -333,6 +333,11 @@ switch (inst.code.op) { CPU_JMP(false,inst.op2.d,inst.op1.d); LoadIP(); goto nextopcode; + case O_JMPFd: + CPU_JMP(true,inst.op2.d,inst.op1.d); + LoadIP(); + goto nextopcode; + case O_INT: SaveIP(); #if C_DEBUG @@ -383,9 +388,27 @@ switch (inst.code.op) { case O_GRP6w: case O_GRP6d: switch (inst.rm_index) { + case 0x00: /* SLDT */ + { + Bitu selector; + CPU_SLDT(selector); + inst.op1.d=selector; + } + break; + case 0x01: /* STR */ + { + Bitu selector; + CPU_STR(selector); + inst.op1.d=selector; + } + break; case 0x02: /* LLDT */ CPU_LLDT(inst.op1.d); goto nextopcode; /* Else value will saved */ + case 0x03: /* LTR */ + CPU_LTR(inst.op1.d); + goto nextopcode; /* Else value will saved */ + default: LOG(LOG_ERROR|LOG_CPU,"Group 6 Illegal subfunction %X",inst.rm_index); } @@ -437,7 +460,46 @@ switch (inst.code.op) { case O_LAR: { Bitu ar;CPU_LAR(inst.op1.d,ar); - inst.op2.d=ar; + inst.op1.d=ar; + } + break; + case O_LSL: + { + Bitu limit;CPU_LSL(inst.op1.d,limit); + inst.op1.d=limit; + } + break; + case O_ARPL: + { + Bitu new_sel=inst.op1.d; + CPU_ARPL(new_sel,inst.op2.d); + inst.op1.d=new_sel; + } + break; + case O_BTw: + case O_BTSw: + case O_BTCw: + case O_BTRw: + { + Bitu val;PhysPt read; + Bitu mask=1 << (inst.op1.d & 15); + FILLFLAGS; + if (inst.rm<0xc0) { + read=inst.rm_eaa+2*(inst.op1.d / 16); + val=mem_readw(read); + } else { + val=reg_16(inst.rm_eai); + } + SETFLAGBIT(CF,(val&mask)>0); + if (inst.code.op==O_BTSw) val|=mask; + if (inst.code.op==O_BTRw) val&=~mask; + if (inst.code.op==O_BTCw) val^=mask; + if (inst.code.op==O_BTw) break; + if (inst.rm<0xc0) { + mem_writew(read,val); + } else { + reg_16(inst.rm_eai)=val; + } } break; case O_BTd: diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 08054c04..bb10ff32 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -69,7 +69,7 @@ static OpCode OpCodeTable[1024]={ /* 0x60 - 0x67 */ {D_PUSHAw ,0 ,0 ,0 },{D_POPAw ,0 ,0 ,0 }, -{L_MODRM ,O_BOUNDw ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_BOUNDw ,0 ,0 },{L_MODRM ,O_ARPL ,S_Ew ,M_EwGw }, {L_PRESEG ,0 ,0 ,fs },{L_PRESEG ,0 ,0 ,gs }, {L_PREOP ,0 ,0 ,0 },{L_PREADD ,0 ,0 ,0 }, /* 0x68 - 0x6f */ @@ -182,7 +182,7 @@ static OpCode OpCodeTable[1024]={ /* 0x100 - 0x107 */ {L_MODRM ,O_GRP6w ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7w ,S_Ew ,M_Ew }, -{L_MODRM ,O_LAR ,S_Gw ,M_Ew },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_LAR ,S_Gw ,M_Ew },{L_MODRM ,O_LSL ,S_Gw ,M_Ew }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x108 - 0x10f */ @@ -539,7 +539,7 @@ static OpCode OpCodeTable[1024]={ /* 0x300 - 0x307 */ {L_MODRM ,O_GRP6d ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7d ,S_Ew ,M_Ew }, -{L_MODRM ,O_LAR ,S_Gd ,M_Ed },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_LAR ,S_Gd ,M_Ew },{L_MODRM ,O_LSL ,S_Gd ,M_Ew }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x308 - 0x30f */ diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 23afd1db..9460c6df 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -82,7 +82,8 @@ enum { O_GRP6w,O_GRP6d, O_GRP7w,O_GRP7d, O_M_Cd_Rd,O_M_Rd_Cd, - O_LAR, + O_LAR,O_LSL, + O_ARPL, O_BTw,O_BTSw,O_BTRw,O_BTCw, O_BTd,O_BTSd,O_BTRd,O_BTCd, From 83dee93e18e013838c6e0088fbfa0cf41bb0a850 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Apr 2003 10:41:59 +0000 Subject: [PATCH 0868/4131] Added 32-bit near calls Forced to 32-bit addressing. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@948 --- src/debug/debug_disasm.cpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/debug/debug_disasm.cpp b/src/debug/debug_disasm.cpp index 897a4c65..ca0467bc 100644 --- a/src/debug/debug_disasm.cpp +++ b/src/debug/debug_disasm.cpp @@ -116,8 +116,6 @@ static int modrmv; /* flag for getting modrm byte */ static int sibv; /* flag for getting sib byte */ static int opsize; /* just like it says ... */ static int addrsize; -static int addr20bit=0; -static int addr24bit=0; static int addr32bit=0; /* some defines for extracting instruction bit fields from bytes */ @@ -444,13 +442,8 @@ static char *addr_to_hex(UINT32 addr, int splitup) { else #endif - if (addr20bit) { - sprintf(buffer, "%05X", addr&0xfffff ); - } else if (addr24bit) { - sprintf(buffer, "%06X", addr&0xffffff ); - } else if (addr32bit) { - sprintf(buffer, "%08X", addr ); - } + sprintf(buffer, "%08X", addr ); + } return buffer; @@ -874,7 +867,6 @@ static void percent(char type, char subtype) vofs = (INT16)vofs; name = addr_to_hex(vofs+instruction_offset+INSTRUCTION_SIZE,0); break; -#if 0 /* i386 */ case 4: vofs = (UINT32)getbyte(); /* yuk! */ @@ -883,7 +875,6 @@ static void percent(char type, char subtype) vofs |= (UINT32)getbyte() << 24; name = addr_to_hex(vofs+instruction_offset+INSTRUCTION_SIZE,1); break; -#endif } if (vofs<0) uprintf("%s ($-%x)", name, -vofs); @@ -1087,7 +1078,7 @@ Bitu DasmI386(char* buffer, PhysPt pc, Bitu cur_ip, bool bit32) ubufp = buffer; first_space = 1; - addr32bit=1;addr20bit=addr24bit=0; + addr32bit=1; prefix = 0; modrmv = sibv = -1; /* set modrm and sib flags */ From bb30f7f309482e181bec9de0e758f76316a3b142 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Apr 2003 10:44:15 +0000 Subject: [PATCH 0869/4131] Fixed mixup with LSB and MSB when reading timer latch. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@949 --- src/hardware/timer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 4194f53c..d0f0e6c0 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -149,12 +149,12 @@ static Bit8u read_latch(Bit32u port) { else pit[counter].read_state = 0; break; - case 1: /* read MSB */ - ret = (pit[counter].read_latch >> 8) & 0xff; + case 1: /* read LSB */ + ret = (pit[counter].read_latch & 0xff); pit[counter].read_latch = -1; break; - case 2: /* read LSB */ - ret = (pit[counter].read_latch & 0xff); + case 2: /* read MSB */ + ret = (pit[counter].read_latch >> 8) & 0xff; pit[counter].read_latch = -1; break; default: From 6910b58618b53e8d949cf6c450220605613d310c Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 20 Apr 2003 12:12:43 +0000 Subject: [PATCH 0870/4131] Added XMS_GetSize Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@950 --- src/ints/xms.cpp | 8 ++++++-- src/ints/xms.h | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 0714b209..4f8ffdf8 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -344,6 +344,9 @@ Bitu XMS_ResizeMemory(Bitu handle, Bitu newSize) return 0; }; +// Return size of xms mem in mb +static Bitu xms_size = 0; +Bitu XMS_GetSize(void) { return xms_size; }; static bool multiplex_xms(void) { switch (reg_ax) { @@ -449,10 +452,11 @@ void XMS_Init(Section* sec) { Bitu size=section->Get_int("xmssize"); if (!size) return; if (size>C_MEM_MAX_SIZE-1) size=C_MEM_MAX_SIZE-1; - DOS_AddMultiplexHandler(multiplex_xms); + xms_size = size; +/* DOS_AddMultiplexHandler(multiplex_xms); call_xms=CALLBACK_Allocate(); CALLBACK_Setup(call_xms,&XMS_Handler,CB_RETF); - xms_callback=CALLBACK_RealPointer(call_xms); + xms_callback=CALLBACK_RealPointer(call_xms);*/ /* Setup the handler table */ Bitu i; for (i=0;i Date: Sun, 20 Apr 2003 12:13:14 +0000 Subject: [PATCH 0871/4131] Fixed bug in detecting breakpoint Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@951 --- src/cpu/core_full/op.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 62f285d7..e3ebfd88 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -341,7 +341,7 @@ switch (inst.code.op) { case O_INT: SaveIP(); #if C_DEBUG - if ((inst.entry==0xcc) && DEBUG_Breakpoint()) return 1; + if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint()) return 1; else if (DEBUG_IntBreakpoint(inst.op1.b)) return 1; #endif Interrupt(inst.op1.b); From da7f3c8829408aeb73618e99d02a7307a110cd2a Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 20 Apr 2003 12:13:58 +0000 Subject: [PATCH 0872/4131] Made data preview safe (not showing addresses out of mem range) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@952 --- src/debug/debug.cpp | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index dc670772..c3264d22 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -34,6 +34,7 @@ #include "mixer.h" #include "debug_inc.h" #include "timer.h" +#include "../ints/xms.h" #include "../shell/shell_inc.h" #ifdef WIN32 @@ -1090,24 +1091,25 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) pos++; }; Bit32u address = GetAddress(seg,adr); - - static char outmask[] = "%s:[%04X]=%02X"; - - if (cpu.state & STATE_PROTECTED) outmask[6] = '8'; + if (address<(XMS_GetSize()+1)*1024*1024) { + static char outmask[] = "%s:[%04X]=%02X"; + + if (cpu.state & STATE_PROTECTED) outmask[6] = '8'; - switch (DasmLastOperandSize()) { - case 8 : { Bit8u val = mem_readb(address); - outmask[12] = '2'; - sprintf(result,outmask,prefix,adr,val); - } break; - case 16: { Bit16u val = mem_readw(address); - outmask[12] = '4'; - sprintf(result,outmask,prefix,adr,val); - } break; - case 32: { Bit32u val = mem_readd(address); - outmask[12] = '8'; - sprintf(result,outmask,prefix,adr,val); - } break; + switch (DasmLastOperandSize()) { + case 8 : { Bit8u val = mem_readb(address); + outmask[12] = '2'; + sprintf(result,outmask,prefix,adr,val); + } break; + case 16: { Bit16u val = mem_readw(address); + outmask[12] = '4'; + sprintf(result,outmask,prefix,adr,val); + } break; + case 32: { Bit32u val = mem_readd(address); + outmask[12] = '8'; + sprintf(result,outmask,prefix,adr,val); + } break; + } } // Variable found ? CDebugVar* var = CDebugVar::FindVar(address); From 96600069ec02eb2809c1bf194c0dcbd87c1b5928 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 20 Apr 2003 12:42:23 +0000 Subject: [PATCH 0873/4131] oops. activated xms handler again. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@953 --- src/ints/xms.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 4f8ffdf8..be417848 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -453,10 +453,10 @@ void XMS_Init(Section* sec) { if (!size) return; if (size>C_MEM_MAX_SIZE-1) size=C_MEM_MAX_SIZE-1; xms_size = size; -/* DOS_AddMultiplexHandler(multiplex_xms); + DOS_AddMultiplexHandler(multiplex_xms); call_xms=CALLBACK_Allocate(); CALLBACK_Setup(call_xms,&XMS_Handler,CB_RETF); - xms_callback=CALLBACK_RealPointer(call_xms);*/ + xms_callback=CALLBACK_RealPointer(call_xms); /* Setup the handler table */ Bitu i; for (i=0;i Date: Mon, 21 Apr 2003 07:49:44 +0000 Subject: [PATCH 0874/4131] Add 32-bit lss and cleared out 32-bit xlat for now. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@954 --- src/cpu/core_full/optable.h | 4 ++-- src/cpu/core_full/save.h | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index bb10ff32..72069f76 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -507,7 +507,7 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,5 ,0 ,M_GRP_1 },{L_MODRM ,7 ,0 ,M_GRP_1 }, {L_MODRM ,5 ,0 ,M_GRP_CL },{L_MODRM ,7 ,0 ,M_GRP_CL }, {L_Ib ,O_AAM ,0 ,0 },{L_Ib ,O_AAD ,0 ,0 }, -{D_SETALC ,0 ,0 ,0 },{D_XLAT ,0 ,0 ,0 }, +{D_SETALC ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x2d8 - 0x2df */ {L_MODRM ,0 ,0 ,0 },{L_MODRM ,0 ,0 ,0 }, {L_MODRM ,0 ,0 ,0 },{L_MODRM ,0 ,0 ,0 }, @@ -662,7 +662,7 @@ static OpCode OpCodeTable[1024]={ /* 0x3b0 - 0x3b7 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{L_MODRM ,O_BTRd ,0 ,0 }, +{L_MODRM ,O_SEGSS ,S_SEGGd,M_Efd },{L_MODRM ,O_BTRd ,0 ,0 }, {L_MODRM ,O_SEGFS ,S_SEGGd,M_Efd },{L_MODRM ,O_SEGGS ,S_SEGGd,M_Efd }, {L_MODRM ,0 ,S_Gd ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ew }, /* 0x3b8 - 0x3bf */ diff --git a/src/cpu/core_full/save.h b/src/cpu/core_full/save.h index fba9ed5f..df574350 100644 --- a/src/cpu/core_full/save.h +++ b/src/cpu/core_full/save.h @@ -61,6 +61,10 @@ switch (inst.code.save) { reg_16(inst.rm_index)=inst.op1.w; CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w); break; + case S_SEGGd: + reg_32(inst.rm_index)=inst.op1.d; + CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w); + break; case S_PUSHw: Push_16(inst.op1.w); break; From d8eae49c04da0481f0b815b8e7ce47cb0574f824 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 22 Apr 2003 20:55:15 +0000 Subject: [PATCH 0875/4131] init cpm_entry in psp class Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@955 --- src/dos/dos_classes.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 0618c108..815d2ca7 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -94,7 +94,9 @@ void DOS_PSP::MakeNew(Bit16u mem_size) sSave(sPSP,next_seg,seg+mem_size); /* far call opcode */ sSave(sPSP,far_call,0xea); -// sSave(sPSP,cmp_entry + // far call to interrupt 0x21 - faked for bill & ted + // lets hope nobody really uses this address + sSave(sPSP,cpm_entry,RealMake(0xDEAD,0xFFFF)); /* Standard blocks,int 20 and int21 retf */ sSave(sPSP,exit[0],0xcd); sSave(sPSP,exit[1],0x20); From 4916b5fb6cd7218721f0d4c27ab4c9f6f13ddf0c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 23 Apr 2003 07:33:06 +0000 Subject: [PATCH 0876/4131] Place #ifdef's around MSVC #pragma's Rewrite some signed/unsigned unions to use casts. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@956 --- include/dos_inc.h | 32 +++++++++++++++++++++++++++++--- include/setup.h | 2 ++ src/cpu/core_16/prefix_66_of.h | 4 ++-- src/cpu/core_16/prefix_of.h | 2 +- src/cpu/modrm.h | 18 +++--------------- src/dos/dos_execute.cpp | 4 ++++ src/dos/dos_files.cpp | 4 ++++ src/dos/dos_mscdex.cpp | 4 ++++ src/dos/dos_tables.cpp | 4 ++++ src/hardware/adlib.cpp | 2 ++ 10 files changed, 55 insertions(+), 21 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 1c4036bd..1b91e545 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -22,14 +22,16 @@ #include #include +#ifdef _MSC_VER #pragma pack (1) +#endif struct CommandTail{ Bit8u count; /* number of bytes returned */ char buffer[127]; /* the buffer itself */ } GCC_ATTRIBUTE(packed); - - +#ifdef _MSC_VER #pragma pack () +#endif struct DOS_Date { Bit16u year; @@ -263,7 +265,9 @@ public: Bit16u FindEntryByHandle (Bit8u handle); private: + #ifdef _MSC_VER #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 */ @@ -289,7 +293,9 @@ private: Bit8u fill_4[4]; /* unused */ CommandTail cmdtail; } GCC_ATTRIBUTE(packed); - #pragma pack() + #ifdef _MSC_VER + #pragma pack() + #endif Bit16u seg; sPSP* psp; public: @@ -302,7 +308,9 @@ public: 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; @@ -315,7 +323,9 @@ public: RealPt initsssp; RealPt initcsip; }GCC_ATTRIBUTE(packed); + #ifdef _MSC_VER #pragma pack() + #endif sExec exec; sOverlay overlay; }; @@ -328,7 +338,9 @@ public: void SetfirstFileTable(RealPt _first_table); RealPt GetPointer (void); private: + #ifdef _MSC_VER #pragma pack(1) + #endif struct sDIB { Bit8u stuff1[22]; // some stuff, hopefully never used.... Bit16u firstMCB; // first memory control block @@ -342,7 +354,9 @@ private: RealPt fcbTable; // pointer to system FCB table // some more stuff, hopefully never used. } GCC_ATTRIBUTE(packed); + #ifdef _MSC_VER #pragma pack () + #endif Bit16u seg; }; @@ -360,7 +374,9 @@ public: void SetDirID(Bit16u entry) { sSave(sDTA,dirID,entry); }; Bit16u GetDirID(void) { return sGet(sDTA,dirID); }; private: + #ifdef _MSC_VER #pragma pack(1) + #endif struct sDTA { Bit8u sdrive; /* The Drive the search is taking place */ Bit8u sattr; /* The Attributes that need to be found */ @@ -374,7 +390,9 @@ private: Bit32u size; char name[DOS_NAMELENGTH_ASCII]; } GCC_ATTRIBUTE(packed); + #ifdef _MSC_VER #pragma pack() + #endif }; class DOS_FCB: public MemStruct { @@ -397,7 +415,9 @@ public: 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 */ @@ -414,7 +434,9 @@ private: 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{ @@ -429,7 +451,9 @@ public: Bit16u GetSize(void) { return sGet(sMCB,size);} Bit16u GetPSPSeg(void) { return sGet(sMCB,psp_segment);} private: + #ifdef _MSC_VER #pragma pack (1) + #endif struct sMCB { Bit8u type; Bit16u psp_segment; @@ -437,7 +461,9 @@ private: Bit8u unused[3]; Bit8u filename[8]; } GCC_ATTRIBUTE(packed); + #ifdef _MSC_VER #pragma pack () + #endif }; extern DOS_InfoBlock dos_infoblock;; diff --git a/include/setup.h b/include/setup.h index 21ea765b..b34a9b41 100644 --- a/include/setup.h +++ b/include/setup.h @@ -19,7 +19,9 @@ #ifndef _SETUP_H_ #define _SETUP_H_ +#ifdef _MSC_VER #pragma warning ( disable : 4786 ) +#endif #include #include diff --git a/src/cpu/core_16/prefix_66_of.h b/src/cpu/core_16/prefix_66_of.h index 2ddb607e..0ec604bd 100644 --- a/src/cpu/core_16/prefix_66_of.h +++ b/src/cpu/core_16/prefix_66_of.h @@ -162,14 +162,14 @@ switch (Fetchb()) { case 0xbe: /* MOVSX Gd,Eb */ { GetRMrd; - if (rm >= 0xc0 ) {GetEArb;*rmrd=*earbs;} + if (rm >= 0xc0 ) {GetEArb;*rmrd=*(Bit8s *)earb;} else {GetEAa;*rmrd=LoadMbs(eaa);} break; } case 0xbf: /* MOVSX Gd,Ew */ { GetRMrd; - if (rm >= 0xc0 ) {GetEArw;*rmrd=*earws;} + if (rm >= 0xc0 ) {GetEArw;*rmrd=*(Bit16s *)earw;} else {GetEAa;*rmrd=LoadMws(eaa);} break; } diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h index b8a5376f..61ad2a3c 100644 --- a/src/cpu/core_16/prefix_of.h +++ b/src/cpu/core_16/prefix_of.h @@ -381,7 +381,7 @@ switch(Fetchb()) { case 0xbe: /* MOVSX Gw,Eb */ { GetRMrw; - if (rm >= 0xc0 ) {GetEArb;*rmrw=*earbs;} + if (rm >= 0xc0 ) {GetEArb;*rmrw=*(Bit8s *)earb;} else {GetEAa;*rmrw=LoadMbs(eaa);} break; } diff --git a/src/cpu/modrm.h b/src/cpu/modrm.h index ad0da0d4..42a34d09 100644 --- a/src/cpu/modrm.h +++ b/src/cpu/modrm.h @@ -53,24 +53,12 @@ extern Bit32u * lookupRMEAregd[256]; #define GetEArb \ - union { \ - Bit8u * earb; \ - Bit8s * earbs; \ - }; \ - earb=lookupRMEAregb[rm]; + Bit8u * earb=lookupRMEAregb[rm]; #define GetEArw \ - union { \ - Bit16u * earw; \ - Bit16s * earws; \ - }; \ - earw=lookupRMEAregw[rm]; + Bit16u * earw=lookupRMEAregw[rm]; #define GetEArd \ - union { \ - Bit32u * eard; \ - Bit32s * eards; \ - }; \ - eard=lookupRMEAregd[rm]; + Bit32u * eard=lookupRMEAregd[rm]; diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index e863ddd8..e5bbe898 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -24,7 +24,9 @@ #include "callback.h" #include "debug.h" +#ifdef _MSC_VER #pragma pack(1) +#endif struct EXE_Header { Bit16u signature; /* EXE Signature MZ or ZM */ Bit16u extrabytes; /* Bytes on the last page */ @@ -41,7 +43,9 @@ struct EXE_Header { Bit16u reloctable; Bit16u overlay; } GCC_ATTRIBUTE(packed); +#ifdef _MSC_VER #pragma pack() +#endif #define MAGIC1 0x5a4d #define MAGIC2 0x4d5a diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index e9e4f537..956e4a64 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -518,7 +518,9 @@ Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u * hasdrive=hasname=hasext=false; Bitu index;bool finished;Bit8u fill; /* First get the old data from the fcb */ +#ifdef _MSC_VER #pragma pack (1) +#endif union { struct { char drive[2]; @@ -527,7 +529,9 @@ Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u * } part GCC_ATTRIBUTE (packed) ; char full[DOS_FCBNAME]; } fcb_name; +#ifdef _MSC_VER #pragma pack() +#endif /* Get the old information from the previous fcb */ fcb.GetName(fcb_name.full);fcb_name.part.drive[1]=0;fcb_name.part.name[8]=0;fcb_name.part.ext[3]=0; /* Strip of the leading sepetaror */ diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index a2f96ddf..60d85cae 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -61,7 +61,9 @@ public: void SetStrategy (Bit16u ofs) { sSave(sDeviceHeader,strategy,ofs); }; public: + #ifdef _MSC_VER #pragma pack(1) + #endif struct sDeviceHeader{ RealPt nextDeviceHeader; Bit16u devAttributes; @@ -72,7 +74,9 @@ public: Bit8u driveLetter; Bit8u numSubUnits; } TDeviceHeader; + #ifdef _MSC_VER #pragma pack() + #endif }; class CMscdex diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index dc94f920..8332e17e 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -20,13 +20,17 @@ #include "mem.h" #include "dos_inc.h" +#ifdef _MSC_VER #pragma pack(1) +#endif struct DOS_TableCase { Bit16u size; Bit8u chars[256]; } GCC_ATTRIBUTE (packed); +#ifdef _MSC_VER #pragma pack () +#endif RealPt DOS_TableUpCase; RealPt DOS_TableLowCase; diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index dc8bb48c..41db8d02 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -33,9 +33,11 @@ namespace MAME { /* Defines */ # define logerror(x) +#ifdef _MSC_VER /* Disable recurring warnings */ # pragma warning ( disable : 4018 ) # pragma warning ( disable : 4244 ) +#endif /* Work around ANSI compliance problem (see driver.h) */ struct __MALLOCPTR { From 336e693b6125ce2634acb987202e9112c44d6a57 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 23 Apr 2003 12:07:53 +0000 Subject: [PATCH 0877/4131] Added support for reading volume labels Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@957 --- include/dos_system.h | 7 ++++++- src/dos/cdrom.h | 2 +- src/dos/dos_mscdex.cpp | 40 ++++++++++++++++++++++++++++++++-------- src/dos/dos_programs.cpp | 3 +++ src/dos/drive_cache.cpp | 32 ++++++++++++++++++++++++++++++-- src/dos/drive_local.cpp | 31 ++++++++++++++++++++++++++++--- 6 files changed, 100 insertions(+), 15 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 0ea54efe..f0878ac2 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -104,6 +104,8 @@ public: void DeleteEntry (const char* path, bool ignoreLastDir = false); void EmptyCache (void); + void SetLabel (const char* name); + char* GetLabel (void) { return label; }; class CFileInfo { public: @@ -140,7 +142,6 @@ private: Bit16u GetFreeID (CFileInfo* dir); void Clear (void); - CFileInfo* dirBase; char dirPath [CROSS_LEN]; char basePath [CROSS_LEN]; @@ -155,6 +156,7 @@ private: char dirSearchName [MAX_OPENDIRS]; bool free [MAX_OPENDIRS]; + char label [CROSS_LEN]; }; class DOS_No_Drive_Cache { @@ -182,6 +184,9 @@ public: Bit16u GetCurrentEntry (void) { return 0; }; void EmptyCache (void) {}; + + void SetLabel (const char* name) {}; + char* GetLabel (void) {}; public: char basePath [CROSS_LEN]; diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index 8dfc97a0..aa00bd6f 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -61,7 +61,7 @@ public: bool PlayAudioSector (unsigned long start,unsigned long len); bool PauseAudio (bool resume); bool StopAudio (void); - bool ReadSectors (void* buffer, bool raw, unsigned long sector, unsigned long num) { return true; }; + bool ReadSectors (void* buffer, bool raw, unsigned long sector, unsigned long num) { return false; }; bool LoadUnloadMedia (bool unload); private: diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 60d85cae..ecb2ebc8 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -23,6 +23,7 @@ #include "dos_system.h" #include "dos_inc.h" #include "setup.h" +#include "support.h" #include "cdrom.h" @@ -101,6 +102,7 @@ public: int AddDrive (Bit16u _drive, char* physicalPath, Bit8u& subUnit); void GetDrives (PhysPt data); void GetDriverInfo (PhysPt data); + bool GetVolumeName (Bit8u subUnit, char* name); bool GetCopyrightName (Bit16u drive, PhysPt data); bool GetAbstractName (Bit16u drive, PhysPt data); bool GetDocumentationName(Bit16u drive, PhysPt data); @@ -233,18 +235,15 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) osi.dwOSVersionInfoSize = sizeof(osi); GetVersionEx(&osi); if ((osi.dwPlatformId==VER_PLATFORM_WIN32_NT) && (osi.dwMajorVersion>4)) { - // WIN NT/200/XP - if (useCdromInterface==CDROM_USE_ASPI) { - cdrom[numDrives] = new CDROM_Interface_Aspi(); - LOG(LOG_MISC,"MSCDEX: ASPI Interface."); - break; - } else if (useCdromInterface==CDROM_USE_IOCTL) { + // only WIN NT/200/XP + if (useCdromInterface==CDROM_USE_IOCTL) { cdrom[numDrives] = new CDROM_Interface_Ioctl(); LOG(LOG_MISC,"MSCDEX: IOCTL Interface."); break; } - } else { - // Win 95/98/ME - always use ASPI + } + if (useCdromInterface==CDROM_USE_ASPI) { + // all Wins - ASPI cdrom[numDrives] = new CDROM_Interface_Aspi(); LOG(LOG_MISC,"MSCDEX: ASPI Interface."); break; @@ -432,6 +431,26 @@ bool CMscdex::ReadVTOC(Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error) return (error==0); }; +bool CMscdex::GetVolumeName(Bit8u subUnit, char* data) +{ + if (subUnit>=numDrives) return false; + Bit16u drive = dinfo[subUnit].drive; + + Bit16u error,seg,size = 128; + bool success = false; + if (DOS_AllocateMemory(&seg,&size)) { + PhysPt ptoc = PhysMake(seg,0); + success = ReadVTOC(drive,0x00,ptoc,error); + if (success) { + MEM_StrCopy(ptoc+40,data,31); + data[31] = 0; + rtrim(data); + }; + DOS_FreeMemory(seg); + } + return success; +}; + bool CMscdex::GetCopyrightName(Bit16u drive, PhysPt data) { Bit16u error,seg,size = 128; @@ -879,6 +898,11 @@ int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit) return result; }; +bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name) +{ + return mscdex->GetVolumeName(subUnit,name); +}; + bool MSCDEX_HasMediaChanged(Bit8u subUnit) { static TMSF leadOut[MSCDEX_MAX_DRIVES]; diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 29d57d63..c00b7f8c 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -35,6 +35,7 @@ public: void Run(void) { DOS_Drive * newdrive;char drive; + std::string label; // Show list of cdroms if (cmd->FindExist("-cd",false)) { @@ -141,6 +142,8 @@ public: /* Set the correct media byte in the table */ mem_writeb(Real2Phys(dos.tables.mediaid)+drive-'A',newdrive->GetMediaByte()); WriteOut("Drive %c mounted as %s\n",drive,newdrive->GetInfo()); + /* check if volume label is given */ + if (cmd->FindString("-label",label,true)) newdrive->dirCache.SetLabel(label.c_str()); return; showusage: WriteOut(MSG_Get("PROGRAM_MOUNT_USAGE")); diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 01b55306..92f0c00c 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -57,9 +57,9 @@ DOS_Drive_Cache::DOS_Drive_Cache(void) dirBase = new CFileInfo; save_dir = 0; srchNr = 0; + label[0] = 0; for (Bit32u i=0; i0) { + if (vname[vnamePos]==0) break; + if (!point && (vname[vnamePos]=='.')) { togo=4; point=true; } + label[labelPos] = vname[vnamePos]; + labelPos++; vnamePos++; + togo--; + if ((togo==0) && !point) { + if (vname[vnamePos]=='.') vnamePos++; + label[labelPos]='.'; labelPos++; point=true; togo=3; + } + }; + label[labelPos]=0; +// LOG(LOG_ERROR,"CACHE: Set volume label to %s",label); +}; + Bit16u DOS_Drive_Cache::GetFreeID(CFileInfo* dir) { for (Bit32u i=0; i Date: Wed, 23 Apr 2003 12:09:30 +0000 Subject: [PATCH 0878/4131] Dont show volume label on standard dir Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@958 --- src/shell/shell_cmds.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index f53e56f7..4095302c 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -242,7 +242,7 @@ void DOS_Shell::CMD_DIR(char * args) { WriteOut(MSG_Get("SHELL_CMD_DIR_INTRO"),path); DOS_DTA dta(dos.dta); - bool ret=DOS_FindFirst(args,0xffff); + bool ret=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME); if (!ret) { WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); return; From f04d776aa9f0247be9d508e03f25be702f76ec55 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 23 Apr 2003 19:22:28 +0000 Subject: [PATCH 0879/4131] Fix for selectors always coming from GDT Removed save function from Descriptor. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@959 --- include/cpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cpu.h b/include/cpu.h index 74957aca..521da441 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -339,7 +339,7 @@ protected: class GDTDescriptorTable : public DescriptorTable { public: bool GetDescriptor (Bitu selector, Descriptor& desc) { - Bitu address=selector&=~7; + Bitu address=selector & ~7; if (selector & 4) { if (address>=ldt_limit) return false; desc.Load(ldt_base+address); From bbe3ba5120d2e00543943bff92e77e6a839ffcf8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 23 Apr 2003 19:24:05 +0000 Subject: [PATCH 0880/4131] Fix for interrupt flag in pmode interrupts Small hack to stop messages from being showed. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@960 --- src/cpu/cpu.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 0dc34471..2f406f6c 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -24,6 +24,10 @@ #include "keyboard.h" #include "setup.h" +#if 1 +#undef LOG_MSG +#define LOG_MSG +#endif Flag_Info flags; CPU_Regs cpu_regs; @@ -181,7 +185,6 @@ bool Interrupt(Bitu num) { switch (gate.Type()) { case DESC_286_INT_GATE: case DESC_386_INT_GATE: - SETFLAGBIT(IF,false); case DESC_286_TRAP_GATE: case DESC_386_TRAP_GATE: { @@ -203,7 +206,7 @@ bool Interrupt(Bitu num) { case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: /* Prepare stack for gate to same priviledge */ if (gate.Type() & 0x8) { /* 32-bit Gate */ - CPU_Push32(flags.word & 0xffff); + CPU_Push32(flags.word); CPU_Push32(SegValue(cs)); CPU_Push32(reg_eip); } else { /* 16-bit gate */ @@ -216,7 +219,7 @@ bool Interrupt(Bitu num) { default: E_Exit("INT:Gate Selector points to illegal descriptor with type %x",desc.Type()); } - + if (!(gate.Type()&1)) SETFLAGBIT(IF,false); SETFLAGBIT(TF,false); SETFLAGBIT(NT,false); Segs.val[cs]=(selector&0xfffc) | cpu.cpl; @@ -464,7 +467,7 @@ RET_same_level: Segs.big[cs]=desc.Big(); Segs.val[cs]=selector; reg_eip=offset; - LOG(LOG_CPU,"RET - Same level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL()); + LOG_MSG("RET - Same level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL()); return CPU_CheckState(); } else { /* Return to higher level */ From 1651123cbf725dafe739fd301d0be648f9ee6c4c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 23 Apr 2003 19:31:04 +0000 Subject: [PATCH 0881/4131] Set a default division rate Stop showing the warning for illegal registers Extra protection before starting RTC timer. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@961 --- src/hardware/cmos.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 4ce97dc1..0b113e8a 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -49,7 +49,7 @@ static void cmos_timerevent(void) { static void cmos_checktimer(void) { PIC_RemoveEvents(cmos_timerevent); - if (!cmos.timer.div && !cmos.timer.enabled) return; + if (!cmos.timer.div || !cmos.timer.enabled) return; if (cmos.timer.div<=2) cmos.timer.div+=7; cmos.timer.micro=(Bitu) (10000000.0/(32768.0 / (1 << (cmos.timer.div - 1)))); LOG(LOG_PIT,"RTC Timer at %f hz",1000000.0/cmos.timer.micro); @@ -89,7 +89,7 @@ static void cmos_writereg(Bit32u port,Bit8u val) { break; default: cmos.regs[cmos.reg]=val & 0x7f; - LOG(LOG_ERROR|LOG_BIOS,"CMOS:Unhandled register %x",cmos.reg); +// LOG(LOG_ERROR|LOG_BIOS,"CMOS:WRite to unhandled register %x",cmos.reg); } } @@ -115,5 +115,8 @@ void CMOS_Init(Section* sec) { IO_RegisterWriteHandler(0x71,cmos_writereg,"CMOS"); IO_RegisterReadHandler(0x71,cmos_readreg,"CMOS"); cmos.timer.enabled=false; + cmos.reg=0xa; + cmos_writereg(0x71,0x26); + } From 1f5dac8c97d3e7e7ed9407d13dc2db3342a99495 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Apr 2003 08:42:42 +0000 Subject: [PATCH 0882/4131] Added 32-bit ENTER and fixed 16-bit one Added 32-bit XLAT Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@962 --- src/cpu/core_full/load.h | 71 +++++++++++++++++++++++++++++++++---- src/cpu/core_full/optable.h | 7 ++-- src/cpu/core_full/support.h | 2 +- 3 files changed, 70 insertions(+), 10 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 8c9764f1..b6ba9938 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -317,10 +317,14 @@ l_M_Ed: case D_SETALC: reg_al = get_CF() ? 0xFF : 0; goto nextopcode; - case D_XLAT: + case D_XLATw: if (inst.prefix & PREFIX_SEG) reg_al=LoadMb(inst.seg.base+reg_bx+reg_al); else reg_al=LoadMb(SegBase(ds)+reg_bx+reg_al); goto nextopcode; + case D_XLATd: + if (inst.prefix & PREFIX_SEG) reg_al=LoadMb(inst.seg.base+reg_ebx+reg_al); + else reg_al=LoadMb(SegBase(ds)+reg_ebx+reg_al); + goto nextopcode; case D_CBW: reg_ax=(Bit8s)reg_al; goto nextopcode; @@ -371,11 +375,66 @@ l_M_Ed: goto nextopcode; case D_ENTERw: { - Bit16u bytes=Fetchw();Bit8u level=Fetchb(); - Push_16(reg_bp);reg_bp=reg_sp;reg_sp-=bytes; - EAPoint reader=SegBase(ss)+reg_bp; - for (Bit8u i=1;i Date: Sun, 27 Apr 2003 07:03:37 +0000 Subject: [PATCH 0883/4131] Changed wait flag handling to use RTC Changed extended memory size to read it out from CMOS Added getting time from RTC call. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@963 --- src/ints/bios.cpp | 60 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 46e7c269..8961bdf5 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -26,7 +26,27 @@ #include "joystick.h" static Bitu call_int1a,call_int11,call_int8,call_int17,call_int12,call_int15,call_int1c; -static Bitu call_int1; +static Bitu call_int1,call_int70; + +static Bitu INT70_Handler(void) { + if (mem_readb(BIOS_WAIT_FLAG_ACTIVE)) { + Bits count=mem_readd(BIOS_WAIT_FLAG_COUNT); + if (count>997) { + mem_writed(BIOS_WAIT_FLAG_COUNT,count-997); + } else { + mem_writed(BIOS_WAIT_FLAG_COUNT,0); + PhysPt where=Real2Phys(mem_readd(BIOS_WAIT_FLAG_POINTER)); + mem_writeb(where,mem_readb(where)|0x80); + mem_writeb(BIOS_WAIT_FLAG_ACTIVE,0); + IO_Write(0x70,0xb); + IO_Write(0x71,IO_Read(0x71)&~0x40); + } + } + /* Signal EOI to both pics */ + IO_Write(0xa0,0x20); + IO_Write(0x20,0x20); + return 0; +} static Bitu INT1A_Handler(void) { switch (reg_ah) { @@ -42,9 +62,14 @@ static Bitu INT1A_Handler(void) { mem_writed(BIOS_TIMER,(reg_cx<<16)|reg_dx); break; case 0x02: /* GET REAL-TIME CLOCK TIME (AT,XT286,PS) */ - reg_dx=reg_cx=0; + IO_Write(0x70,0x04); //Hours + reg_ch=IO_Read(0x71); + IO_Write(0x70,0x02); //Minutes + reg_cl=IO_Read(0x71); + IO_Write(0x70,0x00); //Seconds + reg_dh=IO_Read(0x71); + reg_dl=0; //Daylight saving disabled CALLBACK_SCF(false); - LOG(LOG_BIOS,"INT1A:02:Faked RTC get time call"); break; case 0x04: /* GET REAL-TIME ClOCK DATA (AT,XT286,PS) */ reg_dx=reg_cx=0; @@ -149,11 +174,6 @@ static Bitu INT17_Handler(void) { return CBRET_NONE; } -static void WaitFlagEvent(void) { - PhysPt where=Real2Phys(mem_readd(BIOS_WAIT_FLAG_POINTER)); - mem_writeb(where,mem_readb(where)|0x80); - mem_writeb(BIOS_WAIT_FLAG_ACTIVE,0); -} static Bitu INT15_Handler(void) { switch (reg_ah) { @@ -170,14 +190,19 @@ static Bitu INT15_Handler(void) { break; case 0x83: /* BIOS - SET EVENT WAIT INTERVAL */ { - if (mem_readb(BIOS_WAIT_FLAG_ACTIVE)) break; - Bit32s count=(reg_cx<<16)|reg_dx; - if (count<1000) count=1000; + if (mem_readb(BIOS_WAIT_FLAG_ACTIVE)) { + reg_ah=0x80; + CALLBACK_SCF(true); + break; + } + Bit32u count=(reg_cx<<16)|reg_dx; mem_writed(BIOS_WAIT_FLAG_POINTER,RealMake(SegValue(es),reg_bx)); mem_writed(BIOS_WAIT_FLAG_COUNT,count); mem_writeb(BIOS_WAIT_FLAG_ACTIVE,1); - PIC_RemoveEvents(&WaitFlagEvent); - PIC_AddEvent(&WaitFlagEvent,count); + /* Reprogram RTC to start */ + IO_Write(0x70,0xb); + IO_Write(0x71,IO_Read(0x71)|0x40); + CALLBACK_SCF(false); } break; case 0x84: /* BIOS - JOYSTICK SUPPORT (XT after 11/8/82,AT,XT286,PS) */ @@ -214,7 +239,10 @@ static Bitu INT15_Handler(void) { CALLBACK_SCF(false); } case 0x88: /* SYSTEM - GET EXTENDED MEMORY SIZE (286+) */ - reg_ax=0; + IO_Write(0x70,0x30); + reg_al=IO_Read(0x71); + IO_Write(0x70,0x31); + reg_ah=IO_Read(0x71); CALLBACK_SCF(false); break; case 0x90: /* OS HOOK - DEVICE BUSY */ @@ -297,6 +325,10 @@ void BIOS_Init(Section* sec) { call_int1c=CALLBACK_Allocate(); CALLBACK_Setup(call_int1c,&INT1C_Handler,CB_IRET); RealSetVec(0x1C,CALLBACK_RealPointer(call_int1c)); + /* IRQ 8 RTC Handler */ + call_int70=CALLBACK_Allocate(); + CALLBACK_Setup(call_int70,&INT70_Handler,CB_IRET); + RealSetVec(0x70,CALLBACK_RealPointer(call_int70)); /* Some defeault CPU error interrupt handlers */ call_int1=CALLBACK_Allocate(); From 6d4a305923182010ad91d2dd1d9b60b69fbb1966 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 27 Apr 2003 07:06:20 +0000 Subject: [PATCH 0884/4131] Support for reading out time/date using hosts time. Support for reading out extended memory size. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@964 --- src/hardware/cmos.cpp | 69 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 0b113e8a..b28b1494 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -16,16 +16,18 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include + #include "dosbox.h" #include "timer.h" #include "pic.h" #include "inout.h" -#include "config.h" +#include "mem.h" static struct { - Bit8u regs[0x40]; bool nmi; + bool bcd; Bit8u reg; struct { bool enabled; @@ -35,7 +37,6 @@ static struct { Bit8u status_c; bool ack; bool update_ended; - } cmos; static void cmos_timerevent(void) { @@ -64,17 +65,21 @@ void cmos_selreg(Bit32u port,Bit8u val) { static void cmos_writereg(Bit32u port,Bit8u val) { switch (cmos.reg) { case 0x00: /* Seconds */ - case 0x01: /* Seconds Alarm */ case 0x02: /* Minutes */ - case 0x03: /* Minutes Alarm */ case 0x04: /* Hours */ - case 0x05: /* Hours Alarm */ case 0x06: /* Day of week */ case 0x07: /* Date of month */ case 0x08: /* Month */ case 0x09: /* Year */ + /* Ignore writes to change alarm */ + break; + case 0x01: /* Seconds Alarm */ + case 0x03: /* Minutes Alarm */ + case 0x05: /* Hours Alarm */ + LOG(LOG_BIOS,"CMOS:Trying to set alarm"); cmos.regs[cmos.reg]=val; break; + case 0x0a: /* Status reg A */ cmos.regs[cmos.reg]=val & 0x7f; if (val & 0x70!=0x20) LOG(LOG_ERROR|LOG_BIOS,"CMOS Illegal 22 stage divider value"); @@ -82,30 +87,71 @@ static void cmos_writereg(Bit32u port,Bit8u val) { cmos_checktimer(); break; case 0x0b: /* Status reg B */ + cmos.bcd=!(val & 0x4); cmos.regs[cmos.reg]=val & 0x7f; cmos.timer.enabled=(val & 0x40)>0; if (val&0x10) LOG(LOG_ERROR|LOG_BIOS,"CMOS:Updated ended interrupt not supported yet"); cmos_checktimer(); break; + case 0x0f: /* Shutdown status byte */ + cmos.regs[cmos.reg]=val & 0x7f; + break; default: cmos.regs[cmos.reg]=val & 0x7f; -// LOG(LOG_ERROR|LOG_BIOS,"CMOS:WRite to unhandled register %x",cmos.reg); + LOG(LOG_ERROR|LOG_BIOS,"CMOS:WRite to unhandled register %x",cmos.reg); } } + +#define MAKE_RETURN(_VAL) (cmos.bcd ? (((_VAL / 10) << 4) | (_VAL % 10)) : _VAL); + static Bit8u cmos_readreg(Bit32u port) { if (cmos.reg>0x3f) { LOG(LOG_ERROR|LOG_BIOS,"CMOS:Read from illegal register %x",cmos.reg); return 0xff; } + time_t curtime; + struct tm *loctime; + + /* Get the current time. */ + curtime = time (NULL); + + /* Convert it to local time representation. */ + loctime = localtime (&curtime); + switch (cmos.reg) { + case 0x00: /* Seconds */ + return MAKE_RETURN(loctime->tm_sec); + case 0x02: /* Minutes */ + return MAKE_RETURN(loctime->tm_min); + case 0x04: /* Hours */ + return MAKE_RETURN(loctime->tm_hour); + case 0x06: /* Day of week */ + return MAKE_RETURN(loctime->tm_wday); + case 0x07: /* Date of month */ + return MAKE_RETURN(loctime->tm_mday); + case 0x08: /* Month */ + return MAKE_RETURN(loctime->tm_mon); + case 0x09: /* Year */ + return MAKE_RETURN(loctime->tm_year); + case 0x01: /* Seconds Alarm */ + case 0x03: /* Minutes Alarm */ + case 0x05: /* Hours Alarm */ + return cmos.regs[cmos.reg]; case 0x0c: if (cmos.ack) return 0; else { cmos.ack=true; return 0x80|cmos.status_c; } + case 0x0f: /* Shutdown status byte */ + case 0x17: /* Extended memory in KB Low Byte */ + case 0x18: /* Extended memory in KB High Byte */ + case 0x30: /* Extended memory in KB Low Byte */ + case 0x31: /* Extended memory in KB High Byte */ + return cmos.regs[cmos.reg]; default: + LOG(LOG_BIOS,"CMOS:Read from reg %F",cmos.reg); return cmos.regs[cmos.reg]; } } @@ -117,6 +163,13 @@ void CMOS_Init(Section* sec) { cmos.timer.enabled=false; cmos.reg=0xa; cmos_writereg(0x71,0x26); - + cmos.reg=0xb; + cmos_writereg(0x71,0); + /* Fill in extended memory size */ + Bitu exsize=MEM_TotalSize()-1024; + cmos.regs[0x17]=(Bit8u)exsize; + cmos.regs[0x18]=(Bit8u)(exsize >> 8); + cmos.regs[0x30]=(Bit8u)exsize; + cmos.regs[0x31]=(Bit8u)(exsize >> 8); } From 1663e758b062e61ab4f11537c181062549f17c53 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 27 Apr 2003 07:06:44 +0000 Subject: [PATCH 0885/4131] Added a total memory size call. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@965 --- src/hardware/memory.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 208b6ca2..075b388a 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -31,6 +31,7 @@ HostPt WriteHostTable[MAX_PAGES]; MEMORY_ReadHandler ReadHandlerTable[MAX_PAGES]; MEMORY_WriteHandler WriteHandlerTable[MAX_PAGES]; +static Bitu total_size; /* Page handlers only work in lower memory */ #define LOW_PAGE_LIMIT PAGE_COUNT(1024*1024) @@ -245,6 +246,10 @@ void MEM_A20_Enable(bool enable) { LOG(LOG_MISC,"A20 Line is %s",enable ? "Enabled" : "Disabled"); } +Bitu MEM_TotalSize(void) { + return total_size; +} + static void write_p92(Bit32u port,Bit8u val) { // Bit 0 = system reset (switch back to real mode) if (val&1) E_Exit("XMS: CPU reset via port 0x92 not supported."); @@ -273,6 +278,7 @@ void MEM_Init(Section * sec) { LOG_MSG("Maximum memory size is %d MB",C_MEM_MAX_SIZE-1); memsize=C_MEM_MAX_SIZE-1; } + total_size=memsize*1024; memory=(Bit8u *)malloc(memsize*1024*1024+64*1024); if (!memory) { throw("Can't allocate memory for memory"); From 52243ceaa477e05e456e8637acf7b450463e34e5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 27 Apr 2003 07:07:30 +0000 Subject: [PATCH 0886/4131] Added total memory size call Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@966 --- include/mem.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/mem.h b/include/mem.h index b3d5a5b2..9c8e5c6b 100644 --- a/include/mem.h +++ b/include/mem.h @@ -46,7 +46,6 @@ INLINE Bit16u PAGES(Bit32u bytes) { return (Bit16u)(1+(bytes>>12)); } - void MEM_SetupPageHandlers(Bitu startpage,Bitu pages,MEMORY_ReadHandler read,MEMORY_WriteHandler write); void MEM_ClearPageHandlers(Bitu startpage,Bitu pages); @@ -56,6 +55,8 @@ void MEM_ClearMapping(Bitu startpage,Bitu pages); bool MEM_A20_Enabled(void); void MEM_A20_Enable(bool enable); +Bitu MEM_TotalSize(void); //Memory size in KB + extern HostPt memory; /* From 12aee4bb55c22a46a0a386143abfabbda1588fbd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 27 Apr 2003 07:08:47 +0000 Subject: [PATCH 0887/4131] Unmask RTC irq 8 by default. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@967 --- src/hardware/pic.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 814d3bfe..f23f8fd4 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -412,6 +412,7 @@ void PIC_Init(Section* sec) { } irqs[0].masked=false; /* Enable system timer */ irqs[1].masked=false; /* Enable Keyboard IRQ */ + irqs[8].masked=false; /* Enable RTC IRQ */ irqs[12].masked=false; /* Enable Mouse IRQ */ IO_RegisterReadHandler(0x20,read_command,"Master PIC Command"); IO_RegisterReadHandler(0x21,read_data,"Master PIC Data"); From 1f6f13672004fba16da454b9099ff20bf00418a3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 27 Apr 2003 11:43:34 +0000 Subject: [PATCH 0888/4131] Save start of an opcode. Decrease cycles after the opcode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@968 --- src/cpu/core_full.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 7b4d9753..3d917e05 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -62,7 +62,7 @@ Bitu Full_DeCode(void) { if (DEBUG_HeavyIsBreakpoint()) return 1; #endif #endif - CPU_Cycles--; + inst.start=IPPoint; inst.entry=cpu.full.entry; inst.prefix=cpu.full.prefix; restartopcode: @@ -73,6 +73,7 @@ restartopcode: #include "core_full/op.h" #include "core_full/save.h" nextopcode:; + CPU_Cycles--; } SaveIP(); return 0; From 47228f94b62cc5bb5d1197033613586393b163bc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 27 Apr 2003 11:44:47 +0000 Subject: [PATCH 0889/4131] Allow interrupting of non flag changing string operations. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@969 --- src/cpu/core_full/string.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index b1079e85..50e805da 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -2,7 +2,7 @@ EAPoint si_base,di_base; Bitu si_index,di_index; Bitu add_mask; - Bitu count,count_max; + Bitu count,count_left; Bits add_index; bool restart=false; @@ -22,8 +22,19 @@ } if (!(inst.prefix & PREFIX_REP)) { count=1; + } else { + /* Calculate amount of ops to do before cycles run out */ + if ((count>CPU_Cycles) && (inst.code.op Date: Sun, 27 Apr 2003 11:45:09 +0000 Subject: [PATCH 0890/4131] New variable for start of opcode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@970 --- src/cpu/core_full/support.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 895cb90c..995f56c1 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -153,7 +153,7 @@ struct OpCode { static struct { Bitu entry; - Bitu entry_default; + EAPoint start; Bitu rm; EAPoint rm_eaa; Bitu rm_off; From 98192874896b99167995b15f7e369968dd8f658e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 27 Apr 2003 13:21:35 +0000 Subject: [PATCH 0891/4131] IOCTL Call 9 handled somewhat. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@971 --- src/dos/dos_ioctl.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 2bcda42b..77ddaba6 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -58,6 +58,17 @@ bool DOS_IOCTL(void) { DOS_SetError(DOSERR_INVALID_DRIVE); return false; } + case 0x09: /* Check if block device remote */ + drive=reg_bl;if (!drive) drive=dos.current_drive;else drive--; + if (Drives[drive]) { + reg_dx=0; + //TODO Cdrom drives are remote + //TODO Set bit 9 on drives that don't support direct I/O + return true; + } else { + DOS_SetError(DOSERR_INVALID_DRIVE); + return false; + } case 0x0D: /* Generic block device request */ { PhysPt ptr = SegPhys(ds)+reg_dx; From 657e5e5806cc713d4f33914cc5bd0b94c1d533ca Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 1 May 2003 11:47:29 +0000 Subject: [PATCH 0892/4131] added backspace hack from Max Horn #708184 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@972 --- src/gui/sdlmain.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 7aeda676..d191b371 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -406,6 +406,12 @@ static void HandleKey(SDL_KeyboardEvent * key) { ((key->keysym.mod & KMOD_ALT) ? KBD_MOD_ALT : 0) | ((key->keysym.mod & KMOD_SHIFT) ? KBD_MOD_SHIFT : 0); Bitu ascii=key->keysym.unicode<128 ? key->keysym.unicode : 0; +#ifdef MACOSX + // HACK: Fix backspace on Mac OS X + // REMOVE ME oneday + if (code==KBD_backspace) + ascii=8; +#endif KEYBOARD_AddKey(code,ascii,mod,(key->state==SDL_PRESSED)); } From 787a0c941a5d268e97e38001fb6beb5ad8bad34c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 1 May 2003 12:59:53 +0000 Subject: [PATCH 0893/4131] Fixed double shift's Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@973 --- src/cpu/core_full/op.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index e3ebfd88..7e6a7578 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -129,22 +129,22 @@ switch (inst.code.op) { case O_DSHLw: { - DSHLW(inst.op1.w,inst.op2.w,inst.imm.b,,LoadD,SaveD); + DSHLW(inst.op1.w,inst.op2.w,inst.imm.b,LoadD,SaveD); break; } case O_DSHRw: { - DSHRW(inst.op1.w,inst.op2.w,inst.imm.b,,LoadD,SaveD); + DSHRW(inst.op1.w,inst.op2.w,inst.imm.b,LoadD,SaveD); break; } case O_DSHLd: { - DSHLD(inst.op1.d,inst.op2.d,inst.imm.b,,LoadD,SaveD); + DSHLD(inst.op1.d,inst.op2.d,inst.imm.b,LoadD,SaveD); break; } case O_DSHRd: { - DSHRD(inst.op1.d,inst.op2.d,inst.imm.b,,LoadD,SaveD); + DSHRD(inst.op1.d,inst.op2.d,inst.imm.b,LoadD,SaveD); break; } From b1da749576c4fb6317124f703b9949268d24bad8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 1 May 2003 13:00:57 +0000 Subject: [PATCH 0894/4131] makefiles for core_full directory Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@974 --- src/cpu/Makefile.am | 4 ++-- src/cpu/core_full/Makefile.am | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 src/cpu/core_full/Makefile.am diff --git a/src/cpu/Makefile.am b/src/cpu/Makefile.am index 97ef51e2..e0d9fd7a 100644 --- a/src/cpu/Makefile.am +++ b/src/cpu/Makefile.am @@ -1,5 +1,5 @@ -SUBDIRS = core_16 +SUBDIRS = core_16 core_full 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 instructions.h \ No newline at end of file +libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h slow_16.cpp core_full.cpp instructions.h \ No newline at end of file diff --git a/src/cpu/core_full/Makefile.am b/src/cpu/core_full/Makefile.am new file mode 100644 index 00000000..41fbe6a2 --- /dev/null +++ b/src/cpu/core_full/Makefile.am @@ -0,0 +1,3 @@ + +noinst_HEADERS = ea_lookup.h load.h loadwrite.h op.h optable.h save.h \ + string.h support.h From 0fcfc4ac117bb75392b0e7cf9d82c4366ce1d2e2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 1 May 2003 13:01:56 +0000 Subject: [PATCH 0895/4131] Make the makefile in core_full directory Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@975 --- configure.in | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.in b/configure.in index adb4ad8c..fb355341 100644 --- a/configure.in +++ b/configure.in @@ -95,6 +95,7 @@ Makefile src/Makefile src/cpu/Makefile src/cpu/core_16/Makefile +src/cpu/core_full/Makefile src/debug/Makefile src/dos/Makefile src/fpu/Makefile From 06ab2d99bb43afb091d928f4bced7e7eb5e017b3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 1 May 2003 18:06:20 +0000 Subject: [PATCH 0896/4131] Added VERR and VERW Added BSWAP Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@976 --- src/cpu/core_full/op.h | 10 ++++++++++ src/cpu/core_full/optable.h | 16 ++++++++-------- src/cpu/core_full/support.h | 1 + 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 7e6a7578..651c01ea 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -408,6 +408,13 @@ switch (inst.code.op) { case 0x03: /* LTR */ CPU_LTR(inst.op1.d); goto nextopcode; /* Else value will saved */ + case 0x04: /* VERR */ + CPU_VERR(inst.op1.d); + goto nextopcode; /* Else value will saved */ + case 0x05: /* VERW */ + CPU_VERW(inst.op1.d); + goto nextopcode; /* Else value will saved */ + default: LOG(LOG_ERROR|LOG_CPU,"Group 6 Illegal subfunction %X",inst.rm_index); @@ -528,6 +535,9 @@ switch (inst.code.op) { } } break; + case O_BSWAP: + BSWAP(inst.op1.d); + break; case 0: break; default: diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 83bf1dcb..7999ef97 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -320,10 +320,10 @@ static OpCode OpCodeTable[1024]={ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x1c8 - 0x1cf */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_REGd ,O_BSWAP ,S_REGd ,REGI_AX},{L_REGd ,O_BSWAP ,S_REGd ,REGI_CX}, +{L_REGd ,O_BSWAP ,S_REGd ,REGI_DX},{L_REGd ,O_BSWAP ,S_REGd ,REGI_BX}, +{L_REGd ,O_BSWAP ,S_REGd ,REGI_SP},{L_REGd ,O_BSWAP ,S_REGd ,REGI_BP}, +{L_REGd ,O_BSWAP ,S_REGd ,REGI_SI},{L_REGd ,O_BSWAP ,S_REGd ,REGI_DI}, /* 0x1d0 - 0x1d7 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, @@ -678,10 +678,10 @@ static OpCode OpCodeTable[1024]={ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x3c8 - 0x3cf */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_REGd ,O_BSWAP ,S_REGd ,REGI_AX},{L_REGd ,O_BSWAP ,S_REGd ,REGI_CX}, +{L_REGd ,O_BSWAP ,S_REGd ,REGI_DX},{L_REGd ,O_BSWAP ,S_REGd ,REGI_BX}, +{L_REGd ,O_BSWAP ,S_REGd ,REGI_SP},{L_REGd ,O_BSWAP ,S_REGd ,REGI_BP}, +{L_REGd ,O_BSWAP ,S_REGd ,REGI_SI},{L_REGd ,O_BSWAP ,S_REGd ,REGI_DI}, /* 0x3d0 - 0x3d7 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 995f56c1..abaa6143 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -89,6 +89,7 @@ enum { O_BTd,O_BTSd,O_BTRd,O_BTCd, O_BSFw,O_BSRw, + O_BSWAP, }; From 82c7fc40211d312820874659252d06fdd65758c3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 1 May 2003 18:08:57 +0000 Subject: [PATCH 0897/4131] Added VERR and VERW Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@977 --- include/cpu.h | 3 +++ src/cpu/cpu.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 521da441..4b55a912 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -90,6 +90,9 @@ Bitu CPU_GET_CRX(Bitu cr); void CPU_SMSW(Bitu & word); bool CPU_LMSW(Bitu word); +void CPU_VERR(Bitu selector); +void CPU_VERW(Bitu selector); + bool CPU_JMP(bool use32,Bitu selector,Bitu offset); bool CPU_CALL(bool use32,Bitu selector,Bitu offset); bool CPU_RET(bool use32,Bitu bytes); diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 2f406f6c..c60c7f40 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -96,7 +96,7 @@ PhysPt SelBase(Bitu sel) { bool CPU_CheckState(void) { cpu.state=0; - if (!cpu.cr0 & CR0_PROTECTION) { + if (!(cpu.cr0 & CR0_PROTECTION)) { cpu.full.entry=cpu.full.prefix=0; return true; } else { @@ -665,11 +665,69 @@ void CPU_LSL(Bitu selector,Bitu & limit) { SETFLAGBIT(ZF,false); return; } - cpu.gdt.GetDescriptor(selector,desc); limit=desc.GetLimit(); SETFLAGBIT(ZF,true); } +void CPU_VERR(Bitu selector) { + Descriptor desc;Bitu rpl=selector & 3; + flags.type=t_UNKNOWN; + if (!cpu.gdt.GetDescriptor(selector,desc)){ + SETFLAGBIT(ZF,false); + return; + } + if (!desc.saved.seg.p) { + SETFLAGBIT(ZF,false); + return; + } + switch (desc.Type()){ + case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: + //Conforming readable code segments can be always read + break; + case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: + case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: + case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + + case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (desc.DPL() Date: Thu, 1 May 2003 18:09:23 +0000 Subject: [PATCH 0898/4131] FLAG_VM was pointing at wrong bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@978 --- include/regs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/regs.h b/include/regs.h index d1b8db0f..5d905f4e 100644 --- a/include/regs.h +++ b/include/regs.h @@ -48,7 +48,7 @@ struct Flag_Info { #define FLAG_IOPL 0x00003000 #define FLAG_NT 0x00004000 -#define FLAG_VM 0x00040000 +#define FLAG_VM 0x00020000 #define SETFLAGBIT(TYPE,TEST) if (TEST) flags.word|=FLAG_ ## TYPE; else flags.word&=~FLAG_ ## TYPE From 672415fcb9e5af0c1105d2ef9db1a645d1431482 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 May 2003 10:51:04 +0000 Subject: [PATCH 0899/4131] fixed crashes when executing rescan on a virtual drive Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@979 --- src/dos/drives.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dos/drives.h b/src/dos/drives.h index db882261..52ddad8f 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -94,6 +94,7 @@ public: bool FileExists(const char* name); bool FileStat(const char* name, FileStat_Block* const stat_block); Bit8u GetMediaByte(void); + void EmptyCache(void){} private: VFILE_Block * search_file; }; From 100f13016e36aa02aada446d17de1f2106701bd8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 May 2003 10:54:31 +0000 Subject: [PATCH 0900/4131] added support for the don't inheritance flag and changed the psp routines to use this flag Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@980 --- include/dos_inc.h | 5 +++-- include/dos_system.h | 4 ++-- src/dos/dos.cpp | 2 +- src/dos/dos_classes.cpp | 18 ++++++++++++++++-- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 1b91e545..8bee9a96 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -125,6 +125,7 @@ void DOS_SetupDevices(void); /* Execute and new process creation */ bool DOS_NewPSP(Bit16u pspseg,Bit16u size); +bool DOS_ChildPSP(Bit16u pspseg,Bit16u size); bool DOS_Execute(char * name,PhysPt block,Bit8u flags); bool DOS_Terminate(bool tsr); @@ -237,7 +238,7 @@ class DOS_PSP :public MemStruct { public: DOS_PSP (Bit16u segment) { SetPt(segment);seg=segment;psp=(sPSP *)HostMake(segment,0);}; void MakeNew (Bit16u memSize); - void CopyFileTable (DOS_PSP* srcpsp); + void CopyFileTable (DOS_PSP* srcpsp,bool createchildpsp); Bit16u FindFreeFileEntry (void); void CloseFiles (void); @@ -263,7 +264,7 @@ public: void SetCommandTail (RealPt src); bool SetNumFiles (Bit16u fileNum); Bit16u FindEntryByHandle (Bit8u handle); - + private: #ifdef _MSC_VER #pragma pack(1) diff --git a/include/dos_system.h b/include/dos_system.h index f0878ac2..1a333eaf 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -51,7 +51,7 @@ class DOS_DTA; class DOS_File { public: - DOS_File() { name=0; }; + DOS_File():flags(0) { name=0; }; virtual ~DOS_File(){}; virtual bool Read(Bit8u * data,Bit16u * size)=0; virtual bool Write(Bit8u * data,Bit16u * size)=0; @@ -220,7 +220,7 @@ public: DOS_Drive_Cache dirCache; }; -enum { OPEN_READ=0,OPEN_WRITE=1,OPEN_READWRITE=2 }; +enum { OPEN_READ=0,OPEN_WRITE=1,OPEN_READWRITE=2, DOS_NOT_INHERIT=128}; enum { DOS_SEEK_SET=0,DOS_SEEK_CUR=1,DOS_SEEK_END=2}; diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index b351b32c..f05a7f9b 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -666,7 +666,7 @@ static Bitu DOS_21Handler(void) { reg_al=dos.verify?1:0; break; case 0x55: /* Create Child PSP*/ - DOS_NewPSP(reg_dx,reg_si); + DOS_ChildPSP(reg_dx,reg_si); dos.psp = reg_dx; break; case 0x56: /* RENAME Rename file */ diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 815d2ca7..dce39fbe 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -156,12 +156,26 @@ Bit16u DOS_PSP::FindEntryByHandle(Bit8u handle) return 0xFF; }; -void DOS_PSP::CopyFileTable(DOS_PSP* srcpsp) +void DOS_PSP::CopyFileTable(DOS_PSP* srcpsp,bool createchildpsp) { /* Copy file table from calling process */ for (Bit16u i=0;i<20;i++) { Bit8u handle = srcpsp->GetFileHandle(i); - SetFileHandle(i,handle); + if(createchildpsp) + { //copy obeying not inherit flag. + if(Files[handle] && !(Files[handle]->flags & DOS_NOT_INHERIT)) + { + SetFileHandle(i,handle); + } + else + { + SetFileHandle(i,0xff); + } + } + else + { //normal copy so don't mind the inheritance + SetFileHandle(i,handle); + } } }; From cb364036b2c68fa40f878ec14a15bcd6a97c591b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 May 2003 11:01:22 +0000 Subject: [PATCH 0901/4131] added support for the don't inheritance flag and changed the psp routines to use this flag Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@981 --- src/dos/dos_execute.cpp | 26 +++++++++++++++++++------- src/dos/dos_files.cpp | 12 +++++------- src/dos/drive_local.cpp | 4 +++- src/dos/drive_virtual.cpp | 1 + 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index e5bbe898..e5149fb3 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -95,11 +95,12 @@ bool DOS_Terminate(bool tsr) { dos.return_mode=RETURN_EXIT; Bit16u mempsp = dos.psp; + DOS_PSP curpsp(dos.psp); if (dos.psp==curpsp.GetParent()) return true; - /* Free Files owned by process */ - if (!tsr) curpsp.CloseFiles(); + if (!tsr) curpsp.CloseFiles(); + /* Get the termination address */ RealPt old22 = curpsp.GetInt22(); /* Restore vector 22,23,24 */ @@ -173,10 +174,18 @@ bool DOS_NewPSP(Bit16u segment, Bit16u size) DOS_PSP psp(segment); psp.MakeNew(size); DOS_PSP psp_parent(psp.GetParent()); - psp.CopyFileTable(&psp_parent); + psp.CopyFileTable(&psp_parent,false); return true; }; +bool DOS_ChildPSP(Bit16u segment, Bit16u size) +{ + DOS_PSP psp(segment); + psp.MakeNew(size); + DOS_PSP psp_parent(psp.GetParent()); + psp.CopyFileTable(&psp_parent,true); + return true; +}; static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { /* Fix the PSP for psp and environment MCB's */ @@ -188,11 +197,11 @@ static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { DOS_PSP psp(pspseg); psp.MakeNew(memsize); psp.SetEnvironment(envseg); - /* Copy file handles */ - if (DOS_PSP::rootpsp!=dos.psp) { + /* Copy file handles //QBIX::ALWAYS COPY BUT LEFT ORIGINAL INCASE OF MISTAKES +/* if (DOS_PSP::rootpsp!=dos.psp) { */ // TODO: Improve this // If prog wasnt started from commandline copy file table (California Games 2) - DOS_PSP oldpsp(dos.psp); +/* DOS_PSP oldpsp(dos.psp); psp.CopyFileTable(&oldpsp); } else { psp.SetFileHandle(STDIN ,DOS_FindDevice("CON")); @@ -201,8 +210,11 @@ static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { psp.SetFileHandle(STDAUX,DOS_FindDevice("CON")); psp.SetFileHandle(STDNUL,DOS_FindDevice("CON")); psp.SetFileHandle(STDPRN,DOS_FindDevice("CON")); - } + } */ /* Save old DTA in psp */ + DOS_PSP oldpsp(dos.psp); + psp.CopyFileTable(&oldpsp,true); + psp.SetDTA(dos.dta); /* Setup the DTA */ dos.dta=RealMake(pspseg,0x80); diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 956e4a64..f0d7f086 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -287,13 +287,11 @@ bool DOS_CloseFile(Bit16u entry) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; -//TODO Figure this out with devices :) - - DOS_PSP psp(dos.psp); - if (entry>STDPRN) psp.SetFileHandle(entry,0xff); - /* Devices won't allow themselves to be closed or killed */ - if (Files[handle]->Close()) { + if (Files[handle]->Close()) + { //if close succesfull => delete file/update psp + DOS_PSP psp(dos.psp); + psp.SetFileHandle(entry,0xff); delete Files[handle]; Files[handle]=0; } @@ -335,7 +333,7 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { /* First check for devices */ if (flags>2) LOG(LOG_FILES|LOG_ERROR,"Special file open command %X file %s",flags,name); else LOG(LOG_FILES,"file open command %X file %s",flags,name); - flags&=3; + DOS_PSP psp(dos.psp); Bit8u handle=DOS_FindDevice((char *)name); bool device=false;char fullname[DOS_PATHLENGTH];Bit8u drive;Bit8u i; diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index a20c3168..907d6ecf 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -55,12 +55,13 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) { dirCache.AddEntry(newname, true); /* Make the 16 bit device information */ *file=new localFile(name,hand,0x202); + return true; }; bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { char * type; - switch (flags) { + switch (flags &3) { case OPEN_READ:type="rb"; break; case OPEN_WRITE:type="rb+"; break; case OPEN_READWRITE:type="rb+"; break; @@ -80,6 +81,7 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { // Bit32u err=errno; if (!hand) return false; *file=new localFile(name,hand,0x202); + (*file)->flags=flags; //for the inheritance flag and maybe check for others. // (*file)->SetFileName(newname); return true; }; diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 5243d477..dd080048 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -132,6 +132,7 @@ bool Virtual_Drive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { if (strcasecmp(name,cur_file->name)==0) { /* We have a match */ *file=new Virtual_File(cur_file->data,cur_file->size); + (*file)->flags=flags; return true; } cur_file=cur_file->next; From 51b1d83a6dd58452418281c887844472411f6540 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 May 2003 11:02:05 +0000 Subject: [PATCH 0902/4131] added support for the don't inheritance flag and changed the psp routines to use this flag Opening batfiles with the don't inheritance flag Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@982 --- src/shell/shell_batch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 304f5987..2c256483 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -27,7 +27,7 @@ BatchFile::BatchFile(DOS_Shell * host,char * name, char * cmd_line) { echo=host->echo; shell=host; cmd=new CommandLine(0,cmd_line); - if (!DOS_OpenFile(name,0,&file_handle)) { + if (!DOS_OpenFile(name,128,&file_handle)) { //TODO Come up with something better E_Exit("SHELL:Can't open BatchFile"); } From 34c95efc05efeddb44f0445a9e7c8913a78ed7ae Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 May 2003 11:33:35 +0000 Subject: [PATCH 0903/4131] fixed return value of findfirst Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@983 --- src/dos/dos_files.cpp | 3 +-- src/dos/drive_local.cpp | 7 ++++++- src/dos/drive_virtual.cpp | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index f0d7f086..fcb583b0 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -206,14 +206,13 @@ bool DOS_FindFirst(char * search,Bit16u attr) { } dta.SetupSearch(drive,(Bit8u)attr,pattern); if (Drives[drive]->FindFirst(dir,dta)) return true; - DOS_SetError(DOSERR_NO_MORE_FILES); + return false; } bool DOS_FindNext(void) { DOS_DTA dta(dos.dta); if (Drives[dta.GetSearchDrive()]->FindNext(dta)) return true; - DOS_SetError(DOSERR_NO_MORE_FILES); return false; } diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 907d6ecf..3e3a3ebf 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -110,7 +110,11 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { if (tempDir[strlen(tempDir)-1]!=CROSS_FILESPLIT) strcat(tempDir,end); Bit16u id; - if (!dirCache.OpenDir(tempDir,id)) return false; + if (!dirCache.OpenDir(tempDir,id)) + { + DOS_SetError(DOSERR_PATH_NOT_FOUND); + return false; + } strcpy(srchInfo[id].srch_dir,tempDir); dta.SetDirID(id); @@ -139,6 +143,7 @@ bool localDrive::FindNext(DOS_DTA & dta) { again: if (!dirCache.ReadDir(id,dir_ent)) { + DOS_SetError(DOSERR_NO_MORE_FILES); return false; } diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index dd080048..3d0cb9de 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -200,6 +200,7 @@ bool Virtual_Drive::FindNext(DOS_DTA & dta) { } search_file=search_file->next; } + DOS_SetError(DOSERR_NO_MORE_FILES); return false; } From b0906a8ed9498b822fb4376f019a8b0bb5624cab Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 4 May 2003 12:44:26 +0000 Subject: [PATCH 0904/4131] added basic support for vidmode 0x7 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@984 --- src/hardware/vga_draw.cpp | 3 ++- src/ints/int10_char.cpp | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 055cefdb..337d04d0 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -101,7 +101,8 @@ void VGA_DrawGFX256U_Fast(Bit8u * bitdata,Bitu next_line) { } void VGA_DrawTEXT(Bit8u * bitdata,Bitu pitch) { - Bit8u * reader=HostMake(0xB800,0); + + Bit8u * reader=HostMake((vga.gfx.miscellaneous & 0x4 ?0xB800:0xB000),0); Bit8u * draw_start=bitdata; /* Todo Blinking and high intensity colors */ for (Bitu cy=0;cy<(vga.draw.height/16);cy++) { diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index abb7d0d7..d2406086 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -242,9 +242,10 @@ INLINE static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u at // Compute the address Bit16u address=SCREEN_MEM_START(curmode->twidth,curmode->theight,page)+(col+row*curmode->twidth)*2; // Write the char - real_writeb(0xb800,address,chr); + Bit16u segment = curmode->sstart; + real_writeb(segment,address,chr); if (useattr) { - real_writeb(0xb800,address+1,attr); + real_writeb(segment,address+1,attr); } } break; From 5bc559f1c4680f274f7cef318e2b1fd4696630d6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 4 May 2003 19:03:28 +0000 Subject: [PATCH 0905/4131] included local cross.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@985 --- include/setup.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/setup.h b/include/setup.h index b34a9b41..0aa9bb46 100644 --- a/include/setup.h +++ b/include/setup.h @@ -23,7 +23,7 @@ #pragma warning ( disable : 4786 ) #endif -#include +#include "cross.h" #include #include From a336b5d7cc2067a609617c21014087e753bebb99 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 4 May 2003 19:09:16 +0000 Subject: [PATCH 0906/4131] added logging.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@986 --- include/Makefile.am | 1 + include/dosbox.h | 23 ++++----------- include/logging.h | 69 +++++++++++++++++++++++++++++++++++++++++++++ visualc/dosbox.dsp | 5 ++++ 4 files changed, 80 insertions(+), 18 deletions(-) create mode 100644 include/logging.h diff --git a/include/Makefile.am b/include/Makefile.am index 4425e6ed..2e395d13 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -13,6 +13,7 @@ hardware.h \ inout.h \ joystick.h \ keyboard.h \ +logging.h \ mem.h \ mixer.h \ modules.h \ diff --git a/include/dosbox.h b/include/dosbox.h index 03205ec0..6d0696a6 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -63,25 +63,12 @@ class Config; extern Config * control; extern Bitu errorlevel; + +#ifndef __LOGGING_H_ +#include "logging.h" +#endif // the logging system. + #define LOG_MSG S_Warn -enum LOG_TYPES { - LOG_ALL, - LOG_VGA, LOG_VGAGFX,LOG_VGAMISC,LOG_INT10, - LOG_SB,LOG_DMA, - LOG_FPU,LOG_CPU, - LOG_FCB,LOG_FILES,LOG_IOCTL,LOG_EXEC,LOG_DOSMISC, - LOG_PIT,LOG_KEYBOARD,LOG_PIC, - LOG_MOUSE,LOG_BIOS,LOG_GUI,LOG_MISC, - LOG_MAX,LOG_ERROR=0x80 -}; - -#if C_DEBUG -extern void DEBUG_ShowMsg(Bit32u msgmask, char * msg,...); -#define LOG DEBUG_ShowMsg -#else -#define LOG -#endif /* C_DEBUG */ - #endif /* __DOSBOX_H */ diff --git a/include/logging.h b/include/logging.h new file mode 100644 index 00000000..9821ee50 --- /dev/null +++ b/include/logging.h @@ -0,0 +1,69 @@ +#ifndef __LOGGING_H_ +#define __LOGGING_H_ +enum LOG_TYPES { + LOG_ALL, + LOG_VGA, LOG_VGAGFX,LOG_VGAMISC,LOG_INT10, + LOG_SB,LOG_DMA, + LOG_FPU,LOG_CPU, + LOG_FCB,LOG_FILES,LOG_IOCTL,LOG_EXEC,LOG_DOSMISC, + LOG_PIT,LOG_KEYBOARD,LOG_PIC, + LOG_MOUSE,LOG_BIOS,LOG_GUI,LOG_MISC, + LOG_MAX +}; + +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* buf, ...); //../src/debug/debug_gui.cpp + +}; + + +#else //C_DEBUG + +struct LOG +{ + LOG(LOG_TYPES type, LOG_SEVERITIES severity) { return;} + void operator()(char* buf) { return;} + void operator()(char* buf, double f1) { return;} + void operator()(char* buf, double f1, Bit32u u1) { return;} + void operator()(char* buf, Bitu u1, double f1) { return;} + + void operator()(char* buf, Bitu u1, Bitu u2) { return;} + void operator()(char* buf, Bits u1, Bits u2) { return;} + void operator()(char* buf, Bitu u1, Bits u2) { return;} + void operator()(char* buf, Bits u1, Bitu u2) { return;} + void operator()(char* buf, Bit32s u1) { return;} + void operator()(char* buf, Bit32u u1) { return;} + void operator()(char* buf, Bits s1) { return;} + void operator()(char* buf, Bitu u1) { return;} + + void operator()(char* buf, char* s1) { return;} + void operator()(char* buf, char* s1, Bit32u u1) { return;} + void operator()(char* buf, char* s1, Bit32u u1, Bit32u u2) { return;} + void operator()(char* buf, Bit32u u1, char* s1) { return;} + + + +}; //add missing operators to here + //try to avoid anything smaller than bit32... + +#endif //C_DEBUG + + +#endif //__LOGGING_H_ + diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index a901901d..be93b060 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -20,6 +20,7 @@ CFG=dosbox - Win32 Debug !MESSAGE "dosbox - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "dosbox - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE + # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" @@ -711,6 +712,10 @@ SOURCE=..\include\keyboard.h # End Source File # Begin Source File +SOURCE=..\include\logging.h +# End Source File +# Begin Source File + SOURCE=..\include\mem.h # End Source File # Begin Source File From c9b747adc43247f22ef398b5c4dec23200df366d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 4 May 2003 19:12:09 +0000 Subject: [PATCH 0907/4131] new logging system Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@987 --- src/cpu/callback.cpp | 2 +- src/cpu/core_16/main.h | 4 ++-- src/cpu/core_16/prefix_66.h | 2 +- src/cpu/core_16/prefix_of.h | 4 ++-- src/cpu/core_16/support.h | 2 +- src/cpu/core_full/load.h | 8 ++++---- src/cpu/core_full/loadwrite.h | 2 +- src/cpu/core_full/op.h | 6 +++--- src/cpu/core_full/save.h | 2 +- src/cpu/core_full/string.h | 4 ++-- src/cpu/cpu.cpp | 14 +++++++------- src/cpu/flags.cpp | 12 ++++++------ src/cpu/slow_16.cpp | 2 +- src/debug/debug.cpp | 2 ++ src/debug/debug_gui.cpp | 12 +++++++++++- 15 files changed, 45 insertions(+), 33 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index fcdd049a..cf8b77cf 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -67,7 +67,7 @@ void CALLBACK_Idle(void) { } static Bitu default_handler(void) { - LOG(LOG_ERROR|LOG_CPU,"Illegal Unhandled Interrupt Called %X",lastint); + LOG(LOG_CPU,LOG_ERROR)("Illegal Unhandled Interrupt Called %X",lastint); return CBRET_NONE; }; diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 381c0e81..44538829 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -880,7 +880,7 @@ restart: case 0xde: /* FPU ESC 6 */ case 0xdf: /* FPU ESC 7 */ { - LOG(LOG_CPU,"FPU used"); + LOG(LOG_CPU,LOG_NORMAL)("FPU used"); Bit8u rm=Fetchb(); if (rm<0xc0) GetEAa; } @@ -956,7 +956,7 @@ restart: IO_Write(reg_dx+1,reg_ah); break; case 0xf0: /* LOCK */ - LOG(LOG_CPU,"CPU:LOCK"); + LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK"); break; case 0xf1: /* Weird call undocumented */ // INTERRUPT(1); diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index b24339fa..0e30f431 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -258,7 +258,7 @@ switch(Fetchb()) { break; } case 0x8c: - LOG(LOG_CPU,"CPU:66:8c looped back"); + LOG(LOG_CPU,LOG_NORMAL)("CPU:66:8c looped back"); break; case 0x8d: /* LEA */ { diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h index 61ad2a3c..750e0dc2 100644 --- a/src/cpu/core_16/prefix_of.h +++ b/src/cpu/core_16/prefix_of.h @@ -41,7 +41,7 @@ switch(Fetchb()) { break; default: GetEAa; - LOG(LOG_CPU|LOG_ERROR,"GRP7:Illegal call %2X",(rm>>3) &3); + LOG(LOG_CPU,LOG_ERROR)("GRP7:Illegal call %2X",(rm>>3) &3); } } break; @@ -63,7 +63,7 @@ switch(Fetchb()) { case 0x23: /* MOV DRx,Rd */ { GetRM; - LOG(LOG_CPU,"CPU:0F:23 does nothing"); + LOG(LOG_CPU,LOG_NORMAL)("CPU:0F:23 does nothing"); } break; /* 0x24 MOV Rd,TRx (386) */ diff --git a/src/cpu/core_16/support.h b/src/cpu/core_16/support.h index 2ec79b49..9bc6686d 100644 --- a/src/cpu/core_16/support.h +++ b/src/cpu/core_16/support.h @@ -395,7 +395,7 @@ rep_again: break; default: IPPoint--; - LOG(LOG_CPU|LOG_ERROR,"Unhandled REP Prefix %X",Fetchb()); + LOG(LOG_CPU,LOG_ERROR)("Unhandled REP Prefix %X",Fetchb()); goto normalexit; } /* If we end up here it's because the CPU_Cycles counter is 0, so restart instruction */ diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index b6ba9938..2dfbfbd2 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -114,7 +114,7 @@ l_M_Ed: break; case M_Efw: if (inst.rm>=0xC0) { - LOG(LOG_CPU|LOG_ERROR,"MODRM:Illegal M_Efw "); + LOG(LOG_CPU,LOG_ERROR)("MODRM:Illegal M_Efw "); goto nextopcode; } inst.op1.d=LoadMw(inst.rm_eaa); @@ -122,7 +122,7 @@ l_M_Ed: break; case M_Efd: if (inst.rm>=0xc0) { - LOG(LOG_CPU|LOG_ERROR,"MODRM:Illegal M_Efw "); + LOG(LOG_CPU,LOG_ERROR)("MODRM:Illegal M_Efw "); goto nextopcode; } inst.op1.d=LoadMd(inst.rm_eaa); @@ -157,7 +157,7 @@ l_M_Ed: case 0: break; default: - LOG(LOG_CPU|LOG_ERROR,"MODRM:Unhandled load %d entry %x",inst.code.extra,inst.entry); + LOG(LOG_CPU,LOG_ERROR)("MODRM:Unhandled load %d entry %x",inst.code.extra,inst.entry); break; } break; @@ -469,7 +469,7 @@ l_M_Ed: CPU_CPUID(); goto nextopcode; default: - LOG(LOG_CPU|LOG_ERROR,"LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry); + LOG(LOG_CPU,LOG_ERROR)("LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry); break; } diff --git a/src/cpu/core_full/loadwrite.h b/src/cpu/core_full/loadwrite.h index c1e192fb..77a9c61d 100644 --- a/src/cpu/core_full/loadwrite.h +++ b/src/cpu/core_full/loadwrite.h @@ -89,4 +89,4 @@ static INLINE Bit32u Pop_32(void) { } \ } -#endif \ No newline at end of file +#endif diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 651c01ea..1d2c3241 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -417,7 +417,7 @@ switch (inst.code.op) { default: - LOG(LOG_ERROR|LOG_CPU,"Group 6 Illegal subfunction %X",inst.rm_index); + LOG(LOG_CPU,LOG_ERROR)("Group 6 Illegal subfunction %X",inst.rm_index); } break; case O_GRP7w: @@ -455,7 +455,7 @@ switch (inst.code.op) { CPU_LMSW(inst.op1.w); goto nextopcode; default: - LOG(LOG_ERROR|LOG_CPU,"Group 7 Illegal subfunction %X",inst.rm_index); + LOG(LOG_CPU,LOG_ERROR)("Group 7 Illegal subfunction %X",inst.rm_index); } break; case O_M_Cd_Rd: @@ -541,6 +541,6 @@ switch (inst.code.op) { case 0: break; default: - LOG(LOG_ERROR|LOG_CPU,"OP:Unhandled code %d entry %X",inst.code.op,inst.entry); + LOG(LOG_CPU,LOG_ERROR)("OP:Unhandled code %d entry %X",inst.code.op,inst.entry); } diff --git a/src/cpu/core_full/save.h b/src/cpu/core_full/save.h index df574350..0f7f4fe4 100644 --- a/src/cpu/core_full/save.h +++ b/src/cpu/core_full/save.h @@ -106,5 +106,5 @@ switch (inst.code.save) { case 0: break; default: - LOG(LOG_ERROR|LOG_CPU,"SAVE:Unhandled code %d entry %X",inst.code.save,inst.entry); + LOG(LOG_CPU,LOG_ERROR)("SAVE:Unhandled code %d entry %X",inst.code.save,inst.entry); } diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index 50e805da..bdc15b4e 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -2,7 +2,7 @@ EAPoint si_base,di_base; Bitu si_index,di_index; Bitu add_mask; - Bitu count,count_left; + Bits count,count_left; Bits add_index; bool restart=false; @@ -195,7 +195,7 @@ } break; default: - LOG(LOG_CPU|LOG_ERROR,"Unhandled string %d entry %X",inst.code.op,inst.entry); + LOG(LOG_CPU,LOG_ERROR)("Unhandled string %d entry %X",inst.code.op,inst.entry); } /* Clean up after certain amount of instructions */ reg_esi&=(~add_mask); diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index c60c7f40..6dce9085 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -121,12 +121,12 @@ bool Interrupt(Bitu num) { #if C_DEBUG switch (num) { case 0x00: - LOG(LOG_CPU,"Divide Error"); + LOG(LOG_CPU,LOG_NORMAL)("Divide Error"); break; case 0x06: break; case 0x07: - LOG(LOG_FPU,"Co Processor Exception"); + LOG(LOG_FPU,LOG_NORMAL)("Co Processor Exception"); break; case 0x08: case 0x09: @@ -148,7 +148,7 @@ bool Interrupt(Bitu num) { break; case 0xcd: #if C_HEAVY_DEBUG - LOG(LOG_CPU|LOG_ERROR,"Call to interrupt 0xCD this is BAD"); + LOG(LOG_CPU,LOG_ERROR)("Call to interrupt 0xCD this is BAD"); DEBUG_HeavyWriteLogInstruction(); #endif E_Exit("Call to interrupt 0xCD this is BAD"); @@ -156,7 +156,7 @@ bool Interrupt(Bitu num) { if (DEBUG_Breakpoint()) return true; break; case 0x05: - LOG(LOG_CPU,"CPU:Out Of Bounds interrupt"); + LOG(LOG_CPU,LOG_NORMAL)("CPU:Out Of Bounds interrupt"); break; default: // LOG_WARN("Call to unsupported INT %02X call %02X",num,reg_ah); @@ -539,7 +539,7 @@ bool CPU_SET_CRX(Bitu cr,Bitu value) { return CPU_CheckState(); } default: - LOG(LOG_CPU|LOG_ERROR,"Unhandled MOV CR%d,%X",cr,value); + LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV CR%d,%X",cr,value); break; } return false; @@ -550,7 +550,7 @@ Bitu CPU_GET_CRX(Bitu cr) { case 0: return cpu.cr0; default: - LOG(LOG_CPU|LOG_ERROR,"Unhandled MOV XXX, CR%d",cr); + LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV XXX, CR%d",cr); break; } return 0; @@ -762,7 +762,7 @@ void CPU_CPUID(void) { reg_edx=0; /* Nothing either */ break; default: - LOG(LOG_CPU|LOG_ERROR,"Unhandled CPUID Function %x",reg_eax); + LOG(LOG_CPU,LOG_ERROR)("Unhandled CPUID Function %x",reg_eax); break; } diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index c7adc6ed..44781cc5 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -134,7 +134,7 @@ Bitu get_CF(void) { case t_DIV: return false; /* Unkown */ default: - LOG(LOG_ERROR|LOG_CPU,"get_CF Unknown %d",flags.type); + LOG(LOG_CPU,LOG_ERROR)("get_CF Unknown %d",flags.type); } return 0; } @@ -229,7 +229,7 @@ again: case t_MUL: return false; /* Unkown */ default: - LOG(LOG_ERROR|LOG_CPU,"get_AF Unknown %d",flags.type); + LOG(LOG_CPU,LOG_ERROR)("get_AF Unknown %d",flags.type); } return 0; } @@ -314,7 +314,7 @@ again: case t_MUL: return false; /* Unkown */ default: - LOG(LOG_ERROR|LOG_CPU,"get_ZF Unknown %d",flags.type); + LOG(LOG_CPU,LOG_ERROR)("get_ZF Unknown %d",flags.type); } return false; } @@ -398,7 +398,7 @@ again: case t_MUL: return false; /* Unkown */ default: - LOG(LOG_ERROR|LOG_CPU,"get_SF Unkown %d",flags.type); + LOG(LOG_CPU,LOG_ERROR)("get_SF Unkown %d",flags.type); } return false; @@ -539,7 +539,7 @@ again: case t_DIV: return false; /* Unkown */ default: - LOG(LOG_ERROR|LOG_CPU,"get_OF Unkown %d",flags.type); + LOG(LOG_CPU,LOG_ERROR)("get_OF Unkown %d",flags.type); } return false; } @@ -800,7 +800,7 @@ Bitu get_Flags(void) { SET_FLAG(FLAG_CF,false); /* Unkown */ break; default: - LOG(LOG_ERROR|LOG_CPU,"Unhandled flag type %d",flags.type); + LOG(LOG_CPU,LOG_ERROR)("Unhandled flag type %d",flags.type); return 0; } flags.word=new_flags; diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp index a8db93b1..428b6aa9 100644 --- a/src/cpu/slow_16.cpp +++ b/src/cpu/slow_16.cpp @@ -83,7 +83,7 @@ decode_start: if (prefix.count) { PrefixReset; //DEBUG_HeavyWriteLogInstruction(); - LOG(LOG_CPU,"Prefix for non prefixed instruction"); + LOG(LOG_CPU,LOG_NORMAL)("Prefix for non prefixed instruction"); } CPU_Cycles--; } diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index c3264d22..0f1d90ec 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -53,6 +53,8 @@ char* AnalyzeInstruction(char* inst, bool saveSelector); void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num); class DEBUG; +extern void DEBUG_ShowMsg(Bit32u entry, char* format, ...); + DEBUG* pDebugcom = 0; bool exitLoop = false; bool logHeavy = false; diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index e5b06b1c..c44fb1ba 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -44,6 +44,9 @@ namespace { }; extern int old_cursor_state; + + + void DEBUG_ShowMsg(Bit32u entry, char * format,...) { if (!(entry & LOG_ERROR) && entry && !loggrp[entry].enabled) return; @@ -58,7 +61,14 @@ void DEBUG_ShowMsg(Bit32u entry, char * format,...) { wrefresh(dbg.win_out); if(debuglog) fprintf(debuglog,"%10d: %s\n",cycle_count,buf); } - +void LOG::operator() (char* format, ...){ + char buf[1024]; + va_list msg; + va_start(msg,format); + vsprintf(buf,format,msg); + va_end(msg); + DEBUG_ShowMsg(this->d_type|this->d_severity,buf); +} static void Draw_RegisterLayout(void) { From 72d44cbc16d8eec173c322f7defc8a9aa46d86e6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 4 May 2003 19:13:21 +0000 Subject: [PATCH 0908/4131] added prototype for DEBUG_ShowMsg Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@988 --- src/misc/support.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/misc/support.cpp b/src/misc/support.cpp index dd9a9bf2..bc00cdf1 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -154,8 +154,8 @@ char * StripWord(char * cmd) { } return trim(cmd+strlen(begin)+1); } - -void GFX_ShowMsg(char * msg); +extern void DEBUG_ShowMsg(Bit32u entry,char* format,...); +extern void GFX_ShowMsg(char * msg); void S_Warn(char * format,...) { char buf[1024]; From bbb7cf45b0098981908aa8e8f21ff964d76c4cc3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 4 May 2003 19:19:09 +0000 Subject: [PATCH 0909/4131] updated loggingsystem Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@989 --- ChangeLog | 7 ++++ src/dos/cdrom.cpp | 2 +- src/dos/cdrom_aspi_win32.cpp | 14 ++++---- src/dos/dev_con.h | 16 +++++----- src/dos/dos.cpp | 62 ++++++++++++++++++------------------ src/dos/dos_execute.cpp | 4 +-- src/dos/dos_files.cpp | 6 ++-- src/dos/dos_ioctl.cpp | 6 ++-- src/dos/dos_misc.cpp | 2 +- src/dos/dos_mscdex.cpp | 24 +++++++------- src/dos/drive_cache.cpp | 4 +-- src/gui/midi.cpp | 2 +- src/gui/midi_win32.h | 2 +- src/gui/sdlmain.cpp | 2 +- src/hardware/cmos.cpp | 14 ++++---- src/hardware/disney.cpp | 8 ++--- src/hardware/dma.cpp | 8 ++--- src/hardware/gameblaster.cpp | 2 +- src/hardware/iohandler.cpp | 8 ++--- src/hardware/keyboard.cpp | 14 ++++---- src/hardware/memory.cpp | 6 ++-- src/hardware/mpu401.cpp | 4 +-- src/hardware/pic.cpp | 12 +++---- src/hardware/sblaster.cpp | 20 ++++++------ src/hardware/tandy_sound.cpp | 2 +- src/hardware/timer.cpp | 6 ++-- src/hardware/vga.cpp | 12 +++---- src/hardware/vga_attr.cpp | 6 ++-- src/hardware/vga_crtc.cpp | 4 +-- src/hardware/vga_dac.cpp | 6 ++-- src/hardware/vga_gfx.cpp | 8 ++--- src/hardware/vga_memory.cpp | 2 +- src/hardware/vga_misc.cpp | 2 +- src/hardware/vga_seq.cpp | 4 +-- src/ints/bios.cpp | 24 +++++++------- src/ints/bios_disk.cpp | 10 +++--- src/ints/bios_keyboard.cpp | 6 ++-- src/ints/ems.cpp | 18 +++++------ src/ints/int10.cpp | 20 ++++++------ src/ints/int10_char.cpp | 2 +- src/ints/int10_modes.cpp | 4 +-- src/ints/int10_put_pixel.cpp | 4 +-- src/ints/mouse.cpp | 10 +++--- src/ints/xms.cpp | 10 +++--- 44 files changed, 208 insertions(+), 201 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3745cf8b..fcf663af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +0.60 + - added support for the not inheritance flags. + - created functions for creating child psp. + - updated errorcodes of findfirst (thanks Mirek!) + - added basic support for vidmode 0x7 + - rewrote loggingsystem to generate less warnings + 0.58 - fixed date and time issues with fcbs - added more commands to the internal Shell diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 1cb924e7..909ef3ca 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -166,7 +166,7 @@ int CDROM_GetMountType(char* path, int forceCD) int num = SDL_CDNumDrives(); // If cd drive is forced then check if its in range and return 0 if ((forceCD>=0) && (forceCD20 */ @@ -818,11 +818,11 @@ static Bitu DOS_21Handler(void) { { switch(reg_al) { case 0x00: /* Get */ - LOG(LOG_ERROR|LOG_MISC,"DOS:Get Disk serial number"); + LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Get Disk serial number"); CALLBACK_SCF(true); break; case 0x01: - LOG(LOG_ERROR|LOG_MISC,"DOS:Set Disk serial number"); + LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Set Disk serial number"); default: E_Exit("DOS:Illegal Get Serial Number call %2X",reg_al); } @@ -834,7 +834,7 @@ static Bitu DOS_21Handler(void) { case 0x71: /* Unknown probably 4dos detection */ reg_ax=0x7100; CALLBACK_SCF(true); - LOG(LOG_DOSMISC,"DOS:Windows long file name support call %2X",reg_al); + LOG(LOG_DOSMISC,LOG_NORMAL)("DOS:Windows long file name support call %2X",reg_al); break; case 0x68: /* FFLUSH Commit file */ case 0x63: /* Weirdo double byte stuff (fails but say it succeeded) available only in MSDOS 2.25 */ @@ -855,7 +855,7 @@ static Bitu DOS_21Handler(void) { case 0x5e: /* More Network Functions */ case 0x5f: /* And Even More Network Functions */ default: - LOG(LOG_ERROR|LOG_MISC,"DOS:Unhandled call %02X al=%02X. Set al to default of 0",reg_ah,reg_al); + LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Unhandled call %02X al=%02X. Set al to default of 0",reg_ah,reg_al); reg_al=0x00; /* default value */ break; }; @@ -888,12 +888,12 @@ static Bitu DOS_25Handler(void) { SETFLAGBIT(CF,false); reg_ax=0; if((reg_cx != 1) ||(reg_dx != 1)) - LOG(LOG_DOSMISC,"int 25 called but not as diskdetection"); + LOG(LOG_DOSMISC,LOG_NORMAL)("int 25 called but not as diskdetection"); } return CBRET_NONE; } static Bitu DOS_26Handler(void) { - LOG(LOG_DOSMISC,"int 26 called: hope for the best!"); + LOG(LOG_DOSMISC,LOG_NORMAL)("int 26 called: hope for the best!"); flags.type=0; if(Drives[reg_al]==0){ reg_ax=0x8002; @@ -909,12 +909,12 @@ static Bitu DOS_28Handler(void) { } static Bitu DOS_29Handler(void) { - LOG(LOG_ERROR|LOG_MISC,"int 29 called"); + LOG(LOG_DOSMISC,LOG_ERROR)("int 29 called"); return CBRET_NONE; } static Bitu DOS_CaseMapFunc(void) { - //LOG(LOG_ERROR|LOG_MISC,"Case map routine called : %c",reg_al); + //LOG(LOG_DOSMISC,LOG_ERROR)("Case map routine called : %c",reg_al); return CBRET_NONE; }; diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index e5149fb3..7da7e712 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -304,12 +304,12 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { pos=headersize;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET); while (imagesize>0x7FFF) { readsize=0x8000;DOS_ReadFile(fhandle,loadaddress,&readsize); - if (readsize!=0x8000) LOG(LOG_EXEC,"Illegal header"); + if (readsize!=0x8000) LOG(LOG_EXEC,LOG_NORMAL)("Illegal header"); loadaddress+=0x8000;imagesize-=0x8000; } if (imagesize>0) { readsize=(Bit16u)imagesize;DOS_ReadFile(fhandle,loadaddress,&readsize); - if (readsize!=imagesize) LOG(LOG_EXEC,"Illegal header"); + if (readsize!=imagesize) LOG(LOG_EXEC,LOG_NORMAL)("Illegal header"); } /* Relocate the exe image */ Bit16u relocate; diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index fcb583b0..812aa7f5 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -330,8 +330,8 @@ bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { /* First check for devices */ - if (flags>2) LOG(LOG_FILES|LOG_ERROR,"Special file open command %X file %s",flags,name); - else LOG(LOG_FILES,"file open command %X file %s",flags,name); + if (flags>2) LOG(LOG_FILES,LOG_ERROR)("Special file open command %X file %s",flags,name); + else LOG(LOG_FILES,LOG_NORMAL)("file open command %X file %s",flags,name); DOS_PSP psp(dos.psp); Bit8u handle=DOS_FindDevice((char *)name); @@ -658,7 +658,7 @@ bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { handle = psp.FindEntryByHandle(i); if (handle==0xFF) { // This shouldnt happen - LOG(LOG_FILES|LOG_ERROR,"DOS: File %s is opened but has no psp entry.",shortname); + LOG(LOG_FILES,LOG_ERROR)("DOS: File %s is opened but has no psp entry.",shortname); return false; } fcb.FileOpen((Bit8u)handle); diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 77ddaba6..313f89a6 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -45,7 +45,7 @@ bool DOS_IOCTL(void) { reg_dx=Files[handle]->GetInformation(); return true; case 0x07: /* Get Output Status */ - LOG(LOG_IOCTL,"DOS:IOCTL:07:Fakes output status is ready for handle %d",handle); + LOG(LOG_IOCTL,LOG_NORMAL)("DOS:IOCTL:07:Fakes output status is ready for handle %d",handle); reg_al=0xff; return true; case 0x08: /* Check if block device removable */ @@ -82,7 +82,7 @@ bool DOS_IOCTL(void) { mem_writeb(ptr+6,0x00); // media type (00=other type) break; default : - LOG(LOG_IOCTL|LOG_ERROR,"DOS:IOCTL Call 0D:%2X Drive %2X unhandled",reg_cl,drive); + LOG(LOG_IOCTL,LOG_ERROR)("DOS:IOCTL Call 0D:%2X Drive %2X unhandled",reg_cl,drive); return false; } return true; @@ -105,7 +105,7 @@ bool DOS_IOCTL(void) { break; } default: - LOG(LOG_DOSMISC|LOG_ERROR,"DOS:IOCTL Call %2X unhandled",reg_al); + LOG(LOG_DOSMISC,LOG_ERROR)("DOS:IOCTL Call %2X unhandled",reg_al); return false; }; return false; diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index e0542159..33b56f1e 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -44,7 +44,7 @@ static Bitu INT2F_Handler(void) { if ((*loop_multiplex->handler)()) return CBRET_NONE; loop_multiplex=loop_multiplex->next; } - LOG(LOG_ERROR,"DOS:Multiplex Unhandled call %4X",reg_ax); + LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Multiplex Unhandled call %4X",reg_ax); return CBRET_NONE; }; diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index ecb2ebc8..4ca544b8 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -228,7 +228,7 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) // Get Mounttype and init needed cdrom interface switch (CDROM_GetMountType(physicalPath,forceCD)) { case 0x00 : { - LOG(LOG_MISC,"MSCDEX: Mounting physical cdrom: %s" ,physicalPath); + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting physical cdrom: %s" ,physicalPath); #if defined (WIN32) // Check OS OSVERSIONINFO osi; @@ -238,30 +238,30 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) // only WIN NT/200/XP if (useCdromInterface==CDROM_USE_IOCTL) { cdrom[numDrives] = new CDROM_Interface_Ioctl(); - LOG(LOG_MISC,"MSCDEX: IOCTL Interface."); + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface."); break; } } if (useCdromInterface==CDROM_USE_ASPI) { // all Wins - ASPI cdrom[numDrives] = new CDROM_Interface_Aspi(); - LOG(LOG_MISC,"MSCDEX: ASPI Interface."); + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: ASPI Interface."); break; } #endif cdrom[numDrives] = new CDROM_Interface_SDL(); - LOG(LOG_MISC,"MSCDEX: SDL Interface."); + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: SDL Interface."); } break; case 0x01 : // iso cdrom interface // FIXME: Not yet supported - LOG(LOG_MISC|LOG_ERROR,"MSCDEX: Mounting iso file as cdrom: %s" ,physicalPath); + LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Mounting iso file as cdrom: %s" ,physicalPath); cdrom[numDrives] = new CDROM_Interface_Fake; return 2; break; case 0x02 : // fake cdrom interface (directories) cdrom[numDrives] = new CDROM_Interface_Fake; - LOG(LOG_MISC,"MSCDEX: Mounting directory as cdrom: %s",physicalPath); - LOG(LOG_MISC,"MSCDEX: You wont have full MSCDEX support !"); + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting directory as cdrom: %s",physicalPath); + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: You wont have full MSCDEX support !"); result = 5; break; default : // weird result @@ -728,7 +728,7 @@ static Bitu MSCDEX_Interrupt_Handler(void) mem_writeb(buffer+10,0x00); break; }; - default : LOG(LOG_ERROR|LOG_MISC,"MSCDEX: Unsupported IOCTL INPUT Subfunction %02X",subFuncNr); + default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unsupported IOCTL INPUT Subfunction %02X",subFuncNr); break; } break; @@ -747,7 +747,7 @@ static Bitu MSCDEX_Interrupt_Handler(void) case 0x05 : // load media mscdex->LoadUnloadMedia(subUnit,false); break; - default : LOG(LOG_ERROR|LOG_MISC,"MSCDEX: Unsupported IOCTL OUTPUT Subfunction %02X",subFuncNr); + default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unsupported IOCTL OUTPUT Subfunction %02X",subFuncNr); break; }; break; @@ -784,7 +784,7 @@ static Bitu MSCDEX_Interrupt_Handler(void) case 0x88 : /* Resume Audio */ mscdex->ResumeAudio(subUnit); break; - default : LOG(LOG_ERROR|LOG_MISC,"MSCDEX: Unsupported Driver Request %02X",funcNr); + default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unsupported Driver Request %02X",funcNr); break; }; @@ -870,7 +870,7 @@ static bool MSCDEX_Handler(void) case 0x1510: /* Device driver request */ mscdex->SendDriverRequest(reg_cx,data); return true; - default : LOG(LOG_ERROR|LOG_MISC,"MSCDEX: Unknwon call : %04X",reg_ax); + default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unknwon call : %04X",reg_ax); return true; }; @@ -882,7 +882,7 @@ public: device_MSCDEX() { name="MSCD001"; } bool Read (Bit8u * data,Bit16u * size) { return false;} bool Write(Bit8u * data,Bit16u * size) { - LOG(0,"Write to mscdex device"); + LOG(LOG_ALL,LOG_NORMAL)("Write to mscdex device"); return false; } bool Seek(Bit32u * pos,Bit32u type){return false;} diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 92f0c00c..16f4f9e0 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -113,13 +113,13 @@ void DOS_Drive_Cache::SetLabel(const char* vname) } }; label[labelPos]=0; -// LOG(LOG_ERROR,"CACHE: Set volume label to %s",label); +// LOG(LOG_ALL,LOG_ERROR)("CACHE: Set volume label to %s",label); }; Bit16u DOS_Drive_Cache::GetFreeID(CFileInfo* dir) { for (Bit32u i=0; iPlaySysex(midi.sysex.buf,midi.sysex.used); - LOG(0,"Sysex message size %d",midi.sysex.used); + LOG(LOG_ALL,LOG_NORMAL)("Sysex message size %d",midi.sysex.used); midi.sysex.active=false; if (data==0xf7) return; } diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index 54d33179..bdac5ded 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -47,7 +47,7 @@ public: }; void PlaySysex(Bit8u * sysex,Bitu len) { if (WaitForSingleObject (m_event, 2000) == WAIT_TIMEOUT) { - LOG(LOG_MISC|LOG_ERROR,"Can't send midi message"); + LOG(LOG_MISC,LOG_ERROR)("Can't send midi message"); return; } midiOutUnprepareHeader (m_out, &m_hdr, sizeof (m_hdr)); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index d191b371..4928e394 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -397,7 +397,7 @@ static void HandleKey(SDL_KeyboardEvent * key) { /* Special Keys */ default: code=KBD_1; - LOG(LOG_ERROR|LOG_KEYBOARD,"Unhandled SDL keysym %d",key->keysym.sym); + LOG(LOG_KEYBOARD,LOG_ERROR)("Unhandled SDL keysym %d",key->keysym.sym); break; } /* Check the modifiers */ diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index b28b1494..3f9a4be5 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -53,7 +53,7 @@ static void cmos_checktimer(void) { if (!cmos.timer.div || !cmos.timer.enabled) return; if (cmos.timer.div<=2) cmos.timer.div+=7; cmos.timer.micro=(Bitu) (10000000.0/(32768.0 / (1 << (cmos.timer.div - 1)))); - LOG(LOG_PIT,"RTC Timer at %f hz",1000000.0/cmos.timer.micro); + LOG(LOG_PIT,LOG_NORMAL)("RTC Timer at %f hz",1000000.0/cmos.timer.micro); PIC_AddEvent(cmos_timerevent,cmos.timer.micro); } @@ -76,13 +76,13 @@ static void cmos_writereg(Bit32u port,Bit8u val) { case 0x01: /* Seconds Alarm */ case 0x03: /* Minutes Alarm */ case 0x05: /* Hours Alarm */ - LOG(LOG_BIOS,"CMOS:Trying to set alarm"); + LOG(LOG_BIOS,LOG_NORMAL)("CMOS:Trying to set alarm"); cmos.regs[cmos.reg]=val; break; case 0x0a: /* Status reg A */ cmos.regs[cmos.reg]=val & 0x7f; - if (val & 0x70!=0x20) LOG(LOG_ERROR|LOG_BIOS,"CMOS Illegal 22 stage divider value"); + if (val & 0x70!=0x20) LOG(LOG_BIOS,LOG_ERROR)("CMOS Illegal 22 stage divider value"); cmos.timer.div=(val & 0xf); cmos_checktimer(); break; @@ -90,7 +90,7 @@ static void cmos_writereg(Bit32u port,Bit8u val) { cmos.bcd=!(val & 0x4); cmos.regs[cmos.reg]=val & 0x7f; cmos.timer.enabled=(val & 0x40)>0; - if (val&0x10) LOG(LOG_ERROR|LOG_BIOS,"CMOS:Updated ended interrupt not supported yet"); + if (val&0x10) LOG(LOG_BIOS,LOG_ERROR)("CMOS:Updated ended interrupt not supported yet"); cmos_checktimer(); break; case 0x0f: /* Shutdown status byte */ @@ -98,7 +98,7 @@ static void cmos_writereg(Bit32u port,Bit8u val) { break; default: cmos.regs[cmos.reg]=val & 0x7f; - LOG(LOG_ERROR|LOG_BIOS,"CMOS:WRite to unhandled register %x",cmos.reg); + LOG(LOG_BIOS,LOG_ERROR)("CMOS:WRite to unhandled register %x",cmos.reg); } } @@ -107,7 +107,7 @@ static void cmos_writereg(Bit32u port,Bit8u val) { static Bit8u cmos_readreg(Bit32u port) { if (cmos.reg>0x3f) { - LOG(LOG_ERROR|LOG_BIOS,"CMOS:Read from illegal register %x",cmos.reg); + LOG(LOG_BIOS,LOG_ERROR)("CMOS:Read from illegal register %x",cmos.reg); return 0xff; } time_t curtime; @@ -151,7 +151,7 @@ static Bit8u cmos_readreg(Bit32u port) { case 0x31: /* Extended memory in KB High Byte */ return cmos.regs[cmos.reg]; default: - LOG(LOG_BIOS,"CMOS:Read from reg %F",cmos.reg); + LOG(LOG_BIOS,LOG_NORMAL)("CMOS:Read from reg %F",cmos.reg); return cmos.regs[cmos.reg]; } } diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index b03fe524..423582db 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -47,7 +47,7 @@ static void disney_write(Bit32u port,Bit8u val) { disney.data=val; break; case 1: /* Status Port */ - LOG(LOG_MISC,"DISNEY:Status write %x",val); + LOG(LOG_MISC,LOG_NORMAL)("DISNEY:Status write %x",val); break; case 2: /* Control Port */ // LOG_WARN("DISNEY:Control write %x",val); @@ -56,7 +56,7 @@ static void disney_write(Bit32u port,Bit8u val) { disney.buffer[disney.used++]=disney.data; } } - if (val&0x10) LOG(LOG_ERROR,"DISNEY:Parallel IRQ Enabled"); + if (val&0x10) LOG(LOG_MISC,LOG_ERROR)("DISNEY:Parallel IRQ Enabled"); disney.control=val; break; } @@ -66,7 +66,7 @@ static Bit8u disney_read(Bit32u port) { switch (port-DISNEY_BASE) { case 0: /* Data Port */ -// LOG(LOG_MISC,"DISNEY:Read from data port"); +// LOG(LOG_MISC,LOG_NORMAL)("DISNEY:Read from data port"); return disney.data; break; case 1: /* Status Port */ @@ -75,7 +75,7 @@ static Bit8u disney_read(Bit32u port) { else return 0x0; break; case 2: /* Control Port */ - LOG(LOG_MISC,"DISNEY:Read from control port"); + LOG(LOG_MISC,LOG_NORMAL)("DISNEY:Read from control port"); return disney.control; break; } diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 13dd2577..80608ac1 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -105,7 +105,7 @@ static Bit8u read_dma(Bit32u port) { ret=0x0; break; default: - LOG(LOG_ERROR,"DMA:Unhandled read from %X",port); + LOG(LOG_DMA,LOG_ERROR)("DMA:Unhandled read from %X",port); } return ret; } @@ -140,7 +140,7 @@ static void write_dma(Bit32u port,Bit8u val) { DMA_TestChannel(chan); break; case 0x08: /* Command Register */ - if (val != 4) LOG(LOG_ERROR,"DMA1:Illegal command %2X",val); + if (val != 4) LOG(LOG_DMA,LOG_ERROR)("DMA1:Illegal command %2X",val); cont->command_reg=val; break; case 0x09: /* Request Register */ @@ -165,7 +165,7 @@ static void write_dma(Bit32u port,Bit8u val) { chan->mode.autoinit_enable = (val & 0x10) > 0; chan->mode.transfer_type = (val >> 2) & 0x03; if (chan->mode.address_decrement) { - LOG(LOG_ERROR,"DMA:Address Decrease not supported yet"); + LOG(LOG_DMA,LOG_ERROR)("DMA:Address Decrease not supported yet"); } DMA_TestChannel(chan); break; @@ -173,7 +173,7 @@ static void write_dma(Bit32u port,Bit8u val) { cont->flipflop=true; break; default: - LOG(LOG_ERROR,"DMA:Unhandled write %X to %X",val,port); + LOG(LOG_DMA,LOG_ERROR)("DMA:Unhandled write %X to %X",static_cast(val),port); }; }; diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index 3deb6748..29f6568e 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -358,7 +358,7 @@ static void saa1099_write_port_w( int chip, int offset, int data ) break; default: /* Error! */ // logerror("%04x: (SAA1099 #%d) Unknown operation (reg:%02x, data:%02x)\n",activecpu_get_pc(), chip, reg, data); - LOG(0|LOG_ERROR,"CMS Unkown write to reg %x with %x",reg, data); + LOG(LOG_MISC,LOG_ERROR)("CMS Unkown write to reg %x with %x",reg, data); } } diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 13138f8b..be6e2d61 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -24,12 +24,12 @@ IO_WriteBlock IO_WriteTable[IO_MAX]; void IO_Write(Bitu num,Bit8u val) { if (num(val),port); IO_RegisterWriteHandler(port,&IO_WriteBlocked,"Blocked Write"); } diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index d03bedc9..a85de1b2 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -47,7 +47,7 @@ struct KeyCode { }; struct KeyEvent { - Bitu type; + Bits type; Bitu state; KEYBOARD_EventHandler * handler; KeyEvent * next; @@ -180,7 +180,7 @@ static void write_p60(Bit32u port,Bit8u val) { KEYBOARD_AddCode(0xfa,0,0,STATE_NORMAL); /* Acknowledge */ break; default: - LOG(LOG_ERROR|LOG_KEYBOARD,"60:Unhandled command %X",val); + LOG(LOG_KEYBOARD,LOG_ERROR)("60:Unhandled command %X",val); } return; case CMD_SETOUTPORT: @@ -218,13 +218,13 @@ static void write_p64(Bit32u port,Bit8u val) { keyb.scheduled=true; PIC_AddEvent(KEYBOARD_GetCode,KEYDELAY); } - LOG(LOG_KEYBOARD,"Activated"); + LOG(LOG_KEYBOARD,LOG_NORMAL)("Activated"); break; case 0xae: /* Deactivate keyboard */ keyb.active=false; PIC_DeActivateIRQ(1); PIC_RemoveEvents(KEYBOARD_GetCode); - LOG(LOG_KEYBOARD,"De-Activated"); + LOG(LOG_KEYBOARD,LOG_NORMAL)("De-Activated"); break; case 0xd0: /* Outport on buffer */ KEYBOARD_AddCode(MEM_A20_Enabled() ? 0x02 : 0,0,0,STATE_NORMAL); @@ -233,7 +233,7 @@ static void write_p64(Bit32u port,Bit8u val) { keyb.command=CMD_SETOUTPORT; break; default: - LOG(LOG_ERROR|LOG_KEYBOARD,"Port 64 write with val %d",val); + LOG(LOG_KEYBOARD,LOG_ERROR)("Port 64 write with val %d",val); break; } } @@ -246,7 +246,7 @@ void KEYBOARD_AddEvent(Bitu keytype,Bitu state,KEYBOARD_EventHandler * handler) KeyEvent * newevent=new KeyEvent; /* Add the event in the correct key structure */ if (keytype>=KBD_LAST) { - LOG(LOG_ERROR|LOG_KEYBOARD,"Illegal key %d for handler",keytype); + LOG(LOG_KEYBOARD,LOG_ERROR)("Illegal key %d for handler",keytype); } newevent->next=event_handlers[keytype]; event_handlers[keytype]=newevent; @@ -372,7 +372,7 @@ void KEYBOARD_AddKey(KBD_KEYS keytype,Bitu unicode,Bitu mod,bool pressed) { case KBD_insert:extend=true;ret=82;break; case KBD_delete:extend=true;ret=83;break; default: - E_Exit("Unsopperted key press"); + E_Exit("Unsupported key press"); break; } /* check for active key events */ diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 075b388a..4fa22ce5 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -93,11 +93,11 @@ void MEM_StrCopy(PhysPt off,char * data,Bitu size) { } static Bit8u Illegal_ReadHandler(PhysPt pt) { - LOG(LOG_ERROR,"MEM:Illegal read from address %4X",pt); + LOG(LOG_ALL,LOG_ERROR)("MEM:Illegal read from address %4X",pt); return 0xff; } static void Illegal_WriteHandler(PhysPt pt,Bit8u val) { - LOG(LOG_ERROR,"Illegal write val %2X to address %4X",val,pt); + LOG(LOG_ALL,LOG_ERROR)("Illegal write val %2X to address %4X",static_cast(val),pt); } /* Could only be called when the pt host entry is 0 ah well :) */ @@ -243,7 +243,7 @@ void MEM_A20_Enable(bool enable) { } else { MEM_SetupMapping(PAGE_COUNT(1024*1024),PAGE_COUNT(64*1024),memory); } - LOG(LOG_MISC,"A20 Line is %s",enable ? "Enabled" : "Disabled"); + LOG(LOG_MISC,LOG_NORMAL)("A20 Line is %s",enable ? "Enabled" : "Disabled"); } Bitu MEM_TotalSize(void) { diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index ff9e9bb1..d68e0a35 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -158,7 +158,7 @@ static void QueueByte(Bit8u data) { if (pos>=MPU_QUEUE) pos-=MPU_QUEUE; mpu.queue_used++; mpu.queue[pos]=data; - } else LOG(LOG_MISC,"MPU401:Data queue full"); + } else LOG(LOG_MISC,LOG_NORMAL)("MPU401:Data queue full"); } static void ClrQueue(void) { @@ -184,7 +184,7 @@ static void MPU401_WriteCommand(Bit32u port,Bit8u val) { break; default: - LOG(LOG_MISC,"MPU401:Unhandled command %X",val); + LOG(LOG_MISC,LOG_NORMAL)("MPU401:Unhandled command %X",val); QueueByte(MSG_CMD_ACK); break; } diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index f23f8fd4..f4fe8730 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -126,14 +126,14 @@ static void write_data(Bit32u port,Bit8u val) { }; break; case 1: /* icw2 */ - LOG(LOG_PIC,"%d:Base vector %X",port==0x21 ? 0 : 1,val); + LOG(LOG_PIC,LOG_NORMAL)("%d:Base vector %X",static_cast(port==0x21 ? 0 : 1),static_cast(val)); for (i=0;i<=7;i++) { irqs[i+irq_base].vector=(val&0xf8)+i; }; if(pic->icw_index++ >= pic->icw_words) pic->icw_index=0; break; case 2: /* icw 3 */ - LOG(LOG_PIC,"%d:ICW 3 %X",port==0x21 ? 0 : 1,val); + LOG(LOG_PIC,LOG_NORMAL)("%d:ICW 3 %X",static_cast(port==0x21 ? 0 : 1),static_cast(val)); if(pic->icw_index++ >= pic->icw_words) pic->icw_index=0; break; case 3: /* icw 4 */ @@ -147,11 +147,11 @@ static void write_data(Bit32u port,Bit8u val) { */ pic->auto_eoi=(val & 0x2)>0; - LOG(LOG_PIC,"%d:ICW 4 %X",port==0x21 ? 0 : 1,val); + LOG(LOG_PIC,LOG_NORMAL)("%d:ICW 4 %X",static_cast(port==0x21 ? 0 : 1),static_cast(val)); if(pic->icw_index++ >= pic->icw_words) pic->icw_index=0; break; default: /* icw 3, and 4*/ - LOG(LOG_PIC,"ICW HUH? %X",val); + LOG(LOG_PIC,LOG_NORMAL)("ICW HUH? %X",val); } } @@ -269,7 +269,7 @@ static void AddEntry(PICEntry * entry) { void PIC_AddEvent(PIC_EventHandler handler,Bitu delay) { if (!pic.free_entry) { - LOG(LOG_ERROR|LOG_PIC,"Event queue full"); + LOG(LOG_PIC,LOG_ERROR)("Event queue full"); return; } PICEntry * entry=pic.free_entry; @@ -284,7 +284,7 @@ void PIC_AddEvent(PIC_EventHandler handler,Bitu delay) { void PIC_AddIRQ(Bitu irq,Bitu delay) { if (irq>15) E_Exit("PIC:Illegal IRQ"); if (!pic.free_entry) { - LOG(LOG_ERROR|LOG_PIC,"Event queue full"); + LOG(LOG_PIC,LOG_ERROR)("Event queue full"); return; } PICEntry * entry=pic.free_entry; diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index f5af8d9a..864e52c0 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -344,7 +344,7 @@ static void GenerateSound(Bitu size) { } } if (sb.out.pos>SB_BUF_SIZE) { - LOG(LOG_ERROR|LOG_SB,"Generation Buffer Full!!!!"); + LOG(LOG_SB,LOG_ERROR)("Generation Buffer Full!!!!"); sb.out.pos=0; } } @@ -408,7 +408,7 @@ static void DSP_StartDMATranfser(DMA_MODES mode) { sb.tmp.add_index=(sb.dma.rate<<16)/sb.hw.rate; break; default: - LOG(LOG_ERROR|LOG_SB,"DSP:Illegal transfer mode %d",mode); + LOG(LOG_SB,LOG_ERROR)("DSP:Illegal transfer mode %d",mode); return; } //TODO Use the 16-bit dma for 16-bit transfers @@ -416,7 +416,7 @@ static void DSP_StartDMATranfser(DMA_MODES mode) { sb.dma.mode=mode; DMA_SetEnableCallBack(sb.hw.dma8,DMA_Enable); //TODO with stereo divide add_index - LOG(LOG_SB,"DMA Transfer:%s rate %d size %d",type,sb.dma.rate,sb.dma.total); + LOG(LOG_SB,LOG_NORMAL)("DMA Transfer:%s rate %d size %d",type,sb.dma.rate,sb.dma.total); } static void DSP_AddData(Bit8u val) { @@ -426,7 +426,7 @@ static void DSP_AddData(Bit8u val) { sb.dsp.out.data[start]=val; sb.dsp.out.used++; } else { - LOG(LOG_ERROR|LOG_SB,"DSP:Data Output buffer full"); + LOG(LOG_SB,LOG_ERROR)("DSP:Data Output buffer full"); } } @@ -538,7 +538,7 @@ static void DSP_DoCommand(void) { break; case 0xe2: /* Weird DMA identification write routine */ { - LOG(LOG_SB,"DSP Function 0xe2"); + LOG(LOG_SB,LOG_NORMAL)("DSP Function 0xe2"); for (Bitu i = 0; i < 8; i++) if ((sb.dsp.in.data[0] >> i) & 0x01) sb.e2.value += E2_incr_table[sb.e2.count % 4][i]; sb.e2.value += E2_incr_table[sb.e2.count % 4][8]; @@ -567,7 +567,7 @@ static void DSP_DoCommand(void) { PIC_AddIRQ(sb.hw.irq,0); break; default: - LOG(LOG_ERROR|LOG_SB,"DSP:Unhandled command %2X",sb.dsp.cmd); + LOG(LOG_SB,LOG_ERROR)("DSP:Unhandled command %2X",sb.dsp.cmd); break; } sb.dsp.cmd=DSP_NO_COMMAND; @@ -610,7 +610,7 @@ static void MIXER_Write(Bit8u val) { sb.mixer.master=val; break; default: - LOG(LOG_ERROR|LOG_SB,"MIXER:Write to unhandled index %X",sb.mixer.index); + LOG(LOG_SB,LOG_ERROR)("MIXER:Write to unhandled index %X",sb.mixer.index); } } @@ -623,7 +623,7 @@ static Bit8u MIXER_Read(void) { ret=sb.mixer.master; break; default: - LOG(LOG_ERROR|LOG_SB,"MIXER:Read from unhandled index %X",sb.mixer.index); + LOG(LOG_SB,LOG_ERROR)("MIXER:Read from unhandled index %X",sb.mixer.index); ret=0xff; } return ret; @@ -659,7 +659,7 @@ static Bit8u read_sb(Bit32u port) { case DSP_RESET: return 0xff; default: - LOG(LOG_SB,"Unhandled read from SB Port %4X",port); + LOG(LOG_SB,LOG_NORMAL)("Unhandled read from SB Port %4X",port); break; } return 0xff; @@ -688,7 +688,7 @@ static void write_sb(Bit32u port,Bit8u val) { break; default: - LOG(LOG_SB,"Unhandled write to SB Port %4X",port); + LOG(LOG_SB,LOG_NORMAL)("Unhandled write to SB Port %4X",port); break; } } diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index c71c1dbd..927a6990 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -99,7 +99,7 @@ static void write_pc0(Bit32u port,Bit8u val) { // tandy.chan[tandy.reg>>1].freq_pos=0; break; default: - LOG(0,"TANDY:Illegal dual byte reg %d",tandy.reg); + LOG(LOG_ALL,LOG_ERROR)("TANDY:Illegal dual byte reg %d",tandy.reg); }; } diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index d0f0e6c0..c9fa47c4 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -84,7 +84,7 @@ static void counter_latch(Bitu counter) { else p->read_latch=(Bit16u)(p->cntr-(((double)micro/(double)p->micro)*(double)p->cntr)); break; default: - LOG(LOG_ERROR|LOG_PIT,"Illegal Mode %d for reading counter %d",p->mode,counter); + LOG(LOG_PIT,LOG_ERROR)("Illegal Mode %d for reading counter %d",p->mode,counter); micro%=p->micro; p->read_latch=(Bit16u)(p->cntr-(((double)micro/(double)p->micro)*(double)p->cntr)); break; @@ -120,14 +120,14 @@ static void write_latch(Bit32u port,Bit8u val) { case 0x00: /* Timer hooked to IRQ 0 */ PIC_RemoveEvents(PIT0_Event); PIC_AddEvent(PIT0_Event,p->micro); - LOG(LOG_PIT,"PIT 0 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode); + LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,(Bit32u)p->mode); break; case 0x02: /* Timer hooked to PC-Speaker */ // LOG(LOG_PIT,"PIT 2 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode); PCSPEAKER_SetCounter(p->cntr,p->mode); break; default: - LOG(LOG_ERROR|LOG_PIT,"PIT:Illegal timer selected for writing"); + LOG(LOG_PIT,LOG_ERROR)("PIT:Illegal timer selected for writing"); } } } diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index f07c5aae..bf94677b 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -56,7 +56,7 @@ static void VGA_DrawHandler(RENDER_Part_Handler part_handler) { Bitu stop=vga.config.line_compare; if (vga.draw.double_height) stop/=2; if (stop>=vga.draw.height){ - LOG(LOG_VGAGFX,"Split at %d",stop); + LOG(LOG_VGAGFX,LOG_NORMAL)("Split at %d",stop); goto drawnormal; } switch (vga.mode) { @@ -73,7 +73,7 @@ static void VGA_DrawHandler(RENDER_Part_Handler part_handler) { bufsplit=memory+0xa0000; break; default: - LOG(LOG_VGAGFX,"VGA:Unhandled split screen mode %d",vga.mode); + LOG(LOG_VGAGFX,LOG_NORMAL)("VGA:Unhandled split screen mode %d",vga.mode); goto norender; } part_handler(buf,0,0,vga.draw.width,stop); @@ -161,8 +161,8 @@ static void VGA_DoResize(void) { /* Check for pixel doubling, master clock/2 */ if (vga.seq.clocking_mode & 0x8) clock/=2; - LOG(LOG_VGA,"H total %d, V Total %d",htotal,vtotal); - LOG(LOG_VGA,"H D End %d, V D End %d",hdispend,vdispend); + LOG(LOG_VGA,LOG_NORMAL)("H total %d, V Total %d",htotal,vtotal); + LOG(LOG_VGA,LOG_NORMAL)("H D End %d, V D End %d",hdispend,vdispend); fps=clock/(vtotal*htotal); vga.draw.resizing=false; @@ -221,8 +221,8 @@ static void VGA_DoResize(void) { vga.draw.height=height; vga.draw.pitch=pitch; - LOG(LOG_VGA,"Width %d, Height %d",width,height); - LOG(LOG_VGA,"Flags %X, fps %f",flags,fps); + LOG(LOG_VGA,LOG_NORMAL)("Width %d, Height %d",width,height); + LOG(LOG_VGA,LOG_NORMAL)("Flags %X, fps %f",flags,fps); RENDER_SetSize(width,height,8,pitch,((float)width/(float)height),flags,&VGA_DrawHandler); vga.draw.blank=(Bitu)(1000000/fps); PIC_AddEvent(VGA_BlankTimer,vga.draw.blank); diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 8c5d06a7..c105d3e1 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -122,10 +122,10 @@ void write_p3c0(Bit32u port,Bit8u val) { except in 256 color mode. Note: this register does not affect 256 color modes. */ - if (val) LOG(LOG_VGAGFX,"VGA:ATTR:DAC index set to %d",val); + if (val) LOG(LOG_VGAGFX,LOG_NORMAL)("VGA:ATTR:DAC index set to %d",val); break; default: - LOG(LOG_VGAMISC,"VGA:ATTR:Write to unkown Index %2X",attr(index)); + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:ATTR:Write to unkown Index %2X",attr(index)); break; } } @@ -151,7 +151,7 @@ Bit8u read_p3c1(Bit32u port) { case 0x14: /* Color Select Register */ return attr(color_select); default: - LOG(LOG_VGAMISC,"VGA:ATTR:Read from unkown Index %2X",attr(index)); + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:ATTR:Read from unkown Index %2X",attr(index)); } return 0; }; diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 56b558b7..e2c40f0a 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -274,7 +274,7 @@ void write_p3d5(Bit32u port,Bit8u val) { break; default: - LOG(LOG_VGAMISC,"VGA:CRTC:Write to unknown index %2X",val,crtc(index)); + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:Write to unknown index %2X",val,crtc(index)); } } @@ -331,7 +331,7 @@ Bit8u read_p3d5(Bit32u port) { case 0x18: /* Line Compare Register */ return crtc(line_compare); default: - LOG(LOG_VGAMISC,"VGA:CRTC:Read from unknown index %X",crtc(index)); + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:Read from unknown index %X",crtc(index)); } return 0; } diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index f03db347..f9c7051c 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -54,7 +54,7 @@ enum {DAC_READ,DAC_WRITE}; static void write_p3c6(Bit32u port,Bit8u val) { - if (val!=0xff) LOG(LOG_VGAGFX,"VGA:Pel Mask not 0xff"); + if (val!=0xff) LOG(LOG_VGAGFX,LOG_NORMAL)("VGA:Pel Mask not 0xff"); vga.dac.pel_mask=val; } @@ -112,7 +112,7 @@ static void write_p3c9(Bit32u port,Bit8u val) { vga.dac.pel_index=0; break; default: - LOG(LOG_VGAGFX,"VGA:DAC:Illegal Pel Index"); //If this can actually happen that will be the day + LOG(LOG_VGAGFX,LOG_NORMAL)("VGA:DAC:Illegal Pel Index"); //If this can actually happen that will be the day }; } @@ -133,7 +133,7 @@ static Bit8u read_p3c9(Bit32u port) { vga.dac.pel_index=0; break; default: - LOG(LOG_VGAMISC,"VGA:DAC:Illegal Pel Index"); //If this can actually happen that will be the day + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:DAC:Illegal Pel Index"); //If this can actually happen that will be the day } return ret; } diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index 89fdf02d..cc363bb0 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -70,7 +70,7 @@ void write_p3cf(Bit32u port,Bit8u val) { case 3: /* Data Rotate */ gfx(data_rotate)=val; vga.config.data_rotate=val & 7; - if (vga.config.data_rotate) LOG(LOG_VGAGFX,"VGA:Data Rotate used %d",val &7); + if (vga.config.data_rotate) LOG(LOG_VGAGFX,LOG_NORMAL)("VGA:Data Rotate used %d",val &7); vga.config.raster_op=(val>>3) & 3; /* 0-2 Number of positions to rotate data right before it is written to @@ -171,12 +171,12 @@ void write_p3cf(Bit32u port,Bit8u val) { case 9: /* Unknown */ /* Crystal Dreams seems to like to write tothis register very weird */ if (!index9warned) { - LOG(LOG_VGAMISC,"VGA:3CF:Write %2X to illegal index 9",val); + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:3CF:Write %2X to illegal index 9",val); index9warned=true; } break; default: - LOG(LOG_VGAMISC,"VGA:3CF:Write %2X to illegal index %2X",val,gfx(index)); + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:3CF:Write %2X to illegal index %2X",val,gfx(index)); break; } } @@ -202,7 +202,7 @@ switch (gfx(index)) { case 8: /* Bit Mask Register */ return gfx(bit_mask); default: - LOG(LOG_VGAMISC,"Reading from illegal index %2X in port %4X",gfx(index),port); + LOG(LOG_VGAMISC,LOG_NORMAL)("Reading from illegal index %2X in port %4X",static_cast(gfx(index)),port); } return 0; /* Compiler happy */ } diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 693d4a36..81d2ee05 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -86,7 +86,7 @@ INLINE static Bit32u ModeOperation(Bit8u val) { full=RasterOp(vga.config.full_set_reset,ExpandTable[val] & vga.config.full_bit_mask); break; default: - LOG(LOG_VGAMISC,"VGA:Unsupported write mode %d",vga.config.write_mode); + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:Unsupported write mode %d",vga.config.write_mode); } return full; } diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 1f4fcf40..82d5d984 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -48,7 +48,7 @@ static Bit8u read_p3da(Bit32u port) { static void write_p3d8(Bit32u port,Bit8u val) { - LOG(LOG_VGAMISC,"Write %2X to 3da",val); + LOG(LOG_VGAMISC,LOG_NORMAL)("Write %2X to 3da",val); /* 3 Vertical Sync Select. If set Vertical Sync to the monitor is the logical OR of the vertical sync and the vertical display enable. diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 2fdaa178..c4b6f198 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -91,7 +91,7 @@ void write_p3c5(Bit32u port,Bit8u val) { VGA_FindSettings(); break; default: - LOG(LOG_VGAMISC,"VGA:SEQ:Write to illegal index %2X",seq(index)); + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:Write to illegal index %2X",seq(index)); }; }; @@ -113,7 +113,7 @@ Bit8u read_p3c5(Bit32u port) { case 4: /* Memory Mode */ return seq(memory_mode); default: - LOG(LOG_VGAMISC,"VGA:SEQ:Read from illegal index %2X",seq(index)); + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:Read from illegal index %2X",seq(index)); }; return 0; }; diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 8961bdf5..4af725f1 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -74,13 +74,13 @@ static Bitu INT1A_Handler(void) { case 0x04: /* GET REAL-TIME ClOCK DATA (AT,XT286,PS) */ reg_dx=reg_cx=0; CALLBACK_SCF(false); - LOG(LOG_ERROR|LOG_BIOS,"INT1A:04:Faked RTC get date call"); + LOG(LOG_BIOS,LOG_ERROR)("INT1A:04:Faked RTC get date call"); break; case 0x80: /* Pcjr Setup Sound Multiplexer */ - LOG(LOG_ERROR|LOG_BIOS,"INT1A:80:Setup tandy sound multiplexer to %d",reg_al); + LOG(LOG_BIOS,LOG_ERROR)("INT1A:80:Setup tandy sound multiplexer to %d",reg_al); break; case 0x81: /* Tandy sound system checks */ - LOG(LOG_ERROR|LOG_BIOS,"INT1A:81:Tandy DAC Check failing"); + LOG(LOG_BIOS,LOG_ERROR)("INT1A:81:Tandy DAC Check failing"); break; /* INT 1A - Tandy 2500, Tandy 1000L series - DIGITAL SOUND - INSTALLATION CHECK @@ -93,7 +93,7 @@ static Bitu INT1A_Handler(void) { clear on return, then call AH=84h"Tandy" */ default: - LOG(LOG_ERROR|LOG_BIOS,"INT1A:Undefined call %2X",reg_ah); + LOG(LOG_BIOS,LOG_ERROR)("INT1A:Undefined call %2X",reg_ah); } return CBRET_NONE; } @@ -122,7 +122,7 @@ static Bitu INT11_Handler(void) { 14-15 number of parallel ports installed */ reg_ax=0x104D; - LOG(LOG_BIOS,"INT11:Equipment list returned %X",reg_ax); + LOG(LOG_BIOS,LOG_NORMAL)("INT11:Equipment list returned %X",reg_ax); return CBRET_NONE; } @@ -158,7 +158,7 @@ static Bitu INT12_Handler(void) { }; static Bitu INT17_Handler(void) { - LOG(LOG_BIOS,"INT17:Function %X",reg_ah); + LOG(LOG_BIOS,LOG_NORMAL)("INT17:Function %X",reg_ah); switch(reg_ah) { case 0x00: /* PRINTER: Write Character */ reg_ah=1; /* Report a timeout */ @@ -178,10 +178,10 @@ static Bitu INT17_Handler(void) { static Bitu INT15_Handler(void) { switch (reg_ah) { case 0x06: - LOG(LOG_BIOS,"INT15 Unkown Function 6"); + LOG(LOG_BIOS,LOG_NORMAL)("INT15 Unkown Function 6"); break; case 0xC0: /* Get Configuration*/ - LOG(LOG_ERROR|LOG_BIOS,"Request BIOS Configuration INT 15 C0"); + LOG(LOG_BIOS,LOG_ERROR)("Request BIOS Configuration INT 15 C0"); CALLBACK_SCF(true); break; case 0x4f: /* BIOS - Keyboard intercept */ @@ -229,7 +229,7 @@ static Bitu INT15_Handler(void) { CALLBACK_SCF(true); } } else { - LOG(LOG_ERROR|LOG_BIOS,"INT15:84:Unknown Bios Joystick functionality."); + LOG(LOG_BIOS,LOG_ERROR)("INT15:84:Unknown Bios Joystick functionality."); } break; case 0x86: /* BIOS - WAIT (AT,PS) */ @@ -259,11 +259,11 @@ static Bitu INT15_Handler(void) { Damn programs should use the mouse drivers So let's fail these calls */ - LOG(LOG_BIOS,"INT15:Function %X called,bios mouse not supported",reg_ah); + LOG(LOG_BIOS,LOG_NORMAL)("INT15:Function %X called,bios mouse not supported",reg_ah); CALLBACK_SCF(true); break; default: - LOG(LOG_ERROR|LOG_BIOS,"INT15:Unknown call %2X",reg_ah); + LOG(LOG_BIOS,LOG_ERROR)("INT15:Unknown call %2X",reg_ah); reg_ah=0x86; CALLBACK_SCF(false); } @@ -274,7 +274,7 @@ static Bitu INT1_Single_Step(void) { static bool warned=false; if (!warned) { warned=true; - LOG(LOG_CPU,"INT 1:Single Step called"); + LOG(LOG_CPU,LOG_NORMAL)("INT 1:Single Step called"); } return CBRET_NONE; } diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 298ad39f..afbe92c6 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -34,10 +34,10 @@ static Bitu INT13_SmallHandler(void) { case 0x0: reg_ah=0x00; CALLBACK_SCF(false); - LOG(LOG_BIOS,"reset disk return succesfull"); + LOG(LOG_BIOS,LOG_NORMAL)("reset disk return succesfull"); break; case 0x02: /* Read Disk Sectors */ - LOG(LOG_BIOS,"INT13:02:Read Disk Sectors not supported failing"); + LOG(LOG_BIOS,LOG_NORMAL)("INT13:02:Read Disk Sectors not supported failing"); reg_ah=0x80; CALLBACK_SCF(true); break; @@ -50,17 +50,17 @@ static Bitu INT13_SmallHandler(void) { reg_ah=0x80; CALLBACK_SCF(true); } - LOG(LOG_BIOS,"INT 13:04 Verify sector used on %d, with result %d",reg_dl,reg_ah); + LOG(LOG_BIOS,LOG_NORMAL)("INT 13:04 Verify sector used on %d, with result %d",reg_dl,reg_ah); break; case 0x08: /* Get Drive Parameters */ - LOG(LOG_BIOS,"INT13:08:Get Drive parameters not supported failing"); + LOG(LOG_BIOS,LOG_NORMAL)("INT13:08:Get Drive parameters not supported failing"); reg_ah=0xff; CALLBACK_SCF(true); break; case 0xff: default: - LOG(LOG_ERROR|LOG_BIOS,"Illegal int 13h call %2X Fail it",reg_ah); + LOG(LOG_BIOS,LOG_ERROR)("Illegal int 13h call %2X Fail it",reg_ah); reg_ah=0xff; CALLBACK_SCF(true); } diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index f84a9b5e..80de0814 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -322,7 +322,7 @@ static Bitu INT16_Handler(void) { reg_al=mem_readb(BIOS_KEYBOARD_FLAGS1); break; case 0x03: /* SET TYPEMATIC RATE AND DELAY */ - LOG(LOG_ERROR|LOG_BIOS,"INT16:Unhandled Typematic Rate Call %2X",reg_al); + LOG(LOG_BIOS,LOG_ERROR)("INT16:Unhandled Typematic Rate Call %2X",reg_al); break; case 0x05: /* STORE KEYSTROKE IN KEYBOARD BUFFER */ //TODO make add_key bool :) @@ -335,10 +335,10 @@ static Bitu INT16_Handler(void) { break; case 0x55: /* Weird call used by some dos apps */ - LOG(LOG_BIOS,"INT16:55:Word TSR compatible call"); + LOG(LOG_BIOS,LOG_NORMAL)("INT16:55:Word TSR compatible call"); break; default: - LOG(LOG_ERROR|LOG_BIOS,"INT16:Unhandled call %02X",reg_ah); + LOG(LOG_BIOS,LOG_ERROR)("INT16:Unhandled call %02X",reg_ah); break; }; diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index cb6621b3..52b8a6a3 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -67,7 +67,7 @@ public: device_EMM(){name="EMMXXXX0";} bool Read(Bit8u * data,Bit16u * size) { return false;} bool Write(Bit8u * data,Bit16u * size){ - LOG(LOG_IOCTL,"EMS:Write to device"); + LOG(LOG_IOCTL,LOG_NORMAL)("EMS:Write to device"); return false; } bool Seek(Bit32u * pos,Bit32u type){return false;} @@ -367,7 +367,7 @@ static Bit8u EMM_PartialPageMapping(void) { reg_al=2+reg_bx*(2+sizeof(EMM_Mapping)); break; default: - LOG(LOG_ERROR|LOG_MISC,"EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); + LOG(LOG_MISC,LOG_ERROR)("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); return EMM_FUNC_NOSUP; } return EMM_NO_ERROR; @@ -404,7 +404,7 @@ static Bit8u HandleNameSearch(void) { reg_bx=EMM_MAX_HANDLES; break; default: - LOG(LOG_ERROR|LOG_MISC,"EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); + LOG(LOG_MISC,LOG_ERROR)("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); return EMM_FUNC_NOSUP; } return EMM_NO_ERROR; @@ -422,7 +422,7 @@ static Bit8u GetSetHandleName(void) { MEM_BlockRead(SegPhys(es)+reg_di,emm_handles[handle].name,8); break; default: - LOG(LOG_ERROR|LOG_MISC,"EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); + LOG(LOG_MISC,LOG_ERROR)("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); return EMM_FUNC_NOSUP; } return EMM_NO_ERROR; @@ -449,7 +449,7 @@ static Bit8u MemoryRegion(void) { Bit8u buf_src[EMM_PAGE_SIZE]; Bit8u buf_dest[EMM_PAGE_SIZE]; if (reg_al>1) { - LOG(LOG_ERROR|LOG_MISC,"EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); + LOG(LOG_MISC,LOG_ERROR)("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); return EMM_FUNC_NOSUP; } LoadMoveRegion(SegPhys(ds)+reg_si,region); @@ -610,7 +610,7 @@ static Bitu INT67_Handler(void) { reg_ah=EMM_NO_ERROR; break; default: - LOG(LOG_ERROR|LOG_MISC,"EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); + LOG(LOG_MISC,LOG_ERROR)("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); reg_ah=EMM_FUNC_NOSUP; break; } @@ -653,7 +653,7 @@ static Bitu INT67_Handler(void) { break; case 0x57: /* Memory region */ reg_ah=MemoryRegion(); - if (reg_ah) LOG(LOG_ERROR,"EMS:Function 57 move failed"); + if (reg_ah) LOG(LOG_MISC,LOG_ERROR)("EMS:Function 57 move failed"); break; case 0x58: // Get mappable physical array address array if (reg_al==0x00) { @@ -669,11 +669,11 @@ static Bitu INT67_Handler(void) { reg_ah = EMM_NO_ERROR; break; case 0xDE: /* VCPI Functions */ - LOG(LOG_ERROR|LOG_MISC,"EMS:VCPI Call %2X not supported",reg_al); + LOG(LOG_MISC,LOG_ERROR)("EMS:VCPI Call %2X not supported",reg_al); reg_ah=EMM_FUNC_NOSUP; break; default: - LOG(LOG_ERROR|LOG_MISC,"EMS:Call %2X not supported",reg_ah); + LOG(LOG_MISC,LOG_ERROR)("EMS:Call %2X not supported",reg_ah); reg_ah=EMM_FUNC_NOSUP; break; } diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 571af946..0554cf69 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -42,7 +42,7 @@ static Bitu INT10_Handler(void) { break; case 0x01: /* Set TextMode Cursor Shape */ vga.internal.cursor=reg_cx; // maybe write some memory somewhere - LOG(LOG_INT10,"INT10:01:Set textmode cursor shape partially supported: %X",reg_cx); + LOG(LOG_INT10,LOG_NORMAL)("INT10:01:Set textmode cursor shape partially supported: %X",reg_cx); break; case 0x02: /* Set Cursor Pos */ //TODO Check some shit but not really usefull @@ -58,7 +58,7 @@ static Bitu INT10_Handler(void) { reg_ah=0; break; case 0x05: /* Set Active Page */ - if (reg_al & 0x80) LOG(LOG_INT10,"Func %x",reg_al); + if (reg_al & 0x80) LOG(LOG_INT10,LOG_NORMAL)("Func %x",reg_al); else INT10_SetActivePage(reg_al); break; case 0x06: /* Scroll Up */ @@ -81,7 +81,7 @@ static Bitu INT10_Handler(void) { break; case 0x0B: /* Set Background/Border Colour & Set Palette*/ if(!warned_int10_0b) { - LOG(LOG_ERROR|LOG_INT10,"Function 0B Unsupported: Set Background/border colour & Set Pallete"); + LOG(LOG_INT10,LOG_ERROR)("Function 0B Unsupported: Set Background/border colour & Set Pallete"); warned_int10_0b=true; } break; @@ -135,7 +135,7 @@ static Bitu INT10_Handler(void) { INT10_GetDACBlock(reg_bx,reg_cx,SegPhys(es)+reg_dx); break; default: - LOG(LOG_ERROR|LOG_INT10,"Function 10:Unhandled EGA/VGA Palette Function %2X",reg_al); + LOG(LOG_INT10,LOG_ERROR)("Function 10:Unhandled EGA/VGA Palette Function %2X",reg_al); } break; case 0x11: /* Character generator functions */ @@ -180,12 +180,12 @@ static Bitu INT10_Handler(void) { break; default: reg_cx=16; - LOG(LOG_ERROR|LOG_INT10,"Fucntion 11:30 Request for font %2X",reg_bh); + LOG(LOG_INT10,LOG_ERROR)("Fucntion 11:30 Request for font %2X",reg_bh); } reg_dl=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS); break; default: - LOG(LOG_ERROR|LOG_INT10,"Function 11:Unsupported character generator call %2X",reg_al); + LOG(LOG_INT10,LOG_ERROR)("Function 11:Unsupported character generator call %2X",reg_al); } break; case 0x12: /* alternate function select */ @@ -198,7 +198,7 @@ static Bitu INT10_Handler(void) { break; } default: - LOG(LOG_ERROR|LOG_INT10,"Function 12:Call %2X not handled",reg_bl); + LOG(LOG_INT10,LOG_ERROR)("Function 12:Call %2X not handled",reg_bl); } break; case 0x13: /* Write String */ @@ -223,15 +223,15 @@ static Bitu INT10_Handler(void) { reg_al=0x1B; break; default: - LOG(LOG_ERROR|LOG_INT10,"Function 1B:Unhandled call BX %2X",reg_bx); + LOG(LOG_INT10,LOG_ERROR)("Function 1B:Unhandled call BX %2X",reg_bx); } break; case 0xff: - if (!warned_ff) LOG(LOG_INT10,"INT10:FF:Weird NC call"); + if (!warned_ff) LOG(LOG_INT10,LOG_NORMAL)("INT10:FF:Weird NC call"); warned_ff=true; break; default: - LOG(LOG_ERROR|LOG_INT10,"Function %2X not supported",reg_ah); + LOG(LOG_INT10,LOG_ERROR)("Function %2X not supported",reg_ah); }; return CBRET_NONE; } diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index d2406086..e30dbc7d 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -267,7 +267,7 @@ INLINE static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u at fontdata=&int10_font_16[chr*16]; break; default: - LOG(LOG_ERROR|LOG_INT10,"Teletype Illegal Font Height"); + LOG(LOG_INT10,LOG_ERROR)("Teletype Illegal Font Height"); return; } x=8*col; diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index a7cfc021..36f0bc87 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -224,7 +224,7 @@ void INT10_SetVideoMode(Bit8u mode) { mode&=mode & 127; line=FindVideoMode(mode); if (line==0xff) { - LOG(LOG_ERROR|LOG_INT10,"INT10:Trying to set non supported video mode %X",mode); + LOG(LOG_INT10,LOG_ERROR)("INT10:Trying to set non supported video mode %X",mode); return; } @@ -279,7 +279,7 @@ void INT10_SetVideoMode(Bit8u mode) { IO_Read(VGAREG_ACTL_RESET); //Set the palette - if ((modeset_ctl&0x08)==0x8) LOG(LOG_INT10,"Mode set without palette"); + if ((modeset_ctl&0x08)==0x8) LOG(LOG_INT10,LOG_NORMAL)("Mode set without palette"); if((modeset_ctl&0x08)==0) { // Set the PEL mask IO_Write(VGAREG_PEL_MASK,vga_modes[line].pelmask); diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 934b7279..22e40ac2 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -86,7 +86,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { case CTEXT: case MTEXT: default: - LOG(LOG_ERROR|LOG_INT10,"PutPixel Unhandled memory model %d",curmode->memmodel); + LOG(LOG_INT10,LOG_ERROR)("PutPixel Unhandled memory model %d",curmode->memmodel); break; } } @@ -135,7 +135,7 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { case CTEXT: case MTEXT: default: - LOG(LOG_ERROR|LOG_INT10,"GetPixel Unhandled memory model %d",curmode->memmodel); + LOG(LOG_INT10,LOG_ERROR)("GetPixel Unhandled memory model %d",curmode->memmodel); break; } } diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 949dc7f9..1788e353 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -425,7 +425,7 @@ static void mouse_reset(void) break; default: mouse.max_y=199; - LOG(LOG_MOUSE|LOG_ERROR,"Unhandled videomode %X on reset",mode); + LOG(LOG_MOUSE,LOG_ERROR)("Unhandled videomode %X on reset",mode); break; } mouse.max_x=639; @@ -433,7 +433,7 @@ static void mouse_reset(void) mouse.min_y=0; // Dont set max coordinates here. it is done by SetResolution! mouse.x=0; // civ wont work otherwise - mouse.y=mouse.max_y/2; + mouse.y=static_cast(mouse.max_y/2); mouse.events=0; mouse.mickey_x=0; mouse.mickey_y=0; @@ -517,7 +517,7 @@ static Bitu INT33_Handler(void) { if (!(max & 1)) max--; mouse.min_x=min; mouse.max_x=max; - LOG(LOG_MOUSE,"Define Hortizontal range min:%d max:%d",min,max); + LOG(LOG_MOUSE,LOG_NORMAL)("Define Hortizontal range min:%d max:%d",min,max); } break; case 0x08: /* Define vertical cursor range */ @@ -528,7 +528,7 @@ static Bitu INT33_Handler(void) { if (!(max & 1)) max--; mouse.min_y=min; mouse.max_y=max; - LOG(LOG_MOUSE,"Define Vertical range min:%d max:%d",min,max); + LOG(LOG_MOUSE,LOG_NORMAL)("Define Vertical range min:%d max:%d",min,max); } break; case 0x09: /* Define GFX Cursor */ @@ -595,7 +595,7 @@ static Bitu INT33_Handler(void) { reg_cl=0; /* Hmm ps2 irq dunno */ break; default: - LOG(LOG_ERROR|LOG_MOUSE,"Mouse Function %2X",reg_ax); + LOG(LOG_MOUSE,LOG_ERROR)("Mouse Function %2X",reg_ax); } return CBRET_NONE; } diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index be417848..6db3f299 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -328,7 +328,7 @@ Bitu XMS_ResizeMemory(Bitu handle, Bitu newSize) xms_handles[next].active = false; } else { // Not enough mem available - LOG(LOG_ERROR,"XMS: Resize failure: out of mem 1"); + LOG(LOG_MISC,LOG_ERROR)("XMS: Resize failure: out of mem 1"); return XMS_OUT_OF_SPACE; }; // Resize and allocate new mem @@ -337,7 +337,7 @@ Bitu XMS_ResizeMemory(Bitu handle, Bitu newSize) //CheckAllocationArea(xms_handles[handle].phys,xms_handles[handle].size*1024); } else { // No more free mem ? - LOG(LOG_ERROR,"XMS: Resize failure: out of mem 2"); + LOG(LOG_MISC,LOG_ERROR)("XMS: Resize failure: out of mem 2"); return XMS_OUT_OF_SPACE; }; }; @@ -363,7 +363,7 @@ static bool multiplex_xms(void) { }; Bitu XMS_Handler(void) { - LOG(LOG_ERROR,"XMS: CALL %02X",reg_ah); + LOG(LOG_MISC,LOG_ERROR)("XMS: CALL %02X",reg_ah); switch (reg_ah) { case XMS_GET_VERSION: /* 00 */ @@ -439,11 +439,11 @@ Bitu XMS_Handler(void) { reg_dx=0; break; case XMS_DEALLOCATE_UMB: /* 11 */ - LOG(LOG_ERROR|LOG_MISC,"XMS:Unhandled call %2X",reg_ah); + LOG(LOG_MISC,LOG_ERROR)("XMS:Unhandled call %2X",reg_ah); break; } - LOG(LOG_ERROR,"XMS: CALL Result: %02X",reg_bl); + LOG(LOG_MISC,LOG_ERROR)("XMS: CALL Result: %02X",reg_bl); return CBRET_NONE; } From 656ceb60fd6538b4a1bddf8d4c32cc7f1ea6836a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 5 May 2003 22:13:25 +0000 Subject: [PATCH 0910/4131] Fake PCI Bios Call Add detection of serial ports to be placed in bios data segment. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@990 --- src/ints/bios.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 4af725f1..1ced4de8 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -29,6 +29,9 @@ static Bitu call_int1a,call_int11,call_int8,call_int17,call_int12,call_int15,cal static Bitu call_int1,call_int70; static Bitu INT70_Handler(void) { + /* Acknowledge irq with cmos */ + IO_Write(0x70,0xc); + IO_Read(0x71); if (mem_readb(BIOS_WAIT_FLAG_ACTIVE)) { Bits count=mem_readd(BIOS_WAIT_FLAG_COUNT); if (count>997) { @@ -91,7 +94,11 @@ static Bitu INT1A_Handler(void) { CF clear if sound chip is free Note: the value of CF is not definitive; call this function until CF is clear on return, then call AH=84h"Tandy" -*/ + */ + case 0xb1: /* PCI Bios Calls */ + LOG(LOG_BIOS,LOG_ERROR)("INT1A:PCI bios call %2X",reg_al); + CALLBACK_SCF(true); + break; default: LOG(LOG_BIOS,LOG_ERROR)("INT1A:Undefined call %2X",reg_ah); } @@ -335,8 +342,12 @@ void BIOS_Init(Section* sec) { CALLBACK_Setup(call_int1,&INT1_Single_Step,CB_IRET); RealSetVec(0x1,CALLBACK_RealPointer(call_int1)); - /* Test for some hardware */ - if (IO_Read(0x378)!=0xff) real_writed(0x40,0x08,0x378); + /* Test for parallel port */ + if (IO_Read(0x378)!=0xff) real_writew(0x40,0x08,0x378); + /* Test for serial port */ + Bitu index=0; + if (IO_Read(0x3f8)!=0xff) real_writew(0x40,(index++)*2,0x3f8); + if (IO_Read(0x2f8)!=0xff) real_writew(0x40,(index++)*2,0x2f8); } From c6a015a866353a42293ca09b489f7e4142e014ca Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 6 May 2003 07:25:25 +0000 Subject: [PATCH 0911/4131] Fix some bugs with logging Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@991 --- src/debug/debug_gui.cpp | 66 +++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index c44fb1ba..cc961d51 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -37,37 +37,35 @@ struct _LogGroup { bool enabled; }; -namespace { - _LogGroup loggrp[LOG_MAX]={"",true,0}; - - FILE* debuglog; -}; +static _LogGroup loggrp[LOG_MAX]={"",true,0}; +static FILE* debuglog; extern int old_cursor_state; -void DEBUG_ShowMsg(Bit32u entry, char * format,...) { +void DEBUG_ShowMsg(char * format,...) { - if (!(entry & LOG_ERROR) && entry && !loggrp[entry].enabled) return; - - char buf[1024]; - strcpy(buf,loggrp[entry&127].front); + char buf[512]; va_list msg; va_start(msg,format); - vsprintf(&buf[strlen(buf)],format,msg); + vsprintf(buf,format,msg); va_end(msg); wprintw(dbg.win_out,"%10d: %s\n",cycle_count,buf); wrefresh(dbg.win_out); if(debuglog) fprintf(debuglog,"%10d: %s\n",cycle_count,buf); } + void LOG::operator() (char* format, ...){ - char buf[1024]; + char buf[512]; va_list msg; va_start(msg,format); vsprintf(buf,format,msg); va_end(msg); - DEBUG_ShowMsg(this->d_type|this->d_severity,buf); + + if (d_type>=LOG_MAX) return; + if ((d_severity!=LOG_ERROR) && (!loggrp[d_type].enabled)) return; + DEBUG_ShowMsg("%s:%s",loggrp[d_type].front,buf); } @@ -159,6 +157,7 @@ static void LOG_Init(Section * sec) { for (Bitu i=1;iGet_bool(buf); } } @@ -166,30 +165,33 @@ static void LOG_Init(Section * sec) { void LOG_StartUp(void) { /* Setup logging groups */ - loggrp[LOG_VGA].front="VGA:"; - loggrp[LOG_VGAGFX].front="VGAGFX:"; - loggrp[LOG_VGAMISC].front="VGAMISC:"; - loggrp[LOG_INT10].front="INT10:"; - loggrp[LOG_SB].front="SBLASTER:"; - loggrp[LOG_DMA].front="DMA:"; + loggrp[LOG_ALL].front="ALL"; + loggrp[LOG_VGA].front="VGA"; + loggrp[LOG_VGAGFX].front="VGAGFX"; + loggrp[LOG_VGAMISC].front="VGAMISC"; + loggrp[LOG_INT10].front="INT10"; + loggrp[LOG_SB].front="SBLASTER"; + loggrp[LOG_DMA].front="DMA"; - loggrp[LOG_FPU].front="FPU:"; - loggrp[LOG_CPU].front="CPU:"; + loggrp[LOG_FPU].front="FPU"; + loggrp[LOG_CPU].front="CPU"; - loggrp[LOG_FCB].front="FCB:"; - loggrp[LOG_FILES].front="FILES:"; - loggrp[LOG_IOCTL].front="IOCTL:"; + loggrp[LOG_FCB].front="FCB"; + loggrp[LOG_FILES].front="FILES"; + loggrp[LOG_IOCTL].front="IOCTL"; loggrp[LOG_EXEC].front="EXEC"; - loggrp[LOG_DOSMISC].front="DOSMISC:"; + loggrp[LOG_DOSMISC].front="DOSMISC"; - loggrp[LOG_PIT].front="PIT:"; - loggrp[LOG_KEYBOARD].front="KEYBOARD:"; - loggrp[LOG_PIC].front="PIC:"; + loggrp[LOG_PIT].front="PIT"; + loggrp[LOG_KEYBOARD].front="KEYBOARD"; + loggrp[LOG_PIC].front="PIC"; - loggrp[LOG_MOUSE].front="MOUSE:"; - loggrp[LOG_BIOS].front="BIOS:"; - loggrp[LOG_GUI].front="GUI:"; - loggrp[LOG_MISC].front="MISC:"; + loggrp[LOG_MOUSE].front="MOUSE"; + loggrp[LOG_BIOS].front="BIOS"; + loggrp[LOG_GUI].front="GUI"; + loggrp[LOG_MISC].front="MISC"; + + loggrp[LOG_IO].front="IO"; /* Register the log section */ Section_prop * sect=control->AddSection_prop("log",LOG_Init); From 05fcec5b12a47a620cf623247d206dcfdbf8bef7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 6 May 2003 07:25:58 +0000 Subject: [PATCH 0912/4131] Cleaned up some more logging functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@992 --- include/dosbox.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/dosbox.h b/include/dosbox.h index 6d0696a6..789aa646 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -22,8 +22,6 @@ void E_Exit(char * message,...); -void S_Warn(char * message,...); - void MSG_Add(const char*,const char*); //add messages to the internal langaugefile const char* MSG_Get(char const *); //get messages from the internal langaugafile @@ -68,7 +66,5 @@ extern Bitu errorlevel; #include "logging.h" #endif // the logging system. -#define LOG_MSG S_Warn - #endif /* __DOSBOX_H */ From 830a9f81e92236405e8ba870747d059d76fed8dc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 6 May 2003 07:31:38 +0000 Subject: [PATCH 0913/4131] New logging target LOG_IO Changed handling of logging without C_DEBUG Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@993 --- include/logging.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/include/logging.h b/include/logging.h index 9821ee50..c4fe491a 100644 --- a/include/logging.h +++ b/include/logging.h @@ -8,13 +8,14 @@ enum LOG_TYPES { LOG_FCB,LOG_FILES,LOG_IOCTL,LOG_EXEC,LOG_DOSMISC, LOG_PIT,LOG_KEYBOARD,LOG_PIC, LOG_MOUSE,LOG_BIOS,LOG_GUI,LOG_MISC, - LOG_MAX + LOG_IO, + LOG_MAX, }; enum LOG_SEVERITIES { LOG_NORMAL, LOG_WARN, - LOG_ERROR + LOG_ERROR, }; #if C_DEBUG @@ -32,6 +33,8 @@ public: }; +void DEBUG_ShowMsg(char * format,...); +#define LOG_MSG DEBUG_ShowMsg #else //C_DEBUG @@ -61,6 +64,8 @@ struct LOG }; //add missing operators to here //try to avoid anything smaller than bit32... +void GFX_ShowMsg(char * format,...); +#define LOG_MSG GFX_ShowMsg #endif //C_DEBUG From bd049528785aed47c42564d7e09cd6f75d480f07 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 6 May 2003 07:35:44 +0000 Subject: [PATCH 0914/4131] Updated GFX_ShowMsg to use variable arguments Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@994 --- src/gui/sdlmain.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 4928e394..5dfd1dde 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include "SDL.h" #include "SDL_thread.h" @@ -532,10 +533,12 @@ void GFX_Events() { } } -void GFX_ShowMsg(char * msg) { - char buf[1024]; - strcpy(buf,msg); - strcat(buf,"\n"); +void GFX_ShowMsg(char * format,...) { + char buf[512]; + va_list msg; + va_start(msg,format); + vsprintf(buf,format,msg); + va_end(msg); printf(buf); }; @@ -550,7 +553,7 @@ int main(int argc, char* argv[]) { DEBUG_SetupConsole(); #endif - if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM + if ( SDL_Init( SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM #ifndef DISABLE_JOYSTICK |SDL_INIT_JOYSTICK From 83a044b472639e086bbe7c685dd95bc4a437adfc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 6 May 2003 07:43:01 +0000 Subject: [PATCH 0915/4131] New logging mesages for IO Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@995 --- src/hardware/iohandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index be6e2d61..4dcf0c78 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -42,13 +42,13 @@ static void IO_WriteBlocked(Bit32u port,Bit8u val) { } static Bit8u IO_ReadDefault(Bit32u port) { - LOG(LOG_ALL,LOG_ERROR)("Reading from undefined port %04X",port); + LOG(LOG_IO,LOG_ERROR)("Reading from undefined port %04X",port); IO_RegisterReadHandler(port,&IO_ReadBlocked,"Blocked Read"); return 0xff; } void IO_WriteDefault(Bit32u port,Bit8u val) { - LOG(LOG_ALL,LOG_ERROR)("Writing %02X to undefined port %04X",static_cast(val),port); + LOG(LOG_IO,LOG_ERROR)("Writing %02X to undefined port %04X",val,port); IO_RegisterWriteHandler(port,&IO_WriteBlocked,"Blocked Write"); } From 62a2b2b34ec2c0efea4068ee3b4af1b62e9731b3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 6 May 2003 07:44:20 +0000 Subject: [PATCH 0916/4131] Added better timer flag support when not running in a periodic timer mode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@996 --- src/hardware/cmos.cpp | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 3f9a4be5..8d15b2ed 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -34,7 +34,11 @@ static struct { Bit8u div; Bitu micro; } timer; - Bit8u status_c; + struct { + Bit64u timer; + Bit64u ended; + Bit64u alarm; + } last; bool ack; bool update_ended; } cmos; @@ -43,16 +47,16 @@ static void cmos_timerevent(void) { PIC_ActivateIRQ(8); if (cmos.ack) { PIC_AddEvent(cmos_timerevent,cmos.timer.micro); - cmos.status_c=0x20; + cmos.regs[0x0c]|=0x0a0; cmos.ack=false; } } static void cmos_checktimer(void) { PIC_RemoveEvents(cmos_timerevent); - if (!cmos.timer.div || !cmos.timer.enabled) return; if (cmos.timer.div<=2) cmos.timer.div+=7; - cmos.timer.micro=(Bitu) (10000000.0/(32768.0 / (1 << (cmos.timer.div - 1)))); + cmos.timer.micro=(Bitu) (1000000.0/(32768.0 / (1 << (cmos.timer.div - 1)))); + if (!cmos.timer.div || !cmos.timer.enabled) return; LOG(LOG_PIT,LOG_NORMAL)("RTC Timer at %f hz",1000000.0/cmos.timer.micro); PIC_AddEvent(cmos_timerevent,cmos.timer.micro); } @@ -138,12 +142,33 @@ static Bit8u cmos_readreg(Bit32u port) { case 0x03: /* Minutes Alarm */ case 0x05: /* Hours Alarm */ return cmos.regs[cmos.reg]; - case 0x0c: - if (cmos.ack) return 0; - else { - cmos.ack=true; - return 0x80|cmos.status_c; + case 0x0a: /* Status register C */ + if (PIC_Index()<0x2) { + return (cmos.regs[0x0a]&0x7f) | 0x80; + } else { + return (cmos.regs[0x0a]&0x7f); } + case 0x0c: /* Status register C */ + if (cmos.timer.enabled) { + /* In periodic interrupt mode only care for those flags */ + Bit8u val=cmos.regs[0xc]; + cmos.regs[0xc]=0; + return val; + } else { + /* Give correct values at certain times */ + Bit8u val=0; + Bit64u index=PIC_MicroCount(); + if (index>=(cmos.last.timer+cmos.timer.micro)) { + cmos.last.timer=index; + val|=0x40; + } + if (index>=(cmos.last.ended+1000000)) { + cmos.last.ended=index; + val|=0x10; + } + return val; + } + case 0x0b: /* Status register B */ case 0x0f: /* Shutdown status byte */ case 0x17: /* Extended memory in KB Low Byte */ case 0x18: /* Extended memory in KB High Byte */ From 8b644202c24dd7b64364f11cd7f6dae5f7076d97 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 7 May 2003 11:00:34 +0000 Subject: [PATCH 0917/4131] Add warning when FPU opcodes are used Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@997 --- src/cpu/core_full/op.h | 3 +++ src/cpu/core_full/optable.h | 16 ++++++++-------- src/cpu/core_full/support.h | 1 + 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 1d2c3241..3d755dc0 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -538,6 +538,9 @@ switch (inst.code.op) { case O_BSWAP: BSWAP(inst.op1.d); break; + case O_FPU: + LOG_MSG("FPU opcode %X unhandled",inst.entry); + break; case 0: break; default: diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 7999ef97..03534e70 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -153,10 +153,10 @@ static OpCode OpCodeTable[1024]={ {D_SETALC ,0 ,0 ,0 },{D_XLATw ,0 ,0 ,0 }, //TODO FPU /* 0xd8 - 0xdf */ -{L_MODRM ,0 ,0 ,0 },{L_MODRM ,0 ,0 ,0 }, -{L_MODRM ,0 ,0 ,0 },{L_MODRM ,0 ,0 ,0 }, -{L_MODRM ,0 ,0 ,0 },{L_MODRM ,0 ,0 ,0 }, -{L_MODRM ,0 ,0 ,0 },{L_MODRM ,0 ,0 ,0 }, +{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,0 ,0 }, +{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,0 ,0 }, +{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,0 ,0 }, +{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,0 ,0 }, /* 0xe0 - 0xe7 */ {L_Ibx ,O_LOOPNZ ,S_AIPw ,0 },{L_Ibx ,O_LOOPZ ,S_AIPw ,0 }, @@ -510,10 +510,10 @@ static OpCode OpCodeTable[1024]={ {L_Ib ,O_AAM ,0 ,0 },{L_Ib ,O_AAD ,0 ,0 }, {D_SETALC ,0 ,0 ,0 },{D_XLATd ,0 ,0 ,0 }, /* 0x2d8 - 0x2df */ -{L_MODRM ,0 ,0 ,0 },{L_MODRM ,0 ,0 ,0 }, -{L_MODRM ,0 ,0 ,0 },{L_MODRM ,0 ,0 ,0 }, -{L_MODRM ,0 ,0 ,0 },{L_MODRM ,0 ,0 ,0 }, -{L_MODRM ,0 ,0 ,0 },{L_MODRM ,0 ,0 ,0 }, +{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,0 ,0 }, +{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,0 ,0 }, +{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,0 ,0 }, +{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,0 ,0 }, /* 0x2e0 - 0x2e7 */ {L_Ibx ,O_LOOPNZ ,S_AIPd ,0 },{L_Ibx ,O_LOOPZ ,S_AIPd ,0 }, diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index abaa6143..5a9e9634 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -90,6 +90,7 @@ enum { O_BSFw,O_BSRw, O_BSWAP, + O_FPU, }; From b48f2de04d58f92afa6e632e027607aad772aecf Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 11 May 2003 10:08:35 +0000 Subject: [PATCH 0918/4131] Updated for new logging system. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@998 --- src/gui/midi_alsa.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 0f2ae276..e1b9735a 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -110,7 +110,7 @@ public: } break; default: - LOG(LOG_MISC,"ALSA:Unknown Command: %08x", (int)msg); + LOG(LOG_MISC,LOG_WARN)("ALSA:Unknown Command: %08x", (int)msg); send_event(1); break; } From 9ac410383d3489f9a354027e2b543ed2e7c56397 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 11 May 2003 10:16:09 +0000 Subject: [PATCH 0919/4131] Clear out DEBUG_ShowMsg define Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@999 --- src/debug/debug.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 0f1d90ec..efc2ecbd 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -53,8 +53,6 @@ char* AnalyzeInstruction(char* inst, bool saveSelector); void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num); class DEBUG; -extern void DEBUG_ShowMsg(Bit32u entry, char* format, ...); - DEBUG* pDebugcom = 0; bool exitLoop = false; bool logHeavy = false; @@ -517,7 +515,7 @@ static bool StepOver() // PhysPt start=SegPhys(cs)+reg_eip; PhysPt start=GetAddress(SegValue(cs),reg_eip); char dline[200];Bitu size; - size=DasmI386(dline, start, reg_eip, (cpu.state & STATE_USE32>0)); + size=DasmI386(dline, start, reg_eip, (cpu.state & STATE_USE32)>0); if (strstr(dline,"call") || strstr(dline,"int") || strstr(dline,"loop") || strstr(dline,"rep")) { CBreakpoint::AddBreakpoint (SegValue(cs),reg_eip+size, true); From bcfeb644133b8051b5d147f83ec89e967d21f35e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 11 May 2003 10:17:58 +0000 Subject: [PATCH 0920/4131] newline at the end Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1000 --- src/debug/debug_inc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h index 880f7ea2..e3d5834f 100644 --- a/src/debug/debug_inc.h +++ b/src/debug/debug_inc.h @@ -51,7 +51,7 @@ struct DASMLine { extern DBGBlock dbg; - /* Local Debug Stuff */ Bitu DasmI386(char* buffer, PhysPt pc, Bitu cur_ip, bool bit32); -int DasmLastOperandSize(void); \ No newline at end of file +int DasmLastOperandSize(void); + From 6b178aefa90b0fb2485141f3fb5d2df832afb849 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 11 May 2003 10:18:32 +0000 Subject: [PATCH 0921/4131] Removed S_Warn Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1001 --- src/misc/support.cpp | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/misc/support.cpp b/src/misc/support.cpp index bc00cdf1..2bc35acc 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -154,22 +154,6 @@ char * StripWord(char * cmd) { } return trim(cmd+strlen(begin)+1); } -extern void DEBUG_ShowMsg(Bit32u entry,char* format,...); -extern void GFX_ShowMsg(char * msg); - -void S_Warn(char * format,...) { - char buf[1024]; - va_list msg; - - va_start(msg,format); - vsprintf(buf,format,msg); - va_end(msg); -#if C_DEBUG - DEBUG_ShowMsg(0,buf); -#else - GFX_ShowMsg(buf); -#endif -} static char buf[1024]; //greater scope as else it doesn't always gets thrown right (linux/gcc2.95) void E_Exit(char * format,...) { From e139c8f9cbea28a0618d57a673b615bfa0a572dc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 11 May 2003 10:19:26 +0000 Subject: [PATCH 0922/4131] newline at end of file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1002 --- src/ints/xms.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/xms.h b/src/ints/xms.h index 8f7fd68e..18360a33 100644 --- a/src/ints/xms.h +++ b/src/ints/xms.h @@ -34,4 +34,4 @@ Bitu XMS_ResizeMemory (Bitu handle, Bitu newSize); Bitu XMS_EnableA20 (bool enable); Bitu XMS_GetEnabledA20 (void); -#endif \ No newline at end of file +#endif From 4dc60a22dbbae122ea919830ec367a88d9892cd0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 11 May 2003 14:55:21 +0000 Subject: [PATCH 0923/4131] Log types no longer have : Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1003 --- src/debug/debug_gui.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index cc961d51..0bd77a0e 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -199,7 +199,6 @@ void LOG_StartUp(void) { char buf[1024]; for (Bitu i=1;iAdd_bool(buf,true); } From 91a11bffcf6cce91ae5ac05cefad8a5ecf08cde9 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 11 May 2003 16:50:21 +0000 Subject: [PATCH 0924/4131] Fixed bug in returning disc label Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1004 --- src/dos/drive_local.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 3e3a3ebf..991a9dbc 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -120,10 +120,13 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { Bit8u sAttr; dta.GetSearchParams(sAttr,tempDir); - if (sAttr & DOS_ATTR_VOLUME) { - // Get Volume Label - dta.SetResult(dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME); - return true; + if ((sAttr & DOS_ATTR_VOLUME) && (*_dir==0)) { + // Get Volume Label (DOS_ATTR_VOLUME) and only in basedir + if (WildFileCmp(dirCache.GetLabel(),tempDir)) { + // Get Volume Label + dta.SetResult(dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME); + return true; + } } return FindNext(dta); } From 75caa32ce0836e54f559b83d28b58bc42679584c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 11 May 2003 17:25:17 +0000 Subject: [PATCH 0925/4131] removed the 0, from all debug_showmsg calls. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1005 --- src/debug/debug.cpp | 62 ++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index efc2ecbd..ec68da39 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -336,7 +336,7 @@ bool CBreakpoint::CheckBreakpoint(PhysPt adr) if (bp->GetValue() != value) { // Yup, memory value changed - DEBUG_ShowMsg(0,"DEBUG: Memory breakpoint: %04X:%04X - %02X -> %02X",bp->GetSegment(),bp->GetOffset(),bp->GetValue(),value); + DEBUG_ShowMsg("DEBUG: Memory breakpoint: %04X:%04X - %02X -> %02X",bp->GetSegment(),bp->GetOffset(),bp->GetValue(),value); bp->SetValue(value); return true; }; @@ -822,7 +822,7 @@ bool ParseCommand(char* str) }; name[15] = 0; - DEBUG_ShowMsg(0,"DEBUG: Created debug var %s at %04X:%04X",name,seg,ofs); + DEBUG_ShowMsg("DEBUG: Created debug var %s at %04X:%04X",name,seg,ofs); CDebugVar::InsertVariable(name,GetAddress(seg,ofs)); return true; } @@ -836,8 +836,8 @@ bool ParseCommand(char* str) else { name[i] = 0; break; }; }; name[12] = 0; - if (CDebugVar::SaveVars(name)) DEBUG_ShowMsg(0,"DEBUG: Variable list save (%s) : ok.",name); - else DEBUG_ShowMsg(0,"DEBUG: Variable list save (%s) : failure",name); + if (CDebugVar::SaveVars(name)) DEBUG_ShowMsg("DEBUG: Variable list save (%s) : ok.",name); + else DEBUG_ShowMsg("DEBUG: Variable list save (%s) : failure",name); return true; } @@ -850,8 +850,8 @@ bool ParseCommand(char* str) else { name[i] = 0; break; }; }; name[12] = 0; - if (CDebugVar::LoadVars(name)) DEBUG_ShowMsg(0,"DEBUG: Variable list load (%s) : ok.",name); - else DEBUG_ShowMsg(0,"DEBUG: Variable list load (%s) : failure",name); + if (CDebugVar::LoadVars(name)) DEBUG_ShowMsg("DEBUG: Variable list load (%s) : ok.",name); + else DEBUG_ShowMsg("DEBUG: Variable list load (%s) : failure",name); return true; } @@ -861,7 +861,7 @@ bool ParseCommand(char* str) Bit16u seg = GetHexValue(found,found);found++; // skip ":" Bit32u ofs = GetHexValue(found,found); CBreakpoint::AddBreakpoint(seg,ofs,false); - DEBUG_ShowMsg(0,"DEBUG: Set breakpoint at %04X:%04X",seg,ofs); + DEBUG_ShowMsg("DEBUG: Set breakpoint at %04X:%04X",seg,ofs); return true; } #if C_HEAVY_DEBUG @@ -871,7 +871,7 @@ bool ParseCommand(char* str) Bit16u seg = GetHexValue(found,found);found++; // skip ":" Bit32u ofs = GetHexValue(found,found); CBreakpoint::AddMemBreakpoint(seg,ofs); - DEBUG_ShowMsg(0,"DEBUG: Set memory breakpoint at %04X:%04X",seg,ofs); + DEBUG_ShowMsg("DEBUG: Set memory breakpoint at %04X:%04X",seg,ofs); return true; } #endif @@ -882,10 +882,10 @@ bool ParseCommand(char* str) Bit8u valAH = GetHexValue(found,found); if ((valAH==0x00) && (*found=='*')) { CBreakpoint::AddIntBreakpoint(intNr,BPINT_ALL,false); - DEBUG_ShowMsg(0,"DEBUG: Set interrupt breakpoint at INT %02X",intNr); + DEBUG_ShowMsg("DEBUG: Set interrupt breakpoint at INT %02X",intNr); } else { CBreakpoint::AddIntBreakpoint(intNr,valAH,false); - DEBUG_ShowMsg(0,"DEBUG: Set interrupt breakpoint at INT %02X AH=%02X",intNr,valAH); + DEBUG_ShowMsg("DEBUG: Set interrupt breakpoint at INT %02X AH=%02X",intNr,valAH); } return true; } @@ -904,7 +904,7 @@ bool ParseCommand(char* str) Bit8u bpNr = GetHexValue(found,found); if ((bpNr==0x00) && (*found=='*')) { // Delete all CBreakpoint::DeleteAll(); - DEBUG_ShowMsg(0,"DEBUG: Breakpoints deleted."); + DEBUG_ShowMsg("DEBUG: Breakpoints deleted."); } else { // delete single breakpoint CBreakpoint::DeleteByIndex(bpNr); @@ -916,7 +916,7 @@ bool ParseCommand(char* str) found++; Bit16u codeSeg = GetHexValue(found,found); found++; Bit32u codeOfs = GetHexValue(found,found); - DEBUG_ShowMsg(0,"DEBUG: Set code overview to %04X:%04X",codeSeg,codeOfs); + DEBUG_ShowMsg("DEBUG: Set code overview to %04X:%04X",codeSeg,codeOfs); codeViewData.useCS = codeSeg; codeViewData.useEIP = codeOfs; return true; @@ -926,22 +926,22 @@ bool ParseCommand(char* str) found++; dataSeg = GetHexValue(found,found); found++; dataOfs = GetHexValue(found,found); - DEBUG_ShowMsg(0,"DEBUG: Set data overview to %04X:%04X",dataSeg,dataOfs); + DEBUG_ShowMsg("DEBUG: Set data overview to %04X:%04X",dataSeg,dataOfs); return true; } found = strstr(str,"LOG "); if (found) { // Create Cpu log file found+=4; - DEBUG_ShowMsg(0,"DEBUG: Starting log"); + DEBUG_ShowMsg("DEBUG: Starting log"); DEBUG_Log_Loop(GetHexValue(found,found)); - DEBUG_ShowMsg(0,"DEBUG: Logfile LOGCPU.TXT created."); + DEBUG_ShowMsg("DEBUG: Logfile LOGCPU.TXT created."); return true; } found = strstr(str,"SR "); if (found) { // Set register value found+=2; - if (ChangeRegister(found)) DEBUG_ShowMsg(0,"DEBUG: Set Register success."); - else DEBUG_ShowMsg(0,"DEBUG: Set Register failure."); + if (ChangeRegister(found)) DEBUG_ShowMsg("DEBUG: Set Register success."); + else DEBUG_ShowMsg("DEBUG: Set Register failure."); return true; } found = strstr(str,"SM "); @@ -958,14 +958,14 @@ bool ParseCommand(char* str) count++; } }; - DEBUG_ShowMsg(0,"DEBUG: Memory changed."); + DEBUG_ShowMsg("DEBUG: Memory changed."); return true; } found = strstr(str,"INTT "); if (found) { // Create Cpu log file found+=4; Bit8u intNr = GetHexValue(found,found); - DEBUG_ShowMsg(0,"DEBUG: Tracing INT %02X",intNr); + DEBUG_ShowMsg("DEBUG: Tracing INT %02X",intNr); Interrupt(intNr); SetCodeWinStart(); return true; @@ -974,7 +974,7 @@ bool ParseCommand(char* str) if (found) { // Create Cpu log file found+=4; Bit8u intNr = GetHexValue(found,found); - DEBUG_ShowMsg(0,"DEBUG: Starting INT %02X",intNr); + DEBUG_ShowMsg("DEBUG: Starting INT %02X",intNr); CBreakpoint::AddBreakpoint (SegValue(cs),reg_eip, true); CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip-1,true); debugging=false; @@ -989,17 +989,17 @@ bool ParseCommand(char* str) while (found[0]==' ') found++; char out1[200],out2[200]; GetDescriptorInfo(found,out1,out2); - DEBUG_ShowMsg(0,"SelectorInfo %s:",found); - DEBUG_ShowMsg(0,"%s",out1); - DEBUG_ShowMsg(0,"%s",out2); + DEBUG_ShowMsg("SelectorInfo %s:",found); + DEBUG_ShowMsg("%s",out1); + DEBUG_ShowMsg("%s",out2); }; #if C_HEAVY_DEBUG found = strstr(str,"HEAVYLOG"); if (found) { // Create Cpu log file logHeavy = !logHeavy; - if (logHeavy) DEBUG_ShowMsg(0,"DEBUG: Heavy cpu logging on."); - else DEBUG_ShowMsg(0,"DEBUG: Heavy cpu logging off."); + if (logHeavy) DEBUG_ShowMsg("DEBUG: Heavy cpu logging on."); + else DEBUG_ShowMsg("DEBUG: Heavy cpu logging off."); return true; } #endif @@ -1209,7 +1209,7 @@ Bit32u DEBUG_CheckKeys(void) { ParseCommand(codeViewData.inputStr); break; case 'T' : DEBUG_RaiseTimerIrq(); - DEBUG_ShowMsg(0,"Debug: Timer Int started."); + DEBUG_ShowMsg("Debug: Timer Int started."); break; case 'V' : showExtend = !showExtend; break; @@ -1544,7 +1544,7 @@ void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num) { FILE* f = fopen("MEMDUMP.TXT","wt"); if (!f) { - DEBUG_ShowMsg(0,"DEBUG: Memory dump failed."); + DEBUG_ShowMsg("DEBUG: Memory dump failed."); return; } @@ -1564,7 +1564,7 @@ void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num) fprintf(f,"%s\n",buffer); }; fclose(f); - DEBUG_ShowMsg(0,"DEBUG: Memory dump success."); + DEBUG_ShowMsg("DEBUG: Memory dump success."); }; // HEAVY DEBUGGING STUFF @@ -1597,11 +1597,11 @@ void DEBUG_HeavyWriteLogInstruction(void) logHeavy = false; - DEBUG_ShowMsg(0,"DEBUG: Creating cpu log LOGCPU_INT_CD.TXT"); + DEBUG_ShowMsg("DEBUG: Creating cpu log LOGCPU_INT_CD.TXT"); FILE* f = fopen("LOGCPU_INT_CD.TXT","wt"); if (!f) { - DEBUG_ShowMsg(0,"DEBUG: Failed."); + DEBUG_ShowMsg("DEBUG: Failed."); return; } @@ -1614,7 +1614,7 @@ void DEBUG_HeavyWriteLogInstruction(void) fclose(f); - DEBUG_ShowMsg(0,"DEBUG: Done."); + DEBUG_ShowMsg("DEBUG: Done."); }; bool DEBUG_HeavyIsBreakpoint(void) From 60292fb70fc740e5a5f417ba9a8d5bacef4b6d04 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 11 May 2003 17:48:01 +0000 Subject: [PATCH 0926/4131] fixed ambiguos call Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1006 --- src/hardware/iohandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 4dcf0c78..628a7361 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -48,7 +48,7 @@ static Bit8u IO_ReadDefault(Bit32u port) { } void IO_WriteDefault(Bit32u port,Bit8u val) { - LOG(LOG_IO,LOG_ERROR)("Writing %02X to undefined port %04X",val,port); + LOG(LOG_IO,LOG_ERROR)("Writing %02X to undefined port %04X",static_cast(val),port); IO_RegisterWriteHandler(port,&IO_WriteBlocked,"Blocked Write"); } From f64cceafdf0b38a3b5686d1ce7a23f8859c94599 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 11 May 2003 19:51:31 +0000 Subject: [PATCH 0927/4131] added const to some char* and some other changes to get it compiling under gcc Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1007 --- include/logging.h | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/include/logging.h b/include/logging.h index c4fe491a..62435fa4 100644 --- a/include/logging.h +++ b/include/logging.h @@ -41,24 +41,24 @@ void DEBUG_ShowMsg(char * format,...); struct LOG { LOG(LOG_TYPES type, LOG_SEVERITIES severity) { return;} - void operator()(char* buf) { return;} - void operator()(char* buf, double f1) { return;} - void operator()(char* buf, double f1, Bit32u u1) { return;} - void operator()(char* buf, Bitu u1, double f1) { return;} + void operator()(char const* buf) { return;} + void operator()(char const* buf, double f1) { return;} + void operator()(char const* buf, double f1, Bit32u u1) { return;} + void operator()(char const* buf, Bitu u1, double f1) { return;} - void operator()(char* buf, Bitu u1, Bitu u2) { return;} - void operator()(char* buf, Bits u1, Bits u2) { return;} - void operator()(char* buf, Bitu u1, Bits u2) { return;} - void operator()(char* buf, Bits u1, Bitu u2) { return;} - void operator()(char* buf, Bit32s u1) { return;} - void operator()(char* buf, Bit32u u1) { return;} - void operator()(char* buf, Bits s1) { return;} - void operator()(char* buf, Bitu u1) { return;} + void operator()(char const* buf, Bitu u1, Bitu u2) { return;} + void operator()(char const* buf, Bits u1, Bits u2) { return;} + void operator()(char const* buf, Bitu u1, Bits u2) { return;} + void operator()(char const* buf, Bits u1, Bitu u2) { return;} + void operator()(char const* buf, Bit32s& u1) { return;} + void operator()(char const* buf, Bit32u& u1) { return;} + void operator()(char const* buf, Bits& s1) { return;} + void operator()(char const* buf, Bitu& u1) { return;} - void operator()(char* buf, char* s1) { return;} - void operator()(char* buf, char* s1, Bit32u u1) { return;} - void operator()(char* buf, char* s1, Bit32u u1, Bit32u u2) { return;} - void operator()(char* buf, Bit32u u1, char* s1) { return;} + void operator()(char const* buf, char const* s1) { return;} + void operator()(char const* buf, char const* s1, Bit32u u1) { return;} + void operator()(char const* buf, char const* s1, Bit32u u1, Bit32u u2) { return;} + void operator()(char const* buf, Bit32u u1, char const* s1) { return;} From 27d7b02a31a9b2ebafb6a7f935cad19c2111ba30 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 12 May 2003 09:19:55 +0000 Subject: [PATCH 0928/4131] Added patches from Guillaume Serre and Justin. Changed copy to strip *.* from target Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1008 --- src/shell/shell.cpp | 16 ++-- src/shell/shell_cmds.cpp | 32 ++++---- src/shell/shell_inc.h | 21 +++-- src/shell/shell_misc.cpp | 163 ++++++++++++++++++++++++++++++--------- 4 files changed, 164 insertions(+), 68 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index c360ef8e..1af2b57d 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -50,14 +50,13 @@ void SHELL_AddAutoexec(char * line,...) { sprintf((autoexec_data+auto_len),"%s\r\n",buf); } - DOS_Shell::DOS_Shell():Program(){ input_handle=STDIN; echo=true; exit=false; bf=0; - memset(&old.buffer,0,CMD_OLDSIZE); - old.size=0; + + completion_start = NULL; } @@ -65,11 +64,14 @@ DOS_Shell::DOS_Shell():Program(){ Bit32u DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn) { + char *output = strrchr(s, '>'); + if (output) { + *output = 0; + // while (!isalnum(*output)) output++; + } return 1; -} - - +} void DOS_Shell::ParseLine(char * line) { @@ -81,7 +83,7 @@ void DOS_Shell::ParseLine(char * line) { line=trim(line); Bit32u num=0; /* Number of commands in this line */ - num = GetRedirection(line,&in, &out); + num = GetRedirection(line, &in, &out); /* TODO in and out redirection */ diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 4095302c..601ae88d 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -24,31 +24,30 @@ static SHELL_Cmd cmd_list[]={ -{ "CD", 0, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"}, +{ "CHDIR", 0, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"}, +{ "CD", 1, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"}, { "CLS", 0, &DOS_Shell::CMD_CLS, "SHELL_CMD_CLS_HELP"}, { "COPY", 0, &DOS_Shell::CMD_COPY, "SHELL_CMD_COPY_HELP"}, { "DIR", 0, &DOS_Shell::CMD_DIR, "SHELL_CMD_DIR_HELP"}, { "DEL", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, { "DELETE", 0, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, +{ "ERASE", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, { "ECHO", 0, &DOS_Shell::CMD_ECHO, "SHELL_CMD_ECHO_HELP"}, { "ECHO.", 1, &DOS_Shell::CMD_EHCODOT, "SHELL_CMD_ECHO_HELP"}, { "EXIT", 0, &DOS_Shell::CMD_EXIT, "SHELL_CMD_EXIT_HELP"}, { "HELP", 0, &DOS_Shell::CMD_HELP, "SHELL_CMD_HELP_HELP"}, -{ "MD", 0, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP"}, -{ "RD", 0, &DOS_Shell::CMD_RMDIR, "SHELL_CMD_RMDIR_HELP"}, +{ "MKDIR", 0, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP"}, +{ "MD", 1, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP"}, +{ "RMDIR", 0, &DOS_Shell::CMD_RMDIR, "SHELL_CMD_RMDIR_HELP"}, +{ "RD", 1, &DOS_Shell::CMD_RMDIR, "SHELL_CMD_RMDIR_HELP"}, { "SET", 0, &DOS_Shell::CMD_SET, "SHELL_CMD_SET_HELP"}, -{ "IF", 0, &DOS_Shell::CMD_IF, "SHELL_CMD_IF_HELP"}, +{ "IF", 0, &DOS_Shell::CMD_IF, "SHELL_CMD_IF_HELP"}, { "GOTO", 0, &DOS_Shell::CMD_GOTO, "SHELL_CMD_GOTO_HELP"}, { "TYPE", 0, &DOS_Shell::CMD_TYPE, "SHELL_CMD_TYPE_HELP"}, { "REM", 0, &DOS_Shell::CMD_REM, "SHELL_CMD_REM_HELP"}, { "RENAME", 0, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP"}, { "REN", 1, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP"}, { "PAUSE", 0, &DOS_Shell::CMD_PAUSE, "SHELL_CMD_PAUSE_HELP"}, -/* - "CHDIR", 0, &DOS_Shell::CMD_CHDIR, "Change Directory", - "MKDIR", 0, &DOS_Shell::CMD_MKDIR, "Make Directory", - "RMDIR", 0, &DOS_Shell::CMD_RMDIR, "Remove Directory", -*/ { 0,0,0,0} }; @@ -235,7 +234,7 @@ void DOS_Shell::CMD_DIR(char * args) { /* Make a full path in the args */ if (!DOS_Canonicalize(args,path)) { - WriteOut(MSG_Get("SHELL_CMD_ILLEGAL_PATH")); + WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); return; } *(strrchr(path,'\\')+1)=0; @@ -332,7 +331,7 @@ void DOS_Shell::CMD_COPY(char * args) { char pathTarget[DOS_PATHLENGTH]; if (!DOS_Canonicalize(source,pathSource)) { - WriteOut(MSG_Get("SHELL_CMD_ILLEGAL_PATH")); + WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); return; } // cut search pattern @@ -340,10 +339,13 @@ void DOS_Shell::CMD_COPY(char * args) { if (pos) *(pos+1) = 0; if (!DOS_Canonicalize(target,pathTarget)) { - WriteOut(MSG_Get("SHELL_CMD_ILLEGAL_PATH")); + WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); return; } - // add '\\' if target is a directoy + char* temp = strstr(pathTarget,"*.*"); + if(temp) *temp = 0;//strip off *.* from target + + // add '\\' if target is a directoy if (pathTarget[strlen(pathTarget)-1]!='\\') { if (DOS_FindFirst(pathTarget,0xffff)) { dta.GetResult(name,size,date,time,attr); @@ -520,8 +522,8 @@ void DOS_Shell::CMD_REM(char * args) { } void DOS_Shell::CMD_PAUSE(char * args){ - WriteOut(MSG_Get("SHELL_CMD_PAUSE")); - Bit8u c;Bit16u n=1; + WriteOut(MSG_Get("SHELL_CMD_PAUSE")); + Bit8u c;Bit16u n=1; DOS_ReadFile (STDIN,&c,&n); } diff --git a/src/shell/shell_inc.h b/src/shell/shell_inc.h index 2896ff92..a50b263c 100644 --- a/src/shell/shell_inc.h +++ b/src/shell/shell_inc.h @@ -26,6 +26,9 @@ #include "callback.h" #include "setup.h" +#include +#include + #define CMD_MAXLINE 4096 #define CMD_MAXCMDS 20 #define CMD_OLDSIZE 4096 @@ -46,11 +49,19 @@ public: CommandLine * cmd; }; - - class DOS_Shell : public Program { + +private: + + std::list 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 */ @@ -87,12 +98,6 @@ public: BatchFile * bf; bool echo; bool exit; - struct { - char buffer[CMD_OLDSIZE]; - Bitu index; - Bitu size; - } old; - }; struct SHELL_Cmd { diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index e586caf9..49eb6d91 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -40,11 +40,14 @@ static void outs(char * str) { } void DOS_Shell::InputCommand(char * line) { - char * prev=old.buffer; - char * reader; Bitu size=CMD_MAXLINE-1; Bit8u c;Bit16u n=1; Bitu str_len=0;Bitu str_index=0; + Bit16u len; + + line[0] = '\0'; + + std::list::iterator it_history = l_history.begin(), it_completion = l_completion.begin(); while (size) { dos.echo=false; @@ -58,41 +61,75 @@ void DOS_Shell::InputCommand(char * line) { { DOS_ReadFile(input_handle,&c,&n); switch (c) { + case 0x3d: /* F3 */ - if (strlen(old.buffer)>str_len) { - reader=&old.buffer[str_len]; - while ((c=*reader++)) { - line[str_index]=c; - str_len++; - str_index++; - size--; + if (!l_history.size()) break; + it_history = l_history.begin(); + if (it_history != l_history.end() && it_history->length() > str_len) { + const char *reader = &(it_history->c_str())[str_len]; + while ((c = *reader++)) { + line[str_index ++] = c; DOS_WriteFile(STDOUT,&c,&n); } + str_len = str_index = it_history->length(); + size = CMD_MAXLINE - str_index - 1; } break; - default: + + case 0x4B: /* LEFT */ + if (str_index) { + outc(8); + str_index --; + } break; + case 0x4D: /* RIGHT */ + if (str_index < str_len) { + outc(line[str_index++]); + } + break; + case 0x48: /* UP */ + if (it_history == l_history.end()) break; + + for (;str_index>0; str_index--) { + // removes all characters + outc(8); outc(' '); outc(8); + } + strcpy(line, it_history->c_str()); + len = it_history->length(); + str_len = str_index = len; + size = CMD_MAXLINE - str_index - 1; + DOS_WriteFile(STDOUT, (Bit8u *)line, &len); + + it_history ++; + if (it_history == l_history.end()) it_history = l_history.begin(); + + break; + + default: + break; } }; break; case 0x08: /* BackSpace */ - if (str_index>0) { - Bit32u str_remain=str_len-str_index; + if (str_index) { + outc(8); + Bit32u str_remain=str_len - str_index; if (str_remain) { - memcpy(&line[str_index-1],&line[str_index],str_remain); - line[str_len]=0; + memmove(&line[str_index-1],&line[str_index],str_remain); + line[--str_len]=0; + str_index --; /* Go back to redraw */ - for (;str_remain>0;str_remain--) { - outc(8); - } + for (Bit16u i=str_index; i < str_len; i++) + outc(line[i]); + } else { + line[--str_index] = '\0'; + str_len--; } - str_index--;str_len--; - outc(8); - outc(' '); - outc(8); - + outc(' '); outc(8); + // moves the cursor left + while (str_remain--) outc(8); } break; case 0x0a: /* New Line not handled */ @@ -103,35 +140,85 @@ void DOS_Shell::InputCommand(char * line) { size=0; //Kill the while loop break; case'\t': - { - Bit8u c=' ';Bit16u n=1; - for(Bitu i=0; i !=4 ;i++) - { - line[str_index]=c; - str_len++;//This should depend on insert being active - str_index++; - size--; - DOS_WriteFile(STDOUT,&c,&n); + { + if (l_completion.size()) { + it_completion ++; + if (it_completion == l_completion.end()) it_completion = l_completion.begin(); + } else { + // build new completion list + + // get completion mask + char *completion_start = strrchr(line, ' '); + + if (completion_start) { + completion_start ++; + completion_index = str_index - strlen(completion_start); + } else { + completion_start = line; + completion_index = 0; + } + + // build the completion list + char mask[DOS_PATHLENGTH]; + if (completion_start) { + strcpy(mask, completion_start); + // not perfect when line already contains wildcards, but works + strcat(mask, "*.*"); + } else { + strcpy(mask, "*.*"); + } + + bool res = DOS_FindFirst(mask, 0xffff & ~DOS_ATTR_VOLUME); + if (!res) break; // TODO: beep + + DOS_DTA dta(dos.dta); + char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr; + + while (res) { + dta.GetResult(name,size,date,time,attr); + // add result to completion list + + if (strcmp(name, ".") && strcmp(name, "..")) + l_completion.push_back(name); + + res=DOS_FindNext(); + } + + it_completion = l_completion.begin(); + } + + if (it_completion->length()) { + for (;str_index > completion_index; str_index--) { + // removes all characters + outc(8); outc(' '); outc(8); + } + + strcpy(&line[completion_index], it_completion->c_str()); + len = it_completion->length(); + str_len = str_index = completion_index + len; + size = CMD_MAXLINE - str_index - 1; + DOS_WriteFile(STDOUT, (Bit8u *)it_completion->c_str(), &len); } } break; default: + if (l_completion.size()) l_completion.clear(); line[str_index]=c; + str_index ++; + if (str_index > str_len) line[str_index] = '\0'; str_len++;//This should depend on insert being active - str_index++; size--; DOS_WriteFile(STDOUT,&c,&n); break; } } -/* String is inputted now save it in the buffer */ - line[str_len]=0; + if (!str_len) return; str_len++; - //Not quite perfect last entries can get screwed :) - size_t first_len=strlen(old.buffer)+1; - memmove(&old.buffer[first_len],&old.buffer[0],CMD_OLDSIZE-first_len); - strcpy(old.buffer,line); + + // add command line to history + l_history.push_front(line); it_history = l_history.begin(); + if (l_completion.size()) l_completion.clear(); } void DOS_Shell::Execute(char * name,char * args) { From 2824c189085783be98d87ea5558f423aab959b52 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 12 May 2003 10:34:32 +0000 Subject: [PATCH 0929/4131] Someone in a warning cleansing frenzy changed some critical values. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1009 --- src/cpu/core_full/string.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index bdc15b4e..78b3e2ee 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -2,7 +2,7 @@ EAPoint si_base,di_base; Bitu si_index,di_index; Bitu add_mask; - Bits count,count_left; + Bitu count,count_left; Bits add_index; bool restart=false; @@ -24,7 +24,7 @@ count=1; } else { /* Calculate amount of ops to do before cycles run out */ - if ((count>CPU_Cycles) && (inst.code.op(Bitu)CPU_Cycles) && (inst.code.op Date: Thu, 15 May 2003 10:14:27 +0000 Subject: [PATCH 0930/4131] added down patch from Guillaume Serre Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1010 --- src/shell/shell_misc.cpp | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 49eb6d91..92ede224 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -90,7 +90,31 @@ void DOS_Shell::InputCommand(char * line) { break; case 0x48: /* UP */ - if (it_history == l_history.end()) break; + if (l_history.empty() || it_history == l_history.end()) break; + + for (;str_index>0; str_index--) { + // removes all characters + outc(8); outc(' '); outc(8); + } + strcpy(line, it_history->c_str()); + len = it_history->length(); + str_len = str_index = len; + size = CMD_MAXLINE - str_index - 1; + DOS_WriteFile(STDOUT, (Bit8u *)line, &len); + it_history ++; + + break; + + case 0x50: /* DOWN */ + if (l_history.empty() || it_history == l_history.begin()) break; + + // not very nice but works .. + it_history --; + if (it_history == l_history.begin()) { + // no previous commands in history + it_history ++; + break; + } else it_history --; for (;str_index>0; str_index--) { // removes all characters @@ -101,9 +125,7 @@ void DOS_Shell::InputCommand(char * line) { str_len = str_index = len; size = CMD_MAXLINE - str_index - 1; DOS_WriteFile(STDOUT, (Bit8u *)line, &len); - it_history ++; - if (it_history == l_history.end()) it_history = l_history.begin(); break; From 12f1965cb43875cd1fca84f5a27a5120e160ed78 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 20 May 2003 15:44:21 +0000 Subject: [PATCH 0931/4131] Update log messages to be warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1011 --- src/hardware/iohandler.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 628a7361..6e2429eb 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -24,12 +24,12 @@ IO_WriteBlock IO_WriteTable[IO_MAX]; void IO_Write(Bitu num,Bit8u val) { if (num(val),port); + LOG(LOG_IO,LOG_WARN)("Writing %02X to undefined port %04X",static_cast(val),port); IO_RegisterWriteHandler(port,&IO_WriteBlocked,"Blocked Write"); } From e70b82aa64fff245700aa36f93444622edaddca0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 21 May 2003 08:31:48 +0000 Subject: [PATCH 0932/4131] Extra tests for environ Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1012 --- configure.in | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/configure.in b/configure.in index fb355341..67e2888a 100644 --- a/configure.in +++ b/configure.in @@ -36,6 +36,15 @@ AC_C_INLINE AC_TYPE_SIZE_T AC_STRUCT_TM + +AC_MSG_CHECKING(if environ can be included) +AC_TRY_LINK([#include +#include ],[*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_TRY_LINK([extern char ** environ;],[*environ;], +[AC_MSG_RESULT(yes);AC_DEFINE(ENVIRON_LINKED,1,[environ can be linked])],AC_MSG_RESULT(no)) + dnl Checks for libraries. #Check if the compiler support attributes From e4249f1006faad9ae93c74dfaaf8138d8bc29ac1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 21 May 2003 08:34:23 +0000 Subject: [PATCH 0933/4131] Changes for environ detection Added special part handler for direct blitting. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1013 --- src/gui/sdlmain.cpp | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 5dfd1dde..e5c22e43 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -19,6 +19,7 @@ #define _GNU_SOURCE #endif +#include #include #include #include @@ -40,7 +41,7 @@ //#define DISABLE_JOYSTICK #define C_GFXTHREADED 1 //Enabled by default -#if defined(MACOSX) +#if !(ENVIRON_INCLUDED) extern char** environ; #endif @@ -55,7 +56,7 @@ struct SDL_Block { bool full_screen; bool nowait; SDL_Surface * surface; - SDL_Surface * shadow_surface; + SDL_Surface * blit_surface; SDL_Joystick * joy; SDL_cond *cond; #if C_GFXTHREADED @@ -94,6 +95,12 @@ static void ResetScreen(void) { if (sdl.surface==0) { E_Exit("SDL:Can't get a surface error:%s.",SDL_GetError()); } + /* Create special surface for direct blitting if needed */ + if (sdl.blit_surface) SDL_FreeSurface(sdl.blit_surface); + sdl.blit_surface=SDL_CreateRGBSurfaceFrom(0,0,0,sdl.surface->format->BytesPerPixel,0, + sdl.surface->format->Rmask,sdl.surface->format->Gmask,sdl.surface->format->Bmask,sdl.surface->format->Amask + ); + SDL_WM_SetCaption(VERSION,VERSION); @@ -142,6 +149,19 @@ void GFX_SwitchFullScreen(void) { SwitchFullScreen(); } +/* Special render part handler that blits directly to the output screen */ +void GFX_Render_Blit(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + sdl.blit_surface->w=dx; + sdl.blit_surface->h=dy; + sdl.blit_surface->pitch=dx; + sdl.blit_surface->pixels=src; + SDL_UnlockSurface(sdl.surface); + SDL_Rect dest; + dest.x=x; + dest.y=y; + SDL_BlitSurface(sdl.blit_surface,0,sdl.surface,&dest); +} + static void SDL_DrawScreen(void) { sdl.drawing=true; if (SDL_MUSTLOCK(sdl.surface)) { @@ -257,6 +277,7 @@ static void GUI_StartUp(Section * sec) { sdl.mouse.autoenable=section->Get_bool("autolock"); sdl.mouse.autolock=false; sdl.mouse.sensitivity=section->Get_int("sensitivity"); + sdl.blit_surface=0; #if C_GFXTHREADED sdl.kill_thread=false; sdl.mutex=SDL_CreateMutex(); @@ -527,7 +548,7 @@ void GFX_Events() { HandleVideoResize(&event.resize); break; case SDL_QUIT: - throw(true); + throw(0); break; } } @@ -543,7 +564,6 @@ void GFX_ShowMsg(char * format,...) { }; int main(int argc, char* argv[]) { - try { CommandLine com_line(argc,argv); Config myconf(&com_line); @@ -574,7 +594,9 @@ int main(int argc, char* argv[]) { } /* Parse the config file */ control->ParseConfigFile(config_file.c_str()); +#if (ENVIRON_LINKED) control->ParseEnv(environ); +#endif /* Init all the sections */ control->Init(); /* Some extra SDL Functions */ @@ -598,7 +620,7 @@ int main(int argc, char* argv[]) { LOG_MSG("Exit to error: %sPress enter to continue.",error); if(!sdl.nowait) fgetc(stdin); } - catch (...){ + catch (int){ if (sdl.full_screen) SwitchFullScreen(); if (sdl.mouse.locked) CaptureMouse(); } From 999c5b36ecd775ae3acef69f87eea74a8f5f678e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 27 May 2003 11:58:32 +0000 Subject: [PATCH 0934/4131] Added helper for fpu instructions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1014 --- src/cpu/core_16/helpers.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/cpu/core_16/helpers.h b/src/cpu/core_16/helpers.h index 252ab178..e826a3bd 100644 --- a/src/cpu/core_16/helpers.h +++ b/src/cpu/core_16/helpers.h @@ -131,3 +131,12 @@ #define EAXId(inst) \ { inst(reg_eax,Fetchd(),LoadRd,SaveRd);} + +#define FPU_ESC(code) { \ + Bit8u rm=Fetchb(); \ + if (rm>=0xc0) { \ + FPU_ESC ## code ## _Normal(rm); \ + } else { \ + GetEAa;FPU_ESC ## code ## _EA(rm,eaa); \ + } \ +} \ No newline at end of file From 3ca547643cd85c2bf6a6c66fbd9019bdc5099742 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 27 May 2003 11:58:46 +0000 Subject: [PATCH 0935/4131] Removed helper for fpu instructions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1015 --- include/fpu.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/include/fpu.h b/include/fpu.h index d181a2ac..a1bfb2e5 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -38,13 +38,4 @@ void FPU_ESC6_EA(Bitu func,PhysPt ea); void FPU_ESC7_Normal(Bitu rm); void FPU_ESC7_EA(Bitu func,PhysPt ea); -#define FPU_ESC(code) { \ - Bit8u rm=Fetchb(); \ - if (rm>=0xc0) { \ - FPU_ESC ## code ## _Normal(rm); \ - } else { \ - GetEAa;FPU_ESC ## code ## _EA(rm,eaa); \ - } \ -} - #endif From 9165867fa705011842ffaaa87bc76981da776d21 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 27 May 2003 11:59:21 +0000 Subject: [PATCH 0936/4131] added fpu.h include Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1016 --- src/cpu/core_full.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 3d917e05..2f7af7ae 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -3,6 +3,7 @@ #include "pic.h" #include "regs.h" #include "cpu.h" +#include "fpu.h" #include "debug.h" #include "inout.h" #include "callback.h" From a5075ffa25f1552bc99c6d6e2c7324e6dcc5ab3a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 27 May 2003 12:00:14 +0000 Subject: [PATCH 0937/4131] Added OUTSD Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1017 --- src/cpu/core_full/string.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index 78b3e2ee..e2824894 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -51,6 +51,16 @@ si_index=(si_index+add_index) & add_mask; } break; + case R_OUTSD: + add_index<<=2; + for (;count>0;count--) { + IO_Write(reg_dx,LoadMb(si_base+si_index)); + IO_Write(reg_dx+1,LoadMb(si_base+si_index+1)); + IO_Write(reg_dx+2,LoadMb(si_base+si_index+2)); + IO_Write(reg_dx+3,LoadMb(si_base+si_index+3)); + si_index=(si_index+add_index) & add_mask; + } + break; case R_INSB: for (;count>0;count--) { reg_dx,SaveMb(di_base+di_index,IO_Read(reg_dx)); From 62959288423afdcf336b03a553a2aaa9712bc6f9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 27 May 2003 12:00:38 +0000 Subject: [PATCH 0938/4131] Added support to call the FPU opcode handlers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1018 --- src/cpu/core_full/op.h | 22 ++++++++++++++++++++-- src/cpu/core_full/optable.h | 16 ++++++++-------- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 3d755dc0..c00aa096 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -539,8 +539,26 @@ switch (inst.code.op) { BSWAP(inst.op1.d); break; case O_FPU: - LOG_MSG("FPU opcode %X unhandled",inst.entry); - break; + switch (((inst.rm>=0xc0) << 3) | inst.code.save) { + case 0x00: FPU_ESC0_EA(inst.rm,inst.rm_eaa);break; + case 0x01: FPU_ESC1_EA(inst.rm,inst.rm_eaa);break; + case 0x02: FPU_ESC2_EA(inst.rm,inst.rm_eaa);break; + case 0x03: FPU_ESC3_EA(inst.rm,inst.rm_eaa);break; + case 0x04: FPU_ESC4_EA(inst.rm,inst.rm_eaa);break; + case 0x05: FPU_ESC5_EA(inst.rm,inst.rm_eaa);break; + case 0x06: FPU_ESC6_EA(inst.rm,inst.rm_eaa);break; + case 0x07: FPU_ESC7_EA(inst.rm,inst.rm_eaa);break; + + case 0x08: FPU_ESC0_Normal(inst.rm);break; + case 0x09: FPU_ESC1_Normal(inst.rm);break; + case 0x0a: FPU_ESC2_Normal(inst.rm);break; + case 0x0b: FPU_ESC3_Normal(inst.rm);break; + case 0x0c: FPU_ESC4_Normal(inst.rm);break; + case 0x0d: FPU_ESC5_Normal(inst.rm);break; + case 0x0e: FPU_ESC6_Normal(inst.rm);break; + case 0x0f: FPU_ESC7_Normal(inst.rm);break; + } + goto nextopcode; case 0: break; default: diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 03534e70..b06b0ffd 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -153,10 +153,10 @@ static OpCode OpCodeTable[1024]={ {D_SETALC ,0 ,0 ,0 },{D_XLATw ,0 ,0 ,0 }, //TODO FPU /* 0xd8 - 0xdf */ -{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,0 ,0 }, -{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,0 ,0 }, -{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,0 ,0 }, -{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,0 ,0 }, +{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,1 ,0 }, +{L_MODRM ,O_FPU ,2 ,0 },{L_MODRM ,O_FPU ,3 ,0 }, +{L_MODRM ,O_FPU ,4 ,0 },{L_MODRM ,O_FPU ,5 ,0 }, +{L_MODRM ,O_FPU ,6 ,0 },{L_MODRM ,O_FPU ,7 ,0 }, /* 0xe0 - 0xe7 */ {L_Ibx ,O_LOOPNZ ,S_AIPw ,0 },{L_Ibx ,O_LOOPZ ,S_AIPw ,0 }, @@ -510,10 +510,10 @@ static OpCode OpCodeTable[1024]={ {L_Ib ,O_AAM ,0 ,0 },{L_Ib ,O_AAD ,0 ,0 }, {D_SETALC ,0 ,0 ,0 },{D_XLATd ,0 ,0 ,0 }, /* 0x2d8 - 0x2df */ -{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,0 ,0 }, -{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,0 ,0 }, -{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,0 ,0 }, -{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,0 ,0 }, +{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,1 ,0 }, +{L_MODRM ,O_FPU ,2 ,0 },{L_MODRM ,O_FPU ,3 ,0 }, +{L_MODRM ,O_FPU ,4 ,0 },{L_MODRM ,O_FPU ,5 ,0 }, +{L_MODRM ,O_FPU ,6 ,0 },{L_MODRM ,O_FPU ,7 ,0 }, /* 0x2e0 - 0x2e7 */ {L_Ibx ,O_LOOPNZ ,S_AIPd ,0 },{L_Ibx ,O_LOOPZ ,S_AIPd ,0 }, From 2667e412a2eb64a1e379ea5580aa1346291c5e52 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 27 May 2003 12:07:46 +0000 Subject: [PATCH 0939/4131] FPU can be enabled/disasbled through C_FPU define. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1019 --- src/cpu/core_full/op.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index c00aa096..ee493b5a 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -539,6 +539,7 @@ switch (inst.code.op) { BSWAP(inst.op1.d); break; case O_FPU: +#if C_FPU switch (((inst.rm>=0xc0) << 3) | inst.code.save) { case 0x00: FPU_ESC0_EA(inst.rm,inst.rm_eaa);break; case 0x01: FPU_ESC1_EA(inst.rm,inst.rm_eaa);break; @@ -559,6 +560,10 @@ switch (inst.code.op) { case 0x0f: FPU_ESC7_Normal(inst.rm);break; } goto nextopcode; +#else + LOG(LOG_CPU,LOG_ERROR)("Unhandled FPU ESCAPE %d",inst.code.save); + goto nextopcode; +#endif case 0: break; default: From b81081ed2b809e0a3a08e7fb9814eae1dcef9210 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 27 May 2003 12:09:03 +0000 Subject: [PATCH 0940/4131] New FPU opcode handling layout Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1020 --- src/fpu/Makefile.am | 2 +- src/fpu/fpu.cpp | 203 +++++--------------------------- src/fpu/fpu_flags.cpp | 235 ------------------------------------- src/fpu/fpu_instructions.h | 155 ++---------------------- src/fpu/fpu_types.h | 62 +++++----- 5 files changed, 77 insertions(+), 580 deletions(-) delete mode 100644 src/fpu/fpu_flags.cpp diff --git a/src/fpu/Makefile.am b/src/fpu/Makefile.am index fb3045f2..14c2d3d4 100644 --- a/src/fpu/Makefile.am +++ b/src/fpu/Makefile.am @@ -1,4 +1,4 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libfpu.a -libfpu_a_SOURCES = fpu.cpp fpu_flags.cpp fpu_types.h fpu_instructions.h \ No newline at end of file +libfpu_a_SOURCES = fpu.cpp fpu_types.h fpu_instructions.h \ No newline at end of file diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 79ee2b97..036cfa02 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -30,101 +30,32 @@ typedef PhysPt EAPoint; #define LoadMw(off) mem_readw(off) #define LoadMd(off) mem_readd(off) -#define LoadMbs(off) (Bit8s)(LoadMb(off)) -#define LoadMws(off) (Bit16s)(LoadMw(off)) -#define LoadMds(off) (Bit32s)(LoadMd(off)) - #define SaveMb(off,val) mem_writeb(off,val) #define SaveMw(off,val) mem_writew(off,val) #define SaveMd(off,val) mem_writed(off,val) -typedef double Real; - #include "fpu_types.h" + +struct { + FPU_Reg regs[8]; + FPU_Tag tags[8]; + Bitu cw; + FPU_Round round; + Bitu ex_mask; + Bitu sw; + Bitu top; + +} fpu; + +INLINE void FPU_SetCW(Bitu word) { + fpu.cw = word; + fpu.round = (FPU_Round)((word >> 8) & 3); + fpu.ex_mask = word & 0x3f; +} + #include "fpu_instructions.h" -FPU_Flag_Info fpu_flags; -FPU_Reg fpu_regs[8]; -#define FPU_GetZF fpu_flags.sw.zf = FPU_get_ZF(); - -#define FPU_ParseCW(newcw) { \ - fpu_flags.cw.ic = ((bool)((newcw&0x1000)>>12)?true:false); \ - fpu_flags.cw.rc = (Bit8u)((newcw&0x0C00)>>10); \ - fpu_flags.cw.pc = (Bit8u)((newcw&0x0300)>>8); \ - fpu_flags.cw.ie = ((bool)((newcw&0x0080)>>7)?true:false); \ - fpu_flags.cw.sf = ((bool)((newcw&0x0040)>>6)?true:false); \ - fpu_flags.cw.pf = ((bool)((newcw&0x0020)>>5)?true:false); \ - fpu_flags.cw.uf = ((bool)((newcw&0x0010)>>4)?true:false); \ - fpu_flags.cw.of = ((bool)((newcw&0x0008)>>3)?true:false); \ - fpu_flags.cw.zf = ((bool)((newcw&0x0004)>>2)?true:false); \ - fpu_flags.cw.df = ((bool)((newcw&0x0002)>>1)?true:false); \ - fpu_flags.cw.in = ((bool)(newcw&0x0001)?true:false); \ -} - -#define FPU_makeCW(newcw) { \ - newcw = (Bit16u)fpu_flags.cw.in; \ - newcw |= (fpu_flags.cw.df<<1); \ - newcw |= (fpu_flags.cw.zf<<2); \ - newcw |= (fpu_flags.cw.of<<3); \ - newcw |= (fpu_flags.cw.uf<<4); \ - newcw |= (fpu_flags.cw.pf<<5); \ - newcw |= (fpu_flags.cw.sf<<6); \ - newcw |= (fpu_flags.cw.ie<<7); \ - newcw |= (fpu_flags.cw.pc<<8); \ - newcw |= (fpu_flags.cw.rc<<10); \ - newcw |= (fpu_flags.cw.ic<<12); \ -} - -#define FPU_ParseSW(newsw) { \ - fpu_flags.sw.bf = ((bool)((newsw&0x8000)>>15)?true:false); \ - fpu_flags.sw.c3 = ((bool)((newsw&0x4000)>>14)?true:false); \ - fpu_flags.sw.tos = (Bit8s)((newsw&0x3800)>>11); \ - fpu_flags.sw.c2 = ((bool)((newsw&0x0400)>>10)?true:false); \ - fpu_flags.sw.c1 = ((bool)((newsw&0x0200)>>9)?true:false); \ - fpu_flags.sw.c0 = ((bool)((newsw&0x0100)>>8)?true:false); \ - fpu_flags.sw.ir = ((bool)((newsw&0x0080)>>7)?true:false); \ - fpu_flags.sw.sf = ((bool)((newsw&0x0040)>>6)?true:false); \ - fpu_flags.sw.pf = ((bool)((newsw&0x0020)>>5)?true:false); \ - fpu_flags.sw.uf = ((bool)((newsw&0x0010)>>4)?true:false); \ - fpu_flags.sw.of = ((bool)((newsw&0x0008)>>3)?true:false); \ - fpu_flags.sw.zf = ((bool)((newsw&0x0004)>>2)?true:false); \ - fpu_flags.sw.df = ((bool)((newsw&0x0002)>>1)?true:false); \ - fpu_flags.sw.in = ((bool)(newsw&0x0001)?true:false); \ -} - -#define FPU_makeSW(newsw) { \ - newsw = (Bit16u)fpu_flags.sw.in; \ - newsw |= (fpu_flags.sw.df<<1); \ - newsw |= (fpu_flags.sw.zf<<2); \ - newsw |= (fpu_flags.sw.of<<3); \ - newsw |= (fpu_flags.sw.uf<<4); \ - newsw |= (fpu_flags.sw.pf<<5); \ - newsw |= (fpu_flags.sw.sf<<6); \ - newsw |= (fpu_flags.sw.ir<<7); \ - newsw |= (fpu_flags.sw.c0<<8); \ - newsw |= (fpu_flags.sw.c1<<9); \ - newsw |= (fpu_flags.sw.c2<<10); \ - newsw |= (fpu_flags.sw.tos<<11); \ - newsw |= (fpu_flags.sw.c3<<14); \ - newsw |= (fpu_flags.sw.bf<<15); \ -} - -#define FPU_LOADFLAGS { \ - fpu_flags.sw.bf = false; \ - fpu_flags.sw.c3 = FPU_get_C3(); \ - fpu_flags.sw.c2 = FPU_get_C2(); \ - fpu_flags.sw.c1 = FPU_get_C1(); \ - fpu_flags.sw.c0 = FPU_get_C0(); \ - fpu_flags.sw.ir = FPU_get_IR(); \ - fpu_flags.sw.sf = FPU_get_SF(); \ - fpu_flags.sw.pf = FPU_get_PF(); \ - fpu_flags.sw.uf = FPU_get_UF(); \ - fpu_flags.sw.of = FPU_get_OF(); \ - fpu_flags.sw.zf = FPU_get_ZF(); \ - fpu_flags.sw.df = FPU_get_DF(); \ - fpu_flags.sw.in = FPU_get_IN(); \ -} void FPU_ESC0_EA(Bitu rm,PhysPt addr) { } @@ -134,50 +65,10 @@ void FPU_ESC0_Normal(Bitu rm) { void FPU_ESC1_EA(Bitu rm,PhysPt addr) { - Bit16u cw; - Bitu opcode = (rm&0x38)>>3; - switch(opcode) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 6: - break; - case 5: - FPU_ParseCW(LoadMw(addr)); /* FLDCW */ - break; - case 7: /* FSTCW */ - FPU_makeCW(cw); - SaveMw(addr,cw); - break; - } } void FPU_ESC1_Normal(Bitu rm) { - Bitu opcode = (rm&0xF0); - - switch(opcode) { - case 0xC0: -// if(rm&8) -// else - FLDST(rm-0xC0); /* FLDST */ - break; - case 0xD0: - break; - } - switch(rm) { - case 0xE0: /* FCHS */ - FCHS; - break; - case 0xE8: /* FLD1 */ - FLD(1); - break; - case 0xEE: /* FLDZ */ - FLD(0); - break; - } } @@ -192,14 +83,18 @@ void FPU_ESC3_EA(Bitu rm,PhysPt addr) { } void FPU_ESC3_Normal(Bitu rm) { - switch( rm ) { - case 0xE3: /* FINIT */ - FPU_ParseCW(0x037F); - for(int i=0;i<8;i++) { - fpu_regs.st[i].r = 0; - fpu_regs.st[i].tag = FPUREG_EMPTY; - } + Bitu group=(rm >> 3) & 7; + Bitu sub=(rm & 7); + switch (group) { + case 0x04: + switch (sub) { + case 0x03: //FINIT + FPU_FINIT(); break; + default: + LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d subfunction %d",group,sub); + } + LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d",group); } } @@ -212,23 +107,6 @@ void FPU_ESC4_Normal(Bitu rm) { void FPU_ESC5_EA(Bitu rm,PhysPt addr) { - Bit16u sw; - Bitu opcode = (rm&0x38)>>3; - - switch(opcode) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: /* FSTSW */ - FPU_LOADFLAGS; - FPU_makeSW(sw); - SaveMw(addr,sw); - break; - } } void FPU_ESC5_Normal(Bitu rm) { @@ -239,27 +117,6 @@ void FPU_ESC6_EA(Bitu rm,PhysPt addr) { } void FPU_ESC6_Normal(Bitu rm) { - Bitu opcode = (rm&0xF0); - - if(rm==0xD9) { /* FCOMPP */ - FCOMPP; - return; - } - switch(opcode) { - case 0xC0: -// if(rm&8) - break; - case 0xD0: -// if(rm&8) - break; - case 0xE0: -// if(rm&8) - break; - case 0xF0: - if(rm&8) - FDIVP(rm-0xF8,0); - break; - } } @@ -271,7 +128,7 @@ void FPU_ESC7_Normal(Bitu rm) { void FPU_Init(void) { - fpu_flags.type = t_FUNKNOWN; + FPU_FINIT(); } #endif diff --git a/src/fpu/fpu_flags.cpp b/src/fpu/fpu_flags.cpp deleted file mode 100644 index 924614fc..00000000 --- a/src/fpu/fpu_flags.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (C) 2002 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "dosbox.h" -#include "fpu.h" -#include "pic.h" -#include "fpu_types.h" -extern FPU_Flag_Info fpu_flags; - -bool FPU_get_C3() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - return fpu_flags.sw.c3; - case t_FCOMP: - return (fpu_flags.result.tag==FPUREG_EMPTY||fpu_flags.result.tag==FPUREG_ZERO); - default: - E_Exit("FPU_get_C3 Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_C2() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - return fpu_flags.sw.c2; - case t_FCOMP: - return (fpu_flags.result.tag==FPUREG_EMPTY); - default: - E_Exit("FPU_get_C2 Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_C1() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - return fpu_flags.sw.c1; - case t_FCOMP: - return false; /* FIXME */ - default: - E_Exit("FPU_get_C1 Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_C0() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - return fpu_flags.sw.c0; - case t_FCOMP: - return (fpu_flags.result.tag!=FPUREG_ZERO&&fpu_flags.result.tag!=FPUREG_PNAN); - default: - E_Exit("FPU_get_C0 Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_IR() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - case t_FCOMP: - return fpu_flags.sw.ir; - default: - E_Exit("FPU_get_IR Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_SF() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - return fpu_flags.sw.sf; - case t_FCOMP: - return false; /* FIXME */ - default: - E_Exit("FPU_get_SF Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_PF() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - case t_FCOMP: - return fpu_flags.sw.pf; - default: - E_Exit("FPU_get_PF Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_UF() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - case t_FCOMP: - return fpu_flags.sw.uf; - default: - E_Exit("FPU_get_UF Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_OF() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - case t_FCOMP: - return fpu_flags.sw.of; - default: - E_Exit("FPU_get_OF Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_ZF() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - case t_FCOMP: - return fpu_flags.sw.zf; - case t_FDIV: - case t_FDIVP: - return (fpu_flags.result.tag==FPUREG_PNAN||fpu_flags.result.tag==FPUREG_NNAN); - default: - E_Exit("FPU_get_ZF Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_DF() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - return fpu_flags.sw.df; - case t_FCOMP: - return false; /* FIXME */ - default: - E_Exit("FPU_get_DF Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_IN(){ - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - return fpu_flags.sw.in; - case t_FCOMP: - return (fpu_flags.result.tag==FPUREG_EMPTY); /* FIXME */ - default: - E_Exit("FPU_get_IN Unknown %d",fpu_flags.type); - } - return 0; -} diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 49de9d00..3b133566 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,147 +16,16 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define FLD(op1) { \ - FPU_GetZF; \ - fpu_flags.type=t_FLD; \ - if(--fpu_flags.sw.tos < 0) \ - fpu_flags.sw.tos = 7; \ - if( fpu_regs.st[fpu_flags.sw.tos].tag != FPUREG_EMPTY ) { \ - fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_NNAN; \ - break; \ - } \ - if(op1) \ - fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_VALID; \ - else \ - fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_ZERO; \ - fpu_flags.result.r = fpu_regs.st[fpu_flags.sw.tos].r = op1; \ -} - -#define FLDST(op1) { \ - FPU_GetZF; \ - fpu_flags.type=t_FLDST; \ - Bit8u reg = fpu_flags.sw.tos+op1; \ - if(reg>7) reg-=8; \ - if(--fpu_flags.sw.tos < 0) \ - fpu_flags.sw.tos = 7; \ - if(fpu_regs.st[fpu_flags.sw.tos].tag!=FPUREG_EMPTY) { \ - fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_NNAN; \ - break; \ - } \ - fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = fpu_regs.st[reg].tag; \ - fpu_flags.result.r = fpu_regs.st[fpu_flags.sw.tos].r = fpu_regs.st[reg].r; \ -} - -#define FPOP { \ - fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_EMPTY; \ - if(++fpu_flags.sw.tos > 7 ) \ - fpu_flags.sw.tos = 0; \ -} -/* FPOP: fpu_flags.result.r = fpu_regs.st[fpu_flags.sw.tos].r = 0; is not really neccessary */ - -#define FDIVP(op1,op2) { \ - Bit8u reg1 = fpu_flags.sw.tos+op1; \ - Bit8u reg2 = fpu_flags.sw.tos+op2; \ - fpu_flags.type=t_FDIVP; \ - if(reg1>7) reg1-=8; \ - if(reg2>7) reg2-=8; \ - if((fpu_regs.st[reg1].tag!=FPUREG_VALID && fpu_regs.st[reg1].tag!=FPUREG_ZERO)||(fpu_regs.st[reg2].tag!=FPUREG_VALID && fpu_regs.st[reg2].tag!=FPUREG_ZERO)) { \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ - FPOP; \ - break; \ - } \ - if(fpu_regs.st[reg2].tag == FPUREG_ZERO) { \ - if(fpu_regs.st[reg1].r > 0) \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_PNAN; \ - else \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ - FPOP; \ - break; \ - } \ - if(fpu_regs.st[reg1].tag == FPUREG_ZERO) { \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_ZERO; \ - FPOP; \ - break; \ - } \ - fpu_flags.result.tag = FPUREG_VALID; \ - fpu_flags.result.r = fpu_regs.st[reg1].r = fpu_regs.st[reg1].r / fpu_regs.st[reg2].r; \ - FPOP; \ -} - -#define FDIV(op1,op2) { \ - Bit8u reg1 = fpu_flags.sw.tos+op1; \ - Bit8u reg2 = fpu_flags.sw.tos+op2; \ - fpu_flags.type=t_FDIV; \ - if(reg1>7) reg1-=7; \ - if(reg2>7) reg2-=7; \ - if((fpu_regs.st[reg1].tag!=FPUREG_VALID && fpu_regs.st[reg1].tag!=FPUREG_ZERO)||(fpu_regs.st[reg2].tag!=FPUREG_VALID && fpu_regs.st[reg2].tag!=FPUREG_ZERO)) { \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ - break; \ - } \ - if(fpu_regs.st[reg2].tag == FPUREG_ZERO) { \ - if(fpu_regs.st[reg1].r > 0) \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_PNAN; \ - else \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ - break; \ - } \ - if(fpu_regs.st[reg1].tag == FPUREG_ZERO) { \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_ZERO; \ - break; \ - } \ - fpu_flags.result.tag = FPUREG_VALID; \ - fpu_flags.result.r = fpu_regs.st[reg1].r = fpu_regs.st[reg1].r / fpu_regs.st[reg2].r; \ -} - -#define FCHS { \ - FPU_GetZF; \ - fpu_flags.type=t_FCHS; \ - if(fpu_regs.st[fpu_flags.sw.tos].tag == FPUREG_PNAN) { \ - fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_NNAN; \ - } else if(fpu_regs.st[fpu_flags.sw.tos].tag == FPUREG_NNAN) { \ - fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_PNAN; \ - } else \ - fpu_regs.st[fpu_flags.sw.tos].r = -fpu_regs.st[fpu_flags.sw.tos].r; \ -} - -#define FCOMPP { \ - Bit8u reg = fpu_flags.sw.tos+1; \ - FPU_GetZF; \ - fpu_flags.type=t_FCOMP; \ - if(reg>7) \ - reg=0; \ - if((fpu_regs.st[reg].tag==FPUREG_VALID||fpu_regs.st[reg].tag==FPUREG_ZERO)&&(fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_VALID||fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_ZERO)) { \ - fpu_flags.result.r = fpu_regs.st[reg].r - fpu_regs.st[fpu_flags.sw.tos].r; \ - if(fpu_flags.result.r==0) \ - fpu_flags.result.tag = FPUREG_ZERO; \ - else \ - fpu_flags.result.tag = FPUREG_VALID; \ - FPOP; \ - FPOP; \ - return; \ - } else if(((fpu_regs.st[reg].tag==FPUREG_EMPTY)||(fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_EMPTY))||((fpu_regs.st[reg].tag==FPUREG_VALID||fpu_regs.st[reg].tag==FPUREG_ZERO)||(fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_VALID||fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_ZERO))) { \ - fpu_flags.result.tag = FPUREG_EMPTY; \ - FPOP; \ - FPOP; \ - return; \ - } \ - Bit8s res = (fpu_regs.st[reg].tag-fpu_regs.st[fpu_flags.sw.tos].tag); \ - if(res==0||fpu_flags.cw.ic==0) { \ - fpu_flags.result.tag = FPUREG_ZERO; \ - FPOP; \ - FPOP; \ - return; \ - } else if(res>0) { \ - fpu_flags.result.tag = FPUREG_NNAN; \ - FPOP; \ - FPOP; \ - return; \ - } \ - fpu_flags.result.tag = FPUREG_PNAN; \ - FPOP; \ - FPOP; \ -} - - - +static void FPU_FINIT(void) { + FPU_SetCW(0x37); + fpu.sw=0; + fpu.tags[0]=TAG_Empty; + fpu.tags[1]=TAG_Empty; + fpu.tags[2]=TAG_Empty; + fpu.tags[3]=TAG_Empty; + fpu.tags[4]=TAG_Empty; + fpu.tags[5]=TAG_Empty; + fpu.tags[6]=TAG_Empty; + fpu.tags[7]=TAG_Empty; +} \ No newline at end of file diff --git a/src/fpu/fpu_types.h b/src/fpu/fpu_types.h index 2d0ced0f..ce9cfaec 100644 --- a/src/fpu/fpu_types.h +++ b/src/fpu/fpu_types.h @@ -1,33 +1,39 @@ +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; + +/* the following deal with IEEE double-precision numbers */ +#define MAXEXPD 0x7ff +#define EXPBIAS 1023 +#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) +#define SIGND(fp) ((fp.l.upper) & 0x80000000) +#define MANTD(fp) (fp.ll & ((1LL << 52) - 1)) +#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20) -enum { FPUREG_VALID=0, FPUREG_ZERO, FPUREG_PNAN, FPUREG_NNAN, FPUREG_EMPTY }; - -enum { - t_FLD=0, t_FLDST, t_FDIV, - t_FDIVP, t_FCHS, t_FCOMP, - - t_FUNKNOWN, - t_FNOTDONE +enum FPU_Tag { + TAG_Valid = 0, + TAG_Zero = 1, + TAG_Weird = 2, + TAG_Empty = 3 }; -struct FPU_Flag_Info { - struct { - Real64 r; - Bit8u tag; - } var1,var2, result; - struct { - bool bf,c3,c2,c1,c0,ir,sf,pf,uf,of,zf,df,in; - Bit8s tos; - } sw; - struct { - bool ic,ie,sf,pf,uf,of,zf,df,in; - Bit8u rc,pc; - } cw; - Bitu type; - Bitu prev_type; -}; -struct FPU_Reg { - Real64 r; - Bit8u tag; -}; +enum FPU_Round { + ROUND_Nearest = 0, + ROUND_Down = 1, + ROUND_Up = 2, + ROUND_Chop = 3 +}; \ No newline at end of file From 0824f2e456cfb9a0d0d8cdf77399f90fde54b384 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 27 May 2003 19:38:56 +0000 Subject: [PATCH 0941/4131] fixed logging system. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1021 --- src/debug/debug_gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 0bd77a0e..636af058 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -156,7 +156,7 @@ static void LOG_Init(Section * sec) { char buf[1024]; for (Bitu i=1;iGet_bool(buf); } From b6501b033272dc60f5b6f702454ff54e10218735 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 27 May 2003 19:39:26 +0000 Subject: [PATCH 0942/4131] some more warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1022 --- src/fpu/fpu.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 036cfa02..fc8b7901 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -61,6 +61,9 @@ void FPU_ESC0_EA(Bitu rm,PhysPt addr) { } void FPU_ESC0_Normal(Bitu rm) { + Bitu group=(rm >> 3) & 7; + Bitu sub=(rm & 7); + LOG(LOG_FPU,LOG_WARN)("ESC 0:Unhandled group %d subfunction %d",group,sub); } @@ -69,6 +72,9 @@ void FPU_ESC1_EA(Bitu rm,PhysPt addr) { } void FPU_ESC1_Normal(Bitu rm) { + Bitu group=(rm >> 3) & 7; + Bitu sub=(rm & 7); + LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %d subfunction %d",group,sub); } @@ -76,6 +82,9 @@ void FPU_ESC2_EA(Bitu rm,PhysPt addr) { } void FPU_ESC2_Normal(Bitu rm) { + Bitu group=(rm >> 3) & 7; + Bitu sub=(rm & 7); + LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",group,sub); } @@ -94,8 +103,12 @@ void FPU_ESC3_Normal(Bitu rm) { default: LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d subfunction %d",group,sub); } - LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d",group); + break; + default: + LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d subfunction %d",group,sub); + break; } + return; } @@ -103,6 +116,9 @@ void FPU_ESC4_EA(Bitu rm,PhysPt addr) { } void FPU_ESC4_Normal(Bitu rm) { + Bitu group=(rm >> 3) & 7; + Bitu sub=(rm & 7); + LOG(LOG_FPU,LOG_WARN)("ESC 4:Unhandled group %d subfunction %d",group,sub); } @@ -110,6 +126,9 @@ void FPU_ESC5_EA(Bitu rm,PhysPt addr) { } void FPU_ESC5_Normal(Bitu rm) { + Bitu group=(rm >> 3) & 7; + Bitu sub=(rm & 7); + LOG(LOG_FPU,LOG_WARN)("ESC 5:Unhandled group %d subfunction %d",group,sub); } From 1471f0d319c5a026bc0f2f36490edc67ed078cbd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 27 May 2003 20:12:34 +0000 Subject: [PATCH 0943/4131] finished esc 3: group 4 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1023 --- src/fpu/fpu.cpp | 16 ++++++++++++++-- src/fpu/fpu_instructions.h | 7 +++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index fc8b7901..70f4b66b 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -97,11 +97,23 @@ void FPU_ESC3_Normal(Bitu rm) { switch (group) { case 0x04: switch (sub) { - case 0x03: //FINIT + 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 + FPU_FCLEX(); + break; + case 0x03: //FNINIT FINIT FPU_FINIT(); break; + case 0x04: //FNSETPM + case 0x05: //FRSTPM + LOG(LOG_FPU,LOG_ERROR)("80267 protected mode (un)set. Nothing done"); + FPU_FNOP(); + break; default: - LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d subfunction %d",group,sub); + E_Exit("ESC 3:ILLEGAL OPCODE group %d subfunction %d",group,sub); } break; default: diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 3b133566..e93ef964 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -28,4 +28,11 @@ static void FPU_FINIT(void) { fpu.tags[5]=TAG_Empty; fpu.tags[6]=TAG_Empty; fpu.tags[7]=TAG_Empty; +} +static void FPU_FCLEX(void){ + fpu.sw&=0x7f00; //should clear exceptions +}; + +static void FPU_FNOP(void){ + return; } \ No newline at end of file From 1aa183e96b6a3ca0712224d06ecfc92fb02efe15 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 29 May 2003 08:53:21 +0000 Subject: [PATCH 0944/4131] fixed bug in INT10_SCROLLWINDOW Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1024 --- src/ints/int10_char.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index e30dbc7d..eb8e8ac2 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -125,7 +125,7 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit /* Copy some lines */ if (nlines>0) { start=rlr-nlines+1; - end=cul; + end=rul; next=-1; } else if (nlines<0) { start=rul-nlines-1; From 68b6e04b5e5eba21bbe2158150fab58056e5319f Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 31 May 2003 16:39:27 +0000 Subject: [PATCH 0945/4131] fixed bug with msf handling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1025 --- src/dos/dos_mscdex.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 4ca544b8..3af23c4b 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -342,12 +342,12 @@ bool CMscdex::PlayAudioMSF(Bit8u subUnit, Bit32u start, Bit32u length) Bit8u min = (start>>16) & 0xFF; Bit8u sec = (start>> 8) & 0xFF; Bit8u fr = (start>> 0) & 0xFF; - Bit32u sector = min*60*76+sec*75+fr - 150; - min = (length>>16) & 0xFF; - sec = (length>> 8) & 0xFF; - fr = (length>> 0) & 0xFF; - Bit32u seclen = min*60*76+sec*75+fr - 150; - return dinfo[subUnit].lastResult = PlayAudioSector(subUnit,sector,seclen); + Bit32u sector = min*60*75+sec*75+fr - 150; +// min = (length>>16) & 0xFF; +// sec = (length>> 8) & 0xFF; +// fr = (length>> 0) & 0xFF; +// Bit32u seclen = min*60*75+sec*75+fr - 150; + return dinfo[subUnit].lastResult = PlayAudioSector(subUnit,sector,length); }; bool CMscdex::GetSubChannelData(Bit8u subUnit, Bit8u& attr, Bit8u& track, Bit8u &index, TMSF& rel, TMSF& abs) @@ -397,7 +397,7 @@ bool CMscdex::StopAudio(Bit8u subUnit) if (dinfo[subUnit].audioPlay) { TMSF pos; GetCurrentPos(subUnit,pos); - dinfo[subUnit].audioStart = pos.min*60*76+pos.sec*75+pos.fr - 150; + dinfo[subUnit].audioStart = pos.min*60*75+pos.sec*75+pos.fr - 150; dinfo[subUnit].audioPaused = true; } else { dinfo[subUnit].audioPaused = false; @@ -519,7 +519,7 @@ bool CMscdex::ReadSectorsMSF(Bit8u subUnit, bool raw, Bit32u start, Bit16u num, Bit8u min = (start>>16) & 0xFF; Bit8u sec = (start>> 8) & 0xFF; Bit8u fr = (start>> 0) & 0xFF; - Bit32u sector = min*60*76+sec*75+fr - 150; + Bit32u sector = min*60*75+sec*75+fr - 150; // TODO: Check, if num has to be converted too ?! return ReadSectors(subUnit,raw,sector,num,data); }; @@ -633,14 +633,14 @@ static Bitu MSCDEX_Interrupt_Handler(void) Bit8u subUnit = mem_readb(data+1); Bit8u funcNr = mem_readb(data+2); -// LOG(LOG_ERROR,"MSCDEX: Driver Function %02X",funcNr); + LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Driver Function %02X",funcNr); switch (funcNr) { case 0x03 : { /* IOCTL INPUT */ PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); subFuncNr = mem_readb(buffer); - //if (subFuncNr!=0x0B) LOG("MSCDEX: IOCTL INPUT Subfunction %02X",subFuncNr); + if (subFuncNr!=0x0B) LOG(LOG_MISC,LOG_ERROR)("MSCDEX: IOCTL INPUT Subfunction %02X",subFuncNr); switch (subFuncNr) { case 0x00 : /* Get Device Header address */ mem_writed(buffer+1,RealMake(mscdex->rootDriverHeaderSeg,0)); @@ -799,7 +799,7 @@ static bool MSCDEX_Handler(void) if (reg_ah!=0x15) return false; PhysPt data = PhysMake(SegValue(es),reg_bx); -// LOG(LOG_ERROR,"MSCDEX: INT 2F %04X",reg_ax); + LOG(LOG_MISC,LOG_ERROR)("MSCDEX: INT 2F %04X",reg_ax); switch (reg_ax) { case 0x1500: /* Install check */ From 7b909131e033ded04e11c52f1d9d098ac3f93b65 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 31 May 2003 21:08:36 +0000 Subject: [PATCH 0946/4131] drive number fix ('and' it with 0xff) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1026 --- src/dos/cdrom.cpp | 2 +- src/dos/dos_mscdex.cpp | 18 +++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 909ef3ca..6d8febea 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -121,7 +121,7 @@ bool CDROM_Interface_SDL::PlayAudioSector (unsigned long start,unsigned long len // Has to be there, otherwise wrong cd status report (dunno why, sdl bug ?) SDL_CDClose(cd); cd = SDL_CDOpen(driveID); - bool success = (SDL_CDPlay(cd,start,len)==0); + bool success = (SDL_CDPlay(cd,start+150,len)==0); return success; }; diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 3af23c4b..1594b27f 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -343,10 +343,6 @@ bool CMscdex::PlayAudioMSF(Bit8u subUnit, Bit32u start, Bit32u length) Bit8u sec = (start>> 8) & 0xFF; Bit8u fr = (start>> 0) & 0xFF; Bit32u sector = min*60*75+sec*75+fr - 150; -// min = (length>>16) & 0xFF; -// sec = (length>> 8) & 0xFF; -// fr = (length>> 0) & 0xFF; -// Bit32u seclen = min*60*75+sec*75+fr - 150; return dinfo[subUnit].lastResult = PlayAudioSector(subUnit,sector,length); }; @@ -581,8 +577,7 @@ bool CMscdex::LoadUnloadMedia(Bit8u subUnit, bool unload) bool CMscdex::SendDriverRequest(Bit16u drive, PhysPt data) { Bit8u subUnit = GetSubUnit(drive); - if (subUnit>=numDrives) return false; - + if (subUnit>=numDrives) return false; // Get SubUnit mem_writeb(data+1,subUnit); // Call Strategy / Interrupt @@ -633,14 +628,14 @@ static Bitu MSCDEX_Interrupt_Handler(void) Bit8u subUnit = mem_readb(data+1); Bit8u funcNr = mem_readb(data+2); - LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Driver Function %02X",funcNr); +// LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Driver Function %02X",funcNr); switch (funcNr) { case 0x03 : { /* IOCTL INPUT */ PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); subFuncNr = mem_readb(buffer); - if (subFuncNr!=0x0B) LOG(LOG_MISC,LOG_ERROR)("MSCDEX: IOCTL INPUT Subfunction %02X",subFuncNr); +// LOG(LOG_MISC,LOG_ERROR)("MSCDEX: IOCTL INPUT Subfunction %02X",subFuncNr); switch (subFuncNr) { case 0x00 : /* Get Device Header address */ mem_writed(buffer+1,RealMake(mscdex->rootDriverHeaderSeg,0)); @@ -666,7 +661,8 @@ static Bitu MSCDEX_Interrupt_Handler(void) break; case 0x09 : /* Media change ? */ Bit8u status; - mscdex->GetMediaStatus(subUnit,status); + //TEMP mscdex->GetMediaStatus(subUnit,status); + status = 1; mem_writeb(buffer+1,status); break; case 0x0A : /* Get Audio Disk info */ @@ -799,7 +795,7 @@ static bool MSCDEX_Handler(void) if (reg_ah!=0x15) return false; PhysPt data = PhysMake(SegValue(es),reg_bx); - LOG(LOG_MISC,LOG_ERROR)("MSCDEX: INT 2F %04X",reg_ax); +// LOG(LOG_MISC,LOG_ERROR)("MSCDEX: INT 2F %04X",reg_ax); switch (reg_ax) { case 0x1500: /* Install check */ @@ -868,7 +864,7 @@ static bool MSCDEX_Handler(void) mscdex->GetDrives(data); return true; case 0x1510: /* Device driver request */ - mscdex->SendDriverRequest(reg_cx,data); + mscdex->SendDriverRequest(reg_cx & 0xFF,data); return true; default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unknwon call : %04X",reg_ax); return true; From 57e3c31efb28430ba277dfda27721c8ff2eab690 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 31 May 2003 21:09:04 +0000 Subject: [PATCH 0947/4131] Removed Open/Close from functions for speedup. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1027 --- src/dos/cdrom_ioctl_win32.cpp | 39 ++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index f832abae..f656570e 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -38,6 +38,7 @@ CDROM_Interface_Ioctl::CDROM_Interface_Ioctl() CDROM_Interface_Ioctl::~CDROM_Interface_Ioctl() { StopAudio(); + Close(); }; bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc) @@ -48,12 +49,12 @@ bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc) bool CDROM_Interface_Ioctl::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut) { - Open(); +// Open(); CDROM_TOC toc; DWORD byteCount; BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), &byteCount,NULL); - Close(); +// Close(); if (!bStat) return false; stTrack = toc.FirstTrack; @@ -66,12 +67,12 @@ bool CDROM_Interface_Ioctl::GetAudioTracks(int& stTrack, int& endTrack, TMSF& le bool CDROM_Interface_Ioctl::GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr) { - Open(); +// Open(); CDROM_TOC toc; DWORD byteCount; BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), &byteCount,NULL); - Close(); +// Close(); if (!bStat) return false; attr = (toc.TrackData[track-1].Adr << 4) | toc.TrackData[track].Control; @@ -83,7 +84,7 @@ bool CDROM_Interface_Ioctl::GetAudioTrackInfo(int track, TMSF& start, unsigned c bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) { - Open(); +// Open(); CDROM_SUB_Q_DATA_FORMAT insub; SUB_Q_CHANNEL_DATA sub; @@ -93,7 +94,7 @@ bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& trac BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), &byteCount,NULL); - Close(); +// Close(); if (!bStat) return false; attr = (sub.CurrentPosition.ADR << 4) | sub.CurrentPosition.Control; @@ -111,7 +112,7 @@ bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& trac bool CDROM_Interface_Ioctl::GetAudioStatus(bool& playing, bool& pause) { - Open(); +// Open(); CDROM_SUB_Q_DATA_FORMAT insub; SUB_Q_CHANNEL_DATA sub; @@ -121,7 +122,7 @@ bool CDROM_Interface_Ioctl::GetAudioStatus(bool& playing, bool& pause) BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), &byteCount,NULL); - Close(); +// Close(); if (!bStat) return false; playing = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_IN_PROGRESS); @@ -149,7 +150,7 @@ bool CDROM_Interface_Ioctl::GetMediaTrayStatus(bool& mediaPresent, bool& mediaCh bool CDROM_Interface_Ioctl::PlayAudioSector (unsigned long start,unsigned long len) { - Open(); +// Open(); CDROM_PLAY_AUDIO_MSF audio; DWORD byteCount; // Start @@ -165,44 +166,44 @@ bool CDROM_Interface_Ioctl::PlayAudioSector (unsigned long start,unsigned long l BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PLAY_AUDIO_MSF, &audio, sizeof(audio), NULL, 0, &byteCount,NULL); - Close(); +// Close(); return bStat>0; }; bool CDROM_Interface_Ioctl::PauseAudio(bool resume) { - Open(); +// Open(); BOOL bStat; DWORD byteCount; if (resume) bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RESUME_AUDIO, NULL, 0, NULL, 0, &byteCount,NULL); else bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PAUSE_AUDIO, NULL, 0, NULL, 0, &byteCount,NULL); - Close(); +// Close(); return bStat>0; }; bool CDROM_Interface_Ioctl::StopAudio(void) { - Open(); +// Open(); BOOL bStat; DWORD byteCount; bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_STOP_AUDIO, NULL, 0, NULL, 0, &byteCount,NULL); - Close(); +// Close(); return bStat>0; }; bool CDROM_Interface_Ioctl::LoadUnloadMedia(bool unload) { - Open(); +// Open(); BOOL bStat; DWORD byteCount; if (unload) bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &byteCount,NULL); else bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, &byteCount,NULL); - Close(); +// Close(); return bStat>0; }; @@ -211,7 +212,7 @@ bool CDROM_Interface_Ioctl::ReadSectors(void* buffer, bool raw, unsigned long se BOOL bStat; DWORD byteCount = 0; - Open(); +// Open(); if (!raw) { // Cooked int success = 0; @@ -228,7 +229,7 @@ bool CDROM_Interface_Ioctl::ReadSectors(void* buffer, bool raw, unsigned long se bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RAW_READ, &in, sizeof(in), buffer, num*RAW_SECTOR_SIZE, &byteCount,NULL); } - Close(); +// Close(); return (byteCount!=num*RAW_SECTOR_SIZE) && (bStat>0); } @@ -240,7 +241,7 @@ bool CDROM_Interface_Ioctl::SetDevice(char* path, int forceCD) strcpy(pathname,"\\\\.\\"); strcat(pathname,letter); if (Open()) { - Close(); +// Close(); return true; }; } From 3a059c870b4b708dd310dea77b276185edde67d4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Jun 2003 14:51:26 +0000 Subject: [PATCH 0948/4131] fpu updated Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1028 --- src/fpu/fpu.cpp | 274 +++++++++++++++++++++++++++++++++++-- src/fpu/fpu_instructions.h | 82 +++++++++++ src/fpu/fpu_types.h | 4 +- 3 files changed, 351 insertions(+), 9 deletions(-) diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 70f4b66b..af40c670 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -23,6 +23,7 @@ #include #include "mem.h" #include "fpu.h" +#include "cpu.h" typedef PhysPt EAPoint; @@ -37,8 +38,8 @@ typedef PhysPt EAPoint; #include "fpu_types.h" struct { - FPU_Reg regs[8]; - FPU_Tag tags[8]; + FPU_Reg regs[9]; + FPU_Tag tags[9]; Bitu cw; FPU_Round round; Bitu ex_mask; @@ -52,33 +53,189 @@ INLINE void FPU_SetCW(Bitu word) { fpu.round = (FPU_Round)((word >> 8) & 3); fpu.ex_mask = word & 0x3f; } +INLINE Bitu FPU_GET_TOP(void){ + return (fpu.sw & 0x3800)>>11; +} +INLINE void FPU_SET_TOP(Bitu val){ + fpu.sw &= ~0x3800; + fpu.sw |= (val&7)<<11; + return; +} + #include "fpu_instructions.h" +/* TODO : MAKE REGULAR TREE A DEFINE or a function + : ESC6normal => esc4normal+pop or a define as well + : Make a smarter top system. won't matter that much in speed though. + : #define ST fpu.top #define ST(i) (fpu.top+(i))&7 maybe*/ +static void EATREE(Bitu _rm){ + Bitu group=(_rm >> 3) & 7; + Bitu top = FPU_GET_TOP(); + /* data will allready be put in register 8 by caller */ + switch(group){ + case 0x00: /* FIADD */ + FPU_FADD(top, 8); + break; + case 0x01: /* FIMUL */ + FPU_FMUL(top, 8); + break; + case 0x02: /* FICOM */ + case 0x03: /* FICOMP */ + LOG(LOG_FPU,LOG_WARN)("ESC EATREE:Unhandled group %d",group); + break; + case 0x04: /* FISUB */ + FPU_FSUB(top,8); + break; + case 0x05: /* FISUBR */ + FPU_FSUBR(top,8); + case 0x06: /* FIDIV */ + FPU_FDIV(top, 8); + break; + case 0x07: /* FIDIVR */ + FPU_FDIVR(top,8); + break; + default: + break; + } + +} void FPU_ESC0_EA(Bitu rm,PhysPt addr) { + /* REGULAR TREE WITH 32 BITS REALS ? float ? */ + //THIS SHOULD GO ALLRIGHT !?! + LOG(LOG_FPU, LOG_WARN)("ESC 0 EA used (check the result!)"); + + union { + float f; + Bit32s l; + } blah; + blah.l = mem_readd(addr); + fpu.regs[8].d = static_cast(blah.f); + EATREE(rm); } void FPU_ESC0_Normal(Bitu rm) { Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); - LOG(LOG_FPU,LOG_WARN)("ESC 0:Unhandled group %d subfunction %d",group,sub); + Bitu top = FPU_GET_TOP(); + switch (group){ + case 0x00: /* FADD ST,STi */ + FPU_FADD(top,(top+sub)&7); + break; + case 0x01: /* FMUL ST,STi */ + FPU_FMUL(top,(top+sub)&7); + break; + case 0x02: /* FCOM STi */ + case 0x03: /* FCOMP STi */ + LOG(LOG_FPU,LOG_WARN)("ESC 0:Unhandled group %d subfunction %d",group,sub); + break; + case 0x04: /* FSUB ST,STi */ + FPU_FSUB(top,(top+sub)&7); + break; + case 0x05: /* FSUBR ST,STi */ + FPU_FSUBR(top,(top+sub)&7); + break; + case 0x06: /* FDIV ST,STi */ + FPU_FDIV(top,(top+sub)&7); + break; + case 0x07: /* FDIVR ST,STi */ + FPU_FDIVR(top,(top+sub)&7); + break; + default: + break; + + } } - void FPU_ESC1_EA(Bitu rm,PhysPt addr) { - + Bitu group=(rm >> 3) & 7; + Bitu sub=(rm & 7); + LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub); } void FPU_ESC1_Normal(Bitu rm) { Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %d subfunction %d",group,sub); + switch (group){ + case 0x00: /* FLD STi */ + { + Bitu top = FPU_GET_TOP(); + FPU_PUSH(fpu.regs[(top+sub)&7].d); + } + break; + case 0x04: + switch(sub){ + case 0x00: /* FCHS */ + case 0x01: /* FABS */ + case 0x02: /* UNKNOWN */ + case 0x03: /* ILLEGAL */ + case 0x04: /* FTST */ + case 0x05: /* FXAM */ + 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 */ + FPU_PUSH(1.0); + break; + case 0x01: /* FLDL2T */ + case 0x02: /* FLDL2E */ + LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); + break; + case 0x03: /* FLDPI */ + FPU_PUSH(PI); + break; + case 0x04: /* FLDLG2 */ + case 0x05: /* FLDLN2 */ + LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); + case 0x06: /* FLDZ*/ + FPU_PUSH_ZERO(); + break; + case 0x07: /* ILLEGAL */ + LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); + break; + } + break; + case 0x06: + LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); + break; + case 0x07: + switch(sub){ + + + case 0x03: /* FSINCOS */ + FPU_FSINCOS(); + break; + case 0x06: /* FSIN */ + FPU_FSIN(); + break; + case 0x07: /* FCOS */ + 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); + } + +// LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); } void FPU_ESC2_EA(Bitu rm,PhysPt addr) { + /* 32 bits integer operants */ + Bit32s blah = mem_readd(addr); + fpu.regs[8].d = static_cast(blah); + EATREE(rm); } void FPU_ESC2_Normal(Bitu rm) { @@ -125,16 +282,52 @@ void FPU_ESC3_Normal(Bitu rm) { void FPU_ESC4_EA(Bitu rm,PhysPt addr) { + /* REGULAR TREE WITH 64 BITS REALS ? double ? */ + E_Exit("how to load a double in esc 4 ea"); + //SEE ESC 0 EA +// double blah = mem_readd(addr); //wrong wrong wrong +// fpu.regs[8].d = static_cast(blah); + EATREE(rm); } void FPU_ESC4_Normal(Bitu rm) { + //LOOKS LIKE number 6 without popping*/ Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); - LOG(LOG_FPU,LOG_WARN)("ESC 4:Unhandled group %d subfunction %d",group,sub); + Bitu top = FPU_GET_TOP(); + switch(group){ + case 0x00: /*FADDP STi,ST*/ + FPU_FADD((top+sub)&7,top); + break; + case 0x01: /* FMULP STi,ST*/ + FPU_FMUL((top+sub)&7,top); + break; + case 0x02: /* FCOMP5*/ + case 0x03: /* weird*/ + LOG(LOG_FPU,LOG_WARN)("ESC 6:Unhandled group %d subfunction %d",group,sub); + break; + case 0x04: /* FSUBRP STi,ST*/ + FPU_FSUBR((top+sub)&7,top); + break; + case 0x05: /* FSUBP STi,ST*/ + FPU_FSUB((top+sub)&7,top); + break; + case 0x06: /* FDIVRP STi,ST*/ + FPU_FDIVR((top+sub)&7,top); + break; + case 0x07: /* FDIVP STi,ST*/ + FPU_FDIV((top+sub)&7,top); + break; + default: + break; + } } void FPU_ESC5_EA(Bitu rm,PhysPt addr) { + Bitu group=(rm >> 3) & 7; + Bitu sub=(rm & 7); + LOG(LOG_FPU,LOG_WARN)("ESC EA 5:Unhandled group %d subfunction %d",group,sub); } void FPU_ESC5_Normal(Bitu rm) { @@ -145,20 +338,85 @@ void FPU_ESC5_Normal(Bitu rm) { void FPU_ESC6_EA(Bitu rm,PhysPt addr) { + /* 16 bit (word integer) operants */ + Bit16s blah = mem_readw(addr); + fpu.regs[8].d = static_cast(blah); + EATREE(rm); } void FPU_ESC6_Normal(Bitu rm) { + /* all P variants working only on registers */ + /* get top before switch and pop afterwards */ + Bitu group=(rm >> 3) & 7; + Bitu sub=(rm & 7); + Bitu top = FPU_GET_TOP(); + switch(group){ + case 0x00: /*FADDP STi,ST*/ + FPU_FADD((top+sub)&7,top); + break; + case 0x01: /* FMULP STi,ST*/ + FPU_FMUL((top+sub)&7,top); + break; + case 0x02: /* FCOMP5*/ + case 0x03: /* weird*/ + LOG(LOG_FPU,LOG_WARN)("ESC 6:Unhandled group %d subfunction %d",group,sub); + // maybe return and don't pop + break; + case 0x04: /* FSUBRP STi,ST*/ + FPU_FSUBR((top+sub)&7,top); + break; + case 0x05: /* FSUBP STi,ST*/ + FPU_FSUB((top+sub)&7,top); + break; + case 0x06: /* FDIVRP STi,ST*/ + FPU_FDIVR((top+sub)&7,top); + break; + case 0x07: /* FDIVP STi,ST*/ + FPU_FDIV((top+sub)&7,top); + break; + default: + break; + } + FPU_FPOP(); } void FPU_ESC7_EA(Bitu rm,PhysPt addr) { + Bitu group=(rm >> 3) & 7; + Bitu sub=(rm & 7); + switch(group){ + case 0x03: /*FISTP */ + { Bitu top = FPU_GET_TOP(); + mem_writew(addr,static_cast(fpu.regs[top].d)); + FPU_FPOP(); + } + break; + default: + LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub); + } } void FPU_ESC7_Normal(Bitu rm) { + Bitu group=(rm >> 3) & 7; + Bitu sub=(rm & 7); + switch (group){ + case 0x04: + switch(sub){ + case 0x00: /* FNSTSW AX*/ + reg_ax = fpu.sw; + break; + default: + break; + } + break; + default: + break; + } + LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub); } -void FPU_Init(void) { +void FPU_Init(Section*) { FPU_FINIT(); } diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index e93ef964..674aaabe 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -35,4 +35,86 @@ static void FPU_FCLEX(void){ static void FPU_FNOP(void){ return; +} + +static void FPU_PUSH(double in){ + Bitu newtop = (FPU_GET_TOP() - 1) &7; + FPU_SET_TOP(newtop); + //actually check if empty + fpu.tags[newtop]=TAG_Valid; + fpu.regs[newtop].d=in; + return; +} +static void FPU_PUSH_ZERO(void){ + Bitu newtop = (FPU_GET_TOP() - 1) &7; + FPU_SET_TOP(newtop); + //actually check if empty + fpu.tags[newtop]=TAG_Zero; + fpu.regs[newtop].d=0.0; + return; +} +static void FPU_FPOP(void){ + Bitu top = FPU_GET_TOP(); + fpu.tags[top]=TAG_Empty; + //maybe set zero in it as well + FPU_SET_TOP((top+1)&7); + return; +} + +static void FPU_FADD(Bitu op1, Bitu op2){ + fpu.regs[op1].d+=fpu.regs[op2].d; + //flags and such :) + return; +} + +static void FPU_FSIN(void){ + Bitu top = FPU_GET_TOP(); + fpu.regs[top].d = sin(fpu.regs[top].d); + //flags and such :) + return; +} + +static void FPU_FSINCOS(void){ + Bitu top = FPU_GET_TOP(); + fpu.regs[top].d = sin(fpu.regs[top].d); + FPU_PUSH(cos(fpu.regs[top].d)); + //flags and such :) + return; +} + +static void FPU_FCOS(void){ + Bitu top = FPU_GET_TOP(); + fpu.regs[top].d = cos(fpu.regs[top].d); + //flags and such :) + return; +} + +static void FPU_FDIV(Bitu st, Bitu other){ + fpu.regs[st].d= fpu.regs[st].d/fpu.regs[other].d; + //flags and such :) + return; +} + +static void FPU_FDIVR(Bitu st, Bitu other){ + fpu.regs[st].d= fpu.regs[other].d/fpu.regs[st].d; + // flags and such :) + return; +}; + +static void FPU_FMUL(Bitu st, Bitu other){ + fpu.regs[st].d*=fpu.regs[other].d; + //flags and such :) + return; +} + +static void FPU_FSUB(Bitu st, Bitu other){ + fpu.regs[st].d = fpu.regs[st].d - fpu.regs[other].d; + //flags and such :) + return; +} + +static void FPU_FSUBR(Bitu st, Bitu other){ + fpu.regs[st].d= fpu.regs[other].d - fpu.regs[st].d; + //flags and such :) + return; } \ No newline at end of file diff --git a/src/fpu/fpu_types.h b/src/fpu/fpu_types.h index ce9cfaec..b7cb434b 100644 --- a/src/fpu/fpu_types.h +++ b/src/fpu/fpu_types.h @@ -36,4 +36,6 @@ enum FPU_Round { ROUND_Down = 1, ROUND_Up = 2, ROUND_Chop = 3 -}; \ No newline at end of file +}; +//get pi from a real library +#define PI 3.1415926535 \ No newline at end of file From 3afdb23daff8492bbabec1e890b4207638981433 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Jun 2003 14:52:20 +0000 Subject: [PATCH 0949/4131] fpu init Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1029 --- src/dosbox.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 34e4629e..fc53a725 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -55,7 +55,9 @@ void DOS_Init(Section*); void CPU_Init(Section*); -//void FPU_Init(); +#if C_FPU +void FPU_Init(Section*); +#endif void DMA_Init(Section*); void MIXER_Init(Section*); void MIDI_Init(Section*); @@ -185,7 +187,9 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("cpu",&CPU_Init); secprop->Add_int("cycles",1800); - +#if C_FPU + secprop->AddInitFunction(&FPU_Init); +#endif secprop->AddInitFunction(&DMA_Init); secprop->AddInitFunction(&VGA_Init); secprop->AddInitFunction(&KEYBOARD_Init); @@ -252,9 +256,6 @@ void DOSBOX_Init(void) { control->SetStartUp(&SHELL_Init); -#if C_FPU - FPU_Init(); -#endif } From 66d0d1648b6ad8313c2db408ee395c02073e6721 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Jun 2003 16:18:47 +0000 Subject: [PATCH 0950/4131] tiny little error in fsincos Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1030 --- src/fpu/fpu_instructions.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 674aaabe..cf45b608 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -76,8 +76,10 @@ static void FPU_FSIN(void){ static void FPU_FSINCOS(void){ Bitu top = FPU_GET_TOP(); - fpu.regs[top].d = sin(fpu.regs[top].d); + + double temp = sin(fpu.regs[top].d); FPU_PUSH(cos(fpu.regs[top].d)); + fpu.regs[top].d = temp; //flags and such :) return; } From a6c80164995c7fff85e4dad83540c33cc0d74a69 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 1 Jun 2003 21:40:44 +0000 Subject: [PATCH 0951/4131] Add default defines for environ being supported in visual c Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1031 --- src/platform/visualc/config.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index ca9fb168..45bb58be 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -17,6 +17,12 @@ /* Enable the FPU module, still only for beta testing */ #define C_FPU 0 +/* environ is defined */ +#define ENVIRON_INCLUDED 1 + +/* environ can be linked */ +#define ENVIRON_LINKED 1 + /* Maximum memory address range in megabytes */ #define C_MEM_MAX_SIZE 12 From 9b6490656084cbd0b32fabd89bfa35253bd343a3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 2 Jun 2003 21:05:18 +0000 Subject: [PATCH 0952/4131] Add definition of parity table Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1032 --- include/cpu.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/cpu.h b/include/cpu.h index 4b55a912..5dbfe745 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -68,6 +68,7 @@ enum { t_LASTFLAG }; +extern bool parity_lookup[256]; void CPU_LLDT(Bitu selector); void CPU_LTR(Bitu selector); From 81e9ba2cdf3fafa1856fe700e48e27c316f430a6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 2 Jun 2003 21:08:31 +0000 Subject: [PATCH 0953/4131] Added some functions for acessing values in an endian safe way. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1033 --- include/mem.h | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/include/mem.h b/include/mem.h index 9c8e5c6b..12a316e7 100644 --- a/include/mem.h +++ b/include/mem.h @@ -79,16 +79,20 @@ INLINE void writeb(HostPt off,Bit8u val) { off[0]=val; }; INLINE void writew(HostPt off,Bit16u val) { - off[0]=(Bit8u)((val & 0x00ff)); - off[1]=(Bit8u)((val & 0xff00) >> 8); + off[0]=(Bit8u)(val); + off[1]=(Bit8u)(val >> 8); }; INLINE void writed(HostPt off,Bit32u val) { - off[0]=(Bit8u)((val & 0x000000ff)); - off[1]=(Bit8u)((val & 0x0000ff00) >> 8); - off[2]=(Bit8u)((val & 0x00ff0000) >> 16); - off[3]=(Bit8u)((val & 0xff000000) >> 24); + off[0]=(Bit8u)(val); + off[1]=(Bit8u)(val >> 8); + off[2]=(Bit8u)(val >> 16); + off[3]=(Bit8u)(val >> 24); }; +#define MLEB(_MLE_VAL_) (_MLE_VAL_) +#define MLEW(_MLE_VAL_) (_MLE_VAL_ >> 8) | (_MLE_VAL_ << 8)) +#define MLED(_MLE_VAL_) (_MLE_VAL_ >> 24)|((_MLE_VAL_ >> 8)&0xFF00)|((_MLE_VAL_ << 8)&0xFF0000)|((_MLE_VAL_ << 24)&0xFF000000)) + #else INLINE Bit8u readb(HostPt off) { @@ -110,8 +114,17 @@ INLINE void writed(HostPt off,Bit32u val) { *(Bit32u *)(off)=val; }; +#define MLEB(_MLE_VAL_) (_MLE_VAL_) +#define MLEW(_MLE_VAL_) (_MLE_VAL_) +#define MLED(_MLE_VAL_) (_MLE_VAL_) + #endif +#define WLE(VAR_,VAL_) \ + if (sizeof(VAR_)==1) VAR_=MLEB(VAL_); \ + if (sizeof(VAR_)==2) VAR_=MLEW(VAL_); \ + if (sizeof(VAR_)==4) VAR_=MLED(VAL_); + /* The Folowing six functions are slower but they recognize the paged memory system */ //TODO maybe make em inline to go a bit faster From 1169165d7fc305bed4883e2f5b454ff610c581bd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 2 Jun 2003 21:18:38 +0000 Subject: [PATCH 0954/4131] Allow switching of cpu cores through certain instructions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1034 --- src/cpu/cpu.cpp | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 6dce9085..f82c064f 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -40,6 +40,24 @@ Bits CPU_CycleMax=1500; CPU_Decoder * cpudecoder; +void CPU_Real_16_Slow_Start(void); +void CPU_Core_Full_Start(void); + +typedef void DecoderStart(void); + +//Determine correct core, to start from cpu state. +DecoderStart * CPU_DecorderStarts[8]={ + CPU_Real_16_Slow_Start, //16-bit real,16-bit stack +// CPU_Core_Full_Start, //16-bit prot,16-bit stack + CPU_Core_Full_Start, //16-bit prot,16-bit stack + 0, //32-bit real,16-bit stack ILLEGAL + CPU_Core_Full_Start, //32-bit prot,16-bit stack + 0, //16-bit real,32-bit stack ILLEGAL + CPU_Core_Full_Start, //16-bit prot,32-bit stack + 0, //32-bit real,32-bit stack ILLEGAL + CPU_Core_Full_Start, //32-bit prot,32-bit stack +}; + INLINE void CPU_Push16(Bitu value) { if (cpu.state & STATE_STACK32) { reg_esp-=2; @@ -95,10 +113,10 @@ PhysPt SelBase(Bitu sel) { } bool CPU_CheckState(void) { - cpu.state=0; + Bitu old_state=cpu.state; + cpu.state=0; if (!(cpu.cr0 & CR0_PROTECTION)) { cpu.full.entry=cpu.full.prefix=0; - return true; } else { cpu.state|=STATE_PROTECTED; if (Segs.big[cs]) { @@ -111,8 +129,11 @@ bool CPU_CheckState(void) { if (Segs.big[ss]) cpu.state|=STATE_STACK32; LOG_MSG("CPL Level %x at %X:%X",cpu.cpl,SegValue(cs),reg_eip); } - return true; + if (old_state==cpu.state) return true; + (*CPU_DecorderStarts[cpu.state])(); + return false; } + Bit8u lastint; bool Interrupt(Bitu num) { lastint=num; @@ -771,14 +792,6 @@ void CPU_CPUID(void) { void CPU_Real_16_Slow_Start(void); void CPU_Core_Full_Start(void); -void SetCPU16bit() -{ - cpu.state=0; - cpu.cr0=false; - CPU_Real_16_Slow_Start(); -// CPU_Core_Full_Start(); -} - static void CPU_CycleIncrease(void) { Bitu old_cycles=CPU_CycleMax; CPU_CycleMax=(Bitu)(CPU_CycleMax*1.2); @@ -818,8 +831,11 @@ void CPU_Init(Section* sec) { flags.type=t_UNKNOWN; cpu.full.entry=cpu.full.prefix=0; - SetCPU16bit(); - + cpu.state=0xff; //To initialize it the first time + cpu.cr0=false; + + CPU_CheckState(); + KEYBOARD_AddEvent(KBD_f11,KBD_MOD_CTRL,CPU_CycleDecrease); KEYBOARD_AddEvent(KBD_f12,KBD_MOD_CTRL,CPU_CycleIncrease); From 74c8142695df607d253f934519d2a7a209f7764b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 2 Jun 2003 21:19:08 +0000 Subject: [PATCH 0955/4131] parity table isn't static anymore Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1035 --- src/cpu/flags.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 44781cc5..c74b1edf 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -544,7 +544,7 @@ again: return false; } -static bool parity_lookup[256] = { +bool parity_lookup[256] = { 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, From 0682de08bec3aed9a8bd5673c431b77db7771484 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 2 Jun 2003 21:20:17 +0000 Subject: [PATCH 0956/4131] Fix flags for AAM and AAD Don't check for nonsense rotates, since they do change the flags. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1036 --- src/cpu/instructions.h | 66 +++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 2f45ae43..0ea3f7a4 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -220,7 +220,6 @@ flags.type=t_DECd; #define ROLB(op1,op2,load,save) \ - if (op2&0x07) { \ LoadZF;LoadSF;LoadAF; \ flags.var1.b=load(op1); \ flags.var2.b=op2&0x07; \ @@ -228,10 +227,9 @@ (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) { \ LoadZF;LoadSF;LoadAF; \ flags.var1.w=load(op1); \ flags.var2.b=op2&0x0F; \ @@ -239,10 +237,9 @@ (flags.var1.w >> (16-flags.var2.b)); \ save(op1,flags.result.w); \ flags.type=t_ROLw; \ - } + #define ROLD(op1,op2,load,save) \ - if (op2) { \ LoadZF;LoadSF;LoadAF; \ flags.var1.d=load(op1); \ flags.var2.b=op2; \ @@ -250,10 +247,9 @@ (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) { \ LoadZF;LoadSF;LoadAF; \ flags.var1.b=load(op1); \ flags.var2.b=op2&0x07; \ @@ -261,7 +257,7 @@ (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) { \ @@ -380,52 +376,52 @@ #define SHLB(op1,op2,load,save) \ - if (!op2) break; \ - flags.var1.b=load(op1);flags.var2.b=op2; \ + 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 ; \ + 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; \ + 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; \ + 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; \ + 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; \ + 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 (!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)| \ @@ -531,25 +527,29 @@ reg_ah=reg_al / BLAH; \ reg_al=reg_al % BLAH; \ flags.type=t_UNKNOWN; \ - SETFLAGBIT(SF,(reg_ah & 0x80)); \ - SETFLAGBIT(ZF,(reg_ax == 0)); \ - SETFLAGBIT(PF,false); \ + SETFLAGBIT(SF,(reg_al & 0x80)); \ + SETFLAGBIT(ZF,(reg_al == 0)); \ + SETFLAGBIT(PF,parity_lookup[reg_al]); \ } +//Took this from bochs, i seriously hate these weird bcd opcodes #define AAD(op1) \ { \ - Bit8u BLAH=op1; \ - reg_al=reg_ah*BLAH+reg_al; \ - reg_ah=0; \ - SETFLAGBIT(CF,(reg_al>=0x80)); \ - SETFLAGBIT(ZF,(reg_al==0)); \ - SETFLAGBIT(PF,false); \ + Bit16u ax1 = reg_ah * op1; \ + Bit16u ax2 = ax1 + reg_al; \ + Bit8u old_al = reg_al; \ + reg_al = (Bit8u) ax2; \ + reg_ah = 0; \ + SETFLAGBIT(AF,(ax1 & 0x08) != (ax2 & 0x08)); \ + SETFLAGBIT(CF,ax2 > 0xff); \ + SETFLAGBIT(OF,(reg_al & 0x80) != (old_al & 0x80)); \ + SETFLAGBIT(SF,reg_al >= 0x80); \ + SETFLAGBIT(ZF,reg_al == 0); \ + SETFLAGBIT(PF,parity_lookup[reg_al]); \ flags.type=t_UNKNOWN; \ } - - #define MULB(op1,load,save) \ flags.type=t_MUL; \ reg_ax=reg_al*load(op1); \ From f92993a1210158b2e05967a1726d2be91da2efdd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 2 Jun 2003 21:22:01 +0000 Subject: [PATCH 0957/4131] add IN EAX,DX Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1037 --- src/cpu/core_16/prefix_66.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index 0e30f431..0c662a56 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -401,13 +401,18 @@ switch(Fetchb()) { GRP2D(1);break; case 0xd3: /* GRP2 Ed,CL */ GRP2D(reg_cl);break; + case 0xed: /* IN EAX,DX */ + reg_eax=IO_Read(reg_dx) | + (IO_Read(reg_dx+1) << 8) | + (IO_Read(reg_dx+2) << 16) | + (IO_Read(reg_dx+3) << 24); + break; case 0xef: /* OUT DX,EAX */ IO_Write(reg_dx,(Bit8u)(reg_eax>>0)); IO_Write(reg_dx+1,(Bit8u)(reg_eax>>8)); IO_Write(reg_dx+2,(Bit8u)(reg_eax>>16)); IO_Write(reg_dx+3,(Bit8u)(reg_eax>>24)); break; - case 0xf2: /* REPNZ */ prefix.count++; Repeat_Normal(false,true); From a8132aee39869f74d8654d8014ab3df6b7681d5e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 2 Jun 2003 21:22:34 +0000 Subject: [PATCH 0958/4131] Cleaned up a load of comments. Support for pmode related instructions to switch to other core. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1038 --- src/cpu/core_16/prefix_66_of.h | 49 +++++++- src/cpu/core_16/prefix_of.h | 203 ++++++++++++++------------------- 2 files changed, 132 insertions(+), 120 deletions(-) diff --git a/src/cpu/core_16/prefix_66_of.h b/src/cpu/core_16/prefix_66_of.h index 0ec604bd..0738eda8 100644 --- a/src/cpu/core_16/prefix_66_of.h +++ b/src/cpu/core_16/prefix_66_of.h @@ -17,8 +17,55 @@ */ switch (Fetchb()) { + case 0x01: /* Group 7 Ed */ + { + GetRM;Bitu which=(rm>>3)&7; + if (rm < 0xc0) { //First ones all use EA + GetEAa;Bitu limit,base; + switch (which) { + case 0x00: /* SGDT */ + CPU_SGDT(limit,base); + SaveMw(eaa,limit); + SaveMd(eaa+2,base); + break; + case 0x01: /* SIDT */ + CPU_SIDT(limit,base); + SaveMw(eaa,limit); + SaveMd(eaa+2,base); + break; + case 0x02: /* LGDT */ + CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2)); + break; + case 0x03: /* LIDT */ + CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2)); + break; + case 0x04: /* SMSW */ + CPU_SMSW(limit); + SaveMw(eaa,limit); + break; + case 0x06: /* LMSW */ + limit=LoadMw(eaa); + if (!CPU_LMSW(limit)) goto decode_end; + break; + } + } else { + GetEArw;Bitu limit; + switch (which) { + case 0x04: /* SMSW */ + CPU_SMSW(limit); + *earw=limit; + break; + case 0x06: /* LMSW */ + if (!CPU_LMSW(*earw)) goto decode_end; + break; + default: + LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which); + break; + } - + } + } + break; case 0xa4: /* SHLD Ed,Gd,Ib */ { GetRMrd; diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h index 750e0dc2..21c1d46e 100644 --- a/src/cpu/core_16/prefix_of.h +++ b/src/cpu/core_16/prefix_of.h @@ -19,95 +19,96 @@ switch(Fetchb()) { case 0x00: /* GRP 6 */ { - EXCEPTION(6); - break; - GetRM; - switch (rm & 0x38) { - case 0x00: - default: - E_Exit("CPU:GRP6:Illegal call %2X",(rm>>3) &3); - } - } - break; - - 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);} + GetRM;Bitu which=(rm>>3)&7; + switch (which) { + case 0x00: /* SLDT */ + case 0x01: /* STR */ + { + Bitu saveval; + if (!which) CPU_SLDT(saveval); + else CPU_STR(saveval); + if (rm>0xc0) {GetEArw;*earw=saveval;} + else {GetEAa;SaveMw(eaa,saveval);} + } break; + case 0x02:case 0x03:case 0x04:case 0x05: + { + Bitu loadval; + if (rm >= 0xc0 ) {GetEArw;loadval=*earw;} + else {GetEAa;loadval=LoadMw(eaa);} + break; + switch (which) { + case 0x02:CPU_LLDT(loadval);break; + case 0x03:CPU_LTR(loadval);break; + case 0x04:CPU_VERR(loadval);break; + case 0x05:CPU_VERW(loadval);break; + } + } default: - GetEAa; - LOG(LOG_CPU,LOG_ERROR)("GRP7:Illegal call %2X",(rm>>3) &3); + LOG(LOG_CPU,LOG_ERROR)("GRP6:Illegal call %2X",which); + } + } + break; + case 0x01: /* Group 7 Ew */ + { + GetRM;Bitu which=(rm>>3)&7; + if (rm < 0xc0) { //First ones all use EA + GetEAa;Bitu limit,base; + switch (which) { + case 0x00: /* SGDT */ + CPU_SGDT(limit,base); + SaveMw(eaa,limit); + SaveMd(eaa+2,base); + break; + case 0x01: /* SIDT */ + CPU_SIDT(limit,base); + SaveMw(eaa,limit); + SaveMd(eaa+2,base); + break; + case 0x02: /* LGDT */ + CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF); + break; + case 0x03: /* LIDT */ + CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF); + break; + case 0x04: /* SMSW */ + CPU_SMSW(limit); + SaveMw(eaa,limit); + break; + case 0x06: /* LMSW */ + limit=LoadMw(eaa); + if (!CPU_LMSW(limit)) goto decode_end; + break; + } + } else { + GetEArw;Bitu limit; + switch (which) { + case 0x04: /* SMSW */ + CPU_SMSW(limit); + *earw=limit; + break; + case 0x06: /* LMSW */ + if (!CPU_LMSW(*earw)) goto decode_end; + break; + default: + LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which); + break; + } } } break; - /* 0x02 LAR Gw,Ew (286) */ - /* 0x03 LSL Gw,Ew (286) */ - /* 0x05 LOADALL (286 only?) */ - /* 0x06 CLTS (286) */ - /* 0x07 LOADALL (386 only?) */ - /* 0x08 INVD (486) */ - /* 0x02 WBINVD (486) */ - /* 0x10 UMOV Eb,Gb (386) */ - /* 0x11 UMOV Ew,Gw (386) */ - /* 0x12 UMOV Gb,Eb (386) */ - /* 0x13 UMOV Gw,Ew (386) */ - /* 0x20 MOV Rd,CRx (386) */ - /* 0x21 MOV Rd,DRx (386) */ - /* 0x22 MOV CRx,Rd (386) */ - /* 0x23 MOV DRx,Rd (386) */ case 0x23: /* MOV DRx,Rd */ { GetRM; - LOG(LOG_CPU,LOG_NORMAL)("CPU:0F:23 does nothing"); + Bitu which=(rm >> 3) & 7; + if (rm >= 0xc0 ) { + GetEArw; + } else { + GetEAa; + LOG(LOG_CPU,LOG_ERROR)("MOV DR%,XXX with non-register",which); + } } break; - /* 0x24 MOV Rd,TRx (386) */ - /* 0x26 MOV TRx,Rd (386) */ - /* 0x30 WRMSR (P5) */ - /* 0x31 RDTSC (P5) */ - /* 0x32 RDMSR (P5) */ - /* 0x33 RDPMC (P6) */ - /* 0x40-4F CMOVcc Gw,Ew (P6) */ - /* 0x50 PAVEB Rq,Eq (CYRIX MMX) */ - /* 0x51 PADDSIW Rq,Eq (CYRIX MMX) */ - /* 0x52 PMAGW Rq,Eq (CYRIX MMX) */ - /* 0x54 PDISTIB Rq,Eq (CYRIX MMX) */ - /* 0x55 PSUBSIW Rq,Eq (CYRIX MMX) */ - /* 0x58 PMVZB Rq,Eq (CYRIX MMX) */ - /* 0x59 PMULHRW Rq,Eq (CYRIX MMX) */ - /* 0x5A PMVNZB Rq,Eq (CYRIX MMX) */ - /* 0x5B PMVLZB Rq,Eq (CYRIX MMX) */ - /* 0x5C PMVGEZB Rq,Eq (CYRIX MMX) */ - /* 0x5D PMULHRIW Rq,Eq (CYRIX MMX) */ - /* 0x5E PMACHRIW Rq,Eq (CYRIX MMX) */ - /* 0x60 PUNPCKLBW Rq,Eq (MMX) */ - /* 0x61 PUNPCKLWD Rq,Eq (MMX) */ - /* 0x62 PUNPCKLDQ Rq,Eq (MMX) */ - /* 0x63 PACKSSWB Rq,Eq (MMX) */ - /* 0x64 PCMPGTB Rq,Eq (MMX) */ - /* 0x65 PCMPGTW Rq,Eq (MMX) */ - /* 0x66 PCMPGTD Rq,Eq (MMX) */ - /* 0x67 PACKUSWB Rq,Eq (MMX) */ - /* 0x68 PUNPCKHBW Rq,Eq (MMX) */ - /* 0x69 PUNPCKHWD Rq,Eq (MMX) */ - /* 0x6A PUNPCKHDQ Rq,Eq (MMX) */ - /* 0x6B PACKSSDW Rq,Eq (MMX) */ - /* 0x6E MOVD Rq,Ed (MMX) */ - /* 0x6F MOVQ Rq,Eq (MMX) */ - /* 0x71 PSLLW/PSRAW/PSRLW Rq,Ib (MMX) */ - /* 0x72 PSLLD/PSRAD/PSRLD Rq,Ib (MMX) */ - /* 0x73 PSLLQ/PSRLQ Rq,Ib (MMX) */ - /* 0x74 PCMPEQB Rq,Eq (MMX) */ - /* 0x75 PCMPEQW Rq,Eq (MMX) */ - /* 0x76 PCMPEQD Rq,Eq (MMX) */ - /* 0x77 EMMS (MMX) */ - /* 0x7E MOVD Ed,Rq (MMX) */ - /* 0x7F MOVQ Ed,Rq (MMX) */ case 0x80: /* JO */ JumpSIw(get_OF());break; case 0x81: /* JNO */ @@ -178,7 +179,9 @@ switch(Fetchb()) { Push_16(SegValue(fs));break; case 0xa1: /* POP FS */ SegSet16(fs,Pop_16());break; - /* 0xa2 CPUID */ + case 0xa2: + CPU_CPUID(); + break; case 0xa3: /* BT Ew,Gw */ { GetRMrw; @@ -199,13 +202,10 @@ switch(Fetchb()) { case 0xa5: /* SHLD Ew,Gw,CL */ RMEwGwOp3(DSHLW,reg_cl); break; - /* 0xa6 XBTS (early 386 only) CMPXCHG (early 486 only) */ - /* 0xa7 IBTS (early 386 only) CMPXCHG (early 486 only) */ case 0xa8: /* PUSH GS */ Push_16(SegValue(gs));break; case 0xa9: /* POP GS */ SegSet16(gs,Pop_16());break; - /* 0xaa RSM */ case 0xab: /* BTS Ew,Gw */ { GetRMrw; @@ -231,9 +231,7 @@ switch(Fetchb()) { case 0xaf: /* IMUL Gw,Ew */ RMGwEwOp3(DIMULW,*rmrw); break; - - /* 0xb0 CMPXCHG Eb,Gb */ - /* 0xb1 CMPXCHG Ew,Gw */ + case 0xb2: /* LSS */ { GetRMrw;GetEAa; @@ -385,10 +383,6 @@ switch(Fetchb()) { else {GetEAa;*rmrw=LoadMbs(eaa);} break; } - /* 0xc0 XADD Eb,Gb (486) */ - /* 0xc1 XADD Ew,Gw (486) */ - /* 0xc7 CMPXCHG8B Mq (P5) */ - /* 0xc8-cf BSWAP Rw (odd behavior,486) */ case 0xc8: BSWAP(reg_eax); break; case 0xc9: BSWAP(reg_ecx); break; case 0xca: BSWAP(reg_edx); break; @@ -398,35 +392,6 @@ switch(Fetchb()) { case 0xce: BSWAP(reg_esi); break; case 0xcf: BSWAP(reg_edi); break; - /* 0xd1 PSRLW Rq,Eq (MMX) */ - /* 0xd2 PSRLD Rq,Eq (MMX) */ - /* 0xd3 PSRLQ Rq,Eq (MMX) */ - /* 0xd5 PMULLW Rq,Eq (MMX) */ - /* 0xd8 PSUBUSB Rq,Eq (MMX) */ - /* 0xd9 PSUBUSW Rq,Eq (MMX) */ - /* 0xdb PAND Rq,Eq (MMX) */ - /* 0xdc PADDUSB Rq,Eq (MMX) */ - /* 0xdd PADDUSW Rq,Eq (MMX) */ - /* 0xdf PANDN Rq,Eq (MMX) */ - /* 0xe1 PSRAW Rq,Eq (MMX) */ - /* 0xe2 PSRAD Rq,Eq (MMX) */ - /* 0xe5 PMULHW Rq,Eq (MMX) */ - /* 0xe8 PSUBSB Rq,Eq (MMX) */ - /* 0xe9 PSUBSW Rq,Eq (MMX) */ - /* 0xeb POR Rq,Eq (MMX) */ - /* 0xec PADDSB Rq,Eq (MMX) */ - /* 0xed PADDSW Rq,Eq (MMX) */ - /* 0xef PXOR Rq,Eq (MMX) */ - /* 0xf1 PSLLW Rq,Eq (MMX) */ - /* 0xf2 PSLLD Rq,Eq (MMX) */ - /* 0xf3 PSLLQ Rq,Eq (MMX) */ - /* 0xf5 PMADDWD Rq,Eq (MMX) */ - /* 0xf8 PSUBB Rq,Eq (MMX) */ - /* 0xf9 PSUBW Rq,Eq (MMX) */ - /* 0xfa PSUBD Rq,Eq (MMX) */ - /* 0xfc PADDB Rq,Eq (MMX) */ - /* 0xfd PADDW Rq,Eq (MMX) */ - /* 0xfe PADDD Rq,Eq (MMX) */ default: SUBIP(1); E_Exit("CPU:Opcode 0F:%2X Unhandled",Fetchb()); From f6e003c808c6a387ee63c699753c352f6538e40e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 2 Jun 2003 21:24:03 +0000 Subject: [PATCH 0959/4131] Disasble built in dpmi host for now Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1039 --- src/ints/dpmi.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index 5c8d7f61..8c277a04 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -52,6 +52,7 @@ static bool DPMI_Multiplex(void) { } void DPMI_Init(Section* sec) { + return; DOS_AddMultiplexHandler(DPMI_Multiplex); From 40a4d72267bf344805faa5f3b957f066603946fd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 3 Jun 2003 18:06:53 +0000 Subject: [PATCH 0960/4131] Some more 0x0f prefixed instructions related to protected mode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1040 --- src/cpu/core_16/prefix_of.h | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h index 21c1d46e..55450955 100644 --- a/src/cpu/core_16/prefix_of.h +++ b/src/cpu/core_16/prefix_of.h @@ -97,12 +97,38 @@ switch(Fetchb()) { } } break; + case 0x20: /* MOV Rd.CRx */ + { + GetRM; + Bitu which=(rm >> 3) & 7; + if (rm >= 0xc0 ) { + GetEArd; + *eard=CPU_GET_CRX(which); + } else { + GetEAa; + LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%d with non-register",which); + } + } + break; + case 0x22: /* MOV CRx,Rd */ + { + GetRM; + Bitu which=(rm >> 3) & 7; + if (rm >= 0xc0 ) { + GetEArd; + if (!CPU_SET_CRX(which,*eard)) goto decode_end; + } else { + GetEAa; + LOG(LOG_CPU,LOG_ERROR)("MOV CR%,XXX with non-register",which); + } + } + break; case 0x23: /* MOV DRx,Rd */ { GetRM; Bitu which=(rm >> 3) & 7; if (rm >= 0xc0 ) { - GetEArw; + GetEArd; } else { GetEAa; LOG(LOG_CPU,LOG_ERROR)("MOV DR%,XXX with non-register",which); From e18eebf29d1495267cc75296656c4404d422e929 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 5 Jun 2003 09:52:13 +0000 Subject: [PATCH 0961/4131] Dont dublicate handles in psp when filetable is copied Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1041 --- src/dos/dos_classes.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index dce39fbe..320a4069 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -162,8 +162,8 @@ void DOS_PSP::CopyFileTable(DOS_PSP* srcpsp,bool createchildpsp) for (Bit16u i=0;i<20;i++) { Bit8u handle = srcpsp->GetFileHandle(i); if(createchildpsp) - { //copy obeying not inherit flag. - if(Files[handle] && !(Files[handle]->flags & DOS_NOT_INHERIT)) + { //copy obeying not inherit flag.(but dont duplicate them) + if(Files[handle] && !(Files[handle]->flags & DOS_NOT_INHERIT) && (FindEntryByHandle(handle)==0xff)) { SetFileHandle(i,handle); } From cf0b2cbd6c88315c9ffa47368f1d9263ebf98466 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 5 Jun 2003 11:03:12 +0000 Subject: [PATCH 0962/4131] dont duplicate handles in psp if filetable is copied (except null-handles) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1042 --- src/dos/dos_classes.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 320a4069..6f622b3e 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -163,7 +163,8 @@ void DOS_PSP::CopyFileTable(DOS_PSP* srcpsp,bool createchildpsp) Bit8u handle = srcpsp->GetFileHandle(i); if(createchildpsp) { //copy obeying not inherit flag.(but dont duplicate them) - if(Files[handle] && !(Files[handle]->flags & DOS_NOT_INHERIT) && (FindEntryByHandle(handle)==0xff)) + bool allowCopy = (handle==0) || ((handle>0) && (FindEntryByHandle(handle)==0xff)); + if(Files[handle] && !(Files[handle]->flags & DOS_NOT_INHERIT) && allowCopy) { SetFileHandle(i,handle); } From 4eaaac62b556db39d1d6f80c661e7ce16aaae49b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 6 Jun 2003 06:51:32 +0000 Subject: [PATCH 0963/4131] sysex messages need a send_event Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1043 --- src/gui/midi_alsa.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index e1b9735a..9f13a652 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -68,6 +68,7 @@ public: char* GetName(void) { return "alsa"; } void PlaySysex(Bit8u * sysex,Bitu len) { snd_seq_ev_set_sysex(&ev, len, sysex); + send_event(1); } void PlayMsg(Bit32u msg) { From 400da21a32e3c4558e84b46dfb4b6342c8770b53 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 9 Jun 2003 23:28:24 +0000 Subject: [PATCH 0964/4131] Added WAIT and 16-bit BSF,BSR Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1044 --- src/cpu/core_full/load.h | 1 + src/cpu/core_full/op.h | 26 ++++++++++++++++++++++++++ src/cpu/core_full/optable.h | 7 +++---- src/cpu/core_full/support.h | 2 +- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 2dfbfbd2..f90180fc 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -371,6 +371,7 @@ l_M_Ed: case D_STD: SETFLAGBIT(DF,true); goto nextopcode; + case D_WAIT: case D_NOP: goto nextopcode; case D_ENTERw: diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index ee493b5a..26057cb6 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -483,6 +483,32 @@ switch (inst.code.op) { inst.op1.d=new_sel; } break; + case O_BSFw: + { + FILLFLAGS; + if (!inst.op1.w) SETFLAGBIT(ZF,true); + Bitu count=0; + while (count<16) { + if ((inst.op1.w>>count) & 1) break; + count++; + } + inst.op1.d=count; + SETFLAGBIT(ZF,false); + } + break; + case O_BSRw: + { + FILLFLAGS; + if (!inst.op1.w) SETFLAGBIT(ZF,true); + Bits count=15; + while (count>0) { + if ((inst.op1.w>>count) & 1) break; + count--; + } + inst.op1.d=count; + SETFLAGBIT(ZF,false); + } + break; case O_BTw: case O_BTSw: case O_BTCw: diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index b06b0ffd..367d46f7 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -109,7 +109,7 @@ static OpCode OpCodeTable[1024]={ {L_REGw ,O_XCHG_AX ,S_REGw ,REGI_SI},{L_REGw ,O_XCHG_AX ,S_REGw ,REGI_DI}, /* 0x98 - 0x9f */ {D_CBW ,0 ,0 ,0 },{D_CWD ,0 ,0 ,0 }, -{L_Ifw ,O_CALLFw ,0 ,0 },{L_ERROR ,0 ,0 ,0 }, +{L_Ifw ,O_CALLFw ,0 ,0 },{D_WAIT ,0 ,0 ,0 }, {L_FLG ,0 ,S_PUSHw,0 },{L_POPw ,0 ,S_FLGw ,0 }, {L_REGb ,0 ,S_FLGb ,REGI_AH},{L_FLG ,0 ,S_REGb ,REGI_AH}, @@ -311,7 +311,7 @@ static OpCode OpCodeTable[1024]={ /* 0x1b8 - 0x1bf */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {L_MODRM ,0xe ,0 ,M_GRP },{L_MODRM ,O_BTCw ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_BSFw ,S_Gw ,M_Ew },{L_MODRM ,O_BSRw ,S_Gw ,M_Ew }, {L_MODRM ,0 ,S_Gw ,M_Ebx },{L_MODRM ,0 ,S_Gw ,M_Ewx }, /* 0x1c0 - 0x1cc */ @@ -466,8 +466,7 @@ static OpCode OpCodeTable[1024]={ {L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_SI},{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_DI}, /* 0x298 - 0x29f */ {D_CWDE ,0 ,0 ,0 },{D_CDQ ,0 ,0 ,0 }, -//TODO Wait shoudn't be nop -{L_Ifd ,O_CALLFd ,0 ,0 },{D_NOP ,0 ,0 ,0 }, +{L_Ifd ,O_CALLFd ,0 ,0 },{D_WAIT ,0 ,0 ,0 }, {L_FLG ,0 ,S_PUSHd,0 },{L_POPd ,0 ,S_FLGd ,0 }, {L_REGb ,0 ,S_FLGb ,REGI_AH},{L_FLG ,0 ,S_REGb ,REGI_AH}, diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 5a9e9634..2d2477de 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -36,7 +36,7 @@ enum { D_SETALC, D_XLATw,D_XLATd, D_CLI,D_STI,D_STC,D_CLC,D_CMC,D_CLD,D_STD, - D_NOP, + D_NOP,D_WAIT, D_ENTERw,D_ENTERd, D_LEAVEw,D_LEAVEd, L_ERROR, From a3b63b239bdebde4cf28471c3cc67504b8e1af3d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 10 Jun 2003 06:56:41 +0000 Subject: [PATCH 0965/4131] Some fpu changes for others to try Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1045 --- src/fpu/fpu.cpp | 291 ++++++++++++++++++++++++++++++++++--- src/fpu/fpu_instructions.h | 86 ++++++++++- src/fpu/fpu_types.h | 6 +- 3 files changed, 353 insertions(+), 30 deletions(-) diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index af40c670..361af493 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -50,9 +50,13 @@ struct { INLINE void FPU_SetCW(Bitu word) { fpu.cw = word; - fpu.round = (FPU_Round)((word >> 8) & 3); + fpu.round = (FPU_Round)((word >> 10) & 3); + // word >>8 &3 is precission fpu.ex_mask = word & 0x3f; } + + + INLINE Bitu FPU_GET_TOP(void){ return (fpu.sw & 0x3800)>>11; } @@ -62,11 +66,39 @@ INLINE void FPU_SET_TOP(Bitu val){ return; } +INLINE void FPU_SET_C0(Bitu C){ + fpu.sw &= ~0x0100; + if(C) fpu.sw |= 0x0100; +} +INLINE void FPU_SET_C1(Bitu C){ + fpu.sw &= ~0x0200; + if(C) fpu.sw |= 0x0200; +} +INLINE void FPU_SET_C2(Bitu C){ + fpu.sw &= ~0x0400; + if(C) fpu.sw |= 0x0400; +} +INLINE void FPU_SET_C3(Bitu C){ + fpu.sw &= ~0x4000; + if(C) fpu.sw |= 0x4000; +} + +INLINE Bitu FPU_GET_C0(void){ + return (fpu.sw & 0x0100)>>8; +} +INLINE Bitu FPU_GET_C1(void){ + return (fpu.sw & 0x0200)>>9; +} +INLINE Bitu FPU_GET_C2(void){ + return (fpu.sw & 0x0400)>>10; +} +INLINE Bitu FPU_GET_C3(void){ + return (fpu.sw & 0x4000)>>14; +} #include "fpu_instructions.h" -/* TODO : MAKE REGULAR TREE A DEFINE or a function - : ESC6normal => esc4normal+pop or a define as well +/* TODO : ESC6normal => esc4normal+pop or a define as well : Make a smarter top system. won't matter that much in speed though. : #define ST fpu.top #define ST(i) (fpu.top+(i))&7 maybe*/ @@ -82,8 +114,11 @@ static void EATREE(Bitu _rm){ FPU_FMUL(top, 8); break; case 0x02: /* FICOM */ + FPU_FCOM(top,8); + break; case 0x03: /* FICOMP */ - LOG(LOG_FPU,LOG_WARN)("ESC EATREE:Unhandled group %d",group); + FPU_FCOM(top,8); + FPU_FPOP(); break; case 0x04: /* FISUB */ FPU_FSUB(top,8); @@ -105,11 +140,11 @@ static void EATREE(Bitu _rm){ void FPU_ESC0_EA(Bitu rm,PhysPt addr) { /* REGULAR TREE WITH 32 BITS REALS ? float ? */ //THIS SHOULD GO ALLRIGHT !?! - LOG(LOG_FPU, LOG_WARN)("ESC 0 EA used (check the result!)"); +// LOG(LOG_FPU, LOG_WARN)("ESC 0 EA used (check the result!)"); union { float f; - Bit32s l; + Bit32u l; } blah; blah.l = mem_readd(addr); fpu.regs[8].d = static_cast(blah.f); @@ -128,8 +163,11 @@ void FPU_ESC0_Normal(Bitu rm) { FPU_FMUL(top,(top+sub)&7); break; case 0x02: /* FCOM STi */ + FPU_FCOM(top,(top+sub)&7); + break; case 0x03: /* FCOMP STi */ - LOG(LOG_FPU,LOG_WARN)("ESC 0:Unhandled group %d subfunction %d",group,sub); + FPU_FCOM(top,(top+sub)&7); + FPU_FPOP(); break; case 0x04: /* FSUB ST,STi */ FPU_FSUB(top,(top+sub)&7); @@ -150,9 +188,61 @@ void FPU_ESC0_Normal(Bitu rm) { } void FPU_ESC1_EA(Bitu rm,PhysPt addr) { +// floats Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); - LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub); + switch(group){ + case 0x00: /* FLD */ + { + union { + float f; + Bit32u l; + } blah; + blah.l = mem_readd(addr); + FPU_PUSH(static_cast(blah.f)); + } + break; + + case 0x01: /* UNKNOWN */ + LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub); + break; + case 0x02: /* FST */ + { + union { + float f; + Bit32u l; + } blah; + //should depend on rounding method + blah.f = static_cast(fpu.regs[FPU_GET_TOP()].d); + mem_writed(addr,blah.l); + } + break; + + case 0x03: /* FSTP */ + { + union { + float f; + Bit32u l; + } blah; + blah.f = static_cast(fpu.regs[FPU_GET_TOP()].d); + mem_writed(addr,blah.l); + } + FPU_FPOP(); + break; + case 0x05: /*FLDCW */ + { + Bit16u temp =mem_readw(addr); + FPU_SetCW(temp); + } + break; + case 0x07: /* FNSTCW*/ + mem_writew(addr,fpu.cw); + break; + default: + LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub); + break; + } + } void FPU_ESC1_Normal(Bitu rm) { @@ -165,13 +255,36 @@ void FPU_ESC1_Normal(Bitu rm) { FPU_PUSH(fpu.regs[(top+sub)&7].d); } break; + case 0x01: /* FXCH STi */ + { + Bitu top = FPU_GET_TOP(); + FPU_FXCH(top,(top+sub)&7); + } + break; case 0x04: switch(sub){ case 0x00: /* FCHS */ + { + Bitu top = FPU_GET_TOP(); + fpu.regs[top].d = -1.0*(fpu.regs[top].d); + } + break; case 0x01: /* FABS */ + { + Bitu top = FPU_GET_TOP(); + fpu.regs[top].d = fabs(fpu.regs[top].d); + } + 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 */ + { Bitu top = FPU_GET_TOP(); + fpu.regs[8].d=0.0; + FPU_FCOM(top,8); + } + break; case 0x05: /* FXAM */ case 0x06: /* FTSTP (cyrix)*/ case 0x07: /* UNKNOWN */ @@ -203,15 +316,35 @@ void FPU_ESC1_Normal(Bitu rm) { } break; case 0x06: + switch(sub){ + case 0x02: /* FPTAN */ + FPU_FPTAN(); + break; + case 0x03: /* FPATAN */ + FPU_FPATAN(); + break; + default: LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); break; + } + break; case 0x07: switch(sub){ - + case 0x02: /* FSQRT */ + FPU_FSQRT(); + break; case 0x03: /* FSINCOS */ FPU_FSINCOS(); break; + case 0x04: /* FRNDINT */ + { + Bitu top = FPU_GET_TOP(); + Bit32s temp= static_cast(FROUND(fpu.regs[top].d)); + fpu.regs[top].d=static_cast(temp); + } + //TODO + break; case 0x06: /* FSIN */ FPU_FSIN(); break; @@ -246,6 +379,33 @@ void FPU_ESC2_Normal(Bitu rm) { void FPU_ESC3_EA(Bitu rm,PhysPt addr) { + Bitu group=(rm >> 3) & 7; + Bitu sub=(rm & 7); + switch(group){ + case 0x00: /* FLD */ + { + Bit32s blah = mem_readd(addr); + FPU_PUSH( static_cast(blah)); + } + break; + case 0x01: /* FISTTP */ + LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub); + break; + + case 0x02: /* FIST */ + { Bitu top = FPU_GET_TOP(); + mem_writed(addr,static_cast(FROUND(fpu.regs[top].d))); + } + break; + case 0x03: /*FISTP */ + { Bitu top = FPU_GET_TOP(); + mem_writed(addr,static_cast(FROUND(fpu.regs[top].d))); + FPU_FPOP(); + } + break; + default: + LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub); + } } void FPU_ESC3_Normal(Bitu rm) { @@ -283,10 +443,9 @@ void FPU_ESC3_Normal(Bitu rm) { void FPU_ESC4_EA(Bitu rm,PhysPt addr) { /* REGULAR TREE WITH 64 BITS REALS ? double ? */ - E_Exit("how to load a double in esc 4 ea"); - //SEE ESC 0 EA -// double blah = mem_readd(addr); //wrong wrong wrong -// fpu.regs[8].d = static_cast(blah); +// E_Exit("how to load a double in esc 4 ea"); + fpu.regs[8].l.lower=mem_readd(addr); + fpu.regs[8].l.upper=mem_readd(addr+4); EATREE(rm); } @@ -302,9 +461,12 @@ void FPU_ESC4_Normal(Bitu rm) { case 0x01: /* FMULP STi,ST*/ FPU_FMUL((top+sub)&7,top); break; - case 0x02: /* FCOMP5*/ - case 0x03: /* weird*/ - LOG(LOG_FPU,LOG_WARN)("ESC 6:Unhandled group %d subfunction %d",group,sub); + case 0x02: /* FCOM*/ + FPU_FCOM(top,(top+sub)&7); + break; /* TODO IS THIS ALLRIGHT ????????? (maybe reverse operators) */ + case 0x03: /* FCOMP*/ + FPU_FCOM(top,(top+sub)&7); + FPU_FPOP(); break; case 0x04: /* FSUBRP STi,ST*/ FPU_FSUBR((top+sub)&7,top); @@ -323,17 +485,73 @@ void FPU_ESC4_Normal(Bitu rm) { } } - void FPU_ESC5_EA(Bitu rm,PhysPt addr) { Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); - LOG(LOG_FPU,LOG_WARN)("ESC EA 5:Unhandled group %d subfunction %d",group,sub); + switch(group){ + case 0x00: /* FLD */ + { + FPU_Reg blah; + blah.l.lower=mem_readd(addr); + blah.l.upper=mem_readd(addr+4); + FPU_PUSH(blah.d); + } + break; + case 0x01: /* FISTTP */ + LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub); + break; + + case 0x02: /* FIST */ + { Bitu top = FPU_GET_TOP(); + mem_writed(addr,fpu.regs[top].l.lower); + mem_writed(addr+4,fpu.regs[top].l.upper); + } + break; + case 0x03: /*FISTP */ + { Bitu top = FPU_GET_TOP(); + mem_writed(addr,fpu.regs[top].l.lower); + mem_writed(addr+4,fpu.regs[top].l.upper); + FPU_FPOP(); + } + break; + case 0x07: /*FNSTSW NG DISAGREES ON THIS*/ + mem_writew(addr,fpu.sw); + //seems to break all dos4gw games :) + break; + default: + LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub); + } } void FPU_ESC5_Normal(Bitu rm) { Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); + Bitu top = FPU_GET_TOP(); + switch(group){ + case 0x00: /* FFREE STi */ + fpu.tags[(top+sub)&7]=TAG_Empty; + break; + case 0x01: /* FXCH STi*/ + FPU_FXCH(top,(top+sub)&7); + break; + case 0x02: /* FST STi */ + FPU_FST(top,(top+sub)&7); + break; + case 0x03: /* FSTP STi*/ + FPU_FST(top,(top+sub)&7); + FPU_FPOP(); + break; + case 0x04: /* FUCOM STi */ + FPU_FUCOM(top,(top+sub)&7); + break; + case 0x05: + FPU_FUCOM(top,(top+sub)&7); + FPU_FPOP(); + break; + default: LOG(LOG_FPU,LOG_WARN)("ESC 5:Unhandled group %d subfunction %d",group,sub); + break; + } } @@ -358,9 +576,15 @@ void FPU_ESC6_Normal(Bitu rm) { FPU_FMUL((top+sub)&7,top); break; case 0x02: /* FCOMP5*/ - case 0x03: /* weird*/ + FPU_FCOM(top,(top+sub)&7); + break; /* TODO IS THIS ALLRIGHT ????????? */ + case 0x03: /* weird*/ /*FCOMPP*/ + if(sub != 1){ LOG(LOG_FPU,LOG_WARN)("ESC 6:Unhandled group %d subfunction %d",group,sub); - // maybe return and don't pop + break; + } + FPU_FCOM(top,(top+sub)&7); + FPU_FPOP(); break; case 0x04: /* FSUBRP STi,ST*/ FPU_FSUBR((top+sub)&7,top); @@ -382,17 +606,34 @@ void FPU_ESC6_Normal(Bitu rm) { void FPU_ESC7_EA(Bitu rm,PhysPt addr) { + /* ROUNDING*/ + Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); switch(group){ + case 0x00: /* FLD */ + { + Bit16s blah = mem_readw(addr); + FPU_PUSH( static_cast(blah)); + } + break; + case 0x01: /* FISTTP */ + LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); + break; + + case 0x02: /* FIST */ + { Bitu top = FPU_GET_TOP(); + mem_writew(addr,static_cast(FROUND(fpu.regs[top].d))); + } + break; case 0x03: /*FISTP */ { Bitu top = FPU_GET_TOP(); - mem_writew(addr,static_cast(fpu.regs[top].d)); + mem_writew(addr,static_cast(FROUND(fpu.regs[top].d))); FPU_FPOP(); } break; default: - LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub); + LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); } } @@ -406,13 +647,15 @@ void FPU_ESC7_Normal(Bitu rm) { reg_ax = fpu.sw; 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; } - LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub); + } diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index cf45b608..52d7e83e 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,8 +17,9 @@ */ + static void FPU_FINIT(void) { - FPU_SetCW(0x37); + FPU_SetCW(0x37F); fpu.sw=0; fpu.tags[0]=TAG_Empty; fpu.tags[1]=TAG_Empty; @@ -28,6 +29,7 @@ static void FPU_FINIT(void) { fpu.tags[5]=TAG_Empty; fpu.tags[6]=TAG_Empty; fpu.tags[7]=TAG_Empty; + fpu.tags[8]=TAG_Valid; // is only used by us } static void FPU_FCLEX(void){ fpu.sw&=0x7f00; //should clear exceptions @@ -70,6 +72,7 @@ static void FPU_FADD(Bitu op1, Bitu op2){ static void FPU_FSIN(void){ Bitu top = FPU_GET_TOP(); fpu.regs[top].d = sin(fpu.regs[top].d); + FPU_SET_C2(0); //flags and such :) return; } @@ -80,6 +83,7 @@ static void FPU_FSINCOS(void){ double temp = sin(fpu.regs[top].d); FPU_PUSH(cos(fpu.regs[top].d)); fpu.regs[top].d = temp; + FPU_SET_C2(0); //flags and such :) return; } @@ -87,10 +91,31 @@ static void FPU_FSINCOS(void){ static void FPU_FCOS(void){ Bitu top = FPU_GET_TOP(); fpu.regs[top].d = cos(fpu.regs[top].d); + FPU_SET_C2(0); //flags and such :) return; } +static void FPU_FSQRT(void){ + Bitu top = FPU_GET_TOP(); + fpu.regs[top].d = sqrt(fpu.regs[top].d); + //flags and such :) + return; +} +static void FPU_FPATAN(void){ + Bitu top = FPU_GET_TOP(); + fpu.regs[top].d = atan(fpu.regs[top].d); + FPU_SET_C2(0); + //flags and such :) + return; +} +static void FPU_FPTAN(void){ + Bitu top = FPU_GET_TOP(); + fpu.regs[top].d = tan(fpu.regs[top].d); + FPU_SET_C2(0); + //flags and such :) + return; +} static void FPU_FDIV(Bitu st, Bitu other){ fpu.regs[st].d= fpu.regs[st].d/fpu.regs[other].d; //flags and such :) @@ -119,4 +144,59 @@ static void FPU_FSUBR(Bitu st, Bitu other){ fpu.regs[st].d= fpu.regs[other].d - fpu.regs[st].d; //flags and such :) return; -} \ No newline at end of file +} + +static void FPU_FXCH(Bitu st, Bitu other){ + FPU_Tag tag = fpu.tags[other]; + FPU_Reg reg = fpu.regs[other]; + fpu.tags[other] = fpu.tags[st]; + fpu.regs[other] = fpu.regs[st]; + fpu.tags[st] = tag; + fpu.regs[st] = reg; +} + +static void FPU_FST(Bitu st, Bitu other){ + fpu.tags[other] = fpu.tags[st]; + fpu.regs[other] = fpu.regs[st]; +} + + + +static void FPU_FCOM(Bitu st, Bitu other){ + if((fpu.tags[st] != TAG_Valid) || (fpu.tags[other] != TAG_Valid)){ + FPU_SET_C3(1);FPU_SET_C2(1);FPU_SET_C0(1);return; + } + if(fpu.regs[st].d == fpu.regs[other].d){ + FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(0);return; + } + if(fpu.regs[st].d < fpu.regs[other].d){ + FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C0(1);return; + } + // st > other + FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C0(0);return; +} + +static void FPU_FUCOM(Bitu st, Bitu other){ + //does atm the same as fcom + FPU_FCOM(st,other); +} + +static double FROUND(double in){ + switch(fpu.round){ + case ROUND_Nearest: + return((in-floor(in)>=0.5)?(floor(in)+1):(floor(in))); + break; + case ROUND_Down: + return (floor(in)); + break; + case ROUND_Up: + return (ceil(in)); + break; + case ROUND_Chop: + return in; //the cast afterwards will do it right maybe cast here + break; + default: + return in; + break; + } +} diff --git a/src/fpu/fpu_types.h b/src/fpu/fpu_types.h index b7cb434b..33bc9e7b 100644 --- a/src/fpu/fpu_types.h +++ b/src/fpu/fpu_types.h @@ -32,10 +32,10 @@ enum FPU_Tag { enum FPU_Round { - ROUND_Nearest = 0, + ROUND_Nearest = 0, ROUND_Down = 1, - ROUND_Up = 2, + ROUND_Up = 2, ROUND_Chop = 3 }; //get pi from a real library -#define PI 3.1415926535 \ No newline at end of file +#define PI 3.14159265358979323846 \ No newline at end of file From 6f9016c8eb2e626ed71d9704193670dffcaaa1d7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 10 Jun 2003 08:50:28 +0000 Subject: [PATCH 0966/4131] Added 32-bit BSF and BSR Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1046 --- src/cpu/core_full/op.h | 26 ++++++++++++++++++++++++++ src/cpu/core_full/optable.h | 2 +- src/cpu/core_full/support.h | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 26057cb6..29f9bc44 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -496,6 +496,19 @@ switch (inst.code.op) { SETFLAGBIT(ZF,false); } break; + case O_BSFd: + { + FILLFLAGS; + if (!inst.op1.d) SETFLAGBIT(ZF,true); + Bitu count=0; + while (count<32) { + if ((inst.op1.d>>count) & 1) break; + count++; + } + inst.op1.d=count; + SETFLAGBIT(ZF,false); + } + break; case O_BSRw: { FILLFLAGS; @@ -509,6 +522,19 @@ switch (inst.code.op) { SETFLAGBIT(ZF,false); } break; + case O_BSRd: + { + FILLFLAGS; + if (!inst.op1.d) SETFLAGBIT(ZF,true); + Bits count=31; + while (count>0) { + if ((inst.op1.d>>count) & 1) break; + count--; + } + inst.op1.d=count; + SETFLAGBIT(ZF,false); + } + break; case O_BTw: case O_BTSw: case O_BTCw: diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 367d46f7..bc6c9908 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -668,7 +668,7 @@ static OpCode OpCodeTable[1024]={ /* 0x3b8 - 0x3bf */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {L_MODRM ,0xf ,0 ,M_GRP },{L_MODRM ,O_BTCd ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_BSFd ,S_Gd ,M_Ed },{L_MODRM ,O_BSRd ,S_Gd ,M_Ed }, {L_MODRM ,0 ,S_Gd ,M_Ebx },{L_MODRM ,0 ,S_Gd ,M_Ewx }, /* 0x3c0 - 0x3cc */ diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 2d2477de..b5a40f59 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -87,7 +87,7 @@ enum { O_BTw,O_BTSw,O_BTRw,O_BTCw, O_BTd,O_BTSd,O_BTRd,O_BTCd, - O_BSFw,O_BSRw, + O_BSFw,O_BSRw,O_BSFd,O_BSRd, O_BSWAP, O_FPU, From 3ea9d2e62ac9802f1afc9b4d308ca4b4c67b94a5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 10 Jun 2003 08:52:16 +0000 Subject: [PATCH 0967/4131] Added more constants to be loaded through FLDxx Added 32-bit FILD and FISTP Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1047 --- src/fpu/fpu.cpp | 29 +++++++++++++++++++++++------ src/fpu/fpu_types.h | 6 +++++- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 361af493..636b2f45 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -298,15 +298,20 @@ void FPU_ESC1_Normal(Bitu rm) { FPU_PUSH(1.0); break; case 0x01: /* FLDL2T */ + FPU_PUSH(L2T); + break; case 0x02: /* FLDL2E */ - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); + FPU_PUSH(L2E); break; case 0x03: /* FLDPI */ FPU_PUSH(PI); break; case 0x04: /* FLDLG2 */ + FPU_PUSH(LG2); + break; case 0x05: /* FLDLN2 */ - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); + FPU_PUSH(LN2); + break; case 0x06: /* FLDZ*/ FPU_PUSH_ZERO(); break; @@ -611,27 +616,39 @@ void FPU_ESC7_EA(Bitu rm,PhysPt addr) { Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); switch(group){ - case 0x00: /* FLD */ + case 0x00: /* FILD Bit16s */ { Bit16s blah = mem_readw(addr); FPU_PUSH( static_cast(blah)); } break; - case 0x01: /* FISTTP */ + case 0x01: /* FISTTP Bit16s */ LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); break; - case 0x02: /* FIST */ + case 0x02: /* FIST Bit16s */ { Bitu top = FPU_GET_TOP(); mem_writew(addr,static_cast(FROUND(fpu.regs[top].d))); } break; - case 0x03: /*FISTP */ + case 0x03: /* FISTP Bit16s */ { Bitu top = FPU_GET_TOP(); mem_writew(addr,static_cast(FROUND(fpu.regs[top].d))); FPU_FPOP(); } break; + case 0x05: /* FILD Bit32s */ + { + Bit32s blah = mem_readd(addr); + FPU_PUSH( static_cast(blah)); + } + break; + case 0x07: /* FISTP Bit32s */ + { Bitu top = FPU_GET_TOP(); + mem_writed(addr,static_cast(FROUND(fpu.regs[top].d))); + FPU_FPOP(); + } + break; default: LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); } diff --git a/src/fpu/fpu_types.h b/src/fpu/fpu_types.h index 33bc9e7b..44260e13 100644 --- a/src/fpu/fpu_types.h +++ b/src/fpu/fpu_types.h @@ -38,4 +38,8 @@ enum FPU_Round { ROUND_Chop = 3 }; //get pi from a real library -#define PI 3.14159265358979323846 \ No newline at end of file +#define PI 3.14159265358979323846 +#define L2E 1.4426950408889634 +#define L2T 3.3219280948873623 +#define LN2 0.69314718055994531 +#define LG2 0.3010299956639812 \ No newline at end of file From 25a243ed74e6a8aa1e8d192146ad98a6c0bbe24c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 10 Jun 2003 11:41:17 +0000 Subject: [PATCH 0968/4131] Check if files are withing MAX_FILES limits Added buffers to lists of lists. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1048 --- src/dos/dos_classes.cpp | 8 +++++++- src/dos/dos_tables.cpp | 4 +++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 6f622b3e..31283fde 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -73,6 +73,12 @@ void DOS_InfoBlock::SetfirstFileTable(RealPt _first_table){ sSave(sDIB,firstFileTable,_first_table); } +void DOS_InfoBlock::SetBuffers(Bit16u x,Bit16u y) { + sSave(sDIB,buffers_x,x); + sSave(sDIB,buffers_y,y); + +} + RealPt DOS_InfoBlock::GetPointer(void) { return RealMake(seg,offsetof(sDIB,firstDPB)); @@ -164,7 +170,7 @@ void DOS_PSP::CopyFileTable(DOS_PSP* srcpsp,bool createchildpsp) if(createchildpsp) { //copy obeying not inherit flag.(but dont duplicate them) bool allowCopy = (handle==0) || ((handle>0) && (FindEntryByHandle(handle)==0xff)); - if(Files[handle] && !(Files[handle]->flags & DOS_NOT_INHERIT) && allowCopy) + if((handleflags & DOS_NOT_INHERIT) && allowCopy) { SetFileHandle(i,handle); } diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 8332e17e..e9035193 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -55,12 +55,14 @@ void DOS_SetupTables(void) { for (i=0;i Date: Tue, 10 Jun 2003 11:42:23 +0000 Subject: [PATCH 0969/4131] Added buffers to DosInfoBlock Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1049 --- include/dos_inc.h | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 8bee9a96..d1434346 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -337,22 +337,26 @@ public: void SetLocation(Bit16u seg); void SetFirstMCB(Bit16u _first_mcb); void SetfirstFileTable(RealPt _first_table); + void SetBuffers(Bit16u x,Bit16u y); RealPt GetPointer (void); -private: + #ifdef _MSC_VER #pragma pack(1) #endif struct sDIB { - Bit8u stuff1[22]; // some stuff, hopefully never used.... - Bit16u firstMCB; // first memory control block - RealPt firstDPB; // first drive parameter block - RealPt firstFileTable; // first system file table - RealPt activeClock; // active clock device header - RealPt activeCon; // active console device header - Bit16u maxSectorLength; // maximum bytes per sector of any block device; - RealPt discInfoBuffer; // pointer to disc info buffer - RealPt curDirStructure; // pointer to current array of directory structure - RealPt fcbTable; // pointer to system FCB table + Bit8u stuff1[22]; // -0x18 some stuff, hopefully never used.... + Bit16u firstMCB; // -0x2 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 discInfoBuffer; // 0x12 pointer to disc info buffer + RealPt curDirStructure; // 0x16 pointer to current array of directory structure + RealPt fcbTable; // 0x1a pointer to system FCB table + Bit8u stuff2[0x21]; // 0x1e more stuff + Bit16u buffers_x; // x in BUFFERS x,y + Bit16u buffers_y; // y in BUFFERS x,y // some more stuff, hopefully never used. } GCC_ATTRIBUTE(packed); #ifdef _MSC_VER From 6daab43bf7dcf6ecf7f14da0b62c46850c06e42c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 10 Jun 2003 21:09:12 +0000 Subject: [PATCH 0970/4131] fixed both fptan and fpatan. Xcom now works flawsless Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1050 --- src/fpu/fpu_instructions.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 52d7e83e..d5953d30 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -104,7 +104,8 @@ static void FPU_FSQRT(void){ } static void FPU_FPATAN(void){ Bitu top = FPU_GET_TOP(); - fpu.regs[top].d = atan(fpu.regs[top].d); + fpu.regs[(top+1)&7].d = atan(fpu.regs[(top+1)&7].d/fpu.regs[top].d); + FPU_FPOP(); FPU_SET_C2(0); //flags and such :) return; @@ -112,6 +113,7 @@ static void FPU_FPATAN(void){ static void FPU_FPTAN(void){ Bitu top = FPU_GET_TOP(); fpu.regs[top].d = tan(fpu.regs[top].d); + FPU_PUSH(1.0); FPU_SET_C2(0); //flags and such :) return; From bb45fd24d7907777b63618ed03ac8f9bd3fa4869 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 12 Jun 2003 12:03:59 +0000 Subject: [PATCH 0971/4131] Fix for 32-bit mov [offset],segment doing 32-bit store, should be 16. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1051 --- src/cpu/core_full/op.h | 10 ++++++++++ src/cpu/core_full/optable.h | 5 ++--- src/cpu/core_full/save.h | 4 ++++ src/cpu/core_full/support.h | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 29f9bc44..0adb0a64 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -616,6 +616,16 @@ switch (inst.code.op) { LOG(LOG_CPU,LOG_ERROR)("Unhandled FPU ESCAPE %d",inst.code.save); goto nextopcode; #endif + case O_BOUNDw: + { + Bit16s bound_min, bound_max; + bound_min=LoadMw(inst.rm_eaa); + bound_max=LoadMw(inst.rm_eaa+2); + if ( (((Bit16s)inst.op1.w) < bound_min) || (((Bit16s)inst.op1.w) > bound_max) ) { + EXCEPTION(5); + } + } + break; case 0: break; default: diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index bc6c9908..b74bbc9f 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -69,7 +69,7 @@ static OpCode OpCodeTable[1024]={ /* 0x60 - 0x67 */ {D_PUSHAw ,0 ,0 ,0 },{D_POPAw ,0 ,0 ,0 }, -{L_MODRM ,O_BOUNDw ,0 ,0 },{L_MODRM ,O_ARPL ,S_Ew ,M_EwGw }, +{L_MODRM ,O_BOUNDw ,0 ,M_Gw },{L_MODRM ,O_ARPL ,S_Ew ,M_EwGw }, {L_PRESEG ,0 ,0 ,fs },{L_PRESEG ,0 ,0 ,gs }, {L_PREOP ,0 ,0 ,0 },{L_PREADD ,0 ,0 ,0 }, /* 0x68 - 0x6f */ @@ -455,8 +455,7 @@ static OpCode OpCodeTable[1024]={ /* 0x288 - 0x28f */ {L_MODRM ,0 ,S_Eb ,M_Gb },{L_MODRM ,0 ,S_Ed ,M_Gd }, {L_MODRM ,0 ,S_Gb ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ed }, -//TODO Check if the saving a segment in 32bit reg does zero extension? -{L_MODRM ,0 ,S_Ed ,M_SEG },{L_MODRM ,0 ,S_Gd ,M_EA }, +{L_MODRM ,0 ,S_EdMw ,M_SEG },{L_MODRM ,0 ,S_Gd ,M_EA }, {L_MODRM ,0 ,S_SEGm ,M_Ew },{L_MODRM ,0 ,S_Ed ,M_POPd }, /* 0x290 - 0x297 */ diff --git a/src/cpu/core_full/save.h b/src/cpu/core_full/save.h index 0f7f4fe4..6c8f9c55 100644 --- a/src/cpu/core_full/save.h +++ b/src/cpu/core_full/save.h @@ -33,6 +33,10 @@ switch (inst.code.save) { if (inst.rm<0xc0) SaveMd(inst.rm_eaa,inst.op1.d); else reg_32(inst.rm_eai)=inst.op1.d; break; + case S_EdMw: /* Special one 16 to memory, 32 zero extend to reg */ + if (inst.rm<0xc0) SaveMw(inst.rm_eaa,inst.op1.w); + else reg_32(inst.rm_eai)=inst.op1.d; + break; case S_Gd: reg_32(inst.rm_index)=inst.op1.d; break; diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index b5a40f59..df35dc4f 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -100,7 +100,7 @@ enum { S_C_Eb, S_Eb,S_Gb,S_EbGb, S_Ew,S_Gw,S_EwGw, - S_Ed,S_Gd,S_EdGd, + S_Ed,S_Gd,S_EdGd,S_EdMw, S_REGb,S_REGw,S_REGd, From 94ea572dc16b9360b12c0a3248ee64e92ab220dd Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 12 Jun 2003 13:01:12 +0000 Subject: [PATCH 0972/4131] Added real mode iretd Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1052 --- src/cpu/cpu.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index f82c064f..7a29579d 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -260,7 +260,9 @@ bool Interrupt(Bitu num) { bool CPU_IRET(bool use32) { if (!(cpu.state & STATE_PROTECTED)) { /*RealMode IRET */ if (use32) { - E_Exit("No support for IRETD in real mode"); + reg_eip=CPU_Pop32(); + SegSet16(cs,CPU_Pop32()); + SETFLAGSw(CPU_Pop32()); } else { reg_eip=CPU_Pop16(); SegSet16(cs,CPU_Pop16()); From 5794ebcb0eeb88149d084dcdbab8116ecfec0b65 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 14 Jun 2003 07:24:17 +0000 Subject: [PATCH 0973/4131] Added HLT instruction Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1053 --- include/cpu.h | 5 ++++- src/cpu/core_full/load.h | 4 ++++ src/cpu/core_full/optable.h | 2 +- src/cpu/core_full/support.h | 1 + 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 5dbfe745..b2036e46 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -103,7 +103,7 @@ bool CPU_IRET(bool use32); bool CPU_SetSegGeneral(SegNames seg,Bitu value); void CPU_CPUID(void); - +void CPU_HLT(void); //Flag Handling Bitu get_CF(void); @@ -386,6 +386,9 @@ struct CPUBlock { struct { Bitu prefix,entry; } full; + struct { + Bitu eip,cs; + } hlt; }; extern CPUBlock cpu; diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index f90180fc..9636a499 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -469,6 +469,10 @@ l_M_Ed: case D_CPUID: CPU_CPUID(); goto nextopcode; + case D_HLT: + SaveIP(); + CPU_HLT(); + return 0x0; default: LOG(LOG_CPU,LOG_ERROR)("LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry); break; diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index b74bbc9f..116fb3c9 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -172,7 +172,7 @@ static OpCode OpCodeTable[1024]={ /* 0xf0 - 0xf7 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {L_PREREPNE ,0 ,0 ,0 },{L_PREREP ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{D_CMC ,0 ,0 ,0 }, +{D_HLT ,0 ,0 ,0 },{D_CMC ,0 ,0 ,0 }, {L_MODRM ,8 ,0 ,M_GRP },{L_MODRM ,9 ,0 ,M_GRP }, /* 0xf8 - 0xff */ {D_CLC ,0 ,0 ,0 },{D_STC ,0 ,0 ,0 }, diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index df35dc4f..6aa563bf 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -44,6 +44,7 @@ enum { D_RETFw,D_RETFd, D_RETFwIw,D_RETFdIw, D_CPUID, + D_HLT, }; From 019442ad4e4fda6659345cf522a874ea33833a28 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 14 Jun 2003 07:26:53 +0000 Subject: [PATCH 0974/4131] Added HLT Instruction Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1054 --- src/cpu/core_16/main.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 44538829..662f8964 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -946,7 +946,7 @@ restart: break; case 0xed: /* IN AX,DX */ reg_al=IO_Read(reg_dx); - reg_ah=IO_Read(reg_dx+1); + reg_ah=IO_Read(reg_dx+1); break; case 0xee: /* OUT DX,AL */ IO_Write(reg_dx,reg_al); @@ -969,7 +969,9 @@ restart: Repeat_Normal(true,false); continue; case 0xf4: /* HLT */ - break; + SAVEIP; + CPU_HLT(); + return 0x0; case 0xf5: /* CMC */ SETFLAGBIT(CF,!get_CF()); if (flags.type!=t_CF) flags.prev_type=flags.type; @@ -1113,7 +1115,9 @@ restart: case CBRET_NONE: LOADIP; break; - case CBRET_STOP:return ret; + case CBRET_STOP: + //TODO Maybe save flags at some time + return ret; default: E_Exit("CPU:Callback %d returned illegal %d code",call,ret); }; From 4d45092d8766342fd3c53498d0ca9e3fb766ef4d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 14 Jun 2003 07:27:27 +0000 Subject: [PATCH 0975/4131] Added HLT Instruction handling routines. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1055 --- src/cpu/cpu.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 7a29579d..050db6a4 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -791,8 +791,24 @@ void CPU_CPUID(void) { } -void CPU_Real_16_Slow_Start(void); -void CPU_Core_Full_Start(void); +static Bitu HLT_Decode(void) { + /* Stay here just as long until an external interrupt has changed CS:EIP */ + if ((reg_eip!=cpu.hlt.eip) || (SegValue(cs)!=cpu.hlt.cs)) { + cpu.state=0xff; //force a new state to set decoder + CPU_CheckState(); + return 0x0; + } + CPU_Cycles=0; + return 0x0; +} + +void CPU_HLT(void) { + cpu.hlt.cs=SegValue(cs); + cpu.hlt.eip=reg_eip; + CPU_Cycles=0; + cpudecoder=&HLT_Decode; +} + static void CPU_CycleIncrease(void) { Bitu old_cycles=CPU_CycleMax; From 34eb272f957dc1e0c182a33c1e34b562e19d1252 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 14 Jun 2003 11:42:45 +0000 Subject: [PATCH 0976/4131] Changed memory limits Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1056 --- include/mem.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/include/mem.h b/include/mem.h index 12a316e7..b459ef32 100644 --- a/include/mem.h +++ b/include/mem.h @@ -33,12 +33,11 @@ typedef void (*MEMORY_WriteHandler)(PhysPt pt,Bit8u val); #define PAGE_SIZE (PAGE_KB*1024) #define PAGE_SHIFT 14 #define PAGE_COUNT(A) (A & ((1 << PAGE_SHIFT)-1) ? 1+(A >> PAGE_SHIFT) : (A >> PAGE_SHIFT) ) -#define MAX_PAGES PAGE_COUNT(C_MEM_MAX_SIZE*1024*1024) -extern HostPt ReadHostTable[MAX_PAGES]; -extern HostPt WriteHostTable[MAX_PAGES]; -extern MEMORY_ReadHandler ReadHandlerTable[MAX_PAGES]; -extern MEMORY_WriteHandler WriteHandlerTable[MAX_PAGES]; +extern HostPt ReadHostTable[]; +extern HostPt WriteHostTable[]; +extern MEMORY_ReadHandler ReadHandlerTable[]; +extern MEMORY_WriteHandler WriteHandlerTable[]; INLINE Bit16u PAGES(Bit32u bytes) { From 81a149ea36971b0954ed6d6d2f6bcd38707ea353 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 14 Jun 2003 11:44:02 +0000 Subject: [PATCH 0977/4131] Better limit checking on memory allocated to XMS Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1057 --- src/ints/xms.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 6db3f299..3701b563 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -363,7 +363,7 @@ static bool multiplex_xms(void) { }; Bitu XMS_Handler(void) { - LOG(LOG_MISC,LOG_ERROR)("XMS: CALL %02X",reg_ah); +// LOG(LOG_MISC,LOG_ERROR)("XMS: CALL %02X",reg_ah); switch (reg_ah) { case XMS_GET_VERSION: /* 00 */ @@ -443,7 +443,7 @@ Bitu XMS_Handler(void) { break; } - LOG(LOG_MISC,LOG_ERROR)("XMS: CALL Result: %02X",reg_bl); +// LOG(LOG_MISC,LOG_ERROR)("XMS: CALL Result: %02X",reg_bl); return CBRET_NONE; } @@ -451,7 +451,9 @@ void XMS_Init(Section* sec) { Section_prop * section=static_cast(sec); Bitu size=section->Get_int("xmssize"); if (!size) return; - if (size>C_MEM_MAX_SIZE-1) size=C_MEM_MAX_SIZE-1; + Bitu memavail=(MEM_TotalSize()-1088)/1024; + + if (size>memavail) size=memavail; xms_size = size; DOS_AddMultiplexHandler(multiplex_xms); call_xms=CALLBACK_Allocate(); From a8cce43b4f1f6dc893a5a044300f2bbd8e64ed7d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 14 Jun 2003 11:45:40 +0000 Subject: [PATCH 0978/4131] Maximum of 34mb addressable memory now with highest 2mb being video memory range. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1058 --- src/hardware/memory.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 4fa22ce5..6e38b63c 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -25,6 +25,12 @@ #include "inout.h" #include "setup.h" +/* Maximum memory address range in megabytes */ +#define MEM_SIZE 32 +#define MAX_PAGES PAGE_COUNT((2+MEM_SIZE)*1024*1024) + + + HostPt memory; HostPt ReadHostTable[MAX_PAGES]; HostPt WriteHostTable[MAX_PAGES]; @@ -34,8 +40,6 @@ MEMORY_WriteHandler WriteHandlerTable[MAX_PAGES]; static Bitu total_size; /* Page handlers only work in lower memory */ -#define LOW_PAGE_LIMIT PAGE_COUNT(1024*1024) -#define MAX_PAGE_LIMIT PAGE_COUNT(C_MEM_MAX_SIZE*1024*1024) void MEM_BlockRead(PhysPt off,void * data,Bitu size) { Bit8u * idata=(Bit8u *)data; @@ -110,7 +114,7 @@ static void Default_WriteHandler(PhysPt pt,Bit8u val) { void MEM_SetupPageHandlers(Bitu startpage,Bitu pages,MEMORY_ReadHandler read,MEMORY_WriteHandler write) { - if (startpage+pages>MAX_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); + if (startpage+pages>MAX_PAGES) E_Exit("Memory:Illegal page for handler"); for (Bitu i=startpage;iMAX_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); + if (startpage+pages>MAX_PAGES) E_Exit("Memory:Illegal page for handler"); for (Bitu i=startpage;iMAX_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); + if (startpage+pages>MAX_PAGES) E_Exit("Memory:Illegal page for handler"); HostPt base=(HostPt)(data)-startpage*PAGE_SIZE; if (!base) LOG_MSG("MEMORY:Unlucky memory allocation"); for (Bitu i=startpage;iMAX_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); + if (startpage+pages>MAX_PAGES) E_Exit("Memory:Illegal page for handler"); for (Bitu i=startpage;i(sec); /* Clear paging tables */ - MEM_SetupPageHandlers(0,MAX_PAGE_LIMIT,Illegal_ReadHandler,Illegal_WriteHandler); + MEM_SetupPageHandlers(0,MAX_PAGES,Illegal_ReadHandler,Illegal_WriteHandler); /* Allocate memory and setup tables */ Bitu memsize=section->Get_int("memsize"); if (memsize<1) memsize=1; - if (memsize>(C_MEM_MAX_SIZE-1)) { - LOG_MSG("Maximum memory size is %d MB",C_MEM_MAX_SIZE-1); - memsize=C_MEM_MAX_SIZE-1; + if (memsize>MEM_SIZE) { + LOG_MSG("Maximum memory size is %d MB",MEM_SIZE); + memsize=MEM_SIZE; } total_size=memsize*1024; memory=(Bit8u *)malloc(memsize*1024*1024+64*1024); From 1b4b7cb77b2f8ed3d2948bceada3e7ff546f0b45 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 15 Jun 2003 19:34:33 +0000 Subject: [PATCH 0979/4131] New function to be called when videomode changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1059 --- include/mouse.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mouse.h b/include/mouse.h index 0123ecbe..07fce5a6 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -26,5 +26,5 @@ void Mouse_ButtonPressed(Bit8u button); void Mouse_ButtonReleased(Bit8u button); void Mouse_AutoLock(bool enable); -void Mouse_SetResolution(Bit16u width, Bit16u height); +void Mouse_NewVideoMode(void); From 155cbb9f3613f9e4953ef9146bdd1ba1300f52b9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 15 Jun 2003 19:37:57 +0000 Subject: [PATCH 0980/4131] New Video bios code: Support for VESA 1.2 Support for text mode font changes Support for setting CGA colors Support for setting text mode cursor shape Support for 16 color palette group changes Some initial tandy mode support Some fixes with graphics mode text output Some cleanups Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1060 --- src/ints/int10.cpp | 195 +++++++-- src/ints/int10.h | 133 +++--- src/ints/int10_char.cpp | 241 ++++++----- src/ints/int10_memory.cpp | 63 ++- src/ints/int10_misc.cpp | 28 +- src/ints/int10_modes.cpp | 755 ++++++++++++++++++++--------------- src/ints/int10_pal.cpp | 54 ++- src/ints/int10_put_pixel.cpp | 38 +- 8 files changed, 921 insertions(+), 586 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 0554cf69..410fb176 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -27,31 +27,42 @@ #include "int10.h" #include "../hardware/vga.h" /* Maybe move this thing */ -#define TEXT_SEG 0xb800 - +Int10Data int10; static Bitu call_10; static bool warned_ff=false; -static bool warned_int10_0b=false; -Int10Data int10; - static Bitu INT10_Handler(void) { +#if 0 + switch (reg_ah) { + case 0x02: + case 0x03: + case 0x09: + case 0xc: + case 0xd: + case 0x0e: + case 0x10: + case 0x4f: + break; + default: + LOG(LOG_INT10,LOG_NORMAL)("Function AX:%04X , BX %04X",reg_ax,reg_bx); + break; + } +#endif switch (reg_ah) { case 0x00: /* Set VideoMode */ INT10_SetVideoMode(reg_al); break; case 0x01: /* Set TextMode Cursor Shape */ - vga.internal.cursor=reg_cx; // maybe write some memory somewhere - LOG(LOG_INT10,LOG_NORMAL)("INT10:01:Set textmode cursor shape partially supported: %X",reg_cx); + INT10_SetCursorShape(reg_ch,reg_cl); break; case 0x02: /* Set Cursor Pos */ - //TODO Check some shit but not really usefull INT10_SetCursorPos(reg_dh,reg_dl,reg_bh); break; case 0x03: /* get Cursor Pos and Cursor Shape*/ - //TODO the Cursor Shape Stuff + reg_ah=0; reg_dl=CURSOR_POS_COL(reg_bh); reg_dh=CURSOR_POS_ROW(reg_bh); + reg_cx=real_readw(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE); break; case 0x04: /* read light pen pos YEAH RIGHT */ /* Light pen is not supported */ @@ -62,15 +73,12 @@ static Bitu INT10_Handler(void) { else INT10_SetActivePage(reg_al); break; case 0x06: /* Scroll Up */ -//TODO Graphics mode scroll INT10_ScrollWindow(reg_ch,reg_cl,reg_dh,reg_dl,-reg_al,reg_bh,0xFF); break; - case 0x07: - /* Scroll Down */ + case 0x07: /* Scroll Down */ INT10_ScrollWindow(reg_ch,reg_cl,reg_dh,reg_dl,reg_al,reg_bh,0xFF); break; case 0x08: /* Read character & attribute at cursor */ -//TODO Check for GRAPH and then just return INT10_ReadCharAttr(®_ax,reg_bh); break; case 0x09: /* Write Character & Attribute at cursor CX times */ @@ -80,10 +88,14 @@ static Bitu INT10_Handler(void) { INT10_WriteChar(reg_al,reg_bl,reg_bh,reg_cx,false); break; case 0x0B: /* Set Background/Border Colour & Set Palette*/ - if(!warned_int10_0b) { - LOG(LOG_INT10,LOG_ERROR)("Function 0B Unsupported: Set Background/border colour & Set Pallete"); - warned_int10_0b=true; - } + switch (reg_bh) { + case 0x00: //Background/Border color + INT10_SetBackgroundBorder(reg_bl); + break; + case 0x01: //Set color Select + INT10_SetColorSelect(reg_bl); + break; + } break; case 0x0C: /* Write Graphics Pixel */ INT10_PutPixel(reg_cx,reg_dx,reg_bh,reg_al); @@ -128,18 +140,68 @@ static Bitu INT10_Handler(void) { case 0x12: /* SET BLOCK OF DAC REGISTERS */ INT10_SetDACBlock(reg_bx,reg_cx,SegPhys(es)+reg_dx); break; + case 0x13: /* SELECT VIDEO DAC COLOR PAGE */ + INT10_SelectDACPage(reg_bl,reg_bh); + break; case 0x15: /* GET INDIVIDUAL DAC REGISTER */ INT10_GetSingleDacRegister(reg_bl,®_dh,®_ch,®_cl); break; case 0x17: /* GET BLOCK OF DAC REGISTER */ INT10_GetDACBlock(reg_bx,reg_cx,SegPhys(es)+reg_dx); break; + case 0x18: /* undocumented - SET PEL MASK */ + INT10_SetPelMask(reg_bl); + break; + case 0x19: /* undocumented - GET PEL MASK */ + INT10_GetPelMask(reg_bl); + break; default: LOG(LOG_INT10,LOG_ERROR)("Function 10:Unhandled EGA/VGA Palette Function %2X",reg_al); } break; case 0x11: /* Character generator functions */ switch (reg_al) { +/* Textmode calls */ + case 0x00: /* Load user font */ + case 0x10: + INT10_LoadFont(SegPhys(es)+reg_bp,reg_al==0x10,reg_cx,reg_dx,reg_bl,reg_bh); + break; + case 0x01: /* Load 8x14 font */ + case 0x11: + INT10_LoadFont(Real2Phys(int10.rom.font_14),true,256,0,0,14); + break; + case 0x02: /* Load 8x8 font */ + case 0x12: + INT10_LoadFont(Real2Phys(int10.rom.font_8_first),true,256,0,0,8); + break; +/* Graphics mode calls */ + case 0x20: /* Set User 8x8 Graphics characters */ + RealSetVec(0x1f,RealMake(SegValue(es),reg_bp)); + break; + case 0x21: /* Set user graphics characters */ + RealSetVec(0x43,RealMake(SegValue(es),reg_bp)); + real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,reg_cx); + goto graphics_chars; + case 0x22: /* Rom 8x14 set */ + RealSetVec(0x43,int10.rom.font_14); + real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,14); + goto graphics_chars; +// case 0x23: /* Rom 8x8 double dot set */ + //TODO + case 0x24: /* Rom 8x16 set */ + RealSetVec(0x43,int10.rom.font_16); + real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,16); + goto graphics_chars; +graphics_chars: + switch (reg_bl) { + case 0x00:real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,reg_dl-1);break; + case 0x01:real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,13);break; + case 0x03:real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,42);break; + case 0x02: + default:real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,24);break; + } + break; +/* General */ case 0x30:/* Get Font Information */ switch (reg_bh) { case 0x00: /* interupt 0x1f vector */ @@ -159,23 +221,23 @@ static Bitu INT10_Handler(void) { } break; case 0x02: /* font 8x14 */ - SegSet16(es,RealSeg(int10_romarea.font_14)); - reg_bp=RealOff(int10_romarea.font_14); + SegSet16(es,RealSeg(int10.rom.font_14)); + reg_bp=RealOff(int10.rom.font_14); reg_cx=14; break; case 0x03: /* font 8x8 first 128 */ - SegSet16(es,RealSeg(int10_romarea.font_8_first)); - reg_bp=RealOff(int10_romarea.font_8_first); + SegSet16(es,RealSeg(int10.rom.font_8_first)); + reg_bp=RealOff(int10.rom.font_8_first); reg_cx=8; break; case 0x04: /* font 8x8 second 128 */ - SegSet16(es,RealSeg(int10_romarea.font_8_second)); - reg_bp=RealOff(int10_romarea.font_8_second); + SegSet16(es,RealSeg(int10.rom.font_8_second)); + reg_bp=RealOff(int10.rom.font_8_second); reg_cx=8; break; case 0x06: /* font 8x16 */ - SegSet16(es,RealSeg(int10_romarea.font_16)); - reg_bp=RealOff(int10_romarea.font_16); + SegSet16(es,RealSeg(int10.rom.font_16)); + reg_bp=RealOff(int10.rom.font_16); reg_cx=16; break; default: @@ -197,8 +259,16 @@ static Bitu INT10_Handler(void) { reg_cx=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES) & 0x0F; break; } + case 0x36: /* VGA Refresh control */ + /* + Call disables/enables the vga from outputting video, + don't support it, but fake a success return + */ + reg_al=0x12; + break; default: LOG(LOG_INT10,LOG_ERROR)("Function 12:Call %2X not handled",reg_bl); + reg_al=0x12; //Always fake a success call } break; case 0x13: /* Write String */ @@ -223,7 +293,76 @@ static Bitu INT10_Handler(void) { reg_al=0x1B; break; default: - LOG(LOG_INT10,LOG_ERROR)("Function 1B:Unhandled call BX %2X",reg_bx); + LOG(LOG_INT10,LOG_ERROR)("1B:Unhandled call BX %2X",reg_bx); + } + break; + case 0x4f: /* VESA Calls */ + switch (reg_al) { + case 0x00: /* Get SVGA Information */ + reg_al=0x4f; + reg_ah=VESA_GetSVGAInformation(SegValue(es),reg_di); + break; + case 0x01: /* Get SVGA Mode Information */ + reg_al=0x4f; + reg_ah=VESA_GetSVGAModeInformation(reg_cx,SegValue(es),reg_di); + break; + case 0x02: /* Set videomode */ + reg_al=0x4f; + reg_ah=VESA_SetSVGAMode(reg_bx); + break; + case 0x03: /* Get videomode */ + reg_al=0x4f; + reg_ah=VESA_GetSVGAMode(reg_bx); + break; + case 0x05: + if (reg_bh==0) { /* Set CPU Window */ + reg_ah=VESA_SetCPUWindow(reg_bl,reg_dx); + reg_al=0x4f; + } else if (reg_bh == 1) { /* Get CPU Window */ + reg_ah=VESA_GetCPUWindow(reg_bl,reg_dx); + reg_al=0x4f; + } else { + LOG(LOG_INT10,LOG_ERROR)("Unhandled VESA Function %X Subfunction %X",reg_al,reg_bh); + reg_ah=0x01; + } + break; + case 0x07: + switch (reg_bl) { + case 0x80: /* Set Display Start during retrace ?? */ + case 0x00: /* Set display Start */ + reg_al=0x4f; + reg_ah=VESA_SetDisplayStart(reg_cx,reg_dx); + break; + case 0x01: + reg_al=0x4f; + reg_bh=0x00; //Weird? + reg_ah=VESA_GetDisplayStart(reg_cx,reg_dx); + break; + default: + LOG(LOG_INT10,LOG_ERROR)("Unhandled VESA Function %X Subfunction %X",reg_al,reg_bl); + reg_ah=0x1; + } + break; + case 0x09: + switch (reg_bl) { + case 0x80: /* Set Palette during retrace */ + //TODO + case 0x00: /* Set Palette */ + reg_ah=VESA_SetPalette(SegPhys(es)+reg_di,reg_dx,reg_cx); + reg_al=0x4f; + break; + case 0x01: /* Get Palette */ + reg_ah=VESA_GetPalette(SegPhys(es)+reg_di,reg_dx,reg_cx); + reg_al=0x4f; + break; + default: + LOG(LOG_INT10,LOG_ERROR)("Unhandled VESA Function %X Subfunction %X",reg_al,reg_bl); + reg_ah=0x01; + } + break; + default: + LOG(LOG_INT10,LOG_ERROR)("Unhandled VESA Function %X",reg_al); + reg_al=0x0; } break; case 0xff: @@ -251,8 +390,6 @@ static void INT10_Seg40Init(void) { real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,0x51); // Set the default MSR real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x09); - - INT10_SetVideoMode(3); } @@ -275,6 +412,8 @@ void INT10_Init(Section* sec) { //Init the 0x40 segment and init the datastructures in the the video rom area INT10_SetupRomMemory(); INT10_Seg40Init(); + INT10_SetupVESA(); + INT10_SetVideoMode(3); }; diff --git a/src/ints/int10.h b/src/ints/int10.h index de9c92ce..05067f67 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "../hardware/vga.h" + #define BIOSMEM_SEG 0x40 #define BIOSMEM_INITIAL_MODE 0x10 @@ -83,99 +85,64 @@ #define VGAMEM_CTEXT 0xB800 #define VGAMEM_MTEXT 0xB000 - - -/* - * - * Tables of default values for each mode - * - */ -#define MODE_MAX 0x13 -#define TEXT 0x00 -#define GRAPH 0x01 - -#define CTEXT 0x00 -#define MTEXT 0x01 -#define CGA 0x02 -#define PLANAR1 0x03 -#define PLANAR2 0x04 -#define PLANAR4 0x05 -#define LINEAR8 0x06 -#define CGA2 0x07 -// for Tandy - -#define TANDY16 0x0A - - -#define LINEAR15 0x10 -#define LINEAR16 0x11 -#define LINEAR24 0x12 -#define LINEAR32 0x13 - - #define SCREEN_SIZE(x,y) (((x*y*2)|0x00ff)+1) #define SCREEN_MEM_START(x,y,p) ((((x*y*2)|0x00ff)+1)*p) #define SCREEN_IO_START(x,y,p) ((((x*y)|0x00ff)+1)*p) +#define BIOS_NCOLS Bit16u ncols=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); +#define BIOS_NROWS Bit16u nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; extern Bit8u int10_font_08[256 * 8]; extern Bit8u int10_font_14[256 * 14]; extern Bit8u int10_font_16[256 * 16]; +struct VideoModeBlock { + Bitu mode; + VGAModes type; + Bitu swidth, sheight; + Bitu twidth, theight; + Bitu cwidth, cheight; + Bitu ptotal,pstart,plength; - -typedef struct -{Bit8u svgamode; - Bit16u vesamode; - Bit8u type; /* TEXT, GRAPH */ - Bit8u memmodel; /* CTEXT,MTEXT,CGA,PL1,PL2,PL4,P8,P15,P16,P24,P32 */ - Bit8u nbpages; - Bit8u pixbits; - Bit16u swidth, sheight; - Bit16u twidth, theight; - Bit16u cwidth, cheight; - Bit16u sstart; - Bit16u slength; - Bit8u miscreg; - Bit8u pelmask; - Bit8u crtcmodel; - Bit8u actlmodel; - Bit8u grdcmodel; - Bit8u sequmodel; - Bit8u dacmodel; /* 0 1 2 3 */ -} VGAMODES; - -extern VGAMODES vga_modes[MODE_MAX+1]; - + Bitu htotal,vtotal; + Bitu hdispend,vdispend; + Bitu special; + +}; +extern VideoModeBlock ModeList[]; +extern VideoModeBlock * CurMode; typedef struct { - RealPt font_8_first; - RealPt font_8_second; - RealPt font_14; - RealPt font_16; - RealPt static_state; -} VGAROMAREA; -extern VGAROMAREA int10_romarea; + struct { + RealPt font_8_first; + RealPt font_8_second; + RealPt font_14; + RealPt font_16; + RealPt static_state; + RealPt oemstring; + RealPt vesa_modes; + Bitu used; + } rom; +} Int10Data; -#define BIOS_NCOLS Bit16u ncols=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); -#define BIOS_NROWS Bit16u nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; +extern Int10Data int10; -inline Bit8u CURSOR_POS_COL(Bit8u page) { +INLINE Bit8u CURSOR_POS_COL(Bit8u page) { return real_readb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2); } -inline Bit8u CURSOR_POS_ROW(Bit8u page) { +INLINE Bit8u CURSOR_POS_ROW(Bit8u page) { return real_readb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2+1); } - -void INT10_SetVideoMode(Bit8u mode); +bool INT10_SetVideoMode(Bitu mode); void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit8u attr,Bit8u page); void INT10_SetActivePage(Bit8u page); void INT10_GetFuncStateInformation(PhysPt save); +void INT10_SetCursorShape(Bit8u first,Bit8u last); void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page); void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page); void INT10_ReadCharAttr(Bit16u * result,Bit8u page); @@ -185,9 +152,13 @@ void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,B /* Graphics Stuff */ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color); void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color); -VGAMODES * GetCurrentMode(void); + +/* Font Stuff */ +void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu height); /* Palette Group */ +void INT10_SetBackgroundBorder(Bit8u val); +void INT10_SetColorSelect(Bit8u val); void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val); void INT10_SetOverscanBorderColor(Bit8u val); void INT10_SetAllPaletteRegisters(PhysPt data); @@ -199,17 +170,27 @@ void INT10_SetSingleDacRegister(Bit8u index,Bit8u red,Bit8u green,Bit8u blue); void INT10_GetSingleDacRegister(Bit8u index,Bit8u * red,Bit8u * green,Bit8u * blue); void INT10_SetDACBlock(Bit16u index,Bit16u count,PhysPt data); void INT10_GetDACBlock(Bit16u index,Bit16u count,PhysPt data); +void INT10_SelectDACPage(Bit8u function,Bit8u mode); +void INT10_SetPelMask(Bit8u mask); +void INT10_GetPelMask(Bit8u & mask); -/* Mouse pointer */ -void INT10_SetGfxControllerToDefault(void); + + +/* Vesa Group */ +Bit8u VESA_GetSVGAInformation(Bit16u seg,Bit16u off); +Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off); +Bit8u VESA_SetSVGAMode(Bit16u mode); +Bit8u VESA_GetSVGAMode(Bit16u & mode); +Bit8u VESA_SetCPUWindow(Bit8u window,Bit16u address); +Bit8u VESA_GetCPUWindow(Bit8u window,Bit16u & address); +Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u & bytes,Bit16u & pixels,Bit16u & lines); +Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y); +Bit8u VESA_GetDisplayStart(Bit16u & x,Bit16u & y); +Bit8u VESA_SetPalette(PhysPt data,Bitu index,Bitu count); +Bit8u VESA_GetPalette(PhysPt data,Bitu index,Bitu count); /* Sup Groups */ void INT10_SetupRomMemory(void); +void INT10_SetupVESA(void); -struct Int10Data { - Bit8u mode; - VGAMODES * entry; -}; - -extern Int10Data int10; diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index eb8e8ac2..2865267e 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -24,28 +24,28 @@ #include "inout.h" #include "int10.h" -static INLINE void CGA_CopyRow(VGAMODES * curmode,Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { - PhysPt dest=base+((curmode->twidth*rnew)*(curmode->cheight/2)+cleft)*2; - PhysPt src=base+((curmode->twidth*rold)*(curmode->cheight/2)+cleft)*2; - Bitu copy=(cright-cleft)*2;Bitu nextline=curmode->twidth*2; - for (Bits i=0;icheight/2;i++) { +static INLINE void CGA_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { + PhysPt dest=base+((CurMode->twidth*rnew)*(CurMode->cheight/2)+cleft)*2; + PhysPt src=base+((CurMode->twidth*rold)*(CurMode->cheight/2)+cleft)*2; + Bitu copy=(cright-cleft)*2;Bitu nextline=CurMode->twidth*2; + for (Bitu i=0;icheight/2;i++) { MEM_BlockCopy(dest,src,copy); MEM_BlockCopy(dest+8*1024,src+8*1024,copy); dest+=nextline;src+=nextline; } } -static INLINE void PLANAR4_CopyRow(VGAMODES * curmode,Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { +static INLINE void EGA16_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { PhysPt src,dest;Bitu copy; - dest=base+(curmode->twidth*rnew)*curmode->cheight+cleft; - src=base+(curmode->twidth*rold)*curmode->cheight+cleft; - Bitu nextline=curmode->twidth; + dest=base+(CurMode->twidth*rnew)*CurMode->cheight+cleft; + src=base+(CurMode->twidth*rold)*CurMode->cheight+cleft; + Bitu nextline=CurMode->twidth; /* Setup registers correctly */ IO_Write(0x3ce,5);IO_Write(0x3cf,1); /* Memory transfer mode */ IO_Write(0x3c4,2);IO_Write(0x3c5,0xf); /* Enable all Write planes */ /* Do some copying */ Bitu rowsize=(cright-cleft); - copy=curmode->cheight; + copy=CurMode->cheight; for (;copy>0;copy--) { for (Bitu x=0;xtwidth+cleft)*2; - dest=base+(rnew*curmode->twidth+cleft)*2; + src=base+(rold*CurMode->twidth+cleft)*2; + dest=base+(rnew*CurMode->twidth+cleft)*2; MEM_BlockCopy(dest,src,(cright-cleft)*2); } -static INLINE void CGA_FillRow(VGAMODES * curmode,Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { - PhysPt dest=base+((curmode->twidth*row)*(curmode->cheight/2)+cleft)*2; - Bitu copy=(cright-cleft)*2;Bitu nextline=curmode->twidth*2; - for (Bits i=0;icheight/2;i++) { +static INLINE void CGA_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { + PhysPt dest=base+((CurMode->twidth*row)*(CurMode->cheight/2)+cleft)*2; + Bitu copy=(cright-cleft)*2;Bitu nextline=CurMode->twidth*2; + for (Bitu i=0;icheight/2;i++) { for (Bitu x=0;xtwidth*row)*curmode->cheight+cleft; - Bitu nextline=curmode->twidth; - Bitu copy=curmode->cheight; Bitu rowsize=(cright-cleft); + dest=base+(CurMode->twidth*row)*CurMode->cheight+cleft; + Bitu nextline=CurMode->twidth; + Bitu copy=CurMode->cheight; Bitu rowsize=(cright-cleft); for (;copy>0;copy--) { for (Bitu x=0;xtwidth+cleft)*2; + dest=base+(row*CurMode->twidth+cleft)*2; Bit16u fill=(attr<<8)+' '; for (Bit8u x=0;x<(cright-cleft);x++) { mem_writew(dest,fill); @@ -107,8 +106,7 @@ static INLINE void TEXT_FillRow(VGAMODES * curmode,Bit8u cleft,Bit8u cright,Bit8 void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit8u attr,Bit8u page) { /* Do some range checking */ - VGAMODES * curmode=GetCurrentMode(); - if (curmode->type==GRAPH) page=0xff; + if (CurMode->type!=M_TEXT16) page=0xff; BIOS_NCOLS;BIOS_NROWS; if(rul>rlr) return; if(cul>clr) return; @@ -118,9 +116,9 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit /* Get the correct page */ if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); - PhysPt base=PhysMake(curmode->sstart,curmode->slength*page); + PhysPt base=CurMode->pstart+CurMode->plength*page; - /* See how much lines need to be copies */ + /* See how much lines need to be copied */ Bit8u start,end;Bits next; /* Copy some lines */ if (nlines>0) { @@ -137,15 +135,16 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit } while (start!=end) { start+=next; - switch (curmode->memmodel) { - case MTEXT: - case CTEXT: - TEXT_CopyRow(curmode,cul,clr,start,start+nlines,base);break; - case CGA2: - case CGA: - CGA_CopyRow(curmode,cul,clr,start,start+nlines,base);break; - case PLANAR4: - PLANAR4_CopyRow(curmode,cul,clr,start,start+nlines,base);break; + switch (CurMode->type) { + case M_TEXT16: + TEXT_CopyRow(cul,clr,start,start+nlines,base);break; + case M_CGA2: + case M_CGA4: + CGA_CopyRow(cul,clr,start,start+nlines,base);break; + case M_EGA16: + EGA16_CopyRow(cul,clr,start,start+nlines,base);break; + default: + LOG(LOG_INT10,LOG_ERROR)("Unhandled mode %d for scroll",CurMode->type); } } /* Fill some lines */ @@ -157,14 +156,16 @@ filling: start=rlr-nlines+1; } for (;nlines>0;nlines--) { - switch (curmode->memmodel) { - case MTEXT: - case CTEXT: - TEXT_FillRow(curmode,cul,clr,start,base,attr);break; - case CGA: - CGA_FillRow(curmode,cul,clr,start,base,attr);break; - case PLANAR4: - PLANAR4_FillRow(curmode,cul,clr,start,base,attr);break; + switch (CurMode->type) { + case M_TEXT16: + TEXT_FillRow(cul,clr,start,base,attr);break; + case M_CGA2: + case M_CGA4: + CGA_FillRow(cul,clr,start,base,attr);break; + case M_EGA16: + EGA16_FillRow(cul,clr,start,base,attr);break; + default: + LOG(LOG_INT10,LOG_ERROR)("Unhandled mode %d for scroll",CurMode->type); } start++; } @@ -175,14 +176,11 @@ void INT10_SetActivePage(Bit8u page) { Bit16u mem_address; Bit8u cur_col=0 ,cur_row=0 ; - VGAMODES * curmode=GetCurrentMode(); - if (curmode==0) return; if (page>7) return; - mem_address=page*curmode->slength; + mem_address=page*CurMode->plength; /* Write the new page start */ real_writew(BIOSMEM_SEG,BIOSMEM_CURRENT_START,mem_address); - if (curmode->svgamode<8) mem_address>>=1; - + if (CurMode->mode<8) mem_address>>=1; /* Write the new start address in vgahardware */ IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0c); @@ -197,6 +195,53 @@ void INT10_SetActivePage(Bit8u page) { INT10_SetCursorPos(cur_row,cur_col,page); } +void INT10_SetCursorShape(Bit8u first,Bit8u last) { + real_writew(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE,last|(first<<8)); + /* Skip CGA cursor emulation if EGA/VGA system is active */ + if (!(real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL) & 0x8)) { + /* Check for CGA type 01, invisible */ + if ((first & 0x60) == 0x20) { + first=0x1e; + last=0x00; + goto dowrite; + } + /* Check if we need to convert CGA Bios cursor values */ + if (!(real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL) & 0x1)) { + if (CurMode->mode>0x3) goto dowrite; //Only mode 0-3 are text modes on cga + if ((first & 0xe0) || (last & 0xe0)) goto dowrite; + Bit8u cheight=real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT)-1; + /* Creative routine i based of the original ibmvga bios */ + if (last=cheight) || !(last==(cheight-1)) || !(first==cheight) ) { + if (last<=3) goto dowrite; + if (first+22) { + first=(cheight+1)/2; + last=cheight; + } else { + last=cheight; + } + } else { + first=(first-last)+cheight; + last=cheight; + if (cheight>0xc) { + first--; + last--; + } + } + } + + } + } +dowrite: + IO_Write(0x3d4,0xa);IO_Write(0x3d5,first); + IO_Write(0x3d4,0xb);IO_Write(0x3d5,last); +} + void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page) { Bit16u address; @@ -217,12 +262,11 @@ void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page) { IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(address&0xff00)>>8); IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0f); IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,address&0x00ff); - } + } } void INT10_ReadCharAttr(Bit16u * result,Bit8u page) { - if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); BIOS_NCOLS;BIOS_NROWS; Bit8u cur_row=CURSOR_POS_ROW(page); @@ -233,66 +277,55 @@ void INT10_ReadCharAttr(Bit16u * result,Bit8u page) { } - -INLINE static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useattr) { - VGAMODES * curmode=GetCurrentMode(); - switch (curmode->type) { - case TEXT: +static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useattr) { + Bit8u * fontdata; + Bitu x,y; + switch (CurMode->type) { + case M_TEXT16: { // Compute the address - Bit16u address=SCREEN_MEM_START(curmode->twidth,curmode->theight,page)+(col+row*curmode->twidth)*2; + Bit16u address=SCREEN_MEM_START(CurMode->twidth,CurMode->theight,page)+(col+row*CurMode->twidth)*2; // Write the char - Bit16u segment = curmode->sstart; - real_writeb(segment,address,chr); + PhysPt where = CurMode->pstart+address; + mem_writeb(where,chr); if (useattr) { - real_writeb(segment,address+1,attr); + mem_writeb(where+1,attr); } } + return; + case M_CGA4: + case M_CGA2: + if (chr<128) fontdata=Real2Host(RealGetVec(0x43))+chr*8; + else { + chr-=128; + fontdata=Real2Host(RealGetVec(0x1F))+(chr)*8; + } break; - case GRAPH: - { - /* Amount of lines */ - Bit8u * fontdata; - Bit16u x,y; - switch (curmode->cheight) { - case 8: -// fontdata=&int10_font_08[chr*8]; - if (chr<128) fontdata=Real2Host(RealGetVec(0x43))+chr*8; - else fontdata=Real2Host(RealGetVec(0x1F))+(chr-128)*8; - break; - case 14: - fontdata=&int10_font_14[chr*14]; - break; - case 16: - fontdata=&int10_font_16[chr*16]; - break; - default: - LOG(LOG_INT10,LOG_ERROR)("Teletype Illegal Font Height"); - return; - } - x=8*col; - y=curmode->cheight*row; - //TODO Check for out of bounds - for (Bit8u h=0;hcheight;h++) { - Bit8u bitsel=128; - Bit8u bitline=*fontdata++; - Bit16u tx=x; - while (bitsel) { - if (bitline&bitsel) INT10_PutPixel(tx,y,page,attr); - else INT10_PutPixel(tx,y,page,attr & 0x80); - tx++; - bitsel>>=1; - } - y++; - } - } + default: + fontdata=Real2Host(RealGetVec(0x43))+chr*real_readw(0x40,BIOSMEM_CHAR_HEIGHT); break; } + x=8*col; + y=CurMode->cheight*row; + //TODO Check for out of bounds + for (Bit8u h=0;hcheight;h++) { + Bit8u bitsel=128; + Bit8u bitline=*fontdata++; + Bit16u tx=x; + while (bitsel) { + if (bitline&bitsel) INT10_PutPixel(tx,y,page,attr); + else INT10_PutPixel(tx,y,page,attr & 0x80); + tx++; + bitsel>>=1; + } + y++; + } + } void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) { - VGAMODES * curmode=GetCurrentMode(); - if (curmode->type==GRAPH) page=0xff; + //TODO Check if this page thing is correct + if (CurMode->type!=M_TEXT16) page=0xff; if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); @@ -310,8 +343,8 @@ void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page) { - VGAMODES * curmode=GetCurrentMode(); - if (curmode->type==GRAPH) page=0xff; + //TODO Check if this page thing is correct + if (CurMode->type!=M_TEXT16) page=0xff; if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); BIOS_NCOLS;BIOS_NROWS; Bit8u cur_row=CURSOR_POS_ROW(page); @@ -357,8 +390,8 @@ void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page) { } void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,Bit16u count,Bit8u page) { - VGAMODES * curmode=GetCurrentMode(); - if (curmode->type==GRAPH) page=0xff; + //TODO Check if this page thing is correct + if (CurMode->type!=M_TEXT16) page=0xff; if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); BIOS_NCOLS;BIOS_NROWS; diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 84b21e05..1370fb0a 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,7 +22,6 @@ #include "int10.h" -VGAROMAREA int10_romarea; static Bit8u static_functionality[0x10]= { /* 0 */ 0xff, // All modes supported #1 @@ -40,35 +39,67 @@ static Bit8u static_functionality[0x10]= /* f */ 0x00 // reserved }; +static Bit16u map_offset[8]={ + 0x0000,0x4000,0x8000,0xc000, + 0x2000,0x6000,0xa000,0xe000 +}; + +void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu height) { + PhysPt where=PhysMake(0xa000,map_offset[map & 0x7]+offset*32); + IO_Write(0x3c4,0x2);IO_Write(0x3c5,0x4); //Enable plane 2 + IO_Write(0x3ce,0x6);IO_Write(0x3cf,0x0); //Disable odd/even and a0000 adressing + for (Bitu i=0;isheight/height)-1); + real_writeb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,height); + //TODO Reprogram cursor size? + } +} + + + void INT10_SetupRomMemory(void) { /* This should fill up certain structures inside the Video Bios Rom Area */ - Bit32u i; - - Bit16u segoff=0; - int10_romarea.font_8_first=RealMake(0xC000,segoff); + Bitu i; + int10.rom.used=2; + real_writew(0xc000,0,0xaa55); + int10.rom.font_8_first=RealMake(0xC000,int10.rom.used); for (i=0;i<128*8;i++) { - real_writeb(0xC000,segoff++,int10_font_08[i]); + real_writeb(0xC000,int10.rom.used++,int10_font_08[i]); } - int10_romarea.font_8_second=RealMake(0xC000,segoff); + int10.rom.font_8_second=RealMake(0xC000,int10.rom.used); for (i=0;i<128*8;i++) { - real_writeb(0xC000,segoff++,int10_font_08[i+128*8]); + real_writeb(0xC000,int10.rom.used++,int10_font_08[i+128*8]); } - int10_romarea.font_14=RealMake(0xC000,segoff); + int10.rom.font_14=RealMake(0xC000,int10.rom.used); for (i=0;i<256*14;i++) { - real_writeb(0xC000,segoff++,int10_font_14[i]); + real_writeb(0xC000,int10.rom.used++,int10_font_14[i]); } - int10_romarea.font_16=RealMake(0xC000,segoff); + int10.rom.font_16=RealMake(0xC000,int10.rom.used); for (i=0;i<256*16;i++) { - real_writeb(0xC000,segoff++,int10_font_16[i]); + real_writeb(0xC000,int10.rom.used++,int10_font_16[i]); } - int10_romarea.static_state=RealMake(0xC000,segoff); + int10.rom.static_state=RealMake(0xC000,int10.rom.used); for (i=0;i<0x10;i++) { - real_writeb(0xC000,segoff++,static_functionality[i]); + real_writeb(0xC000,int10.rom.used++,static_functionality[i]); } MEM_BlockWrite(PhysMake(0xf000,0xfa6e),int10_font_08,128*8); - RealSetVec(0x1F,int10_romarea.font_8_second); + RealSetVec(0x1F,int10.rom.font_8_second); }; diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 2ec9f019..40a8a918 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -73,12 +73,12 @@ struct Dynamic_Functionality { void INT10_GetFuncStateInformation(PhysPt save) { /* set static state pointer */ - mem_writed(save,int10_romarea.static_state); + mem_writed(save,int10.rom.static_state); /* Copy BIOS Segment areas */ Bit16u i; /* First area in Bios Seg */ - for (i=0;i<30;i++) { + for (i=0;i<0x1e;i++) { mem_writeb(save+0x4+i,real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE+i)); } /* Second area */ @@ -89,31 +89,27 @@ void INT10_GetFuncStateInformation(PhysPt save) { for (i=0x25;i<0x40;i++) mem_writeb(save+i,0); /* DCC Index */ mem_writeb(save+0x25,real_readb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX)); - VGAMODES * curmode=GetCurrentMode(); - if (!curmode) return; Bit16u col_count=0; - switch (curmode->memmodel) { - case CTEXT: - col_count=2;break; - case MTEXT: + switch (CurMode->type) { + case M_TEXT16: col_count=16;break; - case CGA: - col_count=4;break; - case PLANAR1: + case M_CGA2: col_count=2;break; - case PLANAR2: + case M_CGA4: col_count=4;break; - case PLANAR4: + case M_EGA16: col_count=16;break; - case LINEAR8: + case M_VGA: col_count=256;break; + default: + LOG(LOG_INT10,LOG_ERROR)("Get Func State illegal mode type %d",CurMode->type); } /* Colour count */ mem_writew(save+0x27,col_count); /* Page count */ - mem_writeb(save+0x29,curmode->nbpages); + mem_writeb(save+0x29,CurMode->ptotal); /* scan lines */ - switch (curmode->sheight) { + switch (CurMode->sheight) { case 200: mem_writeb(save+0x2a,0);break; case 350: diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 36f0bc87..806ae16a 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1,20 +1,4 @@ -/* - * Copyright (C) 2002-2003 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ +#include #include "dosbox.h" #include "mem.h" @@ -22,113 +6,57 @@ #include "int10.h" #include "mouse.h" -//TODO Maybe also add PCJR Video Modes could be nice :) -//TODO include some credits to bochs/plex86 bios i used for info/tables +#define _HALF_CLOCK 0x0001 +#define _LINE_DOUBLE 0x0002 + +#define SEQ_REGS 0x05 +#define GFX_REGS 0x09 +#define ATT_REGS 0x15 + +VideoModeBlock ModeList[]={ +/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde ,special flags */ +{ 0x000 ,M_TEXT16 ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_HALF_CLOCK }, +{ 0x001 ,M_TEXT16 ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_HALF_CLOCK }, +{ 0x002 ,M_TEXT16 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x003 ,M_TEXT16 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, +{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,_LINE_DOUBLE }, +{ 0x007 ,M_TEXT16 ,720 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, +/* 8,9,0xa are tandy modes */ +{ 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, + -VGAMODES vga_modes[MODE_MAX+1]= -{//mode vesa class model pg bits sw sh tw th cw ch sstart slength misc pelm crtc actl gdc sequ dac - {0x00, 0xFFFF, TEXT, CTEXT, 8, 4, 360, 400, 40, 25, 9, 16, 0xB800, 0x0800, 0x67, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x02}, - {0x01, 0xFFFF, TEXT, CTEXT, 8, 4, 360, 400, 40, 25, 9, 16, 0xB800, 0x0800, 0x67, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x02}, - {0x02, 0xFFFF, TEXT, CTEXT, 4, 4, 720, 400, 80, 25, 9, 16, 0xB800, 0x1000, 0x67, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x02}, - {0x03, 0xFFFF, TEXT, CTEXT, 4, 4, 720, 400, 80, 25, 9, 16, 0xB800, 0x1000, 0x67, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x02}, - {0x04, 0xFFFF, GRAPH, CGA, 4, 2, 320, 200, 40, 25, 8, 8, 0xB800, 0x0800, 0x63, 0xFF, 0x02, 0x01, 0x01, 0x02, 0x01}, - {0x05, 0xFFFF, GRAPH, CGA, 1, 2, 320, 200, 40, 25, 8, 8, 0xB800, 0x0800, 0x63, 0xFF, 0x02, 0x01, 0x01, 0x02, 0x01}, - {0x06, 0xFFFF, GRAPH, CGA2, 1, 1, 640, 200, 80, 25, 8, 8, 0xB800, 0x1000, 0x63, 0xFF, 0x03, 0x02, 0x02, 0x03, 0x01}, - {0x07, 0xFFFF, TEXT, MTEXT, 4, 4, 720, 400, 80, 25, 9, 16, 0xB000, 0x1000, 0x66, 0xFF, 0x04, 0x03, 0x03, 0x01, 0x00}, - {0x0D, 0xFFFF, GRAPH, PLANAR4, 8, 4, 320, 200, 40, 25, 8, 8, 0xA000, 0x2000, 0x63, 0xFF, 0x05, 0x04, 0x04, 0x04, 0x01}, - {0x0E, 0xFFFF, GRAPH, PLANAR4, 4, 4, 640, 200, 80, 25, 8, 8, 0xA000, 0x4000, 0x63, 0xFF, 0x06, 0x04, 0x04, 0x05, 0x01}, - {0x0F, 0xFFFF, GRAPH, PLANAR2, 2, 2, 640, 350, 80, 25, 8, 14, 0xA000, 0x8000, 0xa2, 0xFF, 0x07, 0x05, 0x04, 0x05, 0x00}, - {0x10, 0xFFFF, GRAPH, PLANAR4, 2, 4, 640, 350, 80, 25, 8, 14, 0xA000, 0x8000, 0xa3, 0xFF, 0x07, 0x06, 0x04, 0x05, 0x02}, - {0x11, 0xFFFF, GRAPH, PLANAR1, 1, 1, 640, 480, 80, 30, 8, 16, 0xA000, 0xA000, 0xe3, 0xFF, 0x08, 0x07, 0x04, 0x05, 0x02}, - {0x12, 0xFFFF, GRAPH, PLANAR4, 1, 4, 640, 480, 80, 30, 8, 16, 0xA000, 0xA000, 0xe3, 0xFF, 0x08, 0x06, 0x04, 0x05, 0x02}, - {0x13, 0xFFFF, GRAPH, LINEAR8, 1, 8, 320, 200, 40, 25, 8, 8, 0xA000, 0xFA00, 0x63, 0xFF, 0x09, 0x08, 0x05, 0x06, 0x03} +{ 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, +{ 0x00E ,M_EGA16 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,_LINE_DOUBLE }, +{ 0x00F ,M_EGA2 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,1 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, +{ 0x011 ,M_EGA2 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,449 ,80 ,480 ,0 }, +{ 0x012 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, +{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,0 }, + +{ 0x100 ,M_LIN8 ,640 ,400 ,80 ,20 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, +{ 0x101 ,M_LIN8 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, + + +{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, + }; -/* CRTC */ -#define CRTC_MAX_REG 0x18 -#define CRTC_MAX_MODEL 0x09 - -static Bit8u crtc_regs[CRTC_MAX_MODEL+1][CRTC_MAX_REG+1]= -{/* Model 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 */ - /* 00 */ {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,0xff}, - /* 01 */ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,0xff}, - /* 02 */ {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,0xff}, - /* 03 */ {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,0xff}, - /* 04 */ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,0xff}, - /* 05 */ {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,0xff}, - /* 06 */ {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,0xff}, - /* 07 */ {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3,0xff}, - /* 08 */ {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xe3,0xff}, - /* 09 */ {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,0xff} -}; - -/* Attribute Controler 0x3c0 */ -#define ACTL_MAX_REG 0x14 -#define ACTL_MAX_MODEL 0x08 - -static Bit8u actl_regs[ACTL_MAX_MODEL+1][ACTL_MAX_REG+1]= -{/* Model 00 01 02 03 04 05 06 07 08 09 0A 0B OC OD OE OF 10 11 12 13 14 */ - /* 00 */ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x0c,0x00,0x0f,0x08,0x00}, - /* 01 */ {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x01,0x00,0x03,0x00,0x00}, - /* 02 */ {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x01,0x00,0x01,0x00,0x00}, - /* 03 */ {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x0e,0x00,0x0f,0x08,0x00}, - /* 04 */ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x01,0x00,0x0f,0x00,0x00}, - /* 05 */ {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,0x0b,0x00,0x05,0x00,0x00}, - /* 06 */ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x01,0x00,0x0f,0x00,0x00}, - /* 07 */ {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x01,0x00,0x01,0x00,0x00}, - /* 08 */ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x41,0x00,0x0f,0x00,0x00} -}; - -/* Sequencer 0x3c4 */ -#define SEQU_MAX_REG 0x04 -#define SEQU_MAX_MODEL 0x06 - -static Bit8u sequ_regs[SEQU_MAX_MODEL+1][SEQU_MAX_REG+1]= -{/* Model 00 01 02 03 04 */ - /* 00 */ {0x03,0x08,0x03,0x00,0x02}, - /* 01 */ {0x03,0x00,0x03,0x00,0x02}, - /* 02 */ {0x03,0x09,0x03,0x00,0x02}, - /* 03 */ {0x03,0x01,0x01,0x00,0x06}, - /* 04 */ {0x03,0x09,0x0f,0x00,0x06}, - /* 05 */ {0x03,0x01,0x0f,0x00,0x06}, - /* 06 */ {0x03,0x01,0x0f,0x00,0x0e} -}; - -/* Graphic ctl 0x3ce */ -#define GRDC_MAX_REG 0x08 -#define GRDC_MAX_MODEL 0x05 - -static Bit8u grdc_regs[GRDC_MAX_MODEL+1][GRDC_MAX_REG+1]= -{/* Model 00 01 02 03 04 05 06 07 08 */ - /* 00 */ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x0f,0xff}, - /* 01 */ {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x0f,0xff}, - /* 02 */ {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x0f,0xff}, - /* 03 */ {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x0f,0xff}, - /* 04 */ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,0xff}, - /* 05 */ {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,0xff} -}; - -/* Default Palette */ -#define DAC_MAX_MODEL 3 - -static Bit8u dac_regs[DAC_MAX_MODEL+1]= -{0x3f,0x3f,0x3f,0xff}; - -/* Mono */ -static Bit8u palette0[63+1][3]= +static Bit8u text_palette[64][3]= { - {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, - {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, - {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, - {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, - {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, - {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, - {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, {0x2a,0x2a,0x2a}, - {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f}, {0x3f,0x3f,0x3f} + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x2a,0x00, 0x2a,0x2a,0x2a, + 0x00,0x00,0x15, 0x00,0x00,0x3f, 0x00,0x2a,0x15, 0x00,0x2a,0x3f, 0x2a,0x00,0x15, 0x2a,0x00,0x3f, 0x2a,0x2a,0x15, 0x2a,0x2a,0x3f, + 0x00,0x15,0x00, 0x00,0x15,0x2a, 0x00,0x3f,0x00, 0x00,0x3f,0x2a, 0x2a,0x15,0x00, 0x2a,0x15,0x2a, 0x2a,0x3f,0x00, 0x2a,0x3f,0x2a, + 0x00,0x15,0x15, 0x00,0x15,0x3f, 0x00,0x3f,0x15, 0x00,0x3f,0x3f, 0x2a,0x15,0x15, 0x2a,0x15,0x3f, 0x2a,0x3f,0x15, 0x2a,0x3f,0x3f, + 0x15,0x00,0x00, 0x15,0x00,0x2a, 0x15,0x2a,0x00, 0x15,0x2a,0x2a, 0x3f,0x00,0x00, 0x3f,0x00,0x2a, 0x3f,0x2a,0x00, 0x3f,0x2a,0x2a, + 0x15,0x00,0x15, 0x15,0x00,0x3f, 0x15,0x2a,0x15, 0x15,0x2a,0x3f, 0x3f,0x00,0x15, 0x3f,0x00,0x3f, 0x3f,0x2a,0x15, 0x3f,0x2a,0x3f, + 0x15,0x15,0x00, 0x15,0x15,0x2a, 0x15,0x3f,0x00, 0x15,0x3f,0x2a, 0x3f,0x15,0x00, 0x3f,0x15,0x2a, 0x3f,0x3f,0x00, 0x3f,0x3f,0x2a, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f }; -static Bit8u palette1[63+1][3]= +static Bit8u ega_palette[64][3]= { {0x00,0x00,0x00}, {0x00,0x00,0x2a}, {0x00,0x2a,0x00}, {0x00,0x2a,0x2a}, {0x2a,0x00,0x00}, {0x2a,0x00,0x2a}, {0x2a,0x15,0x00}, {0x2a,0x2a,0x2a}, {0x00,0x00,0x00}, {0x00,0x00,0x2a}, {0x00,0x2a,0x00}, {0x00,0x2a,0x2a}, {0x2a,0x00,0x00}, {0x2a,0x00,0x2a}, {0x2a,0x15,0x00}, {0x2a,0x2a,0x2a}, @@ -140,220 +68,415 @@ static Bit8u palette1[63+1][3]= {0x15,0x15,0x15}, {0x15,0x15,0x3f}, {0x15,0x3f,0x15}, {0x15,0x3f,0x3f}, {0x3f,0x15,0x15}, {0x3f,0x15,0x3f}, {0x3f,0x3f,0x15}, {0x3f,0x3f,0x3f} }; -static Bit8u palette2[63+1][3]= + +static Bit8u vga_palette[256][3]= { - {0x00,0x00,0x00}, {0x00,0x00,0x2a}, {0x00,0x2a,0x00}, {0x00,0x2a,0x2a}, {0x2a,0x00,0x00}, {0x2a,0x00,0x2a}, {0x2a,0x2a,0x00}, {0x2a,0x2a,0x2a}, - {0x00,0x00,0x15}, {0x00,0x00,0x3f}, {0x00,0x2a,0x15}, {0x00,0x2a,0x3f}, {0x2a,0x00,0x15}, {0x2a,0x00,0x3f}, {0x2a,0x2a,0x15}, {0x2a,0x2a,0x3f}, - {0x00,0x15,0x00}, {0x00,0x15,0x2a}, {0x00,0x3f,0x00}, {0x00,0x3f,0x2a}, {0x2a,0x15,0x00}, {0x2a,0x15,0x2a}, {0x2a,0x3f,0x00}, {0x2a,0x3f,0x2a}, - {0x00,0x15,0x15}, {0x00,0x15,0x3f}, {0x00,0x3f,0x15}, {0x00,0x3f,0x3f}, {0x2a,0x15,0x15}, {0x2a,0x15,0x3f}, {0x2a,0x3f,0x15}, {0x2a,0x3f,0x3f}, - {0x15,0x00,0x00}, {0x15,0x00,0x2a}, {0x15,0x2a,0x00}, {0x15,0x2a,0x2a}, {0x3f,0x00,0x00}, {0x3f,0x00,0x2a}, {0x3f,0x2a,0x00}, {0x3f,0x2a,0x2a}, - {0x15,0x00,0x15}, {0x15,0x00,0x3f}, {0x15,0x2a,0x15}, {0x15,0x2a,0x3f}, {0x3f,0x00,0x15}, {0x3f,0x00,0x3f}, {0x3f,0x2a,0x15}, {0x3f,0x2a,0x3f}, - {0x15,0x15,0x00}, {0x15,0x15,0x2a}, {0x15,0x3f,0x00}, {0x15,0x3f,0x2a}, {0x3f,0x15,0x00}, {0x3f,0x15,0x2a}, {0x3f,0x3f,0x00}, {0x3f,0x3f,0x2a}, - {0x15,0x15,0x15}, {0x15,0x15,0x3f}, {0x15,0x3f,0x15}, {0x15,0x3f,0x3f}, {0x3f,0x15,0x15}, {0x3f,0x15,0x3f}, {0x3f,0x3f,0x15}, {0x3f,0x3f,0x3f} + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, + 0x00,0x00,0x00, 0x05,0x05,0x05, 0x08,0x08,0x08, 0x0b,0x0b,0x0b, 0x0e,0x0e,0x0e, 0x11,0x11,0x11, 0x14,0x14,0x14, 0x18,0x18,0x18, + 0x1c,0x1c,0x1c, 0x20,0x20,0x20, 0x24,0x24,0x24, 0x28,0x28,0x28, 0x2d,0x2d,0x2d, 0x32,0x32,0x32, 0x38,0x38,0x38, 0x3f,0x3f,0x3f, + 0x00,0x00,0x3f, 0x10,0x00,0x3f, 0x1f,0x00,0x3f, 0x2f,0x00,0x3f, 0x3f,0x00,0x3f, 0x3f,0x00,0x2f, 0x3f,0x00,0x1f, 0x3f,0x00,0x10, + 0x3f,0x00,0x00, 0x3f,0x10,0x00, 0x3f,0x1f,0x00, 0x3f,0x2f,0x00, 0x3f,0x3f,0x00, 0x2f,0x3f,0x00, 0x1f,0x3f,0x00, 0x10,0x3f,0x00, + 0x00,0x3f,0x00, 0x00,0x3f,0x10, 0x00,0x3f,0x1f, 0x00,0x3f,0x2f, 0x00,0x3f,0x3f, 0x00,0x2f,0x3f, 0x00,0x1f,0x3f, 0x00,0x10,0x3f, + 0x1f,0x1f,0x3f, 0x27,0x1f,0x3f, 0x2f,0x1f,0x3f, 0x37,0x1f,0x3f, 0x3f,0x1f,0x3f, 0x3f,0x1f,0x37, 0x3f,0x1f,0x2f, 0x3f,0x1f,0x27, + + 0x3f,0x1f,0x1f, 0x3f,0x27,0x1f, 0x3f,0x2f,0x1f, 0x3f,0x37,0x1f, 0x3f,0x3f,0x1f, 0x37,0x3f,0x1f, 0x2f,0x3f,0x1f, 0x27,0x3f,0x1f, + 0x1f,0x3f,0x1f, 0x1f,0x3f,0x27, 0x1f,0x3f,0x2f, 0x1f,0x3f,0x37, 0x1f,0x3f,0x3f, 0x1f,0x37,0x3f, 0x1f,0x2f,0x3f, 0x1f,0x27,0x3f, + 0x2d,0x2d,0x3f, 0x31,0x2d,0x3f, 0x36,0x2d,0x3f, 0x3a,0x2d,0x3f, 0x3f,0x2d,0x3f, 0x3f,0x2d,0x3a, 0x3f,0x2d,0x36, 0x3f,0x2d,0x31, + 0x3f,0x2d,0x2d, 0x3f,0x31,0x2d, 0x3f,0x36,0x2d, 0x3f,0x3a,0x2d, 0x3f,0x3f,0x2d, 0x3a,0x3f,0x2d, 0x36,0x3f,0x2d, 0x31,0x3f,0x2d, + 0x2d,0x3f,0x2d, 0x2d,0x3f,0x31, 0x2d,0x3f,0x36, 0x2d,0x3f,0x3a, 0x2d,0x3f,0x3f, 0x2d,0x3a,0x3f, 0x2d,0x36,0x3f, 0x2d,0x31,0x3f, + 0x00,0x00,0x1c, 0x07,0x00,0x1c, 0x0e,0x00,0x1c, 0x15,0x00,0x1c, 0x1c,0x00,0x1c, 0x1c,0x00,0x15, 0x1c,0x00,0x0e, 0x1c,0x00,0x07, + 0x1c,0x00,0x00, 0x1c,0x07,0x00, 0x1c,0x0e,0x00, 0x1c,0x15,0x00, 0x1c,0x1c,0x00, 0x15,0x1c,0x00, 0x0e,0x1c,0x00, 0x07,0x1c,0x00, + 0x00,0x1c,0x00, 0x00,0x1c,0x07, 0x00,0x1c,0x0e, 0x00,0x1c,0x15, 0x00,0x1c,0x1c, 0x00,0x15,0x1c, 0x00,0x0e,0x1c, 0x00,0x07,0x1c, + + 0x0e,0x0e,0x1c, 0x11,0x0e,0x1c, 0x15,0x0e,0x1c, 0x18,0x0e,0x1c, 0x1c,0x0e,0x1c, 0x1c,0x0e,0x18, 0x1c,0x0e,0x15, 0x1c,0x0e,0x11, + 0x1c,0x0e,0x0e, 0x1c,0x11,0x0e, 0x1c,0x15,0x0e, 0x1c,0x18,0x0e, 0x1c,0x1c,0x0e, 0x18,0x1c,0x0e, 0x15,0x1c,0x0e, 0x11,0x1c,0x0e, + 0x0e,0x1c,0x0e, 0x0e,0x1c,0x11, 0x0e,0x1c,0x15, 0x0e,0x1c,0x18, 0x0e,0x1c,0x1c, 0x0e,0x18,0x1c, 0x0e,0x15,0x1c, 0x0e,0x11,0x1c, + 0x14,0x14,0x1c, 0x16,0x14,0x1c, 0x18,0x14,0x1c, 0x1a,0x14,0x1c, 0x1c,0x14,0x1c, 0x1c,0x14,0x1a, 0x1c,0x14,0x18, 0x1c,0x14,0x16, + 0x1c,0x14,0x14, 0x1c,0x16,0x14, 0x1c,0x18,0x14, 0x1c,0x1a,0x14, 0x1c,0x1c,0x14, 0x1a,0x1c,0x14, 0x18,0x1c,0x14, 0x16,0x1c,0x14, + 0x14,0x1c,0x14, 0x14,0x1c,0x16, 0x14,0x1c,0x18, 0x14,0x1c,0x1a, 0x14,0x1c,0x1c, 0x14,0x1a,0x1c, 0x14,0x18,0x1c, 0x14,0x16,0x1c, + 0x00,0x00,0x10, 0x04,0x00,0x10, 0x08,0x00,0x10, 0x0c,0x00,0x10, 0x10,0x00,0x10, 0x10,0x00,0x0c, 0x10,0x00,0x08, 0x10,0x00,0x04, + 0x10,0x00,0x00, 0x10,0x04,0x00, 0x10,0x08,0x00, 0x10,0x0c,0x00, 0x10,0x10,0x00, 0x0c,0x10,0x00, 0x08,0x10,0x00, 0x04,0x10,0x00, + + 0x00,0x10,0x00, 0x00,0x10,0x04, 0x00,0x10,0x08, 0x00,0x10,0x0c, 0x00,0x10,0x10, 0x00,0x0c,0x10, 0x00,0x08,0x10, 0x00,0x04,0x10, + 0x08,0x08,0x10, 0x0a,0x08,0x10, 0x0c,0x08,0x10, 0x0e,0x08,0x10, 0x10,0x08,0x10, 0x10,0x08,0x0e, 0x10,0x08,0x0c, 0x10,0x08,0x0a, + 0x10,0x08,0x08, 0x10,0x0a,0x08, 0x10,0x0c,0x08, 0x10,0x0e,0x08, 0x10,0x10,0x08, 0x0e,0x10,0x08, 0x0c,0x10,0x08, 0x0a,0x10,0x08, + 0x08,0x10,0x08, 0x08,0x10,0x0a, 0x08,0x10,0x0c, 0x08,0x10,0x0e, 0x08,0x10,0x10, 0x08,0x0e,0x10, 0x08,0x0c,0x10, 0x08,0x0a,0x10, + 0x0b,0x0b,0x10, 0x0c,0x0b,0x10, 0x0d,0x0b,0x10, 0x0f,0x0b,0x10, 0x10,0x0b,0x10, 0x10,0x0b,0x0f, 0x10,0x0b,0x0d, 0x10,0x0b,0x0c, + 0x10,0x0b,0x0b, 0x10,0x0c,0x0b, 0x10,0x0d,0x0b, 0x10,0x0f,0x0b, 0x10,0x10,0x0b, 0x0f,0x10,0x0b, 0x0d,0x10,0x0b, 0x0c,0x10,0x0b, + 0x0b,0x10,0x0b, 0x0b,0x10,0x0c, 0x0b,0x10,0x0d, 0x0b,0x10,0x0f, 0x0b,0x10,0x10, 0x0b,0x0f,0x10, 0x0b,0x0d,0x10, 0x0b,0x0c,0x10, + 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00 }; -static Bit8u palette3[256][3]= -{ - {0x00,0x00,0x00}, {0x00,0x00,0x2a}, {0x00,0x2a,0x00}, {0x00,0x2a,0x2a}, {0x2a,0x00,0x00}, {0x2a,0x00,0x2a}, {0x2a,0x15,0x00}, {0x2a,0x2a,0x2a}, - {0x15,0x15,0x15}, {0x15,0x15,0x3f}, {0x15,0x3f,0x15}, {0x15,0x3f,0x3f}, {0x3f,0x15,0x15}, {0x3f,0x15,0x3f}, {0x3f,0x3f,0x15}, {0x3f,0x3f,0x3f}, - {0x00,0x00,0x00}, {0x05,0x05,0x05}, {0x08,0x08,0x08}, {0x0b,0x0b,0x0b}, {0x0e,0x0e,0x0e}, {0x11,0x11,0x11}, {0x14,0x14,0x14}, {0x18,0x18,0x18}, - {0x1c,0x1c,0x1c}, {0x20,0x20,0x20}, {0x24,0x24,0x24}, {0x28,0x28,0x28}, {0x2d,0x2d,0x2d}, {0x32,0x32,0x32}, {0x38,0x38,0x38}, {0x3f,0x3f,0x3f}, - {0x00,0x00,0x3f}, {0x10,0x00,0x3f}, {0x1f,0x00,0x3f}, {0x2f,0x00,0x3f}, {0x3f,0x00,0x3f}, {0x3f,0x00,0x2f}, {0x3f,0x00,0x1f}, {0x3f,0x00,0x10}, - {0x3f,0x00,0x00}, {0x3f,0x10,0x00}, {0x3f,0x1f,0x00}, {0x3f,0x2f,0x00}, {0x3f,0x3f,0x00}, {0x2f,0x3f,0x00}, {0x1f,0x3f,0x00}, {0x10,0x3f,0x00}, - {0x00,0x3f,0x00}, {0x00,0x3f,0x10}, {0x00,0x3f,0x1f}, {0x00,0x3f,0x2f}, {0x00,0x3f,0x3f}, {0x00,0x2f,0x3f}, {0x00,0x1f,0x3f}, {0x00,0x10,0x3f}, - {0x1f,0x1f,0x3f}, {0x27,0x1f,0x3f}, {0x2f,0x1f,0x3f}, {0x37,0x1f,0x3f}, {0x3f,0x1f,0x3f}, {0x3f,0x1f,0x37}, {0x3f,0x1f,0x2f}, {0x3f,0x1f,0x27}, +VideoModeBlock * CurMode; - {0x3f,0x1f,0x1f}, {0x3f,0x27,0x1f}, {0x3f,0x2f,0x1f}, {0x3f,0x37,0x1f}, {0x3f,0x3f,0x1f}, {0x37,0x3f,0x1f}, {0x2f,0x3f,0x1f}, {0x27,0x3f,0x1f}, - {0x1f,0x3f,0x1f}, {0x1f,0x3f,0x27}, {0x1f,0x3f,0x2f}, {0x1f,0x3f,0x37}, {0x1f,0x3f,0x3f}, {0x1f,0x37,0x3f}, {0x1f,0x2f,0x3f}, {0x1f,0x27,0x3f}, - {0x2d,0x2d,0x3f}, {0x31,0x2d,0x3f}, {0x36,0x2d,0x3f}, {0x3a,0x2d,0x3f}, {0x3f,0x2d,0x3f}, {0x3f,0x2d,0x3a}, {0x3f,0x2d,0x36}, {0x3f,0x2d,0x31}, - {0x3f,0x2d,0x2d}, {0x3f,0x31,0x2d}, {0x3f,0x36,0x2d}, {0x3f,0x3a,0x2d}, {0x3f,0x3f,0x2d}, {0x3a,0x3f,0x2d}, {0x36,0x3f,0x2d}, {0x31,0x3f,0x2d}, - {0x2d,0x3f,0x2d}, {0x2d,0x3f,0x31}, {0x2d,0x3f,0x36}, {0x2d,0x3f,0x3a}, {0x2d,0x3f,0x3f}, {0x2d,0x3a,0x3f}, {0x2d,0x36,0x3f}, {0x2d,0x31,0x3f}, - {0x00,0x00,0x1c}, {0x07,0x00,0x1c}, {0x0e,0x00,0x1c}, {0x15,0x00,0x1c}, {0x1c,0x00,0x1c}, {0x1c,0x00,0x15}, {0x1c,0x00,0x0e}, {0x1c,0x00,0x07}, - {0x1c,0x00,0x00}, {0x1c,0x07,0x00}, {0x1c,0x0e,0x00}, {0x1c,0x15,0x00}, {0x1c,0x1c,0x00}, {0x15,0x1c,0x00}, {0x0e,0x1c,0x00}, {0x07,0x1c,0x00}, - {0x00,0x1c,0x00}, {0x00,0x1c,0x07}, {0x00,0x1c,0x0e}, {0x00,0x1c,0x15}, {0x00,0x1c,0x1c}, {0x00,0x15,0x1c}, {0x00,0x0e,0x1c}, {0x00,0x07,0x1c}, - - {0x0e,0x0e,0x1c}, {0x11,0x0e,0x1c}, {0x15,0x0e,0x1c}, {0x18,0x0e,0x1c}, {0x1c,0x0e,0x1c}, {0x1c,0x0e,0x18}, {0x1c,0x0e,0x15}, {0x1c,0x0e,0x11}, - {0x1c,0x0e,0x0e}, {0x1c,0x11,0x0e}, {0x1c,0x15,0x0e}, {0x1c,0x18,0x0e}, {0x1c,0x1c,0x0e}, {0x18,0x1c,0x0e}, {0x15,0x1c,0x0e}, {0x11,0x1c,0x0e}, - {0x0e,0x1c,0x0e}, {0x0e,0x1c,0x11}, {0x0e,0x1c,0x15}, {0x0e,0x1c,0x18}, {0x0e,0x1c,0x1c}, {0x0e,0x18,0x1c}, {0x0e,0x15,0x1c}, {0x0e,0x11,0x1c}, - {0x14,0x14,0x1c}, {0x16,0x14,0x1c}, {0x18,0x14,0x1c}, {0x1a,0x14,0x1c}, {0x1c,0x14,0x1c}, {0x1c,0x14,0x1a}, {0x1c,0x14,0x18}, {0x1c,0x14,0x16}, - {0x1c,0x14,0x14}, {0x1c,0x16,0x14}, {0x1c,0x18,0x14}, {0x1c,0x1a,0x14}, {0x1c,0x1c,0x14}, {0x1a,0x1c,0x14}, {0x18,0x1c,0x14}, {0x16,0x1c,0x14}, - {0x14,0x1c,0x14}, {0x14,0x1c,0x16}, {0x14,0x1c,0x18}, {0x14,0x1c,0x1a}, {0x14,0x1c,0x1c}, {0x14,0x1a,0x1c}, {0x14,0x18,0x1c}, {0x14,0x16,0x1c}, - {0x00,0x00,0x10}, {0x04,0x00,0x10}, {0x08,0x00,0x10}, {0x0c,0x00,0x10}, {0x10,0x00,0x10}, {0x10,0x00,0x0c}, {0x10,0x00,0x08}, {0x10,0x00,0x04}, - {0x10,0x00,0x00}, {0x10,0x04,0x00}, {0x10,0x08,0x00}, {0x10,0x0c,0x00}, {0x10,0x10,0x00}, {0x0c,0x10,0x00}, {0x08,0x10,0x00}, {0x04,0x10,0x00}, - - {0x00,0x10,0x00}, {0x00,0x10,0x04}, {0x00,0x10,0x08}, {0x00,0x10,0x0c}, {0x00,0x10,0x10}, {0x00,0x0c,0x10}, {0x00,0x08,0x10}, {0x00,0x04,0x10}, - {0x08,0x08,0x10}, {0x0a,0x08,0x10}, {0x0c,0x08,0x10}, {0x0e,0x08,0x10}, {0x10,0x08,0x10}, {0x10,0x08,0x0e}, {0x10,0x08,0x0c}, {0x10,0x08,0x0a}, - {0x10,0x08,0x08}, {0x10,0x0a,0x08}, {0x10,0x0c,0x08}, {0x10,0x0e,0x08}, {0x10,0x10,0x08}, {0x0e,0x10,0x08}, {0x0c,0x10,0x08}, {0x0a,0x10,0x08}, - {0x08,0x10,0x08}, {0x08,0x10,0x0a}, {0x08,0x10,0x0c}, {0x08,0x10,0x0e}, {0x08,0x10,0x10}, {0x08,0x0e,0x10}, {0x08,0x0c,0x10}, {0x08,0x0a,0x10}, - {0x0b,0x0b,0x10}, {0x0c,0x0b,0x10}, {0x0d,0x0b,0x10}, {0x0f,0x0b,0x10}, {0x10,0x0b,0x10}, {0x10,0x0b,0x0f}, {0x10,0x0b,0x0d}, {0x10,0x0b,0x0c}, - {0x10,0x0b,0x0b}, {0x10,0x0c,0x0b}, {0x10,0x0d,0x0b}, {0x10,0x0f,0x0b}, {0x10,0x10,0x0b}, {0x0f,0x10,0x0b}, {0x0d,0x10,0x0b}, {0x0c,0x10,0x0b}, - {0x0b,0x10,0x0b}, {0x0b,0x10,0x0c}, {0x0b,0x10,0x0d}, {0x0b,0x10,0x0f}, {0x0b,0x10,0x10}, {0x0b,0x0f,0x10}, {0x0b,0x0d,0x10}, {0x0b,0x0c,0x10}, - {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00}, {0x00,0x00,0x00} -}; - -static Bit8u FindVideoMode(Bit8u mode) { - Bit8u line=0xff; - for(Bit8u i=0;i<=MODE_MAX;i++) { - if(vga_modes[i].svgamode==mode) { - line=i; - break; - } - } - return line; - -} - -VGAMODES * GetCurrentMode(void) { - Bit8u mode=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)&127; - if (mode==int10.mode) return int10.entry; - int10.mode=mode; - int10.entry=&vga_modes[FindVideoMode(mode)]; - return int10.entry; -} +bool INT10_SetVideoMode(Bitu mode) { -void INT10_SetVideoMode(Bit8u mode) { - - bool clearmem=(mode & 128)==0; - Bit8u *palette; - Bit16u i,twidth,theight,cheight; + bool clearmem=true; Bit8u modeset_ctl,video_ctl,vga_switches; Bit16u crtc_addr; - Bit8u line; - mode&=mode & 127; - line=FindVideoMode(mode); - if (line==0xff) { - LOG(LOG_INT10,LOG_ERROR)("INT10:Trying to set non supported video mode %X",mode); - return; + if (mode<256) { + if (mode & 128) { + clearmem=false; + mode-=128; + } + } else { + /* Check for special vesa mode bits */ + mode&=0xfff; } - - twidth=vga_modes[line].twidth; - theight=vga_modes[line].theight; - cheight=vga_modes[line].cheight; - - // Read the bios vga control + LOG(LOG_INT10,LOG_NORMAL)("Set Video Mode %X",mode); + Bitu i=0; + while (ModeList[i].mode!=0xffff) { + if (ModeList[i].mode==mode) goto foundmode; + i++; + } + LOG(LOG_INT10,LOG_ERROR)("Trying to set illegal mode %X",mode); + return false; +foundmode: + CurMode=&ModeList[i]; + + /* First read mode setup settings from bios area */ video_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL); - - // Read the bios vga switches vga_switches=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES); - - // Read the bios mode set control modeset_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); + /* Setup the VGA to the correct mode */ + VGA_SetMode(CurMode->type); - - /* Reset Attribute ctl into address mode just to be safe */ - - IO_Read(VGAREG_ACTL_RESET); - // Set the High Attribute Ctl - for(i=0x10;i<=ACTL_MAX_REG;i++) { - IO_Write(VGAREG_ACTL_ADDRESS,(Bit8u)i); - IO_Write(VGAREG_ACTL_WRITE_DATA,actl_regs[vga_modes[line].actlmodel][i]); + /* Setup MISC Output Register */ + Bit8u misc_output=0x3; //Color and cpu memory access + /* Program Sequencer */ + Bit8u seq_data[SEQ_REGS]; + memset(seq_data,0,SEQ_REGS); + seq_data[1]|=1; //8 dot fonts by default + seq_data[1]|= //Check for half clock + (CurMode->special & _HALF_CLOCK) ? 0x08 : 0x00; + seq_data[4]|=0x02; //More than 64kb + switch (CurMode->type) { + case M_TEXT16: + seq_data[2]|=0x3; //Enable plane 0 and 1 + seq_data[4]|=0x05; //Alpanumeric and odd/even enabled + break; + case M_EGA16: + seq_data[2]|=0xf; //Enable all planes for writing + break; + case M_LIN8: //Seems to have the same reg layout from testing + case M_VGA: + seq_data[2]|=0xf; //Enable all planes for writing + seq_data[4]|=0xc; //Graphics - odd/even - Chained + break; } - // Set Sequencer Ctl - for(i=0;i<=SEQU_MAX_REG;i++) { - IO_Write(VGAREG_SEQU_ADDRESS,(Bit8u)i); - IO_Write(VGAREG_SEQU_DATA,sequ_regs[vga_modes[line].sequmodel][i]); + for (i=0;ihtotal-5); + hor_overflow|=((CurMode->htotal-5) & 0x100) >> 8; + /* Horizontal Display End */ + IO_Write(0x3d4,0x01);IO_Write(0x3d5,CurMode->hdispend-1); + hor_overflow|=((CurMode->hdispend-1) & 0x100) >> 7; + /* Start horizontal Blanking */ + IO_Write(0x3d4,0x02);IO_Write(0x3d5,CurMode->hdispend); + hor_overflow|=((CurMode->hdispend) & 0x100) >> 6; + /* End horizontal Blanking */ + Bitu blank_end; + if (CurMode->special & _HALF_CLOCK) { + blank_end = (CurMode->htotal-1) & 0x7f; + } else { + blank_end = (CurMode->htotal-2) & 0x7f; } + IO_Write(0x3d4,0x03);IO_Write(0x3d5,0x80|(blank_end & 0x1f)); +// hor_overflow|=(blank_end & 0x40) >> 3; - // Set the misc register - IO_Write(VGAREG_WRITE_MISC_OUTPUT,vga_modes[line].miscreg); - - // Enable video - IO_Write(VGAREG_ACTL_ADDRESS,0x20); - IO_Read(VGAREG_ACTL_RESET); - - //Set the palette - if ((modeset_ctl&0x08)==0x8) LOG(LOG_INT10,LOG_NORMAL)("Mode set without palette"); - if((modeset_ctl&0x08)==0) { - // Set the PEL mask - IO_Write(VGAREG_PEL_MASK,vga_modes[line].pelmask); - // Set the whole dac always, from 0 - IO_Write(VGAREG_DAC_WRITE_ADDRESS,0x00); - // From which palette - switch(vga_modes[line].dacmodel) { - case 0: - palette=(Bit8u*)&palette0; - break; - case 1: - palette=(Bit8u*)&palette1; - break; - case 2: - palette=(Bit8u*)&palette2; - break; - case 3: - palette=(Bit8u*)&palette3; - break; - default: - palette=(Bit8u*)&palette0;/*for gcc*/ - E_Exit("INT10: palette error in setvidmode"); - break; - } - // Set the actual palette - for (i=0;i<256;i++) { - if (i<=dac_regs[vga_modes[line].dacmodel]) { - IO_Write(VGAREG_DAC_DATA,palette[(i*3)+0]); - IO_Write(VGAREG_DAC_DATA,palette[(i*3)+1]); - IO_Write(VGAREG_DAC_DATA,palette[(i*3)+2]); - } else { - IO_Write(VGAREG_DAC_DATA,0); - IO_Write(VGAREG_DAC_DATA,0); - IO_Write(VGAREG_DAC_DATA,0); - } - } + /* Start Horizontal Retrace */ + Bitu ret_start; + if (CurMode->special & _HALF_CLOCK) { + ret_start = (CurMode->hdispend+2); + } else { + ret_start = (CurMode->hdispend+4); } - - IO_Read(VGAREG_ACTL_RESET); - // Set the Low Attribute Ctl - for(i=0;i<=0xf;i++) { - IO_Write(VGAREG_ACTL_ADDRESS,(Bit8u)i); - IO_Write(VGAREG_ACTL_WRITE_DATA,actl_regs[vga_modes[line].actlmodel][i]); + IO_Write(0x3d4,0x04);IO_Write(0x3d5,ret_start); + hor_overflow|=(ret_start & 0x100) >> 4; + /* End Horizontal Retrace */ + Bitu ret_end; + if (CurMode->special & _HALF_CLOCK) { + ret_end = (CurMode->htotal-2) & 0x3f; + } else { + ret_end = (CurMode->htotal-4) & 0x3f; } + IO_Write(0x3d4,0x05);IO_Write(0x3d5,(ret_end & 0x1f) | (blank_end & 0x20) << 2); +// hor_overflow|=(ret_end & 0x20); +//TODO Be sure about these ending values in extended overflow of s3 + + /* Vertical Total */ + IO_Write(0x3d4,0x06);IO_Write(0x3d5,(CurMode->vtotal-2)); + overflow|=((CurMode->vtotal-2) & 0x100) >> 8; + overflow|=((CurMode->vtotal-2) & 0x200) >> 4; + ver_overflow|=((CurMode->vtotal-2) & 0x400) >> 10; +/* + These aren't exactly accurate i think, + Should be more like a certain percentage based on vertical total + So you get same sized borders, but okay :) + */ + /* Vertical Retrace Start */ + IO_Write(0x3d4,0x10);IO_Write(0x3d5,(CurMode->vdispend+12)); + overflow|=((CurMode->vdispend+12) & 0x100) >> 6; + overflow|=((CurMode->vdispend+12) & 0x200) >> 2; + ver_overflow|=((CurMode->vdispend+12) & 0x400) >> 6; + /* Vertical Retrace End */ + IO_Write(0x3d4,0x11);IO_Write(0x3d5,(CurMode->vdispend+14) & 0xF); + + /* Vertical Display End */ + IO_Write(0x3d4,0x12);IO_Write(0x3d5,(CurMode->vdispend-1)); + overflow|=((CurMode->vdispend-1) & 0x100) >> 7; + overflow|=((CurMode->vdispend-1) & 0x200) >> 3; + ver_overflow|=((CurMode->vdispend-1) & 0x400) >> 9; - Bit32u tel; - if(clearmem) { - if(vga_modes[line].type==TEXT) { - PhysPt dest=PhysMake(vga_modes[line].sstart,0); - for (tel=0;tel<0x4000;tel++) { - mem_writew(dest,0x0720); - dest+=2; + /* Vertical Blank Start */ + IO_Write(0x3d4,0x15);IO_Write(0x3d5,(CurMode->vdispend+8)); + overflow|=((CurMode->vdispend+8) & 0x100) >> 5; + max_scanline|=((CurMode->vdispend+8) & 0x200) >> 3; + ver_overflow|=((CurMode->vdispend+8) & 0x400) >> 8; + /* Vertical Retrace End */ + IO_Write(0x3d4,0x16);IO_Write(0x3d5,(CurMode->vtotal-8)); + /* Line Compare */ + Bitu line_compare=CurMode->vtotal+1; //Out of range + IO_Write(0x3d4,0x18);IO_Write(0x3d5,line_compare&0xff); + overflow|=(line_compare & 0x100) >> 4; + max_scanline|=(line_compare & 0x200) >> 3; + ver_overflow|=(line_compare & 0x400) >> 4; + Bit8u underline=0; + /* Maximum scanline / Underline Location */ + if (CurMode->special & _LINE_DOUBLE) max_scanline|=0x80; + switch (CurMode->type) { + case M_TEXT16: + max_scanline|=CurMode->theight-1; + underline=0x1f; + break; + case M_VGA: + underline=0x40; + max_scanline|=1; //Vga doesn't use double line but this + break; + case M_LIN8: + underline=0x60; //Seems to enable the every 4th clock on my s3 + break; + } + IO_Write(0x3d4,0x09);IO_Write(0x3d5,max_scanline); + IO_Write(0x3d4,0x14);IO_Write(0x3d5,underline); + + /* OverFlow */ + IO_Write(0x3d4,0x07);IO_Write(0x3d5,overflow); + /* Extended Horizontal Overflow */ + IO_Write(0x3d4,0x5d);IO_Write(0x3d5,hor_overflow); + /* Extended Vertical Overflow */ + IO_Write(0x3d4,0x5e);IO_Write(0x3d5,ver_overflow); + /* Offset Register */ + IO_Write(0x3d4,0x13); + switch (CurMode->type) { + case M_LIN8: + IO_Write(0x3d5,CurMode->swidth/8); + break; + default: + IO_Write(0x3d5,CurMode->hdispend/2); + } + /* Mode Control */ + Bit8u mode_control=0; + switch (CurMode->type) { + case M_CGA4: + case M_CGA2: + mode_control=0xa2; + break; + case M_EGA16: + mode_control=0xe3; + break; + case M_TEXT16: + case M_VGA: + mode_control=0xa3; + break; + case M_LIN8: + mode_control=0xab; + break; + + } + IO_Write(0x3d4,0x17);IO_Write(0x3d5,mode_control); + /* Renable write protection */ + IO_Write(0x3d4,0x11); + IO_Write(0x3d5,IO_Read(0x3d5)|0x80); + /* Setup the correct clock */ + if (CurMode->mode<0x100) { + //Stick to 25mhz clock for now + } else { + misc_output|=0xef; //Select clock 3 + Bitu clock=CurMode->vtotal*8*CurMode->htotal*70; + VGA_SetClock(3,clock/1000); + } + /* Write Misc Output */ + IO_Write(0x3c2,misc_output); + + /* Program Graphics controller */ + Bit8u gfx_data[GFX_REGS]; + memset(gfx_data,0,GFX_REGS); + gfx_data[0x7]=0xf; /* Color don't care */ + gfx_data[0x8]=0xff; /* BitMask */ + switch (CurMode->type) { + case M_TEXT16: + gfx_data[0x5]|=0x10; //Odd-Even Mode + gfx_data[0x6]|=0x0e; //alphanumeric mode at 0xb800=0xbffff + break; + case M_LIN8: + case M_VGA: + gfx_data[0x5]|=0x40; //256 color mode + gfx_data[0x6]|=0x05; //graphics mode at 0xa000-affff + break; + case M_EGA16: + gfx_data[0x6]|=0x05; //graphics mode at 0xa000-affff + break; + case M_CGA4: + gfx_data[0x5]|=0x20; //CGA mode + gfx_data[0x6]|=0x05; //graphics mode at 0xa000-affff + break; + } + for (i=0;itype) { + case M_EGA16: + if (CurMode->mode>0xe) goto att_text16; + case M_TANDY16: + att_data[0x10]=0x01; //Color Graphics + for (i=0;i<8;i++) { + att_data[i]=i; + att_data[i+8]=i+0x10; + } + break; + case M_TEXT16: + att_data[0x13]=0x08; //Pel panning on 8, although we don't have 9 dot text mode + att_data[0x10]=0x0C; //Color Text with blinking +att_text16: + for (i=0;i<8;i++) { + att_data[i]=i; + att_data[i+8]=i+0x38; + } + break; + case M_CGA2: + case M_CGA4: + IO_Write(0x3d9,0x20); //Setup using CGA color select register + goto skipatt; + case M_VGA: + case M_LIN8: + for (i=0;i<16;i++) { + att_data[i]=i; + } + att_data[0x10]=0x41; //Color Graphics 8-bit + break; + } + + IO_Read(0x3da); + for (i=0;itype) { + case M_EGA16: + if (CurMode->mode>0xe) goto dac_text16; + case M_CGA2: + case M_CGA4: + case M_TANDY16: + for (i=0;i<64;i++) { + IO_Write(0x3c9,ega_palette[i][0]); + IO_Write(0x3c9,ega_palette[i][1]); + IO_Write(0x3c9,ega_palette[i][2]); + } + break; + case M_TEXT16: +dac_text16: + for (i=0;i<64;i++) { + IO_Write(0x3c9,text_palette[i][0]); + IO_Write(0x3c9,text_palette[i][1]); + IO_Write(0x3c9,text_palette[i][2]); + } + break; + case M_VGA: + case M_LIN8: + for (i=0;i<256;i++) { + IO_Write(0x3c9,vga_palette[i][0]); + IO_Write(0x3c9,vga_palette[i][1]); + IO_Write(0x3c9,vga_palette[i][2]); + } + break; + } + /* Setup registers for special video modes */ + switch (CurMode->type) { + case M_TANDY16: + IO_Write(0x3df,0x80); //Enter 32k mode and banks on 0 + break; + } + /* Setup some remaining S3 registers */ + + IO_Write(0x3d4,0x31);IO_Write(0x3d5,0x9); //Enable banked memory and 256k+ access + IO_Write(0x3d4,0x58);IO_Write(0x3d5,0x3); //Enable 8 mb of linear addressing + IO_Write(0x3d4,0x38);IO_Write(0x3d5,0x48); //Register lock 1 + IO_Write(0x3d4,0x39);IO_Write(0x3d5,0xa5); //Register lock 2 + + /* Load text mode font */ + if (CurMode->type==M_TEXT16) { + INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); + } + /* Clear video memory if needs be */ + if (clearmem) { + switch (CurMode->type) { + case M_CGA4: + case M_CGA2: + for (i=0;i<16*1024;i++) { + real_writew(0xb800,i*2,0x0000); } - } else { - PhysPt dest=PhysMake(0xb800,0); - for (tel=0;tel<0x4000;tel++) { - mem_writew(dest,0x0000); - dest+=2; + break; + case M_TEXT16: + for (i=0;i<16*1024;i++) { + real_writew(0xb800,i*2,0x0700); } - dest=PhysMake(0xa000,0); - for (tel=0;tel<0x8000;tel++) { - mem_writew(dest,0x0000); - dest+=2; + break; + case M_EGA16: + case M_VGA: + for (i=0;i<64*1024;i++) { + real_writeb(0xa000,i,0x00); } - // FIXME should handle gfx mode + break; } } - // Set the BIOS mem - real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode|((!clearmem) << 7)); - real_writew(BIOSMEM_SEG,BIOSMEM_NB_COLS,twidth); - real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,vga_modes[line].slength); + /* Setup the CRTC Address */ + + crtc_addr=0x3d4; + + /* Setup the BIOS */ + if (mode<128) real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode); + else real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode-0x98); //Looks like the s3 bios + real_writew(BIOSMEM_SEG,BIOSMEM_NB_COLS,CurMode->twidth); + real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,CurMode->plength); real_writew(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_addr); - real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,theight-1); - real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,cheight); + real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,CurMode->theight-1); + real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,CurMode->cheight); real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem << 7))); real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0x09); real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); @@ -368,27 +491,23 @@ void INT10_SetVideoMode(Bit8u mode) { real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x00); // Unavailable on vanilla vga, but... // Set cursor shape - if(vga_modes[line].type==TEXT) { -//TODO cursor shape biosfn_set_cursor_shape(0x06,0x07); + if(CurMode->type==M_TEXT16) { + INT10_SetCursorShape(0x06,07); } // Set cursor pos for page 0..7 for(i=0;i<8;i++) INT10_SetCursorPos(0,0,(Bit8u)i); // Set active page 0 INT10_SetActivePage(0); /* Set some interrupt vectors */ - RealSetVec(0x43,int10_romarea.font_8_first); + switch (CurMode->cheight) { + case 8:RealSetVec(0x43,int10.rom.font_8_first);break; + case 14:RealSetVec(0x43,int10.rom.font_14);break; + case 16:RealSetVec(0x43,int10.rom.font_16);break; + } /* Tell mouse resolution change */ - Mouse_SetResolution(vga_modes[line].swidth,vga_modes[line].sheight); -}; + Mouse_NewVideoMode(); + return true; +} + + -void INT10_SetGfxControllerToDefault() -// reset gfx controller to default values -// needed for drawing mouse pointer -{ - Bit8u line=FindVideoMode(real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)&127); - // Set Grafx Ctl - for(Bit8u i=0;i<=GRDC_MAX_REG;i++) { - IO_Write(VGAREG_GRDC_ADDRESS,(Bit8u)i); - IO_Write(VGAREG_GRDC_DATA,grdc_regs[vga_modes[line].grdcmodel][i]); - } -}; \ No newline at end of file diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index c73553a4..2563e30b 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -29,6 +29,7 @@ void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val) { IO_Write(VGAREG_ACTL_ADDRESS,reg); IO_Write(VGAREG_ACTL_WRITE_DATA,val); } + IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette } @@ -36,6 +37,7 @@ void INT10_SetOverscanBorderColor(Bit8u val) { IO_Read(VGAREG_ACTL_RESET); IO_Write(VGAREG_ACTL_ADDRESS,0x11); IO_Write(VGAREG_ACTL_WRITE_DATA,val); + IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette } void INT10_SetAllPaletteRegisters(PhysPt data) { @@ -49,6 +51,7 @@ void INT10_SetAllPaletteRegisters(PhysPt data) { // Then the border IO_Write(VGAREG_ACTL_ADDRESS,0x11); IO_Write(VGAREG_ACTL_WRITE_DATA,mem_readb(data)); + IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette } void INT10_ToggleBlinkingBit(Bit8u state) { @@ -64,19 +67,20 @@ void INT10_ToggleBlinkingBit(Bit8u state) { IO_Read(VGAREG_ACTL_RESET); IO_Write(VGAREG_ACTL_ADDRESS,0x10); IO_Write(VGAREG_ACTL_WRITE_DATA,value); + IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette } void INT10_GetSinglePaletteRegister(Bit8u reg,Bit8u * val) { if(reg<=ACTL_MAX_REG) { IO_Read(VGAREG_ACTL_RESET); - IO_Write(VGAREG_ACTL_ADDRESS,reg); + IO_Write(VGAREG_ACTL_ADDRESS,reg+32); *val=IO_Read(VGAREG_ACTL_READ_DATA); } } void INT10_GetOverscanBorderColor(Bit8u * val) { IO_Read(VGAREG_ACTL_RESET); - IO_Write(VGAREG_ACTL_ADDRESS,0x11); + IO_Write(VGAREG_ACTL_ADDRESS,0x11+32); *val=IO_Read(VGAREG_ACTL_READ_DATA); } @@ -89,7 +93,7 @@ void INT10_GetAllPaletteRegisters(PhysPt data) { data++; } // Then the border - IO_Write(VGAREG_ACTL_ADDRESS,0x11); + IO_Write(VGAREG_ACTL_ADDRESS,0x11+32); mem_writeb(data,IO_Read(VGAREG_ACTL_READ_DATA)); } @@ -123,4 +127,46 @@ void INT10_GetDACBlock(Bit16u index,Bit16u count,PhysPt data) { mem_writeb(data++,IO_Read(VGAREG_DAC_DATA)); mem_writeb(data++,IO_Read(VGAREG_DAC_DATA)); } -}; +} + +void INT10_SelectDACPage(Bit8u function,Bit8u mode) { + IO_Read(VGAREG_ACTL_RESET); + IO_Write(VGAREG_ACTL_ADDRESS,0x10); + Bit8u old10=IO_Read(VGAREG_ACTL_READ_DATA); + if (!function) { //Select paging mode + if (mode) old10|=0x80; + else old10&=0x7f; + IO_Write(VGAREG_ACTL_ADDRESS,0x10); + IO_Write(VGAREG_ACTL_WRITE_DATA,old10); + } else { //Select page + if (!(old10 & 0x80)) mode<<=2; + mode&=0xf; + IO_Write(VGAREG_ACTL_ADDRESS,0x14); + IO_Write(VGAREG_ACTL_WRITE_DATA,mode); + } + IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette +} + +void INT10_SetPelMask(Bit8u mask) { + IO_Write(VGAREG_PEL_MASK,mask); +} + +void INT10_GetPelMask(Bit8u & mask) { + mask=IO_Read(VGAREG_PEL_MASK); +} + + +void INT10_SetBackgroundBorder(Bit8u val) { +//TODO Detect if we're CGA? + Bit8u old=IO_Read(0x3d9) & 0xf0; + old|=val & 0xf; + IO_Write(0x3d9,old); +} + +void INT10_SetColorSelect(Bit8u val) { +//TODO Detect if we're CGA? + Bit8u old=IO_Read(0x3d9) & ~0x20; + old|=(val & 1) << 5; + IO_Write(0x3d9,old); +} + diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 22e40ac2..efa0a336 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -25,9 +25,8 @@ static Bit8u cga_masks[4]={~192,~48,~12,~3}; static Bit8u cga_masks2[8]={~128,~64,~32,~16,~8,~4,~2,~1}; void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { - VGAMODES * curmode=GetCurrentMode(); - switch (curmode->memmodel) { - case CGA: + switch (CurMode->type) { + case M_CGA4: { Bit16u off=(y>>1)*80+(x>>2); if (y&1) off+=8*1024; @@ -41,7 +40,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { real_writeb(0xb800,off,old); } break; - case CGA2: + case M_CGA2: { Bit16u off=(y>>1)*80+(x>>3); if (y&1) off+=8*1024; @@ -55,7 +54,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { real_writeb(0xb800,off,old); } break; - case PLANAR4: + case M_EGA16: { /* Set the correct bitmask for the pixel position */ IO_Write(0x3ce,0x8);Bit8u mask=128>>(x&7);IO_Write(0x3cf,mask); @@ -67,7 +66,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { if (color & 0x80) { IO_Write(0x3ce,0x3);IO_Write(0x3cf,0x18); } //Perhaps also set mode 1 /* Calculate where the pixel is in video memory */ - PhysPt off=0xa0000+curmode->slength*page+((y*curmode->swidth+x)>>3); + PhysPt off=0xa0000+CurMode->plength*page+((y*CurMode->swidth+x)>>3); /* Bitmask and set/reset should do the rest */ mem_readb(off); mem_writeb(off,0xff); @@ -78,23 +77,18 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { if (color & 0x80) { IO_Write(0x3ce,0x3);IO_Write(0x3cf,0x0); } break; } - case LINEAR8: + case M_VGA: mem_writeb(Real2Phys(RealMake(0xa000,y*320+x)),color); break; - case PLANAR1: - case PLANAR2: - case CTEXT: - case MTEXT: default: - LOG(LOG_INT10,LOG_ERROR)("PutPixel Unhandled memory model %d",curmode->memmodel); + LOG(LOG_INT10,LOG_ERROR)("PutPixel unhandled mode type %d",CurMode->type); break; } } void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { - VGAMODES * curmode=GetCurrentMode(); - switch (curmode->memmodel) { - case CGA: + switch (CurMode->type) { + case M_CGA4: { Bit16u off=(y>>1)*80+(x>>2); if (y&1) off+=8*1024; @@ -102,7 +96,7 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { *color=(val>>(((3-x&3))*2)) & 3 ; } break; - case CGA2: + case M_CGA2: { Bit16u off=(y>>1)*80+(x>>3); if (y&1) off+=8*1024; @@ -110,10 +104,10 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { *color=(val>>(((7-x&7)))) & 1 ; } break; - case PLANAR4: + case M_EGA16: { /* Calculate where the pixel is in video memory */ - PhysPt off=0xa0000+curmode->slength*page+((y*curmode->swidth+x)>>3); + PhysPt off=0xa0000+CurMode->plength*page+((y*CurMode->swidth+x)>>3); Bitu shift=7-(x & 7); /* Set the read map */ *color=0; @@ -127,15 +121,11 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { *color|=((mem_readb(off)>>shift) & 1) << 3; break; } - case LINEAR8: + case M_VGA: *color=mem_readb(PhysMake(0xa000,320*y+x)); break; - case PLANAR1: - case PLANAR2: - case CTEXT: - case MTEXT: default: - LOG(LOG_INT10,LOG_ERROR)("GetPixel Unhandled memory model %d",curmode->memmodel); + LOG(LOG_INT10,LOG_ERROR)("GetPixel unhandled mode type %d",CurMode->type); break; } } From 3f5aecccf27d8f368482bf12f28bcc9104edcd7d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 15 Jun 2003 19:38:47 +0000 Subject: [PATCH 0981/4131] VESA Routines. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1061 --- src/ints/int10_vesa.cpp | 298 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 src/ints/int10_vesa.cpp diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp new file mode 100644 index 00000000..029bcb3f --- /dev/null +++ b/src/ints/int10_vesa.cpp @@ -0,0 +1,298 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include + +#include "dosbox.h" +#include "callback.h" +#include "regs.h" +#include "mem.h" +#include "inout.h" +#include "int10.h" +#include "dos_inc.h" + +static struct { + Bitu setwindow; +} callback; + + +#ifdef _MSC_VER +#pragma pack (1) +#endif +struct MODE_INFO{ + Bit16u ModeAttributes; + Bit8u WinAAttributes; + Bit8u WinBAttributes; + Bit16u WinGranularity; + Bit16u WinSize; + Bit16u WinASegment; + Bit16u WinBSegment; + Bit32u WinFuncPtr; + Bit16u BytesPerScanLine; + Bit16u XResolution; + Bit16u YResolution; + Bit8u XCharSize; + Bit8u YCharSize; + Bit8u NumberOfPlanes; + Bit8u BitsPerPixel; + Bit8u NumberOfBanks; + Bit8u MemoryModel; + Bit8u BankSize; + Bit8u NumberOfImagePages; + Bit8u Reserved_page; + Bit8u RedMaskSize; + Bit8u RedMaskPos; + Bit8u GreenMaskSize; + Bit8u GreenMaskPos; + Bit8u BlueMaskSize; + Bit8u BlueMaskPos; + Bit8u ReservedMaskSize; + Bit8u ReservedMaskPos; + Bit8u DirectColorModeInfo; + Bit32u PhysBasePtr; + Bit32u OffScreenMemOffset; + Bit16u OffScreenMemSize; + Bit8u Reserved[206]; +} GCC_ATTRIBUTE(packed); +#ifdef _MSC_VER +#pragma pack() +#endif + + + +Bit8u VESA_GetSVGAInformation(Bit16u seg,Bit16u off) { + /* Fill 256 byte buffer with VESA information */ + PhysPt buffer=PhysMake(seg,off); + Bitu i; + bool vbe2=false; + if (mem_readd(buffer)==0x32454256) vbe2=true; + if (vbe2) { + for (i=0;i<0x200;i++) mem_writeb(buffer+i,0); + } else { + for (i=0;i<0x100;i++) mem_writeb(buffer+i,0); + } + /* Fill common data */ + MEM_BlockWrite(buffer,"VESA",4); //Identification + mem_writew(buffer+0x04,0x102); //Vesa version + mem_writed(buffer+0x06,int10.rom.oemstring); //Oemstring + mem_writed(buffer+0x0a,0x0); //Capabilities and flags + mem_writed(buffer+0x0e,int10.rom.vesa_modes); //VESA Mode list + mem_writew(buffer+0x12,32); //32 64kb blocks for 2 mb memory + return 0x00; +} + + + +Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off) { + MODE_INFO minfo; + memset(&minfo,0,sizeof(minfo)); + PhysPt buf=PhysMake(seg,off); + + Bitu i=0; + if (mode<0x100) return 0x01; + while (ModeList[i].mode!=0xffff) { + if (mode==ModeList[i].mode) goto foundit; else i++; + } + return 0x01; +foundit: + VideoModeBlock * mblock=&ModeList[i]; + switch (mblock->type) { + case M_LIN8: //Linear 8-bit + WLE(minfo.ModeAttributes,0x1b); //No bios output support, although would be easy + WLE(minfo.WinAAttributes,0x7); //Exists/readable/writable + WLE(minfo.WinGranularity,64); + WLE(minfo.WinSize,64); + WLE(minfo.WinASegment,0xa000); + WLE(minfo.WinBSegment,0xa000); + WLE(minfo.WinFuncPtr,CALLBACK_RealPointer(callback.setwindow)); + WLE(minfo.BytesPerScanLine,mblock->swidth); + WLE(minfo.NumberOfPlanes,0x1); + WLE(minfo.BitsPerPixel,0x08); + WLE(minfo.NumberOfBanks,0x1); + WLE(minfo.MemoryModel,0x04); //packed pixel + WLE(minfo.NumberOfImagePages,0x05); + WLE(minfo.Reserved_page,0x1); + break; + } + WLE(minfo.XResolution,mblock->swidth); + WLE(minfo.YResolution,mblock->sheight); + WLE(minfo.XCharSize,mblock->cwidth); + WLE(minfo.YCharSize,mblock->cheight); + MEM_BlockWrite(buf,&minfo,sizeof(MODE_INFO)); + return 0x00; +} + + +Bit8u VESA_SetSVGAMode(Bit16u mode) { + if (INT10_SetVideoMode(mode)) return 0x00; + return 0x01; +}; + +Bit8u VESA_GetSVGAMode(Bit16u & mode) { + mode=CurMode->mode; + return 0x00; +} + +Bit8u VESA_SetCPUWindow(Bit8u window,Bit16u address) { + if (!window && (address<32)) { + IO_Write(0x3d4,0x6a); + IO_Write(0x3d5,(Bit8u)address); + return 0x0; + } else return 0x1; +} + +Bit8u VESA_GetCPUWindow(Bit8u window,Bit16u & address) { + if (!window) { + IO_Write(0x3d4,0x6a); + address=IO_Read(0x3d5); + return 0x0; + } else return 0x1; +} + + +Bit8u VESA_SetPalette(PhysPt data,Bitu index,Bitu count) { + if (index>255) return 0x1; + if (index+count>256) return 0x1; + IO_Write(0x3c8,index); + while (count) { + IO_Write(0x3c9,mem_readb(data++)); + IO_Write(0x3c9,mem_readb(data++)); + IO_Write(0x3c9,mem_readb(data++)); + data++; + count--; + } + return 0x00; +} + + +Bit8u VESA_GetPalette(PhysPt data,Bitu index,Bitu count) { + if (index>255) return 0x1; + if (index+count>256) return 0x1; + IO_Write(0x3c7,index); + while (count) { + mem_writeb(data++,IO_Read(0x3c9)); + mem_writeb(data++,IO_Read(0x3c9)); + mem_writeb(data++,IO_Read(0x3c9)); + data++; + count--; + } + return 0x00; +} + + +Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u & bytes,Bit16u & pixels,Bit16u & lines) { + Bit8u bpp; + switch (CurMode->type) { + case M_LIN8: + bpp=1;break; + default: + return 0x1; + } + Bitu scan_len; + lines=0xfff; //Does anyone care? + switch (subcall) { + case 0x00: /* Set in pixels */ + bytes=(pixels*bpp); + case 0x02: /* Set in bytes */ + scan_len=bytes/4; + if (bytes % 4) scan_len++; + vga.config.scan_len=scan_len; + VGA_StartResize(); + break; + case 0x03: /* Get maximum */ + bytes=0x400*4; + pixels=bytes/bpp; + return 0x00; + case 0x01: /* Get lengths */ + break; + default: + return 0x1; //Illegal call + } + /* Write the scan line to video card the simple way */ + pixels=(vga.config.scan_len*4)/bpp; + bytes=vga.config.scan_len*4; + return 0x0; +} + +Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y) { + //TODO Maybe do things differently with lowres double line modes? + Bitu start; + switch (CurMode->type) { + case M_LIN8: + start=vga.config.scan_len*4*y+x; + vga.config.display_start=start/4; + IO_Read(0x3da); + IO_Write(0x3c0,0x13+32); + IO_Write(0x3c0,(start % 4)*2); + break; + default: + return 0x1; + } + return 0x00; +} + +Bit8u VESA_GetDisplayStart(Bit16u & x,Bit16u & y) { + Bitu times=vga.config.display_start/(vga.config.scan_len*4); + Bitu rem=vga.config.display_start % (vga.config.scan_len*4); + Bitu pan=vga.config.pel_panning; + switch (CurMode->type) { + case M_LIN8: + y=times; + x=rem*4+pan; + break; + default: + return 0x1; + } + return 0x00; + + +} + + +static char oemstring[]="S3 Incorporated. Trio64"; + +static Bitu SetWindowPositionHandler(void) { + VESA_SetCPUWindow(reg_bl,reg_dx); + return 0; +} + + +void INT10_SetupVESA(void) { + /* Put the mode list somewhere in memory */ + Bitu i; + i=0; + int10.rom.vesa_modes=RealMake(0xc000,int10.rom.used); +//TODO Maybe add normal vga modes too, but only seems to complicate things + while (ModeList[i].mode!=0xffff) { + if (ModeList[i].mode>=0x100){ + real_writew(0xc000,int10.rom.used,ModeList[i].mode); + int10.rom.used+=2; + } + i++; + } + real_writew(0xc000,int10.rom.used,0xffff); + int10.rom.used+=2; + int10.rom.oemstring=RealMake(0xc000,int10.rom.used); + Bitu len=strlen(oemstring)+1; + MEM_BlockWrite(PhysMake(0xc000,int10.rom.used),oemstring,len); + int10.rom.used+=len; + callback.setwindow=CALLBACK_Allocate(); + CALLBACK_Setup(callback.setwindow,SetWindowPositionHandler,CB_RETF); + +} \ No newline at end of file From e8892d4f61b631f9810580500090a1607ebb065c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 15 Jun 2003 19:39:21 +0000 Subject: [PATCH 0982/4131] Removed hack for setting limits -1 Small change for handling the mouse cursor in graphics mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1062 --- src/ints/mouse.cpp | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 1788e353..5f24a7dc 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -181,18 +181,19 @@ void SaveVgaRegisters() for (int i=0; i<9; i++) { IO_Write (0x3CE,i); gfxReg[i] = IO_Read(0x3CF); - }; - // Set default - INT10_SetGfxControllerToDefault(); -}; + } + /* Setup some default values in GFX regs that should work */ + IO_Write (0x3CE,3);IO_Write(0x3Cf,0); //disable rotate and operation + IO_Write (0x3CE,5);IO_Write(0x3Cf,0); //Force read/write mode 0 +} void RestoreVgaRegisters() { for (int i=0; i<9; i++) { IO_Write(0x3CE,i); IO_Write(0x3CF,gfxReg[i]); - }; -}; + } +} void ClipCursorArea(Bit16s& x1, Bit16s& x2, Bit16s& y1, Bit16s& y2, Bit16u& addx1, Bit16u& addx2, Bit16u& addy) { @@ -253,17 +254,15 @@ void DrawCursor() { if (mouse.shown<0) return; // Get Clipping ranges - VGAMODES * curmode=GetCurrentMode(); - if (!curmode) return; - + // In Textmode ? - if (curmode->type==TEXT) { + if (CurMode->type==M_TEXT16) { DrawCursorText(); return; } - mouse.clipx = curmode->swidth-1; - mouse.clipy = curmode->sheight-1; + mouse.clipx = CurMode->swidth-1; + mouse.clipy = CurMode->sheight-1; RestoreCursorBackground(); @@ -389,10 +388,10 @@ static void SetMickeyPixelRate(Bit16s px, Bit16s py) } }; -void Mouse_SetResolution(Bit16u width, Bit16u height) +void Mouse_NewVideoMode(void) { mouse.shown = -1; // hide cursor -}; +} static void mouse_reset(void) { @@ -471,9 +470,8 @@ static Bitu INT33_Handler(void) { break; case 0x02: /* Hide Mouse */ { - VGAMODES * curmode=GetCurrentMode(); - if (curmode && curmode->type==GRAPH) RestoreCursorBackground(); - else RestoreCursorBackgroundText(); + if (CurMode->type!=M_TEXT16) RestoreCursorBackground(); + else RestoreCursorBackgroundText(); mouse.shown--; } break; @@ -514,7 +512,6 @@ static Bitu INT33_Handler(void) { Bits max,min; if ((Bit16s)reg_cx<(Bit16s)reg_dx) { min=(Bit16s)reg_cx;max=(Bit16s)reg_dx;} else { min=(Bit16s)reg_dx;max=(Bit16s)reg_cx;} - if (!(max & 1)) max--; mouse.min_x=min; mouse.max_x=max; LOG(LOG_MOUSE,LOG_NORMAL)("Define Hortizontal range min:%d max:%d",min,max); @@ -525,7 +522,6 @@ static Bitu INT33_Handler(void) { Bits max,min; if ((Bit16s)reg_cx<(Bit16s)reg_dx) { min=(Bit16s)reg_cx;max=(Bit16s)reg_dx;} else { min=(Bit16s)reg_dx;max=(Bit16s)reg_cx;} - if (!(max & 1)) max--; mouse.min_y=min; mouse.max_y=max; LOG(LOG_MOUSE,LOG_NORMAL)("Define Vertical range min:%d max:%d",min,max); @@ -630,6 +626,7 @@ static Bitu INT74_Handler(void) { } } IO_Write(0xa0,0x20); + IO_Write(0x20,0x20); /* Check for more Events if so reactivate IRQ */ if (mouse.events) { PIC_ActivateIRQ(12); From c908fa9a094621fa42e53a4be6728297a54d9d92 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 15 Jun 2003 19:44:58 +0000 Subject: [PATCH 0983/4131] SVGA support by emulating an S3/trio 64 card with 2 mb Support for dual CGA palette and background colors Support for attribute palette group changing Changes to work together with bios somewhat in supporting different video cards Basic support for Tandy pcjr 320x200x16 color mode Text mode support for changing font and panning support. Support for data rotate in 16 color modes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1063 --- src/hardware/vga.cpp | 238 +++++------------------- src/hardware/vga.h | 146 +++++++++------ src/hardware/vga_attr.cpp | 63 +++++-- src/hardware/vga_crtc.cpp | 311 ++++++++++++++++++++++++++++--- src/hardware/vga_dac.cpp | 27 ++- src/hardware/vga_draw.cpp | 355 +++++++++++++++++++++++++++++++----- src/hardware/vga_gfx.cpp | 20 +- src/hardware/vga_memory.cpp | 99 ++++++---- src/hardware/vga_misc.cpp | 101 +++++++++- src/hardware/vga_seq.cpp | 53 +++++- 10 files changed, 1009 insertions(+), 404 deletions(-) diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index bf94677b..17a03739 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -22,221 +22,65 @@ #include "dosbox.h" #include "video.h" #include "pic.h" -#include "render.h" #include "timer.h" #include "vga.h" +#include "inout.h" VGA_Type vga; -Bit32u CGAWriteTable[256]; +Bit32u CGA_4_Table[256]; Bit32u ExpandTable[256]; Bit32u Expand16Table[4][16]; Bit32u Expand16BigTable[0x10000]; Bit32u FillTable[16]; -static void EndRetrace(void) { - /* start the actual display update now */ - RENDER_DoUpdate(); - vga.config.retrace=false; -} -static void VGA_BlankTimer() { - PIC_AddEvent(VGA_BlankTimer,vga.draw.blank); - PIC_AddEvent(EndRetrace,667); - /* Setup a timer to destroy the vertical retrace bit in a few microseconds */ - vga.config.real_start=vga.config.display_start; - vga.config.retrace=true; -} - -static void VGA_DrawHandler(RENDER_Part_Handler part_handler) { - Bit8u * buf,* bufsplit; - /* Draw the current frame */ - if (!vga.draw.resizing) { - if (vga.config.line_compare=vga.draw.height){ - LOG(LOG_VGAGFX,LOG_NORMAL)("Split at %d",stop); - goto drawnormal; - } - switch (vga.mode) { - case GFX_16: - buf=&vga.buffer[vga.config.real_start*8+vga.config.pel_panning]; - bufsplit=vga.buffer; - break; - case GFX_256U: - buf=&vga.mem.linear[vga.config.real_start*4+vga.config.pel_panning/2]; - bufsplit=vga.mem.linear; - break; - case GFX_256C: - buf=memory+0xa0000; - bufsplit=memory+0xa0000; - break; - default: - LOG(LOG_VGAGFX,LOG_NORMAL)("VGA:Unhandled split screen mode %d",vga.mode); - goto norender; - } - part_handler(buf,0,0,vga.draw.width,stop); - part_handler(bufsplit,0,stop,vga.draw.width,vga.draw.height-stop); - } else { -drawnormal: - switch (vga.mode) { - case GFX_2: - VGA_DrawGFX2_Fast(vga.buffer,vga.draw.width); - buf=vga.buffer; - break; - case GFX_4: - VGA_DrawGFX4_Fast(vga.buffer,vga.draw.width); - buf=vga.buffer; - break; - case TEXT_16: - VGA_DrawTEXT(vga.buffer,vga.draw.width); - buf=vga.buffer; - break; - case GFX_16: - buf=&vga.buffer[vga.config.real_start*8+vga.config.pel_panning]; - break; - case GFX_256C: - buf=memory+0xa0000; - break; - case GFX_256U: - buf=&vga.mem.linear[vga.config.real_start*4+vga.config.pel_panning/2]; - break; - } - part_handler(buf,0,0,vga.draw.width,vga.draw.height); - } -norender:; - } - -} - -void VGA_FindSettings(void) { - /* Sets up the correct memory handler from the vga.mode setting */ - MEM_ClearPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x20000)); - /* Detect the kind of video mode this is */ - if (vga.config.gfxmode) { - if (vga.config.vga_enabled) { - if (vga.config.chained) { - /* 256 color chained vga */ - vga.mode=GFX_256C; - //Doesn't need a memory handler - } else { - /* 256 color unchained vga */ - vga.mode=GFX_256U; - MEM_SetupPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000), - &VGA_NormalReadHandler,&VGA_GFX_256U_WriteHandler); - } - } else if (vga.config.cga_enabled) { - /* 4 color cga */ - //TODO Detect hercules modes, probably set them up in bios too - if (vga.seq.clocking_mode & 0x8) { - vga.mode=GFX_4; -// MEM_SetupPageHandlers(PAGE_COUNT(0x0b8000),PAGE_COUNT(0x10000),&VGA_GFX_4_ReadHandler,&VGA_GFX_4_WriteHandler); - } else vga.mode=GFX_2; - //TODO Maybe also use a page handler for cga mode - } else { - /* 16 color ega */ - vga.mode=GFX_16; - MEM_SetupPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000), - &VGA_NormalReadHandler,&VGA_GFX_16_WriteHandler); - } - } else { - vga.mode=TEXT_16; - } +void VGA_SetMode(VGAModes mode) { + vga.mode=mode; + VGA_SetupHandlers(); VGA_StartResize(); } -static void VGA_DoResize(void) { - /* Calculate the FPS for this screen */ - double fps; - Bitu vtotal=2 + (vga.crtc.vertical_total | ((vga.crtc.overflow & 1) << 8) | ((vga.crtc.overflow & 0x20) << 4) ); - Bitu htotal=5 + vga.crtc.horizontal_total; - Bitu vdispend = 1 + (vga.crtc.vertical_display_end | ((vga.crtc.overflow & 2)<<7) | ((vga.crtc.overflow & 0x40) << 3) ); - Bitu hdispend = 1 + (vga.crtc.horizontal_display_end); - //TODO Maybe check if blanking comes before display_end - - double clock=(double)vga.config.clock; - /* Check for 8 for 9 character clock mode */ - if (vga.seq.clocking_mode & 1 ) clock/=8; else clock/=9; - /* Check for pixel doubling, master clock/2 */ - if (vga.seq.clocking_mode & 0x8) clock/=2; - - LOG(LOG_VGA,LOG_NORMAL)("H total %d, V Total %d",htotal,vtotal); - LOG(LOG_VGA,LOG_NORMAL)("H D End %d, V D End %d",hdispend,vdispend); - fps=clock/(vtotal*htotal); - - vga.draw.resizing=false; - Bitu width,height,pitch,flags; - - flags=0; - vga.draw.lines=height=vdispend; - width=hdispend; - vga.draw.double_height=vga.config.vline_double; - vga.draw.double_width=(vga.seq.clocking_mode & 0x8)>0; - vga.draw.font_height=vga.config.vline_height+1; - switch (vga.mode) { - case GFX_256C: - case GFX_256U: - vga.draw.double_width=true; //Hack since 256 color modes use 2 clocks for a pixel - /* Don't know might do this different sometime, will have to do for now */ - if (!vga.draw.double_height) { - if (vga.config.vline_height&1) { - vga.draw.double_height=true; - vga.draw.font_height/=2; - } - } - width<<=2; - pitch=vga.config.scan_len*8; - break; - case GFX_16: - width<<=3; - pitch=vga.config.scan_len*16; - break; - case GFX_4: - width<<=3; - pitch=width; - break; - case GFX_2: - width<<=3; - pitch=width; - break; - case TEXT_16: - /* probably a 16-color text mode, got to detect mono mode somehow */ - width<<=3; /* 8 bit wide text font */ - if (width>640) width=640; - if (height>480) height=480; - pitch=width; - }; - if (vga.draw.double_height) { - flags|=DoubleHeight; - height/=2; - } - if (vga.draw.double_width) { - flags|=DoubleWidth; - /* Double width is dividing main clock, the width should be correct already for this */ - } - if (( width != vga.draw.width) || (height != vga.draw.height) || (pitch != vga.draw.pitch)) { - PIC_RemoveEvents(VGA_BlankTimer); - vga.draw.width=width; - vga.draw.height=height; - vga.draw.pitch=pitch; - - LOG(LOG_VGA,LOG_NORMAL)("Width %d, Height %d",width,height); - LOG(LOG_VGA,LOG_NORMAL)("Flags %X, fps %f",flags,fps); - RENDER_SetSize(width,height,8,pitch,((float)width/(float)height),flags,&VGA_DrawHandler); - vga.draw.blank=(Bitu)(1000000/fps); - PIC_AddEvent(VGA_BlankTimer,vga.draw.blank); - } -}; - void VGA_StartResize(void) { if (!vga.draw.resizing) { vga.draw.resizing=true; /* Start a resize after 50 ms */ - PIC_AddEvent(VGA_DoResize,50000); + PIC_AddEvent(VGA_SetupDrawing,50000); } } +void VGA_SetClock(Bitu which,Bitu target) { + struct{ + Bitu n,m; + Bits err; + } best; + best.err=target; + Bitu n,m,r; + + for (r = 0; r <= 3; r++) { + Bitu f_vco = target * (1 << r); + if (MIN_VCO <= f_vco && f_vco < MAX_VCO) break; + } + for (n=1;n<=31;n++) { + m=(target * (n + 2) * (1 << r) + (S3_CLOCK_REF/2)) / S3_CLOCK_REF - 2; + if (0 <= m && m <= 127) { + Bitu temp_target = S3_CLOCK(m,n,r); + Bits err = target - temp_target; + if (err < 0) err = -err; + if (err < best.err) { + best.err = err; + best.m = m; + best.n = n; + } + } + } + /* Program the s3 clock chip */ + vga.s3.clk[which].m=best.m; + vga.s3.clk[which].r=r; + vga.s3.clk[which].n=best.n; + VGA_StartResize(); +} + void VGA_Init(Section* sec) { vga.draw.resizing=false; VGA_SetupMemory(); @@ -245,14 +89,16 @@ void VGA_Init(Section* sec) { VGA_SetupGFX(); VGA_SetupSEQ(); VGA_SetupAttr(); + VGA_SetClock(0,CLK_25); + VGA_SetClock(1,CLK_28); /* Generate tables */ Bitu i,j; for (i=0;i<256;i++) { ExpandTable[i]=i | (i << 8)| (i <<16) | (i << 24); #ifdef WORDS_BIGENDIAN - CGAWriteTable[i]=((i>>0)&3) | (((i>>2)&3) << 8)| (((i>>4)&3) <<16) | (((i>>6)&3) << 24); + CGA_4_Table[i]=((i>>0)&3) | (((i>>2)&3) << 8)| (((i>>4)&3) <<16) | (((i>>6)&3) << 24); #else - CGAWriteTable[i]=((i>>6)&3) | (((i>>4)&3) << 8)| (((i>>2)&3) <<16) | (((i>>0)&3) << 24); + CGA_4_Table[i]=((i>>6)&3) | (((i>>4)&3) << 8)| (((i>>2)&3) <<16) | (((i>>0)&3) << 24); #endif } for (i=0;i<16;i++) { diff --git a/src/hardware/vga.h b/src/hardware/vga.h index 9ce4b993..c3a7f9b0 100644 --- a/src/hardware/vga.h +++ b/src/hardware/vga.h @@ -22,39 +22,53 @@ #include #include "dosbox.h" -#undef TEXT -#undef GRAPH -/* conflicts with int10.h */ -enum { TEXT, GRAPH }; -enum { GFX_256C,GFX_256U,GFX_16,GFX_4,GFX_2, TEXT_16 }; +enum VGAModes { + M_TEXT16, + M_CGA2,M_CGA4, + M_TANDY16, + M_EGA2,M_EGA4,M_EGA16, + M_VGA, + M_LIN8, + 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 */ + +/* Different functions that should be handle by memory handler */ + +#define MH_ROTATEOP 0x0001; +#define MH_SETRESET 0x0002; +#define MH_BITMASK 0x0004; typedef struct { - bool attrindex; - Bit16u cursor; } VGA_Internal; typedef struct { +/* Memory handlers */ + Bitu mh_mask; /* Video drawing */ - Bit16u display_start; - Bit16u real_start; - bool retrace; /* A retrace has started */ + 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; - Bitu clock; - bool clock_half; - bool chained; /* Enable or Disabled Chain 4 Mode */ - bool gfxmode; /* Yes or No Easy no */ bool blinking; /* Attribute bit 7 is blinking */ - bool vga_enabled; - bool cga_enabled; - bool vline_double; Bit8u vline_height; @@ -64,6 +78,7 @@ typedef struct { Bit8u bytes_skip; /* Specific stuff memory write/read handling */ + PhysPt mem_base; Bit8u read_mode; Bit8u write_mode; Bit8u read_map_select; @@ -91,13 +106,48 @@ typedef struct { bool double_width; bool double_height; Bitu lines; - Bit8u * font; Bit8u font_height; + Bit8u font[64*1024]; + Bitu rows,cols; struct { - Bitu row,col,sline,eline,count; + Bit8u sline,eline; + Bit8u count,delay; + Bit8u enabled; } cursor; } VGA_Draw; +typedef struct { + Bit8u bank; + Bit8u reg_lock1; + Bit8u reg_lock2; + Bit8u reg_31; + Bit8u reg_35; + Bit8u reg_43; + Bit8u reg_58; + Bit8u reg_51; + Bit8u reg_55; + Bit8u ex_hor_overflow; + Bit8u ex_ver_overflow; + struct { + Bit8u r; + Bit8u n; + Bit8u m; + } clk[4],mclk; + struct { + Bit8u lock; + Bit8u cmd; + } pll; +} VGA_S3; + +typedef struct { + Bit8u color_select; +} VGA_CGA; + +typedef struct { + Bit8u mem_bank; + Bit8u disp_bank; + Bit8u reg_index; +} VGA_TANDY; typedef struct { Bit8u index; @@ -109,7 +159,6 @@ typedef struct { Bit8u memory_mode; } VGA_Seq; - typedef struct { Bit8u palette[16]; Bit8u mode_control; @@ -118,9 +167,9 @@ typedef struct { Bit8u color_plane_enable; Bit8u color_select; Bit8u index; + Bit8u enabled; } VGA_Attr; - typedef struct { Bit8u horizontal_total; Bit8u horizontal_display_end; @@ -143,12 +192,13 @@ typedef struct { Bit8u vertical_display_end; Bit8u offset; Bit8u underline_location; - Bit8u start_vertical_blank; - Bit8u end_vertical_blank; + Bit8u start_vertical_blanking; + Bit8u end_vertical_blanking; Bit8u mode_control; Bit8u line_compare; Bit8u index; + bool read_only; } VGA_Crtc; typedef struct { @@ -188,15 +238,14 @@ union VGA_Latch { }; union VGA_Memory { - Bit8u linear[64*1024*4]; - Bit8u paged[64*1024][4]; - VGA_Latch latched[64*1024]; + Bit8u linear[512*1024*4]; + Bit8u paged[512*1024][4]; + VGA_Latch latched[512*1024]; }; - - typedef struct { - Bitu mode; /* The mode the vga system is in */ + VGAModes mode; /* The mode the vga system is in */ + Bit8u misc_output; VGA_Draw draw; VGA_Config config; VGA_Internal internal; @@ -207,40 +256,21 @@ typedef struct { VGA_Gfx gfx; VGA_Dac dac; VGA_Latch latch; + VGA_S3 s3; + VGA_CGA cga; + VGA_TANDY tandy; VGA_Memory mem; -/* Extra buffer following main video ram with double data for overflowing of addresses */ - Bit8u buffer[1024*1024]; /* 256 kb vid ram with 16 colors and double addresses */ } VGA_Type; - - - - /* Functions for different resolutions */ -//void VGA_FindSize(void); -void VGA_FindSettings(void); +void VGA_SetMode(VGAModes mode); +void VGA_SetupHandlers(void); void VGA_StartResize(void); - -/* The Different Drawing functions */ -void VGA_DrawTEXT(Bit8u * bitdata,Bitu next_line); -void VGA_DrawGFX256U_Full(Bit8u * bitdata,Bitu next_line); -void VGA_DrawGFX16_Fast(Bit8u * bitdata,Bitu next_line); -void VGA_DrawGFX4_Fast(Bit8u * bitdata,Bitu next_line); -void VGA_DrawGFX2_Fast(Bit8u * bitdata,Bitu next_line); -/* The Different Memory Read/Write Handlers */ -Bit8u VGA_NormalReadHandler(Bit32u start); - -void VGA_GFX_256U_WriteHandler(Bit32u start,Bit8u val); -void VGA_GFX_16_WriteHandler(Bit32u start,Bit8u val); -void VGA_GFX_4_WriteHandler(Bit32u start,Bit8u val); - -Bit8u VGA_GFX_4_ReadHandler(Bit32u start); - - +void VGA_SetupDrawing(void); /* Some support functions */ void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal); - +void VGA_ATTR_SetPalette(Bit8u index,Bit8u val); /* The VGA Subfunction startups */ void VGA_SetupAttr(void); @@ -252,17 +282,15 @@ void VGA_SetupGFX(void); void VGA_SetupSEQ(void); /* Some Support Functions */ +void VGA_SetClock(Bitu which,Bitu target); void VGA_DACSetEntirePalette(void); void VGA_StartRetrace(void); extern VGA_Type vga; -extern Bit8u vga_rom_08[256 * 8]; -extern Bit8u vga_rom_14[256 * 14]; -extern Bit8u vga_rom_16[256 * 16]; extern Bit32u ExpandTable[256]; extern Bit32u FillTable[16]; -extern Bit32u CGAWriteTable[256]; +extern Bit32u CGA_4_Table[256]; extern Bit32u Expand16Table[4][16]; extern Bit32u Expand16BigTable[0x10000]; diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index c105d3e1..e94936c2 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -22,14 +22,23 @@ #define attr(blah) vga.attr.blah + +void VGA_ATTR_SetPalette(Bit8u index,Bit8u val) { + vga.attr.palette[index]=val; + if (vga.attr.mode_control & 0x80) val=(val&0xf) | (vga.attr.color_select << 4); + else val|=(vga.attr.color_select & 0xc) << 4; + VGA_DAC_CombineColor(index,val); +} + void write_p3c0(Bit32u port,Bit8u val) { if (!vga.internal.attrindex) { attr(index)=val & 0x1F; vga.internal.attrindex=true; + attr(enabled)=val & 0x20; /* - 0-4 Address of data register to write to port 3C0h or read from port 3C1h - If set screen output is enabled and the palette can not be modified, - if clear screen output is disabled and the palette can be modified. + 0-4 Address of data register to write to port 3C0h or read from port 3C1h + 5 If set screen output is enabled and the palette can not be modified, + if clear screen output is disabled and the palette can be modified. */ return; } else { @@ -40,20 +49,29 @@ void write_p3c0(Bit32u port,Bit8u val) { case 0x04: case 0x05: case 0x06: case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: - val&=0x3f; - attr(palette[attr(index)])=val; - VGA_DAC_CombineColor(attr(index),val); + if (!attr(enabled)) VGA_ATTR_SetPalette(attr(index),val); /* 0-5 Index into the 256 color DAC table. May be modified by 3C0h index 10h and 14h. */ break; case 0x10: /* Mode Control Register */ - if (val != attr(mode_control)) { + if ((attr(mode_control) ^ val) & 0x80) { attr(mode_control)=val; - vga.config.gfxmode=val&1; - vga.config.vga_enabled=(val & 0x40)>0; - VGA_FindSettings(); + for (Bitu i=0;i<0x10;i++) { + VGA_ATTR_SetPalette(i,vga.attr.palette[i]); + } + } + attr(mode_control)=val; + /* + Special hacks for games programming registers themselves, + Doesn't work if they program EGA16 themselves, + but haven't encountered that yet + */ + if (val&0x40) { + if (vga.mode0x7) vga.config.pel_panning=0; + else vga.config.pel_panning=val+1; + break; + case M_VGA: + case M_LIN8: + vga.config.pel_panning=(val & 0x7)/2; + break; + default: + vga.config.pel_panning=(val & 0x7); + } /* 0-3 Indicates number of pixels to shift the display left Value 9bit textmode 256color mode Other modes @@ -114,7 +141,12 @@ void write_p3c0(Bit32u port,Bit8u val) { */ break; case 0x14: /* Color Select Register */ - attr(color_select)=val; + if (attr(color_select) ^ val) { + attr(color_select)=val; + for (Bitu i=0;i<0x10;i++) { + VGA_ATTR_SetPalette(i,vga.attr.palette[i]); + } + } /* 0-1 If 3C0h index 10h bit 7 is set these 2 bits are used as bits 4-5 of the index into the DAC table. @@ -122,7 +154,6 @@ void write_p3c0(Bit32u port,Bit8u val) { except in 256 color mode. Note: this register does not affect 256 color modes. */ - if (val) LOG(LOG_VGAGFX,LOG_NORMAL)("VGA:ATTR:DAC index set to %d",val); break; default: LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:ATTR:Write to unkown Index %2X",attr(index)); diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index e2c40f0a..fe704ed2 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -19,7 +19,8 @@ #include "dosbox.h" #include "inout.h" #include "vga.h" - +#include "debug.h" +#include "cpu.h" #define crtc(blah) vga.crtc.blah @@ -34,12 +35,15 @@ Bit8u read_p3d4(Bit32u port) { void write_p3d5(Bit32u port,Bit8u val) { +// if (crtc(index)>0x18) LOG_MSG("VGA CRCT write %X to reg %X",val,crtc(index)); switch(crtc(index)) { case 0x00: /* Horizontal Total Register */ + if (crtc(read_only)) break; crtc(horizontal_total)=val; /* 0-7 Horizontal Total Character Clocks-5 */ break; case 0x01: /* Horizontal Display End Register */ + if (crtc(read_only)) break; if (val != crtc(horizontal_display_end)) { crtc(horizontal_display_end)=val; VGA_StartResize(); @@ -47,10 +51,12 @@ void write_p3d5(Bit32u port,Bit8u val) { /* 0-7 Number of Character Clocks Displayed -1 */ break; case 0x02: /* Start Horizontal Blanking Register */ + if (crtc(read_only)) break; crtc(start_horizontal_blanking)=val; /* 0-7 The count at which Horizontal Blanking starts */ break; case 0x03: /* End Horizontal Blanking Register */ + if (crtc(read_only)) break; crtc(end_horizontal_blanking)=val; /* 0-4 Horizontal Blanking ends when the last 6 bits of the character @@ -62,10 +68,12 @@ void write_p3d5(Bit32u port,Bit8u val) { */ break; case 0x04: /* Start Horizontal Retrace Register */ + if (crtc(read_only)) break; crtc(start_horizontal_retrace)=val; /* 0-7 Horizontal Retrace starts when the Character Counter reaches this value. */ break; case 0x05: /* End Horizontal Retrace Register */ + if (crtc(read_only)) break; crtc(end_horizontal_retrace)=val; /* 0-4 Horizontal Retrace ends when the last 5 bits of the character counter @@ -76,6 +84,7 @@ void write_p3d5(Bit32u port,Bit8u val) { */ break; case 0x06: /* Vertical Total Register */ + if (crtc(read_only)) break; if (val != crtc(vertical_total)) { crtc(vertical_total)=val; VGA_StartResize(); @@ -86,9 +95,10 @@ void write_p3d5(Bit32u port,Bit8u val) { */ break; case 0x07: /* Overflow Register */ - crtc(overflow)=val; - vga.config.line_compare=(vga.config.line_compare & 0x2ff) | (val & 0x10) << 4; - if ((vga.crtc.overflow ^ val) & 0xef) { + //Line compare bit ignores read only */ + vga.config.line_compare=(vga.config.line_compare & 0x6ff) | (val & 0x10) << 4; + if (crtc(read_only)) break; + if ((vga.crtc.overflow ^ val) & 0xd6) { crtc(overflow)=val; VGA_StartResize(); } else crtc(overflow)=val; @@ -119,7 +129,7 @@ void write_p3d5(Bit32u port,Bit8u val) { case 0x09: /* Maximum Scan Line Register */ vga.config.vline_double=(val & 128)>1; vga.config.vline_height=(val & 0xf); - vga.config.line_compare=(vga.config.line_compare & 0x1ff)|(val&0x40)<<3; + vga.config.line_compare=(vga.config.line_compare & 0x5ff)|(val&0x40)<<3; if ((vga.crtc.maximum_scan_line ^ val) & 0xbf) { crtc(maximum_scan_line)=val; VGA_StartResize(); @@ -137,6 +147,8 @@ void write_p3d5(Bit32u port,Bit8u val) { break; case 0x0A: /* Cursor Start Register */ crtc(cursor_start)=val; + vga.draw.cursor.sline=val&0x1f; + vga.draw.cursor.enabled=!(val&0x20); /* 0-4 First scanline of cursor within character. 5 Turns Cursor off if set @@ -144,6 +156,9 @@ void write_p3d5(Bit32u port,Bit8u val) { break; case 0x0B: /* Cursor End Register */ crtc(cursor_end)=val; + vga.draw.cursor.eline=val&0x1f; + vga.draw.cursor.delay=(val>>5)&0x3; + /* 0-4 Last scanline of cursor within character 5-6 Delay of cursor data in character clocks. @@ -151,27 +166,25 @@ void write_p3d5(Bit32u port,Bit8u val) { break; case 0x0C: /* Start Address High Register */ crtc(start_address_high)=val; - vga.config.display_start=(vga.config.display_start & 0x00FF)| (val << 8); + vga.config.display_start=(vga.config.display_start & 0xFF00FF)| (val << 8); /* 0-7 Upper 8 bits of the start address of the display buffer */ break; case 0x0D: /* Start Address Low Register */ crtc(start_address_low)=val; - vga.config.display_start=(vga.config.display_start & 0xFF00)| val; + vga.config.display_start=(vga.config.display_start & 0xFFFF00)| val; /* 0-7 Lower 8 bits of the start address of the display buffer */ break; case 0x0E: /*Cursor Location High Register */ crtc(cursor_location_high)=val; - if (vga.config.scan_len<2) break; - vga.draw.cursor.row=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))/(vga.config.scan_len*2); - vga.draw.cursor.col=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))%(vga.config.scan_len*2); + vga.config.cursor_start&=0xff00ff; + vga.config.cursor_start|=val << 8; /* 0-7 Upper 8 bits of the address of the cursor */ break; case 0x0F: /* Cursor Location Low Register */ //TODO update cursor on screen crtc(cursor_location_low)=val; - if (vga.config.scan_len<2) break; - vga.draw.cursor.row=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))/(vga.config.scan_len*2); - vga.draw.cursor.col=(crtc(cursor_location_high)<<8|crtc(cursor_location_low))%(vga.config.scan_len*2); + vga.config.cursor_start&=0xffff00; + vga.config.cursor_start|=val; /* 0-7 Lower 8 bits of the address of the cursor */ break; case 0x10: /* Vertical Retrace Start Register */ @@ -184,6 +197,7 @@ void write_p3d5(Bit32u port,Bit8u val) { break; case 0x11: /* Vertical Retrace End Register */ crtc(vertical_retrace_end)=val; + crtc(read_only)=(val & 128)>0; /* 0-3 Vertical Retrace ends when the last 4 bits of the line counter equals this value. @@ -209,7 +223,8 @@ void write_p3d5(Bit32u port,Bit8u val) { case 0x13: /* Offset register */ if (val!=crtc(offset)) { crtc(offset)=val; - vga.config.scan_len=val; + vga.config.scan_len&=0x300; + vga.config.scan_len|=val; VGA_StartResize(); } /* @@ -226,7 +241,10 @@ void write_p3d5(Bit32u port,Bit8u val) { */ break; case 0x15: /* Start Vertical Blank Register */ - crtc(start_vertical_blank)=val; + if (val!=crtc(start_vertical_blanking)) { + crtc(start_vertical_blanking)=val; + VGA_StartResize(); + } /* 0-7 Lower 8 bits of Vertical Blank Start. Vertical blanking starts when the line counter reaches this value. Bit 8 is found in 3d4h index 7 @@ -234,18 +252,14 @@ void write_p3d5(Bit32u port,Bit8u val) { */ break; case 0x16: /* End Vertical Blank Register */ - crtc(end_vertical_blank)=val; + crtc(end_vertical_blanking)=val; /* 0-6 Vertical blanking stops when the lower 7 bits of the line counter equals this field. Some SVGA chips uses all 8 bits! */ break; case 0x17: /* Mode Control Register */ - if (val!=crtc(mode_control)) { - crtc(mode_control)=val; - vga.config.cga_enabled=!((val&1)>0); - VGA_FindSettings(); - } + crtc(mode_control)=val; /* 0 If clear use CGA compatible memory addressing system by substituting character row scan counter bit 0 for address bit 13, @@ -264,21 +278,217 @@ void write_p3d5(Bit32u port,Bit8u val) { break; case 0x18: /* Line Compare Register */ crtc(line_compare)=val; - vga.config.line_compare=(vga.config.line_compare & 0x300) | val; + vga.config.line_compare=(vga.config.line_compare & 0x700) | val; /* 0-7 Lower 8 bits of the Line Compare. When the Line counter reaches this value, the display address wraps to 0. Provides Split Screen facilities. Bit 8 is found in 3d4h index 7 bit 4. Bit 9 is found in 3d4h index 9 bit 6. */ - break; +/* S3 specific group */ + case 0x31: /* CR31 Memory Configuration */ +//TODO Base address + vga.s3.reg_31=val; + break; + /* + 0 Enable Base Address Offset (CPUA BASE). Enables bank operation if + set, disables if clear. + 1 Two Page Screen Image. If set enables 2048 pixel wide screen setup + 2 VGA 16bit Memory Bus Width. Set for 16bit, clear for 8bit + 3 Use Enhanced Mode Memory Mapping (ENH MAP). Set to enable access to + video memory above 256k. + 4-5 Bit 16-17 of the Display Start Address. For the 801/5,928 see index + 51h, for the 864/964 see index 69h. + 6 High Speed Text Display Font Fetch Mode. If set enables Page Mode + for Alpha Mode Font Access. + 7 (not 864/964) Extended BIOS ROM Space Mapped out. If clear the area + C6800h-C7FFFh is mapped out, if set it is accessible. + */ + case 0x35: /* CR35 CRT Register Lock */ + if (vga.s3.reg_lock1 != 0x48) return; //Needed for uvconfig detection + vga.s3.reg_35=val & 0xf0; + if ((vga.s3.bank & 0xf) ^ (val & 0xf)) { + vga.s3.bank&=0xf0; + vga.s3.bank|=val & 0xf; + VGA_SetupHandlers(); + } + break; + /* + 0-3 CPU Base Address. 64k bank number. For the 801/5 and 928 see 3d4h + index 51h bits 2-3. For the 864/964 see index 6Ah. + 4 Lock Vertical Timing Registers (LOCK VTMG). Locks 3d4h index 6, 7 + (bits 0,2,3,5,7), 9 bit 5, 10h, 11h bits 0-3, 15h, 16h if set + 5 Lock Horizontal Timing Registers (LOCK HTMG). Locks 3d4h index + 0,1,2,3,4,5,17h bit 2 if set + 6 (911/924) Lock VSync Polarity. + 7 (911/924) Lock HSync Polarity. + */ + case 0x38: /* CR38 Register Lock 1 */ + vga.s3.reg_lock1=val; + break; + case 0x39: /* CR39 Register Lock 2 */ + vga.s3.reg_lock2=val; + break; + case 0x43: /* CR43 Extended Mode */ + vga.s3.reg_43=val & ~0x4; + if (((val & 0x4) ^ (vga.config.scan_len >> 6)) & 0x4) { + vga.config.scan_len&=0x2ff; + vga.config.scan_len|=(val & 0x4) << 6; + VGA_StartResize(); + } + break; + /* + 2 Logical Screen Width bit 8. Bit 8 of the Display Offset Register/ + (3d4h index 13h). (801/5,928) Only active if 3d4h index 51h bits 4-5 + are 0 + */ + case 0x51: /* Extended System Control 2 */ + vga.s3.reg_51=val & 0xc0; //Only store bits 6,7 + //TODO Display start + vga.config.display_start&=0xFCFFFF; + vga.config.display_start|=(val & 3) << 16; + if ((vga.s3.bank&0xcf) ^ ((val&0xc)<<2)) { + vga.s3.bank&=0xcf; + vga.s3.bank|=(val&0xc)<<2; + VGA_SetupHandlers(); + } + if (((val & 0x30) ^ (vga.config.scan_len >> 4)) & 0x30) { + vga.config.scan_len&=0xff; + vga.config.scan_len|=(val & 0x30) << 4; + VGA_StartResize(); + } + break; + /* + 0 (80x) Display Start Address bit 18 + 0-1 (928 +) Display Start Address bit 18-19 + Bits 16-17 are in index 31h bits 4-5, Bits 0-15 are in 3d4h index + 0Ch,0Dh. For the 864/964 see 3d4h index 69h + 2 (80x) CPU BASE. CPU Base Address Bit 18. + 2-3 (928 +) Old CPU Base Address Bits 19-18. + 64K Bank register bits 4-5. Bits 0-3 are in 3d4h index 35h. + For the 864/964 see 3d4h index 6Ah + 4-5 Logical Screen Width Bit [8-9]. Bits 8-9 of the CRTC Offset register + (3d4h index 13h). If this field is 0, 3d4h index 43h bit 2 is active + 6 (928,964) DIS SPXF. Disable Split Transfers if set. Spilt Transfers + allows transferring one half of the VRAM shift register data while + the other half is being output. For the 964 Split Transfers + must be enabled in enhanced modes (4AE8h bit 0 set). Guess: They + probably can't time the VRAM load cycle closely enough while the + graphics engine is running. + 7 (not 864/964) Enable EPROM Write. If set enables flash memory write + control to the BIOS ROM address + */ + case 0x55: /* Extended Video DAC Control */ + vga.s3.reg_55=val; + break; + /* + 0-1 DAC Register Select Bits. Passed to the RS2 and RS3 pins on the + RAMDAC, allowing access to all 8 or 16 registers on advanced RAMDACs. + If this field is 0, 3d4h index 43h bit 1 is active. + 2 Enable General Input Port Read. If set DAC reads are disabled and the + STRD strobe for reading the General Input Port is enabled for reading + while DACRD is active, if clear DAC reads are enabled. + 3 (928) Enable External SID Operation if set. If set video data is + passed directly from the VRAMs to the DAC rather than through the + VGA chip + 4 Hardware Cursor MS/X11 Mode. If set the Hardware Cursor is in X11 + mode, if clear in MS-Windows mode + 5 (80x,928) Hardware Cursor External Operation Mode. If set the two + bits of cursor data ,is output on the HC[0-1] pins for the video DAC + The SENS pin becomes HC1 and the MID2 pin becomes HC0. + 6 ?? + 7 (80x,928) Disable PA Output. If set PA[0-7] and VCLK are tristated. + (864/964) TOFF VCLK. Tri-State Off VCLK Output. VCLK output tri + -stated if set + */ + case 0x58: /* Linear Address Window Control */ + vga.s3.reg_58=val; + break; + /* + 0-1 Linear Address Window Size. Must be less than or equal to video + memory size. 0: 64K, 1: 1MB, 2: 2MB, 3: 4MB (928)/8Mb (864/964) + 2 (not 864/964) Enable Read Ahead Cache if set + 3 (80x,928) ISA Latch Address. If set latches address during every ISA + cycle, unlatches during every ISA cycle if clear. + (864/964) LAT DEL. Address Latch Delay Control (VL-Bus only). If set + address latching occours in the T1 cycle, if clear in the T2 cycle + (I.e. one clock cycle delayed). + 4 ENB LA. Enable Linear Addressing if set. + 5 (not 864/964) Limit Entry Depth for Write-Post. If set limits Write + -Post Entry Depth to avoid ISA bus timeout due to wait cycle limit. + 6 (928,964) Serial Access Mode (SAM) 256 Words Control. If set SAM + control is 256 words, if clear 512 words. + 7 (928) RAS 6-MCLK. If set the random read/write cycle time is 6MCLKs, + if clear 7MCLKs + */ + case 0x5D: /* Extended Horizontal Overflow */ + if ((val & vga.s3.ex_hor_overflow) ^ 3) { + vga.s3.ex_hor_overflow=val; + VGA_StartResize(); + } else vga.s3.ex_hor_overflow=val; + break; + /* + 0 Horizontal Total bit 8. Bit 8 of the Horizontal Total register (3d4h + index 0) + 1 Horizontal Display End bit 8. Bit 8 of the Horizontal Display End + register (3d4h index 1) + 2 Start Horizontal Blank bit 8. Bit 8 of the Horizontal Start Blanking + register (3d4h index 2). + 3 (864,964) EHB+64. End Horizontal Blank +64. If set the /BLANK pulse + is extended by 64 DCLKs. Note: Is this bit 6 of 3d4h index 3 or + does it really extend by 64 ? + 4 Start Horizontal Sync Position bit 8. Bit 8 of the Horizontal Start + Retrace register (3d4h index 4). + 5 (864,964) EHS+32. End Horizontal Sync +32. If set the HSYNC pulse + is extended by 32 DCLKs. Note: Is this bit 5 of 3d4h index 5 or + does it really extend by 32 ? + 6 (928,964) Data Transfer Position bit 8. Bit 8 of the Data Transfer + Position register (3d4h index 3Bh) + 7 (928,964) Bus-Grant Terminate Position bit 8. Bit 8 of the Bus Grant + Termination register (3d4h index 5Fh). + */ + case 0x5e: /* Extended Vertical Overflow */ + vga.config.line_compare=(vga.config.line_compare & 0x3ff) | (val & 0x40) << 4; + if ((val ^ vga.s3.ex_ver_overflow) & 0x3) { + vga.s3.ex_ver_overflow=val; + VGA_StartResize(); + } else vga.s3.ex_ver_overflow=val; + break; + /* + 0 Vertical Total bit 10. Bit 10 of the Vertical Total register (3d4h + index 6). Bits 8 and 9 are in 3d4h index 7 bit 0 and 5. + 1 Vertical Display End bit 10. Bit 10 of the Vertical Display End + register (3d4h index 12h). Bits 8 and 9 are in 3d4h index 7 bit 1 + and 6 + 2 Start Vertical Blank bit 10. Bit 10 of the Vertical Start Blanking + register (3d4h index 15h). Bit 8 is in 3d4h index 7 bit 3 and bit 9 + in 3d4h index 9 bit 5 + 4 Vertical Retrace Start bit 10. Bit 10 of the Vertical Start Retrace + register (3d4h index 10h). Bits 8 and 9 are in 3d4h index 7 bit 2 + and 7. + 6 Line Compare Position bit 10. Bit 10 of the Line Compare register + (3d4h index 18h). Bit 8 is in 3d4h index 7 bit 4 and bit 9 in 3d4h + index 9 bit 6. + */ + case 0x69: /* Extended System Control 3 */ + if (((vga.config.display_start & 0x1f0000)>>16) ^ (val & 0x1f)) { + vga.config.display_start&=0xffff; + vga.config.display_start|=(val & 0x1f) << 16; + } + break; + case 0x6a: /* Extended System Control 4 */ + vga.s3.bank=val & 0x3f; + VGA_SetupHandlers(); + break; + default: - LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:Write to unknown index %2X",val,crtc(index)); + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:Write %X to unknown index %2X",val,crtc(index)); } } Bit8u read_p3d5(Bit32u port) { +// LOG_MSG("VGA CRCT read from reg %X",crtc(index)); switch(crtc(index)) { case 0x00: /* Horizontal Total Register */ return crtc(horizontal_total); @@ -323,17 +533,64 @@ Bit8u read_p3d5(Bit32u port) { case 0x14: /* Underline Location Register */ return crtc(underline_location); case 0x15: /* Start Vertical Blank Register */ - return crtc(start_vertical_blank); + return crtc(start_vertical_blanking); case 0x16: /* End Vertical Blank Register */ - return crtc(end_vertical_blank); + return crtc(end_vertical_blanking); case 0x17: /* Mode Control Register */ return crtc(mode_control); case 0x18: /* Line Compare Register */ return crtc(line_compare); + + +/* Additions for S3 SVGA Support */ + case 0x2d: /* Extended Chip ID. */ + return 0x88; + // Always 88h ? + case 0x2e: /* New Chip ID */ + return 0x11; + //Trio 64 id + case 0x2f: /* Revision */ + return 0x80; + case 0x30: /* CR30 Chip ID/REV register */ + return 0xe0; //Trio+ dual byte + // Trio32/64 has 0xe0. extended + case 0x31: /* CR31 Memory Configuration */ +//TODO mix in bits from baseaddress; + return vga.s3.reg_31; + case 0x35: /* CR35 CRT Register Lock */ + return vga.s3.reg_35|(vga.s3.bank & 0xf); + case 0x36: /* CR36 Reset State Read 1 */ + return 0x8f; + //2 Mb PCI and some bios settings + case 0x37: /* Reset state read 2 */ + return 0x2b; + case 0x38: /* CR38 Register Lock 1 */ + return vga.s3.reg_lock1; + case 0x39: /* CR39 Register Lock 2 */ + return vga.s3.reg_lock2; + case 0x43: /* CR43 Extended Mode */ + return vga.s3.reg_43|((vga.config.scan_len>>6)&0x4); + case 0x51: /* Extended System Control 2 */ + return ((vga.config.display_start >> 16) & 3 ) | + ((vga.s3.bank & 0x30) >> 2) | + ((vga.config.scan_len & 0x300) >> 4) | + vga.s3.reg_51; + case 0x55: /* Extended Video DAC Control */ + return vga.s3.reg_55; + case 0x58: /* Linear Address Window Control */ + return vga.s3.reg_58; + case 0x5D: /* Extended Horizontal Overflow */ + return vga.s3.ex_hor_overflow; + case 0x5e: /* Extended Vertical Overflow */ + return vga.s3.ex_ver_overflow; + case 0x69: /* Extended System Control 3 */ + return (Bit8u)((vga.config.display_start & 0x1f0000)>>16); + case 0x6a: /* Extended System Control 4 */ + return (Bit8u)(vga.s3.bank & 0x3f); default: LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:Read from unknown index %X",crtc(index)); } - return 0; + return 0x0; } diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index f9c7051c..b387d91b 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -68,6 +68,12 @@ static void write_p3c7(Bit32u port,Bit8u val) { vga.dac.read_index=val; vga.dac.pel_index=0; vga.dac.state=DAC_READ; + +} + +static Bit8u read_p3c7(Bit32u port) { + if (vga.dac.state==DAC_READ) return 0x3; + else return 0x0; } static void write_p3c8(Bit32u port,Bit8u val) { @@ -89,8 +95,8 @@ static void write_p3c9(Bit32u port,Bit8u val) { case 2: vga.dac.rgb[vga.dac.write_index].blue=val; switch (vga.mode) { - case GFX_256C: - case GFX_256U: + case M_VGA: + case M_LIN8: RENDER_SetPal(vga.dac.write_index, vga.dac.rgb[vga.dac.write_index].red << 2, vga.dac.rgb[vga.dac.write_index].green << 2, @@ -141,12 +147,17 @@ static Bit8u read_p3c9(Bit32u port) { void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal) { /* Check if this is a new color */ vga.dac.attr[attr]=pal; - if (vga.mode != GFX_256U && vga.mode != GFX_256C) - RENDER_SetPal(attr, - vga.dac.rgb[pal].red << 2, - vga.dac.rgb[pal].green << 2, - vga.dac.rgb[pal].blue << 2 + switch (vga.mode) { + case M_VGA: + case M_LIN8: + break; + default: + RENDER_SetPal(attr, + vga.dac.rgb[pal].red << 2, + vga.dac.rgb[pal].green << 2, + vga.dac.rgb[pal].blue << 2 ); + } } void VGA_SetupDAC(void) { @@ -157,11 +168,11 @@ void VGA_SetupDAC(void) { vga.dac.state=DAC_READ; vga.dac.read_index=0; vga.dac.write_index=0; - /* Setup the DAC IO port Handlers */ IO_RegisterWriteHandler(0x3c6,write_p3c6,"PEL Mask"); IO_RegisterReadHandler(0x3c6,read_p3c6,"PEL Mask"); IO_RegisterWriteHandler(0x3c7,write_p3c7,"PEL Read Mode"); + IO_RegisterReadHandler(0x3c7,read_p3c7,"PEL Status Mode"); IO_RegisterWriteHandler(0x3c8,write_p3c8,"PEL Write Mode"); IO_RegisterWriteHandler(0x3c9,write_p3c9,"PEL Data"); IO_RegisterReadHandler(0x3c9,read_p3c9,"PEL Data"); diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 337d04d0..ca517d30 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -19,11 +19,13 @@ #include #include "dosbox.h" #include "video.h" +#include "render.h" #include "vga.h" +#include "pic.h" //TODO Make the full draw like the vga really does from video memory. -void VGA_DrawGFX2_Fast(Bit8u * bitdata,Bitu pitch) { +static void VGA_CGA2_Draw(Bit8u * bitdata,Bitu pitch) { Bit8u * reader=HostMake(0xB800,0); Bit8u * flip=HostMake(0xB800,8*1024); Bit8u * draw; @@ -36,7 +38,7 @@ void VGA_DrawGFX2_Fast(Bit8u * bitdata,Bitu pitch) { }; draw=bitdata; //TODO Look up table like in 4color mode - for (Bit32u x=vga.draw.width>>3;x>0;x--) { + for (Bitu x=vga.draw.width>>3;x>0;x--) { Bit8u val=*(tempread++); *(draw+0)=(val>>7)&1; *(draw+1)=(val>>6)&1; @@ -52,7 +54,7 @@ void VGA_DrawGFX2_Fast(Bit8u * bitdata,Bitu pitch) { } } -void VGA_DrawGFX4_Fast(Bit8u * bitdata,Bitu pitch) { +static void VGA_CGA4_Draw(Bit8u * bitdata,Bitu pitch) { Bit8u * reader=HostMake(0xB800,vga.config.display_start*2); Bit8u * flip=HostMake(0xB800,8*1024); Bit8u * draw; @@ -65,74 +67,333 @@ void VGA_DrawGFX4_Fast(Bit8u * bitdata,Bitu pitch) { if (reader>=flip) reader-=8*1024; } draw=bitdata; - for (Bit32u x=0;x>2;x++) { + for (Bitu x=0;x>2;x++) { Bit8u val=*(tempread++); - *(Bit32u *)draw=CGAWriteTable[val]; + *(Bit32u *)draw=CGA_4_Table[val]; draw+=4; } bitdata+=pitch; } } -/* Draw the screen using the lookup buffer */ -void VGA_DrawGFX16_Fast(Bit8u * bitdata,Bitu next_line) { - Bit8u * reader=&vga.buffer[vga.config.display_start*8+vga.config.pel_panning]; - for (Bitu y=0;y>2;x++) { - for (Bit32u dx=0;dx<4;dx++) { - (*bitdata++)=vga.mem.paged[xreader][dx]; - } - xreader++; + Bit8u val1=*(tempread++); + Bit8u val2=*(tempread++); + Bit32u full=(val1 & 0x0f) << 8 | + (val1 & 0xf0) >> 4 | + (val2 & 0x0f) << 24 | + (val2 & 0xf0) << 12; + *(Bit32u *)draw=full; + draw+=4; } - yreader+=vga.config.scan_len*2; - bitdata+=next_line; + bitdata+=pitch; + if ((y & 3)==3)reader+=160; } } -void VGA_DrawTEXT(Bit8u * bitdata,Bitu pitch) { - - Bit8u * reader=HostMake((vga.gfx.miscellaneous & 0x4 ?0xB800:0xB000),0); + +void VGA_TEXT_Draw(Bit8u * bitdata,Bitu start,Bitu panning,Bitu rows) { + Bit8u * reader=HostMake(0xb800,start); Bit8u * draw_start=bitdata; /* Todo Blinking and high intensity colors */ - for (Bitu cy=0;cy<(vga.draw.height/16);cy++) { + Bitu next_charline=vga.draw.font_height*vga.draw.width; + Bitu next_line=vga.draw.width; + Bitu next_start=(vga.config.scan_len*2)-vga.draw.cols; + for (Bitu cy=rows;cy>0;cy--) { Bit8u * draw_char=draw_start; - for (Bitu cx=0;cx<(vga.draw.width/8);cx++) { + /* Do first character keeping track of panning */ + { Bit8u c=*(reader++); - Bit8u * findex=&vga_rom_16[c*16]; + Bit8u * findex=&vga.draw.font[c*32]; + Bit8u col=*(reader++); + Bit8u fg=col & 0xF; + Bit8u bg=(col>> 4); + Bit8u * draw_line=draw_char; + Bit8u bit_index=1 << (7-panning); + for (Bitu y=vga.draw.font_height;y>0;y--) { + Bit8u * draw=draw_line; + draw_line+=next_line; + Bit8u bit=bit_index; + Bit8u bit_mask=*findex++; + while (bit) { + if (bit_mask & bit) *draw=fg; + else *draw=bg; + draw++;bit>>=1; + } + } + draw_char+=8-panning; + } + for (Bitu cx=vga.draw.cols-1;cx>0;cx--) { + Bit8u c=*(reader++); + Bit8u * findex=&vga.draw.font[c*32]; Bit8u col=*(reader++); Bit8u fg=col & 0xF; Bit8u bg=(col>> 4); Bit8u * draw=draw_char; - for (Bitu y=0;y<16;y++) { + for (Bitu y=vga.draw.font_height;y>0;y--) { Bit8u bit_mask=*findex++; #include "font-switch.h" - draw+=pitch; - }; + draw+=next_line; + } draw_char+=8; - }; - draw_start+=16*pitch; - }; - if(!(vga.internal.cursor & 0x2000)) { - /* Draw a cursor */ - if (((Bitu)vga.draw.cursor.col*8)>=vga.draw.width) return; - if (((Bitu)vga.draw.cursor.row*16)>=vga.draw.height) return; - Bit8u * cursor_draw=bitdata+(vga.draw.cursor.row*16+15)*pitch+vga.draw.cursor.col*8; - if (vga.draw.cursor.count>8) { - for (Bit8u loop=0;loop<8;loop++) *cursor_draw++=15; } - vga.draw.cursor.count++; - if (vga.draw.cursor.count>16) vga.draw.cursor.count=0; - } -}; + /* Do last character if needed */ + if (panning) { + Bit8u c=*(reader); + Bit8u * findex=&vga.draw.font[c*32]; + Bit8u col=*(reader+1); + Bit8u fg=col & 0xF; + Bit8u bg=(col>> 4); + Bit8u * draw_line=draw_char; + Bit8u bit_index=1 << panning; + for (Bitu y=vga.draw.font_height;y>0;y--) { + Bit8u * draw=draw_line; + draw_line+=next_line; + Bit8u bit=bit_index; + Bit8u bit_mask=*findex++; + while (bit) { + if (bit_mask & bit) *draw=fg; + else *draw=bg; + draw++;bit>>=1; + } + } + } + draw_start+=next_charline; + reader+=next_start; + } +/* Cursor handling */ + vga.draw.cursor.count++; + if (vga.draw.cursor.count>16) vga.draw.cursor.count=0; + if(vga.draw.cursor.enabled && (vga.draw.cursor.count>8)) { /* Draw a cursor if enabled */ + Bits cur_start=vga.config.cursor_start-start; + if (cur_start<0) return; + + Bitu row=cur_start / (vga.config.scan_len*2); + Bitu col=cur_start % (vga.config.scan_len*2); + Bit32u att=*HostMake(0xb800,vga.config.cursor_start*2+1)&0xf; + att=(att << 8) | att; + att=(att << 16) | att; + + if ((col*8)>=vga.draw.width) return; + if ((row*vga.draw.font_height)>=vga.draw.height) return; + if (vga.draw.cursor.sline>=vga.draw.font_height) return; + if (vga.draw.cursor.sline>vga.draw.cursor.eline) return; + Bit8u * cursor_draw=bitdata+(row*vga.draw.font_height+vga.draw.cursor.sline)*vga.draw.width+col*8; + + for (Bits loop=vga.draw.cursor.eline-vga.draw.cursor.sline;loop>=0;loop--) { + *((Bit32u *)cursor_draw)=att; + *((Bit32u *)(cursor_draw+4))=att; + cursor_draw+=vga.draw.width; + } + } +} + +static void EndRetrace(void) { + /* start the actual display update now */ + RENDER_DoUpdate(); + vga.config.retrace=false; +} + +static void VGA_BlankTimer() { + PIC_AddEvent(VGA_BlankTimer,vga.draw.blank); + PIC_AddEvent(EndRetrace,667); + /* Setup a timer to destroy the vertical retrace bit in a few microseconds */ + vga.config.real_start=vga.config.display_start; + vga.config.retrace=true; +} + + +void VGA_DrawHandler(RENDER_Part_Handler part_handler) { + Bit8u * buf,* bufsplit; + /* Draw the current frame */ + if (!vga.draw.resizing) { + if (vga.config.line_compare=vga.draw.height){ + LOG(LOG_VGAGFX,LOG_NORMAL)("Split at %d",stop); + goto drawnormal; + } + switch (vga.mode) { + case M_EGA16: + buf=&vga.mem.linear[512*1024+vga.config.real_start*8+vga.config.pel_panning]; + bufsplit=&vga.mem.linear[512*1024]; + break; + case M_VGA: + case M_LIN8: + buf=&vga.mem.linear[vga.config.real_start*4+vga.config.pel_panning]; + bufsplit=vga.mem.linear; + break; + case M_TEXT16: + { + Bitu first_rows=stop/vga.draw.font_height; + if (vga.config.hlines_skip) first_rows++; + if (stop%vga.draw.font_height) first_rows++; + Bitu next_rows=(vga.draw.height-stop)/vga.draw.font_height; + if ((vga.draw.height-stop)%vga.draw.font_height) next_rows++; + VGA_TEXT_Draw(&vga.mem.linear[512*1024],vga.config.real_start,vga.config.pel_panning,first_rows); + VGA_TEXT_Draw(&vga.mem.linear[1024*1024],0,0,next_rows); + buf=&vga.mem.linear[512*1024+vga.config.hlines_skip*vga.draw.width]; + bufsplit=&vga.mem.linear[1024*1024]; + } + break; + default: + LOG(LOG_VGAGFX,LOG_NORMAL)("VGA:Unhandled split screen mode %d",vga.mode); + goto norender; + } + if (stop) part_handler(buf,0,0,vga.draw.width,stop); + if (vga.draw.height-stop) part_handler(bufsplit,0,stop,vga.draw.width,vga.draw.height-stop); + } else { +drawnormal: + switch (vga.mode) { + case M_CGA2: + VGA_CGA2_Draw(&vga.mem.linear[512*1024],vga.draw.width); + buf=&vga.mem.linear[512*1024]; + break; + case M_CGA4: + VGA_CGA4_Draw(&vga.mem.linear[512*1024],vga.draw.width); + buf=&vga.mem.linear[512*1024]; + break; + case M_TANDY16: + VGA_TANDY16_Draw(&vga.mem.linear[512*1024],vga.draw.width); + buf=&vga.mem.linear[512*1024]; + break; + case M_EGA16: + buf=&vga.mem.linear[512*1024+vga.config.real_start*8+vga.config.pel_panning]; + break; + case M_VGA: + case M_LIN8: + buf=&vga.mem.linear[vga.config.real_start*4+vga.config.pel_panning]; + break; + case M_TEXT16: + { + Bitu rows=vga.draw.rows; + if (vga.config.hlines_skip) rows++; + VGA_TEXT_Draw(&vga.mem.linear[512*1024],vga.config.real_start,vga.config.pel_panning,rows); + buf=&vga.mem.linear[512*1024+vga.config.hlines_skip*vga.draw.width]; + } + break; + default: + return; + } + part_handler(buf,0,0,vga.draw.width,vga.draw.height); + } +norender:; + } + +} + + +void VGA_SetupDrawing(void) { + /* Calculate the FPS for this screen */ + double fps; + Bitu vtotal=2 + (vga.crtc.vertical_total | ((vga.crtc.overflow & 1) << 8) | ((vga.crtc.overflow & 0x20) << 4) ); + Bitu htotal=5 + vga.crtc.horizontal_total; + Bitu vdispend = 1 + (vga.crtc.vertical_display_end | ((vga.crtc.overflow & 2)<<7) | ((vga.crtc.overflow & 0x40) << 3) ); + Bitu hdispend = 1 + (vga.crtc.horizontal_display_end); + + Bitu hbstart = vga.crtc.start_horizontal_blanking; + Bitu vbstart = vga.crtc.start_vertical_blanking | ((vga.crtc.overflow & 0x08) << 5) | ((vga.crtc.maximum_scan_line & 0x20) << 4) ; + + if (hbstart> 2) & 3; + clock=1000*S3_CLOCK(vga.s3.clk[clock].m,vga.s3.clk[clock].n,vga.s3.clk[clock].r); + /* Check for 8 for 9 character clock mode */ + if (vga.seq.clocking_mode & 1 ) clock/=8; else clock/=9; + /* Check for pixel doubling, master clock/2 */ + if (vga.seq.clocking_mode & 0x8) clock/=2; + /* Check for dual transfer whatever thing,master clock/2 */ + if (vga.s3.pll.cmd & 0x10) clock/=2; + + + LOG(LOG_VGA,LOG_NORMAL)("H total %d, V Total %d",htotal,vtotal); + LOG(LOG_VGA,LOG_NORMAL)("H D End %d, V D End %d",hdispend,vdispend); + fps=clock/(vtotal*htotal); + + vga.draw.resizing=false; + Bitu width,height,pitch,flags; + + flags=0; + vga.draw.lines=height=vdispend; + width=hdispend; + vga.draw.double_height=vga.config.vline_double; + vga.draw.double_width=(vga.seq.clocking_mode & 0x8)>0; + vga.draw.font_height=vga.config.vline_height+1; + switch (vga.mode) { + case M_VGA: + vga.draw.double_width=true; //Hack since 256 color modes use 2 clocks for a pixel + /* Don't know might do this different sometime, will have to do for now */ + if (!vga.draw.double_height) { + if (vga.config.vline_height&1) { + vga.draw.double_height=true; + vga.draw.font_height/=2; + } + } + width<<=2; + pitch=vga.config.scan_len*8; + break; + case M_LIN8: + width<<=3; + pitch=vga.config.scan_len*8; + break; + case M_EGA16: + width<<=3; + pitch=vga.config.scan_len*16; + break; + case M_CGA4: + width<<=3; + pitch=width; + break; + case M_CGA2: + width<<=3; + pitch=width; + break; + case M_TANDY16: + width<<=3; + pitch=width; + break; + case M_TEXT16: + /* probably a 16-color text mode, got to detect mono mode somehow */ + vga.draw.font_height=vga.config.vline_height+1; + vga.draw.cols=width; + vga.draw.rows=(height/vga.draw.font_height); + if (height % vga.draw.font_height) vga.draw.rows++; + width<<=3; /* 8 bit wide text font */ + if (width>640) width=640; + if (height>480) height=480; + pitch=width; + break; + default: + LOG(LOG_VGA,LOG_ERROR)("Unhandled VGA type %d while checking for resolution"); + }; + if (vga.draw.double_height) { + flags|=DoubleHeight; + height/=2; + } + if (vga.draw.double_width) { + flags|=DoubleWidth; + /* Double width is dividing main clock, the width should be correct already for this */ + } + if (( width != vga.draw.width) || (height != vga.draw.height) || (pitch != vga.draw.pitch)) { + PIC_RemoveEvents(VGA_BlankTimer); + vga.draw.width=width; + vga.draw.height=height; + vga.draw.pitch=pitch; + + LOG(LOG_VGA,LOG_NORMAL)("Width %d, Height %d",width,height); + LOG(LOG_VGA,LOG_NORMAL)("Flags %X, fps %f",flags,fps); + RENDER_SetSize(width,height,8,pitch,((float)width/(float)height),flags,&VGA_DrawHandler); + vga.draw.blank=(Bitu)(1000000/fps); + PIC_AddEvent(VGA_BlankTimer,vga.draw.blank); + } +}; diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index cc363bb0..dafe1ada 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -56,6 +56,8 @@ void write_p3cf(Bit32u port,Bit8u val) { vga.config.full_not_enable_set_reset=~vga.config.full_enable_set_reset; vga.config.full_enable_and_set_reset=vga.config.full_set_reset & vga.config.full_enable_set_reset; +// if (gfx(enable_set_reset)) vga.config.mh_mask|=MH_SETRESET else vga.config.mh_mask&=~MH_SETRESET; + break; case 2: /* Color Compare Register */ gfx(color_compare)=val & 0x0f; /* @@ -70,7 +72,7 @@ void write_p3cf(Bit32u port,Bit8u val) { case 3: /* Data Rotate */ gfx(data_rotate)=val; vga.config.data_rotate=val & 7; - if (vga.config.data_rotate) LOG(LOG_VGAGFX,LOG_NORMAL)("VGA:Data Rotate used %d",val &7); +// if (val) vga.config.mh_mask|=MH_ROTATEOP else vga.config.mh_mask&=~MH_ROTATEOP; vga.config.raster_op=(val>>3) & 3; /* 0-2 Number of positions to rotate data right before it is written to @@ -83,7 +85,6 @@ void write_p3cf(Bit32u port,Bit8u val) { 2: CPU data is ORed with the latch data. 3: CPU data is XORed with the latched data. */ -// if (vga.config.data_rotate || vga.config.raster_op ) LOG_DEBUG("Data Rotate = %2X Raster op %2X",val & 7,(val>>3) & 3 ); break; case 4: /* Read Map Select Register */ /* 0-1 number of the plane Read Mode 0 will read from */ @@ -138,6 +139,19 @@ void write_p3cf(Bit32u port,Bit8u val) { break; case 6: /* Miscellaneous Register */ gfx(miscellaneous)=val; + switch ((val >> 2) & 3) { + case 0: + case 1: + vga.config.mem_base=0xa0000; + break; + case 2: + vga.config.mem_base=0xb0000; + break; + case 3: + vga.config.mem_base=0xb8000; + break; + } + if (vga.mode==M_TEXT16) VGA_SetupHandlers(); /* 0 Indicates Graphics Mode if set, Alphanumeric mode else. 1 Enables Odd/Even mode if set. @@ -182,7 +196,7 @@ void write_p3cf(Bit32u port,Bit8u val) { } Bit8u read_p3cf(Bit32u port) { -switch (gfx(index)) { + switch (gfx(index)) { case 0: /* Set/Reset Register */ return gfx(set_reset); case 1: /* Enable Set/Reset Register */ diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 81d2ee05..f87385d2 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -26,16 +26,7 @@ #include "vga.h" -Bit8u VGA_ChainedReadHandler(Bit32u start) { - return vga.mem.linear[start]; -} - -void VGA_ChainedWriteHandler(Bit32u start,Bit8u val) { - vga.mem.linear[start]=val; -}; - - -Bit8u VGA_NormalReadHandler(PhysPt start) { +static Bit8u VGA_NormalReadHandler(PhysPt start) { start-=0xa0000; vga.latch.d=vga.mem.latched[start].d; switch (vga.config.read_mode) { @@ -50,6 +41,7 @@ Bit8u VGA_NormalReadHandler(PhysPt start) { } //Nice one from DosEmu + INLINE static Bit32u RasterOp(Bit32u input,Bit32u mask) { switch (vga.config.raster_op) { case 0x00: /* None */ @@ -64,6 +56,7 @@ INLINE static Bit32u RasterOp(Bit32u input,Bit32u mask) { return 0; } + INLINE static Bit32u ModeOperation(Bit8u val) { Bit32u full; switch (vga.config.write_mode) { @@ -91,26 +84,27 @@ INLINE static Bit32u ModeOperation(Bit8u val) { return full; } -Bit8u VGA_GFX_4_ReadHandler(Bit32u start) { +static Bit8u VGA_CGA_4_ReadHandler(PhysPt start) { return vga.mem.linear[start-0xb8000]; } -void VGA_GFX_4_WriteHandler(Bit32u start,Bit8u val) { +static void VGA_CGA_4_WriteHandler(PhysPt start,Bit8u val) { start-=0xb8000; vga.mem.linear[start]=val; Bitu off; if (start>0x2000) off=320*(((start-0x2000)/80)*2+1)+((start-0x2000) % 80)*4; else off=320*(((start)/80)*2)+(start % 80)*4; - Bit32u * draw=(Bit32u *)&vga.buffer[off]; + Bit32u * draw=(Bit32u *)&vga.mem.linear[512*1024+off]; /* TODO Could also use a Bit32u lookup table for this */ - *draw=CGAWriteTable[val]; - draw=(Bit32u *)&vga.buffer[off+0x4000*4]; - *draw=CGAWriteTable[val]; + *draw=CGA_4_Table[val]; + draw=(Bit32u *)&vga.mem.linear[512*1024+off+0x4000*4]; + *draw=CGA_4_Table[val]; } -void VGA_GFX_16_WriteHandler(Bit32u start,Bit8u val) { +static void VGA_GFX_16_WriteHandler(PhysPt start,Bit8u val) { start-=0xa0000; + val=(val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate)); Bit32u data=ModeOperation(val); /* Update video memory and the pixel buffer */ VGA_Latch pixels; @@ -118,7 +112,7 @@ void VGA_GFX_16_WriteHandler(Bit32u start,Bit8u val) { pixels.d&=vga.config.full_not_map_mask; pixels.d|=(data & vga.config.full_map_mask); vga.mem.latched[start].d=pixels.d; - Bit8u * write_pixels=&vga.buffer[start<<3]; + Bit8u * write_pixels=&vga.mem.linear[512*1024+(start<<3)]; Bit32u colors0_3, colors4_7; VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f; @@ -140,36 +134,75 @@ void VGA_GFX_16_WriteHandler(Bit32u start,Bit8u val) { } -void VGA_GFX_256U_WriteHandler(Bit32u start,Bit8u val) { +static void VGA_GFX_256U_WriteHandler(PhysPt start,Bit8u val) { start-=0xa0000; Bit32u data=ModeOperation(val); +// Bit32u data=ExpandTable[val]; VGA_Latch pixels; pixels.d=vga.mem.latched[start].d; pixels.d&=vga.config.full_not_map_mask; pixels.d|=(data & vga.config.full_map_mask); vga.mem.latched[start].d=pixels.d; vga.mem.latched[start+64*1024].d=pixels.d; -}; - - - - - - - - +} +static void VGA_TEXT16_Write(PhysPt start,Bit8u val) { + start-=vga.config.mem_base; + /* Check for page 2 being enabled for writing */ + if (vga.seq.map_mask & 0x4) { + vga.draw.font[start]=val; + } + //TODO Check for writes to other pages with normal text characters/attributes +} +static Bit8u VGA_TEXT16_Read(PhysPt start) { + start-=vga.config.mem_base; + return vga.draw.font[start]; +} +void VGA_SetupHandlers(void) { + /* Sets up the correct memory handler from the vga.mode setting */ + MEM_ClearPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x20000)); + switch (vga.mode) { + case M_LIN8: + MEM_SetupMapping(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000),&vga.mem.linear[vga.s3.bank*64*1024]); + break; + case M_VGA: + if (vga.config.chained) { + MEM_SetupMapping(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000),&vga.mem.linear[vga.s3.bank*64*1024]); + } else { + MEM_SetupPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000), + &VGA_NormalReadHandler,&VGA_GFX_256U_WriteHandler); + } + break; + case M_EGA16: + MEM_SetupPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000), + &VGA_NormalReadHandler,&VGA_GFX_16_WriteHandler); + break; + case M_TEXT16: + /* Check if we're not in odd/even mode */ + if (vga.gfx.miscellaneous & 0x2) break; + MEM_SetupPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000),&VGA_TEXT16_Read,&VGA_TEXT16_Write); + //Could also do it using 0xb8000, let's double map + MEM_SetupPageHandlers(PAGE_COUNT(0xb8000),PAGE_COUNT(0x8000),&VGA_TEXT16_Read,&VGA_TEXT16_Write); + break; + case M_TANDY16: + MEM_SetupMapping(PAGE_COUNT(0xb8000),PAGE_COUNT(0x8000),&vga.mem.linear[vga.tandy.mem_bank << 14]); + break; + case M_CGA4: + case M_CGA2: + break; + default: + LOG_MSG("Unhandled vga mode %X",vga.mode); + } +} void VGA_SetupMemory() { - memset((void *)&vga.mem,0,256*1024); - /* Alocate Video Memory */ - /* Not needed for VGA memory it gets allocated together with emulator maybe - later for VESA memory */ - + memset((void *)&vga.mem,0,512*1024*4); + /* Map linear frame buffer at 32 mb */ + MEM_SetupMapping(PAGE_COUNT(32*1024*1024),PAGE_COUNT(2*1024*1024),&vga.mem); } diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 82d5d984..b08f322b 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -48,16 +48,95 @@ static Bit8u read_p3da(Bit32u port) { static void write_p3d8(Bit32u port,Bit8u val) { - LOG(LOG_VGAMISC,LOG_NORMAL)("Write %2X to 3da",val); + switch (vga.mode) { + case M_CGA4: + + break; + default: + break; + } + LOG(LOG_VGAMISC,LOG_NORMAL)("Write %2X to 3d8",val); /* 3 Vertical Sync Select. If set Vertical Sync to the monitor is the logical OR of the vertical sync and the vertical display enable. */ } -static void write_p3c2(Bit32u port,Bit8u val) { - p3c2data=val; +static void write_p3d9(Bit32u port,Bit8u val) { + switch (vga.mode) { + case M_CGA2: + vga.cga.color_select=val; + /* changes attribute 1 */ + vga.attr.palette[1]=(val & 7) + ((val & 8) ? 0x38 : 0); + VGA_DAC_CombineColor(1,vga.attr.palette[0]); + break; + case M_CGA4: + vga.cga.color_select=val; + /* changes attribute 0 */ + VGA_ATTR_SetPalette(0,(val & 7) + ((val & 8) ? 0x38 : 0)); + if (val & 0x020) { + VGA_ATTR_SetPalette(1,0x13); + VGA_ATTR_SetPalette(2,0x15); + VGA_ATTR_SetPalette(3,0x17); + } else { + VGA_ATTR_SetPalette(1,0x02); + VGA_ATTR_SetPalette(2,0x04); + VGA_ATTR_SetPalette(3,0x06); + } + break; + /* Color Select register + Text modes: 320x200 modes: 640x200 mode: + 0 Blue border Blue background Blue ForeGround + 1 Green border Green background Green ForeGround + 2 Red border Red background Red ForeGround + 3 Bright border Bright background Bright ForeGround + 4 Backgr. color Alt. intens. colors Alt. intens colors + 5 No func. Selects palette + Palette 0 is Green, red and brown, + Palette 1 is Cyan, magenta and white. + */ + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to %X in mode %d",val,port,vga.mode); + } +} +static void write_p3df(Bit32u port,Bit8u val) { + switch (vga.mode) { + case M_TANDY16: + vga.tandy.disp_bank=val & ((val & 0x80) ? 0x6 : 0x7); + vga.tandy.mem_bank=(val >> 3) & ((val & 0x80) ? 0x6 : 0x7); + VGA_SetupHandlers(); + + break; + /* + 0-2 Identifies the page of main memory being displayed in units of 16K. + 0: 0K, 1: 16K...7: 112K. In 32K modes (bits 6-7 = 2) only 0,2,4 and + 6 are valid, as the next page will also be used. + 3-5 Identifies the page of main memory that can be read/written at B8000h + in units of 16K. 0: 0K, 1: 16K...7: 112K. In 32K modes (bits 6-7 = 2) + only 0,2,4 and 6 are valid, as the next page will also be used. + 6-7 Display mode. 0: Text, 1: 16K graphics mode (4,5,6,8) + 2: 32K graphics mode (9,Ah) + */ + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to %X in mode %d",val,port,vga.mode); + break; + } +} + +static Bit8u read_p3d9(Bit32u port) { + switch (vga.mode) { + case M_CGA2: + case M_CGA4: + return vga.cga.color_select; + default: + return 0xff; + } +} + + +static void write_p3c2(Bit32u port,Bit8u val) { + vga.misc_output=val; if (val & 0x1) { IO_RegisterWriteHandler(0x3d4,write_p3d4,"VGA:CRTC Index Select"); IO_RegisterReadHandler(0x3d4,read_p3d4,"VGA:CRTC Index Select"); @@ -77,11 +156,6 @@ static void write_p3c2(Bit32u port,Bit8u val) { IO_FreeWriteHandler(0x3d5); IO_FreeReadHandler(0x3d5); } - if (val & 0x4) vga.config.clock=28322000; - else vga.config.clock=25175000; - - VGA_StartResize(); - /* 0 If set Color Emulation. Base Address=3Dxh else Mono Emulation. Base Address=3Bxh. 2-3 Clock Select. 0: 25MHz, 1: 28MHz @@ -97,7 +171,7 @@ static void write_p3c2(Bit32u port,Bit8u val) { static Bit8u read_p3cc(Bit32u port) { - return p3c2data; + return vga.misc_output; } void VGA_SetupMisc(void) { @@ -105,8 +179,17 @@ void VGA_SetupMisc(void) { IO_RegisterReadHandler(0x3ba,read_p3da,"VGA Input Status 1"); IO_RegisterWriteHandler(0x3d8,write_p3d8,"VGA Feature Control Register"); + + + IO_RegisterWriteHandler(0x3d9,write_p3d9,"CGA Color Select Register"); + IO_RegisterReadHandler(0x3d9,read_p3d9,"CGA Color Select Register"); + + IO_RegisterWriteHandler(0x3c2,write_p3c2,"VGA Misc Output"); + IO_RegisterReadHandler(0x3cc,read_p3cc,"VGA Misc Output"); + IO_RegisterWriteHandler(0x3df,write_p3df,"PCJR Setting"); + } diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index c4b6f198..c608cc69 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -31,6 +31,8 @@ void write_p3c4(Bit32u port,Bit8u val) { }; void write_p3c5(Bit32u port,Bit8u val) { + if (seq(index)>0x8 && vga.s3.pll.lock!=0x6) return; +// LOG_MSG("SEQ WRITE reg %X val %X",seq(index),val); switch(seq(index)) { case 0: /* Reset */ seq(reset)=val; @@ -88,8 +90,31 @@ void write_p3c5(Bit32u port,Bit8u val) { /* Changing this means changing the VGA Memory Read/Write Handler */ if (val&0x08) vga.config.chained=true; else vga.config.chained=false; - VGA_FindSettings(); + VGA_SetupHandlers(); break; +/* S3 specific group */ + case 0x08: + vga.s3.pll.lock=val; + break; + case 0x10: /* Memory PLL Data Low */ + vga.s3.mclk.n=val & 0x1f; + vga.s3.mclk.r=val >> 5; + break; + case 0x11: /* Memory PLL Data High */ + vga.s3.mclk.m=val & 0x7f; + break; + case 0x12: /* Video PLL Data Low */ + vga.s3.clk[3].n=val & 0x1f; + vga.s3.clk[3].r=val >> 5; + break; + case 0x13: /* Video PLL Data High */ + vga.s3.clk[3].m=val & 0x7f; + break; + case 0x15: + vga.s3.pll.cmd=val; + VGA_StartResize(); + break; + default: LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:Write to illegal index %2X",seq(index)); }; @@ -97,21 +122,37 @@ void write_p3c5(Bit32u port,Bit8u val) { Bit8u read_p3c5(Bit32u port) { +// LOG_MSG("VGA:SEQ:Read from index %2X",seq(index)); + if (seq(index)>0x8 && vga.s3.pll.lock!=0x6) return seq(index); switch(seq(index)) { - case 0: /* Reset */ + case 0: /* Reset */ return seq(reset); break; - case 1: /* Clocking Mode */ + case 1: /* Clocking Mode */ return seq(clocking_mode); break; - case 2: /* Map Mask */ + case 2: /* Map Mask */ return seq(map_mask); break; - case 3: /* Character Map Select */ + case 3: /* Character Map Select */ return seq(character_map_select); break; - case 4: /* Memory Mode */ + case 4: /* Memory Mode */ return seq(memory_mode); + /* S3 specific group */ + case 0x08: /* PLL Unlock */ + return vga.s3.pll.lock; + case 0x10: /* Memory PLL Data Low */ + return vga.s3.mclk.n || (vga.s3.mclk.r << 5); + case 0x11: /* Memory PLL Data High */ + return vga.s3.mclk.m; + case 0x12: /* Video PLL Data Low */ + return vga.s3.clk[3].n || (vga.s3.clk[3].r << 5); + case 0x13: /* Video Data High */ + return vga.s3.clk[3].m; + case 0x15: + return vga.s3.pll.cmd; + default: LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:Read from illegal index %2X",seq(index)); }; From bf7b67272eb072325ebda032166e84907e9e4ab5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 15 Jun 2003 19:52:52 +0000 Subject: [PATCH 0984/4131] Removed vga_fonts.cpp Added int10_vesa.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1064 --- visualc/dosbox.dsp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index be93b060..d6577e94 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -402,10 +402,6 @@ SOURCE=..\src\hardware\vga_draw.cpp # End Source File # Begin Source File -SOURCE=..\src\hardware\vga_fonts.cpp -# End Source File -# Begin Source File - SOURCE=..\src\hardware\vga_gfx.cpp # End Source File # Begin Source File @@ -532,6 +528,10 @@ SOURCE=..\src\ints\int10_pal.cpp SOURCE=..\src\ints\int10_put_pixel.cpp # End Source File +# Begin Source File + +SOURCE=..\src\ints\int10_vesa.cpp +# End Source File # End Group # Begin Source File From 056921a226eb86d4f6ecc82e85cb30bc602d32f5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 15 Jun 2003 19:54:58 +0000 Subject: [PATCH 0985/4131] No longer need vga_fonts.cpp, since fonts are loaded from bios Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1065 --- src/hardware/vga_fonts.cpp | 1254 ------------------------------------ 1 file changed, 1254 deletions(-) delete mode 100644 src/hardware/vga_fonts.cpp diff --git a/src/hardware/vga_fonts.cpp b/src/hardware/vga_fonts.cpp deleted file mode 100644 index f5e75640..00000000 --- a/src/hardware/vga_fonts.cpp +++ /dev/null @@ -1,1254 +0,0 @@ -/* - * Copyright (C) 2002-2003 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* - * Bitmap fonts for the VGA emulation; taken from - * ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip - * - * See copyleft_vgafonts.txt for the copyright notice. - */ -#include "dosbox.h" -#include "mem.h" -#include "vga.h" - -Bit8u vga_rom_08[256 * 8] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, - 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, - 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, - 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, - 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c, - 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, - 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, - 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, - 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, - 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, - 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, - 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, - 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0, - 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, - 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99, - 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, - 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, - 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, - 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, - 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78, - 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, - 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff, - 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, - 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, - 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, - 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, - 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, - 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, - 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, - 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00, - 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, - 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, - 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, - 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, - 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, - 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, - 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, - 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, - 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, - 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, - 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00, - 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, - 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00, - 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, - 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, - 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, - 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00, - 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, - 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, - 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, - 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, - 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, - 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, - 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, - 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00, - 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, - 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00, - 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, - 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, - 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, - 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00, - 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, - 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, - 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, - 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, - 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, - 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, - 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, - 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, - 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00, - 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, - 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00, - 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, - 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00, - 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, - 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00, - 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, - 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00, - 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, - 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, - 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, - 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, - 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, - 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00, - 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, - 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, - 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, - 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, - 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, - 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, - 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00, - 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, - 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, - 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, - 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00, - 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, - 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00, - 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, - 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, - 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00, - 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, - 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00, - 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, - 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78, - 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, - 0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, - 0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00, - 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, - 0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, - 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, - 0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38, - 0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00, - 0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, - 0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, - 0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, - 0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, - 0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00, - 0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00, - 0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00, - 0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00, - 0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, - 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, - 0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, - 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, - 0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00, - 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, - 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18, - 0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00, - 0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30, - 0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7, - 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70, - 0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, - 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, - 0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00, - 0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00, - 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, - 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, - 0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, - 0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f, - 0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03, - 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, - 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00, - 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00, - 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, - 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, - 0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, - 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, - 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, - 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, - 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, - 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, - 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, - 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, - 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, - 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00, - 0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0, - 0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, - 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, - 0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00, - 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00, - 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0, - 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00, - 0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc, - 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00, - 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00, - 0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, - 0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0, - 0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00, - 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, - 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00, - 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00, - 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, - 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00, - 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, - 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, - 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, - 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, - 0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, - 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -Bit8u vga_rom_14[256 * 14] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, - 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, - 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, - 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, - 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, - 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, - 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, - 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, - 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x70, 0xf0, - 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, - 0x7f, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, - 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, 0xf8, - 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x06, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x06, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, - 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, - 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x7c, - 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, - 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, - 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, - 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, - 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, - 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, - 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, - 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x66, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, - 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0x76, 0x00, - 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, - 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, - 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, - 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, - 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, - 0x3c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, - 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x60, - 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x0c, - 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, - 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x0c, - 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, - 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, - 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, - 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, - 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, - 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0xfc, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, - 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, - 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xf0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, - 0xc0, 0xde, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, - 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe6, 0x66, 0x6c, 0x6c, - 0x78, 0x6c, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, - 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xe6, - 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, - 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, - 0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, - 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, - 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, - 0xd6, 0xd6, 0xfe, 0x7c, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x38, - 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, - 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, - 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x3c, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, - 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, - 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, - 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x7c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, - 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, - 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, - 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xf0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, - 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, - 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, - 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, - 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, - 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, - 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, - 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0xf0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, - 0xc6, 0x70, 0x1c, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, - 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, - 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, - 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, - 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, - 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x66, 0xfe, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, - 0x70, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, - 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, - 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, - 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc2, - 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, 0x00, - 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, - 0x76, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, - 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, - 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x78, 0x0c, 0x7c, - 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x60, - 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, - 0x76, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, - 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, - 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, - 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xcc, 0xcc, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, - 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x38, - 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, - 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x60, - 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x10, - 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, - 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, - 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, - 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, - 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xce, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, - 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x60, - 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0xcc, - 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, - 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, - 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, - 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, 0x00, 0xc6, - 0xc6, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, - 0x38, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x00, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, - 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, - 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, - 0x18, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, 0xcc, - 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xc6, 0x00, - 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, - 0x7e, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, - 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x0c, - 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, - 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, - 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x76, 0xdc, - 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, - 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, - 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, - 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, - 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x66, - 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x3c, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, - 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, - 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x55, 0xaa, - 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, - 0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, - 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, - 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, - 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, - 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, - 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, - 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, - 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, - 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xfc, 0xc6, 0xc6, 0xfc, - 0xc0, 0xc0, 0x40, 0x00, 0x00, 0x00, 0xfe, 0xc6, - 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, - 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, - 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, - 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, - 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, - 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, - 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, - 0x3e, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, - 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, - 0x60, 0x60, 0x7c, 0x60, 0x60, 0x30, 0x1c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, - 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, - 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, - 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, - 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, - 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0xec, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, - 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -Bit8u vga_rom_16[256 * 16] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, - 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, - 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, - 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, - 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, - 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, - 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, - 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, - 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, - 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, - 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, - 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, - 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, - 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, - 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, - 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, - 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, - 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, - 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, - 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, - 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, - 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, - 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, - 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, - 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, - 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, - 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, - 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, - 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, - 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, - 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, - 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, - 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, - 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, - 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, - 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, - 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, - 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, - 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, - 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, - 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, - 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, - 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, - 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, - 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, - 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, - 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, - 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, - 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, - 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, - 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, - 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, - 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, - 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, - 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, - 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, - 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, - 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, - 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, - 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, - 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, - 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, - 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, - 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, - 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, - 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, - 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, - 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, - 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, - 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, - 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, - 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, - 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, - 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, - 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, - 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, - 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, - 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, - 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, - 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, - 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, - 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, - 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, - 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, - 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, - 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, - 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, - 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, - 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, - 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, - 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, - 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, - 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, - 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, - 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, - 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, - 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, - 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, - 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, - 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, - 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, - 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, - 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, - 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, - 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, - 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, - 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, - 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00, - 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, - 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, - 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, - 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, - 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, - 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, - 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, - 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, - 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, - 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, - 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, - 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, - 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, - 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, - 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, - 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, - 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, - 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, - 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, - 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, - 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, - 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, - 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, - 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, - 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, - 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, - 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, - 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, - 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, - 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, - 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - - From 188379a5422f62c2f1c0f94628f3dbbe4c9484d2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 15 Jun 2003 19:55:31 +0000 Subject: [PATCH 0986/4131] remove vga_fonts.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1066 --- src/hardware/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index 6fca05e8..e950ad3a 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -6,7 +6,7 @@ noinst_LIBRARIES = libhardware.a libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler.cpp joystick.cpp keyboard.cpp \ memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ - vga.cpp vga.h vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_fonts.cpp vga_gfx.cpp \ + vga.cpp vga.h vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp \ vga_memory.cpp vga_misc.cpp vga_seq.cpp font-switch.h ega-switch.h cmos.cpp disney.cpp \ gus.cpp mpu401.cpp From 9db66c505b51aa9f004dc4c2d6cfbcb35db76b24 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 15 Jun 2003 19:56:20 +0000 Subject: [PATCH 0987/4131] Added int10_vesa.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1067 --- src/ints/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ints/Makefile.am b/src/ints/Makefile.am index 4a35bac5..e1ffaba2 100644 --- a/src/ints/Makefile.am +++ b/src/ints/Makefile.am @@ -2,5 +2,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libints.a libints_a_SOURCES = mouse.cpp xms.cpp xms.h ems.cpp dpmi.cpp \ - int10.cpp int10.h int10_char.cpp int10_memory.cpp int10_misc.cpp int10_modes.cpp int10_pal.cpp int10_put_pixel.cpp \ + int10.cpp int10.h int10_char.cpp int10_memory.cpp int10_misc.cpp int10_modes.cpp \ + int10_vesa.cpp int10_pal.cpp int10_put_pixel.cpp \ bios.cpp bios_disk.cpp bios_keyboard.cpp From 1dbdb9412a759465340a8683d330eaef8988c68c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 15 Jun 2003 20:35:37 +0000 Subject: [PATCH 0988/4131] Changed interrupt 0x11 to read from bios segment Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1068 --- src/ints/bios.cpp | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 1ced4de8..3b23e9ae 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -106,30 +106,7 @@ static Bitu INT1A_Handler(void) { } static Bitu INT11_Handler(void) { - /* - AX = BIOS equipment list word - bits - 0 floppy disk(s) installed (see bits 6-7) - 1 80x87 coprocessor installed - 2,3 number of 16K banks of RAM on motherboard (PC only) - number of 64K banks of RAM on motherboard (XT only) - 2 pointing device installed (PS) - 3 unused (PS) - 4-5 initial video mode - 00 EGA, VGA, or PGA - 01 40x25 color - 10 80x25 color - 11 80x25 monochrome - 6-7 number of floppies installed less 1 (if bit 0 set) - 8 DMA support installed (PCjr, some Tandy 1000s, 1400LT) - 9-11 number of serial ports installed - 12 game port installed - 13 serial printer attached (PCjr) - internal modem installed (PC/Convertible) - 14-15 number of parallel ports installed - */ - reg_ax=0x104D; - LOG(LOG_BIOS,LOG_NORMAL)("INT11:Equipment list returned %X",reg_ax); + reg_ax=mem_readw(BIOS_CONFIGURATION); return CBRET_NONE; } @@ -342,12 +319,16 @@ void BIOS_Init(Section* sec) { CALLBACK_Setup(call_int1,&INT1_Single_Step,CB_IRET); RealSetVec(0x1,CALLBACK_RealPointer(call_int1)); + /* Setup some stuff in 0x40 bios segment */ /* Test for parallel port */ if (IO_Read(0x378)!=0xff) real_writew(0x40,0x08,0x378); /* Test for serial port */ Bitu index=0; if (IO_Read(0x3f8)!=0xff) real_writew(0x40,(index++)*2,0x3f8); if (IO_Read(0x2f8)!=0xff) real_writew(0x40,(index++)*2,0x2f8); + /* Setup equipment list */ + mem_writew(BIOS_CONFIGURATION,0xc823); //1 Floppy,FPU,2 serial, 1 parallel + } From feee892489d587e31a84955eb0608d98bc235513 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 16 Jun 2003 12:26:34 +0000 Subject: [PATCH 0989/4131] Add a newline Added cast to allow string to be used an argument for blockwrite Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1069 --- src/ints/int10_vesa.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 029bcb3f..007441cb 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -88,7 +88,7 @@ Bit8u VESA_GetSVGAInformation(Bit16u seg,Bit16u off) { for (i=0;i<0x100;i++) mem_writeb(buffer+i,0); } /* Fill common data */ - MEM_BlockWrite(buffer,"VESA",4); //Identification + MEM_BlockWrite(buffer,(void *)"VESA",4); //Identification mem_writew(buffer+0x04,0x102); //Vesa version mem_writed(buffer+0x06,int10.rom.oemstring); //Oemstring mem_writed(buffer+0x0a,0x0); //Capabilities and flags @@ -294,5 +294,5 @@ void INT10_SetupVESA(void) { int10.rom.used+=len; callback.setwindow=CALLBACK_Allocate(); CALLBACK_Setup(callback.setwindow,SetWindowPositionHandler,CB_RETF); +} -} \ No newline at end of file From 90140ef5fcda63876c9ba7145068ce9785b49c94 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 16 Jun 2003 12:29:43 +0000 Subject: [PATCH 0990/4131] Changes to always include debug_win32.cpp in the make. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1070 --- src/debug/Makefile.am | 3 +-- src/debug/debug_win32.cpp | 7 ++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/debug/Makefile.am b/src/debug/Makefile.am index a939db12..dfee7924 100644 --- a/src/debug/Makefile.am +++ b/src/debug/Makefile.am @@ -1,5 +1,4 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -EXTRA_DIST = debug_win32.cpp noinst_LIBRARIES = libdebug.a -libdebug_a_SOURCES = debug.cpp debug_gui.cpp debug_disasm.cpp debug_inc.h disasm_tables.h \ No newline at end of file +libdebug_a_SOURCES = debug.cpp debug_gui.cpp debug_disasm.cpp debug_inc.h disasm_tables.h debug_win32.cpp \ No newline at end of file diff --git a/src/debug/debug_win32.cpp b/src/debug/debug_win32.cpp index 28f94711..33c1ea54 100644 --- a/src/debug/debug_win32.cpp +++ b/src/debug/debug_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifdef WIN32 + #include #include #include @@ -70,5 +72,4 @@ void WIN32_Console() { } - - +#endif From d23a0871e3ac7ffccdd531e4d0e77950ed529505 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 17 Jun 2003 06:10:09 +0000 Subject: [PATCH 0991/4131] REP SCASD Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1071 --- src/cpu/core_full/string.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index e2824894..b4d5d237 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -162,6 +162,18 @@ CMPW(reg_ax,val2,LoadD,0); } break; + case R_SCASD: + { + add_index<<=2;Bit32u val2; + for (;count>0;) { + count--; + val2=LoadMd(di_base+di_index); + di_index=(di_index+add_index) & add_mask; + if ((reg_eax==val2)!=inst.repz) break; + } + CMPD(reg_eax,val2,LoadD,0); + } + break; case R_CMPSB: { Bit8u val1,val2; From 7338e635664494777f62ddea29cf312307beabe6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 17 Jun 2003 20:27:01 +0000 Subject: [PATCH 0992/4131] Reverse active and deactive keyboard commands Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1072 --- src/hardware/keyboard.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index a85de1b2..c73f585e 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -212,7 +212,7 @@ static void write_p61(Bit32u port,Bit8u val) { static void write_p64(Bit32u port,Bit8u val) { switch (val) { - case 0xad: /* Activate keyboard */ + case 0xae: /* Activate keyboard */ keyb.active=true; if (keyb.buf.used && !keyb.scheduled) { keyb.scheduled=true; @@ -220,7 +220,7 @@ static void write_p64(Bit32u port,Bit8u val) { } LOG(LOG_KEYBOARD,LOG_NORMAL)("Activated"); break; - case 0xae: /* Deactivate keyboard */ + case 0xad: /* Deactivate keyboard */ keyb.active=false; PIC_DeActivateIRQ(1); PIC_RemoveEvents(KEYBOARD_GetCode); From fdd6fdcb2c630b75ab30deec1a022417feeaea7c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 18 Jun 2003 07:16:31 +0000 Subject: [PATCH 0993/4131] Removed C_MEM_MAX_SIZE Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1073 --- src/dosbox.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index fc53a725..a1b07714 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -172,8 +172,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&IO_Init); secprop->AddInitFunction(&MEM_Init); - /* Keep 1 mb free for video memory some day */ - secprop->Add_int("memsize",C_MEM_MAX_SIZE-1); + secprop->Add_int("memsize",8); //Default to 8 mb total memory secprop->AddInitFunction(&CALLBACK_Init); secprop->AddInitFunction(&PIC_Init); secprop->AddInitFunction(&PROGRAMS_Init); From df749c8286f579bab2d9bf59978959797a87e9ea Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 18 Jun 2003 07:20:46 +0000 Subject: [PATCH 0994/4131] Changed configure to enable FPU by default Rewrote some scripts Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1074 --- acinclude.m4 | 7 ------- configure.in | 12 ++++++++++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index bdf27631..84406fc3 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -326,8 +326,6 @@ AH_TOP([ */ ]) -AH_TEMPLATE([C_HAS_ATTRIBUTE],[Determines if the compilers supports attributes for structures.]) - AH_BOTTOM([#define INLINE inline]) AH_BOTTOM([#if C_HAS_ATTRIBUTE @@ -343,11 +341,6 @@ AH_BOTTOM([ /* Enable some big compile-time increasing inlines */ #define C_EXTRAINLINE 0 -/* Enable the FPU module, still only for beta testing */ -#define C_FPU 0 - -/* Maximum memory address range in megabytes */ -#define C_MEM_MAX_SIZE 12 ]) diff --git a/configure.in b/configure.in index 67e2888a..655c9e37 100644 --- a/configure.in +++ b/configure.in @@ -48,6 +48,7 @@ AC_TRY_LINK([extern char ** environ;],[*environ;], dnl Checks for libraries. #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_TRY_COMPILE([], [typedef struct { } __attribute__ ((packed)) junk;], [ AC_MSG_RESULT(yes);AC_DEFINE(C_HAS_ATTRIBUTE)],AC_MSG_RESULT(no)) @@ -59,7 +60,7 @@ AC_C_BIGENDIAN #Features to enable/disable AH_TEMPLATE(C_DEBUG,[Define to 1 to enable internal debugger, requires libcurses]) -AC_ARG_ENABLE(debug,[ --enable-debug Enable debug mode],[ +AC_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, , ) @@ -72,7 +73,7 @@ AC_ARG_ENABLE(debug,[ --enable-debug Enable debug mode],[ ],) AH_TEMPLATE(C_SSHOT,[Define to 1 to enable screenshots, requires libpng]) -AC_ARG_ENABLE(shots,[ --enable-shots Enable screenshot support],[ +AC_ARG_ENABLE(shots,AC_HELP_STRING([--enable-shots],[Enable screenshot support]),[ AC_CHECK_HEADER(png.h,have_png_h=yes,) AC_CHECK_LIB(png, png_check_sig, have_png_lib=yes, ,-lz) if test x$have_png_lib = xyes -a x$have_png_h = xyes ; then @@ -83,6 +84,13 @@ AC_ARG_ENABLE(shots,[ --enable-shots Enable screenshot support],[ 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]), + AC_MSG_RESULT([FPU support has been disabled]), + AC_DEFINE(C_FPU,1) +) + dnl Some host detection and actions for them case "$target" in *-*-cygwin* | *-*-mingw32*) From 4cff9c2f1e4850769d3a5a1cbe7846c1b6168b26 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 18 Jun 2003 19:50:46 +0000 Subject: [PATCH 0995/4131] improved breakpoint handling in protected mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1075 --- src/debug/debug.cpp | 81 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 69 insertions(+), 12 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index ec68da39..ad33a6e1 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -45,12 +45,15 @@ void WIN32_Console(); static struct termios consolesettings; int old_cursor_state; #endif + // Forwards static void DrawCode(void); static bool DEBUG_Log_Loop(int count); static void DEBUG_RaiseTimerIrq(void); char* AnalyzeInstruction(char* inst, bool saveSelector); void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num); +Bit32u GetHexValue(char* str, char*& hex); + class DEBUG; DEBUG* pDebugcom = 0; @@ -122,7 +125,8 @@ bool GetDescriptorInfo(char* selname, char* out1, char* out2) if (strstr(selname,"es") || strstr(selname,"ES")) sel = SegValue(es); else if (strstr(selname,"fs") || strstr(selname,"FS")) sel = SegValue(fs); else if (strstr(selname,"gs") || strstr(selname,"GS")) sel = SegValue(gs); else - if (strstr(selname,"ss") || strstr(selname,"SS")) sel = SegValue(ss); + if (strstr(selname,"ss") || strstr(selname,"SS")) sel = SegValue(ss); else + sel = GetHexValue(selname,selname); // FIXME: Call Gate Descriptors if (cpu.gdt.GetDescriptor(sel,desc)) { sprintf(out1,"%s: b:%08X type:%02X parbg",selname,desc.GetBase(),desc.saved.seg.type); @@ -204,6 +208,7 @@ public: static CBreakpoint* AddMemBreakpoint (Bit16u seg, Bit32u off); static void ActivateBreakpoints (PhysPt adr, bool activate); static bool CheckBreakpoint (PhysPt adr); + static bool CheckBreakpoint (Bitu seg, Bitu off); static bool CheckIntBreakpoint (PhysPt adr, Bit8u intNr, Bit16u ahValue); static bool IsBreakpoint (PhysPt where); static bool IsBreakpointDrawn (PhysPt where); @@ -257,6 +262,7 @@ void CBreakpoint::Activate(bool _active) // Statics std::list CBreakpoint::BPoints; CBreakpoint* CBreakpoint::ignoreOnce = 0; +Bitu ignoreAddressOnce = 0; CBreakpoint* CBreakpoint::AddBreakpoint(Bit16u seg, Bit32u off, bool once) { @@ -302,15 +308,21 @@ void CBreakpoint::ActivateBreakpoints(PhysPt adr, bool activate) }; }; -bool CBreakpoint::CheckBreakpoint(PhysPt adr) +bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off) // Checks if breakpoint is valid an should stop execution { + if ((ignoreAddressOnce!=0) && (GetAddress(seg,off)==ignoreAddressOnce)) { + ignoreAddressOnce = 0; + return false; + } else + ignoreAddressOnce = 0; + // Search matching breakpoint std::list::iterator i; CBreakpoint* bp; for(i=BPoints.begin(); i != BPoints.end(); i++) { bp = static_cast(*i); - if ((bp->GetType()==BKPNT_PHYSICAL) && bp->IsActive() && (bp->GetLocation()==adr)) { + if ((bp->GetType()==BKPNT_PHYSICAL) && bp->IsActive() && (bp->GetSegment()==seg) && (bp->GetOffset()==off)) { // Ignore Once ? if (ignoreOnce==bp) { ignoreOnce=0; @@ -331,8 +343,10 @@ bool CBreakpoint::CheckBreakpoint(PhysPt adr) #if C_HEAVY_DEBUG // Memory breakpoint support else if ((bp->GetType()==BKPNT_MEMORY) && bp->IsActive()) { - - Bit8u value = mem_readb(bp->GetLocation()); + + Bitu address = GetAddress(bp->GetSegment(),bp->GetOffset()); +// Bitu address = bp->GetSegment()*16 + bp->GetOffset(); + Bit8u value = mem_readb(address); if (bp->GetValue() != value) { // Yup, memory value changed @@ -350,6 +364,12 @@ bool CBreakpoint::CheckBreakpoint(PhysPt adr) bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue) // Checks if interrupt breakpoint is valid an should stop execution { + if ((ignoreAddressOnce!=0) && (adr==ignoreAddressOnce)) { + ignoreAddressOnce = 0; + return false; + } else + ignoreAddressOnce = 0; + // Search matching breakpoint std::list::iterator i; CBreakpoint* bp; @@ -437,6 +457,9 @@ bool CBreakpoint::IsBreakpoint(PhysPt adr) CBreakpoint* bp; for(i=BPoints.begin(); i != BPoints.end(); i++) { bp = static_cast(*i); + if ((bp->GetType()==BKPNT_PHYSICAL) && (bp->GetSegment()==adr)) { + return true; + }; if ((bp->GetType()==BKPNT_PHYSICAL) && (bp->GetLocation()==adr)) { return true; }; @@ -487,7 +510,7 @@ bool DEBUG_Breakpoint(void) /* First get the phyiscal address and check for a set Breakpoint */ // PhysPt where=SegPhys(cs)+reg_eip-1; PhysPt where=GetAddress(SegValue(cs),reg_eip-1); - if (!CBreakpoint::CheckBreakpoint(where)) return false; + if (!CBreakpoint::CheckBreakpoint(SegValue(cs),reg_eip-1)) return false; // Found. Breakpoint is valid reg_eip -= 1; CBreakpoint::ActivateBreakpoints(where,false); // Deactivate all breakpoints @@ -515,7 +538,7 @@ static bool StepOver() // PhysPt start=SegPhys(cs)+reg_eip; PhysPt start=GetAddress(SegValue(cs),reg_eip); char dline[200];Bitu size; - size=DasmI386(dline, start, reg_eip, (cpu.state & STATE_USE32)>0); + size=DasmI386(dline, start, reg_eip, (cpu.state & STATE_USE32>0)); if (strstr(dline,"call") || strstr(dline,"int") || strstr(dline,"loop") || strstr(dline,"rep")) { CBreakpoint::AddBreakpoint (SegValue(cs),reg_eip+size, true); @@ -543,6 +566,7 @@ bool DEBUG_ExitLoop(void) static void DrawData(void) { + Bit8u ch; Bit32u add = dataOfs; Bit32u address; /* Data win */ @@ -551,7 +575,7 @@ static void DrawData(void) { mvwprintw (dbg.win_data,1+y,0,"%04X:%04X ",dataSeg,add); for (int x=0; x<16; x++) { address = GetAddress(dataSeg,add); - Bit8u ch = mem_readb(address); + if (address<8*1024*1024) ch = mem_readb(address); else ch = 0; mvwprintw (dbg.win_data,1+y,11+3*x,"%02X",ch); if (ch<32) ch='.'; mvwprintw (dbg.win_data,1+y,60+x,"%c",ch); @@ -608,6 +632,9 @@ static void DrawRegisters(void) { oldflags=flags.word; + if (cpu.state & STATE_PROTECTED) mvwprintw(dbg.win_reg,0,76,"Prot"); + else mvwprintw(dbg.win_reg,0,76,"Real"); + // Selector info, if available if ((cpu.state & STATE_PROTECTED) && curSelectorName[0]) { char out1[200], out2[200]; @@ -994,6 +1021,15 @@ bool ParseCommand(char* str) DEBUG_ShowMsg("%s",out2); }; +/* found = strstr(str,"EXCEPTION "); + if (found) { + found += 9; + Bit8u num = GetHexValue(found,found); + DPMI_CreateException(num,0xDD); + DEBUG_ShowMsg("Exception %04X",num); + }; +*/ + #if C_HEAVY_DEBUG found = strstr(str,"HEAVYLOG"); if (found) { // Create Cpu log file @@ -1228,7 +1264,8 @@ Bit32u DEBUG_CheckKeys(void) { break; case KEY_F(5): // Run Programm debugging=false; - CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); + CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); + ignoreAddressOnce = SegPhys(cs)+reg_eip; DOSBOX_SetNormalLoop(); break; case KEY_F(9): // Set/Remove TBreakpoint @@ -1627,13 +1664,33 @@ bool DEBUG_HeavyIsBreakpoint(void) return false; } +/* static bool once = false; + Descriptor desc; + if (!once && cpu.gdt.GetDescriptor(0x44,desc)) { + if (desc.GetBase()==0x40000000) { + LOG(LOG_ERROR,"Selector 44 base 0x40000000: %04X,%08X",SegValue(cs),reg_eip); + once = true; + exitLoop = true; + DEBUG_Enable(); + return true; + }; + } +*/ +/* if (cpu.state & STATE_PROTECTED) { + if ((reg_ebx==0x000F)) { + exitLoop = true; + DEBUG_Enable(); + return true; + } + } +*/ PhysPt where = SegPhys(cs)+reg_eip; - if (CBreakpoint::CheckBreakpoint(where)) { + if (CBreakpoint::CheckBreakpoint(SegValue(cs),reg_eip)) { exitLoop = true; DEBUG_Enable(); - return true; - }; + return true; + } return false; }; From d5231d435124be56799daf8726e6712346e2b54b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 19 Jun 2003 15:36:08 +0000 Subject: [PATCH 0996/4131] Fix for Big Endian writing of variables Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1076 --- include/mem.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/mem.h b/include/mem.h index b459ef32..9723e830 100644 --- a/include/mem.h +++ b/include/mem.h @@ -88,9 +88,9 @@ INLINE void writed(HostPt off,Bit32u val) { off[3]=(Bit8u)(val >> 24); }; -#define MLEB(_MLE_VAL_) (_MLE_VAL_) -#define MLEW(_MLE_VAL_) (_MLE_VAL_ >> 8) | (_MLE_VAL_ << 8)) -#define MLED(_MLE_VAL_) (_MLE_VAL_ >> 24)|((_MLE_VAL_ >> 8)&0xFF00)|((_MLE_VAL_ << 8)&0xFF0000)|((_MLE_VAL_ << 24)&0xFF000000)) +#define MLEB(_MLE_VAL_) (_MLE_VAL_) +#define MLEW(_MLE_VAL_) ( (_MLE_VAL_ >> 8) | (_MLE_VAL_ << 8)) +#define MLED(_MLE_VAL_) ( (_MLE_VAL_ >> 24)|((_MLE_VAL_ >> 8)&0xFF00)|((_MLE_VAL_ << 8)&0xFF0000)|((_MLE_VAL_ << 24)&0xFF000000)) #else From b222a9576a81fc928f1302d11a324ec7b0643031 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 19 Jun 2003 17:12:50 +0000 Subject: [PATCH 0997/4131] Warning clean up Removing some old unused routines Addind some newlines after some files. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1077 --- include/dos_system.h | 2 +- src/cpu/core_16/helpers.h | 2 +- src/cpu/core_full/string.h | 3 +- src/cpu/cpu.cpp | 6 +-- src/debug/debug.cpp | 7 +--- src/debug/debug_gui.cpp | 2 +- src/dos/dos_files.cpp | 16 -------- src/dos/dos_ioctl.cpp | 4 -- src/fpu/fpu_types.h | 2 +- src/hardware/mixer.cpp | 2 +- src/hardware/timer.cpp | 4 +- src/hardware/vga_misc.cpp | 3 -- src/ints/int10_modes.cpp | 80 +++++++++++++++++++------------------- 13 files changed, 52 insertions(+), 81 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 1a333eaf..41624704 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -186,7 +186,7 @@ public: void EmptyCache (void) {}; void SetLabel (const char* name) {}; - char* GetLabel (void) {}; + char* GetLabel (void) {return "";}; public: char basePath [CROSS_LEN]; diff --git a/src/cpu/core_16/helpers.h b/src/cpu/core_16/helpers.h index e826a3bd..c6586e1b 100644 --- a/src/cpu/core_16/helpers.h +++ b/src/cpu/core_16/helpers.h @@ -139,4 +139,4 @@ } else { \ GetEAa;FPU_ESC ## code ## _EA(rm,eaa); \ } \ -} \ No newline at end of file +} diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index b4d5d237..f9a80136 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -4,7 +4,6 @@ Bitu add_mask; Bitu count,count_left; Bits add_index; - bool restart=false; if (inst.prefix & PREFIX_SEG) si_base=inst.seg.base; else si_base=SegBase(ds); @@ -63,7 +62,7 @@ break; case R_INSB: for (;count>0;count--) { - reg_dx,SaveMb(di_base+di_index,IO_Read(reg_dx)); + SaveMb(di_base+di_index,IO_Read(reg_dx)); di_index=(di_index+add_index) & add_mask; } break; diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 050db6a4..91ffcb3d 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -811,15 +811,15 @@ void CPU_HLT(void) { static void CPU_CycleIncrease(void) { - Bitu old_cycles=CPU_CycleMax; - CPU_CycleMax=(Bitu)(CPU_CycleMax*1.2); + Bits old_cycles=CPU_CycleMax; + CPU_CycleMax=(Bits)(CPU_CycleMax*1.2); CPU_CycleLeft=0;CPU_Cycles=0; if (CPU_CycleMax==old_cycles) CPU_CycleMax++; LOG_MSG("CPU:%d cycles",CPU_CycleMax); } static void CPU_CycleDecrease(void) { - CPU_CycleMax=(Bitu)(CPU_CycleMax/1.2); + CPU_CycleMax=(Bits)(CPU_CycleMax/1.2); CPU_CycleLeft=0;CPU_Cycles=0; if (!CPU_CycleMax) CPU_CycleMax=1; LOG_MSG("CPU:%d cycles",CPU_CycleMax); diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index ad33a6e1..de164068 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -69,7 +69,6 @@ static char curSelectorName[3] = { 0,0,0 }; static Segment oldsegs[6]; static Bitu oldflags; DBGBlock dbg; -static char input_line[256]; static Bitu input_count; Bitu cycle_count; static bool debugging; @@ -434,7 +433,6 @@ bool CBreakpoint::DeleteByIndex(Bit16u index) bool CBreakpoint::DeleteBreakpoint(PhysPt where) { // Search matching breakpoint - int nr = 0; std::list::iterator i; CBreakpoint* bp; for(i=BPoints.begin(); i != BPoints.end(); i++) { @@ -655,7 +653,7 @@ static void DrawCode(void) PhysPt start = GetAddress(codeViewData.useCS,codeViewData.useEIP); char dline[200];Bitu size;Bitu c; - for (Bit32u i=0;i<10;i++) { + for (int i=0;i<10;i++) { saveSel = false; if (has_colors()) { if ((codeViewData.useCS==SegValue(cs)) && (disEIP == reg_eip)) { @@ -780,8 +778,6 @@ Bit32u GetHexValue(char* str, char*& hex) bool ChangeRegister(char* str) { - Bit32u value = 0; - char* hex = str; while (*hex==' ') hex++; if (strstr(hex,"EAX")==hex) { hex+=3; reg_eax = GetHexValue(hex,hex); } else @@ -920,7 +916,6 @@ bool ParseCommand(char* str) if (found) { wprintw(dbg.win_out,"Breakpoint list:\n"); wprintw(dbg.win_out,"-------------------------------------------------------------------------\n"); - Bit32u nr = 0; CBreakpoint::ShowList(); return true; }; diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 636af058..40a886c9 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -37,7 +37,7 @@ struct _LogGroup { bool enabled; }; -static _LogGroup loggrp[LOG_MAX]={"",true,0}; +static _LogGroup loggrp[LOG_MAX]={{"",true},{0,false}}; static FILE* debuglog; extern int old_cursor_state; diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 812aa7f5..a5babc4b 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -127,7 +127,6 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { char * ext=strchr(tempdir,'.'); if (ext) { ext[4]=0; - Bitu blah=strlen(tempdir); if (strlen(tempdir)>12) memmove(tempdir+8,ext,5); } else tempdir[8]=0; strcat(fullname,tempdir); @@ -475,14 +474,6 @@ bool DOS_CreateTempFile(char * name,Bit16u * entry) { return true; } - - -static bool FCB_MakeName2 (DOS_FCB & fcb, char* outname, Bit8u* outdrive){ - char short_name[DOS_FCBNAME]; - fcb.GetName(short_name); - return DOS_MakeName(short_name,outname, outdrive); -} - #define FCB_SEP ":.;,=+" #define ILLEGAL ":.;,=+ \t/\"[]<>|" @@ -491,13 +482,6 @@ static bool isvalid(const char in){ return (Bit8u(in)>0x1F) && (!strchr(ill,in)); } -static void vullen (char* veld,char* pveld){ - for(Bitu i=(pveld-veld);id_name); char * test=strstr(tempname,".wav"); diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index c9fa47c4..c65b2791 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -115,7 +115,7 @@ static void write_latch(Bit32u port,Bit8u val) { if (p->write_latch == 0) p->cntr = 0x10000; else p->cntr = p->write_latch; p->start=PIC_MicroCount(); - p->micro=1000000/((float)PIT_TICK_RATE/(float)p->cntr); + p->micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)p->cntr)); switch (counter) { case 0x00: /* Timer hooked to IRQ 0 */ PIC_RemoveEvents(PIT0_Event); @@ -287,7 +287,7 @@ void TIMER_Init(Section* sect) { pit[0].write_latch=0; pit[0].mode=3; - pit[0].micro=1000000/((float)PIT_TICK_RATE/(float)pit[0].cntr); + pit[0].micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)pit[0].cntr)); pit[2].micro=100; PIC_AddEvent(PIT0_Event,pit[0].micro); } diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index b08f322b..6bb0188b 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -22,9 +22,6 @@ #include "vga.h" static Bit8u flip=0; -static Bit32u keep_vretrace; -static bool keeping=false; -static Bit8u p3c2data=0; void write_p3d4(Bit32u port,Bit8u val); Bit8u read_p3d4(Bit32u port); diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 806ae16a..970c2a0e 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -46,14 +46,14 @@ VideoModeBlock ModeList[]={ static Bit8u text_palette[64][3]= { - 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x2a,0x00, 0x2a,0x2a,0x2a, - 0x00,0x00,0x15, 0x00,0x00,0x3f, 0x00,0x2a,0x15, 0x00,0x2a,0x3f, 0x2a,0x00,0x15, 0x2a,0x00,0x3f, 0x2a,0x2a,0x15, 0x2a,0x2a,0x3f, - 0x00,0x15,0x00, 0x00,0x15,0x2a, 0x00,0x3f,0x00, 0x00,0x3f,0x2a, 0x2a,0x15,0x00, 0x2a,0x15,0x2a, 0x2a,0x3f,0x00, 0x2a,0x3f,0x2a, - 0x00,0x15,0x15, 0x00,0x15,0x3f, 0x00,0x3f,0x15, 0x00,0x3f,0x3f, 0x2a,0x15,0x15, 0x2a,0x15,0x3f, 0x2a,0x3f,0x15, 0x2a,0x3f,0x3f, - 0x15,0x00,0x00, 0x15,0x00,0x2a, 0x15,0x2a,0x00, 0x15,0x2a,0x2a, 0x3f,0x00,0x00, 0x3f,0x00,0x2a, 0x3f,0x2a,0x00, 0x3f,0x2a,0x2a, - 0x15,0x00,0x15, 0x15,0x00,0x3f, 0x15,0x2a,0x15, 0x15,0x2a,0x3f, 0x3f,0x00,0x15, 0x3f,0x00,0x3f, 0x3f,0x2a,0x15, 0x3f,0x2a,0x3f, - 0x15,0x15,0x00, 0x15,0x15,0x2a, 0x15,0x3f,0x00, 0x15,0x3f,0x2a, 0x3f,0x15,0x00, 0x3f,0x15,0x2a, 0x3f,0x3f,0x00, 0x3f,0x3f,0x2a, - 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f + {0x00,0x00,0x00},{0x00,0x00,0x2a},{0x00,0x2a,0x00},{0x00,0x2a,0x2a},{0x2a,0x00,0x00},{0x2a,0x00,0x2a},{0x2a,0x2a,0x00},{0x2a,0x2a,0x2a}, + {0x00,0x00,0x15},{0x00,0x00,0x3f},{0x00,0x2a,0x15},{0x00,0x2a,0x3f},{0x2a,0x00,0x15},{0x2a,0x00,0x3f},{0x2a,0x2a,0x15},{0x2a,0x2a,0x3f}, + {0x00,0x15,0x00},{0x00,0x15,0x2a},{0x00,0x3f,0x00},{0x00,0x3f,0x2a},{0x2a,0x15,0x00},{0x2a,0x15,0x2a},{0x2a,0x3f,0x00},{0x2a,0x3f,0x2a}, + {0x00,0x15,0x15},{0x00,0x15,0x3f},{0x00,0x3f,0x15},{0x00,0x3f,0x3f},{0x2a,0x15,0x15},{0x2a,0x15,0x3f},{0x2a,0x3f,0x15},{0x2a,0x3f,0x3f}, + {0x15,0x00,0x00},{0x15,0x00,0x2a},{0x15,0x2a,0x00},{0x15,0x2a,0x2a},{0x3f,0x00,0x00},{0x3f,0x00,0x2a},{0x3f,0x2a,0x00},{0x3f,0x2a,0x2a}, + {0x15,0x00,0x15},{0x15,0x00,0x3f},{0x15,0x2a,0x15},{0x15,0x2a,0x3f},{0x3f,0x00,0x15},{0x3f,0x00,0x3f},{0x3f,0x2a,0x15},{0x3f,0x2a,0x3f}, + {0x15,0x15,0x00},{0x15,0x15,0x2a},{0x15,0x3f,0x00},{0x15,0x3f,0x2a},{0x3f,0x15,0x00},{0x3f,0x15,0x2a},{0x3f,0x3f,0x00},{0x3f,0x3f,0x2a}, + {0x15,0x15,0x15},{0x15,0x15,0x3f},{0x15,0x3f,0x15},{0x15,0x3f,0x3f},{0x3f,0x15,0x15},{0x3f,0x15,0x3f},{0x3f,0x3f,0x15},{0x3f,0x3f,0x3f} }; static Bit8u ega_palette[64][3]= @@ -71,41 +71,41 @@ static Bit8u ega_palette[64][3]= static Bit8u vga_palette[256][3]= { - 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, - 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, - 0x00,0x00,0x00, 0x05,0x05,0x05, 0x08,0x08,0x08, 0x0b,0x0b,0x0b, 0x0e,0x0e,0x0e, 0x11,0x11,0x11, 0x14,0x14,0x14, 0x18,0x18,0x18, - 0x1c,0x1c,0x1c, 0x20,0x20,0x20, 0x24,0x24,0x24, 0x28,0x28,0x28, 0x2d,0x2d,0x2d, 0x32,0x32,0x32, 0x38,0x38,0x38, 0x3f,0x3f,0x3f, - 0x00,0x00,0x3f, 0x10,0x00,0x3f, 0x1f,0x00,0x3f, 0x2f,0x00,0x3f, 0x3f,0x00,0x3f, 0x3f,0x00,0x2f, 0x3f,0x00,0x1f, 0x3f,0x00,0x10, - 0x3f,0x00,0x00, 0x3f,0x10,0x00, 0x3f,0x1f,0x00, 0x3f,0x2f,0x00, 0x3f,0x3f,0x00, 0x2f,0x3f,0x00, 0x1f,0x3f,0x00, 0x10,0x3f,0x00, - 0x00,0x3f,0x00, 0x00,0x3f,0x10, 0x00,0x3f,0x1f, 0x00,0x3f,0x2f, 0x00,0x3f,0x3f, 0x00,0x2f,0x3f, 0x00,0x1f,0x3f, 0x00,0x10,0x3f, - 0x1f,0x1f,0x3f, 0x27,0x1f,0x3f, 0x2f,0x1f,0x3f, 0x37,0x1f,0x3f, 0x3f,0x1f,0x3f, 0x3f,0x1f,0x37, 0x3f,0x1f,0x2f, 0x3f,0x1f,0x27, + {0x00,0x00,0x00},{0x00,0x00,0x2a},{0x00,0x2a,0x00},{0x00,0x2a,0x2a},{0x2a,0x00,0x00},{0x2a,0x00,0x2a},{0x2a,0x15,0x00},{0x2a,0x2a,0x2a}, + {0x15,0x15,0x15},{0x15,0x15,0x3f},{0x15,0x3f,0x15},{0x15,0x3f,0x3f},{0x3f,0x15,0x15},{0x3f,0x15,0x3f},{0x3f,0x3f,0x15},{0x3f,0x3f,0x3f}, + {0x00,0x00,0x00},{0x05,0x05,0x05},{0x08,0x08,0x08},{0x0b,0x0b,0x0b},{0x0e,0x0e,0x0e},{0x11,0x11,0x11},{0x14,0x14,0x14},{0x18,0x18,0x18}, + {0x1c,0x1c,0x1c},{0x20,0x20,0x20},{0x24,0x24,0x24},{0x28,0x28,0x28},{0x2d,0x2d,0x2d},{0x32,0x32,0x32},{0x38,0x38,0x38},{0x3f,0x3f,0x3f}, + {0x00,0x00,0x3f},{0x10,0x00,0x3f},{0x1f,0x00,0x3f},{0x2f,0x00,0x3f},{0x3f,0x00,0x3f},{0x3f,0x00,0x2f},{0x3f,0x00,0x1f},{0x3f,0x00,0x10}, + {0x3f,0x00,0x00},{0x3f,0x10,0x00},{0x3f,0x1f,0x00},{0x3f,0x2f,0x00},{0x3f,0x3f,0x00},{0x2f,0x3f,0x00},{0x1f,0x3f,0x00},{0x10,0x3f,0x00}, + {0x00,0x3f,0x00},{0x00,0x3f,0x10},{0x00,0x3f,0x1f},{0x00,0x3f,0x2f},{0x00,0x3f,0x3f},{0x00,0x2f,0x3f},{0x00,0x1f,0x3f},{0x00,0x10,0x3f}, + {0x1f,0x1f,0x3f},{0x27,0x1f,0x3f},{0x2f,0x1f,0x3f},{0x37,0x1f,0x3f},{0x3f,0x1f,0x3f},{0x3f,0x1f,0x37},{0x3f,0x1f,0x2f},{0x3f,0x1f,0x27}, - 0x3f,0x1f,0x1f, 0x3f,0x27,0x1f, 0x3f,0x2f,0x1f, 0x3f,0x37,0x1f, 0x3f,0x3f,0x1f, 0x37,0x3f,0x1f, 0x2f,0x3f,0x1f, 0x27,0x3f,0x1f, - 0x1f,0x3f,0x1f, 0x1f,0x3f,0x27, 0x1f,0x3f,0x2f, 0x1f,0x3f,0x37, 0x1f,0x3f,0x3f, 0x1f,0x37,0x3f, 0x1f,0x2f,0x3f, 0x1f,0x27,0x3f, - 0x2d,0x2d,0x3f, 0x31,0x2d,0x3f, 0x36,0x2d,0x3f, 0x3a,0x2d,0x3f, 0x3f,0x2d,0x3f, 0x3f,0x2d,0x3a, 0x3f,0x2d,0x36, 0x3f,0x2d,0x31, - 0x3f,0x2d,0x2d, 0x3f,0x31,0x2d, 0x3f,0x36,0x2d, 0x3f,0x3a,0x2d, 0x3f,0x3f,0x2d, 0x3a,0x3f,0x2d, 0x36,0x3f,0x2d, 0x31,0x3f,0x2d, - 0x2d,0x3f,0x2d, 0x2d,0x3f,0x31, 0x2d,0x3f,0x36, 0x2d,0x3f,0x3a, 0x2d,0x3f,0x3f, 0x2d,0x3a,0x3f, 0x2d,0x36,0x3f, 0x2d,0x31,0x3f, - 0x00,0x00,0x1c, 0x07,0x00,0x1c, 0x0e,0x00,0x1c, 0x15,0x00,0x1c, 0x1c,0x00,0x1c, 0x1c,0x00,0x15, 0x1c,0x00,0x0e, 0x1c,0x00,0x07, - 0x1c,0x00,0x00, 0x1c,0x07,0x00, 0x1c,0x0e,0x00, 0x1c,0x15,0x00, 0x1c,0x1c,0x00, 0x15,0x1c,0x00, 0x0e,0x1c,0x00, 0x07,0x1c,0x00, - 0x00,0x1c,0x00, 0x00,0x1c,0x07, 0x00,0x1c,0x0e, 0x00,0x1c,0x15, 0x00,0x1c,0x1c, 0x00,0x15,0x1c, 0x00,0x0e,0x1c, 0x00,0x07,0x1c, + {0x3f,0x1f,0x1f},{0x3f,0x27,0x1f},{0x3f,0x2f,0x1f},{0x3f,0x37,0x1f},{0x3f,0x3f,0x1f},{0x37,0x3f,0x1f},{0x2f,0x3f,0x1f},{0x27,0x3f,0x1f}, + {0x1f,0x3f,0x1f},{0x1f,0x3f,0x27},{0x1f,0x3f,0x2f},{0x1f,0x3f,0x37},{0x1f,0x3f,0x3f},{0x1f,0x37,0x3f},{0x1f,0x2f,0x3f},{0x1f,0x27,0x3f}, + {0x2d,0x2d,0x3f},{0x31,0x2d,0x3f},{0x36,0x2d,0x3f},{0x3a,0x2d,0x3f},{0x3f,0x2d,0x3f},{0x3f,0x2d,0x3a},{0x3f,0x2d,0x36},{0x3f,0x2d,0x31}, + {0x3f,0x2d,0x2d},{0x3f,0x31,0x2d},{0x3f,0x36,0x2d},{0x3f,0x3a,0x2d},{0x3f,0x3f,0x2d},{0x3a,0x3f,0x2d},{0x36,0x3f,0x2d},{0x31,0x3f,0x2d}, + {0x2d,0x3f,0x2d},{0x2d,0x3f,0x31},{0x2d,0x3f,0x36},{0x2d,0x3f,0x3a},{0x2d,0x3f,0x3f},{0x2d,0x3a,0x3f},{0x2d,0x36,0x3f},{0x2d,0x31,0x3f}, + {0x00,0x00,0x1c},{0x07,0x00,0x1c},{0x0e,0x00,0x1c},{0x15,0x00,0x1c},{0x1c,0x00,0x1c},{0x1c,0x00,0x15},{0x1c,0x00,0x0e},{0x1c,0x00,0x07}, + {0x1c,0x00,0x00},{0x1c,0x07,0x00},{0x1c,0x0e,0x00},{0x1c,0x15,0x00},{0x1c,0x1c,0x00},{0x15,0x1c,0x00},{0x0e,0x1c,0x00},{0x07,0x1c,0x00}, + {0x00,0x1c,0x00},{0x00,0x1c,0x07},{0x00,0x1c,0x0e},{0x00,0x1c,0x15},{0x00,0x1c,0x1c},{0x00,0x15,0x1c},{0x00,0x0e,0x1c},{0x00,0x07,0x1c}, - 0x0e,0x0e,0x1c, 0x11,0x0e,0x1c, 0x15,0x0e,0x1c, 0x18,0x0e,0x1c, 0x1c,0x0e,0x1c, 0x1c,0x0e,0x18, 0x1c,0x0e,0x15, 0x1c,0x0e,0x11, - 0x1c,0x0e,0x0e, 0x1c,0x11,0x0e, 0x1c,0x15,0x0e, 0x1c,0x18,0x0e, 0x1c,0x1c,0x0e, 0x18,0x1c,0x0e, 0x15,0x1c,0x0e, 0x11,0x1c,0x0e, - 0x0e,0x1c,0x0e, 0x0e,0x1c,0x11, 0x0e,0x1c,0x15, 0x0e,0x1c,0x18, 0x0e,0x1c,0x1c, 0x0e,0x18,0x1c, 0x0e,0x15,0x1c, 0x0e,0x11,0x1c, - 0x14,0x14,0x1c, 0x16,0x14,0x1c, 0x18,0x14,0x1c, 0x1a,0x14,0x1c, 0x1c,0x14,0x1c, 0x1c,0x14,0x1a, 0x1c,0x14,0x18, 0x1c,0x14,0x16, - 0x1c,0x14,0x14, 0x1c,0x16,0x14, 0x1c,0x18,0x14, 0x1c,0x1a,0x14, 0x1c,0x1c,0x14, 0x1a,0x1c,0x14, 0x18,0x1c,0x14, 0x16,0x1c,0x14, - 0x14,0x1c,0x14, 0x14,0x1c,0x16, 0x14,0x1c,0x18, 0x14,0x1c,0x1a, 0x14,0x1c,0x1c, 0x14,0x1a,0x1c, 0x14,0x18,0x1c, 0x14,0x16,0x1c, - 0x00,0x00,0x10, 0x04,0x00,0x10, 0x08,0x00,0x10, 0x0c,0x00,0x10, 0x10,0x00,0x10, 0x10,0x00,0x0c, 0x10,0x00,0x08, 0x10,0x00,0x04, - 0x10,0x00,0x00, 0x10,0x04,0x00, 0x10,0x08,0x00, 0x10,0x0c,0x00, 0x10,0x10,0x00, 0x0c,0x10,0x00, 0x08,0x10,0x00, 0x04,0x10,0x00, + {0x0e,0x0e,0x1c},{0x11,0x0e,0x1c},{0x15,0x0e,0x1c},{0x18,0x0e,0x1c},{0x1c,0x0e,0x1c},{0x1c,0x0e,0x18},{0x1c,0x0e,0x15},{0x1c,0x0e,0x11}, + {0x1c,0x0e,0x0e},{0x1c,0x11,0x0e},{0x1c,0x15,0x0e},{0x1c,0x18,0x0e},{0x1c,0x1c,0x0e},{0x18,0x1c,0x0e},{0x15,0x1c,0x0e},{0x11,0x1c,0x0e}, + {0x0e,0x1c,0x0e},{0x0e,0x1c,0x11},{0x0e,0x1c,0x15},{0x0e,0x1c,0x18},{0x0e,0x1c,0x1c},{0x0e,0x18,0x1c},{0x0e,0x15,0x1c},{0x0e,0x11,0x1c}, + {0x14,0x14,0x1c},{0x16,0x14,0x1c},{0x18,0x14,0x1c},{0x1a,0x14,0x1c},{0x1c,0x14,0x1c},{0x1c,0x14,0x1a},{0x1c,0x14,0x18},{0x1c,0x14,0x16}, + {0x1c,0x14,0x14},{0x1c,0x16,0x14},{0x1c,0x18,0x14},{0x1c,0x1a,0x14},{0x1c,0x1c,0x14},{0x1a,0x1c,0x14},{0x18,0x1c,0x14},{0x16,0x1c,0x14}, + {0x14,0x1c,0x14},{0x14,0x1c,0x16},{0x14,0x1c,0x18},{0x14,0x1c,0x1a},{0x14,0x1c,0x1c},{0x14,0x1a,0x1c},{0x14,0x18,0x1c},{0x14,0x16,0x1c}, + {0x00,0x00,0x10},{0x04,0x00,0x10},{0x08,0x00,0x10},{0x0c,0x00,0x10},{0x10,0x00,0x10},{0x10,0x00,0x0c},{0x10,0x00,0x08},{0x10,0x00,0x04}, + {0x10,0x00,0x00},{0x10,0x04,0x00},{0x10,0x08,0x00},{0x10,0x0c,0x00},{0x10,0x10,0x00},{0x0c,0x10,0x00},{0x08,0x10,0x00},{0x04,0x10,0x00}, - 0x00,0x10,0x00, 0x00,0x10,0x04, 0x00,0x10,0x08, 0x00,0x10,0x0c, 0x00,0x10,0x10, 0x00,0x0c,0x10, 0x00,0x08,0x10, 0x00,0x04,0x10, - 0x08,0x08,0x10, 0x0a,0x08,0x10, 0x0c,0x08,0x10, 0x0e,0x08,0x10, 0x10,0x08,0x10, 0x10,0x08,0x0e, 0x10,0x08,0x0c, 0x10,0x08,0x0a, - 0x10,0x08,0x08, 0x10,0x0a,0x08, 0x10,0x0c,0x08, 0x10,0x0e,0x08, 0x10,0x10,0x08, 0x0e,0x10,0x08, 0x0c,0x10,0x08, 0x0a,0x10,0x08, - 0x08,0x10,0x08, 0x08,0x10,0x0a, 0x08,0x10,0x0c, 0x08,0x10,0x0e, 0x08,0x10,0x10, 0x08,0x0e,0x10, 0x08,0x0c,0x10, 0x08,0x0a,0x10, - 0x0b,0x0b,0x10, 0x0c,0x0b,0x10, 0x0d,0x0b,0x10, 0x0f,0x0b,0x10, 0x10,0x0b,0x10, 0x10,0x0b,0x0f, 0x10,0x0b,0x0d, 0x10,0x0b,0x0c, - 0x10,0x0b,0x0b, 0x10,0x0c,0x0b, 0x10,0x0d,0x0b, 0x10,0x0f,0x0b, 0x10,0x10,0x0b, 0x0f,0x10,0x0b, 0x0d,0x10,0x0b, 0x0c,0x10,0x0b, - 0x0b,0x10,0x0b, 0x0b,0x10,0x0c, 0x0b,0x10,0x0d, 0x0b,0x10,0x0f, 0x0b,0x10,0x10, 0x0b,0x0f,0x10, 0x0b,0x0d,0x10, 0x0b,0x0c,0x10, - 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00 + {0x00,0x10,0x00},{0x00,0x10,0x04},{0x00,0x10,0x08},{0x00,0x10,0x0c},{0x00,0x10,0x10},{0x00,0x0c,0x10},{0x00,0x08,0x10},{0x00,0x04,0x10}, + {0x08,0x08,0x10},{0x0a,0x08,0x10},{0x0c,0x08,0x10},{0x0e,0x08,0x10},{0x10,0x08,0x10},{0x10,0x08,0x0e},{0x10,0x08,0x0c},{0x10,0x08,0x0a}, + {0x10,0x08,0x08},{0x10,0x0a,0x08},{0x10,0x0c,0x08},{0x10,0x0e,0x08},{0x10,0x10,0x08},{0x0e,0x10,0x08},{0x0c,0x10,0x08},{0x0a,0x10,0x08}, + {0x08,0x10,0x08},{0x08,0x10,0x0a},{0x08,0x10,0x0c},{0x08,0x10,0x0e},{0x08,0x10,0x10},{0x08,0x0e,0x10},{0x08,0x0c,0x10},{0x08,0x0a,0x10}, + {0x0b,0x0b,0x10},{0x0c,0x0b,0x10},{0x0d,0x0b,0x10},{0x0f,0x0b,0x10},{0x10,0x0b,0x10},{0x10,0x0b,0x0f},{0x10,0x0b,0x0d},{0x10,0x0b,0x0c}, + {0x10,0x0b,0x0b},{0x10,0x0c,0x0b},{0x10,0x0d,0x0b},{0x10,0x0f,0x0b},{0x10,0x10,0x0b},{0x0f,0x10,0x0b},{0x0d,0x10,0x0b},{0x0c,0x10,0x0b}, + {0x0b,0x10,0x0b},{0x0b,0x10,0x0c},{0x0b,0x10,0x0d},{0x0b,0x10,0x0f},{0x0b,0x10,0x10},{0x0b,0x0f,0x10},{0x0b,0x0d,0x10},{0x0b,0x0c,0x10}, + {0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00} }; VideoModeBlock * CurMode; From a32e1ba6586f91f78f998a16db586bbef26b2ae4 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 19 Jun 2003 17:47:56 +0000 Subject: [PATCH 0998/4131] Fix SETXF instructions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1078 --- src/cpu/core_full/save.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_full/save.h b/src/cpu/core_full/save.h index 6c8f9c55..06e80770 100644 --- a/src/cpu/core_full/save.h +++ b/src/cpu/core_full/save.h @@ -2,7 +2,7 @@ switch (inst.code.save) { /* Byte */ case S_C_Eb: - inst.op1.b=inst.cond; + inst.op1.b=inst.cond ? 1 : 0; case S_Eb: if (inst.rm<0xc0) SaveMb(inst.rm_eaa,inst.op1.b); else reg_8(inst.rm_eai)=inst.op1.b; From 42711fd8551f02b936e96d698e200b7f06a53e2a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 3 Jul 2003 20:30:48 +0000 Subject: [PATCH 0999/4131] added shell4.patch from Guillaume Serre Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1079 --- src/shell/shell_misc.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 92ede224..efb8c696 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -153,6 +153,7 @@ void DOS_Shell::InputCommand(char * line) { // moves the cursor left while (str_remain--) outc(8); } + if (strlen(line) == 0 && l_completion.size()) l_completion.clear(); break; case 0x0a: /* New Line not handled */ /* Don't care */ @@ -200,8 +201,15 @@ void DOS_Shell::InputCommand(char * line) { dta.GetResult(name,size,date,time,attr); // add result to completion list - if (strcmp(name, ".") && strcmp(name, "..")) - l_completion.push_back(name); + char *ext; // file extension + if (strcmp(name, ".") && strcmp(name, "..")) { + ext = strrchr(name, '.'); + if (ext && (strcmp(ext, ".BAT") == 0 || strcmp(ext, ".COM") == 0 || strcmp(ext, ".EXE") == 0)) + // we add executables to the start of the list + l_completion.push_front(name); + else + l_completion.push_back(name); + } res=DOS_FindNext(); } From 3b0f6bfda84ea926bda513cc1ad6ea60dee53c3b Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 5 Jul 2003 14:05:05 +0000 Subject: [PATCH 1000/4131] Added CALLBACK_SetupAt Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1080 --- include/callback.h | 1 + src/cpu/callback.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/include/callback.h b/include/callback.h index 065dd9b5..ff4f5835 100644 --- a/include/callback.h +++ b/include/callback.h @@ -47,6 +47,7 @@ void CALLBACK_RunRealInt(Bit8u intnum); void CALLBACK_RunRealFar(Bit16u seg,Bit16u off); bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type); +bool CALLBACK_SetupAt(Bitu callback,CallBack_Handler handler,Bitu type,Bitu linearAddress); bool CALLBACK_Free(Bitu callback); diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index cf8b77cf..fe649d03 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -148,6 +148,35 @@ bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type) { return true; } +bool CALLBACK_SetupAt(Bitu callback,CallBack_Handler handler,Bitu type,Bitu linearAddress) { + if (callback>=CB_MAX) return false; + switch (type) { + case CB_RETF: + mem_writeb(linearAddress+0,(Bit8u)0xFE); //GRP 4 + mem_writeb(linearAddress+1,(Bit8u)0x38); //Extra Callback instruction + mem_writew(linearAddress+2, callback); //The immediate word + mem_writeb(linearAddress+4,(Bit8u)0xCB); //A RETF Instruction + break; + case CB_IRET: + mem_writeb(linearAddress+0,(Bit8u)0xFE); //GRP 4 + mem_writeb(linearAddress+1,(Bit8u)0x38); //Extra Callback instruction + mem_writew(linearAddress+2,callback); //The immediate word + mem_writeb(linearAddress+4,(Bit8u)0xCF); //An IRET Instruction + break; + case CB_IRET_STI: + mem_writeb(linearAddress+0,(Bit8u)0xFB); //STI + mem_writeb(linearAddress+1,(Bit8u)0xFE); //GRP 4 + mem_writeb(linearAddress+2,(Bit8u)0x38); //Extra Callback instruction + mem_writew(linearAddress+3, callback); //The immediate word + mem_writeb(linearAddress+5,(Bit8u)0xCF); //An IRET Instruction + break; + default: + E_Exit("CALLBACK:Setup:Illegal type %d",type); + } + CallBack_Handlers[callback]=handler; + return true; +} + void CALLBACK_Init(Section* sec) { Bitu i; for (i=0;i Date: Sat, 5 Jul 2003 14:05:39 +0000 Subject: [PATCH 1001/4131] Made CPU_Push/Pop accessable Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1081 --- include/cpu.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/cpu.h b/include/cpu.h index b2036e46..8f62abb8 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -105,6 +105,11 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value); void CPU_CPUID(void); void CPU_HLT(void); +Bitu CPU_Pop16(void); +Bitu CPU_Pop32(void); +void CPU_Push16(Bitu value); +void CPU_Push32(Bitu value); + //Flag Handling Bitu get_CF(void); Bitu get_AF(void); From 12be0e35a1eaef0ad3696cc1c9b8ed1576ae4f93 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 5 Jul 2003 14:06:32 +0000 Subject: [PATCH 1002/4131] save int 21 stack entry in psp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1082 --- src/dos/dos.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index e14b1cea..c7c548a6 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -42,6 +42,10 @@ void DOS_SetError(Bit16u code) { #define DOSNAMEBUF 256 static Bitu DOS_21Handler(void) { + + DOS_PSP psp(dos.psp); + psp.SetStack(RealMake(SegValue(ss),reg_sp)); + char name1[DOSNAMEBUF+1]; char name2[DOSNAMEBUF+1]; switch (reg_ah) { From c2f035784b135465005e627525482fcefd1934de Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 5 Jul 2003 14:07:29 +0000 Subject: [PATCH 1003/4131] internal dpmi server Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1083 --- src/ints/dpmi.cpp | 2721 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 2703 insertions(+), 18 deletions(-) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index 8c277a04..d6578b62 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -19,6 +19,7 @@ #include #include #include "dosbox.h" +#include "dos_inc.h" #include "callback.h" #include "mem.h" #include "regs.h" @@ -28,32 +29,2716 @@ #include "xms.h" #include "cpu.h" +//#define DPMI_LOG LOG(LOG_MISC,LOG_ERROR) +#define DPMI_LOG -static bool DPMI_Multiplex(void) { - switch (reg_ax) { - case 0x1686: /* Get CPU Mode */ - reg_ax=1; /* Not protected */ - return true; - break; - case 0x1687: /* Get Mode switch entry point */ - reg_ax=0; /* supported */ - reg_bx=1; /* Support 32-bit */ - reg_cl=4; /* 486 */ - reg_dh=0; /* dpmi 0.9 */ - reg_dl=9; - reg_si=0; /* No need for private data */ +#define DPMI_LOG_ERROR LOG(LOG_MISC,LOG_ERROR) +//#define DPMI_LOG_ERROR +#define DPMI_DPL 3 +#define GDT_ZERO 0 +#define GDT_LDT ((0x1 << 3) | DPMI_DPL) +#define GDT_CODE ((0x2 << 3) | DPMI_DPL) +#define GDT_PROTCODE ((0x3 << 3) | DPMI_DPL) +#define GDT_DOSDATA ((0x4 << 3) | DPMI_DPL) +#define GDT_ENVIRONMENT ((0x5 << 3) | DPMI_DPL) - break; +// TEMP +#define GDT_DOSSEG40 (0x40) + +/* Amount of descriptors in each table */ +#define GDT_SIZE 32 +#define IDT_SIZE 256 +#define LDT_SIZE 1024 +#define INT_SIZE 256 + +#define TOTAL_SIZE ((GDT_SIZE+IDT_SIZE+LDT_SIZE+INT_SIZE)*8) + +#define LDT_ENTRY(BLAH_) (BLAH_ << 3) + +#define LDT_FIRSTSELECTOR 16 + +#define DPMI_ERROR_UNSUPPORTED 0x8001 +#define DPMI_ERROR_DESCRIPTOR_UNAVAILABLE 0x8011 +#define DPMI_ERROR_LINEAR_MEMORY_UNAVAILABLE 0x8012 +#define DPMI_ERROR_PHYSICAL_MEMORY_UNAVAILABLE 0x8013 +#define DPMI_ERROR_CALLBACK_UNAVAILABLE 0x8015 +#define DPMI_ERROR_INVALID_SELECTOR 0x8022 +#define DPMI_ERROR_INVALID_VALUE 0x8022 +#define DPMI_ERROR_INVALID_HANDLE 0x8023 +#define DPMI_ERROR_INVALID_CALLBACK 0x8024 +#define DPMI_ERROR_INVALID_LINEAR_ADDRESS 0x8025 + +#define DPMI_XMSHANDLES_MAX 256 +#define DPMI_XMSHANDLE_FREE 0xFFFF +#define DPMI_EXCEPTION_MAX 0x20 +#define DPMI_PAGE_SIZE (4*1024) +#define DPMI_REALMODE_CALLBACK_MAX 32 +#define DPMI_REALMODE_STACKSIZE 4096 +#define DPMI_PROTMODE_STACK_MAX 3 +#define DPMI_PROTMODE_STACKSIZE (4*1024) +#define DPMI_REALVEC_MAX 17 +#define DPMI_SAVESTACK_MAX 1024 + +#define DPMI_CB_APIMSDOSENTRY_OFFSET 256*8 +#define DPMI_CB_ENTERREALMODE_OFFSET 257*8 +#define DPMI_CB_SAVESTATE_OFFSET 258*8 +#define DPMI_CB_EXCEPTION_OFFSET 259*8 +#define DPMI_CB_EXCEPTIONRETURN_OFFSET 260*8 +#define DPMI_CB_VENDORENTRY_OFFSET 261*8 + +#define DPMI_HOOK_HARDWARE_INTS 1 + +static Bitu rmIndexToInt[DPMI_REALVEC_MAX] = +{ 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x1C }; + +// General functions +void CALLBACK32_SCF(bool val) +{ + Bit32u tempf=mem_readd(SegPhys(ss)+reg_esp+8) & 0xFFFFFFFE; + Bit32u newCF=(val==true); + mem_writed(SegPhys(ss)+reg_esp+8,(tempf | newCF)); +}; + +#define DPMI_CALLBACK_SCF(b) if (dpmi.client.bit32) CALLBACK32_SCF(b); else CALLBACK_SCF(b) + +// ********************************************** +// SetDescriptor Class +// ********************************************** + +#pragma pack(1) +class SetDescriptor : public Descriptor { +public: + void Save(PhysPt address) { + Bit32u* data = (Bit32u*)&saved; + mem_writed(address,*data); + mem_writed(address+4,*(data+1)); } - return false; + void SetBase(Bitu _base) { + saved.seg.base_24_31=_base >> 24; + saved.seg.base_16_23=_base >> 16; + saved.seg.base_0_15=_base; + } + void SetLimit (Bitu _limit) { + if (_limit<1048576) saved.seg.g=false; + else { + saved.seg.g=true; + _limit>>=12; + } + saved.seg.limit_0_15=_limit; + saved.seg.limit_16_19=_limit>>16; + } + void SetOffset(Bitu _offset) { + saved.gate.offset_0_15=_offset; + saved.gate.offset_16_31=(_offset>>16); + } + void SetSelector(Bitu _selector) { + saved.gate.selector=_selector; + } + void SetType(Bitu _type) { + saved.seg.type=_type; + } + void Clear(void) { + saved.fill[0]=saved.fill[1]=0; + } +}; +#pragma pack() + +// ********************************************** +// DPMI Class +// ********************************************** + +class DPMI { + +public: + DPMI (void); + ~DPMI (void); + + // Settp/Startup methods + void Setup (void); + Bitu Entrypoint (void); + RealPt HookInterrupt (Bitu num, Bitu intHandler); + void RestoreHookedInterrupt (Bitu num, RealPt oldVec); + void CreateStackSpace (void); + bool HasClient (void) { return dpmi.client.have; }; + void Terminate (void); + void Reactivate (void); + + // DPMI Services + Bitu AllocateLDTDescriptor (Bitu count,Bitu & base); + Bitu AllocateLDTDescriptor2 (Bitu count,Bitu & base); // TEMP + bool AllocateMem (Bitu size, Bitu& outHandle, Bitu& linear); + Bitu CreateAlias (Bitu selector, Bit16u& alias); + void ReloadSegments (Bitu selector); + + // Special Interrupt handlers + Bitu Int2fHandler (void); + Bitu Int31Handler (void); + + // Exceptions + void CreateException (Bitu num, Bitu errorCode); + Bitu ExceptionReturn (void); + + // Realmode callbacks + bool AllocateRealModeCallback(Bitu codeSel,Bitu codeOff,Bitu dataSel, Bitu dataOff, Bitu& segment, Bitu& offset); + Bitu RealModeCallback (void); + Bitu RealModeCallbackReturn (void); + + // Real mode reflection callbacks + void PrepareReflectToReal (Bitu num); + Bitu CallRealIRETFrame (void); + Bitu CallRealIRETFrameReturn (void); + Bitu SimulateInt (void); + Bitu SimulateIntReturn (void); + Bitu ptorHandler (void); + Bitu ptorHandlerReturn (void); + Bitu Int21Handler (void); + Bitu Int21HandlerReturn (void); + Bitu HWIntDefaultHandler (void); + void RemoveIntCallbacks (void); + void RestoreIntCallbacks (void); + + // Switching modes + void SaveRegisterState (Bitu num); + void LoadRegisterState (Bitu num); + Bitu EnterProtMode (void); + Bitu EnterRealMode (void); + Bitu RealSaveState (void); + Bitu ProtSaveState (void); + + // virtual interrupt flag + bool GetVirtualIntFlag (void); + void SetVirtualIntFlag (bool on); + + // Internal Stack for saving processor status + void PushStack (Bitu val) { saveStack[savePtr++] = val; }; + Bitu PopStack (void) { return saveStack[--savePtr]; }; + void SaveSegments (void); + void SaveRegister (void); + void RestoreSegments (void); + void RestoreRegister (void); + + void CopyRegistersToBuffer (PhysPt data); + void LoadRegistersFromBuffer (PhysPt data); + + void ProvideRealModeStack (PhysPt prStack, Bitu toCopy); + void UpdateRealModeStack (void); + + // xms handle information + void SetXMSHandle (Bitu handle); + void ClearXMSHandles (void); + void FreeXMSHandle (Bitu handle); + + // special msdos api stuff + Bitu GetSegmentFromSelector (Bitu selector); + bool GetMsdosSelector (Bitu realseg, Bitu realoff, Bitu &protsel, Bitu &protoff); + void API_Init_MSDOS (void); + Bitu API_Entry_MSDOS (void); + Bitu API_Int21_MSDOS (void); + +private: + Bitu saveStack[DPMI_SAVESTACK_MAX]; + Bitu savePtr; + Bitu rm_ss, rm_sp; + + struct { + struct { + bool have; + bool bit32; + Bitu psp; + } client; + Bit16u xms_handle; /* Handle for GDT/IDT */ + struct { + PhysPt base; + Bitu limit; + } gdt,idt,ldt; + struct { + bool inCall; + bool inUse; + bool stop; + Bitu callCount; + Bitu id; + Bitu dataSelector,dataOffset; + Bitu codeSelector,codeOffset; + Bitu realSegment ,realOffset; + } rmCallback[DPMI_REALMODE_CALLBACK_MAX]; + + RealPt realModeVec [DPMI_REALVEC_MAX]; + Bitu oldRealVec [DPMI_REALVEC_MAX]; + Bitu defaultHWIntFromProtMode[DPMI_REALVEC_MAX]; + Bitu firstRmCallback; + Bitu firstRmCallbackInt; + bool inHWINTDefaultHandler[DPMI_REALVEC_MAX]; + + PhysPt ptorint_base; /* Base of pmode int handlers that reflect to realmode */ + Bitu exceptionSelector[DPMI_EXCEPTION_MAX],exceptionOffset[DPMI_EXCEPTION_MAX]; + + + Bitu xmsHandles[DPMI_XMSHANDLES_MAX]; + Bitu protStack; + + Bitu protStackSelector[DPMI_PROTMODE_STACK_MAX]; + Bitu realStackSelector[DPMI_PROTMODE_STACK_MAX]; + Bitu dataSelector [DPMI_PROTMODE_STACK_MAX]; + Bitu protStackCurrent; + + Bitu vIntFlag; + + bool pharlap; + bool suppressRMCB; + } dpmi; + + Bit32u* modIntTable; + DPMI* prevDPMI; + + Bitu dtaAddress; + Bitu save_cs[2],save_ds[2],save_es[2],save_fs[2],save_gs[2],save_ss[2]; + Bitu save_eax[2],save_ebx[2],save_ecx[2],save_edx[2],save_esi[2],save_edi[2]; + Bitu save_ebp[2],save_esp[2],save_eip[2],save_fl[2]; +}; + +struct { + Bitu entry; + Bitu ptorint; + Bitu ptorintReturn; + Bitu int31; + Bitu int21; + Bitu int21Return; + Bitu int2f; + Bitu enterpmode; + Bitu enterrmode; + Bitu protsavestate; + Bitu realsavestate; + Bitu simint; + Bitu simintReturn; + Bitu rmIntFrame; + Bitu rmIntFrameReturn; + Bitu rmCallbackReturn; + Bitu exception; + Bitu exceptionret; + // Special callbacks for special dos extenders + Bitu apimsdosentry; + Bitu int21msdos; +} callback; + +// ************************************************ +// DPMI static functions +// ************************************************ + +static DPMI* activeDPMI = 0; +static Bit32u originalIntTable[256]; + +bool DPMI_IsActive(void) +{ + return (cpu.cr0 & CR0_PROTECTION) && activeDPMI && activeDPMI->HasClient(); } -void DPMI_Init(Section* sec) { - return; +void DPMI_SetVirtualIntFlag(bool on) +{ + if (activeDPMI) activeDPMI->SetVirtualIntFlag(on); +} + +void DPMI_CreateException(Bitu num, Bitu errorCode) +{ + if (activeDPMI) activeDPMI->CreateException(num,errorCode); +} + +// ************************************************ +// DPMI Methods +// ************************************************ + +DPMI::DPMI(void) +{ + memset(&dpmi,0,sizeof(dpmi)); + savePtr = 0; + dtaAddress = 0; + rm_ss = rm_sp = 0; + modIntTable = 0; + prevDPMI = activeDPMI; +}; + +DPMI::~DPMI(void) +{ + XMS_FreeMemory(dpmi.xms_handle); + // TODO: Free all memory allocated with DOS_GetMemory + // Activate previous dpmi + activeDPMI = prevDPMI; +}; + +void DPMI::ClearXMSHandles(void) +{ + for (Bitu i=0; i=DPMI_SAVESTACK_MAX) E_Exit("DPMI: Stack too small."); + saveStack[savePtr++] = SegValue(ds); + saveStack[savePtr++] = SegValue(es); + saveStack[savePtr++] = SegValue(fs); + saveStack[savePtr++] = SegValue(gs); + saveStack[savePtr++] = SegValue(ss); +} + +void DPMI::SaveRegister(void) +{ + SaveSegments(); + if (savePtr+8>=DPMI_SAVESTACK_MAX) E_Exit("DPMI: Stack too small."); + saveStack[savePtr++] = reg_eax; + saveStack[savePtr++] = reg_ebx; + saveStack[savePtr++] = reg_ecx; + saveStack[savePtr++] = reg_edx; + saveStack[savePtr++] = reg_esi; + saveStack[savePtr++] = reg_edi; + saveStack[savePtr++] = reg_ebp; + saveStack[savePtr++] = reg_esp; +}; + +void DPMI::RestoreSegments(void) +{ + CPU_SetSegGeneral(ss,saveStack[--savePtr]); + CPU_SetSegGeneral(gs,saveStack[--savePtr]); + CPU_SetSegGeneral(fs,saveStack[--savePtr]); + CPU_SetSegGeneral(es,saveStack[--savePtr]); + CPU_SetSegGeneral(ds,saveStack[--savePtr]); +}; + +void DPMI::RestoreRegister(void) +{ + reg_esp = saveStack[--savePtr]; + reg_ebp = saveStack[--savePtr]; + reg_edi = saveStack[--savePtr]; + reg_esi = saveStack[--savePtr]; + reg_edx = saveStack[--savePtr]; + reg_ecx = saveStack[--savePtr]; + reg_ebx = saveStack[--savePtr]; + reg_eax = saveStack[--savePtr]; + RestoreSegments(); +}; + +void DPMI::CopyRegistersToBuffer(PhysPt data) +{ + // Save Values in structure + mem_writed(data+0x00, reg_edi); + mem_writed(data+0x04, reg_esi); + mem_writed(data+0x08, reg_ebp); + mem_writed(data+0x0C, 0x0000); + mem_writed(data+0x10, reg_ebx); + mem_writed(data+0x14, reg_edx); + mem_writed(data+0x18, reg_ecx); + mem_writed(data+0x1C, reg_eax); + FILLFLAGS; + mem_writew(data+0x20, flags.word); + mem_writew(data+0x22, SegValue(es)); + mem_writew(data+0x24, SegValue(ds)); + mem_writew(data+0x26, SegValue(fs)); + mem_writew(data+0x28, SegValue(gs)); + mem_writew(data+0x2A, reg_ip); + mem_writew(data+0x2C, SegValue(cs)); + mem_writew(data+0x2E, reg_sp); + mem_writew(data+0x30, SegValue(ss)); +} + +void DPMI::LoadRegistersFromBuffer(PhysPt data) +{ + reg_edi = mem_readd(data+0x00); + reg_esi = mem_readd(data+0x04); + reg_ebp = mem_readd(data+0x08); + reg_ebx = mem_readd(data+0x10); + reg_edx = mem_readd(data+0x14); + reg_ecx = mem_readd(data+0x18); + reg_eax = mem_readd(data+0x1C); + SETFLAGSw(mem_readw(data+0x20)); + SegSet16(es,mem_readw(data+0x22)); + SegSet16(ds,mem_readw(data+0x24)); + SegSet16(fs,mem_readw(data+0x26)); + SegSet16(gs,mem_readw(data+0x28)); + reg_esp = mem_readw(data+0x2E); + SegSet16(ss,mem_readw(data+0x30)); + if (!dpmi.client.bit32) { + reg_eax &= 0xFFFF; + reg_ebx &= 0xFFFF; + reg_ecx &= 0xFFFF; + reg_edx &= 0xFFFF; + reg_edi &= 0xFFFF; + reg_esi &= 0xFFFF; + reg_ebp &= 0xFFFF; + reg_esp &= 0xFFFF; + }; +}; + +void DPMI::ProvideRealModeStack(PhysPt prStack, Bitu toCopy) +{ + // Check stack, if zero provide it + if ((SegValue(ss)==0) && (reg_sp==0)) { + SegSet16(ss,rm_ss); + reg_sp = rm_sp; + } else { + if (SegValue(ss)==rm_ss) reg_sp = rm_sp; + }; + // We have to be in realmode here + if (toCopy>0) { + Bitu numBytes = toCopy*2; + if (reg_spDPMI_REALMODE_STACKSIZE) E_Exit("DPMI:Realmode stack out of range: %04X",reg_sp); + rm_sp = reg_sp; + } +}; + +Bitu DPMI::AllocateLDTDescriptor(Bitu count,Bitu & base) { + + SetDescriptor test; + Bitu i=16, found=0; + PhysPt address = dpmi.ldt.base + LDT_FIRSTSELECTOR*8; + while (i0;found--) { + test.Save(address); + address+=8; + } + return true; + } + } + return false; +} + +Bitu DPMI::AllocateLDTDescriptor2(Bitu count,Bitu & base) { + + static Bitu allocated = 0; + + SetDescriptor desc; + Bitu nr = LDT_FIRSTSELECTOR + allocated; + if (nr+count < LDT_SIZE) { + desc.Clear(); + desc.SetType(DESC_DATA_EU_RW_NA); + desc.saved.seg.p = 1; + desc.saved.seg.big = dpmi.client.bit32; + desc.saved.seg.dpl = DPMI_DPL; + base = (nr << 3)|(4|DPMI_DPL); /* Make it an LDT Entry */ + allocated += count; + Bitu address = dpmi.ldt.base+(base & ~7); + for (;count>0;count--) { + desc.Save(address); + address+=8; + } + return true; + }; + return false; +} + +Bitu DPMI::CreateAlias(Bitu selector, Bit16u& alias) +{ + Descriptor oldDesc; + Bitu base; + if (!cpu.gdt.GetDescriptor(selector,oldDesc)) { alias = DPMI_ERROR_INVALID_SELECTOR; return false; }; + if (!AllocateLDTDescriptor(1,base)) { alias = DPMI_ERROR_DESCRIPTOR_UNAVAILABLE; return false; }; + SetDescriptor desc; + desc.Clear(); + desc.SetLimit(oldDesc.GetLimit()); + desc.SetBase (oldDesc.GetBase()); + desc.SetType (DESC_DATA_ED_RW_A); + desc.saved.seg.p=1; + desc.saved.seg.dpl = DPMI_DPL; + desc.Save (dpmi.ldt.base+(base & ~7)); + alias = base; + return true; +}; + +void DPMI::ReloadSegments(Bitu selector) +{ + if (SegValue(cs)==selector) CPU_SetSegGeneral(cs,selector); + if (SegValue(ds)==selector) CPU_SetSegGeneral(ds,selector); + if (SegValue(es)==selector) CPU_SetSegGeneral(es,selector); + if (SegValue(fs)==selector) CPU_SetSegGeneral(fs,selector); + if (SegValue(gs)==selector) CPU_SetSegGeneral(gs,selector); + if (SegValue(ss)==selector) CPU_SetSegGeneral(ss,selector); +}; + +void DPMI::CreateException(Bitu num, Bitu errorCode) +{ + if (dpmi.client.bit32) { + CPU_Push32(SegValue(ss)); + CPU_Push32(reg_esp); + CPU_Push32(flags.word); + CPU_Push32(SegValue(cs)); + CPU_Push32(reg_eip-2); // FIXME: Fake ! + CPU_Push32(errorCode); + CPU_Push32(GDT_PROTCODE); // return cs + CPU_Push32(DPMI_CB_EXCEPTIONRETURN_OFFSET); // return eip + } else { + CPU_Push16(SegValue(ss)); + CPU_Push16(reg_sp); + CPU_Push16(flags.word); + CPU_Push16(SegValue(cs)); + CPU_Push16(reg_ip-2); // FIXME: Fake ! + CPU_Push16(errorCode); + CPU_Push16(GDT_PROTCODE); // return cs + CPU_Push16(DPMI_CB_EXCEPTIONRETURN_OFFSET); // return eip + }; + DPMI_LOG("DPMI: Exception occured : %04X (%04X:%08X)",num,dpmi.exceptionSelector[num],dpmi.exceptionOffset[num]); + CPU_JMP(dpmi.client.bit32,dpmi.exceptionSelector[num],dpmi.exceptionOffset[num]); +}; + +Bitu DPMI::ExceptionReturn(void) +{ + Bitu error; + // Restore Registers + if (dpmi.client.bit32) { + error = CPU_Pop32(); + reg_eip = CPU_Pop32(); + CPU_SetSegGeneral(cs,CPU_Pop32()); + SETFLAGSd(CPU_Pop32()); + reg_esp = CPU_Pop32(); + CPU_SetSegGeneral(ss,CPU_Pop32()); + } else { + error = CPU_Pop16(); + reg_eip = CPU_Pop16(); + CPU_SetSegGeneral(cs,CPU_Pop16()); + SETFLAGSw(CPU_Pop16()); + reg_esp = CPU_Pop16(); + CPU_SetSegGeneral(ss,CPU_Pop16()); + }; + DPMI_LOG("DPMI: Return from Exception. Jump to %04X:%08X",SegValue(cs),reg_eip); + CPU_JMP(dpmi.client.bit32,SegValue(cs),reg_eip); + return 0; +}; + +void DPMI::RemoveIntCallbacks() +// When switching dpmi clients, remove active callbacks from hardware int +{ + Bitu i; + modIntTable = new Bit32u[256]; + // read and store interrupt table + for (i=0; i<256; i++) modIntTable[i] = mem_readd(i*4); + // set a clean interrupt table + for (i=0; i<256; i++) mem_writed(i*4,originalIntTable[i]); +}; + +void DPMI::RestoreIntCallbacks() +{ + if (modIntTable) { + // restore modified interrupt table + for (int i=0; i<256; i++) mem_writed(i*4,modIntTable[i]); + delete[] modIntTable; modIntTable = 0; + } +}; + +bool DPMI::AllocateRealModeCallback(Bitu codeSel,Bitu codeOff,Bitu dataSel, Bitu dataOff, Bitu& segment, Bitu& offset) +{ + Bitu num = 0; + for (Bitu i=0; i=DPMI_REALMODE_CALLBACK_MAX) || !dpmi.rmCallback[num].inUse) E_Exit("DPMI: Illegal Realmode callback %02X.",num); + + if (dpmi.rmCallback[num].inCall) DPMI_LOG("DPMI: Recursive Realmode callback %02X",num); + if (dpmi.protStackCurrent>DPMI_PROTMODE_STACK_MAX) E_Exit("DPMI: Too many recursive Realmode callbacks. Stack failure."); + + PushStack(num); + + DPMI_LOG("DPMI: Realmode Callback %02X (%04X:%08X) enter",num,dpmi.rmCallback[num].codeSelector,dpmi.rmCallback[num].codeOffset); + dpmi.rmCallback[num].inCall= true; + dpmi.rmCallback[num].callCount++; + + // Important! Update realmode stack + UpdateRealModeStack(); + // Setup stack selector of real mode stack + SetDescriptor desc; + if (cpu.gdt.GetDescriptor(dpmi.realStackSelector[dpmi.protStackCurrent],desc)) { + desc.SetBase (SegValue(ss)<<4); + desc.SetLimit(0xFFFF); + desc.Save (dpmi.ldt.base+(dpmi.realStackSelector[dpmi.protStackCurrent] & ~7)); + } else E_Exit("DPMI: RealmodeCB: Could not provide real mode stack descriptor."); + /* Switch to protected mode */ + CPU_SET_CRX(0,cpu.cr0 | CR0_PROTECTION); + // Setup dataSelector + Descriptor data; + Bitu dataSelector; + if (dpmi.rmCallback[num].dataSelector==0x0000) dataSelector = dpmi.dataSelector[dpmi.protStackCurrent]; + else dataSelector = dpmi.rmCallback[num].dataSelector; + if (!cpu.gdt.GetDescriptor(dataSelector,data)) E_Exit("DPMI: Init RM-Callback failed."); + + DPMI_LOG("DPMI: CB: Writing RegData at = %04X:%04X",dataSelector,dpmi.rmCallback[num].dataOffset); + // Prepare data buffer + CopyRegistersToBuffer(PhysPt(data.GetBase()+dpmi.rmCallback[num].dataOffset)); + DPMI_LOG("DPMI: CB: Stored cs:ip = %04X:%04X",SegValue(cs),reg_ip); + // setup registers for protected mode func + CPU_SetSegGeneral(ds,dpmi.realStackSelector[dpmi.protStackCurrent]); // DS:ESI = RM Stack + reg_esi = reg_esp; + CPU_SetSegGeneral(es,dataSelector); // ES:EDI = RM Register data + reg_edi = dpmi.rmCallback[num].dataOffset; + // SS:ESP = API stack + CPU_SetSegGeneral(ss,dpmi.protStackSelector[dpmi.protStackCurrent++]); + reg_esp = DPMI_PROTMODE_STACKSIZE; + // prepare stack for iret + FILLFLAGS; + if (dpmi.client.bit32) CPU_Push32(flags.word); else CPU_Push16(flags.word); + // Setup cs:ip to return to DPMI_ReturnFromRealModeCallback + CPU_SetSegGeneral(cs,GDT_CODE); + reg_eip = RealOff(CALLBACK_RealPointer(callback.rmCallbackReturn)); + // call protected mode func + SETFLAGBIT(IF,false); + SETFLAGBIT(TF,false); + CPU_Push32(flags.word); + CPU_CALL(dpmi.client.bit32,dpmi.rmCallback[num].codeSelector,dpmi.rmCallback[num].codeOffset); + return 0; +}; + +Bitu DPMI::RealModeCallbackReturn(void) +{ + // returning from protected mode function, now back to real mode + Bitu num = PopStack(); + DPMI_LOG("DPMI: Realmode Callback leave %02X",num); + dpmi.suppressRMCB = false; + dpmi.rmCallback[num].inCall = false; + dpmi.rmCallback[num].stop = false; + dpmi.rmCallback[num].callCount--; + PhysPt data = PhysPt(SegPhys(es)+reg_edi); + DPMI_LOG("DPMI: CB: Reading RegData at = %04X:%04X",SegValue(es),reg_edi); + /* Swtich to real mode */ + CPU_SET_CRX(0,cpu.cr0 & ~CR0_PROTECTION); + dpmi.protStackCurrent--; + // Restore Registers + LoadRegistersFromBuffer(data); + Bitu newCS = mem_readw(data+0x2C); + Bitu newIP = mem_readw(data+0x2A); + UpdateRealModeStack(); + DPMI_LOG("DPMI: CB: Retored cs:ip = %04X:%04X",newCS,newIP); + CPU_JMP(false,newCS,newIP); + return 0; +}; + +Bitu DPMI::CallRealIRETFrame(void) +{ + Bitu calledIP = mem_readd(SegPhys(ss)+reg_esp); + Bitu calledCS = mem_readd(SegPhys(ss)+reg_esp+4); + DPMI_LOG("DPMI: ENTER REAL PROC IRETF %04X:%08X",calledCS,calledIP); + // Save changed registers + PushStack(SegValue(cs)); + SaveRegister(); + Bitu toCopy = reg_cx; + // Load Registers + PhysPt data = SegPhys(es) + reg_edi; + PhysPt prStack = SegPhys(ss) + reg_esp; + LoadRegistersFromBuffer(data); + PushStack(data); + /* Switch to real mode */ + CPU_SET_CRX(0,cpu.cr0 & ~CR0_PROTECTION); + // Provide Stack + ProvideRealModeStack(prStack,toCopy); + // Push flags + FILLFLAGS; + CPU_Push16(flags.word); + // Setup IP + Bitu newCS = mem_readw(data+0x2C); + Bitu newIP = mem_readw(data+0x2A); + // Setup cs:ip to return to DPMI_CallRealIRETFrame callback + SegSet16(cs,RealSeg(CALLBACK_RealPointer(callback.rmIntFrameReturn))); + reg_ip = RealOff(CALLBACK_RealPointer(callback.rmIntFrameReturn)); + SETFLAGBIT(IF,false); + SETFLAGBIT(TF,false); + CPU_CALL(false,newCS,newIP); + return 0; +} + +Bitu DPMI::CallRealIRETFrameReturn(void) +{ + UpdateRealModeStack(); + // returning from realmode func + DPMI_LOG("DPMI: LEAVE REAL PROC IRETF"); + /* Switch to protected mode */ + CPU_SET_CRX(0,cpu.cr0 | CR0_PROTECTION); + // Save registers into real mode structure + CopyRegistersToBuffer(PopStack()); + // Restore changed Resgisters + RestoreRegister(); + CPU_SetSegGeneral(cs,PopStack()); + // Free last realmode stack + DPMI_CALLBACK_SCF(false); + return 0; +}; + +Bitu DPMI::SimulateInt(void) +{ + Bitu num = reg_bl; + DPMI_LOG("DPMI: SIM INT %02X %04X called.",num,reg_ax); + // Save changed registers + PushStack(SegValue(cs)); + SaveRegister(); + Bitu toCopy = reg_cx; + // Load Registers + PhysPt data = SegPhys(es) + reg_edi; + PhysPt prStack = SegPhys(ss) + reg_esp; + LoadRegistersFromBuffer(data); + PushStack(data); + /* Switch to real mode */ + CPU_SET_CRX(0,cpu.cr0 & ~CR0_PROTECTION); + // Provide Stack + ProvideRealModeStack(prStack,toCopy); + // prepare for return + SegSet16(cs,RealSeg(CALLBACK_RealPointer(callback.simintReturn))); + reg_ip = RealOff(CALLBACK_RealPointer(callback.simintReturn)); + // Push flags from structure on stack + DPMI_LOG("DPMI: SimInt1: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_sp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); + flags.word = mem_readw(data+0x20); + Interrupt(num); + DPMI_LOG("DPMI: SimInt2: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_sp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); + return 0; +}; + +Bitu DPMI::SimulateIntReturn(void) +{ + // returning from realmode func + DPMI_LOG("DPMI: SIM INT return"); + DPMI_LOG("DPMI: SimIntRet1: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_sp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); + + UpdateRealModeStack(); + /* Switch to protected mode */ + CPU_SET_CRX(0,cpu.cr0 | CR0_PROTECTION); + // Save registers into real mode structure + CopyRegistersToBuffer(PopStack()); + // Restore changed Resgisters + RestoreRegister(); + CPU_SetSegGeneral(cs,PopStack()); + // Free last realmode stack + DPMI_CALLBACK_SCF(false); + DPMI_LOG("DPMI: SimIntRet2: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_sp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); + return 0; +}; + +void DPMI::PrepareReflectToReal(Bitu num) +{ + // Save segment and stack register + SaveSegments(); + PushStack(reg_esp); + PushStack(num); + PushStack(reg_eip); + PushStack(SegValue(cs)); + /* Swtich to real mode */ + CPU_SET_CRX(0,cpu.cr0 & ~CR0_PROTECTION); + // Setup cs:ip to return to intreturn + SegSet16(cs,RealSeg(CALLBACK_RealPointer(callback.ptorintReturn))); + reg_ip = RealOff(CALLBACK_RealPointer(callback.ptorintReturn)); + // setup stack + SegSet16(ss,rm_ss); + reg_sp = rm_sp; +} + +Bitu DPMI::ptorHandler(void) +{ + /* Pmode interrupt handler that maps the interrupt to realmode */ + Bitu num = reg_eip >> 3; + if (!dpmi.vIntFlag) { + if ((num>=0x08) && (num<=0x0F)) return 0; + if ((num>=0x70) && (num<=0x77)) return 0; + }; + PrepareReflectToReal(num); + if (num==0x0F) + DPMI_LOG("DPMI: INT %02X %04X called.",num,reg_ax); + // Prepare flags for real int + // SETFLAGSw(flags.word & 0x3ED5); // 0011111011010101b + Interrupt(num); + return 0; +} + +Bitu DPMI::ptorHandlerReturn(void) +// Return from reflected real mode int +{ + UpdateRealModeStack(); + /* Switch to protected mode */ + CPU_SET_CRX(0,cpu.cr0 | CR0_PROTECTION); + // Restore Registers + CPU_SetSegGeneral(cs,PopStack()); + reg_eip = PopStack(); + Bitu num = PopStack(); + reg_esp = PopStack(); + RestoreSegments(); +// if (num==0x0F) + DPMI_LOG("DPMI: INT %02X RETURN",num); + // hardware ints exit here + if (((num>=0x08) && (num<=0x0F)) || ((num>=0x70) && (num<=0x77))) { + for (Bitu i=0; iReactivate(); + } + return 0; +}; + +Bitu DPMI::Int21HandlerReturn(void) +{ + UpdateRealModeStack(); + /* Switch to protected mode */ + CPU_SET_CRX(0,cpu.cr0 | CR0_PROTECTION); + // Restore Registers + CPU_SetSegGeneral(es,PopStack()); + CPU_SetSegGeneral(ds,PopStack()); + reg_esp = PopStack(); + CPU_SetSegGeneral(ss,PopStack()); + // DPMI_RestoreSegments(); + // Set carry flag + DPMI_CALLBACK_SCF(flags.word & 1); + DPMI_LOG("DPMI: INT 21 RETURN"); + return 0; +} + +Bitu DPMI::HWIntDefaultHandler() +// Wir sind hier im Protected mode +// a) durch einen INTerrupt im protected mode +// b) durch einen INTerrupt im real mode (durch RMCB) +{ + Bitu index = mem_readw(PhysPt(SegPhys(cs)+reg_eip-2)) - dpmi.defaultHWIntFromProtMode[0]; + if (index>=DPMI_REALVEC_MAX) E_Exit("DPMI: Illegal realmode interrupt callback: %02X",index); + Bitu num = rmIndexToInt[index]; + + RealPt vec = RealGetVec(num); + // Falls INT in protected mode gestartet wurde ist hier callCount noch 0 + if (num==0x0F) { + int brk = 0; + }; + + SetVirtualIntFlag(false); + if (dpmi.rmCallback[index].callCount==0) { + // INT PROT (Use Handler is already done). + // Wenn rmcb noch in Realmode Int table installiert, dann originalMethode aufrufef + if (vec==dpmi.realModeVec[index]) { + // originalroutine aufrufen + dpmi.rmCallback[index].stop = false; + PrepareReflectToReal(num); + FILLFLAGS; + CPU_Push16(flags.word); + SETFLAGBIT(IF,false); + SETFLAGBIT(TF,false); + CPU_CALL(false,RealSeg(dpmi.oldRealVec[index]),RealOff(dpmi.oldRealVec[index])); + } else { + // user real mode handler in real mode int table aktiv. + // Moeglich, dass dieser den RMCB von Hand noch aufruft + // dann wird aber callCount>0 sein (da RMCB aktiv) und + // dann die alte Routine aufgerufen... + // RMCB sperren, um einen erneuten Aufruf des User Handlers zu vermeiden,.. + + // This is a hack for cybermage wich wont work otherwise. But why ? + if (num==0x0F) { + if (dpmi.suppressRMCB) { + dpmi.suppressRMCB = false; + return 0; + } else { + dpmi.suppressRMCB = true; + } + }; + PrepareReflectToReal(num); + FILLFLAGS; + SETFLAGBIT(IF,false); + SETFLAGBIT(TF,false); + CPU_Push16(flags.word); + CPU_CALL(false,RealSeg(vec),RealOff(vec)); + } + } else { + // INT REAL (vom RMCB aktiviert) + // Falls user handler schon aktiv war (int von prot->reflected to real) + // rufe original routine auf + if (dpmi.rmCallback[index].stop) { + dpmi.rmCallback[index].stop = false; + PrepareReflectToReal(num); + FILLFLAGS; + CPU_Push16(flags.word); + SETFLAGBIT(IF,false); + SETFLAGBIT(TF,false); + CPU_CALL(false,RealSeg(dpmi.oldRealVec[index]),RealOff(dpmi.oldRealVec[index])); + } else { + // User routine wurde noch nicht aktiviert, callback aber ausgeführt + // falls spezieller protected mode handler aktiviert wurde, + // wird dieser jetzt aufgerufen (user routine im protected mode) + Descriptor gate; + gate.Load(dpmi.idt.base+num*8); + if ((gate.GetSelector()!=GDT_CODE) || (gate.GetOffset()!=RealOff(dpmi.defaultHWIntFromProtMode[index]))) { + dpmi.rmCallback[index].stop = true; // vermeide rekursion + CPU_JMP(dpmi.client.bit32,gate.GetSelector(),gate.GetOffset()); + } else { + // kein spezieller Protmode handler - Rufe originalroutine auf + PrepareReflectToReal(num); + FILLFLAGS; + CPU_Push16(flags.word); + SETFLAGBIT(IF,false); + SETFLAGBIT(TF,false); + CPU_CALL(false,RealSeg(dpmi.oldRealVec[index]),RealOff(dpmi.oldRealVec[index])); + }; + }; + } + return 0; +}; + +void DPMI::SaveRegisterState(Bitu num) +// Copy Current Registers to structure +{ + save_cs[num] = SegValue(cs); + save_ds[num] = SegValue(ds); + save_es[num] = SegValue(es); + save_fs[num] = SegValue(fs); + save_gs[num] = SegValue(gs); + save_ss[num] = SegValue(ss); + save_eip[num] = reg_eip; + save_eax[num] = reg_eax; + save_ebx[num] = reg_ebx; + save_ecx[num] = reg_ecx; + save_edx[num] = reg_edx; + save_esi[num] = reg_esi; + save_edi[num] = reg_edi; + save_ebp[num] = reg_ebp; + save_esp[num] = reg_esp; + save_fl [num] = flags.word; +}; + +void DPMI::LoadRegisterState(Bitu num) +// Copy Current Registers to structure +{ + CPU_SetSegGeneral(fs,save_fs[num]); + CPU_SetSegGeneral(gs,save_gs[num]); + reg_eax = save_eax[num]; + reg_ebx = save_ebx[num]; + reg_ecx = save_ecx[num]; + reg_edx = save_edx[num]; + reg_esi = save_esi[num]; + reg_edi = save_edi[num]; + flags.word = save_fl [num]; +}; + +Bitu DPMI::EnterProtMode(void) { + + /* Save real mode register state */ + SaveRegisterState(0); + + /* Switch to protected mode */ + CPU_SET_CRX(0,cpu.cr0 | CR0_PROTECTION); + + CPU_SetSegGeneral(ds,reg_ax); + CPU_SetSegGeneral(es,reg_cx); + CPU_SetSegGeneral(ss,reg_dx); + CPU_SetSegGeneral(ds,reg_ax); + + if (dpmi.client.bit32) { + reg_esp = reg_ebx; + CPU_JMP(true,reg_si,reg_edi); + } else { + reg_sp = reg_bx; + CPU_JMP(false,reg_si,reg_di); + }; + + /* Load prot mode register state (all other unchanged registers */ + LoadRegisterState(1); + + DPMI_LOG("DPMI: Switch to protected mode."); + return 0; +} + +Bitu DPMI::EnterRealMode(void) { + + /* Save Prot Mode Registers */ + SaveRegisterState(1); + + /* Swtich to real mode */ + CPU_SET_CRX(0,cpu.cr0 & ~CR0_PROTECTION); + // (E)BP will be preserved across the mode switch call so it can be used as a pointer. + // TODO: If interrupts are disabled when the mode switch procedure is invoked, + // they will not be re-enabled by the DPMI host (even temporarily). + SegSet16(ds,reg_ax); + SegSet16(es,reg_cx); + SegSet16(ss,reg_dx); + SegSet16(fs,0); + SegSet16(gs,0); + if (dpmi.client.bit32) { + reg_esp = reg_ebx; + CPU_JMP(true,reg_si,reg_edi); + } else { + reg_sp = reg_bx; + CPU_JMP(false,reg_si,reg_di); + }; + + /* Load real mode register state (all other unchanged registers) */ + LoadRegisterState(0); + DPMI_LOG("DPMI: Switch to real mode."); + return CBRET_NONE; +}; + +Bitu DPMI::RealSaveState(void) +{ + /* Save Protected mode state */ + if (reg_al==0) { + PhysPt data = SegPhys(es) + reg_edi; + mem_writew(data+ 0,save_cs[1]); + mem_writew(data+ 2,save_ds[1]); + mem_writew(data+ 4,save_es[1]); + mem_writew(data+ 6,save_fs[1]); + mem_writew(data+ 8,save_gs[1]); + mem_writew(data+10,save_ss[1]); + mem_writed(data+12,save_eax[1]); + mem_writed(data+16,save_ebx[1]); + mem_writed(data+20,save_ecx[1]); + mem_writed(data+24,save_edx[1]); + mem_writed(data+28,save_esi[1]); + mem_writed(data+32,save_edi[1]); + mem_writed(data+36,save_ebp[1]); + mem_writed(data+40,save_esp[1]); + mem_writed(data+44,save_fl [1]); + DPMI_LOG("DPMI: Prot Save State."); + } else if (reg_al==1) { + /* restore state of prot mode registers */ + PhysPt data = SegPhys(es) + reg_edi; + save_cs [1] = mem_readw(data+ 0); + save_ds [1] = mem_readw(data+ 2); + save_es [1] = mem_readw(data+ 4); + save_fs [1] = mem_readw(data+ 6); + save_gs [1] = mem_readw(data+ 8); + save_ss [1] = mem_readw(data+10); + save_eax[1] = mem_readd(data+12); + save_ebx[1] = mem_readd(data+26); + save_ecx[1] = mem_readd(data+20); + save_edx[1] = mem_readd(data+24); + save_edi[1] = mem_readd(data+28); + save_esi[1] = mem_readd(data+32); + save_ebp[1] = mem_readd(data+36); + save_esp[1] = mem_readd(data+40); +// save_eip[1] = mem_readd(data+44); + save_fl [1] = mem_readd(data+44); + DPMI_LOG("DPMI: Prot Restore State."); + }; + return CBRET_NONE; +}; + +Bitu DPMI::ProtSaveState(void) +{ + if (reg_al==0) { + /* Save State of real mode registers */ + PhysPt data = SegPhys(es) + reg_edi; + mem_writew(data+ 0,save_cs[0]); + mem_writew(data+ 2,save_ds[0]); + mem_writew(data+ 4,save_es[0]); + mem_writew(data+ 6,save_fs[0]); + mem_writew(data+ 8,save_gs[0]); + mem_writew(data+10,save_ss[0]); + mem_writed(data+12,save_eax[0]); + mem_writed(data+16,save_ebx[0]); + mem_writed(data+20,save_ecx[0]); + mem_writed(data+24,save_edx[0]); + mem_writed(data+28,save_esi[0]); + mem_writed(data+32,save_edi[0]); + mem_writed(data+36,save_ebp[0]); + mem_writed(data+40,save_esp[0]); + mem_writed(data+44,save_eip[0]); + mem_writed(data+48,save_fl [0]); + DPMI_LOG("DPMI: Real Save State."); + } else if (reg_al==1) { + /* restore state of real mode registers */ + PhysPt data = SegPhys(es) + reg_edi; + save_cs [0] = mem_readw(data+ 0); + save_ds [0] = mem_readw(data+ 2); + save_es [0] = mem_readw(data+ 4); + save_fs [0] = mem_readw(data+ 6); + save_gs [0] = mem_readw(data+ 8); + save_ss [0] = mem_readw(data+10); + save_eax[0] = mem_readd(data+12); + save_ebx[0] = mem_readd(data+26); + save_ecx[0] = mem_readd(data+20); + save_edx[0] = mem_readd(data+24); + save_edi[0] = mem_readd(data+28); + save_esi[0] = mem_readd(data+32); + save_ebp[0] = mem_readd(data+36); + save_esp[0] = mem_readd(data+40); + save_eip[0] = mem_readd(data+44); + save_fl [0] = mem_readd(data+48); + DPMI_LOG("DPMI: Real Restore State."); + }; + return CBRET_NONE; +}; + +bool DPMI::GetVirtualIntFlag(void) +// only to call from int 31 cos it uses the pushed flags on int stack +{ + if (dpmi.client.bit32) return (mem_readd(SegPhys(ss)+reg_esp+8) & FLAG_IF)>0; + else return (mem_readd(SegPhys(ss)+reg_sp+4) & FLAG_IF)>0; +}; + +void DPMI::SetVirtualIntFlag(bool on) +{ + dpmi.vIntFlag = on; +}; + +bool DPMI::AllocateMem(Bitu size, Bitu& outHandle, Bitu& linear) +{ + Bit16u handle; + Bit32u address; + Bitu pages = (size/1024) + ((size%1024)>0); // Convert to 1KB pages + if (XMS_AllocateMemory(pages,handle)==0) { + if (XMS_LockMemory(handle,address)==0) { + SetXMSHandle(handle); + outHandle = handle; + linear = address; + XMS_UnlockMemory(handle); + return true; + } + } + return false; +}; + +Bitu DPMI::Int31Handler(void) +{ + DPMI_LOG("DPMI: %04X",reg_ax); + + switch (reg_ax) { + + case 0x0000:{// Allocate LDT Descriptors + Bitu base; + Descriptor desc; + if (AllocateLDTDescriptor(reg_cx,base)) { + reg_ax = base; + DPMI_LOG("DPMI: 0000: Allocate %d descriptors: %04X",reg_cx,base); + DPMI_CALLBACK_SCF(false); + } else { + DPMI_LOG_ERROR("DPMI: 0000: Allocate %d descriptors failure",reg_cx); + reg_ax = DPMI_ERROR_DESCRIPTOR_UNAVAILABLE; + DPMI_CALLBACK_SCF(true); + }; + }; break; + case 0x0001:{// Free Descriptor + SetDescriptor desc; + if (cpu.gdt.GetDescriptor(reg_bx,desc)) { + desc.saved.seg.p = 0; + desc.Save (dpmi.ldt.base+(reg_bx & ~7)); + DPMI_LOG("DPMI: 0001: Free Descriptor: %04X",reg_bx); + DPMI_CALLBACK_SCF(false); + } else { + DPMI_LOG_ERROR("DPMI: 0001: Free Descriptor failure : %04X",reg_bx); + reg_ax = DPMI_ERROR_INVALID_SELECTOR; + DPMI_CALLBACK_SCF(true); + }; + }; break; + case 0x0002:{// Segment to Descriptor + SetDescriptor desc; Bitu base; + if (AllocateLDTDescriptor(1,base)) { + desc.Load (dpmi.ldt.base+(base & ~7)); + desc.SetLimit(0xFFFF); + desc.SetBase (reg_bx<<4); + desc.saved.seg.dpl=3; + desc.Save (dpmi.ldt.base+(base & ~7)); + reg_ax = base; + DPMI_CALLBACK_SCF(false); + } else { + // No more Descriptors available + DPMI_LOG_ERROR("DPMI: 0002: No more Descriptors available."); + reg_ax = DPMI_ERROR_DESCRIPTOR_UNAVAILABLE; + DPMI_CALLBACK_SCF(true); + }; + }; break; + case 0x0003:// Get Next Selector Increment Value + reg_ax = 8; + DPMI_CALLBACK_SCF(false); + break; + case 0x0004:// undocumented (reserved) lock selector + case 0x0005:// undocumented (reserved) unlock selector + DPMI_CALLBACK_SCF(true); + break; + case 0x0006:{ // Get Segment Base Address + SetDescriptor desc; + if (cpu.gdt.GetDescriptor(reg_bx,desc)) { + reg_cx = desc.GetBase()>>16; + reg_dx = desc.GetBase()&0xFFFF; + DPMI_CALLBACK_SCF(false); + } else { + DPMI_LOG_ERROR("DPMI: 0006: Invalid Selector: %04X",reg_bx); + reg_ax = DPMI_ERROR_INVALID_SELECTOR; + DPMI_CALLBACK_SCF(true); + }; + }; break; + case 0x0007:{// Set Segment base address + SetDescriptor desc; + if (cpu.gdt.GetDescriptor(reg_bx,desc)) { + Bitu base; + if (!dpmi.client.bit32) base = (reg_cl<<16)+reg_dx; + else base = (reg_cx<<16)+reg_dx; + desc.SetBase(base); + desc.Save (dpmi.ldt.base+(reg_bx & ~7)); + ReloadSegments(reg_bx); + DPMI_CALLBACK_SCF(false); + DPMI_LOG("DPMI: 0007: Set Base %08X",base); + } else { + DPMI_LOG_ERROR("DPMI: 0007: Invalid Selector: %04X",reg_bx); + reg_ax = DPMI_ERROR_INVALID_SELECTOR; + DPMI_CALLBACK_SCF(true); + }; + }; break; + case 0x0008:{// Set Segment limit + SetDescriptor desc; + if ((!dpmi.client.bit32) && (reg_cx!=0)) { + // 16-bit DPMI implementations can not set segment limits greater + // than 0FFFFh (64K) so CX must be zero when calling + reg_ax = DPMI_ERROR_INVALID_VALUE; + DPMI_CALLBACK_SCF(true); + } else if (cpu.gdt.GetDescriptor(reg_bx,desc)) { + desc.SetLimit((reg_cx<<16)+reg_dx); + desc.Save (dpmi.ldt.base+(reg_bx & ~7)); + ReloadSegments(reg_bx); + DPMI_CALLBACK_SCF(false); + DPMI_LOG("DPMI: 0008: Set Limit %08X",(reg_cx<<16)+reg_dx); + } else { + DPMI_LOG_ERROR("DPMI: 0008: Invalid Selector: %04X",reg_bx); + reg_ax = DPMI_ERROR_INVALID_SELECTOR; + DPMI_CALLBACK_SCF(true); + }; + }; break; + case 0x0009:{// Set Descriptor Access Rights + SetDescriptor desc; + Bit8u rcl = reg_cl; + Bit8u rch = reg_ch; + if (cpu.gdt.GetDescriptor(reg_bx,desc)) { +/* if (!(reg_cl & 0x10) || (reg_ch & 0x20) || (desc.saved.seg.dpl!=DPMI_DPL)) { + DPMI_LOG_ERROR("DPMI: 0009: Set Rights %04X : failure",reg_bx); + reg_ax = DPMI_ERROR_INVALID_VALUE; + DPMI_CALLBACK_SCF(true); + break; + };*/ + desc.SetType (reg_cl&0x1F); + desc.saved.seg.dpl = DPMI_DPL; + desc.saved.seg.p = (reg_cl&0x80)>0; + desc.saved.seg.avl = (reg_ch&0x10)>0; + desc.saved.seg.r = (reg_ch&0x20)>0; + desc.saved.seg.big = (reg_ch&0x40)>0; + desc.saved.seg.g = (reg_ch&0x80)>0; + desc.Save(dpmi.ldt.base+(reg_bx & ~7)); + ReloadSegments(reg_bx); + DPMI_CALLBACK_SCF(false); + DPMI_LOG("DPMI: 0009: Set Rights %04X : %04X",reg_bx,reg_cx); + } else { + DPMI_LOG_ERROR("DPMI: 0009: Set Rights %04X : failure",reg_bx); + reg_ax = DPMI_ERROR_DESCRIPTOR_UNAVAILABLE; + DPMI_CALLBACK_SCF(true); + }; + }; break; + case 0x000A:{// Create Alias Descriptor + Descriptor desc; + if (CreateAlias(reg_bx, reg_ax)) DPMI_CALLBACK_SCF(false); + else { + DPMI_CALLBACK_SCF(true); + DPMI_LOG_ERROR("DPMI: 000A: Invalid Selector: %04X",reg_bx); + }; }; break; + case 0x000B:{//Get Descriptor + SetDescriptor desc; + if (cpu.gdt.GetDescriptor(reg_bx,desc)) { + desc.Save(SegPhys(es)+reg_edi); + DPMI_CALLBACK_SCF(false); + DPMI_LOG("DPMI: 000B: Get Descriptor %04X : B:%08X L:%08X",reg_bx,desc.GetBase(),desc.GetLimit()); + } else { + DPMI_LOG_ERROR("DPMI: 000B: Get Descriptor %04X : failure",reg_bx); + reg_ax = DPMI_ERROR_DESCRIPTOR_UNAVAILABLE; + DPMI_CALLBACK_SCF(true); + }; + }; break; + case 0x000C:{//Set Descriptor + SetDescriptor desc; + if (cpu.gdt.GetDescriptor(reg_bx,desc)) { + desc.Load (SegPhys(es)+reg_edi); + // Check access rights +/* if (!(desc.saved.seg.type & 0x10) || (desc.saved.seg.r) || (desc.saved.seg.dpl!=DPMI_DPL)) { + DPMI_LOG("DPMI: 000C: Set Rights %04X : failure",reg_bx); + reg_ax = DPMI_ERROR_INVALID_VALUE; + DPMI_CALLBACK_SCF(true); + break; + };*/ + if (!desc.saved.seg.p) { + DPMI_LOG_ERROR("DPMI: 000C: Set Rights %04X : not present",reg_bx); + desc.saved.seg.p = 1; + } +// desc.saved.seg.type |= 0x10; +// if (!dpmi.client.bit32) +// desc.SetBase (desc.GetBase() & 0xFFFF); +// desc.SetLimit (desc.GetLimit() & 0xFFFF); +// }; + desc.Save(dpmi.ldt.base+(reg_bx & ~7)); + ReloadSegments(reg_bx); + DPMI_LOG("DPMI: 000C: Base %08X : Limit %08X : P %01X",desc.GetBase(),desc.GetLimit(),desc.saved.seg.p); + DPMI_CALLBACK_SCF(false); + } else { + DPMI_LOG_ERROR("DPMI: 000C: Set Descriptor %04X failed",reg_bx); + reg_ax = DPMI_ERROR_DESCRIPTOR_UNAVAILABLE; + DPMI_CALLBACK_SCF(true); + }; + }; break; + case 0x000D:{ // Allocate specific LDT Descriptor : TODO: Support it + DPMI_LOG("DPMI: 000D: Alloc Specific LDT Selector: %04X",reg_bx); + SetDescriptor desc; + if (cpu.gdt.GetDescriptor(reg_bx,desc)) { + if (!desc.saved.seg.p) { + desc.saved.seg.p = 1; + desc.SetLimit(0); + desc.SetBase (0); + desc.Save (dpmi.ldt.base+(reg_bx & ~7)); + DPMI_CALLBACK_SCF(false); + break; + } else { + DPMI_LOG_ERROR("DPMI: 000D: Invalid Selector: %04X",reg_bx); + reg_ax = DPMI_ERROR_DESCRIPTOR_UNAVAILABLE; + }; + } else reg_ax = DPMI_ERROR_INVALID_SELECTOR; + DPMI_CALLBACK_SCF(true); + }; break; + case 0x0100:{// Allocate DOS Memory Block + Bit16u blocks = reg_bx; + if (DOS_AllocateMemory(®_ax,&blocks)) { + // Allocate Selector for block + SetDescriptor desc; Bitu base; Bitu numDesc; + numDesc = reg_bx/0x1000 + ((reg_bx%0x1000)>0); + if (AllocateLDTDescriptor(numDesc,base)) { + reg_dx = base; + // First selector + if (numDesc>1) { + Bitu descBase = reg_ax*16; + Bitu length = reg_bx*16; + desc.Load (dpmi.ldt.base+(base & ~7)); + desc.SetBase (descBase); + desc.SetLimit(dpmi.client.bit32?length:0xFFFF); + desc.Save (dpmi.ldt.base+(base & ~7)); + for (Bitu i=1; i>4; + DOS_MCB mcb(seg-1); + Bitu size = mcb.GetSize()*16; + if (DOS_FreeMemory(seg)) { + while (size>0) { + desc.Load(dpmi.ldt.base+(sel & ~7)); + desc.saved.seg.p = 0; + desc.Save(dpmi.ldt.base+(sel & ~7)); + size -= (size>=0x10000)?0x10000:size; + sel+=8; + }; + DPMI_CALLBACK_SCF(false); + break; + } + } + DPMI_LOG_ERROR("DPMI: 0101: Invalid Selector: %04X",reg_bx); + reg_ax = DPMI_ERROR_INVALID_SELECTOR; + DPMI_CALLBACK_SCF(true); + };break; + case 0x0200:{// Get Real Mode Interrupt Vector + RealPt vec = RealGetVec(reg_bl); + reg_cx = RealSeg(vec); + reg_dx = RealOff(vec); + DPMI_CALLBACK_SCF(false); + }; break; + case 0x0201:{// Set Real Mode Interrupt Vector + RealSetVec(reg_bl,RealMake(reg_cx,reg_dx)); + DPMI_CALLBACK_SCF(false); + }; break; + case 0x0202:// Get Processor Exception Handler Vector + if (reg_bl>16); + reg_cx = (linear&0xFFFF); + DPMI_CALLBACK_SCF(false); + XMS_QueryFreeMemory(largest,total); // in KB + if (total==2804) { + int brk = 0; + } + DPMI_LOG("DPMI: 0501: Allocation success (%d KB) (R:%d KB)",length/1024,total); + } else { + reg_ax = DPMI_ERROR_PHYSICAL_MEMORY_UNAVAILABLE; + DPMI_CALLBACK_SCF(true); + XMS_QueryFreeMemory(largest,total); // in KB + DPMI_LOG_ERROR("DPMI: 0501: Allocation failure (%d KB) (R:%d KB)",length/1024,total); + }; + }; break; + case 0x0502://Free Memory Block + if (XMS_FreeMemory((reg_si<<16)+reg_di)==0) { + FreeXMSHandle((reg_si<<16)+reg_di); + DPMI_CALLBACK_SCF(false); + } else { + DPMI_LOG_ERROR("DPMI: 0502: Invalid Handle: %04X%04X",reg_si,reg_di); + reg_ax = DPMI_ERROR_INVALID_HANDLE; + DPMI_CALLBACK_SCF(true); + }; + break; + case 0x0503:{//Resize Memory Block + Bit32u newSize = (Bitu(reg_bx<<16)+reg_cx)/1024; + Bitu handle = (reg_si<<16)+reg_di; + if (XMS_ResizeMemory(handle,newSize)==0) { + if (XMS_LockMemory(handle,newSize)==0) { + reg_bx = (newSize>>16); + reg_cx = (newSize&0xFFFF); + DPMI_CALLBACK_SCF(false); + XMS_UnlockMemory(handle); + break; + } + } else { + Bitu newHandle,linear; + // Not possible, try to allocate + if (AllocateMem((reg_bx<<16)+reg_cx,newHandle,linear)) { + DPMI_LOG_ERROR("DPMI: 0503: Reallocated Memory: %d KB",newSize); + reg_si = 0; reg_di = newHandle; + reg_bx = (linear>>16); + reg_cx = (linear&0xFFFF); + DPMI_CALLBACK_SCF(false); + // FIXME: What to do with the old mem block ? delete ? + // FIXME: Copy contents ?! + if (XMS_FreeMemory(handle)==0) { + FreeXMSHandle(handle); + } else { + DPMI_LOG_ERROR("DPMI: 0503: Free old memory failure"); + }; + break; + } else { + AllocateMem((reg_bx<<16)+reg_cx,newHandle,linear); + DPMI_LOG_ERROR("DPMI: 0503: Reallocated Memory failure: %d KB",newSize); + } + }; + DPMI_LOG_ERROR("DPMI: 0503: Memory unavailable . %08X",newSize); + reg_ax = DPMI_ERROR_PHYSICAL_MEMORY_UNAVAILABLE; + DPMI_CALLBACK_SCF(true); + }; break; + case 0x0506:// Get Page Attributes + reg_ax = DPMI_ERROR_UNSUPPORTED; + DPMI_CALLBACK_SCF(true); + break; + case 0x0507:// Set Page Attributes + DPMI_CALLBACK_SCF(false); + break; + case 0x0509:{//Map Conventional Memory in Memory Block + Bit32u xmsAddress; + Bitu handle = reg_esi; + Bitu offset = reg_ebx; + Bitu numPages = reg_ecx; + Bitu linearAdr = reg_edx; + if (XMS_LockMemory(handle,xmsAddress)==0) { + LOG(LOG_MISC,LOG_ERROR)("DPMI: 0509: Mapping convmem %04X to %08X",linearAdr,xmsAddress+offset); + if ((numPages%4)!=0) E_Exit("DPMI: Cannot map conventional memory."); + MEM_SetupMapping(PAGE_COUNT((xmsAddress+offset)),PAGE_COUNT(numPages*DPMI_PAGE_SIZE),((Bit8u*)memory)+linearAdr); + XMS_UnlockMemory(handle); + DPMI_CALLBACK_SCF(false); + } else { + LOG(LOG_MISC,LOG_ERROR)("DPMI: 0509: Mapping convmem failure."); + reg_ax = DPMI_ERROR_INVALID_HANDLE; + DPMI_CALLBACK_SCF(true); + } + }; break; + case 0x0600:{//Lock Linear Region + Bitu address = (reg_bx<<16)+reg_cx; + Bitu size = (reg_si<<16)+reg_di; + DPMI_CALLBACK_SCF(false); + }; break; + case 0x0601://unlock Linear Region + DPMI_CALLBACK_SCF(false); + break; + case 0x0602:// Mark Real Mode Region as Pageable + DPMI_CALLBACK_SCF(false); + break; + case 0x0603:// Relock Real Mode Region + DPMI_CALLBACK_SCF(false); + break; + case 0x0604:// Get page size + reg_bx=0; reg_cx=DPMI_PAGE_SIZE; + DPMI_CALLBACK_SCF(false); + break; + case 0x0701:// Undocumented discard page contents + DPMI_CALLBACK_SCF(true); + break; + case 0x0702://Mark Page as Demand Paging Candidate + DPMI_CALLBACK_SCF(false); + break; + case 0x0703://Discard Page contents + DPMI_CALLBACK_SCF(false); + break; + case 0x0800:{//Physical Address Mapping + // bx and cx remain the same linear address = physical address + Bitu phys = (reg_bx<<16) + reg_cx; + Bitu size = (reg_si<<16) + reg_di; + DPMI_LOG_ERROR("DPMI: 0800: Phys-adr-map not supported : %08X.(%08X).",phys,size); + DPMI_CALLBACK_SCF(false); + }; break; + case 0x0801:// Free physical address mapping + DPMI_CALLBACK_SCF(false); + break; + case 0x0900://Get and Disable Virtual Interrupt State + reg_al = dpmi.vIntFlag; + dpmi.vIntFlag = 0; + DPMI_CALLBACK_SCF(false); + break; + case 0x0901://Get and Enable Virtual Interrupt State + reg_al = dpmi.vIntFlag; + dpmi.vIntFlag = 1; + DPMI_CALLBACK_SCF(false); + break; + case 0x0902:{//Get Virtual Interrupt State + reg_al = dpmi.vIntFlag; + DPMI_CALLBACK_SCF(false); + }; break; + case 0x0A00:{//Get Vendor Specific API Entry Point + char name[256]; + MEM_StrCopy(SegPhys(ds)+reg_esi,name,255); + LOG(LOG_MISC,LOG_WARN)("DPMI: Get API: %s",name); + if (strcmp(name,"MS-DOS")==0) { + CPU_SetSegGeneral(es,GDT_PROTCODE); + reg_edi = DPMI_CB_APIMSDOSENTRY_OFFSET; + API_Init_MSDOS(); + DPMI_CALLBACK_SCF(false); + } else if (strstr(name,"PHARLAP")!=0) { + CPU_SetSegGeneral(es,GDT_PROTCODE); + reg_edi = DPMI_CB_APIMSDOSENTRY_OFFSET; + API_Init_MSDOS(); + DPMI_CALLBACK_SCF(false); + dpmi.pharlap = true; + } else { + reg_ax = DPMI_ERROR_UNSUPPORTED; + DPMI_CALLBACK_SCF(true); + } + }; break; + case 0x0D00:{//Allocate Shared Memory + PhysPt data = SegPhys(es)+reg_edi; + Bit32u linadr; + Bitu length = mem_readd(data); + Bitu pages = (length/1024) + ((length%1024)>0); + Bit16u handle; + if (XMS_AllocateMemory(pages,handle)==0) { + if (XMS_LockMemory(handle,linadr)==0) { + SetXMSHandle(handle); + mem_writed(data+0x04,pages*1024); + mem_writed(data+0x08,handle); + mem_writed(data+0x0C,linadr); + DPMI_CALLBACK_SCF(false); + XMS_UnlockMemory(handle); + DPMI_LOG("DPMI: 0D00: Allocation shared success (%d KB)",pages*1024); + break; + } + } + DPMI_LOG_ERROR("DPMI: 0D00: Allocation shared failure (%d KB)",pages*1024); + reg_ax = DPMI_ERROR_PHYSICAL_MEMORY_UNAVAILABLE; + DPMI_CALLBACK_SCF(true); + }; break; + case 0x0B00:// Set debug watchpoint + case 0x0B01:// Clear debug watchpoint + DPMI_CALLBACK_SCF(true); + break; + case 0x0E00:// Get Coprocessor Status + reg_ax = 0x45; // nope, no coprocessor + DPMI_CALLBACK_SCF(false); + break; + case 0x0E01:// Set Coprocessor Emulation + DPMI_CALLBACK_SCF(true); // failure + break; + default :E_Exit("DPMI: Unsupported func %04X",reg_ax); + }; + return 0; +} + +Bitu DPMI::Int2fHandler(void) +{ + // Only available in ProtectedMode + //LOG(LOG_MISC,LOG_WARN)("DPMI: 0x2F %04x",reg_ax); + switch (reg_ax) { + case 0x1686: /* Get CPU Mode */ + reg_ax = 0; + break; + case 0x168A: // Only available in protected mode + // Get Vendor-Specific API Entry Point + char name[256]; + MEM_StrCopy(SegPhys(ds)+reg_esi,name,255); + LOG(LOG_MISC,LOG_WARN)("DPMI: 0x2F 0x168A: Get Specific API :%s",name); + if (strcmp(name,"MS-DOS")==0) { + CPU_SetSegGeneral(es,GDT_PROTCODE); + reg_edi = DPMI_CB_APIMSDOSENTRY_OFFSET; + reg_al = 0x00; // Success, whatever they want... + API_Init_MSDOS(); + }; + break; + default : // reflect to real + ptorHandler(); + break; + } + return 0; +}; + +// ********************************************************************* +// Callbacks and Callback-Returns +// ********************************************************************* + +static Bitu DPMI_ExceptionReturn(void) { return activeDPMI->ExceptionReturn(); }; +static Bitu DPMI_RealModeCallback(void) { return activeDPMI->RealModeCallback(); }; +static Bitu DPMI_RealModeCallbackReturn(void) { return activeDPMI->RealModeCallbackReturn(); }; +static Bitu DPMI_CallRealIRETFrame(void) { return activeDPMI->CallRealIRETFrame(); }; +static Bitu DPMI_CallRealIRETFrameReturn(void) { return activeDPMI->CallRealIRETFrameReturn(); }; +static Bitu DPMI_SimulateInt(void) { return activeDPMI->SimulateInt(); }; +static Bitu DPMI_SimulateIntReturn(void) { return activeDPMI->SimulateIntReturn(); }; +static Bitu DPMI_ptorHandler(void) { return activeDPMI->ptorHandler(); }; +static Bitu DPMI_ptorHandlerReturn(void) { return activeDPMI->ptorHandlerReturn(); }; +static Bitu DPMI_Int21Handler(void) { return activeDPMI->Int21Handler(); }; +static Bitu DPMI_Int21HandlerReturn(void) { return activeDPMI->Int21HandlerReturn(); }; +static Bitu DPMI_HWIntDefaultHandler(void) { return activeDPMI->HWIntDefaultHandler(); }; +static Bitu DPMI_EnterProtMode(void) { return activeDPMI->EnterProtMode(); }; +static Bitu DPMI_EnterRealMode(void) { return activeDPMI->EnterRealMode(); }; +static Bitu DPMI_RealSaveState(void) { return activeDPMI->RealSaveState(); }; +static Bitu DPMI_ProtSaveState(void) { return activeDPMI->ProtSaveState(); }; +static Bitu DPMI_Int2fHandler(void) { return activeDPMI->Int2fHandler(); }; +static Bitu DPMI_Int31Handler(void) { return activeDPMI->Int31Handler(); }; +static Bitu DPMI_API_Int21_MSDOS(void) { return activeDPMI->API_Int21_MSDOS(); }; +static Bitu DPMI_API_Entry_MSDOS(void) { return activeDPMI->API_Entry_MSDOS(); }; + + +// **************************************************************** +// Setup stuff +// **************************************************************** + +RealPt DPMI::HookInterrupt(Bitu num, Bitu intHandler) +{ + // Setup realmode hook + RealPt oldVec; + Bitu segment, offset; + // Allocate Realmode callback + RealPt func = CALLBACK_RealPointer(intHandler); + if (AllocateRealModeCallback(GDT_CODE,RealOff(func),0x0000,0x0000,segment,offset)) { + oldVec = RealGetVec(num); + RealSetVec(num,RealMake(segment,offset)); + } else E_Exit("DPMI: Couldnt allocate Realmode-Callback for INT %04X",num); + // Setup protmode hook + func = CALLBACK_RealPointer(intHandler); + SetDescriptor gate; + gate.Load (dpmi.idt.base+num*8); + gate.SetSelector(GDT_CODE); + gate.SetOffset (RealOff(func)); + gate.Save (dpmi.idt.base+num*8); + return oldVec; +} + +void DPMI::RestoreHookedInterrupt(Bitu num, RealPt oldVec) +{ + //.Restore hooked int + RealSetVec(num,oldVec); + RealPt func = CALLBACK_RealPointer(callback.ptorint); + SetDescriptor gate; + gate.Load (dpmi.idt.base+num*8); + gate.SetSelector(GDT_CODE); + gate.SetOffset (RealOff(func)); + gate.Save (dpmi.idt.base+num*8); +} + +void DPMI::Terminate(void) +{ + Bitu i; + cpu.cpl = 0; + dpmi.client.have = false; + // 1. Clear the LDT + for (i=0; iRemoveIntCallbacks(); + } + activeDPMI = new DPMI(); + return activeDPMI->Entrypoint(); +} + +Bitu DPMI::Entrypoint(void) +{ + /* This should switch to pmode */ + if (dpmi.client.have) E_Exit("DPMI:Already have a client"); + + LOG(LOG_MISC,LOG_ERROR)("DPMI: Entrypoint (%d Bit)",(reg_ax & 1) ? 32:16); + + // Create gdt, ldt, idt and other stuff + Setup(); + + // Save Realmode Registers + SaveRegisterState(0); + + dpmi.client.have = true; + dpmi.client.bit32 = reg_ax & 1; + + // Clear XMS Handles + ClearXMSHandles(); + /* Clear the LDT */ + Bitu i; + for (i=0;i> 10,dpmi.xms_handle)) { + LOG_MSG("DPMI:Can't allocate XMS memory, disabling dpmi support."); + return; + } + // Allocate real mode stack space + rm_ss = DOS_GetMemory(DPMI_REALMODE_STACKSIZE/16); + rm_sp = DPMI_REALMODE_STACKSIZE; + /* Allocate the GDT,LDT,IDT Stack space */ + Bit32u address; + XMS_LockMemory(dpmi.xms_handle,address); + // Get Begin of protected mode stack + dpmi.protStack = address + xmssize; + /* Clear the memory */ + PhysPt w; + for (w=address;w0xFFFFF) || (base & 0x0F)) E_Exit("DPMI:MSDOS: Invalid Selector (convert to segment not possible)"); + base >>= 4; + } else E_Exit("DPMI:MSDOS: Invalid Selector (not found)"); + return base; +}; + +bool DPMI::GetMsdosSelector(Bitu realseg, Bitu realoff, Bitu &protsel, Bitu &protoff) +{ + if (AllocateLDTDescriptor(1,protsel)) { + SetDescriptor desc; + desc.Load (dpmi.ldt.base+(protsel & ~7)); + desc.SetBase (realseg<<4); + desc.SetLimit (0xFFFF); + desc.Save (dpmi.ldt.base+(protsel & ~7)); + } else E_Exit("DPMI:MSDOS: No more selectors."); + protoff = realoff; + return true; +}; + +void DPMI::API_Init_MSDOS(void) +{ + // Enable special Int 21 Handler.... + RealPt func = CALLBACK_RealPointer(callback.int21msdos); + SetDescriptor gate; + gate.Load (dpmi.idt.base+0x21*8); + gate.SetSelector(GDT_CODE); + gate.SetOffset (RealOff(func)); + gate.Save (dpmi.idt.base+0x21*8); +}; + +Bitu DPMI::API_Entry_MSDOS(void) +{ + LOG(LOG_MISC,LOG_WARN)("DPMI: MSDOS Extension API Entry."); + switch (reg_ax) { + case 0x0000:// Get MS-DOS Extension Version + reg_ax = 0x0000; + SETFLAGBIT(CF,false); + break; + case 0x0100:// Get Selector to Base of LDT + // Note that the DPMI host has the option of either failing + // this call, or to return a read-only descriptor (we fail it). + SETFLAGBIT(CF,true); + break; + default: SETFLAGBIT(CF,true); + LOG(LOG_MISC,LOG_ERROR)("DPMI:MSDOS-API:Unknown ax on entry point %04X.",reg_ax); + break; + } + return 0; +}; + +Bitu DPMI::API_Int21_MSDOS(void) +{ +// LOG(LOG_MISC,LOG_ERROR)("DPMI:MSDOS:INT 21 %04X",reg_ax); + Bitu protsel,protoff,seg,off; + Bitu sax = reg_ax; + switch (reg_ah) { + + case 0x1a: /* Set Disk Transfer Area Address */ + LOG(LOG_MISC,LOG_ERROR)("DPMI:MSDOS:Set DTA not supported"); + dtaAddress = SegPhys(ds) + reg_edx; + break; + case 0x25: { // Set Protected mode Interrupt Vector + if (dpmi.pharlap) { + //LOG(LOG_MISC,LOG_ERROR) + switch (reg_al) { + + case 0x05: // Set Real mode Int Vector + RealSetVec(reg_cl,reg_ebx); + DPMI_CALLBACK_SCF(false); + break; + + default : E_Exit("DPMI:PHARLAP:System call %04X",reg_ax); + }; + + } else { + // ms dos api + SetDescriptor gate; + gate.Clear(); + gate.saved.seg.p=1; + gate.SetSelector(SegValue(ds)); + gate.SetOffset (reg_edx); + gate.SetType (dpmi.client.bit32?DESC_386_INT_GATE:DESC_286_INT_GATE); + gate.saved.seg.dpl = DPMI_DPL; + gate.Save(dpmi.idt.base+reg_al*8); + } + }; break; + case 0x35: { // Get Protected Mode Interrupt Vector + SetDescriptor gate; + gate.Load(dpmi.idt.base+reg_al*8); + CPU_SetSegGeneral(es,gate.GetSelector()); + reg_ebx = gate.GetOffset(); + DPMI_CALLBACK_SCF(false); + }; break; + + case 0x2f: /* Get Disk Transfer Area */ + seg = RealSeg(dos.dta); + off = RealOff(dos.dta); + GetMsdosSelector(seg,off,protsel,protoff); + CPU_SetSegGeneral(es,protsel); + reg_ebx = protoff; + break; + + case 0x34 : // Get INDOS Flag address + seg = RealSeg(dos.tables.indosflag); + off = RealOff(dos.tables.indosflag); + GetMsdosSelector(seg,off,protsel,protoff); + CPU_SetSegGeneral(es,protsel); + reg_bx = protoff; + break; + case 0x3c: { /* CREATE Create of truncate file */ + char name1[256]; + MEM_StrCopy(SegPhys(ds)+reg_edx,name1,255); + if (DOS_CreateFile(name1,reg_cx,®_ax)) { + DPMI_CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + DPMI_CALLBACK_SCF(true); + } + }; break; + case 0x3d: { /* OPEN Open existing file */ + char name1[256]; + MEM_StrCopy(SegPhys(ds)+reg_edx,name1,255); + if (DOS_OpenFile(name1,reg_al,®_ax)) { + LOG(LOG_MISC,LOG_ERROR)("DOS: Open success; %s",name1); + DPMI_CALLBACK_SCF(false); + } else { + LOG(LOG_MISC,LOG_ERROR)("DOS: Open failure; %s",name1); + reg_ax=dos.errorcode; + DPMI_CALLBACK_SCF(true); + } + };break; + case 0x3f: /* READ Read from file or device */ + { + if (reg_ecx>0xFFFF) { + E_Exit("DPMI:DOS: Read file size > 0xffff"); + }; + + Bit16u toread = reg_ecx; + dos.echo = true; + if (DOS_ReadFile(reg_bx,dos_copybuf,&toread)) { + MEM_BlockWrite(SegPhys(ds)+reg_edx,dos_copybuf,toread); + reg_eax=toread; + DPMI_CALLBACK_SCF(false); + + } else { + reg_ax=dos.errorcode; + DPMI_CALLBACK_SCF(true); + } + dos.echo=false; + break; + } + case 0x40: {/* WRITE Write to file or device */ + Bit16u towrite = reg_ecx; + MEM_BlockRead(SegPhys(ds)+reg_edx,dos_copybuf,towrite); + if (DOS_WriteFile(reg_bx,dos_copybuf,&towrite)) { + reg_eax=towrite; + DPMI_CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + DPMI_CALLBACK_SCF(true); + } + }; break; + case 0x41: { /* UNLINK Delete file */ + char name1[256]; + MEM_StrCopy(SegPhys(ds)+reg_edx,name1,255); + if (DOS_UnlinkFile(name1)) { + DPMI_CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + DPMI_CALLBACK_SCF(true); + } + }; break; + case 0x42: /* LSEEK Set current file position */ + { + Bit32u pos=(reg_cx<<16) + reg_dx; + if (DOS_SeekFile(reg_bx,&pos,reg_al)) { + reg_dx=(Bit16u)(pos >> 16); + reg_ax=(Bit16u)(pos & 0xFFFF); + DPMI_CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + DPMI_CALLBACK_SCF(true); + } + break; + } + case 0x43: { /* Get/Set file attributes */ + char name1[256]; + MEM_StrCopy(SegPhys(ds)+reg_edx,name1,255); + switch (reg_al) + case 0x00: /* Get */ + { + if (DOS_GetFileAttr(name1,®_cx)) { + DPMI_CALLBACK_SCF(false); + } else { + DPMI_CALLBACK_SCF(true); + reg_ax=dos.errorcode; + } + break; + case 0x01: /* Set */ + LOG(LOG_MISC,LOG_ERROR)("DOS:Set File Attributes for %s not supported",name1); + DPMI_CALLBACK_SCF(false); + break; + default: + E_Exit("DOS:0x43:Illegal subfunction %2X",reg_al); + } + }; break; + + case 0x4E: {/* Get first dir entry */ + char name1[256]; + MEM_StrCopy(SegPhys(ds)+reg_edx,name1,255); + if (DOS_FindFirst(name1,reg_cx)) { + DPMI_CALLBACK_SCF(false); + // Copy result to internal dta + if (dtaAddress) MEM_BlockCopy(dtaAddress,PhysMake(RealSeg(dos.dta),RealOff(dos.dta)),dpmi.pharlap?43:128); + reg_ax=0; /* Undocumented */ + } else { + reg_ax=dos.errorcode; + DPMI_CALLBACK_SCF(true); + }; + }; break; + case 0x4f: /* FINDNEXT Find next matching file */ + // Copy data to dos dta + if (dtaAddress) MEM_BlockCopy(PhysMake(RealSeg(dos.dta),RealOff(dos.dta)),dtaAddress,dpmi.pharlap?43:128); + if (DOS_FindNext()) { + CALLBACK_SCF(false); + // Copy result to internal dta + if (dtaAddress) MEM_BlockCopy(dtaAddress,PhysMake(RealSeg(dos.dta),RealOff(dos.dta)),dpmi.pharlap?43:128); + reg_ax=0xffff; /* Undocumented */ + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + }; + break; + case 0x50: /* Set current PSP */ + if (dpmi.pharlap) dos.psp = reg_bx; // pharlap uses real mode paragraph address + else + dos.psp = GetSegmentFromSelector(reg_bx); + LOG(LOG_MISC,LOG_ERROR)("DPMI:MSDOS:0x50:Set current psp:%04X",reg_bx); + break; + case 0x51: /* Get current PSP */ + if (dpmi.pharlap) reg_bx = dos.psp; // pharlap uses real mode paragraph address + else { + GetMsdosSelector(dos.psp,0x0000,protsel,protoff); + reg_bx = protsel; + }; + LOG(LOG_MISC,LOG_ERROR)("DPMI:MSDOS:0x51:Get current psp:%04X",reg_bx); + break; + case 0x55 : { // Neuen PSP erstellen + Bitu segment = GetSegmentFromSelector(reg_dx); + DOS_ChildPSP(segment,reg_si); + dos.psp = segment; + DPMI_CALLBACK_SCF(false); + LOG(LOG_MISC,LOG_ERROR)("DPMI:MSDOS:0x55:Create new psp:%04X",segment); + }; break; + case 0x5D : // Get Address of dos swappable area + // FIXME: This is totally faked... + // FIXME: Add size in bytes (at least pharlap) + // FIXME: Depending on al, two functions (pharlap) + GetMsdosSelector(0xDEAD,0xDEAD,protsel,protoff); + CPU_SetSegGeneral(ds,protsel); + reg_si = protoff; + LOG(LOG_MISC,LOG_ERROR)("DPMI:MSDOS:0x5D:Get Addres of DOS SwapArea:%04X",reg_si); + break; + case 0x62 : /* Get Current PSP Address */ + GetMsdosSelector(dos.psp,0x0000,protsel,protoff); + reg_bx = protsel; + LOG(LOG_MISC,LOG_ERROR)("DPMI:MSDOS:0x62:Get current psp:%04X",reg_bx); + break; + + case 0x09: + case 0x0A: + case 0x0C: + case 0x1B: + case 0x1C: + case 0x26: // Pharlap != MS-DOS +// case 0x30: // Pharlap extended information + case 0x31: + case 0x32: + case 0x38: + case 0x3A: + case 0x3B: + case 0x47: + case 0x48: // Pharlap = 4KB mem pages + case 0x49: + case 0x4A: // Pharlap = 4KB mem pages + case 0x4B: + case 0x52: + case 0x53: + case 0x56: + case 0x59: + case 0x5A: + case 0x5B: + case 0x5E: + case 0x5F: + case 0x60: +// case 0x62: + case 0x65: + case 0x6C: + E_Exit("DPMI:MSDOS-API:function %04X not yet supported.",reg_ax); + break; + + // *** PASS THROUGH *** + case 0x44: if ((reg_al==0x02) || (reg_al==0x03) || (reg_al==0x04) || (reg_al==0x05) || (reg_al==0x0C) || (reg_al==0x0D)) { + E_Exit("DPMI:MSDOS-API:function %04X not yet supported.",reg_ax); + }; + case 0x0E: case 0x19: case 0x2A: case 0x2C: case 0x2D: case 0x30: case 0x36: + case 0x3E: case 0x4C: case 0x58: case 0x67: + { + // reflect top real mode + DPMI_Int21Handler(); + }; + break; + default: E_Exit("DPMI:MSDOS-API:Missing function %04X",reg_ax); + + }; + return 0; +}; -} \ No newline at end of file From 2b61bd2759336be61f4e3d4a537d83c21aba275e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Jul 2003 13:07:16 +0000 Subject: [PATCH 1004/4131] Initial version of modem and serial port Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1084 --- include/serialport.h | 135 ++++++++ src/hardware/serialport.cpp | 441 +++++++++++++++++++++++++ src/hardware/softmodem.cpp | 635 ++++++++++++++++++++++++++++++++++++ 3 files changed, 1211 insertions(+) create mode 100644 include/serialport.h create mode 100644 src/hardware/serialport.cpp create mode 100644 src/hardware/softmodem.cpp diff --git a/include/serialport.h b/include/serialport.h new file mode 100644 index 00000000..9f08303a --- /dev/null +++ b/include/serialport.h @@ -0,0 +1,135 @@ +/* + * 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. + */ + +#if !defined __SERIALPORT_H +#define __SERIALPORT_H + +#include + +//If it's too high you overflow terminal clients buffers i think +#define FIFO_SIZE (1024) + +// Serial port interface // + +#define M_CTS 0x01 +#define M_DSR 0x02 +#define M_RI 0x04 +#define M_DCD 0x08 + +enum INT_TYPES { + INT_MS, + INT_TX, + INT_RX, + INT_RX_FIFO, + INT_LS, + INT_NONE, +}; + +typedef void MControl_Handler(Bitu mc); + +class CSerial { +public: + + // Constructor takes base port (0x3f0, 0x2f0, 0x2e0, etc.), IRQ, and initial bps // + CSerial (Bit16u initbase, Bit8u initirq, Bit32u initbps); + virtual ~CSerial(); + + // External port functions for IOHandlers // + void write_port(Bit32u port, Bit8u val); + Bit8u read_port(Bit32u port); + + static void write_serial(Bit32u port,Bit8u val); + static Bit8u read_serial(Bit32u port); + + void SetMCHandler(MControl_Handler * mcontrol); + + /* Allow the modem to change the modem status bits */ + void setmodemstatus(Bit8u status); + Bit8u getmodemstatus(void); + Bit8u getlinestatus(void); + + void checkint(void); + void raiseint(INT_TYPES type); + void lowerint(INT_TYPES type); + + /* Access to the receive fifo */ + Bitu rx_free(); + void rx_addb(Bit8u byte); + void rx_adds(Bit8u * data,Bitu size); + Bitu rx_size(); + Bit8u rx_readb(void); + + /* Access to the transmit fifo */ + Bitu tx_free(); + void tx_addb(Bit8u byte); + Bitu tx_size(); + Bit8u tx_readb(void); + + + // These variables maintain the status of the serial port + Bit16u base; + Bit16u irq; + Bit32u bps; + + bool FIFOenabled; + Bit16u FIFOsize; + +private: + + void setdivisor(Bit8u dmsb, Bit8u dlsb); + void checkforirq(void); + struct { + Bitu used; + Bitu pos; + Bit8u data[FIFO_SIZE]; + } rx_fifo,tx_fifo; + struct { + Bitu requested; + Bitu enabled; + INT_TYPES active; + } ints; + + Bitu rx_lastread; + Bit8u irq_pending; + + Bit8u scratch; + Bit8u dlab; + Bit8u divisor_lsb; + Bit8u divisor_msb; + Bit8u wordlen; + Bit8u dtr; + Bit8u rts; + Bit8u out1; + Bit8u out2; + Bit8u local_loopback; + Bit8u linectrl; + Bit8u intid; + Bit8u ierval; + Bit8u mstatus; + + Bit8u txval; + Bit8u timeout; + + MControl_Handler * mc_handler; + char remotestr[4096]; +}; + +// This function returns the CSerial objects for ports 1-4 // +CSerial *getComport(Bitu portnum); + +#endif \ No newline at end of file diff --git a/src/hardware/serialport.cpp b/src/hardware/serialport.cpp new file mode 100644 index 00000000..eb040151 --- /dev/null +++ b/src/hardware/serialport.cpp @@ -0,0 +1,441 @@ +/* + * 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. + */ + +#include +#include "sdl_syswm.h" + +#include "dosbox.h" +#include "inout.h" +#include "mixer.h" +#include "pic.h" +#include "setup.h" +#include "timer.h" +#include "math.h" +#include "regs.h" +#include "serialport.h" + +#define SERIALBASERATE 115200 +#define SERIALPORT_COUNT 2 + +#define LOG_UART LOG_MSG +CSerial *serialports[SERIALPORT_COUNT]; + + +void CSerial::setdivisor(Bit8u dmsb, Bit8u dlsb) { + Bitu divsize=(dmsb << 8) | dlsb; + if (divsize!=0) { + bps = SERIALBASERATE / divsize; + } +} + + +void CSerial::checkint(void) { + /* Find lowest priority interrupt to activate */ + Bitu i; + for (i=0;i> 6) { + case 0: + FIFOsize = 1; + break; + case 1: + FIFOsize = 4; + break; + case 2: + FIFOsize = 8; + break; + case 3: + FIFOsize = 14; + break; + } + break; + case 0xb: // Line control register + linectrl = val; + wordlen = (val & 0x3); + dlab = (val & 0x80) > 0; + break; + case 0xc: // Modem control register + dtr = val & 0x01; + rts = (val & 0x02) > 0 ; + out1 = (val & 0x04) > 0; + out2 = (val & 0x08) > 0; + if (mc_handler) (*mc_handler)(val & 0xf); + local_loopback = (val & 0x10) > 0; + break; + case 0xf: // Scratch register + scratch = val; + break; + default: + LOG_UART("Modem: Write to 0x%x, with 0x%x '%c'\n", port,val,val); + break; + } +} + +void CSerial::write_serial(Bit32u port, Bit8u val) { + int i; + + for(i=0;i=serialports[i]->base+0x8) && (port<=(serialports[i]->base+0xf)) ) { + serialports[i]->write_port(port,val); + } + } +} + +Bit8u CSerial::read_port(Bit32u port) { + Bit8u outval = 0; + + port-=base; +// LOG_MSG("Serial read form %X",port); + switch(port) { + case 0x8: // Receive buffer + Divisor LSB + if (dlab) { + return divisor_lsb ; + } else { + outval = rx_readb(); +// LOG_UART("Read from %X %X %c remain %d",port,outval,outval,rx_fifo.used); + return outval; + } + case 0x9: // Interrupt enable register + Divisor MSB + if (dlab) { + return divisor_msb ; + } else { +// LOG_UART("Read from %X %X",port,ierval); + return ierval; + } + case 0xa: // Interrupt identification register + switch (ints.active) { + case INT_MS: + outval = 0x0; + break; + case INT_TX: + outval = 0x2; + lowerint(INT_TX); + goto skipreset; + case INT_RX: + outval = 0x4; + break; + case INT_RX_FIFO: + lowerint(INT_RX_FIFO); + outval = 0xc; + goto skipreset; + case INT_LS: + outval = 0x6; + break; + case INT_NONE: + outval = 0x1; + break; + } + ints.active=INT_NONE; +skipreset: + if (FIFOenabled) outval |= 3 << 6; +// LOG_UART("Read from %X %X",port,outval); + return outval; + case 0xb: // Line control register + LOG_UART("Read from %X %X",port,outval); + return linectrl; + case 0xC: // Modem control register + outval = dtr | (rts << 1) | (out1 << 2) | (out2 << 3) | (local_loopback << 4); +// LOG_UART("Read from %X %X",port,outval); + return outval; + case 0xD: // Line status register + lowerint(INT_LS); + outval = 0x40; + if (FIFOenabled) { + if (!tx_fifo.used) outval|=0x20; + } else if (tx_fifo.used=serialports[i]->base+0x8) && (port<=(serialports[i]->base+0xf)) ) { + return serialports[i]->read_port(port); + } + } + return 0x00; +} + +Bitu CSerial::rx_free() { + return FIFO_SIZE-rx_fifo.used; +} + +Bitu CSerial::tx_free() { + return FIFO_SIZE-tx_fifo.used; +} + +Bitu CSerial::tx_size() { + if (FIFOenabled && rx_fifo.used && (rx_lastread < (PIC_Ticks-2))) { + raiseint(INT_RX_FIFO); + } + return tx_fifo.used; +} + +Bitu CSerial::rx_size() { + return rx_fifo.used; +} + +void CSerial::rx_addb(Bit8u data) { + LOG_UART("RX add %c",data); + if (rx_fifo.used=FIFO_SIZE) where-=FIFO_SIZE; + rx_fifo.data[where]=data; + rx_fifo.used++; + if (FIFOenabled && (rx_fifo.used < FIFOsize)) return; + /* Raise rx irq if possible */ + if (ints.active != INT_RX) raiseint(INT_RX); + } +} + +void CSerial::rx_adds(Bit8u * data,Bitu size) { + if ((rx_fifo.used+size)<=FIFO_SIZE) { + Bitu where=rx_fifo.pos+rx_fifo.used; + rx_fifo.used+=size; + while (size--) { + if (where>=FIFO_SIZE) where-=FIFO_SIZE; + rx_fifo.data[where++]=*data++; + } + if (FIFOenabled && (rx_fifo.used < FIFOsize)) return; + if (ints.active != INT_RX) raiseint(INT_RX); + } else LOG_MSG("WTF"); +} + +void CSerial::tx_addb(Bit8u data) { + LOG_UART("TX add %c",data); + if (tx_fifo.used=FIFO_SIZE) where-=FIFO_SIZE; + tx_fifo.data[where]=data; + tx_fifo.used++; + if (tx_fifo.used<(FIFO_SIZE-16)) { + /* Only generate FIFO irq's every 16 bytes */ + if (FIFOenabled && (tx_fifo.used & 0xf)) return; + raiseint(INT_TX); + } + } else { + LOG_MSG("tx addb"); + } +} + +Bit8u CSerial::rx_readb() { + if (rx_fifo.used) { + rx_lastread=PIC_Ticks; + Bit8u val=rx_fifo.data[rx_fifo.pos]; + rx_fifo.pos++; + if (rx_fifo.pos>=FIFO_SIZE) rx_fifo.pos-=FIFO_SIZE; + rx_fifo.used--; + //Don't care for FIFO Size + if (FIFOenabled || !rx_fifo.used) lowerint(INT_RX); + else raiseint(INT_RX); + return val; + } else { + LOG_MSG("WTF rx readb"); + return 0; + } +} + +Bit8u CSerial::tx_readb() { + if (tx_fifo.used) { + Bit8u val=tx_fifo.data[tx_fifo.pos]; + tx_fifo.pos++; + if (tx_fifo.pos>=FIFO_SIZE) tx_fifo.pos-=FIFO_SIZE; + tx_fifo.used--; + if (FIFOenabled && !tx_fifo.used) raiseint(INT_TX); + return val; + } else { + LOG_MSG("WTF tx readb"); + return 0; + } +} + + +void CSerial::setmodemstatus(Bit8u status) { + Bitu oldstatus=mstatus >> 4; + if(oldstatus ^ status ) { + mstatus=status << 4; + mstatus|=(oldstatus ^ status); + raiseint(INT_MS); + } +} + +Bit8u CSerial::getmodemstatus() { + return (mstatus >> 4); +} + +Bit8u CSerial::getlinestatus() { + return read_port(0xd); +} + + +void CSerial::SetMCHandler(MControl_Handler * mcontrol) { + mc_handler=mcontrol; +} + +CSerial::CSerial (Bit16u initbase, Bit8u initirq, Bit32u initbps) { + + int i; + Bit16u initdiv; + + base=initbase; + irq=initirq; + bps=initbps; + + mc_handler = 0; + tx_fifo.used = tx_fifo.pos = 0; + rx_fifo.used = rx_fifo.pos = 0; + + rx_lastread = PIC_Ticks; + linectrl = dtr = rts = out1 = out2 = 0; + local_loopback = 0; + ierval = 0; + ints.enabled=1 << INT_RX_FIFO; + ints.active=INT_NONE; + ints.requested=0; + + FIFOenabled = false; + FIFOsize = 1; + timeout = 0; + dlab = 0; + ierval = 0; + + initdiv = SERIALBASERATE / bps; + setdivisor(initdiv >> 8, initdiv & 0x0f); + + for (i=8;i<=0xf;i++) { + + IO_RegisterWriteHandler(initbase+i,write_serial,"Serial Port"); + IO_RegisterReadHandler(initbase+i,read_serial,"Serial Port"); + } + + PIC_RegisterIRQ(irq,0,"SERIAL"); + + +}; + +CSerial::~CSerial(void) +{ + +}; + + + +CSerial *getComport(Bitu portnum) +{ + return serialports[portnum-1]; +} + +void SERIAL_Init(Section* sec) { + + unsigned long args = 1; + Section_prop * section=static_cast(sec); + +// if(!section->Get_bool("enabled")) return; + + serialports[0] = new CSerial(0x3f0,4,SERIALBASERATE); + serialports[1] = new CSerial(0x2f0,3,SERIALBASERATE); +} diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp new file mode 100644 index 00000000..dcdf449d --- /dev/null +++ b/src/hardware/softmodem.cpp @@ -0,0 +1,635 @@ +/* + * 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. + */ + +#include +#include "sdl_net.h" + + +#include "dosbox.h" +#include "inout.h" +#include "mixer.h" +#include "dma.h" +#include "pic.h" +#include "hardware.h" +#include "setup.h" +#include "programs.h" +#include "debug.h" +#include "timer.h" +#include "callback.h" +#include "math.h" +#include "regs.h" +#include "serialport.h" + +#define MODEMSPD 57600 +#define CONNECTED (M_CTS | M_DSR | M_DCD ) +#define DISCONNECTED (M_CTS | M_DSR ) + + +/* DTMF tone generator */ +float col[] = { 1209.0, 1336.0, 1477.0, 1633.0 }; +float row[] = { 697.0, 770.0, 852.0, 941.0 }; +char positions[] = "123A456B789C*0#D"; +#define duration 1000 +#define pause 400 + +static Bit8u tmpbuf[FIFO_SIZE+1]; + +struct ModemHd { + char cmdbuf[FIFO_SIZE]; + bool commandmode; + bool cantrans; + bool incomingcall; + bool autoanswer; + bool echo; + Bitu cmdpause; + Bits ringcounter; + Bit16u plusinc; + Bit16u cmdpos; + + + TCPsocket socket; + TCPsocket listensocket; + SDLNet_SocketSet socketset; + + IPaddress openip; + + Bitu comport; + Bitu listenport; + + char remotestr[4096]; + + bool dialing; + float f1, f2; + Bitu diallen; + Bitu dialpos; + char dialstr[256]; + MIXER_Channel * chan; +}; + +static CSerial * mdm; +static ModemHd mhd; + +static void sendStr(const char *usestr) { + if (!mhd.echo) return; + Bitu i=0; + while (*usestr != 0) { + if (*usestr == 10) { + mdm->rx_addb(0xd); + mdm->rx_addb(0xa); + } else { + mdm->rx_addb((Bit8u)*usestr); + } + usestr++; + } +} + +static void sendOK() { + sendStr("\nOK\n"); +} + +static void sendError() { + sendStr("\nERROR\n"); +} + +static void toUpcase(char *buffer) { + Bitu i=0; + while (buffer[i] != 0) { + buffer[i] = toupper(buffer[i]); + i++; + } +} + +static void openConnection() { + if (mhd.socket) { + LOG_MSG("Huh? already connected"); + SDLNet_TCP_DelSocket(mhd.socketset,mhd.socket); + SDLNet_TCP_Close(mhd.socket); + } + mhd.socket = SDLNet_TCP_Open(&mhd.openip); + if (mhd.socket) { + SDLNet_TCP_AddSocket(mhd.socketset,mhd.socket); + sendStr("\nCONNECT 57600\n"); + mhd.commandmode = false; + mdm->setmodemstatus(CONNECTED); + } else { + sendStr("\nNO DIALTONE\n"); + } +} + +static bool Dial(char * host) { + + /* Scan host for port */ + Bit16u port; + char * hasport=strrchr(host,':'); + if (hasport) { + *hasport++=0; + port=(Bit16u)atoi(hasport); + } else port=23; + /* Resolve host we're gonna dial */ + LOG_MSG("host %s port %x",host,port); + if (!SDLNet_ResolveHost(&mhd.openip,host,port)) { + /* Prepare string for dial sound generator */ + int c; + char *addrptr=host; + mhd.dialstr[0] = 'd'; + mhd.dialstr[1] = 'd'; + mhd.dialstr[2] = 'd'; + mhd.dialstr[3] = 'd'; + mhd.dialstr[4] = 'd'; + mhd.dialstr[5] = 'p'; + c=6; + while(*addrptr != 0x00) { + if (strchr(positions, *addrptr)) { + mhd.dialstr[c] = *addrptr; + c++; + } + addrptr++; + } + mhd.dialstr[c] = 0x00; + + mhd.diallen = strlen(mhd.dialstr) * (Bit32u)(duration + pause); + mhd.dialpos = 0; + mhd.f1 = 0; + mhd.f2 = 0; + mhd.dialing = true; + MIXER_Enable(mhd.chan,true); + return true; + } else { + LOG_MSG("Failed to resolve host %s:%s",host,SDLNet_GetError()); + sendStr("\nNO CARRIER\n"); + return false; + } +} + + +static void DoCommand() { + bool found = false; + bool foundat = false; + char *foundstr; + bool connResult = false; + char msgbuf[4096]; + + Bitu result; + mhd.cmdbuf[mhd.cmdpos] = 0; + toUpcase(mhd.cmdbuf); + LOG_MSG("Modem Sent Command: %s\n", mhd.cmdbuf); + mhd.cmdpos = 0; + + result = 0; + + + /* Just for kicks */ + if ((mhd.cmdbuf[0] == 'A') && (mhd.cmdbuf[1] == 'T')) foundat = true; + if (foundat) { + if (strstr(mhd.cmdbuf,"I3")) { + sendStr("\nDosBox Emulated Modem Firmware V1.00\n"); + result = 1; + } + if (strstr(mhd.cmdbuf,"I4")) { + sprintf(msgbuf, "\nModem compiled for DosBox version %s\n", VERSION); + sendStr(msgbuf); + result = 1; + } + if (strstr(mhd.cmdbuf,"S0=1")) { + mhd.autoanswer = true; + } + if (strstr(mhd.cmdbuf,"S0=0")) { + mhd.autoanswer = false; + } + + if (strstr(mhd.cmdbuf,"E0")) { + mhd.echo = false; + } + if (strstr(mhd.cmdbuf,"E1")) { + mhd.echo = true; + } + + if (strstr(mhd.cmdbuf,"ATH")) { + /* Check if we're actually connected */ + if (mhd.socket) { + sendStr("\nNO CARRIER\n"); + SDLNet_TCP_DelSocket(mhd.socketset,mhd.socket); + SDLNet_TCP_Close(mhd.socket); + mhd.socket=0; + mdm->setmodemstatus(DISCONNECTED); + mhd.commandmode = true; + result = 3; + } else result = 2; + } + if(strstr(mhd.cmdbuf,"ATO")) { + /* Check for connection before switching to data mode */ + if (mhd.socket) { + mhd.commandmode = false; + result=3; + } else { + result=2; + } + } + if(strstr(mhd.cmdbuf,"ATDT")) { + foundstr = strstr(mhd.cmdbuf,"ATDT"); + foundstr+=4; + /* Small protection against empty line */ + if (!foundstr[0]) { + result=2; + } else { + connResult = Dial(foundstr); + result=3; + } + } + if(strstr(mhd.cmdbuf,"ATA")) { + if (mhd.incomingcall) { + sendStr("\nCONNECT 57600\n"); + LOG_MSG("Connected!\n"); + MIXER_Enable(mhd.chan,false); + mdm->setmodemstatus(CONNECTED); + mhd.incomingcall = false; + mhd.commandmode = false; + SDLNet_TCP_AddSocket(mhd.socketset,mhd.socket); + result = 3; + } else { + mhd.autoanswer = true; + result = 3; + } + } + if (result==0) result = 1; + } else result=2; + + if (strlen(mhd.cmdbuf)<2) { + if(!mhd.dialing) { + result = 0; + mhd.autoanswer = false; + } else { + MIXER_Enable(mhd.chan,false); + mhd.dialing = false; + sendStr("\nNO CARRIER\n"); + result = 0; + } + } + + switch (result) { + case 1: + sendOK(); + break; + case 2: + sendError(); + break; + } + +} + + +static void MC_Changed(Bitu new_mc) { + + +} + +static void MODEM_Hardware(Bitu ticks) { + int result =0; + unsigned long args = 1; + bool sendbyte = true; + Bitu usesize; + Bit8u txval; + + /* Check for eventual break command */ + if (!mhd.commandmode) mhd.cmdpause++; + /* Handle incoming data from serial port, read as much as available */ + Bitu tx_size=mdm->tx_size(); + while (tx_size--) { + txval = mdm->tx_readb(); + if (mhd.commandmode) { + if(txval != 0xd) { + if(txval == 0x8) { + if (mhd.cmdpos > 0) { + --mhd.cmdpos; + } + } else { + if (txval != '+') { + if(mhd.cmdposrx_addb(txval); + } else if (mhd.echo) { + mdm->rx_addb(10); + mdm->rx_addb(13); + } + } else { + DoCommand(); + } + } else { + /* 1000 ticks have passed, can check for pause command */ + if (mhd.cmdpause > 1000) { + if(txval == '+') { + mhd.plusinc++; + if(mhd.plusinc>=3) { + mhd.commandmode = true; + sendStr("\nOK\n"); + mhd.plusinc = 0; + } + sendbyte=false; + } else { + mhd.plusinc=0; + } +//If not a special pause command, should go for bigger blocks to send + } + + tmpbuf[0] = txval; + tmpbuf[1] = 0x0; + + if (mhd.socket && sendbyte) { + SDLNet_TCP_Send(mhd.socket, tmpbuf,1); + //TODO error testing + } + } + } + + SDLNet_CheckSockets(mhd.socketset,0); + /* Handle outgoing to the serial port */ + if(!mhd.commandmode && mhd.socket && mdm->rx_free() && SDLNet_SocketReady(mhd.socket)) { + usesize = mdm->rx_free(); + result = SDLNet_TCP_Recv(mhd.socket, tmpbuf, usesize); + if (result>0) { + mdm->rx_adds(tmpbuf,result); + mhd.cmdpause = 0; + } else { + /* Error close the socket and disconnect */ + mdm->setmodemstatus(DISCONNECTED); + mhd.commandmode = true; + sendStr("\nNO CARRIER\n"); + SDLNet_TCP_DelSocket(mhd.socketset,mhd.socket); + SDLNet_TCP_Close(mhd.socket); + mhd.socket=0; + } + } + + /* Check for incoming calls */ + if (!mhd.socket && !mhd.incomingcall && mhd.listensocket) { + mhd.socket = SDLNet_TCP_Accept(mhd.listensocket); + if (mhd.socket) { + mhd.dialpos = 0; + mhd.incomingcall = true; + mhd.diallen = 12000; + mhd.dialpos = 0; +//TODO Set ring in Modemstatus? + sendStr("\nRING\n"); + MIXER_Enable(mhd.chan,true); + mhd.ringcounter = 24000; + } + } + + if (mhd.incomingcall) { + if (mhd.ringcounter <= 0) { + if (mhd.autoanswer) { + mhd.incomingcall = false; + sendStr("\nCONNECT 57600\n"); + MIXER_Enable(mhd.chan,false); + mdm->setmodemstatus(CONNECTED); + mhd.incomingcall = false; + mhd.commandmode = false; + SDLNet_TCP_AddSocket(mhd.socketset,mhd.socket); + return; + } + sendStr("\nRING\n"); + mhd.diallen = 12000; + mhd.dialpos = 0; + + MIXER_Enable(mhd.chan,true); + + mhd.ringcounter = 3000; /* Ring every three seconds for accurate emulation */ + + } + if (mhd.ringcounter > 0) --mhd.ringcounter; + + } + +} + +/* +03F8 -W serial port, transmitter holding register (THR), which contains the + character to be sent. Bit 0 is sent first. + bit 7-0 data bits when DLAB=0 (Divisor Latch Access Bit) +03F8 R- receiver buffer register (RBR), which contains the received + character. Bit 0 is received first + bit 7-0 data bits when DLAB=0 (Divisor Latch Access Bit) +03F8 RW divisor latch low byte (DLL) when DLAB=1 (see #P0876) +03F9 RW divisor latch high byte (DLM) when DLAB=1 (see #P0876) +03F9 RW interrupt enable register (IER) when DLAB=0 (see #P0877) +03FA R- interrupt identification register (see #P0878) + Information about a pending interrupt is stored here. When the ID + register is addressed, thehighest priority interrupt is held, and + no other interrupts are acknowledged until the CPU services that + interrupt. +03FA -W 16650 FIFO Control Register (FCR) (see #P0879) +03FB RW line control register (LCR) (see #P0880) +03FC RW modem control register (see #P0881) +03FD R- line status register (LSR) (see #P0882) +03FE R- modem status register (MSR) (see #P0883) +03FF RW scratch register (SCR) + (not used for serial I/O; available to any application using 16450, + 16550) (not present on original 8250) +*/ + +static void MODEM_CallBack(Bit8u * stream,Bit32u len) { + char *cp; + float ci,ri; + Bit32u innum, splitnum, quad, eighth, sixth, amp; + Bit8u curchar; + Bit32s buflen = (Bit32s)len; + if(mhd.incomingcall) { + + if(mhd.dialpos>=mhd.diallen) { + MIXER_Enable(mhd.chan,false); + return; + } else { + quad = (mhd.diallen/14); + eighth = quad / 2; + sixth = eighth /2; + + while ((buflen>0) && (mhd.dialpos=mhd.diallen) { + while(len-->0) { + *(Bit16s*)(stream) = 0; + stream+=2; + } + MIXER_Enable(mhd.chan,false); + mhd.dialing = false; + openConnection(); + return; + } else { + + while ((buflen>0) && (mhd.dialpos(sec); + + if(!section->Get_bool("enabled")) return; + + if(SDLNet_Init()==-1) { + LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); + return; + } + + mhd.cmdpos = 0; + mhd.commandmode = true; + mhd.plusinc = 0; + mhd.cantrans = false; + mhd.incomingcall = false; + mhd.autoanswer = false; + mhd.cmdpause = 0; + mhd.echo = true; + + /* Bind the modem to the correct serial port */ + mhd.comport=section->Get_int("comport"); + strcpy(mhd.remotestr, section->Get_string("remote")); + mdm = getComport(mhd.comport); + mdm->setmodemstatus(DISCONNECTED); + mdm->SetMCHandler(&MC_Changed); + + TIMER_RegisterTickHandler(&MODEM_Hardware); + + /* Initialize the sockets and setup the listening port */ + mhd.socketset = SDLNet_AllocSocketSet(1); + if (!mhd.socketset) { + LOG_MSG("MODEM:Can't open socketset:%s",SDLNet_GetError()); +//TODO Should probably just exit + return; + } + mhd.socket=0; + mhd.listenport=section->Get_int("listenport"); + if (mhd.listenport) { + IPaddress listen_ip; + SDLNet_ResolveHost(&listen_ip, NULL, mhd.listenport); + mhd.listensocket=SDLNet_TCP_Open(&listen_ip); + if (!mhd.listensocket) LOG_MSG("MODEM:Can't open listen port:%s",SDLNet_GetError()); + } else mhd.listensocket=0; + + mhd.chan=MIXER_AddChannel(&MODEM_CallBack,8000,"MODEM"); + MIXER_Enable(mhd.chan,false); + MIXER_SetMode(mhd.chan,MIXER_16MONO); +} + + + From cbd33bfa95095b47f874bac55848bf9457918a41 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Jul 2003 13:08:18 +0000 Subject: [PATCH 1005/4131] Removed lazy flag stuff Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1085 --- include/cpu.h | 78 +++++--------------------------------------------- include/regs.h | 1 + 2 files changed, 8 insertions(+), 71 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 8f62abb8..4c266319 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -37,37 +37,6 @@ extern CPU_Decoder * cpudecoder; //CPU Stuff void SetCPU16bit( ); -//Types of Flag changing instructions -enum { - t_UNKNOWN=0, - t_ADDb,t_ADDw,t_ADDd, - t_ORb,t_ORw,t_ORd, - t_ADCb,t_ADCw,t_ADCd, - 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, - - t_DSHLw,t_DSHLd, - t_DSHRw,t_DSHRd, - t_MUL,t_DIV, - t_NOTDONE, - t_LASTFLAG -}; - extern bool parity_lookup[256]; void CPU_LLDT(Bitu selector); @@ -110,51 +79,18 @@ Bitu CPU_Pop32(void); void CPU_Push16(Bitu value); void CPU_Push32(Bitu value); -//Flag Handling -Bitu get_CF(void); -Bitu get_AF(void); -Bitu get_ZF(void); -Bitu get_SF(void); -Bitu get_OF(void); -Bitu get_PF(void); +void CPU_SetFlags(Bitu word); -#define SETFLAGSb(FLAGB) \ -{ \ - SETFLAGBIT(OF,get_OF()); \ - flags.type=t_UNKNOWN; \ - flags.word&=0xffffff00;flags.word|=(FLAGB&0xff); \ -} +INLINE void CPU_SetFlagsd(Bit32u word) { + CPU_SetFlags(word); +}; -#define SETFLAGSw(FLAGW) \ -{ \ - flags.type=t_UNKNOWN; \ - flags.word&=0xffff0000;flags.word|=(FLAGW&0xffff); \ -} +INLINE void CPU_SetFlagsw(Bit16u word) { + CPU_SetFlags((flags.word&0xffff0000)|word); +}; -#define SETFLAGSd(FLAGD) \ -{ \ - flags.type=t_UNKNOWN; \ - flags.word=FLAGD; \ -} -#define FILLFLAGS \ -{ \ - flags.word=(flags.word & ~FLAG_MASK) | \ - (get_CF() ? FLAG_CF : 0 ) | \ - (get_PF() ? FLAG_PF : 0 ) | \ - (get_AF() ? FLAG_AF : 0 ) | \ - (get_ZF() ? FLAG_ZF : 0 ) | \ - (get_SF() ? FLAG_SF : 0 ) | \ - (get_OF() ? FLAG_OF : 0 ); \ - flags.type=t_UNKNOWN; \ -} - -#define LoadCF SETFLAGBIT(CF,get_CF()); -#define LoadZF SETFLAGBIT(ZF,get_ZF()); -#define LoadSF SETFLAGBIT(SF,get_SF()); -#define LoadOF SETFLAGBIT(OF,get_OF()); -#define LoadAF SETFLAGBIT(AF,get_AF()); // ********************************************************************* // Descriptor diff --git a/include/regs.h b/include/regs.h index 5d905f4e..c95e529d 100644 --- a/include/regs.h +++ b/include/regs.h @@ -54,6 +54,7 @@ struct Flag_Info { #define SETFLAGBIT(TYPE,TEST) if (TEST) flags.word|=FLAG_ ## TYPE; else flags.word&=~FLAG_ ## TYPE #define GETFLAG(TYPE) (flags.word & FLAG_ ## TYPE) +#define GETFLAGBOOL(TYPE) ((flags.word & FLAG_ ## TYPE) ? true : false ) struct Segment { Bit16u val; From 708d8cb3c301de87d84dfba3d2ac63536f146ce0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Jul 2003 13:10:28 +0000 Subject: [PATCH 1006/4131] CPU Cores keep their own flag handling New lazyflags header file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1086 --- src/cpu/core_full.cpp | 52 +++++++++++++++---- src/cpu/core_full/load.h | 4 +- src/cpu/core_full/loadwrite.h | 3 +- src/cpu/core_full/op.h | 10 +++- src/cpu/core_full/save.h | 4 +- src/cpu/cpu.cpp | 21 ++++---- src/cpu/flags.cpp | 1 + src/cpu/lazyflags.h | 94 +++++++++++++++++++++++++++++++++++ 8 files changed, 160 insertions(+), 29 deletions(-) create mode 100644 src/cpu/lazyflags.h diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 2f7af7ae..7e2d8e53 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -3,24 +3,51 @@ #include "pic.h" #include "regs.h" #include "cpu.h" +#include "lazyflags.h" #include "fpu.h" #include "debug.h" #include "inout.h" #include "callback.h" + +Bit8u PAGE_Readb(PhysPt address); +Bit16u PAGE_Readw(PhysPt address); +Bit32u PAGE_Readd(PhysPt address); + +void PAGE_Writeb(PhysPt address,Bit8u val); +void PAGE_Writew(PhysPt address,Bit16u val); +void PAGE_Writed(PhysPt address,Bit32u val); + typedef PhysPt EAPoint; #define SegBase(c) SegPhys(c) -#define LoadMb(off) mem_readb_inline(off) -#define LoadMw(off) mem_readw_inline(off) -#define LoadMd(off) mem_readd_inline(off) +#if 1 +#define LoadMb(off) mem_readb(off) +#define LoadMw(off) mem_readw(off) +#define LoadMd(off) mem_readd(off) #define LoadMbs(off) (Bit8s)(LoadMb(off)) #define LoadMws(off) (Bit16s)(LoadMw(off)) #define LoadMds(off) (Bit32s)(LoadMd(off)) -#define SaveMb(off,val) mem_writeb_inline(off,val) -#define SaveMw(off,val) mem_writew_inline(off,val) -#define SaveMd(off,val) mem_writed_inline(off,val) +#define SaveMb(off,val) mem_writeb(off,val) +#define SaveMw(off,val) mem_writew(off,val) +#define SaveMd(off,val) mem_writed(off,val) + +#else + +#define LoadMb(off) PAGE_Readb(off) +#define LoadMw(off) PAGE_Readw(off) +#define LoadMd(off) PAGE_Readd(off) + +#define LoadMbs(off) (Bit8s)(LoadMb(off)) +#define LoadMws(off) (Bit16s)(LoadMw(off)) +#define LoadMds(off) (Bit32s)(LoadMd(off)) + +#define SaveMb(off,val) PAGE_Writeb(off,val) +#define SaveMw(off,val) PAGE_Writew(off,val) +#define SaveMd(off,val) PAGE_Writed(off,val) + +#endif #define LoadD(reg) reg #define SaveD(reg,val) reg=val @@ -43,10 +70,14 @@ static INLINE void DecodeModRM(void) { if (inst.rm<0xc0) inst.rm_eaa=(inst.prefix & PREFIX_ADDR) ? RMAddress_32() : RMAddress_16(); } +#define LEAVECORE \ + SaveIP(); \ + FILLFLAGS; + #define EXCEPTION(blah) \ { \ Bit8u new_num=blah; \ - SaveIP(); \ + LEAVECORE; \ Interrupt(new_num); \ LoadIP(); \ goto nextopcode; \ @@ -55,11 +86,12 @@ static INLINE void DecodeModRM(void) { Bitu Full_DeCode(void) { LoadIP(); + flags.type=t_UNKNOWN; while (CPU_Cycles>0) { #if C_DEBUG cycle_count++; #if C_HEAVY_DEBUG - SaveIP(); + LEAVECORE; if (DEBUG_HeavyIsBreakpoint()) return 1; #endif #endif @@ -76,8 +108,8 @@ restartopcode: nextopcode:; CPU_Cycles--; } - SaveIP(); - return 0; + LEAVECORE; + return CBRET_NONE; } diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 9636a499..97e2b348 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -265,10 +265,12 @@ l_M_Ed: inst.op1.d=4; break; case D_IRETw: + flags.type=t_UNKNOWN; CPU_IRET(false); LoadIP(); goto nextopcode; case D_IRETd: + flags.type=t_UNKNOWN; CPU_IRET(true); LoadIP(); goto nextopcode; @@ -470,7 +472,7 @@ l_M_Ed: CPU_CPUID(); goto nextopcode; case D_HLT: - SaveIP(); + LEAVECORE; CPU_HLT(); return 0x0; default: diff --git a/src/cpu/core_full/loadwrite.h b/src/cpu/core_full/loadwrite.h index 77a9c61d..3b3aec07 100644 --- a/src/cpu/core_full/loadwrite.h +++ b/src/cpu/core_full/loadwrite.h @@ -80,10 +80,9 @@ static INLINE Bit32u Pop_32(void) { } } - #if 0 if (flags.intf && PIC_IRQCheck) { \ - SaveIP(); \ + LEAVECORE; \ PIC_runIRQs(); \ LoadIP(); \ } \ diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 0adb0a64..7e425a57 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -339,7 +339,7 @@ switch (inst.code.op) { goto nextopcode; case O_INT: - SaveIP(); + LEAVECORE; #if C_DEBUG if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint()) return 1; else if (DEBUG_IntBreakpoint(inst.op1.b)) return 1; @@ -371,7 +371,7 @@ switch (inst.code.op) { goto nextopcode; case O_CBACK: if (inst.op1.d Date: Sun, 6 Jul 2003 13:36:10 +0000 Subject: [PATCH 1007/4131] New lazy flag headers on detection of IRQ leave the core. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1087 --- src/cpu/core_16/main.h | 25 ++++++++++++++++--------- src/cpu/core_16/prefix_66.h | 3 +++ src/cpu/core_16/support.h | 10 +++++++--- src/cpu/slow_16.cpp | 8 ++++++-- 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 662f8964..bf6ba202 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -585,6 +585,9 @@ restart: case 0x9d: /* POPF */ SETFLAGSw(Pop_16()); CheckTF(); +#ifdef CPU_PIC_CHECK + if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; +#endif break; case 0x9e: /* SAHF */ SETFLAGSb(reg_ah); @@ -798,7 +801,7 @@ restart: #if C_DEBUG SAVEIP; if (DEBUG_Breakpoint()) { - LOADIP; + LEAVECORE; return 1; } LOADIP; @@ -810,7 +813,10 @@ restart: Bit8u num=Fetchb(); #if C_DEBUG SAVEIP; - if (DEBUG_IntBreakpoint(num)) return 1; + if (DEBUG_IntBreakpoint(num)) { + LEAVECORE; + return 1; + } #endif EXCEPTION(num); } @@ -825,6 +831,9 @@ restart: Bit16u pflags=Pop_16(); SETFLAGSw(pflags); CheckTF(); +#ifdef CPU_PIC_CHECK + if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; +#endif break; } case 0xd0: /* GRP2 Eb,1 */ @@ -969,7 +978,7 @@ restart: Repeat_Normal(true,false); continue; case 0xf4: /* HLT */ - SAVEIP; + LEAVECORE; CPU_HLT(); return 0x0; case 0xf5: /* CMC */ @@ -1079,11 +1088,9 @@ restart: break; case 0xfb: /* STI */ SETFLAGBIT(IF,true); - if (PIC_IRQCheck) { - SAVEIP; - PIC_runIRQs(); - LOADIP; - }; +#ifdef CPU_PIC_CHECK + if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; +#endif break; case 0xfc: /* CLD */ SETFLAGBIT(DF,false); @@ -1105,7 +1112,7 @@ restart: { Bit32u ret; Bit16u call=Fetchw(); - SAVEIP; + LEAVECORE; if (call0) { #if C_DEBUG cycle_count++; #if C_HEAVY_DEBUG - SAVEIP; + LEAVECORE; if (DEBUG_HeavyIsBreakpoint()) return 1; #endif #endif @@ -88,7 +92,7 @@ decode_start: CPU_Cycles--; } decode_end: - SAVEIP; + LEAVECORE; return CBRET_NONE; } From b7f369b3ecdee16b9261a629697810b8efe4b060 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Jul 2003 13:36:48 +0000 Subject: [PATCH 1008/4131] New flag funcions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1088 --- src/debug/debug.cpp | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index de164068..a511b37a 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -605,8 +605,6 @@ static void DrawRegisters(void) { /*Individual flags*/ - FILLFLAGS; - SetColor((flags.word ^ oldflags)&FLAG_CF); mvwprintw (dbg.win_reg,1,53,"%01X",GETFLAG(CF) ? 1:0); SetColor((flags.word ^ oldflags)&FLAG_ZF); @@ -1122,26 +1120,25 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) pos++; }; Bit32u address = GetAddress(seg,adr); - if (address<(XMS_GetSize()+1)*1024*1024) { - static char outmask[] = "%s:[%04X]=%02X"; - - if (cpu.state & STATE_PROTECTED) outmask[6] = '8'; - +// if (address<(XMS_GetSize()+1)*1024*1024) { + static char outmask[] = "%s:[%04X]=%02X"; + + if (cpu.state & STATE_PROTECTED) outmask[6] = '8'; switch (DasmLastOperandSize()) { - case 8 : { Bit8u val = mem_readb(address); - outmask[12] = '2'; - sprintf(result,outmask,prefix,adr,val); - } break; - case 16: { Bit16u val = mem_readw(address); - outmask[12] = '4'; - sprintf(result,outmask,prefix,adr,val); - } break; - case 32: { Bit32u val = mem_readd(address); - outmask[12] = '8'; - sprintf(result,outmask,prefix,adr,val); - } break; - } + case 8 : { Bit8u val = mem_readb(address); + outmask[12] = '2'; + sprintf(result,outmask,prefix,adr,val); + } break; + case 16: { Bit16u val = mem_readw(address); + outmask[12] = '4'; + sprintf(result,outmask,prefix,adr,val); + } break; + case 32: { Bit32u val = mem_readd(address); + outmask[12] = '8'; + sprintf(result,outmask,prefix,adr,val); + } break; } +// } // Variable found ? CDebugVar* var = CDebugVar::FindVar(address); if (var) { @@ -1348,7 +1345,9 @@ static void LogInstruction(Bit16u segValue, Bit32u eipValue, char* buffer) if (len<30) for (Bitu i=0; i<30-len; i++) strcat(dline," "); // Get register values - sprintf(buffer,"%04X:%08X %s %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X\n",segValue,eipValue,dline,res,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss),get_CF(),get_ZF(),get_SF(),get_OF(),get_AF(),get_PF()); + + sprintf(buffer,"%04X:%08X %s %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X\n",segValue,eipValue,dline,res,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss), + GETFLAGBOOL(CF),GETFLAGBOOL(ZF),GETFLAGBOOL(SF),GETFLAGBOOL(OF),GETFLAGBOOL(AF),GETFLAGBOOL(PF)); }; static bool DEBUG_Log_Loop(int count) { From c1157a83ce6392c4468da63e5e0c88612b2147d8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Jul 2003 13:44:30 +0000 Subject: [PATCH 1009/4131] added serialport and modem link sdl_net.lib Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1089 --- visualc/dosbox.dsp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index d6577e94..634ea5cd 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -50,7 +50,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 winmm.lib zlib.lib libpng.lib sdlmain.lib sdl.lib curses.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 winmm.lib zlib.lib libpng.lib sdl_net.lib sdlmain.lib sdl.lib curses.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 !ELSEIF "$(CFG)" == "dosbox - Win32 Debug" @@ -75,7 +75,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 winmm.lib zlib.lib libpng.lib sdlmain.lib sdl.lib curses.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 sdl_net.lib winmm.lib zlib.lib libpng.lib sdlmain.lib sdl.lib curses.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept !ENDIF @@ -483,6 +483,14 @@ SOURCE=..\src\hardware\sblaster.cpp # End Source File # Begin Source File +SOURCE=..\src\hardware\serialport.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\hardware\softmodem.cpp +# End Source File +# Begin Source File + SOURCE=..\src\hardware\tandy_sound.cpp # End Source File # Begin Source File From c184fbd2a0d69bf4bdaaf583f84309efb80bb448 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Jul 2003 15:30:21 +0000 Subject: [PATCH 1010/4131] Fix some warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1090 --- include/dos_inc.h | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index d1434346..b2d2b868 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -202,29 +202,31 @@ INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) { #define DOSERR_NOT_SAME_DEVICE 17 #define DOSERR_NO_MORE_FILES 18 + /* Remains some classes used to access certain things */ -#define sGet(s,m) GetIt(((s *)Phys2Host(pt))->m,(PhysPt)&(((s *)0)->m)) -#define sSave(s,m,val) SaveIt(((s *)Phys2Host(pt))->m,(PhysPt)&(((s *)0)->m),val) +#define sGet(s,m) GetIt(((s *)0)->m,(PhysPt)&(((s *)0)->m)) +#define sSave(s,m,val) SaveIt(((s *)0)->m,(PhysPt)&(((s *)0)->m),val) + class MemStruct { public: - INLINE Bit8u GetIt(Bit8u,PhysPt addr) { + INLINE Bit8u GetIt(Bit8u&,PhysPt addr) { return mem_readb(pt+addr); } - INLINE Bit16u GetIt(Bit16u,PhysPt addr) { + INLINE Bit16u GetIt(Bit16u&,PhysPt addr) { return mem_readw(pt+addr); } - INLINE Bit32u GetIt(Bit32u,PhysPt addr) { + INLINE Bit32u GetIt(Bit32u&,PhysPt addr) { return mem_readd(pt+addr); } - INLINE void SaveIt(Bit8u,PhysPt addr,Bit8u val) { + INLINE void SaveIt(Bit8u&,PhysPt addr,Bit8u val) { mem_writeb(pt+addr,val); } - INLINE void SaveIt(Bit16u,PhysPt addr,Bit16u val) { + INLINE void SaveIt(Bit16u&,PhysPt addr,Bit16u val) { mem_writew(pt+addr,val); } - INLINE void SaveIt(Bit32u,PhysPt addr,Bit32u val) { + INLINE void SaveIt(Bit32u&,PhysPt addr,Bit32u val) { mem_writed(pt+addr,val); } INLINE void SetPt(Bit16u seg) { pt=PhysMake(seg,0);} @@ -236,7 +238,7 @@ protected: class DOS_PSP :public MemStruct { public: - DOS_PSP (Bit16u segment) { SetPt(segment);seg=segment;psp=(sPSP *)HostMake(segment,0);}; + DOS_PSP (Bit16u segment) { SetPt(segment);seg=segment;}; void MakeNew (Bit16u memSize); void CopyFileTable (DOS_PSP* srcpsp,bool createchildpsp); Bit16u FindFreeFileEntry (void); @@ -245,7 +247,7 @@ public: void SaveVectors (void); void RestoreVectors (void); void SetSize (Bit16u size) { sSave(sPSP,next_seg,size); }; - Bit16u GetSize () { return sGet(sPSP,next_seg); }; + Bit16u GetSize (void) { return sGet(sPSP,next_seg); }; void SetDTA (RealPt ptdta) { sSave(sPSP,dta,ptdta); }; RealPt GetDTA (void) { return sGet(sPSP,dta); }; void SetEnvironment (Bit16u envseg) { sSave(sPSP,environment,envseg); }; @@ -298,7 +300,6 @@ private: #pragma pack() #endif Bit16u seg; - sPSP* psp; public: static Bit16u rootpsp; }; From 75c8236f5b17b92d4d362d78e37cae12f83a8fe5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Jul 2003 15:31:47 +0000 Subject: [PATCH 1011/4131] don't exit on unhandled pit commands Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1091 --- src/hardware/timer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index c65b2791..6f501644 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -190,7 +190,9 @@ static void write_p43(Bit32u port,Bit8u val) { if (val & 0x02) counter_latch(0); if (val & 0x04) counter_latch(1); if (val & 0x08) counter_latch(2); - } else E_Exit("PIT:Latch Timer Status %X",val); + } else if ((val & 0x10)==0) { /* Latch status words */ + LOG(LOG_PIT,LOG_ERROR)("Unsupported Latch status word call"); + } else LOG(LOG_PIT,LOG_ERROR)("Unhandled command:%X",val); break; } } From 53ae6c8e567df9986837d33e397eb63213595dff Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Jul 2003 15:32:29 +0000 Subject: [PATCH 1012/4131] Remove usage of HostPt Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1092 --- src/dos/dos_execute.cpp | 43 +++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 7da7e712..130f72b2 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -129,45 +129,48 @@ static bool MakeEnv(char * name,Bit16u * segment) { /* If segment to copy environment is 0 copy the caller's environment */ DOS_PSP psp(dos.psp); - Bit8u * envread,*envwrite; + PhysPt envread,envwrite; Bit16u envsize=1; bool parentenv=true; if (*segment==0) { if (!psp.GetEnvironment()) parentenv=false; //environment seg=0 - envread=HostMake(psp.GetEnvironment(),0); + envread=PhysMake(psp.GetEnvironment(),0); } else { if (!*segment) parentenv=false; //environment seg=0 - envread=HostMake(*segment,0); + envread=PhysMake(*segment,0); } if (parentenv) { // hack to allow creation from envblock in unused mem (0xCD) - if (readw(envread)==0xCDCD) writew(envread,0x0000); + if (mem_readb(envread)==0xCDCD) mem_writew(envread,0x0000); for (envsize=0; ;envsize++) { if (envsize>=MAXENV - ENV_KEEPFREE) { DOS_SetError(DOSERR_ENVIRONMENT_INVALID); return false; } - if (readw(envread+envsize)==0) break; + if (mem_readw(envread+envsize)==0) break; } envsize += 2; /* account for trailing \0\0 */ } Bit16u size=long2para(envsize+ENV_KEEPFREE); if (!DOS_AllocateMemory(segment,&size)) return false; - envwrite=HostMake(*segment,0); + envwrite=PhysMake(*segment,0); if (parentenv) { - bmemcpy(envwrite,envread,envsize); + mem_memcpy(envwrite,envread,envsize); envwrite+=envsize; } else { - *envwrite++=0; + mem_writeb(envwrite++,0); } - *((Bit16u *) envwrite)=1; + mem_writew(envwrite,1); envwrite+=2; - - return DOS_Canonicalize(name,(char *)envwrite); -}; + char namebuf[DOS_PATHLENGTH]; + if (DOS_Canonicalize(name,namebuf)) { + MEM_BlockWrite(envwrite,namebuf,strlen(namebuf)+1); + return true; + } else return false; +} bool DOS_NewPSP(Bit16u segment, Bit16u size) { @@ -231,9 +234,10 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { EXE_Header head;Bitu i; Bit16u fhandle;Bit16u len;Bit32u pos; Bit16u pspseg,envseg,loadseg,memsize,readsize; - HostPt loadaddress;RealPt relocpt; + PhysPt loadaddress;RealPt relocpt; Bitu headersize,imagesize; DOS_ParamBlock block(block_pt); + block.LoadData(); if (flags!=LOADNGO && flags!=OVERLAY && flags!=LOAD) { E_Exit("DOS:Not supported execute mode %d for file %s",flags,name); @@ -295,20 +299,24 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { SetupCMDLine(pspseg,block); } else loadseg=block.overlay.loadseg; /* Load the executable */ - loadaddress=HostMake(loadseg,0); + Bit8u * loadbuf=(Bit8u *)new Bit8u[0x10000]; + loadaddress=PhysMake(loadseg,0); if (iscom) { /* COM Load 64k - 256 bytes max */ pos=0;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET); readsize=0xffff-256; - DOS_ReadFile(fhandle,loadaddress,&readsize); + DOS_ReadFile(fhandle,loadbuf,&readsize); + MEM_BlockWrite(loadaddress,loadbuf,readsize); } else { /* EXE Load in 32kb blocks and then relocate */ pos=headersize;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET); while (imagesize>0x7FFF) { - readsize=0x8000;DOS_ReadFile(fhandle,loadaddress,&readsize); + readsize=0x8000;DOS_ReadFile(fhandle,loadbuf,&readsize); + MEM_BlockWrite(loadaddress,loadbuf,readsize); if (readsize!=0x8000) LOG(LOG_EXEC,LOG_NORMAL)("Illegal header"); loadaddress+=0x8000;imagesize-=0x8000; } if (imagesize>0) { - readsize=(Bit16u)imagesize;DOS_ReadFile(fhandle,loadaddress,&readsize); + readsize=(Bit16u)imagesize;DOS_ReadFile(fhandle,loadbuf,&readsize); + MEM_BlockWrite(loadaddress,loadbuf,readsize); if (readsize!=imagesize) LOG(LOG_EXEC,LOG_NORMAL)("Illegal header"); } /* Relocate the exe image */ @@ -323,6 +331,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { mem_writew(address,mem_readw(address)+relocate); } } + delete[] loadbuf; DOS_CloseFile(fhandle); CALLBACK_SCF(false); /* Carry flag cleared for caller if successfull */ if (flags==OVERLAY) return true; /* Everything done for overlays */ From 8b94e8d40835f6f27bc13cff38142249448339bb Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 6 Jul 2003 16:11:36 +0000 Subject: [PATCH 1013/4131] replaced mem_memcpy with MEM_BlockCopy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1093 --- src/dos/dos_execute.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 130f72b2..c03331cd 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -158,7 +158,8 @@ static bool MakeEnv(char * name,Bit16u * segment) { if (!DOS_AllocateMemory(segment,&size)) return false; envwrite=PhysMake(*segment,0); if (parentenv) { - mem_memcpy(envwrite,envread,envsize); + MEM_BlockCopy(envwrite,envread,envsize); +// mem_memcpy(envwrite,envread,envsize); envwrite+=envsize; } else { mem_writeb(envwrite++,0); From 090a3a0aa83ca024819a14a0980b6be1af8c7198 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 6 Jul 2003 16:13:02 +0000 Subject: [PATCH 1014/4131] cpu-flag changes and removed some stuff no longer needed Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1094 --- src/ints/dpmi.cpp | 39 ++++++++------------------------------- 1 file changed, 8 insertions(+), 31 deletions(-) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index d6578b62..68c0666c 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -268,14 +268,10 @@ private: RealPt realModeVec [DPMI_REALVEC_MAX]; Bitu oldRealVec [DPMI_REALVEC_MAX]; Bitu defaultHWIntFromProtMode[DPMI_REALVEC_MAX]; - Bitu firstRmCallback; - Bitu firstRmCallbackInt; - bool inHWINTDefaultHandler[DPMI_REALVEC_MAX]; PhysPt ptorint_base; /* Base of pmode int handlers that reflect to realmode */ Bitu exceptionSelector[DPMI_EXCEPTION_MAX],exceptionOffset[DPMI_EXCEPTION_MAX]; - Bitu xmsHandles[DPMI_XMSHANDLES_MAX]; Bitu protStack; @@ -448,7 +444,6 @@ void DPMI::CopyRegistersToBuffer(PhysPt data) mem_writed(data+0x14, reg_edx); mem_writed(data+0x18, reg_ecx); mem_writed(data+0x1C, reg_eax); - FILLFLAGS; mem_writew(data+0x20, flags.word); mem_writew(data+0x22, SegValue(es)); mem_writew(data+0x24, SegValue(ds)); @@ -469,7 +464,7 @@ void DPMI::LoadRegistersFromBuffer(PhysPt data) reg_edx = mem_readd(data+0x14); reg_ecx = mem_readd(data+0x18); reg_eax = mem_readd(data+0x1C); - SETFLAGSw(mem_readw(data+0x20)); + CPU_SetFlagsw(mem_readw(data+0x20)); SegSet16(es,mem_readw(data+0x22)); SegSet16(ds,mem_readw(data+0x24)); SegSet16(fs,mem_readw(data+0x26)); @@ -630,14 +625,14 @@ Bitu DPMI::ExceptionReturn(void) error = CPU_Pop32(); reg_eip = CPU_Pop32(); CPU_SetSegGeneral(cs,CPU_Pop32()); - SETFLAGSd(CPU_Pop32()); + CPU_SetFlagsd(CPU_Pop32()); reg_esp = CPU_Pop32(); CPU_SetSegGeneral(ss,CPU_Pop32()); } else { error = CPU_Pop16(); reg_eip = CPU_Pop16(); CPU_SetSegGeneral(cs,CPU_Pop16()); - SETFLAGSw(CPU_Pop16()); + CPU_SetFlagsw(CPU_Pop16()); reg_esp = CPU_Pop16(); CPU_SetSegGeneral(ss,CPU_Pop16()); }; @@ -690,7 +685,7 @@ Bitu DPMI::RealModeCallback(void) { // Call protected mode function Bitu num = mem_readw(PhysPt(SegPhys(cs)+reg_eip-2)); - num -= dpmi.firstRmCallback; + num -= dpmi.rmCallback[0].id; if ((num>=DPMI_REALMODE_CALLBACK_MAX) || !dpmi.rmCallback[num].inUse) E_Exit("DPMI: Illegal Realmode callback %02X.",num); if (dpmi.rmCallback[num].inCall) DPMI_LOG("DPMI: Recursive Realmode callback %02X",num); @@ -733,7 +728,6 @@ Bitu DPMI::RealModeCallback(void) CPU_SetSegGeneral(ss,dpmi.protStackSelector[dpmi.protStackCurrent++]); reg_esp = DPMI_PROTMODE_STACKSIZE; // prepare stack for iret - FILLFLAGS; if (dpmi.client.bit32) CPU_Push32(flags.word); else CPU_Push16(flags.word); // Setup cs:ip to return to DPMI_ReturnFromRealModeCallback CPU_SetSegGeneral(cs,GDT_CODE); @@ -789,7 +783,6 @@ Bitu DPMI::CallRealIRETFrame(void) // Provide Stack ProvideRealModeStack(prStack,toCopy); // Push flags - FILLFLAGS; CPU_Push16(flags.word); // Setup IP Bitu newCS = mem_readw(data+0x2C); @@ -898,7 +891,7 @@ Bitu DPMI::ptorHandler(void) if (num==0x0F) DPMI_LOG("DPMI: INT %02X %04X called.",num,reg_ax); // Prepare flags for real int - // SETFLAGSw(flags.word & 0x3ED5); // 0011111011010101b + // CPU_SetFlagsw(flags.word & 0x3ED5); // 0011111011010101b Interrupt(num); return 0; } @@ -919,12 +912,6 @@ Bitu DPMI::ptorHandlerReturn(void) DPMI_LOG("DPMI: INT %02X RETURN",num); // hardware ints exit here if (((num>=0x08) && (num<=0x0F)) || ((num>=0x70) && (num<=0x77))) { - for (Bitu i=0; i Date: Tue, 8 Jul 2003 16:46:28 +0000 Subject: [PATCH 1015/4131] Check for interrupt flag and waiting irq's on moments where flags are changed. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1095 --- src/cpu/core_full/load.h | 11 +++++++---- src/cpu/core_full/save.h | 8 ++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 97e2b348..86634ccc 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -268,6 +268,10 @@ l_M_Ed: flags.type=t_UNKNOWN; CPU_IRET(false); LoadIP(); + if (GETFLAG(IF) && PIC_IRQCheck) { + SaveIP(); + return CBRET_NONE; + } goto nextopcode; case D_IRETd: flags.type=t_UNKNOWN; @@ -346,10 +350,9 @@ l_M_Ed: goto nextopcode; case D_STI: SETFLAGBIT(IF,true); - if (PIC_IRQCheck) { - SaveIP(); - PIC_runIRQs(); - LoadIP(); + if (GETFLAG(IF) && PIC_IRQCheck) { + LEAVECORE; + return CBRET_NONE; } goto nextopcode; case D_STC: diff --git a/src/cpu/core_full/save.h b/src/cpu/core_full/save.h index 9e849d18..a5e97eb1 100644 --- a/src/cpu/core_full/save.h +++ b/src/cpu/core_full/save.h @@ -103,9 +103,17 @@ switch (inst.code.save) { break; case S_FLGw: SETFLAGSw(inst.op1.w); + if (GETFLAG(IF) && PIC_IRQCheck) { + SaveIP(); + return CBRET_NONE; + } break; case S_FLGd: SETFLAGSd(inst.op1.d); + if (GETFLAG(IF) && PIC_IRQCheck) { + SaveIP(); + return CBRET_NONE; + } break; case 0: break; From 569fd602d1d8465cad496821f93df34f8db7acff Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 8 Jul 2003 16:50:27 +0000 Subject: [PATCH 1016/4131] Root z:\ directory is valid Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1096 --- src/dos/drive_virtual.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 3d0cb9de..64663fde 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -157,6 +157,7 @@ bool Virtual_Drive::MakeDir(char * dir) { } bool Virtual_Drive::TestDir(char * dir) { + if (!dir[0]) return true; //only valid dir is the empty dir return false; } From 9bbec94977dfdcddd405578c792297ee2cff67b8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 8 Jul 2003 16:51:26 +0000 Subject: [PATCH 1017/4131] Slightly better support for ioctl function 0x6 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1097 --- src/dos/dos_ioctl.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index e2602186..f509242a 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -40,8 +40,16 @@ bool DOS_IOCTL(void) { case 0x00: /* Get Device Information */ reg_dx=Files[handle]->GetInformation(); return true; + case 0x06: /* Get Input Status */ + if (Files[handle]->GetInformation() & 0x8000) { //Check for device + reg_al=(Files[handle]->GetInformation() & 0x40) ? 0xff : 0; + } else { + LOG(LOG_IOCTL,LOG_NORMAL)("06:Unsupported File handle %d",handle); + reg_al=0xff; + } + return true; case 0x07: /* Get Output Status */ - LOG(LOG_IOCTL,LOG_NORMAL)("DOS:IOCTL:07:Fakes output status is ready for handle %d",handle); + LOG(LOG_IOCTL,LOG_NORMAL)("07:Fakes output status is ready for handle %d",handle); reg_al=0xff; return true; case 0x08: /* Check if block device removable */ @@ -93,13 +101,6 @@ bool DOS_IOCTL(void) { return false; } break; - case 0x06: /* Get Input Status */ - if(reg_bx==0x00) { /* might work for other handles, but tested it only for STDIN */ - if(Files[handle]->GetInformation() & 0x40) reg_al=0x00; else - reg_al=0xFF; - return true; - break; - } default: LOG(LOG_DOSMISC,LOG_ERROR)("DOS:IOCTL Call %2X unhandled",reg_al); return false; From 11d98caddbe32e61c1919ea0159de787963f83c6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 8 Jul 2003 16:53:07 +0000 Subject: [PATCH 1018/4131] Added softmodem and serialport Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1098 --- src/hardware/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index e950ad3a..efe59594 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -8,5 +8,5 @@ libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ vga.cpp vga.h vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp \ vga_memory.cpp vga_misc.cpp vga_seq.cpp font-switch.h ega-switch.h cmos.cpp disney.cpp \ - gus.cpp mpu401.cpp + gus.cpp mpu401.cpp serialport.cpp softmodem.cpp From a8a7d4ed98bdcb9f02fb28aaa30217b07be0b0be Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 8 Jul 2003 17:11:04 +0000 Subject: [PATCH 1019/4131] Update logging with some new targets for better compling without debugging Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1099 --- include/Makefile.am | 1 + include/logging.h | 27 +++++++++------------------ 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/include/Makefile.am b/include/Makefile.am index 2e395d13..20f35bb0 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -23,6 +23,7 @@ programs.h \ render.h \ regs.h \ render.h \ +serialport.h \ setup.h \ support.h \ timer.h \ diff --git a/include/logging.h b/include/logging.h index 62435fa4..1735dfff 100644 --- a/include/logging.h +++ b/include/logging.h @@ -40,25 +40,16 @@ void DEBUG_ShowMsg(char * format,...); struct LOG { - LOG(LOG_TYPES type, LOG_SEVERITIES severity) { return;} - void operator()(char const* buf) { return;} - void operator()(char const* buf, double f1) { return;} - void operator()(char const* buf, double f1, Bit32u u1) { return;} - void operator()(char const* buf, Bitu u1, double f1) { return;} + LOG(LOG_TYPES type, LOG_SEVERITIES severity) { return;} + void operator()(char const* buf) { return;} + void operator()(char const* buf, double f1) { return;} + void operator()(char const* buf, double f1, double f2) { return;} + void operator()(char const* buf, double f1, double f2, double f3) { return;} - void operator()(char const* buf, Bitu u1, Bitu u2) { return;} - void operator()(char const* buf, Bits u1, Bits u2) { return;} - void operator()(char const* buf, Bitu u1, Bits u2) { return;} - void operator()(char const* buf, Bits u1, Bitu u2) { return;} - void operator()(char const* buf, Bit32s& u1) { return;} - void operator()(char const* buf, Bit32u& u1) { return;} - void operator()(char const* buf, Bits& s1) { return;} - void operator()(char const* buf, Bitu& u1) { return;} - - void operator()(char const* buf, char const* s1) { return;} - void operator()(char const* buf, char const* s1, Bit32u u1) { return;} - void operator()(char const* buf, char const* s1, Bit32u u1, Bit32u u2) { return;} - void operator()(char const* buf, Bit32u u1, char const* s1) { return;} + void operator()(char const* buf, char const* s1) { return;} + void operator()(char const* buf, char const* s1, double f1) { return;} + void operator()(char const* buf, char const* s1, double f1,double f2) { return;} + void operator()(char const* buf, double f1, char const* s1) { return;} From 4f61b6c47a45b08defbd99f7dac804a2f75afee5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 8 Jul 2003 18:21:22 +0000 Subject: [PATCH 1020/4131] C_MODEM checking Correct caps for sdl_net header Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1100 --- src/hardware/softmodem.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp index dcdf449d..b76b6221 100644 --- a/src/hardware/softmodem.cpp +++ b/src/hardware/softmodem.cpp @@ -16,9 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include "sdl_net.h" +#if C_MODEM +#include +#include "SDL_net.h" #include "dosbox.h" #include "inout.h" @@ -631,5 +632,5 @@ void MODEM_Init(Section* sec) { MIXER_SetMode(mhd.chan,MIXER_16MONO); } - +#endif From 95411985d727758c24bca2dabff7e744926cca7e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 8 Jul 2003 18:24:36 +0000 Subject: [PATCH 1021/4131] Screenshot will now be disabled if there's no libpng else enabled default Checking fo SDL_net if softmodem can be enabled. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1101 --- configure.in | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/configure.in b/configure.in index 655c9e37..fafa8333 100644 --- a/configure.in +++ b/configure.in @@ -72,25 +72,33 @@ AC_ARG_ENABLE(debug,AC_HELP_STRING([--enable-debug],[Enable debug mode]),[ fi ],) -AH_TEMPLATE(C_SSHOT,[Define to 1 to enable screenshots, requires libpng]) -AC_ARG_ENABLE(shots,AC_HELP_STRING([--enable-shots],[Enable screenshot support]),[ - AC_CHECK_HEADER(png.h,have_png_h=yes,) - AC_CHECK_LIB(png, png_check_sig, have_png_lib=yes, ,-lz) - if test x$have_png_lib = xyes -a x$have_png_h = xyes ; then - LIBS="$LIBS -lpng -lz" - AC_DEFINE(C_SSHOT,1) - else - AC_MSG_WARN([Can't enable screenshots without libpng]) - fi -],) - - AH_TEMPLATE(C_FPU,[Define to 1 to enable floating point emulation]) AC_ARG_ENABLE(fpu,AC_HELP_STRING([--disable-fpu],[Disable FPU support]), AC_MSG_RESULT([FPU support has been disabled]), AC_DEFINE(C_FPU,1) ) +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]) +AC_CHECK_HEADER(SDL/SDL_net.h,have_sdl_net_h=yes,) +AC_CHECK_LIB(SDL_net, SDLNet_Init, have_sdl_net_lib=yes, , ) +if test x$have_sdl_net_lib = xyes -a x$have_sdl_net_h = xyes ; then + LIBS="$LIBS -lSDL_net" + AC_DEFINE(C_MODEM,1) +else + AC_MSG_WARN([Can't find SDL_net, internal modem disabled]) +fi + + dnl Some host detection and actions for them case "$target" in *-*-cygwin* | *-*-mingw32*) From 17d3f156437371042bf4d1a7625021e757d1c3dc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 8 Jul 2003 18:27:14 +0000 Subject: [PATCH 1022/4131] Make push/pop calls non-inline Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1102 --- src/cpu/cpu.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 4e9ec644..6d23c9b1 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -58,7 +58,7 @@ DecoderStart * CPU_DecorderStarts[8]={ CPU_Core_Full_Start, //32-bit prot,32-bit stack }; -INLINE void CPU_Push16(Bitu value) { +void CPU_Push16(Bitu value) { if (cpu.state & STATE_STACK32) { reg_esp-=2; mem_writew(SegPhys(ss)+reg_esp,value); @@ -68,7 +68,7 @@ INLINE void CPU_Push16(Bitu value) { } } -INLINE void CPU_Push32(Bitu value) { +void CPU_Push32(Bitu value) { if (cpu.state & STATE_STACK32) { reg_esp-=4; mem_writed(SegPhys(ss)+reg_esp,value); @@ -78,7 +78,7 @@ INLINE void CPU_Push32(Bitu value) { } } -INLINE Bitu CPU_Pop16(void) { +Bitu CPU_Pop16(void) { if (cpu.state & STATE_STACK32) { Bitu val=mem_readw(SegPhys(ss)+reg_esp); reg_esp+=2; @@ -90,7 +90,7 @@ INLINE Bitu CPU_Pop16(void) { } } -INLINE Bitu CPU_Pop32(void) { +Bitu CPU_Pop32(void) { if (cpu.state & STATE_STACK32) { Bitu val=mem_readd(SegPhys(ss)+reg_esp); reg_esp+=4; From a9e6d0bacc4a9597834709035d78530352080521 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 8 Jul 2003 20:11:08 +0000 Subject: [PATCH 1023/4131] Change order of includes for defines Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1103 --- src/hardware/softmodem.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp index b76b6221..b05102e2 100644 --- a/src/hardware/softmodem.cpp +++ b/src/hardware/softmodem.cpp @@ -16,12 +16,15 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + + +#include "dosbox.h" + #if C_MODEM #include #include "SDL_net.h" -#include "dosbox.h" #include "inout.h" #include "mixer.h" #include "dma.h" From 8f10df38307ebcff94ef4f36dfb0edd48f6f3126 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 9 Jul 2003 15:24:22 +0000 Subject: [PATCH 1024/4131] fixed bug in func 503, wrong resize size calculated Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1104 --- src/ints/dpmi.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index 68c0666c..4109587c 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -1467,6 +1467,7 @@ Bitu DPMI::Int31Handler(void) }; break; case 0x0100:{// Allocate DOS Memory Block Bit16u blocks = reg_bx; + DPMI_LOG("DPMI: 0100: Allocate DOS Mem: (%04X Blocks)",blocks); if (DOS_AllocateMemory(®_ax,&blocks)) { // Allocate Selector for block SetDescriptor desc; Bitu base; Bitu numDesc; @@ -1678,16 +1679,14 @@ Bitu DPMI::Int31Handler(void) Bitu length = (reg_bx<<16)+reg_cx; // TEMP Bit16u largest,total; + DPMI_LOG("DPMI: 0501: Allocate memory (%d KB)",length/1024); if (AllocateMem(length,handle,linear)) { reg_si = 0; reg_di = handle; reg_bx = (linear>>16); reg_cx = (linear&0xFFFF); DPMI_CALLBACK_SCF(false); XMS_QueryFreeMemory(largest,total); // in KB - if (total==2804) { - int brk = 0; - } - DPMI_LOG("DPMI: 0501: Allocation success (%d KB) (R:%d KB)",length/1024,total); + DPMI_LOG("DPMI: 0501: Allocation success: H:%04X%04X (%d KB) (R:%d KB)",reg_si,reg_di,length/1024,total); } else { reg_ax = DPMI_ERROR_PHYSICAL_MEMORY_UNAVAILABLE; DPMI_CALLBACK_SCF(true); @@ -1696,6 +1695,7 @@ Bitu DPMI::Int31Handler(void) }; }; break; case 0x0502://Free Memory Block + DPMI_LOG("DPMI: 0502: Free Mem: H:%04X%04X",reg_si,reg_di); if (XMS_FreeMemory((reg_si<<16)+reg_di)==0) { FreeXMSHandle((reg_si<<16)+reg_di); DPMI_CALLBACK_SCF(false); @@ -1706,8 +1706,10 @@ Bitu DPMI::Int31Handler(void) }; break; case 0x0503:{//Resize Memory Block - Bit32u newSize = (Bitu(reg_bx<<16)+reg_cx)/1024; + Bitu newByte = (reg_bx<<16)+reg_cx; + Bit32u newSize = (newByte/1024)+((newByte & 1023)>0); Bitu handle = (reg_si<<16)+reg_di; + DPMI_LOG("DPMI: 0503: Resize Memory: H:%08X (%d KB)",handle,newSize); if (XMS_ResizeMemory(handle,newSize)==0) { if (XMS_LockMemory(handle,newSize)==0) { reg_bx = (newSize>>16); From c840ac87c870cf5fd6f65379b4f6d11912f0b050 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 9 Jul 2003 16:06:47 +0000 Subject: [PATCH 1025/4131] LEAVECORE is called only if breakpoint is detected (heavy debug) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1105 --- src/cpu/core_full.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 7e2d8e53..b7351f59 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -91,8 +91,10 @@ Bitu Full_DeCode(void) { #if C_DEBUG cycle_count++; #if C_HEAVY_DEBUG - LEAVECORE; - if (DEBUG_HeavyIsBreakpoint()) return 1; + if (DEBUG_HeavyIsBreakpoint()) { + LEAVECORE; + return 1; + }; #endif #endif inst.start=IPPoint; From c44112560670b2e40b389aa2943fde54f4d287da Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 9 Jul 2003 16:11:30 +0000 Subject: [PATCH 1026/4131] LEAVECORE is called only if breakpoint is detected (heavy debug), added SaveIP. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1106 --- src/cpu/core_full.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index b7351f59..6b3d1360 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -91,6 +91,7 @@ Bitu Full_DeCode(void) { #if C_DEBUG cycle_count++; #if C_HEAVY_DEBUG + SaveIP(); if (DEBUG_HeavyIsBreakpoint()) { LEAVECORE; return 1; From 4520aa573e9c37800702e92bd524f4cd247cfe2a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 10 Jul 2003 12:34:08 +0000 Subject: [PATCH 1027/4131] remove obsolete #include Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1107 --- src/hardware/serialport.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/serialport.cpp b/src/hardware/serialport.cpp index eb040151..120a5603 100644 --- a/src/hardware/serialport.cpp +++ b/src/hardware/serialport.cpp @@ -17,7 +17,6 @@ */ #include -#include "sdl_syswm.h" #include "dosbox.h" #include "inout.h" @@ -439,3 +438,4 @@ void SERIAL_Init(Section* sec) { serialports[0] = new CSerial(0x3f0,4,SERIALBASERATE); serialports[1] = new CSerial(0x2f0,3,SERIALBASERATE); } + From 3d2607e514d3df905c846a0b451afab0ab2e5f0f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 10 Jul 2003 12:35:53 +0000 Subject: [PATCH 1028/4131] tada a newline at the end Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1108 --- include/serialport.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/serialport.h b/include/serialport.h index 9f08303a..1347ac62 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -132,4 +132,5 @@ private: // This function returns the CSerial objects for ports 1-4 // CSerial *getComport(Bitu portnum); -#endif \ No newline at end of file +#endif + From e8d9586feee734ab312d8f7390b012ea2bedc556 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 10 Jul 2003 22:28:44 +0000 Subject: [PATCH 1029/4131] Only report a coprocessor when enabled Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1109 --- src/ints/bios.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 3b23e9ae..59447d4a 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -327,8 +327,11 @@ void BIOS_Init(Section* sec) { if (IO_Read(0x3f8)!=0xff) real_writew(0x40,(index++)*2,0x3f8); if (IO_Read(0x2f8)!=0xff) real_writew(0x40,(index++)*2,0x2f8); /* Setup equipment list */ +#if (C_FPU) mem_writew(BIOS_CONFIGURATION,0xc823); //1 Floppy,FPU,2 serial, 1 parallel - +#else + mem_writew(BIOS_CONFIGURATION,0xc821); //1 Floppy,FPU,2 serial, 1 parallel +#endif } From 15bdfcb09c1b2252ec714be5ecbbb1f21e194edc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 08:12:53 +0000 Subject: [PATCH 1030/4131] CB_BASE defined Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1110 --- include/callback.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/callback.h b/include/callback.h index ff4f5835..9b083be6 100644 --- a/include/callback.h +++ b/include/callback.h @@ -28,6 +28,7 @@ enum { CB_RETF,CB_IRET,CB_IRET_STI }; #define CB_MAX 1024 #define CB_SEG 0xC800 +#define CB_BASE (CB_SEG << 4) enum { CBRET_NONE=0,CBRET_STOP=1 From 2174ca5c3bec4cd48dacbe79f26294b81723abef Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 08:13:26 +0000 Subject: [PATCH 1031/4131] LOG_PAGING target. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1111 --- include/logging.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/logging.h b/include/logging.h index 1735dfff..570bc7f2 100644 --- a/include/logging.h +++ b/include/logging.h @@ -4,7 +4,7 @@ enum LOG_TYPES { LOG_ALL, LOG_VGA, LOG_VGAGFX,LOG_VGAMISC,LOG_INT10, LOG_SB,LOG_DMA, - LOG_FPU,LOG_CPU, + 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, From 695d8e91d47a3cadb1ddf00fd9b91196d656d41e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 08:16:04 +0000 Subject: [PATCH 1032/4131] New headers and changes for new paging support. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1112 --- include/mem.h | 118 ++++++------------------- include/paging.h | 225 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 252 insertions(+), 91 deletions(-) create mode 100644 include/paging.h diff --git a/include/mem.h b/include/mem.h index 9723e830..23e8fcea 100644 --- a/include/mem.h +++ b/include/mem.h @@ -26,37 +26,27 @@ typedef Bit32u PhysPt; typedef Bit8u * HostPt; typedef Bit32u RealPt; -typedef Bit8u (*MEMORY_ReadHandler)(PhysPt pt); -typedef void (*MEMORY_WriteHandler)(PhysPt pt,Bit8u val); +typedef Bits MemHandle; -#define PAGE_KB 16 -#define PAGE_SIZE (PAGE_KB*1024) -#define PAGE_SHIFT 14 -#define PAGE_COUNT(A) (A & ((1 << PAGE_SHIFT)-1) ? 1+(A >> PAGE_SHIFT) : (A >> PAGE_SHIFT) ) - -extern HostPt ReadHostTable[]; -extern HostPt WriteHostTable[]; -extern MEMORY_ReadHandler ReadHandlerTable[]; -extern MEMORY_WriteHandler WriteHandlerTable[]; - - -INLINE Bit16u PAGES(Bit32u bytes) { - if ((bytes & 4095) == 0) return (Bit16u)(bytes>>12); - return (Bit16u)(1+(bytes>>12)); -} - -void MEM_SetupPageHandlers(Bitu startpage,Bitu pages,MEMORY_ReadHandler read,MEMORY_WriteHandler write); -void MEM_ClearPageHandlers(Bitu startpage,Bitu pages); - -void MEM_SetupMapping(Bitu startpage,Bitu pages,void * data); -void MEM_ClearMapping(Bitu startpage,Bitu pages); +#define MEM_PAGESIZE 4096 bool MEM_A20_Enabled(void); void MEM_A20_Enable(bool enable); -Bitu MEM_TotalSize(void); //Memory size in KB +/* Memory management / EMS mapping */ +HostPt MEM_GetBlockPage(void); +Bitu MEM_FreeTotal(void); //Free 4 kb pages +Bitu MEM_FreeLargest(void); //Largest free 4 kb pages block +Bitu MEM_TotalPages(void); //Total amount of 4 kb pages +MemHandle MEM_AllocatePages(Bitu pages,bool sequence); +PhysPt MEM_AllocatePage(void); +void MEM_ReleasePages(MemHandle handle); +bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence); +void MEM_MapPages(Bitu phys_page,MemHandle mem,Bitu mem_page,Bitu pages); +void MEM_UnmapPages(Bitu phys_page,Bitu pages); -extern HostPt memory; + +MemHandle MEM_NextHandle(MemHandle handle); /* The folowing six functions are used everywhere in the end so these should be changed for @@ -88,9 +78,9 @@ INLINE void writed(HostPt off,Bit32u val) { off[3]=(Bit8u)(val >> 24); }; -#define MLEB(_MLE_VAL_) (_MLE_VAL_) -#define MLEW(_MLE_VAL_) ( (_MLE_VAL_ >> 8) | (_MLE_VAL_ << 8)) -#define MLED(_MLE_VAL_) ( (_MLE_VAL_ >> 24)|((_MLE_VAL_ >> 8)&0xFF00)|((_MLE_VAL_ << 8)&0xFF0000)|((_MLE_VAL_ << 24)&0xFF000000)) +#define MLEB(_MLE_VAL_) (_MLE_VAL_) +#define MLEW(_MLE_VAL_) ((_MLE_VAL_ >> 8) | (_MLE_VAL_ << 8)) +#define MLED(_MLE_VAL_) ((_MLE_VAL_ >> 24)|((_MLE_VAL_ >> 8)&0xFF00)|((_MLE_VAL_ << 8)&0xFF0000)|((_MLE_VAL_ << 24)&0xFF000000)) #else @@ -125,8 +115,6 @@ INLINE void writed(HostPt off,Bit32u val) { if (sizeof(VAR_)==4) VAR_=MLED(VAL_); /* 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); Bit16u mem_readw(PhysPt pt); @@ -136,63 +124,22 @@ void mem_writeb(PhysPt pt,Bit8u val); void mem_writew(PhysPt pt,Bit16u val); void mem_writed(PhysPt pt,Bit32u val); -INLINE void mem_writeb_inline(PhysPt pt,Bit8u val) { - if (WriteHostTable[pt >> PAGE_SHIFT]) writeb(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); - else { - WriteHandlerTable[pt >> PAGE_SHIFT](pt,val); - } -} +void phys_writeb(PhysPt addr,Bit8u val); +void phys_writew(PhysPt addr,Bit16u val); +void phys_writed(PhysPt addr,Bit32u val); -INLINE void mem_writew_inline(PhysPt pt,Bit16u val) { - if (WriteHostTable[pt >> PAGE_SHIFT]) writew(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); - else { - WriteHandlerTable[pt >> PAGE_SHIFT](pt+0,(Bit8u)(val & 0xff)); - WriteHandlerTable[pt >> PAGE_SHIFT](pt+1,(Bit8u)((val >> 8) & 0xff) ); - } -} - -INLINE void mem_writed_inline(PhysPt pt,Bit32u val) { - if (WriteHostTable[pt >> PAGE_SHIFT]) writed(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); - else { - WriteHandlerTable[pt >> PAGE_SHIFT](pt+0,(Bit8u)(val & 0xff)); - WriteHandlerTable[pt >> PAGE_SHIFT](pt+1,(Bit8u)((val >> 8) & 0xff) ); - WriteHandlerTable[pt >> PAGE_SHIFT](pt+2,(Bit8u)((val >> 16) & 0xff) ); - WriteHandlerTable[pt >> PAGE_SHIFT](pt+3,(Bit8u)((val >> 24) & 0xff) ); - } -} - -INLINE Bit8u mem_readb_inline(PhysPt pt) { - if (ReadHostTable[pt >> PAGE_SHIFT]) return readb(ReadHostTable[pt >> PAGE_SHIFT]+pt); - else { - return ReadHandlerTable[pt >> PAGE_SHIFT](pt); - } -} - -INLINE Bit16u mem_readw_inline(PhysPt pt) { - if (ReadHostTable[pt >> PAGE_SHIFT]) return readw(ReadHostTable[pt >> PAGE_SHIFT]+pt); - else { - return - (ReadHandlerTable[pt >> PAGE_SHIFT](pt+0)) | - (ReadHandlerTable[pt >> PAGE_SHIFT](pt+1)) << 8; - } -} - -INLINE Bit32u mem_readd_inline(PhysPt pt){ - if (ReadHostTable[pt >> PAGE_SHIFT]) return readd(ReadHostTable[pt >> PAGE_SHIFT]+pt); - else { - return - (ReadHandlerTable[pt >> PAGE_SHIFT](pt+0)) | - (ReadHandlerTable[pt >> PAGE_SHIFT](pt+1)) << 8 | - (ReadHandlerTable[pt >> PAGE_SHIFT](pt+2)) << 16 | - (ReadHandlerTable[pt >> PAGE_SHIFT](pt+3)) << 24; - } -} +/* These don't check for alignment, better be sure it's correct */ +Bit32u phys_page_readd(Bitu page,Bitu off); void MEM_BlockWrite(PhysPt pt,void * data,Bitu size); void MEM_BlockRead(PhysPt pt,void * data,Bitu size); 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); +Bitu mem_strlen(PhysPt pt); +void mem_strcpy(PhysPt dest,PhysPt src); + /* The folowing functions are all shortcuts to the above functions using physical addressing */ INLINE Bit8u real_readb(Bit16u seg,Bit16u off) { @@ -215,13 +162,6 @@ INLINE void real_writed(Bit16u seg,Bit16u off,Bit32u val) { mem_writed(((seg<<4)+off),val); } -INLINE HostPt HostMake(Bit16u seg,Bit16u off) { - return memory+(seg<<4)+off; -} - -INLINE HostPt Phys2Host(PhysPt pt) { - return memory+pt; -} INLINE Bit16u RealSeg(RealPt pt) { return (Bit16u)(pt>>16); @@ -239,10 +179,6 @@ INLINE PhysPt PhysMake(Bit16u seg,Bit16u off) { return (seg<<4)+off; } -INLINE HostPt Real2Host(RealPt pt) { - return memory+(RealSeg(pt)<<4) +RealOff(pt); -} - INLINE RealPt RealMake(Bit16u seg,Bit16u off) { return (seg<<16)+off; } diff --git a/include/paging.h b/include/paging.h new file mode 100644 index 00000000..172612a9 --- /dev/null +++ b/include/paging.h @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _PAGING_H_ +#define _PAGING_H_ + +#include "mem.h" + +class PageDirectory; +struct PageEntry; +struct PageLink; + +#define MEM_PAGE_SIZE (4096) +#define XMS_START (0x110) + +enum EntryTypes { //The type of memory contained in this link + ENTRY_VGA, + ENTRY_CHANGES, + ENTRY_INIT, + ENTRY_NA, + ENTRY_ROM, + ENTRY_LFB, + ENTRY_RAM, + ENTRY_ALLOC, +}; + +enum VGA_RANGES { + VGA_RANGE_A000, + VGA_RANGE_B000, + VGA_RANGE_B800, +}; + + +class PageChange { +public: + virtual void Changed(PageLink * link,Bitu start,Bitu end)=0; +}; + +/* Some other functions */ +void PAGING_Enable(bool enabled); +bool PAGING_Enabled(void); + +void MEM_CheckLinks(PageEntry * theentry); + +PageDirectory * MEM_DefaultDirectory(void); +Bitu PAGING_GetDirBase(void); +void PAGING_SetDirBase(Bitu cr3); + +PageLink * MEM_LinkPage(Bitu phys_page,PhysPt lin_base); + +void MEM_UnlinkPage(PageLink * link); +void MEM_SetLFB(Bitu _page,Bitu _pages,HostPt _pt); + +#pragma pack(1) +typedef struct { + 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; +} X86_PageEntryBlock GCC_ATTRIBUTE(packed); +#pragma pack() + +union X86PageEntry { + Bit32u load; + X86_PageEntryBlock block; +}; + +struct PageLink { + HostPt read; + HostPt write; + PageChange * change; + PhysPt lin_base; + PageEntry * entry; + union { + PageDirectory * dir; + Bitu table; + } data; + PageLink * next; +}; + +struct PageEntry { + PageLink * links; + EntryTypes type; + union { + HostPt mem; + PhysPt vga_base; + PageDirectory * dir; + } data; + MemHandle next_handle; +}; + +class PageDirectory { +public: + PageDirectory(); + ~PageDirectory(); + void ClearDirectory(void); + void SetBase(PhysPt page); + void LinkPage(Bitu lin_page,Bitu phys_page); + bool InitPage(Bitu lin_address); + bool InitPageLinear(Bitu lin_address); + void InvalidateTable(Bitu table); + void InvalidateLink(Bitu table,Bitu index); + PageDirectory * next; + PageLink *links[1024*1024]; + PageLink *tables[1024]; + PageLink *link_dir; //Handler for main directory table + PageEntry entry_init; //Handler for pages that need init + PageLink link_init; //Handler for pages that need init + Bit32u base_page; //Base got from CR3 + PageChange * table_change; + PageChange * dir_change; +}; + +struct PagingBlock { + PageDirectory * cache; + PageDirectory * dir; + PageLink * free_link; + Bitu cr3; + bool enabled; +}; + +extern PagingBlock paging; + +/* Some support functions */ + +static INLINE PageLink * GetPageLink(PhysPt address) { + Bitu index=(address>>12); + return paging.dir->links[index]; +} + +void PAGING_AddFreePageLink(PageLink * link); + +PageLink * PAGING_GetFreePageLink(void); +void MEM_SetupVGA(VGA_RANGES range,HostPt base); + +/* Page Handler functions */ + +Bit8u ENTRY_readb(PageEntry * pentry,PhysPt address); +Bit16u ENTRY_readw(PageEntry * pentry,PhysPt address); +Bit32u ENTRY_readd(PageEntry * pentry,PhysPt address); +void ENTRY_writeb(PageEntry * pentry,PhysPt address,Bit8u val); +void ENTRY_writew(PageEntry * pentry,PhysPt address,Bit16u val); +void ENTRY_writed(PageEntry * pentry,PhysPt address,Bit32u val); + +/* 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); + +/* Special inlined memory reading/writing */ + +INLINE Bit8u mem_readb_inline(PhysPt address) { + PageLink * plink=GetPageLink(address); + + if (plink->read) return readb(plink->read+address); + else return ENTRY_readb(plink->entry,address); +} + +INLINE Bit16u mem_readw_inline(PhysPt address) { + if (address & 1) return mem_unalignedreadw(address); + PageLink * plink=GetPageLink(address); + + if (plink->read) return readw(plink->read+address); + else return ENTRY_readw(plink->entry,address); +} + + +INLINE Bit32u mem_readd_inline(PhysPt address) { + if (address & 3) return mem_unalignedreadd(address); + PageLink * plink=GetPageLink(address); + + if (plink->read) return readd(plink->read+address); + else return ENTRY_readd(plink->entry,address); +} + +INLINE void mem_writeb_inline(PhysPt address,Bit8u val) { + PageLink * plink=GetPageLink(address); + + if (plink->write) writeb(plink->write+address,val); + else ENTRY_writeb(plink->entry,address,val); +} + +INLINE void mem_writew_inline(PhysPt address,Bit16u val) { + if (address & 1) {mem_unalignedwritew(address,val);return;} + + PageLink * plink=GetPageLink(address); + + if (plink->write) writew(plink->write+address,val); + else ENTRY_writew(plink->entry,address,val); +} + +INLINE void mem_writed_inline(PhysPt address,Bit32u val) { + if (address & 3) {mem_unalignedwrited(address,val);return;} + + PageLink * plink=GetPageLink(address); + + if (plink->write) writed(plink->write+address,val); + else ENTRY_writed(plink->entry,address,val); +} + + +#endif \ No newline at end of file From 84b3d2d4c2a55893b08e573c2fd8c150aa337630 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 08:20:33 +0000 Subject: [PATCH 1033/4131] Changes for new allocation system Changes for new page mapping system Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1113 --- src/ints/ems.cpp | 239 ++++++++++------------------------------- src/ints/xms.cpp | 271 +++++++++++++---------------------------------- src/ints/xms.h | 3 - 3 files changed, 126 insertions(+), 387 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 52b8a6a3..063af139 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -22,6 +22,7 @@ #include "dosbox.h" #include "callback.h" #include "mem.h" +#include "paging.h" #include "bios.h" #include "keyboard.h" #include "regs.h" @@ -29,9 +30,8 @@ #include "dos_inc.h" #include "setup.h" -#define EMM_USEHANDLER 1 - #define EMM_PAGEFRAME 0xE000 +#define EMM_PAGEFRAME4K ((EMM_PAGEFRAME*16)/4096) #define EMM_MAX_HANDLES 50 /* 255 Max */ #define EMM_PAGE_SIZE (16*1024) #define EMM_MAX_PAGES (32 * 1024 / 16 ) @@ -82,26 +82,17 @@ struct EMM_Mapping { Bit16u page; }; -struct EMM_Page { - HostPt memory; - Bit16u handle; - Bit16u next; -}; - struct EMM_Handle { - Bit16u first_page; Bit16u pages; + MemHandle mem; char name[8]; bool saved_page_map; EMM_Mapping page_map[EMM_MAX_PHYS]; }; static EMM_Handle emm_handles[EMM_MAX_HANDLES]; -static EMM_Page emm_pages[EMM_MAX_PAGES]; static EMM_Mapping emm_mappings[EMM_MAX_PHYS]; -static HostPt emm_pagebase[EMM_MAX_PHYS]; -static Bitu emm_page_count; -Bitu call_int67; +static Bitu call_int67; struct MoveRegion { Bit32u bytes; @@ -115,26 +106,10 @@ struct MoveRegion { Bit16u dest_page_seg; }; -#if EMM_USEHANDLER -Bit8u EMM_ReadHandler(PhysPt start) { - start-=EMM_PAGEFRAME * 16; - Bitu page=start>>14; - return readb(emm_pagebase[page]+(start&0x3fff)); -} - -void EMM_WriteHandler(PhysPt start,Bit8u val) { - start-=EMM_PAGEFRAME * 16; - Bitu page=start>>14; - writeb(emm_pagebase[page]+(start&0x3fff),val); -} -#endif - static Bit16u EMM_GetFreePages(void) { - Bit16u count=0; - for (Bitu index=0;index0x7fff) count=0x7fff; + return (Bit16u)count; } static bool INLINE ValidHandle(Bit16u handle) { @@ -147,118 +122,47 @@ static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & handle) { /* Check for 0 page allocation */ if (!pages) return EMM_ZERO_PAGES; /* Check for enough free pages */ - if (EMM_GetFreePages()=EMM_MAX_HANDLES) {handle=NULL_HANDLE;return EMM_OUT_OF_HANDLES;} } - /* Allocate the pages */ - Bit16u page=0;Bit16u last=NULL_PAGE; + MemHandle mem=MEM_AllocatePages(pages*4,false); + if (!mem) E_Exit("EMS:Memory allocation failure"); emm_handles[handle].pages=pages; - while (pages) { - if (emm_pages[page].handle==NULL_HANDLE) { - emm_pages[page].handle=handle; - emm_pages[page].memory=(HostPt)malloc(EMM_PAGE_SIZE); - if (!emm_pages[page].memory) E_Exit("EMM:Cannont allocate memory"); - if (last!=NULL_PAGE) emm_pages[last].next=page; - else emm_handles[handle].first_page=page; - last=page; - pages--; - } else { - if (++page>=emm_page_count) E_Exit("EMM:Ran out of pages"); - } - } + emm_handles[handle].mem=mem; return EMM_NO_ERROR; } static Bit8u EMM_ReallocatePages(Bit16u handle,Bit16u & pages) { /* Check for valid handle */ - if (handle>=EMM_MAX_HANDLES || emm_handles[handle].pages==NULL_HANDLE) return EMM_INVALID_HANDLE; + if (!ValidHandle(handle)) return EMM_INVALID_HANDLE; /* Check for enough pages */ - if ((emm_handles[handle].pages+EMM_GetFreePages())0 && page_count>0) { - if (emm_pages[page].handle!=handle) E_Exit("EMM:Error illegal handle reference"); - last=page; - page=emm_pages[page].next; - pages--; - page_count--; - } - /* Free the rest of the handles */ - if (page_count && !pages) { - emm_handles[handle].pages-=page_count; - while (page_count>0) { - free(emm_pages[page].memory); - emm_pages[page].memory=0; - emm_pages[page].handle=NULL_HANDLE; - Bit16u next_page=emm_pages[page].next; - emm_pages[page].next=NULL_PAGE; - page=next_page;page_count--; - } - pages=emm_handles[handle].pages; - if (!pages) emm_handles[handle].first_page=NULL_PAGE; - return EMM_NO_ERROR; - } - if (!page_count && pages) { - /* Allocate extra pages */ - emm_handles[handle].pages+=pages; - page=0; - while (pages) { - if (emm_pages[page].handle==NULL_HANDLE) { - emm_pages[page].handle=handle; - emm_pages[page].memory=(HostPt)malloc(EMM_PAGE_SIZE); - if (!emm_pages[page].memory) E_Exit("EMM:Cannont allocate memory"); - if (last!=NULL_PAGE) emm_pages[last].next=page; - else emm_handles[handle].first_page=page; - last=page; - pages--; - } else { - if (++page>=emm_page_count) E_Exit("EMM:Ran out of pages"); - } - } - pages=emm_handles[handle].pages; - return EMM_NO_ERROR; - } - /* Size exactly the same as the original size */ - pages=emm_handles[handle].pages; + if (!MEM_ReAllocatePages(emm_handles[handle].mem,pages*4,false)) return EMM_OUT_OF_LOG; + /* Update size */ + emm_handles[handle].pages=pages; return EMM_NO_ERROR; } static Bit8u EMM_MapPage(Bitu phys_page,Bit16u handle,Bit16u log_page) { +// LOG_MSG("EMS MapPage handle %d phys %d log %d",handle,phys_page,log_page); /* Check for too high physical page */ if (phys_page>=EMM_MAX_PHYS) return EMM_ILL_PHYS; /* Check for valid handle */ - if (handle>=EMM_MAX_HANDLES || emm_handles[handle].pages==NULL_HANDLE) return EMM_INVALID_HANDLE; + if (!ValidHandle(handle)) return EMM_INVALID_HANDLE; /* Check to do unmapping or mappning */ if (log_page=EMM_MAX_HANDLES || emm_handles[handle].pages==NULL_HANDLE) return EMM_INVALID_HANDLE; - Bit16u page=emm_handles[handle].first_page; - Bit16u pages=emm_handles[handle].pages; - while (pages) { - free(emm_pages[page].memory); - emm_pages[page].memory=0; - emm_pages[page].handle=NULL_HANDLE; - Bit16u next_page=emm_pages[page].next; - emm_pages[page].next=NULL_PAGE; - page=next_page;pages--; - } + if (!ValidHandle(handle)) return EMM_INVALID_HANDLE; + MEM_ReleasePages(emm_handles[handle].mem); /* Reset handle */ - emm_handles[handle].first_page=NULL_PAGE; + emm_handles[handle].mem=0; emm_handles[handle].pages=NULL_HANDLE; emm_handles[handle].saved_page_map=false; memset(&emm_handles[handle].name,0,8); @@ -446,8 +341,8 @@ static void LoadMoveRegion(PhysPt data,MoveRegion & region) { static Bit8u MemoryRegion(void) { MoveRegion region; - Bit8u buf_src[EMM_PAGE_SIZE]; - Bit8u buf_dest[EMM_PAGE_SIZE]; + Bit8u buf_src[MEM_PAGE_SIZE]; + Bit8u buf_dest[MEM_PAGE_SIZE]; if (reg_al>1) { LOG(LOG_MISC,LOG_ERROR)("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); return EMM_FUNC_NOSUP; @@ -455,46 +350,43 @@ static Bit8u MemoryRegion(void) { LoadMoveRegion(SegPhys(ds)+reg_si,region); /* Parse the region for information */ PhysPt src_mem,dest_mem; - Bit16u src_page,dest_page;Bitu src_off,dest_off;Bitu src_remain,dest_remain; + MemHandle src_handle,dest_handle; + Bitu src_off,dest_off;Bitu src_remain,dest_remain; if (!region.src_type) { src_mem=region.src_page_seg*16+region.src_offset; } else { if (!ValidHandle(region.src_handle)) return EMM_INVALID_HANDLE; if (emm_handles[region.src_handle].pages*EMM_PAGE_SIZE < (region.src_page_seg*EMM_PAGE_SIZE)+region.src_offset+region.bytes) return EMM_LOG_OUT_RANGE; - src_page=emm_handles[region.src_handle].first_page; - while (region.src_page_seg>0) { - src_page=emm_pages[src_page].next; - region.src_page_seg--; - } - src_off=region.src_offset; - src_remain=EMM_PAGE_SIZE-src_off; + src_handle=emm_handles[region.src_handle].mem; + Bitu pages=region.src_page_seg*4+(region.src_offset/MEM_PAGE_SIZE); + for (;pages>0;pages--) src_handle=MEM_NextHandle(src_handle); + src_off=region.src_offset&(MEM_PAGE_SIZE-1); + src_remain=MEM_PAGE_SIZE-src_off; } if (!region.dest_type) { dest_mem=region.dest_page_seg*16+region.dest_offset; } else { if (!ValidHandle(region.dest_handle)) return EMM_INVALID_HANDLE; if (emm_handles[region.dest_handle].pages*EMM_PAGE_SIZE < (region.dest_page_seg*EMM_PAGE_SIZE)+region.dest_offset+region.bytes) return EMM_LOG_OUT_RANGE; - dest_page=emm_handles[region.dest_handle].first_page; - while (region.dest_page_seg>0) { - dest_page=emm_pages[dest_page].next; - region.dest_page_seg--; - } - dest_off=region.dest_offset; - dest_remain=EMM_PAGE_SIZE-dest_off; + dest_handle=emm_handles[region.dest_handle].mem; + Bitu pages=region.dest_page_seg*4+(region.dest_offset/MEM_PAGE_SIZE); + for (;pages>0;pages--) dest_handle=MEM_NextHandle(dest_handle); + dest_off=region.dest_offset&(MEM_PAGE_SIZE-1); + dest_remain=MEM_PAGE_SIZE-dest_off; } Bitu toread; while (region.bytes>0) { - if (region.bytes>EMM_PAGE_SIZE) toread=EMM_PAGE_SIZE; + if (region.bytes>MEM_PAGE_SIZE) toread=MEM_PAGE_SIZE; else toread=region.bytes; /* Read from the source */ if (!region.src_type) { MEM_BlockRead(src_mem,buf_src,toread); } else { if (toread(sec); - Bitu size=section->Get_int("emssize"); - if (!size) return; - if ((size*(1024/16))>EMM_MAX_PAGES) { - LOG_MSG("EMS Max size is %d",EMM_MAX_PAGES/(1024/16)); - emm_page_count=EMM_MAX_PAGES; - } else { - emm_page_count=size*(1024/16); - } + if (!section->Get_bool("ems")) return; call_int67=CALLBACK_Allocate(); CALLBACK_Setup(call_int67,&INT67_Handler,CB_IRET); /* Register the ems device */ @@ -709,13 +593,8 @@ void EMS_Init(Section* sec) { RealSetVec(0x67,RealMake(seg,0)); /* Clear handle and page tables */ Bitu i; - for (i=0;i=XMS_HANDLES) || xms_handles[handle].free); +} + Bitu XMS_QueryFreeMemory(Bit16u& largestFree, Bit16u& totalFree) { /* Scan the tree for free memory and find largest free block */ - Bit16u index=1; - largestFree=totalFree=0; - while (xms_handles[index].active) { - if (!xms_handles[index].allocated) { - if (xms_handles[index].size>largestFree) largestFree=xms_handles[index].size; - totalFree+=xms_handles[index].size; - } - if (xms_handles[index].next=size) { - /* Check if block is bigger than request */ - if (xms_handles[index].size>size) { - /* Split Block, find new handle and split up memory */ - Bit16u new_index=1; - while (new_indexXMS_HANDLES) return XMS_OUT_OF_HANDLES; } - /* Found no good blocks give some errors */ - return XMS_OUT_OF_SPACE; + Bitu pages=(size/4) + (size & 3) ? 1 : 0; + MemHandle mem=MEM_AllocatePages(pages,true); + if (!mem) return XMS_OUT_OF_SPACE; + xms_handles[index].free=false; + xms_handles[index].mem=mem; + xms_handles[index].locked=0; + xms_handles[index].size=size; + handle=index; + return 0; }; Bitu XMS_FreeMemory(Bitu handle) { - /* Check for a valid handle */ - if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { - return XMS_INVALID_HANDLE; - } - /* Free the memory in the block and merge the blocks previous and next block */ - Bit16u prev=xms_handles[handle].prev; - Bit16u next=xms_handles[handle].next; - xms_handles[handle].allocated=0; - if ((next=XMS_HANDLES) || !xms_handles[block.src_handle].active ||!xms_handles[block.src_handle].allocated) { + /* Read the block with mem_read's */ + Bitu length=mem_readd(bpt+offsetof(XMS_MemMove,length)); + Bitu src_handle=mem_readw(bpt+offsetof(XMS_MemMove,src_handle)); + union { + RealPt realpt; + Bit32u offset; + } src,dest; + src.offset=mem_readd(bpt+offsetof(XMS_MemMove,src.offset)); + Bitu dest_handle=mem_readw(bpt+offsetof(XMS_MemMove,dest_handle)); + dest.offset=mem_readd(bpt+offsetof(XMS_MemMove,dest.offset)); + PhysPt srcpt,destpt; + if (src_handle) { + if (InvalidHandle(src_handle)) { return 0xa3; /* Src Handle invalid */ } - if (block.src.offset>=(xms_handles[block.src_handle].size*1024U)) { + if (src.offset>=(xms_handles[src_handle].size*1024U)) { return 0xa4; /* Src Offset invalid */ } - if (block.length>xms_handles[block.src_handle].size*1024U-block.src.offset) { + if (length>xms_handles[src_handle].size*1024U-src.offset) { return 0xa7; /* Length invalid */ } - src=xms_handles[block.src_handle].phys+block.src.offset; + srcpt=(xms_handles[src_handle].mem*4096)+src.offset; } else { - src=Real2Phys(block.src.realpt); + srcpt=Real2Phys(src.realpt); } - if (block.dest_handle) { - if ((block.dest_handle>=XMS_HANDLES) || !xms_handles[block.dest_handle].active ||!xms_handles[block.dest_handle].allocated) { + if (dest_handle) { + if (InvalidHandle(dest_handle)) { return 0xa3; /* Dest Handle invalid */ } - if (block.dest.offset>=(xms_handles[block.dest_handle].size*1024U)) { + if (dest.offset>=(xms_handles[dest_handle].size*1024U)) { return 0xa4; /* Dest Offset invalid */ } - if (block.length>xms_handles[block.dest_handle].size*1024U-block.dest.offset) { + if (length>xms_handles[dest_handle].size*1024U-dest.offset) { return 0xa7; /* Length invalid */ } - dest=xms_handles[block.dest_handle].phys+block.dest.offset; + destpt=(xms_handles[dest_handle].mem*4096)+dest.offset; } else { - dest=Real2Phys(block.dest.realpt); + destpt=Real2Phys(dest.realpt); } - MEM_BlockCopy(dest,src,block.length); +// LOG_MSG("XMS move src %X dest %X length %X",srcpt,destpt,length); + mem_memcpy(destpt,srcpt,length); return 0; } Bitu XMS_LockMemory(Bitu handle, Bit32u& address) { - /* Check for a valid handle */ - if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { - return XMS_INVALID_HANDLE; - } + if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; if (xms_handles[handle].locked<255) xms_handles[handle].locked++; - address = xms_handles[handle].phys; + address = xms_handles[handle].mem*4096; return 0; }; Bitu XMS_UnlockMemory(Bitu handle) { - /* Check for a valid handle */ - if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { - return XMS_INVALID_HANDLE; - } + if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; if (xms_handles[handle].locked) { xms_handles[handle].locked--; return 0; @@ -259,94 +208,27 @@ Bitu XMS_UnlockMemory(Bitu handle) Bitu XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFree, Bit16u& size) { - /* Check for a valid handle */ - if (!handle || (handle>=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { - return XMS_INVALID_HANDLE; - } + if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; lockCount = xms_handles[handle].locked; /* Find available blocks */ - numFree=0;{ for (Bitu i=1;i=XMS_HANDLES) || !xms_handles[handle].active || !xms_handles[handle].allocated ) { - return XMS_INVALID_HANDLE; - } + if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; // Block has to be unlocked if (xms_handles[handle].locked>0) return XMS_BLOCK_LOCKED; - - if (newSize=XMS_HANDLES) return XMS_OUT_OF_HANDLES; - xms_handles[newindex].active = true; - xms_handles[newindex].allocated = false; - xms_handles[newindex].locked = 0; - xms_handles[newindex].prev = handle; - xms_handles[newindex].next = next; - xms_handles[newindex].phys = xms_handles[handle].phys+newSize*1024; - xms_handles[newindex].size = sizeDelta; - - xms_handles[handle] .next = newindex; - if (nextxms_handles[handle].size) { - // Lets see if successor has enough free space to do that - Bit16u oldSize = xms_handles[handle].size; - Bit16u next = xms_handles[handle].next; - Bit16u sizeDelta = newSize - xms_handles[handle].size; - if (nextsizeDelta) { - // remove size from it - xms_handles[next].size-=sizeDelta; - xms_handles[next].phys+=sizeDelta*1024; - } else if (xms_handles[next].size==sizeDelta) { - // exact match, skip it - xms_handles[handle].next = xms_handles[next].next; - xms_handles[next].active = false; - } else { - // Not enough mem available - LOG(LOG_MISC,LOG_ERROR)("XMS: Resize failure: out of mem 1"); - return XMS_OUT_OF_SPACE; - }; - // Resize and allocate new mem - xms_handles[handle].size = newSize; - xms_handles[handle].allocated = 1; - //CheckAllocationArea(xms_handles[handle].phys,xms_handles[handle].size*1024); - } else { - // No more free mem ? - LOG(LOG_MISC,LOG_ERROR)("XMS: Resize failure: out of mem 2"); - return XMS_OUT_OF_SPACE; - }; - }; - return 0; -}; - -// Return size of xms mem in mb -static Bitu xms_size = 0; -Bitu XMS_GetSize(void) { return xms_size; }; + Bitu pages=newSize/4 + (newSize & 3) ? 1 : 0; + if (MEM_ReAllocatePages(xms_handles[handle].mem,pages,true)) { + return 0; + } else return XMS_OUT_OF_SPACE; +} static bool multiplex_xms(void) { switch (reg_ax) { @@ -448,33 +330,22 @@ Bitu XMS_Handler(void) { } void XMS_Init(Section* sec) { + Section_prop * section=static_cast(sec); - Bitu size=section->Get_int("xmssize"); - if (!size) return; - Bitu memavail=(MEM_TotalSize()-1088)/1024; + if (!section->Get_bool("ems")) return; + Bitu i; - if (size>memavail) size=memavail; - xms_size = size; DOS_AddMultiplexHandler(multiplex_xms); call_xms=CALLBACK_Allocate(); CALLBACK_Setup(call_xms,&XMS_Handler,CB_RETF); xms_callback=CALLBACK_RealPointer(call_xms); - /* Setup the handler table */ - Bitu i; for (i=0;i Date: Mon, 14 Jul 2003 08:23:32 +0000 Subject: [PATCH 1034/4131] Some changes for correct memory region setup in gfx registers. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1114 --- src/ints/int10_modes.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 970c2a0e..b716e043 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -334,7 +334,7 @@ foundmode: switch (CurMode->type) { case M_TEXT16: gfx_data[0x5]|=0x10; //Odd-Even Mode - gfx_data[0x6]|=0x0e; //alphanumeric mode at 0xb800=0xbffff + gfx_data[0x6]|=0x0e; //alphanumeric mode at 0xb800=0xbfff break; case M_LIN8: case M_VGA: @@ -344,9 +344,11 @@ foundmode: case M_EGA16: gfx_data[0x6]|=0x05; //graphics mode at 0xa000-affff break; + case M_CGA2: case M_CGA4: + case M_TANDY16: gfx_data[0x5]|=0x20; //CGA mode - gfx_data[0x6]|=0x05; //graphics mode at 0xa000-affff + gfx_data[0x6]|=0x0f; //graphics mode at at 0xb800=0xbfff break; } for (i=0;i Date: Mon, 14 Jul 2003 08:24:42 +0000 Subject: [PATCH 1035/4131] Use phys_write for access to rom memory. Remove usage of HostPt while reading the fonts. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1115 --- src/ints/int10_char.cpp | 11 +++++------ src/ints/int10_memory.cpp | 18 ++++++++++-------- src/ints/int10_vesa.cpp | 9 +++++---- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 2865267e..4f799a1f 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -180,7 +180,6 @@ void INT10_SetActivePage(Bit8u page) { mem_address=page*CurMode->plength; /* Write the new page start */ real_writew(BIOSMEM_SEG,BIOSMEM_CURRENT_START,mem_address); - if (CurMode->mode<8) mem_address>>=1; /* Write the new start address in vgahardware */ IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0c); @@ -278,7 +277,7 @@ void INT10_ReadCharAttr(Bit16u * result,Bit8u page) { static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useattr) { - Bit8u * fontdata; + PhysPt fontdata; Bitu x,y; switch (CurMode->type) { case M_TEXT16: @@ -295,14 +294,14 @@ static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool return; case M_CGA4: case M_CGA2: - if (chr<128) fontdata=Real2Host(RealGetVec(0x43))+chr*8; + if (chr<128) fontdata=Real2Phys(RealGetVec(0x43))+chr*8; else { chr-=128; - fontdata=Real2Host(RealGetVec(0x1F))+(chr)*8; + fontdata=Real2Phys(RealGetVec(0x1F))+(chr)*8; } break; default: - fontdata=Real2Host(RealGetVec(0x43))+chr*real_readw(0x40,BIOSMEM_CHAR_HEIGHT); + fontdata=Real2Phys(RealGetVec(0x43))+chr*real_readw(0x40,BIOSMEM_CHAR_HEIGHT); break; } x=8*col; @@ -310,7 +309,7 @@ static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool //TODO Check for out of bounds for (Bit8u h=0;hcheight;h++) { Bit8u bitsel=128; - Bit8u bitline=*fontdata++; + Bit8u bitline=mem_readb(fontdata); Bit16u tx=x; while (bitsel) { if (bitline&bitsel) INT10_PutPixel(tx,y,page,attr); diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 1370fb0a..af827cec 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -72,33 +72,35 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu - void INT10_SetupRomMemory(void) { /* This should fill up certain structures inside the Video Bios Rom Area */ + PhysPt rom_base=PhysMake(0xc000,0); Bitu i; int10.rom.used=2; - real_writew(0xc000,0,0xaa55); + phys_writew(rom_base+0,0xaa55); int10.rom.font_8_first=RealMake(0xC000,int10.rom.used); for (i=0;i<128*8;i++) { - real_writeb(0xC000,int10.rom.used++,int10_font_08[i]); + phys_writeb(rom_base+int10.rom.used++,int10_font_08[i]); } int10.rom.font_8_second=RealMake(0xC000,int10.rom.used); for (i=0;i<128*8;i++) { - real_writeb(0xC000,int10.rom.used++,int10_font_08[i+128*8]); + phys_writeb(rom_base+int10.rom.used++,int10_font_08[i+128*8]); } int10.rom.font_14=RealMake(0xC000,int10.rom.used); for (i=0;i<256*14;i++) { - real_writeb(0xC000,int10.rom.used++,int10_font_14[i]); + phys_writeb(rom_base+int10.rom.used++,int10_font_14[i]); } int10.rom.font_16=RealMake(0xC000,int10.rom.used); for (i=0;i<256*16;i++) { - real_writeb(0xC000,int10.rom.used++,int10_font_16[i]); + phys_writeb(rom_base+int10.rom.used++,int10_font_16[i]); } int10.rom.static_state=RealMake(0xC000,int10.rom.used); for (i=0;i<0x10;i++) { - real_writeb(0xC000,int10.rom.used++,static_functionality[i]); + phys_writeb(rom_base+int10.rom.used++,static_functionality[i]); + } + for (i=0;i<128*8;i++) { + phys_writeb(PhysMake(0xf000,0xfa6e)+i,int10_font_08[i]); } - MEM_BlockWrite(PhysMake(0xf000,0xfa6e),int10_font_08,128*8); RealSetVec(0x1F,int10.rom.font_8_second); }; diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 007441cb..91d7a1ea 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -281,17 +281,18 @@ void INT10_SetupVESA(void) { //TODO Maybe add normal vga modes too, but only seems to complicate things while (ModeList[i].mode!=0xffff) { if (ModeList[i].mode>=0x100){ - real_writew(0xc000,int10.rom.used,ModeList[i].mode); + phys_writew(PhysMake(0xc000,int10.rom.used),ModeList[i].mode); int10.rom.used+=2; } i++; } - real_writew(0xc000,int10.rom.used,0xffff); + phys_writew(PhysMake(0xc000,int10.rom.used),0xffff); int10.rom.used+=2; int10.rom.oemstring=RealMake(0xc000,int10.rom.used); Bitu len=strlen(oemstring)+1; - MEM_BlockWrite(PhysMake(0xc000,int10.rom.used),oemstring,len); - int10.rom.used+=len; + for (i=0;i Date: Mon, 14 Jul 2003 08:25:18 +0000 Subject: [PATCH 1036/4131] use phys_write for setting up callback in rom area. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1116 --- src/ints/mouse.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 5f24a7dc..be956dfb 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -649,11 +649,11 @@ void CreateMouseCallback(void) // Create a mouse vector with weird address // for strange mouse detection routines in Sim City & Wasteland Bit16u ofs = call_int33<<4; - real_writeb((Bit16u)CB_SEG,ofs+0,(Bit8u)0x90); //NOP - real_writeb((Bit16u)CB_SEG,ofs+1,(Bit8u)0xFE); //GRP 4 - real_writeb((Bit16u)CB_SEG,ofs+2,(Bit8u)0x38); //Extra Callback instruction - real_writew((Bit16u)CB_SEG,ofs+3,call_int33); //The immediate word - real_writeb((Bit16u)CB_SEG,ofs+5,(Bit8u)0xCF); //An IRET Instruction + phys_writeb(CB_BASE+ofs+0,(Bit8u)0x90); //NOP + phys_writeb(CB_BASE+ofs+1,(Bit8u)0xFE); //GRP 4 + phys_writeb(CB_BASE+ofs+2,(Bit8u)0x38); //Extra Callback instruction + phys_writew(CB_BASE+ofs+3,call_int33); //The immediate word + phys_writeb(CB_BASE+ofs+5,(Bit8u)0xCF); //An IRET Instruction // Write weird vector WriteMouseIntVector(); }; From 35188cb6c8532bdcc64e1824d3ac3774ef5fd71b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 08:26:07 +0000 Subject: [PATCH 1037/4131] use phys_write for rom area. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1117 --- src/cpu/callback.cpp | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index fe649d03..0dd180f7 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -121,23 +121,23 @@ bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type) { if (callback>=CB_MAX) return false; switch (type) { case CB_RETF: - real_writeb((Bit16u)CB_SEG,(callback<<4)+0,(Bit8u)0xFE); //GRP 4 - real_writeb((Bit16u)CB_SEG,(callback<<4)+1,(Bit8u)0x38); //Extra Callback instruction - real_writew((Bit16u)CB_SEG,(callback<<4)+2,callback); //The immediate word - real_writeb((Bit16u)CB_SEG,(callback<<4)+4,(Bit8u)0xCB); //A RETF Instruction + phys_writeb(CB_BASE+(callback<<4)+0,(Bit8u)0xFE); //GRP 4 + phys_writeb(CB_BASE+(callback<<4)+1,(Bit8u)0x38); //Extra Callback instruction + phys_writew(CB_BASE+(callback<<4)+2,callback); //The immediate word + phys_writeb(CB_BASE+(callback<<4)+4,(Bit8u)0xCB); //A RETF Instruction break; case CB_IRET: - real_writeb((Bit16u)CB_SEG,(callback<<4)+0,(Bit8u)0xFE); //GRP 4 - real_writeb((Bit16u)CB_SEG,(callback<<4)+1,(Bit8u)0x38); //Extra Callback instruction - real_writew((Bit16u)CB_SEG,(callback<<4)+2,callback); //The immediate word - real_writeb((Bit16u)CB_SEG,(callback<<4)+4,(Bit8u)0xCF); //An IRET Instruction + phys_writeb(CB_BASE+(callback<<4)+0,(Bit8u)0xFE); //GRP 4 + phys_writeb(CB_BASE+(callback<<4)+1,(Bit8u)0x38); //Extra Callback instruction + phys_writew(CB_BASE+(callback<<4)+2,callback); //The immediate word + phys_writeb(CB_BASE+(callback<<4)+4,(Bit8u)0xCF); //An IRET Instruction break; case CB_IRET_STI: - real_writeb((Bit16u)CB_SEG,(callback<<4)+0,(Bit8u)0xFB); //STI - real_writeb((Bit16u)CB_SEG,(callback<<4)+1,(Bit8u)0xFE); //GRP 4 - real_writeb((Bit16u)CB_SEG,(callback<<4)+2,(Bit8u)0x38); //Extra Callback instruction - real_writew((Bit16u)CB_SEG,(callback<<4)+3,callback); //The immediate word - real_writeb((Bit16u)CB_SEG,(callback<<4)+5,(Bit8u)0xCF); //An IRET Instruction + phys_writeb(CB_BASE+(callback<<4)+0,(Bit8u)0xFB); //STI + phys_writeb(CB_BASE+(callback<<4)+1,(Bit8u)0xFE); //GRP 4 + phys_writeb(CB_BASE+(callback<<4)+2,(Bit8u)0x38); //Extra Callback instruction + phys_writew(CB_BASE+(callback<<4)+3,callback); //The immediate word + phys_writeb(CB_BASE+(callback<<4)+5,(Bit8u)0xCF); //An IRET Instruction break; default: @@ -185,16 +185,16 @@ void CALLBACK_Init(Section* sec) { /* Setup the Stop Handler */ call_stop=CALLBACK_Allocate(); CallBack_Handlers[call_stop]=stop_handler; - real_writeb((Bit16u)CB_SEG,(call_stop<<4)+0,0xFE); - real_writeb((Bit16u)CB_SEG,(call_stop<<4)+1,0x38); - real_writew((Bit16u)CB_SEG,(call_stop<<4)+2,call_stop); + phys_writeb(CB_BASE+(call_stop<<4)+0,0xFE); + phys_writeb(CB_BASE+(call_stop<<4)+1,0x38); + phys_writew(CB_BASE+(call_stop<<4)+2,call_stop); /* Setup the idle handler */ call_idle=CALLBACK_Allocate(); CallBack_Handlers[call_idle]=stop_handler; - for (i=0;i<=11;i++) real_writeb((Bit16u)CB_SEG,(call_idle<<4)+i,0x90); - real_writeb((Bit16u)CB_SEG,(call_idle<<4)+12,0xFE); - real_writeb((Bit16u)CB_SEG,(call_idle<<4)+13,0x38); - real_writew((Bit16u)CB_SEG,(call_idle<<4)+14,call_idle); + for (i=0;i<=11;i++) phys_writeb(CB_BASE+(call_idle<<4)+i,0x90); + phys_writeb(CB_BASE+(call_idle<<4)+12,0xFE); + phys_writeb(CB_BASE+(call_idle<<4)+13,0x38); + phys_writew(CB_BASE+(call_idle<<4)+14,call_idle); /* Setup all Interrupt to point to the default handler */ call_default=CALLBACK_Allocate(); @@ -204,7 +204,7 @@ void CALLBACK_Init(Section* sec) { real_writed(0,i*4,CALLBACK_RealPointer(call_default)); } real_writed(0,0x67*4,CALLBACK_RealPointer(call_default)); - + real_writed(0,0xf*4,0); } From a1993a714cc450fade903fd9753ebba1ea10b32b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 08:32:22 +0000 Subject: [PATCH 1038/4131] Call paging functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1118 --- src/cpu/cpu.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 6d23c9b1..cc0bd791 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -23,6 +23,7 @@ #include "debug.h" #include "keyboard.h" #include "setup.h" +#include "paging.h" #if 1 #undef LOG_MSG @@ -556,14 +557,18 @@ bool CPU_SET_CRX(Bitu cr,Bitu value) { Bitu changed=cpu.cr0 ^ value; if (!changed) return true; cpu.cr0=value; - if (value & CR0_PAGING) LOG_MSG("Paging enabled"); if (value & CR0_PROTECTION) { LOG_MSG("Protected mode"); + PAGING_Enable((value & CR0_PAGING)>0); } else { + PAGING_Enable(false); LOG_MSG("Real mode"); } return CPU_CheckState(); } + case 3: + PAGING_SetDirBase(value); + break; default: LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV CR%d,%X",cr,value); break; @@ -575,6 +580,8 @@ Bitu CPU_GET_CRX(Bitu cr) { switch (cr) { case 0: return cpu.cr0; + case 3: + return PAGING_GetDirBase(); default: LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV XXX, CR%d",cr); break; From 93c6c0c803a1d31142dc110e8a08481921592f2a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 08:32:39 +0000 Subject: [PATCH 1039/4131] Main paging handler. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1119 --- src/cpu/paging.cpp | 250 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 src/cpu/paging.cpp diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp new file mode 100644 index 00000000..d8fdc8fa --- /dev/null +++ b/src/cpu/paging.cpp @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + +#include "dosbox.h" +#include "mem.h" +#include "paging.h" +#include "../hardware/vga.h" + + +#define LINK_TOTAL (64*1024) + +static PageLink link_list[LINK_TOTAL]; +struct PagingBlock paging; + +class PageDirChange : public PageChange { +public: + PageDirChange(PageDirectory * mydir) { dir=mydir;} + void Changed(PageLink * link,Bitu start,Bitu end) { + start>>=2;end>>=2; + for (;start<=end;start++) { + dir->InvalidateTable(start); + } + } +private: + PageDirectory * dir; +}; + +class PageTableChange : public PageChange { +public: + PageTableChange(PageDirectory * mydir) { dir=mydir;} + void Changed(PageLink * link,Bitu start,Bitu end) { + start>>=2;end>>=2; + for (;start<=end;start++) { + dir->InvalidateLink(link->data.table,start); + } + } +private: + PageDirectory * dir; +}; + + + +PageDirectory::PageDirectory() { + entry_init.data.dir=this; + entry_init.type=ENTRY_INIT; + link_init.read=0; + link_init.write=0; + link_init.entry=&entry_init; + table_change = new PageTableChange(this); + dir_change = new PageDirChange(this); +} +PageDirectory::~PageDirectory() { + delete table_change; + delete dir_change; +} +void PageDirectory::ClearDirectory(void) { + Bitu i; + for (i=0;i<1024*1024;i++) links[i]=&link_init; + for (i=0;i<1024;i++) { + tables[i]=0; + } +} +void PageDirectory::SetBase(PhysPt page) { + base_page=page; + ClearDirectory(); + /* Setup handler for PageDirectory changes */ + link_dir=MEM_LinkPage(base_page,0); + if (!link_dir) E_Exit("PageDirectory setup on illegal address"); + link_dir->data.dir=this; + link_dir->change=dir_change; + MEM_CheckLinks(link_dir->entry); +} +void PageDirectory::LinkPage(Bitu lin_page,Bitu phys_page) { + if (links[lin_page] != &link_init) MEM_UnlinkPage(links[lin_page]); + PageLink * link=MEM_LinkPage(phys_page,lin_page*4096); + if (link) links[lin_page]=link; + else links[lin_page]=&link_init; +} + +bool PageDirectory::InitPage(Bitu lin_address) { + Bitu lin_page=lin_address >> 12; + Bitu table=lin_page >> 10; + Bitu index=lin_page & 0x3ff; + /* Check if there already is table linked */ + if (!tables[table]) { + X86PageEntry table_entry; + table_entry.load=phys_page_readd(base_page,0); + if (!table_entry.block.p) { + LOG(LOG_PAGING,LOG_ERROR)("NP TABLE"); + return false; + } + PageLink * link=MEM_LinkPage(table_entry.block.base,table_entry.block.base); + if (!link) return false; + link->data.table=table; + link->change=table_change; + MEM_CheckLinks(link->entry); + tables[table]=link; + } + X86PageEntry entry; + entry.load=phys_page_readd(tables[table]->lin_base,index); + if (!entry.block.p) { + LOG(LOG_PAGING,LOG_ERROR)("NP PAGE"); + return false; + } + PageLink * link=MEM_LinkPage(entry.block.base,lin_page*4096); + if (!link) return false; + links[lin_page]=link; + return true; +} + + +bool PageDirectory::InitPageLinear(Bitu lin_address) { + Bitu phys_page=lin_address >> 12; + PageLink * link=MEM_LinkPage(phys_page,phys_page*4096); + if (link) { + /* Set the page entry in our table */ + links[phys_page]=link; + return true; + } + return false; +} + + +void PageDirectory::InvalidateTable(Bitu table) { + if (tables[table]) { + MEM_UnlinkPage(tables[table]); + tables[table]=0; + for (Bitu i=(table*1024);i<(table+1)*1024;i++) { + if (links[i]!=&link_init) { + MEM_UnlinkPage(links[i]); + links[i]=&link_init; + } + } + } +} + +void PageDirectory::InvalidateLink(Bitu table,Bitu index) { + Bitu i=(table*1024)+index; + if (links[i]!=&link_init) { + MEM_UnlinkPage(links[i]); + links[i]=&link_init; + } +} + + +Bitu PAGING_GetDirBase(void) { + return paging.cr3; +} + +void PAGING_SetDirBase(Bitu cr3) { + paging.cr3=cr3; + Bitu base_page=cr3 >> 12; + LOG_MSG("CR3:%X Base %X",cr3,base_page); + if (paging.enabled) { + /* Check if we already have this one cached */ + PageDirectory * dir=paging.cache; + while (dir) { + if (dir->base_page==base_page) { + paging.dir=dir; + return; + } + dir=dir->next; + } + /* Couldn't find cached directory, make a new one */ + dir=new PageDirectory(); + dir->next=paging.cache; + paging.cache=dir; + dir->SetBase(base_page); + paging.dir=dir; + } +} + +void PAGING_Enable(bool enabled) { + /* If paging is disable we work from a default paging table */ + if (paging.enabled==enabled) return; + paging.enabled=enabled; + if (!enabled) { + LOG_MSG("Paging disabled"); + paging.dir=MEM_DefaultDirectory(); + } else { + LOG_MSG("Paging enabled"); + PAGING_SetDirBase(paging.cr3); + } +} + +bool PAGING_Enabled(void) { + return paging.enabled; +} + + +void PAGING_FreePageLink(PageLink * link) { + MEM_UnlinkPage(link); + PAGING_AddFreePageLink(link); +} + +void PAGING_LinkPage(PageDirectory * dir,Bitu lin_page,Bitu phys_page) { + PageLink * link=MEM_LinkPage(phys_page,lin_page*4096); + /* Only replace if we can */ + if (link) { + PAGING_FreePageLink(dir->links[lin_page]); + dir->links[lin_page]=link; + } +} + +void PAGING_AddFreePageLink(PageLink * link) { + link->read=0; + link->write=0; + link->change=0; + link->next=paging.free_link; + link->entry=0; + paging.free_link=link; +} + +PageLink * PAGING_GetFreePageLink(void) { + PageLink * ret; + if (paging.free_link) ret=paging.free_link; + else E_Exit("PAGING:Ran out of PageEntries"); + paging.free_link=ret->next; + ret->next=0; + return ret; +} + +void PAGING_Init(Section * sec) { + Bitu i; + /* Setup the free pages tables for fast page allocation */ + paging.cache=0; + paging.free_link=0; + for (i=0;i Date: Mon, 14 Jul 2003 08:35:28 +0000 Subject: [PATCH 1040/4131] Support for paged memory and handlers on changes to those pages. On demand allocation of memory Setup a range for linear frame buffer Handle ROM/VGA memory sections. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1120 --- src/hardware/memory.cpp | 964 +++++++++++++++++++++++++++++++--------- 1 file changed, 762 insertions(+), 202 deletions(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 6e38b63c..53f6039c 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -20,240 +20,752 @@ #include #include #include + #include "dosbox.h" #include "mem.h" #include "inout.h" #include "setup.h" +#include "paging.h" +#include "vga.h" -/* Maximum memory address range in megabytes */ -#define MEM_SIZE 32 -#define MAX_PAGES PAGE_COUNT((2+MEM_SIZE)*1024*1024) +#define PAGES_IN_BLOCK ((1024*1024)/MEM_PAGE_SIZE) +#define MAX_MEMORY 64 +#define LFB_PAGES 512 +static Bit8u controlport_data; +static bool a20_enabled; +struct AllocBlock { + Bit8u data[PAGES_IN_BLOCK*4096]; + AllocBlock * next; +}; -HostPt memory; -HostPt ReadHostTable[MAX_PAGES]; -HostPt WriteHostTable[MAX_PAGES]; -MEMORY_ReadHandler ReadHandlerTable[MAX_PAGES]; -MEMORY_WriteHandler WriteHandlerTable[MAX_PAGES]; +static struct MemoryBlock { + Bitu pages; + Bitu free_pages; + PageEntry * entries; + struct { + Bitu pages; + HostPt cur_page; + AllocBlock *cur_block; + } block; + struct { + Bitu start_page; + Bitu end_page; + Bitu pages; + HostPt address; + PageEntry entries[LFB_PAGES]; + } lfb; + struct { + HostPt ram_bases[128/4]; + HostPt map_base; + VGA_RANGES range; + } vga; + PageDirectory dir; +} memory; -static Bitu total_size; +Bit8u ENTRY_readb(PageEntry * pentry,PhysPt address) { + switch(pentry->type) { + case ENTRY_VGA: + return (*vga.config.readhandler)(pentry->data.vga_base+(address & 4095)); + case ENTRY_NA: + if (pentry->data.dir->InitPageLinear(address)) return mem_readb(address); + break; + case ENTRY_INIT: + if (pentry->data.dir->InitPage(address)) return mem_readb(address); + break; -/* Page handlers only work in lower memory */ + default: + LOG(LOG_PAGING,LOG_ERROR)("Entry read from %X with illegal type %d",address,pentry->type); + } + return 0; +} -void MEM_BlockRead(PhysPt off,void * data,Bitu size) { - Bit8u * idata=(Bit8u *)data; - while (size>0) { - Bitu page=off >> PAGE_SHIFT; - Bitu start=off & (PAGE_SIZE-1); - Bitu tocopy=PAGE_SIZE-start; - if (tocopy>size) tocopy=size; - size-=tocopy; - if (ReadHostTable[page]) { - memcpy(idata,ReadHostTable[page]+off,tocopy); - idata+=tocopy;off+=tocopy; - } else { - for (;tocopy>0;tocopy--) *idata++=ReadHandlerTable[page](off++); +Bit16u ENTRY_readw(PageEntry * pentry,PhysPt address) { + switch(pentry->type) { + case ENTRY_VGA: + { + VGA_ReadHandler * handler=vga.config.readhandler; + address=pentry->data.vga_base + (address & 4095); + return (*handler)(address) | + ((*handler)(address+1) << 8); } + case ENTRY_NA: + if (pentry->data.dir->InitPageLinear(address)) return mem_readw(address); + break; + case ENTRY_INIT: + if (pentry->data.dir->InitPage(address)) return mem_readw(address); + break; + default: + LOG(LOG_PAGING,LOG_ERROR)("Entry read from %X with illegal type %d",address,pentry->type); + } + return 0; +} + +Bit32u ENTRY_readd(PageEntry * pentry,PhysPt address) { + switch(pentry->type) { + case ENTRY_VGA: + { + VGA_ReadHandler * handler=vga.config.readhandler; + address=pentry->data.vga_base + (address & 4095); + return (*handler)(address) | + ((*handler)(address+1) << 8) | + ((*handler)(address+2) << 16) | + ((*handler)(address+3) << 24); + } + case ENTRY_NA: + if (pentry->data.dir->InitPageLinear(address)) return mem_readd(address); + break; + case ENTRY_INIT: + if (pentry->data.dir->InitPage(address)) return mem_readd(address); + break; + default: + LOG(LOG_PAGING,LOG_ERROR)("Entry read from %X with illegal type %d",address,pentry->type); + } + return 0; +} + +void ENTRY_writeb(PageEntry * pentry,PhysPt address,Bit8u val) { + switch(pentry->type) { + case ENTRY_VGA: + (*vga.config.writehandler)(pentry->data.vga_base+(address&4095),val); + break; + case ENTRY_NA: + if (pentry->data.dir->InitPageLinear(address)) mem_writeb(address,val); + break; + case ENTRY_INIT: + if (pentry->data.dir->InitPage(address)) mem_writeb(address,val); + break; + case ENTRY_ROM: + LOG(LOG_PAGING,LOG_WARN)("Write %X to ROM at %X",val,address); + break; + case ENTRY_CHANGES: + writeb(pentry->data.mem+(address&4095),val); + { + Bitu start=address&4095;Bitu end=start; + for (PageLink * link=pentry->links;link;link=link->next) + if (link->change) link->change->Changed(link,start,end); + } + break; + default: + LOG(LOG_PAGING,LOG_ERROR)("Entry write %X to %X with illegal type %d",val,address,pentry->type); } } -void MEM_BlockWrite(PhysPt off,void * data,Bitu size) { - Bit8u * idata=(Bit8u *)data; - while (size>0) { - Bitu page=off >> PAGE_SHIFT; - Bitu start=off & (PAGE_SIZE-1); - Bitu tocopy=PAGE_SIZE-start; - if (tocopy>size) tocopy=size; - size-=tocopy; - if (WriteHostTable[page]) { - memcpy(WriteHostTable[page]+off,idata,tocopy); - idata+=tocopy;off+=tocopy; - } else { - for (;tocopy>0;tocopy--) WriteHandlerTable[page](off++,*idata++); +void ENTRY_writew(PageEntry * pentry,PhysPt address,Bit16u val) { + switch(pentry->type) { + case ENTRY_VGA: + { + VGA_WriteHandler * handler=vga.config.writehandler; + address=pentry->data.vga_base+(address&4095); + (*handler)(address,(Bit8u)val); + (*handler)(address+1,(Bit8u)(val>>8)); } + break; + case ENTRY_NA: + if (pentry->data.dir->InitPageLinear(address)) mem_writew(address,val); + break; + case ENTRY_INIT: + if (pentry->data.dir->InitPage(address)) mem_writew(address,val); + break; + case ENTRY_ROM: + LOG(LOG_PAGING,LOG_WARN)("Write %X to ROM at %X",val,address); + break; + case ENTRY_CHANGES: + writew(pentry->data.mem+(address&4095),val); + { + Bitu start=address&4095;Bitu end=start+1; + for (PageLink * link=pentry->links;link;link=link->next) + if (link->change) link->change->Changed(link,start,end); + } + break; + default: + LOG(LOG_PAGING,LOG_ERROR)("Entry write %X to %X with illegal type %d",val,address,pentry->type); + } +} + + +void ENTRY_writed(PageEntry * pentry,PhysPt address,Bit32u val) { + switch(pentry->type) { + case ENTRY_VGA: + { + VGA_WriteHandler * handler=vga.config.writehandler; + address=pentry->data.vga_base+(address&4095); + (*handler)(address,(Bit8u)val); + (*handler)(address+1,(Bit8u)(val>>8)); + (*handler)(address+2,(Bit8u)(val>>16)); + (*handler)(address+3,(Bit8u)(val>>24)); + } + break; + case ENTRY_NA: + if (pentry->data.dir->InitPageLinear(address)) mem_writed(address,val); + break; + case ENTRY_INIT: + if (pentry->data.dir->InitPage(address)) mem_writed(address,val); + break; + case ENTRY_ROM: + LOG(LOG_PAGING,LOG_WARN)("Write %X to ROM at %X",val,address); + break; + case ENTRY_CHANGES: + writed(pentry->data.mem+(address&4095),val); + { + Bitu start=address&4095;Bitu end=start+3; + for (PageLink * link=pentry->links;link;link=link->next) + if (link->change) link->change->Changed(link,start,end); + } + break; + default: + LOG(LOG_PAGING,LOG_ERROR)("Entry write %X to %X with illegal type %d",val,address,pentry->type); + } +} + + +Bitu mem_strlen(PhysPt pt) { + Bitu x=0; + while (x<1024) { + if (!mem_readb_inline(pt+x)) return x; + x++; + } + return 0; //Hope this doesn't happend +} + +void mem_strcpy(PhysPt dest,PhysPt src) { + Bit8u r; + while (r=mem_readb(src++)) mem_writeb_inline(dest++,r); + mem_writeb_inline(dest,0); +} + +void mem_memcpy(PhysPt dest,PhysPt src,Bitu size) { + while (size--) mem_writeb_inline(dest++,mem_readb_inline(src++)); +} + +void MEM_BlockRead(PhysPt pt,void * data,Bitu size) { + Bit8u * write=(Bit8u *) data; + while (size--) { + *write++=mem_readb_inline(pt++); + } +} + +void MEM_BlockWrite(PhysPt pt,void * data,Bitu size) { + Bit8u * read=(Bit8u *) data; + while (size--) { + mem_writeb_inline(pt++,*read++); } } void MEM_BlockCopy(PhysPt dest,PhysPt src,Bitu size) { - Bitu c; - for (c=1;c<=(size>>2);c++) { - mem_writed(dest,mem_readd(src)); - dest+=4;src+=4; + mem_memcpy(dest,src,size); +} + +void MEM_StrCopy(PhysPt pt,char * data,Bitu size) { + while (size--) { + Bit8u r=mem_readb_inline(pt++); + if (!r) break; + *data++=r; } - for (c=1;c<=(size&3);c++) { - mem_writeb(dest,mem_readb(src)); - dest+=1;src+=1; + *data=0; +} + +Bitu MEM_TotalPages(void) { + return memory.pages; +} + +void MEM_UnlinkPage(PageLink * plink) { + PageLink * checker=plink->entry->links; + PageLink * * last=&plink->entry->links; + while (checker) { + if (checker == plink) { + *last=plink->next; + PAGING_AddFreePageLink(plink); + return; + } + last=&checker->next; + checker=checker->next; } -}; + E_Exit("Unlinking unlinked link"); + +} -void MEM_StrCopy(PhysPt off,char * data,Bitu size) { - Bit8u c; - while ((c=mem_readb(off)) && size) { - *data=c; - off++;data++;size--; +PageLink * MEM_LinkPage(Bitu phys_page,PhysPt lin_base) { + PageEntry * entry; + /* Check if it's in a valid memory range */ + if (phys_page=memory.lfb.start_page && phys_page(val),pt); -} - -/* Could only be called when the pt host entry is 0 ah well :) */ -static Bit8u Default_ReadHandler(PhysPt pt) { - return readb(WriteHostTable[pt >> PAGE_SHIFT]+pt); -} -static void Default_WriteHandler(PhysPt pt,Bit8u val) { - writeb(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); + PageLink * link=PAGING_GetFreePageLink(); + link->lin_base=lin_base; + link->change=0; + /* Check what kind of handler we need to give the page */ + switch (entry->type) { + case ENTRY_RAM: + link->read=entry->data.mem - lin_base; + link->write=link->read; + break; + case ENTRY_ROM: + link->read=entry->data.mem - lin_base; + link->write=0; + break; + case ENTRY_VGA: + link->read=0; + link->write=0; + break; + case ENTRY_LFB: + link->read=entry->data.mem - lin_base; + link->write=link->read; + break; + case ENTRY_ALLOC: + entry->type=ENTRY_RAM; + entry->data.mem=MEM_GetBlockPage(); + link->read=entry->data.mem - lin_base; + link->write=link->read; + break; + case ENTRY_CHANGES: + link->read=entry->data.mem - lin_base; + link->write=0; + break; + default: + E_Exit("LinkPage:Illegal type %d",entry->type); + } + /* Place the entry in the link */ + link->entry=entry; + link->next=entry->links; + entry->links=link; + return link; } -void MEM_SetupPageHandlers(Bitu startpage,Bitu pages,MEMORY_ReadHandler read,MEMORY_WriteHandler write) { - if (startpage+pages>MAX_PAGES) E_Exit("Memory:Illegal page for handler"); - for (Bitu i=startpage;itype!=ENTRY_RAM && theentry->type!=ENTRY_CHANGES) { + LOG(LOG_PAGING,LOG_NORMAL)("Checking links on type %d",theentry->type); + return; + } + bool haschange=false;PageLink * link; + for (link=theentry->links;link;link=link->next) { + if (link->change) { + haschange=true;break; + } + } + if (haschange) { + theentry->type=ENTRY_CHANGES; + for (link=theentry->links;link;link=link->next) { + link->read=theentry->data.mem - link->lin_base; + link->write=0; + } + } else { + theentry->type=ENTRY_RAM; + for (link=theentry->links;link;link=link->next) { + link->read=theentry->data.mem - link->lin_base; + link->write=link->read; + } } } +void MEM_AllocLinkMemory(PageEntry * theentry) { + //TODO Maybe check if this is a LINK_ALLOC type + HostPt themem=MEM_GetBlockPage(); + theentry->data.mem=themem; + theentry->type=ENTRY_RAM; + theentry->links=0; +} -void MEM_ClearPageHandlers(Bitu startpage,Bitu pages) { - if (startpage+pages>MAX_PAGES) E_Exit("Memory:Illegal page for handler"); - for (Bitu i=startpage;iLFB_PAGES) E_Exit("MEM:LFB to large"); + LOG_MSG("LFB Base at %X",page*4096); + memory.lfb.pages=pages; + memory.lfb.start_page=page; + memory.lfb.end_page=page+pages; + memory.lfb.address=pt; + for (Bitu i=0;idata.mem=themem; + theentry->type=ENTRY_LFB; + PageLink * link=theentry->links; + while (link) { + link->read=themem - link->lin_base; + link->write=link->read; + link=link->next; + } + } + memory.vga.range=range; + } + /* Setup the new range, check if it's gonna handler based */ + Bitu start,end; + switch (range) { + case VGA_RANGE_A000:start=0;end=16;break; + case VGA_RANGE_B000:start=16;end=24;break; + case VGA_RANGE_B800:start=24;end=32;break; + } + if (base) { + /* If it has an address it's a mapping */ + for (i=start;itype=ENTRY_LFB; + theentry->data.mem=themem; + PageLink * link=theentry->links; + while (link) { + link->read=themem - link->lin_base; + link->write=link->read; + link=link->next; + } + } + } else { + /* No address, so it'll be a handler */ + for (i=start;itype=ENTRY_VGA; + PhysPt thebase=(i-start)*4096; + PageLink * link=theentry->links; + theentry->data.vga_base=thebase; + while (link) { + link->read=0; + link->write=0; + link=link->next; + } + } } } -void MEM_SetupMapping(Bitu startpage,Bitu pages,void * data) { - if (startpage+pages>MAX_PAGES) E_Exit("Memory:Illegal page for handler"); - HostPt base=(HostPt)(data)-startpage*PAGE_SIZE; - if (!base) LOG_MSG("MEMORY:Unlucky memory allocation"); - for (Bitu i=startpage;ilargest) largest=size; + size=0; + } + index++; + } + if (size>largest) largest=size; + return largest; +} + + +Bitu MEM_FreeTotal(void) { + Bitu free=0; + Bitu index=XMS_START; + while (indexsize) { + if (pages=size) && (index-first0) { + MemHandle next=memory.entries[handle].next_handle; + memory.entries[handle].next_handle=0; + handle=next; } } -void MEM_ClearMapping(Bitu startpage,Bitu pages) { - if (startpage+pages>MAX_PAGES) E_Exit("Memory:Illegal page for handler"); - for (Bitu i=startpage;i0) { + old_pages++; + last=index; + index=memory.entries[index].next_handle; + } + if (old_pages == pages) return true; + if (old_pages > pages) { + /* Decrease size */ + pages--;index=handle;old_pages--; + while (pages) { + index=memory.entries[index].next_handle; + pages--;old_pages--; + } + MemHandle next=memory.entries[index].next_handle; + memory.entries[index].next_handle=-1; + index=next; + while (old_pages) { + next=memory.entries[index].next_handle; + memory.entries[index].next_handle=0; + index=next; + old_pages--; + } + return true; + } else { + /* Increase size, check for enough free space */ + Bitu need=pages-old_pages; + if (sequence) { + index=last+1; + Bitu free=0; + while ((index=need) { + /* Enough space allocate more pages */ + index=last; + while (need) { + memory.entries[index].next_handle=index+1; + need--;index++; + } + memory.entries[index].next_handle=-1; + return true; + } else { + /* Not Enough space allocate new block and copy */ + MemHandle newhandle=MEM_AllocatePages(pages,true); + if (!newhandle) return false; + MEM_BlockCopy(newhandle*4096,handle*4096,old_pages*4096); + MEM_ReleasePages(handle); + handle=newhandle; + return true; + } + } else { + MemHandle rem=MEM_AllocatePages(need,false); + if (!rem) return false; + memory.entries[last].next_handle=rem; + return true; + } + } + return 0; +} + + +void MEM_UnmapPages(Bitu phys_page,Bitu pages) { + for (;pages;pages--) { + memory.dir.LinkPage(phys_page,phys_page); + phys_page++; } } -static void HandlerWritew(Bitu page,PhysPt pt,Bit16u val) { - WriteHandlerTable[page](pt+0,(Bit8u)(val & 0xff)); - WriteHandlerTable[page](pt+1,(Bit8u)((val >> 8) & 0xff) ); -} - -static void HandlerWrited(Bitu page,PhysPt pt,Bit32u val) { - WriteHandlerTable[page](pt+0,(Bit8u)(val & 0xff)); - WriteHandlerTable[page](pt+1,(Bit8u)((val >> 8) & 0xff) ); - WriteHandlerTable[page](pt+2,(Bit8u)((val >> 16) & 0xff) ); - WriteHandlerTable[page](pt+3,(Bit8u)((val >> 24) & 0xff) ); -} - -void mem_writeb(PhysPt pt,Bit8u val) { - if (WriteHostTable[pt >> PAGE_SHIFT]) writeb(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); - else { - WriteHandlerTable[pt >> PAGE_SHIFT](pt,val); +void MEM_MapPages(Bitu phys_page,MemHandle mem,Bitu mem_page,Bitu pages) { + for (;mem_page;mem_page--) { + if (mem<=0) E_Exit("MEM:MapPages:Fault in memory tables"); + mem=memory.entries[mem].next_handle; + } + for (;pages;pages--) { + if (mem<=0) E_Exit("MEM:MapPages:Fault in memory tables"); + memory.dir.LinkPage(phys_page++,mem); + mem=memory.entries[mem].next_handle; } } -void mem_writew(PhysPt pt,Bit16u val) { - if (!WriteHostTable[pt >> PAGE_SHIFT]) { - WriteHandlerTable[pt >> PAGE_SHIFT](pt+0,(Bit8u)(val & 0xff)); - WriteHandlerTable[pt >> PAGE_SHIFT](pt+1,(Bit8u)((val >> 8) & 0xff) ); - } else writew(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); +MemHandle MEM_NextHandle(MemHandle handle) { + return memory.entries[handle].next_handle; } -void mem_writed(PhysPt pt,Bit32u val) { - if (!WriteHostTable[pt >> PAGE_SHIFT]) { - WriteHandlerTable[pt >> PAGE_SHIFT](pt+0,(Bit8u)(val & 0xff)); - WriteHandlerTable[pt >> PAGE_SHIFT](pt+1,(Bit8u)((val >> 8) & 0xff) ); - WriteHandlerTable[pt >> PAGE_SHIFT](pt+2,(Bit8u)((val >> 16) & 0xff) ); - WriteHandlerTable[pt >> PAGE_SHIFT](pt+3,(Bit8u)((val >> 24) & 0xff) ); - } else writed(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); -} - - -static Bit16u HandlerReadw(Bitu page,PhysPt pt) { - return (ReadHandlerTable[page](pt+0)) | - (ReadHandlerTable[page](pt+1)) << 8; -} - -static Bit32u HandlerReadd(Bitu page,PhysPt pt) { - return (ReadHandlerTable[page](pt+0)) | - (ReadHandlerTable[page](pt+1)) << 8 | - (ReadHandlerTable[page](pt+2)) << 16 | - (ReadHandlerTable[page](pt+3)) << 24; -} - -Bit8u mem_readb(PhysPt pt) { - if (ReadHostTable[pt >> PAGE_SHIFT]) return readb(ReadHostTable[pt >> PAGE_SHIFT]+pt); - else { - return ReadHandlerTable[pt >> PAGE_SHIFT](pt); - } -} - -Bit16u mem_readw(PhysPt pt) { - if (!ReadHostTable[pt >> PAGE_SHIFT]) { - return - (ReadHandlerTable[pt >> PAGE_SHIFT](pt+0)) | - (ReadHandlerTable[pt >> PAGE_SHIFT](pt+1)) << 8; - } else return readw(ReadHostTable[pt >> PAGE_SHIFT]+pt); -} - -Bit32u mem_readd(PhysPt pt){ - if (ReadHostTable[pt >> PAGE_SHIFT]) return readd(ReadHostTable[pt >> PAGE_SHIFT]+pt); - else { - return - (ReadHandlerTable[pt >> PAGE_SHIFT](pt+0)) | - (ReadHandlerTable[pt >> PAGE_SHIFT](pt+1)) << 8 | - (ReadHandlerTable[pt >> PAGE_SHIFT](pt+2)) << 16 | - (ReadHandlerTable[pt >> PAGE_SHIFT](pt+3)) << 24; - } -} - - -/* A20 Line Handling */ -static Bit8u controlport_data = 0; -static bool a20_enabled; - +/* + A20 line handling, + Basically maps the 4 pages at the 1mb to 0mb in the default page directory +*/ bool MEM_A20_Enabled(void) { return a20_enabled; } -void MEM_A20_Enable(bool enable) { - if (a20_enabled==enable) return; - a20_enabled=enable; - if (enable) { - MEM_SetupMapping(PAGE_COUNT(1024*1024),PAGE_COUNT(64*1024),((Bit8u*)memory)+1024*1024); +void MEM_A20_Enable(bool enabled) { + a20_enabled=enabled; + Bitu i; + if (!enabled) { + for (i=0x0;i<0x10;i++) { + memory.dir.LinkPage(0x100+i,i); + } } else { - MEM_SetupMapping(PAGE_COUNT(1024*1024),PAGE_COUNT(64*1024),memory); + for (i=0x0;i<0x10;i++) { + memory.dir.LinkPage(0x100+i,0x100+i); + } } - LOG(LOG_MISC,LOG_NORMAL)("A20 Line is %s",enable ? "Enabled" : "Disabled"); } -Bitu MEM_TotalSize(void) { - return total_size; + +/* Memory access functions */ +Bit16u mem_unalignedreadw(PhysPt address) { + return mem_readb_inline(address) | + mem_readb_inline(address+1) << 8; } +Bit32u mem_unalignedreadd(PhysPt address) { + return mem_readb_inline(address) | + (mem_readb_inline(address+1) << 8) | + (mem_readb_inline(address+2) << 16) | + (mem_readb_inline(address+3) << 24); +} + + +void mem_unalignedwritew(PhysPt address,Bit16u val) { + mem_writeb_inline(address,(Bit8u)val);val>>=8; + mem_writeb_inline(address+1,(Bit8u)val); +} + +void mem_unalignedwrited(PhysPt address,Bit32u val) { + mem_writeb_inline(address,(Bit8u)val);val>>=8; + mem_writeb_inline(address+1,(Bit8u)val);val>>=8; + mem_writeb_inline(address+2,(Bit8u)val);val>>=8; + mem_writeb_inline(address+3,(Bit8u)val); +} + + +Bit8u mem_readb(PhysPt address) { + return mem_readb_inline(address); +} + +Bit16u mem_readw(PhysPt address) { + return mem_readw_inline(address); +} + +Bit32u mem_readd(PhysPt address) { + return mem_readd_inline(address); +} + +void mem_writeb(PhysPt address,Bit8u val) { + mem_writeb_inline(address,val); +} + +void mem_writew(PhysPt address,Bit16u val) { + mem_writew_inline(address,val); +} + +void mem_writed(PhysPt address,Bit32u val) { + mem_writed_inline(address,val); +} + +void phys_writeb(PhysPt addr,Bit8u val) { + Bitu page=addr>>12; + if (page>=memory.pages) E_Exit("physwrite:outside of physical range"); + PageEntry * theentry=&memory.entries[page]; + switch (theentry->type) { + case ENTRY_ALLOC: + MEM_AllocLinkMemory(theentry); + break; + case ENTRY_RAM: + case ENTRY_ROM: + break; + default: + E_Exit("physwrite:illegal type %d",theentry->type); + } + writeb(theentry->data.mem+(addr & 4095),val); +} + +void phys_writew(PhysPt addr,Bit16u val) { + phys_writeb(addr,(Bit8u)val); + phys_writeb(addr+1,(Bit8u)(val >> 8)); +} + +void phys_writed(PhysPt addr,Bit32u val) { + phys_writeb(addr,(Bit8u)val); + phys_writeb(addr+1,(Bit8u)(val >> 8)); + phys_writeb(addr+2,(Bit8u)(val >> 16)); + phys_writeb(addr+3,(Bit8u)(val >> 24)); +} + +Bit32u phys_page_readd(Bitu page,Bitu index) { + if (page>=memory.pages) E_Exit("physwrite:outside of physical range"); + PageEntry * theentry=&memory.entries[page]; + switch (theentry->type) { + case ENTRY_CHANGES: + case ENTRY_RAM: + case ENTRY_ROM: + return readd(memory.entries[page].data.mem+index*4); + break; + default: + E_Exit("pageread:illegal type %d",theentry->type); + } + return 0; +} + + static void write_p92(Bit32u port,Bit8u val) { // Bit 0 = system reset (switch back to real mode) if (val&1) E_Exit("XMS: CPU reset via port 0x92 not supported."); @@ -265,42 +777,90 @@ static Bit8u read_p92(Bit32u port) { return controlport_data | (a20_enabled ? 0x02 : 0); } + +PageDirectory * MEM_DefaultDirectory(void) { + return &memory.dir; +} + +HostPt MEM_GetBlockPage(void) { + HostPt ret; + if (memory.block.pages) { + ret=memory.block.cur_page; + memory.block.pages--; + memory.block.cur_page+=4096; + } else { + AllocBlock * newblock=new AllocBlock; + memset(newblock,0,sizeof(AllocBlock)); //zero new allocated memory + newblock->next=memory.block.cur_block; + memory.block.cur_block=newblock; + + memory.block.pages=PAGES_IN_BLOCK-1; + ret=&newblock->data[0]; + memory.block.cur_page=&newblock->data[4096]; + } + return ret; +} + static void MEM_ShutDown(Section * sec) { - free(memory); - memory=0; -}; + AllocBlock * theblock=memory.block.cur_block; + while (theblock) { + AllocBlock * next=theblock->next; + delete theblock; + theblock=next; + } +} void MEM_Init(Section * sec) { + Bitu i; Section_prop * section=static_cast(sec); - /* Clear paging tables */ - MEM_SetupPageHandlers(0,MAX_PAGES,Illegal_ReadHandler,Illegal_WriteHandler); - /* Allocate memory and setup tables */ + /* Setup Memory Block */ + memory.block.pages=0; + memory.block.cur_block=0; + + /* Setup the Physical Page Links */ Bitu memsize=section->Get_int("memsize"); + if (memsize<1) memsize=1; - if (memsize>MEM_SIZE) { - LOG_MSG("Maximum memory size is %d MB",MEM_SIZE); - memsize=MEM_SIZE; + if (memsize>MAX_MEMORY) { + LOG_MSG("Maximum memory size is %d MB",MAX_MEMORY); + memsize=MAX_MEMORY; } - total_size=memsize*1024; - memory=(Bit8u *)malloc(memsize*1024*1024+64*1024); - if (!memory) { - throw("Can't allocate memory for memory"); + memory.pages=(memsize*1024*1024)/4096; + if (memory.pages>0x110) memory.free_pages=memory.pages-0x110; + else memory.free_pages=0; + + memory.entries= new PageEntry[memory.pages]; + for (i=0;i1) { - MEM_SetupMapping(PAGE_COUNT((1024+64)*1024),PAGE_COUNT((((memsize-1)*1024)-64)*1024),memory+(1024+64)*1024); + /* Setup 128kb of memory for the VGA segments */ + for (i=0;i<128/4;i++) { + memory.vga.ram_bases[i]=MEM_GetBlockPage(); + memory.entries[0xa0+i].type=ENTRY_LFB; + memory.entries[0xa0+i].data.mem=memory.vga.ram_bases[i]; + } + memory.vga.range=VGA_RANGE_B800; + /* Setup the default page mapping */ + memory.dir.entry_init.type=ENTRY_NA; //Setup to use NA by default + memory.dir.ClearDirectory(); + /* All pages now pointing to NA handler that will check on first access */ + /* Setup the ROM Areas */ + for (i=0xc0;i<0xd0;i++) { + MEM_AllocLinkMemory(&memory.entries[i]); + memory.entries[i].type=ENTRY_ROM; + } + for (i=0xf0;i<0x100;i++) { + MEM_AllocLinkMemory(&memory.entries[i]); + memory.entries[i].type=ENTRY_ROM; } // A20 Line - PS/2 system control port A IO_RegisterWriteHandler(0x92,write_p92,"Control Port"); IO_RegisterReadHandler(0x92,read_p92,"Control Port"); + MEM_A20_Enable(false); /* shutdown function */ sec->AddDestroyFunction(&MEM_ShutDown); } From 74676d9bb7ab14635ca5172f5ef9d2c4b2bd264c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 08:36:12 +0000 Subject: [PATCH 1041/4131] Memory size now reported in 4kb blocks Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1121 --- src/hardware/cmos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 8d15b2ed..bf179069 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -191,7 +191,7 @@ void CMOS_Init(Section* sec) { cmos.reg=0xb; cmos_writereg(0x71,0); /* Fill in extended memory size */ - Bitu exsize=MEM_TotalSize()-1024; + Bitu exsize=(MEM_TotalPages()*4)-1024; cmos.regs[0x17]=(Bit8u)exsize; cmos.regs[0x18]=(Bit8u)(exsize >> 8); cmos.regs[0x30]=(Bit8u)exsize; From 4d26f08a37a611079013be4fe9dc75c722693e5f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 08:39:40 +0000 Subject: [PATCH 1042/4131] Support for setting linear frame buffer base. New way of setting up vga read/write handler or frame buffer. No longer use HostPt memory for certain video modes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1122 --- src/hardware/vga.h | 15 ++++++- src/hardware/vga_crtc.cpp | 8 ++++ src/hardware/vga_draw.cpp | 12 ++--- src/hardware/vga_gfx.cpp | 14 +----- src/hardware/vga_memory.cpp | 89 ++++++++++++++++++++----------------- 5 files changed, 76 insertions(+), 62 deletions(-) diff --git a/src/hardware/vga.h b/src/hardware/vga.h index c3a7f9b0..6f928bbb 100644 --- a/src/hardware/vga.h +++ b/src/hardware/vga.h @@ -48,6 +48,10 @@ enum VGAModes { #define MH_SETRESET 0x0002; #define MH_BITMASK 0x0004; + +typedef Bit8u VGA_ReadHandler(PhysPt off); +typedef void VGA_WriteHandler(PhysPt off,Bit8u val); + typedef struct { bool attrindex; } VGA_Internal; @@ -78,7 +82,10 @@ typedef struct { Bit8u bytes_skip; /* Specific stuff memory write/read handling */ - PhysPt mem_base; + + VGA_ReadHandler * readhandler; + VGA_WriteHandler * writehandler; + Bit8u read_mode; Bit8u write_mode; Bit8u read_map_select; @@ -128,6 +135,7 @@ typedef struct { Bit8u reg_55; Bit8u ex_hor_overflow; Bit8u ex_ver_overflow; + Bit16u la_window; struct { Bit8u r; Bit8u n; @@ -262,13 +270,15 @@ typedef struct { VGA_Memory mem; } VGA_Type; + + /* Functions for different resolutions */ void VGA_SetMode(VGAModes mode); void VGA_SetupHandlers(void); void VGA_StartResize(void); void VGA_SetupDrawing(void); -/* Some support functions */ +/* Some DAC/Attribute functions */ void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal); void VGA_ATTR_SetPalette(Bit8u index,Bit8u val); @@ -285,6 +295,7 @@ void VGA_SetupSEQ(void); void VGA_SetClock(Bitu which,Bitu target); void VGA_DACSetEntirePalette(void); void VGA_StartRetrace(void); +void VGA_StartUpdateLFB(void); extern VGA_Type vga; diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index fe704ed2..13280529 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -422,6 +422,14 @@ void write_p3d5(Bit32u port,Bit8u val) { 7 (928) RAS 6-MCLK. If set the random read/write cycle time is 6MCLKs, if clear 7MCLKs */ + case 0x59: /* Linear Address Window Position Low */ + vga.s3.la_window=(vga.s3.la_window&0xff00) | val; + VGA_StartUpdateLFB(); + break; + case 0x5a: /* Linear Address Window Position High */ + vga.s3.la_window=(vga.s3.la_window&0x00ff) | (val << 8); + VGA_StartUpdateLFB(); + break; case 0x5D: /* Extended Horizontal Overflow */ if ((val & vga.s3.ex_hor_overflow) ^ 3) { vga.s3.ex_hor_overflow=val; diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index ca517d30..59ae43ec 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -26,8 +26,8 @@ //TODO Make the full draw like the vga really does from video memory. static void VGA_CGA2_Draw(Bit8u * bitdata,Bitu pitch) { - Bit8u * reader=HostMake(0xB800,0); - Bit8u * flip=HostMake(0xB800,8*1024); + Bit8u * reader=&vga.mem.linear[0]; + Bit8u * flip=&vga.mem.linear[8*1024]; Bit8u * draw; for (Bitu y=0;y> 2) & 3) { - case 0: - case 1: - vga.config.mem_base=0xa0000; - break; - case 2: - vga.config.mem_base=0xb0000; - break; - case 3: - vga.config.mem_base=0xb8000; - break; - } - if (vga.mode==M_TEXT16) VGA_SetupHandlers(); + VGA_SetupHandlers(); /* 0 Indicates Graphics Mode if set, Alphanumeric mode else. 1 Enables Odd/Even mode if set. diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index f87385d2..5f8fe67e 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -24,10 +24,10 @@ #include "dosbox.h" #include "mem.h" #include "vga.h" - +#include "paging.h" +#include "pic.h" static Bit8u VGA_NormalReadHandler(PhysPt start) { - start-=0xa0000; vga.latch.d=vga.mem.latched[start].d; switch (vga.config.read_mode) { case 0: @@ -56,7 +56,6 @@ INLINE static Bit32u RasterOp(Bit32u input,Bit32u mask) { return 0; } - INLINE static Bit32u ModeOperation(Bit8u val) { Bit32u full; switch (vga.config.write_mode) { @@ -84,26 +83,7 @@ INLINE static Bit32u ModeOperation(Bit8u val) { return full; } -static Bit8u VGA_CGA_4_ReadHandler(PhysPt start) { - return vga.mem.linear[start-0xb8000]; -} - -static void VGA_CGA_4_WriteHandler(PhysPt start,Bit8u val) { - start-=0xb8000; - vga.mem.linear[start]=val; - Bitu off; - if (start>0x2000) off=320*(((start-0x2000)/80)*2+1)+((start-0x2000) % 80)*4; - else off=320*(((start)/80)*2)+(start % 80)*4; - Bit32u * draw=(Bit32u *)&vga.mem.linear[512*1024+off]; - /* TODO Could also use a Bit32u lookup table for this */ - *draw=CGA_4_Table[val]; - draw=(Bit32u *)&vga.mem.linear[512*1024+off+0x4000*4]; - *draw=CGA_4_Table[val]; - -} - static void VGA_GFX_16_WriteHandler(PhysPt start,Bit8u val) { - start-=0xa0000; val=(val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate)); Bit32u data=ModeOperation(val); /* Update video memory and the pixel buffer */ @@ -135,7 +115,6 @@ static void VGA_GFX_16_WriteHandler(PhysPt start,Bit8u val) { } static void VGA_GFX_256U_WriteHandler(PhysPt start,Bit8u val) { - start-=0xa0000; Bit32u data=ModeOperation(val); // Bit32u data=ExpandTable[val]; VGA_Latch pixels; @@ -147,7 +126,6 @@ static void VGA_GFX_256U_WriteHandler(PhysPt start,Bit8u val) { } static void VGA_TEXT16_Write(PhysPt start,Bit8u val) { - start-=vga.config.mem_base; /* Check for page 2 being enabled for writing */ if (vga.seq.map_mask & 0x4) { vga.draw.font[start]=val; @@ -156,53 +134,82 @@ static void VGA_TEXT16_Write(PhysPt start,Bit8u val) { } static Bit8u VGA_TEXT16_Read(PhysPt start) { - start-=vga.config.mem_base; return vga.draw.font[start]; } void VGA_SetupHandlers(void) { - /* Sets up the correct memory handler from the vga.mode setting */ - MEM_ClearPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x20000)); + HostPt where; switch (vga.mode) { case M_LIN8: - MEM_SetupMapping(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000),&vga.mem.linear[vga.s3.bank*64*1024]); + where=&vga.mem.linear[vga.s3.bank*64*1024]; break; case M_VGA: if (vga.config.chained) { - MEM_SetupMapping(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000),&vga.mem.linear[vga.s3.bank*64*1024]); + where=&vga.mem.linear[vga.s3.bank*64*1024]; } else { - MEM_SetupPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000), - &VGA_NormalReadHandler,&VGA_GFX_256U_WriteHandler); + vga.config.readhandler=&VGA_NormalReadHandler, + vga.config.writehandler=&VGA_GFX_256U_WriteHandler; + where=0; } break; case M_EGA16: - MEM_SetupPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000), - &VGA_NormalReadHandler,&VGA_GFX_16_WriteHandler); + vga.config.readhandler=&VGA_NormalReadHandler, + vga.config.writehandler=&VGA_GFX_16_WriteHandler; + where=0; break; case M_TEXT16: /* Check if we're not in odd/even mode */ - if (vga.gfx.miscellaneous & 0x2) break; - MEM_SetupPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000),&VGA_TEXT16_Read,&VGA_TEXT16_Write); - //Could also do it using 0xb8000, let's double map - MEM_SetupPageHandlers(PAGE_COUNT(0xb8000),PAGE_COUNT(0x8000),&VGA_TEXT16_Read,&VGA_TEXT16_Write); + if (vga.gfx.miscellaneous & 0x2) { + where=&vga.mem.linear[0]; + } else { + vga.config.readhandler=&VGA_TEXT16_Read; + vga.config.writehandler=&VGA_TEXT16_Write; + where=0; + } break; case M_TANDY16: - MEM_SetupMapping(PAGE_COUNT(0xb8000),PAGE_COUNT(0x8000),&vga.mem.linear[vga.tandy.mem_bank << 14]); + where=&vga.mem.linear[vga.tandy.mem_bank << 14]; break; case M_CGA4: case M_CGA2: + where=&vga.mem.linear[0]; break; default: LOG_MSG("Unhandled vga mode %X",vga.mode); } + VGA_RANGES range; + switch ((vga.gfx.miscellaneous >> 2) & 3) { + case 0: + case 1: + range=VGA_RANGE_A000; + break; + case 2: + range=VGA_RANGE_B000; + break; + case 3: + range=VGA_RANGE_B800; + break; + } + MEM_SetupVGA(range,where); } +bool lfb_update; +static void VGA_DoUpdateLFB(void) { + lfb_update=false; + MEM_SetLFB(vga.s3.la_window << 4,sizeof(vga.mem.linear)/4096,&vga.mem.linear[0]); +} - +void VGA_StartUpdateLFB(void) { + if (!lfb_update) { + lfb_update=true; + PIC_AddEvent(VGA_DoUpdateLFB,2000); //2 milliseconds later + } +} void VGA_SetupMemory() { memset((void *)&vga.mem,0,512*1024*4); - /* Map linear frame buffer at 32 mb */ - MEM_SetupMapping(PAGE_COUNT(32*1024*1024),PAGE_COUNT(2*1024*1024),&vga.mem); + /* Setup linear window to some initial value */ + vga.s3.la_window=0xc000; + VGA_DoUpdateLFB(); } From 63933fcad4e5ecea90a7270d5d69894e1936e840 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 08:40:20 +0000 Subject: [PATCH 1043/4131] New LOG_PAGING target Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1123 --- src/debug/debug_gui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 40a886c9..840233ce 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -175,6 +175,7 @@ void LOG_StartUp(void) { loggrp[LOG_FPU].front="FPU"; loggrp[LOG_CPU].front="CPU"; + loggrp[LOG_PAGING].front="PAGING"; loggrp[LOG_FCB].front="FCB"; loggrp[LOG_FILES].front="FILES"; From 96bece4cca08feb2f56664953fbba8e0412bc3ef Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 08:41:52 +0000 Subject: [PATCH 1044/4131] Remove usage of HostPt while going through environment strings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1124 --- src/misc/programs.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 2fcaedb2..111699da 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -80,14 +80,16 @@ Program::Program() { /* Find the command line and setup the PSP */ psp = new DOS_PSP(dos.psp); /* Scan environment for filename */ - char * envscan=(char *)HostMake(psp->GetEnvironment(),0); - while (*envscan) envscan+=strlen(envscan)+1; + PhysPt envscan=PhysMake(psp->GetEnvironment(),0); + while (mem_readb(envscan)) envscan+=mem_strlen(envscan)+1; envscan+=3; CommandTail tail; MEM_BlockRead(PhysMake(dos.psp,128),&tail,128); if (tail.count<127) tail.buffer[tail.count]=0; else tail.buffer[126]=0; - cmd = new CommandLine(envscan,tail.buffer); + char filename[256]; + MEM_StrCopy(envscan,filename,256); + cmd = new CommandLine(filename,tail.buffer); } void Program::WriteOut(const char * format,...) { From f6062818d39cceaf83ab46d4a2d94ec5663e2986 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 08:42:37 +0000 Subject: [PATCH 1045/4131] Remove old memory size defines Enable C_MODEM by default Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1125 --- src/platform/visualc/config.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 45bb58be..51b6dc26 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -8,6 +8,9 @@ /* Define to 1 to enable screenshots, requires libpng */ #define C_SSHOT 1 +/* Define to 1 to enable internal modem support, requires SDL_net */ +#define C_MODEM 1 + /* Enable some heavy debugging options */ #define C_HEAVY_DEBUG 0 @@ -15,7 +18,7 @@ #define C_EXTRAINLINE 0 /* Enable the FPU module, still only for beta testing */ -#define C_FPU 0 +#define C_FPU 1 /* environ is defined */ #define ENVIRON_INCLUDED 1 @@ -23,7 +26,4 @@ /* environ can be linked */ #define ENVIRON_LINKED 1 -/* Maximum memory address range in megabytes */ -#define C_MEM_MAX_SIZE 12 - #define GCC_ATTRIBUTE(x) /* attribute not supported */ From a44c5064d10107bd21f9128691f8e224b2dd02db Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 08:46:01 +0000 Subject: [PATCH 1046/4131] init's for modem/serial/paging. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1126 --- src/dosbox.cpp | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index a1b07714..65120b05 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -44,6 +44,7 @@ Bitu errorlevel=1; void MSG_Init(Section_prop *); void LOG_StartUp(void); void MEM_Init(Section *); +void PAGING_Init(Section *); void IO_Init(Section * ); void CALLBACK_Init(Section*); void PROGRAMS_Init(Section*); @@ -75,6 +76,8 @@ void PCSPEAKER_Init(Section*); void TANDYSOUND_Init(Section*); void CMS_Init(Section*); void DISNEY_Init(Section*); +void SERIAL_Init(Section*); +void MODEM_Init(Section*); void PIC_Init(Section*); void TIMER_Init(Section*); @@ -171,13 +174,16 @@ void DOSBOX_Init(void) { #endif secprop->AddInitFunction(&IO_Init); + secprop->AddInitFunction(&PAGING_Init); secprop->AddInitFunction(&MEM_Init); - secprop->Add_int("memsize",8); //Default to 8 mb total memory + secprop->Add_int("memsize",8); //We Default to 8 mb seems okay for now secprop->AddInitFunction(&CALLBACK_Init); secprop->AddInitFunction(&PIC_Init); secprop->AddInitFunction(&PROGRAMS_Init); secprop->AddInitFunction(&TIMER_Init); secprop->AddInitFunction(&CMOS_Init); + secprop->AddInitFunction(&SERIAL_Init); + secprop=control->AddSection_prop("render",&RENDER_Init); secprop->Add_int("frameskip",0); secprop->Add_bool("keepsmall",false); @@ -242,19 +248,23 @@ void DOSBOX_Init(void) { //TODO Maybe combine most of the dos stuff in one section like ems,xms secprop=control->AddSection_prop("dos",&DOS_Init); secprop->AddInitFunction(&XMS_Init); - secprop->Add_int("xmssize",8); + secprop->Add_bool("xms",true); secprop->AddInitFunction(&EMS_Init); - secprop->Add_int("emssize",4); + secprop->Add_bool("ems",true); secprop->AddInitFunction(&DPMI_Init); + secprop->Add_bool("dpmi",true); +#if C_MODEM + secprop=control->AddSection_prop("modem",&MODEM_Init); + secprop->Add_bool("enabled",true); + secprop->Add_hex("comport",2); + secprop->Add_int("listenport",23); +#endif - // Mscdex secprop->AddInitFunction(&MSCDEX_Init); secline=control->AddSection_line("autoexec",&AUTOEXEC_Init); - control->SetStartUp(&SHELL_Init); - + control->SetStartUp(&SHELL_Init); } - From 3d2bf4e625738d66a8b11f1cfa862ddfe4b9c48d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 08:53:50 +0000 Subject: [PATCH 1047/4131] paging.cpp and paging.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1127 --- visualc/dosbox.dsp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index 634ea5cd..fdd35959 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -199,6 +199,10 @@ SOURCE=..\src\cpu\modrm.h # End Source File # Begin Source File +SOURCE=..\src\cpu\paging.cpp +# End Source File +# Begin Source File + SOURCE=..\src\cpu\slow_16.cpp # End Source File # End Group @@ -736,6 +740,10 @@ SOURCE=..\include\mouse.h # End Source File # Begin Source File +SOURCE=..\include\paging.h +# End Source File +# Begin Source File + SOURCE=..\include\pic.h # End Source File # Begin Source File From 4d4b0d6df211275d508bc456b9fd5237135b8502 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 08:54:32 +0000 Subject: [PATCH 1048/4131] Add paging.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1128 --- include/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/include/Makefile.am b/include/Makefile.am index 20f35bb0..d910b84d 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -18,6 +18,7 @@ mem.h \ mixer.h \ modules.h \ mouse.h \ +paging.h \ pic.h \ programs.h \ render.h \ From fd3d6659567cc1961f71e0f904682a202d7fbfce Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 08:55:04 +0000 Subject: [PATCH 1049/4131] add paging.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1129 --- src/cpu/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpu/Makefile.am b/src/cpu/Makefile.am index e0d9fd7a..18061a5d 100644 --- a/src/cpu/Makefile.am +++ b/src/cpu/Makefile.am @@ -2,4 +2,5 @@ SUBDIRS = core_16 core_full AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libcpu.a -libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h slow_16.cpp core_full.cpp instructions.h \ No newline at end of file +libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h slow_16.cpp core_full.cpp instructions.h \ + paging.cpp \ No newline at end of file From 66d2196e7c97a67813c8bfeb70de6cd32e5c5673 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 11:06:37 +0000 Subject: [PATCH 1050/4131] Incorrect calculation of size for alloc and realloc Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1130 --- src/ints/xms.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 1e9e0a7d..70693fb6 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -121,7 +121,7 @@ Bitu XMS_AllocateMemory(Bitu size, Bit16u& handle) while (!xms_handles[index].free) { if (++index>XMS_HANDLES) return XMS_OUT_OF_HANDLES; } - Bitu pages=(size/4) + (size & 3) ? 1 : 0; + Bitu pages=(size/4) + ((size & 3) ? 1 : 0); MemHandle mem=MEM_AllocatePages(pages,true); if (!mem) return XMS_OUT_OF_SPACE; xms_handles[index].free=false; @@ -224,7 +224,7 @@ Bitu XMS_ResizeMemory(Bitu handle, Bitu newSize) if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; // Block has to be unlocked if (xms_handles[handle].locked>0) return XMS_BLOCK_LOCKED; - Bitu pages=newSize/4 + (newSize & 3) ? 1 : 0; + Bitu pages=newSize/4 + ((newSize & 3) ? 1 : 0); if (MEM_ReAllocatePages(xms_handles[handle].mem,pages,true)) { return 0; } else return XMS_OUT_OF_SPACE; From b0780d0cb4f46fade6dbea5899dd0825f1fd5863 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 11:21:08 +0000 Subject: [PATCH 1051/4131] Use inlined memory access functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1131 --- src/cpu/core_full.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 6b3d1360..c9b8ba05 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -4,6 +4,7 @@ #include "regs.h" #include "cpu.h" #include "lazyflags.h" +#include "paging.h" #include "fpu.h" #include "debug.h" #include "inout.h" @@ -21,17 +22,17 @@ void PAGE_Writed(PhysPt address,Bit32u val); typedef PhysPt EAPoint; #define SegBase(c) SegPhys(c) #if 1 -#define LoadMb(off) mem_readb(off) -#define LoadMw(off) mem_readw(off) -#define LoadMd(off) mem_readd(off) +#define LoadMb(off) mem_readb_inline(off) +#define LoadMw(off) mem_readw_inline(off) +#define LoadMd(off) mem_readd_inline(off) #define LoadMbs(off) (Bit8s)(LoadMb(off)) #define LoadMws(off) (Bit16s)(LoadMw(off)) #define LoadMds(off) (Bit32s)(LoadMd(off)) -#define SaveMb(off,val) mem_writeb(off,val) -#define SaveMw(off,val) mem_writew(off,val) -#define SaveMd(off,val) mem_writed(off,val) +#define SaveMb(off,val) mem_writeb_inline(off,val) +#define SaveMw(off,val) mem_writew_inline(off,val) +#define SaveMd(off,val) mem_writed_inline(off,val) #else @@ -110,7 +111,7 @@ restartopcode: #include "core_full/save.h" nextopcode:; CPU_Cycles--; - } + } LEAVECORE; return CBRET_NONE; } From 640e059254b679dd6c8ad27d468456ea1ba98032 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 14 Jul 2003 11:35:06 +0000 Subject: [PATCH 1052/4131] Removed HostPt in ReadSector Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1132 --- src/dos/cdrom.h | 11 ++++++----- src/dos/cdrom_aspi_win32.cpp | 14 +++++++++++--- src/dos/cdrom_ioctl_win32.cpp | 18 +++++++++++++++--- src/dos/dos_mscdex.cpp | 3 +-- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index aa00bd6f..3c307cfb 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -5,6 +5,7 @@ #define MAX_ASPI_CDROM 5 #include +#include "mem.h" #include "SDL.h" #define RAW_SECTOR_SIZE 2352 @@ -40,7 +41,7 @@ public: virtual bool PauseAudio (bool resume) = 0; virtual bool StopAudio (void) = 0; - virtual bool ReadSectors (void* buffer, bool raw, unsigned long sector, unsigned long num) = 0; + virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0; virtual bool LoadUnloadMedia (bool unload) = 0; }; @@ -61,7 +62,7 @@ public: bool PlayAudioSector (unsigned long start,unsigned long len); bool PauseAudio (bool resume); bool StopAudio (void); - bool ReadSectors (void* buffer, bool raw, unsigned long sector, unsigned long num) { return false; }; + bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) { return false; }; bool LoadUnloadMedia (bool unload); private: @@ -86,7 +87,7 @@ public: bool PlayAudioSector (unsigned long start,unsigned long len) { return true; }; bool PauseAudio (bool resume) { return true; }; bool StopAudio (void) { return true; }; - bool ReadSectors (void* buffer, bool raw, unsigned long sector, unsigned long num) { return true; }; + bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) { return true; }; bool LoadUnloadMedia (bool unload) { return true; }; }; @@ -117,7 +118,7 @@ public: bool PauseAudio (bool resume); bool StopAudio (void); - bool ReadSectors (void* buffer, bool raw, unsigned long sector, unsigned long num); + bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); bool LoadUnloadMedia (bool unload); @@ -164,7 +165,7 @@ public: bool PauseAudio (bool resume); bool StopAudio (void); - bool ReadSectors (void* buffer, bool raw, unsigned long sector, unsigned long num); + bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); bool LoadUnloadMedia (bool unload); diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index de7a6cbf..c3ed83ce 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -667,7 +667,7 @@ bool CDROM_Interface_Aspi::GetMediaTrayStatus(bool& mediaPresent, bool& mediaCha return true; }; -bool CDROM_Interface_Aspi::ReadSectors(void* buffer, bool raw, unsigned long sector, unsigned long num) +bool CDROM_Interface_Aspi::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) { SRB_ExecSCSICmd s;DWORD dwStatus; @@ -675,6 +675,9 @@ bool CDROM_Interface_Aspi::ReadSectors(void* buffer, bool raw, unsigned long sec memset(&s,0,sizeof(s)); + Bitu buflen = raw?2352*num:2048*num; + Bit8u* bufdata = new Bit8u[buflen]; + s.SRB_Cmd = SC_EXEC_SCSI_CMD; s.SRB_HaId = haId; s.SRB_Target = target; @@ -682,8 +685,8 @@ bool CDROM_Interface_Aspi::ReadSectors(void* buffer, bool raw, unsigned long sec s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; s.SRB_SenseLen = SENSE_LEN; - s.SRB_BufLen = raw?2352*num:2048*num; - s.SRB_BufPointer = (BYTE FAR*)buffer; + s.SRB_BufLen = buflen; + s.SRB_BufPointer = (BYTE FAR*)bufdata; s.SRB_CDBLen = 12; s.SRB_PostProc = (LPVOID)hEvent; @@ -705,6 +708,11 @@ bool CDROM_Interface_Aspi::ReadSectors(void* buffer, bool raw, unsigned long sec CloseHandle(hEvent); + // Copy to PhysPt + MEM_BlockWrite(buffer,bufdata,buflen); + + delete[] bufdata; + return (s.SRB_Status==SS_COMP); }; diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index f656570e..34e0492d 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -140,6 +140,10 @@ bool CDROM_Interface_Ioctl::GetMediaTrayStatus(bool& mediaPresent, bool& mediaCh mediaPresent = GetAudioTracks(track1, track2, leadOut), trayOpen = !mediaPresent; mediaChanged = (oldLeadOut.min!=leadOut.min) || (oldLeadOut.sec!=leadOut.sec) || (oldLeadOut.fr!=leadOut.fr); + if (mediaChanged) { + // Open new media + Close(); Open(); + }; // Save old values oldLeadOut.min = leadOut.min; oldLeadOut.sec = leadOut.sec; @@ -207,17 +211,21 @@ bool CDROM_Interface_Ioctl::LoadUnloadMedia(bool unload) return bStat>0; }; -bool CDROM_Interface_Ioctl::ReadSectors(void* buffer, bool raw, unsigned long sector, unsigned long num) +bool CDROM_Interface_Ioctl::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) { BOOL bStat; DWORD byteCount = 0; // Open(); + + Bitu buflen = raw ? num*RAW_SECTOR_SIZE : num*COOKED_SECTOR_SIZE; + Bit8u* bufdata = new Bit8u[buflen]; + if (!raw) { // Cooked int success = 0; DWORD newPos = SetFilePointer(hIOCTL, sector*COOKED_SECTOR_SIZE, 0, FILE_BEGIN); - if (newPos != 0xFFFFFFFF) success = ReadFile(hIOCTL, buffer, num*COOKED_SECTOR_SIZE, &byteCount, NULL); + if (newPos != 0xFFFFFFFF) success = ReadFile(hIOCTL, bufdata, buflen, &byteCount, NULL); bStat = (success!=0); } else { // Raw @@ -227,9 +235,13 @@ bool CDROM_Interface_Ioctl::ReadSectors(void* buffer, bool raw, unsigned long se in.SectorCount = num; in.TrackMode = CDDA; bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RAW_READ, &in, sizeof(in), - buffer, num*RAW_SECTOR_SIZE, &byteCount,NULL); + bufdata, buflen, &byteCount,NULL); } // Close(); + + MEM_BlockWrite(buffer,bufdata,buflen); + delete[] bufdata; + return (byteCount!=num*RAW_SECTOR_SIZE) && (bStat>0); } diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 1594b27f..580108a2 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -504,8 +504,7 @@ bool CMscdex::GetUPC(Bit8u subUnit, Bit8u& attr, char* upc) bool CMscdex::ReadSectors(Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data) { if (subUnit>=numDrives) return false; - void* buffer = (void*)Phys2Host(data); - dinfo[subUnit].lastResult = cdrom[subUnit]->ReadSectors(buffer,raw,sector,num); + dinfo[subUnit].lastResult = cdrom[subUnit]->ReadSectors(data,raw,sector,num); return dinfo[subUnit].lastResult; }; From 344afaf577cdf46793451d8cede0cb7046b16715 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 14 Jul 2003 11:37:27 +0000 Subject: [PATCH 1053/4131] check for bool "dpmi" in dpmi_init to enable/disable dpmi Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1133 --- src/ints/dpmi.cpp | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index 4109587c..95b53ce0 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -88,7 +88,7 @@ #define DPMI_CB_EXCEPTIONRETURN_OFFSET 260*8 #define DPMI_CB_VENDORENTRY_OFFSET 261*8 -#define DPMI_HOOK_HARDWARE_INTS 1 +#define DPMI_HOOK_HARDWARE_INTS 0 static Bitu rmIndexToInt[DPMI_REALVEC_MAX] = { 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x1C }; @@ -1630,7 +1630,7 @@ Bitu DPMI::Int31Handler(void) reg_cx = RealOff(entry); reg_si = GDT_PROTCODE; reg_edi= DPMI_CB_SAVESTATE_OFFSET; - reg_ax = 48; // 20 bytes buffer needed + reg_ax = 0; // 20 bytes buffer needed DPMI_CALLBACK_SCF(false); }; break; case 0x0306:{// Get raw mode switch address @@ -1658,7 +1658,7 @@ Bitu DPMI::Int31Handler(void) XMS_QueryFreeMemory(largest,total); // in KB Bitu largeB = (Bitu)largest*1024;// - 1024*1024; // in bytes Bitu totalB = (Bitu)total*1024;// - 1024*1024; // in bytes - Bitu sizeB = (Bitu)XMS_GetSize()*1024*1024;//-1024*1024; // in bytes + Bitu sizeB = (Bitu)MEM_TotalPages()*DPMI_PAGE_SIZE; //-1024*1024; // in bytes mem_writed(data+0x00,largeB); // Size in bytes mem_writed(data+0x04,largeB/DPMI_PAGE_SIZE); // total number of pages mem_writed(data+0x08,largeB/DPMI_PAGE_SIZE); // largest block in pages @@ -1752,7 +1752,10 @@ Bitu DPMI::Int31Handler(void) DPMI_CALLBACK_SCF(false); break; case 0x0509:{//Map Conventional Memory in Memory Block - Bit32u xmsAddress; + DPMI_LOG_ERROR("DPMI: 0509: Mapping convmem not supported."); + reg_ax = DPMI_ERROR_UNSUPPORTED; + DPMI_CALLBACK_SCF(true); +/* Bit32u xmsAddress; Bitu handle = reg_esi; Bitu offset = reg_ebx; Bitu numPages = reg_ecx; @@ -1760,14 +1763,14 @@ Bitu DPMI::Int31Handler(void) if (XMS_LockMemory(handle,xmsAddress)==0) { LOG(LOG_MISC,LOG_ERROR)("DPMI: 0509: Mapping convmem %04X to %08X",linearAdr,xmsAddress+offset); if ((numPages%4)!=0) E_Exit("DPMI: Cannot map conventional memory."); - MEM_SetupMapping(PAGE_COUNT((xmsAddress+offset)),PAGE_COUNT(numPages*DPMI_PAGE_SIZE),((Bit8u*)memory)+linearAdr); +// MEM_SetupMapping(PAGE_COUNT((xmsAddress+offset)),PAGE_COUNT(numPages*DPMI_PAGE_SIZE),((Bit8u*)memory)+linearAdr); XMS_UnlockMemory(handle); DPMI_CALLBACK_SCF(false); } else { LOG(LOG_MISC,LOG_ERROR)("DPMI: 0509: Mapping convmem failure."); reg_ax = DPMI_ERROR_INVALID_HANDLE; DPMI_CALLBACK_SCF(true); - } + }*/ }; break; case 0x0600:{//Lock Linear Region Bitu address = (reg_bx<<16)+reg_cx; @@ -1873,7 +1876,10 @@ Bitu DPMI::Int31Handler(void) case 0x0E01:// Set Coprocessor Emulation DPMI_CALLBACK_SCF(true); // failure break; - default :E_Exit("DPMI: Unsupported func %04X",reg_ax); + default :LOG(LOG_MISC,LOG_ERROR)("DPMI: Unsupported func %04X",reg_ax); + reg_ax = DPMI_ERROR_UNSUPPORTED; + DPMI_CALLBACK_SCF(true); // failure + break; }; return 0; } @@ -2224,6 +2230,9 @@ static bool DPMI_Multiplex(void) { void DPMI_Init(Section* sec) { + Section_prop * section=static_cast(sec); + if (!section->Get_bool("dpmi")) return; + memset(&callback,0,sizeof(callback)); /* setup Real mode Callbacks */ @@ -2454,7 +2463,7 @@ Bitu DPMI::API_Entry_MSDOS(void) Bitu DPMI::API_Int21_MSDOS(void) { -// LOG(LOG_MISC,LOG_ERROR)("DPMI:MSDOS:INT 21 %04X",reg_ax); + LOG(LOG_MISC,LOG_ERROR)("DPMI:MSDOS-API:INT 21 %04X",reg_ax); Bitu protsel,protoff,seg,off; Bitu sax = reg_ax; switch (reg_ah) { @@ -2525,10 +2534,10 @@ Bitu DPMI::API_Int21_MSDOS(void) char name1[256]; MEM_StrCopy(SegPhys(ds)+reg_edx,name1,255); if (DOS_OpenFile(name1,reg_al,®_ax)) { - LOG(LOG_MISC,LOG_ERROR)("DOS: Open success; %s",name1); + LOG(LOG_MISC,LOG_ERROR)("DOS: Open success: %s",name1); DPMI_CALLBACK_SCF(false); } else { - LOG(LOG_MISC,LOG_ERROR)("DOS: Open failure; %s",name1); + LOG(LOG_MISC,LOG_ERROR)("DOS: Open failure: %s",name1); reg_ax=dos.errorcode; DPMI_CALLBACK_SCF(true); } @@ -2653,7 +2662,6 @@ Bitu DPMI::API_Int21_MSDOS(void) Bitu segment = GetSegmentFromSelector(reg_dx); DOS_ChildPSP(segment,reg_si); dos.psp = segment; - DPMI_CALLBACK_SCF(false); LOG(LOG_MISC,LOG_ERROR)("DPMI:MSDOS:0x55:Create new psp:%04X",segment); }; break; case 0x5D : // Get Address of dos swappable area @@ -2710,7 +2718,7 @@ Bitu DPMI::API_Int21_MSDOS(void) case 0x0E: case 0x19: case 0x2A: case 0x2C: case 0x2D: case 0x30: case 0x36: case 0x3E: case 0x4C: case 0x58: case 0x67: { - // reflect top real mode + // reflect to real mode DPMI_Int21Handler(); }; break; From 7c02953cfc8a61134eb9b3d3e977fb0cf3fdd5e3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 12:43:51 +0000 Subject: [PATCH 1054/4131] New direct mapping support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1134 --- include/mem.h | 3 ++- src/hardware/memory.cpp | 10 ++++++++-- src/ints/ems.cpp | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/include/mem.h b/include/mem.h index 23e8fcea..61d53312 100644 --- a/include/mem.h +++ b/include/mem.h @@ -42,7 +42,8 @@ MemHandle MEM_AllocatePages(Bitu pages,bool sequence); PhysPt MEM_AllocatePage(void); void MEM_ReleasePages(MemHandle handle); bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence); -void MEM_MapPages(Bitu phys_page,MemHandle mem,Bitu mem_page,Bitu pages); +void MEM_MapPagesHandle(Bitu lin_page,MemHandle mem,Bitu mem_page,Bitu pages); +void MEM_MapPagesDirect(Bitu lin_page,Bitu phys_page,Bitu pages); void MEM_UnmapPages(Bitu phys_page,Bitu pages); diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 53f6039c..d10e41cc 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -631,18 +631,24 @@ void MEM_UnmapPages(Bitu phys_page,Bitu pages) { } } -void MEM_MapPages(Bitu phys_page,MemHandle mem,Bitu mem_page,Bitu pages) { +void MEM_MapPagesHandle(Bitu lin_page,MemHandle mem,Bitu mem_page,Bitu pages) { for (;mem_page;mem_page--) { if (mem<=0) E_Exit("MEM:MapPages:Fault in memory tables"); mem=memory.entries[mem].next_handle; } for (;pages;pages--) { if (mem<=0) E_Exit("MEM:MapPages:Fault in memory tables"); - memory.dir.LinkPage(phys_page++,mem); + memory.dir.LinkPage(lin_page++,mem); mem=memory.entries[mem].next_handle; } } +void MEM_MapPagesDirect(Bitu lin_page,Bitu phys_page,Bitu pages) { + for (;pages;pages--) { + memory.dir.LinkPage(lin_page++,phys_page++); + } +} + MemHandle MEM_NextHandle(MemHandle handle) { return memory.entries[handle].next_handle; } diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 063af139..81ce3b27 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -156,7 +156,7 @@ static Bit8u EMM_MapPage(Bitu phys_page,Bit16u handle,Bit16u log_page) { /* Mapping it is */ emm_mappings[phys_page].handle=handle; emm_mappings[phys_page].page=log_page; - MEM_MapPages(EMM_PAGEFRAME4K+phys_page*4,emm_handles[handle].mem,log_page*4,4); + MEM_MapPagesHandle(EMM_PAGEFRAME4K+phys_page*4,emm_handles[handle].mem,log_page*4,4); return EMM_NO_ERROR; } else if (log_page==NULL_PAGE) { /* Unmapping it is */ From 836fa347867b6b8a83367ffd527dc48237758ca3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 12:44:23 +0000 Subject: [PATCH 1055/4131] Check for xms being enabled not ems Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1135 --- src/ints/xms.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 70693fb6..f610ef94 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -332,7 +332,7 @@ Bitu XMS_Handler(void) { void XMS_Init(Section* sec) { Section_prop * section=static_cast(sec); - if (!section->Get_bool("ems")) return; + if (!section->Get_bool("xms")) return; Bitu i; DOS_AddMultiplexHandler(multiplex_xms); From fc02a41aad30f3abaa0abda52313a1e844b022d9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 14 Jul 2003 17:44:00 +0000 Subject: [PATCH 1056/4131] Added support for pressing esc in shell so it escapes the current line and allows you to type a new command Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1136 --- src/shell/shell_misc.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index efb8c696..249ccde5 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -231,6 +231,16 @@ void DOS_Shell::InputCommand(char * line) { } } break; + case 0x1b: /* ESC */ + //write a backslash and return to the next line + outc('\\'); + outc('\n'); + *line = 0; // reset the line. + if (l_completion.size()) l_completion.clear(); //reset the completion list. + this->InputCommand(line); //Get the NEW line. + size = 0; // stop the next loop + str_len = 0; // prevent multiple adds of the same line + break; default: if (l_completion.size()) l_completion.clear(); line[str_index]=c; From 4e62907e37ba57b660432aef962dc5cdb59c6d60 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 15 Jul 2003 09:05:19 +0000 Subject: [PATCH 1057/4131] include ctype.h for toupper Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1137 --- src/hardware/softmodem.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp index b05102e2..ad11e532 100644 --- a/src/hardware/softmodem.cpp +++ b/src/hardware/softmodem.cpp @@ -23,6 +23,7 @@ #if C_MODEM #include +#include #include "SDL_net.h" #include "inout.h" From e2f947a1c1478779fb18a4092fce37977782a8bc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 19 Jul 2003 05:54:10 +0000 Subject: [PATCH 1058/4131] Changed the TOP system. Added support for 80 bits loading and saving Added support BCD saving Added FPREM Adden FXAM Fixed bug when comparing zero to an nonzero number. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1138 --- src/fpu/fpu.cpp | 211 ++++++++++++++++++------------------- src/fpu/fpu_instructions.h | 160 ++++++++++++++++++++++------ src/fpu/fpu_types.h | 27 +++-- 3 files changed, 246 insertions(+), 152 deletions(-) diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 636b2f45..66934324 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -27,6 +27,9 @@ typedef PhysPt EAPoint; +#define TOP fpu.top +#define ST(i) ( (fpu.top+ (i) ) & 7 ) + #define LoadMb(off) mem_readb(off) #define LoadMw(off) mem_readw(off) #define LoadMd(off) mem_readd(off) @@ -99,37 +102,39 @@ INLINE Bitu FPU_GET_C3(void){ #include "fpu_instructions.h" /* TODO : ESC6normal => esc4normal+pop or a define as well - : Make a smarter top system. won't matter that much in speed though. - : #define ST fpu.top #define ST(i) (fpu.top+(i))&7 maybe*/ +*/ +/* WATCHIT : ALWAYS UPDATE REGISTERS BEFORE AND AFTER USING THEM + STATUS WORD => FPU_SET_TOP(TOP) BEFORE a read + TOP=FPU_GET_TOP() after a write; + */ static void EATREE(Bitu _rm){ Bitu group=(_rm >> 3) & 7; - Bitu top = FPU_GET_TOP(); /* data will allready be put in register 8 by caller */ switch(group){ case 0x00: /* FIADD */ - FPU_FADD(top, 8); + FPU_FADD(TOP, 8); break; case 0x01: /* FIMUL */ - FPU_FMUL(top, 8); + FPU_FMUL(TOP, 8); break; case 0x02: /* FICOM */ - FPU_FCOM(top,8); + FPU_FCOM(TOP,8); break; case 0x03: /* FICOMP */ - FPU_FCOM(top,8); + FPU_FCOM(TOP,8); FPU_FPOP(); break; case 0x04: /* FISUB */ - FPU_FSUB(top,8); + FPU_FSUB(TOP,8); break; case 0x05: /* FISUBR */ - FPU_FSUBR(top,8); + FPU_FSUBR(TOP,8); case 0x06: /* FIDIV */ - FPU_FDIV(top, 8); + FPU_FDIV(TOP, 8); break; case 0x07: /* FIDIVR */ - FPU_FDIVR(top,8); + FPU_FDIVR(TOP,8); break; default: break; @@ -138,10 +143,7 @@ static void EATREE(Bitu _rm){ } void FPU_ESC0_EA(Bitu rm,PhysPt addr) { - /* REGULAR TREE WITH 32 BITS REALS ? float ? */ - //THIS SHOULD GO ALLRIGHT !?! -// LOG(LOG_FPU, LOG_WARN)("ESC 0 EA used (check the result!)"); - + /* REGULAR TREE WITH 32 BITS REALS -> float */ union { float f; Bit32u l; @@ -154,32 +156,31 @@ void FPU_ESC0_EA(Bitu rm,PhysPt addr) { void FPU_ESC0_Normal(Bitu rm) { Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); - Bitu top = FPU_GET_TOP(); switch (group){ case 0x00: /* FADD ST,STi */ - FPU_FADD(top,(top+sub)&7); + FPU_FADD(TOP,ST(sub)); break; case 0x01: /* FMUL ST,STi */ - FPU_FMUL(top,(top+sub)&7); + FPU_FMUL(TOP,ST(sub)); break; case 0x02: /* FCOM STi */ - FPU_FCOM(top,(top+sub)&7); + FPU_FCOM(TOP,ST(sub)); break; case 0x03: /* FCOMP STi */ - FPU_FCOM(top,(top+sub)&7); + FPU_FCOM(TOP,ST(sub)); FPU_FPOP(); break; case 0x04: /* FSUB ST,STi */ - FPU_FSUB(top,(top+sub)&7); + FPU_FSUB(TOP,ST(sub)); break; case 0x05: /* FSUBR ST,STi */ - FPU_FSUBR(top,(top+sub)&7); + FPU_FSUBR(TOP,ST(sub)); break; case 0x06: /* FDIV ST,STi */ - FPU_FDIV(top,(top+sub)&7); + FPU_FDIV(TOP,ST(sub)); break; case 0x07: /* FDIVR ST,STi */ - FPU_FDIVR(top,(top+sub)&7); + FPU_FDIVR(TOP,ST(sub)); break; default: break; @@ -192,7 +193,7 @@ void FPU_ESC1_EA(Bitu rm,PhysPt addr) { Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); switch(group){ - case 0x00: /* FLD */ + case 0x00: /* FLD float*/ { union { float f; @@ -206,25 +207,25 @@ void FPU_ESC1_EA(Bitu rm,PhysPt addr) { case 0x01: /* UNKNOWN */ LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub); break; - case 0x02: /* FST */ + case 0x02: /* FST float*/ { union { float f; Bit32u l; } blah; //should depend on rounding method - blah.f = static_cast(fpu.regs[FPU_GET_TOP()].d); + blah.f = static_cast(fpu.regs[TOP].d); mem_writed(addr,blah.l); } break; - case 0x03: /* FSTP */ + case 0x03: /* FSTP float*/ { union { float f; Bit32u l; } blah; - blah.f = static_cast(fpu.regs[FPU_GET_TOP()].d); + blah.f = static_cast(fpu.regs[TOP].d); mem_writed(addr,blah.l); } FPU_FPOP(); @@ -250,42 +251,30 @@ void FPU_ESC1_Normal(Bitu rm) { Bitu sub=(rm & 7); switch (group){ case 0x00: /* FLD STi */ - { - Bitu top = FPU_GET_TOP(); - FPU_PUSH(fpu.regs[(top+sub)&7].d); - } + FPU_PUSH(fpu.regs[ST(sub)].d); break; case 0x01: /* FXCH STi */ - { - Bitu top = FPU_GET_TOP(); - FPU_FXCH(top,(top+sub)&7); - } + FPU_FXCH(TOP,ST(sub)); break; case 0x04: switch(sub){ case 0x00: /* FCHS */ - { - Bitu top = FPU_GET_TOP(); - fpu.regs[top].d = -1.0*(fpu.regs[top].d); - } + fpu.regs[TOP].d = -1.0*(fpu.regs[TOP].d); break; case 0x01: /* FABS */ - { - Bitu top = FPU_GET_TOP(); - fpu.regs[top].d = fabs(fpu.regs[top].d); - } + fpu.regs[TOP].d = fabs(fpu.regs[TOP].d); 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 */ - { Bitu top = FPU_GET_TOP(); - fpu.regs[8].d=0.0; - FPU_FCOM(top,8); - } + fpu.regs[8].d=0.0; + FPU_FCOM(TOP,8); break; case 0x05: /* FXAM */ + FPU_FXAM(); + break; case 0x06: /* FTSTP (cyrix)*/ case 0x07: /* UNKNOWN */ LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); @@ -335,7 +324,9 @@ void FPU_ESC1_Normal(Bitu rm) { break; case 0x07: switch(sub){ - + case 0x00: /* FPREM */ + FPU_FPREM(); + break; case 0x02: /* FSQRT */ FPU_FSQRT(); break; @@ -344,9 +335,9 @@ void FPU_ESC1_Normal(Bitu rm) { break; case 0x04: /* FRNDINT */ { - Bitu top = FPU_GET_TOP(); - Bit32s temp= static_cast(FROUND(fpu.regs[top].d)); - fpu.regs[top].d=static_cast(temp); +//TODO + Bit64s temp= static_cast(FROUND(fpu.regs[TOP].d)); + fpu.regs[TOP].d=static_cast(temp); } //TODO break; @@ -356,6 +347,7 @@ void FPU_ESC1_Normal(Bitu rm) { case 0x07: /* FCOS */ FPU_FCOS(); break; + case 0x01: /* FYL2XP1 */ default: LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); break; @@ -398,15 +390,18 @@ void FPU_ESC3_EA(Bitu rm,PhysPt addr) { break; case 0x02: /* FIST */ - { Bitu top = FPU_GET_TOP(); - mem_writed(addr,static_cast(FROUND(fpu.regs[top].d))); - } + mem_writed(addr,static_cast(FROUND(fpu.regs[TOP].d))); break; case 0x03: /*FISTP */ - { Bitu top = FPU_GET_TOP(); - mem_writed(addr,static_cast(FROUND(fpu.regs[top].d))); - FPU_FPOP(); - } + mem_writed(addr,static_cast(FROUND(fpu.regs[TOP].d))); + FPU_FPOP(); + break; + case 0x05: /* FLD 80 Bits Real */ + FPU_FLD80(addr); + break; + case 0x07: /* FSTP 80 Bits Real */ + FPU_ST80(addr); + FPU_FPOP(); break; default: LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub); @@ -458,32 +453,31 @@ void FPU_ESC4_Normal(Bitu rm) { //LOOKS LIKE number 6 without popping*/ Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); - Bitu top = FPU_GET_TOP(); switch(group){ case 0x00: /*FADDP STi,ST*/ - FPU_FADD((top+sub)&7,top); + FPU_FADD(ST(sub),TOP); break; case 0x01: /* FMULP STi,ST*/ - FPU_FMUL((top+sub)&7,top); + FPU_FMUL(ST(sub),TOP); break; case 0x02: /* FCOM*/ - FPU_FCOM(top,(top+sub)&7); + FPU_FCOM(TOP,ST(sub)); break; /* TODO IS THIS ALLRIGHT ????????? (maybe reverse operators) */ case 0x03: /* FCOMP*/ - FPU_FCOM(top,(top+sub)&7); + FPU_FCOM(TOP,ST(sub)); FPU_FPOP(); break; case 0x04: /* FSUBRP STi,ST*/ - FPU_FSUBR((top+sub)&7,top); + FPU_FSUBR(ST(sub),TOP); break; case 0x05: /* FSUBP STi,ST*/ - FPU_FSUB((top+sub)&7,top); + FPU_FSUB(ST(sub),TOP); break; case 0x06: /* FDIVRP STi,ST*/ - FPU_FDIVR((top+sub)&7,top); + FPU_FDIVR(ST(sub),TOP); break; case 0x07: /* FDIVP STi,ST*/ - FPU_FDIV((top+sub)&7,top); + FPU_FDIV(ST(sub),TOP); break; default: break; @@ -494,7 +488,7 @@ void FPU_ESC5_EA(Bitu rm,PhysPt addr) { Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); switch(group){ - case 0x00: /* FLD */ + case 0x00: /* FLD double real*/ { FPU_Reg blah; blah.l.lower=mem_readd(addr); @@ -502,24 +496,21 @@ void FPU_ESC5_EA(Bitu rm,PhysPt addr) { FPU_PUSH(blah.d); } break; - case 0x01: /* FISTTP */ + case 0x01: /* FISTTP longint*/ LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub); break; - case 0x02: /* FIST */ - { Bitu top = FPU_GET_TOP(); - mem_writed(addr,fpu.regs[top].l.lower); - mem_writed(addr+4,fpu.regs[top].l.upper); - } + case 0x02: /* FIST double real*/ + mem_writed(addr,fpu.regs[TOP].l.lower); + mem_writed(addr+4,fpu.regs[TOP].l.upper); break; - case 0x03: /*FISTP */ - { Bitu top = FPU_GET_TOP(); - mem_writed(addr,fpu.regs[top].l.lower); - mem_writed(addr+4,fpu.regs[top].l.upper); - FPU_FPOP(); - } + case 0x03: /*FISTP double real*/ + mem_writed(addr,fpu.regs[TOP].l.lower); + mem_writed(addr+4,fpu.regs[TOP].l.upper); + FPU_FPOP(); break; case 0x07: /*FNSTSW NG DISAGREES ON THIS*/ + FPU_SET_TOP(TOP); mem_writew(addr,fpu.sw); //seems to break all dos4gw games :) break; @@ -531,26 +522,25 @@ void FPU_ESC5_EA(Bitu rm,PhysPt addr) { void FPU_ESC5_Normal(Bitu rm) { Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); - Bitu top = FPU_GET_TOP(); switch(group){ case 0x00: /* FFREE STi */ - fpu.tags[(top+sub)&7]=TAG_Empty; + fpu.tags[ST(sub)]=TAG_Empty; break; case 0x01: /* FXCH STi*/ - FPU_FXCH(top,(top+sub)&7); + FPU_FXCH(TOP,ST(sub)); break; case 0x02: /* FST STi */ - FPU_FST(top,(top+sub)&7); + FPU_FST(TOP,ST(sub)); break; case 0x03: /* FSTP STi*/ - FPU_FST(top,(top+sub)&7); + FPU_FST(TOP,ST(sub)); FPU_FPOP(); break; case 0x04: /* FUCOM STi */ - FPU_FUCOM(top,(top+sub)&7); + FPU_FUCOM(TOP,ST(sub)); break; - case 0x05: - FPU_FUCOM(top,(top+sub)&7); + case 0x05: /*FUCOMP STi */ + FPU_FUCOM(TOP,ST(sub)); FPU_FPOP(); break; default: @@ -572,36 +562,36 @@ void FPU_ESC6_Normal(Bitu rm) { /* get top before switch and pop afterwards */ Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); - Bitu top = FPU_GET_TOP(); switch(group){ case 0x00: /*FADDP STi,ST*/ - FPU_FADD((top+sub)&7,top); + FPU_FADD(ST(sub),TOP); break; case 0x01: /* FMULP STi,ST*/ - FPU_FMUL((top+sub)&7,top); + FPU_FMUL(ST(sub),TOP); break; case 0x02: /* FCOMP5*/ - FPU_FCOM(top,(top+sub)&7); + FPU_FCOM(TOP,ST(sub)); break; /* TODO IS THIS ALLRIGHT ????????? */ case 0x03: /* weird*/ /*FCOMPP*/ if(sub != 1){ LOG(LOG_FPU,LOG_WARN)("ESC 6:Unhandled group %d subfunction %d",group,sub); + ; break; } - FPU_FCOM(top,(top+sub)&7); - FPU_FPOP(); + FPU_FCOM(TOP,ST(1)); + FPU_FPOP(); /* extra pop at the bottom*/ break; case 0x04: /* FSUBRP STi,ST*/ - FPU_FSUBR((top+sub)&7,top); + FPU_FSUBR(ST(sub),TOP); break; case 0x05: /* FSUBP STi,ST*/ - FPU_FSUB((top+sub)&7,top); + FPU_FSUB(ST(sub),TOP); break; case 0x06: /* FDIVRP STi,ST*/ - FPU_FDIVR((top+sub)&7,top); + FPU_FDIVR(ST(sub),TOP); break; case 0x07: /* FDIVP STi,ST*/ - FPU_FDIV((top+sub)&7,top); + FPU_FDIV(ST(sub),TOP); break; default: break; @@ -627,15 +617,11 @@ void FPU_ESC7_EA(Bitu rm,PhysPt addr) { break; case 0x02: /* FIST Bit16s */ - { Bitu top = FPU_GET_TOP(); - mem_writew(addr,static_cast(FROUND(fpu.regs[top].d))); - } + mem_writew(addr,static_cast(FROUND(fpu.regs[TOP].d))); break; case 0x03: /* FISTP Bit16s */ - { Bitu top = FPU_GET_TOP(); - mem_writew(addr,static_cast(FROUND(fpu.regs[top].d))); - FPU_FPOP(); - } + mem_writew(addr,static_cast(FROUND(fpu.regs[TOP].d))); + FPU_FPOP(); break; case 0x05: /* FILD Bit32s */ { @@ -643,11 +629,13 @@ void FPU_ESC7_EA(Bitu rm,PhysPt addr) { FPU_PUSH( static_cast(blah)); } break; + case 0x06: /* FBSTP packed BCD */ + FPU_FBST(addr); + FPU_FPOP(); + break; case 0x07: /* FISTP Bit32s */ - { Bitu top = FPU_GET_TOP(); - mem_writed(addr,static_cast(FROUND(fpu.regs[top].d))); - FPU_FPOP(); - } + mem_writed(addr,static_cast(FROUND(fpu.regs[TOP].d))); + FPU_FPOP(); break; default: LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); @@ -661,6 +649,7 @@ void FPU_ESC7_Normal(Bitu rm) { case 0x04: switch(sub){ case 0x00: /* FNSTSW AX*/ + FPU_SET_TOP(TOP); reg_ax = fpu.sw; break; default: diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index d5953d30..57d7d6ac 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -21,6 +21,7 @@ static void FPU_FINIT(void) { FPU_SetCW(0x37F); fpu.sw=0; + TOP=FPU_GET_TOP(); fpu.tags[0]=TAG_Empty; fpu.tags[1]=TAG_Empty; fpu.tags[2]=TAG_Empty; @@ -40,26 +41,22 @@ static void FPU_FNOP(void){ } static void FPU_PUSH(double in){ - Bitu newtop = (FPU_GET_TOP() - 1) &7; - FPU_SET_TOP(newtop); + TOP = (TOP - 1) &7; //actually check if empty - fpu.tags[newtop]=TAG_Valid; - fpu.regs[newtop].d=in; + fpu.tags[TOP]=TAG_Valid; + fpu.regs[TOP].d=in; +// LOG(LOG_FPU,LOG_ERROR)("Pushed at %d %g to the stack",newtop,in); return; } static void FPU_PUSH_ZERO(void){ - Bitu newtop = (FPU_GET_TOP() - 1) &7; - FPU_SET_TOP(newtop); - //actually check if empty - fpu.tags[newtop]=TAG_Zero; - fpu.regs[newtop].d=0.0; - return; + FPU_PUSH(0.0); + return; //maybe oneday needed } static void FPU_FPOP(void){ - Bitu top = FPU_GET_TOP(); - fpu.tags[top]=TAG_Empty; + fpu.tags[TOP]=TAG_Empty; //maybe set zero in it as well - FPU_SET_TOP((top+1)&7); + TOP = ((TOP+1)&7); +// LOG(LOG_FPU,LOG_ERROR)("popped from %d %g off the stack",top,fpu.regs[top].d); return; } @@ -70,49 +67,42 @@ static void FPU_FADD(Bitu op1, Bitu op2){ } static void FPU_FSIN(void){ - Bitu top = FPU_GET_TOP(); - fpu.regs[top].d = sin(fpu.regs[top].d); + fpu.regs[TOP].d = sin(fpu.regs[TOP].d); FPU_SET_C2(0); //flags and such :) return; } static void FPU_FSINCOS(void){ - Bitu top = FPU_GET_TOP(); - - double temp = sin(fpu.regs[top].d); - FPU_PUSH(cos(fpu.regs[top].d)); - fpu.regs[top].d = temp; + Real64 temp = fpu.regs[TOP].d; + fpu.regs[TOP].d = sin(temp); + FPU_PUSH(cos(temp)); FPU_SET_C2(0); //flags and such :) return; } static void FPU_FCOS(void){ - Bitu top = FPU_GET_TOP(); - fpu.regs[top].d = cos(fpu.regs[top].d); + fpu.regs[TOP].d = cos(fpu.regs[TOP].d); FPU_SET_C2(0); //flags and such :) return; } static void FPU_FSQRT(void){ - Bitu top = FPU_GET_TOP(); - fpu.regs[top].d = sqrt(fpu.regs[top].d); + fpu.regs[TOP].d = sqrt(fpu.regs[TOP].d); //flags and such :) return; } static void FPU_FPATAN(void){ - Bitu top = FPU_GET_TOP(); - fpu.regs[(top+1)&7].d = atan(fpu.regs[(top+1)&7].d/fpu.regs[top].d); + fpu.regs[ST(1)].d = atan(fpu.regs[ST(1)].d/fpu.regs[TOP].d); FPU_FPOP(); FPU_SET_C2(0); //flags and such :) return; } static void FPU_FPTAN(void){ - Bitu top = FPU_GET_TOP(); - fpu.regs[top].d = tan(fpu.regs[top].d); + fpu.regs[TOP].d = tan(fpu.regs[TOP].d); FPU_PUSH(1.0); FPU_SET_C2(0); //flags and such :) @@ -166,16 +156,16 @@ static void FPU_FST(Bitu st, Bitu other){ static void FPU_FCOM(Bitu st, Bitu other){ if((fpu.tags[st] != TAG_Valid) || (fpu.tags[other] != TAG_Valid)){ - FPU_SET_C3(1);FPU_SET_C2(1);FPU_SET_C0(1);return; + FPU_SET_C3(1);FPU_SET_C1(1);FPU_SET_C0(1);return; } if(fpu.regs[st].d == fpu.regs[other].d){ - FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(0);return; + FPU_SET_C3(1);FPU_SET_C1(0);FPU_SET_C0(0);return; } if(fpu.regs[st].d < fpu.regs[other].d){ - FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C0(1);return; + FPU_SET_C3(0);FPU_SET_C1(0);FPU_SET_C0(1);return; } // st > other - FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C0(0);return; + FPU_SET_C3(0);FPU_SET_C1(0);FPU_SET_C0(0);return; } static void FPU_FUCOM(Bitu st, Bitu other){ @@ -202,3 +192,109 @@ static double FROUND(double in){ break; } } + +static void FPU_FPREM(void){ + Real64 valtop = fpu.regs[TOP].d; + Real64 valdiv = fpu.regs[ST(1)].d; + Real64 res = floor(valtop/valdiv); + res=valtop - res*valdiv; + fpu.regs[TOP].d = res; + FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C1(0);FPU_SET_C0(0); +} + +static void FPU_FXAM(void){ + if(fpu.tags[TOP] == TAG_Empty) + { + FPU_SET_C3(1);FPU_SET_C0(1); + return; + } + if(fpu.regs[TOP].ll & 0x8000000000000000) //sign + { + FPU_SET_C1(1); + } + else + { + FPU_SET_C1(0); + } + if(fpu.regs[TOP].d == 0.0) //zero or normalized number. + { + FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(0); + } + else{ + FPU_SET_C3(0);FPU_SET_C2(1);FPU_SET_C0(0); + } +} + +static void FPU_FBST(PhysPt addr) +{ + FPU_Reg val = fpu.regs[TOP]; + bool sign = false; + if(val.d<0.0){ //sign + sign=true; + val.d=-val.d; + } + //numbers from back to front + Real64 temp=val.d; + Bitu p; + for(Bitu i=0;i<9;i++){ + val.d=temp; + temp = static_cast(static_cast(floor(val.d/10.0))); + p = static_cast(val.d - 10.0*temp); + val.d=temp; + temp = static_cast(static_cast(floor(val.d/10.0))); + p |= (static_cast(val.d - 10.0*temp)<<4); + + mem_writeb(addr+i,p); + } + val.d=temp; + temp = static_cast(static_cast(floor(val.d/10.0))); + p = static_cast(val.d - 10.0*temp); + if(sign) + p|=0x80; + mem_writeb(addr+9,p); +} + +#define BIAS80 16383 +#define BIAS64 1023 + +static void FPU_FLD80(PhysPt addr) +{ + struct{ + Bit16s begin; + FPU_Reg eind; + } test; + test.eind.l.lower=mem_readd(addr); + test.eind.l.upper =mem_readd(addr+4); + test.begin=mem_readw(addr+8); + + Bit64s exp64= (((test.begin & 0x7fff) - BIAS80)); + Bit64s blah= ((exp64 >0)?exp64:-exp64)&0x3ff; + Bit64s exp64final= ((exp64 >0)?blah:-blah) +BIAS64; + + Bit64s mant64= (test.eind.ll >> 11) & 0xfffffffffffff; + Bit64s sign = (test.begin &0x8000)?1:0; + FPU_Reg result; + result.ll= (sign <<63)|(exp64final << 52)| mant64; + FPU_PUSH(result.d); + //mant64= test.mant80/2***64 * 2 **53 +} + +static void FPU_ST80(PhysPt addr) +{ + struct{ + Bit16s begin; + FPU_Reg eind; + } test; + Bit64s sign80= (fpu.regs[TOP].ll&0x8000000000000000)?1:0; + Bit64s exp80 = fpu.regs[TOP].ll&0x7ff0000000000000; + Bit64s exp80final= (exp80>>52) - BIAS64 + BIAS80; + Bit64s mant80 = fpu.regs[TOP].ll&0x000fffffffffffff; + Bit64s mant80final= (mant80 << 11) | 0x8000000000000000; + test.begin= (static_cast(sign80)<<15)| static_cast(exp80final); + test.eind.ll=mant80final; + mem_writed(addr,test.eind.l.lower); + mem_writed(addr+4,test.eind.l.upper); + mem_writew(addr+8,test.begin); +} + + diff --git a/src/fpu/fpu_types.h b/src/fpu/fpu_types.h index 7cec00b2..c459feb8 100644 --- a/src/fpu/fpu_types.h +++ b/src/fpu/fpu_types.h @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + typedef union { double d; #ifndef WORDS_BIGENDIAN @@ -14,15 +32,6 @@ typedef union { Bit64s ll; } FPU_Reg; -/* the following deal with IEEE double-precision numbers */ -#define MAXEXPD 0x7ff -#define EXPBIAS 1023 -#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) -#define SIGND(fp) ((fp.l.upper) & 0x80000000) -#define MANTD(fp) (fp.ll & ((1LL << 52) - 1)) -#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20) - - enum FPU_Tag { TAG_Valid = 0, TAG_Zero = 1, From 5d93540ca0d150aed0437d3ab604716bbdfbe3e2 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 21 Jul 2003 09:38:35 +0000 Subject: [PATCH 1059/4131] Added int 21 6c - Extended open Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1139 --- include/dos_inc.h | 1 + src/dos/dos.cpp | 8 +++++++- src/dos/dos_files.cpp | 26 ++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index b2d2b868..43ba1d15 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -97,6 +97,7 @@ bool DOS_GetFileDate(Bit16u entry, Bit16u* otime, Bit16u* odate); /* Routines for Drive Class */ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry); +bool DOS_OpenFileExtended(char *name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status); bool DOS_CreateFile(char * name,Bit16u attribute,Bit16u * entry); bool DOS_UnlinkFile(char * name); bool DOS_FindFirst(char *search,Bit16u attr); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index c7c548a6..fc6da360 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -833,7 +833,13 @@ static Bitu DOS_21Handler(void) { break; } case 0x6c: /* Extended Open/Create */ - E_Exit("Unhandled Dos 21 call %02X",reg_ah); + MEM_StrCopy(SegPhys(ds)+reg_si,name1,DOSNAMEBUF); + if (DOS_OpenFileExtended(name1,reg_bx,reg_cx,reg_dx,®_ax,®_cx)) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } break; case 0x71: /* Unknown probably 4dos detection */ reg_ax=0x7100; diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index a5babc4b..95f7ae07 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -370,6 +370,32 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { } } +bool DOS_OpenFileExtended(char *name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status) +// FIXME: Not yet supported : Bit 13 of flags (int 0x24 on critical error +{ + Bit16u result = 0; + if (DOS_OpenFile(name, flags, entry)) { + // File already exists + switch (action & 0x0f) { + case 0x00 : return false; // failed + case 0x01 : result = 1; break; // file open (already done) + case 0x02 : DOS_CloseFile(*entry); // replace + if (!DOS_CreateFile(name, flags, entry)) return false; + result = 3; + break; + default : E_Exit("DOS: OpenFileExtended: Unknown action."); + }; + } else { + // File doesnt exist + if ((action & 0xf0)==0) return false; + // Create File + if (!DOS_CreateFile(name, flags, entry)) return false; + result = 2; + }; + *status = result; + return true; +}; + bool DOS_UnlinkFile(char * name) { char fullname[DOS_PATHLENGTH];Bit8u drive; if (!DOS_MakeName(name,fullname,&drive)) return false; From 027ce473e7f3d9eae379835b2e6a6f74bb8bc5a1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 21 Jul 2003 16:56:40 +0000 Subject: [PATCH 1060/4131] fixed the treh demo and some other. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1140 --- src/ints/int10_char.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 4f799a1f..da968f63 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -309,7 +309,7 @@ static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool //TODO Check for out of bounds for (Bit8u h=0;hcheight;h++) { Bit8u bitsel=128; - Bit8u bitline=mem_readb(fontdata); + Bit8u bitline=mem_readb(fontdata++); //added ++ for at least the CGA modes. Bit16u tx=x; while (bitsel) { if (bitline&bitsel) INT10_PutPixel(tx,y,page,attr); From 048006f2ac43934cc514b064365fa29a040b7b34 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 22 Jul 2003 14:01:24 +0000 Subject: [PATCH 1061/4131] removed xms usage, added more log messages Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1141 --- src/ints/dpmi.cpp | 249 +++++++++++++++++++++++++--------------------- 1 file changed, 136 insertions(+), 113 deletions(-) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index 95b53ce0..18fc859b 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -26,7 +26,6 @@ #include "dos_system.h" #include "setup.h" #include "inout.h" -#include "xms.h" #include "cpu.h" //#define DPMI_LOG LOG(LOG_MISC,LOG_ERROR) @@ -88,7 +87,7 @@ #define DPMI_CB_EXCEPTIONRETURN_OFFSET 260*8 #define DPMI_CB_VENDORENTRY_OFFSET 261*8 -#define DPMI_HOOK_HARDWARE_INTS 0 +#define DPMI_HOOK_HARDWARE_INTS 1 static Bitu rmIndexToInt[DPMI_REALVEC_MAX] = { 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x1C }; @@ -249,7 +248,7 @@ private: bool bit32; Bitu psp; } client; - Bit16u xms_handle; /* Handle for GDT/IDT */ + Bit16u mem_handle; /* Handle for GDT/IDT */ struct { PhysPt base; Bitu limit; @@ -357,7 +356,7 @@ DPMI::DPMI(void) DPMI::~DPMI(void) { - XMS_FreeMemory(dpmi.xms_handle); + MEM_ReleasePages(dpmi.mem_handle); // TODO: Free all memory allocated with DOS_GetMemory // Activate previous dpmi activeDPMI = prevDPMI; @@ -1248,6 +1247,16 @@ void DPMI::SetVirtualIntFlag(bool on) dpmi.vIntFlag = on; }; +bool DPMI::AllocateMem(Bitu size, Bitu& outHandle, Bitu& linear) +{ + Bitu pages = (size/DPMI_PAGE_SIZE) + ((size%DPMI_PAGE_SIZE)>0); // Convert to 4KB pages + outHandle = MEM_AllocatePages(pages,true); + linear = outHandle*DPMI_PAGE_SIZE; + if (outHandle!=0) SetXMSHandle(outHandle); + return (outHandle!=0); +}; + +/* bool DPMI::AllocateMem(Bitu size, Bitu& outHandle, Bitu& linear) { Bit16u handle; @@ -1264,11 +1273,10 @@ bool DPMI::AllocateMem(Bitu size, Bitu& outHandle, Bitu& linear) } return false; }; +*/ Bitu DPMI::Int31Handler(void) { - DPMI_LOG("DPMI: %04X",reg_ax); - switch (reg_ax) { case 0x0000:{// Allocate LDT Descriptors @@ -1306,6 +1314,7 @@ Bitu DPMI::Int31Handler(void) desc.saved.seg.dpl=3; desc.Save (dpmi.ldt.base+(base & ~7)); reg_ax = base; + DPMI_LOG("DPMI: 0000: Seg %04X to Desc: %04X",reg_bx,base); DPMI_CALLBACK_SCF(false); } else { // No more Descriptors available @@ -1316,15 +1325,18 @@ Bitu DPMI::Int31Handler(void) }; break; case 0x0003:// Get Next Selector Increment Value reg_ax = 8; + DPMI_LOG("DPMI: 0003: Get Selector Inc Value: %04X",reg_ax); DPMI_CALLBACK_SCF(false); break; case 0x0004:// undocumented (reserved) lock selector case 0x0005:// undocumented (reserved) unlock selector + DPMI_LOG("DPMI: 0004: Undoc: (un)lock selector",reg_ax); DPMI_CALLBACK_SCF(true); break; case 0x0006:{ // Get Segment Base Address SetDescriptor desc; if (cpu.gdt.GetDescriptor(reg_bx,desc)) { + DPMI_LOG("DPMI: 0006: Get Base %04X : B:%08X",reg_bx,desc.GetBase()); reg_cx = desc.GetBase()>>16; reg_dx = desc.GetBase()&0xFFFF; DPMI_CALLBACK_SCF(false); @@ -1344,7 +1356,7 @@ Bitu DPMI::Int31Handler(void) desc.Save (dpmi.ldt.base+(reg_bx & ~7)); ReloadSegments(reg_bx); DPMI_CALLBACK_SCF(false); - DPMI_LOG("DPMI: 0007: Set Base %08X",base); + DPMI_LOG("DPMI: 0007: Set Base %04X : B:%08X",reg_bx,base); } else { DPMI_LOG_ERROR("DPMI: 0007: Invalid Selector: %04X",reg_bx); reg_ax = DPMI_ERROR_INVALID_SELECTOR; @@ -1356,6 +1368,7 @@ Bitu DPMI::Int31Handler(void) if ((!dpmi.client.bit32) && (reg_cx!=0)) { // 16-bit DPMI implementations can not set segment limits greater // than 0FFFFh (64K) so CX must be zero when calling + DPMI_LOG_ERROR("DPMI: 0008: Set Segment Limit invalid: %04X ",reg_bx); reg_ax = DPMI_ERROR_INVALID_VALUE; DPMI_CALLBACK_SCF(true); } else if (cpu.gdt.GetDescriptor(reg_bx,desc)) { @@ -1400,8 +1413,10 @@ Bitu DPMI::Int31Handler(void) }; break; case 0x000A:{// Create Alias Descriptor Descriptor desc; - if (CreateAlias(reg_bx, reg_ax)) DPMI_CALLBACK_SCF(false); - else { + if (CreateAlias(reg_bx, reg_ax)) { + DPMI_LOG("DPMI: 000A: Create Alias : %04X - %04X",reg_bx,reg_ax); + DPMI_CALLBACK_SCF(false); + } else { DPMI_CALLBACK_SCF(true); DPMI_LOG_ERROR("DPMI: 000A: Invalid Selector: %04X",reg_bx); }; }; break; @@ -1433,13 +1448,13 @@ Bitu DPMI::Int31Handler(void) desc.saved.seg.p = 1; } // desc.saved.seg.type |= 0x10; -// if (!dpmi.client.bit32) +// if (!dpmi.client.bit32) { // desc.SetBase (desc.GetBase() & 0xFFFF); // desc.SetLimit (desc.GetLimit() & 0xFFFF); // }; desc.Save(dpmi.ldt.base+(reg_bx & ~7)); ReloadSegments(reg_bx); - DPMI_LOG("DPMI: 000C: Base %08X : Limit %08X : P %01X",desc.GetBase(),desc.GetLimit(),desc.saved.seg.p); + DPMI_LOG("DPMI: 000B: Set Descriptor %04X : B:%08X L:%08X : P %01X",reg_bx,desc.GetBase(),desc.GetLimit(),desc.saved.seg.p); DPMI_CALLBACK_SCF(false); } else { DPMI_LOG_ERROR("DPMI: 000C: Set Descriptor %04X failed",reg_bx); @@ -1529,6 +1544,7 @@ Bitu DPMI::Int31Handler(void) sel+=8; }; DPMI_CALLBACK_SCF(false); + DPMI_LOG_ERROR("DPMI: 0101: Free Dos Mem: %04X",reg_dx); break; } } @@ -1540,9 +1556,11 @@ Bitu DPMI::Int31Handler(void) RealPt vec = RealGetVec(reg_bl); reg_cx = RealSeg(vec); reg_dx = RealOff(vec); + DPMI_LOG("DPMI: 0200: Get Real Int Vector %02X (%04X:%04X)",reg_bl,reg_cx,reg_dx); DPMI_CALLBACK_SCF(false); }; break; case 0x0201:{// Set Real Mode Interrupt Vector + DPMI_LOG("DPMI: 0201: Set Real Int Vector %02X (%04X:%04X)",reg_bl,reg_cx,reg_dx); RealSetVec(reg_bl,RealMake(reg_cx,reg_dx)); DPMI_CALLBACK_SCF(false); }; break; @@ -1550,6 +1568,7 @@ Bitu DPMI::Int31Handler(void) if (reg_bl>16); reg_cx = (linear&0xFFFF); + total = MEM_FreeLargest(); // in KB DPMI_CALLBACK_SCF(false); - XMS_QueryFreeMemory(largest,total); // in KB - DPMI_LOG("DPMI: 0501: Allocation success: H:%04X%04X (%d KB) (R:%d KB)",reg_si,reg_di,length/1024,total); + DPMI_LOG("DPMI: 0501: Allocation success: H:%04X%04X (%d KB) (R:%d KB)",reg_si,reg_di,length/1024 + ((length%1024)>0),total*4); } else { reg_ax = DPMI_ERROR_PHYSICAL_MEMORY_UNAVAILABLE; DPMI_CALLBACK_SCF(true); - XMS_QueryFreeMemory(largest,total); // in KB - DPMI_LOG_ERROR("DPMI: 0501: Allocation failure (%d KB) (R:%d KB)",length/1024,total); + total = MEM_FreeLargest(); // in KB + DPMI_LOG("DPMI: 0501: Allocation failure (%d KB) (R:%d KB)",length/1024 + ((length%1024)>0),total*4); }; }; break; case 0x0502://Free Memory Block DPMI_LOG("DPMI: 0502: Free Mem: H:%04X%04X",reg_si,reg_di); - if (XMS_FreeMemory((reg_si<<16)+reg_di)==0) { - FreeXMSHandle((reg_si<<16)+reg_di); - DPMI_CALLBACK_SCF(false); - } else { - DPMI_LOG_ERROR("DPMI: 0502: Invalid Handle: %04X%04X",reg_si,reg_di); - reg_ax = DPMI_ERROR_INVALID_HANDLE; - DPMI_CALLBACK_SCF(true); - }; + MEM_ReleasePages((reg_si<<16)+reg_di); + FreeXMSHandle((reg_si<<16)+reg_di); + DPMI_CALLBACK_SCF(false); break; case 0x0503:{//Resize Memory Block - Bitu newByte = (reg_bx<<16)+reg_cx; - Bit32u newSize = (newByte/1024)+((newByte & 1023)>0); - Bitu handle = (reg_si<<16)+reg_di; - DPMI_LOG("DPMI: 0503: Resize Memory: H:%08X (%d KB)",handle,newSize); - if (XMS_ResizeMemory(handle,newSize)==0) { - if (XMS_LockMemory(handle,newSize)==0) { - reg_bx = (newSize>>16); - reg_cx = (newSize&0xFFFF); - DPMI_CALLBACK_SCF(false); - XMS_UnlockMemory(handle); - break; - } + Bitu newByte = (reg_bx<<16)+reg_cx; + Bitu newSize = (newByte/DPMI_PAGE_SIZE)+((newByte & (DPMI_PAGE_SIZE-1))>0); + MemHandle handle = (reg_si<<16)+reg_di; + DPMI_LOG_ERROR("DPMI: 0503: Resize Memory: H:%08X (%d KB)",handle,newSize*4); + if (MEM_ReAllocatePages(handle,newSize,true)) { + reg_bx = (newSize>>16); + reg_cx = (newSize&0xFFFF); + DPMI_CALLBACK_SCF(false); + break; } else { Bitu newHandle,linear; // Not possible, try to allocate if (AllocateMem((reg_bx<<16)+reg_cx,newHandle,linear)) { - DPMI_LOG_ERROR("DPMI: 0503: Reallocated Memory: %d KB",newSize); + DPMI_LOG_ERROR("DPMI: 0503: Reallocated Memory: %d KB",newSize*4); reg_si = 0; reg_di = newHandle; reg_bx = (linear>>16); reg_cx = (linear&0xFFFF); DPMI_CALLBACK_SCF(false); // FIXME: What to do with the old mem block ? delete ? // FIXME: Copy contents ?! - if (XMS_FreeMemory(handle)==0) { - FreeXMSHandle(handle); - } else { - DPMI_LOG_ERROR("DPMI: 0503: Free old memory failure"); - }; + MEM_ReleasePages(handle); + FreeXMSHandle(handle); break; } else { AllocateMem((reg_bx<<16)+reg_cx,newHandle,linear); - DPMI_LOG_ERROR("DPMI: 0503: Reallocated Memory failure: %d KB",newSize); + DPMI_LOG_ERROR("DPMI: 0503: Reallocated Memory failure: %d KB",newSize*4); } }; DPMI_LOG_ERROR("DPMI: 0503: Memory unavailable . %08X",newSize); @@ -1745,58 +1760,63 @@ Bitu DPMI::Int31Handler(void) DPMI_CALLBACK_SCF(true); }; break; case 0x0506:// Get Page Attributes + DPMI_LOG("DPMI: 0506: Get Page Attributes"); reg_ax = DPMI_ERROR_UNSUPPORTED; DPMI_CALLBACK_SCF(true); break; case 0x0507:// Set Page Attributes + DPMI_LOG("DPMI: 0507: Set Page Attributes"); DPMI_CALLBACK_SCF(false); break; case 0x0509:{//Map Conventional Memory in Memory Block - DPMI_LOG_ERROR("DPMI: 0509: Mapping convmem not supported."); - reg_ax = DPMI_ERROR_UNSUPPORTED; - DPMI_CALLBACK_SCF(true); -/* Bit32u xmsAddress; + Bitu xmsAddress = reg_esi*DPMI_PAGE_SIZE; Bitu handle = reg_esi; Bitu offset = reg_ebx; Bitu numPages = reg_ecx; Bitu linearAdr = reg_edx; - if (XMS_LockMemory(handle,xmsAddress)==0) { - LOG(LOG_MISC,LOG_ERROR)("DPMI: 0509: Mapping convmem %04X to %08X",linearAdr,xmsAddress+offset); - if ((numPages%4)!=0) E_Exit("DPMI: Cannot map conventional memory."); -// MEM_SetupMapping(PAGE_COUNT((xmsAddress+offset)),PAGE_COUNT(numPages*DPMI_PAGE_SIZE),((Bit8u*)memory)+linearAdr); - XMS_UnlockMemory(handle); - DPMI_CALLBACK_SCF(false); - } else { - LOG(LOG_MISC,LOG_ERROR)("DPMI: 0509: Mapping convmem failure."); - reg_ax = DPMI_ERROR_INVALID_HANDLE; - DPMI_CALLBACK_SCF(true); - }*/ + if ((linearAdr & 3) || ((xmsAddress+offset) & 3)) { + // Not page aligned + DPMI_LOG_ERROR("DPMI: Cannot map conventional memory (address not page aligned)."); + reg_ax = DPMI_ERROR_INVALID_LINEAR_ADDRESS; + DPMI_CALLBACK_SCF(true); + break; + } + MEM_MapPagesDirect(linearAdr/DPMI_PAGE_SIZE,(xmsAddress+offset)/DPMI_PAGE_SIZE,numPages); + DPMI_CALLBACK_SCF(false); }; break; case 0x0600:{//Lock Linear Region + DPMI_LOG("DPMI: 0600: Lock Linear Region"); Bitu address = (reg_bx<<16)+reg_cx; Bitu size = (reg_si<<16)+reg_di; DPMI_CALLBACK_SCF(false); }; break; case 0x0601://unlock Linear Region + DPMI_LOG("DPMI: 0601: Unlock Linear Region"); DPMI_CALLBACK_SCF(false); break; case 0x0602:// Mark Real Mode Region as Pageable + DPMI_LOG("DPMI: 0602: Mark Realmode Region pageable"); DPMI_CALLBACK_SCF(false); break; case 0x0603:// Relock Real Mode Region + DPMI_LOG("DPMI: 0603: Relock Realmode Region"); DPMI_CALLBACK_SCF(false); break; case 0x0604:// Get page size reg_bx=0; reg_cx=DPMI_PAGE_SIZE; + DPMI_LOG("DPMI: 0604: Get Page Size: %04X",reg_cx); DPMI_CALLBACK_SCF(false); break; case 0x0701:// Undocumented discard page contents + DPMI_LOG("DPMI: 0701: Discard Page contents"); DPMI_CALLBACK_SCF(true); break; case 0x0702://Mark Page as Demand Paging Candidate + DPMI_LOG("DPMI: 0702: Mark page as demand paging candidate"); DPMI_CALLBACK_SCF(false); break; case 0x0703://Discard Page contents + DPMI_LOG("DPMI: 0703: Discard Page contents"); DPMI_CALLBACK_SCF(false); break; case 0x0800:{//Physical Address Mapping @@ -1807,20 +1827,24 @@ Bitu DPMI::Int31Handler(void) DPMI_CALLBACK_SCF(false); }; break; case 0x0801:// Free physical address mapping + DPMI_LOG("DPMI: 0801: Free physical address mapping"); DPMI_CALLBACK_SCF(false); break; case 0x0900://Get and Disable Virtual Interrupt State reg_al = dpmi.vIntFlag; dpmi.vIntFlag = 0; + DPMI_LOG("DPMI: 0900: Get and disbale vi : %01X",reg_al); DPMI_CALLBACK_SCF(false); break; case 0x0901://Get and Enable Virtual Interrupt State reg_al = dpmi.vIntFlag; dpmi.vIntFlag = 1; + DPMI_LOG("DPMI: 0901: Get and enable vi : %01X",reg_al); DPMI_CALLBACK_SCF(false); break; case 0x0902:{//Get Virtual Interrupt State reg_al = dpmi.vIntFlag; + DPMI_LOG("DPMI: 0900: Get vi : %01X",reg_al); DPMI_CALLBACK_SCF(false); }; break; case 0x0A00:{//Get Vendor Specific API Entry Point @@ -1845,35 +1869,32 @@ Bitu DPMI::Int31Handler(void) }; break; case 0x0D00:{//Allocate Shared Memory PhysPt data = SegPhys(es)+reg_edi; - Bit32u linadr; Bitu length = mem_readd(data); - Bitu pages = (length/1024) + ((length%1024)>0); - Bit16u handle; - if (XMS_AllocateMemory(pages,handle)==0) { - if (XMS_LockMemory(handle,linadr)==0) { - SetXMSHandle(handle); - mem_writed(data+0x04,pages*1024); - mem_writed(data+0x08,handle); - mem_writed(data+0x0C,linadr); - DPMI_CALLBACK_SCF(false); - XMS_UnlockMemory(handle); - DPMI_LOG("DPMI: 0D00: Allocation shared success (%d KB)",pages*1024); - break; - } - } - DPMI_LOG_ERROR("DPMI: 0D00: Allocation shared failure (%d KB)",pages*1024); - reg_ax = DPMI_ERROR_PHYSICAL_MEMORY_UNAVAILABLE; - DPMI_CALLBACK_SCF(true); + Bitu pages = (length/DPMI_PAGE_SIZE)+((length%DPMI_PAGE_SIZE)>0); + Bitu handle,linear; + if (AllocateMem(length,handle,linear)) { + DPMI_LOG("DPMI: 0D00: Allocate shared memory (%d KB)",pages*4); + mem_writed(data+0x04,pages*DPMI_PAGE_SIZE); + mem_writed(data+0x08,handle); + mem_writed(data+0x0C,linear); + DPMI_CALLBACK_SCF(false); + } else { + DPMI_LOG_ERROR("DPMI: 0D00: Allocation shared failure (%d KB)",pages*4); + reg_ax = DPMI_ERROR_PHYSICAL_MEMORY_UNAVAILABLE; + DPMI_CALLBACK_SCF(true); + }; }; break; case 0x0B00:// Set debug watchpoint case 0x0B01:// Clear debug watchpoint DPMI_CALLBACK_SCF(true); break; case 0x0E00:// Get Coprocessor Status + DPMI_LOG("DPMI: 0E00: Get Coprocessor status"); reg_ax = 0x45; // nope, no coprocessor DPMI_CALLBACK_SCF(false); break; case 0x0E01:// Set Coprocessor Emulation + DPMI_LOG("DPMI: 0E01: Set Coprocessor emulation"); DPMI_CALLBACK_SCF(true); // failure break; default :LOG(LOG_MISC,LOG_ERROR)("DPMI: Unsupported func %04X",reg_ax); @@ -1984,7 +2005,7 @@ void DPMI::Terminate(void) // 2.Deallocate Callbacks for (i=0; i> 10,dpmi.xms_handle)) { + Bitu xmssize = (TOTAL_SIZE|(DPMI_PAGE_SIZE-1))+1; + Bitu protStackSize = ((DPMI_PROTMODE_STACK_MAX*DPMI_PROTMODE_STACKSIZE)|(DPMI_PAGE_SIZE-1))+1; + Bitu sizePages = ((xmssize+protStackSize) >> 12); + + dpmi.mem_handle = MEM_AllocatePages(sizePages,true); + if (dpmi.mem_handle==0) { LOG_MSG("DPMI:Can't allocate XMS memory, disabling dpmi support."); return; } + // Allocate real mode stack space rm_ss = DOS_GetMemory(DPMI_REALMODE_STACKSIZE/16); rm_sp = DPMI_REALMODE_STACKSIZE; /* Allocate the GDT,LDT,IDT Stack space */ - Bit32u address; - XMS_LockMemory(dpmi.xms_handle,address); + Bitu address = dpmi.mem_handle*DPMI_PAGE_SIZE;; // Get Begin of protected mode stack dpmi.protStack = address + xmssize; /* Clear the memory */ @@ -2463,13 +2487,12 @@ Bitu DPMI::API_Entry_MSDOS(void) Bitu DPMI::API_Int21_MSDOS(void) { - LOG(LOG_MISC,LOG_ERROR)("DPMI:MSDOS-API:INT 21 %04X",reg_ax); + DPMI_LOG("DPMI:MSDOS-API:INT 21 %04X",reg_ax); Bitu protsel,protoff,seg,off; Bitu sax = reg_ax; switch (reg_ah) { case 0x1a: /* Set Disk Transfer Area Address */ - LOG(LOG_MISC,LOG_ERROR)("DPMI:MSDOS:Set DTA not supported"); dtaAddress = SegPhys(ds) + reg_edx; break; case 0x25: { // Set Protected mode Interrupt Vector @@ -2534,10 +2557,10 @@ Bitu DPMI::API_Int21_MSDOS(void) char name1[256]; MEM_StrCopy(SegPhys(ds)+reg_edx,name1,255); if (DOS_OpenFile(name1,reg_al,®_ax)) { - LOG(LOG_MISC,LOG_ERROR)("DOS: Open success: %s",name1); + DPMI_LOG("DOS: Open success: %s",name1); DPMI_CALLBACK_SCF(false); } else { - LOG(LOG_MISC,LOG_ERROR)("DOS: Open failure: %s",name1); + DPMI_LOG("DOS: Open failure: %s",name1); reg_ax=dos.errorcode; DPMI_CALLBACK_SCF(true); } @@ -2610,7 +2633,7 @@ Bitu DPMI::API_Int21_MSDOS(void) } break; case 0x01: /* Set */ - LOG(LOG_MISC,LOG_ERROR)("DOS:Set File Attributes for %s not supported",name1); + DPMI_LOG_ERROR("DOS:Set File Attributes for %s not supported",name1); DPMI_CALLBACK_SCF(false); break; default: @@ -2648,7 +2671,7 @@ Bitu DPMI::API_Int21_MSDOS(void) if (dpmi.pharlap) dos.psp = reg_bx; // pharlap uses real mode paragraph address else dos.psp = GetSegmentFromSelector(reg_bx); - LOG(LOG_MISC,LOG_ERROR)("DPMI:MSDOS:0x50:Set current psp:%04X",reg_bx); + DPMI_LOG("DPMI:MSDOS:0x50:Set current psp:%04X",reg_bx); break; case 0x51: /* Get current PSP */ if (dpmi.pharlap) reg_bx = dos.psp; // pharlap uses real mode paragraph address @@ -2656,13 +2679,13 @@ Bitu DPMI::API_Int21_MSDOS(void) GetMsdosSelector(dos.psp,0x0000,protsel,protoff); reg_bx = protsel; }; - LOG(LOG_MISC,LOG_ERROR)("DPMI:MSDOS:0x51:Get current psp:%04X",reg_bx); + DPMI_LOG("DPMI:MSDOS:0x51:Get current psp:%04X",reg_bx); break; case 0x55 : { // Neuen PSP erstellen Bitu segment = GetSegmentFromSelector(reg_dx); DOS_ChildPSP(segment,reg_si); dos.psp = segment; - LOG(LOG_MISC,LOG_ERROR)("DPMI:MSDOS:0x55:Create new psp:%04X",segment); + DPMI_LOG("DPMI:MSDOS:0x55:Create new psp:%04X",segment); }; break; case 0x5D : // Get Address of dos swappable area // FIXME: This is totally faked... @@ -2671,12 +2694,12 @@ Bitu DPMI::API_Int21_MSDOS(void) GetMsdosSelector(0xDEAD,0xDEAD,protsel,protoff); CPU_SetSegGeneral(ds,protsel); reg_si = protoff; - LOG(LOG_MISC,LOG_ERROR)("DPMI:MSDOS:0x5D:Get Addres of DOS SwapArea:%04X",reg_si); + DPMI_LOG("DPMI:MSDOS:0x5D:Get Addres of DOS SwapArea:%04X",reg_si); break; case 0x62 : /* Get Current PSP Address */ GetMsdosSelector(dos.psp,0x0000,protsel,protoff); reg_bx = protsel; - LOG(LOG_MISC,LOG_ERROR)("DPMI:MSDOS:0x62:Get current psp:%04X",reg_bx); + DPMI_LOG("DPMI:MSDOS:0x62:Get current psp:%04X",reg_bx); break; case 0x09: From 7ee73a90b7a078e2e744115c949f31e61477898c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 23 Jul 2003 11:45:08 +0000 Subject: [PATCH 1062/4131] Hack for 0xcd memory no longer needed Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1142 --- src/dos/dos_execute.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index c03331cd..57eff983 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -142,9 +142,6 @@ static bool MakeEnv(char * name,Bit16u * segment) { } if (parentenv) { - // hack to allow creation from envblock in unused mem (0xCD) - if (mem_readb(envread)==0xCDCD) mem_writew(envread,0x0000); - for (envsize=0; ;envsize++) { if (envsize>=MAXENV - ENV_KEEPFREE) { DOS_SetError(DOSERR_ENVIRONMENT_INVALID); From 4092577e26c48e90c4221bcc31c106a11da79280 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 23 Jul 2003 11:50:15 +0000 Subject: [PATCH 1063/4131] Check correct types for -t option of mount Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1143 --- src/dos/dos_programs.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index c00b7f8c..98ae9df6 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -68,14 +68,15 @@ public: if (type=="floppy") { str_size="512,1,2847,2847";/* All space free */ mediaid=0xF0; /* Floppy 1.44 media */ - } - if (type=="dir") { + } else if (type=="dir") { str_size="512,127,16513,1700"; mediaid=0xF8; /* Hard Disk */ - } - if (type=="cdrom") { + } else if (type=="cdrom") { str_size="650,127,16513,1700"; mediaid=0xF8; /* Hard Disk */ + } else { + WriteOut(MSG_Get("PROGAM_MOUNT_ILL_TYPE"),type.c_str()); + return; } cmd->FindString("-size",str_size,true); char number[20];const char * scan=str_size.c_str(); @@ -131,6 +132,9 @@ public: } else { newdrive=new localDrive(temp_line.c_str(),sizes[0],bit8size,sizes[2],sizes[3],mediaid); } + } else { + WriteOut(MSG_Get("PROGRAM_MOUNT_ILL_TYPE"),type.c_str()); + return; } if (Drives[drive-'A']) { WriteOut(MSG_Get("PROGRAM_MOUNT_ALLREADY_MOUNTED"),drive,Drives[drive-'A']->GetInfo()); @@ -293,6 +297,7 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_MOUNT_STATUS_1","Current mounted drives are:\n"); MSG_Add("PROGRAM_MOUNT_ERROR_1","Directory %s doesn't exist.\n"); MSG_Add("PROGRAM_MOUNT_ERROR_2","%s isn't a directory\n"); + MSG_Add("PROGRAM_MOUNT_ILL_TYPE","Illegal type %s\n"); MSG_Add("PROGRAM_MOUNT_ALLREADY_MOUNTED","Drive %c already mounted with %s\n"); MSG_Add("PROGRAM_MOUNT_USAGE","Usage MOUNT Drive-Letter Local-Directory\nSo a MOUNT c c:\\windows mounts windows directory as the c: drive in DOSBox\n"); From f2f9b04b5ce442b25ba86b1f61d6a15c76f7b126 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 24 Jul 2003 10:31:41 +0000 Subject: [PATCH 1064/4131] DOS_Execute: Moved creation of psp after closing exe, to avoid dead file handle of exe in copied psp. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1144 --- src/dos/dos_execute.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 57eff983..4c4147f7 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -292,9 +292,6 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { else memsize=maxsize; if (!DOS_AllocateMemory(&pspseg,&memsize)) E_Exit("DOS:Exec error in memory"); loadseg=pspseg+16; - /* Setup a psp */ - SetupPSP(pspseg,memsize,envseg); - SetupCMDLine(pspseg,block); } else loadseg=block.overlay.loadseg; /* Load the executable */ Bit8u * loadbuf=(Bit8u *)new Bit8u[0x10000]; @@ -331,6 +328,14 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { } delete[] loadbuf; DOS_CloseFile(fhandle); + + /* Setup a psp */ + if (flags!=OVERLAY) { + // Create psp after closing exe, to avoid dead file handle of exe in copied psp + SetupPSP(pspseg,memsize,envseg); + SetupCMDLine(pspseg,block); + }; + CALLBACK_SCF(false); /* Carry flag cleared for caller if successfull */ if (flags==OVERLAY) return true; /* Everything done for overlays */ RealPt csip,sssp; From d61bdb00947fe0be485d6c4d441d11129563f948 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Jul 2003 12:39:59 +0000 Subject: [PATCH 1065/4131] Added LONGTYPE => long long for different platforms Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1145 --- include/cross.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/cross.h b/include/cross.h index 813ff256..730bdc88 100644 --- a/include/cross.h +++ b/include/cross.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,9 +26,11 @@ #if defined (_MSC_VER) /* MS Visual C++ */ #include #include -#else /* LINUX */ +#define LONGTYPE(a) a##i64 +#else /* LINUX / GCC */ #include #include +#define LONGTYPE(a) a##LL #endif #define CROSS_LEN 512 /* Maximum filename size */ From cdf4503fe042fdb99ead219380263b76616b6b6a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Jul 2003 12:41:33 +0000 Subject: [PATCH 1066/4131] Changed long constants to LONGTYPE for compiler issues include cross.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1146 --- src/fpu/fpu.cpp | 1 + src/fpu/fpu_instructions.h | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 66934324..dac36612 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -21,6 +21,7 @@ #include #include +#include "cross.h" #include "mem.h" #include "fpu.h" #include "cpu.h" diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 57d7d6ac..438d2f0d 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -208,7 +208,7 @@ static void FPU_FXAM(void){ FPU_SET_C3(1);FPU_SET_C0(1); return; } - if(fpu.regs[TOP].ll & 0x8000000000000000) //sign + if(fpu.regs[TOP].ll & LONGTYPE(0x8000000000000000)) //sign { FPU_SET_C1(1); } @@ -271,7 +271,7 @@ static void FPU_FLD80(PhysPt addr) Bit64s blah= ((exp64 >0)?exp64:-exp64)&0x3ff; Bit64s exp64final= ((exp64 >0)?blah:-blah) +BIAS64; - Bit64s mant64= (test.eind.ll >> 11) & 0xfffffffffffff; + Bit64s mant64= (test.eind.ll >> 11) & LONGTYPE(0xfffffffffffff); Bit64s sign = (test.begin &0x8000)?1:0; FPU_Reg result; result.ll= (sign <<63)|(exp64final << 52)| mant64; @@ -285,11 +285,11 @@ static void FPU_ST80(PhysPt addr) Bit16s begin; FPU_Reg eind; } test; - Bit64s sign80= (fpu.regs[TOP].ll&0x8000000000000000)?1:0; - Bit64s exp80 = fpu.regs[TOP].ll&0x7ff0000000000000; + Bit64s sign80= (fpu.regs[TOP].ll&LONGTYPE(0x8000000000000000))?1:0; + Bit64s exp80 = fpu.regs[TOP].ll&LONGTYPE(0x7ff0000000000000); Bit64s exp80final= (exp80>>52) - BIAS64 + BIAS80; - Bit64s mant80 = fpu.regs[TOP].ll&0x000fffffffffffff; - Bit64s mant80final= (mant80 << 11) | 0x8000000000000000; + Bit64s mant80 = fpu.regs[TOP].ll&LONGTYPE(0x000fffffffffffff); + Bit64s mant80final= (mant80 << 11) | LONGTYPE(0x8000000000000000); test.begin= (static_cast(sign80)<<15)| static_cast(exp80final); test.eind.ll=mant80final; mem_writed(addr,test.eind.l.lower); From 54ef7a5825bf9ebb8d434396f2956b77428ca8d5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Jul 2003 12:42:17 +0000 Subject: [PATCH 1067/4131] Warning cleanup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1147 --- src/gui/render.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 356c6283..bf65ece0 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -252,7 +252,9 @@ void RENDER_DoUpdate(void) { static void RENDER_DrawScreen(void * data) { switch (render.op.type) { +#if (C_SSHOT) doagain: +#endif case OP_None: render.op.dest=render.op.pixels=data; render.src.draw_handler(render.op.part_handler); From 2daf8b32c747e43adc18ed7619afc18321f4d3ed Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 24 Jul 2003 19:13:58 +0000 Subject: [PATCH 1068/4131] Added MEM_AllocatedPages. Get amount of allocated pages of handle Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1148 --- include/mem.h | 1 + src/hardware/memory.cpp | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/mem.h b/include/mem.h index 61d53312..509a4416 100644 --- a/include/mem.h +++ b/include/mem.h @@ -38,6 +38,7 @@ HostPt MEM_GetBlockPage(void); Bitu MEM_FreeTotal(void); //Free 4 kb 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 MemHandle MEM_AllocatePages(Bitu pages,bool sequence); PhysPt MEM_AllocatePage(void); void MEM_ReleasePages(MemHandle handle); diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index d10e41cc..94e5b51a 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -468,7 +468,6 @@ Bitu MEM_FreeLargest(void) { return largest; } - Bitu MEM_FreeTotal(void) { Bitu free=0; Bitu index=XMS_START; @@ -479,6 +478,15 @@ Bitu MEM_FreeTotal(void) { return free; } +Bitu MEM_AllocatedPages(MemHandle handle) +{ + Bitu pages = 0; + while (handle>0) { + pages++; + handle=memory.entries[handle].next_handle; + } + return pages; +} //TODO Maybe some protection for this whole allocation scheme From 7a0bfeb19400985e2740770dfcdee6961c83b5d8 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 24 Jul 2003 19:14:47 +0000 Subject: [PATCH 1069/4131] Fixed a resize memory bug Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1149 --- src/ints/dpmi.cpp | 64 ++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index 18fc859b..0bbdb8e4 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -1703,20 +1703,21 @@ Bitu DPMI::Int31Handler(void) case 0x0501:{// Allocate Memory Bitu handle,linear; Bitu length = (reg_bx<<16)+reg_cx; - // TEMP - Bitu total; //DPMI_LOG("DPMI: 0501: Allocate memory (%d KB)",length/1024); if (AllocateMem(length,handle,linear)) { - reg_si = 0; reg_di = handle; - reg_bx = (linear>>16); - reg_cx = (linear&0xFFFF); - total = MEM_FreeLargest(); // in KB + reg_si = handle>>16; + reg_di = handle&0xFFFF; + reg_bx = linear>>16; + reg_cx = linear&0xFFFF; DPMI_CALLBACK_SCF(false); + // TEMP + Bitu total = MEM_FreeLargest(); // in KB DPMI_LOG("DPMI: 0501: Allocation success: H:%04X%04X (%d KB) (R:%d KB)",reg_si,reg_di,length/1024 + ((length%1024)>0),total*4); } else { reg_ax = DPMI_ERROR_PHYSICAL_MEMORY_UNAVAILABLE; DPMI_CALLBACK_SCF(true); - total = MEM_FreeLargest(); // in KB + // TEMP + Bitu total = MEM_FreeLargest(); // in KB DPMI_LOG("DPMI: 0501: Allocation failure (%d KB) (R:%d KB)",length/1024 + ((length%1024)>0),total*4); }; }; break; @@ -1727,37 +1728,38 @@ Bitu DPMI::Int31Handler(void) DPMI_CALLBACK_SCF(false); break; case 0x0503:{//Resize Memory Block + Bitu linear,newHandle; Bitu newByte = (reg_bx<<16)+reg_cx; Bitu newSize = (newByte/DPMI_PAGE_SIZE)+((newByte & (DPMI_PAGE_SIZE-1))>0); MemHandle handle = (reg_si<<16)+reg_di; - DPMI_LOG_ERROR("DPMI: 0503: Resize Memory: H:%08X (%d KB)",handle,newSize*4); + DPMI_LOG("DPMI: 0503: Resize Memory: H:%08X (%d KB)",handle,newSize*4); if (MEM_ReAllocatePages(handle,newSize,true)) { - reg_bx = (newSize>>16); - reg_cx = (newSize&0xFFFF); + linear = handle * DPMI_PAGE_SIZE; + reg_si = handle>>16; + reg_di = handle&0xFFFF; + reg_bx = linear>>16; + reg_cx = linear&0xFFFF; DPMI_CALLBACK_SCF(false); - break; - } else { - Bitu newHandle,linear; + } else if (AllocateMem(newByte,newHandle,linear)) { // Not possible, try to allocate - if (AllocateMem((reg_bx<<16)+reg_cx,newHandle,linear)) { - DPMI_LOG_ERROR("DPMI: 0503: Reallocated Memory: %d KB",newSize*4); - reg_si = 0; reg_di = newHandle; - reg_bx = (linear>>16); - reg_cx = (linear&0xFFFF); - DPMI_CALLBACK_SCF(false); - // FIXME: What to do with the old mem block ? delete ? - // FIXME: Copy contents ?! - MEM_ReleasePages(handle); - FreeXMSHandle(handle); - break; - } else { - AllocateMem((reg_bx<<16)+reg_cx,newHandle,linear); - DPMI_LOG_ERROR("DPMI: 0503: Reallocated Memory failure: %d KB",newSize*4); - } + DPMI_LOG("DPMI: 0503: Reallocated Memory: %d KB",newSize*4); + reg_si = newHandle>>16; + reg_di = newHandle&0xFFFF; + reg_bx = linear>>16; + reg_cx = linear&0xFFFF; + // copy contents + Bitu size = MEM_AllocatedPages(handle); + if (newSize Date: Fri, 25 Jul 2003 11:15:08 +0000 Subject: [PATCH 1070/4131] Fix for timing/crashings problem caused by large count when used with scas/cmps Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1150 --- src/cpu/core_full/string.h | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index f9a80136..183c2d97 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -31,7 +31,6 @@ } else { /* Won't interrupt scas and cmps instruction since they can interrupt themselves */ count_left=0; - CPU_Cycles-=count; } } add_index=GETFLAG(DF) ? -1 : 1; @@ -141,7 +140,7 @@ { Bit8u val2; for (;count>0;) { - count--; + count--;CPU_Cycles--; val2=LoadMb(di_base+di_index); di_index=(di_index+add_index) & add_mask; if ((reg_al==val2)!=inst.repz) break; @@ -153,7 +152,7 @@ { add_index<<=1;Bit16u val2; for (;count>0;) { - count--; + count--;CPU_Cycles--; val2=LoadMw(di_base+di_index); di_index=(di_index+add_index) & add_mask; if ((reg_ax==val2)!=inst.repz) break; @@ -165,7 +164,7 @@ { add_index<<=2;Bit32u val2; for (;count>0;) { - count--; + count--;CPU_Cycles--; val2=LoadMd(di_base+di_index); di_index=(di_index+add_index) & add_mask; if ((reg_eax==val2)!=inst.repz) break; @@ -177,7 +176,7 @@ { Bit8u val1,val2; for (;count>0;) { - count--; + count--;CPU_Cycles--; val1=LoadMb(si_base+si_index); val2=LoadMb(di_base+di_index); si_index=(si_index+add_index) & add_mask; @@ -191,7 +190,7 @@ { add_index<<=1;Bit16u val1,val2; for (;count>0;) { - count--; + count--;CPU_Cycles--; val1=LoadMw(si_base+si_index); val2=LoadMw(di_base+di_index); si_index=(si_index+add_index) & add_mask; @@ -205,7 +204,7 @@ { add_index<<=2;Bit32u val1,val2; for (;count>0;) { - count--; + count--;CPU_Cycles--; val1=LoadMd(si_base+si_index); val2=LoadMd(di_base+di_index); si_index=(si_index+add_index) & add_mask; From 4a07f3e97bad3f249da1cbe6751359cd8a30b01f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 26 Jul 2003 10:25:38 +0000 Subject: [PATCH 1071/4131] new callback and tick handling in main loop. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1151 --- src/dosbox.cpp | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 65120b05..0ca13ceb 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -99,24 +99,31 @@ void INT10_Init(Section*); static LoopHandler * loop; -Bitu RemainTicks;; -Bitu LastTicks; +Bits RemainTicks;; +Bits LastTicks; static Bitu Normal_Loop(void) { - Bitu ret,NewTicks; - while (RemainTicks) { - ret=PIC_RunQueue(); - #if C_DEBUG - if (DEBUG_ExitLoop()) return 0; - #endif - if (ret) return ret; - RemainTicks--; - TIMER_AddTick(); - GFX_Events(); + Bits ret,NewTicks; + while (1) { + if (PIC_RunQueue()) { + ret=(*cpudecoder)(); + if (ret<0) return 1; + if (ret>0) { + Bitu blah=(*CallBack_Handlers[ret])(); + if (blah) return blah; + } + } else { + if (RemainTicks>0) { + TIMER_AddTick(); + RemainTicks--; + GFX_Events(); + } else goto increaseticks; + } } +increaseticks: NewTicks=GetTicks(); if (NewTicks>LastTicks) { - RemainTicks+=NewTicks-LastTicks; + RemainTicks=NewTicks-LastTicks; if (RemainTicks>20) { // LOG_DEBUG("Ticks to handle overflow %d",RemainTicks); RemainTicks=20; @@ -124,7 +131,7 @@ static Bitu Normal_Loop(void) { LastTicks=NewTicks; } //TODO Make this selectable in the config file, since it gives some lag */ - if (!RemainTicks) { + if (RemainTicks<=0) { SDL_Delay(1); return 0; } From bafbf29f94cb4513e87264baeec5c53728f3ae6e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 26 Jul 2003 10:33:37 +0000 Subject: [PATCH 1072/4131] New handling of pmode related functions Preperations for taskswitching/v86 mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1152 --- include/cpu.h | 63 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 4c266319..40ea13f0 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -30,13 +30,20 @@ extern Bits CPU_CycleMax; /* Some common Defines */ /* A CPU Handler */ -typedef Bitu (CPU_Decoder)(void); +typedef Bits (CPU_Decoder)(void); extern CPU_Decoder * cpudecoder; //CPU Stuff void SetCPU16bit( ); +enum CODE_TYPE { + CODE_REAL, + CODE_PMODE16, + CODE_PMODE32, + CODE_INIT, +}; + extern bool parity_lookup[256]; void CPU_LLDT(Bitu selector); @@ -69,7 +76,7 @@ bool CPU_RET(bool use32,Bitu bytes); bool Interrupt(Bitu num); bool CPU_IRET(bool use32); -bool CPU_SetSegGeneral(SegNames seg,Bitu value); +void CPU_SetSegGeneral(SegNames seg,Bitu value); void CPU_CPUID(void); void CPU_HLT(void); @@ -193,6 +200,33 @@ struct G_Descriptor { #pragma pack() + +struct TaskSegment_32 { + Bit32u esp0; /* The CK stack pointer */ + Bit32u esp1; /* The parent KL stack pointer */ + Bit32u esp2; /* Unused */ + Bit32u cr3; /* The page directory pointer */ + Bit32u eip; /* The instruction pointer */ + Bit32u eflags; /* The flags */ + Bit32u eax, ecx, edx, ebx; /* The general purpose registers */ + Bit32u esp, ebp, esi, edi; /* The special purpose registers */ + Bit16u back; /* Backlink */ + Bit16u ss0; /* The CK stack selector */ + Bit16u ss1; /* The parent KL stack selector */ + Bit16u ss2; /* Unused */ + Bit16u es; /* The extra selector */ + Bit16u cs; /* The code selector */ + Bit16u ss; /* The application stack selector */ + Bit16u ds; /* The data selector */ + Bit16u fs; /* And another extra selector */ + Bit16u gs; /* ... and another one */ + Bit16u ldt; /* The local descriptor table */ + Bit16u trap; /* The trap flag (for debugging) */ + Bit16u io; /* The I/O Map base address */ +}; + +void CPU_ReadTaskSeg32(PhysPt base,TaskSegment_32 * seg); + class TaskStateSegment { public: @@ -212,8 +246,7 @@ private: Bitu seg_limit; Bitu seg_value; }; - - + class Descriptor { public: @@ -314,22 +347,26 @@ private: Bitu ldt_value; }; -#define STATE_PROTECTED 0x0001 -#define STATE_USE32 0x0002 -#define STATE_STACK32 0x0004 - struct CPUBlock { Bitu cpl; /* Current Privilege */ - Bitu state; Bitu cr0; + bool v86; /* Are we in a v86 task */ + bool pmode; /* Is Protected mode enabled */ GDTDescriptorTable gdt; DescriptorTable idt; struct { - Bitu prefix,entry; - } full; + Bit16u val; + PhysPt base; + Bitu type; + } tr; struct { - Bitu eip,cs; - } hlt; + Bitu mask; + bool big; + } stack; + struct { + CODE_TYPE type; /* What kind of code are we running */ + bool big; + } code; }; extern CPUBlock cpu; From 0cce18012d468676f165a792f812df420a5a4b51 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 26 Jul 2003 10:34:18 +0000 Subject: [PATCH 1073/4131] Runqueu is now a bool, wether or not to stard cpu core. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1153 --- include/pic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pic.h b/include/pic.h index af16996e..d40a5f92 100644 --- a/include/pic.h +++ b/include/pic.h @@ -57,7 +57,7 @@ void PIC_runIRQs(void); void PIC_RegisterIRQ(Bit32u irq,PIC_EOIHandler handler,char * name); void PIC_FreeIRQ(Bit32u irq); -Bitu PIC_RunQueue(void); +bool PIC_RunQueue(void); void PIC_AddIRQ(Bitu irq,Bitu delay); void PIC_AddEvent(PIC_EventHandler handler,Bitu delay); From 6be6e65e9320e5fd98ed003a0724d1c8218b8c17 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 26 Jul 2003 10:34:49 +0000 Subject: [PATCH 1074/4131] No big in segment structure anymore Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1154 --- include/regs.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/regs.h b/include/regs.h index c95e529d..a3a266f0 100644 --- a/include/regs.h +++ b/include/regs.h @@ -64,7 +64,6 @@ struct Segment { enum SegNames { es=0,cs,ss,ds,fs,gs}; struct Segments { - Bitu big[8]; Bitu val[8]; PhysPt phys[8]; }; From 3070b19d737f180558d3859d193683ae7be0953b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 26 Jul 2003 10:36:56 +0000 Subject: [PATCH 1075/4131] Little bit of cleaning up Callbacks now return from the cpu core. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1155 --- src/cpu/core_16/helpers.h | 3 +- src/cpu/core_16/main.h | 61 +++------ src/cpu/core_16/prefix_66.h | 19 +-- src/cpu/core_16/support.h | 78 +++++------ src/cpu/core_16/table_ea.h | 266 +++++++++++++++++------------------- src/cpu/slow_16.cpp | 31 +++-- 6 files changed, 206 insertions(+), 252 deletions(-) diff --git a/src/cpu/core_16/helpers.h b/src/cpu/core_16/helpers.h index c6586e1b..11099840 100644 --- a/src/cpu/core_16/helpers.h +++ b/src/cpu/core_16/helpers.h @@ -18,7 +18,7 @@ #define GetEAa \ - EAPoint eaa=(*lookupEATable)[rm](); + PhysPt eaa=(*lookupEATable)[rm](); #define GetRMEAa \ GetRM; \ @@ -140,3 +140,4 @@ GetEAa;FPU_ESC ## code ## _EA(rm,eaa); \ } \ } + diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index bf6ba202..97ff4080 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -82,7 +82,7 @@ restart: AXIw(SBBW);break; case 0x1e: /* PUSH DS */ Push_16(SegValue(ds));break; - case 0x1f: /* POP DS */ + case 0x1f: /* POP DS */ SegSet16(ds,Pop_16());break; case 0x20: /* AND Eb,Gb */ RMEbGb(ANDB);break; @@ -251,11 +251,8 @@ restart: break; case 0x67: /* Address Size Prefix */ #ifdef CPU_PREFIX_67 - prefix.mark|=PREFIX_ADDR; -#ifdef CPU_PREFIX_COUNT - prefix.count++; -#endif - lookupEATable=EAPrefixTable[prefix.mark]; + core_16.prefixes|=PREFIX_ADDR; + lookupEATable=EAPrefixTable[core_16.prefixes]; goto restart; #else NOTDONE; @@ -500,9 +497,9 @@ restart: } case 0x8d: /* LEA */ { - prefix.segbase=0; - prefix.mark|=PREFIX_SEG; - lookupEATable=EAPrefixTable[prefix.mark]; + core_16.segbase=0; + core_16.prefixes|=PREFIX_SEG; + lookupEATable=EAPrefixTable[core_16.prefixes]; GetRMrw;GetEAa; *rmrw=(Bit16u)eaa; break; @@ -600,22 +597,22 @@ restart: } case 0xa0: /* MOV AL,Ob */ { - reg_al=LoadMb(GetEADirect[prefix.mark]()); + reg_al=LoadMb(GetEADirect[core_16.prefixes]()); } break; case 0xa1: /* MOV AX,Ow */ { - reg_ax=LoadMw(GetEADirect[prefix.mark]()); + reg_ax=LoadMw(GetEADirect[core_16.prefixes]()); } break; case 0xa2: /* MOV Ob,AL */ { - SaveMb(GetEADirect[prefix.mark](),reg_al); + SaveMb(GetEADirect[core_16.prefixes](),reg_al); } break; case 0xa3: /* MOV Ow,AX */ { - SaveMw(GetEADirect[prefix.mark](),reg_ax); + SaveMw(GetEADirect[core_16.prefixes](),reg_ax); } break; case 0xa4: /* MOVSB */ @@ -777,7 +774,7 @@ restart: { Bit16u bytes=Fetchw();Bit8u level=Fetchb(); Push_16(reg_bp);reg_bp=reg_sp;reg_sp-=bytes; - EAPoint reader=SegBase(ss)+reg_bp; + PhysPt reader=SegBase(ss)+reg_bp; for (Bit8u i=1;i>3) & 7); break; diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index c23b4985..a4b479eb 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -155,11 +155,8 @@ switch(Fetchb()) { SegPrefix_66(gs);break; case 0x67: /* Address Size Prefix */ #ifdef CPU_PREFIX_67 - prefix.mark|=PREFIX_ADDR; -#ifdef CPU_PREFIX_COUNT - prefix.count++; -#endif - lookupEATable=EAPrefixTable[prefix.mark]; + core_16.prefixes|=PREFIX_ADDR; + lookupEATable=EAPrefixTable[core_16.prefixes]; goto restart_66; #else NOTDONE; @@ -262,9 +259,9 @@ switch(Fetchb()) { break; case 0x8d: /* LEA */ { - prefix.segbase=0; - prefix.mark|=PREFIX_SEG; - lookupEATable=EAPrefixTable[prefix.mark]; + core_16.segbase=0; + core_16.prefixes|=PREFIX_SEG; + lookupEATable=EAPrefixTable[core_16.prefixes]; GetRMrd;GetEAa; *rmrd=(Bit32u)eaa; break; @@ -317,10 +314,10 @@ switch(Fetchb()) { #endif break; case 0xa1: /* MOV EAX,Ow */ - reg_eax=LoadMd(GetEADirect[prefix.mark]()); + reg_eax=LoadMd(GetEADirect[core_16.prefixes]()); break; case 0xa3: /* MOV Ow,EAX */ - SaveMd(GetEADirect[prefix.mark](),reg_eax); + SaveMd(GetEADirect[core_16.prefixes](),reg_eax); break; case 0xa5: /* MOVSD */ { @@ -417,11 +414,9 @@ switch(Fetchb()) { IO_Write(reg_dx+3,(Bit8u)(reg_eax>>24)); break; case 0xf2: /* REPNZ */ - prefix.count++; Repeat_Normal(false,true); continue; case 0xf3: /* REPZ */ - prefix.count++; Repeat_Normal(true,true); continue; case 0xf7: /* GRP3 Ed(,Id) */ diff --git a/src/cpu/core_16/support.h b/src/cpu/core_16/support.h index 45957f70..ede6fe25 100644 --- a/src/cpu/core_16/support.h +++ b/src/cpu/core_16/support.h @@ -16,24 +16,23 @@ * 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 SUBIP(a) core_16.ip_lookup-=a +#define SETIP(a) core_16.ip_lookup=SegBase(cs)+a +#define GETIP (Bit16u)(core_16.ip_lookup-SegBase(cs)) #define SAVEIP reg_ip=GETIP -#define LOADIP IPPoint=SegBase(cs)+reg_ip +#define LOADIP core_16.ip_lookup=SegBase(cs)+reg_ip #define LEAVECORE \ SAVEIP; \ FILLFLAGS; static INLINE void ADDIP(Bit16u add) { - IPPoint=SegBase(cs)+((Bit16u)(((Bit16u)(IPPoint-SegBase(cs)))+(Bit16u)add)); + core_16.ip_lookup=SegBase(cs)+((Bit16u)(((Bit16u)(core_16.ip_lookup-SegBase(cs)))+(Bit16u)add)); } static INLINE void ADDIPFAST(Bit16s blah) { - IPPoint+=blah; + core_16.ip_lookup+=blah; } #define CheckTF() \ @@ -57,19 +56,19 @@ static INLINE void ADDIPFAST(Bit16s blah) { } static INLINE Bit8u Fetchb() { - Bit8u temp=LoadMb(IPPoint); - IPPoint+=1; + Bit8u temp=LoadMb(core_16.ip_lookup); + core_16.ip_lookup+=1; return temp; } static INLINE Bit16u Fetchw() { - Bit16u temp=LoadMw(IPPoint); - IPPoint+=2; + Bit16u temp=LoadMw(core_16.ip_lookup); + core_16.ip_lookup+=2; return temp; } static INLINE Bit32u Fetchd() { - Bit32u temp=LoadMd(IPPoint); - IPPoint+=4; + Bit32u temp=LoadMd(core_16.ip_lookup); + core_16.ip_lookup+=4; return temp; } @@ -135,14 +134,13 @@ static INLINE Bit32u Pop_32() { #define stringDI \ - EAPoint to; \ + PhysPt to; \ to=SegBase(es)+reg_di #define stringSI \ - EAPoint from; \ - if (prefix.mark & PREFIX_SEG) { \ - from=(prefix.segbase+reg_si); \ - PrefixReset; \ + PhysPt from; \ + if (core_16.prefixes & PREFIX_SEG) { \ + from=(core_16.segbase+reg_si); \ } else { \ from=SegBase(ds)+reg_si; \ } @@ -159,46 +157,39 @@ static void Repeat_Normal(bool testz,bool prefix_66) { if (GETFLAG(DF)) direct=-1; else direct=1; base_di=SegBase(es); - if (prefix.mark & PREFIX_ADDR) E_Exit("Unhandled 0x67 prefixed string op"); + if (core_16.prefixes & PREFIX_ADDR) E_Exit("Unhandled 0x67 prefixed string op"); rep_again: - if (prefix.mark & PREFIX_SEG) { - base_si=(prefix.segbase); + if (core_16.prefixes & PREFIX_SEG) { + base_si=(core_16.segbase); } else { base_si=SegBase(ds); } switch (Fetchb()) { case 0x26: /* ES Prefix */ - prefix.segbase=SegBase(es); - prefix.mark|=PREFIX_SEG; - prefix.count++; + core_16.segbase=SegBase(es); + core_16.prefixes|=PREFIX_SEG; goto rep_again; case 0x2e: /* CS Prefix */ - prefix.segbase=SegBase(cs); - prefix.mark|=PREFIX_SEG; - prefix.count++; + core_16.segbase=SegBase(cs); + core_16.prefixes|=PREFIX_SEG; goto rep_again; case 0x36: /* SS Prefix */ - prefix.segbase=SegBase(ss); - prefix.mark|=PREFIX_SEG; - prefix.count++; + core_16.segbase=SegBase(ss); + core_16.prefixes|=PREFIX_SEG; goto rep_again; case 0x3e: /* DS Prefix */ - prefix.segbase=SegBase(ds); - prefix.mark|=PREFIX_SEG; - prefix.count++; + core_16.segbase=SegBase(ds); + core_16.prefixes|=PREFIX_SEG; goto rep_again; case 0x64: /* FS Prefix */ - prefix.segbase=SegBase(fs); - prefix.mark|=PREFIX_SEG; - prefix.count++; + core_16.segbase=SegBase(fs); + core_16.prefixes|=PREFIX_SEG; goto rep_again; case 0x65: /* GS Prefix */ - prefix.segbase=SegBase(gs); - prefix.mark|=PREFIX_SEG; - prefix.count++; + core_16.segbase=SegBase(gs); + core_16.prefixes|=PREFIX_SEG; goto rep_again; case 0x66: /* Size Prefix */ - prefix.count++; prefix_66=!prefix_66; goto rep_again; case 0x6c: /* REP INSB */ @@ -398,13 +389,12 @@ rep_again: } break; default: - IPPoint--; + core_16.ip_lookup--; LOG(LOG_CPU,LOG_ERROR)("Unhandled REP Prefix %X",Fetchb()); goto normalexit; } /* If we end up here it's because the CPU_Cycles counter is 0, so restart instruction */ - IPPoint-=(prefix.count+2); /* Rep instruction and whatever string instruction */ -normalexit: - PrefixReset; + core_16.ip_lookup=core_16.ip_start; +normalexit:; } diff --git a/src/cpu/core_16/table_ea.h b/src/cpu/core_16/table_ea.h index 8cecfee7..28ec08b7 100644 --- a/src/cpu/core_16/table_ea.h +++ b/src/cpu/core_16/table_ea.h @@ -18,8 +18,8 @@ /* Some variables for EA Loolkup */ -typedef EAPoint (*GetEATable[256])(void); -typedef EAPoint (*EA_LookupHandler)(void); +typedef PhysPt (*GetEATable[256])(void); +typedef PhysPt (*EA_LookupHandler)(void); static GetEATable * lookupEATable; @@ -28,64 +28,51 @@ static GetEATable * lookupEATable; #define PREFIX_ADDR 0x2 #define PREFIX_SEG_ADDR 0x3 -static struct { - Bitu mark; - Bitu count; - EAPoint segbase; -} prefix; /* Gets initialized at the bottem, can't seem to declare forward references */ static GetEATable * EAPrefixTable[4]; #define SegPrefix(blah) \ - prefix.segbase=SegBase(blah); \ - prefix.mark|=PREFIX_SEG; \ - prefix.count++; \ - lookupEATable=EAPrefixTable[prefix.mark]; \ + core_16.segbase=SegBase(blah); \ + core_16.prefixes|=PREFIX_SEG; \ + lookupEATable=EAPrefixTable[core_16.prefixes]; \ goto restart; #define SegPrefix_66(blah) \ - prefix.segbase=SegBase(blah); \ - prefix.mark|=PREFIX_SEG; \ - prefix.count++; \ - lookupEATable=EAPrefixTable[prefix.mark]; \ + core_16.segbase=SegBase(blah); \ + core_16.prefixes|=PREFIX_SEG; \ + lookupEATable=EAPrefixTable[core_16.prefixes]; \ goto restart_66; -#define PrefixReset \ - prefix.mark=PREFIX_NONE; \ - prefix.count=0; \ - lookupEATable=EAPrefixTable[PREFIX_NONE]; - - /* 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 PhysPt EA_16_00_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si); } +static PhysPt EA_16_01_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di); } +static PhysPt EA_16_02_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si); } +static PhysPt EA_16_03_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di); } +static PhysPt EA_16_04_n(void) { return SegBase(ds)+(Bit16u)(reg_si); } +static PhysPt EA_16_05_n(void) { return SegBase(ds)+(Bit16u)(reg_di); } +static PhysPt EA_16_06_n(void) { return SegBase(ds)+(Bit16u)(Fetchw());} +static PhysPt EA_16_07_n(void) { return SegBase(ds)+(Bit16u)(reg_bx); } -static 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 PhysPt EA_16_40_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); } +static PhysPt EA_16_41_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); } +static PhysPt EA_16_42_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); } +static PhysPt EA_16_43_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); } +static PhysPt EA_16_44_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchbs()); } +static PhysPt EA_16_45_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchbs()); } +static PhysPt EA_16_46_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchbs()); } +static PhysPt EA_16_47_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchbs()); } -static 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 PhysPt EA_16_80_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); } +static PhysPt EA_16_81_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); } +static PhysPt EA_16_82_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); } +static PhysPt EA_16_83_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); } +static PhysPt EA_16_84_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchws()); } +static PhysPt EA_16_85_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchws()); } +static PhysPt EA_16_86_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchws()); } +static PhysPt EA_16_87_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchws()); } static GetEATable GetEA_16_n={ /* 00 */ @@ -123,34 +110,33 @@ static GetEATable GetEA_16_n={ }; -#define segprefixed(val) EAPoint ret=prefix.segbase+val;PrefixReset;return ret; -static EAPoint EA_16_00_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_si)) } -static EAPoint EA_16_01_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_di)) } -static EAPoint EA_16_02_s(void) { segprefixed((Bit16u)(reg_bp+(Bit16s)reg_si)) } -static EAPoint EA_16_03_s(void) { segprefixed((Bit16u)(reg_bp+(Bit16s)reg_di)) } -static EAPoint EA_16_04_s(void) { segprefixed((Bit16u)(reg_si)) } -static EAPoint EA_16_05_s(void) { segprefixed((Bit16u)(reg_di)) } -static EAPoint EA_16_06_s(void) { segprefixed((Bit16u)(Fetchw())) } -static EAPoint EA_16_07_s(void) { segprefixed((Bit16u)(reg_bx)) } +static PhysPt EA_16_00_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_si); } +static PhysPt EA_16_01_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_di); } +static PhysPt EA_16_02_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_si); } +static PhysPt EA_16_03_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_di); } +static PhysPt EA_16_04_s(void) { return core_16.segbase+(Bit16u)(reg_si); } +static PhysPt EA_16_05_s(void) { return core_16.segbase+(Bit16u)(reg_di); } +static PhysPt EA_16_06_s(void) { return core_16.segbase+(Bit16u)(Fetchw()); } +static PhysPt EA_16_07_s(void) { return core_16.segbase+(Bit16u)(reg_bx); } -static EAPoint EA_16_40_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs())) } -static EAPoint EA_16_41_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs())) } -static EAPoint EA_16_42_s(void) { segprefixed((Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs())) } -static EAPoint EA_16_43_s(void) { segprefixed((Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs())) } -static EAPoint EA_16_44_s(void) { segprefixed((Bit16u)(reg_si+Fetchbs())) } -static EAPoint EA_16_45_s(void) { segprefixed((Bit16u)(reg_di+Fetchbs())) } -static EAPoint EA_16_46_s(void) { segprefixed((Bit16u)(reg_bp+Fetchbs())) } -static EAPoint EA_16_47_s(void) { segprefixed((Bit16u)(reg_bx+Fetchbs())) } +static PhysPt EA_16_40_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); } +static PhysPt EA_16_41_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); } +static PhysPt EA_16_42_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); } +static PhysPt EA_16_43_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); } +static PhysPt EA_16_44_s(void) { return core_16.segbase+(Bit16u)(reg_si+Fetchbs()); } +static PhysPt EA_16_45_s(void) { return core_16.segbase+(Bit16u)(reg_di+Fetchbs()); } +static PhysPt EA_16_46_s(void) { return core_16.segbase+(Bit16u)(reg_bp+Fetchbs()); } +static PhysPt EA_16_47_s(void) { return core_16.segbase+(Bit16u)(reg_bx+Fetchbs()); } -static EAPoint EA_16_80_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws())) } -static EAPoint EA_16_81_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws())) } -static EAPoint EA_16_82_s(void) { segprefixed((Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws())) } -static EAPoint EA_16_83_s(void) { segprefixed((Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws())) } -static EAPoint EA_16_84_s(void) { segprefixed((Bit16u)(reg_si+Fetchws())) } -static EAPoint EA_16_85_s(void) { segprefixed((Bit16u)(reg_di+Fetchws())) } -static EAPoint EA_16_86_s(void) { segprefixed((Bit16u)(reg_bp+Fetchws())) } -static EAPoint EA_16_87_s(void) { segprefixed((Bit16u)(reg_bx+Fetchws())) } +static PhysPt EA_16_80_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); } +static PhysPt EA_16_81_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); } +static PhysPt EA_16_82_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); } +static PhysPt EA_16_83_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); } +static PhysPt EA_16_84_s(void) { return core_16.segbase+(Bit16u)(reg_si+Fetchws()); } +static PhysPt EA_16_85_s(void) { return core_16.segbase+(Bit16u)(reg_di+Fetchws()); } +static PhysPt EA_16_86_s(void) { return core_16.segbase+(Bit16u)(reg_bp+Fetchws()); } +static PhysPt EA_16_87_s(void) { return core_16.segbase+(Bit16u)(reg_bx+Fetchws()); } static GetEATable GetEA_16_s={ /* 00 */ @@ -190,9 +176,9 @@ static GetEATable GetEA_16_s={ static Bit32u SIBZero=0; static Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi }; -INLINE EAPoint Sib(Bitu mode) { +INLINE PhysPt Sib(Bitu mode) { Bit8u sib=Fetchb(); - EAPoint base; + PhysPt base; switch (sib&7) { case 0: /* EAX Base */ base=SegBase(ds)+reg_eax;break; @@ -220,32 +206,32 @@ INLINE EAPoint Sib(Bitu mode) { }; -static EAPoint EA_32_00_n(void) { PrefixReset;return SegBase(ds)+reg_eax; } -static EAPoint EA_32_01_n(void) { PrefixReset;return SegBase(ds)+reg_ecx; } -static EAPoint EA_32_02_n(void) { PrefixReset;return SegBase(ds)+reg_edx; } -static EAPoint EA_32_03_n(void) { PrefixReset;return SegBase(ds)+reg_ebx; } -static EAPoint EA_32_04_n(void) { PrefixReset;return Sib(0);} -static EAPoint EA_32_05_n(void) { PrefixReset;return SegBase(ds)+Fetchd(); } -static EAPoint EA_32_06_n(void) { PrefixReset;return SegBase(ds)+reg_esi; } -static EAPoint EA_32_07_n(void) { PrefixReset;return SegBase(ds)+reg_edi; } +static PhysPt EA_32_00_n(void) { return SegBase(ds)+reg_eax; } +static PhysPt EA_32_01_n(void) { return SegBase(ds)+reg_ecx; } +static PhysPt EA_32_02_n(void) { return SegBase(ds)+reg_edx; } +static PhysPt EA_32_03_n(void) { return SegBase(ds)+reg_ebx; } +static PhysPt EA_32_04_n(void) { return Sib(0);} +static PhysPt EA_32_05_n(void) { return SegBase(ds)+Fetchd(); } +static PhysPt EA_32_06_n(void) { return SegBase(ds)+reg_esi; } +static PhysPt EA_32_07_n(void) { return SegBase(ds)+reg_edi; } -static EAPoint EA_32_40_n(void) { PrefixReset;return SegBase(ds)+reg_eax+Fetchbs(); } -static EAPoint EA_32_41_n(void) { PrefixReset;return SegBase(ds)+reg_ecx+Fetchbs(); } -static EAPoint EA_32_42_n(void) { PrefixReset;return SegBase(ds)+reg_edx+Fetchbs(); } -static EAPoint EA_32_43_n(void) { PrefixReset;return SegBase(ds)+reg_ebx+Fetchbs(); } -static EAPoint EA_32_44_n(void) { PrefixReset;EAPoint temp=Sib(1);return temp+Fetchbs();} -static EAPoint EA_32_45_n(void) { PrefixReset;return SegBase(ss)+reg_ebp+Fetchbs(); } -static EAPoint EA_32_46_n(void) { PrefixReset;return SegBase(ds)+reg_esi+Fetchbs(); } -static EAPoint EA_32_47_n(void) { PrefixReset;return SegBase(ds)+reg_edi+Fetchbs(); } +static PhysPt EA_32_40_n(void) { return SegBase(ds)+reg_eax+Fetchbs(); } +static PhysPt EA_32_41_n(void) { return SegBase(ds)+reg_ecx+Fetchbs(); } +static PhysPt EA_32_42_n(void) { return SegBase(ds)+reg_edx+Fetchbs(); } +static PhysPt EA_32_43_n(void) { return SegBase(ds)+reg_ebx+Fetchbs(); } +static PhysPt EA_32_44_n(void) { PhysPt temp=Sib(1);return temp+Fetchbs();} +static PhysPt EA_32_45_n(void) { return SegBase(ss)+reg_ebp+Fetchbs(); } +static PhysPt EA_32_46_n(void) { return SegBase(ds)+reg_esi+Fetchbs(); } +static PhysPt EA_32_47_n(void) { return SegBase(ds)+reg_edi+Fetchbs(); } -static EAPoint EA_32_80_n(void) { PrefixReset;return SegBase(ds)+reg_eax+Fetchds(); } -static EAPoint EA_32_81_n(void) { PrefixReset;return SegBase(ds)+reg_ecx+Fetchds(); } -static EAPoint EA_32_82_n(void) { PrefixReset;return SegBase(ds)+reg_edx+Fetchds(); } -static EAPoint EA_32_83_n(void) { PrefixReset;return SegBase(ds)+reg_ebx+Fetchds(); } -static EAPoint EA_32_84_n(void) { PrefixReset;EAPoint temp=Sib(2);return temp+Fetchds();} -static EAPoint EA_32_85_n(void) { PrefixReset;return SegBase(ss)+reg_ebp+Fetchds(); } -static EAPoint EA_32_86_n(void) { PrefixReset;return SegBase(ds)+reg_esi+Fetchds(); } -static EAPoint EA_32_87_n(void) { PrefixReset;return SegBase(ds)+reg_edi+Fetchds(); } +static PhysPt EA_32_80_n(void) { return SegBase(ds)+reg_eax+Fetchds(); } +static PhysPt EA_32_81_n(void) { return SegBase(ds)+reg_ecx+Fetchds(); } +static PhysPt EA_32_82_n(void) { return SegBase(ds)+reg_edx+Fetchds(); } +static PhysPt EA_32_83_n(void) { return SegBase(ds)+reg_ebx+Fetchds(); } +static PhysPt EA_32_84_n(void) { PhysPt temp=Sib(2);return temp+Fetchds();} +static PhysPt EA_32_85_n(void) { return SegBase(ss)+reg_ebp+Fetchds(); } +static PhysPt EA_32_86_n(void) { return SegBase(ds)+reg_esi+Fetchds(); } +static PhysPt EA_32_87_n(void) { return SegBase(ds)+reg_edi+Fetchds(); } static GetEATable GetEA_32_n={ /* 00 */ @@ -282,64 +268,62 @@ static GetEATable GetEA_32_n={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -INLINE EAPoint Sib_s(Bitu mode) { +INLINE PhysPt Sib_s(Bitu mode) { Bit8u sib=Fetchb(); - EAPoint base; + PhysPt base; switch (sib&7) { case 0: /* EAX Base */ - base=prefix.segbase+reg_eax;break; + base=core_16.segbase+reg_eax;break; case 1: /* ECX Base */ - base=prefix.segbase+reg_ecx;break; + base=core_16.segbase+reg_ecx;break; case 2: /* EDX Base */ - base=prefix.segbase+reg_edx;break; + base=core_16.segbase+reg_edx;break; case 3: /* EBX Base */ - base=prefix.segbase+reg_ebx;break; + base=core_16.segbase+reg_ebx;break; case 4: /* ESP Base */ - base=prefix.segbase+reg_esp;break; + base=core_16.segbase+reg_esp;break; case 5: /* #1 Base */ if (!mode) { - base=prefix.segbase+Fetchd();break; + base=core_16.segbase+Fetchd();break; } else { - base=prefix.segbase+reg_ebp;break; + base=core_16.segbase+reg_ebp;break; } case 6: /* ESI Base */ - base=prefix.segbase+reg_esi;break; + base=core_16.segbase+reg_esi;break; case 7: /* EDI Base */ - base=prefix.segbase+reg_edi;break; + base=core_16.segbase+reg_edi;break; } base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6); - PrefixReset; return base; }; -#define segprefixed_32(val) EAPoint ret=prefix.segbase+(Bit32u)(val);PrefixReset;return ret; -static EAPoint EA_32_00_s(void) { segprefixed_32(reg_eax); } -static EAPoint EA_32_01_s(void) { segprefixed_32(reg_ecx); } -static EAPoint EA_32_02_s(void) { segprefixed_32(reg_edx); } -static EAPoint EA_32_03_s(void) { segprefixed_32(reg_ebx); } -static EAPoint EA_32_04_s(void) { return Sib_s(0);} -static EAPoint EA_32_05_s(void) { segprefixed_32(Fetchd()); } -static EAPoint EA_32_06_s(void) { segprefixed_32(reg_esi); } -static EAPoint EA_32_07_s(void) { segprefixed_32(reg_edi); } +static PhysPt EA_32_00_s(void) { return core_16.segbase+(Bit32u)(reg_eax); } +static PhysPt EA_32_01_s(void) { return core_16.segbase+(Bit32u)(reg_ecx); } +static PhysPt EA_32_02_s(void) { return core_16.segbase+(Bit32u)(reg_edx); } +static PhysPt EA_32_03_s(void) { return core_16.segbase+(Bit32u)(reg_ebx); } +static PhysPt EA_32_04_s(void) { return core_16.segbase+(Bit32u)(Sib_s(0));} +static PhysPt EA_32_05_s(void) { return core_16.segbase+(Bit32u)(Fetchd()); } +static PhysPt EA_32_06_s(void) { return core_16.segbase+(Bit32u)(reg_esi); } +static PhysPt EA_32_07_s(void) { return core_16.segbase+(Bit32u)(reg_edi); } -static EAPoint EA_32_40_s(void) { segprefixed_32(reg_eax+Fetchbs()); } -static EAPoint EA_32_41_s(void) { segprefixed_32(reg_ecx+Fetchbs()); } -static EAPoint EA_32_42_s(void) { segprefixed_32(reg_edx+Fetchbs()); } -static EAPoint EA_32_43_s(void) { segprefixed_32(reg_ebx+Fetchbs()); } -static EAPoint EA_32_44_s(void) { return Sib_s(1)+Fetchbs();} -static EAPoint EA_32_45_s(void) { segprefixed_32(reg_ebp+Fetchbs()); } -static EAPoint EA_32_46_s(void) { segprefixed_32(reg_esi+Fetchbs()); } -static EAPoint EA_32_47_s(void) { segprefixed_32(reg_edi+Fetchbs()); } +static PhysPt EA_32_40_s(void) { return core_16.segbase+(Bit32u)(reg_eax+Fetchbs()); } +static PhysPt EA_32_41_s(void) { return core_16.segbase+(Bit32u)(reg_ecx+Fetchbs()); } +static PhysPt EA_32_42_s(void) { return core_16.segbase+(Bit32u)(reg_edx+Fetchbs()); } +static PhysPt EA_32_43_s(void) { return core_16.segbase+(Bit32u)(reg_ebx+Fetchbs()); } +static PhysPt EA_32_44_s(void) { return core_16.segbase+(Bit32u)(Sib_s(1)+Fetchbs());} +static PhysPt EA_32_45_s(void) { return core_16.segbase+(Bit32u)(reg_ebp+Fetchbs()); } +static PhysPt EA_32_46_s(void) { return core_16.segbase+(Bit32u)(reg_esi+Fetchbs()); } +static PhysPt EA_32_47_s(void) { return core_16.segbase+(Bit32u)(reg_edi+Fetchbs()); } -static EAPoint EA_32_80_s(void) { segprefixed_32(reg_eax+Fetchds()); } -static EAPoint EA_32_81_s(void) { segprefixed_32(reg_ecx+Fetchds()); } -static EAPoint EA_32_82_s(void) { segprefixed_32(reg_edx+Fetchds()); } -static EAPoint EA_32_83_s(void) { segprefixed_32(reg_ebx+Fetchds()); } -static EAPoint EA_32_84_s(void) { return Sib_s(2)+Fetchds();} -static EAPoint EA_32_85_s(void) { segprefixed_32(reg_ebp+Fetchds()); } -static EAPoint EA_32_86_s(void) { segprefixed_32(reg_esi+Fetchds()); } -static EAPoint EA_32_87_s(void) { segprefixed_32(reg_edi+Fetchds()); } +static PhysPt EA_32_80_s(void) { return core_16.segbase+(Bit32u)(reg_eax+Fetchds()); } +static PhysPt EA_32_81_s(void) { return core_16.segbase+(Bit32u)(reg_ecx+Fetchds()); } +static PhysPt EA_32_82_s(void) { return core_16.segbase+(Bit32u)(reg_edx+Fetchds()); } +static PhysPt EA_32_83_s(void) { return core_16.segbase+(Bit32u)(reg_ebx+Fetchds()); } +static PhysPt EA_32_84_s(void) { return core_16.segbase+(Bit32u)(Sib_s(2)+Fetchds());} +static PhysPt EA_32_85_s(void) { return core_16.segbase+(Bit32u)(reg_ebp+Fetchds()); } +static PhysPt EA_32_86_s(void) { return core_16.segbase+(Bit32u)(reg_esi+Fetchds()); } +static PhysPt EA_32_87_s(void) { return core_16.segbase+(Bit32u)(reg_edi+Fetchds()); } static GetEATable GetEA_32_s={ @@ -377,20 +361,20 @@ static GetEATable GetEA_32_s={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static EAPoint GetEADirect_NONE(void) { - EAPoint result=SegBase(ds)+Fetchw(); +static PhysPt GetEADirect_NONE(void) { + PhysPt result=SegBase(ds)+Fetchw(); return result; } -static EAPoint GetEADirect_SEG(void) { - EAPoint result=prefix.segbase+Fetchw();PrefixReset; +static PhysPt GetEADirect_SEG(void) { + PhysPt result=core_16.segbase+Fetchw(); return result; } -static EAPoint GetEADirect_ADDR(void) { - EAPoint result=SegBase(ds)+Fetchd();PrefixReset; +static PhysPt GetEADirect_ADDR(void) { + PhysPt result=SegBase(ds)+Fetchd(); return result; } -static EAPoint GetEADirect_SEG_ADDR(void) { - EAPoint result=prefix.segbase+Fetchd();PrefixReset; +static PhysPt GetEADirect_SEG_ADDR(void) { + PhysPt result=core_16.segbase+Fetchd(); return result; } diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp index 091e52f5..67b08d87 100644 --- a/src/cpu/slow_16.cpp +++ b/src/cpu/slow_16.cpp @@ -57,21 +57,25 @@ extern Bitu cycle_count; /* Enable parts of the cpu emulation */ #define CPU_386 //Enable 386 instructions #define CPU_PREFIX_67 //Enable the 0x67 prefix -#define CPU_PREFIX_COUNT //Enable counting of prefixes #define CPU_PIC_CHECK //Check for IRQ's on critical moment #if C_FPU #define CPU_FPU //Enable FPU escape instructions #endif - +static struct { + Bitu prefixes; + PhysPt segbase; + PhysPt ip_lookup; + PhysPt ip_start; +}core_16 ; #include "instructions.h" #include "core_16/support.h" -static Bitu CPU_Real_16_Slow_Decode_Trap(void); +static Bits CPU_Real_16_Slow_Decode_Trap(void); -static Bitu CPU_Real_16_Slow_Decode(void) { +static Bits CPU_Real_16_Slow_Decode(void) { decode_start: LOADIP; flags.type=t_UNKNOWN; @@ -83,12 +87,10 @@ decode_start: if (DEBUG_HeavyIsBreakpoint()) return 1; #endif #endif + core_16.ip_start=core_16.ip_lookup; + core_16.prefixes=0; + lookupEATable=EAPrefixTable[0]; #include "core_16/main.h" - if (prefix.count) { - PrefixReset; - //DEBUG_HeavyWriteLogInstruction(); - LOG(LOG_CPU,LOG_NORMAL)("Prefix for non prefixed instruction"); - } CPU_Cycles--; } decode_end: @@ -96,11 +98,11 @@ decode_end: return CBRET_NONE; } -static Bitu CPU_Real_16_Slow_Decode_Trap(void) { +static Bits CPU_Real_16_Slow_Decode_Trap(void) { Bits oldCycles = CPU_Cycles; CPU_Cycles = 1; - CPU_Real_16_Slow_Decode(); + Bits ret=CPU_Real_16_Slow_Decode(); // LOG_DEBUG("TRAP: Trap Flag executed"); Interrupt(1); @@ -108,15 +110,16 @@ static Bitu CPU_Real_16_Slow_Decode_Trap(void) { CPU_Cycles = oldCycles-1; cpudecoder = &CPU_Real_16_Slow_Decode; - return CBRET_NONE; + return ret; } -void CPU_Real_16_Slow_Start(void) { +void CPU_Real_16_Slow_Start(bool big) { + if (big) E_Exit("Core 16 only runs 16-bit code"); cpudecoder=&CPU_Real_16_Slow_Decode; EAPrefixTable[2]=&GetEA_32_n; EAPrefixTable[3]=&GetEA_32_s; EAPrefixTable[0]=&GetEA_16_n; EAPrefixTable[1]=&GetEA_16_s; - PrefixReset; + }; From 8ca9fc4faaa2afd4a7aee87917abb9a8a91c17c5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 26 Jul 2003 10:39:01 +0000 Subject: [PATCH 1076/4131] Some cleanups Callbacks now return from the decoder Stacks are now read using a mask. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1156 --- src/cpu/core_full.cpp | 59 ++++++++++++++++++----------------- src/cpu/core_full/load.h | 20 +++++------- src/cpu/core_full/loadwrite.h | 51 ++++++------------------------ src/cpu/core_full/op.h | 21 +++---------- src/cpu/core_full/support.h | 2 ++ 5 files changed, 53 insertions(+), 100 deletions(-) diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index c9b8ba05..5663a9b4 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + #include "dosbox.h" #include "pic.h" @@ -11,17 +29,9 @@ #include "callback.h" -Bit8u PAGE_Readb(PhysPt address); -Bit16u PAGE_Readw(PhysPt address); -Bit32u PAGE_Readd(PhysPt address); - -void PAGE_Writeb(PhysPt address,Bit8u val); -void PAGE_Writew(PhysPt address,Bit16u val); -void PAGE_Writed(PhysPt address,Bit32u val); - typedef PhysPt EAPoint; #define SegBase(c) SegPhys(c) -#if 1 + #define LoadMb(off) mem_readb_inline(off) #define LoadMw(off) mem_readw_inline(off) #define LoadMd(off) mem_readd_inline(off) @@ -34,22 +44,6 @@ typedef PhysPt EAPoint; #define SaveMw(off,val) mem_writew_inline(off,val) #define SaveMd(off,val) mem_writed_inline(off,val) -#else - -#define LoadMb(off) PAGE_Readb(off) -#define LoadMw(off) PAGE_Readw(off) -#define LoadMd(off) PAGE_Readd(off) - -#define LoadMbs(off) (Bit8s)(LoadMb(off)) -#define LoadMws(off) (Bit16s)(LoadMw(off)) -#define LoadMds(off) (Bit32s)(LoadMd(off)) - -#define SaveMb(off,val) PAGE_Writeb(off,val) -#define SaveMw(off,val) PAGE_Writew(off,val) -#define SaveMd(off,val) PAGE_Writed(off,val) - -#endif - #define LoadD(reg) reg #define SaveD(reg,val) reg=val @@ -84,7 +78,7 @@ static INLINE void DecodeModRM(void) { goto nextopcode; \ } -Bitu Full_DeCode(void) { +Bits Full_DeCode(void) { LoadIP(); flags.type=t_UNKNOWN; @@ -100,8 +94,8 @@ Bitu Full_DeCode(void) { #endif #endif inst.start=IPPoint; - inst.entry=cpu.full.entry; - inst.prefix=cpu.full.prefix; + inst.entry=inst.start_entry; + inst.prefix=inst.start_prefix; restartopcode: inst.entry=(inst.entry & 0xffffff00) | Fetchb(); @@ -117,6 +111,13 @@ nextopcode:; } -void CPU_Core_Full_Start(void) { +void CPU_Core_Full_Start(bool big) { + if (!big) { + inst.start_prefix=0x0;; + inst.start_entry=0x0; + } else { + inst.start_prefix=PREFIX_ADDR; + inst.start_entry=0x200; + } cpudecoder=&Full_DeCode; } diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 86634ccc..780a50ed 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -383,7 +383,7 @@ l_M_Ed: { Bitu bytes=Fetchw();Bitu level=Fetchb() & 0x1f; Bitu frame_ptr=reg_esp-2; - if (cpu.state & STATE_STACK32) { + if (cpu.stack.big) { reg_esp-=2; mem_writew(SegBase(ss)+reg_esp,reg_bp); for (Bitu i=1;i> 24)); goto nextopcode; case O_CBACK: - if (inst.op1.d Date: Sat, 26 Jul 2003 10:39:14 +0000 Subject: [PATCH 1077/4131] callbacks start from 1 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1157 --- src/cpu/callback.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 0dd180f7..79e12ab5 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -40,7 +40,7 @@ static Bitu illegal_handler(void) { } Bitu CALLBACK_Allocate(void) { - for (Bitu i=0;(i Date: Sat, 26 Jul 2003 10:41:34 +0000 Subject: [PATCH 1078/4131] Setting stack segment now sets a stack mask Check for cpu decoder changes when CS changes. Changed handling of HLT a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1158 --- src/cpu/cpu.cpp | 321 ++++++++++++++++++++++++------------------------ 1 file changed, 162 insertions(+), 159 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index cc0bd791..a70c5d22 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -17,6 +17,7 @@ */ +#include #include "dosbox.h" #include "cpu.h" #include "memory.h" @@ -41,66 +42,37 @@ Bits CPU_CycleMax=1500; CPU_Decoder * cpudecoder; -void CPU_Real_16_Slow_Start(void); -void CPU_Core_Full_Start(void); +void CPU_Real_16_Slow_Start(bool big); +void CPU_Core_Full_Start(bool big); +void CPU_Core_Insane_Start(bool big); + typedef void DecoderStart(void); -//Determine correct core, to start from cpu state. -DecoderStart * CPU_DecorderStarts[8]={ - CPU_Real_16_Slow_Start, //16-bit real,16-bit stack -// CPU_Core_Full_Start, //16-bit prot,16-bit stack - CPU_Core_Full_Start, //16-bit prot,16-bit stack - 0, //32-bit real,16-bit stack ILLEGAL - CPU_Core_Full_Start, //32-bit prot,16-bit stack - 0, //16-bit real,32-bit stack ILLEGAL - CPU_Core_Full_Start, //16-bit prot,32-bit stack - 0, //32-bit real,32-bit stack ILLEGAL - CPU_Core_Full_Start, //32-bit prot,32-bit stack -}; +#define realcore_start CPU_Real_16_Slow_Start +//#define realcore_start CPU_Core_Insane_Start +//#define realcore_start CPU_Core_Full_Start void CPU_Push16(Bitu value) { - if (cpu.state & STATE_STACK32) { - reg_esp-=2; - mem_writew(SegPhys(ss)+reg_esp,value); - } else { - reg_sp-=2; - mem_writew(SegPhys(ss)+reg_sp,value); - } + reg_esp-=2; + mem_writew(SegPhys(ss) + (reg_esp & cpu.stack.mask) ,value); } void CPU_Push32(Bitu value) { - if (cpu.state & STATE_STACK32) { - reg_esp-=4; - mem_writed(SegPhys(ss)+reg_esp,value); - } else { - reg_sp-=4; - mem_writed(SegPhys(ss)+reg_sp,value); - } + reg_esp-=4; + mem_writed(SegPhys(ss) + (reg_esp & cpu.stack.mask) ,value); } Bitu CPU_Pop16(void) { - if (cpu.state & STATE_STACK32) { - Bitu val=mem_readw(SegPhys(ss)+reg_esp); - reg_esp+=2; - return val; - } else { - Bitu val=mem_readw(SegPhys(ss)+reg_sp); - reg_sp+=2; - return val; - } + Bitu val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); + reg_esp+=2; + return val; } Bitu CPU_Pop32(void) { - if (cpu.state & STATE_STACK32) { - Bitu val=mem_readd(SegPhys(ss)+reg_esp); - reg_esp+=4; - return val; - } else { - Bitu val=mem_readd(SegPhys(ss)+reg_sp); - reg_sp+=4; - return val; - } + Bitu val=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask)); + reg_esp+=4; + return val; } PhysPt SelBase(Bitu sel) { @@ -117,61 +89,28 @@ void CPU_SetFlags(Bitu word) { flags.word=word; } -bool CPU_CheckState(void) { - Bitu old_state=cpu.state; - cpu.state=0; - if (!(cpu.cr0 & CR0_PROTECTION)) { - cpu.full.entry=cpu.full.prefix=0; - } else { - cpu.state|=STATE_PROTECTED; - if (Segs.big[cs]) { - cpu.state|=STATE_USE32; - cpu.full.entry=0x200; - cpu.full.prefix=0x02; /* PREFIX_ADDR */ - } else { - cpu.full.entry=cpu.full.prefix=0; - } - if (Segs.big[ss]) cpu.state|=STATE_STACK32; - LOG_MSG("CPL Level %x at %X:%X",cpu.cpl,SegValue(cs),reg_eip); +bool CPU_CheckCodeType(CODE_TYPE type) { + if (cpu.code.type==type) return true; + cpu.code.type=type; + switch (cpu.code.type) { + case CODE_REAL: + realcore_start(false); + break; + case CODE_PMODE16: + CPU_Core_Full_Start(false); + break; + case CODE_PMODE32: + CPU_Core_Full_Start(true); + break; } - if (old_state==cpu.state) return true; - (*CPU_DecorderStarts[cpu.state])(); return false; } Bit8u lastint; bool Interrupt(Bitu num) { lastint=num; -//DEBUG THINGIE to check fucked ints - #if C_DEBUG switch (num) { - case 0x00: - LOG(LOG_CPU,LOG_NORMAL)("Divide Error"); - break; - case 0x06: - break; - case 0x07: - LOG(LOG_FPU,LOG_NORMAL)("Co Processor Exception"); - break; - case 0x08: - case 0x09: - case 0x10: - case 0x11: - case 0x12: - case 0x13: - case 0x15: - case 0x16: - case 0x17: - case 0x1A: - case 0x1C: - case 0x21: - case 0x2a: - case 0x2f: - case 0x33: - case 0x67: - case 0x74: - break; case 0xcd: #if C_HEAVY_DEBUG LOG(LOG_CPU,LOG_ERROR)("Call to interrupt 0xCD this is BAD"); @@ -180,17 +119,10 @@ bool Interrupt(Bitu num) { E_Exit("Call to interrupt 0xCD this is BAD"); case 0x03: if (DEBUG_Breakpoint()) return true; - break; - case 0x05: - LOG(LOG_CPU,LOG_NORMAL)("CPU:Out Of Bounds interrupt"); - break; - default: -// LOG_WARN("Call to unsupported INT %02X call %02X",num,reg_ah); - break; }; #endif - if (!(cpu.state & STATE_PROTECTED)) { /* RealMode Interrupt */ + if (!cpu.pmode) { /* Save everything on a 16-bit stack */ CPU_Push16(flags.word & 0xffff); CPU_Push16(SegValue(cs)); @@ -201,8 +133,9 @@ bool Interrupt(Bitu num) { reg_eip=mem_readw(num << 2); Segs.val[cs]=mem_readw((num << 2)+2); Segs.phys[cs]=Segs.val[cs]<<4; - return true; - } else { /* Protected Mode Interrupt */ + return CPU_CheckCodeType(CODE_REAL); + } else { + /* Protected Mode Interrupt */ Descriptor gate; //TODO Check for software interrupt and check gate's dpl0; LOG_MSG("INT:Gate to %X:%X big %d %s",selector,reg_eip,desc.Big(),gate.Type() & 0x8 ? "386" : "286"); reg_eip=offset; - return CPU_CheckState(); + return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); } default: E_Exit("Illegal descriptor type %X for int %X",gate.Type(),num); } } - return true; + assert(1); + return false; +} + + +bool CPU_Exception(Bitu exception,Bit32u error_code) { + if (!cpu.pmode) { /* RealMode Interrupt */ + /* Save everything on a 16-bit stack */ + CPU_Push16(flags.word & 0xffff); + CPU_Push16(SegValue(cs)); + CPU_Push16(reg_ip); + SETFLAGBIT(IF,false); + SETFLAGBIT(TF,false); + /* Get the new CS:IP from vector table */ + reg_eip=mem_readw(exception << 2); + Segs.val[cs]=mem_readw((exception << 2)+2); + Segs.phys[cs]=Segs.val[cs]<<4; + return CPU_CheckCodeType(CODE_REAL); + } else { /* Protected Mode Exception */ + + + + } + return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); } bool CPU_IRET(bool use32) { - if (!(cpu.state & STATE_PROTECTED)) { /*RealMode IRET */ + if (!cpu.pmode || cpu.v86) { /* RealMode IRET */ if (use32) { reg_eip=CPU_Pop32(); SegSet16(cs,CPU_Pop32()); @@ -272,9 +228,15 @@ bool CPU_IRET(bool use32) { SegSet16(cs,CPU_Pop16()); CPU_SetFlagsw(CPU_Pop16()); } - return true; + return CPU_CheckCodeType(CODE_REAL); } else { /* Protected mode IRET */ - if (GETFLAG(NT)) E_Exit("No task support"); + /* Check if this is task IRET */ + if (GETFLAG(NT)) { + if (GETFLAG(VM)) E_Exit("Pmode IRET with VM bit set"); + E_Exit("Task IRET"); + + + } Bitu selector,offset,old_flags; if (use32) { offset=CPU_Pop32(); @@ -289,7 +251,8 @@ bool CPU_IRET(bool use32) { Bitu rpl=selector & 3; Descriptor desc; cpu.gdt.GetDescriptor(selector,desc); - if (rpl0; Segs.val[cs]=(selector & 0xfffc) | cpu.cpl;; reg_eip=offset; CPU_SetFlags(old_flags); @@ -325,7 +288,7 @@ bool CPU_IRET(bool use32) { E_Exit("IRET from illegal descriptor type %X",desc.Type()); } Segs.phys[cs]=desc.GetBase(); - Segs.big[cs]=desc.Big(); + cpu.code.big=desc.Big()>0; Segs.val[cs]=selector; cpu.cpl=rpl; reg_eip=offset; @@ -342,20 +305,20 @@ bool CPU_IRET(bool use32) { //TODO Maybe validate other segments, but why would anyone use them? LOG_MSG("IRET:Outer level return to %X:%X",selector,offset); } - return CPU_CheckState(); + return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); } return false; } bool CPU_JMP(bool use32,Bitu selector,Bitu offset) { - if (!(cpu.state & STATE_PROTECTED)) { + if (!cpu.pmode || cpu.v86) { if (!use32) { reg_eip=offset&0xffff; } else { reg_eip=offset; } SegSet16(cs,selector); - return true; + return CPU_CheckCodeType(CODE_REAL); } else { Bitu rpl=selector & 3; Descriptor desc; @@ -374,22 +337,22 @@ bool CPU_JMP(bool use32,Bitu selector,Bitu offset) { CODE_jmp: /* Normal jump to another selector:offset */ Segs.phys[cs]=desc.GetBase(); - Segs.big[cs]=desc.Big(); + cpu.code.big=desc.Big()>0; Segs.val[cs]=(selector & 0xfffc) | cpu.cpl; reg_eip=offset; - return CPU_CheckState(); + return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); default: E_Exit("JMP Illegal descriptor type %X",desc.Type()); - } - } + assert(1); return false; } + bool CPU_CALL(bool use32,Bitu selector,Bitu offset) { - if (!(cpu.state & STATE_PROTECTED)) { + if (!cpu.pmode || cpu.v86) { if (!use32) { CPU_Push16(SegValue(cs)); CPU_Push16(reg_ip); @@ -400,7 +363,7 @@ bool CPU_CALL(bool use32,Bitu selector,Bitu offset) { reg_eip=offset; } SegSet16(cs,selector); - return true; + return CPU_CheckCodeType(CODE_REAL); } else { Descriptor call; Bitu rpl=selector & 3; @@ -428,22 +391,21 @@ call_code: reg_eip=offset; } Segs.phys[cs]=call.GetBase(); - Segs.big[cs]=call.Big(); + cpu.code.big=call.Big()>0; Segs.val[cs]=(selector & 0xfffc) | cpu.cpl; reg_eip=offset; - return CPU_CheckState(); + return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); default: E_Exit("CALL:Descriptor type %x unsupported",call.Type()); - }; - return CPU_CheckState(); + } } - return false; + assert(1); } bool CPU_RET(bool use32,Bitu bytes) { - if (!(cpu.state & STATE_PROTECTED)) { + if (!cpu.pmode || cpu.v86) { Bitu new_ip,new_cs; if (!use32) { new_ip=CPU_Pop16(); @@ -455,7 +417,7 @@ bool CPU_RET(bool use32,Bitu bytes) { reg_esp+=bytes; SegSet16(cs,new_cs); reg_eip=new_ip; - return true; + return CPU_CheckCodeType(CODE_REAL); } else { Bitu offset,selector; if (!use32) { @@ -465,7 +427,7 @@ bool CPU_RET(bool use32,Bitu bytes) { offset=CPU_Pop32(); selector=CPU_Pop32() & 0xffff; } - if (cpu.state & STATE_STACK32) { + if (cpu.stack.big) { reg_esp+=bytes; } else { reg_sp+=bytes; @@ -491,17 +453,17 @@ bool CPU_RET(bool use32,Bitu bytes) { } RET_same_level: Segs.phys[cs]=desc.GetBase(); - Segs.big[cs]=desc.Big(); + cpu.code.big=desc.Big()>0; Segs.val[cs]=selector; reg_eip=offset; LOG_MSG("RET - Same level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL()); - return CPU_CheckState(); + return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); } else { /* Return to higher level */ E_Exit("REturn to higher priviledge"); } LOG_MSG("Prot ret %X:%X",selector,offset); - return CPU_CheckState(); + return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); } return false; } @@ -557,14 +519,17 @@ bool CPU_SET_CRX(Bitu cr,Bitu value) { Bitu changed=cpu.cr0 ^ value; if (!changed) return true; cpu.cr0=value; +//TODO Maybe always first change to core_full for a change to cr0 if (value & CR0_PROTECTION) { + cpu.pmode=true; LOG_MSG("Protected mode"); PAGING_Enable((value & CR0_PAGING)>0); } else { + cpu.pmode=false; PAGING_Enable(false); LOG_MSG("Real mode"); } - return CPU_CheckState(); + return false; //Only changes with next CS change } case 3: PAGING_SetDirBase(value); @@ -757,22 +722,29 @@ void CPU_VERW(Bitu selector) { } -bool CPU_SetSegGeneral(SegNames seg,Bitu value) { +void CPU_SetSegGeneral(SegNames seg,Bitu value) { Segs.val[seg]=value; - if (cpu.state & STATE_PROTECTED) { + if (!cpu.pmode || cpu.v86) { + Segs.phys[seg]=value << 4; +//TODO maybe just always do this when they enable/real/v86 mode + if (seg==ss) { + cpu.stack.big=false; + cpu.stack.mask=0xffff; + } + } else { Descriptor desc; cpu.gdt.GetDescriptor(value,desc); Segs.phys[seg]=desc.GetBase(); -// LOG_MSG("Segment %d Set with base %X limit %X",seg,desc.GetBase(),desc.GetLimit()); if (seg==ss) { - Segs.big[ss]=desc.Big(); - return CPU_CheckState(); - } else return true; - } else { - Segs.phys[seg]=value << 4; - return true; - } - return false; + if (desc.Big()) { + cpu.stack.big=true; + cpu.stack.mask=0xffffffff; + } else { + cpu.stack.big=false; + cpu.stack.mask=0xffff; + } + } + } } void CPU_CPUID(void) { @@ -793,24 +765,52 @@ void CPU_CPUID(void) { LOG(LOG_CPU,LOG_ERROR)("Unhandled CPUID Function %x",reg_eax); break; } - } -static Bitu HLT_Decode(void) { - /* Stay here just as long until an external interrupt has changed CS:EIP */ - if ((reg_eip!=cpu.hlt.eip) || (SegValue(cs)!=cpu.hlt.cs)) { - cpu.state=0xff; //force a new state to set decoder - CPU_CheckState(); - return 0x0; - } +void CPU_ReadTaskSeg32(PhysPt base,TaskSegment_32 * seg) { + seg->back =mem_readw(base+offsetof(TSS_386,back )); + seg->esp0 =mem_readd(base+offsetof(TSS_386,esp0 )); + seg->ss0 =mem_readw(base+offsetof(TSS_386,ss0 )); + seg->esp1 =mem_readd(base+offsetof(TSS_386,esp1 )); + seg->ss1 =mem_readw(base+offsetof(TSS_386,ss1 )); + seg->esp2 =mem_readd(base+offsetof(TSS_386,esp2 )); + seg->ss2 =mem_readw(base+offsetof(TSS_386,ss2 )); + + seg->cr3 =mem_readd(base+offsetof(TSS_386,cr3 )); + seg->eflags =mem_readd(base+offsetof(TSS_386,eflags )); + seg->eip =mem_readd(base+offsetof(TSS_386,eip )); + + seg->eax =mem_readd(base+offsetof(TSS_386,eax )); + seg->ecx =mem_readd(base+offsetof(TSS_386,ecx )); + seg->edx =mem_readd(base+offsetof(TSS_386,edx )); + seg->ebx =mem_readd(base+offsetof(TSS_386,ebx )); + seg->esp =mem_readd(base+offsetof(TSS_386,esp )); + seg->ebp =mem_readd(base+offsetof(TSS_386,ebp )); + seg->esi =mem_readd(base+offsetof(TSS_386,esi )); + seg->edi =mem_readd(base+offsetof(TSS_386,edi )); + + seg->es =mem_readw(base+offsetof(TSS_386,es )); + seg->cs =mem_readw(base+offsetof(TSS_386,cs )); + seg->ss =mem_readw(base+offsetof(TSS_386,ss )); + seg->ds =mem_readw(base+offsetof(TSS_386,ds )); + seg->fs =mem_readw(base+offsetof(TSS_386,fs )); + seg->gs =mem_readw(base+offsetof(TSS_386,gs )); + + seg->ldt =mem_readw(base+offsetof(TSS_386,ldt )); + seg->trap =mem_readw(base+offsetof(TSS_386,trap )); + seg->io =mem_readw(base+offsetof(TSS_386,io )); + +} + +static Bits HLT_Decode(void) { + /* Once an interrupt occurs, it should change cpu core */ CPU_Cycles=0; - return 0x0; + return 0; } void CPU_HLT(void) { - cpu.hlt.cs=SegValue(cs); - cpu.hlt.eip=reg_eip; CPU_Cycles=0; + cpu.code.type=CODE_INIT; cpudecoder=&HLT_Decode; } @@ -851,12 +851,15 @@ void CPU_Init(Section* sec) { reg_eip=0; flags.word=FLAG_IF; + cpu.cr0=0xffffffff; + CPU_SET_CRX(0,0); //Initialize + cpu.v86=false; + cpu.code.big=false; + cpu.code.type=CODE_INIT; //So a new cpu core will be started + cpu.stack.mask=0xffff; + cpu.stack.big=false; - cpu.full.entry=cpu.full.prefix=0; - cpu.state=0xff; //To initialize it the first time - cpu.cr0=false; - - CPU_CheckState(); + CPU_JMP(false,0,0); //Setup the first cpu core KEYBOARD_AddEvent(KBD_f11,KBD_MOD_CTRL,CPU_CycleDecrease); KEYBOARD_AddEvent(KBD_f12,KBD_MOD_CTRL,CPU_CycleIncrease); From 7190b03145ea1a5553889e83207e2f5227c25124 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 26 Jul 2003 10:43:03 +0000 Subject: [PATCH 1079/4131] Some changes in detecting pmode and 32-bit code segements Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1159 --- src/debug/debug.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index a511b37a..caf7f1ff 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -110,7 +110,7 @@ Bit32u PhysMakeProt(Bit16u selector, Bit32u offset) Bit32u GetAddress(Bit16u seg, Bit32u offset) { - if (cpu.state & STATE_PROTECTED) return PhysMakeProt(seg,offset); + if (cpu.pmode) return PhysMakeProt(seg,offset); return (seg<<4)+offset; }; @@ -536,7 +536,7 @@ static bool StepOver() // PhysPt start=SegPhys(cs)+reg_eip; PhysPt start=GetAddress(SegValue(cs),reg_eip); char dline[200];Bitu size; - size=DasmI386(dline, start, reg_eip, (cpu.state & STATE_USE32>0)); + size=DasmI386(dline, start, reg_eip, cpu.code.big); if (strstr(dline,"call") || strstr(dline,"int") || strstr(dline,"loop") || strstr(dline,"rep")) { CBreakpoint::AddBreakpoint (SegValue(cs),reg_eip+size, true); @@ -628,11 +628,11 @@ static void DrawRegisters(void) { oldflags=flags.word; - if (cpu.state & STATE_PROTECTED) mvwprintw(dbg.win_reg,0,76,"Prot"); + if (cpu.pmode) mvwprintw(dbg.win_reg,0,76,"Prot"); else mvwprintw(dbg.win_reg,0,76,"Real"); // Selector info, if available - if ((cpu.state & STATE_PROTECTED) && curSelectorName[0]) { + if ((cpu.pmode) && curSelectorName[0]) { char out1[200], out2[200]; GetDescriptorInfo(curSelectorName,out1,out2); mvwprintw(dbg.win_reg,2,28,out1); @@ -675,7 +675,7 @@ static void DrawCode(void) } - Bitu drawsize=size=DasmI386(dline, start, disEIP, (cpu.state & STATE_USE32)>0); + Bitu drawsize=size=DasmI386(dline, start, disEIP, cpu.code.big); bool toolarge = false; mvwprintw(dbg.win_code,i,0,"%04X:%04X ",codeViewData.useCS,disEIP); @@ -1123,7 +1123,7 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) // if (address<(XMS_GetSize()+1)*1024*1024) { static char outmask[] = "%s:[%04X]=%02X"; - if (cpu.state & STATE_PROTECTED) outmask[6] = '8'; + if (cpu.pmode) outmask[6] = '8'; switch (DasmLastOperandSize()) { case 8 : { Bit8u val = mem_readb(address); outmask[12] = '2'; @@ -1154,7 +1154,7 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) }; }; // show descriptor info, if available - if ((cpu.state & STATE_PROTECTED) && saveSelector) { + if ((cpu.pmode) && saveSelector) { strcpy(curSelectorName,prefix); }; }; From feb42742acf5fc15973fa2d7c659f3d8395d08a5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 26 Jul 2003 10:45:11 +0000 Subject: [PATCH 1080/4131] Moved some timer tick handling to PIC Changed pic_runqueue a bit for new pic scheduling handling. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1160 --- src/hardware/pic.cpp | 159 ++++++++++++++++++++++++++++++----------- src/hardware/timer.cpp | 85 ---------------------- 2 files changed, 116 insertions(+), 128 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index f4fe8730..d0d666c4 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,11 +16,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include #include "dosbox.h" #include "inout.h" #include "cpu.h" #include "pic.h" +#include "timer.h" #define PIC_QUEUESIZE 128 @@ -326,53 +328,101 @@ void PIC_RemoveEvents(PIC_EventHandler handler) { } } -Bitu PIC_RunQueue(void) { - Bitu ret; +bool PIC_RunQueue(void) { /* Check to see if a new milisecond needs to be started */ - if (CPU_Cycles>0) { - CPU_CycleLeft+=CPU_Cycles; - CPU_Cycles=0; + CPU_CycleLeft+=CPU_Cycles; + CPU_Cycles=0; + if (CPU_CycleLeft<=0) { + return false; } - while (CPU_CycleLeft>0) { - /* Check the queue for an entry */ - Bitu index=PIC_Index(); - while (pic.next_entry && pic.next_entry->index<=index) { - PICEntry * entry=pic.next_entry; - pic.next_entry=entry->next; - switch (entry->type) { - case EVENT: - (entry->event)(); - break; - case IRQ: - PIC_ActivateIRQ(entry->irq); - break; - } - /* Put the entry in the free list */ - entry->next=pic.free_entry; - pic.free_entry=entry; + /* Check the queue for an entry */ + Bitu index=PIC_Index(); + while (pic.next_entry && pic.next_entry->index<=index) { + PICEntry * entry=pic.next_entry; + pic.next_entry=entry->next; + switch (entry->type) { + case EVENT: + (entry->event)(); + break; + case IRQ: + PIC_ActivateIRQ(entry->irq); + break; } - /* Check when to set the new cycle end */ - if (pic.next_entry) { - Bits cycles=PIC_MakeCycles(pic.next_entry->index-index); - if (!cycles) cycles=1; - if (cycles0) { - CPU_CycleLeft+=CPU_Cycles; - CPU_Cycles=0; - } - if (ret) return ret; + /* Put the entry in the free list */ + entry->next=pic.free_entry; + pic.free_entry=entry; } - /* Prepare everything for next round */ + /* Check when to set the new cycle end */ + if (pic.next_entry) { + Bits cycles=PIC_MakeCycles(pic.next_entry->index-index); + if (!cycles) cycles=1; + if (cycles Timers; + +TIMER_Block * TIMER_RegisterTickHandler(TIMER_TickHandler handler) { + Timer * new_timer=new(Timer); + new_timer->type=T_TICK; + new_timer->tick.handler=handler; + Timers.push_front(new_timer); + return (TIMER_Block *)new_timer; +} + +TIMER_Block * TIMER_RegisterMicroHandler(TIMER_MicroHandler handler,Bitu micro) { + Timer * new_timer=new(Timer); + new_timer->type=T_MICRO; + new_timer->micro.handler=handler; + Timers.push_front(new_timer); + TIMER_SetNewMicro(new_timer,micro); + return (TIMER_Block *)new_timer; +} + +void TIMER_SetNewMicro(TIMER_Block * block,Bitu micro) { + Timer * timer=(Timer *)block; + if (timer->type!=T_MICRO) E_Exit("TIMER:Illegal handler type"); + timer->micro.total=micro; + Bitu index=PIC_Index(); + while ((1000-index)>micro) { + PIC_AddEvent(timer->micro.handler,micro); + micro+=micro; + index+=micro; + } + timer->micro.left=timer->micro.total-(1000-index); +} + +void TIMER_AddTick(void) { + /* Setup new amount of cycles for PIC */ + CPU_CycleLeft=CPU_CycleMax; + CPU_Cycles=0; PIC_Ticks++; /* Go through the list of scheduled irq's and lower their index with 1000 */ PICEntry * entry=pic.next_entry; @@ -381,9 +431,32 @@ Bitu PIC_RunQueue(void) { else entry->index=0; entry=entry->next; } - return 0; + Bits index; + /* Check if there are timer handlers that need to be called */ + std::list::iterator i; + for(i=Timers.begin(); i != Timers.end(); ++i) { + Timer * timers=(*i); + switch (timers->type) { + case T_TICK: + timers->tick.handler(1); + break; + case T_MICRO: + index=1000; + while (index>=timers->micro.left) { + PIC_AddEvent(timers->micro.handler,timers->micro.left); + index-=timers->micro.left; + timers->micro.left=timers->micro.total; + } + timers->micro.left-=index; + break; + default: + E_Exit("TIMER:Illegal handler type"); + } + } } + + void PIC_Init(Section* sec) { /* Setup pic0 and pic1 with initial values like DOS has normally */ PIC_IRQCheck=0; diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 6f501644..4590789b 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -17,9 +17,6 @@ */ - - -#include #include "dosbox.h" #include "inout.h" #include "pic.h" @@ -29,8 +26,6 @@ #include "mixer.h" #include "timer.h" - - struct PIT_Block { Bit8u mode; /* Current Counter Mode */ @@ -165,10 +160,6 @@ static Bit8u read_latch(Bit32u port) { return ret; } - - - - static void write_p43(Bit32u port,Bit8u val) { Bitu latch=(val >> 6) & 0x03; switch (latch) { @@ -197,82 +188,6 @@ static void write_p43(Bit32u port,Bit8u val) { } } -/* The TIMER Part */ - -enum { T_TICK,T_MICRO,T_DELAY}; - -struct Timer { - Bitu type; - union { - struct { - TIMER_TickHandler handler; - } tick; - struct{ - Bits left; - Bits total; - TIMER_MicroHandler handler; - } micro; - }; -}; - -static Timer * first_timer=0; -static std::list Timers; - -TIMER_Block * TIMER_RegisterTickHandler(TIMER_TickHandler handler) { - Timer * new_timer=new(Timer); - new_timer->type=T_TICK; - new_timer->tick.handler=handler; - Timers.push_front(new_timer); - return (TIMER_Block *)new_timer; -} - -TIMER_Block * TIMER_RegisterMicroHandler(TIMER_MicroHandler handler,Bitu micro) { - Timer * new_timer=new(Timer); - new_timer->type=T_MICRO; - new_timer->micro.handler=handler; - Timers.push_front(new_timer); - TIMER_SetNewMicro(new_timer,micro); - return (TIMER_Block *)new_timer; -} - -void TIMER_SetNewMicro(TIMER_Block * block,Bitu micro) { - Timer * timer=(Timer *)block; - if (timer->type!=T_MICRO) E_Exit("TIMER:Illegal handler type"); - timer->micro.total=micro; - Bitu index=PIC_Index(); - while ((1000-index)>micro) { - PIC_AddEvent(timer->micro.handler,micro); - micro+=micro; - index+=micro; - } - timer->micro.left=timer->micro.total-(1000-index); -} - -void TIMER_AddTick(void) { - Bits index; - /* Check if there are timer handlers that need to be called */ - std::list::iterator i; - for(i=Timers.begin(); i != Timers.end(); ++i) { - Timer * timers=(*i); - switch (timers->type) { - case T_TICK: - timers->tick.handler(1); - break; - case T_MICRO: - index=1000; - while (index>=timers->micro.left) { - PIC_AddEvent(timers->micro.handler,timers->micro.left); - index-=timers->micro.left; - timers->micro.left=timers->micro.total; - } - timers->micro.left-=index; - break; - default: - E_Exit("TIMER:Illegal handler type"); - } - - } -} void TIMER_Init(Section* sect) { IO_RegisterWriteHandler(0x40,write_latch,"PIT Timer 0"); From d017f22b89573bfebb0fbde02ce1224b25824ca5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 26 Jul 2003 10:47:47 +0000 Subject: [PATCH 1081/4131] Initial checking for redirection, will need more changes in dos to allow this too work. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1161 --- src/shell/shell.cpp | 86 ++++++++++++++++++++++++++++++++----------- src/shell/shell_inc.h | 2 +- 2 files changed, 66 insertions(+), 22 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 1af2b57d..f82fcb77 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -19,6 +19,7 @@ #include #include +#include #include "setup.h" #include "shell_inc.h" @@ -62,31 +63,75 @@ DOS_Shell::DOS_Shell():Program(){ -Bit32u DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn) { +Bitu DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn,bool * append) { - char *output = strrchr(s, '>'); - if (output) { - *output = 0; - // while (!isalnum(*output)) output++; + char * lr=s; + char * lw=s; + char ch; + Bitu num=0; + + while (ch=*lr++) { + switch (ch) { + case '>': + *append=(*lr)=='>'; + if (append) lr++; + lr=ltrim(lr); + if (*ofn) free(*ofn); + *ofn=lr; + while (*lr && *lr!=' ') lr++; + *lr=0; + *ofn=strdup(*ofn); + continue; + case '<': + if (*ifn) free(*ifn); + lr=ltrim(lr); + *ifn=lr; + while (*lr && *lr!=' ') lr++; + *lr=0; + *ifn=strdup(*ifn); + continue; + case '|': + ch=0; + num++; + } + *lw++=ch; } - - return 1; -} + *lw=0; + return num; +} void DOS_Shell::ParseLine(char * line) { - char * in=0; - char * out=0; - /* Check for a leading @ */ if (line[0]=='@') line[0]=' '; line=trim(line); - Bit32u num=0; /* Number of commands in this line */ - num = GetRedirection(line, &in, &out); +#if 1 + /* Do redirection and pipe checks */ + + char * in=0; + char * out=0; + + Bit16u old_in,old_out; + + Bitu num=0; /* Number of commands in this line */ + bool append; + + num = GetRedirection(line,&in, &out,&append); + if (num>1) LOG_MSG("SHELL:Multiple command on 1 line not supported"); +// if (in || num>1) DOS_DuplicateEntry(0,&old_in); + + if (in) { + LOG_MSG("SHELL:Redirect input from %s",in); + DOS_CloseFile(0); + free(in); + } + if (out) { + LOG_MSG("SHELL:Redirect output to %s",out); + free(out); + } +#endif -/* TODO in and out redirection */ - DoCommand(line); } @@ -159,15 +204,10 @@ void DOS_Shell::SyntaxError(void) { void AUTOEXEC_Init(Section * sec) { MSG_Add("AUTOEXEC_CONFIGFILE_HELP","Add here the lines you want to execute on startup.\n"); /* Register a virtual AUOEXEC.BAT file */ - + std::string line; Section_line * section=static_cast(sec); char * extra=(char *)section->data.c_str(); if (extra) SHELL_AddAutoexec(extra); - /* Check to see for extra command line options to be added */ - std::string line; - while (control->cmdline->FindString("-c",line,true)) { - SHELL_AddAutoexec((char *)line.c_str()); - } /* Check for first command being a directory or file */ char buffer[CROSS_LEN]; if (control->cmdline->FindCommand(1,line)) { @@ -191,6 +231,10 @@ void AUTOEXEC_Init(Section * sec) { SHELL_AddAutoexec(name); } } + /* Check to see for extra command line options to be added */ + while (control->cmdline->FindString("-c",line,true)) { + SHELL_AddAutoexec((char *)line.c_str()); + } nomount: VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,strlen(autoexec_data)); } diff --git a/src/shell/shell_inc.h b/src/shell/shell_inc.h index a50b263c..725b9695 100644 --- a/src/shell/shell_inc.h +++ b/src/shell/shell_inc.h @@ -66,7 +66,7 @@ public: void RunInternal(void); //for command /C /* A load of subfunctions */ void ParseLine(char * line); - Bit32u GetRedirection(char *s, char **ifn, char **ofn); + Bitu GetRedirection(char *s, char **ifn, char **ofn,bool * append); void InputCommand(char * line); void ShowPrompt(); void DoCommand(char * cmd); From 5f169bf3cf8f56d306636250f9969b8e3dc9e7cc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 26 Jul 2003 12:01:41 +0000 Subject: [PATCH 1082/4131] added missing break in eatree. Xcom is finally perfect added F2XM1,FYL2X,FSCALE Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1162 --- src/fpu/fpu.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index dac36612..1012d2f5 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -131,6 +131,7 @@ static void EATREE(Bitu _rm){ break; case 0x05: /* FISUBR */ FPU_FSUBR(TOP,8); + break; case 0x06: /* FIDIV */ FPU_FDIV(TOP, 8); break; @@ -312,6 +313,12 @@ void FPU_ESC1_Normal(Bitu rm) { break; case 0x06: switch(sub){ + case 0x00: /* F2XM1 */ + FPU_F2XM1(); + break; + case 0x01: /* FYL2X */ + FPU_FYL2X(); + break; case 0x02: /* FPTAN */ FPU_FPTAN(); break; @@ -342,6 +349,9 @@ void FPU_ESC1_Normal(Bitu rm) { } //TODO break; + case 0x05: /* FSCALE */ + FPU_FSCALE(); + break; case 0x06: /* FSIN */ FPU_FSIN(); break; @@ -638,8 +648,11 @@ void FPU_ESC7_EA(Bitu rm,PhysPt addr) { mem_writed(addr,static_cast(FROUND(fpu.regs[TOP].d))); FPU_FPOP(); break; + case 0x04: /* FBLD packed BCD */ + //Don't think anybody will ever use this. default: LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); + break; } } From 7e11075f0891b5a87d4b461f57c1f09e9ecc3cec Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 26 Jul 2003 12:02:26 +0000 Subject: [PATCH 1083/4131] added F2XM1,FYL2X,FSCALE changed flags in FCOM Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1163 --- src/fpu/fpu_instructions.h | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 438d2f0d..06b3ded4 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -156,16 +156,16 @@ static void FPU_FST(Bitu st, Bitu other){ static void FPU_FCOM(Bitu st, Bitu other){ if((fpu.tags[st] != TAG_Valid) || (fpu.tags[other] != TAG_Valid)){ - FPU_SET_C3(1);FPU_SET_C1(1);FPU_SET_C0(1);return; + FPU_SET_C3(1);FPU_SET_C2(1);FPU_SET_C1(1);FPU_SET_C0(1);return; } if(fpu.regs[st].d == fpu.regs[other].d){ - FPU_SET_C3(1);FPU_SET_C1(0);FPU_SET_C0(0);return; + FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C1(0);FPU_SET_C0(0);return; } if(fpu.regs[st].d < fpu.regs[other].d){ - FPU_SET_C3(0);FPU_SET_C1(0);FPU_SET_C0(1);return; + FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C1(0);FPU_SET_C0(1);return; } // st > other - FPU_SET_C3(0);FPU_SET_C1(0);FPU_SET_C0(0);return; + FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C1(0);FPU_SET_C0(0);return; } static void FPU_FUCOM(Bitu st, Bitu other){ @@ -297,4 +297,18 @@ static void FPU_ST80(PhysPt addr) mem_writew(addr+8,test.begin); } +static void FPU_F2XM1(void){ + fpu.regs[TOP].d=pow(2.0,fpu.regs[TOP].d) -1; + return; +} + +static void FPU_FYL2X(void){ + fpu.regs[ST(1)].d*=log(fpu.regs[TOP].d)/log(2); + FPU_FPOP(); + return; +} +static void FPU_FSCALE(void){ + fpu.regs[TOP].d *=pow(2.0,static_cast(static_cast(FROUND(fpu.regs[ST(1)].d)))); + return; //2^x where x is chopped. +} From 4fe5eb776f9bffff9214d6d0777f1e44060cae5b Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 26 Jul 2003 16:32:29 +0000 Subject: [PATCH 1084/4131] changes to support cpu core switching Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1164 --- src/ints/dpmi.cpp | 69 ++++++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index 0bbdb8e4..273d65f6 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -487,24 +487,24 @@ void DPMI::ProvideRealModeStack(PhysPt prStack, Bitu toCopy) // Check stack, if zero provide it if ((SegValue(ss)==0) && (reg_sp==0)) { SegSet16(ss,rm_ss); - reg_sp = rm_sp; + reg_esp = rm_sp; } else { - if (SegValue(ss)==rm_ss) reg_sp = rm_sp; + if (SegValue(ss)==rm_ss) reg_esp = rm_sp; }; // We have to be in realmode here if (toCopy>0) { Bitu numBytes = toCopy*2; - if (reg_spDPMI_REALMODE_STACKSIZE) E_Exit("DPMI:Realmode stack out of range: %04X",reg_sp); + if (reg_esp>DPMI_REALMODE_STACKSIZE) E_Exit("DPMI:Realmode stack out of range: %04X",reg_esp); rm_sp = reg_sp; } }; @@ -620,23 +620,24 @@ Bitu DPMI::ExceptionReturn(void) { Bitu error; // Restore Registers + Bitu newcs; if (dpmi.client.bit32) { error = CPU_Pop32(); reg_eip = CPU_Pop32(); - CPU_SetSegGeneral(cs,CPU_Pop32()); + newcs = CPU_Pop32(); CPU_SetFlagsd(CPU_Pop32()); reg_esp = CPU_Pop32(); CPU_SetSegGeneral(ss,CPU_Pop32()); } else { error = CPU_Pop16(); reg_eip = CPU_Pop16(); - CPU_SetSegGeneral(cs,CPU_Pop16()); + newcs = CPU_Pop16(); CPU_SetFlagsw(CPU_Pop16()); reg_esp = CPU_Pop16(); CPU_SetSegGeneral(ss,CPU_Pop16()); }; DPMI_LOG("DPMI: Return from Exception. Jump to %04X:%08X",SegValue(cs),reg_eip); - CPU_JMP(dpmi.client.bit32,SegValue(cs),reg_eip); + CPU_JMP(dpmi.client.bit32,newcs,reg_eip); return 0; }; @@ -758,11 +759,13 @@ Bitu DPMI::RealModeCallbackReturn(void) Bitu newCS = mem_readw(data+0x2C); Bitu newIP = mem_readw(data+0x2A); UpdateRealModeStack(); - DPMI_LOG("DPMI: CB: Retored cs:ip = %04X:%04X",newCS,newIP); + DPMI_LOG("DPMI: CB: Retored cs:ip = %04X:%04X (%d)",newCS,newIP); CPU_JMP(false,newCS,newIP); return 0; }; +static Bitu count = 0; + Bitu DPMI::CallRealIRETFrame(void) { Bitu calledIP = mem_readd(SegPhys(ss)+reg_esp); @@ -799,15 +802,17 @@ Bitu DPMI::CallRealIRETFrameReturn(void) { UpdateRealModeStack(); // returning from realmode func - DPMI_LOG("DPMI: LEAVE REAL PROC IRETF"); + DPMI_LOG("DPMI: LEAVE REAL PROC IRETF %d",count); /* Switch to protected mode */ CPU_SET_CRX(0,cpu.cr0 | CR0_PROTECTION); // Save registers into real mode structure CopyRegistersToBuffer(PopStack()); // Restore changed Resgisters RestoreRegister(); - CPU_SetSegGeneral(cs,PopStack()); - // Free last realmode stack + Bitu newcs = PopStack(); + + CPU_JMP(dpmi.client.bit32,newcs,reg_eip); + DPMI_CALLBACK_SCF(false); return 0; }; @@ -815,7 +820,7 @@ Bitu DPMI::CallRealIRETFrameReturn(void) Bitu DPMI::SimulateInt(void) { Bitu num = reg_bl; - DPMI_LOG("DPMI: SIM INT %02X %04X called.",num,reg_ax); + DPMI_LOG("DPMI: SIM INT %02X %04X called. cs = %04X",num,reg_ax,SegValue(cs)); // Save changed registers PushStack(SegValue(cs)); SaveRegister(); @@ -833,10 +838,10 @@ Bitu DPMI::SimulateInt(void) SegSet16(cs,RealSeg(CALLBACK_RealPointer(callback.simintReturn))); reg_ip = RealOff(CALLBACK_RealPointer(callback.simintReturn)); // Push flags from structure on stack - DPMI_LOG("DPMI: SimInt1: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_sp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); + DPMI_LOG("DPMI: SimInt1: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_esp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); flags.word = mem_readw(data+0x20); Interrupt(num); - DPMI_LOG("DPMI: SimInt2: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_sp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); + DPMI_LOG("DPMI: SimInt2: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_esp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); return 0; }; @@ -844,7 +849,7 @@ Bitu DPMI::SimulateIntReturn(void) { // returning from realmode func DPMI_LOG("DPMI: SIM INT return"); - DPMI_LOG("DPMI: SimIntRet1: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_sp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); + DPMI_LOG("DPMI: SimIntRet1: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_esp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); UpdateRealModeStack(); /* Switch to protected mode */ @@ -853,10 +858,12 @@ Bitu DPMI::SimulateIntReturn(void) CopyRegistersToBuffer(PopStack()); // Restore changed Resgisters RestoreRegister(); - CPU_SetSegGeneral(cs,PopStack()); + Bitu newcs = PopStack(); + DPMI_LOG("DPMI: SimIntRet: JUMP to %04X:%08X",newcs,reg_eip); + CPU_JMP(dpmi.client.bit32,newcs,reg_eip); // Free last realmode stack DPMI_CALLBACK_SCF(false); - DPMI_LOG("DPMI: SimIntRet2: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_sp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); + DPMI_LOG("DPMI: SimIntRet2: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_esp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); return 0; }; @@ -871,11 +878,14 @@ void DPMI::PrepareReflectToReal(Bitu num) /* Swtich to real mode */ CPU_SET_CRX(0,cpu.cr0 & ~CR0_PROTECTION); // Setup cs:ip to return to intreturn + Bitu retcs = RealSeg(CALLBACK_RealPointer(callback.ptorintReturn)); + Bitu retip = RealOff(CALLBACK_RealPointer(callback.ptorintReturn)); + SegSet16(cs,RealSeg(CALLBACK_RealPointer(callback.ptorintReturn))); reg_ip = RealOff(CALLBACK_RealPointer(callback.ptorintReturn)); // setup stack SegSet16(ss,rm_ss); - reg_sp = rm_sp; + reg_esp = rm_sp; } Bitu DPMI::ptorHandler(void) @@ -887,7 +897,7 @@ Bitu DPMI::ptorHandler(void) if ((num>=0x70) && (num<=0x77)) return 0; }; PrepareReflectToReal(num); - if (num==0x0F) +// if (num==0x0F) DPMI_LOG("DPMI: INT %02X %04X called.",num,reg_ax); // Prepare flags for real int // CPU_SetFlagsw(flags.word & 0x3ED5); // 0011111011010101b @@ -902,15 +912,16 @@ Bitu DPMI::ptorHandlerReturn(void) /* Switch to protected mode */ CPU_SET_CRX(0,cpu.cr0 | CR0_PROTECTION); // Restore Registers - CPU_SetSegGeneral(cs,PopStack()); - reg_eip = PopStack(); - Bitu num = PopStack(); - reg_esp = PopStack(); + Bitu newcs = PopStack(); + reg_eip = PopStack(); + Bitu num = PopStack(); + reg_esp = PopStack(); RestoreSegments(); // if (num==0x0F) DPMI_LOG("DPMI: INT %02X RETURN",num); // hardware ints exit here if (((num>=0x08) && (num<=0x0F)) || ((num>=0x70) && (num<=0x77))) { + CPU_JMP(dpmi.client.bit32,newcs,reg_eip); return 0; } // Change flags on stack to reflect possible results from ints @@ -923,6 +934,7 @@ Bitu DPMI::ptorHandlerReturn(void) Bit16u userFlags = flags.word & FLAG_MASK; // Mask out illegal flags not to change by int (0011111011010101b) mem_writew(SegPhys(ss)+reg_sp+4,oldFlags|userFlags); }; + CPU_JMP(dpmi.client.bit32,newcs,reg_eip); return 0; } @@ -972,6 +984,7 @@ Bitu DPMI::Int21HandlerReturn(void) // Set carry flag DPMI_CALLBACK_SCF(flags.word & 1); DPMI_LOG("DPMI: INT 21 RETURN"); + CPU_JMP(dpmi.client.bit32,SegValue(cs),reg_eip); return 0; } @@ -1522,7 +1535,7 @@ Bitu DPMI::Int31Handler(void) DPMI_CALLBACK_SCF(true); }; } else { - DPMI_LOG_ERROR("DPMI: 0100: Allocation failure : %04X (R:%04X)",reg_bx,blocks); + DPMI_LOG("DPMI: 0100: Allocation failure : %04X (R:%04X)",reg_bx,blocks); reg_bx = blocks; reg_ax = 0x008; // Insufficient memory DPMI_CALLBACK_SCF(true); @@ -1544,7 +1557,7 @@ Bitu DPMI::Int31Handler(void) sel+=8; }; DPMI_CALLBACK_SCF(false); - DPMI_LOG_ERROR("DPMI: 0101: Free Dos Mem: %04X",reg_dx); + DPMI_LOG("DPMI: 0101: Free Dos Mem: %04X",reg_dx); break; } } @@ -1910,7 +1923,7 @@ Bitu DPMI::Int31Handler(void) Bitu DPMI::Int2fHandler(void) { // Only available in ProtectedMode - //LOG(LOG_MISC,LOG_WARN)("DPMI: 0x2F %04x",reg_ax); + // LOG(LOG_MISC,LOG_WARN)("DPMI: 0x2F %04x",reg_ax); switch (reg_ax) { case 0x1686: /* Get CPU Mode */ reg_ax = 0; From dc824945f592557852c10e97474941dd28afc65d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 26 Jul 2003 18:39:20 +0000 Subject: [PATCH 1085/4131] Fixed messages when running non-debug mode (under linux) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1165 --- src/gui/sdlmain.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index e5c22e43..117b8def 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -559,8 +559,9 @@ void GFX_ShowMsg(char * format,...) { va_list msg; va_start(msg,format); vsprintf(buf,format,msg); + strcat(buf,"\n"); va_end(msg); - printf(buf); + printf(buf); }; int main(int argc, char* argv[]) { From 359e55ed8cca839b7067d8438fb24c3e125bab2f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 27 Jul 2003 12:12:05 +0000 Subject: [PATCH 1086/4131] Added support for regular files with int 21 ax =4406 (get input status) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1166 --- src/dos/dos_ioctl.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index f509242a..4bd7fcd6 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: dos_ioctl.cpp,v 1.12 2003-07-27 12:12:05 qbix79 Exp $ */ + #include #include "dosbox.h" #include "callback.h" @@ -43,9 +45,19 @@ bool DOS_IOCTL(void) { case 0x06: /* Get Input Status */ if (Files[handle]->GetInformation() & 0x8000) { //Check for device reg_al=(Files[handle]->GetInformation() & 0x40) ? 0xff : 0; - } else { - LOG(LOG_IOCTL,LOG_NORMAL)("06:Unsupported File handle %d",handle); - reg_al=0xff; + } else { // FILE + Bit32u oldlocation=0; + Files[handle]->Seek(&oldlocation, DOS_SEEK_CUR); + Bit32u endlocation=0; + Files[handle]->Seek(&endlocation, DOS_SEEK_END); + if(oldlocation < endlocation){//Still data available + reg_al=0x0; + } else + { + reg_al=0xff; //EOF or beyond + } + Files[handle]->Seek(&oldlocation, DOS_SEEK_SET); //restore filelocation + LOG(LOG_IOCTL,LOG_NORMAL)("06:Used Get Input Status on regualar file with handle %d",handle); } return true; case 0x07: /* Get Output Status */ From 09ed20abec733efeac47df09d213e683947d45c5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 27 Jul 2003 19:47:47 +0000 Subject: [PATCH 1087/4131] Removed double segment prefix base add for SIB lookups Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1167 --- src/cpu/core_16/table_ea.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/cpu/core_16/table_ea.h b/src/cpu/core_16/table_ea.h index 28ec08b7..cf7131fd 100644 --- a/src/cpu/core_16/table_ea.h +++ b/src/cpu/core_16/table_ea.h @@ -273,25 +273,25 @@ INLINE PhysPt Sib_s(Bitu mode) { PhysPt base; switch (sib&7) { case 0: /* EAX Base */ - base=core_16.segbase+reg_eax;break; + base=reg_eax;break; case 1: /* ECX Base */ - base=core_16.segbase+reg_ecx;break; + base=reg_ecx;break; case 2: /* EDX Base */ - base=core_16.segbase+reg_edx;break; + base=reg_edx;break; case 3: /* EBX Base */ - base=core_16.segbase+reg_ebx;break; + base=reg_ebx;break; case 4: /* ESP Base */ - base=core_16.segbase+reg_esp;break; + base=reg_esp;break; case 5: /* #1 Base */ if (!mode) { - base=core_16.segbase+Fetchd();break; + base=Fetchd();break; } else { - base=core_16.segbase+reg_ebp;break; + base=reg_ebp;break; } case 6: /* ESI Base */ - base=core_16.segbase+reg_esi;break; + base=reg_esi;break; case 7: /* EDI Base */ - base=core_16.segbase+reg_edi;break; + base=reg_edi;break; } base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6); return base; From a1fe43c151ae7e18301ffcf99bcf474ac06551a4 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 27 Jul 2003 20:20:40 +0000 Subject: [PATCH 1088/4131] Debugger is activated via callback now Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1168 --- include/debug.h | 1 + src/cpu/core_16/main.h | 6 ++++-- src/cpu/core_full.cpp | 3 +-- src/cpu/core_full/op.h | 4 ++-- src/cpu/slow_16.cpp | 2 +- src/debug/debug.cpp | 43 +++++++++++++++++++++++++----------------- src/dosbox.cpp | 4 ++++ 7 files changed, 39 insertions(+), 24 deletions(-) diff --git a/include/debug.h b/include/debug.h index de1d460e..28f02975 100644 --- a/include/debug.h +++ b/include/debug.h @@ -25,6 +25,7 @@ void DEBUG_CheckExecuteBreakpoint(Bit16u seg, Bit32u off); bool DEBUG_ExitLoop(void); extern Bitu cycle_count; +extern Bitu debugCallback; #ifdef C_HEAVY_DEBUG bool DEBUG_HeavyIsBreakpoint(void); diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 97ff4080..2814fe54 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -798,8 +798,9 @@ restart: #if C_DEBUG SAVEIP; if (DEBUG_Breakpoint()) { + LOADIP; LEAVECORE; - return -1; + return debugCallback; } LOADIP; #endif @@ -811,8 +812,9 @@ restart: #if C_DEBUG SAVEIP; if (DEBUG_IntBreakpoint(num)) { + LOADIP; LEAVECORE; - return -1; + return debugCallback; } #endif EXCEPTION(num); diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 5663a9b4..5dd03875 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -55,7 +55,6 @@ static EAPoint IPPoint; #include "core_full/ea_lookup.h" #include "instructions.h" - static INLINE void DecodeModRM(void) { inst.rm=Fetchb(); inst.rm_index=(inst.rm >> 3) & 7; @@ -89,7 +88,7 @@ Bits Full_DeCode(void) { SaveIP(); if (DEBUG_HeavyIsBreakpoint()) { LEAVECORE; - return 1; + return debugCallback; }; #endif #endif diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 98596f49..8243fdaf 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -341,8 +341,8 @@ switch (inst.code.op) { case O_INT: LEAVECORE; #if C_DEBUG - if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint()) return -1; - else if (DEBUG_IntBreakpoint(inst.op1.b)) return -1; + if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint()) return debugCallback; + else if (DEBUG_IntBreakpoint(inst.op1.b)) return debugCallback; #endif Interrupt(inst.op1.b); LoadIP(); diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp index 67b08d87..4ebe1ced 100644 --- a/src/cpu/slow_16.cpp +++ b/src/cpu/slow_16.cpp @@ -84,7 +84,7 @@ decode_start: cycle_count++; #if C_HEAVY_DEBUG LEAVECORE; - if (DEBUG_HeavyIsBreakpoint()) return 1; + if (DEBUG_HeavyIsBreakpoint()) return debugCallback; #endif #endif core_16.ip_start=core_16.ip_lookup; diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index caf7f1ff..351c8f17 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -512,8 +512,8 @@ bool DEBUG_Breakpoint(void) // Found. Breakpoint is valid reg_eip -= 1; CBreakpoint::ActivateBreakpoints(where,false); // Deactivate all breakpoints - exitLoop = true; - DEBUG_Enable(); +// exitLoop = true; +// DEBUG_Enable(); return true; }; @@ -526,8 +526,8 @@ bool DEBUG_IntBreakpoint(Bit8u intNum) // Found. Breakpoint is valid reg_eip -= 2; CBreakpoint::ActivateBreakpoints(where,false); // Deactivate all breakpoints - exitLoop = true; - DEBUG_Enable(); +// exitLoop = true; +// DEBUG_Enable(); return true; }; @@ -628,8 +628,8 @@ static void DrawRegisters(void) { oldflags=flags.word; - if (cpu.pmode) mvwprintw(dbg.win_reg,0,76,"Prot"); - else mvwprintw(dbg.win_reg,0,76,"Real"); + if (cpu.pmode) mvwprintw(dbg.win_reg,0,76,"Prot"); + else mvwprintw(dbg.win_reg,0,76,"Real"); // Selector info, if available if ((cpu.pmode) && curSelectorName[0]) { @@ -1272,6 +1272,7 @@ Bit32u DEBUG_CheckKeys(void) { skipFirstInstruction = true; // for heavy debugger CPU_Cycles = 1; Bitu ret=(*cpudecoder)(); + if (ret>0) ret=(*CallBack_Handlers[ret])(); SetCodeWinStart(); CBreakpoint::ignoreOnce = 0; } @@ -1280,15 +1281,11 @@ Bit32u DEBUG_CheckKeys(void) { skipFirstInstruction = true; // for heavy debugger CPU_Cycles = 1; ret = (*cpudecoder)(); + if (ret>0) ret=(*CallBack_Handlers[ret])(); SetCodeWinStart(); CBreakpoint::ignoreOnce = 0; break; - -// default: -// // FIXME : Is this correct ? -// if (key<0x200) ret=(*cpudecoder)(1); -// break; - }; + } DEBUG_DrawScreen(); } return ret; @@ -1308,7 +1305,6 @@ Bitu DEBUG_Loop(void) { DOSBOX_SetNormalLoop(); return 0; } - return DEBUG_CheckKeys(); } @@ -1371,7 +1367,8 @@ static bool DEBUG_Log_Loop(int count) { CPU_Cycles = 1; ret=(*cpudecoder)(); - + if (ret>0) ret=(*CallBack_Handlers[ret])(); + count--; if (count==0) break; @@ -1446,6 +1443,13 @@ void DEBUG_CheckExecuteBreakpoint(Bit16u seg, Bit32u off) }; }; +Bitu DEBUG_EnableDebugger(void) +{ + exitLoop = true; + DEBUG_Enable(); + return 0; +}; + static void DEBUG_ProgramStart(Program * * make) { *make=new DEBUG; } @@ -1481,6 +1485,8 @@ static void DEBUG_ShutDown(Section * sec) #endif }; +Bitu debugCallback; + void DEBUG_Init(Section* sec) { MSG_Add("DEBUG_CONFIGFILE_HELP","Nothing to setup yet!\n"); @@ -1492,6 +1498,9 @@ void DEBUG_Init(Section* sec) { memset((void*)&codeViewData,0,sizeof(codeViewData)); /* setup debug.com */ PROGRAMS_MakeFile("DEBUG.COM",DEBUG_ProgramStart); + /* Setup callback */ + debugCallback=CALLBACK_Allocate(); + CALLBACK_Setup(debugCallback,DEBUG_EnableDebugger,CB_RETF); /* shutdown function */ sec->AddDestroyFunction(&DEBUG_ShutDown); } @@ -1602,7 +1611,7 @@ void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num) #if C_HEAVY_DEBUG -const Bit32u LOGCPUMAX = 200; +const Bit32u LOGCPUMAX = 20000; static Bit16u logCpuCS [LOGCPUMAX]; static Bit32u logCpuEIP[LOGCPUMAX]; @@ -1681,8 +1690,8 @@ bool DEBUG_HeavyIsBreakpoint(void) PhysPt where = SegPhys(cs)+reg_eip; if (CBreakpoint::CheckBreakpoint(SegValue(cs),reg_eip)) { - exitLoop = true; - DEBUG_Enable(); +// exitLoop = true; +// DEBUG_Enable(); return true; } return false; diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 0ca13ceb..fb9d96a6 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -111,6 +111,9 @@ static Bitu Normal_Loop(void) { if (ret>0) { Bitu blah=(*CallBack_Handlers[ret])(); if (blah) return blah; +#if C_DEBUG + if (DEBUG_ExitLoop()) return 0; +#endif } } else { if (RemainTicks>0) { @@ -260,6 +263,7 @@ void DOSBOX_Init(void) { secprop->Add_bool("ems",true); secprop->AddInitFunction(&DPMI_Init); secprop->Add_bool("dpmi",true); + #if C_MODEM secprop=control->AddSection_prop("modem",&MODEM_Init); secprop->Add_bool("enabled",true); From 1780f7023289dfa6a4626ed08dec71a5ecd76fc9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 27 Jul 2003 22:53:37 +0000 Subject: [PATCH 1089/4131] Core_full cpu decoder starts up when protected mode is enabled. Small change for certain flag bits always being on/off Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1169 --- src/cpu/cpu.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index a70c5d22..c44dcd7a 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -86,7 +86,7 @@ PhysPt SelBase(Bitu sel) { } void CPU_SetFlags(Bitu word) { - flags.word=word; + flags.word=(word|2)&~0x14; } bool CPU_CheckCodeType(CODE_TYPE type) { @@ -524,6 +524,7 @@ bool CPU_SET_CRX(Bitu cr,Bitu value) { cpu.pmode=true; LOG_MSG("Protected mode"); PAGING_Enable((value & CR0_PAGING)>0); + CPU_Core_Full_Start(cpu.code.big); } else { cpu.pmode=false; PAGING_Enable(false); @@ -850,7 +851,7 @@ void CPU_Init(Section* sec) { SegSet16(ss,0); reg_eip=0; - flags.word=FLAG_IF; + CPU_SetFlags(FLAG_IF); //Enable interrupts cpu.cr0=0xffffffff; CPU_SET_CRX(0,0); //Initialize cpu.v86=false; From 2a4fa63ace68cc4b3d93f4c8b27fb23f0d69557a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 27 Jul 2003 22:55:28 +0000 Subject: [PATCH 1090/4131] 8-bit flag saves need to save Overflow flag and now use cpu function for saving flags. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1170 --- src/cpu/lazyflags.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index 479c8929..a10e6207 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -26,9 +26,9 @@ Bitu get_PF(void); #define SETFLAGSb(FLAGB) \ { \ + SETFLAGBIT(OF,get_OF()); \ flags.type=t_UNKNOWN; \ - flags.word&=0xffffff00; \ - flags.word|=(FLAGB&0xff); \ + CPU_SetFlags((flags.word&0xffffff00)|((FLAGB) & 0xff)); \ } #define SETFLAGSw(FLAGW) \ From 1ae2780eceb243fea1465797bb86b87358057d60 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 28 Jul 2003 08:22:15 +0000 Subject: [PATCH 1091/4131] Interrupt now handled without using EXCEPTION. Exception now resets IP to the faulting instruction. LAHF uses the lower 8-bit of the flags word. SS changing instruction do another cycle to be interrupt free. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1171 --- src/cpu/core_16/main.h | 41 ++++++++++++++++++++++--------------- src/cpu/core_16/prefix_66.h | 2 +- src/cpu/core_16/prefix_of.h | 1 + src/cpu/core_16/support.h | 23 +++++++++++---------- 4 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 2814fe54..2ccd460d 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -67,7 +67,8 @@ restart: Push_16(SegValue(ss));break; case 0x17: /* POP SS */ SegSet16(ss,Pop_16()); - goto restart; + CPU_Cycles++;//Be sure we run another instruction + break; case 0x18: /* SBB Eb,Gb */ RMEbGb(SBBB);break; case 0x19: /* SBB Ew,Gw */ @@ -251,7 +252,7 @@ restart: break; case 0x67: /* Address Size Prefix */ #ifdef CPU_PREFIX_67 - core_16.prefixes|=PREFIX_ADDR; + core_16.prefixes^=PREFIX_ADDR; lookupEATable=EAPrefixTable[core_16.prefixes]; goto restart; #else @@ -517,7 +518,7 @@ restart: break; case 0x10: /* MOV SS,Ew */ SegSet16(ss,val); - goto restart; + CPU_Cycles++;//Be sure we run another instruction break; case 0x18: /* MOV DS,Ew */ SegSet16(ds,val);break; @@ -591,8 +592,8 @@ restart: break; case 0x9f: /* LAHF */ { - reg_ah=(get_CF() << 0) | (get_PF() << 2) | (get_AF() << 4) | - (get_ZF() << 6) | (get_SF() << 7); + FILLFLAGS; + reg_ah=(Bit8u)flags.word; break; } case 0xa0: /* MOV AL,Ob */ @@ -795,29 +796,37 @@ restart: } break; case 0xcc: /* INT3 */ + LEAVECORE; #if C_DEBUG - SAVEIP; if (DEBUG_Breakpoint()) { - LOADIP; - LEAVECORE; return debugCallback; } - LOADIP; -#endif - EXCEPTION(3); - break; +#endif + if (Interrupt(3)) { + if (GETFLAG(TF)) { + LOG_MSG("Switch to trap decoder"); + cpudecoder=CPU_Real_16_Slow_Decode_Trap; + return CBRET_NONE; + } + goto decode_start; + } else return CBRET_NONE; case 0xcd: /* INT Ib */ { Bit8u num=Fetchb(); + LEAVECORE; #if C_DEBUG - SAVEIP; if (DEBUG_IntBreakpoint(num)) { - LOADIP; - LEAVECORE; return debugCallback; } #endif - EXCEPTION(num); + if (Interrupt(num)) { + if (GETFLAG(TF)) { + LOG_MSG("Switch to trap decoder"); + cpudecoder=CPU_Real_16_Slow_Decode_Trap; + return CBRET_NONE; + } + goto decode_start; + } else return CBRET_NONE; } break; case 0xce: /* INTO */ diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index a4b479eb..6173b87e 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -155,7 +155,7 @@ switch(Fetchb()) { SegPrefix_66(gs);break; case 0x67: /* Address Size Prefix */ #ifdef CPU_PREFIX_67 - core_16.prefixes|=PREFIX_ADDR; + core_16.prefixes^=PREFIX_ADDR; lookupEATable=EAPrefixTable[core_16.prefixes]; goto restart_66; #else diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h index 55450955..f28113c8 100644 --- a/src/cpu/core_16/prefix_of.h +++ b/src/cpu/core_16/prefix_of.h @@ -262,6 +262,7 @@ switch(Fetchb()) { { GetRMrw;GetEAa; *rmrw=LoadMw(eaa);SegSet16(ss,LoadMw(eaa+2)); + CPU_Cycles++;//Be sure we run another instruction break; } case 0xb3: /* BTR Ew,Gw */ diff --git a/src/cpu/core_16/support.h b/src/cpu/core_16/support.h index ede6fe25..02ed3a44 100644 --- a/src/cpu/core_16/support.h +++ b/src/cpu/core_16/support.h @@ -42,17 +42,18 @@ static INLINE void ADDIPFAST(Bit16s blah) { } -#define EXCEPTION(blah) \ - { \ - Bit8u new_num=blah; \ - LEAVECORE; \ - if (Interrupt(new_num)) { \ - if (GETFLAG(TF)) { \ - cpudecoder=CPU_Real_16_Slow_Decode_Trap; \ - return CBRET_NONE; \ - } \ - goto decode_start; \ - } else return CBRET_NONE; \ +#define EXCEPTION(blah) \ + { \ + Bit8u new_num=blah; \ + core_16.ip_lookup=core_16.ip_start; \ + LEAVECORE; \ + if (Interrupt(new_num)) { \ + if (GETFLAG(TF)) { \ + cpudecoder=CPU_Real_16_Slow_Decode_Trap; \ + return CBRET_NONE; \ + } \ + goto decode_start; \ + } else return CBRET_NONE; \ } static INLINE Bit8u Fetchb() { From 551fb535f14f83f7c16f06e8cb33abf176c50778 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 28 Jul 2003 08:23:14 +0000 Subject: [PATCH 1092/4131] Add lazy_flags.h to the makefile Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1172 --- src/cpu/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/Makefile.am b/src/cpu/Makefile.am index 18061a5d..b485ebed 100644 --- a/src/cpu/Makefile.am +++ b/src/cpu/Makefile.am @@ -3,4 +3,4 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libcpu.a libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h slow_16.cpp core_full.cpp instructions.h \ - paging.cpp \ No newline at end of file + paging.cpp lazyflags.h \ No newline at end of file From f6cd3dd51e8bf226b0078f1fa4ddcf0d3dc637df Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 28 Jul 2003 08:25:02 +0000 Subject: [PATCH 1093/4131] On exception reset eip to start of opcode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1173 --- src/cpu/core_full.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 5dd03875..053e339f 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -71,6 +71,7 @@ static INLINE void DecodeModRM(void) { #define EXCEPTION(blah) \ { \ Bit8u new_num=blah; \ + IPPoint=inst.start_entry; \ LEAVECORE; \ Interrupt(new_num); \ LoadIP(); \ From dabe910b108cf2e95a8c8c477b1d901cf5326414 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 29 Jul 2003 09:24:37 +0000 Subject: [PATCH 1094/4131] fixed a bug when calling int 21/31 (set to pm code segment) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1174 --- src/ints/dpmi.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index 273d65f6..fa98edb7 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -950,6 +950,7 @@ Bitu DPMI::Int21Handler(void) PushStack(reg_esp); PushStack(SegValue(ds)); PushStack(SegValue(es)); + PushStack(SegValue(cs)); /* Swtich to real mode */ CPU_SET_CRX(0,cpu.cr0 & ~CR0_PROTECTION); @@ -958,7 +959,7 @@ Bitu DPMI::Int21Handler(void) reg_ip = RealOff(CALLBACK_RealPointer(callback.int21Return)); // setup stack SegSet16(ss,rm_ss); - reg_sp = rm_sp; + reg_esp = rm_sp; // Call realmode interrupt DPMI_LOG("DPMI: INT 21 %04X called.",reg_ax); Interrupt(0x21); @@ -976,15 +977,15 @@ Bitu DPMI::Int21HandlerReturn(void) /* Switch to protected mode */ CPU_SET_CRX(0,cpu.cr0 | CR0_PROTECTION); // Restore Registers + Bitu newcs = PopStack(); CPU_SetSegGeneral(es,PopStack()); CPU_SetSegGeneral(ds,PopStack()); reg_esp = PopStack(); CPU_SetSegGeneral(ss,PopStack()); - // DPMI_RestoreSegments(); // Set carry flag DPMI_CALLBACK_SCF(flags.word & 1); DPMI_LOG("DPMI: INT 21 RETURN"); - CPU_JMP(dpmi.client.bit32,SegValue(cs),reg_eip); + CPU_JMP(dpmi.client.bit32,newcs,reg_eip); return 0; } From 76ec14475b9272c48f39e4a0e9346b4399148d48 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 31 Jul 2003 15:33:08 +0000 Subject: [PATCH 1095/4131] Bit testing opcodes didn't load first operand Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1175 --- src/cpu/core_full/optable.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 116fb3c9..aaee0edc 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -294,23 +294,23 @@ static OpCode OpCodeTable[1024]={ /* 0x1a0 - 0x1a7 */ {L_SEG ,0 ,S_PUSHw ,fs },{L_POPw ,0 ,S_SEGI ,fs }, -{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTw ,0 ,0 }, +{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTw ,0 ,M_Gw }, {L_MODRM ,O_DSHLw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHLw ,S_Ew ,M_EwGwCL }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x1a8 - 0x1af */ {L_SEG ,0 ,S_PUSHw ,gs },{L_POPw ,0 ,S_SEGI ,gs }, -{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSw ,0 ,0 }, +{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSw ,0 ,M_Gw }, {L_MODRM ,O_DSHRw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHRw ,S_Ew ,M_EwGwCL }, {0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRw ,S_Gw ,M_EwxGwx }, /* 0x1b0 - 0x1b7 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,O_SEGSS ,S_SEGGw,M_Efw },{L_MODRM ,O_BTRw ,0 ,0 }, +{L_MODRM ,O_SEGSS ,S_SEGGw,M_Efw },{L_MODRM ,O_BTRw ,0 ,M_Gw }, {L_MODRM ,O_SEGFS ,S_SEGGw,M_Efw },{L_MODRM ,O_SEGGS ,S_SEGGw,M_Efw }, {L_MODRM ,0 ,S_Gw ,M_Eb },{L_MODRM ,0 ,S_Gw ,M_Ew }, /* 0x1b8 - 0x1bf */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,0xe ,0 ,M_GRP },{L_MODRM ,O_BTCw ,0 ,0 }, +{L_MODRM ,0xe ,0 ,M_GRP },{L_MODRM ,O_BTCw ,0 ,M_Gw }, {L_MODRM ,O_BSFw ,S_Gw ,M_Ew },{L_MODRM ,O_BSRw ,S_Gw ,M_Ew }, {L_MODRM ,0 ,S_Gw ,M_Ebx },{L_MODRM ,0 ,S_Gw ,M_Ewx }, @@ -650,23 +650,23 @@ static OpCode OpCodeTable[1024]={ /* 0x3a0 - 0x3a7 */ {L_SEG ,0 ,S_PUSHd ,fs },{L_POPd ,0 ,S_SEGI ,fs }, -{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTd ,0 ,0 }, +{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTd ,0 ,M_Gd }, {L_MODRM ,O_DSHLd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHLd ,S_Ed ,M_EdGdCL }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x3a8 - 0x3af */ {L_SEG ,0 ,S_PUSHd ,gs },{L_POPd ,0 ,S_SEGI ,gs }, -{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSd ,0 ,0 }, +{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSd ,0 ,M_Gd }, {L_MODRM ,O_DSHRd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHRd ,S_Ed ,M_EdGdCL }, {0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdxGdx }, /* 0x3b0 - 0x3b7 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,O_SEGSS ,S_SEGGd,M_Efd },{L_MODRM ,O_BTRd ,0 ,0 }, +{L_MODRM ,O_SEGSS ,S_SEGGd,M_Efd },{L_MODRM ,O_BTRd ,0 ,M_Gd }, {L_MODRM ,O_SEGFS ,S_SEGGd,M_Efd },{L_MODRM ,O_SEGGS ,S_SEGGd,M_Efd }, {L_MODRM ,0 ,S_Gd ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ew }, /* 0x3b8 - 0x3bf */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,0xf ,0 ,M_GRP },{L_MODRM ,O_BTCd ,0 ,0 }, +{L_MODRM ,0xf ,0 ,M_GRP },{L_MODRM ,O_BTCd ,0 ,M_Gd }, {L_MODRM ,O_BSFd ,S_Gd ,M_Ed },{L_MODRM ,O_BSRd ,S_Gd ,M_Ed }, {L_MODRM ,0 ,S_Gd ,M_Ebx },{L_MODRM ,0 ,S_Gd ,M_Ewx }, From f97b4bb8001f1e15031438cb8b562ec7f701a9a9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 31 Jul 2003 16:05:16 +0000 Subject: [PATCH 1096/4131] BSR and BSF correctly set zero flag now and 0 source for scan Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1176 --- src/cpu/core_full/op.h | 68 +++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 8243fdaf..99d90f3e 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -479,53 +479,65 @@ switch (inst.code.op) { case O_BSFw: { FILLFLAGS; - if (!inst.op1.w) SETFLAGBIT(ZF,true); - Bitu count=0; - while (count<16) { - if ((inst.op1.w>>count) & 1) break; - count++; + if (!inst.op1.w) { + SETFLAGBIT(ZF,true); + } else { + Bitu count=0; + while (count<16) { + if ((inst.op1.w>>count) & 1) break; + count++; + } + inst.op1.d=count; + SETFLAGBIT(ZF,false); } - inst.op1.d=count; - SETFLAGBIT(ZF,false); } break; case O_BSFd: { FILLFLAGS; - if (!inst.op1.d) SETFLAGBIT(ZF,true); - Bitu count=0; - while (count<32) { - if ((inst.op1.d>>count) & 1) break; - count++; + if (!inst.op1.d) { + SETFLAGBIT(ZF,true); + } else { + Bitu count=0; + while (count<32) { + if ((inst.op1.d>>count) & 1) break; + count++; + } + inst.op1.d=count; + SETFLAGBIT(ZF,false); } - inst.op1.d=count; - SETFLAGBIT(ZF,false); } break; case O_BSRw: { FILLFLAGS; - if (!inst.op1.w) SETFLAGBIT(ZF,true); - Bits count=15; - while (count>0) { - if ((inst.op1.w>>count) & 1) break; - count--; + if (!inst.op1.w) { + SETFLAGBIT(ZF,true); + } else { + Bits count=15; + while (count>0) { + if ((inst.op1.w>>count) & 1) break; + count--; + } + inst.op1.d=count; + SETFLAGBIT(ZF,false); } - inst.op1.d=count; - SETFLAGBIT(ZF,false); } break; case O_BSRd: { FILLFLAGS; - if (!inst.op1.d) SETFLAGBIT(ZF,true); - Bits count=31; - while (count>0) { - if ((inst.op1.d>>count) & 1) break; - count--; + if (!inst.op1.d) { + SETFLAGBIT(ZF,true); + } else { + Bits count=31; + while (count>0) { + if ((inst.op1.d>>count) & 1) break; + count--; + } + inst.op1.d=count; + SETFLAGBIT(ZF,false); } - inst.op1.d=count; - SETFLAGBIT(ZF,false); } break; case O_BTw: From cb91fc53effeaa05e65c00c572a45988d5df9973 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 1 Aug 2003 10:05:11 +0000 Subject: [PATCH 1097/4131] remove it Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1177 --- src/dos/cdrom_ioctl.cpp | 531 ---------------------------------------- 1 file changed, 531 deletions(-) delete mode 100644 src/dos/cdrom_ioctl.cpp diff --git a/src/dos/cdrom_ioctl.cpp b/src/dos/cdrom_ioctl.cpp deleted file mode 100644 index 51356562..00000000 --- a/src/dos/cdrom_ioctl.cpp +++ /dev/null @@ -1,531 +0,0 @@ -/* - * Copyright (C) 2002-2003 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -// IOCTL support for linux CDROM - -#if __linux__ - -#include -#include -#include -#include -#include -#include - -#include "cdrom.h" - -CDROM_Interface_Linux::CDROM_Interface_Linux(void) -{ - pathname[0] = 0; - memset(&oldLeadOut,0,sizeof(oldLeadOut)); -}; - -CDROM_Interface_Linux::~CDROM_Interface_Linux(void) -{ - // Stop Audio, if neccessary - StopAudio(); -}; - -bool CDROM_Interface_Linux::SetDevice(char* path) -{ - strcpy(pathname,path); - if (Open()) { - Close(); - return true; - }; - return false; -}; - -bool CDROM_Interface_Linux::Open(void) -{ - dhandle = open(pathname,O_RDONLY|O_NONBLOCK); - return (dhandle>=0); -}; - -void CDROM_Interface_Linux::Close(void) -{ - close (dhandle); -}; - -bool CDROM_Interface_Linux::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut) -{ - struct cdrom_tochdr header; - - Open(); - /* read the header information */ - if (ioctl(dhandle, CDROMREADTOCHDR, &header) != 0) { - Close(); - return false; - } - - /* store the resulting information */ - stTrack = header.cdth_trk0; /* you can assume this to be zero */ - endTrack = header.cdth_trk1; - - /* Get the leadout track */ - struct cdrom_tocentry entry; - - entry.cdte_track = CDROM_LEADOUT; /* find the address of the leadout track */ - entry.cdte_format = CDROM_MSF; /* choose MSF addressing */ - - if (ioctl(dhandle, CDROMREADTOCENTRY,&entry)!=0) { - Close(); - return false; - } - - leadOut.min = entry.cdte_addr.msf.minute; - leadOut.sec = entry.cdte_addr.msf.second; - leadOut.fr = entry.cdte_addr.msf.frame; - - Close(); - return false; -}; - -bool CDROM_Interface_Linux::GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr) -{ - Open(); - struct cdrom_tocentry entry; - - entry.cdte_track = track; /* find the address of the first track */ - entry.cdte_format = CDROM_MSF; /* choose MSF addressing */ - - if (ioctl(dhandle, CDROMREADTOCENTRY,&entry)!=0) { - Close(); - return false; - } - - /* attribtute */ - attr = (entry.cdte_adr<<4) | entry.cdte_ctrl; - /* store the address information */ - start.min = entry.cdte_addr.msf.minute; - start.sec = entry.cdte_addr.msf.second; - start.fr = entry.cdte_addr.msf.frame; - - Close(); - return true; -}; - -bool CDROM_Interface_Linux::PlayAudioSector(unsigned long start,unsigned long len) -{ - struct cdrom_blk addr; - addr.from = start; - addr.len = len; - Open(); - bool res = (ioctl(dhandle, CDROMPLAYBLK, &addr)==0); - Close(); - return res; -} - -bool CDROM_Interface_Linux::StopAudio(void) -{ - Open(); - bool res = (ioctl(dhandle,CDROMSTOP,0)==0); - Close(); - return res; -}; - -bool CDROM_Interface_Linux::PauseAudio(bool resume) -{ - Open(); - bool res = false; - if (resume) res = (ioctl(dhandle, CDROMRESUME,0)==0); - else res = (ioctl(dhandle, CDROMPAUSE,0)==0); - Close(); - return res; -}; - -bool CDROM_Interface_Linux::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) -{ - struct cdrom_subchnl sub; - - Open(); - sub.cdsc_format = CDROM_MSF; - if (ioctl(dhandle, CDROMSUBCHNL, &sub)!=0) { - Close(); - return false; - } - - /* attribute */ - attr = (sub.cdsc_adr<<4) | sub.cdsc_ctrl; - track = sub.cdsc_trk; - index = sub.cdsc_ind; - relPos.fr = sub.cdsc_absaddr.msf.frame; - relPos.sec = sub.cdsc_absaddr.msf.second; - relPos.min = sub.cdsc_absaddr.msf.minute; - absPos.fr = sub.cdsc_reladdr.msf.frame; - absPos.sec = sub.cdsc_reladdr.msf.second; - absPos.min = sub.cdsc_reladdr.msf.minute; - Close(); - return true; -}; - -bool CDROM_Interface_Linux::GetUPC(unsigned char& attr, char* upcdata) -{ - Open(); - bool res = (ioctl(dhandle, CDROM_GET_UPC, (void*)upcdata)==0); - Close(); - return res; -}; - -bool CDROM_Interface_Linux::GetAudioStatus(bool& playing, bool& pause) -{ - Open(); - struct cdrom_subchnl sub; - - sub.cdsc_format = CDROM_MSF; - if (ioctl(dhandle, CDROMSUBCHNL, &sub)!=0) { - Close(); - return false; - }; - - playing = (sub.cdsc_audiostatus==CDROM_AUDIO_PLAY); - pause = (sub.cdsc_audiostatus==CDROM_AUDIO_PAUSED); - - Close(); - return true; -}; - -bool CDROM_Interface_Linux::LoadUnloadMedia(bool unload) -{ - Open(); - bool res = (ioctl(dhandle, CDROMEJECT,0)==0); - Close(); - return res; -}; - -bool CDROM_Interface_Linux::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) -{ - // Seems not possible to get this values using ioctl... - int track1,track2; - TMSF leadOut; - // If we can read, there's a media - mediaPresent = GetAudioTracks(track1, track2, leadOut); - trayOpen = !mediaPresent; - mediaChanged = (oldLeadOut.min!=leadOut.min) || (oldLeadOut.sec!=leadOut.sec) || (oldLeadOut.fr!=leadOut.fr); - // Save old values - oldLeadOut.min = leadOut.min; - oldLeadOut.sec = leadOut.sec; - oldLeadOut.fr = leadOut.fr; - // always success - return true; -}; - -bool CDROM_Interface_Linux::ReadSectors(void* buffer, bool raw, unsigned long sector, unsigned long num) -{ - // FIXME: ToDo - return false; -}; - -int CDROM_GetMountType(char* path) -// 0 - physical CDROM -// 1 - Iso file -// 2 - subdirectory -{ - // 1. Smells like a real cdrom - // FIXME: Better check if drive is a cdrom - if ((strchr(path,'/')==strrchr(path,'/')) && strstr(path,"cdrom")) return 0; - // 2. Iso file ? - // FIXME : How to detect them ? - // return 1; - // 3. bah, ordinary directory - return 2; -}; - -#elif defined (WIN32) - - -// ***************************************************************** -// Windows IOCTL functions (not suitable for 95/98/Me) -// ***************************************************************** - -#include "cdrom.h" -#include // Ioctl stuff -#include "ntddcdrm.h" // Ioctl stuff - -CDROM_Interface_Ioctl::CDROM_Interface_Ioctl() -{ - pathname[0] = 0; - hIOCTL = INVALID_HANDLE_VALUE; - memset(&oldLeadOut,0,sizeof(oldLeadOut)); -}; - -CDROM_Interface_Ioctl::~CDROM_Interface_Ioctl() -{ - StopAudio(); -}; - -bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc) -{ - // FIXME : To Do - return true; -} - -bool CDROM_Interface_Ioctl::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut) -{ - Open(); - CDROM_TOC toc; - DWORD byteCount; - BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, - &toc, sizeof(toc), &byteCount,NULL); - Close(); - if (!bStat) return false; - - stTrack = toc.FirstTrack; - endTrack = toc.LastTrack; - leadOut.min = toc.TrackData[endTrack].Address[1]; - leadOut.sec = toc.TrackData[endTrack].Address[2]; - leadOut.fr = toc.TrackData[endTrack].Address[3]; - return true; -}; - -bool CDROM_Interface_Ioctl::GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr) -{ - Open(); - CDROM_TOC toc; - DWORD byteCount; - BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, - &toc, sizeof(toc), &byteCount,NULL); - Close(); - if (!bStat) return false; - - attr = (toc.TrackData[track-1].Adr << 4) | toc.TrackData[track].Control; - start.min = toc.TrackData[track-1].Address[1]; - start.sec = toc.TrackData[track-1].Address[2]; - start.fr = toc.TrackData[track-1].Address[3]; - return true; -}; - -bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) -{ - Open(); - - CDROM_SUB_Q_DATA_FORMAT insub; - SUB_Q_CHANNEL_DATA sub; - DWORD byteCount; - - insub.Format = IOCTL_CDROM_CURRENT_POSITION; - - BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), - &sub, sizeof(sub), &byteCount,NULL); - Close(); - if (!bStat) return false; - - attr = (sub.CurrentPosition.ADR << 4) | sub.CurrentPosition.Control; - track = sub.CurrentPosition.TrackNumber; - index = sub.CurrentPosition.IndexNumber; - relPos.min = sub.CurrentPosition.TrackRelativeAddress[1]; - relPos.sec = sub.CurrentPosition.TrackRelativeAddress[2]; - relPos.fr = sub.CurrentPosition.TrackRelativeAddress[3]; - absPos.min = sub.CurrentPosition.AbsoluteAddress[1]; - absPos.sec = sub.CurrentPosition.AbsoluteAddress[2]; - absPos.fr = sub.CurrentPosition.AbsoluteAddress[3]; - - return true; -}; - -bool CDROM_Interface_Ioctl::GetAudioStatus(bool& playing, bool& pause) -{ - Open(); - - CDROM_SUB_Q_DATA_FORMAT insub; - SUB_Q_CHANNEL_DATA sub; - DWORD byteCount; - - insub.Format = IOCTL_CDROM_CURRENT_POSITION; - - BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), - &sub, sizeof(sub), &byteCount,NULL); - Close(); - if (!bStat) return false; - - playing = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_IN_PROGRESS); - pause = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_PAUSED); - - return true; -}; - -bool CDROM_Interface_Ioctl::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) -{ - // Seems not possible to get this values using ioctl... - int track1,track2; - TMSF leadOut; - // If we can read, there's a media - mediaPresent = GetAudioTracks(track1, track2, leadOut), - trayOpen = !mediaPresent; - mediaChanged = (oldLeadOut.min!=leadOut.min) || (oldLeadOut.sec!=leadOut.sec) || (oldLeadOut.fr!=leadOut.fr); - // Save old values - oldLeadOut.min = leadOut.min; - oldLeadOut.sec = leadOut.sec; - oldLeadOut.fr = leadOut.fr; - // always success - return true; -}; - -bool CDROM_Interface_Ioctl::PlayAudioSector (unsigned long start,unsigned long len) -{ - Open(); - CDROM_PLAY_AUDIO_MSF audio; - DWORD byteCount; - // Start - unsigned long addr = start + 150; - audio.StartingF = (UCHAR)(addr%75); addr/=75; - audio.StartingS = (UCHAR)(addr%60); - audio.StartingM = (UCHAR)(addr/60); - // End - addr = start + len + 150; - audio.EndingF = (UCHAR)(addr%75); addr/=75; - audio.EndingS = (UCHAR)(addr%60); - audio.EndingM = (UCHAR)(addr/60); - - BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PLAY_AUDIO_MSF, &audio, sizeof(audio), - NULL, 0, &byteCount,NULL); - Close(); - return bStat>0; -}; - -bool CDROM_Interface_Ioctl::PauseAudio(bool resume) -{ - Open(); - BOOL bStat; - DWORD byteCount; - if (resume) bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RESUME_AUDIO, NULL, 0, - NULL, 0, &byteCount,NULL); - else bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PAUSE_AUDIO, NULL, 0, - NULL, 0, &byteCount,NULL); - Close(); - return bStat>0; -}; - -bool CDROM_Interface_Ioctl::StopAudio(void) -{ - Open(); - BOOL bStat; - DWORD byteCount; - bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_STOP_AUDIO, NULL, 0, - NULL, 0, &byteCount,NULL); - Close(); - return bStat>0; -}; - -bool CDROM_Interface_Ioctl::LoadUnloadMedia(bool unload) -{ - Open(); - BOOL bStat; - DWORD byteCount; - if (unload) bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, - NULL, 0, &byteCount,NULL); - else bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, - NULL, 0, &byteCount,NULL); - Close(); - return bStat>0; -}; - -bool CDROM_Interface_Ioctl::ReadSectors(void* buffer, bool raw, unsigned long sector, unsigned long num) -{ - // TODO : How to copy cooked without current overhead ? - BOOL bStat; - DWORD byteCount; - RAW_READ_INFO in; - char* inPtr; - - in.DiskOffset.LowPart = sector; - in.DiskOffset.HighPart = 0; - in.SectorCount = num; - in.TrackMode = CDDA; - - if (!raw) inPtr = new char[num*RAW_SECTOR_SIZE]; - else inPtr = (char*)buffer; - - bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RAW_READ, &in, sizeof(in), - inPtr, num*RAW_SECTOR_SIZE, &byteCount,NULL); - - if (!raw) { - char* source = inPtr; - source+=16; // jump 16 bytes - char* outPtr = (char*)buffer; - for (unsigned long i=0; i0); -} - -bool CDROM_Interface_Ioctl::SetDevice(char* path) -{ - if (GetDriveType(path)==DRIVE_CDROM) { - char letter [3] = { 0, ':', 0 }; - letter[0] = path[0]; - strcpy(pathname,"\\\\.\\"); - strcat(pathname,letter); - if (Open()) { - Close(); - return true; - }; - } - return false; -} - -bool CDROM_Interface_Ioctl::Open(void) -{ - hIOCTL = CreateFile(pathname, // drive to open - GENERIC_READ, // read access - FILE_SHARE_READ | // share mode - FILE_SHARE_WRITE, - NULL, // default security attributes - OPEN_EXISTING, // disposition - 0, // file attributes - NULL); // do not copy file attributes - return (hIOCTL!=INVALID_HANDLE_VALUE); -}; - -void CDROM_Interface_Ioctl::Close(void) -{ - CloseHandle(hIOCTL); -}; - -/* -int CDROM_GetMountType(char* path) -// 0 - physical CDROM -// 1 - Iso file -// 2 - subdirectory -{ - // 1. Smells like a real cdrom - if ((strlen(path)<=3) && (path[2]=='\\') && (strchr(path,'\\')==strrchr(path,'\\')) && (GetDriveType(path)==DRIVE_CDROM)) return 0; - // 2. Iso file ? - // FIXME : How to detect them ? - // return 1; - // 3. bah, ordinary directory - return 2; -}; -*/ -#else - -// Get Mounttype function for unsupported systems -// always return 0 - physical cdrom - -int CDROM_GetMountType(char* path) -// Always return 0; -{ - return 0; -}; - -#endif \ No newline at end of file From 2cacfbc98ee3c6350481853a09db22944d4a50d9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 1 Aug 2003 16:48:55 +0000 Subject: [PATCH 1098/4131] Added patch 776979 from Florian Albrecht (in a modified format as it was made against 0.58) Fixed Bugs related to .. and ... Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1178 --- src/dos/dos_files.cpp | 29 +++++++++++++++++++-- src/shell/shell_cmds.cpp | 7 ++--- src/shell/shell_misc.cpp | 56 +++++++++++++++++++--------------------- 3 files changed, 57 insertions(+), 35 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 95f7ae07..8c725df9 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: dos_files.cpp,v 1.42 2003-08-01 16:48:55 qbix79 Exp $ */ + #include #include #include @@ -110,7 +112,28 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { w=0;r++; continue; } - if (strcmp(tempdir,"..")==0) { + + Bit32u iDown, cDots; + bool dots = true; + Bit32u templen =strlen(tempdir); + for(iDown=0;(iDown < templen) && dots;iDown++) + if(tempdir[iDown] != '.') + dots = false; + + // only dots? + cDots = templen - 1; + if(dots && (cDots > 0)) + { + for(iDown=strlen(fullname)-1;iDown>=0;iDown--) + { + if(fullname[iDown]=='\\' || iDown==0) + { + lastdir = iDown; + cDots--; + if(cDots==0) + break; + } + } fullname[lastdir]=0; Bit32u t=0;lastdir=0; while (fullname[t]!=0) { @@ -121,8 +144,10 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { w=0;r++; continue; } + + lastdir=strlen(fullname); - //TODO Maybe another check for correct type because of .... stuff + if (lastdir!=0) strcat(fullname,"\\"); char * ext=strchr(tempdir,'.'); if (ext) { diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 601ae88d..35662011 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,6 +15,9 @@ * 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_cmds.cpp,v 1.24 2003-08-01 16:48:25 qbix79 Exp $ */ + #include #include "shell_inc.h" @@ -59,8 +62,6 @@ void DOS_Shell::DoCommand(char * line) { while (*line) { if (*line==32) break; if (*line=='/') break; - if ((*line=='.') && (*(line+1)=='.')) break; -// if ((*line=='.') && (*(line+1)==0)) break; *cmd_write++=*line++; } *cmd_write=0; diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 249ccde5..bbeb9ec8 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: shell_misc.cpp,v 1.21 2003-08-01 16:48:25 qbix79 Exp $ */ + #include #include #include "shell_inc.h" @@ -352,22 +354,18 @@ static char which_ret[DOS_PATHLENGTH]; char * DOS_Shell::Which(char * name) { /* Parse through the Path to find the correct entry */ /* Check if name is already ok but just misses an extension */ - char * ext=strrchr(name,'.'); - if (ext) if (strlen(ext)>4) ext=0; - if (ext) { - if (DOS_FileExists(name)) return name; - } else { - /* try to find .com .exe .bat */ - strcpy(which_ret,name); - strcat(which_ret,com_ext); - if (DOS_FileExists(which_ret)) return which_ret; - strcpy(which_ret,name); - strcat(which_ret,exe_ext); - if (DOS_FileExists(which_ret)) return which_ret; - strcpy(which_ret,name); - strcat(which_ret,bat_ext); - if (DOS_FileExists(which_ret)) return which_ret; - } + if (DOS_FileExists(name)) return name; + /* try to find .com .exe .bat */ + strcpy(which_ret,name); + strcat(which_ret,com_ext); + if (DOS_FileExists(which_ret)) return which_ret; + strcpy(which_ret,name); + strcat(which_ret,exe_ext); + if (DOS_FileExists(which_ret)) return which_ret; + strcpy(which_ret,name); + strcat(which_ret,bat_ext); + if (DOS_FileExists(which_ret)) return which_ret; + /* No Path in filename look through path environment string */ static char path[DOS_PATHLENGTH];std::string temp; @@ -387,19 +385,17 @@ char * DOS_Shell::Which(char * name) { *path_write++=0; strcat(path,name); strcpy(which_ret,path); - if (ext) { - if (DOS_FileExists(which_ret)) return which_ret; - } else { - strcpy(which_ret,path); - strcat(which_ret,com_ext); - if (DOS_FileExists(which_ret)) return which_ret; - strcpy(which_ret,path); - strcat(which_ret,exe_ext); - if (DOS_FileExists(which_ret)) return which_ret; - strcpy(which_ret,path); - strcat(which_ret,bat_ext); - if (DOS_FileExists(which_ret)) return which_ret; - } + if (DOS_FileExists(which_ret)) return which_ret; + strcpy(which_ret,path); + strcat(which_ret,com_ext); + if (DOS_FileExists(which_ret)) return which_ret; + strcpy(which_ret,path); + strcat(which_ret,exe_ext); + if (DOS_FileExists(which_ret)) return which_ret; + strcpy(which_ret,path); + strcat(which_ret,bat_ext); + if (DOS_FileExists(which_ret)) return which_ret; + path_write=path; if (*pathenv) pathenv++; } From e5137b4d74bd11b819ecc1915117e546654259ab Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 6 Aug 2003 14:46:58 +0000 Subject: [PATCH 1099/4131] fixed bug in drive_cache finddirinfo. Thanks to helpfull person on irc. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1179 --- src/dos/drive_cache.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 16f4f9e0..3a978309 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,6 +17,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: drive_cache.cpp,v 1.22 2003-08-06 14:46:58 qbix79 Exp $ */ + #include "drives.h" #include "dos_inc.h" #include "dirent.h" @@ -435,7 +437,7 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* char dir [CROSS_LEN]; char work [CROSS_LEN]; - char* start = (char*)path; + const char* start = path; char* pos; CFileInfo* curDir = dirBase; Bit16u id; @@ -483,11 +485,8 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* if ((nextDir>=0) && curDir->fileList[nextDir]->isDir) { curDir = curDir->fileList[nextDir]; strcpy (curDir->orgname,dir); - strcpy (work,path); - // Cut Directory, if its only part of whole path - if (pos) work[(Bit32u)pos-(Bit32u)path] = 0; if (!IsCachedIn(curDir)) { - if (OpenDir(curDir,work,id)) { + if (OpenDir(curDir,expandedPath,id)) { char buffer[CROSS_LEN]; char * result; strcpy(buffer,dirPath); From 6fed40f0a8243f2a6bccd617f1c6ffd8aca5e573 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 11 Aug 2003 08:42:58 +0000 Subject: [PATCH 1100/4131] Remove the FILLFLAGS define and use a function call for it. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1180 --- src/cpu/core_full.cpp | 2 +- src/cpu/core_full/load.h | 2 +- src/cpu/core_full/op.h | 24 ++++++++++++------------ src/cpu/flags.cpp | 15 ++++++++++++--- src/cpu/lazyflags.h | 14 ++------------ 5 files changed, 28 insertions(+), 29 deletions(-) diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 053e339f..67999d92 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -66,7 +66,7 @@ static INLINE void DecodeModRM(void) { #define LEAVECORE \ SaveIP(); \ - FILLFLAGS; + FillFlags(); #define EXCEPTION(blah) \ { \ diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 780a50ed..e75cd13c 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -216,7 +216,7 @@ l_M_Ed: inst.op1.d=reg_32(inst.code.extra); break; case L_FLG: - FILLFLAGS; + FillFlags(); inst.op1.d = flags.word; break; case L_SEG: diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 99d90f3e..6eaae095 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -396,11 +396,11 @@ switch (inst.code.op) { CPU_LTR(inst.op1.d); goto nextopcode; /* Else value will saved */ case 0x04: /* VERR */ - FILLFLAGS; + FillFlags(); CPU_VERR(inst.op1.d); goto nextopcode; /* Else value will saved */ case 0x05: /* VERW */ - FILLFLAGS; + FillFlags(); CPU_VERW(inst.op1.d); goto nextopcode; /* Else value will saved */ @@ -441,7 +441,7 @@ switch (inst.code.op) { break; } case 6: /* LMSW */ - FILLFLAGS; + FillFlags(); CPU_LMSW(inst.op1.w); goto nextopcode; default: @@ -456,21 +456,21 @@ switch (inst.code.op) { break; case O_LAR: { - FILLFLAGS; + FillFlags(); Bitu ar;CPU_LAR(inst.op1.d,ar); inst.op1.d=ar; } break; case O_LSL: { - FILLFLAGS; + FillFlags(); Bitu limit;CPU_LSL(inst.op1.d,limit); inst.op1.d=limit; } break; case O_ARPL: { - FILLFLAGS; + FillFlags(); Bitu new_sel=inst.op1.d; CPU_ARPL(new_sel,inst.op2.d); inst.op1.d=new_sel; @@ -478,7 +478,7 @@ switch (inst.code.op) { break; case O_BSFw: { - FILLFLAGS; + FillFlags(); if (!inst.op1.w) { SETFLAGBIT(ZF,true); } else { @@ -494,7 +494,7 @@ switch (inst.code.op) { break; case O_BSFd: { - FILLFLAGS; + FillFlags(); if (!inst.op1.d) { SETFLAGBIT(ZF,true); } else { @@ -510,7 +510,7 @@ switch (inst.code.op) { break; case O_BSRw: { - FILLFLAGS; + FillFlags(); if (!inst.op1.w) { SETFLAGBIT(ZF,true); } else { @@ -526,7 +526,7 @@ switch (inst.code.op) { break; case O_BSRd: { - FILLFLAGS; + FillFlags(); if (!inst.op1.d) { SETFLAGBIT(ZF,true); } else { @@ -547,7 +547,7 @@ switch (inst.code.op) { { Bitu val;PhysPt read; Bitu mask=1 << (inst.op1.d & 15); - FILLFLAGS; + FillFlags(); if (inst.rm<0xc0) { read=inst.rm_eaa+2*(inst.op1.d / 16); val=mem_readw(read); @@ -573,7 +573,7 @@ switch (inst.code.op) { { Bitu val;PhysPt read; Bitu mask=1 << (inst.op1.d & 31); - FILLFLAGS; + FillFlags(); if (inst.rm<0xc0) { read=inst.rm_eaa+4*(inst.op1.d / 32); val=mem_readd(read); diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index db5b1e89..dc09460d 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -575,9 +575,18 @@ Bitu get_PF(void) { } -#define SET_FLAG(TYPE,TEST) if ( TEST ) new_flags|=TYPE +void FillFlags(void) { + flags.word=(flags.word & ~FLAG_MASK); + if (get_CF()) flags.word|=FLAG_CF; + if (get_PF()) flags.word|=FLAG_PF; + if (get_AF()) flags.word|=FLAG_AF; + if (get_ZF()) flags.word|=FLAG_ZF; + if (get_SF()) flags.word|=FLAG_SF; + if (get_OF()) flags.word|=FLAG_OF; + flags.type=t_UNKNOWN; +} + #if 0 -#endif Bitu get_Flags(void) { Bitu new_flags=0; @@ -808,4 +817,4 @@ Bitu get_Flags(void) { return 0; } -Bit8u * blah=(Bit8u *)&get_Flags; +#endif diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index a10e6207..2ab6ca18 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -24,6 +24,8 @@ Bitu get_SF(void); Bitu get_OF(void); Bitu get_PF(void); +void FillFlags(void); + #define SETFLAGSb(FLAGB) \ { \ SETFLAGBIT(OF,get_OF()); \ @@ -43,18 +45,6 @@ Bitu get_PF(void); CPU_SetFlags(FLAGD); \ } -#define FILLFLAGS \ -{ \ - flags.word=(flags.word & ~FLAG_MASK) | \ - (get_CF() ? FLAG_CF : 0 ) | \ - (get_PF() ? FLAG_PF : 0 ) | \ - (get_AF() ? FLAG_AF : 0 ) | \ - (get_ZF() ? FLAG_ZF : 0 ) | \ - (get_SF() ? FLAG_SF : 0 ) | \ - (get_OF() ? FLAG_OF : 0 ); \ - flags.type=t_UNKNOWN; \ -} - #define LoadCF SETFLAGBIT(CF,get_CF()); #define LoadZF SETFLAGBIT(ZF,get_ZF()); #define LoadSF SETFLAGBIT(SF,get_SF()); From db97e36e5858887cc069165106004565732f4585 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 11 Aug 2003 11:50:30 +0000 Subject: [PATCH 1101/4131] Added reference counting for dos_files Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1181 --- include/dos_system.h | 5 ++++- src/dos/dos_files.cpp | 12 +++++++++--- src/dos/drive_local.cpp | 8 ++++++-- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 41624704..68380b59 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -51,7 +51,7 @@ class DOS_DTA; class DOS_File { public: - DOS_File():flags(0) { name=0; }; + DOS_File():flags(0) { name=0; refCtr = 0; }; virtual ~DOS_File(){}; virtual bool Read(Bit8u * data,Bit16u * size)=0; virtual bool Write(Bit8u * data,Bit16u * size)=0; @@ -62,12 +62,15 @@ public: virtual char* GetName(void) { return name; }; virtual bool IsOpen() { return open; }; virtual bool IsName(const char* _name) { if (!name) return false; return strcmp(name,_name)==0; }; + virtual void AddRef() { refCtr++; }; + virtual Bits RemoveRef() { return --refCtr; }; Bit8u type; Bit32u flags; Bit16u time; Bit16u date; Bit16u attr; Bit32u size; + Bits refCtr; bool open; char* name; /* Some Device Specific Stuff */ diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 8c725df9..086a1f88 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.42 2003-08-01 16:48:55 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.43 2003-08-11 11:49:58 finsterr Exp $ */ #include #include @@ -315,8 +315,10 @@ bool DOS_CloseFile(Bit16u entry) { { //if close succesfull => delete file/update psp DOS_PSP psp(dos.psp); psp.SetFileHandle(entry,0xff); - delete Files[handle]; - Files[handle]=0; + if (Files[handle]->RemoveRef()<=0) { + delete Files[handle]; + Files[handle]=0; + } } return true; } @@ -345,6 +347,7 @@ bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { } bool foundit=Drives[drive]->FileCreate(&Files[handle],fullname,attributes); if (foundit) { + Files[handle]->AddRef(); psp.SetFileHandle(*entry,handle); return true; } else { @@ -387,6 +390,7 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { bool exists=false; if (!device) exists=Drives[drive]->FileOpen(&Files[handle],fullname,flags); if (exists || device ) { + Files[handle]->AddRef(); psp.SetFileHandle(*entry,handle); return true; } else { @@ -476,6 +480,7 @@ bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); return false; } + Files[handle]->AddRef(); psp.SetFileHandle(*newentry,handle); return true; }; @@ -500,6 +505,7 @@ bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry) { return false; }; DOS_PSP psp(dos.psp); + Files[orig]->AddRef(); psp.SetFileHandle(newentry,(Bit8u)entry); return true; }; diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 991a9dbc..8c0c119e 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -372,8 +372,12 @@ bool localFile::Seek(Bit32u * pos,Bit32u type) { bool localFile::Close() { - open=false; - fclose(fhandle); + // only close if one reference left + if (refCtr==1) { + fclose(fhandle); + fhandle = 0; + open = false; + }; return true; } From 856e7b3fa931b8cd5728936ff72200de5026b55c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 11 Aug 2003 15:49:14 +0000 Subject: [PATCH 1102/4131] bug with directly changing the flags.word Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1182 --- src/cpu/flags.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index dc09460d..4f3e07cd 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -576,13 +576,14 @@ Bitu get_PF(void) { void FillFlags(void) { - flags.word=(flags.word & ~FLAG_MASK); - if (get_CF()) flags.word|=FLAG_CF; - if (get_PF()) flags.word|=FLAG_PF; - if (get_AF()) flags.word|=FLAG_AF; - if (get_ZF()) flags.word|=FLAG_ZF; - if (get_SF()) flags.word|=FLAG_SF; - if (get_OF()) flags.word|=FLAG_OF; + Bitu new_word=(flags.word & ~FLAG_MASK); + if (get_CF()) new_word|=FLAG_CF; + if (get_PF()) new_word|=FLAG_PF; + if (get_AF()) new_word|=FLAG_AF; + if (get_ZF()) new_word|=FLAG_ZF; + if (get_SF()) new_word|=FLAG_SF; + if (get_OF()) new_word|=FLAG_OF; + flags.word=new_word; flags.type=t_UNKNOWN; } From 8b48f20dbdaa61557ccd6ecf1a2545b4ed0cdb91 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 11 Aug 2003 15:50:52 +0000 Subject: [PATCH 1103/4131] FILLFLAGS -> FillFlags Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1183 --- src/cpu/core_16/main.h | 4 ++-- src/cpu/core_16/prefix_66.h | 2 +- src/cpu/core_16/support.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 2ccd460d..1bda6241 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -577,7 +577,7 @@ restart: case 0x9b: /* WAIT */ break; /* No waiting here */ case 0x9c: /* PUSHF */ - FILLFLAGS; + FillFlags(); Push_16(flags.word); break; case 0x9d: /* POPF */ @@ -592,7 +592,7 @@ restart: break; case 0x9f: /* LAHF */ { - FILLFLAGS; + FillFlags(); reg_ah=(Bit8u)flags.word; break; } diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index 6173b87e..47ee3d66 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -303,7 +303,7 @@ switch(Fetchb()) { else reg_edx=0; break; case 0x9c: /* PUSHFD */ - FILLFLAGS; + FillFlags(); Push_32(flags.word); break; case 0x9d: /* POPFD */ diff --git a/src/cpu/core_16/support.h b/src/cpu/core_16/support.h index 02ed3a44..8770a7de 100644 --- a/src/cpu/core_16/support.h +++ b/src/cpu/core_16/support.h @@ -25,7 +25,7 @@ #define LEAVECORE \ SAVEIP; \ - FILLFLAGS; + FillFlags(); static INLINE void ADDIP(Bit16u add) { core_16.ip_lookup=SegBase(cs)+((Bit16u)(((Bit16u)(core_16.ip_lookup-SegBase(cs)))+(Bit16u)add)); From d9c77e001c82aef4fbe218704f0bc19e5ef9c903 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 13 Aug 2003 14:46:15 +0000 Subject: [PATCH 1104/4131] fixed bug in drive_cache for win98 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1184 --- include/dos_system.h | 4 +++- src/dos/drive_cache.cpp | 12 +++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 68380b59..14593882 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: dos_system.h,v 1.14 2003-08-13 14:46:15 qbix79 Exp $ */ + #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ @@ -140,7 +142,7 @@ private: bool IsCachedIn (CFileInfo* dir); CFileInfo* FindDirInfo (const char* path, char* expandedPath); bool RemoveSpaces (char* str); - bool OpenDir (CFileInfo* dir, char* path, Bit16u& id); + bool OpenDir (CFileInfo* dir, const char* path, Bit16u& id); void CreateEntry (CFileInfo* dir, const char* name); Bit16u GetFreeID (CFileInfo* dir); void Clear (void); diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 3a978309..0ff1ccd1 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.22 2003-08-06 14:46:58 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.23 2003-08-13 14:45:31 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -521,21 +521,23 @@ bool DOS_Drive_Cache::OpenDir(const char* path, Bit16u& id) return false; }; -bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, char* expand, Bit16u& id) +bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, const char* expand, Bit16u& id) { id = GetFreeID(dir); dirSearch[id] = dir; + char expandcopy [CROSS_LEN]; + strcpy(expandcopy,expand); // Add "/" char end[2]={CROSS_FILESPLIT,0}; - if (expand[strlen(expand)-1]!=CROSS_FILESPLIT) strcat(expand,end); + if (expandcopy[strlen(expandcopy)-1]!=CROSS_FILESPLIT) strcat(expandcopy,end); // open dir if (dirSearch[id]) { // open dir - DIR* dirp = opendir(expand); + DIR* dirp = opendir(expandcopy); if (dirp) { // Reset it.. closedir(dirp); - strcpy(dirPath,expand); + strcpy(dirPath,expandcopy); free[id] = false; return true; } From 2a97e6e02291715b8bd22a55bd888917cc7c58c5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 13 Aug 2003 14:55:24 +0000 Subject: [PATCH 1105/4131] added windows.h header file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1185 --- src/dos/drive_cache.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 0ff1ccd1..a9119220 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,13 +17,18 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.23 2003-08-13 14:45:31 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.24 2003-08-13 14:55:24 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" #include "dirent.h" #include "support.h" +#if defined (WIN32) /* Win 32 */ +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from +#include +#endif + // STL stuff #include #include From 7e7b721588b948e2cfeee8a3d6df9de37f982d0d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 13 Aug 2003 19:14:58 +0000 Subject: [PATCH 1106/4131] Fix mov crx,reg drx,reg disassembly Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1186 --- src/debug/debug_disasm.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/debug/debug_disasm.cpp b/src/debug/debug_disasm.cpp index ca0467bc..11aa3266 100644 --- a/src/debug/debug_disasm.cpp +++ b/src/debug/debug_disasm.cpp @@ -830,12 +830,12 @@ static void percent(char type, char subtype) break; case 'C': /* reg(r/m) picks control reg */ - uprintf("C%d", REG(modrm())); + uprintf("CR%d", REG(modrm())); must_do_size = 0; break; case 'D': /* reg(r/m) picks debug reg */ - uprintf("D%d", REG(modrm())); + uprintf("DR%d", REG(modrm())); must_do_size = 0; break; @@ -911,7 +911,7 @@ static void percent(char type, char subtype) break; case 'R': /* mod(r/m) picks register */ - reg_name(REG(modrm()), subtype); /* rh */ + reg_name(RM(modrm()), subtype); /* rh */ must_do_size = 0; break; From 7fe21bc48234ef930d52ba98cc2222cae3feb985 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 17 Aug 2003 13:08:05 +0000 Subject: [PATCH 1107/4131] Added generation of cpu_log at E_Exit if Heavy_debugging is enabled Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1187 --- src/misc/support.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 2bc35acc..31ef5c87 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: support.cpp,v 1.17 2003-08-17 13:08:05 qbix79 Exp $ */ #include #include @@ -25,6 +26,7 @@ #include #include #include "dosbox.h" +#include "debug.h" #include "support.h" #include "video.h" @@ -157,6 +159,9 @@ char * StripWord(char * cmd) { static char buf[1024]; //greater scope as else it doesn't always gets thrown right (linux/gcc2.95) void E_Exit(char * format,...) { +#if C_HEAVY_DEBUG + DEBUG_HeavyWriteLogInstruction(); +#endif if(errorlevel>=1) { va_list msg; va_start(msg,format); From db9cee0e064629ab54ac13b1c17675559203972e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 17 Aug 2003 13:15:08 +0000 Subject: [PATCH 1108/4131] explicit cast of int parameters to Real64 for VC7 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1188 --- src/fpu/fpu_instructions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 06b3ded4..9ff1e54c 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -303,7 +303,7 @@ static void FPU_F2XM1(void){ } static void FPU_FYL2X(void){ - fpu.regs[ST(1)].d*=log(fpu.regs[TOP].d)/log(2); + fpu.regs[ST(1)].d*=log(fpu.regs[TOP].d)/log(static_cast(2.0)); FPU_FPOP(); return; } From cf05aa87a9d5cc712bb908598f5969327814eead Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 19 Aug 2003 17:59:25 +0000 Subject: [PATCH 1109/4131] allowed things like /w/p in commandscanbool Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1189 --- src/misc/support.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 31ef5c87..2d087870 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.17 2003-08-17 13:08:05 qbix79 Exp $ */ +/* $Id: support.cpp,v 1.18 2003-08-19 17:59:25 qbix79 Exp $ */ #include #include @@ -90,7 +90,7 @@ bool ScanCMDBool(char * cmd,char * check) { while ((scan=strchr(scan,'/'))) { /* found a / now see behind it */ scan++; - if (strncasecmp(scan,check,c_len)==0 && (scan[c_len]==' ' || scan[c_len]==0)) { + if (strncasecmp(scan,check,c_len)==0 && (scan[c_len]==' ' || scan[c_len]=='/' || scan[c_len]==0)) { /* Found a math now remove it from the string */ memmove(scan-1,scan+c_len,strlen(scan+c_len)+1); trim(scan-1); From 974254cb8a6d1c0e17ce2c3904201d07a8c75540 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 19 Aug 2003 18:01:57 +0000 Subject: [PATCH 1110/4131] allowed stuff like cd.. cd\ and del. Fixed execution of non-executables. removed ECHODOT. Fixed crashes when tabcompletion was used on an empty directory. Fixed copy when the files were in the root directory. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1190 --- src/shell/shell_cmds.cpp | 82 ++++++++++++++++++++++++++-------------- src/shell/shell_inc.h | 32 +++++++++++++++- src/shell/shell_misc.cpp | 31 ++++++++++----- 3 files changed, 107 insertions(+), 38 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 35662011..89126618 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.24 2003-08-01 16:48:25 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.25 2003-08-19 18:01:57 qbix79 Exp $ */ #include @@ -24,8 +24,6 @@ #include "callback.h" #include "regs.h" - - static SHELL_Cmd cmd_list[]={ { "CHDIR", 0, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"}, { "CD", 1, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"}, @@ -36,7 +34,6 @@ static SHELL_Cmd cmd_list[]={ { "DELETE", 0, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, { "ERASE", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, { "ECHO", 0, &DOS_Shell::CMD_ECHO, "SHELL_CMD_ECHO_HELP"}, -{ "ECHO.", 1, &DOS_Shell::CMD_EHCODOT, "SHELL_CMD_ECHO_HELP"}, { "EXIT", 0, &DOS_Shell::CMD_EXIT, "SHELL_CMD_EXIT_HELP"}, { "HELP", 0, &DOS_Shell::CMD_HELP, "SHELL_CMD_HELP_HELP"}, { "MKDIR", 0, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP"}, @@ -62,11 +59,21 @@ void DOS_Shell::DoCommand(char * line) { while (*line) { if (*line==32) break; if (*line=='/') break; + if ((*line=='.') ||(*line =='\\')) { //allow stuff like cd.. and dir.exe cd\kees + *cmd_write=0; + Bit32u cmd_index=0; + while (cmd_list[cmd_index].name) { + if (strcasecmp(cmd_list[cmd_index].name,cmd)==0) { + (this->*(cmd_list[cmd_index].handler))(line); + return; + } + cmd_index++; + } + } *cmd_write++=*line++; } *cmd_write=0; if (strlen(cmd)==0) return; - line=trim(line); /* Check the internal list */ Bit32u cmd_index=0; while (cmd_list[cmd_index].name) { @@ -87,12 +94,16 @@ void DOS_Shell::CMD_CLS(char * args) { }; void DOS_Shell::CMD_DELETE(char * args) { + char * rem=ScanCMDRemain(args); if (rem) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); return; } char full[DOS_PATHLENGTH]; + char buffer[CROSS_LEN]; + args = ExpandDot(args,buffer); + StripSpaces(args); if (!DOS_Canonicalize(args,full)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH"));return; } //TODO Maybe support confirmation for *.* like dos does. bool res=DOS_FindFirst(args,0xff); @@ -125,42 +136,42 @@ void DOS_Shell::CMD_HELP(char * args){ } void DOS_Shell::CMD_RENAME(char * args){ - if(!*args) {SyntaxError();return;} - if((strchr(args,'*')!=NULL) || (strchr(args,'?')!=NULL) ) { WriteOut(MSG_Get("SHELL_CMD_NO_WILD"));return;} - char * arg2 =StripWord(args); - DOS_Rename(args,arg2); + StripSpaces(args); + if(!*args) {SyntaxError();return;} + if((strchr(args,'*')!=NULL) || (strchr(args,'?')!=NULL) ) { WriteOut(MSG_Get("SHELL_CMD_NO_WILD"));return;} + char * arg2 =StripWord(args); + DOS_Rename(args,arg2); } - - - - -void DOS_Shell::CMD_ECHO(char * args) { +void DOS_Shell::CMD_ECHO(char * args){ if (!*args) { if (echo) { WriteOut(MSG_Get("SHELL_CMD_ECHO_ON"));} else { WriteOut(MSG_Get("SHELL_CMD_ECHO_OFF"));} - return; + return; } - if (strcasecmp(args,"OFF")==0) { + char buffer[512]; + char* pbuffer = buffer; + strcpy(buffer,args); + StripSpaces(pbuffer); + if (strcasecmp(pbuffer,"OFF")==0) { echo=false; return; } - if (strcasecmp(args,"ON")==0) { + if (strcasecmp(pbuffer,"ON")==0) { echo=true; return; } + args++;//skip first character. either a slash or dot or space WriteOut("%s\n",args); }; -void DOS_Shell::CMD_EHCODOT(char* args) { - WriteOut("\n"); -} void DOS_Shell::CMD_EXIT(char * args) { exit=true; }; void DOS_Shell::CMD_CHDIR(char * args) { + StripSpaces(args); if (!*args) { Bit8u drive=DOS_GetDefaultDrive()+'A'; char dir[DOS_PATHLENGTH]; @@ -176,6 +187,7 @@ void DOS_Shell::CMD_CHDIR(char * args) { }; void DOS_Shell::CMD_MKDIR(char * args) { + StripSpaces(args); char * rem=ScanCMDRemain(args); if (rem) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); @@ -187,6 +199,7 @@ void DOS_Shell::CMD_MKDIR(char * args) { }; void DOS_Shell::CMD_RMDIR(char * args) { + StripSpaces(args); char * rem=ScanCMDRemain(args); if (rem) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); @@ -228,10 +241,15 @@ void DOS_Shell::CMD_DIR(char * args) { return; } Bit32u byte_count,file_count,dir_count; - Bit32u w_count=0; + Bitu w_count=0; + Bitu p_count=0; + Bitu w_size = optW?5:1; byte_count=file_count=dir_count=0; - + + char buffer[CROSS_LEN]; if (strlen(args)==0) args="*.*"; + args = ExpandDot(args,buffer); + StripSpaces(args); /* Make a full path in the args */ if (!DOS_Canonicalize(args,path)) { @@ -287,10 +305,16 @@ void DOS_Shell::CMD_DIR(char * args) { w_count++; } ret=DOS_FindNext(); + if(optP) { + if(!(++p_count%(22*w_size))) { + CMD_PAUSE(args); + } + } } if (optW) { if (w_count%5) WriteOut("\n"); } + /* Show the summary of results */ FormatNumber(byte_count,numformat); WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_USED"),file_count,numformat); @@ -307,7 +331,7 @@ void DOS_Shell::CMD_DIR(char * args) { } void DOS_Shell::CMD_COPY(char * args) { - + StripSpaces(args); DOS_DTA dta(dos.dta); Bit32u size;Bit16u date;Bit16u time;Bit8u attr; char name[DOS_NAMELENGTH_ASCII]; @@ -348,14 +372,14 @@ void DOS_Shell::CMD_COPY(char * args) { // add '\\' if target is a directoy if (pathTarget[strlen(pathTarget)-1]!='\\') { - if (DOS_FindFirst(pathTarget,0xffff)) { + if (DOS_FindFirst(pathTarget,0xffff & ~DOS_ATTR_VOLUME)) { dta.GetResult(name,size,date,time,attr); if (attr & DOS_ATTR_DIRECTORY) strcat(pathTarget,"\\"); } }; - bool ret=DOS_FindFirst(args,0xffff); + bool ret=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME); if (!ret) { WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); return; @@ -404,6 +428,7 @@ void DOS_Shell::CMD_COPY(char * args) { } void DOS_Shell::CMD_SET(char * args) { + StripSpaces(args); std::string line; if (!*args) { /* No command line show all environment lines */ @@ -427,8 +452,8 @@ void DOS_Shell::CMD_SET(char * args) { void DOS_Shell::CMD_IF(char * args) { + StripSpaces(args); bool has_not=false; - char * comp=strchr(args,'='); if (comp) { if (comp[1]!='=') {SyntaxError();return;} @@ -481,8 +506,9 @@ void DOS_Shell::CMD_IF(char * args) { } void DOS_Shell::CMD_GOTO(char * args) { + StripSpaces(args); if (!bf) return; - if (*args==':') args++; + if (*args &&(*args==':')) args++; if (!*args) { WriteOut(MSG_Get("SHELL_CMD_GOTO_MISSING_LABEL")); return; @@ -495,7 +521,7 @@ void DOS_Shell::CMD_GOTO(char * args) { void DOS_Shell::CMD_TYPE(char * args) { - + StripSpaces(args); if (!*args) { WriteOut(MSG_Get("SHELL_SYNTAXERROR")); return; diff --git a/src/shell/shell_inc.h b/src/shell/shell_inc.h index 725b9695..a09fd9fe 100644 --- a/src/shell/shell_inc.h +++ b/src/shell/shell_inc.h @@ -15,6 +15,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* $Id */ + #include #include #include "dosbox.h" @@ -92,7 +95,6 @@ public: void CMD_RENAME(char * args); void SyntaxError(void); void CMD_PAUSE(char * args); - void CMD_EHCODOT(char* args); /* The shell's variables */ Bit16u input_handle; BatchFile * bf; @@ -107,4 +109,32 @@ struct SHELL_Cmd { const char * help; /* String with command help */ }; +static inline void StripSpaces(char*&args) +{ + while(*args && (*args == ' ')) + args++; +} + + +static inline char* ExpandDot(char*args, char* buffer) +{ + if(*args=='.') + { + if(*(args+1)==0) + { + strcpy(buffer,"*.*"); + return buffer; + } + if( (*(args+1)!='.') && (*(args+1)!='\\') ) + { + buffer[0]='*'; + buffer[1]=0; + strcat(buffer,args); + return buffer; + } + } + else strcpy(buffer,args); + return buffer; +} + diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index bbeb9ec8..a5f0878a 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.21 2003-08-01 16:48:25 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.22 2003-08-19 18:01:57 qbix79 Exp $ */ #include #include @@ -219,7 +219,7 @@ void DOS_Shell::InputCommand(char * line) { it_completion = l_completion.begin(); } - if (it_completion->length()) { + if (l_completion.size() && it_completion->length()) { for (;str_index > completion_index; str_index--) { // removes all characters outc(8); outc(' '); outc(8); @@ -265,13 +265,20 @@ void DOS_Shell::InputCommand(char * line) { void DOS_Shell::Execute(char * name,char * args) { char * fullname; - char line[255]; - if(strlen(args)!=0){ - line[0]=' ';line[1]=0; - strcat(line,args); - }else{ - line[0]=0; - }; + char line[255]; + if(strlen(args)!= 0){ + if(*args != ' '){ //put a space in front + line[0]=' ';line[1]=0; + strcat(line,args); + } + else + { + strcpy(line,args); + } + }else{ + line[0]=0; + }; + /* check for a drive change */ if ((strcmp(name + 1, ":") == 0) && isalpha(*name)) { @@ -290,6 +297,12 @@ void DOS_Shell::Execute(char * name,char * args) { /* Run the .bat file */ bf=new BatchFile(this,fullname,line); } else { + if(strcasecmp(strrchr(fullname, '.'), ".com") !=0) { + if(strcasecmp(strrchr(fullname, '.'), ".exe") !=0){ + WriteOut(MSG_Get("SHELL_EXECUTE_ILLEGAL_COMMAND"),fullname); + return; + } + } /* Run the .exe or .com file from the shell */ /* Allocate some stack space for tables in physical memory */ reg_sp-=0x200; From f56a4d0de032f90a85077fc1be591b83c2eee7d6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 19 Aug 2003 20:05:47 +0000 Subject: [PATCH 1111/4131] added refcounting to create_childpsp. Xcom2 installer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1191 --- src/dos/dos_classes.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 31283fde..e61cdafa 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: dos_classes.cpp,v 1.30 2003-08-19 20:05:47 qbix79 Exp $ */ + #include #include #include "dosbox.h" @@ -171,7 +173,8 @@ void DOS_PSP::CopyFileTable(DOS_PSP* srcpsp,bool createchildpsp) { //copy obeying not inherit flag.(but dont duplicate them) bool allowCopy = (handle==0) || ((handle>0) && (FindEntryByHandle(handle)==0xff)); if((handleflags & DOS_NOT_INHERIT) && allowCopy) - { + { + Files[handle]->AddRef(); SetFileHandle(i,handle); } else From 9d063495e7681cff547cfc533b309a93633a14b0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 20 Aug 2003 12:21:42 +0000 Subject: [PATCH 1112/4131] fixed little bug in dir. (dir /a was broken) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1192 --- src/shell/shell_cmds.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 89126618..dae78761 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.25 2003-08-19 18:01:57 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.26 2003-08-20 12:21:42 qbix79 Exp $ */ #include @@ -100,6 +100,8 @@ void DOS_Shell::CMD_DELETE(char * args) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); return; } + /* If delete accept switches mind the space infront of them. See the dir /p code */ + char full[DOS_PATHLENGTH]; char buffer[CROSS_LEN]; args = ExpandDot(args,buffer); @@ -247,7 +249,8 @@ void DOS_Shell::CMD_DIR(char * args) { byte_count=file_count=dir_count=0; char buffer[CROSS_LEN]; - if (strlen(args)==0) args="*.*"; + if (strlen(args)==0) args="*.*"; //no arguments. + if ((strlen(args)==1) && (args[0]==' ')) args="*.*"; //stuff like dir /p args = ExpandDot(args,buffer); StripSpaces(args); From 8f655ccc0d5cda187826196a3046f4b7277c534c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 22 Aug 2003 08:09:39 +0000 Subject: [PATCH 1113/4131] Reset the CPU Window on mode set Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1193 --- src/ints/int10_modes.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index b716e043..0a990b1f 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -434,8 +434,11 @@ dac_text16: IO_Write(0x3df,0x80); //Enter 32k mode and banks on 0 break; } + /* Setup the CPU Window */ + IO_Write(0x3d4,0x6a); + IO_Write(0x3d5,0); + /* Setup some remaining S3 registers */ - IO_Write(0x3d4,0x31);IO_Write(0x3d5,0x9); //Enable banked memory and 256k+ access IO_Write(0x3d4,0x58);IO_Write(0x3d5,0x3); //Enable 8 mb of linear addressing IO_Write(0x3d4,0x38);IO_Write(0x3d5,0x48); //Register lock 1 From c2d6a1e2c4e05a49626bc6ae33c258416cf5de5a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 22 Aug 2003 08:09:59 +0000 Subject: [PATCH 1114/4131] Don't check valid window parameter in cpu window calls Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1194 --- src/ints/int10_vesa.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 91d7a1ea..2d452f0f 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -150,7 +150,8 @@ Bit8u VESA_GetSVGAMode(Bit16u & mode) { } Bit8u VESA_SetCPUWindow(Bit8u window,Bit16u address) { - if (!window && (address<32)) { +//TODO Check with univbe if it doesn't check for window param either + if ((address<32)) { IO_Write(0x3d4,0x6a); IO_Write(0x3d5,(Bit8u)address); return 0x0; @@ -158,11 +159,10 @@ Bit8u VESA_SetCPUWindow(Bit8u window,Bit16u address) { } Bit8u VESA_GetCPUWindow(Bit8u window,Bit16u & address) { - if (!window) { - IO_Write(0x3d4,0x6a); - address=IO_Read(0x3d5); - return 0x0; - } else return 0x1; +//TODO Check with univbe if it doesn't check for window param either + IO_Write(0x3d4,0x6a); + address=IO_Read(0x3d5); + return 0x0; } @@ -268,7 +268,8 @@ Bit8u VESA_GetDisplayStart(Bit16u & x,Bit16u & y) { static char oemstring[]="S3 Incorporated. Trio64"; static Bitu SetWindowPositionHandler(void) { - VESA_SetCPUWindow(reg_bl,reg_dx); + if (reg_bh) VESA_GetCPUWindow(reg_bl,reg_dx); + else VESA_SetCPUWindow(reg_bl,reg_dx); return 0; } From 07abb99dcef97b5f12b4b1f0545b73050889d438 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 22 Aug 2003 08:10:53 +0000 Subject: [PATCH 1115/4131] Unsigned/Signed comparison fix Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1195 --- src/ints/ems.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 81ce3b27..7cabca45 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -33,7 +33,7 @@ #define EMM_PAGEFRAME 0xE000 #define EMM_PAGEFRAME4K ((EMM_PAGEFRAME*16)/4096) #define EMM_MAX_HANDLES 50 /* 255 Max */ -#define EMM_PAGE_SIZE (16*1024) +#define EMM_PAGE_SIZE (16*1024U) #define EMM_MAX_PAGES (32 * 1024 / 16 ) #define EMM_MAX_PHYS 4 /* 4 16kb pages in pageframe */ @@ -356,7 +356,7 @@ static Bit8u MemoryRegion(void) { src_mem=region.src_page_seg*16+region.src_offset; } else { if (!ValidHandle(region.src_handle)) return EMM_INVALID_HANDLE; - if (emm_handles[region.src_handle].pages*EMM_PAGE_SIZE < (region.src_page_seg*EMM_PAGE_SIZE)+region.src_offset+region.bytes) return EMM_LOG_OUT_RANGE; + if ((emm_handles[region.src_handle].pages*EMM_PAGE_SIZE) < ((region.src_page_seg*EMM_PAGE_SIZE)+region.src_offset+region.bytes)) return EMM_LOG_OUT_RANGE; src_handle=emm_handles[region.src_handle].mem; Bitu pages=region.src_page_seg*4+(region.src_offset/MEM_PAGE_SIZE); for (;pages>0;pages--) src_handle=MEM_NextHandle(src_handle); From 2ae4a3e7d98707b125b1eeb549ea3db34a7c55cd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 22 Aug 2003 09:21:41 +0000 Subject: [PATCH 1116/4131] Change switches a bit so compiler can create jump tables Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1196 --- src/cpu/instructions.h | 102 ++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 0ea3f7a4..7f0d731b 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -725,32 +725,32 @@ #define GRP2B(blah) \ { \ - GetRM; \ + GetRM;Bitu which=(rm>>3)&7; \ if (rm >= 0xc0) { \ GetEArb; \ Bit8u val=blah & 0x1f; \ - switch (rm&0x38) { \ + switch (which) { \ 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; \ + case 0x01:RORB(*earb,val,LoadRb,SaveRb);break; \ + case 0x02:RCLB(*earb,val,LoadRb,SaveRb);break; \ + case 0x03:RCRB(*earb,val,LoadRb,SaveRb);break; \ + case 0x04:/* SHL and SAL are the same */ \ + case 0x06:SHLB(*earb,val,LoadRb,SaveRb);break; \ + case 0x05:SHRB(*earb,val,LoadRb,SaveRb);break; \ + case 0x07:SARB(*earb,val,LoadRb,SaveRb);break; \ } \ } else { \ GetEAa; \ Bit8u val=blah & 0x1f; \ - switch (rm & 0x38) { \ + switch (which) { \ 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; \ + case 0x01:RORB(eaa,val,LoadMb,SaveMb);break; \ + case 0x02:RCLB(eaa,val,LoadMb,SaveMb);break; \ + case 0x03:RCRB(eaa,val,LoadMb,SaveMb);break; \ + case 0x04:/* SHL and SAL are the same */ \ + case 0x06:SHLB(eaa,val,LoadMb,SaveMb);break; \ + case 0x05:SHRB(eaa,val,LoadMb,SaveMb);break; \ + case 0x07:SARB(eaa,val,LoadMb,SaveMb);break; \ } \ } \ } @@ -759,32 +759,32 @@ #define GRP2W(blah) \ { \ - GetRM; \ + GetRM;Bitu which=(rm>>3)&7; \ if (rm >= 0xc0) { \ GetEArw; \ Bit8u val=blah & 0x1f; \ - switch (rm&0x38) { \ + switch (which) { \ 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; \ + case 0x01:RORW(*earw,val,LoadRw,SaveRw);break; \ + case 0x02:RCLW(*earw,val,LoadRw,SaveRw);break; \ + case 0x03:RCRW(*earw,val,LoadRw,SaveRw);break; \ + case 0x04:/* SHL and SAL are the same */ \ + case 0x06:SHLW(*earw,val,LoadRw,SaveRw);break; \ + case 0x05:SHRW(*earw,val,LoadRw,SaveRw);break; \ + case 0x07:SARW(*earw,val,LoadRw,SaveRw);break; \ } \ } else { \ GetEAa; \ Bit8u val=blah & 0x1f; \ - switch (rm & 0x38) { \ + switch (which) { \ 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; \ + case 0x01:RORW(eaa,val,LoadMw,SaveMw);break; \ + case 0x02:RCLW(eaa,val,LoadMw,SaveMw);break; \ + case 0x03:RCRW(eaa,val,LoadMw,SaveMw);break; \ + case 0x04:/* SHL and SAL are the same */ \ + case 0x06:SHLW(eaa,val,LoadMw,SaveMw);break; \ + case 0x05:SHRW(eaa,val,LoadMw,SaveMw);break; \ + case 0x07:SARW(eaa,val,LoadMw,SaveMw);break; \ } \ } \ } @@ -792,32 +792,32 @@ #define GRP2D(blah) \ { \ - GetRM; \ + GetRM;Bitu which=(rm>>3)&7; \ if (rm >= 0xc0) { \ GetEArd; \ Bit8u val=blah & 0x1f; \ - switch (rm&0x38) { \ + switch (which) { \ 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; \ + case 0x01:RORD(*eard,val,LoadRd,SaveRd);break; \ + case 0x02:RCLD(*eard,val,LoadRd,SaveRd);break; \ + case 0x03:RCRD(*eard,val,LoadRd,SaveRd);break; \ + case 0x04:/* SHL and SAL are the same */ \ + case 0x06:SHLD(*eard,val,LoadRd,SaveRd);break; \ + case 0x05:SHRD(*eard,val,LoadRd,SaveRd);break; \ + case 0x07:SARD(*eard,val,LoadRd,SaveRd);break; \ } \ } else { \ GetEAa; \ Bit8u val=blah & 0x1f; \ - switch (rm & 0x38) { \ + switch (which) { \ 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; \ + case 0x01:RORD(eaa,val,LoadMd,SaveMd);break; \ + case 0x02:RCLD(eaa,val,LoadMd,SaveMd);break; \ + case 0x03:RCRD(eaa,val,LoadMd,SaveMd);break; \ + case 0x04:/* SHL and SAL are the same */ \ + case 0x06:SHLD(eaa,val,LoadMd,SaveMd);break; \ + case 0x05:SHRD(eaa,val,LoadMd,SaveMd);break; \ + case 0x07:SARD(eaa,val,LoadMd,SaveMd);break; \ } \ } \ } From 49f89c9f50cc0dc9a0fb743f2f0e9b6ae3be65ca Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 22 Aug 2003 17:23:36 +0000 Subject: [PATCH 1117/4131] Added Int 0x10 function 0x1C Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1197 --- src/ints/int10.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 410fb176..c2dbb936 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -296,6 +296,10 @@ graphics_chars: LOG(LOG_INT10,LOG_ERROR)("1B:Unhandled call BX %2X",reg_bx); } break; + case 0x1C: /* Video Save Area */ + if (reg_al==0) reg_bx = 0; + reg_al = 0x1C; + break; case 0x4f: /* VESA Calls */ switch (reg_al) { case 0x00: /* Get SVGA Information */ From c71f9c3d1f746d2ce1f0f3cc46573d87349ec06d Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 22 Aug 2003 17:28:02 +0000 Subject: [PATCH 1118/4131] Added shared memory handling Improved set descriptor access rights Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1198 --- src/ints/dpmi.cpp | 366 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 269 insertions(+), 97 deletions(-) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index fa98edb7..6e562693 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -34,6 +34,9 @@ #define DPMI_LOG_ERROR LOG(LOG_MISC,LOG_ERROR) //#define DPMI_LOG_ERROR + +#define DPMI_ALLOC_NEEDEDMEM_HIGH 1 + #define DPMI_DPL 3 #define GDT_ZERO 0 @@ -49,7 +52,7 @@ /* Amount of descriptors in each table */ #define GDT_SIZE 32 #define IDT_SIZE 256 -#define LDT_SIZE 1024 +#define LDT_SIZE 2048 #define INT_SIZE 256 #define TOTAL_SIZE ((GDT_SIZE+IDT_SIZE+LDT_SIZE+INT_SIZE)*8) @@ -145,6 +148,20 @@ public: }; #pragma pack() +// ********************************************** +// Shared Memory +// ********************************************** + +typedef struct SSharedMem { + + std::string name; + Bitu handle; + Bitu pages; + +} TSharedMem; + +std::list g_sharedMemList; + // ********************************************** // DPMI Class // ********************************************** @@ -171,6 +188,7 @@ public: bool AllocateMem (Bitu size, Bitu& outHandle, Bitu& linear); Bitu CreateAlias (Bitu selector, Bit16u& alias); void ReloadSegments (Bitu selector); + bool SetAccessRights (Bitu selector, SetDescriptor& desc, Bitu rights); // Special Interrupt handlers Bitu Int2fHandler (void); @@ -230,6 +248,12 @@ public: void ClearXMSHandles (void); void FreeXMSHandle (Bitu handle); + // shared memory + void SetSharedMem (const char* name, Bitu handle, Bitu pages); + bool GetSharedMem (const char* name, Bitu& handle, Bitu& pages); + bool IsSharedMem (Bitu handle); + bool RemoveSharedMem (Bitu handle); + // special msdos api stuff Bitu GetSegmentFromSelector (Bitu selector); bool GetMsdosSelector (Bitu realseg, Bitu realoff, Bitu &protsel, Bitu &protoff); @@ -238,6 +262,8 @@ public: Bitu API_Int21_MSDOS (void); private: + Bitu Mask (Bitu value); + Bitu saveStack[DPMI_SAVESTACK_MAX]; Bitu savePtr; Bitu rm_ss, rm_sp; @@ -367,6 +393,56 @@ void DPMI::ClearXMSHandles(void) for (Bitu i=0; iname = name; + smem->handle= handle; + smem->pages = pages; + g_sharedMemList.push_back(smem); +}; + +bool DPMI::GetSharedMem(const char* name, Bitu& handle, Bitu& pages) +{ + TSharedMem* smem; + std::list::iterator i; + for(i = g_sharedMemList.begin(); i != g_sharedMemList.end(); i++) { + smem = static_cast(*i); + if (smem->name.compare(name)==0) { + handle = smem->handle; + pages = smem->pages; + return true; + } + + }; + return false; +}; + +bool DPMI::IsSharedMem(Bitu handle) +{ + std::list::iterator i; + for(i = g_sharedMemList.begin(); i != g_sharedMemList.end(); i++) { + if ((*i)->handle==handle) return true; + }; + return false; +}; + +bool DPMI::RemoveSharedMem(Bitu handle) +{ + TSharedMem* smem; + std::list::iterator i; + for(i = g_sharedMemList.begin(); i != g_sharedMemList.end(); i++) { + smem = static_cast(*i); + if (smem->handle==handle) { + g_sharedMemList.remove(*i); + delete smem; + return true; + } + + }; + return false; +}; + void DPMI::SetXMSHandle(Bitu handle) { for (Bitu i=0; i0); // Convert to 1KB pages - if (XMS_AllocateMemory(pages,handle)==0) { - if (XMS_LockMemory(handle,address)==0) { - SetXMSHandle(handle); - outHandle = handle; - linear = address; - XMS_UnlockMemory(handle); - return true; - } + // must equal caller DPL + if (((rights & 0x60)>>5)!=DPMI_DPL) { + DPMI_LOG("DPMI: Set Rights %04X : %04X failure (dpl=%02X)",selector,rights,(rights & 0x60)>>5); + return false; } - return false; + // must be 1 + if ((rights & 0x10)==0) { + DPMI_LOG_ERROR("DPMI: Set Rights %04X : %04X failure (must be 1)",selector,rights); + return false; + }; + // must be 0 + if (dpmi.client.bit32 && desc.saved.seg.p && (rights & 0x2000)) { + DPMI_LOG_ERROR("DPMI: Set Rights %04X : %04X failure (must be 0)",selector,rights); + return false; + }; + // all tests passed, set rights for 16 + 32 Bit + desc.SetType (rights&0x1F); + desc.saved.seg.dpl = (rights&0x60)>>5; +// desc.saved.seg.dpl = DPMI_DPL; + desc.saved.seg.p = (rights&0x80)>0; + // extended rights for 32 Bit apps + if (dpmi.client.bit32) { + desc.saved.seg.avl = (rights&0x1000)>0; + desc.saved.seg.r = (rights&0x2000)>0; + desc.saved.seg.big = (rights&0x4000)>0; + desc.saved.seg.g = (rights&0x8000)>0; + }; + return true; }; -*/ Bitu DPMI::Int31Handler(void) { @@ -1402,25 +1499,18 @@ Bitu DPMI::Int31Handler(void) Bit8u rcl = reg_cl; Bit8u rch = reg_ch; if (cpu.gdt.GetDescriptor(reg_bx,desc)) { -/* if (!(reg_cl & 0x10) || (reg_ch & 0x20) || (desc.saved.seg.dpl!=DPMI_DPL)) { + if (!SetAccessRights(reg_bx,desc,reg_cx)) { DPMI_LOG_ERROR("DPMI: 0009: Set Rights %04X : failure",reg_bx); reg_ax = DPMI_ERROR_INVALID_VALUE; DPMI_CALLBACK_SCF(true); break; - };*/ - desc.SetType (reg_cl&0x1F); - desc.saved.seg.dpl = DPMI_DPL; - desc.saved.seg.p = (reg_cl&0x80)>0; - desc.saved.seg.avl = (reg_ch&0x10)>0; - desc.saved.seg.r = (reg_ch&0x20)>0; - desc.saved.seg.big = (reg_ch&0x40)>0; - desc.saved.seg.g = (reg_ch&0x80)>0; + }; desc.Save(dpmi.ldt.base+(reg_bx & ~7)); ReloadSegments(reg_bx); DPMI_CALLBACK_SCF(false); DPMI_LOG("DPMI: 0009: Set Rights %04X : %04X",reg_bx,reg_cx); } else { - DPMI_LOG_ERROR("DPMI: 0009: Set Rights %04X : failure",reg_bx); + DPMI_LOG_ERROR("DPMI: 0009: Set Rights %04X : invalid selector",reg_bx); reg_ax = DPMI_ERROR_DESCRIPTOR_UNAVAILABLE; DPMI_CALLBACK_SCF(true); }; @@ -1450,22 +1540,13 @@ Bitu DPMI::Int31Handler(void) SetDescriptor desc; if (cpu.gdt.GetDescriptor(reg_bx,desc)) { desc.Load (SegPhys(es)+reg_edi); - // Check access rights -/* if (!(desc.saved.seg.type & 0x10) || (desc.saved.seg.r) || (desc.saved.seg.dpl!=DPMI_DPL)) { - DPMI_LOG("DPMI: 000C: Set Rights %04X : failure",reg_bx); + Bitu rights = (mem_readb(SegPhys(es)+reg_edi+6)<<8) + mem_readb(SegPhys(es)+reg_edi+5); + if (!SetAccessRights(reg_bx,desc,rights)) { + DPMI_LOG_ERROR("DPMI: 000C: Set Rights %04X : failure",reg_bx); reg_ax = DPMI_ERROR_INVALID_VALUE; DPMI_CALLBACK_SCF(true); break; - };*/ - if (!desc.saved.seg.p) { - DPMI_LOG_ERROR("DPMI: 000C: Set Rights %04X : not present",reg_bx); - desc.saved.seg.p = 1; - } -// desc.saved.seg.type |= 0x10; -// if (!dpmi.client.bit32) { -// desc.SetBase (desc.GetBase() & 0xFFFF); -// desc.SetLimit (desc.GetLimit() & 0xFFFF); -// }; + }; desc.Save(dpmi.ldt.base+(reg_bx & ~7)); ReloadSegments(reg_bx); DPMI_LOG("DPMI: 000B: Set Descriptor %04X : B:%08X L:%08X : P %01X",reg_bx,desc.GetBase(),desc.GetLimit(),desc.saved.seg.p); @@ -1732,7 +1813,7 @@ Bitu DPMI::Int31Handler(void) DPMI_CALLBACK_SCF(true); // TEMP Bitu total = MEM_FreeLargest(); // in KB - DPMI_LOG("DPMI: 0501: Allocation failure (%d KB) (R:%d KB)",length/1024 + ((length%1024)>0),total*4); + DPMI_LOG_ERROR("DPMI: 0501: Allocation failure (%d KB) (R:%d KB)",length/1024 + ((length%1024)>0),total*4); }; }; break; case 0x0502://Free Memory Block @@ -1746,7 +1827,7 @@ Bitu DPMI::Int31Handler(void) Bitu newByte = (reg_bx<<16)+reg_cx; Bitu newSize = (newByte/DPMI_PAGE_SIZE)+((newByte & (DPMI_PAGE_SIZE-1))>0); MemHandle handle = (reg_si<<16)+reg_di; - DPMI_LOG("DPMI: 0503: Resize Memory: H:%08X (%d KB)",handle,newSize*4); + DPMI_LOG_ERROR("DPMI: 0503: Resize Memory: H:%08X (%d KB)",handle,newSize*4); if (MEM_ReAllocatePages(handle,newSize,true)) { linear = handle * DPMI_PAGE_SIZE; reg_si = handle>>16; @@ -1756,7 +1837,7 @@ Bitu DPMI::Int31Handler(void) DPMI_CALLBACK_SCF(false); } else if (AllocateMem(newByte,newHandle,linear)) { // Not possible, try to allocate - DPMI_LOG("DPMI: 0503: Reallocated Memory: %d KB",newSize*4); + DPMI_LOG_ERROR("DPMI: 0503: Reallocated Memory: %d KB",newSize*4); reg_si = newHandle>>16; reg_di = newHandle&0xFFFF; reg_bx = linear>>16; @@ -1839,7 +1920,11 @@ Bitu DPMI::Int31Handler(void) // bx and cx remain the same linear address = physical address Bitu phys = (reg_bx<<16) + reg_cx; Bitu size = (reg_si<<16) + reg_di; - DPMI_LOG_ERROR("DPMI: 0800: Phys-adr-map not supported : %08X.(%08X).",phys,size); + MEM_MapPagesDirect(phys/DPMI_PAGE_SIZE,phys/DPMI_PAGE_SIZE,size/DPMI_PAGE_SIZE); + Bitu linear = phys; + reg_bx = linear>>16; + reg_cx = linear & 0xFFFF; + DPMI_LOG_ERROR("DPMI: 0800: Phys-adr-map not supported : %08X (%08X) - %08X.",phys,size,linear); DPMI_CALLBACK_SCF(false); }; break; case 0x0801:// Free physical address mapping @@ -1860,6 +1945,7 @@ Bitu DPMI::Int31Handler(void) break; case 0x0902:{//Get Virtual Interrupt State reg_al = dpmi.vIntFlag; + reg_al = 0; // TEMP DPMI_LOG("DPMI: 0900: Get vi : %01X",reg_al); DPMI_CALLBACK_SCF(false); }; break; @@ -1872,6 +1958,9 @@ Bitu DPMI::Int31Handler(void) reg_edi = DPMI_CB_APIMSDOSENTRY_OFFSET; API_Init_MSDOS(); DPMI_CALLBACK_SCF(false); +// } else if (strstr(name,"HWINT")!=0) { +// reg_ax = DPMI_ERROR_UNSUPPORTED; +// DPMI_CALLBACK_SCF(true); } else if (strstr(name,"PHARLAP")!=0) { CPU_SetSegGeneral(es,GDT_PROTCODE); reg_edi = DPMI_CB_APIMSDOSENTRY_OFFSET; @@ -1884,21 +1973,45 @@ Bitu DPMI::Int31Handler(void) } }; break; case 0x0D00:{//Allocate Shared Memory - PhysPt data = SegPhys(es)+reg_edi; - Bitu length = mem_readd(data); - Bitu pages = (length/DPMI_PAGE_SIZE)+((length%DPMI_PAGE_SIZE)>0); - Bitu handle,linear; - if (AllocateMem(length,handle,linear)) { - DPMI_LOG("DPMI: 0D00: Allocate shared memory (%d KB)",pages*4); - mem_writed(data+0x04,pages*DPMI_PAGE_SIZE); - mem_writed(data+0x08,handle); - mem_writed(data+0x0C,linear); - DPMI_CALLBACK_SCF(false); - } else { - DPMI_LOG_ERROR("DPMI: 0D00: Allocation shared failure (%d KB)",pages*4); - reg_ax = DPMI_ERROR_PHYSICAL_MEMORY_UNAVAILABLE; + char name[256]; + PhysPt data = SegPhys(es)+reg_edi; + Bitu length = mem_readd(data); + Bitu pages = (length/DPMI_PAGE_SIZE)+((length%DPMI_PAGE_SIZE)>0); + Bitu handle = mem_readd(data+0x08); + Bitu linear = mem_readd(data+0x0C); + Bitu strOffset = mem_readd(data+0x10); + Bitu strSelect = mem_readw(data+0x14); + + Descriptor desc; + if (!cpu.gdt.GetDescriptor(strSelect,desc)) { + DPMI_LOG_ERROR("DPMI: 0D00: shared memory: invalid name selector"); + reg_ax = DPMI_ERROR_INVALID_VALUE; DPMI_CALLBACK_SCF(true); + return false; + }; + MEM_StrCopy(desc.GetBase()+strOffset,name,256); + + // Already allocated ? + if (!GetSharedMem(name,handle,pages)) { + if (!AllocateMem(length,handle,linear)) { + DPMI_LOG_ERROR("DPMI: 0D00: Allocation shared failure %s (%d KB)",name,pages*4); + reg_ax = DPMI_ERROR_PHYSICAL_MEMORY_UNAVAILABLE; + DPMI_CALLBACK_SCF(true); + break; + }; + // Init first paragraph with zeros + for (Bitu i=0; i<16; i++) mem_writeb(linear+i,0); + SetSharedMem(name,handle,pages); + DPMI_LOG("DPMI: 0D00: Allocate shared memory %s (%d KB) ",name,pages*4); + } else { + linear = handle*DPMI_PAGE_SIZE; + DPMI_LOG("DPMI: 0D00: Reuse shared memory %s (%d KB) ",name,pages*4); }; + + mem_writed(data+0x04,pages*DPMI_PAGE_SIZE); + mem_writed(data+0x08,handle); + mem_writed(data+0x0C,linear); + DPMI_CALLBACK_SCF(false); }; break; case 0x0B00:// Set debug watchpoint case 0x0B01:// Clear debug watchpoint @@ -1952,26 +2065,26 @@ Bitu DPMI::Int2fHandler(void) // Callbacks and Callback-Returns // ********************************************************************* -static Bitu DPMI_ExceptionReturn(void) { return activeDPMI->ExceptionReturn(); }; -static Bitu DPMI_RealModeCallback(void) { return activeDPMI->RealModeCallback(); }; -static Bitu DPMI_RealModeCallbackReturn(void) { return activeDPMI->RealModeCallbackReturn(); }; -static Bitu DPMI_CallRealIRETFrame(void) { return activeDPMI->CallRealIRETFrame(); }; -static Bitu DPMI_CallRealIRETFrameReturn(void) { return activeDPMI->CallRealIRETFrameReturn(); }; -static Bitu DPMI_SimulateInt(void) { return activeDPMI->SimulateInt(); }; -static Bitu DPMI_SimulateIntReturn(void) { return activeDPMI->SimulateIntReturn(); }; -static Bitu DPMI_ptorHandler(void) { return activeDPMI->ptorHandler(); }; -static Bitu DPMI_ptorHandlerReturn(void) { return activeDPMI->ptorHandlerReturn(); }; -static Bitu DPMI_Int21Handler(void) { return activeDPMI->Int21Handler(); }; -static Bitu DPMI_Int21HandlerReturn(void) { return activeDPMI->Int21HandlerReturn(); }; -static Bitu DPMI_HWIntDefaultHandler(void) { return activeDPMI->HWIntDefaultHandler(); }; -static Bitu DPMI_EnterProtMode(void) { return activeDPMI->EnterProtMode(); }; -static Bitu DPMI_EnterRealMode(void) { return activeDPMI->EnterRealMode(); }; -static Bitu DPMI_RealSaveState(void) { return activeDPMI->RealSaveState(); }; -static Bitu DPMI_ProtSaveState(void) { return activeDPMI->ProtSaveState(); }; -static Bitu DPMI_Int2fHandler(void) { return activeDPMI->Int2fHandler(); }; -static Bitu DPMI_Int31Handler(void) { return activeDPMI->Int31Handler(); }; -static Bitu DPMI_API_Int21_MSDOS(void) { return activeDPMI->API_Int21_MSDOS(); }; -static Bitu DPMI_API_Entry_MSDOS(void) { return activeDPMI->API_Entry_MSDOS(); }; +static Bitu DPMI_ExceptionReturn(void) { if (activeDPMI) return activeDPMI->ExceptionReturn(); return 0;}; +static Bitu DPMI_RealModeCallback(void) { if (activeDPMI) return activeDPMI->RealModeCallback(); return 0;}; +static Bitu DPMI_RealModeCallbackReturn(void) { if (activeDPMI) return activeDPMI->RealModeCallbackReturn(); return 0;}; +static Bitu DPMI_CallRealIRETFrame(void) { if (activeDPMI) return activeDPMI->CallRealIRETFrame(); return 0;}; +static Bitu DPMI_CallRealIRETFrameReturn(void) { if (activeDPMI) return activeDPMI->CallRealIRETFrameReturn(); return 0;}; +static Bitu DPMI_SimulateInt(void) { if (activeDPMI) return activeDPMI->SimulateInt(); return 0;}; +static Bitu DPMI_SimulateIntReturn(void) { if (activeDPMI) return activeDPMI->SimulateIntReturn(); return 0;}; +static Bitu DPMI_ptorHandler(void) { if (activeDPMI) return activeDPMI->ptorHandler(); return 0;}; +static Bitu DPMI_ptorHandlerReturn(void) { if (activeDPMI) return activeDPMI->ptorHandlerReturn(); return 0;}; +static Bitu DPMI_Int21Handler(void) { if (activeDPMI) return activeDPMI->Int21Handler(); return 0;}; +static Bitu DPMI_Int21HandlerReturn(void) { if (activeDPMI) return activeDPMI->Int21HandlerReturn(); return 0;}; +static Bitu DPMI_HWIntDefaultHandler(void) { if (activeDPMI) return activeDPMI->HWIntDefaultHandler(); return 0;}; +static Bitu DPMI_EnterProtMode(void) { if (activeDPMI) return activeDPMI->EnterProtMode(); return 0;}; +static Bitu DPMI_EnterRealMode(void) { if (activeDPMI) return activeDPMI->EnterRealMode(); return 0;}; +static Bitu DPMI_RealSaveState(void) { if (activeDPMI) return activeDPMI->RealSaveState(); return 0;}; +static Bitu DPMI_ProtSaveState(void) { if (activeDPMI) return activeDPMI->ProtSaveState(); return 0;}; +static Bitu DPMI_Int2fHandler(void) { if (activeDPMI) return activeDPMI->Int2fHandler(); return 0;}; +static Bitu DPMI_Int31Handler(void) { if (activeDPMI) return activeDPMI->Int31Handler(); return 0;}; +static Bitu DPMI_API_Int21_MSDOS(void) { if (activeDPMI) return activeDPMI->API_Int21_MSDOS(); return 0;}; +static Bitu DPMI_API_Entry_MSDOS(void) { if (activeDPMI) return activeDPMI->API_Entry_MSDOS(); return 0;}; // **************************************************************** @@ -2020,8 +2133,13 @@ void DPMI::Terminate(void) for (i=0; i::iterator i; + for(i=g_sharedMemList.begin(); i != g_sharedMemList.end(); i++) + delete static_cast(*i); + (g_sharedMemList.clear)(); +}; + void DPMI_Init(Section* sec) { Section_prop * section=static_cast(sec); @@ -2300,6 +2428,9 @@ void DPMI_Init(Section* sec) /* Setup multiplex */ DOS_AddMultiplexHandler(DPMI_Multiplex); + + /* shutdown function */ + sec->AddDestroyFunction(&DPMI_ShutDown); } void DPMI::Reactivate() @@ -2317,19 +2448,29 @@ void DPMI::Setup() Bitu i; Bitu xmssize = (TOTAL_SIZE|(DPMI_PAGE_SIZE-1))+1; Bitu protStackSize = ((DPMI_PROTMODE_STACK_MAX*DPMI_PROTMODE_STACKSIZE)|(DPMI_PAGE_SIZE-1))+1; - Bitu sizePages = ((xmssize+protStackSize) >> 12); + Bitu numPages = ((xmssize+protStackSize) >> 12); - dpmi.mem_handle = MEM_AllocatePages(sizePages,true); +#if DPMI_ALLOC_NEEDEDMEM_HIGH + /* Allocate the GDT,LDT,IDT Stack space (High Mem) */ + dpmi.mem_handle = MEM_AllocatePages(numPages,true); if (dpmi.mem_handle==0) { LOG_MSG("DPMI:Can't allocate XMS memory, disabling dpmi support."); return; } - + Bitu address = dpmi.mem_handle*DPMI_PAGE_SIZE;; +#else + // load LDT and stuff in low mem ( + Bit16u segment; + Bit16u blocks = numPages*4096/16; + if (!DOS_AllocateMemory(&segment,&blocks)) { + LOG_MSG("DPMI:Can't allocate XMS memory, disabling dpmi support."); + return; + }; + Bitu address = segment * 16; +#endif // Allocate real mode stack space rm_ss = DOS_GetMemory(DPMI_REALMODE_STACKSIZE/16); rm_sp = DPMI_REALMODE_STACKSIZE; - /* Allocate the GDT,LDT,IDT Stack space */ - Bitu address = dpmi.mem_handle*DPMI_PAGE_SIZE;; // Get Begin of protected mode stack dpmi.protStack = address + xmssize; /* Clear the memory */ @@ -2501,6 +2642,12 @@ Bitu DPMI::API_Entry_MSDOS(void) return 0; }; +Bitu DPMI::Mask(Bitu value) +{ + if (dpmi.client.bit32) return value; + else return value & 0xFFFF; +}; + Bitu DPMI::API_Int21_MSDOS(void) { DPMI_LOG("DPMI:MSDOS-API:INT 21 %04X",reg_ax); @@ -2509,7 +2656,7 @@ Bitu DPMI::API_Int21_MSDOS(void) switch (reg_ah) { case 0x1a: /* Set Disk Transfer Area Address */ - dtaAddress = SegPhys(ds) + reg_edx; + dtaAddress = SegPhys(ds) + Mask(reg_edx); break; case 0x25: { // Set Protected mode Interrupt Vector if (dpmi.pharlap) { @@ -2517,7 +2664,7 @@ Bitu DPMI::API_Int21_MSDOS(void) switch (reg_al) { case 0x05: // Set Real mode Int Vector - RealSetVec(reg_cl,reg_ebx); + RealSetVec(reg_cl,Mask(reg_ebx)); DPMI_CALLBACK_SCF(false); break; @@ -2530,7 +2677,7 @@ Bitu DPMI::API_Int21_MSDOS(void) gate.Clear(); gate.saved.seg.p=1; gate.SetSelector(SegValue(ds)); - gate.SetOffset (reg_edx); + gate.SetOffset (Mask(reg_edx)); gate.SetType (dpmi.client.bit32?DESC_386_INT_GATE:DESC_286_INT_GATE); gate.saved.seg.dpl = DPMI_DPL; gate.Save(dpmi.idt.base+reg_al*8); @@ -2559,9 +2706,19 @@ Bitu DPMI::API_Int21_MSDOS(void) CPU_SetSegGeneral(es,protsel); reg_bx = protoff; break; + case 0x39:{ // MKDIR Create directory + char name1[256]; + MEM_StrCopy(SegPhys(ds)+Mask(reg_edx),name1,255); + if (DOS_MakeDir(name1)) { + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + }; break; case 0x3c: { /* CREATE Create of truncate file */ char name1[256]; - MEM_StrCopy(SegPhys(ds)+reg_edx,name1,255); + MEM_StrCopy(SegPhys(ds)+Mask(reg_edx),name1,255); if (DOS_CreateFile(name1,reg_cx,®_ax)) { DPMI_CALLBACK_SCF(false); } else { @@ -2571,12 +2728,18 @@ Bitu DPMI::API_Int21_MSDOS(void) }; break; case 0x3d: { /* OPEN Open existing file */ char name1[256]; - MEM_StrCopy(SegPhys(ds)+reg_edx,name1,255); + MEM_StrCopy(SegPhys(ds)+Mask(reg_edx),name1,255); if (DOS_OpenFile(name1,reg_al,®_ax)) { DPMI_LOG("DOS: Open success: %s",name1); DPMI_CALLBACK_SCF(false); } else { - DPMI_LOG("DOS: Open failure: %s",name1); + DOS_PSP psp(dos.psp); + psp.SetNumFiles(40); + if (DOS_OpenFile(name1,reg_al,®_ax)) { + DPMI_LOG_ERROR("DOS: Open success (Hack): %s",name1); + DPMI_CALLBACK_SCF(false); + break; + }; reg_ax=dos.errorcode; DPMI_CALLBACK_SCF(true); } @@ -2587,10 +2750,10 @@ Bitu DPMI::API_Int21_MSDOS(void) E_Exit("DPMI:DOS: Read file size > 0xffff"); }; - Bit16u toread = reg_ecx; + Bit16u toread = Mask(reg_ecx); dos.echo = true; if (DOS_ReadFile(reg_bx,dos_copybuf,&toread)) { - MEM_BlockWrite(SegPhys(ds)+reg_edx,dos_copybuf,toread); + MEM_BlockWrite(SegPhys(ds)+Mask(reg_edx),dos_copybuf,toread); reg_eax=toread; DPMI_CALLBACK_SCF(false); @@ -2602,19 +2765,21 @@ Bitu DPMI::API_Int21_MSDOS(void) break; } case 0x40: {/* WRITE Write to file or device */ - Bit16u towrite = reg_ecx; - MEM_BlockRead(SegPhys(ds)+reg_edx,dos_copybuf,towrite); + Bit16u towrite = Mask(reg_ecx); + MEM_BlockRead(SegPhys(ds)+Mask(reg_edx),dos_copybuf,towrite); + if (reg_bx>=5) LOG(LOG_MISC,LOG_ERROR)("INT 21 40: %s",dos_copybuf); if (DOS_WriteFile(reg_bx,dos_copybuf,&towrite)) { reg_eax=towrite; DPMI_CALLBACK_SCF(false); } else { + DPMI_LOG_ERROR("DPMI:MSDOS:Write file failure."); reg_ax=dos.errorcode; DPMI_CALLBACK_SCF(true); } }; break; case 0x41: { /* UNLINK Delete file */ char name1[256]; - MEM_StrCopy(SegPhys(ds)+reg_edx,name1,255); + MEM_StrCopy(SegPhys(ds)+Mask(reg_edx),name1,255); if (DOS_UnlinkFile(name1)) { DPMI_CALLBACK_SCF(false); } else { @@ -2637,7 +2802,7 @@ Bitu DPMI::API_Int21_MSDOS(void) } case 0x43: { /* Get/Set file attributes */ char name1[256]; - MEM_StrCopy(SegPhys(ds)+reg_edx,name1,255); + MEM_StrCopy(SegPhys(ds)+Mask(reg_edx),name1,255); switch (reg_al) case 0x00: /* Get */ { @@ -2659,7 +2824,7 @@ Bitu DPMI::API_Int21_MSDOS(void) case 0x4E: {/* Get first dir entry */ char name1[256]; - MEM_StrCopy(SegPhys(ds)+reg_edx,name1,255); + MEM_StrCopy(SegPhys(ds)+Mask(reg_edx),name1,255); if (DOS_FindFirst(name1,reg_cx)) { DPMI_CALLBACK_SCF(false); // Copy result to internal dta @@ -2701,6 +2866,10 @@ Bitu DPMI::API_Int21_MSDOS(void) Bitu segment = GetSegmentFromSelector(reg_dx); DOS_ChildPSP(segment,reg_si); dos.psp = segment; + if (dpmi.pharlap) { + DOS_PSP psp(dos.psp); + psp.SetNumFiles(40); + }; DPMI_LOG("DPMI:MSDOS:0x55:Create new psp:%04X",segment); }; break; case 0x5D : // Get Address of dos swappable area @@ -2717,6 +2886,9 @@ Bitu DPMI::API_Int21_MSDOS(void) reg_bx = protsel; DPMI_LOG("DPMI:MSDOS:0x62:Get current psp:%04X",reg_bx); break; + case 0x68: // Flush file to disc + DPMI_CALLBACK_SCF(false); + break; case 0x09: case 0x0A: From e18440ce3213fa89e3f84964cd9f47a7267e4bc9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 22 Aug 2003 20:13:48 +0000 Subject: [PATCH 1119/4131] New core_normal based on old core_16 for handling real and protected mode code. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1199 --- src/cpu/Makefile.am | 4 +- src/cpu/core_normal.cpp | 221 ++++++ src/cpu/core_normal/Makefile.am | 3 + src/cpu/core_normal/helpers.h | 143 ++++ src/cpu/core_normal/prefix_0f.h | 449 +++++++++++ src/cpu/core_normal/prefix_66.h | 611 +++++++++++++++ src/cpu/core_normal/prefix_66_0f.h | 370 +++++++++ src/cpu/core_normal/prefix_none.h | 1171 ++++++++++++++++++++++++++++ src/cpu/core_normal/string.h | 243 ++++++ src/cpu/core_normal/support.h | 138 ++++ src/cpu/core_normal/table_ea.h | 356 +++++++++ src/cpu/cpu.cpp | 32 +- 12 files changed, 3726 insertions(+), 15 deletions(-) create mode 100644 src/cpu/core_normal.cpp create mode 100644 src/cpu/core_normal/Makefile.am create mode 100644 src/cpu/core_normal/helpers.h create mode 100644 src/cpu/core_normal/prefix_0f.h create mode 100644 src/cpu/core_normal/prefix_66.h create mode 100644 src/cpu/core_normal/prefix_66_0f.h create mode 100644 src/cpu/core_normal/prefix_none.h create mode 100644 src/cpu/core_normal/string.h create mode 100644 src/cpu/core_normal/support.h create mode 100644 src/cpu/core_normal/table_ea.h diff --git a/src/cpu/Makefile.am b/src/cpu/Makefile.am index b485ebed..6eee8926 100644 --- a/src/cpu/Makefile.am +++ b/src/cpu/Makefile.am @@ -1,6 +1,6 @@ -SUBDIRS = core_16 core_full +SUBDIRS = core_16 core_full core_normal AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libcpu.a libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h slow_16.cpp core_full.cpp instructions.h \ - paging.cpp lazyflags.h \ No newline at end of file + paging.cpp lazyflags.h core_normal.cpp \ No newline at end of file diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp new file mode 100644 index 00000000..73522a22 --- /dev/null +++ b/src/cpu/core_normal.cpp @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "dosbox.h" +#include "mem.h" +#include "cpu.h" +#include "lazyflags.h" +#include "inout.h" +#include "callback.h" +#include "pic.h" +#include "fpu.h" + +#if C_DEBUG +#include "debug.h" +#endif + + +#define SegBase(c) SegPhys(c) +#if (!C_CORE_INLINE) + +#define LoadMb(off) mem_readb(off) +#define LoadMw(off) mem_readw(off) +#define LoadMd(off) mem_readd(off) + +#define SaveMb(off,val) mem_writeb(off,val) +#define SaveMw(off,val) mem_writew(off,val) +#define SaveMd(off,val) mem_writed(off,val) + +#else + +#include "paging.h" +#define LoadMb(off) mem_readb_inline(off) +#define LoadMw(off) mem_readw_inline(off) +#define LoadMd(off) mem_readd_inline(off) + +#define SaveMb(off,val) mem_writeb_inline(off,val) +#define SaveMw(off,val) mem_writew_inline(off,val) +#define SaveMd(off,val) mem_writed_inline(off,val) + +#endif + +#define LoadMbs(off) (Bit8s)(LoadMb(off)) +#define LoadMws(off) (Bit16s)(LoadMw(off)) +#define LoadMds(off) (Bit32s)(LoadMd(off)) + +#define LoadRb(reg) reg +#define LoadRw(reg) reg +#define LoadRd(reg) reg + +#define SaveRb(reg,val) reg=val +#define SaveRw(reg,val) reg=val +#define SaveRd(reg,val) reg=val + +extern Bitu cycle_count; + +#if C_FPU +#define CPU_FPU 1 //Enable FPU escape instructions +#endif + +#define CPU_PIC_CHECK 1 +#define CPU_TRAP_CHECK 1 + +#define OPCODE_NONE 0x000 +#define OPCODE_0F 0x100 +#define OPCODE_SIZE 0x200 + +#define PREFIX_SEG 0x1 +#define PREFIX_ADDR 0x2 +#define PREFIX_SEG_ADDR (PREFIX_SEG|PREFIX_ADDR) +#define PREFIX_REP 0x4 + +#define TEST_PREFIX_SEG (core.prefixes & PREFIX_SEG) +#define TEST_PREFIX_ADDR (core.prefixes & PREFIX_ADDR) +#define TEST_PREFIX_REP (core.prefixes & PREFIX_REP) + +#define DO_PREFIX_SEG(_SEG) \ + core.prefixes|=PREFIX_SEG; \ + core.seg_prefix_base=SegBase(_SEG); \ + goto restart_prefix; + +#define DO_PREFIX_ADDR() \ + core.prefixes^=PREFIX_ADDR; \ + goto restart_prefix; + +#define DO_PREFIX_REP(_ZERO) \ + core.prefixes|=PREFIX_REP; \ + core.rep_zero=_ZERO; \ + goto restart_prefix; + +typedef PhysPt (*GetEATable[256])(void); + +static struct { + Bitu opcode_index; + Bitu prefixes; + Bitu index_default; + Bitu prefix_default; + PhysPt op_start; + PhysPt ip_lookup; + PhysPt seg_prefix_base; + bool rep_zero; + GetEATable * ea_table; +} core; + +#include "instructions.h" +#include "core_normal/support.h" +#include "core_normal/string.h" + +static GetEATable * EAPrefixTable[8] = { + &GetEA_NONE,&GetEA_SEG,&GetEA_ADDR,&GetEA_SEG_ADDR, + &GetEA_NONE,&GetEA_SEG,&GetEA_ADDR,&GetEA_SEG_ADDR, +}; + +#define CASE_W(_WHICH) \ + case (OPCODE_NONE+_WHICH): + +#define CASE_D(_WHICH) \ + case (OPCODE_SIZE+_WHICH): + +#define CASE_B(_WHICH) \ + CASE_W(_WHICH) \ + CASE_D(_WHICH) + +#define CASE_0F_W(_WHICH) \ + case ((OPCODE_0F|OPCODE_NONE)+_WHICH): + +#define CASE_0F_D(_WHICH) \ + case ((OPCODE_0F|OPCODE_SIZE)+_WHICH): + +#define CASE_0F_B(_WHICH) \ + CASE_0F_W(_WHICH) \ + CASE_0F_D(_WHICH) + +#define EALookupTable (*(core.ea_table)) + + +static Bits CPU_Core_Normal_Decode_Trap(void); + +static Bits CPU_Core_Normal_Decode(void) { +decode_start: + LOADIP; + flags.type=t_UNKNOWN; + while (CPU_Cycles>0) { + core.op_start=core.ip_lookup; + core.opcode_index=core.index_default; + core.prefixes=core.prefix_default; +#if C_DEBUG + cycle_count++; +#if C_HEAVY_DEBUG + SAVEIP; + if (DEBUG_HeavyIsBreakpoint()) { + LEAVECORE; + return debugCallback; + }; +#endif +#endif + CPU_Cycles--; +restart_prefix: + core.ea_table=EAPrefixTable[core.prefixes]; +restart_opcode: + switch (core.opcode_index+Fetchb()) { + + #include "core_normal/prefix_none.h" + #include "core_normal/prefix_0f.h" + #include "core_normal/prefix_66.h" + #include "core_normal/prefix_66_0f.h" + default: + ADDIPFAST(-1); + LOG_MSG("Unhandled code %X",core.opcode_index+Fetchb()); + } + } + decode_end: + LEAVECORE; + return CBRET_NONE; +} + +static Bits CPU_Core_Normal_Decode_Trap(void) { + + Bits oldCycles = CPU_Cycles; + CPU_Cycles = 1; + Bits ret=CPU_Core_Normal_Decode(); + + Interrupt(1); + + CPU_Cycles = oldCycles-1; + cpudecoder = &CPU_Core_Normal_Decode; + + return ret; +} + + + +void CPU_Core_Normal_Start(bool big) { + + if (GETFLAG(TF)) cpudecoder=CPU_Core_Normal_Decode_Trap; + else cpudecoder=CPU_Core_Normal_Decode; + + if (big) { + core.index_default=0x200; + core.prefix_default=PREFIX_ADDR; + } else { + core.index_default=0; + core.prefix_default=0; + } +} + diff --git a/src/cpu/core_normal/Makefile.am b/src/cpu/core_normal/Makefile.am new file mode 100644 index 00000000..99f76f3d --- /dev/null +++ b/src/cpu/core_normal/Makefile.am @@ -0,0 +1,3 @@ + +noinst_HEADERS = helpers.h prefix_none.h prefix_66.h prefix_0f.h support.h table_ea.h \ + prefix_66_0f.h string.h diff --git a/src/cpu/core_normal/helpers.h b/src/cpu/core_normal/helpers.h new file mode 100644 index 00000000..6a30e052 --- /dev/null +++ b/src/cpu/core_normal/helpers.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#define GetEAa \ + PhysPt eaa=EALookupTable[rm](); + +#define GetRMEAa \ + GetRM; \ + GetEAa; + + +#define RMEbGb(inst) \ + { \ + GetRMrb; \ + if (rm >= 0xc0 ) {GetEArb;inst(*earb,*rmrb,LoadRb,SaveRb);} \ + else {GetEAa;inst(eaa,*rmrb,LoadMb,SaveMb);} \ + } + +#define RMGbEb(inst) \ + { \ + GetRMrb; \ + if (rm >= 0xc0 ) {GetEArb;inst(*rmrb,*earb,LoadRb,SaveRb);} \ + else {GetEAa;inst(*rmrb,LoadMb(eaa),LoadRb,SaveRb);} \ + } + +#define RMEb(inst) \ + { \ + if (rm >= 0xc0 ) {GetEArb;inst(*earb,LoadRb,SaveRb);} \ + else {GetEAa;inst(eaa,LoadMb,SaveMb);} \ + } + +#define RMEwGw(inst) \ + { \ + GetRMrw; \ + if (rm >= 0xc0 ) {GetEArw;inst(*earw,*rmrw,LoadRw,SaveRw);} \ + else {GetEAa;inst(eaa,*rmrw,LoadMw,SaveMw);} \ + } + +#define RMEwGwOp3(inst,op3) \ + { \ + GetRMrw; \ + if (rm >= 0xc0 ) {GetEArw;inst(*earw,*rmrw,op3,LoadRw,SaveRw);} \ + else {GetEAa;inst(eaa,*rmrw,op3,LoadMw,SaveMw);} \ + } + +#define RMGwEw(inst) \ + { \ + GetRMrw; \ + if (rm >= 0xc0 ) {GetEArw;inst(*rmrw,*earw,LoadRw,SaveRw);} \ + else {GetEAa;inst(*rmrw,LoadMw(eaa),LoadRw,SaveRw);} \ + } + +#define RMGwEwOp3(inst,op3) \ + { \ + GetRMrw; \ + if (rm >= 0xc0 ) {GetEArw;inst(*rmrw,*earw,op3,LoadRw,SaveRw);} \ + else {GetEAa;inst(*rmrw,LoadMw(eaa),op3,LoadRw,SaveRw);} \ + } + +#define RMEw(inst) \ + { \ + if (rm >= 0xc0 ) {GetEArw;inst(*earw,LoadRw,SaveRw);} \ + else {GetEAa;inst(eaa,LoadMw,SaveMw);} \ + } + +#define RMEdGd(inst) \ + { \ + GetRMrd; \ + if (rm >= 0xc0 ) {GetEArd;inst(*eard,*rmrd,LoadRd,SaveRd);} \ + else {GetEAa;inst(eaa,*rmrd,LoadMd,SaveMd);} \ + } + +#define RMEdGdOp3(inst,op3) \ + { \ + GetRMrd; \ + if (rm >= 0xc0 ) {GetEArd;inst(*eard,*rmrd,op3,LoadRd,SaveRd);} \ + else {GetEAa;inst(eaa,*rmrd,op3,LoadMd,SaveMd);} \ + } + + +#define RMGdEd(inst) \ + { \ + GetRMrd; \ + if (rm >= 0xc0 ) {GetEArd;inst(*rmrd,*eard,LoadRd,SaveRd);} \ + else {GetEAa;inst(*rmrd,LoadMd(eaa),LoadRd,SaveRd);} \ + } + +#define RMGdEdOp3(inst,op3) \ + { \ + GetRMrd; \ + if (rm >= 0xc0 ) {GetEArd;inst(*rmrd,*eard,op3,LoadRd,SaveRd);} \ + else {GetEAa;inst(*rmrd,LoadMd(eaa),op3,LoadRd,SaveRd);} \ + } + + + + +#define RMEw(inst) \ + { \ + if (rm >= 0xc0 ) {GetEArw;inst(*earw,LoadRw,SaveRw);} \ + else {GetEAa;inst(eaa,LoadMw,SaveMw);} \ + } + +#define RMEd(inst) \ + { \ + if (rm >= 0xc0 ) {GetEArd;inst(*eard,LoadRd,SaveRd);} \ + else {GetEAa;inst(eaa,LoadMd,SaveMd);} \ + } + +#define ALIb(inst) \ + { inst(reg_al,Fetchb(),LoadRb,SaveRb)} + +#define AXIw(inst) \ + { inst(reg_ax,Fetchw(),LoadRw,SaveRw);} + +#define EAXId(inst) \ + { inst(reg_eax,Fetchd(),LoadRd,SaveRd);} + +#define FPU_ESC(code) { \ + Bit8u rm=Fetchb(); \ + if (rm >= 0xc0) { \ + FPU_ESC ## code ## _Normal(rm); \ + } else { \ + GetEAa;FPU_ESC ## code ## _EA(rm,eaa); \ + } \ +} + diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h new file mode 100644 index 00000000..0871fab1 --- /dev/null +++ b/src/cpu/core_normal/prefix_0f.h @@ -0,0 +1,449 @@ +/* + * 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. + */ + + CASE_0F_W(0x00) /* GRP 6 Exxx */ + { + GetRM;Bitu which=(rm>>3)&7; + switch (which) { + case 0x00: /* SLDT */ + case 0x01: /* STR */ + { + Bitu saveval; + if (!which) CPU_SLDT(saveval); + else CPU_STR(saveval); + if (rm >= 0xc0) {GetEArw;*earw=saveval;} + else {GetEAa;SaveMw(eaa,saveval);} + } + break; + case 0x02:case 0x03:case 0x04:case 0x05: + { + FillFlags(); + Bitu loadval; + if (rm >= 0xc0 ) {GetEArw;loadval=*earw;} + else {GetEAa;loadval=LoadMw(eaa);} + break; + switch (which) { + case 0x02:CPU_LLDT(loadval);break; + case 0x03:CPU_LTR(loadval);break; + case 0x04:CPU_VERR(loadval);break; + case 0x05:CPU_VERW(loadval);break; + } + } + default: + LOG(LOG_CPU,LOG_ERROR)("GRP6:Illegal call %2X",which); + } + } + break; + CASE_0F_W(0x01) /* Group 7 Ew */ + { + GetRM;Bitu which=(rm>>3)&7; + if (rm < 0xc0) { //First ones all use EA + GetEAa;Bitu limit,base; + switch (which) { + case 0x00: /* SGDT */ + CPU_SGDT(limit,base); + SaveMw(eaa,limit); + SaveMd(eaa+2,base); + break; + case 0x01: /* SIDT */ + CPU_SIDT(limit,base); + SaveMw(eaa,limit); + SaveMd(eaa+2,base); + break; + case 0x02: /* LGDT */ + CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF); + break; + case 0x03: /* LIDT */ + CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF); + break; + case 0x04: /* SMSW */ + CPU_SMSW(limit); + SaveMw(eaa,limit); + break; + case 0x06: /* LMSW */ + limit=LoadMw(eaa); + if (!CPU_LMSW(limit)) goto decode_end; + break; + } + } else { + GetEArw;Bitu limit; + switch (which) { + case 0x04: /* SMSW */ + CPU_SMSW(limit); + *earw=limit; + break; + case 0x06: /* LMSW */ + if (!CPU_LMSW(*earw)) goto decode_end; + break; + default: + LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which); + break; + } + } + } + break; + CASE_0F_W(0x02) /* LAR Gw,Ew */ + { + FillFlags(); + GetRMrw;Bitu ar; + if (rm >= 0xc0) { + GetEArw;CPU_LAR(*earw,ar); + } else { + GetEAa;CPU_LAR(LoadMw(eaa),ar); + } + *rmrw=(Bit16u)ar; + } + break; + CASE_0F_W(0x03) /* LSL Gw,Ew */ + { + FillFlags(); + GetRMrw;Bitu limit; + if (rm >= 0xc0) { + GetEArw;CPU_LSL(*earw,limit); + } else { + GetEAa;CPU_LSL(LoadMw(eaa),limit); + } + *rmrw=(Bit16u)limit; + } + break; + CASE_0F_B(0x20) /* MOV Rd.CRx */ + { + GetRM; + Bitu which=(rm >> 3) & 7; + if (rm >= 0xc0 ) { + GetEArd; + *eard=CPU_GET_CRX(which); + } else { + GetEAa; + LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%d with non-register",which); + } + } + break; + CASE_0F_B(0x22) /* MOV CRx,Rd */ + { + GetRM; + Bitu which=(rm >> 3) & 7; + if (rm >= 0xc0 ) { + GetEArd; + if (!CPU_SET_CRX(which,*eard)) goto decode_end; + } else { + GetEAa; + LOG(LOG_CPU,LOG_ERROR)("MOV CR%,XXX with non-register",which); + } + } + break; + CASE_0F_B(0x23) /* MOV DRx,Rd */ + { + GetRM; + Bitu which=(rm >> 3) & 7; + if (rm >= 0xc0 ) { + GetEArd; + } else { + GetEAa; + LOG(LOG_CPU,LOG_ERROR)("MOV DR%,XXX with non-register",which); + } + } + break; + CASE_0F_W(0x80) /* JO */ + JumpSIw(get_OF());break; + CASE_0F_W(0x81) /* JNO */ + JumpSIw(!get_OF());break; + CASE_0F_W(0x82) /* JB */ + JumpSIw(get_CF());break; + CASE_0F_W(0x83) /* JNB */ + JumpSIw(!get_CF());break; + CASE_0F_W(0x84) /* JZ */ + JumpSIw(get_ZF());break; + CASE_0F_W(0x85) /* JNZ */ + JumpSIw(!get_ZF());break; + CASE_0F_W(0x86) /* JBE */ + JumpSIw(get_CF() || get_ZF());break; + CASE_0F_W(0x87) /* JNBE */ + JumpSIw(!get_CF() && !get_ZF());break; + CASE_0F_W(0x88) /* JS */ + JumpSIw(get_SF());break; + CASE_0F_W(0x89) /* JNS */ + JumpSIw(!get_SF());break; + CASE_0F_W(0x8a) /* JP */ + JumpSIw(get_PF());break; + CASE_0F_W(0x8b) /* JNP */ + JumpSIw(!get_PF());break; + CASE_0F_W(0x8c) /* JL */ + JumpSIw(get_SF() != get_OF());break; + CASE_0F_W(0x8d) /* JNL */ + JumpSIw(get_SF() == get_OF());break; + CASE_0F_W(0x8e) /* JLE */ + JumpSIw(get_ZF() || (get_SF() != get_OF()));break; + CASE_0F_W(0x8f) /* JNLE */ + JumpSIw((get_SF() == get_OF()) && !get_ZF());break; + CASE_0F_B(0x90) /* SETO */ + SETcc(get_OF());break; + CASE_0F_B(0x91) /* SETNO */ + SETcc(!get_OF());break; + CASE_0F_B(0x92) /* SETB */ + SETcc(get_CF());break; + CASE_0F_B(0x93) /* SETNB */ + SETcc(!get_CF());break; + CASE_0F_B(0x94) /* SETZ */ + SETcc(get_ZF());break; + CASE_0F_B(0x95) /* SETNZ */ + SETcc(!get_ZF()); break; + CASE_0F_B(0x96) /* SETBE */ + SETcc(get_CF() || get_ZF());break; + CASE_0F_B(0x97) /* SETNBE */ + SETcc(!get_CF() && !get_ZF());break; + CASE_0F_B(0x98) /* SETS */ + SETcc(get_SF());break; + CASE_0F_B(0x99) /* SETNS */ + SETcc(!get_SF());break; + CASE_0F_B(0x9a) /* SETP */ + SETcc(get_PF());break; + CASE_0F_B(0x9b) /* SETNP */ + SETcc(!get_PF());break; + CASE_0F_B(0x9c) /* SETL */ + SETcc(get_SF() != get_OF());break; + CASE_0F_B(0x9d) /* SETNL */ + SETcc(get_SF() == get_OF());break; + CASE_0F_B(0x9e) /* SETLE */ + SETcc(get_ZF() || (get_SF() != get_OF()));break; + CASE_0F_B(0x9f) /* SETNLE */ + SETcc((get_SF() == get_OF()) && !get_ZF());break; + + CASE_0F_W(0xa0) /* PUSH FS */ + Push_16(SegValue(fs));break; + CASE_0F_W(0xa1) /* POP FS */ + CPU_SetSegGeneral(fs,Pop_16());break; + CASE_0F_B(0xa2) /* CPUID */ + CPU_CPUID();break; + CASE_0F_W(0xa3) /* BT Ew,Gw */ + { + GetRMrw; + Bit16u mask=1 << (*rmrw & 15); + if (rm >= 0xc0 ) { + GetEArw; + SETFLAGBIT(CF,(*earw & mask)); + } else { + GetEAa;Bit16u old=LoadMw(eaa); + SETFLAGBIT(CF,(old & mask)); + } + if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + break; + } + CASE_0F_W(0xa4) /* SHLD Ew,Gw,Ib */ + RMEwGwOp3(DSHLW,Fetchb()); + break; + CASE_0F_W(0xa5) /* SHLD Ew,Gw,CL */ + RMEwGwOp3(DSHLW,reg_cl); + break; + CASE_0F_W(0xa8) /* PUSH GS */ + Push_16(SegValue(gs));break; + CASE_0F_W(0xa9) /* POP GS */ + CPU_SetSegGeneral(gs,Pop_16());break; + CASE_0F_W(0xab) /* BTS Ew,Gw */ + { + GetRMrw; + Bit16u mask=1 << (*rmrw & 15); + if (rm >= 0xc0 ) { + GetEArw; + SETFLAGBIT(CF,(*earw & mask)); + *earw|=mask; + } else { + GetEAa;Bit16u old=LoadMw(eaa); + SETFLAGBIT(CF,(old & mask)); + SaveMw(eaa,old | mask); + } + if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + break; + } + CASE_0F_W(0xac) /* SHRD Ew,Gw,Ib */ + RMEwGwOp3(DSHRW,Fetchb()); + break; + CASE_0F_W(0xad) /* SHRD Ew,Gw,CL */ + RMEwGwOp3(DSHRW,reg_cl); + break; + CASE_0F_W(0xaf) /* IMUL Gw,Ew */ + RMGwEwOp3(DIMULW,*rmrw); + break; + CASE_0F_W(0xb2) /* LSS Ew */ + { + GetRMrw;GetEAa; + *rmrw=LoadMw(eaa);CPU_SetSegGeneral(ss,LoadMw(eaa+2)); + break; + } + CASE_0F_W(0xb3) /* BTR Ew,Gw */ + { + GetRMrw; + Bit16u mask=1 << (*rmrw & 15); + if (rm >= 0xc0 ) { + GetEArw; + SETFLAGBIT(CF,(*earw & mask)); + *earw&= ~mask; + } else { + GetEAa;Bit16u old=LoadMw(eaa); + SETFLAGBIT(CF,(old & mask)); + SaveMw(eaa,old & ~mask); + } + if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + break; + } + CASE_0F_W(0xb4) /* LFS Ew */ + { + GetRMrw;GetEAa; + *rmrw=LoadMw(eaa);CPU_SetSegGeneral(fs,LoadMw(eaa+2)); + break; + } + CASE_0F_W(0xb5) /* LGS Ew */ + { + GetRMrw;GetEAa; + *rmrw=LoadMw(eaa);CPU_SetSegGeneral(gs,LoadMw(eaa+2)); + break; + } + CASE_0F_W(0xb6) /* MOVZX Gw,Eb */ + { + GetRMrw; + if (rm >= 0xc0 ) {GetEArb;*rmrw=*earb;} + else {GetEAa;*rmrw=LoadMb(eaa);} + break; + } + CASE_0F_W(0xb7) /* MOVZX Gw,Ew */ + CASE_0F_W(0xbf) /* MOVSX Gw,Ew */ + { + GetRMrw; + if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;} + else {GetEAa;*rmrw=LoadMw(eaa);} + break; + } + CASE_0F_W(0xba) /* GRP8 Ew,Ib */ + { + GetRM; + if (rm >= 0xc0 ) { + GetEArw; + Bit16u mask=1 << (Fetchb() & 15); + SETFLAGBIT(CF,(*earw & mask)); + switch (rm & 0x38) { + case 0x20: /* BT */ + break; + case 0x28: /* BTS */ + *earw|=mask; + break; + case 0x30: /* BTR */ + *earw&= ~mask; + break; + case 0x38: /* BTC */ + *earw^=mask; + break; + default: + E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38); + } + } else { + GetEAa;Bit16u old=LoadMw(eaa); + Bit16u mask=1 << (Fetchb() & 15); + SETFLAGBIT(CF,(old & mask)); + switch (rm & 0x38) { + case 0x20: /* BT */ + break; + case 0x28: /* BTS */ + SaveMw(eaa,old|mask); + break; + case 0x30: /* BTR */ + SaveMw(eaa,old & ~mask); + break; + case 0x38: /* BTC */ + SaveMw(eaa,old ^ mask); + break; + default: + E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38); + } + } + if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + break; + } + CASE_0F_W(0xbb) /* BTC Ew,Gw */ + { + GetRMrw; + Bit16u mask=1 << (*rmrw & 15); + if (rm >= 0xc0 ) { + GetEArw; + SETFLAGBIT(CF,(*earw & mask)); + *earw^=mask; + } else { + GetEAa;Bit16u old=LoadMw(eaa); + SETFLAGBIT(CF,(old & mask)); + SaveMw(eaa,old ^ mask); + } + if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + break; + } + CASE_0F_W(0xbc) /* BSF Gw,Ew */ + { + GetRMrw; + Bit16u result,value; + if (rm >= 0xc0) { GetEArw; value=*earw; } + else { GetEAa; value=LoadMw(eaa); } + if (value==0) { + SETFLAGBIT(ZF,true); + } else { + result = 0; + while ((value & 0x01)==0) { result++; value>>=1; } + SETFLAGBIT(ZF,false); + *rmrw = result; + } + flags.type=t_UNKNOWN; + break; + } + CASE_0F_W(0xbd) /* BSR Gw,Ew */ + { + GetRMrw; + Bit16u result,value; + if (rm >= 0xc0) { GetEArw; value=*earw; } + else { GetEAa; value=LoadMw(eaa); } + if (value==0) { + SETFLAGBIT(ZF,true); + } else { + result = 15; // Operandsize-1 + while ((value & 0x8000)==0) { result--; value<<=1; } + SETFLAGBIT(ZF,false); + *rmrw = result; + } + flags.type=t_UNKNOWN; + break; + } + CASE_0F_W(0xbe) /* MOVSX Gw,Eb */ + { + GetRMrw; + if (rm >= 0xc0 ) {GetEArb;*rmrw=*(Bit8s *)earb;} + else {GetEAa;*rmrw=LoadMbs(eaa);} + break; + } + CASE_0F_B(0xc8) /* BSWAP EAX */ + BSWAP(reg_eax);break; + CASE_0F_B(0xc9) /* BSWAP ECX */ + BSWAP(reg_ecx);break; + CASE_0F_B(0xca) /* BSWAP EDX */ + BSWAP(reg_edx);break; + CASE_0F_B(0xcb) /* BSWAP EBX */ + BSWAP(reg_ebx);break; + CASE_0F_B(0xcc) /* BSWAP ESP */ + BSWAP(reg_esp);break; + CASE_0F_B(0xcd) /* BSWAP EBP */ + BSWAP(reg_ebp);break; + CASE_0F_B(0xce) /* BSWAP ESI */ + BSWAP(reg_esi);break; + CASE_0F_B(0xcf) /* BSWAP EDI */ + BSWAP(reg_edi);break; + diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h new file mode 100644 index 00000000..7f769ef5 --- /dev/null +++ b/src/cpu/core_normal/prefix_66.h @@ -0,0 +1,611 @@ +/* + * 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. + */ + + CASE_D(0x01) /* ADD Ed,Gd */ + RMEdGd(ADDD);break; + CASE_D(0x03) /* ADD Gd,Ed */ + RMGdEd(ADDD);break; + CASE_D(0x05) /* ADD EAX,Id */ + EAXId(ADDD);break; + CASE_D(0x06) /* PUSH ES */ + Push_32(SegValue(es));break; + CASE_D(0x07) /* POP ES */ + CPU_SetSegGeneral(es,(Bit16u)Pop_32());break; + CASE_D(0x09) /* OR Ed,Gd */ + RMEdGd(ORD);break; + CASE_D(0x0b) /* OR Gd,Ed */ + RMGdEd(ORD);break; + CASE_D(0x0d) /* OR EAX,Id */ + EAXId(ORD);break; + CASE_D(0x0e) /* PUSH CS */ + Push_32(SegValue(cs));break; + CASE_D(0x11) /* ADC Ed,Gd */ + RMEdGd(ADCD);break; + CASE_D(0x13) /* ADC Gd,Ed */ + RMGdEd(ADCD);break; + CASE_D(0x15) /* ADC EAX,Id */ + EAXId(ADCD);break; + CASE_D(0x16) /* PUSH SS */ + Push_32(SegValue(ss));break; + CASE_D(0x17) /* POP SS */ + CPU_SetSegGeneral(ss,(Bit16u)Pop_32());break; + CASE_D(0x19) /* SBB Ed,Gd */ + RMEdGd(SBBD);break; + CASE_D(0x1b) /* SBB Gd,Ed */ + RMGdEd(SBBD);break; + CASE_D(0x1d) /* SBB EAX,Id */ + EAXId(SBBD);break; + CASE_D(0x1e) /* PUSH DS */ + Push_32(SegValue(ds));break; + CASE_D(0x1f) /* POP DS */ + CPU_SetSegGeneral(ds,(Bit16u)Pop_32());break; + CASE_D(0x21) /* AND Ed,Gd */ + RMEdGd(ANDD);break; + CASE_D(0x23) /* AND Gd,Ed */ + RMGdEd(ANDD);break; + CASE_D(0x25) /* AND EAX,Id */ + EAXId(ANDD);break; + CASE_D(0x29) /* SUB Ed,Gd */ + RMEdGd(SUBD);break; + CASE_D(0x2b) /* SUB Gd,Ed */ + RMGdEd(SUBD);break; + CASE_D(0x2d) /* SUB EAX,Id */ + EAXId(SUBD);break; + CASE_D(0x31) /* XOR Ed,Gd */ + RMEdGd(XORD);break; + CASE_D(0x33) /* XOR Gd,Ed */ + RMGdEd(XORD);break; + CASE_D(0x35) /* XOR EAX,Id */ + EAXId(XORD);break; + CASE_D(0x39) /* CMP Ed,Gd */ + RMEdGd(CMPD);break; + CASE_D(0x3b) /* CMP Gd,Ed */ + RMGdEd(CMPD);break; + CASE_D(0x3d) /* CMP EAX,Id */ + EAXId(CMPD);break; + CASE_D(0x40) /* INC EAX */ + INCD(reg_eax,LoadRd,SaveRd);break; + CASE_D(0x41) /* INC ECX */ + INCD(reg_ecx,LoadRd,SaveRd);break; + CASE_D(0x42) /* INC EDX */ + INCD(reg_edx,LoadRd,SaveRd);break; + CASE_D(0x43) /* INC EBX */ + INCD(reg_ebx,LoadRd,SaveRd);break; + CASE_D(0x44) /* INC ESP */ + INCD(reg_esp,LoadRd,SaveRd);break; + CASE_D(0x45) /* INC EBP */ + INCD(reg_ebp,LoadRd,SaveRd);break; + CASE_D(0x46) /* INC ESI */ + INCD(reg_esi,LoadRd,SaveRd);break; + CASE_D(0x47) /* INC EDI */ + INCD(reg_edi,LoadRd,SaveRd);break; + CASE_D(0x48) /* DEC EAX */ + DECD(reg_eax,LoadRd,SaveRd);break; + CASE_D(0x49) /* DEC ECX */ + DECD(reg_ecx,LoadRd,SaveRd);break; + CASE_D(0x4a) /* DEC EDX */ + DECD(reg_edx,LoadRd,SaveRd);break; + CASE_D(0x4b) /* DEC EBX */ + DECD(reg_ebx,LoadRd,SaveRd);break; + CASE_D(0x4c) /* DEC ESP */ + DECD(reg_esp,LoadRd,SaveRd);break; + CASE_D(0x4d) /* DEC EBP */ + DECD(reg_ebp,LoadRd,SaveRd);break; + CASE_D(0x4e) /* DEC ESI */ + DECD(reg_esi,LoadRd,SaveRd);break; + CASE_D(0x4f) /* DEC EDI */ + DECD(reg_edi,LoadRd,SaveRd);break; + CASE_D(0x50) /* PUSH EAX */ + Push_32(reg_eax);break; + CASE_D(0x51) /* PUSH ECX */ + Push_32(reg_ecx);break; + CASE_D(0x52) /* PUSH EDX */ + Push_32(reg_edx);break; + CASE_D(0x53) /* PUSH EBX */ + Push_32(reg_ebx);break; + CASE_D(0x54) /* PUSH ESP */ + Push_32(reg_esp);break; + CASE_D(0x55) /* PUSH EBP */ + Push_32(reg_ebp);break; + CASE_D(0x56) /* PUSH ESI */ + Push_32(reg_esi);break; + CASE_D(0x57) /* PUSH EDI */ + Push_32(reg_edi);break; + CASE_D(0x58) /* POP EAX */ + reg_eax=Pop_32();break; + CASE_D(0x59) /* POP ECX */ + reg_ecx=Pop_32();break; + CASE_D(0x5a) /* POP EDX */ + reg_edx=Pop_32();break; + CASE_D(0x5b) /* POP EBX */ + reg_ebx=Pop_32();break; + CASE_D(0x5c) /* POP ESP */ + reg_esp=Pop_32();break; + CASE_D(0x5d) /* POP EBP */ + reg_ebp=Pop_32();break; + CASE_D(0x5e) /* POP ESI */ + reg_esi=Pop_32();break; + CASE_D(0x5f) /* POP EDI */ + reg_edi=Pop_32();break; + CASE_D(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_D(0x61) /* POPAD */ + reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP + reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32(); + break; + CASE_D(0x68) /* PUSH Id */ + Push_32(Fetchd());break; + CASE_D(0x69) /* IMUL Gd,Ed,Id */ + RMGdEdOp3(DIMULD,Fetchds()); + break; + CASE_D(0x6a) /* PUSH Ib */ + Push_32(Fetchbs());break; + CASE_D(0x6b) /* IMUL Gd,Ed,Ib */ + RMGdEdOp3(DIMULD,Fetchbs()); + break; + CASE_D(0x81) /* Grpl Ed,Id */ + { + GetRM;Bitu which=(rm>>3)&7; + if (rm >= 0xc0) { + GetEArd;Bit32u id=Fetchd(); + switch (which) { + case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break; + case 0x01: ORD(*eard,id,LoadRd,SaveRd);break; + case 0x02:ADCD(*eard,id,LoadRd,SaveRd);break; + case 0x03:SBBD(*eard,id,LoadRd,SaveRd);break; + case 0x04:ANDD(*eard,id,LoadRd,SaveRd);break; + case 0x05:SUBD(*eard,id,LoadRd,SaveRd);break; + case 0x06:XORD(*eard,id,LoadRd,SaveRd);break; + case 0x07:CMPD(*eard,id,LoadRd,SaveRd);break; + } + } else { + GetEAa;Bit32u id=Fetchd(); + switch (which) { + case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break; + case 0x01: ORD(eaa,id,LoadMd,SaveMd);break; + case 0x02:ADCD(eaa,id,LoadMd,SaveMd);break; + case 0x03:SBBD(eaa,id,LoadMd,SaveMd);break; + case 0x04:ANDD(eaa,id,LoadMd,SaveMd);break; + case 0x05:SUBD(eaa,id,LoadMd,SaveMd);break; + case 0x06:XORD(eaa,id,LoadMd,SaveMd);break; + case 0x07:CMPD(eaa,id,LoadMd,SaveMd);break; + } + } + } + break; + CASE_D(0x83) /* Grpl Ed,Ix */ + { + GetRM;Bitu which=(rm>>3)&7; + if (rm >= 0xc0) { + GetEArd;Bit32u id=(Bit32s)Fetchbs(); + switch (which) { + case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break; + case 0x01: ORD(*eard,id,LoadRd,SaveRd);break; + case 0x02:ADCD(*eard,id,LoadRd,SaveRd);break; + case 0x03:SBBD(*eard,id,LoadRd,SaveRd);break; + case 0x04:ANDD(*eard,id,LoadRd,SaveRd);break; + case 0x05:SUBD(*eard,id,LoadRd,SaveRd);break; + case 0x06:XORD(*eard,id,LoadRd,SaveRd);break; + case 0x07:CMPD(*eard,id,LoadRd,SaveRd);break; + } + } else { + GetEAa;Bit32u id=(Bit32s)Fetchbs(); + switch (which) { + case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break; + case 0x01: ORD(eaa,id,LoadMd,SaveMd);break; + case 0x02:ADCD(eaa,id,LoadMd,SaveMd);break; + case 0x03:SBBD(eaa,id,LoadMd,SaveMd);break; + case 0x04:ANDD(eaa,id,LoadMd,SaveMd);break; + case 0x05:SUBD(eaa,id,LoadMd,SaveMd);break; + case 0x06:XORD(eaa,id,LoadMd,SaveMd);break; + case 0x07:CMPD(eaa,id,LoadMd,SaveMd);break; + } + } + } + break; + CASE_D(0x85) /* TEST Ed,Gd */ + RMEdGd(TESTD);break; + CASE_D(0x87) /* XCHG Ed,Gd */ + { + GetRMrd;Bit32u oldrmrd=*rmrd; + if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;*eard=oldrmrd;} + else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,oldrmrd);} + break; + } + CASE_D(0x89) /* MOV Ed,Gd */ + { + GetRMrd; + if (rm >= 0xc0 ) {GetEArd;*eard=*rmrd;} + else {GetEAa;SaveMd(eaa,*rmrd);} + break; + } + CASE_D(0x8b) /* MOV Gd,Ed */ + { + GetRMrd; + if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;} + else {GetEAa;*rmrd=LoadMd(eaa);} + break; + } + CASE_D(0x8c) /* Mov Ew,Sw */ + { + GetRM;Bit16u val;Bitu which=(rm>>3)&7; + switch (which) { + case 0x00: /* MOV Ew,ES */ + val=SegValue(es);break; + case 0x01: /* MOV Ew,CS */ + val=SegValue(cs);break; + case 0x02: /* MOV Ew,SS */ + val=SegValue(ss);break; + case 0x03: /* MOV Ew,DS */ + val=SegValue(ds);break; + case 0x04: /* MOV Ew,FS */ + val=SegValue(fs);break; + case 0x05: /* MOV Ew,GS */ + val=SegValue(gs);break; + default: + val=0; + E_Exit("CPU:8c:Illegal RM Byte"); + } + if (rm >= 0xc0 ) {GetEArd;*eard=val;} + else {GetEAa;SaveMd(eaa,val);} + break; + } + CASE_D(0x8d) /* LEA Gd */ + { + //Little hack to always use segprefixed version + core.seg_prefix_base=0; + GetRMrd; + if (TEST_PREFIX_ADDR) { + *rmrd=(Bit32u)(*GetEA_SEG_ADDR[rm])(); + } else { + *rmrd=(Bit32u)(*GetEA_SEG[rm])(); + } + break; + } + CASE_D(0x8f) /* POP Ed */ + { + GetRM; + if (rm >= 0xc0 ) {GetEArd;*eard=Pop_32();} + else {GetEAa;SaveMd(eaa,Pop_32());} + break; + } + CASE_D(0x91) /* XCHG ECX,EAX */ + { Bit32u temp=reg_eax;reg_eax=reg_ecx;reg_ecx=temp;break;} + CASE_D(0x92) /* XCHG EDX,EAX */ + { Bit32u temp=reg_eax;reg_eax=reg_edx;reg_edx=temp;break;} + break; + CASE_D(0x93) /* XCHG EBX,EAX */ + { Bit32u temp=reg_eax;reg_eax=reg_ebx;reg_ebx=temp;break;} + break; + CASE_D(0x94) /* XCHG ESP,EAX */ + { Bit32u temp=reg_eax;reg_eax=reg_esp;reg_esp=temp;break;} + break; + CASE_D(0x95) /* XCHG EBP,EAX */ + { Bit32u temp=reg_eax;reg_eax=reg_ebp;reg_ebp=temp;break;} + break; + CASE_D(0x96) /* XCHG ESI,EAX */ + { Bit32u temp=reg_eax;reg_eax=reg_esi;reg_esi=temp;break;} + break; + CASE_D(0x97) /* XCHG EDI,EAX */ + { Bit32u temp=reg_eax;reg_eax=reg_edi;reg_edi=temp;break;} + break; + CASE_D(0x98) /* CWDE */ + reg_eax=(Bit16s)reg_ax;break; + CASE_D(0x99) /* CDQ */ + if (reg_eax & 0x80000000) reg_edx=0xffffffff; + else reg_edx=0; + break; + CASE_D(0x9c) /* PUSHFD */ + FillFlags(); + Push_32(flags.word); + break; + CASE_D(0x9d) /* POPFD */ + SETFLAGSd(Pop_32()) +#if CPU_TRAP_CHECK + if (GETFLAG(TF)) { + cpudecoder=CPU_Core_Normal_Decode_Trap; + goto decode_end; + } +#endif +#ifdef CPU_PIC_CHECK + if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; +#endif + + break; + CASE_D(0xa1) /* MOV EAX,Od */ + { + GetEADirect; + reg_eax=LoadMd(eaa); + } + break; + CASE_D(0xa3) /* MOV Od,EAX */ + { + GetEADirect; + SaveMd(eaa,reg_eax); + } + break; + CASE_D(0xa5) /* MOVSD */ + DoString(R_MOVSD);break; + CASE_D(0xa7) /* CMPSD */ + DoString(R_CMPSD);break; + CASE_D(0xa9) /* TEST EAX,Id */ + EAXId(TESTD);break; + CASE_D(0xab) /* STOSD */ + DoString(R_STOSD);break; + CASE_D(0xad) /* LODSD */ + DoString(R_LODSD);break; + CASE_D(0xaf) /* SCASD */ + DoString(R_SCASD);break; + CASE_D(0xb8) /* MOV EAX,Id */ + reg_eax=Fetchd();break; + CASE_D(0xb9) /* MOV ECX,Id */ + reg_ecx=Fetchd();break; + CASE_D(0xba) /* MOV EDX,Iw */ + reg_edx=Fetchd();break; + CASE_D(0xbb) /* MOV EBX,Id */ + reg_ebx=Fetchd();break; + CASE_D(0xbc) /* MOV ESP,Id */ + reg_esp=Fetchd();break; + CASE_D(0xbd) /* MOV EBP.Id */ + reg_ebp=Fetchd();break; + CASE_D(0xbe) /* MOV ESI,Id */ + reg_esi=Fetchd();break; + CASE_D(0xbf) /* MOV EDI,Id */ + reg_edi=Fetchd();break; + CASE_D(0xc1) /* GRP2 Ed,Ib */ + GRP2D(Fetchb());break; + CASE_D(0xc2) /* RETN Iw */ + { + Bit16u addsp=Fetchw(); + SETIP(Pop_32());reg_esp+=addsp; + break; + } + CASE_D(0xc3) /* RETN */ + SETIP(Pop_32()); + break; + CASE_D(0xc4) /* LES */ + { + GetRMrd;GetEAa; + *rmrd=LoadMd(eaa);CPU_SetSegGeneral(es,LoadMw(eaa+4)); + break; + } + CASE_D(0xc5) /* LDS */ + { + GetRMrd;GetEAa; + *rmrd=LoadMd(eaa);CPU_SetSegGeneral(ds,LoadMw(eaa+4)); + break; + } + CASE_D(0xc7) /* MOV Ed,Id */ + { + GetRM; + if (rm >= 0xc0) {GetEArd;*eard=Fetchd();} + else {GetEAa;SaveMd(eaa,Fetchd());} + break; + } + CASE_D(0xc8) /* ENTER Iw,Ib */ + { + Bitu bytes=Fetchw();Bitu level=Fetchb() & 0x1f; + Bitu frame_ptr=reg_esp-4; + if (cpu.stack.big) { + reg_esp-=4; + mem_writed(SegBase(ss)+reg_esp,reg_ebp); + for (Bitu i=1;i>0)); + IO_Write(reg_dx+1,(Bit8u)(reg_eax>>8)); + IO_Write(reg_dx+2,(Bit8u)(reg_eax>>16)); + IO_Write(reg_dx+3,(Bit8u)(reg_eax>>24)); + break; + CASE_D(0xf7) /* GRP3 Ed(,Id) */ + { + GetRM;Bitu which=(rm>>3)&7; + switch (which) { + case 0x00: /* TEST Ed,Id */ + case 0x01: /* TEST Ed,Id Undocumented*/ + { + if (rm >= 0xc0 ) {GetEArd;TESTD(*eard,Fetchd(),LoadRd,SaveRd);} + else {GetEAa;TESTD(eaa,Fetchd(),LoadMd,SaveMd);} + break; + } + case 0x02: /* NOT Ed */ + { + if (rm >= 0xc0 ) {GetEArd;*eard=~*eard;} + else {GetEAa;SaveMd(eaa,~LoadMd(eaa));} + break; + } + case 0x03: /* NEG Ed */ + { + flags.type=t_NEGd; + if (rm >= 0xc0 ) { + GetEArd;flags.var1.d=*eard;flags.result.d=0-flags.var1.d; + *eard=flags.result.d; + } else { + GetEAa;flags.var1.d=LoadMd(eaa);flags.result.d=0-flags.var1.d; + SaveMd(eaa,flags.result.d); + } + break; + } + case 0x04: /* MUL EAX,Ed */ + RMEd(MULD); + break; + case 0x05: /* IMUL EAX,Ed */ + RMEd(IMULD); + break; + case 0x06: /* DIV Ed */ + RMEd(DIVD); + break; + case 0x07: /* IDIV Ed */ + RMEd(IDIVD); + break; + } + break; + } + CASE_D(0xff) /* GRP 5 Ed */ + { + GetRM;Bitu which=(rm>>3)&7; + switch (which) { + case 0x00: /* INC Ed */ + RMEd(INCD); + break; + case 0x01: /* DEC Ed */ + RMEd(DECD); + break; + case 0x02: /* CALL NEAR Ed */ + if (rm >= 0xc0 ) {GetEArd;Push_32(GETIP);SETIP(*eard);} + else {GetEAa;Push_32(GETIP);SETIP(LoadMd(eaa));} + break; + case 0x03: /* CALL FAR Ed */ + { + GetEAa; + Bit32u newip=LoadMd(eaa); + Bit16u newcs=LoadMw(eaa+4); + SAVEIP; + if (CPU_CALL(true,newcs,newip)) { + LOADIP; + } else { + FillFlags();return CBRET_NONE; + } + } + break; + case 0x04: /* JMP NEAR Ed */ + if (rm >= 0xc0 ) {GetEArd;SETIP(*eard);} + else {GetEAa;SETIP(LoadMd(eaa));} + break; + case 0x05: /* JMP FAR Ed */ + { + GetEAa; + Bit32u newip=LoadMd(eaa); + Bit16u newcs=LoadMw(eaa+4); + SAVEIP; + if (CPU_JMP(true,newcs,newip)) { + LOADIP; + } else { + FillFlags();return CBRET_NONE; + } + } + break; + case 0x06: /* 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",which); + break; + } + break; + } + + diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h new file mode 100644 index 00000000..d24ebc8a --- /dev/null +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -0,0 +1,370 @@ +/* + * 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. + */ + CASE_0F_D(0x00) /* GRP 6 Exxx */ + { + GetRM;Bitu which=(rm>>3)&7; + switch (which) { + case 0x00: /* SLDT */ + case 0x01: /* STR */ + { + Bitu saveval; + if (!which) CPU_SLDT(saveval); + else CPU_STR(saveval); + if (rm >= 0xc0) {GetEArd;*eard=saveval;} + else {GetEAa;SaveMd(eaa,saveval);} + } + break; + case 0x02:case 0x03:case 0x04:case 0x05: + { + /* Just use 16-bit loads since were only using selectors */ + FillFlags(); + Bitu loadval; + if (rm >= 0xc0 ) {GetEArw;loadval=*earw;} + else {GetEAa;loadval=LoadMw(eaa);} + break; + switch (which) { + case 0x02:CPU_LLDT(loadval);break; + case 0x03:CPU_LTR(loadval);break; + case 0x04:CPU_VERR(loadval);break; + case 0x05:CPU_VERW(loadval);break; + } + } + default: + LOG(LOG_CPU,LOG_ERROR)("GRP6:Illegal call %2X",which); + } + } + break; + CASE_0F_D(0x01) /* Group 7 Ed */ + { + GetRM;Bitu which=(rm>>3)&7; + if (rm < 0xc0) { //First ones all use EA + GetEAa;Bitu limit,base; + switch (which) { + case 0x00: /* SGDT */ + CPU_SGDT(limit,base); + SaveMw(eaa,limit); + SaveMd(eaa+2,base); + break; + case 0x01: /* SIDT */ + CPU_SIDT(limit,base); + SaveMw(eaa,limit); + SaveMd(eaa+2,base); + break; + case 0x02: /* LGDT */ + CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2)); + break; + case 0x03: /* LIDT */ + CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2)); + break; + case 0x04: /* SMSW */ + CPU_SMSW(limit); + SaveMw(eaa,limit); + break; + case 0x06: /* LMSW */ + limit=LoadMw(eaa); + if (!CPU_LMSW(limit)) goto decode_end; + break; + } + } else { + GetEArw;Bitu limit; + switch (which) { + case 0x04: /* SMSW */ + CPU_SMSW(limit); + *earw=limit; + break; + case 0x06: /* LMSW */ + if (!CPU_LMSW(*earw)) goto decode_end; + break; + default: + LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which); + break; + } + + } + } + break; + CASE_0F_D(0x02) /* LAR Gd,Ed */ + { + FillFlags(); + GetRMrd;Bitu ar; + if (rm >= 0xc0) { + GetEArw;CPU_LAR(*earw,ar); + } else { + GetEAa;CPU_LAR(LoadMw(eaa),ar); + } + *rmrd=(Bit32u)ar; + } + break; + CASE_0F_D(0x03) /* LSL Gd,Ew */ + { + FillFlags(); + GetRMrd;Bitu limit; + /* Just load 16-bit values for selectors */ + if (rm >= 0xc0) { + GetEArw;CPU_LSL(*earw,limit); + } else { + GetEAa;CPU_LSL(LoadMw(eaa),limit); + } + *rmrd=(Bit16u)limit; + } + break; + CASE_0F_D(0x80) /* JO */ + JumpSId(get_OF());break; + CASE_0F_D(0x81) /* JNO */ + JumpSId(!get_OF());break; + CASE_0F_D(0x82) /* JB */ + JumpSId(get_CF());break; + CASE_0F_D(0x83) /* JNB */ + JumpSId(!get_CF());break; + CASE_0F_D(0x84) /* JZ */ + JumpSId(get_ZF());break; + CASE_0F_D(0x85) /* JNZ */ + JumpSId(!get_ZF());break; + CASE_0F_D(0x86) /* JBE */ + JumpSId(get_CF() || get_ZF());break; + CASE_0F_D(0x87) /* JNBE */ + JumpSId(!get_CF() && !get_ZF());break; + CASE_0F_D(0x88) /* JS */ + JumpSId(get_SF());break; + CASE_0F_D(0x89) /* JNS */ + JumpSId(!get_SF());break; + CASE_0F_D(0x8a) /* JP */ + JumpSId(get_PF());break; + CASE_0F_D(0x8b) /* JNP */ + JumpSId(!get_PF());break; + CASE_0F_D(0x8c) /* JL */ + JumpSId(get_SF() != get_OF());break; + CASE_0F_D(0x8d) /* JNL */ + JumpSId(get_SF() == get_OF());break; + CASE_0F_D(0x8e) /* JLE */ + JumpSId(get_ZF() || (get_SF() != get_OF()));break; + CASE_0F_D(0x8f) /* JNLE */ + JumpSId((get_SF() == get_OF()) && !get_ZF());break; + + CASE_0F_D(0xa0) /* PUSH FS */ + Push_32(SegValue(fs));break; + CASE_0F_D(0xa1) /* POP FS */ + CPU_SetSegGeneral(fs,(Bit16u)Pop_32());break; + + CASE_0F_D(0xa3) /* BT Ed,Gd */ + { + GetRMrd; + Bit32u mask=1 << (*rmrd & 31); + if (rm >= 0xc0 ) { + GetEArd; + SETFLAGBIT(CF,(*eard & mask)); + } else { + GetEAa;Bit32u old=LoadMd(eaa); + SETFLAGBIT(CF,(old & mask)); + } + if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + break; + } + CASE_0F_D(0xa4) /* SHLD Ed,Gd,Ib */ + { + GetRMrd; + if (rm >= 0xc0 ) {GetEArd;DSHLD(*eard,*rmrd,Fetchb(),LoadRd,SaveRd);} + else {GetEAa;DSHLD(eaa,*rmrd,Fetchb(),LoadMd,SaveMd);} + break; + } + + CASE_0F_D(0xa8) /* PUSH GS */ + Push_32(SegValue(gs));break; + CASE_0F_D(0xa9) /* POP GS */ + CPU_SetSegGeneral(gs,(Bit16u)Pop_32());break; + CASE_0F_D(0xab) /* BTS Ed,Gd */ + { + GetRMrd; + Bit32u mask=1 << (*rmrd & 31); + if (rm >= 0xc0 ) { + GetEArd; + SETFLAGBIT(CF,(*eard & mask)); + *eard|=mask; + } else { + GetEAa;Bit32u old=LoadMd(eaa); + SETFLAGBIT(CF,(old & mask)); + SaveMd(eaa,old | mask); + } + if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + break; + } + + CASE_0F_D(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_0F_D(0xad) /* SHRD Ed,Gd,Cl */ + { + GetRMrd; + if (rm >= 0xc0 ) {GetEArd;DSHRD(*eard,*rmrd,reg_cl,LoadRd,SaveRd);} + else {GetEAa;DSHRD(eaa,*rmrd,reg_cl,LoadMd,SaveMd);} + break; + } + CASE_0F_D(0xb4) /* LFS Ed */ + { + GetRMrd;GetEAa; + *rmrd=LoadMd(eaa);CPU_SetSegGeneral(fs,LoadMw(eaa+4)); + break; + } + CASE_0F_D(0xb5) /* LGS Ed */ + { + GetRMrd;GetEAa; + *rmrd=LoadMd(eaa);CPU_SetSegGeneral(gs,LoadMw(eaa+4)); + break; + } + CASE_0F_D(0xb6) /* MOVZX Gd,Eb */ + { + GetRMrd; + if (rm >= 0xc0 ) {GetEArb;*rmrd=*earb;} + else {GetEAa;*rmrd=LoadMb(eaa);} + break; + } + CASE_0F_D(0xaf) /* IMUL Gd,Ed */ + { + RMGdEdOp3(DIMULD,*rmrd); + break; + } + CASE_0F_D(0xb2) /* LSS Ed */ + { + GetRMrd;GetEAa; + *rmrd=LoadMd(eaa);CPU_SetSegGeneral(ss,LoadMw(eaa+4)); + break; + } + CASE_0F_D(0xb7) /* MOVXZ Gd,Ew */ + { + GetRMrd; + if (rm >= 0xc0 ) {GetEArw;*rmrd=*earw;} + else {GetEAa;*rmrd=LoadMw(eaa);} + break; + } + CASE_0F_D(0xba) /* GRP8 Ed,Ib */ + { + GetRM; + if (rm >= 0xc0 ) { + GetEArd; + Bit32u mask=1 << (Fetchb() & 31); + SETFLAGBIT(CF,(*eard & mask)); + switch (rm & 0x38) { + case 0x20: /* BT */ + break; + case 0x28: /* BTS */ + *eard|=mask; + break; + case 0x30: /* BTR */ + *eard&=~mask; + break; + case 0x38: /* BTC */ + if (GETFLAG(CF)) *eard&=~mask; + else *eard|=mask; + break; + default: + E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38); + } + } else { + GetEAa;Bit32u old=LoadMd(eaa); + Bit32u mask=1 << (Fetchb() & 31); + SETFLAGBIT(CF,(old & mask)); + switch (rm & 0x38) { + case 0x20: /* BT */ + break; + case 0x28: /* BTS */ + SaveMd(eaa,old|mask); + break; + case 0x30: /* BTR */ + SaveMd(eaa,old & ~mask); + break; + case 0x38: /* BTC */ + if (GETFLAG(CF)) old&=~mask; + else old|=mask; + SaveMd(eaa,old); + break; + default: + E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38); + } + } + if (flags.type!=t_CF) flags.prev_type=flags.type; + flags.type=t_CF; + break; + } + CASE_0F_D(0xbb) /* BTC Ed,Gd */ + { + GetRMrd; + Bit32u mask=1 << (*rmrd & 31); + if (rm >= 0xc0 ) { + GetEArd; + SETFLAGBIT(CF,(*eard & mask)); + *eard^=mask; + } else { + GetEAa;Bit32u old=LoadMd(eaa); + SETFLAGBIT(CF,(old & mask)); + SaveMd(eaa,old ^ mask); + } + if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + break; + } + CASE_0F_D(0xbc) /* BSF Gd,Ed */ + { + GetRMrd; + Bit32u result,value; + if (rm >= 0xc0) { GetEArd; value=*eard; } + else { GetEAa; value=LoadMd(eaa); } + if (value==0) { + SETFLAGBIT(ZF,true); + } else { + result = 0; + while ((value & 0x01)==0) { result++; value>>=1; } + SETFLAGBIT(ZF,false); + *rmrd = result; + } + flags.type=t_UNKNOWN; + break; + } + CASE_0F_D(0xbd) /* BSR Gd,Ed */ + { + GetRMrd; + Bit32u result,value; + if (rm >= 0xc0) { GetEArd; value=*eard; } + else { GetEAa; value=LoadMd(eaa); } + if (value==0) { + SETFLAGBIT(ZF,true); + } else { + result = 35; // Operandsize-1 + while ((value & 0x80000000)==0) { result--; value<<=1; } + SETFLAGBIT(ZF,false); + *rmrd = result; + } + flags.type=t_UNKNOWN; + break; + } + CASE_0F_D(0xbe) /* MOVSX Gd,Eb */ + { + GetRMrd; + if (rm >= 0xc0 ) {GetEArb;*rmrd=*(Bit8s *)earb;} + else {GetEAa;*rmrd=LoadMbs(eaa);} + break; + } + CASE_0F_D(0xbf) /* MOVSX Gd,Ew */ + { + GetRMrd; + if (rm >= 0xc0 ) {GetEArw;*rmrd=*(Bit16s *)earw;} + else {GetEAa;*rmrd=LoadMws(eaa);} + break; + } diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h new file mode 100644 index 00000000..0e40cd8c --- /dev/null +++ b/src/cpu/core_normal/prefix_none.h @@ -0,0 +1,1171 @@ +/* + * 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. + */ + + CASE_B(0x00) /* ADD Eb,Gb */ + RMEbGb(ADDB);break; + CASE_W(0x01) /* ADD Ew,Gw */ + RMEwGw(ADDW);break; + CASE_B(0x02) /* ADD Gb,Eb */ + RMGbEb(ADDB);break; + CASE_W(0x03) /* ADD Gw,Ew */ + RMGwEw(ADDW);break; + CASE_B(0x04) /* ADD AL,Ib */ + ALIb(ADDB);break; + CASE_W(0x05) /* ADD AX,Iw */ + AXIw(ADDW);break; + CASE_W(0x06) /* PUSH ES */ + Push_16(SegValue(es));break; + CASE_W(0x07) /* POP ES */ + CPU_SetSegGeneral(es,Pop_16());break; + CASE_B(0x08) /* OR Eb,Gb */ + RMEbGb(ORB);break; + CASE_W(0x09) /* OR Ew,Gw */ + RMEwGw(ORW);break; + CASE_B(0x0a) /* OR Gb,Eb */ + RMGbEb(ORB);break; + CASE_W(0x0b) /* OR Gw,Ew */ + RMGwEw(ORW);break; + CASE_B(0x0c) /* OR AL,Ib */ + ALIb(ORB);break; + CASE_W(0x0d) /* OR AX,Iw */ + AXIw(ORW);break; + CASE_W(0x0e) /* PUSH CS */ + Push_16(SegValue(cs));break; + CASE_B(0x0f) /* 2 byte opcodes*/ + core.opcode_index|=OPCODE_0F; + goto restart_opcode; + break; + CASE_B(0x10) /* ADC Eb,Gb */ + RMEbGb(ADCB);break; + CASE_W(0x11) /* ADC Ew,Gw */ + RMEwGw(ADCW);break; + CASE_B(0x12) /* ADC Gb,Eb */ + RMGbEb(ADCB);break; + CASE_W(0x13) /* ADC Gw,Ew */ + RMGwEw(ADCW);break; + CASE_B(0x14) /* ADC AL,Ib */ + ALIb(ADCB);break; + CASE_W(0x15) /* ADC AX,Iw */ + AXIw(ADCW);break; + CASE_W(0x16) /* PUSH SS */ + Push_16(SegValue(ss));break; + CASE_W(0x17) /* POP SS */ + CPU_SetSegGeneral(ss,Pop_16());break; + CASE_B(0x18) /* SBB Eb,Gb */ + RMEbGb(SBBB);break; + CASE_W(0x19) /* SBB Ew,Gw */ + RMEwGw(SBBW);break; + CASE_B(0x1a) /* SBB Gb,Eb */ + RMGbEb(SBBB);break; + CASE_W(0x1b) /* SBB Gw,Ew */ + RMGwEw(SBBW);break; + CASE_B(0x1c) /* SBB AL,Ib */ + ALIb(SBBB);break; + CASE_W(0x1d) /* SBB AX,Iw */ + AXIw(SBBW);break; + CASE_W(0x1e) /* PUSH DS */ + Push_16(SegValue(ds));break; + CASE_W(0x1f) /* POP DS */ + CPU_SetSegGeneral(ds,Pop_16());break; + CASE_B(0x20) /* AND Eb,Gb */ + RMEbGb(ANDB);break; + CASE_W(0x21) /* AND Ew,Gw */ + RMEwGw(ANDW);break; + CASE_B(0x22) /* AND Gb,Eb */ + RMGbEb(ANDB);break; + CASE_W(0x23) /* AND Gw,Ew */ + RMGwEw(ANDW);break; + CASE_B(0x24) /* AND AL,Ib */ + ALIb(ANDB);break; + CASE_W(0x25) /* AND AX,Iw */ + AXIw(ANDW);break; + CASE_B(0x26) /* SEG ES: */ + DO_PREFIX_SEG(es);break; + CASE_B(0x27) /* DAA */ + DAA();break; + CASE_B(0x28) /* SUB Eb,Gb */ + RMEbGb(SUBB);break; + CASE_W(0x29) /* SUB Ew,Gw */ + RMEwGw(SUBW);break; + CASE_B(0x2a) /* SUB Gb,Eb */ + RMGbEb(SUBB);break; + CASE_W(0x2b) /* SUB Gw,Ew */ + RMGwEw(SUBW);break; + CASE_B(0x2c) /* SUB AL,Ib */ + ALIb(SUBB);break; + CASE_W(0x2d) /* SUB AX,Iw */ + AXIw(SUBW);break; + CASE_B(0x2e) /* SEG CS: */ + DO_PREFIX_SEG(cs);break; + CASE_B(0x2f) /* DAS */ + DAS();break; + CASE_B(0x30) /* XOR Eb,Gb */ + RMEbGb(XORB);break; + CASE_W(0x31) /* XOR Ew,Gw */ + RMEwGw(XORW);break; + CASE_B(0x32) /* XOR Gb,Eb */ + RMGbEb(XORB);break; + CASE_W(0x33) /* XOR Gw,Ew */ + RMGwEw(XORW);break; + CASE_B(0x34) /* XOR AL,Ib */ + ALIb(XORB);break; + CASE_W(0x35) /* XOR AX,Iw */ + AXIw(XORW);break; + CASE_B(0x36) /* SEG SS: */ + DO_PREFIX_SEG(ss);break; + CASE_B(0x37) /* AAA */ + AAA();break; + CASE_B(0x38) /* CMP Eb,Gb */ + RMEbGb(CMPB);break; + CASE_W(0x39) /* CMP Ew,Gw */ + RMEwGw(CMPW);break; + CASE_B(0x3a) /* CMP Gb,Eb */ + RMGbEb(CMPB);break; + CASE_W(0x3b) /* CMP Gw,Ew */ + RMGwEw(CMPW);break; + CASE_B(0x3c) /* CMP AL,Ib */ + ALIb(CMPB);break; + CASE_W(0x3d) /* CMP AX,Iw */ + AXIw(CMPW);break; + CASE_B(0x3e) /* SEG DS: */ + DO_PREFIX_SEG(ds);break; + CASE_B(0x3f) /* AAS */ + AAS();break; + CASE_W(0x40) /* INC AX */ + INCW(reg_ax,LoadRw,SaveRw);break; + CASE_W(0x41) /* INC CX */ + INCW(reg_cx,LoadRw,SaveRw);break; + CASE_W(0x42) /* INC DX */ + INCW(reg_dx,LoadRw,SaveRw);break; + CASE_W(0x43) /* INC BX */ + INCW(reg_bx,LoadRw,SaveRw);break; + CASE_W(0x44) /* INC SP */ + INCW(reg_sp,LoadRw,SaveRw);break; + CASE_W(0x45) /* INC BP */ + INCW(reg_bp,LoadRw,SaveRw);break; + CASE_W(0x46) /* INC SI */ + INCW(reg_si,LoadRw,SaveRw);break; + CASE_W(0x47) /* INC DI */ + INCW(reg_di,LoadRw,SaveRw);break; + CASE_W(0x48) /* DEC AX */ + DECW(reg_ax,LoadRw,SaveRw);break; + CASE_W(0x49) /* DEC CX */ + DECW(reg_cx,LoadRw,SaveRw);break; + CASE_W(0x4a) /* DEC DX */ + DECW(reg_dx,LoadRw,SaveRw);break; + CASE_W(0x4b) /* DEC BX */ + DECW(reg_bx,LoadRw,SaveRw);break; + CASE_W(0x4c) /* DEC SP */ + DECW(reg_sp,LoadRw,SaveRw);break; + CASE_W(0x4d) /* DEC BP */ + DECW(reg_bp,LoadRw,SaveRw);break; + CASE_W(0x4e) /* DEC SI */ + DECW(reg_si,LoadRw,SaveRw);break; + CASE_W(0x4f) /* DEC DI */ + DECW(reg_di,LoadRw,SaveRw);break; + CASE_W(0x50) /* PUSH AX */ + Push_16(reg_ax);break; + CASE_W(0x51) /* PUSH CX */ + Push_16(reg_cx);break; + CASE_W(0x52) /* PUSH DX */ + Push_16(reg_dx);break; + CASE_W(0x53) /* PUSH BX */ + Push_16(reg_bx);break; + CASE_W(0x54) /* PUSH SP */ +//TODO Check if this is correct i think it's SP+2 or something + Push_16(reg_sp);break; + CASE_W(0x55) /* PUSH BP */ + Push_16(reg_bp);break; + CASE_W(0x56) /* PUSH SI */ + Push_16(reg_si);break; + CASE_W(0x57) /* PUSH DI */ + Push_16(reg_di);break; + CASE_W(0x58) /* POP AX */ + reg_ax=Pop_16();break; + CASE_W(0x59) /* POP CX */ + reg_cx=Pop_16();break; + CASE_W(0x5a) /* POP DX */ + reg_dx=Pop_16();break; + CASE_W(0x5b) /* POP BX */ + reg_bx=Pop_16();break; + CASE_W(0x5c) /* POP SP */ + reg_sp=Pop_16();break; + CASE_W(0x5d) /* POP BP */ + reg_bp=Pop_16();break; + CASE_W(0x5e) /* POP SI */ + reg_si=Pop_16();break; + CASE_W(0x5f) /* POP DI */ + reg_di=Pop_16();break; + CASE_W(0x60) /* PUSHA */ + { + Bit16u old_sp=reg_sp; + Push_16(reg_ax);Push_16(reg_cx);Push_16(reg_dx);Push_16(reg_bx); + Push_16(old_sp);Push_16(reg_bp);Push_16(reg_si);Push_16(reg_di); + } + break; + CASE_W(0x61) /* POPA */ + reg_di=Pop_16();reg_si=Pop_16();reg_bp=Pop_16();Pop_16();//Don't save SP + reg_bx=Pop_16();reg_dx=Pop_16();reg_cx=Pop_16();reg_ax=Pop_16(); + break; + CASE_W(0x62) /* BOUND */ + { + Bit16s bound_min, bound_max; + GetRMrw;GetEAa; + bound_min=LoadMw(eaa); + bound_max=LoadMw(eaa+2); + if ( (((Bit16s)*rmrw) < bound_min) || (((Bit16s)*rmrw) > bound_max) ) { + EXCEPTION(5); + } + } + break; + CASE_W(0x63) /* ARPL Ew,Rw */ + { + FillFlags(); + GetRMrw; + if (rm >= 0xc0 ) { + GetEArw;Bitu new_sel=*earw; + CPU_ARPL(new_sel,*rmrw); + *earw=(Bit16u)new_sel; + } else { + GetEAa;Bitu new_sel=LoadMw(eaa); + CPU_ARPL(new_sel,*rmrw); + SaveMw(eaa,(Bit16u)new_sel); + } + } + break; + CASE_B(0x64) /* SEG FS: */ + DO_PREFIX_SEG(fs);break; + CASE_B(0x65) /* SEG GS: */ + DO_PREFIX_SEG(gs);break; + CASE_B(0x66) /* Operand Size Prefix */ + core.opcode_index^=OPCODE_SIZE; + goto restart_opcode; + CASE_B(0x67) /* Address Size Prefix */ + DO_PREFIX_ADDR(); + CASE_W(0x68) /* PUSH Iw */ + Push_16(Fetchw());break; + CASE_W(0x69) /* IMUL Gw,Ew,Iw */ + RMGwEwOp3(DIMULW,Fetchws()); + break; + CASE_W(0x6a) /* PUSH Ib */ + Push_16(Fetchbs()); + break; + CASE_W(0x6b) /* IMUL Gw,Ew,Ib */ + RMGwEwOp3(DIMULW,Fetchbs()); + break; + CASE_B(0x6c) /* INSB */ + DoString(R_INSB);break; + CASE_W(0x6d) /* INSW */ + DoString(R_INSW);break; + CASE_B(0x6e) /* OUTSB */ + DoString(R_OUTSB);break; + CASE_W(0x6f) /* OUTSW */ + DoString(R_OUTSW);break; + CASE_B(0x70) /* JO */ + JumpSIb(get_OF());break; + CASE_B(0x71) /* JNO */ + JumpSIb(!get_OF());break; + CASE_B(0x72) /* JB */ + JumpSIb(get_CF());break; + CASE_B(0x73) /* JNB */ + JumpSIb(!get_CF());break; + CASE_B(0x74) /* JZ */ + JumpSIb(get_ZF());break; + CASE_B(0x75) /* JNZ */ + JumpSIb(!get_ZF());break; + CASE_B(0x76) /* JBE */ + JumpSIb(get_CF() || get_ZF());break; + CASE_B(0x77) /* JNBE */ + JumpSIb(!get_CF() && !get_ZF());break; + CASE_B(0x78) /* JS */ + JumpSIb(get_SF());break; + CASE_B(0x79) /* JNS */ + JumpSIb(!get_SF());break; + CASE_B(0x7a) /* JP */ + JumpSIb(get_PF());break; + CASE_B(0x7b) /* JNP */ + JumpSIb(!get_PF());break; + CASE_B(0x7c) /* JL */ + JumpSIb(get_SF() != get_OF());break; + CASE_B(0x7d) /* JNL */ + JumpSIb(get_SF() == get_OF());break; + CASE_B(0x7e) /* JLE */ + JumpSIb(get_ZF() || (get_SF() != get_OF()));break; + CASE_B(0x7f) /* JNLE */ + JumpSIb((get_SF() == get_OF()) && !get_ZF());break; + CASE_B(0x80) /* Grpl Eb,Ib */ + CASE_B(0x82) /* Grpl Eb,Ib Mirror instruction*/ + { + GetRM;Bitu which=(rm>>3)&7; + if (rm>= 0xc0) { + GetEArb;Bit8u ib=Fetchb(); + switch (which) { + case 0x00:ADDB(*earb,ib,LoadRb,SaveRb);break; + case 0x01: ORB(*earb,ib,LoadRb,SaveRb);break; + case 0x02:ADCB(*earb,ib,LoadRb,SaveRb);break; + case 0x03:SBBB(*earb,ib,LoadRb,SaveRb);break; + case 0x04:ANDB(*earb,ib,LoadRb,SaveRb);break; + case 0x05:SUBB(*earb,ib,LoadRb,SaveRb);break; + case 0x06:XORB(*earb,ib,LoadRb,SaveRb);break; + case 0x07:CMPB(*earb,ib,LoadRb,SaveRb);break; + } + } else { + GetEAa;Bit8u ib=Fetchb(); + switch (which) { + case 0x00:ADDB(eaa,ib,LoadMb,SaveMb);break; + case 0x01: ORB(eaa,ib,LoadMb,SaveMb);break; + case 0x02:ADCB(eaa,ib,LoadMb,SaveMb);break; + case 0x03:SBBB(eaa,ib,LoadMb,SaveMb);break; + case 0x04:ANDB(eaa,ib,LoadMb,SaveMb);break; + case 0x05:SUBB(eaa,ib,LoadMb,SaveMb);break; + case 0x06:XORB(eaa,ib,LoadMb,SaveMb);break; + case 0x07:CMPB(eaa,ib,LoadMb,SaveMb);break; + } + } + break; + } + CASE_W(0x81) /* Grpl Ew,Iw */ + { + GetRM;Bitu which=(rm>>3)&7; + if (rm>= 0xc0) { + GetEArw;Bit16u iw=Fetchw(); + switch (which) { + case 0x00:ADDW(*earw,iw,LoadRw,SaveRw);break; + case 0x01: ORW(*earw,iw,LoadRw,SaveRw);break; + case 0x02:ADCW(*earw,iw,LoadRw,SaveRw);break; + case 0x03:SBBW(*earw,iw,LoadRw,SaveRw);break; + case 0x04:ANDW(*earw,iw,LoadRw,SaveRw);break; + case 0x05:SUBW(*earw,iw,LoadRw,SaveRw);break; + case 0x06:XORW(*earw,iw,LoadRw,SaveRw);break; + case 0x07:CMPW(*earw,iw,LoadRw,SaveRw);break; + } + } else { + GetEAa;Bit16u iw=Fetchw(); + switch (which) { + case 0x00:ADDW(eaa,iw,LoadMw,SaveMw);break; + case 0x01: ORW(eaa,iw,LoadMw,SaveMw);break; + case 0x02:ADCW(eaa,iw,LoadMw,SaveMw);break; + case 0x03:SBBW(eaa,iw,LoadMw,SaveMw);break; + case 0x04:ANDW(eaa,iw,LoadMw,SaveMw);break; + case 0x05:SUBW(eaa,iw,LoadMw,SaveMw);break; + case 0x06:XORW(eaa,iw,LoadMw,SaveMw);break; + case 0x07:CMPW(eaa,iw,LoadMw,SaveMw);break; + } + } + break; + } + CASE_W(0x83) /* Grpl Ew,Ix */ + { + GetRM;Bitu which=(rm>>3)&7; + if (rm>= 0xc0) { + GetEArw;Bit16u iw=(Bit16s)Fetchbs(); + switch (which) { + case 0x00:ADDW(*earw,iw,LoadRw,SaveRw);break; + case 0x01: ORW(*earw,iw,LoadRw,SaveRw);break; + case 0x02:ADCW(*earw,iw,LoadRw,SaveRw);break; + case 0x03:SBBW(*earw,iw,LoadRw,SaveRw);break; + case 0x04:ANDW(*earw,iw,LoadRw,SaveRw);break; + case 0x05:SUBW(*earw,iw,LoadRw,SaveRw);break; + case 0x06:XORW(*earw,iw,LoadRw,SaveRw);break; + case 0x07:CMPW(*earw,iw,LoadRw,SaveRw);break; + } + } else { + GetEAa;Bit16u iw=(Bit16s)Fetchbs(); + switch (which) { + case 0x00:ADDW(eaa,iw,LoadMw,SaveMw);break; + case 0x01: ORW(eaa,iw,LoadMw,SaveMw);break; + case 0x02:ADCW(eaa,iw,LoadMw,SaveMw);break; + case 0x03:SBBW(eaa,iw,LoadMw,SaveMw);break; + case 0x04:ANDW(eaa,iw,LoadMw,SaveMw);break; + case 0x05:SUBW(eaa,iw,LoadMw,SaveMw);break; + case 0x06:XORW(eaa,iw,LoadMw,SaveMw);break; + case 0x07:CMPW(eaa,iw,LoadMw,SaveMw);break; + } + } + break; + } + CASE_B(0x84) /* TEST Eb,Gb */ + RMEbGb(TESTB); + break; + CASE_W(0x85) /* TEST Ew,Gw */ + RMEwGw(TESTW); + break; + CASE_B(0x86) /* XCHG Eb,Gb */ + { + GetRMrb;Bit8u oldrmrb=*rmrb; + if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;*earb=oldrmrb;} + else {GetEAa;*rmrb=LoadMb(eaa);SaveMb(eaa,oldrmrb);} + break; + } + CASE_W(0x87) /* XCHG Ew,Gw */ + { + GetRMrw;Bit16u oldrmrw=*rmrw; + if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;*earw=oldrmrw;} + else {GetEAa;*rmrw=LoadMw(eaa);SaveMw(eaa,oldrmrw);} + break; + } + CASE_B(0x88) /* MOV Eb,Gb */ + { + GetRMrb; + if (rm >= 0xc0 ) {GetEArb;*earb=*rmrb;} + else {GetEAa;SaveMb(eaa,*rmrb);} + break; + } + CASE_W(0x89) /* MOV Ew,Gw */ + { + GetRMrw; + if (rm >= 0xc0 ) {GetEArw;*earw=*rmrw;} + else {GetEAa;SaveMw(eaa,*rmrw);} + break; + } + CASE_B(0x8a) /* MOV Gb,Eb */ + { + GetRMrb; + if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;} + else {GetEAa;*rmrb=LoadMb(eaa);} + break; + } + CASE_W(0x8b) /* MOV Gw,Ew */ + { + GetRMrw; + if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;} + else {GetEAa;*rmrw=LoadMw(eaa);} + break; + } + CASE_W(0x8c) /* Mov Ew,Sw */ + { + GetRM;Bit16u val;Bitu which=(rm>>3)&7; + switch (which) { + case 0x00: /* MOV Ew,ES */ + val=SegValue(es);break; + case 0x01: /* MOV Ew,CS */ + val=SegValue(cs);break; + case 0x02: /* MOV Ew,SS */ + val=SegValue(ss);break; + case 0x03: /* MOV Ew,DS */ + val=SegValue(ds);break; + case 0x04: /* MOV Ew,FS */ + val=SegValue(fs);break; + case 0x05: /* MOV Ew,GS */ + val=SegValue(gs);break; + default: + val=0; + E_Exit("CPU:8c:Illegal RM Byte"); + } + if (rm >= 0xc0 ) {GetEArw;*earw=val;} + else {GetEAa;SaveMw(eaa,val);} + break; + } + CASE_W(0x8d) /* LEA Gw */ + { + //Little hack to always use segprefixed version + core.seg_prefix_base=0; + GetRMrw; + if (TEST_PREFIX_ADDR) { + *rmrw=(Bit16u)(*GetEA_SEG_ADDR[rm])(); + } else { + *rmrw=(Bit16u)(*GetEA_SEG[rm])(); + } + break; + } + CASE_B(0x8e) /* MOV Sw,Ew */ + { + GetRM;Bit16u val;Bitu which=(rm>>3)&7; + if (rm >= 0xc0 ) {GetEArw;val=*earw;} + else {GetEAa;val=LoadMw(eaa);} + switch (which) { + case 0x00: /* MOV ES,Ew */ + CPU_SetSegGeneral(es,val);break; + case 0x01: /* MOV CS,Ew Illegal*/ + E_Exit("CPU:Illegal MOV CS Call"); + break; + case 0x02: /* MOV SS,Ew */ + CPU_SetSegGeneral(ss,val); + break; + case 0x03: /* MOV DS,Ew */ + CPU_SetSegGeneral(ds,val);break; + case 0x04: /* MOV FS,Ew */ + CPU_SetSegGeneral(fs,val);break; + case 0x05: /* MOV GS,Ew */ + CPU_SetSegGeneral(gs,val);break; + default: + E_Exit("CPU:8E:Illegal RM Byte"); + } + break; + } + CASE_W(0x8f) /* POP Ew */ + { + GetRM; + if (rm >= 0xc0 ) {GetEArw;*earw=Pop_16();} + else {GetEAa;SaveMw(eaa,Pop_16());} + break; + } + CASE_B(0x90) /* NOP */ + break; + CASE_W(0x91) /* XCHG CX,AX */ + { Bit16u temp=reg_ax;reg_ax=reg_cx;reg_cx=temp; } + break; + CASE_W(0x92) /* XCHG DX,AX */ + { Bit16u temp=reg_ax;reg_ax=reg_dx;reg_dx=temp; } + break; + CASE_W(0x93) /* XCHG BX,AX */ + { Bit16u temp=reg_ax;reg_ax=reg_bx;reg_bx=temp; } + break; + CASE_W(0x94) /* XCHG SP,AX */ + { Bit16u temp=reg_ax;reg_ax=reg_sp;reg_sp=temp; } + break; + CASE_W(0x95) /* XCHG BP,AX */ + { Bit16u temp=reg_ax;reg_ax=reg_bp;reg_bp=temp; } + break; + CASE_W(0x96) /* XCHG SI,AX */ + { Bit16u temp=reg_ax;reg_ax=reg_si;reg_si=temp; } + break; + CASE_W(0x97) /* XCHG DI,AX */ + { Bit16u temp=reg_ax;reg_ax=reg_di;reg_di=temp; } + break; + CASE_W(0x98) /* CBW */ + reg_ax=(Bit8s)reg_al;break; + CASE_W(0x99) /* CWD */ + if (reg_ax & 0x8000) reg_dx=0xffff;else reg_dx=0; + break; + CASE_W(0x9a) /* CALL Ap */ + { + Bit16u newip=Fetchw();Bit16u newcs=Fetchw(); + SAVEIP; + if (CPU_CALL(false,newcs,newip)) { + LOADIP; + } else { + FillFlags();return CBRET_NONE; + } + break; + } + CASE_B(0x9b) /* WAIT */ + break; /* No waiting here */ + CASE_W(0x9c) /* PUSHF */ + FillFlags(); + Push_16(flags.word); + break; + CASE_W(0x9d) /* POPF */ + SETFLAGSw(Pop_16()); +#if CPU_TRAP_CHECK + if (GETFLAG(TF)) { + cpudecoder=CPU_Core_Normal_Decode_Trap; + goto decode_end; + } +#endif +#ifdef CPU_PIC_CHECK + if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; +#endif + break; + CASE_B(0x9e) /* SAHF */ + SETFLAGSb(reg_ah); + break; + CASE_B(0x9f) /* LAHF */ + FillFlags(); + reg_ah=flags.word&0xff; + break; + CASE_B(0xa0) /* MOV AL,Ob */ + { + GetEADirect; + reg_al=LoadMb(eaa); + } + break; + CASE_W(0xa1) /* MOV AX,Ow */ + { + GetEADirect; + reg_ax=LoadMw(eaa); + } + break; + CASE_B(0xa2) /* MOV Ob,AL */ + { + GetEADirect; + SaveMb(eaa,reg_al); + } + break; + CASE_W(0xa3) /* MOV Ow,AX */ + { + GetEADirect; + SaveMw(eaa,reg_ax); + } + break; + CASE_B(0xa4) /* MOVSB */ + DoString(R_MOVSB);break; + CASE_W(0xa5) /* MOVSW */ + DoString(R_MOVSW);break; + CASE_B(0xa6) /* CMPSB */ + DoString(R_CMPSB);break; + CASE_W(0xa7) /* CMPSW */ + DoString(R_CMPSW);break; + CASE_B(0xa8) /* TEST AL,Ib */ + ALIb(TESTB);break; + CASE_W(0xa9) /* TEST AX,Iw */ + AXIw(TESTW);break; + CASE_B(0xaa) /* STOSB */ + DoString(R_STOSB);break; + CASE_W(0xab) /* STOSW */ + DoString(R_STOSW);break; + CASE_B(0xac) /* LODSB */ + DoString(R_LODSB);break; + CASE_W(0xad) /* LODSW */ + DoString(R_LODSW);break; + CASE_B(0xae) /* SCASB */ + DoString(R_SCASB);break; + CASE_W(0xaf) /* SCASW */ + DoString(R_SCASW);break; + CASE_B(0xb0) /* MOV AL,Ib */ + reg_al=Fetchb();break; + CASE_B(0xb1) /* MOV CL,Ib */ + reg_cl=Fetchb();break; + CASE_B(0xb2) /* MOV DL,Ib */ + reg_dl=Fetchb();break; + CASE_B(0xb3) /* MOV BL,Ib */ + reg_bl=Fetchb();break; + CASE_B(0xb4) /* MOV AH,Ib */ + reg_ah=Fetchb();break; + CASE_B(0xb5) /* MOV CH,Ib */ + reg_ch=Fetchb();break; + CASE_B(0xb6) /* MOV DH,Ib */ + reg_dh=Fetchb();break; + CASE_B(0xb7) /* MOV BH,Ib */ + reg_bh=Fetchb();break; + CASE_W(0xb8) /* MOV AX,Iw */ + reg_ax=Fetchw();break; + CASE_W(0xb9) /* MOV CX,Iw */ + reg_cx=Fetchw();break; + CASE_W(0xba) /* MOV DX,Iw */ + reg_dx=Fetchw();break; + CASE_W(0xbb) /* MOV BX,Iw */ + reg_bx=Fetchw();break; + CASE_W(0xbc) /* MOV SP,Iw */ + reg_sp=Fetchw();break; + CASE_W(0xbd) /* MOV BP.Iw */ + reg_bp=Fetchw();break; + CASE_W(0xbe) /* MOV SI,Iw */ + reg_si=Fetchw();break; + CASE_W(0xbf) /* MOV DI,Iw */ + reg_di=Fetchw();break; + CASE_B(0xc0) /* GRP2 Eb,Ib */ + GRP2B(Fetchb());break; + CASE_W(0xc1) /* GRP2 Ew,Ib */ + GRP2W(Fetchb());break; + CASE_W(0xc2) /* RETN Iw */ + { + Bit16u addsp=Fetchw(); + SETIP(Pop_16());reg_esp+=addsp; + break; + } + CASE_W(0xc3) /* RETN */ + SETIP(Pop_16()); + break; + CASE_W(0xc4) /* LES */ + { + GetRMrw;GetEAa; + *rmrw=LoadMw(eaa);CPU_SetSegGeneral(es,LoadMw(eaa+2)); + break; + } + CASE_W(0xc5) /* LDS */ + { + GetRMrw;GetEAa; + *rmrw=LoadMw(eaa);CPU_SetSegGeneral(ds,LoadMw(eaa+2)); + break; + } + CASE_B(0xc6) /* MOV Eb,Ib */ + { + GetRM; + if (rm >= 0xc0) {GetEArb;*earb=Fetchb();} + else {GetEAa;SaveMb(eaa,Fetchb());} + break; + } + CASE_W(0xc7) /* MOV EW,Iw */ + { + GetRM; + if (rm >= 0xc0) {GetEArw;*earw=Fetchw();} + else {GetEAa;SaveMw(eaa,Fetchw());} + break; + } + CASE_W(0xc8) /* ENTER Iw,Ib */ + { + Bitu bytes=Fetchw();Bitu level=Fetchb() & 0x1f; + Bitu frame_ptr=reg_esp-2; + if (cpu.stack.big) { + reg_esp-=2; + mem_writew(SegBase(ss)+reg_esp,reg_bp); + for (Bitu i=1;i>3)&7; + switch (which) { + case 0x00: /* TEST Eb,Ib */ + case 0x01: /* TEST Eb,Ib Undocumented*/ + { + if (rm >= 0xc0 ) {GetEArb;TESTB(*earb,Fetchb(),LoadRb,0)} + else {GetEAa;TESTB(eaa,Fetchb(),LoadMb,0);} + break; + } + case 0x02: /* NOT Eb */ + { + if (rm >= 0xc0 ) {GetEArb;*earb=~*earb;} + else {GetEAa;SaveMb(eaa,~LoadMb(eaa));} + break; + } + case 0x03: /* NEG Eb */ + { + flags.type=t_NEGb; + if (rm >= 0xc0 ) { + GetEArb;flags.var1.b=*earb;flags.result.b=0-flags.var1.b; + *earb=flags.result.b; + } else { + GetEAa;flags.var1.b=LoadMb(eaa);flags.result.b=0-flags.var1.b; + SaveMb(eaa,flags.result.b); + } + break; + } + case 0x04: /* MUL AL,Eb */ + RMEb(MULB); + break; + case 0x05: /* IMUL AL,Eb */ + RMEb(IMULB); + break; + case 0x06: /* DIV Eb */ + RMEb(DIVB); + break; + case 0x07: /* IDIV Eb */ + RMEb(IDIVB); + break; + } + break; + } + CASE_W(0xf7) /* GRP3 Ew(,Iw) */ + { + GetRM;Bitu which=(rm>>3)&7; + switch (which) { + case 0x00: /* TEST Ew,Iw */ + case 0x01: /* TEST Ew,Iw Undocumented*/ + { + if (rm >= 0xc0 ) {GetEArw;TESTW(*earw,Fetchw(),LoadRw,SaveRw);} + else {GetEAa;TESTW(eaa,Fetchw(),LoadMw,SaveMw);} + break; + } + case 0x02: /* NOT Ew */ + { + if (rm >= 0xc0 ) {GetEArw;*earw=~*earw;} + else {GetEAa;SaveMw(eaa,~LoadMw(eaa));} + break; + } + case 0x03: /* NEG Ew */ + { + flags.type=t_NEGw; + if (rm >= 0xc0 ) { + GetEArw;flags.var1.w=*earw;flags.result.w=0-flags.var1.w; + *earw=flags.result.w; + } else { + GetEAa;flags.var1.w=LoadMw(eaa);flags.result.w=0-flags.var1.w; + SaveMw(eaa,flags.result.w); + } + break; + } + case 0x04: /* MUL AX,Ew */ + RMEw(MULW); + break; + case 0x05: /* IMUL AX,Ew */ + RMEw(IMULW) + break; + case 0x06: /* DIV Ew */ + RMEw(DIVW) + break; + case 0x07: /* IDIV Ew */ + RMEw(IDIVW) + break; + } + break; + } + CASE_B(0xf8) /* CLC */ + SETFLAGBIT(CF,false); + if (flags.type!=t_CF) flags.prev_type=flags.type; + flags.type=t_CF; + break; + CASE_B(0xf9) /* STC */ + SETFLAGBIT(CF,true); + if (flags.type!=t_CF) flags.prev_type=flags.type; + flags.type=t_CF; + break; + CASE_B(0xfa) /* CLI */ + SETFLAGBIT(IF,false); + break; + CASE_B(0xfb) /* STI */ + SETFLAGBIT(IF,true); +#ifdef CPU_PIC_CHECK + if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; +#endif + break; + CASE_B(0xfc) /* CLD */ + SETFLAGBIT(DF,false); + break; + CASE_B(0xfd) /* STD */ + SETFLAGBIT(DF,true); + break; + CASE_B(0xfe) /* GRP4 Eb */ + { + GetRM;Bitu which=(rm>>3)&7; + switch (which) { + case 0x00: /* INC Eb */ + RMEb(INCB); + break; + case 0x01: /* DEC Eb */ + RMEb(DECB); + break; + case 0x07: /* CallBack */ + { + Bitu cb=Fetchw(); + LEAVECORE; + return cb; + } + default: + E_Exit("Illegal GRP4 Call %d",(rm>>3) & 7); + break; + } + break; + } + CASE_W(0xff) /* GRP5 Ew */ + { + GetRM;Bitu which=(rm>>3)&7; + switch (which) { + case 0x00: /* INC Ew */ + RMEw(INCW); + break; + case 0x01: /* DEC Ew */ + RMEw(DECW); + break; + case 0x02: /* CALL Ev */ + if (rm >= 0xc0 ) {GetEArw;Push_16((Bit16u)GETIP);SETIP(*earw);} + else {GetEAa;Push_16((Bit16u)GETIP);SETIP(LoadMw(eaa));} + break; + case 0x03: /* CALL Ep */ + { + GetEAa; + Bit16u newip=LoadMw(eaa); + Bit16u newcs=LoadMw(eaa+2); + SAVEIP; + if (CPU_CALL(false,newcs,newip)) { + LOADIP; + } else { + FillFlags();return CBRET_NONE; + } + } + break; + case 0x04: /* JMP Ev */ + if (rm >= 0xc0 ) {GetEArw;SETIP(*earw);} + else {GetEAa;SETIP(LoadMw(eaa));} + break; + case 0x05: /* JMP Ep */ + { + GetEAa; + Bit16u newip=LoadMw(eaa); + Bit16u newcs=LoadMw(eaa+2); + SAVEIP; + if (CPU_JMP(false,newcs,newip)) { + LOADIP; + } else { + FillFlags();return CBRET_NONE; + } } + break; + case 0x06: /* PUSH Ev */ + if (rm >= 0xc0 ) {GetEArw;Push_16(*earw);} + else {GetEAa;Push_16(LoadMw(eaa));} + break; + default: + E_Exit("CPU:GRP5:Illegal Call %2X",which); + break; + } + break; + } + + + + diff --git a/src/cpu/core_normal/string.h b/src/cpu/core_normal/string.h new file mode 100644 index 00000000..524025f4 --- /dev/null +++ b/src/cpu/core_normal/string.h @@ -0,0 +1,243 @@ +enum STRING_OP { + R_OUTSB,R_OUTSW,R_OUTSD, + R_INSB,R_INSW,R_INSD, + R_MOVSB,R_MOVSW,R_MOVSD, + R_LODSB,R_LODSW,R_LODSD, + R_STOSB,R_STOSW,R_STOSD, + R_SCASB,R_SCASW,R_SCASD, + R_CMPSB,R_CMPSW,R_CMPSD, +}; + +#define LoadD(_BLAH) _BLAH + +static void DoString(STRING_OP type) { + PhysPt si_base,di_base; + Bitu si_index,di_index; + Bitu add_mask; + Bitu count,count_left; + Bits add_index; + + if (TEST_PREFIX_SEG) si_base=core.seg_prefix_base; + else si_base=SegBase(ds); + di_base=SegBase(es); + if (TEST_PREFIX_ADDR) { + add_mask=0xFFFFFFFF; + si_index=reg_esi; + di_index=reg_edi; + count=reg_ecx; + } else { + add_mask=0xFFFF; + si_index=reg_si; + di_index=reg_di; + count=reg_cx; + } + if (!(TEST_PREFIX_REP)) { + count=1; + } else { + CPU_Cycles++; + /* Calculate amount of ops to do before cycles run out */ + if ((count>(Bitu)CPU_Cycles) && (type0;count--) { + IO_Write(reg_dx,LoadMb(si_base+si_index)); + si_index=(si_index+add_index) & add_mask; + } + break; + case R_OUTSW: + add_index<<=1; + for (;count>0;count--) { + IO_Write(reg_dx,LoadMb(si_base+si_index)); + IO_Write(reg_dx+1,LoadMb(si_base+si_index+1)); + si_index=(si_index+add_index) & add_mask; + } + break; + case R_OUTSD: + add_index<<=2; + for (;count>0;count--) { + IO_Write(reg_dx,LoadMb(si_base+si_index)); + IO_Write(reg_dx+1,LoadMb(si_base+si_index+1)); + IO_Write(reg_dx+2,LoadMb(si_base+si_index+2)); + IO_Write(reg_dx+3,LoadMb(si_base+si_index+3)); + si_index=(si_index+add_index) & add_mask; + } + break; + case R_INSB: + for (;count>0;count--) { + SaveMb(di_base+di_index,IO_Read(reg_dx)); + di_index=(di_index+add_index) & add_mask; + } + break; + case R_INSW: + add_index<<=1; + for (;count>0;count--) { + SaveMb(di_base+di_index,IO_Read(reg_dx)); + SaveMb(di_base+di_index+1,IO_Read(reg_dx+1)); + di_index=(di_index+add_index) & add_mask; + } + break; + case R_STOSB: + for (;count>0;count--) { + SaveMb(di_base+di_index,reg_al); + di_index=(di_index+add_index) & add_mask; + } + break; + case R_STOSW: + add_index<<=1; + for (;count>0;count--) { + SaveMw(di_base+di_index,reg_ax); + di_index=(di_index+add_index) & add_mask; + } + break; + case R_STOSD: + add_index<<=2; + for (;count>0;count--) { + SaveMd(di_base+di_index,reg_eax); + di_index=(di_index+add_index) & add_mask; + } + break; + case R_MOVSB: + for (;count>0;count--) { + SaveMb(di_base+di_index,LoadMb(si_base+si_index)); + di_index=(di_index+add_index) & add_mask; + si_index=(si_index+add_index) & add_mask; + } + break; + case R_MOVSW: + add_index<<=1; + for (;count>0;count--) { + SaveMw(di_base+di_index,LoadMw(si_base+si_index)); + di_index=(di_index+add_index) & add_mask; + si_index=(si_index+add_index) & add_mask; + } + break; + case R_MOVSD: + add_index<<=2; + for (;count>0;count--) { + SaveMd(di_base+di_index,LoadMd(si_base+si_index)); + di_index=(di_index+add_index) & add_mask; + si_index=(si_index+add_index) & add_mask; + } + break; + case R_LODSB: + for (;count>0;count--) { + reg_al=LoadMb(si_base+si_index); + si_index=(si_index+add_index) & add_mask; + } + break; + case R_LODSW: + add_index<<=1; + for (;count>0;count--) { + reg_ax=LoadMw(si_base+si_index); + si_index=(si_index+add_index) & add_mask; + } + break; + case R_LODSD: + add_index<<=2; + for (;count>0;count--) { + reg_eax=LoadMd(si_base+si_index); + si_index=(si_index+add_index) & add_mask; + } + break; + case R_SCASB: + { + Bit8u val2; + for (;count>0;) { + count--;CPU_Cycles--; + val2=LoadMb(di_base+di_index); + di_index=(di_index+add_index) & add_mask; + if ((reg_al==val2)!=core.rep_zero) break; + } + CMPB(reg_al,val2,LoadD,0); + } + break; + case R_SCASW: + { + add_index<<=1;Bit16u val2; + for (;count>0;) { + count--;CPU_Cycles--; + val2=LoadMw(di_base+di_index); + di_index=(di_index+add_index) & add_mask; + if ((reg_ax==val2)!=core.rep_zero) break; + } + CMPW(reg_ax,val2,LoadD,0); + } + break; + case R_SCASD: + { + add_index<<=2;Bit32u val2; + for (;count>0;) { + count--;CPU_Cycles--; + val2=LoadMd(di_base+di_index); + di_index=(di_index+add_index) & add_mask; + if ((reg_eax==val2)!=core.rep_zero) break; + } + CMPD(reg_eax,val2,LoadD,0); + } + break; + case R_CMPSB: + { + Bit8u val1,val2; + for (;count>0;) { + count--;CPU_Cycles--; + val1=LoadMb(si_base+si_index); + val2=LoadMb(di_base+di_index); + si_index=(si_index+add_index) & add_mask; + di_index=(di_index+add_index) & add_mask; + if ((val1==val2)!=core.rep_zero) break; + } + CMPB(val1,val2,LoadD,0); + } + break; + case R_CMPSW: + { + add_index<<=1;Bit16u val1,val2; + for (;count>0;) { + count--;CPU_Cycles--; + val1=LoadMw(si_base+si_index); + val2=LoadMw(di_base+di_index); + si_index=(si_index+add_index) & add_mask; + di_index=(di_index+add_index) & add_mask; + if ((val1==val2)!=core.rep_zero) break; + } + CMPW(val1,val2,LoadD,0); + } + break; + case R_CMPSD: + { + add_index<<=2;Bit32u val1,val2; + for (;count>0;) { + count--;CPU_Cycles--; + val1=LoadMd(si_base+si_index); + val2=LoadMd(di_base+di_index); + si_index=(si_index+add_index) & add_mask; + di_index=(di_index+add_index) & add_mask; + if ((val1==val2)!=core.rep_zero) break; + } + CMPD(val1,val2,LoadD,0); + } + break; + default: + LOG(LOG_CPU,LOG_ERROR)("Unhandled string op %d",type); + } + /* Clean up after certain amount of instructions */ + reg_esi&=(~add_mask); + reg_esi|=(si_index & add_mask); + reg_edi&=(~add_mask); + reg_edi|=(di_index & add_mask); + if (TEST_PREFIX_REP) { + count+=count_left; + reg_ecx&=(~add_mask); + reg_ecx|=(count & add_mask); + } +} \ No newline at end of file diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h new file mode 100644 index 00000000..d0e4d2a1 --- /dev/null +++ b/src/cpu/core_normal/support.h @@ -0,0 +1,138 @@ +/* + * 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 SETIP(_a_) (core.ip_lookup=SegBase(cs)+_a_) +#define GETIP (Bit32u)(core.ip_lookup-SegBase(cs)) +#define SAVEIP {reg_eip=GETIP;} +#define LOADIP {core.ip_lookup=(SegBase(cs)+reg_eip);} + +#define LEAVECORE \ + SAVEIP; \ + FillFlags(); + +static INLINE void ADDIPw(Bits add) { + SAVEIP; + reg_eip=(Bit16u)(reg_eip+add); + LOADIP; +} + +static INLINE void ADDIPd(Bits add) { + SAVEIP; + reg_eip=(reg_eip+add); + LOADIP; +} + + +static INLINE void ADDIPFAST(Bits blah) { + core.ip_lookup+=blah; +} + +#define EXCEPTION(blah) \ + { \ + Bit8u new_num=blah; \ + core.ip_lookup=core.op_start; \ + LEAVECORE; \ + if (Interrupt(new_num)) { \ + goto decode_start; \ + } else return CBRET_NONE; \ + } + +static INLINE Bit8u Fetchb() { + Bit8u temp=LoadMb(core.ip_lookup); + core.ip_lookup+=1; + return temp; +} + +static INLINE Bit16u Fetchw() { + Bit16u temp=LoadMw(core.ip_lookup); + core.ip_lookup+=2; + return temp; +} +static INLINE Bit32u Fetchd() { + Bit32u temp=LoadMd(core.ip_lookup); + core.ip_lookup+=4; + return temp; +} + +static INLINE Bit8s Fetchbs() { + return Fetchb(); +} +static INLINE Bit16s Fetchws() { + return Fetchw(); +} + +static INLINE Bit32s Fetchds() { + return Fetchd(); +} + +static INLINE void Push_16(Bit16u blah) { + reg_esp-=2; + SaveMw(SegBase(ss)+(reg_esp & cpu.stack.mask),blah); +}; + +static INLINE void Push_32(Bit32u blah) { + reg_esp-=4; + SaveMd(SegBase(ss)+(reg_esp & cpu.stack.mask),blah); +}; + +static INLINE Bit16u Pop_16() { + Bit16u temp=LoadMw(SegBase(ss)+(reg_esp & cpu.stack.mask)); + reg_esp+=2; + return temp; +}; + +static INLINE Bit32u Pop_32() { + Bit32u temp=LoadMd(SegBase(ss)+(reg_esp & cpu.stack.mask)); + reg_esp+=4; + return temp; +}; + +#define JumpSIb(blah) \ + if (blah) { \ + ADDIPFAST(Fetchbs()); \ + } else { \ + ADDIPFAST(1); \ + } + +#define JumpSIw(blah) \ + if (blah) { \ + ADDIPw(Fetchws()); \ + } else { \ + ADDIPFAST(2); \ + } + + +#define JumpSId(blah) \ + if (blah) { \ + ADDIPd(Fetchds()); \ + } else { \ + ADDIPFAST(4); \ + } + +#define SETcc(cc) \ + { \ + GetRM; \ + if (rm >= 0xc0 ) {GetEArb;*earb=(cc) ? 1 : 0;} \ + else {GetEAa;SaveMb(eaa,(cc) ? 1 : 0);} \ + } + +#include "helpers.h" +#include "table_ea.h" +#include "../modrm.h" + + diff --git a/src/cpu/core_normal/table_ea.h b/src/cpu/core_normal/table_ea.h new file mode 100644 index 00000000..a93182e4 --- /dev/null +++ b/src/cpu/core_normal/table_ea.h @@ -0,0 +1,356 @@ +/* + * 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. + */ + +typedef PhysPt (*GetEATable[256])(void); +typedef PhysPt (*EA_LookupHandler)(void); + + +/* The MOD/RM Decoder for EA for this decoder's addressing modes */ +static PhysPt EA_16_00_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si); } +static PhysPt EA_16_01_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di); } +static PhysPt EA_16_02_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si); } +static PhysPt EA_16_03_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di); } +static PhysPt EA_16_04_n(void) { return SegBase(ds)+(Bit16u)(reg_si); } +static PhysPt EA_16_05_n(void) { return SegBase(ds)+(Bit16u)(reg_di); } +static PhysPt EA_16_06_n(void) { return SegBase(ds)+(Bit16u)(Fetchw());} +static PhysPt EA_16_07_n(void) { return SegBase(ds)+(Bit16u)(reg_bx); } + +static PhysPt EA_16_40_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); } +static PhysPt EA_16_41_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); } +static PhysPt EA_16_42_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); } +static PhysPt EA_16_43_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); } +static PhysPt EA_16_44_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchbs()); } +static PhysPt EA_16_45_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchbs()); } +static PhysPt EA_16_46_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchbs()); } +static PhysPt EA_16_47_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchbs()); } + +static PhysPt EA_16_80_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); } +static PhysPt EA_16_81_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); } +static PhysPt EA_16_82_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); } +static PhysPt EA_16_83_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); } +static PhysPt EA_16_84_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchws()); } +static PhysPt EA_16_85_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchws()); } +static PhysPt EA_16_86_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchws()); } +static PhysPt EA_16_87_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchws()); } + +static GetEATable GetEA_NONE={ +/* 00 */ + EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, + EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, + EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, + EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, + EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, + EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, + EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, + EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, +/* 01 */ + EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, + EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, + EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, + EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, + EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, + EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, + EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, + EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, +/* 10 */ + EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, + EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, + EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, + EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, + EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, + EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, + EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, + EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, +/* 11 These are illegal so make em 0 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + + + +static PhysPt EA_16_00_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_si); } +static PhysPt EA_16_01_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_di); } +static PhysPt EA_16_02_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_si); } +static PhysPt EA_16_03_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_di); } +static PhysPt EA_16_04_s(void) { return core.seg_prefix_base+(Bit16u)(reg_si); } +static PhysPt EA_16_05_s(void) { return core.seg_prefix_base+(Bit16u)(reg_di); } +static PhysPt EA_16_06_s(void) { return core.seg_prefix_base+(Bit16u)(Fetchw()); } +static PhysPt EA_16_07_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx); } + +static PhysPt EA_16_40_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); } +static PhysPt EA_16_41_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); } +static PhysPt EA_16_42_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); } +static PhysPt EA_16_43_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); } +static PhysPt EA_16_44_s(void) { return core.seg_prefix_base+(Bit16u)(reg_si+Fetchbs()); } +static PhysPt EA_16_45_s(void) { return core.seg_prefix_base+(Bit16u)(reg_di+Fetchbs()); } +static PhysPt EA_16_46_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+Fetchbs()); } +static PhysPt EA_16_47_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+Fetchbs()); } + +static PhysPt EA_16_80_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); } +static PhysPt EA_16_81_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); } +static PhysPt EA_16_82_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); } +static PhysPt EA_16_83_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); } +static PhysPt EA_16_84_s(void) { return core.seg_prefix_base+(Bit16u)(reg_si+Fetchws()); } +static PhysPt EA_16_85_s(void) { return core.seg_prefix_base+(Bit16u)(reg_di+Fetchws()); } +static PhysPt EA_16_86_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+Fetchws()); } +static PhysPt EA_16_87_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+Fetchws()); } + +static GetEATable GetEA_SEG={ +/* 00 */ + EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, + EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, + EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, + EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, + EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, + EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, + EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, + EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, +/* 01 */ + EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, + EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, + EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, + EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, + EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, + EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, + EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, + EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, +/* 10 */ + EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, + EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, + EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, + EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, + EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, + EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, + EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, + EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, +/* 11 These are illegal so make em 0 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static Bit32u SIBZero=0; +static Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi }; + +INLINE PhysPt Sib(Bitu mode) { + Bit8u sib=Fetchb(); + PhysPt base; + switch (sib&7) { + case 0: /* EAX Base */ + base=SegBase(ds)+reg_eax;break; + case 1: /* ECX Base */ + base=SegBase(ds)+reg_ecx;break; + case 2: /* EDX Base */ + base=SegBase(ds)+reg_edx;break; + case 3: /* EBX Base */ + base=SegBase(ds)+reg_ebx;break; + case 4: /* ESP Base */ + base=SegBase(ss)+reg_esp;break; + case 5: /* #1 Base */ + if (!mode) { + base=SegBase(ds)+Fetchd();break; + } else { + base=SegBase(ss)+reg_ebp;break; + } + case 6: /* ESI Base */ + base=SegBase(ds)+reg_esi;break; + case 7: /* EDI Base */ + base=SegBase(ds)+reg_edi;break; + } + base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6); + return base; +}; + + +static PhysPt EA_32_00_n(void) { return SegBase(ds)+reg_eax; } +static PhysPt EA_32_01_n(void) { return SegBase(ds)+reg_ecx; } +static PhysPt EA_32_02_n(void) { return SegBase(ds)+reg_edx; } +static PhysPt EA_32_03_n(void) { return SegBase(ds)+reg_ebx; } +static PhysPt EA_32_04_n(void) { return Sib(0);} +static PhysPt EA_32_05_n(void) { return SegBase(ds)+Fetchd(); } +static PhysPt EA_32_06_n(void) { return SegBase(ds)+reg_esi; } +static PhysPt EA_32_07_n(void) { return SegBase(ds)+reg_edi; } + +static PhysPt EA_32_40_n(void) { return SegBase(ds)+reg_eax+Fetchbs(); } +static PhysPt EA_32_41_n(void) { return SegBase(ds)+reg_ecx+Fetchbs(); } +static PhysPt EA_32_42_n(void) { return SegBase(ds)+reg_edx+Fetchbs(); } +static PhysPt EA_32_43_n(void) { return SegBase(ds)+reg_ebx+Fetchbs(); } +static PhysPt EA_32_44_n(void) { PhysPt temp=Sib(1);return temp+Fetchbs();} +//static PhysPt EA_32_44_n(void) { return Sib(1)+Fetchbs();} +static PhysPt EA_32_45_n(void) { return SegBase(ss)+reg_ebp+Fetchbs(); } +static PhysPt EA_32_46_n(void) { return SegBase(ds)+reg_esi+Fetchbs(); } +static PhysPt EA_32_47_n(void) { return SegBase(ds)+reg_edi+Fetchbs(); } + +static PhysPt EA_32_80_n(void) { return SegBase(ds)+reg_eax+Fetchds(); } +static PhysPt EA_32_81_n(void) { return SegBase(ds)+reg_ecx+Fetchds(); } +static PhysPt EA_32_82_n(void) { return SegBase(ds)+reg_edx+Fetchds(); } +static PhysPt EA_32_83_n(void) { return SegBase(ds)+reg_ebx+Fetchds(); } +static PhysPt EA_32_84_n(void) { PhysPt temp=Sib(2);return temp+Fetchds();} +//static PhysPt EA_32_84_n(void) { return Sib(2)+Fetchds();} +static PhysPt EA_32_85_n(void) { return SegBase(ss)+reg_ebp+Fetchds(); } +static PhysPt EA_32_86_n(void) { return SegBase(ds)+reg_esi+Fetchds(); } +static PhysPt EA_32_87_n(void) { return SegBase(ds)+reg_edi+Fetchds(); } + +static GetEATable GetEA_ADDR={ +/* 00 */ + EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, + EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, + EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, + EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, + EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, + EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, + EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, + EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, +/* 01 */ + EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, + EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, + EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, + EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, + EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, + EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, + EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, + EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, +/* 10 */ + EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, + EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, + EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, + EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, + EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, + EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, + EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, + EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, +/* 11 These are illegal so make em 0 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +INLINE PhysPt Sib_s(Bitu mode) { + Bit8u sib=Fetchb(); + PhysPt base; + switch (sib&7) { + case 0: /* EAX Base */ + base=reg_eax;break; + case 1: /* ECX Base */ + base=reg_ecx;break; + case 2: /* EDX Base */ + base=reg_edx;break; + case 3: /* EBX Base */ + base=reg_ebx;break; + case 4: /* ESP Base */ + base=reg_esp;break; + case 5: /* #1 Base */ + if (!mode) { + base=Fetchd();break; + } else { + base=reg_ebp;break; + } + case 6: /* ESI Base */ + base=reg_esi;break; + case 7: /* EDI Base */ + base=reg_edi;break; + } + base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6); + return base; +}; + + +static PhysPt EA_32_00_s(void) { return core.seg_prefix_base+(Bit32u)(reg_eax); } +static PhysPt EA_32_01_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ecx); } +static PhysPt EA_32_02_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edx); } +static PhysPt EA_32_03_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebx); } +static PhysPt EA_32_04_s(void) { return core.seg_prefix_base+(Bit32u)(Sib_s(0));} +static PhysPt EA_32_05_s(void) { return core.seg_prefix_base+(Bit32u)(Fetchd()); } +static PhysPt EA_32_06_s(void) { return core.seg_prefix_base+(Bit32u)(reg_esi); } +static PhysPt EA_32_07_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edi); } + +static PhysPt EA_32_40_s(void) { return core.seg_prefix_base+(Bit32u)(reg_eax+Fetchbs()); } +static PhysPt EA_32_41_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ecx+Fetchbs()); } +static PhysPt EA_32_42_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edx+Fetchbs()); } +static PhysPt EA_32_43_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebx+Fetchbs()); } +static PhysPt EA_32_44_s(void) { PhysPt temp=Sib_s(1);return core.seg_prefix_base+(Bit32u)(temp+Fetchbs());} +static PhysPt EA_32_45_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebp+Fetchbs()); } +static PhysPt EA_32_46_s(void) { return core.seg_prefix_base+(Bit32u)(reg_esi+Fetchbs()); } +static PhysPt EA_32_47_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edi+Fetchbs()); } + +static PhysPt EA_32_80_s(void) { return core.seg_prefix_base+(Bit32u)(reg_eax+Fetchds()); } +static PhysPt EA_32_81_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ecx+Fetchds()); } +static PhysPt EA_32_82_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edx+Fetchds()); } +static PhysPt EA_32_83_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebx+Fetchds()); } +static PhysPt EA_32_84_s(void) { PhysPt temp=Sib_s(2);return core.seg_prefix_base+(Bit32u)(temp+Fetchds());} +static PhysPt EA_32_85_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebp+Fetchds()); } +static PhysPt EA_32_86_s(void) { return core.seg_prefix_base+(Bit32u)(reg_esi+Fetchds()); } +static PhysPt EA_32_87_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edi+Fetchds()); } + + +static GetEATable GetEA_SEG_ADDR={ +/* 00 */ + EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, + EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, + EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, + EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, + EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, + EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, + EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, + EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, +/* 01 */ + EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, + EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, + EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, + EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, + EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, + EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, + EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, + EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, +/* 10 */ + EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, + EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, + EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, + EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, + EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, + EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, + EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, + EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, +/* 11 These are illegal so make em 0 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +#define GetEADirect \ + PhysPt eaa; \ + if (TEST_PREFIX_SEG) { \ + if (TEST_PREFIX_ADDR) { \ + eaa=core.seg_prefix_base+Fetchd(); \ + } else { \ + eaa=core.seg_prefix_base+Fetchw(); \ + } \ + } else { \ + if (TEST_PREFIX_ADDR) { \ + eaa=SegBase(ds)+Fetchd(); \ + } else { \ + eaa=SegBase(ds)+Fetchw(); \ + } \ + } + + diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index c44dcd7a..5e7662af 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -44,14 +44,19 @@ CPU_Decoder * cpudecoder; void CPU_Real_16_Slow_Start(bool big); void CPU_Core_Full_Start(bool big); -void CPU_Core_Insane_Start(bool big); +void CPU_Core_Normal_Start(bool big); +#if 1 -typedef void DecoderStart(void); +#define realcore_start CPU_Core_Normal_Start +#define pmodecore_start CPU_Core_Normal_Start -#define realcore_start CPU_Real_16_Slow_Start -//#define realcore_start CPU_Core_Insane_Start -//#define realcore_start CPU_Core_Full_Start +#else + +#define realcore_start CPU_Core_Full_Start +#define pmodecore_start CPU_Core_Full_Start + +#endif void CPU_Push16(Bitu value) { reg_esp-=2; @@ -86,7 +91,7 @@ PhysPt SelBase(Bitu sel) { } void CPU_SetFlags(Bitu word) { - flags.word=(word|2)&~0x14; + flags.word=(word|2)&~0x28; } bool CPU_CheckCodeType(CODE_TYPE type) { @@ -97,10 +102,10 @@ bool CPU_CheckCodeType(CODE_TYPE type) { realcore_start(false); break; case CODE_PMODE16: - CPU_Core_Full_Start(false); + pmodecore_start(false); break; case CODE_PMODE32: - CPU_Core_Full_Start(true); + pmodecore_start(true); break; } return false; @@ -272,7 +277,7 @@ bool CPU_IRET(bool use32) { Segs.val[cs]=(selector & 0xfffc) | cpu.cpl;; reg_eip=offset; CPU_SetFlags(old_flags); - LOG_MSG("IRET:Same level return to %X:%X",selector,offset); + LOG_MSG("IRET:Same level return to %X:%X big %d",selector,offset,cpu.code.big); } else { /* Return to higher privilege */ switch (desc.Type()) { @@ -303,7 +308,7 @@ bool CPU_IRET(bool use32) { reg_esp=new_esp; CPU_SetSegGeneral(ss,new_ss); //TODO Maybe validate other segments, but why would anyone use them? - LOG_MSG("IRET:Outer level return to %X:%X",selector,offset); + LOG_MSG("IRET:Outer level return to %X:X big %d",selector,offset,cpu.code.big); } return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); } @@ -329,11 +334,11 @@ bool CPU_JMP(bool use32,Bitu selector,Bitu offset) { if (rpl>cpu.cpl) E_Exit("JMP:NC:RPL>CPL"); if (rpl!=desc.DPL()) E_Exit("JMP:NC:RPL != DPL"); cpu.cpl=desc.DPL(); - LOG_MSG("JMP:Code:NC to %X:%X",selector,offset); + LOG_MSG("JMP:Code:NC to %X:%X big %d",selector,offset,desc.Big()); goto CODE_jmp; case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: - LOG_MSG("JMP:Code:C to %X:%X",selector,offset); + LOG_MSG("JMP:Code:C to %X:%X big %d",selector,offset,desc.Big()); CODE_jmp: /* Normal jump to another selector:offset */ Segs.phys[cs]=desc.GetBase(); @@ -524,7 +529,6 @@ bool CPU_SET_CRX(Bitu cr,Bitu value) { cpu.pmode=true; LOG_MSG("Protected mode"); PAGING_Enable((value & CR0_PAGING)>0); - CPU_Core_Full_Start(cpu.code.big); } else { cpu.pmode=false; PAGING_Enable(false); @@ -578,6 +582,7 @@ void CPU_ARPL(Bitu & dest_sel,Bitu src_sel) { void CPU_LAR(Bitu selector,Bitu & ar) { Descriptor desc;Bitu rpl=selector & 3; + ar=0; if (!cpu.gdt.GetDescriptor(selector,desc)){ SETFLAGBIT(ZF,false); return; @@ -625,6 +630,7 @@ void CPU_LAR(Bitu selector,Bitu & ar) { void CPU_LSL(Bitu selector,Bitu & limit) { Descriptor desc;Bitu rpl=selector & 3; + limit=0; if (!cpu.gdt.GetDescriptor(selector,desc)){ SETFLAGBIT(ZF,false); return; From a91af64d77e02aa5d9cb162b4e4d1fef4399e3d9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 23 Aug 2003 07:13:06 +0000 Subject: [PATCH 1120/4131] Changed SHLD and SHRD instructions to use common function defines. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1200 --- src/cpu/core_normal/prefix_66_0f.h | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index d24ebc8a..dc100f62 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -176,13 +176,11 @@ break; } CASE_0F_D(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; - } - + RMEdGdOp3(DSHLD,Fetchb()); + break; + CASE_0F_D(0xa5) /* SHLD Ed,Gd,CL */ + RMEdGdOp3(DSHLD,reg_cl); + break; CASE_0F_D(0xa8) /* PUSH GS */ Push_32(SegValue(gs));break; CASE_0F_D(0xa9) /* POP GS */ @@ -205,19 +203,11 @@ } CASE_0F_D(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_0F_D(0xad) /* SHRD Ed,Gd,Cl */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArd;DSHRD(*eard,*rmrd,reg_cl,LoadRd,SaveRd);} - else {GetEAa;DSHRD(eaa,*rmrd,reg_cl,LoadMd,SaveMd);} - break; - } + RMEdGdOp3(DSHRD,Fetchb()); + break; + CASE_0F_D(0xad) /* SHRD Ed,Gd,CL */ + RMEdGdOp3(DSHRD,reg_cl); + break; CASE_0F_D(0xb4) /* LFS Ed */ { GetRMrd;GetEAa; From 42cf596c568991a57d204c01a8699a268e4a9183 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 23 Aug 2003 11:00:08 +0000 Subject: [PATCH 1121/4131] Fix correct address of linear frame buffer. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1201 --- src/hardware/vga_crtc.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 13280529..ebddee0e 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -422,12 +422,12 @@ void write_p3d5(Bit32u port,Bit8u val) { 7 (928) RAS 6-MCLK. If set the random read/write cycle time is 6MCLKs, if clear 7MCLKs */ - case 0x59: /* Linear Address Window Position Low */ - vga.s3.la_window=(vga.s3.la_window&0xff00) | val; + case 0x59: /* Linear Address Window Position High */ + vga.s3.la_window=(vga.s3.la_window&0x00ff) | (val << 8); VGA_StartUpdateLFB(); break; - case 0x5a: /* Linear Address Window Position High */ - vga.s3.la_window=(vga.s3.la_window&0x00ff) | (val << 8); + case 0x5a: /* Linear Address Window Position Low */ + vga.s3.la_window=(vga.s3.la_window&0xff00) | val; VGA_StartUpdateLFB(); break; case 0x5D: /* Extended Horizontal Overflow */ From 8cd083552e5b22b5599ca87ca6fe6834810d111a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 23 Aug 2003 11:01:28 +0000 Subject: [PATCH 1122/4131] Lower delay for setting up the new LFB address in memory Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1202 --- src/hardware/vga_memory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 5f8fe67e..23e43b4d 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -197,13 +197,13 @@ bool lfb_update; static void VGA_DoUpdateLFB(void) { lfb_update=false; - MEM_SetLFB(vga.s3.la_window << 4,sizeof(vga.mem.linear)/4096,&vga.mem.linear[0]); + MEM_SetLFB(vga.s3.la_window << 4 ,sizeof(vga.mem.linear)/4096,&vga.mem.linear[0]); } void VGA_StartUpdateLFB(void) { if (!lfb_update) { lfb_update=true; - PIC_AddEvent(VGA_DoUpdateLFB,2000); //2 milliseconds later + PIC_AddEvent(VGA_DoUpdateLFB,100); //100 microseconds later } } From ef53831d80c97105eadef759cb2c399882284cee Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 24 Aug 2003 14:43:15 +0000 Subject: [PATCH 1123/4131] A NEWLINE Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1203 --- include/paging.h | 3 +-- src/cpu/core_normal/string.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/paging.h b/include/paging.h index 172612a9..73169bc2 100644 --- a/include/paging.h +++ b/include/paging.h @@ -221,5 +221,4 @@ INLINE void mem_writed_inline(PhysPt address,Bit32u val) { else ENTRY_writed(plink->entry,address,val); } - -#endif \ No newline at end of file +#endif diff --git a/src/cpu/core_normal/string.h b/src/cpu/core_normal/string.h index 524025f4..4fce8638 100644 --- a/src/cpu/core_normal/string.h +++ b/src/cpu/core_normal/string.h @@ -240,4 +240,4 @@ static void DoString(STRING_OP type) { reg_ecx&=(~add_mask); reg_ecx|=(count & add_mask); } -} \ No newline at end of file +} From ad6ba002e1819a72e66095401c3657d0e93bcc4a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 24 Aug 2003 14:44:32 +0000 Subject: [PATCH 1124/4131] Some new configure options for core inlining and heavy debugging. Fixed the --disable-fpu option Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1204 --- acinclude.m4 | 12 ------------ configure.in | 35 +++++++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 84406fc3..f0a8266b 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -303,9 +303,6 @@ AC_SUBST(ALSA_CFLAGS) AC_SUBST(ALSA_LIBS) ]) - - - AH_TOP([ /* * Copyright (C) 2002-2003 The DOSBox Team @@ -334,13 +331,4 @@ AH_BOTTOM([#if C_HAS_ATTRIBUTE #define GCC_ATTRIBUTE(x) /* attribute not supported */ #endif]) -AH_BOTTOM([ -/* Enable some heavy debugging options */ -#define C_HEAVY_DEBUG 0 - -/* Enable some big compile-time increasing inlines */ -#define C_EXTRAINLINE 0 - -]) - diff --git a/configure.in b/configure.in index fafa8333..d1bea377 100644 --- a/configure.in +++ b/configure.in @@ -60,23 +60,45 @@ 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(pdcurses, initscr, have_pdcurses_lib=yes, , ) if test x$have_curses_lib = xyes -a x$have_curses_h = xyes ; then - LIBS="$LIBS -lcurses" + 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_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_WARN([Can't enable debug mode without libcurses]) + AC_MSG_WARN([Can't find curses, debug mode disabled]) 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 +],) + AH_TEMPLATE(C_FPU,[Define to 1 to enable floating point emulation]) - AC_ARG_ENABLE(fpu,AC_HELP_STRING([--disable-fpu],[Disable FPU support]), - AC_MSG_RESULT([FPU support has been disabled]), - AC_DEFINE(C_FPU,1) -) +AC_ARG_ENABLE(fpu,AC_HELP_STRING([--disable-fpu],[Disable FPU support]),[ + if test x$enable_fpu = xno ; then + AC_MSG_RESULT([disabling FPU supportd]) + else + AC_DEFINE(C_FPU,1) + fi +],AC_DEFINE(C_FPU,1)) AH_TEMPLATE(C_SSHOT,[Define to 1 to enable screenshots, requires libpng]) AC_CHECK_HEADER(png.h,have_png_h=yes,) @@ -121,6 +143,7 @@ src/Makefile src/cpu/Makefile src/cpu/core_16/Makefile src/cpu/core_full/Makefile +src/cpu/core_normal/Makefile src/debug/Makefile src/dos/Makefile src/fpu/Makefile From 67e1e4d00fc0b49aaa29fbe928bc8f6d059c5995 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 24 Aug 2003 14:46:21 +0000 Subject: [PATCH 1125/4131] Cast some Bit8u string to char Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1205 --- src/ints/dpmi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index 6e562693..cf94c483 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -2767,7 +2767,7 @@ Bitu DPMI::API_Int21_MSDOS(void) case 0x40: {/* WRITE Write to file or device */ Bit16u towrite = Mask(reg_ecx); MEM_BlockRead(SegPhys(ds)+Mask(reg_edx),dos_copybuf,towrite); - if (reg_bx>=5) LOG(LOG_MISC,LOG_ERROR)("INT 21 40: %s",dos_copybuf); + if (reg_bx>=5) LOG(LOG_MISC,LOG_ERROR)("INT 21 40: %s",(char *)dos_copybuf); if (DOS_WriteFile(reg_bx,dos_copybuf,&towrite)) { reg_eax=towrite; DPMI_CALLBACK_SCF(false); From c9a62c462f314b67aa0ddd24465c152f7c46ee06 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 29 Aug 2003 08:16:48 +0000 Subject: [PATCH 1126/4131] Removed an E_Exit from an illegal call, seems to fix impulse tracker. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1206 --- src/dos/dos.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index fc6da360..fe98e810 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -532,7 +532,9 @@ static Bitu DOS_21Handler(void) { CALLBACK_SCF(false); break; default: - E_Exit("DOS:0x43:Illegal subfunction %2X",reg_al); + LOG(LOG_MISC,LOG_ERROR)("DOS:0x43:Illegal subfunction %2X",reg_al); + CALLBACK_SCF(false); + break; } break; case 0x44: /* IOCTL Functions */ From 9c53a50c704f6982b1e9c16be5cb057bd80ffd54 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 29 Aug 2003 08:17:49 +0000 Subject: [PATCH 1127/4131] Fix some conversion warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1207 --- src/dos/dos_files.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 086a1f88..4fe7b066 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.43 2003-08-11 11:49:58 finsterr Exp $ */ +/* $Id: dos_files.cpp,v 1.44 2003-08-29 08:17:49 harekiet Exp $ */ #include #include @@ -403,7 +403,7 @@ bool DOS_OpenFileExtended(char *name, Bit16u flags, Bit16u createAttr, Bit16u ac // FIXME: Not yet supported : Bit 13 of flags (int 0x24 on critical error { Bit16u result = 0; - if (DOS_OpenFile(name, flags, entry)) { + if (DOS_OpenFile(name, (Bit8u)flags, entry)) { // File already exists switch (action & 0x0f) { case 0x00 : return false; // failed @@ -693,7 +693,7 @@ bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { if (!DOS_MakeName(shortname,fullname,&drive)) return false; /* Check, if file is already opened */ - for (Bit16u i=0;iIsOpen() && Files[i]->IsName(fullname)) { handle = psp.FindEntryByHandle(i); From 942bef0e094251d27c6cc0500095d3a51304cf36 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 29 Aug 2003 08:38:59 +0000 Subject: [PATCH 1128/4131] Some updates to DMA to allow better handling of masked bit and reaching terminal count. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1208 --- src/hardware/dma.cpp | 79 ++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 29 deletions(-) diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 80608ac1..d90ef803 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -32,12 +32,6 @@ #include "dma.h" #include "pic.h" -#if DEBUG_DMA -#define DMA_DEBUG LOG_DEBUG -#else -#define DMA_DEBUG -#endif - #define DMA_MODE_DEMAND 0 #define DMA_MODE_SINGLE 1 #define DMA_MODE_BLOCK 2 @@ -71,7 +65,9 @@ struct DMA_CONTROLLER { }; static DMA_CONTROLLER dma[2]; -void DMA_TestChannel(DMA_CHANNEL * chan); + +void DMA_CheckEnabled(DMA_CHANNEL * chan); +void DMA_SetEnabled(DMA_CHANNEL * chan,bool enabled); static Bit8u read_dma(Bit32u port) { /* only use first dma for now */ @@ -107,10 +103,10 @@ static Bit8u read_dma(Bit32u port) { default: LOG(LOG_DMA,LOG_ERROR)("DMA:Unhandled read from %X",port); } +// LOG_MSG("DMA Read port %x result %x",port,ret); return ret; } - static void write_dma(Bit32u port,Bit8u val) { /* only use first dma for now */ DMA_CONTROLLER * cont=&dma[0]; @@ -123,7 +119,6 @@ static void write_dma(Bit32u port,Bit8u val) { } else { chan->base_address=(chan->base_address & 0x00ff) | (val<<8); } -// LOG_MSG("DMA:Address %X",chan->base_address); cont->flipflop=!cont->flipflop; chan->addr_changed=true; break; @@ -134,10 +129,9 @@ static void write_dma(Bit32u port,Bit8u val) { } else { chan->base_count=(chan->base_count & 0x00ff) | (val<<8); } -// LOG_MSG("DMA:count %X",chan->base_count); cont->flipflop=!cont->flipflop; chan->addr_changed=true; - DMA_TestChannel(chan); + DMA_CheckEnabled(chan); break; case 0x08: /* Command Register */ if (val != 4) LOG(LOG_DMA,LOG_ERROR)("DMA1:Illegal command %2X",val); @@ -155,8 +149,13 @@ static void write_dma(Bit32u port,Bit8u val) { break; case 0x0a: /* single mask bit register */ chan=&cont->chan[val & 0x3]; - chan->masked=(val & 4)>0; - DMA_TestChannel(chan); + if ((val & 4)>0) { + DMA_SetEnabled(chan,false); + chan->masked=(val & 4)>0; //Set it later + } else { + chan->masked=(val & 4)>0; + DMA_CheckEnabled(chan); + } break; case 0x0b: /* mode register */ chan=&cont->chan[val & 0x3]; @@ -167,7 +166,7 @@ static void write_dma(Bit32u port,Bit8u val) { if (chan->mode.address_decrement) { LOG(LOG_DMA,LOG_ERROR)("DMA:Address Decrease not supported yet"); } - DMA_TestChannel(chan); + DMA_CheckEnabled(chan); break; case 0x0c: /* Clear Flip/Flip */ cont->flipflop=true; @@ -177,7 +176,6 @@ static void write_dma(Bit32u port,Bit8u val) { }; }; - void write_dma_page(Bit32u port,Bit8u val) { Bitu channel; switch (port) { @@ -194,20 +192,33 @@ void write_dma_page(Bit32u port,Bit8u val) { dma[0].chan[channel].addr_changed=true; } +Bit8u read_dma_page(Bit32u port) { + Bitu channel; + switch (port) { + case 0x81: /* dma0 page register, channel 2 */ + channel=2;break; + case 0x82: /* dma0 page register, channel 3 */ + channel=3;break; + case 0x83: /* dma0 page register, channel 1 */ + channel=1;break; + case 0x87: /* dma0 page register, channel 0 */ + channel=0;break; + } + return dma[0].chan[channel].page; +} INLINE void ResetDMA8(DMA_CHANNEL * chan) { chan->addr_changed=false; chan->address=(chan->page << 16)+chan->base_address; chan->current_count=chan->base_count+1; chan->current_address=chan->base_address; -// LOG_MSG("DMA8:Setup at address %X:%X count %X",chan->page<<12,chan->base_address,chan->current_count); + LOG(LOG_DMA,LOG_NORMAL)("Setup at address %X:%X count %X",chan->page<<12,chan->base_address,chan->current_count); } - - Bitu DMA_8_Read(Bitu dmachan,Bit8u * buffer,Bitu count) { DMA_CHANNEL * chan=&dma[0].chan[dmachan]; - if (chan->masked || !count) return 0; + if (chan->masked) return 0; + if (!count) return 0; if (chan->addr_changed) ResetDMA8(chan); if (chan->current_count>count) { MEM_BlockRead(chan->address,buffer,count); @@ -222,10 +233,10 @@ Bitu DMA_8_Read(Bitu dmachan,Bit8u * buffer,Bitu count) { /* Set the end of counter bit */ dma[0].status_reg|=(1 << dmachan); count=chan->current_count; - chan->current_address+=count;; + chan->address+=count; chan->current_count=0; - if (chan->enable_callback) chan->enable_callback(false); chan->enabled=false; + LOG(LOG_DMA,LOG_NORMAL)("8-bit Channel %d reached terminal count"); return count; } else { buffer+=chan->current_count; @@ -244,7 +255,8 @@ Bitu DMA_8_Read(Bitu dmachan,Bit8u * buffer,Bitu count) { Bitu DMA_8_Write(Bitu dmachan,Bit8u * buffer,Bitu count) { DMA_CHANNEL * chan=&dma[0].chan[dmachan]; - if (chan->masked || !count) return 0; + if (chan->masked) return 0; + if (!count) return 0; if (chan->addr_changed) ResetDMA8(chan); if (chan->current_count>count) { MEM_BlockWrite(chan->address,buffer,count); @@ -261,6 +273,7 @@ Bitu DMA_8_Write(Bitu dmachan,Bit8u * buffer,Bitu count) { count=chan->current_count; chan->current_address+=count;; chan->current_count=0; + chan->enabled=false; return count; } else { buffer+=chan->current_count; @@ -289,8 +302,13 @@ Bitu DMA_16_Write(Bitu dmachan,Bit8u * buffer,Bitu count) { return 0; } -void DMA_TestChannel(DMA_CHANNEL * chan) { - if (!chan->enable_callback) return; +void DMA_SetEnabled(DMA_CHANNEL * chan,bool enabled) { + if (chan->enabled == enabled) return; + chan->enabled=enabled; + if (chan->enable_callback) (*chan->enable_callback)(enabled); +} + +void DMA_CheckEnabled(DMA_CHANNEL * chan) { bool enabled; if (chan->masked) enabled=false; else { @@ -298,10 +316,7 @@ void DMA_TestChannel(DMA_CHANNEL * chan) { else if (chan->current_count || chan->addr_changed) enabled=true; else enabled=false; } - if (enabled == chan->enabled) return; - chan->enabled=enabled; - chan->enable_callback(enabled); - + DMA_SetEnabled(chan,enabled); } @@ -314,7 +329,7 @@ void DMA_SetEnableCallBack(Bitu channel,DMA_EnableCallBack callback) { } else return; chan->enabled=false; chan->enable_callback=callback; - DMA_TestChannel(chan); + DMA_CheckEnabled(chan); } void DMA_Init(Section* sec) { @@ -327,4 +342,10 @@ void DMA_Init(Section* sec) { IO_RegisterWriteHandler(0x82,write_dma_page,"DMA Pages"); IO_RegisterWriteHandler(0x83,write_dma_page,"DMA Pages"); IO_RegisterWriteHandler(0x87,write_dma_page,"DMA Pages"); + + IO_RegisterReadHandler(0x81,read_dma_page,"DMA Pages"); + IO_RegisterReadHandler(0x82,read_dma_page,"DMA Pages"); + IO_RegisterReadHandler(0x83,read_dma_page,"DMA Pages"); + IO_RegisterReadHandler(0x87,read_dma_page,"DMA Pages"); + } From d3ee970936a73d621e92683108c28ce8d64e10ae Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 31 Aug 2003 20:04:55 +0000 Subject: [PATCH 1129/4131] Change EXTRA_INLINE define to CORE_INLINE Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1209 --- src/platform/visualc/config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 51b6dc26..b0f14bd6 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -14,8 +14,8 @@ /* Enable some heavy debugging options */ #define C_HEAVY_DEBUG 0 -/* Enable some big compile-time increasing inlines */ -#define C_EXTRAINLINE 0 +/* Enable memory function inlining in */ +#define C_CORE_INLINE 0 /* Enable the FPU module, still only for beta testing */ #define C_FPU 1 From 10a29d64de4717dc2bfa19beaa8ca741029f3c17 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 31 Aug 2003 20:05:23 +0000 Subject: [PATCH 1130/4131] Fix some compile warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1210 --- src/platform/visualc/dirent.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/visualc/dirent.c b/src/platform/visualc/dirent.c index cc536bf3..d2e25c2a 100644 --- a/src/platform/visualc/dirent.c +++ b/src/platform/visualc/dirent.c @@ -20,7 +20,7 @@ DIR * opendir(const char *dirname) { static DIR dir; - int len; + size_t len; /* Stash the directory name */ strcpy(dir.pathName,dirname); @@ -81,7 +81,7 @@ struct dirent * readdir(DIR *dirp) { memset(&d,'\0', sizeof(struct dirent)); strcpy(d.d_name,dirp->findFileData.cFileName); - d.d_namlen = strlen(d.d_name); + d.d_namlen = (char)strlen(d.d_name); return &d; } From 5183db22023de7e7c4684f3d42ae42805f320572 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 31 Aug 2003 20:34:52 +0000 Subject: [PATCH 1131/4131] Prevent added autoexec lines in config file to be parsed by sprintf Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1211 --- src/shell/shell.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index f82fcb77..1e5dfc83 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -207,7 +207,7 @@ void AUTOEXEC_Init(Section * sec) { std::string line; Section_line * section=static_cast(sec); char * extra=(char *)section->data.c_str(); - if (extra) SHELL_AddAutoexec(extra); + if (extra) SHELL_AddAutoexec("%s",extra); /* Check for first command being a directory or file */ char buffer[CROSS_LEN]; if (control->cmdline->FindCommand(1,line)) { From fcca902bc8120d72add754f48d47b4e58613232c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 1 Sep 2003 08:08:22 +0000 Subject: [PATCH 1132/4131] Always allocate a console Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1212 --- src/debug/debug_win32.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/debug/debug_win32.cpp b/src/debug/debug_win32.cpp index 33c1ea54..cfed35e1 100644 --- a/src/debug/debug_win32.cpp +++ b/src/debug/debug_win32.cpp @@ -68,8 +68,7 @@ static void ResizeConsole( HANDLE hConsole, SHORT xSize, SHORT ySize ) { void WIN32_Console() { + AllocConsole(); ResizeConsole(GetStdHandle(STD_OUTPUT_HANDLE),80,50); - - } #endif From a67453b78e471ca09d1de8cfc3674ec1d2223e45 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 1 Sep 2003 14:27:57 +0000 Subject: [PATCH 1133/4131] Added SBPRO 2.0 support Added a new ADPCM decoding algorithm Added better timing for short detection dma transfers Added new registers to mixer Some new debug messages and clean up Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1213 --- src/hardware/sblaster.cpp | 252 +++++++++++++++++++++++++++++--------- 1 file changed, 193 insertions(+), 59 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 864e52c0..d2a44eb2 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include #include #include "dosbox.h" #include "inout.h" @@ -26,11 +27,12 @@ #include "setup.h" #include "programs.h" - #define SB_PIC_EVENTS 0 +#define SB_NEW_ADPCM 1 -#define DSP_MAJOR 2 -#define DSP_MINOR 0 + +#define DSP_MAJOR 3 +#define DSP_MINOR 1 #define MIXER_INDEX 0x04 #define MIXER_DATA 0x05 @@ -51,6 +53,8 @@ #define SB_BUF_SIZE 8096 enum {DSP_S_RESET,DSP_S_NORMAL,DSP_S_HIGHSPEED}; +enum SB_IRQS {SB_IRQ_8,SB_IRQ_16,SB_IRQ_MPU}; + enum DSP_MODES { MODE_NONE,MODE_DAC, @@ -63,6 +67,7 @@ enum DMA_MODES { DMA_8_SILENCE, DMA_4_SINGLE, DMA_8_SINGLE,DMA_8_AUTO, + DMA_16_SINGLE,DMA_16_AUTO, }; enum { @@ -72,7 +77,7 @@ enum { struct SB_INFO { Bit16u freq; struct { - bool active,stereo; + bool active,stereo,filtered; DMA_MODES mode; Bitu total,left; Bitu rate,rate_mul; @@ -87,6 +92,10 @@ struct SB_INFO { Bit8u time_constant; bool use_time_constant; DSP_MODES mode; + struct { + bool pending_8bit; + bool pending_16bit; + } irq; struct { Bit8u state; Bit8u cmd; @@ -107,11 +116,13 @@ struct SB_INFO { } dac; struct { Bit8u index; - Bit8u master; - Bit8u mic,voice,fm; + struct { + Bit8u left,right; + } dac,fm,cda,master,lin; + Bit8u mic; } mixer; struct { - Bits reference,scale; + Bits reference,stepsize; } adpcm; struct { Bitu base; @@ -189,6 +200,19 @@ static void DSP_SetSpeaker(bool how) { sb.speaker=how; } +static INLINE void SB_RaiseIRQ(SB_IRQS type) { + LOG(LOG_SB,LOG_NORMAL)("Raising IRQ"); + PIC_AddIRQ(sb.hw.irq,0); + switch (type) { + case SB_IRQ_8: + sb.irq.pending_8bit=true; + break; + case SB_IRQ_16: + sb.irq.pending_16bit=true; + break; + } +} + static INLINE void DSP_FlushData(void) { sb.dsp.out.used=0; sb.dsp.out.pos=0; @@ -202,15 +226,52 @@ static void DSP_StopDMA(void) { static void DMA_Enable(bool enable) { sb.dma.active=enable; if (sb.mode==MODE_DMA_WAIT && enable) { + LOG(LOG_SB,LOG_NORMAL)("DMA enabled,starting output"); DSP_ChangeMode(MODE_DMA); CheckDMAEnd(); + return; } if (sb.mode==MODE_DMA && !enable) { DSP_ChangeMode(MODE_DMA_WAIT); + LOG(LOG_SB,LOG_NORMAL)("DMA disabled,stopping output"); + return; } } -INLINE Bit8u decode_ADPCM_4_sample(Bit8u sample,Bits& reference,Bits& scale) { + +#define MIN_ADAPTIVE_STEP_SIZE 511 +#define MAX_ADAPTIVE_STEP_SIZE 32767 +#define DC_OFFSET_FADE 254 + +INLINE Bits Clip(Bits sample) { + if (sample>MAX_AUDIO) return MAX_AUDIO; + if (sample> 1)); + if (adpcm & 1 ) scale = Clip(scale + (stepsize >> 2)); + scale = Clip(stepsize >> 3); + if (adpcm & 8) scale = -scale; + + reference=Clip(scale+((reference * DC_OFFSET_FADE) >> 8)); + // compute the next step size + stepsize=(stepsize * quantize[adpcm & 0x7]) >> 8; + if (stepsize < MIN_ADAPTIVE_STEP_SIZE) stepsize=MIN_ADAPTIVE_STEP_SIZE; + else if (stepsize > MAX_ADAPTIVE_STEP_SIZE) stepsize=MAX_ADAPTIVE_STEP_SIZE; + + return (Bit16s)reference; +} + +#else +INLINE Bit16s decode_ADPCM_4_sample(Bit8u sample,Bits& reference,Bits& scale) { static Bits scaleMap[8] = { -2, -1, 0, 0, 1, 1, 1, 1 }; if (sample & 0x08) { @@ -219,61 +280,77 @@ INLINE Bit8u decode_ADPCM_4_sample(Bit8u sample,Bits& reference,Bits& scale) { reference = min(0xff, reference + ((sample & 0x07) << scale)); } scale = max(2, min(6, scaleMap[sample & 0x07])); - return (Bit8u)reference; + return (((Bit8s)reference)^0x80)<<8; } +#endif + static void GenerateDMASound(Bitu size) { - //TODO For stereo make sure it's multiple of 2 + /* Check some variables */ if (!size) return; - Bitu read,i; + if (!sb.dma.rate) return; + /* First check if this transfer is gonna end in the next 2 milliseconds */ + Bitu index=(Bitu)(((float)sb.dma.left*(float)1000000)/(float)sb.dma.rate); +#if (SB_PIC_EVENTS) + if (index-PIC_Index()<1000) PIC_AddEvent(END_DMA_Event,index); +#else + if (index<2000) size=sb.dma.left; +#endif + Bitu read,i; switch (sb.dma.mode) { case DMA_4_SINGLE: - if (sb.adpcm.reference<0 && sb.dma.left) { + if (sb.adpcm.reference==0x1000000 && sb.dma.left) { +//TODO Check this Bit8u ref; read=DMA_8_Read(sb.hw.dma8,&ref,1); if (!read) { sb.mode=MODE_NONE;return; } //TODO warnings? sb.dma.left--; - sb.adpcm.reference=ref; + sb.adpcm.reference=0; + sb.adpcm.stepsize=MIN_ADAPTIVE_STEP_SIZE; } if (sb.dma.left> 4,sb.adpcm.reference,sb.adpcm.scale)^0x80))<<8; - sb.tmp.buf.m[i*2+1]=((Bit8s)(decode_ADPCM_4_sample(sb.dma.buf.b8[i] & 0xf,sb.adpcm.reference,sb.adpcm.scale)^0x80))<<8; + sb.tmp.buf.m[i*2+0]=decode_ADPCM_4_sample(sb.dma.buf.b8[i] >> 4,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[i*2+1]=decode_ADPCM_4_sample(sb.dma.buf.b8[i] & 0xf,sb.adpcm.reference,sb.adpcm.stepsize); } read*=2; break; case DMA_8_SINGLE: if (sb.dma.leftread) { sb.dma.left-=read; } else { sb.dma.left=(sb.dma.total+sb.dma.left)-read; - PIC_AddIRQ(sb.hw.irq,0); + SB_RaiseIRQ(SB_IRQ_8); +// LOG_MSG("SB DMA AUTO IRQ Raised"); } for (i=0;i(pos=sb.tmp.index>>16)) { - (*stream++)=sb.tmp.buf.s[pos][0]; - (*stream++)=sb.tmp.buf.s[pos][1]; - sb.tmp.index+=sb.tmp.add_index; - sb.out.pos++; + if (read&1){ + LOG_MSG("DMA Unaligned"); + } else { + Bitu pos;read>>=1;Bitu index_add=sb.tmp.add_index >> 1; + while (read>(pos=sb.tmp.index>>16)) { + (*stream++)=sb.tmp.buf.s[pos][1]; //SB default seems to be swapped + (*stream++)=sb.tmp.buf.s[pos][0]; + sb.tmp.index+=index_add; + sb.out.pos++; + } + sb.tmp.index&=0xffff; } - sb.tmp.index&=0xffff; } } @@ -337,6 +418,7 @@ static void GenerateSound(Bitu size) { Bitu len=size*sb.dma.rate_mul; if (len & 0xffff) len=1+(len>>16); else len>>=16; + if (sb.dma.stereo && (len & 1)) len++; GenerateDMASound(len); break; } @@ -351,15 +433,14 @@ static void GenerateSound(Bitu size) { static void END_DMA_Event(void) { GenerateDMASound(sb.dma.left); - sb.dma.left=0; - DSP_ChangeMode(MODE_NONE); } static void CheckDMAEnd(void) { if (!sb.dma.rate) return; Bitu index=(Bitu)(((float)sb.dma.left*(float)1000000)/(float)sb.dma.rate); if (index<(1000-PIC_Index())) { -#if SB_PIC_EVENTS +#if 1 + LOG(LOG_SB,LOG_NORMAL)("Sub millisecond transfer scheduling IRQ in %d microseconds",index); PIC_AddEvent(END_DMA_Event,index); #else GenerateDMASound(sb.dma.left); @@ -386,7 +467,6 @@ static void DSP_StartDMATranfser(DMA_MODES mode) { sb.dma.rate=(1000000 / (256 - sb.time_constant)); }; sb.dma.rate_mul=(sb.dma.rate<<16)/sb.hw.rate; - sb.dma.mode=mode; sb.tmp.index=0; switch (mode) { @@ -394,7 +474,6 @@ static void DSP_StartDMATranfser(DMA_MODES mode) { PIC_AddIRQ(sb.hw.irq,((1000000*sb.dma.left)/sb.dma.rate)); sb.dma.mode=DMA_NONE; return; - break; case DMA_8_SINGLE: type="8-Bit Single Cycle"; sb.tmp.add_index=(sb.dma.rate<<16)/sb.hw.rate; @@ -438,6 +517,7 @@ static void DSP_Reset(void) { sb.dsp.write_busy=0; sb.dma.left=0; sb.dma.total=0; + sb.dma.stereo=false; sb.freq=22050; sb.use_time_constant=true; sb.time_constant=45; @@ -445,12 +525,14 @@ static void DSP_Reset(void) { sb.dac.last=0; sb.e2.value=0xaa; sb.e2.count=0; + sb.irq.pending_8bit=false; + sb.irq.pending_16bit=false; DSP_SetSpeaker(false); } static void DSP_DoReset(Bit8u val) { - if (val&1!=0) { + if ((val&1)!=0) { //TODO Get out of highspeed mode DSP_Reset(); sb.dsp.state=DSP_S_RESET; @@ -467,12 +549,16 @@ static void DMA_E2_Enable(bool enable) { Bit8u val=sb.e2.value; DMA_8_Write(sb.hw.dma8,&val,1); DMA_SetEnableCallBack(sb.hw.dma8,0); -// PIC_AddIRQ(sb.hw.irq,0); } } static void DSP_DoCommand(void) { + //LOG_MSG("DSP Command %X",sb.dsp.cmd); switch (sb.dsp.cmd) { + case 0x04: /* DSP Statues SB 2.0/pro version */ + DSP_FlushData(); + DSP_AddData(0xff); //Everthing enabled + break; case 0x10: /* Direct DAC */ DSP_ChangeMode(MODE_DAC); if (sb.dac.used> 4) << 1; break; - case 0x22: /* Master Volume */ - sb.mixer.master=val; + case 0x04: /* DAC Volume (SBPRO) */ + sb.mixer.dac.left= (val & 0xf) << 1; + sb.mixer.dac.right=(val >> 4) << 1; + break; + case 0x06: /* FM output selection, Somewhat obsolete with dual OPL SBpro */ + sb.mixer.fm.left= (val & 0xf) << 1; + sb.mixer.fm.right=(val & 0xf) << 1; + //TODO Change FM Mode if only 1 fm channel is selected + break; + case 0x0a: /* Mic Level */ + sb.mixer.mic=(val & 0xf) << 1; + break; + case 0x0e: /* Output/Stereo Select */ + sb.dma.stereo=(val & 0x2) > 0; + sb.dma.filtered=(val & 0x20) > 0; + LOG(LOG_SB,LOG_WARN)("Mixer set to %s",sb.dma.stereo ? "STEREO" : "MONO"); + break; + case 0x26: /* FM Volume (SBPRO) */ + sb.mixer.fm.left= (val & 0xf) << 1; + sb.mixer.fm.right=(val >> 4) << 1; + break; + case 0x28: /* CD Audio Volume (SBPRO) */ + sb.mixer.cda.left= (val & 0xf) << 1; + sb.mixer.cda.right=(val >> 4) << 1; + break; + case 0x2e: /* Line-IN Volume (SBPRO) */ + sb.mixer.lin.left= (val & 0xf) << 1; + sb.mixer.lin.right=(val >> 4) << 1; break; default: - LOG(LOG_SB,LOG_ERROR)("MIXER:Write to unhandled index %X",sb.mixer.index); + LOG(LOG_SB,LOG_WARN)("MIXER:Write %X to unhandled index %X",val,sb.mixer.index); } } static Bit8u MIXER_Read(void) { Bit8u ret; switch (sb.mixer.index) { + case 0x00: /* RESET */ + return 0x00; + case 0x02: /* Master Voulme (SBPRO) Obsolete? */ + case 0x22: /* Master Volume (SBPRO) */ + return ((sb.mixer.master.left & 0x1e) >> 1) | + ((sb.mixer.master.right & 0x1e) << 3); + case 0x04: /* DAC Volume (SBPRO) */ + return ((sb.mixer.dac.left & 0x1e) >> 1) | + ((sb.mixer.dac.right & 0x1e) << 3); +// case 0x06: /* FM output selection, Somewhat obsolete with dual OPL SBpro */ case 0x0a: /* Mic Level */ - ret=sb.mixer.mic; - case 0x22: /* Master Volume */ - ret=sb.mixer.master; - break; - default: - LOG(LOG_SB,LOG_ERROR)("MIXER:Read from unhandled index %X",sb.mixer.index); - ret=0xff; + return sb.mixer.mic; + case 0x0e: /* Output/Stereo Select */ + return 0x11|(sb.dma.stereo ? 0x02 : 0x00)|(sb.dma.filtered ? 0x20 : 0x00); + case 0x26: /* FM Volume (SBPRO) */ + return ((sb.mixer.fm.left & 0x1e) >> 1) | + ((sb.mixer.fm.right & 0x1e) << 3); + case 0x28: /* CD Audio Volume (SBPRO) */ + return ((sb.mixer.cda.left & 0x1e) >> 1) | + ((sb.mixer.cda.right & 0x1e) << 3); + case 0x2e: /* Line-IN Volume (SBPRO) */ + return ((sb.mixer.lin.left & 0x1e) >> 1) | + ((sb.mixer.lin.right & 0x1e) << 3); + case 0x82: + return (sb.irq.pending_8bit ? 0x1 : 0) | + (sb.irq.pending_16bit ? 0x2 : 0); + default: /* IRQ Status */ + LOG(LOG_SB,LOG_WARN)("MIXER:Read from unhandled index %X",sb.mixer.index); + ret=0xa; } return ret; } @@ -639,8 +773,8 @@ static Bit8u read_sb(Bit32u port) { case DSP_READ_DATA: return DSP_ReadData(); case DSP_READ_STATUS: - //TODO Acknowledge 8bit irq //TODO See for high speed dma :) + sb.irq.pending_8bit=false; if (sb.dsp.out.used) return 0xff; else return 0x7f; case DSP_WRITE_STATUS: @@ -730,5 +864,5 @@ void SBLASTER_Init(Section* sec) { PIC_RegisterIRQ(sb.hw.irq,0,"SB"); DSP_Reset(); - SHELL_AddAutoexec("SET BLASTER=A%3X I%d D%d T3",sb.hw.base,sb.hw.irq,sb.hw.dma8); + SHELL_AddAutoexec("SET BLASTER=A%3X I%d D%d T4",sb.hw.base,sb.hw.irq,sb.hw.dma8); } From 3a869f20de79db238addebbaa5db63d5a30c9666 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 1 Sep 2003 14:28:37 +0000 Subject: [PATCH 1134/4131] Check if cycles need to be lowered when adding new irqs/events Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1214 --- src/hardware/pic.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index d0d666c4..18821383 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -244,29 +244,30 @@ static void AddEntry(PICEntry * entry) { if (!find_entry) { entry->next=0; pic.next_entry=entry; - return; - } - if (find_entry->index>entry->index) { + } else if (find_entry->index>entry->index) { pic.next_entry=entry; entry->next=find_entry; - return; - } - while (find_entry) { + } else while (find_entry) { if (find_entry->next) { /* See if the next index comes later than this one */ - if (find_entry->next->index>entry->index) { + if (find_entry->next->index > entry->index) { entry->next=find_entry->next; find_entry->next=entry; - return; + break; } else { find_entry=find_entry->next; } } else { entry->next=find_entry->next; find_entry->next=entry; - return; + break; } } + Bits cycles=PIC_MakeCycles(pic.next_entry->index-PIC_Index()); + if (cycles Date: Mon, 1 Sep 2003 18:19:22 +0000 Subject: [PATCH 1135/4131] Fix some compilation warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1215 --- src/hardware/fmopl.c | 6 +++--- src/hardware/softmodem.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hardware/fmopl.c b/src/hardware/fmopl.c index ebc97920..b4d7c8e4 100644 --- a/src/hardware/fmopl.c +++ b/src/hardware/fmopl.c @@ -1118,7 +1118,7 @@ static int init_tables(void) for (x=0; x0.0) - o = 8*log(1.0/m)/log(2); /* convert to 'decibels' */ + o = 8*log(1.0/m)/log(2.0); /* convert to 'decibels' */ else - o = 8*log(-1.0/m)/log(2); /* convert to 'decibels' */ + o = 8*log(-1.0/m)/log(2.0); /* convert to 'decibels' */ o = o / (ENV_STEP/4); diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp index ad11e532..38e568e1 100644 --- a/src/hardware/softmodem.cpp +++ b/src/hardware/softmodem.cpp @@ -79,7 +79,7 @@ struct ModemHd { char remotestr[4096]; bool dialing; - float f1, f2; + double f1, f2; Bitu diallen; Bitu dialpos; char dialstr[256]; @@ -455,7 +455,7 @@ static void MODEM_Hardware(Bitu ticks) { static void MODEM_CallBack(Bit8u * stream,Bit32u len) { char *cp; float ci,ri; - Bit32u innum, splitnum, quad, eighth, sixth, amp; + int innum, splitnum, quad, eighth, sixth, amp; Bit8u curchar; Bit32s buflen = (Bit32s)len; if(mhd.incomingcall) { From e884b051ca8352d04cd1ddd2043e15e3eb7398f7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 1 Sep 2003 18:19:55 +0000 Subject: [PATCH 1136/4131] fixed execution of files without an extension Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1216 --- src/shell/shell_misc.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index a5f0878a..4f06cb34 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.22 2003-08-19 18:01:57 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.23 2003-09-01 18:19:55 qbix79 Exp $ */ #include #include @@ -293,12 +293,26 @@ void DOS_Shell::Execute(char * name,char * args) { WriteOut(MSG_Get("SHELL_EXECUTE_ILLEGAL_COMMAND"),name); return; } - if (strcasecmp(strrchr(fullname, '.'), ".bat") == 0) { - /* Run the .bat file */ + + char* extension =strrchr(fullname,'.'); + + /*always disallow files without extension from being executed. */ + /*only internal commands can be run this way and they never get in this handler */ + if(extension == 0) + { + WriteOut(MSG_Get("SHELL_EXECUTE_ILLEGAL_COMMAND"),fullname); + return; + } + if (strcasecmp(extension, ".bat") == 0) + { /* Run the .bat file */ bf=new BatchFile(this,fullname,line); - } else { - if(strcasecmp(strrchr(fullname, '.'), ".com") !=0) { - if(strcasecmp(strrchr(fullname, '.'), ".exe") !=0){ + } + else + { /* only .bat .exe .com extensions maybe be executed by the shell */ + if(strcasecmp(extension, ".com") !=0) + { + if(strcasecmp(extension, ".exe") !=0) + { WriteOut(MSG_Get("SHELL_EXECUTE_ILLEGAL_COMMAND"),fullname); return; } From eba92fc10a5bd4139c00acbe4313012df43abec3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 1 Sep 2003 20:16:59 +0000 Subject: [PATCH 1137/4131] fixed crashes in MadTv1 (reading from pit 2 without being latched first) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1217 --- src/hardware/timer.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 4590789b..e13a65a2 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: timer.cpp,v 1.16 2003-09-01 20:16:59 qbix79 Exp $ */ #include "dosbox.h" #include "inout.h" @@ -203,9 +204,12 @@ void TIMER_Init(Section* sect) { pit[0].read_latch=-1; pit[0].write_latch=0; pit[0].mode=3; + pit[0].micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)pit[0].cntr)); pit[2].micro=100; + pit[2].read_latch=-1; /* MadTv1 */ + PIC_AddEvent(PIT0_Event,pit[0].micro); } From 4c2a65992a5179245a842dec911d926762a37d51 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 1 Sep 2003 20:59:20 +0000 Subject: [PATCH 1138/4131] Added 32-bit ARPL and 32-bit direct far call Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1218 --- src/cpu/core_normal/prefix_66.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 7f769ef5..86efc6df 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -150,6 +150,21 @@ reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32(); break; + CASE_D(0x63) /* ARPL Ed,Rd */ + { + FillFlags(); + GetRMrw; + if (rm >= 0xc0 ) { + GetEArd;Bitu new_sel=(Bit16u)*eard; + CPU_ARPL(new_sel,*rmrw); + *eard=(Bit32u)new_sel; + } else { + GetEAa;Bitu new_sel=LoadMw(eaa); + CPU_ARPL(new_sel,*rmrw); + SaveMd(eaa,(Bit32u)new_sel); + } + } + break; CASE_D(0x68) /* PUSH Id */ Push_32(Fetchd());break; CASE_D(0x69) /* IMUL Gd,Ed,Id */ @@ -312,6 +327,17 @@ if (reg_eax & 0x80000000) reg_edx=0xffffffff; else reg_edx=0; break; + CASE_D(0x9a) /* CALL FAR Ad */ + { + Bit32u newip=Fetchd();Bit16u newcs=Fetchw(); + SAVEIP; + if (CPU_CALL(true,newcs,newip)) { + LOADIP; + } else { + FillFlags();return CBRET_NONE; + } + break; + } CASE_D(0x9c) /* PUSHFD */ FillFlags(); Push_32(flags.word); From b191e859252c3c348da1d012bb594162a43f268c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 3 Sep 2003 20:20:59 +0000 Subject: [PATCH 1139/4131] Add new call for vesa pmode interface Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1219 --- src/ints/int10.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index c2dbb936..4a7d2db7 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -42,9 +42,10 @@ static Bitu INT10_Handler(void) { case 0x0e: case 0x10: case 0x4f: + break; default: - LOG(LOG_INT10,LOG_NORMAL)("Function AX:%04X , BX %04X",reg_ax,reg_bx); + LOG(LOG_INT10,LOG_NORMAL)("Function AX:%04X , BX %04X DX %04X",reg_ax,reg_bx,reg_dx); break; } #endif @@ -104,7 +105,7 @@ static Bitu INT10_Handler(void) { INT10_GetPixel(reg_cx,reg_dx,reg_bh,®_al); break; case 0x0E: /* Teletype OutPut */ - INT10_TeletypeOutput(reg_al,reg_bl,false,reg_bh); + INT10_TeletypeOutput(reg_al,reg_bl,false); break; case 0x0F: /* Get videomode */ reg_bh=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); @@ -174,6 +175,9 @@ static Bitu INT10_Handler(void) { case 0x12: INT10_LoadFont(Real2Phys(int10.rom.font_8_first),true,256,0,0,8); break; + case 0x03: /* Set Block Specifier */ + IO_Write(0x3c4,0x3);IO_Write(0x3c5,reg_bl); + break; /* Graphics mode calls */ case 0x20: /* Set User 8x8 Graphics characters */ RealSetVec(0x1f,RealMake(SegValue(es),reg_bp)); @@ -364,6 +368,13 @@ graphics_chars: reg_ah=0x01; } break; + case 0x0a: /* Get Pmode Inteface */ + reg_edi=RealOff(int10.rom.pmode_interface); + SegSet16(es,RealSeg(int10.rom.pmode_interface)); + reg_cx=int10.rom.pmode_interface_size; + reg_ax=0x004f; + break; + default: LOG(LOG_INT10,LOG_ERROR)("Unhandled VESA Function %X",reg_al); reg_al=0x0; From e171830d6c0e64029c1974f039267c4ee637bce6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 3 Sep 2003 20:21:49 +0000 Subject: [PATCH 1140/4131] Linear frame buffer support. Remove page parameter for teletype function Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1220 --- src/ints/int10.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ints/int10.h b/src/ints/int10.h index 05067f67..b6bfca58 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -18,7 +18,9 @@ #include "../hardware/vga.h" -#define BIOSMEM_SEG 0x40 +#define S3_LFB_BASE 0xC0000000 + +#define BIOSMEM_SEG 0x40 #define BIOSMEM_INITIAL_MODE 0x10 #define BIOSMEM_CURRENT_MODE 0x49 @@ -85,10 +87,6 @@ #define VGAMEM_CTEXT 0xB800 #define VGAMEM_MTEXT 0xB000 -#define SCREEN_SIZE(x,y) (((x*y*2)|0x00ff)+1) -#define SCREEN_MEM_START(x,y,p) ((((x*y*2)|0x00ff)+1)*p) -#define SCREEN_IO_START(x,y,p) ((((x*y)|0x00ff)+1)*p) - #define BIOS_NCOLS Bit16u ncols=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); #define BIOS_NROWS Bit16u nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; @@ -121,6 +119,8 @@ typedef struct { RealPt static_state; RealPt oemstring; RealPt vesa_modes; + RealPt pmode_interface; + Bit16u pmode_interface_size; Bitu used; } rom; } Int10Data; @@ -144,7 +144,7 @@ void INT10_GetFuncStateInformation(PhysPt save); void INT10_SetCursorShape(Bit8u first,Bit8u last); void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page); -void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page); +void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr); void INT10_ReadCharAttr(Bit16u * result,Bit8u page); void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr); void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,Bit16u count,Bit8u page); From a202f5f1754f0ac486e72312a7145b4191d30b41 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 3 Sep 2003 20:22:49 +0000 Subject: [PATCH 1141/4131] Linear frame buffer support. Initial flags for low res vesa modes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1221 --- src/ints/int10_modes.cpp | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 0a990b1f..9cf4e1fc 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -6,8 +6,10 @@ #include "int10.h" #include "mouse.h" -#define _HALF_CLOCK 0x0001 -#define _LINE_DOUBLE 0x0002 +#define _HALF_CLOCK 0x0001 +#define _LINE_DOUBLE 0x0002 +#define _VGA_LINE_DOUBLE 0x0004 +#define _VGA_PIXEL_DOUBLE 0x0008 #define SEQ_REGS 0x05 #define GFX_REGS 0x09 @@ -22,11 +24,9 @@ VideoModeBlock ModeList[]={ { 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, { 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, { 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,_LINE_DOUBLE }, -{ 0x007 ,M_TEXT16 ,720 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x007 ,M_TEXT16 ,720 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, /* 8,9,0xa are tandy modes */ { 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, - - { 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, { 0x00E ,M_EGA16 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,_LINE_DOUBLE }, @@ -34,11 +34,10 @@ VideoModeBlock ModeList[]={ { 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,1 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, { 0x011 ,M_EGA2 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,449 ,80 ,480 ,0 }, { 0x012 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, -{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,_VGA_LINE_DOUBLE }, -{ 0x100 ,M_LIN8 ,640 ,400 ,80 ,20 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, -{ 0x101 ,M_LIN8 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, - +{ 0x100 ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, +{ 0x101 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, {0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, @@ -268,10 +267,12 @@ foundmode: break; case M_VGA: underline=0x40; + if (CurMode->special & _VGA_LINE_DOUBLE) max_scanline|=1; max_scanline|=1; //Vga doesn't use double line but this break; case M_LIN8: underline=0x60; //Seems to enable the every 4th clock on my s3 + if (CurMode->special & _VGA_LINE_DOUBLE) max_scanline|=1; break; } IO_Write(0x3d4,0x09);IO_Write(0x3d5,max_scanline); @@ -437,7 +438,12 @@ dac_text16: /* Setup the CPU Window */ IO_Write(0x3d4,0x6a); IO_Write(0x3d5,0); - + /* Setup the linear frame buffer */ + IO_Write(0x3d4,0x59); + IO_Write(0x3d5,(Bit8u)(S3_LFB_BASE >> 24)); + IO_Write(0x3d4,0x5a); + IO_Write(0x3d5,(Bit8u)(S3_LFB_BASE >> 16)); + /* Setup some remaining S3 registers */ IO_Write(0x3d4,0x31);IO_Write(0x3d5,0x9); //Enable banked memory and 256k+ access IO_Write(0x3d4,0x58);IO_Write(0x3d5,0x3); //Enable 8 mb of linear addressing @@ -462,12 +468,13 @@ dac_text16: real_writew(0xb800,i*2,0x0700); } break; - case M_EGA16: + case M_EGA16: case M_VGA: - for (i=0;i<64*1024;i++) { - real_writeb(0xa000,i,0x00); + case M_LIN8: + /* Just clear the whole 2 mb of memory */ + for (i=0;i<2*1024*1024/4;i++) { + mem_writed(S3_LFB_BASE+i*4,0); } - break; } } /* Setup the CRTC Address */ From 7cb8ed12e0ee687defeab3ae185bc2e65ea24f90 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 3 Sep 2003 20:24:09 +0000 Subject: [PATCH 1142/4131] Corrected calculation of page starts when changing active page. Characters get written to correct page now Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1222 --- src/ints/int10_char.cpp | 43 ++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index da968f63..c0935a9a 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -116,7 +116,7 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit /* Get the correct page */ if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); - PhysPt base=CurMode->pstart+CurMode->plength*page; + PhysPt base=CurMode->pstart+page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); /* See how much lines need to be copied */ Bit8u start,end;Bits next; @@ -174,22 +174,22 @@ filling: void INT10_SetActivePage(Bit8u page) { Bit16u mem_address; - Bit8u cur_col=0 ,cur_row=0 ; if (page>7) return; - mem_address=page*CurMode->plength; + mem_address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); /* Write the new page start */ real_writew(BIOSMEM_SEG,BIOSMEM_CURRENT_START,mem_address); - + if (CurMode->mode<0x8) mem_address>>=1; /* Write the new start address in vgahardware */ IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0c); - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(mem_address&0xff00)>>8); + IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(Bit8u)(mem_address>>8)); IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0d); - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,mem_address&0x00ff); + IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(Bit8u)mem_address); // And change the BIOS page real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE,page); - + Bit8u cur_row=CURSOR_POS_ROW(page); + Bit8u cur_col=CURSOR_POS_COL(page); // Display the cursor, now the page is active INT10_SetCursorPos(cur_row,cur_col,page); } @@ -253,26 +253,29 @@ void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page) { Bit8u current=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); if(page==current) { // Get the dimensions - BIOS_NCOLS;BIOS_NROWS; + BIOS_NCOLS; // Calculate the address knowing nbcols nbrows and page num - address=SCREEN_IO_START(ncols,nrows,page)+col+row*ncols; + address=(ncols*row)+col+real_readw(BIOSMEM_SEG,BIOSMEM_CURRENT_START); // CRTC regs 0x0e and 0x0f IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0e); - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(address&0xff00)>>8); + IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(Bit8u)(address>>8)); IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0f); - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,address&0x00ff); + IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(Bit8u)address); } } void INT10_ReadCharAttr(Bit16u * result,Bit8u page) { if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); - BIOS_NCOLS;BIOS_NROWS; Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); - Bit16u address=SCREEN_MEM_START(ncols,nrows,page)+(cur_col+cur_row*ncols)*2; - *result=real_readw(0xb800,address); + // Compute the address + Bit16u address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); + address+=(cur_row*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)+cur_col)*2; + // REad the char + PhysPt where = CurMode->pstart+address; + *result=mem_readw(where); } @@ -283,7 +286,8 @@ static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool case M_TEXT16: { // Compute the address - Bit16u address=SCREEN_MEM_START(CurMode->twidth,CurMode->theight,page)+(col+row*CurMode->twidth)*2; + Bit16u address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); + address+=(row*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)+col)*2; // Write the char PhysPt where = CurMode->pstart+address; mem_writeb(where,chr); @@ -341,10 +345,9 @@ void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) } -void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page) { +void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr) { //TODO Check if this page thing is correct - if (CurMode->type!=M_TEXT16) page=0xff; - if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); + Bit8u page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); BIOS_NCOLS;BIOS_NROWS; Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); @@ -365,7 +368,7 @@ void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page) { break; case '\t': do { - INT10_TeletypeOutput(' ',attr,showattr,page); + INT10_TeletypeOutput(' ',attr,showattr); cur_row=CURSOR_POS_ROW(page); cur_col=CURSOR_POS_COL(page); } while(cur_col%8==0); @@ -411,7 +414,7 @@ void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,B attr=mem_readb(string); string++; } - INT10_TeletypeOutput(chr,attr,true,page); + INT10_TeletypeOutput(chr,attr,true); count--; } if (flag & 1) { From 2676825d871623bd96d57df2dfc2ae73580d58c7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 3 Sep 2003 20:26:52 +0000 Subject: [PATCH 1143/4131] Fill out VBE2 mode information Added Pmode interface code Corrected some return codes with far page change function Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1223 --- src/ints/int10_vesa.cpp | 72 ++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 16 deletions(-) diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 2d452f0f..644c45ae 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -31,6 +31,10 @@ static struct { Bitu setwindow; } callback; +static char string_oem[]="S3 Incorporated. Trio64"; +static char string_vendorname[]="DOSBox Development Team"; +static char string_productname[]="DOSBox - The DOS Emulator"; +static char string_productrev[]="DOSBox "VERSION; #ifdef _MSC_VER #pragma pack (1) @@ -80,7 +84,7 @@ Bit8u VESA_GetSVGAInformation(Bit16u seg,Bit16u off) { /* Fill 256 byte buffer with VESA information */ PhysPt buffer=PhysMake(seg,off); Bitu i; - bool vbe2=false; + bool vbe2=false;Bit16u vbe2_pos=256+off; if (mem_readd(buffer)==0x32454256) vbe2=true; if (vbe2) { for (i=0;i<0x200;i++) mem_writeb(buffer+i,0); @@ -88,9 +92,22 @@ Bit8u VESA_GetSVGAInformation(Bit16u seg,Bit16u off) { for (i=0;i<0x100;i++) mem_writeb(buffer+i,0); } /* Fill common data */ - MEM_BlockWrite(buffer,(void *)"VESA",4); //Identification - mem_writew(buffer+0x04,0x102); //Vesa version - mem_writed(buffer+0x06,int10.rom.oemstring); //Oemstring + MEM_BlockWrite(buffer,(void *)"VESA",4); //Identification + if (vbe2) { + mem_writew(buffer+0x04,0x200); //Vesa version 0x200 + mem_writed(buffer+0x06,RealMake(seg,vbe2_pos)); + for (i=0;itype) { case M_LIN8: //Linear 8-bit - WLE(minfo.ModeAttributes,0x1b); //No bios output support, although would be easy + WLE(minfo.ModeAttributes,0x9b); WLE(minfo.WinAAttributes,0x7); //Exists/readable/writable WLE(minfo.WinGranularity,64); WLE(minfo.WinSize,64); WLE(minfo.WinASegment,0xa000); - WLE(minfo.WinBSegment,0xa000); +// WLE(minfo.WinBSegment,0xa000); WLE(minfo.WinFuncPtr,CALLBACK_RealPointer(callback.setwindow)); WLE(minfo.BytesPerScanLine,mblock->swidth); WLE(minfo.NumberOfPlanes,0x1); @@ -134,6 +151,8 @@ foundit: WLE(minfo.YResolution,mblock->sheight); WLE(minfo.XCharSize,mblock->cwidth); WLE(minfo.YCharSize,mblock->cheight); + WLE(minfo.PhysBasePtr,S3_LFB_BASE); + MEM_BlockWrite(buf,&minfo,sizeof(MODE_INFO)); return 0x00; } @@ -150,7 +169,7 @@ Bit8u VESA_GetSVGAMode(Bit16u & mode) { } Bit8u VESA_SetCPUWindow(Bit8u window,Bit16u address) { -//TODO Check with univbe if it doesn't check for window param either + if (window) return 0x1; if ((address<32)) { IO_Write(0x3d4,0x6a); IO_Write(0x3d5,(Bit8u)address); @@ -159,7 +178,7 @@ Bit8u VESA_SetCPUWindow(Bit8u window,Bit16u address) { } Bit8u VESA_GetCPUWindow(Bit8u window,Bit16u & address) { -//TODO Check with univbe if it doesn't check for window param either + if (window) return 0x1; IO_Write(0x3d4,0x6a); address=IO_Read(0x3d5); return 0x0; @@ -230,12 +249,26 @@ Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u & bytes,Bit16u & pixels,Bit16u & return 0x0; } + +/* Based of the s3 univbe driver */ +static Bit8u PmodeInterface[]={ + 0x08,0x00,0x19,0x00,0x57,0x00,0x00,0x00,0x50,0x52,0x8b,0xc2,0x8a,0xe0,0xb0,0x6a, + 0x66,0xba,0xd4,0x03,0x66,0xef,0x5a,0x58,0xc3,0x52,0x66,0xba,0xda,0x03,0xec,0xa8, + 0x01,0x75,0xfb,0x5a,0x53,0x8a,0xf9,0xb3,0x0d,0xb1,0x0c,0x66,0x8b,0xf2,0x66,0xba, + 0xd4,0x03,0x66,0x8b,0xc3,0x66,0xef,0x66,0x8b,0xc1,0x66,0xef,0x66,0x8b,0xde,0x8a, + 0xe3,0xb0,0x69,0x66,0xef,0x5b,0x52,0xf6,0xc3,0x80,0x74,0x09,0x66,0xba,0xda,0x03, + 0xec,0xa8,0x08,0x74,0xfb,0x5a,0xc3,0xf6,0xc3,0x80,0x74,0x10,0x52,0x66,0xba,0xda, + 0x03,0xec,0xa8,0x08,0x75,0xfb,0xec,0xa8,0x08,0x74,0xfb,0x5a,0x1e,0x06,0x1f,0x0f, + 0xb7,0xc9,0x8b,0xc2,0x66,0xba,0xc8,0x03,0xee,0x42,0xfc,0x8a,0x47,0x02,0xee,0x8a, + 0x47,0x01,0xee,0x8a,0x07,0xee,0x83,0xc7,0x04,0x49,0x75,0xef,0x1f,0xc3 +}; + Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y) { //TODO Maybe do things differently with lowres double line modes? Bitu start; switch (CurMode->type) { case M_LIN8: - start=vga.config.scan_len*4*y+x; + start=vga.config.scan_len*8*y+x; vga.config.display_start=start/4; IO_Read(0x3da); IO_Write(0x3c0,0x13+32); @@ -248,8 +281,8 @@ Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y) { } Bit8u VESA_GetDisplayStart(Bit16u & x,Bit16u & y) { - Bitu times=vga.config.display_start/(vga.config.scan_len*4); - Bitu rem=vga.config.display_start % (vga.config.scan_len*4); + Bitu times=(vga.config.display_start*4)/(vga.config.scan_len*8); + Bitu rem=(vga.config.display_start*4) % (vga.config.scan_len*8); Bitu pan=vga.config.pel_panning; switch (CurMode->type) { case M_LIN8: @@ -265,11 +298,11 @@ Bit8u VESA_GetDisplayStart(Bit16u & x,Bit16u & y) { } -static char oemstring[]="S3 Incorporated. Trio64"; static Bitu SetWindowPositionHandler(void) { - if (reg_bh) VESA_GetCPUWindow(reg_bl,reg_dx); - else VESA_SetCPUWindow(reg_bl,reg_dx); + if (reg_bh) reg_ah=VESA_GetCPUWindow(reg_bl,reg_dx); + else reg_ah=VESA_SetCPUWindow(reg_bl,reg_dx); + reg_al=0x4f; return 0; } @@ -290,10 +323,17 @@ void INT10_SetupVESA(void) { phys_writew(PhysMake(0xc000,int10.rom.used),0xffff); int10.rom.used+=2; int10.rom.oemstring=RealMake(0xc000,int10.rom.used); - Bitu len=strlen(oemstring)+1; + Bitu len=strlen(string_oem)+1; for (i=0;i Date: Wed, 3 Sep 2003 20:28:07 +0000 Subject: [PATCH 1144/4131] Teletype output doesn't need page parameter anymore Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1224 --- src/dos/dev_con.h | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 961f86e2..0e23e7a0 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -18,6 +18,7 @@ #include "dos_inc.h" #include "../ints/int10.h" +#include #define NUMBER_ANSI_DATA 10 @@ -45,8 +46,6 @@ private: } ansi; }; -void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page); -void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page); bool device_CON::Read(Bit8u * data,Bit16u * size) { Bit16u oldax=reg_ax; @@ -54,7 +53,7 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { if ((cache) && (*size)) { data[count++]=cache; if(dos.echo) { - INT10_TeletypeOutput(cache,7,false,0); + INT10_TeletypeOutput(cache,7,false); } cache=0; @@ -69,8 +68,8 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { *size=count; reg_ax=oldax; if(dos.echo) { - INT10_TeletypeOutput(13,7,false,0); //maybe don't do this ( no need for it actually ) (but it's compatible) - INT10_TeletypeOutput(10,7,false,0); + INT10_TeletypeOutput(13,7,false); //maybe don't do this ( no need for it actually ) (but it's compatible) + INT10_TeletypeOutput(10,7,false); } return true; break; @@ -78,8 +77,8 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { if(*size==1) data[count++]=reg_al; //one char at the time so give back that BS else if(count) { //Remove data if it exists (extended keys don't go right) data[count--]=0; - INT10_TeletypeOutput(8,7,false,0); - INT10_TeletypeOutput(' ',7,false,0); + INT10_TeletypeOutput(8,7,false); + INT10_TeletypeOutput(' ',7,false); } else { continue; //no data read yet so restart whileloop. } @@ -96,7 +95,7 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { } if(dos.echo) { //what to do if *size==1 and character is BS ????? - INT10_TeletypeOutput(reg_al,7,false,0); + INT10_TeletypeOutput(reg_al,7,false); } } *size=count; @@ -110,7 +109,6 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { Bitu i; Bit8s col,row; static bool ansi_enabled=false; - while (*size>count) { if (!ansi.esc){ if(data[count]=='\033') { @@ -127,7 +125,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { } else { // pass attribute only if ansi is enabled - INT10_TeletypeOutput(data[count],ansi.attr,ansi_enabled,0); + INT10_TeletypeOutput(data[count],ansi.attr,ansi_enabled); count++; continue; }; @@ -288,7 +286,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { LOG(LOG_IOCTL,LOG_NORMAL)("ANSI: esc[%dJ called : not supported",ansi.data[0]); break; } - for(i=0;i<(Bitu)ansi.ncols*ansi.nrows;i++) INT10_TeletypeOutput(' ',ansi.attr,true,0); + for(i=0;i<(Bitu)ansi.ncols*ansi.nrows;i++) INT10_TeletypeOutput(' ',ansi.attr,true); ClearAnsi(); INT10_SetCursorPos(0,0,0); break; From 66c850027e2af59662cf1da1421f38bbaf0e8279 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 3 Sep 2003 20:31:49 +0000 Subject: [PATCH 1145/4131] Only set LFB address if it changes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1225 --- src/hardware/vga_crtc.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index ebddee0e..ad7becd1 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -423,12 +423,16 @@ void write_p3d5(Bit32u port,Bit8u val) { if clear 7MCLKs */ case 0x59: /* Linear Address Window Position High */ - vga.s3.la_window=(vga.s3.la_window&0x00ff) | (val << 8); - VGA_StartUpdateLFB(); + if ((vga.s3.la_window&0xff00) ^ (val << 8)) { + vga.s3.la_window=(vga.s3.la_window&0x00ff) | (val << 8); + VGA_StartUpdateLFB(); + } break; case 0x5a: /* Linear Address Window Position Low */ - vga.s3.la_window=(vga.s3.la_window&0xff00) | val; - VGA_StartUpdateLFB(); + if ((vga.s3.la_window&0x00ff) ^ val) { + vga.s3.la_window=(vga.s3.la_window&0xff00) | val; + VGA_StartUpdateLFB(); + } break; case 0x5D: /* Extended Horizontal Overflow */ if ((val & vga.s3.ex_hor_overflow) ^ 3) { From 72e2a732df2f149cfe3672a41c4510ff2a3c8fa0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 3 Sep 2003 20:36:28 +0000 Subject: [PATCH 1146/4131] Text mode uses start address now. Support for double lined vesa modes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1226 --- src/hardware/vga_draw.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 59ae43ec..cbdb01c5 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -99,7 +99,7 @@ static void VGA_TANDY16_Draw(Bit8u * bitdata,Bitu pitch) { void VGA_TEXT_Draw(Bit8u * bitdata,Bitu start,Bitu panning,Bitu rows) { - Bit8u * reader=&vga.mem.linear[0]; + Bit8u * reader=&vga.mem.linear[start*2]; Bit8u * draw_start=bitdata; /* Todo Blinking and high intensity colors */ Bitu next_charline=vga.draw.font_height*vga.draw.width; @@ -344,6 +344,13 @@ void VGA_SetupDrawing(void) { break; case M_LIN8: width<<=3; + if (vga.draw.double_width) width>>=1; + if (!vga.draw.double_height) { + if (vga.config.vline_height&1) { + vga.draw.double_height=true; + vga.draw.font_height/=2; + } + } pitch=vga.config.scan_len*8; break; case M_EGA16: @@ -390,7 +397,7 @@ void VGA_SetupDrawing(void) { vga.draw.height=height; vga.draw.pitch=pitch; - LOG(LOG_VGA,LOG_NORMAL)("Width %d, Height %d",width,height); + LOG(LOG_VGA,LOG_NORMAL)("Width %d, Height %d, Pitch %d",width,height,pitch); LOG(LOG_VGA,LOG_NORMAL)("Flags %X, fps %f",flags,fps); RENDER_SetSize(width,height,8,pitch,((float)width/(float)height),flags,&VGA_DrawHandler); vga.draw.blank=(Bitu)(1000000/fps); From 6de41171d1d6927ce36215b9806fad2e98fc2db3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 4 Sep 2003 15:47:55 +0000 Subject: [PATCH 1147/4131] Fix memory allocation using same memory block again while doing bestmatch Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1227 --- src/hardware/memory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 94e5b51a..24e70213 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -377,7 +377,7 @@ void MEM_AllocLinkMemory(PageEntry * theentry) { void MEM_SetLFB(Bitu page,Bitu pages,HostPt pt) { if (pages>LFB_PAGES) E_Exit("MEM:LFB to large"); - LOG_MSG("LFB Base at %X",page*4096); + LOG_MSG("LFB Base at address %X,page %X",page*4096,page); memory.lfb.pages=pages; memory.lfb.start_page=page; memory.lfb.end_page=page+pages; @@ -550,8 +550,8 @@ MemHandle MEM_AllocatePages(Bitu pages,bool sequence) { next=&memory.entries[index].next_handle; index++;pages--; } + *next=-1; //Invalidate it in case we need another match } - *next=-1; } return ret; } From 2fd4a98dde24bd34daeb5122e33ef846b490248f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 4 Sep 2003 15:49:00 +0000 Subject: [PATCH 1148/4131] Initial font selection Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1228 --- src/hardware/vga.h | 2 ++ src/hardware/vga_seq.cpp | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga.h b/src/hardware/vga.h index 6f928bbb..51d0edc8 100644 --- a/src/hardware/vga.h +++ b/src/hardware/vga.h @@ -115,6 +115,8 @@ typedef struct { Bitu lines; Bit8u font_height; Bit8u font[64*1024]; + Bitu font1_start; + Bitu font2_start; Bitu rows,cols; struct { Bit8u sline,eline; diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index c608cc69..4433f765 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -67,7 +67,13 @@ void write_p3c5(Bit32u port,Bit8u val) { */ break; case 3: /* Character Map Select */ - seq(character_map_select)=val; + { + seq(character_map_select)=val; + Bit8u font1=(val & 0x3) | ((val & 0x10) >> 2); + vga.draw.font1_start=((font1&3) * 16*1024) + ((font1 > 4) ? (8*1024) : 0); + Bit8u font2=((val & 0xc) >> 2) | ((val & 0x20) >> 3); + vga.draw.font2_start=((font2&3) * 16*1024) + ((font2 > 4) ? (8*1024) : 0); + } /* 0,1,4 Selects VGA Character Map (0..7) if bit 3 of the character attribute is clear. From 21ca26be960e7a6e616cd7480897614ea7c09202 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 4 Sep 2003 19:17:57 +0000 Subject: [PATCH 1149/4131] Reading SBPRO microphone level fixed. Triggering 8-bit irq DSP function doesn't return data. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1229 --- src/hardware/sblaster.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index d2a44eb2..4d3099d9 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -553,7 +553,7 @@ static void DMA_E2_Enable(bool enable) { } static void DSP_DoCommand(void) { - //LOG_MSG("DSP Command %X",sb.dsp.cmd); +// LOG_MSG("DSP Command %X",sb.dsp.cmd); switch (sb.dsp.cmd) { case 0x04: /* DSP Statues SB 2.0/pro version */ DSP_FlushData(); @@ -647,8 +647,6 @@ static void DSP_DoCommand(void) { DSP_AddData(sb.dsp.test_register);; break; case 0xf2: /* Trigger 8bit IRQ */ - DSP_FlushData(); - DSP_AddData(0xaa); SB_RaiseIRQ(SB_IRQ_8); break; default: @@ -740,8 +738,8 @@ static Bit8u MIXER_Read(void) { return ((sb.mixer.dac.left & 0x1e) >> 1) | ((sb.mixer.dac.right & 0x1e) << 3); // case 0x06: /* FM output selection, Somewhat obsolete with dual OPL SBpro */ - case 0x0a: /* Mic Level */ - return sb.mixer.mic; + case 0x0a: /* Mic Level (SBPRO) */ + return (sb.mixer.mic >> 1); case 0x0e: /* Output/Stereo Select */ return 0x11|(sb.dma.stereo ? 0x02 : 0x00)|(sb.dma.filtered ? 0x20 : 0x00); case 0x26: /* FM Volume (SBPRO) */ From 20083140da2fe681ed293537c325f86ffddcb274 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 7 Sep 2003 10:28:18 +0000 Subject: [PATCH 1150/4131] Fixed 32-bit BSR Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1230 --- src/cpu/core_normal/prefix_66_0f.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index dc100f62..8a61ae72 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -336,7 +336,7 @@ if (value==0) { SETFLAGBIT(ZF,true); } else { - result = 35; // Operandsize-1 + result = 31; // Operandsize-1 while ((value & 0x80000000)==0) { result--; value<<=1; } SETFLAGBIT(ZF,false); *rmrd = result; From 7d2bdc65e37600878a268246056806738ab74130 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 7 Sep 2003 14:35:41 +0000 Subject: [PATCH 1151/4131] Allow reallocation of memory handles to 0 pages. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1231 --- src/hardware/memory.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 24e70213..2da66a0c 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -565,11 +565,17 @@ void MEM_ReleasePages(MemHandle handle) { } bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence) { - MemHandle index=handle; - if (index<0 || !pages) { - E_Exit("MEM:Resized to size 0"); - return 0; + if (handle<0) { + if (!pages) return true; + handle=MEM_AllocatePages(pages,sequence); + return (handle>0); } + if (!pages) { + MEM_ReleasePages(handle); + handle=-1; + return true; + } + MemHandle index=handle; MemHandle last;Bitu old_pages=0; while (index>0) { old_pages++; From 334fb33d97b8e185891f40e4a4eeac5f5dcd0afc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 8 Sep 2003 18:06:44 +0000 Subject: [PATCH 1152/4131] ansi can now turns itself off. fixed all cursor movement commands added delete current row Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1232 --- src/dos/dev_con.h | 79 ++++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 28 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 0e23e7a0..09f67321 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: dev_con.h,v 1.14 2003-09-08 18:06:44 qbix79 Exp $ */ + #include "dos_inc.h" #include "../ints/int10.h" #include @@ -36,6 +38,7 @@ private: struct ansi { /* should create a constructor which fills them with the appriorate values */ bool esc; bool sci; + bool enabled; Bit8u attr; Bit8u data[NUMBER_ANSI_DATA]; Bit8u numberofarg; @@ -107,8 +110,8 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { bool device_CON::Write(Bit8u * data,Bit16u * size) { Bit16u count=0; Bitu i; - Bit8s col,row; - static bool ansi_enabled=false; + Bit8u col,row; + Bit8u tempdata; while (*size>count) { if (!ansi.esc){ if(data[count]=='\033') { @@ -117,20 +120,16 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { /* start the sequence */ ansi.esc=true; count++; - if(!ansi_enabled) { - LOG(LOG_IOCTL,LOG_NORMAL)("ANSI sequences detected. enabling ansi support"); /* maybe LOG_MSG */ - ansi_enabled=true; - } continue; } else { // pass attribute only if ansi is enabled - INT10_TeletypeOutput(data[count],ansi.attr,ansi_enabled); + INT10_TeletypeOutput(data[count],ansi.attr,ansi.enabled); count++; continue; }; }; - /* ansi.esc=true */ + if(!ansi.sci){ switch(data[count]){ @@ -169,10 +168,11 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { break; case 'm': /* SGR */ for(i=0;i<=ansi.numberofarg;i++){ - + ansi.enabled=true; switch(ansi.data[i]){ case 0: /* normal */ ansi.attr=0x7; + ansi.enabled=false; break; case 1: /* bold mode on*/ ansi.attr|=0x8; @@ -264,19 +264,48 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { INT10_SetCursorPos(--(ansi.data[0]),--(ansi.data[1]),0); /*ansi=1 based, int10 is 0 based */ ClearAnsi(); break; + /* cursor up down and forward and backward only change the row or the col not both */ case 'A': /* cursor up*/ col=CURSOR_POS_COL(0) ; - row=CURSOR_POS_ROW(0) - (ansi.data[0]? ansi.data[0] : 1); + row=CURSOR_POS_ROW(0) ; + tempdata = (ansi.data[0]? ansi.data[0] : 1); + if(tempdata > row) + { row=0; } + else + { row-=tempdata;} + INT10_SetCursorPos(row,col,0); + ClearAnsi(); + break; + case 'B': /*cursor Down */ + col=CURSOR_POS_COL(0) ; + row=CURSOR_POS_ROW(0) ; + tempdata = (ansi.data[0]? ansi.data[0] : 1); + if(tempdata + static_cast(row) >= ansi.nrows) + { row = ansi.nrows - 1;} + else + { row += tempdata; } + INT10_SetCursorPos(row,col,0); + ClearAnsi(); + break; + case 'C': /*cursor forward */ + col=CURSOR_POS_COL(0); + row=CURSOR_POS_ROW(0); + tempdata=(ansi.data[0]? ansi.data[0] : 1); + if(tempdata + static_cast(col) >= ansi.ncols) + { col = ansi.ncols - 1;} + else + { col += tempdata;} INT10_SetCursorPos(row,col,0); ClearAnsi(); break; - case 'C': /*cursor forward */ - col=CURSOR_POS_COL(0) + (ansi.data[0]? ansi.data[0] : 1); + case 'D': /*Cursor Backward */ + col=CURSOR_POS_COL(0); row=CURSOR_POS_ROW(0); - while(col>=ansi.ncols) { - row++; - col = col - ansi.ncols; // should depend on linebrake mode - } + tempdata=(ansi.data[0]? ansi.data[0] : 1); + if(tempdata > col) + {col = 0;} + else + { col -= tempdata;} INT10_SetCursorPos(row,col,0); ClearAnsi(); break; @@ -295,16 +324,6 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { LOG(LOG_IOCTL,LOG_NORMAL)("ANSI: set/reset mode called(not supported)"); ClearAnsi(); break; - case 'D': /*Cursor Backward */ - col=CURSOR_POS_COL(0) - (ansi.data[0]? ansi.data[0] : 1); - row=CURSOR_POS_ROW(0); - while(col<0) { - row--; - col = col + ansi.ncols ; // should depend on linebrake mode - } - INT10_SetCursorPos(row,col,0); - ClearAnsi(); - break; case 'u': /* Restore Cursor Pos */ INT10_SetCursorPos(ansi.saverow,ansi.savecol,0); ClearAnsi(); @@ -314,7 +333,10 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { ansi.saverow=CURSOR_POS_ROW(0); ClearAnsi(); break; - case 'K':/* erase till end of line */ + case 'K':/* erase till end of line */ + for(i = CURSOR_POS_COL(0);i<(Bitu) ansi.ncols; i++) INT10_TeletypeOutput(' ',ansi.attr,true); + ClearAnsi(); /* maybe set cursor back to starting place ???? */ + break; case 'l':/* (if code =7) disable linewrap */ case 'p':/* reassign keys (needs strings) */ case 'i':/* printer stuff */ @@ -352,11 +374,12 @@ device_CON::device_CON() { cache=0; ansi.esc=false; ansi.sci=false; + ansi.enabled=false; ansi.attr=0x7; ansi.numberofarg=0; for(Bit8u i=0; i Date: Mon, 8 Sep 2003 18:10:08 +0000 Subject: [PATCH 1153/4131] Added some nice colors to the intro command :) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1233 --- src/dos/dos_programs.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 98ae9df6..85a8acae 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: dos_programs.cpp,v 1.20 2003-09-08 18:10:08 qbix79 Exp $ */ + #include #include #include @@ -321,25 +323,26 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_RESCAN_SUCCESS","Drive cache cleared.\n"); MSG_Add("PROGRAM_INTRO", - "Welcome to DOSBox, an x86 emulator with sound and graphics.\n" + "Welcome to DOSBox, an x86 emulator with sound and graphics.\n" "DOSBox creates a shell for you which looks like old plain DOS.\n" "\n" "Here are some commands to get you started:\n" "Before you can use the files located on your own filesystem,\n" "You have to mount the directory containing the files.\n" "For Windows:\n" - "mount c c:\\dosprog will create a C drive in dosbox with c:\\dosprog as contents.\n" + "\033[33mmount c c:\\dosprog\033[0m will create a C drive in dosbox with c:\\dosprog as contents.\n" "\n" - "For other platfroms:\n" - "mount c /home/user/dosprog will do the same.\n" + "For other platforms:\n" + "\033[33mmount c /home/user/dosprog\033[0m will do the same.\n" "\n" - "When the mount has succesfully completed you can type c: to go to your freshly\n" - "mounted C-drive. Typing dir there will show its contents. cd will allow you to\n" + "When the mount has succesfully completed you can type \033[33mc:\033[0m to go to your freshly\n" + "mounted C-drive. Typing \033[33mdir\033[0m there will show its contents." + " \033[33mcd\033[0m will allow you to\n" "enter a directory (recognised by the [] in a directory listing).\n" - "You can run programs/files which end with .exe .bat and .com .\n" + "You can run programs/files which end with .exe .bat and .com.\n" "\n" - "DOSBox will stop/exit without a warning if an error occured!\n" + "DOSBox will stop/exit without a warning if an error occured!\n" ); /*regular setup*/ From 43abd3f1e4af8c82ba0982f97f562b4901632064 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 8 Sep 2003 18:17:23 +0000 Subject: [PATCH 1154/4131] Added the Call command Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1234 --- src/shell/shell_inc.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/shell/shell_inc.h b/src/shell/shell_inc.h index a09fd9fe..4dc1f73b 100644 --- a/src/shell/shell_inc.h +++ b/src/shell/shell_inc.h @@ -60,7 +60,7 @@ private: char *completion_start; Bit16u completion_index; - + public: DOS_Shell(); @@ -93,6 +93,7 @@ public: 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); /* The shell's variables */ @@ -100,6 +101,7 @@ public: BatchFile * bf; bool echo; bool exit; + bool call; }; struct SHELL_Cmd { From c862dbbe8c3739841c318bf9608202d53e0325ac Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 8 Sep 2003 18:19:28 +0000 Subject: [PATCH 1155/4131] updated copyright and ID Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1235 --- src/shell/shell_inc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_inc.h b/src/shell/shell_inc.h index 4dc1f73b..18a1c1ce 100644 --- a/src/shell/shell_inc.h +++ b/src/shell/shell_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id */ +/* $Id: shell_inc.h,v 1.17 2003-09-08 18:19:28 qbix79 Exp $ */ #include #include From c4d5fb062b954eda6fb4f444cae4eec198a80a51 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 8 Sep 2003 18:21:19 +0000 Subject: [PATCH 1156/4131] Added Call Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1236 --- src/shell/shell_cmds.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index dae78761..d6da2bb6 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.26 2003-08-20 12:21:42 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.27 2003-09-08 18:21:19 qbix79 Exp $ */ #include @@ -48,6 +48,7 @@ static SHELL_Cmd cmd_list[]={ { "RENAME", 0, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP"}, { "REN", 1, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP"}, { "PAUSE", 0, &DOS_Shell::CMD_PAUSE, "SHELL_CMD_PAUSE_HELP"}, +{ "CALL", 0, &DOS_Shell::CMD_CALL, "SHELL_CMD_CALL_HELP"}, { 0,0,0,0} }; @@ -557,3 +558,9 @@ void DOS_Shell::CMD_PAUSE(char * args){ DOS_ReadFile (STDIN,&c,&n); } + +void DOS_Shell::CMD_CALL(char * args){ + this->call=true; /* else the old batchfile will be closed first */ + this->ParseLine(args); + this->call=false; +} \ No newline at end of file From 4199f0d4838da2ae66a9624807bd4cec1b8bfcf3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 8 Sep 2003 18:22:57 +0000 Subject: [PATCH 1157/4131] Added Call support to the execute function. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1237 --- src/shell/shell_misc.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 4f06cb34..c546352e 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.23 2003-09-01 18:19:55 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.24 2003-09-08 18:22:57 qbix79 Exp $ */ #include #include @@ -305,6 +305,8 @@ void DOS_Shell::Execute(char * name,char * args) { } if (strcasecmp(extension, ".bat") == 0) { /* Run the .bat file */ + /* delete old batch file if call is not active*/ + if(bf && !call) delete bf; bf=new BatchFile(this,fullname,line); } else From 5d82be71aab9e9f286cdb084fd251a06541c3c57 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 8 Sep 2003 18:25:44 +0000 Subject: [PATCH 1158/4131] Added call support spiced up the startup message Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1238 --- src/shell/shell.cpp | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 1e5dfc83..1d73485b 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: shell.cpp,v 1.33 2003-09-08 18:25:44 qbix79 Exp $ */ #include #include @@ -56,7 +57,7 @@ DOS_Shell::DOS_Shell():Program(){ echo=true; exit=false; bf=0; - + call=false; completion_start = NULL; } @@ -177,21 +178,24 @@ void DOS_Shell::Run(void) { ParseLine(input_line); } do { - if (bf && bf->ReadLine(input_line)) { - if (echo) { - if (input_line[0]!='@') { - ShowPrompt(); - WriteOut(input_line); - WriteOut("\n"); + if (bf){ + if(bf->ReadLine(input_line)) { + if (echo) { + if (input_line[0]!='@') { + ShowPrompt(); + WriteOut(input_line); + WriteOut("\n"); + }; }; - }; + ParseLine(input_line); + if (echo) WriteOut("\n"); + } } else { if (echo) ShowPrompt(); InputCommand(input_line); - + ParseLine(input_line); + if (echo) WriteOut("\n"); } - ParseLine(input_line); - if (echo) WriteOut("\n"); } while (!exit); } @@ -277,9 +281,9 @@ void SHELL_Init() { MSG_Add("SHELL_STARTUP","DOSBox Shell v" VERSION "\n" "DOSBox does not run protected mode games!\n" - "For supported shell commands type: HELP\n" - "For a short introduction type: INTRO\n\n" - "For more information read the README file in DOSBox directory.\n" + "For supported shell commands type: HELP\n" + "For a short introduction type: INTRO\n\n" + "For more information read the README file in DOSBox directory.\n" "\nHAVE FUN!\nThe DOSBox Team\n\n" ); @@ -300,7 +304,7 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_RENAME_HELP","Renames files.\n"); MSG_Add("SHELL_CMD_DELETE_HELP","Removes files.\n"); MSG_Add("SHELL_CMD_COPY_HELP","Copy files.\n"); - MSG_Add("SHELL_CMD_INTRO_HELP","Gives an introduction into dosbox\n"); + MSG_Add("SHELL_CMD_CALL_HELP","Start a batch file from within another batch file.\n"); /* Regular startup */ call_shellstop=CALLBACK_Allocate(); /* Setup the startup CS:IP to kill the last running machine when exitted */ From 14ac18fa8496e29227ce41af5243fdcaab2b1ae4 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 9 Sep 2003 11:34:11 +0000 Subject: [PATCH 1159/4131] Fixed a bug when logging pmode instructions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1239 --- src/debug/debug.cpp | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 351c8f17..ba746325 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -533,6 +533,7 @@ bool DEBUG_IntBreakpoint(Bit8u intNum) static bool StepOver() { + exitLoop = false; // PhysPt start=SegPhys(cs)+reg_eip; PhysPt start=GetAddress(SegValue(cs),reg_eip); char dline[200];Bitu size; @@ -1269,6 +1270,7 @@ Bit32u DEBUG_CheckKeys(void) { case KEY_F(10): // Step over inst if (StepOver()) return 0; else { + exitLoop = false; skipFirstInstruction = true; // for heavy debugger CPU_Cycles = 1; Bitu ret=(*cpudecoder)(); @@ -1278,6 +1280,7 @@ Bit32u DEBUG_CheckKeys(void) { } break; case KEY_F(11): // trace into + exitLoop = false; skipFirstInstruction = true; // for heavy debugger CPU_Cycles = 1; ret = (*cpudecoder)(); @@ -1331,7 +1334,7 @@ static void LogInstruction(Bit16u segValue, Bit32u eipValue, char* buffer) PhysPt start = GetAddress(segValue,eipValue); char dline[200];Bitu size; - size = DasmI386(dline, start, reg_eip, false); + size = DasmI386(dline, start, reg_eip, cpu.code.big); Bitu len = strlen(dline); char* res = empty; if (showExtend) { @@ -1666,27 +1669,6 @@ bool DEBUG_HeavyIsBreakpoint(void) skipFirstInstruction = false; return false; } - -/* static bool once = false; - Descriptor desc; - if (!once && cpu.gdt.GetDescriptor(0x44,desc)) { - if (desc.GetBase()==0x40000000) { - LOG(LOG_ERROR,"Selector 44 base 0x40000000: %04X,%08X",SegValue(cs),reg_eip); - once = true; - exitLoop = true; - DEBUG_Enable(); - return true; - }; - } -*/ -/* if (cpu.state & STATE_PROTECTED) { - if ((reg_ebx==0x000F)) { - exitLoop = true; - DEBUG_Enable(); - return true; - } - } -*/ PhysPt where = SegPhys(cs)+reg_eip; if (CBreakpoint::CheckBreakpoint(SegValue(cs),reg_eip)) { From 2e3f978afe8ff0145e676eb02e9575697d224eeb Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 9 Sep 2003 14:00:02 +0000 Subject: [PATCH 1160/4131] fixed bug in mscdex status word handling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1240 --- src/dos/dos_mscdex.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 580108a2..26a2cb93 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -587,13 +587,11 @@ bool CMscdex::SendDriverRequest(Bit16u drive, PhysPt data) Bit16u CMscdex::GetStatusWord(Bit8u subUnit) { - if (subUnit>=numDrives) return false; + if (subUnit>=numDrives) return 0x02; // error : Drive not ready Bit16u status ; if (dinfo[subUnit].lastResult) status = REQUEST_STATUS_DONE; // ok - else { - status = REQUEST_STATUS_ERROR | 0x02; // error : Drive not ready - } + else status = REQUEST_STATUS_ERROR; if (dinfo[subUnit].audioPlay) { // Check if audio is still playing.... @@ -731,7 +729,7 @@ static Bitu MSCDEX_Interrupt_Handler(void) case 0x0C : { /* IOCTL OUTPUT */ PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); subFuncNr = mem_readb(buffer); - // if (subFuncNr!=0x0B) LOG("MSCDEX: IOCTL OUTPUT Subfunction %02X",subFuncNr); +// LOG(LOG_MISC,LOG_ERROR)("MSCDEX: IOCTL OUTPUT Subfunction %02X",subFuncNr); switch (subFuncNr) { case 0x00 : // Unload /eject) media mscdex->LoadUnloadMedia(subUnit,true); From 3da5dcbd9b76660a7e000c3937141b5a232b9fc8 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 9 Sep 2003 14:01:06 +0000 Subject: [PATCH 1161/4131] fixed return value of ReadSectors Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1241 --- src/dos/cdrom_ioctl_win32.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index 34e0492d..3d15e366 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -242,7 +242,7 @@ bool CDROM_Interface_Ioctl::ReadSectors(PhysPt buffer, bool raw, unsigned long s MEM_BlockWrite(buffer,bufdata,buflen); delete[] bufdata; - return (byteCount!=num*RAW_SECTOR_SIZE) && (bStat>0); + return (byteCount==buflen) && (bStat>0); } bool CDROM_Interface_Ioctl::SetDevice(char* path, int forceCD) From 0c1d2529e0d037664c2cde7be944c23526a1cdb6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 9 Sep 2003 19:25:04 +0000 Subject: [PATCH 1162/4131] changed various CurMode->cheight into cheight which is read from the bios. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1242 --- src/ints/int10_char.cpp | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index c0935a9a..a1723891 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: int10_char.cpp,v 1.18 2003-09-09 19:25:04 qbix79 Exp $ */ + /* Character displaying moving functions */ #include "dosbox.h" @@ -25,10 +27,11 @@ #include "int10.h" static INLINE void CGA_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { - PhysPt dest=base+((CurMode->twidth*rnew)*(CurMode->cheight/2)+cleft)*2; - PhysPt src=base+((CurMode->twidth*rold)*(CurMode->cheight/2)+cleft)*2; + Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); + PhysPt dest=base+((CurMode->twidth*rnew)*(cheight/2)+cleft)*2; + PhysPt src=base+((CurMode->twidth*rold)*(cheight/2)+cleft)*2; Bitu copy=(cright-cleft)*2;Bitu nextline=CurMode->twidth*2; - for (Bitu i=0;icheight/2;i++) { + for (Bitu i=0;itwidth*rnew)*CurMode->cheight+cleft; - src=base+(CurMode->twidth*rold)*CurMode->cheight+cleft; + Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); + dest=base+(CurMode->twidth*rnew)*cheight+cleft; + src=base+(CurMode->twidth*rold)*cheight+cleft; Bitu nextline=CurMode->twidth; /* Setup registers correctly */ IO_Write(0x3ce,5);IO_Write(0x3cf,1); /* Memory transfer mode */ IO_Write(0x3c4,2);IO_Write(0x3c5,0xf); /* Enable all Write planes */ /* Do some copying */ Bitu rowsize=(cright-cleft); - copy=CurMode->cheight; + copy=cheight; for (;copy>0;copy--) { for (Bitu x=0;xtwidth*row)*(CurMode->cheight/2)+cleft)*2; + Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); + PhysPt dest=base+((CurMode->twidth*row)*(cheight/2)+cleft)*2; Bitu copy=(cright-cleft)*2;Bitu nextline=CurMode->twidth*2; - for (Bitu i=0;icheight/2;i++) { + for (Bitu i=0;itwidth*row)*CurMode->cheight+cleft; + Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); + dest=base+(CurMode->twidth*row)*cheight+cleft; Bitu nextline=CurMode->twidth; - Bitu copy=CurMode->cheight; Bitu rowsize=(cright-cleft); + Bitu copy = cheight; Bitu rowsize=(cright-cleft); for (;copy>0;copy--) { for (Bitu x=0;xtype) { case M_TEXT16: { @@ -298,20 +305,20 @@ static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool return; case M_CGA4: case M_CGA2: - if (chr<128) fontdata=Real2Phys(RealGetVec(0x43))+chr*8; + if (chr<128) fontdata=Real2Phys(RealGetVec(0x43))+chr*cheight; //was plain 8 else { chr-=128; - fontdata=Real2Phys(RealGetVec(0x1F))+(chr)*8; + fontdata=Real2Phys(RealGetVec(0x1F))+(chr)*cheight; //was plain 8 } break; default: - fontdata=Real2Phys(RealGetVec(0x43))+chr*real_readw(0x40,BIOSMEM_CHAR_HEIGHT); + fontdata=Real2Phys(RealGetVec(0x43))+chr*cheight; break; } x=8*col; - y=CurMode->cheight*row; + y=cheight*row; //TODO Check for out of bounds - for (Bit8u h=0;hcheight;h++) { + for (Bit8u h=0;h Date: Wed, 10 Sep 2003 12:57:40 +0000 Subject: [PATCH 1163/4131] volume label always upcase Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1243 --- src/dos/drive_cache.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index a9119220..db57b6f0 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.24 2003-08-13 14:55:24 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.25 2003-09-10 12:57:40 finsterr Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -111,7 +111,8 @@ void DOS_Drive_Cache::SetLabel(const char* vname) while (togo>0) { if (vname[vnamePos]==0) break; if (!point && (vname[vnamePos]=='.')) { togo=4; point=true; } - label[labelPos] = vname[vnamePos]; + label[labelPos] = vname[vnamePos]; + label[labelPos] = *upcase(&label[labelPos]); labelPos++; vnamePos++; togo--; if ((togo==0) && !point) { From 55237d31e3751ebacfa23eeac0751110a15b7fa8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 11 Sep 2003 07:02:04 +0000 Subject: [PATCH 1164/4131] Setting file date/time gives a success result now. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1244 --- src/dos/dos.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index fe98e810..a00d86b3 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -691,11 +691,12 @@ static Bitu DOS_21Handler(void) { CALLBACK_SCF(false); } else { CALLBACK_SCF(true); - }; + } + } else if (reg_al==0x01) { + LOG(LOG_DOSMISC,LOG_ERROR)("DOS:57:Set File Date Time Faked"); + CALLBACK_SCF(false); } else { - reg_cx=0; - reg_dx=0; - LOG(LOG_DOSMISC,LOG_ERROR)("DOS:57:Setting File Date is faked",reg_ah); + LOG(LOG_DOSMISC,LOG_ERROR)("DOS:57:Unsupported subtion %X",reg_al); } break; case 0x58: /* Get/Set Memory allocation strategy */ From 8c86a9768ed19208c6817b025c7dd36c8b9c1837 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 11 Sep 2003 13:52:31 +0000 Subject: [PATCH 1165/4131] int 21 31 does not set the carry flag anymore Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1245 --- src/dos/dos.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index a00d86b3..f1035b4e 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -327,16 +327,12 @@ static Bitu DOS_21Handler(void) { reg_ah=dos.version.minor; break; case 0x31: /* Terminate and stay resident */ -//TODO First get normal files executing + //TODO First get normal files executing + // Important: This service does not set the carry flag! DOS_ResizeMemory(dos.psp,®_dx); - if (DOS_Terminate(true)) { - dos.return_code=reg_al; - dos.return_mode=RETURN_TSR; - CALLBACK_SCF(false); - } else { - reg_ax=dos.errorcode; - CALLBACK_SCF(true); - } + DOS_Terminate(true); + dos.return_code=reg_al; + dos.return_mode=RETURN_TSR; break; case 0x33: /* Extended Break Checking */ switch (reg_al) { From b86cba702851b7ff916b10f5b23a3d96e27a8f29 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 12 Sep 2003 16:14:27 +0000 Subject: [PATCH 1166/4131] Set code.big to false when settings CS in real mode. SMSW stores entire cr0 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1246 --- src/cpu/cpu.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 5e7662af..c38e550f 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -138,6 +138,7 @@ bool Interrupt(Bitu num) { reg_eip=mem_readw(num << 2); Segs.val[cs]=mem_readw((num << 2)+2); Segs.phys[cs]=Segs.val[cs]<<4; + cpu.code.big=false; return CPU_CheckCodeType(CODE_REAL); } else { /* Protected Mode Interrupt */ @@ -213,6 +214,7 @@ bool CPU_Exception(Bitu exception,Bit32u error_code) { reg_eip=mem_readw(exception << 2); Segs.val[cs]=mem_readw((exception << 2)+2); Segs.phys[cs]=Segs.val[cs]<<4; + cpu.code.big=false; return CPU_CheckCodeType(CODE_REAL); } else { /* Protected Mode Exception */ @@ -233,6 +235,7 @@ bool CPU_IRET(bool use32) { SegSet16(cs,CPU_Pop16()); CPU_SetFlagsw(CPU_Pop16()); } + cpu.code.big=false; return CPU_CheckCodeType(CODE_REAL); } else { /* Protected mode IRET */ /* Check if this is task IRET */ @@ -323,6 +326,7 @@ bool CPU_JMP(bool use32,Bitu selector,Bitu offset) { reg_eip=offset; } SegSet16(cs,selector); + cpu.code.big=false; return CPU_CheckCodeType(CODE_REAL); } else { Bitu rpl=selector & 3; @@ -367,6 +371,7 @@ bool CPU_CALL(bool use32,Bitu selector,Bitu offset) { CPU_Push32(reg_eip); reg_eip=offset; } + cpu.code.big=false; SegSet16(cs,selector); return CPU_CheckCodeType(CODE_REAL); } else { @@ -422,6 +427,7 @@ bool CPU_RET(bool use32,Bitu bytes) { reg_esp+=bytes; SegSet16(cs,new_cs); reg_eip=new_ip; + cpu.code.big=false; return CPU_CheckCodeType(CODE_REAL); } else { Bitu offset,selector; @@ -561,7 +567,7 @@ Bitu CPU_GET_CRX(Bitu cr) { void CPU_SMSW(Bitu & word) { - word=cpu.cr0 & 0xffff; + word=cpu.cr0; } bool CPU_LMSW(Bitu word) { From cdfcb1733575abd53625af61e611361996ada36e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 12 Sep 2003 16:15:55 +0000 Subject: [PATCH 1167/4131] Add 32-bit bound and saving segment values to memory only saves 16-bit value Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1247 --- src/cpu/core_normal/prefix_66.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 86efc6df..0fd1d5dc 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -150,6 +150,17 @@ reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32(); break; + CASE_D(0x62) /* BOUND Ed */ + { + Bit32s bound_min, bound_max; + GetRMrd;GetEAa; + bound_min=LoadMd(eaa); + bound_max=LoadMd(eaa+4); + if ( (((Bit32s)*rmrd) < bound_min) || (((Bit32s)*rmrd) > bound_max) ) { + EXCEPTION(5); + } + } + break; CASE_D(0x63) /* ARPL Ed,Rd */ { FillFlags(); @@ -279,7 +290,7 @@ E_Exit("CPU:8c:Illegal RM Byte"); } if (rm >= 0xc0 ) {GetEArd;*eard=val;} - else {GetEAa;SaveMd(eaa,val);} + else {GetEAa;SaveMw(eaa,val);} break; } CASE_D(0x8d) /* LEA Gd */ From ccbc6f2a8bea1f4c596ba5e5dc4cd558d62af3f6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 12 Sep 2003 16:28:20 +0000 Subject: [PATCH 1168/4131] Fix some issues with opcodes saving 32-bit results where they should save 16-bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1248 --- src/cpu/core_normal/prefix_66_0f.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 8a61ae72..7496d841 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -25,8 +25,8 @@ Bitu saveval; if (!which) CPU_SLDT(saveval); else CPU_STR(saveval); - if (rm >= 0xc0) {GetEArd;*eard=saveval;} - else {GetEAa;SaveMd(eaa,saveval);} + if (rm >= 0xc0) {GetEArw;*earw=(Bit16u)saveval;} + else {GetEAa;SaveMw(eaa,saveval);} } break; case 0x02:case 0x03:case 0x04:case 0x05: @@ -57,13 +57,13 @@ switch (which) { case 0x00: /* SGDT */ CPU_SGDT(limit,base); - SaveMw(eaa,limit); - SaveMd(eaa+2,base); + SaveMw(eaa,(Bit16u)limit); + SaveMd(eaa+2,(Bit32u)base); break; case 0x01: /* SIDT */ CPU_SIDT(limit,base); - SaveMw(eaa,limit); - SaveMd(eaa+2,base); + SaveMw(eaa,(Bit16u)limit); + SaveMd(eaa+2,(Bit32u)base); break; case 0x02: /* LGDT */ CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2)); @@ -73,22 +73,22 @@ break; case 0x04: /* SMSW */ CPU_SMSW(limit); - SaveMw(eaa,limit); + SaveMw(eaa,(Bit16u)limit); break; case 0x06: /* LMSW */ limit=LoadMw(eaa); - if (!CPU_LMSW(limit)) goto decode_end; + if (!CPU_LMSW((Bit16u)limit)) goto decode_end; break; } } else { - GetEArw;Bitu limit; + GetEArd;Bitu limit; switch (which) { case 0x04: /* SMSW */ CPU_SMSW(limit); - *earw=limit; + *eard=(Bit32u)limit; break; case 0x06: /* LMSW */ - if (!CPU_LMSW(*earw)) goto decode_end; + if (!CPU_LMSW(*eard)) goto decode_end; break; default: LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which); From a4713efd901aebc032386d304ee967e4a78a00e5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 17 Sep 2003 19:15:49 +0000 Subject: [PATCH 1169/4131] Several Mouse fixes: cd-v19, iron seed, cm93. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1249 --- src/ints/mouse.cpp | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index be956dfb..8b85259e 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: mouse.cpp,v 1.22 2003-09-17 19:15:49 qbix79 Exp $ */ #include #include "dosbox.h" @@ -261,9 +262,11 @@ void DrawCursor() { return; } - mouse.clipx = CurMode->swidth-1; + mouse.clipx = CurMode->swidth-1; /* Get from bios ? */ mouse.clipy = CurMode->sheight-1; - + Bit16s xratio = 640 / CurMode->swidth; /* might be mouse.max_x-.mouse.min_x+1/swidth */ + /* might even be vidmode == 0x13?2:1 */ + RestoreCursorBackground(); SaveVgaRegisters(); @@ -272,7 +275,7 @@ void DrawCursor() { Bit16s x,y; Bit16u addx1,addx2,addy; Bit16u dataPos = 0; - Bit16s x1 = POS_X - mouse.hotx; + Bit16s x1 = POS_X / xratio - mouse.hotx; Bit16s y1 = POS_Y - mouse.hoty; Bit16s x2 = x1 + CURSORX - 1; Bit16s y2 = y1 + CURSORY - 1; @@ -288,7 +291,7 @@ void DrawCursor() { dataPos += addx2; }; mouse.background= true; - mouse.backposx = POS_X - mouse.hotx; + mouse.backposx = POS_X / xratio - mouse.hotx; mouse.backposy = POS_Y - mouse.hoty; // Draw Mousecursor @@ -388,10 +391,6 @@ static void SetMickeyPixelRate(Bit16s px, Bit16s py) } }; -void Mouse_NewVideoMode(void) -{ - mouse.shown = -1; // hide cursor -} static void mouse_reset(void) { @@ -436,9 +435,10 @@ static void mouse_reset(void) mouse.events=0; mouse.mickey_x=0; mouse.mickey_y=0; - mouse.sub_mask=0; - mouse.sub_seg=0; - mouse.sub_ofs=0; + //mouse.sub_mask=0; + //mouse.sub_seg=0; + //mouse.sub_ofs=0; + //disabled this for iron seed mouse.hotx = 0; mouse.hoty = 0; @@ -451,9 +451,16 @@ static void mouse_reset(void) SetMickeyPixelRate(8,16); } +void Mouse_NewVideoMode(void) +{ + //mouse.shown = -1; + mouse_reset(); + //Added this for cd-v19 +} + static Bitu INT33_Handler(void) { -// LOG(0,"MOUSE: %04X",reg_ax); +// LOG(LOG_MOUSE,LOG_NORMAL)("MOUSE: %04X",reg_ax); switch (reg_ax) { case 0x00: /* Reset Driver and Read Status */ case 0x21: /* Software Reset */ @@ -481,8 +488,8 @@ static Bitu INT33_Handler(void) { reg_dx=POS_Y; break; case 0x04: /* Position Mouse */ - mouse.x=(float)reg_cx; - mouse.y=(float)reg_dx; + mouse.x = static_cast(((reg_cx > mouse.max_x) ? mouse.max_x : reg_cx)); + mouse.y = static_cast(((reg_dx > mouse.max_y) ? mouse.max_y : reg_dx)); DrawCursor(); break; case 0x05: /* Return Button Press Data */ @@ -508,20 +515,23 @@ static Bitu INT33_Handler(void) { break; } case 0x07: /* Define horizontal cursor range */ - { + { //lemmings set 1-640 and wants that. iron seeds set 0-640 but doesn't like 640 Bits max,min; if ((Bit16s)reg_cx<(Bit16s)reg_dx) { min=(Bit16s)reg_cx;max=(Bit16s)reg_dx;} else { min=(Bit16s)reg_dx;max=(Bit16s)reg_cx;} + if(max - min + 1 > 640) max = min + 640 - 1; mouse.min_x=min; mouse.max_x=max; LOG(LOG_MOUSE,LOG_NORMAL)("Define Hortizontal range min:%d max:%d",min,max); } break; case 0x08: /* Define vertical cursor range */ - { + { // not sure what to take instead of the CurMode (see case 0x07 as well) + // especially the cases where sheight= 400 and we set it with the mouse_reset to 200 Bits max,min; if ((Bit16s)reg_cx<(Bit16s)reg_dx) { min=(Bit16s)reg_cx;max=(Bit16s)reg_dx;} else { min=(Bit16s)reg_dx;max=(Bit16s)reg_cx;} + if(static_cast(max - min + 1) > CurMode->sheight) max = min + CurMode->sheight - 1; mouse.min_y=min; mouse.max_y=max; LOG(LOG_MOUSE,LOG_NORMAL)("Define Vertical range min:%d max:%d",min,max); From a221b69c29871aefef73088dd1ad494178db5783 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 17 Sep 2003 19:17:35 +0000 Subject: [PATCH 1170/4131] Ignoring int 17:20 now. Fixes some picture game Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1250 --- src/ints/bios.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 59447d4a..d04a0e6c 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -15,6 +15,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* $Id: bios.cpp,v 1.21 2003-09-17 19:17:35 qbix79 Exp $ */ + #include #include "dosbox.h" #include "bios.h" @@ -152,8 +155,11 @@ static Bitu INT17_Handler(void) { case 0x02: /* PRINTER: Get Status */ reg_ah=0; break; + case 0x20: /* Some sort of printerdriver install check*/ + break; default: E_Exit("Unhandled INT 17 call %2X",reg_ah); + }; return CBRET_NONE; } From 9a220bdfcb9aea4e8d411cca8ca06004ce1b6e16 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 17 Sep 2003 20:29:56 +0000 Subject: [PATCH 1171/4131] fixed syndicate (removed Y restriction) seperated the hardware and the software reset. Everything makes much more sense now. software reset: don't touch irq 12 handlers(User Interupt Routine) Hardware reset: do touch irq 12 A software reset is issued if a new videomode is set(now it doesn't destroy the UIR) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1251 --- src/ints/mouse.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 8b85259e..c5f2ddf8 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.22 2003-09-17 19:15:49 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.23 2003-09-17 20:29:56 qbix79 Exp $ */ #include #include "dosbox.h" @@ -391,6 +391,11 @@ static void SetMickeyPixelRate(Bit16s px, Bit16s py) } }; +static void mouse_reset_hardware(void){ + mouse.sub_mask=0; + mouse.sub_seg=0; + mouse.sub_ofs=0; +}; static void mouse_reset(void) { @@ -435,10 +440,6 @@ static void mouse_reset(void) mouse.events=0; mouse.mickey_x=0; mouse.mickey_y=0; - //mouse.sub_mask=0; - //mouse.sub_seg=0; - //mouse.sub_ofs=0; - //disabled this for iron seed mouse.hotx = 0; mouse.hoty = 0; @@ -463,9 +464,10 @@ static Bitu INT33_Handler(void) { // LOG(LOG_MOUSE,LOG_NORMAL)("MOUSE: %04X",reg_ax); switch (reg_ax) { case 0x00: /* Reset Driver and Read Status */ + mouse_reset_hardware(); /* fallthrough */ case 0x21: /* Software Reset */ reg_ax=0xffff; - reg_bx=MOUSE_BUTTONS; + reg_bx=MOUSE_BUTTONS; mouse_reset(); Mouse_AutoLock(true); break; @@ -528,10 +530,11 @@ static Bitu INT33_Handler(void) { case 0x08: /* Define vertical cursor range */ { // not sure what to take instead of the CurMode (see case 0x07 as well) // especially the cases where sheight= 400 and we set it with the mouse_reset to 200 + //disabled it at the moment. Seems to break syndicate who want 400 in mode 13 Bits max,min; if ((Bit16s)reg_cx<(Bit16s)reg_dx) { min=(Bit16s)reg_cx;max=(Bit16s)reg_dx;} else { min=(Bit16s)reg_dx;max=(Bit16s)reg_cx;} - if(static_cast(max - min + 1) > CurMode->sheight) max = min + CurMode->sheight - 1; + // if(static_cast(max - min + 1) > CurMode->sheight) max = min + CurMode->sheight - 1; mouse.min_y=min; mouse.max_y=max; LOG(LOG_MOUSE,LOG_NORMAL)("Define Vertical range min:%d max:%d",min,max); @@ -678,6 +681,7 @@ void MOUSE_Init(Section* sec) { real_writed(0,(0x74<<2),CALLBACK_RealPointer(call_int74)); memset(&mouse,0,sizeof(mouse)); + mouse_reset_hardware(); mouse_reset(); } From 3145bf21652056d10fa41adce74ff3a293912e97 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 19 Sep 2003 12:57:27 +0000 Subject: [PATCH 1172/4131] fixed rtc timers to behave like timer instead of a onetime event. fixes several games Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1252 --- src/hardware/cmos.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index bf179069..08b08b0d 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -45,6 +45,7 @@ static struct { static void cmos_timerevent(void) { PIC_ActivateIRQ(8); + if(cmos.timer.enabled) PIC_AddEvent(cmos_timerevent,cmos.timer.micro); if (cmos.ack) { PIC_AddEvent(cmos_timerevent,cmos.timer.micro); cmos.regs[0x0c]|=0x0a0; From b051edeeba516f10329437394310183a522b3228 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 19 Sep 2003 15:06:06 +0000 Subject: [PATCH 1173/4131] Added support detection of directory via getfileatrribues. Fixed Ancient Domain of Mystery Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1253 --- src/dos/drive_local.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 8c0c119e..4abace09 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -197,6 +197,7 @@ bool localDrive::GetFileAttr(char * name,Bit16u * attr) { struct stat status; if (stat(newname,&status)==0) { *attr=DOS_ATTR_ARCHIVE; + if(status.st_mode & S_IFDIR) *attr|=DOS_ATTR_DIRECTORY; return true; } *attr=0; From 9303d2300ec316a0100a2c1589e2d100268ca1be Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 21 Sep 2003 12:16:02 +0000 Subject: [PATCH 1174/4131] fixed -c and added -exit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1254 --- src/shell/shell.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 1d73485b..6182fa18 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.33 2003-09-08 18:25:44 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.34 2003-09-21 12:16:02 qbix79 Exp $ */ #include #include @@ -212,12 +212,19 @@ void AUTOEXEC_Init(Section * sec) { Section_line * section=static_cast(sec); char * extra=(char *)section->data.c_str(); if (extra) SHELL_AddAutoexec("%s",extra); + /* Check to see for extra command line options to be added (before the command specified on commandline) */ + while (control->cmdline->FindString("-c",line,true)) + SHELL_AddAutoexec((char *)line.c_str()); + + /* Check for the -exit switch which causes dosbox to when the command on the commandline has finished */ + bool addexit = control->cmdline->FindExist("-exit",true); + /* Check for first command being a directory or file */ char buffer[CROSS_LEN]; if (control->cmdline->FindCommand(1,line)) { struct stat test; strcpy(buffer,line.c_str()); - if (stat(buffer,&test)) { + if (stat(buffer,&test)){ getcwd(buffer,CROSS_LEN); strcat(buffer,line.c_str()); if (stat(buffer,&test)) goto nomount; @@ -233,12 +240,9 @@ void AUTOEXEC_Init(Section * sec) { SHELL_AddAutoexec("MOUNT C \"%s\"",buffer); SHELL_AddAutoexec("C:"); SHELL_AddAutoexec(name); + if(addexit) SHELL_AddAutoexec("exit"); } } - /* Check to see for extra command line options to be added */ - while (control->cmdline->FindString("-c",line,true)) { - SHELL_AddAutoexec((char *)line.c_str()); - } nomount: VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,strlen(autoexec_data)); } From 79a1dcd2bccd81ef77fba25423124470dfa42eac Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 21 Sep 2003 13:30:25 +0000 Subject: [PATCH 1175/4131] Fixed path parsing. made it more robust as well. (and slower offcourse) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1255 --- src/shell/shell_misc.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index c546352e..f7d78f27 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.24 2003-09-08 18:22:57 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.25 2003-09-21 13:30:25 qbix79 Exp $ */ #include #include @@ -397,7 +397,7 @@ char * DOS_Shell::Which(char * name) { /* No Path in filename look through path environment string */ - static char path[DOS_PATHLENGTH];std::string temp; + char path[DOS_PATHLENGTH];std::string temp; if (!GetEnvStr("PATH",temp)) return 0; const char * pathenv=temp.c_str(); if (!pathenv) return 0; @@ -406,12 +406,21 @@ char * DOS_Shell::Which(char * name) { pathenv++; char * path_write=path; while (*pathenv) { - if (*pathenv!=';') { + /* remove ; and ;; at the beginning. (and from the second entry etc) */ + while(*pathenv && (*pathenv ==';')) + pathenv++; + + /* Clear old path */ + for(Bitu dummy = 0;dummy < DOS_PATHLENGTH; dummy++) + path[dummy] = 0; //OVERKILL could be strlen(path). but run no risks + + /* get next entry */ + while(*pathenv && (*pathenv !=';')) *path_write++=*pathenv++; - } - if (*pathenv==';' || *(pathenv)==0) { - if (*path_write!='\\') *path_write++='\\'; - *path_write++=0; + + /* check entry */ + if(Bitu len=strlen(path)){ + if(path[strlen(path)-1]!='\\') strcat(path,"\\"); strcat(path,name); strcpy(which_ret,path); if (DOS_FileExists(which_ret)) return which_ret; @@ -424,10 +433,9 @@ char * DOS_Shell::Which(char * name) { strcpy(which_ret,path); strcat(which_ret,bat_ext); if (DOS_FileExists(which_ret)) return which_ret; - - path_write=path; - if (*pathenv) pathenv++; } + path_write=path; /* reset it */ + } return 0; } From 1beb5f4835f4a443f65372031d37111073bb7c47 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 21 Sep 2003 15:01:14 +0000 Subject: [PATCH 1176/4131] Update to reflect the mount -label command. and hopefully made it better understandable. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1256 --- README | 229 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 142 insertions(+), 87 deletions(-) diff --git a/README b/README index 1369451f..cc29c5f8 100644 --- a/README +++ b/README @@ -1,34 +1,35 @@ -DOSBox v0.58 +DOSBox v0.60 +====== Usage: ====== -With the new internal shell,we've changed the command line a bit, -so let's just give some examples of what you can do now. +dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] + [-lang languagefile] -dosbox - With nothing on the command line you'll end up on the internal drive and - from there you can mount directories as drives. -dosbox [filename/directory] - If dosbox detects a directory it'll mount that as the C: drive - and then start the shell from c:\. - If dosbox doesn't detect a directory it'll assume you mean an executable. - This can be .bat .com .exe. Doesn't need to have extension included. - It will mount the directory the file is in as the C: drive. - Then start up the shell which will start the file. + name + If "name" is a directory it'll mount that as the C: drive. + If "name" is a executable it'll mount the directory of "name" + as the C: drive and execute "name". + + -exit + dosbox will exit after the "name" has been executed. -There also are a couple of command line switches. + -c command + Runs the specified command before running "name". Multiple commands + can be specified. Each command should start with -c though. -dosbox -fullscreen - starts dosbox in fullscreen mode. -dosbox -conf file - loads file as a configfile. -dosbox -lang file - loads file as a languagefile. + -fullscreen + Starts dosbox in fullscreenmode. -You can also add commands to be executed before the main program starts. -Or you can use them to start the program. -To add commands use the -c command line switch. + -conf configfile + Start dosbox with the options specified in "configfile". + + -lang languagefile + Start dosbox using the language string specified in "languagefile". + +Note: If a name/command/configfile/languagefile contains a space in it put + the whole name/command/configfile/languagefile between quotes("example"). For example: @@ -37,61 +38,82 @@ dosbox c:\atlantis\atlantis.exe -c "MOUNT D C:\SAVES" Before it does that it would first mount C:\SAVES as the D drive. In Windows you can also drag directories/files on the dosbox executable. + + +================== Internal Programs: ================== -MOUNT -Program to mount local directories as drives inside DOSBox. -The option -t specifies the media: Where can be. - dir = harddisk - floppy = floppy drive - cdrom = cdrom drive +dosbox supports most of the DOS commands found in command.com. +In addition, the following commands are available: -The option -cd lists all found cdrom drives and their id. -The option -usecd [x] forces to use the cdrom number x (id as shown in list -cd) +MOUNT Driveletter sourcedirectory [-t type] [-aspi] [-ioctl] + [-usecd number] [-size drivesize] [-label drivelabel] +MOUNT -cd + + Program to mount local directories as drives inside DOSBox. -The option -aspi forces to use aspi driver - (only valid if mounting a cdrom and on Windows systems with ASPI-Layer). -The option -ioctl forces to use ioctl functions - (only valid if mounting a cdrom and on Win2000/XP/NT systems). + Driveletter + The driveletter inside dosbox (eg. C) -For example to mount c:\floppy as a floppy : mount a c:\floppy -t floppy -For example to mount system cdrom drive e as cdrom drive d in dosbox - mount d e:\ -t cdrom -For example to mount system cdrom drive at mountpoint /media/cdrom as cdrom -drive d in dosbox - mount d /media/cdrom -t cdrom -usecd 0 + sourcedirectory + The local directory you want to have inside dosbox. -It is also possible to mount a directory as cdrom, but it's limited. + -t type + Type of the mounted directory. Supported are: dir (standard), + floppy, cdrom. + + -size drivesize + Sets the size of the drive. + + -label drivelabel + Sets the name of the drive to "drivelabel". Usefull when a + program can't find it's cdrom. + + -aspi + Forces to use the aspi layer. Only valid if mounting a cdrom under + Windows systems with an ASPI-Layer + + -ioctl + Forces to use ioctl commands. Only valid if mounting a cdrom under + windows which support them (Win2000/XP/NT). + + -usecd number + Forces to use SDL cdrom support for drive number. + Number can be found by -cd. Valid on all systems + + -cd + Displays all detected cdrom drives and their numbers. Use with -usecd + + Note: It's possible to mount a local directory as cdrom drive. + Hardware support is then missing. + + Examples: + 1. To mount c:\floppy as a floppy : + mount a c:\floppy -t floppy + 2. To mount system cdrom drive E as cdrom drive D in dosbox: + mount d e:\ -t cdrom + 3. To mount system cdrom drive at mountpoint /media/cdrom as cdrom drive D + in dosbox: + mount d /media/cdrom -t cdrom -usecd 0 MEM -Program to display the amount of free memory + Program to display the amount of free memory -CONFIG -Utility for generating a config file and language file. -The option -writeconf filename is used to write the current config settings. -The option -writelang filename is used to write the current language strings. +CONFIG [-writeconf] [-writelang] localfile + Write the current configuration or language settings to file. + "localfile" is located on the local drive !!! + +LOADFIX + Program to "eat up" memory. Usefull for old programs which don't expect much + memory to be free. For more information use the the /? command line switch with the programs. -The Config File: -=============== -A config file can be generated by CONFIG.COM, edit it to customize DOSBox. -The file is divided in several sections (the names got [] around it). -Some sections have options which you can set. -# and % indicate commentlines. -The generated configfile contains the current settings. You can alter them and -start dosbox with the -conf switch to load the file and use these settings. -The Language File: -================= -A language file can be generated by CONFIG.COM. -Read it and you will hopefuly understand how to change it. -Start Dosbox with -lang switch to use your new language file -Or you can setup the filename in the config file in the [dosbox] section. -There's a language= entry that can be changed with the filename. +============= Special Keys: ============= @@ -105,38 +127,20 @@ CTRL-F10 Capture/Release the mouse. CTRL-F11 Slowdown emulation. CTRL-F12 Speedup emulation. +==================== System requirements: ==================== Fast machine my guess would be pentium-2 400+ to get decent emulation of games written for an 286 machine. - -FAQ: -==== - -Q: I've got a Z instead of a C at the prompt. -A: In DOSBox you can mount directories as drives - in win32: mount c D:\ would give you an C in DOSBox which points - at D:\ in win32 - in linux: mount c /home/username would give you and C in DOSBox - which points at /home/username in Linux - -Q: The mouse doesn't work. -A: Normally dosbox detects the mouse being used by a game, if you click on - the screen then it should get locked and work. - Sometimes the dosbox mouse detection doesn't work with certain games, you - might have to force to lock the mouse then with ctrl-f10. - -Q: The sound stutters. -A: Your using too much cpu power to keep dosbox running at the current speed. - You can either lower the cycles or skip frames or get a faster machine. - - -For more questions check the site/forum. +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 somewhat up. +================================ To run resource-demanding games: -=============================== +================================ DOSBox emulates the CPU, the sound and graphic cards, and some other stuff, all at the same time. You can overclock DOSBox by using CTRL+F12, but @@ -164,12 +168,62 @@ You can also try to disable the sound through the setup utility of the game to further reduce load on your CPU. +==== +FAQ: +==== + +Q: I've got a Z instead of a C at the prompt. +A: In DOSBox you can mount directories as drives + in win32: mount c D:\ would give you a C in DOSBox which points + at D:\ in win32 + in linux: mount c /home/username would give you a C in DOSBox + which points at /home/username in Linux + +Q: The mouse doesn't work. +A: Normally dosbox detects the mouse being used by a game, if you click on + the screen then it should get locked and work. + Sometimes the dosbox mouse detection doesn't work with certain games, you + might have to force to lock the mouse then with ctrl-F10. + +Q: The sound stutters. +A: Your using too much cpu power to keep dosbox running at the current speed. + You can either lower the cycles or skip frames or get a faster machine. + + +For more questions check the site/forum: +http://dosbox.sourceforge.net + + +================ +The Config File: +================ + +A config file can be generated by CONFIG.COM, edit it to customize DOSBox. +The file is divided in several sections (the names got [] around it). +Some sections have options which you can set. +# and % indicate commentlines. +The generated configfile contains the current settings. You can alter them and +start dosbox with the -conf switch to load the file and use these settings. + +================== +The Language File: +================== + +A language file can be generated by CONFIG.COM. +Read it and you will hopefuly understand how to change it. +Start Dosbox with -lang switch to use your new language file +Or you can setup the filename in the config file in the [dosbox] section. +There's a language= entry that can be changed with the filename. + + +================================= Building your own Version DOSBox: ================================= Dowload the source. Check the INSTALL in the source distribution. +=============== Special Thanks: =============== @@ -179,8 +233,9 @@ The Bochs and DOSemu projects which I used for information. Freedos for ideas in making my shell. The Beta Testers. +======== Contact: ======== Harekiet harekiet@zophar.net -http://dosbox.zophar.net +http://dosbox.sourceforge.net From 341c2c90518290e55b48bf53e62319ba3d5cd29d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 21 Sep 2003 16:11:08 +0000 Subject: [PATCH 1177/4131] Spelling errors corrected by wjp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1257 --- README | 70 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/README b/README index cc29c5f8..17046551 100644 --- a/README +++ b/README @@ -9,7 +9,7 @@ dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] name If "name" is a directory it'll mount that as the C: drive. - If "name" is a executable it'll mount the directory of "name" + If "name" is an executable it'll mount the directory of "name" as the C: drive and execute "name". -exit @@ -20,7 +20,7 @@ dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] can be specified. Each command should start with -c though. -fullscreen - Starts dosbox in fullscreenmode. + Starts dosbox in fullscreen mode. -conf configfile Start dosbox with the options specified in "configfile". @@ -28,16 +28,16 @@ dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] -lang languagefile Start dosbox using the language string specified in "languagefile". -Note: If a name/command/configfile/languagefile contains a space in it put +Note: If a name/command/configfile/languagefile contains a space in it, put the whole name/command/configfile/languagefile between quotes("example"). For example: dosbox c:\atlantis\atlantis.exe -c "MOUNT D C:\SAVES" - This would mount c:\atlanis as c:\ and run atlantis.exe. + This would mount c:\atlantis as c:\ and run atlantis.exe. Before it does that it would first mount C:\SAVES as the D drive. -In Windows you can also drag directories/files on the dosbox executable. +In Windows you can also drag directories/files onto the dosbox executable. @@ -55,7 +55,7 @@ MOUNT -cd Program to mount local directories as drives inside DOSBox. Driveletter - The driveletter inside dosbox (eg. C) + The driveletter inside dosbox (eg. C). sourcedirectory The local directory you want to have inside dosbox. @@ -68,12 +68,12 @@ MOUNT -cd Sets the size of the drive. -label drivelabel - Sets the name of the drive to "drivelabel". Usefull when a - program can't find it's cdrom. + Sets the name of the drive to "drivelabel". Useful when a + program can't find its cdrom. -aspi Forces to use the aspi layer. Only valid if mounting a cdrom under - Windows systems with an ASPI-Layer + Windows systems with an ASPI-Layer. -ioctl Forces to use ioctl commands. Only valid if mounting a cdrom under @@ -81,10 +81,10 @@ MOUNT -cd -usecd number Forces to use SDL cdrom support for drive number. - Number can be found by -cd. Valid on all systems + Number can be found by -cd. Valid on all systems. -cd - Displays all detected cdrom drives and their numbers. Use with -usecd + Displays all detected cdrom drives and their numbers. Use with -usecd. Note: It's possible to mount a local directory as cdrom drive. Hardware support is then missing. @@ -99,17 +99,17 @@ MOUNT -cd mount d /media/cdrom -t cdrom -usecd 0 MEM - Program to display the amount of free memory + Program to display the amount of free memory. CONFIG [-writeconf] [-writelang] localfile Write the current configuration or language settings to file. "localfile" is located on the local drive !!! LOADFIX - Program to "eat up" memory. Usefull for old programs which don't expect much + Program to "eat up" memory. Useful for old programs which don't expect much memory to be free. -For more information use the the /? command line switch with the programs. +For more information use the /? command line switch with the programs. @@ -124,18 +124,18 @@ CTRL-F7 Decrease frameskip. CTRL-F8 Increase frameskip. CTRL-F9 Kill dosbox. CTRL-F10 Capture/Release the mouse. -CTRL-F11 Slowdown emulation. -CTRL-F12 Speedup emulation. +CTRL-F11 Slow down emulation. +CTRL-F12 Speed up emulation. ==================== System requirements: ==================== -Fast machine my guess would be pentium-2 400+ to get decent emulation +Fast machine. My guess would be pentium-2 400+ to get decent emulation of games written for an 286 machine. 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 somewhat up. +it up somewhat. ================================ @@ -173,20 +173,20 @@ FAQ: ==== Q: I've got a Z instead of a C at the prompt. -A: In DOSBox you can mount directories as drives - in win32: mount c D:\ would give you a C in DOSBox which points - at D:\ in win32 - in linux: mount c /home/username would give you a C in DOSBox - which points at /home/username in Linux +A: In DOSBox you can mount directories as drives. + In win32: mount c D:\ would give you a C in DOSBox which points + at D:\ in win32. + In linux: mount c /home/username would give you a C in DOSBox + which points at /home/username in Linux. Q: The mouse doesn't work. -A: Normally dosbox detects the mouse being used by a game, if you click on +A: Normally dosbox detects the mouse being used by a game. If you click on the screen then it should get locked and work. - Sometimes the dosbox mouse detection doesn't work with certain games, you + Sometimes the dosbox mouse detection doesn't work with certain games. You might have to force to lock the mouse then with ctrl-F10. Q: The sound stutters. -A: Your using too much cpu power to keep dosbox running at the current speed. +A: You're using too much cpu power to keep dosbox running at the current speed. You can either lower the cycles or skip frames or get a faster machine. @@ -198,8 +198,8 @@ http://dosbox.sourceforge.net The Config File: ================ -A config file can be generated by CONFIG.COM, edit it to customize DOSBox. -The file is divided in several sections (the names got [] around it). +A config file can be generated by CONFIG.COM. Edit it to customize DOSBox. +The file is divided into several sections (the names have [] around it). Some sections have options which you can set. # and % indicate commentlines. The generated configfile contains the current settings. You can alter them and @@ -210,17 +210,17 @@ The Language File: ================== A language file can be generated by CONFIG.COM. -Read it and you will hopefuly understand how to change it. -Start Dosbox with -lang switch to use your new language file -Or you can setup the filename in the config file in the [dosbox] section. +Read it and you will hopefully understand how to change it. +Start Dosbox with the -lang switch to use your new language file +or you can setup the filename in the config file in the [dosbox] section. There's a language= entry that can be changed with the filename. -================================= -Building your own Version DOSBox: -================================= +==================================== +Building your own version of DOSBox: +==================================== -Dowload the source. +Download the source. Check the INSTALL in the source distribution. =============== From d95aa00127d375bf34fa1b895a18a3f39b0f77ab Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 22 Sep 2003 12:20:51 +0000 Subject: [PATCH 1178/4131] Use new FindFirst/FindNext methods of drive-cache Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1258 --- src/dos/drive_local.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 4abace09..f10fbed7 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -110,7 +110,8 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { if (tempDir[strlen(tempDir)-1]!=CROSS_FILESPLIT) strcat(tempDir,end); Bit16u id; - if (!dirCache.OpenDir(tempDir,id)) +// if (!dirCache.OpenDir(tempDir,id)) + if (!dirCache.FindFirst(tempDir,id)) { DOS_SetError(DOSERR_PATH_NOT_FOUND); return false; @@ -145,7 +146,8 @@ bool localDrive::FindNext(DOS_DTA & dta) { Bit16u id = dta.GetDirID(); again: - if (!dirCache.ReadDir(id,dir_ent)) { +// if (!dirCache.ReadDir(id,dir_ent)) { + if (!dirCache.FindNext(id,dir_ent)) { DOS_SetError(DOSERR_NO_MORE_FILES); return false; } From 52c0878c0c20f48d18802423833926af43bd53ff Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 22 Sep 2003 12:21:53 +0000 Subject: [PATCH 1179/4131] new FindFirst/FindNext methods, removed outputList, changed Bit16s types to Bits Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1259 --- src/dos/drive_cache.cpp | 89 ++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 37 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index db57b6f0..93daf90f 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.25 2003-09-10 12:57:40 finsterr Exp $ */ +/* $Id: drive_cache.cpp,v 1.26 2003-09-22 12:21:53 finsterr Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -65,6 +65,7 @@ DOS_Drive_Cache::DOS_Drive_Cache(void) save_dir = 0; srchNr = 0; label[0] = 0; + dirFindFirst= 0; for (Bit32u i=0; ifileList.begin(), dir->fileList.end(), SortByName); - // Output list - user defined - switch (sortDirType) { - case ALPHABETICAL : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByName); break; - case DIRALPHABETICAL : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByDirName); break; - case ALPHABETICALREV : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByNameRev); break; - case DIRALPHABETICALREV : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByDirNameRev); break; - case NOSORT : break; - }; - - Bit16s index = GetLongName(dir,file); + Bits index = GetLongName(dir,file); if (index>=0) { Bit32u i; // Check if there are any open search dir that are affected by this... @@ -258,7 +252,6 @@ void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) // clear lists dir->fileList.clear(); dir->longNameList.clear(); - dir->outputList.clear(); dir->shortNr = 0; save_dir = 0; }; @@ -275,9 +268,9 @@ bool DOS_Drive_Cache::GetShortName(const char* fullname, char* shortname) char expand[CROSS_LEN] = {0}; CFileInfo* curDir = FindDirInfo(fullname,expand); - Bit16s low = 0; - Bit16s high = curDir->longNameList.size()-1; - Bit16s mid, res; + Bits low = 0; + Bits high = curDir->longNameList.size()-1; + Bits mid, res; while (low<=high) { mid = (low+high)/2; @@ -294,10 +287,10 @@ bool DOS_Drive_Cache::GetShortName(const char* fullname, char* shortname) Bit16u DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name) { - Bit16s foundNr = 0; - Bit16s low = 0; - Bit16s high = curDir->longNameList.size()-1; - Bit16s mid, res; + Bits foundNr = 0; + Bits low = 0; + Bits high = curDir->longNameList.size()-1; + Bits mid, res; while (low<=high) { mid = (low+high)/2; @@ -329,14 +322,14 @@ bool DOS_Drive_Cache::RemoveTrailingDot(char* shortname) return false; }; -Bit16s DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) +Bits DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) { // Remove dot, if no extension... RemoveTrailingDot(shortName); // Search long name and return array number of element - Bit16s low = 0; - Bit16s high = curDir->fileList.size()-1; - Bit16s mid,res; + Bits low = 0; + Bits high = curDir->fileList.size()-1; + Bits mid,res; while (low<=high) { mid = (low+high)/2; res = strcmp(shortName,curDir->fileList[mid]->shortname); @@ -365,8 +358,8 @@ bool DOS_Drive_Cache::RemoveSpaces(char* str) void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) { - Bit16s len = 0; - Bit16s lenExt = 0; + Bits len = 0; + Bits lenExt = 0; bool createShort = false; char tmpNameBuffer[CROSS_LEN]; @@ -479,7 +472,7 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* else { strcpy(dir,start); }; // Path found - Bit16s nextDir = GetLongName(curDir,dir); + Bits nextDir = GetLongName(curDir,dir); strcat(expandedPath,dir); // Error check @@ -567,7 +560,6 @@ void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name) CreateShortName(dir, info); // Put file in lists dir->fileList.push_back(info); - dir->outputList.push_back(info); }; bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) @@ -592,14 +584,6 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) } // close dir closedir(dirp); - // Output list - user defined - switch (sortDirType) { - case ALPHABETICAL : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByName); break; - case DIRALPHABETICAL : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByDirName); break; - case ALPHABETICALREV : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByNameRev); break; - case DIRALPHABETICALREV : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByDirNameRev); break; - case NOSORT : break; - }; // Info /* if (!dirp) { LOG_DEBUG("DIR: Error Caching in %s",dirPath); @@ -620,8 +604,8 @@ bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bit16u entryNr) static char res[CROSS_LEN]; result = res; - if (entryNr>=dir->outputList.size()) return false; - CFileInfo* info = dir->outputList[entryNr]; + if (entryNr>=dir->fileList.size()) return false; + CFileInfo* info = dir->fileList[entryNr]; // copy filename, short version strcpy(res,info->shortname); // Set to next Entry @@ -629,6 +613,37 @@ bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bit16u entryNr) return true; }; +// FindFirst / FindNext +bool DOS_Drive_Cache::FindFirst(char* path, Bit16u& id) +{ + // Cache directory in + if (!OpenDir(path,id)) return false; + // Find Free ID for directory copy + if (dirFindFirst) delete dirFindFirst; + dirFindFirst = new CFileInfo(); + dirFindFirst->nextEntry = 0; + // Copy entries to use with FindNext + for (Bitu i=0; ifileList.size(); i++) { + CreateEntry(dirFindFirst,dirSearch[id]->fileList[i]->orgname); + // Sort Lists - filelist has to be alphabetically sorted, even in between (for finding double file names) + std::sort(dirFindFirst->fileList.begin(), dirFindFirst->fileList.end(), SortByName); + }; + // Now re-sort the fileList accordingly to output + switch (sortDirType) { + case ALPHABETICAL : std::sort(dirFindFirst->fileList.begin(), dirFindFirst->fileList.end(), SortByName); break; + case DIRALPHABETICAL : std::sort(dirFindFirst->fileList.begin(), dirFindFirst->fileList.end(), SortByDirName); break; + case ALPHABETICALREV : std::sort(dirFindFirst->fileList.begin(), dirFindFirst->fileList.end(), SortByNameRev); break; + case DIRALPHABETICALREV : std::sort(dirFindFirst->fileList.begin(), dirFindFirst->fileList.end(), SortByDirNameRev); break; + case NOSORT : break; + }; + return true; +}; + +bool DOS_Drive_Cache::FindNext(Bit16u& id, char* &result) +{ + return SetResult(dirFindFirst, result, dirFindFirst->nextEntry); +}; + // **************************************************************************** // No Dir Cache, // **************************************************************************** From da87c80cef4a08761b02e87d317d4e859fbf0f69 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 22 Sep 2003 12:22:25 +0000 Subject: [PATCH 1180/4131] Drivecache: new FindFirst/FindNext methods, removed outputList, changed Bit16s types to Bits Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1260 --- include/dos_system.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 14593882..02ce52c2 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.14 2003-08-13 14:46:15 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.15 2003-09-22 12:22:25 finsterr Exp $ */ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ @@ -104,6 +104,9 @@ public: char* GetExpandName (const char* path); bool GetShortName (const char* fullname, char* shortname); + bool FindFirst (char* path, Bit16u& id); + bool FindNext (Bit16u& 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); @@ -118,7 +121,6 @@ public: for (Bit32u i=0; i fileList; std::vector longNameList; - std::vector outputList; }; private: bool RemoveTrailingDot (char* shortname); - Bit16s GetLongName (CFileInfo* info, char* shortname); + Bits GetLongName (CFileInfo* info, char* shortname); void CreateShortName (CFileInfo* dir, CFileInfo* info); Bit16u CreateShortNameID (CFileInfo* dir, const char* name); bool SetResult (CFileInfo* dir, char * &result, Bit16u entryNr); @@ -160,6 +161,7 @@ private: CFileInfo* dirSearch [MAX_OPENDIRS]; char dirSearchName [MAX_OPENDIRS]; bool free [MAX_OPENDIRS]; + CFileInfo* dirFindFirst; char label [CROSS_LEN]; }; From 155cbc5dffb9f7cda4441b9b3174d616ed7895cd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 22 Sep 2003 14:36:13 +0000 Subject: [PATCH 1181/4131] Add opcode 0xe5 an 0xe7 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1261 --- src/cpu/core_normal/prefix_66.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 0fd1d5dc..1530db9a 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -512,6 +512,24 @@ GRP2D(1);break; CASE_D(0xd3) /* GRP2 Ed,CL */ GRP2D(reg_cl);break; + CASE_D(0xe5) /* IN EAX,Ib */ + { + Bit16u port=Fetchb(); + reg_eax=IO_Read(port) | + (IO_Read(port+1) << 8 ) | + (IO_Read(port+2) << 16 ) | + (IO_Read(port+3) << 24 ); + break; + } + CASE_D(0xe7) /* OUT Ib,EAX */ + { + Bit16u port=Fetchb(); + IO_Write(port+0,(Bit8u)(reg_eax >> 0)); + IO_Write(port+1,(Bit8u)(reg_eax >> 8)); + IO_Write(port+2,(Bit8u)(reg_eax >> 16)); + IO_Write(port+3,(Bit8u)(reg_eax >> 24)); + break; + } CASE_D(0xe8) /* CALL Jd */ { Bit32s newip=Fetchds(); From 223ab1a2bcf1dee527299f833c13436f510b6dbd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 24 Sep 2003 16:56:35 +0000 Subject: [PATCH 1182/4131] Added core_normal to the visual C 6 workspace Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1262 --- visualc/dosbox.dsp | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index fdd35959..63283221 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -169,6 +169,42 @@ SOURCE=..\src\cpu\core_full\string.h SOURCE=..\src\cpu\core_full\support.h # End Source File # End Group +# Begin Group "core_normal" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\src\cpu\core_normal\helpers.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_normal\prefix_0f.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_normal\prefix_66.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_normal\prefix_66_0f.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_normal\prefix_none.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_normal\string.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_normal\support.h +# End Source File +# Begin Source File + +SOURCE=..\src\cpu\core_normal\table_ea.h +# End Source File +# End Group # Begin Source File SOURCE=..\src\cpu\callback.cpp @@ -179,6 +215,10 @@ SOURCE=..\src\cpu\core_full.cpp # End Source File # Begin Source File +SOURCE=..\src\cpu\core_normal.cpp +# End Source File +# Begin Source File + SOURCE=..\src\cpu\cpu.cpp # End Source File # Begin Source File @@ -191,6 +231,10 @@ SOURCE=..\src\cpu\instructions.h # End Source File # Begin Source File +SOURCE=..\src\cpu\lazyflags.h +# End Source File +# Begin Source File + SOURCE=..\src\cpu\modrm.cpp # End Source File # Begin Source File From b5ddbf0034f4aeb33c09184ae2361510df56689b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 24 Sep 2003 18:47:31 +0000 Subject: [PATCH 1183/4131] a bit more updated Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1263 --- INSTALL | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/INSTALL b/INSTALL index fae00576..12c4bd97 100644 --- a/INSTALL +++ b/INSTALL @@ -1,21 +1,28 @@ Things needed for compilation. SDL - The Simple DirectMedia Library available at http://www.libsdl.org + The Simple DirectMedia Library available at http://www.libsdl.org Curses - If you want to enable the debugger you need a curses library. - ncurses should be installed on just about every unix distro. - For win32 get pdcurses at http://pdcurses.sourceforge.net + (optional) + If you want to enable the debugger you need a curses library. + ncurses should be installed on just about every unix distro. + For win32 get pdcurses at http://pdcurses.sourceforge.net Libpng - Needed for the screenshots. (--enable-shots when configuring dosbox) + Needed for the screenshots. (optional) For win32 get libpng from http://www.sourceforge.net/projects/gnuwin32 Zlib - Needed by libpng. + Needed by libpng. (optional) For win32 get libz (rename to zlib) from http://www.sourceforge.net/projects/gnuwin32 +SDL_Net + For modem support(optional). Get it from http://www.libsdl.org + +ALSA_Headers + (optional) + ???????? for Alsa support under linux 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 @@ -26,19 +33,28 @@ If you are building from the cvs run ./autogen.sh first before doing the followi 1. ./configure 2. make -In step 1 you could add the following switches --enable-shots this will -enable the screenshot facility, also --enable-debug is a valid switch. This -will enable the internal debugger. (It can be started by pressing - on the -numeric keyboard) +In step 1 you could add the following switches: +--enable-debug + 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 - on numeric keyboard to enter the debugger. + +--disable-fpu + Will disable the emulated fpu. Although the fpu emulation hasn't finished and isn't + entirely accurate it's advised to leave it on. + +--enable-core-inline + enables some memory increasing inlines. This greatly increases compiletime for maybe a increase + in speed. Check the src subdir for the binary. + + Compiling on FreeBSD might be a problem since SDL has no joystick support there. To get around this edit sdlmain.cpp to enable some #define. Let's hope someday the sdl people will just report 0 joysticks in freebsd or get it working some other way :) Build instructions for VC++6 - -Open the workspace in the visualc subdir and build from there. - +Don't use VC++ 6:it creates faulty code in core_normal.cpp From 4c9fc85b6cc0cff54a5e2cf69dbeffa0497e92d8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 24 Sep 2003 19:33:26 +0000 Subject: [PATCH 1184/4131] fixed int10_teletype output when displaying a tab Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1264 --- src/ints/int10_char.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index a1723891..26e755b0 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.18 2003-09-09 19:25:04 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.19 2003-09-24 19:33:26 qbix79 Exp $ */ /* Character displaying moving functions */ @@ -378,7 +378,7 @@ void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr) { INT10_TeletypeOutput(' ',attr,showattr); cur_row=CURSOR_POS_ROW(page); cur_col=CURSOR_POS_COL(page); - } while(cur_col%8==0); + } while(cur_col%8); break; default: /* Draw the actual Character */ From e67f82f9134985437005b3e13765943e95a2f8c9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 24 Sep 2003 19:35:01 +0000 Subject: [PATCH 1185/4131] disabled iron seed hack. Should fix higres vesa modi Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1265 --- src/ints/mouse.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index c5f2ddf8..cb8dd185 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.23 2003-09-17 20:29:56 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.24 2003-09-24 19:35:01 qbix79 Exp $ */ #include #include "dosbox.h" @@ -521,7 +521,7 @@ static Bitu INT33_Handler(void) { Bits max,min; if ((Bit16s)reg_cx<(Bit16s)reg_dx) { min=(Bit16s)reg_cx;max=(Bit16s)reg_dx;} else { min=(Bit16s)reg_dx;max=(Bit16s)reg_cx;} - if(max - min + 1 > 640) max = min + 640 - 1; + //if(max - min + 1 > 640) max = min + 640 - 1; mouse.min_x=min; mouse.max_x=max; LOG(LOG_MOUSE,LOG_NORMAL)("Define Hortizontal range min:%d max:%d",min,max); From 1786adb90bc9de21a56a1622159f40639bc26eda Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 24 Sep 2003 19:36:14 +0000 Subject: [PATCH 1186/4131] Allowed tab as breaking character in a commandline Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1266 --- src/shell/shell_cmds.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index d6da2bb6..a4badc92 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.27 2003-09-08 18:21:19 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.28 2003-09-24 19:36:14 qbix79 Exp $ */ #include @@ -60,6 +60,7 @@ void DOS_Shell::DoCommand(char * line) { while (*line) { if (*line==32) break; if (*line=='/') break; + if (*line=='\t') break; if ((*line=='.') ||(*line =='\\')) { //allow stuff like cd.. and dir.exe cd\kees *cmd_write=0; Bit32u cmd_index=0; From e195ea341e5c8e08b9139dc43f846f0bdfcafe76 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 24 Sep 2003 19:37:14 +0000 Subject: [PATCH 1187/4131] added tab as valid character when reading a batchfile Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1267 --- src/shell/shell_batch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 2c256483..c927e889 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -49,7 +49,7 @@ emptyline: n=1; DOS_ReadFile(file_handle,&c,&n); if (n>0) { - if (c>31 || c==0x1b) + if (c>31 || c==0x1b || c=='\t') *cmd_write++=c; } } while (c!='\n' && n); From 1b31d7c8352d07811da995b3ad418498b95ac5bf Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 24 Sep 2003 19:46:36 +0000 Subject: [PATCH 1188/4131] changes fcom flags. applied changes from c2wood to the cvs (modified them to match) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1268 --- src/fpu/fpu_instructions.h | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 9ff1e54c..70df617a 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: fpu_instructions.h,v 1.12 2003-09-24 19:46:36 qbix79 Exp $ */ static void FPU_FINIT(void) { @@ -156,16 +157,16 @@ static void FPU_FST(Bitu st, Bitu other){ static void FPU_FCOM(Bitu st, Bitu other){ if((fpu.tags[st] != TAG_Valid) || (fpu.tags[other] != TAG_Valid)){ - FPU_SET_C3(1);FPU_SET_C2(1);FPU_SET_C1(1);FPU_SET_C0(1);return; + FPU_SET_C3(1);FPU_SET_C1(1);FPU_SET_C0(1);return; } if(fpu.regs[st].d == fpu.regs[other].d){ - FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C1(0);FPU_SET_C0(0);return; + FPU_SET_C3(1);FPU_SET_C1(0);FPU_SET_C0(0);return; } if(fpu.regs[st].d < fpu.regs[other].d){ - FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C1(0);FPU_SET_C0(1);return; + FPU_SET_C3(0);FPU_SET_C1(0);FPU_SET_C0(1);return; } // st > other - FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C1(0);FPU_SET_C0(0);return; + FPU_SET_C3(0);FPU_SET_C1(0);FPU_SET_C0(0);return; } static void FPU_FUCOM(Bitu st, Bitu other){ @@ -175,8 +176,10 @@ static void FPU_FUCOM(Bitu st, Bitu other){ static double FROUND(double in){ switch(fpu.round){ - case ROUND_Nearest: - return((in-floor(in)>=0.5)?(floor(in)+1):(floor(in))); + case ROUND_Nearest: + if (in-floor(in)>0.5) return (floor(in)+1); + else if (in-floor(in)<0.5) return (floor(in)); + else return (((static_cast(floor(in)))&1)!=0)?(floor(in)+1):(floor(in)); break; case ROUND_Down: return (floor(in)); @@ -197,9 +200,13 @@ static void FPU_FPREM(void){ Real64 valtop = fpu.regs[TOP].d; Real64 valdiv = fpu.regs[ST(1)].d; Real64 res = floor(valtop/valdiv); + Bit64s ressaved = static_cast(res); res=valtop - res*valdiv; fpu.regs[TOP].d = res; - FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C1(0);FPU_SET_C0(0); + FPU_SET_C3(static_cast(ressaved&4)); + FPU_SET_C2(static_cast(ressaved&2)); + FPU_SET_C1(static_cast(ressaved&1)); + FPU_SET_C0(0); } static void FPU_FXAM(void){ From 4f4eefda178416949d38a3b5d6c2d6757dd4db75 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 25 Sep 2003 19:30:23 +0000 Subject: [PATCH 1189/4131] Really clear the lower 4 bits Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1269 --- src/hardware/dma.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index d90ef803..7a35d16d 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -93,7 +93,7 @@ static Bit8u read_dma(Bit32u port) { break; case 0x08: /* Read Status */ ret=cont->status_reg; - cont->status_reg&=0xf; /* Clear lower 4 bits on read */ + cont->status_reg&=~0xf; /* Clear lower 4 bits on read */ break; case 0x0a: case 0x0e: From 6b72dfd2f0e7b6dbc4e5ab7e78679347264b791b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 25 Sep 2003 19:30:55 +0000 Subject: [PATCH 1190/4131] Fix signed/unsigned warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1270 --- src/hardware/mixer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index c9daeb2a..aeca9cce 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -230,7 +230,7 @@ static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { /* Copy data from out buffer to the stream */ Bitu size=MIXER_BUFSIZE+mixer.out.write-mixer.out.read; if (size>=MIXER_BUFSIZE) size-=MIXER_BUFSIZE; - if (size*MIXER_SSIZE Date: Mon, 29 Sep 2003 16:38:34 +0000 Subject: [PATCH 1191/4131] Fix bug in move memory region where it would copy from the wrong place Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1271 --- src/ints/ems.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 7cabca45..d9b75de0 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -419,7 +419,7 @@ static Bit8u MemoryRegion(void) { MEM_BlockWrite(dest_mem,buf_src,toread); } else { if (toread Date: Mon, 29 Sep 2003 19:33:11 +0000 Subject: [PATCH 1192/4131] rewrote message routines Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1272 --- src/cpu/cpu.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index c38e550f..a5fc0412 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -27,8 +27,8 @@ #include "paging.h" #if 1 -#undef LOG_MSG -#define LOG_MSG +#undef LOG +#define LOG(X,Y) #endif Flag_Info flags; @@ -189,7 +189,7 @@ bool Interrupt(Bitu num) { Segs.val[cs]=(selector&0xfffc) | cpu.cpl; Segs.phys[cs]=desc.GetBase(); cpu.code.big=desc.Big()>0; - LOG_MSG("INT:Gate to %X:%X big %d %s",selector,reg_eip,desc.Big(),gate.Type() & 0x8 ? "386" : "286"); + LOG(LOG_CPU,LOG_NORMAL)("INT:Gate to %X:%X big %d %s",selector,reg_eip,desc.Big(),gate.Type() & 0x8 ? "386" : "286"); reg_eip=offset; return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); } @@ -280,7 +280,7 @@ bool CPU_IRET(bool use32) { Segs.val[cs]=(selector & 0xfffc) | cpu.cpl;; reg_eip=offset; CPU_SetFlags(old_flags); - LOG_MSG("IRET:Same level return to %X:%X big %d",selector,offset,cpu.code.big); + LOG(LOG_CPU,LOG_NORMAL)("IRET:Same level return to %X:%X big %d",selector,offset,cpu.code.big); } else { /* Return to higher privilege */ switch (desc.Type()) { @@ -311,7 +311,7 @@ bool CPU_IRET(bool use32) { reg_esp=new_esp; CPU_SetSegGeneral(ss,new_ss); //TODO Maybe validate other segments, but why would anyone use them? - LOG_MSG("IRET:Outer level return to %X:X big %d",selector,offset,cpu.code.big); + LOG(LOG_CPU,LOG_NORMAL)("IRET:Outer level return to %X:X big %d",selector,offset,cpu.code.big); } return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); } @@ -338,11 +338,11 @@ bool CPU_JMP(bool use32,Bitu selector,Bitu offset) { if (rpl>cpu.cpl) E_Exit("JMP:NC:RPL>CPL"); if (rpl!=desc.DPL()) E_Exit("JMP:NC:RPL != DPL"); cpu.cpl=desc.DPL(); - LOG_MSG("JMP:Code:NC to %X:%X big %d",selector,offset,desc.Big()); + LOG(LOG_CPU,LOG_NORMAL)("JMP:Code:NC to %X:%X big %d",selector,offset,desc.Big()); goto CODE_jmp; case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: - LOG_MSG("JMP:Code:C to %X:%X big %d",selector,offset,desc.Big()); + LOG(LOG_CPU,LOG_NORMAL)("JMP:Code:C to %X:%X big %d",selector,offset,desc.Big()); CODE_jmp: /* Normal jump to another selector:offset */ Segs.phys[cs]=desc.GetBase(); @@ -384,12 +384,12 @@ bool CPU_CALL(bool use32,Bitu selector,Bitu offset) { case DESC_CODE_R_NC_A:case DESC_CODE_R_NC_NA: if (rpl>cpu.cpl) E_Exit("CALL:CODE:NC:RPL>CPL"); if (call.DPL()!=cpu.cpl) E_Exit("CALL:CODE:NC:DPL!=CPL"); - LOG_MSG("CALL:CODE:NC to %X:%X",selector,offset); + LOG(LOG_CPU,LOG_NORMAL)("CALL:CODE:NC to %X:%X",selector,offset); goto call_code; case DESC_CODE_N_C_A:case DESC_CODE_N_C_NA: case DESC_CODE_R_C_A:case DESC_CODE_R_C_NA: if (call.DPL()>cpu.cpl) E_Exit("CALL:CODE:C:DPL>CPL"); - LOG_MSG("CALL:CODE:C to %X:%X",selector,offset); + LOG(LOG_CPU,LOG_NORMAL)("CALL:CODE:C to %X:%X",selector,offset); call_code: if (!use32) { CPU_Push16(SegValue(cs)); @@ -467,13 +467,13 @@ RET_same_level: cpu.code.big=desc.Big()>0; Segs.val[cs]=selector; reg_eip=offset; - LOG_MSG("RET - Same level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL()); + LOG(LOG_CPU,LOG_NORMAL)("RET - Same level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL()); return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); } else { /* Return to higher level */ E_Exit("REturn to higher priviledge"); } - LOG_MSG("Prot ret %X:%X",selector,offset); + LOG(LOG_CPU,LOG_NORMAL)("Prot ret %X:%X",selector,offset); return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); } return false; @@ -487,7 +487,7 @@ void CPU_SLDT(Bitu & selector) { Bitu tr=0; void CPU_LLDT(Bitu selector) { cpu.gdt.LLDT(selector); - LOG_MSG("LDT Set to %X",selector); + LOG(LOG_CPU,LOG_NORMAL)("LDT Set to %X",selector); } void CPU_STR(Bitu & selector) { @@ -496,18 +496,18 @@ void CPU_STR(Bitu & selector) { void CPU_LTR(Bitu selector) { tr=selector; - LOG_MSG("TR Set to %X",selector); + LOG(LOG_CPU,LOG_NORMAL)("TR Set to %X",selector); } void CPU_LGDT(Bitu limit,Bitu base) { - LOG_MSG("GDT Set to base:%X limit:%X",base,limit); + LOG(LOG_CPU,LOG_NORMAL)("GDT Set to base:%X limit:%X",base,limit); cpu.gdt.SetLimit(limit); cpu.gdt.SetBase(base); } void CPU_LIDT(Bitu limit,Bitu base) { - LOG_MSG("IDT Set to base:%X limit:%X",base,limit); + LOG(LOG_CPU,LOG_NORMAL)("IDT Set to base:%X limit:%X",base,limit); cpu.idt.SetLimit(limit); cpu.idt.SetBase(base); } @@ -533,12 +533,12 @@ bool CPU_SET_CRX(Bitu cr,Bitu value) { //TODO Maybe always first change to core_full for a change to cr0 if (value & CR0_PROTECTION) { cpu.pmode=true; - LOG_MSG("Protected mode"); + LOG(LOG_CPU,LOG_NORMAL)("Protected mode"); PAGING_Enable((value & CR0_PAGING)>0); } else { cpu.pmode=false; PAGING_Enable(false); - LOG_MSG("Real mode"); + LOG(LOG_CPU,LOG_NORMAL)("Real mode"); } return false; //Only changes with next CS change } From e088330dea4acaf240d5bd82d731284e8dc14619 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 29 Sep 2003 19:35:23 +0000 Subject: [PATCH 1193/4131] version number update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1273 --- VERSION | 2 +- configure.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index f2c6f753..08072c18 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.58 +0.60 diff --git a/configure.in b/configure.in index d1bea377..305dc4c5 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Init. -AC_INIT(dosbox,0.58) +AC_INIT(dosbox,0.60) AC_PREREQ(2.50) AC_CONFIG_SRCDIR(README) From d079c8388ad2352e57a308adb54d2133ae51a5d0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 29 Sep 2003 21:05:59 +0000 Subject: [PATCH 1194/4131] Added title support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1274 --- src/cpu/cpu.cpp | 6 +++++- src/gui/render.cpp | 6 ++++++ src/gui/sdlmain.cpp | 15 ++++++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index a5fc0412..630b3d31 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: cpu.cpp,v 1.33 2003-09-29 21:05:59 qbix79 Exp $ */ #include #include "dosbox.h" @@ -828,12 +829,14 @@ void CPU_HLT(void) { } +extern void GFX_SetTitle(Bits cycles ,Bits frameskip); static void CPU_CycleIncrease(void) { Bits old_cycles=CPU_CycleMax; CPU_CycleMax=(Bits)(CPU_CycleMax*1.2); CPU_CycleLeft=0;CPU_Cycles=0; if (CPU_CycleMax==old_cycles) CPU_CycleMax++; LOG_MSG("CPU:%d cycles",CPU_CycleMax); + GFX_SetTitle(CPU_CycleMax,-1); } static void CPU_CycleDecrease(void) { @@ -841,6 +844,7 @@ static void CPU_CycleDecrease(void) { CPU_CycleLeft=0;CPU_Cycles=0; if (!CPU_CycleMax) CPU_CycleMax=1; LOG_MSG("CPU:%d cycles",CPU_CycleMax); + GFX_SetTitle(CPU_CycleMax,-1); } @@ -881,7 +885,7 @@ void CPU_Init(Section* sec) { CPU_CycleMax=section->Get_int("cycles");; if (!CPU_CycleMax) CPU_CycleMax=1500; CPU_CycleLeft=0; - + GFX_SetTitle(CPU_CycleMax,-1); MSG_Add("CPU_CONFIGFILE_HELP","The amount of cycles to execute each loop. Lowering this setting will slowdown dosbox\n"); } diff --git a/src/gui/render.cpp b/src/gui/render.cpp index bf65ece0..568c7118 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: render.cpp,v 1.16 2003-09-29 21:05:05 qbix79 Exp $ */ + #include #include @@ -357,14 +359,17 @@ normalop: GFX_Start(); } +extern void GFX_SetTitle(Bits cycles, Bits frameskip); static void IncreaseFrameSkip(void) { if (render.frameskip.max<10) render.frameskip.max++; LOG_MSG("Frame Skip at %d",render.frameskip.max); + GFX_SetTitle(-1,render.frameskip.max); } static void DecreaseFrameSkip(void) { if (render.frameskip.max>0) render.frameskip.max--; LOG_MSG("Frame Skip at %d",render.frameskip.max); + GFX_SetTitle(-1,render.frameskip.max); } void RENDER_Init(Section * sec) { @@ -394,5 +399,6 @@ void RENDER_Init(Section * sec) { } KEYBOARD_AddEvent(KBD_f7,KBD_MOD_CTRL,DecreaseFrameSkip); KEYBOARD_AddEvent(KBD_f8,KBD_MOD_CTRL,IncreaseFrameSkip); + GFX_SetTitle(-1,render.frameskip.max); } diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 117b8def..2399dd5a 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -15,6 +15,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* $Id: sdlmain.cpp,v 1.43 2003-09-29 21:04:31 qbix79 Exp $ */ + #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif @@ -78,6 +81,16 @@ struct SDL_Block { static SDL_Block sdl; static void CaptureMouse(void); +void GFX_SetTitle(Bits cycles,Bits frameskip){ + char title[200]={0}; + static internal_cycles=0; + static internal_frameskip=0; + if(cycles != -1) internal_cycles = cycles; + if(frameskip != -1) internal_frameskip = frameskip; + sprintf(title,"Cpu Cycles: %8d, Frameskip %2d",internal_cycles,internal_frameskip); + SDL_WM_SetCaption(title,VERSION); +} + /* Reset the screen with current values in the sdl structure */ static void ResetScreen(void) { GFX_Stop(); @@ -102,7 +115,7 @@ static void ResetScreen(void) { ); - SDL_WM_SetCaption(VERSION,VERSION); + GFX_SetTitle(-1,-1); Bitu flags=MODE_SET; if (sdl.full_screen) flags|=MODE_FULLSCREEN; From 4280d1cef5ce9c491131520c2b669db6f3df400a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 29 Sep 2003 21:06:49 +0000 Subject: [PATCH 1195/4131] Disabled zeroing of int f handler. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1275 --- src/cpu/callback.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 79e12ab5..1b553fba 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: callback.cpp,v 1.16 2003-09-29 21:06:49 qbix79 Exp $ */ + #include #include @@ -204,7 +206,7 @@ void CALLBACK_Init(Section* sec) { real_writed(0,i*4,CALLBACK_RealPointer(call_default)); } real_writed(0,0x67*4,CALLBACK_RealPointer(call_default)); - real_writed(0,0xf*4,0); + //real_writed(0,0xf*4,0); some games don't like it } From 85f59175f690a0beaf71c1cc0bdb0cbb99f34d9d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 29 Sep 2003 21:10:59 +0000 Subject: [PATCH 1196/4131] version number update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1276 --- src/platform/visualc/config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index b0f14bd6..f05615f0 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -1,9 +1,9 @@ #define INLINE __forceinline -#define VERSION "0.58" +#define VERSION "0.60" /* Define to 1 to enable internal debugger, requires libcurses */ -#define C_DEBUG 1 +#define C_DEBUG 0 /* Define to 1 to enable screenshots, requires libpng */ #define C_SSHOT 1 From f03d9708888ee8c0cecbb7eaa1c4ad5ca41194ab Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 29 Sep 2003 21:22:01 +0000 Subject: [PATCH 1197/4131] Added Version number to the Title. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1277 --- src/gui/sdlmain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 2399dd5a..1db8bb19 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.43 2003-09-29 21:04:31 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.44 2003-09-29 21:22:01 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -87,7 +87,7 @@ void GFX_SetTitle(Bits cycles,Bits frameskip){ static internal_frameskip=0; if(cycles != -1) internal_cycles = cycles; if(frameskip != -1) internal_frameskip = frameskip; - sprintf(title,"Cpu Cycles: %8d, Frameskip %2d",internal_cycles,internal_frameskip); + sprintf(title,"DOSBox %s, Cpu Cycles: %8d, Frameskip %2d",VERSION,internal_cycles,internal_frameskip); SDL_WM_SetCaption(title,VERSION); } From 3585764f19adcb6dae13de8accf31d5532af8f43 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Sep 2003 08:56:52 +0000 Subject: [PATCH 1198/4131] Inadvertly changed the the ready state to 0x0 instead of 0xff Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1278 --- src/dos/dos_ioctl.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 4bd7fcd6..73ff3205 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.12 2003-07-27 12:12:05 qbix79 Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.13 2003-09-30 08:56:52 qbix79 Exp $ */ #include #include "dosbox.h" @@ -44,17 +44,17 @@ bool DOS_IOCTL(void) { return true; case 0x06: /* Get Input Status */ if (Files[handle]->GetInformation() & 0x8000) { //Check for device - reg_al=(Files[handle]->GetInformation() & 0x40) ? 0xff : 0; + reg_al=(Files[handle]->GetInformation() & 0x40) ? 0x0 : 0xff; } else { // FILE Bit32u oldlocation=0; Files[handle]->Seek(&oldlocation, DOS_SEEK_CUR); Bit32u endlocation=0; Files[handle]->Seek(&endlocation, DOS_SEEK_END); if(oldlocation < endlocation){//Still data available - reg_al=0x0; + reg_al=0xff; } else { - reg_al=0xff; //EOF or beyond + reg_al=0x0; //EOF or beyond } Files[handle]->Seek(&oldlocation, DOS_SEEK_SET); //restore filelocation LOG(LOG_IOCTL,LOG_NORMAL)("06:Used Get Input Status on regualar file with handle %d",handle); From 74686ee39ae867339888459597dc67d9b6f76fd6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Sep 2003 08:58:10 +0000 Subject: [PATCH 1199/4131] Turn Write_heavylog instruction off if C_DEBUG is not defined Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1279 --- src/misc/support.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 2d087870..54e5e228 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.18 2003-08-19 17:59:25 qbix79 Exp $ */ +/* $Id: support.cpp,v 1.19 2003-09-30 08:58:10 qbix79 Exp $ */ #include #include @@ -159,8 +159,10 @@ char * StripWord(char * cmd) { static char buf[1024]; //greater scope as else it doesn't always gets thrown right (linux/gcc2.95) void E_Exit(char * format,...) { +#if C_DEBUG #if C_HEAVY_DEBUG DEBUG_HeavyWriteLogInstruction(); +#endif #endif if(errorlevel>=1) { va_list msg; From 4114c37e3e4062cd8e82aeeba2fb807ce10fc26e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Sep 2003 08:59:18 +0000 Subject: [PATCH 1200/4131] Added type info to some variables (ISO C++ violations) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1280 --- src/gui/sdlmain.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 1db8bb19..8a03f647 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.44 2003-09-29 21:22:01 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.45 2003-09-30 08:59:18 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -83,8 +83,8 @@ static void CaptureMouse(void); void GFX_SetTitle(Bits cycles,Bits frameskip){ char title[200]={0}; - static internal_cycles=0; - static internal_frameskip=0; + static Bits internal_cycles=0; + static Bits internal_frameskip=0; if(cycles != -1) internal_cycles = cycles; if(frameskip != -1) internal_frameskip = frameskip; sprintf(title,"DOSBox %s, Cpu Cycles: %8d, Frameskip %2d",VERSION,internal_cycles,internal_frameskip); From a031928dcbbaa4c36214ebd07225457fbf7dbf7f Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 30 Sep 2003 13:48:20 +0000 Subject: [PATCH 1201/4131] Added 286-Callgates and return to higher privilege Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1281 --- src/cpu/cpu.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 630b3d31..f72090f2 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.33 2003-09-29 21:05:59 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.34 2003-09-30 13:48:20 finsterr Exp $ */ #include #include "dosbox.h" @@ -101,6 +101,7 @@ bool CPU_CheckCodeType(CODE_TYPE type) { switch (cpu.code.type) { case CODE_REAL: realcore_start(false); + cpu.code.big = false; break; case CODE_PMODE16: pmodecore_start(false); @@ -406,6 +407,71 @@ call_code: Segs.val[cs]=(selector & 0xfffc) | cpu.cpl; reg_eip=offset; return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); + case DESC_286_CALL_GATE: { + if (call.DPL()0; + reg_eip = neweip; + // Set CPL to stack segment DPL + // Set RPL of CS to CPL + cpu.cpl = newcpl; + Segs.val[cs] = (newcs & 0xfffc) | newcpl; + // 4. Load SS descriptor + // 5. Push long pointer of old stack onto new stack + Bitu oldsp = reg_sp; + CPU_Push16(SegValue(ss)); + CPU_Push16(oldsp); + // 6. Get word count from call gate, mask to 5 bits + Bitu wordCount = call.saved.gate.paramcount; + if (wordCount>0) LOG(LOG_CPU,LOG_NORMAL)("CPU: Callgate 286 wordcount : %d)",wordCount); + // 7. Copy parameters from old stack onto new stack + while (wordCount>0) { + CPU_Push16(mem_readw(SegPhys(ss)+oldsp)); + oldsp += 2; wordCount--; + } + // Push return address onto new stack + CPU_Push16(oldcs); + CPU_Push16(oldip); +// LOG(LOG_MISC,LOG_ERROR)("CPU: Callgate (Higher) %04X:%04X",newcs,neweip); + return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); + } else { + // same privilidge level + Bitu oldcs = SegValue(cs); + Bitu oldip = reg_ip; + Bitu newcs = call.GetSelector() | 3; + Bitu neweip = call.GetOffset(); + // 3. Load CS descriptor (Set RPL of CS to CPL) + Descriptor code2; + if (!cpu.gdt.GetDescriptor(newcs,code2)) E_Exit("286 Call Gate: Invalid code segment."); + Segs.phys[cs] = code.GetBase(); + cpu.code.big = code.Big()>0; + // Set RPL of CS to CPL + cpu.cpl = seldpl; + Segs.val[cs] = (newcs & 0xfffc) | seldpl; + reg_eip = neweip; + // Push return address onto new stack + CPU_Push16(oldcs); + CPU_Push16(oldip); +// LOG(LOG_MISC,LOG_ERROR)("CPU: Callgate (Same) %04X:%04X",newcs,neweip); + return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); + }; break; + }; default: E_Exit("CALL:Descriptor type %x unsupported",call.Type()); @@ -472,7 +538,17 @@ RET_same_level: return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); } else { /* Return to higher level */ - E_Exit("REturn to higher priviledge"); + Bitu newsp = CPU_Pop16(); + Bitu newss = CPU_Pop16(); + cpu.cpl = rpl; + CPU_SetSegGeneral(ss,newss); + reg_esp = newsp; + Segs.phys[cs]=desc.GetBase(); + cpu.code.big=desc.Big()>0; + Segs.val[cs]=selector; + reg_eip=offset; +// LOG(LOG_MISC,LOG_ERROR)("RET - Higher level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL()); + return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); } LOG(LOG_CPU,LOG_NORMAL)("Prot ret %X:%X",selector,offset); return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); From ffe68640216ef82ac578a71fd3bbe55c6b588a12 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 30 Sep 2003 13:49:34 +0000 Subject: [PATCH 1202/4131] Added int 15 87 - Move memory region Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1282 --- src/ints/bios.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index d04a0e6c..63b65afd 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.21 2003-09-17 19:17:35 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.22 2003-09-30 13:49:34 finsterr Exp $ */ #include #include "dosbox.h" @@ -228,11 +228,26 @@ static Bitu INT15_Handler(void) { Bit32u micro=(reg_cx<<16)|reg_dx; CALLBACK_SCF(false); } + case 0x87: /* Copy extended memory */ + { + bool enabled = MEM_A20_Enabled(); + MEM_A20_Enable(true); + Bitu bytes = reg_cx * 2; + PhysPt data = SegPhys(es)+reg_si; + PhysPt source = mem_readd(data+0x12) & 0x00FFFFFF + (mem_readb(data+0x16)<<24); + PhysPt dest = mem_readd(data+0x1A) & 0x00FFFFFF + (mem_readb(data+0x1E)<<24); + MEM_BlockCopy(dest,source,bytes); + reg_ax = 0x00; + MEM_A20_Enable(enabled); + CALLBACK_SCF(false); + break; + } case 0x88: /* SYSTEM - GET EXTENDED MEMORY SIZE (286+) */ IO_Write(0x70,0x30); reg_al=IO_Read(0x71); IO_Write(0x70,0x31); reg_ah=IO_Read(0x71); + LOG(LOG_BIOS,LOG_NORMAL)("INT15:Function 0x88 Remaining %04X kb",reg_ax); CALLBACK_SCF(false); break; case 0x90: /* OS HOOK - DEVICE BUSY */ @@ -253,7 +268,7 @@ static Bitu INT15_Handler(void) { CALLBACK_SCF(true); break; default: - LOG(LOG_BIOS,LOG_ERROR)("INT15:Unknown call %2X",reg_ah); + LOG(LOG_BIOS,LOG_ERROR)("INT15:Unknown call %4X",reg_ax); reg_ah=0x86; CALLBACK_SCF(false); } From 319c12c235b4acde79d8324b13e71f9cf7a4bba9 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 30 Sep 2003 13:50:21 +0000 Subject: [PATCH 1203/4131] added some special stuff for pharlap/msdos api Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1283 --- src/ints/dpmi.cpp | 483 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 358 insertions(+), 125 deletions(-) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index cf94c483..1f6f8696 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -16,8 +16,18 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +// Pharlap Special Infos: +// - Dont hook hardware ints +// - CMOS Memory Size has to return 0 otherwise it tries to map physical memory +// - Set PM Int Vector : Use it on current idt, not only dpmi one (ultima 8 mouse check fails otherwise) +// - Ultima 8 wants 40 Files (Hack in PSP::SetNumFiles +// - Ultima 8 and Bioforge work with DPL 3 +// - Crusaders 1+2 seem to need DPL 0, which is bad... +// - Bioforge uses more than 2048 descriptos in ldt (4096) + #include #include +#include #include "dosbox.h" #include "dos_inc.h" #include "callback.h" @@ -28,12 +38,13 @@ #include "inout.h" #include "cpu.h" +#include "debug.h" + //#define DPMI_LOG LOG(LOG_MISC,LOG_ERROR) #define DPMI_LOG #define DPMI_LOG_ERROR LOG(LOG_MISC,LOG_ERROR) -//#define DPMI_LOG_ERROR - +//#define DPMI_LOG_ERROR #define DPMI_ALLOC_NEEDEDMEM_HIGH 1 @@ -46,13 +57,12 @@ #define GDT_DOSDATA ((0x4 << 3) | DPMI_DPL) #define GDT_ENVIRONMENT ((0x5 << 3) | DPMI_DPL) -// TEMP #define GDT_DOSSEG40 (0x40) /* Amount of descriptors in each table */ #define GDT_SIZE 32 #define IDT_SIZE 256 -#define LDT_SIZE 2048 +#define LDT_SIZE 4096 #define INT_SIZE 256 #define TOTAL_SIZE ((GDT_SIZE+IDT_SIZE+LDT_SIZE+INT_SIZE)*8) @@ -90,7 +100,9 @@ #define DPMI_CB_EXCEPTIONRETURN_OFFSET 260*8 #define DPMI_CB_VENDORENTRY_OFFSET 261*8 -#define DPMI_HOOK_HARDWARE_INTS 1 +static bool g_hookHardwareInts = true; + +void CMOS_SetRegister(Bitu regNr, Bit8u val); static Bitu rmIndexToInt[DPMI_REALVEC_MAX] = { 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x1C }; @@ -98,9 +110,11 @@ static Bitu rmIndexToInt[DPMI_REALVEC_MAX] = // General functions void CALLBACK32_SCF(bool val) { - Bit32u tempf=mem_readd(SegPhys(ss)+reg_esp+8) & 0xFFFFFFFE; + Bitu v_esp = 0; + if (cpu.stack.big) v_esp = reg_esp; else v_esp = reg_sp; + Bit32u tempf=mem_readd(SegPhys(ss)+v_esp+8) & 0xFFFFFFFE; Bit32u newCF=(val==true); - mem_writed(SegPhys(ss)+reg_esp+8,(tempf | newCF)); + mem_writed(SegPhys(ss)+v_esp+8,(tempf | newCF)); }; #define DPMI_CALLBACK_SCF(b) if (dpmi.client.bit32) CALLBACK32_SCF(b); else CALLBACK_SCF(b) @@ -255,12 +269,17 @@ public: bool RemoveSharedMem (Bitu handle); // special msdos api stuff + void SetupPharlapSelectors (void); + bool Pharlap_AllocateMem (Bitu size, Bitu& outHandle, Bitu& linear); Bitu GetSegmentFromSelector (Bitu selector); bool GetMsdosSelector (Bitu realseg, Bitu realoff, Bitu &protsel, Bitu &protoff); void API_Init_MSDOS (void); Bitu API_Entry_MSDOS (void); Bitu API_Int21_MSDOS (void); + // debug + void Debug_ShowDescriptors (void); + private: Bitu Mask (Bitu value); @@ -309,10 +328,15 @@ private: bool pharlap; bool suppressRMCB; + + // Pharlap stuff + Bitu initialcs,initialds; + Bitu initialenv; } dpmi; Bit32u* modIntTable; DPMI* prevDPMI; + std::vector dosSelectorList; Bitu dtaAddress; Bitu save_cs[2],save_ds[2],save_es[2],save_fs[2],save_gs[2],save_ss[2]; @@ -383,9 +407,12 @@ DPMI::DPMI(void) DPMI::~DPMI(void) { MEM_ReleasePages(dpmi.mem_handle); + dosSelectorList.clear(); // TODO: Free all memory allocated with DOS_GetMemory // Activate previous dpmi activeDPMI = prevDPMI; + // Restore hookHardwareInts ability which may be changed by a pharlap program + if (!activeDPMI) g_hookHardwareInts = true; }; void DPMI::ClearXMSHandles(void) @@ -811,6 +838,7 @@ Bitu DPMI::RealModeCallback(void) CPU_SetSegGeneral(cs,GDT_CODE); reg_eip = RealOff(CALLBACK_RealPointer(callback.rmCallbackReturn)); // call protected mode func + SetVirtualIntFlag(false); SETFLAGBIT(IF,false); SETFLAGBIT(TF,false); CPU_Push32(flags.word); @@ -837,6 +865,7 @@ Bitu DPMI::RealModeCallbackReturn(void) Bitu newCS = mem_readw(data+0x2C); Bitu newIP = mem_readw(data+0x2A); UpdateRealModeStack(); + SetVirtualIntFlag(true); DPMI_LOG("DPMI: CB: Retored cs:ip = %04X:%04X (%d)",newCS,newIP); CPU_JMP(false,newCS,newIP); return 0; @@ -870,6 +899,7 @@ Bitu DPMI::CallRealIRETFrame(void) // Setup cs:ip to return to DPMI_CallRealIRETFrame callback SegSet16(cs,RealSeg(CALLBACK_RealPointer(callback.rmIntFrameReturn))); reg_ip = RealOff(CALLBACK_RealPointer(callback.rmIntFrameReturn)); + SetVirtualIntFlag(false); SETFLAGBIT(IF,false); SETFLAGBIT(TF,false); CPU_CALL(false,newCS,newIP); @@ -891,6 +921,7 @@ Bitu DPMI::CallRealIRETFrameReturn(void) CPU_JMP(dpmi.client.bit32,newcs,reg_eip); + SetVirtualIntFlag(true); DPMI_CALLBACK_SCF(false); return 0; }; @@ -898,10 +929,6 @@ Bitu DPMI::CallRealIRETFrameReturn(void) Bitu DPMI::SimulateInt(void) { Bitu num = reg_bl; - // TEMP - if (num==0x5C) { - int brk = 0; - } DPMI_LOG("DPMI: SIM INT %02X %04X called. cs = %04X",num,reg_ax,SegValue(cs)); // Save changed registers PushStack(SegValue(cs)); @@ -943,6 +970,7 @@ Bitu DPMI::SimulateIntReturn(void) Bitu newcs = PopStack(); DPMI_LOG("DPMI: SimIntRet: JUMP to %04X:%08X",newcs,reg_eip); CPU_JMP(dpmi.client.bit32,newcs,reg_eip); + SetVirtualIntFlag(true); // Free last realmode stack DPMI_CALLBACK_SCF(false); DPMI_LOG("DPMI: SimIntRet2: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_esp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); @@ -974,10 +1002,10 @@ Bitu DPMI::ptorHandler(void) { /* Pmode interrupt handler that maps the interrupt to realmode */ Bitu num = reg_eip >> 3; - if (!dpmi.vIntFlag) { - if ((num>=0x08) && (num<=0x0F)) return 0; - if ((num>=0x70) && (num<=0x77)) return 0; - }; +// if (!dpmi.vIntFlag) { +// if ((num>=0x08) && (num<=0x0F)) return 0; +// if ((num>=0x70) && (num<=0x77)) return 0; +// }; PrepareReflectToReal(num); // if (num==0x0F) DPMI_LOG("DPMI: INT %02X %04X called.",num,reg_ax); @@ -1003,6 +1031,7 @@ Bitu DPMI::ptorHandlerReturn(void) DPMI_LOG("DPMI: INT %02X RETURN",num); // hardware ints exit here if (((num>=0x08) && (num<=0x0F)) || ((num>=0x70) && (num<=0x77))) { + SetVirtualIntFlag(true); CPU_JMP(dpmi.client.bit32,newcs,reg_eip); return 0; } @@ -1016,6 +1045,7 @@ Bitu DPMI::ptorHandlerReturn(void) Bit16u userFlags = flags.word & FLAG_MASK; // Mask out illegal flags not to change by int (0011111011010101b) mem_writew(SegPhys(ss)+reg_sp+4,oldFlags|userFlags); }; + SetVirtualIntFlag(true); CPU_JMP(dpmi.client.bit32,newcs,reg_eip); return 0; } @@ -1067,6 +1097,7 @@ Bitu DPMI::Int21HandlerReturn(void) // Set carry flag DPMI_CALLBACK_SCF(flags.word & 1); DPMI_LOG("DPMI: INT 21 RETURN"); + SetVirtualIntFlag(true); CPU_JMP(dpmi.client.bit32,newcs,reg_eip); return 0; } @@ -1090,6 +1121,7 @@ Bitu DPMI::HWIntDefaultHandler() dpmi.rmCallback[index].stop = false; PrepareReflectToReal(num); CPU_Push16(flags.word); + SetVirtualIntFlag(false); SETFLAGBIT(IF,false); SETFLAGBIT(TF,false); CPU_CALL(false,RealSeg(dpmi.oldRealVec[index]),RealOff(dpmi.oldRealVec[index])); @@ -1110,6 +1142,7 @@ Bitu DPMI::HWIntDefaultHandler() } }; PrepareReflectToReal(num); + SetVirtualIntFlag(false); SETFLAGBIT(IF,false); SETFLAGBIT(TF,false); CPU_Push16(flags.word); @@ -1123,6 +1156,7 @@ Bitu DPMI::HWIntDefaultHandler() dpmi.rmCallback[index].stop = false; PrepareReflectToReal(num); CPU_Push16(flags.word); + SetVirtualIntFlag(false); SETFLAGBIT(IF,false); SETFLAGBIT(TF,false); CPU_CALL(false,RealSeg(dpmi.oldRealVec[index]),RealOff(dpmi.oldRealVec[index])); @@ -1139,6 +1173,7 @@ Bitu DPMI::HWIntDefaultHandler() // kein spezieller Protmode handler - Rufe originalroutine auf PrepareReflectToReal(num); CPU_Push16(flags.word); + SetVirtualIntFlag(false); SETFLAGBIT(IF,false); SETFLAGBIT(TF,false); CPU_CALL(false,RealSeg(dpmi.oldRealVec[index]),RealOff(dpmi.oldRealVec[index])); @@ -1151,6 +1186,7 @@ Bitu DPMI::HWIntDefaultHandler() void DPMI::SaveRegisterState(Bitu num) // Copy Current Registers to structure { + return; save_cs[num] = SegValue(cs); save_ds[num] = SegValue(ds); save_es[num] = SegValue(es); @@ -1172,6 +1208,7 @@ void DPMI::SaveRegisterState(Bitu num) void DPMI::LoadRegisterState(Bitu num) // Copy Current Registers to structure { + return; CPU_SetSegGeneral(fs,save_fs[num]); CPU_SetSegGeneral(gs,save_gs[num]); reg_eax = save_eax[num]; @@ -1342,7 +1379,7 @@ bool DPMI::GetVirtualIntFlag(void) void DPMI::SetVirtualIntFlag(bool on) { - dpmi.vIntFlag = on; + dpmi.vIntFlag = 1; //on; }; bool DPMI::AllocateMem(Bitu size, Bitu& outHandle, Bitu& linear) @@ -1359,7 +1396,7 @@ bool DPMI::SetAccessRights(Bitu selector, SetDescriptor& desc, Bitu rights) // must equal caller DPL if (((rights & 0x60)>>5)!=DPMI_DPL) { DPMI_LOG("DPMI: Set Rights %04X : %04X failure (dpl=%02X)",selector,rights,(rights & 0x60)>>5); - return false; +// return false; } // must be 1 if ((rights & 0x10)==0) { @@ -1374,7 +1411,7 @@ bool DPMI::SetAccessRights(Bitu selector, SetDescriptor& desc, Bitu rights) // all tests passed, set rights for 16 + 32 Bit desc.SetType (rights&0x1F); desc.saved.seg.dpl = (rights&0x60)>>5; -// desc.saved.seg.dpl = DPMI_DPL; + desc.saved.seg.dpl = DPMI_DPL; desc.saved.seg.p = (rights&0x80)>0; // extended rights for 32 Bit apps if (dpmi.client.bit32) { @@ -1527,7 +1564,7 @@ Bitu DPMI::Int31Handler(void) case 0x000B:{//Get Descriptor SetDescriptor desc; if (cpu.gdt.GetDescriptor(reg_bx,desc)) { - desc.Save(SegPhys(es)+reg_edi); + desc.Save(SegPhys(es)+Mask(reg_edi)); DPMI_CALLBACK_SCF(false); DPMI_LOG("DPMI: 000B: Get Descriptor %04X : B:%08X L:%08X",reg_bx,desc.GetBase(),desc.GetLimit()); } else { @@ -1539,8 +1576,8 @@ Bitu DPMI::Int31Handler(void) case 0x000C:{//Set Descriptor SetDescriptor desc; if (cpu.gdt.GetDescriptor(reg_bx,desc)) { - desc.Load (SegPhys(es)+reg_edi); - Bitu rights = (mem_readb(SegPhys(es)+reg_edi+6)<<8) + mem_readb(SegPhys(es)+reg_edi+5); + desc.Load (SegPhys(es)+Mask(reg_edi)); + Bitu rights = (mem_readb(SegPhys(es)+Mask(reg_edi)+6)<<8) + mem_readb(SegPhys(es)+Mask(reg_edi)+5); if (!SetAccessRights(reg_bx,desc,rights)) { DPMI_LOG_ERROR("DPMI: 000C: Set Rights %04X : failure",reg_bx); reg_ax = DPMI_ERROR_INVALID_VALUE; @@ -1561,17 +1598,17 @@ Bitu DPMI::Int31Handler(void) DPMI_LOG("DPMI: 000D: Alloc Specific LDT Selector: %04X",reg_bx); SetDescriptor desc; if (cpu.gdt.GetDescriptor(reg_bx,desc)) { - if (!desc.saved.seg.p) { +// if (!desc.saved.seg.p) { desc.saved.seg.p = 1; - desc.SetLimit(0); - desc.SetBase (0); +// desc.SetLimit(0xDEADAAAA); +// desc.SetBase (0xDEADBBBB); desc.Save (dpmi.ldt.base+(reg_bx & ~7)); DPMI_CALLBACK_SCF(false); break; - } else { - DPMI_LOG_ERROR("DPMI: 000D: Invalid Selector: %04X",reg_bx); - reg_ax = DPMI_ERROR_DESCRIPTOR_UNAVAILABLE; - }; +// } else { +// DPMI_LOG_ERROR("DPMI: 000D: Invalid Selector: %04X",reg_bx); +// reg_ax = DPMI_ERROR_DESCRIPTOR_UNAVAILABLE; +// }; } else reg_ax = DPMI_ERROR_INVALID_SELECTOR; DPMI_CALLBACK_SCF(true); }; break; @@ -1662,7 +1699,8 @@ Bitu DPMI::Int31Handler(void) case 0x0202:// Get Processor Exception Handler Vector if (reg_bl>16; reg_di = handle&0xFFFF; reg_bx = linear>>16; reg_cx = linear&0xFFFF; DPMI_CALLBACK_SCF(false); // TEMP - Bitu total = MEM_FreeLargest(); // in KB - DPMI_LOG("DPMI: 0501: Allocation success: H:%04X%04X (%d KB) (R:%d KB)",reg_si,reg_di,length/1024 + ((length%1024)>0),total*4); +// Bitu total = MEM_FreeLargest(); // in KB +// DPMI_LOG_ERROR("DPMI: 0501: Allocation success: H:%04X%04X (%d KB) (R:%d KB)",reg_si,reg_di,length/1024 + ((length%1024)>0),total*4); } else { reg_ax = DPMI_ERROR_PHYSICAL_MEMORY_UNAVAILABLE; DPMI_CALLBACK_SCF(true); // TEMP Bitu total = MEM_FreeLargest(); // in KB - DPMI_LOG_ERROR("DPMI: 0501: Allocation failure (%d KB) (R:%d KB)",length/1024 + ((length%1024)>0),total*4); + DPMI_LOG("DPMI: 0501: Allocation failure (%d KB) (R:%d KB)",length/1024 + ((length%1024)>0),total*4); }; }; break; case 0x0502://Free Memory Block @@ -1827,7 +1883,7 @@ Bitu DPMI::Int31Handler(void) Bitu newByte = (reg_bx<<16)+reg_cx; Bitu newSize = (newByte/DPMI_PAGE_SIZE)+((newByte & (DPMI_PAGE_SIZE-1))>0); MemHandle handle = (reg_si<<16)+reg_di; - DPMI_LOG_ERROR("DPMI: 0503: Resize Memory: H:%08X (%d KB)",handle,newSize*4); + DPMI_LOG("DPMI: 0503: Resize Memory: H:%08X (%d KB)",handle,newSize*4); if (MEM_ReAllocatePages(handle,newSize,true)) { linear = handle * DPMI_PAGE_SIZE; reg_si = handle>>16; @@ -1837,7 +1893,7 @@ Bitu DPMI::Int31Handler(void) DPMI_CALLBACK_SCF(false); } else if (AllocateMem(newByte,newHandle,linear)) { // Not possible, try to allocate - DPMI_LOG_ERROR("DPMI: 0503: Reallocated Memory: %d KB",newSize*4); + DPMI_LOG("DPMI: 0503: Reallocated Memory: %d KB",newSize*4); reg_si = newHandle>>16; reg_di = newHandle&0xFFFF; reg_bx = linear>>16; @@ -1866,11 +1922,11 @@ Bitu DPMI::Int31Handler(void) DPMI_CALLBACK_SCF(false); break; case 0x0509:{//Map Conventional Memory in Memory Block - Bitu xmsAddress = reg_esi*DPMI_PAGE_SIZE; - Bitu handle = reg_esi; - Bitu offset = reg_ebx; - Bitu numPages = reg_ecx; - Bitu linearAdr = reg_edx; + Bitu xmsAddress = Mask(reg_esi)*DPMI_PAGE_SIZE; + Bitu handle = Mask(reg_esi); + Bitu offset = Mask(reg_ebx); + Bitu numPages = Mask(reg_ecx); + Bitu linearAdr = Mask(reg_edx); if ((linearAdr & 3) || ((xmsAddress+offset) & 3)) { // Not page aligned DPMI_LOG_ERROR("DPMI: Cannot map conventional memory (address not page aligned)."); @@ -1919,12 +1975,13 @@ Bitu DPMI::Int31Handler(void) case 0x0800:{//Physical Address Mapping // bx and cx remain the same linear address = physical address Bitu phys = (reg_bx<<16) + reg_cx; + Bitu linear = (reg_bx<<16) + reg_cx; Bitu size = (reg_si<<16) + reg_di; - MEM_MapPagesDirect(phys/DPMI_PAGE_SIZE,phys/DPMI_PAGE_SIZE,size/DPMI_PAGE_SIZE); - Bitu linear = phys; + MEM_MapPagesDirect(linear/DPMI_PAGE_SIZE,phys/DPMI_PAGE_SIZE,size/DPMI_PAGE_SIZE); + //Bitu linear = phys; reg_bx = linear>>16; reg_cx = linear & 0xFFFF; - DPMI_LOG_ERROR("DPMI: 0800: Phys-adr-map not supported : %08X (%08X) - %08X.",phys,size,linear); + DPMI_LOG_ERROR("DPMI: 0800: Phys-adr-map not supported : Start:%08X (Size:%08X) - Linear:%08X.",phys,size,linear); DPMI_CALLBACK_SCF(false); }; break; case 0x0801:// Free physical address mapping @@ -1944,26 +2001,30 @@ Bitu DPMI::Int31Handler(void) DPMI_CALLBACK_SCF(false); break; case 0x0902:{//Get Virtual Interrupt State - reg_al = dpmi.vIntFlag; - reg_al = 0; // TEMP - DPMI_LOG("DPMI: 0900: Get vi : %01X",reg_al); + reg_al = 0; //dpmi.vIntFlag; + DPMI_LOG("DPMI: 0902: Get vi : %01X",reg_al); DPMI_CALLBACK_SCF(false); }; break; case 0x0A00:{//Get Vendor Specific API Entry Point char name[256]; - MEM_StrCopy(SegPhys(ds)+reg_esi,name,255); + MEM_StrCopy(SegPhys(ds)+Mask(reg_esi),name,255); LOG(LOG_MISC,LOG_WARN)("DPMI: Get API: %s",name); if (strcmp(name,"MS-DOS")==0) { CPU_SetSegGeneral(es,GDT_PROTCODE); - reg_edi = DPMI_CB_APIMSDOSENTRY_OFFSET; + if (dpmi.client.bit32) reg_edi = DPMI_CB_APIMSDOSENTRY_OFFSET; + else reg_di = DPMI_CB_APIMSDOSENTRY_OFFSET; API_Init_MSDOS(); DPMI_CALLBACK_SCF(false); -// } else if (strstr(name,"HWINT")!=0) { -// reg_ax = DPMI_ERROR_UNSUPPORTED; -// DPMI_CALLBACK_SCF(true); + } else if (strstr(name,"HWINT_SUPPORT")!=0) { + reg_ax = DPMI_ERROR_UNSUPPORTED; + DPMI_CALLBACK_SCF(true); + } else if (strstr(name,"CE_SUPPORT")!=0) { + reg_ax = DPMI_ERROR_UNSUPPORTED; + DPMI_CALLBACK_SCF(true); } else if (strstr(name,"PHARLAP")!=0) { CPU_SetSegGeneral(es,GDT_PROTCODE); - reg_edi = DPMI_CB_APIMSDOSENTRY_OFFSET; + if (dpmi.client.bit32) reg_edi = DPMI_CB_APIMSDOSENTRY_OFFSET; + else reg_di = DPMI_CB_APIMSDOSENTRY_OFFSET; API_Init_MSDOS(); DPMI_CALLBACK_SCF(false); dpmi.pharlap = true; @@ -1974,7 +2035,7 @@ Bitu DPMI::Int31Handler(void) }; break; case 0x0D00:{//Allocate Shared Memory char name[256]; - PhysPt data = SegPhys(es)+reg_edi; + PhysPt data = SegPhys(es)+Mask(reg_edi); Bitu length = mem_readd(data); Bitu pages = (length/DPMI_PAGE_SIZE)+((length%DPMI_PAGE_SIZE)>0); Bitu handle = mem_readd(data+0x08); @@ -2045,11 +2106,12 @@ Bitu DPMI::Int2fHandler(void) case 0x168A: // Only available in protected mode // Get Vendor-Specific API Entry Point char name[256]; - MEM_StrCopy(SegPhys(ds)+reg_esi,name,255); + MEM_StrCopy(SegPhys(ds)+Mask(reg_esi),name,255); LOG(LOG_MISC,LOG_WARN)("DPMI: 0x2F 0x168A: Get Specific API :%s",name); if (strcmp(name,"MS-DOS")==0) { CPU_SetSegGeneral(es,GDT_PROTCODE); - reg_edi = DPMI_CB_APIMSDOSENTRY_OFFSET; + if (dpmi.client.bit32) reg_edi = DPMI_CB_APIMSDOSENTRY_OFFSET; + else reg_di = DPMI_CB_APIMSDOSENTRY_OFFSET; reg_al = 0x00; // Success, whatever they want... API_Init_MSDOS(); }; @@ -2124,8 +2186,25 @@ void DPMI::RestoreHookedInterrupt(Bitu num, RealPt oldVec) gate.Save (dpmi.idt.base+num*8); } +void DPMI::Debug_ShowDescriptors(void) +{ + char out1[512]; + SetDescriptor desc; + Bitu i=0; + PhysPt address = dpmi.ldt.base; + while (i> 12); #if DPMI_ALLOC_NEEDEDMEM_HIGH - /* Allocate the GDT,LDT,IDT Stack space (High Mem) */ + // Allocate the GDT,LDT,IDT Stack space (High Mem) + Bitu max = MEM_FreeLargest(); + Bitu temphandle = MEM_AllocatePages(max-numPages,true); dpmi.mem_handle = MEM_AllocatePages(numPages,true); if (dpmi.mem_handle==0) { LOG_MSG("DPMI:Can't allocate XMS memory, disabling dpmi support."); return; } Bitu address = dpmi.mem_handle*DPMI_PAGE_SIZE;; + MEM_ReleasePages(temphandle); #else // load LDT and stuff in low mem ( Bit16u segment; @@ -2535,14 +2628,14 @@ void DPMI::Setup() code.saved.seg.big = 0; code.saved.seg.dpl = 0; code.Save (dpmi.gdt.base+(GDT_DOSSEG40 & ~7)); - -#if DPMI_HOOK_HARDWARE_INTS - // Setup Hardware Interrupt handler - for (i=0; i0); // Convert to 4KB pages + Bitu maxPages = MEM_FreeLargest(); + if (maxPages0xFFFF) { - E_Exit("DPMI:DOS: Read file size > 0xffff"); - }; + if (Mask(reg_ecx)>0xFFFF) E_Exit("DPMI:DOS: Read file size > 0xffff"); Bit16u toread = Mask(reg_ecx); dos.echo = true; if (DOS_ReadFile(reg_bx,dos_copybuf,&toread)) { MEM_BlockWrite(SegPhys(ds)+Mask(reg_edx),dos_copybuf,toread); - reg_eax=toread; + if (dpmi.client.bit32) reg_eax=toread; else reg_ax=toread; +// LOG(LOG_MISC,LOG_ERROR)("READ FILE Handle:%d Size:%d Read:%d",reg_bx,toread,reg_eax); DPMI_CALLBACK_SCF(false); } else { + LOG(LOG_MISC,LOG_ERROR)("DOS: Read file %d failed",reg_bx); reg_ax=dos.errorcode; DPMI_CALLBACK_SCF(true); } @@ -2767,12 +2971,13 @@ Bitu DPMI::API_Int21_MSDOS(void) case 0x40: {/* WRITE Write to file or device */ Bit16u towrite = Mask(reg_ecx); MEM_BlockRead(SegPhys(ds)+Mask(reg_edx),dos_copybuf,towrite); - if (reg_bx>=5) LOG(LOG_MISC,LOG_ERROR)("INT 21 40: %s",(char *)dos_copybuf); +// if (reg_bx<=5) LOG(LOG_MISC,LOG_ERROR)("INT 21 40: %s",(char *)dos_copybuf); if (DOS_WriteFile(reg_bx,dos_copybuf,&towrite)) { - reg_eax=towrite; + if (dpmi.client.bit32) reg_eax=towrite; + else reg_ax =towrite; DPMI_CALLBACK_SCF(false); } else { - DPMI_LOG_ERROR("DPMI:MSDOS:Write file failure."); + DPMI_LOG("DPMI:MSDOS:Write %d file failure.",reg_bx); reg_ax=dos.errorcode; DPMI_CALLBACK_SCF(true); } @@ -2790,11 +2995,17 @@ Bitu DPMI::API_Int21_MSDOS(void) case 0x42: /* LSEEK Set current file position */ { Bit32u pos=(reg_cx<<16) + reg_dx; + Bit32u topos = pos; if (DOS_SeekFile(reg_bx,&pos,reg_al)) { reg_dx=(Bit16u)(pos >> 16); reg_ax=(Bit16u)(pos & 0xFFFF); DPMI_CALLBACK_SCF(false); + if ((reg_al==0) && (topos!=pos)) { + LOG(LOG_MISC,LOG_ERROR)("SEEK FILE Handle:%d Seek:%d Pos:%d",reg_bx,topos,pos); + LOG(LOG_MISC,LOG_ERROR)("SEEK FILE ERROR : Pos differs"); + } } else { + LOG(LOG_MISC,LOG_ERROR)("DOS: Seek file %d failed",reg_bx); reg_ax=dos.errorcode; DPMI_CALLBACK_SCF(true); } @@ -2814,7 +3025,7 @@ Bitu DPMI::API_Int21_MSDOS(void) } break; case 0x01: /* Set */ - DPMI_LOG_ERROR("DOS:Set File Attributes for %s not supported",name1); + DPMI_LOG("DOS:Set File Attributes for %s not supported",name1); DPMI_CALLBACK_SCF(false); break; default: @@ -2822,15 +3033,31 @@ Bitu DPMI::API_Int21_MSDOS(void) } }; break; + case 0x47: { /* CWD Get current directory */ + char name1[256]; + if (DOS_GetCurrentDir(reg_dl,name1)) { + MEM_BlockWrite(SegPhys(ds)+Mask(reg_esi),name1,strlen(name1)+1); + LOG(LOG_MISC,LOG_ERROR)("DOS: Get Dir %s ",name1); + reg_ax=0x0100; + CALLBACK_SCF(false); + } else { + LOG(LOG_MISC,LOG_ERROR)("DOS: Get Dir failed %s ",name1); + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + }; break; + case 0x4E: {/* Get first dir entry */ char name1[256]; MEM_StrCopy(SegPhys(ds)+Mask(reg_edx),name1,255); if (DOS_FindFirst(name1,reg_cx)) { + LOG(LOG_MISC,LOG_ERROR)("DOS: Find Dir entry %s success",name1); DPMI_CALLBACK_SCF(false); // Copy result to internal dta if (dtaAddress) MEM_BlockCopy(dtaAddress,PhysMake(RealSeg(dos.dta),RealOff(dos.dta)),dpmi.pharlap?43:128); reg_ax=0; /* Undocumented */ } else { + LOG(LOG_MISC,LOG_ERROR)("DOS: Find Dir entry %s failure",name1); reg_ax=dos.errorcode; DPMI_CALLBACK_SCF(true); }; @@ -2839,11 +3066,13 @@ Bitu DPMI::API_Int21_MSDOS(void) // Copy data to dos dta if (dtaAddress) MEM_BlockCopy(PhysMake(RealSeg(dos.dta),RealOff(dos.dta)),dtaAddress,dpmi.pharlap?43:128); if (DOS_FindNext()) { + LOG(LOG_MISC,LOG_ERROR)("DOS: FindNext Dir entry success"); CALLBACK_SCF(false); // Copy result to internal dta if (dtaAddress) MEM_BlockCopy(dtaAddress,PhysMake(RealSeg(dos.dta),RealOff(dos.dta)),dpmi.pharlap?43:128); reg_ax=0xffff; /* Undocumented */ } else { + LOG(LOG_MISC,LOG_ERROR)("DOS: FindNext Dir entry failure"); reg_ax=dos.errorcode; CALLBACK_SCF(true); }; @@ -2866,12 +3095,20 @@ Bitu DPMI::API_Int21_MSDOS(void) Bitu segment = GetSegmentFromSelector(reg_dx); DOS_ChildPSP(segment,reg_si); dos.psp = segment; - if (dpmi.pharlap) { - DOS_PSP psp(dos.psp); - psp.SetNumFiles(40); - }; DPMI_LOG("DPMI:MSDOS:0x55:Create new psp:%04X",segment); }; break; + case 0x56: { /* RENAME Rename file */ + char name1[256+1]; + char name2[256+1]; + MEM_StrCopy(SegPhys(ds)+Mask(reg_edx),name1,256); + MEM_StrCopy(SegPhys(es)+Mask(reg_edi),name2,256); + if (DOS_Rename(name1,name2)) { + DPMI_CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + DPMI_CALLBACK_SCF(true); + } + }; break; case 0x5D : // Get Address of dos swappable area // FIXME: This is totally faked... // FIXME: Add size in bytes (at least pharlap) @@ -2899,17 +3136,13 @@ Bitu DPMI::API_Int21_MSDOS(void) // case 0x30: // Pharlap extended information case 0x31: case 0x32: - case 0x38: case 0x3A: - case 0x3B: - case 0x47: case 0x48: // Pharlap = 4KB mem pages case 0x49: case 0x4A: // Pharlap = 4KB mem pages case 0x4B: case 0x52: case 0x53: - case 0x56: case 0x59: case 0x5A: case 0x5B: @@ -2926,8 +3159,8 @@ Bitu DPMI::API_Int21_MSDOS(void) case 0x44: if ((reg_al==0x02) || (reg_al==0x03) || (reg_al==0x04) || (reg_al==0x05) || (reg_al==0x0C) || (reg_al==0x0D)) { E_Exit("DPMI:MSDOS-API:function %04X not yet supported.",reg_ax); }; - case 0x0E: case 0x19: case 0x2A: case 0x2C: case 0x2D: case 0x30: case 0x36: - case 0x3E: case 0x4C: case 0x58: case 0x67: + case 0x07: case 0x0B: case 0x0E: case 0x19: case 0x2A: case 0x2C: case 0x2D: case 0x30: + case 0x36: case 0x3E: case 0x4C: case 0x58: case 0x67: { // reflect to real mode DPMI_Int21Handler(); From efd7d24b2e8d534dcb059ed9895e592ddfe18489 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 30 Sep 2003 13:51:15 +0000 Subject: [PATCH 1204/4131] Give PSP:SetNumFiles a few more files then requested (hack) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1284 --- src/dos/dos_classes.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index e61cdafa..e773fb14 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.30 2003-08-19 20:05:47 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.31 2003-09-30 13:51:15 finsterr Exp $ */ #include #include @@ -236,6 +236,7 @@ bool DOS_PSP::SetNumFiles(Bit16u fileNum) { if (fileNum>20) { // Allocate needed paragraphs + fileNum+=2; // Add a few more files for safety Bit16u para = (fileNum/16)+((fileNum%16)>0); RealPt data = RealMake(DOS_GetMemory(para),0); sSave(sPSP,file_table,data); From 7ce6f668654dc3d30f3f94b01e2796e430cbf906 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 30 Sep 2003 15:42:12 +0000 Subject: [PATCH 1205/4131] Added CMOS_SetRegister Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1285 --- src/hardware/cmos.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 08b08b0d..e44933b1 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -175,6 +175,7 @@ static Bit8u cmos_readreg(Bit32u port) { case 0x18: /* Extended memory in KB High Byte */ case 0x30: /* Extended memory in KB Low Byte */ case 0x31: /* Extended memory in KB High Byte */ +// LOG(LOG_BIOS,LOG_NORMAL)("CMOS:Read from reg %F : %04X",cmos.reg,cmos.regs[cmos.reg]); return cmos.regs[cmos.reg]; default: LOG(LOG_BIOS,LOG_NORMAL)("CMOS:Read from reg %F",cmos.reg); @@ -182,6 +183,11 @@ static Bit8u cmos_readreg(Bit32u port) { } } +void CMOS_SetRegister(Bitu regNr, Bit8u val) +{ + cmos.regs[regNr] = val; +}; + void CMOS_Init(Section* sec) { IO_RegisterWriteHandler(0x70,cmos_selreg,"CMOS"); IO_RegisterWriteHandler(0x71,cmos_writereg,"CMOS"); From 775ffc2526ca3195753f1f12469af7a197d7ad48 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 30 Sep 2003 15:44:30 +0000 Subject: [PATCH 1206/4131] Made core full reentrant Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1286 --- src/cpu/core_full.cpp | 30 +++++++----------------- src/cpu/core_full/ea_lookup.h | 22 +++++++----------- src/cpu/core_full/load.h | 40 ++++++++++++++++++++++++------- src/cpu/core_full/loadwrite.h | 44 ++++++++++++++--------------------- src/cpu/core_full/op.h | 38 +++++++++++++++++++----------- src/cpu/core_full/support.h | 4 ++-- 6 files changed, 92 insertions(+), 86 deletions(-) diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 67999d92..dcaf00d4 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -47,23 +47,11 @@ typedef PhysPt EAPoint; #define LoadD(reg) reg #define SaveD(reg,val) reg=val -static EAPoint IPPoint; - #include "core_full/loadwrite.h" #include "core_full/support.h" #include "core_full/optable.h" -#include "core_full/ea_lookup.h" #include "instructions.h" -static INLINE void DecodeModRM(void) { - inst.rm=Fetchb(); - inst.rm_index=(inst.rm >> 3) & 7; - inst.rm_eai=inst.rm&07; - inst.rm_mod=inst.rm>>6; - /* Decode address of mod/rm if needed */ - if (inst.rm<0xc0) inst.rm_eaa=(inst.prefix & PREFIX_ADDR) ? RMAddress_32() : RMAddress_16(); -} - #define LEAVECORE \ SaveIP(); \ FillFlags(); @@ -79,7 +67,15 @@ static INLINE void DecodeModRM(void) { } Bits Full_DeCode(void) { - + FullData inst; + if (!cpu.code.big) { + inst.start_prefix=0x0;; + inst.start_entry=0x0; + } else { + inst.start_prefix=PREFIX_ADDR; + inst.start_entry=0x200; + } + EAPoint IPPoint; LoadIP(); flags.type=t_UNKNOWN; while (CPU_Cycles>0) { @@ -98,7 +94,6 @@ Bits Full_DeCode(void) { inst.prefix=inst.start_prefix; restartopcode: inst.entry=(inst.entry & 0xffffff00) | Fetchb(); - inst.code=OpCodeTable[inst.entry]; #include "core_full/load.h" #include "core_full/op.h" @@ -112,12 +107,5 @@ nextopcode:; void CPU_Core_Full_Start(bool big) { - if (!big) { - inst.start_prefix=0x0;; - inst.start_entry=0x0; - } else { - inst.start_prefix=PREFIX_ADDR; - inst.start_entry=0x200; - } cpudecoder=&Full_DeCode; } diff --git a/src/cpu/core_full/ea_lookup.h b/src/cpu/core_full/ea_lookup.h index 0c19b04e..cd8834e0 100644 --- a/src/cpu/core_full/ea_lookup.h +++ b/src/cpu/core_full/ea_lookup.h @@ -1,4 +1,4 @@ -static EAPoint RMAddress_16(void) { +{ EAPoint seg_base; Bit16u off; switch ((inst.rm_mod<<3)|inst.rm_eai) { @@ -103,16 +103,13 @@ static EAPoint RMAddress_16(void) { } inst.rm_off=off; if (inst.prefix & PREFIX_SEG) { - return inst.seg.base+off; + inst.rm_eaa=inst.seg.base+off; } else { - return seg_base+off; + inst.rm_eaa=seg_base+off; } -} +} else { -static Bit32u SIBZero=0; -static Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi }; - #define SIB(MODE) { \ Bitu sib=Fetchb(); \ switch (sib&7) { \ @@ -128,9 +125,8 @@ static Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,® } \ off+=*SIBIndex[(sib >> 3) &7] << (sib >> 6); \ }; - - -static EAPoint RMAddress_32(void) { + static Bit32u SIBZero=0; + static Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi }; EAPoint seg_base; Bit32u off; switch ((inst.rm_mod<<3)|inst.rm_eai) { @@ -231,13 +227,11 @@ static EAPoint RMAddress_32(void) { off=reg_edi+Fetchds(); seg_base=SegBase(ds); break; - - } inst.rm_off=off; if (inst.prefix & PREFIX_SEG) { - return inst.seg.base+off; + inst.rm_eaa=inst.seg.base+off; } else { - return seg_base+off; + inst.rm_eaa=seg_base+off; } } diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index e75cd13c..b0adcce4 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -1,7 +1,15 @@ switch (inst.code.load) { /* General loading */ case L_MODRM: - DecodeModRM(); + inst.rm=Fetchb(); + inst.rm_index=(inst.rm >> 3) & 7; + inst.rm_eai=inst.rm&07; + inst.rm_mod=inst.rm>>6; + /* Decode address of mod/rm if needed */ + if (inst.rm<0xc0) { + if (!(inst.prefix & PREFIX_ADDR)) + #include "ea_lookup.h" + } l_MODRMswitch: switch (inst.code.extra) { /* Byte */ @@ -266,32 +274,46 @@ l_M_Ed: break; case D_IRETw: flags.type=t_UNKNOWN; - CPU_IRET(false); - LoadIP(); + if (!CPU_IRET(false)) return CBRET_NONE; if (GETFLAG(IF) && PIC_IRQCheck) { - SaveIP(); return CBRET_NONE; } + LoadIP(); goto nextopcode; case D_IRETd: flags.type=t_UNKNOWN; - CPU_IRET(true); + if (!CPU_IRET(true)) return CBRET_NONE; + if (GETFLAG(IF) && PIC_IRQCheck) { + return CBRET_NONE; + } LoadIP(); goto nextopcode; case D_RETFwIw: - CPU_RET(false,Fetchw()); + if (!CPU_RET(false,Fetchw())) { + FillFlags(); + return CBRET_NONE; + } LoadIP(); goto nextopcode; case D_RETFw: - CPU_RET(false,0); + if (!CPU_RET(false,0)) { + FillFlags(); + return CBRET_NONE; + } LoadIP(); goto nextopcode; case D_RETFdIw: - CPU_RET(true,Fetchw()); + if (!CPU_RET(true,Fetchw())) { + FillFlags(); + return CBRET_NONE; + } LoadIP(); goto nextopcode; case D_RETFd: - CPU_RET(true,0); + if (!CPU_RET(true,0)) { + FillFlags(); + return CBRET_NONE; + } LoadIP(); goto nextopcode; /* Direct operations */ diff --git a/src/cpu/core_full/loadwrite.h b/src/cpu/core_full/loadwrite.h index 4b990369..2a9bdb09 100644 --- a/src/cpu/core_full/loadwrite.h +++ b/src/cpu/core_full/loadwrite.h @@ -1,40 +1,32 @@ -static INLINE void SaveIP(void) { - Bitu left=IPPoint-SegBase(cs); - reg_eip=left; -} - -static INLINE void LoadIP(void) { - IPPoint=SegBase(cs)+reg_eip; -} +#define SaveIP() reg_eip=(Bit32u)(IPPoint-SegBase(cs)); +#define LoadIP() IPPoint=SegBase(cs)+reg_eip; -static INLINE Bit8u Fetchb() { - Bit8u temp=LoadMb(IPPoint); - IPPoint+=1; +static INLINE Bit8u the_Fetchb(EAPoint & loc) { + Bit8u temp=LoadMb(loc); + loc+=1; return temp; } -static INLINE Bit16u Fetchw() { - Bit16u temp=LoadMw(IPPoint); - IPPoint+=2; +static INLINE Bit16u the_Fetchw(EAPoint & loc) { + Bit16u temp=LoadMw(loc); + loc+=2; return temp; } -static INLINE Bit32u Fetchd() { - Bit32u temp=LoadMd(IPPoint); - IPPoint+=4; +static INLINE Bit32u the_Fetchd(EAPoint & loc) { + Bit32u temp=LoadMd(loc); + loc+=4; return temp; } -static INLINE Bit8s Fetchbs() { - return Fetchb(); -} -static INLINE Bit16s Fetchws() { - return Fetchw(); -} +#define Fetchb() the_Fetchb(IPPoint) +#define Fetchw() the_Fetchw(IPPoint) +#define Fetchd() the_Fetchd(IPPoint) + +#define Fetchbs() (Bit8s)the_Fetchb(IPPoint) +#define Fetchws() (Bit16s)the_Fetchw(IPPoint) +#define Fetchds() (Bit32s)the_Fetchd(IPPoint) -static INLINE Bit32s Fetchds() { - return Fetchd(); -} static INLINE void Push_16(Bit16u blah) { reg_esp-=2; diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 6eaae095..3a5e4200 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -321,20 +321,32 @@ switch (inst.code.op) { break; case O_CALLFw: SaveIP(); - CPU_CALL(false,inst.op2.d,inst.op1.d); + if (!CPU_CALL(false,inst.op2.d,inst.op1.d)) { + FillFlags(); + return CBRET_NONE; + } LoadIP(); goto nextopcode; case O_CALLFd: SaveIP(); - CPU_CALL(true,inst.op2.d,inst.op1.d); + if (!CPU_CALL(true,inst.op2.d,inst.op1.d)) { + FillFlags(); + return CBRET_NONE; + } LoadIP(); goto nextopcode; case O_JMPFw: - CPU_JMP(false,inst.op2.d,inst.op1.d); + if (!CPU_JMP(false,inst.op2.d,inst.op1.d)){ + FillFlags(); + return CBRET_NONE; + } LoadIP(); goto nextopcode; case O_JMPFd: - CPU_JMP(true,inst.op2.d,inst.op1.d); + if (!CPU_JMP(true,inst.op2.d,inst.op1.d)) { + FillFlags(); + return CBRET_NONE; + } LoadIP(); goto nextopcode; @@ -344,7 +356,7 @@ switch (inst.code.op) { if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint()) return debugCallback; else if (DEBUG_IntBreakpoint(inst.op1.b)) return debugCallback; #endif - Interrupt(inst.op1.b); + if (!Interrupt(inst.op1.b)) return CBRET_NONE; LoadIP(); break; case O_INb: @@ -379,14 +391,14 @@ switch (inst.code.op) { { Bitu selector; CPU_SLDT(selector); - inst.op1.d=selector; + inst.op1.d=(Bit32u)selector; } break; case 0x01: /* STR */ { Bitu selector; CPU_STR(selector); - inst.op1.d=selector; + inst.op1.d=(Bit32u)selector; } break; case 0x02: /* LLDT */ @@ -403,8 +415,6 @@ switch (inst.code.op) { FillFlags(); CPU_VERW(inst.op1.d); goto nextopcode; /* Else value will saved */ - - default: LOG(LOG_CPU,LOG_ERROR)("Group 6 Illegal subfunction %X",inst.rm_index); } @@ -458,14 +468,14 @@ switch (inst.code.op) { { FillFlags(); Bitu ar;CPU_LAR(inst.op1.d,ar); - inst.op1.d=ar; + inst.op1.d=(Bit32u)ar; } break; case O_LSL: { FillFlags(); Bitu limit;CPU_LSL(inst.op1.d,limit); - inst.op1.d=limit; + inst.op1.d=(Bit32u)limit; } break; case O_ARPL: @@ -473,7 +483,7 @@ switch (inst.code.op) { FillFlags(); Bitu new_sel=inst.op1.d; CPU_ARPL(new_sel,inst.op2.d); - inst.op1.d=new_sel; + inst.op1.d=(Bit32u)new_sel; } break; case O_BSFw: @@ -549,7 +559,7 @@ switch (inst.code.op) { Bitu mask=1 << (inst.op1.d & 15); FillFlags(); if (inst.rm<0xc0) { - read=inst.rm_eaa+2*(inst.op1.d / 16); + read=inst.rm_eaa;//+2*(inst.op1.d / 16); val=mem_readw(read); } else { val=reg_16(inst.rm_eai); @@ -575,7 +585,7 @@ switch (inst.code.op) { Bitu mask=1 << (inst.op1.d & 31); FillFlags(); if (inst.rm<0xc0) { - read=inst.rm_eaa+4*(inst.op1.d / 32); + read=inst.rm_eaa;//+4*(inst.op1.d / 32); val=mem_readd(read); } else { val=reg_32(inst.rm_eai); diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 5be628e4..fd50313b 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -154,7 +154,7 @@ struct OpCode { Bit8u load,op,save,extra; }; -static struct { +struct FullData { Bitu entry; EAPoint start; Bitu rm; @@ -178,7 +178,7 @@ static struct { Bitu prefix; Bitu start_prefix; Bitu start_entry; -} inst; +}; #define PREFIX_NONE 0x0 From 48f857d35192ec89322be60710b1b906ae12b256 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Sep 2003 19:12:44 +0000 Subject: [PATCH 1207/4131] Fixed getredirection. Added support for stuff like copy >NUL f1.exe blah Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1287 --- src/shell/shell.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 6182fa18..221d46ae 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.34 2003-09-21 12:16:02 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.35 2003-09-30 19:12:44 qbix79 Exp $ */ #include #include @@ -74,13 +74,16 @@ Bitu DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn,bool * append) { while (ch=*lr++) { switch (ch) { case '>': - *append=(*lr)=='>'; - if (append) lr++; + *append=((*lr)=='>'); + if (*append) lr++; lr=ltrim(lr); if (*ofn) free(*ofn); *ofn=lr; while (*lr && *lr!=' ') lr++; - *lr=0; + if(*lr && *(lr+1)) + *lr++=0; + else + *lr=0; *ofn=strdup(*ofn); continue; case '<': @@ -88,7 +91,10 @@ Bitu DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn,bool * append) { lr=ltrim(lr); *ifn=lr; while (*lr && *lr!=' ') lr++; - *lr=0; + if(*lr && *(lr+1)) + *lr++=0; + else + *lr=0; *ifn=strdup(*ifn); continue; case '|': @@ -284,7 +290,7 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_COPY_SUCCESS"," %d File(s) copied.\n"); MSG_Add("SHELL_STARTUP","DOSBox Shell v" VERSION "\n" - "DOSBox does not run protected mode games!\n" + "This version runs some protected mode games!\n" "For supported shell commands type: HELP\n" "For a short introduction type: INTRO\n\n" "For more information read the README file in DOSBox directory.\n" From 5235b729e6843dc403a3f39d8e37dfa2fad62cf0 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 2 Oct 2003 11:07:11 +0000 Subject: [PATCH 1208/4131] Moved a LEAVECORE out of a C_DEBUG define (int 3) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1288 --- src/cpu/core_normal/prefix_none.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 0e40cd8c..040e1786 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -754,8 +754,8 @@ break; } CASE_B(0xcc) /* INT3 */ -#if C_DEBUG LEAVECORE; +#if C_DEBUG if (DEBUG_Breakpoint()) { return debugCallback; } From f1925e686eb66dea374cc91c284f7c0e4692c187 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 2 Oct 2003 18:00:54 +0000 Subject: [PATCH 1209/4131] Updated Help message. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1289 --- src/dos/dos.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index f1035b4e..383296ad 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: dos.cpp,v 1.53 2003-10-02 18:00:54 qbix79 Exp $ */ + #include #include #include @@ -934,7 +936,7 @@ void DOS_ShutDown(Section* sec) void DOS_Init(Section* sec) { - MSG_Add("DOS_CONFIGFILE_HELP","Setting a memory size to 0 will disable it.\n"); + MSG_Add("DOS_CONFIGFILE_HELP","Disabling or enabling DPMI makes a huge difference for protected mode games. Try both!\n"); call_20=CALLBACK_Allocate(); CALLBACK_Setup(call_20,DOS_20Handler,CB_IRET); RealSetVec(0x20,CALLBACK_RealPointer(call_20)); From 813880ae1592b12b2bc815be9b5a3dc880977840 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 3 Oct 2003 12:28:19 +0000 Subject: [PATCH 1210/4131] Added changes (dpmi, cd label, debugger) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1290 --- ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index fcf663af..a8e16218 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,13 @@ - updated errorcodes of findfirst (thanks Mirek!) - added basic support for vidmode 0x7 - 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 0.58 - fixed date and time issues with fcbs From 16577268afa0e04971d32c9a1fb273d3c774fe16 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 3 Oct 2003 12:28:41 +0000 Subject: [PATCH 1211/4131] Added changes (cd label, loadfix) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1291 --- README | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/README b/README index 17046551..048555a4 100644 --- a/README +++ b/README @@ -86,6 +86,9 @@ MOUNT -cd -cd Displays all detected cdrom drives and their numbers. Use with -usecd. + -label name + Set the cd label to the given name. Needed on some systems if the cd label isnt read correctly. + Note: It's possible to mount a local directory as cdrom drive. Hardware support is then missing. @@ -105,10 +108,22 @@ CONFIG [-writeconf] [-writelang] localfile Write the current configuration or language settings to file. "localfile" is located on the local drive !!! -LOADFIX +LOADFIX [-option] [programname] [parameters] Program to "eat up" memory. Useful for old programs which don't expect much memory to be free. + -[size] number of kb to "eat up", default = 64kb + + -f frees all previously allocated memory + + Examples: + 1. To start mm2.exe and allocate 64kb memory : + loadfix mm2 + 2. To start mm2.exe and allocate 32kb memory : + loadfix -32 mm2 + 3. To free previous allocated memory : + loadfix -f + For more information use the /? command line switch with the programs. From 004287340eeb419815d9fbe1e868f4e63fad27ec Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 4 Oct 2003 12:38:34 +0000 Subject: [PATCH 1212/4131] fixed a bug in EMM_PartialPageMapping Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1292 --- src/ints/ems.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index d9b75de0..de226fd8 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -32,7 +32,7 @@ #define EMM_PAGEFRAME 0xE000 #define EMM_PAGEFRAME4K ((EMM_PAGEFRAME*16)/4096) -#define EMM_MAX_HANDLES 50 /* 255 Max */ +#define EMM_MAX_HANDLES 100 /* 255 Max */ #define EMM_PAGE_SIZE (16*1024U) #define EMM_MAX_PAGES (32 * 1024 / 16 ) #define EMM_MAX_PHYS 4 /* 4 16kb pages in pageframe */ @@ -241,7 +241,8 @@ static Bit8u EMM_PartialPageMapping(void) { mem_writew(data,count);data+=2; for (;count>0;count--) { Bit16u page=mem_readw(list);list+=2; - if (page>=EMM_MAX_PHYS) return EMM_ILL_PHYS; + if ((page=EMM_PAGEFRAME+0x1000)) return EMM_ILL_PHYS; + page = (page-EMM_PAGEFRAME) / (EMM_PAGE_SIZE>>4); mem_writew(data,page);data+=2; MEM_BlockWrite(data,&emm_mappings[page],sizeof(EMM_Mapping)); data+=sizeof(EMM_Mapping); @@ -348,7 +349,7 @@ static Bit8u MemoryRegion(void) { return EMM_FUNC_NOSUP; } LoadMoveRegion(SegPhys(ds)+reg_si,region); -/* Parse the region for information */ + /* Parse the region for information */ PhysPt src_mem,dest_mem; MemHandle src_handle,dest_handle; Bitu src_off,dest_off;Bitu src_remain,dest_remain; From 17c499ba5db055c8375833334a98bdd9d06cc0ab Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 4 Oct 2003 12:40:28 +0000 Subject: [PATCH 1213/4131] added '+' as a valid char in DOS_MakeName added hack: devices can only be opened once Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1293 --- src/dos/dos_files.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 4fe7b066..4c60428b 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.44 2003-08-29 08:17:49 harekiet Exp $ */ +/* $Id: dos_files.cpp,v 1.45 2003-10-04 12:40:28 finsterr Exp $ */ #include #include @@ -81,7 +81,7 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { case '\\': case '$': case '#': case '@': case '(': case ')': case '!': case '%': case '{': case '}': case '`': case '~': case '_': case '-': case '.': case '*': case '?': case '&': - case '\'': + case '\'': case '+': upname[w++]=c; break; default: @@ -390,6 +390,8 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { bool exists=false; if (!device) exists=Drives[drive]->FileOpen(&Files[handle],fullname,flags); if (exists || device ) { + // devices can only be opened once + if (device && ((*entry=psp.FindEntryByHandle(handle))!=0xff)) return true; Files[handle]->AddRef(); psp.SetFileHandle(*entry,handle); return true; From c441866164497d6f4e75202e952a37a7dff53d8e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 5 Oct 2003 14:48:43 +0000 Subject: [PATCH 1214/4131] Fix a missing line while rendering Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1294 --- src/gui/render_normal.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/render_normal.h b/src/gui/render_normal.h index 5d4beeee..32e131ab 100644 --- a/src/gui/render_normal.h +++ b/src/gui/render_normal.h @@ -79,7 +79,6 @@ static void Normal_ ## FUNC ## _ ##BPP(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy Bitu next_src=render.src.pitch-dx; \ Bitu next_dest=(LINES_ ## FUNC*render.op.pitch) - (dx*PIXELS_ ## FUNC * SIZE_ ## BPP); \ dx/=LOOPSIZE; \ - dy--; \ for (;dy>0;dy--) { \ for (Bitu tempx=dx;tempx>0;tempx--) { \ NORMAL_LOOP(LOOPSIZE,FUNC,BPP); \ From 21949d32258e037547ceb1395df51f1b080021dc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 5 Oct 2003 19:12:09 +0000 Subject: [PATCH 1215/4131] Auto intialize dma transfers now use the dma block size parameter setup previously Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1295 --- src/hardware/sblaster.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 4d3099d9..4b36aac8 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -461,7 +461,6 @@ static void DSP_StartDMATranfser(DMA_MODES mode) { char * type; /* First fill with current whatever is playing */ DSP_ChangeMode(MODE_NONE); - sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); sb.dma.left=sb.dma.total; if (sb.use_time_constant) { sb.dma.rate=(1000000 / (256 - sb.time_constant)); @@ -568,6 +567,7 @@ static void DSP_DoCommand(void) { case 0x24: /* Singe Cycle 8-Bit DMA ADC */ case 0x14: /* Singe Cycle 8-Bit DMA DAC */ case 0x91: /* Singe Cycle 8-Bit DMA High speed DAC */ + sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); DSP_StartDMATranfser(DMA_8_SINGLE); break; case 0x90: /* Auto Init 8-bit DMA High Speed */ @@ -585,9 +585,11 @@ static void DSP_DoCommand(void) { case 0x75: /* 075h : Single Cycle 4-bit ADPCM Reference */ sb.adpcm.reference=0x1000000; case 0x74: /* 074h : Single Cycle 4-bit ADPCM */ + sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); DSP_StartDMATranfser(DMA_4_SINGLE); break; case 0x80: /* Silence DAC */ + sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); DSP_StartDMATranfser(DMA_8_SILENCE); break; case 0xd0: /* Halt 8-bit DMA */ From b46b57b84574791b72156ae34080fc191ad0782a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 5 Oct 2003 19:13:15 +0000 Subject: [PATCH 1216/4131] Manpage updated Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1296 --- docs/dosbox.1 | 183 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 151 insertions(+), 32 deletions(-) diff --git a/docs/dosbox.1 b/docs/dosbox.1 index 805b8539..b8acc8fc 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -1,59 +1,178 @@ .\" Hey, EMACS: -*- nroff -*- -.TH DOSBOX 1 "March 31, 2003" +.TH DOSBOX 1 "October 5, 2003" .\" Please adjust this date whenever revising the manpage. .SH NAME -dosbox \- an x86/DOS emulator with sound/graphics primarily for games +dosbox \- an x86/DOS emulator with sound/graphics .SH SYNOPSIS .B dosbox -[\fB-fullscreen\fR] -[\fB-conf\fR \fIconfigfile\fR] -[\fB-lang\fR \fIlangfile\fR] -[\fBfile\fR] -[\fB-c\fR \fIcommand1\fR <\fIcommand2\fR>...] -.br +.B [\-fullscreen] +.BI "[\-conf " configfile ] +.BI "[\-lang " langfile ] +.B [file] +.BI "[\-c " command ] +.B [\-exit] .SH DESCRIPTION This manual page briefly documents -\fBdosbox\fR, an x86/DOS emulator capable of running many games. +.BR "dosbox" ", an x86/DOS emulator." .TP -The optional \fBfile\fR argument should be a DOS executable or a directory. If it is a dos executable (.com .exe .bat) the program will run automatically. If it is a directory, a DOS session will run with the directory mounted as C:. +.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:." .SH OPTIONS A summary of options is included below. .TP -\fB-fullscreen\fR -Start DOSBox in fullscreen mode +.B \-fullscreen +.RB "Start " dosbox " in fullscreen mode." .TP -\fB-c\fR \fIcommand 1\fR [\fIcommand 2\fR] ... -Run one or more DOS commands after starting \fBdosbox\fR. If an executable is -also specified, these commands will be executed before running the program. +.BI \-c " command" +.RI "Runs the specified " command " before running " +.BR file . +.RI "Multiple commands can be specified. Each " command " should start with \-c though." .TP -\fB-conf\fR \fIconfigfile\fR -Start \fBdosbox\fR with the options specified in \fIconfigfile\fR +.BI \-conf " configfile +.RB "Start " dosbox " with the options specified in " +.IR configfile . .TP -\fB-lang\fR \fIlangfile\fR -Start \fBdosbox\fR with the language specified in \fIlangfile\fR -.SH INTERNAL COMMANDS +.BI \-lang " langfile +.RB "Start " dosbox " with the language specified in " +.IR langfile . +.TP +.B \-exit +.BR dosbox " will exit after running the program specified by " file . +.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 [\-aspi] [\-ioctl] +.BI "[\-usecd " number "] [\-label " drivelabel ] +.LP +.B MOUNT \-cd +.LP +.RB "Program to mount local directories as drives inside " dosbox . +.RS .TP -\fBMOUNT\fR [\fB-t\fR \fItype\fR] [\fB-size\fR \fIsize\fR] \fBdriveletter\fR \fBsourcedirectory\fR [\fB-aspi\fR] -Map \fBsourcedirectory\fR to \fBdriveletter\fR. -\fItype\fR may be \fIdir\fR for a hard drive, \fIfloppy\fR for a floppy -drive or \fIcdrom\fR for a cdrom. \fIsize\fR specifies the size of the volume. -You can force ASPI mode for a cdrom with \fB-aspi\fR. +.I driveletter +The driveletter inside dosbox (eg. C). .TP -\fBMEM\fR +.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. +.TP +.BI \-label " drivelabel" +.RI "Sets the name of the drive to " drivelabel ". Needed on some" +systems if the cd label isnt read correctly. Useful when a +program can't find its cdrom. +.TP +.B \-aspi +Forces to use the aspi layer. Only valid if mounting a cdrom under +Windows systems with an ASPI-Layer. +.TP +.B \-ioctl +Forces to use ioctl commands. Only valid if mounting a cdrom under +windows which support them (Win2000/XP/NT). +.TP +.BI \-usecd " number" +Forces to use SDL cdrom support for drive number. +.IR Number " can be found by " +.BR \-cd ". Valid on all systems." +.TP +.B \-cd +.RB "Displays all detected cdrom drives and their numbers. Use with " \-usecd "." +.RE +.TP +.B MEM +.LP Display the amount of free memory .TP -\fBCONFIG\fR [\fB-writeconf\fR] [\fB-writelang\fR] \fBfile\fR -Write the current configuration or language settings to \fBfile\fR +.B CONFIG [\-writeconf] [\-writelang] file +.LP +.RB "Write the current configuration or language settings to " file . +.TP +.B LOADFIX [\-size] [programname] [parameters] +.LP +.B LOADFIX \-f +.LP +Program to eat up memory, Usefull 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 it's 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 .SH FILES Configuration and language files use a format similar to Windows .ini files. If a file named -\fBdosbox.conf\fR is found in the current directory, it will be automatically loaded. +.BR dosbox.conf " is found in the current directory, it will be automatically loaded." +.SH "SPECIAL KEYS" +.TP 12m +.IP ALT\-ENTER +Go full screen and back. +.IP CTRL\-F5 +Save a screenshot. +.IP CTRL\-F6 +Start/Stop recording sound output to a wave file. +.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. +.IP CTRL\-F12 +Speed up emulation. +.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 CRTL+F8. Your CPU usage should decrease. +Go back one step and repeat this until the game runs fast enough for you. +Please note that this is a trade off: you lose in fluidity of video what you +gain in speed. +.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 Gigahertz PC is roughly the equivalent of a 16MHz 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. Notably, any program that uses protected mode will not work at all. -DOSBox will exit without warning if an error occured. -.SH SEE ALSO +Not all DOS programs work properly. +.BR dosbox " will exit without warning if an error occured." +.SH "SEE ALSO" The README in /usr/share/doc/dosbox .SH AUTHOR This manual page was written by Peter Veenstra and James Oakley , From 78c9d2a8a3babf382577c18e2e331f806dee3110 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 5 Oct 2003 19:15:07 +0000 Subject: [PATCH 1217/4131] Updated README to include note Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1297 --- README | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/README b/README index 048555a4..a13f30f9 100644 --- a/README +++ b/README @@ -1,5 +1,19 @@ DOSBox v0.60 +===== +NOTE: +===== + +While we hope that, one day, DosBox will run virtually all programs +ever made for the PC...we are not there yet. At present, DosBox run on a 1 +Gigahertz PC is roughly the equivalent of a 16MHz 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 require a much faster processor for you to run it properly +in DosBox. + ====== Usage: ====== @@ -68,7 +82,8 @@ MOUNT -cd Sets the size of the drive. -label drivelabel - Sets the name of the drive to "drivelabel". Useful when a + Sets the name of the drive to "drivelabel". Needed on some + systems if the cd label isnt read correctly. Useful when a program can't find its cdrom. -aspi @@ -86,9 +101,6 @@ MOUNT -cd -cd Displays all detected cdrom drives and their numbers. Use with -usecd. - -label name - Set the cd label to the given name. Needed on some systems if the cd label isnt read correctly. - Note: It's possible to mount a local directory as cdrom drive. Hardware support is then missing. @@ -100,7 +112,9 @@ MOUNT -cd 3. To mount system cdrom drive at mountpoint /media/cdrom as cdrom drive D in dosbox: mount d /media/cdrom -t cdrom -usecd 0 - + 4. To mount a drive with 870 mb free diskspace (rarely needed! experts only): + mount c d:\ -size 4025,127,16513,1700 + MEM Program to display the amount of free memory. @@ -108,15 +122,19 @@ CONFIG [-writeconf] [-writelang] localfile Write the current configuration or language settings to file. "localfile" is located on the local drive !!! -LOADFIX [-option] [programname] [parameters] +LOADFIX [-size] [program] [program-parameters] +LOADFIX -f Program to "eat up" memory. Useful for old programs which don't expect much memory to be free. - -[size] number of kb to "eat up", default = 64kb + -size + number of kb to "eat up", default = 64kb - -f frees all previously allocated memory + -f + frees all previously allocated memory - Examples: + +Examples: 1. To start mm2.exe and allocate 64kb memory : loadfix mm2 2. To start mm2.exe and allocate 32kb memory : From 3db4631b74217e10fb650908989ca1649bd0d290 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 5 Oct 2003 19:31:21 +0000 Subject: [PATCH 1218/4131] typos corrected by wjp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1298 --- README | 2 +- docs/dosbox.1 | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README b/README index a13f30f9..2ebb8cd8 100644 --- a/README +++ b/README @@ -83,7 +83,7 @@ MOUNT -cd -label drivelabel Sets the name of the drive to "drivelabel". Needed on some - systems if the cd label isnt read correctly. Useful when a + systems if the cd label isn't read correctly. Useful when a program can't find its cdrom. -aspi diff --git a/docs/dosbox.1 b/docs/dosbox.1 index b8acc8fc..999f95e1 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -66,7 +66,7 @@ Sets the size of the drive. .TP .BI \-label " drivelabel" .RI "Sets the name of the drive to " drivelabel ". Needed on some" -systems if the cd label isnt read correctly. Useful when a +systems if the cd label isn't read correctly. Useful when a program can't find its cdrom. .TP .B \-aspi @@ -98,11 +98,11 @@ Display the amount of free memory .LP .B LOADFIX \-f .LP -Program to eat up memory, Usefull for old programs which don't expect much memory to be free. +Program to eat up memory, 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 it's memory. +The name of the program which is executed after loadfix eats up its memory. .TP .B [parameters] .RB "Parameters given to the " programname " executable." From cc967c135b9de896d40e971097cca835a3f80892 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 7 Oct 2003 10:33:55 +0000 Subject: [PATCH 1219/4131] typo and addition to config Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1299 --- docs/dosbox.1 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/dosbox.1 b/docs/dosbox.1 index 999f95e1..313dc2ba 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -25,7 +25,8 @@ A summary of options is included below. .BI \-c " command" .RI "Runs the specified " command " before running " .BR file . -.RI "Multiple commands can be specified. Each " command " should start with \-c though." +.RI "Multiple commands can be specified. Each " command " should start with " +.BR \-c " though." .TP .BI \-conf " configfile .RB "Start " dosbox " with the options specified in " @@ -42,7 +43,7 @@ A summary of options is included below. 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 ] +.BI "MOUNT [\-t " type "] [\-size " size ] .I driveletter sourcedirectory .B [\-aspi] [\-ioctl] .BI "[\-usecd " number "] [\-label " drivelabel ] @@ -92,7 +93,9 @@ Display the amount of free memory .TP .B CONFIG [\-writeconf] [\-writelang] file .LP -.RB "Write the current configuration or language settings to " file . +.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 LOADFIX [\-size] [programname] [parameters] .LP From ee7b9ac813cb61c63ec1aacc7b3dc74c4c9dc55c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 7 Oct 2003 10:42:01 +0000 Subject: [PATCH 1220/4131] Fixes of c2woody for the first c2woody fixes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1300 --- src/fpu/fpu_instructions.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 70df617a..bdd9bcf9 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.12 2003-09-24 19:46:36 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.13 2003-10-07 10:42:01 qbix79 Exp $ */ static void FPU_FINIT(void) { @@ -157,16 +157,16 @@ static void FPU_FST(Bitu st, Bitu other){ static void FPU_FCOM(Bitu st, Bitu other){ if((fpu.tags[st] != TAG_Valid) || (fpu.tags[other] != TAG_Valid)){ - FPU_SET_C3(1);FPU_SET_C1(1);FPU_SET_C0(1);return; + FPU_SET_C3(1);FPU_SET_C2(1);FPU_SET_C0(1);return; } if(fpu.regs[st].d == fpu.regs[other].d){ - FPU_SET_C3(1);FPU_SET_C1(0);FPU_SET_C0(0);return; + FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(0);return; } if(fpu.regs[st].d < fpu.regs[other].d){ - FPU_SET_C3(0);FPU_SET_C1(0);FPU_SET_C0(1);return; + FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C0(1);return; } // st > other - FPU_SET_C3(0);FPU_SET_C1(0);FPU_SET_C0(0);return; + FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C0(0);return; } static void FPU_FUCOM(Bitu st, Bitu other){ @@ -203,10 +203,10 @@ static void FPU_FPREM(void){ Bit64s ressaved = static_cast(res); res=valtop - res*valdiv; fpu.regs[TOP].d = res; - FPU_SET_C3(static_cast(ressaved&4)); - FPU_SET_C2(static_cast(ressaved&2)); + FPU_SET_C0(static_cast(ressaved&4)); + FPU_SET_C3(static_cast(ressaved&2)); FPU_SET_C1(static_cast(ressaved&1)); - FPU_SET_C0(0); + FPU_SET_C2(0); } static void FPU_FXAM(void){ From 8e8651dc7944f712296d2d776e460e9d1da77b67 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 9 Oct 2003 11:50:15 +0000 Subject: [PATCH 1221/4131] update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1301 --- ChangeLog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index a8e16218..abeefe83 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,14 @@ - debugger shows selector- and cpu mode info - added SELINFO (selector information) command to debugger - added reference counting for dos files + - Added tabcompletion !! + - Added basic fpu support. + - Fixed several bugs with case sensitive filesystems. + - Added more shell commands and improved their behaviour. + - Mouse improvements. + - Real time clock inprovements. + - DMA fixes. + - Improved .BAT file support. 0.58 - fixed date and time issues with fcbs From 9572158abbf8884a7e51d22587706f433e6b66eb Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 9 Oct 2003 13:47:06 +0000 Subject: [PATCH 1222/4131] fixed bug in DOS_DTA:SetupSearch (dont overwrite directory id) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1302 --- src/dos/dos_classes.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index e773fb14..b5a8b5be 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.31 2003-09-30 13:51:15 finsterr Exp $ */ +/* $Id: dos_classes.cpp,v 1.32 2003-10-09 13:47:06 finsterr Exp $ */ #include #include @@ -256,7 +256,7 @@ void DOS_DTA::SetupSearch(Bit8u _sdrive,Bit8u _sattr,char * pattern) { sSave(sDTA,sattr,_sattr); /* Fill with spaces */ Bitu i; - for (i=0;i<12;i++) mem_writeb(pt+offsetof(sDTA,sname)+i,' '); + for (i=0;i<11;i++) mem_writeb(pt+offsetof(sDTA,sname)+i,' '); char * find_ext; find_ext=strchr(pattern,'.'); if (find_ext) { From 4fae68a7b6864305766c010e35b6d4c2c409533b Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 9 Oct 2003 13:47:44 +0000 Subject: [PATCH 1223/4131] dont duplicate console handles Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1303 --- src/dos/dos_files.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 4c60428b..6402fe2d 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.45 2003-10-04 12:40:28 finsterr Exp $ */ +/* $Id: dos_files.cpp,v 1.46 2003-10-09 13:47:44 finsterr Exp $ */ #include #include @@ -467,6 +467,13 @@ bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit8u * sectors,Bit16u * cl } bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry) { + + // Dont duplicate console handles + if (entry<=STDPRN) { + *newentry = entry; + return true; + }; + Bit8u handle=RealHandle(entry); if (handle>=DOS_FILES) { DOS_SetError(DOSERR_INVALID_HANDLE); @@ -488,6 +495,13 @@ bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry) { }; bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry) { + + // Dont duplicate console handles + if (entry<=STDPRN) { + newentry = entry; + return true; + }; + Bit8u orig=RealHandle(entry); if (orig>=DOS_FILES) { DOS_SetError(DOSERR_INVALID_HANDLE); From 8100d28f827b8cdf9fb3179501c5420f129e251d Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 9 Oct 2003 13:50:27 +0000 Subject: [PATCH 1224/4131] Enabled multiple FindFirst/Next Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1304 --- include/dos_system.h | 9 ++--- src/dos/drive_cache.cpp | 76 +++++++++++++++++++++++++++++------------ src/dos/drive_local.cpp | 8 ++--- 3 files changed, 63 insertions(+), 30 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 02ce52c2..32212304 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.15 2003-09-22 12:22:25 finsterr Exp $ */ +/* $Id: dos_system.h,v 1.16 2003-10-09 13:50:27 finsterr Exp $ */ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ @@ -104,8 +104,8 @@ public: char* GetExpandName (const char* path); bool GetShortName (const char* fullname, char* shortname); - bool FindFirst (char* path, Bit16u& id); - bool FindNext (Bit16u& id, char* &result); + bool FindFirst (char* path, Bitu dtaAddress, Bitu& id); + bool FindNext (Bitu id, char* &result); void CacheOut (const char* path, bool ignoreLastDir = false); void AddEntry (const char* path, bool checkExist = false); @@ -121,6 +121,7 @@ public: for (Bit32u i=0; inextEntry = 0; + if (!OpenDir(path,dirID)) return false; + // Seacrh if dta was already used before + for (Bitu n=0; ncompareCount == dtaAddress) { + // Reuse old dta + dirFindFirstID = n; break; + } + } else if (dirFindFirstID==0xffff) { + dirFindFirstID = n; + } + } + if (dirFindFirstID==0xffff) { + // no free slot found... + LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst/Next failure : All slots full."); + // always use first then + dirFindFirstID = 0; + } + // Clear and reuse slot + delete dirFindFirst[dirFindFirstID]; + dirFindFirst[dirFindFirstID] = new CFileInfo(); + dirFindFirst[dirFindFirstID]-> nextEntry = 0; + dirFindFirst[dirFindFirstID]-> compareCount = dtaAddress; +// strcpy(dirFindFirst[dirFindFirstID]->orgname,path); + // Copy entries to use with FindNext - for (Bitu i=0; ifileList.size(); i++) { - CreateEntry(dirFindFirst,dirSearch[id]->fileList[i]->orgname); + for (Bitu i=0; ifileList.size(); i++) { + CreateEntry(dirFindFirst[dirFindFirstID],dirSearch[dirID]->fileList[i]->orgname); // Sort Lists - filelist has to be alphabetically sorted, even in between (for finding double file names) - std::sort(dirFindFirst->fileList.begin(), dirFindFirst->fileList.end(), SortByName); + std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByName); }; // Now re-sort the fileList accordingly to output switch (sortDirType) { - case ALPHABETICAL : std::sort(dirFindFirst->fileList.begin(), dirFindFirst->fileList.end(), SortByName); break; - case DIRALPHABETICAL : std::sort(dirFindFirst->fileList.begin(), dirFindFirst->fileList.end(), SortByDirName); break; - case ALPHABETICALREV : std::sort(dirFindFirst->fileList.begin(), dirFindFirst->fileList.end(), SortByNameRev); break; - case DIRALPHABETICALREV : std::sort(dirFindFirst->fileList.begin(), dirFindFirst->fileList.end(), SortByDirNameRev); break; + case ALPHABETICAL : std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByName); break; + case DIRALPHABETICAL : std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByDirName); break; + case ALPHABETICALREV : std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByNameRev); break; + case DIRALPHABETICALREV : std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByDirNameRev); break; case NOSORT : break; }; + +// LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst : %s (ID:%02X)",path,dirFindFirstID); + id = dirFindFirstID; return true; }; -bool DOS_Drive_Cache::FindNext(Bit16u& id, char* &result) +bool DOS_Drive_Cache::FindNext(Bitu id, char* &result) { - return SetResult(dirFindFirst, result, dirFindFirst->nextEntry); + // out of range ? + if ((id>=MAX_OPENDIRS) || !dirFindFirst[id]) { + LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst/Next failure : ID out of range: %04X",id); + return false; + } + if (!SetResult(dirFindFirst[id], result, dirFindFirst[id]->nextEntry)) { + // free slot + delete dirFindFirst[id]; dirFindFirst[id] = 0; + return false; + } + return true; }; // **************************************************************************** diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index f10fbed7..509d083f 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -109,9 +109,8 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { char end[2]={CROSS_FILESPLIT,0}; if (tempDir[strlen(tempDir)-1]!=CROSS_FILESPLIT) strcat(tempDir,end); - Bit16u id; -// if (!dirCache.OpenDir(tempDir,id)) - if (!dirCache.FindFirst(tempDir,id)) + Bitu id; + if (!dirCache.FindFirst(tempDir,(Bitu)dos.dta,id)) { DOS_SetError(DOSERR_PATH_NOT_FOUND); return false; @@ -143,10 +142,9 @@ bool localDrive::FindNext(DOS_DTA & dta) { dta.GetSearchParams(srch_attr,srch_pattern); - Bit16u id = dta.GetDirID(); + Bitu id = dta.GetDirID(); again: -// if (!dirCache.ReadDir(id,dir_ent)) { if (!dirCache.FindNext(id,dir_ent)) { DOS_SetError(DOSERR_NO_MORE_FILES); return false; From 1153f2766ba8f9da6c3c1f3486f0e09839bbcc45 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 10 Oct 2003 08:11:48 +0000 Subject: [PATCH 1225/4131] Fix the logging messages and give an e_exit in non-debug version for enabling paging. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1305 --- src/cpu/paging.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index d8fdc8fa..8f6c68b9 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -84,7 +84,7 @@ void PageDirectory::SetBase(PhysPt page) { ClearDirectory(); /* Setup handler for PageDirectory changes */ link_dir=MEM_LinkPage(base_page,0); - if (!link_dir) E_Exit("PageDirectory setup on illegal address"); + if (!link_dir) E_Exit("PAGING:Directory setup on illegal address"); link_dir->data.dir=this; link_dir->change=dir_change; MEM_CheckLinks(link_dir->entry); @@ -169,7 +169,7 @@ Bitu PAGING_GetDirBase(void) { void PAGING_SetDirBase(Bitu cr3) { paging.cr3=cr3; Bitu base_page=cr3 >> 12; - LOG_MSG("CR3:%X Base %X",cr3,base_page); + LOG(LOG_PAGING,LOG_NORMAL)("CR3:%X Base %X",cr3,base_page); if (paging.enabled) { /* Check if we already have this one cached */ PageDirectory * dir=paging.cache; @@ -194,10 +194,13 @@ void PAGING_Enable(bool enabled) { if (paging.enabled==enabled) return; paging.enabled=enabled; if (!enabled) { - LOG_MSG("Paging disabled"); + LOG(LOG_PAGING,LOG_NORMAL)("Disabled"); paging.dir=MEM_DefaultDirectory(); } else { - LOG_MSG("Paging enabled"); + LOG(LOG_PAGING,LOG_NORMAL)("Enabled"); +#if !(C_DEBUG) + E_Exit("CPU Paging features aren't supported"); +#endif PAGING_SetDirBase(paging.cr3); } } From 60f95a14eb6599df9d0ab9ea0845e5120db0c2e2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 10 Oct 2003 08:15:49 +0000 Subject: [PATCH 1226/4131] Added Tandy emulation based on sn76496.c from MAME Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1306 --- src/hardware/tandy_sound.cpp | 388 ++++++++++++++++++++++++++--------- 1 file changed, 288 insertions(+), 100 deletions(-) diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 927a6990..d7d55fa7 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -17,7 +17,7 @@ */ /* - Probably just use the mame code for the same chip sometime + Based of sn76496.c of the M.A.M.E. project */ #include @@ -26,121 +26,309 @@ #include "mixer.h" #include "mem.h" #include "setup.h" +#include "pic.h" -#define TANDY_DIV 111860 -#define TANDY_RATE 22050 -#define BIT_SHIFT 16 -#define TANDY_VOLUME 10000 -static MIXER_Channel * tandy_chan; -struct TandyChannel { - Bit32u div; - Bit32u freq_add; - Bit32u freq_pos; +#define MAX_OUTPUT 0x7fff +#define STEP 0x10000 + +/* Formulas for noise generator */ +/* bit0 = output */ + +/* noise feedback for white noise mode (verified on real SN76489 by John Kortink) */ +#define FB_WNOISE 0x14002 /* (16bits) bit16 = bit0(out) ^ bit2 ^ bit15 */ + +/* noise feedback for periodic noise mode */ +//#define FB_PNOISE 0x10000 /* 16bit rorate */ +#define FB_PNOISE 0x08000 /* JH 981127 - fixes Do Run Run */ + +/* +0x08000 is definitely wrong. The Master System conversion of Marble Madness +uses periodic noise as a baseline. With a 15-bit rotate, the bassline is +out of tune. +The 16-bit rotate has been confirmed against a real PAL Sega Master System 2. +Hope that helps the System E stuff, more news on the PSG as and when! +*/ + +/* noise generator start preset (for periodic noise) */ +#define NG_PRESET 0x0f35 + + +struct SN76496 +{ + int SampleRate; + unsigned int UpdateStep; + int VolTable[16]; /* volume table */ + int Register[8]; /* registers */ + int LastRegister; /* last register written */ + int Volume[4]; /* volume of voice 0-2 and noise */ + unsigned int RNG; /* noise generator */ + int NoiseFB; /* noise feedback mask */ + int Period[4]; + int Count[4]; + int Output[4]; }; - -struct TandyBlock { - TandyChannel chan[3]; - - Bit32s volume[4]; - Bit8u reg; -}; - -static TandyBlock tandy; +static struct SN76496 sn; +static struct { + MIXER_Channel * chan; + bool enabled; + Bitu last_write; +} tandy; -#define REG_CHAN0DIV 0 /* 0 0 0 */ -#define REG_CHAN0ATT 1 /* 0 0 1 */ -#define REG_CHAN1DIV 2 /* 0 1 0 */ -#define REG_CHAN1ATT 3 /* 0 1 1 */ -#define REG_CHAN2DIV 4 /* 1 0 0 */ -#define REG_CHAN2ATT 5 /* 1 0 1 */ -#define REG_NOISEATT 7 /* 1 1 1 */ +static void SN76496Write(Bit32u port,Bit8u data) +{ + struct SN76496 *R = &sn; -//TODO a db volume table :) -static Bit32s vol_table[16]; - - -static void write_pc0(Bit32u port,Bit8u val) { - /* Test for a command byte */ - if (val & 0x80) { - tandy.reg=(val>>4) & 7; - switch (tandy.reg) { - case REG_CHAN0DIV: - case REG_CHAN1DIV: - case REG_CHAN2DIV: - tandy.chan[tandy.reg>>1].div=val&15; - break; - case REG_CHAN0ATT: - case REG_CHAN1ATT: - case REG_CHAN2ATT: - case REG_NOISEATT: - tandy.volume[tandy.reg>>1]=vol_table[val&15]; - if (tandy.volume[0] || tandy.volume[1] || tandy.volume[2] || tandy.volume[3]) { - MIXER_Enable(tandy_chan,true); - } else { - MIXER_Enable(tandy_chan,false); - } - break; - default: -// LOG_WARN("TANDY:Illegal register %d selected",tandy.reg); - break; - } - } else { -/* Dual byte command */ - switch (tandy.reg) { -#define MAKE_ADD(DIV)(Bit32u)((2 << BIT_SHIFT)/((float)TANDY_RATE/((float)TANDY_DIV/(float)DIV))); - case REG_CHAN0DIV: - case REG_CHAN1DIV: - case REG_CHAN2DIV: - tandy.chan[tandy.reg>>1].div|=(val & 63)<<4; - tandy.chan[tandy.reg>>1].freq_add=MAKE_ADD(tandy.chan[tandy.reg>>1].div); -// tandy.chan[tandy.reg>>1].freq_pos=0; - break; - default: - LOG(LOG_ALL,LOG_ERROR)("TANDY:Illegal dual byte reg %d",tandy.reg); - }; + tandy.last_write=PIC_Ticks; + if (!tandy.enabled) { + MIXER_Enable(tandy.chan,true); + tandy.enabled=true; } + /* update the output buffer before changing the registers */ + + if (data & 0x80) + { + int r = (data & 0x70) >> 4; + int c = r/2; + + R->LastRegister = r; + R->Register[r] = (R->Register[r] & 0x3f0) | (data & 0x0f); + switch (r) + { + case 0: /* tone 0 : frequency */ + case 2: /* tone 1 : frequency */ + case 4: /* tone 2 : frequency */ + R->Period[c] = R->UpdateStep * R->Register[r]; + if (R->Period[c] == 0) R->Period[c] = R->UpdateStep; + if (r == 4) + { + /* update noise shift frequency */ + if ((R->Register[6] & 0x03) == 0x03) + R->Period[3] = 2 * R->Period[2]; + } + break; + case 1: /* tone 0 : volume */ + case 3: /* tone 1 : volume */ + case 5: /* tone 2 : volume */ + case 7: /* noise : volume */ + R->Volume[c] = R->VolTable[data & 0x0f]; + break; + case 6: /* noise : frequency, mode */ + { + int n = R->Register[6]; + R->NoiseFB = (n & 4) ? FB_WNOISE : FB_PNOISE; + n &= 3; + /* N/512,N/1024,N/2048,Tone #3 output */ + R->Period[3] = (n == 3) ? 2 * R->Period[2] : (R->UpdateStep << (5+n)); + + /* reset noise shifter */ + R->RNG = NG_PRESET; + R->Output[3] = R->RNG & 1; + } + break; + } + } + else + { + int r = R->LastRegister; + int c = r/2; + + switch (r) + { + case 0: /* tone 0 : frequency */ + case 2: /* tone 1 : frequency */ + case 4: /* tone 2 : frequency */ + R->Register[r] = (R->Register[r] & 0x0f) | ((data & 0x3f) << 4); + R->Period[c] = R->UpdateStep * R->Register[r]; + if (R->Period[c] == 0) R->Period[c] = R->UpdateStep; + if (r == 4) + { + /* update noise shift frequency */ + if ((R->Register[6] & 0x03) == 0x03) + R->Period[3] = 2 * R->Period[2]; + } + break; + } + } } -static void TANDYSOUND_CallBack(Bit8u * stream,Bit32u len) { - for (Bit32u i=0;i=(2 << BIT_SHIFT)) tandy.chan[c].freq_pos-=(2 << BIT_SHIFT); - } - } - /* Generate the noise channel */ - - if (sample>MAX_AUDIO) *(Bit16s *)stream=MAX_AUDIO; - else if (sampleVolume[i] == 0) + { + /* note that I do count += length, NOT count = length + 1. You might think */ + /* it's the same since the volume is 0, but doing the latter could cause */ + /* interferencies when the program is rapidly modulating the volume. */ + if (R->Count[i] <= (int)length*STEP) R->Count[i] += length*STEP; + } + } + + while (length > 0) + { + int vol[4]; + unsigned int out; + int left; + + + /* vol[] keeps track of how long each square wave stays */ + /* in the 1 position during the sample period. */ + vol[0] = vol[1] = vol[2] = vol[3] = 0; + + for (i = 0;i < 3;i++) + { + if (R->Output[i]) vol[i] += R->Count[i]; + R->Count[i] -= STEP; + /* Period[i] is the half period of the square wave. Here, in each */ + /* loop I add Period[i] twice, so that at the end of the loop the */ + /* square wave is in the same status (0 or 1) it was at the start. */ + /* vol[i] is also incremented by Period[i], since the wave has been 1 */ + /* exactly half of the time, regardless of the initial position. */ + /* If we exit the loop in the middle, Output[i] has to be inverted */ + /* and vol[i] incremented only if the exit status of the square */ + /* wave is 1. */ + while (R->Count[i] <= 0) + { + R->Count[i] += R->Period[i]; + if (R->Count[i] > 0) + { + R->Output[i] ^= 1; + if (R->Output[i]) vol[i] += R->Period[i]; + break; + } + R->Count[i] += R->Period[i]; + vol[i] += R->Period[i]; + } + if (R->Output[i]) vol[i] -= R->Count[i]; + } + + left = STEP; + do + { + int nextevent; + + + if (R->Count[3] < left) nextevent = R->Count[3]; + else nextevent = left; + + if (R->Output[3]) vol[3] += R->Count[3]; + R->Count[3] -= nextevent; + if (R->Count[3] <= 0) + { + if (R->RNG & 1) R->RNG ^= R->NoiseFB; + R->RNG >>= 1; + R->Output[3] = R->RNG & 1; + R->Count[3] += R->Period[3]; + if (R->Output[3]) vol[3] += R->Period[3]; + } + if (R->Output[3]) vol[3] -= R->Count[3]; + + left -= nextevent; + } while (left > 0); + + out = vol[0] * R->Volume[0] + vol[1] * R->Volume[1] + + vol[2] * R->Volume[2] + vol[3] * R->Volume[3]; + + if (out > MAX_OUTPUT * STEP) out = MAX_OUTPUT * STEP; + + *(buffer++) = out / STEP; + + length--; + } +} + + + +static void SN76496_set_clock(int clock) +{ + struct SN76496 *R = &sn; + + + /* the base clock for the tone generators is the chip clock divided by 16; */ + /* for the noise generator, it is clock / 256. */ + /* Here we calculate the number of steps which happen during one sample */ + /* at the given sample rate. No. of events = sample rate / (clock/16). */ + /* STEP is a multiplier used to turn the fraction into a fixed point */ + /* number. */ + R->UpdateStep = (unsigned int)(((double)STEP * R->SampleRate * 16) / clock); +} + + + +static void SN76496_set_gain(int gain) +{ + struct SN76496 *R = &sn; + int i; + double out; + + + gain &= 0xff; + + /* increase max output basing on gain (0.2 dB per step) */ + out = MAX_OUTPUT / 3; + while (gain-- > 0) + out *= 1.023292992; /* = (10 ^ (0.2/20)) */ + + /* build volume table (2dB per step) */ + for (i = 0;i < 15;i++) + { + /* limit volume to avoid clipping */ + if (out > MAX_OUTPUT / 3) R->VolTable[i] = MAX_OUTPUT / 3; + else R->VolTable[i] = (int)out; + + out /= 1.258925412; /* = 10 ^ (2/20) = 2dB */ + } + R->VolTable[15] = 0; +} + + + void TANDYSOUND_Init(Section* sec) { Section_prop * section=static_cast(sec); if(!section->Get_bool("tandy")) return; - IO_RegisterWriteHandler(0xc0,write_pc0,"Tandy Sound"); - tandy_chan=MIXER_AddChannel(&TANDYSOUND_CallBack,TANDY_RATE,"TANDY"); - MIXER_Enable(tandy_chan,false); - MIXER_SetMode(tandy_chan,MIXER_16MONO); - /* Calculate the volume table */ - float out=TANDY_VOLUME; - for (Bit32u i=0;i<15;i++) { - vol_table[i]=(Bit32s)out; - out /= (float)1.258925412; /* = 10 ^ (2/20) = 2dB */ + + IO_RegisterWriteHandler(0xc0,SN76496Write,"Tandy Sound"); + + Bit32u sample_rate = section->Get_int("tandyrate"); + tandy.chan=MIXER_AddChannel(&SN76496Update,sample_rate,"TANDY"); + + MIXER_Enable(tandy.chan,false); + tandy.enabled=false; + MIXER_SetMode(tandy.chan,MIXER_16MONO); + + Bitu i; + struct SN76496 *R = &sn; + R->SampleRate = sample_rate; + SN76496_set_clock(2386360); + for (i = 0;i < 4;i++) R->Volume[i] = 0; + R->LastRegister = 0; + for (i = 0;i < 8;i+=2) + { + R->Register[i] = 0; + R->Register[i + 1] = 0x0f; /* volume = 0 */ } - vol_table[15]=0; - /* Setup a byte for tandy detection */ - real_writeb(0xffff,0xe,0xfd); + + for (i = 0;i < 4;i++) + { + R->Output[i] = 0; + R->Period[i] = R->Count[i] = R->UpdateStep; + } + R->RNG = NG_PRESET; + R->Output[3] = R->RNG & 1; + SN76496_set_gain(0x1); } From e2428843545a5189487e9c27b2eda8d1a1c4debc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 10 Oct 2003 09:21:35 +0000 Subject: [PATCH 1227/4131] Added patch from Srecko Morovic Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1307 --- src/shell/shell_misc.cpp | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index f7d78f27..c688f83c 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.25 2003-09-21 13:30:25 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.26 2003-10-10 09:21:35 qbix79 Exp $ */ #include #include @@ -293,21 +293,52 @@ void DOS_Shell::Execute(char * name,char * args) { WriteOut(MSG_Get("SHELL_EXECUTE_ILLEGAL_COMMAND"),name); return; } - + char* extension =strrchr(fullname,'.'); /*always disallow files without extension from being executed. */ /*only internal commands can be run this way and they never get in this handler */ if(extension == 0) { - WriteOut(MSG_Get("SHELL_EXECUTE_ILLEGAL_COMMAND"),fullname); - return; + char temp_name[256],* temp_fullname; + //try to add .com, .exe and .bat extensions to filename + + strcpy(temp_name,fullname); + strcat(temp_name,".COM"); + temp_fullname=Which(temp_name); + if (temp_fullname) { extension=".com";strcpy(fullname,temp_fullname); } + + else + { + strcpy(temp_name,fullname); + strcat(temp_name,".EXE"); + temp_fullname=Which(temp_name); + if (temp_fullname) { extension=".exe";strcpy(fullname,temp_fullname);} + + else + { + strcpy(temp_name,fullname); + strcat(temp_name,".BAT"); + temp_fullname=Which(temp_name); + if (temp_fullname) { extension=".bat";strcpy(fullname,temp_fullname);} + + else + { + WriteOut(MSG_Get("SHELL_EXECUTE_ILLEGAL_COMMAND"),fullname); + return; + } + + } + } } + if (strcasecmp(extension, ".bat") == 0) { /* Run the .bat file */ /* delete old batch file if call is not active*/ + bool temp_echo=echo; /*keep the current echostate (as delete bf might change it )*/ if(bf && !call) delete bf; bf=new BatchFile(this,fullname,line); + echo=temp_echo; //restore it. } else { /* only .bat .exe .com extensions maybe be executed by the shell */ From bc9a5537839f5022694c1bca17a0138bb68d591c Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 10 Oct 2003 13:50:34 +0000 Subject: [PATCH 1228/4131] fixed bug in dos_openfile (removed assignment of *entry out of if statement) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1308 --- src/dos/dos_files.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 6402fe2d..82dace06 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.46 2003-10-09 13:47:44 finsterr Exp $ */ +/* $Id: dos_files.cpp,v 1.47 2003-10-10 13:50:34 finsterr Exp $ */ #include #include @@ -391,7 +391,10 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { if (!device) exists=Drives[drive]->FileOpen(&Files[handle],fullname,flags); if (exists || device ) { // devices can only be opened once - if (device && ((*entry=psp.FindEntryByHandle(handle))!=0xff)) return true; + if (device && (psp.FindEntryByHandle(handle)!=0xff)) { + *entry=psp.FindEntryByHandle(handle); + return true; + } Files[handle]->AddRef(); psp.SetFileHandle(*entry,handle); return true; From a870f5d6cf86c9aaf4b3748d25598d5a2b3f7d20 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 11 Oct 2003 10:02:47 +0000 Subject: [PATCH 1229/4131] EMMS instruction after the mmx scale2x Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1309 --- src/gui/render_scale2x.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/render_scale2x.h b/src/gui/render_scale2x.h index 2cc1547b..0f98a225 100644 --- a/src/gui/render_scale2x.h +++ b/src/gui/render_scale2x.h @@ -495,6 +495,8 @@ static __inline__ void scale2x_8_mmx_single(scale2x_uint8* dst, const scale2x_ui "movq %%mm2,(%3)\n" "movq %%mm3,8(%3)\n" + "emms" + : "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count) : : "cc" From b79e8b1a5281fb94223ec994370919668771c645 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 11 Oct 2003 12:16:35 +0000 Subject: [PATCH 1230/4131] fixed bug in delete. (Slor) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1310 --- src/shell/shell_cmds.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index a4badc92..ab62f079 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.28 2003-09-24 19:36:14 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.29 2003-10-11 12:16:35 qbix79 Exp $ */ #include @@ -110,7 +110,7 @@ void DOS_Shell::CMD_DELETE(char * args) { StripSpaces(args); if (!DOS_Canonicalize(args,full)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH"));return; } //TODO Maybe support confirmation for *.* like dos does. - bool res=DOS_FindFirst(args,0xff); + bool res=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME); if (!res) { WriteOut(MSG_Get("SHELL_CMD_DEL_ERROR"),args);return; } @@ -564,4 +564,5 @@ void DOS_Shell::CMD_CALL(char * args){ this->call=true; /* else the old batchfile will be closed first */ this->ParseLine(args); this->call=false; -} \ No newline at end of file +} + From 7b27e666f2a4868ea580735c77e396b4580ac40f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 12 Oct 2003 18:28:54 +0000 Subject: [PATCH 1231/4131] Nicht Sehr Gut's Comments added Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1311 --- README | 41 +++++++++++++++++++++++++++++++---------- docs/dosbox.1 | 24 ++++++++++++++++++------ 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/README b/README index 2ebb8cd8..057f3dbc 100644 --- a/README +++ b/README @@ -5,8 +5,8 @@ NOTE: ===== While we hope that, one day, DosBox will run virtually all programs -ever made for the PC...we are not there yet. At present, DosBox run on a 1 -Gigahertz PC is roughly the equivalent of a 16MHz 386 PC. While the 0.60 +ever made for the PC...we are not there yet. At present, DosBox run on a 1.7 +Gigahertz PC is roughly the equivalent of a 25MHz 386 PC. While the 0.60 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 @@ -62,17 +62,20 @@ Internal Programs: dosbox supports most of the DOS commands found in command.com. In addition, the following commands are available: -MOUNT Driveletter sourcedirectory [-t type] [-aspi] [-ioctl] - [-usecd number] [-size drivesize] [-label drivelabel] +MOUNT "Emulated Drive letter" "Real Drive or Directory" + [-t type] [-aspi] [-ioctl] [-usecd number] [-size drivesize] + [-label drivelabel] MOUNT -cd Program to mount local directories as drives inside DOSBox. - Driveletter + "Emulated Drive letter" The driveletter inside dosbox (eg. C). - sourcedirectory + "Real Drive letter or Directory" The local directory you want to have inside dosbox. + (Under Win32 usually the same as "Emulated Drive letter". + For Example: mount c c:\ ) -t type Type of the mounted directory. Supported are: dir (standard), @@ -104,7 +107,19 @@ MOUNT -cd Note: It's possible to mount a local directory as cdrom drive. Hardware support is then missing. - Examples: + Basically, MOUNT allows you to connect real hardware to DosBox's "emulated" + PC. So MOUNT C C:\ tells DosBox to use your real C: drive as drive C: in + DosBox. It also allows you to change the drive's letter identification for + programs that demand specific drive letters. + + For example: Touche: Adventures of The Fifth Musketeer must be run on your C: + drive. Using DosBox and it's mount command, you can trick into thinking it + is on C drive while placing it where you want it. For example, if the game + were in D:\TOUCHE, you can use the command MOUNT C D:\ would allow you to + run Touche from the D drive. + + + General MOUNT Examples: 1. To mount c:\floppy as a floppy : mount a c:\floppy -t floppy 2. To mount system cdrom drive E as cdrom drive D in dosbox: @@ -114,7 +129,9 @@ MOUNT -cd mount d /media/cdrom -t cdrom -usecd 0 4. To mount a drive with 870 mb free diskspace (rarely needed! experts only): mount c d:\ -size 4025,127,16513,1700 - + 5. to mount /home/dos/dosgames as drive C in dosbox: + mount c /home/dos/dosgames + MEM Program to display the amount of free memory. @@ -157,8 +174,12 @@ CTRL-F7 Decrease frameskip. CTRL-F8 Increase frameskip. CTRL-F9 Kill dosbox. CTRL-F10 Capture/Release the mouse. -CTRL-F11 Slow down emulation. -CTRL-F12 Speed up emulation. +CTRL-F11 Slow down emulation (Decrease DOSBox Cycles). +CTRL-F12 Speed up emulation (Increase DOSox Cycles). + +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. ==================== System requirements: diff --git a/docs/dosbox.1 b/docs/dosbox.1 index 313dc2ba..a140290c 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -86,6 +86,13 @@ Forces to use SDL cdrom support for drive number. .B \-cd .RB "Displays all detected cdrom drives and their numbers. Use with " \-usecd "." .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 @@ -136,9 +143,14 @@ Kill dosbox. .IP CTRL\-F10 Capture/Release the mouse. .IP CTRL\-F11 -Slow down emulation. +Slow down emulation (Increase DOSBox Cycles). .IP CTRL\-F12 -Speed up emulation. +Speed up emulation (Decrease DOSBox Cycles). +.PP +.B "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. @@ -147,7 +159,7 @@ 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" +.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" @@ -157,17 +169,17 @@ So: .PP .RB "Close every program but " dosbox . .PP -.RB "Overclock " dosbox " until 100% of your CPU is used.(CTRL+F12)" +.RB "Overclock " dosbox " until 100% of your CPU is used.(CTR\-+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 CRTL+F8. Your CPU usage should decrease. +increments of one) by pressing CRTL\-F8. Your CPU usage should decrease. Go back one step and repeat this until the game runs fast enough for you. Please note that this is a trade off: you lose in fluidity of video what you gain in speed. .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 Gigahertz PC is roughly the equivalent of a 16MHz 386 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 From 55591a56da1e001ffbac8636de84b46dd124be84 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 13 Oct 2003 19:44:47 +0000 Subject: [PATCH 1232/4131] no message Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1312 --- include/callback.h | 2 +- src/cpu/core_16/main.h | 8 +- src/cpu/core_full/load.h | 8 +- src/debug/debug.cpp | 192 ++++++++++++++++++++++++++++++++-- src/debug/debug_gui.cpp | 2 +- src/dos/dos.cpp | 14 ++- src/dos/dos_ioctl.cpp | 3 +- src/dosbox.cpp | 8 +- src/gui/sdlmain.cpp | 6 +- src/hardware/dma.cpp | 2 +- src/hardware/iohandler.cpp | 4 +- src/hardware/memory.cpp | 17 ++- src/hardware/timer.cpp | 4 +- src/ints/dpmi.cpp | 4 +- src/ints/ems.cpp | 1 + src/ints/xms.cpp | 3 +- src/platform/visualc/config.h | 4 +- src/shell/shell_cmds.cpp | 5 +- 18 files changed, 246 insertions(+), 41 deletions(-) diff --git a/include/callback.h b/include/callback.h index 9b083be6..1a1a3d6f 100644 --- a/include/callback.h +++ b/include/callback.h @@ -24,7 +24,7 @@ typedef Bitu (*CallBack_Handler)(void); extern CallBack_Handler CallBack_Handlers[]; -enum { CB_RETF,CB_IRET,CB_IRET_STI }; +enum { CB_RETF,CB_IRET,CB_IRET_STI,CB_IRET_ONLY }; #define CB_MAX 1024 #define CB_SEG 0xC800 diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 1bda6241..948ac46e 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -1091,10 +1091,14 @@ restart: flags.type=t_CF; break; case 0xfa: /* CLI */ - SETFLAGBIT(IF,false); +// if (DPMI_IsActive()) DPMI_SetVirtualIntFlag(false); +// else + SETFLAGBIT(IF,false); break; case 0xfb: /* STI */ - SETFLAGBIT(IF,true); +// if (DPMI_IsActive()) DPMI_SetVirtualIntFlag(true); +// else + SETFLAGBIT(IF,true); #ifdef CPU_PIC_CHECK if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; #endif diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index b0adcce4..9866be0e 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -368,10 +368,14 @@ l_M_Ed: else reg_edx=0; goto nextopcode; case D_CLI: - SETFLAGBIT(IF,false); +// if (DPMI_IsActive()) DPMI_SetVirtualIntFlag(false); +// else + SETFLAGBIT(IF,false); goto nextopcode; case D_STI: - SETFLAGBIT(IF,true); +// if (DPMI_IsActive()) DPMI_SetVirtualIntFlag(true); +// else + SETFLAGBIT(IF,true); if (GETFLAG(IF) && PIC_IRQCheck) { LEAVECORE; return CBRET_NONE; diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index ba746325..fa7b762c 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -369,6 +369,14 @@ bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue) } else ignoreAddressOnce = 0; + // TEMP + static bool once = false; + if (!once) { + if ((intNr==0x21) && (reg_ah==0x3f) && (reg_cx==8450)) { + once = true; + return true; + } + } // Search matching breakpoint std::list::iterator i; CBreakpoint* bp; @@ -629,8 +637,10 @@ static void DrawRegisters(void) { oldflags=flags.word; - if (cpu.pmode) mvwprintw(dbg.win_reg,0,76,"Prot"); - else mvwprintw(dbg.win_reg,0,76,"Real"); + if (cpu.pmode) { + if (cpu.code.big) mvwprintw(dbg.win_reg,0,76,"Pr32"); + else mvwprintw(dbg.win_reg,0,76,"Pr16"); + } else mvwprintw(dbg.win_reg,0,76,"Real"); // Selector info, if available if ((cpu.pmode) && curSelectorName[0]) { @@ -877,6 +887,13 @@ bool ParseCommand(char* str) return true; } + found = strstr(str,"SR "); + if (found) { // Set register value + found+=2; + if (ChangeRegister(found)) DEBUG_ShowMsg("DEBUG: Set Register success."); + else DEBUG_ShowMsg("DEBUG: Set Register failure."); + return true; + } found = strstr(str,"BP "); if (found) { // Add new breakpoint found+=3; @@ -958,13 +975,6 @@ bool ParseCommand(char* str) DEBUG_ShowMsg("DEBUG: Logfile LOGCPU.TXT created."); return true; } - found = strstr(str,"SR "); - if (found) { // Set register value - found+=2; - if (ChangeRegister(found)) DEBUG_ShowMsg("DEBUG: Set Register success."); - else DEBUG_ShowMsg("DEBUG: Set Register failure."); - return true; - } found = strstr(str,"SM "); if (found) { // Set memory with following values found+=3; @@ -1614,7 +1624,7 @@ void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num) #if C_HEAVY_DEBUG -const Bit32u LOGCPUMAX = 20000; +const Bit32u LOGCPUMAX = 100000; static Bit16u logCpuCS [LOGCPUMAX]; static Bit32u logCpuEIP[LOGCPUMAX]; @@ -1669,8 +1679,168 @@ bool DEBUG_HeavyIsBreakpoint(void) skipFirstInstruction = false; return false; } - PhysPt where = SegPhys(cs)+reg_eip; + + static bool once = false; + static Bit8u oldValue = 0; + +/* if (!once && (mem_readb(0x276000)==205)) { + LOG(LOG_MISC,LOG_ERROR)("Changed to 205"); + DEBUG_HeavyWriteLogInstruction(); + once = true; + exitLoop = true; + DEBUG_Enable(); + return true; + } + /* + if (cpu.pmode) { + + if ((SegValue(cs)==0x010F) && (reg_eip==0x45941)) { + LOG(LOG_MISC,LOG_ERROR)("REP MOVSB DS:ESI=%04X:%08X ES:EDI=%04X:%08X ECX=%08X",SegValue(ds),reg_esi,SegValue(es),reg_edi,reg_ecx); + } + + Descriptor desc; + if (cpu.gdt.GetDescriptor(0x10F,desc)) { + Bit8u newValue = mem_readb(desc.GetBase()+0x45941); + if (oldValue!=newValue) { + LOG(LOG_MISC,LOG_ERROR)("Value changed from %02X to %02X",oldValue,newValue); + DEBUG_HeavyWriteLogInstruction(); + once = true; + exitLoop = true; + DEBUG_Enable(); + oldValue = newValue; + return true; + } + }; + }; + + +/* if (!once && cpu.pmode) { +// if (mem_readw(0x779e64+0x2A5A)==0x05d4) { + if (mem_readw(0x74cef0+0x0786)==0x05d4) { + LOG(LOG_MISC,LOG_ERROR)("Compare value set to 0x05d4"); + DEBUG_HeavyWriteLogInstruction(); + once = true; + exitLoop = true; + DEBUG_Enable(); + return true; + } + } + + /* + Descriptor desc; + if (!once && cpu.gdt.GetDescriptor(0x43c,desc)) { +// if (mem_readw(desc.GetBase()+0x97B4)==0x018C) { + if (mem_readw(desc.GetBase()+0x2E10)==0x0000) { + LOG(LOG_MISC,LOG_ERROR)("Index set ot 0x018C"); + //once = true; + mem_writew(desc.GetBase()+0x2E10,0x0010); + exitLoop = true; + DEBUG_Enable(); + return true; + }; + } + } + +/* static Bitu lastval = 0; +// if (mem_readd(0x11F000+0xB856)!=lastval) { + if (mem_readd(0x11F000)!=lastval) { +// lastval = mem_readd(0x11F000+0xB856); + lastval = mem_readd(0x11F000); + LOG(LOG_MISC,LOG_ERROR)("Changed to %08X",lastval); + if (lastval==0) { + DEBUG_HeavyWriteLogInstruction(); + exitLoop = true; + DEBUG_Enable(); + return true; + }; + } + + + if (cpu.pmode) { + if (mem_readd(SegPhys(cs)+reg_eip)==0) { + DEBUG_HeavyWriteLogInstruction(); + exitLoop = true; + DEBUG_Enable(); + return true; + } + } +*/ +/* if (cpu.pmode) { + if ((SegValue(cs)==0x397) && (reg_eip==0x23B)) { + DEBUG_HeavyWriteLogInstruction(); + exitLoop = true; + DEBUG_Enable(); + return true; + } + } +*/ +/* if (cpu.pmode) { + if (mem_readd(0x23602c)==0x00236030) { + DEBUG_HeavyWriteLogInstruction(); + exitLoop = true; + DEBUG_Enable(); + return true; + } + } +*/ +// if (!once && cpu.pmode) { + +/* if (mem_readw(0x007f6904+2)==0xFEF0) { + DEBUG_HeavyWriteLogInstruction(); + exitLoop = true; + DEBUG_Enable(); + once = true; + return true; + }; + +/* Descriptor desc; + if (cpu.gdt.GetDescriptor(0x0514,desc) && desc.saved.seg.p) { +// if (desc.GetBase()!=0) { //6EEC1F1) { + if (mem_readw(desc.GetBase()+0x000095a4)==0x006F) { //6EEC1F1) { + DEBUG_HeavyWriteLogInstruction(); + exitLoop = true; + DEBUG_Enable(); + once = true; + return true; + } + } +/* if ((SegValue(cs)==0x01B) && (reg_eip==0x018C) && (reg_ax==0x0267)) { + DEBUG_HeavyWriteLogInstruction(); + exitLoop = true; + DEBUG_Enable(); + once = true; + return true; + }*/ +/* if ((SegValue(cs)==0x01B) && (reg_eip==0x018C) && (((reg_cx<<16)+reg_dx)==0x20)) { + DEBUG_HeavyWriteLogInstruction(); + exitLoop = true; + DEBUG_Enable(); + once = true; + return true; + }*/ +// } + +/* if (!once && cpu.pmode) { + if ((SegValue(cs)==0x001B) && (reg_eip==0x018C) && (reg_ax==0x0008) && (((reg_cx<<16)+reg_dx)==0x20)) { + DEBUG_HeavyWriteLogInstruction(); + exitLoop = true; + DEBUG_Enable(); + once = true; + return true; + } + } +*/ + +/* if (SegValue(es)==0xFD5D) { + DEBUG_HeavyWriteLogInstruction(); + exitLoop = true; + DEBUG_Enable(); + return true; + }; +*/ + + PhysPt where = SegPhys(cs)+reg_eip; if (CBreakpoint::CheckBreakpoint(SegValue(cs),reg_eip)) { // exitLoop = true; // DEBUG_Enable(); diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 840233ce..9a254378 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -196,7 +196,7 @@ void LOG_StartUp(void) { /* Register the log section */ Section_prop * sect=control->AddSection_prop("log",LOG_Init); - sect->Add_string("logfile",""); + sect->Add_string("logfile","log.txt"); char buf[1024]; for (Bitu i=1;i #include @@ -38,6 +38,8 @@ Bit8u dos_copybuf[0x10000]; static Bitu call_20,call_21,call_25,call_26,call_27,call_28,call_29; static Bitu call_casemap; +void DEBUG_HeavyWriteLogInstruction(void); + void DOS_SetError(Bit16u code) { dos.errorcode=code; } @@ -48,6 +50,8 @@ static Bitu DOS_21Handler(void) { DOS_PSP psp(dos.psp); psp.SetStack(RealMake(SegValue(ss),reg_sp)); + LOG(LOG_MISC,LOG_ERROR)("DOS: Call %04X %04X %04X %04X",reg_ax,reg_bx,reg_cx,reg_dx); + char name1[DOSNAMEBUF+1]; char name2[DOSNAMEBUF+1]; switch (reg_ah) { @@ -270,6 +274,8 @@ static Bitu DOS_21Handler(void) { dos.dta=RealMakeSeg(ds,reg_dx); DOS_PSP psp(dos.psp); psp.SetDTA(dos.dta); + DOS_DTA dta(dos.dta); + LOG(LOG_MISC,LOG_ERROR)("DOS:1A:Set DTA %04X:%04X (ID:%04X)",SegValue(ds),reg_dx,dta.GetDirID()); } break; case 0x25: /* Set Interrupt Vector */ @@ -321,6 +327,7 @@ static Bitu DOS_21Handler(void) { case 0x2f: /* Get Disk Transfer Area */ SegSet16(es,RealSeg(dos.dta)); reg_bx=RealOff(dos.dta); + LOG(LOG_DOSMISC,LOG_ERROR)("DOS:2F:Get DTA: %04X:%04X",SegValue(es),reg_bx); break; case 0x30: /* Get DOS Version */ if (reg_al==0) reg_bh=0xFF; /* Fake Microsoft DOS */ @@ -331,6 +338,7 @@ static Bitu DOS_21Handler(void) { case 0x31: /* Terminate and stay resident */ //TODO First get normal files executing // Important: This service does not set the carry flag! + LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Terminated."); DOS_ResizeMemory(dos.psp,®_dx); DOS_Terminate(true); dos.return_code=reg_al; @@ -527,7 +535,7 @@ static Bitu DOS_21Handler(void) { break; case 0x01: /* Set */ LOG(LOG_MISC,LOG_ERROR)("DOS:Set File Attributes for %s not supported",name1); - CALLBACK_SCF(false); + CALLBACK_SCF(true); break; default: LOG(LOG_MISC,LOG_ERROR)("DOS:0x43:Illegal subfunction %2X",reg_al); @@ -618,6 +626,8 @@ static Bitu DOS_21Handler(void) { case 0x4c: /* EXIT Terminate with return code */ { + DEBUG_HeavyWriteLogInstruction(); + LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Terminated 0x4C."); if (DOS_Terminate(false)) { /* This can't ever return false normally */ } else { diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 73ff3205..aaabd5f6 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.13 2003-09-30 08:56:52 qbix79 Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.14 2003-10-13 19:44:46 finsterr Exp $ */ #include #include "dosbox.h" @@ -28,6 +28,7 @@ bool DOS_IOCTL(void) { Bitu handle;Bit8u drive; if (reg_al<8) { /* call 0-7 use a file handle */ + Bitu what = reg_bx; handle=RealHandle(reg_bx); if (handle>=DOS_FILES) { DOS_SetError(DOSERR_INVALID_HANDLE); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index fb9d96a6..2860e5c1 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -186,7 +186,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&IO_Init); secprop->AddInitFunction(&PAGING_Init); secprop->AddInitFunction(&MEM_Init); - secprop->Add_int("memsize",8); //We Default to 8 mb seems okay for now + secprop->Add_int("memsize",16); //We Default to 8 mb seems okay for now secprop->AddInitFunction(&CALLBACK_Init); secprop->AddInitFunction(&PIC_Init); secprop->AddInitFunction(&PROGRAMS_Init); @@ -198,10 +198,10 @@ void DOSBOX_Init(void) { secprop->Add_int("frameskip",0); secprop->Add_bool("keepsmall",false); secprop->Add_string("snapshots","snaps"); - secprop->Add_string("scaler","none"); + secprop->Add_string("scaler","scale2x"); secprop=control->AddSection_prop("cpu",&CPU_Init); - secprop->Add_int("cycles",1800); + secprop->Add_int("cycles",8000); #if C_FPU secprop->AddInitFunction(&FPU_Init); #endif @@ -270,7 +270,7 @@ void DOSBOX_Init(void) { secprop->Add_hex("comport",2); secprop->Add_int("listenport",23); #endif - + // Mscdex secprop->AddInitFunction(&MSCDEX_Init); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 8a03f647..64d33695 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.45 2003-09-30 08:59:18 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.46 2003-10-13 19:44:46 finsterr Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -284,7 +284,7 @@ static void GUI_StartUp(Section * sec) { Section_prop * section=static_cast(sec); sdl.active=false; sdl.full_screen=false; - sdl.nowait=section->Get_bool("nowait"); + sdl.nowait=false; //section->Get_bool("nowait"); sdl.mouse.locked=false; sdl.mouse.requestlock=false; sdl.mouse.autoenable=section->Get_bool("autolock"); @@ -300,7 +300,7 @@ static void GUI_StartUp(Section * sec) { /* Initialize screen for first time */ GFX_SetSize(640,400,8,0,0,0); SDL_EnableKeyRepeat(250,30); - SDL_EnableUNICODE(1); + SDL_EnableUNICODE(0); /* Get some Keybinds */ KEYBOARD_AddEvent(KBD_f9,KBD_MOD_CTRL,KillSwitch); KEYBOARD_AddEvent(KBD_f10,KBD_MOD_CTRL,CaptureMouse); diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 7a35d16d..7ccd22d0 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -212,7 +212,7 @@ INLINE void ResetDMA8(DMA_CHANNEL * chan) { chan->address=(chan->page << 16)+chan->base_address; chan->current_count=chan->base_count+1; chan->current_address=chan->base_address; - LOG(LOG_DMA,LOG_NORMAL)("Setup at address %X:%X count %X",chan->page<<12,chan->base_address,chan->current_count); +// LOG(LOG_DMA,LOG_NORMAL)("Setup at address %X:%X count %X",chan->page<<12,chan->base_address,chan->current_count); } Bitu DMA_8_Read(Bitu dmachan,Bit8u * buffer,Bitu count) { diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 6e2429eb..48242f78 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -24,7 +24,9 @@ IO_WriteBlock IO_WriteTable[IO_MAX]; void IO_Write(Bitu num,Bit8u val) { if (numnext=memory.block.cur_block; memory.block.cur_block=newblock; @@ -830,6 +836,11 @@ static void MEM_ShutDown(Section * sec) { } } +void MEM_SetRemainingMem(Bitu remaining) +{ + +}; + void MEM_Init(Section * sec) { Bitu i; Section_prop * section=static_cast(sec); diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index e13a65a2..29a6ae7e 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.16 2003-09-01 20:16:59 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.17 2003-10-13 19:44:47 finsterr Exp $ */ #include "dosbox.h" #include "inout.h" @@ -116,7 +116,7 @@ static void write_latch(Bit32u port,Bit8u val) { case 0x00: /* Timer hooked to IRQ 0 */ PIC_RemoveEvents(PIT0_Event); PIC_AddEvent(PIT0_Event,p->micro); - LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,(Bit32u)p->mode); +// LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,(Bit32u)p->mode); break; case 0x02: /* Timer hooked to PC-Speaker */ // LOG(LOG_PIT,"PIT 2 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode); diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index 1f6f8696..21bb050e 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -839,7 +839,7 @@ Bitu DPMI::RealModeCallback(void) reg_eip = RealOff(CALLBACK_RealPointer(callback.rmCallbackReturn)); // call protected mode func SetVirtualIntFlag(false); - SETFLAGBIT(IF,false); +// SETFLAGBIT(IF,false); SETFLAGBIT(TF,false); CPU_Push32(flags.word); CPU_CALL(dpmi.client.bit32,dpmi.rmCallback[num].codeSelector,dpmi.rmCallback[num].codeOffset); @@ -900,7 +900,7 @@ Bitu DPMI::CallRealIRETFrame(void) SegSet16(cs,RealSeg(CALLBACK_RealPointer(callback.rmIntFrameReturn))); reg_ip = RealOff(CALLBACK_RealPointer(callback.rmIntFrameReturn)); SetVirtualIntFlag(false); - SETFLAGBIT(IF,false); +// SETFLAGBIT(IF,false); SETFLAGBIT(TF,false); CPU_CALL(false,newCS,newIP); return 0; diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index de226fd8..68ca79f8 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -438,6 +438,7 @@ static Bit8u MemoryRegion(void) { static Bitu INT67_Handler(void) { Bitu i; + LOG(LOG_MISC,LOG_ERROR)("EMS: Call %04X %04X %04X %04X",reg_ax,reg_bx,reg_cx,reg_dx); switch (reg_ah) { case 0x40: /* Get Status */ reg_ah=EMM_NO_ERROR; diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index f610ef94..3c407157 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -107,6 +107,7 @@ static INLINE bool InvalidHandle(Bitu handle) { Bitu XMS_QueryFreeMemory(Bit16u& largestFree, Bit16u& totalFree) { /* Scan the tree for free memory and find largest free block */ + totalFree=(Bit16u)(MEM_FreeTotal()*4); largestFree=(Bit16u)(MEM_FreeLargest()*4); if (!totalFree) return XMS_OUT_OF_SPACE; @@ -245,7 +246,7 @@ static bool multiplex_xms(void) { }; Bitu XMS_Handler(void) { -// LOG(LOG_MISC,LOG_ERROR)("XMS: CALL %02X",reg_ah); + LOG(LOG_MISC,LOG_ERROR)("XMS: CALL %02X",reg_ah); switch (reg_ah) { case XMS_GET_VERSION: /* 00 */ diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index f05615f0..ef36a1bf 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -3,7 +3,7 @@ #define VERSION "0.60" /* Define to 1 to enable internal debugger, requires libcurses */ -#define C_DEBUG 0 +#define C_DEBUG 1 /* Define to 1 to enable screenshots, requires libpng */ #define C_SSHOT 1 @@ -12,7 +12,7 @@ #define C_MODEM 1 /* Enable some heavy debugging options */ -#define C_HEAVY_DEBUG 0 +#define C_HEAVY_DEBUG 1 /* Enable memory function inlining in */ #define C_CORE_INLINE 0 diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index ab62f079..c419489a 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.29 2003-10-11 12:16:35 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.30 2003-10-13 19:44:47 finsterr Exp $ */ #include @@ -265,7 +265,8 @@ void DOS_Shell::CMD_DIR(char * args) { WriteOut(MSG_Get("SHELL_CMD_DIR_INTRO"),path); DOS_DTA dta(dos.dta); - bool ret=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME); +// bool ret=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME); + bool ret=DOS_FindFirst(args,0xffff); if (!ret) { WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); return; From 5e13e5c0e4f5549a9d684ee133144179a7acfc90 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 13 Oct 2003 22:01:07 +0000 Subject: [PATCH 1233/4131] argh, committed good file... Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1313 --- src/debug/debug.cpp | 192 ++-------------------------------- src/debug/debug_gui.cpp | 2 +- src/dos/dos.cpp | 14 +-- src/dos/dos_ioctl.cpp | 3 +- src/dosbox.cpp | 8 +- src/gui/sdlmain.cpp | 6 +- src/hardware/memory.cpp | 17 +-- src/hardware/timer.cpp | 4 +- src/ints/ems.cpp | 1 - src/ints/xms.cpp | 3 +- src/platform/visualc/config.h | 4 +- src/shell/shell_cmds.cpp | 5 +- 12 files changed, 32 insertions(+), 227 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index fa7b762c..ba746325 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -369,14 +369,6 @@ bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue) } else ignoreAddressOnce = 0; - // TEMP - static bool once = false; - if (!once) { - if ((intNr==0x21) && (reg_ah==0x3f) && (reg_cx==8450)) { - once = true; - return true; - } - } // Search matching breakpoint std::list::iterator i; CBreakpoint* bp; @@ -637,10 +629,8 @@ static void DrawRegisters(void) { oldflags=flags.word; - if (cpu.pmode) { - if (cpu.code.big) mvwprintw(dbg.win_reg,0,76,"Pr32"); - else mvwprintw(dbg.win_reg,0,76,"Pr16"); - } else mvwprintw(dbg.win_reg,0,76,"Real"); + if (cpu.pmode) mvwprintw(dbg.win_reg,0,76,"Prot"); + else mvwprintw(dbg.win_reg,0,76,"Real"); // Selector info, if available if ((cpu.pmode) && curSelectorName[0]) { @@ -887,13 +877,6 @@ bool ParseCommand(char* str) return true; } - found = strstr(str,"SR "); - if (found) { // Set register value - found+=2; - if (ChangeRegister(found)) DEBUG_ShowMsg("DEBUG: Set Register success."); - else DEBUG_ShowMsg("DEBUG: Set Register failure."); - return true; - } found = strstr(str,"BP "); if (found) { // Add new breakpoint found+=3; @@ -975,6 +958,13 @@ bool ParseCommand(char* str) DEBUG_ShowMsg("DEBUG: Logfile LOGCPU.TXT created."); return true; } + found = strstr(str,"SR "); + if (found) { // Set register value + found+=2; + if (ChangeRegister(found)) DEBUG_ShowMsg("DEBUG: Set Register success."); + else DEBUG_ShowMsg("DEBUG: Set Register failure."); + return true; + } found = strstr(str,"SM "); if (found) { // Set memory with following values found+=3; @@ -1624,7 +1614,7 @@ void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num) #if C_HEAVY_DEBUG -const Bit32u LOGCPUMAX = 100000; +const Bit32u LOGCPUMAX = 20000; static Bit16u logCpuCS [LOGCPUMAX]; static Bit32u logCpuEIP[LOGCPUMAX]; @@ -1679,168 +1669,8 @@ bool DEBUG_HeavyIsBreakpoint(void) skipFirstInstruction = false; return false; } - - static bool once = false; - static Bit8u oldValue = 0; - -/* if (!once && (mem_readb(0x276000)==205)) { - LOG(LOG_MISC,LOG_ERROR)("Changed to 205"); - DEBUG_HeavyWriteLogInstruction(); - once = true; - exitLoop = true; - DEBUG_Enable(); - return true; - } - - /* - if (cpu.pmode) { - - if ((SegValue(cs)==0x010F) && (reg_eip==0x45941)) { - LOG(LOG_MISC,LOG_ERROR)("REP MOVSB DS:ESI=%04X:%08X ES:EDI=%04X:%08X ECX=%08X",SegValue(ds),reg_esi,SegValue(es),reg_edi,reg_ecx); - } - - Descriptor desc; - if (cpu.gdt.GetDescriptor(0x10F,desc)) { - Bit8u newValue = mem_readb(desc.GetBase()+0x45941); - if (oldValue!=newValue) { - LOG(LOG_MISC,LOG_ERROR)("Value changed from %02X to %02X",oldValue,newValue); - DEBUG_HeavyWriteLogInstruction(); - once = true; - exitLoop = true; - DEBUG_Enable(); - oldValue = newValue; - return true; - } - }; - }; - - -/* if (!once && cpu.pmode) { -// if (mem_readw(0x779e64+0x2A5A)==0x05d4) { - if (mem_readw(0x74cef0+0x0786)==0x05d4) { - LOG(LOG_MISC,LOG_ERROR)("Compare value set to 0x05d4"); - DEBUG_HeavyWriteLogInstruction(); - once = true; - exitLoop = true; - DEBUG_Enable(); - return true; - } - } - - /* - Descriptor desc; - if (!once && cpu.gdt.GetDescriptor(0x43c,desc)) { -// if (mem_readw(desc.GetBase()+0x97B4)==0x018C) { - if (mem_readw(desc.GetBase()+0x2E10)==0x0000) { - LOG(LOG_MISC,LOG_ERROR)("Index set ot 0x018C"); - //once = true; - mem_writew(desc.GetBase()+0x2E10,0x0010); - exitLoop = true; - DEBUG_Enable(); - return true; - }; - } - } - -/* static Bitu lastval = 0; -// if (mem_readd(0x11F000+0xB856)!=lastval) { - if (mem_readd(0x11F000)!=lastval) { -// lastval = mem_readd(0x11F000+0xB856); - lastval = mem_readd(0x11F000); - LOG(LOG_MISC,LOG_ERROR)("Changed to %08X",lastval); - if (lastval==0) { - DEBUG_HeavyWriteLogInstruction(); - exitLoop = true; - DEBUG_Enable(); - return true; - }; - } - - - if (cpu.pmode) { - if (mem_readd(SegPhys(cs)+reg_eip)==0) { - DEBUG_HeavyWriteLogInstruction(); - exitLoop = true; - DEBUG_Enable(); - return true; - } - } -*/ -/* if (cpu.pmode) { - if ((SegValue(cs)==0x397) && (reg_eip==0x23B)) { - DEBUG_HeavyWriteLogInstruction(); - exitLoop = true; - DEBUG_Enable(); - return true; - } - } -*/ -/* if (cpu.pmode) { - if (mem_readd(0x23602c)==0x00236030) { - DEBUG_HeavyWriteLogInstruction(); - exitLoop = true; - DEBUG_Enable(); - return true; - } - } -*/ -// if (!once && cpu.pmode) { - -/* if (mem_readw(0x007f6904+2)==0xFEF0) { - DEBUG_HeavyWriteLogInstruction(); - exitLoop = true; - DEBUG_Enable(); - once = true; - return true; - }; - -/* Descriptor desc; - if (cpu.gdt.GetDescriptor(0x0514,desc) && desc.saved.seg.p) { -// if (desc.GetBase()!=0) { //6EEC1F1) { - if (mem_readw(desc.GetBase()+0x000095a4)==0x006F) { //6EEC1F1) { - DEBUG_HeavyWriteLogInstruction(); - exitLoop = true; - DEBUG_Enable(); - once = true; - return true; - } - } -/* if ((SegValue(cs)==0x01B) && (reg_eip==0x018C) && (reg_ax==0x0267)) { - DEBUG_HeavyWriteLogInstruction(); - exitLoop = true; - DEBUG_Enable(); - once = true; - return true; - }*/ -/* if ((SegValue(cs)==0x01B) && (reg_eip==0x018C) && (((reg_cx<<16)+reg_dx)==0x20)) { - DEBUG_HeavyWriteLogInstruction(); - exitLoop = true; - DEBUG_Enable(); - once = true; - return true; - }*/ -// } - -/* if (!once && cpu.pmode) { - if ((SegValue(cs)==0x001B) && (reg_eip==0x018C) && (reg_ax==0x0008) && (((reg_cx<<16)+reg_dx)==0x20)) { - DEBUG_HeavyWriteLogInstruction(); - exitLoop = true; - DEBUG_Enable(); - once = true; - return true; - } - } -*/ - -/* if (SegValue(es)==0xFD5D) { - DEBUG_HeavyWriteLogInstruction(); - exitLoop = true; - DEBUG_Enable(); - return true; - }; -*/ - PhysPt where = SegPhys(cs)+reg_eip; + if (CBreakpoint::CheckBreakpoint(SegValue(cs),reg_eip)) { // exitLoop = true; // DEBUG_Enable(); diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 9a254378..840233ce 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -196,7 +196,7 @@ void LOG_StartUp(void) { /* Register the log section */ Section_prop * sect=control->AddSection_prop("log",LOG_Init); - sect->Add_string("logfile","log.txt"); + sect->Add_string("logfile",""); char buf[1024]; for (Bitu i=1;i #include @@ -38,8 +38,6 @@ Bit8u dos_copybuf[0x10000]; static Bitu call_20,call_21,call_25,call_26,call_27,call_28,call_29; static Bitu call_casemap; -void DEBUG_HeavyWriteLogInstruction(void); - void DOS_SetError(Bit16u code) { dos.errorcode=code; } @@ -50,8 +48,6 @@ static Bitu DOS_21Handler(void) { DOS_PSP psp(dos.psp); psp.SetStack(RealMake(SegValue(ss),reg_sp)); - LOG(LOG_MISC,LOG_ERROR)("DOS: Call %04X %04X %04X %04X",reg_ax,reg_bx,reg_cx,reg_dx); - char name1[DOSNAMEBUF+1]; char name2[DOSNAMEBUF+1]; switch (reg_ah) { @@ -274,8 +270,6 @@ static Bitu DOS_21Handler(void) { dos.dta=RealMakeSeg(ds,reg_dx); DOS_PSP psp(dos.psp); psp.SetDTA(dos.dta); - DOS_DTA dta(dos.dta); - LOG(LOG_MISC,LOG_ERROR)("DOS:1A:Set DTA %04X:%04X (ID:%04X)",SegValue(ds),reg_dx,dta.GetDirID()); } break; case 0x25: /* Set Interrupt Vector */ @@ -327,7 +321,6 @@ static Bitu DOS_21Handler(void) { case 0x2f: /* Get Disk Transfer Area */ SegSet16(es,RealSeg(dos.dta)); reg_bx=RealOff(dos.dta); - LOG(LOG_DOSMISC,LOG_ERROR)("DOS:2F:Get DTA: %04X:%04X",SegValue(es),reg_bx); break; case 0x30: /* Get DOS Version */ if (reg_al==0) reg_bh=0xFF; /* Fake Microsoft DOS */ @@ -338,7 +331,6 @@ static Bitu DOS_21Handler(void) { case 0x31: /* Terminate and stay resident */ //TODO First get normal files executing // Important: This service does not set the carry flag! - LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Terminated."); DOS_ResizeMemory(dos.psp,®_dx); DOS_Terminate(true); dos.return_code=reg_al; @@ -535,7 +527,7 @@ static Bitu DOS_21Handler(void) { break; case 0x01: /* Set */ LOG(LOG_MISC,LOG_ERROR)("DOS:Set File Attributes for %s not supported",name1); - CALLBACK_SCF(true); + CALLBACK_SCF(false); break; default: LOG(LOG_MISC,LOG_ERROR)("DOS:0x43:Illegal subfunction %2X",reg_al); @@ -626,8 +618,6 @@ static Bitu DOS_21Handler(void) { case 0x4c: /* EXIT Terminate with return code */ { - DEBUG_HeavyWriteLogInstruction(); - LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Terminated 0x4C."); if (DOS_Terminate(false)) { /* This can't ever return false normally */ } else { diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index aaabd5f6..0f048413 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.14 2003-10-13 19:44:46 finsterr Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.15 2003-10-13 21:56:25 finsterr Exp $ */ #include #include "dosbox.h" @@ -28,7 +28,6 @@ bool DOS_IOCTL(void) { Bitu handle;Bit8u drive; if (reg_al<8) { /* call 0-7 use a file handle */ - Bitu what = reg_bx; handle=RealHandle(reg_bx); if (handle>=DOS_FILES) { DOS_SetError(DOSERR_INVALID_HANDLE); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 2860e5c1..fb9d96a6 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -186,7 +186,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&IO_Init); secprop->AddInitFunction(&PAGING_Init); secprop->AddInitFunction(&MEM_Init); - secprop->Add_int("memsize",16); //We Default to 8 mb seems okay for now + secprop->Add_int("memsize",8); //We Default to 8 mb seems okay for now secprop->AddInitFunction(&CALLBACK_Init); secprop->AddInitFunction(&PIC_Init); secprop->AddInitFunction(&PROGRAMS_Init); @@ -198,10 +198,10 @@ void DOSBOX_Init(void) { secprop->Add_int("frameskip",0); secprop->Add_bool("keepsmall",false); secprop->Add_string("snapshots","snaps"); - secprop->Add_string("scaler","scale2x"); + secprop->Add_string("scaler","none"); secprop=control->AddSection_prop("cpu",&CPU_Init); - secprop->Add_int("cycles",8000); + secprop->Add_int("cycles",1800); #if C_FPU secprop->AddInitFunction(&FPU_Init); #endif @@ -270,7 +270,7 @@ void DOSBOX_Init(void) { secprop->Add_hex("comport",2); secprop->Add_int("listenport",23); #endif - + // Mscdex secprop->AddInitFunction(&MSCDEX_Init); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 64d33695..f3afdbc3 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.46 2003-10-13 19:44:46 finsterr Exp $ */ +/* $Id: sdlmain.cpp,v 1.47 2003-10-13 21:56:53 finsterr Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -284,7 +284,7 @@ static void GUI_StartUp(Section * sec) { Section_prop * section=static_cast(sec); sdl.active=false; sdl.full_screen=false; - sdl.nowait=false; //section->Get_bool("nowait"); + sdl.nowait=section->Get_bool("nowait"); sdl.mouse.locked=false; sdl.mouse.requestlock=false; sdl.mouse.autoenable=section->Get_bool("autolock"); @@ -300,7 +300,7 @@ static void GUI_StartUp(Section * sec) { /* Initialize screen for first time */ GFX_SetSize(640,400,8,0,0,0); SDL_EnableKeyRepeat(250,30); - SDL_EnableUNICODE(0); + SDL_EnableUNICODE(1); /* Get some Keybinds */ KEYBOARD_AddEvent(KBD_f9,KBD_MOD_CTRL,KillSwitch); KEYBOARD_AddEvent(KBD_f10,KBD_MOD_CTRL,CaptureMouse); diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 9d4ed17a..2da66a0c 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -242,20 +242,14 @@ void mem_memcpy(PhysPt dest,PhysPt src,Bitu size) { void MEM_BlockRead(PhysPt pt,void * data,Bitu size) { Bit8u * write=(Bit8u *) data; while (size--) { -// *write++=mem_readb_inline(pt++); - *write = mem_readb(pt); - write++; - pt++; + *write++=mem_readb_inline(pt++); } } void MEM_BlockWrite(PhysPt pt,void * data,Bitu size) { Bit8u * read=(Bit8u *) data; while (size--) { -// mem_writeb_inline(pt++,*read++); - mem_writeb(pt,*read); - pt++; - read++; + mem_writeb_inline(pt++,*read++); } } @@ -816,7 +810,7 @@ HostPt MEM_GetBlockPage(void) { memory.block.cur_page+=4096; } else { AllocBlock * newblock=new AllocBlock; - memset(newblock,0xcd,sizeof(AllocBlock)); //zero new allocated memory + memset(newblock,0,sizeof(AllocBlock)); //zero new allocated memory newblock->next=memory.block.cur_block; memory.block.cur_block=newblock; @@ -836,11 +830,6 @@ static void MEM_ShutDown(Section * sec) { } } -void MEM_SetRemainingMem(Bitu remaining) -{ - -}; - void MEM_Init(Section * sec) { Bitu i; Section_prop * section=static_cast(sec); diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 29a6ae7e..b0529155 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.17 2003-10-13 19:44:47 finsterr Exp $ */ +/* $Id: timer.cpp,v 1.18 2003-10-13 21:57:35 finsterr Exp $ */ #include "dosbox.h" #include "inout.h" @@ -116,7 +116,7 @@ static void write_latch(Bit32u port,Bit8u val) { case 0x00: /* Timer hooked to IRQ 0 */ PIC_RemoveEvents(PIT0_Event); PIC_AddEvent(PIT0_Event,p->micro); -// LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,(Bit32u)p->mode); + LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,(Bit32u)p->mode); break; case 0x02: /* Timer hooked to PC-Speaker */ // LOG(LOG_PIT,"PIT 2 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode); diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 68ca79f8..de226fd8 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -438,7 +438,6 @@ static Bit8u MemoryRegion(void) { static Bitu INT67_Handler(void) { Bitu i; - LOG(LOG_MISC,LOG_ERROR)("EMS: Call %04X %04X %04X %04X",reg_ax,reg_bx,reg_cx,reg_dx); switch (reg_ah) { case 0x40: /* Get Status */ reg_ah=EMM_NO_ERROR; diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 3c407157..f610ef94 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -107,7 +107,6 @@ static INLINE bool InvalidHandle(Bitu handle) { Bitu XMS_QueryFreeMemory(Bit16u& largestFree, Bit16u& totalFree) { /* Scan the tree for free memory and find largest free block */ - totalFree=(Bit16u)(MEM_FreeTotal()*4); largestFree=(Bit16u)(MEM_FreeLargest()*4); if (!totalFree) return XMS_OUT_OF_SPACE; @@ -246,7 +245,7 @@ static bool multiplex_xms(void) { }; Bitu XMS_Handler(void) { - LOG(LOG_MISC,LOG_ERROR)("XMS: CALL %02X",reg_ah); +// LOG(LOG_MISC,LOG_ERROR)("XMS: CALL %02X",reg_ah); switch (reg_ah) { case XMS_GET_VERSION: /* 00 */ diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index ef36a1bf..f05615f0 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -3,7 +3,7 @@ #define VERSION "0.60" /* Define to 1 to enable internal debugger, requires libcurses */ -#define C_DEBUG 1 +#define C_DEBUG 0 /* Define to 1 to enable screenshots, requires libpng */ #define C_SSHOT 1 @@ -12,7 +12,7 @@ #define C_MODEM 1 /* Enable some heavy debugging options */ -#define C_HEAVY_DEBUG 1 +#define C_HEAVY_DEBUG 0 /* Enable memory function inlining in */ #define C_CORE_INLINE 0 diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index c419489a..7c442643 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.30 2003-10-13 19:44:47 finsterr Exp $ */ +/* $Id: shell_cmds.cpp,v 1.31 2003-10-13 22:01:07 finsterr Exp $ */ #include @@ -265,8 +265,7 @@ void DOS_Shell::CMD_DIR(char * args) { WriteOut(MSG_Get("SHELL_CMD_DIR_INTRO"),path); DOS_DTA dta(dos.dta); -// bool ret=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME); - bool ret=DOS_FindFirst(args,0xffff); + bool ret=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME); if (!ret) { WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); return; From c36318f7210934e5df3b2e376085b5336a7b8e44 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 14 Oct 2003 08:38:36 +0000 Subject: [PATCH 1234/4131] correct all unintentional changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1314 --- include/callback.h | 2 +- src/cpu/core_16/main.h | 8 ++------ src/cpu/core_full/load.h | 8 ++------ src/dos/dos.cpp | 2 +- src/dos/dos_ioctl.cpp | 2 +- src/gui/sdlmain.cpp | 2 +- src/hardware/dma.cpp | 2 +- src/hardware/iohandler.cpp | 4 +--- src/hardware/timer.cpp | 2 +- src/ints/dpmi.cpp | 4 ++-- src/shell/shell_cmds.cpp | 2 +- 11 files changed, 14 insertions(+), 24 deletions(-) diff --git a/include/callback.h b/include/callback.h index 1a1a3d6f..9b083be6 100644 --- a/include/callback.h +++ b/include/callback.h @@ -24,7 +24,7 @@ typedef Bitu (*CallBack_Handler)(void); extern CallBack_Handler CallBack_Handlers[]; -enum { CB_RETF,CB_IRET,CB_IRET_STI,CB_IRET_ONLY }; +enum { CB_RETF,CB_IRET,CB_IRET_STI }; #define CB_MAX 1024 #define CB_SEG 0xC800 diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 948ac46e..1bda6241 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -1091,14 +1091,10 @@ restart: flags.type=t_CF; break; case 0xfa: /* CLI */ -// if (DPMI_IsActive()) DPMI_SetVirtualIntFlag(false); -// else - SETFLAGBIT(IF,false); + SETFLAGBIT(IF,false); break; case 0xfb: /* STI */ -// if (DPMI_IsActive()) DPMI_SetVirtualIntFlag(true); -// else - SETFLAGBIT(IF,true); + SETFLAGBIT(IF,true); #ifdef CPU_PIC_CHECK if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; #endif diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 9866be0e..b0adcce4 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -368,14 +368,10 @@ l_M_Ed: else reg_edx=0; goto nextopcode; case D_CLI: -// if (DPMI_IsActive()) DPMI_SetVirtualIntFlag(false); -// else - SETFLAGBIT(IF,false); + SETFLAGBIT(IF,false); goto nextopcode; case D_STI: -// if (DPMI_IsActive()) DPMI_SetVirtualIntFlag(true); -// else - SETFLAGBIT(IF,true); + SETFLAGBIT(IF,true); if (GETFLAG(IF) && PIC_IRQCheck) { LEAVECORE; return CBRET_NONE; diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index b1cceb09..33f99628 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.55 2003-10-13 21:56:25 finsterr Exp $ */ +/* $Id: dos.cpp,v 1.56 2003-10-14 08:38:35 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 0f048413..e6cd9fb0 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.15 2003-10-13 21:56:25 finsterr Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.16 2003-10-14 08:38:35 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index f3afdbc3..db168bf0 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.47 2003-10-13 21:56:53 finsterr Exp $ */ +/* $Id: sdlmain.cpp,v 1.48 2003-10-14 08:38:36 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 7ccd22d0..7a35d16d 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -212,7 +212,7 @@ INLINE void ResetDMA8(DMA_CHANNEL * chan) { chan->address=(chan->page << 16)+chan->base_address; chan->current_count=chan->base_count+1; chan->current_address=chan->base_address; -// LOG(LOG_DMA,LOG_NORMAL)("Setup at address %X:%X count %X",chan->page<<12,chan->base_address,chan->current_count); + LOG(LOG_DMA,LOG_NORMAL)("Setup at address %X:%X count %X",chan->page<<12,chan->base_address,chan->current_count); } Bitu DMA_8_Read(Bitu dmachan,Bit8u * buffer,Bitu count) { diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 48242f78..6e2429eb 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -24,9 +24,7 @@ IO_WriteBlock IO_WriteTable[IO_MAX]; void IO_Write(Bitu num,Bit8u val) { if (num From 828e7113b9509343049fb38720ce7e0dfddbdf5e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 13:12:25 +0000 Subject: [PATCH 1235/4131] Disabled WTF log_msg for now Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1315 --- src/hardware/serialport.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/hardware/serialport.cpp b/src/hardware/serialport.cpp index 120a5603..c2ba4a94 100644 --- a/src/hardware/serialport.cpp +++ b/src/hardware/serialport.cpp @@ -301,7 +301,8 @@ void CSerial::rx_adds(Bit8u * data,Bitu size) { } if (FIFOenabled && (rx_fifo.used < FIFOsize)) return; if (ints.active != INT_RX) raiseint(INT_RX); - } else LOG_MSG("WTF"); + } +// else LOG_MSG("WTF"); } void CSerial::tx_addb(Bit8u data) { @@ -317,7 +318,7 @@ void CSerial::tx_addb(Bit8u data) { raiseint(INT_TX); } } else { - LOG_MSG("tx addb"); +// LOG_MSG("tx addb"); } } @@ -333,7 +334,7 @@ Bit8u CSerial::rx_readb() { else raiseint(INT_RX); return val; } else { - LOG_MSG("WTF rx readb"); +// LOG_MSG("WTF rx readb"); return 0; } } @@ -347,7 +348,7 @@ Bit8u CSerial::tx_readb() { if (FIFOenabled && !tx_fifo.used) raiseint(INT_TX); return val; } else { - LOG_MSG("WTF tx readb"); +// LOG_MSG("WTF tx readb"); return 0; } } From fd18e5929e40feaec6070c411ed8d1104171fadf Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 14:32:34 +0000 Subject: [PATCH 1236/4131] Some more changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1316 --- ChangeLog | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index abeefe83..90cdcdbc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,22 +1,32 @@ 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!) - - added basic support for vidmode 0x7 - rewrote loggingsystem to generate less warnings - - Added dos protected mode interface (dpmi) + - 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 tabcompletion !! - - Added basic fpu support. - - Fixed several bugs with case sensitive filesystems. - - Added more shell commands and improved their behaviour. - - Mouse improvements. - - Real time clock inprovements. + - 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. From ce6e9b42da49b37c8a84547bac4d1588b44d947f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 15:24:21 +0000 Subject: [PATCH 1237/4131] Add some new config file options and renamed some Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1317 --- src/dosbox.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index fb9d96a6..97236020 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -198,7 +198,7 @@ void DOSBOX_Init(void) { secprop->Add_int("frameskip",0); secprop->Add_bool("keepsmall",false); secprop->Add_string("snapshots","snaps"); - secprop->Add_string("scaler","none"); + secprop->Add_string("scaler","normal2x"); secprop=control->AddSection_prop("cpu",&CPU_Init); secprop->Add_int("cycles",1800); @@ -213,7 +213,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("mixer",&MIXER_Init); secprop->Add_bool("nosound",false); - secprop->Add_int("freq",22050); + secprop->Add_int("rate",22050); secprop->Add_int("blocksize",2048); secprop->Add_string("wavedir","waves"); @@ -240,8 +240,6 @@ void DOSBOX_Init(void) { secprop->Add_bool("cms",false); secprop->Add_int("cmsrate",22050); -// secprop=control->AddSection_prop("gus",&GUS_Init); - secprop=control->AddSection_prop("disney",&DISNEY_Init); secprop->Add_bool("enabled",true); @@ -250,6 +248,7 @@ void DOSBOX_Init(void) { secprop->Add_int("pcrate",22050); secprop->AddInitFunction(&TANDYSOUND_Init); secprop->Add_bool("tandy",false); + secprop->Add_int("tandyrate",22050); secprop=control->AddSection_prop("bios",&BIOS_Init); secprop->AddInitFunction(&INT10_Init); From a6e31b665445efcdce8b7d36d1cd57ba0d937f76 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 15:25:21 +0000 Subject: [PATCH 1238/4131] use rate instead of freq Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1318 --- src/hardware/mixer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index aeca9cce..a0062554 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -307,7 +307,7 @@ void MIXER_Init(Section* sec) { MSG_Add("MIXER_CONFIGFILE_HELP","Nothing to setup yet!\n"); Section_prop * section=static_cast(sec); /* Read out config section */ - mixer.freq=section->Get_int("freq"); + mixer.freq=section->Get_int("rate"); mixer.nosound=section->Get_bool("nosound"); mixer.blocksize=section->Get_int("blocksize"); mixer.wave.dir=section->Get_string("wavedir"); From b2538dc0ca8cf98b4408099b32cfcdd85e0d08fd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 15:27:22 +0000 Subject: [PATCH 1239/4131] Work around for 24 bpp display depth Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1319 --- src/gui/sdlmain.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index db168bf0..86fb3dce 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.48 2003-10-14 08:38:36 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.49 2003-10-14 15:27:22 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -96,14 +96,24 @@ static void ResetScreen(void) { GFX_Stop(); if (sdl.full_screen) { if (sdl.flags & GFX_SHADOW) { + withshadow: /* TODO Maybe allocate a shadow surface and blit yourself and do real double buffering too */ sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_SWSURFACE|SDL_FULLSCREEN); } else { + Bitu test_bpp=SDL_VideoModeOK(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN|SDL_DOUBLEBUF); + if (test_bpp != sdl.bpp) + goto withshadow; sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN|SDL_DOUBLEBUF); } } else { - if (sdl.flags & GFX_FIXED_BPP) sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE); - else sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,0,SDL_HWSURFACE); + if (sdl.flags & GFX_FIXED_BPP) { + withfixed: + sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE); + } else { + sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,0,SDL_HWSURFACE); + if (sdl.surface->format->BitsPerPixel==24) + goto withfixed; + } } if (sdl.surface==0) { E_Exit("SDL:Can't get a surface error:%s.",SDL_GetError()); @@ -298,6 +308,10 @@ static void GUI_StartUp(Section * sec) { sdl.thread=SDL_CreateThread(&SDL_DisplayThread,0); #endif /* Initialize screen for first time */ + sdl.surface=SDL_SetVideoMode(640,400,0,0); + if (sdl.surface->format->BitsPerPixel==32) { + LOG_MSG("SDL:You are running in 24 bpp mode, this will slow down things!"); + } GFX_SetSize(640,400,8,0,0,0); SDL_EnableKeyRepeat(250,30); SDL_EnableUNICODE(1); From 857b872857b50c1c9e3f08eaad92a9e69b86010e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 15:27:39 +0000 Subject: [PATCH 1240/4131] New scaler name and removed keepsmall Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1320 --- src/gui/render.cpp | 53 +++++++++++++++++++++++++++------------- src/gui/render_scale2x.h | 2 +- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 568c7118..5cd0404c 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.16 2003-09-29 21:05:05 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.17 2003-10-14 15:27:39 harekiet Exp $ */ #include #include @@ -38,8 +38,8 @@ struct PalData { Bit8u blue; Bit8u unused; } rgb[256]; - Bitu first; - Bitu last; + volatile Bitu first; + volatile Bitu last; union { Bit32u bpp32[256]; Bit16u bpp16[256]; @@ -82,7 +82,6 @@ static struct { const char * dir; } shot; #endif - bool keep_small; bool screenshot; bool active; } render; @@ -261,7 +260,11 @@ doagain: render.op.dest=render.op.pixels=data; render.src.draw_handler(render.op.part_handler); break; - case OP_Scale2x: + case OP_Blit: + render.op.dest=render.op.pixels=data; + render.src.draw_handler(render.op.part_handler); + break; + case OP_AdvMame2x: render.op.dest=render.op.pixels=data; render.src.draw_handler(render.op.part_handler); break; @@ -292,6 +295,17 @@ static void RENDER_Resize(Bitu * width,Bitu * height) { } } +static void Render_Blit_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags) { + render.op.width=width; + render.op.height=height; + render.op.bpp=bpp; + render.op.pitch=pitch; + render.op.type=OP_Blit; + render.op.part_handler=GFX_Render_Blit; + RENDER_ResetPal(); +} + + void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu flags,RENDER_Draw_Handler draw_handler) { if ((!width) || (!height) || (!pitch)) { render.active=false;return; @@ -323,21 +337,26 @@ normalop: flags=0; break; case DoubleBoth: - if (render.keep_small) { - render.src.flags=0; - flags=0; - } else { - width*=2;height*=2; - flags=GFX_SHADOW; - } + render.src.flags=0; + flags=0; break; } mode_callback=Render_Normal_CallBack; break; - case OP_Scale2x: + case OP_Normal2x: + switch (render.src.flags) { + case DoubleBoth: + width*=2;height*=2; + flags=GFX_SHADOW; + mode_callback=Render_Normal_CallBack; + break; + default: + goto normalop; + } + break; + case OP_AdvMame2x: switch (render.src.flags) { case DoubleBoth: - if (render.keep_small) goto normalop; mode_callback=Render_Scale2x_CallBack; width*=2;height*=2; #if defined (SCALE2X_NORMAL) @@ -373,12 +392,11 @@ static void DecreaseFrameSkip(void) { } void RENDER_Init(Section * sec) { - MSG_Add("RENDER_CONFIGFILE_HELP","Available scalers: scale2x, none\n"); + MSG_Add("RENDER_CONFIGFILE_HELP","Available scalers: none, normal2x, advmame2x\n"); Section_prop * section=static_cast(sec); render.pal.first=256; render.pal.last=0; - render.keep_small=section->Get_bool("keepsmall"); render.frameskip.max=section->Get_int("frameskip"); render.frameskip.count=0; #if (C_SSHOT) @@ -392,7 +410,8 @@ void RENDER_Init(Section * sec) { scaler=section->Get_string("scaler"); } if (!strcasecmp(scaler,"none")) render.op.want_type=OP_None; - else if (!strcasecmp(scaler,"scale2x")) render.op.want_type=OP_Scale2x; + else if (!strcasecmp(scaler,"normal2x")) render.op.want_type=OP_Normal2x; + else if (!strcasecmp(scaler,"advmame2x")) render.op.want_type=OP_AdvMame2x; else { render.op.want_type=OP_None; LOG_MSG("Illegal scaler type %s,falling back to none.",scaler); diff --git a/src/gui/render_scale2x.h b/src/gui/render_scale2x.h index 0f98a225..3b12c35f 100644 --- a/src/gui/render_scale2x.h +++ b/src/gui/render_scale2x.h @@ -538,7 +538,7 @@ static void Render_Scale2x_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,B render.op.height=height; render.op.bpp=bpp; render.op.pitch=pitch; - render.op.type=OP_Scale2x; + render.op.type=OP_AdvMame2x; #if defined(SCALE2X_NORMAL) switch (bpp) { case 8: From 02f0a367f8f3e864e0bacba543db5aa14c27579a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 15:28:14 +0000 Subject: [PATCH 1241/4131] New scaler names Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1321 --- include/render.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/render.h b/include/render.h index 054941c8..2f637088 100644 --- a/include/render.h +++ b/include/render.h @@ -19,8 +19,11 @@ enum RENDER_Operation { - OP_None,OP_Shot, - OP_2xSai,OP_Scale2x, + OP_None, + OP_Shot, + OP_Normal2x, + OP_AdvMame2x, + OP_Blit, }; enum { From 3ce6494b9dc3e40e76f0b148fc75e00c9faeadf6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 15:28:28 +0000 Subject: [PATCH 1242/4131] support for special blit scaler someday Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1322 --- include/video.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/video.h b/include/video.h index a7304ffa..33997cc9 100644 --- a/include/video.h +++ b/include/video.h @@ -34,6 +34,8 @@ struct GFX_PalEntry { #define GFX_FIXED_BPP 0x01 #define GFX_RESIZEABLE 0x02 #define GFX_SHADOW 0x04 +#define GFX_BLITTING 0x08 + #define MODE_SET 0x01 @@ -50,6 +52,8 @@ void GFX_Start(void); void GFX_Stop(void); void GFX_SwitchFullScreen(void); +void GFX_Render_Blit(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy); + void GFX_DoUpdate(void); #endif From 49c6f278306242b72256165fd5771c3777b819d3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 15:29:04 +0000 Subject: [PATCH 1243/4131] remove keepsmall Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1323 --- src/dosbox.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 97236020..b1386151 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -196,7 +196,6 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("render",&RENDER_Init); secprop->Add_int("frameskip",0); - secprop->Add_bool("keepsmall",false); secprop->Add_string("snapshots","snaps"); secprop->Add_string("scaler","normal2x"); From fea163586739328f904f21d857bcfa07aaaba9ff Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 15:38:57 +0000 Subject: [PATCH 1244/4131] Change lfb base message to a debug one Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1324 --- src/hardware/memory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 2da66a0c..e91b9d55 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -377,7 +377,7 @@ void MEM_AllocLinkMemory(PageEntry * theentry) { void MEM_SetLFB(Bitu page,Bitu pages,HostPt pt) { if (pages>LFB_PAGES) E_Exit("MEM:LFB to large"); - LOG_MSG("LFB Base at address %X,page %X",page*4096,page); + LOG(LOG_PAGING,LOG_NORMAL)("LFB Base at address %X,page %X",page*4096,page); memory.lfb.pages=pages; memory.lfb.start_page=page; memory.lfb.end_page=page+pages; From 91fa140b2c9f342c4cf1ad3181c6d1cd4c7bde14 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 20:25:32 +0000 Subject: [PATCH 1245/4131] Exit with unhandled opcode if not running debug version Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1325 --- src/cpu/core_normal.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 73522a22..c7c77f73 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -181,7 +181,11 @@ restart_opcode: #include "core_normal/prefix_66_0f.h" default: ADDIPFAST(-1); +#if C_DEBUG LOG_MSG("Unhandled code %X",core.opcode_index+Fetchb()); +#else + E_Exit("Unhandled CPU opcode"); +#endif } } decode_end: From 22643f6858872ddc52eada5dcc0a030795c137c2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 20:39:36 +0000 Subject: [PATCH 1246/4131] Removed errorlevel, always show exit error Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1326 --- include/dosbox.h | 2 -- src/dosbox.cpp | 6 ------ src/misc/support.cpp | 22 ++++++++-------------- 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/include/dosbox.h b/include/dosbox.h index 789aa646..4d7507ff 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -59,8 +59,6 @@ void DOSBOX_Init(void); class Config; extern Config * control; -extern Bitu errorlevel; - #ifndef __LOGGING_H_ #include "logging.h" diff --git a/src/dosbox.cpp b/src/dosbox.cpp index b1386151..77f1ebce 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -38,7 +38,6 @@ #include "support.h" Config * control; -Bitu errorlevel=1; /* The whole load of startups for all the subfunctions */ void MSG_Init(Section_prop *); @@ -159,7 +158,6 @@ void DOSBOX_RunMachine(void){ static void DOSBOX_RealInit(Section * sec) { Section_prop * section=static_cast(sec); /* Initialize some dosbox internals */ - errorlevel=section->Get_int("warnings"); MSG_Add("DOSBOX_CONFIGFILE_HELP","General Dosbox settings\n"); RemainTicks=0;LastTicks=GetTicks(); DOSBOX_SetLoop(&Normal_Loop); @@ -177,12 +175,8 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit); secprop->Add_string("language",""); #if C_DEBUG - secprop->Add_int("warnings",4); LOG_StartUp(); -#else - secprop->Add_int("warnings",0); #endif - secprop->AddInitFunction(&IO_Init); secprop->AddInitFunction(&PAGING_Init); secprop->AddInitFunction(&MEM_Init); diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 54e5e228..2f361783 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.19 2003-09-30 08:58:10 qbix79 Exp $ */ +/* $Id: support.cpp,v 1.20 2003-10-14 20:39:02 harekiet Exp $ */ #include #include @@ -159,20 +159,14 @@ char * StripWord(char * cmd) { static char buf[1024]; //greater scope as else it doesn't always gets thrown right (linux/gcc2.95) void E_Exit(char * format,...) { -#if C_DEBUG -#if C_HEAVY_DEBUG +#if C_DEBUG && C_HEAVY_DEBUG DEBUG_HeavyWriteLogInstruction(); #endif -#endif - if(errorlevel>=1) { - va_list msg; - va_start(msg,format); - vsprintf(buf,format,msg); - va_end(msg); - - strcat(buf,"\n"); - } else { - strcpy(buf,"an unsupported feature\n"); - } + va_list msg; + va_start(msg,format); + vsprintf(buf,format,msg); + va_end(msg); + strcat(buf,"\n"); + throw(buf); } From 36e7c16b48f2f16f19b5f8a41f51526b517f85f6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 20:44:15 +0000 Subject: [PATCH 1247/4131] new command line option for win32 for hide console else it'll redirect output to files. Hopefully always show console now with mingw Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1327 --- src/gui/sdlmain.cpp | 58 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 86fb3dce..0e40d5f8 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.49 2003-10-14 15:27:22 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.50 2003-10-14 20:44:15 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -48,6 +48,16 @@ extern char** environ; #endif + +#ifdef WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#define STDOUT_FILE TEXT("stdout.txt") +#define STDERR_FILE TEXT("stderr.txt") +#endif + struct SDL_Block { volatile bool active; //If this isn't set don't draw volatile bool drawing; @@ -57,7 +67,7 @@ struct SDL_Block { Bitu flags; GFX_ModeCallBack mode_callback; bool full_screen; - bool nowait; + bool wait_on_error; SDL_Surface * surface; SDL_Surface * blit_surface; SDL_Joystick * joy; @@ -294,7 +304,7 @@ static void GUI_StartUp(Section * sec) { Section_prop * section=static_cast(sec); sdl.active=false; sdl.full_screen=false; - sdl.nowait=section->Get_bool("nowait"); + sdl.wait_on_error=section->Get_bool("waitonerror"); sdl.mouse.locked=false; sdl.mouse.requestlock=false; sdl.mouse.autoenable=section->Get_bool("autolock"); @@ -309,7 +319,7 @@ static void GUI_StartUp(Section * sec) { #endif /* Initialize screen for first time */ sdl.surface=SDL_SetVideoMode(640,400,0,0); - if (sdl.surface->format->BitsPerPixel==32) { + if (sdl.surface->format->BitsPerPixel==24) { LOG_MSG("SDL:You are running in 24 bpp mode, this will slow down things!"); } GFX_SetSize(640,400,8,0,0,0); @@ -319,6 +329,7 @@ static void GUI_StartUp(Section * sec) { KEYBOARD_AddEvent(KBD_f9,KBD_MOD_CTRL,KillSwitch); KEYBOARD_AddEvent(KBD_f10,KBD_MOD_CTRL,CaptureMouse); KEYBOARD_AddEvent(KBD_enter,KBD_MOD_ALT,SwitchFullScreen); + } void Mouse_AutoLock(bool enable) { @@ -596,7 +607,28 @@ int main(int argc, char* argv[]) { CommandLine com_line(argc,argv); Config myconf(&com_line); control=&myconf; - + + /* Can't disable the console with debugger enabled */ +#if defined(WIN32) && !(C_DEBUG) + if (control->cmdline->FindExist("-noconsole")) { + FreeConsole(); + /* Redirect standard input and standard output */ + freopen(STDOUT_FILE, "w", stdout); + freopen(STDERR_FILE, "w", stderr); + setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* Line buffered */ + setbuf(stderr, NULL); /* No buffering */ + } else { + if (AllocConsole()) { + fclose(stdin); + fclose(stdout); + fclose(stderr); + freopen("CONIN$","w",stdin); + freopen("CONOUT$","w",stdout); + freopen("CONOUT$","w",stderr); + } + } +#endif //defined(WIN32) && !(C_DEBUG) + #if C_DEBUG DEBUG_SetupConsole(); #endif @@ -611,8 +643,9 @@ int main(int argc, char* argv[]) { sdl_sec->Add_bool("fullscreen",false); sdl_sec->Add_bool("autolock",true); sdl_sec->Add_int("sensitivity",100); - sdl_sec->Add_bool("nowait",true); + sdl_sec->Add_bool("waitonerror",true); /* Init all the dosbox subsystems */ + DOSBOX_Init(); std::string config_file; if (control->cmdline->FindString("-conf",config_file,true)) { @@ -645,8 +678,17 @@ int main(int argc, char* argv[]) { } catch (char * error) { if (sdl.full_screen) SwitchFullScreen(); if (sdl.mouse.locked) CaptureMouse(); - LOG_MSG("Exit to error: %sPress enter to continue.",error); - if(!sdl.nowait) fgetc(stdin); + LOG_MSG("Exit to error: %s",error); + if(sdl.wait_on_error) { + //TODO Maybe look for some way to show message in linux? +#if (C_DEBUG) + LOG_MSG("Press enter to continue",error); + fgetc(stdin); +#elif defined(WIN32) + Sleep(5000); +#endif + } + } catch (int){ if (sdl.full_screen) SwitchFullScreen(); From 3fb5978769cef0be15826a3f87997601e3b44088 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 20:55:03 +0000 Subject: [PATCH 1248/4131] add -noconsole info Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1328 --- README | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README b/README index 057f3dbc..4a7d377f 100644 --- a/README +++ b/README @@ -42,6 +42,10 @@ dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] -lang languagefile Start dosbox using the language string specified in "languagefile". + -noconsole (Windows Only) + Start dosbox without showing the console window, output will + be redirected to stdout.txt and stderr.txt + Note: If a name/command/configfile/languagefile contains a space in it, put the whole name/command/configfile/languagefile between quotes("example"). From b1fe464f4f2566d8f16f4729a872ad8d5b16986d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 23:02:32 +0000 Subject: [PATCH 1249/4131] Remove help line and changed option. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1329 --- src/hardware/pcspeaker.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 85a255af..a5361953 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -206,9 +206,8 @@ static void PCSPEAKER_CallBack(Bit8u * stream,Bit32u len) { } void PCSPEAKER_Init(Section* sec) { - MSG_Add("SPEAKER_CONFIGFILE_HELP","PC-Speaker and TandySound options.\n"); Section_prop * section=static_cast(sec); - if(!section->Get_bool("enabled")) return; + if(!section->Get_bool("pcspeaker")) return; spkr.volume=SPKR_VOLUME; spkr.mode=MODE_NONE; spkr.pit_mode=MODE_WAVE; From 57d6fa9b6496bb98f16c2d033823faa020732740 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 23:03:01 +0000 Subject: [PATCH 1250/4131] Removed help line Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1330 --- src/hardware/mixer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index a0062554..f3cc674a 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -304,7 +304,6 @@ static void MIXER_Stop(Section* sec) { void MIXER_Init(Section* sec) { sec->AddDestroyFunction(&MIXER_Stop); - MSG_Add("MIXER_CONFIGFILE_HELP","Nothing to setup yet!\n"); Section_prop * section=static_cast(sec); /* Read out config section */ mixer.freq=section->Get_int("rate"); From fb4053b38ca0aedc3ed9b4dbdf283f55d0e98e1c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 23:03:39 +0000 Subject: [PATCH 1251/4131] Removed help line and changed option. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1331 --- src/hardware/sblaster.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 4b36aac8..fc8f6a44 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -843,9 +843,8 @@ static void SBLASTER_CallBack(Bit8u * stream,Bit32u len) { void SBLASTER_Init(Section* sec) { Bitu i; - MSG_Add("SBLASTER_CONFIGFILE_HELP","Sound Blaster related options.\n"); Section_prop * section=static_cast(sec); - if(!section->Get_bool("enabled")) return; + if(!section->Get_bool("sblaster")) return; sb.chan=MIXER_AddChannel(&SBLASTER_CallBack,22050,"SBLASTER"); MIXER_Enable(sb.chan,false); sb.dsp.state=DSP_S_NORMAL; From a0144ccfa9fcdb15f70062c1dc3a757940b67e43 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 23:30:59 +0000 Subject: [PATCH 1252/4131] Support multiple lines in config file comments. warning fix Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1332 --- src/misc/setup.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 52091726..39785d0d 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -155,7 +155,7 @@ void Section_line::PrintData(FILE* outfile) { } void Config::PrintConfig(const char* configfilename){ - char temp[50]; + char temp[50];char helpline[256]; FILE* outfile=fopen(configfilename,"w+t"); if(outfile==NULL) return; for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ @@ -165,9 +165,20 @@ void Config::PrintConfig(const char* configfilename){ fprintf(outfile,"[%s]\n",temp); upcase(temp); strcat(temp,"_CONFIGFILE_HELP"); - fprintf(outfile,"# %s",MSG_Get(temp)); + const char * helpstr=MSG_Get(temp); + char * helpwrite=helpline; + while (*helpstr) { + *helpwrite++=*helpstr; + if (*helpstr == '\n') { + *helpwrite=0; + fprintf(outfile,"# %s",helpline); + helpwrite=helpline; + } + helpstr++; + } + fprintf(outfile,"\n"); (*tel)->PrintData(outfile); - fprintf(outfile,"\n"); /* Always an empty line between sections */ + fprintf(outfile,"\n"); /* Always an empty line between sections */ } fclose(outfile); } @@ -313,7 +324,7 @@ bool CommandLine::FindString(char * name,std::string & value,bool remove) { return true; } -bool CommandLine::FindCommand(int which,std::string & value) { +bool CommandLine::FindCommand(unsigned int which,std::string & value) { if (which<1) return false; if (which>cmds.size()) return false; cmd_it it=cmds.begin(); @@ -356,7 +367,7 @@ bool CommandLine::FindStringRemain(char * name,std::string & value) { } -int CommandLine::GetCount(void) { +unsigned int CommandLine::GetCount(void) { return cmds.size(); } From 4fadb16b4785e2e3a64c84c8356657c1dd08207f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 23:31:12 +0000 Subject: [PATCH 1253/4131] warning fix Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1333 --- include/setup.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/setup.h b/include/setup.h index 0aa9bb46..f66b619c 100644 --- a/include/setup.h +++ b/include/setup.h @@ -37,10 +37,10 @@ public: bool FindHex(char * name,int & value,bool remove=false); bool FindInt(char * name,int & value,bool remove=false); bool FindString(char * name,std::string & value,bool remove=false); - bool FindCommand(int which,std::string & value); + bool FindCommand(unsigned int which,std::string & value); bool FindStringBegin(char * begin,std::string & value, bool remove=false); bool FindStringRemain(char * name,std::string & value); - int GetCount(void); + unsigned int GetCount(void); private: typedef std::list::iterator cmd_it; std::list cmds; From 77dda34be0503570dde0c6d674c252bcc82ae4a7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 23:32:32 +0000 Subject: [PATCH 1254/4131] Remove help line and change an option Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1334 --- src/gui/midi.cpp | 1 - src/gui/render.cpp | 5 ++--- src/gui/sdlmain.cpp | 11 +++++++++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 5530ce17..8145d7bc 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -148,7 +148,6 @@ bool MIDI_Available(void) { void MIDI_Init(Section * sec) { Section_prop * section=static_cast(sec); - MSG_Add("MIDI_CONFIGFILE_HELP","Set midi output device,alsa,oss,win32,coreaudio,none\n"); const char * dev=section->Get_string("device"); const char * conf=section->Get_string("config"); /* If device = "default" go for first handler that works */ diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 5cd0404c..4db420f5 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.17 2003-10-14 15:27:39 harekiet Exp $ */ +/* $Id: render.cpp,v 1.18 2003-10-14 23:32:32 harekiet Exp $ */ #include #include @@ -392,7 +392,6 @@ static void DecreaseFrameSkip(void) { } void RENDER_Init(Section * sec) { - MSG_Add("RENDER_CONFIGFILE_HELP","Available scalers: none, normal2x, advmame2x\n"); Section_prop * section=static_cast(sec); render.pal.first=256; @@ -400,7 +399,7 @@ void RENDER_Init(Section * sec) { render.frameskip.max=section->Get_int("frameskip"); render.frameskip.count=0; #if (C_SSHOT) - render.shot.dir=section->Get_string("snapshots"); + render.shot.dir=section->Get_string("snapdir"); KEYBOARD_AddEvent(KBD_f5,KBD_MOD_CTRL,EnableScreenShot); #endif const char * scaler;std::string cline; diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 0e40d5f8..22b5a696 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.50 2003-10-14 20:44:15 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.51 2003-10-14 23:32:32 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -299,7 +299,6 @@ static void KillSwitch(void){ } static void GUI_StartUp(Section * sec) { - MSG_Add("SDL_CONFIGFILE_HELP","SDL related options.\n"); sec->AddDestroyFunction(&GUI_ShutDown); Section_prop * section=static_cast(sec); sdl.active=false; @@ -645,6 +644,14 @@ int main(int argc, char* argv[]) { sdl_sec->Add_int("sensitivity",100); sdl_sec->Add_bool("waitonerror",true); /* Init all the dosbox subsystems */ + + MSG_Add("SDL_CONFIGFILE_HELP", + "fullscreen -- Start dosbox directly in fullscreen.\n" + "autolock -- Mouse will automatically lock, if you click on the screen.\n" + "sensitiviy -- Mouse sensitivity.\n" + "waitonerror -- Wait before closing the console if dosbox has an error.\n" + ); + DOSBOX_Init(); std::string config_file; From 157e84e2a53c21a51748b1d7be7e3129d92980b9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 23:34:23 +0000 Subject: [PATCH 1255/4131] Direct access to dos variables Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1335 --- src/shell/shell_cmds.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index caceeabe..b9a4d022 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.32 2003-10-14 08:38:36 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.33 2003-10-14 23:34:23 harekiet Exp $ */ #include @@ -41,7 +41,7 @@ static SHELL_Cmd cmd_list[]={ { "RMDIR", 0, &DOS_Shell::CMD_RMDIR, "SHELL_CMD_RMDIR_HELP"}, { "RD", 1, &DOS_Shell::CMD_RMDIR, "SHELL_CMD_RMDIR_HELP"}, { "SET", 0, &DOS_Shell::CMD_SET, "SHELL_CMD_SET_HELP"}, -{ "IF", 0, &DOS_Shell::CMD_IF, "SHELL_CMD_IF_HELP"}, +{ "IF", 0, &DOS_Shell::CMD_IF, "SHELL_CMD_IF_HELP"}, { "GOTO", 0, &DOS_Shell::CMD_GOTO, "SHELL_CMD_GOTO_HELP"}, { "TYPE", 0, &DOS_Shell::CMD_TYPE, "SHELL_CMD_TYPE_HELP"}, { "REM", 0, &DOS_Shell::CMD_REM, "SHELL_CMD_REM_HELP"}, @@ -498,9 +498,7 @@ void DOS_Shell::CMD_IF(char * args) { return; } /* Read the error code from DOS */ - reg_ah=0x4d; - CALLBACK_RunRealInt(0x21); - if ((reg_al>=n) ==(!has_not)) DoCommand(args); + if ((dos.return_code>=n) ==(!has_not)) DoCommand(args); return; } /* Normal if string compare */ From f901c5e096c41a295e5bc8bf6234b61f11b21876 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 23:34:28 +0000 Subject: [PATCH 1256/4131] Remove help line Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1336 --- src/cpu/cpu.cpp | 4 +--- src/dos/dos.cpp | 3 +-- src/shell/shell.cpp | 3 +-- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index f72090f2..9c765aed 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.34 2003-09-30 13:48:20 finsterr Exp $ */ +/* $Id: cpu.cpp,v 1.35 2003-10-14 23:31:51 harekiet Exp $ */ #include #include "dosbox.h" @@ -962,7 +962,5 @@ void CPU_Init(Section* sec) { if (!CPU_CycleMax) CPU_CycleMax=1500; CPU_CycleLeft=0; GFX_SetTitle(CPU_CycleMax,-1); - MSG_Add("CPU_CONFIGFILE_HELP","The amount of cycles to execute each loop. Lowering this setting will slowdown dosbox\n"); - } diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 33f99628..e0959e8d 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.56 2003-10-14 08:38:35 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.57 2003-10-14 23:33:33 harekiet Exp $ */ #include #include @@ -936,7 +936,6 @@ void DOS_ShutDown(Section* sec) void DOS_Init(Section* sec) { - MSG_Add("DOS_CONFIGFILE_HELP","Disabling or enabling DPMI makes a huge difference for protected mode games. Try both!\n"); call_20=CALLBACK_Allocate(); CALLBACK_Setup(call_20,DOS_20Handler,CB_IRET); RealSetVec(0x20,CALLBACK_RealPointer(call_20)); diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 221d46ae..5cf3ddd6 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.35 2003-09-30 19:12:44 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.36 2003-10-14 23:34:28 harekiet Exp $ */ #include #include @@ -212,7 +212,6 @@ void DOS_Shell::SyntaxError(void) { void AUTOEXEC_Init(Section * sec) { - MSG_Add("AUTOEXEC_CONFIGFILE_HELP","Add here the lines you want to execute on startup.\n"); /* Register a virtual AUOEXEC.BAT file */ std::string line; Section_line * section=static_cast(sec); From b7c84d5aff739260270cba2bcdaeac77e128fc93 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 14 Oct 2003 23:42:55 +0000 Subject: [PATCH 1257/4131] Added config file help lines to here and changed some config file options. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1337 --- src/dosbox.cpp | 101 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 83 insertions(+), 18 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 77f1ebce..09311a5a 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -158,7 +158,7 @@ void DOSBOX_RunMachine(void){ static void DOSBOX_RealInit(Section * sec) { Section_prop * section=static_cast(sec); /* Initialize some dosbox internals */ - MSG_Add("DOSBOX_CONFIGFILE_HELP","General Dosbox settings\n"); + RemainTicks=0;LastTicks=GetTicks(); DOSBOX_SetLoop(&Normal_Loop); MSG_Init(section); @@ -166,7 +166,6 @@ static void DOSBOX_RealInit(Section * sec) { void DOSBOX_Init(void) { -// Section * sec; Section_prop * secprop; Section_line * secline; @@ -180,7 +179,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&IO_Init); secprop->AddInitFunction(&PAGING_Init); secprop->AddInitFunction(&MEM_Init); - secprop->Add_int("memsize",8); //We Default to 8 mb seems okay for now + secprop->Add_int("memsize",16); secprop->AddInitFunction(&CALLBACK_Init); secprop->AddInitFunction(&PIC_Init); secprop->AddInitFunction(&PROGRAMS_Init); @@ -188,13 +187,28 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&CMOS_Init); secprop->AddInitFunction(&SERIAL_Init); + MSG_Add("DOSBOX_CONFIGFILE_HELP", + "language -- Select another language file.\n" + "memsize -- Amount of memory dosbox has in megabytes.\n" + ); + secprop=control->AddSection_prop("render",&RENDER_Init); secprop->Add_int("frameskip",0); - secprop->Add_string("snapshots","snaps"); + secprop->Add_string("snapdir","snaps"); secprop->Add_string("scaler","normal2x"); + MSG_Add("RENDER_CONFIGFILE_HELP", + "frameskip -- How many frames dosbox skips before drawing one.\n" + "snapdir -- Directory where screenshots get saved.\n" + "scaler -- Scaler used to enlarge/enhance low resolution modes.\n" + " Supported are none,normal2x,advmame2x\n" + ); secprop=control->AddSection_prop("cpu",&CPU_Init); secprop->Add_int("cycles",1800); + MSG_Add("CPU_CONFIGFILE_HELP", + "cycles -- Amount of instructions dosbox tries to emulate each millsecond.\n" + " Setting this higher than your machine can handle is bad!\n" + ); #if C_FPU secprop->AddInitFunction(&FPU_Init); #endif @@ -210,39 +224,73 @@ void DOSBOX_Init(void) { secprop->Add_int("blocksize",2048); secprop->Add_string("wavedir","waves"); + MSG_Add("MIXER_CONFIGFILE_HELP", + "nosound -- Enable silent mode, sound is still emulated though.\n" + "rate -- Mixer sample rate, setting any devices higher than this will\n" + " probably lower their sound quality.\n" + "blocksize -- Mixer block size, larger blocks might help sound stuttering\n" + " but sound will also be more lagged.\n" + "wavedir -- Directory where saved sound output goes when you use the\n" + " sound record key-combination, check README file.\n" + ); + secprop=control->AddSection_prop("midi",&MIDI_Init); secprop->AddInitFunction(&MPU401_Init); secprop->Add_bool("mpu401",true); secprop->Add_string("device","default"); secprop->Add_string("config",""); + MSG_Add("MIDI_CONFIGFILE_HELP", + "mpu401 -- Enable MPU-401 Emulation.\n" + "device -- Device that will receive the MIDI data from MPU-401.\n" + " This can be default,alsa,oss,win32,coreaudio,none.\n" + "config -- Special configuration options for the device.\n" + ); + #if C_DEBUG secprop=control->AddSection_prop("debug",&DEBUG_Init); #endif secprop=control->AddSection_prop("sblaster",&SBLASTER_Init); + secprop->Add_bool("sblaster",true); secprop->Add_hex("base",0x220); secprop->Add_int("irq",7); secprop->Add_int("dma",1); - secprop->Add_int("hdma",5); +// secprop->Add_int("hdma",5); secprop->Add_int("sbrate",22050); - secprop->Add_bool("enabled",true); - secprop->AddInitFunction(&ADLIB_Init); secprop->Add_bool("adlib",true); + secprop->Add_int("adlibrate",22050); secprop->AddInitFunction(&CMS_Init); secprop->Add_bool("cms",false); secprop->Add_int("cmsrate",22050); - secprop=control->AddSection_prop("disney",&DISNEY_Init); - secprop->Add_bool("enabled",true); + MSG_Add("SBLASTER_CONFIGFILE_HELP", + "sblaster -- Enable the soundblaster emulation.\n" + "base,irq,dma -- The IO/IRQ/DMA address of the soundblaster.\n" + "sbrate -- Sample rate of soundblaster emulation.\n" + "adlib -- Enable the adlib emulation.\n" + "adlibrate -- Sample rate of adlib emulation.\n" + "cms -- Enable the Creative Music System/Gameblaster emulation.\n" + " Enabling both the adlib and cms might give conflicts!\n" + "cmsrate -- Sample rate of cms emulation.\n" + ); secprop=control->AddSection_prop("speaker",&PCSPEAKER_Init); - secprop->Add_bool("enabled",true); + secprop->Add_bool("pcspeaker",true); secprop->Add_int("pcrate",22050); secprop->AddInitFunction(&TANDYSOUND_Init); - secprop->Add_bool("tandy",false); + secprop->Add_bool("tandy",true); secprop->Add_int("tandyrate",22050); + secprop->AddInitFunction(&DISNEY_Init); + secprop->Add_bool("disney",true); + MSG_Add("SPEAKER_CONFIGFILE_HELP", + "pcspeaker -- Enable PC-Speaker emulation.\n" + "pcrate -- Sample rate of the PC-Speaker sound generation.\n" + "tandy -- Enable Tandy 3-Voice emulation.\n" + "tandyrate -- Sample rate of the Tandy 3-Voice generation.\n" + "disney -- Enable Disney Sound Source emulation.\n" + ); secprop=control->AddSection_prop("bios",&BIOS_Init); secprop->AddInitFunction(&INT10_Init); @@ -256,18 +304,35 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&DPMI_Init); secprop->Add_bool("dpmi",true); -#if C_MODEM - secprop=control->AddSection_prop("modem",&MODEM_Init); - secprop->Add_bool("enabled",true); - secprop->Add_hex("comport",2); - secprop->Add_int("listenport",23); -#endif - + MSG_Add("DOS_CONFIGFILE_HELP", + "xms -- Enable XMS support.\n" + "ems -- Enable EMS support.\n" + "dpmi -- Enable builtin DPMI host support.\n" + " This might help in getting some games to work, but might crash others.\n" + " So be sure to try both settings.\n" + ); // Mscdex secprop->AddInitFunction(&MSCDEX_Init); +#if C_MODEM + secprop=control->AddSection_prop("modem",&MODEM_Init); + secprop->Add_bool("modem",true); + secprop->Add_hex("comport",2); + secprop->Add_int("listenport",23); + + MSG_Add("MODEM_CONFIGFILE_HELP", + "modem -- Enable virtual modem emulation.\n" + "comport -- COM Port modem is connected to.\n" + "listenport -- TCP Port the momdem listens on for incoming connections.\n" + ); +#endif + secline=control->AddSection_line("autoexec",&AUTOEXEC_Init); + MSG_Add("AUTOEXEC_CONFIGFILE_HELP", + "Lines in this section will be run at startup.\n" + ); + control->SetStartUp(&SHELL_Init); } From e1dfb66baa1836cfd150c777d2964d145ceecf11 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 15 Oct 2003 08:20:50 +0000 Subject: [PATCH 1258/4131] MMX render only works when it can blit directly to 8bpp surface Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1338 --- src/gui/render.cpp | 8 ++++---- src/gui/render_scale2x.h | 15 +++++---------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 4db420f5..4be97f16 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.18 2003-10-14 23:32:32 harekiet Exp $ */ +/* $Id: render.cpp,v 1.19 2003-10-15 08:20:50 harekiet Exp $ */ #include #include @@ -359,10 +359,10 @@ normalop: case DoubleBoth: mode_callback=Render_Scale2x_CallBack; width*=2;height*=2; -#if defined (SCALE2X_NORMAL) +#if defined (SCALE2X_MMX) + flags=GFX_SHADOW; +#else flags=GFX_SHADOW; -#elif defined (SCALE2X_MMX) - flags=GFX_FIXED_BPP; #endif break; default: diff --git a/src/gui/render_scale2x.h b/src/gui/render_scale2x.h index 3b12c35f..7d63d572 100644 --- a/src/gui/render_scale2x.h +++ b/src/gui/render_scale2x.h @@ -59,10 +59,6 @@ typedef Bit8u scale2x_uint8; typedef Bit16u scale2x_uint16; typedef Bit32u scale2x_uint32; -#if !defined(__GNUC__) || !defined(__i386__) - -#define SCALE2X_NORMAL 1 - static void scale2x_line_8(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count) { assert(count >= 2); @@ -306,7 +302,7 @@ static void Scale2x_32(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { scale2x_line_32((Bit32u *)dest,(Bit32u *)(dest+render.op.pitch),src-render.src.pitch,src,src,dx); } -#else +#if defined(__GNUC__) || defined(__i386__) #define SCALE2X_MMX 1 @@ -539,10 +535,13 @@ static void Render_Scale2x_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,B render.op.bpp=bpp; render.op.pitch=pitch; render.op.type=OP_AdvMame2x; -#if defined(SCALE2X_NORMAL) switch (bpp) { case 8: +#if defined(SCALE2X_MMX) + render.op.part_handler=Scale2x_8_mmx; +#else render.op.part_handler=Scale2x_8; +#endif break; case 16: render.op.part_handler=Scale2x_16;; @@ -554,10 +553,6 @@ static void Render_Scale2x_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,B E_Exit("RENDER:Unsupported display depth of %d",bpp); break; } -#elif defined(SCALE2X_MMX) - assert (bpp==8); - render.op.part_handler=Scale2x_8_mmx; -#endif RENDER_ResetPal(); } From 6b3762422121d52146a854454645cf7164dffb06 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 15 Oct 2003 10:00:29 +0000 Subject: [PATCH 1259/4131] 0.60 update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1339 --- NEWS | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/NEWS b/NEWS index 6afcd458..7e7c1e57 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,35 @@ +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 From 0a38163dc7ba8eff799fd60f8f3dcbaaea3b16f5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 15 Oct 2003 10:22:56 +0000 Subject: [PATCH 1260/4131] Added install script. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1340 --- scripts/dosbox-installer.nsi | 83 ++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 scripts/dosbox-installer.nsi diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi new file mode 100644 index 00000000..fb74bacd --- /dev/null +++ b/scripts/dosbox-installer.nsi @@ -0,0 +1,83 @@ +!define VER_MAYOR 0 +!define VER_MINOR 60 + +; The name of the installer +Name "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer" + +; 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 bzip2 + +LicenseData COPYING +LicenseText "DOSBox v${VER_MAYOR}.${VER_MINOR} License" + +; The stuff to install +Section "ThisNameIsIgnoredSoWhyBother?" + ; Set output path to the installation directory. + SetOutPath $INSTDIR + + ; Put file there + 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 libpng12.dll + + CreateDirectory "$INSTDIR\snaps" + CreateDirectory "$INSTDIR\waves" + CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}" + 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$\"" + 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" + +WriteUninstaller "uninstall.exe" + +SectionEnd ; end the section + +UninstallText "This will uninstall DOSBox v${VER_MAYOR}.${VER_MINOR}. Hit next to continue." + +Section "Uninstall" + ; 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\libpng12.dll + + ; 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.conf.lnk" + +; remove directories used. + RMDir "$INSTDIR" + RMDir "$INSTDIR\snaps" + RMDir "$INSTDIR\waves" + RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}" +SectionEnd + +; eof \ No newline at end of file From 2fc3c4b3b68bb01efd0c7ec069933e567c08d480 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 15 Oct 2003 10:27:00 +0000 Subject: [PATCH 1261/4131] added fanskapet. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1341 --- AUTHORS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AUTHORS b/AUTHORS index e5076c36..7d2b32af 100644 --- a/AUTHORS +++ b/AUTHORS @@ -5,3 +5,5 @@ Sjoerd v.d. Berg Peter Veenstra Felix Jakschitsch Ulf Wohlers +Tommy Frössman + From 6124dc639a44aef2ef4ff07569a403bcf3a1818a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 15 Oct 2003 15:07:22 +0000 Subject: [PATCH 1262/4131] changed directory delete order. (is used for 0.60) don't worry Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1343 --- scripts/dosbox-installer.nsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index fb74bacd..dbc96be1 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -74,9 +74,9 @@ Section "Uninstall" Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.conf.lnk" ; remove directories used. - RMDir "$INSTDIR" RMDir "$INSTDIR\snaps" RMDir "$INSTDIR\waves" + RMDir "$INSTDIR" RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}" SectionEnd From dc3bf0be87152c84b56b92a17d3bd6115b964761 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 16 Oct 2003 07:14:27 +0000 Subject: [PATCH 1263/4131] oopsie Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1344 --- src/gui/render_scale2x.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/render_scale2x.h b/src/gui/render_scale2x.h index 7d63d572..979b9dc9 100644 --- a/src/gui/render_scale2x.h +++ b/src/gui/render_scale2x.h @@ -302,7 +302,7 @@ static void Scale2x_32(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { scale2x_line_32((Bit32u *)dest,(Bit32u *)(dest+render.op.pitch),src-render.src.pitch,src,src,dx); } -#if defined(__GNUC__) || defined(__i386__) +#if defined(__GNUC__) && defined(__i386__) #define SCALE2X_MMX 1 From 628357a1b0273540ea224a1820949fd2c4fc6468 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 17 Oct 2003 16:53:24 +0000 Subject: [PATCH 1264/4131] added new memory breakpoint types : bppm (selector:offset) and bplm (linear address) show prot-mode type : pr16 / pr32 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1345 --- src/debug/debug.cpp | 66 +++++++++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 17 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index ba746325..c5bd13b8 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -174,7 +174,7 @@ std::list CDebugVar::varList; bool skipFirstInstruction = false; -enum EBreakpoint { BKPNT_UNKNOWN, BKPNT_PHYSICAL, BKPNT_INTERRUPT, BKPNT_MEMORY }; +enum EBreakpoint { BKPNT_UNKNOWN, BKPNT_PHYSICAL, BKPNT_INTERRUPT, BKPNT_MEMORY, BKPNT_MEMORY_PROT, BKPNT_MEMORY_LINEAR }; #define BPINT_ALL 0x100 @@ -341,19 +341,29 @@ bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off) } #if C_HEAVY_DEBUG // Memory breakpoint support - else if ((bp->GetType()==BKPNT_MEMORY) && bp->IsActive()) { + else if (bp->IsActive()) { + if ((bp->GetType()==BKPNT_MEMORY) || (bp->GetType()==BKPNT_MEMORY_PROT) || (bp->GetType()==BKPNT_MEMORY_LINEAR)) { + // Watch Protected Mode Memoryonly in pmode + if (bp->GetType()==BKPNT_MEMORY_PROT) { + // Check if pmode is active + if (!cpu.pmode) return false; + // Check if descriptor is valid + Descriptor desc; + if (!cpu.gdt.GetDescriptor(bp->GetSegment(),desc)) return false; + if (desc.GetLimit()==0) return false; + } - Bitu address = GetAddress(bp->GetSegment(),bp->GetOffset()); -// Bitu address = bp->GetSegment()*16 + bp->GetOffset(); - Bit8u value = mem_readb(address); - if (bp->GetValue() != value) { - // Yup, memory value changed - - DEBUG_ShowMsg("DEBUG: Memory breakpoint: %04X:%04X - %02X -> %02X",bp->GetSegment(),bp->GetOffset(),bp->GetValue(),value); - bp->SetValue(value); - return true; - }; - + Bitu address; + if (bp->GetType()==BKPNT_MEMORY_LINEAR) address = bp->GetOffset(); + else address = GetAddress(bp->GetSegment(),bp->GetOffset()); + Bit8u value = mem_readb(address); + if (bp->GetValue() != value) { + // Yup, memory value changed + DEBUG_ShowMsg("DEBUG: Memory breakpoint %s: %04X:%04X - %02X -> %02X",(bp->GetType()==BKPNT_MEMORY_PROT)?"(Prot)":"",bp->GetSegment(),bp->GetOffset(),bp->GetValue(),value); + bp->SetValue(value); + return true; + }; + } }; #endif }; @@ -629,8 +639,11 @@ static void DrawRegisters(void) { oldflags=flags.word; - if (cpu.pmode) mvwprintw(dbg.win_reg,0,76,"Prot"); - else mvwprintw(dbg.win_reg,0,76,"Real"); + if (cpu.pmode) { + if (cpu.code.big) mvwprintw(dbg.win_reg,0,76,"Pr32"); + else mvwprintw(dbg.win_reg,0,76,"Pr16"); + } else + mvwprintw(dbg.win_reg,0,76,"Real"); // Selector info, if available if ((cpu.pmode) && curSelectorName[0]) { @@ -896,6 +909,25 @@ bool ParseCommand(char* str) DEBUG_ShowMsg("DEBUG: Set memory breakpoint at %04X:%04X",seg,ofs); return true; } + found = strstr(str,"BPPM "); + if (found) { // Add new breakpoint + found+=4; + Bit16u seg = GetHexValue(found,found);found++; // skip ":" + Bit32u ofs = GetHexValue(found,found); + CBreakpoint* bp = CBreakpoint::AddMemBreakpoint(seg,ofs); + if (bp) bp->SetType(BKPNT_MEMORY_PROT); + DEBUG_ShowMsg("DEBUG: Set prot-mode memory breakpoint at %04X:%08X",seg,ofs); + return true; + } + found = strstr(str,"BPLM "); + if (found) { // Add new breakpoint + found+=4; + Bitu ofs = GetHexValue(found,found); + CBreakpoint* bp = CBreakpoint::AddMemBreakpoint(0,ofs); + if (bp) bp->SetType(BKPNT_MEMORY_LINEAR); + DEBUG_ShowMsg("DEBUG: Set linear memory breakpoint at %08X",ofs); + return true; + } #endif found = strstr(str,"BPINT"); if (found) { // Add Interrupt Breakpoint @@ -1051,6 +1083,8 @@ bool ParseCommand(char* str) wprintw(dbg.win_out,"BPINT [intNr] [ah] - Set interrupt breakpoint with ah\n"); #if C_HEAVY_DEBUG wprintw(dbg.win_out,"BPM [segment]:[offset] - Set memory breakpoint (memory change)\n"); + wprintw(dbg.win_out,"BPPM [selector]:[offset]- Set pmode-memory breakpoint (memory change)\n"); + wprintw(dbg.win_out,"BPLM [linear address] - Set linear memory breakpoint (memory change)\n"); #endif wprintw(dbg.win_out,"BPLIST - List breakpoints\n"); wprintw(dbg.win_out,"BPDEL [bpNr] / * - Delete breakpoint nr / all\n"); @@ -1672,8 +1706,6 @@ bool DEBUG_HeavyIsBreakpoint(void) PhysPt where = SegPhys(cs)+reg_eip; if (CBreakpoint::CheckBreakpoint(SegValue(cs),reg_eip)) { -// exitLoop = true; -// DEBUG_Enable(); return true; } return false; From 3a49d4acf2f40fdc553e52467dd43f08f95ec87e Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 17 Oct 2003 16:56:38 +0000 Subject: [PATCH 1265/4131] added DOS_SetFileAttr : check if file is available, failure if cdrom, but no change of file attributes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1346 --- include/dos_inc.h | 1 + src/dos/dos.cpp | 9 +++++++-- src/dos/dos_files.cpp | 17 ++++++++++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 43ba1d15..df977352 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -117,6 +117,7 @@ bool DOS_RemoveDir(char * dir); bool DOS_Rename(char * oldname,char * newname); bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit8u * sectors,Bit16u * clusters,Bit16u * free); bool DOS_GetFileAttr(char * name,Bit16u * attr); +bool DOS_SetFileAttr(char * name,Bit16u attr); /* IOCTL Stuff */ bool DOS_IOCTL(void); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index e0959e8d..02243133 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.57 2003-10-14 23:33:33 harekiet Exp $ */ +/* $Id: dos.cpp,v 1.58 2003-10-17 16:56:38 finsterr Exp $ */ #include #include @@ -527,7 +527,12 @@ static Bitu DOS_21Handler(void) { break; case 0x01: /* Set */ LOG(LOG_MISC,LOG_ERROR)("DOS:Set File Attributes for %s not supported",name1); - CALLBACK_SCF(false); + if (DOS_SetFileAttr(name1,reg_cx)) { + CALLBACK_SCF(false); + } else { + CALLBACK_SCF(true); + reg_ax=dos.errorcode; + } break; default: LOG(LOG_MISC,LOG_ERROR)("DOS:0x43:Illegal subfunction %2X",reg_al); diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 82dace06..74fb195b 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.47 2003-10-10 13:50:34 finsterr Exp $ */ +/* $Id: dos_files.cpp,v 1.48 2003-10-17 16:56:06 finsterr Exp $ */ #include #include @@ -447,6 +447,21 @@ bool DOS_GetFileAttr(char * name,Bit16u * attr) { } } +bool DOS_SetFileAttr(char * name,Bit16u attr) +// this function does not change the file attributs +// it just does some tests if file is available +// returns false when using on cdrom (stonekeep) +{ + Bit16u attrTemp; + char fullname[DOS_PATHLENGTH];Bit8u drive; + if (!DOS_MakeName(name,fullname,&drive)) return false; + if (strcmp(Drives[drive]->GetInfo(),"CDRom.")==0) { + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; + } + return Drives[drive]->GetFileAttr(fullname,&attrTemp); +} + bool DOS_Canonicalize(char * name,char * big) { //TODO Add Better support for devices and shit but will it be needed i doubt it :) Bit8u drive; From d6e2f1021c1673456d7dcf1e5ebbd9dfd2e1ee46 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 19 Oct 2003 17:07:34 +0000 Subject: [PATCH 1266/4131] added patch 826373 by Marius Strobl. Fixed a typo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1347 --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 305dc4c5..ee8f53c0 100644 --- a/configure.in +++ b/configure.in @@ -86,7 +86,7 @@ AC_ARG_ENABLE(debug,AC_HELP_STRING([--enable-debug],[Enable debug mode]),[ AH_TEMPLATE(C_CORE_INLINE,[Define to 1 to use inlined memory functions in cpu core]) AC_ARG_ENABLE(core-inline,AC_HELP_STRING([--enable-core-inline],[Enable inlined memory handling in CPU Core]),[ if test x$enable_core_inline = xyes ; then - AC_MSG_RESULT([enabling inlined memory handling in CPU Core]), + AC_MSG_RESULT([enabling inlined memory handling in CPU Core]) AC_DEFINE(C_CORE_INLINE,1) fi ],) @@ -94,7 +94,7 @@ AC_ARG_ENABLE(core-inline,AC_HELP_STRING([--enable-core-inline],[Enable inlined AH_TEMPLATE(C_FPU,[Define to 1 to enable floating point emulation]) AC_ARG_ENABLE(fpu,AC_HELP_STRING([--disable-fpu],[Disable FPU support]),[ if test x$enable_fpu = xno ; then - AC_MSG_RESULT([disabling FPU supportd]) + AC_MSG_RESULT([disabling FPU support]) else AC_DEFINE(C_FPU,1) fi From 7dab3d53e5f9498b7bf04c20f0a5ec2d61e6b5c3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 19 Oct 2003 19:21:12 +0000 Subject: [PATCH 1267/4131] fixes from c2woody and some of myself Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1348 --- src/fpu/fpu.cpp | 15 ++++++++------- src/fpu/fpu_instructions.h | 15 ++++++++------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 1012d2f5..cb7b87e9 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: fpu.cpp,v 1.14 2003-10-19 19:21:12 qbix79 Exp $ */ + #include "dosbox.h" #if C_FPU @@ -375,7 +377,7 @@ void FPU_ESC1_Normal(Bitu rm) { void FPU_ESC2_EA(Bitu rm,PhysPt addr) { /* 32 bits integer operants */ Bit32s blah = mem_readd(addr); - fpu.regs[8].d = static_cast(blah); + fpu.regs[8].d = static_cast(blah); EATREE(rm); } @@ -453,8 +455,7 @@ void FPU_ESC3_Normal(Bitu rm) { void FPU_ESC4_EA(Bitu rm,PhysPt addr) { - /* REGULAR TREE WITH 64 BITS REALS ? double ? */ -// E_Exit("how to load a double in esc 4 ea"); + /* REGULAR TREE WITH 64 BITS REALS: double */ fpu.regs[8].l.lower=mem_readd(addr); fpu.regs[8].l.upper=mem_readd(addr+4); EATREE(rm); @@ -478,16 +479,16 @@ void FPU_ESC4_Normal(Bitu rm) { FPU_FCOM(TOP,ST(sub)); FPU_FPOP(); break; - case 0x04: /* FSUBRP STi,ST*/ + case 0x04: /* FSUBR STi,ST*/ FPU_FSUBR(ST(sub),TOP); break; - case 0x05: /* FSUBP STi,ST*/ + case 0x05: /* FSUB STi,ST*/ FPU_FSUB(ST(sub),TOP); break; - case 0x06: /* FDIVRP STi,ST*/ + case 0x06: /* FDIVR STi,ST*/ FPU_FDIVR(ST(sub),TOP); break; - case 0x07: /* FDIVP STi,ST*/ + case 0x07: /* FDIV STi,ST*/ FPU_FDIV(ST(sub),TOP); break; default: diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index bdd9bcf9..23671e13 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.13 2003-10-07 10:42:01 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.14 2003-10-19 19:21:12 qbix79 Exp $ */ static void FPU_FINIT(void) { @@ -199,10 +199,11 @@ static double FROUND(double in){ static void FPU_FPREM(void){ Real64 valtop = fpu.regs[TOP].d; Real64 valdiv = fpu.regs[ST(1)].d; - Real64 res = floor(valtop/valdiv); - Bit64s ressaved = static_cast(res); - res=valtop - res*valdiv; - fpu.regs[TOP].d = res; + Bit64s ressaved = static_cast( (valtop/valdiv) ); +// Some backups +// Real64 res=valtop - ressaved*valdiv; +// res= fmod(valtop,valdiv); + fpu.regs[TOP].d = valtop - ressaved*valdiv; FPU_SET_C0(static_cast(ressaved&4)); FPU_SET_C3(static_cast(ressaved&2)); FPU_SET_C1(static_cast(ressaved&1)); @@ -309,13 +310,13 @@ static void FPU_F2XM1(void){ return; } -static void FPU_FYL2X(void){ +static void FPU_FYL2X(void){ fpu.regs[ST(1)].d*=log(fpu.regs[TOP].d)/log(static_cast(2.0)); FPU_FPOP(); return; } static void FPU_FSCALE(void){ - fpu.regs[TOP].d *=pow(2.0,static_cast(static_cast(FROUND(fpu.regs[ST(1)].d)))); + fpu.regs[TOP].d *= pow(2.0,static_cast(static_cast(fpu.regs[ST(1)].d))); return; //2^x where x is chopped. } From e21e61ce04fdca8769ec479aa5a7bad075b9d478 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 19 Oct 2003 19:31:59 +0000 Subject: [PATCH 1268/4131] Little hack to skip CLTS instruction in non-debug mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1349 --- src/cpu/core_normal/prefix_0f.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 0871fab1..e0a361d7 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -121,6 +121,10 @@ *rmrw=(Bit16u)limit; } break; +#if !(C_DEBUG) + CASE_0F_B(0x06) /* CLTS */ + break; +#endif CASE_0F_B(0x20) /* MOV Rd.CRx */ { GetRM; From 8c0b7658ea09de6fa2df320fc188d3a49e92b80e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 21 Oct 2003 18:18:01 +0000 Subject: [PATCH 1269/4131] Added patch 827580 from James Wilkinson Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1350 --- src/shell/shell_cmds.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index b9a4d022..543c8f3f 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.33 2003-10-14 23:34:23 harekiet Exp $ */ +/* $Id: shell_cmds.cpp,v 1.34 2003-10-21 18:18:01 qbix79 Exp $ */ #include @@ -251,10 +251,26 @@ void DOS_Shell::CMD_DIR(char * args) { byte_count=file_count=dir_count=0; char buffer[CROSS_LEN]; - if (strlen(args)==0) args="*.*"; //no arguments. - if ((strlen(args)==1) && (args[0]==' ')) args="*.*"; //stuff like dir /p + args = trim(args); + int argLen = strlen(args); + if (argLen == 0) { + strcpy(args,"*.*"); //no arguments. + } else { + switch (args[argLen-1]) + { + case '\\': // handle \, C:\, etc. + case ':' : // handle C:, etc. + strcat(args,"*.*"); + break; + case '*': // handle *, \*, C:\*, etc. + // (not ideal - could end up *.*.*, but that'll net the same result) + strcat(args,".*"); + break; + default: + break; + } + } args = ExpandDot(args,buffer); - StripSpaces(args); /* Make a full path in the args */ if (!DOS_Canonicalize(args,path)) { From 9e4ddd517b9fd890a93504317d9134092cfaa362 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 22 Oct 2003 14:18:15 +0000 Subject: [PATCH 1270/4131] Move vga.h to includes dir Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1351 --- src/hardware/vga.h | 312 --------------------------------------------- 1 file changed, 312 deletions(-) delete mode 100644 src/hardware/vga.h diff --git a/src/hardware/vga.h b/src/hardware/vga.h deleted file mode 100644 index 51d0edc8..00000000 --- a/src/hardware/vga.h +++ /dev/null @@ -1,312 +0,0 @@ - /* - * Copyright (C) 2002-2003 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef VGA_H_ -#define VGA_H_ - -#include -#include "dosbox.h" - -enum VGAModes { - M_TEXT16, - M_CGA2,M_CGA4, - M_TANDY16, - M_EGA2,M_EGA4,M_EGA16, - M_VGA, - M_LIN8, - 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 */ - -/* Different functions that should be handle by memory handler */ - -#define MH_ROTATEOP 0x0001; -#define MH_SETRESET 0x0002; -#define MH_BITMASK 0x0004; - - -typedef Bit8u VGA_ReadHandler(PhysPt off); -typedef void VGA_WriteHandler(PhysPt off,Bit8u val); - -typedef struct { - bool attrindex; -} VGA_Internal; - -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 blinking; /* Attribute bit 7 is blinking */ - - bool vline_double; - Bit8u vline_height; - - /* Pixel Scrolling */ - Bit8u pel_panning; /* Amount of pixels to skip when starting horizontal line */ - Bit8u hlines_skip; - Bit8u bytes_skip; - -/* Specific stuff memory write/read handling */ - - VGA_ReadHandler * readhandler; - VGA_WriteHandler * writehandler; - - Bit8u read_mode; - Bit8u write_mode; - 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 pitch; - Bitu blank; - bool double_width; - bool double_height; - Bitu lines; - Bit8u font_height; - Bit8u font[64*1024]; - Bitu font1_start; - Bitu font2_start; - Bitu rows,cols; - struct { - Bit8u sline,eline; - Bit8u count,delay; - Bit8u enabled; - } cursor; -} VGA_Draw; - -typedef struct { - Bit8u bank; - Bit8u reg_lock1; - Bit8u reg_lock2; - Bit8u reg_31; - Bit8u reg_35; - Bit8u reg_43; - Bit8u reg_58; - Bit8u reg_51; - Bit8u reg_55; - Bit8u ex_hor_overflow; - Bit8u ex_ver_overflow; - Bit16u la_window; - struct { - Bit8u r; - Bit8u n; - Bit8u m; - } clk[4],mclk; - struct { - Bit8u lock; - Bit8u cmd; - } pll; -} VGA_S3; - -typedef struct { - Bit8u color_select; -} VGA_CGA; - -typedef struct { - Bit8u mem_bank; - Bit8u disp_bank; - Bit8u reg_index; -} 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; - -struct RGBEntry { - Bit8u red; - Bit8u green; - Bit8u blue; -}; - -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; - RGBEntry rgb[0x100]; - Bit8u attr[16]; -} VGA_Dac; - -union VGA_Latch { - Bit32u d; - Bit8u b[4]; -}; - -union VGA_Memory { - Bit8u linear[512*1024*4]; - Bit8u paged[512*1024][4]; - VGA_Latch latched[512*1024]; -}; - -typedef struct { - VGAModes mode; /* The mode the vga system is in */ - 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_CGA cga; - VGA_TANDY tandy; - VGA_Memory mem; -} VGA_Type; - - - -/* Functions for different resolutions */ -void VGA_SetMode(VGAModes mode); -void VGA_SetupHandlers(void); -void VGA_StartResize(void); -void VGA_SetupDrawing(void); - -/* Some DAC/Attribute functions */ -void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal); -void VGA_ATTR_SetPalette(Bit8u index,Bit8u val); - -/* The VGA Subfunction startups */ -void VGA_SetupAttr(void); -void VGA_SetupMemory(void); -void VGA_SetupDAC(void); -void VGA_SetupCRTC(void); -void VGA_SetupMisc(void); -void VGA_SetupGFX(void); -void VGA_SetupSEQ(void); - -/* Some Support Functions */ -void VGA_SetClock(Bitu which,Bitu target); -void VGA_DACSetEntirePalette(void); -void VGA_StartRetrace(void); -void VGA_StartUpdateLFB(void); - -extern VGA_Type vga; - -extern Bit32u ExpandTable[256]; -extern Bit32u FillTable[16]; -extern Bit32u CGA_4_Table[256]; -extern Bit32u Expand16Table[4][16]; -extern Bit32u Expand16BigTable[0x10000]; - - -#endif - From a2948b3d589745a3abad6fa0b7770db31f29998c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 22 Oct 2003 14:21:49 +0000 Subject: [PATCH 1271/4131] New machine type variable Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1352 --- include/dosbox.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/include/dosbox.h b/include/dosbox.h index 4d7507ff..2f47f113 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -19,7 +19,6 @@ #if !defined __DOSBOX_H #define __DOSBOX_H - void E_Exit(char * message,...); void MSG_Add(const char*,const char*); //add messages to the internal langaugefile @@ -60,6 +59,16 @@ void DOSBOX_Init(void); class Config; extern Config * control; +enum MachineType { + MCH_HERC, + MCH_CGA, + MCH_TANDY, + MCH_VGA, + MCH_AUTO +}; + +extern MachineType machine; + #ifndef __LOGGING_H_ #include "logging.h" #endif // the logging system. From f634f2792484b56c4cee5b32486edab56dee7215 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 22 Oct 2003 14:25:52 +0000 Subject: [PATCH 1272/4131] Changes for new paging/memory functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1353 --- include/mem.h | 31 ++++----- include/paging.h | 168 ++++++++++++++++------------------------------- 2 files changed, 71 insertions(+), 128 deletions(-) diff --git a/include/mem.h b/include/mem.h index 509a4416..2c1bc990 100644 --- a/include/mem.h +++ b/include/mem.h @@ -26,7 +26,7 @@ typedef Bit32u PhysPt; typedef Bit8u * HostPt; typedef Bit32u RealPt; -typedef Bits MemHandle; +typedef Bit32s MemHandle; #define MEM_PAGESIZE 4096 @@ -43,12 +43,9 @@ MemHandle MEM_AllocatePages(Bitu pages,bool sequence); PhysPt MEM_AllocatePage(void); void MEM_ReleasePages(MemHandle handle); bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence); -void MEM_MapPagesHandle(Bitu lin_page,MemHandle mem,Bitu mem_page,Bitu pages); -void MEM_MapPagesDirect(Bitu lin_page,Bitu phys_page,Bitu pages); -void MEM_UnmapPages(Bitu phys_page,Bitu pages); - MemHandle MEM_NextHandle(MemHandle handle); +MemHandle MEM_NextHandleAt(MemHandle handle,Bitu where); /* The folowing six functions are used everywhere in the end so these should be changed for @@ -57,23 +54,23 @@ MemHandle MEM_NextHandle(MemHandle handle); #ifdef WORDS_BIGENDIAN -INLINE Bit8u readb(HostPt off) { +INLINE Bit8u host_readb(HostPt off) { return off[0]; }; -INLINE Bit16u readw(HostPt off) { +INLINE Bit16u host_readw(HostPt off) { return off[0] | (off[1] << 8); }; -INLINE Bit32u readd(HostPt off) { +INLINE Bit32u host_readd(HostPt off) { return off[0] | (off[1] << 8) | (off[2] << 16) | (off[3] << 24); }; -INLINE void writeb(HostPt off,Bit8u val) { +INLINE void host_writeb(HostPt off,Bit8u val) { off[0]=val; }; -INLINE void writew(HostPt off,Bit16u val) { +INLINE void host_writew(HostPt off,Bit16u val) { off[0]=(Bit8u)(val); off[1]=(Bit8u)(val >> 8); }; -INLINE void writed(HostPt off,Bit32u val) { +INLINE void host_writed(HostPt off,Bit32u val) { off[0]=(Bit8u)(val); off[1]=(Bit8u)(val >> 8); off[2]=(Bit8u)(val >> 16); @@ -86,22 +83,22 @@ INLINE void writed(HostPt off,Bit32u val) { #else -INLINE Bit8u readb(HostPt off) { +INLINE Bit8u host_readb(HostPt off) { return *(Bit8u *)off; }; -INLINE Bit16u readw(HostPt off) { +INLINE Bit16u host_readw(HostPt off) { return *(Bit16u *)off; }; -INLINE Bit32u readd(HostPt off) { +INLINE Bit32u host_readd(HostPt off) { return *(Bit32u *)off; }; -INLINE void writeb(HostPt off,Bit8u val) { +INLINE void host_writeb(HostPt off,Bit8u val) { *(Bit8u *)(off)=val; }; -INLINE void writew(HostPt off,Bit16u val) { +INLINE void host_writew(HostPt off,Bit16u val) { *(Bit16u *)(off)=val; }; -INLINE void writed(HostPt off,Bit32u val) { +INLINE void host_writed(HostPt off,Bit32u val) { *(Bit32u *)(off)=val; }; diff --git a/include/paging.h b/include/paging.h index 73169bc2..73529ca9 100644 --- a/include/paging.h +++ b/include/paging.h @@ -22,49 +22,52 @@ #include "mem.h" class PageDirectory; -struct PageEntry; -struct PageLink; #define MEM_PAGE_SIZE (4096) #define XMS_START (0x110) +#define TLB_SIZE (1024*1024) -enum EntryTypes { //The type of memory contained in this link - ENTRY_VGA, - ENTRY_CHANGES, - ENTRY_INIT, - ENTRY_NA, - ENTRY_ROM, - ENTRY_LFB, - ENTRY_RAM, - ENTRY_ALLOC, -}; +#define PFLAG_READABLE 0x1 +#define PFLAG_WRITEABLE 0x2 +#define PFLAG_HASROM 0x4 +#define PFLAG_HASCODE 0x8 //Page contains dynamic code +#define PFLAG_NOCODE 0x10 //No dynamic code can be generated here +#define PFLAG_ILLEGAL 0x20 //No dynamic code can be generated here -enum VGA_RANGES { - VGA_RANGE_A000, - VGA_RANGE_B000, - VGA_RANGE_B800, -}; +#define LINK_START ((1024+64)/4) //Start right after the HMA - -class PageChange { +class PageHandler { public: - virtual void Changed(PageLink * link,Bitu start,Bitu end)=0; + virtual Bitu readb(PhysPt addr); + virtual Bitu readw(PhysPt addr); + virtual Bitu readd(PhysPt addr); + virtual void writeb(PhysPt addr,Bitu val); + virtual void writew(PhysPt addr,Bitu val); + virtual void writed(PhysPt addr,Bitu val); + virtual void AddPageLink(Bitu lin_page, Bitu phys_page)=0; + virtual HostPt GetHostPt(Bitu phys_page); + Bitu flags; }; /* Some other functions */ void PAGING_Enable(bool enabled); bool PAGING_Enabled(void); -void MEM_CheckLinks(PageEntry * theentry); - -PageDirectory * MEM_DefaultDirectory(void); Bitu PAGING_GetDirBase(void); void PAGING_SetDirBase(Bitu cr3); +void PAGING_InitTLB(void); +void PAGING_ClearTLB(void); +void PAGING_ClearTLBEntries(Bitu pages,Bit32u * entries); -PageLink * MEM_LinkPage(Bitu phys_page,PhysPt lin_base); +void PAGING_LinkPage(Bitu lin_page,Bitu phys_page); +/* This maps the page directly, only use when paging is disabled */ +void PAGING_MapPage(Bitu lin_page,Bitu phys_page); -void MEM_UnlinkPage(PageLink * link); void MEM_SetLFB(Bitu _page,Bitu _pages,HostPt _pt); +void MEM_SetPageHandler(Bitu phys_page,Bitu pages,PageHandler * handler); +void MEM_UnlinkPages(void); + + #pragma pack(1) typedef struct { @@ -87,57 +90,18 @@ union X86PageEntry { X86_PageEntryBlock block; }; -struct PageLink { - HostPt read; - HostPt write; - PageChange * change; - PhysPt lin_base; - PageEntry * entry; - union { - PageDirectory * dir; - Bitu table; - } data; - PageLink * next; -}; - -struct PageEntry { - PageLink * links; - EntryTypes type; - union { - HostPt mem; - PhysPt vga_base; - PageDirectory * dir; - } data; - MemHandle next_handle; -}; - -class PageDirectory { -public: - PageDirectory(); - ~PageDirectory(); - void ClearDirectory(void); - void SetBase(PhysPt page); - void LinkPage(Bitu lin_page,Bitu phys_page); - bool InitPage(Bitu lin_address); - bool InitPageLinear(Bitu lin_address); - void InvalidateTable(Bitu table); - void InvalidateLink(Bitu table,Bitu index); - PageDirectory * next; - PageLink *links[1024*1024]; - PageLink *tables[1024]; - PageLink *link_dir; //Handler for main directory table - PageEntry entry_init; //Handler for pages that need init - PageLink link_init; //Handler for pages that need init - Bit32u base_page; //Base got from CR3 - PageChange * table_change; - PageChange * dir_change; -}; - struct PagingBlock { - PageDirectory * cache; - PageDirectory * dir; - PageLink * free_link; Bitu cr3; + struct { + Bitu page; + PhysPt addr; + } base; + struct { + HostPt read[TLB_SIZE]; + HostPt write[TLB_SIZE]; + PageHandler * handler[TLB_SIZE]; + Bit32u phys_page[TLB_SIZE]; + } tlb; bool enabled; }; @@ -145,24 +109,7 @@ extern PagingBlock paging; /* Some support functions */ -static INLINE PageLink * GetPageLink(PhysPt address) { - Bitu index=(address>>12); - return paging.dir->links[index]; -} - -void PAGING_AddFreePageLink(PageLink * link); - -PageLink * PAGING_GetFreePageLink(void); -void MEM_SetupVGA(VGA_RANGES range,HostPt base); - -/* Page Handler functions */ - -Bit8u ENTRY_readb(PageEntry * pentry,PhysPt address); -Bit16u ENTRY_readw(PageEntry * pentry,PhysPt address); -Bit32u ENTRY_readd(PageEntry * pentry,PhysPt address); -void ENTRY_writeb(PageEntry * pentry,PhysPt address,Bit8u val); -void ENTRY_writew(PageEntry * pentry,PhysPt address,Bit16u val); -void ENTRY_writed(PageEntry * pentry,PhysPt address,Bit32u val); +PageHandler * MEM_GetPageHandler(Bitu phys_page); /* Unaligned address handlers */ Bit16u mem_unalignedreadw(PhysPt address); @@ -173,52 +120,51 @@ void mem_unalignedwrited(PhysPt address,Bit32u val); /* Special inlined memory reading/writing */ INLINE Bit8u mem_readb_inline(PhysPt address) { - PageLink * plink=GetPageLink(address); - - if (plink->read) return readb(plink->read+address); - else return ENTRY_readb(plink->entry,address); + Bitu index=(address>>12); + if (paging.tlb.read[index]) return host_readb(paging.tlb.read[index]+address); + else return paging.tlb.handler[index]->readb(address); } INLINE Bit16u mem_readw_inline(PhysPt address) { if (address & 1) return mem_unalignedreadw(address); - PageLink * plink=GetPageLink(address); - if (plink->read) return readw(plink->read+address); - else return ENTRY_readw(plink->entry,address); + Bitu index=(address>>12); + if (paging.tlb.read[index]) return host_readw(paging.tlb.read[index]+address); + else return paging.tlb.handler[index]->readw(address); } INLINE Bit32u mem_readd_inline(PhysPt address) { if (address & 3) return mem_unalignedreadd(address); - PageLink * plink=GetPageLink(address); - if (plink->read) return readd(plink->read+address); - else return ENTRY_readd(plink->entry,address); + Bitu index=(address>>12); + if (paging.tlb.read[index]) return host_readd(paging.tlb.read[index]+address); + else return paging.tlb.handler[index]->readd(address); } INLINE void mem_writeb_inline(PhysPt address,Bit8u val) { - PageLink * plink=GetPageLink(address); + Bitu index=(address>>12); - if (plink->write) writeb(plink->write+address,val); - else ENTRY_writeb(plink->entry,address,val); + if (paging.tlb.write[index]) host_writeb(paging.tlb.write[index]+address,val); + else return paging.tlb.handler[index]->writeb(address,val); } INLINE void mem_writew_inline(PhysPt address,Bit16u val) { if (address & 1) {mem_unalignedwritew(address,val);return;} - PageLink * plink=GetPageLink(address); + Bitu index=(address>>12); - if (plink->write) writew(plink->write+address,val); - else ENTRY_writew(plink->entry,address,val); + if (paging.tlb.write[index]) host_writew(paging.tlb.write[index]+address,val); + else return paging.tlb.handler[index]->writew(address,val); } INLINE void mem_writed_inline(PhysPt address,Bit32u val) { if (address & 3) {mem_unalignedwrited(address,val);return;} - PageLink * plink=GetPageLink(address); + Bitu index=(address>>12); + if (paging.tlb.write[index]) host_writed(paging.tlb.write[index]+address,val); + else return paging.tlb.handler[index]->writed(address,val); - if (plink->write) writed(plink->write+address,val); - else ENTRY_writed(plink->entry,address,val); } #endif From 80b885b36ee3e1480a1664b52b7b935f34883e4b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 22 Oct 2003 14:26:07 +0000 Subject: [PATCH 1273/4131] New paging related functions Changes for hercules/cga/tandy support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1354 --- include/vga.h | 309 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 include/vga.h diff --git a/include/vga.h b/include/vga.h new file mode 100644 index 00000000..fa1ae3c2 --- /dev/null +++ b/include/vga.h @@ -0,0 +1,309 @@ + /* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef VGA_H_ +#define VGA_H_ + +#include +#include "dosbox.h" + +enum VGAModes { + M_TEXT2,M_TEXT16, + M_HERC, + M_CGA2,M_CGA4,M_CGA16, + M_TANDY16, + M_EGA2,M_EGA4,M_EGA16, + M_VGA, + M_LIN8, + 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 */ + +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 blinking; /* Attribute bit 7 is blinking */ + + bool vline_double; + Bit8u vline_height; + + /* Pixel Scrolling */ + Bit8u pel_panning; /* Amount of pixels to skip when starting horizontal line */ + Bit8u hlines_skip; + Bit8u bytes_skip; + +/* Specific stuff memory write/read handling */ + + 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 pitch; + Bitu blank; + bool double_width; + bool double_height; + Bitu lines; + Bit8u font_height; + Bit8u font[64*1024]; + Bitu font1_start; + Bitu font2_start; + Bitu rows,cols; + struct { + Bit8u sline,eline; + Bit8u count,delay; + Bit8u enabled; + } cursor; +} VGA_Draw; + +typedef struct { + Bit8u bank; + Bit8u reg_lock1; + Bit8u reg_lock2; + Bit8u reg_31; + Bit8u reg_35; + Bit8u reg_43; + Bit8u reg_58; + Bit8u reg_51; + Bit8u reg_55; + Bit8u ex_hor_overflow; + Bit8u ex_ver_overflow; + Bit16u la_window; + struct { + Bit8u r; + Bit8u n; + Bit8u m; + } clk[4],mclk; + struct { + Bit8u lock; + Bit8u cmd; + } pll; +} VGA_S3; + +typedef struct { + Bit8u mode_control; + Bit8u enable_bits; +} VGA_HERC; + +typedef struct { + Bit8u color_select; +} VGA_CGA; + +typedef struct { + Bit8u mem_bank; + Bit8u disp_bank; + Bit8u reg_index; + bool set_reg; +} 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; + +struct RGBEntry { + Bit8u red; + Bit8u green; + Bit8u blue; +}; + +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; + RGBEntry rgb[0x100]; + Bit8u attr[16]; +} VGA_Dac; + +union VGA_Latch { + Bit32u d; + Bit8u b[4]; +}; + +union VGA_Memory { + Bit8u linear[512*1024*4]; + Bit8u paged[512*1024][4]; + VGA_Latch latched[512*1024]; +}; + +typedef struct { + VGAModes mode; /* The mode the vga system is in */ + 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_HERC herc; + VGA_CGA cga; + VGA_TANDY tandy; + VGA_Memory mem; +} VGA_Type; + + + +/* Functions for different resolutions */ +void VGA_SetMode(VGAModes mode); +void VGA_SetupHandlers(void); +void VGA_StartResize(void); +void VGA_SetupDrawing(void); + +/* Some DAC/Attribute functions */ +void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal); +void VGA_ATTR_SetPalette(Bit8u index,Bit8u val); + +/* The VGA Subfunction startups */ +void VGA_SetupAttr(void); +void VGA_SetupMemory(void); +void VGA_SetupDAC(void); +void VGA_SetupCRTC(void); +void VGA_SetupMisc(void); +void VGA_SetupGFX(void); +void VGA_SetupSEQ(void); + +/* Some Support Functions */ +void VGA_SetClock(Bitu which,Bitu target); +void VGA_DACSetEntirePalette(void); +void VGA_StartRetrace(void); +void VGA_StartUpdateLFB(void); + +extern VGA_Type vga; + +extern Bit32u ExpandTable[256]; +extern Bit32u FillTable[16]; +extern Bit32u CGA_2_Table[16]; +extern Bit32u CGA_4_Table[256]; +extern Bit32u CGA_16_Table[256]; +extern Bit32u Expand16Table[4][16]; +extern Bit32u Expand16BigTable[0x10000]; + + +#endif + From 708eee4f86ffab62002dcde19a2f648f68a00dcf Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 22 Oct 2003 14:29:56 +0000 Subject: [PATCH 1274/4131] changed host memory reading/writing functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1355 --- src/dos/dos_execute.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 4c4147f7..05a1bba7 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -251,7 +251,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { /* Convert the header to correct endian, i hope this works */ HostPt endian=(HostPt)&head; for (i=0;i Date: Wed, 22 Oct 2003 14:30:57 +0000 Subject: [PATCH 1275/4131] Paging tables/functions changed somewhat Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1356 --- src/cpu/paging.cpp | 330 ++++++++++------------ src/hardware/memory.cpp | 592 +++++++++------------------------------- 2 files changed, 282 insertions(+), 640 deletions(-) diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 8f6c68b9..6d777b72 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -23,169 +23,165 @@ #include "dosbox.h" #include "mem.h" #include "paging.h" -#include "../hardware/vga.h" - +#include "regs.h" #define LINK_TOTAL (64*1024) -static PageLink link_list[LINK_TOTAL]; -struct PagingBlock paging; +PagingBlock paging; +static Bit32u mapfirstmb[LINK_START]; -class PageDirChange : public PageChange { -public: - PageDirChange(PageDirectory * mydir) { dir=mydir;} - void Changed(PageLink * link,Bitu start,Bitu end) { - start>>=2;end>>=2; - for (;start<=end;start++) { - dir->InvalidateTable(start); - } - } -private: - PageDirectory * dir; +Bitu PageHandler::readb(PhysPt addr) { + E_Exit("No byte handler for read from %d",addr); + return 0; +} +Bitu PageHandler::readw(PhysPt addr) { + return + (readb(addr+0) << 0) | + (readb(addr+1) << 8); +} +Bitu PageHandler::readd(PhysPt addr) { + return + (readb(addr+0) << 0) | + (readb(addr+1) << 8) | + (readb(addr+2) << 16) | + (readb(addr+3) << 24); +} + +void PageHandler::writeb(PhysPt addr,Bitu val) { + E_Exit("No byte handler for write to %d",addr); }; -class PageTableChange : public PageChange { +void PageHandler::writew(PhysPt addr,Bitu val) { + writeb(addr+0,(Bit8u) (val >> 0)); + writeb(addr+1,(Bit8u) (val >> 8)); +} +void PageHandler::writed(PhysPt addr,Bitu val) { + writeb(addr+0,(Bit8u) (val >> 0)); + writeb(addr+1,(Bit8u) (val >> 8)); + writeb(addr+2,(Bit8u) (val >> 16)); + writeb(addr+3,(Bit8u) (val >> 24)); +}; + +HostPt PageHandler::GetHostPt(Bitu phys_page) { + return 0; +} + + +class InitPageHandler : public PageHandler { public: - PageTableChange(PageDirectory * mydir) { dir=mydir;} - void Changed(PageLink * link,Bitu start,Bitu end) { - start>>=2;end>>=2; - for (;start<=end;start++) { - dir->InvalidateLink(link->data.table,start); - } + InitPageHandler() {flags=0;} + void AddPageLink(Bitu lin_page, Bitu phys_page) { + assert(0); + } + Bitu readb(PhysPt addr) { + InitPage(addr); + return mem_readb(addr); + } + Bitu readw(PhysPt addr) { + InitPage(addr); + return mem_readw(addr); + } + Bitu readd(PhysPt addr) { + InitPage(addr); + return mem_readd(addr); + } + void writeb(PhysPt addr,Bitu val) { + InitPage(addr); + mem_writeb(addr,val); + } + void writew(PhysPt addr,Bitu val) { + InitPage(addr); + mem_writew(addr,val); + } + void writed(PhysPt addr,Bitu val) { + InitPage(addr); + mem_writed(addr,val); + } + void InitPage(Bitu addr) { + Bitu lin_page=addr >> 12; + Bitu phys_page; + if (paging.enabled) { + E_Exit("No paging support"); + } else { + if (lin_pagedata.dir=this; - link_dir->change=dir_change; - MEM_CheckLinks(link_dir->entry); -} -void PageDirectory::LinkPage(Bitu lin_page,Bitu phys_page) { - if (links[lin_page] != &link_init) MEM_UnlinkPage(links[lin_page]); - PageLink * link=MEM_LinkPage(phys_page,lin_page*4096); - if (link) links[lin_page]=link; - else links[lin_page]=&link_init; -} - -bool PageDirectory::InitPage(Bitu lin_address) { - Bitu lin_page=lin_address >> 12; - Bitu table=lin_page >> 10; - Bitu index=lin_page & 0x3ff; - /* Check if there already is table linked */ - if (!tables[table]) { - X86PageEntry table_entry; - table_entry.load=phys_page_readd(base_page,0); - if (!table_entry.block.p) { - LOG(LOG_PAGING,LOG_ERROR)("NP TABLE"); - return false; - } - PageLink * link=MEM_LinkPage(table_entry.block.base,table_entry.block.base); - if (!link) return false; - link->data.table=table; - link->change=table_change; - MEM_CheckLinks(link->entry); - tables[table]=link; - } - X86PageEntry entry; - entry.load=phys_page_readd(tables[table]->lin_base,index); - if (!entry.block.p) { - LOG(LOG_PAGING,LOG_ERROR)("NP PAGE"); - return false; - } - PageLink * link=MEM_LinkPage(entry.block.base,lin_page*4096); - if (!link) return false; - links[lin_page]=link; - return true; -} - - -bool PageDirectory::InitPageLinear(Bitu lin_address) { - Bitu phys_page=lin_address >> 12; - PageLink * link=MEM_LinkPage(phys_page,phys_page*4096); - if (link) { - /* Set the page entry in our table */ - links[phys_page]=link; - return true; - } - return false; -} - - -void PageDirectory::InvalidateTable(Bitu table) { - if (tables[table]) { - MEM_UnlinkPage(tables[table]); - tables[table]=0; - for (Bitu i=(table*1024);i<(table+1)*1024;i++) { - if (links[i]!=&link_init) { - MEM_UnlinkPage(links[i]); - links[i]=&link_init; - } - } - } -} - -void PageDirectory::InvalidateLink(Bitu table,Bitu index) { - Bitu i=(table*1024)+index; - if (links[i]!=&link_init) { - MEM_UnlinkPage(links[i]); - links[i]=&link_init; - } -} +static InitPageHandler init_page_handler; Bitu PAGING_GetDirBase(void) { return paging.cr3; } +void PAGING_ClearTLB(void) { + LOG(LOG_PAGING,LOG_NORMAL)("Clearing TLB"); + Bitu i; + for (i=0;i0;pages--) { + Bitu page=*entries++; + paging.tlb.read[page]=0; + paging.tlb.write[page]=0; + paging.tlb.handler[page]=&init_page_handler; + } +} + +void PAGING_LinkPage(Bitu lin_page,Bitu phys_page) { + + PageHandler * handler=MEM_GetPageHandler(phys_page); + Bitu lin_base=lin_page << 12; + + HostPt host_mem=handler->GetHostPt(phys_page); + paging.tlb.phys_page[lin_page]=phys_page; + if (handler->flags & PFLAG_READABLE) paging.tlb.read[lin_page]=host_mem-lin_base; + else paging.tlb.read[lin_page]=0; + if (handler->flags & PFLAG_WRITEABLE) paging.tlb.write[lin_page]=host_mem-lin_base; + else paging.tlb.write[lin_page]=0; + + handler->AddPageLink(lin_page,phys_page); + paging.tlb.handler[lin_page]=handler; +} + +void PAGING_MapPage(Bitu lin_page,Bitu phys_page) { + if (lin_page> 12; - LOG(LOG_PAGING,LOG_NORMAL)("CR3:%X Base %X",cr3,base_page); + + paging.base.page=cr3 >> 12; + paging.base.addr=cr3 & ~4095; + LOG(LOG_PAGING,LOG_NORMAL)("CR3:%X Base %X",cr3,paging.base.page); if (paging.enabled) { - /* Check if we already have this one cached */ - PageDirectory * dir=paging.cache; - while (dir) { - if (dir->base_page==base_page) { - paging.dir=dir; - return; - } - dir=dir->next; - } - /* Couldn't find cached directory, make a new one */ - dir=new PageDirectory(); - dir->next=paging.cache; - paging.cache=dir; - dir->SetBase(base_page); - paging.dir=dir; + PAGING_ClearTLB(); } } @@ -195,7 +191,6 @@ void PAGING_Enable(bool enabled) { paging.enabled=enabled; if (!enabled) { LOG(LOG_PAGING,LOG_NORMAL)("Disabled"); - paging.dir=MEM_DefaultDirectory(); } else { LOG(LOG_PAGING,LOG_NORMAL)("Enabled"); #if !(C_DEBUG) @@ -203,51 +198,20 @@ void PAGING_Enable(bool enabled) { #endif PAGING_SetDirBase(paging.cr3); } + PAGING_ClearTLB(); } bool PAGING_Enabled(void) { return paging.enabled; } - -void PAGING_FreePageLink(PageLink * link) { - MEM_UnlinkPage(link); - PAGING_AddFreePageLink(link); -} - -void PAGING_LinkPage(PageDirectory * dir,Bitu lin_page,Bitu phys_page) { - PageLink * link=MEM_LinkPage(phys_page,lin_page*4096); - /* Only replace if we can */ - if (link) { - PAGING_FreePageLink(dir->links[lin_page]); - dir->links[lin_page]=link; +void PAGING_Init(Section * sec) { + /* Setup default Page Directory, force it to update */ + paging.enabled=false; + PAGING_InitTLB(); + Bitu i; + for (i=0;iread=0; - link->write=0; - link->change=0; - link->next=paging.free_link; - link->entry=0; - paging.free_link=link; -} - -PageLink * PAGING_GetFreePageLink(void) { - PageLink * ret; - if (paging.free_link) ret=paging.free_link; - else E_Exit("PAGING:Ran out of PageEntries"); - paging.free_link=ret->next; - ret->next=0; - return ret; -} - -void PAGING_Init(Section * sec) { - Bitu i; - /* Setup the free pages tables for fast page allocation */ - paging.cache=0; - paging.free_link=0; - for (i=0;itype) { - case ENTRY_VGA: - return (*vga.config.readhandler)(pentry->data.vga_base+(address & 4095)); - case ENTRY_NA: - if (pentry->data.dir->InitPageLinear(address)) return mem_readb(address); - break; - case ENTRY_INIT: - if (pentry->data.dir->InitPage(address)) return mem_readb(address); - break; +class IllegalPageHandler : public PageHandler { +public: + void AddPageLink(Bitu lin_page, Bitu phys_page) { - default: - LOG(LOG_PAGING,LOG_ERROR)("Entry read from %X with illegal type %d",address,pentry->type); + } + IllegalPageHandler() { + flags=0; + } +}; + +class RAMPageHandler : public PageHandler { +public: + void AddPageLink(Bitu lin_page, Bitu phys_page) { + /* Always clear links in first MB on TLB change */ + if (lin_page=memory.lfb.start_page) && (phys_pagetype) { - case ENTRY_VGA: - { - VGA_ReadHandler * handler=vga.config.readhandler; - address=pentry->data.vga_base + (address & 4095); - return (*handler)(address) | - ((*handler)(address+1) << 8); - } - case ENTRY_NA: - if (pentry->data.dir->InitPageLinear(address)) return mem_readw(address); - break; - case ENTRY_INIT: - if (pentry->data.dir->InitPage(address)) return mem_readw(address); - break; - default: - LOG(LOG_PAGING,LOG_ERROR)("Entry read from %X with illegal type %d",address,pentry->type); - } - return 0; -} - -Bit32u ENTRY_readd(PageEntry * pentry,PhysPt address) { - switch(pentry->type) { - case ENTRY_VGA: - { - VGA_ReadHandler * handler=vga.config.readhandler; - address=pentry->data.vga_base + (address & 4095); - return (*handler)(address) | - ((*handler)(address+1) << 8) | - ((*handler)(address+2) << 16) | - ((*handler)(address+3) << 24); - } - case ENTRY_NA: - if (pentry->data.dir->InitPageLinear(address)) return mem_readd(address); - break; - case ENTRY_INIT: - if (pentry->data.dir->InitPage(address)) return mem_readd(address); - break; - default: - LOG(LOG_PAGING,LOG_ERROR)("Entry read from %X with illegal type %d",address,pentry->type); - } - return 0; -} - -void ENTRY_writeb(PageEntry * pentry,PhysPt address,Bit8u val) { - switch(pentry->type) { - case ENTRY_VGA: - (*vga.config.writehandler)(pentry->data.vga_base+(address&4095),val); - break; - case ENTRY_NA: - if (pentry->data.dir->InitPageLinear(address)) mem_writeb(address,val); - break; - case ENTRY_INIT: - if (pentry->data.dir->InitPage(address)) mem_writeb(address,val); - break; - case ENTRY_ROM: - LOG(LOG_PAGING,LOG_WARN)("Write %X to ROM at %X",val,address); - break; - case ENTRY_CHANGES: - writeb(pentry->data.mem+(address&4095),val); - { - Bitu start=address&4095;Bitu end=start; - for (PageLink * link=pentry->links;link;link=link->next) - if (link->change) link->change->Changed(link,start,end); - } - break; - default: - LOG(LOG_PAGING,LOG_ERROR)("Entry write %X to %X with illegal type %d",val,address,pentry->type); +void MEM_SetPageHandler(Bitu phys_page,Bitu pages,PageHandler * handler) { + for (;pages>0;pages--) { + memory.phandlers[phys_page]=handler; + phys_page++; } } -void ENTRY_writew(PageEntry * pentry,PhysPt address,Bit16u val) { - switch(pentry->type) { - case ENTRY_VGA: - { - VGA_WriteHandler * handler=vga.config.writehandler; - address=pentry->data.vga_base+(address&4095); - (*handler)(address,(Bit8u)val); - (*handler)(address+1,(Bit8u)(val>>8)); - } - break; - case ENTRY_NA: - if (pentry->data.dir->InitPageLinear(address)) mem_writew(address,val); - break; - case ENTRY_INIT: - if (pentry->data.dir->InitPage(address)) mem_writew(address,val); - break; - case ENTRY_ROM: - LOG(LOG_PAGING,LOG_WARN)("Write %X to ROM at %X",val,address); - break; - case ENTRY_CHANGES: - writew(pentry->data.mem+(address&4095),val); - { - Bitu start=address&4095;Bitu end=start+1; - for (PageLink * link=pentry->links;link;link=link->next) - if (link->change) link->change->Changed(link,start,end); - } - break; - default: - LOG(LOG_PAGING,LOG_ERROR)("Entry write %X to %X with illegal type %d",val,address,pentry->type); - } +void MEM_UnlinkPages(void) { + PAGING_ClearTLBEntries(memory.links.used,memory.links.pages); } - -void ENTRY_writed(PageEntry * pentry,PhysPt address,Bit32u val) { - switch(pentry->type) { - case ENTRY_VGA: - { - VGA_WriteHandler * handler=vga.config.writehandler; - address=pentry->data.vga_base+(address&4095); - (*handler)(address,(Bit8u)val); - (*handler)(address+1,(Bit8u)(val>>8)); - (*handler)(address+2,(Bit8u)(val>>16)); - (*handler)(address+3,(Bit8u)(val>>24)); - } - break; - case ENTRY_NA: - if (pentry->data.dir->InitPageLinear(address)) mem_writed(address,val); - break; - case ENTRY_INIT: - if (pentry->data.dir->InitPage(address)) mem_writed(address,val); - break; - case ENTRY_ROM: - LOG(LOG_PAGING,LOG_WARN)("Write %X to ROM at %X",val,address); - break; - case ENTRY_CHANGES: - writed(pentry->data.mem+(address&4095),val); - { - Bitu start=address&4095;Bitu end=start+3; - for (PageLink * link=pentry->links;link;link=link->next) - if (link->change) link->change->Changed(link,start,end); - } - break; - default: - LOG(LOG_PAGING,LOG_ERROR)("Entry write %X to %X with illegal type %d",val,address,pentry->type); - } -} - - Bitu mem_strlen(PhysPt pt) { Bitu x=0; while (x<1024) { @@ -270,193 +198,11 @@ Bitu MEM_TotalPages(void) { return memory.pages; } -void MEM_UnlinkPage(PageLink * plink) { - PageLink * checker=plink->entry->links; - PageLink * * last=&plink->entry->links; - while (checker) { - if (checker == plink) { - *last=plink->next; - PAGING_AddFreePageLink(plink); - return; - } - last=&checker->next; - checker=checker->next; - } - E_Exit("Unlinking unlinked link"); - -} - -PageLink * MEM_LinkPage(Bitu phys_page,PhysPt lin_base) { - PageEntry * entry; - /* Check if it's in a valid memory range */ - if (phys_page=memory.lfb.start_page && phys_pagelin_base=lin_base; - link->change=0; - /* Check what kind of handler we need to give the page */ - switch (entry->type) { - case ENTRY_RAM: - link->read=entry->data.mem - lin_base; - link->write=link->read; - break; - case ENTRY_ROM: - link->read=entry->data.mem - lin_base; - link->write=0; - break; - case ENTRY_VGA: - link->read=0; - link->write=0; - break; - case ENTRY_LFB: - link->read=entry->data.mem - lin_base; - link->write=link->read; - break; - case ENTRY_ALLOC: - entry->type=ENTRY_RAM; - entry->data.mem=MEM_GetBlockPage(); - link->read=entry->data.mem - lin_base; - link->write=link->read; - break; - case ENTRY_CHANGES: - link->read=entry->data.mem - lin_base; - link->write=0; - break; - default: - E_Exit("LinkPage:Illegal type %d",entry->type); - } - /* Place the entry in the link */ - link->entry=entry; - link->next=entry->links; - entry->links=link; - return link; -} - - -void MEM_CheckLinks(PageEntry * theentry) { - if (theentry->type!=ENTRY_RAM && theentry->type!=ENTRY_CHANGES) { - LOG(LOG_PAGING,LOG_NORMAL)("Checking links on type %d",theentry->type); - return; - } - bool haschange=false;PageLink * link; - for (link=theentry->links;link;link=link->next) { - if (link->change) { - haschange=true;break; - } - } - if (haschange) { - theentry->type=ENTRY_CHANGES; - for (link=theentry->links;link;link=link->next) { - link->read=theentry->data.mem - link->lin_base; - link->write=0; - } - } else { - theentry->type=ENTRY_RAM; - for (link=theentry->links;link;link=link->next) { - link->read=theentry->data.mem - link->lin_base; - link->write=link->read; - } - } -} - -void MEM_AllocLinkMemory(PageEntry * theentry) { - //TODO Maybe check if this is a LINK_ALLOC type - HostPt themem=MEM_GetBlockPage(); - theentry->data.mem=themem; - theentry->type=ENTRY_RAM; - theentry->links=0; -} - -void MEM_SetLFB(Bitu page,Bitu pages,HostPt pt) { - if (pages>LFB_PAGES) E_Exit("MEM:LFB to large"); - LOG(LOG_PAGING,LOG_NORMAL)("LFB Base at address %X,page %X",page*4096,page); - memory.lfb.pages=pages; - memory.lfb.start_page=page; - memory.lfb.end_page=page+pages; - memory.lfb.address=pt; - for (Bitu i=0;idata.mem=themem; - theentry->type=ENTRY_LFB; - PageLink * link=theentry->links; - while (link) { - link->read=themem - link->lin_base; - link->write=link->read; - link=link->next; - } - } - memory.vga.range=range; - } - /* Setup the new range, check if it's gonna handler based */ - Bitu start,end; - switch (range) { - case VGA_RANGE_A000:start=0;end=16;break; - case VGA_RANGE_B000:start=16;end=24;break; - case VGA_RANGE_B800:start=24;end=32;break; - } - if (base) { - /* If it has an address it's a mapping */ - for (i=start;itype=ENTRY_LFB; - theentry->data.mem=themem; - PageLink * link=theentry->links; - while (link) { - link->read=themem - link->lin_base; - link->write=link->read; - link=link->next; - } - } - } else { - /* No address, so it'll be a handler */ - for (i=start;itype=ENTRY_VGA; - PhysPt thebase=(i-start)*4096; - PageLink * link=theentry->links; - theentry->data.vga_base=thebase; - while (link) { - link->read=0; - link->write=0; - link=link->next; - } - } - } -} - Bitu MEM_FreeLargest(void) { Bitu size=0;Bitu largest=0; Bitu index=XMS_START; while (indexlargest) largest=size; @@ -472,7 +218,7 @@ Bitu MEM_FreeTotal(void) { Bitu free=0; Bitu index=XMS_START; while (index0) { pages++; - handle=memory.entries[handle].next_handle; + handle=memory.mhandles[handle]; } return pages; } @@ -499,12 +245,12 @@ INLINE Bitu BestMatch(Bitu size) { /* Check if we are searching for first free page */ if (!first) { /* Check if this is a free page */ - if (!memory.entries[index].next_handle) { + if (!memory.mhandles[index]) { first=index; } } else { /* Check if this still is used page */ - if (memory.entries[index].next_handle) { + if (memory.mhandles[index]) { Bitu pages=index-first; if (pages==size) { return first; @@ -535,7 +281,7 @@ MemHandle MEM_AllocatePages(Bitu pages,bool sequence) { MemHandle * next=&ret; while (pages) { *next=index; - next=&memory.entries[index].next_handle; + next=&memory.mhandles[index]; index++;pages--; } *next=-1; @@ -545,9 +291,9 @@ MemHandle MEM_AllocatePages(Bitu pages,bool sequence) { while (pages) { Bitu index=BestMatch(1); if (!index) E_Exit("MEM:corruption during allocate"); - while (pages && (!memory.entries[index].next_handle)) { + while (pages && (!memory.mhandles[index])) { *next=index; - next=&memory.entries[index].next_handle; + next=&memory.mhandles[index]; index++;pages--; } *next=-1; //Invalidate it in case we need another match @@ -558,8 +304,8 @@ MemHandle MEM_AllocatePages(Bitu pages,bool sequence) { void MEM_ReleasePages(MemHandle handle) { while (handle>0) { - MemHandle next=memory.entries[handle].next_handle; - memory.entries[handle].next_handle=0; + MemHandle next=memory.mhandles[handle]; + memory.mhandles[handle]=0; handle=next; } } @@ -580,22 +326,22 @@ bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence) { while (index>0) { old_pages++; last=index; - index=memory.entries[index].next_handle; + index=memory.mhandles[index]; } if (old_pages == pages) return true; if (old_pages > pages) { /* Decrease size */ pages--;index=handle;old_pages--; while (pages) { - index=memory.entries[index].next_handle; + index=memory.mhandles[index]; pages--;old_pages--; } - MemHandle next=memory.entries[index].next_handle; - memory.entries[index].next_handle=-1; + MemHandle next=memory.mhandles[index]; + memory.mhandles[index]=-1; index=next; while (old_pages) { - next=memory.entries[index].next_handle; - memory.entries[index].next_handle=0; + next=memory.mhandles[index]; + memory.mhandles[index]=0; index=next; old_pages--; } @@ -606,17 +352,17 @@ bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence) { if (sequence) { index=last+1; Bitu free=0; - while ((index=need) { /* Enough space allocate more pages */ index=last; while (need) { - memory.entries[index].next_handle=index+1; + memory.mhandles[index]=index+1; need--;index++; } - memory.entries[index].next_handle=-1; + memory.mhandles[index]=-1; return true; } else { /* Not Enough space allocate new block and copy */ @@ -630,63 +376,38 @@ bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence) { } else { MemHandle rem=MEM_AllocatePages(need,false); if (!rem) return false; - memory.entries[last].next_handle=rem; + memory.mhandles[last]=rem; return true; } } return 0; } - -void MEM_UnmapPages(Bitu phys_page,Bitu pages) { - for (;pages;pages--) { - memory.dir.LinkPage(phys_page,phys_page); - phys_page++; - } -} - -void MEM_MapPagesHandle(Bitu lin_page,MemHandle mem,Bitu mem_page,Bitu pages) { - for (;mem_page;mem_page--) { - if (mem<=0) E_Exit("MEM:MapPages:Fault in memory tables"); - mem=memory.entries[mem].next_handle; - } - for (;pages;pages--) { - if (mem<=0) E_Exit("MEM:MapPages:Fault in memory tables"); - memory.dir.LinkPage(lin_page++,mem); - mem=memory.entries[mem].next_handle; - } -} - -void MEM_MapPagesDirect(Bitu lin_page,Bitu phys_page,Bitu pages) { - for (;pages;pages--) { - memory.dir.LinkPage(lin_page++,phys_page++); - } -} - MemHandle MEM_NextHandle(MemHandle handle) { - return memory.entries[handle].next_handle; + return memory.mhandles[handle]; } +MemHandle MEM_NextHandleAt(MemHandle handle,Bitu where) { + while (where) { + where--; + handle=memory.mhandles[handle]; + } + return handle; +} + + /* A20 line handling, Basically maps the 4 pages at the 1mb to 0mb in the default page directory */ bool MEM_A20_Enabled(void) { - return a20_enabled; + return memory.a20.enabled; } void MEM_A20_Enable(bool enabled) { - a20_enabled=enabled; - Bitu i; - if (!enabled) { - for (i=0x0;i<0x10;i++) { - memory.dir.LinkPage(0x100+i,i); - } - } else { - for (i=0x0;i<0x10;i++) { - memory.dir.LinkPage(0x100+i,0x100+i); - } - } + Bitu phys_base=enabled ? (1024/4) : 0; + for (Bitu i=0;i<16;i++) PAGING_MapPage((1024/4)+i,phys_base+i); + memory.a20.enabled=enabled; } @@ -742,20 +463,11 @@ void mem_writed(PhysPt address,Bit32u val) { } void phys_writeb(PhysPt addr,Bit8u val) { - Bitu page=addr>>12; - if (page>=memory.pages) E_Exit("physwrite:outside of physical range"); - PageEntry * theentry=&memory.entries[page]; - switch (theentry->type) { - case ENTRY_ALLOC: - MEM_AllocLinkMemory(theentry); - break; - case ENTRY_RAM: - case ENTRY_ROM: - break; - default: - E_Exit("physwrite:illegal type %d",theentry->type); + HostPt block=memory.hostpts[addr >> 12]; + if (!block) { + block=memory.hostpts[addr >> 12]=MEM_GetBlockPage(); } - writeb(theentry->data.mem+(addr & 4095),val); + host_writeb(block+(addr & 4095),val); } void phys_writew(PhysPt addr,Bit16u val) { @@ -771,17 +483,6 @@ void phys_writed(PhysPt addr,Bit32u val) { } Bit32u phys_page_readd(Bitu page,Bitu index) { - if (page>=memory.pages) E_Exit("physwrite:outside of physical range"); - PageEntry * theentry=&memory.entries[page]; - switch (theentry->type) { - case ENTRY_CHANGES: - case ENTRY_RAM: - case ENTRY_ROM: - return readd(memory.entries[page].data.mem+index*4); - break; - default: - E_Exit("pageread:illegal type %d",theentry->type); - } return 0; } @@ -789,19 +490,15 @@ Bit32u phys_page_readd(Bitu page,Bitu index) { static void write_p92(Bit32u port,Bit8u val) { // Bit 0 = system reset (switch back to real mode) if (val&1) E_Exit("XMS: CPU reset via port 0x92 not supported."); - controlport_data = val & ~2; + memory.a20.controlport = val & ~2; MEM_A20_Enable((val & 2)>0); } static Bit8u read_p92(Bit32u port) { - return controlport_data | (a20_enabled ? 0x02 : 0); + return memory.a20.controlport | (memory.a20.enabled ? 0x02 : 0); } -PageDirectory * MEM_DefaultDirectory(void) { - return &memory.dir; -} - HostPt MEM_GetBlockPage(void) { HostPt ret; if (memory.block.pages) { @@ -847,36 +544,17 @@ void MEM_Init(Section * sec) { memsize=MAX_MEMORY; } memory.pages=(memsize*1024*1024)/4096; - if (memory.pages>0x110) memory.free_pages=memory.pages-0x110; - else memory.free_pages=0; - - memory.entries= new PageEntry[memory.pages]; + /* Allocate the data for the different page information blocks */ + memory.hostpts=new HostPt[memory.pages]; + memory.phandlers=new PageHandler * [memory.pages]; + memory.mhandles=new MemHandle [memory.pages]; for (i=0;i Date: Wed, 22 Oct 2003 14:38:17 +0000 Subject: [PATCH 1276/4131] Small cleanups Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1357 --- src/hardware/vga_dac.cpp | 2 - src/hardware/vga_draw.cpp | 93 +++++++++++++++++++++++++++++++++------ 2 files changed, 80 insertions(+), 15 deletions(-) diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index b387d91b..ab3acdd8 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -22,8 +22,6 @@ #include "vga.h" /* -//TODO PEL Mask Maybe -//TODO Find some way to get palette lookups in groups 3C6h (R/W): PEL Mask bit 0-7 This register is anded with the palette index sent for each dot. Should be set to FFh. diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index cbdb01c5..1365795e 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -25,29 +25,42 @@ //TODO Make the full draw like the vga really does from video memory. +#define FIXED_CGA_SIZED 1 + +static void VGA_HERC_Draw(Bit8u * bitdata,Bitu pitch) { + Bit8u * reader=&vga.mem.linear[(vga.herc.mode_control & 0x80) ? 8*1024 : 0]; + for (Bitu y=0;y>3;x>0;x--) { + Bit8u val=*(tempread++); + *(Bit32u *)(draw+0)=CGA_2_Table[val >> 4]; + *(Bit32u *)(draw+4)=CGA_2_Table[val & 0xf]; + draw+=8; + } + if ((y & 3)==3) reader+=90; + bitdata+=pitch; + } +} + static void VGA_CGA2_Draw(Bit8u * bitdata,Bitu pitch) { Bit8u * reader=&vga.mem.linear[0]; Bit8u * flip=&vga.mem.linear[8*1024]; Bit8u * draw; for (Bitu y=0;y>3;x>0;x--) { Bit8u val=*(tempread++); - *(draw+0)=(val>>7)&1; - *(draw+1)=(val>>6)&1; - *(draw+2)=(val>>5)&1; - *(draw+3)=(val>>4)&1; - *(draw+4)=(val>>3)&1; - *(draw+5)=(val>>2)&1; - *(draw+6)=(val>>1)&1; - *(draw+7)=(val>>0)&1; + *(Bit32u *)(draw+0)=CGA_2_Table[val >> 4]; + *(Bit32u *)(draw+4)=CGA_2_Table[val & 0xf]; draw+=8; } bitdata+=pitch; @@ -76,6 +89,37 @@ static void VGA_CGA4_Draw(Bit8u * bitdata,Bitu pitch) { } } + +static Bit8u convert16[16]={ + 0x0,0x2,0x1,0x3,0x5,0x7,0x4,0x9, + 0x6,0xa,0x8,0xb,0xd,0xe,0xc,0xf +}; + +static void VGA_CGA16_Draw(Bit8u * bitdata,Bitu pitch) { + Bit8u * reader=&vga.mem.linear[0]; + Bit8u * flip=&vga.mem.linear[8*1024]; + Bit8u * draw; + for (Bitu y=0;y<200;y++) { + Bit8u * tempread; + tempread=reader; + if (y&1) { + tempread+=8*1024; + reader+=80; + if (reader>=flip) reader-=8*1024; + } + draw=bitdata; + for (Bitu x=0;x<80;x++) { + Bit8u val=*(tempread++); + + Bit32u full=convert16[(val & 0xf0) >> 4] | convert16[val & 0xf] << 16; + full|=full<<8; + *(Bit32u *)draw=full; + draw+=4; + } + bitdata+=pitch; + } +} + static void VGA_TANDY16_Draw(Bit8u * bitdata,Bitu pitch) { Bit8u * reader=&vga.mem.linear[(vga.tandy.disp_bank << 14) + vga.config.display_start*2]; @@ -231,6 +275,7 @@ void VGA_DrawHandler(RENDER_Part_Handler part_handler) { buf=&vga.mem.linear[vga.config.real_start*4+vga.config.pel_panning]; bufsplit=vga.mem.linear; break; + case M_TEXT2: case M_TEXT16: { Bitu first_rows=stop/vga.draw.font_height; @@ -253,6 +298,10 @@ void VGA_DrawHandler(RENDER_Part_Handler part_handler) { } else { drawnormal: switch (vga.mode) { + case M_HERC: + VGA_HERC_Draw(&vga.mem.linear[512*1024],vga.draw.width); + buf=&vga.mem.linear[512*1024]; + break; case M_CGA2: VGA_CGA2_Draw(&vga.mem.linear[512*1024],vga.draw.width); buf=&vga.mem.linear[512*1024]; @@ -261,6 +310,10 @@ drawnormal: VGA_CGA4_Draw(&vga.mem.linear[512*1024],vga.draw.width); buf=&vga.mem.linear[512*1024]; break; + case M_CGA16: + VGA_CGA16_Draw(&vga.mem.linear[512*1024],vga.draw.width); + buf=&vga.mem.linear[512*1024]; + break; case M_TANDY16: VGA_TANDY16_Draw(&vga.mem.linear[512*1024],vga.draw.width); buf=&vga.mem.linear[512*1024]; @@ -272,6 +325,7 @@ drawnormal: case M_LIN8: buf=&vga.mem.linear[vga.config.real_start*4+vga.config.pel_panning]; break; + case M_TEXT2: case M_TEXT16: { Bitu rows=vga.draw.rows; @@ -358,20 +412,33 @@ void VGA_SetupDrawing(void) { pitch=vga.config.scan_len*16; break; case M_CGA4: - width<<=3; + case M_CGA16: //Let is use 320x200 res and double pixels myself + vga.draw.double_width=true; //Hack if there's a runtime switch + vga.draw.double_height=true; //Hack if there's a runtime switch + width<<=2; pitch=width; break; case M_CGA2: + vga.draw.double_width=false; //Hack if there's a runtime switch width<<=3; pitch=width; break; + case M_HERC: + vga.draw.double_height=false; //Hack if there's a runtime switch + width*=9; + height=384; + pitch=width; + break; case M_TANDY16: width<<=3; pitch=width; break; + case M_TEXT2: case M_TEXT16: - /* probably a 16-color text mode, got to detect mono mode somehow */ vga.draw.font_height=vga.config.vline_height+1; + if (vga.draw.font_height<4 && (machine Date: Wed, 22 Oct 2003 14:44:41 +0000 Subject: [PATCH 1277/4131] updated ems/dpmi functions for new paging mapping Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1358 --- src/ints/dpmi.cpp | 29 ++++++++++++++++------------- src/ints/ems.cpp | 10 ++++++++-- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index 1f6f8696..79287516 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -37,6 +37,7 @@ #include "setup.h" #include "inout.h" #include "cpu.h" +#include "paging.h" #include "debug.h" @@ -1485,8 +1486,8 @@ Bitu DPMI::Int31Handler(void) SetDescriptor desc; if (cpu.gdt.GetDescriptor(reg_bx,desc)) { DPMI_LOG("DPMI: 0006: Get Base %04X : B:%08X",reg_bx,desc.GetBase()); - reg_cx = desc.GetBase()>>16; - reg_dx = desc.GetBase()&0xFFFF; + reg_cx = (Bit16u)(desc.GetBase()>>16); + reg_dx = (Bit16u)(desc.GetBase()&0xFFFF); DPMI_CALLBACK_SCF(false); } else { DPMI_LOG_ERROR("DPMI: 0006: Invalid Selector: %04X",reg_bx); @@ -1886,18 +1887,18 @@ Bitu DPMI::Int31Handler(void) DPMI_LOG("DPMI: 0503: Resize Memory: H:%08X (%d KB)",handle,newSize*4); if (MEM_ReAllocatePages(handle,newSize,true)) { linear = handle * DPMI_PAGE_SIZE; - reg_si = handle>>16; - reg_di = handle&0xFFFF; - reg_bx = linear>>16; - reg_cx = linear&0xFFFF; + reg_si = (Bit16u)(handle>>16); + reg_di = (Bit16u)(handle&0xFFFF); + reg_bx = (Bit16u)(linear>>16); + reg_cx = (Bit16u)(linear&0xFFFF); DPMI_CALLBACK_SCF(false); } else if (AllocateMem(newByte,newHandle,linear)) { // Not possible, try to allocate DPMI_LOG("DPMI: 0503: Reallocated Memory: %d KB",newSize*4); - reg_si = newHandle>>16; - reg_di = newHandle&0xFFFF; - reg_bx = linear>>16; - reg_cx = linear&0xFFFF; + reg_si = (Bit16u)(newHandle>>16); + reg_di = (Bit16u)(newHandle&0xFFFF); + reg_bx = (Bit16u)(linear>>16); + reg_cx = (Bit16u)(linear&0xFFFF); // copy contents Bitu size = MEM_AllocatedPages(handle); if (newSize>16; reg_cx = linear & 0xFFFF; diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index de226fd8..6efb5131 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -156,13 +156,19 @@ static Bit8u EMM_MapPage(Bitu phys_page,Bit16u handle,Bit16u log_page) { /* Mapping it is */ emm_mappings[phys_page].handle=handle; emm_mappings[phys_page].page=log_page; - MEM_MapPagesHandle(EMM_PAGEFRAME4K+phys_page*4,emm_handles[handle].mem,log_page*4,4); + + MemHandle memh=MEM_NextHandleAt(emm_handles[handle].mem,log_page*4);; + for (Bitu i=0;i<4;i++) { + PAGING_MapPage(EMM_PAGEFRAME4K+phys_page*4+i,memh); + memh=MEM_NextHandle(memh); + } return EMM_NO_ERROR; } else if (log_page==NULL_PAGE) { /* Unmapping it is */ emm_mappings[phys_page].handle=NULL_HANDLE; emm_mappings[phys_page].page=NULL_PAGE; - MEM_UnmapPages(EMM_PAGEFRAME4K+phys_page*4,4); + for (Bitu i=0;i<4;i++) + PAGING_MapPage(EMM_PAGEFRAME4K+phys_page*4+i,EMM_PAGEFRAME4K+phys_page*4+i); return EMM_NO_ERROR; } else { /* Illegal logical page it is */ From 97e1c2dc4279eeda5ba6cadb6b29be088c1881e8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 22 Oct 2003 14:45:54 +0000 Subject: [PATCH 1278/4131] changes for different machine types Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1359 --- src/ints/int10.cpp | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 4a7d2db7..5587041a 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -25,7 +25,9 @@ #include "video.h" #include "inout.h" #include "int10.h" -#include "../hardware/vga.h" /* Maybe move this thing */ +#include "setup.h" +#include "support.h" +#include "vga.h" Int10Data int10; static Bitu call_10; @@ -70,7 +72,7 @@ static Bitu INT10_Handler(void) { reg_ah=0; break; case 0x05: /* Set Active Page */ - if (reg_al & 0x80) LOG(LOG_INT10,LOG_NORMAL)("Func %x",reg_al); + if (reg_al & 0x80) LOG(LOG_INT10,LOG_NORMAL)("Tandy set CRT/CPU Page Func %x",reg_al); else INT10_SetActivePage(reg_al); break; case 0x06: /* Scroll Up */ @@ -105,7 +107,7 @@ static Bitu INT10_Handler(void) { INT10_GetPixel(reg_cx,reg_dx,reg_bh,®_al); break; case 0x0E: /* Teletype OutPut */ - INT10_TeletypeOutput(reg_al,reg_bl,false); + INT10_TeletypeOutput(reg_al,reg_bl); break; case 0x0F: /* Get videomode */ reg_bh=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); @@ -255,6 +257,7 @@ graphics_chars: } break; case 0x12: /* alternate function select */ + if (machine Date: Wed, 22 Oct 2003 14:50:28 +0000 Subject: [PATCH 1279/4131] More tandy/cga/hercules support, determined by machine type. Changed teletype output function with attirbutes Mono text mode support somewhat Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1360 --- src/ints/int10.h | 5 +- src/ints/int10_char.cpp | 104 ++++++++++++++----- src/ints/int10_memory.cpp | 5 +- src/ints/int10_misc.cpp | 2 + src/ints/int10_modes.cpp | 192 ++++++++++++++++++++++------------- src/ints/int10_pal.cpp | 17 ++-- src/ints/int10_put_pixel.cpp | 22 +++- 7 files changed, 237 insertions(+), 110 deletions(-) diff --git a/src/ints/int10.h b/src/ints/int10.h index b6bfca58..da3cccd7 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "../hardware/vga.h" +#include "vga.h" #define S3_LFB_BASE 0xC0000000 @@ -144,7 +144,8 @@ void INT10_GetFuncStateInformation(PhysPt save); void INT10_SetCursorShape(Bit8u first,Bit8u last); void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page); -void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr); +void INT10_TeletypeOutput(Bit8u chr,Bit8u attr); +void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr); void INT10_ReadCharAttr(Bit16u * result,Bit8u page); void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr); void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,Bit16u count,Bit8u page); diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 26e755b0..e4b70950 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.19 2003-09-24 19:33:26 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.20 2003-10-22 14:50:28 harekiet Exp $ */ /* Character displaying moving functions */ @@ -26,18 +26,32 @@ #include "inout.h" #include "int10.h" -static INLINE void CGA_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { +static INLINE void CGA4_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); PhysPt dest=base+((CurMode->twidth*rnew)*(cheight/2)+cleft)*2; PhysPt src=base+((CurMode->twidth*rold)*(cheight/2)+cleft)*2; Bitu copy=(cright-cleft)*2;Bitu nextline=CurMode->twidth*2; - for (Bitu i=0;itwidth*rnew)*(cheight/4)+cleft)*4; + PhysPt src=base+((CurMode->twidth*rold)*(cheight/4)+cleft)*4; + Bitu copy=(cright-cleft)*4;Bitu nextline=CurMode->twidth*4; + for (Bitu i=0;itwidth*row)*(cheight/2)+cleft)*2; Bitu copy=(cright-cleft)*2;Bitu nextline=CurMode->twidth*2; - for (Bitu i=0;itwidth*row)*cheight+cleft)*4; + Bitu copy=(cright-cleft)*4;Bitu nextline=CurMode->twidth*4; + attr=(attr & 0xf) | (attr & 0xf) << 4; + for (Bitu i=0;itype!=M_TEXT16) page=0xff; + if (CurMode->type>M_TEXT16) page=0xff; BIOS_NCOLS;BIOS_NROWS; if(rul>rlr) return; if(cul>clr) return; @@ -142,11 +175,14 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit while (start!=end) { start+=next; switch (CurMode->type) { + case M_TEXT2: case M_TEXT16: TEXT_CopyRow(cul,clr,start,start+nlines,base);break; - case M_CGA2: +// case M_CGA2: case M_CGA4: - CGA_CopyRow(cul,clr,start,start+nlines,base);break; + CGA4_CopyRow(cul,clr,start,start+nlines,base);break; + case M_TANDY16: + TANDY16_CopyRow(cul,clr,start,start+nlines,base);break; case M_EGA16: EGA16_CopyRow(cul,clr,start,start+nlines,base);break; default: @@ -163,11 +199,14 @@ filling: } for (;nlines>0;nlines--) { switch (CurMode->type) { + case M_TEXT2: case M_TEXT16: TEXT_FillRow(cul,clr,start,base,attr);break; - case M_CGA2: +// case M_CGA2: case M_CGA4: - CGA_FillRow(cul,clr,start,base,attr);break; + CGA4_FillRow(cul,clr,start,base,attr);break; + case M_TANDY16: + TANDY16_FillRow(cul,clr,start,base,attr);break; case M_EGA16: EGA16_FillRow(cul,clr,start,base,attr);break; default: @@ -187,10 +226,11 @@ void INT10_SetActivePage(Bit8u page) { real_writew(BIOSMEM_SEG,BIOSMEM_CURRENT_START,mem_address); if (CurMode->mode<0x8) mem_address>>=1; /* Write the new start address in vgahardware */ - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0c); - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(Bit8u)(mem_address>>8)); - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0d); - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(Bit8u)mem_address); + Bit16u base=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + IO_Write(base,0x0c); + IO_Write(base+1,(Bit8u)(mem_address>>8)); + IO_Write(base,0x0d); + IO_Write(base+1,(Bit8u)mem_address); // And change the BIOS page real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE,page); @@ -243,8 +283,9 @@ void INT10_SetCursorShape(Bit8u first,Bit8u last) { } } dowrite: - IO_Write(0x3d4,0xa);IO_Write(0x3d5,first); - IO_Write(0x3d4,0xb);IO_Write(0x3d5,last); + Bit16u base=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + IO_Write(base,0xa);IO_Write(base+1,first); + IO_Write(base,0xb);IO_Write(base+1,last); } @@ -263,10 +304,11 @@ void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page) { // Calculate the address knowing nbcols nbrows and page num address=(ncols*row)+col+real_readw(BIOSMEM_SEG,BIOSMEM_CURRENT_START); // CRTC regs 0x0e and 0x0f - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0e); - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(Bit8u)(address>>8)); - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0f); - IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(Bit8u)address); + Bit16u base=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + IO_Write(base,0x0e); + IO_Write(base+1,(Bit8u)(address>>8)); + IO_Write(base,0x0f); + IO_Write(base+1,(Bit8u)address); } } @@ -290,6 +332,7 @@ static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool Bitu x,y; Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); switch (CurMode->type) { + case M_TEXT2: case M_TEXT16: { // Compute the address @@ -305,6 +348,7 @@ static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool return; case M_CGA4: case M_CGA2: + case M_TANDY16: if (chr<128) fontdata=Real2Phys(RealGetVec(0x43))+chr*cheight; //was plain 8 else { chr-=128; @@ -335,7 +379,7 @@ static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) { //TODO Check if this page thing is correct - if (CurMode->type!=M_TEXT16) page=0xff; + if (CurMode->type>M_TEXT16) page=0xff; if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); @@ -351,8 +395,7 @@ void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) } } - -void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr) { +void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr) { //TODO Check if this page thing is correct Bit8u page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); BIOS_NCOLS;BIOS_NROWS; @@ -375,14 +418,14 @@ void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr) { break; case '\t': do { - INT10_TeletypeOutput(' ',attr,showattr); + INT10_TeletypeOutputAttr(' ',attr,useattr); cur_row=CURSOR_POS_ROW(page); cur_col=CURSOR_POS_COL(page); } while(cur_col%8); break; default: /* Draw the actual Character */ - WriteChar(cur_col,cur_row,page,chr,attr,showattr); + WriteChar(cur_col,cur_row,page,chr,attr,useattr); cur_col++; } if(cur_col==ncols) { @@ -398,9 +441,14 @@ void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr) { INT10_SetCursorPos(cur_row,cur_col,page); } + +void INT10_TeletypeOutput(Bit8u chr,Bit8u attr) { + INT10_TeletypeOutputAttr(chr,attr,CurMode->type>M_TEXT16); +} + void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,Bit16u count,Bit8u page) { //TODO Check if this page thing is correct - if (CurMode->type!=M_TEXT16) page=0xff; + if (CurMode->type>M_TEXT16) page=0xff; if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); BIOS_NCOLS;BIOS_NROWS; @@ -420,8 +468,8 @@ void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,B if (flag&2) { attr=mem_readb(string); string++; - } - INT10_TeletypeOutput(chr,attr,true); + } else attr=7; + INT10_TeletypeOutputAttr(chr,attr,flag & 2); count--; } if (flag & 1) { diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index af827cec..7d42c366 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -59,8 +59,9 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu /* Reload tables and registers with new values based on this height */ if (reload) { //Max scanline - IO_Write(0x3d4,0x9); - IO_Write(0x3d5,(IO_Read(0x3d5) & 0xe0)|(height-1)); + Bit16u base=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + IO_Write(base,0x9); + IO_Write(base+1,(IO_Read(base+1) & 0xe0)|(height-1)); //Vertical display end bios says, but should stay the same? //Rows setting in bios segment real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,(CurMode->sheight/height)-1); diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 40a8a918..2f5987f0 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -93,6 +93,8 @@ void INT10_GetFuncStateInformation(PhysPt save) { switch (CurMode->type) { case M_TEXT16: col_count=16;break; + case M_TEXT2: + col_count=2;break; // ?? case M_CGA2: col_count=2;break; case M_CGA4: diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 9cf4e1fc..e26e739e 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -21,12 +21,12 @@ VideoModeBlock ModeList[]={ { 0x001 ,M_TEXT16 ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_HALF_CLOCK }, { 0x002 ,M_TEXT16 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, { 0x003 ,M_TEXT16 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, -{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, -{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, +{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,_LINE_DOUBLE }, +{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,_LINE_DOUBLE }, { 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,_LINE_DOUBLE }, -{ 0x007 ,M_TEXT16 ,720 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x007 ,M_TEXT2 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, /* 8,9,0xa are tandy modes */ -{ 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, +{ 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, { 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, { 0x00E ,M_EGA16 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,_LINE_DOUBLE }, @@ -34,11 +34,16 @@ VideoModeBlock ModeList[]={ { 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,1 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, { 0x011 ,M_EGA2 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,449 ,80 ,480 ,0 }, { 0x012 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, -{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,_VGA_LINE_DOUBLE }, +{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,_VGA_PIXEL_DOUBLE | _VGA_LINE_DOUBLE }, { 0x100 ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, { 0x101 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, +{ 0x150 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE | _VGA_LINE_DOUBLE }, +{ 0x151 ,M_LIN8 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE | _VGA_LINE_DOUBLE }, +{ 0x152 ,M_LIN8 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE }, +{ 0x153 ,M_LIN8 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE }, + {0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, }; @@ -67,6 +72,18 @@ static Bit8u ega_palette[64][3]= {0x15,0x15,0x15}, {0x15,0x15,0x3f}, {0x15,0x3f,0x15}, {0x15,0x3f,0x3f}, {0x3f,0x15,0x15}, {0x3f,0x15,0x3f}, {0x3f,0x3f,0x15}, {0x3f,0x3f,0x3f} }; +#if 0 +static Bit8u cga_palette[64][3]= { + {0x00,0x00,0x00}, {0x00,0x00,0x1f}, {0x00,0x1f,0x00}, {0x00,0x1f,0x1f}, {0x1f,0x00,0x00}, {0x1f,0x00,0x1f}, {0x1f,0x1f,0x00}, {0x1f,0x1f,0x1f}, + {0x0f,0x0f,0x0f}, {0x00,0x00,0x3f}, {0x00,0x3f,0x00}, {0x00,0x3f,0x3f}, {0x3f,0x00,0x00}, {0x3f,0x00,0x3f}, {0x3f,0x3f,0x00}, {0x3f,0x3f,0x3f}, +}; +#else +static Bit8u cga_palette[16][3]= { + {0x00,0x00,0x00}, {0x00,0x00,0x2a}, {0x00,0x2a,0x00}, {0x00,0x2a,0x2a}, {0x2a,0x00,0x00}, {0x2a,0x00,0x2a}, {0x2a,0x15,0x00}, {0x2a,0x2a,0x2a}, + {0x15,0x15,0x15}, {0x15,0x15,0x3f}, {0x15,0x3f,0x15}, {0x15,0x3f,0x3f}, {0x3f,0x15,0x15}, {0x3f,0x15,0x3f}, {0x3f,0x3f,0x15}, {0x3f,0x3f,0x3f}, +}; +#endif + static Bit8u vga_palette[256][3]= { @@ -114,7 +131,6 @@ bool INT10_SetVideoMode(Bitu mode) { bool clearmem=true; Bit8u modeset_ctl,video_ctl,vga_switches; - Bit16u crtc_addr; if (mode<256) { if (mode & 128) { @@ -143,9 +159,17 @@ foundmode: /* Setup the VGA to the correct mode */ VGA_SetMode(CurMode->type); - + + Bit16u crtc_base; + bool mono_mode=CurMode->type == M_TEXT2; + if (mono_mode) { + crtc_base=0x3b4; + } else { + crtc_base=0x3d4; + } /* Setup MISC Output Register */ - Bit8u misc_output=0x3; //Color and cpu memory access + Bit8u misc_output=0x2 | (mono_mode ? 0x0 : 0x1); + IO_Write(0x3c2,misc_output); //Setup for 3b4 or 3d4 /* Program Sequencer */ Bit8u seq_data[SEQ_REGS]; memset(seq_data,0,SEQ_REGS); @@ -154,6 +178,7 @@ foundmode: (CurMode->special & _HALF_CLOCK) ? 0x08 : 0x00; seq_data[4]|=0x02; //More than 64kb switch (CurMode->type) { + case M_TEXT2: case M_TEXT16: seq_data[2]|=0x3; //Enable plane 0 and 1 seq_data[4]|=0x05; //Alpanumeric and odd/even enabled @@ -173,22 +198,22 @@ foundmode: } /* Program CRTC */ /* First disable write protection */ - IO_Write(0x3d4,0x11); - IO_Write(0x3d5,IO_Read(0x3d5)&0x7f); + IO_Write(crtc_base,0x11); + IO_Write(crtc_base+1,IO_Read(crtc_base+1)&0x7f); /* Clear all the regs */ for (i=0x0;i<=0x18;i++) { - IO_Write(0x3d4,i);IO_Write(0x3d5,0); + IO_Write(crtc_base,i);IO_Write(crtc_base+1,0); } Bit8u overflow=0;Bit8u max_scanline=0; Bit8u ver_overflow=0;Bit8u hor_overflow=0; /* Horizontal Total */ - IO_Write(0x3d4,0x00);IO_Write(0x3d5,CurMode->htotal-5); + IO_Write(crtc_base,0x00);IO_Write(crtc_base+1,CurMode->htotal-5); hor_overflow|=((CurMode->htotal-5) & 0x100) >> 8; /* Horizontal Display End */ - IO_Write(0x3d4,0x01);IO_Write(0x3d5,CurMode->hdispend-1); + IO_Write(crtc_base,0x01);IO_Write(crtc_base+1,CurMode->hdispend-1); hor_overflow|=((CurMode->hdispend-1) & 0x100) >> 7; /* Start horizontal Blanking */ - IO_Write(0x3d4,0x02);IO_Write(0x3d5,CurMode->hdispend); + IO_Write(crtc_base,0x02);IO_Write(crtc_base+1,CurMode->hdispend); hor_overflow|=((CurMode->hdispend) & 0x100) >> 6; /* End horizontal Blanking */ Bitu blank_end; @@ -197,7 +222,7 @@ foundmode: } else { blank_end = (CurMode->htotal-2) & 0x7f; } - IO_Write(0x3d4,0x03);IO_Write(0x3d5,0x80|(blank_end & 0x1f)); + IO_Write(crtc_base,0x03);IO_Write(crtc_base+1,0x80|(blank_end & 0x1f)); // hor_overflow|=(blank_end & 0x40) >> 3; /* Start Horizontal Retrace */ @@ -207,7 +232,7 @@ foundmode: } else { ret_start = (CurMode->hdispend+4); } - IO_Write(0x3d4,0x04);IO_Write(0x3d5,ret_start); + IO_Write(crtc_base,0x04);IO_Write(crtc_base+1,ret_start); hor_overflow|=(ret_start & 0x100) >> 4; /* End Horizontal Retrace */ Bitu ret_end; @@ -216,12 +241,12 @@ foundmode: } else { ret_end = (CurMode->htotal-4) & 0x3f; } - IO_Write(0x3d4,0x05);IO_Write(0x3d5,(ret_end & 0x1f) | (blank_end & 0x20) << 2); + IO_Write(crtc_base,0x05);IO_Write(crtc_base+1,(ret_end & 0x1f) | (blank_end & 0x20) << 2); // hor_overflow|=(ret_end & 0x20); //TODO Be sure about these ending values in extended overflow of s3 /* Vertical Total */ - IO_Write(0x3d4,0x06);IO_Write(0x3d5,(CurMode->vtotal-2)); + IO_Write(crtc_base,0x06);IO_Write(crtc_base+1,(CurMode->vtotal-2)); overflow|=((CurMode->vtotal-2) & 0x100) >> 8; overflow|=((CurMode->vtotal-2) & 0x200) >> 4; ver_overflow|=((CurMode->vtotal-2) & 0x400) >> 10; @@ -231,29 +256,29 @@ foundmode: So you get same sized borders, but okay :) */ /* Vertical Retrace Start */ - IO_Write(0x3d4,0x10);IO_Write(0x3d5,(CurMode->vdispend+12)); + IO_Write(crtc_base,0x10);IO_Write(crtc_base+1,(CurMode->vdispend+12)); overflow|=((CurMode->vdispend+12) & 0x100) >> 6; overflow|=((CurMode->vdispend+12) & 0x200) >> 2; ver_overflow|=((CurMode->vdispend+12) & 0x400) >> 6; /* Vertical Retrace End */ - IO_Write(0x3d4,0x11);IO_Write(0x3d5,(CurMode->vdispend+14) & 0xF); + IO_Write(crtc_base,0x11);IO_Write(crtc_base+1,(CurMode->vdispend+14) & 0xF); /* Vertical Display End */ - IO_Write(0x3d4,0x12);IO_Write(0x3d5,(CurMode->vdispend-1)); + IO_Write(crtc_base,0x12);IO_Write(crtc_base+1,(CurMode->vdispend-1)); overflow|=((CurMode->vdispend-1) & 0x100) >> 7; overflow|=((CurMode->vdispend-1) & 0x200) >> 3; ver_overflow|=((CurMode->vdispend-1) & 0x400) >> 9; /* Vertical Blank Start */ - IO_Write(0x3d4,0x15);IO_Write(0x3d5,(CurMode->vdispend+8)); + IO_Write(crtc_base,0x15);IO_Write(crtc_base+1,(CurMode->vdispend+8)); overflow|=((CurMode->vdispend+8) & 0x100) >> 5; max_scanline|=((CurMode->vdispend+8) & 0x200) >> 3; ver_overflow|=((CurMode->vdispend+8) & 0x400) >> 8; /* Vertical Retrace End */ - IO_Write(0x3d4,0x16);IO_Write(0x3d5,(CurMode->vtotal-8)); + IO_Write(crtc_base,0x16);IO_Write(crtc_base+1,(CurMode->vtotal-8)); /* Line Compare */ Bitu line_compare=CurMode->vtotal+1; //Out of range - IO_Write(0x3d4,0x18);IO_Write(0x3d5,line_compare&0xff); + IO_Write(crtc_base,0x18);IO_Write(crtc_base+1,line_compare&0xff); overflow|=(line_compare & 0x100) >> 4; max_scanline|=(line_compare & 0x200) >> 3; ver_overflow|=(line_compare & 0x400) >> 4; @@ -261,8 +286,9 @@ foundmode: /* Maximum scanline / Underline Location */ if (CurMode->special & _LINE_DOUBLE) max_scanline|=0x80; switch (CurMode->type) { + case M_TEXT2: case M_TEXT16: - max_scanline|=CurMode->theight-1; + max_scanline|=CurMode->cheight-1; underline=0x1f; break; case M_VGA: @@ -275,23 +301,23 @@ foundmode: if (CurMode->special & _VGA_LINE_DOUBLE) max_scanline|=1; break; } - IO_Write(0x3d4,0x09);IO_Write(0x3d5,max_scanline); - IO_Write(0x3d4,0x14);IO_Write(0x3d5,underline); + IO_Write(crtc_base,0x09);IO_Write(crtc_base+1,max_scanline); + IO_Write(crtc_base,0x14);IO_Write(crtc_base+1,underline); /* OverFlow */ - IO_Write(0x3d4,0x07);IO_Write(0x3d5,overflow); + IO_Write(crtc_base,0x07);IO_Write(crtc_base+1,overflow); /* Extended Horizontal Overflow */ - IO_Write(0x3d4,0x5d);IO_Write(0x3d5,hor_overflow); + IO_Write(crtc_base,0x5d);IO_Write(crtc_base+1,hor_overflow); /* Extended Vertical Overflow */ - IO_Write(0x3d4,0x5e);IO_Write(0x3d5,ver_overflow); + IO_Write(crtc_base,0x5e);IO_Write(crtc_base+1,ver_overflow); /* Offset Register */ - IO_Write(0x3d4,0x13); + IO_Write(crtc_base,0x13); switch (CurMode->type) { case M_LIN8: - IO_Write(0x3d5,CurMode->swidth/8); + IO_Write(crtc_base+1,CurMode->swidth/8); break; default: - IO_Write(0x3d5,CurMode->hdispend/2); + IO_Write(crtc_base+1,CurMode->hdispend/2); } /* Mode Control */ Bit8u mode_control=0; @@ -303,6 +329,7 @@ foundmode: case M_EGA16: mode_control=0xe3; break; + case M_TEXT2: case M_TEXT16: case M_VGA: mode_control=0xa3; @@ -310,12 +337,11 @@ foundmode: case M_LIN8: mode_control=0xab; break; - } - IO_Write(0x3d4,0x17);IO_Write(0x3d5,mode_control); + IO_Write(crtc_base,0x17);IO_Write(crtc_base+1,mode_control); /* Renable write protection */ - IO_Write(0x3d4,0x11); - IO_Write(0x3d5,IO_Read(0x3d5)|0x80); + IO_Write(crtc_base,0x11); + IO_Write(crtc_base+1,IO_Read(crtc_base+1)|0x80); /* Setup the correct clock */ if (CurMode->mode<0x100) { //Stick to 25mhz clock for now @@ -333,6 +359,10 @@ foundmode: gfx_data[0x7]=0xf; /* Color don't care */ gfx_data[0x8]=0xff; /* BitMask */ switch (CurMode->type) { + case M_TEXT2: + gfx_data[0x5]|=0x10; //Odd-Even Mode + gfx_data[0x6]|=0x0a; //alphanumeric mode at 0xb000=0x7fff + break; case M_TEXT16: gfx_data[0x5]|=0x10; //Odd-Even Mode gfx_data[0x6]|=0x0e; //alphanumeric mode at 0xb800=0xbfff @@ -365,11 +395,11 @@ foundmode: if (CurMode->mode>0xe) goto att_text16; case M_TANDY16: att_data[0x10]=0x01; //Color Graphics - for (i=0;i<8;i++) { + for (i=0;i<16;i++) { att_data[i]=i; - att_data[i+8]=i+0x10; } break; + case M_TEXT2: case M_TEXT16: att_data[0x13]=0x08; //Pel panning on 8, although we don't have 9 dot text mode att_data[0x10]=0x0C; //Color Text with blinking @@ -380,8 +410,12 @@ att_text16: } break; case M_CGA2: + IO_Write(0x3d9,0x7); //Setup using CGA color select register + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x7); + goto skipatt; case M_CGA4: - IO_Write(0x3d9,0x20); //Setup using CGA color select register + IO_Write(0x3d9,0x30); //Setup using CGA color select register + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x30); goto skipatt; case M_VGA: case M_LIN8: @@ -392,7 +426,7 @@ att_text16: break; } - IO_Read(0x3da); + IO_Read(mono_mode ? 0x3ba : 0x3da); for (i=0;itype) { + case M_CGA2: + feature=(feature&~0x30)|0x20; + IO_Write(0x3d8,0x12); //Setup using CGA color select register + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x12); + break; + case M_CGA4: + feature=(feature&~0x30)|0x20; + IO_Write(0x3d8,0x2); //Setup using CGA color select register + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x2); + break; case M_TANDY16: + feature=(feature&~0x30)|0x20; IO_Write(0x3df,0x80); //Enter 32k mode and banks on 0 break; + case M_TEXT2: + feature=(feature&~0x30)|0x30; + break; + case M_TEXT16: + feature=(feature&~0x30)|0x20; + break; + case M_EGA16: + case M_VGA: + feature=(feature&~0x30); + break; + } + real_writeb(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE,feature); /* Setup the CPU Window */ - IO_Write(0x3d4,0x6a); - IO_Write(0x3d5,0); + IO_Write(crtc_base,0x6a); + IO_Write(crtc_base+1,0); /* Setup the linear frame buffer */ - IO_Write(0x3d4,0x59); - IO_Write(0x3d5,(Bit8u)(S3_LFB_BASE >> 24)); - IO_Write(0x3d4,0x5a); - IO_Write(0x3d5,(Bit8u)(S3_LFB_BASE >> 16)); + IO_Write(crtc_base,0x59); + IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 24)); + IO_Write(crtc_base,0x5a); + IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 16)); /* Setup some remaining S3 registers */ - IO_Write(0x3d4,0x31);IO_Write(0x3d5,0x9); //Enable banked memory and 256k+ access - IO_Write(0x3d4,0x58);IO_Write(0x3d5,0x3); //Enable 8 mb of linear addressing - IO_Write(0x3d4,0x38);IO_Write(0x3d5,0x48); //Register lock 1 - IO_Write(0x3d4,0x39);IO_Write(0x3d5,0xa5); //Register lock 2 + IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,0x9); //Enable banked memory and 256k+ access + IO_Write(crtc_base,0x58);IO_Write(crtc_base+1,0x3); //Enable 8 mb of linear addressing + IO_Write(crtc_base,0x38);IO_Write(crtc_base+1,0x48); //Register lock 1 + IO_Write(crtc_base,0x39);IO_Write(crtc_base+1,0xa5); //Register lock 2 /* Load text mode font */ - if (CurMode->type==M_TEXT16) { + if (CurMode->type<=M_TEXT16) { INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); } /* Clear video memory if needs be */ @@ -463,9 +522,14 @@ dac_text16: real_writew(0xb800,i*2,0x0000); } break; + case M_TEXT2: + for (i=0;i<16*1024;i++) { + real_writew(0xb000,i*2,0x0120); + } + break; case M_TEXT16: for (i=0;i<16*1024;i++) { - real_writew(0xb800,i*2,0x0700); + real_writew(0xb800,i*2,0x0720); } break; case M_EGA16: @@ -477,16 +541,12 @@ dac_text16: } } } - /* Setup the CRTC Address */ - - crtc_addr=0x3d4; - /* Setup the BIOS */ if (mode<128) real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode); else real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode-0x98); //Looks like the s3 bios real_writew(BIOSMEM_SEG,BIOSMEM_NB_COLS,CurMode->twidth); real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,CurMode->plength); - real_writew(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_addr); + real_writew(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_base); real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,CurMode->theight-1); real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,CurMode->cheight); real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem << 7))); @@ -498,12 +558,8 @@ dac_text16: real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER,0x00); real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2,0x00); - // FIXME - real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x00); // Unavailable on vanilla vga, but... - real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x00); // Unavailable on vanilla vga, but... - // Set cursor shape - if(CurMode->type==M_TEXT16) { + if(CurMode->type<=M_TEXT16) { INT10_SetCursorShape(0x06,07); } // Set cursor pos for page 0..7 diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 2563e30b..3c7a0840 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -155,18 +155,17 @@ void INT10_GetPelMask(Bit8u & mask) { mask=IO_Read(VGAREG_PEL_MASK); } - void INT10_SetBackgroundBorder(Bit8u val) { -//TODO Detect if we're CGA? - Bit8u old=IO_Read(0x3d9) & 0xf0; - old|=val & 0xf; - IO_Write(0x3d9,old); + Bitu temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL); + temp=(temp & 0xe0) | (val & 0x1f); + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp); + IO_Write(0x3d9,temp); } void INT10_SetColorSelect(Bit8u val) { -//TODO Detect if we're CGA? - Bit8u old=IO_Read(0x3d9) & ~0x20; - old|=(val & 1) << 5; - IO_Write(0x3d9,old); + Bitu temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL); + temp=(temp & 0xdf) | ((val & 1) ? 0x20 : 0x0); + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp); + IO_Write(0x3d9,temp); } diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index efa0a336..dd07b596 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -54,6 +54,25 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { real_writeb(0xb800,off,old); } break; + case M_TANDY16: + { + Bit16u off=(y>>2)*160+(x>>1); + off+=(8*1024) * (y & 3); + Bit8u old=real_readb(0xb800,off); + Bit8u p[2]; + p[1] = (old >> 4) & 0xf; + p[0] = old & 0xf; + Bitu ind = 1-(x & 0x1); + + if (color & 0x80) { + p[ind]^=color; + } else { + p[ind]=color; + } + old = (p[1] << 4) | p[0]; + real_writeb(0xb800,off,old); + } + break; case M_EGA16: { /* Set the correct bitmask for the pixel position */ @@ -77,8 +96,9 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { if (color & 0x80) { IO_Write(0x3ce,0x3);IO_Write(0x3cf,0x0); } break; } + case M_VGA: - mem_writeb(Real2Phys(RealMake(0xa000,y*320+x)),color); + mem_writeb(PhysMake(0xa000,y*320+x),color); break; default: LOG(LOG_INT10,LOG_ERROR)("PutPixel unhandled mode type %d",CurMode->type); From 35858d84e5d3f31a0c4596ae263d5a69fb682a32 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 22 Oct 2003 14:51:17 +0000 Subject: [PATCH 1280/4131] Some CGA/tandy/hercules register support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1361 --- src/hardware/vga_misc.cpp | 157 ++++++++++++++++++++++++++++---------- 1 file changed, 117 insertions(+), 40 deletions(-) diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 6bb0188b..829398f8 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -20,6 +20,7 @@ #include "inout.h" #include "pic.h" #include "vga.h" +#include "../ints/int10.h" static Bit8u flip=0; @@ -28,10 +29,21 @@ Bit8u read_p3d4(Bit32u port); void write_p3d5(Bit32u port,Bit8u val); Bit8u read_p3d5(Bit32u port); +static void write_p3d9(Bit32u port,Bit8u val); + static Bit8u read_p3da(Bit32u port) { vga.internal.attrindex=false; + vga.tandy.set_reg=true; if (vga.config.retrace) { - return 9; + switch (vga.mode) { + case M_HERC: + return 0x81; + case M_TEXT2: + if (machine==MCH_HERC) return 0x81; + if (machine==MCH_AUTO) return 0x89; + default: + return 9; + } } flip++; if (flip>10) flip=0; @@ -45,14 +57,32 @@ static Bit8u read_p3da(Bit32u port) { static void write_p3d8(Bit32u port,Bit8u val) { + switch (machine) { + case MCH_CGA: + goto cga_3d8; + }; switch (vga.mode) { + case M_CGA16: case M_CGA4: - + case M_CGA2: +cga_3d8: + if (val & 0x2) { + if (val & 0x10) { + if (val & 0x8) { + VGA_SetMode(M_CGA16); //Video burst 16 160x200 color mode + } else { + VGA_SetMode(M_CGA2); + } + } else VGA_SetMode(M_CGA4); + write_p3d9(0x3d9,vga.cga.color_select); //Setup the correct palette + } else { + VGA_SetMode(M_TEXT16); + } break; default: + LOG(LOG_VGAMISC,LOG_NORMAL)("Write %2X to 3d8 in mode %d",val,vga.mode); break; } - LOG(LOG_VGAMISC,LOG_NORMAL)("Write %2X to 3d8",val); /* 3 Vertical Sync Select. If set Vertical Sync to the monitor is the logical OR of the vertical sync and the vertical display enable. @@ -60,50 +90,46 @@ static void write_p3d8(Bit32u port,Bit8u val) { } static void write_p3d9(Bit32u port,Bit8u val) { + Bitu i; + vga.cga.color_select=val; switch (vga.mode) { case M_CGA2: - vga.cga.color_select=val; /* changes attribute 1 */ - vga.attr.palette[1]=(val & 7) + ((val & 8) ? 0x38 : 0); - VGA_DAC_CombineColor(1,vga.attr.palette[0]); + VGA_ATTR_SetPalette(0,0); + VGA_ATTR_SetPalette(1,val & 0xf); break; case M_CGA4: - vga.cga.color_select=val; - /* changes attribute 0 */ - VGA_ATTR_SetPalette(0,(val & 7) + ((val & 8) ? 0x38 : 0)); - if (val & 0x020) { - VGA_ATTR_SetPalette(1,0x13); - VGA_ATTR_SetPalette(2,0x15); - VGA_ATTR_SetPalette(3,0x17); - } else { - VGA_ATTR_SetPalette(1,0x02); - VGA_ATTR_SetPalette(2,0x04); - VGA_ATTR_SetPalette(3,0x06); + /* changes attribute 0 */ + { + VGA_ATTR_SetPalette(0,(val & 0xf)); + Bit8u pal_base=(val & 0x10) ? 0x08 : 0; + if (val & 0x020) { + VGA_ATTR_SetPalette(1,0x03+pal_base); + VGA_ATTR_SetPalette(2,0x05+pal_base); + VGA_ATTR_SetPalette(3,0x07+pal_base); + } else { + VGA_ATTR_SetPalette(1,0x02+pal_base); + VGA_ATTR_SetPalette(2,0x04+pal_base); + VGA_ATTR_SetPalette(3,0x06+pal_base); + } } break; - /* Color Select register - Text modes: 320x200 modes: 640x200 mode: - 0 Blue border Blue background Blue ForeGround - 1 Green border Green background Green ForeGround - 2 Red border Red background Red ForeGround - 3 Bright border Bright background Bright ForeGround - 4 Backgr. color Alt. intens. colors Alt. intens colors - 5 No func. Selects palette - Palette 0 is Green, red and brown, - Palette 1 is Cyan, magenta and white. - */ + case M_CGA16: + for(i=0;i<0x10;i++) VGA_ATTR_SetPalette(i,i); + break; default: LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to %X in mode %d",val,port,vga.mode); } } static void write_p3df(Bit32u port,Bit8u val) { + if (machine==MCH_TANDY) goto tandy_3df; switch (vga.mode) { case M_TANDY16: +tandy_3df: vga.tandy.disp_bank=val & ((val & 0x80) ? 0x6 : 0x7); vga.tandy.mem_bank=(val >> 3) & ((val & 0x80) ? 0x6 : 0x7); VGA_SetupHandlers(); - break; /* 0-2 Identifies the page of main memory being displayed in units of 16K. @@ -122,36 +148,44 @@ static void write_p3df(Bit32u port,Bit8u val) { } static Bit8u read_p3d9(Bit32u port) { - switch (vga.mode) { - case M_CGA2: - case M_CGA4: + switch (machine) { + case MCH_AUTO: + case MCH_CGA: + case MCH_TANDY: return vga.cga.color_select; default: return 0xff; - } + }; } static void write_p3c2(Bit32u port,Bit8u val) { vga.misc_output=val; + if (val & 0x1) { IO_RegisterWriteHandler(0x3d4,write_p3d4,"VGA:CRTC Index Select"); IO_RegisterReadHandler(0x3d4,read_p3d4,"VGA:CRTC Index Select"); IO_RegisterWriteHandler(0x3d5,write_p3d5,"VGA:CRTC Data Register"); IO_RegisterReadHandler(0x3d5,read_p3d5,"VGA:CRTC Data Register"); + IO_RegisterReadHandler(0x3da,read_p3da,"VGA Input Status 1"); + IO_FreeWriteHandler(0x3b4); IO_FreeReadHandler(0x3b4); IO_FreeWriteHandler(0x3b5); IO_FreeReadHandler(0x3b5); + IO_FreeReadHandler(0x3ba); } else { IO_RegisterWriteHandler(0x3b4,write_p3d4,"VGA:CRTC Index Select"); IO_RegisterReadHandler(0x3b4,read_p3d4,"VGA:CRTC Index Select"); IO_RegisterWriteHandler(0x3b5,write_p3d5,"VGA:CRTC Data Register"); IO_RegisterReadHandler(0x3b5,read_p3d5,"VGA:CRTC Data Register"); + IO_RegisterReadHandler(0x3ba,read_p3da,"VGA Input Status 1"); + IO_FreeWriteHandler(0x3d4); IO_FreeReadHandler(0x3d4); IO_FreeWriteHandler(0x3d5); IO_FreeReadHandler(0x3d5); + IO_FreeReadHandler(0x3da); } /* 0 If set Color Emulation. Base Address=3Dxh else Mono Emulation. Base Address=3Bxh. @@ -171,20 +205,63 @@ static Bit8u read_p3cc(Bit32u port) { return vga.misc_output; } + +static void write_hercules(Bit32u port,Bit8u val) { + switch (port) { + case 0x3b8: + if (vga.herc.enable_bits & 1) { + if (vga.mode != M_HERC || vga.mode != M_TEXT2) { + VGA_ATTR_SetPalette(1,0x0f); + /* Hack around like it looks we are in 0xb000 segment */ + vga.gfx.miscellaneous=(vga.gfx.miscellaneous & ~0x0c)|0x0a; + if (vga.misc_output & 1) write_p3c2(0,vga.misc_output & ~1); + } + if (val & 0x2) { + if (vga.mode != M_HERC) VGA_SetMode(M_HERC); + } else { + if (vga.mode != M_TEXT2) VGA_SetMode(M_TEXT2); + } + } + if (vga.herc.enable_bits & 0x2) { + LOG_MSG("Herc page %d",val >> 7); + } + vga.herc.mode_control=val; + break; + case 0x3bf: + vga.herc.enable_bits=val; + break; + default: + LOG_MSG("write %x to Herc port %x",val,port); + } +} + +static Bit8u read_hercules(Bit32u port) { + switch (port) { + case 0x3b8: + default: + LOG_MSG("read from Herc port %x",port); + } + return 0; +} + + + + void VGA_SetupMisc(void) { - IO_RegisterReadHandler(0x3da,read_p3da,"VGA Input Status 1"); - IO_RegisterReadHandler(0x3ba,read_p3da,"VGA Input Status 1"); +// if (machine==MCH_HERC) EnableHercules(); + vga.herc.enable_bits=0; IO_RegisterWriteHandler(0x3d8,write_p3d8,"VGA Feature Control Register"); - - IO_RegisterWriteHandler(0x3d9,write_p3d9,"CGA Color Select Register"); IO_RegisterReadHandler(0x3d9,read_p3d9,"CGA Color Select Register"); - - - IO_RegisterWriteHandler(0x3c2,write_p3c2,"VGA Misc Output"); + IO_RegisterWriteHandler(0x3c2,write_p3c2,"VGA Misc Output"); IO_RegisterReadHandler(0x3cc,read_p3cc,"VGA Misc Output"); + + if (machine==MCH_HERC || machine==MCH_AUTO) { + IO_RegisterWriteHandler(0x3b8,write_hercules,"Hercules"); + IO_RegisterWriteHandler(0x3bf,write_hercules,"Hercules"); + } IO_RegisterWriteHandler(0x3df,write_p3df,"PCJR Setting"); } From b23dc28497282102da78b72e1dbd883976aa1a3f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 22 Oct 2003 14:51:50 +0000 Subject: [PATCH 1281/4131] changes for new paging/memory system Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1362 --- src/hardware/vga_memory.cpp | 222 ++++++++++++++++++++++++++++++------ 1 file changed, 185 insertions(+), 37 deletions(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 23e43b4d..2deb3d3d 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -27,15 +27,15 @@ #include "paging.h" #include "pic.h" -static Bit8u VGA_NormalReadHandler(PhysPt start) { +static Bitu VGA_NormalReadHandler(PhysPt start) { vga.latch.d=vga.mem.latched[start].d; switch (vga.config.read_mode) { case 0: - return(vga.latch.b[vga.config.read_map_select]); + return (vga.latch.b[vga.config.read_map_select]); case 1: VGA_Latch templatch; templatch.d=(vga.latch.d & FillTable[vga.config.color_dont_care]) ^ FillTable[vga.config.color_compare & vga.config.color_dont_care]; - return ~(templatch.b[0] | templatch.b[1] | templatch.b[2] | templatch.b[3]); + return (Bit8u)~(templatch.b[0] | templatch.b[1] | templatch.b[2] | templatch.b[3]); } return 0; } @@ -84,7 +84,7 @@ INLINE static Bit32u ModeOperation(Bit8u val) { } static void VGA_GFX_16_WriteHandler(PhysPt start,Bit8u val) { - val=(val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate)); + val=((val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate))); Bit32u data=ModeOperation(val); /* Update video memory and the pixel buffer */ VGA_Latch pixels; @@ -116,7 +116,6 @@ static void VGA_GFX_16_WriteHandler(PhysPt start,Bit8u val) { static void VGA_GFX_256U_WriteHandler(PhysPt start,Bit8u val) { Bit32u data=ModeOperation(val); -// Bit32u data=ExpandTable[val]; VGA_Latch pixels; pixels.d=vga.mem.latched[start].d; pixels.d&=vga.config.full_not_map_mask; @@ -125,72 +124,223 @@ static void VGA_GFX_256U_WriteHandler(PhysPt start,Bit8u val) { vga.mem.latched[start+64*1024].d=pixels.d; } -static void VGA_TEXT16_Write(PhysPt start,Bit8u val) { - /* Check for page 2 being enabled for writing */ - if (vga.seq.map_mask & 0x4) { - vga.draw.font[start]=val; - } - //TODO Check for writes to other pages with normal text characters/attributes +/* Gonna assume that whoever maps vga memory, maps it on 32/64kb boundary */ + +#define LINK_MAX 64 +#define VGA_PAGES (128/4) +#define VGA_PAGE_A0 (0xA0000/4096) +#define VGA_PAGE_B0 (0xB0000/4096) +#define VGA_PAGE_B8 (0xB8000/4096) + +static struct { + Bitu used_links; + Bit32u links[LINK_MAX]; + Bit8u ram_area[VGA_PAGES*4096]; + Bitu map_base; +} vgapages; + + +void VGA_ClearPageLinks(void) { + PAGING_ClearTLBEntries(vgapages.used_links,vgapages.links); + vgapages.used_links=0; } -static Bit8u VGA_TEXT16_Read(PhysPt start) { - return vga.draw.font[start]; -} +class VGA_PageHandler : public PageHandler { + void AddPageLink(Bitu lin_page, Bitu phys_page) { + if (vgapages.used_links> 0)); + } + void writew(PhysPt addr,Bitu val) { + addr&=0xffff; + VGA_GFX_16_WriteHandler(addr+0,(Bit8u)(val >> 0)); + VGA_GFX_16_WriteHandler(addr+1,(Bit8u)(val >> 8)); + } + void writed(PhysPt addr,Bitu val) { + addr&=0xffff; + VGA_GFX_16_WriteHandler(addr+0,(Bit8u)(val >> 0)); + VGA_GFX_16_WriteHandler(addr+1,(Bit8u)(val >> 8)); + VGA_GFX_16_WriteHandler(addr+2,(Bit8u)(val >> 16)); + VGA_GFX_16_WriteHandler(addr+3,(Bit8u)(val >> 24)); + } +}; + +class VGA_256_PageHandler : public VGARead_PageHandler { +public: + VGA_256_PageHandler() { + flags=PFLAG_NOCODE; + } + void writeb(PhysPt addr,Bitu val) { + addr&=0xffff; + VGA_GFX_256U_WriteHandler(addr+0,(Bit8u)(val >> 0)); + } + void writew(PhysPt addr,Bitu val) { + addr&=0xffff; + VGA_GFX_256U_WriteHandler(addr+0,(Bit8u)(val >> 0)); + VGA_GFX_256U_WriteHandler(addr+1,(Bit8u)(val >> 8)); + } + void writed(PhysPt addr,Bitu val) { + addr&=0xffff; + VGA_GFX_256U_WriteHandler(addr+0,(Bit8u)(val >> 0)); + VGA_GFX_256U_WriteHandler(addr+1,(Bit8u)(val >> 8)); + VGA_GFX_256U_WriteHandler(addr+2,(Bit8u)(val >> 16)); + VGA_GFX_256U_WriteHandler(addr+3,(Bit8u)(val >> 24)); + } +}; + +class VGA_TEXT_PageHandler : public VGA_PageHandler { +public: + VGA_TEXT_PageHandler() { + flags=PFLAG_NOCODE; + } + Bitu readb(PhysPt addr) { + addr&=0x7fff; + return vga.draw.font[addr]; + } + void writeb(PhysPt addr,Bitu val){ + addr&=0x7fff; + if (vga.seq.map_mask & 0x4) { + vga.draw.font[addr]=(Bit8u)val; + } + } +}; + + +class VGA_RAM_PageHandler : public VGA_PageHandler { +public: + VGA_RAM_PageHandler() { + flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; + } + HostPt GetHostPt(Bitu phys_page) { + phys_page-=VGA_PAGE_A0; + return &vgapages.ram_area[phys_page*4096]; + } +}; + +class VGA_MAP_PageHandler : public VGA_PageHandler { +public: + VGA_MAP_PageHandler() { + flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; + } + HostPt GetHostPt(Bitu phys_page) { + phys_page-=vgapages.map_base; + return &vga.mem.linear[vga.s3.bank*64*1024+phys_page*4096]; + } +}; + +class VGA_TANDY_PageHandler : public VGA_PageHandler { +public: + VGA_TANDY_PageHandler() { + flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; + } + HostPt GetHostPt(Bitu phys_page) { + phys_page-=vgapages.map_base; + return &vga.mem.linear[(vga.tandy.mem_bank << 14)+(phys_page * 4096)]; + } +}; + + +static struct { + VGA_RAM_PageHandler hram; + VGA_MAP_PageHandler hmap; + VGA_TEXT_PageHandler htext; + VGA_TANDY_PageHandler htandy; + VGA_256_PageHandler h256; + VGA_16_PageHandler h16; +} vgaph; + void VGA_SetupHandlers(void) { - HostPt where; + PageHandler * range_handler; switch (vga.mode) { case M_LIN8: - where=&vga.mem.linear[vga.s3.bank*64*1024]; + range_handler=&vgaph.hmap; break; case M_VGA: if (vga.config.chained) { - where=&vga.mem.linear[vga.s3.bank*64*1024]; + range_handler=&vgaph.hmap; } else { - vga.config.readhandler=&VGA_NormalReadHandler, - vga.config.writehandler=&VGA_GFX_256U_WriteHandler; - where=0; + range_handler=&vgaph.h256; } break; case M_EGA16: - vga.config.readhandler=&VGA_NormalReadHandler, - vga.config.writehandler=&VGA_GFX_16_WriteHandler; - where=0; + range_handler=&vgaph.h16; break; + case M_TEXT2: case M_TEXT16: /* Check if we're not in odd/even mode */ if (vga.gfx.miscellaneous & 0x2) { - where=&vga.mem.linear[0]; + range_handler=&vgaph.hmap; } else { - vga.config.readhandler=&VGA_TEXT16_Read; - vga.config.writehandler=&VGA_TEXT16_Write; - where=0; + range_handler=&vgaph.htext; } break; case M_TANDY16: - where=&vga.mem.linear[vga.tandy.mem_bank << 14]; + range_handler=&vgaph.htandy; break; + case M_CGA16: case M_CGA4: case M_CGA2: - where=&vga.mem.linear[0]; + case M_HERC: + range_handler=&vgaph.hmap; break; default: LOG_MSG("Unhandled vga mode %X",vga.mode); } - VGA_RANGES range; switch ((vga.gfx.miscellaneous >> 2) & 3) { case 0: case 1: - range=VGA_RANGE_A000; + vgapages.map_base=VGA_PAGE_A0; + MEM_SetPageHandler(VGA_PAGE_A0,16,range_handler); + MEM_SetPageHandler(VGA_PAGE_B0,16,&vgaph.hram); break; case 2: - range=VGA_RANGE_B000; + vgapages.map_base=VGA_PAGE_B0; + MEM_SetPageHandler(VGA_PAGE_B0,8,range_handler); + MEM_SetPageHandler(VGA_PAGE_A0,16,&vgaph.hram); + MEM_SetPageHandler(VGA_PAGE_B8,8,&vgaph.hram); break; case 3: - range=VGA_RANGE_B800; + vgapages.map_base=VGA_PAGE_B8; + MEM_SetPageHandler(VGA_PAGE_B8,8,range_handler); + MEM_SetPageHandler(VGA_PAGE_A0,16,&vgaph.hram); + MEM_SetPageHandler(VGA_PAGE_B0,8,&vgaph.hram); break; } - MEM_SetupVGA(range,where); + VGA_ClearPageLinks(); } bool lfb_update; @@ -209,7 +359,5 @@ void VGA_StartUpdateLFB(void) { void VGA_SetupMemory() { memset((void *)&vga.mem,0,512*1024*4); - /* Setup linear window to some initial value */ - vga.s3.la_window=0xc000; - VGA_DoUpdateLFB(); + vgapages.used_links=0; } From fde309a4e72cc25e0d8946004476068a786bfc4d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 22 Oct 2003 14:52:34 +0000 Subject: [PATCH 1282/4131] mono text mode change Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1363 --- src/hardware/vga_attr.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index e94936c2..1b8a48eb 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -114,6 +114,7 @@ void write_p3c0(Bit32u port,Bit8u val) { case 0x13: /* Horizontal PEL Panning Register */ attr(horizontal_pel_panning)=val & 0xF; switch (vga.mode) { + case M_TEXT2: case M_TEXT16: if (val==0x7) vga.config.pel_panning=7; if (val>0x7) vga.config.pel_panning=0; From 6878b36703fa5ed34d0c1636c35b0bc5fc3eb43a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 22 Oct 2003 14:53:23 +0000 Subject: [PATCH 1283/4131] ... Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1364 --- src/hardware/vga.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 17a03739..280db46e 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -28,7 +28,9 @@ VGA_Type vga; +Bit32u CGA_2_Table[16]; Bit32u CGA_4_Table[256]; +Bit32u CGA_16_Table[256]; Bit32u ExpandTable[256]; Bit32u Expand16Table[4][16]; Bit32u Expand16BigTable[0x10000]; @@ -36,6 +38,7 @@ Bit32u FillTable[16]; void VGA_SetMode(VGAModes mode) { + if (vga.mode == mode) return; vga.mode=mode; VGA_SetupHandlers(); VGA_StartResize(); @@ -99,15 +102,19 @@ void VGA_Init(Section* sec) { CGA_4_Table[i]=((i>>0)&3) | (((i>>2)&3) << 8)| (((i>>4)&3) <<16) | (((i>>6)&3) << 24); #else CGA_4_Table[i]=((i>>6)&3) | (((i>>4)&3) << 8)| (((i>>2)&3) <<16) | (((i>>0)&3) << 24); + + #endif } for (i=0;i<16;i++) { #ifdef WORDS_BIGENDIAN + CGA_2_Table[i]=((i>>0)&1) | (((i>>1)&1) << 8)| (((i>>1)&1) <<16) | (((i>>3)&1) << 24); FillTable[i]= ((i & 1) ? 0xff000000 : 0) | - ((i & 2) ? 0x00ff0000 : 0) | + ((i & 2) ? 0x00ff0000 : 0) | ((i & 4) ? 0x0000ff00 : 0) | ((i & 8) ? 0x000000ff : 0) ; #else + CGA_2_Table[i]=((i>>3)&1) | (((i>>2)&1) << 8)| (((i>>1)&1) <<16) | (((i>>0)&1) << 24); FillTable[i]= ((i & 1) ? 0x000000ff : 0) | ((i & 2) ? 0x0000ff00 : 0) | ((i & 4) ? 0x00ff0000 : 0) | From 338aa25384f3c6cb683e0ad998e900acbe562a0e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 22 Oct 2003 14:56:07 +0000 Subject: [PATCH 1284/4131] New machine type option in config file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1365 --- src/dosbox.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 09311a5a..9e73cbbf 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -38,6 +38,7 @@ #include "support.h" Config * control; +MachineType machine; /* The whole load of startups for all the subfunctions */ void MSG_Init(Section_prop *); @@ -127,7 +128,7 @@ increaseticks: if (NewTicks>LastTicks) { RemainTicks=NewTicks-LastTicks; if (RemainTicks>20) { -// LOG_DEBUG("Ticks to handle overflow %d",RemainTicks); +// LOG_MSG("Ticks to handle overflow %d",RemainTicks); RemainTicks=20; } LastTicks=NewTicks; @@ -162,6 +163,15 @@ static void DOSBOX_RealInit(Section * sec) { RemainTicks=0;LastTicks=GetTicks(); DOSBOX_SetLoop(&Normal_Loop); MSG_Init(section); + + machine=MCH_AUTO; + const char * mtype=section->Get_string("machine"); + if (strcasecmp(mtype,"cga")==0) machine=MCH_CGA; + else if (strcasecmp(mtype,"tandy")==0) machine=MCH_TANDY; + else if (strcasecmp(mtype,"hercules")==0) machine=MCH_HERC; + else if (strcasecmp(mtype,"vga")==0) machine=MCH_VGA; + else if (strcasecmp(mtype,"auto")==0) machine=MCH_AUTO; + else LOG_MSG("DOSBOX:Unkown machine type %s",mtype); } @@ -173,9 +183,12 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit); secprop->Add_string("language",""); + secprop->Add_string("machine","auto"); + #if C_DEBUG LOG_StartUp(); #endif + secprop->AddInitFunction(&IO_Init); secprop->AddInitFunction(&PAGING_Init); secprop->AddInitFunction(&MEM_Init); @@ -223,7 +236,7 @@ void DOSBOX_Init(void) { secprop->Add_int("rate",22050); secprop->Add_int("blocksize",2048); secprop->Add_string("wavedir","waves"); - + MSG_Add("MIXER_CONFIGFILE_HELP", "nosound -- Enable silent mode, sound is still emulated though.\n" "rate -- Mixer sample rate, setting any devices higher than this will\n" @@ -239,7 +252,7 @@ void DOSBOX_Init(void) { secprop->Add_bool("mpu401",true); secprop->Add_string("device","default"); secprop->Add_string("config",""); - + MSG_Add("MIDI_CONFIGFILE_HELP", "mpu401 -- Enable MPU-401 Emulation.\n" "device -- Device that will receive the MIDI data from MPU-401.\n" @@ -260,6 +273,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&ADLIB_Init); secprop->Add_bool("adlib",true); secprop->Add_int("adlibrate",22050); + secprop->Add_string("adlibmode","adlib"); secprop->AddInitFunction(&CMS_Init); secprop->Add_bool("cms",false); secprop->Add_int("cmsrate",22050); From a9dedff7a275fcbd24b0a9eb9cc5d014f6fb6745 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 22 Oct 2003 15:48:20 +0000 Subject: [PATCH 1285/4131] New teletype functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1366 --- src/dos/dev_con.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 09f67321..8183ce0a 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.14 2003-09-08 18:06:44 qbix79 Exp $ */ +/* $Id: dev_con.h,v 1.15 2003-10-22 15:48:20 harekiet Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" @@ -56,7 +56,7 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { if ((cache) && (*size)) { data[count++]=cache; if(dos.echo) { - INT10_TeletypeOutput(cache,7,false); + INT10_TeletypeOutput(cache,7); } cache=0; @@ -71,8 +71,8 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { *size=count; reg_ax=oldax; if(dos.echo) { - INT10_TeletypeOutput(13,7,false); //maybe don't do this ( no need for it actually ) (but it's compatible) - INT10_TeletypeOutput(10,7,false); + INT10_TeletypeOutput(13,7); //maybe don't do this ( no need for it actually ) (but it's compatible) + INT10_TeletypeOutput(10,7); } return true; break; @@ -80,8 +80,8 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { if(*size==1) data[count++]=reg_al; //one char at the time so give back that BS else if(count) { //Remove data if it exists (extended keys don't go right) data[count--]=0; - INT10_TeletypeOutput(8,7,false); - INT10_TeletypeOutput(' ',7,false); + INT10_TeletypeOutput(8,7); + INT10_TeletypeOutput(' ',7); } else { continue; //no data read yet so restart whileloop. } @@ -98,7 +98,7 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { } if(dos.echo) { //what to do if *size==1 and character is BS ????? - INT10_TeletypeOutput(reg_al,7,false); + INT10_TeletypeOutput(reg_al,7); } } *size=count; @@ -124,7 +124,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { } else { // pass attribute only if ansi is enabled - INT10_TeletypeOutput(data[count],ansi.attr,ansi.enabled); + INT10_TeletypeOutputAttr(data[count],ansi.attr,ansi.enabled); count++; continue; }; @@ -315,7 +315,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { LOG(LOG_IOCTL,LOG_NORMAL)("ANSI: esc[%dJ called : not supported",ansi.data[0]); break; } - for(i=0;i<(Bitu)ansi.ncols*ansi.nrows;i++) INT10_TeletypeOutput(' ',ansi.attr,true); + for(i=0;i<(Bitu)ansi.ncols*ansi.nrows;i++) INT10_TeletypeOutputAttr(' ',ansi.attr,true); ClearAnsi(); INT10_SetCursorPos(0,0,0); break; @@ -334,7 +334,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { ClearAnsi(); break; case 'K':/* erase till end of line */ - for(i = CURSOR_POS_COL(0);i<(Bitu) ansi.ncols; i++) INT10_TeletypeOutput(' ',ansi.attr,true); + for(i = CURSOR_POS_COL(0);i<(Bitu) ansi.ncols; i++) INT10_TeletypeOutputAttr(' ',ansi.attr,true); ClearAnsi(); /* maybe set cursor back to starting place ???? */ break; case 'l':/* (if code =7) disable linewrap */ From f9a917548ca4605c7989371f7f2c6d2b96c95f94 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 22 Oct 2003 16:08:41 +0000 Subject: [PATCH 1286/4131] new host_write functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1367 --- src/hardware/mixer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index f3cc674a..839a312c 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -257,10 +257,10 @@ static void MIXER_WaveEvent(void) { /* Write last piece of audio in buffer */ fwrite(mixer.wave.buf,1,mixer.wave.used,mixer.wave.handle); /* Fill in the header with useful information */ - writed(&wavheader[4],mixer.wave.length+sizeof(wavheader)-8); - writed(&wavheader[0x18],mixer.freq); - writed(&wavheader[0x1C],mixer.freq*4); - writed(&wavheader[0x28],mixer.wave.length); + host_writed(&wavheader[4],mixer.wave.length+sizeof(wavheader)-8); + host_writed(&wavheader[0x18],mixer.freq); + host_writed(&wavheader[0x1C],mixer.freq*4); + host_writed(&wavheader[0x28],mixer.wave.length); fseek(mixer.wave.handle,0,0); fwrite(wavheader,1,sizeof(wavheader),mixer.wave.handle); From b84ff3d9c3daf1343b6d293e6301647bd2bb9a5c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 22 Oct 2003 16:27:12 +0000 Subject: [PATCH 1287/4131] remove vga.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1368 --- src/hardware/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index efe59594..d5bb84f2 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -6,7 +6,7 @@ noinst_LIBRARIES = libhardware.a libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler.cpp joystick.cpp keyboard.cpp \ memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ - vga.cpp vga.h vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp \ + vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp \ vga_memory.cpp vga_misc.cpp vga_seq.cpp font-switch.h ega-switch.h cmos.cpp disney.cpp \ gus.cpp mpu401.cpp serialport.cpp softmodem.cpp From 1d7d80028edffd04bdcaa39e6254f0668181344a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 22 Oct 2003 16:27:36 +0000 Subject: [PATCH 1288/4131] add vga.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1369 --- include/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/include/Makefile.am b/include/Makefile.am index d910b84d..49e67147 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -28,5 +28,6 @@ serialport.h \ setup.h \ support.h \ timer.h \ +vga.h \ video.h From 94a38c265efa36c3edf62c6872ca4160ca8bc2e9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 22 Oct 2003 19:55:42 +0000 Subject: [PATCH 1289/4131] Fixed write functions returns values Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1370 --- include/paging.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/paging.h b/include/paging.h index 73529ca9..5fbbfd41 100644 --- a/include/paging.h +++ b/include/paging.h @@ -146,7 +146,7 @@ INLINE void mem_writeb_inline(PhysPt address,Bit8u val) { Bitu index=(address>>12); if (paging.tlb.write[index]) host_writeb(paging.tlb.write[index]+address,val); - else return paging.tlb.handler[index]->writeb(address,val); + else paging.tlb.handler[index]->writeb(address,val); } INLINE void mem_writew_inline(PhysPt address,Bit16u val) { @@ -155,7 +155,7 @@ INLINE void mem_writew_inline(PhysPt address,Bit16u val) { Bitu index=(address>>12); if (paging.tlb.write[index]) host_writew(paging.tlb.write[index]+address,val); - else return paging.tlb.handler[index]->writew(address,val); + else paging.tlb.handler[index]->writew(address,val); } INLINE void mem_writed_inline(PhysPt address,Bit32u val) { @@ -163,7 +163,7 @@ INLINE void mem_writed_inline(PhysPt address,Bit32u val) { Bitu index=(address>>12); if (paging.tlb.write[index]) host_writed(paging.tlb.write[index]+address,val); - else return paging.tlb.handler[index]->writed(address,val); + else paging.tlb.handler[index]->writed(address,val); } From 953da984248196116b97f002d63ec704ffa80b4d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 23 Oct 2003 07:03:37 +0000 Subject: [PATCH 1290/4131] fix 16 color graphics colors Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1371 --- src/ints/int10_modes.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index e26e739e..1fc3d5b6 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -393,6 +393,11 @@ foundmode: switch (CurMode->type) { case M_EGA16: if (CurMode->mode>0xe) goto att_text16; + for (i=0;i<8;i++) { + att_data[i]=i; + att_data[i+8]=i+0x10; + } + break; case M_TANDY16: att_data[0x10]=0x01; //Color Graphics for (i=0;i<16;i++) { @@ -437,6 +442,12 @@ skipatt: switch (CurMode->type) { case M_EGA16: if (CurMode->mode>0xe) goto dac_text16; + for (i=0;i<64;i++) { + IO_Write(0x3c9,ega_palette[i][0]); + IO_Write(0x3c9,ega_palette[i][1]); + IO_Write(0x3c9,ega_palette[i][2]); + } + break; case M_CGA2: case M_CGA4: case M_TANDY16: From 59316dda6da298bdb6ac5a5a9a56707de72e47c1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 23 Oct 2003 11:59:09 +0000 Subject: [PATCH 1291/4131] enabled modem again.(Jammet) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1372 --- src/hardware/softmodem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp index 38e568e1..902996ea 100644 --- a/src/hardware/softmodem.cpp +++ b/src/hardware/softmodem.cpp @@ -590,7 +590,7 @@ void MODEM_Init(Section* sec) { unsigned long args = 1; Section_prop * section=static_cast(sec); - if(!section->Get_bool("enabled")) return; + if(!section->Get_bool("modem")) return; if(SDLNet_Init()==-1) { LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); From b76723b848988c966e72fc7f063950ee9125c429 Mon Sep 17 00:00:00 2001 From: uid83799 Date: Thu, 23 Oct 2003 19:42:35 +0000 Subject: [PATCH 1292/4131] new config file line of help Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1373 --- src/dosbox.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 9e73cbbf..4c966832 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -203,6 +203,8 @@ void DOSBOX_Init(void) { MSG_Add("DOSBOX_CONFIGFILE_HELP", "language -- Select another language file.\n" "memsize -- Amount of memory dosbox has in megabytes.\n" + "machine -- The type of machine tries to emulate.\n" + " You can select from auto,hercules,tandy,vga.\n" ); secprop=control->AddSection_prop("render",&RENDER_Init); From 23bbc96f4dba2b8a67f9d6a550d17803bbdb92ef Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 24 Oct 2003 20:03:33 +0000 Subject: [PATCH 1293/4131] Change the disney enabling config setting Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1374 --- src/hardware/disney.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 423582db..e93056a8 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -101,7 +101,7 @@ static void DISNEY_CallBack(Bit8u * stream,Bit32u len) { void DISNEY_Init(Section* sec) { MSG_Add("DISNEY_CONFIGFILE_HELP","Nothing to setup yet!\n"); Section_prop * section=static_cast(sec); - if(!section->Get_bool("enabled")) return; + if(!section->Get_bool("disney")) return; IO_RegisterWriteHandler(DISNEY_BASE,disney_write,"DISNEY"); IO_RegisterWriteHandler(DISNEY_BASE+1,disney_write,"DISNEY"); From 8c832a4a812b559d94601c51ac4c3ae324f700ec Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 26 Oct 2003 17:44:35 +0000 Subject: [PATCH 1294/4131] Remove the old slow_16 core Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1375 --- src/cpu/Makefile.am | 2 +- src/cpu/slow_16.cpp | 125 -------------------------------------------- 2 files changed, 1 insertion(+), 126 deletions(-) delete mode 100644 src/cpu/slow_16.cpp diff --git a/src/cpu/Makefile.am b/src/cpu/Makefile.am index 6eee8926..878bc1de 100644 --- a/src/cpu/Makefile.am +++ b/src/cpu/Makefile.am @@ -2,5 +2,5 @@ SUBDIRS = core_16 core_full core_normal AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libcpu.a -libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h slow_16.cpp core_full.cpp instructions.h \ +libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h core_full.cpp instructions.h \ paging.cpp lazyflags.h core_normal.cpp \ No newline at end of file diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp deleted file mode 100644 index 4ebe1ced..00000000 --- a/src/cpu/slow_16.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2002-2003 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#include "dosbox.h" -#include "mem.h" -#include "cpu.h" -#include "lazyflags.h" -#include "inout.h" -#include "callback.h" -#include "pic.h" -#include "fpu.h" - -#if C_DEBUG -#include "debug.h" -#endif - -typedef PhysPt EAPoint; -#define SegBase(c) SegPhys(c) -#define LoadMb(off) mem_readb(off) -#define LoadMw(off) mem_readw(off) -#define LoadMd(off) mem_readd(off) - -#define LoadMbs(off) (Bit8s)(LoadMb(off)) -#define LoadMws(off) (Bit16s)(LoadMw(off)) -#define LoadMds(off) (Bit32s)(LoadMd(off)) - -#define SaveMb(off,val) mem_writeb(off,val) -#define SaveMw(off,val) mem_writew(off,val) -#define SaveMd(off,val) mem_writed(off,val) - -#define LoadRb(reg) reg -#define LoadRw(reg) reg -#define LoadRd(reg) reg - -#define SaveRb(reg,val) reg=val -#define SaveRw(reg,val) reg=val -#define SaveRd(reg,val) reg=val - -extern Bitu cycle_count; - -/* Enable parts of the cpu emulation */ -#define CPU_386 //Enable 386 instructions -#define CPU_PREFIX_67 //Enable the 0x67 prefix -#define CPU_PIC_CHECK //Check for IRQ's on critical moment - -#if C_FPU -#define CPU_FPU //Enable FPU escape instructions -#endif - -static struct { - Bitu prefixes; - PhysPt segbase; - PhysPt ip_lookup; - PhysPt ip_start; -}core_16 ; - - -#include "instructions.h" -#include "core_16/support.h" -static Bits CPU_Real_16_Slow_Decode_Trap(void); - -static Bits CPU_Real_16_Slow_Decode(void) { -decode_start: - LOADIP; - flags.type=t_UNKNOWN; - while (CPU_Cycles>0) { -#if C_DEBUG - cycle_count++; -#if C_HEAVY_DEBUG - LEAVECORE; - if (DEBUG_HeavyIsBreakpoint()) return debugCallback; -#endif -#endif - core_16.ip_start=core_16.ip_lookup; - core_16.prefixes=0; - lookupEATable=EAPrefixTable[0]; - #include "core_16/main.h" - CPU_Cycles--; - } -decode_end: - LEAVECORE; - return CBRET_NONE; -} - -static Bits CPU_Real_16_Slow_Decode_Trap(void) { - - Bits oldCycles = CPU_Cycles; - CPU_Cycles = 1; - Bits ret=CPU_Real_16_Slow_Decode(); - -// LOG_DEBUG("TRAP: Trap Flag executed"); - Interrupt(1); - - CPU_Cycles = oldCycles-1; - cpudecoder = &CPU_Real_16_Slow_Decode; - - return ret; -} - - -void CPU_Real_16_Slow_Start(bool big) { - if (big) E_Exit("Core 16 only runs 16-bit code"); - cpudecoder=&CPU_Real_16_Slow_Decode; - EAPrefixTable[2]=&GetEA_32_n; - EAPrefixTable[3]=&GetEA_32_s; - EAPrefixTable[0]=&GetEA_16_n; - EAPrefixTable[1]=&GetEA_16_s; - -}; From 4f130819d60c275b350a1b0cebc6ed94ac1045eb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 26 Oct 2003 18:57:46 +0000 Subject: [PATCH 1295/4131] remove lazy flag references Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1376 --- src/dos/dos.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 02243133..82d7641c 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.58 2003-10-17 16:56:38 finsterr Exp $ */ +/* $Id: dos.cpp,v 1.59 2003-10-26 18:57:46 harekiet Exp $ */ #include #include @@ -896,7 +896,6 @@ static Bitu DOS_27Handler(void) return CBRET_NONE; } static Bitu DOS_25Handler(void) { - flags.type=0; if(Drives[reg_al]==0){ reg_ax=0x8002; SETFLAGBIT(CF,true); @@ -910,7 +909,6 @@ static Bitu DOS_25Handler(void) { } static Bitu DOS_26Handler(void) { LOG(LOG_DOSMISC,LOG_NORMAL)("int 26 called: hope for the best!"); - flags.type=0; if(Drives[reg_al]==0){ reg_ax=0x8002; SETFLAGBIT(CF,true); From e92e17addd702efceeb5db86de74edc38032c685 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 26 Oct 2003 18:58:46 +0000 Subject: [PATCH 1296/4131] New lazy flag header file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1377 --- include/cpu.h | 3 +-- include/regs.h | 33 +++++++-------------------------- 2 files changed, 8 insertions(+), 28 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 40ea13f0..3aeeae1d 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -88,13 +88,12 @@ void CPU_Push32(Bitu value); void CPU_SetFlags(Bitu word); - INLINE void CPU_SetFlagsd(Bit32u word) { CPU_SetFlags(word); }; INLINE void CPU_SetFlagsw(Bit16u word) { - CPU_SetFlags((flags.word&0xffff0000)|word); + CPU_SetFlags((cpu_regs.flags&0xffff0000)|word); }; diff --git a/include/regs.h b/include/regs.h index a3a266f0..35981184 100644 --- a/include/regs.h +++ b/include/regs.h @@ -21,19 +21,6 @@ #include -struct Flag_Info { - union { - Bit8u b; - Bit16u w; - Bit32u d; - } var1,var2,result; - Bitu type; - Bitu prev_type; - Bitu oldcf; - Bitu word; -}; - - #define FLAG_CF 0x00000001 #define FLAG_PF 0x00000004 #define FLAG_AF 0x00000010 @@ -50,11 +37,10 @@ struct Flag_Info { #define FLAG_NT 0x00004000 #define FLAG_VM 0x00020000 +#define SETFLAGBIT(TYPE,TEST) if (TEST) reg_flags|=FLAG_ ## TYPE; else reg_flags&=~FLAG_ ## TYPE -#define SETFLAGBIT(TYPE,TEST) if (TEST) flags.word|=FLAG_ ## TYPE; else flags.word&=~FLAG_ ## TYPE - -#define GETFLAG(TYPE) (flags.word & FLAG_ ## TYPE) -#define GETFLAGBOOL(TYPE) ((flags.word & FLAG_ ## TYPE) ? true : false ) +#define GETFLAG(TYPE) (reg_flags & FLAG_ ## TYPE) +#define GETFLAGBOOL(TYPE) ((reg_flags & FLAG_ ## TYPE) ? true : false ) struct Segment { Bit16u val; @@ -91,17 +77,13 @@ union GenReg32 { #endif struct CPU_Regs { - GenReg32 regs[8],ip; + GenReg32 regs[8],ip; + Bitu flags; }; extern Segments Segs; -extern Flag_Info flags; extern CPU_Regs cpu_regs; - -//#define SegPhys(index) Segs[index].phys -//#define SegValue(index) Segs[index].val - INLINE PhysPt SegPhys(SegNames index) { return Segs.phys[index]; } @@ -109,7 +91,6 @@ INLINE PhysPt SegPhys(SegNames index) { INLINE Bit16u SegValue(SegNames index) { return Segs.val[index]; } - INLINE RealPt RealMakeSeg(SegNames index,Bit16u off) { return RealMake(SegValue(index),off); @@ -121,7 +102,6 @@ INLINE void SegSet16(Bitu index,Bit16u val) { Segs.phys[index]=val << 4; } - enum { REGI_AX, REGI_CX, REGI_DX, REGI_BX, REGI_SP, REGI_BP, REGI_SI, REGI_DI @@ -140,7 +120,6 @@ enum { #define reg_16(reg) (cpu_regs.regs[(reg)].word[W_INDEX]) #define reg_32(reg) (cpu_regs.regs[(reg)].dword[DW_INDEX]) - #define reg_al cpu_regs.regs[REGI_AX].byte[BL_INDEX] #define reg_ah cpu_regs.regs[REGI_AX].byte[BH_INDEX] #define reg_ax cpu_regs.regs[REGI_AX].word[W_INDEX] @@ -176,5 +155,7 @@ enum { #define reg_ip cpu_regs.ip.word[W_INDEX] #define reg_eip cpu_regs.ip.dword[DW_INDEX] +#define reg_flags cpu_regs.flags + #endif From 66df37b5336668d947e6cb751f61c6789fa755bc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 26 Oct 2003 19:00:47 +0000 Subject: [PATCH 1297/4131] New lazy flag header file and endian fixes for flags Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1378 --- src/cpu/Makefile.am | 2 +- src/cpu/core_16/Makefile.am | 3 - src/cpu/core_16/helpers.h | 143 ---- src/cpu/core_16/main.h | 1182 ---------------------------- src/cpu/core_16/prefix_66.h | 490 ------------ src/cpu/core_16/prefix_66_of.h | 226 ------ src/cpu/core_16/prefix_of.h | 425 ---------- src/cpu/core_16/support.h | 401 ---------- src/cpu/core_16/table_ea.h | 381 --------- src/cpu/core_full.cpp | 4 +- src/cpu/core_full/load.h | 15 +- src/cpu/core_full/op.h | 86 +- src/cpu/core_normal.cpp | 2 +- src/cpu/core_normal/prefix_0f.h | 14 +- src/cpu/core_normal/prefix_66.h | 12 +- src/cpu/core_normal/prefix_66_0f.h | 13 +- src/cpu/core_normal/prefix_none.h | 33 +- src/cpu/cpu.cpp | 15 +- src/cpu/flags.cpp | 365 ++++----- src/cpu/instructions.h | 590 +++++++------- src/cpu/lazyflags.h | 45 +- 21 files changed, 614 insertions(+), 3833 deletions(-) delete mode 100644 src/cpu/core_16/Makefile.am delete mode 100644 src/cpu/core_16/helpers.h delete mode 100644 src/cpu/core_16/main.h delete mode 100644 src/cpu/core_16/prefix_66.h delete mode 100644 src/cpu/core_16/prefix_66_of.h delete mode 100644 src/cpu/core_16/prefix_of.h delete mode 100644 src/cpu/core_16/support.h delete mode 100644 src/cpu/core_16/table_ea.h diff --git a/src/cpu/Makefile.am b/src/cpu/Makefile.am index 878bc1de..2274f9a4 100644 --- a/src/cpu/Makefile.am +++ b/src/cpu/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = core_16 core_full core_normal +SUBDIRS = core_full core_normal AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libcpu.a diff --git a/src/cpu/core_16/Makefile.am b/src/cpu/core_16/Makefile.am deleted file mode 100644 index 2971ca9c..00000000 --- a/src/cpu/core_16/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ - -noinst_HEADERS = helpers.h main.h prefix_66.h prefix_of.h support.h table_ea.h \ - prefix_66_of.h diff --git a/src/cpu/core_16/helpers.h b/src/cpu/core_16/helpers.h deleted file mode 100644 index 11099840..00000000 --- a/src/cpu/core_16/helpers.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2002 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#define GetEAa \ - PhysPt eaa=(*lookupEATable)[rm](); - -#define GetRMEAa \ - GetRM; \ - GetEAa; - - -#define RMEbGb(inst) \ - { \ - GetRMrb; \ - if (rm >= 0xc0 ) {GetEArb;inst(*earb,*rmrb,LoadRb,SaveRb);} \ - else {GetEAa;inst(eaa,*rmrb,LoadMb,SaveMb);} \ - } - -#define RMGbEb(inst) \ - { \ - GetRMrb; \ - if (rm >= 0xc0 ) {GetEArb;inst(*rmrb,*earb,LoadRb,SaveRb);} \ - else {GetEAa;inst(*rmrb,LoadMb(eaa),LoadRb,SaveRb);} \ - } - -#define RMEb(inst) \ - { \ - if (rm >= 0xc0 ) {GetEArb;inst(*earb,LoadRb,SaveRb);} \ - else {GetEAa;inst(eaa,LoadMb,SaveMb);} \ - } - -#define RMEwGw(inst) \ - { \ - GetRMrw; \ - if (rm >= 0xc0 ) {GetEArw;inst(*earw,*rmrw,LoadRw,SaveRw);} \ - else {GetEAa;inst(eaa,*rmrw,LoadMw,SaveMw);} \ - } - -#define RMEwGwOp3(inst,op3) \ - { \ - GetRMrw; \ - if (rm >= 0xc0 ) {GetEArw;inst(*earw,*rmrw,op3,LoadRw,SaveRw);} \ - else {GetEAa;inst(eaa,*rmrw,op3,LoadMw,SaveMw);} \ - } - -#define RMGwEw(inst) \ - { \ - GetRMrw; \ - if (rm >= 0xc0 ) {GetEArw;inst(*rmrw,*earw,LoadRw,SaveRw);} \ - else {GetEAa;inst(*rmrw,LoadMw(eaa),LoadRw,SaveRw);} \ - } - -#define RMGwEwOp3(inst,op3) \ - { \ - GetRMrw; \ - if (rm >= 0xc0 ) {GetEArw;inst(*rmrw,*earw,op3,LoadRw,SaveRw);} \ - else {GetEAa;inst(*rmrw,LoadMw(eaa),op3,LoadRw,SaveRw);} \ - } - -#define RMEw(inst) \ - { \ - if (rm >= 0xc0 ) {GetEArw;inst(*earw,LoadRw,SaveRw);} \ - else {GetEAa;inst(eaa,LoadMw,SaveMw);} \ - } - -#define RMEdGd(inst) \ - { \ - GetRMrd; \ - if (rm >= 0xc0 ) {GetEArd;inst(*eard,*rmrd,LoadRd,SaveRd);} \ - else {GetEAa;inst(eaa,*rmrd,LoadMd,SaveMd);} \ - } - -#define RMEdGdOp3(inst,op3) \ - { \ - GetRMrd; \ - if (rm >= 0xc0 ) {GetEArd;inst(*eard,*rmrd,op3,LoadRd,SaveRd);} \ - else {GetEAa;inst(eaa,*rmrd,op3,LoadMd,SaveMd);} \ - } - - -#define RMGdEd(inst) \ - { \ - GetRMrd; \ - if (rm >= 0xc0 ) {GetEArd;inst(*rmrd,*eard,LoadRd,SaveRd);} \ - else {GetEAa;inst(*rmrd,LoadMd(eaa),LoadRd,SaveRd);} \ - } - -#define RMGdEdOp3(inst,op3) \ - { \ - GetRMrd; \ - if (rm >= 0xc0 ) {GetEArd;inst(*rmrd,*eard,op3,LoadRd,SaveRd);} \ - else {GetEAa;inst(*rmrd,LoadMd(eaa),op3,LoadRd,SaveRd);} \ - } - - - - -#define RMEw(inst) \ - { \ - if (rm >= 0xc0 ) {GetEArw;inst(*earw,LoadRw,SaveRw);} \ - else {GetEAa;inst(eaa,LoadMw,SaveMw);} \ - } - -#define RMEd(inst) \ - { \ - if (rm >= 0xc0 ) {GetEArd;inst(*eard,LoadRd,SaveRd);} \ - else {GetEAa;inst(eaa,LoadMd,SaveMd);} \ - } - -#define ALIb(inst) \ - { inst(reg_al,Fetchb(),LoadRb,SaveRb)} - -#define AXIw(inst) \ - { inst(reg_ax,Fetchw(),LoadRw,SaveRw);} - -#define EAXId(inst) \ - { inst(reg_eax,Fetchd(),LoadRd,SaveRd);} - -#define FPU_ESC(code) { \ - Bit8u rm=Fetchb(); \ - if (rm>=0xc0) { \ - FPU_ESC ## code ## _Normal(rm); \ - } else { \ - GetEAa;FPU_ESC ## code ## _EA(rm,eaa); \ - } \ -} - diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h deleted file mode 100644 index 1bda6241..00000000 --- a/src/cpu/core_16/main.h +++ /dev/null @@ -1,1182 +0,0 @@ -/* - * Copyright (C) 2002 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -restart: - switch(Fetchb()) { - case 0x00: /* ADD Eb,Gb */ - RMEbGb(ADDB);break; - case 0x01: /* ADD Ew,Gw */ - RMEwGw(ADDW);break; - case 0x02: /* ADD Gb,Eb */ - RMGbEb(ADDB);break; - case 0x03: /* ADD Gw,Ew */ - RMGwEw(ADDW);break; - case 0x04: /* ADD AL,Ib */ - ALIb(ADDB);break; - case 0x05: /* ADD AX,Iw */ - AXIw(ADDW);break; - case 0x06: /* PUSH ES */ - Push_16(SegValue(es));break; - case 0x07: /* POP ES */ - SegSet16(es,Pop_16());break; - case 0x08: /* OR Eb,Gb */ - RMEbGb(ORB);break; - case 0x09: /* OR Ew,Gw */ - RMEwGw(ORW);break; - case 0x0a: /* OR Gb,Eb */ - RMGbEb(ORB);break; - case 0x0b: /* OR Gw,Ew */ - RMGwEw(ORW);break; - case 0x0c: /* OR AL,Ib */ - ALIb(ORB);break; - case 0x0d: /* OR AX,Iw */ - AXIw(ORW);break; - case 0x0e: /* PUSH CS */ - Push_16(SegValue(cs));break; - case 0x0f: /* 2 byte opcodes*/ - #include "prefix_of.h" - break; - case 0x10: /* ADC Eb,Gb */ - RMEbGb(ADCB);break; - case 0x11: /* ADC Ew,Gw */ - RMEwGw(ADCW);break; - case 0x12: /* ADC Gb,Eb */ - RMGbEb(ADCB);break; - case 0x13: /* ADC Gw,Ew */ - RMGwEw(ADCW);break; - case 0x14: /* ADC AL,Ib */ - ALIb(ADCB);break; - case 0x15: /* ADC AX,Iw */ - AXIw(ADCW);break; - case 0x16: /* PUSH SS */ - Push_16(SegValue(ss));break; - case 0x17: /* POP SS */ - SegSet16(ss,Pop_16()); - CPU_Cycles++;//Be sure we run another instruction - break; - case 0x18: /* SBB Eb,Gb */ - RMEbGb(SBBB);break; - case 0x19: /* SBB Ew,Gw */ - RMEwGw(SBBW);break; - case 0x1a: /* SBB Gb,Eb */ - RMGbEb(SBBB);break; - case 0x1b: /* SBB Gw,Ew */ - RMGwEw(SBBW);break; - case 0x1c: /* SBB AL,Ib */ - ALIb(SBBB);break; - case 0x1d: /* SBB AX,Iw */ - AXIw(SBBW);break; - case 0x1e: /* PUSH DS */ - Push_16(SegValue(ds));break; - case 0x1f: /* POP DS */ - SegSet16(ds,Pop_16());break; - case 0x20: /* AND Eb,Gb */ - RMEbGb(ANDB);break; - case 0x21: /* AND Ew,Gw */ - RMEwGw(ANDW);break; - case 0x22: /* AND Gb,Eb */ - RMGbEb(ANDB);break; - case 0x23: /* AND Gw,Ew */ - RMGwEw(ANDW);break; - case 0x24: /* AND AL,Ib */ - ALIb(ANDB);break; - case 0x25: /* AND AX,Iw */ - AXIw(ANDW);break; - case 0x26: /* SEG ES: */ - SegPrefix(es);break; - case 0x27: /* DAA */ - DAA(); - break; - case 0x28: /* SUB Eb,Gb */ - RMEbGb(SUBB);break; - case 0x29: /* SUB Ew,Gw */ - RMEwGw(SUBW);break; - case 0x2a: /* SUB Gb,Eb */ - RMGbEb(SUBB);break; - case 0x2b: /* SUB Gw,Ew */ - RMGwEw(SUBW);break; - case 0x2c: /* SUB AL,Ib */ - ALIb(SUBB);break; - case 0x2d: /* SUB AX,Iw */ - AXIw(SUBW);break; - case 0x2e: /* SEG CS: */ - SegPrefix(cs);break; - case 0x2f: /* DAS */ - DAS(); - break; - case 0x30: /* XOR Eb,Gb */ - RMEbGb(XORB);break; - case 0x31: /* XOR Ew,Gw */ - RMEwGw(XORW);break; - case 0x32: /* XOR Gb,Eb */ - RMGbEb(XORB);break; - case 0x33: /* XOR Gw,Ew */ - RMGwEw(XORW);break; - case 0x34: /* XOR AL,Ib */ - ALIb(XORB);break; - case 0x35: /* XOR AX,Iw */ - AXIw(XORW);break; - case 0x36: /* SEG SS: */ - SegPrefix(ss);break; - case 0x37: /* AAA */ - AAA(); - break; - case 0x38: /* CMP Eb,Gb */ - RMEbGb(CMPB);break; - case 0x39: /* CMP Ew,Gw */ - RMEwGw(CMPW);break; - case 0x3a: /* CMP Gb,Eb */ - RMGbEb(CMPB);break; - case 0x3b: /* CMP Gw,Ew */ - RMGwEw(CMPW);break; - case 0x3c: /* CMP AL,Ib */ - ALIb(CMPB);break; - case 0x3d: /* CMP AX,Iw */ - AXIw(CMPW);break; - case 0x3e: /* SEG DS: */ - SegPrefix(ds);break; - case 0x3f: /* AAS */ - AAS(); - break; - case 0x40: /* INC AX */ - INCW(reg_ax,LoadRw,SaveRw);break; - case 0x41: /* INC CX */ - INCW(reg_cx,LoadRw,SaveRw);break; - case 0x42: /* INC DX */ - INCW(reg_dx,LoadRw,SaveRw);break; - case 0x43: /* INC BX */ - INCW(reg_bx,LoadRw,SaveRw);break; - case 0x44: /* INC SP */ - INCW(reg_sp,LoadRw,SaveRw);break; - case 0x45: /* INC BP */ - INCW(reg_bp,LoadRw,SaveRw);break; - case 0x46: /* INC SI */ - INCW(reg_si,LoadRw,SaveRw);break; - case 0x47: /* INC DI */ - INCW(reg_di,LoadRw,SaveRw);break; - case 0x48: /* DEC AX */ - DECW(reg_ax,LoadRw,SaveRw);break; - case 0x49: /* DEC CX */ - DECW(reg_cx,LoadRw,SaveRw);break; - case 0x4a: /* DEC DX */ - DECW(reg_dx,LoadRw,SaveRw);break; - case 0x4b: /* DEC BX */ - DECW(reg_bx,LoadRw,SaveRw);break; - case 0x4c: /* DEC SP */ - DECW(reg_sp,LoadRw,SaveRw);break; - case 0x4d: /* DEC BP */ - DECW(reg_bp,LoadRw,SaveRw);break; - case 0x4e: /* DEC SI */ - DECW(reg_si,LoadRw,SaveRw);break; - case 0x4f: /* DEC DI */ - DECW(reg_di,LoadRw,SaveRw);break; - case 0x50: /* PUSH AX */ - Push_16(reg_ax);break; - case 0x51: /* PUSH CX */ - Push_16(reg_cx);break; - case 0x52: /* PUSH DX */ - Push_16(reg_dx);break; - case 0x53: /* PUSH BX */ - Push_16(reg_bx);break; - case 0x54: /* PUSH SP */ -//TODO Check if this is correct i think it's SP+2 or something - Push_16(reg_sp);break; - case 0x55: /* PUSH BP */ - Push_16(reg_bp);break; - case 0x56: /* PUSH SI */ - Push_16(reg_si);break; - case 0x57: /* PUSH DI */ - Push_16(reg_di);break; - case 0x58: /* POP AX */ - reg_ax=Pop_16();break; - case 0x59: /* POP CX */ - reg_cx=Pop_16();break; - case 0x5a: /* POP DX */ - reg_dx=Pop_16();break; - case 0x5b: /* POP BX */ - reg_bx=Pop_16();break; - case 0x5c: /* POP SP */ - reg_sp=Pop_16();break; - case 0x5d: /* POP BP */ - reg_bp=Pop_16();break; - case 0x5e: /* POP SI */ - reg_si=Pop_16();break; - case 0x5f: /* POP DI */ - reg_di=Pop_16();break; - case 0x60: /* PUSHA */ - { - Bit16u old_sp=reg_sp; - Push_16(reg_ax);Push_16(reg_cx);Push_16(reg_dx);Push_16(reg_bx); - Push_16(old_sp);Push_16(reg_bp);Push_16(reg_si);Push_16(reg_di); - } - break; - case 0x61: /* POPA */ - reg_di=Pop_16();reg_si=Pop_16();reg_bp=Pop_16();Pop_16();//Don't save SP - reg_bx=Pop_16();reg_dx=Pop_16();reg_cx=Pop_16();reg_ax=Pop_16(); - break; - case 0x62: /* BOUND */ - { - Bit16s bound_min, bound_max; - GetRMrw;GetEAa; - bound_min=LoadMw(eaa); - bound_max=LoadMw(eaa+2); - if ( (((Bit16s)*rmrw) < bound_min) || (((Bit16s)*rmrw) > bound_max) ) { - EXCEPTION(5); - } - } - break; - case 0x63: /* ARPL */ - NOTDONE;break; -#ifdef CPU_386 - case 0x64: /* SEG FS: */ - SegPrefix(fs);break; - case 0x65: /* SEG GS: */ - SegPrefix(gs);break; - case 0x66: /* Operand Size Prefix */ - #include "prefix_66.h" - break; - case 0x67: /* Address Size Prefix */ -#ifdef CPU_PREFIX_67 - core_16.prefixes^=PREFIX_ADDR; - lookupEATable=EAPrefixTable[core_16.prefixes]; - goto restart; -#else - NOTDONE; -#endif - break; -#endif - case 0x68: /* PUSH Iw */ - Push_16(Fetchw());break; - case 0x69: /* IMUL Gw,Ew,Iw */ - RMGwEwOp3(DIMULW,Fetchws()); - break; - case 0x6a: /* PUSH Ib */ - Push_16(Fetchbs()); - break; - case 0x6b: /* IMUL Gw,Ew,Ib */ - RMGwEwOp3(DIMULW,Fetchbs()); - break; - case 0x6c: /* INSB */ - { - stringDI; - SaveMb(to,IO_Read(reg_dx)); - if (GETFLAG(DF)) reg_di--; else reg_di++; - break; - } - case 0x6d: /* INSW */ - { - stringDI; - SaveMb(to,IO_Read(reg_dx)); - SaveMb((to+1),IO_Read(reg_dx+1)); - if (GETFLAG(DF)) reg_di-=2; else reg_di+=2; - break; - } - case 0x6e: /* OUTSB */ - { - stringSI; - IO_Write(reg_dx,LoadMb(from)); - if (GETFLAG(DF)) reg_si--; else reg_si++; - break; - } - case 0x6f: /* OUTSW */ - { - stringSI; - IO_Write(reg_dx,LoadMb(from)); - IO_Write(reg_dx+1,LoadMb(from+1)); - if (GETFLAG(DF)) reg_si-=2; else reg_si+=2; - break; - } - case 0x70: /* JO */ - JumpSIb(get_OF());break; - case 0x71: /* JNO */ - JumpSIb(!get_OF());break; - case 0x72: /* JB */ - JumpSIb(get_CF());break; - case 0x73: /* JNB */ - JumpSIb(!get_CF());break; - case 0x74: /* JZ */ - JumpSIb(get_ZF());break; - case 0x75: /* JNZ */ - JumpSIb(!get_ZF()); break; - case 0x76: /* JBE */ - JumpSIb(get_CF() || get_ZF());break; - case 0x77: /* JNBE */ - JumpSIb(!get_CF() && !get_ZF());break; - case 0x78: /* JS */ - JumpSIb(get_SF());break; - case 0x79: /* JNS */ - JumpSIb(!get_SF());break; - case 0x7a: /* JP */ - JumpSIb(get_PF());break; - case 0x7b: /* JNP */ - JumpSIb(!get_PF());break; - case 0x7c: /* JL */ - JumpSIb(get_SF() != get_OF());break; - case 0x7d: /* JNL */ - JumpSIb(get_SF() == get_OF());break; - case 0x7e: /* JLE */ - JumpSIb(get_ZF() || (get_SF() != get_OF()));break; - case 0x7f: /* JNLE */ - JumpSIb((get_SF() == get_OF()) && !get_ZF());break; - case 0x80: /* Grpl Eb,Ib */ - case 0x82: /* Grpl Eb,Ib Mirror instruction*/ - { - GetRM; - if (rm>= 0xc0) { - GetEArb;Bit8u ib=Fetchb(); - switch (rm & 0x38) { - case 0x00:ADDB(*earb,ib,LoadRb,SaveRb);break; - case 0x08: ORB(*earb,ib,LoadRb,SaveRb);break; - case 0x10:ADCB(*earb,ib,LoadRb,SaveRb);break; - case 0x18:SBBB(*earb,ib,LoadRb,SaveRb);break; - case 0x20:ANDB(*earb,ib,LoadRb,SaveRb);break; - case 0x28:SUBB(*earb,ib,LoadRb,SaveRb);break; - case 0x30:XORB(*earb,ib,LoadRb,SaveRb);break; - case 0x38:CMPB(*earb,ib,LoadRb,SaveRb);break; - } - } else { - GetEAa;Bit8u ib=Fetchb(); - switch (rm & 0x38) { - case 0x00:ADDB(eaa,ib,LoadMb,SaveMb);break; - case 0x08: ORB(eaa,ib,LoadMb,SaveMb);break; - case 0x10:ADCB(eaa,ib,LoadMb,SaveMb);break; - case 0x18:SBBB(eaa,ib,LoadMb,SaveMb);break; - case 0x20:ANDB(eaa,ib,LoadMb,SaveMb);break; - case 0x28:SUBB(eaa,ib,LoadMb,SaveMb);break; - case 0x30:XORB(eaa,ib,LoadMb,SaveMb);break; - case 0x38:CMPB(eaa,ib,LoadMb,SaveMb);break; - } - } - break; - } - case 0x81: /* Grpl Ew,Iw */ - { - GetRM; - if (rm>= 0xc0) { - GetEArw;Bit16u iw=Fetchw(); - switch (rm & 0x38) { - case 0x00:ADDW(*earw,iw,LoadRw,SaveRw);break; - case 0x08: ORW(*earw,iw,LoadRw,SaveRw);break; - case 0x10:ADCW(*earw,iw,LoadRw,SaveRw);break; - case 0x18:SBBW(*earw,iw,LoadRw,SaveRw);break; - case 0x20:ANDW(*earw,iw,LoadRw,SaveRw);break; - case 0x28:SUBW(*earw,iw,LoadRw,SaveRw);break; - case 0x30:XORW(*earw,iw,LoadRw,SaveRw);break; - case 0x38:CMPW(*earw,iw,LoadRw,SaveRw);break; - } - } else { - GetEAa;Bit16u iw=Fetchw(); - switch (rm & 0x38) { - case 0x00:ADDW(eaa,iw,LoadMw,SaveMw);break; - case 0x08: ORW(eaa,iw,LoadMw,SaveMw);break; - case 0x10:ADCW(eaa,iw,LoadMw,SaveMw);break; - case 0x18:SBBW(eaa,iw,LoadMw,SaveMw);break; - case 0x20:ANDW(eaa,iw,LoadMw,SaveMw);break; - case 0x28:SUBW(eaa,iw,LoadMw,SaveMw);break; - case 0x30:XORW(eaa,iw,LoadMw,SaveMw);break; - case 0x38:CMPW(eaa,iw,LoadMw,SaveMw);break; - } - } - break; - } - case 0x83: /* Grpl Ew,Ix */ - { - GetRM; - if (rm>= 0xc0) { - GetEArw;Bit16u iw=(Bit16s)Fetchbs(); - switch (rm & 0x38) { - case 0x00:ADDW(*earw,iw,LoadRw,SaveRw);break; - case 0x08: ORW(*earw,iw,LoadRw,SaveRw);break; - case 0x10:ADCW(*earw,iw,LoadRw,SaveRw);break; - case 0x18:SBBW(*earw,iw,LoadRw,SaveRw);break; - case 0x20:ANDW(*earw,iw,LoadRw,SaveRw);break; - case 0x28:SUBW(*earw,iw,LoadRw,SaveRw);break; - case 0x30:XORW(*earw,iw,LoadRw,SaveRw);break; - case 0x38:CMPW(*earw,iw,LoadRw,SaveRw);break; - } - } else { - GetEAa;Bit16u iw=(Bit16s)Fetchbs(); - switch (rm & 0x38) { - case 0x00:ADDW(eaa,iw,LoadMw,SaveMw);break; - case 0x08: ORW(eaa,iw,LoadMw,SaveMw);break; - case 0x10:ADCW(eaa,iw,LoadMw,SaveMw);break; - case 0x18:SBBW(eaa,iw,LoadMw,SaveMw);break; - case 0x20:ANDW(eaa,iw,LoadMw,SaveMw);break; - case 0x28:SUBW(eaa,iw,LoadMw,SaveMw);break; - case 0x30:XORW(eaa,iw,LoadMw,SaveMw);break; - case 0x38:CMPW(eaa,iw,LoadMw,SaveMw);break; - } - } - break; - } - case 0x84: /* TEST Eb,Gb */ - RMEbGb(TESTB); - break; - case 0x85: /* TEST Ew,Gw */ - RMEwGw(TESTW); - break; - case 0x86: /* XCHG Eb,Gb */ - { - GetRMrb;Bit8u oldrmrb=*rmrb; - if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;*earb=oldrmrb;} - else {GetEAa;*rmrb=LoadMb(eaa);SaveMb(eaa,oldrmrb);} - break; - } - case 0x87: /* XCHG Ew,Gw */ - { - GetRMrw;Bit16u oldrmrw=*rmrw; - if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;*earw=oldrmrw;} - else {GetEAa;*rmrw=LoadMw(eaa);SaveMw(eaa,oldrmrw);} - break; - } - case 0x88: /* MOV Eb,Gb */ - { - GetRMrb; - if (rm >= 0xc0 ) {GetEArb;*earb=*rmrb;} - else {GetEAa;SaveMb(eaa,*rmrb);} - break; - } - case 0x89: /* MOV Ew,Gw */ - { - GetRMrw; - if (rm >= 0xc0 ) {GetEArw;*earw=*rmrw;} - else {GetEAa;SaveMw(eaa,*rmrw);} - break; - } - case 0x8a: /* MOV Gb,Eb */ - { - GetRMrb; - if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;} - else {GetEAa;*rmrb=LoadMb(eaa);} - break; - } - case 0x8b: /* MOV Gw,Ew */ - { - GetRMrw; - if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;} - else {GetEAa;*rmrw=LoadMw(eaa);} - break; - } - case 0x8c: /* Mov Ew,Sw */ - { - GetRM;Bit16u val; - switch (rm & 0x38) { - case 0x00: /* MOV Ew,ES */ - val=SegValue(es);break; - case 0x08: /* MOV Ew,CS */ - val=SegValue(cs);break; - case 0x10: /* MOV Ew,SS */ - val=SegValue(ss);break; - case 0x18: /* MOV Ew,DS */ - val=SegValue(ds);break; - case 0x20: /* MOV Ew,FS */ - val=SegValue(fs);break; - case 0x28: /* MOV Ew,GS */ - val=SegValue(gs);break; - default: - val=0; - E_Exit("CPU:8c:Illegal RM Byte"); - } - if (rm >= 0xc0 ) {GetEArw;*earw=val;} - else {GetEAa;SaveMw(eaa,val);} - break; - } - case 0x8d: /* LEA */ - { - core_16.segbase=0; - core_16.prefixes|=PREFIX_SEG; - lookupEATable=EAPrefixTable[core_16.prefixes]; - GetRMrw;GetEAa; - *rmrw=(Bit16u)eaa; - break; - } - case 0x8e: /* MOV Sw,Ew */ - { - GetRM;Bit16u val; - if (rm >= 0xc0 ) {GetEArw;val=*earw;} - else {GetEAa;val=LoadMw(eaa);} - switch (rm & 0x38) { - case 0x00: /* MOV ES,Ew */ - SegSet16(es,val);break; - case 0x08: /* MOV CS,Ew Illegal*/ - E_Exit("CPU:Illegal MOV CS Call"); - break; - case 0x10: /* MOV SS,Ew */ - SegSet16(ss,val); - CPU_Cycles++;//Be sure we run another instruction - break; - case 0x18: /* MOV DS,Ew */ - SegSet16(ds,val);break; - case 0x20: /* MOV FS,Ew */ - SegSet16(fs,val);break; - case 0x28: /* MOV GS,Ew */ - SegSet16(gs,val);break; - default: - E_Exit("CPU:8e:Illegal RM Byte"); - } - break; - } - case 0x8f: /* POP Ew */ - { - GetRM; - if (rm >= 0xc0 ) {GetEArw;*earw=Pop_16();} - else {GetEAa;SaveMw(eaa,Pop_16());} - break; - } - case 0x90: /* NOP */ - break; - case 0x91: /* XCHG CX,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_cx;reg_cx=temp; } - break; - case 0x92: /* XCHG DX,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_dx;reg_dx=temp; } - break; - case 0x93: /* XCHG BX,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_bx;reg_bx=temp; } - break; - case 0x94: /* XCHG SP,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_sp;reg_sp=temp; } - break; - case 0x95: /* XCHG BP,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_bp;reg_bp=temp; } - break; - case 0x96: /* XCHG SI,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_si;reg_si=temp; } - break; - case 0x97: /* XCHG DI,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_di;reg_di=temp; } - break; - case 0x98: /* CBW */ - reg_ax=(Bit8s)reg_al;break; - case 0x99: /* CWD */ - if (reg_ax & 0x8000) reg_dx=0xffff; - else reg_dx=0; - break; - case 0x9a: /* CALL Ap */ - { - Bit16u newip=Fetchw();Bit16u newcs=Fetchw(); - Push_16(SegValue(cs));Push_16(GETIP); - SegSet16(cs,newcs);SETIP(newip); - break; - } - case 0x9b: /* WAIT */ - break; /* No waiting here */ - case 0x9c: /* PUSHF */ - FillFlags(); - Push_16(flags.word); - break; - case 0x9d: /* POPF */ - SETFLAGSw(Pop_16()); - CheckTF(); -#ifdef CPU_PIC_CHECK - if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; -#endif - break; - case 0x9e: /* SAHF */ - SETFLAGSb(reg_ah); - break; - case 0x9f: /* LAHF */ - { - FillFlags(); - reg_ah=(Bit8u)flags.word; - break; - } - case 0xa0: /* MOV AL,Ob */ - { - reg_al=LoadMb(GetEADirect[core_16.prefixes]()); - } - break; - case 0xa1: /* MOV AX,Ow */ - { - reg_ax=LoadMw(GetEADirect[core_16.prefixes]()); - } - break; - case 0xa2: /* MOV Ob,AL */ - { - SaveMb(GetEADirect[core_16.prefixes](),reg_al); - } - break; - case 0xa3: /* MOV Ow,AX */ - { - SaveMw(GetEADirect[core_16.prefixes](),reg_ax); - } - break; - case 0xa4: /* MOVSB */ - { - stringSI;stringDI; - SaveMb(to,LoadMb(from));; - if (GETFLAG(DF)) { reg_si--;reg_di--; } - else {reg_si++;reg_di++;} - break; - } - case 0xa5: /* MOVSW */ - { - stringSI;stringDI; - SaveMw(to,LoadMw(from)); - if (GETFLAG(DF)) { reg_si-=2;reg_di-=2; } - else {reg_si+=2;reg_di+=2;} - break; - } - case 0xa6: /* CMPSB */ - { - stringSI;stringDI; - CMPB(from,LoadMb(to),LoadMb,0); - if (GETFLAG(DF)) { reg_si--;reg_di--; } - else {reg_si++;reg_di++;} - break; - } - case 0xa7: /* CMPSW */ - { - stringSI;stringDI; - CMPW(from,LoadMw(to),LoadMw,0); - if (GETFLAG(DF)) { reg_si-=2;reg_di-=2; } - else {reg_si+=2;reg_di+=2;} - break; - } - case 0xa8: /* TEST AL,Ib */ - ALIb(TESTB);break; - case 0xa9: /* TEST AX,Iw */ - AXIw(TESTW);break; - case 0xaa: /* STOSB */ - { - stringDI; - SaveMb(to,reg_al); - if (GETFLAG(DF)) { reg_di--; } - else {reg_di++;} - break; - } - case 0xab: /* STOSW */ - { - stringDI; - SaveMw(to,reg_ax); - if (GETFLAG(DF)) { reg_di-=2; } - else {reg_di+=2;} - break; - } - case 0xac: /* LODSB */ - { - stringSI; - reg_al=LoadMb(from); - if (GETFLAG(DF)) { reg_si--; } - else {reg_si++;} - break; - } - case 0xad: /* LODSW */ - { - stringSI; - reg_ax=LoadMw(from); - if (GETFLAG(DF)) { reg_si-=2;} - else {reg_si+=2;} - break; - } - case 0xae: /* SCASB */ - { - stringDI; - CMPB(reg_al,LoadMb(to),LoadRb,0); - if (GETFLAG(DF)) { reg_di--; } - else {reg_di++;} - break; - } - case 0xaf: /* SCASW */ - { - stringDI; - CMPW(reg_ax,LoadMw(to),LoadRw,0); - if (GETFLAG(DF)) { reg_di-=2; } - else {reg_di+=2;} - break; - } - case 0xb0: /* MOV AL,Ib */ - reg_al=Fetchb();break; - case 0xb1: /* MOV CL,Ib */ - reg_cl=Fetchb();break; - case 0xb2: /* MOV DL,Ib */ - reg_dl=Fetchb();break; - case 0xb3: /* MOV BL,Ib */ - reg_bl=Fetchb();break; - case 0xb4: /* MOV AH,Ib */ - reg_ah=Fetchb();break; - case 0xb5: /* MOV CH,Ib */ - reg_ch=Fetchb();break; - case 0xb6: /* MOV DH,Ib */ - reg_dh=Fetchb();break; - case 0xb7: /* MOV BH,Ib */ - reg_bh=Fetchb();break; - case 0xb8: /* MOV AX,Iw */ - reg_ax=Fetchw();break; - case 0xb9: /* MOV CX,Iw */ - reg_cx=Fetchw();break; - case 0xba: /* MOV DX,Iw */ - reg_dx=Fetchw();break; - case 0xbb: /* MOV BX,Iw */ - reg_bx=Fetchw();break; - case 0xbc: /* MOV SP,Iw */ - reg_sp=Fetchw();break; - case 0xbd: /* MOV BP.Iw */ - reg_bp=Fetchw();break; - case 0xbe: /* MOV SI,Iw */ - reg_si=Fetchw();break; - case 0xbf: /* MOV DI,Iw */ - reg_di=Fetchw();break; - case 0xc0: /* GRP2 Eb,Ib */ - GRP2B(Fetchb());break; - case 0xc1: /* GRP2 Ew,Ib */ - GRP2W(Fetchb());break; - case 0xc2: /* RETN Iw */ - { - Bit16u addsp=Fetchw(); - SETIP(Pop_16());reg_sp+=addsp; - break; - } - case 0xc3: /* RETN */ - SETIP(Pop_16()); - break; - case 0xc4: /* LES */ - { - GetRMrw;GetEAa; - *rmrw=LoadMw(eaa);SegSet16(es,LoadMw(eaa+2)); - break; - } - case 0xc5: /* LDS */ - { - GetRMrw;GetEAa; - *rmrw=LoadMw(eaa);SegSet16(ds,LoadMw(eaa+2)); - break; - } - case 0xc6: /* MOV Eb,Ib */ - { - GetRM; - if (rm>0xc0) {GetEArb;*earb=Fetchb();} - else {GetEAa;SaveMb(eaa,Fetchb());} - break; - } - case 0xc7: /* MOV EW,Iw */ - { - GetRM; - if (rm>0xc0) {GetEArw;*earw=Fetchw();} - else {GetEAa;SaveMw(eaa,Fetchw());} - break; - } - case 0xc8: /* ENTER Iw,Ib */ - { - Bit16u bytes=Fetchw();Bit8u level=Fetchb(); - Push_16(reg_bp);reg_bp=reg_sp;reg_sp-=bytes; - PhysPt reader=SegBase(ss)+reg_bp; - for (Bit8u i=1;i>3) { - case 0x00: /* TEST Eb,Ib */ - case 0x01: /* TEST Eb,Ib Undocumented*/ - { - if (rm >= 0xc0 ) {GetEArb;TESTB(*earb,Fetchb(),LoadRb,0)} - else {GetEAa;TESTB(eaa,Fetchb(),LoadMb,0);} - break; - } - case 0x02: /* NOT Eb */ - { - if (rm >= 0xc0 ) {GetEArb;*earb=~*earb;} - else {GetEAa;SaveMb(eaa,~LoadMb(eaa));} - break; - } - case 0x03: /* NEG Eb */ - { - flags.type=t_NEGb; - if (rm >= 0xc0 ) { - GetEArb;flags.var1.b=*earb;flags.result.b=0-flags.var1.b; - *earb=flags.result.b; - } else { - GetEAa;flags.var1.b=LoadMb(eaa);flags.result.b=0-flags.var1.b; - SaveMb(eaa,flags.result.b); - } - break; - } - case 0x04: /* MUL AL,Eb */ - RMEb(MULB); - break; - case 0x05: /* IMUL AL,Eb */ - RMEb(IMULB); - break; - case 0x06: /* DIV Eb */ - RMEb(DIVB); - break; - case 0x07: /* IDIV Eb */ - RMEb(IDIVB); - break; - } - break; - } - case 0xf7: /* GRP3 Ew(,Iw) */ - { GetRM; - switch ((rm & 0x38)>>3) { - case 0x00: /* TEST Ew,Iw */ - case 0x01: /* TEST Ew,Iw Undocumented*/ - { - if (rm >= 0xc0 ) {GetEArw;TESTW(*earw,Fetchw(),LoadRw,SaveRw);} - else {GetEAa;TESTW(eaa,Fetchw(),LoadMw,SaveMw);} - break; - } - case 0x02: /* NOT Ew */ - { - if (rm >= 0xc0 ) {GetEArw;*earw=~*earw;} - else {GetEAa;SaveMw(eaa,~LoadMw(eaa));} - break; - } - case 0x03: /* NEG Ew */ - { - flags.type=t_NEGw; - if (rm >= 0xc0 ) { - GetEArw;flags.var1.w=*earw;flags.result.w=0-flags.var1.w; - *earw=flags.result.w; - } else { - GetEAa;flags.var1.w=LoadMw(eaa);flags.result.w=0-flags.var1.w; - SaveMw(eaa,flags.result.w); - } - break; - } - case 0x04: /* MUL AX,Ew */ - RMEw(MULW); - break; - case 0x05: /* IMUL AX,Ew */ - RMEw(IMULW) - break; - case 0x06: /* DIV Ew */ - RMEw(DIVW) - break; - case 0x07: /* IDIV Ew */ - RMEw(IDIVW) - break; - } - break; - } - case 0xf8: /* CLC */ - SETFLAGBIT(CF,false); - if (flags.type!=t_CF) flags.prev_type=flags.type; - flags.type=t_CF; - break; - case 0xf9: /* STC */ - SETFLAGBIT(CF,true); - if (flags.type!=t_CF) flags.prev_type=flags.type; - flags.type=t_CF; - break; - case 0xfa: /* CLI */ - SETFLAGBIT(IF,false); - break; - case 0xfb: /* STI */ - SETFLAGBIT(IF,true); -#ifdef CPU_PIC_CHECK - if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; -#endif - break; - case 0xfc: /* CLD */ - SETFLAGBIT(DF,false); - break; - case 0xfd: /* STD */ - SETFLAGBIT(DF,true); - break; - case 0xfe: /* GRP4 Eb */ - { - GetRM; - switch (rm & 0x38) { - case 0x00: /* INC Eb */ - RMEb(INCB); - break; - case 0x08: /* DEC Eb */ - RMEb(DECB); - break; - case 0x38: /* CallBack */ - { - Bitu cb=Fetchw(); - LEAVECORE; - return cb; - } - - default: - E_Exit("Illegal GRP4 Call %d",(rm>>3) & 7); - break; - } - break; - } - case 0xff: /* GRP5 Ew */ - { - GetRM; - switch (rm & 0x38) { - case 0x00: /* INC Ew */ - RMEw(INCW); - break; - case 0x08: /* DEC Ew */ - RMEw(DECW); - break; - case 0x10: /* CALL Ev */ - if (rm >= 0xc0 ) {GetEArw;Push_16(GETIP);SETIP(*earw);} - else {GetEAa;Push_16(GETIP);SETIP(LoadMw(eaa));} - break; - case 0x18: /* CALL Ep */ - { - Push_16(SegValue(cs)); - GetEAa;Push_16(GETIP); - Bit16u newip=LoadMw(eaa); - Bit16u newcs=LoadMw(eaa+2); - SegSet16(cs,newcs); - SETIP(newip); - } - break; - case 0x20: /* JMP Ev */ - if (rm >= 0xc0 ) {GetEArw;SETIP(*earw);} - else {GetEAa;SETIP(LoadMw(eaa));} - break; - case 0x28: /* JMP Ep */ - { - GetEAa; - Bit16u newip=LoadMw(eaa); - Bit16u newcs=LoadMw(eaa+2); - SegSet16(cs,newcs); - SETIP(newip); - } - break; - case 0x30: /* PUSH Ev */ - if (rm >= 0xc0 ) {GetEArw;Push_16(*earw);} - else {GetEAa;Push_16(LoadMw(eaa));} - break; - default: - E_Exit("CPU:GRP5:Illegal Call %2X",rm & 0x38); - break; - } - break; - } - default: - NOTDONE; - break; - } - diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h deleted file mode 100644 index 47ee3d66..00000000 --- a/src/cpu/core_16/prefix_66.h +++ /dev/null @@ -1,490 +0,0 @@ -/* - * Copyright (C) 2002 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -restart_66: -switch(Fetchb()) { - case 0x01: /* ADD Ed,Gd */ - RMEdGd(ADDD);break; - case 0x03: /* ADD Gd,Ed */ - RMGdEd(ADDD);break; - case 0x05: /* ADD EAX,Id */ - EAXId(ADDD);break; - case 0x09: /* OR Ed,Gd */ - RMEdGd(ORD);break; - case 0x0b: /* OR Gd,Ed */ - RMGdEd(ORD);break; - case 0x0d: /* OR EAX,Id */ - EAXId(ORD);break; - case 0x0f: /* 2 Byte opcodes */ -#include "prefix_66_of.h" - break; - case 0x11: /* ADC Ed,Gd */ - RMEdGd(ADCD);break; - case 0x13: /* ADC Gd,Ed */ - RMGdEd(ADCD);break; - case 0x15: /* ADC EAX,Id */ - EAXId(ADCD);break; - case 0x19: /* SBB Ed,Gd */ - RMEdGd(SBBD);break; - case 0x1b: /* SBB Gd,Ed */ - RMGdEd(SBBD);break; - case 0x1d: /* SBB EAX,Id */ - EAXId(SBBD);break; - case 0x21: /* AND Ed,Gd */ - RMEdGd(ANDD);break; - case 0x23: /* AND Gd,Ed */ - RMGdEd(ANDD);break; - case 0x25: /* AND EAX,Id */ - EAXId(ANDD);break; - case 0x29: /* SUB Ed,Gd */ - RMEdGd(SUBD);break; - case 0x2b: /* SUB Gd,Ed */ - RMGdEd(SUBD);break; - case 0x2d: /* SUB EAX,Id */ - EAXId(SUBD);break; - case 0x31: /* XOR Ed,Gd */ - RMEdGd(XORD);break; - case 0x33: /* XOR Gd,Ed */ - RMGdEd(XORD);break; - case 0x35: /* XOR EAX,Id */ - EAXId(XORD);break; - case 0x39: /* CMP Ed,Gd */ - RMEdGd(CMPD);break; - case 0x3b: /* CMP Gd,Ed */ - RMGdEd(CMPD);break; - case 0x3d: /* CMP EAX,Id */ - EAXId(CMPD);break; - case 0x26: /* SEG ES: */ - SegPrefix_66(es);break; - case 0x2e: /* SEG CS: */ - SegPrefix_66(cs);break; - case 0x36: /* SEG SS: */ - SegPrefix_66(ss);break; - case 0x3e: /* SEG DS: */ - SegPrefix_66(ds);break; - case 0x40: /* INC EAX */ - INCD(reg_eax,LoadRd,SaveRd);break; - case 0x41: /* INC ECX */ - INCD(reg_ecx,LoadRd,SaveRd);break; - case 0x42: /* INC EDX */ - INCD(reg_edx,LoadRd,SaveRd);break; - case 0x43: /* INC EBX */ - INCD(reg_ebx,LoadRd,SaveRd);break; - case 0x44: /* INC ESP */ - INCD(reg_esp,LoadRd,SaveRd);break; - case 0x45: /* INC EBP */ - INCD(reg_ebp,LoadRd,SaveRd);break; - case 0x46: /* INC ESI */ - INCD(reg_esi,LoadRd,SaveRd);break; - case 0x47: /* INC EDI */ - INCD(reg_edi,LoadRd,SaveRd);break; - case 0x48: /* DEC EAX */ - DECD(reg_eax,LoadRd,SaveRd);break; - case 0x49: /* DEC ECX */ - DECD(reg_ecx,LoadRd,SaveRd);break; - case 0x4a: /* DEC EDX */ - DECD(reg_edx,LoadRd,SaveRd);break; - case 0x4b: /* DEC EBX */ - DECD(reg_ebx,LoadRd,SaveRd);break; - case 0x4c: /* DEC ESP */ - DECD(reg_esp,LoadRd,SaveRd);break; - case 0x4d: /* DEC EBP */ - DECD(reg_ebp,LoadRd,SaveRd);break; - case 0x4e: /* DEC ESI */ - DECD(reg_esi,LoadRd,SaveRd);break; - case 0x4f: /* DEC EDI */ - DECD(reg_edi,LoadRd,SaveRd);break; - case 0x50: /* PUSH EAX */ - Push_32(reg_eax);break; - case 0x51: /* PUSH ECX */ - Push_32(reg_ecx);break; - case 0x52: /* PUSH EDX */ - Push_32(reg_edx);break; - case 0x53: /* PUSH EBX */ - Push_32(reg_ebx);break; - case 0x54: /* PUSH ESP */ - Push_32(reg_esp);break; - case 0x55: /* PUSH EBP */ - Push_32(reg_ebp);break; - case 0x56: /* PUSH ESI */ - Push_32(reg_esi);break; - case 0x57: /* PUSH EDI */ - Push_32(reg_edi);break; - case 0x58: /* POP EAX */ - reg_eax=Pop_32();break; - case 0x59: /* POP ECX */ - reg_ecx=Pop_32();break; - case 0x5a: /* POP EDX */ - reg_edx=Pop_32();break; - case 0x5b: /* POP EBX */ - reg_ebx=Pop_32();break; - case 0x5c: /* POP ESP */ - reg_esp=Pop_32();break; - case 0x5d: /* POP EBP */ - reg_ebp=Pop_32();break; - case 0x5e: /* POP ESI */ - reg_esi=Pop_32();break; - case 0x5f: /* POP EDI */ - reg_edi=Pop_32();break; - case 0x60: /* PUSHAD */ - Push_32(reg_eax);Push_32(reg_ecx);Push_32(reg_edx);Push_32(reg_ebx); - Push_32(reg_esp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi); - break; - case 0x61: /* POPAD */ - reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP - reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32(); - break; - case 0x64: /* SEG FS: */ - SegPrefix_66(fs);break; - case 0x65: /* SEG GS: */ - SegPrefix_66(gs);break; - case 0x67: /* Address Size Prefix */ -#ifdef CPU_PREFIX_67 - core_16.prefixes^=PREFIX_ADDR; - lookupEATable=EAPrefixTable[core_16.prefixes]; - goto restart_66; -#else - NOTDONE; -#endif - case 0x68: /* PUSH Id */ - Push_32(Fetchd());break; - case 0x69: /* IMUL Gd,Ed,Id */ - RMGdEdOp3(DIMULD,Fetchds()); - break; - case 0x6a: /* PUSH Ib */ - Push_32(Fetchbs());break; - case 0x6b: /* IMUL Gd,Ed,Ib */ - RMGdEdOp3(DIMULD,Fetchbs()); - break; - case 0x81: /* Grpl Ed,Id */ - { - GetRM; - if (rm>= 0xc0) { - GetEArd;Bit32u id=Fetchd(); - switch (rm & 0x38) { - case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break; - case 0x08: ORD(*eard,id,LoadRd,SaveRd);break; - case 0x10:ADCD(*eard,id,LoadRd,SaveRd);break; - case 0x18:SBBD(*eard,id,LoadRd,SaveRd);break; - case 0x20:ANDD(*eard,id,LoadRd,SaveRd);break; - case 0x28:SUBD(*eard,id,LoadRd,SaveRd);break; - case 0x30:XORD(*eard,id,LoadRd,SaveRd);break; - case 0x38:CMPD(*eard,id,LoadRd,SaveRd);break; - } - } else { - GetEAa;Bit32u id=Fetchd(); - switch (rm & 0x38) { - case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break; - case 0x08: ORD(eaa,id,LoadMd,SaveMd);break; - case 0x10:ADCD(eaa,id,LoadMd,SaveMd);break; - case 0x18:SBBD(eaa,id,LoadMd,SaveMd);break; - case 0x20:ANDD(eaa,id,LoadMd,SaveMd);break; - case 0x28:SUBD(eaa,id,LoadMd,SaveMd);break; - case 0x30:XORD(eaa,id,LoadMd,SaveMd);break; - case 0x38:CMPD(eaa,id,LoadMd,SaveMd);break; - } - } - } - break; - case 0x83: /* Grpl Ed,Ix */ - { - GetRM; - if (rm>= 0xc0) { - GetEArd;Bit32u id=(Bit32s)Fetchbs(); - switch (rm & 0x38) { - case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break; - case 0x08: ORD(*eard,id,LoadRd,SaveRd);break; - case 0x10:ADCD(*eard,id,LoadRd,SaveRd);break; - case 0x18:SBBD(*eard,id,LoadRd,SaveRd);break; - case 0x20:ANDD(*eard,id,LoadRd,SaveRd);break; - case 0x28:SUBD(*eard,id,LoadRd,SaveRd);break; - case 0x30:XORD(*eard,id,LoadRd,SaveRd);break; - case 0x38:CMPD(*eard,id,LoadRd,SaveRd);break; - } - } else { - GetEAa;Bit32u id=(Bit32s)Fetchbs(); - switch (rm & 0x38) { - case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break; - case 0x08: ORD(eaa,id,LoadMd,SaveMd);break; - case 0x10:ADCD(eaa,id,LoadMd,SaveMd);break; - case 0x18:SBBD(eaa,id,LoadMd,SaveMd);break; - case 0x20:ANDD(eaa,id,LoadMd,SaveMd);break; - case 0x28:SUBD(eaa,id,LoadMd,SaveMd);break; - case 0x30:XORD(eaa,id,LoadMd,SaveMd);break; - case 0x38:CMPD(eaa,id,LoadMd,SaveMd);break; - } - } - } - break; - case 0x85: /* TEST Ed,Gd */ - RMEdGd(TESTD);break; - case 0x87: /* XCHG Ev,Gv */ - { - GetRMrd;Bit32u oldrmrd=*rmrd; - if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;*eard=oldrmrd;} - else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,oldrmrd);} - break; - } - case 0x89: /* MOV Ed,Gd */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArd;*eard=*rmrd;} - else {GetEAa;SaveMd(eaa,*rmrd);} - break; - } - case 0x8b: /* MOV Gd,Ed */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;} - else {GetEAa;*rmrd=LoadMd(eaa);} - break; - } - case 0x8c: - LOG(LOG_CPU,LOG_NORMAL)("CPU:66:8c looped back"); - break; - case 0x8d: /* LEA */ - { - core_16.segbase=0; - core_16.prefixes|=PREFIX_SEG; - lookupEATable=EAPrefixTable[core_16.prefixes]; - GetRMrd;GetEAa; - *rmrd=(Bit32u)eaa; - break; - } - case 0x8f: /* POP Ed */ - { - GetRM; - if (rm >= 0xc0 ) {GetEArd;*eard=Pop_32();} - else {GetEAa;SaveMd(eaa,Pop_32());} - break; - } - case 0x90: /* NOP */ - break; - case 0x91: /* XCHG ECX,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_ecx;reg_ecx=temp; } - break; - case 0x92: /* XCHG EDX,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_edx;reg_edx=temp; } - break; - case 0x93: /* XCHG EBX,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_ebx;reg_ebx=temp; } - break; - case 0x94: /* XCHG ESP,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_esp;reg_esp=temp; } - break; - case 0x95: /* XCHG EBP,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_ebp;reg_ebp=temp; } - break; - case 0x96: /* XCHG ESI,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_esi;reg_esi=temp; } - break; - case 0x97: /* XCHG EDI,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_edi;reg_edi=temp; } - break; - case 0x98: /* CWD */ - reg_eax=(Bit16s)reg_ax;break; - case 0x99: /* CDQ */ - if (reg_eax & 0x80000000) reg_edx=0xffffffff; - else reg_edx=0; - break; - case 0x9c: /* PUSHFD */ - FillFlags(); - Push_32(flags.word); - break; - case 0x9d: /* POPFD */ - SETFLAGSd(Pop_32()) - CheckTF(); -#ifdef CPU_PIC_CHECK - if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; -#endif - break; - case 0xa1: /* MOV EAX,Ow */ - reg_eax=LoadMd(GetEADirect[core_16.prefixes]()); - break; - case 0xa3: /* MOV Ow,EAX */ - SaveMd(GetEADirect[core_16.prefixes](),reg_eax); - break; - case 0xa5: /* MOVSD */ - { - stringSI;stringDI;SaveMd(to,LoadMd(from)); - if (GETFLAG(DF)) { reg_si-=4;reg_di-=4; } - else { reg_si+=4;reg_di+=4;} - } - break; - case 0xa7: /* CMPSD */ - { - stringSI;stringDI; CMPD(to,LoadMd(from),LoadMd,0); - if (GETFLAG(DF)) { reg_si-=4;reg_di-=4; } - else { reg_si+=4;reg_di+=4;} - } - break; - case 0xa9: /* TEST EAX,Id */ - EAXId(TESTD); - break; - case 0xab: /* STOSD */ - { - stringDI; - SaveMd(to,reg_eax); - if (GETFLAG(DF)) { reg_di-=4; } - else {reg_di+=4;} - break; - } - case 0xad: /* LODSD */ - { - stringSI; - reg_eax=LoadMd(from); - if (GETFLAG(DF)) { reg_si-=4;} - else {reg_si+=4;} - break; - } - case 0xaf: /* SCASD */ - { - stringDI; - CMPD(reg_eax,LoadMd(to),LoadRd,0); - if (GETFLAG(DF)) { reg_di-=4; } - else {reg_di+=4;} - break; - } - case 0xb8: /* MOV EAX,Id */ - reg_eax=Fetchd();break; - case 0xb9: /* MOV ECX,Id */ - reg_ecx=Fetchd();break; - case 0xba: /* MOV EDX,Iw */ - reg_edx=Fetchd();break; - case 0xbb: /* MOV EBX,Id */ - reg_ebx=Fetchd();break; - case 0xbc: /* MOV ESP,Id */ - reg_esp=Fetchd();break; - case 0xbd: /* MOV EBP.Id */ - reg_ebp=Fetchd();break; - case 0xbe: /* MOV ESI,Id */ - reg_esi=Fetchd();break; - case 0xbf: /* MOV EDI,Id */ - reg_edi=Fetchd();break; - case 0xc1: /* GRP2 Ed,Ib */ - GRP2D(Fetchb());break; - case 0xc4: /* LES */ - { - GetRMrd;GetEAa; - *rmrd=LoadMd(eaa);SegSet16(es,LoadMw(eaa+4)); - break; - } - case 0xc5: /* LDS */ - { - GetRMrd;GetEAa; - *rmrd=LoadMd(eaa);SegSet16(ds,LoadMw(eaa+4)); - break; - } - case 0xc7: /* MOV Ed,Id */ - { - GetRM; - if (rm>0xc0) {GetEArd;*eard=Fetchd();} - else {GetEAa;SaveMd(eaa,Fetchd());} - break; - } - case 0xd1: /* GRP2 Ed,1 */ - GRP2D(1);break; - case 0xd3: /* GRP2 Ed,CL */ - GRP2D(reg_cl);break; - case 0xed: /* IN EAX,DX */ - reg_eax=IO_Read(reg_dx) | - (IO_Read(reg_dx+1) << 8) | - (IO_Read(reg_dx+2) << 16) | - (IO_Read(reg_dx+3) << 24); - break; - case 0xef: /* OUT DX,EAX */ - IO_Write(reg_dx,(Bit8u)(reg_eax>>0)); - IO_Write(reg_dx+1,(Bit8u)(reg_eax>>8)); - IO_Write(reg_dx+2,(Bit8u)(reg_eax>>16)); - IO_Write(reg_dx+3,(Bit8u)(reg_eax>>24)); - break; - case 0xf2: /* REPNZ */ - Repeat_Normal(false,true); - continue; - case 0xf3: /* REPZ */ - Repeat_Normal(true,true); - continue; - case 0xf7: /* GRP3 Ed(,Id) */ - { - GetRM; - switch ((rm & 0x38)>>3) { - case 0x00: /* TEST Ed,Id */ - case 0x01: /* TEST Ed,Id Undocumented*/ - { - if (rm >= 0xc0 ) {GetEArd;TESTD(*eard,Fetchd(),LoadRd,SaveRd);} - else {GetEAa;TESTD(eaa,Fetchd(),LoadMd,SaveMd);} - break; - } - case 0x02: /* NOT Ed */ - { - if (rm >= 0xc0 ) {GetEArd;*eard=~*eard;} - else {GetEAa;SaveMd(eaa,~LoadMd(eaa));} - break; - } - case 0x03: /* NEG Ed */ - { - flags.type=t_NEGd; - if (rm >= 0xc0 ) { - GetEArd;flags.var1.d=*eard;flags.result.d=0-flags.var1.d; - *eard=flags.result.d; - } else { - GetEAa;flags.var1.d=LoadMd(eaa);flags.result.d=0-flags.var1.d; - SaveMd(eaa,flags.result.d); - } - break; - } - case 0x04: /* MUL EAX,Ed */ - RMEd(MULD); - break; - case 0x05: /* IMUL EAX,Ed */ - RMEd(IMULD); - break; - case 0x06: /* DIV Ed */ - RMEd(DIVD); - break; - case 0x07: /* IDIV Ed */ - RMEd(IDIVD); - break; - } - break; - } - case 0xff: /* Group 5 */ - { - GetRM; - switch (rm & 0x38) { - case 0x00: /* INC Ed */ - RMEd(INCD); - break; - case 0x08: /* DEC Ed */ - RMEd(DECD); - break; - case 0x30: /* Push Ed */ - if (rm >= 0xc0 ) {GetEArd;Push_32(*eard);} - else {GetEAa;Push_32(LoadMd(eaa));} - break; - default: - E_Exit("CPU:66:GRP5:Illegal call %2X",rm & 0x38); - break; - } - break; - } - default: - NOTDONE66; - } - - diff --git a/src/cpu/core_16/prefix_66_of.h b/src/cpu/core_16/prefix_66_of.h deleted file mode 100644 index 0738eda8..00000000 --- a/src/cpu/core_16/prefix_66_of.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (C) 2002 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -switch (Fetchb()) { - case 0x01: /* Group 7 Ed */ - { - GetRM;Bitu which=(rm>>3)&7; - if (rm < 0xc0) { //First ones all use EA - GetEAa;Bitu limit,base; - switch (which) { - case 0x00: /* SGDT */ - CPU_SGDT(limit,base); - SaveMw(eaa,limit); - SaveMd(eaa+2,base); - break; - case 0x01: /* SIDT */ - CPU_SIDT(limit,base); - SaveMw(eaa,limit); - SaveMd(eaa+2,base); - break; - case 0x02: /* LGDT */ - CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2)); - break; - case 0x03: /* LIDT */ - CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2)); - break; - case 0x04: /* SMSW */ - CPU_SMSW(limit); - SaveMw(eaa,limit); - break; - case 0x06: /* LMSW */ - limit=LoadMw(eaa); - if (!CPU_LMSW(limit)) goto decode_end; - break; - } - } else { - GetEArw;Bitu limit; - switch (which) { - case 0x04: /* SMSW */ - CPU_SMSW(limit); - *earw=limit; - break; - case 0x06: /* LMSW */ - if (!CPU_LMSW(*earw)) goto decode_end; - break; - default: - LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which); - break; - } - - } - } - break; - case 0xa4: /* SHLD Ed,Gd,Ib */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArd;DSHLD(*eard,*rmrd,Fetchb(),LoadRd,SaveRd);} - else {GetEAa;DSHLD(eaa,*rmrd,Fetchb(),LoadMd,SaveMd);} - break; - } - case 0xac: /* SHRD Ed,Gd,Ib */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArd;DSHRD(*eard,*rmrd,Fetchb(),LoadRd,SaveRd);} - else {GetEAa;DSHRD(eaa,*rmrd,Fetchb(),LoadMd,SaveMd);} - break; - } - case 0xad: /* SHRD Ed,Gd,Cl */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArd;DSHRD(*eard,*rmrd,reg_cl,LoadRd,SaveRd);} - else {GetEAa;DSHRD(eaa,*rmrd,reg_cl,LoadMd,SaveMd);} - break; - } - - case 0xb6: /* MOVZX Gd,Eb */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArb;*rmrd=*earb;} - else {GetEAa;*rmrd=LoadMb(eaa);} - break; - } - case 0xaf: /* IMUL Gd,Ed */ - { - RMGdEdOp3(DIMULD,*rmrd); - break; - }; - case 0xb7: /* MOVXZ Gd,Ew */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArw;*rmrd=*earw;} - else {GetEAa;*rmrd=LoadMw(eaa);} - break; - } - case 0xba: /* GRP8 Ed,Ib */ - { - GetRM; - if (rm >= 0xc0 ) { - GetEArd; - Bit32u mask=1 << (Fetchb() & 31); - SETFLAGBIT(CF,(*eard & mask)); - switch (rm & 0x38) { - case 0x20: /* BT */ - break; - case 0x28: /* BTS */ - *eard|=mask; - break; - case 0x30: /* BTR */ - *eard&=~mask; - break; - case 0x38: /* BTC */ - if (GETFLAG(CF)) *eard&=~mask; - else *eard|=mask; - break; - default: - E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38); - } - } else { - GetEAa;Bit32u old=LoadMd(eaa); - Bit32u mask=1 << (Fetchb() & 31); - SETFLAGBIT(CF,(old & mask)); - switch (rm & 0x38) { - case 0x20: /* BT */ - break; - case 0x28: /* BTS */ - SaveMd(eaa,old|mask); - break; - case 0x30: /* BTR */ - SaveMd(eaa,old & ~mask); - break; - case 0x38: /* BTC */ - if (GETFLAG(CF)) old&=~mask; - else old|=mask; - SaveMd(eaa,old); - break; - default: - E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38); - } - } - if (flags.type!=t_CF) flags.prev_type=flags.type; - flags.type=t_CF; - break; - } - case 0xbb: /* BTC Ed,Gd */ - { - GetRMrd; - Bit32u mask=1 << (*rmrd & 31); - if (rm >= 0xc0 ) { - GetEArd; - SETFLAGBIT(CF,(*eard & mask)); - *eard^=mask; - } else { - GetEAa;Bit32u old=LoadMd(eaa); - SETFLAGBIT(CF,(old & mask)); - SaveMd(eaa,old ^ mask); - } - if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } - break; - } - case 0xbc: /* BSF Gd,Ed */ - { - GetRMrd; - Bit32u result,value; - if (rm >= 0xc0) { GetEArd; value=*eard; } - else { GetEAa; value=LoadMd(eaa); } - if (value==0) { - SETFLAGBIT(ZF,true); - } else { - result = 0; - while ((value & 0x01)==0) { result++; value>>=1; } - SETFLAGBIT(ZF,false); - *rmrd = result; - } - flags.type=t_UNKNOWN; - break; - } - case 0xbd: /* BSR Gd,Ed */ - { - GetRMrd; - Bit32u result,value; - if (rm >= 0xc0) { GetEArd; value=*eard; } - else { GetEAa; value=LoadMd(eaa); } - if (value==0) { - SETFLAGBIT(ZF,true); - } else { - result = 35; // Operandsize-1 - while ((value & 0x80000000)==0) { result--; value<<=1; } - SETFLAGBIT(ZF,false); - *rmrd = result; - } - flags.type=t_UNKNOWN; - break; - } - case 0xbe: /* MOVSX Gd,Eb */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArb;*rmrd=*(Bit8s *)earb;} - else {GetEAa;*rmrd=LoadMbs(eaa);} - break; - } - case 0xbf: /* MOVSX Gd,Ew */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArw;*rmrd=*(Bit16s *)earw;} - else {GetEAa;*rmrd=LoadMws(eaa);} - break; - } - default: - SUBIP(1); - E_Exit("CPU:Opcode 66:0F:%2X Unhandled",Fetchb()); -} diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h deleted file mode 100644 index f28113c8..00000000 --- a/src/cpu/core_16/prefix_of.h +++ /dev/null @@ -1,425 +0,0 @@ -/* - * Copyright (C) 2002 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -switch(Fetchb()) { - case 0x00: /* GRP 6 */ - { - GetRM;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* SLDT */ - case 0x01: /* STR */ - { - Bitu saveval; - if (!which) CPU_SLDT(saveval); - else CPU_STR(saveval); - if (rm>0xc0) {GetEArw;*earw=saveval;} - else {GetEAa;SaveMw(eaa,saveval);} - } - break; - case 0x02:case 0x03:case 0x04:case 0x05: - { - Bitu loadval; - if (rm >= 0xc0 ) {GetEArw;loadval=*earw;} - else {GetEAa;loadval=LoadMw(eaa);} - break; - switch (which) { - case 0x02:CPU_LLDT(loadval);break; - case 0x03:CPU_LTR(loadval);break; - case 0x04:CPU_VERR(loadval);break; - case 0x05:CPU_VERW(loadval);break; - } - } - default: - LOG(LOG_CPU,LOG_ERROR)("GRP6:Illegal call %2X",which); - } - } - break; - case 0x01: /* Group 7 Ew */ - { - GetRM;Bitu which=(rm>>3)&7; - if (rm < 0xc0) { //First ones all use EA - GetEAa;Bitu limit,base; - switch (which) { - case 0x00: /* SGDT */ - CPU_SGDT(limit,base); - SaveMw(eaa,limit); - SaveMd(eaa+2,base); - break; - case 0x01: /* SIDT */ - CPU_SIDT(limit,base); - SaveMw(eaa,limit); - SaveMd(eaa+2,base); - break; - case 0x02: /* LGDT */ - CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF); - break; - case 0x03: /* LIDT */ - CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF); - break; - case 0x04: /* SMSW */ - CPU_SMSW(limit); - SaveMw(eaa,limit); - break; - case 0x06: /* LMSW */ - limit=LoadMw(eaa); - if (!CPU_LMSW(limit)) goto decode_end; - break; - } - } else { - GetEArw;Bitu limit; - switch (which) { - case 0x04: /* SMSW */ - CPU_SMSW(limit); - *earw=limit; - break; - case 0x06: /* LMSW */ - if (!CPU_LMSW(*earw)) goto decode_end; - break; - default: - LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which); - break; - } - } - } - break; - case 0x20: /* MOV Rd.CRx */ - { - GetRM; - Bitu which=(rm >> 3) & 7; - if (rm >= 0xc0 ) { - GetEArd; - *eard=CPU_GET_CRX(which); - } else { - GetEAa; - LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%d with non-register",which); - } - } - break; - case 0x22: /* MOV CRx,Rd */ - { - GetRM; - Bitu which=(rm >> 3) & 7; - if (rm >= 0xc0 ) { - GetEArd; - if (!CPU_SET_CRX(which,*eard)) goto decode_end; - } else { - GetEAa; - LOG(LOG_CPU,LOG_ERROR)("MOV CR%,XXX with non-register",which); - } - } - break; - case 0x23: /* MOV DRx,Rd */ - { - GetRM; - Bitu which=(rm >> 3) & 7; - if (rm >= 0xc0 ) { - GetEArd; - } else { - GetEAa; - LOG(LOG_CPU,LOG_ERROR)("MOV DR%,XXX with non-register",which); - } - } - break; - case 0x80: /* JO */ - JumpSIw(get_OF());break; - case 0x81: /* JNO */ - JumpSIw(!get_OF());break; - case 0x82: /* JB */ - JumpSIw(get_CF());break; - case 0x83: /* JNB */ - JumpSIw(!get_CF());break; - case 0x84: /* JZ */ - JumpSIw(get_ZF());break; - case 0x85: /* JNZ */ - JumpSIw(!get_ZF()); break; - case 0x86: /* JBE */ - JumpSIw(get_CF() || get_ZF());break; - case 0x87: /* JNBE */ - JumpSIw(!get_CF() && !get_ZF());break; - case 0x88: /* JS */ - JumpSIw(get_SF());break; - case 0x89: /* JNS */ - JumpSIw(!get_SF());break; - case 0x8a: /* JP */ - JumpSIw(get_PF());break; - case 0x8b: /* JNP */ - JumpSIw(!get_PF());break; - case 0x8c: /* JL */ - JumpSIw(get_SF() != get_OF());break; - case 0x8d: /* JNL */ - JumpSIw(get_SF() == get_OF());break; - case 0x8e: /* JLE */ - JumpSIw(get_ZF() || (get_SF() != get_OF()));break; - case 0x8f: /* JNLE */ - JumpSIw((get_SF() == get_OF()) && !get_ZF());break; - - case 0x90: /* SETO */ - SETcc(get_OF());break; - case 0x91: /* SETNO */ - SETcc(!get_OF());break; - case 0x92: /* SETB */ - SETcc(get_CF());break; - case 0x93: /* SETNB */ - SETcc(!get_CF());break; - case 0x94: /* SETZ */ - SETcc(get_ZF());break; - case 0x95: /* SETNZ */ - SETcc(!get_ZF()); break; - case 0x96: /* SETBE */ - SETcc(get_CF() || get_ZF());break; - case 0x97: /* SETNBE */ - SETcc(!get_CF() && !get_ZF());break; - case 0x98: /* SETS */ - SETcc(get_SF());break; - case 0x99: /* SETNS */ - SETcc(!get_SF());break; - case 0x9a: /* SETP */ - SETcc(get_PF());break; - case 0x9b: /* SETNP */ - SETcc(!get_PF());break; - case 0x9c: /* SETL */ - SETcc(get_SF() != get_OF());break; - case 0x9d: /* SETNL */ - SETcc(get_SF() == get_OF());break; - case 0x9e: /* SETLE */ - SETcc(get_ZF() || (get_SF() != get_OF()));break; - case 0x9f: /* SETNLE */ - SETcc((get_SF() == get_OF()) && !get_ZF());break; - - case 0xa0: /* PUSH FS */ - Push_16(SegValue(fs));break; - case 0xa1: /* POP FS */ - SegSet16(fs,Pop_16());break; - case 0xa2: - CPU_CPUID(); - break; - case 0xa3: /* BT Ew,Gw */ - { - GetRMrw; - Bit16u mask=1 << (*rmrw & 15); - if (rm >= 0xc0 ) { - GetEArw; - SETFLAGBIT(CF,(*earw & mask)); - } else { - GetEAa;Bit16u old=LoadMw(eaa); - SETFLAGBIT(CF,(old & mask)); - } - if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } - break; - } - case 0xa4: /* SHLD Ew,Gw,Ib */ - RMEwGwOp3(DSHLW,Fetchb()); - break; - case 0xa5: /* SHLD Ew,Gw,CL */ - RMEwGwOp3(DSHLW,reg_cl); - break; - case 0xa8: /* PUSH GS */ - Push_16(SegValue(gs));break; - case 0xa9: /* POP GS */ - SegSet16(gs,Pop_16());break; - case 0xab: /* BTS Ew,Gw */ - { - GetRMrw; - Bit16u mask=1 << (*rmrw & 15); - if (rm >= 0xc0 ) { - GetEArw; - SETFLAGBIT(CF,(*earw & mask)); - *earw|=mask; - } else { - GetEAa;Bit16u old=LoadMw(eaa); - SETFLAGBIT(CF,(old & mask)); - SaveMw(eaa,old | mask); - } - if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } - break; - } - case 0xac: /* SHRD Ew,Gw,Ib */ - RMEwGwOp3(DSHRW,Fetchb()); - break; - case 0xad: /* SHRD Ew,Gw,CL */ - RMEwGwOp3(DSHRW,reg_cl); - break; - case 0xaf: /* IMUL Gw,Ew */ - RMGwEwOp3(DIMULW,*rmrw); - break; - - case 0xb2: /* LSS */ - { - GetRMrw;GetEAa; - *rmrw=LoadMw(eaa);SegSet16(ss,LoadMw(eaa+2)); - CPU_Cycles++;//Be sure we run another instruction - break; - } - case 0xb3: /* BTR Ew,Gw */ - { - GetRMrw; - Bit16u mask=1 << (*rmrw & 15); - if (rm >= 0xc0 ) { - GetEArw; - SETFLAGBIT(CF,(*earw & mask)); - *earw&= ~mask; - } else { - GetEAa;Bit16u old=LoadMw(eaa); - SETFLAGBIT(CF,(old & mask)); - SaveMw(eaa,old & ~mask); - } - if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } - break; - } - case 0xb4: /* LFS */ - { - GetRMrw;GetEAa; - *rmrw=LoadMw(eaa);SegSet16(fs,LoadMw(eaa+2)); - break; - } - case 0xb5: /* LGS */ - { - GetRMrw;GetEAa; - *rmrw=LoadMw(eaa);SegSet16(gs,LoadMw(eaa+2)); - break; - } - case 0xb6: /* MOVZX Gw,Eb */ - { - GetRMrw; - if (rm >= 0xc0 ) {GetEArb;*rmrw=*earb;} - else {GetEAa;*rmrw=LoadMb(eaa);} - break; - } - case 0xb7: /* MOVZX Gw,Ew */ - case 0xbf: /* MOVSX Gw,Ew */ - { - GetRMrw; - if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;} - else {GetEAa;*rmrw=LoadMw(eaa);} - break; - } - case 0xba: /* GRP8 Ew,Ib */ - { - GetRM; - if (rm >= 0xc0 ) { - GetEArw; - Bit16u mask=1 << (Fetchb() & 15); - SETFLAGBIT(CF,(*earw & mask)); - switch (rm & 0x38) { - case 0x20: /* BT */ - break; - case 0x28: /* BTS */ - *earw|=mask; - break; - case 0x30: /* BTR */ - *earw&= ~mask; - break; - case 0x38: /* BTC */ - *earw^=mask; - break; - default: - E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38); - } - } else { - GetEAa;Bit16u old=LoadMw(eaa); - Bit16u mask=1 << (Fetchb() & 15); - SETFLAGBIT(CF,(old & mask)); - switch (rm & 0x38) { - case 0x20: /* BT */ - break; - case 0x28: /* BTS */ - SaveMw(eaa,old|mask); - break; - case 0x30: /* BTR */ - SaveMw(eaa,old & ~mask); - break; - case 0x38: /* BTC */ - SaveMw(eaa,old ^ mask); - break; - default: - E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38); - } - } - if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } - break; - } - case 0xbb: /* BTC Ew,Gw */ - { - GetRMrw; - Bit16u mask=1 << (*rmrw & 15); - if (rm >= 0xc0 ) { - GetEArw; - SETFLAGBIT(CF,(*earw & mask)); - *earw^=mask; - } else { - GetEAa;Bit16u old=LoadMw(eaa); - SETFLAGBIT(CF,(old & mask)); - SaveMw(eaa,old ^ mask); - } - if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } - break; - } - case 0xbc: /* 0xbc BSF Gw,Ew */ - { - GetRMrw; - Bit16u result,value; - if (rm >= 0xc0) { GetEArw; value=*earw; } - else { GetEAa; value=LoadMw(eaa); } - if (value==0) { - SETFLAGBIT(ZF,true); - } else { - result = 0; - while ((value & 0x01)==0) { result++; value>>=1; } - SETFLAGBIT(ZF,false); - *rmrw = result; - } - flags.type=t_UNKNOWN; - break; - } - case 0xbd: /* 0xbd BSR Gw,Ew */ - { - GetRMrw; - Bit16u result,value; - if (rm >= 0xc0) { GetEArw; value=*earw; } - else { GetEAa; value=LoadMw(eaa); } - if (value==0) { - SETFLAGBIT(ZF,true); - } else { - result = 15; // Operandsize-1 - while ((value & 0x8000)==0) { result--; value<<=1; } - SETFLAGBIT(ZF,false); - *rmrw = result; - } - flags.type=t_UNKNOWN; - break; - } - case 0xbe: /* MOVSX Gw,Eb */ - { - GetRMrw; - if (rm >= 0xc0 ) {GetEArb;*rmrw=*(Bit8s *)earb;} - else {GetEAa;*rmrw=LoadMbs(eaa);} - break; - } - case 0xc8: BSWAP(reg_eax); break; - case 0xc9: BSWAP(reg_ecx); break; - case 0xca: BSWAP(reg_edx); break; - case 0xcb: BSWAP(reg_ebx); break; - case 0xcc: BSWAP(reg_esp); break; - case 0xcd: BSWAP(reg_ebp); break; - case 0xce: BSWAP(reg_esi); break; - case 0xcf: BSWAP(reg_edi); break; - - default: - SUBIP(1); - E_Exit("CPU:Opcode 0F:%2X Unhandled",Fetchb()); - } diff --git a/src/cpu/core_16/support.h b/src/cpu/core_16/support.h deleted file mode 100644 index 8770a7de..00000000 --- a/src/cpu/core_16/support.h +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright (C) 2002 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#define SUBIP(a) core_16.ip_lookup-=a -#define SETIP(a) core_16.ip_lookup=SegBase(cs)+a -#define GETIP (Bit16u)(core_16.ip_lookup-SegBase(cs)) -#define SAVEIP reg_ip=GETIP -#define LOADIP core_16.ip_lookup=SegBase(cs)+reg_ip - -#define LEAVECORE \ - SAVEIP; \ - FillFlags(); - -static INLINE void ADDIP(Bit16u add) { - core_16.ip_lookup=SegBase(cs)+((Bit16u)(((Bit16u)(core_16.ip_lookup-SegBase(cs)))+(Bit16u)add)); -} - -static INLINE void ADDIPFAST(Bit16s blah) { - core_16.ip_lookup+=blah; -} - -#define CheckTF() \ - if (GETFLAG(TF)) { \ - cpudecoder=CPU_Real_16_Slow_Decode_Trap; \ - goto decode_end; \ - } - - -#define EXCEPTION(blah) \ - { \ - Bit8u new_num=blah; \ - core_16.ip_lookup=core_16.ip_start; \ - LEAVECORE; \ - if (Interrupt(new_num)) { \ - if (GETFLAG(TF)) { \ - cpudecoder=CPU_Real_16_Slow_Decode_Trap; \ - return CBRET_NONE; \ - } \ - goto decode_start; \ - } else return CBRET_NONE; \ - } - -static INLINE Bit8u Fetchb() { - Bit8u temp=LoadMb(core_16.ip_lookup); - core_16.ip_lookup+=1; - return temp; -} - -static INLINE Bit16u Fetchw() { - Bit16u temp=LoadMw(core_16.ip_lookup); - core_16.ip_lookup+=2; - return temp; -} -static INLINE Bit32u Fetchd() { - Bit32u temp=LoadMd(core_16.ip_lookup); - core_16.ip_lookup+=4; - return temp; -} - -static INLINE Bit8s Fetchbs() { - return Fetchb(); -} -static INLINE Bit16s Fetchws() { - return Fetchw(); -} - -static INLINE Bit32s Fetchds() { - return Fetchd(); -} - -static INLINE void Push_16(Bit16u blah) { - reg_sp-=2; - SaveMw(SegBase(ss)+reg_sp,blah); -}; - -static INLINE void Push_32(Bit32u blah) { - reg_sp-=4; - SaveMd(SegBase(ss)+reg_sp,blah); -}; - -static INLINE Bit16u Pop_16() { - Bit16u temp=LoadMw(SegBase(ss)+reg_sp); - reg_sp+=2; - return temp; -}; - -static INLINE Bit32u Pop_32() { - Bit32u temp=LoadMd(SegBase(ss)+reg_sp); - reg_sp+=4; - return temp; -}; - -#define JumpSIb(blah) \ - if (blah) { \ - ADDIPFAST(Fetchbs()); \ - } else { \ - ADDIPFAST(1); \ - } - -#define JumpSIw(blah) \ - if (blah) { \ - ADDIPFAST(Fetchws()); \ - } else { \ - ADDIPFAST(2); \ - } - -#define SETcc(cc) \ - { \ - GetRM; \ - if (rm >= 0xc0 ) {GetEArb;*earb=(cc) ? 1 : 0;} \ - else {GetEAa;SaveMb(eaa,(cc) ? 1 : 0);} \ - } - -#define NOTDONE \ - SUBIP(1);E_Exit("CPU:Opcode %2X Unhandled",Fetchb()); - -#define NOTDONE66 \ - SUBIP(1);E_Exit("CPU:Opcode 66:%2X Unhandled",Fetchb()); - - -#define stringDI \ - PhysPt to; \ - to=SegBase(es)+reg_di - -#define stringSI \ - PhysPt from; \ - if (core_16.prefixes & PREFIX_SEG) { \ - from=(core_16.segbase+reg_si); \ - } else { \ - from=SegBase(ds)+reg_si; \ - } - -#include "helpers.h" -#include "table_ea.h" -#include "../modrm.h" - -static void Repeat_Normal(bool testz,bool prefix_66) { - - PhysPt base_si,base_di; - - Bit16s direct; - if (GETFLAG(DF)) direct=-1; - else direct=1; - base_di=SegBase(es); - if (core_16.prefixes & PREFIX_ADDR) E_Exit("Unhandled 0x67 prefixed string op"); -rep_again: - if (core_16.prefixes & PREFIX_SEG) { - base_si=(core_16.segbase); - } else { - base_si=SegBase(ds); - } - switch (Fetchb()) { - case 0x26: /* ES Prefix */ - core_16.segbase=SegBase(es); - core_16.prefixes|=PREFIX_SEG; - goto rep_again; - case 0x2e: /* CS Prefix */ - core_16.segbase=SegBase(cs); - core_16.prefixes|=PREFIX_SEG; - goto rep_again; - case 0x36: /* SS Prefix */ - core_16.segbase=SegBase(ss); - core_16.prefixes|=PREFIX_SEG; - goto rep_again; - case 0x3e: /* DS Prefix */ - core_16.segbase=SegBase(ds); - core_16.prefixes|=PREFIX_SEG; - goto rep_again; - case 0x64: /* FS Prefix */ - core_16.segbase=SegBase(fs); - core_16.prefixes|=PREFIX_SEG; - goto rep_again; - case 0x65: /* GS Prefix */ - core_16.segbase=SegBase(gs); - core_16.prefixes|=PREFIX_SEG; - goto rep_again; - case 0x66: /* Size Prefix */ - prefix_66=!prefix_66; - goto rep_again; - case 0x6c: /* REP INSB */ - for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) goto normalexit; reg_cx--; - SaveMb(base_di+reg_di,IO_Read(reg_dx)); - reg_di+=direct; - } - break; - case 0x6d: /* REP INSW/D */ - if (prefix_66) { - direct*=4; - for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) goto normalexit; reg_cx--; - SaveMb(base_di+reg_di+0,IO_Read(reg_dx+0)); - SaveMb(base_di+reg_di+1,IO_Read(reg_dx+1)); - SaveMb(base_di+reg_di+2,IO_Read(reg_dx+2)); - SaveMb(base_di+reg_di+3,IO_Read(reg_dx+3)); - reg_di+=direct; - } - } else { - direct*=2; - for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) goto normalexit; reg_cx--; - SaveMb(base_di+reg_di+0,IO_Read(reg_dx+0)); - SaveMb(base_di+reg_di+1,IO_Read(reg_dx+1)); - reg_di+=direct; - } - } - break; - case 0x6e: /* REP OUTSB */ - for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) goto normalexit; reg_cx--; - IO_Write(reg_dx,LoadMb(base_si+reg_si)); - reg_si+=direct; - } - break; - case 0x6f: /* REP OUTSW/D */ - if (prefix_66) { - direct*=4; - for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) goto normalexit; reg_cx--; - IO_Write(reg_dx+0,LoadMb(base_si+reg_si+0)); - IO_Write(reg_dx+1,LoadMb(base_si+reg_si+1)); - IO_Write(reg_dx+2,LoadMb(base_si+reg_si+2)); - IO_Write(reg_dx+3,LoadMb(base_si+reg_si+3)); - reg_si+=direct; - } - } else { - direct*=2; - for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) goto normalexit; reg_cx--; - IO_Write(reg_dx+0,LoadMb(base_si+reg_si+0)); - IO_Write(reg_dx+1,LoadMb(base_si+reg_si+1)); - reg_si+=direct; - } - } - break; - case 0xa4: /* REP MOVSB */ - for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) goto normalexit; reg_cx--; - SaveMb(base_di+reg_di,LoadMb(base_si+reg_si)); - reg_si+=direct;reg_di+=direct; - } - break; - case 0xa5: /* REP MOVSW/D */ - if (prefix_66) { - direct*=4; - for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) goto normalexit; reg_cx--; - SaveMd(base_di+reg_di,LoadMd(base_si+reg_si)); - reg_si+=direct;reg_di+=direct; - } - } else { - direct*=2; - for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) goto normalexit; reg_cx--; - SaveMw(base_di+reg_di,LoadMw(base_si+reg_si)); - reg_si+=direct;reg_di+=direct; - } - } - break; - case 0xa6: /* REP CMPSB */ - { - Bit8u op1,op2; - if (!reg_cx) { CPU_Cycles--;goto normalexit; } - for (;CPU_Cycles>0;CPU_Cycles--) { - op1=LoadMb(base_si+reg_si);op2=LoadMb(base_di+reg_di); - reg_cx--;reg_si+=direct;reg_di+=direct; - if ((op1==op2)!=testz || !reg_cx) { CMPB(op1,op2,LoadRb,0);goto normalexit; } - } - CMPB(op1,op2,LoadRb,0); - } - break; - case 0xa7: /* REP CMPSW */ - { - if (!reg_cx) { CPU_Cycles--;goto normalexit; } - if (prefix_66) { - direct*=4;Bit32u op1,op2; - for (;CPU_Cycles>0;CPU_Cycles--) { - op1=LoadMd(base_si+reg_si);op2=LoadMd(base_di+reg_di); - reg_cx--;reg_si+=direct;reg_di+=direct; - if ((op1==op2)!=testz || !reg_cx) { CMPD(op1,op2,LoadRd,0);goto normalexit; } - } - CMPD(op1,op2,LoadRd,0); - } else { - direct*=2;Bit16u op1,op2; - for (;CPU_Cycles>0;CPU_Cycles--) { - op1=LoadMw(base_si+reg_si);op2=LoadMw(base_di+reg_di); - reg_cx--,reg_si+=direct;reg_di+=direct; - if ((op1==op2)!=testz || !reg_cx) { CMPW(op1,op2,LoadRw,0);goto normalexit; } - } - CMPW(op1,op2,LoadRw,0); - } - } - break; - case 0xaa: /* REP STOSB */ - for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) goto normalexit; reg_cx--; - SaveMb(base_di+reg_di,reg_al); - reg_di+=direct; - } - break; - case 0xab: /* REP STOSW */ - if (prefix_66) { - direct*=4; - for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) goto normalexit; reg_cx--; - SaveMd(base_di+reg_di,reg_eax); - reg_di+=direct; - } - } else { - direct*=2; - for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) goto normalexit; reg_cx--; - SaveMw(base_di+reg_di,reg_ax); - reg_di+=direct; - } - } - break; - case 0xac: /* REP LODSB */ - for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) goto normalexit; reg_cx--; - reg_al=LoadMb(base_si+reg_si); - reg_si+=direct; - } - break; - case 0xad: /* REP LODSW */ - if (prefix_66) { - direct*=4; - for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) goto normalexit; reg_cx--; - reg_eax=LoadMd(base_si+reg_si); - reg_si+=direct; - } - } else { - direct*=2; - for (;CPU_Cycles>0;CPU_Cycles--) { - if (!reg_cx) goto normalexit; reg_cx--; - reg_ax=LoadMw(base_si+reg_si); - reg_si+=direct; - } - } - break; - case 0xae: /* REP SCASB */ - { - Bit8u op2; - if (!reg_cx) { CPU_Cycles--;goto normalexit; } - for (;CPU_Cycles>0;CPU_Cycles--) { - op2=LoadMb(base_di+reg_di); - reg_cx--;reg_di+=direct; - if ((reg_al==op2)!=testz || !reg_cx) { CMPB(reg_al,op2,LoadRb,0);goto normalexit; } - } - CMPB(reg_al,op2,LoadRb,0); - } - break; - case 0xaf: /* REP SCASW */ - { - if (!reg_cx) { CPU_Cycles--;goto normalexit; } - if (prefix_66) { - direct*=4;Bit32u op2; - for (;CPU_Cycles>0;CPU_Cycles--) { - op2=LoadMd(base_di+reg_di); - reg_cx--;reg_di+=direct; - if ((reg_eax==op2)!=testz || !reg_cx) { CMPD(reg_eax,op2,LoadRd,0);goto normalexit; } - } - CMPD(reg_eax,op2,LoadRd,0); - } else { - direct*=2;Bit16u op2; - for (;CPU_Cycles>0;CPU_Cycles--) { - op2=LoadMw(base_di+reg_di); - reg_cx--;reg_di+=direct; - if ((reg_ax==op2)!=testz || !reg_cx) { CMPW(reg_ax,op2,LoadRw,0);goto normalexit; } - } - CMPW(reg_ax,op2,LoadRw,0); - } - } - break; - default: - core_16.ip_lookup--; - LOG(LOG_CPU,LOG_ERROR)("Unhandled REP Prefix %X",Fetchb()); - goto normalexit; - } - /* If we end up here it's because the CPU_Cycles counter is 0, so restart instruction */ - core_16.ip_lookup=core_16.ip_start; -normalexit:; -} - diff --git a/src/cpu/core_16/table_ea.h b/src/cpu/core_16/table_ea.h deleted file mode 100644 index cf7131fd..00000000 --- a/src/cpu/core_16/table_ea.h +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (C) 2002 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* Some variables for EA Loolkup */ - -typedef PhysPt (*GetEATable[256])(void); -typedef PhysPt (*EA_LookupHandler)(void); - -static GetEATable * lookupEATable; - -#define PREFIX_NONE 0x0 -#define PREFIX_SEG 0x1 -#define PREFIX_ADDR 0x2 -#define PREFIX_SEG_ADDR 0x3 - - -/* Gets initialized at the bottem, can't seem to declare forward references */ -static GetEATable * EAPrefixTable[4]; - - -#define SegPrefix(blah) \ - core_16.segbase=SegBase(blah); \ - core_16.prefixes|=PREFIX_SEG; \ - lookupEATable=EAPrefixTable[core_16.prefixes]; \ - goto restart; - -#define SegPrefix_66(blah) \ - core_16.segbase=SegBase(blah); \ - core_16.prefixes|=PREFIX_SEG; \ - lookupEATable=EAPrefixTable[core_16.prefixes]; \ - goto restart_66; - - -/* The MOD/RM Decoder for EA for this decoder's addressing modes */ -static PhysPt EA_16_00_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si); } -static PhysPt EA_16_01_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di); } -static PhysPt EA_16_02_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si); } -static PhysPt EA_16_03_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di); } -static PhysPt EA_16_04_n(void) { return SegBase(ds)+(Bit16u)(reg_si); } -static PhysPt EA_16_05_n(void) { return SegBase(ds)+(Bit16u)(reg_di); } -static PhysPt EA_16_06_n(void) { return SegBase(ds)+(Bit16u)(Fetchw());} -static PhysPt EA_16_07_n(void) { return SegBase(ds)+(Bit16u)(reg_bx); } - -static PhysPt EA_16_40_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); } -static PhysPt EA_16_41_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); } -static PhysPt EA_16_42_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); } -static PhysPt EA_16_43_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); } -static PhysPt EA_16_44_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchbs()); } -static PhysPt EA_16_45_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchbs()); } -static PhysPt EA_16_46_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchbs()); } -static PhysPt EA_16_47_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchbs()); } - -static PhysPt EA_16_80_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); } -static PhysPt EA_16_81_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); } -static PhysPt EA_16_82_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); } -static PhysPt EA_16_83_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); } -static PhysPt EA_16_84_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchws()); } -static PhysPt EA_16_85_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchws()); } -static PhysPt EA_16_86_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchws()); } -static PhysPt EA_16_87_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchws()); } - -static GetEATable GetEA_16_n={ -/* 00 */ - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, -/* 01 */ - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, -/* 10 */ - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, -/* 11 These are illegal so make em 0 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - - - -static PhysPt EA_16_00_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_si); } -static PhysPt EA_16_01_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_di); } -static PhysPt EA_16_02_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_si); } -static PhysPt EA_16_03_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_di); } -static PhysPt EA_16_04_s(void) { return core_16.segbase+(Bit16u)(reg_si); } -static PhysPt EA_16_05_s(void) { return core_16.segbase+(Bit16u)(reg_di); } -static PhysPt EA_16_06_s(void) { return core_16.segbase+(Bit16u)(Fetchw()); } -static PhysPt EA_16_07_s(void) { return core_16.segbase+(Bit16u)(reg_bx); } - -static PhysPt EA_16_40_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); } -static PhysPt EA_16_41_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); } -static PhysPt EA_16_42_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); } -static PhysPt EA_16_43_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); } -static PhysPt EA_16_44_s(void) { return core_16.segbase+(Bit16u)(reg_si+Fetchbs()); } -static PhysPt EA_16_45_s(void) { return core_16.segbase+(Bit16u)(reg_di+Fetchbs()); } -static PhysPt EA_16_46_s(void) { return core_16.segbase+(Bit16u)(reg_bp+Fetchbs()); } -static PhysPt EA_16_47_s(void) { return core_16.segbase+(Bit16u)(reg_bx+Fetchbs()); } - -static PhysPt EA_16_80_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); } -static PhysPt EA_16_81_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); } -static PhysPt EA_16_82_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); } -static PhysPt EA_16_83_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); } -static PhysPt EA_16_84_s(void) { return core_16.segbase+(Bit16u)(reg_si+Fetchws()); } -static PhysPt EA_16_85_s(void) { return core_16.segbase+(Bit16u)(reg_di+Fetchws()); } -static PhysPt EA_16_86_s(void) { return core_16.segbase+(Bit16u)(reg_bp+Fetchws()); } -static PhysPt EA_16_87_s(void) { return core_16.segbase+(Bit16u)(reg_bx+Fetchws()); } - -static GetEATable GetEA_16_s={ -/* 00 */ - EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, - EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, - EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, - EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, - EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, - EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, - EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, - EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, -/* 01 */ - EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, - EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, - EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, - EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, - EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, - EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, - EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, - EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, -/* 10 */ - EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, - EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, - EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, - EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, - EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, - EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, - EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, - EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, -/* 11 These are illegal so make em 0 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static Bit32u SIBZero=0; -static Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi }; - -INLINE PhysPt Sib(Bitu mode) { - Bit8u sib=Fetchb(); - PhysPt base; - switch (sib&7) { - case 0: /* EAX Base */ - base=SegBase(ds)+reg_eax;break; - case 1: /* ECX Base */ - base=SegBase(ds)+reg_ecx;break; - case 2: /* EDX Base */ - base=SegBase(ds)+reg_edx;break; - case 3: /* EBX Base */ - base=SegBase(ds)+reg_ebx;break; - case 4: /* ESP Base */ - base=SegBase(ss)+reg_esp;break; - case 5: /* #1 Base */ - if (!mode) { - base=SegBase(ds)+Fetchd();break; - } else { - base=SegBase(ss)+reg_ebp;break; - } - case 6: /* ESI Base */ - base=SegBase(ds)+reg_esi;break; - case 7: /* EDI Base */ - base=SegBase(ds)+reg_edi;break; - } - base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6); - return base; -}; - - -static PhysPt EA_32_00_n(void) { return SegBase(ds)+reg_eax; } -static PhysPt EA_32_01_n(void) { return SegBase(ds)+reg_ecx; } -static PhysPt EA_32_02_n(void) { return SegBase(ds)+reg_edx; } -static PhysPt EA_32_03_n(void) { return SegBase(ds)+reg_ebx; } -static PhysPt EA_32_04_n(void) { return Sib(0);} -static PhysPt EA_32_05_n(void) { return SegBase(ds)+Fetchd(); } -static PhysPt EA_32_06_n(void) { return SegBase(ds)+reg_esi; } -static PhysPt EA_32_07_n(void) { return SegBase(ds)+reg_edi; } - -static PhysPt EA_32_40_n(void) { return SegBase(ds)+reg_eax+Fetchbs(); } -static PhysPt EA_32_41_n(void) { return SegBase(ds)+reg_ecx+Fetchbs(); } -static PhysPt EA_32_42_n(void) { return SegBase(ds)+reg_edx+Fetchbs(); } -static PhysPt EA_32_43_n(void) { return SegBase(ds)+reg_ebx+Fetchbs(); } -static PhysPt EA_32_44_n(void) { PhysPt temp=Sib(1);return temp+Fetchbs();} -static PhysPt EA_32_45_n(void) { return SegBase(ss)+reg_ebp+Fetchbs(); } -static PhysPt EA_32_46_n(void) { return SegBase(ds)+reg_esi+Fetchbs(); } -static PhysPt EA_32_47_n(void) { return SegBase(ds)+reg_edi+Fetchbs(); } - -static PhysPt EA_32_80_n(void) { return SegBase(ds)+reg_eax+Fetchds(); } -static PhysPt EA_32_81_n(void) { return SegBase(ds)+reg_ecx+Fetchds(); } -static PhysPt EA_32_82_n(void) { return SegBase(ds)+reg_edx+Fetchds(); } -static PhysPt EA_32_83_n(void) { return SegBase(ds)+reg_ebx+Fetchds(); } -static PhysPt EA_32_84_n(void) { PhysPt temp=Sib(2);return temp+Fetchds();} -static PhysPt EA_32_85_n(void) { return SegBase(ss)+reg_ebp+Fetchds(); } -static PhysPt EA_32_86_n(void) { return SegBase(ds)+reg_esi+Fetchds(); } -static PhysPt EA_32_87_n(void) { return SegBase(ds)+reg_edi+Fetchds(); } - -static GetEATable GetEA_32_n={ -/* 00 */ - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, -/* 01 */ - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, -/* 10 */ - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, -/* 11 These are illegal so make em 0 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -INLINE PhysPt Sib_s(Bitu mode) { - Bit8u sib=Fetchb(); - PhysPt base; - switch (sib&7) { - case 0: /* EAX Base */ - base=reg_eax;break; - case 1: /* ECX Base */ - base=reg_ecx;break; - case 2: /* EDX Base */ - base=reg_edx;break; - case 3: /* EBX Base */ - base=reg_ebx;break; - case 4: /* ESP Base */ - base=reg_esp;break; - case 5: /* #1 Base */ - if (!mode) { - base=Fetchd();break; - } else { - base=reg_ebp;break; - } - case 6: /* ESI Base */ - base=reg_esi;break; - case 7: /* EDI Base */ - base=reg_edi;break; - } - base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6); - return base; -}; - - -static PhysPt EA_32_00_s(void) { return core_16.segbase+(Bit32u)(reg_eax); } -static PhysPt EA_32_01_s(void) { return core_16.segbase+(Bit32u)(reg_ecx); } -static PhysPt EA_32_02_s(void) { return core_16.segbase+(Bit32u)(reg_edx); } -static PhysPt EA_32_03_s(void) { return core_16.segbase+(Bit32u)(reg_ebx); } -static PhysPt EA_32_04_s(void) { return core_16.segbase+(Bit32u)(Sib_s(0));} -static PhysPt EA_32_05_s(void) { return core_16.segbase+(Bit32u)(Fetchd()); } -static PhysPt EA_32_06_s(void) { return core_16.segbase+(Bit32u)(reg_esi); } -static PhysPt EA_32_07_s(void) { return core_16.segbase+(Bit32u)(reg_edi); } - -static PhysPt EA_32_40_s(void) { return core_16.segbase+(Bit32u)(reg_eax+Fetchbs()); } -static PhysPt EA_32_41_s(void) { return core_16.segbase+(Bit32u)(reg_ecx+Fetchbs()); } -static PhysPt EA_32_42_s(void) { return core_16.segbase+(Bit32u)(reg_edx+Fetchbs()); } -static PhysPt EA_32_43_s(void) { return core_16.segbase+(Bit32u)(reg_ebx+Fetchbs()); } -static PhysPt EA_32_44_s(void) { return core_16.segbase+(Bit32u)(Sib_s(1)+Fetchbs());} -static PhysPt EA_32_45_s(void) { return core_16.segbase+(Bit32u)(reg_ebp+Fetchbs()); } -static PhysPt EA_32_46_s(void) { return core_16.segbase+(Bit32u)(reg_esi+Fetchbs()); } -static PhysPt EA_32_47_s(void) { return core_16.segbase+(Bit32u)(reg_edi+Fetchbs()); } - -static PhysPt EA_32_80_s(void) { return core_16.segbase+(Bit32u)(reg_eax+Fetchds()); } -static PhysPt EA_32_81_s(void) { return core_16.segbase+(Bit32u)(reg_ecx+Fetchds()); } -static PhysPt EA_32_82_s(void) { return core_16.segbase+(Bit32u)(reg_edx+Fetchds()); } -static PhysPt EA_32_83_s(void) { return core_16.segbase+(Bit32u)(reg_ebx+Fetchds()); } -static PhysPt EA_32_84_s(void) { return core_16.segbase+(Bit32u)(Sib_s(2)+Fetchds());} -static PhysPt EA_32_85_s(void) { return core_16.segbase+(Bit32u)(reg_ebp+Fetchds()); } -static PhysPt EA_32_86_s(void) { return core_16.segbase+(Bit32u)(reg_esi+Fetchds()); } -static PhysPt EA_32_87_s(void) { return core_16.segbase+(Bit32u)(reg_edi+Fetchds()); } - - -static GetEATable GetEA_32_s={ -/* 00 */ - EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, - EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, - EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, - EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, - EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, - EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, - EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, - EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, -/* 01 */ - EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, - EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, - EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, - EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, - EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, - EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, - EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, - EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, -/* 10 */ - EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, - EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, - EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, - EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, - EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, - EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, - EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, - EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, -/* 11 These are illegal so make em 0 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static PhysPt GetEADirect_NONE(void) { - PhysPt result=SegBase(ds)+Fetchw(); - return result; -} -static PhysPt GetEADirect_SEG(void) { - PhysPt result=core_16.segbase+Fetchw(); - return result; -} -static PhysPt GetEADirect_ADDR(void) { - PhysPt result=SegBase(ds)+Fetchd(); - return result; -} -static PhysPt GetEADirect_SEG_ADDR(void) { - PhysPt result=core_16.segbase+Fetchd(); - return result; -} - -static EA_LookupHandler GetEADirect[4]={GetEADirect_NONE,GetEADirect_SEG,GetEADirect_ADDR,GetEADirect_SEG_ADDR}; diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index dcaf00d4..803457c4 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -47,6 +47,8 @@ typedef PhysPt EAPoint; #define LoadD(reg) reg #define SaveD(reg,val) reg=val + + #include "core_full/loadwrite.h" #include "core_full/support.h" #include "core_full/optable.h" @@ -77,7 +79,7 @@ Bits Full_DeCode(void) { } EAPoint IPPoint; LoadIP(); - flags.type=t_UNKNOWN; + lflags.type=t_UNKNOWN; while (CPU_Cycles>0) { #if C_DEBUG cycle_count++; diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index b0adcce4..6fd52404 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -225,7 +225,7 @@ l_M_Ed: break; case L_FLG: FillFlags(); - inst.op1.d = flags.word; + inst.op1.d = reg_flags; break; case L_SEG: inst.op1.d=SegValue((SegNames)inst.code.extra); @@ -273,7 +273,7 @@ l_M_Ed: inst.op1.d=4; break; case D_IRETw: - flags.type=t_UNKNOWN; + lflags.type=t_UNKNOWN; if (!CPU_IRET(false)) return CBRET_NONE; if (GETFLAG(IF) && PIC_IRQCheck) { return CBRET_NONE; @@ -281,7 +281,7 @@ l_M_Ed: LoadIP(); goto nextopcode; case D_IRETd: - flags.type=t_UNKNOWN; + lflags.type=t_UNKNOWN; if (!CPU_IRET(true)) return CBRET_NONE; if (GETFLAG(IF) && PIC_IRQCheck) { return CBRET_NONE; @@ -379,18 +379,15 @@ l_M_Ed: goto nextopcode; case D_STC: SETFLAGBIT(CF,true); - if (flags.type!=t_CF) flags.prev_type=flags.type; - flags.type=t_CF; + SetTypeCF(); goto nextopcode; case D_CLC: SETFLAGBIT(CF,false); - if (flags.type!=t_CF) flags.prev_type=flags.type; - flags.type=t_CF; + SetTypeCF(); goto nextopcode; case D_CMC: SETFLAGBIT(CF,!get_CF()); - if (flags.type!=t_CF) flags.prev_type=flags.type; - flags.type=t_CF; + SetTypeCF(); goto nextopcode; case D_CLD: SETFLAGBIT(DF,false); diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 3a5e4200..84bccea9 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -1,60 +1,60 @@ /* Do the actual opcode */ switch (inst.code.op) { case t_ADDb: case t_ADDw: case t_ADDd: - flags.var1.d=inst.op1.d; - flags.var2.d=inst.op2.d; - inst.op1.d=flags.result.d=flags.var1.d + flags.var2.d; - flags.type=inst.code.op; + lf_var1d=inst.op1.d; + lf_var2d=inst.op2.d; + inst.op1.d=lf_resd=lf_var1d + lf_var2d; + lflags.type=inst.code.op; break; case t_CMPb: case t_CMPw: case t_CMPd: case t_SUBb: case t_SUBw: case t_SUBd: - flags.var1.d=inst.op1.d; - flags.var2.d=inst.op2.d; - inst.op1.d=flags.result.d=flags.var1.d - flags.var2.d; - flags.type=inst.code.op; + lf_var1d=inst.op1.d; + lf_var2d=inst.op2.d; + inst.op1.d=lf_resd=lf_var1d - lf_var2d; + lflags.type=inst.code.op; break; case t_ORb: case t_ORw: case t_ORd: - flags.var1.d=inst.op1.d; - flags.var2.d=inst.op2.d; - inst.op1.d=flags.result.d=flags.var1.d | flags.var2.d; - flags.type=inst.code.op; + lf_var1d=inst.op1.d; + lf_var2d=inst.op2.d; + inst.op1.d=lf_resd=lf_var1d | lf_var2d; + lflags.type=inst.code.op; break; case t_XORb: case t_XORw: case t_XORd: - flags.var1.d=inst.op1.d; - flags.var2.d=inst.op2.d; - inst.op1.d=flags.result.d=flags.var1.d ^ flags.var2.d; - flags.type=inst.code.op; + lf_var1d=inst.op1.d; + lf_var2d=inst.op2.d; + inst.op1.d=lf_resd=lf_var1d ^ lf_var2d; + lflags.type=inst.code.op; break; case t_TESTb: case t_TESTw: case t_TESTd: case t_ANDb: case t_ANDw: case t_ANDd: - flags.var1.d=inst.op1.d; - flags.var2.d=inst.op2.d; - inst.op1.d=flags.result.d=flags.var1.d & flags.var2.d; - flags.type=inst.code.op; + lf_var1d=inst.op1.d; + lf_var2d=inst.op2.d; + inst.op1.d=lf_resd=lf_var1d & lf_var2d; + lflags.type=inst.code.op; break; case t_ADCb: case t_ADCw: case t_ADCd: - flags.oldcf=get_CF(); - flags.var1.d=inst.op1.d; - flags.var2.d=inst.op2.d; - inst.op1.d=flags.result.d=flags.var1.d + flags.var2.d + flags.oldcf; - flags.type=inst.code.op; + lflags.oldcf=get_CF(); + lf_var1d=inst.op1.d; + lf_var2d=inst.op2.d; + inst.op1.d=lf_resd=lf_var1d + lf_var2d + lflags.oldcf; + lflags.type=inst.code.op; break; case t_SBBb: case t_SBBw: case t_SBBd: - flags.oldcf=get_CF(); - flags.var1.d=inst.op1.d; - flags.var2.d=inst.op2.d; - inst.op1.d=flags.result.d=flags.var1.d - flags.var2.d - flags.oldcf; - flags.type=inst.code.op; + lflags.oldcf=get_CF(); + lf_var1d=inst.op1.d; + lf_var2d=inst.op2.d; + inst.op1.d=lf_resd=lf_var1d - lf_var2d - lflags.oldcf; + lflags.type=inst.code.op; break; case t_INCb: case t_INCw: case t_INCd: SETFLAGBIT(CF,get_CF()); - inst.op1.d=flags.result.d=inst.op1.d+1; - flags.type=inst.code.op; + inst.op1.d=lf_resd=inst.op1.d+1; + lflags.type=inst.code.op; break; case t_DECb: case t_DECw: case t_DECd: SETFLAGBIT(CF,get_CF()); - inst.op1.d=flags.result.d=inst.op1.d-1; - flags.type=inst.code.op; + inst.op1.d=lf_resd=inst.op1.d-1; + lflags.type=inst.code.op; break; /* Using the instructions.h defines */ case t_ROLb: @@ -149,19 +149,19 @@ switch (inst.code.op) { } case t_NEGb: - flags.var1.b=inst.op1.b; - inst.op1.b=flags.result.b=0-inst.op1.b; - flags.type=t_NEGb; + lf_var1b=inst.op1.b; + inst.op1.b=lf_resb=0-inst.op1.b; + lflags.type=t_NEGb; break; case t_NEGw: - flags.var1.w=inst.op1.w; - inst.op1.w=flags.result.w=0-inst.op1.w; - flags.type=t_NEGw; + lf_var1w=inst.op1.w; + inst.op1.w=lf_resw=0-inst.op1.w; + lflags.type=t_NEGw; break; case t_NEGd: - flags.var1.d=inst.op1.d; - inst.op1.d=flags.result.d=0-inst.op1.d; - flags.type=t_NEGd; + lf_var1d=inst.op1.d; + inst.op1.d=lf_resd=0-inst.op1.d; + lflags.type=t_NEGd; break; case O_NOT: diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index c7c77f73..b4fb3317 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -154,7 +154,7 @@ static Bits CPU_Core_Normal_Decode_Trap(void); static Bits CPU_Core_Normal_Decode(void) { decode_start: LOADIP; - flags.type=t_UNKNOWN; + lflags.type=t_UNKNOWN; while (CPU_Cycles>0) { core.op_start=core.ip_lookup; core.opcode_index=core.index_default; diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index e0a361d7..ad397e44 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -245,7 +245,7 @@ GetEAa;Bit16u old=LoadMw(eaa); SETFLAGBIT(CF,(old & mask)); } - if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + SetTypeCF(); break; } CASE_0F_W(0xa4) /* SHLD Ew,Gw,Ib */ @@ -271,7 +271,7 @@ SETFLAGBIT(CF,(old & mask)); SaveMw(eaa,old | mask); } - if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + SetTypeCF(); break; } CASE_0F_W(0xac) /* SHRD Ew,Gw,Ib */ @@ -302,7 +302,7 @@ SETFLAGBIT(CF,(old & mask)); SaveMw(eaa,old & ~mask); } - if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + SetTypeCF(); break; } CASE_0F_W(0xb4) /* LFS Ew */ @@ -374,7 +374,7 @@ E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38); } } - if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + SetTypeCF(); break; } CASE_0F_W(0xbb) /* BTC Ew,Gw */ @@ -390,7 +390,7 @@ SETFLAGBIT(CF,(old & mask)); SaveMw(eaa,old ^ mask); } - if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + SetTypeCF(); break; } CASE_0F_W(0xbc) /* BSF Gw,Ew */ @@ -407,7 +407,7 @@ SETFLAGBIT(ZF,false); *rmrw = result; } - flags.type=t_UNKNOWN; + lflags.type=t_UNKNOWN; break; } CASE_0F_W(0xbd) /* BSR Gw,Ew */ @@ -424,7 +424,7 @@ SETFLAGBIT(ZF,false); *rmrw = result; } - flags.type=t_UNKNOWN; + lflags.type=t_UNKNOWN; break; } CASE_0F_W(0xbe) /* MOVSX Gw,Eb */ diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 1530db9a..677a4391 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -351,7 +351,7 @@ } CASE_D(0x9c) /* PUSHFD */ FillFlags(); - Push_32(flags.word); + Push_32(reg_flags); break; CASE_D(0x9d) /* POPFD */ SETFLAGSd(Pop_32()) @@ -583,13 +583,13 @@ } case 0x03: /* NEG Ed */ { - flags.type=t_NEGd; + lflags.type=t_NEGd; if (rm >= 0xc0 ) { - GetEArd;flags.var1.d=*eard;flags.result.d=0-flags.var1.d; - *eard=flags.result.d; + GetEArd;lf_var1d=*eard;lf_resd=0-lf_var1d; + *eard=lf_resd; } else { - GetEAa;flags.var1.d=LoadMd(eaa);flags.result.d=0-flags.var1.d; - SaveMd(eaa,flags.result.d); + GetEAa;lf_var1d=LoadMd(eaa);lf_resd=0-lf_var1d; + SaveMd(eaa,lf_resd); } break; } diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 7496d841..7493fa8b 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -172,7 +172,7 @@ GetEAa;Bit32u old=LoadMd(eaa); SETFLAGBIT(CF,(old & mask)); } - if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + SetTypeCF(); break; } CASE_0F_D(0xa4) /* SHLD Ed,Gd,Ib */ @@ -198,7 +198,7 @@ SETFLAGBIT(CF,(old & mask)); SaveMd(eaa,old | mask); } - if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + SetTypeCF(); break; } @@ -290,8 +290,7 @@ E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38); } } - if (flags.type!=t_CF) flags.prev_type=flags.type; - flags.type=t_CF; + SetTypeCF(); break; } CASE_0F_D(0xbb) /* BTC Ed,Gd */ @@ -307,7 +306,7 @@ SETFLAGBIT(CF,(old & mask)); SaveMd(eaa,old ^ mask); } - if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } + SetTypeCF(); break; } CASE_0F_D(0xbc) /* BSF Gd,Ed */ @@ -324,7 +323,7 @@ SETFLAGBIT(ZF,false); *rmrd = result; } - flags.type=t_UNKNOWN; + lflags.type=t_UNKNOWN; break; } CASE_0F_D(0xbd) /* BSR Gd,Ed */ @@ -341,7 +340,7 @@ SETFLAGBIT(ZF,false); *rmrd = result; } - flags.type=t_UNKNOWN; + lflags.type=t_UNKNOWN; break; } CASE_0F_D(0xbe) /* MOVSX Gd,Eb */ diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 040e1786..78800206 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -558,7 +558,7 @@ break; /* No waiting here */ CASE_W(0x9c) /* PUSHF */ FillFlags(); - Push_16(flags.word); + Push_16(reg_flags); break; CASE_W(0x9d) /* POPF */ SETFLAGSw(Pop_16()); @@ -577,7 +577,7 @@ break; CASE_B(0x9f) /* LAHF */ FillFlags(); - reg_ah=flags.word&0xff; + reg_ah=reg_flags&0xff; break; CASE_B(0xa0) /* MOV AL,Ob */ { @@ -974,8 +974,7 @@ return CBRET_NONE; CASE_B(0xf5) /* CMC */ SETFLAGBIT(CF,!get_CF()); - if (flags.type!=t_CF) flags.prev_type=flags.type; - flags.type=t_CF; + SetTypeCF() ; break; CASE_B(0xf6) /* GRP3 Eb(,Ib) */ { @@ -996,13 +995,13 @@ } case 0x03: /* NEG Eb */ { - flags.type=t_NEGb; + lflags.type=t_NEGb; if (rm >= 0xc0 ) { - GetEArb;flags.var1.b=*earb;flags.result.b=0-flags.var1.b; - *earb=flags.result.b; + GetEArb;lf_var1b=*earb;lf_resb=0-lf_var1b; + *earb=lf_resb; } else { - GetEAa;flags.var1.b=LoadMb(eaa);flags.result.b=0-flags.var1.b; - SaveMb(eaa,flags.result.b); + GetEAa;lf_var1b=LoadMb(eaa);lf_resb=0-lf_var1b; + SaveMb(eaa,lf_resb); } break; } @@ -1040,13 +1039,13 @@ } case 0x03: /* NEG Ew */ { - flags.type=t_NEGw; + lflags.type=t_NEGw; if (rm >= 0xc0 ) { - GetEArw;flags.var1.w=*earw;flags.result.w=0-flags.var1.w; - *earw=flags.result.w; + GetEArw;lf_var1w=*earw;lf_resw=0-lf_var1w; + *earw=lf_resw; } else { - GetEAa;flags.var1.w=LoadMw(eaa);flags.result.w=0-flags.var1.w; - SaveMw(eaa,flags.result.w); + GetEAa;lf_var1w=LoadMw(eaa);lf_resw=0-lf_var1w; + SaveMw(eaa,lf_resw); } break; } @@ -1067,13 +1066,11 @@ } CASE_B(0xf8) /* CLC */ SETFLAGBIT(CF,false); - if (flags.type!=t_CF) flags.prev_type=flags.type; - flags.type=t_CF; + SetTypeCF(); break; CASE_B(0xf9) /* STC */ SETFLAGBIT(CF,true); - if (flags.type!=t_CF) flags.prev_type=flags.type; - flags.type=t_CF; + SetTypeCF(); break; CASE_B(0xfa) /* CLI */ SETFLAGBIT(IF,false); diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 9c765aed..050861d7 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.35 2003-10-14 23:31:51 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.36 2003-10-26 19:00:38 harekiet Exp $ */ #include #include "dosbox.h" @@ -32,7 +32,6 @@ #define LOG(X,Y) #endif -Flag_Info flags; CPU_Regs cpu_regs; CPUBlock cpu; Segments Segs; @@ -92,7 +91,7 @@ PhysPt SelBase(Bitu sel) { } void CPU_SetFlags(Bitu word) { - flags.word=(word|2)&~0x28; + reg_flags=(word|2)&~0x28; } bool CPU_CheckCodeType(CODE_TYPE type) { @@ -131,7 +130,7 @@ bool Interrupt(Bitu num) { if (!cpu.pmode) { /* Save everything on a 16-bit stack */ - CPU_Push16(flags.word & 0xffff); + CPU_Push16(reg_flags & 0xffff); CPU_Push16(SegValue(cs)); CPU_Push16(reg_ip); SETFLAGBIT(IF,false); @@ -172,11 +171,11 @@ bool Interrupt(Bitu num) { case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: /* Prepare stack for gate to same priviledge */ if (gate.Type() & 0x8) { /* 32-bit Gate */ - CPU_Push32(flags.word); + CPU_Push32(reg_flags); CPU_Push32(SegValue(cs)); CPU_Push32(reg_eip); } else { /* 16-bit gate */ - CPU_Push16(flags.word & 0xffff); + CPU_Push16(reg_flags & 0xffff); CPU_Push16(SegValue(cs)); CPU_Push16(reg_ip); } @@ -207,7 +206,7 @@ bool Interrupt(Bitu num) { bool CPU_Exception(Bitu exception,Bit32u error_code) { if (!cpu.pmode) { /* RealMode Interrupt */ /* Save everything on a 16-bit stack */ - CPU_Push16(flags.word & 0xffff); + CPU_Push16(reg_flags & 0xffff); CPU_Push16(SegValue(cs)); CPU_Push16(reg_ip); SETFLAGBIT(IF,false); @@ -256,7 +255,7 @@ bool CPU_IRET(bool use32) { } else { offset=CPU_Pop16(); selector=CPU_Pop16(); - old_flags=(flags.word & 0xffff0000) | CPU_Pop16(); + old_flags=(reg_flags & 0xffff0000) | CPU_Pop16(); } Bitu rpl=selector & 3; Descriptor desc; diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 4f3e07cd..5bdb3b8d 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -26,13 +26,14 @@ #include "lazyflags.h" #include "pic.h" +LazyFlags lflags; /* CF Carry Flag -- Set on high-order bit carry or borrow; cleared otherwise. */ Bitu get_CF(void) { - switch (flags.type) { + switch (lflags.type) { case t_UNKNOWN: case t_CF: case t_INCb: @@ -48,77 +49,77 @@ Bitu get_CF(void) { return GETFLAG(CF); break; case t_ADDb: - return (flags.result.b8) return false; - else return (flags.var1.b >> (8-flags.var2.b)) & 1; + if (lf_var2b>8) return false; + else return (lf_var1b >> (8-lf_var2b)) & 1; case t_SHLw: - if (flags.var2.b>16) return false; - else return (flags.var1.w >> (16-flags.var2.b)) & 1; + if (lf_var2b>16) return false; + else return (lf_var1w >> (16-lf_var2b)) & 1; case t_SHLd: case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */ case t_DSHLd: - return (flags.var1.d >> (32 - flags.var2.b)) & 1; + return (lf_var1d >> (32 - lf_var2b)) & 1; case t_RCRb: case t_SHRb: - return (flags.var1.b >> (flags.var2.b - 1)) & 1; + return (lf_var1b >> (lf_var2b - 1)) & 1; case t_RCRw: case t_SHRw: - return (flags.var1.w >> (flags.var2.b - 1)) & 1; + return (lf_var1w >> (lf_var2b - 1)) & 1; case t_RCRd: case t_SHRd: case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ case t_DSHRd: - return (flags.var1.d >> (flags.var2.b - 1)) & 1; + return (lf_var1d >> (lf_var2b - 1)) & 1; case t_SARb: - return (((Bit8s) flags.var1.b) >> (flags.var2.b - 1)) & 1; + return (((Bit8s) lf_var1b) >> (lf_var2b - 1)) & 1; case t_SARw: - return (((Bit16s) flags.var1.w) >> (flags.var2.b - 1)) & 1; + return (((Bit16s) lf_var1w) >> (lf_var2b - 1)) & 1; case t_SARd: - return (((Bit32s) flags.var1.d) >> (flags.var2.b - 1)) & 1; + return (((Bit32s) lf_var1d) >> (lf_var2b - 1)) & 1; case t_NEGb: - return (flags.var1.b!=0); + return (lf_var1b!=0); case t_NEGw: - return (flags.var1.w!=0); + return (lf_var1w!=0); case t_NEGd: - return (flags.var1.d!=0); + return (lf_var1d!=0); case t_ROLb: - return flags.result.b & 1; + return lf_resb & 1; case t_ROLw: - return flags.result.w & 1; + return lf_resw & 1; case t_ROLd: - return flags.result.d & 1; + return lf_resd & 1; case t_RORb: - return (flags.result.b & 0x80)>0; + return (lf_resb & 0x80)>0; case t_RORw: - return (flags.result.w & 0x8000)>0; + return (lf_resw & 0x8000)>0; case t_RORd: - return (flags.result.d & 0x80000000)>0; + return (lf_resd & 0x80000000)>0; case t_ORb: case t_ORw: case t_ORd: @@ -135,7 +136,7 @@ Bitu get_CF(void) { case t_DIV: return false; /* Unkown */ default: - LOG(LOG_CPU,LOG_ERROR)("get_CF Unknown %d",flags.type); + LOG(LOG_CPU,LOG_ERROR)("get_CF Unknown %d",lflags.type); } return 0; } @@ -145,7 +146,7 @@ Bitu get_CF(void) { arithmetic. */ Bitu get_AF(void) { - Bitu type=flags.type; + Bitu type=lflags.type; again: switch (type) { case t_UNKNOWN: @@ -163,44 +164,44 @@ again: case t_RCRd: return GETFLAG(AF); case t_CF: - type=flags.prev_type; + type=lflags.prev_type; goto again; case t_ADDb: case t_ADCb: case t_SBBb: case t_SUBb: case t_CMPb: - return (((flags.var1.b ^ flags.var2.b) ^ flags.result.b) & 0x10)>0; + return (((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10)>0; case t_ADDw: case t_ADCw: case t_SBBw: case t_SUBw: case t_CMPw: - return (((flags.var1.w ^ flags.var2.w) ^ flags.result.w) & 0x10)>0; + return (((lf_var1w ^ lf_var2w) ^ lf_resw) & 0x10)>0; case t_ADCd: case t_ADDd: case t_SBBd: case t_SUBd: case t_CMPd: - return (((flags.var1.d ^ flags.var2.d) ^ flags.result.d) & 0x10)>0; + return (((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10)>0; case t_INCb: - return (flags.result.b & 0x0f) == 0; + return (lf_resb & 0x0f) == 0; case t_INCw: - return (flags.result.w & 0x0f) == 0; + return (lf_resw & 0x0f) == 0; case t_INCd: - return (flags.result.d & 0x0f) == 0; + return (lf_resd & 0x0f) == 0; case t_DECb: - return (flags.result.b & 0x0f) == 0x0f; + return (lf_resb & 0x0f) == 0x0f; case t_DECw: - return (flags.result.w & 0x0f) == 0x0f; + return (lf_resw & 0x0f) == 0x0f; case t_DECd: - return (flags.result.d & 0x0f) == 0x0f; + return (lf_resd & 0x0f) == 0x0f; case t_NEGb: - return (flags.var1.b & 0x0f) > 0; + return (lf_var1b & 0x0f) > 0; case t_NEGw: - return (flags.var1.w & 0x0f) > 0; + return (lf_var1w & 0x0f) > 0; case t_NEGd: - return (flags.var1.d & 0x0f) > 0; + return (lf_var1d & 0x0f) > 0; case t_ORb: case t_ORw: case t_ORd: @@ -230,7 +231,7 @@ again: case t_MUL: return false; /* Unkown */ default: - LOG(LOG_CPU,LOG_ERROR)("get_AF Unknown %d",flags.type); + LOG(LOG_CPU,LOG_ERROR)("get_AF Unknown %d",lflags.type); } return 0; } @@ -239,7 +240,7 @@ again: */ Bitu get_ZF(void) { - Bitu type=flags.type; + Bitu type=lflags.type; again: switch (type) { case t_UNKNOWN: @@ -257,7 +258,7 @@ again: case t_RCRd: return GETFLAG(ZF); case t_CF: - type=flags.prev_type; + type=lflags.prev_type; goto again; case t_ADDb: case t_ORb: @@ -274,7 +275,7 @@ again: case t_SHRb: case t_SARb: case t_NEGb: - return (flags.result.b==0); + return (lf_resb==0); case t_ADDw: case t_ORw: case t_ADCw: @@ -292,7 +293,7 @@ again: case t_DSHLw: case t_DSHRw: case t_NEGw: - return (flags.result.w==0); + return (lf_resw==0); case t_ADDd: case t_ORd: case t_ADCd: @@ -310,12 +311,12 @@ again: case t_DSHLd: case t_DSHRd: case t_NEGd: - return (flags.result.d==0); + return (lf_resd==0); case t_DIV: case t_MUL: return false; /* Unkown */ default: - LOG(LOG_CPU,LOG_ERROR)("get_ZF Unknown %d",flags.type); + LOG(LOG_CPU,LOG_ERROR)("get_ZF Unknown %d",lflags.type); } return false; } @@ -323,7 +324,7 @@ again: positive, 1 if negative). */ Bitu get_SF(void) { - Bitu type=flags.type; + Bitu type=lflags.type; again: switch (type) { case t_UNKNOWN: @@ -341,7 +342,7 @@ again: case t_RCRd: return GETFLAG(SF); case t_CF: - type=flags.prev_type; + type=lflags.prev_type; goto again; case t_ADDb: case t_ORb: @@ -358,7 +359,7 @@ again: case t_SHRb: case t_SARb: case t_NEGb: - return (flags.result.b>=0x80); + return (lf_resb>=0x80); case t_ADDw: case t_ORw: case t_ADCw: @@ -376,7 +377,7 @@ again: case t_DSHLw: case t_DSHRw: case t_NEGw: - return (flags.result.w>=0x8000); + return (lf_resw>=0x8000); case t_ADDd: case t_ORd: case t_ADCd: @@ -394,12 +395,12 @@ again: case t_DSHLd: case t_DSHRd: case t_NEGd: - return (flags.result.d>=0x80000000); + return (lf_resd>=0x80000000); case t_DIV: case t_MUL: return false; /* Unkown */ default: - LOG(LOG_CPU,LOG_ERROR)("get_SF Unkown %d",flags.type); + LOG(LOG_CPU,LOG_ERROR)("get_SF Unkown %d",lflags.type); } return false; @@ -409,7 +410,7 @@ Bitu get_OF(void) { Bit16u var1w15, var2w15, resultw15; Bit32u var1d31, var2d31, resultd31; - Bitu type=flags.type; + Bitu type=lflags.type; again: switch (type) { case t_UNKNOWN: @@ -422,108 +423,108 @@ again: case t_SARd: return GETFLAG(OF); case t_CF: - type=flags.prev_type; + type=lflags.prev_type; goto again; case t_ADDb: case t_ADCb: -// return (((flags.result.b) ^ (flags.var2.b)) & ((flags.result.b) ^ (flags.var1.b)) & 0x80)>0; - var1b7 = flags.var1.b & 0x80; - var2b7 = flags.var2.b & 0x80; - resultb7 = flags.result.b & 0x80; +// return (((lf_resb) ^ (lf_var2b)) & ((lf_resb) ^ (lf_var1b)) & 0x80)>0; + var1b7 = lf_var1b & 0x80; + var2b7 = lf_var2b & 0x80; + resultb7 = lf_resb & 0x80; return (var1b7 == var2b7) && (resultb7 ^ var2b7); case t_ADDw: case t_ADCw: -// return (((flags.result.w) ^ (flags.var2.w)) & ((flags.result.w) ^ (flags.var1.w)) & 0x8000)>0; - var1w15 = flags.var1.w & 0x8000; - var2w15 = flags.var2.w & 0x8000; - resultw15 = flags.result.w & 0x8000; +// return (((lf_resw) ^ (lf_var2w)) & ((lf_resw) ^ (lf_var1w)) & 0x8000)>0; + var1w15 = lf_var1w & 0x8000; + var2w15 = lf_var2w & 0x8000; + resultw15 = lf_resw & 0x8000; return (var1w15 == var2w15) && (resultw15 ^ var2w15); case t_ADDd: case t_ADCd: //TODO fix dword Overflow - var1d31 = flags.var1.d & 0x80000000; - var2d31 = flags.var2.d & 0x80000000; - resultd31 = flags.result.d & 0x80000000; + var1d31 = lf_var1d & 0x80000000; + var2d31 = lf_var2d & 0x80000000; + resultd31 = lf_resd & 0x80000000; return (var1d31 == var2d31) && (resultd31 ^ var2d31); case t_SBBb: case t_SUBb: case t_CMPb: -// return (((flags.var1.b) ^ (flags.var2.b)) & ((flags.var1.b) ^ (flags.result.b)) & 0x80)>0; - var1b7 = flags.var1.b & 0x80; - var2b7 = flags.var2.b & 0x80; - resultb7 = flags.result.b & 0x80; +// return (((lf_var1b) ^ (lf_var2b)) & ((lf_var1b) ^ (lf_resb)) & 0x80)>0; + var1b7 = lf_var1b & 0x80; + var2b7 = lf_var2b & 0x80; + resultb7 = lf_resb & 0x80; return (var1b7 ^ var2b7) && (var1b7 ^ resultb7); case t_SBBw: case t_SUBw: case t_CMPw: -// return (((flags.var1.w) ^ (flags.var2.w)) & ((flags.var1.w) ^ (flags.result.w)) & 0x8000)>0; - var1w15 = flags.var1.w & 0x8000; - var2w15 = flags.var2.w & 0x8000; - resultw15 = flags.result.w & 0x8000; +// return (((lf_var1w) ^ (lf_var2w)) & ((lf_var1w) ^ (lf_resw)) & 0x8000)>0; + var1w15 = lf_var1w & 0x8000; + var2w15 = lf_var2w & 0x8000; + resultw15 = lf_resw & 0x8000; return (var1w15 ^ var2w15) && (var1w15 ^ resultw15); case t_SBBd: case t_SUBd: case t_CMPd: - var1d31 = flags.var1.d & 0x80000000; - var2d31 = flags.var2.d & 0x80000000; - resultd31 = flags.result.d & 0x80000000; + var1d31 = lf_var1d & 0x80000000; + var2d31 = lf_var2d & 0x80000000; + resultd31 = lf_resd & 0x80000000; return (var1d31 ^ var2d31) && (var1d31 ^ resultd31); case t_INCb: - return (flags.result.b == 0x80); + return (lf_resb == 0x80); case t_INCw: - return (flags.result.w == 0x8000); + return (lf_resw == 0x8000); case t_INCd: - return (flags.result.d == 0x80000000); + return (lf_resd == 0x80000000); case t_DECb: - return (flags.result.b == 0x7f); + return (lf_resb == 0x7f); case t_DECw: - return (flags.result.w == 0x7fff); + return (lf_resw == 0x7fff); case t_DECd: - return (flags.result.d == 0x7fffffff); + return (lf_resd == 0x7fffffff); case t_NEGb: - return (flags.var1.b == 0x80); + return (lf_var1b == 0x80); case t_NEGw: - return (flags.var1.w == 0x8000); + return (lf_var1w == 0x8000); case t_NEGd: - return (flags.var1.d == 0x80000000); + return (lf_var1d == 0x80000000); case t_ROLb: - return ((flags.result.b & 0x80) ^ (flags.result.b & 1 ? 0x80 : 0)) != 0; + return ((lf_resb & 0x80) ^ (lf_resb & 1 ? 0x80 : 0)) != 0; case t_ROLw: - return ((flags.result.w & 0x8000) ^ (flags.result.w & 1 ? 0x8000 : 0)) != 0; + return ((lf_resw & 0x8000) ^ (lf_resw & 1 ? 0x8000 : 0)) != 0; case t_ROLd: - return ((flags.result.d & 0x80000000) ^ (flags.result.d & 1 ? 0x80000000 : 0)) != 0; + return ((lf_resd & 0x80000000) ^ (lf_resd & 1 ? 0x80000000 : 0)) != 0; case t_SHLb: - if (flags.var2.b>9) return false; - return ((flags.result.b & 0x80) ^ - ((flags.var1.b << (flags.var2.b - 1)) & 0x80)) != 0; + if (lf_var2b>9) return false; + return ((lf_resb & 0x80) ^ + ((lf_var1b << (lf_var2b - 1)) & 0x80)) != 0; case t_SHLw: - if (flags.var2.b>17) return false; - return ((flags.result.w & 0x8000) ^ - ((flags.var1.w << (flags.var2.b - 1)) & 0x8000)) != 0; + if (lf_var2b>17) return false; + return ((lf_resw & 0x8000) ^ + ((lf_var1w << (lf_var2b - 1)) & 0x8000)) != 0; case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */ - return ((flags.result.w & 0x8000) ^ - (((flags.var1.d << (flags.var2.b - 1)) >> 16) & 0x8000)) != 0; + return ((lf_resw & 0x8000) ^ + (((lf_var1d << (lf_var2b - 1)) >> 16) & 0x8000)) != 0; case t_SHLd: case t_DSHLd: - return ((flags.result.d & 0x80000000) ^ - ((flags.var1.d << (flags.var2.b - 1)) & 0x80000000)) != 0; + return ((lf_resd & 0x80000000) ^ + ((lf_var1d << (lf_var2b - 1)) & 0x80000000)) != 0; case t_RORb: case t_RCRb: - return ((flags.result.b ^ (flags.result.b << 1)) & 0x80) > 0; + return ((lf_resb ^ (lf_resb << 1)) & 0x80) > 0; case t_RORw: case t_RCRw: case t_DSHRw: - return ((flags.result.w ^ (flags.result.w << 1)) & 0x8000) > 0; + return ((lf_resw ^ (lf_resw << 1)) & 0x8000) > 0; case t_RORd: case t_RCRd: case t_DSHRd: - return ((flags.result.d ^ (flags.result.d << 1)) & 0x80000000) > 0; + return ((lf_resd ^ (lf_resd << 1)) & 0x80000000) > 0; case t_SHRb: - return (flags.result.b >= 0x40); + return (lf_resb >= 0x40); case t_SHRw: - return (flags.result.w >= 0x4000); + return (lf_resw >= 0x4000); case t_SHRd: - return (flags.result.d >= 0x40000000); + return (lf_resd >= 0x40000000); case t_ORb: case t_ORw: case t_ORd: @@ -540,7 +541,7 @@ again: case t_DIV: return false; /* Unkown */ default: - LOG(LOG_CPU,LOG_ERROR)("get_OF Unkown %d",flags.type); + LOG(LOG_CPU,LOG_ERROR)("get_OF Unkown %d",lflags.type); } return false; } @@ -565,89 +566,89 @@ bool parity_lookup[256] = { }; Bitu get_PF(void) { - switch (flags.type) { + switch (lflags.type) { case t_UNKNOWN: return GETFLAG(PF); default: - return (parity_lookup[flags.result.b]);; + return (parity_lookup[lf_resb]);; }; return false; } void FillFlags(void) { - Bitu new_word=(flags.word & ~FLAG_MASK); + Bitu new_word=(reg_flags & ~FLAG_MASK); if (get_CF()) new_word|=FLAG_CF; if (get_PF()) new_word|=FLAG_PF; if (get_AF()) new_word|=FLAG_AF; if (get_ZF()) new_word|=FLAG_ZF; if (get_SF()) new_word|=FLAG_SF; if (get_OF()) new_word|=FLAG_OF; - flags.word=new_word; - flags.type=t_UNKNOWN; + reg_flags=new_word; + lflags.type=t_UNKNOWN; } #if 0 Bitu get_Flags(void) { Bitu new_flags=0; - switch (flags.type) { + switch (lflags.type) { case t_ADDb: - SET_FLAG(FLAG_CF,(flags.result.b0); + SET_FLAG(FLAG_CF,(lf_resb0); break; case t_ADDw: - SET_FLAG(FLAG_CF,(flags.result.w0); + SET_FLAG(FLAG_CF,(lf_resw0); break; case t_ADDd: - SET_FLAG(FLAG_CF,(flags.result.d0); + SET_FLAG(FLAG_CF,(lf_resd0); break; case t_ADCb: - SET_FLAG(FLAG_CF,(flags.result.b < flags.var1.b) || (flags.oldcf && (flags.result.b == flags.var1.b))); - SET_FLAG(FLAG_AF,(((flags.var1.b ^ flags.var2.b) ^ flags.result.b) & 0x10)>0); + SET_FLAG(FLAG_CF,(lf_resb < lf_var1b) || (lflags.oldcf && (lf_resb == lf_var1b))); + SET_FLAG(FLAG_AF,(((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10)>0); break; case t_ADCw: - SET_FLAG(FLAG_CF,(flags.result.w < flags.var1.w) || (flags.oldcf && (flags.result.w == flags.var1.w))); - SET_FLAG(FLAG_AF,(((flags.var1.w ^ flags.var2.w) ^ flags.result.w) & 0x10)>0); + SET_FLAG(FLAG_CF,(lf_resw < lf_var1w) || (lflags.oldcf && (lf_resw == lf_var1w))); + SET_FLAG(FLAG_AF,(((lf_var1w ^ lf_var2w) ^ lf_resw) & 0x10)>0); break; case t_ADCd: - SET_FLAG(FLAG_CF,(flags.result.d < flags.var1.d) || (flags.oldcf && (flags.result.d == flags.var1.d))); - SET_FLAG(FLAG_AF,(((flags.var1.d ^ flags.var2.d) ^ flags.result.d) & 0x10)>0); + SET_FLAG(FLAG_CF,(lf_resd < lf_var1d) || (lflags.oldcf && (lf_resd == lf_var1d))); + SET_FLAG(FLAG_AF,(((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10)>0); break; case t_SBBb: - SET_FLAG(FLAG_CF,(flags.var1.b < flags.result.b) || (flags.oldcf && (flags.var2.b==0xff))); - SET_FLAG(FLAG_AF,(((flags.var1.b ^ flags.var2.b) ^ flags.result.b) & 0x10)>0); + SET_FLAG(FLAG_CF,(lf_var1b < lf_resb) || (lflags.oldcf && (lf_var2b==0xff))); + SET_FLAG(FLAG_AF,(((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10)>0); break; case t_SBBw: - SET_FLAG(FLAG_CF,(flags.var1.w < flags.result.w) || (flags.oldcf && (flags.var2.w==0xffff))); - SET_FLAG(FLAG_AF,(((flags.var1.w ^ flags.var2.w) ^ flags.result.w) & 0x10)>0); + SET_FLAG(FLAG_CF,(lf_var1w < lf_resw) || (lflags.oldcf && (lf_var2w==0xffff))); + SET_FLAG(FLAG_AF,(((lf_var1w ^ lf_var2w) ^ lf_resw) & 0x10)>0); break; case t_SBBd: - SET_FLAG(FLAG_CF,(flags.var1.d < flags.result.d) || (flags.oldcf && (flags.var2.d==0xffffffff))); - SET_FLAG(FLAG_AF,(((flags.var1.d ^ flags.var2.d) ^ flags.result.d) & 0x10)>0); + SET_FLAG(FLAG_CF,(lf_var1d < lf_resd) || (lflags.oldcf && (lf_var2d==0xffffffff))); + SET_FLAG(FLAG_AF,(((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10)>0); break; case t_SUBb: case t_CMPb: - SET_FLAG(FLAG_CF,(flags.var1.b0); + SET_FLAG(FLAG_CF,(lf_var1b0); break; case t_SUBw: case t_CMPw: - SET_FLAG(FLAG_CF,(flags.var1.w0); + SET_FLAG(FLAG_CF,(lf_var1w0); break; case t_SUBd: case t_CMPd: - SET_FLAG(FLAG_CF,(flags.var1.d0); + SET_FLAG(FLAG_CF,(lf_var1d0); break; @@ -688,122 +689,122 @@ Bitu get_Flags(void) { case t_SHLb: - if (flags.var2.b>8) SET_FLAG(FLAG_CF,false); - else SET_FLAG(FLAG_CF,(flags.var1.b >> (8-flags.var2.b)) & 1); + if (lf_var2b>8) SET_FLAG(FLAG_CF,false); + else SET_FLAG(FLAG_CF,(lf_var1b >> (8-lf_var2b)) & 1); break; case t_SHLw: - if (flags.var2.b>16) SET_FLAG(FLAG_CF,false); - else SET_FLAG(FLAG_CF,(flags.var1.w >> (16-flags.var2.b)) & 1); + if (lf_var2b>16) SET_FLAG(FLAG_CF,false); + else SET_FLAG(FLAG_CF,(lf_var1w >> (16-lf_var2b)) & 1); break; case t_SHLd: - SET_FLAG(FLAG_CF,(flags.var1.d >> (32 - flags.var2.b)) & 1); + SET_FLAG(FLAG_CF,(lf_var1d >> (32 - lf_var2b)) & 1); break; case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */ - SET_FLAG(FLAG_CF,(flags.var1.d >> (32 - flags.var2.b)) & 1); + SET_FLAG(FLAG_CF,(lf_var1d >> (32 - lf_var2b)) & 1); break; case t_DSHLd: - SET_FLAG(FLAG_CF,(flags.var1.d >> (32 - flags.var2.b)) & 1); + SET_FLAG(FLAG_CF,(lf_var1d >> (32 - lf_var2b)) & 1); break; case t_SHRb: - SET_FLAG(FLAG_CF,(flags.var1.b >> (flags.var2.b - 1)) & 1); + SET_FLAG(FLAG_CF,(lf_var1b >> (lf_var2b - 1)) & 1); break; case t_SHRw: - SET_FLAG(FLAG_CF,(flags.var1.w >> (flags.var2.b - 1)) & 1); + SET_FLAG(FLAG_CF,(lf_var1w >> (lf_var2b - 1)) & 1); break; case t_SHRd: - SET_FLAG(FLAG_CF,(flags.var1.d >> (flags.var2.b - 1)) & 1); + SET_FLAG(FLAG_CF,(lf_var1d >> (lf_var2b - 1)) & 1); break; case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ - SET_FLAG(FLAG_CF,(flags.var1.d >> (flags.var2.b - 1)) & 1); + SET_FLAG(FLAG_CF,(lf_var1d >> (lf_var2b - 1)) & 1); break; case t_DSHRd: - SET_FLAG(FLAG_CF,(flags.var1.d >> (flags.var2.b - 1)) & 1); + SET_FLAG(FLAG_CF,(lf_var1d >> (lf_var2b - 1)) & 1); break; case t_SARb: - SET_FLAG(FLAG_CF,(((Bit8s) flags.var1.b) >> (flags.var2.b - 1)) & 1); + SET_FLAG(FLAG_CF,(((Bit8s) lf_var1b) >> (lf_var2b - 1)) & 1); break; case t_SARw: - SET_FLAG(FLAG_CF,(((Bit16s) flags.var1.w) >> (flags.var2.b - 1)) & 1); + SET_FLAG(FLAG_CF,(((Bit16s) lf_var1w) >> (lf_var2b - 1)) & 1); break; case t_SARd: - SET_FLAG(FLAG_CF,(((Bit32s) flags.var1.d) >> (flags.var2.b - 1)) & 1); + SET_FLAG(FLAG_CF,(((Bit32s) lf_var1d) >> (lf_var2b - 1)) & 1); break; case t_ROLb: - SET_FLAG(FLAG_CF,flags.result.b & 1); + SET_FLAG(FLAG_CF,lf_resb & 1); break; case t_ROLw: - SET_FLAG(FLAG_CF,flags.result.w & 1); + SET_FLAG(FLAG_CF,lf_resw & 1); break; case t_ROLd: - SET_FLAG(FLAG_CF,flags.result.d & 1); + SET_FLAG(FLAG_CF,lf_resd & 1); break; case t_RORb: - SET_FLAG(FLAG_CF,(flags.result.b & 0x80)>0); + SET_FLAG(FLAG_CF,(lf_resb & 0x80)>0); break; case t_RORw: - SET_FLAG(FLAG_CF,(flags.result.w & 0x8000)>0); + SET_FLAG(FLAG_CF,(lf_resw & 0x8000)>0); break; case t_RORd: - SET_FLAG(FLAG_CF,(flags.result.d & 0x80000000)>0); + SET_FLAG(FLAG_CF,(lf_resd & 0x80000000)>0); break; case t_RCRb: - SET_FLAG(FLAG_CF,(flags.var1.b >> (flags.var2.b - 1)) & 1); + SET_FLAG(FLAG_CF,(lf_var1b >> (lf_var2b - 1)) & 1); break; case t_RCRw: - SET_FLAG(FLAG_CF,(flags.var1.w >> (flags.var2.b - 1)) & 1); + SET_FLAG(FLAG_CF,(lf_var1w >> (lf_var2b - 1)) & 1); break; case t_RCRd: - SET_FLAG(FLAG_CF,(flags.var1.d >> (flags.var2.b - 1)) & 1); + SET_FLAG(FLAG_CF,(lf_var1d >> (lf_var2b - 1)) & 1); break; case t_INCb: - SET_FLAG(FLAG_OF,(flags.result.b == 0x80)); - SET_FLAG(FLAG_AF,((flags.result.b & 0x0f) == 0)); + SET_FLAG(FLAG_OF,(lf_resb == 0x80)); + SET_FLAG(FLAG_AF,((lf_resb & 0x0f) == 0)); break; case t_INCw: - SET_FLAG(FLAG_OF,(flags.result.w == 0x8000)); - SET_FLAG(FLAG_AF,((flags.result.w & 0x0f) == 0)); + SET_FLAG(FLAG_OF,(lf_resw == 0x8000)); + SET_FLAG(FLAG_AF,((lf_resw & 0x0f) == 0)); break; case t_INCd: - SET_FLAG(FLAG_OF,(flags.result.d == 0x80000000)); - SET_FLAG(FLAG_AF,((flags.result.d & 0x0f) == 0)); + SET_FLAG(FLAG_OF,(lf_resd == 0x80000000)); + SET_FLAG(FLAG_AF,((lf_resd & 0x0f) == 0)); break; case t_DECb: - SET_FLAG(FLAG_OF,(flags.result.b == 0x7f)); + SET_FLAG(FLAG_OF,(lf_resb == 0x7f)); break; case t_DECw: - SET_FLAG(FLAG_OF,(flags.result.w == 0x7fff)); + SET_FLAG(FLAG_OF,(lf_resw == 0x7fff)); break; case t_DECd: - SET_FLAG(FLAG_OF,(flags.result.d == 0x7fffffff)); + SET_FLAG(FLAG_OF,(lf_resd == 0x7fffffff)); break; case t_NEGb: - SET_FLAG(FLAG_CF,(flags.var1.b!=0)); + SET_FLAG(FLAG_CF,(lf_var1b!=0)); break; case t_NEGw: - SET_FLAG(FLAG_CF,(flags.var1.w!=0)); + SET_FLAG(FLAG_CF,(lf_var1w!=0)); break; case t_NEGd: - SET_FLAG(FLAG_CF,(flags.var1.d!=0)); + SET_FLAG(FLAG_CF,(lf_var1d!=0)); break; @@ -811,10 +812,10 @@ Bitu get_Flags(void) { SET_FLAG(FLAG_CF,false); /* Unkown */ break; default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled flag type %d",flags.type); + LOG(LOG_CPU,LOG_ERROR)("Unhandled flag type %d",lflags.type); return 0; } - flags.word=new_flags; + lflags.word=new_flags; return 0; } diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 7f0d731b..9b5a4cdc 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -20,265 +20,265 @@ /* All Byte genereal instructions */ #define ADDB(op1,op2,load,save) \ - flags.var1.b=load(op1);flags.var2.b=op2; \ - flags.result.b=flags.var1.b+flags.var2.b; \ - save(op1,flags.result.b); \ - flags.type=t_ADDb; + lf_var1b=load(op1);lf_var2b=op2; \ + lf_resb=lf_var1b+lf_var2b; \ + save(op1,lf_resb); \ + lflags.type=t_ADDb; #define ADCB(op1,op2,load,save) \ - flags.oldcf=get_CF(); \ - flags.var1.b=load(op1);flags.var2.b=op2; \ - flags.result.b=flags.var1.b+flags.var2.b+flags.oldcf; \ - save(op1,flags.result.b); \ - flags.type=t_ADCb; + lflags.oldcf=get_CF(); \ + lf_var1b=load(op1);lf_var2b=op2; \ + lf_resb=lf_var1b+lf_var2b+lflags.oldcf; \ + save(op1,lf_resb); \ + lflags.type=t_ADCb; #define SBBB(op1,op2,load,save) \ - flags.oldcf=get_CF(); \ - flags.var1.b=load(op1);flags.var2.b=op2; \ - flags.result.b=flags.var1.b-(flags.var2.b+flags.oldcf); \ - save(op1,flags.result.b); \ - flags.type=t_SBBb; + lflags.oldcf=get_CF(); \ + lf_var1b=load(op1);lf_var2b=op2; \ + lf_resb=lf_var1b-(lf_var2b+lflags.oldcf); \ + save(op1,lf_resb); \ + lflags.type=t_SBBb; #define SUBB(op1,op2,load,save) \ - flags.var1.b=load(op1);flags.var2.b=op2; \ - flags.result.b=flags.var1.b-flags.var2.b; \ - save(op1,flags.result.b); \ - flags.type=t_SUBb; + lf_var1b=load(op1);lf_var2b=op2; \ + lf_resb=lf_var1b-lf_var2b; \ + save(op1,lf_resb); \ + lflags.type=t_SUBb; #define ORB(op1,op2,load,save) \ - flags.var1.b=load(op1);flags.var2.b=op2; \ - flags.result.b=flags.var1.b | flags.var2.b; \ - save(op1,flags.result.b); \ - flags.type=t_ORb; + lf_var1b=load(op1);lf_var2b=op2; \ + lf_resb=lf_var1b | lf_var2b; \ + save(op1,lf_resb); \ + lflags.type=t_ORb; #define XORB(op1,op2,load,save) \ - flags.var1.b=load(op1);flags.var2.b=op2; \ - flags.result.b=flags.var1.b ^ flags.var2.b; \ - save(op1,flags.result.b); \ - flags.type=t_XORb; + lf_var1b=load(op1);lf_var2b=op2; \ + lf_resb=lf_var1b ^ lf_var2b; \ + save(op1,lf_resb); \ + lflags.type=t_XORb; #define ANDB(op1,op2,load,save) \ - flags.var1.b=load(op1);flags.var2.b=op2; \ - flags.result.b=flags.var1.b & flags.var2.b; \ - save(op1,flags.result.b); \ - flags.type=t_ANDb; + lf_var1b=load(op1);lf_var2b=op2; \ + lf_resb=lf_var1b & lf_var2b; \ + save(op1,lf_resb); \ + lflags.type=t_ANDb; #define CMPB(op1,op2,load,save) \ - flags.var1.b=load(op1);flags.var2.b=op2; \ - flags.result.b=flags.var1.b-flags.var2.b; \ - flags.type=t_CMPb; + lf_var1b=load(op1);lf_var2b=op2; \ + lf_resb=lf_var1b-lf_var2b; \ + lflags.type=t_CMPb; #define TESTB(op1,op2,load,save) \ - flags.var1.b=load(op1);flags.var2.b=op2; \ - flags.result.b=flags.var1.b & flags.var2.b; \ - flags.type=t_TESTb; + lf_var1b=load(op1);lf_var2b=op2; \ + lf_resb=lf_var1b & lf_var2b; \ + lflags.type=t_TESTb; /* All Word General instructions */ #define ADDW(op1,op2,load,save) \ - flags.var1.w=load(op1);flags.var2.w=op2; \ - flags.result.w=flags.var1.w+flags.var2.w; \ - save(op1,flags.result.w); \ - flags.type=t_ADDw; + lf_var1w=load(op1);lf_var2w=op2; \ + lf_resw=lf_var1w+lf_var2w; \ + save(op1,lf_resw); \ + lflags.type=t_ADDw; #define ADCW(op1,op2,load,save) \ - flags.oldcf=get_CF(); \ - flags.var1.w=load(op1);flags.var2.w=op2; \ - flags.result.w=flags.var1.w+flags.var2.w+flags.oldcf; \ - save(op1,flags.result.w); \ - flags.type=t_ADCw; + lflags.oldcf=get_CF(); \ + lf_var1w=load(op1);lf_var2w=op2; \ + lf_resw=lf_var1w+lf_var2w+lflags.oldcf; \ + save(op1,lf_resw); \ + lflags.type=t_ADCw; #define SBBW(op1,op2,load,save) \ - flags.oldcf=get_CF(); \ - flags.var1.w=load(op1);flags.var2.w=op2; \ - flags.result.w=flags.var1.w-(flags.var2.w+flags.oldcf); \ - save(op1,flags.result.w); \ - flags.type=t_SBBw; + lflags.oldcf=get_CF(); \ + lf_var1w=load(op1);lf_var2w=op2; \ + lf_resw=lf_var1w-(lf_var2w+lflags.oldcf); \ + save(op1,lf_resw); \ + lflags.type=t_SBBw; #define SUBW(op1,op2,load,save) \ - flags.var1.w=load(op1);flags.var2.w=op2; \ - flags.result.w=flags.var1.w-flags.var2.w; \ - save(op1,flags.result.w); \ - flags.type=t_SUBw; + lf_var1w=load(op1);lf_var2w=op2; \ + lf_resw=lf_var1w-lf_var2w; \ + save(op1,lf_resw); \ + lflags.type=t_SUBw; #define ORW(op1,op2,load,save) \ - flags.var1.w=load(op1);flags.var2.w=op2; \ - flags.result.w=flags.var1.w | flags.var2.w; \ - save(op1,flags.result.w); \ - flags.type=t_ORw; + lf_var1w=load(op1);lf_var2w=op2; \ + lf_resw=lf_var1w | lf_var2w; \ + save(op1,lf_resw); \ + lflags.type=t_ORw; #define XORW(op1,op2,load,save) \ - flags.var1.w=load(op1);flags.var2.w=op2; \ - flags.result.w=flags.var1.w ^ flags.var2.w; \ - save(op1,flags.result.w); \ - flags.type=t_XORw; + lf_var1w=load(op1);lf_var2w=op2; \ + lf_resw=lf_var1w ^ lf_var2w; \ + save(op1,lf_resw); \ + lflags.type=t_XORw; #define ANDW(op1,op2,load,save) \ - flags.var1.w=load(op1);flags.var2.w=op2; \ - flags.result.w=flags.var1.w & flags.var2.w; \ - save(op1,flags.result.w); \ - flags.type=t_ANDw; + lf_var1w=load(op1);lf_var2w=op2; \ + lf_resw=lf_var1w & lf_var2w; \ + save(op1,lf_resw); \ + lflags.type=t_ANDw; #define CMPW(op1,op2,load,save) \ - flags.var1.w=load(op1);flags.var2.w=op2; \ - flags.result.w=flags.var1.w-flags.var2.w; \ - flags.type=t_CMPw; + lf_var1w=load(op1);lf_var2w=op2; \ + lf_resw=lf_var1w-lf_var2w; \ + lflags.type=t_CMPw; #define TESTW(op1,op2,load,save) \ - flags.var1.w=load(op1);flags.var2.w=op2; \ - flags.result.w=flags.var1.w & flags.var2.w; \ - flags.type=t_TESTw; + lf_var1w=load(op1);lf_var2w=op2; \ + lf_resw=lf_var1w & lf_var2w; \ + lflags.type=t_TESTw; /* All DWORD General Instructions */ #define ADDD(op1,op2,load,save) \ - flags.var1.d=load(op1);flags.var2.d=op2; \ - flags.result.d=flags.var1.d+flags.var2.d; \ - save(op1,flags.result.d); \ - flags.type=t_ADDd; + lf_var1d=load(op1);lf_var2d=op2; \ + lf_resd=lf_var1d+lf_var2d; \ + save(op1,lf_resd); \ + lflags.type=t_ADDd; #define ADCD(op1,op2,load,save) \ - flags.oldcf=get_CF(); \ - flags.var1.d=load(op1);flags.var2.d=op2; \ - flags.result.d=flags.var1.d+flags.var2.d+flags.oldcf; \ - save(op1,flags.result.d); \ - flags.type=t_ADCd; + lflags.oldcf=get_CF(); \ + lf_var1d=load(op1);lf_var2d=op2; \ + lf_resd=lf_var1d+lf_var2d+lflags.oldcf; \ + save(op1,lf_resd); \ + lflags.type=t_ADCd; #define SBBD(op1,op2,load,save) \ - flags.oldcf=get_CF(); \ - flags.var1.d=load(op1);flags.var2.d=op2; \ - flags.result.d=flags.var1.d-(flags.var2.d+flags.oldcf); \ - save(op1,flags.result.d); \ - flags.type=t_SBBd; + lflags.oldcf=get_CF(); \ + lf_var1d=load(op1);lf_var2d=op2; \ + lf_resd=lf_var1d-(lf_var2d+lflags.oldcf); \ + save(op1,lf_resd); \ + lflags.type=t_SBBd; #define SUBD(op1,op2,load,save) \ - flags.var1.d=load(op1);flags.var2.d=op2; \ - flags.result.d=flags.var1.d-flags.var2.d; \ - save(op1,flags.result.d); \ - flags.type=t_SUBd; + lf_var1d=load(op1);lf_var2d=op2; \ + lf_resd=lf_var1d-lf_var2d; \ + save(op1,lf_resd); \ + lflags.type=t_SUBd; #define ORD(op1,op2,load,save) \ - flags.var1.d=load(op1);flags.var2.d=op2; \ - flags.result.d=flags.var1.d | flags.var2.d; \ - save(op1,flags.result.d); \ - flags.type=t_ORd; + lf_var1d=load(op1);lf_var2d=op2; \ + lf_resd=lf_var1d | lf_var2d; \ + save(op1,lf_resd); \ + lflags.type=t_ORd; #define XORD(op1,op2,load,save) \ - flags.var1.d=load(op1);flags.var2.d=op2; \ - flags.result.d=flags.var1.d ^ flags.var2.d; \ - save(op1,flags.result.d); \ - flags.type=t_XORd; + lf_var1d=load(op1);lf_var2d=op2; \ + lf_resd=lf_var1d ^ lf_var2d; \ + save(op1,lf_resd); \ + lflags.type=t_XORd; #define ANDD(op1,op2,load,save) \ - flags.var1.d=load(op1);flags.var2.d=op2; \ - flags.result.d=flags.var1.d & flags.var2.d; \ - save(op1,flags.result.d); \ - flags.type=t_ANDd; + lf_var1d=load(op1);lf_var2d=op2; \ + lf_resd=lf_var1d & lf_var2d; \ + save(op1,lf_resd); \ + lflags.type=t_ANDd; #define CMPD(op1,op2,load,save) \ - flags.var1.d=load(op1);flags.var2.d=op2; \ - flags.result.d=flags.var1.d-flags.var2.d; \ - flags.type=t_CMPd; + lf_var1d=load(op1);lf_var2d=op2; \ + lf_resd=lf_var1d-lf_var2d; \ + lflags.type=t_CMPd; #define TESTD(op1,op2,load,save) \ - flags.var1.d=load(op1);flags.var2.d=op2; \ - flags.result.d=flags.var1.d & flags.var2.d; \ - flags.type=t_TESTd; + lf_var1d=load(op1);lf_var2d=op2; \ + lf_resd=lf_var1d & lf_var2d; \ + lflags.type=t_TESTd; #define INCB(op1,load,save) \ - LoadCF;flags.result.b=load(op1)+1; \ - save(op1,flags.result.b); \ - flags.type=t_INCb; \ + LoadCF;lf_resb=load(op1)+1; \ + save(op1,lf_resb); \ + lflags.type=t_INCb; \ #define INCW(op1,load,save) \ - LoadCF;flags.result.w=load(op1)+1; \ - save(op1,flags.result.w); \ - flags.type=t_INCw; + LoadCF;lf_resw=load(op1)+1; \ + save(op1,lf_resw); \ + lflags.type=t_INCw; #define INCD(op1,load,save) \ - LoadCF;flags.result.d=load(op1)+1; \ - save(op1,flags.result.d); \ - flags.type=t_INCd; + LoadCF;lf_resd=load(op1)+1; \ + save(op1,lf_resd); \ + lflags.type=t_INCd; #define DECB(op1,load,save) \ - LoadCF;flags.result.b=load(op1)-1; \ - save(op1,flags.result.b); \ - flags.type=t_DECb; + LoadCF;lf_resb=load(op1)-1; \ + save(op1,lf_resb); \ + lflags.type=t_DECb; #define DECW(op1,load,save) \ - LoadCF;flags.result.w=load(op1)-1; \ - save(op1,flags.result.w); \ - flags.type=t_DECw; + LoadCF;lf_resw=load(op1)-1; \ + save(op1,lf_resw); \ + lflags.type=t_DECw; #define DECD(op1,load,save) \ - LoadCF;flags.result.d=load(op1)-1; \ - save(op1,flags.result.d); \ - flags.type=t_DECd; + LoadCF;lf_resd=load(op1)-1; \ + save(op1,lf_resd); \ + lflags.type=t_DECd; #define ROLB(op1,op2,load,save) \ LoadZF;LoadSF;LoadAF; \ - flags.var1.b=load(op1); \ - flags.var2.b=op2&0x07; \ - flags.result.b=(flags.var1.b << flags.var2.b) | \ - (flags.var1.b >> (8-flags.var2.b)); \ - save(op1,flags.result.b); \ - flags.type=t_ROLb; \ + lf_var1b=load(op1); \ + lf_var2b=op2&0x07; \ + lf_resb=(lf_var1b << lf_var2b) | \ + (lf_var1b >> (8-lf_var2b)); \ + save(op1,lf_resb); \ + lflags.type=t_ROLb; \ #define ROLW(op1,op2,load,save) \ LoadZF;LoadSF;LoadAF; \ - flags.var1.w=load(op1); \ - flags.var2.b=op2&0x0F; \ - flags.result.w=(flags.var1.w << flags.var2.b) | \ - (flags.var1.w >> (16-flags.var2.b)); \ - save(op1,flags.result.w); \ - flags.type=t_ROLw; \ + lf_var1w=load(op1); \ + lf_var2b=op2&0x0F; \ + lf_resw=(lf_var1w << lf_var2b) | \ + (lf_var1w >> (16-lf_var2b)); \ + save(op1,lf_resw); \ + lflags.type=t_ROLw; \ #define ROLD(op1,op2,load,save) \ LoadZF;LoadSF;LoadAF; \ - flags.var1.d=load(op1); \ - flags.var2.b=op2; \ - flags.result.d=(flags.var1.d << flags.var2.b) | \ - (flags.var1.d >> (32-flags.var2.b)); \ - save(op1,flags.result.d); \ - flags.type=t_ROLd; \ + lf_var1d=load(op1); \ + lf_var2b=op2; \ + lf_resd=(lf_var1d << lf_var2b) | \ + (lf_var1d >> (32-lf_var2b)); \ + save(op1,lf_resd); \ + lflags.type=t_ROLd; \ #define RORB(op1,op2,load,save) \ LoadZF;LoadSF;LoadAF; \ - flags.var1.b=load(op1); \ - flags.var2.b=op2&0x07; \ - flags.result.b=(flags.var1.b >> flags.var2.b) | \ - (flags.var1.b << (8-flags.var2.b)); \ - save(op1,flags.result.b); \ - flags.type=t_RORb; \ + lf_var1b=load(op1); \ + lf_var2b=op2&0x07; \ + lf_resb=(lf_var1b >> lf_var2b) | \ + (lf_var1b << (8-lf_var2b)); \ + save(op1,lf_resb); \ + lflags.type=t_RORb; \ #define RORW(op1,op2,load,save) \ if (op2&0x0F) { \ LoadZF;LoadSF;LoadAF; \ - flags.var1.w=load(op1); \ - flags.var2.b=op2&0x0F; \ - flags.result.w=(flags.var1.w >> flags.var2.b) | \ - (flags.var1.w << (16-flags.var2.b)); \ - save(op1,flags.result.w); \ - flags.type=t_RORw; \ + lf_var1w=load(op1); \ + lf_var2b=op2&0x0F; \ + lf_resw=(lf_var1w >> lf_var2b) | \ + (lf_var1w << (16-lf_var2b)); \ + save(op1,lf_resw); \ + lflags.type=t_RORw; \ } #define RORD(op1,op2,load,save) \ if (op2) { \ LoadZF;LoadSF;LoadAF; \ - flags.var1.d=load(op1); \ - flags.var2.b=op2; \ - flags.result.d=(flags.var1.d >> flags.var2.b) | \ - (flags.var1.d << (32-flags.var2.b)); \ - save(op1,flags.result.d); \ - flags.type=t_RORd; \ + lf_var1d=load(op1); \ + lf_var2b=op2; \ + lf_resd=(lf_var1d >> lf_var2b) | \ + (lf_var1d << (32-lf_var2b)); \ + save(op1,lf_resd); \ + lflags.type=t_RORd; \ } @@ -286,176 +286,176 @@ if (op2%9) { \ LoadZF;LoadSF;LoadAF; \ Bit8u cf=get_CF(); \ - flags.var1.b=load(op1); \ - flags.var2.b=op2%9; \ - flags.type=t_RCLb; \ - flags.result.b=(flags.var1.b << flags.var2.b) | \ - (cf << (flags.var2.b-1)) | \ - (flags.var1.b >> (9-flags.var2.b)); \ - SETFLAGBIT(CF,((flags.var1.b >> (8-flags.var2.b)) & 1)); \ - SETFLAGBIT(OF,(flags.var1.b ^ flags.result.b) & 0x80); \ - save(op1,flags.result.b); \ + lf_var1b=load(op1); \ + lf_var2b=op2%9; \ + lflags.type=t_RCLb; \ + lf_resb=(lf_var1b << lf_var2b) | \ + (cf << (lf_var2b-1)) | \ + (lf_var1b >> (9-lf_var2b)); \ + SETFLAGBIT(CF,((lf_var1b >> (8-lf_var2b)) & 1)); \ + SETFLAGBIT(OF,(lf_var1b ^ lf_resb) & 0x80); \ + save(op1,lf_resb); \ } #define RCLW(op1,op2,load,save) \ if (op2%17) { \ LoadZF;LoadSF;LoadAF; \ Bit16u cf=get_CF(); \ - flags.var1.w=load(op1); \ - flags.var2.b=op2%17; \ - flags.type=t_RCLw; \ - flags.result.w=(flags.var1.w << flags.var2.b) | \ - (cf << (flags.var2.b-1)) | \ - (flags.var1.w >> (17-flags.var2.b)); \ - SETFLAGBIT(CF,((flags.var1.w >> (16-flags.var2.b)) & 1)); \ - SETFLAGBIT(OF,(flags.var1.w ^ flags.result.w) & 0x8000); \ - save(op1,flags.result.w); \ + lf_var1w=load(op1); \ + lf_var2b=op2%17; \ + lflags.type=t_RCLw; \ + lf_resw=(lf_var1w << lf_var2b) | \ + (cf << (lf_var2b-1)) | \ + (lf_var1w >> (17-lf_var2b)); \ + SETFLAGBIT(CF,((lf_var1w >> (16-lf_var2b)) & 1)); \ + SETFLAGBIT(OF,(lf_var1w ^ lf_resw) & 0x8000); \ + save(op1,lf_resw); \ } #define RCLD(op1,op2,load,save) \ if (op2) { \ LoadZF;LoadSF;LoadAF; \ Bit32u cf=get_CF(); \ - flags.var1.d=load(op1); \ - flags.var2.b=op2; \ - flags.type=t_RCLd; \ - if (flags.var2.b==1) { \ - flags.result.d=(flags.var1.d << 1) | cf; \ + lf_var1d=load(op1); \ + lf_var2b=op2; \ + lflags.type=t_RCLd; \ + if (lf_var2b==1) { \ + lf_resd=(lf_var1d << 1) | cf; \ } else { \ - flags.result.d=(flags.var1.d << flags.var2.b) | \ - (cf << (flags.var2.b-1)) | \ - (flags.var1.d >> (33-flags.var2.b)); \ + lf_resd=(lf_var1d << lf_var2b) | \ + (cf << (lf_var2b-1)) | \ + (lf_var1d >> (33-lf_var2b)); \ } \ - SETFLAGBIT(CF,((flags.var1.d >> (32-flags.var2.b)) & 1)); \ - SETFLAGBIT(OF,(flags.var1.d ^ flags.result.d) & 0x80000000); \ - save(op1,flags.result.d); \ + SETFLAGBIT(CF,((lf_var1d >> (32-lf_var2b)) & 1)); \ + SETFLAGBIT(OF,(lf_var1d ^ lf_resd) & 0x80000000); \ + save(op1,lf_resd); \ } #define RCRB(op1,op2,load,save) \ if (op2%9) { \ LoadZF;LoadSF;LoadAF; \ Bit8u cf=get_CF(); \ - flags.var1.b=load(op1); \ - flags.var2.b=op2%9; \ - flags.type=t_RCRb; \ - flags.result.b=(flags.var1.b >> flags.var2.b) | \ - (cf << (8-flags.var2.b)) | \ - (flags.var1.b << (9-flags.var2.b)); \ - save(op1,flags.result.b); \ + lf_var1b=load(op1); \ + lf_var2b=op2%9; \ + lflags.type=t_RCRb; \ + lf_resb=(lf_var1b >> lf_var2b) | \ + (cf << (8-lf_var2b)) | \ + (lf_var1b << (9-lf_var2b)); \ + save(op1,lf_resb); \ } #define RCRW(op1,op2,load,save) \ if (op2%17) { \ LoadZF;LoadSF;LoadAF; \ Bit16u cf=get_CF(); \ - flags.var1.w=load(op1); \ - flags.var2.b=op2%17; \ - flags.type=t_RCRw; \ - flags.result.w=(flags.var1.w >> flags.var2.b) | \ - (cf << (16-flags.var2.b)) | \ - (flags.var1.w << (17-flags.var2.b)); \ - save(op1,flags.result.w); \ + lf_var1w=load(op1); \ + lf_var2b=op2%17; \ + lflags.type=t_RCRw; \ + lf_resw=(lf_var1w >> lf_var2b) | \ + (cf << (16-lf_var2b)) | \ + (lf_var1w << (17-lf_var2b)); \ + save(op1,lf_resw); \ } #define RCRD(op1,op2,load,save) \ if (op2) { \ LoadZF;LoadSF;LoadAF; \ Bit32u cf=get_CF(); \ - flags.var1.d=load(op1); \ - flags.var2.b=op2; \ - flags.type=t_RCRd; \ - if (flags.var2.b==1) { \ - flags.result.d=flags.var1.d >> 1 | cf << 31; \ + lf_var1d=load(op1); \ + lf_var2b=op2; \ + lflags.type=t_RCRd; \ + if (lf_var2b==1) { \ + lf_resd=lf_var1d >> 1 | cf << 31; \ } else { \ - flags.result.d=(flags.var1.d >> flags.var2.b) | \ - (cf << (32-flags.var2.b)) | \ - (flags.var1.d << (33-flags.var2.b)); \ + lf_resd=(lf_var1d >> lf_var2b) | \ + (cf << (32-lf_var2b)) | \ + (lf_var1d << (33-lf_var2b)); \ } \ - save(op1,flags.result.d); \ + save(op1,lf_resd); \ } #define SHLB(op1,op2,load,save) \ if (!op2) break; \ - flags.var1.b=load(op1);flags.var2.b=op2; \ - flags.result.b=flags.var1.b << flags.var2.b; \ - save(op1,flags.result.b); \ - flags.type=t_SHLb; + lf_var1b=load(op1);lf_var2b=op2; \ + lf_resb=lf_var1b << lf_var2b; \ + save(op1,lf_resb); \ + lflags.type=t_SHLb; #define SHLW(op1,op2,load,save) \ if (!op2) break; \ - flags.var1.w=load(op1);flags.var2.b=op2 ; \ - flags.result.w=flags.var1.w << flags.var2.b; \ - save(op1,flags.result.w); \ - flags.type=t_SHLw; + lf_var1w=load(op1);lf_var2b=op2 ; \ + lf_resw=lf_var1w << lf_var2b; \ + save(op1,lf_resw); \ + lflags.type=t_SHLw; #define SHLD(op1,op2,load,save) \ if (!op2) break; \ - flags.var1.d=load(op1);flags.var2.b=op2; \ - flags.result.d=flags.var1.d << flags.var2.b; \ - save(op1,flags.result.d); \ - flags.type=t_SHLd; + lf_var1d=load(op1);lf_var2b=op2; \ + lf_resd=lf_var1d << lf_var2b; \ + save(op1,lf_resd); \ + lflags.type=t_SHLd; #define SHRB(op1,op2,load,save) \ if (!op2) break; \ - flags.var1.b=load(op1);flags.var2.b=op2; \ - flags.result.b=flags.var1.b >> flags.var2.b; \ - save(op1,flags.result.b); \ - flags.type=t_SHRb; + lf_var1b=load(op1);lf_var2b=op2; \ + lf_resb=lf_var1b >> lf_var2b; \ + save(op1,lf_resb); \ + lflags.type=t_SHRb; #define SHRW(op1,op2,load,save) \ if (!op2) break; \ - flags.var1.w=load(op1);flags.var2.b=op2; \ - flags.result.w=flags.var1.w >> flags.var2.b; \ - save(op1,flags.result.w); \ - flags.type=t_SHRw; + lf_var1w=load(op1);lf_var2b=op2; \ + lf_resw=lf_var1w >> lf_var2b; \ + save(op1,lf_resw); \ + lflags.type=t_SHRw; #define SHRD(op1,op2,load,save) \ if (!op2) break; \ - flags.var1.d=load(op1);flags.var2.b=op2; \ - flags.result.d=flags.var1.d >> flags.var2.b; \ - save(op1,flags.result.d); \ - flags.type=t_SHRd; + lf_var1d=load(op1);lf_var2b=op2; \ + lf_resd=lf_var1d >> lf_var2b; \ + save(op1,lf_resd); \ + lflags.type=t_SHRd; #define SARB(op1,op2,load,save) \ if (!op2) break; \ - flags.var1.b=load(op1);flags.var2.b=op2; \ - if (flags.var2.b>8) flags.var2.b=8; \ - if (flags.var1.b & 0x80) { \ - flags.result.b=(flags.var1.b >> flags.var2.b)| \ - (0xff << (8 - flags.var2.b)); \ + lf_var1b=load(op1);lf_var2b=op2; \ + if (lf_var2b>8) lf_var2b=8; \ + if (lf_var1b & 0x80) { \ + lf_resb=(lf_var1b >> lf_var2b)| \ + (0xff << (8 - lf_var2b)); \ } else { \ - flags.result.b=flags.var1.b >> flags.var2.b; \ + lf_resb=lf_var1b >> lf_var2b; \ } \ - save(op1,flags.result.b); \ - flags.type=t_SARb; + save(op1,lf_resb); \ + lflags.type=t_SARb; #define SARW(op1,op2,load,save) \ if (!op2) break; \ - flags.var1.w=load(op1);flags.var2.b=op2; \ - if (flags.var2.b>16) flags.var2.b=16; \ - if (flags.var1.w & 0x8000) { \ - flags.result.w=(flags.var1.w >> flags.var2.b)| \ - (0xffff << (16 - flags.var2.b)); \ + lf_var1w=load(op1);lf_var2b=op2; \ + if (lf_var2b>16) lf_var2b=16; \ + if (lf_var1w & 0x8000) { \ + lf_resw=(lf_var1w >> lf_var2b)| \ + (0xffff << (16 - lf_var2b)); \ } else { \ - flags.result.w=flags.var1.w >> flags.var2.b; \ + lf_resw=lf_var1w >> lf_var2b; \ } \ - save(op1,flags.result.w); \ - flags.type=t_SARw; + save(op1,lf_resw); \ + lflags.type=t_SARw; #define SARD(op1,op2,load,save) \ if (!op2) break; \ - flags.var2.b=op2;flags.var1.d=load(op1); \ - if (flags.var1.d & 0x80000000) { \ - flags.result.d=(flags.var1.d >> flags.var2.b)| \ - (0xffffffff << (32 - flags.var2.b)); \ + lf_var2b=op2;lf_var1d=load(op1); \ + if (lf_var1d & 0x80000000) { \ + lf_resd=(lf_var1d >> lf_var2b)| \ + (0xffffffff << (32 - lf_var2b)); \ } else { \ - flags.result.d=flags.var1.d >> flags.var2.b; \ + lf_resd=lf_var1d >> lf_var2b; \ } \ - save(op1,flags.result.d); \ - flags.type=t_SARd; + save(op1,lf_resd); \ + lflags.type=t_SARd; @@ -474,7 +474,7 @@ } \ SETFLAGBIT(SF,(reg_al&0x80)); \ SETFLAGBIT(ZF,(reg_al==0)); \ - flags.type=t_UNKNOWN; + lflags.type=t_UNKNOWN; #define DAS() \ @@ -490,7 +490,7 @@ } else { \ SETFLAGBIT(CF,false); \ } \ - flags.type=t_UNKNOWN; + lflags.type=t_UNKNOWN; #define AAA() \ @@ -505,7 +505,7 @@ SETFLAGBIT(CF,false); \ } \ reg_al &= 0x0F; \ - flags.type=t_UNKNOWN; + lflags.type=t_UNKNOWN; #define AAS() \ if (((reg_al & 0x0f)>9) || get_AF()) { \ @@ -519,14 +519,14 @@ SETFLAGBIT(CF,false); \ } \ reg_al &= 0x0F; \ - flags.type=t_UNKNOWN; + lflags.type=t_UNKNOWN; #define AAM(op1) \ { \ Bit8u BLAH=op1; \ reg_ah=reg_al / BLAH; \ reg_al=reg_al % BLAH; \ - flags.type=t_UNKNOWN; \ + lflags.type=t_UNKNOWN; \ SETFLAGBIT(SF,(reg_al & 0x80)); \ SETFLAGBIT(ZF,(reg_al == 0)); \ SETFLAGBIT(PF,parity_lookup[reg_al]); \ @@ -547,11 +547,11 @@ SETFLAGBIT(SF,reg_al >= 0x80); \ SETFLAGBIT(ZF,reg_al == 0); \ SETFLAGBIT(PF,parity_lookup[reg_al]); \ - flags.type=t_UNKNOWN; \ + lflags.type=t_UNKNOWN; \ } #define MULB(op1,load,save) \ - flags.type=t_MUL; \ + lflags.type=t_MUL; \ reg_ax=reg_al*load(op1); \ if (reg_ax & 0xff00) { \ SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ @@ -564,7 +564,7 @@ Bitu tempu=(Bitu)reg_ax*(Bitu)(load(op1)); \ reg_ax=(Bit16u)(tempu); \ reg_dx=(Bit16u)(tempu >> 16); \ - flags.type=t_MUL; \ + lflags.type=t_MUL; \ if (reg_dx) { \ SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ } else { \ @@ -577,7 +577,7 @@ Bit64u tempu=(Bit64u)reg_eax*(Bit64u)(load(op1)); \ reg_eax=(Bit32u)(tempu); \ reg_edx=(Bit32u)(tempu >> 32); \ - flags.type=t_MUL; \ + lflags.type=t_MUL; \ if (reg_edx) { \ SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ } else { \ @@ -654,7 +654,7 @@ #define IMULB(op1,load,save) \ { \ - flags.type=t_MUL; \ + lflags.type=t_MUL; \ reg_ax=((Bit8s)reg_al) * ((Bit8s)(load(op1))); \ if ((reg_ax & 0xff80)==0xff80 || \ (reg_ax & 0xff80)==0x0000) { \ @@ -670,7 +670,7 @@ Bits temps=((Bit16s)reg_ax)*((Bit16s)(load(op1))); \ reg_ax=(Bit16s)(temps); \ reg_dx=(Bit16s)(temps >> 16); \ - flags.type=t_MUL; \ + lflags.type=t_MUL; \ if (((temps & 0xffff8000)==0xffff8000 || \ (temps & 0xffff8000)==0x0000)) { \ SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ @@ -685,7 +685,7 @@ ((Bit64s)((Bit32s)(load(op1)))); \ reg_eax=(Bit32u)(temps); \ reg_edx=(Bit32u)(temps >> 32); \ - flags.type=t_MUL; \ + lflags.type=t_MUL; \ if ((reg_edx==0xffffffff) && \ (reg_eax & 0x80000000) ) { \ SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ @@ -702,7 +702,7 @@ Bits res; \ res=((Bit16s)op2) * ((Bit16s)op3); \ save(op1,res & 0xffff); \ - flags.type=t_MUL; \ + lflags.type=t_MUL; \ if ((res> -32768) && (res<32767)) { \ SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ } else { \ @@ -714,7 +714,7 @@ { \ Bit64s res=((Bit64s)((Bit32s)op2))*((Bit64s)((Bit32s)op3)); \ save(op1,(Bit32s)res); \ - flags.type=t_MUL; \ + lflags.type=t_MUL; \ if ((res>-((Bit64s)(2147483647)+1)) && \ (res<(Bit64s)2147483647)) { \ SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ @@ -827,39 +827,39 @@ #define DSHLW(op1,op2,op3,load,save) \ Bit8u val=op3 & 0x1F; \ if (!val) break; \ - flags.var2.b=val;flags.var1.d=(load(op1)<<16)|op2; \ - Bit32u tempd=flags.var1.d << flags.var2.b; \ - if (flags.var2.b>16) tempd |= (op2 << (flags.var2.b - 16)); \ - flags.result.w=(Bit16u)(tempd >> 16); \ - save(op1,flags.result.w); \ - flags.type=t_DSHLw; + lf_var2b=val;lf_var1d=(load(op1)<<16)|op2; \ + Bit32u tempd=lf_var1d << lf_var2b; \ + if (lf_var2b>16) tempd |= (op2 << (lf_var2b - 16)); \ + lf_resw=(Bit16u)(tempd >> 16); \ + save(op1,lf_resw); \ + lflags.type=t_DSHLw; #define DSHLD(op1,op2,op3,load,save) \ Bit8u val=op3 & 0x1F; \ if (!val) break; \ - flags.var2.b=val;flags.var1.d=load(op1); \ - flags.result.d=(flags.var1.d << flags.var2.b) | (op2 >> (32-flags.var2.b)); \ - save(op1,flags.result.d); \ - flags.type=t_DSHLd; + lf_var2b=val;lf_var1d=load(op1); \ + lf_resd=(lf_var1d << lf_var2b) | (op2 >> (32-lf_var2b)); \ + save(op1,lf_resd); \ + lflags.type=t_DSHLd; /* double-precision shift right has high bits in second argument */ #define DSHRW(op1,op2,op3,load,save) \ Bit8u val=op3 & 0x1F; \ if (!val) break; \ - flags.var2.b=val;flags.var1.d=(op2<<16)|load(op1); \ - Bit32u tempd=flags.var1.d >> flags.var2.b; \ - if (flags.var2.b>16) tempd |= (op2 << (32-flags.var2.b )); \ - flags.result.w=(Bit16u)(tempd); \ - save(op1,flags.result.w); \ - flags.type=t_DSHRw; + lf_var2b=val;lf_var1d=(op2<<16)|load(op1); \ + Bit32u tempd=lf_var1d >> lf_var2b; \ + if (lf_var2b>16) tempd |= (op2 << (32-lf_var2b )); \ + lf_resw=(Bit16u)(tempd); \ + save(op1,lf_resw); \ + lflags.type=t_DSHRw; #define DSHRD(op1,op2,op3,load,save) \ Bit8u val=op3 & 0x1F; \ if (!val) break; \ - flags.var2.b=val;flags.var1.d=load(op1); \ - flags.result.d=(flags.var1.d >> flags.var2.b) | (op2 << (32-flags.var2.b)); \ - save(op1,flags.result.d); \ - flags.type=t_DSHRd; + lf_var2b=val;lf_var1d=load(op1); \ + lf_resd=(lf_var1d >> lf_var2b) | (op2 << (32-lf_var2b)); \ + save(op1,lf_resd); \ + lflags.type=t_DSHRd; #define BSWAP(op1) \ op1 = (op1>>24)|((op1>>8)&0xFF00)|((op1<<8)&0xFF0000)|((op1<<24)&0xFF000000); diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index 2ab6ca18..79be9fba 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -16,6 +16,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#if !defined __LAZYFLAGS_H +#define __LAZYFLAG_H + //Flag Handling Bitu get_CF(void); Bitu get_AF(void); @@ -26,22 +29,48 @@ Bitu get_PF(void); void FillFlags(void); +#include "regs.h" + +struct LazyFlags { + GenReg32 var1,var2,res; + Bitu type; + Bitu prev_type; + Bitu oldcf; +}; + +extern LazyFlags lfags; + +#define lf_var1b lflags.var1.byte[BL_INDEX] +#define lf_var2b lflags.var2.byte[BL_INDEX] +#define lf_resb lflags.res.byte[BL_INDEX] + +#define lf_var1w lflags.var1.word[W_INDEX] +#define lf_var2w lflags.var2.word[W_INDEX] +#define lf_resw lflags.res.word[W_INDEX] + +#define lf_var1d lflags.var1.dword[DW_INDEX] +#define lf_var2d lflags.var2.dword[DW_INDEX] +#define lf_resd lflags.res.dword[DW_INDEX] + + +extern LazyFlags lflags; + #define SETFLAGSb(FLAGB) \ { \ SETFLAGBIT(OF,get_OF()); \ - flags.type=t_UNKNOWN; \ - CPU_SetFlags((flags.word&0xffffff00)|((FLAGB) & 0xff)); \ + lflags.type=t_UNKNOWN; \ + CPU_SetFlags((reg_flags&0xffffff00)|((FLAGB) & 0xff)); \ } #define SETFLAGSw(FLAGW) \ { \ - flags.type=t_UNKNOWN; \ + lflags.type=t_UNKNOWN; \ CPU_SetFlagsw(FLAGW); \ } #define SETFLAGSd(FLAGD) \ { \ - flags.type=t_UNKNOWN; \ + lflags.type=t_UNKNOWN; \ CPU_SetFlags(FLAGD); \ } @@ -82,3 +111,11 @@ enum { t_LASTFLAG }; +INLINE void SetTypeCF(void) { + if (lflags.type!=t_CF) { + lflags.prev_type=lflags.type; + lflags.type=t_CF; + } +} + +#endif \ No newline at end of file From 45c1f1c663e74adfa1b29c0a9414f99871b16e83 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 26 Oct 2003 19:05:01 +0000 Subject: [PATCH 1298/4131] Changes for new flag word Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1379 --- src/debug/debug.cpp | 20 ++++++++++---------- src/ints/dpmi.cpp | 34 +++++++++++++++++----------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index c5bd13b8..125375a4 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -616,28 +616,28 @@ static void DrawRegisters(void) { /*Individual flags*/ - SetColor((flags.word ^ oldflags)&FLAG_CF); + SetColor((reg_flags ^ oldflags)&FLAG_CF); mvwprintw (dbg.win_reg,1,53,"%01X",GETFLAG(CF) ? 1:0); - SetColor((flags.word ^ oldflags)&FLAG_ZF); + SetColor((reg_flags ^ oldflags)&FLAG_ZF); mvwprintw (dbg.win_reg,1,56,"%01X",GETFLAG(ZF) ? 1:0); - SetColor((flags.word ^ oldflags)&FLAG_SF); + SetColor((reg_flags ^ oldflags)&FLAG_SF); mvwprintw (dbg.win_reg,1,59,"%01X",GETFLAG(SF) ? 1:0); - SetColor((flags.word ^ oldflags)&FLAG_OF); + SetColor((reg_flags ^ oldflags)&FLAG_OF); mvwprintw (dbg.win_reg,1,62,"%01X",GETFLAG(OF) ? 1:0); - SetColor((flags.word ^ oldflags)&FLAG_AF); + SetColor((reg_flags ^ oldflags)&FLAG_AF); mvwprintw (dbg.win_reg,1,65,"%01X",GETFLAG(AF) ? 1:0); - SetColor((flags.word ^ oldflags)&FLAG_PF); + SetColor((reg_flags ^ oldflags)&FLAG_PF); mvwprintw (dbg.win_reg,1,68,"%01X",GETFLAG(PF) ? 1:0); - SetColor((flags.word ^ oldflags)&FLAG_DF); + SetColor((reg_flags ^ oldflags)&FLAG_DF); mvwprintw (dbg.win_reg,1,71,"%01X",GETFLAG(DF) ? 1:0); - SetColor((flags.word ^ oldflags)&FLAG_IF); + SetColor((reg_flags ^ oldflags)&FLAG_IF); mvwprintw (dbg.win_reg,1,74,"%01X",GETFLAG(IF) ? 1:0); - SetColor((flags.word ^ oldflags)&FLAG_TF); + SetColor((reg_flags ^ oldflags)&FLAG_TF); mvwprintw (dbg.win_reg,1,77,"%01X",GETFLAG(TF) ? 1:0); - oldflags=flags.word; + oldflags=reg_flags; if (cpu.pmode) { if (cpu.code.big) mvwprintw(dbg.win_reg,0,76,"Pr32"); diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index 79287516..88beadc5 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -549,7 +549,7 @@ void DPMI::CopyRegistersToBuffer(PhysPt data) mem_writed(data+0x14, reg_edx); mem_writed(data+0x18, reg_ecx); mem_writed(data+0x1C, reg_eax); - mem_writew(data+0x20, flags.word); + mem_writew(data+0x20, reg_flags); mem_writew(data+0x22, SegValue(es)); mem_writew(data+0x24, SegValue(ds)); mem_writew(data+0x26, SegValue(fs)); @@ -702,7 +702,7 @@ void DPMI::CreateException(Bitu num, Bitu errorCode) if (dpmi.client.bit32) { CPU_Push32(SegValue(ss)); CPU_Push32(reg_esp); - CPU_Push32(flags.word); + CPU_Push32(reg_flags); CPU_Push32(SegValue(cs)); CPU_Push32(reg_eip-2); // FIXME: Fake ! CPU_Push32(errorCode); @@ -711,7 +711,7 @@ void DPMI::CreateException(Bitu num, Bitu errorCode) } else { CPU_Push16(SegValue(ss)); CPU_Push16(reg_sp); - CPU_Push16(flags.word); + CPU_Push16(reg_flags); CPU_Push16(SegValue(cs)); CPU_Push16(reg_ip-2); // FIXME: Fake ! CPU_Push16(errorCode); @@ -834,7 +834,7 @@ Bitu DPMI::RealModeCallback(void) CPU_SetSegGeneral(ss,dpmi.protStackSelector[dpmi.protStackCurrent++]); reg_esp = DPMI_PROTMODE_STACKSIZE; // prepare stack for iret - if (dpmi.client.bit32) CPU_Push32(flags.word); else CPU_Push16(flags.word); + if (dpmi.client.bit32) CPU_Push32(reg_flags); else CPU_Push16(reg_flags); // Setup cs:ip to return to DPMI_ReturnFromRealModeCallback CPU_SetSegGeneral(cs,GDT_CODE); reg_eip = RealOff(CALLBACK_RealPointer(callback.rmCallbackReturn)); @@ -842,7 +842,7 @@ Bitu DPMI::RealModeCallback(void) SetVirtualIntFlag(false); SETFLAGBIT(IF,false); SETFLAGBIT(TF,false); - CPU_Push32(flags.word); + CPU_Push32(reg_flags); CPU_CALL(dpmi.client.bit32,dpmi.rmCallback[num].codeSelector,dpmi.rmCallback[num].codeOffset); return 0; }; @@ -893,7 +893,7 @@ Bitu DPMI::CallRealIRETFrame(void) // Provide Stack ProvideRealModeStack(prStack,toCopy); // Push flags - CPU_Push16(flags.word); + CPU_Push16(reg_flags); // Setup IP Bitu newCS = mem_readw(data+0x2C); Bitu newIP = mem_readw(data+0x2A); @@ -949,7 +949,7 @@ Bitu DPMI::SimulateInt(void) reg_ip = RealOff(CALLBACK_RealPointer(callback.simintReturn)); // Push flags from structure on stack DPMI_LOG("DPMI: SimInt1: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_esp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); - flags.word = mem_readw(data+0x20); + reg_flags = mem_readw(data+0x20); Interrupt(num); DPMI_LOG("DPMI: SimInt2: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_esp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); return 0; @@ -1011,7 +1011,7 @@ Bitu DPMI::ptorHandler(void) // if (num==0x0F) DPMI_LOG("DPMI: INT %02X %04X called.",num,reg_ax); // Prepare flags for real int - // CPU_SetFlagsw(flags.word & 0x3ED5); // 0011111011010101b + // CPU_SetFlagsw(reg_flags & 0x3ED5); // 0011111011010101b Interrupt(num); return 0; } @@ -1039,11 +1039,11 @@ Bitu DPMI::ptorHandlerReturn(void) // Change flags on stack to reflect possible results from ints if (dpmi.client.bit32) { Bit32u oldFlags = mem_readd(SegPhys(ss)+reg_esp+8) & ~FLAG_MASK;// leave only flags that cannot be changed by int - Bit32u userFlags = flags.word & FLAG_MASK; // Mask out illegal flags not to change by int (0011111011010101b) + Bit32u userFlags = reg_flags & FLAG_MASK; // Mask out illegal flags not to change by int (0011111011010101b) mem_writed(SegPhys(ss)+reg_esp+8,oldFlags|userFlags); } else { Bit16u oldFlags = mem_readw(SegPhys(ss)+reg_sp+4) & ~FLAG_MASK; // leave only flags that cannot be changed by int - Bit16u userFlags = flags.word & FLAG_MASK; // Mask out illegal flags not to change by int (0011111011010101b) + Bit16u userFlags = reg_flags & FLAG_MASK; // Mask out illegal flags not to change by int (0011111011010101b) mem_writew(SegPhys(ss)+reg_sp+4,oldFlags|userFlags); }; SetVirtualIntFlag(true); @@ -1096,7 +1096,7 @@ Bitu DPMI::Int21HandlerReturn(void) reg_esp = PopStack(); CPU_SetSegGeneral(ss,PopStack()); // Set carry flag - DPMI_CALLBACK_SCF(flags.word & 1); + DPMI_CALLBACK_SCF(reg_flags & 1); DPMI_LOG("DPMI: INT 21 RETURN"); SetVirtualIntFlag(true); CPU_JMP(dpmi.client.bit32,newcs,reg_eip); @@ -1121,7 +1121,7 @@ Bitu DPMI::HWIntDefaultHandler() // originalroutine aufrufen dpmi.rmCallback[index].stop = false; PrepareReflectToReal(num); - CPU_Push16(flags.word); + CPU_Push16(reg_flags); SetVirtualIntFlag(false); SETFLAGBIT(IF,false); SETFLAGBIT(TF,false); @@ -1146,7 +1146,7 @@ Bitu DPMI::HWIntDefaultHandler() SetVirtualIntFlag(false); SETFLAGBIT(IF,false); SETFLAGBIT(TF,false); - CPU_Push16(flags.word); + CPU_Push16(reg_flags); CPU_CALL(false,RealSeg(vec),RealOff(vec)); } } else { @@ -1156,7 +1156,7 @@ Bitu DPMI::HWIntDefaultHandler() if (dpmi.rmCallback[index].stop) { dpmi.rmCallback[index].stop = false; PrepareReflectToReal(num); - CPU_Push16(flags.word); + CPU_Push16(reg_flags); SetVirtualIntFlag(false); SETFLAGBIT(IF,false); SETFLAGBIT(TF,false); @@ -1173,7 +1173,7 @@ Bitu DPMI::HWIntDefaultHandler() } else { // kein spezieller Protmode handler - Rufe originalroutine auf PrepareReflectToReal(num); - CPU_Push16(flags.word); + CPU_Push16(reg_flags); SetVirtualIntFlag(false); SETFLAGBIT(IF,false); SETFLAGBIT(TF,false); @@ -1203,7 +1203,7 @@ void DPMI::SaveRegisterState(Bitu num) save_edi[num] = reg_edi; save_ebp[num] = reg_ebp; save_esp[num] = reg_esp; - save_fl [num] = flags.word; + save_fl [num] = reg_flags; }; void DPMI::LoadRegisterState(Bitu num) @@ -1218,7 +1218,7 @@ void DPMI::LoadRegisterState(Bitu num) reg_edx = save_edx[num]; reg_esi = save_esi[num]; reg_edi = save_edi[num]; - flags.word = save_fl [num]; + reg_flags = save_fl [num]; }; Bitu DPMI::EnterProtMode(void) { From 9f6a6bc5cffd972d30ed1f084b51296884a51169 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 27 Oct 2003 13:19:19 +0000 Subject: [PATCH 1299/4131] New IO Functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1380 --- include/inout.h | 58 +++++++----- src/cpu/core_normal/prefix_0f.h | 14 +++ src/cpu/core_normal/prefix_66.h | 30 ++----- src/cpu/core_normal/prefix_none.h | 34 +++---- src/cpu/core_normal/string.h | 15 ++-- src/hardware/iohandler.cpp | 141 +++++++++++++++++++++--------- 6 files changed, 168 insertions(+), 124 deletions(-) diff --git a/include/inout.h b/include/inout.h index 91f00a81..9bf30192 100644 --- a/include/inout.h +++ b/include/inout.h @@ -16,33 +16,43 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -typedef Bit8u (IO_ReadHandler)(Bit32u port); -typedef void (IO_WriteHandler)(Bit32u port,Bit8u value); +typedef Bit8u (IO_ReadBHandler)(Bit32u port); +typedef Bit16u (IO_ReadWHandler)(Bit32u port); +typedef Bit32u (IO_ReadDHandler)(Bit32u port); +typedef void (IO_WriteBHandler)(Bit32u port,Bit8u value); +typedef void (IO_WriteWHandler)(Bit32u port,Bit16u value); +typedef void (IO_WriteDHandler)(Bit32u port,Bit32u value); -#define IO_MAX 1024 +void IO_RegisterReadBHandler(Bitu port,IO_ReadBHandler * handler); +void IO_RegisterReadWHandler(Bitu port,IO_ReadWHandler * handler); +void IO_RegisterReadDHandler(Bitu port,IO_ReadDHandler * handler); -struct IO_ReadBlock{ - IO_ReadHandler * handler; - char * name; -}; +void IO_RegisterWriteBHandler(Bitu port,IO_WriteBHandler * handler); +void IO_RegisterWriteWHandler(Bitu port,IO_WriteWHandler * handler); +void IO_RegisterWriteDHandler(Bitu port,IO_WriteDHandler * handler); -struct IO_WriteBlock{ - IO_WriteHandler * handler; - char * name; -}; +void IO_FreeReadHandler(Bitu port); +void IO_FreeWriteHandler(Bitu port); -extern IO_ReadBlock IO_ReadTable[IO_MAX]; -extern IO_WriteBlock IO_WriteTable[IO_MAX]; - - - -void IO_Write(Bitu num,Bit8u val); -Bit8u IO_Read(Bitu num); - -void IO_RegisterReadHandler(Bit32u port,IO_ReadHandler * handler,char * name); -void IO_RegisterWriteHandler(Bit32u port,IO_WriteHandler * handler,char * name); - -void IO_FreeReadHandler(Bit32u port); -void IO_FreeWriteHandler(Bit32u port); +void IO_WriteB(Bitu port,Bit8u val); +Bit8u IO_ReadB(Bitu port); +void IO_WriteW(Bitu port,Bit16u val); +Bit16u IO_ReadW(Bitu port); +void IO_WriteD(Bitu port,Bit32u val); +Bit32u IO_ReadD(Bitu port); + +INLINE void IO_Write(Bitu port,Bit8u val) { + IO_WriteB(port,val); +} +INLINE Bit8u IO_Read(Bitu port){ + return IO_ReadB(port); +} + +INLINE void IO_RegisterReadHandler(Bitu port,IO_ReadBHandler * handler,char * name) { + IO_RegisterReadBHandler(port,handler); +} +INLINE void IO_RegisterWriteHandler(Bitu port,IO_WriteBHandler * handler,char * name) { + IO_RegisterWriteBHandler(port,handler); +} diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index ad397e44..d4923ffb 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -138,6 +138,19 @@ } } break; + CASE_0F_B(0x21) /* MOV Rd,DRx */ + { + GetRM; + Bitu which=(rm >> 3) & 7; + LOG_MSG("MOV REG,DR%d",which); + if (rm >= 0xc0 ) { + GetEArd; + } else { + GetEAa; + LOG(LOG_CPU,LOG_ERROR)("MOV XXX,DR% with non-register",which); + } + } + break; CASE_0F_B(0x22) /* MOV CRx,Rd */ { GetRM; @@ -155,6 +168,7 @@ { GetRM; Bitu which=(rm >> 3) & 7; + LOG_MSG("MOV DR%d,REG",which); if (rm >= 0xc0 ) { GetEArd; } else { diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 677a4391..b64b65c0 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -513,23 +513,11 @@ CASE_D(0xd3) /* GRP2 Ed,CL */ GRP2D(reg_cl);break; CASE_D(0xe5) /* IN EAX,Ib */ - { - Bit16u port=Fetchb(); - reg_eax=IO_Read(port) | - (IO_Read(port+1) << 8 ) | - (IO_Read(port+2) << 16 ) | - (IO_Read(port+3) << 24 ); - break; - } + reg_eax=IO_ReadD(Fetchb()); + break; CASE_D(0xe7) /* OUT Ib,EAX */ - { - Bit16u port=Fetchb(); - IO_Write(port+0,(Bit8u)(reg_eax >> 0)); - IO_Write(port+1,(Bit8u)(reg_eax >> 8)); - IO_Write(port+2,(Bit8u)(reg_eax >> 16)); - IO_Write(port+3,(Bit8u)(reg_eax >> 24)); - break; - } + IO_WriteD(Fetchb(),reg_eax); + break; CASE_D(0xe8) /* CALL Jd */ { Bit32s newip=Fetchds(); @@ -553,16 +541,10 @@ break; } CASE_D(0xed) /* IN EAX,DX */ - reg_eax=IO_Read(reg_dx) | - (IO_Read(reg_dx+1) << 8) | - (IO_Read(reg_dx+2) << 16) | - (IO_Read(reg_dx+3) << 24); + reg_eax=IO_ReadD(reg_dx); break; CASE_D(0xef) /* OUT DX,EAX */ - IO_Write(reg_dx,(Bit8u)(reg_eax>>0)); - IO_Write(reg_dx+1,(Bit8u)(reg_eax>>8)); - IO_Write(reg_dx+2,(Bit8u)(reg_eax>>16)); - IO_Write(reg_dx+3,(Bit8u)(reg_eax>>24)); + IO_WriteD(reg_dx,reg_eax); break; CASE_D(0xf7) /* GRP3 Ed(,Id) */ { diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 78800206..fa097f1b 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -901,31 +901,17 @@ break; } CASE_B(0xe4) /* IN AL,Ib */ - { - Bit16u port=Fetchb(); - reg_al=IO_Read(port); - break; - } + reg_al=IO_ReadB(Fetchb()); + break; CASE_W(0xe5) /* IN AX,Ib */ - { - Bit16u port=Fetchb(); - reg_al=IO_Read(port); - reg_ah=IO_Read(port+1); - break; - } + reg_ax=IO_ReadW(Fetchb()); + break; CASE_B(0xe6) /* OUT Ib,AL */ - { - Bit16u port=Fetchb(); - IO_Write(port,reg_al); - break; - } + IO_WriteB(Fetchb(),reg_al); + break; CASE_W(0xe7) /* OUT Ib,AX */ - { - Bit16u port=Fetchb(); - IO_Write(port,reg_al); - IO_Write(port+1,reg_ah); - break; - } + IO_WriteW(Fetchb(),reg_ax); + break; CASE_W(0xe8) /* CALL Jw */ { Bit16s newip=Fetchws(); @@ -956,9 +942,9 @@ reg_al=IO_Read(reg_dx);reg_ah=IO_Read(reg_dx+1); break; CASE_B(0xee) /* OUT DX,AL */ - IO_Write(reg_dx,reg_al);break; + IO_WriteB(reg_dx,reg_al);break; CASE_W(0xef) /* OUT DX,AX */ - IO_Write(reg_dx,reg_al);IO_Write(reg_dx+1,reg_ah);break; + IO_WriteW(reg_dx,reg_ax);break; CASE_B(0xf0) /* LOCK */ LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK"); break; diff --git a/src/cpu/core_normal/string.h b/src/cpu/core_normal/string.h index 4fce8638..00d70c0c 100644 --- a/src/cpu/core_normal/string.h +++ b/src/cpu/core_normal/string.h @@ -50,39 +50,34 @@ static void DoString(STRING_OP type) { if (count) switch (type) { case R_OUTSB: for (;count>0;count--) { - IO_Write(reg_dx,LoadMb(si_base+si_index)); + IO_WriteB(reg_dx,LoadMb(si_base+si_index)); si_index=(si_index+add_index) & add_mask; } break; case R_OUTSW: add_index<<=1; for (;count>0;count--) { - IO_Write(reg_dx,LoadMb(si_base+si_index)); - IO_Write(reg_dx+1,LoadMb(si_base+si_index+1)); + IO_WriteW(reg_dx,LoadMw(si_base+si_index)); si_index=(si_index+add_index) & add_mask; } break; case R_OUTSD: add_index<<=2; for (;count>0;count--) { - IO_Write(reg_dx,LoadMb(si_base+si_index)); - IO_Write(reg_dx+1,LoadMb(si_base+si_index+1)); - IO_Write(reg_dx+2,LoadMb(si_base+si_index+2)); - IO_Write(reg_dx+3,LoadMb(si_base+si_index+3)); + IO_WriteD(reg_dx,LoadMd(si_base+si_index)); si_index=(si_index+add_index) & add_mask; } break; case R_INSB: for (;count>0;count--) { - SaveMb(di_base+di_index,IO_Read(reg_dx)); + SaveMb(di_base+di_index,IO_ReadB(reg_dx)); di_index=(di_index+add_index) & add_mask; } break; case R_INSW: add_index<<=1; for (;count>0;count--) { - SaveMb(di_base+di_index,IO_Read(reg_dx)); - SaveMb(di_base+di_index+1,IO_Read(reg_dx+1)); + SaveMw(di_base+di_index,IO_ReadW(reg_dx)); di_index=(di_index+add_index) & add_mask; } break; diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 6e2429eb..be213f39 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -19,71 +19,128 @@ #include "dosbox.h" #include "inout.h" -IO_ReadBlock IO_ReadTable[IO_MAX]; -IO_WriteBlock IO_WriteTable[IO_MAX]; +#define IO_MAX 1024 -void IO_Write(Bitu num,Bit8u val) { - if (num(val),port); - IO_RegisterWriteHandler(port,&IO_WriteBlocked,"Blocked Write"); + io.write_b[port]=IO_WriteBBlocked; +} +void IO_WriteDefaultW(Bit32u port,Bit16u val) { + io.write_b[port](port,(Bit8u)val); + io.write_b[port+1](port+1,(Bit8u)(val>>8)); +} +void IO_WriteDefaultD(Bit32u port,Bit32u val) { + io.write_b[port](port,(Bit8u)val); + io.write_b[port+1](port+1,(Bit8u)(val>>8)); + io.write_b[port+2](port+2,(Bit8u)(val>>16)); + io.write_b[port+3](port+3,(Bit8u)(val>>24)); +} + +void IO_RegisterReadBHandler(Bitu port,IO_ReadBHandler * handler) { + if (port>=IO_MAX) return; + io.read_b[port]=handler; +} +void IO_RegisterReadWHandler(Bitu port,IO_ReadWHandler * handler) { + if (port>=IO_MAX) return; + io.read_w[port]=handler; +} +void IO_RegisterReadDHandler(Bitu port,IO_ReadDHandler * handler) { + if (port>=IO_MAX) return; + io.read_d[port]=handler; +} +void IO_RegisterWriteBHandler(Bitu port,IO_WriteBHandler * handler) { + if (port>=IO_MAX) return; + io.write_b[port]=handler; +} +void IO_RegisterWriteWHandler(Bitu port,IO_WriteWHandler * handler) { + if (port>=IO_MAX) return; + io.write_w[port]=handler; +} +void IO_RegisterWriteDHandler(Bitu port,IO_WriteDHandler * handler) { + if (port>=IO_MAX) return; + io.write_d[port]=handler; } -void IO_RegisterReadHandler(Bit32u port,IO_ReadHandler * handler,char * name) { - if (port=IO_MAX) return; + io.read_b[port]=IO_ReadDefaultB; + io.read_w[port]=IO_ReadDefaultW; + io.read_d[port]=IO_ReadDefaultD; } - -void IO_RegisterWriteHandler(Bit32u port,IO_WriteHandler * handler,char * name) { - if (port=IO_MAX) return; + io.write_b[port]=IO_WriteDefaultB; + io.write_w[port]=IO_WriteDefaultW; + io.write_d[port]=IO_WriteDefaultD; } - -void IO_FreeReadHandler(Bit32u port) { - if (port Date: Mon, 27 Oct 2003 14:09:41 +0000 Subject: [PATCH 1300/4131] removed core_16 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1381 --- configure.in | 1 - 1 file changed, 1 deletion(-) diff --git a/configure.in b/configure.in index ee8f53c0..5f99ba8d 100644 --- a/configure.in +++ b/configure.in @@ -141,7 +141,6 @@ AC_OUTPUT([ Makefile src/Makefile src/cpu/Makefile -src/cpu/core_16/Makefile src/cpu/core_full/Makefile src/cpu/core_normal/Makefile src/debug/Makefile From 87216faa9b27ca75f84934caea569ccf4e002e9e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Oct 2003 14:16:59 +0000 Subject: [PATCH 1301/4131] Added patch 826821 from phearbear Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1382 --- include/support.h | 3 +++ src/dos/drive_cache.cpp | 8 ++++---- src/dos/drives.cpp | 2 +- src/shell/shell_batch.cpp | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/include/support.h b/include/support.h index 8e260588..1e850f14 100644 --- a/include/support.h +++ b/include/support.h @@ -33,6 +33,9 @@ //#define nocasestrcmp(a,b) stricmp(a,b) #endif +#ifdef HAVE_STRINGS_H +#include +#endif void strreplace(char * str,char o,char n); char *ltrim(char *str); diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 4319c246..bdf363a8 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.27 2003-10-09 13:49:48 finsterr Exp $ */ +/* $Id: drive_cache.cpp,v 1.28 2003-10-27 14:16:59 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -162,7 +162,7 @@ char* DOS_Drive_Cache::GetExpandName(const char* path) work[0] = 0; strcpy (dir,path); - char* pos = strrchr(path,CROSS_FILESPLIT); + const char* pos = strrchr(path,CROSS_FILESPLIT); if (pos) dir[pos-path+1] = 0; CFileInfo* dirInfo = FindDirInfo(dir, work); @@ -183,7 +183,7 @@ void DOS_Drive_Cache::AddEntry(const char* path, bool checkExists) char expand [CROSS_LEN]; CFileInfo* dir = FindDirInfo(path,expand); - char* pos = strrchr(path,CROSS_FILESPLIT); + const char* pos = strrchr(path,CROSS_FILESPLIT); if (pos) { strcpy(file,pos+1); @@ -435,7 +435,7 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* char dir [CROSS_LEN]; char work [CROSS_LEN]; const char* start = path; - char* pos; + const char* pos; CFileInfo* curDir = dirBase; Bit16u id; diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index 65d6483f..ea712f0e 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -27,7 +27,7 @@ bool WildFileCmp(const char * file, const char * wild) char file_ext[4]; char wild_name[9]; char wild_ext[4]; - char * find_ext; + const char * find_ext; Bitu r; strcpy(file_name," "); diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index c927e889..538f3e30 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -89,7 +89,7 @@ emptyline: if (!first) continue; *first++=0; std::string temp; if (shell->GetEnvStr(cmd_read,temp)) { - char * equals=strchr(temp.c_str(),'='); + const char * equals=strchr(temp.c_str(),'='); if (!equals) continue; equals++; strcpy(cmd_write,equals); From 7180399a9842a0cf4defe8cf8208f5af9a93ff88 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 27 Oct 2003 15:36:21 +0000 Subject: [PATCH 1302/4131] Added mode 0x103 and fixed bug with vertical blank start. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1383 --- src/ints/int10_modes.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 1fc3d5b6..7cfba564 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -38,6 +38,8 @@ VideoModeBlock ModeList[]={ { 0x100 ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, { 0x101 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, +{ 0x103 ,M_LIN8 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, + { 0x150 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE | _VGA_LINE_DOUBLE }, { 0x151 ,M_LIN8 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE | _VGA_LINE_DOUBLE }, @@ -272,7 +274,7 @@ foundmode: /* Vertical Blank Start */ IO_Write(crtc_base,0x15);IO_Write(crtc_base+1,(CurMode->vdispend+8)); overflow|=((CurMode->vdispend+8) & 0x100) >> 5; - max_scanline|=((CurMode->vdispend+8) & 0x200) >> 3; + max_scanline|=((CurMode->vdispend+8) & 0x200) >> 4; ver_overflow|=((CurMode->vdispend+8) & 0x400) >> 8; /* Vertical Retrace End */ IO_Write(crtc_base,0x16);IO_Write(crtc_base+1,(CurMode->vtotal-8)); From def42bde5fc91243155722044fc9165a392ab520 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 27 Oct 2003 17:18:27 +0000 Subject: [PATCH 1303/4131] added function 0x0301 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1384 --- src/ints/dpmi.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index 88beadc5..2aa538ad 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -220,7 +220,7 @@ public: // Real mode reflection callbacks void PrepareReflectToReal (Bitu num); - Bitu CallRealIRETFrame (void); + Bitu CallRealIRETFrame (bool callAsInt); Bitu CallRealIRETFrameReturn (void); Bitu SimulateInt (void); Bitu SimulateIntReturn (void); @@ -874,7 +874,7 @@ Bitu DPMI::RealModeCallbackReturn(void) static Bitu count = 0; -Bitu DPMI::CallRealIRETFrame(void) +Bitu DPMI::CallRealIRETFrame(bool callAsInt) { Bitu calledIP = mem_readd(SegPhys(ss)+reg_esp); Bitu calledCS = mem_readd(SegPhys(ss)+reg_esp+4); @@ -893,7 +893,7 @@ Bitu DPMI::CallRealIRETFrame(void) // Provide Stack ProvideRealModeStack(prStack,toCopy); // Push flags - CPU_Push16(reg_flags); + if (callAsInt) CPU_Push16(reg_flags); // Setup IP Bitu newCS = mem_readw(data+0x2C); Bitu newIP = mem_readw(data+0x2A); @@ -1758,8 +1758,11 @@ Bitu DPMI::Int31Handler(void) case 0x0300:// Simulate Real Mode Interrupt SimulateInt(); break; + case 0x0301:// Call Real Mode Procedure With RET Frame + CallRealIRETFrame(false); + break; case 0x0302:// Call Real Mode Procedure With IRET Frame - CallRealIRETFrame(); + CallRealIRETFrame(true); break; case 0x0303:{//Allocate Real Mode Callback Address Bitu num = 0; @@ -2133,7 +2136,7 @@ Bitu DPMI::Int2fHandler(void) static Bitu DPMI_ExceptionReturn(void) { if (activeDPMI) return activeDPMI->ExceptionReturn(); return 0;}; static Bitu DPMI_RealModeCallback(void) { if (activeDPMI) return activeDPMI->RealModeCallback(); return 0;}; static Bitu DPMI_RealModeCallbackReturn(void) { if (activeDPMI) return activeDPMI->RealModeCallbackReturn(); return 0;}; -static Bitu DPMI_CallRealIRETFrame(void) { if (activeDPMI) return activeDPMI->CallRealIRETFrame(); return 0;}; +static Bitu DPMI_CallRealIRETFrame(void) { if (activeDPMI) return activeDPMI->CallRealIRETFrame(true); return 0;}; static Bitu DPMI_CallRealIRETFrameReturn(void) { if (activeDPMI) return activeDPMI->CallRealIRETFrameReturn(); return 0;}; static Bitu DPMI_SimulateInt(void) { if (activeDPMI) return activeDPMI->SimulateInt(); return 0;}; static Bitu DPMI_SimulateIntReturn(void) { if (activeDPMI) return activeDPMI->SimulateIntReturn(); return 0;}; From 166b944fc9d105636a23a034e718c62157f608a6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 27 Oct 2003 18:36:12 +0000 Subject: [PATCH 1304/4131] void function returning a value Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1385 --- src/hardware/iohandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index be213f39..aa8da329 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -40,7 +40,7 @@ void IO_WriteW(Bitu port,Bit16u val) { else LOG(LOG_IO,LOG_WARN)("WriteW:Out or range write %X to port %4X",val,port); } void IO_WriteD(Bitu port,Bit32u val) { - if (port<(IO_MAX & ~3)) return io.write_d[port](port,val); + if (port<(IO_MAX & ~3)) io.write_d[port](port,val); else LOG(LOG_IO,LOG_WARN)("WriteD:Out or range write %X to port %4X",val,port); } From 66e76bc0d5420a3dd81682b4c76b7a3b7f18fb4b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 27 Oct 2003 21:05:25 +0000 Subject: [PATCH 1305/4131] Set correct size while making child psp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1386 --- src/dos/dos_execute.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 05a1bba7..99139c8b 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -185,6 +185,7 @@ bool DOS_ChildPSP(Bit16u segment, Bit16u size) psp.MakeNew(size); DOS_PSP psp_parent(psp.GetParent()); psp.CopyFileTable(&psp_parent,true); + psp.SetSize(size); return true; }; static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { From 63cd8d1b5de2e24632c3a88e584ffd65d5680ecd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 28 Oct 2003 09:43:06 +0000 Subject: [PATCH 1306/4131] Fix errors with trap flag and interrupts Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1387 --- src/cpu/core_normal.cpp | 8 ++++++-- src/cpu/core_normal/prefix_none.h | 6 +++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index b4fb3317..fded8ef7 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -115,6 +115,9 @@ static struct { PhysPt seg_prefix_base; bool rep_zero; GetEATable * ea_table; + struct { + bool skip; + } trap; } core; #include "instructions.h" @@ -197,9 +200,10 @@ static Bits CPU_Core_Normal_Decode_Trap(void) { Bits oldCycles = CPU_Cycles; CPU_Cycles = 1; + core.trap.skip=false; + Bits ret=CPU_Core_Normal_Decode(); - - Interrupt(1); + if (!core.trap.skip) Interrupt(1); CPU_Cycles = oldCycles-1; cpudecoder = &CPU_Core_Normal_Decode; diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index fa097f1b..3eba569c 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -496,6 +496,7 @@ break; case 0x02: /* MOV SS,Ew */ CPU_SetSegGeneral(ss,val); + CPU_Cycles++; //Always do another instruction break; case 0x03: /* MOV DS,Ew */ CPU_SetSegGeneral(ds,val);break; @@ -759,7 +760,8 @@ if (DEBUG_Breakpoint()) { return debugCallback; } -#endif +#endif + core.trap.skip=true; if (!Interrupt(3)) return CBRET_NONE; goto decode_start; CASE_B(0xcd) /* INT Ib */ @@ -771,6 +773,7 @@ return debugCallback; } #endif + core.trap.skip=true; if (!Interrupt(num)) return CBRET_NONE; goto decode_start; //Restore IP with a LOADIP } @@ -778,6 +781,7 @@ CASE_B(0xce) /* INTO */ if (get_OF()) { LEAVECORE; + core.trap.skip=true; if (!Interrupt(4)) return CBRET_NONE; goto decode_start; //Restore IP with a LOADIP } From d78a0f9be03ab15127dfdb0eaf5a7430fdba6dcc Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 29 Oct 2003 10:18:30 +0000 Subject: [PATCH 1307/4131] Fixed a bug with the control status Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1388 --- src/dos/cdrom_aspi_win32.cpp | 4 ++-- src/dos/cdrom_ioctl_win32.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index c3ed83ce..62b92ce7 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -292,7 +292,7 @@ bool CDROM_Interface_Aspi::GetAudioTrackInfo (int track, TMSF& start, unsigned c start.min = (unsigned char)(toc.tracks[track-1].lAddr >> 8) &0xFF; start.sec = (unsigned char)(toc.tracks[track-1].lAddr >> 16) &0xFF; start.fr = (unsigned char)(toc.tracks[track-1].lAddr >> 24) &0xFF; - attr = toc.tracks[track-1].cAdrCtrl; + attr = (toc.tracks[track-1].cAdrCtrl << 4) & 0xEF; return true; }; return false; @@ -503,7 +503,7 @@ bool CDROM_Interface_Aspi::GetAudioSub(unsigned char& attr, unsigned char& track if (s.SRB_Status!=SS_COMP) return false; - attr = (pos.ADR<<4) | pos.Control; + attr = (pos.Control<<4) &0xEF; track = pos.TrackNumber; index = pos.IndexNumber; absPos.min = pos.AbsoluteAddress[1]; diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index 3d15e366..ddff8925 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -75,7 +75,7 @@ bool CDROM_Interface_Ioctl::GetAudioTrackInfo(int track, TMSF& start, unsigned c // Close(); if (!bStat) return false; - attr = (toc.TrackData[track-1].Adr << 4) | toc.TrackData[track].Control; + attr = (toc.TrackData[track-1].Control << 4) & 0xEF; start.min = toc.TrackData[track-1].Address[1]; start.sec = toc.TrackData[track-1].Address[2]; start.fr = toc.TrackData[track-1].Address[3]; @@ -97,7 +97,7 @@ bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& trac // Close(); if (!bStat) return false; - attr = (sub.CurrentPosition.ADR << 4) | sub.CurrentPosition.Control; + attr = (sub.CurrentPosition.Control << 4) & 0xEF; track = sub.CurrentPosition.TrackNumber; index = sub.CurrentPosition.IndexNumber; relPos.min = sub.CurrentPosition.TrackRelativeAddress[1]; From fbd28bf4bb5dafd74ca87c425033b9fd4bcecf50 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 29 Oct 2003 19:42:19 +0000 Subject: [PATCH 1308/4131] Fixed issue with long filenames (directory entries not displayed) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1389 --- include/dos_system.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/dos_system.h b/include/dos_system.h index 32212304..5c4cddf8 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.16 2003-10-09 13:50:27 finsterr Exp $ */ +/* $Id: dos_system.h,v 1.17 2003-10-29 19:42:19 finsterr Exp $ */ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ @@ -140,6 +140,7 @@ private: Bits GetLongName (CFileInfo* info, char* shortname); void CreateShortName (CFileInfo* dir, CFileInfo* info); Bit16u CreateShortNameID (CFileInfo* dir, const char* name); + int CompareShortname (const char* compareName, const char* shortName); bool SetResult (CFileInfo* dir, char * &result, Bit16u entryNr); bool IsCachedIn (CFileInfo* dir); CFileInfo* FindDirInfo (const char* path, char* expandedPath); From 95bb9c0372ac39f7c503c4beac297986083faf9b Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 29 Oct 2003 19:43:22 +0000 Subject: [PATCH 1309/4131] Fixed issue with long filenames (directory entries not displayed) init some static vars with 0 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1390 --- src/dos/drive_cache.cpp | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index bdf363a8..6a94cb28 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.28 2003-10-27 14:16:59 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.29 2003-10-29 19:43:22 finsterr Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -156,7 +156,7 @@ void DOS_Drive_Cache::ExpandName(char* path) char* DOS_Drive_Cache::GetExpandName(const char* path) { - static char work [CROSS_LEN]; + static char work [CROSS_LEN] = { 0 }; char dir [CROSS_LEN]; work[0] = 0; @@ -250,7 +250,6 @@ void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) // clear lists dir->fileList.clear(); dir->longNameList.clear(); - dir->shortNr = 0; save_dir = 0; }; @@ -283,6 +282,25 @@ bool DOS_Drive_Cache::GetShortName(const char* fullname, char* shortname) return false; }; +int DOS_Drive_Cache::CompareShortname(const char* compareName, const char* shortName) +{ + char* cpos = strchr(shortName,'~'); + if (cpos) { + Bits compareCount1 = (int)cpos - (int)shortName; + char* endPos = strchr(cpos,'.'); + Bitu numberSize = endPos ? int(endPos)-int(cpos) : strlen(cpos); + + char* lpos = strchr(compareName,'.'); + Bits compareCount2 = lpos ? int(lpos)-int(compareName) : strlen(compareName); + if (compareCount2>8) compareCount2 = 8; + + compareCount2 -= numberSize; + if (compareCount2>compareCount1) compareCount1 = compareCount2; + return strncmp(compareName,shortName,compareCount1); + } + return strcmp(compareName,shortName); +}; + Bit16u DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name) { Bits foundNr = 0; @@ -292,7 +310,8 @@ Bit16u DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name) while (low<=high) { mid = (low+high)/2; - res = strncmp(name,curDir->longNameList[mid]->shortname,curDir->longNameList[mid]->compareCount); + res = CompareShortname(name,curDir->longNameList[mid]->shortname); + if (res>0) low = mid+1; else if (res<0) high = mid-1; else { @@ -300,7 +319,7 @@ Bit16u DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name) do { foundNr = curDir->longNameList[mid]->shortNr; mid++; - } while(midlongNameList.size() && (strncmp(name,curDir->longNameList[mid]->shortname,curDir->longNameList[mid]->compareCount)==0)); + } while(midlongNameList.size() && (CompareShortname(name,curDir->longNameList[mid]->shortname)==0)); break; }; } @@ -409,7 +428,7 @@ void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) strcat(info->shortname,"~"); strcat(info->shortname,buffer); // Create compare Count - info->compareCount = tocopy; +// info->compareCount = tocopy; // Add (and cut) Extension, if available if (pos) { // Step to last extension... @@ -599,7 +618,7 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bit16u entryNr) { - static char res[CROSS_LEN]; + static char res[CROSS_LEN] = { 0 }; result = res; if (entryNr>=dir->fileList.size()) return false; @@ -616,7 +635,7 @@ bool DOS_Drive_Cache::FindFirst(char* path, Bitu dtaAddress, Bitu& id) { Bit16u dirID; Bitu dirFindFirstID = 0xffff; - + // Cache directory in if (!OpenDir(path,dirID)) return false; // Seacrh if dta was already used before @@ -641,7 +660,6 @@ bool DOS_Drive_Cache::FindFirst(char* path, Bitu dtaAddress, Bitu& id) dirFindFirst[dirFindFirstID] = new CFileInfo(); dirFindFirst[dirFindFirstID]-> nextEntry = 0; dirFindFirst[dirFindFirstID]-> compareCount = dtaAddress; -// strcpy(dirFindFirst[dirFindFirstID]->orgname,path); // Copy entries to use with FindNext for (Bitu i=0; ifileList.size(); i++) { @@ -704,7 +722,7 @@ bool DOS_No_Drive_Cache::OpenDir(const char* path, Bit16u& id) bool DOS_No_Drive_Cache::ReadDir(Bit16u id, char* &result) { - static char res[CROSS_LEN]; + static char res[CROSS_LEN] = { 0 }; dirent * ent; if (!srch_opendir) return false; From 7ee41eb2e6029576a7007c1b0c5bd3abba588112 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 30 Oct 2003 09:08:58 +0000 Subject: [PATCH 1310/4131] Maybe improve fullscreen rendering Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1391 --- src/gui/sdlmain.cpp | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 22b5a696..acb2ae78 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.51 2003-10-14 23:32:32 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.52 2003-10-30 09:08:58 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -42,7 +42,7 @@ #include "debug.h" //#define DISABLE_JOYSTICK -#define C_GFXTHREADED 1 //Enabled by default +#define C_GFXTHREADED 0 //Enabled by default #if !(ENVIRON_INCLUDED) extern char** environ; @@ -104,26 +104,25 @@ void GFX_SetTitle(Bits cycles,Bits frameskip){ /* Reset the screen with current values in the sdl structure */ static void ResetScreen(void) { GFX_Stop(); - if (sdl.full_screen) { - if (sdl.flags & GFX_SHADOW) { - withshadow: - /* TODO Maybe allocate a shadow surface and blit yourself and do real double buffering too */ - sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_SWSURFACE|SDL_FULLSCREEN); + Bit32u mode_flags=0; + if (sdl.full_screen) { + mode_flags|=SDL_FULLSCREEN; + if (sdl.bpp==8) mode_flags|=SDL_HWPALETTE; + if (sdl.flags & GFX_SHADOW) { + mode_flags|=SDL_SWSURFACE; } else { - Bitu test_bpp=SDL_VideoModeOK(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN|SDL_DOUBLEBUF); - if (test_bpp != sdl.bpp) - goto withshadow; - sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN|SDL_DOUBLEBUF); + mode_flags|=SDL_HWSURFACE|SDL_DOUBLEBUF; } + } else mode_flags|=SDL_SWSURFACE; + if (sdl.flags & GFX_FIXED_BPP) { + dofixed: + sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,mode_flags); } else { - if (sdl.flags & GFX_FIXED_BPP) { - withfixed: - sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE); - } else { - sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,0,SDL_HWSURFACE); - if (sdl.surface->format->BitsPerPixel==24) - goto withfixed; - } + Bitu test_bpp=SDL_VideoModeOK(sdl.width,sdl.height,sdl.bpp,mode_flags); + if (test_bpp==sdl.bpp) goto dofixed; + sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,0,mode_flags); + if (sdl.surface->format->BitsPerPixel==24) goto dofixed; + } if (sdl.surface==0) { E_Exit("SDL:Can't get a surface error:%s.",SDL_GetError()); @@ -134,9 +133,7 @@ static void ResetScreen(void) { sdl.surface->format->Rmask,sdl.surface->format->Gmask,sdl.surface->format->Bmask,sdl.surface->format->Amask ); - GFX_SetTitle(-1,-1); - Bitu flags=MODE_SET; if (sdl.full_screen) flags|=MODE_FULLSCREEN; if (sdl.mode_callback) sdl.mode_callback(sdl.surface->w,sdl.surface->h,sdl.surface->format->BitsPerPixel,sdl.surface->pitch,flags); @@ -701,5 +698,5 @@ int main(int argc, char* argv[]) { if (sdl.full_screen) SwitchFullScreen(); if (sdl.mouse.locked) CaptureMouse(); } - return 0; + return 0; }; From 83209226a02a28d59e64c36434a3df8a07fcef75 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 30 Oct 2003 22:15:28 +0000 Subject: [PATCH 1311/4131] Remove PIC_AddIRQ usage Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1392 --- src/hardware/sblaster.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index fc8f6a44..cf91e3da 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -202,7 +202,7 @@ static void DSP_SetSpeaker(bool how) { static INLINE void SB_RaiseIRQ(SB_IRQS type) { LOG(LOG_SB,LOG_NORMAL)("Raising IRQ"); - PIC_AddIRQ(sb.hw.irq,0); + PIC_ActivateIRQ(sb.hw.irq); switch (type) { case SB_IRQ_8: sb.irq.pending_8bit=true; @@ -457,6 +457,10 @@ static void DSP_ChangeMode(DSP_MODES mode) { sb.mode=mode; } +static void DSP_RaiseIRQEvent(void) { + SB_RaiseIRQ(SB_IRQ_8); +} + static void DSP_StartDMATranfser(DMA_MODES mode) { char * type; /* First fill with current whatever is playing */ @@ -470,7 +474,7 @@ static void DSP_StartDMATranfser(DMA_MODES mode) { sb.tmp.index=0; switch (mode) { case DMA_8_SILENCE: - PIC_AddIRQ(sb.hw.irq,((1000000*sb.dma.left)/sb.dma.rate)); + PIC_AddEvent(&DSP_RaiseIRQEvent,((1000000*sb.dma.left)/sb.dma.rate)); sb.dma.mode=DMA_NONE; return; case DMA_8_SINGLE: @@ -510,6 +514,8 @@ static void DSP_AddData(Bit8u val) { static void DSP_Reset(void) { + LOG(LOG_SB,LOG_ERROR)("DSP:Reset"); + PIC_DeActivateIRQ(sb.hw.irq); DSP_ChangeMode(MODE_NONE); sb.dsp.cmd_len=0; sb.dsp.in.pos=0; From cf9a3a8931870f7d5e7422ef0e027ff26a322d58 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 30 Oct 2003 22:18:15 +0000 Subject: [PATCH 1312/4131] Remove PIC_AddIRQ Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1393 --- include/pic.h | 9 +++-- src/hardware/pic.cpp | 79 +++++++++++++++----------------------------- 2 files changed, 30 insertions(+), 58 deletions(-) diff --git a/include/pic.h b/include/pic.h index d40a5f92..17f21e43 100644 --- a/include/pic.h +++ b/include/pic.h @@ -49,17 +49,16 @@ INLINE Bit64u PIC_MicroCount(void) { return PIC_Ticks*1000+PIC_Index(); } -void PIC_ActivateIRQ(Bit32u irq); +void PIC_ActivateIRQ(Bitu irq); -void PIC_DeActivateIRQ(Bit32u irq); +void PIC_DeActivateIRQ(Bitu irq); void PIC_runIRQs(void); -void PIC_RegisterIRQ(Bit32u irq,PIC_EOIHandler handler,char * name); -void PIC_FreeIRQ(Bit32u irq); +void PIC_RegisterIRQ(Bitu irq,PIC_EOIHandler handler,char * name); +void PIC_FreeIRQ(Bitu irq); bool PIC_RunQueue(void); -void PIC_AddIRQ(Bitu irq,Bitu delay); void PIC_AddEvent(PIC_EventHandler handler,Bitu delay); void PIC_RemoveEvents(PIC_EventHandler handler); diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 18821383..65a1ba07 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -55,14 +55,7 @@ Bitu PIC_IRQActive; static IRQ_Block irqs[16]; static PIC_Controller pics[2]; - -enum QUEUE_TYPE { - IRQ,EVENT -}; - struct PICEntry { - QUEUE_TYPE type; - Bitu irq; Bitu index; PIC_EventHandler event; PICEntry * next; @@ -126,6 +119,12 @@ static void write_data(Bit32u port,Bit8u val) { if (irqs[i+irq_base].active && !irqs[i+irq_base].masked) PIC_IRQCheck|=(1 << (i+irq_base)); else PIC_IRQCheck&=~(1 << (i+irq_base)); }; +#if 0 + if (PIC_IRQCheck) { + CPU_CycleLeft+=CPU_Cycles; + CPU_Cycles=0; + } +#endif break; case 1: /* icw2 */ LOG(LOG_PIC,LOG_NORMAL)("%d:Base vector %X",static_cast(port==0x21 ? 0 : 1),static_cast(val)); @@ -187,13 +186,13 @@ static Bit8u read_data(Bit32u port) { return ret; } -void PIC_RegisterIRQ(Bit32u irq,PIC_EOIHandler handler,char * name) { +void PIC_RegisterIRQ(Bitu irq,PIC_EOIHandler handler,char * name) { if (irq>15) E_Exit("PIC:Illegal IRQ"); irqs[irq].name=name; irqs[irq].handler=handler; } -void PIC_FreeIRQ(Bit32u irq) { +void PIC_FreeIRQ(Bitu irq) { if (irq>15) E_Exit("PIC:Illegal IRQ"); irqs[irq].name=0; irqs[irq].handler=0; @@ -202,7 +201,7 @@ void PIC_FreeIRQ(Bit32u irq) { PIC_IRQCheck&=~(1 << irq); } -void PIC_ActivateIRQ(Bit32u irq) { +void PIC_ActivateIRQ(Bitu irq) { if (irq<16) { irqs[irq].active=true; if (!irqs[irq].masked) { @@ -211,7 +210,7 @@ void PIC_ActivateIRQ(Bit32u irq) { } } -void PIC_DeActivateIRQ(Bit32u irq) { +void PIC_DeActivateIRQ(Bitu irq) { if (irq<16) { irqs[irq].active=false; PIC_IRQCheck&=~(1 << irq); @@ -279,22 +278,6 @@ void PIC_AddEvent(PIC_EventHandler handler,Bitu delay) { Bitu index=delay+PIC_Index(); entry->index=index; entry->event=handler; - entry->type=EVENT; - pic.free_entry=pic.free_entry->next; - AddEntry(entry); -} - -void PIC_AddIRQ(Bitu irq,Bitu delay) { - if (irq>15) E_Exit("PIC:Illegal IRQ"); - if (!pic.free_entry) { - LOG(LOG_PIC,LOG_ERROR)("Event queue full"); - return; - } - PICEntry * entry=pic.free_entry; - Bitu index=delay+PIC_Index(); - entry->index=index; - entry->irq=irq; - entry->type=IRQ; pic.free_entry=pic.free_entry->next; AddEntry(entry); } @@ -305,30 +288,27 @@ void PIC_RemoveEvents(PIC_EventHandler handler) { PICEntry * prev_entry; prev_entry=0; while (entry) { - switch (entry->type) { - case EVENT: - if (entry->event==handler) { - if (prev_entry) { - prev_entry->next=entry->next; - entry->next=pic.free_entry; - pic.free_entry=entry; - entry=prev_entry->next; - continue; - } else { - pic.next_entry=entry->next; - entry->next=pic.free_entry; - pic.free_entry=entry; - entry=pic.next_entry; - continue; - } + if (entry->event==handler) { + if (prev_entry) { + prev_entry->next=entry->next; + entry->next=pic.free_entry; + pic.free_entry=entry; + entry=prev_entry->next; + continue; + } else { + pic.next_entry=entry->next; + entry->next=pic.free_entry; + pic.free_entry=entry; + entry=pic.next_entry; + continue; } - break; } prev_entry=entry; entry=entry->next; - } + } } + bool PIC_RunQueue(void) { /* Check to see if a new milisecond needs to be started */ CPU_CycleLeft+=CPU_Cycles; @@ -341,14 +321,7 @@ bool PIC_RunQueue(void) { while (pic.next_entry && pic.next_entry->index<=index) { PICEntry * entry=pic.next_entry; pic.next_entry=entry->next; - switch (entry->type) { - case EVENT: - (entry->event)(); - break; - case IRQ: - PIC_ActivateIRQ(entry->irq); - break; - } + (entry->event)(); /* Put the entry in the free list */ entry->next=pic.free_entry; pic.free_entry=entry; From 9c3002204e1d17accabe88d47e63098789010c14 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 1 Nov 2003 16:03:42 +0000 Subject: [PATCH 1313/4131] undocumented feature with resize returning segment in AX Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1394 --- src/dos/dos.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 82d7641c..57c48ef3 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.59 2003-10-26 18:57:46 harekiet Exp $ */ +/* $Id: dos.cpp,v 1.60 2003-11-01 16:03:42 harekiet Exp $ */ #include #include @@ -599,6 +599,7 @@ static Bitu DOS_21Handler(void) { { Bit16u size=reg_bx; if (DOS_ResizeMemory(SegValue(es),&size)) { + reg_ax=SegValue(es); CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; From f9cb7aa8dba90e5bdecba36fe3a8f6d514b5295f Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Tue, 4 Nov 2003 03:39:23 +0000 Subject: [PATCH 1314/4131] Added GUS functionality Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1395 --- src/hardware/gus.cpp | 1059 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1057 insertions(+), 2 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index bb716391..c8ccc505 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -7,17 +7,1072 @@ #include "hardware.h" #include "setup.h" #include "programs.h" +#include "math.h" +#include "regs.h" + + +#define GUS_BASE myGUS.portbase +#define GUS_RATE myGUS.rate + +static MIXER_Channel * gus_chan; + +static Bit16u vol8bit[256]; +static Bit16s vol16bit[4096]; + +static Bit8u irqtable[8] = { 0, 2, 5, 3, 7, 11, 12, 15 }; + +static Bit8u dmatable[6] = { 3, 1, 5, 5, 6, 7 }; + +static Bit8u GUSRam[1024*1024]; // 1024K of GUS Ram + +struct GFGus { + Bit8u gRegSelect; + Bit16u gRegData; + Bit32u gDramAddr; + Bit16u gCurChannel; + + Bit8u DMAControl; + Bit16u dmaAddr; + Bit8u TimerControl; + Bit8u SampControl; + Bit8u mixControl; + + Bit32u basefreq; + Bit16u activechan; + Bit16u mupersamp; + Bit16u muperchan; + + + Bit16u timerReg; + struct GusTimer { + Bit16u bytetimer; + Bit32s countdown; + Bit32s setting; + bool active; + } timers[2]; + + + Bit32u rate; + Bit16u portbase; + Bit16u dma1; + Bit16u dma2; + + Bit16u irq1; + Bit16u irq2; + + char ultradir[512]; + + bool irqenabled; + + struct IRQStat { + bool MIDITx; + bool MIDIRx; + bool T1; + bool T2; + bool Resv; + bool WaveTable; + bool VolRamp; + bool DMATC; + } irq; + +} myGUS; + +#define GUSFIFOSIZE 1024 + +static void UseDMA(DmaChannel *useDMA); + +struct IRQFifoEntry { + Bit8u channum; + bool WaveIRQ; + bool RampIRQ; +}; + +struct IRQFifoDef { + IRQFifoEntry entry[GUSFIFOSIZE]; + Bit16s stackpos; +} IRQFifo; + +static void pushIRQ(Bit8u channum, bool WaveIRQ, bool RampIRQ) { + IRQFifo.stackpos++; + //LOG_MSG("Stack position %d", IRQFifo.stackpos); + if(IRQFifo.stackpos < GUSFIFOSIZE) { + myGUS.irq.WaveTable = WaveIRQ; + myGUS.irq.VolRamp = RampIRQ; + + IRQFifo.entry[IRQFifo.stackpos].channum = channum; + IRQFifo.entry[IRQFifo.stackpos].RampIRQ = RampIRQ; + IRQFifo.entry[IRQFifo.stackpos].WaveIRQ = WaveIRQ; + } else { + LOG_MSG("GUS IRQ Fifo full!"); + } +} + +INLINE Bit16s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { + Bit32u useAddr; + Bit32u holdAddr; + useAddr = CurAddr >> 9; + if(eightbit) { + if(Delta >= 1024) { + Bit8s tmpsmall = (Bit8s)GUSRam[useAddr]; + return (Bit16s)(tmpsmall << 7); + } else { + Bit8s b1 = (Bit8s)GUSRam[useAddr]; + Bit8s b2 = (Bit8s)GUSRam[useAddr+1]; + Bit16s w1 = b1 << 7; + Bit16s w2 = b2 << 7; + Bit16s diff = w2 - w1; + return (w1 + (((Bit32s)diff * (Bit32s)(CurAddr & 0x3fe)) >> 10)); + + } + } else { + + holdAddr = useAddr & 0xc0000L; + useAddr = useAddr & 0x1ffffL; + useAddr = useAddr << 1; + useAddr = (holdAddr | useAddr); + //LOG_MSG("Sample from %x (%d)", useAddr, useAddr); + + if(Delta >= 1024) { + + return (Bit16s)((Bit16u)GUSRam[useAddr] | ((Bit16u)GUSRam[useAddr+1] << 8)) >> 1; + + } else { + Bit16s w1 = (Bit16s)((Bit16u)GUSRam[useAddr] | ((Bit16u)GUSRam[useAddr+1] << 8)); + Bit16s w2 = (Bit16s)((Bit16u)GUSRam[useAddr+2] | ((Bit16u)GUSRam[useAddr+3] << 8)); + Bit16s diff = w2 - w1; + return (w1 + (((Bit32s)diff * (Bit32s)((CurAddr) & 0x3fe)) >> 10)) >> 1; + + } + } +} + +static void popIRQ(IRQFifoEntry * tmpentry) { + if(IRQFifo.stackpos<0) { + tmpentry->channum = 0; + tmpentry->RampIRQ = false; + tmpentry->WaveIRQ = false; + return; + } + memcpy(tmpentry, &IRQFifo.entry[IRQFifo.stackpos], sizeof(IRQFifoEntry)); + --IRQFifo.stackpos; + //LOG_MSG("Stack position %d", IRQFifo.stackpos); + if(IRQFifo.stackpos >= 0) { + myGUS.irq.WaveTable = IRQFifo.entry[IRQFifo.stackpos].WaveIRQ; + myGUS.irq.VolRamp = IRQFifo.entry[IRQFifo.stackpos].RampIRQ; + } else { + myGUS.irq.WaveTable = false; + myGUS.irq.VolRamp = false; + } +} + +class GUSChannels { +public: + Bit8u voiceCont; + Bit16u FreqCont; + Bit32u RealDelta; + Bit32u StartAddr; + Bit32u EndAddr; + Bit8s VolRampRate; + Bit16s VolRampStart; + Bit16s VolRampEnd; + Bit8u VolRampStartOrg; + Bit8u VolRampEndOrg; + Bit32s CurVolume; + Bit32u CurAddr; + Bit8u PanPot; + Bit8u VolControl; + Bit16u channum; + + bool moving; + bool playing; + bool ramping; + bool dir; + bool voldir; + +public: + bool notifyonce; + Bit32s leftvol; + Bit32s rightvol; + Bit32s nextramp; + + GUSChannels(Bit16u num) { + channum = num; + playing = true; + ramping = false; + moving = false; + dir = false; + voldir = false; + StartAddr = 0; + EndAddr = 0; + CurAddr = 0; + VolRampRate = 0; + VolRampStart = 0; + VolRampEnd = 0; + leftvol = 255; + rightvol = 255; + nextramp = 0; + + }; + + void WriteVoiceCtrl(Bit8u val) { + voiceCont = val; + if (val & 0x3) moving = false; + if ((val & 0x3) == 0) { + //playing = true; + moving = true; + } + dir = false; + if((val & 0x40) !=0) dir = true; + + } + Bit8u ReadVoiceCtrl(void) { + Bit8u tmpval = voiceCont & 0xfe; + if(!playing) tmpval++; + return tmpval; + } + + void WriteFreqCtrl(Bit16u val) { + FreqCont = val; + //RealDelta = (myGUS.basefreq * (Bit32u)val) / GUS_RATE; + int fc; + fc = val; + fc = fc >> 1; + fc = fc * myGUS.basefreq; + fc = fc - (myGUS.basefreq >> 1); + fc = fc / 512; + float simple; + + simple = ((float)fc / (float)GUS_RATE) * 512; + RealDelta = (Bit32u)simple; + + + } + Bit16u ReadFreqCtrl(void) { + return FreqCont; + } + + void WritePanPot(Bit8u val) { + if(val<8) { + leftvol = 255; + rightvol = val << 5; + } else { + rightvol = 255; + leftvol = (8-(val-8)) << 5; + } + PanPot = val; + + } + Bit8u ReadPanPot(void) { + return PanPot; + } + + void WriteVolControl(Bit8u val) { + VolControl = val; + if (val & 0x3) ramping = false; + if ((val & 0x3) == 0) ramping = true; + voldir = false; + if((val & 0x40) !=0) voldir = true; + + } + Bit8u ReadVolControl(void) { + Bit8u tmpval = VolControl & 0xfe; + if(!ramping) tmpval++; + return tmpval; + } + + + void NotifyEndSamp(void) { + if(!notifyonce) { + if((voiceCont & 0x20) != 0) { + pushIRQ(channum,true,false); + notifyonce = true; + } + } + } + void NotifyEndRamp(void) { + if(!notifyonce) { + if((VolControl & 0x20) != 0) { + pushIRQ(channum,false,true); + notifyonce = true; + } + } + } + + void ShowAddr(void) { + LOG_MSG("Chan %d Start %d End %d Current %d", channum, StartAddr>>9, EndAddr>>9, CurAddr>>9); + } + + + void generateSamples(Bit16s * stream,Bit32u len) { + int i; + Bit16s tmpsamp; + bool eightbit; + eightbit = ((voiceCont & 0x4) == 0); + + notifyonce = false; + + //if((voiceCont & 0x4) == 0) { + // 8-bit data + for(i=0;i4095) CurVolume = 4095; + if(CurVolume<0) CurVolume = 0; + tmpsamp = (tmpsamp * vol16bit[CurVolume]) >> 12; + + stream[i<<1] = (Bit16s)(((Bit32s)tmpsamp * (Bit32s)leftvol)>>8) ; + stream[(i<<1)+1] = (Bit16s)(((Bit32s)tmpsamp * rightvol)>>8); + + if(dir) { + if (moving) CurAddr -= RealDelta; + if ((!eightbit) && (moving)) CurAddr -= RealDelta; + + if(CurAddr <= StartAddr) { + if((VolControl & 0x4) == 0) { + if((voiceCont & 0x8) != 0) { + if((voiceCont & 0x10) != 0) { + dir = !dir; + } else { + CurAddr = EndAddr; + } + + } else { + moving = false; + //NotifyEndSamp(); + //break; + } + NotifyEndSamp(); + } else { + NotifyEndSamp(); + + } + + } + + } else { + if (moving) CurAddr += RealDelta; + if ((!eightbit) && (moving)) CurAddr += RealDelta; + //LOG_MSG("Cur %x to %x or (%x, %x) %d", CurAddr >> 9, EndAddr >> 9, CurAddr, EndAddr, (CurAddr >= EndAddr) ); + if(CurAddr >= EndAddr) { + if((VolControl & 0x4) == 0) { + if((voiceCont & 0x8) != 0) { + if((voiceCont & 0x10) != 0) { + dir = !dir; + } else { + CurAddr = StartAddr; + } + + } else { + moving = false; + //NotifyEndSamp(); + //break; + } + NotifyEndSamp(); + } else { + NotifyEndSamp(); + } + } + } + + + // Update volume + if(ramping) { + nextramp -= myGUS.mupersamp; + bool flagged; + flagged = false; + while(nextramp <= 0) { + if(voldir) { + CurVolume -= (VolRampRate & 0x3f); + if (CurVolume <= 0) { + CurVolume = 0; + flagged = true; + } + + if((vol16bit[CurVolume]<=VolRampStart) || (flagged)){ + if((VolControl & 0x8) != 0) { + if((VolControl & 0x10) != 0) { + voldir = !voldir; + } else { + CurVolume = VolRampEndOrg; + } + } else { + ramping = false; + } + NotifyEndRamp(); + } + + } else { + CurVolume += (VolRampRate & 0x3f); + if (CurVolume >= 4095) { + CurVolume = 4095; + flagged = true; + } + + if((vol16bit[CurVolume]>=VolRampEnd) || (flagged)){ + if((VolControl & 0x8) != 0) { + if((VolControl & 0x10) != 0) { + voldir = !voldir; + } else { + CurVolume = VolRampStartOrg; + } + } else { + ramping = false; + } + NotifyEndRamp(); + } + + } + + + switch(VolRampRate >> 6) { + case 0: + nextramp += myGUS.muperchan; + break; + case 1: + nextramp += myGUS.muperchan * 8; + break; + case 2: + nextramp += myGUS.muperchan * 64; + break; + case 3: + nextramp += myGUS.muperchan * 512; + break; + default: + nextramp += myGUS.muperchan * 512; + break; + + } + + } + + } + + + } + //} else { + // 16-bit data + // LOG_MSG("16-bit data not supported yet!"); + + //} + } + + +}; + + +GUSChannels *guschan[32]; + +GUSChannels *curchan; + + +static void GUSReset(void) +{ + if((myGUS.gRegData & 0x1) == 0x1) { + // Reset + myGUS.timerReg = 85; + memset(&myGUS.irq, 0, sizeof(myGUS.irq)); + //IRQFifo.stackpos = -1; + } + if((myGUS.gRegData & 0x4) != 0) { + myGUS.irqenabled = true; + } else { + myGUS.irqenabled = false; + } + //LOG_MSG("Gus reset"); + myGUS.timers[0].active = false; + myGUS.timers[1].active = false; + int i; + for(i=0;i<32;i++) { + guschan[i]->WriteVoiceCtrl(0x3); + + } + IRQFifo.stackpos = -1; + + + //MIXER_Enable(gus_chan,false); + +} -void GUS_Init(Section* sec) { - MSG_Add("GUS_CONFIGFILE_HELP","Nothing to setup yet!\n"); +static Bit16u ExecuteReadRegister(void) { + Bit8u tmpreg; + switch (myGUS.gRegSelect) { + case 0x41: + + tmpreg = myGUS.DMAControl & 0xbf; + if(myGUS.irq.DMATC) tmpreg |= 0x40; + + myGUS.irq.DMATC = false; + PIC_DeActivateIRQ(myGUS.irq1); + + return (Bit16u)(tmpreg << 8); + case 0x42: + return myGUS.dmaAddr; + case 0x49: + tmpreg = myGUS.DMAControl & 0xbf; + if(myGUS.irq.DMATC) tmpreg |= 0x40; + + myGUS.irq.DMATC = false; + PIC_DeActivateIRQ(myGUS.irq1); + //LOG_MSG("Read sampling status, returned 0x%x", tmpreg); + + return (Bit16u)(tmpreg << 8); + case 0x80: + if(curchan != NULL) { + Bit8u sndout; + sndout = curchan->voiceCont & 0xFC; + if(!curchan->moving) sndout |= 0x3; + + return (Bit16u)(sndout<< 8); + } else return 0x0300; + + case 0x82: + if(curchan != NULL) { + return (curchan->StartAddr >> 16); + } else return 0x0000; + case 0x83: + if(curchan != NULL) { + return (curchan->StartAddr & 0xffff); + } else return 0x0000; + case 0x89: + if(curchan != NULL) { + return (curchan->CurVolume << 4); + } else return 0x0000; + case 0x8a: + if(curchan != NULL) { + return (curchan->CurAddr >> 16); + } else return 0x0000; + + case 0x8b: + if(curchan != NULL) { + return (curchan->CurAddr & 0xFFFF); + } else return 0x0000; + case 0x8d: + if(curchan != NULL) { + Bit8u volout; + volout = curchan->VolControl & 0xFC; + if(!curchan->ramping) volout |= 0x3; + //LOG_MSG("Ret at 8D %x - chan %d - ramp %d move %d rate %d pos %d dir %d py %d", volout, curchan->channum, curchan->ramping, curchan->moving, curchan->VolRampRate & 0x3f, vol16bit[curchan->CurVolume], curchan->voldir, curchan->playing); + return (volout << 8); + } else return 0x0300; + + case 0x8f: + Bit8u temp; + temp = 0x20; + IRQFifoEntry tmpentry; + PIC_DeActivateIRQ(myGUS.irq1); + popIRQ(&tmpentry); + if(!tmpentry.WaveIRQ) temp |= 0x80; + if(!tmpentry.RampIRQ) temp |= 0x40; + temp |= tmpentry.channum; + + return (Bit16u)(temp << 8); + default: + LOG_MSG("Read Register num 0x%x", myGUS.gRegSelect); + return myGUS.gRegData; + } +} + + +static void ExecuteGlobRegister(void) { + //LOG_MSG("Access global register %x with %x", myGUS.gRegSelect, myGUS.gRegData); + switch(myGUS.gRegSelect) { + case 0x0: + if(curchan != NULL) { + curchan->WriteVoiceCtrl((Bit8u)myGUS.gRegData); + } + break; + case 0x1: + if(curchan != NULL) { + curchan->WriteFreqCtrl(myGUS.gRegData); + } + break; + case 0x2: + if(curchan != NULL) { + Bit32u tmpaddr = myGUS.gRegData << 16; + curchan->StartAddr = (curchan->StartAddr & 0xFFFF) | tmpaddr; + } + break; + case 0x3: + if(curchan != NULL) { + Bit32u tmpaddr = (Bit32u)(myGUS.gRegData); + curchan->StartAddr = (curchan->StartAddr & 0x1FFF0000) | tmpaddr; + } + break; + case 0x4: + if(curchan != NULL) { + Bit32u tmpaddr = (Bit32u)myGUS.gRegData << 16; + curchan->EndAddr = (curchan->EndAddr & 0xFFFF) | tmpaddr; + } + break; + case 0x5: + if(curchan != NULL) { + Bit32u tmpaddr = (Bit32u)(myGUS.gRegData); + curchan->EndAddr = (curchan->EndAddr & 0x1FFF0000) | tmpaddr; + } + break; + case 0x6: + if(curchan != NULL) { + Bit8u tmpdata = (Bit8u)myGUS.gRegData; + curchan->VolRampRate = tmpdata; + } + break; + case 0x7: + if(curchan != NULL) { + Bit8u tmpdata = (Bit8u)myGUS.gRegData; + curchan->VolRampStart = vol8bit[tmpdata]; + curchan->VolRampStartOrg = tmpdata << 4; + } + break; + case 0x8: + if(curchan != NULL) { + Bit8u tmpdata = (Bit8u)myGUS.gRegData; + curchan->VolRampEnd = vol8bit[tmpdata]; + curchan->VolRampEndOrg = tmpdata << 4; + } + break; + case 0x9: + if(curchan != NULL) { + Bit16u tmpdata = (Bit16u)myGUS.gRegData >> 4; + curchan->CurVolume = tmpdata; + } + break; + case 0xA: + if(curchan != NULL) { + curchan->CurAddr = (curchan->CurAddr & 0xFFFF) | ((Bit32u)myGUS.gRegData << 16); + } + break; + case 0xB: + if(curchan != NULL) { + curchan->CurAddr = (curchan->CurAddr & 0xFFFF0000) | ((Bit32u)myGUS.gRegData); + } + break; + case 0xC: + if(curchan != NULL) { + curchan->WritePanPot((Bit8u)myGUS.gRegData); + } + break; + case 0xD: + if(curchan != NULL) { + curchan->WriteVolControl((Bit8u)myGUS.gRegData); + } + break; + case 0xE: + myGUS.activechan = myGUS.gRegData & 63; + if(myGUS.activechan < 14) myGUS.activechan = 14; + MIXER_Enable(gus_chan,true); + myGUS.basefreq = (Bit32u)((float)1000000/(1.619695497*(float)myGUS.activechan)); + + float simple; + simple = (1.0 / (float)GUS_RATE) / 0.000001; + myGUS.mupersamp = (Bit16u)simple; + myGUS.muperchan = (Bit16u)((float)1.6 * (float)myGUS.activechan); + LOG_MSG("GUS set to %d channels", myGUS.activechan); + break; + case 0x41: + myGUS.DMAControl = (Bit8u)myGUS.gRegData; + if ((myGUS.DMAControl & 0x1) != 0) { + //LOG_MSG("GUS request DMA transfer"); + if(DmaChannels[myGUS.dma1]->enabled) UseDMA(DmaChannels[myGUS.dma1]); + } + break; + case 0x42: + myGUS.dmaAddr = myGUS.gRegData; + break; + case 0x43: + myGUS.gDramAddr = (0xff0000 & myGUS.gDramAddr) | ((Bit32u)myGUS.gRegData); + break; + case 0x44: + myGUS.gDramAddr = (0xffff & myGUS.gDramAddr) | ((Bit32u)myGUS.gRegData) << 16; + break; + case 0x45: + myGUS.TimerControl = (Bit8u)myGUS.gRegData; + if((myGUS.TimerControl & 0x08) !=0) myGUS.timers[1].countdown = myGUS.timers[1].setting; + if((myGUS.TimerControl & 0x04) !=0) myGUS.timers[0].countdown = myGUS.timers[0].setting; + myGUS.irq.T1 = false; + myGUS.irq.T2 = false; + PIC_DeActivateIRQ(myGUS.irq1); + break; + + case 0x46: + myGUS.timers[0].bytetimer = (Bit8u)myGUS.gRegData; + myGUS.timers[0].setting = ((Bit32s)0xff - (Bit32s)myGUS.timers[0].bytetimer) * (Bit32s)80; + myGUS.timers[0].countdown = myGUS.timers[0].setting; + break; + case 0x47: + myGUS.timers[1].bytetimer = (Bit8u)myGUS.gRegData; + myGUS.timers[1].setting = ((Bit32s)0xff - (Bit32s)myGUS.timers[1].bytetimer) * (Bit32s)360; + myGUS.timers[1].countdown = myGUS.timers[1].setting; + break; + case 0x49: + myGUS.SampControl = (Bit8u)myGUS.gRegData; + if ((myGUS.SampControl & 0x1) != 0) { + if(DmaChannels[myGUS.dma1]->enabled) UseDMA(DmaChannels[myGUS.dma1]); + } + break; + case 0x4c: + GUSReset(); + break; + default: + LOG_MSG("Unimplemented global register %x -- %x", myGUS.gRegSelect, myGUS.gRegData); + } + return; +} + + +static Bit16u read_gus16(Bit32u port) { + + return ExecuteReadRegister(); +} + +static void write_gus16(Bit32u port,Bit16u val) { + myGUS.gRegData = val; + ExecuteGlobRegister(); +} + + +static Bit8u read_gus(Bit32u port) { + + switch(port - GUS_BASE) { + case 0x206: + Bit8u temp; + temp = 0; + if(myGUS.irq.MIDITx) temp |= 1; + if(myGUS.irq.MIDIRx) temp |= 2; + if(myGUS.irq.T1) temp |= 4; + if(myGUS.irq.T2) temp |= 8; + if(myGUS.irq.Resv) temp |= 16; + if(myGUS.irq.WaveTable) temp |= 32; + if(myGUS.irq.VolRamp) temp |= 64; + if(myGUS.irq.DMATC) temp |= 128; + PIC_DeActivateIRQ(myGUS.irq1); + return temp; + case 0x208: + Bit8u tmptime; + tmptime = 0; + + if(myGUS.irq.T1) tmptime |= (1 << 6); + if(myGUS.irq.T2) tmptime |= (1 << 5); + if((myGUS.irq.T1) || (myGUS.irq.T2)) tmptime |= (1 << 7); + return tmptime; + case 0x20a: + return myGUS.timerReg; + case 0x302: + return (Bit8u)myGUS.gCurChannel; + case 0x303: + return myGUS.gRegSelect; + case 0x304: + return ExecuteReadRegister() & 0xff; + case 0x305: + return ExecuteReadRegister() >> 8; + case 0x307: + if(myGUS.gDramAddr < sizeof(GUSRam)) { + return GUSRam[myGUS.gDramAddr]; + } else { + return 0; + } + default: + LOG_MSG("Read GUS at port 0x%x", port); + break; + } + + return 0xff; +} + + +static void write_gus(Bit32u port,Bit8u val) { + FILE *fp; + + switch(port - GUS_BASE) { + case 0x200: + myGUS.mixControl = val; + break; + case 0x208: + myGUS.timerReg = val; + break; + case 0x209: + myGUS.timers[0].active = ((val & 0x1) > 0); + myGUS.timers[1].active = ((val & 0x2) > 0); + + fp = fopen("gusdump.raw","wb"); + fwrite(&GUSRam[0],1024*1024,1,fp); + fclose(fp); + + + //LOG_MSG("Timer output reg %x", val); + break; + case 0x20b: + if((myGUS.mixControl & 0x40) != 0) { + // IRQ configuration + Bit8u temp = val & 0x7; // Select GF1 irq + if(myGUS.irq1 == irqtable[temp]) { + } else { + LOG_MSG("Attempt to assign GUS to wrong IRQ - at %x set to %x", myGUS.irq1, irqtable[temp]); + } + } else { + // DMA configuration + Bit8u temp = val & 0x7; // Select playback IRQ + if(myGUS.dma1 == dmatable[temp]) { + } else { + LOG_MSG("Attempt to assign GUS to wrong DMA - at %x, assigned %x", myGUS.dma1, dmatable[temp]); + } + } + + break; + case 0x302: + myGUS.gCurChannel = val; + curchan = guschan[val]; + break; + case 0x303: + myGUS.gRegSelect = val; + myGUS.gRegData = 0; + break; + case 0x304: + myGUS.gRegData = (0x00ff & myGUS.gRegData) | val << 8; + ExecuteGlobRegister(); + break; + case 0x305: + myGUS.gRegData = (0xff00 & myGUS.gRegData) | val; + ExecuteGlobRegister(); + break; + + case 0x307: + if(myGUS.gDramAddr < sizeof(GUSRam)) GUSRam[myGUS.gDramAddr] = val; + break; + default: + LOG_MSG("Write GUS at port 0x%x with %x", port, val); + break; + } + + +} + +static void UseDMA(DmaChannel *useDMA) { + Bit32s dmaaddr = myGUS.dmaAddr << 4; + if((myGUS.DMAControl & 0x2) == 0) { + //Write data into UltraSound + Bit32s comsize = useDMA->currcnt; + + useDMA->Read(useDMA->currcnt,&GUSRam[dmaaddr]); + if((myGUS.DMAControl & 0x80) != 0) { + //Invert the MSB to convert twos compliment form + + int i; + if((myGUS.DMAControl & 0x40) == 0) { + // 8-bit data + for(i=dmaaddr;i<(dmaaddr+comsize);i++) GUSRam[i] ^= 0x80; + } else { + // 16-bit data + for(i=dmaaddr+1;i<(dmaaddr+comsize-1);i+=2) GUSRam[i] ^= 0x80; + } + } + } else { + //Read data out of UltraSound + useDMA->Write(useDMA->currcnt,&GUSRam[dmaaddr]); + + } +} + +static void GUS_DMA_Callback(void *useChannel, bool tc) { + DmaChannel *myDMA; + myDMA = (DmaChannel *)useChannel; + + if(tc) { + if((myGUS.DMAControl & 0x20) != 0) { + myGUS.irq.DMATC = true; + PIC_ActivateIRQ(myGUS.irq2); + } + } else { + if ((myGUS.DMAControl & 0x1) != 0) UseDMA(myDMA); + } + + +} + +static void GUS_CallBack(Bit8u * stream,Bit32u len) { + + Bit16s *bufptr; + Bit16s buffer[4096]; + Bit32s tmpbuf[4096]; + + memset(&buffer[0],0,len*4); + memset(&tmpbuf[0],0,len*8); + + int i,t; + for(i=0;i<=myGUS.activechan;i++) { + if (guschan[i]->playing) { + guschan[i]->generateSamples(&buffer[0],len); + + for(t=0;t= 0) { + PIC_ActivateIRQ(myGUS.irq1); + } + } + + if(myGUS.timers[0].active) { + myGUS.timers[0].countdown-=(len * (Bit32u)myGUS.mupersamp); + if(!myGUS.irq.T1) { + if(myGUS.timers[0].countdown < 0) { + if((myGUS.TimerControl & 0x04) !=0) { + PIC_ActivateIRQ(myGUS.irq1); + } + myGUS.irq.T1 = true; + //LOG_MSG("T1 timer expire"); + //myGUS.timers[0].countdown = myGUS.timers[0].setting; + } + } + } + if(myGUS.timers[1].active) { + if(!myGUS.irq.T2) { + myGUS.timers[1].countdown-=(len * (Bit32u)myGUS.mupersamp); + if(myGUS.timers[1].countdown < 0) { + if((myGUS.TimerControl & 0x08) !=0) { + PIC_ActivateIRQ(myGUS.irq1); + } + myGUS.irq.T2 = true; + //LOG_MSG("T2 timer expire"); + //myGUS.timers[1].countdown = myGUS.timers[1].setting; + } + } + } + + + + bufptr = (Bit16s *)stream; + //for(i=0;i> 4)); + b = 1.0+((float)(i & 0xf))/(float)16; + a *= b; + a /= 16; + vol8bit[i] = (Bit16u)a; + } + for(i=0;i<4096;i++) { + float a,b; + a = pow(2,(float)(i >> 8)); + b = 1.0+((float)(i & 0xff))/(float)256; + a *= b; + a /= 16; + vol16bit[i] = (Bit16u)a; + } } +void GUS_Init(Section* sec) { + + + memset(&myGUS,0,sizeof(myGUS)); + memset(GUSRam,0,1024*1024); + + Section_prop * section=static_cast(sec); + if(!section->Get_bool("gus")) return; + myGUS.rate=section->Get_int("rate"); + + myGUS.portbase = section->Get_hex("base") - 0x200; + myGUS.dma1 = section->Get_int("dma1"); + myGUS.dma2 = section->Get_int("dma2"); + myGUS.irq1 = section->Get_int("irq1"); + myGUS.irq2 = section->Get_int("irq2"); + strcpy(&myGUS.ultradir[0], section->Get_string("ultradir")); + + myGUS.timerReg = 85; + myGUS.timers[0].active = false; + myGUS.timers[1].active = false; + + + memset(&myGUS.irq, 0, sizeof(myGUS.irq)); + IRQFifo.stackpos = -1; + myGUS.irqenabled = false; + + // We'll leave the MIDI interface to the MPU-401 + + // Ditto for the Joystick + + // GF1 Synthesizer + + IO_RegisterWriteHandler(0x302 + GUS_BASE,write_gus,"GF1 Page Register"); + IO_RegisterReadHandler(0x302 + GUS_BASE,read_gus,"GF1 Page Register"); + + IO_RegisterWriteHandler(0x303 + GUS_BASE,write_gus,"GF1 Global Register Select"); + IO_RegisterReadHandler(0x303 + GUS_BASE,read_gus,"GF1 Global Register Select"); + + IO_RegisterWriteHandler(0x304 + GUS_BASE,write_gus,"GF1 Global Data Low Byte"); + IO_RegisterReadHandler(0x304 + GUS_BASE,read_gus,"GF1 Global Data Low Byte"); + + IO_RegisterWriteWHandler(0x304 + GUS_BASE,write_gus16); + IO_RegisterReadWHandler(0x304 + GUS_BASE,read_gus16); + + IO_RegisterWriteHandler(0x305 + GUS_BASE,write_gus,"GF1 Global Data High Byte"); + IO_RegisterReadHandler(0x305 + GUS_BASE,read_gus,"GF1 Global Data High Byte"); + + IO_RegisterReadHandler(0x206 + GUS_BASE,read_gus,"GF1 IRQ Status Register"); + + IO_RegisterWriteHandler(0x208 + GUS_BASE,write_gus,"Timer Control Reg"); + IO_RegisterReadHandler(0x208 + GUS_BASE,read_gus,"Timer Control Reg"); + + IO_RegisterWriteHandler(0x209 + GUS_BASE,write_gus,"Timer Data IO"); + + IO_RegisterWriteHandler(0x307 + GUS_BASE,write_gus,"DRAM IO"); + IO_RegisterReadHandler(0x307 + GUS_BASE,read_gus,"DRAM IO"); + + // Board Only + + IO_RegisterWriteHandler(0x200 + GUS_BASE,write_gus,"Mix Control Register"); + IO_RegisterReadHandler(0x20A + GUS_BASE,read_gus,"GUS Undocumented"); + IO_RegisterWriteHandler(0x20B + GUS_BASE,write_gus,"IRQ/DMA Control Register"); + + PIC_RegisterIRQ(myGUS.irq1,0,"GUS"); + PIC_RegisterIRQ(myGUS.irq2,0,"GUS"); + + DmaChannels[myGUS.dma1]->RegisterCallback(GUS_DMA_Callback); + + MakeTables(); + + int i; + for(i=0;i<32;i++) { + guschan[i] = new GUSChannels(i); + } + + // Register the Mixer CallBack + + gus_chan=MIXER_AddChannel(GUS_CallBack,GUS_RATE,"GUS"); + MIXER_SetMode(gus_chan,MIXER_16STEREO); + MIXER_Enable(gus_chan,false); + + int portat = 0x200+GUS_BASE; + // ULTRASND=Port,DMA1,DMA2,IRQ1,IRQ2 + SHELL_AddAutoexec("SET ULTRASND=%3X,%d,%d,%d,%d",portat,myGUS.dma1,myGUS.dma2,myGUS.irq1,myGUS.irq2); + SHELL_AddAutoexec("SET ULTRADIR=%s", myGUS.ultradir); + + +} + + + From 4057f50057575e2a2d4edee15a42babee419aa8a Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Tue, 4 Nov 2003 03:40:22 +0000 Subject: [PATCH 1315/4131] Added port hack to Gravis to aid in GUS detection Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1396 --- src/hardware/adlib.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 41db8d02..d1de1322 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -109,6 +109,10 @@ static Bit8u read_p388(Bit32u port) { static void write_p388(Bit32u port,Bit8u val) { regsel=val; + + // The following writes this value to ultrasounds equivalent register. + // I don't know of any other way to do this + IO_Write(0x248,val); } static void write_p389(Bit32u port,Bit8u val) { From 9d8d93a7ddb8c33bc32d437410bfa8a5a6274a90 Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Tue, 4 Nov 2003 03:40:59 +0000 Subject: [PATCH 1316/4131] Added GUS init section Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1397 --- src/dosbox.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 4c966832..443cd350 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -291,6 +291,27 @@ void DOSBOX_Init(void) { "cmsrate -- Sample rate of cms emulation.\n" ); + secprop=control->AddSection_prop("gus",&GUS_Init); + secprop->Add_bool("gus",true); + secprop->Add_int("rate",22050); + secprop->Add_hex("base",0x240); + secprop->Add_int("irq1",5); + secprop->Add_int("irq2",5); + secprop->Add_int("dma1",3); + secprop->Add_int("dma2",3); + secprop->Add_string("ultradir","C:\\ULTRASND"); + + MSG_Add("GUS_CONFIGFILE_HELP", + "gus -- Enable the Gravis Ultrasound emulation.\n" + "base,irq1,irq2,dma1,dma2 -- The IO/IRQ/DMA addresses of the \n" + " Gravis Ultrasound. (Same IRQ's and DMA's are OK.)\n" + "rate -- Sample rate of Ultrasound emulation.\n" + "ultradir -- Path to Ultrasound directory. In this directory\n" + " there should be a MIDI directory that contains\n" + " the patch files for GUS playback. Patch sets used\n" + " with Timidity should work fine.\n" + ); + secprop=control->AddSection_prop("speaker",&PCSPEAKER_Init); secprop->Add_bool("pcspeaker",true); secprop->Add_int("pcrate",22050); @@ -318,7 +339,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&EMS_Init); secprop->Add_bool("ems",true); secprop->AddInitFunction(&DPMI_Init); - secprop->Add_bool("dpmi",true); + secprop->Add_bool("dpmi",false); MSG_Add("DOS_CONFIGFILE_HELP", "xms -- Enable XMS support.\n" @@ -342,7 +363,8 @@ void DOSBOX_Init(void) { "listenport -- TCP Port the momdem listens on for incoming connections.\n" ); #endif - + + secline=control->AddSection_line("autoexec",&AUTOEXEC_Init); MSG_Add("AUTOEXEC_CONFIGFILE_HELP", From ed4d000c145a12361999e7d0d8dc32b669df48cd Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Tue, 4 Nov 2003 03:41:33 +0000 Subject: [PATCH 1317/4131] Implemented 16-bit DMA support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1398 --- include/dma.h | 333 +++++++++++++++++++++++++++++++++ src/hardware/dma.cpp | 431 ++++++++++++++++++------------------------- 2 files changed, 513 insertions(+), 251 deletions(-) diff --git a/include/dma.h b/include/dma.h index 58f78c69..02819e0c 100644 --- a/include/dma.h +++ b/include/dma.h @@ -16,14 +16,347 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef __DMA_H +#define __DMA_H + +#include "mem.h" + +#define DMA_MODE_DEMAND 0 +#define DMA_MODE_SINGLE 1 +#define DMA_MODE_BLOCK 2 +#define DMA_MODE_CASCADE 3 + +#define DMA_BASEADDR 0 +#define DMA_TRANSCOUNT 1 +#define DMA_PAGEREG 2 + +#define DMA_CMDREG 0 +#define DMA_MODEREG 1 +#define DMA_CLEARREG 2 +#define DMA_DMACREG 3 +#define DMA_CLRMASKREG 4 +#define DMA_SINGLEREG 5 +#define DMA_WRITEALLREG 6 + +static Bit8u ChannelPorts [3][8] = { 0x00, 0x02, 0x04, 0x06, 0xff, 0xc4, 0xc8, 0xcc, + 0x01, 0x03, 0x05, 0x07, 0xff, 0xc6, 0xca, 0xce, + 0x87, 0x83, 0x81, 0x82, 0xff, 0x8b, 0x89, 0x8a }; + +static Bit8u ControllerPorts [2][7] = { 0x08, 0x0b, 0x0c, 0x0d, 0x0e, 0x0a, 0xf, + 0xd0, 0xd6, 0xd8, 0xda, 0xdc, 0xd4, 0xde }; + + typedef void (* DMA_EnableCallBack)(bool enable); +typedef void (* DMA_NewCallBack)(void *useChannel, bool tc); void DMA_SetEnableCallBack(Bitu channel,DMA_EnableCallBack callback); +void DMA_CheckEnabled(void * usechan); + Bitu DMA_8_Read(Bitu channel,Bit8u * buffer,Bitu count); Bitu DMA_8_Write(Bitu dmachan,Bit8u * buffer,Bitu count); Bitu DMA_16_Read(Bitu channel,Bit8u * buffer,Bitu count); Bitu DMA_16_Write(Bitu dmachan,Bit8u * buffer,Bitu count); +extern Bit8u read_dmaB(Bit32u port); +extern Bit16u read_dmaW(Bit32u port); + +extern void write_dmaB(Bit32u port,Bit8u val); +extern void write_dmaW(Bit32u port,Bit16u val); + +class DmaController { +public: + bool flipflop; + Bit8u ctrlnum; +public: + + DmaController(Bit8u num) { + int i; + for(i=0;i<7;i++) { + IO_RegisterReadBHandler(ControllerPorts[num][i],read_dmaB); + IO_RegisterReadWHandler(ControllerPorts[num][i],read_dmaW); + + IO_RegisterWriteBHandler(ControllerPorts[num][i],write_dmaB); + IO_RegisterWriteWHandler(ControllerPorts[num][i],write_dmaW); + } + flipflop = true; + ctrlnum = num; + } + + Bit16u portRead(Bit32u port, bool eightbit); + void portWrite(Bit32u port, Bit16u val, bool eightbit); + +}; + + +#define ff myController->flipflop + +class DmaChannel { +public: + + Bit8u channum; + Bit16u baseaddr; + Bit16u current_addr; + Bit16u pageaddr; + PhysPt physaddr; + PhysPt curraddr; + Bit32s transcnt; + Bit32s currcnt; + DmaController *myController; + bool DMA16; +public: + Bit8u dmamode; + bool dir; + bool autoinit; + Bit8u trantype; + bool masked; + bool enabled; + DMA_EnableCallBack enable_callback; + DMA_NewCallBack newcallback; + + DmaChannel(Bit8u num, DmaController *useController, bool sb) { + int i; + masked = true; + enabled = false; + enable_callback = NULL; + newcallback = NULL; + if(num == 4) return; + + for(i=0;i<3;i++) { + IO_RegisterReadBHandler(ChannelPorts[i][num],read_dmaB); + IO_RegisterReadWHandler(ChannelPorts[i][num],read_dmaW); + + IO_RegisterWriteBHandler(ChannelPorts[i][num],write_dmaB); + IO_RegisterWriteWHandler(ChannelPorts[i][num],write_dmaW); + } + myController = useController; + channum = num; + DMA16 = sb; + baseaddr = 0; + pageaddr = 0; + physaddr = 0; + curraddr = 0; + transcnt = 0; + currcnt = 0; + dir = false; + autoinit = false; + } + + void RegisterCallback(DMA_NewCallBack useCallBack) { newcallback = useCallBack; } + + void reset(void) { + curraddr = physaddr; + currcnt = transcnt+1; + current_addr = baseaddr; + //LOG(LOG_DMA,LOG_NORMAL)("Setup at address %X:%X count %X",pageaddr,baseaddr,currcnt); + } + + void MakeCallback(bool tc) { + if (newcallback != NULL) { + if(tc) { + (*newcallback)(this, true); + } else { + if ((enabled) && (!masked) && (transcnt!=0)) { + (*newcallback)(this, false); + } + } + + } + } + + Bit32u Read(Bit32s requestsize, Bit8u * buffer) { + Bit32s bytesread; + bytesread = 0; + if(autoinit) { + while(requestsize>0) { + if(currcnt>=requestsize) { + MEM_BlockRead(curraddr,buffer,requestsize); + curraddr+=requestsize; + buffer+=requestsize; + currcnt-=requestsize; + bytesread+=requestsize; + requestsize=0; + break; + } else { + MEM_BlockRead(curraddr,buffer,currcnt); + bytesread+=currcnt; + buffer+=currcnt; + requestsize-=currcnt; + reset(); + MakeCallback(true); + } + } + if(currcnt==0) { + reset(); + MakeCallback(true); + } + return bytesread; + + } else { + if(currcnt>=requestsize) { + MEM_BlockRead(curraddr,buffer,requestsize); + curraddr+=requestsize; + buffer+=requestsize; + currcnt-=requestsize; + bytesread+=requestsize; + } else { + MEM_BlockRead(curraddr,buffer,currcnt); + buffer+=currcnt; + requestsize-=currcnt; + bytesread+=currcnt; + currcnt=0; + } + } + if(currcnt==0) MakeCallback(true); + return bytesread; + } + + Bit32u Write(Bit32s requestsize, Bit8u * buffer) { + Bit32s byteswrite; + byteswrite = 0; + if(autoinit) { + while(requestsize>0) { + if(currcnt>=requestsize) { + MEM_BlockWrite(curraddr,buffer,requestsize); + curraddr+=requestsize; + buffer+=requestsize; + currcnt-=requestsize; + byteswrite+=requestsize; + requestsize=0; + break; + } else { + MEM_BlockWrite(curraddr,buffer,currcnt); + byteswrite+=currcnt; + buffer+=currcnt; + requestsize-=currcnt; + reset(); + MakeCallback(true); + } + } + if(currcnt==0) { + reset(); + MakeCallback(true); + } + return byteswrite; + + } else { + if(currcnt>=requestsize) { + MEM_BlockWrite(curraddr,buffer,requestsize); + curraddr+=requestsize; + buffer+=requestsize; + currcnt-=requestsize; + byteswrite+=requestsize; + } else { + MEM_BlockWrite(curraddr,buffer,currcnt); + buffer+=currcnt; + requestsize-=currcnt; + byteswrite+=currcnt; + currcnt=0; + } + } + if(currcnt==0) MakeCallback(true); + return byteswrite; + } + + + void calcPhys(void) { + if (DMA16) { + physaddr = (baseaddr << 1) | ((pageaddr >> 1) << 17); + } else { + physaddr = (baseaddr) | (pageaddr << 16); + } + curraddr = physaddr; + current_addr = baseaddr; + } + + Bit16u portRead(Bit32u port, bool eightbit) { + if (port == ChannelPorts[DMA_BASEADDR][channum]) { + if(eightbit) { + if(ff) { + ff = !ff; + return current_addr & 0xff; + } else { + ff = !ff; + return current_addr >> 8; + } + } else { + return current_addr; + } + } + if (port == ChannelPorts[DMA_TRANSCOUNT][channum]) { + if(eightbit) { + if(ff) { + ff = !ff; + return (Bit8u)(currcnt & 0xff); + } else { + ff = !ff; + return (Bit8u)(currcnt >> 8); + } + } else { + return (Bit16u)currcnt; + } + } + if (port == ChannelPorts[DMA_PAGEREG][channum]) return pageaddr; + return 0xffff; + } + + void portWrite(Bit32u port, Bit16u val, bool eightbit) { + if (port == ChannelPorts[DMA_BASEADDR][channum]) { + if(eightbit) { + if(ff) { + baseaddr = (baseaddr & 0xff00) | (Bit8u)val; + } else { + baseaddr = (baseaddr & 0xff) | (val << 8); + } + ff = !ff; + } else { + baseaddr = val; + } + calcPhys(); + reset(); + } + if (port == ChannelPorts[DMA_TRANSCOUNT][channum]) { + if(eightbit) { + if(ff) { + transcnt = (transcnt & 0xff00) | (Bit8u)val; + } else { + transcnt = (transcnt & 0xff) | (val << 8); + } + ff = !ff; + } else { + transcnt = val; + } + currcnt = transcnt+1; + reset(); + DMA_CheckEnabled(this); + MakeCallback(false); + + } + if (port == ChannelPorts[DMA_PAGEREG][channum]) { + pageaddr = val; + calcPhys(); + reset(); + } + + } + + // Notify channel when mask changes + void Notify(void) { + if(!masked) { + DMA_CheckEnabled(this); + MakeCallback(false); + } + } + +}; + +#undef ff + +extern DmaChannel *DmaChannels[8]; +extern DmaController *DmaControllers[2]; + + + +#endif \ No newline at end of file diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 7a35d16d..d165ac2a 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -20,11 +20,6 @@ Based the port handling from the bochs dma code. */ -/* - TODO - Implement 16-bit dma -*/ - #include #include "dosbox.h" #include "mem.h" @@ -32,259 +27,193 @@ #include "dma.h" #include "pic.h" -#define DMA_MODE_DEMAND 0 -#define DMA_MODE_SINGLE 1 -#define DMA_MODE_BLOCK 2 -#define DMA_MODE_CASCADE 3 - -struct DMA_CHANNEL { - struct { - Bit8u mode_type; - bool address_decrement; - bool autoinit_enable; - Bit8u transfer_type; - } mode; - Bit16u base_address; - Bit16u base_count; - Bit16u current_address; - Bitu current_count; - Bit8u page; - bool masked; - PhysPt address; - bool addr_changed; - bool enabled; - DMA_EnableCallBack enable_callback; -}; +DmaChannel *DmaChannels[8]; +DmaController *DmaControllers[2]; -struct DMA_CONTROLLER { - bool flipflop; - Bit8u status_reg; - Bit8u command_reg; - DMA_CHANNEL chan[4]; -}; +Bit16u DmaController::portRead(Bit32u port, bool eightbit) { + LOG_MSG("Reading DMA controller at %x", port); + return 0xffff; +} -static DMA_CONTROLLER dma[2]; - -void DMA_CheckEnabled(DMA_CHANNEL * chan); -void DMA_SetEnabled(DMA_CHANNEL * chan,bool enabled); - -static Bit8u read_dma(Bit32u port) { - /* only use first dma for now */ - DMA_CONTROLLER * cont=&dma[0]; - DMA_CHANNEL * chan=&cont->chan[port>>1]; - Bit8u ret; - switch (port) { - case 0x00:case 0x02:case 0x04:case 0x06: - if (cont->flipflop) { - ret=chan->current_address & 0xff; - } else { - ret=(chan->current_address>>8)&0xff; - } - cont->flipflop=!cont->flipflop; - break; - case 0x01:case 0x03:case 0x05:case 0x07: - if (cont->flipflop) { - ret=(Bit8u)((chan->current_count-1) & 0xff); - } else { - ret=(Bit8u)(((chan->current_count-1)>>8)&0xff); - } - cont->flipflop=!cont->flipflop; - break; - case 0x08: /* Read Status */ - ret=cont->status_reg; - cont->status_reg&=~0xf; /* Clear lower 4 bits on read */ - break; - case 0x0a: - case 0x0e: - /* Seem to return 0 on a real controller */ - ret=0x0; - break; - default: - LOG(LOG_DMA,LOG_ERROR)("DMA:Unhandled read from %X",port); +void DmaController::portWrite(Bit32u port, Bit16u val, bool eightbit) { + bool found; + found = false; + if(port == ControllerPorts[ctrlnum][DMA_CLRMASKREG]) { + found = true; + flipflop = true; + // Disable DMA requests + // Clear command and status registers } -// LOG_MSG("DMA Read port %x result %x",port,ret); - return ret; -} - -static void write_dma(Bit32u port,Bit8u val) { - /* only use first dma for now */ - DMA_CONTROLLER * cont=&dma[0]; - DMA_CHANNEL * chan; - switch (port) { - case 0x00:case 0x02:case 0x04:case 0x06: - chan=&cont->chan[port>>1]; - if (cont->flipflop) { - chan->base_address=(chan->base_address & 0xff00) | val; - } else { - chan->base_address=(chan->base_address & 0x00ff) | (val<<8); - } - cont->flipflop=!cont->flipflop; - chan->addr_changed=true; - break; - case 0x01:case 0x03:case 0x05:case 0x07: - chan=&cont->chan[port>>1]; - if (cont->flipflop) { - chan->base_count=(chan->base_count & 0xff00) | val; - } else { - chan->base_count=(chan->base_count & 0x00ff) | (val<<8); - } - cont->flipflop=!cont->flipflop; - chan->addr_changed=true; - DMA_CheckEnabled(chan); - break; - case 0x08: /* Command Register */ - if (val != 4) LOG(LOG_DMA,LOG_ERROR)("DMA1:Illegal command %2X",val); - cont->command_reg=val; - break; - case 0x09: /* Request Register */ - if (val&4) { - /* Set Request bit */ - Bitu channel = val & 0x03; - cont->status_reg |= (1 << (channel+4)); - } else { - Bitu channel = val & 0x03; - cont->status_reg &= ~(1 << (channel+4)); - } - break; - case 0x0a: /* single mask bit register */ - chan=&cont->chan[val & 0x3]; - if ((val & 4)>0) { - DMA_SetEnabled(chan,false); - chan->masked=(val & 4)>0; //Set it later - } else { - chan->masked=(val & 4)>0; - DMA_CheckEnabled(chan); - } - break; - case 0x0b: /* mode register */ - chan=&cont->chan[val & 0x3]; - chan->mode.mode_type = (val >> 6) & 0x03; - chan->mode.address_decrement = (val & 0x20) > 0; - chan->mode.autoinit_enable = (val & 0x10) > 0; - chan->mode.transfer_type = (val >> 2) & 0x03; - if (chan->mode.address_decrement) { - LOG(LOG_DMA,LOG_ERROR)("DMA:Address Decrease not supported yet"); - } - DMA_CheckEnabled(chan); - break; - case 0x0c: /* Clear Flip/Flip */ - cont->flipflop=true; - break; - default: - LOG(LOG_DMA,LOG_ERROR)("DMA:Unhandled write %X to %X",static_cast(val),port); - }; -}; - -void write_dma_page(Bit32u port,Bit8u val) { - Bitu channel; - switch (port) { - case 0x81: /* dma0 page register, channel 2 */ - channel=2;break; - case 0x82: /* dma0 page register, channel 3 */ - channel=3;break; - case 0x83: /* dma0 page register, channel 1 */ - channel=1;break; - case 0x87: /* dma0 page register, channel 0 */ - channel=0;break; + if(port == ControllerPorts[ctrlnum][DMA_SINGLEREG]) { + found = true; + int dmachan; + dmachan = (ctrlnum * 2) + (val & 0x3); + DmaChannels[dmachan]->masked = ((val & 0x4) == 0x4); + DmaChannels[dmachan]->Notify(); } - dma[0].chan[channel].page=val; - dma[0].chan[channel].addr_changed=true; -} - -Bit8u read_dma_page(Bit32u port) { - Bitu channel; - switch (port) { - case 0x81: /* dma0 page register, channel 2 */ - channel=2;break; - case 0x82: /* dma0 page register, channel 3 */ - channel=3;break; - case 0x83: /* dma0 page register, channel 1 */ - channel=1;break; - case 0x87: /* dma0 page register, channel 0 */ - channel=0;break; + if(port == ControllerPorts[ctrlnum][DMA_WRITEALLREG]) { + found = true; + int dmachan,i,r; + dmachan = (ctrlnum * 2); + r = 0; + for(i=dmachan;imasked = (((val >> r) & 0x1) == 0x1); + DmaChannels[i]->Notify(); + r++; + } } - return dma[0].chan[channel].page; + if(port == ControllerPorts[ctrlnum][DMA_CLEARREG]) { + found = true; + flipflop = true; + } + if(port == ControllerPorts[ctrlnum][DMA_MODEREG]) { + found = true; + int dmachan; + dmachan = (ctrlnum * 2) + (val & 0x3); + DmaChannels[dmachan]->trantype = (val >> 2) & 0x3; + DmaChannels[dmachan]->autoinit = ((val & 0x10) == 0x10); + DmaChannels[dmachan]->dir = ((val & 0x20) == 0x20); + DmaChannels[dmachan]->dmamode = (val >> 6) & 0x3; + DMA_CheckEnabled(DmaChannels[dmachan]); + } + if(!found) LOG_MSG("Write to DMA port %x with %x", port, val); + } -INLINE void ResetDMA8(DMA_CHANNEL * chan) { - chan->addr_changed=false; - chan->address=(chan->page << 16)+chan->base_address; - chan->current_count=chan->base_count+1; - chan->current_address=chan->base_address; - LOG(LOG_DMA,LOG_NORMAL)("Setup at address %X:%X count %X",chan->page<<12,chan->base_address,chan->current_count); + +static Bit16u readDMAPorts(Bit32u port, bool eightbit) { + int i,j; + + // Check for controller access + for(i=0;i<2;i++) { + for(j=0;j<7;j++) { + if(ControllerPorts[i][j] == port) { + return DmaControllers[i]->portRead(port, eightbit); + } + } + } + + // Check for DMA access + for(i=0;i<8;i++) { + for(j=0;j<3;j++) { + if(ChannelPorts[j][i] == port) { + return DmaChannels[i]->portRead(port, eightbit); + } + } + } + + LOG_MSG("Unmatched read port %x", port); + + return 0xffff; + } +static void writeDMAPorts(Bit32u port, Bit16u val, bool eightbit) { + int i,j; + + // Check for controller access + for(i=0;i<2;i++) { + for(j=0;j<7;j++) { + if(ControllerPorts[i][j] == port) { + DmaControllers[i]->portWrite(port,val,eightbit); + return; + } + } + } + + // Check for DMA access + for(i=0;i<8;i++) { + for(j=0;j<3;j++) { + if(ChannelPorts[j][i] == port) { + DmaChannels[i]->portWrite(port,val,eightbit); + return; + } + } + } + + LOG_MSG("Unmatched write port %x - val %x", port, val); + +} + +Bit8u read_dmaB(Bit32u port) { return (Bit8u)readDMAPorts(port,true); } + +Bit16u read_dmaW(Bit32u port) { return readDMAPorts(port,false); } + +void write_dmaB(Bit32u port,Bit8u val) { writeDMAPorts(port,val,true); } + +void write_dmaW(Bit32u port,Bit16u val) { writeDMAPorts(port,val,false); } + + +// Deprecated DMA read/write routines -- Keep compatibility with Sound Blaster Bitu DMA_8_Read(Bitu dmachan,Bit8u * buffer,Bitu count) { - DMA_CHANNEL * chan=&dma[0].chan[dmachan]; + DmaChannel *chan=DmaChannels[dmachan]; + if (chan->masked) return 0; if (!count) return 0; - if (chan->addr_changed) ResetDMA8(chan); - if (chan->current_count>count) { - MEM_BlockRead(chan->address,buffer,count); - chan->address+=count; - chan->current_address+=count; - chan->current_count-=count; + if (chan->currcnt>count) { + MEM_BlockRead(chan->curraddr,buffer,count); + chan->curraddr+=count; + chan->current_addr+=count; + chan->currcnt-=count; return count; } else { - /* Copy remaining piece of first buffer */ - MEM_BlockRead(chan->address,buffer,chan->current_count); - if (!chan->mode.autoinit_enable) { - /* Set the end of counter bit */ - dma[0].status_reg|=(1 << dmachan); - count=chan->current_count; - chan->address+=count; - chan->current_count=0; + // Copy remaining piece of first buffer + MEM_BlockRead(chan->curraddr,buffer,chan->currcnt); + if (!chan->autoinit) { + // Set the end of counter bit + //dma[0].status_reg|=(1 << dmachan); + count=chan->currcnt; + chan->curraddr+=count; + chan->current_addr+=count; + chan->currcnt=0; chan->enabled=false; LOG(LOG_DMA,LOG_NORMAL)("8-bit Channel %d reached terminal count"); return count; } else { - buffer+=chan->current_count; - Bitu left=count-(Bit16u)chan->current_count; - /* Autoinit reset the dma channel */ - ResetDMA8(chan); - /* Copy the rest of the buffer */ - MEM_BlockRead(chan->address,buffer,left); - chan->address+=left; - chan->current_address+=left; - chan->current_count-=left; + buffer+=chan->currcnt; + Bitu left=count-(Bit16u)chan->currcnt; + // Autoinit reset the dma channel + chan->reset(); + // Copy the rest of the buffer + MEM_BlockRead(chan->curraddr,buffer,left); + chan->curraddr+=left; + chan->current_addr+=left; + chan->currcnt-=left; return count; } } } Bitu DMA_8_Write(Bitu dmachan,Bit8u * buffer,Bitu count) { - DMA_CHANNEL * chan=&dma[0].chan[dmachan]; + DmaChannel *chan=DmaChannels[dmachan]; + if (chan->masked) return 0; if (!count) return 0; - if (chan->addr_changed) ResetDMA8(chan); - if (chan->current_count>count) { - MEM_BlockWrite(chan->address,buffer,count); - chan->address+=count; - chan->current_address+=count; - chan->current_count-=count; + if (chan->currcnt>count) { + MEM_BlockWrite(chan->curraddr,buffer,count); + chan->curraddr+=count; + chan->currcnt-=count; return count; } else { - /* Copy remaining piece of first buffer */ - MEM_BlockWrite(chan->address,buffer,chan->current_count); - if (!chan->mode.autoinit_enable) { - /* Set the end of counter bit */ - dma[0].status_reg|=(1 << dmachan); - count=chan->current_count; - chan->current_address+=count;; - chan->current_count=0; - chan->enabled=false; + // Copy remaining piece of first buffer + MEM_BlockWrite(chan->curraddr,buffer,chan->currcnt); + if (!chan->autoinit) { + // Set the end of counter bit + //dma[0].status_reg|=(1 << dmachan); + count=chan->currcnt; + chan->curraddr+=count;; + chan->currcnt=0; return count; } else { - buffer+=chan->current_count; - Bitu left=count-(Bit16u)chan->current_count; - /* Autoinit reset the dma channel */ - ResetDMA8(chan); - /* Copy the rest of the buffer */ - MEM_BlockWrite(chan->address,buffer,left); - chan->address+=left; - chan->current_address+=left; - chan->current_count-=left; + buffer+=chan->currcnt; + Bitu left=count-(Bit16u)chan->currcnt; + // Autoinit reset the dma channel + chan->reset(); + // Copy the rest of the buffer + MEM_BlockWrite(chan->curraddr,buffer,left); + chan->curraddr+=left; + chan->currcnt-=left; return count; } } @@ -302,18 +231,21 @@ Bitu DMA_16_Write(Bitu dmachan,Bit8u * buffer,Bitu count) { return 0; } -void DMA_SetEnabled(DMA_CHANNEL * chan,bool enabled) { +void DMA_SetEnabled(DmaChannel * chan,bool enabled) { if (chan->enabled == enabled) return; chan->enabled=enabled; if (chan->enable_callback) (*chan->enable_callback)(enabled); } -void DMA_CheckEnabled(DMA_CHANNEL * chan) { +void DMA_CheckEnabled(void * usechan) { + DmaChannel * chan; + chan = (DmaChannel *)usechan; + bool enabled; if (chan->masked) enabled=false; else { - if (chan->mode.autoinit_enable) enabled=true; - else if (chan->current_count || chan->addr_changed) enabled=true; + if (chan->autoinit) enabled=true; + else if (chan->currcnt) enabled=true; else enabled=false; } DMA_SetEnabled(chan,enabled); @@ -321,31 +253,28 @@ void DMA_CheckEnabled(DMA_CHANNEL * chan) { void DMA_SetEnableCallBack(Bitu channel,DMA_EnableCallBack callback) { - DMA_CHANNEL * chan; - if (channel<4) { - chan=&dma[0].chan[channel]; - } else if (channel<8) { - chan=&dma[1].chan[channel-4]; - } else return; + DmaChannel * chan; + chan = DmaChannels[channel]; chan->enabled=false; chan->enable_callback=callback; DMA_CheckEnabled(chan); } -void DMA_Init(Section* sec) { - Bitu i; - for (i=0;i<0x10;i++) { - IO_RegisterWriteHandler(i,write_dma,"DMA1"); - IO_RegisterReadHandler(i,read_dma,"DMA1"); - } - IO_RegisterWriteHandler(0x81,write_dma_page,"DMA Pages"); - IO_RegisterWriteHandler(0x82,write_dma_page,"DMA Pages"); - IO_RegisterWriteHandler(0x83,write_dma_page,"DMA Pages"); - IO_RegisterWriteHandler(0x87,write_dma_page,"DMA Pages"); - IO_RegisterReadHandler(0x81,read_dma_page,"DMA Pages"); - IO_RegisterReadHandler(0x82,read_dma_page,"DMA Pages"); - IO_RegisterReadHandler(0x83,read_dma_page,"DMA Pages"); - IO_RegisterReadHandler(0x87,read_dma_page,"DMA Pages"); +void DMA_Init(Section* sec) { + + Bitu i; + + DmaControllers[0] = new DmaController(0); + DmaControllers[1] = new DmaController(1); + + for(i=0;i<4;i++) { + DmaChannels[i] = new DmaChannel(i,DmaControllers[0],false); + } + for(i=4;i<8;i++) { + DmaChannels[i] = new DmaChannel(i,DmaControllers[1],true); + } } + + From c0eeebc16a25546f73f864581b8f1eb32b927721 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 5 Nov 2003 19:39:51 +0000 Subject: [PATCH 1318/4131] Some changes for main interrupt handler and endian fixes for descriptor structures Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1399 --- include/cpu.h | 69 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 17 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 3aeeae1d..90ae88ef 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -33,18 +33,9 @@ extern Bits CPU_CycleMax; typedef Bits (CPU_Decoder)(void); extern CPU_Decoder * cpudecoder; - //CPU Stuff -void SetCPU16bit( ); -enum CODE_TYPE { - CODE_REAL, - CODE_PMODE16, - CODE_PMODE32, - CODE_INIT, -}; - -extern bool parity_lookup[256]; +extern Bit16u parity_lookup[256]; void CPU_LLDT(Bitu selector); void CPU_LTR(Bitu selector); @@ -70,12 +61,27 @@ bool CPU_LMSW(Bitu word); void CPU_VERR(Bitu selector); void CPU_VERW(Bitu selector); -bool CPU_JMP(bool use32,Bitu selector,Bitu offset); -bool CPU_CALL(bool use32,Bitu selector,Bitu offset); -bool CPU_RET(bool use32,Bitu bytes); +void CPU_JMP(bool use32,Bitu selector,Bitu offset); +void CPU_CALL(bool use32,Bitu selector,Bitu offset); +void CPU_RET(bool use32,Bitu bytes); -bool Interrupt(Bitu num); -bool CPU_IRET(bool use32); +#define CPU_INT_HARDWARE 0x1 +#define CPU_INT_HAS_ERROR 0x2 + +void CPU_Interrupt(Bitu num,Bitu error_code,Bitu type); +INLINE void CPU_HW_Interrupt(Bitu num) { + CPU_Interrupt(num,0,CPU_INT_HARDWARE); +} +INLINE void CPU_SW_Interrupt(Bitu num) { + CPU_Interrupt(num,0,0); +} +void CPU_Exception(Bitu num,Bitu error_code=0); + +INLINE void Interrupt(Bitu num) { + CPU_SW_Interrupt(num); +} + +void CPU_IRET(bool use32); void CPU_SetSegGeneral(SegNames seg,Bitu value); void CPU_CPUID(void); @@ -169,9 +175,23 @@ struct TSS_386 { Bit16u ldt, RESERVED10; /* The local descriptor table */ Bit16u trap; /* The trap flag (for debugging) */ Bit16u io; /* The I/O Map base address */ -} GCC_ATTRIBUTE(packed);; +} GCC_ATTRIBUTE(packed); 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; @@ -184,9 +204,20 @@ struct S_Descriptor { Bit32u big :1; Bit32u g :1; Bit32u base_24_31 :8; +#endif }GCC_ATTRIBUTE(packed); struct G_Descriptor { +#ifdef WORDS_BIGENDIAN + Bit32u selector: 16; + Bit32u offset_0_15 :16; + Bit32u offset_16_31 :16; + Bit32u p :1; + Bit32u dpl :2; + Bit32u type :5; + Bit32u reserved :3; + Bit32u paramcount :5; +#else Bit32u offset_0_15 :16; Bit32u selector :16; Bit32u paramcount :5; @@ -195,6 +226,7 @@ struct G_Descriptor { Bit32u dpl :2; Bit32u p :1; Bit32u offset_16_31 :16; +#endif } GCC_ATTRIBUTE(packed); #pragma pack() @@ -363,9 +395,12 @@ struct CPUBlock { bool big; } stack; struct { - CODE_TYPE type; /* What kind of code are we running */ bool big; } code; + struct { + Bitu cs,eip; + CPU_Decoder * old_decoder; + } hlt; }; extern CPUBlock cpu; From e23bab62ff7d9414ab4fb6733efdaafb6cade05c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 5 Nov 2003 19:41:10 +0000 Subject: [PATCH 1319/4131] Removed code type options Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1400 --- src/cpu/cpu.cpp | 111 ++++++++++++++++++------------------------------ 1 file changed, 41 insertions(+), 70 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 050861d7..9c6ae0d7 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.36 2003-10-26 19:00:38 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.37 2003-11-05 19:41:10 harekiet Exp $ */ #include #include "dosbox.h" @@ -46,6 +46,9 @@ void CPU_Real_16_Slow_Start(bool big); void CPU_Core_Full_Start(bool big); void CPU_Core_Normal_Start(bool big); +static Bits CPU_Core_Normal_Decode(void); +static Bits CPU_Core_Full_Decode(void); + #if 1 #define realcore_start CPU_Core_Normal_Start @@ -94,26 +97,12 @@ void CPU_SetFlags(Bitu word) { reg_flags=(word|2)&~0x28; } -bool CPU_CheckCodeType(CODE_TYPE type) { - if (cpu.code.type==type) return true; - cpu.code.type=type; - switch (cpu.code.type) { - case CODE_REAL: - realcore_start(false); - cpu.code.big = false; - break; - case CODE_PMODE16: - pmodecore_start(false); - break; - case CODE_PMODE32: - pmodecore_start(true); - break; - } - return false; +Bit8u lastint; +void CPU_Exception(Bitu num,Bitu error_code) { + CPU_Interrupt(num,0,0); } -Bit8u lastint; -bool Interrupt(Bitu num) { +void CPU_Interrupt(Bitu num,Bitu error_code,Bitu type) { lastint=num; #if C_DEBUG switch (num) { @@ -124,10 +113,12 @@ bool Interrupt(Bitu num) { #endif E_Exit("Call to interrupt 0xCD this is BAD"); case 0x03: - if (DEBUG_Breakpoint()) return true; + if (DEBUG_Breakpoint()) { + CPU_Cycles=0; + return; + } }; #endif - if (!cpu.pmode) { /* Save everything on a 16-bit stack */ CPU_Push16(reg_flags & 0xffff); @@ -140,7 +131,7 @@ bool Interrupt(Bitu num) { Segs.val[cs]=mem_readw((num << 2)+2); Segs.phys[cs]=Segs.val[cs]<<4; cpu.code.big=false; - return CPU_CheckCodeType(CODE_REAL); + return; } else { /* Protected Mode Interrupt */ Descriptor gate; @@ -192,40 +183,16 @@ bool Interrupt(Bitu num) { cpu.code.big=desc.Big()>0; LOG(LOG_CPU,LOG_NORMAL)("INT:Gate to %X:%X big %d %s",selector,reg_eip,desc.Big(),gate.Type() & 0x8 ? "386" : "286"); reg_eip=offset; - return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); + return; } default: E_Exit("Illegal descriptor type %X for int %X",gate.Type(),num); } } assert(1); - return false; } - -bool CPU_Exception(Bitu exception,Bit32u error_code) { - if (!cpu.pmode) { /* RealMode Interrupt */ - /* Save everything on a 16-bit stack */ - CPU_Push16(reg_flags & 0xffff); - CPU_Push16(SegValue(cs)); - CPU_Push16(reg_ip); - SETFLAGBIT(IF,false); - SETFLAGBIT(TF,false); - /* Get the new CS:IP from vector table */ - reg_eip=mem_readw(exception << 2); - Segs.val[cs]=mem_readw((exception << 2)+2); - Segs.phys[cs]=Segs.val[cs]<<4; - cpu.code.big=false; - return CPU_CheckCodeType(CODE_REAL); - } else { /* Protected Mode Exception */ - - - - } - return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); -} - -bool CPU_IRET(bool use32) { +void CPU_IRET(bool use32) { if (!cpu.pmode || cpu.v86) { /* RealMode IRET */ if (use32) { reg_eip=CPU_Pop32(); @@ -237,11 +204,11 @@ bool CPU_IRET(bool use32) { CPU_SetFlagsw(CPU_Pop16()); } cpu.code.big=false; - return CPU_CheckCodeType(CODE_REAL); + return; } else { /* Protected mode IRET */ /* Check if this is task IRET */ if (GETFLAG(NT)) { - if (GETFLAG(VM)) E_Exit("Pmode IRET with VM bit set"); + if (GETFLAG(VM)) E_Exit("Pmode IRET with VM bit set"); E_Exit("Task IRET"); @@ -314,12 +281,11 @@ bool CPU_IRET(bool use32) { //TODO Maybe validate other segments, but why would anyone use them? LOG(LOG_CPU,LOG_NORMAL)("IRET:Outer level return to %X:X big %d",selector,offset,cpu.code.big); } - return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); + return; } - return false; } -bool CPU_JMP(bool use32,Bitu selector,Bitu offset) { +void CPU_JMP(bool use32,Bitu selector,Bitu offset) { if (!cpu.pmode || cpu.v86) { if (!use32) { reg_eip=offset&0xffff; @@ -328,7 +294,7 @@ bool CPU_JMP(bool use32,Bitu selector,Bitu offset) { } SegSet16(cs,selector); cpu.code.big=false; - return CPU_CheckCodeType(CODE_REAL); + return; } else { Bitu rpl=selector & 3; Descriptor desc; @@ -350,18 +316,17 @@ CODE_jmp: cpu.code.big=desc.Big()>0; Segs.val[cs]=(selector & 0xfffc) | cpu.cpl; reg_eip=offset; - return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); + return; default: E_Exit("JMP Illegal descriptor type %X",desc.Type()); } } assert(1); - return false; } -bool CPU_CALL(bool use32,Bitu selector,Bitu offset) { +void CPU_CALL(bool use32,Bitu selector,Bitu offset) { if (!cpu.pmode || cpu.v86) { if (!use32) { CPU_Push16(SegValue(cs)); @@ -374,7 +339,7 @@ bool CPU_CALL(bool use32,Bitu selector,Bitu offset) { } cpu.code.big=false; SegSet16(cs,selector); - return CPU_CheckCodeType(CODE_REAL); + return; } else { Descriptor call; Bitu rpl=selector & 3; @@ -405,7 +370,7 @@ call_code: cpu.code.big=call.Big()>0; Segs.val[cs]=(selector & 0xfffc) | cpu.cpl; reg_eip=offset; - return CPU_CheckCodeType(cpu.code.big ? CODE_PMODE32 : CODE_PMODE16); + return; case DESC_286_CALL_GATE: { if (call.DPL() Date: Wed, 5 Nov 2003 19:43:02 +0000 Subject: [PATCH 1320/4131] parity table changed to bit16u Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1401 --- src/cpu/flags.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 5bdb3b8d..441fd2e7 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -546,7 +546,7 @@ again: return false; } -bool parity_lookup[256] = { +Bit16u parity_lookup[256] = { 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, From f28bdda7b1f32415069f70c06f162e6f0e19fb97 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 5 Nov 2003 19:45:07 +0000 Subject: [PATCH 1321/4131] Far jmps/calls interrupts restart the core Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1402 --- src/cpu/core_full.cpp | 5 ++-- src/cpu/core_full/load.h | 62 +++++++++++++++++----------------------- src/cpu/core_full/op.h | 48 +++++++++++-------------------- 3 files changed, 45 insertions(+), 70 deletions(-) diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 803457c4..a6658cfe 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -63,13 +63,14 @@ typedef PhysPt EAPoint; Bit8u new_num=blah; \ IPPoint=inst.start_entry; \ LEAVECORE; \ - Interrupt(new_num); \ + CPU_Exception(new_num,0); \ LoadIP(); \ goto nextopcode; \ } Bits Full_DeCode(void) { FullData inst; +restart_core: if (!cpu.code.big) { inst.start_prefix=0x0;; inst.start_entry=0x0; @@ -83,6 +84,7 @@ Bits Full_DeCode(void) { while (CPU_Cycles>0) { #if C_DEBUG cycle_count++; + CPU_Cycles--; #if C_HEAVY_DEBUG SaveIP(); if (DEBUG_HeavyIsBreakpoint()) { @@ -101,7 +103,6 @@ restartopcode: #include "core_full/op.h" #include "core_full/save.h" nextopcode:; - CPU_Cycles--; } LEAVECORE; return CBRET_NONE; diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 6fd52404..1acb09af 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -273,49 +273,41 @@ l_M_Ed: inst.op1.d=4; break; case D_IRETw: - lflags.type=t_UNKNOWN; - if (!CPU_IRET(false)) return CBRET_NONE; + LEAVECORE; + CPU_IRET(false); if (GETFLAG(IF) && PIC_IRQCheck) { return CBRET_NONE; } - LoadIP(); - goto nextopcode; + goto restart_core; case D_IRETd: - lflags.type=t_UNKNOWN; - if (!CPU_IRET(true)) return CBRET_NONE; + LEAVECORE; + CPU_IRET(true); if (GETFLAG(IF) && PIC_IRQCheck) { return CBRET_NONE; } - LoadIP(); - goto nextopcode; + goto restart_core; case D_RETFwIw: - if (!CPU_RET(false,Fetchw())) { - FillFlags(); - return CBRET_NONE; + { + Bitu words=Fetchw(); + LEAVECORE; + CPU_RET(false,words); + goto restart_core; } - LoadIP(); - goto nextopcode; case D_RETFw: - if (!CPU_RET(false,0)) { - FillFlags(); - return CBRET_NONE; - } - LoadIP(); - goto nextopcode; + LEAVECORE; + CPU_RET(false,0); + goto restart_core; case D_RETFdIw: - if (!CPU_RET(true,Fetchw())) { - FillFlags(); - return CBRET_NONE; + { + Bitu words=Fetchw(); + LEAVECORE; + CPU_RET(true,words); + goto restart_core; } - LoadIP(); - goto nextopcode; case D_RETFd: - if (!CPU_RET(true,0)) { - FillFlags(); - return CBRET_NONE; - } - LoadIP(); - goto nextopcode; + LEAVECORE; + CPU_RET(true,0); + goto restart_core; /* Direct operations */ case L_STRING: #include "string.h" @@ -378,16 +370,14 @@ l_M_Ed: } goto nextopcode; case D_STC: - SETFLAGBIT(CF,true); - SetTypeCF(); + FillFlags();SETFLAGBIT(CF,true); goto nextopcode; case D_CLC: - SETFLAGBIT(CF,false); - SetTypeCF(); + FillFlags();SETFLAGBIT(CF,false); goto nextopcode; case D_CMC: - SETFLAGBIT(CF,!get_CF()); - SetTypeCF(); + FillFlags(); + SETFLAGBIT(CF,!(reg_flags & FLAG_CF)); goto nextopcode; case D_CLD: SETFLAGBIT(DF,false); diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 84bccea9..6137cd6a 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -33,14 +33,14 @@ switch (inst.code.op) { lflags.type=inst.code.op; break; case t_ADCb: case t_ADCw: case t_ADCd: - lflags.oldcf=get_CF(); + lflags.oldcf=get_CF()!=0; lf_var1d=inst.op1.d; lf_var2d=inst.op2.d; inst.op1.d=lf_resd=lf_var1d + lf_var2d + lflags.oldcf; lflags.type=inst.code.op; break; case t_SBBb: case t_SBBw: case t_SBBd: - lflags.oldcf=get_CF(); + lflags.oldcf=get_CF()!=0; lf_var1d=inst.op1.d; lf_var2d=inst.op2.d; inst.op1.d=lf_resd=lf_var1d - lf_var2d - lflags.oldcf; @@ -320,45 +320,29 @@ switch (inst.code.op) { Push_32(reg_eip); break; case O_CALLFw: - SaveIP(); - if (!CPU_CALL(false,inst.op2.d,inst.op1.d)) { - FillFlags(); - return CBRET_NONE; - } - LoadIP(); - goto nextopcode; + LEAVECORE; + CPU_CALL(false,inst.op2.d,inst.op1.d); + goto restart_core; case O_CALLFd: - SaveIP(); - if (!CPU_CALL(true,inst.op2.d,inst.op1.d)) { - FillFlags(); - return CBRET_NONE; - } - LoadIP(); - goto nextopcode; + LEAVECORE; + CPU_CALL(true,inst.op2.d,inst.op1.d); + goto restart_core; case O_JMPFw: - if (!CPU_JMP(false,inst.op2.d,inst.op1.d)){ - FillFlags(); - return CBRET_NONE; - } - LoadIP(); - goto nextopcode; + LEAVECORE; + CPU_JMP(false,inst.op2.d,inst.op1.d); + goto restart_core; case O_JMPFd: - if (!CPU_JMP(true,inst.op2.d,inst.op1.d)) { - FillFlags(); - return CBRET_NONE; - } - LoadIP(); - goto nextopcode; - + LEAVECORE; + CPU_JMP(true,inst.op2.d,inst.op1.d); + goto restart_core; case O_INT: LEAVECORE; #if C_DEBUG if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint()) return debugCallback; else if (DEBUG_IntBreakpoint(inst.op1.b)) return debugCallback; #endif - if (!Interrupt(inst.op1.b)) return CBRET_NONE; - LoadIP(); - break; + Interrupt(inst.op1.b); + goto restart_core; case O_INb: reg_al=IO_Read(inst.op1.d); goto nextopcode; From b4753c5c62ac5241f26869fd76e6d21a4620452d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 5 Nov 2003 19:48:49 +0000 Subject: [PATCH 1322/4131] Far jmps/calls interrupts restart the core Changes for new lazy flag testing Removed carry flag only changing type Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1403 --- src/cpu/core_normal.cpp | 16 ++-- src/cpu/core_normal/prefix_0f.h | 79 ++++++++--------- src/cpu/core_normal/prefix_66.h | 76 ++++++---------- src/cpu/core_normal/prefix_66_0f.h | 44 +++++---- src/cpu/core_normal/prefix_none.h | 138 +++++++++++++---------------- src/cpu/core_normal/support.h | 5 +- 6 files changed, 155 insertions(+), 203 deletions(-) diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index fded8ef7..34c95897 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -156,6 +156,13 @@ static Bits CPU_Core_Normal_Decode_Trap(void); static Bits CPU_Core_Normal_Decode(void) { decode_start: + if (cpu.code.big) { + core.index_default=0x200; + core.prefix_default=PREFIX_ADDR; + } else { + core.index_default=0; + core.prefix_default=0; + } LOADIP; lflags.type=t_UNKNOWN; while (CPU_Cycles>0) { @@ -214,16 +221,7 @@ static Bits CPU_Core_Normal_Decode_Trap(void) { void CPU_Core_Normal_Start(bool big) { - if (GETFLAG(TF)) cpudecoder=CPU_Core_Normal_Decode_Trap; else cpudecoder=CPU_Core_Normal_Decode; - - if (big) { - core.index_default=0x200; - core.prefix_default=PREFIX_ADDR; - } else { - core.index_default=0; - core.prefix_default=0; - } } diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index d4923ffb..d08a2a36 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -178,69 +178,69 @@ } break; CASE_0F_W(0x80) /* JO */ - JumpSIw(get_OF());break; + JumpSIw(TFLG_O);break; CASE_0F_W(0x81) /* JNO */ - JumpSIw(!get_OF());break; + JumpSIw(TFLG_NO);break; CASE_0F_W(0x82) /* JB */ - JumpSIw(get_CF());break; + JumpSIw(TFLG_B);break; CASE_0F_W(0x83) /* JNB */ - JumpSIw(!get_CF());break; + JumpSIw(TFLG_NB);break; CASE_0F_W(0x84) /* JZ */ - JumpSIw(get_ZF());break; + JumpSIw(TFLG_Z);break; CASE_0F_W(0x85) /* JNZ */ - JumpSIw(!get_ZF());break; + JumpSIw(TFLG_NZ);break; CASE_0F_W(0x86) /* JBE */ - JumpSIw(get_CF() || get_ZF());break; + JumpSIw(TFLG_BE);break; CASE_0F_W(0x87) /* JNBE */ - JumpSIw(!get_CF() && !get_ZF());break; + JumpSIw(TFLG_NBE);break; CASE_0F_W(0x88) /* JS */ - JumpSIw(get_SF());break; + JumpSIw(TFLG_S);break; CASE_0F_W(0x89) /* JNS */ - JumpSIw(!get_SF());break; + JumpSIw(TFLG_NS);break; CASE_0F_W(0x8a) /* JP */ - JumpSIw(get_PF());break; + JumpSIw(TFLG_P);break; CASE_0F_W(0x8b) /* JNP */ - JumpSIw(!get_PF());break; + JumpSIw(TFLG_NP);break; CASE_0F_W(0x8c) /* JL */ - JumpSIw(get_SF() != get_OF());break; + JumpSIw(TFLG_L);break; CASE_0F_W(0x8d) /* JNL */ - JumpSIw(get_SF() == get_OF());break; + JumpSIw(TFLG_NL);break; CASE_0F_W(0x8e) /* JLE */ - JumpSIw(get_ZF() || (get_SF() != get_OF()));break; + JumpSIw(TFLG_LE);break; CASE_0F_W(0x8f) /* JNLE */ - JumpSIw((get_SF() == get_OF()) && !get_ZF());break; + JumpSIw(TFLG_NLE);break; CASE_0F_B(0x90) /* SETO */ - SETcc(get_OF());break; + SETcc(TFLG_O);break; CASE_0F_B(0x91) /* SETNO */ - SETcc(!get_OF());break; + SETcc(TFLG_NO);break; CASE_0F_B(0x92) /* SETB */ - SETcc(get_CF());break; + SETcc(TFLG_B);break; CASE_0F_B(0x93) /* SETNB */ - SETcc(!get_CF());break; + SETcc(TFLG_NB);break; CASE_0F_B(0x94) /* SETZ */ - SETcc(get_ZF());break; + SETcc(TFLG_Z);break; CASE_0F_B(0x95) /* SETNZ */ - SETcc(!get_ZF()); break; + SETcc(TFLG_NZ); break; CASE_0F_B(0x96) /* SETBE */ - SETcc(get_CF() || get_ZF());break; + SETcc(TFLG_BE);break; CASE_0F_B(0x97) /* SETNBE */ - SETcc(!get_CF() && !get_ZF());break; + SETcc(TFLG_NBE);break; CASE_0F_B(0x98) /* SETS */ - SETcc(get_SF());break; + SETcc(TFLG_S);break; CASE_0F_B(0x99) /* SETNS */ - SETcc(!get_SF());break; + SETcc(TFLG_NS);break; CASE_0F_B(0x9a) /* SETP */ - SETcc(get_PF());break; + SETcc(TFLG_P);break; CASE_0F_B(0x9b) /* SETNP */ - SETcc(!get_PF());break; + SETcc(TFLG_NP);break; CASE_0F_B(0x9c) /* SETL */ - SETcc(get_SF() != get_OF());break; + SETcc(TFLG_L);break; CASE_0F_B(0x9d) /* SETNL */ - SETcc(get_SF() == get_OF());break; + SETcc(TFLG_NL);break; CASE_0F_B(0x9e) /* SETLE */ - SETcc(get_ZF() || (get_SF() != get_OF()));break; + SETcc(TFLG_LE);break; CASE_0F_B(0x9f) /* SETNLE */ - SETcc((get_SF() == get_OF()) && !get_ZF());break; + SETcc(TFLG_NLE);break; CASE_0F_W(0xa0) /* PUSH FS */ Push_16(SegValue(fs));break; @@ -250,7 +250,7 @@ CPU_CPUID();break; CASE_0F_W(0xa3) /* BT Ew,Gw */ { - GetRMrw; + FillFlags();GetRMrw; Bit16u mask=1 << (*rmrw & 15); if (rm >= 0xc0 ) { GetEArw; @@ -259,7 +259,6 @@ GetEAa;Bit16u old=LoadMw(eaa); SETFLAGBIT(CF,(old & mask)); } - SetTypeCF(); break; } CASE_0F_W(0xa4) /* SHLD Ew,Gw,Ib */ @@ -274,7 +273,7 @@ CPU_SetSegGeneral(gs,Pop_16());break; CASE_0F_W(0xab) /* BTS Ew,Gw */ { - GetRMrw; + FillFlags();GetRMrw; Bit16u mask=1 << (*rmrw & 15); if (rm >= 0xc0 ) { GetEArw; @@ -285,7 +284,6 @@ SETFLAGBIT(CF,(old & mask)); SaveMw(eaa,old | mask); } - SetTypeCF(); break; } CASE_0F_W(0xac) /* SHRD Ew,Gw,Ib */ @@ -305,7 +303,7 @@ } CASE_0F_W(0xb3) /* BTR Ew,Gw */ { - GetRMrw; + FillFlags();GetRMrw; Bit16u mask=1 << (*rmrw & 15); if (rm >= 0xc0 ) { GetEArw; @@ -316,7 +314,6 @@ SETFLAGBIT(CF,(old & mask)); SaveMw(eaa,old & ~mask); } - SetTypeCF(); break; } CASE_0F_W(0xb4) /* LFS Ew */ @@ -348,7 +345,7 @@ } CASE_0F_W(0xba) /* GRP8 Ew,Ib */ { - GetRM; + FillFlags();GetRM; if (rm >= 0xc0 ) { GetEArw; Bit16u mask=1 << (Fetchb() & 15); @@ -388,12 +385,11 @@ E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38); } } - SetTypeCF(); break; } CASE_0F_W(0xbb) /* BTC Ew,Gw */ { - GetRMrw; + FillFlags();GetRMrw; Bit16u mask=1 << (*rmrw & 15); if (rm >= 0xc0 ) { GetEArw; @@ -404,7 +400,6 @@ SETFLAGBIT(CF,(old & mask)); SaveMw(eaa,old ^ mask); } - SetTypeCF(); break; } CASE_0F_W(0xbc) /* BSF Gw,Ew */ diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index b64b65c0..cd0b2ee4 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -341,13 +341,9 @@ CASE_D(0x9a) /* CALL FAR Ad */ { Bit32u newip=Fetchd();Bit16u newcs=Fetchw(); - SAVEIP; - if (CPU_CALL(true,newcs,newip)) { - LOADIP; - } else { - FillFlags();return CBRET_NONE; - } - break; + LEAVECORE; + CPU_CALL(true,newcs,newip); + goto decode_start; } CASE_D(0x9c) /* PUSHFD */ FillFlags(); @@ -475,38 +471,32 @@ break; CASE_D(0xca) /* RETF Iw */ { - if (CPU_RET(true,Fetchw())) { - LOADIP; - } else { - FillFlags();return CBRET_NONE; - } - break; - } + Bitu words=Fetchw(); + LEAVECORE; + CPU_RET(true,words); + goto decode_start; + } CASE_D(0xcb) /* RETF */ { - if (CPU_RET(true,0)) { - LOADIP; - } else { - FillFlags();return CBRET_NONE; - } - break; + LEAVECORE; + CPU_RET(true,0); + goto decode_start; } CASE_D(0xcf) /* IRET */ { - if (CPU_IRET(true)) { + LEAVECORE; + CPU_IRET(true); #if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Decode_Trap; - return CBRET_NONE; - } + if (GETFLAG(TF)) { + cpudecoder=CPU_Core_Normal_Decode_Trap; + return CBRET_NONE; + } #endif #ifdef CPU_PIC_CHECK - if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; + if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; #endif //TODO TF check - goto decode_start; - } else return CBRET_NONE; - break; + goto decode_start; } CASE_D(0xd1) /* GRP2 Ed,1 */ GRP2D(1);break; @@ -532,13 +522,9 @@ { Bit32u newip=Fetchd(); Bit16u newcs=Fetchw(); - SAVEIP; - if (CPU_JMP(true,newcs,newip)) { - LOADIP; - } else { - FillFlags();return CBRET_NONE; - } - break; + LEAVECORE; + CPU_JMP(true,newcs,newip); + goto decode_start; } CASE_D(0xed) /* IN EAX,DX */ reg_eax=IO_ReadD(reg_dx); @@ -609,12 +595,9 @@ GetEAa; Bit32u newip=LoadMd(eaa); Bit16u newcs=LoadMw(eaa+4); - SAVEIP; - if (CPU_CALL(true,newcs,newip)) { - LOADIP; - } else { - FillFlags();return CBRET_NONE; - } + LEAVECORE; + CPU_CALL(true,newcs,newip); + goto decode_start; } break; case 0x04: /* JMP NEAR Ed */ @@ -626,12 +609,9 @@ GetEAa; Bit32u newip=LoadMd(eaa); Bit16u newcs=LoadMw(eaa+4); - SAVEIP; - if (CPU_JMP(true,newcs,newip)) { - LOADIP; - } else { - FillFlags();return CBRET_NONE; - } + LEAVECORE; + CPU_JMP(true,newcs,newip); + goto decode_start; } break; case 0x06: /* Push Ed */ diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 7493fa8b..02c1102d 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -124,37 +124,37 @@ } break; CASE_0F_D(0x80) /* JO */ - JumpSId(get_OF());break; + JumpSId(TFLG_O);break; CASE_0F_D(0x81) /* JNO */ - JumpSId(!get_OF());break; + JumpSId(TFLG_NO);break; CASE_0F_D(0x82) /* JB */ - JumpSId(get_CF());break; + JumpSId(TFLG_B);break; CASE_0F_D(0x83) /* JNB */ - JumpSId(!get_CF());break; + JumpSId(TFLG_NB);break; CASE_0F_D(0x84) /* JZ */ - JumpSId(get_ZF());break; + JumpSId(TFLG_Z);break; CASE_0F_D(0x85) /* JNZ */ - JumpSId(!get_ZF());break; + JumpSId(TFLG_NZ);break; CASE_0F_D(0x86) /* JBE */ - JumpSId(get_CF() || get_ZF());break; + JumpSId(TFLG_BE);break; CASE_0F_D(0x87) /* JNBE */ - JumpSId(!get_CF() && !get_ZF());break; + JumpSId(TFLG_NBE);break; CASE_0F_D(0x88) /* JS */ - JumpSId(get_SF());break; + JumpSId(TFLG_S);break; CASE_0F_D(0x89) /* JNS */ - JumpSId(!get_SF());break; + JumpSId(TFLG_NS);break; CASE_0F_D(0x8a) /* JP */ - JumpSId(get_PF());break; + JumpSId(TFLG_P);break; CASE_0F_D(0x8b) /* JNP */ - JumpSId(!get_PF());break; + JumpSId(TFLG_NP);break; CASE_0F_D(0x8c) /* JL */ - JumpSId(get_SF() != get_OF());break; + JumpSId(TFLG_L);break; CASE_0F_D(0x8d) /* JNL */ - JumpSId(get_SF() == get_OF());break; + JumpSId(TFLG_NL);break; CASE_0F_D(0x8e) /* JLE */ - JumpSId(get_ZF() || (get_SF() != get_OF()));break; + JumpSId(TFLG_LE);break; CASE_0F_D(0x8f) /* JNLE */ - JumpSId((get_SF() == get_OF()) && !get_ZF());break; + JumpSId(TFLG_NLE);break; CASE_0F_D(0xa0) /* PUSH FS */ Push_32(SegValue(fs));break; @@ -163,7 +163,7 @@ CASE_0F_D(0xa3) /* BT Ed,Gd */ { - GetRMrd; + FillFlags();GetRMrd; Bit32u mask=1 << (*rmrd & 31); if (rm >= 0xc0 ) { GetEArd; @@ -172,7 +172,6 @@ GetEAa;Bit32u old=LoadMd(eaa); SETFLAGBIT(CF,(old & mask)); } - SetTypeCF(); break; } CASE_0F_D(0xa4) /* SHLD Ed,Gd,Ib */ @@ -187,7 +186,7 @@ CPU_SetSegGeneral(gs,(Bit16u)Pop_32());break; CASE_0F_D(0xab) /* BTS Ed,Gd */ { - GetRMrd; + FillFlags();GetRMrd; Bit32u mask=1 << (*rmrd & 31); if (rm >= 0xc0 ) { GetEArd; @@ -198,7 +197,6 @@ SETFLAGBIT(CF,(old & mask)); SaveMd(eaa,old | mask); } - SetTypeCF(); break; } @@ -247,7 +245,7 @@ } CASE_0F_D(0xba) /* GRP8 Ed,Ib */ { - GetRM; + FillFlags();GetRM; if (rm >= 0xc0 ) { GetEArd; Bit32u mask=1 << (Fetchb() & 31); @@ -290,12 +288,11 @@ E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38); } } - SetTypeCF(); break; } CASE_0F_D(0xbb) /* BTC Ed,Gd */ { - GetRMrd; + FillFlags();GetRMrd; Bit32u mask=1 << (*rmrd & 31); if (rm >= 0xc0 ) { GetEArd; @@ -306,7 +303,6 @@ SETFLAGBIT(CF,(old & mask)); SaveMd(eaa,old ^ mask); } - SetTypeCF(); break; } CASE_0F_D(0xbc) /* BSF Gd,Ed */ diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 3eba569c..913058b7 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -277,37 +277,37 @@ CASE_W(0x6f) /* OUTSW */ DoString(R_OUTSW);break; CASE_B(0x70) /* JO */ - JumpSIb(get_OF());break; + JumpSIb(TFLG_O);break; CASE_B(0x71) /* JNO */ - JumpSIb(!get_OF());break; + JumpSIb(TFLG_NO);break; CASE_B(0x72) /* JB */ - JumpSIb(get_CF());break; + JumpSIb(TFLG_B);break; CASE_B(0x73) /* JNB */ - JumpSIb(!get_CF());break; + JumpSIb(TFLG_NB);break; CASE_B(0x74) /* JZ */ - JumpSIb(get_ZF());break; + JumpSIb(TFLG_Z);break; CASE_B(0x75) /* JNZ */ - JumpSIb(!get_ZF());break; + JumpSIb(TFLG_NZ);break; CASE_B(0x76) /* JBE */ - JumpSIb(get_CF() || get_ZF());break; + JumpSIb(TFLG_BE);break; CASE_B(0x77) /* JNBE */ - JumpSIb(!get_CF() && !get_ZF());break; + JumpSIb(TFLG_NBE);break; CASE_B(0x78) /* JS */ - JumpSIb(get_SF());break; + JumpSIb(TFLG_S);break; CASE_B(0x79) /* JNS */ - JumpSIb(!get_SF());break; + JumpSIb(TFLG_NS);break; CASE_B(0x7a) /* JP */ - JumpSIb(get_PF());break; + JumpSIb(TFLG_P);break; CASE_B(0x7b) /* JNP */ - JumpSIb(!get_PF());break; + JumpSIb(TFLG_NP);break; CASE_B(0x7c) /* JL */ - JumpSIb(get_SF() != get_OF());break; + JumpSIb(TFLG_L);break; CASE_B(0x7d) /* JNL */ - JumpSIb(get_SF() == get_OF());break; + JumpSIb(TFLG_NL);break; CASE_B(0x7e) /* JLE */ - JumpSIb(get_ZF() || (get_SF() != get_OF()));break; + JumpSIb(TFLG_LE);break; CASE_B(0x7f) /* JNLE */ - JumpSIb((get_SF() == get_OF()) && !get_ZF());break; + JumpSIb(TFLG_NLE);break; CASE_B(0x80) /* Grpl Eb,Ib */ CASE_B(0x82) /* Grpl Eb,Ib Mirror instruction*/ { @@ -547,13 +547,9 @@ CASE_W(0x9a) /* CALL Ap */ { Bit16u newip=Fetchw();Bit16u newcs=Fetchw(); - SAVEIP; - if (CPU_CALL(false,newcs,newip)) { - LOADIP; - } else { - FillFlags();return CBRET_NONE; - } - break; + LEAVECORE; + CPU_CALL(false,newcs,newip); + goto decode_start; } CASE_B(0x9b) /* WAIT */ break; /* No waiting here */ @@ -737,32 +733,27 @@ reg_bp=Pop_16(); break; CASE_W(0xca) /* RETF Iw */ - { - if (CPU_RET(false,Fetchw())) { - LOADIP; - } else { - FillFlags();return CBRET_NONE; - } - break; + { + Bitu words=Fetchw(); + LEAVECORE; + CPU_RET(false,words); + goto decode_start; } CASE_W(0xcb) /* RETF */ - { - if (CPU_RET(false,0)) { - LOADIP; - } else { - FillFlags();return CBRET_NONE; - } - break; - } + LEAVECORE; + CPU_RET(false,0); + goto decode_start; CASE_B(0xcc) /* INT3 */ LEAVECORE; #if C_DEBUG if (DEBUG_Breakpoint()) { return debugCallback; } -#endif +#endif + CPU_SW_Interrupt(3); +#if CPU_TRAP_CHECK core.trap.skip=true; - if (!Interrupt(3)) return CBRET_NONE; +#endif goto decode_start; CASE_B(0xcd) /* INT Ib */ { @@ -773,37 +764,39 @@ return debugCallback; } #endif + CPU_SW_Interrupt(num); +#if CPU_TRAP_CHECK core.trap.skip=true; - if (!Interrupt(num)) return CBRET_NONE; - goto decode_start; //Restore IP with a LOADIP +#endif + goto decode_start; } break; CASE_B(0xce) /* INTO */ if (get_OF()) { LEAVECORE; + CPU_SW_Interrupt(4); +#if CPU_TRAP_CHECK core.trap.skip=true; - if (!Interrupt(4)) return CBRET_NONE; - goto decode_start; //Restore IP with a LOADIP +#endif + goto decode_start; + } break; CASE_W(0xcf) /* IRET */ { - if (CPU_IRET(false)) { + LEAVECORE; + CPU_IRET(false); #ifdef CPU_PIC_CHECK - if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; + if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; #endif #if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Decode_Trap; - return CBRET_NONE; - } + if (GETFLAG(TF)) { + cpudecoder=CPU_Core_Normal_Decode_Trap; + return CBRET_NONE; + } #endif goto decode_start; - } else { - return CBRET_NONE; } - break; - } CASE_B(0xd0) /* GRP2 Eb,1 */ GRP2B(1);break; CASE_W(0xd1) /* GRP2 Ew,1 */ @@ -930,13 +923,9 @@ { Bit16u newip=Fetchw(); Bit16u newcs=Fetchw(); - SAVEIP; - if (CPU_JMP(false,newcs,newip)) { - LOADIP; - } else { - FillFlags();return CBRET_NONE; - } - break; + LEAVECORE; + CPU_JMP(false,newcs,newip); + goto decode_start; } CASE_B(0xeb) /* JMP Jb */ ADDIPFAST(Fetchbs());break; @@ -963,8 +952,8 @@ CPU_HLT(); return CBRET_NONE; CASE_B(0xf5) /* CMC */ - SETFLAGBIT(CF,!get_CF()); - SetTypeCF() ; + FillFlags(); + SETFLAGBIT(CF,!(reg_flags & FLAG_CF)); break; CASE_B(0xf6) /* GRP3 Eb(,Ib) */ { @@ -1055,12 +1044,12 @@ break; } CASE_B(0xf8) /* CLC */ + FillFlags(); SETFLAGBIT(CF,false); - SetTypeCF(); break; CASE_B(0xf9) /* STC */ + FillFlags(); SETFLAGBIT(CF,true); - SetTypeCF(); break; CASE_B(0xfa) /* CLI */ SETFLAGBIT(IF,false); @@ -1118,12 +1107,9 @@ GetEAa; Bit16u newip=LoadMw(eaa); Bit16u newcs=LoadMw(eaa+2); - SAVEIP; - if (CPU_CALL(false,newcs,newip)) { - LOADIP; - } else { - FillFlags();return CBRET_NONE; - } + LEAVECORE; + CPU_CALL(false,newcs,newip); + goto decode_start; } break; case 0x04: /* JMP Ev */ @@ -1135,12 +1121,10 @@ GetEAa; Bit16u newip=LoadMw(eaa); Bit16u newcs=LoadMw(eaa+2); - SAVEIP; - if (CPU_JMP(false,newcs,newip)) { - LOADIP; - } else { - FillFlags();return CBRET_NONE; - } } + LEAVECORE; + CPU_JMP(false,newcs,newip); + goto decode_start; + } break; case 0x06: /* PUSH Ev */ if (rm >= 0xc0 ) {GetEArw;Push_16(*earw);} diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index d0e4d2a1..7ed92cbe 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -47,9 +47,8 @@ static INLINE void ADDIPFAST(Bits blah) { Bit8u new_num=blah; \ core.ip_lookup=core.op_start; \ LEAVECORE; \ - if (Interrupt(new_num)) { \ - goto decode_start; \ - } else return CBRET_NONE; \ + CPU_Exception(new_num); \ + goto decode_start; \ } static INLINE Bit8u Fetchb() { From 814ed9bef54ba1211098e8e66efa7d26608fed93 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 5 Nov 2003 19:49:30 +0000 Subject: [PATCH 1323/4131] New lazyflag testing and fillflags returns the flags Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1404 --- src/cpu/lazyflags.h | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index 79be9fba..c0fd7d4c 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -27,7 +27,7 @@ Bitu get_SF(void); Bitu get_OF(void); Bitu get_PF(void); -void FillFlags(void); +Bitu FillFlags(void); #include "regs.h" @@ -80,6 +80,23 @@ extern LazyFlags lflags; #define LoadOF SETFLAGBIT(OF,get_OF()); #define LoadAF SETFLAGBIT(AF,get_AF()); +#define TFLG_O (get_OF()) +#define TFLG_NO (!get_OF()) +#define TFLG_B (get_CF()) +#define TFLG_NB (!get_CF()) +#define TFLG_Z (get_ZF()) +#define TFLG_NZ (!get_ZF()) +#define TFLG_BE (get_CF() || get_ZF()) +#define TFLG_NBE (!get_CF() && !get_ZF()) +#define TFLG_S (get_SF()) +#define TFLG_NS (!get_SF()) +#define TFLG_P (get_PF()) +#define TFLG_NP (!get_PF()) +#define TFLG_L ((get_SF()!=0) != (get_OF()!=0)) +#define TFLG_NL ((get_SF()!=0) == (get_OF()!=0)) +#define TFLG_LE (get_ZF() || ((get_SF()!=0) != (get_OF()!=0))) +#define TFLG_NLE (!get_ZF() && ((get_SF()!=0) == (get_OF()!=0))) + //Types of Flag changing instructions enum { t_UNKNOWN=0, @@ -102,8 +119,7 @@ enum { t_RCLb,t_RCLw,t_RCLd, t_RCRb,t_RCRw,t_RCRd, t_NEGb,t_NEGw,t_NEGd, - t_CF,t_ZF, - + t_DSHLw,t_DSHLd, t_DSHRw,t_DSHRd, t_MUL,t_DIV, @@ -111,11 +127,4 @@ enum { t_LASTFLAG }; -INLINE void SetTypeCF(void) { - if (lflags.type!=t_CF) { - lflags.prev_type=lflags.type; - lflags.type=t_CF; - } -} - -#endif \ No newline at end of file +#endif From d11ec849a558dbc04917bf9714d4e323cc81501d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 5 Nov 2003 19:50:33 +0000 Subject: [PATCH 1324/4131] Forcing get_CF to be bool and INC/DEC set var1 flag variable Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1405 --- src/cpu/instructions.h | 57 ++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 9b5a4cdc..cf00531f 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -26,14 +26,14 @@ lflags.type=t_ADDb; #define ADCB(op1,op2,load,save) \ - lflags.oldcf=get_CF(); \ + lflags.oldcf=get_CF()!=0; \ lf_var1b=load(op1);lf_var2b=op2; \ lf_resb=lf_var1b+lf_var2b+lflags.oldcf; \ save(op1,lf_resb); \ lflags.type=t_ADCb; #define SBBB(op1,op2,load,save) \ - lflags.oldcf=get_CF(); \ + lflags.oldcf=get_CF()!=0; \ lf_var1b=load(op1);lf_var2b=op2; \ lf_resb=lf_var1b-(lf_var2b+lflags.oldcf); \ save(op1,lf_resb); \ @@ -82,14 +82,14 @@ lflags.type=t_ADDw; #define ADCW(op1,op2,load,save) \ - lflags.oldcf=get_CF(); \ + lflags.oldcf=get_CF()!=0; \ lf_var1w=load(op1);lf_var2w=op2; \ lf_resw=lf_var1w+lf_var2w+lflags.oldcf; \ save(op1,lf_resw); \ lflags.type=t_ADCw; #define SBBW(op1,op2,load,save) \ - lflags.oldcf=get_CF(); \ + lflags.oldcf=get_CF()!=0; \ lf_var1w=load(op1);lf_var2w=op2; \ lf_resw=lf_var1w-(lf_var2w+lflags.oldcf); \ save(op1,lf_resw); \ @@ -138,14 +138,14 @@ lflags.type=t_ADDd; #define ADCD(op1,op2,load,save) \ - lflags.oldcf=get_CF(); \ + lflags.oldcf=get_CF()!=0; \ lf_var1d=load(op1);lf_var2d=op2; \ lf_resd=lf_var1d+lf_var2d+lflags.oldcf; \ save(op1,lf_resd); \ lflags.type=t_ADCd; #define SBBD(op1,op2,load,save) \ - lflags.oldcf=get_CF(); \ + lflags.oldcf=get_CF()!=0; \ lf_var1d=load(op1);lf_var2d=op2; \ lf_resd=lf_var1d-(lf_var2d+lflags.oldcf); \ save(op1,lf_resd); \ @@ -190,33 +190,39 @@ #define INCB(op1,load,save) \ - LoadCF;lf_resb=load(op1)+1; \ - save(op1,lf_resb); \ + LoadCF;lf_var1b=load(op1); \ + lf_resb=lf_var1b+1; \ + save(op1,lf_resb); \ lflags.type=t_INCb; \ #define INCW(op1,load,save) \ - LoadCF;lf_resw=load(op1)+1; \ - save(op1,lf_resw); \ + LoadCF;lf_var1w=load(op1); \ + lf_resw=lf_var1w+1; \ + save(op1,lf_resw); \ lflags.type=t_INCw; #define INCD(op1,load,save) \ - LoadCF;lf_resd=load(op1)+1; \ - save(op1,lf_resd); \ + LoadCF;lf_var1d=load(op1); \ + lf_resd=lf_var1d+1; \ + save(op1,lf_resd); \ lflags.type=t_INCd; #define DECB(op1,load,save) \ - LoadCF;lf_resb=load(op1)-1; \ - save(op1,lf_resb); \ + LoadCF;lf_var1b=load(op1); \ + lf_resb=lf_var1b-1; \ + save(op1,lf_resb); \ lflags.type=t_DECb; #define DECW(op1,load,save) \ - LoadCF;lf_resw=load(op1)-1; \ - save(op1,lf_resw); \ + LoadCF;lf_var1w=load(op1); \ + lf_resw=lf_var1w-1; \ + save(op1,lf_resw); \ lflags.type=t_DECw; #define DECD(op1,load,save) \ - LoadCF;lf_resd=load(op1)-1; \ - save(op1,lf_resd); \ + LoadCF;lf_var1d=load(op1); \ + lf_resd=lf_var1d-1; \ + save(op1,lf_resd); \ lflags.type=t_DECd; #define ROLB(op1,op2,load,save) \ @@ -285,7 +291,7 @@ #define RCLB(op1,op2,load,save) \ if (op2%9) { \ LoadZF;LoadSF;LoadAF; \ - Bit8u cf=get_CF(); \ + Bit8u cf=get_CF()!=0; \ lf_var1b=load(op1); \ lf_var2b=op2%9; \ lflags.type=t_RCLb; \ @@ -293,14 +299,13 @@ (cf << (lf_var2b-1)) | \ (lf_var1b >> (9-lf_var2b)); \ SETFLAGBIT(CF,((lf_var1b >> (8-lf_var2b)) & 1)); \ - SETFLAGBIT(OF,(lf_var1b ^ lf_resb) & 0x80); \ save(op1,lf_resb); \ } #define RCLW(op1,op2,load,save) \ if (op2%17) { \ LoadZF;LoadSF;LoadAF; \ - Bit16u cf=get_CF(); \ + Bit16u cf=get_CF()!=0; \ lf_var1w=load(op1); \ lf_var2b=op2%17; \ lflags.type=t_RCLw; \ @@ -308,14 +313,13 @@ (cf << (lf_var2b-1)) | \ (lf_var1w >> (17-lf_var2b)); \ SETFLAGBIT(CF,((lf_var1w >> (16-lf_var2b)) & 1)); \ - SETFLAGBIT(OF,(lf_var1w ^ lf_resw) & 0x8000); \ save(op1,lf_resw); \ } #define RCLD(op1,op2,load,save) \ if (op2) { \ LoadZF;LoadSF;LoadAF; \ - Bit32u cf=get_CF(); \ + Bit32u cf=get_CF()!=0; \ lf_var1d=load(op1); \ lf_var2b=op2; \ lflags.type=t_RCLd; \ @@ -327,14 +331,13 @@ (lf_var1d >> (33-lf_var2b)); \ } \ SETFLAGBIT(CF,((lf_var1d >> (32-lf_var2b)) & 1)); \ - SETFLAGBIT(OF,(lf_var1d ^ lf_resd) & 0x80000000); \ save(op1,lf_resd); \ } #define RCRB(op1,op2,load,save) \ if (op2%9) { \ LoadZF;LoadSF;LoadAF; \ - Bit8u cf=get_CF(); \ + Bit8u cf=get_CF()!=0; \ lf_var1b=load(op1); \ lf_var2b=op2%9; \ lflags.type=t_RCRb; \ @@ -347,7 +350,7 @@ #define RCRW(op1,op2,load,save) \ if (op2%17) { \ LoadZF;LoadSF;LoadAF; \ - Bit16u cf=get_CF(); \ + Bit16u cf=get_CF()!=0; \ lf_var1w=load(op1); \ lf_var2b=op2%17; \ lflags.type=t_RCRw; \ @@ -360,7 +363,7 @@ #define RCRD(op1,op2,load,save) \ if (op2) { \ LoadZF;LoadSF;LoadAF; \ - Bit32u cf=get_CF(); \ + Bit32u cf=get_CF()!=0; \ lf_var1d=load(op1); \ lf_var2b=op2; \ lflags.type=t_RCRd; \ From a74a1dc337536474501baee021482f4d084ee0fb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 5 Nov 2003 19:57:13 +0000 Subject: [PATCH 1325/4131] Changed some of the flag handling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1406 --- src/cpu/flags.cpp | 547 +++++++++++++++++++++++++++++----------------- 1 file changed, 342 insertions(+), 205 deletions(-) diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 441fd2e7..6fef35ef 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -35,7 +35,6 @@ Bitu get_CF(void) { switch (lflags.type) { case t_UNKNOWN: - case t_CF: case t_INCb: case t_INCw: case t_INCd: @@ -103,11 +102,11 @@ Bitu get_CF(void) { case t_SARd: return (((Bit32s) lf_var1d) >> (lf_var2b - 1)) & 1; case t_NEGb: - return (lf_var1b!=0); + return lf_var1b; case t_NEGw: - return (lf_var1w!=0); + return lf_var1w; case t_NEGd: - return (lf_var1d!=0); + return lf_var1d; case t_ROLb: return lf_resb & 1; case t_ROLw: @@ -115,11 +114,11 @@ Bitu get_CF(void) { case t_ROLd: return lf_resd & 1; case t_RORb: - return (lf_resb & 0x80)>0; + return (lf_resb & 0x80); case t_RORw: - return (lf_resw & 0x8000)>0; + return (lf_resw & 0x8000); case t_RORd: - return (lf_resd & 0x80000000)>0; + return (lf_resd & 0x80000000); case t_ORb: case t_ORw: case t_ORd: @@ -147,7 +146,6 @@ Bitu get_CF(void) { */ Bitu get_AF(void) { Bitu type=lflags.type; -again: switch (type) { case t_UNKNOWN: case t_ROLb: @@ -163,27 +161,24 @@ again: case t_RCLd: case t_RCRd: return GETFLAG(AF); - case t_CF: - type=lflags.prev_type; - goto again; case t_ADDb: case t_ADCb: case t_SBBb: case t_SUBb: case t_CMPb: - return (((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10)>0; + return ((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10; case t_ADDw: case t_ADCw: case t_SBBw: case t_SUBw: case t_CMPw: - return (((lf_var1w ^ lf_var2w) ^ lf_resw) & 0x10)>0; + return ((lf_var1w ^ lf_var2w) ^ lf_resw) & 0x10; case t_ADCd: case t_ADDd: case t_SBBd: case t_SUBd: case t_CMPd: - return (((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10)>0; + return ((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10; case t_INCb: return (lf_resb & 0x0f) == 0; case t_INCw: @@ -197,11 +192,11 @@ again: case t_DECd: return (lf_resd & 0x0f) == 0x0f; case t_NEGb: - return (lf_var1b & 0x0f) > 0; + return lf_var1b & 0x0f; case t_NEGw: - return (lf_var1w & 0x0f) > 0; + return lf_var1w & 0x0f; case t_NEGd: - return (lf_var1d & 0x0f) > 0; + return lf_var1d & 0x0f; case t_ORb: case t_ORw: case t_ORd: @@ -241,7 +236,6 @@ again: Bitu get_ZF(void) { Bitu type=lflags.type; -again: switch (type) { case t_UNKNOWN: case t_ROLb: @@ -257,9 +251,6 @@ again: case t_RCLd: case t_RCRd: return GETFLAG(ZF); - case t_CF: - type=lflags.prev_type; - goto again; case t_ADDb: case t_ORb: case t_ADCb: @@ -325,7 +316,6 @@ again: */ Bitu get_SF(void) { Bitu type=lflags.type; -again: switch (type) { case t_UNKNOWN: case t_ROLb: @@ -341,9 +331,6 @@ again: case t_RCLd: case t_RCRd: return GETFLAG(SF); - case t_CF: - type=lflags.prev_type; - goto again; case t_ADDb: case t_ORb: case t_ADCb: @@ -359,7 +346,7 @@ again: case t_SHRb: case t_SARb: case t_NEGb: - return (lf_resb>=0x80); + return (lf_resb&0x80); case t_ADDw: case t_ORw: case t_ADCw: @@ -377,7 +364,7 @@ again: case t_DSHLw: case t_DSHRw: case t_NEGw: - return (lf_resw>=0x8000); + return (lf_resw&0x8000); case t_ADDd: case t_ORd: case t_ADCd: @@ -395,7 +382,7 @@ again: case t_DSHLd: case t_DSHRd: case t_NEGd: - return (lf_resd>=0x80000000); + return (lf_resd&0x80000000); case t_DIV: case t_MUL: return false; /* Unkown */ @@ -406,69 +393,32 @@ again: } Bitu get_OF(void) { - Bit8u var1b7, var2b7, resultb7; - Bit16u var1w15, var2w15, resultw15; - Bit32u var1d31, var2d31, resultd31; - Bitu type=lflags.type; -again: switch (type) { case t_UNKNOWN: case t_MUL: - case t_RCLb: - case t_RCLw: - case t_RCLd: - case t_SARb: - case t_SARw: - case t_SARd: return GETFLAG(OF); - case t_CF: - type=lflags.prev_type; - goto again; case t_ADDb: case t_ADCb: -// return (((lf_resb) ^ (lf_var2b)) & ((lf_resb) ^ (lf_var1b)) & 0x80)>0; - var1b7 = lf_var1b & 0x80; - var2b7 = lf_var2b & 0x80; - resultb7 = lf_resb & 0x80; - return (var1b7 == var2b7) && (resultb7 ^ var2b7); + return ((lf_var1b ^ lf_var2b ^ 0x80) & (lf_resb ^ lf_var2b)) & 0x80; case t_ADDw: case t_ADCw: -// return (((lf_resw) ^ (lf_var2w)) & ((lf_resw) ^ (lf_var1w)) & 0x8000)>0; - var1w15 = lf_var1w & 0x8000; - var2w15 = lf_var2w & 0x8000; - resultw15 = lf_resw & 0x8000; - return (var1w15 == var2w15) && (resultw15 ^ var2w15); + return ((lf_var1w ^ lf_var2w ^ 0x8000) & (lf_resw ^ lf_var2w)) & 0x8000; case t_ADDd: case t_ADCd: -//TODO fix dword Overflow - var1d31 = lf_var1d & 0x80000000; - var2d31 = lf_var2d & 0x80000000; - resultd31 = lf_resd & 0x80000000; - return (var1d31 == var2d31) && (resultd31 ^ var2d31); + return ((lf_var1d ^ lf_var2d ^ 0x80000000) & (lf_resd ^ lf_var2d)) & 0x80000000; case t_SBBb: case t_SUBb: case t_CMPb: -// return (((lf_var1b) ^ (lf_var2b)) & ((lf_var1b) ^ (lf_resb)) & 0x80)>0; - var1b7 = lf_var1b & 0x80; - var2b7 = lf_var2b & 0x80; - resultb7 = lf_resb & 0x80; - return (var1b7 ^ var2b7) && (var1b7 ^ resultb7); + return ((lf_var1b ^ lf_var2b) & (lf_var1b ^ lf_resb)) & 0x80; case t_SBBw: case t_SUBw: case t_CMPw: -// return (((lf_var1w) ^ (lf_var2w)) & ((lf_var1w) ^ (lf_resw)) & 0x8000)>0; - var1w15 = lf_var1w & 0x8000; - var2w15 = lf_var2w & 0x8000; - resultw15 = lf_resw & 0x8000; - return (var1w15 ^ var2w15) && (var1w15 ^ resultw15); + return ((lf_var1w ^ lf_var2w) & (lf_var1w ^ lf_resw)) & 0x8000; case t_SBBd: case t_SUBd: case t_CMPd: - var1d31 = lf_var1d & 0x80000000; - var2d31 = lf_var2d & 0x80000000; - resultd31 = lf_resd & 0x80000000; - return (var1d31 ^ var2d31) && (var1d31 ^ resultd31); + return ((lf_var1d ^ lf_var2d) & (lf_var1d ^ lf_resd)) & 0x80000000; case t_INCb: return (lf_resb == 0x80); case t_INCw: @@ -488,43 +438,30 @@ again: case t_NEGd: return (lf_var1d == 0x80000000); case t_ROLb: - return ((lf_resb & 0x80) ^ (lf_resb & 1 ? 0x80 : 0)) != 0; - case t_ROLw: - return ((lf_resw & 0x8000) ^ (lf_resw & 1 ? 0x8000 : 0)) != 0; - case t_ROLd: - return ((lf_resd & 0x80000000) ^ (lf_resd & 1 ? 0x80000000 : 0)) != 0; - case t_SHLb: - if (lf_var2b>9) return false; - return ((lf_resb & 0x80) ^ - ((lf_var1b << (lf_var2b - 1)) & 0x80)) != 0; - case t_SHLw: - if (lf_var2b>17) return false; - return ((lf_resw & 0x8000) ^ - ((lf_var1w << (lf_var2b - 1)) & 0x8000)) != 0; - case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */ - return ((lf_resw & 0x8000) ^ - (((lf_var1d << (lf_var2b - 1)) >> 16) & 0x8000)) != 0; - case t_SHLd: - case t_DSHLd: - return ((lf_resd & 0x80000000) ^ - ((lf_var1d << (lf_var2b - 1)) & 0x80000000)) != 0; case t_RORb: + case t_RCLb: case t_RCRb: - return ((lf_resb ^ (lf_resb << 1)) & 0x80) > 0; - case t_RORw: - case t_RCRw: - case t_DSHRw: - return ((lf_resw ^ (lf_resw << 1)) & 0x8000) > 0; - case t_RORd: - case t_RCRd: - case t_DSHRd: - return ((lf_resd ^ (lf_resd << 1)) & 0x80000000) > 0; + case t_SHLb: case t_SHRb: - return (lf_resb >= 0x40); + return (lf_resb ^ lf_var1b) & 0x80; + case t_ROLw: + case t_RORw: + case t_RCLw: + case t_RCRw: + case t_SHLw: case t_SHRw: - return (lf_resw >= 0x4000); + case t_DSHRw: + case t_DSHLw: + return (lf_resw ^ lf_var1w) & 0x8000; + case t_ROLd: + case t_RORd: + case t_RCLd: + case t_RCRd: + case t_SHLd: case t_SHRd: - return (lf_resd >= 0x40000000); + case t_DSHRd: + case t_DSHLd: + return (lf_resd ^ lf_var1d) & 0x80000000; case t_ORb: case t_ORw: case t_ORd: @@ -537,7 +474,10 @@ again: case t_TESTb: case t_TESTw: case t_TESTd: - return false; /* Return false */ + case t_SARb: + case t_SARw: + case t_SARd: + return false; /* Return false */ case t_DIV: return false; /* Unkown */ default: @@ -547,22 +487,22 @@ again: } Bit16u parity_lookup[256] = { - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 + FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, + 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, + 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, + FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, + 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, + FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, + FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, + 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, + 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, + FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, + FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, + 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, + FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, + 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, + 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, + FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF }; Bitu get_PF(void) { @@ -576,7 +516,10 @@ Bitu get_PF(void) { } -void FillFlags(void) { +#if 0 + +Bitu FillFlags(void) { +// if (lflags.type==t_UNKNOWN) return reg_flags; Bitu new_word=(reg_flags & ~FLAG_MASK); if (get_CF()) new_word|=FLAG_CF; if (get_PF()) new_word|=FLAG_PF; @@ -586,237 +529,431 @@ void FillFlags(void) { if (get_OF()) new_word|=FLAG_OF; reg_flags=new_word; lflags.type=t_UNKNOWN; + return reg_flags; } -#if 0 +#else -Bitu get_Flags(void) { - Bitu new_flags=0; +#define DOFLAG_PF reg_flags=(reg_flags & ~FLAG_PF) | parity_lookup[lf_resb]; + +#define DOFLAG_AF reg_flags=(reg_flags & ~FLAG_AF) | (((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10); + +#define DOFLAG_ZFb SETFLAGBIT(ZF,lf_resb==0); +#define DOFLAG_ZFw SETFLAGBIT(ZF,lf_resw==0); +#define DOFLAG_ZFd SETFLAGBIT(ZF,lf_resd==0); + +#define DOFLAG_SFb reg_flags=(reg_flags & ~FLAG_SF) | ((lf_resb & 0x80) >> 0); +#define DOFLAG_SFw reg_flags=(reg_flags & ~FLAG_SF) | ((lf_resw & 0x8000) >> 8); +#define DOFLAG_SFd reg_flags=(reg_flags & ~FLAG_SF) | ((lf_resd & 0x80000000) >> 24); + + + +#define SET_FLAG SETFLAGBIT +Bitu FillFlags(void) { switch (lflags.type) { + case t_UNKNOWN: + break; case t_ADDb: - SET_FLAG(FLAG_CF,(lf_resb0); + SET_FLAG(CF,(lf_resb0); + SET_FLAG(CF,(lf_resw0); + SET_FLAG(CF,(lf_resd0); + SET_FLAG(CF,(lf_resb < lf_var1b) || (lflags.oldcf && (lf_resb == lf_var1b))); + DOFLAG_AF; + DOFLAG_ZFb; + SET_FLAG(SF,(lf_resb&0x80)); + SET_FLAG(OF,((lf_var1b ^ lf_var2b ^ 0x80) & (lf_resb ^ lf_var1b)) & 0x80); + DOFLAG_PF; break; case t_ADCw: - SET_FLAG(FLAG_CF,(lf_resw < lf_var1w) || (lflags.oldcf && (lf_resw == lf_var1w))); - SET_FLAG(FLAG_AF,(((lf_var1w ^ lf_var2w) ^ lf_resw) & 0x10)>0); + SET_FLAG(CF,(lf_resw < lf_var1w) || (lflags.oldcf && (lf_resw == lf_var1w))); + DOFLAG_AF; + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,((lf_var1w ^ lf_var2w ^ 0x8000) & (lf_resw ^ lf_var1w)) & 0x8000); + DOFLAG_PF; break; case t_ADCd: - SET_FLAG(FLAG_CF,(lf_resd < lf_var1d) || (lflags.oldcf && (lf_resd == lf_var1d))); - SET_FLAG(FLAG_AF,(((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10)>0); + SET_FLAG(CF,(lf_resd < lf_var1d) || (lflags.oldcf && (lf_resd == lf_var1d))); + DOFLAG_AF; + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,((lf_var1d ^ lf_var2d ^ 0x80000000) & (lf_resd ^ lf_var1d)) & 0x80000000); + DOFLAG_PF; break; - + case t_SBBb: - SET_FLAG(FLAG_CF,(lf_var1b < lf_resb) || (lflags.oldcf && (lf_var2b==0xff))); - SET_FLAG(FLAG_AF,(((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10)>0); + SET_FLAG(CF,(lf_var1b < lf_resb) || (lflags.oldcf && (lf_var2b==0xff))); + DOFLAG_AF; + DOFLAG_ZFb; + SET_FLAG(SF,(lf_resb&0x80)); + SET_FLAG(OF,(lf_var1b ^ lf_var2b) & (lf_var1b ^ lf_resb) & 0x80); + DOFLAG_PF; break; case t_SBBw: - SET_FLAG(FLAG_CF,(lf_var1w < lf_resw) || (lflags.oldcf && (lf_var2w==0xffff))); - SET_FLAG(FLAG_AF,(((lf_var1w ^ lf_var2w) ^ lf_resw) & 0x10)>0); + SET_FLAG(CF,(lf_var1w < lf_resw) || (lflags.oldcf && (lf_var2w==0xffff))); + DOFLAG_AF; + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,(lf_var1w ^ lf_var2w) & (lf_var1w ^ lf_resw) & 0x8000); + DOFLAG_PF; break; case t_SBBd: - SET_FLAG(FLAG_CF,(lf_var1d < lf_resd) || (lflags.oldcf && (lf_var2d==0xffffffff))); - SET_FLAG(FLAG_AF,(((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10)>0); + SET_FLAG(CF,(lf_var1d < lf_resd) || (lflags.oldcf && (lf_var2d==0xffffffff))); + DOFLAG_AF; + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,(lf_var1d ^ lf_var2d) & (lf_var1d ^ lf_resd) & 0x80000000); + DOFLAG_PF; break; case t_SUBb: case t_CMPb: - SET_FLAG(FLAG_CF,(lf_var1b0); + SET_FLAG(CF,(lf_var1b0); + SET_FLAG(CF,(lf_var1w0); + SET_FLAG(CF,(lf_var1d8) SET_FLAG(FLAG_CF,false); - else SET_FLAG(FLAG_CF,(lf_var1b >> (8-lf_var2b)) & 1); + if (lf_var2b>8) SET_FLAG(CF,false); + else SET_FLAG(CF,(lf_var1b >> (8-lf_var2b)) & 1); + DOFLAG_ZFb; + SET_FLAG(SF,(lf_resb&0x80)); + SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); + DOFLAG_PF; break; case t_SHLw: - if (lf_var2b>16) SET_FLAG(FLAG_CF,false); - else SET_FLAG(FLAG_CF,(lf_var1w >> (16-lf_var2b)) & 1); + if (lf_var2b>16) SET_FLAG(CF,false); + else SET_FLAG(CF,(lf_var1w >> (16-lf_var2b)) & 1); + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); + DOFLAG_PF; break; case t_SHLd: - SET_FLAG(FLAG_CF,(lf_var1d >> (32 - lf_var2b)) & 1); + SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); + DOFLAG_PF; break; - case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */ - SET_FLAG(FLAG_CF,(lf_var1d >> (32 - lf_var2b)) & 1); + case t_DSHLw: + SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); + DOFLAG_PF; break; case t_DSHLd: - SET_FLAG(FLAG_CF,(lf_var1d >> (32 - lf_var2b)) & 1); + SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); + DOFLAG_PF; break; case t_SHRb: - SET_FLAG(FLAG_CF,(lf_var1b >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(lf_var1b >> (lf_var2b - 1)) & 1); + DOFLAG_ZFb; + SET_FLAG(SF,(lf_resb&0x80)); + SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); + DOFLAG_PF; break; case t_SHRw: - SET_FLAG(FLAG_CF,(lf_var1w >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(lf_var1w >> (lf_var2b - 1)) & 1); + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); + DOFLAG_PF; break; case t_SHRd: - SET_FLAG(FLAG_CF,(lf_var1d >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); + DOFLAG_PF; break; case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ - SET_FLAG(FLAG_CF,(lf_var1d >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); + DOFLAG_PF; break; case t_DSHRd: - SET_FLAG(FLAG_CF,(lf_var1d >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); + DOFLAG_PF; break; case t_SARb: - SET_FLAG(FLAG_CF,(((Bit8s) lf_var1b) >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(((Bit8s) lf_var1b) >> (lf_var2b - 1)) & 1); + DOFLAG_ZFb; + SET_FLAG(SF,(lf_resb&0x80)); + SET_FLAG(OF,false); + DOFLAG_PF; break; case t_SARw: - SET_FLAG(FLAG_CF,(((Bit16s) lf_var1w) >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(((Bit16s) lf_var1w) >> (lf_var2b - 1)) & 1); + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,false); + DOFLAG_PF; break; case t_SARd: - SET_FLAG(FLAG_CF,(((Bit32s) lf_var1d) >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(((Bit32s) lf_var1d) >> (lf_var2b - 1)) & 1); + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,false); + DOFLAG_PF; break; case t_ROLb: - SET_FLAG(FLAG_CF,lf_resb & 1); + SET_FLAG(CF,lf_resb & 1); + SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); break; case t_ROLw: - SET_FLAG(FLAG_CF,lf_resw & 1); + SET_FLAG(CF,lf_resw & 1); + SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); break; case t_ROLd: - SET_FLAG(FLAG_CF,lf_resd & 1); + SET_FLAG(CF,lf_resd & 1); + SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); break; case t_RORb: - SET_FLAG(FLAG_CF,(lf_resb & 0x80)>0); + SET_FLAG(CF,(lf_resb & 0x80)); + SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); break; case t_RORw: - SET_FLAG(FLAG_CF,(lf_resw & 0x8000)>0); + SET_FLAG(CF,(lf_resw & 0x8000)); + SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); break; case t_RORd: - SET_FLAG(FLAG_CF,(lf_resd & 0x80000000)>0); + SET_FLAG(CF,(lf_resd & 0x80000000)); + SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); break; + case t_RCLb: + SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); + break; + case t_RCLw: + SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); + break; + case t_RCLd: + SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); + break; case t_RCRb: - SET_FLAG(FLAG_CF,(lf_var1b >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(lf_var1b >> (lf_var2b - 1)) & 1); + SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); break; case t_RCRw: - SET_FLAG(FLAG_CF,(lf_var1w >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(lf_var1w >> (lf_var2b - 1)) & 1); + SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); break; case t_RCRd: - SET_FLAG(FLAG_CF,(lf_var1d >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); + SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); break; - case t_INCb: - SET_FLAG(FLAG_OF,(lf_resb == 0x80)); - SET_FLAG(FLAG_AF,((lf_resb & 0x0f) == 0)); + SET_FLAG(AF,(lf_resb & 0x0f) == 0); + DOFLAG_ZFb; + SET_FLAG(SF,(lf_resb&0x80)); + SET_FLAG(OF,(lf_resb == 0x80)); + DOFLAG_PF; break; case t_INCw: - SET_FLAG(FLAG_OF,(lf_resw == 0x8000)); - SET_FLAG(FLAG_AF,((lf_resw & 0x0f) == 0)); + SET_FLAG(AF,(lf_resw & 0x0f) == 0); + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,(lf_resw == 0x8000)); + DOFLAG_PF; break; case t_INCd: - SET_FLAG(FLAG_OF,(lf_resd == 0x80000000)); - SET_FLAG(FLAG_AF,((lf_resd & 0x0f) == 0)); + SET_FLAG(AF,(lf_resd & 0x0f) == 0); + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,(lf_resd == 0x80000000)); + DOFLAG_PF; break; - case t_DECb: - SET_FLAG(FLAG_OF,(lf_resb == 0x7f)); + SET_FLAG(AF,(lf_resb & 0x0f) == 0); + DOFLAG_ZFb; + SET_FLAG(SF,(lf_resb&0x80)); + SET_FLAG(OF,(lf_resb == 0x7f)); + DOFLAG_PF; break; case t_DECw: - SET_FLAG(FLAG_OF,(lf_resw == 0x7fff)); + SET_FLAG(AF,(lf_resw & 0x0f) == 0); + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,(lf_resw == 0x7fff)); + DOFLAG_PF; break; case t_DECd: - SET_FLAG(FLAG_OF,(lf_resd == 0x7fffffff)); + SET_FLAG(AF,(lf_resd & 0x0f) == 0); + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,(lf_resd == 0x7fffffff)); + DOFLAG_PF; break; - case t_NEGb: - SET_FLAG(FLAG_CF,(lf_var1b!=0)); + SET_FLAG(CF,(lf_var1b!=0)); + SET_FLAG(AF,(lf_resb & 0x0f) == 0); + DOFLAG_ZFb; + SET_FLAG(SF,(lf_resb&0x80)); + SET_FLAG(OF,(lf_var1b == 0x80)); + DOFLAG_PF; break; case t_NEGw: - SET_FLAG(FLAG_CF,(lf_var1w!=0)); + SET_FLAG(CF,(lf_var1w!=0)); + SET_FLAG(AF,(lf_resw & 0x0f) == 0); + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,(lf_var1w == 0x8000)); + DOFLAG_PF; break; case t_NEGd: - SET_FLAG(FLAG_CF,(lf_var1d!=0)); + SET_FLAG(CF,(lf_var1d!=0)); + SET_FLAG(AF,(lf_resd & 0x0f) == 0); + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,(lf_var1d == 0x80000000)); + DOFLAG_PF; break; case t_DIV: - SET_FLAG(FLAG_CF,false); /* Unkown */ + case t_MUL: break; + default: LOG(LOG_CPU,LOG_ERROR)("Unhandled flag type %d",lflags.type); return 0; } - lflags.word=new_flags; - return 0; + lflags.type=t_UNKNOWN; + return reg_flags; } #endif From 622310e567cadcbc59fa669dea532a205dbd7e40 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 5 Nov 2003 20:28:29 +0000 Subject: [PATCH 1326/4131] fixed a crash, removed some warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1407 --- src/debug/debug.cpp | 107 +++++++++++++++++++++++--------------------- 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 125375a4..2d45ee5a 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -34,6 +34,7 @@ #include "mixer.h" #include "debug_inc.h" #include "timer.h" +#include "paging.h" #include "../ints/xms.h" #include "../shell/shell_inc.h" @@ -51,7 +52,7 @@ static void DrawCode(void); static bool DEBUG_Log_Loop(int count); static void DEBUG_RaiseTimerIrq(void); char* AnalyzeInstruction(char* inst, bool saveSelector); -void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num); +void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num); Bit32u GetHexValue(char* str, char*& hex); class DEBUG; @@ -116,7 +117,7 @@ Bit32u GetAddress(Bit16u seg, Bit32u offset) bool GetDescriptorInfo(char* selname, char* out1, char* out2) { - Bit16u sel; + Bitu sel; Descriptor desc; if (strstr(selname,"cs") || strstr(selname,"CS")) sel = SegValue(cs); else @@ -801,21 +802,21 @@ bool ChangeRegister(char* str) if (strstr(hex,"EBP")==hex) { hex+=3; reg_ebp = GetHexValue(hex,hex); } else if (strstr(hex,"ESP")==hex) { hex+=3; reg_esp = GetHexValue(hex,hex); } else if (strstr(hex,"EIP")==hex) { hex+=3; reg_eip = GetHexValue(hex,hex); } else - if (strstr(hex,"AX")==hex) { hex+=2; reg_ax = GetHexValue(hex,hex); } else - if (strstr(hex,"BX")==hex) { hex+=2; reg_bx = GetHexValue(hex,hex); } else - if (strstr(hex,"CX")==hex) { hex+=2; reg_cx = GetHexValue(hex,hex); } else - if (strstr(hex,"DX")==hex) { hex+=2; reg_dx = GetHexValue(hex,hex); } else - if (strstr(hex,"SI")==hex) { hex+=2; reg_si = GetHexValue(hex,hex); } else - if (strstr(hex,"DI")==hex) { hex+=2; reg_di = GetHexValue(hex,hex); } else - if (strstr(hex,"BP")==hex) { hex+=2; reg_bp = GetHexValue(hex,hex); } else - if (strstr(hex,"SP")==hex) { hex+=2; reg_sp = GetHexValue(hex,hex); } else - if (strstr(hex,"IP")==hex) { hex+=2; reg_ip = GetHexValue(hex,hex); } else - if (strstr(hex,"CS")==hex) { hex+=2; SegSet16(cs,GetHexValue(hex,hex)); } else - if (strstr(hex,"DS")==hex) { hex+=2; SegSet16(ds,GetHexValue(hex,hex)); } else - if (strstr(hex,"ES")==hex) { hex+=2; SegSet16(es,GetHexValue(hex,hex)); } else - if (strstr(hex,"FS")==hex) { hex+=2; SegSet16(fs,GetHexValue(hex,hex)); } else - if (strstr(hex,"GS")==hex) { hex+=2; SegSet16(gs,GetHexValue(hex,hex)); } else - if (strstr(hex,"SS")==hex) { hex+=2; SegSet16(ss,GetHexValue(hex,hex)); } else + if (strstr(hex,"AX")==hex) { hex+=2; reg_ax = (Bit16u)GetHexValue(hex,hex); } else + if (strstr(hex,"BX")==hex) { hex+=2; reg_bx = (Bit16u)GetHexValue(hex,hex); } else + if (strstr(hex,"CX")==hex) { hex+=2; reg_cx = (Bit16u)GetHexValue(hex,hex); } else + if (strstr(hex,"DX")==hex) { hex+=2; reg_dx = (Bit16u)GetHexValue(hex,hex); } else + if (strstr(hex,"SI")==hex) { hex+=2; reg_si = (Bit16u)GetHexValue(hex,hex); } else + if (strstr(hex,"DI")==hex) { hex+=2; reg_di = (Bit16u)GetHexValue(hex,hex); } else + if (strstr(hex,"BP")==hex) { hex+=2; reg_bp = (Bit16u)GetHexValue(hex,hex); } else + if (strstr(hex,"SP")==hex) { hex+=2; reg_sp = (Bit16u)GetHexValue(hex,hex); } else + if (strstr(hex,"IP")==hex) { hex+=2; reg_ip = (Bit16u)GetHexValue(hex,hex); } else + if (strstr(hex,"CS")==hex) { hex+=2; SegSet16(cs,(Bit16u)GetHexValue(hex,hex)); } else + if (strstr(hex,"DS")==hex) { hex+=2; SegSet16(ds,(Bit16u)GetHexValue(hex,hex)); } else + if (strstr(hex,"ES")==hex) { hex+=2; SegSet16(es,(Bit16u)GetHexValue(hex,hex)); } else + if (strstr(hex,"FS")==hex) { hex+=2; SegSet16(fs,(Bit16u)GetHexValue(hex,hex)); } else + if (strstr(hex,"GS")==hex) { hex+=2; SegSet16(gs,(Bit16u)GetHexValue(hex,hex)); } else + if (strstr(hex,"SS")==hex) { hex+=2; SegSet16(ss,(Bit16u)GetHexValue(hex,hex)); } else if (strstr(hex,"AF")==hex) { hex+=2; SETFLAGBIT(AF,GetHexValue(hex,hex)); } else if (strstr(hex,"CF")==hex) { hex+=2; SETFLAGBIT(CF,GetHexValue(hex,hex)); } else if (strstr(hex,"DF")==hex) { hex+=2; SETFLAGBIT(PF,GetHexValue(hex,hex)); } else @@ -838,7 +839,7 @@ bool ParseCommand(char* str) found = strstr(str,"MEMDUMP "); if (found) { // Insert variable found+=8; - Bit16u seg = GetHexValue(found,found); found++; + Bit16u seg = (Bit16u)GetHexValue(found,found); found++; Bit32u ofs = GetHexValue(found,found); found++; Bit32u num = GetHexValue(found,found); found++; SaveMemory(seg,ofs,num); @@ -848,8 +849,8 @@ bool ParseCommand(char* str) found = strstr(str,"IV "); if (found) { // Insert variable found+=3; - Bit16u seg = GetHexValue(found,found); found++; - Bit32u ofs = GetHexValue(found,found); found++; + Bit16u seg = (Bit16u)GetHexValue(found,found); found++; + Bit32u ofs = (Bit16u)GetHexValue(found,found); found++; char name[16]; for (int i=0; i<16; i++) { if ((found[i]!=' ') && (found[i]!=0)) name[i] = found[i]; @@ -893,7 +894,7 @@ bool ParseCommand(char* str) found = strstr(str,"BP "); if (found) { // Add new breakpoint found+=3; - Bit16u seg = GetHexValue(found,found);found++; // skip ":" + Bit16u seg = (Bit16u)GetHexValue(found,found);found++; // skip ":" Bit32u ofs = GetHexValue(found,found); CBreakpoint::AddBreakpoint(seg,ofs,false); DEBUG_ShowMsg("DEBUG: Set breakpoint at %04X:%04X",seg,ofs); @@ -903,7 +904,7 @@ bool ParseCommand(char* str) found = strstr(str,"BPM "); if (found) { // Add new breakpoint found+=3; - Bit16u seg = GetHexValue(found,found);found++; // skip ":" + Bit16u seg = (Bit16u)GetHexValue(found,found);found++; // skip ":" Bit32u ofs = GetHexValue(found,found); CBreakpoint::AddMemBreakpoint(seg,ofs); DEBUG_ShowMsg("DEBUG: Set memory breakpoint at %04X:%04X",seg,ofs); @@ -912,7 +913,7 @@ bool ParseCommand(char* str) found = strstr(str,"BPPM "); if (found) { // Add new breakpoint found+=4; - Bit16u seg = GetHexValue(found,found);found++; // skip ":" + Bit16u seg = (Bit16u)GetHexValue(found,found);found++; // skip ":" Bit32u ofs = GetHexValue(found,found); CBreakpoint* bp = CBreakpoint::AddMemBreakpoint(seg,ofs); if (bp) bp->SetType(BKPNT_MEMORY_PROT); @@ -932,8 +933,8 @@ bool ParseCommand(char* str) found = strstr(str,"BPINT"); if (found) { // Add Interrupt Breakpoint found+=5; - Bit8u intNr = GetHexValue(found,found); found++; - Bit8u valAH = GetHexValue(found,found); + Bit8u intNr = (Bit8u)GetHexValue(found,found); found++; + Bit8u valAH = (Bit8u)GetHexValue(found,found); if ((valAH==0x00) && (*found=='*')) { CBreakpoint::AddIntBreakpoint(intNr,BPINT_ALL,false); DEBUG_ShowMsg("DEBUG: Set interrupt breakpoint at INT %02X",intNr); @@ -954,7 +955,7 @@ bool ParseCommand(char* str) found = strstr(str,"BPDEL"); if (found) { // Delete Breakpoints found+=5; - Bit8u bpNr = GetHexValue(found,found); + Bit8u bpNr = (Bit8u)GetHexValue(found,found); if ((bpNr==0x00) && (*found=='*')) { // Delete all CBreakpoint::DeleteAll(); DEBUG_ShowMsg("DEBUG: Breakpoints deleted."); @@ -967,7 +968,7 @@ bool ParseCommand(char* str) found = strstr(str,"C "); if (found==(char*)str) { // Set code overview found++; - Bit16u codeSeg = GetHexValue(found,found); found++; + Bit16u codeSeg = (Bit16u)GetHexValue(found,found); found++; Bit32u codeOfs = GetHexValue(found,found); DEBUG_ShowMsg("DEBUG: Set code overview to %04X:%04X",codeSeg,codeOfs); codeViewData.useCS = codeSeg; @@ -977,7 +978,7 @@ bool ParseCommand(char* str) found = strstr(str,"D "); if (found==(char*)str) { // Set data overview found++; - dataSeg = GetHexValue(found,found); found++; + dataSeg = (Bit16u)GetHexValue(found,found); found++; dataOfs = GetHexValue(found,found); DEBUG_ShowMsg("DEBUG: Set data overview to %04X:%04X",dataSeg,dataOfs); return true; @@ -1000,13 +1001,13 @@ bool ParseCommand(char* str) found = strstr(str,"SM "); if (found) { // Set memory with following values found+=3; - Bit16u seg = GetHexValue(found,found); found++; + Bit16u seg = (Bit16u)GetHexValue(found,found); found++; Bit32u ofs = GetHexValue(found,found); found++; Bit16u count = 0; while (*found) { while (*found==' ') found++; if (*found) { - Bit8u value = GetHexValue(found,found); found++; + Bit8u value = (Bit8u)GetHexValue(found,found); found++; mem_writeb(GetAddress(seg,ofs+count),value); count++; } @@ -1017,7 +1018,7 @@ bool ParseCommand(char* str) found = strstr(str,"INTT "); if (found) { // Create Cpu log file found+=4; - Bit8u intNr = GetHexValue(found,found); + Bit8u intNr = (Bit8u)GetHexValue(found,found); DEBUG_ShowMsg("DEBUG: Tracing INT %02X",intNr); Interrupt(intNr); SetCodeWinStart(); @@ -1026,7 +1027,7 @@ bool ParseCommand(char* str) found = strstr(str,"INT "); if (found) { // Create Cpu log file found+=4; - Bit8u intNr = GetHexValue(found,found); + Bit8u intNr = (Bit8u)GetHexValue(found,found); DEBUG_ShowMsg("DEBUG: Starting INT %02X",intNr); CBreakpoint::AddBreakpoint (SegValue(cs),reg_eip, true); CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip-1,true); @@ -1131,7 +1132,7 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) prefix[0] = tolower(*segpos); prefix[1] = tolower(*(segpos+1)); prefix[2] = 0; - seg = GetHexValue(segpos,segpos); + seg = (Bit16u)GetHexValue(segpos,segpos); } else { if (strstr(pos,"SP") || strstr(pos,"BP")) { seg = SegValue(ss); @@ -1155,25 +1156,27 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) pos++; }; Bit32u address = GetAddress(seg,adr); -// if (address<(XMS_GetSize()+1)*1024*1024) { - static char outmask[] = "%s:[%04X]=%02X"; - - if (cpu.pmode) outmask[6] = '8'; - switch (DasmLastOperandSize()) { - case 8 : { Bit8u val = mem_readb(address); - outmask[12] = '2'; - sprintf(result,outmask,prefix,adr,val); - } break; - case 16: { Bit16u val = mem_readw(address); - outmask[12] = '4'; - sprintf(result,outmask,prefix,adr,val); - } break; - case 32: { Bit32u val = mem_readd(address); - outmask[12] = '8'; - sprintf(result,outmask,prefix,adr,val); - } break; + if (address Date: Thu, 6 Nov 2003 01:14:05 +0000 Subject: [PATCH 1327/4131] Moved DMA channel code to dma.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1408 --- include/dma.h | 185 ++---------------------------------------- src/hardware/dma.cpp | 189 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 179 deletions(-) diff --git a/include/dma.h b/include/dma.h index 02819e0c..f97be390 100644 --- a/include/dma.h +++ b/include/dma.h @@ -91,7 +91,6 @@ public: }; -#define ff myController->flipflop class DmaChannel { public: @@ -166,193 +165,21 @@ public: } } - Bit32u Read(Bit32s requestsize, Bit8u * buffer) { - Bit32s bytesread; - bytesread = 0; - if(autoinit) { - while(requestsize>0) { - if(currcnt>=requestsize) { - MEM_BlockRead(curraddr,buffer,requestsize); - curraddr+=requestsize; - buffer+=requestsize; - currcnt-=requestsize; - bytesread+=requestsize; - requestsize=0; - break; - } else { - MEM_BlockRead(curraddr,buffer,currcnt); - bytesread+=currcnt; - buffer+=currcnt; - requestsize-=currcnt; - reset(); - MakeCallback(true); - } - } - if(currcnt==0) { - reset(); - MakeCallback(true); - } - return bytesread; + Bit32u Read(Bit32s requestsize, Bit8u * buffer); - } else { - if(currcnt>=requestsize) { - MEM_BlockRead(curraddr,buffer,requestsize); - curraddr+=requestsize; - buffer+=requestsize; - currcnt-=requestsize; - bytesread+=requestsize; - } else { - MEM_BlockRead(curraddr,buffer,currcnt); - buffer+=currcnt; - requestsize-=currcnt; - bytesread+=currcnt; - currcnt=0; - } - } - if(currcnt==0) MakeCallback(true); - return bytesread; - } + Bit32u Write(Bit32s requestsize, Bit8u * buffer); - Bit32u Write(Bit32s requestsize, Bit8u * buffer) { - Bit32s byteswrite; - byteswrite = 0; - if(autoinit) { - while(requestsize>0) { - if(currcnt>=requestsize) { - MEM_BlockWrite(curraddr,buffer,requestsize); - curraddr+=requestsize; - buffer+=requestsize; - currcnt-=requestsize; - byteswrite+=requestsize; - requestsize=0; - break; - } else { - MEM_BlockWrite(curraddr,buffer,currcnt); - byteswrite+=currcnt; - buffer+=currcnt; - requestsize-=currcnt; - reset(); - MakeCallback(true); - } - } - if(currcnt==0) { - reset(); - MakeCallback(true); - } - return byteswrite; + void calcPhys(void); - } else { - if(currcnt>=requestsize) { - MEM_BlockWrite(curraddr,buffer,requestsize); - curraddr+=requestsize; - buffer+=requestsize; - currcnt-=requestsize; - byteswrite+=requestsize; - } else { - MEM_BlockWrite(curraddr,buffer,currcnt); - buffer+=currcnt; - requestsize-=currcnt; - byteswrite+=currcnt; - currcnt=0; - } - } - if(currcnt==0) MakeCallback(true); - return byteswrite; - } + Bit16u portRead(Bit32u port, bool eightbit); - - void calcPhys(void) { - if (DMA16) { - physaddr = (baseaddr << 1) | ((pageaddr >> 1) << 17); - } else { - physaddr = (baseaddr) | (pageaddr << 16); - } - curraddr = physaddr; - current_addr = baseaddr; - } - - Bit16u portRead(Bit32u port, bool eightbit) { - if (port == ChannelPorts[DMA_BASEADDR][channum]) { - if(eightbit) { - if(ff) { - ff = !ff; - return current_addr & 0xff; - } else { - ff = !ff; - return current_addr >> 8; - } - } else { - return current_addr; - } - } - if (port == ChannelPorts[DMA_TRANSCOUNT][channum]) { - if(eightbit) { - if(ff) { - ff = !ff; - return (Bit8u)(currcnt & 0xff); - } else { - ff = !ff; - return (Bit8u)(currcnt >> 8); - } - } else { - return (Bit16u)currcnt; - } - } - if (port == ChannelPorts[DMA_PAGEREG][channum]) return pageaddr; - return 0xffff; - } - - void portWrite(Bit32u port, Bit16u val, bool eightbit) { - if (port == ChannelPorts[DMA_BASEADDR][channum]) { - if(eightbit) { - if(ff) { - baseaddr = (baseaddr & 0xff00) | (Bit8u)val; - } else { - baseaddr = (baseaddr & 0xff) | (val << 8); - } - ff = !ff; - } else { - baseaddr = val; - } - calcPhys(); - reset(); - } - if (port == ChannelPorts[DMA_TRANSCOUNT][channum]) { - if(eightbit) { - if(ff) { - transcnt = (transcnt & 0xff00) | (Bit8u)val; - } else { - transcnt = (transcnt & 0xff) | (val << 8); - } - ff = !ff; - } else { - transcnt = val; - } - currcnt = transcnt+1; - reset(); - DMA_CheckEnabled(this); - MakeCallback(false); - - } - if (port == ChannelPorts[DMA_PAGEREG][channum]) { - pageaddr = val; - calcPhys(); - reset(); - } - - } + void portWrite(Bit32u port, Bit16u val, bool eightbit); // Notify channel when mask changes - void Notify(void) { - if(!masked) { - DMA_CheckEnabled(this); - MakeCallback(false); - } - } + void Notify(void); }; -#undef ff extern DmaChannel *DmaChannels[8]; extern DmaController *DmaControllers[2]; diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index d165ac2a..58fb48ef 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -82,6 +82,195 @@ void DmaController::portWrite(Bit32u port, Bit16u val, bool eightbit) { } +Bit32u DmaChannel::Read(Bit32s requestsize, Bit8u * buffer) { + Bit32s bytesread; + bytesread = 0; + if(autoinit) { + while(requestsize>0) { + if(currcnt>=requestsize) { + MEM_BlockRead(curraddr,buffer,requestsize); + curraddr+=requestsize; + buffer+=requestsize; + currcnt-=requestsize; + bytesread+=requestsize; + requestsize=0; + break; + } else { + MEM_BlockRead(curraddr,buffer,currcnt); + bytesread+=currcnt; + buffer+=currcnt; + requestsize-=currcnt; + reset(); + MakeCallback(true); + } + } + if(currcnt==0) { + reset(); + MakeCallback(true); + } + return bytesread; + + } else { + if(currcnt>=requestsize) { + MEM_BlockRead(curraddr,buffer,requestsize); + curraddr+=requestsize; + buffer+=requestsize; + currcnt-=requestsize; + bytesread+=requestsize; + } else { + MEM_BlockRead(curraddr,buffer,currcnt); + buffer+=currcnt; + requestsize-=currcnt; + bytesread+=currcnt; + currcnt=0; + } + } + if(currcnt==0) MakeCallback(true); + return bytesread; +} + +Bit32u DmaChannel::Write(Bit32s requestsize, Bit8u * buffer) { + Bit32s byteswrite; + byteswrite = 0; + if(autoinit) { + while(requestsize>0) { + if(currcnt>=requestsize) { + MEM_BlockWrite(curraddr,buffer,requestsize); + curraddr+=requestsize; + buffer+=requestsize; + currcnt-=requestsize; + byteswrite+=requestsize; + requestsize=0; + break; + } else { + MEM_BlockWrite(curraddr,buffer,currcnt); + byteswrite+=currcnt; + buffer+=currcnt; + requestsize-=currcnt; + reset(); + MakeCallback(true); + } + } + if(currcnt==0) { + reset(); + MakeCallback(true); + } + return byteswrite; + + } else { + if(currcnt>=requestsize) { + MEM_BlockWrite(curraddr,buffer,requestsize); + curraddr+=requestsize; + buffer+=requestsize; + currcnt-=requestsize; + byteswrite+=requestsize; + } else { + MEM_BlockWrite(curraddr,buffer,currcnt); + buffer+=currcnt; + requestsize-=currcnt; + byteswrite+=currcnt; + currcnt=0; + } + } + if(currcnt==0) MakeCallback(true); + return byteswrite; +} + + +void DmaChannel::calcPhys(void) { + if (DMA16) { + physaddr = (baseaddr << 1) | ((pageaddr >> 1) << 17); + } else { + physaddr = (baseaddr) | (pageaddr << 16); + } + curraddr = physaddr; + current_addr = baseaddr; +} + +#define ff myController->flipflop + +Bit16u DmaChannel::portRead(Bit32u port, bool eightbit) { + if (port == ChannelPorts[DMA_BASEADDR][channum]) { + if(eightbit) { + if(ff) { + ff = !ff; + return current_addr & 0xff; + } else { + ff = !ff; + return current_addr >> 8; + } + } else { + return current_addr; + } + } + if (port == ChannelPorts[DMA_TRANSCOUNT][channum]) { + if(eightbit) { + if(ff) { + ff = !ff; + return (Bit8u)(currcnt & 0xff); + } else { + ff = !ff; + return (Bit8u)(currcnt >> 8); + } + } else { + return (Bit16u)currcnt; + } + } + if (port == ChannelPorts[DMA_PAGEREG][channum]) return pageaddr; + return 0xffff; +} + +void DmaChannel::portWrite(Bit32u port, Bit16u val, bool eightbit) { + if (port == ChannelPorts[DMA_BASEADDR][channum]) { + if(eightbit) { + if(ff) { + baseaddr = (baseaddr & 0xff00) | (Bit8u)val; + } else { + baseaddr = (baseaddr & 0xff) | (val << 8); + } + ff = !ff; + } else { + baseaddr = val; + } + calcPhys(); + reset(); + } + if (port == ChannelPorts[DMA_TRANSCOUNT][channum]) { + if(eightbit) { + if(ff) { + transcnt = (transcnt & 0xff00) | (Bit8u)val; + } else { + transcnt = (transcnt & 0xff) | (val << 8); + } + ff = !ff; + } else { + transcnt = val; + } + currcnt = transcnt+1; + reset(); + DMA_CheckEnabled(this); + MakeCallback(false); + + } + if (port == ChannelPorts[DMA_PAGEREG][channum]) { + pageaddr = val; + calcPhys(); + reset(); + } + +} + +#undef ff + +// Notify channel when mask changes +void DmaChannel::Notify(void) { + if(!masked) { + DMA_CheckEnabled(this); + MakeCallback(false); + } +} + + static Bit16u readDMAPorts(Bit32u port, bool eightbit) { int i,j; From 247678bbe687d19ce611c6ca3523a25827377675 Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Thu, 6 Nov 2003 01:15:10 +0000 Subject: [PATCH 1328/4131] Added documentation. Removed outdated code. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1409 --- src/hardware/gus.cpp | 430 ++++++++++++++++++++++--------------------- 1 file changed, 224 insertions(+), 206 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index c8ccc505..bed77567 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + #include #include "dosbox.h" #include "inout.h" @@ -64,6 +82,7 @@ struct GFGus { bool irqenabled; + // IRQ status register values struct IRQStat { bool MIDITx; bool MIDIRx; @@ -92,9 +111,10 @@ struct IRQFifoDef { Bit16s stackpos; } IRQFifo; + +// Routines to manage IRQ requests coming from the GUS static void pushIRQ(Bit8u channum, bool WaveIRQ, bool RampIRQ) { IRQFifo.stackpos++; - //LOG_MSG("Stack position %d", IRQFifo.stackpos); if(IRQFifo.stackpos < GUSFIFOSIZE) { myGUS.irq.WaveTable = WaveIRQ; myGUS.irq.VolRamp = RampIRQ; @@ -110,6 +130,26 @@ static void pushIRQ(Bit8u channum, bool WaveIRQ, bool RampIRQ) { } } +static void popIRQ(IRQFifoEntry * tmpentry) { + if(IRQFifo.stackpos<0) { + tmpentry->channum = 0; + tmpentry->RampIRQ = false; + tmpentry->WaveIRQ = false; + return; + } + memcpy(tmpentry, &IRQFifo.entry[IRQFifo.stackpos], sizeof(IRQFifoEntry)); + --IRQFifo.stackpos; + if(IRQFifo.stackpos >= 0) { + myGUS.irq.WaveTable = IRQFifo.entry[IRQFifo.stackpos].WaveIRQ; + myGUS.irq.VolRamp = IRQFifo.entry[IRQFifo.stackpos].RampIRQ; + } else { + myGUS.irq.WaveTable = false; + myGUS.irq.VolRamp = false; + } +} + + +// Returns a single 16-bit sample from the Gravis's RAM INLINE Bit16s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { Bit32u useAddr; Bit32u holdAddr; @@ -119,6 +159,8 @@ INLINE Bit16s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { Bit8s tmpsmall = (Bit8s)GUSRam[useAddr]; return (Bit16s)(tmpsmall << 7); } else { + + // Interpolate Bit8s b1 = (Bit8s)GUSRam[useAddr]; Bit8s b2 = (Bit8s)GUSRam[useAddr+1]; Bit16s w1 = b1 << 7; @@ -129,17 +171,19 @@ INLINE Bit16s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { } } else { + // Formula used to convert addresses for use with 16-bit samples holdAddr = useAddr & 0xc0000L; useAddr = useAddr & 0x1ffffL; useAddr = useAddr << 1; useAddr = (holdAddr | useAddr); - //LOG_MSG("Sample from %x (%d)", useAddr, useAddr); - + if(Delta >= 1024) { return (Bit16s)((Bit16u)GUSRam[useAddr] | ((Bit16u)GUSRam[useAddr+1] << 8)) >> 1; } else { + + // Interpolate Bit16s w1 = (Bit16s)((Bit16u)GUSRam[useAddr] | ((Bit16u)GUSRam[useAddr+1] << 8)); Bit16s w2 = (Bit16s)((Bit16u)GUSRam[useAddr+2] | ((Bit16u)GUSRam[useAddr+3] << 8)); Bit16s diff = w2 - w1; @@ -149,25 +193,6 @@ INLINE Bit16s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { } } -static void popIRQ(IRQFifoEntry * tmpentry) { - if(IRQFifo.stackpos<0) { - tmpentry->channum = 0; - tmpentry->RampIRQ = false; - tmpentry->WaveIRQ = false; - return; - } - memcpy(tmpentry, &IRQFifo.entry[IRQFifo.stackpos], sizeof(IRQFifoEntry)); - --IRQFifo.stackpos; - //LOG_MSG("Stack position %d", IRQFifo.stackpos); - if(IRQFifo.stackpos >= 0) { - myGUS.irq.WaveTable = IRQFifo.entry[IRQFifo.stackpos].WaveIRQ; - myGUS.irq.VolRamp = IRQFifo.entry[IRQFifo.stackpos].RampIRQ; - } else { - myGUS.irq.WaveTable = false; - myGUS.irq.VolRamp = false; - } -} - class GUSChannels { public: Bit8u voiceCont; @@ -217,6 +242,7 @@ public: }; + // Voice control register void WriteVoiceCtrl(Bit8u val) { voiceCont = val; if (val & 0x3) moving = false; @@ -234,9 +260,9 @@ public: return tmpval; } + // Frequency control register void WriteFreqCtrl(Bit16u val) { FreqCont = val; - //RealDelta = (myGUS.basefreq * (Bit32u)val) / GUS_RATE; int fc; fc = val; fc = fc >> 1; @@ -247,13 +273,12 @@ public: simple = ((float)fc / (float)GUS_RATE) * 512; RealDelta = (Bit32u)simple; - - } Bit16u ReadFreqCtrl(void) { return FreqCont; } + // Pan position register void WritePanPot(Bit8u val) { if(val<8) { leftvol = 255; @@ -263,12 +288,12 @@ public: leftvol = (8-(val-8)) << 5; } PanPot = val; - } Bit8u ReadPanPot(void) { return PanPot; } + // Volume ramping control register void WriteVolControl(Bit8u val) { VolControl = val; if (val & 0x3) ramping = false; @@ -284,6 +309,7 @@ public: } + // Methods to queue IRQ on ramp or sample end void NotifyEndSamp(void) { if(!notifyonce) { if((voiceCont & 0x20) != 0) { @@ -301,11 +327,16 @@ public: } } + // Debug routine to show current channel position void ShowAddr(void) { LOG_MSG("Chan %d Start %d End %d Current %d", channum, StartAddr>>9, EndAddr>>9, CurAddr>>9); } + // Generate the samples required by the callback routine + // It should be noted that unless a channel is stopped, it will + // continue to return the sample it is pointing to, regardless + // of whether or not the channel is moving or ramping. void generateSamples(Bit16s * stream,Bit32u len) { int i; Bit16s tmpsamp; @@ -314,157 +345,156 @@ public: notifyonce = false; - //if((voiceCont & 0x4) == 0) { - // 8-bit data - for(i=0;i4095) CurVolume = 4095; + if(CurVolume<0) CurVolume = 0; + tmpsamp = (tmpsamp * vol16bit[CurVolume]) >> 12; - tmpsamp = GetSample(RealDelta, CurAddr, eightbit); + // Output stereo sample + stream[i<<1] = (Bit16s)(((Bit32s)tmpsamp * (Bit32s)leftvol)>>8) ; + stream[(i<<1)+1] = (Bit16s)(((Bit32s)tmpsamp * rightvol)>>8); - if(CurVolume>4095) CurVolume = 4095; - if(CurVolume<0) CurVolume = 0; - tmpsamp = (tmpsamp * vol16bit[CurVolume]) >> 12; - stream[i<<1] = (Bit16s)(((Bit32s)tmpsamp * (Bit32s)leftvol)>>8) ; - stream[(i<<1)+1] = (Bit16s)(((Bit32s)tmpsamp * rightvol)>>8); + if(dir) { + // Increment backwards + if (moving) CurAddr -= RealDelta; + if ((!eightbit) && (moving)) CurAddr -= RealDelta; - if(dir) { - if (moving) CurAddr -= RealDelta; - if ((!eightbit) && (moving)) CurAddr -= RealDelta; + if(CurAddr <= StartAddr) { + if((VolControl & 0x4) == 0) { + if((voiceCont & 0x8) != 0) { + if((voiceCont & 0x10) != 0) { + dir = !dir; + } else { + CurAddr = EndAddr; + } + + } else { + moving = false; + } + NotifyEndSamp(); + } else { + NotifyEndSamp(); + + } - if(CurAddr <= StartAddr) { - if((VolControl & 0x4) == 0) { - if((voiceCont & 0x8) != 0) { - if((voiceCont & 0x10) != 0) { - dir = !dir; - } else { - CurAddr = EndAddr; - } - - } else { - moving = false; - //NotifyEndSamp(); - //break; - } - NotifyEndSamp(); - } else { - NotifyEndSamp(); - - } - - } - - } else { - if (moving) CurAddr += RealDelta; - if ((!eightbit) && (moving)) CurAddr += RealDelta; - //LOG_MSG("Cur %x to %x or (%x, %x) %d", CurAddr >> 9, EndAddr >> 9, CurAddr, EndAddr, (CurAddr >= EndAddr) ); - if(CurAddr >= EndAddr) { - if((VolControl & 0x4) == 0) { - if((voiceCont & 0x8) != 0) { - if((voiceCont & 0x10) != 0) { - dir = !dir; - } else { - CurAddr = StartAddr; - } - - } else { - moving = false; - //NotifyEndSamp(); - //break; - } - NotifyEndSamp(); - } else { - NotifyEndSamp(); - } - } } + } else { - // Update volume - if(ramping) { - nextramp -= myGUS.mupersamp; - bool flagged; - flagged = false; - while(nextramp <= 0) { - if(voldir) { - CurVolume -= (VolRampRate & 0x3f); - if (CurVolume <= 0) { - CurVolume = 0; - flagged = true; - } - - if((vol16bit[CurVolume]<=VolRampStart) || (flagged)){ - if((VolControl & 0x8) != 0) { - if((VolControl & 0x10) != 0) { - voldir = !voldir; - } else { - CurVolume = VolRampEndOrg; - } - } else { - ramping = false; - } - NotifyEndRamp(); + // Increment forwards + if (moving) CurAddr += RealDelta; + if ((!eightbit) && (moving)) CurAddr += RealDelta; + if(CurAddr >= EndAddr) { + if((VolControl & 0x4) == 0) { + if((voiceCont & 0x8) != 0) { + if((voiceCont & 0x10) != 0) { + dir = !dir; + } else { + CurAddr = StartAddr; } } else { - CurVolume += (VolRampRate & 0x3f); - if (CurVolume >= 4095) { - CurVolume = 4095; - flagged = true; - } + moving = false; + } + NotifyEndSamp(); + } else { + NotifyEndSamp(); + } + } + } - if((vol16bit[CurVolume]>=VolRampEnd) || (flagged)){ - if((VolControl & 0x8) != 0) { - if((VolControl & 0x10) != 0) { - voldir = !voldir; - } else { - CurVolume = VolRampStartOrg; - } + // Update volume + if(ramping) { + + // Subtract ramp counter by elapsed microseconds + nextramp -= myGUS.mupersamp; + bool flagged; + flagged = false; + + // Ramp volume until nextramp is a positive integer + while(nextramp <= 0) { + if(voldir) { + CurVolume -= (VolRampRate & 0x3f); + if (CurVolume <= 0) { + CurVolume = 0; + flagged = true; + } + + if((vol16bit[CurVolume]<=VolRampStart) || (flagged)){ + if((VolControl & 0x8) != 0) { + if((VolControl & 0x10) != 0) { + voldir = !voldir; } else { - ramping = false; + CurVolume = VolRampEndOrg; } - NotifyEndRamp(); + } else { + ramping = false; } - + NotifyEndRamp(); } - - switch(VolRampRate >> 6) { - case 0: - nextramp += myGUS.muperchan; - break; - case 1: - nextramp += myGUS.muperchan * 8; - break; - case 2: - nextramp += myGUS.muperchan * 64; - break; - case 3: - nextramp += myGUS.muperchan * 512; - break; - default: - nextramp += myGUS.muperchan * 512; - break; - + } else { + CurVolume += (VolRampRate & 0x3f); + if (CurVolume >= 4095) { + CurVolume = 4095; + flagged = true; } - + + if((vol16bit[CurVolume]>=VolRampEnd) || (flagged)){ + if((VolControl & 0x8) != 0) { + if((VolControl & 0x10) != 0) { + voldir = !voldir; + } else { + CurVolume = VolRampStartOrg; + } + } else { + ramping = false; + } + NotifyEndRamp(); + } + } - } + switch(VolRampRate >> 6) { + case 0: + nextramp += myGUS.muperchan; + break; + case 1: + nextramp += myGUS.muperchan * 8; + break; + case 2: + nextramp += myGUS.muperchan * 64; + break; + case 3: + nextramp += myGUS.muperchan * 512; + break; + default: + nextramp += myGUS.muperchan * 512; + break; + + } + + } } - //} else { - // 16-bit data - // LOG_MSG("16-bit data not supported yet!"); - //} + + } + + } }; -GUSChannels *guschan[32]; +GUSChannels *guschan[33]; GUSChannels *curchan; @@ -475,16 +505,17 @@ static void GUSReset(void) // Reset myGUS.timerReg = 85; memset(&myGUS.irq, 0, sizeof(myGUS.irq)); - //IRQFifo.stackpos = -1; } if((myGUS.gRegData & 0x4) != 0) { myGUS.irqenabled = true; } else { myGUS.irqenabled = false; } - //LOG_MSG("Gus reset"); + myGUS.timers[0].active = false; myGUS.timers[1].active = false; + + // Stop all channels int i; for(i=0;i<32;i++) { guschan[i]->WriteVoiceCtrl(0x3); @@ -492,9 +523,6 @@ static void GUSReset(void) } IRQFifo.stackpos = -1; - - //MIXER_Enable(gus_chan,false); - } @@ -503,8 +531,7 @@ static Bit16u ExecuteReadRegister(void) { Bit8u tmpreg; switch (myGUS.gRegSelect) { - case 0x41: - + case 0x41: // Dma control register - read acknowledges DMA IRQ tmpreg = myGUS.DMAControl & 0xbf; if(myGUS.irq.DMATC) tmpreg |= 0x40; @@ -512,9 +539,9 @@ static Bit16u ExecuteReadRegister(void) { PIC_DeActivateIRQ(myGUS.irq1); return (Bit16u)(tmpreg << 8); - case 0x42: + case 0x42: // Dma address register return myGUS.dmaAddr; - case 0x49: + case 0x49: // Dma sample register tmpreg = myGUS.DMAControl & 0xbf; if(myGUS.irq.DMATC) tmpreg |= 0x40; @@ -523,7 +550,7 @@ static Bit16u ExecuteReadRegister(void) { //LOG_MSG("Read sampling status, returned 0x%x", tmpreg); return (Bit16u)(tmpreg << 8); - case 0x80: + case 0x80: // Channel voice control read register if(curchan != NULL) { Bit8u sndout; sndout = curchan->voiceCont & 0xFC; @@ -532,37 +559,36 @@ static Bit16u ExecuteReadRegister(void) { return (Bit16u)(sndout<< 8); } else return 0x0300; - case 0x82: + case 0x82: // Channel MSB address register if(curchan != NULL) { return (curchan->StartAddr >> 16); } else return 0x0000; - case 0x83: + case 0x83: // Channel LSW address register if(curchan != NULL) { return (curchan->StartAddr & 0xffff); } else return 0x0000; - case 0x89: + case 0x89: // Channel volume register if(curchan != NULL) { return (curchan->CurVolume << 4); } else return 0x0000; - case 0x8a: + case 0x8a: // Channel MSB current address register if(curchan != NULL) { return (curchan->CurAddr >> 16); } else return 0x0000; - case 0x8b: + case 0x8b: // Channel LSW current address register if(curchan != NULL) { return (curchan->CurAddr & 0xFFFF); } else return 0x0000; - case 0x8d: + case 0x8d: // Channel volume control register if(curchan != NULL) { Bit8u volout; volout = curchan->VolControl & 0xFC; if(!curchan->ramping) volout |= 0x3; - //LOG_MSG("Ret at 8D %x - chan %d - ramp %d move %d rate %d pos %d dir %d py %d", volout, curchan->channum, curchan->ramping, curchan->moving, curchan->VolRampRate & 0x3f, vol16bit[curchan->CurVolume], curchan->voldir, curchan->playing); return (volout << 8); } else return 0x0300; - case 0x8f: + case 0x8f: // General channel IRQ status register Bit8u temp; temp = 0x20; IRQFifoEntry tmpentry; @@ -583,89 +609,90 @@ static Bit16u ExecuteReadRegister(void) { static void ExecuteGlobRegister(void) { //LOG_MSG("Access global register %x with %x", myGUS.gRegSelect, myGUS.gRegData); switch(myGUS.gRegSelect) { - case 0x0: + case 0x0: // Channel voice control register if(curchan != NULL) { curchan->WriteVoiceCtrl((Bit8u)myGUS.gRegData); } break; - case 0x1: + case 0x1: // Channel frequency control register if(curchan != NULL) { curchan->WriteFreqCtrl(myGUS.gRegData); } break; - case 0x2: + case 0x2: // Channel MSB start address register if(curchan != NULL) { Bit32u tmpaddr = myGUS.gRegData << 16; curchan->StartAddr = (curchan->StartAddr & 0xFFFF) | tmpaddr; } break; - case 0x3: + case 0x3: // Channel LSB start address register if(curchan != NULL) { Bit32u tmpaddr = (Bit32u)(myGUS.gRegData); curchan->StartAddr = (curchan->StartAddr & 0x1FFF0000) | tmpaddr; } break; - case 0x4: + case 0x4: // Channel MSB end address register if(curchan != NULL) { Bit32u tmpaddr = (Bit32u)myGUS.gRegData << 16; curchan->EndAddr = (curchan->EndAddr & 0xFFFF) | tmpaddr; } break; - case 0x5: + case 0x5: // Channel MSB end address register if(curchan != NULL) { Bit32u tmpaddr = (Bit32u)(myGUS.gRegData); curchan->EndAddr = (curchan->EndAddr & 0x1FFF0000) | tmpaddr; } break; - case 0x6: + case 0x6: // Channel volume ramp rate register if(curchan != NULL) { Bit8u tmpdata = (Bit8u)myGUS.gRegData; curchan->VolRampRate = tmpdata; } break; - case 0x7: + case 0x7: // Channel volume ramp start register EEEEMMMM if(curchan != NULL) { Bit8u tmpdata = (Bit8u)myGUS.gRegData; curchan->VolRampStart = vol8bit[tmpdata]; curchan->VolRampStartOrg = tmpdata << 4; } break; - case 0x8: + case 0x8: // Channel volume ramp end register EEEEMMMM if(curchan != NULL) { Bit8u tmpdata = (Bit8u)myGUS.gRegData; curchan->VolRampEnd = vol8bit[tmpdata]; curchan->VolRampEndOrg = tmpdata << 4; } break; - case 0x9: + case 0x9: // Channel current volume register if(curchan != NULL) { Bit16u tmpdata = (Bit16u)myGUS.gRegData >> 4; curchan->CurVolume = tmpdata; } break; - case 0xA: + case 0xA: // Channel MSB current address register if(curchan != NULL) { curchan->CurAddr = (curchan->CurAddr & 0xFFFF) | ((Bit32u)myGUS.gRegData << 16); } break; - case 0xB: + case 0xB: // Channel LSW current address register if(curchan != NULL) { curchan->CurAddr = (curchan->CurAddr & 0xFFFF0000) | ((Bit32u)myGUS.gRegData); } break; - case 0xC: + case 0xC: // Channel pan pot register if(curchan != NULL) { curchan->WritePanPot((Bit8u)myGUS.gRegData); } break; - case 0xD: + case 0xD: // Channel volume control register if(curchan != NULL) { curchan->WriteVolControl((Bit8u)myGUS.gRegData); } break; - case 0xE: + case 0xE: // Set active channel register myGUS.activechan = myGUS.gRegData & 63; if(myGUS.activechan < 14) myGUS.activechan = 14; + if(myGUS.activechan > 32) myGUS.activechan = 32; MIXER_Enable(gus_chan,true); myGUS.basefreq = (Bit32u)((float)1000000/(1.619695497*(float)myGUS.activechan)); @@ -675,23 +702,23 @@ static void ExecuteGlobRegister(void) { myGUS.muperchan = (Bit16u)((float)1.6 * (float)myGUS.activechan); LOG_MSG("GUS set to %d channels", myGUS.activechan); break; - case 0x41: + case 0x41: // Dma control register myGUS.DMAControl = (Bit8u)myGUS.gRegData; if ((myGUS.DMAControl & 0x1) != 0) { //LOG_MSG("GUS request DMA transfer"); if(DmaChannels[myGUS.dma1]->enabled) UseDMA(DmaChannels[myGUS.dma1]); } break; - case 0x42: + case 0x42: // Gravis DRAM DMA address register myGUS.dmaAddr = myGUS.gRegData; break; - case 0x43: + case 0x43: // MSB Peek/poke DRAM position myGUS.gDramAddr = (0xff0000 & myGUS.gDramAddr) | ((Bit32u)myGUS.gRegData); break; - case 0x44: + case 0x44: // LSW Peek/poke DRAM position myGUS.gDramAddr = (0xffff & myGUS.gDramAddr) | ((Bit32u)myGUS.gRegData) << 16; break; - case 0x45: + case 0x45: // Timer control register. Identical in operation to Adlib's timer myGUS.TimerControl = (Bit8u)myGUS.gRegData; if((myGUS.TimerControl & 0x08) !=0) myGUS.timers[1].countdown = myGUS.timers[1].setting; if((myGUS.TimerControl & 0x04) !=0) myGUS.timers[0].countdown = myGUS.timers[0].setting; @@ -700,23 +727,23 @@ static void ExecuteGlobRegister(void) { PIC_DeActivateIRQ(myGUS.irq1); break; - case 0x46: + case 0x46: // Timer 1 control myGUS.timers[0].bytetimer = (Bit8u)myGUS.gRegData; myGUS.timers[0].setting = ((Bit32s)0xff - (Bit32s)myGUS.timers[0].bytetimer) * (Bit32s)80; myGUS.timers[0].countdown = myGUS.timers[0].setting; break; - case 0x47: + case 0x47: // Timer 2 control myGUS.timers[1].bytetimer = (Bit8u)myGUS.gRegData; myGUS.timers[1].setting = ((Bit32s)0xff - (Bit32s)myGUS.timers[1].bytetimer) * (Bit32s)360; myGUS.timers[1].countdown = myGUS.timers[1].setting; break; - case 0x49: + case 0x49: // DMA sampling control register myGUS.SampControl = (Bit8u)myGUS.gRegData; if ((myGUS.SampControl & 0x1) != 0) { if(DmaChannels[myGUS.dma1]->enabled) UseDMA(DmaChannels[myGUS.dma1]); } break; - case 0x4c: + case 0x4c: // GUS reset register GUSReset(); break; default: @@ -800,12 +827,6 @@ static void write_gus(Bit32u port,Bit8u val) { myGUS.timers[0].active = ((val & 0x1) > 0); myGUS.timers[1].active = ((val & 0x2) > 0); - fp = fopen("gusdump.raw","wb"); - fwrite(&GUSRam[0],1024*1024,1,fp); - fclose(fp); - - - //LOG_MSG("Timer output reg %x", val); break; case 0x20b: if((myGUS.mixControl & 0x40) != 0) { @@ -826,7 +847,8 @@ static void write_gus(Bit32u port,Bit8u val) { break; case 0x302: - myGUS.gCurChannel = val; + myGUS.gCurChannel = val ; + if (myGUS.gCurChannel > 32) myGUS.gCurChannel = 32; curchan = guschan[val]; break; case 0x303: @@ -924,6 +946,7 @@ static void GUS_CallBack(Bit8u * stream,Bit32u len) { if(myGUS.timers[0].active) { myGUS.timers[0].countdown-=(len * (Bit32u)myGUS.mupersamp); if(!myGUS.irq.T1) { + // Expire Timer 1 if(myGUS.timers[0].countdown < 0) { if((myGUS.TimerControl & 0x04) !=0) { PIC_ActivateIRQ(myGUS.irq1); @@ -937,32 +960,27 @@ static void GUS_CallBack(Bit8u * stream,Bit32u len) { if(myGUS.timers[1].active) { if(!myGUS.irq.T2) { myGUS.timers[1].countdown-=(len * (Bit32u)myGUS.mupersamp); + // Expire Timer 2 if(myGUS.timers[1].countdown < 0) { if((myGUS.TimerControl & 0x08) !=0) { PIC_ActivateIRQ(myGUS.irq1); } myGUS.irq.T2 = true; - //LOG_MSG("T2 timer expire"); - //myGUS.timers[1].countdown = myGUS.timers[1].setting; } } } - - + bufptr = (Bit16s *)stream; - //for(i=0;i Date: Sat, 8 Nov 2003 09:41:45 +0000 Subject: [PATCH 1329/4131] New height scaling variable Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1410 --- include/vga.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/vga.h b/include/vga.h index fa1ae3c2..1faf3c25 100644 --- a/include/vga.h +++ b/include/vga.h @@ -98,6 +98,7 @@ typedef struct { Bitu height; Bitu pitch; Bitu blank; + Bitu scaleh; bool double_width; bool double_height; Bitu lines; From a1e279829b3a30ad0bbe087bd86cf38b44e0c103 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 8 Nov 2003 09:53:11 +0000 Subject: [PATCH 1330/4131] Rendering rewrite for aspect correction and vga vertical stretching Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1411 --- include/render.h | 12 +- src/gui/Makefile.am | 3 +- src/gui/render.cpp | 292 ++++++++++++-------- src/gui/render_normal.h | 191 +++---------- src/gui/render_scale2x.h | 536 ++----------------------------------- src/gui/render_templates.h | 53 ++++ 6 files changed, 302 insertions(+), 785 deletions(-) create mode 100644 src/gui/render_templates.h diff --git a/include/render.h b/include/render.h index 2f637088..8154c422 100644 --- a/include/render.h +++ b/include/render.h @@ -23,23 +23,13 @@ enum RENDER_Operation { OP_Shot, OP_Normal2x, OP_AdvMame2x, - OP_Blit, }; -enum { - DoubleNone= 0x00, - DoubleWidth= 0x01, - DoubleHeight= 0x02, - DoubleBoth= 0x03 -}; - - - typedef void (* RENDER_Part_Handler)(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy); typedef void (* RENDER_Draw_Handler)(RENDER_Part_Handler part_handler); void RENDER_DoUpdate(void); -void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu flags,RENDER_Draw_Handler draw_handler); +void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,double ratio,Bitu scalew,Bitu scaleh,RENDER_Draw_Handler draw_handler); void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue); diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index fafd8e72..0aea3749 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -1,6 +1,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libgui.a -libgui_a_SOURCES = sdlmain.cpp render.cpp render_normal.h render_scale2x.h \ +libgui_a_SOURCES = sdlmain.cpp \ + render.cpp render_normal.h render_scale2x.h render_templates.h \ midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h midi_alsa.h diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 4be97f16..fb0cec8e 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,10 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.19 2003-10-15 08:20:50 harekiet Exp $ */ +/* $Id: render.cpp,v 1.20 2003-11-08 09:53:11 harekiet Exp $ */ #include #include +#include +#include #include "dosbox.h" #include "video.h" @@ -29,7 +31,8 @@ #include "cross.h" #include "support.h" -#define MAX_RES 2048 +#define RENDER_MAXWIDTH 1280 +#define RENDER_MAXHEIGHT 1024 struct PalData { struct { @@ -43,6 +46,7 @@ struct PalData { union { Bit32u bpp32[256]; Bit16u bpp16[256]; + Bit32u yuv[256]; } lookup; }; @@ -53,28 +57,36 @@ static struct { Bitu height; Bitu bpp; Bitu pitch; - Bitu flags; - float ratio; + Bitu scalew; + Bitu scaleh; + double ratio; RENDER_Draw_Handler draw_handler; } src; struct { Bitu width; Bitu height; Bitu pitch; - Bitu bpp; /* The type of BPP the operation requires for input */ + GFX_MODES gfx_mode; RENDER_Operation type; RENDER_Operation want_type; RENDER_Part_Handler part_handler; - void * dest; - void * buffer; - void * pixels; + Bit8u * dest; + Bit8u * buffer; + Bit8u * pixels; } op; struct { Bitu count; Bitu max; } frameskip; - Bitu flags; PalData pal; + struct { + Bit8u hlines[RENDER_MAXHEIGHT]; + Bit16u hindex[RENDER_MAXHEIGHT]; + } normal; + struct { + Bit16u hindex[RENDER_MAXHEIGHT]; + Bitu line_starts[RENDER_MAXHEIGHT][3]; + } advmame2x; #if (C_SSHOT) struct { RENDER_Operation type; @@ -84,12 +96,14 @@ static struct { #endif bool screenshot; bool active; + bool aspect; } render; /* Forward declerations */ static void RENDER_ResetPal(void); /* Include the different rendering routines */ +#include "render_templates.h" #include "render_normal.h" #include "render_scale2x.h" @@ -201,28 +215,41 @@ static void EnableScreenShot(void) { /* This could go kinda bad with multiple threads */ static void Check_Palette(void) { if (render.pal.first>render.pal.last) return; - switch (render.op.bpp) { - case 8: + Bitu i; + switch (render.op.gfx_mode) { + case GFX_8BPP: GFX_SetPalette(render.pal.first,render.pal.last-render.pal.first+1,(GFX_PalEntry *)&render.pal.rgb[render.pal.first]); break; - case 16: - for (;render.pal.first<=render.pal.last;render.pal.first++) { - render.pal.lookup.bpp16[render.pal.first]=GFX_GetRGB( - render.pal.rgb[render.pal.first].red, - render.pal.rgb[render.pal.first].green, - render.pal.rgb[render.pal.first].blue); + case GFX_15BPP: + case GFX_16BPP: + for (i=render.pal.first;i<=render.pal.last;i++) { + Bit8u r=render.pal.rgb[i].red; + Bit8u g=render.pal.rgb[i].green; + Bit8u b=render.pal.rgb[i].blue; + render.pal.lookup.bpp16[i]=GFX_GetRGB(r,g,b); } break; - case 32: - for (;render.pal.first<=render.pal.last;render.pal.first++) { - render.pal.lookup.bpp32[render.pal.first]= - GFX_GetRGB( - render.pal.rgb[render.pal.first].red, - render.pal.rgb[render.pal.first].green, - render.pal.rgb[render.pal.first].blue); + case GFX_24BPP: + case GFX_32BPP: + for (i=render.pal.first;i<=render.pal.last;i++) { + Bit8u r=render.pal.rgb[i].red; + Bit8u g=render.pal.rgb[i].green; + Bit8u b=render.pal.rgb[i].blue; + render.pal.lookup.bpp32[i]=GFX_GetRGB(r,g,b); } break; - }; + case GFX_YUV: + for (i=render.pal.first;i<=render.pal.last;i++) { + Bit8u r=render.pal.rgb[i].red; + Bit8u g=render.pal.rgb[i].green; + Bit8u b=render.pal.rgb[i].blue; + Bit8u y = ( 9797*(r) + 19237*(g) + 3734*(b) ) >> 15; + Bit8u u = (18492*((b)-(y)) >> 15) + 128; + Bit8u v = (23372*((r)-(y)) >> 15) + 128; + render.pal.lookup.yuv[i]=(u << 0) | (y << 8) | (v << 16) | (y << 24); + } + break; + } /* Setup pal index to startup values */ render.pal.first=256; render.pal.last=0; @@ -251,19 +278,14 @@ void RENDER_DoUpdate(void) { GFX_DoUpdate(); } -static void RENDER_DrawScreen(void * data) { +static void RENDER_DrawScreen(Bit8u * data,Bitu pitch) { + render.op.pitch=pitch; switch (render.op.type) { #if (C_SSHOT) doagain: #endif case OP_None: - render.op.dest=render.op.pixels=data; - render.src.draw_handler(render.op.part_handler); - break; - case OP_Blit: - render.op.dest=render.op.pixels=data; - render.src.draw_handler(render.op.part_handler); - break; + case OP_Normal2x: case OP_AdvMame2x: render.op.dest=render.op.pixels=data; render.src.draw_handler(render.op.part_handler); @@ -272,8 +294,8 @@ doagain: case OP_Shot: render.shot.pitch=render.op.pitch; render.op.pitch=render.src.width; - render.op.pixels=malloc(render.src.width*render.src.height); - render.src.draw_handler(Normal_DN_8); + render.op.pixels=(Bit8u*)malloc(render.src.width*render.src.height); +// render.src.draw_handler(Normal_DN_8); TakeScreenShot((Bit8u *)render.op.pixels); free(render.op.pixels); render.op.pitch=render.shot.pitch; @@ -283,30 +305,134 @@ doagain: } } -static void RENDER_Resize(Bitu * width,Bitu * height) { - /* Calculate the new size the window should be */ - if (!*width && !*height) { - /* Special command to reset any resizing for fullscreen */ - *width=render.src.width; - *height=render.src.height; - } else { - if ((*width/render.src.ratio)<*height) *height=(Bitu)(*width/render.src.ratio); - else *width=(Bitu)(*height*render.src.ratio); - } +static void SetAdvMameTable(Bitu index,Bits src0,Bits src1,Bits src2) { + if (src0<0) src0=0; + if ((Bitu)src0>=render.src.height) src0=render.src.height-1; + if ((Bitu)src1>=render.src.height) src1=render.src.height-1; + if ((Bitu)src2>=render.src.height) src2=render.src.height-1; + render.advmame2x.line_starts[index][0]=src0*render.src.pitch; + render.advmame2x.line_starts[index][1]=src1*render.src.pitch; + render.advmame2x.line_starts[index][2]=src2*render.src.pitch; + } -static void Render_Blit_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags) { + +void RENDER_ReInit(void) { + Bitu width=render.src.width; + Bitu height=render.src.height; + Bitu bpp=render.src.bpp; + + Bitu scalew=render.src.scalew; + Bitu scaleh=render.src.scaleh; + + double gfx_scalew=1.0; + double gfx_scaleh=1.0; + + if (render.src.ratio>1.0) gfx_scaleh*=render.src.ratio; + else gfx_scalew*=(1/render.src.ratio); + + GFX_MODES gfx_mode;Bitu gfx_flags; + gfx_mode=GFX_GetBestMode(render.src.bpp,gfx_flags); + Bitu index; + switch (gfx_mode) { + case GFX_8BPP: index=0;break; + case GFX_15BPP: index=1;break; + case GFX_16BPP: index=1;break; + case GFX_24BPP: index=2;break; + case GFX_32BPP: index=3;break; + case GFX_YUV: index=3;break; + } + /* Initial scaler testing */ + switch (render.op.want_type) { + case OP_Normal2x: + case OP_None: + render.op.type=render.op.want_type; +normalop: + if (gfx_flags & GFX_HASSCALING) { + gfx_scalew*=scalew; + gfx_scaleh*=scaleh; + render.op.part_handler=Normal_SINGLE_8[index]; + for (Bitu i=0;i1 && (render.op.type==OP_None)) { + render.op.part_handler=Normal_SINGLE_8[index]; + scalew>>=1;gfx_scaleh/=2; + } else { + render.op.part_handler=Normal_DOUBLE_8[index]; + } + } else render.op.part_handler=Normal_SINGLE_8[index]; + width*=scalew; + double lines=0.0; + gfx_scaleh=(gfx_scaleh*render.src.height-(double)render.src.height)/(double)render.src.height; + height=0; + for (Bitu i=0;i0;lines--) SetAdvMameTable(height++,i,i,i); + SetAdvMameTable(height++,i+1,i,i-1); + break; + } + } + render.op.part_handler=AdvMame2x_8_Table[index]; + } + break; + } + render.op.gfx_mode=gfx_mode; render.op.width=width; render.op.height=height; - render.op.bpp=bpp; - render.op.pitch=pitch; - render.op.type=OP_Blit; - render.op.part_handler=GFX_Render_Blit; + GFX_SetSize(width,height,gfx_mode,gfx_scalew,gfx_scaleh,&RENDER_ReInit,RENDER_DrawScreen); RENDER_ResetPal(); + GFX_Start(); } -void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu flags,RENDER_Draw_Handler draw_handler) { +void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,double ratio,Bitu scalew,Bitu scaleh,RENDER_Draw_Handler draw_handler) { if ((!width) || (!height) || (!pitch)) { render.active=false;return; } @@ -315,67 +441,12 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu render.src.height=height; render.src.bpp=bpp; render.src.pitch=pitch; - render.src.ratio=ratio; - render.src.flags=flags; + render.src.ratio=render.aspect ? ratio : 1.0; + render.src.scalew=scalew; + render.src.scaleh=scaleh; render.src.draw_handler=draw_handler; + RENDER_ReInit(); - GFX_ModeCallBack mode_callback=0; - switch (render.op.want_type) { - - case OP_None: -normalop: - switch (render.src.flags) { - case DoubleNone: - flags=0; - break; - case DoubleWidth: - width*=2; - flags=GFX_SHADOW; - break; - case DoubleHeight: - height*=2; - flags=0; - break; - case DoubleBoth: - render.src.flags=0; - flags=0; - break; - } - mode_callback=Render_Normal_CallBack; - break; - case OP_Normal2x: - switch (render.src.flags) { - case DoubleBoth: - width*=2;height*=2; - flags=GFX_SHADOW; - mode_callback=Render_Normal_CallBack; - break; - default: - goto normalop; - } - break; - case OP_AdvMame2x: - switch (render.src.flags) { - case DoubleBoth: - mode_callback=Render_Scale2x_CallBack; - width*=2;height*=2; -#if defined (SCALE2X_MMX) - flags=GFX_SHADOW; -#else - flags=GFX_SHADOW; -#endif - break; - default: - goto normalop; - } - - break; - default: - goto normalop; - - } - GFX_SetSize(width,height,bpp,flags,mode_callback,RENDER_DrawScreen); - GFX_Start(); } extern void GFX_SetTitle(Bits cycles, Bits frameskip); @@ -396,6 +467,7 @@ void RENDER_Init(Section * sec) { render.pal.first=256; render.pal.last=0; + render.aspect=section->Get_bool("aspect"); render.frameskip.max=section->Get_int("frameskip"); render.frameskip.count=0; #if (C_SSHOT) diff --git a/src/gui/render_normal.h b/src/gui/render_normal.h index 32e131ab..860acac3 100644 --- a/src/gui/render_normal.h +++ b/src/gui/render_normal.h @@ -16,166 +16,49 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define LOOPSIZE 4 +static Bit8u normal_cache[RENDER_MAXWIDTH*2]; -#define SIZE_8 1 -#define SIZE_16 2 -#define SIZE_32 4 - -#define MAKE_8(FROM) Bit8u val=*(Bit8u *)(FROM); -#define MAKE_16(FROM) Bit16u val=render.pal.lookup.bpp16[*(Bit8u *)(FROM)]; -#define MAKE_32(FROM) Bit32u val=render.pal.lookup.bpp32[*(Bit8u *)(FROM)]; - -#define SAVE_8(WHERE) *(Bit8u *)(WHERE)=val; -#define SAVE_16(WHERE) *(Bit16u *)(WHERE)=val; -#define SAVE_32(WHERE) *(Bit32u *)(WHERE)=val; - -#define LINES_DN 1 -#define LINES_DW 1 -#define LINES_DH 2 -#define LINES_DB 2 - -#define PIXELS_DN 1 -#define PIXELS_DW 2 -#define PIXELS_DH 1 -#define PIXELS_DB 2 - -#define NORMAL_DN(BPP,FROM,DEST) \ - MAKE_ ## BPP(FROM); \ - SAVE_ ## BPP(DEST); \ - -#define NORMAL_DW(BPP,FROM,DEST) \ - MAKE_ ## BPP (FROM); \ - SAVE_ ## BPP (DEST); \ - SAVE_ ## BPP (DEST + SIZE_ ## BPP); \ - -#define NORMAL_DH(BPP,FROM,DEST) \ - MAKE_ ## BPP (FROM); \ - SAVE_ ## BPP (DEST); \ - SAVE_ ## BPP ((DEST) + render.op.pitch); \ - - -#define NORMAL_DB(BPP,FROM,DEST) \ - MAKE_ ## BPP (FROM); \ - SAVE_ ## BPP (DEST); \ - SAVE_ ## BPP ((DEST)+SIZE_ ## BPP ); \ - SAVE_ ## BPP ((DEST)+render.op.pitch ); \ - SAVE_ ## BPP ((DEST)+render.op.pitch+SIZE_ ## BPP ); \ - - -#define NORMAL_LOOP(COUNT,FUNC,BPP) \ - if (COUNT>0) {NORMAL_ ## FUNC (BPP,(src+0),(dest+0 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ - if (COUNT>1) {NORMAL_ ## FUNC (BPP,(src+1),(dest+1 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ - if (COUNT>2) {NORMAL_ ## FUNC (BPP,(src+2),(dest+2 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ - if (COUNT>3) {NORMAL_ ## FUNC (BPP,(src+3),(dest+3 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ - if (COUNT>4) {NORMAL_ ## FUNC (BPP,(src+4),(dest+4 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ - if (COUNT>5) {NORMAL_ ## FUNC (BPP,(src+5),(dest+5 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ - if (COUNT>6) {NORMAL_ ## FUNC (BPP,(src+6),(dest+6 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ - if (COUNT>7) {NORMAL_ ## FUNC (BPP,(src+7),(dest+7 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ - -#define MAKENORMAL(FUNC,BPP) \ -static void Normal_ ## FUNC ## _ ##BPP(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { \ - Bit8u * dest=(Bit8u *)render.op.pixels+y*LINES_ ## FUNC*render.op.pitch+x*PIXELS_ ## FUNC * SIZE_ ## BPP; \ - Bitu next_src=render.src.pitch-dx; \ - Bitu next_dest=(LINES_ ## FUNC*render.op.pitch) - (dx*PIXELS_ ## FUNC * SIZE_ ## BPP); \ - dx/=LOOPSIZE; \ - for (;dy>0;dy--) { \ - for (Bitu tempx=dx;tempx>0;tempx--) { \ - NORMAL_LOOP(LOOPSIZE,FUNC,BPP); \ - src+=LOOPSIZE;dest+=LOOPSIZE*PIXELS_ ## FUNC * SIZE_ ## BPP; \ - } \ - src+=next_src;dest+=next_dest; \ - } \ -} - -MAKENORMAL(DW,8); -MAKENORMAL(DB,8); - -MAKENORMAL(DN,16); -MAKENORMAL(DW,16); -MAKENORMAL(DH,16); -MAKENORMAL(DB,16); - -MAKENORMAL(DN,32); -MAKENORMAL(DW,32); -MAKENORMAL(DH,32); -MAKENORMAL(DB,32); - -/* Special versions for the 8-bit ones that can do direct line copying */ - -static void Normal_DN_8(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x; - Bitu next_src=render.src.pitch-dx; - Bitu next_dest=render.op.pitch-dx; - Bitu rem=dx&3;dx>>=2; - for (;dy>0;dy--) { - Bitu tempx; - for (tempx=dx;tempx>0;tempx--) { - Bit32u temp=*(Bit32u *)src;src+=4; - *(Bit32u *)dest=temp; - dest+=4; +template +static void Normal(Bit8u * src,Bitu x,Bitu y,Bitu _dx,Bitu _dy) { + Bit8u * dst=render.op.pixels+(render.normal.hindex[y]*render.op.pitch); + Bitu line_size=LineSize(_dx) * (xdouble ? 2 : 1); + src+=x; + Bit8u * line; + for (;_dy;_dy--) { + if (sbpp == dbpp && !xdouble) { + line=src; + BituMove(dst,line,line_size); + } else { + Bit8u * line_dst=&normal_cache[0]; + Bit8u * real_dst=dst; + line=line_dst; + Bit8u * temp_src=src; + for (Bitu tempx=_dx;tempx;tempx--) { + Bitu val=ConvBPP(LoadSrc(temp_src)); + AddDst(line_dst,val); + AddDst(real_dst,val); + if (xdouble) { + AddDst(line_dst,val); + AddDst(real_dst,val); + } + } } - for (tempx=rem;tempx>0;tempx--) { - *dest++=*src++; + dst+=render.op.pitch; + for (Bitu lines=render.normal.hlines[y++];lines;lines--) { + BituMove(dst,line,line_size); + dst+=render.op.pitch; } - src+=next_src;dest+=next_dest; + src+=render.src.pitch; } } -static void Normal_DH_8(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x; - Bitu next_src=render.src.pitch-dx; - Bitu next_dest=(2*render.op.pitch)-dx; - Bitu rem=dx&3;dx>>=2; - for (;dy>0;dy--) { - Bitu tempx; - for (tempx=dx;tempx>0;tempx--) { - Bit32u temp=*(Bit32u *)src;src+=4; - *(Bit32u *)dest=temp; - *(Bit32u *)(dest+render.op.pitch)=temp; - dest+=4; - } - for (tempx=rem;tempx>0;tempx--) { - *dest=*src; - *(dest+render.op.pitch)=*src; - dest++; - } - src+=next_src;dest+=next_dest; - } -} -static RENDER_Part_Handler Render_Normal_8_Table[4]= { - Normal_DN_8,Normal_DW_8,Normal_DH_8,Normal_DB_8, +RENDER_Part_Handler Normal_SINGLE_8[4]={ + Normal<8,8 ,false>,Normal<8,16,false>, + Normal<8,24,false>,Normal<8,32,false>, }; -static RENDER_Part_Handler Render_Normal_16_Table[4]= { - Normal_DN_16,Normal_DW_16,Normal_DH_16,Normal_DB_16, -}; - -static RENDER_Part_Handler Render_Normal_32_Table[4]= { - Normal_DN_32,Normal_DW_32,Normal_DH_32,Normal_DB_32, -}; - -static void Render_Normal_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags) { - if (!(flags & MODE_SET)) return; - render.op.width=width; - render.op.height=height; - render.op.bpp=bpp; - render.op.pitch=pitch; - render.op.type=OP_None; - switch (bpp) { - case 8: - render.op.part_handler=Render_Normal_8_Table[render.src.flags]; - break; - case 16: - render.op.part_handler=Render_Normal_16_Table[render.src.flags]; - break; - case 32: - render.op.part_handler=Render_Normal_32_Table[render.src.flags]; - break; - default: - E_Exit("RENDER:Unsupported display depth of %d",bpp); - break; - } - RENDER_ResetPal(); -} +RENDER_Part_Handler Normal_DOUBLE_8[4]={ + Normal<8,8 ,true>,Normal<8,16,true>, + Normal<8,24,true>,Normal<8,32,true>, +}; \ No newline at end of file diff --git a/src/gui/render_scale2x.h b/src/gui/render_scale2x.h index 979b9dc9..c48ddc19 100644 --- a/src/gui/render_scale2x.h +++ b/src/gui/render_scale2x.h @@ -29,531 +29,49 @@ */ /* - * This file contains a C and MMX implentation of the Scale2x effect. - * - * You can found an high level description of the effect at : - * + * This algorithm was based on the scale2x/advmame2x effect. * http://scale2x.sourceforge.net/scale2x.html - * - * Alternatively at the previous license terms, you are allowed to use this - * code in your program with these conditions: - * - the program is not used in commercial activities. - * - the whole source code of the program is released with the binary. - * - derivative works of the program are allowed. - */ - -/* - * Made some changes to only support the 8-bit version. - * Also added mulitple destination bpp targets. */ #ifndef __SCALE2X_H #define __SCALE2X_H -#include - -/***************************************************************************/ -/* basic types */ - -typedef Bit8u scale2x_uint8; -typedef Bit16u scale2x_uint16; -typedef Bit32u scale2x_uint32; - -static void scale2x_line_8(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count) -{ - assert(count >= 2); - - /* first pixel */ - dst0[0] = src1[0]; - dst1[0] = src1[0]; - if (src1[1] == src0[0] && src2[0] != src0[0]) - dst0[1] = src0[0]; - else - dst0[1] = src1[0]; - if (src1[1] == src2[0] && src0[0] != src2[0]) - dst1[1] = src2[0]; - else - dst1[1] = src1[0]; - ++src0; - ++src1; - ++src2; - dst0 += 2; - dst1 += 2; - +template +static void AdvMame2x_line(Bit8u * dst, const Bit8u * src0, const Bit8u * src1, const Bit8u * src2, Bitu count) { + AddDst(dst,ConvBPP(src1[0])); + AddDst(dst,ConvBPP((src1[1] == src0[0] && src2[0] != src0[0]) ? src0[0] : src1[0])); + src0++;src1++;src2++;count-=2; /* central pixels */ - count -= 2; while (count) { - if (src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0]) - dst0[0] = src0[0]; - else - dst0[0] = src1[0]; - if (src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0]) - dst0[1] = src0[0]; - else - dst0[1] = src1[0]; - - if (src1[-1] == src2[0] && src0[0] != src2[0] && src1[1] != src2[0]) - dst1[0] = src2[0]; - else - dst1[0] = src1[0]; - if (src1[1] == src2[0] && src0[0] != src2[0] && src1[-1] != src2[0]) - dst1[1] = src2[0]; - else - dst1[1] = src1[0]; - - ++src0; - ++src1; - ++src2; - dst0 += 2; - dst1 += 2; - --count; + AddDst(dst,ConvBPP((src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0]) ? src0[0] : src1[0])); + AddDst(dst,ConvBPP((src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0]) ? src0[0] : src1[0])); + src0++;src1++;src2++;count--; } - /* last pixel */ - if (src1[-1] == src0[0] && src2[0] != src0[0]) - dst0[0] = src0[0]; - else - dst0[0] = src1[0]; - if (src1[-1] == src2[0] && src0[0] != src2[0]) - dst1[0] = src2[0]; - else - dst1[0] = src1[0]; - dst0[1] = src1[0]; - dst1[1] = src1[0]; + AddDst(dst,ConvBPP((src1[-1] == src0[0] && src2[0] != src0[0]) ? src0[0] : src1[0])); + AddDst(dst,ConvBPP(src1[0])); } -static void scale2x_line_16(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count) -{ - assert(count >= 2); - - /* first pixel */ - dst0[0] = render.pal.lookup.bpp16[src1[0]]; - dst1[0] = render.pal.lookup.bpp16[src1[0]]; - if (src1[1] == src0[0] && src2[0] != src0[0]) - dst0[1] = render.pal.lookup.bpp16[src0[0]]; - else - dst0[1] = render.pal.lookup.bpp16[src1[0]]; - if (src1[1] == src2[0] && src0[0] != src2[0]) - dst1[1] = render.pal.lookup.bpp16[src2[0]]; - else - dst1[1] = render.pal.lookup.bpp16[src1[0]]; - ++src0; - ++src1; - ++src2; - dst0 += 2; - dst1 += 2; - - /* central pixels */ - count -= 2; - while (count) { - if (src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0]) - dst0[0] = render.pal.lookup.bpp16[src0[0]]; - else - dst0[0] = render.pal.lookup.bpp16[src1[0]]; - if (src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0]) - dst0[1] = render.pal.lookup.bpp16[src0[0]]; - else - dst0[1] = render.pal.lookup.bpp16[src1[0]]; - - if (src1[-1] == src2[0] && src0[0] != src2[0] && src1[1] != src2[0]) - dst1[0] = render.pal.lookup.bpp16[src2[0]]; - else - dst1[0] = render.pal.lookup.bpp16[src1[0]]; - if (src1[1] == src2[0] && src0[0] != src2[0] && src1[-1] != src2[0]) - dst1[1] = render.pal.lookup.bpp16[src2[0]]; - else - dst1[1] = render.pal.lookup.bpp16[src1[0]]; - - ++src0; - ++src1; - ++src2; - dst0 += 2; - dst1 += 2; - --count; +template +static void AdvMame2x(Bit8u * src,Bitu x,Bitu y,Bitu _dx,Bitu _dy) { + _dy=render.advmame2x.hindex[y+_dy]; + y=render.advmame2x.hindex[y]; + Bit8u * dest=render.op.pixels+render.op.pitch*y; + src-=render.advmame2x.line_starts[y][0]; + src+=x; + for (;y<_dy;y++) { + Bit8u * src0=src+render.advmame2x.line_starts[y][0]; + Bit8u * src1=src+render.advmame2x.line_starts[y][1]; + Bit8u * src2=src+render.advmame2x.line_starts[y][2]; + AdvMame2x_line(dest,src0,src1,src2,_dx); + dest+=render.op.pitch; } - - /* last pixel */ - if (src1[-1] == src0[0] && src2[0] != src0[0]) - dst0[0] = render.pal.lookup.bpp16[src0[0]]; - else - dst0[0] = render.pal.lookup.bpp16[src1[0]]; - if (src1[-1] == src2[0] && src0[0] != src2[0]) - dst1[0] = render.pal.lookup.bpp16[src2[0]]; - else - dst1[0] = render.pal.lookup.bpp16[src1[0]]; - dst0[1] = render.pal.lookup.bpp16[src1[0]]; - dst1[1] = render.pal.lookup.bpp16[src1[0]]; } -static void scale2x_line_32(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count) -{ - assert(count >= 2); - /* first pixel */ - dst0[0] = render.pal.lookup.bpp32[src1[0]]; - dst1[0] = render.pal.lookup.bpp32[src1[0]]; - if (src1[1] == src0[0] && src2[0] != src0[0]) - dst0[1] = render.pal.lookup.bpp32[src0[0]]; - else - dst0[1] = render.pal.lookup.bpp32[src1[0]]; - if (src1[1] == src2[0] && src0[0] != src2[0]) - dst1[1] = render.pal.lookup.bpp32[src2[0]]; - else - dst1[1] = render.pal.lookup.bpp32[src1[0]]; - ++src0; - ++src1; - ++src2; - dst0 += 2; - dst1 += 2; +RENDER_Part_Handler AdvMame2x_8_Table[4]={ + AdvMame2x<8,8>,AdvMame2x<8,16>,AdvMame2x<8,24>,AdvMame2x<8,32> +}; - /* central pixels */ - count -= 2; - while (count) { - if (src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0]) - dst0[0] = render.pal.lookup.bpp32[src0[0]]; - else - dst0[0] = render.pal.lookup.bpp32[src1[0]]; - if (src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0]) - dst0[1] = render.pal.lookup.bpp32[src0[0]]; - else - dst0[1] = render.pal.lookup.bpp32[src1[0]]; - - if (src1[-1] == src2[0] && src0[0] != src2[0] && src1[1] != src2[0]) - dst1[0] = render.pal.lookup.bpp32[src2[0]]; - else - dst1[0] = render.pal.lookup.bpp32[src1[0]]; - if (src1[1] == src2[0] && src0[0] != src2[0] && src1[-1] != src2[0]) - dst1[1] = render.pal.lookup.bpp32[src2[0]]; - else - dst1[1] = render.pal.lookup.bpp32[src1[0]]; - - ++src0; - ++src1; - ++src2; - dst0 += 2; - dst1 += 2; - --count; - } - - /* last pixel */ - if (src1[-1] == src0[0] && src2[0] != src0[0]) - dst0[0] = render.pal.lookup.bpp32[src0[0]]; - else - dst0[0] = render.pal.lookup.bpp32[src1[0]]; - if (src1[-1] == src2[0] && src0[0] != src2[0]) - dst1[0] = render.pal.lookup.bpp32[src2[0]]; - else - dst1[0] = render.pal.lookup.bpp32[src1[0]]; - dst0[1] = render.pal.lookup.bpp32[src1[0]]; - dst1[1] = render.pal.lookup.bpp32[src1[0]]; -} - -static void Scale2x_8(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - if (dy<3) return; - Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch; - /* First line */ - scale2x_line_8(dest,dest+render.op.pitch,src,src,src+render.src.pitch,dx); - dest+=render.op.pitch*2; - src+=render.src.pitch; - dy-=2; - /* Middle part */ - for (;dy>0;dy--) { - scale2x_line_8((Bit8u *)dest,(Bit8u *)(dest+render.op.pitch),src-render.src.pitch,src,src+render.src.pitch,dx); - dest+=render.op.pitch*2; - src+=render.src.pitch; - } - /* Last Line */ - scale2x_line_8((Bit8u *)dest,(Bit8u *)(dest+render.op.pitch),src-render.src.pitch,src,src,dx); -} - -static void Scale2x_16(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - if (dy<3) return; - Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch; - /* First line */ - scale2x_line_16((Bit16u *)dest,(Bit16u *)(dest+render.op.pitch),src,src,src+render.src.pitch,dx); - dest+=render.op.pitch*2; - src+=render.src.pitch; - dy-=2; - /* Middle part */ - for (;dy>0;dy--) { - scale2x_line_16((Bit16u *)dest,(Bit16u *)(dest+render.op.pitch),src-render.src.pitch,src,src+render.src.pitch,dx); - dest+=render.op.pitch*2; - src+=render.src.pitch; - } - /* Last Line */ - scale2x_line_16((Bit16u *)dest,(Bit16u *)(dest+render.op.pitch),src-render.src.pitch,src,src,dx); -} - -static void Scale2x_32(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - if (dy<3) return; - Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch; - /* First line */ - scale2x_line_32((Bit32u *)dest,(Bit32u *)(dest+render.op.pitch),src,src,src+render.src.pitch,dx); - dest+=render.op.pitch*2; - src+=render.src.pitch; - dy-=2; - /* Middle part */ - for (;dy>0;dy--) { - scale2x_line_32((Bit32u *)dest,(Bit32u *)(dest+render.op.pitch),src-render.src.pitch,src,src+render.src.pitch,dx); - dest+=render.op.pitch*2; - src+=render.src.pitch; - } - /* Last Line */ - scale2x_line_32((Bit32u *)dest,(Bit32u *)(dest+render.op.pitch),src-render.src.pitch,src,src,dx); -} - -#if defined(__GNUC__) && defined(__i386__) - -#define SCALE2X_MMX 1 - -static __inline__ void scale2x_8_mmx_single(scale2x_uint8* dst, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count) -{ - assert(count >= 16); - assert(count % 8 == 0); - - /* always do the first and last run */ - count -= 2*8; - - __asm__ __volatile__( -/* first run */ - /* set the current, current_pre, current_next registers */ - "movq 0(%1),%%mm0\n" - "movq 0(%1),%%mm7\n" - "movq 8(%1),%%mm1\n" - "psllq $56,%%mm0\n" - "psllq $56,%%mm1\n" - "psrlq $56,%%mm0\n" - "movq %%mm7,%%mm2\n" - "movq %%mm7,%%mm3\n" - "psllq $8,%%mm2\n" - "psrlq $8,%%mm3\n" - "por %%mm2,%%mm0\n" - "por %%mm3,%%mm1\n" - - /* current_upper */ - "movq (%0),%%mm6\n" - - /* compute the upper-left pixel for dst on %%mm2 */ - /* compute the upper-right pixel for dst on %%mm4 */ - "movq %%mm0,%%mm2\n" - "movq %%mm1,%%mm4\n" - "movq %%mm0,%%mm3\n" - "movq %%mm1,%%mm5\n" - "pcmpeqb %%mm6,%%mm2\n" - "pcmpeqb %%mm6,%%mm4\n" - "pcmpeqb (%2),%%mm3\n" - "pcmpeqb (%2),%%mm5\n" - "pandn %%mm2,%%mm3\n" - "pandn %%mm4,%%mm5\n" - "movq %%mm0,%%mm2\n" - "movq %%mm1,%%mm4\n" - "pcmpeqb %%mm1,%%mm2\n" - "pcmpeqb %%mm0,%%mm4\n" - "pandn %%mm3,%%mm2\n" - "pandn %%mm5,%%mm4\n" - "movq %%mm2,%%mm3\n" - "movq %%mm4,%%mm5\n" - "pand %%mm6,%%mm2\n" - "pand %%mm6,%%mm4\n" - "pandn %%mm7,%%mm3\n" - "pandn %%mm7,%%mm5\n" - "por %%mm3,%%mm2\n" - "por %%mm5,%%mm4\n" - - /* set *dst */ - "movq %%mm2,%%mm3\n" - "punpcklbw %%mm4,%%mm2\n" - "punpckhbw %%mm4,%%mm3\n" - "movq %%mm2,(%3)\n" - "movq %%mm3,8(%3)\n" - - /* next */ - "addl $8,%0\n" - "addl $8,%1\n" - "addl $8,%2\n" - "addl $16,%3\n" - -/* central runs */ - "shrl $3,%4\n" - "jz 1f\n" - - "0:\n" - - /* set the current, current_pre, current_next registers */ - "movq -8(%1),%%mm0\n" - "movq (%1),%%mm7\n" - "movq 8(%1),%%mm1\n" - "psrlq $56,%%mm0\n" - "psllq $56,%%mm1\n" - "movq %%mm7,%%mm2\n" - "movq %%mm7,%%mm3\n" - "psllq $8,%%mm2\n" - "psrlq $8,%%mm3\n" - "por %%mm2,%%mm0\n" - "por %%mm3,%%mm1\n" - - /* current_upper */ - "movq (%0),%%mm6\n" - - /* compute the upper-left pixel for dst on %%mm2 */ - /* compute the upper-right pixel for dst on %%mm4 */ - "movq %%mm0,%%mm2\n" - "movq %%mm1,%%mm4\n" - "movq %%mm0,%%mm3\n" - "movq %%mm1,%%mm5\n" - "pcmpeqb %%mm6,%%mm2\n" - "pcmpeqb %%mm6,%%mm4\n" - "pcmpeqb (%2),%%mm3\n" - "pcmpeqb (%2),%%mm5\n" - "pandn %%mm2,%%mm3\n" - "pandn %%mm4,%%mm5\n" - "movq %%mm0,%%mm2\n" - "movq %%mm1,%%mm4\n" - "pcmpeqb %%mm1,%%mm2\n" - "pcmpeqb %%mm0,%%mm4\n" - "pandn %%mm3,%%mm2\n" - "pandn %%mm5,%%mm4\n" - "movq %%mm2,%%mm3\n" - "movq %%mm4,%%mm5\n" - "pand %%mm6,%%mm2\n" - "pand %%mm6,%%mm4\n" - "pandn %%mm7,%%mm3\n" - "pandn %%mm7,%%mm5\n" - "por %%mm3,%%mm2\n" - "por %%mm5,%%mm4\n" - - /* set *dst */ - "movq %%mm2,%%mm3\n" - "punpcklbw %%mm4,%%mm2\n" - "punpckhbw %%mm4,%%mm3\n" - "movq %%mm2,(%3)\n" - "movq %%mm3,8(%3)\n" - - /* next */ - "addl $8,%0\n" - "addl $8,%1\n" - "addl $8,%2\n" - "addl $16,%3\n" - - "decl %4\n" - "jnz 0b\n" - "1:\n" - -/* final run */ - /* set the current, current_pre, current_next registers */ - "movq (%1),%%mm1\n" - "movq (%1),%%mm7\n" - "movq -8(%1),%%mm0\n" - "psrlq $56,%%mm1\n" - "psrlq $56,%%mm0\n" - "psllq $56,%%mm1\n" - "movq %%mm7,%%mm2\n" - "movq %%mm7,%%mm3\n" - "psllq $8,%%mm2\n" - "psrlq $8,%%mm3\n" - "por %%mm2,%%mm0\n" - "por %%mm3,%%mm1\n" - - /* current_upper */ - "movq (%0),%%mm6\n" - - /* compute the upper-left pixel for dst on %%mm2 */ - /* compute the upper-right pixel for dst on %%mm4 */ - "movq %%mm0,%%mm2\n" - "movq %%mm1,%%mm4\n" - "movq %%mm0,%%mm3\n" - "movq %%mm1,%%mm5\n" - "pcmpeqb %%mm6,%%mm2\n" - "pcmpeqb %%mm6,%%mm4\n" - "pcmpeqb (%2),%%mm3\n" - "pcmpeqb (%2),%%mm5\n" - "pandn %%mm2,%%mm3\n" - "pandn %%mm4,%%mm5\n" - "movq %%mm0,%%mm2\n" - "movq %%mm1,%%mm4\n" - "pcmpeqb %%mm1,%%mm2\n" - "pcmpeqb %%mm0,%%mm4\n" - "pandn %%mm3,%%mm2\n" - "pandn %%mm5,%%mm4\n" - "movq %%mm2,%%mm3\n" - "movq %%mm4,%%mm5\n" - "pand %%mm6,%%mm2\n" - "pand %%mm6,%%mm4\n" - "pandn %%mm7,%%mm3\n" - "pandn %%mm7,%%mm5\n" - "por %%mm3,%%mm2\n" - "por %%mm5,%%mm4\n" - - /* set *dst */ - "movq %%mm2,%%mm3\n" - "punpcklbw %%mm4,%%mm2\n" - "punpckhbw %%mm4,%%mm3\n" - "movq %%mm2,(%3)\n" - "movq %%mm3,8(%3)\n" - - "emms" - - : "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count) - : - : "cc" - ); -} - -static void scale2x_line_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count) -{ - assert(count >= 16); - assert(count % 8 == 0); - - scale2x_8_mmx_single(dst0, src0, src1, src2, count); - scale2x_8_mmx_single(dst1, src2, src1, src0, count); -} - -static void Scale2x_8_mmx(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - if (dy<3) return; - Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch; - /* First line */ - scale2x_line_8_mmx(dest,dest+render.op.pitch,src,src,src+render.src.pitch,dx); - dest+=render.op.pitch*2; - src+=render.src.pitch; - dy-=2; - /* Middle part */ - for (;dy>0;dy--) { - scale2x_line_8_mmx((Bit8u *)dest,(Bit8u *)(dest+render.op.pitch),src-render.src.pitch,src,src+render.src.pitch,dx); - dest+=render.op.pitch*2; - src+=render.src.pitch; - } - /* Last Line */ - scale2x_line_8_mmx((Bit8u *)dest,(Bit8u *)(dest+render.op.pitch),src-render.src.pitch,src,src,dx); -} - -#endif - -static void Render_Scale2x_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags) { - if (!(flags & MODE_SET)) return; - render.op.width=width; - render.op.height=height; - render.op.bpp=bpp; - render.op.pitch=pitch; - render.op.type=OP_AdvMame2x; - switch (bpp) { - case 8: -#if defined(SCALE2X_MMX) - render.op.part_handler=Scale2x_8_mmx; -#else - render.op.part_handler=Scale2x_8; -#endif - break; - case 16: - render.op.part_handler=Scale2x_16;; - break; - case 32: - render.op.part_handler=Scale2x_32; - break; - default: - E_Exit("RENDER:Unsupported display depth of %d",bpp); - break; - } - RENDER_ResetPal(); -} #endif diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h new file mode 100644 index 00000000..3d903609 --- /dev/null +++ b/src/gui/render_templates.h @@ -0,0 +1,53 @@ +template +static INLINE void AddDst(Bit8u * & dst,Bitu val) { + switch (dbpp) { + case 8: *(Bit8u*)dst=val;dst+=1;break; + case 16:*(Bit16u*)dst=val;dst+=2;break; + case 24:*(Bit32u*)dst=val;dst+=3;break; + case 32:*(Bit32u*)dst=val;dst+=4;break; + } +} + +template +static INLINE Bitu LineSize(Bitu pixels) { + switch (bpp) { + case 8:return pixels; + case 16:return pixels*2; + case 24:return pixels*3; + case 32:return pixels*4; + } + return 0; +} + +static INLINE void BituMove(Bit8u * dst,Bit8u * src,Bitu pixels) { + pixels/=sizeof(Bitu); + while (pixels--) { + *(Bitu*)dst=*(Bitu*)src; + src+=sizeof(Bitu); + dst+=sizeof(Bitu); + } +} + +template +static INLINE Bitu LoadSrc(Bit8u * & src) { + Bitu val; + switch (sbpp) { + case 8:val=*(Bit8u *) src;src+=1;break; + case 16:val=*(Bit16u *) src;src+=2;break; + case 24:val=(*(Bit32u *)src)&0xffffff;src+=3;break; + case 32:val=*(Bit32u *)src;src+=4;break; + } + return val; +} + + +template +static INLINE Bitu ConvBPP(Bitu val) { + if (sbpp==8) switch (dbpp) { + case 8:return val; + case 16:return render.pal.lookup.bpp16[val]; + case 24:return render.pal.lookup.bpp32[val]; + case 32:return render.pal.lookup.bpp32[val]; + } + return 0; +} From b4dcb24e355c8e968b3ab2140cc6342f120d5bd8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 8 Nov 2003 09:59:10 +0000 Subject: [PATCH 1331/4131] Enabling aspect correction option for config file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1412 --- src/dosbox.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 443cd350..22903502 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -210,10 +210,12 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("render",&RENDER_Init); secprop->Add_int("frameskip",0); secprop->Add_string("snapdir","snaps"); + secprop->Add_bool("aspect",true); secprop->Add_string("scaler","normal2x"); MSG_Add("RENDER_CONFIGFILE_HELP", "frameskip -- How many frames dosbox skips before drawing one.\n" "snapdir -- Directory where screenshots get saved.\n" + "aspect -- Do aspect correction.\n" "scaler -- Scaler used to enlarge/enhance low resolution modes.\n" " Supported are none,normal2x,advmame2x\n" ); From 433ec14aca442090768721056d04314d6b4a5146 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 8 Nov 2003 10:10:03 +0000 Subject: [PATCH 1332/4131] Added hardware overlay support with hardware scaling Added fixed fullscreen resolutions for you LCD freaks Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1413 --- include/video.h | 29 +++-- src/gui/sdlmain.cpp | 284 ++++++++++++++++++++++++++++++-------------- 2 files changed, 209 insertions(+), 104 deletions(-) diff --git a/include/video.h b/include/video.h index 33997cc9..32befb71 100644 --- a/include/video.h +++ b/include/video.h @@ -20,9 +20,19 @@ #define __VIDEO_H -typedef void (* GFX_ModeCallBack)(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags); +enum GFX_MODES { + GFX_8BPP=0, + GFX_15BPP=1, + GFX_16BPP=2, + GFX_24BPP=3, + GFX_32BPP=4, + GFX_YUV=5, + GFX_MODE_SIZE=6 +}; -typedef void (* GFX_DrawCallBack)(void * data); +typedef void (* GFX_ResetCallBack)(void); + +typedef void (* GFX_RenderCallBack)(Bit8u * data,Bitu pitch); struct GFX_PalEntry { Bit8u r; @@ -31,22 +41,15 @@ struct GFX_PalEntry { Bit8u unused; }; -#define GFX_FIXED_BPP 0x01 -#define GFX_RESIZEABLE 0x02 -#define GFX_SHADOW 0x04 -#define GFX_BLITTING 0x08 - - - -#define MODE_SET 0x01 -#define MODE_FULLSCREEN 0x02 -#define MODE_RESIZE 0x04 +#define GFX_HASSCALING 0x0001 +#define GFX_HASCONVERT 0x0002 void GFX_Events(void); void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries); +GFX_MODES GFX_GetBestMode(Bitu bpp,Bitu & gfx_flags); Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue); -void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu flags,GFX_ModeCallBack mode_callback, GFX_DrawCallBack draw_callback); +void GFX_SetSize(Bitu width,Bitu height,GFX_MODES gfx_mode,double scalex,double scaley,GFX_ResetCallBack cb_reset, GFX_RenderCallBack cb_render); void GFX_Start(void); void GFX_Stop(void); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index acb2ae78..44c1b0ec 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.52 2003-10-30 09:08:58 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.53 2003-11-08 10:09:52 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -42,7 +42,7 @@ #include "debug.h" //#define DISABLE_JOYSTICK -#define C_GFXTHREADED 0 //Enabled by default +#define C_GFXTHREADED 1 //Enabled by default #if !(ENVIRON_INCLUDED) extern char** environ; @@ -58,18 +58,37 @@ extern char** environ; #define STDERR_FILE TEXT("stderr.txt") #endif +enum SCREEN_TYPES { + SCREEN_SURFACE, + SCREEN_OVERLAY, + SCREEN_OPENGL +}; + + struct SDL_Block { volatile bool active; //If this isn't set don't draw volatile bool drawing; - Bitu width; - Bitu height; - Bitu bpp; - Bitu flags; - GFX_ModeCallBack mode_callback; - bool full_screen; + struct { + Bit32u width; + Bit32u height; + GFX_MODES gfx_mode; + double scalex,scaley; + struct { + GFX_ResetCallBack reset; + GFX_RenderCallBack render; + } cb; + } draw; bool wait_on_error; + struct { + Bit32u width,height,bpp; + bool fixed; + bool fullscreen; + bool doublebuf; + SCREEN_TYPES type; + } desktop; + SDL_Rect clip; SDL_Surface * surface; - SDL_Surface * blit_surface; + SDL_Overlay * overlay; SDL_Joystick * joy; SDL_cond *cond; #if C_GFXTHREADED @@ -78,7 +97,7 @@ struct SDL_Block { SDL_sem *sem; volatile bool kill_thread; #endif - GFX_DrawCallBack draw_callback; + struct { bool autolock; bool autoenable; @@ -102,54 +121,114 @@ void GFX_SetTitle(Bits cycles,Bits frameskip){ } /* Reset the screen with current values in the sdl structure */ -static void ResetScreen(void) { - GFX_Stop(); - Bit32u mode_flags=0; - if (sdl.full_screen) { - mode_flags|=SDL_FULLSCREEN; - if (sdl.bpp==8) mode_flags|=SDL_HWPALETTE; - if (sdl.flags & GFX_SHADOW) { - mode_flags|=SDL_SWSURFACE; +GFX_MODES GFX_GetBestMode(Bitu bpp,Bitu & gfx_flags) { + GFX_MODES gfx_mode;gfx_flags=0; + switch (sdl.desktop.type) { + case SCREEN_SURFACE: + Bitu what_bpp; + if (sdl.desktop.fullscreen) { + what_bpp=SDL_VideoModeOK(640,480,bpp,SDL_FULLSCREEN|SDL_HWSURFACE | + (sdl.desktop.doublebuf ? SDL_DOUBLEBUF : 0) | ((bpp==8) ? SDL_HWPALETTE : 0) ); } else { - mode_flags|=SDL_HWSURFACE|SDL_DOUBLEBUF; + what_bpp=sdl.desktop.bpp; } - } else mode_flags|=SDL_SWSURFACE; - if (sdl.flags & GFX_FIXED_BPP) { - dofixed: - sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,mode_flags); - } else { - Bitu test_bpp=SDL_VideoModeOK(sdl.width,sdl.height,sdl.bpp,mode_flags); - if (test_bpp==sdl.bpp) goto dofixed; - sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,0,mode_flags); - if (sdl.surface->format->BitsPerPixel==24) goto dofixed; - + gfx_flags|=GFX_HASCONVERT; + switch (what_bpp) { + case 8: gfx_mode=GFX_8BPP;break; + case 15: gfx_mode=GFX_15BPP;break; + case 16: gfx_mode=GFX_16BPP;break; + case 24: gfx_mode=GFX_24BPP;break; + case 32: gfx_mode=GFX_32BPP;break; + } + break; + case SCREEN_OVERLAY: + gfx_mode=GFX_YUV; + gfx_flags|=GFX_HASSCALING; } - if (sdl.surface==0) { - E_Exit("SDL:Can't get a surface error:%s.",SDL_GetError()); - } - /* Create special surface for direct blitting if needed */ - if (sdl.blit_surface) SDL_FreeSurface(sdl.blit_surface); - sdl.blit_surface=SDL_CreateRGBSurfaceFrom(0,0,0,sdl.surface->format->BytesPerPixel,0, - sdl.surface->format->Rmask,sdl.surface->format->Gmask,sdl.surface->format->Bmask,sdl.surface->format->Amask - ); - - GFX_SetTitle(-1,-1); - Bitu flags=MODE_SET; - if (sdl.full_screen) flags|=MODE_FULLSCREEN; - if (sdl.mode_callback) sdl.mode_callback(sdl.surface->w,sdl.surface->h,sdl.surface->format->BitsPerPixel,sdl.surface->pitch,flags); - GFX_Start(); + return gfx_mode; } -void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu flags,GFX_ModeCallBack mode_callback, GFX_DrawCallBack draw_callback){ +static void ResetScreen(void) { GFX_Stop(); - sdl.width=width; - sdl.height=height; - sdl.bpp=bpp; - sdl.flags=flags; - sdl.mode_callback=mode_callback; - sdl.draw_callback=draw_callback; - ResetScreen(); + if (sdl.draw.cb.reset) (sdl.draw.cb.reset)(); + GFX_Start(); +} + +void GFX_SetSize(Bitu width,Bitu height,GFX_MODES gfx_mode,double scalex,double scaley,GFX_ResetCallBack cb_reset, GFX_RenderCallBack cb_render) { + GFX_Stop(); + sdl.draw.width=width; + sdl.draw.height=height; + sdl.draw.gfx_mode=gfx_mode; + sdl.draw.cb.render=cb_render; + sdl.draw.cb.reset=cb_reset; + sdl.draw.scalex=scalex; + sdl.draw.scaley=scaley; + + Bitu bpp; + switch (gfx_mode) { + case GFX_8BPP:bpp=8;break; + case GFX_15BPP:bpp=15;break; + case GFX_16BPP:bpp=16;break; + case GFX_24BPP:bpp=24;break; + case GFX_32BPP:bpp=32;break; + case GFX_YUV:bpp=0;break; + } + switch (sdl.desktop.type) { + case SCREEN_SURFACE: +dosurface: + sdl.clip.w=width; + sdl.clip.h=height; + if (sdl.desktop.fullscreen) { + if (sdl.desktop.fixed) { + sdl.clip.x=(Sint16)((sdl.desktop.width-width)/2); + sdl.clip.y=(Sint16)((sdl.desktop.height-height)/2); + sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,bpp, + SDL_FULLSCREEN|SDL_HWSURFACE|(sdl.desktop.doublebuf ? SDL_DOUBLEBUF : 0)|SDL_HWPALETTE); + } else { + sdl.clip.x=0;sdl.clip.y=0; + sdl.surface=SDL_SetVideoMode(width,height,bpp, + SDL_FULLSCREEN|SDL_HWSURFACE|(sdl.desktop.doublebuf ? SDL_DOUBLEBUF : 0)|SDL_HWPALETTE); + } + } else { + sdl.clip.x=0;sdl.clip.y=0; + sdl.surface=SDL_SetVideoMode(width,height,bpp,SDL_HWSURFACE); + } + break; + case SCREEN_OVERLAY: + if (sdl.overlay) SDL_FreeYUVOverlay(sdl.overlay); + sdl.overlay=0; + if (gfx_mode!=GFX_YUV) goto dosurface; + if (sdl.desktop.fullscreen) { + if (sdl.desktop.fixed) { + double ratio_w=(double)sdl.desktop.width/(width*scalex); + double ratio_h=(double)sdl.desktop.height/(height*scaley); + if ( ratio_w < ratio_h) { + sdl.clip.w=(Bit16u)sdl.desktop.width; + sdl.clip.h=(Bit16u)(height*scaley*ratio_w); + } else { + sdl.clip.w=(Bit16u)(width*scalex*ratio_h); + sdl.clip.h=(Bit16u)sdl.desktop.height; + } + sdl.clip.x=(Sint16)((sdl.desktop.width-sdl.clip.w)/2); + sdl.clip.y=(Sint16)((sdl.desktop.height-sdl.clip.h)/2); + sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,bpp,SDL_FULLSCREEN|SDL_HWSURFACE); + } else { + sdl.clip.x=0;sdl.clip.y=0; + sdl.clip.w=(Bit16u)(width*scalex); + sdl.clip.h=(Bit16u)(height*scaley); + sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,SDL_FULLSCREEN|SDL_HWSURFACE); + } + } else { + sdl.clip.x=0;sdl.clip.y=0; + sdl.clip.w=(Bit16u)(width*scalex); + sdl.clip.h=(Bit16u)(height*scaley); + sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,SDL_HWSURFACE); + } + sdl.overlay=SDL_CreateYUVOverlay(width*2,height,SDL_UYVY_OVERLAY,sdl.surface); + break; + } + GFX_Start(); } @@ -165,8 +244,8 @@ static void CaptureMouse(void) { } static void SwitchFullScreen(void) { - sdl.full_screen=!sdl.full_screen; - if (sdl.full_screen) { + sdl.desktop.fullscreen=!sdl.desktop.fullscreen; + if (sdl.desktop.fullscreen) { //TODO Give an resize event if (!sdl.mouse.locked) CaptureMouse(); } else { @@ -179,33 +258,38 @@ void GFX_SwitchFullScreen(void) { SwitchFullScreen(); } -/* Special render part handler that blits directly to the output screen */ -void GFX_Render_Blit(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - sdl.blit_surface->w=dx; - sdl.blit_surface->h=dy; - sdl.blit_surface->pitch=dx; - sdl.blit_surface->pixels=src; - SDL_UnlockSurface(sdl.surface); - SDL_Rect dest; - dest.x=x; - dest.y=y; - SDL_BlitSurface(sdl.blit_surface,0,sdl.surface,&dest); -} static void SDL_DrawScreen(void) { - sdl.drawing=true; + Bit8u * pixels;Bitu pitch; + sdl.drawing=true; + switch (sdl.desktop.type) { + case SCREEN_SURFACE: if (SDL_MUSTLOCK(sdl.surface)) { if (SDL_LockSurface(sdl.surface)) { + LOG_MSG("SDL Lock failed"); sdl.drawing=false; return; } } - sdl.draw_callback(sdl.surface->pixels); + pixels=(Bit8u *)sdl.surface->pixels; + pixels+=sdl.clip.y*sdl.surface->pitch; + pixels+=sdl.clip.x*sdl.surface->format->BytesPerPixel; + sdl.draw.cb.render(pixels,sdl.surface->pitch); if (SDL_MUSTLOCK(sdl.surface)) { SDL_UnlockSurface(sdl.surface); } SDL_Flip(sdl.surface); - sdl.drawing=false; + break; + case SCREEN_OVERLAY: + SDL_LockYUVOverlay(sdl.overlay); + pixels=(Bit8u *)*(sdl.overlay->pixels); + pitch=*(sdl.overlay->pitches); + sdl.draw.cb.render(pixels,pitch); + SDL_UnlockYUVOverlay(sdl.overlay); + SDL_DisplayYUVOverlay(sdl.overlay,&sdl.clip); + + } + sdl.drawing=false; } #if C_GFXTHREADED @@ -242,7 +326,7 @@ void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries) { }; #endif /* I should probably not change the GFX_PalEntry :) */ - if (sdl.full_screen) { + if (sdl.surface->flags & SDL_HWPALETTE) { if (!SDL_SetPalette(sdl.surface,SDL_PHYSPAL,(SDL_Color *)entries,start,count)) { E_Exit("SDL:Can't set palette"); } @@ -280,7 +364,7 @@ void GFX_Start() { static void GUI_ShutDown(Section * sec) { GFX_Stop(); if (sdl.mouse.locked) CaptureMouse(); - if (sdl.full_screen) SwitchFullScreen(); + if (sdl.desktop.fullscreen) SwitchFullScreen(); #if C_GFXTHREADED sdl.kill_thread=true; SDL_SemPost(sdl.sem); @@ -299,14 +383,37 @@ static void GUI_StartUp(Section * sec) { sec->AddDestroyFunction(&GUI_ShutDown); Section_prop * section=static_cast(sec); sdl.active=false; - sdl.full_screen=false; + sdl.desktop.fullscreen=section->Get_bool("fullscreen"); sdl.wait_on_error=section->Get_bool("waitonerror"); sdl.mouse.locked=false; sdl.mouse.requestlock=false; - sdl.mouse.autoenable=section->Get_bool("autolock"); + sdl.desktop.fixed=section->Get_bool("fullfixed"); + sdl.desktop.width=section->Get_int("fullwidth"); + sdl.desktop.height=section->Get_int("fullheight"); + sdl.desktop.doublebuf=section->Get_bool("fulldouble"); + if (!sdl.desktop.width) { +#ifdef WIN32 + sdl.desktop.width=GetSystemMetrics(SM_CXSCREEN); +#else + sdl.desktop.width=1024; +#endif + } + if (!sdl.desktop.height) { +#ifdef WIN32 + sdl.desktop.height=GetSystemMetrics(SM_CYSCREEN); +#else + sdl.desktop.height=768; +#endif + } + sdl.mouse.autoenable=section->Get_bool("autolock"); sdl.mouse.autolock=false; sdl.mouse.sensitivity=section->Get_int("sensitivity"); - sdl.blit_surface=0; + if (section->Get_bool("overlay")) { + sdl.desktop.type=SCREEN_OVERLAY; + } else { + sdl.desktop.type=SCREEN_SURFACE; + } + sdl.overlay=0; #if C_GFXTHREADED sdl.kill_thread=false; sdl.mutex=SDL_CreateMutex(); @@ -315,10 +422,11 @@ static void GUI_StartUp(Section * sec) { #endif /* Initialize screen for first time */ sdl.surface=SDL_SetVideoMode(640,400,0,0); - if (sdl.surface->format->BitsPerPixel==24) { + sdl.desktop.bpp=sdl.surface->format->BitsPerPixel; + if (sdl.desktop.bpp==24) { LOG_MSG("SDL:You are running in 24 bpp mode, this will slow down things!"); } - GFX_SetSize(640,400,8,0,0,0); + GFX_SetSize(640,400,GFX_8BPP,1.0,1.0,0,0); SDL_EnableKeyRepeat(250,30); SDL_EnableUNICODE(1); /* Get some Keybinds */ @@ -472,11 +580,8 @@ static void HandleKey(SDL_KeyboardEvent * key) { } static void HandleMouseMotion(SDL_MouseMotionEvent * motion) { - if (sdl.mouse.locked) { + if (sdl.mouse.locked) Mouse_CursorMoved((float)motion->xrel*sdl.mouse.sensitivity/100,(float)motion->yrel*sdl.mouse.sensitivity/100); - } else { -// Mouse_CursorSet((float)motion->x/(float)sdl.width,(float)motion->y/(float)sdl.height); - } } static void HandleMouseButton(SDL_MouseButtonEvent * button) { @@ -535,14 +640,6 @@ static void HandleJoystickButton(SDL_JoyButtonEvent * jbutton) { } -static void HandleVideoResize(SDL_ResizeEvent * resize) { - - - - - -} - static Bit8u laltstate = SDL_KEYUP; void GFX_Events() { @@ -579,7 +676,7 @@ void GFX_Events() { HandleJoystickButton(&event.jbutton); break; case SDL_VIDEORESIZE: - HandleVideoResize(&event.resize); +// HandleVideoResize(&event.resize); break; case SDL_QUIT: throw(0); @@ -637,11 +734,16 @@ int main(int argc, char* argv[]) { ) < 0 ) E_Exit("Can't init SDL %s",SDL_GetError()); Section_prop * sdl_sec=control->AddSection_prop("sdl",&GUI_StartUp); sdl_sec->Add_bool("fullscreen",false); + sdl_sec->Add_bool("fulldouble",false); + sdl_sec->Add_bool("fullfixed",false); + sdl_sec->Add_int("fullwidth",0); + sdl_sec->Add_int("fullheight",0); + sdl_sec->Add_bool("overlay",false); sdl_sec->Add_bool("autolock",true); sdl_sec->Add_int("sensitivity",100); sdl_sec->Add_bool("waitonerror",true); /* Init all the dosbox subsystems */ - + MSG_Add("SDL_CONFIGFILE_HELP", "fullscreen -- Start dosbox directly in fullscreen.\n" "autolock -- Mouse will automatically lock, if you click on the screen.\n" @@ -680,7 +782,7 @@ int main(int argc, char* argv[]) { control->StartUp(); /* Shutdown everything */ } catch (char * error) { - if (sdl.full_screen) SwitchFullScreen(); + if (sdl.desktop.fullscreen) SwitchFullScreen(); if (sdl.mouse.locked) CaptureMouse(); LOG_MSG("Exit to error: %s",error); if(sdl.wait_on_error) { @@ -695,7 +797,7 @@ int main(int argc, char* argv[]) { } catch (int){ - if (sdl.full_screen) SwitchFullScreen(); + if (sdl.desktop.fullscreen) SwitchFullScreen(); if (sdl.mouse.locked) CaptureMouse(); } return 0; From 895995c073680a044a0e2aa0f9fdbe935259e856 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 8 Nov 2003 10:11:25 +0000 Subject: [PATCH 1333/4131] Added some kind of aspect correction calcuation, still not perfect Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1414 --- src/hardware/vga_draw.cpp | 60 +++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 1365795e..a8de2f15 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -30,11 +30,8 @@ static void VGA_HERC_Draw(Bit8u * bitdata,Bitu pitch) { Bit8u * reader=&vga.mem.linear[(vga.herc.mode_control & 0x80) ? 8*1024 : 0]; for (Bitu y=0;y>3;x>0;x--) { Bit8u val=*(tempread++); *(Bit32u *)(draw+0)=CGA_2_Table[val >> 4]; @@ -259,8 +256,7 @@ void VGA_DrawHandler(RENDER_Part_Handler part_handler) { /* Draw the current frame */ if (!vga.draw.resizing) { if (vga.config.line_compare=vga.draw.height){ LOG(LOG_VGAGFX,LOG_NORMAL)("Split at %d",stop); goto drawnormal; @@ -348,9 +344,13 @@ norender:; void VGA_SetupDrawing(void) { /* Calculate the FPS for this screen */ double fps; - Bitu vtotal=2 + (vga.crtc.vertical_total | ((vga.crtc.overflow & 1) << 8) | ((vga.crtc.overflow & 0x20) << 4) ); + Bitu vtotal=2 + vga.crtc.vertical_total | + ((vga.crtc.overflow & 1) << 8) | ((vga.crtc.overflow & 0x20) << 4) + ; Bitu htotal=5 + vga.crtc.horizontal_total; - Bitu vdispend = 1 + (vga.crtc.vertical_display_end | ((vga.crtc.overflow & 2)<<7) | ((vga.crtc.overflow & 0x40) << 3) ); + Bitu vdispend = 1 + (vga.crtc.vertical_display_end | + ((vga.crtc.overflow & 2)<<7) | ((vga.crtc.overflow & 0x40) << 3) | + ((vga.s3.ex_ver_overflow & 0x2) << 9)); Bitu hdispend = 1 + (vga.crtc.horizontal_display_end); Bitu hbstart = vga.crtc.start_horizontal_blanking; @@ -365,19 +365,25 @@ void VGA_SetupDrawing(void) { /* Check for 8 for 9 character clock mode */ if (vga.seq.clocking_mode & 1 ) clock/=8; else clock/=9; /* Check for pixel doubling, master clock/2 */ - if (vga.seq.clocking_mode & 0x8) clock/=2; + if (vga.seq.clocking_mode & 0x8) { + clock/=2; + htotal*=2; + } /* Check for dual transfer whatever thing,master clock/2 */ if (vga.s3.pll.cmd & 0x10) clock/=2; - + LOG(LOG_VGA,LOG_NORMAL)("H total %d, V Total %d",htotal,vtotal); LOG(LOG_VGA,LOG_NORMAL)("H D End %d, V D End %d",hdispend,vdispend); fps=clock/(vtotal*htotal); - + double correct_ratio=(100.0/525.0); + double aspect_ratio=((double)htotal/((double)vtotal)/correct_ratio); + vga.draw.resizing=false; - Bitu width,height,pitch,flags; + Bitu width,height,pitch; + Bitu scalew=1; + Bitu scaleh=1; - flags=0; vga.draw.lines=height=vdispend; width=hdispend; vga.draw.double_height=vga.config.vline_double; @@ -387,29 +393,19 @@ void VGA_SetupDrawing(void) { case M_VGA: vga.draw.double_width=true; //Hack since 256 color modes use 2 clocks for a pixel /* Don't know might do this different sometime, will have to do for now */ - if (!vga.draw.double_height) { - if (vga.config.vline_height&1) { - vga.draw.double_height=true; - vga.draw.font_height/=2; - } - } + scaleh*=vga.draw.font_height; width<<=2; pitch=vga.config.scan_len*8; break; case M_LIN8: width<<=3; - if (vga.draw.double_width) width>>=1; - if (!vga.draw.double_height) { - if (vga.config.vline_height&1) { - vga.draw.double_height=true; - vga.draw.font_height/=2; - } - } + scaleh*=vga.draw.font_height; pitch=vga.config.scan_len*8; break; case M_EGA16: width<<=3; pitch=vga.config.scan_len*16; + scaleh*=vga.draw.font_height; break; case M_CGA4: case M_CGA16: //Let is use 320x200 res and double pixels myself @@ -435,6 +431,7 @@ void VGA_SetupDrawing(void) { break; case M_TEXT2: case M_TEXT16: + aspect_ratio=1.0; vga.draw.font_height=vga.config.vline_height+1; if (vga.draw.font_height<4 && (machine Date: Sat, 8 Nov 2003 10:18:06 +0000 Subject: [PATCH 1334/4131] Logging message changed a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1415 --- src/hardware/vga_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index a8de2f15..50685f97 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -462,7 +462,7 @@ void VGA_SetupDrawing(void) { vga.draw.pitch=pitch; vga.draw.scaleh=scaleh; - LOG(LOG_VGA,LOG_NORMAL)("Width %d, Height %d, Pitch %d fps %f",width,height,pitch,fps); + LOG(LOG_VGA,LOG_NORMAL)("Width %d, Height %d, fps %f",width,height,fps); LOG(LOG_VGA,LOG_NORMAL)("Scalew %d, Scaleh %d aspect %f",scalew,scaleh,aspect_ratio); RENDER_SetSize(width,height,8,pitch,aspect_ratio,scalew,scaleh,&VGA_DrawHandler); vga.draw.blank=(Bitu)(1000000/fps); From b8c73b0ff17141f724e23be15ba04ef4bc7bd5c1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 8 Nov 2003 13:41:04 +0000 Subject: [PATCH 1335/4131] Don't allow directories or volume labels to be opened. Return proper error code Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1416 --- src/dos/dos_files.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 74fb195b..33174e22 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.48 2003-10-17 16:56:06 finsterr Exp $ */ +/* $Id: dos_files.cpp,v 1.49 2003-11-08 13:41:04 qbix79 Exp $ */ #include #include @@ -359,7 +359,15 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { /* First check for devices */ if (flags>2) LOG(LOG_FILES,LOG_ERROR)("Special file open command %X file %s",flags,name); else LOG(LOG_FILES,LOG_NORMAL)("file open command %X file %s",flags,name); - + + Bit16u attr; + if(DOS_GetFileAttr(name,&attr)){ //DON'T ALLOW directories to be openened + if((attr & DOS_ATTR_DIRECTORY) || (attr & DOS_ATTR_VOLUME)){ + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; + } + } + DOS_PSP psp(dos.psp); Bit8u handle=DOS_FindDevice((char *)name); bool device=false;char fullname[DOS_PATHLENGTH];Bit8u drive;Bit8u i; From 9d0029f51b80d2882d71d152e1653d783da19f9a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 8 Nov 2003 18:00:47 +0000 Subject: [PATCH 1336/4131] Add method for checking a remote drive. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1417 --- include/dos_system.h | 3 ++- src/dos/dos_ioctl.cpp | 5 +++-- src/dos/drive_local.cpp | 8 ++++++++ src/dos/drive_virtual.cpp | 3 +++ src/dos/drives.h | 4 +++- 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 5c4cddf8..d93b19be 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.17 2003-10-29 19:42:19 finsterr Exp $ */ +/* $Id: dos_system.h,v 1.18 2003-11-08 17:59:30 harekiet Exp $ */ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ @@ -222,6 +222,7 @@ public: virtual Bit8u GetMediaByte(void)=0; virtual void SetDir(const char* path) { strcpy(curdir,path); }; virtual void EmptyCache(void) { dirCache.EmptyCache(); }; + virtual bool isRemote(void)=0; char * GetInfo(void); char curdir[DOS_PATHLENGTH]; char info[256]; diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index e6cd9fb0..a5d14c00 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.16 2003-10-14 08:38:35 qbix79 Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.17 2003-11-08 18:00:46 harekiet Exp $ */ #include #include "dosbox.h" @@ -78,8 +78,9 @@ bool DOS_IOCTL(void) { drive=reg_bl;if (!drive) drive=dos.current_drive;else drive--; if (Drives[drive]) { reg_dx=0; - //TODO Cdrom drives are remote + if (Drives[drive]->isRemote()) reg_dx|=(1 << 12); //TODO Set bit 9 on drives that don't support direct I/O + reg_al=0; return true; } else { DOS_SetError(DOSERR_INVALID_DRIVE); diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 509d083f..b2c14279 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -311,6 +311,10 @@ Bit8u localDrive::GetMediaByte(void) { return allocation.mediaid; } +bool localDrive::isRemote(void) { + return false; +} + localDrive::localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid) { strcpy(basedir,startdir); sprintf(info,"local directory %s",startdir); @@ -499,3 +503,7 @@ void cdromDrive::SetDir(const char* path) } localDrive::SetDir(path); }; + +bool cdromDrive::isRemote(void) { + return true; +} diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 64663fde..9dff9f21 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -227,3 +227,6 @@ Bit8u Virtual_Drive::GetMediaByte(void) { return 0xF8; } +bool Virtual_Drive::isRemote(void) { + return false; +} diff --git a/src/dos/drives.h b/src/dos/drives.h index 52ddad8f..37158423 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -41,7 +41,7 @@ public: virtual bool FileExists(const char* name); virtual bool FileStat(const char* name, FileStat_Block * const stat_block); virtual Bit8u GetMediaByte(void); - + virtual bool isRemote(void); private: char basedir[CROSS_LEN]; @@ -71,6 +71,7 @@ public: virtual bool GetFileAttr(char * name,Bit16u * attr); virtual bool FindFirst(char * _dir,DOS_DTA & dta); virtual void SetDir(const char* path); + virtual bool isRemote(void); private: Bit8u subUnit; }; @@ -95,6 +96,7 @@ public: bool FileStat(const char* name, FileStat_Block* const stat_block); Bit8u GetMediaByte(void); void EmptyCache(void){} + bool isRemote(void); private: VFILE_Block * search_file; }; From 909f7333fb1d2a0aa170ea70d4f244bf67eff705 Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Sun, 9 Nov 2003 04:05:06 +0000 Subject: [PATCH 1337/4131] Restored lost DMA functionality. (Fixed MM45 bug.) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1418 --- src/hardware/dma.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 58fb48ef..af3efba3 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -62,6 +62,7 @@ void DmaController::portWrite(Bit32u port, Bit16u val, bool eightbit) { DmaChannels[i]->Notify(); r++; } + } if(port == ControllerPorts[ctrlnum][DMA_CLEARREG]) { found = true; @@ -75,7 +76,7 @@ void DmaController::portWrite(Bit32u port, Bit16u val, bool eightbit) { DmaChannels[dmachan]->autoinit = ((val & 0x10) == 0x10); DmaChannels[dmachan]->dir = ((val & 0x20) == 0x20); DmaChannels[dmachan]->dmamode = (val >> 6) & 0x3; - DMA_CheckEnabled(DmaChannels[dmachan]); + DmaChannels[dmachan]->Notify(); } if(!found) LOG_MSG("Write to DMA port %x with %x", port, val); @@ -207,10 +208,10 @@ Bit16u DmaChannel::portRead(Bit32u port, bool eightbit) { if(eightbit) { if(ff) { ff = !ff; - return (Bit8u)(currcnt & 0xff); + return (Bit8u)(currcnt-1 & 0xff); } else { ff = !ff; - return (Bit8u)(currcnt >> 8); + return (Bit8u)(currcnt-1 >> 8); } } else { return (Bit16u)currcnt; @@ -233,7 +234,7 @@ void DmaChannel::portWrite(Bit32u port, Bit16u val, bool eightbit) { baseaddr = val; } calcPhys(); - reset(); + addr_changed = true; } if (port == ChannelPorts[DMA_TRANSCOUNT][channum]) { if(eightbit) { @@ -247,7 +248,7 @@ void DmaChannel::portWrite(Bit32u port, Bit16u val, bool eightbit) { transcnt = val; } currcnt = transcnt+1; - reset(); + addr_changed = true; DMA_CheckEnabled(this); MakeCallback(false); @@ -340,6 +341,8 @@ Bitu DMA_8_Read(Bitu dmachan,Bit8u * buffer,Bitu count) { if (chan->masked) return 0; if (!count) return 0; + if (chan->addr_changed) chan->reset(); + if (chan->currcnt>count) { MEM_BlockRead(chan->curraddr,buffer,count); chan->curraddr+=count; @@ -357,7 +360,7 @@ Bitu DMA_8_Read(Bitu dmachan,Bit8u * buffer,Bitu count) { chan->current_addr+=count; chan->currcnt=0; chan->enabled=false; - LOG(LOG_DMA,LOG_NORMAL)("8-bit Channel %d reached terminal count"); + LOG(LOG_DMA,LOG_NORMAL)("8-bit Channel %d reached terminal count",chan->channum); return count; } else { buffer+=chan->currcnt; @@ -420,7 +423,10 @@ Bitu DMA_16_Write(Bitu dmachan,Bit8u * buffer,Bitu count) { return 0; } -void DMA_SetEnabled(DmaChannel * chan,bool enabled) { +void DMA_SetEnabled(void * usechan,bool enabled) { + DmaChannel * chan; + chan = (DmaChannel *)usechan; + if (chan->enabled == enabled) return; chan->enabled=enabled; if (chan->enable_callback) (*chan->enable_callback)(enabled); From 6a3c799e18814cc1b94e5f05c6c2d0b3edc6dfe9 Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Sun, 9 Nov 2003 04:05:51 +0000 Subject: [PATCH 1338/4131] Tuned 16-bit samples. Increased support for some tracker programs. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1419 --- src/hardware/gus.cpp | 46 +++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index bed77567..a33d4f94 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -57,8 +57,8 @@ struct GFGus { Bit32u basefreq; Bit16u activechan; - Bit16u mupersamp; - Bit16u muperchan; + Bit32s mupersamp; + Bit32s muperchan; Bit16u timerReg; @@ -179,7 +179,8 @@ INLINE Bit16s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { if(Delta >= 1024) { - return (Bit16s)((Bit16u)GUSRam[useAddr] | ((Bit16u)GUSRam[useAddr+1] << 8)) >> 1; + return (Bit16s)((Bit16u)GUSRam[useAddr] | ((Bit16u)GUSRam[useAddr+1] << 8)) >> 2 + ; } else { @@ -187,7 +188,7 @@ INLINE Bit16s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { Bit16s w1 = (Bit16s)((Bit16u)GUSRam[useAddr] | ((Bit16u)GUSRam[useAddr+1] << 8)); Bit16s w2 = (Bit16s)((Bit16u)GUSRam[useAddr+2] | ((Bit16u)GUSRam[useAddr+3] << 8)); Bit16s diff = w2 - w1; - return (w1 + (((Bit32s)diff * (Bit32s)((CurAddr) & 0x3fe)) >> 10)) >> 1; + return (w1 + (((Bit32s)diff * (Bit32s)((CurAddr) & 0x3fe)) >> 10)) >> 2; } } @@ -278,6 +279,9 @@ public: return FreqCont; } + // Used when GUS changes channel numbers during playback + void UpdateFreqCtrl() { WriteFreqCtrl(FreqCont); } + // Pan position register void WritePanPot(Bit8u val) { if(val<8) { @@ -362,7 +366,9 @@ public: if(dir) { // Increment backwards if (moving) CurAddr -= RealDelta; - if ((!eightbit) && (moving)) CurAddr -= RealDelta; + + //Thought 16-bit needed this + //if ((!eightbit) && (moving)) CurAddr -= RealDelta; if(CurAddr <= StartAddr) { if((VolControl & 0x4) == 0) { @@ -388,7 +394,9 @@ public: // Increment forwards if (moving) CurAddr += RealDelta; - if ((!eightbit) && (moving)) CurAddr += RealDelta; + + //Thought 16-bit needed this + //if ((!eightbit) && (moving)) CurAddr += RealDelta; if(CurAddr >= EndAddr) { if((VolControl & 0x4) == 0) { if((voiceCont & 0x8) != 0) { @@ -463,10 +471,10 @@ public: switch(VolRampRate >> 6) { case 0: - nextramp += myGUS.muperchan; + nextramp += myGUS.muperchan; break; case 1: - nextramp += myGUS.muperchan * 8; + nextramp += myGUS.muperchan* 8; break; case 2: nextramp += myGUS.muperchan * 64; @@ -514,6 +522,8 @@ static void GUSReset(void) myGUS.timers[0].active = false; myGUS.timers[1].active = false; + myGUS.timers[0].bytetimer = 0x0; + myGUS.timers[1].bytetimer = 0x0; // Stop all channels int i; @@ -541,6 +551,9 @@ static Bit16u ExecuteReadRegister(void) { return (Bit16u)(tmpreg << 8); case 0x42: // Dma address register return myGUS.dmaAddr; + case 0x45: // Timer control register. Identical in operation to Adlib's timer + return (Bit16u)(myGUS.TimerControl << 8); + break; case 0x49: // Dma sample register tmpreg = myGUS.DMAControl & 0xbf; if(myGUS.irq.DMATC) tmpreg |= 0x40; @@ -607,6 +620,7 @@ static Bit16u ExecuteReadRegister(void) { static void ExecuteGlobRegister(void) { + int i; //LOG_MSG("Access global register %x with %x", myGUS.gRegSelect, myGUS.gRegData); switch(myGUS.gRegSelect) { case 0x0: // Channel voice control register @@ -698,9 +712,14 @@ static void ExecuteGlobRegister(void) { float simple; simple = (1.0 / (float)GUS_RATE) / 0.000001; - myGUS.mupersamp = (Bit16u)simple; - myGUS.muperchan = (Bit16u)((float)1.6 * (float)myGUS.activechan); + myGUS.mupersamp = (Bit32s)simple*1024; + myGUS.muperchan = (Bit32s)((float)1.6 * (float)myGUS.activechan * 1024); LOG_MSG("GUS set to %d channels", myGUS.activechan); + + for(i=0;i<=myGUS.activechan;i++) { if(guschan[i] != NULL) guschan[i]->UpdateFreqCtrl(); } + + break; + case 0x10: // Undocumented register used in Fast Tracker 2 break; case 0x41: // Dma control register myGUS.DMAControl = (Bit8u)myGUS.gRegData; @@ -713,6 +732,7 @@ static void ExecuteGlobRegister(void) { myGUS.dmaAddr = myGUS.gRegData; break; case 0x43: // MSB Peek/poke DRAM position + myGUS.gDramAddr = (0xff0000 & myGUS.gDramAddr) | ((Bit32u)myGUS.gRegData); break; case 0x44: // LSW Peek/poke DRAM position @@ -729,12 +749,12 @@ static void ExecuteGlobRegister(void) { case 0x46: // Timer 1 control myGUS.timers[0].bytetimer = (Bit8u)myGUS.gRegData; - myGUS.timers[0].setting = ((Bit32s)0xff - (Bit32s)myGUS.timers[0].bytetimer) * (Bit32s)80; + myGUS.timers[0].setting = ((Bit32s)0xff - (Bit32s)myGUS.timers[0].bytetimer) * ((Bit32s)80 << 10); myGUS.timers[0].countdown = myGUS.timers[0].setting; break; case 0x47: // Timer 2 control myGUS.timers[1].bytetimer = (Bit8u)myGUS.gRegData; - myGUS.timers[1].setting = ((Bit32s)0xff - (Bit32s)myGUS.timers[1].bytetimer) * (Bit32s)360; + myGUS.timers[1].setting = ((Bit32s)0xff - (Bit32s)myGUS.timers[1].bytetimer) * ((Bit32s)360 << 10); myGUS.timers[1].countdown = myGUS.timers[1].setting; break; case 0x49: // DMA sampling control register @@ -972,7 +992,7 @@ static void GUS_CallBack(Bit8u * stream,Bit32u len) { bufptr = (Bit16s *)stream; - for(i=0;i Date: Sun, 9 Nov 2003 08:19:54 +0000 Subject: [PATCH 1339/4131] New variable dma.cpp needs Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1420 --- include/dma.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dma.h b/include/dma.h index f97be390..1d42efcf 100644 --- a/include/dma.h +++ b/include/dma.h @@ -105,6 +105,7 @@ public: Bit32s currcnt; DmaController *myController; bool DMA16; + bool addr_changed; public: Bit8u dmamode; bool dir; From 7139da9f0d5def09d0ea2e6207d397e717610ef4 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 9 Nov 2003 08:20:23 +0000 Subject: [PATCH 1340/4131] Fix some vstudio.net warnings/errors Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1421 --- src/hardware/dma.cpp | 8 ++++---- src/hardware/gus.cpp | 15 +++++++-------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index af3efba3..f93ac9fa 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -208,10 +208,10 @@ Bit16u DmaChannel::portRead(Bit32u port, bool eightbit) { if(eightbit) { if(ff) { ff = !ff; - return (Bit8u)(currcnt-1 & 0xff); + return (Bit8u)(currcnt-1); } else { ff = !ff; - return (Bit8u)(currcnt-1 >> 8); + return (Bit8u)((currcnt-1) >> 8); } } else { return (Bit16u)currcnt; @@ -343,7 +343,7 @@ Bitu DMA_8_Read(Bitu dmachan,Bit8u * buffer,Bitu count) { if (!count) return 0; if (chan->addr_changed) chan->reset(); - if (chan->currcnt>count) { + if (chan->currcnt>(Bits)count) { MEM_BlockRead(chan->curraddr,buffer,count); chan->curraddr+=count; chan->current_addr+=count; @@ -382,7 +382,7 @@ Bitu DMA_8_Write(Bitu dmachan,Bit8u * buffer,Bitu count) { if (chan->masked) return 0; if (!count) return 0; - if (chan->currcnt>count) { + if (chan->currcnt>(Bits)count) { MEM_BlockWrite(chan->curraddr,buffer,count); chan->curraddr+=count; chan->currcnt-=count; diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index a33d4f94..64ad12a0 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -166,7 +166,7 @@ INLINE Bit16s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { Bit16s w1 = b1 << 7; Bit16s w2 = b2 << 7; Bit16s diff = w2 - w1; - return (w1 + (((Bit32s)diff * (Bit32s)(CurAddr & 0x3fe)) >> 10)); + return (Bit16s)(w1 + (((Bit32s)diff * (Bit32s)(CurAddr & 0x3fe)) >> 10)); } } else { @@ -188,7 +188,7 @@ INLINE Bit16s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { Bit16s w1 = (Bit16s)((Bit16u)GUSRam[useAddr] | ((Bit16u)GUSRam[useAddr+1] << 8)); Bit16s w2 = (Bit16s)((Bit16u)GUSRam[useAddr+2] | ((Bit16u)GUSRam[useAddr+3] << 8)); Bit16s diff = w2 - w1; - return (w1 + (((Bit32s)diff * (Bit32s)((CurAddr) & 0x3fe)) >> 10)) >> 2; + return (Bit16s)(w1 + (((Bit32s)diff * (Bit32s)((CurAddr) & 0x3fe)) >> 10)) >> 2; } } @@ -210,7 +210,7 @@ public: Bit32u CurAddr; Bit8u PanPot; Bit8u VolControl; - Bit16u channum; + Bit8u channum; bool moving; bool playing; @@ -224,7 +224,7 @@ public: Bit32s rightvol; Bit32s nextramp; - GUSChannels(Bit16u num) { + GUSChannels(Bit8u num) { channum = num; playing = true; ramping = false; @@ -349,7 +349,7 @@ public: notifyonce = false; - for(i=0;i> 4)); + a = pow(2.0f,(float)(i >> 4)); b = 1.0+((float)(i & 0xf))/(float)16; a *= b; a /= 16; @@ -1012,7 +1011,7 @@ void MakeTables(void) } for(i=0;i<4096;i++) { float a,b; - a = pow(2,(float)(i >> 8)); + a = pow(2.0f,(float)(i >> 8)); b = 1.0+((float)(i & 0xff))/(float)256; a *= b; a /= 16; From db3d7e757687c3c58b09292c6c87dc7309106b7b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 9 Nov 2003 08:30:07 +0000 Subject: [PATCH 1341/4131] variable needs some setting up too Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1422 --- include/dma.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/dma.h b/include/dma.h index 1d42efcf..dcca1e81 100644 --- a/include/dma.h +++ b/include/dma.h @@ -123,6 +123,7 @@ public: enable_callback = NULL; newcallback = NULL; if(num == 4) return; + addr_changed=false; for(i=0;i<3;i++) { IO_RegisterReadBHandler(ChannelPorts[i][num],read_dmaB); @@ -147,6 +148,7 @@ public: void RegisterCallback(DMA_NewCallBack useCallBack) { newcallback = useCallBack; } void reset(void) { + addr_changed=false; curraddr = physaddr; currcnt = transcnt+1; current_addr = baseaddr; From 53874d092a97abc84c42a323ca1db3e2dc3b7c7d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 9 Nov 2003 09:45:01 +0000 Subject: [PATCH 1342/4131] Fix flags with binary operations setting the overflow flag to 0 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1423 --- src/cpu/flags.cpp | 91 ++++++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 41 deletions(-) diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 6fef35ef..a1475523 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -546,7 +546,7 @@ Bitu FillFlags(void) { #define DOFLAG_SFw reg_flags=(reg_flags & ~FLAG_SF) | ((lf_resw & 0x8000) >> 8); #define DOFLAG_SFd reg_flags=(reg_flags & ~FLAG_SF) | ((lf_resd & 0x80000000) >> 24); - +#define SETCF(NEWBIT) reg_flags=(reg_flags & ~FLAG_CF)|(NEWBIT); #define SET_FLAG SETFLAGBIT Bitu FillFlags(void) { @@ -581,7 +581,7 @@ Bitu FillFlags(void) { SET_FLAG(CF,(lf_resb < lf_var1b) || (lflags.oldcf && (lf_resb == lf_var1b))); DOFLAG_AF; DOFLAG_ZFb; - SET_FLAG(SF,(lf_resb&0x80)); + DOFLAG_SFb; SET_FLAG(OF,((lf_var1b ^ lf_var2b ^ 0x80) & (lf_resb ^ lf_var1b)) & 0x80); DOFLAG_PF; break; @@ -589,7 +589,7 @@ Bitu FillFlags(void) { SET_FLAG(CF,(lf_resw < lf_var1w) || (lflags.oldcf && (lf_resw == lf_var1w))); DOFLAG_AF; DOFLAG_ZFw; - SET_FLAG(SF,(lf_resw&0x8000)); + DOFLAG_SFw; SET_FLAG(OF,((lf_var1w ^ lf_var2w ^ 0x8000) & (lf_resw ^ lf_var1w)) & 0x8000); DOFLAG_PF; break; @@ -597,7 +597,7 @@ Bitu FillFlags(void) { SET_FLAG(CF,(lf_resd < lf_var1d) || (lflags.oldcf && (lf_resd == lf_var1d))); DOFLAG_AF; DOFLAG_ZFd; - SET_FLAG(SF,(lf_resd&0x80000000)); + DOFLAG_SFd; SET_FLAG(OF,((lf_var1d ^ lf_var2d ^ 0x80000000) & (lf_resd ^ lf_var1d)) & 0x80000000); DOFLAG_PF; break; @@ -607,7 +607,7 @@ Bitu FillFlags(void) { SET_FLAG(CF,(lf_var1b < lf_resb) || (lflags.oldcf && (lf_var2b==0xff))); DOFLAG_AF; DOFLAG_ZFb; - SET_FLAG(SF,(lf_resb&0x80)); + DOFLAG_SFb; SET_FLAG(OF,(lf_var1b ^ lf_var2b) & (lf_var1b ^ lf_resb) & 0x80); DOFLAG_PF; break; @@ -615,7 +615,7 @@ Bitu FillFlags(void) { SET_FLAG(CF,(lf_var1w < lf_resw) || (lflags.oldcf && (lf_var2w==0xffff))); DOFLAG_AF; DOFLAG_ZFw; - SET_FLAG(SF,(lf_resw&0x8000)); + DOFLAG_SFw; SET_FLAG(OF,(lf_var1w ^ lf_var2w) & (lf_var1w ^ lf_resw) & 0x8000); DOFLAG_PF; break; @@ -623,7 +623,7 @@ Bitu FillFlags(void) { SET_FLAG(CF,(lf_var1d < lf_resd) || (lflags.oldcf && (lf_var2d==0xffffffff))); DOFLAG_AF; DOFLAG_ZFd; - SET_FLAG(SF,(lf_resd&0x80000000)); + DOFLAG_SFd; SET_FLAG(OF,(lf_var1d ^ lf_var2d) & (lf_var1d ^ lf_resd) & 0x80000000); DOFLAG_PF; break; @@ -634,7 +634,7 @@ Bitu FillFlags(void) { SET_FLAG(CF,(lf_var1b8) SET_FLAG(CF,false); else SET_FLAG(CF,(lf_var1b >> (8-lf_var2b)) & 1); DOFLAG_ZFb; - SET_FLAG(SF,(lf_resb&0x80)); + DOFLAG_SFb; SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); DOFLAG_PF; break; @@ -733,14 +742,14 @@ Bitu FillFlags(void) { if (lf_var2b>16) SET_FLAG(CF,false); else SET_FLAG(CF,(lf_var1w >> (16-lf_var2b)) & 1); DOFLAG_ZFw; - SET_FLAG(SF,(lf_resw&0x8000)); + DOFLAG_SFw; SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); DOFLAG_PF; break; case t_SHLd: SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); DOFLAG_ZFd; - SET_FLAG(SF,(lf_resd&0x80000000)); + DOFLAG_SFd; SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); DOFLAG_PF; break; @@ -749,14 +758,14 @@ Bitu FillFlags(void) { case t_DSHLw: SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); DOFLAG_ZFw; - SET_FLAG(SF,(lf_resw&0x8000)); + DOFLAG_SFw; SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); DOFLAG_PF; break; case t_DSHLd: SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); DOFLAG_ZFd; - SET_FLAG(SF,(lf_resd&0x80000000)); + DOFLAG_SFd; SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); DOFLAG_PF; break; @@ -765,21 +774,21 @@ Bitu FillFlags(void) { case t_SHRb: SET_FLAG(CF,(lf_var1b >> (lf_var2b - 1)) & 1); DOFLAG_ZFb; - SET_FLAG(SF,(lf_resb&0x80)); + DOFLAG_SFb; SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); DOFLAG_PF; break; case t_SHRw: SET_FLAG(CF,(lf_var1w >> (lf_var2b - 1)) & 1); DOFLAG_ZFw; - SET_FLAG(SF,(lf_resw&0x8000)); + DOFLAG_SFw; SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); DOFLAG_PF; break; case t_SHRd: SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); DOFLAG_ZFd; - SET_FLAG(SF,(lf_resd&0x80000000)); + DOFLAG_SFd; SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); DOFLAG_PF; break; @@ -788,14 +797,14 @@ Bitu FillFlags(void) { case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); DOFLAG_ZFw; - SET_FLAG(SF,(lf_resw&0x8000)); + DOFLAG_SFw; SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); DOFLAG_PF; break; case t_DSHRd: SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); DOFLAG_ZFd; - SET_FLAG(SF,(lf_resd&0x80000000)); + DOFLAG_SFd; SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); DOFLAG_PF; break; @@ -804,21 +813,21 @@ Bitu FillFlags(void) { case t_SARb: SET_FLAG(CF,(((Bit8s) lf_var1b) >> (lf_var2b - 1)) & 1); DOFLAG_ZFb; - SET_FLAG(SF,(lf_resb&0x80)); + DOFLAG_SFb; SET_FLAG(OF,false); DOFLAG_PF; break; case t_SARw: SET_FLAG(CF,(((Bit16s) lf_var1w) >> (lf_var2b - 1)) & 1); DOFLAG_ZFw; - SET_FLAG(SF,(lf_resw&0x8000)); + DOFLAG_SFw; SET_FLAG(OF,false); DOFLAG_PF; break; case t_SARd: SET_FLAG(CF,(((Bit32s) lf_var1d) >> (lf_var2b - 1)) & 1); DOFLAG_ZFd; - SET_FLAG(SF,(lf_resd&0x80000000)); + DOFLAG_SFd; SET_FLAG(OF,false); DOFLAG_PF; break; @@ -877,21 +886,21 @@ Bitu FillFlags(void) { case t_INCb: SET_FLAG(AF,(lf_resb & 0x0f) == 0); DOFLAG_ZFb; - SET_FLAG(SF,(lf_resb&0x80)); + DOFLAG_SFb; SET_FLAG(OF,(lf_resb == 0x80)); DOFLAG_PF; break; case t_INCw: SET_FLAG(AF,(lf_resw & 0x0f) == 0); DOFLAG_ZFw; - SET_FLAG(SF,(lf_resw&0x8000)); + DOFLAG_SFw; SET_FLAG(OF,(lf_resw == 0x8000)); DOFLAG_PF; break; case t_INCd: SET_FLAG(AF,(lf_resd & 0x0f) == 0); DOFLAG_ZFd; - SET_FLAG(SF,(lf_resd&0x80000000)); + DOFLAG_SFd; SET_FLAG(OF,(lf_resd == 0x80000000)); DOFLAG_PF; break; @@ -899,21 +908,21 @@ Bitu FillFlags(void) { case t_DECb: SET_FLAG(AF,(lf_resb & 0x0f) == 0); DOFLAG_ZFb; - SET_FLAG(SF,(lf_resb&0x80)); + DOFLAG_SFb; SET_FLAG(OF,(lf_resb == 0x7f)); DOFLAG_PF; break; case t_DECw: SET_FLAG(AF,(lf_resw & 0x0f) == 0); DOFLAG_ZFw; - SET_FLAG(SF,(lf_resw&0x8000)); + DOFLAG_SFw; SET_FLAG(OF,(lf_resw == 0x7fff)); DOFLAG_PF; break; case t_DECd: SET_FLAG(AF,(lf_resd & 0x0f) == 0); DOFLAG_ZFd; - SET_FLAG(SF,(lf_resd&0x80000000)); + DOFLAG_SFd; SET_FLAG(OF,(lf_resd == 0x7fffffff)); DOFLAG_PF; break; @@ -922,7 +931,7 @@ Bitu FillFlags(void) { SET_FLAG(CF,(lf_var1b!=0)); SET_FLAG(AF,(lf_resb & 0x0f) == 0); DOFLAG_ZFb; - SET_FLAG(SF,(lf_resb&0x80)); + DOFLAG_SFb; SET_FLAG(OF,(lf_var1b == 0x80)); DOFLAG_PF; break; @@ -930,7 +939,7 @@ Bitu FillFlags(void) { SET_FLAG(CF,(lf_var1w!=0)); SET_FLAG(AF,(lf_resw & 0x0f) == 0); DOFLAG_ZFw; - SET_FLAG(SF,(lf_resw&0x8000)); + DOFLAG_SFw; SET_FLAG(OF,(lf_var1w == 0x8000)); DOFLAG_PF; break; @@ -938,7 +947,7 @@ Bitu FillFlags(void) { SET_FLAG(CF,(lf_var1d!=0)); SET_FLAG(AF,(lf_resd & 0x0f) == 0); DOFLAG_ZFd; - SET_FLAG(SF,(lf_resd&0x80000000)); + DOFLAG_SFd; SET_FLAG(OF,(lf_var1d == 0x80000000)); DOFLAG_PF; break; From 4730d55ed965634a1b9dd4523460b5326552f3ff Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 9 Nov 2003 09:46:39 +0000 Subject: [PATCH 1343/4131] RCL/RCR instructions changed a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1424 --- src/cpu/instructions.h | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index cf00531f..0f2c1e14 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -290,22 +290,20 @@ #define RCLB(op1,op2,load,save) \ if (op2%9) { \ - LoadZF;LoadSF;LoadAF; \ - Bit8u cf=get_CF()!=0; \ - lf_var1b=load(op1); \ - lf_var2b=op2%9; \ + Bit8u cf=(Bit8u)FillFlags()&0x1; \ + lf_var1b=load(op1); \ + lf_var2b=op2%9; \ lflags.type=t_RCLb; \ - lf_resb=(lf_var1b << lf_var2b) | \ - (cf << (lf_var2b-1)) | \ - (lf_var1b >> (9-lf_var2b)); \ - SETFLAGBIT(CF,((lf_var1b >> (8-lf_var2b)) & 1)); \ - save(op1,lf_resb); \ + lf_resb=(lf_var1b << lf_var2b) | \ + (cf << (lf_var2b-1)) | \ + (lf_var1b >> (9-lf_var2b)); \ + SETFLAGBIT(CF,((lf_var1b >> (8-lf_var2b)) & 1)); \ + save(op1,lf_resb); \ } #define RCLW(op1,op2,load,save) \ if (op2%17) { \ - LoadZF;LoadSF;LoadAF; \ - Bit16u cf=get_CF()!=0; \ + Bit16u cf=(Bit16u)FillFlags()&0x1; \ lf_var1w=load(op1); \ lf_var2b=op2%17; \ lflags.type=t_RCLw; \ @@ -318,8 +316,7 @@ #define RCLD(op1,op2,load,save) \ if (op2) { \ - LoadZF;LoadSF;LoadAF; \ - Bit32u cf=get_CF()!=0; \ + Bit32u cf=(Bit32u)FillFlags()&0x1; \ lf_var1d=load(op1); \ lf_var2b=op2; \ lflags.type=t_RCLd; \ @@ -336,8 +333,7 @@ #define RCRB(op1,op2,load,save) \ if (op2%9) { \ - LoadZF;LoadSF;LoadAF; \ - Bit8u cf=get_CF()!=0; \ + Bit8u cf=(Bit8u)FillFlags()&0x1; \ lf_var1b=load(op1); \ lf_var2b=op2%9; \ lflags.type=t_RCRb; \ @@ -349,8 +345,7 @@ #define RCRW(op1,op2,load,save) \ if (op2%17) { \ - LoadZF;LoadSF;LoadAF; \ - Bit16u cf=get_CF()!=0; \ + Bit16u cf=(Bit16u)FillFlags()&0x1; \ lf_var1w=load(op1); \ lf_var2b=op2%17; \ lflags.type=t_RCRw; \ @@ -362,8 +357,7 @@ #define RCRD(op1,op2,load,save) \ if (op2) { \ - LoadZF;LoadSF;LoadAF; \ - Bit32u cf=get_CF()!=0; \ + Bit32u cf=(Bit32u)FillFlags()&0x1; \ lf_var1d=load(op1); \ lf_var2b=op2; \ lflags.type=t_RCRd; \ From 81ed2689cbdf1837cf2300a50bc3be95ce582581 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 9 Nov 2003 09:48:02 +0000 Subject: [PATCH 1344/4131] Use new lazy flag defines for conditional testing changed inc/dec instructions to also safe first parameter Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1425 --- src/cpu/core_full/op.h | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 6137cd6a..67d93e8c 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -33,26 +33,28 @@ switch (inst.code.op) { lflags.type=inst.code.op; break; case t_ADCb: case t_ADCw: case t_ADCd: - lflags.oldcf=get_CF()!=0; + lflags.oldcf=(get_CF()!=0); lf_var1d=inst.op1.d; lf_var2d=inst.op2.d; inst.op1.d=lf_resd=lf_var1d + lf_var2d + lflags.oldcf; lflags.type=inst.code.op; break; case t_SBBb: case t_SBBw: case t_SBBd: - lflags.oldcf=get_CF()!=0; + lflags.oldcf=(get_CF()!=0); lf_var1d=inst.op1.d; lf_var2d=inst.op2.d; inst.op1.d=lf_resd=lf_var1d - lf_var2d - lflags.oldcf; lflags.type=inst.code.op; break; case t_INCb: case t_INCw: case t_INCd: - SETFLAGBIT(CF,get_CF()); + LoadCF; + lf_var1d=inst.op1.d; inst.op1.d=lf_resd=inst.op1.d+1; lflags.type=inst.code.op; break; case t_DECb: case t_DECw: case t_DECd: - SETFLAGBIT(CF,get_CF()); + LoadCF; + lf_var1d=inst.op1.d; inst.op1.d=lf_resd=inst.op1.d-1; lflags.type=inst.code.op; break; @@ -218,22 +220,22 @@ switch (inst.code.op) { AAD(inst.op1.b); goto nextopcode; - case O_C_O: inst.cond=get_OF(); break; - case O_C_NO: inst.cond=!get_OF(); break; - case O_C_B: inst.cond=get_CF(); break; - case O_C_NB: inst.cond=!get_CF(); break; - case O_C_Z: inst.cond=get_ZF(); break; - case O_C_NZ: inst.cond=!get_ZF(); break; - case O_C_BE: inst.cond=get_CF() || get_ZF(); break; - case O_C_NBE: inst.cond=!get_CF() && !get_ZF(); break; - case O_C_S: inst.cond=get_SF(); break; - case O_C_NS: inst.cond=!get_SF(); break; - case O_C_P: inst.cond=get_PF(); break; - case O_C_NP: inst.cond=!get_PF(); break; - case O_C_L: inst.cond=get_SF() != get_OF(); break; - case O_C_NL: inst.cond=get_SF() == get_OF(); break; - case O_C_LE: inst.cond=get_ZF() || (get_SF() != get_OF()); break; - case O_C_NLE: inst.cond=(get_SF() == get_OF()) && !get_ZF(); break; + case O_C_O: inst.cond=TFLG_O; break; + case O_C_NO: inst.cond=TFLG_NO; break; + case O_C_B: inst.cond=TFLG_B; break; + case O_C_NB: inst.cond=TFLG_NB; break; + case O_C_Z: inst.cond=TFLG_Z; break; + case O_C_NZ: inst.cond=TFLG_NZ; break; + case O_C_BE: inst.cond=TFLG_BE; break; + case O_C_NBE: inst.cond=TFLG_NBE; break; + case O_C_S: inst.cond=TFLG_S; break; + case O_C_NS: inst.cond=TFLG_NS; break; + case O_C_P: inst.cond=TFLG_P; break; + case O_C_NP: inst.cond=TFLG_NP; break; + case O_C_L: inst.cond=TFLG_L; break; + case O_C_NL: inst.cond=TFLG_NL; break; + case O_C_LE: inst.cond=TFLG_LE; break; + case O_C_NLE: inst.cond=TFLG_NLE; break; case O_ALOP: reg_al=LoadMb(inst.rm_eaa); From 8b82835ccaa59f6e7a1406f67698372c1275587e Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 9 Nov 2003 16:42:55 +0000 Subject: [PATCH 1345/4131] Added div0 exception Added descriptions for dpmi callbacks Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1426 --- src/ints/dpmi.cpp | 140 ++++++++++++++++++++++++++++------------------ 1 file changed, 85 insertions(+), 55 deletions(-) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index 2aa538ad..92029586 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -204,12 +204,14 @@ public: Bitu CreateAlias (Bitu selector, Bit16u& alias); void ReloadSegments (Bitu selector); bool SetAccessRights (Bitu selector, SetDescriptor& desc, Bitu rights); + bool SetProtInterrupt (Bitu num, Bitu selector, Bitu offset); // Special Interrupt handlers Bitu Int2fHandler (void); Bitu Int31Handler (void); // Exceptions + Bitu CreateException (void); void CreateException (Bitu num, Bitu errorCode); Bitu ExceptionReturn (void); @@ -294,7 +296,7 @@ private: bool bit32; Bitu psp; } client; - Bit16u mem_handle; /* Handle for GDT/IDT */ + Bit32s mem_handle; /* Handle for GDT/IDT */ struct { PhysPt base; Bitu limit; @@ -697,23 +699,42 @@ void DPMI::ReloadSegments(Bitu selector) if (SegValue(ss)==selector) CPU_SetSegGeneral(ss,selector); }; +Bitu DPMI::CreateException(void) +{ + // Division by Zero + CreateException(0,0); + return CBRET_NONE; +}; + void DPMI::CreateException(Bitu num, Bitu errorCode) { + // Assuming Stack looks like a int has occured + Bitu stack_eip,stack_cs,stack_flags; if (dpmi.client.bit32) { + // Clean up stack + stack_eip = CPU_Pop32(); + stack_cs = CPU_Pop32(); + stack_flags = CPU_Pop32(); + // Push values for exception handler CPU_Push32(SegValue(ss)); CPU_Push32(reg_esp); - CPU_Push32(reg_flags); - CPU_Push32(SegValue(cs)); - CPU_Push32(reg_eip-2); // FIXME: Fake ! + CPU_Push32(stack_flags); + CPU_Push32(stack_cs); + CPU_Push32(stack_eip); CPU_Push32(errorCode); CPU_Push32(GDT_PROTCODE); // return cs CPU_Push32(DPMI_CB_EXCEPTIONRETURN_OFFSET); // return eip } else { + // Clean up stack + stack_eip = CPU_Pop16(); + stack_cs = CPU_Pop16(); + stack_flags = CPU_Pop16(); + // Push values for exception handler CPU_Push16(SegValue(ss)); CPU_Push16(reg_sp); - CPU_Push16(reg_flags); - CPU_Push16(SegValue(cs)); - CPU_Push16(reg_ip-2); // FIXME: Fake ! + CPU_Push16(stack_flags); + CPU_Push16(stack_cs); + CPU_Push16(stack_eip); CPU_Push16(errorCode); CPU_Push16(GDT_PROTCODE); // return cs CPU_Push16(DPMI_CB_EXCEPTIONRETURN_OFFSET); // return eip @@ -1720,8 +1741,6 @@ Bitu DPMI::Int31Handler(void) DPMI_CALLBACK_SCF(true); }; break; - DPMI_CALLBACK_SCF(false); - break; case 0x0204:{// Get Protected Mode Interrupt Vector SetDescriptor gate; if (dpmi.pharlap) { @@ -1739,20 +1758,9 @@ Bitu DPMI::Int31Handler(void) DPMI_LOG("DPMI: 0204: Get Prot Int Vector %02X (%04X:%08X)",reg_bl,reg_cx,reg_edx); DPMI_CALLBACK_SCF(false); }; break; - case 0x0205:{// Set Protected Mode Interrupt Vector - SetDescriptor gate; - gate.Clear(); - gate.saved.seg.p=1; - gate.SetSelector(reg_cx); - gate.SetOffset(Mask(reg_edx)); - gate.SetType(dpmi.client.bit32?DESC_386_INT_GATE:DESC_286_INT_GATE); - gate.saved.seg.dpl = DPMI_DPL; - gate.Save(dpmi.idt.base+reg_bl*8); - if (dpmi.pharlap) { - gate.Save(cpu.idt.GetBase()+reg_bl*8); - DPMI_LOG("DPMI: 0205: Pharlap: Set Prot Int Vector %02X (%04X:%08X)",reg_bl,reg_cx,reg_edx); - } else - DPMI_LOG("DPMI: 0205: Set Prot Int Vector %02X (%04X:%08X)",reg_bl,reg_cx,reg_edx); + case 0x0205:{// Set Protected Mode Interrupt Vector + DPMI_LOG("DPMI: 0205: Set Prot Int Vector %02X (%04X:%08X)",reg_bl,reg_cx,reg_edx); + SetProtInterrupt(reg_bl,reg_cx,reg_edx); DPMI_CALLBACK_SCF(false); }; break; case 0x0300:// Simulate Real Mode Interrupt @@ -2133,6 +2141,7 @@ Bitu DPMI::Int2fHandler(void) // Callbacks and Callback-Returns // ********************************************************************* +static Bitu DPMI_Exception(void) { if (activeDPMI) return activeDPMI->CreateException(); return 0;}; static Bitu DPMI_ExceptionReturn(void) { if (activeDPMI) return activeDPMI->ExceptionReturn(); return 0;}; static Bitu DPMI_RealModeCallback(void) { if (activeDPMI) return activeDPMI->RealModeCallback(); return 0;}; static Bitu DPMI_RealModeCallbackReturn(void) { if (activeDPMI) return activeDPMI->RealModeCallbackReturn(); return 0;}; @@ -2159,6 +2168,27 @@ static Bitu DPMI_API_Entry_MSDOS(void) { if (activeDPMI) return activeDPMI->AP // Setup stuff // **************************************************************** +bool DPMI::SetProtInterrupt(Bitu num, Bitu selector, Bitu offset) +{ + // Nobody messes with the div0 vector + if (num==0) return true; + + SetDescriptor gate; + gate.Clear(); + gate.saved.seg.p=1; + gate.SetSelector(selector); + gate.SetOffset (Mask(offset)); + gate.SetType (dpmi.client.bit32?DESC_386_INT_GATE:DESC_286_INT_GATE); + gate.saved.seg.dpl = DPMI_DPL; + gate.Save(dpmi.idt.base+num*8); + // Special Pharlap stuff + if (dpmi.pharlap) { + gate.Save(cpu.idt.GetBase()+num*8); + DPMI_LOG("DPMI: 0205: Pharlap: Set Prot Int Vector %02X (%04X:%08X)",reg_bl,reg_cx,reg_edx); + } + return true; +}; + RealPt DPMI::HookInterrupt(Bitu num, Bitu intHandler) { // Setup realmode hook @@ -2172,11 +2202,7 @@ RealPt DPMI::HookInterrupt(Bitu num, Bitu intHandler) } else E_Exit("DPMI: Couldnt allocate Realmode-Callback for INT %04X",num); // Setup protmode hook func = CALLBACK_RealPointer(intHandler); - SetDescriptor gate; - gate.Load (dpmi.idt.base+num*8); - gate.SetSelector(GDT_CODE); - gate.SetOffset (RealOff(func)); - gate.Save (dpmi.idt.base+num*8); + SetProtInterrupt(num,GDT_CODE,RealOff(func)); return oldVec; } @@ -2498,29 +2524,29 @@ void DPMI_Init(Section* sec) /* setup Real mode Callbacks */ callback.entry=CALLBACK_Allocate(); - CALLBACK_Setup(callback.entry,DPMI_EntryPoint,CB_RETF); + CALLBACK_Setup(callback.entry,DPMI_EntryPoint,CB_RETF,"Entrypoint"); callback.enterpmode=CALLBACK_Allocate(); - CALLBACK_Setup(callback.enterpmode,DPMI_EnterProtMode,CB_RETF); + CALLBACK_Setup(callback.enterpmode,DPMI_EnterProtMode,CB_RETF,"Enter PMode"); callback.realsavestate=CALLBACK_Allocate(); - CALLBACK_Setup(callback.realsavestate,DPMI_RealSaveState,CB_RETF); + CALLBACK_Setup(callback.realsavestate,DPMI_RealSaveState,CB_RETF,"Save RealState"); callback.simint=CALLBACK_Allocate(); - CALLBACK_Setup(callback.simint,DPMI_SimulateInt,CB_IRET); + CALLBACK_Setup(callback.simint,DPMI_SimulateInt,CB_IRET,"Sim INT"); callback.simintReturn=CALLBACK_Allocate(); - CALLBACK_Setup(callback.simintReturn,DPMI_SimulateIntReturn,CB_IRET); + CALLBACK_Setup(callback.simintReturn,DPMI_SimulateIntReturn,CB_IRET,"Sim INT RET"); callback.rmIntFrame=CALLBACK_Allocate(); - CALLBACK_Setup(callback.rmIntFrame,DPMI_CallRealIRETFrame,CB_IRET); + CALLBACK_Setup(callback.rmIntFrame,DPMI_CallRealIRETFrame,CB_IRET,"Call REAL IRET"); callback.rmIntFrameReturn=CALLBACK_Allocate(); - CALLBACK_Setup(callback.rmIntFrameReturn,DPMI_CallRealIRETFrameReturn,CB_IRET); + CALLBACK_Setup(callback.rmIntFrameReturn,DPMI_CallRealIRETFrameReturn,CB_IRET,"Call REAL IRET RET"); callback.ptorint=CALLBACK_Allocate(); - CALLBACK_Setup(callback.ptorint,DPMI_ptorHandler,CB_IRET); + CALLBACK_Setup(callback.ptorint,DPMI_ptorHandler,CB_IRET,"INT Handler"); callback.ptorintReturn=CALLBACK_Allocate(); - CALLBACK_Setup(callback.ptorintReturn,DPMI_ptorHandlerReturn,CB_IRET); + CALLBACK_Setup(callback.ptorintReturn,DPMI_ptorHandlerReturn,CB_IRET,"INT Handler RET"); callback.int21Return=CALLBACK_Allocate(); - CALLBACK_Setup(callback.int21Return,DPMI_Int21HandlerReturn,CB_IRET); + CALLBACK_Setup(callback.int21Return,DPMI_Int21HandlerReturn,CB_IRET,"INT 21 RET"); callback.rmCallbackReturn=CALLBACK_Allocate(); - CALLBACK_Setup(callback.rmCallbackReturn,DPMI_RealModeCallbackReturn,CB_IRET); + CALLBACK_Setup(callback.rmCallbackReturn,DPMI_RealModeCallbackReturn,CB_IRET,"RMCB RET"); callback.int21msdos=CALLBACK_Allocate(); - CALLBACK_Setup(callback.int21msdos,DPMI_API_Int21_MSDOS,CB_IRET); + CALLBACK_Setup(callback.int21msdos,DPMI_API_Int21_MSDOS,CB_IRET,"MSDOS INT 21 API"); /* Setup multiplex */ DOS_AddMultiplexHandler(DPMI_Multiplex); @@ -2639,46 +2665,52 @@ void DPMI::Setup() // Setup Hardware Interrupt handler for (i=0; i Date: Sun, 9 Nov 2003 16:44:27 +0000 Subject: [PATCH 1346/4131] Added callback descriptions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1427 --- include/callback.h | 5 +++-- src/cpu/callback.cpp | 24 +++++++++++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/include/callback.h b/include/callback.h index 9b083be6..e46a8ea3 100644 --- a/include/callback.h +++ b/include/callback.h @@ -47,9 +47,10 @@ void CALLBACK_Idle(void); void CALLBACK_RunRealInt(Bit8u intnum); void CALLBACK_RunRealFar(Bit16u seg,Bit16u off); -bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type); -bool CALLBACK_SetupAt(Bitu callback,CallBack_Handler handler,Bitu type,Bitu linearAddress); +bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* description=0); +bool CALLBACK_SetupAt(Bitu callback,CallBack_Handler handler,Bitu type,Bitu linearAddress, const char* description=0); +const char* CALLBACK_GetDescription(Bitu callback); bool CALLBACK_Free(Bitu callback); void CALLBACK_SCF(bool val); diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 1b553fba..9374f4bc 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,10 +16,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.16 2003-09-29 21:06:49 qbix79 Exp $ */ +/* $Id: callback.cpp,v 1.17 2003-11-09 16:44:07 finsterr Exp $ */ #include #include +#include #include "dosbox.h" #include "callback.h" @@ -34,6 +35,8 @@ CallBack_Handler CallBack_Handlers[CB_MAX]; +char* CallBack_Description[CB_MAX]; + static Bitu call_stop,call_idle,call_default; static Bitu illegal_handler(void) { @@ -117,9 +120,22 @@ void CALLBACK_SCF(bool val) { mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newCF)); }; +void CALLBACK_SetDescription(Bitu nr, const char* descr) +{ + if (descr) { + CallBack_Description[nr] = new char[strlen(descr)+1]; + strcpy(CallBack_Description[nr],descr); + } else + CallBack_Description[nr] = 0; +}; +const char* CALLBACK_GetDescription(Bitu nr) +{ + if (nr>=CB_MAX) return 0; + return CallBack_Description[nr]; +}; -bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type) { +bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* descr) { if (callback>=CB_MAX) return false; switch (type) { case CB_RETF: @@ -147,10 +163,11 @@ bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type) { } CallBack_Handlers[callback]=handler; + CALLBACK_SetDescription(callback,descr); return true; } -bool CALLBACK_SetupAt(Bitu callback,CallBack_Handler handler,Bitu type,Bitu linearAddress) { +bool CALLBACK_SetupAt(Bitu callback,CallBack_Handler handler,Bitu type,Bitu linearAddress,const char* descr) { if (callback>=CB_MAX) return false; switch (type) { case CB_RETF: @@ -176,6 +193,7 @@ bool CALLBACK_SetupAt(Bitu callback,CallBack_Handler handler,Bitu type,Bitu line E_Exit("CALLBACK:Setup:Illegal type %d",type); } CallBack_Handlers[callback]=handler; + CALLBACK_SetDescription(callback,descr); return true; } From aebbee499f7a207164afd263ada26570591d4737 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sun, 9 Nov 2003 16:45:08 +0000 Subject: [PATCH 1347/4131] Show callback descriptions in debugger Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1428 --- src/debug/debug.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 2d45ee5a..a6280edc 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1196,6 +1196,16 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) strcpy(curSelectorName,prefix); }; }; + // If it is a callback add additional info + pos = strstr(inst,"callback"); + if (pos) { + pos += 9; + Bitu nr = GetHexValue(pos,pos); + const char* descr = CALLBACK_GetDescription(nr); + if (descr) { + strcat(inst," ("); strcat(inst,descr); strcat(inst,")"); + } + }; return result; }; From 37f7aa5de5b47f6d6ca7e94f60e3e405999c0207 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 11 Nov 2003 08:15:52 +0000 Subject: [PATCH 1348/4131] Fix opcode group 6 Fix POP R/M have to change sp before the r/m lookup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1429 --- src/cpu/core_normal/prefix_0f.h | 2 +- src/cpu/core_normal/prefix_66.h | 5 +++-- src/cpu/core_normal/prefix_66_0f.h | 2 +- src/cpu/core_normal/prefix_none.h | 5 +++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index d08a2a36..85945dce 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -36,7 +36,6 @@ Bitu loadval; if (rm >= 0xc0 ) {GetEArw;loadval=*earw;} else {GetEAa;loadval=LoadMw(eaa);} - break; switch (which) { case 0x02:CPU_LLDT(loadval);break; case 0x03:CPU_LTR(loadval);break; @@ -44,6 +43,7 @@ case 0x05:CPU_VERW(loadval);break; } } + break; default: LOG(LOG_CPU,LOG_ERROR)("GRP6:Illegal call %2X",which); } diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index cd0b2ee4..397f4f09 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -307,9 +307,10 @@ } CASE_D(0x8f) /* POP Ed */ { + Bit32u val=Pop_32(); GetRM; - if (rm >= 0xc0 ) {GetEArd;*eard=Pop_32();} - else {GetEAa;SaveMd(eaa,Pop_32());} + if (rm >= 0xc0 ) {GetEArd;*eard=val;} + else {GetEAa;SaveMd(eaa,val);} break; } CASE_D(0x91) /* XCHG ECX,EAX */ diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 02c1102d..5ce7dc65 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -36,7 +36,6 @@ Bitu loadval; if (rm >= 0xc0 ) {GetEArw;loadval=*earw;} else {GetEAa;loadval=LoadMw(eaa);} - break; switch (which) { case 0x02:CPU_LLDT(loadval);break; case 0x03:CPU_LTR(loadval);break; @@ -44,6 +43,7 @@ case 0x05:CPU_VERW(loadval);break; } } + break; default: LOG(LOG_CPU,LOG_ERROR)("GRP6:Illegal call %2X",which); } diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 913058b7..bd44cbe7 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -511,9 +511,10 @@ } CASE_W(0x8f) /* POP Ew */ { + Bit16u val=Pop_16(); GetRM; - if (rm >= 0xc0 ) {GetEArw;*earw=Pop_16();} - else {GetEAa;SaveMw(eaa,Pop_16());} + if (rm >= 0xc0 ) {GetEArw;*earw=val;} + else {GetEAa;SaveMw(eaa,val);} break; } CASE_B(0x90) /* NOP */ From fdc23c8e0412c2c53a76a6cbd24e3de74e3ed334 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 11 Nov 2003 18:28:05 +0000 Subject: [PATCH 1349/4131] added some undocumented aliases Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1430 --- src/fpu/fpu.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index cb7b87e9..dbc20d20 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu.cpp,v 1.14 2003-10-19 19:21:12 qbix79 Exp $ */ +/* $Id: fpu.cpp,v 1.15 2003-11-11 18:28:05 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU @@ -260,6 +260,13 @@ void FPU_ESC1_Normal(Bitu rm) { case 0x01: /* FXCH STi */ FPU_FXCH(TOP,ST(sub)); break; + case 0x02: /* FNOP */ + FPU_FNOP(); + break; + case 0x03: /* FSTP STi */ + FPU_FST(TOP,ST(sub)); + FPU_FPOP(); + break; case 0x04: switch(sub){ case 0x00: /* FCHS */ @@ -661,6 +668,14 @@ void FPU_ESC7_Normal(Bitu rm) { Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); switch (group){ + case 0x01: /* FXCH STi*/ + FPU_FXCH(TOP,ST(sub)); + break; + case 0x02: /* FSTP STi*/ + case 0x03: /* FSTP STi*/ + FPU_FST(TOP,ST(sub)); + FPU_FPOP(); + break; case 0x04: switch(sub){ case 0x00: /* FNSTSW AX*/ From a03d87e551d56f54f2edf1136dbd00b11f8e8e6b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 11 Nov 2003 18:47:25 +0000 Subject: [PATCH 1350/4131] Added patch 829954 from James Wilkinson Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1431 --- src/shell/shell_cmds.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 543c8f3f..f942c2e8 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.34 2003-10-21 18:18:01 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.35 2003-11-11 18:47:25 qbix79 Exp $ */ #include @@ -252,7 +252,7 @@ void DOS_Shell::CMD_DIR(char * args) { char buffer[CROSS_LEN]; args = trim(args); - int argLen = strlen(args); + Bit32u argLen = strlen(args); if (argLen == 0) { strcpy(args,"*.*"); //no arguments. } else { @@ -262,16 +262,22 @@ void DOS_Shell::CMD_DIR(char * args) { case ':' : // handle C:, etc. strcat(args,"*.*"); break; - case '*': // handle *, \*, C:\*, etc. - // (not ideal - could end up *.*.*, but that'll net the same result) - strcat(args,".*"); - break; default: break; } } args = ExpandDot(args,buffer); + if (!strrchr(args,'*') && !strrchr(args,'?')) { + Bit16u attribute=0; + if(DOS_GetFileAttr(args,&attribute) && (attribute&DOS_ATTR_DIRECTORY) ) { + strcat(args,"\\*.*"); // if no wildcard and a directory, get its files + } + } + if (!strrchr(args,'.')) { + strcat(args,".*"); // if no extension, get them all + } + /* Make a full path in the args */ if (!DOS_Canonicalize(args,path)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); From 1eef79ef64c320ec1b6546331873f389af8544c0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 11 Nov 2003 20:20:02 +0000 Subject: [PATCH 1351/4131] Made the window the right size Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1432 --- src/debug/debug_gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 840233ce..11105712 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -216,7 +216,7 @@ void DBGUI_StartUp(void) { nodelay(dbg.win_main,true); keypad(dbg.win_main,true); #ifndef WIN32 - resizeterm(50,80); + resizeterm(50,81); touchwin(dbg.win_main); old_cursor_state = curs_set(0); #endif From c4269952c4fef27d21aab64ad977fdb16973c607 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 12 Nov 2003 07:16:46 +0000 Subject: [PATCH 1352/4131] Increase the line cache size Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1433 --- src/gui/render_normal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/render_normal.h b/src/gui/render_normal.h index 860acac3..1c87ade1 100644 --- a/src/gui/render_normal.h +++ b/src/gui/render_normal.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -static Bit8u normal_cache[RENDER_MAXWIDTH*2]; +static Bit8u normal_cache[RENDER_MAXWIDTH*2*4]; template static void Normal(Bit8u * src,Bitu x,Bitu y,Bitu _dx,Bitu _dy) { From 81b197a1cb9b9265e3277b901fa26f27d76903dc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 12 Nov 2003 13:27:39 +0000 Subject: [PATCH 1353/4131] fixed a bug switching too many times to fullscreen Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1434 --- src/gui/sdlmain.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 44c1b0ec..d5ac3c4e 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.53 2003-11-08 10:09:52 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.54 2003-11-12 13:27:39 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -776,7 +776,9 @@ int main(int argc, char* argv[]) { } #endif if (control->cmdline->FindExist("-fullscreen") || sdl_sec->Get_bool("fullscreen")) { - SwitchFullScreen(); + if(!sdl.desktop.fullscreen) { //only switch if not allready in fullscreen + SwitchFullScreen(); + } } /* Start up main machine */ control->StartUp(); From 670173ebc491b035ce55c2b06ef33a11b67a937f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 13 Nov 2003 22:49:10 +0000 Subject: [PATCH 1354/4131] added 32-bit btr opcode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1435 --- src/cpu/core_normal/prefix_66_0f.h | 37 +++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 5ce7dc65..2b578bdc 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -206,6 +206,32 @@ CASE_0F_D(0xad) /* SHRD Ed,Gd,CL */ RMEdGdOp3(DSHRD,reg_cl); break; + CASE_0F_D(0xaf) /* IMUL Gd,Ed */ + { + RMGdEdOp3(DIMULD,*rmrd); + break; + } + CASE_0F_D(0xb2) /* LSS Ed */ + { + GetRMrd;GetEAa; + *rmrd=LoadMd(eaa);CPU_SetSegGeneral(ss,LoadMw(eaa+4)); + break; + } + CASE_0F_D(0xb3) /* BTR Ed,Gd */ + { + FillFlags();GetRMrd; + Bit32u mask=1 << (*rmrd & 31); + if (rm >= 0xc0 ) { + GetEArd; + SETFLAGBIT(CF,(*eard & mask)); + *eard&= ~mask; + } else { + GetEAa;Bit32u old=LoadMd(eaa); + SETFLAGBIT(CF,(old & mask)); + SaveMd(eaa,old & ~mask); + } + break; + } CASE_0F_D(0xb4) /* LFS Ed */ { GetRMrd;GetEAa; @@ -225,17 +251,6 @@ else {GetEAa;*rmrd=LoadMb(eaa);} break; } - CASE_0F_D(0xaf) /* IMUL Gd,Ed */ - { - RMGdEdOp3(DIMULD,*rmrd); - break; - } - CASE_0F_D(0xb2) /* LSS Ed */ - { - GetRMrd;GetEAa; - *rmrd=LoadMd(eaa);CPU_SetSegGeneral(ss,LoadMw(eaa+4)); - break; - } CASE_0F_D(0xb7) /* MOVXZ Gd,Ew */ { GetRMrd; From b6a4b0fb5ce26206a535256afe62e9b8ee735201 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 14 Nov 2003 00:01:56 +0000 Subject: [PATCH 1355/4131] new function to zero the reported extended memory size Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1436 --- include/bios.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/bios.h b/include/bios.h index ef37fa88..61632b69 100644 --- a/include/bios.h +++ b/include/bios.h @@ -114,6 +114,7 @@ private: }; +void BIOS_ZeroExtendedSize(void); void char_out(Bit8u chr,Bit32u att,Bit8u page); void INT10_StartUp(void); void INT16_StartUp(void); From 8f5af81299bdd4aea6270c6c07012efbea6aa266 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 14 Nov 2003 00:04:27 +0000 Subject: [PATCH 1356/4131] zero reported extended memory size if xms/ems/dpmi is loaded Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1437 --- src/ints/bios.cpp | 18 +++++++++++++----- src/ints/dpmi.cpp | 2 ++ src/ints/ems.cpp | 1 + src/ints/xms.cpp | 3 ++- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 63b65afd..00d6c78b 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.22 2003-09-30 13:49:34 finsterr Exp $ */ +/* $Id: bios.cpp,v 1.23 2003-11-14 00:04:25 harekiet Exp $ */ #include #include "dosbox.h" @@ -30,6 +30,7 @@ static Bitu call_int1a,call_int11,call_int8,call_int17,call_int12,call_int15,call_int1c; static Bitu call_int1,call_int70; +static Bit16u size_extended; static Bitu INT70_Handler(void) { /* Acknowledge irq with cmos */ @@ -243,10 +244,7 @@ static Bitu INT15_Handler(void) { break; } case 0x88: /* SYSTEM - GET EXTENDED MEMORY SIZE (286+) */ - IO_Write(0x70,0x30); - reg_al=IO_Read(0x71); - IO_Write(0x70,0x31); - reg_ah=IO_Read(0x71); + reg_ax=size_extended; LOG(LOG_BIOS,LOG_NORMAL)("INT15:Function 0x88 Remaining %04X kb",reg_ax); CALLBACK_SCF(false); break; @@ -284,6 +282,10 @@ static Bitu INT1_Single_Step(void) { return CBRET_NONE; } +void BIOS_ZeroExtendedSize(void) { + size_extended=0; +} + void BIOS_SetupKeyboard(void); void BIOS_SetupDisks(void); @@ -353,6 +355,12 @@ void BIOS_Init(Section* sec) { #else mem_writew(BIOS_CONFIGURATION,0xc821); //1 Floppy,FPU,2 serial, 1 parallel #endif + /* Setup extended memory size */ + IO_Write(0x70,0x30); + size_extended=IO_Read(0x71); + IO_Write(0x70,0x31); + size_extended|=(IO_Read(0x71) << 8); + } diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index 92029586..13a47707 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -37,6 +37,7 @@ #include "setup.h" #include "inout.h" #include "cpu.h" +#include "bios.h" #include "paging.h" #include "debug.h" @@ -2520,6 +2521,7 @@ void DPMI_Init(Section* sec) Section_prop * section=static_cast(sec); if (!section->Get_bool("dpmi")) return; + BIOS_ZeroExtendedSize(); memset(&callback,0,sizeof(callback)); /* setup Real mode Callbacks */ diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 6efb5131..5f4d753c 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -583,6 +583,7 @@ static Bitu INT67_Handler(void) { void EMS_Init(Section* sec) { Section_prop * section=static_cast(sec); if (!section->Get_bool("ems")) return; + BIOS_ZeroExtendedSize(); call_int67=CALLBACK_Allocate(); CALLBACK_Setup(call_int67,&INT67_Handler,CB_IRET); /* Register the ems device */ diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index f610ef94..a02177c6 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -26,6 +26,7 @@ #include "setup.h" #include "inout.h" #include "xms.h" +#include "bios.h" #define XMS_HANDLES 50 /* 50 XMS Memory Blocks */ #define XMS_VERSION 0x0300 /* version 3.00 */ @@ -334,7 +335,7 @@ void XMS_Init(Section* sec) { Section_prop * section=static_cast(sec); if (!section->Get_bool("xms")) return; Bitu i; - + BIOS_ZeroExtendedSize(); DOS_AddMultiplexHandler(multiplex_xms); call_xms=CALLBACK_Allocate(); CALLBACK_Setup(call_xms,&XMS_Handler,CB_RETF); From 57a32fa94e13064da7b7f5a320cedb4b356b9c43 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 18 Nov 2003 20:46:01 +0000 Subject: [PATCH 1357/4131] Runrealint uses a table with 0xcd 0x00-0xff instructions now Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1438 --- src/cpu/callback.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 9374f4bc..e5a94cc0 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.17 2003-11-09 16:44:07 finsterr Exp $ */ +/* $Id: callback.cpp,v 1.18 2003-11-18 20:46:01 harekiet Exp $ */ #include #include @@ -98,9 +98,8 @@ void CALLBACK_RunRealFar(Bit16u seg,Bit16u off) { void CALLBACK_RunRealInt(Bit8u intnum) { Bit32u oldeip=reg_eip; Bit16u oldcs=SegValue(cs); - reg_eip=call_stop<<4; + reg_eip=(CB_MAX*16)+(intnum*6); SegSet16(cs,CB_SEG); - Interrupt(intnum); DOSBOX_RunMachine(); reg_eip=oldeip; SegSet16(cs,oldcs); @@ -223,6 +222,17 @@ void CALLBACK_Init(Section* sec) { for (i=0;i<0x40;i++) { real_writed(0,i*4,CALLBACK_RealPointer(call_default)); } + /* Setup block of 0xCD 0xxx instructions */ + PhysPt rint_base=CB_BASE+CB_MAX*16; + for (i=0;i<=0xff;i++) { + phys_writeb(rint_base,0xCD); + phys_writeb(rint_base+1,i); + phys_writeb(rint_base+2,0xFE); + phys_writeb(rint_base+3,0x38); + phys_writew(rint_base+4,call_stop); + rint_base+=6; + + } real_writed(0,0x67*4,CALLBACK_RealPointer(call_default)); //real_writed(0,0xf*4,0); some games don't like it } From 01bdd5f6f76b2760f84d6fd37db5df8970a5b475 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 18 Nov 2003 20:49:44 +0000 Subject: [PATCH 1358/4131] Added v86 mode detection Added better breaking of current code to enter debugger Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1439 --- src/debug/debug.cpp | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index a6280edc..92486fef 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -111,9 +111,14 @@ Bit32u PhysMakeProt(Bit16u selector, Bit32u offset) Bit32u GetAddress(Bit16u seg, Bit32u offset) { - if (cpu.pmode) return PhysMakeProt(seg,offset); + if (seg==SegValue(cs)) return SegPhys(cs)+offset; + if (cpu.pmode) { + Descriptor desc; + if (cpu.gdt.GetDescriptor(seg,desc)) return PhysMakeProt(seg,offset); + } return (seg<<4)+offset; -}; +} + bool GetDescriptorInfo(char* selname, char* out1, char* out2) { @@ -641,8 +646,9 @@ static void DrawRegisters(void) { oldflags=reg_flags; if (cpu.pmode) { - if (cpu.code.big) mvwprintw(dbg.win_reg,0,76,"Pr32"); - else mvwprintw(dbg.win_reg,0,76,"Pr16"); + if (reg_flags & FLAG_VM) mvwprintw(dbg.win_reg,0,76,"VM86"); + else if (cpu.code.big) mvwprintw(dbg.win_reg,0,76,"Pr32"); + else mvwprintw(dbg.win_reg,0,76,"Pr16"); } else mvwprintw(dbg.win_reg,0,76,"Real"); @@ -1020,7 +1026,7 @@ bool ParseCommand(char* str) found+=4; Bit8u intNr = (Bit8u)GetHexValue(found,found); DEBUG_ShowMsg("DEBUG: Tracing INT %02X",intNr); - Interrupt(intNr); + CPU_HW_Interrupt(intNr); SetCodeWinStart(); return true; } @@ -1034,7 +1040,7 @@ bool ParseCommand(char* str) debugging=false; DrawCode(); DOSBOX_SetNormalLoop(); - Interrupt(intNr); + CPU_HW_Interrupt(intNr); return true; } found = strstr(str,"SELINFO "); @@ -1156,7 +1162,7 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) pos++; }; Bit32u address = GetAddress(seg,adr); - if (address> 12]->flags & PFLAG_ILLEGAL)) { static char outmask[] = "%s:[%04X]=%02X"; if (cpu.pmode) outmask[6] = '8'; @@ -1236,7 +1242,7 @@ Bit32u DEBUG_CheckKeys(void) { }; int key=getch(); - Bit32u ret=0; + Bits ret=0; if (key>0) { switch (toupper(key)) { case '1': @@ -1321,7 +1327,6 @@ Bit32u DEBUG_CheckKeys(void) { skipFirstInstruction = true; // for heavy debugger CPU_Cycles = 1; Bitu ret=(*cpudecoder)(); - if (ret>0) ret=(*CallBack_Handlers[ret])(); SetCodeWinStart(); CBreakpoint::ignoreOnce = 0; } @@ -1331,11 +1336,20 @@ Bit32u DEBUG_CheckKeys(void) { skipFirstInstruction = true; // for heavy debugger CPU_Cycles = 1; ret = (*cpudecoder)(); - if (ret>0) ret=(*CallBack_Handlers[ret])(); SetCodeWinStart(); CBreakpoint::ignoreOnce = 0; break; } + if (ret<0) return ret; + if (ret>0){ + ret=(*CallBack_Handlers[ret])(); + if (ret) { + exitLoop=true; + CPU_Cycles=CPU_CycleLeft=0; + return ret; + } + } + ret=0; DEBUG_DrawScreen(); } return ret; @@ -1497,6 +1511,7 @@ Bitu DEBUG_EnableDebugger(void) { exitLoop = true; DEBUG_Enable(); + CPU_Cycles=CPU_CycleLeft=0; return 0; }; From db195c0ad1b4be01fdcf23022f4c914cf63518eb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 18 Nov 2003 20:50:26 +0000 Subject: [PATCH 1359/4131] Changed exit loop to always check after a cpu core has run Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1440 --- src/dosbox.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 22903502..a518deb7 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -111,10 +111,10 @@ static Bitu Normal_Loop(void) { if (ret>0) { Bitu blah=(*CallBack_Handlers[ret])(); if (blah) return blah; -#if C_DEBUG - if (DEBUG_ExitLoop()) return 0; -#endif } +#if C_DEBUG + if (DEBUG_ExitLoop()) return 0; +#endif } else { if (RemainTicks>0) { TIMER_AddTick(); @@ -222,9 +222,13 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("cpu",&CPU_Init); secprop->Add_int("cycles",1800); + secprop->Add_int("cycleup",500); + secprop->Add_int("cycledown",20); MSG_Add("CPU_CONFIGFILE_HELP", "cycles -- Amount of instructions dosbox tries to emulate each millsecond.\n" " Setting this higher than your machine can handle is bad!\n" + "cycleup -- Amount of cycles to increase/decrease with keycombo.\n" + "cycledown Setting it lower than 100 will be a percentage.\n" ); #if C_FPU secprop->AddInitFunction(&FPU_Init); From d46d87c72f7c83dfd559e290b651ca878aa07256 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 18 Nov 2003 20:51:55 +0000 Subject: [PATCH 1360/4131] changed some flag masks for different privilege levels Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1441 --- include/regs.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/include/regs.h b/include/regs.h index 35981184..15d32e46 100644 --- a/include/regs.h +++ b/include/regs.h @@ -26,22 +26,27 @@ #define FLAG_AF 0x00000010 #define FLAG_ZF 0x00000040 #define FLAG_SF 0x00000080 +#define FLAG_OF 0x00000800 + #define FLAG_TF 0x00000100 #define FLAG_IF 0x00000200 #define FLAG_DF 0x00000400 -#define FLAG_OF 0x00000800 - -#define FLAG_MASK (FLAG_CF | FLAG_PF | FLAG_AF | FLAG_ZF | FLAG_SF | FLAG_OF) #define FLAG_IOPL 0x00003000 #define FLAG_NT 0x00004000 #define FLAG_VM 0x00020000 +#define 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) +#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 { Bit16u val; PhysPt phys; /* The phyiscal address start in emulated machine */ From 22c885b09f8cda0592b95f3bd408c8277ac3d1de Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 18 Nov 2003 20:52:35 +0000 Subject: [PATCH 1361/4131] New cr2 registers and physical memory reading function Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1442 --- include/paging.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/paging.h b/include/paging.h index 5fbbfd41..a5b9930f 100644 --- a/include/paging.h +++ b/include/paging.h @@ -67,6 +67,9 @@ void MEM_SetLFB(Bitu _page,Bitu _pages,HostPt _pt); void MEM_SetPageHandler(Bitu phys_page,Bitu pages,PageHandler * handler); void MEM_UnlinkPages(void); +Bit32u MEM_PhysReadD(Bitu addr); + + #pragma pack(1) @@ -92,6 +95,7 @@ union X86PageEntry { struct PagingBlock { Bitu cr3; + Bitu cr2; struct { Bitu page; PhysPt addr; From ab8c33523002bd563399cbb4954a03f81023d1d0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 18 Nov 2003 22:07:51 +0000 Subject: [PATCH 1362/4131] use the new flag masks Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1443 --- src/ints/dpmi.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index 13a47707..fe66ceae 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -972,7 +972,7 @@ Bitu DPMI::SimulateInt(void) // Push flags from structure on stack DPMI_LOG("DPMI: SimInt1: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_esp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); reg_flags = mem_readw(data+0x20); - Interrupt(num); + CPU_SW_Interrupt(num,0); DPMI_LOG("DPMI: SimInt2: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_esp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); return 0; }; @@ -1034,7 +1034,7 @@ Bitu DPMI::ptorHandler(void) DPMI_LOG("DPMI: INT %02X %04X called.",num,reg_ax); // Prepare flags for real int // CPU_SetFlagsw(reg_flags & 0x3ED5); // 0011111011010101b - Interrupt(num); + CPU_SW_Interrupt(num,0); return 0; } @@ -1060,12 +1060,12 @@ Bitu DPMI::ptorHandlerReturn(void) } // Change flags on stack to reflect possible results from ints if (dpmi.client.bit32) { - Bit32u oldFlags = mem_readd(SegPhys(ss)+reg_esp+8) & ~FLAG_MASK;// leave only flags that cannot be changed by int - Bit32u userFlags = reg_flags & FLAG_MASK; // Mask out illegal flags not to change by int (0011111011010101b) + Bit32u oldFlags = mem_readd(SegPhys(ss)+reg_esp+8) & ~FMASK_NORMAL; // leave only flags that cannot be changed by int + Bit32u userFlags = reg_flags & FMASK_NORMAL; // Mask out illegal flags not to change by int (0011111011010101b) mem_writed(SegPhys(ss)+reg_esp+8,oldFlags|userFlags); } else { - Bit16u oldFlags = mem_readw(SegPhys(ss)+reg_sp+4) & ~FLAG_MASK; // leave only flags that cannot be changed by int - Bit16u userFlags = reg_flags & FLAG_MASK; // Mask out illegal flags not to change by int (0011111011010101b) + Bit16u oldFlags = mem_readw(SegPhys(ss)+reg_sp+4) & ~FMASK_NORMAL; // leave only flags that cannot be changed by int + Bit16u userFlags = reg_flags & FMASK_NORMAL; // Mask out illegal flags not to change by int (0011111011010101b) mem_writew(SegPhys(ss)+reg_sp+4,oldFlags|userFlags); }; SetVirtualIntFlag(true); @@ -1097,7 +1097,7 @@ Bitu DPMI::Int21Handler(void) reg_esp = rm_sp; // Call realmode interrupt DPMI_LOG("DPMI: INT 21 %04X called.",reg_ax); - Interrupt(0x21); + CPU_SW_Interrupt(0x21,0); if (reg_ah==0x4C) { // Shut doen dpmi and restore previous one delete this; From 69374f45bcb8c0faf36374175aefc8fbe0b35f81 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 18 Nov 2003 22:15:51 +0000 Subject: [PATCH 1363/4131] changed some functions to allow exceptions. Changed the task segment stuff Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1444 --- include/cpu.h | 170 +++++++++++++++++++++++--------------------------- 1 file changed, 77 insertions(+), 93 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 90ae88ef..2de0a508 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -65,44 +65,30 @@ void CPU_JMP(bool use32,Bitu selector,Bitu offset); void CPU_CALL(bool use32,Bitu selector,Bitu offset); void CPU_RET(bool use32,Bitu bytes); -#define CPU_INT_HARDWARE 0x1 +#define CPU_INT_SOFTWARE 0x1 #define CPU_INT_HAS_ERROR 0x2 void CPU_Interrupt(Bitu num,Bitu error_code,Bitu type); INLINE void CPU_HW_Interrupt(Bitu num) { - CPU_Interrupt(num,0,CPU_INT_HARDWARE); -} -INLINE void CPU_SW_Interrupt(Bitu num) { CPU_Interrupt(num,0,0); } -void CPU_Exception(Bitu num,Bitu error_code=0); - -INLINE void Interrupt(Bitu num) { - CPU_SW_Interrupt(num); +INLINE void CPU_SW_Interrupt(Bitu num,Bitu oplen) { + CPU_Interrupt(num,oplen,CPU_INT_SOFTWARE); } +void CPU_Exception(Bitu num,Bitu error_code=0); void CPU_IRET(bool use32); void CPU_SetSegGeneral(SegNames seg,Bitu value); void CPU_CPUID(void); -void CPU_HLT(void); +void CPU_HLT(Bitu oplen); Bitu CPU_Pop16(void); Bitu CPU_Pop32(void); void CPU_Push16(Bitu value); void CPU_Push32(Bitu value); -void CPU_SetFlags(Bitu word); - -INLINE void CPU_SetFlagsd(Bit32u word) { - CPU_SetFlags(word); -}; - -INLINE void CPU_SetFlagsw(Bit16u word) { - CPU_SetFlags((cpu_regs.flags&0xffff0000)|word); -}; - - +void CPU_SetFlags(Bitu word,Bitu mask); // ********************************************************************* // Descriptor @@ -151,32 +137,6 @@ INLINE void CPU_SetFlagsw(Bit16u word) { #define DESC_CODE_R_C_A 0x1e #define DESC_CODE_R_C_NA 0x1f -#pragma pack(1) -/* TSS Struct from Bochs - http://bochs.sf.net */ -struct TSS_386 { - Bit16u back, RESERVED0; /* Backlink */ - Bit32u esp0; /* The CK stack pointer */ - Bit16u ss0, RESERVED1; /* The CK stack selector */ - Bit32u esp1; /* The parent KL stack pointer */ - Bit16u ss1, RESERVED2; /* The parent KL stack selector */ - Bit32u esp2; /* Unused */ - Bit16u ss2, RESERVED3; /* Unused */ - Bit32u cr3; /* The page directory pointer */ - Bit32u eip; /* The instruction pointer */ - Bit32u eflags; /* The flags */ - Bit32u eax, ecx, edx, ebx; /* The general purpose registers */ - Bit32u esp, ebp, esi, edi; /* The special purpose registers */ - Bit16u es, RESERVED4; /* The extra selector */ - Bit16u cs, RESERVED5; /* The code selector */ - Bit16u ss, RESERVED6; /* The application stack selector */ - Bit16u ds, RESERVED7; /* The data selector */ - Bit16u fs, RESERVED8; /* And another extra selector */ - Bit16u gs, RESERVED9; /* ... and another one */ - Bit16u ldt, RESERVED10; /* The local descriptor table */ - Bit16u trap; /* The trap flag (for debugging) */ - Bit16u io; /* The I/O Map base address */ -} GCC_ATTRIBUTE(packed); - struct S_Descriptor { #ifdef WORDS_BIGENDIAN Bit32u base_0_15 :16; @@ -229,55 +189,49 @@ struct G_Descriptor { #endif } GCC_ATTRIBUTE(packed); -#pragma pack() - - -struct TaskSegment_32 { - Bit32u esp0; /* The CK stack pointer */ - Bit32u esp1; /* The parent KL stack pointer */ - Bit32u esp2; /* Unused */ - Bit32u cr3; /* The page directory pointer */ - Bit32u eip; /* The instruction pointer */ - Bit32u eflags; /* The flags */ - Bit32u eax, ecx, edx, ebx; /* The general purpose registers */ - Bit32u esp, ebp, esi, edi; /* The special purpose registers */ - Bit16u back; /* Backlink */ +struct TSS_16 { + Bit16u back; /* Back link to other task */ + Bit16u sp0; /* The CK stack pointer */ Bit16u ss0; /* The CK stack selector */ + Bit16u sp1; /* The parent KL stack pointer */ Bit16u ss1; /* The parent KL stack selector */ + Bit16u sp2; /* Unused */ Bit16u ss2; /* Unused */ + Bit16u ip; /* The instruction pointer */ + Bit16u flags; /* The flags */ + Bit16u ax, cx, dx, bx; /* The general purpose registers */ + Bit16u sp, bp, si, di; /* The special purpose registers */ Bit16u es; /* The extra selector */ Bit16u cs; /* The code selector */ Bit16u ss; /* The application stack selector */ Bit16u ds; /* The data selector */ - Bit16u fs; /* And another extra selector */ - Bit16u gs; /* ... and another one */ Bit16u ldt; /* The local descriptor table */ - Bit16u trap; /* The trap flag (for debugging) */ - Bit16u io; /* The I/O Map base address */ -}; +} GCC_ATTRIBUTE(packed); -void CPU_ReadTaskSeg32(PhysPt base,TaskSegment_32 * seg); +struct TSS_32 { + Bit32u back; /* Back link to other task */ + Bit32u esp0; /* The CK stack pointer */ + Bit32u ss0; /* The CK stack selector */ + Bit32u esp1; /* The parent KL stack pointer */ + Bit32u ss1; /* The parent KL stack selector */ + Bit32u esp2; /* Unused */ + Bit32u ss2; /* Unused */ + Bit32u cr3; /* The page directory pointer */ + Bit32u eip; /* The instruction pointer */ + Bit32u eflags; /* The flags */ + Bit32u eax, ecx, edx, ebx; /* The general purpose registers */ + Bit32u esp, ebp, esi, edi; /* The special purpose registers */ + Bit32u es; /* The extra selector */ + Bit32u cs; /* The code selector */ + Bit32u ss; /* The application stack selector */ + Bit32u ds; /* The data selector */ + Bit32u fs; /* And another extra selector */ + Bit32u gs; /* ... and another one */ + Bit32u ldt; /* The local descriptor table */ +} GCC_ATTRIBUTE(packed); + +#pragma pack() -class TaskStateSegment -{ -public: - bool Get_ss_esp(Bitu which,Bitu & _ss,Bitu & _esp) { - PhysPt reader=seg_base+offsetof(TSS_386,esp0)+which*8; - _esp=mem_readd(reader); - _ss=mem_readw(reader+4); - return true; - } - bool Get_cr3(Bitu which,Bitu & _cr3) { - _cr3=mem_readd(seg_base+offsetof(TSS_386,cr3));; - return true; - } - -private: - PhysPt seg_base; - Bitu seg_limit; - Bitu seg_value; -}; - class Descriptor { public: @@ -347,7 +301,7 @@ protected: class GDTDescriptorTable : public DescriptorTable { public: - bool GetDescriptor (Bitu selector, Descriptor& desc) { + bool GetDescriptor(Bitu selector, Descriptor& desc) { Bitu address=selector & ~7; if (selector & 4) { if (address>=ldt_limit) return false; @@ -359,7 +313,18 @@ public: return true; } } - + bool SetDescriptor(Bitu selector, Descriptor& desc) { + Bitu address=selector & ~7; + if (selector & 4) { + if (address>=ldt_limit) return false; + desc.Save(ldt_base+address); + return true; + } else { + if (address>=table_limit) return false; + desc.Save(table_base+address); + return true; + } + } Bitu SLDT(void) { return ldt_value; } @@ -378,18 +343,27 @@ private: Bitu ldt_value; }; +class TSS_Descriptor : public Descriptor { +public: + Bitu IsBusy(void) { + return saved.seg.type & 2; + } + Bitu Is386(void) { + return saved.seg.type & 8; + } + void SetBusy(bool busy) { + if (busy) saved.seg.type|=2; + else saved.seg.type&=~2; + } +}; + + struct CPUBlock { Bitu cpl; /* Current Privilege */ Bitu cr0; - bool v86; /* Are we in a v86 task */ bool pmode; /* Is Protected mode enabled */ GDTDescriptorTable gdt; DescriptorTable idt; - struct { - Bit16u val; - PhysPt base; - Bitu type; - } tr; struct { Bitu mask; bool big; @@ -405,5 +379,15 @@ struct CPUBlock { extern CPUBlock cpu; +INLINE void CPU_SetFlagsd(Bitu word) { + Bitu mask=cpu.cpl ? FMASK_NORMAL : FMASK_ALL; + CPU_SetFlags(word,mask); +}; + +INLINE void CPU_SetFlagsw(Bitu word) { + Bitu mask=(cpu.cpl ? FMASK_NORMAL : FMASK_ALL) & 0xffff; + CPU_SetFlags(word,mask); +}; + #endif From e23e7206e58ef6f1c9d5f432d10e2e853926a2e2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 18 Nov 2003 22:17:25 +0000 Subject: [PATCH 1364/4131] removed the physical page read function Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1445 --- include/mem.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/mem.h b/include/mem.h index 2c1bc990..ad483275 100644 --- a/include/mem.h +++ b/include/mem.h @@ -128,7 +128,6 @@ void phys_writew(PhysPt addr,Bit16u val); void phys_writed(PhysPt addr,Bit32u val); /* These don't check for alignment, better be sure it's correct */ -Bit32u phys_page_readd(Bitu page,Bitu off); void MEM_BlockWrite(PhysPt pt,void * data,Bitu size); void MEM_BlockRead(PhysPt pt,void * data,Bitu size); From f854f9a58c918651792cceaa889c3aec7ab9e08a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 18 Nov 2003 22:20:10 +0000 Subject: [PATCH 1365/4131] Some kind of pagefault implementation Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1446 --- src/cpu/paging.cpp | 90 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 4 deletions(-) diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 6d777b72..b68538a9 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -24,6 +24,9 @@ #include "mem.h" #include "paging.h" #include "regs.h" +#include "lazyflags.h" +#include "cpu.h" +#include "debug.h" #define LINK_TOTAL (64*1024) @@ -67,9 +70,64 @@ HostPt PageHandler::GetHostPt(Bitu phys_page) { } +Bits Full_DeCode(void); +struct PF_Entry { + Bitu cs; + Bitu eip; + Bitu page_addr; +}; + +#define PF_QUEUESIZE 16 +struct { + Bitu used; + PF_Entry entries[PF_QUEUESIZE]; +} pf_queue; + +static Bits PageFaultCore(void) { + CPU_CycleLeft+=CPU_Cycles; + CPU_Cycles=1; + Bitu ret=Full_DeCode(); + CPU_CycleLeft+=CPU_Cycles; + if (ret<0) E_Exit("Got a dosbox close machine in pagefault core?"); + if (ret) + return ret; + if (!pf_queue.used) E_Exit("PF Core without PF"); + PF_Entry * entry=&pf_queue.entries[pf_queue.used-1]; + X86PageEntry pentry; + pentry.load=MEM_PhysReadD(entry->page_addr); + if (pentry.block.p && entry->cs == SegValue(cs) && entry->eip==reg_eip) + return -1; + return 0; +} + +Bitu DEBUG_EnableDebugger(void); + +void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu type) { + /* Save the state of the cpu cores */ + LOG_MSG("PageFault at %X type %d queue %d",lin_addr,type,pf_queue.used); + LazyFlags old_lflags; + memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); + CPU_Decoder * old_cpudecoder; + old_cpudecoder=cpudecoder; + cpudecoder=&PageFaultCore; + paging.cr2=lin_addr; + PF_Entry * entry=&pf_queue.entries[pf_queue.used++]; + entry->cs=SegValue(cs); + entry->eip=reg_eip; + entry->page_addr=page_addr; + //Caused by a write by default? + CPU_Exception(14,0x2 | ((cpu.cpl>0) ? 0x1 : 0)); + DEBUG_EnableDebugger(); + DOSBOX_RunMachine(); + pf_queue.used--; + memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); + cpudecoder=old_cpudecoder; +} + + class InitPageHandler : public PageHandler { public: - InitPageHandler() {flags=0;} + InitPageHandler() {flags=PFLAG_ILLEGAL;} void AddPageLink(Bitu lin_page, Bitu phys_page) { assert(0); } @@ -97,11 +155,34 @@ public: InitPage(addr); mem_writed(addr,val); } - void InitPage(Bitu addr) { - Bitu lin_page=addr >> 12; + void InitPage(Bitu lin_addr) { + Bitu lin_page=lin_addr >> 12; Bitu phys_page; if (paging.enabled) { - E_Exit("No paging support"); + Bitu d_index=lin_page >> 10; + Bitu t_index=lin_page & 0x3ff; + Bitu table_addr=(paging.base.page<<12)+d_index*4; + X86PageEntry table; + table.load=MEM_PhysReadD(table_addr); + if (!table.block.p) { + LOG(LOG_PAGING,LOG_ERROR)("NP Table"); + PAGING_PageFault(lin_addr,table_addr,0); + table.load=MEM_PhysReadD(table_addr); + if (!table.block.p) + E_Exit("Pagefault didn't correct table"); + } + X86PageEntry entry; + Bitu entry_addr=(table.block.base << 12)+t_index*4; + entry.load=MEM_PhysReadD(entry_addr); + if (!entry.block.p) { + LOG(LOG_PAGING,LOG_ERROR)("NP Page"); + PAGING_PageFault(lin_addr,entry_addr,0); + entry.load=MEM_PhysReadD(entry_addr); + if (!entry.block.p) + E_Exit("Pagefault didn't correct page"); + } + phys_page=entry.block.base; + LOG_MSG("Linked page lin page %X to phys page %X",lin_page,phys_page); } else { if (lin_page Date: Tue, 18 Nov 2003 22:23:50 +0000 Subject: [PATCH 1366/4131] Fix the POP Mod/rm issue Changes for new interrupts Some privileged instructions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1447 --- src/cpu/core_full.cpp | 5 +++-- src/cpu/core_full/load.h | 11 +++++++++-- src/cpu/core_full/op.h | 19 ++++++++++++++----- src/cpu/core_full/optable.h | 12 ++++++------ src/cpu/core_full/string.h | 1 + src/cpu/core_full/support.h | 7 +++---- 6 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index a6658cfe..7b2899f4 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -71,6 +71,7 @@ typedef PhysPt EAPoint; Bits Full_DeCode(void) { FullData inst; restart_core: + if (CPU_Cycles<=0) return CBRET_NONE; if (!cpu.code.big) { inst.start_prefix=0x0;; inst.start_entry=0x0; @@ -81,10 +82,9 @@ restart_core: EAPoint IPPoint; LoadIP(); lflags.type=t_UNKNOWN; - while (CPU_Cycles>0) { + while (CPU_Cycles--) { #if C_DEBUG cycle_count++; - CPU_Cycles--; #if C_HEAVY_DEBUG SaveIP(); if (DEBUG_HeavyIsBreakpoint()) { @@ -104,6 +104,7 @@ restartopcode: #include "core_full/save.h" nextopcode:; } +exit_core: LEAVECORE; return CBRET_NONE; } diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 1acb09af..3ea74c89 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -1,5 +1,12 @@ switch (inst.code.load) { /* General loading */ + case L_POPwRM: + inst.op1.w = Pop_16(); + goto case_L_MODRM; + case L_POPdRM: + inst.op1.d = Pop_32(); + goto case_L_MODRM; +case_L_MODRM: case L_MODRM: inst.rm=Fetchb(); inst.rm_index=(inst.rm >> 3) & 7; @@ -245,7 +252,7 @@ l_M_Ed: break; /* Special cases */ case L_DOUBLE: - inst.entry|=0x100; + inst.entry=inst.start_prefix^0x100; goto restartopcode; case L_PRESEG: inst.prefix|=PREFIX_SEG; @@ -479,7 +486,7 @@ l_M_Ed: goto nextopcode; case D_HLT: LEAVECORE; - CPU_HLT(); + CPU_HLT(IPPoint-inst.start); return CBRET_NONE; default: LOG(LOG_CPU,LOG_ERROR)("LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry); diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 67d93e8c..4bc16941 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -340,10 +340,12 @@ switch (inst.code.op) { case O_INT: LEAVECORE; #if C_DEBUG - if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint()) return debugCallback; - else if (DEBUG_IntBreakpoint(inst.op1.b)) return debugCallback; + if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint()) + return debugCallback; + else if (DEBUG_IntBreakpoint(inst.op1.b)) + return debugCallback; #endif - Interrupt(inst.op1.b); + CPU_SW_Interrupt(inst.op1.b,IPPoint-inst.start); goto restart_core; case O_INb: reg_al=IO_Read(inst.op1.d); @@ -444,12 +446,19 @@ switch (inst.code.op) { LOG(LOG_CPU,LOG_ERROR)("Group 7 Illegal subfunction %X",inst.rm_index); } break; - case O_M_Cd_Rd: + case O_M_CRx_Rd: CPU_SET_CRX(inst.rm_index,inst.op1.d); break; - case O_M_Rd_Cd: + case O_M_Rd_CRx: inst.op1.d=CPU_GET_CRX(inst.rm_index); break; + case O_M_DRx_Rd: + LOG(LOG_CPU,LOG_NORMAL)("MOV DR%d,%X",inst.rm_index,inst.op1.d); + break; + case O_M_Rd_DRx: + inst.op1.d=0; + LOG(LOG_CPU,LOG_NORMAL)("MOV %X,DR%d",inst.op1.d,inst.rm_index); + break; case O_LAR: { FillFlags(); diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index aaee0edc..7213c6fc 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -100,7 +100,7 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,0 ,S_Eb ,M_Gb },{L_MODRM ,0 ,S_Ew ,M_Gw }, {L_MODRM ,0 ,S_Gb ,M_Eb },{L_MODRM ,0 ,S_Gw ,M_Ew }, {L_MODRM ,0 ,S_Ew ,M_SEG },{L_MODRM ,0 ,S_Gw ,M_EA }, -{L_MODRM ,0 ,S_SEGm ,M_Ew },{L_MODRM ,0 ,S_Ew ,M_POPw }, +{L_MODRM ,0 ,S_SEGm ,M_Ew },{L_POPwRM ,0 ,S_Ew ,M_None }, /* 0x90 - 0x97 */ {D_NOP ,0 ,0 ,0 },{L_REGw ,O_XCHG_AX ,S_REGw ,REGI_CX}, @@ -203,8 +203,8 @@ static OpCode OpCodeTable[1024]={ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x120 - 0x127 */ -{L_MODRM ,O_M_Rd_Cd ,S_Ed ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,O_M_Cd_Rd ,0 ,M_Ed },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_M_Rd_CRx ,S_Ed ,0 },{L_MODRM ,O_M_Rd_DRx ,S_Ed ,0 }, +{L_MODRM ,O_M_CRx_Rd ,0 ,M_Ed },{L_MODRM ,O_M_DRx_Rd ,0 ,M_Ed }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, @@ -456,7 +456,7 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,0 ,S_Eb ,M_Gb },{L_MODRM ,0 ,S_Ed ,M_Gd }, {L_MODRM ,0 ,S_Gb ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ed }, {L_MODRM ,0 ,S_EdMw ,M_SEG },{L_MODRM ,0 ,S_Gd ,M_EA }, -{L_MODRM ,0 ,S_SEGm ,M_Ew },{L_MODRM ,0 ,S_Ed ,M_POPd }, +{L_MODRM ,0 ,S_SEGm ,M_Ew },{L_POPdRM ,0 ,S_Ed ,M_None }, /* 0x290 - 0x297 */ {D_NOP ,0 ,0 ,0 },{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_CX}, @@ -559,8 +559,8 @@ static OpCode OpCodeTable[1024]={ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x320 - 0x327 */ -{L_MODRM ,O_M_Rd_Cd ,S_Ed ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,O_M_Cd_Rd ,0 ,M_Ed },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_M_Rd_CRx ,S_Ed ,0 },{L_MODRM ,O_M_Rd_DRx ,S_Ed ,0 }, +{L_MODRM ,O_M_CRx_Rd ,0 ,M_Ed },{L_MODRM ,O_M_DRx_Rd ,0 ,M_Ed }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index 183c2d97..95ce58f6 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -23,6 +23,7 @@ count=1; } else { /* Calculate amount of ops to do before cycles run out */ + CPU_Cycles++; if ((count>(Bitu)CPU_Cycles) && (inst.code.op Date: Tue, 18 Nov 2003 22:25:49 +0000 Subject: [PATCH 1367/4131] Changes for new interrupts Some privileged instructions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1448 --- src/cpu/core_normal.cpp | 2 +- src/cpu/core_normal/prefix_none.h | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 34c95897..467451da 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -210,7 +210,7 @@ static Bits CPU_Core_Normal_Decode_Trap(void) { core.trap.skip=false; Bits ret=CPU_Core_Normal_Decode(); - if (!core.trap.skip) Interrupt(1); + if (!core.trap.skip) CPU_SW_Interrupt(1,0); CPU_Cycles = oldCycles-1; cpudecoder = &CPU_Core_Normal_Decode; diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index bd44cbe7..ac649c59 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -253,7 +253,7 @@ CASE_B(0x65) /* SEG GS: */ DO_PREFIX_SEG(gs);break; CASE_B(0x66) /* Operand Size Prefix */ - core.opcode_index^=OPCODE_SIZE; + core.opcode_index=core.index_default^OPCODE_SIZE; goto restart_opcode; CASE_B(0x67) /* Address Size Prefix */ DO_PREFIX_ADDR(); @@ -751,7 +751,7 @@ return debugCallback; } #endif - CPU_SW_Interrupt(3); + CPU_SW_Interrupt(3,core.ip_lookup-core.op_start); #if CPU_TRAP_CHECK core.trap.skip=true; #endif @@ -765,7 +765,7 @@ return debugCallback; } #endif - CPU_SW_Interrupt(num); + CPU_SW_Interrupt(num,core.ip_lookup-core.op_start); #if CPU_TRAP_CHECK core.trap.skip=true; #endif @@ -775,7 +775,7 @@ CASE_B(0xce) /* INTO */ if (get_OF()) { LEAVECORE; - CPU_SW_Interrupt(4); + CPU_SW_Interrupt(4,core.ip_lookup-core.op_start); #if CPU_TRAP_CHECK core.trap.skip=true; #endif @@ -950,7 +950,7 @@ break; CASE_B(0xf4) /* HLT */ LEAVECORE; - CPU_HLT(); + CPU_HLT(core.ip_lookup-core.op_start); return CBRET_NONE; CASE_B(0xf5) /* CMC */ FillFlags(); From 09366aa37f6059df7b5b941cab2b11e76b2a5ce4 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 18 Nov 2003 22:29:31 +0000 Subject: [PATCH 1368/4131] Basic task switching support. Basic v86 mode support. Added some privilege level exceptions Better support of software interrupts Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1449 --- src/cpu/cpu.cpp | 674 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 470 insertions(+), 204 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 9c6ae0d7..1168c0cd 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.37 2003-11-05 19:41:10 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.38 2003-11-18 22:29:31 harekiet Exp $ */ #include #include "dosbox.h" @@ -27,6 +27,8 @@ #include "setup.h" #include "paging.h" +Bitu DEBUG_EnableDebugger(void); + #if 1 #undef LOG #define LOG(X,Y) @@ -39,7 +41,6 @@ Segments Segs; Bits CPU_Cycles=0; Bits CPU_CycleLeft=0; Bits CPU_CycleMax=1500; - CPU_Decoder * cpudecoder; void CPU_Real_16_Slow_Start(bool big); @@ -49,15 +50,14 @@ void CPU_Core_Normal_Start(bool big); static Bits CPU_Core_Normal_Decode(void); static Bits CPU_Core_Full_Decode(void); + #if 1 #define realcore_start CPU_Core_Normal_Start -#define pmodecore_start CPU_Core_Normal_Start #else #define realcore_start CPU_Core_Full_Start -#define pmodecore_start CPU_Core_Full_Start #endif @@ -93,15 +93,188 @@ PhysPt SelBase(Bitu sel) { } } -void CPU_SetFlags(Bitu word) { - reg_flags=(word|2)&~0x28; +void CPU_SetFlags(Bitu word,Bitu mask) { + reg_flags=(reg_flags & ~mask)|(word & mask)|2; +} + +class TaskStateSegment { +public: + TaskStateSegment() { + valid=false; + } + bool IsValid(void) { + return valid; + } + Bitu Get_back(void) { + return mem_readw(base); + } + void SaveSelector(void) { + cpu.gdt.SetDescriptor(selector,desc); + } + void Get_SSx_ESPx(Bitu level,Bitu & _ss,Bitu & _esp) { + if (is386) { + PhysPt where=base+offsetof(TSS_32,esp0)+level*8; + _esp=mem_readd(where); + _ss=mem_readw(where+4); + } else { + PhysPt where=base+offsetof(TSS_16,sp0)+level*4; + _esp=mem_readw(where); + _ss=mem_readw(where+2); + } + } + bool SetSelector(Bitu new_sel) { + valid=false; + selector=new_sel; + if (!cpu.gdt.GetDescriptor(selector,desc)) return false; + switch (desc.Type()) { + case DESC_286_TSS_A: case DESC_286_TSS_B: + case DESC_386_TSS_A: case DESC_386_TSS_B: + break; + default: + valid=false; + return false; + } + valid=true; + base=desc.GetBase(); + limit=desc.GetLimit(); + is386=desc.Is386(); + return true; + } + TSS_Descriptor desc; + Bitu selector; + PhysPt base; + Bitu limit; + Bitu is386; + bool valid; +}; + +TaskStateSegment cpu_tss; + +enum TSwitchType { + TSwitch_JMP,TSwitch_CALL_INT,TSwitch_IRET +}; + +bool CPU_SwitchTask(Bitu new_tss_selector,TSwitchType tstype) { + TaskStateSegment new_tss; + if (!new_tss.SetSelector(new_tss_selector)) + E_Exit("Illegal TSS for switch"); + /* Save current context in current TSS */ + /* Check if we need to clear busy bit of old TASK */ + if (tstype==TSwitch_JMP || tstype==TSwitch_IRET) { + cpu_tss.desc.SetBusy(false); + cpu_tss.SaveSelector(); + } + Bitu new_cr3=0; + Bitu new_es,new_cs,new_ss,new_ds,new_fs,new_gs; + Bitu new_ldt; + if (cpu_tss.is386) { + mem_writed(cpu_tss.base+offsetof(TSS_32,eflags),reg_flags); + mem_writed(cpu_tss.base+offsetof(TSS_32,eip),reg_eip); + + mem_writed(cpu_tss.base+offsetof(TSS_32,eax),reg_eax); + mem_writed(cpu_tss.base+offsetof(TSS_32,ecx),reg_ecx); + mem_writed(cpu_tss.base+offsetof(TSS_32,edx),reg_edx); + mem_writed(cpu_tss.base+offsetof(TSS_32,ebx),reg_ebx); + mem_writed(cpu_tss.base+offsetof(TSS_32,esp),reg_esp); + mem_writed(cpu_tss.base+offsetof(TSS_32,ebp),reg_ebp); + mem_writed(cpu_tss.base+offsetof(TSS_32,esi),reg_esi); + mem_writed(cpu_tss.base+offsetof(TSS_32,edi),reg_edi); + + mem_writed(cpu_tss.base+offsetof(TSS_32,es),SegValue(es)); + mem_writed(cpu_tss.base+offsetof(TSS_32,cs),SegValue(cs)); + mem_writed(cpu_tss.base+offsetof(TSS_32,ss),SegValue(ss)); + mem_writed(cpu_tss.base+offsetof(TSS_32,ds),SegValue(ds)); + mem_writed(cpu_tss.base+offsetof(TSS_32,fs),SegValue(fs)); + mem_writed(cpu_tss.base+offsetof(TSS_32,gs),SegValue(gs)); + } else { + E_Exit("286 task switch"); + } + /* Load new context from new TSS */ + if (new_tss.is386) { + new_cr3=mem_readd(new_tss.base+offsetof(TSS_32,cr3)); + reg_eip=mem_readd(new_tss.base+offsetof(TSS_32,eip)); + CPU_SetFlags(mem_readd(new_tss.base+offsetof(TSS_32,eflags)),FMASK_ALL | FLAG_VM); + reg_eax=mem_readd(new_tss.base+offsetof(TSS_32,eax)); + reg_ecx=mem_readd(new_tss.base+offsetof(TSS_32,ecx)); + reg_edx=mem_readd(new_tss.base+offsetof(TSS_32,edx)); + reg_ebx=mem_readd(new_tss.base+offsetof(TSS_32,ebx)); + reg_esp=mem_readd(new_tss.base+offsetof(TSS_32,esp)); + reg_ebp=mem_readd(new_tss.base+offsetof(TSS_32,ebp)); + reg_edi=mem_readd(new_tss.base+offsetof(TSS_32,edi)); + reg_esi=mem_readd(new_tss.base+offsetof(TSS_32,esi)); + + new_es=mem_readw(new_tss.base+offsetof(TSS_32,es)); + new_cs=mem_readw(new_tss.base+offsetof(TSS_32,cs)); + new_ss=mem_readw(new_tss.base+offsetof(TSS_32,ss)); + new_ds=mem_readw(new_tss.base+offsetof(TSS_32,ds)); + new_fs=mem_readw(new_tss.base+offsetof(TSS_32,fs)); + new_gs=mem_readw(new_tss.base+offsetof(TSS_32,gs)); + new_ldt=mem_readw(new_tss.base+offsetof(TSS_32,ldt)); + } else { + E_Exit("286 task switch"); + } + /* Setup a back link to the old TSS in new TSS */ + if (tstype==TSwitch_CALL_INT) { + if (new_tss.is386) { + mem_writed(new_tss.base+offsetof(TSS_32,back),cpu_tss.selector); + } else { + mem_writew(new_tss.base+offsetof(TSS_16,back),cpu_tss.selector); + } + /* And make the new task's eflag have the nested task bit */ + reg_flags|=FLAG_NT; + } + /* Set the busy bit in the new task */ + if (tstype==TSwitch_JMP || tstype==TSwitch_IRET) { + new_tss.desc.SetBusy(true); + new_tss.SaveSelector(); + } + /* Setup the new cr3 */ + PAGING_SetDirBase(new_cr3); + /* Load the new selectors */ + if (reg_flags & FLAG_VM) { +// LOG_MSG("Entering v86 task"); + SegSet16(cs,new_cs); + cpu.code.big=false; + cpu.cpl=3; //We don't have segment caches so this will do + } else { + //DEBUG_EnableDebugger(); + /* Protected mode task */ + CPU_LLDT(new_ldt); + /* Load the new CS*/ + Descriptor cs_desc; + cpu.cpl=new_cs & 3; + cpu.gdt.GetDescriptor(new_cs,cs_desc); + switch (cs_desc.Type()) { + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: + case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl != cs_desc.DPL()) E_Exit("Task CS RPL != DPL"); + goto doconforming; + case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: + case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: +doconforming: + Segs.phys[cs]=cs_desc.GetBase(); + cpu.code.big=cs_desc.Big()>0; + Segs.val[cs]=new_cs; + break; + default: + E_Exit("Task switch CS Type %d",cs_desc.Type()); + } + } + CPU_SetSegGeneral(es,new_es); + CPU_SetSegGeneral(ss,new_ss); + CPU_SetSegGeneral(ds,new_ds); + CPU_SetSegGeneral(fs,new_fs); + CPU_SetSegGeneral(gs,new_gs); + CPU_LTR(new_tss_selector); +// LOG_MSG("Task CPL %X CS:%X IP:%X SS:%X SP:%X eflags %x",cpu.cpl,SegValue(cs),reg_eip,SegValue(ss),reg_esp,reg_flags); + return true; } Bit8u lastint; void CPU_Exception(Bitu num,Bitu error_code) { - CPU_Interrupt(num,0,0); +// LOG_MSG("Exception %d CS:%X IP:%X FLAGS:%X",num,SegValue(cs),reg_eip,reg_flags); + CPU_Interrupt(num,error_code,((num>=8) ? CPU_INT_HAS_ERROR : 0)); } - void CPU_Interrupt(Bitu num,Bitu error_code,Bitu type) { lastint=num; #if C_DEBUG @@ -127,64 +300,128 @@ void CPU_Interrupt(Bitu num,Bitu error_code,Bitu type) { SETFLAGBIT(IF,false); SETFLAGBIT(TF,false); /* Get the new CS:IP from vector table */ - reg_eip=mem_readw(num << 2); - Segs.val[cs]=mem_readw((num << 2)+2); + PhysPt base=cpu.idt.GetBase(); + reg_eip=mem_readw(base+(num << 2)); + Segs.val[cs]=mem_readw(base+(num << 2)+2); Segs.phys[cs]=Segs.val[cs]<<4; cpu.code.big=false; return; } else { /* Protected Mode Interrupt */ +// if (type&CPU_INT_SOFTWARE && cpu.v86) goto realmode_interrupt; +// DEBUG_EnableDebugger(); +// LOG_MSG("interrupt start CPL %d v86 %d",cpu.cpl,cpu.v86); + if ((reg_flags & FLAG_VM) && (type&CPU_INT_SOFTWARE)) { + LOG_MSG("Software int in v86, AH %X IOPL %x",reg_ah,(reg_flags & FLAG_IOPL) >>12); + if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) { + reg_eip-=error_code; + CPU_Exception(13,0); + return; + } + } Descriptor gate; //TODO Check for software interrupt and check gate's dplcpu.cpl) E_Exit("Interrupt to higher privilege"); - switch (desc.Type()) { + Descriptor cs_desc; + Bitu gate_sel=gate.GetSelector(); + Bitu gate_off=gate.GetOffset(); + cpu.gdt.GetDescriptor(gate_sel,cs_desc); + Bitu cs_dpl=cs_desc.DPL(); + if (cs_dpl>cpu.cpl) E_Exit("Interrupt to higher privilege"); + switch (cs_desc.Type()) { case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (dpl0; - LOG(LOG_CPU,LOG_NORMAL)("INT:Gate to %X:%X big %d %s",selector,reg_eip,desc.Big(),gate.Type() & 0x8 ? "386" : "286"); - reg_eip=offset; + SETFLAGBIT(VM,false); + Segs.val[cs]=(gate_sel&0xfffc) | cpu.cpl; + Segs.phys[cs]=cs_desc.GetBase(); + cpu.code.big=cs_desc.Big()>0; + LOG(LOG_CPU,LOG_NORMAL)("INT:Gate to %X:%X big %d %s",gate_sel,gate_off,cs_desc.Big(),gate.Type() & 0x8 ? "386" : "286"); + reg_eip=gate_off; return; } + case DESC_TASK_GATE: + CPU_SwitchTask(gate.GetSelector(),TSwitch_CALL_INT); + if (type & CPU_INT_HAS_ERROR) { + //TODO Be sure about this, seems somewhat unclear + if (cpu_tss.is386) CPU_Push32(error_code); + else CPU_Push16(error_code); + } + return; default: E_Exit("Illegal descriptor type %X for int %X",gate.Type(),num); } @@ -193,11 +430,12 @@ void CPU_Interrupt(Bitu num,Bitu error_code,Bitu type) { } void CPU_IRET(bool use32) { - if (!cpu.pmode || cpu.v86) { /* RealMode IRET */ + if (!cpu.pmode) { /* RealMode IRET */ +realmode_iret: if (use32) { reg_eip=CPU_Pop32(); SegSet16(cs,CPU_Pop32()); - CPU_SetFlags(CPU_Pop32()); + CPU_SetFlagsd(CPU_Pop32()); } else { reg_eip=CPU_Pop16(); SegSet16(cs,CPU_Pop16()); @@ -206,87 +444,125 @@ void CPU_IRET(bool use32) { cpu.code.big=false; return; } else { /* Protected mode IRET */ - /* Check if this is task IRET */ + if (reg_flags & FLAG_VM) { + if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) { + reg_eip--; + CPU_Exception(13,0); + return; + } else goto realmode_iret; + } +// DEBUG_EnableDebugger(); +// LOG_MSG("IRET start CPL %d v86 %d",cpu.cpl,cpu.v86); + /* Check if this is task IRET */ if (GETFLAG(NT)) { if (GETFLAG(VM)) E_Exit("Pmode IRET with VM bit set"); - E_Exit("Task IRET"); - - + if (!cpu_tss.IsValid()) E_Exit("TASK Iret without valid TSS"); + Bitu back_link=cpu_tss.Get_back(); + CPU_SwitchTask(back_link,TSwitch_IRET); + return; } - Bitu selector,offset,old_flags; + Bitu n_cs_sel,n_eip,n_flags; if (use32) { - offset=CPU_Pop32(); - selector=CPU_Pop32() & 0xffff; - old_flags=CPU_Pop32(); - if (old_flags & FLAG_VM) E_Exit("No vm86 support"); + n_eip=CPU_Pop32(); + n_cs_sel=CPU_Pop32() & 0xffff; + n_flags=CPU_Pop32(); + if (n_flags & FLAG_VM) { + cpu.cpl=3; + CPU_SetFlags(n_flags,FMASK_ALL | FLAG_VM); + Bitu n_ss,n_esp,n_es,n_ds,n_fs,n_gs; + n_esp=CPU_Pop32(); + n_ss=CPU_Pop32() & 0xffff; + + n_es=CPU_Pop32() & 0xffff; + n_ds=CPU_Pop32() & 0xffff; + n_fs=CPU_Pop32() & 0xffff; + n_gs=CPU_Pop32() & 0xffff; + CPU_SetSegGeneral(ss,n_ss); + CPU_SetSegGeneral(es,n_es); + CPU_SetSegGeneral(ds,n_ds); + CPU_SetSegGeneral(fs,n_fs); + CPU_SetSegGeneral(gs,n_gs); + reg_eip=n_eip & 0xffff; + reg_esp=n_esp; + cpu.code.big=false; + SegSet16(cs,n_cs_sel); + LOG(LOG_CPU,LOG_NORMAL)("IRET:Back to V86: CS:%X IP %X SS:%X SP %X FLAGS:%X",SegValue(cs),reg_eip,SegValue(ss),reg_esp,reg_flags); + return; + } } else { - offset=CPU_Pop16(); - selector=CPU_Pop16(); - old_flags=(reg_flags & 0xffff0000) | CPU_Pop16(); + n_eip=CPU_Pop16(); + n_cs_sel=CPU_Pop16(); + n_flags=(reg_flags & 0xffff0000) | CPU_Pop16(); + if (n_flags & FLAG_VM) E_Exit("VM Flag in 16-bit iret"); } - Bitu rpl=selector & 3; - Descriptor desc; - cpu.gdt.GetDescriptor(selector,desc); - if (rpl=cpu.cpl)) E_Exit("IRET:Same level:C:DPL=cpu.cpl)) E_Exit("IRET:Same level:C:DPL0; - Segs.val[cs]=(selector & 0xfffc) | cpu.cpl;; - reg_eip=offset; - CPU_SetFlags(old_flags); - LOG(LOG_CPU,LOG_NORMAL)("IRET:Same level return to %X:%X big %d",selector,offset,cpu.code.big); + Segs.phys[cs]=n_cs_desc.GetBase(); + cpu.code.big=n_cs_desc.Big()>0; + Segs.val[cs]=n_cs_sel; + reg_eip=n_eip; + CPU_SetFlagsd(n_flags); + LOG(LOG_CPU,LOG_NORMAL)("IRET:Same level:%X:%X big %d",n_cs_sel,n_eip,cpu.code.big); } else { - /* Return to higher privilege */ - switch (desc.Type()) { + /* Return to outer level */ + switch (n_cs_desc.Type()) { case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (!(cpu.cpl==rpl)) E_Exit("IRET:Outer level:NC:RPL != DPL"); + if (n_cs_desc.DPL()!=n_cs_rpl) E_Exit("IRET:Outer level:NC:CS RPL != CS DPL"); break; case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: - if (!(desc.DPL()>cpu.cpl)) E_Exit("IRET:Outer level:C:DPL <= CPL"); + if (n_cs_desc.DPL()<=cpu.cpl) E_Exit("IRET:Outer level:C:DPL <= CPL"); break; default: - E_Exit("IRET from illegal descriptor type %X",desc.Type()); + E_Exit("IRET:Outer level:Illegal descriptor type %X",n_cs_desc.Type()); } - Segs.phys[cs]=desc.GetBase(); - cpu.code.big=desc.Big()>0; - Segs.val[cs]=selector; - cpu.cpl=rpl; - reg_eip=offset; - Bitu new_ss,new_esp; + Segs.phys[cs]=n_cs_desc.GetBase(); + cpu.code.big=n_cs_desc.Big()>0; + Segs.val[cs]=n_cs_sel; + cpu.cpl=n_cs_rpl; + reg_eip=n_eip; + CPU_SetFlagsd(n_flags); + Bitu n_ss,n_esp; if (use32) { - new_esp=CPU_Pop32(); - new_ss=CPU_Pop32() & 0xffff; + n_esp=CPU_Pop32(); + n_ss=CPU_Pop32() & 0xffff; } else { - new_esp=CPU_Pop16(); - new_ss=CPU_Pop16(); + n_esp=CPU_Pop16(); + n_ss=CPU_Pop16(); + } + CPU_SetSegGeneral(ss,n_ss); + if (cpu.stack.big) { + reg_esp=n_esp; + } else { + reg_sp=n_esp; } - reg_esp=new_esp; - CPU_SetSegGeneral(ss,new_ss); //TODO Maybe validate other segments, but why would anyone use them? - LOG(LOG_CPU,LOG_NORMAL)("IRET:Outer level return to %X:X big %d",selector,offset,cpu.code.big); + LOG(LOG_CPU,LOG_NORMAL)("IRET:Outer level:%X:X big %d",n_cs_sel,n_eip,cpu.code.big); } return; } } void CPU_JMP(bool use32,Bitu selector,Bitu offset) { - if (!cpu.pmode || cpu.v86) { + if (!cpu.pmode || (reg_flags & FLAG_VM)) { if (!use32) { reg_eip=offset&0xffff; } else { @@ -317,6 +593,12 @@ CODE_jmp: Segs.val[cs]=(selector & 0xfffc) | cpu.cpl; reg_eip=offset; return; + case DESC_386_TSS_A: + if (desc.DPL()0; Segs.val[cs]=(selector & 0xfffc) | cpu.cpl; - reg_eip=offset; return; - case DESC_286_CALL_GATE: { - if (call.DPL()0; - reg_eip = neweip; - // Set CPL to stack segment DPL - // Set RPL of CS to CPL - cpu.cpl = newcpl; - Segs.val[cs] = (newcs & 0xfffc) | newcpl; - // 4. Load SS descriptor - // 5. Push long pointer of old stack onto new stack - Bitu oldsp = reg_sp; - CPU_Push16(SegValue(ss)); - CPU_Push16(oldsp); - // 6. Get word count from call gate, mask to 5 bits - Bitu wordCount = call.saved.gate.paramcount; - if (wordCount>0) LOG(LOG_CPU,LOG_NORMAL)("CPU: Callgate 286 wordcount : %d)",wordCount); - // 7. Copy parameters from old stack onto new stack - while (wordCount>0) { - CPU_Push16(mem_readw(SegPhys(ss)+oldsp)); - oldsp += 2; wordCount--; + case DESC_386_CALL_GATE: + case DESC_286_CALL_GATE: + { + if (call.DPL()0; + reg_eip = n_eip; + if (!use32) reg_eip&=0xffff; + break; + } + case DESC_CODE_N_C_A:case DESC_CODE_N_C_NA: + case DESC_CODE_R_C_A:case DESC_CODE_R_C_NA: +call_gate_same_privilege: + E_Exit("Call gate to same priviledge"); + break; } - // Push return address onto new stack - CPU_Push16(oldcs); - CPU_Push16(oldip); -// LOG(LOG_MISC,LOG_ERROR)("CPU: Callgate (Higher) %04X:%04X",newcs,neweip); - return; - } else { - // same privilidge level - Bitu oldcs = SegValue(cs); - Bitu oldip = reg_ip; - Bitu newcs = call.GetSelector() | 3; - Bitu neweip = call.GetOffset(); - // 3. Load CS descriptor (Set RPL of CS to CPL) - Descriptor code2; - if (!cpu.gdt.GetDescriptor(newcs,code2)) E_Exit("286 Call Gate: Invalid code segment."); - Segs.phys[cs] = code.GetBase(); - cpu.code.big = code.Big()>0; - // Set RPL of CS to CPL - cpu.cpl = seldpl; - Segs.val[cs] = (newcs & 0xfffc) | seldpl; - reg_eip = neweip; - // Push return address onto new stack - CPU_Push16(oldcs); - CPU_Push16(oldip); -// LOG(LOG_MISC,LOG_ERROR)("CPU: Callgate (Same) %04X:%04X",newcs,neweip); - return; - }; break; - }; + } /* Call Gates */ + break; + case DESC_386_TSS_A: + if (call.DPL()0; Segs.val[cs]=selector; @@ -525,26 +815,26 @@ void CPU_SLDT(Bitu & selector) { selector=cpu.gdt.SLDT(); } -Bitu tr=0; void CPU_LLDT(Bitu selector) { cpu.gdt.LLDT(selector); LOG(LOG_CPU,LOG_NORMAL)("LDT Set to %X",selector); } void CPU_STR(Bitu & selector) { - selector=tr; + selector=cpu_tss.selector; } void CPU_LTR(Bitu selector) { - tr=selector; - LOG(LOG_CPU,LOG_NORMAL)("TR Set to %X",selector); + cpu_tss.SetSelector(selector); } - +static gdt_count=0; void CPU_LGDT(Bitu limit,Bitu base) { - LOG(LOG_CPU,LOG_NORMAL)("GDT Set to base:%X limit:%X",base,limit); + LOG(LOG_CPU,LOG_NORMAL)("GDT Set to base:%X limit:%X count %d",base,limit,gdt_count++); cpu.gdt.SetLimit(limit); cpu.gdt.SetBase(base); +// if (gdt_count>20) DEBUG_EnableDebugger(); +// DEBUG_EnableDebugger(); } void CPU_LIDT(Bitu limit,Bitu base) { @@ -583,6 +873,9 @@ bool CPU_SET_CRX(Bitu cr,Bitu value) { } return false; //Only changes with next CS change } + case 2: + paging.cr2=value; + break; case 3: PAGING_SetDirBase(value); break; @@ -597,6 +890,8 @@ Bitu CPU_GET_CRX(Bitu cr) { switch (cr) { case 0: return cpu.cr0; + case 2: + return paging.cr2; case 3: return PAGING_GetDirBase(); default: @@ -612,8 +907,9 @@ void CPU_SMSW(Bitu & word) { } bool CPU_LMSW(Bitu word) { - word&=0xffff; - word|=(cpu.cr0&0xffff0000); + word&=0xf; + if (cpu.cr0 & 1) word|=1; + word|=(cpu.cr0&0xfffffff0); return CPU_SET_CRX(0,word); } @@ -778,9 +1074,8 @@ void CPU_VERW(Bitu selector) { void CPU_SetSegGeneral(SegNames seg,Bitu value) { Segs.val[seg]=value; - if (!cpu.pmode || cpu.v86) { + if (!cpu.pmode || (reg_flags & FLAG_VM)) { Segs.phys[seg]=value << 4; -//TODO maybe just always do this when they enable/real/v86 mode if (seg==ss) { cpu.stack.big=false; cpu.stack.mask=0xffff; @@ -821,41 +1116,6 @@ void CPU_CPUID(void) { } } -void CPU_ReadTaskSeg32(PhysPt base,TaskSegment_32 * seg) { - seg->back =mem_readw(base+offsetof(TSS_386,back )); - seg->esp0 =mem_readd(base+offsetof(TSS_386,esp0 )); - seg->ss0 =mem_readw(base+offsetof(TSS_386,ss0 )); - seg->esp1 =mem_readd(base+offsetof(TSS_386,esp1 )); - seg->ss1 =mem_readw(base+offsetof(TSS_386,ss1 )); - seg->esp2 =mem_readd(base+offsetof(TSS_386,esp2 )); - seg->ss2 =mem_readw(base+offsetof(TSS_386,ss2 )); - - seg->cr3 =mem_readd(base+offsetof(TSS_386,cr3 )); - seg->eflags =mem_readd(base+offsetof(TSS_386,eflags )); - seg->eip =mem_readd(base+offsetof(TSS_386,eip )); - - seg->eax =mem_readd(base+offsetof(TSS_386,eax )); - seg->ecx =mem_readd(base+offsetof(TSS_386,ecx )); - seg->edx =mem_readd(base+offsetof(TSS_386,edx )); - seg->ebx =mem_readd(base+offsetof(TSS_386,ebx )); - seg->esp =mem_readd(base+offsetof(TSS_386,esp )); - seg->ebp =mem_readd(base+offsetof(TSS_386,ebp )); - seg->esi =mem_readd(base+offsetof(TSS_386,esi )); - seg->edi =mem_readd(base+offsetof(TSS_386,edi )); - - seg->es =mem_readw(base+offsetof(TSS_386,es )); - seg->cs =mem_readw(base+offsetof(TSS_386,cs )); - seg->ss =mem_readw(base+offsetof(TSS_386,ss )); - seg->ds =mem_readw(base+offsetof(TSS_386,ds )); - seg->fs =mem_readw(base+offsetof(TSS_386,fs )); - seg->gs =mem_readw(base+offsetof(TSS_386,gs )); - - seg->ldt =mem_readw(base+offsetof(TSS_386,ldt )); - seg->trap =mem_readw(base+offsetof(TSS_386,trap )); - seg->io =mem_readw(base+offsetof(TSS_386,io )); - -} - static Bits HLT_Decode(void) { /* Once an interrupt occurs, it should change cpu core */ if (reg_eip!=cpu.hlt.eip || SegValue(cs) != cpu.hlt.cs) { @@ -866,7 +1126,12 @@ static Bits HLT_Decode(void) { return 0; } -void CPU_HLT(void) { +void CPU_HLT(Bitu oplen) { + if (cpu.cpl) { + reg_eip-=oplen; + CPU_Exception(13,0); + return; + } CPU_Cycles=0; cpu.hlt.cs=SegValue(cs); cpu.hlt.eip=reg_eip; @@ -912,14 +1177,15 @@ void CPU_Init(Section* sec) { SegSet16(gs,0); SegSet16(ss,0); - reg_eip=0; - CPU_SetFlags(FLAG_IF); //Enable interrupts + reg_flags=0x2; + CPU_SetFlags(FLAG_IF,FMASK_ALL); //Enable interrupts cpu.cr0=0xffffffff; - CPU_SET_CRX(0,0); //Initialize - cpu.v86=false; + CPU_SET_CRX(0,0); //Initialize cpu.code.big=false; cpu.stack.mask=0xffff; cpu.stack.big=false; + cpu.idt.SetBase(0); + cpu.idt.SetLimit(1023); realcore_start(false); CPU_JMP(false,0,0); //Setup the first cpu core From 27fd691fff5a125a5664934d884ce403a98d57bd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 18 Nov 2003 22:31:03 +0000 Subject: [PATCH 1369/4131] Check for illegal pages being linked New physical page read function Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1450 --- src/hardware/memory.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 6b6cde9e..37db0530 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -70,10 +70,20 @@ static struct MemoryBlock { class IllegalPageHandler : public PageHandler { public: void AddPageLink(Bitu lin_page, Bitu phys_page) { - } + IllegalPageHandler() { - flags=0; + flags=PFLAG_ILLEGAL|PFLAG_NOCODE; + } + Bitu readb(PhysPt addr) { + LOG_MSG("Illegal read from %x",addr); + return 0; + } + void writeb(PhysPt addr,Bitu val) { + LOG_MSG("Illegal write to %x",addr); + } + HostPt GetHostPt(Bitu phys_page) { + return 0; } }; @@ -134,7 +144,7 @@ PageHandler * MEM_GetPageHandler(Bitu phys_page) { } else if ((phys_page>=memory.lfb.start_page) && (phys_page> 24)); } -Bit32u phys_page_readd(Bitu page,Bitu index) { - return 0; +Bit32u MEM_PhysReadD(Bitu addr) { + Bitu page=addr >> 12; + Bitu index=(addr & 4095); + HostPt block=memory.hostpts[page]; + if (!block) { + E_Exit("Reading from empty page"); + } + return host_readd(block+index); } From b91359610a028d4190d2cd7559a34c4a8a24c852 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 18 Nov 2003 22:32:13 +0000 Subject: [PATCH 1370/4131] port 61 xors bit 4 on and off during reads Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1451 --- src/hardware/keyboard.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index c73f585e..23d9395d 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -197,6 +197,7 @@ static void write_p60(Bit32u port,Bit8u val) { static Bit8u read_p61(Bit32u port) { port_61_data^=0x20; + port_61_data^=0x10; return port_61_data; } From f8978947dfadddc6d790fc32fb224152070c92e3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 18 Nov 2003 22:35:56 +0000 Subject: [PATCH 1371/4131] bug fix with gdt_count Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1452 --- src/cpu/cpu.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 1168c0cd..36084d92 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.38 2003-11-18 22:29:31 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.39 2003-11-18 22:35:56 harekiet Exp $ */ #include #include "dosbox.h" @@ -827,7 +827,8 @@ void CPU_STR(Bitu & selector) { void CPU_LTR(Bitu selector) { cpu_tss.SetSelector(selector); } -static gdt_count=0; + +Bitu gdt_count=0; void CPU_LGDT(Bitu limit,Bitu base) { LOG(LOG_CPU,LOG_NORMAL)("GDT Set to base:%X limit:%X count %d",base,limit,gdt_count++); From 16ef4fa54c7afeeb9854c186ec470c843795ca22 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 18 Nov 2003 22:40:51 +0000 Subject: [PATCH 1372/4131] Use new flag mask Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1453 --- src/cpu/lazyflags.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index c0fd7d4c..11187b8d 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -59,7 +59,7 @@ extern LazyFlags lflags; { \ SETFLAGBIT(OF,get_OF()); \ lflags.type=t_UNKNOWN; \ - CPU_SetFlags((reg_flags&0xffffff00)|((FLAGB) & 0xff)); \ + CPU_SetFlags(reg_flags,FMASK_NORMAL & 0xff); \ } #define SETFLAGSw(FLAGW) \ @@ -71,7 +71,7 @@ extern LazyFlags lflags; #define SETFLAGSd(FLAGD) \ { \ lflags.type=t_UNKNOWN; \ - CPU_SetFlags(FLAGD); \ + CPU_SetFlagsd(FLAGD); \ } #define LoadCF SETFLAGBIT(CF,get_CF()); From d7b678ab45cc1abaf5b8de9c3c3426a5ea03c986 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 18 Nov 2003 22:43:58 +0000 Subject: [PATCH 1373/4131] Use a HW_interrupt Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1454 --- src/hardware/pic.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 65a1ba07..896b7c78 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -114,6 +114,7 @@ static void write_data(Bit32u port,Bit8u val) { Bitu i; switch(pic->icw_index) { case 0: /* mask register */ + LOG(LOG_PIC,LOG_NORMAL)("%d mask %X",port==0x21 ? 0 : 1,val); for (i=0;i<=7;i++) { irqs[i+irq_base].masked=(val&(1<0; if (irqs[i+irq_base].active && !irqs[i+irq_base].masked) PIC_IRQCheck|=(1 << (i+irq_base)); @@ -127,14 +128,14 @@ static void write_data(Bit32u port,Bit8u val) { #endif break; case 1: /* icw2 */ - LOG(LOG_PIC,LOG_NORMAL)("%d:Base vector %X",static_cast(port==0x21 ? 0 : 1),static_cast(val)); + LOG(LOG_PIC,LOG_NORMAL)("%d:Base vector %X",port==0x21 ? 0 : 1,val); for (i=0;i<=7;i++) { irqs[i+irq_base].vector=(val&0xf8)+i; }; if(pic->icw_index++ >= pic->icw_words) pic->icw_index=0; break; case 2: /* icw 3 */ - LOG(LOG_PIC,LOG_NORMAL)("%d:ICW 3 %X",static_cast(port==0x21 ? 0 : 1),static_cast(val)); + LOG(LOG_PIC,LOG_NORMAL)("%d:ICW 3 %X",port==0x21 ? 0 : 1,val); if(pic->icw_index++ >= pic->icw_words) pic->icw_index=0; break; case 3: /* icw 4 */ @@ -148,7 +149,7 @@ static void write_data(Bit32u port,Bit8u val) { */ pic->auto_eoi=(val & 0x2)>0; - LOG(LOG_PIC,LOG_NORMAL)("%d:ICW 4 %X",static_cast(port==0x21 ? 0 : 1),static_cast(val)); + LOG(LOG_PIC,LOG_NORMAL)("%d:ICW 4 %X",port==0x21 ? 0 : 1,val); if(pic->icw_index++ >= pic->icw_words) pic->icw_index=0; break; default: /* icw 3, and 4*/ @@ -227,7 +228,7 @@ void PIC_runIRQs(void) { if (!irqs[i].masked && irqs[i].active) { irqs[i].active=false; PIC_IRQCheck&=~(1 << i); - Interrupt(irqs[i].vector); + CPU_HW_Interrupt(irqs[i].vector); if (!pics[0].auto_eoi) { PIC_IRQActive=i; irqs[i].inservice=true; From 88b14bdd8d38000e78ff7c1b4af019b56af6e471 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 20 Nov 2003 10:29:32 +0000 Subject: [PATCH 1374/4131] Fixed stargunner and possibly others. Very little bug in Create new file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1455 --- src/dos/dos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 57c48ef3..6e401a0f 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.60 2003-11-01 16:03:42 harekiet Exp $ */ +/* $Id: dos.cpp,v 1.61 2003-11-20 10:29:32 qbix79 Exp $ */ #include #include @@ -750,7 +750,7 @@ static Bitu DOS_21Handler(void) { DOS_CloseFile(handle); DOS_SetError(DOSERR_ACCESS_DENIED); reg_ax=dos.errorcode; - CALLBACK_SCF(false); + CALLBACK_SCF(true); break; } if (DOS_CreateFile(name1,reg_cx,&handle)) { From e548646683ce544640d0caf5054b7130c7c9b45c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 20 Nov 2003 18:12:13 +0000 Subject: [PATCH 1375/4131] Made cvs compilable again Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1456 --- src/cpu/paging.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index b68538a9..cb376c5a 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -99,8 +99,9 @@ static Bits PageFaultCore(void) { return -1; return 0; } - +#if C_DEBUG Bitu DEBUG_EnableDebugger(void); +#endif void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu type) { /* Save the state of the cpu cores */ @@ -117,7 +118,9 @@ void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu type) { entry->page_addr=page_addr; //Caused by a write by default? CPU_Exception(14,0x2 | ((cpu.cpl>0) ? 0x1 : 0)); +#if C_DEBUG DEBUG_EnableDebugger(); +#endif DOSBOX_RunMachine(); pf_queue.used--; memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); From fa9eb4efa6d2666ef750edc1d15a04d9bd5c5129 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 21 Nov 2003 19:28:50 +0000 Subject: [PATCH 1376/4131] Fix fps for ega Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1457 --- src/hardware/vga_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 50685f97..31fb6318 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -366,7 +366,6 @@ void VGA_SetupDrawing(void) { if (vga.seq.clocking_mode & 1 ) clock/=8; else clock/=9; /* Check for pixel doubling, master clock/2 */ if (vga.seq.clocking_mode & 0x8) { - clock/=2; htotal*=2; } /* Check for dual transfer whatever thing,master clock/2 */ @@ -424,6 +423,7 @@ void VGA_SetupDrawing(void) { width*=9; height=384; pitch=width; + aspect_ratio=1.0; break; case M_TANDY16: width<<=3; From 5152dda24ecd8a5f7aa38d65c15151b63bb8c87b Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 21 Nov 2003 19:54:41 +0000 Subject: [PATCH 1377/4131] set idt to 0 if switching to real mode fixed flag mask to reflect int changes on real mode ints Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1458 --- src/ints/dpmi.cpp | 50 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index fe66ceae..bc8246e5 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -298,6 +298,7 @@ private: Bitu psp; } client; Bit32s mem_handle; /* Handle for GDT/IDT */ + Bitu idtBase,idtLimit; struct { PhysPt base; Bitu limit; @@ -376,6 +377,14 @@ struct { // DPMI static functions // ************************************************ +#define SWITCH_TO_REALMODE CPU_SET_CRX(0,cpu.cr0 & ~CR0_PROTECTION); \ + CPU_SIDT(dpmi.idtLimit,dpmi.idtBase); \ + CPU_LIDT(256*4,0); + +#define SWITCH_TO_PROTMODE CPU_SET_CRX(0,cpu.cr0 | CR0_PROTECTION); \ + CPU_LIDT(dpmi.idtLimit,dpmi.idtBase); + + static DPMI* activeDPMI = 0; static Bit32u originalIntTable[256]; @@ -835,7 +844,7 @@ Bitu DPMI::RealModeCallback(void) desc.Save (dpmi.ldt.base+(dpmi.realStackSelector[dpmi.protStackCurrent] & ~7)); } else E_Exit("DPMI: RealmodeCB: Could not provide real mode stack descriptor."); /* Switch to protected mode */ - CPU_SET_CRX(0,cpu.cr0 | CR0_PROTECTION); + SWITCH_TO_PROTMODE // Setup dataSelector Descriptor data; Bitu dataSelector; @@ -881,7 +890,7 @@ Bitu DPMI::RealModeCallbackReturn(void) PhysPt data = PhysPt(SegPhys(es)+reg_edi); DPMI_LOG("DPMI: CB: Reading RegData at = %04X:%04X",SegValue(es),reg_edi); /* Swtich to real mode */ - CPU_SET_CRX(0,cpu.cr0 & ~CR0_PROTECTION); + SWITCH_TO_REALMODE dpmi.protStackCurrent--; // Restore Registers LoadRegistersFromBuffer(data); @@ -911,7 +920,7 @@ Bitu DPMI::CallRealIRETFrame(bool callAsInt) LoadRegistersFromBuffer(data); PushStack(data); /* Switch to real mode */ - CPU_SET_CRX(0,cpu.cr0 & ~CR0_PROTECTION); + SWITCH_TO_REALMODE // Provide Stack ProvideRealModeStack(prStack,toCopy); // Push flags @@ -935,7 +944,7 @@ Bitu DPMI::CallRealIRETFrameReturn(void) // returning from realmode func DPMI_LOG("DPMI: LEAVE REAL PROC IRETF %d",count); /* Switch to protected mode */ - CPU_SET_CRX(0,cpu.cr0 | CR0_PROTECTION); + SWITCH_TO_PROTMODE // Save registers into real mode structure CopyRegistersToBuffer(PopStack()); // Restore changed Resgisters @@ -963,7 +972,7 @@ Bitu DPMI::SimulateInt(void) LoadRegistersFromBuffer(data); PushStack(data); /* Switch to real mode */ - CPU_SET_CRX(0,cpu.cr0 & ~CR0_PROTECTION); + SWITCH_TO_REALMODE // Provide Stack ProvideRealModeStack(prStack,toCopy); // prepare for return @@ -985,7 +994,7 @@ Bitu DPMI::SimulateIntReturn(void) UpdateRealModeStack(); /* Switch to protected mode */ - CPU_SET_CRX(0,cpu.cr0 | CR0_PROTECTION); + SWITCH_TO_PROTMODE // Save registers into real mode structure CopyRegistersToBuffer(PopStack()); // Restore changed Resgisters @@ -1009,7 +1018,7 @@ void DPMI::PrepareReflectToReal(Bitu num) PushStack(reg_eip); PushStack(SegValue(cs)); /* Swtich to real mode */ - CPU_SET_CRX(0,cpu.cr0 & ~CR0_PROTECTION); + SWITCH_TO_REALMODE // Setup cs:ip to return to intreturn Bitu retcs = RealSeg(CALLBACK_RealPointer(callback.ptorintReturn)); Bitu retip = RealOff(CALLBACK_RealPointer(callback.ptorintReturn)); @@ -1043,7 +1052,7 @@ Bitu DPMI::ptorHandlerReturn(void) { UpdateRealModeStack(); /* Switch to protected mode */ - CPU_SET_CRX(0,cpu.cr0 | CR0_PROTECTION); + SWITCH_TO_PROTMODE // Restore Registers Bitu newcs = PopStack(); reg_eip = PopStack(); @@ -1060,11 +1069,11 @@ Bitu DPMI::ptorHandlerReturn(void) } // Change flags on stack to reflect possible results from ints if (dpmi.client.bit32) { - Bit32u oldFlags = mem_readd(SegPhys(ss)+reg_esp+8) & ~FMASK_NORMAL; // leave only flags that cannot be changed by int + Bit32u oldFlags = mem_readd(SegPhys(ss)+reg_esp+8) & ~FMASK_TEST; // leave only flags that cannot be changed by int Bit32u userFlags = reg_flags & FMASK_NORMAL; // Mask out illegal flags not to change by int (0011111011010101b) mem_writed(SegPhys(ss)+reg_esp+8,oldFlags|userFlags); } else { - Bit16u oldFlags = mem_readw(SegPhys(ss)+reg_sp+4) & ~FMASK_NORMAL; // leave only flags that cannot be changed by int + Bit16u oldFlags = mem_readw(SegPhys(ss)+reg_sp+4) & ~FMASK_TEST; // leave only flags that cannot be changed by int Bit16u userFlags = reg_flags & FMASK_NORMAL; // Mask out illegal flags not to change by int (0011111011010101b) mem_writew(SegPhys(ss)+reg_sp+4,oldFlags|userFlags); }; @@ -1088,7 +1097,7 @@ Bitu DPMI::Int21Handler(void) PushStack(SegValue(cs)); /* Swtich to real mode */ - CPU_SET_CRX(0,cpu.cr0 & ~CR0_PROTECTION); + SWITCH_TO_REALMODE // Setup cs:ip to return to intreturn SegSet16(cs,RealSeg(CALLBACK_RealPointer(callback.int21Return))); reg_ip = RealOff(CALLBACK_RealPointer(callback.int21Return)); @@ -1110,7 +1119,7 @@ Bitu DPMI::Int21HandlerReturn(void) { UpdateRealModeStack(); /* Switch to protected mode */ - CPU_SET_CRX(0,cpu.cr0 | CR0_PROTECTION); + SWITCH_TO_PROTMODE // Restore Registers Bitu newcs = PopStack(); CPU_SetSegGeneral(es,PopStack()); @@ -1249,7 +1258,7 @@ Bitu DPMI::EnterProtMode(void) { SaveRegisterState(0); /* Switch to protected mode */ - CPU_SET_CRX(0,cpu.cr0 | CR0_PROTECTION); + SWITCH_TO_PROTMODE CPU_SetSegGeneral(ds,reg_ax); CPU_SetSegGeneral(es,reg_cx); @@ -1277,7 +1286,7 @@ Bitu DPMI::EnterRealMode(void) { SaveRegisterState(1); /* Swtich to real mode */ - CPU_SET_CRX(0,cpu.cr0 & ~CR0_PROTECTION); + SWITCH_TO_REALMODE // (E)BP will be preserved across the mode switch call so it can be used as a pointer. // TODO: If interrupts are disabled when the mode switch procedure is invoked, // they will not be re-enabled by the DPMI host (even temporarily). @@ -1539,7 +1548,7 @@ Bitu DPMI::Int31Handler(void) if ((!dpmi.client.bit32) && (reg_cx!=0)) { // 16-bit DPMI implementations can not set segment limits greater // than 0FFFFh (64K) so CX must be zero when calling - DPMI_LOG_ERROR("DPMI: 0008: Set Segment Limit invalid: %04X ",reg_bx); + DPMI_LOG_ERROR("DPMI: 0008: Set Segment Limit invalid: %04X (%04X%04X)",reg_bx,reg_cx,reg_dx); reg_ax = DPMI_ERROR_INVALID_VALUE; DPMI_CALLBACK_SCF(true); } else if (cpu.gdt.GetDescriptor(reg_bx,desc)) { @@ -1607,6 +1616,17 @@ Bitu DPMI::Int31Handler(void) DPMI_CALLBACK_SCF(true); break; }; + // TEMP : Test +/* if (!dpmi.client.bit32) { + if (desc.GetLimit()>0xFFFF) { + DPMI_LOG_ERROR("DPMI: 000C: Set Limit %04X : failure (%08X)",reg_bx,desc.GetLimit()); + desc.SetLimit(0xFFFF); + } + if (desc.GetBase ()>0xFFFFFF) { + DPMI_LOG_ERROR("DPMI: 000C: Set Base %04X : failure (%08X)",reg_bx,desc.GetBase()); + desc.SetBase(desc.GetBase() % 0xFFFFFF); + } + }*/ desc.Save(dpmi.ldt.base+(reg_bx & ~7)); ReloadSegments(reg_bx); DPMI_LOG("DPMI: 000B: Set Descriptor %04X : B:%08X L:%08X : P %01X",reg_bx,desc.GetBase(),desc.GetLimit(),desc.saved.seg.p); From fb6045aef14ca17865204c6a1a31a6659eba9a36 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 22 Nov 2003 17:03:49 +0000 Subject: [PATCH 1378/4131] Fix loading a new font always setting vga range to b800-bffff, should fix monochromo text mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1459 --- src/ints/int10_memory.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 7d42c366..e0358ae3 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -47,15 +47,17 @@ static Bit16u map_offset[8]={ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu height) { PhysPt where=PhysMake(0xa000,map_offset[map & 0x7]+offset*32); IO_Write(0x3c4,0x2);IO_Write(0x3c5,0x4); //Enable plane 2 - IO_Write(0x3ce,0x6);IO_Write(0x3cf,0x0); //Disable odd/even and a0000 adressing + IO_Write(0x3ce,0x6);Bitu old_6=IO_Read(0x3cf); + IO_Write(0x3cf,0x0); //Disable odd/even and a0000 adressing for (Bitu i=0;i Date: Sun, 23 Nov 2003 09:49:48 +0000 Subject: [PATCH 1379/4131] Fix 0x66 0x0f prefixed instructions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1460 --- src/cpu/core_full/load.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 3ea74c89..fc3caf66 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -252,7 +252,7 @@ l_M_Ed: break; /* Special cases */ case L_DOUBLE: - inst.entry=inst.start_prefix^0x100; + inst.entry|=0x100; goto restartopcode; case L_PRESEG: inst.prefix|=PREFIX_SEG; @@ -267,7 +267,7 @@ l_M_Ed: inst.repz=true; goto restartopcode; case L_PREOP: - inst.entry^=0x200; + inst.entry=inst.start_entry ^ 0x200; goto restartopcode; case L_PREADD: inst.prefix^=PREFIX_ADDR; From 796809564e7027a1b1c86f13a0ad5c92c0d2132e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 25 Nov 2003 08:26:44 +0000 Subject: [PATCH 1380/4131] Fix setflagb helper Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1461 --- src/cpu/lazyflags.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index 11187b8d..1069e1cd 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -59,7 +59,7 @@ extern LazyFlags lflags; { \ SETFLAGBIT(OF,get_OF()); \ lflags.type=t_UNKNOWN; \ - CPU_SetFlags(reg_flags,FMASK_NORMAL & 0xff); \ + CPU_SetFlags(FLAGB,FMASK_NORMAL & 0xff); \ } #define SETFLAGSw(FLAGW) \ From 96df8584cf232081548f527624e0c2d964abe9fe Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 25 Nov 2003 08:27:50 +0000 Subject: [PATCH 1381/4131] Added reset and enable commands for port 0x60 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1462 --- src/hardware/keyboard.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 23d9395d..8f60f903 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -179,8 +179,21 @@ static void write_p60(Bit32u port,Bit8u val) { keyb.command=CMD_SETTYPERATE; KEYBOARD_AddCode(0xfa,0,0,STATE_NORMAL); /* Acknowledge */ break; + case 0xf4: /* Enable keyboard,clear buffer, start scanning */ + keyb.active=true; + KEYBOARD_ClrBuffer(); + LOG(LOG_KEYBOARD,LOG_NORMAL)("Activated"); + KEYBOARD_AddCode(0xfa,0,0,STATE_NORMAL); /* Acknowledge */ + break; + case 0xf5: /* Reset keyboard and disable scanning */ + case 0xf6: /* Reset keyboard and enable scanning */ + LOG(LOG_KEYBOARD,LOG_NORMAL)("Reset"); + KEYBOARD_AddCode(0xfa,0,0,STATE_NORMAL); /* Acknowledge */ + break; default: + /* Just always acknowledge strange commands */ LOG(LOG_KEYBOARD,LOG_ERROR)("60:Unhandled command %X",val); + KEYBOARD_AddCode(0xfa,0,0,STATE_NORMAL); /* Acknowledge */ } return; case CMD_SETOUTPORT: From f7678d231b528b4afc67b0722715ce7bacd8a87b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 26 Nov 2003 08:38:23 +0000 Subject: [PATCH 1382/4131] Copyright update, g++ warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1463 --- include/dma.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/dma.h b/include/dma.h index dcca1e81..ecda6d36 100644 --- a/include/dma.h +++ b/include/dma.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: dma.h,v 1.8 2003-11-26 08:38:23 qbix79 Exp $ */ + #ifndef __DMA_H #define __DMA_H @@ -189,4 +191,5 @@ extern DmaController *DmaControllers[2]; -#endif \ No newline at end of file +#endif + From 6d1d97b139e272807762049c54f11f140dadb8bf Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 26 Nov 2003 09:25:51 +0000 Subject: [PATCH 1383/4131] Added switch to protected mode call 0x89 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1464 --- src/ints/bios.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 00d6c78b..0958a892 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,12 +16,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.23 2003-11-14 00:04:25 harekiet Exp $ */ +/* $Id: bios.cpp,v 1.24 2003-11-26 09:25:51 harekiet Exp $ */ #include #include "dosbox.h" #include "bios.h" #include "regs.h" +#include "cpu.h" #include "callback.h" #include "inout.h" #include "mem.h" @@ -248,6 +249,24 @@ static Bitu INT15_Handler(void) { LOG(LOG_BIOS,LOG_NORMAL)("INT15:Function 0x88 Remaining %04X kb",reg_ax); CALLBACK_SCF(false); break; + case 0x89: /* SYSTEM - SWITCH TO PROTECTED MODE */ + { + IO_Write(0x20,0x10);IO_Write(0x21,reg_bh);IO_Write(0x21,0); + IO_Write(0xA0,0x10);IO_Write(0xA1,reg_bl);IO_Write(0xA1,0); + MEM_A20_Enable(true); + PhysPt table=SegPhys(es)+reg_si; + CPU_LGDT(mem_readw(table+0x8),mem_readd(table+0x8+0x2) & 0xFFFFFF); + CPU_LIDT(mem_readw(table+0x10),mem_readd(table+0x10+0x2) & 0xFFFFFF); + CPU_SET_CRX(0,CPU_GET_CRX(0)|1); + CPU_SetSegGeneral(ds,0x18); + CPU_SetSegGeneral(es,0x20); + CPU_SetSegGeneral(ss,0x28); + reg_sp+=6; //Clear stack of interrupt frame + CPU_SetFlags(0,FMASK_ALL); + reg_ax=0; + CPU_JMP(false,0x30,reg_cx); + } + break; case 0x90: /* OS HOOK - DEVICE BUSY */ CALLBACK_SCF(false); reg_ah=0; From 2ef1879ac5987cb8ee873298398193a4ced8984a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 26 Nov 2003 17:24:36 +0000 Subject: [PATCH 1384/4131] Fix 32-bit LSL instruction and remove some logging messages for debug registers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1465 --- src/cpu/core_normal/prefix_0f.h | 2 -- src/cpu/core_normal/prefix_66_0f.h | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 85945dce..150a5c33 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -142,7 +142,6 @@ { GetRM; Bitu which=(rm >> 3) & 7; - LOG_MSG("MOV REG,DR%d",which); if (rm >= 0xc0 ) { GetEArd; } else { @@ -168,7 +167,6 @@ { GetRM; Bitu which=(rm >> 3) & 7; - LOG_MSG("MOV DR%d,REG",which); if (rm >= 0xc0 ) { GetEArd; } else { diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 2b578bdc..9aa15dc2 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -120,7 +120,7 @@ } else { GetEAa;CPU_LSL(LoadMw(eaa),limit); } - *rmrd=(Bit16u)limit; + *rmrd=(Bit32u)limit; } break; CASE_0F_D(0x80) /* JO */ From b0d9929ed346bef0f50dd3e913ad0d4b0c913d06 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 27 Nov 2003 09:20:26 +0000 Subject: [PATCH 1385/4131] Fix line compare to always be 1023 for vga mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1466 --- src/ints/int10_modes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 7cfba564..f0f1b0c5 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -279,7 +279,7 @@ foundmode: /* Vertical Retrace End */ IO_Write(crtc_base,0x16);IO_Write(crtc_base+1,(CurMode->vtotal-8)); /* Line Compare */ - Bitu line_compare=CurMode->vtotal+1; //Out of range + Bitu line_compare=(mode>=256) ? 2047 : 1023; IO_Write(crtc_base,0x18);IO_Write(crtc_base+1,line_compare&0xff); overflow|=(line_compare & 0x100) >> 4; max_scanline|=(line_compare & 0x200) >> 3; From ba0c8d9542a23d9376a147a28e65c49fb8223dfa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 27 Nov 2003 18:54:22 +0000 Subject: [PATCH 1386/4131] Added patch 847168 from Michael Drueing Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1467 --- src/ints/mouse.cpp | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index cb8dd185..54a9bf25 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.24 2003-09-24 19:35:01 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.25 2003-11-27 18:54:22 qbix79 Exp $ */ #include #include "dosbox.h" @@ -585,6 +585,23 @@ static Bitu INT33_Handler(void) { SegSet16(es,oldSeg); } break; + case 0x15: /* Get Driver storage space requirements */ + reg_bx = sizeof(mouse); + break; + case 0x16: /* Save driver state */ + { + LOG(LOG_MOUSE,LOG_WARN)("Saving driver state..."); + PhysPt dest = SegPhys(es)+reg_dx; + MEM_BlockWrite(dest, &mouse, sizeof(mouse)); + } + break; + case 0x17: /* load driver state */ + { + LOG(LOG_MOUSE,LOG_WARN)("Loading driver state..."); + PhysPt src = SegPhys(es)+reg_dx; + MEM_BlockRead(src, &mouse, sizeof(mouse)); + } + break; case 0x1a: /* Set mouse sensitivity */ SetMickeyPixelRate(reg_bx,reg_cx); // ToDo : double mouse speed value @@ -600,11 +617,16 @@ static Bitu INT33_Handler(void) { break; case 0x24: /* Get Software version and mouse type */ reg_bx=0x805; //Version 8.05 woohoo - reg_ch=0xff; /* Unkown type */ + reg_ch=0x04; /* PS/2 type */ reg_cl=0; /* Hmm ps2 irq dunno */ break; + case 0x26: /* Get Maximum virtual coordinates */ + reg_bx=(mouse.shown < 0 ? 0xffff : 0x0000); + reg_cx=mouse.max_x; + reg_dx=mouse.max_y; + break; default: - LOG(LOG_MOUSE,LOG_ERROR)("Mouse Function %2X",reg_ax); + LOG(LOG_MOUSE,LOG_ERROR)("Mouse Function %04X not implemented!",reg_ax); } return CBRET_NONE; } From 53008fb6ec2adf5e6812380ef9de2c01e1923e06 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 27 Nov 2003 18:57:42 +0000 Subject: [PATCH 1387/4131] Added c2woody's way of handling 1 concurrent IRQ Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1468 --- src/hardware/pic.cpp | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 896b7c78..08464bf7 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: pic.cpp,v 1.14 2003-11-27 18:57:42 qbix79 Exp $ */ + #include #include "dosbox.h" @@ -70,6 +72,9 @@ static struct { static void write_command(Bit32u port,Bit8u val) { PIC_Controller * pic=&pics[port==0x20 ? 0 : 1]; Bitu irq_base=port==0x20 ? 0 : 8; + Bitu i; + Bit16u IRQ_priority_table[16] = + { 0,1,8,9,10,11,12,13,14,15,2,3,4,5,6,7 }; switch (val) { case 0x0A: /* select read interrupt request register */ pic->request_issr=false; @@ -90,7 +95,13 @@ static void write_command(Bit32u port,Bit8u val) { irqs[PIC_IRQActive].inservice=false; if (irqs[PIC_IRQActive].handler!=0) irqs[PIC_IRQActive].handler(); PIC_IRQActive=PIC_NOIRQ; - }//TODO Warnings? + for (i=0; i<=15; i++){ + if(irqs[IRQ_priority_table[i]].inservice) { + PIC_IRQActive=IRQ_priority_table[i]; + break; + } + } + } //TODO Warnings? break; case 0x60:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:case 0x67: /* Spefific EOI 0-7 */ @@ -98,6 +109,12 @@ static void write_command(Bit32u port,Bit8u val) { irqs[PIC_IRQActive].inservice=false; if (irqs[PIC_IRQActive].handler!=0) irqs[PIC_IRQActive].handler(); PIC_IRQActive=PIC_NOIRQ; + for (i=0; i<=15; i++) { + if (irqs[IRQ_priority_table[i]].inservice) { + PIC_IRQActive=IRQ_priority_table[i]; + break; + } + } }//TODO Warnings? break; case 0xC0:case 0xC1:case 0xC2:case 0xC3:case 0xC4:case 0xC5:case 0xC6:case 0xC7: @@ -221,19 +238,24 @@ void PIC_DeActivateIRQ(Bitu irq) { void PIC_runIRQs(void) { Bitu i; if (!GETFLAG(IF)) return; - if (PIC_IRQActive!=PIC_NOIRQ) return; if (!PIC_IRQCheck) return; + Bit16u IRQ_priority_lookup[17] = + { 0,1,10,11,12,13,14,15,2,3,4,5,6,7,8,9,16 }; + Bit16u activeIRQ = PIC_IRQActive; + if (activeIRQ==PIC_NOIRQ) activeIRQ = 16; for (i=0;i<=15;i++) { - if (i!=2) { - if (!irqs[i].masked && irqs[i].active) { - irqs[i].active=false; - PIC_IRQCheck&=~(1 << i); - CPU_HW_Interrupt(irqs[i].vector); - if (!pics[0].auto_eoi) { - PIC_IRQActive=i; - irqs[i].inservice=true; + if (IRQ_priority_lookup[i] Date: Thu, 27 Nov 2003 20:00:52 +0000 Subject: [PATCH 1388/4131] childpsp gets environment block from parent psp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1469 --- src/dos/dos_execute.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 99139c8b..760b3ccd 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -185,9 +185,11 @@ bool DOS_ChildPSP(Bit16u segment, Bit16u size) psp.MakeNew(size); DOS_PSP psp_parent(psp.GetParent()); psp.CopyFileTable(&psp_parent,true); + psp.SetEnvironment(psp_parent.GetEnvironment()); psp.SetSize(size); return true; }; + static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { /* Fix the PSP for psp and environment MCB's */ From 5ad16d203740f38312eb3684b3207352ffead95d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 30 Nov 2003 11:51:09 +0000 Subject: [PATCH 1389/4131] make static table Fix templates not inlining with gcc Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1470 --- src/gui/render_normal.h | 6 +++--- src/gui/render_scale2x.h | 2 +- src/gui/render_templates.h | 10 ++++++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/gui/render_normal.h b/src/gui/render_normal.h index 1c87ade1..380fff5a 100644 --- a/src/gui/render_normal.h +++ b/src/gui/render_normal.h @@ -53,12 +53,12 @@ static void Normal(Bit8u * src,Bitu x,Bitu y,Bitu _dx,Bitu _dy) { } -RENDER_Part_Handler Normal_SINGLE_8[4]={ +static RENDER_Part_Handler Normal_SINGLE_8[4]={ Normal<8,8 ,false>,Normal<8,16,false>, Normal<8,24,false>,Normal<8,32,false>, }; -RENDER_Part_Handler Normal_DOUBLE_8[4]={ +static RENDER_Part_Handler Normal_DOUBLE_8[4]={ Normal<8,8 ,true>,Normal<8,16,true>, Normal<8,24,true>,Normal<8,32,true>, -}; \ No newline at end of file +}; diff --git a/src/gui/render_scale2x.h b/src/gui/render_scale2x.h index c48ddc19..fcbc16f7 100644 --- a/src/gui/render_scale2x.h +++ b/src/gui/render_scale2x.h @@ -69,7 +69,7 @@ static void AdvMame2x(Bit8u * src,Bitu x,Bitu y,Bitu _dx,Bitu _dy) { } -RENDER_Part_Handler AdvMame2x_8_Table[4]={ +static RENDER_Part_Handler AdvMame2x_8_Table[4]={ AdvMame2x<8,8>,AdvMame2x<8,16>,AdvMame2x<8,24>,AdvMame2x<8,32> }; diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index 3d903609..d5228cdb 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -1,5 +1,11 @@ -template -static INLINE void AddDst(Bit8u * & dst,Bitu val) { +#ifdef __GNUC__ +template static INLINE void AddDst(Bit8u * & dst,Bitu val) __attribute__ ((always_inline)); +template static INLINE Bitu LineSize(Bitu pixels) __attribute__ ((always_inline)); +template static INLINE Bitu LoadSrc(Bit8u * & src) __attribute__ ((always_inline)); +template static INLINE Bitu ConvBPP(Bitu val) __attribute__ ((always_inline)); +#endif + +template static INLINE void AddDst(Bit8u * & dst,Bitu val) { switch (dbpp) { case 8: *(Bit8u*)dst=val;dst+=1;break; case 16:*(Bit16u*)dst=val;dst+=2;break; From 9f1e9e305d6c4b209d94bab0e5a2ceebfd01c1fe Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Wed, 3 Dec 2003 01:30:28 +0000 Subject: [PATCH 1390/4131] Change to ensure correct number of channels played Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1471 --- src/hardware/gus.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 64ad12a0..8c82ae93 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -704,7 +704,7 @@ static void ExecuteGlobRegister(void) { } break; case 0xE: // Set active channel register - myGUS.activechan = myGUS.gRegData & 63; + myGUS.activechan = (myGUS.gRegData & 31) + 1; if(myGUS.activechan < 14) myGUS.activechan = 14; if(myGUS.activechan > 32) myGUS.activechan = 32; MIXER_Enable(gus_chan,true); From 0bec45e6b7048adc7191c7cbdb4dad9becd85fd3 Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Wed, 3 Dec 2003 02:51:57 +0000 Subject: [PATCH 1391/4131] Fixed channel iterating Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1472 --- src/hardware/gus.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 8c82ae93..1341b2f3 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -704,7 +704,7 @@ static void ExecuteGlobRegister(void) { } break; case 0xE: // Set active channel register - myGUS.activechan = (myGUS.gRegData & 31) + 1; + myGUS.activechan = (myGUS.gRegData & 31) +1; if(myGUS.activechan < 14) myGUS.activechan = 14; if(myGUS.activechan > 32) myGUS.activechan = 32; MIXER_Enable(gus_chan,true); @@ -716,7 +716,7 @@ static void ExecuteGlobRegister(void) { myGUS.muperchan = (Bit32s)((float)1.6 * (float)myGUS.activechan * 1024); LOG_MSG("GUS set to %d channels", myGUS.activechan); - for(i=0;i<=myGUS.activechan;i++) { if(guschan[i] != NULL) guschan[i]->UpdateFreqCtrl(); } + for(i=0;iUpdateFreqCtrl(); } break; case 0x10: // Undocumented register used in Fast Tracker 2 @@ -946,7 +946,7 @@ static void GUS_CallBack(Bit8u * stream,Bit32u len) { memset(&tmpbuf[0],0,len*8); int i,t; - for(i=0;i<=myGUS.activechan;i++) { + for(i=0;iplaying) { guschan[i]->generateSamples(&buffer[0],len); From 3655cc0cc65885b905b3c71aa0aeb92e8dca656e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 3 Dec 2003 09:44:43 +0000 Subject: [PATCH 1392/4131] First run scancodes through int 15 0x4f before handling them in bios Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1473 --- src/ints/bios_keyboard.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 80de0814..864f09e9 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -207,6 +207,12 @@ static Bitu IRQ1_Handler(void) { KEYBOARD_ReadKey(scancode,ascii,mod); // LOG(0,"Got code %X ascii %C mod %X",scancode,ascii,mod); #endif + Bit16u old_ax=reg_ax; + reg_flags|=1; + reg_ah=0x4f;reg_al=scancode; + CALLBACK_RunRealInt(0x15); + reg_ax=old_ax; + if (!(reg_flags&1)) goto irq1_return; //TODO maybe implement the int 0x15 ah=4f scancode lookup hook Bit8u flags1=mem_readb(BIOS_KEYBOARD_FLAGS1); @@ -284,6 +290,7 @@ irq1_end: mem_writeb(BIOS_KEYBOARD_FLAGS1,flags1); mem_writeb(BIOS_KEYBOARD_FLAGS2,flags2); mem_writeb(BIOS_KEYBOARD_FLAGS3,flags3); +irq1_return: IO_Write(0x20,0x20); #if 0 /* Signal the keyboard for next code */ From f90b1c310d91ccc9657697df833a3c8efec4bc53 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 3 Dec 2003 14:01:11 +0000 Subject: [PATCH 1393/4131] Fix correct releasing of paging links new phys_read/write functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1474 --- src/hardware/memory.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 37db0530..f9ed5a56 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -40,7 +40,7 @@ struct AllocBlock { }; struct LinkBlock { - Bit8u used; + Bitu used; Bit32u pages[MAX_LINKS]; }; @@ -156,6 +156,7 @@ void MEM_SetPageHandler(Bitu phys_page,Bitu pages,PageHandler * handler) { void MEM_UnlinkPages(void) { PAGING_ClearTLBEntries(memory.links.used,memory.links.pages); + memory.links.used=0; } Bitu mem_strlen(PhysPt pt) { @@ -495,6 +496,8 @@ void phys_writed(PhysPt addr,Bit32u val) { Bit32u MEM_PhysReadD(Bitu addr) { Bitu page=addr >> 12; Bitu index=(addr & 4095); + if (page>memory.pages) + E_Exit("Reading from illegal page"); HostPt block=memory.hostpts[page]; if (!block) { E_Exit("Reading from empty page"); @@ -502,6 +505,18 @@ Bit32u MEM_PhysReadD(Bitu addr) { return host_readd(block+index); } +void MEM_PhysWriteD(Bitu addr,Bit32u val) { + Bitu page=addr >> 12; + Bitu index=(addr & 4095); + if (page>memory.pages) + E_Exit("Writing from illegal page"); + HostPt block=memory.hostpts[page]; + if (!block) { + E_Exit("Writing to empty page"); + } + host_writed(block+index,val); +} + static void write_p92(Bit32u port,Bit8u val) { // Bit 0 = system reset (switch back to real mode) From c13138ad6ecfe3fe894405bdc758c22c26f6ffca Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 3 Dec 2003 14:02:29 +0000 Subject: [PATCH 1394/4131] Set dirty/access bits on page acces use new physical memory read/write functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1475 --- src/cpu/paging.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index cb376c5a..af2230f4 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -105,7 +105,6 @@ Bitu DEBUG_EnableDebugger(void); void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu type) { /* Save the state of the cpu cores */ - LOG_MSG("PageFault at %X type %d queue %d",lin_addr,type,pf_queue.used); LazyFlags old_lflags; memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); CPU_Decoder * old_cpudecoder; @@ -113,21 +112,24 @@ void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu type) { cpudecoder=&PageFaultCore; paging.cr2=lin_addr; PF_Entry * entry=&pf_queue.entries[pf_queue.used++]; + LOG(LOG_PAGING,LOG_NORMAL)("PageFault at %X type %d queue %d",lin_addr,type,pf_queue.used); entry->cs=SegValue(cs); entry->eip=reg_eip; entry->page_addr=page_addr; //Caused by a write by default? - CPU_Exception(14,0x2 | ((cpu.cpl>0) ? 0x1 : 0)); + CPU_Exception(14,0x2 ); #if C_DEBUG - DEBUG_EnableDebugger(); +// DEBUG_EnableDebugger(); #endif DOSBOX_RunMachine(); pf_queue.used--; + LOG(LOG_PAGING,LOG_NORMAL)("Left PageFault for %x queue %d",lin_addr,pf_queue.used); memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); cpudecoder=old_cpudecoder; } +void MEM_PhysWriteD(Bitu addr,Bit32u val); class InitPageHandler : public PageHandler { public: InitPageHandler() {flags=PFLAG_ILLEGAL;} @@ -174,6 +176,8 @@ public: if (!table.block.p) E_Exit("Pagefault didn't correct table"); } + table.block.a=table.block.d=1; //Set access/Dirty + MEM_PhysWriteD(table_addr,table.load); X86PageEntry entry; Bitu entry_addr=(table.block.base << 12)+t_index*4; entry.load=MEM_PhysReadD(entry_addr); @@ -184,8 +188,9 @@ public: if (!entry.block.p) E_Exit("Pagefault didn't correct page"); } + entry.block.a=entry.block.d=1; //Set access/Dirty + MEM_PhysWriteD(entry_addr,entry.load); phys_page=entry.block.base; - LOG_MSG("Linked page lin page %X to phys page %X",lin_page,phys_page); } else { if (lin_page=TLB_SIZE || phys_page>=TLB_SIZE) + E_Exit("Illegal page"); HostPt host_mem=handler->GetHostPt(phys_page); paging.tlb.phys_page[lin_page]=phys_page; if (handler->flags & PFLAG_READABLE) paging.tlb.read[lin_page]=host_mem-lin_base; From e281aed2dd9f845a34bbd8f43b8c237a8b4bdf8f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 3 Dec 2003 14:06:09 +0000 Subject: [PATCH 1395/4131] fix variable init errors in gcc Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1476 --- src/ints/bios_keyboard.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 864f09e9..b5e300c9 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -211,13 +211,13 @@ static Bitu IRQ1_Handler(void) { reg_flags|=1; reg_ah=0x4f;reg_al=scancode; CALLBACK_RunRealInt(0x15); - reg_ax=old_ax; + reg_ax=old_ax;Bit8u flags1,flags2,flags3; if (!(reg_flags&1)) goto irq1_return; //TODO maybe implement the int 0x15 ah=4f scancode lookup hook - Bit8u flags1=mem_readb(BIOS_KEYBOARD_FLAGS1); - Bit8u flags2=mem_readb(BIOS_KEYBOARD_FLAGS2); - Bit8u flags3=mem_readb(BIOS_KEYBOARD_FLAGS3); + flags1=mem_readb(BIOS_KEYBOARD_FLAGS1); + flags2=mem_readb(BIOS_KEYBOARD_FLAGS2); + flags3=mem_readb(BIOS_KEYBOARD_FLAGS3); switch (scancode) { /* First the hard ones */ case 0xe0: /* Extended key */ From ff18ffe3141c5fcfe1cc23fc279a095292a39443 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 9 Dec 2003 21:10:31 +0000 Subject: [PATCH 1396/4131] Fixed possible bug in xms with handlecount Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1477 --- src/ints/xms.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index a02177c6..854e099c 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: xms.cpp,v 1.29 2003-12-09 21:10:31 qbix79 Exp $ */ + #include #include #include "dosbox.h" @@ -120,7 +122,7 @@ Bitu XMS_AllocateMemory(Bitu size, Bit16u& handle) /* Find free handle */ Bit16u index=1; while (!xms_handles[index].free) { - if (++index>XMS_HANDLES) return XMS_OUT_OF_HANDLES; + if (++index>=XMS_HANDLES) return XMS_OUT_OF_HANDLES; } Bitu pages=(size/4) + ((size & 3) ? 1 : 0); MemHandle mem=MEM_AllocatePages(pages,true); From 40e2a1507a67a7c41b61b3a17841a7c1d4cba4ef Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Dec 2003 09:34:21 +0000 Subject: [PATCH 1397/4131] changed dta in dos_Execute fixes: zone66 and unpack Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1478 --- src/dos/dos_execute.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 760b3ccd..e1d73073 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -374,7 +374,8 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { /* Switch the psp's and set new DTA */ dos.psp=pspseg; DOS_PSP newpsp(dos.psp); - dos.dta=newpsp.GetDTA(); + newpsp.SetDTA(dos.dta); /* Original: change this and line below. This way seems better(zone66 and unpack) */ + //dos.dta=newpsp.GetDTA(); /* save vectors */ newpsp.SaveVectors(); /* copy fcbs */ From 6fdc7a5359f987fedf5e9428265199dcd5d40ab0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Dec 2003 13:20:26 +0000 Subject: [PATCH 1398/4131] added cpu cycle changing by configfile Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1479 --- src/cpu/cpu.cpp | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 36084d92..4081808a 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.39 2003-11-18 22:35:56 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.40 2003-12-10 13:20:26 qbix79 Exp $ */ #include #include "dosbox.h" @@ -38,9 +38,11 @@ CPU_Regs cpu_regs; CPUBlock cpu; Segments Segs; -Bits CPU_Cycles=0; -Bits CPU_CycleLeft=0; -Bits CPU_CycleMax=1500; +Bits CPU_Cycles = 0; +Bits CPU_CycleLeft = 0; +Bits CPU_CycleMax = 1800; +Bits CPU_CycleUp = 0; +Bits CPU_CycleDown = 0; CPU_Decoder * cpudecoder; void CPU_Real_16_Slow_Start(bool big); @@ -1144,7 +1146,12 @@ void CPU_HLT(Bitu oplen) { extern void GFX_SetTitle(Bits cycles ,Bits frameskip); static void CPU_CycleIncrease(void) { Bits old_cycles=CPU_CycleMax; - CPU_CycleMax=(Bits)(CPU_CycleMax*1.2); + if(CPU_CycleUp < 100){ + CPU_CycleMax = (Bits)(CPU_CycleMax * (1 + (float)CPU_CycleUp / 100.0)); + } else { + CPU_CycleMax = (Bits)(CPU_CycleMax + CPU_CycleUp); + } + CPU_CycleLeft=0;CPU_Cycles=0; if (CPU_CycleMax==old_cycles) CPU_CycleMax++; LOG_MSG("CPU:%d cycles",CPU_CycleMax); @@ -1152,9 +1159,13 @@ static void CPU_CycleIncrease(void) { } static void CPU_CycleDecrease(void) { - CPU_CycleMax=(Bits)(CPU_CycleMax/1.2); + if(CPU_CycleDown < 100){ + CPU_CycleMax = (Bits)(CPU_CycleMax / (1 + (float)CPU_CycleDown / 100.0)); + } else { + CPU_CycleMax = (Bits)(CPU_CycleMax - CPU_CycleDown); + } CPU_CycleLeft=0;CPU_Cycles=0; - if (!CPU_CycleMax) CPU_CycleMax=1; + if (CPU_CycleMax <= 0) CPU_CycleMax=1; LOG_MSG("CPU:%d cycles",CPU_CycleMax); GFX_SetTitle(CPU_CycleMax,-1); } @@ -1196,7 +1207,11 @@ void CPU_Init(Section* sec) { CPU_Cycles=0; CPU_CycleMax=section->Get_int("cycles");; - if (!CPU_CycleMax) CPU_CycleMax=1500; + CPU_CycleUp=section->Get_int("cycleup"); + CPU_CycleDown=section->Get_int("cycledown"); + if (!CPU_CycleMax) CPU_CycleMax = 1800; + if(!CPU_CycleUp) CPU_CycleUp = 500; + if(!CPU_CycleDown) CPU_CycleDown = 20; CPU_CycleLeft=0; GFX_SetTitle(CPU_CycleMax,-1); } From 60e425dfe9538a6942a20782d64bcd75940b796e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Dec 2003 14:55:49 +0000 Subject: [PATCH 1399/4131] added PIC_SetIRQMask Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1480 --- include/pic.h | 1 + src/hardware/pic.cpp | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/include/pic.h b/include/pic.h index 17f21e43..6daa09e3 100644 --- a/include/pic.h +++ b/include/pic.h @@ -63,5 +63,6 @@ void PIC_AddEvent(PIC_EventHandler handler,Bitu delay); void PIC_RemoveEvents(PIC_EventHandler handler); +void PIC_SetIRQMask(Bitu irq, bool masked); #endif diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 08464bf7..47c4dc65 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.14 2003-11-27 18:57:42 qbix79 Exp $ */ +/* $Id: pic.cpp,v 1.15 2003-12-10 14:55:08 qbix79 Exp $ */ #include @@ -261,6 +261,19 @@ void PIC_runIRQs(void) { } } +void PIC_SetIRQMask(Bitu irq, bool masked) { + irqs[irq].masked=masked; + if (irqs[irq].active && !irqs[irq].masked) { + PIC_IRQCheck|=(1 << (irq)); + } else { + PIC_IRQCheck&=~(1 << (irq)); + }; + if (PIC_IRQCheck) { + CPU_CycleLeft+=CPU_Cycles; + CPU_Cycles=0; + } +} + static void AddEntry(PICEntry * entry) { PICEntry * find_entry=pic.next_entry; if (!find_entry) { @@ -483,7 +496,7 @@ void PIC_Init(Section* sec) { irqs[0].masked=false; /* Enable system timer */ irqs[1].masked=false; /* Enable Keyboard IRQ */ irqs[8].masked=false; /* Enable RTC IRQ */ - irqs[12].masked=false; /* Enable Mouse IRQ */ +/* irqs[12].masked=false; moved to mouse.cpp */ /* Enable Mouse IRQ */ IO_RegisterReadHandler(0x20,read_command,"Master PIC Command"); IO_RegisterReadHandler(0x21,read_data,"Master PIC Data"); IO_RegisterWriteHandler(0x20,write_command,"Master PIC Command"); From a3f5f3c445f1ab16190c19392528b922a8dd7feb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Dec 2003 14:59:53 +0000 Subject: [PATCH 1400/4131] unmask irq on hardware reset. used MOUSE_IRQ instead of 12 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1481 --- src/ints/mouse.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 54a9bf25..09f18bdd 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.25 2003-11-27 18:54:22 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.26 2003-12-10 14:59:53 qbix79 Exp $ */ #include #include "dosbox.h" @@ -120,7 +120,7 @@ INLINE void Mouse_AddEvent(Bit16u type) { mouse.event_queue[mouse.events].buttons=mouse.buttons; mouse.events++; } - PIC_ActivateIRQ(12); + PIC_ActivateIRQ(MOUSE_IRQ); } // *************************************************************************** @@ -395,12 +395,20 @@ static void mouse_reset_hardware(void){ mouse.sub_mask=0; mouse.sub_seg=0; mouse.sub_ofs=0; + PIC_SetIRQMask(MOUSE_IRQ,false); }; static void mouse_reset(void) { WriteMouseIntVector(); - real_writed(0,(0x74<<2),CALLBACK_RealPointer(call_int74)); + +// real_writed(0,(0x74<<2),CALLBACK_RealPointer(call_int74)); + if(MOUSE_IRQ > 7) { + real_writed(0,((0x70+MOUSE_IRQ-8)<<2),CALLBACK_RealPointer(call_int74)); + } else { + real_writed(0,((0x8+MOUSE_IRQ)<<2),CALLBACK_RealPointer(call_int74)); + } + mouse.shown=-1; /* Get the correct resolution from the current video mode */ Bitu mode=mem_readb(BIOS_VIDEO_MODE); @@ -618,7 +626,7 @@ static Bitu INT33_Handler(void) { case 0x24: /* Get Software version and mouse type */ reg_bx=0x805; //Version 8.05 woohoo reg_ch=0x04; /* PS/2 type */ - reg_cl=0; /* Hmm ps2 irq dunno */ + reg_cl=MOUSE_IRQ; /* Hmm ps2 irq dunno */ break; case 0x26: /* Get Maximum virtual coordinates */ reg_bx=(mouse.shown < 0 ? 0xffff : 0x0000); @@ -664,7 +672,7 @@ static Bitu INT74_Handler(void) { IO_Write(0x20,0x20); /* Check for more Events if so reactivate IRQ */ if (mouse.events) { - PIC_ActivateIRQ(12); + PIC_ActivateIRQ(MOUSE_IRQ); } return CBRET_NONE; } @@ -700,7 +708,11 @@ void MOUSE_Init(Section* sec) { call_int74=CALLBACK_Allocate(); CALLBACK_Setup(call_int74,&INT74_Handler,CB_IRET); - real_writed(0,(0x74<<2),CALLBACK_RealPointer(call_int74)); + if(MOUSE_IRQ > 7) { + real_writed(0,((0x70+MOUSE_IRQ-8)<<2),CALLBACK_RealPointer(call_int74)); + } else { + real_writed(0,((0x8+MOUSE_IRQ)<<2),CALLBACK_RealPointer(call_int74)); + } memset(&mouse,0,sizeof(mouse)); mouse_reset_hardware(); From 9c7b2aa63826ce1830e2b431d60a59fb746a2661 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 10 Dec 2003 17:02:22 +0000 Subject: [PATCH 1401/4131] Changed exception handling to let core start the exception. Added support for segment load exceptions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1482 --- src/cpu/core_full/load.h | 13 +++- src/cpu/core_full/op.h | 117 +++++++++++++---------------- src/cpu/core_full/optable.h | 24 +++--- src/cpu/core_full/support.h | 2 +- src/cpu/core_normal.cpp | 14 ++-- src/cpu/core_normal/helpers.h | 14 ++++ src/cpu/core_normal/prefix_0f.h | 17 +++-- src/cpu/core_normal/prefix_66.h | 20 +++-- src/cpu/core_normal/prefix_66_0f.h | 15 ++-- src/cpu/core_normal/prefix_none.h | 58 ++++++++------ src/cpu/cpu.cpp | 67 ++++++++++------- 11 files changed, 206 insertions(+), 155 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index fc3caf66..64740693 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -61,9 +61,12 @@ l_M_Ewx: if (inst.rm<0xc0) inst.op1.ds=(Bit16s)LoadMw(inst.rm_eaa); else inst.op1.ds=(Bit16s)reg_16(inst.rm_eai); break; + case M_EwIb: + inst.op2.d=Fetchb(); + goto l_M_Ew; case M_EwIbx: inst.op2.ds=Fetchbs(); - goto l_M_Ew; + goto l_M_Ew; case M_EwIw: inst.op2.d=Fetchw(); goto l_M_Ew; @@ -96,6 +99,9 @@ l_M_Ew: if (inst.rm<0xc0) inst.op1.d=(Bit32s)LoadMd(inst.rm_eaa); else inst.op1.d=(Bit32s)reg_32(inst.rm_eai); break; + case M_EdIb: + inst.op2.d=Fetchb(); + goto l_M_Ed; case M_EdIbx: inst.op2.ds=Fetchbs(); goto l_M_Ed; @@ -486,7 +492,10 @@ l_M_Ed: goto nextopcode; case D_HLT: LEAVECORE; - CPU_HLT(IPPoint-inst.start); + if (CPU_HLT()) { + reg_eip-=IPPoint-inst.start; + CPU_StartException(); + } return CBRET_NONE; default: LOG(LOG_CPU,LOG_ERROR)("LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry); diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 4bc16941..c54567a5 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -345,7 +345,10 @@ switch (inst.code.op) { else if (DEBUG_IntBreakpoint(inst.op1.b)) return debugCallback; #endif - CPU_SW_Interrupt(inst.op1.b,IPPoint-inst.start); + if (CPU_SW_Interrupt(inst.op1.b)) { + reg_eip-=IPPoint-inst.start; + CPU_StartException(); + } goto restart_core; case O_INb: reg_al=IO_Read(inst.op1.d); @@ -453,11 +456,11 @@ switch (inst.code.op) { inst.op1.d=CPU_GET_CRX(inst.rm_index); break; case O_M_DRx_Rd: - LOG(LOG_CPU,LOG_NORMAL)("MOV DR%d,%X",inst.rm_index,inst.op1.d); +// LOG(LOG_CPU,LOG_NORMAL)("MOV DR%d,%X",inst.rm_index,inst.op1.d); break; case O_M_Rd_DRx: inst.op1.d=0; - LOG(LOG_CPU,LOG_NORMAL)("MOV %X,DR%d",inst.op1.d,inst.rm_index); +// LOG(LOG_CPU,LOG_NORMAL)("MOV %X,DR%d",inst.op1.d,inst.rm_index); break; case O_LAR: { @@ -483,14 +486,14 @@ switch (inst.code.op) { break; case O_BSFw: { - FillFlags(); if (!inst.op1.w) { SETFLAGBIT(ZF,true); + goto nextopcode; } else { Bitu count=0; - while (count<16) { - if ((inst.op1.w>>count) & 1) break; - count++; + while (1) { + if (inst.op1.w & 0x1) break; + count++;inst.op1.w>>=1; } inst.op1.d=count; SETFLAGBIT(ZF,false); @@ -502,11 +505,12 @@ switch (inst.code.op) { FillFlags(); if (!inst.op1.d) { SETFLAGBIT(ZF,true); + goto nextopcode; } else { Bitu count=0; - while (count<32) { - if ((inst.op1.d>>count) & 1) break; - count++; + while (1) { + if (inst.op1.d & 0x1) break; + count++;inst.op1.d>>=1; } inst.op1.d=count; SETFLAGBIT(ZF,false); @@ -518,11 +522,12 @@ switch (inst.code.op) { FillFlags(); if (!inst.op1.w) { SETFLAGBIT(ZF,true); + goto nextopcode; } else { - Bits count=15; - while (count>0) { - if ((inst.op1.w>>count) & 1) break; - count--; + Bitu count=15; + while (1) { + if (inst.op1.w & 0x8000) break; + count--;inst.op1.w<<=1; } inst.op1.d=count; SETFLAGBIT(ZF,false); @@ -534,11 +539,12 @@ switch (inst.code.op) { FillFlags(); if (!inst.op1.d) { SETFLAGBIT(ZF,true); + goto nextopcode; } else { - Bits count=31; - while (count>0) { - if ((inst.op1.d>>count) & 1) break; - count--; + Bitu count=31; + while (1) { + if (inst.op1.d & 0x80000000) break; + count--;inst.op1.d<<=1; } inst.op1.d=count; SETFLAGBIT(ZF,false); @@ -546,57 +552,42 @@ switch (inst.code.op) { } break; case O_BTw: + FillFlags(); + SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15)))); + break; case O_BTSw: + FillFlags(); + SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15)))); + inst.op1.d|=(1 << (inst.op2.d & 15)); + break; case O_BTCw: + FillFlags(); + SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15)))); + inst.op1.d&=~(1 << (inst.op2.d & 15)); + break; case O_BTRw: - { - Bitu val;PhysPt read; - Bitu mask=1 << (inst.op1.d & 15); - FillFlags(); - if (inst.rm<0xc0) { - read=inst.rm_eaa;//+2*(inst.op1.d / 16); - val=mem_readw(read); - } else { - val=reg_16(inst.rm_eai); - } - SETFLAGBIT(CF,(val&mask)>0); - if (inst.code.op==O_BTSw) val|=mask; - if (inst.code.op==O_BTRw) val&=~mask; - if (inst.code.op==O_BTCw) val^=mask; - if (inst.code.op==O_BTw) break; - if (inst.rm<0xc0) { - mem_writew(read,val); - } else { - reg_16(inst.rm_eai)=val; - } - } + FillFlags(); + SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15)))); + inst.op1.d^=(1 << (inst.op2.d & 15)); break; case O_BTd: - case O_BTSd: - case O_BTCd: - case O_BTRd: - { - Bitu val;PhysPt read; - Bitu mask=1 << (inst.op1.d & 31); - FillFlags(); - if (inst.rm<0xc0) { - read=inst.rm_eaa;//+4*(inst.op1.d / 32); - val=mem_readd(read); - } else { - val=reg_32(inst.rm_eai); - } - SETFLAGBIT(CF,(val&mask)>0); - if (inst.code.op==O_BTSd) val|=mask; - if (inst.code.op==O_BTRd) val&=~mask; - if (inst.code.op==O_BTCd) val^=mask; - if (inst.code.op==O_BTd) break; - if (inst.rm<0xc0) { - mem_writed(read,val); - } else { - reg_32(inst.rm_eai)=val; - } - } + FillFlags(); + SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31)))); break; + case O_BTSd: + FillFlags(); + SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31)))); + inst.op1.d|=(1 << (inst.op2.d & 31)); + break; + case O_BTCd: + FillFlags(); + SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31)))); + inst.op1.d&=~(1 << (inst.op2.d & 31)); + break; + case O_BTRd: + FillFlags(); + SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31)))); + inst.op1.d^=(1 << (inst.op2.d & 31)); case O_BSWAP: BSWAP(inst.op1.d); break; diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 7213c6fc..3b82fca2 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -294,23 +294,23 @@ static OpCode OpCodeTable[1024]={ /* 0x1a0 - 0x1a7 */ {L_SEG ,0 ,S_PUSHw ,fs },{L_POPw ,0 ,S_SEGI ,fs }, -{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTw ,0 ,M_Gw }, +{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTw ,S_Ew ,M_EwGw }, {L_MODRM ,O_DSHLw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHLw ,S_Ew ,M_EwGwCL }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x1a8 - 0x1af */ {L_SEG ,0 ,S_PUSHw ,gs },{L_POPw ,0 ,S_SEGI ,gs }, -{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSw ,0 ,M_Gw }, +{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSw ,S_Ew ,M_EwGw }, {L_MODRM ,O_DSHRw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHRw ,S_Ew ,M_EwGwCL }, {0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRw ,S_Gw ,M_EwxGwx }, /* 0x1b0 - 0x1b7 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,O_SEGSS ,S_SEGGw,M_Efw },{L_MODRM ,O_BTRw ,0 ,M_Gw }, +{L_MODRM ,O_SEGSS ,S_SEGGw,M_Efw },{L_MODRM ,O_BTRw ,S_Ew ,M_EwGw }, {L_MODRM ,O_SEGFS ,S_SEGGw,M_Efw },{L_MODRM ,O_SEGGS ,S_SEGGw,M_Efw }, {L_MODRM ,0 ,S_Gw ,M_Eb },{L_MODRM ,0 ,S_Gw ,M_Ew }, /* 0x1b8 - 0x1bf */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,0xe ,0 ,M_GRP },{L_MODRM ,O_BTCw ,0 ,M_Gw }, +{L_MODRM ,0xe ,0 ,M_GRP },{L_MODRM ,O_BTCw ,S_Ew ,M_EwGw }, {L_MODRM ,O_BSFw ,S_Gw ,M_Ew },{L_MODRM ,O_BSRw ,S_Gw ,M_Ew }, {L_MODRM ,0 ,S_Gw ,M_Ebx },{L_MODRM ,0 ,S_Gw ,M_Ewx }, @@ -650,23 +650,23 @@ static OpCode OpCodeTable[1024]={ /* 0x3a0 - 0x3a7 */ {L_SEG ,0 ,S_PUSHd ,fs },{L_POPd ,0 ,S_SEGI ,fs }, -{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTd ,0 ,M_Gd }, +{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTd ,S_Ed ,M_EdGd }, {L_MODRM ,O_DSHLd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHLd ,S_Ed ,M_EdGdCL }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x3a8 - 0x3af */ {L_SEG ,0 ,S_PUSHd ,gs },{L_POPd ,0 ,S_SEGI ,gs }, -{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSd ,0 ,M_Gd }, +{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSd ,S_Ed ,M_EdGd }, {L_MODRM ,O_DSHRd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHRd ,S_Ed ,M_EdGdCL }, {0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdxGdx }, /* 0x3b0 - 0x3b7 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,O_SEGSS ,S_SEGGd,M_Efd },{L_MODRM ,O_BTRd ,0 ,M_Gd }, +{L_MODRM ,O_SEGSS ,S_SEGGd,M_Efd },{L_MODRM ,O_BTRd ,S_Ed ,M_EdGd }, {L_MODRM ,O_SEGFS ,S_SEGGd,M_Efd },{L_MODRM ,O_SEGGS ,S_SEGGd,M_Efd }, {L_MODRM ,0 ,S_Gd ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ew }, /* 0x3b8 - 0x3bf */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,0xf ,0 ,M_GRP },{L_MODRM ,O_BTCd ,0 ,M_Gd }, +{L_MODRM ,0xf ,0 ,M_GRP },{L_MODRM ,O_BTCd ,S_Ed ,M_EdGd }, {L_MODRM ,O_BSFd ,S_Gd ,M_Ed },{L_MODRM ,O_BSRd ,S_Gd ,M_Ed }, {L_MODRM ,0 ,S_Gd ,M_Ebx },{L_MODRM ,0 ,S_Gd ,M_Ewx }, @@ -796,13 +796,13 @@ static OpCode Groups[16][8]={ },{ /* 0x0e Group 8 Ew */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,O_BTw ,0 ,M_Ib },{0 ,O_BTSw ,0 ,M_Ib }, -{0 ,O_BTRw ,0 ,M_Ib },{0 ,O_BTCw ,0 ,M_Ib }, +{0 ,O_BTw ,S_Ew ,M_EwIb },{0 ,O_BTSw ,S_Ew ,M_EwIb }, +{0 ,O_BTRw ,S_Ew ,M_EwIb },{0 ,O_BTCw ,S_Ew ,M_EwIb }, },{ /* 0x0f Group 8 Ed */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,O_BTd ,0 ,M_Ib },{0 ,O_BTSd ,0 ,M_Ib }, -{0 ,O_BTRd ,0 ,M_Ib },{0 ,O_BTCd ,0 ,M_Ib }, +{0 ,O_BTd ,S_Ed ,M_Ib },{0 ,O_BTSd ,S_Ed ,M_EdIb }, +{0 ,O_BTRd ,S_Ed ,M_Ib },{0 ,O_BTCd ,S_Ed ,M_EdIb }, diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 685b5b2c..ade673e8 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -133,7 +133,7 @@ enum { M_Ewx,M_Ew,M_Gw,M_EwGw,M_GwEw,M_EwxGwx, M_Edx,M_Ed,M_Gd,M_EdGd,M_GdEd,M_EdxGdx, - M_EbIb, + M_EbIb,M_EwIb,M_EdIb, M_EwIw,M_EwIbx,M_EwxIbx,M_EwxIwx,M_EwGwIb,M_EwGwCL, M_EdId,M_EdIbx,M_EdGdIb,M_EdGdCL, diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 467451da..af52aeea 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -152,9 +152,9 @@ static GetEATable * EAPrefixTable[8] = { #define EALookupTable (*(core.ea_table)) -static Bits CPU_Core_Normal_Decode_Trap(void); +Bits CPU_Core_Normal_Decode_Trap(void); -static Bits CPU_Core_Normal_Decode(void) { +Bits CPU_Core_Normal_Decode(void) { decode_start: if (cpu.code.big) { core.index_default=0x200; @@ -165,7 +165,7 @@ decode_start: } LOADIP; lflags.type=t_UNKNOWN; - while (CPU_Cycles>0) { + while (CPU_Cycles-->0) { core.op_start=core.ip_lookup; core.opcode_index=core.index_default; core.prefixes=core.prefix_default; @@ -179,7 +179,6 @@ decode_start: }; #endif #endif - CPU_Cycles--; restart_prefix: core.ea_table=EAPrefixTable[core.prefixes]; restart_opcode: @@ -203,15 +202,16 @@ restart_opcode: return CBRET_NONE; } -static Bits CPU_Core_Normal_Decode_Trap(void) { +Bits CPU_Core_Normal_Decode_Trap(void) { Bits oldCycles = CPU_Cycles; CPU_Cycles = 1; core.trap.skip=false; Bits ret=CPU_Core_Normal_Decode(); - if (!core.trap.skip) CPU_SW_Interrupt(1,0); - + if (!core.trap.skip) if (CPU_SW_Interrupt(1)) { + E_Exit("Exception in trap flag cpu core, noooooooo"); + } CPU_Cycles = oldCycles-1; cpudecoder = &CPU_Core_Normal_Decode; diff --git a/src/cpu/core_normal/helpers.h b/src/cpu/core_normal/helpers.h index 6a30e052..97727801 100644 --- a/src/cpu/core_normal/helpers.h +++ b/src/cpu/core_normal/helpers.h @@ -141,3 +141,17 @@ } \ } +#define POPSEG(_SEG_,_VAL_,_ESP_CHANGE_) \ + if (CPU_SetSegGeneral(_SEG_,_VAL_)) { \ + LEAVECORE; \ + reg_eip-=(core.ip_lookup-core.op_start);reg_esp-=_ESP_CHANGE_; \ + CPU_StartException();goto decode_start; \ + } + +#define LOADSEG(_SEG_,_SEG_VAL_) \ + if (CPU_SetSegGeneral(_SEG_,_SEG_VAL_)) { \ + LEAVECORE; \ + reg_eip-=(core.ip_lookup-core.op_start); \ + CPU_StartException();goto decode_start; \ + } \ + diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 150a5c33..16ce83ed 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -242,8 +242,9 @@ CASE_0F_W(0xa0) /* PUSH FS */ Push_16(SegValue(fs));break; - CASE_0F_W(0xa1) /* POP FS */ - CPU_SetSegGeneral(fs,Pop_16());break; + CASE_0F_W(0xa1) /* POP FS */ + POPSEG(fs,Pop_16(),2); + break; CASE_0F_B(0xa2) /* CPUID */ CPU_CPUID();break; CASE_0F_W(0xa3) /* BT Ew,Gw */ @@ -268,7 +269,7 @@ CASE_0F_W(0xa8) /* PUSH GS */ Push_16(SegValue(gs));break; CASE_0F_W(0xa9) /* POP GS */ - CPU_SetSegGeneral(gs,Pop_16());break; + POPSEG(fs,Pop_16(),2);break; CASE_0F_W(0xab) /* BTS Ew,Gw */ { FillFlags();GetRMrw; @@ -295,8 +296,10 @@ break; CASE_0F_W(0xb2) /* LSS Ew */ { + CPU_Cycles++; GetRMrw;GetEAa; - *rmrw=LoadMw(eaa);CPU_SetSegGeneral(ss,LoadMw(eaa+2)); + LOADSEG(ss,LoadMw(eaa+2)); + *rmrw=LoadMw(eaa); break; } CASE_0F_W(0xb3) /* BTR Ew,Gw */ @@ -317,13 +320,15 @@ CASE_0F_W(0xb4) /* LFS Ew */ { GetRMrw;GetEAa; - *rmrw=LoadMw(eaa);CPU_SetSegGeneral(fs,LoadMw(eaa+2)); + LOADSEG(fs,LoadMw(eaa+2)); + *rmrw=LoadMw(eaa); break; } CASE_0F_W(0xb5) /* LGS Ew */ { GetRMrw;GetEAa; - *rmrw=LoadMw(eaa);CPU_SetSegGeneral(gs,LoadMw(eaa+2)); + LOADSEG(gs,LoadMw(eaa+2)); + *rmrw=LoadMw(eaa); break; } CASE_0F_W(0xb6) /* MOVZX Gw,Eb */ diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 397f4f09..2bae5eb2 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -24,8 +24,8 @@ EAXId(ADDD);break; CASE_D(0x06) /* PUSH ES */ Push_32(SegValue(es));break; - CASE_D(0x07) /* POP ES */ - CPU_SetSegGeneral(es,(Bit16u)Pop_32());break; + CASE_D(0x07) /* POP ES */ + POPSEG(es,Pop_32(),4);break; CASE_D(0x09) /* OR Ed,Gd */ RMEdGd(ORD);break; CASE_D(0x0b) /* OR Gd,Ed */ @@ -40,10 +40,12 @@ RMGdEd(ADCD);break; CASE_D(0x15) /* ADC EAX,Id */ EAXId(ADCD);break; - CASE_D(0x16) /* PUSH SS */ + CASE_D(0x16) /* PUSH SS */ Push_32(SegValue(ss));break; - CASE_D(0x17) /* POP SS */ - CPU_SetSegGeneral(ss,(Bit16u)Pop_32());break; + CASE_D(0x17) /* POP SS */ + POPSEG(ss,Pop_32(),4); + CPU_Cycles++; + break; CASE_D(0x19) /* SBB Ed,Gd */ RMEdGd(SBBD);break; CASE_D(0x1b) /* SBB Gd,Ed */ @@ -53,7 +55,7 @@ CASE_D(0x1e) /* PUSH DS */ Push_32(SegValue(ds));break; CASE_D(0x1f) /* POP DS */ - CPU_SetSegGeneral(ds,(Bit16u)Pop_32());break; + POPSEG(ds,Pop_32(),4);break; CASE_D(0x21) /* AND Ed,Gd */ RMEdGd(ANDD);break; CASE_D(0x23) /* AND Gd,Ed */ @@ -417,13 +419,15 @@ CASE_D(0xc4) /* LES */ { GetRMrd;GetEAa; - *rmrd=LoadMd(eaa);CPU_SetSegGeneral(es,LoadMw(eaa+4)); + LOADSEG(es,LoadMw(eaa+4)); + *rmrd=LoadMd(eaa); break; } CASE_D(0xc5) /* LDS */ { GetRMrd;GetEAa; - *rmrd=LoadMd(eaa);CPU_SetSegGeneral(ds,LoadMw(eaa+4)); + LOADSEG(ds,LoadMw(eaa+4)); + *rmrd=LoadMd(eaa); break; } CASE_D(0xc7) /* MOV Ed,Id */ diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 9aa15dc2..3ceb1160 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -159,8 +159,7 @@ CASE_0F_D(0xa0) /* PUSH FS */ Push_32(SegValue(fs));break; CASE_0F_D(0xa1) /* POP FS */ - CPU_SetSegGeneral(fs,(Bit16u)Pop_32());break; - + POPSEG(fs,Pop_32(),4);break; CASE_0F_D(0xa3) /* BT Ed,Gd */ { FillFlags();GetRMrd; @@ -183,7 +182,7 @@ CASE_0F_D(0xa8) /* PUSH GS */ Push_32(SegValue(gs));break; CASE_0F_D(0xa9) /* POP GS */ - CPU_SetSegGeneral(gs,(Bit16u)Pop_32());break; + POPSEG(gs,Pop_32(),4);break; CASE_0F_D(0xab) /* BTS Ed,Gd */ { FillFlags();GetRMrd; @@ -214,7 +213,9 @@ CASE_0F_D(0xb2) /* LSS Ed */ { GetRMrd;GetEAa; - *rmrd=LoadMd(eaa);CPU_SetSegGeneral(ss,LoadMw(eaa+4)); + LOADSEG(ss,LoadMw(eaa+4)); + CPU_Cycles++; + *rmrd=LoadMd(eaa); break; } CASE_0F_D(0xb3) /* BTR Ed,Gd */ @@ -235,13 +236,15 @@ CASE_0F_D(0xb4) /* LFS Ed */ { GetRMrd;GetEAa; - *rmrd=LoadMd(eaa);CPU_SetSegGeneral(fs,LoadMw(eaa+4)); + LOADSEG(fs,LoadMw(eaa+4)); + *rmrd=LoadMd(eaa); break; } CASE_0F_D(0xb5) /* LGS Ed */ { GetRMrd;GetEAa; - *rmrd=LoadMd(eaa);CPU_SetSegGeneral(gs,LoadMw(eaa+4)); + LOADSEG(gs,LoadMw(eaa+4)); + *rmrd=LoadMd(eaa); break; } CASE_0F_D(0xb6) /* MOVZX Gd,Eb */ diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index ac649c59..e1b2953b 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -30,8 +30,8 @@ AXIw(ADDW);break; CASE_W(0x06) /* PUSH ES */ Push_16(SegValue(es));break; - CASE_W(0x07) /* POP ES */ - CPU_SetSegGeneral(es,Pop_16());break; + CASE_W(0x07) /* POP ES */ + POPSEG(es,Pop_16(),2);break; CASE_B(0x08) /* OR Eb,Gb */ RMEbGb(ORB);break; CASE_W(0x09) /* OR Ew,Gw */ @@ -65,7 +65,9 @@ CASE_W(0x16) /* PUSH SS */ Push_16(SegValue(ss));break; CASE_W(0x17) /* POP SS */ - CPU_SetSegGeneral(ss,Pop_16());break; + POPSEG(ss,Pop_16(),2); + CPU_Cycles++; //Always do another instruction + break; CASE_B(0x18) /* SBB Eb,Gb */ RMEbGb(SBBB);break; CASE_W(0x19) /* SBB Ew,Gw */ @@ -81,7 +83,8 @@ CASE_W(0x1e) /* PUSH DS */ Push_16(SegValue(ds));break; CASE_W(0x1f) /* POP DS */ - CPU_SetSegGeneral(ds,Pop_16());break; + POPSEG(ds,Pop_16(),2); + break; CASE_B(0x20) /* AND Eb,Gb */ RMEbGb(ANDB);break; CASE_W(0x21) /* AND Ew,Gw */ @@ -489,21 +492,17 @@ if (rm >= 0xc0 ) {GetEArw;val=*earw;} else {GetEAa;val=LoadMw(eaa);} switch (which) { + case 0x02: /* MOV SS,Ew */ + CPU_Cycles++; //Always do another instruction case 0x00: /* MOV ES,Ew */ - CPU_SetSegGeneral(es,val);break; + case 0x03: /* MOV DS,Ew */ + case 0x05: /* MOV GS,Ew */ + case 0x04: /* MOV FS,Ew */ + LOADSEG((SegNames)which,val); + break; case 0x01: /* MOV CS,Ew Illegal*/ E_Exit("CPU:Illegal MOV CS Call"); break; - case 0x02: /* MOV SS,Ew */ - CPU_SetSegGeneral(ss,val); - CPU_Cycles++; //Always do another instruction - break; - case 0x03: /* MOV DS,Ew */ - CPU_SetSegGeneral(ds,val);break; - case 0x04: /* MOV FS,Ew */ - CPU_SetSegGeneral(fs,val);break; - case 0x05: /* MOV GS,Ew */ - CPU_SetSegGeneral(gs,val);break; default: E_Exit("CPU:8E:Illegal RM Byte"); } @@ -673,13 +672,15 @@ CASE_W(0xc4) /* LES */ { GetRMrw;GetEAa; - *rmrw=LoadMw(eaa);CPU_SetSegGeneral(es,LoadMw(eaa+2)); + LOADSEG(es,LoadMw(eaa+2)); + *rmrw=LoadMw(eaa); break; } CASE_W(0xc5) /* LDS */ { GetRMrw;GetEAa; - *rmrw=LoadMw(eaa);CPU_SetSegGeneral(ds,LoadMw(eaa+2)); + LOADSEG(ds,LoadMw(eaa+2)); + *rmrw=LoadMw(eaa); break; } CASE_B(0xc6) /* MOV Eb,Ib */ @@ -751,7 +752,10 @@ return debugCallback; } #endif - CPU_SW_Interrupt(3,core.ip_lookup-core.op_start); + if (CPU_SW_Interrupt(3)) { + reg_eip-=(core.ip_lookup-core.op_start); + CPU_StartException(); + }; #if CPU_TRAP_CHECK core.trap.skip=true; #endif @@ -765,7 +769,10 @@ return debugCallback; } #endif - CPU_SW_Interrupt(num,core.ip_lookup-core.op_start); + if (CPU_SW_Interrupt(num)) { + reg_eip-=core.ip_lookup-core.op_start; + CPU_StartException(); + } #if CPU_TRAP_CHECK core.trap.skip=true; #endif @@ -775,7 +782,10 @@ CASE_B(0xce) /* INTO */ if (get_OF()) { LEAVECORE; - CPU_SW_Interrupt(4,core.ip_lookup-core.op_start); + if (CPU_SW_Interrupt(4)) { + reg_eip-=core.ip_lookup-core.op_start; + CPU_StartException(); + } #if CPU_TRAP_CHECK core.trap.skip=true; #endif @@ -950,8 +960,12 @@ break; CASE_B(0xf4) /* HLT */ LEAVECORE; - CPU_HLT(core.ip_lookup-core.op_start); - return CBRET_NONE; + if (CPU_HLT()) { + reg_eip-=core.ip_lookup-core.op_start; + CPU_StartException(); + goto decode_start; + } + return CBRET_NONE; //Needs to return for hlt cpu core CASE_B(0xf5) /* CMC */ FillFlags(); SETFLAGBIT(CF,!(reg_flags & FLAG_CF)); diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 4081808a..d750fee2 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.40 2003-12-10 13:20:26 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.41 2003-12-10 17:02:22 harekiet Exp $ */ #include #include "dosbox.h" @@ -45,9 +45,13 @@ Bits CPU_CycleUp = 0; Bits CPU_CycleDown = 0; CPU_Decoder * cpudecoder; -void CPU_Real_16_Slow_Start(bool big); +static struct { + Bitu which,errorcode; +} exception; + void CPU_Core_Full_Start(bool big); void CPU_Core_Normal_Start(bool big); +void CPU_Dynamic_Start(bool big); static Bits CPU_Core_Normal_Decode(void); static Bits CPU_Core_Full_Decode(void); @@ -272,12 +276,22 @@ doconforming: return true; } -Bit8u lastint; -void CPU_Exception(Bitu num,Bitu error_code) { -// LOG_MSG("Exception %d CS:%X IP:%X FLAGS:%X",num,SegValue(cs),reg_eip,reg_flags); - CPU_Interrupt(num,error_code,((num>=8) ? CPU_INT_HAS_ERROR : 0)); +void CPU_StartException(void) { + CPU_Interrupt(cpu.exception.which,CPU_INT_EXCEPTION | ((cpu.exception.which>=8) ? CPU_INT_HAS_ERROR : 0)); } -void CPU_Interrupt(Bitu num,Bitu error_code,Bitu type) { +void CPU_SetupException(Bitu which,Bitu error) { + cpu.exception.which=which; + cpu.exception.error=error; +} + +void CPU_Exception(Bitu which,Bitu error ) { +// LOG_MSG("Exception %d CS:%X IP:%X FLAGS:%X",num,SegValue(cs),reg_eip,reg_flags); + CPU_SetupException(which,error); + CPU_StartException(); +} + +Bit8u lastint; +bool CPU_Interrupt(Bitu num,Bitu type) { lastint=num; #if C_DEBUG switch (num) { @@ -290,7 +304,7 @@ void CPU_Interrupt(Bitu num,Bitu error_code,Bitu type) { case 0x03: if (DEBUG_Breakpoint()) { CPU_Cycles=0; - return; + return false; } }; #endif @@ -307,7 +321,7 @@ void CPU_Interrupt(Bitu num,Bitu error_code,Bitu type) { Segs.val[cs]=mem_readw(base+(num << 2)+2); Segs.phys[cs]=Segs.val[cs]<<4; cpu.code.big=false; - return; + return false; } else { /* Protected Mode Interrupt */ // if (type&CPU_INT_SOFTWARE && cpu.v86) goto realmode_interrupt; @@ -316,18 +330,16 @@ void CPU_Interrupt(Bitu num,Bitu error_code,Bitu type) { if ((reg_flags & FLAG_VM) && (type&CPU_INT_SOFTWARE)) { LOG_MSG("Software int in v86, AH %X IOPL %x",reg_ah,(reg_flags & FLAG_IOPL) >>12); if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) { - reg_eip-=error_code; - CPU_Exception(13,0); - return; + CPU_SetupException(13,0); + return true; } } Descriptor gate; //TODO Check for software interrupt and check gate's dpl0; LOG(LOG_CPU,LOG_NORMAL)("INT:Gate to %X:%X big %d %s",gate_sel,gate_off,cs_desc.Big(),gate.Type() & 0x8 ? "386" : "286"); reg_eip=gate_off; - return; + return false; } case DESC_TASK_GATE: CPU_SwitchTask(gate.GetSelector(),TSwitch_CALL_INT); if (type & CPU_INT_HAS_ERROR) { //TODO Be sure about this, seems somewhat unclear - if (cpu_tss.is386) CPU_Push32(error_code); - else CPU_Push16(error_code); + if (cpu_tss.is386) CPU_Push32(cpu.exception.error); + else CPU_Push16(cpu.exception.error); } - return; + return false; default: E_Exit("Illegal descriptor type %X for int %X",gate.Type(),num); } @@ -1075,7 +1087,7 @@ void CPU_VERW(Bitu selector) { } -void CPU_SetSegGeneral(SegNames seg,Bitu value) { +bool CPU_SetSegGeneral(SegNames seg,Bitu value) { Segs.val[seg]=value; if (!cpu.pmode || (reg_flags & FLAG_VM)) { Segs.phys[seg]=value << 4; @@ -1083,6 +1095,7 @@ void CPU_SetSegGeneral(SegNames seg,Bitu value) { cpu.stack.big=false; cpu.stack.mask=0xffff; } + return false; } else { Descriptor desc; cpu.gdt.GetDescriptor(value,desc); @@ -1096,6 +1109,7 @@ void CPU_SetSegGeneral(SegNames seg,Bitu value) { cpu.stack.mask=0xffff; } } + return false; } } @@ -1129,17 +1143,14 @@ static Bits HLT_Decode(void) { return 0; } -void CPU_HLT(Bitu oplen) { - if (cpu.cpl) { - reg_eip-=oplen; - CPU_Exception(13,0); - return; - } +bool CPU_HLT(void) { + if (cpu.cpl) return true; CPU_Cycles=0; cpu.hlt.cs=SegValue(cs); cpu.hlt.eip=reg_eip; cpu.hlt.old_decoder=cpudecoder; cpudecoder=&HLT_Decode; + return false; } From 67c0a2329f6194d86243ef52961aaea112e9c245 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 10 Dec 2003 17:24:13 +0000 Subject: [PATCH 1402/4131] New entries for exception generating instructions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1483 --- include/cpu.h | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 2de0a508..ef488cc1 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -66,22 +66,29 @@ void CPU_CALL(bool use32,Bitu selector,Bitu offset); void CPU_RET(bool use32,Bitu bytes); #define CPU_INT_SOFTWARE 0x1 -#define CPU_INT_HAS_ERROR 0x2 +#define CPU_INT_EXCEPTION 0x2 +#define CPU_INT_HAS_ERROR 0x4 -void CPU_Interrupt(Bitu num,Bitu error_code,Bitu type); + +bool CPU_Interrupt(Bitu num,Bitu type); INLINE void CPU_HW_Interrupt(Bitu num) { - CPU_Interrupt(num,0,0); + CPU_Interrupt(num,0); } -INLINE void CPU_SW_Interrupt(Bitu num,Bitu oplen) { - CPU_Interrupt(num,oplen,CPU_INT_SOFTWARE); +INLINE bool CPU_SW_Interrupt(Bitu num) { + return CPU_Interrupt(num,CPU_INT_SOFTWARE); } -void CPU_Exception(Bitu num,Bitu error_code=0); + +void CPU_Exception(Bitu which,Bitu error=0); +void CPU_StartException(void); +void CPU_SetupException(Bitu which,Bitu error=0); + + void CPU_IRET(bool use32); -void CPU_SetSegGeneral(SegNames seg,Bitu value); +bool CPU_SetSegGeneral(SegNames seg,Bitu value); void CPU_CPUID(void); -void CPU_HLT(Bitu oplen); +bool CPU_HLT(void); Bitu CPU_Pop16(void); Bitu CPU_Pop32(void); @@ -375,6 +382,9 @@ struct CPUBlock { Bitu cs,eip; CPU_Decoder * old_decoder; } hlt; + struct { + Bitu which,error; + } exception; }; extern CPUBlock cpu; From 9c01f2cc3365b78830df20c3e937f77fdf9b5cde Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 10 Dec 2003 17:39:13 +0000 Subject: [PATCH 1403/4131] Use new cpu_sw_interrupt Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1484 --- src/ints/dpmi.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index bc8246e5..83f6f1c3 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -981,7 +981,7 @@ Bitu DPMI::SimulateInt(void) // Push flags from structure on stack DPMI_LOG("DPMI: SimInt1: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_esp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); reg_flags = mem_readw(data+0x20); - CPU_SW_Interrupt(num,0); + CPU_SW_Interrupt(num); DPMI_LOG("DPMI: SimInt2: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_esp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); return 0; }; @@ -1043,7 +1043,7 @@ Bitu DPMI::ptorHandler(void) DPMI_LOG("DPMI: INT %02X %04X called.",num,reg_ax); // Prepare flags for real int // CPU_SetFlagsw(reg_flags & 0x3ED5); // 0011111011010101b - CPU_SW_Interrupt(num,0); + CPU_SW_Interrupt(num); return 0; } @@ -1106,7 +1106,7 @@ Bitu DPMI::Int21Handler(void) reg_esp = rm_sp; // Call realmode interrupt DPMI_LOG("DPMI: INT 21 %04X called.",reg_ax); - CPU_SW_Interrupt(0x21,0); + CPU_SW_Interrupt(0x21); if (reg_ah==0x4C) { // Shut doen dpmi and restore previous one delete this; From fdcf5243aab976139245def28b7cf4a7528523b4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Dec 2003 18:28:25 +0000 Subject: [PATCH 1404/4131] Updated alsa checks to support 1.0 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1485 --- src/gui/midi_alsa.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 9f13a652..fad0d4f7 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -16,12 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: midi_alsa.h,v 1.4 2003-12-10 18:28:25 qbix79 Exp $ */ + #include #include #define ADDR_DELIM ".:" -#if SND_LIB_MINOR >= 6 +#if ((SND_LIB_MINOR >= 6) && (SND_LIB_MAJOR == 0)) || (SND_LIB_MAJOR >= 1) #define snd_seq_flush_output(x) snd_seq_drain_output(x) #define snd_seq_set_client_group(x,name) /*nop */ #define my_snd_seq_open(seqp) snd_seq_open(seqp, "hw", SND_SEQ_OPEN_OUTPUT, 0) From d7d47dfaee9cd4767d9d888c83cff9a5c3bd86e6 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 11 Dec 2003 21:32:55 +0000 Subject: [PATCH 1405/4131] added exception 'segment not present', removed some unneccessary checks in VERR,VERW,LAR,LSL Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1486 --- src/cpu/cpu.cpp | 83 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 26 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index d750fee2..1298a4c1 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.41 2003-12-10 17:02:22 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.42 2003-12-11 21:32:55 finsterr Exp $ */ #include #include "dosbox.h" @@ -250,6 +250,10 @@ bool CPU_SwitchTask(Bitu new_tss_selector,TSwitchType tstype) { Descriptor cs_desc; cpu.cpl=new_cs & 3; cpu.gdt.GetDescriptor(new_cs,cs_desc); + if (!cs_desc.saved.seg.p) { + E_Exit("Task switch with non present code-segment"); + return false; + } switch (cs_desc.Type()) { case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: @@ -277,8 +281,10 @@ doconforming: } void CPU_StartException(void) { +// if (cpu.exception.which==0x0B) LOG_MSG("**** Exception %d CS:%X IP:%X FLAGS:%X Error:%X",cpu.exception.which,SegValue(cs),reg_eip,reg_flags,cpu.exception.error); CPU_Interrupt(cpu.exception.which,CPU_INT_EXCEPTION | ((cpu.exception.which>=8) ? CPU_INT_HAS_ERROR : 0)); } + void CPU_SetupException(Bitu which,Bitu error) { cpu.exception.which=which; cpu.exception.error=error; @@ -293,8 +299,13 @@ void CPU_Exception(Bitu which,Bitu error ) { Bit8u lastint; bool CPU_Interrupt(Bitu num,Bitu type) { lastint=num; +// if ((num!=0x08) && (num!=0x1C)) LOG_MSG("Interrupt %02X %04X %04X",num,reg_ax,reg_bx); #if C_DEBUG switch (num) { + case 0x00: { + int brk = 0; + break; + } case 0xcd: #if C_HEAVY_DEBUG LOG(LOG_CPU,LOG_ERROR)("Call to interrupt 0xCD this is BAD"); @@ -441,6 +452,7 @@ do_interrupt: } } assert(1); + return false; // make compiler happy } void CPU_IRET(bool use32) { @@ -575,7 +587,7 @@ realmode_iret: } } -void CPU_JMP(bool use32,Bitu selector,Bitu offset) { +void CPU_JMP(bool use32,Bitu selector,Bitu offset,Bitu opLen) { if (!cpu.pmode || (reg_flags & FLAG_VM)) { if (!use32) { reg_eip=offset&0xffff; @@ -589,6 +601,11 @@ void CPU_JMP(bool use32,Bitu selector,Bitu offset) { Bitu rpl=selector & 3; Descriptor desc; cpu.gdt.GetDescriptor(selector,desc); + if (!desc.saved.seg.p) { + reg_eip -= opLen; + CPU_Exception(0x0B,selector & 0xfffc); + return; + } switch (desc.Type()) { case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: @@ -622,7 +639,7 @@ CODE_jmp: -void CPU_CALL(bool use32,Bitu selector,Bitu offset) { +void CPU_CALL(bool use32,Bitu selector,Bitu offset,Bitu opLen) { if (!cpu.pmode || (reg_flags & FLAG_VM)) { if (!use32) { CPU_Push16(SegValue(cs)); @@ -640,6 +657,11 @@ void CPU_CALL(bool use32,Bitu selector,Bitu offset) { Descriptor call; Bitu rpl=selector & 3; cpu.gdt.GetDescriptor(selector,call); + if (!call.saved.seg.p) { + reg_eip -= opLen; + CPU_Exception(0x0B,selector & 0xfffc); + return; + } /* Check for type of far call */ switch (call.Type()) { case DESC_CODE_N_NC_A:case DESC_CODE_N_NC_NA: @@ -674,6 +696,11 @@ call_code: Descriptor n_cs_desc; Bitu n_cs_sel=call.GetSelector(); if (!cpu.gdt.GetDescriptor(n_cs_sel,n_cs_desc)) E_Exit("Call:Gate:Invalid CS selector."); + if (!n_cs_desc.saved.seg.p) { + reg_eip -= opLen; + CPU_Exception(0x0B,selector & 0xfffc); + return; + } Bitu n_cs_dpl = n_cs_desc.DPL(); Bitu n_cs_rpl = n_cs_sel & 3; Bitu n_eip = call.GetOffset(); @@ -744,7 +771,7 @@ call_gate_same_privilege: } -void CPU_RET(bool use32,Bitu bytes) { +void CPU_RET(bool use32,Bitu bytes,Bitu opLen) { if (!cpu.pmode || (reg_flags & FLAG_VM)) { Bitu new_ip,new_cs; if (!use32) { @@ -761,6 +788,20 @@ void CPU_RET(bool use32,Bitu bytes) { return; } else { Bitu offset,selector; + if (!use32) selector = mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask) + 2); + else selector = mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask) + 4) & 0xffff; + + Descriptor desc; + Bitu rpl=selector & 3; + if (rpl0; Segs.val[cs]=selector; @@ -945,10 +983,6 @@ void CPU_LAR(Bitu selector,Bitu & ar) { SETFLAGBIT(ZF,false); return; } - if (!desc.saved.seg.p) { - SETFLAGBIT(ZF,false); - return; - } switch (desc.Type()){ case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: @@ -993,10 +1027,6 @@ void CPU_LSL(Bitu selector,Bitu & limit) { SETFLAGBIT(ZF,false); return; } - if (!desc.saved.seg.p) { - SETFLAGBIT(ZF,false); - return; - } switch (desc.Type()){ case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: @@ -1035,10 +1065,6 @@ void CPU_VERR(Bitu selector) { SETFLAGBIT(ZF,false); return; } - if (!desc.saved.seg.p) { - SETFLAGBIT(ZF,false); - return; - } switch (desc.Type()){ case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: //Conforming readable code segments can be always read @@ -1067,10 +1093,6 @@ void CPU_VERW(Bitu selector) { SETFLAGBIT(ZF,false); return; } - if (!desc.saved.seg.p) { - SETFLAGBIT(ZF,false); - return; - } switch (desc.Type()){ case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: @@ -1088,8 +1110,8 @@ void CPU_VERW(Bitu selector) { bool CPU_SetSegGeneral(SegNames seg,Bitu value) { - Segs.val[seg]=value; if (!cpu.pmode || (reg_flags & FLAG_VM)) { + Segs.val[seg]=value; Segs.phys[seg]=value << 4; if (seg==ss) { cpu.stack.big=false; @@ -1099,6 +1121,15 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) { } else { Descriptor desc; cpu.gdt.GetDescriptor(value,desc); + if ((value!=0) && (!desc.saved.seg.p)) { + if (seg==ss) { + E_Exit("CPU_SetSegGeneral: Stack segment not present."); + } + // Throw Exception 0x0B - Segment not present + CPU_SetupException(0x0B,value & 0xfffc); + return true; + } + Segs.val[seg]=value; Segs.phys[seg]=desc.GetBase(); if (seg==ss) { if (desc.Big()) { From 7d859fe795eaee7dd20d5d1abf3a0ef292a576a7 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 11 Dec 2003 21:35:06 +0000 Subject: [PATCH 1406/4131] added opcode length as parameter for ret,call and jmp instructions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1487 --- include/cpu.h | 6 +++--- src/cpu/core_normal/prefix_66.h | 14 ++++++++------ src/cpu/core_normal/prefix_none.h | 14 +++++++------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index ef488cc1..70a13d86 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -61,9 +61,9 @@ bool CPU_LMSW(Bitu word); void CPU_VERR(Bitu selector); void CPU_VERW(Bitu selector); -void CPU_JMP(bool use32,Bitu selector,Bitu offset); -void CPU_CALL(bool use32,Bitu selector,Bitu offset); -void CPU_RET(bool use32,Bitu bytes); +void CPU_JMP(bool use32,Bitu selector,Bitu offset,Bitu opLen=0); +void CPU_CALL(bool use32,Bitu selector,Bitu offset,Bitu opLen=0); +void CPU_RET(bool use32,Bitu bytes,Bitu opLen=0); #define CPU_INT_SOFTWARE 0x1 #define CPU_INT_EXCEPTION 0x2 diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 2bae5eb2..50e4ea74 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -145,9 +145,11 @@ CASE_D(0x5f) /* POP EDI */ reg_edi=Pop_32();break; CASE_D(0x60) /* PUSHAD */ + { + Bitu tmpesp = reg_esp; Push_32(reg_eax);Push_32(reg_ecx);Push_32(reg_edx);Push_32(reg_ebx); - Push_32(reg_esp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi); - break; + Push_32(tmpesp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi); + }; break; CASE_D(0x61) /* POPAD */ reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32(); @@ -478,13 +480,13 @@ { Bitu words=Fetchw(); LEAVECORE; - CPU_RET(true,words); + CPU_RET(true,words,core.ip_lookup-core.op_start); goto decode_start; } CASE_D(0xcb) /* RETF */ { LEAVECORE; - CPU_RET(true,0); + CPU_RET(true,0,core.ip_lookup-core.op_start); goto decode_start; } CASE_D(0xcf) /* IRET */ @@ -528,7 +530,7 @@ Bit32u newip=Fetchd(); Bit16u newcs=Fetchw(); LEAVECORE; - CPU_JMP(true,newcs,newip); + CPU_JMP(true,newcs,newip,core.ip_lookup-core.op_start); goto decode_start; } CASE_D(0xed) /* IN EAX,DX */ @@ -615,7 +617,7 @@ Bit32u newip=LoadMd(eaa); Bit16u newcs=LoadMw(eaa+4); LEAVECORE; - CPU_JMP(true,newcs,newip); + CPU_JMP(true,newcs,newip,core.ip_lookup-core.op_start); goto decode_start; } break; diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index e1b2953b..464c3171 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -548,7 +548,7 @@ { Bit16u newip=Fetchw();Bit16u newcs=Fetchw(); LEAVECORE; - CPU_CALL(false,newcs,newip); + CPU_CALL(false,newcs,newip,core.ip_lookup-core.op_start); goto decode_start; } CASE_B(0x9b) /* WAIT */ @@ -738,12 +738,12 @@ { Bitu words=Fetchw(); LEAVECORE; - CPU_RET(false,words); + CPU_RET(false,words,core.ip_lookup-core.op_start); goto decode_start; } CASE_W(0xcb) /* RETF */ LEAVECORE; - CPU_RET(false,0); + CPU_RET(false,0,core.ip_lookup-core.op_start); goto decode_start; CASE_B(0xcc) /* INT3 */ LEAVECORE; @@ -935,7 +935,7 @@ Bit16u newip=Fetchw(); Bit16u newcs=Fetchw(); LEAVECORE; - CPU_JMP(false,newcs,newip); + CPU_JMP(false,newcs,newip,core.ip_lookup-core.op_start); goto decode_start; } CASE_B(0xeb) /* JMP Jb */ @@ -962,7 +962,7 @@ LEAVECORE; if (CPU_HLT()) { reg_eip-=core.ip_lookup-core.op_start; - CPU_StartException(); + CPU_Exception(13,0); goto decode_start; } return CBRET_NONE; //Needs to return for hlt cpu core @@ -1123,7 +1123,7 @@ Bit16u newip=LoadMw(eaa); Bit16u newcs=LoadMw(eaa+2); LEAVECORE; - CPU_CALL(false,newcs,newip); + CPU_CALL(false,newcs,newip,core.ip_lookup-core.op_start); goto decode_start; } break; @@ -1137,7 +1137,7 @@ Bit16u newip=LoadMw(eaa); Bit16u newcs=LoadMw(eaa+2); LEAVECORE; - CPU_JMP(false,newcs,newip); + CPU_JMP(false,newcs,newip,core.ip_lookup-core.op_start); goto decode_start; } break; From a7b5694f5e3ed91ca5da65f9ca4b1c8e2eecce6b Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 11 Dec 2003 22:12:41 +0000 Subject: [PATCH 1407/4131] added INT15 C3 and improved INT 1A 04. Thanks c2woody. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1488 --- src/ints/bios.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 0958a892..b2210247 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.24 2003-11-26 09:25:51 harekiet Exp $ */ +/* $Id: bios.cpp,v 1.25 2003-12-11 22:12:41 finsterr Exp $ */ #include #include "dosbox.h" @@ -80,10 +80,15 @@ static Bitu INT1A_Handler(void) { CALLBACK_SCF(false); break; case 0x04: /* GET REAL-TIME ClOCK DATA (AT,XT286,PS) */ - reg_dx=reg_cx=0; - CALLBACK_SCF(false); - LOG(LOG_BIOS,LOG_ERROR)("INT1A:04:Faked RTC get date call"); - break; + reg_dx=0; + reg_cx=0x2003; + CALLBACK_SCF(false); + LOG(LOG_BIOS,LOG_ERROR)("INT1A:04:Faked RTC get date call"); + break; +// reg_dx=reg_cx=0; +// CALLBACK_SCF(false); +// LOG(LOG_BIOS,LOG_ERROR)("INT1A:04:Faked RTC get date call"); +// break; case 0x80: /* Pcjr Setup Sound Multiplexer */ LOG(LOG_BIOS,LOG_ERROR)("INT1A:80:Setup tandy sound multiplexer to %d",reg_al); break; @@ -275,6 +280,10 @@ static Bitu INT15_Handler(void) { CALLBACK_SCF(false); reg_ah=0; break; + case 0xc3: /* set carry flag so BorlandRTM doesn't assume a VECTRA/PS2 */ + reg_ah=0x86; + CALLBACK_SCF(true); + break; case 0xc2: /* BIOS PS2 Pointing Device Support */ case 0xc4: /* BIOS POS Programma option Select */ /* From f6f780f1086205af13bd2148534c4e9703bcbb75 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 12 Dec 2003 17:23:55 +0000 Subject: [PATCH 1408/4131] Clear segment registers when interrupting a v86 task Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1489 --- src/cpu/cpu.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 1298a4c1..31f3da06 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.42 2003-12-11 21:32:55 finsterr Exp $ */ +/* $Id: cpu.cpp,v 1.43 2003-12-12 17:23:55 harekiet Exp $ */ #include #include "dosbox.h" @@ -387,15 +387,13 @@ bool CPU_Interrupt(Bitu num,Bitu type) { } if (gate.Type() & 0x8) { /* 32-bit Gate */ if (reg_flags & FLAG_VM) { - SegSet16(fs,0xffff); - CPU_Push32(SegValue(gs)); - CPU_Push32(SegValue(fs)); - CPU_Push32(SegValue(ds)); - CPU_Push32(SegValue(es)); + CPU_Push32(SegValue(gs));SegSet16(gs,0x0); + CPU_Push32(SegValue(fs));SegSet16(fs,0x0); + CPU_Push32(SegValue(ds));SegSet16(ds,0x0); + CPU_Push32(SegValue(es));SegSet16(es,0x0); } CPU_Push32(o_ss); CPU_Push32(o_esp); - } else { /* 16-bit Gate */ if (reg_flags & FLAG_VM) E_Exit("V86 to 16-bit gate"); CPU_Push16(o_ss); @@ -1175,7 +1173,10 @@ static Bits HLT_Decode(void) { } bool CPU_HLT(void) { - if (cpu.cpl) return true; + if (cpu.cpl) { + CPU_SetupException(13,0); + return true; + } CPU_Cycles=0; cpu.hlt.cs=SegValue(cs); cpu.hlt.eip=reg_eip; From b07c69403d8c18632ca2006481bc8371b799e0a0 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 12 Dec 2003 19:51:20 +0000 Subject: [PATCH 1409/4131] limit value in CPU_SetSegGeneral to 16bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1490 --- src/cpu/cpu.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 31f3da06..84d056e3 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.43 2003-12-12 17:23:55 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.44 2003-12-12 19:51:20 finsterr Exp $ */ #include #include "dosbox.h" @@ -1108,6 +1108,7 @@ void CPU_VERW(Bitu selector) { bool CPU_SetSegGeneral(SegNames seg,Bitu value) { + value &= 0xffff; if (!cpu.pmode || (reg_flags & FLAG_VM)) { Segs.val[seg]=value; Segs.phys[seg]=value << 4; From 660bc441557a5e6b69edf06cb24ef0cbd6e645f6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 12 Dec 2003 22:11:14 +0000 Subject: [PATCH 1410/4131] removed core_16(I hope. Mail me if not) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1491 --- visualc/dosbox.dsp | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index 63283221..a01dc422 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -89,46 +89,6 @@ LINK32=link.exe # Begin Group "cpu" # PROP Default_Filter "" -# Begin Group "core_16" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\src\cpu\core_16\helpers.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_16\main.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_16\prefix_66.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_16\prefix_66_of.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_16\prefix_of.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_16\start.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_16\stop.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_16\support.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_16\table_ea.h -# End Source File -# End Group # Begin Group "core_full" # PROP Default_Filter "" From b82ffd8088da9e6228d27656a36bf368ab0882ca Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Sat, 13 Dec 2003 15:57:26 +0000 Subject: [PATCH 1411/4131] fixed pop gs Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1492 --- src/cpu/core_normal/prefix_0f.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 16ce83ed..56a0a65c 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -269,7 +269,7 @@ CASE_0F_W(0xa8) /* PUSH GS */ Push_16(SegValue(gs));break; CASE_0F_W(0xa9) /* POP GS */ - POPSEG(fs,Pop_16(),2);break; + POPSEG(gs,Pop_16(),2);break; CASE_0F_W(0xab) /* BTS Ew,Gw */ { FillFlags();GetRMrw; From 82155f2b42b3b0c0406bbd51d3d44e70578b6061 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 17 Dec 2003 21:50:59 +0000 Subject: [PATCH 1412/4131] moved shell_inc.h to include and added subst and loadhigh (Srecko) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1493 --- src/shell/shell.cpp | 17 +++-- src/shell/shell_batch.cpp | 2 +- src/shell/shell_cmds.cpp | 62 ++++++++++++++++- src/shell/shell_inc.h | 142 -------------------------------------- src/shell/shell_misc.cpp | 4 +- 5 files changed, 73 insertions(+), 154 deletions(-) delete mode 100644 src/shell/shell_inc.h diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 5cf3ddd6..eea7529b 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,13 +16,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.36 2003-10-14 23:34:28 harekiet Exp $ */ +/* $Id: shell.cpp,v 1.37 2003-12-17 21:50:59 qbix79 Exp $ */ #include #include #include #include "setup.h" -#include "shell_inc.h" +#include "shell.h" Bitu call_shellstop; @@ -71,7 +71,7 @@ Bitu DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn,bool * append) { char ch; Bitu num=0; - while (ch=*lr++) { + while ( (ch=*lr++) ) { switch (ch) { case '>': *append=((*lr)=='>'); @@ -283,10 +283,12 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_DIR_BYTES_FREE","%5d Dir(s) %17s Bytes free\n"); MSG_Add("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\n"); MSG_Add("SHELL_EXECUTE_ILLEGAL_COMMAND","Illegal command: %s.\n"); - MSG_Add("SHELL_CMD_PAUSE","Press any key to continue.\n"); + MSG_Add("SHELL_CMD_PAUSE","Press any key to continue.\n"); MSG_Add("SHELL_CMD_PAUSE_HELP","Waits for 1 keystroke to continue.\n"); MSG_Add("SHELL_CMD_COPY_FAILURE","Copy failure : %s.\n"); MSG_Add("SHELL_CMD_COPY_SUCCESS"," %d File(s) copied.\n"); + MSG_Add("SHELL_CMD_SUBST_NO_REMOVE","Removing drive not supported. Doing nothing.\n"); + MSG_Add("SHELL_CMD_SUBST_FAILURE","SUBST failed. You either made an error in your commandline or the target drive is already used.\nIt's only possible to use SUBST on Local drives"); MSG_Add("SHELL_STARTUP","DOSBox Shell v" VERSION "\n" "This version runs some protected mode games!\n" @@ -311,10 +313,13 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_REM_HELP","Add comments in a batch file.\n"); MSG_Add("SHELL_CMD_NO_WILD","This is a simple version of the command, no wildcards allowed!\n"); MSG_Add("SHELL_CMD_RENAME_HELP","Renames files.\n"); - MSG_Add("SHELL_CMD_DELETE_HELP","Removes files.\n"); + MSG_Add("SHELL_CMD_DELETE_HELP","Removes files.\n"); MSG_Add("SHELL_CMD_COPY_HELP","Copy files.\n"); MSG_Add("SHELL_CMD_CALL_HELP","Start a batch file from within another batch file.\n"); - /* Regular startup */ + MSG_Add("SHELL_CMD_SUBST_HELP","Assign an internal directory to a drive\n"); + MSG_Add("SHELL_CMD_LOADHIGH_HELP","Run a program. For batch file compatibility only.\n"); + + /* Regular startup */ call_shellstop=CALLBACK_Allocate(); /* Setup the startup CS:IP to kill the last running machine when exitted */ RealPt newcsip=CALLBACK_RealPointer(call_shellstop); diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 538f3e30..735b3f88 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -19,7 +19,7 @@ #include #include -#include "shell_inc.h" +#include "shell.h" BatchFile::BatchFile(DOS_Shell * host,char * name, char * cmd_line) { diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index f942c2e8..32a246ea 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,13 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.35 2003-11-11 18:47:25 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.36 2003-12-17 21:50:59 qbix79 Exp $ */ #include -#include "shell_inc.h" +#include "shell.h" #include "callback.h" #include "regs.h" +#include "../dos/drives.h" static SHELL_Cmd cmd_list[]={ { "CHDIR", 0, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"}, @@ -49,7 +50,10 @@ static SHELL_Cmd cmd_list[]={ { "REN", 1, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP"}, { "PAUSE", 0, &DOS_Shell::CMD_PAUSE, "SHELL_CMD_PAUSE_HELP"}, { "CALL", 0, &DOS_Shell::CMD_CALL, "SHELL_CMD_CALL_HELP"}, -{ 0,0,0,0} +{ "SUBST", 0, &DOS_Shell::CMD_SUBST, "SHELL_CMD_SUBST_HELP"}, +{ "LOADHIGH", 0, &DOS_Shell::CMD_LOADHIGH, "SHELL_CMD_LOADHIGH_HELP"}, +{ "LH", 1, &DOS_Shell::CMD_LOADHIGH, "SHELL_CMD_LOADHIGH_HELP"}, +{0,0,0,0} }; void DOS_Shell::DoCommand(char * line) { @@ -586,3 +590,55 @@ void DOS_Shell::CMD_CALL(char * args){ this->call=false; } +void DOS_Shell::CMD_SUBST (char * args) { +/* If more that one type can be substed think of something else + * E.g. make basedir member dos_drive instead of localdrive + */ + localDrive* ldp=0; + char mountstring[DOS_PATHLENGTH+CROSS_LEN+20]; + char temp_str[2] = { 0,0 }; + try { + strcpy(mountstring,"MOUNT "); + StripSpaces(args); + std::string arg; + CommandLine command(0,args); + + if (command.GetCount() != 2) throw 0 ; + command.FindCommand(2,arg); + if((arg=="/D" ) || (arg=="/d")) throw 1; //No removal (one day) + + command.FindCommand(1,arg); + if(arg[1] !=':') throw(0); + temp_str[0]=toupper(args[0]); + if(Drives[temp_str[0]-'A'] ) throw 0; //targetdrive in use + strcat(mountstring,temp_str); + strcat(mountstring," "); + + command.FindCommand(2,arg); + Bit8u drive;char fulldir[DOS_PATHLENGTH]; + if (!DOS_MakeName(const_cast(arg.c_str()),fulldir,&drive)) throw 0; + + if( ( ldp=dynamic_cast(Drives[drive])) == 0 ) throw 0; + char newname[CROSS_LEN]; + strcpy(newname, ldp->basedir); + strcat(newname,fulldir); + CROSS_FILENAME(newname); + ldp->dirCache.ExpandName(newname); + strcat(mountstring, newname); + this->ParseLine(mountstring); + } + catch(int a){ + if(a == 0) { + WriteOut(MSG_Get("SHELL_CMD_SUBST_FAILURE")); + } else { + WriteOut(MSG_Get("SHELL_CMD_SUBST_NO_REMOVE")); + } + return; + } + + return; +} + +void DOS_Shell::CMD_LOADHIGH(char *args){ + this->ParseLine(args); +} diff --git a/src/shell/shell_inc.h b/src/shell/shell_inc.h deleted file mode 100644 index 18a1c1ce..00000000 --- a/src/shell/shell_inc.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2002-2003 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* $Id: shell_inc.h,v 1.17 2003-09-08 18:19:28 qbix79 Exp $ */ - -#include -#include -#include "dosbox.h" -#include "mem.h" -#include "programs.h" -#include "dos_inc.h" -#include "regs.h" -#include "support.h" -#include "callback.h" -#include "setup.h" - -#include -#include - -#define CMD_MAXLINE 4096 -#define CMD_MAXCMDS 20 -#define CMD_OLDSIZE 4096 -extern Bitu call_shellstop; -class DOS_Shell; - - -class BatchFile { -public: - BatchFile(DOS_Shell * host,char * name, char * cmd_line); - ~BatchFile(); - bool ReadLine(char * line); - bool Goto(char * where); - Bit16u file_handle; - bool echo; - DOS_Shell * shell; - BatchFile * prev; - CommandLine * cmd; -}; - -class DOS_Shell : public Program { - -private: - - std::list 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); - void Execute(char * name,char * args); -/* 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); - /* 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 */ -}; - -static inline void StripSpaces(char*&args) -{ - while(*args && (*args == ' ')) - args++; -} - - -static inline char* ExpandDot(char*args, char* buffer) -{ - if(*args=='.') - { - if(*(args+1)==0) - { - strcpy(buffer,"*.*"); - return buffer; - } - if( (*(args+1)!='.') && (*(args+1)!='\\') ) - { - buffer[0]='*'; - buffer[1]=0; - strcat(buffer,args); - return buffer; - } - } - else strcpy(buffer,args); - return buffer; -} - - diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index c688f83c..4465ffad 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,11 +16,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.26 2003-10-10 09:21:35 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.27 2003-12-17 21:50:59 qbix79 Exp $ */ #include #include -#include "shell_inc.h" +#include "shell.h" #include "regs.h" From 735883416c6fd75393b519dfcefce332f0e7fba8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 17 Dec 2003 21:55:42 +0000 Subject: [PATCH 1413/4131] moved shell_inc.h to include Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1494 --- include/shell.h | 149 +++++++++++++++++++++++++++++++++++++++ src/debug/debug.cpp | 4 +- src/dos/dos_programs.cpp | 4 +- src/dos/drives.h | 7 +- 4 files changed, 159 insertions(+), 5 deletions(-) create mode 100644 include/shell.h diff --git a/include/shell.h b/include/shell.h new file mode 100644 index 00000000..e0c4bdd4 --- /dev/null +++ b/include/shell.h @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* $Id: shell.h,v 1.1 2003-12-17 21:49:31 qbix79 Exp $ */ + +#ifndef SHELL_H_ +#define SHELL_H_ + + +#include +#include +#include "dosbox.h" +#include "mem.h" +#include "programs.h" +#include "dos_inc.h" +#include "regs.h" +#include "support.h" +#include "callback.h" +#include "setup.h" + +#include +#include + +#define CMD_MAXLINE 4096 +#define CMD_MAXCMDS 20 +#define CMD_OLDSIZE 4096 +extern Bitu call_shellstop; +class DOS_Shell; + + +class BatchFile { +public: + BatchFile(DOS_Shell * host,char * name, char * cmd_line); + ~BatchFile(); + bool ReadLine(char * line); + bool Goto(char * where); + Bit16u file_handle; + bool echo; + DOS_Shell * shell; + BatchFile * prev; + CommandLine * cmd; +}; + +class DOS_Shell : public Program { + +private: + + std::list 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); + void Execute(char * name,char * args); +/* 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); + /* 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 */ +}; + +static inline void StripSpaces(char*&args) +{ + while(*args && (*args == ' ')) + args++; +} + + +static inline char* ExpandDot(char*args, char* buffer) +{ + if(*args=='.') + { + if(*(args+1)==0) + { + strcpy(buffer,"*.*"); + return buffer; + } + if( (*(args+1)!='.') && (*(args+1)!='\\') ) + { + buffer[0]='*'; + buffer[1]=0; + strcat(buffer,args); + return buffer; + } + } + else strcpy(buffer,args); + return buffer; +} + + +#endif diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 92486fef..a2753d69 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: debug.cpp,v 1.48 2003-12-17 21:52:23 qbix79 Exp $ */ + #include "programs.h" #include @@ -36,7 +38,7 @@ #include "timer.h" #include "paging.h" #include "../ints/xms.h" -#include "../shell/shell_inc.h" +#include "shell.h" #ifdef WIN32 void WIN32_Console(); diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 85a8acae..a44f83a7 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.20 2003-09-08 18:10:08 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.21 2003-12-17 21:55:42 qbix79 Exp $ */ #include #include @@ -28,7 +28,7 @@ #include "regs.h" #include "callback.h" #include "cdrom.h" -#include "../shell/shell_inc.h" + void MSCDEX_SetCDInterface(int intNr, int forceCD); diff --git a/src/dos/drives.h b/src/dos/drives.h index 37158423..4158507e 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2003 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,11 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: drives.h,v 1.18 2003-12-17 21:54:31 qbix79 Exp $ */ + #ifndef _DRIVES_H__ #define _DRIVES_H__ #include #include "dos_system.h" +#include "shell.h" /* for DOS_Shell */ bool WildFileCmp(const char * file, const char * wild); @@ -44,7 +47,7 @@ public: virtual bool isRemote(void); private: char basedir[CROSS_LEN]; - + friend void DOS_Shell::CMD_SUBST(char* args); struct { char srch_dir[CROSS_LEN]; } srchInfo[MAX_OPENDIRS]; From c831e34ffb58a194b2e5117b766226a298c5c362 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 17 Dec 2003 21:57:51 +0000 Subject: [PATCH 1414/4131] exported DOS_MakeName Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1495 --- include/dos_inc.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/dos_inc.h b/include/dos_inc.h index df977352..541c2544 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -106,6 +106,8 @@ bool DOS_Canonicalize(char * name,char * big); bool DOS_CreateTempFile(char * name,Bit16u * entry); bool DOS_FileExists(char * name); +/* Helper Functions */ +bool DOS_MakeName(char * name,char * fullname,Bit8u * drive); /* Drive Handing Routines */ Bit8u DOS_GetDefaultDrive(void); void DOS_SetDefaultDrive(Bit8u drive); From 36073bb20f5d24b194200e1fc9e530f474e04077 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 17 Dec 2003 23:04:40 +0000 Subject: [PATCH 1415/4131] added int 15 c0 - bios configuration Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1496 --- src/ints/bios.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index b2210247..fc3f0df3 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.25 2003-12-11 22:12:41 finsterr Exp $ */ +/* $Id: bios.cpp,v 1.26 2003-12-17 23:04:40 finsterr Exp $ */ #include #include "dosbox.h" @@ -28,6 +28,7 @@ #include "mem.h" #include "pic.h" #include "joystick.h" +#include "dos_inc.h" static Bitu call_int1a,call_int11,call_int8,call_int17,call_int12,call_int15,call_int1c; static Bitu call_int1,call_int70; @@ -173,14 +174,30 @@ static Bitu INT17_Handler(void) { static Bitu INT15_Handler(void) { + static Bitu biosConfigSeg=0; + switch (reg_ah) { case 0x06: LOG(LOG_BIOS,LOG_NORMAL)("INT15 Unkown Function 6"); break; case 0xC0: /* Get Configuration*/ - LOG(LOG_BIOS,LOG_ERROR)("Request BIOS Configuration INT 15 C0"); - CALLBACK_SCF(true); - break; + { + if (biosConfigSeg==0) biosConfigSeg = DOS_GetMemory(1); //We have 16 bytes + PhysPt data = PhysMake(biosConfigSeg,0); + mem_writew(data,8); // 3 Bytes following + mem_writeb(data+2,0xFC); // Model ID + mem_writeb(data+3,0x00); // Submodel ID + mem_writeb(data+4,0x01); // Bios Revision + mem_writeb(data+5,(1<<6)|(1<<5)|(1<<4));// Feature Byte 1 + mem_writeb(data+6,(1<<6)); // Feature Byte 2 + mem_writeb(data+7,0); // Feature Byte 3 + mem_writeb(data+8,0); // Feature Byte 4 + mem_writeb(data+9,0); // Feature Byte 4 + CPU_SetSegGeneral(es,biosConfigSeg); + reg_bx = 0; + reg_ah = 0; + CALLBACK_SCF(false); + }; break; case 0x4f: /* BIOS - Keyboard intercept */ /* Carry should be set but let's just set it just in case */ CALLBACK_SCF(true); From 559e21d17b44f29fe95ba944f71a376b614fdb72 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 17 Dec 2003 23:10:00 +0000 Subject: [PATCH 1416/4131] added exception if ss is loaded with illegal segment fixed bug in IRET - return to outer level Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1497 --- src/cpu/cpu.cpp | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 84d056e3..35fe0899 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.44 2003-12-12 19:51:20 finsterr Exp $ */ +/* $Id: cpu.cpp,v 1.45 2003-12-17 23:10:00 finsterr Exp $ */ #include #include "dosbox.h" @@ -281,7 +281,6 @@ doconforming: } void CPU_StartException(void) { -// if (cpu.exception.which==0x0B) LOG_MSG("**** Exception %d CS:%X IP:%X FLAGS:%X Error:%X",cpu.exception.which,SegValue(cs),reg_eip,reg_flags,cpu.exception.error); CPU_Interrupt(cpu.exception.which,CPU_INT_EXCEPTION | ((cpu.exception.which>=8) ? CPU_INT_HAS_ERROR : 0)); } @@ -299,13 +298,8 @@ void CPU_Exception(Bitu which,Bitu error ) { Bit8u lastint; bool CPU_Interrupt(Bitu num,Bitu type) { lastint=num; -// if ((num!=0x08) && (num!=0x1C)) LOG_MSG("Interrupt %02X %04X %04X",num,reg_ax,reg_bx); #if C_DEBUG switch (num) { - case 0x00: { - int brk = 0; - break; - } case 0xcd: #if C_HEAVY_DEBUG LOG(LOG_CPU,LOG_ERROR)("Call to interrupt 0xCD this is BAD"); @@ -339,7 +333,7 @@ bool CPU_Interrupt(Bitu num,Bitu type) { // DEBUG_EnableDebugger(); // LOG_MSG("interrupt start CPL %d v86 %d",cpu.cpl,cpu.v86); if ((reg_flags & FLAG_VM) && (type&CPU_INT_SOFTWARE)) { - LOG_MSG("Software int in v86, AH %X IOPL %x",reg_ah,(reg_flags & FLAG_IOPL) >>12); +// LOG_MSG("Software int in v86, AH %X IOPL %x",reg_ah,(reg_flags & FLAG_IOPL) >>12); if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) { CPU_SetupException(13,0); return true; @@ -838,8 +832,14 @@ RET_same_level: } else { /* Return to higher level */ if (bytes) E_Exit("RETF with immediate value"); - Bitu n_esp = CPU_Pop16(); - Bitu n_ss = CPU_Pop16(); + Bitu n_esp,n_ss; + if (use32) { + n_esp = CPU_Pop32(); + n_ss = CPU_Pop32() & 0xffff; + } else { + n_esp = CPU_Pop16(); + n_ss = CPU_Pop16(); + } cpu.cpl = rpl; CPU_SetSegGeneral(ss,n_ss); if (cpu.stack.big) { @@ -1106,7 +1106,6 @@ void CPU_VERW(Bitu selector) { SETFLAGBIT(ZF,true); } - bool CPU_SetSegGeneral(SegNames seg,Bitu value) { value &= 0xffff; if (!cpu.pmode || (reg_flags & FLAG_VM)) { @@ -1120,13 +1119,20 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) { } else { Descriptor desc; cpu.gdt.GetDescriptor(value,desc); - if ((value!=0) && (!desc.saved.seg.p)) { - if (seg==ss) { - E_Exit("CPU_SetSegGeneral: Stack segment not present."); + + if (value!=0) { + if (!desc.saved.seg.p) { + if (seg==ss) E_Exit("CPU_SetSegGeneral: Stack segment not present."); + // Throw Exception 0x0B - Segment not present + CPU_SetupException(0x0B,value & 0xfffc); + return true; + } else if (seg==ss) { + // Stack segment loaded with illegal segment ? + if ((desc.saved.seg.typeDESC_DATA_ED_RW_A)) { + CPU_SetupException(0x0D,value & 0xfffc); + return true; + } } - // Throw Exception 0x0B - Segment not present - CPU_SetupException(0x0B,value & 0xfffc); - return true; } Segs.val[seg]=value; Segs.phys[seg]=desc.GetBase(); From f9780a04f1716335bf8fadd79933def657ff40b3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 18 Dec 2003 09:30:48 +0000 Subject: [PATCH 1417/4131] added ^ as valid character Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1498 --- src/dos/dos_files.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 33174e22..b34e909f 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.49 2003-11-08 13:41:04 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.50 2003-12-18 09:30:48 qbix79 Exp $ */ #include #include @@ -81,7 +81,7 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { case '\\': case '$': case '#': case '@': case '(': case ')': case '!': case '%': case '{': case '}': case '`': case '~': case '_': case '-': case '.': case '*': case '?': case '&': - case '\'': case '+': + case '\'': case '+': case '^': upname[w++]=c; break; default: From 355320d1019aa56c9371d18f7d569c4e4a3e1536 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 19 Dec 2003 15:46:52 +0000 Subject: [PATCH 1418/4131] fix the 0x82 opcode displaying Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1499 --- src/debug/debug_disasm.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/debug/debug_disasm.cpp b/src/debug/debug_disasm.cpp index 11aa3266..f0c0460e 100644 --- a/src/debug/debug_disasm.cpp +++ b/src/debug/debug_disasm.cpp @@ -220,8 +220,7 @@ static char *op386map1[256] = { "js %Jb", "jns %Jb", "jpe %Jb", "jpo %Jb", "jl %Jb", "jge %Jb", "jle %Jb", "jg %Jb", /* 8 */ -/* "%g0 %Eb,%Ib", "%g0 %Ev,%Iv", "%g0 %Ev,%Ib", "%g0 %Ev,%Ib", */ - "%g0 %Eb,%Ib", "%g0 %Ev,%Iv", "%g0 %Ev,%Ix", "%g0 %Ev,%Ix", + "%g0 %Eb,%Ib", "%g0 %Ev,%Iv", "%g0 %Eb,%Ib", "%g0 %Ev,%Ix", "test %Eb,%Gb", "test %Ev,%Gv", "xchg %Eb,%Gb", "xchg %Ev,%Gv", "mov %Eb,%Gb", "mov %Ev,%Gv", "mov %Gb,%Eb", "mov %Gv,%Ev", "mov %Ew,%Sw", "lea %Gv,%M ", "mov %Sw,%Ew", "pop %Ev", From 6cdb0c89948f758a3733094cbbd320b43cd7a69b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 19 Dec 2003 16:08:26 +0000 Subject: [PATCH 1419/4131] Fixed Bit testing instructions, thanks srecko Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1500 --- src/cpu/core_full/load.h | 12 ++++++++++++ src/cpu/core_full/op.h | 8 ++++---- src/cpu/core_full/optable.h | 20 ++++++++++---------- src/cpu/core_full/support.h | 4 ++-- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 64740693..00818973 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -75,6 +75,12 @@ l_M_Ewx: goto l_M_EwGw; case M_EwGwIb: inst.imm.d=Fetchb(); + goto l_M_EwGw; + case M_EwGwt: + inst.op2.d=reg_16(inst.rm_index); + inst.rm_eaa=((Bit32s)inst.op1.d >> 4) * 2; + inst.op2.d&=15; + goto l_M_Ew; l_M_EwGw: case M_EwGw: inst.op2.d=reg_16(inst.rm_index); @@ -111,8 +117,14 @@ l_M_Ew: case M_EdGdCL: inst.imm.d=reg_cl; goto l_M_EdGd; + case M_EdGdt: + inst.op2.d=reg_32(inst.rm_index); + inst.rm_eaa=((Bit32s)inst.op1.d >> 5) * 4; + inst.op2.d&=31; + goto l_M_Ed; case M_EdGdIb: inst.imm.d=Fetchb(); + goto l_M_EdGd; l_M_EdGd: case M_EdGd: inst.op2.d=reg_32(inst.rm_index); diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index c54567a5..1ccb4227 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -563,12 +563,12 @@ switch (inst.code.op) { case O_BTCw: FillFlags(); SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15)))); - inst.op1.d&=~(1 << (inst.op2.d & 15)); + inst.op1.d^=(1 << (inst.op2.d & 15)); break; case O_BTRw: FillFlags(); SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15)))); - inst.op1.d^=(1 << (inst.op2.d & 15)); + inst.op1.d&=~(1 << (inst.op2.d & 15)); break; case O_BTd: FillFlags(); @@ -582,12 +582,12 @@ switch (inst.code.op) { case O_BTCd: FillFlags(); SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31)))); - inst.op1.d&=~(1 << (inst.op2.d & 31)); + inst.op1.d^=(1 << (inst.op2.d & 31)); break; case O_BTRd: FillFlags(); SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31)))); - inst.op1.d^=(1 << (inst.op2.d & 31)); + inst.op1.d&=~(1 << (inst.op2.d & 31)); case O_BSWAP: BSWAP(inst.op1.d); break; diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 3b82fca2..bc9d0a0b 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -294,23 +294,23 @@ static OpCode OpCodeTable[1024]={ /* 0x1a0 - 0x1a7 */ {L_SEG ,0 ,S_PUSHw ,fs },{L_POPw ,0 ,S_SEGI ,fs }, -{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTw ,S_Ew ,M_EwGw }, +{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTw ,S_Ew ,M_EwGwt }, {L_MODRM ,O_DSHLw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHLw ,S_Ew ,M_EwGwCL }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x1a8 - 0x1af */ {L_SEG ,0 ,S_PUSHw ,gs },{L_POPw ,0 ,S_SEGI ,gs }, -{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSw ,S_Ew ,M_EwGw }, +{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSw ,S_Ew ,M_EwGwt }, {L_MODRM ,O_DSHRw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHRw ,S_Ew ,M_EwGwCL }, {0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRw ,S_Gw ,M_EwxGwx }, /* 0x1b0 - 0x1b7 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,O_SEGSS ,S_SEGGw,M_Efw },{L_MODRM ,O_BTRw ,S_Ew ,M_EwGw }, +{L_MODRM ,O_SEGSS ,S_SEGGw,M_Efw },{L_MODRM ,O_BTRw ,S_Ew ,M_EwGwt }, {L_MODRM ,O_SEGFS ,S_SEGGw,M_Efw },{L_MODRM ,O_SEGGS ,S_SEGGw,M_Efw }, {L_MODRM ,0 ,S_Gw ,M_Eb },{L_MODRM ,0 ,S_Gw ,M_Ew }, /* 0x1b8 - 0x1bf */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,0xe ,0 ,M_GRP },{L_MODRM ,O_BTCw ,S_Ew ,M_EwGw }, +{L_MODRM ,0xe ,0 ,M_GRP },{L_MODRM ,O_BTCw ,S_Ew ,M_EwGwt }, {L_MODRM ,O_BSFw ,S_Gw ,M_Ew },{L_MODRM ,O_BSRw ,S_Gw ,M_Ew }, {L_MODRM ,0 ,S_Gw ,M_Ebx },{L_MODRM ,0 ,S_Gw ,M_Ewx }, @@ -650,23 +650,23 @@ static OpCode OpCodeTable[1024]={ /* 0x3a0 - 0x3a7 */ {L_SEG ,0 ,S_PUSHd ,fs },{L_POPd ,0 ,S_SEGI ,fs }, -{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTd ,S_Ed ,M_EdGd }, +{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTd ,S_Ed ,M_EdGdt }, {L_MODRM ,O_DSHLd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHLd ,S_Ed ,M_EdGdCL }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x3a8 - 0x3af */ {L_SEG ,0 ,S_PUSHd ,gs },{L_POPd ,0 ,S_SEGI ,gs }, -{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSd ,S_Ed ,M_EdGd }, +{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSd ,S_Ed ,M_EdGdt }, {L_MODRM ,O_DSHRd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHRd ,S_Ed ,M_EdGdCL }, {0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdxGdx }, /* 0x3b0 - 0x3b7 */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,O_SEGSS ,S_SEGGd,M_Efd },{L_MODRM ,O_BTRd ,S_Ed ,M_EdGd }, +{L_MODRM ,O_SEGSS ,S_SEGGd,M_Efd },{L_MODRM ,O_BTRd ,S_Ed ,M_EdGdt }, {L_MODRM ,O_SEGFS ,S_SEGGd,M_Efd },{L_MODRM ,O_SEGGS ,S_SEGGd,M_Efd }, {L_MODRM ,0 ,S_Gd ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ew }, /* 0x3b8 - 0x3bf */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,0xf ,0 ,M_GRP },{L_MODRM ,O_BTCd ,S_Ed ,M_EdGd }, +{L_MODRM ,0xf ,0 ,M_GRP },{L_MODRM ,O_BTCd ,S_Ed ,M_EdGdt }, {L_MODRM ,O_BSFd ,S_Gd ,M_Ed },{L_MODRM ,O_BSRd ,S_Gd ,M_Ed }, {L_MODRM ,0 ,S_Gd ,M_Ebx },{L_MODRM ,0 ,S_Gd ,M_Ewx }, @@ -801,8 +801,8 @@ static OpCode Groups[16][8]={ },{ /* 0x0f Group 8 Ed */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,O_BTd ,S_Ed ,M_Ib },{0 ,O_BTSd ,S_Ed ,M_EdIb }, -{0 ,O_BTRd ,S_Ed ,M_Ib },{0 ,O_BTCd ,S_Ed ,M_EdIb }, +{0 ,O_BTd ,S_Ed ,M_EdIb },{0 ,O_BTSd ,S_Ed ,M_EdIb }, +{0 ,O_BTRd ,S_Ed ,M_EdIb },{0 ,O_BTCd ,S_Ed ,M_EdIb }, diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index ade673e8..27b9419d 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -130,8 +130,8 @@ enum { enum { M_None=0, M_Ebx,M_Eb,M_Gb,M_EbGb,M_GbEb, - M_Ewx,M_Ew,M_Gw,M_EwGw,M_GwEw,M_EwxGwx, - M_Edx,M_Ed,M_Gd,M_EdGd,M_GdEd,M_EdxGdx, + M_Ewx,M_Ew,M_Gw,M_EwGw,M_GwEw,M_EwxGwx,M_EwGwt, + M_Edx,M_Ed,M_Gd,M_EdGd,M_GdEd,M_EdxGdx,M_EdGdt, M_EbIb,M_EwIb,M_EdIb, M_EwIw,M_EwIbx,M_EwxIbx,M_EwxIwx,M_EwGwIb,M_EwGwCL, From 485eb2d5d4be8657ece84201074f213bc4e57c44 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 19 Dec 2003 16:17:51 +0000 Subject: [PATCH 1420/4131] Fixing the fixes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1501 --- src/cpu/core_full/load.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 00818973..f0b1e4ab 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -78,8 +78,7 @@ l_M_Ewx: goto l_M_EwGw; case M_EwGwt: inst.op2.d=reg_16(inst.rm_index); - inst.rm_eaa=((Bit32s)inst.op1.d >> 4) * 2; - inst.op2.d&=15; + inst.rm_eaa+=((Bit32s)inst.op2.d >> 4) * 2; goto l_M_Ew; l_M_EwGw: case M_EwGw: @@ -119,8 +118,7 @@ l_M_Ew: goto l_M_EdGd; case M_EdGdt: inst.op2.d=reg_32(inst.rm_index); - inst.rm_eaa=((Bit32s)inst.op1.d >> 5) * 4; - inst.op2.d&=31; + inst.rm_eaa+=((Bit32s)inst.op2.d >> 5) * 4; goto l_M_Ed; case M_EdGdIb: inst.imm.d=Fetchb(); From 20d576a2565e58c3ed6a1efdec82ef3b8d9930a8 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 26 Dec 2003 20:38:34 +0000 Subject: [PATCH 1421/4131] Fixed drive letter bug in mscdex device header Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1502 --- src/dos/dos_mscdex.cpp | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 26a2cb93..4ed099ed 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -27,6 +27,9 @@ #include "cdrom.h" +//#define MSCDEX_LOG LOG(LOG_MISC,LOG_ERROR) +#define MSCDEX_LOG + #define MSCDEX_VERSION_HIGH 2 #define MSCDEX_VERSION_LOW 23 #define MSCDEX_MAX_DRIVES 5 @@ -191,7 +194,7 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) Bit16u seg = DOS_GetMemory(driverSize/16+((driverSize%16)>0)); DOS_DeviceHeader devHeader(PhysMake(seg,0)); devHeader.SetNextDeviceHeader (0xFFFFFFFF); - devHeader.SetDriveLetter ('A'+_drive); + devHeader.SetDriveLetter (_drive+1); devHeader.SetNumSubUnits (1); devHeader.SetName ("MSCD001 "); @@ -205,8 +208,7 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) real_writeb(seg,off+4,(Bit8u)0xCB); //A RETF Instruction devHeader.SetStrategy(off); - // Create Callback Interrupt - off += 5; + // Create Callback Interruptoff += 5; Bitu call_interrupt=CALLBACK_Allocate(); CallBack_Handlers[call_interrupt]=MSCDEX_Interrupt_Handler; real_writeb(seg,off+0,(Bit8u)0xFE); //GRP 4 @@ -268,7 +270,7 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) return 6; }; if (!cdrom[numDrives]->SetDevice(physicalPath,forceCD)) return 3; - subUnit = numDrives; + subUnit = (Bit8u)numDrives; // Set drive DOS_DeviceHeader devHeader(PhysMake(rootDriverHeaderSeg,0)); devHeader.SetNumSubUnits(devHeader.GetNumSubUnits()+1); @@ -339,9 +341,9 @@ bool CMscdex::PlayAudioSector(Bit8u subUnit, Bit32u sector, Bit32u length) bool CMscdex::PlayAudioMSF(Bit8u subUnit, Bit32u start, Bit32u length) { if (subUnit>=numDrives) return false; - Bit8u min = (start>>16) & 0xFF; - Bit8u sec = (start>> 8) & 0xFF; - Bit8u fr = (start>> 0) & 0xFF; + Bit8u min = (Bit8u)(start>>16) & 0xFF; + Bit8u sec = (Bit8u)(start>> 8) & 0xFF; + Bit8u fr = (Bit8u)(start>> 0) & 0xFF; Bit32u sector = min*60*75+sec*75+fr - 150; return dinfo[subUnit].lastResult = PlayAudioSector(subUnit,sector,length); }; @@ -511,9 +513,9 @@ bool CMscdex::ReadSectors(Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, Ph bool CMscdex::ReadSectorsMSF(Bit8u subUnit, bool raw, Bit32u start, Bit16u num, PhysPt data) { if (subUnit>=numDrives) return false; - Bit8u min = (start>>16) & 0xFF; - Bit8u sec = (start>> 8) & 0xFF; - Bit8u fr = (start>> 0) & 0xFF; + Bit8u min = (Bit8u)(start>>16) & 0xFF; + Bit8u sec = (Bit8u)(start>> 8) & 0xFF; + Bit8u fr = (Bit8u)(start>> 0) & 0xFF; Bit32u sector = min*60*75+sec*75+fr - 150; // TODO: Check, if num has to be converted too ?! return ReadSectors(subUnit,raw,sector,num,data); @@ -625,14 +627,14 @@ static Bitu MSCDEX_Interrupt_Handler(void) Bit8u subUnit = mem_readb(data+1); Bit8u funcNr = mem_readb(data+2); -// LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Driver Function %02X",funcNr); + MSCDEX_LOG("MSCDEX: Driver Function %02X",funcNr); switch (funcNr) { case 0x03 : { /* IOCTL INPUT */ PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); subFuncNr = mem_readb(buffer); -// LOG(LOG_MISC,LOG_ERROR)("MSCDEX: IOCTL INPUT Subfunction %02X",subFuncNr); + MSCDEX_LOG("MSCDEX: IOCTL INPUT Subfunction %02X",subFuncNr); switch (subFuncNr) { case 0x00 : /* Get Device Header address */ mem_writed(buffer+1,RealMake(mscdex->rootDriverHeaderSeg,0)); @@ -784,6 +786,7 @@ static Bitu MSCDEX_Interrupt_Handler(void) // Set Statusword mem_writew(data+3,mscdex->GetStatusWord(subUnit)); + MSCDEX_LOG("MSCDEX: Status : %04X",mem_readw(data+3)); return CBRET_NONE; } @@ -792,7 +795,7 @@ static bool MSCDEX_Handler(void) if (reg_ah!=0x15) return false; PhysPt data = PhysMake(SegValue(es),reg_bx); -// LOG(LOG_MISC,LOG_ERROR)("MSCDEX: INT 2F %04X",reg_ax); + MSCDEX_LOG("MSCDEX: INT 2F %04X",reg_ax); switch (reg_ax) { case 0x1500: /* Install check */ @@ -861,7 +864,7 @@ static bool MSCDEX_Handler(void) mscdex->GetDrives(data); return true; case 0x1510: /* Device driver request */ - mscdex->SendDriverRequest(reg_cx & 0xFF,data); + mscdex->SendDriverRequest(reg_cx,data); return true; default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unknwon call : %04X",reg_ax); return true; From af56fa8d087cbd6bc25ab99544047aa428230f3b Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 26 Dec 2003 20:39:27 +0000 Subject: [PATCH 1422/4131] deletion of files now safer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1503 --- src/dos/drive_cache.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 6a94cb28..66429947 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.29 2003-10-29 19:43:22 finsterr Exp $ */ +/* $Id: drive_cache.cpp,v 1.30 2003-12-26 20:39:27 finsterr Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -34,6 +34,7 @@ #include #include +int fileInfoCounter = 0; bool SortByName(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b) { @@ -127,7 +128,7 @@ void DOS_Drive_Cache::SetLabel(const char* vname) Bit16u DOS_Drive_Cache::GetFreeID(CFileInfo* dir) { - for (Bit32u i=0; inextEntry>0) dirSearch[srchNr]->nextEntry--; + if (dirSearch[srchNr] && (dirSearch[srchNr]->nextEntry>0)) dirSearch[srchNr]->nextEntry--; if (!ignoreLastDir) { // Check if there are any open search dir that are affected by this... @@ -246,7 +247,10 @@ void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) // LOG_DEBUG("DIR: Caching out %s : dir %s",expand,dir->orgname); // delete file objects... - for(Bit32u i=0; ifileList.size(); i++) delete dir->fileList[i]; + for(Bit32u i=0; ifileList.size(); i++) { + if (dirSearch[srchNr]==dir->fileList[i]) dirSearch[srchNr] = 0; + delete dir->fileList[i]; dir->fileList[i] = 0; + } // clear lists dir->fileList.clear(); dir->longNameList.clear(); From c26a547cde8953f85f7aba770c8d2200762a8e05 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 29 Dec 2003 22:42:23 +0000 Subject: [PATCH 1423/4131] Added Some warning concerning writeprotection Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1504 --- src/dos/drive_local.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index b2c14279..5e312116 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: drive_local.cpp,v 1.41 2003-12-29 22:42:23 qbix79 Exp $ */ + #include #include #include @@ -51,7 +53,11 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) { strcat(newname,name); CROSS_FILENAME(newname); FILE * hand=fopen(dirCache.GetExpandName(newname),"wb+"); - if (!hand) return false; + if (!hand){ + LOG_MSG("Warning: file creation failed: %s",newname); + return false; + } + dirCache.AddEntry(newname, true); /* Make the 16 bit device information */ *file=new localFile(name,hand,0x202); @@ -79,7 +85,17 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { FILE * hand=fopen(newname,type); // Bit32u err=errno; - if (!hand) return false; + if (!hand) { + if((flags&3) != OPEN_READ) { + FILE * hmm=fopen(newname,"rb"); + if (hmm) { + fclose(hmm); + LOG_MSG("Warning: file %s exists and failed to open in write mode.\nPlease Remove write-protection",newname); + } + } + return false; + } + *file=new localFile(name,hand,0x202); (*file)->flags=flags; //for the inheritance flag and maybe check for others. // (*file)->SetFileName(newname); @@ -100,7 +116,7 @@ bool localDrive::FileUnlink(char * name) { bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { - + char tempDir[CROSS_LEN]; strcpy(tempDir,basedir); strcat(tempDir,_dir); @@ -132,7 +148,7 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { } bool localDrive::FindNext(DOS_DTA & dta) { - + char * dir_ent; struct stat stat_block; char full_name[CROSS_LEN]; @@ -376,7 +392,6 @@ bool localFile::Seek(Bit32u * pos,Bit32u type) { } bool localFile::Close() { - // only close if one reference left if (refCtr==1) { fclose(fhandle); From de536dfae01ea9ee45dade3d58870c4eee86c5ac Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 29 Dec 2003 22:53:02 +0000 Subject: [PATCH 1424/4131] Changed the paging link management Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1505 --- include/paging.h | 15 +++++++++++---- src/hardware/memory.cpp | 17 +---------------- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/include/paging.h b/include/paging.h index a5b9930f..c027d407 100644 --- a/include/paging.h +++ b/include/paging.h @@ -32,10 +32,14 @@ class PageDirectory; #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_ILLEGAL 0x20 //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 Bitu readb(PhysPt addr); @@ -44,7 +48,6 @@ public: virtual void writeb(PhysPt addr,Bitu val); virtual void writew(PhysPt addr,Bitu val); virtual void writed(PhysPt addr,Bitu val); - virtual void AddPageLink(Bitu lin_page, Bitu phys_page)=0; virtual HostPt GetHostPt(Bitu phys_page); Bitu flags; }; @@ -57,15 +60,15 @@ Bitu PAGING_GetDirBase(void); void PAGING_SetDirBase(Bitu cr3); void PAGING_InitTLB(void); void PAGING_ClearTLB(void); -void PAGING_ClearTLBEntries(Bitu pages,Bit32u * entries); void PAGING_LinkPage(Bitu lin_page,Bitu phys_page); +void PAGING_UnlinkPages(Bitu lin_page,Bitu pages); /* This maps the page directly, only use when paging is disabled */ void PAGING_MapPage(Bitu lin_page,Bitu phys_page); +bool PAGING_MakePhysPage(Bitu & page); void MEM_SetLFB(Bitu _page,Bitu _pages,HostPt _pt); void MEM_SetPageHandler(Bitu phys_page,Bitu pages,PageHandler * handler); -void MEM_UnlinkPages(void); Bit32u MEM_PhysReadD(Bitu addr); @@ -106,6 +109,10 @@ struct PagingBlock { PageHandler * handler[TLB_SIZE]; Bit32u phys_page[TLB_SIZE]; } tlb; + struct { + Bitu used; + Bit32u entries[PAGING_LINKS]; + } links; bool enabled; }; diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index f9ed5a56..9756befd 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -69,11 +69,8 @@ static struct MemoryBlock { class IllegalPageHandler : public PageHandler { public: - void AddPageLink(Bitu lin_page, Bitu phys_page) { - } - IllegalPageHandler() { - flags=PFLAG_ILLEGAL|PFLAG_NOCODE; + flags=PFLAG_INIT|PFLAG_NOCODE; } Bitu readb(PhysPt addr) { LOG_MSG("Illegal read from %x",addr); @@ -89,13 +86,6 @@ public: class RAMPageHandler : public PageHandler { public: - void AddPageLink(Bitu lin_page, Bitu phys_page) { - /* Always clear links in first MB on TLB change */ - if (lin_page Date: Mon, 29 Dec 2003 23:07:12 +0000 Subject: [PATCH 1425/4131] Changed the paging link management Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1506 --- src/cpu/paging.cpp | 56 ++++++++++++++++++++++--------------- src/hardware/vga_memory.cpp | 30 ++++---------------- src/ints/ems.cpp | 3 ++ 3 files changed, 43 insertions(+), 46 deletions(-) diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index af2230f4..ea14b6d3 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -132,10 +132,7 @@ void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu type) { void MEM_PhysWriteD(Bitu addr,Bit32u val); class InitPageHandler : public PageHandler { public: - InitPageHandler() {flags=PFLAG_ILLEGAL;} - void AddPageLink(Bitu lin_page, Bitu phys_page) { - assert(0); - } + InitPageHandler() {flags=PFLAG_INIT|PFLAG_NOCODE;} Bitu readb(PhysPt addr) { InitPage(addr); return mem_readb(addr); @@ -179,7 +176,7 @@ public: table.block.a=table.block.d=1; //Set access/Dirty MEM_PhysWriteD(table_addr,table.load); X86PageEntry entry; - Bitu entry_addr=(table.block.base << 12)+t_index*4; + Bitu entry_addr=(table.block.base<<12)+t_index*4; entry.load=MEM_PhysReadD(entry_addr); if (!entry.block.p) { LOG(LOG_PAGING,LOG_ERROR)("NP Page"); @@ -199,6 +196,23 @@ public: } }; +bool PAGING_MakePhysPage(Bitu & page) { + if (paging.enabled) { + Bitu d_index=page >> 10; + Bitu t_index=page & 0x3ff; + X86PageEntry table; + table.load=MEM_PhysReadD((paging.base.page<<12)+d_index*4); + if (!table.block.p) return false; + X86PageEntry entry; + entry.load=MEM_PhysReadD((table.block.base<<12)+t_index*4); + if (!entry.block.p) return false; + page=entry.block.base; + } else { + if (page0;pages--) { +void PAGING_ClearTLB(void) { + Bit32u * entries=&paging.links.entries[0]; + for (;paging.links.used>0;paging.links.used--) { Bitu page=*entries++; paging.tlb.read[page]=0; paging.tlb.write[page]=0; paging.tlb.handler[page]=&init_page_handler; } + paging.links.used=0; +} + +void PAGING_UnlinkPages(Bitu lin_page,Bitu pages) { + for (;pages>0;pages--) { + paging.tlb.read[lin_page]=0; + paging.tlb.write[lin_page]=0; + paging.tlb.handler[lin_page]=&init_page_handler; + } } void PAGING_LinkPage(Bitu lin_page,Bitu phys_page) { - PageHandler * handler=MEM_GetPageHandler(phys_page); Bitu lin_base=lin_page << 12; @@ -249,8 +261,8 @@ void PAGING_LinkPage(Bitu lin_page,Bitu phys_page) { else paging.tlb.read[lin_page]=0; if (handler->flags & PFLAG_WRITEABLE) paging.tlb.write[lin_page]=host_mem-lin_base; else paging.tlb.write[lin_page]=0; - - handler->AddPageLink(lin_page,phys_page); + if (paging.links.used>=PAGING_LINKS) E_Exit("Not enough paging links"); + paging.links.entries[paging.links.used++]=lin_page; paging.tlb.handler[lin_page]=handler; } diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 2deb3d3d..fde8dcc5 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -126,34 +126,17 @@ static void VGA_GFX_256U_WriteHandler(PhysPt start,Bit8u val) { /* Gonna assume that whoever maps vga memory, maps it on 32/64kb boundary */ -#define LINK_MAX 64 #define VGA_PAGES (128/4) #define VGA_PAGE_A0 (0xA0000/4096) #define VGA_PAGE_B0 (0xB0000/4096) #define VGA_PAGE_B8 (0xB8000/4096) static struct { - Bitu used_links; - Bit32u links[LINK_MAX]; Bit8u ram_area[VGA_PAGES*4096]; Bitu map_base; } vgapages; - -void VGA_ClearPageLinks(void) { - PAGING_ClearTLBEntries(vgapages.used_links,vgapages.links); - vgapages.used_links=0; -} - -class VGA_PageHandler : public PageHandler { - void AddPageLink(Bitu lin_page, Bitu phys_page) { - if (vgapages.used_links Date: Mon, 29 Dec 2003 23:16:46 +0000 Subject: [PATCH 1426/4131] Changed the paging link management Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1507 --- src/debug/debug.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index a2753d69..13080006 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.48 2003-12-17 21:52:23 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.49 2003-12-29 23:16:46 harekiet Exp $ */ #include "programs.h" @@ -1164,7 +1164,7 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) pos++; }; Bit32u address = GetAddress(seg,adr); - if (!(paging.tlb.handler[address >> 12]->flags & PFLAG_ILLEGAL)) { + if (!(paging.tlb.handler[address >> 12]->flags & PFLAG_INIT)) { static char outmask[] = "%s:[%04X]=%02X"; if (cpu.pmode) outmask[6] = '8'; From 880b4454d38356a9441f05a20db725dc5d3cfb32 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Dec 2003 19:07:42 +0000 Subject: [PATCH 1427/4131] Added changes from woody for fixing al1 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1508 --- src/dos/dos.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 6e401a0f..82815417 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.61 2003-11-20 10:29:32 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.62 2003-12-30 19:07:42 qbix79 Exp $ */ #include #include @@ -44,10 +44,10 @@ void DOS_SetError(Bit16u code) { #define DOSNAMEBUF 256 static Bitu DOS_21Handler(void) { - - DOS_PSP psp(dos.psp); - psp.SetStack(RealMake(SegValue(ss),reg_sp)); - + if (((reg_ah != 0x50) && (reg_ah != 0x51) && (reg_ah != 0x62) && (reg_ah != 0x64)) && (reg_ah<0x6c)) { + DOS_PSP psp(dos.psp); + psp.SetStack(RealMake(SegValue(ss),reg_sp-20)); + } char name1[DOSNAMEBUF+1]; char name2[DOSNAMEBUF+1]; switch (reg_ah) { From f3e3d24e8977efb2bd1a1cdc4c1df5aa9bcf115a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Dec 2003 20:39:07 +0000 Subject: [PATCH 1428/4131] added patch 857225 from Curt Coder (partly). Added support for disabling the mouse driver as requested at vogons. Added correct *hopefully* results for get maximum virtual coordinates Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1509 --- src/ints/mouse.cpp | 94 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 89 insertions(+), 5 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 09f18bdd..e249987c 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.26 2003-12-10 14:59:53 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.27 2003-12-30 20:39:07 qbix79 Exp $ */ #include #include "dosbox.h" @@ -100,7 +100,14 @@ static struct { float mickeysPerPixel_y; float pixelPerMickey_x; float pixelPerMickey_y; - + Bit16u updateRegion_x[2]; + Bit16u updateRegion_y[2]; + Bit16u page; + Bit16u doubleSpeedThreshold; + Bit16u language; + Bit16u cursorType; + bool enabled; + Bit16s oldshown; } mouse; #define X_MICKEY 8 @@ -253,7 +260,21 @@ void RestoreCursorBackground() void DrawCursor() { if (mouse.shown<0) return; +// Check video page + if (real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE)!=mouse.page) return; +// Check if cursor in update region +/* if ((POS_X >= mouse.updateRegion_x[0]) && (POS_X <= mouse.updateRegion_x[1]) && + (POS_Y >= mouse.updateRegion_y[0]) && (POS_Y <= mouse.updateRegion_y[1])) { + if (CurMode->type==M_TEXT16) + RestoreCursorBackgroundText(); + else + RestoreCursorBackground(); + mouse.shown--; + return; + } + */ /*Not sure yet what to do update region should be set to ??? */ + // Get Clipping ranges // In Textmode ? @@ -456,7 +477,17 @@ static void mouse_reset(void) mouse.cursorMask = defaultCursorMask; mouse.textAndMask= defaultTextAndMask; mouse.textXorMask= defaultTextXorMask; - + mouse.language = 0; + mouse.page = 0; + mouse.doubleSpeedThreshold = 64; + mouse.updateRegion_x[0] = 1; + mouse.updateRegion_y[0] = 1; + mouse.updateRegion_x[1] = 1; + mouse.updateRegion_y[1] = 1; + mouse.cursorType = 0; + mouse.enabled=true; + mouse.oldshown=-1; + SetMickeyPixelRate(8,16); } @@ -557,10 +588,12 @@ static Bitu INT33_Handler(void) { mouse.cursorMask = userdefCursorMask; mouse.hotx = reg_bx; mouse.hoty = reg_cx; + mouse.cursorType = 2; DrawCursor(); } break; case 0x0a: /* Define Text Cursor */ + mouse.cursorType = reg_bx; mouse.textAndMask = reg_cx; mouse.textXorMask = reg_dx; break; @@ -578,6 +611,19 @@ static Bitu INT33_Handler(void) { mouse.mickey_x=0; mouse.mickey_y=0; break; + case 0x10: /* Define screen region for updating */ + mouse.updateRegion_x[0]=reg_cx; + mouse.updateRegion_y[0]=reg_dx; + mouse.updateRegion_x[1]=reg_si; + mouse.updateRegion_y[1]=reg_di; + break; + case 0x11: /* Get number of buttons */ + reg_ax=0xffff; + reg_bx=MOUSE_BUTTONS; + break; + case 0x13: /* Set double-speed threshold */ + mouse.doubleSpeedThreshold=(reg_bx ? reg_bx : 64); + break; case 0x14: /* Exchange event-handler */ { Bit16u oldSeg = mouse.sub_seg; @@ -623,13 +669,51 @@ static Bitu INT33_Handler(void) { case 0x1c: /* Set interrupt rate */ /* Can't really set a rate this is host determined */ break; + case 0x1d: /* Set display page number */ + mouse.page=reg_bx; + break; + case 0x1e: /* Get display page number */ + reg_bx=mouse.page; + break; + case 0x1f: /* Disable Mousedriver */ + /* ES:BX old mouse driver Zero at the moment TODO */ + reg_bx=0; + SegSet16(es,0); + mouse.enabled=false; /* Just for reporting not doing a thing with it */ + mouse.oldshown=mouse.shown; + mouse.shown=-1; + break; + case 0x20: /* Enable Mousedriver */ + mouse.enabled=true; + mouse.shown=mouse.oldshown; + break; + case 0x22: /* Set language for messages */ + /* + * Values for mouse driver language: + * + * 00h English + * 01h French + * 02h Dutch + * 03h German + * 04h Swedish + * 05h Finnish + * 06h Spanish + * 07h Portugese + * 08h Italian + * + */ + mouse.language=reg_bx; + break; + case 0x23: /* Get language for messages */ + reg_bx=mouse.language; + break; case 0x24: /* Get Software version and mouse type */ reg_bx=0x805; //Version 8.05 woohoo reg_ch=0x04; /* PS/2 type */ - reg_cl=MOUSE_IRQ; /* Hmm ps2 irq dunno */ + reg_cl=0;//MOUSE_IRQ; /* Hmm ps2 irq 0!!!! */ break; case 0x26: /* Get Maximum virtual coordinates */ - reg_bx=(mouse.shown < 0 ? 0xffff : 0x0000); + reg_bx=(mouse.enabled ? 0x0000 : 0xffff); reg_cx=mouse.max_x; reg_dx=mouse.max_y; break; From 99b81667e5ca631522929a015d5ac30a869cf658 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 30 Dec 2003 23:28:54 +0000 Subject: [PATCH 1429/4131] Enable paging for non-debug builds Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1510 --- src/cpu/paging.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index ea14b6d3..35c4b633 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -296,9 +296,6 @@ void PAGING_Enable(bool enabled) { LOG(LOG_PAGING,LOG_NORMAL)("Disabled"); } else { LOG(LOG_PAGING,LOG_NORMAL)("Enabled"); -#if !(C_DEBUG) - E_Exit("CPU Paging features aren't supported"); -#endif PAGING_SetDirBase(paging.cr3); } PAGING_ClearTLB(); From 4a8f40c92d528194f5f58209df9172b4da629b5f Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 30 Dec 2003 23:55:47 +0000 Subject: [PATCH 1430/4131] added mscdex function 0f : Get directory entry Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1511 --- src/dos/dos_mscdex.cpp | 100 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 4ed099ed..cd1c8da2 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -109,6 +109,7 @@ public: bool GetCopyrightName (Bit16u drive, PhysPt data); bool GetAbstractName (Bit16u drive, PhysPt data); bool GetDocumentationName(Bit16u drive, PhysPt data); + bool GetDirectoryEntry (Bit16u drive, bool copyFlag, PhysPt pathname, PhysPt buffer, Bitu& error); bool ReadVTOC (Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error); bool ReadSectors (Bit16u drive, Bit32u sector, Bit16u num, PhysPt data); bool ReadSectors (Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data); @@ -128,8 +129,10 @@ public: private: + PhysPt GetDefaultBuffer (void); + Bit16u numDrives; - + typedef struct SDriveInfo { Bit8u drive; // drive letter in dosbox Bit8u physDrive; // drive letter in system @@ -142,6 +145,7 @@ private: Bit32u volumeSize; // for media change } TDriveInfo; + PhysPt defaultBuffer; TDriveInfo dinfo[MSCDEX_MAX_DRIVES]; CDROM_Interface* cdrom[MSCDEX_MAX_DRIVES]; @@ -153,13 +157,18 @@ CMscdex::CMscdex(void) { numDrives = 0; rootDriverHeaderSeg = 0; - + defaultBuffer = 0; + memset(dinfo,0,sizeof(dinfo)); for (Bit32u i=0; i0) { + index = 0; + if (!ReadSectors(GetSubUnit(drive),false,dirEntrySector,1,defBuffer)) return false; + // Get string part + foundName = false; + useName = searchPos; + searchPos = strchr(searchPos,'\\'); + if (searchPos) { *searchPos = 0; searchPos++; } + else foundComplete = true; + + do { + entryLength = mem_readb(defBuffer+index); + if (entryLength==0) break; + nameLength = mem_readb(defBuffer+index+32); + MEM_StrCopy(defBuffer+index+33,entryName,nameLength); + if (strcmp(entryName,useName)==0) { +// LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Get DirEntry : Found : %s",useName); + foundName = true; + break; + } + index += entryLength; + } while (index+33<=2048); + + if (foundName) { + // TO DO : name gefunden, Daten in den Buffer kopieren + if (foundComplete) { + if (copyFlag) E_Exit("MSCDEX: GetDirEntry: Unsupported copyflag"); + // Direct copy + MEM_BlockCopy(buffer,defBuffer+index,entryLength); + error = iso ? 1:0; + return true; + } + // directory wechseln + dirEntrySector = mem_readd(defBuffer+index+2); + dirSize = mem_readd(defBuffer+index+10); + } else { + // continue search in next sector + dirSize -= 2048; + dirEntrySector++; + } + }; + error = 2; // file not found + return false; // not found +}; + bool CMscdex::GetCurrentPos(Bit8u subUnit, TMSF& pos) { if (subUnit>=numDrives) return false; @@ -863,6 +953,12 @@ static bool MSCDEX_Handler(void) case 0x150D: /* Get drives */ mscdex->GetDrives(data); return true; + case 0x150F: { // Get directory entry + Bitu error; + bool success = mscdex->GetDirectoryEntry(reg_cl,reg_ch&1,data,PhysMake(reg_si,reg_di),error); + reg_ax = error; + CALLBACK_SCF(!success); + }; return true; case 0x1510: /* Device driver request */ mscdex->SendDriverRequest(reg_cx,data); return true; From 5cc3d9d24b2a20dfdd4f50aabee08aba302bc183 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 1 Jan 2004 10:45:59 +0000 Subject: [PATCH 1431/4131] Changed echo lines Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1512 --- autogen.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/autogen.sh b/autogen.sh index 9126bca9..5e6dff91 100755 --- a/autogen.sh +++ b/autogen.sh @@ -10,4 +10,5 @@ autoheader automake --gnits --include-deps --add-missing --copy autoconf -echo "Now you are ready to run ./configure, afterwards check config.h for extra build settings" +echo "Now you are ready to run ./configure." +echo "You can also run ./configure --help for extra features to enable/disable." From 23a4d8fe3d6540e7136588dcdd9b6aab342a2647 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 1 Jan 2004 12:26:08 +0000 Subject: [PATCH 1432/4131] Changed cpu core names Changed the exception handling of far jmp/calls interrupts and some others Added x86 dynamic core startup code Some new defines to enable/disable the dynamic core Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1513 --- include/cpu.h | 16 ++++--- src/cpu/core_full.cpp | 8 ++-- src/cpu/core_full/load.h | 5 +-- src/cpu/core_full/op.h | 5 +-- src/cpu/core_normal.cpp | 20 +++------ src/cpu/core_normal/prefix_66.h | 4 +- src/cpu/core_normal/prefix_none.h | 25 +++-------- src/cpu/cpu.cpp | 75 +++++++++++++++++-------------- src/cpu/paging.cpp | 3 +- src/ints/dpmi.cpp | 6 +-- src/platform/visualc/config.h | 8 +++- 11 files changed, 82 insertions(+), 93 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 70a13d86..50025ab5 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -33,6 +33,11 @@ extern Bits CPU_CycleMax; typedef Bits (CPU_Decoder)(void); extern CPU_Decoder * cpudecoder; +Bits CPU_Core_Normal_Run(void); +Bits CPU_Core_Normal_Trap_Run(void); +Bits CPU_Core_Full_Run(void); +Bits CPU_Core_Dyn_X86_Run(void); + //CPU Stuff extern Bit16u parity_lookup[256]; @@ -70,26 +75,23 @@ void CPU_RET(bool use32,Bitu bytes,Bitu opLen=0); #define CPU_INT_HAS_ERROR 0x4 -bool CPU_Interrupt(Bitu num,Bitu type); +void CPU_Interrupt(Bitu num,Bitu type,Bitu opLen=0); INLINE void CPU_HW_Interrupt(Bitu num) { CPU_Interrupt(num,0); } -INLINE bool CPU_SW_Interrupt(Bitu num) { - return CPU_Interrupt(num,CPU_INT_SOFTWARE); +INLINE void CPU_SW_Interrupt(Bitu num,Bitu OpLen) { + CPU_Interrupt(num,CPU_INT_SOFTWARE,OpLen); } void CPU_Exception(Bitu which,Bitu error=0); void CPU_StartException(void); void CPU_SetupException(Bitu which,Bitu error=0); - - void CPU_IRET(bool use32); bool CPU_SetSegGeneral(SegNames seg,Bitu value); +void CPU_HLT(Bitu opLen); void CPU_CPUID(void); -bool CPU_HLT(void); - Bitu CPU_Pop16(void); Bitu CPU_Pop32(void); void CPU_Push16(Bitu value); diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 7b2899f4..07017525 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -68,7 +68,7 @@ typedef PhysPt EAPoint; goto nextopcode; \ } -Bits Full_DeCode(void) { +Bits CPU_Core_Full_Run(void) { FullData inst; restart_core: if (CPU_Cycles<=0) return CBRET_NONE; @@ -82,7 +82,7 @@ restart_core: EAPoint IPPoint; LoadIP(); lflags.type=t_UNKNOWN; - while (CPU_Cycles--) { + while (CPU_Cycles-->0) { #if C_DEBUG cycle_count++; #if C_HEAVY_DEBUG @@ -110,6 +110,6 @@ exit_core: } -void CPU_Core_Full_Start(bool big) { - cpudecoder=&Full_DeCode; +void CPU_Core_Full_Init(void) { + } diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index f0b1e4ab..8bcf8744 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -502,10 +502,7 @@ l_M_Ed: goto nextopcode; case D_HLT: LEAVECORE; - if (CPU_HLT()) { - reg_eip-=IPPoint-inst.start; - CPU_StartException(); - } + CPU_HLT(IPPoint-inst.start); return CBRET_NONE; default: LOG(LOG_CPU,LOG_ERROR)("LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry); diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 1ccb4227..f8be1e40 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -345,10 +345,7 @@ switch (inst.code.op) { else if (DEBUG_IntBreakpoint(inst.op1.b)) return debugCallback; #endif - if (CPU_SW_Interrupt(inst.op1.b)) { - reg_eip-=IPPoint-inst.start; - CPU_StartException(); - } + CPU_SW_Interrupt(inst.op1.b,IPPoint-inst.start); goto restart_core; case O_INb: reg_al=IO_Read(inst.op1.d); diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index af52aeea..85b7638c 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -151,10 +151,7 @@ static GetEATable * EAPrefixTable[8] = { #define EALookupTable (*(core.ea_table)) - -Bits CPU_Core_Normal_Decode_Trap(void); - -Bits CPU_Core_Normal_Decode(void) { +Bits CPU_Core_Normal_Run(void) { decode_start: if (cpu.code.big) { core.index_default=0x200; @@ -202,26 +199,23 @@ restart_opcode: return CBRET_NONE; } -Bits CPU_Core_Normal_Decode_Trap(void) { +Bits CPU_Core_Normal_Trap_Run(void) { Bits oldCycles = CPU_Cycles; CPU_Cycles = 1; core.trap.skip=false; - Bits ret=CPU_Core_Normal_Decode(); - if (!core.trap.skip) if (CPU_SW_Interrupt(1)) { - E_Exit("Exception in trap flag cpu core, noooooooo"); - } + Bits ret=CPU_Core_Normal_Run(); + if (!core.trap.skip) CPU_SW_Interrupt(1,0); CPU_Cycles = oldCycles-1; - cpudecoder = &CPU_Core_Normal_Decode; + cpudecoder = &CPU_Core_Normal_Run; return ret; } -void CPU_Core_Normal_Start(bool big) { - if (GETFLAG(TF)) cpudecoder=CPU_Core_Normal_Decode_Trap; - else cpudecoder=CPU_Core_Normal_Decode; +void CPU_Core_Normal_Init(void) { + } diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 50e4ea74..f5f58363 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -358,7 +358,7 @@ SETFLAGSd(Pop_32()) #if CPU_TRAP_CHECK if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Decode_Trap; + cpudecoder=CPU_Core_Normal_Trap_Run; goto decode_end; } #endif @@ -495,7 +495,7 @@ CPU_IRET(true); #if CPU_TRAP_CHECK if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Decode_Trap; + cpudecoder=CPU_Core_Normal_Trap_Run; return CBRET_NONE; } #endif diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 464c3171..cbb7d382 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -561,7 +561,7 @@ SETFLAGSw(Pop_16()); #if CPU_TRAP_CHECK if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Decode_Trap; + cpudecoder=CPU_Core_Normal_Trap_Run; goto decode_end; } #endif @@ -752,10 +752,7 @@ return debugCallback; } #endif - if (CPU_SW_Interrupt(3)) { - reg_eip-=(core.ip_lookup-core.op_start); - CPU_StartException(); - }; + CPU_SW_Interrupt(3,(core.ip_lookup-core.op_start)); #if CPU_TRAP_CHECK core.trap.skip=true; #endif @@ -769,10 +766,7 @@ return debugCallback; } #endif - if (CPU_SW_Interrupt(num)) { - reg_eip-=core.ip_lookup-core.op_start; - CPU_StartException(); - } + CPU_SW_Interrupt(num,core.ip_lookup-core.op_start); #if CPU_TRAP_CHECK core.trap.skip=true; #endif @@ -782,10 +776,7 @@ CASE_B(0xce) /* INTO */ if (get_OF()) { LEAVECORE; - if (CPU_SW_Interrupt(4)) { - reg_eip-=core.ip_lookup-core.op_start; - CPU_StartException(); - } + CPU_SW_Interrupt(4,core.ip_lookup-core.op_start); #if CPU_TRAP_CHECK core.trap.skip=true; #endif @@ -802,7 +793,7 @@ #endif #if CPU_TRAP_CHECK if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Decode_Trap; + cpudecoder=CPU_Core_Normal_Trap_Run; return CBRET_NONE; } #endif @@ -960,11 +951,7 @@ break; CASE_B(0xf4) /* HLT */ LEAVECORE; - if (CPU_HLT()) { - reg_eip-=core.ip_lookup-core.op_start; - CPU_Exception(13,0); - goto decode_start; - } + CPU_HLT(core.ip_lookup-core.op_start); return CBRET_NONE; //Needs to return for hlt cpu core CASE_B(0xf5) /* CMC */ FillFlags(); diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 35fe0899..4a221399 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.45 2003-12-17 23:10:00 finsterr Exp $ */ +/* $Id: cpu.cpp,v 1.46 2004-01-01 12:26:08 harekiet Exp $ */ #include #include "dosbox.h" @@ -49,24 +49,22 @@ static struct { Bitu which,errorcode; } exception; -void CPU_Core_Full_Start(bool big); -void CPU_Core_Normal_Start(bool big); -void CPU_Dynamic_Start(bool big); +void CPU_Core_Full_Init(void); +void CPU_Core_Normal_Init(void); +void CPU_Core_Dyn_X86_Init(void); -static Bits CPU_Core_Normal_Decode(void); -static Bits CPU_Core_Full_Decode(void); +#if (C_DYNAMIC_X86) - -#if 1 - -#define realcore_start CPU_Core_Normal_Start +#define startcpu_core CPU_Core_Dyn_X86_Run #else -#define realcore_start CPU_Core_Full_Start +#define startcpu_core CPU_Core_Normal_Run +//#define startcpu_core CPU_Core_Full_Run #endif + void CPU_Push16(Bitu value) { reg_esp-=2; mem_writew(SegPhys(ss) + (reg_esp & cpu.stack.mask) ,value); @@ -296,7 +294,7 @@ void CPU_Exception(Bitu which,Bitu error ) { } Bit8u lastint; -bool CPU_Interrupt(Bitu num,Bitu type) { +void CPU_Interrupt(Bitu num,Bitu type,Bitu opLen) { lastint=num; #if C_DEBUG switch (num) { @@ -309,7 +307,7 @@ bool CPU_Interrupt(Bitu num,Bitu type) { case 0x03: if (DEBUG_Breakpoint()) { CPU_Cycles=0; - return false; + return; } }; #endif @@ -326,7 +324,7 @@ bool CPU_Interrupt(Bitu num,Bitu type) { Segs.val[cs]=mem_readw(base+(num << 2)+2); Segs.phys[cs]=Segs.val[cs]<<4; cpu.code.big=false; - return false; + return; } else { /* Protected Mode Interrupt */ // if (type&CPU_INT_SOFTWARE && cpu.v86) goto realmode_interrupt; @@ -335,16 +333,18 @@ bool CPU_Interrupt(Bitu num,Bitu type) { if ((reg_flags & FLAG_VM) && (type&CPU_INT_SOFTWARE)) { // LOG_MSG("Software int in v86, AH %X IOPL %x",reg_ah,(reg_flags & FLAG_IOPL) >>12); if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) { - CPU_SetupException(13,0); - return true; + reg_eip-=opLen; + CPU_Exception(13,0); + return; } } Descriptor gate; //TODO Check for software interrupt and check gate's dpl0; LOG(LOG_CPU,LOG_NORMAL)("INT:Gate to %X:%X big %d %s",gate_sel,gate_off,cs_desc.Big(),gate.Type() & 0x8 ? "386" : "286"); reg_eip=gate_off; - return false; + return; } case DESC_TASK_GATE: CPU_SwitchTask(gate.GetSelector(),TSwitch_CALL_INT); @@ -438,13 +438,13 @@ do_interrupt: if (cpu_tss.is386) CPU_Push32(cpu.exception.error); else CPU_Push16(cpu.exception.error); } - return false; + return; default: E_Exit("Illegal descriptor type %X for int %X",gate.Type(),num); } } assert(1); - return false; // make compiler happy + return ; // make compiler happy } void CPU_IRET(bool use32) { @@ -801,12 +801,6 @@ void CPU_RET(bool use32,Bitu bytes,Bitu opLen) { offset=CPU_Pop32(); selector=CPU_Pop32() & 0xffff; } - if (cpu.stack.big) { - reg_esp+=bytes; - } else { - reg_sp+=bytes; - } - if (cpu.cpl==rpl) { /* Return to same level */ switch (desc.Type()) { @@ -827,11 +821,16 @@ RET_same_level: cpu.code.big=desc.Big()>0; Segs.val[cs]=selector; reg_eip=offset; + if (cpu.stack.big) { + reg_esp+=bytes; + } else { + reg_sp+=bytes; + } LOG(LOG_CPU,LOG_NORMAL)("RET - Same level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL()); return; } else { - /* Return to higher level */ - if (bytes) E_Exit("RETF with immediate value"); + /* Return to outer level */ + if (bytes) E_Exit("RETF outeer level with immediate value"); Bitu n_esp,n_ss; if (use32) { n_esp = CPU_Pop32(); @@ -1179,17 +1178,18 @@ static Bits HLT_Decode(void) { return 0; } -bool CPU_HLT(void) { +void CPU_HLT(Bitu opLen) { if (cpu.cpl) { - CPU_SetupException(13,0); - return true; + reg_eip-=opLen; + CPU_Exception(13,0); + return; } CPU_Cycles=0; cpu.hlt.cs=SegValue(cs); cpu.hlt.eip=reg_eip; cpu.hlt.old_decoder=cpudecoder; cpudecoder=&HLT_Decode; - return false; + return; } @@ -1248,7 +1248,14 @@ void CPU_Init(Section* sec) { cpu.stack.big=false; cpu.idt.SetBase(0); cpu.idt.SetLimit(1023); - realcore_start(false); + + /* Init the cpu cores */ + CPU_Core_Normal_Init(); + CPU_Core_Full_Init(); +#if (C_DYNAMIC_X86) + CPU_Core_Dyn_X86_Init(); +#endif + cpudecoder=&startcpu_core; CPU_JMP(false,0,0); //Setup the first cpu core diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 35c4b633..5ab6c4ca 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -70,7 +70,6 @@ HostPt PageHandler::GetHostPt(Bitu phys_page) { } -Bits Full_DeCode(void); struct PF_Entry { Bitu cs; Bitu eip; @@ -86,7 +85,7 @@ struct { static Bits PageFaultCore(void) { CPU_CycleLeft+=CPU_Cycles; CPU_Cycles=1; - Bitu ret=Full_DeCode(); + Bitu ret=CPU_Core_Full_Run(); CPU_CycleLeft+=CPU_Cycles; if (ret<0) E_Exit("Got a dosbox close machine in pagefault core?"); if (ret) diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index 83f6f1c3..bc8246e5 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -981,7 +981,7 @@ Bitu DPMI::SimulateInt(void) // Push flags from structure on stack DPMI_LOG("DPMI: SimInt1: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_esp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); reg_flags = mem_readw(data+0x20); - CPU_SW_Interrupt(num); + CPU_SW_Interrupt(num,0); DPMI_LOG("DPMI: SimInt2: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_esp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); return 0; }; @@ -1043,7 +1043,7 @@ Bitu DPMI::ptorHandler(void) DPMI_LOG("DPMI: INT %02X %04X called.",num,reg_ax); // Prepare flags for real int // CPU_SetFlagsw(reg_flags & 0x3ED5); // 0011111011010101b - CPU_SW_Interrupt(num); + CPU_SW_Interrupt(num,0); return 0; } @@ -1106,7 +1106,7 @@ Bitu DPMI::Int21Handler(void) reg_esp = rm_sp; // Call realmode interrupt DPMI_LOG("DPMI: INT 21 %04X called.",reg_ax); - CPU_SW_Interrupt(0x21); + CPU_SW_Interrupt(0x21,0); if (reg_ah==0x4C) { // Shut doen dpmi and restore previous one delete this; diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index f05615f0..fcd1b404 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -3,7 +3,7 @@ #define VERSION "0.60" /* Define to 1 to enable internal debugger, requires libcurses */ -#define C_DEBUG 0 +#define C_DEBUG 1 /* Define to 1 to enable screenshots, requires libpng */ #define C_SSHOT 1 @@ -14,6 +14,12 @@ /* Enable some heavy debugging options */ #define C_HEAVY_DEBUG 0 +/* The type of cpu this host has */ +#define C_HOSTCPU X86 + +/* Define to 1 to use x86 dynamic cpu core */ +#define C_DYNAMIC_X86 1 + /* Enable memory function inlining in */ #define C_CORE_INLINE 0 From f5c2365e73e607f83f4d5ebe1628beb39f974ed1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 1 Jan 2004 12:27:27 +0000 Subject: [PATCH 1433/4131] New directory added for x86 dynamic core Added disable argument for x86 dynamic core Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1514 --- configure.in | 50 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/configure.in b/configure.in index 5f99ba8d..9c28ec81 100644 --- a/configure.in +++ b/configure.in @@ -91,14 +91,47 @@ AC_ARG_ENABLE(core-inline,AC_HELP_STRING([--enable-core-inline],[Enable inlined fi ],) + +dnl The target cpu checks for dynamic cores +AH_TEMPLATE(C_HOSTCPU,[The type of cpu this host has]) +AC_MSG_CHECKING(for target cpu type) +case "$target_cpu" in + i386|i486|i586|i686) + AC_DEFINE(C_HOSTCPU,X86) + AC_MSG_RESULT(x86 compatible) + c_hostcpu="x86" + ;; + *) + AC_DEFINE(C_HOSTCPU,UNKOWN) + AC_MSG_RESULT(unknown) + ;; +esac +AH_TEMPLATE(C_DYNAMIC_X86,[Define to 1 to use x86 dynamic cpu core]) +AC_ARG_ENABLE(dynamic-x86,AC_HELP_STRING([--disable-dynamic-x86],[Disable x86 dynamic cpu core]),,enable_dynamic_x86=yes) +AC_MSG_CHECKING(whether x86 dynamic cpu core will be enabled) +if test x$enable_dynamic_x86 = xno ; then + AC_MSG_RESULT(no) +else + if test x$c_hostcpu = xx86 ; then + AC_DEFINE(C_DYNAMIC_X86,1) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi +fi + + + AH_TEMPLATE(C_FPU,[Define to 1 to enable floating point emulation]) -AC_ARG_ENABLE(fpu,AC_HELP_STRING([--disable-fpu],[Disable FPU support]),[ - if test x$enable_fpu = xno ; then - AC_MSG_RESULT([disabling FPU support]) - else - AC_DEFINE(C_FPU,1) - fi -],AC_DEFINE(C_FPU,1)) +AC_ARG_ENABLE(fpu,AC_HELP_STRING([--disable-fpu],[Disable fpu support]),,enable_fpu=yes) +AC_MSG_CHECKING(whether fpu emulation will be enabled) +if test x$enable_fpu = xyes ; then + AC_MSG_RESULT(yes) + AC_DEFINE(C_FPU,1) +else + AC_MSG_RESULT(no) +fi + AH_TEMPLATE(C_SSHOT,[Define to 1 to enable screenshots, requires libpng]) AC_CHECK_HEADER(png.h,have_png_h=yes,) @@ -120,7 +153,6 @@ else AC_MSG_WARN([Can't find SDL_net, internal modem disabled]) fi - dnl Some host detection and actions for them case "$target" in *-*-cygwin* | *-*-mingw32*) @@ -136,13 +168,13 @@ case "$target" in ;; esac - AC_OUTPUT([ Makefile src/Makefile src/cpu/Makefile src/cpu/core_full/Makefile src/cpu/core_normal/Makefile +src/cpu/core_dyn_x86/Makefile src/debug/Makefile src/dos/Makefile src/fpu/Makefile From f4059666c33ed3051566945ef21ce229b0913f88 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 1 Jan 2004 12:33:03 +0000 Subject: [PATCH 1434/4131] x86 dynamic core Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1515 --- src/cpu/Makefile.am | 5 +- src/cpu/core_dyn_x86.cpp | 344 ++++++++ src/cpu/core_dyn_x86/Makefile.am | 1 + src/cpu/core_dyn_x86/cache.h | 300 +++++++ src/cpu/core_dyn_x86/decoder.h | 1252 ++++++++++++++++++++++++++++++ src/cpu/core_dyn_x86/helpers.h | 57 ++ src/cpu/core_dyn_x86/risc_x86.h | 719 +++++++++++++++++ src/cpu/core_dyn_x86/string.h | 0 8 files changed, 2676 insertions(+), 2 deletions(-) create mode 100644 src/cpu/core_dyn_x86.cpp create mode 100644 src/cpu/core_dyn_x86/Makefile.am create mode 100644 src/cpu/core_dyn_x86/cache.h create mode 100644 src/cpu/core_dyn_x86/decoder.h create mode 100644 src/cpu/core_dyn_x86/helpers.h create mode 100644 src/cpu/core_dyn_x86/risc_x86.h create mode 100644 src/cpu/core_dyn_x86/string.h diff --git a/src/cpu/Makefile.am b/src/cpu/Makefile.am index 2274f9a4..261369fb 100644 --- a/src/cpu/Makefile.am +++ b/src/cpu/Makefile.am @@ -1,6 +1,7 @@ -SUBDIRS = core_full core_normal +SUBDIRS = core_full core_normal core_dyn_x86 AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libcpu.a libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h core_full.cpp instructions.h \ - paging.cpp lazyflags.h core_normal.cpp \ No newline at end of file + paging.cpp lazyflags.h core_normal.cpp \ + core_dyn_x86.cpp \ No newline at end of file diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp new file mode 100644 index 00000000..2d551f0a --- /dev/null +++ b/src/cpu/core_dyn_x86.cpp @@ -0,0 +1,344 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "dosbox.h" + +#if (C_DYNAMIC_X86) + +#include +#include +#include +#include + +#include "callback.h" +#include "regs.h" +#include "mem.h" +#include "cpu.h" +#include "debug.h" +#include "paging.h" +#include "inout.h" + +#define CACHE_TOTAL (1024*1024*2) +#define CACHE_MAXSIZE (4096) +#define CACHE_BLOCKS (50*1024) +#define CACHE_ALIGN (16) +#define DYN_HASH_SHIFT (4) +#define DYN_PAGE_HASH (4096>>DYN_HASH_SHIFT) +#define DYN_LINKS (16) + +#if 1 +#define DYN_LOG LOG_MSG +#else +#define DYN_LOG +#endif + +enum { + G_EAX,G_ECX,G_EDX,G_EBX, + G_ESP,G_EBP,G_ESI,G_EDI, + G_ES,G_CS,G_SS,G_DS,G_FS,G_GS, + G_FLAGS,G_SMASK,G_EIP, + G_EA,G_STACK,G_CYCLES, + G_TMPB,G_TMPW,G_SHIFT, + G_EXIT, + G_MAX, +}; + +enum SingleOps { + SOP_INC,SOP_DEC, + SOP_NOT,SOP_NEG, +}; + +enum DualOps { + DOP_ADD,DOP_ADC, + DOP_SUB,DOP_SBB, + DOP_CMP,DOP_XOR, + DOP_AND,DOP_OR, + DOP_MOV, + DOP_TEST, + DOP_IMUL, + DOP_XCHG, +}; + +enum ShiftOps { + SHIFT_ROL,SHIFT_ROR, + SHIFT_RCL,SHIFT_RCR, + SHIFT_SHL,SHIFT_SHR, + SHIFT_SAR, +}; + +enum BranchTypes { + BR_O,BR_NO,BR_B,BR_NB, + BR_Z,BR_NZ,BR_BE,BR_NBE, + BR_S,BR_NS,BR_P,BR_NP, + BR_L,BR_NL,BR_LE,BR_NLE +}; + +enum BlockType { + BT_Free=0, + BT_Normal, + BT_SingleLink, + BT_DualLink, + BT_CheckFlags, +}; + +enum BlockReturn { + BR_Normal=0, + BR_Cycles, + BR_Link1,BR_Link2, + BR_Opcode, + BR_CallBack, +}; + +#define DYNFLG_HAS16 0x1 //Would like 8-bit host reg support +#define DYNFLG_HAS8 0x2 //Would like 16-bit host reg support +#define DYNFLG_LOAD 0x4 //Load value when accessed +#define DYNFLG_SAVE 0x8 //Needs to be saved back at the end of block +#define DYNFLG_CHANGED 0x10 //Load value only once because of save +#define DYNFLG_LOADONCE 0x20 //Load value only once because of save + +class GenReg; +class CodePageHandler; + +struct DynReg { + Bitu flags; + GenReg * genreg; + void * data; +}; + +enum DynAccess { + DA_d,DA_w, + DA_bh,DA_bl +}; + +enum ByteCombo { + BC_ll,BC_lh, + BC_hl,BC_hh, +}; + +static DynReg DynRegs[G_MAX]; +#define DREG(_WHICH_) &DynRegs[G_ ## _WHICH_ ] + +static struct { + Bitu ea,tmpb,tmpd,stack,shift; +} extra_regs; + +static void IllegalOption(void) { + E_Exit("Illegal option"); +} + +#include "core_dyn_x86\cache.h" + +static struct { + Bitu callback; + CacheBlock * lastblock; +} core_dyn; + + +#include "core_dyn_x86\risc_x86.h" + +struct DynState { + DynReg regs[G_MAX]; +}; + +static void dyn_releaseregs(void) { + for (Bitu i=0;iregs[i].flags=DynRegs[i].flags; + state->regs[i].genreg=DynRegs[i].genreg; + } +} + +static void dyn_loadstate(DynState * state) { + for (Bitu i=0;iregs[i]); + } +} + + +static void dyn_synchstate(DynState * state) { + for (Bitu i=0;iregs[i]); + } +} +#include "core_dyn_x86\decoder.h" + +Bits CPU_Core_Dyn_X86_Run(void) { + /* Determine the linear address of CS:EIP */ +restart_core: + PhysPt ip_point=SegPhys(cs)+reg_eip; + Bitu ip_page=ip_point>>12; + mem_readb(ip_point); //Init whatever page we are in + PageHandler * handler=paging.tlb.handler[ip_page]; + CodePageHandler * chandler=0; + #if C_HEAVY_DEBUG + if (DEBUG_HeavyIsBreakpoint()) return debugCallback; + #endif + if (handler->flags & PFLAG_HASCODE) { + /* Find correct Dynamic Block to run */ + chandler=(CodePageHandler *)handler; +findblock:; + CacheBlock * block=chandler->FindCacheBlock(ip_point&4095); + if (!block) { + block=CreateCacheBlock(ip_point,cpu.code.big,128); + DYN_LOG("Created block size %x type %d",block->cache.size,block->type); + chandler->AddCacheBlock(block); + if (block->page.end>=4096) { + DYN_LOG("block crosses page boundary"); + } + } +run_block: + BlockReturn ret=gen_runcode(block->cache.start); + switch (ret) { + case BR_Normal: + /* Maybe check if we staying in the same page? */ +#if C_HEAVY_DEBUG + if (DEBUG_HeavyIsBreakpoint()) return debugCallback; +#endif + goto restart_core; + case BR_Cycles: +#if C_HEAVY_DEBUG + if (DEBUG_HeavyIsBreakpoint()) return debugCallback; +#endif + return CBRET_NONE; + case BR_CallBack: + return core_dyn.callback; + case BR_Opcode: + CPU_CycleLeft+=CPU_Cycles; + CPU_Cycles=1; + return CPU_Core_Normal_Run(); + case BR_Link1: + case BR_Link2: + { + Bitu temp_ip=SegPhys(cs)+reg_eip; + Bitu temp_page=temp_ip >> 12; + CodePageHandler * temp_handler=(CodePageHandler *)paging.tlb.handler[temp_page]; + if (temp_handler->flags & PFLAG_HASCODE) { + block=temp_handler->FindCacheBlock(temp_ip & 4095); + if (!block) goto restart_core; + cache_linkblocks(core_dyn.lastblock,block,ret==BR_Link2); + goto run_block; + } + } + goto restart_core; + } + } else { + if (handler->flags & PFLAG_NOCODE) { + LOG_MSG("can't run code in this page"); + return CPU_Core_Normal_Run(); + } + Bitu phys_page=ip_page; + if (!PAGING_MakePhysPage(phys_page)) { + LOG_MSG("Can't find physpage"); + return CPU_Core_Normal_Run(); + } + chandler=new CodePageHandler(handler); + MEM_SetPageHandler(phys_page,1,chandler); //Setup the handler + PAGING_UnlinkPages(ip_page,1); + goto findblock; + } + return 0; +} + + +void CPU_Core_Dyn_X86_Init(void) { + Bits i; + /* Setup the global registers and their flags */ + for (i=0;iflags|PFLAG_HASCODE; + flags&=~PFLAG_WRITEABLE; + memset(&hash_map,0,sizeof(hash_map)); + memset(&write_map,0,sizeof(write_map)); + } + void InvalidateRange(Bits start,Bits end) { + Bits maps=start>>DYN_HASH_SHIFT; + Bits map=maps; + Bits count=write_map[maps]; + while (map>=0 && count>0) { + CacheBlock * block=hash_map[map]; + CacheBlock * * where=&hash_map[map]; + while (block) { + CacheBlock * nextblock=block->hash.next; + if (start<=block->page.end && end>=block->page.start) { + for (Bitu i=block->page.first;i<=block->page.last;i++) write_map[i]--; + block->code_page=0; //Else resetblock will do double work + count--; + cache_resetblock(block); + *where=nextblock; + } else { + where=&block->hash.next; + } + block=nextblock; + } + map--; + } + } + void writeb(PhysPt addr,Bitu val){ + if (val!=host_readb(hostmem+(addr&4095))) { + InvalidateRange(addr&4095,addr&4095); + host_writeb(hostmem+(addr&4095),val); + } + } + void writew(PhysPt addr,Bitu val){ + if (val!=host_readw(hostmem+(addr&4095))) { + InvalidateRange(addr&4095,(addr&4095)+1); + host_writew(hostmem+(addr&4095),val); + } + } + void writed(PhysPt addr,Bitu val){ + if (val!=host_readd(hostmem+(addr&4095))) { + InvalidateRange(addr&4095,(addr&4095)+3); + host_writed(hostmem+(addr&4095),val); + } + } + void AddCacheBlock(CacheBlock * block) { + Bit16u first,last; + if (block->page.start<0) first=0; + else first=block->page.start>>DYN_HASH_SHIFT; + block->hash.next=hash_map[first]; + hash_map[first]=block; + if (block->page.end>=4096) last=DYN_PAGE_HASH-1; + else last=block->page.end>>DYN_HASH_SHIFT; + block->page.first=first; + block->page.last=last; + for (;first<=last;first++) { + write_map[first]++; + } + block->code_page=this; + } + void DelCacheBlock(CacheBlock * block) { + CacheBlock * * where=&hash_map[block->page.first]; + while (*where) { + if (*where==block) { + *where=block->hash.next; + break; + } + where=&((*where)->hash.next); + } + for (Bitu i=block->page.first;i<=block->page.last;i++) { + write_map[i]--; + } + } + CacheBlock * FindCacheBlock(Bitu start) { + CacheBlock * block=hash_map[start>>DYN_HASH_SHIFT]; + while (block) { + if (block->page.start==start) return block; + block=block->hash.next; + } + return 0; + } + HostPt GetHostPt(Bitu phys_page) { + hostmem=old_pagehandler->GetHostPt(phys_page); + return hostmem; + } +private: + PageHandler * old_pagehandler; + CacheBlock * hash_map[DYN_PAGE_HASH]; + Bit8u write_map[DYN_PAGE_HASH]; + HostPt hostmem; +}; + + +static INLINE void cache_addunsedblock(CacheBlock * block) { + block->list_next=cache.block.free; + cache.block.free=block; +} + +static CacheBlock * cache_getblock(void) { + CacheBlock * ret=cache.block.free; + if (!ret) E_Exit("Ran out of CacheBlocks" ); + cache.block.free=ret->list_next; + return ret; +} + +static INLINE void cache_clearlinkfrom(CacheBlock * block,CacheBlock * from) { + for (Bitu i=0;ilink.from[i]==from) block->link.from[i]=0; + } +} + +static INLINE void cache_clearlinkto(CacheBlock * block,CacheBlock * to) { + if (block->link.to[0]==to) block->link.to[0]=&cache.linkblocks[0]; + if (block->link.to[1]==to) block->link.to[1]=&cache.linkblocks[1]; +} + +static void cache_linkblocks(CacheBlock * from,CacheBlock * to,Bitu link) { + from->link.to[link]=to; + CacheBlock * clear=to->link.from[to->link.index]; + if (clear) { + DYN_LOG("backlink buffer full"); + cache_clearlinkto(to->link.from[to->link.index],to); + } + to->link.from[to->link.index]=from; + to->link.index++; + if (to->link.index>=DYN_LINKS) to->link.index=0; +} + +static void cache_resetblock(CacheBlock * block) { + Bits i; + DYN_LOG("Resetted block"); + block->type=BT_Free; + /* Clear all links to this block from other blocks */ + for (i=0;ilink.from[i]) cache_clearlinkto(block->link.from[i],block); + block->link.from[i]=0; + } + /* Clear all links from this block to other blocks */ + if (block->link.to[0]!=&cache.linkblocks[0]) { + cache_clearlinkfrom(block->link.to[0],block); + block->link.to[0]=&cache.linkblocks[0]; + } + if (block->link.to[1]!=&cache.linkblocks[1]) { + cache_clearlinkfrom(block->link.to[1],block); + block->link.to[1]=&cache.linkblocks[1]; + } + block->link.index=0; + if (block->code_page) block->code_page->DelCacheBlock(block); +} + +static CacheBlock * cache_openblock(void) { + CacheBlock * block=cache.block.active; + /* check for enough space in this block */ + Bitu size=block->cache.size; + CacheBlock * nextblock=block->list_next; + while (sizecache.size; + CacheBlock * tempblock=nextblock->list_next; + if (nextblock->type!=BT_Free) cache_resetblock(nextblock); + cache_addunsedblock(nextblock); + nextblock=tempblock; + } +skipresize: + block->cache.size=size; + block->list_next=nextblock; + cache.pos=block->cache.start; + return block; +} + +static void cache_closeblock(BlockType type) { + CacheBlock * block=cache.block.active; + /* Setup some structures in the block determined by type */ + block->type=type; + switch (type) { + case BT_Normal: + break; + case BT_SingleLink: + block->link.to[0]=&cache.linkblocks[0]; + break; + case BT_DualLink: + block->link.to[0]=&cache.linkblocks[0]; + block->link.to[1]=&cache.linkblocks[1]; + break; + } + /* Close the block with correct alignments */ + Bitu written=cache.pos-block->cache.start; + if (written>block->cache.size) { + if (!block->list_next) { + if (written>block->cache.size+CACHE_MAXSIZE) E_Exit("CacheBlock overrun"); + } else E_Exit("CacheBlock overrun"); + } else { + Bitu new_size; + Bitu left=block->cache.size-written; + /* Smaller than cache align then don't bother to resize */ + if (left>CACHE_ALIGN) { + new_size=((written-1)|(CACHE_ALIGN-1))+1; + } else new_size=block->cache.size; + CacheBlock * newblock=cache_getblock(); + newblock->cache.start=block->cache.start+new_size; + newblock->cache.size=block->cache.size-new_size; + newblock->list_next=block->list_next; + newblock->type=BT_Free; + block->cache.size=new_size; + block->list_next=newblock; + } + /* Advance the active block pointer */ + if (!block->list_next) { + DYN_LOG("Cache full restarting"); + cache.block.active=cache.block.first; + } else { + cache.block.active=block->list_next; + } +} + +static INLINE void cache_addb(Bit8u val) { + *cache.pos++=val; +} + +static INLINE void cache_addw(Bit16u val) { + *(Bit16u*)cache.pos=val; + cache.pos+=2; +} + +static INLINE void cache_addd(Bit32u val) { + *(Bit32u*)cache.pos=val; + cache.pos+=4; +} + + +static void gen_return(BlockReturn retcode); + +static void cache_init(void) { + Bits i; + memset(&cache_blocks,0,sizeof(cache_blocks)); + cache.block.free=&cache_blocks[0]; + for (i=0;icache.start=&cache_code[0]; + block->cache.size=CACHE_TOTAL; + block->list_next=0; //Last block in the list + cache.pos=&cache_code_link_blocks[0][0]; + cache.linkblocks[0].cache.start=cache.pos; + gen_return(BR_Link1); + cache.pos=&cache_code_link_blocks[1][0]; + cache.linkblocks[1].cache.start=cache.pos; + gen_return(BR_Link2); +} \ No newline at end of file diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h new file mode 100644 index 00000000..8326d252 --- /dev/null +++ b/src/cpu/core_dyn_x86/decoder.h @@ -0,0 +1,1252 @@ +static struct DynDecode { + PhysPt code; + PhysPt code_start; + PhysPt op_start; + bool big_op; + bool big_addr; + bool rep; + Bitu cycles; + CacheBlock * block; + struct { + Bitu val; + Bitu mod; + Bitu rm; + Bitu reg; + } modrm; + DynReg * segprefix; +} decode; + +#define FASTCALL __fastcall + +#include "helpers.h" + +static Bit8u FASTCALL decode_fetchb(void) { + return mem_readb(decode.code++); +} +static Bit16u FASTCALL decode_fetchw(void) { + decode.code+=2; + return mem_readw(decode.code-2); +} +static Bit32u FASTCALL decode_fetchd(void) { + decode.code+=4; + return mem_readd(decode.code-4); +} + +static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { + if (high) gen_call_function((void *)&mem_readb,"%Dd%Rh",addr,dst); + else gen_call_function((void *)&mem_readb,"%Dd%Rl",addr,dst); +} +static void dyn_write_byte(DynReg * addr,DynReg * val,Bitu high) { + if (high) gen_call_function((void *)&mem_writeb,"%Dd%Dh",addr,val); + else gen_call_function((void *)&mem_writeb,"%Dd%Dl",addr,val); +} + +static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) { + if (dword) gen_call_function((void *)&mem_readd,"%Dd%Rd",addr,dst); + else gen_call_function((void *)&mem_readw,"%Dd%Rw",addr,dst); +} + +static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { + if (dword) gen_call_function((void *)&mem_writed,"%Dd%Dd",addr,val); + else gen_call_function((void *)&mem_writew,"%Dd%Dw",addr,val); +} + +static void dyn_reduce_cycles(void) { + if (!decode.cycles) decode.cycles++; + gen_lea(DREG(CYCLES),DREG(CYCLES),0,0,-(Bits)decode.cycles); + gen_releasereg(DREG(CYCLES)); +} + +static void dyn_push(DynReg * dynreg) { + gen_storeflags(); + if (decode.big_op) { + gen_dop_word_imm(DOP_SUB,true,DREG(ESP),4); + } else { + gen_dop_word_imm(DOP_SUB,true,DREG(ESP),2); + } + gen_dop_word(DOP_MOV,true,DREG(STACK),DREG(ESP)); + gen_dop_word(DOP_AND,true,DREG(STACK),DREG(SMASK)); + gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); + if (decode.big_op) { + gen_call_function((void *)&mem_writed,"%Drd%Dd",DREG(STACK),dynreg); + } else { + //Can just push the whole 32-bit word as operand + gen_call_function((void *)&mem_writew,"%Drd%Dd",DREG(STACK),dynreg); + } + gen_releasereg(DREG(STACK)); + gen_restoreflags(); +} + +static void dyn_pop(DynReg * dynreg) { + gen_storeflags(); + gen_dop_word(DOP_MOV,true,DREG(STACK),DREG(ESP)); + gen_dop_word(DOP_AND,true,DREG(STACK),DREG(SMASK)); + gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); + if (decode.big_op) { + gen_call_function((void *)&mem_readd,"%Rd%Drd",dynreg,DREG(STACK)); + } else { + gen_call_function((void *)&mem_readw,"%Rw%Drd",dynreg,DREG(STACK)); + } + if (dynreg!=DREG(ESP)) { + if (decode.big_op) { + gen_dop_word_imm(DOP_ADD,true,DREG(ESP),4); + } else { + gen_dop_word_imm(DOP_ADD,true,DREG(ESP),2); + } + } + gen_releasereg(DREG(STACK)); + gen_restoreflags(); +} + +static void FASTCALL dyn_get_modrm(void) { + decode.modrm.val=decode_fetchb(); + decode.modrm.mod=(decode.modrm.val >> 6) & 3; + decode.modrm.reg=(decode.modrm.val >> 3) & 7; + decode.modrm.rm=(decode.modrm.val & 7); +} + +static void FASTCALL dyn_fill_ea(bool addseg=true) { + DynReg * segbase; + if (!decode.big_addr) { + Bits imm; + switch (decode.modrm.mod) { + case 0:imm=0;break; + case 1:imm=(Bit8s)decode_fetchb();break; + case 2:imm=(Bit16s)decode_fetchw();break; + } + switch (decode.modrm.rm) { + case 0:/* BX+SI */ + gen_lea(DREG(EA),DREG(EBX),DREG(ESI),0,imm); + segbase=DREG(DS); + break; + case 1:/* BX+DI */ + gen_lea(DREG(EA),DREG(EBX),DREG(EDI),0,imm); + segbase=DREG(DS); + break; + case 2:/* BP+SI */ + gen_lea(DREG(EA),DREG(EBP),DREG(ESI),0,imm); + segbase=DREG(SS); + break; + case 3:/* BP+DI */ + gen_lea(DREG(EA),DREG(EBP),DREG(EDI),0,imm); + segbase=DREG(SS); + break; + case 4:/* SI */ + gen_lea(DREG(EA),DREG(ESI),0,0,imm); + segbase=DREG(DS); + break; + case 5:/* DI */ + gen_lea(DREG(EA),DREG(EDI),0,0,imm); + segbase=DREG(DS); + break; + case 6:/* imm/BP */ + if (!decode.modrm.mod) { + imm=(Bit16s)decode_fetchw(); + gen_dop_word_imm(DOP_MOV,true,DREG(EA),imm); + segbase=DREG(DS); + } else { + gen_lea(DREG(EA),DREG(EBP),0,0,imm); + segbase=DREG(SS); + } + break; + case 7: /* BX */ + gen_lea(DREG(EA),DREG(EBX),0,0,imm); + segbase=DREG(DS); + break; + } + gen_extend_word(false,DREG(EA),DREG(EA)); + } else { + Bits imm=0; + DynReg * base=0;DynReg * scaled=0;Bitu scale=0; + switch (decode.modrm.rm) { + case 0:base=DREG(EAX);segbase=DREG(DS);break; + case 1:base=DREG(ECX);segbase=DREG(DS);break; + case 2:base=DREG(EDX);segbase=DREG(DS);break; + case 3:base=DREG(EBX);segbase=DREG(DS);break; + case 4: /* SIB */ + { + Bitu sib=decode_fetchb(); + switch (sib & 7) { + case 0:base=DREG(EAX);segbase=DREG(DS);break; + case 1:base=DREG(ECX);segbase=DREG(DS);break; + case 2:base=DREG(EDX);segbase=DREG(DS);break; + case 3:base=DREG(EBX);segbase=DREG(DS);break; + case 4:base=DREG(ESP);segbase=DREG(SS);break; + case 5: + if (decode.modrm.mod) { + base=DREG(EBP);segbase=DREG(SS); + } else { + imm=(Bit32s)decode_fetchd();segbase=DREG(DS); + } + break; + case 6:base=DREG(ESI);segbase=DREG(DS);break; + case 7:base=DREG(EDI);segbase=DREG(DS);break; + } + static DynReg * scaledtable[8]={ + DREG(EAX),DREG(ECX),DREG(EDX),DREG(EBX), + 0,DREG(EBP),DREG(ESI),DREG(EDI), + }; + scaled=scaledtable[(sib >> 3) &7]; + scale=(sib >> 6); + } + break; /* SIB Break */ + case 5: + if (decode.modrm.mod) { + base=DREG(EBP);segbase=DREG(SS); + } else { + imm=(Bit32s)decode_fetchd();segbase=DREG(DS); + } + break; + case 6:base=DREG(ESI);segbase=DREG(DS);break; + case 7:base=DREG(EDI);segbase=DREG(DS);break; + } + switch (decode.modrm.mod) { + case 1:imm=(Bit8s)decode_fetchb();break; + case 2:imm=(Bit32s)decode_fetchd();break; + } + gen_lea(DREG(EA),base,scaled,scale,imm); + } + if (addseg) { + gen_lea(DREG(EA),DREG(EA),decode.segprefix ? decode.segprefix : segbase,0,0); + } +} + +static void dyn_dop_ebgb(DualOps op) { + dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg&3]; + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_read_byte(DREG(EA),DREG(TMPB),false); + gen_dop_byte(op,DREG(TMPB),0,rm_reg,decode.modrm.reg&4); + dyn_write_byte(DREG(EA),DREG(TMPB),false); + gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB)); + } else { + gen_dop_byte(op,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,rm_reg,decode.modrm.reg&4); + } +} + + +static void dyn_dop_gbeb(DualOps op) { + dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg&3]; + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_read_byte(DREG(EA),DREG(TMPB),false); + gen_dop_byte(op,rm_reg,decode.modrm.reg&4,DREG(TMPB),0); + gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB)); + } else { + gen_dop_byte(op,rm_reg,decode.modrm.reg&4,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); + } +} + +static void dyn_mov_ebib(void) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + //TODO Maybe not use a temp register here and call mem_writeb directly? + dyn_fill_ea(); + gen_dop_byte_imm(DOP_MOV,DREG(TMPB),0,decode_fetchb()); + dyn_write_byte(DREG(EA),DREG(TMPB),false); + gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB)); + } else { + gen_dop_byte_imm(DOP_MOV,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,decode_fetchb()); + } +} + +static void dyn_mov_ebgb(void) { + dyn_get_modrm(); + DynReg * rm_reg=&DynRegs[decode.modrm.reg&3];Bitu rm_regi=decode.modrm.reg&4; + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_write_byte(DREG(EA),rm_reg,rm_regi); + gen_releasereg(DREG(EA)); + } else { + gen_dop_byte(DOP_MOV,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,rm_reg,rm_regi); + } +} + +static void dyn_mov_gbeb(void) { + dyn_get_modrm(); + DynReg * rm_reg=&DynRegs[decode.modrm.reg&3];Bitu rm_regi=decode.modrm.reg&4; + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_read_byte(DREG(EA),rm_reg,rm_regi); + gen_releasereg(DREG(EA)); + } else { + gen_dop_byte(DOP_MOV,rm_reg,rm_regi,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); + } +} + +static void dyn_dop_evgv(DualOps op) { + dyn_get_modrm(); + DynReg * rm_reg=&DynRegs[decode.modrm.reg]; + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); + gen_dop_word(op,decode.big_op,DREG(TMPW),rm_reg); + dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); + gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPW)); + } else { + gen_dop_word(op,decode.big_op,&DynRegs[decode.modrm.rm],rm_reg); + } +} + +static void dyn_dop_gvev(DualOps op) { + dyn_get_modrm(); + DynReg * rm_reg=&DynRegs[decode.modrm.reg]; + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); + gen_dop_word(op,decode.big_op,rm_reg,DREG(TMPW)); + gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPW)); + } else { + gen_dop_word(op,decode.big_op,rm_reg,&DynRegs[decode.modrm.rm]); + } +} + +static void dyn_mov_evgv(void) { + dyn_get_modrm(); + DynReg * rm_reg=&DynRegs[decode.modrm.reg]; + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_write_word(DREG(EA),rm_reg,decode.big_op); + gen_releasereg(DREG(EA)); + } else { + gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],rm_reg); + } +} + +static void dyn_mov_gvev(void) { + dyn_get_modrm(); + DynReg * rm_reg=&DynRegs[decode.modrm.reg]; + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_read_word(DREG(EA),rm_reg,decode.big_op); + gen_releasereg(DREG(EA)); + } else { + gen_dop_word(DOP_MOV,decode.big_op,rm_reg,&DynRegs[decode.modrm.rm]); + } +} +static void dyn_mov_eviv(void) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(); + gen_dop_word_imm(DOP_MOV,decode.big_op,DREG(TMPW),decode.big_op ? decode_fetchd() : decode_fetchw()); + dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); + gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPW)); + } else { + gen_dop_word_imm(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],decode.big_op ? decode_fetchd() : decode_fetchw()); + } +} + +static void dyn_dshift_ev_gv(bool left,bool immediate) { + dyn_get_modrm(); + DynReg * rm_reg=&DynRegs[decode.modrm.reg]; + DynReg * ea_reg; + if (decode.modrm.mod<3) { + dyn_fill_ea();ea_reg=DREG(TMPW); + dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); + } else ea_reg=&DynRegs[decode.modrm.rm]; + if (immediate) gen_dshift_imm(decode.big_op,left,ea_reg,rm_reg,decode_fetchb()); + else gen_dshift_cl(decode.big_op,left,ea_reg,rm_reg,DREG(ECX)); + if (decode.modrm.mod<3) { + dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); + gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPW)); + } +} + + +static DualOps grp1_table[8]={DOP_ADD,DOP_OR,DOP_ADC,DOP_SBB,DOP_AND,DOP_SUB,DOP_XOR,DOP_CMP}; +static void dyn_grp1_eb_ib(void) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_read_byte(DREG(EA),DREG(TMPB),false); + gen_dop_byte_imm(grp1_table[decode.modrm.reg],DREG(TMPB),0,decode_fetchb()); + if (grp1_table[decode.modrm.reg]!=DOP_CMP) dyn_write_byte(DREG(EA),DREG(TMPB),false); + gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB)); + } else { + gen_dop_byte_imm(grp1_table[decode.modrm.reg],&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,decode_fetchb()); + } +} + +static void dyn_grp1_ev_ivx(bool withbyte) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); + Bits imm=withbyte ? (Bit8s)decode_fetchb() : (decode.big_op ? decode_fetchd(): decode_fetchw()); + gen_dop_word_imm(grp1_table[decode.modrm.reg],decode.big_op,DREG(TMPW),imm); + dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); + gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPW)); + } else { + Bits imm=withbyte ? (Bit8s)decode_fetchb() : (decode.big_op ? decode_fetchd(): decode_fetchw()); + gen_dop_word_imm(grp1_table[decode.modrm.reg],decode.big_op,&DynRegs[decode.modrm.rm],imm); + } +} + + +static ShiftOps grp2_table[8]={ + SHIFT_ROL,SHIFT_ROR,SHIFT_RCL,SHIFT_RCR, + SHIFT_SHL,SHIFT_SHR,SHIFT_SHL,SHIFT_SAR +}; + +enum grp2_types { + grp2_1,grp2_imm,grp2_cl, +}; + +static void dyn_grp2_eb(grp2_types type) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_read_byte(DREG(EA),DREG(TMPB),false); + DynReg * shift; + switch (type) { + case grp2_cl:shift=DREG(ECX);break; + case grp2_1:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,1);break; + case grp2_imm:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,decode_fetchb());break; + } + gen_shift_byte(grp2_table[decode.modrm.reg],shift,DREG(TMPB),0); + dyn_write_byte(DREG(EA),DREG(TMPB),false); + gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB));gen_releasereg(DREG(SHIFT)); + } else { + DynReg * shift; + switch (type) { + case grp2_cl:shift=DREG(ECX);break; + case grp2_1:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,1);break; + case grp2_imm:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,decode_fetchb());break; + } + gen_shift_byte(grp2_table[decode.modrm.reg],shift,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); + gen_releasereg(DREG(SHIFT)); + } +} + +static void dyn_grp2_ev(grp2_types type) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); + DynReg * shift; + switch (type) { + case grp2_cl:shift=DREG(ECX);break; + case grp2_1:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,1);break; + case grp2_imm:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,decode_fetchb());break; + } + gen_shift_word(grp2_table[decode.modrm.reg],shift,decode.big_op,DREG(TMPW)); + dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); + gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPW));gen_releasereg(DREG(SHIFT)); + } else { + DynReg * shift; + switch (type) { + case grp2_cl:shift=DREG(ECX);break; + case grp2_1:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,1);break; + case grp2_imm:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,decode_fetchb());break; + } + gen_shift_word(grp2_table[decode.modrm.reg],shift,decode.big_op,&DynRegs[decode.modrm.rm]); + gen_releasereg(DREG(SHIFT)); + } +} + +static void dyn_grp3_eb(void) { + DynState state;Bit8u * branch; + dyn_get_modrm();DynReg * src;Bit8u src_i; + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_read_byte(DREG(EA),DREG(TMPB),false); + src=DREG(TMPB);src_i=0; + } else { + src=&DynRegs[decode.modrm.rm&3]; + src_i=decode.modrm.rm&4; + } + switch (decode.modrm.reg) { + case 0x0: /* test eb,ib */ + gen_dop_byte_imm(DOP_TEST,src,src_i,decode_fetchb()); + goto skipsave; + case 0x2: /* NOT Eb */ + gen_sop_byte(SOP_NOT,src,src_i); + break; + case 0x3: /* NEG Eb */ + gen_sop_byte(SOP_NEG,src,src_i); + break; + case 0x4: /* mul Eb */ + gen_mul_byte(false,DREG(EAX),src,src_i); + goto skipsave; + case 0x5: /* imul Eb */ + gen_mul_byte(true,DREG(EAX),src,src_i); + goto skipsave; + case 0x6: /* div Eb */ + case 0x7: /* idiv Eb */ + /* EAX could be used, so precache it */ + if (decode.modrm.mod==3) + gen_dop_byte(DOP_MOV,DREG(TMPB),0,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); + gen_storeflags();gen_releasereg(DREG(EAX)); + gen_call_function((decode.modrm.reg==6) ? (void *)&dyn_helper_divb : (void *)&dyn_helper_idivb, + "%Rd%Drl",DREG(TMPB),DREG(TMPB)); + gen_dop_word(DOP_OR,true,DREG(TMPB),DREG(TMPB)); + branch=gen_create_branch(BR_Z); + dyn_savestate(&state); + dyn_reduce_cycles(); + gen_lea(DREG(EIP),DREG(EIP),0,0,decode.op_start-decode.code_start); + dyn_save_flags(true); + dyn_releaseregs(); + gen_call_function((void *)&CPU_Exception,"%Id%Id",0,0); + dyn_load_flags(); + gen_return(BR_Normal); + dyn_loadstate(&state); + gen_fill_branch(branch); + gen_restoreflags(); + goto skipsave; + } + /* Save the result if memory op */ + if (decode.modrm.mod<3) dyn_write_byte(DREG(EA),DREG(TMPB),false); +skipsave: + gen_releasereg(DREG(TMPB));gen_releasereg(DREG(EA)); +} + +static void dyn_grp3_ev(void) { + DynState state;Bit8u * branch; + dyn_get_modrm();DynReg * src; + if (decode.modrm.mod<3) { + dyn_fill_ea();src=DREG(TMPW); + dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); + } else src=&DynRegs[decode.modrm.rm]; + switch (decode.modrm.reg) { + case 0x0: /* test ev,iv */ + gen_dop_word_imm(DOP_TEST,decode.big_op,src,decode.big_op ? decode_fetchd() : decode_fetchw()); + goto skipsave; + case 0x2: /* NOT Ev */ + gen_sop_word(SOP_NOT,decode.big_op,src); + break; + case 0x3: /* NEG Eb */ + gen_sop_word(SOP_NEG,decode.big_op,src); + break; + case 0x4: /* mul Eb */ + gen_mul_word(false,DREG(EAX),DREG(EDX),decode.big_op,src); + goto skipsave; + case 0x5: /* imul Eb */ + gen_mul_word(true,DREG(EAX),DREG(EDX),decode.big_op,src); + goto skipsave; + case 0x6: /* div Eb */ + case 0x7: /* idiv Eb */ + /* EAX could be used, so precache it */ + if (decode.modrm.mod==3) + gen_dop_word(DOP_MOV,decode.big_op,DREG(TMPW),&DynRegs[decode.modrm.rm]); + gen_storeflags();gen_releasereg(DREG(EAX));gen_releasereg(DREG(EDX)); + void * func=(decode.modrm.reg==6) ? + (decode.big_op ? (void *)&dyn_helper_divd : (void *)&dyn_helper_divw) : + (decode.big_op ? (void *)&dyn_helper_idivd : (void *)&dyn_helper_idivw); + gen_call_function(func,"%Rd%Drd",DREG(TMPW),DREG(TMPW)); + gen_dop_word(DOP_OR,true,DREG(TMPW),DREG(TMPW)); + branch=gen_create_branch(BR_Z); + dyn_savestate(&state); + dyn_reduce_cycles(); + gen_lea(DREG(EIP),DREG(EIP),0,0,decode.op_start-decode.code_start); + dyn_save_flags(true); + dyn_releaseregs(); + gen_call_function((void *)&CPU_Exception,"%Id%Id",0,0); + dyn_load_flags(); + gen_return(BR_Normal); + dyn_loadstate(&state); + gen_fill_branch(branch); + gen_restoreflags(); + goto skipsave; + } + /* Save the result if memory op */ + if (decode.modrm.mod<3) dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); +skipsave: + gen_releasereg(DREG(TMPW));gen_releasereg(DREG(EA)); +} + + +static void dyn_mov_ev_seg(void) { + dyn_get_modrm(); + gen_load_host(&Segs.val[(SegNames) decode.modrm.reg],DREG(TMPW),2); + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); + gen_releasereg(DREG(EA)); + } else { + gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],DREG(TMPW)); + } + gen_releasereg(DREG(TMPW)); +} + +static void dyn_mov_seg_ev(void) { + dyn_get_modrm(); + SegNames seg=(SegNames)decode.modrm.reg; + if (seg==cs) IllegalOption(); + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_read_word(DREG(EA),DREG(EA),decode.big_op); + gen_call_function((void *)&CPU_SetSegGeneral,"%Id%Drw",seg,DREG(EA)); + } else { + gen_call_function((void *)&CPU_SetSegGeneral,"%Id%Dw",seg,&DynRegs[decode.modrm.rm]); + } + gen_releasereg(&DynRegs[G_ES+seg]); +} + + +static void dyn_push_seg(SegNames seg) { + gen_load_host(&Segs.val[seg],DREG(TMPW),2); + dyn_push(DREG(TMPW)); + gen_releasereg(DREG(TMPW)); +} + +static void dyn_pop_seg(SegNames seg) { + gen_storeflags(); + dyn_pop(DREG(TMPW)); + gen_call_function((void*)&CPU_SetSegGeneral,"%Id%Drw",seg,DREG(TMPW)); + gen_releasereg(&DynRegs[G_ES+seg]); + gen_restoreflags(); +} + +static void dyn_pop_ev(void) { + gen_storeflags(); + dyn_pop(DREG(TMPW)); + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); + gen_releasereg(DREG(EA)); + } else { + gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],DREG(TMPW)); + } + gen_releasereg(DREG(TMPW)); + gen_restoreflags(); +} + +static void dyn_leave(void) { + gen_storeflags(); + gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(SMASK)); + gen_sop_word(SOP_NOT,true,DREG(TMPW)); + gen_dop_word(DOP_AND,true,DREG(ESP),DREG(TMPW)); + gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(EBP)); + gen_dop_word(DOP_AND,true,DREG(TMPW),DREG(SMASK)); + gen_dop_word(DOP_OR,true,DREG(ESP),DREG(TMPW)); + dyn_pop(DREG(EBP)); + gen_releasereg(DREG(TMPW)); + gen_restoreflags(); +} + +static void dyn_segprefix(SegNames seg) { + if (decode.segprefix) IllegalOption(); + decode.segprefix=&DynRegs[G_ES+seg]; +} + +static void dyn_closeblock(BlockType type) { + //Shouldn't create empty block normally but let's do it like this + if (decode.code>decode.code_start) decode.code--; + Bitu start_page=decode.code_start >> 12; + Bitu end_page=decode.code>>12; + decode.block->page.start=(Bit16s)decode.code_start & 4095; + decode.block->page.end=(Bit16s)((end_page-start_page)*4096+(decode.code&4095)); + cache_closeblock(type); +} + +static void dyn_normal_exit(BlockReturn code) { + gen_lea(DREG(EIP),DREG(EIP),0,0,decode.code-decode.code_start); + dyn_reduce_cycles(); + dyn_releaseregs(); + gen_return(code); + dyn_closeblock(BT_Normal); +} + +static void dyn_exit_link(bool dword,Bits eip_change) { + gen_lea(DREG(EIP),DREG(EIP),0,0,(decode.code-decode.code_start)+eip_change); + if (!dword) gen_extend_word(false,DREG(EIP),DREG(EIP)); + dyn_reduce_cycles(); + dyn_releaseregs(); +// gen_return(BR_Normal); + gen_jmp_ptr(&decode.block->link.to[0],offsetof(CacheBlock,cache.start)); + dyn_closeblock(BT_SingleLink); +} + +static void dyn_branched_exit(BranchTypes btype,Bit32s eip_add) { + dyn_reduce_cycles(); + dyn_releaseregs(); + Bitu eip_base=decode.code-decode.code_start; + Bit8u * data=gen_create_branch(btype); + /* Branch not taken */ + gen_lea(DREG(EIP),DREG(EIP),0,0,eip_base); + gen_releasereg(DREG(EIP)); +// gen_return(BR_Normal); + gen_jmp_ptr(&decode.block->link.to[0],offsetof(CacheBlock,cache.start)); + gen_fill_branch(data); + /* Branch taken */ + gen_lea(DREG(EIP),DREG(EIP),0,0,eip_base+eip_add); + gen_releasereg(DREG(EIP)); +// gen_return(BR_Normal); + gen_jmp_ptr(&decode.block->link.to[1],offsetof(CacheBlock,cache.start)); + dyn_closeblock(BT_DualLink); +} + +enum LoopTypes { + LOOP_NONE,LOOP_NE,LOOP_E, +}; + +static void dyn_loop(LoopTypes type) { + Bits eip_add=(Bit8s)decode_fetchb(); + Bitu eip_base=decode.code-decode.code_start; + gen_storeflags(); + dyn_reduce_cycles(); + Bit8u * branch1; + Bit8u * branch2=0; + gen_sop_word(SOP_DEC,decode.big_addr,DREG(ECX)); + dyn_releaseregs(); + branch1=gen_create_branch(BR_Z); + gen_restoreflags(true); + switch (type) { + case LOOP_NONE: + break; + case LOOP_E: + branch2=gen_create_branch(BR_NZ); + break; + case LOOP_NE: + branch2=gen_create_branch(BR_Z); + break; + } + gen_lea(DREG(EIP),DREG(EIP),0,0,eip_base+eip_add); + gen_releasereg(DREG(EIP)); + gen_jmp_ptr(&decode.block->link.to[0],offsetof(CacheBlock,cache.start)); + gen_fill_branch(branch1); + if (branch2) gen_fill_branch(branch2); + /* Branch taken */ + gen_restoreflags(); + gen_lea(DREG(EIP),DREG(EIP),0,0,eip_base); + gen_releasereg(DREG(EIP)); + gen_jmp_ptr(&decode.block->link.to[1],offsetof(CacheBlock,cache.start)); + dyn_closeblock(BT_DualLink); +} + +static void dyn_ret_near(Bitu bytes) { + dyn_reduce_cycles(); +//TODO maybe AND eip 0xffff, but shouldn't be needed + gen_storeflags(); + dyn_pop(DREG(EIP)); + if (bytes) gen_dop_word_imm(DOP_ADD,true,DREG(ESP),bytes); + dyn_releaseregs(); + gen_restoreflags(); + gen_return(BR_Normal); + dyn_closeblock(BT_Normal); +} + +static void dyn_ret_far(Bitu bytes) { + dyn_reduce_cycles(); +//TODO maybe AND eip 0xffff, but shouldn't be needed + gen_lea(DREG(EIP),DREG(EIP),0,0,decode.code-decode.code_start); + dyn_save_flags(); + dyn_releaseregs(); + gen_call_function((void*)&CPU_RET,"%Id%Id%Id",decode.big_op,bytes,decode.code-decode.op_start); + dyn_load_flags(); + dyn_releaseregs();; + gen_return(BR_Normal); + dyn_closeblock(BT_Normal); +} + +static void dyn_call_near_imm(void) { + Bits imm; + if (decode.big_op) imm=(Bit32s)decode_fetchd(); + else imm=(Bit16s)decode_fetchw(); + gen_lea(DREG(EIP),DREG(EIP),0,0,decode.code-decode.code_start); + dyn_push(DREG(EIP)); + gen_lea(DREG(EIP),DREG(EIP),0,0,imm); + if (!decode.big_op) gen_extend_word(false,DREG(EIP),DREG(EIP)); + dyn_reduce_cycles(); + dyn_releaseregs(); + gen_return(BR_Normal); +// gen_jmp_ptr(&decode.block->link.to[0],offsetof(CacheBlock,cache.start)); + dyn_closeblock(BT_SingleLink); +} + +static void dyn_call_far_imm(void) { + Bitu sel,off; + off=decode.big_op ? decode_fetchd() : decode_fetchw(); + sel=decode_fetchw(); + dyn_reduce_cycles(); + gen_lea(DREG(EIP),DREG(EIP),0,0,decode.code-decode.code_start); + dyn_save_flags(); + dyn_releaseregs(); + gen_call_function((void*)&CPU_CALL,"%Id%Id%Id%Id",decode.big_op,sel,off,decode.code-decode.op_start); + dyn_load_flags(); + dyn_releaseregs(); + gen_return(BR_Normal); + dyn_closeblock(BT_Normal); +} + +static void dyn_jmp_far_imm(void) { + Bitu sel,off; + off=decode.big_op ? decode_fetchd() : decode_fetchw(); + sel=decode_fetchw(); + dyn_reduce_cycles(); + gen_lea(DREG(EIP),DREG(EIP),0,0,decode.code-decode.code_start); + dyn_save_flags(); + dyn_releaseregs(); + gen_call_function((void*)&CPU_JMP,"%Id%Id%Id%Id",decode.big_op,sel,off,decode.code-decode.op_start); + dyn_load_flags(); + dyn_releaseregs(); + gen_return(BR_Normal); + dyn_closeblock(BT_Normal); +} + +static void dyn_iret(void) { + dyn_save_flags(); + dyn_reduce_cycles(); + gen_dop_word_imm(DOP_ADD,true,DREG(EIP),decode.code-decode.code_start); + dyn_releaseregs(); + gen_call_function((void*)&CPU_IRET,"%Id%Id",decode.big_op,decode.code-decode.op_start); + dyn_load_flags(); + dyn_releaseregs(); + gen_return(BR_Normal); + dyn_closeblock(BT_CheckFlags); +} + +static void dyn_interrupt(Bitu num) { + dyn_save_flags(); + dyn_reduce_cycles(); + gen_dop_word_imm(DOP_ADD,true,DREG(EIP),decode.code-decode.code_start); + dyn_releaseregs(); + gen_call_function((void*)&CPU_Interrupt,"%Id%Id%Id",num,CPU_INT_SOFTWARE,decode.code-decode.op_start); + dyn_load_flags(); + dyn_releaseregs(); + gen_return(BR_Normal); + dyn_closeblock(BT_Normal); +} + +static CacheBlock * CreateCacheBlock(PhysPt start,bool big,Bitu max_opcodes) { + Bits i; + decode.code_start=start; + decode.code=start; + Bitu cycles=0; + decode.block=cache_openblock(); + gen_save_host_direct(&core_dyn.lastblock,(Bit32u)decode.block); + for (i=0;i=G_EAX;i--) { + dyn_pop((i!=G_ESP) ? &DynRegs[i] : DREG(TMPW)); + } + gen_restoreflags();gen_releasereg(DREG(TMPW)); + break; + //segprefix FS,GS + case 0x64:dyn_segprefix(fs);goto restart_prefix; + case 0x65:dyn_segprefix(gs);goto restart_prefix; + //Push immediates + //Operand size + case 0x66:decode.big_op=!big;goto restart_prefix; + //Address size + case 0x67:decode.big_addr=!big;goto restart_prefix; + case 0x68: /* PUSH Iv */ + gen_dop_word_imm(DOP_MOV,decode.big_op,DREG(TMPW),decode.big_op ? decode_fetchd() : decode_fetchw()); + dyn_push(DREG(TMPW)); + gen_releasereg(DREG(TMPW)); + break; + case 0x6a: /* PUSH Ibx */ + gen_dop_word_imm(DOP_MOV,true,DREG(TMPW),(Bit8s)decode_fetchb()); + dyn_push(DREG(TMPW)); + gen_releasereg(DREG(TMPW)); + break; + /* 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()); + return decode.block; + /* Group 1 */ + + case 0x80:dyn_grp1_eb_ib();break; + case 0x81:dyn_grp1_ev_ivx(false);break; + case 0x82:dyn_grp1_eb_ib();break; + case 0x83:dyn_grp1_ev_ivx(true);break; + /* TEST Gb,Eb Gv,Ev */ //Can use G,E since results don't get saved + case 0x84:dyn_dop_gbeb(DOP_TEST);break; + case 0x85:dyn_dop_gvev(DOP_TEST);break; + /* XCHG Eb,Gb Ev,Gv */ + case 0x86:dyn_dop_ebgb(DOP_XCHG);break; + case 0x87:dyn_dop_evgv(DOP_XCHG);break; + /* MOV e,g and g,e */ + case 0x88:dyn_mov_ebgb();break; + case 0x89:dyn_mov_evgv();break; + case 0x8a:dyn_mov_gbeb();break; + case 0x8b:dyn_mov_gvev();break; + /* MOV ev,seg */ + case 0x8c:dyn_mov_ev_seg();break; + /* LEA Gv */ + case 0x8d: + dyn_get_modrm();dyn_fill_ea(false); + gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.reg],DREG(EA)); + gen_releasereg(DREG(EA)); + break; + /* Mov seg,ev */ +// case 0x8e:dyn_mov_seg_ev();break; + /* POP Ev */ + case 0x8f:dyn_pop_ev();break; + //NOP + case 0x90: + break; + //XCHG ax,reg + case 0x91:case 0x92:case 0x93:case 0x94:case 0x95:case 0x96:case 0x97: + gen_dop_word(DOP_XCHG,decode.big_op,DREG(EAX),&DynRegs[opcode&07]); + break; + /* CBW/CWDE */ + case 0x98: + if (decode.big_op) gen_extend_word(true,DREG(EAX),DREG(EAX)); + else gen_extend_byte(true,false,DREG(EAX),DREG(EAX),0); + break; + /* CALL FAR Ip */ + case 0x9a:dyn_call_far_imm();return decode.block; + /* MOV AL,direct addresses */ + case 0xa0: + gen_lea(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),0,0, + decode.big_addr ? decode_fetchd() : decode_fetchw()); + dyn_read_byte(DREG(EA),DREG(EAX),false); + gen_releasereg(DREG(EA)); + break; + /* MOV AX,direct addresses */ + case 0xa1: + gen_lea(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),0,0, + decode.big_addr ? decode_fetchd() : decode_fetchw()); + dyn_read_word(DREG(EA),DREG(EAX),decode.big_op); + gen_releasereg(DREG(EA)); + break; + /* MOV direct address,AL */ + case 0xa2: + gen_lea(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),0,0, + decode.big_addr ? decode_fetchd() : decode_fetchw()); + dyn_write_byte(DREG(EA),DREG(EAX),false); + gen_releasereg(DREG(EA)); + break; + /* MOV direct addresses,AX */ + case 0xa3: + gen_lea(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),0,0, + decode.big_addr ? decode_fetchd() : decode_fetchw()); + dyn_write_word(DREG(EA),DREG(EAX),decode.big_op); + gen_releasereg(DREG(EA)); + break; + /* TEST AL,AX Imm */ + case 0xa8:gen_dop_byte_imm(DOP_TEST,DREG(EAX),0,decode_fetchb());break; + case 0xa9:gen_dop_word_imm(DOP_TEST,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; + + //Mov Byte reg,Imm byte + case 0xb0:case 0xb1:case 0xb2:case 0xb3:case 0xb4:case 0xb5:case 0xb6:case 0xb7: + gen_dop_byte_imm(DOP_MOV,&DynRegs[opcode&3],opcode&4,decode_fetchb()); + break; + //Mov word reg imm byte,word, + case 0xb8:case 0xb9:case 0xba:case 0xbb:case 0xbc:case 0xbd:case 0xbe:case 0xbf: + gen_dop_word_imm(DOP_MOV,decode.big_op,&DynRegs[opcode&7],decode.big_op ? decode_fetchd() : decode_fetchw());break; + break; + //GRP2 Eb/Ev,Ib + case 0xc0:dyn_grp2_eb(grp2_imm);break; + case 0xc1:dyn_grp2_ev(grp2_imm);break; + //RET near Iw / Ret + case 0xc2:dyn_ret_near(decode_fetchw());return decode.block; + case 0xc3:dyn_ret_near(0);return decode.block; + // MOV Eb/Ev,Ib/Iv + case 0xc6:dyn_mov_ebib();break; + case 0xc7:dyn_mov_eviv();break; + // LEAVE + case 0xc9:dyn_leave();break; + //RET far Iw / Ret + case 0xca:dyn_ret_far(decode_fetchw());return decode.block; + case 0xcb:dyn_ret_far(0);return decode.block; + /* Interrupt */ + case 0xcd:dyn_interrupt(decode_fetchb());return decode.block; + /* IRET */ + case 0xcF:dyn_iret();return decode.block; + //GRP2 Eb/Ev,1 + case 0xd0:dyn_grp2_eb(grp2_1);break; + case 0xd1:dyn_grp2_ev(grp2_1);break; + //GRP2 Eb/Ev,CL + case 0xd2:dyn_grp2_eb(grp2_cl);break; + case 0xd3:dyn_grp2_ev(grp2_cl);break; + //IN AL/AX,imm + case 0xe2:dyn_loop(LOOP_NONE);return decode.block; + case 0xe4:gen_call_function((void*)&IO_ReadB,"%Id%Rl",decode_fetchb(),DREG(EAX));break; + case 0xe5: + if (decode.big_op) { + gen_call_function((void*)&IO_ReadD,"%Id%Rd",decode_fetchb(),DREG(EAX)); + } else { + gen_call_function((void*)&IO_ReadW,"%Id%Rw",decode_fetchb(),DREG(EAX)); + } + break; + //OUT imm,AL + case 0xe6:gen_call_function((void*)&IO_WriteB,"%Id%Dl",decode_fetchb(),DREG(EAX));break; + case 0xe7: + if (decode.big_op) { + gen_call_function((void*)&IO_WriteD,"%Id%Dd",decode_fetchb(),DREG(EAX)); + } else { + gen_call_function((void*)&IO_WriteW,"%Id%Dw",decode_fetchb(),DREG(EAX)); + } + break; + case 0xe8: /* CALL Ivx */ + dyn_call_near_imm(); + return decode.block; + case 0xe9: /* Jmp Ivx */ + dyn_exit_link(decode.big_op,decode.big_op ? (Bit32s)decode_fetchd() : (Bit16s)decode_fetchw()); + return decode.block; + /* CALL FAR Ip */ + case 0xea:dyn_jmp_far_imm();return decode.block; + /* Jmp Ibx */ + case 0xeb:dyn_exit_link(decode.big_op,(Bit8s)decode_fetchb());return decode.block; + /* IN AL/AX,DX*/ + case 0xec:gen_call_function((void*)&IO_ReadB,"%Dw%Rl",DREG(EDX),DREG(EAX));break; + case 0xed: + if (decode.big_op) { + gen_call_function((void*)&IO_ReadD,"%Dw%Rd",DREG(EDX),DREG(EAX)); + } else { + gen_call_function((void*)&IO_ReadW,"%Dw%Rw",DREG(EDX),DREG(EAX)); + } + break; + /* OUT DX,AL/AX */ + case 0xee:gen_call_function((void*)&IO_WriteB,"%Dw%Dl",DREG(EDX),DREG(EAX));break; + case 0xef: + if (decode.big_op) { + gen_call_function((void*)&IO_WriteD,"%Dw%Dd",DREG(EDX),DREG(EAX)); + } else { + gen_call_function((void*)&IO_WriteW,"%Dw%Dw",DREG(EDX),DREG(EAX)); + } + break; + /* Change carry flag */ + case 0xf5: //CMC + case 0xf8: //CLC + case 0xf9: //STC + cache_addb(opcode);break; + /* GRP 3 Eb/EV */ + case 0xf6:dyn_grp3_eb();break; + case 0xf7:dyn_grp3_ev();break; + /* Change interrupt flag */ + case 0xfa: //CLI + gen_storeflags(); + gen_dop_word_imm(DOP_AND,true,DREG(FLAGS),~FLAG_IF); + gen_restoreflags(); + break; + case 0xfb: //STI + gen_storeflags(); + gen_dop_word_imm(DOP_OR,true,DREG(FLAGS),FLAG_IF); + gen_restoreflags(); + if (max_opcodes<=0) max_opcodes=1; //Allow 1 extra opcode + break; + /* GRP 4 Eb and callback's */ + case 0xfe: + dyn_get_modrm(); + switch (decode.modrm.reg) { + case 0x0://INC Eb + case 0x1://DEC Eb + if (decode.modrm.mod<3) { + dyn_fill_ea();dyn_read_byte(DREG(EA),DREG(TMPB),false); + gen_sop_byte(decode.modrm.reg==0 ? SOP_INC : SOP_DEC,DREG(TMPB),0); + dyn_write_byte(DREG(EA),DREG(TMPB),false); + gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB)); + } else { + gen_sop_byte(decode.modrm.reg==0 ? SOP_INC : SOP_DEC, + &DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); + } + break; + case 0x7: //CALBACK Iw + gen_save_host_direct(&core_dyn.callback,decode_fetchw()); + gen_lea(DREG(EIP),DREG(EIP),0,0,decode.code-decode.code_start); + dyn_reduce_cycles(); + dyn_releaseregs(); + gen_return(BR_CallBack); + dyn_closeblock(BT_Normal); + return decode.block; + } + break; + case 0xff: + { + dyn_get_modrm();DynReg * src; + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); + src=DREG(TMPW); + } else src=&DynRegs[decode.modrm.rm]; + switch (decode.modrm.reg) { + case 0x0://INC Ev + case 0x1://DEC Ev + gen_sop_word(decode.modrm.reg==0 ? SOP_INC : SOP_DEC,decode.big_op,src); + if (decode.modrm.mod<3){ + dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); + gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPW)); + } + break; + case 0x2: /* CALL Ev */ + gen_lea(DREG(EIP),DREG(EIP),0,0,decode.code-decode.code_start); + dyn_push(DREG(EIP)); + gen_dop_word(DOP_MOV,decode.big_op,DREG(EIP),src); + goto core_close_block; + case 0x4: /* JMP Ev */ + gen_dop_word(DOP_MOV,decode.big_op,DREG(EIP),src); + goto core_close_block; + case 0x3: /* CALL Ep */ + case 0x5: /* JMP Ep */ + dyn_save_flags(); + gen_lea(DREG(EA),DREG(EA),0,0,decode.big_op ? 4: 2); + gen_lea(DREG(EIP),DREG(EIP),0,0,decode.code-decode.code_start); + dyn_read_word(DREG(EA),DREG(EA),false); + for (Bitu i=0;i0xff) return 1; + return 0; +} + +static Bitu dyn_helper_idivb(Bit8s val) { + if (!val) return 1; + Bits quo=(Bit16s)reg_ax / val; + reg_ah=(Bit8s)((Bit16s)reg_ax % val); + reg_al=(Bit8s)quo; + if (quo!=(Bit8s)reg_al) return 1; + return 0; +} + +static Bitu dyn_helper_divw(Bit16u val) { + if (!val) return 1; + Bitu num=(reg_dx<<16)|reg_ax; + Bitu quo=num/val; + reg_dx=(Bit16u)(num % val); + reg_ax=(Bit16u)quo; + if (quo!=reg_ax) return 1; + return 0; +} + +static Bitu dyn_helper_idivw(Bit16s val) { + if (!val) return 1; + Bits num=(reg_dx<<16)|reg_ax; + Bits quo=num/val; + reg_dx=(Bit16s)(num % val); + reg_ax=(Bit16s)quo; + if (quo!=(Bit16s)reg_ax) return 1; + return 0; +} + +static Bitu dyn_helper_divd(Bit32u val) { + if (!val) return 1; + Bit64u num=(((Bit64u)reg_edx)<<32)|reg_eax; + Bit64u quo=num/val; + reg_edx=(Bit32u)(num % val); + reg_eax=(Bit32u)quo; + if (quo!=(Bit64u)reg_eax) return 1; + return 0; +} + +static Bitu dyn_helper_idivd(Bit32s val) { + if (!val) return 1; + Bit64s num=(((Bit64u)reg_edx)<<32)|reg_eax; + Bit64s quo=num/val; + reg_edx=(Bit32s)(num % val); + reg_eax=(Bit32s)(quo); + if (quo!=(Bit64s)((Bit32s)reg_eax)) return 1; + return 0; +} diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h new file mode 100644 index 00000000..8d149ba5 --- /dev/null +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -0,0 +1,719 @@ +#define GEN_HAS_IMM 1 + +static void gen_init(void); + +/* End of needed */ + +#define X86_REGS 7 +#define X86_REG_EAX 0x00 +#define X86_REG_ECX 0x01 +#define X86_REG_EDX 0x02 +#define X86_REG_EBX 0x03 +#define X86_REG_EBP 0x04 +#define X86_REG_ESI 0x05 +#define X86_REG_EDI 0x06 + +#define X86_REG_MASK(_REG_) (1 << X86_REG_ ## _REG_) + +static struct { + Bitu last_used; + Bitu stored_flags; + GenReg * regs[X86_REGS]; +} x86gen; + +class GenReg { +public: + GenReg(Bit8u _index,bool _protect) { + index=_index;protect=_protect; + notusable=false;dynreg=0; + } + DynReg * dynreg; + Bitu last_used; //Keeps track of last assigned regs + Bit8u index; + bool notusable; + bool protect; + void Load(DynReg * _dynreg) { + if (!_dynreg) return; + if (dynreg) Clear(); + dynreg=_dynreg; + last_used=x86gen.last_used; + dynreg->flags&=~DYNFLG_CHANGED; + dynreg->genreg=this; + if (dynreg->flags & (DYNFLG_LOAD|DYNFLG_LOADONCE)) { + dynreg->flags&=~DYNFLG_LOADONCE; + cache_addw(0x058b+(index << (8+3))); //Mov reg,[data] + cache_addd((Bit32u)dynreg->data); + } + } + void Save(void) { + if (!dynreg) IllegalOption(); + dynreg->flags&=~DYNFLG_CHANGED; + cache_addw(0x0589+(index << (8+3))); //Mov [data],reg + cache_addd((Bit32u)dynreg->data); + } + void Release(void) { + if (!dynreg) return; + if (dynreg->flags&DYNFLG_CHANGED && dynreg->flags&DYNFLG_SAVE) { + Save(); + } + dynreg->flags&=~(DYNFLG_CHANGED|DYNFLG_LOADONCE); + dynreg->genreg=0;dynreg=0; + } + void Clear(void) { + if (!dynreg) return; + if (dynreg->flags&DYNFLG_CHANGED) { + dynreg->flags|=DYNFLG_LOADONCE; + Save(); + } + dynreg->genreg=0;dynreg=0; + } + + +}; + +static Bit32u kut=10; +static BlockReturn gen_runcode(Bit8u * code) { + BlockReturn retval; + #define NEW_MASK $FMASK_TEST + __asm__ volatile ( + + "pushfl \n" + "movl %1,%%ebx \n" + "andl %2,%%ebx \n" + "popl %%ecx \n" + "andl %3,%%ecx \n" + "orl %%ebx,%%ecx \n" + "pushl %%ecx \n" + "popfl \n" + "call %4 \n" + "pushfl \n" + "movl %1,%%ebx \n" + "andl %3,%%ebx \n" + "popl %%ecx \n" + "andl %2,%%ecx \n" + "orl %%ecx,%%ebx \n" + "movl %%ebx,%1 \n" + :"=a" (retval) + :"m" (reg_flags), "n" (FMASK_TEST),"n" (~FMASK_TEST),"m" (code) + :"%ecx","%edx","%ebx","%ebp","%edi","%esi","cc","memory" + ); +#if 0 +/* Prepare the flags */ + pushfd + mov ebx,[reg_flags] + and ebx,FMASK_TEST + pop ecx + and ecx,~FMASK_TEST + or ecx,ebx + push ecx + popfd + call dword ptr [code]; +/* Restore the flags */ + pushfd + mov ebx,[reg_flags] + and ebx,~FMASK_TEST + pop ecx + and ecx,FMASK_TEST + or ebx,ecx + mov [reg_flags],ebx + pop edi + pop esi + pop ebp + pop ebx + mov [retval],eax + } +#endif + return retval; +} + + + + + + +static GenReg * FindDynReg(DynReg * dynreg) { + x86gen.last_used++; + if (dynreg->genreg) { + dynreg->genreg->last_used=x86gen.last_used; + return dynreg->genreg; + } + /* Find best match for selected global reg */ + Bits i; + Bits first_used,first_index; + first_used=-1; + if (dynreg->flags & DYNFLG_HAS8) { + /* Has to be eax,ebx,ecx,edx */ + for (i=first_index=0;i<=X86_REG_EDX;i++) { + GenReg * genreg=x86gen.regs[i]; + if (genreg->notusable) continue; + if (!(genreg->dynreg)) { + genreg->Load(dynreg); + return genreg; + } + if (genreg->last_usedlast_used; + first_index=i; + } + } + /* No free register found use earliest assigned one */ + GenReg * newreg=x86gen.regs[first_index]; + newreg->Load(dynreg); + return newreg; + } else { + for (i=first_index=X86_REGS-1;i>=0;i--) { + GenReg * genreg=x86gen.regs[i]; + if (genreg->notusable) continue; + if (!(genreg->dynreg)) { + genreg->Load(dynreg); + return genreg; + } + if (genreg->last_usedlast_used; + first_index=i; + } + } + /* No free register found use earliest assigned one */ + GenReg * newreg=x86gen.regs[first_index]; + newreg->Load(dynreg); + return newreg; + } +} + +static GenReg * ForceDynReg(GenReg * genreg,DynReg * dynreg) { + genreg->last_used=++x86gen.last_used; + if (dynreg->genreg==genreg) return genreg; + if (genreg->dynreg) genreg->Clear(); + if (dynreg->genreg) dynreg->genreg->Clear(); + genreg->Load(dynreg); + return genreg; +} +static void gen_releasereg(DynReg * dynreg) { + GenReg * genreg=dynreg->genreg; + if (genreg) genreg->Release(); + else dynreg->flags&=~(DYNFLG_LOADONCE|DYNFLG_CHANGED); +} + +static void gen_setupreg(DynReg * dnew,DynReg * dsetup) { + dnew->flags=dsetup->flags; + if (dnew->genreg==dsetup->genreg) return; + /* Not the same genreg must be wrong */ + if (dnew->genreg) { + /* Check if the genreg i'm changing is actually linked to me */ + if (dnew->genreg->dynreg==dnew) dnew->genreg->dynreg=0; + } + dnew->genreg=dsetup->genreg; + if (dnew->genreg) dnew->genreg->dynreg=dnew; +} + +static void gen_synchreg(DynReg * dnew,DynReg * dsynch) { + /* First make sure the registers match */ + if (dnew->genreg!=dsynch->genreg) { + if (dnew->genreg) dnew->genreg->Clear(); + if (dsynch->genreg) { + dsynch->genreg->Load(dnew); + } + } + /* Always use the loadonce flag from either state */ + dnew->flags|=(dsynch->flags & dnew->flags&DYNFLG_LOADONCE); + if ((dnew->flags ^ dsynch->flags) & DYNFLG_CHANGED) { + /* Ensure the changed value gets saved */ + if (dnew->flags & DYNFLG_CHANGED) { + dnew->genreg->Save(); + } + } +} + +static void gen_storeflags(void) { + if (!x86gen.stored_flags) { + cache_addb(0x9c); //PUSHFD + } + x86gen.stored_flags++; +} + +static void gen_restoreflags(bool noreduce=false) { + if (noreduce) { + cache_addb(0x9d); + return; + } + if (x86gen.stored_flags) { + x86gen.stored_flags--; + if (!x86gen.stored_flags) + cache_addb(0x9d); //POPFD + } else IllegalOption(); +} + +static void gen_reinit(void) { + x86gen.last_used=0; + x86gen.stored_flags=0; + for (Bitu i=0;idynreg=0; + } +} + +static void gen_dop_byte(DualOps op,DynReg * dr1,Bit8u di1,DynReg * dr2,Bit8u di2) { + GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2); + switch (op) { + case DOP_ADD:cache_addb(0x02);dr1->flags|=DYNFLG_CHANGED;break; + case DOP_OR: cache_addb(0x0a);dr1->flags|=DYNFLG_CHANGED;break; + case DOP_ADC:cache_addb(0x12);dr1->flags|=DYNFLG_CHANGED;break; + case DOP_SBB:cache_addb(0x1a);dr1->flags|=DYNFLG_CHANGED;break; + case DOP_AND:cache_addb(0x22);dr1->flags|=DYNFLG_CHANGED;break; + case DOP_SUB:cache_addb(0x2a);dr1->flags|=DYNFLG_CHANGED;break; + case DOP_XOR:cache_addb(0x32);dr1->flags|=DYNFLG_CHANGED;break; + case DOP_CMP:cache_addb(0x3a);break; + case DOP_MOV:cache_addb(0x8a);dr1->flags|=DYNFLG_CHANGED;break; + case DOP_XCHG:cache_addb(0x86);dr1->flags|=DYNFLG_CHANGED;dr2->flags|=DYNFLG_CHANGED;break; + case DOP_TEST:cache_addb(0x84);break; + default: + IllegalOption(); + } + cache_addb(0xc0+((gr1->index+di1)<<3)+gr2->index+di2); +} + +static void gen_dop_byte_imm(DualOps op,DynReg * dr1,Bit8u di1,Bitu imm) { + GenReg * gr1=FindDynReg(dr1); + switch (op) { + case DOP_ADD: + cache_addw(0xc080+((gr1->index+di1)<<8)); + dr1->flags|=DYNFLG_CHANGED; + break; + case DOP_OR: + cache_addw(0xc880+((gr1->index+di1)<<8)); + dr1->flags|=DYNFLG_CHANGED; + break; + case DOP_ADC: + cache_addw(0xd080+((gr1->index+di1)<<8)); + dr1->flags|=DYNFLG_CHANGED; + break; + case DOP_SBB: + cache_addw(0xd880+((gr1->index+di1)<<8)); + dr1->flags|=DYNFLG_CHANGED; + break; + case DOP_AND: + cache_addw(0xe080+((gr1->index+di1)<<8)); + dr1->flags|=DYNFLG_CHANGED; + break; + case DOP_SUB: + cache_addw(0xe880+((gr1->index+di1)<<8)); + dr1->flags|=DYNFLG_CHANGED; + break; + case DOP_XOR: + cache_addw(0xf080+((gr1->index+di1)<<8)); + dr1->flags|=DYNFLG_CHANGED; + break; + case DOP_CMP: + cache_addw(0xf880+((gr1->index+di1)<<8)); + break;//Doesn't change + case DOP_MOV: + cache_addb(0xb0+gr1->index+di1); + dr1->flags|=DYNFLG_CHANGED; + break; + case DOP_TEST: + cache_addw(0xc0f6+((gr1->index+di1)<<8)); + break;//Doesn't change + default: + IllegalOption(); + } + cache_addb(imm); +} + +static void gen_sop_byte(SingleOps op,DynReg * dr1,Bit8u di1) { + GenReg * gr1=FindDynReg(dr1); + switch (op) { + case SOP_INC:cache_addw(0xc0FE + ((gr1->index+di1)<<8));break; + case SOP_DEC:cache_addw(0xc8FE + ((gr1->index+di1)<<8));break; + case SOP_NOT:cache_addw(0xd0f6 + ((gr1->index+di1)<<8));break; + case SOP_NEG:cache_addw(0xd8f6 + ((gr1->index+di1)<<8));break; + default: + IllegalOption(); + } + dr1->flags|=DYNFLG_CHANGED; +} + + +static void gen_extend_word(bool sign,DynReg * ddr,DynReg * dsr) { + GenReg * gdr=FindDynReg(ddr);GenReg * gsr=FindDynReg(dsr); + if (sign) cache_addw(0xbf0f); + else cache_addw(0xb70f); + cache_addb(0xc0+(gdr->index<<3)+(gsr->index)); + ddr->flags|=DYNFLG_CHANGED; +} + +static void gen_extend_byte(bool sign,bool dword,DynReg * ddr,DynReg * dsr,Bit8u dsi) { + GenReg * gdr=FindDynReg(ddr);GenReg * gsr=FindDynReg(dsr); + if (!dword) cache_addb(0x66); + if (sign) cache_addw(0xbe0f); + else cache_addw(0xb60f); + cache_addb(0xc0+(gdr->index<<3)+(gsr->index+dsi)); + ddr->flags|=DYNFLG_CHANGED; +} + +static void gen_lea(DynReg * ddr,DynReg * dsr1,DynReg * dsr2,Bitu scale,Bits imm) { + GenReg * gdr=FindDynReg(ddr); + Bitu imm_size; + Bit8u rm_base=(gdr->index << 3); + if (dsr1) { + GenReg * gsr1=FindDynReg(dsr1); + if (!imm && (gsr1->index!=0x5)) { + imm_size=0; rm_base+=0x0; //no imm + } else if ((imm>=-128 && imm<=127)) { + imm_size=1;rm_base+=0x40; //Signed byte imm + } else { + imm_size=4;rm_base+=0x80; //Signed dword imm + } + if (dsr2) { + GenReg * gsr2=FindDynReg(dsr2); + cache_addb(0x8d); //LEA + cache_addb(rm_base+0x4); //The sib indicator + Bit8u sib=(gsr1->index)+(gsr2->index<<3)+(scale<<6); + cache_addb(sib); + } else { + cache_addb(0x8d); //LEA + cache_addb(rm_base+gsr1->index); + } + } else { + if (dsr2) { + GenReg * gsr2=FindDynReg(dsr2); + cache_addb(0x8d); //LEA + cache_addb(rm_base+0x4); //The sib indicator + Bit8u sib=(5+(gsr2->index<<3)+(scale<<6)); + cache_addb(sib); + imm_size=4; + } else { + cache_addb(0x8d); //LEA + cache_addb(rm_base+0x05); //dword imm + imm_size=4; + } + } + switch (imm_size) { + case 0: break; + case 1:cache_addb(imm);break; + case 4:cache_addd(imm);break; + } + ddr->flags|=DYNFLG_CHANGED; +} + +static void gen_dop_word(DualOps op,bool dword,DynReg * dr1,DynReg * dr2) { + GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2); + if (!dword) cache_addb(0x66); + switch (op) { + case DOP_ADD:cache_addb(0x03);dr1->flags|=DYNFLG_CHANGED;break; + case DOP_OR: cache_addb(0x0b);dr1->flags|=DYNFLG_CHANGED;break; + case DOP_ADC:cache_addb(0x13);dr1->flags|=DYNFLG_CHANGED;break; + case DOP_SBB:cache_addb(0x1b);dr1->flags|=DYNFLG_CHANGED;break; + case DOP_AND:cache_addb(0x23);dr1->flags|=DYNFLG_CHANGED;break; + case DOP_SUB:cache_addb(0x2b);dr1->flags|=DYNFLG_CHANGED;break; + case DOP_XOR:cache_addb(0x33);dr1->flags|=DYNFLG_CHANGED;break; + case DOP_CMP:cache_addb(0x3b);break; + case DOP_MOV:cache_addb(0x8b);dr1->flags|=DYNFLG_CHANGED;break; + case DOP_XCHG:cache_addb(0x87);dr1->flags|=DYNFLG_CHANGED;dr2->flags|=DYNFLG_CHANGED;break; + case DOP_TEST:cache_addb(0x85);break; + default: + IllegalOption(); + } + cache_addb(0xc0+(gr1->index<<3)+gr2->index); +} + +static void gen_dop_word_imm(DualOps op,bool dword,DynReg * dr1,Bits imm) { + GenReg * gr1=FindDynReg(dr1); + if (!dword) cache_addb(0x66); + switch (op) { + case DOP_ADD:cache_addw(0xc081+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break; + case DOP_OR: cache_addw(0xc881+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break; + case DOP_ADC:cache_addw(0xd081+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break; + case DOP_SBB:cache_addw(0xd881+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break; + case DOP_AND:cache_addw(0xe081+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break; + case DOP_SUB:cache_addw(0xe881+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break; + case DOP_XOR:cache_addw(0xf081+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break; + case DOP_CMP:cache_addw(0xf881+(gr1->index<<8));break;//Doesn't change + case DOP_MOV:cache_addb(0xb8+(gr1->index));dr1->flags|=DYNFLG_CHANGED;break; + case DOP_TEST:cache_addw(0xc0f7+(gr1->index<<8));break;//Doesn't change + default: + IllegalOption(); + } + if (dword) cache_addd(imm); + else cache_addw(imm); +} +static void gen_sop_word(SingleOps op,bool dword,DynReg * dr1) { + GenReg * gr1=FindDynReg(dr1); + if (!dword) cache_addb(0x66); + switch (op) { + case SOP_INC:cache_addb(0x40+gr1->index);break; + case SOP_DEC:cache_addb(0x48+gr1->index);break; + case SOP_NOT:cache_addw(0xd0f7+(gr1->index<<8));break; + case SOP_NEG:cache_addw(0xd8f7+(gr1->index<<8));break; + default: + IllegalOption(); + } + dr1->flags|=DYNFLG_CHANGED; +} + +static void gen_shift_byte(ShiftOps op,DynReg * drecx,DynReg * dr1,Bit8u di1) { + ForceDynReg(x86gen.regs[X86_REG_ECX],drecx); + GenReg * gr1=FindDynReg(dr1); + switch (op) { + case SHIFT_ROL:cache_addw(0xc0d2+((gr1->index+di1)<<8));break; + case SHIFT_ROR:cache_addw(0xc8d2+((gr1->index+di1)<<8));break; + case SHIFT_RCL:cache_addw(0xd0d2+((gr1->index+di1)<<8));break; + case SHIFT_RCR:cache_addw(0xd8d2+((gr1->index+di1)<<8));break; + case SHIFT_SHL:cache_addw(0xe0d2+((gr1->index+di1)<<8));break; + case SHIFT_SHR:cache_addw(0xe8d2+((gr1->index+di1)<<8));break; + case SHIFT_SAR:cache_addw(0xf8d2+((gr1->index+di1)<<8));break; + default: + IllegalOption(); + } + dr1->flags|=DYNFLG_CHANGED; +} + +static void gen_shift_word(ShiftOps op,DynReg * drecx,bool dword,DynReg * dr1) { + ForceDynReg(x86gen.regs[X86_REG_ECX],drecx); + GenReg * gr1=FindDynReg(dr1); + if (!dword) cache_addb(0x66); + switch (op) { + case SHIFT_ROL:cache_addw(0xc0d3+((gr1->index)<<8));break; + case SHIFT_ROR:cache_addw(0xc8d3+((gr1->index)<<8));break; + case SHIFT_RCL:cache_addw(0xd0d3+((gr1->index)<<8));break; + case SHIFT_RCR:cache_addw(0xd8d3+((gr1->index)<<8));break; + case SHIFT_SHL:cache_addw(0xe0d3+((gr1->index)<<8));break; + case SHIFT_SHR:cache_addw(0xe8d3+((gr1->index)<<8));break; + case SHIFT_SAR:cache_addw(0xf8d3+((gr1->index)<<8));break; + default: + IllegalOption(); + } + dr1->flags|=DYNFLG_CHANGED; +} + + +static void gen_mul_byte(bool imul,DynReg * dyn_ax,DynReg * dr1,Bit8u di1) { + ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax); + GenReg * gr1=FindDynReg(dr1); + if (imul) cache_addw(0xe8f6+((gr1->index+di1)<<8)); + else cache_addw(0xe0f6+((gr1->index+di1)<<8)); + dyn_ax->flags|=DYNFLG_CHANGED; +} + +static void gen_mul_word(bool imul,DynReg * dyn_ax,DynReg * dyn_dx,bool dword,DynReg * dr1) { + ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax); + ForceDynReg(x86gen.regs[X86_REG_EDX],dyn_dx); + GenReg * gr1=FindDynReg(dr1); + if (!dword) cache_addb(0x66); + if (imul) cache_addw(0xe8f7+(gr1->index<<8)); + else cache_addw(0xe0f7+(gr1->index<<8)); + dyn_ax->flags|=DYNFLG_CHANGED; + dyn_dx->flags|=DYNFLG_CHANGED; +} + +static void gen_dshift_imm(bool dword,bool left,DynReg * dr1,DynReg * dr2,Bitu imm) { + GenReg * gr1=FindDynReg(dr1); + GenReg * gr2=FindDynReg(dr2); + if (!dword) cache_addb(0x66); + if (left) cache_addw(0xa40f); //SHLD IMM + else cache_addw(0xac0f); //SHRD IMM + cache_addb(0xc0+gr1->index+(gr2->index<<8)); + cache_addb(imm); + dr1->flags|=DYNFLG_CHANGED; +} + +static void gen_dshift_cl(bool dword,bool left,DynReg * dr1,DynReg * dr2,DynReg * drecx) { + GenReg * gr1=FindDynReg(dr1); + GenReg * gr2=FindDynReg(dr2); + ForceDynReg(x86gen.regs[X86_REG_ECX],drecx); + if (!dword) cache_addb(0x66); + if (left) cache_addw(0xa50f); //SHLD CL + else cache_addw(0xad0f); //SHRD CL + cache_addb(0xc0+gr1->index+(gr2->index<<8)); + dr1->flags|=DYNFLG_CHANGED; +} + +static void gen_call_function(void * func,char * ops,...) { + Bits paramcount=0; + struct ParamInfo { + char * line; + Bitu value; + } pinfo[32]; + ParamInfo * retparam=0; + /* Clear the EAX Genreg for usage */ + x86gen.regs[X86_REG_EAX]->Clear(); + x86gen.regs[X86_REG_EAX]->notusable=true;; + /* Save the flags */ + gen_storeflags(); + /* Scan for the amount of params */ + if (ops) { + va_list params; + va_start(params,ops); + Bits pindex=0; + while (*ops) { + if (*ops=='%') { + pinfo[pindex].line=ops+1; + pinfo[pindex].value=va_arg(params,Bitu); + pindex++; + } + ops++; + } + paramcount=0; + while (pindex) { + pindex--; + char * scan=pinfo[pindex].line; + switch (*scan++) { + case 'I': /* immediate value */ + paramcount++; + cache_addb(0x68); //Push immediate + cache_addd(pinfo[pindex].value); //Push value + break; + case 'D': /* Dynamic register */ + { + bool release=false; + paramcount++; + DynReg * dynreg=(DynReg *)pinfo[pindex].value; + GenReg * genreg=FindDynReg(dynreg); + scanagain: + switch (*scan++) { + case 'd': + cache_addb(0x50+genreg->index); //Push reg + break; + case 'w': + cache_addw(0xb70f); //MOVZX EAX,reg + cache_addb(0xc0+genreg->index); + cache_addb(0x50); //Push EAX + break; + case 'l': + cache_addw(0xb60f); //MOVZX EAX,reg[0] + cache_addb(0xc0+genreg->index); + cache_addb(0x50); //Push EAX + break; + case 'h': + cache_addw(0xb60f); //MOVZX EAX,reg[1] + cache_addb(0xc4+genreg->index); + cache_addb(0x50); //Push EAX + break; + case 'r': /* release the reg afterwards */ + release=true; + goto scanagain; + default: + IllegalOption(); + } + if (release) gen_releasereg(dynreg); + } + break; + case 'R': /* Dynamic register to get the return value */ + retparam =&pinfo[pindex]; + pinfo[pindex].line=scan; + break; + default: + IllegalOption(); + } + } + } + /* Clear some unprotected registers */ + x86gen.regs[X86_REG_ECX]->Clear(); + x86gen.regs[X86_REG_EDX]->Clear(); + /* Do the actual call to the procedure */ + cache_addb(0xe8); + cache_addd((Bit32u)func - (Bit32u)cache.pos-4); + /* Restore the params of the stack */ + if (paramcount) { + cache_addw(0xc483); //add ESP,imm byte + cache_addb(paramcount*4); + } + /* Save the return value in correct register */ + if (retparam) { + DynReg * dynreg=(DynReg *)retparam->value; + GenReg * genreg=FindDynReg(dynreg); + switch (*retparam->line) { + case 'd': + cache_addw(0xc08b+(genreg->index <<(8+3))); //mov reg,eax + break; + case 'w': + cache_addb(0x66); + cache_addw(0xc08b+(genreg->index <<(8+3))); //mov reg,eax + break; + case 'l': + cache_addw(0xc08a+(genreg->index <<(8+3))); //mov reg,eax + break; + case 'h': + cache_addw(0xc08a+((genreg->index+4) <<(8+3))); //mov reg,eax + break; + } + dynreg->flags|=DYNFLG_CHANGED; + } + gen_restoreflags(); + /* Restore EAX registers to be used again */ + x86gen.regs[X86_REG_EAX]->notusable=false; +} + +static Bit8u * gen_create_branch(BranchTypes type) { + /* First free all registers */ + cache_addb(0x70+type); + cache_addb(0); + return (cache.pos-1); +} + +static void gen_fill_branch(Bit8u * data) { + *data=(cache.pos-data-1); +} + +static void gen_jmp_ptr(void * ptr,Bits imm=0) { + cache_addb(0xa1); + cache_addd((Bit32u)ptr); + cache_addb(0xff); //JMP EA + if (!imm) { //NO EBP + cache_addb(0x20); + } else if ((imm>=-128 && imm<=127)) { + cache_addb(0x60); + cache_addb(imm); + } else { + cache_addb(0xa0); + cache_addd(imm); + } +} + +static void gen_save_flags(DynReg * dynreg,bool stored) { + GenReg * genreg=FindDynReg(dynreg); + if (!stored) cache_addb(0x9c); //Pushfd + cache_addb(0x58+genreg->index); //POP 32 REG + dynreg->flags|=DYNFLG_CHANGED; +} + +static void gen_load_flags(DynReg * dynreg) { + GenReg * genreg=FindDynReg(dynreg); + cache_addb(0x50+genreg->index); //PUSH 32 + cache_addb(0x9d); //POPFD +} + +static void gen_save_host_direct(void * data,Bits imm) { + cache_addw(0x05c7); //MOV [],dword + cache_addd((Bit32u)data); + cache_addd(imm); +} + +static void gen_load_host(void * data,DynReg * dr1,Bitu size) { + GenReg * gr1=FindDynReg(dr1); + switch (size) { + case 1:cache_addw(0xb60f);break; //movzx byte + case 2:cache_addw(0xb70f);break; //movzx word + case 4:cache_addb(0x8b);break; //mov + default: + IllegalOption(); + } + cache_addb(0x5+(gr1->index<<3)); + cache_addd((Bit32u)data); + dr1->flags|=DYNFLG_CHANGED; +} + +static void gen_return(BlockReturn retcode) { + cache_addb(0xb8); + cache_addd(retcode); + cache_addb(0xc3); +} + +static void gen_init(void) { + x86gen.regs[X86_REG_EAX]=new GenReg(0,false); + x86gen.regs[X86_REG_ECX]=new GenReg(1,false); + x86gen.regs[X86_REG_EDX]=new GenReg(2,false); + x86gen.regs[X86_REG_EBX]=new GenReg(3,true); + x86gen.regs[X86_REG_EBP]=new GenReg(5,true); + x86gen.regs[X86_REG_ESI]=new GenReg(6,true); + x86gen.regs[X86_REG_EDI]=new GenReg(7,true); +} + + diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h new file mode 100644 index 00000000..e69de29b From bd8196414c3642bb770f55aa4141dc6d2f12cf35 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 1 Jan 2004 12:39:53 +0000 Subject: [PATCH 1435/4131] Fix for visual c startup assembly code Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1516 --- src/cpu/core_dyn_x86/risc_x86.h | 52 ++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 8d149ba5..6f482fcb 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -74,31 +74,13 @@ public: static Bit32u kut=10; static BlockReturn gen_runcode(Bit8u * code) { BlockReturn retval; - #define NEW_MASK $FMASK_TEST - __asm__ volatile ( - - "pushfl \n" - "movl %1,%%ebx \n" - "andl %2,%%ebx \n" - "popl %%ecx \n" - "andl %3,%%ecx \n" - "orl %%ebx,%%ecx \n" - "pushl %%ecx \n" - "popfl \n" - "call %4 \n" - "pushfl \n" - "movl %1,%%ebx \n" - "andl %3,%%ebx \n" - "popl %%ecx \n" - "andl %2,%%ecx \n" - "orl %%ecx,%%ebx \n" - "movl %%ebx,%1 \n" - :"=a" (retval) - :"m" (reg_flags), "n" (FMASK_TEST),"n" (~FMASK_TEST),"m" (code) - :"%ecx","%edx","%ebx","%ebp","%edi","%esi","cc","memory" - ); -#if 0 +#if defined (_MSC_VER) + __asm { /* Prepare the flags */ + push ebx + push ebp + push esi + push edi pushfd mov ebx,[reg_flags] and ebx,FMASK_TEST @@ -122,6 +104,28 @@ static BlockReturn gen_runcode(Bit8u * code) { pop ebx mov [retval],eax } +#else + __asm__ volatile ( + "pushfl \n" + "movl %1,%%ebx \n" + "andl %2,%%ebx \n" + "popl %%ecx \n" + "andl %3,%%ecx \n" + "orl %%ebx,%%ecx \n" + "pushl %%ecx \n" + "popfl \n" + "call %4 \n" + "pushfl \n" + "movl %1,%%ebx \n" + "andl %3,%%ebx \n" + "popl %%ecx \n" + "andl %2,%%ecx \n" + "orl %%ecx,%%ebx \n" + "movl %%ebx,%1 \n" + :"=a" (retval) + :"m" (reg_flags), "n" (FMASK_TEST),"n" (~FMASK_TEST),"m" (code) + :"%ecx","%edx","%ebx","%ebp","%edi","%esi","cc","memory" + ); #endif return retval; } From a6dfd08d163bb31944c43325b5b9b62379800212 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 1 Jan 2004 13:53:48 +0000 Subject: [PATCH 1436/4131] Add visual c.net solution and project Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1517 --- configure.in | 1 + visualc_net/Makefile.am | 1 + visualc_net/dosbox.sln | 21 ++ visualc_net/dosbox.vcproj | 739 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 762 insertions(+) create mode 100644 visualc_net/Makefile.am create mode 100644 visualc_net/dosbox.sln create mode 100644 visualc_net/dosbox.vcproj diff --git a/configure.in b/configure.in index 9c28ec81..1a2758f5 100644 --- a/configure.in +++ b/configure.in @@ -186,6 +186,7 @@ src/shell/Makefile src/platform/Makefile src/platform/visualc/Makefile visualc/Makefile +visualc_net/Makefile include/Makefile docs/Makefile ]) diff --git a/visualc_net/Makefile.am b/visualc_net/Makefile.am new file mode 100644 index 00000000..6d1c6dd6 --- /dev/null +++ b/visualc_net/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST = dosbox.sln dosbox.vcproj \ No newline at end of file diff --git a/visualc_net/dosbox.sln b/visualc_net/dosbox.sln new file mode 100644 index 00000000..5f2be4c3 --- /dev/null +++ b/visualc_net/dosbox.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dosbox", "dosbox.vcproj", "{7FCFFB9B-8629-4D51-849C-8490CECF8AB7}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {7FCFFB9B-8629-4D51-849C-8490CECF8AB7}.Debug.ActiveCfg = Debug|Win32 + {7FCFFB9B-8629-4D51-849C-8490CECF8AB7}.Debug.Build.0 = Debug|Win32 + {7FCFFB9B-8629-4D51-849C-8490CECF8AB7}.Release.ActiveCfg = Release|Win32 + {7FCFFB9B-8629-4D51-849C-8490CECF8AB7}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj new file mode 100644 index 00000000..de9ee920 --- /dev/null +++ b/visualc_net/dosbox.vcproj @@ -0,0 +1,739 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From ce71f7d35a529b4e91b32974a63767d19af42f41 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 1 Jan 2004 16:48:36 +0000 Subject: [PATCH 1437/4131] Only use #pragma's in visual c Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1518 --- include/cpu.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/cpu.h b/include/cpu.h index 50025ab5..9b265197 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -146,6 +146,10 @@ void CPU_SetFlags(Bitu word,Bitu mask); #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; @@ -239,8 +243,9 @@ struct TSS_32 { Bit32u ldt; /* The local descriptor table */ } GCC_ATTRIBUTE(packed); +#ifdef _MSC_VER #pragma pack() - +#endif class Descriptor { public: From 00e6d3c31d1a221d027db8465d5db0ed21a04876 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 1 Jan 2004 20:33:22 +0000 Subject: [PATCH 1438/4131] No longer directly stack variables in assembly Changed initial flag loading Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1519 --- src/cpu/core_dyn_x86/risc_x86.h | 34 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 6f482fcb..b04866ae 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -71,7 +71,6 @@ public: }; -static Bit32u kut=10; static BlockReturn gen_runcode(Bit8u * code) { BlockReturn retval; #if defined (_MSC_VER) @@ -106,35 +105,26 @@ static BlockReturn gen_runcode(Bit8u * code) { } #else __asm__ volatile ( - "pushfl \n" - "movl %1,%%ebx \n" - "andl %2,%%ebx \n" - "popl %%ecx \n" - "andl %3,%%ecx \n" - "orl %%ebx,%%ecx \n" - "pushl %%ecx \n" + "movl %1,%%esi \n" + "andl %2,%%esi \n" + "pushl %%ebp \n" + "pushl %%esi \n" "popfl \n" - "call %4 \n" + "calll %4 \n" + "popl %%ebp \n" "pushfl \n" - "movl %1,%%ebx \n" - "andl %3,%%ebx \n" - "popl %%ecx \n" - "andl %2,%%ecx \n" - "orl %%ecx,%%ebx \n" - "movl %%ebx,%1 \n" + "andl %3,(%1) \n" + "popl %%esi \n" + "andl %2,%%esi \n" + "orl %%esi,(%1) \n" :"=a" (retval) - :"m" (reg_flags), "n" (FMASK_TEST),"n" (~FMASK_TEST),"m" (code) - :"%ecx","%edx","%ebx","%ebp","%edi","%esi","cc","memory" + :"m" (reg_flags), "n" (FMASK_TEST),"n" (~FMASK_TEST),"r" (code) + :"%ecx","%edx","%ebx","%edi","%esi","cc","memory" ); #endif return retval; } - - - - - static GenReg * FindDynReg(DynReg * dynreg) { x86gen.last_used++; if (dynreg->genreg) { From 1ac82ec8348f2a64ee4976ab6a0d94aaaea60f49 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 1 Jan 2004 20:35:44 +0000 Subject: [PATCH 1439/4131] Changed #include filename slashes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1520 --- src/cpu/core_dyn_x86.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 2d551f0a..7b27ffe2 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -141,7 +141,7 @@ static void IllegalOption(void) { E_Exit("Illegal option"); } -#include "core_dyn_x86\cache.h" +#include "core_dyn_x86/cache.h" static struct { Bitu callback; @@ -149,7 +149,7 @@ static struct { } core_dyn; -#include "core_dyn_x86\risc_x86.h" +#include "core_dyn_x86/risc_x86.h" struct DynState { DynReg regs[G_MAX]; @@ -196,7 +196,7 @@ static void dyn_synchstate(DynState * state) { gen_synchreg(&DynRegs[i],&state->regs[i]); } } -#include "core_dyn_x86\decoder.h" +#include "core_dyn_x86/decoder.h" Bits CPU_Core_Dyn_X86_Run(void) { /* Determine the linear address of CS:EIP */ From ce2a446de9fab95ab93519078412ac27ed3e21e5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 1 Jan 2004 20:44:09 +0000 Subject: [PATCH 1440/4131] Removed last remaining fastcall functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1521 --- src/cpu/core_dyn_x86/decoder.h | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 8326d252..82e8bf1c 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -16,18 +16,16 @@ static struct DynDecode { DynReg * segprefix; } decode; -#define FASTCALL __fastcall - #include "helpers.h" -static Bit8u FASTCALL decode_fetchb(void) { +static Bit8u INLINE decode_fetchb(void) { return mem_readb(decode.code++); } -static Bit16u FASTCALL decode_fetchw(void) { +static Bit16u INLINE decode_fetchw(void) { decode.code+=2; return mem_readw(decode.code-2); } -static Bit32u FASTCALL decode_fetchd(void) { +static Bit32u INLINE decode_fetchd(void) { decode.code+=4; return mem_readd(decode.code-4); } @@ -98,14 +96,14 @@ static void dyn_pop(DynReg * dynreg) { gen_restoreflags(); } -static void FASTCALL dyn_get_modrm(void) { +static void INLINE dyn_get_modrm(void) { decode.modrm.val=decode_fetchb(); decode.modrm.mod=(decode.modrm.val >> 6) & 3; decode.modrm.reg=(decode.modrm.val >> 3) & 7; decode.modrm.rm=(decode.modrm.val & 7); } -static void FASTCALL dyn_fill_ea(bool addseg=true) { +static void dyn_fill_ea(bool addseg=true) { DynReg * segbase; if (!decode.big_addr) { Bits imm; From 68c7731c911eac5388a44e28db29719d849eea20 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 Jan 2004 14:34:48 +0000 Subject: [PATCH 1441/4131] Replaced it with the one from Bochs Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1522 --- src/dos/scsidefs.h | 867 +++++++++++++++------------------------------ 1 file changed, 288 insertions(+), 579 deletions(-) diff --git a/src/dos/scsidefs.h b/src/dos/scsidefs.h index 7db5c9e6..3b02c274 100644 --- a/src/dos/scsidefs.h +++ b/src/dos/scsidefs.h @@ -1,579 +1,288 @@ -//*************************************************************************** -// -// Name: SCSIDEFS.H -// -// Description: SCSI definitions ('C' Language) -// -//*************************************************************************** - -//*************************************************************************** -// %%% TARGET STATUS VALUES %%% -//*************************************************************************** -#define STATUS_GOOD 0x00 // Status Good -#define STATUS_CHKCOND 0x02 // Check Condition -#define STATUS_CONDMET 0x04 // Condition Met -#define STATUS_BUSY 0x08 // Busy -#define STATUS_INTERM 0x10 // Intermediate -#define STATUS_INTCDMET 0x14 // Intermediate-condition met -#define STATUS_RESCONF 0x18 // Reservation conflict -#define STATUS_COMTERM 0x22 // Command Terminated -#define STATUS_QFULL 0x28 // Queue full - -//*************************************************************************** -// %%% SCSI MISCELLANEOUS EQUATES %%% -//*************************************************************************** -#define MAXLUN 7 // Maximum Logical Unit Id -#define MAXTARG 7 // Maximum Target Id -#define MAX_SCSI_LUNS 64 // Maximum Number of SCSI LUNs -#define MAX_NUM_HA 8 // Maximum Number of SCSI HA's - -//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ -// -// %%% SCSI COMMAND OPCODES %%% -// -///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ - -//*************************************************************************** -// %%% Commands for all Device Types %%% -//*************************************************************************** -#define SCSI_CHANGE_DEF 0x40 // Change Definition (Optional) -#define SCSI_COMPARE 0x39 // Compare (O) -#define SCSI_COPY 0x18 // Copy (O) -#define SCSI_COP_VERIFY 0x3A // Copy and Verify (O) -#define SCSI_INQUIRY 0x12 // Inquiry (MANDATORY) -#define SCSI_LOG_SELECT 0x4C // Log Select (O) -#define SCSI_LOG_SENSE 0x4D // Log Sense (O) -#define SCSI_MODE_SEL6 0x15 // Mode Select 6-byte (Device Specific) -#define SCSI_MODE_SEL10 0x55 // Mode Select 10-byte (Device Specific) -#define SCSI_MODE_SEN6 0x1A // Mode Sense 6-byte (Device Specific) -#define SCSI_MODE_SEN10 0x5A // Mode Sense 10-byte (Device Specific) -#define SCSI_READ_BUFF 0x3C // Read Buffer (O) -#define SCSI_REQ_SENSE 0x03 // Request Sense (MANDATORY) -#define SCSI_SEND_DIAG 0x1D // Send Diagnostic (O) -#define SCSI_TST_U_RDY 0x00 // Test Unit Ready (MANDATORY) -#define SCSI_WRITE_BUFF 0x3B // Write Buffer (O) - -//*************************************************************************** -// %%% Commands Unique to Direct Access Devices %%% -//*************************************************************************** -#define SCSI_COMPARE 0x39 // Compare (O) -#define SCSI_FORMAT 0x04 // Format Unit (MANDATORY) -#define SCSI_LCK_UN_CAC 0x36 // Lock Unlock Cache (O) -#define SCSI_PREFETCH 0x34 // Prefetch (O) -#define SCSI_MED_REMOVL 0x1E // Prevent/Allow medium Removal (O) -#define SCSI_READ6 0x08 // Read 6-byte (MANDATORY) -#define SCSI_READ10 0x28 // Read 10-byte (MANDATORY) -#define SCSI_RD_CAPAC 0x25 // Read Capacity (MANDATORY) -#define SCSI_RD_DEFECT 0x37 // Read Defect Data (O) -#define SCSI_READ_LONG 0x3E // Read Long (O) -#define SCSI_REASS_BLK 0x07 // Reassign Blocks (O) -#define SCSI_RCV_DIAG 0x1C // Receive Diagnostic Results (O) -#define SCSI_RELEASE 0x17 // Release Unit (MANDATORY) -#define SCSI_REZERO 0x01 // Rezero Unit (O) -#define SCSI_SRCH_DAT_E 0x31 // Search Data Equal (O) -#define SCSI_SRCH_DAT_H 0x30 // Search Data High (O) -#define SCSI_SRCH_DAT_L 0x32 // Search Data Low (O) -#define SCSI_SEEK6 0x0B // Seek 6-Byte (O) -#define SCSI_SEEK10 0x2B // Seek 10-Byte (O) -#define SCSI_SEND_DIAG 0x1D // Send Diagnostics (MANDATORY) -#define SCSI_SET_LIMIT 0x33 // Set Limits (O) -#define SCSI_START_STP 0x1B // Start/Stop Unit (O) -#define SCSI_SYNC_CACHE 0x35 // Synchronize Cache (O) -#define SCSI_VERIFY 0x2F // Verify (O) -#define SCSI_WRITE6 0x0A // Write 6-Byte (MANDATORY) -#define SCSI_WRITE10 0x2A // Write 10-Byte (MANDATORY) -#define SCSI_WRT_VERIFY 0x2E // Write and Verify (O) -#define SCSI_WRITE_LONG 0x3F // Write Long (O) -#define SCSI_WRITE_SAME 0x41 // Write Same (O) - -//*************************************************************************** -// %%% Commands Unique to Sequential Access Devices %%% -//*************************************************************************** -#define SCSI_ERASE 0x19 // Erase (MANDATORY) -#define SCSI_LOAD_UN 0x1B // Load/Unload (O) -#define SCSI_LOCATE 0x2B // Locate (O) -#define SCSI_RD_BLK_LIM 0x05 // Read Block Limits (MANDATORY) -#define SCSI_READ_POS 0x34 // Read Position (O) -#define SCSI_READ_REV 0x0F // Read Reverse (O) -#define SCSI_REC_BF_DAT 0x14 // Recover Buffer Data (O) -#define SCSI_RESERVE 0x16 // Reserve Unit (MANDATORY) -#define SCSI_REWIND 0x01 // Rewind (MANDATORY) -#define SCSI_SPACE 0x11 // Space (MANDATORY) -#define SCSI_VERIFY_T 0x13 // Verify (Tape) (O) -#define SCSI_WRT_FILE 0x10 // Write Filemarks (MANDATORY) - -//*************************************************************************** -// %%% Commands Unique to Printer Devices %%% -//*************************************************************************** -#define SCSI_PRINT 0x0A // Print (MANDATORY) -#define SCSI_SLEW_PNT 0x0B // Slew and Print (O) -#define SCSI_STOP_PNT 0x1B // Stop Print (O) -#define SCSI_SYNC_BUFF 0x10 // Synchronize Buffer (O) - -//*************************************************************************** -// %%% Commands Unique to Processor Devices %%% -//*************************************************************************** -#define SCSI_RECEIVE 0x08 // Receive (O) -#define SCSI_SEND 0x0A // Send (O) - -//*************************************************************************** -// %%% Commands Unique to Write-Once Devices %%% -//*************************************************************************** -#define SCSI_MEDIUM_SCN 0x38 // Medium Scan (O) -#define SCSI_SRCHDATE10 0x31 // Search Data Equal 10-Byte (O) -#define SCSI_SRCHDATE12 0xB1 // Search Data Equal 12-Byte (O) -#define SCSI_SRCHDATH10 0x30 // Search Data High 10-Byte (O) -#define SCSI_SRCHDATH12 0xB0 // Search Data High 12-Byte (O) -#define SCSI_SRCHDATL10 0x32 // Search Data Low 10-Byte (O) -#define SCSI_SRCHDATL12 0xB2 // Search Data Low 12-Byte (O) -#define SCSI_SET_LIM_10 0x33 // Set Limits 10-Byte (O) -#define SCSI_SET_LIM_12 0xB3 // Set Limits 10-Byte (O) -#define SCSI_VERIFY10 0x2F // Verify 10-Byte (O) -#define SCSI_VERIFY12 0xAF // Verify 12-Byte (O) -#define SCSI_WRITE12 0xAA // Write 12-Byte (O) -#define SCSI_WRT_VER10 0x2E // Write and Verify 10-Byte (O) -#define SCSI_WRT_VER12 0xAE // Write and Verify 12-Byte (O) - -//*************************************************************************** -// %%% Commands Unique to CD-ROM Devices %%% -//*************************************************************************** -#define SCSI_PLAYAUD_10 0x45 // Play Audio 10-Byte (O) -#define SCSI_PLAYAUD_12 0xA5 // Play Audio 12-Byte 12-Byte (O) -#define SCSI_PLAYAUDMSF 0x47 // Play Audio MSF (O) -#define SCSI_PLAYA_TKIN 0x48 // Play Audio Track/Index (O) -#define SCSI_PLYTKREL10 0x49 // Play Track Relative 10-Byte (O) -#define SCSI_PLYTKREL12 0xA9 // Play Track Relative 12-Byte (O) -#define SCSI_READCDCAP 0x25 // Read CD-ROM Capacity (MANDATORY) -#define SCSI_READHEADER 0x44 // Read Header (O) -#define SCSI_SUBCHANNEL 0x42 // Read Subchannel (O) -#define SCSI_READ_TOC 0x43 // Read TOC (O) - -//*************************************************************************** -// %%% Commands Unique to Scanner Devices %%% -//*************************************************************************** -#define SCSI_GETDBSTAT 0x34 // Get Data Buffer Status (O) -#define SCSI_GETWINDOW 0x25 // Get Window (O) -#define SCSI_OBJECTPOS 0x31 // Object Postion (O) -#define SCSI_SCAN 0x1B // Scan (O) -#define SCSI_SETWINDOW 0x24 // Set Window (MANDATORY) - -//*************************************************************************** -// %%% Commands Unique to Optical Memory Devices %%% -//*************************************************************************** -#define SCSI_UpdateBlk 0x3D // Update Block (O) - -//*************************************************************************** -// %%% Commands Unique to Medium Changer Devices %%% -//*************************************************************************** -#define SCSI_EXCHMEDIUM 0xA6 // Exchange Medium (O) -#define SCSI_INITELSTAT 0x07 // Initialize Element Status (O) -#define SCSI_POSTOELEM 0x2B // Position to Element (O) -#define SCSI_REQ_VE_ADD 0xB5 // Request Volume Element Address (O) -#define SCSI_SENDVOLTAG 0xB6 // Send Volume Tag (O) - -//*************************************************************************** -// %%% Commands Unique to Communication Devices %%% -//*************************************************************************** -#define SCSI_GET_MSG_6 0x08 // Get Message 6-Byte (MANDATORY) -#define SCSI_GET_MSG_10 0x28 // Get Message 10-Byte (O) -#define SCSI_GET_MSG_12 0xA8 // Get Message 12-Byte (O) -#define SCSI_SND_MSG_6 0x0A // Send Message 6-Byte (MANDATORY) -#define SCSI_SND_MSG_10 0x2A // Send Message 10-Byte (O) -#define SCSI_SND_MSG_12 0xAA // Send Message 12-Byte (O) - -//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ -// -// %%% END OF SCSI COMMAND OPCODES %%% -// -///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ - -//*************************************************************************** -// %%% Request Sense Data Format %%% -//*************************************************************************** -typedef struct { - - BYTE ErrorCode; // Error Code (70H or 71H) - BYTE SegmentNum; // Number of current segment descriptor - BYTE SenseKey; // Sense Key(See bit definitions too) - BYTE InfoByte0; // Information MSB - BYTE InfoByte1; // Information MID - BYTE InfoByte2; // Information MID - BYTE InfoByte3; // Information LSB - BYTE AddSenLen; // Additional Sense Length - BYTE ComSpecInf0; // Command Specific Information MSB - BYTE ComSpecInf1; // Command Specific Information MID - BYTE ComSpecInf2; // Command Specific Information MID - BYTE ComSpecInf3; // Command Specific Information LSB - BYTE AddSenseCode; // Additional Sense Code - BYTE AddSenQual; // Additional Sense Code Qualifier - BYTE FieldRepUCode; // Field Replaceable Unit Code - BYTE SenKeySpec15; // Sense Key Specific 15th byte - BYTE SenKeySpec16; // Sense Key Specific 16th byte - BYTE SenKeySpec17; // Sense Key Specific 17th byte - BYTE AddSenseBytes; // Additional Sense Bytes - -} SENSE_DATA_FMT; - -//*************************************************************************** -// %%% REQUEST SENSE ERROR CODE %%% -//*************************************************************************** -#define SERROR_CURRENT 0x70 // Current Errors -#define SERROR_DEFERED 0x71 // Deferred Errors - -//*************************************************************************** -// %%% REQUEST SENSE BIT DEFINITIONS %%% -//*************************************************************************** -#define SENSE_VALID 0x80 // Byte 0 Bit 7 -#define SENSE_FILEMRK 0x80 // Byte 2 Bit 7 -#define SENSE_EOM 0x40 // Byte 2 Bit 6 -#define SENSE_ILI 0x20 // Byte 2 Bit 5 - -//*************************************************************************** -// %%% REQUEST SENSE SENSE KEY DEFINITIONS %%% -//*************************************************************************** -#define KEY_NOSENSE 0x00 // No Sense -#define KEY_RECERROR 0x01 // Recovered Error -#define KEY_NOTREADY 0x02 // Not Ready -#define KEY_MEDIUMERR 0x03 // Medium Error -#define KEY_HARDERROR 0x04 // Hardware Error -#define KEY_ILLGLREQ 0x05 // Illegal Request -#define KEY_UNITATT 0x06 // Unit Attention -#define KEY_DATAPROT 0x07 // Data Protect -#define KEY_BLANKCHK 0x08 // Blank Check -#define KEY_VENDSPEC 0x09 // Vendor Specific -#define KEY_COPYABORT 0x0A // Copy Abort -#define KEY_EQUAL 0x0C // Equal (Search) -#define KEY_VOLOVRFLW 0x0D // Volume Overflow -#define KEY_MISCOMP 0x0E // Miscompare (Search) -#define KEY_RESERVED 0x0F // Reserved - -//*************************************************************************** -// %%% PERIPHERAL DEVICE TYPE DEFINITIONS %%% -//*************************************************************************** -#define DTYPE_DASD 0x00 // Disk Device -#define DTYPE_SEQD 0x01 // Tape Device -#define DTYPE_PRNT 0x02 // Printer -#define DTYPE_PROC 0x03 // Processor -#define DTYPE_WORM 0x04 // Write-once read-multiple -#define DTYPE_CROM 0x05 // CD-ROM device -#define DTYPE_CDROM 0x05 // CD-ROM device -#define DTYPE_SCAN 0x06 // Scanner device -#define DTYPE_OPTI 0x07 // Optical memory device -#define DTYPE_JUKE 0x08 // Medium Changer device -#define DTYPE_COMM 0x09 // Communications device -#define DTYPE_RESL 0x0A // Reserved (low) -#define DTYPE_RESH 0x1E // Reserved (high) -#define DTYPE_UNKNOWN 0x1F // Unknown or no device type - -//*************************************************************************** -// %%% ANSI APPROVED VERSION DEFINITIONS %%% -//*************************************************************************** -#define ANSI_MAYBE 0x0 // Device may or may not be ANSI approved stand -#define ANSI_SCSI1 0x1 // Device complies to ANSI X3.131-1986 (SCSI-1) -#define ANSI_SCSI2 0x2 // Device complies to SCSI-2 -#define ANSI_RESLO 0x3 // Reserved (low) -#define ANSI_RESHI 0x7 // Reserved (high) - - -//////////////////////////////////////////////////////////////// - -typedef struct { - USHORT Length; - UCHAR ScsiStatus; - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; - UCHAR CdbLength; - UCHAR SenseInfoLength; - UCHAR DataIn; - ULONG DataTransferLength; - ULONG TimeOutValue; - ULONG DataBufferOffset; - ULONG SenseInfoOffset; - UCHAR Cdb[16]; -} SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH; - - -typedef struct { - USHORT Length; - UCHAR ScsiStatus; - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; - UCHAR CdbLength; - UCHAR SenseInfoLength; - UCHAR DataIn; - ULONG DataTransferLength; - ULONG TimeOutValue; - PVOID DataBuffer; - ULONG SenseInfoOffset; - UCHAR Cdb[16]; -} SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT; - - -typedef struct { - SCSI_PASS_THROUGH spt; - ULONG Filler; - UCHAR ucSenseBuf[32]; - UCHAR ucDataBuf[512]; -} SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS; - - -typedef struct { - SCSI_PASS_THROUGH_DIRECT spt; - ULONG Filler; - UCHAR ucSenseBuf[32]; -} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER; - - - -typedef struct { - UCHAR NumberOfLogicalUnits; - UCHAR InitiatorBusId; - ULONG InquiryDataOffset; -} SCSI_BUS_DATA, *PSCSI_BUS_DATA; - - -typedef struct { - UCHAR NumberOfBusses; - SCSI_BUS_DATA BusData[1]; -} SCSI_ADAPTER_BUS_INFO, *PSCSI_ADAPTER_BUS_INFO; - - -typedef struct { - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; - BOOLEAN DeviceClaimed; - ULONG InquiryDataLength; - ULONG NextInquiryDataOffset; - UCHAR InquiryData[1]; -} SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA; - - -typedef struct { - ULONG Length; - UCHAR PortNumber; - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; -} SCSI_ADDRESS, *PSCSI_ADDRESS; - - -/* - * method codes - */ -#define METHOD_BUFFERED 0 -#define METHOD_IN_DIRECT 1 -#define METHOD_OUT_DIRECT 2 -#define METHOD_NEITHER 3 - -/* - * file access values - */ -#define FILE_ANY_ACCESS 0 -#define FILE_READ_ACCESS (0x0001) -#define FILE_WRITE_ACCESS (0x0002) - - -#define IOCTL_SCSI_BASE 0x00000004 - -/* - * constants for DataIn member of SCSI_PASS_THROUGH* structures - */ -#define SCSI_IOCTL_DATA_OUT 0 -#define SCSI_IOCTL_DATA_IN 1 -#define SCSI_IOCTL_DATA_UNSPECIFIED 2 - -/* - * Standard IOCTL define - */ -#define CTL_CODE( DevType, Function, Method, Access ) ( \ - ((DevType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ -) - -#define IOCTL_SCSI_PASS_THROUGH CTL_CODE( IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS ) -#define IOCTL_SCSI_MINIPORT CTL_CODE( IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS ) -#define IOCTL_SCSI_GET_INQUIRY_DATA CTL_CODE( IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE( IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE( IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS ) -#define IOCTL_SCSI_GET_ADDRESS CTL_CODE( IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS ) - -#define FILE_DEVICE_MASS_STORAGE 0x0000002d -#define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE - -#define IOCTL_STORAGE_CHECK_VERIFY CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_STORAGE_CHECK_VERIFY2 CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_STORAGE_MEDIA_REMOVAL CTL_CODE(IOCTL_STORAGE_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_STORAGE_EJECT_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_STORAGE_LOAD_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_STORAGE_LOAD_MEDIA2 CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_STORAGE_RESERVE CTL_CODE(IOCTL_STORAGE_BASE, 0x0204, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_STORAGE_RELEASE CTL_CODE(IOCTL_STORAGE_BASE, 0x0205, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_STORAGE_FIND_NEW_DEVICES CTL_CODE(IOCTL_STORAGE_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS) - -#define FILE_DEVICE_CD_ROM 0x00000002 -#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM -#define IOCTL_CDROM_RAW_READ CTL_CODE(IOCTL_CDROM_BASE, 0x000F, METHOD_OUT_DIRECT, FILE_READ_ACCESS) -#define IOCTL_CDROM_READ_Q_CHANNEL CTL_CODE(IOCTL_CDROM_BASE, 0x000B, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_SEEK_AUDIO_MSF CTL_CODE(IOCTL_CDROM_BASE, 0x0001, METHOD_BUFFERED, FILE_READ_ACCESS) - -typedef struct _CDROM_SEEK_AUDIO_MSF { - UCHAR M; - UCHAR S; - UCHAR F; -} CDROM_SEEK_AUDIO_MSF, *PCDROM_SEEK_AUDIO_MSF; - -// -// CD ROM Sub-Q Channel Data Format -// - -#define IOCTL_CDROM_SUB_Q_CHANNEL 0x00 -#define IOCTL_CDROM_CURRENT_POSITION 0x01 -#define IOCTL_CDROM_MEDIA_CATALOG 0x02 -#define IOCTL_CDROM_TRACK_ISRC 0x03 - -typedef struct _CDROM_SUB_Q_DATA_FORMAT { - UCHAR Format; - UCHAR Track; -} CDROM_SUB_Q_DATA_FORMAT, *PCDROM_SUB_Q_DATA_FORMAT; - -typedef struct _SUB_Q_HEADER { - UCHAR Reserved; - UCHAR AudioStatus; - UCHAR DataLength[2]; -} SUB_Q_HEADER, *PSUB_Q_HEADER; - -typedef struct _SUB_Q_CURRENT_POSITION { - SUB_Q_HEADER Header; - UCHAR FormatCode; - UCHAR Control : 4; - UCHAR ADR : 4; - UCHAR TrackNumber; - UCHAR IndexNumber; - UCHAR AbsoluteAddress[4]; - UCHAR TrackRelativeAddress[4]; -} SUB_Q_CURRENT_POSITION, *PSUB_Q_CURRENT_POSITION; - -typedef struct _SUB_Q_MEDIA_CATALOG_NUMBER { - SUB_Q_HEADER Header; - UCHAR FormatCode; - UCHAR Reserved[3]; - UCHAR Reserved1 : 7; - UCHAR Mcval : 1; - UCHAR MediaCatalog[15]; -} SUB_Q_MEDIA_CATALOG_NUMBER, *PSUB_Q_MEDIA_CATALOG_NUMBER; - -typedef struct _SUB_Q_TRACK_ISRC { - SUB_Q_HEADER Header; - UCHAR FormatCode; - UCHAR Reserved0; - UCHAR Track; - UCHAR Reserved1; - UCHAR Reserved2 : 7; - UCHAR Tcval : 1; - UCHAR TrackIsrc[15]; -} SUB_Q_TRACK_ISRC, *PSUB_Q_TRACK_ISRC; - -typedef union _SUB_Q_CHANNEL_DATA { - SUB_Q_CURRENT_POSITION CurrentPosition; - SUB_Q_MEDIA_CATALOG_NUMBER MediaCatalog; - SUB_Q_TRACK_ISRC TrackIsrc; -} SUB_Q_CHANNEL_DATA, *PSUB_Q_CHANNEL_DATA; - - -// IOCTL_DISK_SET_CACHE allows the caller to get or set the state of the disk -// read/write caches. -// -// If the structure is provided as the input buffer for the ioctl the read & -// write caches will be enabled or disabled depending on the parameters -// provided. -// -// If the structure is provided as an output buffer for the ioctl the state -// of the read & write caches will be returned. If both input and outut buffers -// are provided the output buffer will contain the cache state BEFORE any -// changes are made - - -typedef enum { - EqualPriority, - KeepPrefetchedData, - KeepReadData -} DISK_CACHE_RETENTION_PRIORITY; - -#define FILE_DEVICE_DISK 0x00000007 -#define IOCTL_DISK_BASE FILE_DEVICE_DISK -#define IOCTL_DISK_GET_CACHE_INFORMATION CTL_CODE(IOCTL_DISK_BASE, 0x0035, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_DISK_SET_CACHE_INFORMATION CTL_CODE(IOCTL_DISK_BASE, 0x0036, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) - -typedef struct _DISK_CACHE_INFORMATION { - - // - // on return indicates that the device is capable of saving any parameters - // in non-volatile storage. On send indicates that the device should - // save the state in non-volatile storage. - // - - BOOLEAN ParametersSavable; - - // - // Indicates whether the write and read caches are enabled. - // - - BOOLEAN ReadCacheEnabled; - BOOLEAN WriteCacheEnabled; - - // - // Controls the likelyhood of data remaining in the cache depending on how - // it got there. Data cached from a READ or WRITE operation may be given - // higher, lower or equal priority to data entered into the cache for other - // means (like prefetch) - // - - DISK_CACHE_RETENTION_PRIORITY ReadRetentionPriority; - DISK_CACHE_RETENTION_PRIORITY WriteRetentionPriority; - - // - // Requests for a larger number of blocks than this may have prefetching - // disabled. If this value is set to 0 prefetch will be disabled. - // - - USHORT DisablePrefetchTransferLength; - - // - // If TRUE then ScalarPrefetch (below) will be valid. If FALSE then - // the minimum and maximum values should be treated as a block count - // (BlockPrefetch) - // - - BOOLEAN PrefetchScalar; - - // - // Contains the minimum and maximum amount of data which will be - // will be prefetched into the cache on a disk operation. This value - // may either be a scalar multiplier of the transfer length of the request, - // or an abolute number of disk blocks. PrefetchScalar (above) indicates - // which interpretation is used. - // - - union { - struct { - USHORT Minimum; - USHORT Maximum; - - // - // The maximum number of blocks which will be prefetched - useful - // with the scalar limits to set definite upper limits. - // - - USHORT MaximumBlocks; - } ScalarPrefetch; - - struct { - USHORT Minimum; - USHORT Maximum; - } BlockPrefetch; - }; - -} DISK_CACHE_INFORMATION, *PDISK_CACHE_INFORMATION; - +/* Got it from Bochs */ + +///////////////////////////////////////////////////////////////////////// +// $Id: scsidefs.h,v 1.2 2004-01-02 14:34:48 qbix79 Exp $ +///////////////////////////////////////////////////////////////////////// +// +// +// iodev/scsidefs.h +// $Id: scsidefs.h,v 1.2 2004-01-02 14:34:48 qbix79 Exp $ +// +// This file was copied from ... ? +// + +//*************************************************************************** +// +// Name: SCSIDEFS.H +// +// Description: SCSI definitions ('C' Language) +// +//*************************************************************************** + +//*************************************************************************** +// %%% TARGET STATUS VALUES %%% +//*************************************************************************** +#define STATUS_GOOD 0x00 // Status Good +#define STATUS_CHKCOND 0x02 // Check Condition +#define STATUS_CONDMET 0x04 // Condition Met +#define STATUS_BUSY 0x08 // Busy +#define STATUS_INTERM 0x10 // Intermediate +#define STATUS_INTCDMET 0x14 // Intermediate-condition met +#define STATUS_RESCONF 0x18 // Reservation conflict +#define STATUS_COMTERM 0x22 // Command Terminated +#define STATUS_QFULL 0x28 // Queue full + +//*************************************************************************** +// %%% SCSI MISCELLANEOUS EQUATES %%% +//*************************************************************************** +#define MAXLUN 7 // Maximum Logical Unit Id +#define MAXTARG 7 // Maximum Target Id +#define MAX_SCSI_LUNS 64 // Maximum Number of SCSI LUNs +#define MAX_NUM_HA 8 // Maximum Number of SCSI HA's + +//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ +// +// %%% SCSI COMMAND OPCODES %%% +// +///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ + +//*************************************************************************** +// %%% Commands for all Device Types %%% +//*************************************************************************** +#define SCSI_CHANGE_DEF 0x40 // Change Definition (Optional) +#define SCSI_COMPARE 0x39 // Compare (O) +#define SCSI_COPY 0x18 // Copy (O) +#define SCSI_COP_VERIFY 0x3A // Copy and Verify (O) +#define SCSI_INQUIRY 0x12 // Inquiry (MANDATORY) +#define SCSI_LOG_SELECT 0x4C // Log Select (O) +#define SCSI_LOG_SENSE 0x4D // Log Sense (O) +#define SCSI_MODE_SEL6 0x15 // Mode Select 6-byte (Device Specific) +#define SCSI_MODE_SEL10 0x55 // Mode Select 10-byte (Device Specific) +#define SCSI_MODE_SEN6 0x1A // Mode Sense 6-byte (Device Specific) +#define SCSI_MODE_SEN10 0x5A // Mode Sense 10-byte (Device Specific) +#define SCSI_READ_BUFF 0x3C // Read Buffer (O) +#define SCSI_REQ_SENSE 0x03 // Request Sense (MANDATORY) +#define SCSI_SEND_DIAG 0x1D // Send Diagnostic (O) +#define SCSI_TST_U_RDY 0x00 // Test Unit Ready (MANDATORY) +#define SCSI_WRITE_BUFF 0x3B // Write Buffer (O) + +//*************************************************************************** +// %%% Commands Unique to Direct Access Devices %%% +//*************************************************************************** +#define SCSI_COMPARE 0x39 // Compare (O) +#define SCSI_FORMAT 0x04 // Format Unit (MANDATORY) +#define SCSI_LCK_UN_CAC 0x36 // Lock Unlock Cache (O) +#define SCSI_PREFETCH 0x34 // Prefetch (O) +#define SCSI_MED_REMOVL 0x1E // Prevent/Allow medium Removal (O) +#define SCSI_READ6 0x08 // Read 6-byte (MANDATORY) +#define SCSI_READ10 0x28 // Read 10-byte (MANDATORY) +#define SCSI_RD_CAPAC 0x25 // Read Capacity (MANDATORY) +#define SCSI_RD_DEFECT 0x37 // Read Defect Data (O) +#define SCSI_READ_LONG 0x3E // Read Long (O) +#define SCSI_REASS_BLK 0x07 // Reassign Blocks (O) +#define SCSI_RCV_DIAG 0x1C // Receive Diagnostic Results (O) +#define SCSI_RELEASE 0x17 // Release Unit (MANDATORY) +#define SCSI_REZERO 0x01 // Rezero Unit (O) +#define SCSI_SRCH_DAT_E 0x31 // Search Data Equal (O) +#define SCSI_SRCH_DAT_H 0x30 // Search Data High (O) +#define SCSI_SRCH_DAT_L 0x32 // Search Data Low (O) +#define SCSI_SEEK6 0x0B // Seek 6-Byte (O) +#define SCSI_SEEK10 0x2B // Seek 10-Byte (O) +#define SCSI_SEND_DIAG 0x1D // Send Diagnostics (MANDATORY) +#define SCSI_SET_LIMIT 0x33 // Set Limits (O) +#define SCSI_START_STP 0x1B // Start/Stop Unit (O) +#define SCSI_SYNC_CACHE 0x35 // Synchronize Cache (O) +#define SCSI_VERIFY 0x2F // Verify (O) +#define SCSI_WRITE6 0x0A // Write 6-Byte (MANDATORY) +#define SCSI_WRITE10 0x2A // Write 10-Byte (MANDATORY) +#define SCSI_WRT_VERIFY 0x2E // Write and Verify (O) +#define SCSI_WRITE_LONG 0x3F // Write Long (O) +#define SCSI_WRITE_SAME 0x41 // Write Same (O) + +//*************************************************************************** +// %%% Commands Unique to Sequential Access Devices %%% +//*************************************************************************** +#define SCSI_ERASE 0x19 // Erase (MANDATORY) +#define SCSI_LOAD_UN 0x1B // Load/Unload (O) +#define SCSI_LOCATE 0x2B // Locate (O) +#define SCSI_RD_BLK_LIM 0x05 // Read Block Limits (MANDATORY) +#define SCSI_READ_POS 0x34 // Read Position (O) +#define SCSI_READ_REV 0x0F // Read Reverse (O) +#define SCSI_REC_BF_DAT 0x14 // Recover Buffer Data (O) +#define SCSI_RESERVE 0x16 // Reserve Unit (MANDATORY) +#define SCSI_REWIND 0x01 // Rewind (MANDATORY) +#define SCSI_SPACE 0x11 // Space (MANDATORY) +#define SCSI_VERIFY_T 0x13 // Verify (Tape) (O) +#define SCSI_WRT_FILE 0x10 // Write Filemarks (MANDATORY) + +//*************************************************************************** +// %%% Commands Unique to Printer Devices %%% +//*************************************************************************** +#define SCSI_PRINT 0x0A // Print (MANDATORY) +#define SCSI_SLEW_PNT 0x0B // Slew and Print (O) +#define SCSI_STOP_PNT 0x1B // Stop Print (O) +#define SCSI_SYNC_BUFF 0x10 // Synchronize Buffer (O) + +//*************************************************************************** +// %%% Commands Unique to Processor Devices %%% +//*************************************************************************** +#define SCSI_RECEIVE 0x08 // Receive (O) +#define SCSI_SEND 0x0A // Send (O) + +//*************************************************************************** +// %%% Commands Unique to Write-Once Devices %%% +//*************************************************************************** +#define SCSI_MEDIUM_SCN 0x38 // Medium Scan (O) +#define SCSI_SRCHDATE10 0x31 // Search Data Equal 10-Byte (O) +#define SCSI_SRCHDATE12 0xB1 // Search Data Equal 12-Byte (O) +#define SCSI_SRCHDATH10 0x30 // Search Data High 10-Byte (O) +#define SCSI_SRCHDATH12 0xB0 // Search Data High 12-Byte (O) +#define SCSI_SRCHDATL10 0x32 // Search Data Low 10-Byte (O) +#define SCSI_SRCHDATL12 0xB2 // Search Data Low 12-Byte (O) +#define SCSI_SET_LIM_10 0x33 // Set Limits 10-Byte (O) +#define SCSI_SET_LIM_12 0xB3 // Set Limits 10-Byte (O) +#define SCSI_VERIFY10 0x2F // Verify 10-Byte (O) +#define SCSI_VERIFY12 0xAF // Verify 12-Byte (O) +#define SCSI_WRITE12 0xAA // Write 12-Byte (O) +#define SCSI_WRT_VER10 0x2E // Write and Verify 10-Byte (O) +#define SCSI_WRT_VER12 0xAE // Write and Verify 12-Byte (O) + +//*************************************************************************** +// %%% Commands Unique to CD-ROM Devices %%% +//*************************************************************************** +#define SCSI_PLAYAUD_10 0x45 // Play Audio 10-Byte (O) +#define SCSI_PLAYAUD_12 0xA5 // Play Audio 12-Byte 12-Byte (O) +#define SCSI_PLAYAUDMSF 0x47 // Play Audio MSF (O) +#define SCSI_PLAYA_TKIN 0x48 // Play Audio Track/Index (O) +#define SCSI_PLYTKREL10 0x49 // Play Track Relative 10-Byte (O) +#define SCSI_PLYTKREL12 0xA9 // Play Track Relative 12-Byte (O) +#define SCSI_READCDCAP 0x25 // Read CD-ROM Capacity (MANDATORY) +#define SCSI_READHEADER 0x44 // Read Header (O) +#define SCSI_SUBCHANNEL 0x42 // Read Subchannel (O) +#define SCSI_READ_TOC 0x43 // Read TOC (O) + +//*************************************************************************** +// %%% Commands Unique to Scanner Devices %%% +//*************************************************************************** +#define SCSI_GETDBSTAT 0x34 // Get Data Buffer Status (O) +#define SCSI_GETWINDOW 0x25 // Get Window (O) +#define SCSI_OBJECTPOS 0x31 // Object Postion (O) +#define SCSI_SCAN 0x1B // Scan (O) +#define SCSI_SETWINDOW 0x24 // Set Window (MANDATORY) + +//*************************************************************************** +// %%% Commands Unique to Optical Memory Devices %%% +//*************************************************************************** +#define SCSI_UpdateBlk 0x3D // Update Block (O) + +//*************************************************************************** +// %%% Commands Unique to Medium Changer Devices %%% +//*************************************************************************** +#define SCSI_EXCHMEDIUM 0xA6 // Exchange Medium (O) +#define SCSI_INITELSTAT 0x07 // Initialize Element Status (O) +#define SCSI_POSTOELEM 0x2B // Position to Element (O) +#define SCSI_REQ_VE_ADD 0xB5 // Request Volume Element Address (O) +#define SCSI_SENDVOLTAG 0xB6 // Send Volume Tag (O) + +//*************************************************************************** +// %%% Commands Unique to Communication Devices %%% +//*************************************************************************** +#define SCSI_GET_MSG_6 0x08 // Get Message 6-Byte (MANDATORY) +#define SCSI_GET_MSG_10 0x28 // Get Message 10-Byte (O) +#define SCSI_GET_MSG_12 0xA8 // Get Message 12-Byte (O) +#define SCSI_SND_MSG_6 0x0A // Send Message 6-Byte (MANDATORY) +#define SCSI_SND_MSG_10 0x2A // Send Message 10-Byte (O) +#define SCSI_SND_MSG_12 0xAA // Send Message 12-Byte (O) + +//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ +// +// %%% END OF SCSI COMMAND OPCODES %%% +// +///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ + +//*************************************************************************** +// %%% Request Sense Data Format %%% +//*************************************************************************** +typedef struct { + + BYTE ErrorCode; // Error Code (70H or 71H) + BYTE SegmentNum; // Number of current segment descriptor + BYTE SenseKey; // Sense Key(See bit definitions too) + BYTE InfoByte0; // Information MSB + BYTE InfoByte1; // Information MID + BYTE InfoByte2; // Information MID + BYTE InfoByte3; // Information LSB + BYTE AddSenLen; // Additional Sense Length + BYTE ComSpecInf0; // Command Specific Information MSB + BYTE ComSpecInf1; // Command Specific Information MID + BYTE ComSpecInf2; // Command Specific Information MID + BYTE ComSpecInf3; // Command Specific Information LSB + BYTE AddSenseCode; // Additional Sense Code + BYTE AddSenQual; // Additional Sense Code Qualifier + BYTE FieldRepUCode; // Field Replaceable Unit Code + BYTE SenKeySpec15; // Sense Key Specific 15th byte + BYTE SenKeySpec16; // Sense Key Specific 16th byte + BYTE SenKeySpec17; // Sense Key Specific 17th byte + BYTE AddSenseBytes; // Additional Sense Bytes + +} SENSE_DATA_FMT; + +//*************************************************************************** +// %%% REQUEST SENSE ERROR CODE %%% +//*************************************************************************** +#define SERROR_CURRENT 0x70 // Current Errors +#define SERROR_DEFERED 0x71 // Deferred Errors + +//*************************************************************************** +// %%% REQUEST SENSE BIT DEFINITIONS %%% +//*************************************************************************** +#define SENSE_VALID 0x80 // Byte 0 Bit 7 +#define SENSE_FILEMRK 0x80 // Byte 2 Bit 7 +#define SENSE_EOM 0x40 // Byte 2 Bit 6 +#define SENSE_ILI 0x20 // Byte 2 Bit 5 + +//*************************************************************************** +// %%% REQUEST SENSE SENSE KEY DEFINITIONS %%% +//*************************************************************************** +#define KEY_NOSENSE 0x00 // No Sense +#define KEY_RECERROR 0x01 // Recovered Error +#define KEY_NOTREADY 0x02 // Not Ready +#define KEY_MEDIUMERR 0x03 // Medium Error +#define KEY_HARDERROR 0x04 // Hardware Error +#define KEY_ILLGLREQ 0x05 // Illegal Request +#define KEY_UNITATT 0x06 // Unit Attention +#define KEY_DATAPROT 0x07 // Data Protect +#define KEY_BLANKCHK 0x08 // Blank Check +#define KEY_VENDSPEC 0x09 // Vendor Specific +#define KEY_COPYABORT 0x0A // Copy Abort +#define KEY_EQUAL 0x0C // Equal (Search) +#define KEY_VOLOVRFLW 0x0D // Volume Overflow +#define KEY_MISCOMP 0x0E // Miscompare (Search) +#define KEY_RESERVED 0x0F // Reserved + +//*************************************************************************** +// %%% PERIPHERAL DEVICE TYPE DEFINITIONS %%% +//*************************************************************************** +#define DTYPE_DASD 0x00 // Disk Device +#define DTYPE_SEQD 0x01 // Tape Device +#define DTYPE_PRNT 0x02 // Printer +#define DTYPE_PROC 0x03 // Processor +#define DTYPE_WORM 0x04 // Write-once read-multiple +#define DTYPE_CROM 0x05 // CD-ROM device +#define DTYPE_CDROM 0x05 // CD-ROM device +#define DTYPE_SCAN 0x06 // Scanner device +#define DTYPE_OPTI 0x07 // Optical memory device +#define DTYPE_JUKE 0x08 // Medium Changer device +#define DTYPE_COMM 0x09 // Communications device +#define DTYPE_RESL 0x0A // Reserved (low) +#define DTYPE_RESH 0x1E // Reserved (high) +#define DTYPE_UNKNOWN 0x1F // Unknown or no device type + +//*************************************************************************** +// %%% ANSI APPROVED VERSION DEFINITIONS %%% +//*************************************************************************** +#define ANSI_MAYBE 0x0 // Device may or may not be ANSI approved stand +#define ANSI_SCSI1 0x1 // Device complies to ANSI X3.131-1986 (SCSI-1) +#define ANSI_SCSI2 0x2 // Device complies to SCSI-2 +#define ANSI_RESLO 0x3 // Reserved (low) +#define ANSI_RESHI 0x7 // Reserved (high) From 3724a83a39f09838d9c9780d0c1071d124f8914c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 Jan 2004 14:38:30 +0000 Subject: [PATCH 1442/4131] removed Nttd* Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1523 --- src/dos/Makefile.am | 2 +- src/dos/Ntddcdrm.h | 548 ------------------------- src/dos/Ntddscsi.h | 313 -------------- src/dos/Ntddstor.h | 746 ---------------------------------- src/dos/cdrom_aspi_win32.cpp | 10 +- src/dos/cdrom_ioctl_win32.cpp | 3 + 6 files changed, 12 insertions(+), 1610 deletions(-) delete mode 100644 src/dos/Ntddcdrm.h delete mode 100644 src/dos/Ntddscsi.h delete mode 100644 src/dos/Ntddstor.h diff --git a/src/dos/Makefile.am b/src/dos/Makefile.am index 821a71b1..14cd2780 100644 --- a/src/dos/Makefile.am +++ b/src/dos/Makefile.am @@ -1,7 +1,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libdos.a -EXTRA_DIST = Ntddcdrm.h Ntddscsi.h Ntddstor.h scsidefs.h wnaspi32.h +EXTRA_DIST = scsidefs.h wnaspi32.h libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioctl.cpp dos_memory.cpp \ dos_misc.cpp dos_classes.cpp dos_programs.cpp dos_tables.cpp \ drives.cpp drives.h drive_virtual.cpp drive_local.cpp drive_cache.cpp \ diff --git a/src/dos/Ntddcdrm.h b/src/dos/Ntddcdrm.h deleted file mode 100644 index 6590a4ee..00000000 --- a/src/dos/Ntddcdrm.h +++ /dev/null @@ -1,548 +0,0 @@ -/*++ BUILD Version: 0001 // Increment this if a change has global effects - -Copyright (c) Microsoft Corporation. All rights reserved. - -Module Name: - - ntddcdrm.h - -Abstract: - - This module contains structures and definitions - associated with CDROM IOCTls. - -Author: - - Mike Glass - -Revision History: - ---*/ - -// begin_winioctl - -#ifndef _NTDDCDRM_ -#define _NTDDCDRM_ - -#if _MSC_VER >= 1200 -#pragma warning(push) -#endif - -#if _MSC_VER > 1000 -#pragma once -#endif - -// -// remove some level 4 warnings for this header file: -#pragma warning(disable:4200) // array[0] -#pragma warning(disable:4201) // nameless struct/unions -#pragma warning(disable:4214) // bit fields other than int - -#ifdef __cplusplus -extern "C" { -#endif - -// -// NtDeviceIoControlFile IoControlCode values for this device. -// -// Warning: Remember that the low two bits of the code specify how the -// buffers are passed to the driver! -// - -#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM - -#define IOCTL_CDROM_UNLOAD_DRIVER CTL_CODE(IOCTL_CDROM_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS) - -// -// CDROM Audio Device Control Functions -// - -#define IOCTL_CDROM_READ_TOC CTL_CODE(IOCTL_CDROM_BASE, 0x0000, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_SEEK_AUDIO_MSF CTL_CODE(IOCTL_CDROM_BASE, 0x0001, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_STOP_AUDIO CTL_CODE(IOCTL_CDROM_BASE, 0x0002, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_PAUSE_AUDIO CTL_CODE(IOCTL_CDROM_BASE, 0x0003, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_RESUME_AUDIO CTL_CODE(IOCTL_CDROM_BASE, 0x0004, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_GET_VOLUME CTL_CODE(IOCTL_CDROM_BASE, 0x0005, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_PLAY_AUDIO_MSF CTL_CODE(IOCTL_CDROM_BASE, 0x0006, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_SET_VOLUME CTL_CODE(IOCTL_CDROM_BASE, 0x000A, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_READ_Q_CHANNEL CTL_CODE(IOCTL_CDROM_BASE, 0x000B, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_GET_CONTROL CTL_CODE(IOCTL_CDROM_BASE, 0x000D, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_GET_LAST_SESSION CTL_CODE(IOCTL_CDROM_BASE, 0x000E, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_RAW_READ CTL_CODE(IOCTL_CDROM_BASE, 0x000F, METHOD_OUT_DIRECT, FILE_READ_ACCESS) -#define IOCTL_CDROM_DISK_TYPE CTL_CODE(IOCTL_CDROM_BASE, 0x0010, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define IOCTL_CDROM_GET_DRIVE_GEOMETRY CTL_CODE(IOCTL_CDROM_BASE, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX CTL_CODE(IOCTL_CDROM_BASE, 0x0014, METHOD_BUFFERED, FILE_READ_ACCESS) - -#define IOCTL_CDROM_READ_TOC_EX CTL_CODE(IOCTL_CDROM_BASE, 0x0015, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_GET_CONFIGURATION CTL_CODE(IOCTL_CDROM_BASE, 0x0016, METHOD_BUFFERED, FILE_READ_ACCESS) - -// end_winioctl - -// -// The following device control codes are common for all class drivers. The -// functions codes defined here must match all of the other class drivers. -// -// Warning: these codes will be replaced in the future with the IOCTL_STORAGE -// codes included below -// - -#define IOCTL_CDROM_CHECK_VERIFY CTL_CODE(IOCTL_CDROM_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_MEDIA_REMOVAL CTL_CODE(IOCTL_CDROM_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_EJECT_MEDIA CTL_CODE(IOCTL_CDROM_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_LOAD_MEDIA CTL_CODE(IOCTL_CDROM_BASE, 0x0203, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_RESERVE CTL_CODE(IOCTL_CDROM_BASE, 0x0204, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_RELEASE CTL_CODE(IOCTL_CDROM_BASE, 0x0205, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_FIND_NEW_DEVICES CTL_CODE(IOCTL_CDROM_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS) - -// -// The following file contains the IOCTL_STORAGE class ioctl definitions -// - -#include "ntddstor.h" - -// begin_winioctl - -// -// The following device control code is for the SIMBAD simulated bad -// sector facility. See SIMBAD.H in this directory for related structures. -// - -#define IOCTL_CDROM_SIMBAD CTL_CODE(IOCTL_CDROM_BASE, 0x1003, METHOD_BUFFERED, FILE_READ_ACCESS) - -// -// Maximum CD Rom size -// - -#define MAXIMUM_NUMBER_TRACKS 100 -#define MAXIMUM_CDROM_SIZE 804 -#define MINIMUM_CDROM_READ_TOC_EX_SIZE 2 // two bytes min transferred - -// -// READ_TOC_EX structure -// -typedef struct _CDROM_READ_TOC_EX { - UCHAR Format : 4; - UCHAR Reserved1 : 3; // future expansion - UCHAR Msf : 1; - UCHAR SessionTrack; - UCHAR Reserved2; // future expansion - UCHAR Reserved3; // future expansion -} CDROM_READ_TOC_EX, *PCDROM_READ_TOC_EX; - -#define CDROM_READ_TOC_EX_FORMAT_TOC 0x00 -#define CDROM_READ_TOC_EX_FORMAT_SESSION 0x01 -#define CDROM_READ_TOC_EX_FORMAT_FULL_TOC 0x02 -#define CDROM_READ_TOC_EX_FORMAT_PMA 0x03 -#define CDROM_READ_TOC_EX_FORMAT_ATIP 0x04 -#define CDROM_READ_TOC_EX_FORMAT_CDTEXT 0x05 - -// -// CD ROM Table OF Contents (TOC) -// Format 0 - Get table of contents -// - -typedef struct _TRACK_DATA { - UCHAR Reserved; - UCHAR Control : 4; - UCHAR Adr : 4; - UCHAR TrackNumber; - UCHAR Reserved1; - UCHAR Address[4]; -} TRACK_DATA, *PTRACK_DATA; - -typedef struct _CDROM_TOC { - - // - // Header - // - - UCHAR Length[2]; // add two bytes for this field - UCHAR FirstTrack; - UCHAR LastTrack; - - // - // Track data - // - - TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS]; -} CDROM_TOC, *PCDROM_TOC; - -#define CDROM_TOC_SIZE sizeof(CDROM_TOC) - -// -// CD ROM Table OF Contents -// Format 1 - Session Information -// - -typedef struct _CDROM_TOC_SESSION_DATA { - - // - // Header - // - - UCHAR Length[2]; // add two bytes for this field - UCHAR FirstCompleteSession; - UCHAR LastCompleteSession; - - // - // One track, representing the first track - // of the last finished session - // - - TRACK_DATA TrackData[1]; - -} CDROM_TOC_SESSION_DATA, *PCDROM_TOC_SESSION_DATA; - - -// -// CD ROM Table OF Contents -// Format 2 - Full TOC -// - -typedef struct _CDROM_TOC_FULL_TOC_DATA_BLOCK { - UCHAR SessionNumber; - UCHAR Control : 4; - UCHAR Adr : 4; - UCHAR Reserved1; - UCHAR Point; - UCHAR MsfExtra[3]; - UCHAR Zero; - UCHAR Msf[3]; -} CDROM_TOC_FULL_TOC_DATA_BLOCK, *PCDROM_TOC_FULL_TOC_DATA_BLOCK; - -typedef struct _CDROM_TOC_FULL_TOC_DATA { - - // - // Header - // - - UCHAR Length[2]; // add two bytes for this field - UCHAR FirstCompleteSession; - UCHAR LastCompleteSession; - - // - // one to N descriptors included - // - - CDROM_TOC_FULL_TOC_DATA_BLOCK Descriptors[0]; - -} CDROM_TOC_FULL_TOC_DATA, *PCDROM_TOC_FULL_TOC_DATA; - -// -// CD ROM Table OF Contents -// Format 3 - Program Memory Area -// -typedef struct _CDROM_TOC_PMA_DATA { - - // - // Header - // - - UCHAR Length[2]; // add two bytes for this field - UCHAR Reserved1; - UCHAR Reserved2; - - // - // one to N descriptors included - // - - CDROM_TOC_FULL_TOC_DATA_BLOCK Descriptors[0]; - -} CDROM_TOC_PMA_DATA, *PCDROM_TOC_PMA_DATA; - -// -// CD ROM Table OF Contents -// Format 4 - Absolute Time In Pregroove -// - -typedef struct _CDROM_TOC_ATIP_DATA_BLOCK { - - UCHAR CdrwReferenceSpeed : 3; - UCHAR Reserved3 : 1; - UCHAR WritePower : 3; - UCHAR True1 : 1; - UCHAR Reserved4 : 6; - UCHAR UnrestrictedUse : 1; - UCHAR Reserved5 : 1; - UCHAR A3Valid : 1; - UCHAR A2Valid : 1; - UCHAR A1Valid : 1; - UCHAR DiscSubType : 3; - UCHAR IsCdrw : 1; - UCHAR True2 : 1; - UCHAR Reserved7; - - UCHAR LeadInMsf[3]; - UCHAR Reserved8; - - UCHAR LeadOutMsf[3]; - UCHAR Reserved9; - - UCHAR A1Values[3]; - UCHAR Reserved10; - - UCHAR A2Values[3]; - UCHAR Reserved11; - - UCHAR A3Values[3]; - UCHAR Reserved12; - -} CDROM_TOC_ATIP_DATA_BLOCK, *PCDROM_TOC_ATIP_DATA_BLOCK; - -typedef struct _CDROM_TOC_ATIP_DATA { - - // - // Header - // - - UCHAR Length[2]; // add two bytes for this field - UCHAR Reserved1; - UCHAR Reserved2; - - // - // zero? to N descriptors included. - // - - CDROM_TOC_ATIP_DATA_BLOCK Descriptors[0]; - -} CDROM_TOC_ATIP_DATA, *PCDROM_TOC_ATIP_DATA; - -// -// CD ROM Table OF Contents -// Format 5 - CD Text Info -// -typedef struct _CDROM_TOC_CD_TEXT_DATA_BLOCK { - UCHAR PackType; - UCHAR TrackNumber : 7; - UCHAR ExtensionFlag : 1; // should be zero! - UCHAR SequenceNumber; - UCHAR CharacterPosition : 4; - UCHAR BlockNumber : 3; - UCHAR Unicode : 1; - union { - UCHAR Text[12]; - WCHAR WText[6]; - }; - UCHAR CRC[2]; -} CDROM_TOC_CD_TEXT_DATA_BLOCK, *PCDROM_TOC_CD_TEXT_DATA_BLOCK; - -typedef struct _CDROM_TOC_CD_TEXT_DATA { - - // - // Header - // - - UCHAR Length[2]; // add two bytes for this field - UCHAR Reserved1; - UCHAR Reserved2; - - // - // the text info comes in discrete blocks of - // a heavily-overloaded structure - // - - CDROM_TOC_CD_TEXT_DATA_BLOCK Descriptors[0]; - -} CDROM_TOC_CD_TEXT_DATA, *PCDROM_TOC_CD_TEXT_DATA; - -// -// These are the types used for PackType field in CDROM_TOC_CD_TEXT_DATA_BLOCK -// and also for requesting specific info from IOCTL_CDROM_READ_CD_TEXT -// -#define CDROM_CD_TEXT_PACK_ALBUM_NAME 0x80 -#define CDROM_CD_TEXT_PACK_PERFORMER 0x81 -#define CDROM_CD_TEXT_PACK_SONGWRITER 0x82 -#define CDROM_CD_TEXT_PACK_COMPOSER 0x83 -#define CDROM_CD_TEXT_PACK_ARRANGER 0x84 -#define CDROM_CD_TEXT_PACK_MESSAGES 0x85 -#define CDROM_CD_TEXT_PACK_DISC_ID 0x86 -#define CDROM_CD_TEXT_PACK_GENRE 0x87 -#define CDROM_CD_TEXT_PACK_TOC_INFO 0x88 -#define CDROM_CD_TEXT_PACK_TOC_INFO2 0x89 -// 0x8a - 0x8d are reserved.... -#define CDROM_CD_TEXT_PACK_UPC_EAN 0x8e -#define CDROM_CD_TEXT_PACK_SIZE_INFO 0x8f - -// -// Play audio starting at MSF and ending at MSF -// - -typedef struct _CDROM_PLAY_AUDIO_MSF { - UCHAR StartingM; - UCHAR StartingS; - UCHAR StartingF; - UCHAR EndingM; - UCHAR EndingS; - UCHAR EndingF; -} CDROM_PLAY_AUDIO_MSF, *PCDROM_PLAY_AUDIO_MSF; - -// -// Seek to MSF -// - -typedef struct _CDROM_SEEK_AUDIO_MSF { - UCHAR M; - UCHAR S; - UCHAR F; -} CDROM_SEEK_AUDIO_MSF, *PCDROM_SEEK_AUDIO_MSF; - - -// -// Flags for the disk type -// - -typedef struct _CDROM_DISK_DATA { - - ULONG DiskData; - -} CDROM_DISK_DATA, *PCDROM_DISK_DATA; - -#define CDROM_DISK_AUDIO_TRACK (0x00000001) -#define CDROM_DISK_DATA_TRACK (0x00000002) - -// -// CD ROM Data Mode Codes, used with IOCTL_CDROM_READ_Q_CHANNEL -// - -#define IOCTL_CDROM_SUB_Q_CHANNEL 0x00 -#define IOCTL_CDROM_CURRENT_POSITION 0x01 -#define IOCTL_CDROM_MEDIA_CATALOG 0x02 -#define IOCTL_CDROM_TRACK_ISRC 0x03 - -typedef struct _CDROM_SUB_Q_DATA_FORMAT { - UCHAR Format; - UCHAR Track; -} CDROM_SUB_Q_DATA_FORMAT, *PCDROM_SUB_Q_DATA_FORMAT; - - -// -// CD ROM Sub-Q Channel Data Format -// - -typedef struct _SUB_Q_HEADER { - UCHAR Reserved; - UCHAR AudioStatus; - UCHAR DataLength[2]; -} SUB_Q_HEADER, *PSUB_Q_HEADER; - -typedef struct _SUB_Q_CURRENT_POSITION { - SUB_Q_HEADER Header; - UCHAR FormatCode; - UCHAR Control : 4; - UCHAR ADR : 4; - UCHAR TrackNumber; - UCHAR IndexNumber; - UCHAR AbsoluteAddress[4]; - UCHAR TrackRelativeAddress[4]; -} SUB_Q_CURRENT_POSITION, *PSUB_Q_CURRENT_POSITION; - -typedef struct _SUB_Q_MEDIA_CATALOG_NUMBER { - SUB_Q_HEADER Header; - UCHAR FormatCode; - UCHAR Reserved[3]; - UCHAR Reserved1 : 7; - UCHAR Mcval : 1; - UCHAR MediaCatalog[15]; -} SUB_Q_MEDIA_CATALOG_NUMBER, *PSUB_Q_MEDIA_CATALOG_NUMBER; - -typedef struct _SUB_Q_TRACK_ISRC { - SUB_Q_HEADER Header; - UCHAR FormatCode; - UCHAR Reserved0; - UCHAR Track; - UCHAR Reserved1; - UCHAR Reserved2 : 7; - UCHAR Tcval : 1; - UCHAR TrackIsrc[15]; -} SUB_Q_TRACK_ISRC, *PSUB_Q_TRACK_ISRC; - -typedef union _SUB_Q_CHANNEL_DATA { - SUB_Q_CURRENT_POSITION CurrentPosition; - SUB_Q_MEDIA_CATALOG_NUMBER MediaCatalog; - SUB_Q_TRACK_ISRC TrackIsrc; -} SUB_Q_CHANNEL_DATA, *PSUB_Q_CHANNEL_DATA; - -// -// Audio Status Codes -// - -#define AUDIO_STATUS_NOT_SUPPORTED 0x00 -#define AUDIO_STATUS_IN_PROGRESS 0x11 -#define AUDIO_STATUS_PAUSED 0x12 -#define AUDIO_STATUS_PLAY_COMPLETE 0x13 -#define AUDIO_STATUS_PLAY_ERROR 0x14 -#define AUDIO_STATUS_NO_STATUS 0x15 - -// -// ADR Sub-channel Q Field -// - -#define ADR_NO_MODE_INFORMATION 0x0 -#define ADR_ENCODES_CURRENT_POSITION 0x1 -#define ADR_ENCODES_MEDIA_CATALOG 0x2 -#define ADR_ENCODES_ISRC 0x3 - -// -// Sub-channel Q Control Bits -// - -#define AUDIO_WITH_PREEMPHASIS 0x1 -#define DIGITAL_COPY_PERMITTED 0x2 -#define AUDIO_DATA_TRACK 0x4 -#define TWO_FOUR_CHANNEL_AUDIO 0x8 - -// -// Get Audio control parameters -// - -typedef struct _CDROM_AUDIO_CONTROL { - UCHAR LbaFormat; - USHORT LogicalBlocksPerSecond; -} CDROM_AUDIO_CONTROL, *PCDROM_AUDIO_CONTROL; - -// -// Volume control - Volume takes a value between 1 and 0xFF. -// SCSI-II CDROM audio suppports up to 4 audio ports with -// Independent volume control. -// - -typedef struct _VOLUME_CONTROL { - UCHAR PortVolume[4]; -} VOLUME_CONTROL, *PVOLUME_CONTROL; - -typedef enum _TRACK_MODE_TYPE { - YellowMode2, - XAForm2, - CDDA -} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE; - -// -// Passed to cdrom to describe the raw read, ie. Mode 2, Form 2, CDDA... -// - -typedef struct __RAW_READ_INFO { - LARGE_INTEGER DiskOffset; - ULONG SectorCount; - TRACK_MODE_TYPE TrackMode; -} RAW_READ_INFO, *PRAW_READ_INFO; - -#ifdef __cplusplus -} -#endif - - -#if _MSC_VER >= 1200 -#pragma warning(pop) // un-sets any local warning changes -#else -#pragma warning(default:4200) // array[0] is not a warning for this file -#pragma warning(default:4201) // nameless struct/unions -#pragma warning(default:4214) // bit fields other than int -#endif - - -#endif // _NTDDCDRM_ - -// end_winioctl - - diff --git a/src/dos/Ntddscsi.h b/src/dos/Ntddscsi.h deleted file mode 100644 index 61f5b250..00000000 --- a/src/dos/Ntddscsi.h +++ /dev/null @@ -1,313 +0,0 @@ -/*++ BUILD Version: 0001 // Increment this if a change has global effects - -Copyright (c) Microsoft Corporation. All rights reserved. - -Module Name: - - ntddscsi.h - -Abstract: - - This is the include file that defines all constants and types for - accessing the SCSI port adapters. - -Author: - - Jeff Havens - -Revision History: - ---*/ - - -// -// Interface GUIDs -// -// need these GUIDs outside conditional includes so that user can -// #include in precompiled header -// #include in a single source file -// #include in that source file a second time to instantiate the GUIDs -// -#ifdef DEFINE_GUID -// -// Make sure FAR is defined... -// -#ifndef FAR -#ifdef _WIN32 -#define FAR -#else -#define FAR _far -#endif -#endif - -DEFINE_GUID(ScsiRawInterfaceGuid, 0x53f56309L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); -DEFINE_GUID(WmiScsiAddressGuid, 0x53f5630fL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); -#endif - -#ifndef _NTDDSCSIH_ -#define _NTDDSCSIH_ - -#ifdef __cplusplus -extern "C" { -#endif - -// -// Device Name - this string is the name of the device. It is the name -// that should be passed to NtOpenFile when accessing the device. -// -// Note: For devices that support multiple units, it should be suffixed -// with the Ascii representation of the unit number. -// - -#define IOCTL_SCSI_BASE FILE_DEVICE_CONTROLLER - -#define DD_SCSI_DEVICE_NAME "\\Device\\ScsiPort" - - -// -// NtDeviceIoControlFile IoControlCode values for this device. -// -// Warning: Remember that the low two bits of the code specify how the -// buffers are passed to the driver! -// - -#define IOCTL_SCSI_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) -#define IOCTL_SCSI_MINIPORT CTL_CODE(IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) -#define IOCTL_SCSI_GET_INQUIRY_DATA CTL_CODE(IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE(IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) -#define IOCTL_SCSI_GET_ADDRESS CTL_CODE(IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_SCSI_RESCAN_BUS CTL_CODE(IOCTL_SCSI_BASE, 0x0407, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_SCSI_GET_DUMP_POINTERS CTL_CODE(IOCTL_SCSI_BASE, 0x0408, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_SCSI_FREE_DUMP_POINTERS CTL_CODE(IOCTL_SCSI_BASE, 0x0409, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_IDE_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x040a, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) - -// -// Define the SCSI pass through structure. -// - -typedef struct _SCSI_PASS_THROUGH { - USHORT Length; - UCHAR ScsiStatus; - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; - UCHAR CdbLength; - UCHAR SenseInfoLength; - UCHAR DataIn; - ULONG DataTransferLength; - ULONG TimeOutValue; - ULONG DataBufferOffset; //ULONG_PTR DataBufferOffset; - ULONG SenseInfoOffset; - UCHAR Cdb[16]; -}SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH; - -// -// Define the SCSI pass through direct structure. -// - -typedef struct _SCSI_PASS_THROUGH_DIRECT { - USHORT Length; - UCHAR ScsiStatus; - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; - UCHAR CdbLength; - UCHAR SenseInfoLength; - UCHAR DataIn; - ULONG DataTransferLength; - ULONG TimeOutValue; - PVOID DataBuffer; - ULONG SenseInfoOffset; - UCHAR Cdb[16]; -}SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT; - - -// -// Define the SCSI pass through direct structure for Win64 (thunking). -// -#if defined(_WIN64) -typedef struct _SCSI_PASS_THROUGH32 { - USHORT Length; - UCHAR ScsiStatus; - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; - UCHAR CdbLength; - UCHAR SenseInfoLength; - UCHAR DataIn; - ULONG DataTransferLength; - ULONG TimeOutValue; - ULONG32 DataBufferOffset; - ULONG SenseInfoOffset; - UCHAR Cdb[16]; -}SCSI_PASS_THROUGH32, *PSCSI_PASS_THROUGH32; - -// -// Define the SCSI pass through direct structure. -// - -typedef struct _SCSI_PASS_THROUGH_DIRECT32 { - USHORT Length; - UCHAR ScsiStatus; - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; - UCHAR CdbLength; - UCHAR SenseInfoLength; - UCHAR DataIn; - ULONG DataTransferLength; - ULONG TimeOutValue; - VOID * POINTER_32 DataBuffer; - ULONG SenseInfoOffset; - UCHAR Cdb[16]; -}SCSI_PASS_THROUGH_DIRECT32, *PSCSI_PASS_THROUGH_DIRECT32; - -#endif - -// -// Define SCSI information. -// Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL. -// - -typedef struct _SCSI_BUS_DATA { - UCHAR NumberOfLogicalUnits; - UCHAR InitiatorBusId; - ULONG InquiryDataOffset; -}SCSI_BUS_DATA, *PSCSI_BUS_DATA; - -// -// Define SCSI adapter bus information structure.. -// Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL. -// - -typedef struct _SCSI_ADAPTER_BUS_INFO { - UCHAR NumberOfBuses; - SCSI_BUS_DATA BusData[1]; -} SCSI_ADAPTER_BUS_INFO, *PSCSI_ADAPTER_BUS_INFO; - -// -// Define SCSI adapter bus information. -// Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL. -// - -typedef struct _SCSI_INQUIRY_DATA { - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; - BOOLEAN DeviceClaimed; - ULONG InquiryDataLength; - ULONG NextInquiryDataOffset; - UCHAR InquiryData[1]; -}SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA; - -// -// Define header for I/O control SRB. -// - -typedef struct _SRB_IO_CONTROL { - ULONG HeaderLength; - UCHAR Signature[8]; - ULONG Timeout; - ULONG ControlCode; - ULONG ReturnCode; - ULONG Length; -} SRB_IO_CONTROL, *PSRB_IO_CONTROL; - -// -// SCSI port driver capabilities structure. -// - -typedef struct _IO_SCSI_CAPABILITIES { - - // - // Length of this structure - // - - ULONG Length; - - // - // Maximum transfer size in single SRB - // - - ULONG MaximumTransferLength; - - // - // Maximum number of physical pages per data buffer - // - - ULONG MaximumPhysicalPages; - - // - // Async calls from port to class - // - - ULONG SupportedAsynchronousEvents; - - // - // Alignment mask for data transfers. - // - - ULONG AlignmentMask; - - // - // Supports tagged queuing - // - - BOOLEAN TaggedQueuing; - - // - // Host adapter scans down for bios devices. - // - - BOOLEAN AdapterScansDown; - - // - // The host adapter uses programmed I/O. - // - - BOOLEAN AdapterUsesPio; - -} IO_SCSI_CAPABILITIES, *PIO_SCSI_CAPABILITIES; - -typedef struct _SCSI_ADDRESS { - ULONG Length; - UCHAR PortNumber; - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; -}SCSI_ADDRESS, *PSCSI_ADDRESS; - -// -// Define structure for returning crash dump pointers. -// - -struct _ADAPTER_OBJECT; - -typedef struct _DUMP_POINTERS { - struct _ADAPTER_OBJECT *AdapterObject; - PVOID MappedRegisterBase; - PVOID DumpData; - PVOID CommonBufferVa; - LARGE_INTEGER CommonBufferPa; - ULONG CommonBufferSize; - BOOLEAN AllocateCommonBuffers; - BOOLEAN UseDiskDump; - UCHAR Spare1[2]; - PVOID DeviceObject; -} DUMP_POINTERS, *PDUMP_POINTERS; - -// -// Define values for pass-through DataIn field. -// - -#define SCSI_IOCTL_DATA_OUT 0 -#define SCSI_IOCTL_DATA_IN 1 -#define SCSI_IOCTL_DATA_UNSPECIFIED 2 - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/dos/Ntddstor.h b/src/dos/Ntddstor.h deleted file mode 100644 index 766f19ce..00000000 --- a/src/dos/Ntddstor.h +++ /dev/null @@ -1,746 +0,0 @@ -/*++ BUILD Version: 0001 // Increment this if a change has global effects - -Copyright (c) Microsoft Corporation. All rights reserved. - -Module Name: - - ntddstor.h - -Abstract: - - This is the include file that defines all common constants and types - accessing the storage class drivers - -Author: - - Peter Wieland 19-Jun-1996 - -Revision History: - ---*/ - - -// -// Interface GUIDs -// -// need these GUIDs outside conditional includes so that user can -// #include in precompiled header -// #include in a single source file -// #include in that source file a second time to instantiate the GUIDs -// -#ifdef DEFINE_GUID -// -// Make sure FAR is defined... -// -#ifndef FAR -#ifdef _WIN32 -#define FAR -#else -#define FAR _far -#endif -#endif - -// begin_wioctlguids -DEFINE_GUID(GUID_DEVINTERFACE_DISK, 0x53f56307L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); -DEFINE_GUID(GUID_DEVINTERFACE_CDROM, 0x53f56308L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); -DEFINE_GUID(GUID_DEVINTERFACE_PARTITION, 0x53f5630aL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); -DEFINE_GUID(GUID_DEVINTERFACE_TAPE, 0x53f5630bL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); -DEFINE_GUID(GUID_DEVINTERFACE_WRITEONCEDISK, 0x53f5630cL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); -DEFINE_GUID(GUID_DEVINTERFACE_VOLUME, 0x53f5630dL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); -DEFINE_GUID(GUID_DEVINTERFACE_MEDIUMCHANGER, 0x53f56310L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); -DEFINE_GUID(GUID_DEVINTERFACE_FLOPPY, 0x53f56311L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); -DEFINE_GUID(GUID_DEVINTERFACE_CDCHANGER, 0x53f56312L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); -DEFINE_GUID(GUID_DEVINTERFACE_STORAGEPORT, 0x2accfe60L, 0xc130, 0x11d2, 0xb0, 0x82, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); -// end_wioctlguids - -// begin_wioctlobsoleteguids -#define DiskClassGuid GUID_DEVINTERFACE_DISK -#define CdRomClassGuid GUID_DEVINTERFACE_CDROM -#define PartitionClassGuid GUID_DEVINTERFACE_PARTITION -#define TapeClassGuid GUID_DEVINTERFACE_TAPE -#define WriteOnceDiskClassGuid GUID_DEVINTERFACE_WRITEONCEDISK -#define VolumeClassGuid GUID_DEVINTERFACE_VOLUME -#define MediumChangerClassGuid GUID_DEVINTERFACE_MEDIUMCHANGER -#define FloppyClassGuid GUID_DEVINTERFACE_FLOPPY -#define CdChangerClassGuid GUID_DEVINTERFACE_CDCHANGER -#define StoragePortClassGuid GUID_DEVINTERFACE_STORAGEPORT -// end_wioctlobsoleteguids -#endif - -// begin_winioctl - -#ifndef _NTDDSTOR_H_ -#define _NTDDSTOR_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -// -// IoControlCode values for storage devices -// - -#define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE - -// -// The following device control codes are common for all class drivers. They -// should be used in place of the older IOCTL_DISK, IOCTL_CDROM and IOCTL_TAPE -// common codes -// - -#define IOCTL_STORAGE_CHECK_VERIFY CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_STORAGE_CHECK_VERIFY2 CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_STORAGE_MEDIA_REMOVAL CTL_CODE(IOCTL_STORAGE_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_STORAGE_EJECT_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_STORAGE_LOAD_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_STORAGE_LOAD_MEDIA2 CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_STORAGE_RESERVE CTL_CODE(IOCTL_STORAGE_BASE, 0x0204, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_STORAGE_RELEASE CTL_CODE(IOCTL_STORAGE_BASE, 0x0205, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_STORAGE_FIND_NEW_DEVICES CTL_CODE(IOCTL_STORAGE_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS) - -#define IOCTL_STORAGE_EJECTION_CONTROL CTL_CODE(IOCTL_STORAGE_BASE, 0x0250, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_STORAGE_MCN_CONTROL CTL_CODE(IOCTL_STORAGE_BASE, 0x0251, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define IOCTL_STORAGE_GET_MEDIA_TYPES CTL_CODE(IOCTL_STORAGE_BASE, 0x0300, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_STORAGE_GET_MEDIA_TYPES_EX CTL_CODE(IOCTL_STORAGE_BASE, 0x0301, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER CTL_CODE(IOCTL_STORAGE_BASE, 0x0304, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_STORAGE_GET_HOTPLUG_INFO CTL_CODE(IOCTL_STORAGE_BASE, 0x0305, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_STORAGE_SET_HOTPLUG_INFO CTL_CODE(IOCTL_STORAGE_BASE, 0x0306, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) - -#define IOCTL_STORAGE_RESET_BUS CTL_CODE(IOCTL_STORAGE_BASE, 0x0400, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_STORAGE_RESET_DEVICE CTL_CODE(IOCTL_STORAGE_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_STORAGE_BREAK_RESERVATION CTL_CODE(IOCTL_STORAGE_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS) - -#define IOCTL_STORAGE_GET_DEVICE_NUMBER CTL_CODE(IOCTL_STORAGE_BASE, 0x0420, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_STORAGE_PREDICT_FAILURE CTL_CODE(IOCTL_STORAGE_BASE, 0x0440, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// end_winioctl - - -#define IOCTL_STORAGE_QUERY_PROPERTY CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS) - - -// begin_winioctl - -// -// These ioctl codes are obsolete. They are defined here to avoid resuing them -// and to allow class drivers to respond to them more easily. -// - -#define OBSOLETE_IOCTL_STORAGE_RESET_BUS CTL_CODE(IOCTL_STORAGE_BASE, 0x0400, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) -#define OBSOLETE_IOCTL_STORAGE_RESET_DEVICE CTL_CODE(IOCTL_STORAGE_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) - - -// -// IOCTL_STORAGE_GET_HOTPLUG_INFO -// - -typedef struct _STORAGE_HOTPLUG_INFO { - ULONG Size; // version - BOOLEAN MediaRemovable; // ie. zip, jaz, cdrom, mo, etc. vs hdd - BOOLEAN MediaHotplug; // ie. does the device succeed a lock even though its not lockable media? - BOOLEAN DeviceHotplug; // ie. 1394, USB, etc. - BOOLEAN WriteCacheEnableOverride; // This field should not be relied upon because it is no longer used -} STORAGE_HOTPLUG_INFO, *PSTORAGE_HOTPLUG_INFO; - -// -// IOCTL_STORAGE_GET_DEVICE_NUMBER -// -// input - none -// -// output - STORAGE_DEVICE_NUMBER structure -// The values in the STORAGE_DEVICE_NUMBER structure are guaranteed -// to remain unchanged until the system is rebooted. They are not -// guaranteed to be persistant across boots. -// - -typedef struct _STORAGE_DEVICE_NUMBER { - - // - // The FILE_DEVICE_XXX type for this device. - // - - DEVICE_TYPE DeviceType; - - // - // The number of this device - // - - ULONG DeviceNumber; - - // - // If the device is partitionable, the partition number of the device. - // Otherwise -1 - // - - ULONG PartitionNumber; -} STORAGE_DEVICE_NUMBER, *PSTORAGE_DEVICE_NUMBER; - -// -// Define the structures for scsi resets -// - -typedef struct _STORAGE_BUS_RESET_REQUEST { - UCHAR PathId; -} STORAGE_BUS_RESET_REQUEST, *PSTORAGE_BUS_RESET_REQUEST; - -// -// IOCTL_STORAGE_MEDIA_REMOVAL disables the mechanism -// on a storage device that ejects media. This function -// may or may not be supported on storage devices that -// support removable media. -// -// TRUE means prevent media from being removed. -// FALSE means allow media removal. -// -#if defined (_MSC_VER) /* MS Visual C++ */ -typedef struct _PREVENT_MEDIA_REMOVAL { - BOOLEAN PreventMediaRemoval; -} PREVENT_MEDIA_REMOVAL, *PPREVENT_MEDIA_REMOVAL; -#endif - -// begin_ntminitape - - -typedef struct _TAPE_STATISTICS { - ULONG Version; - ULONG Flags; - LARGE_INTEGER RecoveredWrites; - LARGE_INTEGER UnrecoveredWrites; - LARGE_INTEGER RecoveredReads; - LARGE_INTEGER UnrecoveredReads; - UCHAR CompressionRatioReads; - UCHAR CompressionRatioWrites; -} TAPE_STATISTICS, *PTAPE_STATISTICS; - -#define RECOVERED_WRITES_VALID 0x00000001 -#define UNRECOVERED_WRITES_VALID 0x00000002 -#define RECOVERED_READS_VALID 0x00000004 -#define UNRECOVERED_READS_VALID 0x00000008 -#define WRITE_COMPRESSION_INFO_VALID 0x00000010 -#define READ_COMPRESSION_INFO_VALID 0x00000020 - -typedef struct _TAPE_GET_STATISTICS { - ULONG Operation; -} TAPE_GET_STATISTICS, *PTAPE_GET_STATISTICS; - -#define TAPE_RETURN_STATISTICS 0L -#define TAPE_RETURN_ENV_INFO 1L -#define TAPE_RESET_STATISTICS 2L - -// -// IOCTL_STORAGE_GET_MEDIA_TYPES_EX will return an array of DEVICE_MEDIA_INFO -// structures, one per supported type, embedded in the GET_MEDIA_TYPES struct. -// - -typedef enum _STORAGE_MEDIA_TYPE { - // - // Following are defined in ntdddisk.h in the MEDIA_TYPE enum - // - // Unknown, // Format is unknown - // F5_1Pt2_512, // 5.25", 1.2MB, 512 bytes/sector - // F3_1Pt44_512, // 3.5", 1.44MB, 512 bytes/sector - // F3_2Pt88_512, // 3.5", 2.88MB, 512 bytes/sector - // F3_20Pt8_512, // 3.5", 20.8MB, 512 bytes/sector - // F3_720_512, // 3.5", 720KB, 512 bytes/sector - // F5_360_512, // 5.25", 360KB, 512 bytes/sector - // F5_320_512, // 5.25", 320KB, 512 bytes/sector - // F5_320_1024, // 5.25", 320KB, 1024 bytes/sector - // F5_180_512, // 5.25", 180KB, 512 bytes/sector - // F5_160_512, // 5.25", 160KB, 512 bytes/sector - // RemovableMedia, // Removable media other than floppy - // FixedMedia, // Fixed hard disk media - // F3_120M_512, // 3.5", 120M Floppy - // F3_640_512, // 3.5" , 640KB, 512 bytes/sector - // F5_640_512, // 5.25", 640KB, 512 bytes/sector - // F5_720_512, // 5.25", 720KB, 512 bytes/sector - // F3_1Pt2_512, // 3.5" , 1.2Mb, 512 bytes/sector - // F3_1Pt23_1024, // 3.5" , 1.23Mb, 1024 bytes/sector - // F5_1Pt23_1024, // 5.25", 1.23MB, 1024 bytes/sector - // F3_128Mb_512, // 3.5" MO 128Mb 512 bytes/sector - // F3_230Mb_512, // 3.5" MO 230Mb 512 bytes/sector - // F8_256_128, // 8", 256KB, 128 bytes/sector - // F3_200Mb_512, // 3.5", 200M Floppy (HiFD) - // - - DDS_4mm = 0x20, // Tape - DAT DDS1,2,... (all vendors) - MiniQic, // Tape - miniQIC Tape - Travan, // Tape - Travan TR-1,2,3,... - QIC, // Tape - QIC - MP_8mm, // Tape - 8mm Exabyte Metal Particle - AME_8mm, // Tape - 8mm Exabyte Advanced Metal Evap - AIT1_8mm, // Tape - 8mm Sony AIT - DLT, // Tape - DLT Compact IIIxt, IV - NCTP, // Tape - Philips NCTP - IBM_3480, // Tape - IBM 3480 - IBM_3490E, // Tape - IBM 3490E - IBM_Magstar_3590, // Tape - IBM Magstar 3590 - IBM_Magstar_MP, // Tape - IBM Magstar MP - STK_DATA_D3, // Tape - STK Data D3 - SONY_DTF, // Tape - Sony DTF - DV_6mm, // Tape - 6mm Digital Video - DMI, // Tape - Exabyte DMI and compatibles - SONY_D2, // Tape - Sony D2S and D2L - CLEANER_CARTRIDGE, // Cleaner - All Drive types that support Drive Cleaners - CD_ROM, // Opt_Disk - CD - CD_R, // Opt_Disk - CD-Recordable (Write Once) - CD_RW, // Opt_Disk - CD-Rewriteable - DVD_ROM, // Opt_Disk - DVD-ROM - DVD_R, // Opt_Disk - DVD-Recordable (Write Once) - DVD_RW, // Opt_Disk - DVD-Rewriteable - MO_3_RW, // Opt_Disk - 3.5" Rewriteable MO Disk - MO_5_WO, // Opt_Disk - MO 5.25" Write Once - MO_5_RW, // Opt_Disk - MO 5.25" Rewriteable (not LIMDOW) - MO_5_LIMDOW, // Opt_Disk - MO 5.25" Rewriteable (LIMDOW) - PC_5_WO, // Opt_Disk - Phase Change 5.25" Write Once Optical - PC_5_RW, // Opt_Disk - Phase Change 5.25" Rewriteable - PD_5_RW, // Opt_Disk - PhaseChange Dual Rewriteable - ABL_5_WO, // Opt_Disk - Ablative 5.25" Write Once Optical - PINNACLE_APEX_5_RW, // Opt_Disk - Pinnacle Apex 4.6GB Rewriteable Optical - SONY_12_WO, // Opt_Disk - Sony 12" Write Once - PHILIPS_12_WO, // Opt_Disk - Philips/LMS 12" Write Once - HITACHI_12_WO, // Opt_Disk - Hitachi 12" Write Once - CYGNET_12_WO, // Opt_Disk - Cygnet/ATG 12" Write Once - KODAK_14_WO, // Opt_Disk - Kodak 14" Write Once - MO_NFR_525, // Opt_Disk - Near Field Recording (Terastor) - NIKON_12_RW, // Opt_Disk - Nikon 12" Rewriteable - IOMEGA_ZIP, // Mag_Disk - Iomega Zip - IOMEGA_JAZ, // Mag_Disk - Iomega Jaz - SYQUEST_EZ135, // Mag_Disk - Syquest EZ135 - SYQUEST_EZFLYER, // Mag_Disk - Syquest EzFlyer - SYQUEST_SYJET, // Mag_Disk - Syquest SyJet - AVATAR_F2, // Mag_Disk - 2.5" Floppy - MP2_8mm, // Tape - 8mm Hitachi - DST_S, // Ampex DST Small Tapes - DST_M, // Ampex DST Medium Tapes - DST_L, // Ampex DST Large Tapes - VXATape_1, // Ecrix 8mm Tape - VXATape_2, // Ecrix 8mm Tape - STK_9840, // STK 9840 - LTO_Ultrium, // IBM, HP, Seagate LTO Ultrium - LTO_Accelis, // IBM, HP, Seagate LTO Accelis - DVD_RAM, // Opt_Disk - DVD-RAM - AIT_8mm, // AIT2 or higher - ADR_1, // OnStream ADR Mediatypes - ADR_2 -} STORAGE_MEDIA_TYPE, *PSTORAGE_MEDIA_TYPE; - -#define MEDIA_ERASEABLE 0x00000001 -#define MEDIA_WRITE_ONCE 0x00000002 -#define MEDIA_READ_ONLY 0x00000004 -#define MEDIA_READ_WRITE 0x00000008 - -#define MEDIA_WRITE_PROTECTED 0x00000100 -#define MEDIA_CURRENTLY_MOUNTED 0x80000000 - -// -// Define the different storage bus types -// Bus types below 128 (0x80) are reserved for Microsoft use -// - -typedef enum _STORAGE_BUS_TYPE { - BusTypeUnknown = 0x00, - BusTypeScsi, - BusTypeAtapi, - BusTypeAta, - BusType1394, - BusTypeSsa, - BusTypeFibre, - BusTypeUsb, - BusTypeRAID, - BusTypeMaxReserved = 0x7F -} STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE; - -typedef struct _DEVICE_MEDIA_INFO { - union { - struct { - LARGE_INTEGER Cylinders; - STORAGE_MEDIA_TYPE MediaType; - ULONG TracksPerCylinder; - ULONG SectorsPerTrack; - ULONG BytesPerSector; - ULONG NumberMediaSides; - ULONG MediaCharacteristics; // Bitmask of MEDIA_XXX values. - } DiskInfo; - - struct { - LARGE_INTEGER Cylinders; - STORAGE_MEDIA_TYPE MediaType; - ULONG TracksPerCylinder; - ULONG SectorsPerTrack; - ULONG BytesPerSector; - ULONG NumberMediaSides; - ULONG MediaCharacteristics; // Bitmask of MEDIA_XXX values. - } RemovableDiskInfo; - - struct { - STORAGE_MEDIA_TYPE MediaType; - ULONG MediaCharacteristics; // Bitmask of MEDIA_XXX values. - ULONG CurrentBlockSize; - STORAGE_BUS_TYPE BusType; - - // - // Bus specific information describing the medium supported. - // - - union { - struct { - UCHAR MediumType; - UCHAR DensityCode; - } ScsiInformation; - } BusSpecificData; - - } TapeInfo; - } DeviceSpecific; -} DEVICE_MEDIA_INFO, *PDEVICE_MEDIA_INFO; - -typedef struct _GET_MEDIA_TYPES { - ULONG DeviceType; // FILE_DEVICE_XXX values - ULONG MediaInfoCount; - DEVICE_MEDIA_INFO MediaInfo[1]; -} GET_MEDIA_TYPES, *PGET_MEDIA_TYPES; - - -// -// IOCTL_STORAGE_PREDICT_FAILURE -// -// input - none -// -// output - STORAGE_PREDICT_FAILURE structure -// PredictFailure returns zero if no failure predicted and non zero -// if a failure is predicted. -// -// VendorSpecific returns 512 bytes of vendor specific information -// if a failure is predicted -// -typedef struct _STORAGE_PREDICT_FAILURE -{ - ULONG PredictFailure; - UCHAR VendorSpecific[512]; -} STORAGE_PREDICT_FAILURE, *PSTORAGE_PREDICT_FAILURE; - -// end_ntminitape -// end_winioctl - -// -// Property Query Structures -// - -// -// IOCTL_STORAGE_QUERY_PROPERTY -// -// Input Buffer: -// a STORAGE_PROPERTY_QUERY structure which describes what type of query -// is being done, what property is being queried for, and any additional -// parameters which a particular property query requires. -// -// Output Buffer: -// Contains a buffer to place the results of the query into. Since all -// property descriptors can be cast into a STORAGE_DESCRIPTOR_HEADER, -// the IOCTL can be called once with a small buffer then again using -// a buffer as large as the header reports is necessary. -// - - -// -// Types of queries -// - -typedef enum _STORAGE_QUERY_TYPE { - PropertyStandardQuery = 0, // Retrieves the descriptor - PropertyExistsQuery, // Used to test whether the descriptor is supported - PropertyMaskQuery, // Used to retrieve a mask of writeable fields in the descriptor - PropertyQueryMaxDefined // use to validate the value -} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE; - -// -// define some initial property id's -// - -typedef enum _STORAGE_PROPERTY_ID { - StorageDeviceProperty = 0, - StorageAdapterProperty, - StorageDeviceIdProperty -} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID; - -// -// Query structure - additional parameters for specific queries can follow -// the header -// - -typedef struct _STORAGE_PROPERTY_QUERY { - - // - // ID of the property being retrieved - // - - STORAGE_PROPERTY_ID PropertyId; - - // - // Flags indicating the type of query being performed - // - - STORAGE_QUERY_TYPE QueryType; - - // - // Space for additional parameters if necessary - // - - UCHAR AdditionalParameters[1]; - -} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY; - -// -// Standard property descriptor header. All property pages should use this -// as their first element or should contain these two elements -// - -typedef struct _STORAGE_DESCRIPTOR_HEADER { - - ULONG Version; - - ULONG Size; - -} STORAGE_DESCRIPTOR_HEADER, *PSTORAGE_DESCRIPTOR_HEADER; - -// -// Device property descriptor - this is really just a rehash of the inquiry -// data retrieved from a scsi device -// -// This may only be retrieved from a target device. Sending this to the bus -// will result in an error -// - -typedef struct _STORAGE_DEVICE_DESCRIPTOR { - - // - // Sizeof(STORAGE_DEVICE_DESCRIPTOR) - // - - ULONG Version; - - // - // Total size of the descriptor, including the space for additional - // data and id strings - // - - ULONG Size; - - // - // The SCSI-2 device type - // - - UCHAR DeviceType; - - // - // The SCSI-2 device type modifier (if any) - this may be zero - // - - UCHAR DeviceTypeModifier; - - // - // Flag indicating whether the device's media (if any) is removable. This - // field should be ignored for media-less devices - // - - BOOLEAN RemovableMedia; - - // - // Flag indicating whether the device can support mulitple outstanding - // commands. The actual synchronization in this case is the responsibility - // of the port driver. - // - - BOOLEAN CommandQueueing; - - // - // Byte offset to the zero-terminated ascii string containing the device's - // vendor id string. For devices with no such ID this will be zero - // - - ULONG VendorIdOffset; - - // - // Byte offset to the zero-terminated ascii string containing the device's - // product id string. For devices with no such ID this will be zero - // - - ULONG ProductIdOffset; - - // - // Byte offset to the zero-terminated ascii string containing the device's - // product revision string. For devices with no such string this will be - // zero - // - - ULONG ProductRevisionOffset; - - // - // Byte offset to the zero-terminated ascii string containing the device's - // serial number. For devices with no serial number this will be zero - // - - ULONG SerialNumberOffset; - - // - // Contains the bus type (as defined above) of the device. It should be - // used to interpret the raw device properties at the end of this structure - // (if any) - // - - STORAGE_BUS_TYPE BusType; - - // - // The number of bytes of bus-specific data which have been appended to - // this descriptor - // - - ULONG RawPropertiesLength; - - // - // Place holder for the first byte of the bus specific property data - // - - UCHAR RawDeviceProperties[1]; - -} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR; - - -// -// Adapter properties -// -// This descriptor can be retrieved from a target device object of from the -// device object for the bus. Retrieving from the target device object will -// forward the request to the underlying bus -// - -typedef struct _STORAGE_ADAPTER_DESCRIPTOR { - - ULONG Version; - - ULONG Size; - - ULONG MaximumTransferLength; - - ULONG MaximumPhysicalPages; - - ULONG AlignmentMask; - - BOOLEAN AdapterUsesPio; - - BOOLEAN AdapterScansDown; - - BOOLEAN CommandQueueing; - - BOOLEAN AcceleratedTransfer; - - UCHAR BusType; - - USHORT BusMajorVersion; - - USHORT BusMinorVersion; - -} STORAGE_ADAPTER_DESCRIPTOR, *PSTORAGE_ADAPTER_DESCRIPTOR; - -// -// Storage identification descriptor. -// The definitions here are based on the SCSI/SBP vital product data -// device identifier page. -// - -typedef enum _STORAGE_IDENTIFIER_CODE_SET { - StorageIdCodeSetReserved = 0, - StorageIdCodeSetBinary = 1, - StorageIdCodeSetAscii = 2 -} STORAGE_IDENTIFIER_CODE_SET, *PSTORAGE_IDENTIFIER_CODE_SET; - -typedef enum _STORAGE_IDENTIFIER_TYPE { - StorageIdTypeVendorSpecific = 0, - StorageIdTypeVendorId = 1, - StorageIdTypeEUI64 = 2, - StorageIdTypeFCPHName = 3, - StorageIdTypePortRelative = 4 -} STORAGE_IDENTIFIER_TYPE, *PSTORAGE_IDENTIFIER_TYPE; - -typedef enum _STORAGE_ASSOCIATION_TYPE { - StorageIdAssocDevice = 0, - StorageIdAssocPort = 1 -} STORAGE_ASSOCIATION_TYPE, *PSTORAGE_ASSOCIATION_TYPE; - -typedef struct _STORAGE_IDENTIFIER { - STORAGE_IDENTIFIER_CODE_SET CodeSet; - STORAGE_IDENTIFIER_TYPE Type; - USHORT IdentifierSize; - USHORT NextOffset; - - // - // Add new fields here since existing code depends on - // the above layout not changing. - // - - STORAGE_ASSOCIATION_TYPE Association; - - // - // The identifier is a variable length array of bytes. - // - - UCHAR Identifier[1]; -} STORAGE_IDENTIFIER, *PSTORAGE_IDENTIFIER; - -typedef struct _STORAGE_DEVICE_ID_DESCRIPTOR { - - ULONG Version; - - ULONG Size; - - // - // The number of identifiers reported by the device. - // - - ULONG NumberOfIdentifiers; - - // - // The following field is actually a variable length array of identification - // descriptors. Unfortunately there's no C notation for an array of - // variable length structures so we're forced to just pretend. - // - - UCHAR Identifiers[1]; -} STORAGE_DEVICE_ID_DESCRIPTOR, *PSTORAGE_DEVICE_ID_DESCRIPTOR; - - -#pragma warning(push) -#pragma warning(disable:4200) -typedef struct _STORAGE_MEDIA_SERIAL_NUMBER_DATA { - - USHORT Reserved; - - // - // the SerialNumberLength will be set to zero - // if the command is supported and the media - // does not have a valid serial number. - // - - USHORT SerialNumberLength; - - // - // the following data is binary, and is not guaranteed - // to be NULL terminated. this is an excercise for the - // caller. - // - - UCHAR SerialNumber[0]; - -} STORAGE_MEDIA_SERIAL_NUMBER_DATA, *PSTORAGE_MEDIA_SERIAL_NUMBER_DATA; -#pragma warning(push) - - -// begin_winioctl - -#ifdef __cplusplus -} -#endif - -#endif // _NTDDSTOR_H_ -// end_winioctl - diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index 62b92ce7..78565f9d 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -16,12 +16,18 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: cdrom_aspi_win32.cpp,v 1.7 2004-01-02 14:38:30 qbix79 Exp $ */ + #if defined (WIN32) #include #include "cdrom.h" -#include "scsidefs.h" // Aspi stuff +//Are actually system includes but leave for now +#include "ntddcdrm.h" +#include "ntddscsi.h" +//#include "scsi.h" // Aspi stuff +#include "scsidefs.h" #include "dosbox.h" // ***************************************************************** @@ -716,4 +722,4 @@ bool CDROM_Interface_Aspi::ReadSectors(PhysPt buffer, bool raw, unsigned long se return (s.SRB_Status==SS_COMP); }; -#endif \ No newline at end of file +#endif diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index ddff8925..b7eb1ef9 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: cdrom_ioctl_win32.cpp,v 1.7 2004-01-02 14:38:30 qbix79 Exp $ */ + #if defined (WIN32) // ***************************************************************** @@ -25,6 +27,7 @@ #include #include // Ioctl stuff #include +//Actually a system include but leave for now #include "ntddcdrm.h" // Ioctl stuff #include "cdrom.h" From 224a302f427a38df014bd7647589b540a919f56f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 Jan 2004 14:40:22 +0000 Subject: [PATCH 1443/4131] added for visual C users include backups(from mingw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1524 --- src/platform/visualc/Makefile.am | 2 +- src/platform/visualc/ntddcdrm.h | 352 +++++++++++++++++++++++++++++++ src/platform/visualc/ntddscsi.h | 176 ++++++++++++++++ src/platform/visualc/ntddstor.h | 338 +++++++++++++++++++++++++++++ 4 files changed, 867 insertions(+), 1 deletion(-) create mode 100644 src/platform/visualc/ntddcdrm.h create mode 100644 src/platform/visualc/ntddscsi.h create mode 100644 src/platform/visualc/ntddstor.h diff --git a/src/platform/visualc/Makefile.am b/src/platform/visualc/Makefile.am index 605cef90..aa491da5 100644 --- a/src/platform/visualc/Makefile.am +++ b/src/platform/visualc/Makefile.am @@ -1 +1 @@ -EXTRA_DIST = dirent.c dirent.h unistd.h config.h +EXTRA_DIST = dirent.c dirent.h unistd.h config.h ntddscsi.h ntddstor.h ntddcdrm.h diff --git a/src/platform/visualc/ntddcdrm.h b/src/platform/visualc/ntddcdrm.h new file mode 100644 index 00000000..e4d830fb --- /dev/null +++ b/src/platform/visualc/ntddcdrm.h @@ -0,0 +1,352 @@ +/* + * ntddcdrm.h + * + * CDROM IOCTL interface. + * + * This file is part of the w32api package. + * + * Contributors: + * Created by Casper S. Hornstrup + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef __NTDDCDRM_H +#define __NTDDCDRM_H + +#if __GNUC__ >=3 +#pragma GCC system_header +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#pragma pack(push,4) + +#include "ntddk.h" +#include "ntddstor.h" + + +#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM + +#define IOCTL_CDROM_CHECK_VERIFY \ + CTL_CODE(IOCTL_CDROM_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_CDROM_FIND_NEW_DEVICES \ + CTL_CODE(IOCTL_CDROM_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_CDROM_GET_CONTROL \ + CTL_CODE(IOCTL_CDROM_BASE, 0x000D, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_CDROM_GET_DRIVE_GEOMETRY \ + CTL_CODE(IOCTL_CDROM_BASE, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_CDROM_GET_LAST_SESSION \ + CTL_CODE(IOCTL_CDROM_BASE, 0x000E, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_CDROM_GET_VOLUME \ + CTL_CODE(IOCTL_CDROM_BASE, 0x0005, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_CDROM_PAUSE_AUDIO \ + CTL_CODE(IOCTL_CDROM_BASE, 0x0003, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_CDROM_PLAY_AUDIO_MSF \ + CTL_CODE(IOCTL_CDROM_BASE, 0x0006, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_CDROM_RAW_READ \ + CTL_CODE(IOCTL_CDROM_BASE, 0x000F, METHOD_OUT_DIRECT, FILE_READ_ACCESS) + +#define IOCTL_CDROM_READ_Q_CHANNEL \ + CTL_CODE(IOCTL_CDROM_BASE, 0x000B, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_CDROM_READ_TOC \ + CTL_CODE(IOCTL_CDROM_BASE, 0x0000, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_CDROM_READ_TOC_EX \ + CTL_CODE(IOCTL_CDROM_BASE, 0x0015, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_CDROM_RESUME_AUDIO \ + CTL_CODE(IOCTL_CDROM_BASE, 0x0004, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_CDROM_SEEK_AUDIO_MSF \ + CTL_CODE(IOCTL_CDROM_BASE, 0x0001, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_CDROM_SET_VOLUME \ + CTL_CODE(IOCTL_CDROM_BASE, 0x000A, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_CDROM_SIMBAD \ + CTL_CODE(IOCTL_CDROM_BASE, 0x1003, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_CDROM_STOP_AUDIO \ + CTL_CODE(IOCTL_CDROM_BASE, 0x0002, METHOD_BUFFERED, FILE_READ_ACCESS) + + +#define MAXIMUM_NUMBER_TRACKS 100 +#define MAXIMUM_CDROM_SIZE 804 +#define MINIMUM_CDROM_READ_TOC_EX_SIZE 2 + +typedef struct _TRACK_DATA { + UCHAR Reserved; + UCHAR Control : 4; + UCHAR Adr : 4; + UCHAR TrackNumber; + UCHAR Reserved1; + UCHAR Address[4]; +} TRACK_DATA, *PTRACK_DATA; + +/* CDROM_DISK_DATA.DiskData flags */ +#define CDROM_DISK_AUDIO_TRACK 0x00000001 +#define CDROM_DISK_DATA_TRACK 0x00000002 + +typedef struct _CDROM_DISK_DATA { + ULONG DiskData; +} CDROM_DISK_DATA, *PCDROM_DISK_DATA; + +typedef struct _CDROM_PLAY_AUDIO_MSF { + UCHAR StartingM; + UCHAR StartingS; + UCHAR StartingF; + UCHAR EndingM; + UCHAR EndingS; + UCHAR EndingF; +} CDROM_PLAY_AUDIO_MSF, *PCDROM_PLAY_AUDIO_MSF; + +/* CDROM_READ_TOC_EX.Format constants */ +#define CDROM_READ_TOC_EX_FORMAT_TOC 0x00 +#define CDROM_READ_TOC_EX_FORMAT_SESSION 0x01 +#define CDROM_READ_TOC_EX_FORMAT_FULL_TOC 0x02 +#define CDROM_READ_TOC_EX_FORMAT_PMA 0x03 +#define CDROM_READ_TOC_EX_FORMAT_ATIP 0x04 +#define CDROM_READ_TOC_EX_FORMAT_CDTEXT 0x05 + +typedef struct _CDROM_READ_TOC_EX { + UCHAR Format : 4; + UCHAR Reserved1 : 3; + UCHAR Msf : 1; + UCHAR SessionTrack; + UCHAR Reserved2; + UCHAR Reserved3; +} CDROM_READ_TOC_EX, *PCDROM_READ_TOC_EX; + +typedef struct _CDROM_SEEK_AUDIO_MSF { + UCHAR M; + UCHAR S; + UCHAR F; +} CDROM_SEEK_AUDIO_MSF, *PCDROM_SEEK_AUDIO_MSF; + +/* CDROM_SUB_Q_DATA_FORMAT.Format constants */ +#define IOCTL_CDROM_SUB_Q_CHANNEL 0x00 +#define IOCTL_CDROM_CURRENT_POSITION 0x01 +#define IOCTL_CDROM_MEDIA_CATALOG 0x02 +#define IOCTL_CDROM_TRACK_ISRC 0x03 + +typedef struct _CDROM_SUB_Q_DATA_FORMAT { + UCHAR Format; + UCHAR Track; +} CDROM_SUB_Q_DATA_FORMAT, *PCDROM_SUB_Q_DATA_FORMAT; + +typedef struct _CDROM_TOC { + UCHAR Length[2]; + UCHAR FirstTrack; + UCHAR LastTrack; + TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS]; +} CDROM_TOC, *PCDROM_TOC; + +#define CDROM_TOC_SIZE sizeof(CDROM_TOC) + +typedef struct _CDROM_TOC_ATIP_DATA_BLOCK { + UCHAR CdrwReferenceSpeed : 3; + UCHAR Reserved3 : 1; + UCHAR WritePower : 3; + UCHAR True1 : 1; + UCHAR Reserved4 : 6; + UCHAR UnrestrictedUse : 1; + UCHAR Reserved5 : 1; + UCHAR A3Valid : 1; + UCHAR A2Valid : 1; + UCHAR A1Valid : 1; + UCHAR Reserved6 : 3; + UCHAR IsCdrw : 1; + UCHAR True2 : 1; + UCHAR Reserved7; + UCHAR LeadInMsf[3]; + UCHAR Reserved8; + UCHAR LeadOutMsf[3]; + UCHAR Reserved9; + UCHAR A1Values[3]; + UCHAR Reserved10; + UCHAR A2Values[3]; + UCHAR Reserved11; + UCHAR A3Values[3]; + UCHAR Reserved12; +} CDROM_TOC_ATIP_DATA_BLOCK, *PCDROM_TOC_ATIP_DATA_BLOCK; + +typedef struct _CDROM_TOC_ATIP_DATA { + UCHAR Length[2]; + UCHAR Reserved1; + UCHAR Reserved2; + CDROM_TOC_ATIP_DATA_BLOCK Descriptors[0]; +} CDROM_TOC_ATIP_DATA, *PCDROM_TOC_ATIP_DATA; + +/* CDROM_TOC_CD_TEXT_DATA_BLOCK.PackType constants */ +#define CDROM_CD_TEXT_PACK_ALBUM_NAME 0x80 +#define CDROM_CD_TEXT_PACK_PERFORMER 0x81 +#define CDROM_CD_TEXT_PACK_SONGWRITER 0x82 +#define CDROM_CD_TEXT_PACK_COMPOSER 0x83 +#define CDROM_CD_TEXT_PACK_ARRANGER 0x84 +#define CDROM_CD_TEXT_PACK_MESSAGES 0x85 +#define CDROM_CD_TEXT_PACK_DISC_ID 0x86 +#define CDROM_CD_TEXT_PACK_GENRE 0x87 +#define CDROM_CD_TEXT_PACK_TOC_INFO 0x88 +#define CDROM_CD_TEXT_PACK_TOC_INFO2 0x89 +#define CDROM_CD_TEXT_PACK_UPC_EAN 0x8e +#define CDROM_CD_TEXT_PACK_SIZE_INFO 0x8f + +typedef struct _CDROM_TOC_CD_TEXT_DATA_BLOCK { + UCHAR PackType; + UCHAR TrackNumber : 7; + UCHAR ExtensionFlag : 1; + UCHAR SequenceNumber; + UCHAR CharacterPosition : 4; + UCHAR BlockNumber : 3; + UCHAR Unicode : 1; + union { + UCHAR Text[12]; + WCHAR WText[6]; + }; + UCHAR CRC[2]; +} CDROM_TOC_CD_TEXT_DATA_BLOCK, *PCDROM_TOC_CD_TEXT_DATA_BLOCK; + +typedef struct _CDROM_TOC_CD_TEXT_DATA { + UCHAR Length[2]; + UCHAR Reserved1; + UCHAR Reserved2; + CDROM_TOC_CD_TEXT_DATA_BLOCK Descriptors[0]; +} CDROM_TOC_CD_TEXT_DATA, *PCDROM_TOC_CD_TEXT_DATA; + +/* CDROM_TOC_FULL_TOC_DATA_BLOCK.Adr constants */ +#define ADR_NO_MODE_INFORMATION 0x0 +#define ADR_ENCODES_CURRENT_POSITION 0x1 +#define ADR_ENCODES_MEDIA_CATALOG 0x2 +#define ADR_ENCODES_ISRC 0x3 + +typedef struct _CDROM_TOC_FULL_TOC_DATA_BLOCK { + UCHAR SessionNumber; + UCHAR Control : 4; + UCHAR Adr : 4; + UCHAR Reserved1; + UCHAR Point; + UCHAR MsfExtra[3]; + UCHAR Zero; + UCHAR Msf[3]; +} CDROM_TOC_FULL_TOC_DATA_BLOCK, *PCDROM_TOC_FULL_TOC_DATA_BLOCK; + +typedef struct _CDROM_TOC_FULL_TOC_DATA { + UCHAR Length[2]; + UCHAR FirstCompleteSession; + UCHAR LastCompleteSession; + CDROM_TOC_FULL_TOC_DATA_BLOCK Descriptors[0]; +} CDROM_TOC_FULL_TOC_DATA, *PCDROM_TOC_FULL_TOC_DATA; + +typedef struct _CDROM_TOC_PMA_DATA { + UCHAR Length[2]; + UCHAR Reserved1; + UCHAR Reserved2; + CDROM_TOC_FULL_TOC_DATA_BLOCK Descriptors[0]; +} CDROM_TOC_PMA_DATA, *PCDROM_TOC_PMA_DATA; + +/* SUB_Q_HEADER.AudioStatus constants */ +#define AUDIO_STATUS_NOT_SUPPORTED 0x00 +#define AUDIO_STATUS_IN_PROGRESS 0x11 +#define AUDIO_STATUS_PAUSED 0x12 +#define AUDIO_STATUS_PLAY_COMPLETE 0x13 +#define AUDIO_STATUS_PLAY_ERROR 0x14 +#define AUDIO_STATUS_NO_STATUS 0x15 + +typedef struct _SUB_Q_HEADER { + UCHAR Reserved; + UCHAR AudioStatus; + UCHAR DataLength[2]; +} SUB_Q_HEADER, *PSUB_Q_HEADER; + +typedef struct _SUB_Q_MEDIA_CATALOG_NUMBER { + SUB_Q_HEADER Header; + UCHAR FormatCode; + UCHAR Reserved[3]; + UCHAR Reserved1 : 7; + UCHAR Mcval :1; + UCHAR MediaCatalog[15]; +} SUB_Q_MEDIA_CATALOG_NUMBER, *PSUB_Q_MEDIA_CATALOG_NUMBER; + +typedef struct _SUB_Q_TRACK_ISRC { + SUB_Q_HEADER Header; + UCHAR FormatCode; + UCHAR Reserved0; + UCHAR Track; + UCHAR Reserved1; + UCHAR Reserved2 : 7; + UCHAR Tcval : 1; + UCHAR TrackIsrc[15]; +} SUB_Q_TRACK_ISRC, *PSUB_Q_TRACK_ISRC; + +typedef struct _SUB_Q_CURRENT_POSITION { + SUB_Q_HEADER Header; + UCHAR FormatCode; + UCHAR Control : 4; + UCHAR ADR : 4; + UCHAR TrackNumber; + UCHAR IndexNumber; + UCHAR AbsoluteAddress[4]; + UCHAR TrackRelativeAddress[4]; +} SUB_Q_CURRENT_POSITION, *PSUB_Q_CURRENT_POSITION; + +typedef union _SUB_Q_CHANNEL_DATA { + SUB_Q_CURRENT_POSITION CurrentPosition; + SUB_Q_MEDIA_CATALOG_NUMBER MediaCatalog; + SUB_Q_TRACK_ISRC TrackIsrc; +} SUB_Q_CHANNEL_DATA, *PSUB_Q_CHANNEL_DATA; + +/* CDROM_AUDIO_CONTROL.LbaFormat constants */ +#define AUDIO_WITH_PREEMPHASIS 0x1 +#define DIGITAL_COPY_PERMITTED 0x2 +#define AUDIO_DATA_TRACK 0x4 +#define TWO_FOUR_CHANNEL_AUDIO 0x8 + +typedef struct _CDROM_AUDIO_CONTROL { + UCHAR LbaFormat; + USHORT LogicalBlocksPerSecond; +} CDROM_AUDIO_CONTROL, *PCDROM_AUDIO_CONTROL; + +typedef struct _VOLUME_CONTROL { + UCHAR PortVolume[4]; +} VOLUME_CONTROL, *PVOLUME_CONTROL; + +typedef enum _TRACK_MODE_TYPE { + YellowMode2, + XAForm2, + CDDA +} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE; + +typedef struct __RAW_READ_INFO { + LARGE_INTEGER DiskOffset; + ULONG SectorCount; + TRACK_MODE_TYPE TrackMode; +} RAW_READ_INFO, *PRAW_READ_INFO; + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif + +#endif /* __NTDDCDRM_H */ diff --git a/src/platform/visualc/ntddscsi.h b/src/platform/visualc/ntddscsi.h new file mode 100644 index 00000000..c580ae3c --- /dev/null +++ b/src/platform/visualc/ntddscsi.h @@ -0,0 +1,176 @@ +/* + * ntddscsi.h + * + * SCSI port IOCTL interface. + * + * This file is part of the w32api package. + * + * Contributors: + * Created by Casper S. Hornstrup + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef __NTDDSCSI_H +#define __NTDDSCSI_H + +#if __GNUC__ >=3 +#pragma GCC system_header +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#pragma pack(push,4) + +#include "ntddk.h" + + +#define DD_SCSI_DEVICE_NAME "\\Device\\ScsiPort" +#define DD_SCSI_DEVICE_NAME_U L"\\Device\\ScsiPort" + +#define IOCTL_SCSI_BASE FILE_DEVICE_CONTROLLER + +#define IOCTL_SCSI_GET_INQUIRY_DATA \ + CTL_CODE(IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_SCSI_GET_CAPABILITIES \ + CTL_CODE(IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_SCSI_GET_ADDRESS \ + CTL_CODE(IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_SCSI_MINIPORT \ + CTL_CODE(IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) + +#define IOCTL_SCSI_PASS_THROUGH \ + CTL_CODE(IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) + +#define IOCTL_SCSI_PASS_THROUGH_DIRECT \ + CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) + +#define IOCTL_SCSI_RESCAN_BUS \ + CTL_CODE(IOCTL_SCSI_BASE, 0x0407, METHOD_BUFFERED, FILE_ANY_ACCESS) + + +DEFINE_GUID(ScsiRawInterfaceGuid, \ + 0x53f56309L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); + +DEFINE_GUID(WmiScsiAddressGuid, \ + 0x53f5630fL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); + +typedef struct _SCSI_PASS_THROUGH { + USHORT Length; + UCHAR ScsiStatus; + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; + UCHAR CdbLength; + UCHAR SenseInfoLength; + UCHAR DataIn; + ULONG DataTransferLength; + ULONG TimeOutValue; + ULONG_PTR DataBufferOffset; + ULONG SenseInfoOffset; + UCHAR Cdb[16]; +} SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH; + +typedef struct _SCSI_PASS_THROUGH_DIRECT { + USHORT Length; + UCHAR ScsiStatus; + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; + UCHAR CdbLength; + UCHAR SenseInfoLength; + UCHAR DataIn; + ULONG DataTransferLength; + ULONG TimeOutValue; + PVOID DataBuffer; + ULONG SenseInfoOffset; + UCHAR Cdb[16]; +} SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT; + +typedef struct _SRB_IO_CONTROL { + ULONG HeaderLength; + UCHAR Signature[8]; + ULONG Timeout; + ULONG ControlCode; + ULONG ReturnCode; + ULONG Length; +} SRB_IO_CONTROL, *PSRB_IO_CONTROL; + +typedef struct _SCSI_ADDRESS { + ULONG Length; + UCHAR PortNumber; + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; +} SCSI_ADDRESS, *PSCSI_ADDRESS; + +typedef struct _SCSI_BUS_DATA { + UCHAR NumberOfLogicalUnits; + UCHAR InitiatorBusId; + ULONG InquiryDataOffset; +}SCSI_BUS_DATA, *PSCSI_BUS_DATA; + +typedef struct _SCSI_ADAPTER_BUS_INFO { + UCHAR NumberOfBuses; + SCSI_BUS_DATA BusData[1]; +} SCSI_ADAPTER_BUS_INFO, *PSCSI_ADAPTER_BUS_INFO; + +typedef struct _IO_SCSI_CAPABILITIES { + ULONG Length; + ULONG MaximumTransferLength; + ULONG MaximumPhysicalPages; + ULONG SupportedAsynchronousEvents; + ULONG AlignmentMask; + BOOLEAN TaggedQueuing; + BOOLEAN AdapterScansDown; + BOOLEAN AdapterUsesPio; +} IO_SCSI_CAPABILITIES, *PIO_SCSI_CAPABILITIES; + +typedef struct _SCSI_INQUIRY_DATA { + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; + BOOLEAN DeviceClaimed; + ULONG InquiryDataLength; + ULONG NextInquiryDataOffset; + UCHAR InquiryData[1]; +} SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA; + +#define SCSI_IOCTL_DATA_OUT 0 +#define SCSI_IOCTL_DATA_IN 1 +#define SCSI_IOCTL_DATA_UNSPECIFIED 2 + +typedef struct _DUMP_POINTERS { + PADAPTER_OBJECT AdapterObject; + PVOID MappedRegisterBase; + PVOID DumpData; + PVOID CommonBufferVa; + LARGE_INTEGER CommonBufferPa; + ULONG CommonBufferSize; + BOOLEAN AllocateCommonBuffers; + BOOLEAN UseDiskDump; + UCHAR Spare1[2]; + PVOID DeviceObject; +} DUMP_POINTERS, *PDUMP_POINTERS; + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif + +#endif /* __NTDDSCSI_H */ diff --git a/src/platform/visualc/ntddstor.h b/src/platform/visualc/ntddstor.h new file mode 100644 index 00000000..6875cd19 --- /dev/null +++ b/src/platform/visualc/ntddstor.h @@ -0,0 +1,338 @@ +/* + * ntddstor.h + * + * Storage class IOCTL interface. + * + * This file is part of the w32api package. + * + * Contributors: + * Created by Casper S. Hornstrup + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef __NTDDSTOR_H +#define __NTDDSTOR_H + +#if __GNUC__ >=3 +#pragma GCC system_header +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#pragma pack(push,4) + +#include "ntddk.h" + + +#define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE + +#define IOCTL_STORAGE_CHECK_VERIFY \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_STORAGE_CHECK_VERIFY2 \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_STORAGE_EJECT_MEDIA \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_STORAGE_EJECTION_CONTROL \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0250, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_STORAGE_FIND_NEW_DEVICES \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_STORAGE_GET_DEVICE_NUMBER \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0420, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0304, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_STORAGE_GET_MEDIA_TYPES \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0300, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_STORAGE_GET_MEDIA_TYPES_EX \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0301, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_STORAGE_LOAD_MEDIA \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_STORAGE_LOAD_MEDIA2 \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_STORAGE_MCN_CONTROL \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0251, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_STORAGE_MEDIA_REMOVAL \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_STORAGE_PREDICT_FAILURE \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0440, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_STORAGE_QUERY_PROPERTY \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_STORAGE_RELEASE \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0205, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_STORAGE_RESERVE \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0204, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define IOCTL_STORAGE_RESET_BUS \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0400, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) + +#define IOCTL_STORAGE_RESET_DEVICE \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) + + +DEFINE_GUID(GUID_DEVINTERFACE_DISK, + 0x53f56307L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); + +DEFINE_GUID(GUID_DEVINTERFACE_CDROM, + 0x53f56308L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); + +DEFINE_GUID(GUID_DEVINTERFACE_PARTITION, + 0x53f5630aL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); + +DEFINE_GUID(GUID_DEVINTERFACE_TAPE, + 0x53f5630bL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); + +DEFINE_GUID(GUID_DEVINTERFACE_WRITEONCEDISK, + 0x53f5630cL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); + +DEFINE_GUID(GUID_DEVINTERFACE_VOLUME, + 0x53f5630dL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); + +DEFINE_GUID(GUID_DEVINTERFACE_MEDIUMCHANGER, + 0x53f56310L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); + +DEFINE_GUID(GUID_DEVINTERFACE_FLOPPY, + 0x53f56311L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); + +DEFINE_GUID(GUID_DEVINTERFACE_CDCHANGER, + 0x53f56312L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); + +DEFINE_GUID(GUID_DEVINTERFACE_STORAGEPORT, + 0x2accfe60L, 0xc130, 0x11d2, 0xb0, 0x82, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); + + +typedef enum _STORAGE_MEDIA_TYPE { + DDS_4mm = 0x20, + MiniQic, + Travan, + QIC, + MP_8mm, + AME_8mm, + AIT1_8mm, + DLT, + NCTP, + IBM_3480, + IBM_3490E, + IBM_Magstar_3590, + IBM_Magstar_MP, + STK_DATA_D3, + SONY_DTF, + DV_6mm, + DMI, + SONY_D2, + CLEANER_CARTRIDGE, + CD_ROM, + CD_R, + CD_RW, + DVD_ROM, + DVD_R, + DVD_RW, + MO_3_RW, + MO_5_WO, + MO_5_RW, + MO_5_LIMDOW, + PC_5_WO, + PC_5_RW, + PD_5_RW, + ABL_5_WO, + PINNACLE_APEX_5_RW, + SONY_12_WO, + PHILIPS_12_WO, + HITACHI_12_WO, + CYGNET_12_WO, + KODAK_14_WO, + MO_NFR_525, + NIKON_12_RW, + IOMEGA_ZIP, + IOMEGA_JAZ, + SYQUEST_EZ135, + SYQUEST_EZFLYER, + SYQUEST_SYJET, + AVATAR_F2, + MP2_8mm, + DST_S, + DST_M, + DST_L, + VXATape_1, + VXATape_2, + STK_9840, + LTO_Ultrium, + LTO_Accelis, + DVD_RAM, + AIT_8mm, + ADR_1, + ADR_2 +} STORAGE_MEDIA_TYPE, *PSTORAGE_MEDIA_TYPE; + +typedef enum _STORAGE_BUS_TYPE { + BusTypeUnknown = 0x00, + BusTypeScsi, + BusTypeAtapi, + BusTypeAta, + BusType1394, + BusTypeSsa, + BusTypeFibre, + BusTypeUsb, + BusTypeRAID, + BusTypeMaxReserved = 0x7F +} STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE; + +/* DEVICE_MEDIA_INFO.DeviceSpecific.DiskInfo.MediaCharacteristics constants */ +#define MEDIA_ERASEABLE 0x00000001 +#define MEDIA_WRITE_ONCE 0x00000002 +#define MEDIA_READ_ONLY 0x00000004 +#define MEDIA_READ_WRITE 0x00000008 +#define MEDIA_WRITE_PROTECTED 0x00000100 +#define MEDIA_CURRENTLY_MOUNTED 0x80000000 + +typedef struct _DEVICE_MEDIA_INFO { + union { + struct { + LARGE_INTEGER Cylinders; + STORAGE_MEDIA_TYPE MediaType; + ULONG TracksPerCylinder; + ULONG SectorsPerTrack; + ULONG BytesPerSector; + ULONG NumberMediaSides; + ULONG MediaCharacteristics; + } DiskInfo; + struct { + LARGE_INTEGER Cylinders; + STORAGE_MEDIA_TYPE MediaType; + ULONG TracksPerCylinder; + ULONG SectorsPerTrack; + ULONG BytesPerSector; + ULONG NumberMediaSides; + ULONG MediaCharacteristics; + } RemovableDiskInfo; + struct { + STORAGE_MEDIA_TYPE MediaType; + ULONG MediaCharacteristics; + ULONG CurrentBlockSize; + STORAGE_BUS_TYPE BusType; + union { + struct { + UCHAR MediumType; + UCHAR DensityCode; + } ScsiInformation; + } BusSpecificData; + } TapeInfo; + } DeviceSpecific; +} DEVICE_MEDIA_INFO, *PDEVICE_MEDIA_INFO; + +typedef struct _GET_MEDIA_TYPES { + ULONG DeviceType; + ULONG MediaInfoCount; + DEVICE_MEDIA_INFO MediaInfo[1]; +} GET_MEDIA_TYPES, *PGET_MEDIA_TYPES; + +typedef struct _STORAGE_ADAPTER_DESCRIPTOR { + ULONG Version; + ULONG Size; + ULONG MaximumTransferLength; + ULONG MaximumPhysicalPages; + ULONG AlignmentMask; + BOOLEAN AdapterUsesPio; + BOOLEAN AdapterScansDown; + BOOLEAN CommandQueueing; + BOOLEAN AcceleratedTransfer; + STORAGE_BUS_TYPE BusType; + USHORT BusMajorVersion; + USHORT BusMinorVersion; +} STORAGE_ADAPTER_DESCRIPTOR, *PSTORAGE_ADAPTER_DESCRIPTOR; + +typedef struct _STORAGE_BUS_RESET_REQUEST { + UCHAR PathId; +} STORAGE_BUS_RESET_REQUEST, *PSTORAGE_BUS_RESET_REQUEST; + +typedef struct _STORAGE_DESCRIPTOR_HEADER { + ULONG Version; + ULONG Size; +} STORAGE_DESCRIPTOR_HEADER, *PSTORAGE_DESCRIPTOR_HEADER; + +typedef struct _STORAGE_DEVICE_DESCRIPTOR { + ULONG Version; + ULONG Size; + UCHAR DeviceType; + UCHAR DeviceTypeModifier; + BOOLEAN RemovableMedia; + BOOLEAN CommandQueueing; + ULONG VendorIdOffset; + ULONG ProductIdOffset; + ULONG ProductRevisionOffset; + ULONG SerialNumberOffset; + STORAGE_BUS_TYPE BusType; + ULONG RawPropertiesLength; + UCHAR RawDeviceProperties[1]; +} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR; + +typedef struct _STORAGE_DEVICE_ID_DESCRIPTOR { + ULONG Version; + ULONG Size; + ULONG NumberOfIdentifiers; + UCHAR Identifiers[1]; +} STORAGE_DEVICE_ID_DESCRIPTOR, *PSTORAGE_DEVICE_ID_DESCRIPTOR; + +typedef struct _STORAGE_DEVICE_NUMBER { + DEVICE_TYPE DeviceType; + ULONG DeviceNumber; + ULONG PartitionNumber; +} STORAGE_DEVICE_NUMBER, *PSTORAGE_DEVICE_NUMBER; + +typedef struct _STORAGE_PREDICT_FAILURE { + ULONG PredictFailure; + UCHAR VendorSpecific[512]; +} STORAGE_PREDICT_FAILURE, *PSTORAGE_PREDICT_FAILURE; + +typedef enum _STORAGE_PROPERTY_ID { + StorageDeviceProperty = 0, + StorageAdapterProperty, + StorageDeviceIdProperty +} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID; + +typedef enum _STORAGE_QUERY_TYPE { + PropertyStandardQuery = 0, + PropertyExistsQuery, + PropertyMaskQuery, + PropertyQueryMaxDefined +} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE; + +typedef struct _STORAGE_PROPERTY_QUERY { + STORAGE_PROPERTY_ID PropertyId; + STORAGE_QUERY_TYPE QueryType; + UCHAR AdditionalParameters[1]; +} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY; + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif + +#endif /* __NTDDSTOR_H */ From aeb604f4d1ff845b7517e5c8b0de587da4e90bff Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 Jan 2004 18:47:13 +0000 Subject: [PATCH 1444/4131] Fixed reported doubleclicks while moving Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1525 --- src/ints/mouse.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index e249987c..2354de4e 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.27 2003-12-30 20:39:07 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.28 2004-01-02 18:47:13 qbix79 Exp $ */ #include #include "dosbox.h" @@ -123,8 +123,13 @@ static struct { INLINE void Mouse_AddEvent(Bit16u type) { if (mouse.events Date: Fri, 2 Jan 2004 19:06:51 +0000 Subject: [PATCH 1445/4131] Added aditional includes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1526 --- src/platform/visualc/Makefile.am | 2 +- src/platform/visualc/ntddk.h | 90 + src/platform/visualc/ntstatus.h | 1105 ++++ src/platform/visualc/win2k.h | 106 + src/platform/visualc/winddk.h | 9074 ++++++++++++++++++++++++++++++ src/platform/visualc/winnt4.h | 608 ++ src/platform/visualc/winxp.h | 38 + 7 files changed, 11022 insertions(+), 1 deletion(-) create mode 100644 src/platform/visualc/ntddk.h create mode 100644 src/platform/visualc/ntstatus.h create mode 100644 src/platform/visualc/win2k.h create mode 100644 src/platform/visualc/winddk.h create mode 100644 src/platform/visualc/winnt4.h create mode 100644 src/platform/visualc/winxp.h diff --git a/src/platform/visualc/Makefile.am b/src/platform/visualc/Makefile.am index aa491da5..b143cad9 100644 --- a/src/platform/visualc/Makefile.am +++ b/src/platform/visualc/Makefile.am @@ -1 +1 @@ -EXTRA_DIST = dirent.c dirent.h unistd.h config.h ntddscsi.h ntddstor.h ntddcdrm.h +EXTRA_DIST = dirent.c dirent.h unistd.h config.h ntddscsi.h ntddstor.h ntddcdrm.h ntddk.h ntstatus.h win2k.h winddk.h winnt4.h winxp.h diff --git a/src/platform/visualc/ntddk.h b/src/platform/visualc/ntddk.h new file mode 100644 index 00000000..480ff0cc --- /dev/null +++ b/src/platform/visualc/ntddk.h @@ -0,0 +1,90 @@ +/* + * ntddk.h + * + * Windows Device Driver Kit + * + * This file is part of the w32api package. + * + * Contributors: + * Created by Casper S. Hornstrup + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * DEFINES: + * DBG - Debugging enabled/disabled (0/1) + * POOL_TAGGING - Enable pool tagging + * _X86_ - X86 environment + */ + +#ifndef __NTDDK_H +#define __NTDDK_H + +#if __GNUC__ >=3 +#pragma GCC system_header +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#pragma pack(push,4) + +#include +#include +#include +#include + +/* Base types, structures and definitions */ +typedef short CSHORT; +typedef CONST int CINT; +typedef CONST char *PCSZ; + +#ifndef STATIC +#define STATIC static +#endif + +#ifndef CALLBACK +#define CALLBACK +#endif + +#ifndef DECL_IMPORT +#define DECL_IMPORT __attribute__((dllimport)) +#endif + +#ifndef DECL_EXPORT +#define DECL_EXPORT __attribute__((dllexport)) +#endif + +/* Windows NT status codes */ +#include "ntstatus.h" + +/* Windows NT definitions exported to user mode */ +#include + +/* Windows Device Driver Kit */ +#include "winddk.h" + +/* Definitions only in Windows XP */ +#include "winxp.h" + +/* Definitions only in Windows 2000 */ +#include "win2k.h" + +/* Definitions only in Windows NT 4 */ +#include "winnt4.h" + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif + +#endif /* __NTDDK_H */ diff --git a/src/platform/visualc/ntstatus.h b/src/platform/visualc/ntstatus.h new file mode 100644 index 00000000..d325d9f1 --- /dev/null +++ b/src/platform/visualc/ntstatus.h @@ -0,0 +1,1105 @@ +/* + * ntstatus.h + * + * Windows NT status codes + * + * This file is part of the w32api package. + * + * Contributors: + * Created by Casper S. Hornstrup + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef _NTSTATUS_H +#define _NTSTATUS_H + +#if __GNUC__ >=3 +#pragma GCC system_header +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(STATUS_SUCCESS) +#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) +#endif /* !STATUS_SUCCESS */ +#define FACILITY_DEBUGGER 0x1 +#define FACILITY_RPC_RUNTIME 0x2 +#define FACILITY_RPC_STUBS 0x3 +#define FACILITY_IO_ERROR_CODE 0x4 +#define FACILITY_TERMINAL_SERVER 0xA +#define FACILITY_USB_ERROR_CODE 0x10 +#define FACILITY_HID_ERROR_CODE 0x11 +#define FACILITY_FIREWIRE_ERROR_CODE 0x12 +#define FACILITY_CLUSTER_ERROR_CODE 0x13 +#define FACILITY_ACPI_ERROR_CODE 0x14 +#define FACILITY_SXS_ERROR_CODE 0x15 +#define STATUS_SEVERITY_SUCCESS 0x0 +#define STATUS_SEVERITY_INFORMATIONAL 0x1 +#define STATUS_SEVERITY_WARNING 0x2 +#define STATUS_SEVERITY_ERROR 0x3 +#define STATUS_WAIT_0 ((NTSTATUS)0x00000000L) +#define STATUS_WAIT_1 ((NTSTATUS)0x00000001L) +#define STATUS_WAIT_2 ((NTSTATUS)0x00000002L) +#define STATUS_WAIT_3 ((NTSTATUS)0x00000003L) +#define STATUS_WAIT_63 ((NTSTATUS)0x0000003FL) +#define STATUS_ABANDONED ((NTSTATUS)0x00000080L) +#define STATUS_ABANDONED_WAIT_0 ((NTSTATUS)0x00000080L) +#define STATUS_ABANDONED_WAIT_63 ((NTSTATUS)0x000000BFL) +#define STATUS_USER_APC ((NTSTATUS)0x000000C0L) +#define STATUS_KERNEL_APC ((NTSTATUS)0x00000100L) +#define STATUS_ALERTED ((NTSTATUS)0x00000101L) +#define STATUS_TIMEOUT ((NTSTATUS)0x00000102L) +#define STATUS_PENDING ((NTSTATUS)0x00000103L) +#define STATUS_REPARSE ((NTSTATUS)0x00000104L) +#define STATUS_MORE_ENTRIES ((NTSTATUS)0x00000105L) +#define STATUS_NOT_ALL_ASSIGNED ((NTSTATUS)0x00000106L) +#define STATUS_SOME_NOT_MAPPED ((NTSTATUS)0x00000107L) +#define STATUS_OPLOCK_BREAK_IN_PROGRESS ((NTSTATUS)0x00000108L) +#define STATUS_VOLUME_MOUNTED ((NTSTATUS)0x00000109L) +#define STATUS_RXACT_COMMITTED ((NTSTATUS)0x0000010AL) +#define STATUS_NOTIFY_CLEANUP ((NTSTATUS)0x0000010BL) +#define STATUS_NOTIFY_ENUM_DIR ((NTSTATUS)0x0000010CL) +#define STATUS_NO_QUOTAS_FOR_ACCOUNT ((NTSTATUS)0x0000010DL) +#define STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED ((NTSTATUS)0x0000010EL) +#define STATUS_PAGE_FAULT_TRANSITION ((NTSTATUS)0x00000110L) +#define STATUS_PAGE_FAULT_DEMAND_ZERO ((NTSTATUS)0x00000111L) +#define STATUS_PAGE_FAULT_COPY_ON_WRITE ((NTSTATUS)0x00000112L) +#define STATUS_PAGE_FAULT_GUARD_PAGE ((NTSTATUS)0x00000113L) +#define STATUS_PAGE_FAULT_PAGING_FILE ((NTSTATUS)0x00000114L) +#define STATUS_CACHE_PAGE_LOCKED ((NTSTATUS)0x00000115L) +#define STATUS_CRASH_DUMP ((NTSTATUS)0x00000116L) +#define STATUS_BUFFER_ALL_ZEROS ((NTSTATUS)0x00000117L) +#define STATUS_REPARSE_OBJECT ((NTSTATUS)0x00000118L) +#define STATUS_RESOURCE_REQUIREMENTS_CHANGED ((NTSTATUS)0x00000119L) +#define STATUS_TRANSLATION_COMPLETE ((NTSTATUS)0x00000120L) +#define STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY ((NTSTATUS)0x00000121L) +#define STATUS_NOTHING_TO_TERMINATE ((NTSTATUS)0x00000122L) +#define STATUS_PROCESS_NOT_IN_JOB ((NTSTATUS)0x00000123L) +#define STATUS_PROCESS_IN_JOB ((NTSTATUS)0x00000124L) +#define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS)0x40000000L) +#define STATUS_THREAD_WAS_SUSPENDED ((NTSTATUS)0x40000001L) +#define STATUS_WORKING_SET_LIMIT_RANGE ((NTSTATUS)0x40000002L) +#define STATUS_IMAGE_NOT_AT_BASE ((NTSTATUS)0x40000003L) +#define STATUS_RXACT_STATE_CREATED ((NTSTATUS)0x40000004L) +#define STATUS_SEGMENT_NOTIFICATION ((NTSTATUS)0x40000005L) +#define STATUS_LOCAL_USER_SESSION_KEY ((NTSTATUS)0x40000006L) +#define STATUS_BAD_CURRENT_DIRECTORY ((NTSTATUS)0x40000007L) +#define STATUS_SERIAL_MORE_WRITES ((NTSTATUS)0x40000008L) +#define STATUS_REGISTRY_RECOVERED ((NTSTATUS)0x40000009L) +#define STATUS_FT_READ_RECOVERY_FROM_BACKUP ((NTSTATUS)0x4000000AL) +#define STATUS_FT_WRITE_RECOVERY ((NTSTATUS)0x4000000BL) +#define STATUS_SERIAL_COUNTER_TIMEOUT ((NTSTATUS)0x4000000CL) +#define STATUS_NULL_LM_PASSWORD ((NTSTATUS)0x4000000DL) +#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH ((NTSTATUS)0x4000000EL) +#define STATUS_RECEIVE_PARTIAL ((NTSTATUS)0x4000000FL) +#define STATUS_RECEIVE_EXPEDITED ((NTSTATUS)0x40000010L) +#define STATUS_RECEIVE_PARTIAL_EXPEDITED ((NTSTATUS)0x40000011L) +#define STATUS_EVENT_DONE ((NTSTATUS)0x40000012L) +#define STATUS_EVENT_PENDING ((NTSTATUS)0x40000013L) +#define STATUS_CHECKING_FILE_SYSTEM ((NTSTATUS)0x40000014L) +#define STATUS_FATAL_APP_EXIT ((NTSTATUS)0x40000015L) +#define STATUS_PREDEFINED_HANDLE ((NTSTATUS)0x40000016L) +#define STATUS_WAS_UNLOCKED ((NTSTATUS)0x40000017L) +#define STATUS_SERVICE_NOTIFICATION ((NTSTATUS)0x40000018L) +#define STATUS_WAS_LOCKED ((NTSTATUS)0x40000019L) +#define STATUS_LOG_HARD_ERROR ((NTSTATUS)0x4000001AL) +#define STATUS_ALREADY_WIN32 ((NTSTATUS)0x4000001BL) +#define STATUS_WX86_UNSIMULATE ((NTSTATUS)0x4000001CL) +#define STATUS_WX86_CONTINUE ((NTSTATUS)0x4000001DL) +#define STATUS_WX86_SINGLE_STEP ((NTSTATUS)0x4000001EL) +#define STATUS_WX86_BREAKPOINT ((NTSTATUS)0x4000001FL) +#define STATUS_WX86_EXCEPTION_CONTINUE ((NTSTATUS)0x40000020L) +#define STATUS_WX86_EXCEPTION_LASTCHANCE ((NTSTATUS)0x40000021L) +#define STATUS_WX86_EXCEPTION_CHAIN ((NTSTATUS)0x40000022L) +#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE ((NTSTATUS)0x40000023L) +#define STATUS_NO_YIELD_PERFORMED ((NTSTATUS)0x40000024L) +#define STATUS_TIMER_RESUME_IGNORED ((NTSTATUS)0x40000025L) +#define STATUS_ARBITRATION_UNHANDLED ((NTSTATUS)0x40000026L) +#define STATUS_CARDBUS_NOT_SUPPORTED ((NTSTATUS)0x40000027L) +#define STATUS_WX86_CREATEWX86TIB ((NTSTATUS)0x40000028L) +#define STATUS_MP_PROCESSOR_MISMATCH ((NTSTATUS)0x40000029L) +#define STATUS_HIBERNATED ((NTSTATUS)0x4000002AL) +#define STATUS_RESUME_HIBERNATION ((NTSTATUS)0x4000002BL) +#define STATUS_GUARD_PAGE_VIOLATION ((NTSTATUS)0x80000001L) +#define STATUS_DATATYPE_MISALIGNMENT ((NTSTATUS)0x80000002L) +#define STATUS_BREAKPOINT ((NTSTATUS)0x80000003L) +#define STATUS_SINGLE_STEP ((NTSTATUS)0x80000004L) +#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L) +#define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006L) +#define STATUS_WAKE_SYSTEM_DEBUGGER ((NTSTATUS)0x80000007L) +#define STATUS_HANDLES_CLOSED ((NTSTATUS)0x8000000AL) +#define STATUS_NO_INHERITANCE ((NTSTATUS)0x8000000BL) +#define STATUS_GUID_SUBSTITUTION_MADE ((NTSTATUS)0x8000000CL) +#define STATUS_PARTIAL_COPY ((NTSTATUS)0x8000000DL) +#define STATUS_DEVICE_PAPER_EMPTY ((NTSTATUS)0x8000000EL) +#define STATUS_DEVICE_POWERED_OFF ((NTSTATUS)0x8000000FL) +#define STATUS_DEVICE_OFF_LINE ((NTSTATUS)0x80000010L) +#define STATUS_DEVICE_BUSY ((NTSTATUS)0x80000011L) +#define STATUS_NO_MORE_EAS ((NTSTATUS)0x80000012L) +#define STATUS_INVALID_EA_NAME ((NTSTATUS)0x80000013L) +#define STATUS_EA_LIST_INCONSISTENT ((NTSTATUS)0x80000014L) +#define STATUS_INVALID_EA_FLAG ((NTSTATUS)0x80000015L) +#define STATUS_VERIFY_REQUIRED ((NTSTATUS)0x80000016L) +#define STATUS_EXTRANEOUS_INFORMATION ((NTSTATUS)0x80000017L) +#define STATUS_RXACT_COMMIT_NECESSARY ((NTSTATUS)0x80000018L) +#define STATUS_NO_MORE_ENTRIES ((NTSTATUS)0x8000001AL) +#define STATUS_FILEMARK_DETECTED ((NTSTATUS)0x8000001BL) +#define STATUS_MEDIA_CHANGED ((NTSTATUS)0x8000001CL) +#define STATUS_BUS_RESET ((NTSTATUS)0x8000001DL) +#define STATUS_END_OF_MEDIA ((NTSTATUS)0x8000001EL) +#define STATUS_BEGINNING_OF_MEDIA ((NTSTATUS)0x8000001FL) +#define STATUS_MEDIA_CHECK ((NTSTATUS)0x80000020L) +#define STATUS_SETMARK_DETECTED ((NTSTATUS)0x80000021L) +#define STATUS_NO_DATA_DETECTED ((NTSTATUS)0x80000022L) +#define STATUS_REDIRECTOR_HAS_OPEN_HANDLES ((NTSTATUS)0x80000023L) +#define STATUS_SERVER_HAS_OPEN_HANDLES ((NTSTATUS)0x80000024L) +#define STATUS_ALREADY_DISCONNECTED ((NTSTATUS)0x80000025L) +#define STATUS_LONGJUMP ((NTSTATUS)0x80000026L) +#define STATUS_CLEANER_CARTRIDGE_INSTALLED ((NTSTATUS)0x80000027L) +#define STATUS_PLUGPLAY_QUERY_VETOED ((NTSTATUS)0x80000028L) +#define STATUS_UNWIND_CONSOLIDATE ((NTSTATUS)0x80000029L) +#define STATUS_CLUSTER_NODE_ALREADY_UP ((NTSTATUS)0x80130001L) +#define STATUS_CLUSTER_NODE_ALREADY_DOWN ((NTSTATUS)0x80130002L) +#define STATUS_CLUSTER_NETWORK_ALREADY_ONLINE ((NTSTATUS)0x80130003L) +#define STATUS_CLUSTER_NETWORK_ALREADY_OFFLINE ((NTSTATUS)0x80130004L) +#define STATUS_CLUSTER_NODE_ALREADY_MEMBER ((NTSTATUS)0x80130005L) +#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) +#define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L) +#define STATUS_INVALID_INFO_CLASS ((NTSTATUS)0xC0000003L) +#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) +#define STATUS_ACCESS_VIOLATION ((NTSTATUS)0xC0000005L) +#define STATUS_IN_PAGE_ERROR ((NTSTATUS)0xC0000006L) +#define STATUS_PAGEFILE_QUOTA ((NTSTATUS)0xC0000007L) +#define STATUS_INVALID_HANDLE ((NTSTATUS)0xC0000008L) +#define STATUS_BAD_INITIAL_STACK ((NTSTATUS)0xC0000009L) +#define STATUS_BAD_INITIAL_PC ((NTSTATUS)0xC000000AL) +#define STATUS_INVALID_CID ((NTSTATUS)0xC000000BL) +#define STATUS_TIMER_NOT_CANCELED ((NTSTATUS)0xC000000CL) +#define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000DL) +#define STATUS_NO_SUCH_DEVICE ((NTSTATUS)0xC000000EL) +#define STATUS_NO_SUCH_FILE ((NTSTATUS)0xC000000FL) +#define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS)0xC0000010L) +#define STATUS_END_OF_FILE ((NTSTATUS)0xC0000011L) +#define STATUS_WRONG_VOLUME ((NTSTATUS)0xC0000012L) +#define STATUS_NO_MEDIA_IN_DEVICE ((NTSTATUS)0xC0000013L) +#define STATUS_UNRECOGNIZED_MEDIA ((NTSTATUS)0xC0000014L) +#define STATUS_NONEXISTENT_SECTOR ((NTSTATUS)0xC0000015L) +#define STATUS_MORE_PROCESSING_REQUIRED ((NTSTATUS)0xC0000016L) +#define STATUS_NO_MEMORY ((NTSTATUS)0xC0000017L) +#define STATUS_CONFLICTING_ADDRESSES ((NTSTATUS)0xC0000018L) +#define STATUS_NOT_MAPPED_VIEW ((NTSTATUS)0xC0000019L) +#define STATUS_UNABLE_TO_FREE_VM ((NTSTATUS)0xC000001AL) +#define STATUS_UNABLE_TO_DELETE_SECTION ((NTSTATUS)0xC000001BL) +#define STATUS_INVALID_SYSTEM_SERVICE ((NTSTATUS)0xC000001CL) +#define STATUS_ILLEGAL_INSTRUCTION ((NTSTATUS)0xC000001DL) +#define STATUS_INVALID_LOCK_SEQUENCE ((NTSTATUS)0xC000001EL) +#define STATUS_INVALID_VIEW_SIZE ((NTSTATUS)0xC000001FL) +#define STATUS_INVALID_FILE_FOR_SECTION ((NTSTATUS)0xC0000020L) +#define STATUS_ALREADY_COMMITTED ((NTSTATUS)0xC0000021L) +#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L) +#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L) +#define STATUS_OBJECT_TYPE_MISMATCH ((NTSTATUS)0xC0000024L) +#define STATUS_NONCONTINUABLE_EXCEPTION ((NTSTATUS)0xC0000025L) +#define STATUS_INVALID_DISPOSITION ((NTSTATUS)0xC0000026L) +#define STATUS_UNWIND ((NTSTATUS)0xC0000027L) +#define STATUS_BAD_STACK ((NTSTATUS)0xC0000028L) +#define STATUS_INVALID_UNWIND_TARGET ((NTSTATUS)0xC0000029L) +#define STATUS_NOT_LOCKED ((NTSTATUS)0xC000002AL) +#define STATUS_PARITY_ERROR ((NTSTATUS)0xC000002BL) +#define STATUS_UNABLE_TO_DECOMMIT_VM ((NTSTATUS)0xC000002CL) +#define STATUS_NOT_COMMITTED ((NTSTATUS)0xC000002DL) +#define STATUS_INVALID_PORT_ATTRIBUTES ((NTSTATUS)0xC000002EL) +#define STATUS_PORT_MESSAGE_TOO_LONG ((NTSTATUS)0xC000002FL) +#define STATUS_INVALID_PARAMETER_MIX ((NTSTATUS)0xC0000030L) +#define STATUS_INVALID_QUOTA_LOWER ((NTSTATUS)0xC0000031L) +#define STATUS_DISK_CORRUPT_ERROR ((NTSTATUS)0xC0000032L) +#define STATUS_OBJECT_NAME_INVALID ((NTSTATUS)0xC0000033L) +#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L) +#define STATUS_OBJECT_NAME_COLLISION ((NTSTATUS)0xC0000035L) +#define STATUS_PORT_DISCONNECTED ((NTSTATUS)0xC0000037L) +#define STATUS_DEVICE_ALREADY_ATTACHED ((NTSTATUS)0xC0000038L) +#define STATUS_OBJECT_PATH_INVALID ((NTSTATUS)0xC0000039L) +#define STATUS_OBJECT_PATH_NOT_FOUND ((NTSTATUS)0xC000003AL) +#define STATUS_OBJECT_PATH_SYNTAX_BAD ((NTSTATUS)0xC000003BL) +#define STATUS_DATA_OVERRUN ((NTSTATUS)0xC000003CL) +#define STATUS_DATA_LATE_ERROR ((NTSTATUS)0xC000003DL) +#define STATUS_DATA_ERROR ((NTSTATUS)0xC000003EL) +#define STATUS_CRC_ERROR ((NTSTATUS)0xC000003FL) +#define STATUS_SECTION_TOO_BIG ((NTSTATUS)0xC0000040L) +#define STATUS_PORT_CONNECTION_REFUSED ((NTSTATUS)0xC0000041L) +#define STATUS_INVALID_PORT_HANDLE ((NTSTATUS)0xC0000042L) +#define STATUS_SHARING_VIOLATION ((NTSTATUS)0xC0000043L) +#define STATUS_QUOTA_EXCEEDED ((NTSTATUS)0xC0000044L) +#define STATUS_INVALID_PAGE_PROTECTION ((NTSTATUS)0xC0000045L) +#define STATUS_MUTANT_NOT_OWNED ((NTSTATUS)0xC0000046L) +#define STATUS_SEMAPHORE_LIMIT_EXCEEDED ((NTSTATUS)0xC0000047L) +#define STATUS_PORT_ALREADY_SET ((NTSTATUS)0xC0000048L) +#define STATUS_SECTION_NOT_IMAGE ((NTSTATUS)0xC0000049L) +#define STATUS_SUSPEND_COUNT_EXCEEDED ((NTSTATUS)0xC000004AL) +#define STATUS_THREAD_IS_TERMINATING ((NTSTATUS)0xC000004BL) +#define STATUS_BAD_WORKING_SET_LIMIT ((NTSTATUS)0xC000004CL) +#define STATUS_INCOMPATIBLE_FILE_MAP ((NTSTATUS)0xC000004DL) +#define STATUS_SECTION_PROTECTION ((NTSTATUS)0xC000004EL) +#define STATUS_EAS_NOT_SUPPORTED ((NTSTATUS)0xC000004FL) +#define STATUS_EA_TOO_LARGE ((NTSTATUS)0xC0000050L) +#define STATUS_NONEXISTENT_EA_ENTRY ((NTSTATUS)0xC0000051L) +#define STATUS_NO_EAS_ON_FILE ((NTSTATUS)0xC0000052L) +#define STATUS_EA_CORRUPT_ERROR ((NTSTATUS)0xC0000053L) +#define STATUS_FILE_LOCK_CONFLICT ((NTSTATUS)0xC0000054L) +#define STATUS_LOCK_NOT_GRANTED ((NTSTATUS)0xC0000055L) +#define STATUS_DELETE_PENDING ((NTSTATUS)0xC0000056L) +#define STATUS_CTL_FILE_NOT_SUPPORTED ((NTSTATUS)0xC0000057L) +#define STATUS_UNKNOWN_REVISION ((NTSTATUS)0xC0000058L) +#define STATUS_REVISION_MISMATCH ((NTSTATUS)0xC0000059L) +#define STATUS_INVALID_OWNER ((NTSTATUS)0xC000005AL) +#define STATUS_INVALID_PRIMARY_GROUP ((NTSTATUS)0xC000005BL) +#define STATUS_NO_IMPERSONATION_TOKEN ((NTSTATUS)0xC000005CL) +#define STATUS_CANT_DISABLE_MANDATORY ((NTSTATUS)0xC000005DL) +#define STATUS_NO_LOGON_SERVERS ((NTSTATUS)0xC000005EL) +#define STATUS_NO_SUCH_LOGON_SESSION ((NTSTATUS)0xC000005FL) +#define STATUS_NO_SUCH_PRIVILEGE ((NTSTATUS)0xC0000060L) +#define STATUS_PRIVILEGE_NOT_HELD ((NTSTATUS)0xC0000061L) +#define STATUS_INVALID_ACCOUNT_NAME ((NTSTATUS)0xC0000062L) +#define STATUS_USER_EXISTS ((NTSTATUS)0xC0000063L) +#define STATUS_NO_SUCH_USER ((NTSTATUS)0xC0000064L) +#define STATUS_GROUP_EXISTS ((NTSTATUS)0xC0000065L) +#define STATUS_NO_SUCH_GROUP ((NTSTATUS)0xC0000066L) +#define STATUS_MEMBER_IN_GROUP ((NTSTATUS)0xC0000067L) +#define STATUS_MEMBER_NOT_IN_GROUP ((NTSTATUS)0xC0000068L) +#define STATUS_LAST_ADMIN ((NTSTATUS)0xC0000069L) +#define STATUS_WRONG_PASSWORD ((NTSTATUS)0xC000006AL) +#define STATUS_ILL_FORMED_PASSWORD ((NTSTATUS)0xC000006BL) +#define STATUS_PASSWORD_RESTRICTION ((NTSTATUS)0xC000006CL) +#define STATUS_LOGON_FAILURE ((NTSTATUS)0xC000006DL) +#define STATUS_ACCOUNT_RESTRICTION ((NTSTATUS)0xC000006EL) +#define STATUS_INVALID_LOGON_HOURS ((NTSTATUS)0xC000006FL) +#define STATUS_INVALID_WORKSTATION ((NTSTATUS)0xC0000070L) +#define STATUS_PASSWORD_EXPIRED ((NTSTATUS)0xC0000071L) +#define STATUS_ACCOUNT_DISABLED ((NTSTATUS)0xC0000072L) +#define STATUS_NONE_MAPPED ((NTSTATUS)0xC0000073L) +#define STATUS_TOO_MANY_LUIDS_REQUESTED ((NTSTATUS)0xC0000074L) +#define STATUS_LUIDS_EXHAUSTED ((NTSTATUS)0xC0000075L) +#define STATUS_INVALID_SUB_AUTHORITY ((NTSTATUS)0xC0000076L) +#define STATUS_INVALID_ACL ((NTSTATUS)0xC0000077L) +#define STATUS_INVALID_SID ((NTSTATUS)0xC0000078L) +#define STATUS_INVALID_SECURITY_DESCR ((NTSTATUS)0xC0000079L) +#define STATUS_PROCEDURE_NOT_FOUND ((NTSTATUS)0xC000007AL) +#define STATUS_INVALID_IMAGE_FORMAT ((NTSTATUS)0xC000007BL) +#define STATUS_NO_TOKEN ((NTSTATUS)0xC000007CL) +#define STATUS_BAD_INHERITANCE_ACL ((NTSTATUS)0xC000007DL) +#define STATUS_RANGE_NOT_LOCKED ((NTSTATUS)0xC000007EL) +#define STATUS_DISK_FULL ((NTSTATUS)0xC000007FL) +#define STATUS_SERVER_DISABLED ((NTSTATUS)0xC0000080L) +#define STATUS_SERVER_NOT_DISABLED ((NTSTATUS)0xC0000081L) +#define STATUS_TOO_MANY_GUIDS_REQUESTED ((NTSTATUS)0xC0000082L) +#define STATUS_GUIDS_EXHAUSTED ((NTSTATUS)0xC0000083L) +#define STATUS_INVALID_ID_AUTHORITY ((NTSTATUS)0xC0000084L) +#define STATUS_AGENTS_EXHAUSTED ((NTSTATUS)0xC0000085L) +#define STATUS_INVALID_VOLUME_LABEL ((NTSTATUS)0xC0000086L) +#define STATUS_SECTION_NOT_EXTENDED ((NTSTATUS)0xC0000087L) +#define STATUS_NOT_MAPPED_DATA ((NTSTATUS)0xC0000088L) +#define STATUS_RESOURCE_DATA_NOT_FOUND ((NTSTATUS)0xC0000089L) +#define STATUS_RESOURCE_TYPE_NOT_FOUND ((NTSTATUS)0xC000008AL) +#define STATUS_RESOURCE_NAME_NOT_FOUND ((NTSTATUS)0xC000008BL) +#define STATUS_ARRAY_BOUNDS_EXCEEDED ((NTSTATUS)0xC000008CL) +#define STATUS_FLOAT_DENORMAL_OPERAND ((NTSTATUS)0xC000008DL) +#define STATUS_FLOAT_DIVIDE_BY_ZERO ((NTSTATUS)0xC000008EL) +#define STATUS_FLOAT_INEXACT_RESULT ((NTSTATUS)0xC000008FL) +#define STATUS_FLOAT_INVALID_OPERATION ((NTSTATUS)0xC0000090L) +#define STATUS_FLOAT_OVERFLOW ((NTSTATUS)0xC0000091L) +#define STATUS_FLOAT_STACK_CHECK ((NTSTATUS)0xC0000092L) +#define STATUS_FLOAT_UNDERFLOW ((NTSTATUS)0xC0000093L) +#define STATUS_INTEGER_DIVIDE_BY_ZERO ((NTSTATUS)0xC0000094L) +#define STATUS_INTEGER_OVERFLOW ((NTSTATUS)0xC0000095L) +#define STATUS_PRIVILEGED_INSTRUCTION ((NTSTATUS)0xC0000096L) +#define STATUS_TOO_MANY_PAGING_FILES ((NTSTATUS)0xC0000097L) +#define STATUS_FILE_INVALID ((NTSTATUS)0xC0000098L) +#define STATUS_ALLOTTED_SPACE_EXCEEDED ((NTSTATUS)0xC0000099L) +#define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS)0xC000009AL) +#define STATUS_DFS_EXIT_PATH_FOUND ((NTSTATUS)0xC000009BL) +#define STATUS_DEVICE_DATA_ERROR ((NTSTATUS)0xC000009CL) +#define STATUS_DEVICE_NOT_CONNECTED ((NTSTATUS)0xC000009DL) +#define STATUS_DEVICE_POWER_FAILURE ((NTSTATUS)0xC000009EL) +#define STATUS_FREE_VM_NOT_AT_BASE ((NTSTATUS)0xC000009FL) +#define STATUS_MEMORY_NOT_ALLOCATED ((NTSTATUS)0xC00000A0L) +#define STATUS_WORKING_SET_QUOTA ((NTSTATUS)0xC00000A1L) +#define STATUS_MEDIA_WRITE_PROTECTED ((NTSTATUS)0xC00000A2L) +#define STATUS_DEVICE_NOT_READY ((NTSTATUS)0xC00000A3L) +#define STATUS_INVALID_GROUP_ATTRIBUTES ((NTSTATUS)0xC00000A4L) +#define STATUS_BAD_IMPERSONATION_LEVEL ((NTSTATUS)0xC00000A5L) +#define STATUS_CANT_OPEN_ANONYMOUS ((NTSTATUS)0xC00000A6L) +#define STATUS_BAD_VALIDATION_CLASS ((NTSTATUS)0xC00000A7L) +#define STATUS_BAD_TOKEN_TYPE ((NTSTATUS)0xC00000A8L) +#define STATUS_BAD_MASTER_BOOT_RECORD ((NTSTATUS)0xC00000A9L) +#define STATUS_INSTRUCTION_MISALIGNMENT ((NTSTATUS)0xC00000AAL) +#define STATUS_INSTANCE_NOT_AVAILABLE ((NTSTATUS)0xC00000ABL) +#define STATUS_PIPE_NOT_AVAILABLE ((NTSTATUS)0xC00000ACL) +#define STATUS_INVALID_PIPE_STATE ((NTSTATUS)0xC00000ADL) +#define STATUS_PIPE_BUSY ((NTSTATUS)0xC00000AEL) +#define STATUS_ILLEGAL_FUNCTION ((NTSTATUS)0xC00000AFL) +#define STATUS_PIPE_DISCONNECTED ((NTSTATUS)0xC00000B0L) +#define STATUS_PIPE_CLOSING ((NTSTATUS)0xC00000B1L) +#define STATUS_PIPE_CONNECTED ((NTSTATUS)0xC00000B2L) +#define STATUS_PIPE_LISTENING ((NTSTATUS)0xC00000B3L) +#define STATUS_INVALID_READ_MODE ((NTSTATUS)0xC00000B4L) +#define STATUS_IO_TIMEOUT ((NTSTATUS)0xC00000B5L) +#define STATUS_FILE_FORCED_CLOSED ((NTSTATUS)0xC00000B6L) +#define STATUS_PROFILING_NOT_STARTED ((NTSTATUS)0xC00000B7L) +#define STATUS_PROFILING_NOT_STOPPED ((NTSTATUS)0xC00000B8L) +#define STATUS_COULD_NOT_INTERPRET ((NTSTATUS)0xC00000B9L) +#define STATUS_FILE_IS_A_DIRECTORY ((NTSTATUS)0xC00000BAL) +#define STATUS_NOT_SUPPORTED ((NTSTATUS)0xC00000BBL) +#define STATUS_REMOTE_NOT_LISTENING ((NTSTATUS)0xC00000BCL) +#define STATUS_DUPLICATE_NAME ((NTSTATUS)0xC00000BDL) +#define STATUS_BAD_NETWORK_PATH ((NTSTATUS)0xC00000BEL) +#define STATUS_NETWORK_BUSY ((NTSTATUS)0xC00000BFL) +#define STATUS_DEVICE_DOES_NOT_EXIST ((NTSTATUS)0xC00000C0L) +#define STATUS_TOO_MANY_COMMANDS ((NTSTATUS)0xC00000C1L) +#define STATUS_ADAPTER_HARDWARE_ERROR ((NTSTATUS)0xC00000C2L) +#define STATUS_INVALID_NETWORK_RESPONSE ((NTSTATUS)0xC00000C3L) +#define STATUS_UNEXPECTED_NETWORK_ERROR ((NTSTATUS)0xC00000C4L) +#define STATUS_BAD_REMOTE_ADAPTER ((NTSTATUS)0xC00000C5L) +#define STATUS_PRINT_QUEUE_FULL ((NTSTATUS)0xC00000C6L) +#define STATUS_NO_SPOOL_SPACE ((NTSTATUS)0xC00000C7L) +#define STATUS_PRINT_CANCELLED ((NTSTATUS)0xC00000C8L) +#define STATUS_NETWORK_NAME_DELETED ((NTSTATUS)0xC00000C9L) +#define STATUS_NETWORK_ACCESS_DENIED ((NTSTATUS)0xC00000CAL) +#define STATUS_BAD_DEVICE_TYPE ((NTSTATUS)0xC00000CBL) +#define STATUS_BAD_NETWORK_NAME ((NTSTATUS)0xC00000CCL) +#define STATUS_TOO_MANY_NAMES ((NTSTATUS)0xC00000CDL) +#define STATUS_TOO_MANY_SESSIONS ((NTSTATUS)0xC00000CEL) +#define STATUS_SHARING_PAUSED ((NTSTATUS)0xC00000CFL) +#define STATUS_REQUEST_NOT_ACCEPTED ((NTSTATUS)0xC00000D0L) +#define STATUS_REDIRECTOR_PAUSED ((NTSTATUS)0xC00000D1L) +#define STATUS_NET_WRITE_FAULT ((NTSTATUS)0xC00000D2L) +#define STATUS_PROFILING_AT_LIMIT ((NTSTATUS)0xC00000D3L) +#define STATUS_NOT_SAME_DEVICE ((NTSTATUS)0xC00000D4L) +#define STATUS_FILE_RENAMED ((NTSTATUS)0xC00000D5L) +#define STATUS_VIRTUAL_CIRCUIT_CLOSED ((NTSTATUS)0xC00000D6L) +#define STATUS_NO_SECURITY_ON_OBJECT ((NTSTATUS)0xC00000D7L) +#define STATUS_CANT_WAIT ((NTSTATUS)0xC00000D8L) +#define STATUS_PIPE_EMPTY ((NTSTATUS)0xC00000D9L) +#define STATUS_CANT_ACCESS_DOMAIN_INFO ((NTSTATUS)0xC00000DAL) +#define STATUS_CANT_TERMINATE_SELF ((NTSTATUS)0xC00000DBL) +#define STATUS_INVALID_SERVER_STATE ((NTSTATUS)0xC00000DCL) +#define STATUS_INVALID_DOMAIN_STATE ((NTSTATUS)0xC00000DDL) +#define STATUS_INVALID_DOMAIN_ROLE ((NTSTATUS)0xC00000DEL) +#define STATUS_NO_SUCH_DOMAIN ((NTSTATUS)0xC00000DFL) +#define STATUS_DOMAIN_EXISTS ((NTSTATUS)0xC00000E0L) +#define STATUS_DOMAIN_LIMIT_EXCEEDED ((NTSTATUS)0xC00000E1L) +#define STATUS_OPLOCK_NOT_GRANTED ((NTSTATUS)0xC00000E2L) +#define STATUS_INVALID_OPLOCK_PROTOCOL ((NTSTATUS)0xC00000E3L) +#define STATUS_INTERNAL_DB_CORRUPTION ((NTSTATUS)0xC00000E4L) +#define STATUS_INTERNAL_ERROR ((NTSTATUS)0xC00000E5L) +#define STATUS_GENERIC_NOT_MAPPED ((NTSTATUS)0xC00000E6L) +#define STATUS_BAD_DESCRIPTOR_FORMAT ((NTSTATUS)0xC00000E7L) +#define STATUS_INVALID_USER_BUFFER ((NTSTATUS)0xC00000E8L) +#define STATUS_UNEXPECTED_IO_ERROR ((NTSTATUS)0xC00000E9L) +#define STATUS_UNEXPECTED_MM_CREATE_ERR ((NTSTATUS)0xC00000EAL) +#define STATUS_UNEXPECTED_MM_MAP_ERROR ((NTSTATUS)0xC00000EBL) +#define STATUS_UNEXPECTED_MM_EXTEND_ERR ((NTSTATUS)0xC00000ECL) +#define STATUS_NOT_LOGON_PROCESS ((NTSTATUS)0xC00000EDL) +#define STATUS_LOGON_SESSION_EXISTS ((NTSTATUS)0xC00000EEL) +#define STATUS_INVALID_PARAMETER_1 ((NTSTATUS)0xC00000EFL) +#define STATUS_INVALID_PARAMETER_2 ((NTSTATUS)0xC00000F0L) +#define STATUS_INVALID_PARAMETER_3 ((NTSTATUS)0xC00000F1L) +#define STATUS_INVALID_PARAMETER_4 ((NTSTATUS)0xC00000F2L) +#define STATUS_INVALID_PARAMETER_5 ((NTSTATUS)0xC00000F3L) +#define STATUS_INVALID_PARAMETER_6 ((NTSTATUS)0xC00000F4L) +#define STATUS_INVALID_PARAMETER_7 ((NTSTATUS)0xC00000F5L) +#define STATUS_INVALID_PARAMETER_8 ((NTSTATUS)0xC00000F6L) +#define STATUS_INVALID_PARAMETER_9 ((NTSTATUS)0xC00000F7L) +#define STATUS_INVALID_PARAMETER_10 ((NTSTATUS)0xC00000F8L) +#define STATUS_INVALID_PARAMETER_11 ((NTSTATUS)0xC00000F9L) +#define STATUS_INVALID_PARAMETER_12 ((NTSTATUS)0xC00000FAL) +#define STATUS_REDIRECTOR_NOT_STARTED ((NTSTATUS)0xC00000FBL) +#define STATUS_REDIRECTOR_STARTED ((NTSTATUS)0xC00000FCL) +#define STATUS_STACK_OVERFLOW ((NTSTATUS)0xC00000FDL) +#define STATUS_NO_SUCH_PACKAGE ((NTSTATUS)0xC00000FEL) +#define STATUS_BAD_FUNCTION_TABLE ((NTSTATUS)0xC00000FFL) +#define STATUS_VARIABLE_NOT_FOUND ((NTSTATUS)0xC0000100L) +#define STATUS_DIRECTORY_NOT_EMPTY ((NTSTATUS)0xC0000101L) +#define STATUS_FILE_CORRUPT_ERROR ((NTSTATUS)0xC0000102L) +#define STATUS_NOT_A_DIRECTORY ((NTSTATUS)0xC0000103L) +#define STATUS_BAD_LOGON_SESSION_STATE ((NTSTATUS)0xC0000104L) +#define STATUS_LOGON_SESSION_COLLISION ((NTSTATUS)0xC0000105L) +#define STATUS_NAME_TOO_LONG ((NTSTATUS)0xC0000106L) +#define STATUS_FILES_OPEN ((NTSTATUS)0xC0000107L) +#define STATUS_CONNECTION_IN_USE ((NTSTATUS)0xC0000108L) +#define STATUS_MESSAGE_NOT_FOUND ((NTSTATUS)0xC0000109L) +#define STATUS_PROCESS_IS_TERMINATING ((NTSTATUS)0xC000010AL) +#define STATUS_INVALID_LOGON_TYPE ((NTSTATUS)0xC000010BL) +#define STATUS_NO_GUID_TRANSLATION ((NTSTATUS)0xC000010CL) +#define STATUS_CANNOT_IMPERSONATE ((NTSTATUS)0xC000010DL) +#define STATUS_IMAGE_ALREADY_LOADED ((NTSTATUS)0xC000010EL) +#define STATUS_ABIOS_NOT_PRESENT ((NTSTATUS)0xC000010FL) +#define STATUS_ABIOS_LID_NOT_EXIST ((NTSTATUS)0xC0000110L) +#define STATUS_ABIOS_LID_ALREADY_OWNED ((NTSTATUS)0xC0000111L) +#define STATUS_ABIOS_NOT_LID_OWNER ((NTSTATUS)0xC0000112L) +#define STATUS_ABIOS_INVALID_COMMAND ((NTSTATUS)0xC0000113L) +#define STATUS_ABIOS_INVALID_LID ((NTSTATUS)0xC0000114L) +#define STATUS_ABIOS_SELECTOR_NOT_AVAILABLE ((NTSTATUS)0xC0000115L) +#define STATUS_ABIOS_INVALID_SELECTOR ((NTSTATUS)0xC0000116L) +#define STATUS_NO_LDT ((NTSTATUS)0xC0000117L) +#define STATUS_INVALID_LDT_SIZE ((NTSTATUS)0xC0000118L) +#define STATUS_INVALID_LDT_OFFSET ((NTSTATUS)0xC0000119L) +#define STATUS_INVALID_LDT_DESCRIPTOR ((NTSTATUS)0xC000011AL) +#define STATUS_INVALID_IMAGE_NE_FORMAT ((NTSTATUS)0xC000011BL) +#define STATUS_RXACT_INVALID_STATE ((NTSTATUS)0xC000011CL) +#define STATUS_RXACT_COMMIT_FAILURE ((NTSTATUS)0xC000011DL) +#define STATUS_MAPPED_FILE_SIZE_ZERO ((NTSTATUS)0xC000011EL) +#define STATUS_TOO_MANY_OPENED_FILES ((NTSTATUS)0xC000011FL) +#define STATUS_CANCELLED ((NTSTATUS)0xC0000120L) +#define STATUS_CANNOT_DELETE ((NTSTATUS)0xC0000121L) +#define STATUS_INVALID_COMPUTER_NAME ((NTSTATUS)0xC0000122L) +#define STATUS_FILE_DELETED ((NTSTATUS)0xC0000123L) +#define STATUS_SPECIAL_ACCOUNT ((NTSTATUS)0xC0000124L) +#define STATUS_SPECIAL_GROUP ((NTSTATUS)0xC0000125L) +#define STATUS_SPECIAL_USER ((NTSTATUS)0xC0000126L) +#define STATUS_MEMBERS_PRIMARY_GROUP ((NTSTATUS)0xC0000127L) +#define STATUS_FILE_CLOSED ((NTSTATUS)0xC0000128L) +#define STATUS_TOO_MANY_THREADS ((NTSTATUS)0xC0000129L) +#define STATUS_THREAD_NOT_IN_PROCESS ((NTSTATUS)0xC000012AL) +#define STATUS_TOKEN_ALREADY_IN_USE ((NTSTATUS)0xC000012BL) +#define STATUS_PAGEFILE_QUOTA_EXCEEDED ((NTSTATUS)0xC000012CL) +#define STATUS_COMMITMENT_LIMIT ((NTSTATUS)0xC000012DL) +#define STATUS_INVALID_IMAGE_LE_FORMAT ((NTSTATUS)0xC000012EL) +#define STATUS_INVALID_IMAGE_NOT_MZ ((NTSTATUS)0xC000012FL) +#define STATUS_INVALID_IMAGE_PROTECT ((NTSTATUS)0xC0000130L) +#define STATUS_INVALID_IMAGE_WIN_16 ((NTSTATUS)0xC0000131L) +#define STATUS_LOGON_SERVER_CONFLICT ((NTSTATUS)0xC0000132L) +#define STATUS_TIME_DIFFERENCE_AT_DC ((NTSTATUS)0xC0000133L) +#define STATUS_SYNCHRONIZATION_REQUIRED ((NTSTATUS)0xC0000134L) +#define STATUS_DLL_NOT_FOUND ((NTSTATUS)0xC0000135L) +#define STATUS_OPEN_FAILED ((NTSTATUS)0xC0000136L) +#define STATUS_IO_PRIVILEGE_FAILED ((NTSTATUS)0xC0000137L) +#define STATUS_ORDINAL_NOT_FOUND ((NTSTATUS)0xC0000138L) +#define STATUS_ENTRYPOINT_NOT_FOUND ((NTSTATUS)0xC0000139L) +#define STATUS_CONTROL_C_EXIT ((NTSTATUS)0xC000013AL) +#define STATUS_LOCAL_DISCONNECT ((NTSTATUS)0xC000013BL) +#define STATUS_REMOTE_DISCONNECT ((NTSTATUS)0xC000013CL) +#define STATUS_REMOTE_RESOURCES ((NTSTATUS)0xC000013DL) +#define STATUS_LINK_FAILED ((NTSTATUS)0xC000013EL) +#define STATUS_LINK_TIMEOUT ((NTSTATUS)0xC000013FL) +#define STATUS_INVALID_CONNECTION ((NTSTATUS)0xC0000140L) +#define STATUS_INVALID_ADDRESS ((NTSTATUS)0xC0000141L) +#define STATUS_DLL_INIT_FAILED ((NTSTATUS)0xC0000142L) +#define STATUS_MISSING_SYSTEMFILE ((NTSTATUS)0xC0000143L) +#define STATUS_UNHANDLED_EXCEPTION ((NTSTATUS)0xC0000144L) +#define STATUS_APP_INIT_FAILURE ((NTSTATUS)0xC0000145L) +#define STATUS_PAGEFILE_CREATE_FAILED ((NTSTATUS)0xC0000146L) +#define STATUS_NO_PAGEFILE ((NTSTATUS)0xC0000147L) +#define STATUS_INVALID_LEVEL ((NTSTATUS)0xC0000148L) +#define STATUS_WRONG_PASSWORD_CORE ((NTSTATUS)0xC0000149L) +#define STATUS_ILLEGAL_FLOAT_CONTEXT ((NTSTATUS)0xC000014AL) +#define STATUS_PIPE_BROKEN ((NTSTATUS)0xC000014BL) +#define STATUS_REGISTRY_CORRUPT ((NTSTATUS)0xC000014CL) +#define STATUS_REGISTRY_IO_FAILED ((NTSTATUS)0xC000014DL) +#define STATUS_NO_EVENT_PAIR ((NTSTATUS)0xC000014EL) +#define STATUS_UNRECOGNIZED_VOLUME ((NTSTATUS)0xC000014FL) +#define STATUS_SERIAL_NO_DEVICE_INITED ((NTSTATUS)0xC0000150L) +#define STATUS_NO_SUCH_ALIAS ((NTSTATUS)0xC0000151L) +#define STATUS_MEMBER_NOT_IN_ALIAS ((NTSTATUS)0xC0000152L) +#define STATUS_MEMBER_IN_ALIAS ((NTSTATUS)0xC0000153L) +#define STATUS_ALIAS_EXISTS ((NTSTATUS)0xC0000154L) +#define STATUS_LOGON_NOT_GRANTED ((NTSTATUS)0xC0000155L) +#define STATUS_TOO_MANY_SECRETS ((NTSTATUS)0xC0000156L) +#define STATUS_SECRET_TOO_LONG ((NTSTATUS)0xC0000157L) +#define STATUS_INTERNAL_DB_ERROR ((NTSTATUS)0xC0000158L) +#define STATUS_FULLSCREEN_MODE ((NTSTATUS)0xC0000159L) +#define STATUS_TOO_MANY_CONTEXT_IDS ((NTSTATUS)0xC000015AL) +#define STATUS_LOGON_TYPE_NOT_GRANTED ((NTSTATUS)0xC000015BL) +#define STATUS_NOT_REGISTRY_FILE ((NTSTATUS)0xC000015CL) +#define STATUS_NT_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS)0xC000015DL) +#define STATUS_DOMAIN_CTRLR_CONFIG_ERROR ((NTSTATUS)0xC000015EL) +#define STATUS_FT_MISSING_MEMBER ((NTSTATUS)0xC000015FL) +#define STATUS_ILL_FORMED_SERVICE_ENTRY ((NTSTATUS)0xC0000160L) +#define STATUS_ILLEGAL_CHARACTER ((NTSTATUS)0xC0000161L) +#define STATUS_UNMAPPABLE_CHARACTER ((NTSTATUS)0xC0000162L) +#define STATUS_UNDEFINED_CHARACTER ((NTSTATUS)0xC0000163L) +#define STATUS_FLOPPY_VOLUME ((NTSTATUS)0xC0000164L) +#define STATUS_FLOPPY_ID_MARK_NOT_FOUND ((NTSTATUS)0xC0000165L) +#define STATUS_FLOPPY_WRONG_CYLINDER ((NTSTATUS)0xC0000166L) +#define STATUS_FLOPPY_UNKNOWN_ERROR ((NTSTATUS)0xC0000167L) +#define STATUS_FLOPPY_BAD_REGISTERS ((NTSTATUS)0xC0000168L) +#define STATUS_DISK_RECALIBRATE_FAILED ((NTSTATUS)0xC0000169L) +#define STATUS_DISK_OPERATION_FAILED ((NTSTATUS)0xC000016AL) +#define STATUS_DISK_RESET_FAILED ((NTSTATUS)0xC000016BL) +#define STATUS_SHARED_IRQ_BUSY ((NTSTATUS)0xC000016CL) +#define STATUS_FT_ORPHANING ((NTSTATUS)0xC000016DL) +#define STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT ((NTSTATUS)0xC000016EL) +#define STATUS_PARTITION_FAILURE ((NTSTATUS)0xC0000172L) +#define STATUS_INVALID_BLOCK_LENGTH ((NTSTATUS)0xC0000173L) +#define STATUS_DEVICE_NOT_PARTITIONED ((NTSTATUS)0xC0000174L) +#define STATUS_UNABLE_TO_LOCK_MEDIA ((NTSTATUS)0xC0000175L) +#define STATUS_UNABLE_TO_UNLOAD_MEDIA ((NTSTATUS)0xC0000176L) +#define STATUS_EOM_OVERFLOW ((NTSTATUS)0xC0000177L) +#define STATUS_NO_MEDIA ((NTSTATUS)0xC0000178L) +#define STATUS_NO_SUCH_MEMBER ((NTSTATUS)0xC000017AL) +#define STATUS_INVALID_MEMBER ((NTSTATUS)0xC000017BL) +#define STATUS_KEY_DELETED ((NTSTATUS)0xC000017CL) +#define STATUS_NO_LOG_SPACE ((NTSTATUS)0xC000017DL) +#define STATUS_TOO_MANY_SIDS ((NTSTATUS)0xC000017EL) +#define STATUS_LM_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS)0xC000017FL) +#define STATUS_KEY_HAS_CHILDREN ((NTSTATUS)0xC0000180L) +#define STATUS_CHILD_MUST_BE_VOLATILE ((NTSTATUS)0xC0000181L) +#define STATUS_DEVICE_CONFIGURATION_ERROR ((NTSTATUS)0xC0000182L) +#define STATUS_DRIVER_INTERNAL_ERROR ((NTSTATUS)0xC0000183L) +#define STATUS_INVALID_DEVICE_STATE ((NTSTATUS)0xC0000184L) +#define STATUS_IO_DEVICE_ERROR ((NTSTATUS)0xC0000185L) +#define STATUS_DEVICE_PROTOCOL_ERROR ((NTSTATUS)0xC0000186L) +#define STATUS_BACKUP_CONTROLLER ((NTSTATUS)0xC0000187L) +#define STATUS_LOG_FILE_FULL ((NTSTATUS)0xC0000188L) +#define STATUS_TOO_LATE ((NTSTATUS)0xC0000189L) +#define STATUS_NO_TRUST_LSA_SECRET ((NTSTATUS)0xC000018AL) +#define STATUS_NO_TRUST_SAM_ACCOUNT ((NTSTATUS)0xC000018BL) +#define STATUS_TRUSTED_DOMAIN_FAILURE ((NTSTATUS)0xC000018CL) +#define STATUS_TRUSTED_RELATIONSHIP_FAILURE ((NTSTATUS)0xC000018DL) +#define STATUS_EVENTLOG_FILE_CORRUPT ((NTSTATUS)0xC000018EL) +#define STATUS_EVENTLOG_CANT_START ((NTSTATUS)0xC000018FL) +#define STATUS_TRUST_FAILURE ((NTSTATUS)0xC0000190L) +#define STATUS_MUTANT_LIMIT_EXCEEDED ((NTSTATUS)0xC0000191L) +#define STATUS_NETLOGON_NOT_STARTED ((NTSTATUS)0xC0000192L) +#define STATUS_ACCOUNT_EXPIRED ((NTSTATUS)0xC0000193L) +#define STATUS_POSSIBLE_DEADLOCK ((NTSTATUS)0xC0000194L) +#define STATUS_NETWORK_CREDENTIAL_CONFLICT ((NTSTATUS)0xC0000195L) +#define STATUS_REMOTE_SESSION_LIMIT ((NTSTATUS)0xC0000196L) +#define STATUS_EVENTLOG_FILE_CHANGED ((NTSTATUS)0xC0000197L) +#define STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT ((NTSTATUS)0xC0000198L) +#define STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT ((NTSTATUS)0xC0000199L) +#define STATUS_NOLOGON_SERVER_TRUST_ACCOUNT ((NTSTATUS)0xC000019AL) +#define STATUS_DOMAIN_TRUST_INCONSISTENT ((NTSTATUS)0xC000019BL) +#define STATUS_FS_DRIVER_REQUIRED ((NTSTATUS)0xC000019CL) +#define STATUS_NO_USER_SESSION_KEY ((NTSTATUS)0xC0000202L) +#define STATUS_USER_SESSION_DELETED ((NTSTATUS)0xC0000203L) +#define STATUS_RESOURCE_LANG_NOT_FOUND ((NTSTATUS)0xC0000204L) +#define STATUS_INSUFF_SERVER_RESOURCES ((NTSTATUS)0xC0000205L) +#define STATUS_INVALID_BUFFER_SIZE ((NTSTATUS)0xC0000206L) +#define STATUS_INVALID_ADDRESS_COMPONENT ((NTSTATUS)0xC0000207L) +#define STATUS_INVALID_ADDRESS_WILDCARD ((NTSTATUS)0xC0000208L) +#define STATUS_TOO_MANY_ADDRESSES ((NTSTATUS)0xC0000209L) +#define STATUS_ADDRESS_ALREADY_EXISTS ((NTSTATUS)0xC000020AL) +#define STATUS_ADDRESS_CLOSED ((NTSTATUS)0xC000020BL) +#define STATUS_CONNECTION_DISCONNECTED ((NTSTATUS)0xC000020CL) +#define STATUS_CONNECTION_RESET ((NTSTATUS)0xC000020DL) +#define STATUS_TOO_MANY_NODES ((NTSTATUS)0xC000020EL) +#define STATUS_TRANSACTION_ABORTED ((NTSTATUS)0xC000020FL) +#define STATUS_TRANSACTION_TIMED_OUT ((NTSTATUS)0xC0000210L) +#define STATUS_TRANSACTION_NO_RELEASE ((NTSTATUS)0xC0000211L) +#define STATUS_TRANSACTION_NO_MATCH ((NTSTATUS)0xC0000212L) +#define STATUS_TRANSACTION_RESPONDED ((NTSTATUS)0xC0000213L) +#define STATUS_TRANSACTION_INVALID_ID ((NTSTATUS)0xC0000214L) +#define STATUS_TRANSACTION_INVALID_TYPE ((NTSTATUS)0xC0000215L) +#define STATUS_NOT_SERVER_SESSION ((NTSTATUS)0xC0000216L) +#define STATUS_NOT_CLIENT_SESSION ((NTSTATUS)0xC0000217L) +#define STATUS_CANNOT_LOAD_REGISTRY_FILE ((NTSTATUS)0xC0000218L) +#define STATUS_DEBUG_ATTACH_FAILED ((NTSTATUS)0xC0000219L) +#define STATUS_SYSTEM_PROCESS_TERMINATED ((NTSTATUS)0xC000021AL) +#define STATUS_DATA_NOT_ACCEPTED ((NTSTATUS)0xC000021BL) +#define STATUS_NO_BROWSER_SERVERS_FOUND ((NTSTATUS)0xC000021CL) +#define STATUS_VDM_HARD_ERROR ((NTSTATUS)0xC000021DL) +#define STATUS_DRIVER_CANCEL_TIMEOUT ((NTSTATUS)0xC000021EL) +#define STATUS_REPLY_MESSAGE_MISMATCH ((NTSTATUS)0xC000021FL) +#define STATUS_MAPPED_ALIGNMENT ((NTSTATUS)0xC0000220L) +#define STATUS_IMAGE_CHECKSUM_MISMATCH ((NTSTATUS)0xC0000221L) +#define STATUS_LOST_WRITEBEHIND_DATA ((NTSTATUS)0xC0000222L) +#define STATUS_CLIENT_SERVER_PARAMETERS_INVALID ((NTSTATUS)0xC0000223L) +#define STATUS_PASSWORD_MUST_CHANGE ((NTSTATUS)0xC0000224L) +#define STATUS_NOT_FOUND ((NTSTATUS)0xC0000225L) +#define STATUS_NOT_TINY_STREAM ((NTSTATUS)0xC0000226L) +#define STATUS_RECOVERY_FAILURE ((NTSTATUS)0xC0000227L) +#define STATUS_STACK_OVERFLOW_READ ((NTSTATUS)0xC0000228L) +#define STATUS_FAIL_CHECK ((NTSTATUS)0xC0000229L) +#define STATUS_DUPLICATE_OBJECTID ((NTSTATUS)0xC000022AL) +#define STATUS_OBJECTID_EXISTS ((NTSTATUS)0xC000022BL) +#define STATUS_CONVERT_TO_LARGE ((NTSTATUS)0xC000022CL) +#define STATUS_RETRY ((NTSTATUS)0xC000022DL) +#define STATUS_FOUND_OUT_OF_SCOPE ((NTSTATUS)0xC000022EL) +#define STATUS_ALLOCATE_BUCKET ((NTSTATUS)0xC000022FL) +#define STATUS_PROPSET_NOT_FOUND ((NTSTATUS)0xC0000230L) +#define STATUS_MARSHALL_OVERFLOW ((NTSTATUS)0xC0000231L) +#define STATUS_INVALID_VARIANT ((NTSTATUS)0xC0000232L) +#define STATUS_DOMAIN_CONTROLLER_NOT_FOUND ((NTSTATUS)0xC0000233L) +#define STATUS_ACCOUNT_LOCKED_OUT ((NTSTATUS)0xC0000234L) +#define STATUS_HANDLE_NOT_CLOSABLE ((NTSTATUS)0xC0000235L) +#define STATUS_CONNECTION_REFUSED ((NTSTATUS)0xC0000236L) +#define STATUS_GRACEFUL_DISCONNECT ((NTSTATUS)0xC0000237L) +#define STATUS_ADDRESS_ALREADY_ASSOCIATED ((NTSTATUS)0xC0000238L) +#define STATUS_ADDRESS_NOT_ASSOCIATED ((NTSTATUS)0xC0000239L) +#define STATUS_CONNECTION_INVALID ((NTSTATUS)0xC000023AL) +#define STATUS_CONNECTION_ACTIVE ((NTSTATUS)0xC000023BL) +#define STATUS_NETWORK_UNREACHABLE ((NTSTATUS)0xC000023CL) +#define STATUS_HOST_UNREACHABLE ((NTSTATUS)0xC000023DL) +#define STATUS_PROTOCOL_UNREACHABLE ((NTSTATUS)0xC000023EL) +#define STATUS_PORT_UNREACHABLE ((NTSTATUS)0xC000023FL) +#define STATUS_REQUEST_ABORTED ((NTSTATUS)0xC0000240L) +#define STATUS_CONNECTION_ABORTED ((NTSTATUS)0xC0000241L) +#define STATUS_BAD_COMPRESSION_BUFFER ((NTSTATUS)0xC0000242L) +#define STATUS_USER_MAPPED_FILE ((NTSTATUS)0xC0000243L) +#define STATUS_AUDIT_FAILED ((NTSTATUS)0xC0000244L) +#define STATUS_TIMER_RESOLUTION_NOT_SET ((NTSTATUS)0xC0000245L) +#define STATUS_CONNECTION_COUNT_LIMIT ((NTSTATUS)0xC0000246L) +#define STATUS_LOGIN_TIME_RESTRICTION ((NTSTATUS)0xC0000247L) +#define STATUS_LOGIN_WKSTA_RESTRICTION ((NTSTATUS)0xC0000248L) +#define STATUS_IMAGE_MP_UP_MISMATCH ((NTSTATUS)0xC0000249L) +#define STATUS_INSUFFICIENT_LOGON_INFO ((NTSTATUS)0xC0000250L) +#define STATUS_BAD_DLL_ENTRYPOINT ((NTSTATUS)0xC0000251L) +#define STATUS_BAD_SERVICE_ENTRYPOINT ((NTSTATUS)0xC0000252L) +#define STATUS_LPC_REPLY_LOST ((NTSTATUS)0xC0000253L) +#define STATUS_IP_ADDRESS_CONFLICT1 ((NTSTATUS)0xC0000254L) +#define STATUS_IP_ADDRESS_CONFLICT2 ((NTSTATUS)0xC0000255L) +#define STATUS_REGISTRY_QUOTA_LIMIT ((NTSTATUS)0xC0000256L) +#define STATUS_PATH_NOT_COVERED ((NTSTATUS)0xC0000257L) +#define STATUS_NO_CALLBACK_ACTIVE ((NTSTATUS)0xC0000258L) +#define STATUS_LICENSE_QUOTA_EXCEEDED ((NTSTATUS)0xC0000259L) +#define STATUS_PWD_TOO_SHORT ((NTSTATUS)0xC000025AL) +#define STATUS_PWD_TOO_RECENT ((NTSTATUS)0xC000025BL) +#define STATUS_PWD_HISTORY_CONFLICT ((NTSTATUS)0xC000025CL) +#define STATUS_PLUGPLAY_NO_DEVICE ((NTSTATUS)0xC000025EL) +#define STATUS_UNSUPPORTED_COMPRESSION ((NTSTATUS)0xC000025FL) +#define STATUS_INVALID_HW_PROFILE ((NTSTATUS)0xC0000260L) +#define STATUS_INVALID_PLUGPLAY_DEVICE_PATH ((NTSTATUS)0xC0000261L) +#define STATUS_DRIVER_ORDINAL_NOT_FOUND ((NTSTATUS)0xC0000262L) +#define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND ((NTSTATUS)0xC0000263L) +#define STATUS_RESOURCE_NOT_OWNED ((NTSTATUS)0xC0000264L) +#define STATUS_TOO_MANY_LINKS ((NTSTATUS)0xC0000265L) +#define STATUS_QUOTA_LIST_INCONSISTENT ((NTSTATUS)0xC0000266L) +#define STATUS_FILE_IS_OFFLINE ((NTSTATUS)0xC0000267L) +#define STATUS_EVALUATION_EXPIRATION ((NTSTATUS)0xC0000268L) +#define STATUS_ILLEGAL_DLL_RELOCATION ((NTSTATUS)0xC0000269L) +#define STATUS_LICENSE_VIOLATION ((NTSTATUS)0xC000026AL) +#define STATUS_DLL_INIT_FAILED_LOGOFF ((NTSTATUS)0xC000026BL) +#define STATUS_DRIVER_UNABLE_TO_LOAD ((NTSTATUS)0xC000026CL) +#define STATUS_DFS_UNAVAILABLE ((NTSTATUS)0xC000026DL) +#define STATUS_VOLUME_DISMOUNTED ((NTSTATUS)0xC000026EL) +#define STATUS_WX86_INTERNAL_ERROR ((NTSTATUS)0xC000026FL) +#define STATUS_WX86_FLOAT_STACK_CHECK ((NTSTATUS)0xC0000270L) +#define STATUS_VALIDATE_CONTINUE ((NTSTATUS)0xC0000271L) +#define STATUS_NO_MATCH ((NTSTATUS)0xC0000272L) +#define STATUS_NO_MORE_MATCHES ((NTSTATUS)0xC0000273L) +#define STATUS_NOT_A_REPARSE_POINT ((NTSTATUS)0xC0000275L) +#define STATUS_IO_REPARSE_TAG_INVALID ((NTSTATUS)0xC0000276L) +#define STATUS_IO_REPARSE_TAG_MISMATCH ((NTSTATUS)0xC0000277L) +#define STATUS_IO_REPARSE_DATA_INVALID ((NTSTATUS)0xC0000278L) +#define STATUS_IO_REPARSE_TAG_NOT_HANDLED ((NTSTATUS)0xC0000279L) +#define STATUS_REPARSE_POINT_NOT_RESOLVED ((NTSTATUS)0xC0000280L) +#define STATUS_DIRECTORY_IS_A_REPARSE_POINT ((NTSTATUS)0xC0000281L) +#define STATUS_RANGE_LIST_CONFLICT ((NTSTATUS)0xC0000282L) +#define STATUS_SOURCE_ELEMENT_EMPTY ((NTSTATUS)0xC0000283L) +#define STATUS_DESTINATION_ELEMENT_FULL ((NTSTATUS)0xC0000284L) +#define STATUS_ILLEGAL_ELEMENT_ADDRESS ((NTSTATUS)0xC0000285L) +#define STATUS_MAGAZINE_NOT_PRESENT ((NTSTATUS)0xC0000286L) +#define STATUS_REINITIALIZATION_NEEDED ((NTSTATUS)0xC0000287L) +#define STATUS_DEVICE_REQUIRES_CLEANING ((NTSTATUS)0x80000288L) +#define STATUS_DEVICE_DOOR_OPEN ((NTSTATUS)0x80000289L) +#define STATUS_ENCRYPTION_FAILED ((NTSTATUS)0xC000028AL) +#define STATUS_DECRYPTION_FAILED ((NTSTATUS)0xC000028BL) +#define STATUS_RANGE_NOT_FOUND ((NTSTATUS)0xC000028CL) +#define STATUS_NO_RECOVERY_POLICY ((NTSTATUS)0xC000028DL) +#define STATUS_NO_EFS ((NTSTATUS)0xC000028EL) +#define STATUS_WRONG_EFS ((NTSTATUS)0xC000028FL) +#define STATUS_NO_USER_KEYS ((NTSTATUS)0xC0000290L) +#define STATUS_FILE_NOT_ENCRYPTED ((NTSTATUS)0xC0000291L) +#define STATUS_NOT_EXPORT_FORMAT ((NTSTATUS)0xC0000292L) +#define STATUS_FILE_ENCRYPTED ((NTSTATUS)0xC0000293L) +#define STATUS_WAKE_SYSTEM ((NTSTATUS)0x40000294L) +#define STATUS_WMI_GUID_NOT_FOUND ((NTSTATUS)0xC0000295L) +#define STATUS_WMI_INSTANCE_NOT_FOUND ((NTSTATUS)0xC0000296L) +#define STATUS_WMI_ITEMID_NOT_FOUND ((NTSTATUS)0xC0000297L) +#define STATUS_WMI_TRY_AGAIN ((NTSTATUS)0xC0000298L) +#define STATUS_SHARED_POLICY ((NTSTATUS)0xC0000299L) +#define STATUS_POLICY_OBJECT_NOT_FOUND ((NTSTATUS)0xC000029AL) +#define STATUS_POLICY_ONLY_IN_DS ((NTSTATUS)0xC000029BL) +#define STATUS_VOLUME_NOT_UPGRADED ((NTSTATUS)0xC000029CL) +#define STATUS_REMOTE_STORAGE_NOT_ACTIVE ((NTSTATUS)0xC000029DL) +#define STATUS_REMOTE_STORAGE_MEDIA_ERROR ((NTSTATUS)0xC000029EL) +#define STATUS_NO_TRACKING_SERVICE ((NTSTATUS)0xC000029FL) +#define STATUS_SERVER_SID_MISMATCH ((NTSTATUS)0xC00002A0L) +#define STATUS_DS_NO_ATTRIBUTE_OR_VALUE ((NTSTATUS)0xC00002A1L) +#define STATUS_DS_INVALID_ATTRIBUTE_SYNTAX ((NTSTATUS)0xC00002A2L) +#define STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED ((NTSTATUS)0xC00002A3L) +#define STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS ((NTSTATUS)0xC00002A4L) +#define STATUS_DS_BUSY ((NTSTATUS)0xC00002A5L) +#define STATUS_DS_UNAVAILABLE ((NTSTATUS)0xC00002A6L) +#define STATUS_DS_NO_RIDS_ALLOCATED ((NTSTATUS)0xC00002A7L) +#define STATUS_DS_NO_MORE_RIDS ((NTSTATUS)0xC00002A8L) +#define STATUS_DS_INCORRECT_ROLE_OWNER ((NTSTATUS)0xC00002A9L) +#define STATUS_DS_RIDMGR_INIT_ERROR ((NTSTATUS)0xC00002AAL) +#define STATUS_DS_OBJ_CLASS_VIOLATION ((NTSTATUS)0xC00002ABL) +#define STATUS_DS_CANT_ON_NON_LEAF ((NTSTATUS)0xC00002ACL) +#define STATUS_DS_CANT_ON_RDN ((NTSTATUS)0xC00002ADL) +#define STATUS_DS_CANT_MOD_OBJ_CLASS ((NTSTATUS)0xC00002AEL) +#define STATUS_DS_CROSS_DOM_MOVE_FAILED ((NTSTATUS)0xC00002AFL) +#define STATUS_DS_GC_NOT_AVAILABLE ((NTSTATUS)0xC00002B0L) +#define STATUS_DIRECTORY_SERVICE_REQUIRED ((NTSTATUS)0xC00002B1L) +#define STATUS_REPARSE_ATTRIBUTE_CONFLICT ((NTSTATUS)0xC00002B2L) +#define STATUS_CANT_ENABLE_DENY_ONLY ((NTSTATUS)0xC00002B3L) +#define STATUS_FLOAT_MULTIPLE_FAULTS ((NTSTATUS)0xC00002B4L) +#define STATUS_FLOAT_MULTIPLE_TRAPS ((NTSTATUS)0xC00002B5L) +#define STATUS_DEVICE_REMOVED ((NTSTATUS)0xC00002B6L) +#define STATUS_JOURNAL_DELETE_IN_PROGRESS ((NTSTATUS)0xC00002B7L) +#define STATUS_JOURNAL_NOT_ACTIVE ((NTSTATUS)0xC00002B8L) +#define STATUS_NOINTERFACE ((NTSTATUS)0xC00002B9L) +#define STATUS_DS_ADMIN_LIMIT_EXCEEDED ((NTSTATUS)0xC00002C1L) +#define STATUS_DRIVER_FAILED_SLEEP ((NTSTATUS)0xC00002C2L) +#define STATUS_MUTUAL_AUTHENTICATION_FAILED ((NTSTATUS)0xC00002C3L) +#define STATUS_CORRUPT_SYSTEM_FILE ((NTSTATUS)0xC00002C4L) +#define STATUS_DATATYPE_MISALIGNMENT_ERROR ((NTSTATUS)0xC00002C5L) +#define STATUS_WMI_READ_ONLY ((NTSTATUS)0xC00002C6L) +#define STATUS_WMI_SET_FAILURE ((NTSTATUS)0xC00002C7L) +#define STATUS_COMMITMENT_MINIMUM ((NTSTATUS)0xC00002C8L) +#define STATUS_REG_NAT_CONSUMPTION ((NTSTATUS)0xC00002C9L) +#define STATUS_TRANSPORT_FULL ((NTSTATUS)0xC00002CAL) +#define STATUS_DS_SAM_INIT_FAILURE ((NTSTATUS)0xC00002CBL) +#define STATUS_ONLY_IF_CONNECTED ((NTSTATUS)0xC00002CCL) +#define STATUS_DS_SENSITIVE_GROUP_VIOLATION ((NTSTATUS)0xC00002CDL) +#define STATUS_PNP_RESTART_ENUMERATION ((NTSTATUS)0xC00002CEL) +#define STATUS_JOURNAL_ENTRY_DELETED ((NTSTATUS)0xC00002CFL) +#define STATUS_DS_CANT_MOD_PRIMARYGROUPID ((NTSTATUS)0xC00002D0L) +#define STATUS_SYSTEM_IMAGE_BAD_SIGNATURE ((NTSTATUS)0xC00002D1L) +#define STATUS_PNP_REBOOT_REQUIRED ((NTSTATUS)0xC00002D2L) +#define STATUS_POWER_STATE_INVALID ((NTSTATUS)0xC00002D3L) +#define STATUS_DS_INVALID_GROUP_TYPE ((NTSTATUS)0xC00002D4L) +#define STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN ((NTSTATUS)0xC00002D5L) +#define STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN ((NTSTATUS)0xC00002D6L) +#define STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER ((NTSTATUS)0xC00002D7L) +#define STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER ((NTSTATUS)0xC00002D8L) +#define STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER ((NTSTATUS)0xC00002D9L) +#define STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER ((NTSTATUS)0xC00002DAL) +#define STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER ((NTSTATUS)0xC00002DBL) +#define STATUS_DS_HAVE_PRIMARY_MEMBERS ((NTSTATUS)0xC00002DCL) +#define STATUS_WMI_NOT_SUPPORTED ((NTSTATUS)0xC00002DDL) +#define STATUS_INSUFFICIENT_POWER ((NTSTATUS)0xC00002DEL) +#define STATUS_SAM_NEED_BOOTKEY_PASSWORD ((NTSTATUS)0xC00002DFL) +#define STATUS_SAM_NEED_BOOTKEY_FLOPPY ((NTSTATUS)0xC00002E0L) +#define STATUS_DS_CANT_START ((NTSTATUS)0xC00002E1L) +#define STATUS_DS_INIT_FAILURE ((NTSTATUS)0xC00002E2L) +#define STATUS_SAM_INIT_FAILURE ((NTSTATUS)0xC00002E3L) +#define STATUS_DS_GC_REQUIRED ((NTSTATUS)0xC00002E4L) +#define STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY ((NTSTATUS)0xC00002E5L) +#define STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS ((NTSTATUS)0xC00002E6L) +#define STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED ((NTSTATUS)0xC00002E7L) +#define STATUS_MULTIPLE_FAULT_VIOLATION ((NTSTATUS)0xC00002E8L) +#define STATUS_CURRENT_DOMAIN_NOT_ALLOWED ((NTSTATUS)0xC00002E9L) +#define STATUS_CANNOT_MAKE ((NTSTATUS)0xC00002EAL) +#define STATUS_SYSTEM_SHUTDOWN ((NTSTATUS)0xC00002EBL) +#define STATUS_DS_INIT_FAILURE_CONSOLE ((NTSTATUS)0xC00002ECL) +#define STATUS_DS_SAM_INIT_FAILURE_CONSOLE ((NTSTATUS)0xC00002EDL) +#define STATUS_UNFINISHED_CONTEXT_DELETED ((NTSTATUS)0xC00002EEL) +#define STATUS_NO_TGT_REPLY ((NTSTATUS)0xC00002EFL) +#define STATUS_OBJECTID_NOT_FOUND ((NTSTATUS)0xC00002F0L) +#define STATUS_NO_IP_ADDRESSES ((NTSTATUS)0xC00002F1L) +#define STATUS_WRONG_CREDENTIAL_HANDLE ((NTSTATUS)0xC00002F2L) +#define STATUS_CRYPTO_SYSTEM_INVALID ((NTSTATUS)0xC00002F3L) +#define STATUS_MAX_REFERRALS_EXCEEDED ((NTSTATUS)0xC00002F4L) +#define STATUS_MUST_BE_KDC ((NTSTATUS)0xC00002F5L) +#define STATUS_STRONG_CRYPTO_NOT_SUPPORTED ((NTSTATUS)0xC00002F6L) +#define STATUS_TOO_MANY_PRINCIPALS ((NTSTATUS)0xC00002F7L) +#define STATUS_NO_PA_DATA ((NTSTATUS)0xC00002F8L) +#define STATUS_PKINIT_NAME_MISMATCH ((NTSTATUS)0xC00002F9L) +#define STATUS_SMARTCARD_LOGON_REQUIRED ((NTSTATUS)0xC00002FAL) +#define STATUS_KDC_INVALID_REQUEST ((NTSTATUS)0xC00002FBL) +#define STATUS_KDC_UNABLE_TO_REFER ((NTSTATUS)0xC00002FCL) +#define STATUS_KDC_UNKNOWN_ETYPE ((NTSTATUS)0xC00002FDL) +#define STATUS_SHUTDOWN_IN_PROGRESS ((NTSTATUS)0xC00002FEL) +#define STATUS_SERVER_SHUTDOWN_IN_PROGRESS ((NTSTATUS)0xC00002FFL) +#define STATUS_NOT_SUPPORTED_ON_SBS ((NTSTATUS)0xC0000300L) +#define STATUS_WMI_GUID_DISCONNECTED ((NTSTATUS)0xC0000301L) +#define STATUS_WMI_ALREADY_DISABLED ((NTSTATUS)0xC0000302L) +#define STATUS_WMI_ALREADY_ENABLED ((NTSTATUS)0xC0000303L) +#define STATUS_MFT_TOO_FRAGMENTED ((NTSTATUS)0xC0000304L) +#define STATUS_COPY_PROTECTION_FAILURE ((NTSTATUS)0xC0000305L) +#define STATUS_CSS_AUTHENTICATION_FAILURE ((NTSTATUS)0xC0000306L) +#define STATUS_CSS_KEY_NOT_PRESENT ((NTSTATUS)0xC0000307L) +#define STATUS_CSS_KEY_NOT_ESTABLISHED ((NTSTATUS)0xC0000308L) +#define STATUS_CSS_SCRAMBLED_SECTOR ((NTSTATUS)0xC0000309L) +#define STATUS_CSS_REGION_MISMATCH ((NTSTATUS)0xC000030AL) +#define STATUS_CSS_RESETS_EXHAUSTED ((NTSTATUS)0xC000030BL) +#define STATUS_PKINIT_FAILURE ((NTSTATUS)0xC0000320L) +#define STATUS_SMARTCARD_SUBSYSTEM_FAILURE ((NTSTATUS)0xC0000321L) +#define STATUS_NO_KERB_KEY ((NTSTATUS)0xC0000322L) +#define STATUS_HOST_DOWN ((NTSTATUS)0xC0000350L) +#define STATUS_UNSUPPORTED_PREAUTH ((NTSTATUS)0xC0000351L) +#define STATUS_EFS_ALG_BLOB_TOO_BIG ((NTSTATUS)0xC0000352L) +#define STATUS_PORT_NOT_SET ((NTSTATUS)0xC0000353L) +#define STATUS_DEBUGGER_INACTIVE ((NTSTATUS)0xC0000354L) +#define STATUS_DS_VERSION_CHECK_FAILURE ((NTSTATUS)0xC0000355L) +#define STATUS_AUDITING_DISABLED ((NTSTATUS)0xC0000356L) +#define STATUS_PRENT4_MACHINE_ACCOUNT ((NTSTATUS)0xC0000357L) +#define STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER ((NTSTATUS)0xC0000358L) +#define STATUS_INVALID_IMAGE_WIN_32 ((NTSTATUS)0xC0000359L) +#define STATUS_INVALID_IMAGE_WIN_64 ((NTSTATUS)0xC000035AL) +#define STATUS_BAD_BINDINGS ((NTSTATUS)0xC000035BL) +#define STATUS_NETWORK_SESSION_EXPIRED ((NTSTATUS)0xC000035CL) +#define STATUS_APPHELP_BLOCK ((NTSTATUS)0xC000035DL) +#define STATUS_ALL_SIDS_FILTERED ((NTSTATUS)0xC000035EL) +#define STATUS_NOT_SAFE_MODE_DRIVER ((NTSTATUS)0xC000035FL) +#define STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT ((NTSTATUS)0xC0000361L) +#define STATUS_ACCESS_DISABLED_BY_POLICY_PATH ((NTSTATUS)0xC0000362L) +#define STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER ((NTSTATUS)0xC0000363L) +#define STATUS_ACCESS_DISABLED_BY_POLICY_OTHER ((NTSTATUS)0xC0000364L) +#define STATUS_FAILED_DRIVER_ENTRY ((NTSTATUS)0xC0000365L) +#define STATUS_DEVICE_ENUMERATION_ERROR ((NTSTATUS)0xC0000366L) +#define STATUS_WAIT_FOR_OPLOCK ((NTSTATUS)0x00000367L) +#define STATUS_MOUNT_POINT_NOT_RESOLVED ((NTSTATUS)0xC0000368L) +#define STATUS_INVALID_DEVICE_OBJECT_PARAMETER ((NTSTATUS)0xC0000369L) +#define STATUS_MCA_OCCURED ((NTSTATUS)0xC000036AL) +#define STATUS_DRIVER_BLOCKED_CRITICAL ((NTSTATUS)0xC000036BL) +#define STATUS_DRIVER_BLOCKED ((NTSTATUS)0xC000036CL) +#define STATUS_DRIVER_DATABASE_ERROR ((NTSTATUS)0xC000036DL) +#define STATUS_SYSTEM_HIVE_TOO_LARGE ((NTSTATUS)0xC000036EL) +#define STATUS_INVALID_IMPORT_OF_NON_DLL ((NTSTATUS)0xC000036FL) +#define STATUS_DS_SHUTTING_DOWN ((NTSTATUS)0x40000370L) +#define STATUS_SMARTCARD_WRONG_PIN ((NTSTATUS)0xC0000380L) +#define STATUS_SMARTCARD_CARD_BLOCKED ((NTSTATUS)0xC0000381L) +#define STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED ((NTSTATUS)0xC0000382L) +#define STATUS_SMARTCARD_NO_CARD ((NTSTATUS)0xC0000383L) +#define STATUS_SMARTCARD_NO_KEY_CONTAINER ((NTSTATUS)0xC0000384L) +#define STATUS_SMARTCARD_NO_CERTIFICATE ((NTSTATUS)0xC0000385L) +#define STATUS_SMARTCARD_NO_KEYSET ((NTSTATUS)0xC0000386L) +#define STATUS_SMARTCARD_IO_ERROR ((NTSTATUS)0xC0000387L) +#define STATUS_DOWNGRADE_DETECTED ((NTSTATUS)0xC0000388L) +#define STATUS_SMARTCARD_CERT_REVOKED ((NTSTATUS)0xC0000389L) +#define STATUS_ISSUING_CA_UNTRUSTED ((NTSTATUS)0xC000038AL) +#define STATUS_REVOCATION_OFFLINE_C ((NTSTATUS)0xC000038BL) +#define STATUS_PKINIT_CLIENT_FAILURE ((NTSTATUS)0xC000038CL) +#define STATUS_SMARTCARD_CERT_EXPIRED ((NTSTATUS)0xC000038DL) +#define STATUS_DRIVER_FAILED_PRIOR_UNLOAD ((NTSTATUS)0xC000038EL) +#define STATUS_WOW_ASSERTION ((NTSTATUS)0xC0009898L) +#define RPC_NT_INVALID_STRING_BINDING ((NTSTATUS)0xC0020001L) +#define RPC_NT_WRONG_KIND_OF_BINDING ((NTSTATUS)0xC0020002L) +#define RPC_NT_INVALID_BINDING ((NTSTATUS)0xC0020003L) +#define RPC_NT_PROTSEQ_NOT_SUPPORTED ((NTSTATUS)0xC0020004L) +#define RPC_NT_INVALID_RPC_PROTSEQ ((NTSTATUS)0xC0020005L) +#define RPC_NT_INVALID_STRING_UUID ((NTSTATUS)0xC0020006L) +#define RPC_NT_INVALID_ENDPOINT_FORMAT ((NTSTATUS)0xC0020007L) +#define RPC_NT_INVALID_NET_ADDR ((NTSTATUS)0xC0020008L) +#define RPC_NT_NO_ENDPOINT_FOUND ((NTSTATUS)0xC0020009L) +#define RPC_NT_INVALID_TIMEOUT ((NTSTATUS)0xC002000AL) +#define RPC_NT_OBJECT_NOT_FOUND ((NTSTATUS)0xC002000BL) +#define RPC_NT_ALREADY_REGISTERED ((NTSTATUS)0xC002000CL) +#define RPC_NT_TYPE_ALREADY_REGISTERED ((NTSTATUS)0xC002000DL) +#define RPC_NT_ALREADY_LISTENING ((NTSTATUS)0xC002000EL) +#define RPC_NT_NO_PROTSEQS_REGISTERED ((NTSTATUS)0xC002000FL) +#define RPC_NT_NOT_LISTENING ((NTSTATUS)0xC0020010L) +#define RPC_NT_UNKNOWN_MGR_TYPE ((NTSTATUS)0xC0020011L) +#define RPC_NT_UNKNOWN_IF ((NTSTATUS)0xC0020012L) +#define RPC_NT_NO_BINDINGS ((NTSTATUS)0xC0020013L) +#define RPC_NT_NO_PROTSEQS ((NTSTATUS)0xC0020014L) +#define RPC_NT_CANT_CREATE_ENDPOINT ((NTSTATUS)0xC0020015L) +#define RPC_NT_OUT_OF_RESOURCES ((NTSTATUS)0xC0020016L) +#define RPC_NT_SERVER_UNAVAILABLE ((NTSTATUS)0xC0020017L) +#define RPC_NT_SERVER_TOO_BUSY ((NTSTATUS)0xC0020018L) +#define RPC_NT_INVALID_NETWORK_OPTIONS ((NTSTATUS)0xC0020019L) +#define RPC_NT_NO_CALL_ACTIVE ((NTSTATUS)0xC002001AL) +#define RPC_NT_CALL_FAILED ((NTSTATUS)0xC002001BL) +#define RPC_NT_CALL_FAILED_DNE ((NTSTATUS)0xC002001CL) +#define RPC_NT_PROTOCOL_ERROR ((NTSTATUS)0xC002001DL) +#define RPC_NT_UNSUPPORTED_TRANS_SYN ((NTSTATUS)0xC002001FL) +#define RPC_NT_UNSUPPORTED_TYPE ((NTSTATUS)0xC0020021L) +#define RPC_NT_INVALID_TAG ((NTSTATUS)0xC0020022L) +#define RPC_NT_INVALID_BOUND ((NTSTATUS)0xC0020023L) +#define RPC_NT_NO_ENTRY_NAME ((NTSTATUS)0xC0020024L) +#define RPC_NT_INVALID_NAME_SYNTAX ((NTSTATUS)0xC0020025L) +#define RPC_NT_UNSUPPORTED_NAME_SYNTAX ((NTSTATUS)0xC0020026L) +#define RPC_NT_UUID_NO_ADDRESS ((NTSTATUS)0xC0020028L) +#define RPC_NT_DUPLICATE_ENDPOINT ((NTSTATUS)0xC0020029L) +#define RPC_NT_UNKNOWN_AUTHN_TYPE ((NTSTATUS)0xC002002AL) +#define RPC_NT_MAX_CALLS_TOO_SMALL ((NTSTATUS)0xC002002BL) +#define RPC_NT_STRING_TOO_LONG ((NTSTATUS)0xC002002CL) +#define RPC_NT_PROTSEQ_NOT_FOUND ((NTSTATUS)0xC002002DL) +#define RPC_NT_PROCNUM_OUT_OF_RANGE ((NTSTATUS)0xC002002EL) +#define RPC_NT_BINDING_HAS_NO_AUTH ((NTSTATUS)0xC002002FL) +#define RPC_NT_UNKNOWN_AUTHN_SERVICE ((NTSTATUS)0xC0020030L) +#define RPC_NT_UNKNOWN_AUTHN_LEVEL ((NTSTATUS)0xC0020031L) +#define RPC_NT_INVALID_AUTH_IDENTITY ((NTSTATUS)0xC0020032L) +#define RPC_NT_UNKNOWN_AUTHZ_SERVICE ((NTSTATUS)0xC0020033L) +#define EPT_NT_INVALID_ENTRY ((NTSTATUS)0xC0020034L) +#define EPT_NT_CANT_PERFORM_OP ((NTSTATUS)0xC0020035L) +#define EPT_NT_NOT_REGISTERED ((NTSTATUS)0xC0020036L) +#define RPC_NT_NOTHING_TO_EXPORT ((NTSTATUS)0xC0020037L) +#define RPC_NT_INCOMPLETE_NAME ((NTSTATUS)0xC0020038L) +#define RPC_NT_INVALID_VERS_OPTION ((NTSTATUS)0xC0020039L) +#define RPC_NT_NO_MORE_MEMBERS ((NTSTATUS)0xC002003AL) +#define RPC_NT_NOT_ALL_OBJS_UNEXPORTED ((NTSTATUS)0xC002003BL) +#define RPC_NT_INTERFACE_NOT_FOUND ((NTSTATUS)0xC002003CL) +#define RPC_NT_ENTRY_ALREADY_EXISTS ((NTSTATUS)0xC002003DL) +#define RPC_NT_ENTRY_NOT_FOUND ((NTSTATUS)0xC002003EL) +#define RPC_NT_NAME_SERVICE_UNAVAILABLE ((NTSTATUS)0xC002003FL) +#define RPC_NT_INVALID_NAF_ID ((NTSTATUS)0xC0020040L) +#define RPC_NT_CANNOT_SUPPORT ((NTSTATUS)0xC0020041L) +#define RPC_NT_NO_CONTEXT_AVAILABLE ((NTSTATUS)0xC0020042L) +#define RPC_NT_INTERNAL_ERROR ((NTSTATUS)0xC0020043L) +#define RPC_NT_ZERO_DIVIDE ((NTSTATUS)0xC0020044L) +#define RPC_NT_ADDRESS_ERROR ((NTSTATUS)0xC0020045L) +#define RPC_NT_FP_DIV_ZERO ((NTSTATUS)0xC0020046L) +#define RPC_NT_FP_UNDERFLOW ((NTSTATUS)0xC0020047L) +#define RPC_NT_FP_OVERFLOW ((NTSTATUS)0xC0020048L) +#define RPC_NT_NO_MORE_ENTRIES ((NTSTATUS)0xC0030001L) +#define RPC_NT_SS_CHAR_TRANS_OPEN_FAIL ((NTSTATUS)0xC0030002L) +#define RPC_NT_SS_CHAR_TRANS_SHORT_FILE ((NTSTATUS)0xC0030003L) +#define RPC_NT_SS_IN_NULL_CONTEXT ((NTSTATUS)0xC0030004L) +#define RPC_NT_SS_CONTEXT_MISMATCH ((NTSTATUS)0xC0030005L) +#define RPC_NT_SS_CONTEXT_DAMAGED ((NTSTATUS)0xC0030006L) +#define RPC_NT_SS_HANDLES_MISMATCH ((NTSTATUS)0xC0030007L) +#define RPC_NT_SS_CANNOT_GET_CALL_HANDLE ((NTSTATUS)0xC0030008L) +#define RPC_NT_NULL_REF_POINTER ((NTSTATUS)0xC0030009L) +#define RPC_NT_ENUM_VALUE_OUT_OF_RANGE ((NTSTATUS)0xC003000AL) +#define RPC_NT_BYTE_COUNT_TOO_SMALL ((NTSTATUS)0xC003000BL) +#define RPC_NT_BAD_STUB_DATA ((NTSTATUS)0xC003000CL) +#define RPC_NT_CALL_IN_PROGRESS ((NTSTATUS)0xC0020049L) +#define RPC_NT_NO_MORE_BINDINGS ((NTSTATUS)0xC002004AL) +#define RPC_NT_GROUP_MEMBER_NOT_FOUND ((NTSTATUS)0xC002004BL) +#define EPT_NT_CANT_CREATE ((NTSTATUS)0xC002004CL) +#define RPC_NT_INVALID_OBJECT ((NTSTATUS)0xC002004DL) +#define RPC_NT_NO_INTERFACES ((NTSTATUS)0xC002004FL) +#define RPC_NT_CALL_CANCELLED ((NTSTATUS)0xC0020050L) +#define RPC_NT_BINDING_INCOMPLETE ((NTSTATUS)0xC0020051L) +#define RPC_NT_COMM_FAILURE ((NTSTATUS)0xC0020052L) +#define RPC_NT_UNSUPPORTED_AUTHN_LEVEL ((NTSTATUS)0xC0020053L) +#define RPC_NT_NO_PRINC_NAME ((NTSTATUS)0xC0020054L) +#define RPC_NT_NOT_RPC_ERROR ((NTSTATUS)0xC0020055L) +#define RPC_NT_UUID_LOCAL_ONLY ((NTSTATUS)0x40020056L) +#define RPC_NT_SEC_PKG_ERROR ((NTSTATUS)0xC0020057L) +#define RPC_NT_NOT_CANCELLED ((NTSTATUS)0xC0020058L) +#define RPC_NT_INVALID_ES_ACTION ((NTSTATUS)0xC0030059L) +#define RPC_NT_WRONG_ES_VERSION ((NTSTATUS)0xC003005AL) +#define RPC_NT_WRONG_STUB_VERSION ((NTSTATUS)0xC003005BL) +#define RPC_NT_INVALID_PIPE_OBJECT ((NTSTATUS)0xC003005CL) +#define RPC_NT_INVALID_PIPE_OPERATION ((NTSTATUS)0xC003005DL) +#define RPC_NT_WRONG_PIPE_VERSION ((NTSTATUS)0xC003005EL) +#define RPC_NT_PIPE_CLOSED ((NTSTATUS)0xC003005FL) +#define RPC_NT_PIPE_DISCIPLINE_ERROR ((NTSTATUS)0xC0030060L) +#define RPC_NT_PIPE_EMPTY ((NTSTATUS)0xC0030061L) +#define RPC_NT_INVALID_ASYNC_HANDLE ((NTSTATUS)0xC0020062L) +#define RPC_NT_INVALID_ASYNC_CALL ((NTSTATUS)0xC0020063L) +#define RPC_NT_SEND_INCOMPLETE ((NTSTATUS)0x400200AFL) +#define STATUS_ACPI_INVALID_OPCODE ((NTSTATUS)0xC0140001L) +#define STATUS_ACPI_STACK_OVERFLOW ((NTSTATUS)0xC0140002L) +#define STATUS_ACPI_ASSERT_FAILED ((NTSTATUS)0xC0140003L) +#define STATUS_ACPI_INVALID_INDEX ((NTSTATUS)0xC0140004L) +#define STATUS_ACPI_INVALID_ARGUMENT ((NTSTATUS)0xC0140005L) +#define STATUS_ACPI_FATAL ((NTSTATUS)0xC0140006L) +#define STATUS_ACPI_INVALID_SUPERNAME ((NTSTATUS)0xC0140007L) +#define STATUS_ACPI_INVALID_ARGTYPE ((NTSTATUS)0xC0140008L) +#define STATUS_ACPI_INVALID_OBJTYPE ((NTSTATUS)0xC0140009L) +#define STATUS_ACPI_INVALID_TARGETTYPE ((NTSTATUS)0xC014000AL) +#define STATUS_ACPI_INCORRECT_ARGUMENT_COUNT ((NTSTATUS)0xC014000BL) +#define STATUS_ACPI_ADDRESS_NOT_MAPPED ((NTSTATUS)0xC014000CL) +#define STATUS_ACPI_INVALID_EVENTTYPE ((NTSTATUS)0xC014000DL) +#define STATUS_ACPI_HANDLER_COLLISION ((NTSTATUS)0xC014000EL) +#define STATUS_ACPI_INVALID_DATA ((NTSTATUS)0xC014000FL) +#define STATUS_ACPI_INVALID_REGION ((NTSTATUS)0xC0140010L) +#define STATUS_ACPI_INVALID_ACCESS_SIZE ((NTSTATUS)0xC0140011L) +#define STATUS_ACPI_ACQUIRE_GLOBAL_LOCK ((NTSTATUS)0xC0140012L) +#define STATUS_ACPI_ALREADY_INITIALIZED ((NTSTATUS)0xC0140013L) +#define STATUS_ACPI_NOT_INITIALIZED ((NTSTATUS)0xC0140014L) +#define STATUS_ACPI_INVALID_MUTEX_LEVEL ((NTSTATUS)0xC0140015L) +#define STATUS_ACPI_MUTEX_NOT_OWNED ((NTSTATUS)0xC0140016L) +#define STATUS_ACPI_MUTEX_NOT_OWNER ((NTSTATUS)0xC0140017L) +#define STATUS_ACPI_RS_ACCESS ((NTSTATUS)0xC0140018L) +#define STATUS_ACPI_INVALID_TABLE ((NTSTATUS)0xC0140019L) +#define STATUS_ACPI_REG_HANDLER_FAILED ((NTSTATUS)0xC0140020L) +#define STATUS_ACPI_POWER_REQUEST_FAILED ((NTSTATUS)0xC0140021L) +#define STATUS_CTX_WINSTATION_NAME_INVALID ((NTSTATUS)0xC00A0001L) +#define STATUS_CTX_INVALID_PD ((NTSTATUS)0xC00A0002L) +#define STATUS_CTX_PD_NOT_FOUND ((NTSTATUS)0xC00A0003L) +#define STATUS_CTX_CDM_CONNECT ((NTSTATUS)0x400A0004L) +#define STATUS_CTX_CDM_DISCONNECT ((NTSTATUS)0x400A0005L) +#define STATUS_CTX_CLOSE_PENDING ((NTSTATUS)0xC00A0006L) +#define STATUS_CTX_NO_OUTBUF ((NTSTATUS)0xC00A0007L) +#define STATUS_CTX_MODEM_INF_NOT_FOUND ((NTSTATUS)0xC00A0008L) +#define STATUS_CTX_INVALID_MODEMNAME ((NTSTATUS)0xC00A0009L) +#define STATUS_CTX_RESPONSE_ERROR ((NTSTATUS)0xC00A000AL) +#define STATUS_CTX_MODEM_RESPONSE_TIMEOUT ((NTSTATUS)0xC00A000BL) +#define STATUS_CTX_MODEM_RESPONSE_NO_CARRIER ((NTSTATUS)0xC00A000CL) +#define STATUS_CTX_MODEM_RESPONSE_NO_DIALTONE ((NTSTATUS)0xC00A000DL) +#define STATUS_CTX_MODEM_RESPONSE_BUSY ((NTSTATUS)0xC00A000EL) +#define STATUS_CTX_MODEM_RESPONSE_VOICE ((NTSTATUS)0xC00A000FL) +#define STATUS_CTX_TD_ERROR ((NTSTATUS)0xC00A0010L) +#define STATUS_CTX_LICENSE_CLIENT_INVALID ((NTSTATUS)0xC00A0012L) +#define STATUS_CTX_LICENSE_NOT_AVAILABLE ((NTSTATUS)0xC00A0013L) +#define STATUS_CTX_LICENSE_EXPIRED ((NTSTATUS)0xC00A0014L) +#define STATUS_CTX_WINSTATION_NOT_FOUND ((NTSTATUS)0xC00A0015L) +#define STATUS_CTX_WINSTATION_NAME_COLLISION ((NTSTATUS)0xC00A0016L) +#define STATUS_CTX_WINSTATION_BUSY ((NTSTATUS)0xC00A0017L) +#define STATUS_CTX_BAD_VIDEO_MODE ((NTSTATUS)0xC00A0018L) +#define STATUS_CTX_GRAPHICS_INVALID ((NTSTATUS)0xC00A0022L) +#define STATUS_CTX_NOT_CONSOLE ((NTSTATUS)0xC00A0024L) +#define STATUS_CTX_CLIENT_QUERY_TIMEOUT ((NTSTATUS)0xC00A0026L) +#define STATUS_CTX_CONSOLE_DISCONNECT ((NTSTATUS)0xC00A0027L) +#define STATUS_CTX_CONSOLE_CONNECT ((NTSTATUS)0xC00A0028L) +#define STATUS_CTX_SHADOW_DENIED ((NTSTATUS)0xC00A002AL) +#define STATUS_CTX_WINSTATION_ACCESS_DENIED ((NTSTATUS)0xC00A002BL) +#define STATUS_CTX_INVALID_WD ((NTSTATUS)0xC00A002EL) +#define STATUS_CTX_WD_NOT_FOUND ((NTSTATUS)0xC00A002FL) +#define STATUS_CTX_SHADOW_INVALID ((NTSTATUS)0xC00A0030L) +#define STATUS_CTX_SHADOW_DISABLED ((NTSTATUS)0xC00A0031L) +#define STATUS_RDP_PROTOCOL_ERROR ((NTSTATUS)0xC00A0032L) +#define STATUS_CTX_CLIENT_LICENSE_NOT_SET ((NTSTATUS)0xC00A0033L) +#define STATUS_CTX_CLIENT_LICENSE_IN_USE ((NTSTATUS)0xC00A0034L) +#define STATUS_CTX_SHADOW_ENDED_BY_MODE_CHANGE ((NTSTATUS)0xC00A0035L) +#define STATUS_CTX_SHADOW_NOT_RUNNING ((NTSTATUS)0xC00A0036L) +#define STATUS_PNP_BAD_MPS_TABLE ((NTSTATUS)0xC0040035L) +#define STATUS_PNP_TRANSLATION_FAILED ((NTSTATUS)0xC0040036L) +#define STATUS_PNP_IRQ_TRANSLATION_FAILED ((NTSTATUS)0xC0040037L) +#define STATUS_SXS_SECTION_NOT_FOUND ((NTSTATUS)0xC0150001L) +#define STATUS_SXS_CANT_GEN_ACTCTX ((NTSTATUS)0xC0150002L) +#define STATUS_SXS_INVALID_ACTCTXDATA_FORMAT ((NTSTATUS)0xC0150003L) +#define STATUS_SXS_ASSEMBLY_NOT_FOUND ((NTSTATUS)0xC0150004L) +#define STATUS_SXS_MANIFEST_FORMAT_ERROR ((NTSTATUS)0xC0150005L) +#define STATUS_SXS_MANIFEST_PARSE_ERROR ((NTSTATUS)0xC0150006L) +#define STATUS_SXS_ACTIVATION_CONTEXT_DISABLED ((NTSTATUS)0xC0150007L) +#define STATUS_SXS_KEY_NOT_FOUND ((NTSTATUS)0xC0150008L) +#define STATUS_SXS_VERSION_CONFLICT ((NTSTATUS)0xC0150009L) +#define STATUS_SXS_WRONG_SECTION_TYPE ((NTSTATUS)0xC015000AL) +#define STATUS_SXS_THREAD_QUERIES_DISABLED ((NTSTATUS)0xC015000BL) +#define STATUS_SXS_ASSEMBLY_MISSING ((NTSTATUS)0xC015000CL) +#define STATUS_SXS_RELEASE_ACTIVATION_CONTEXT ((NTSTATUS)0x4015000DL) +#define STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET ((NTSTATUS)0xC015000EL) +#define STATUS_SXS_EARLY_DEACTIVATION ((NTSTATUS)0xC015000FL) +#define STATUS_SXS_INVALID_DEACTIVATION ((NTSTATUS)0xC0150010L) +#define STATUS_SXS_MULTIPLE_DEACTIVATION ((NTSTATUS)0xC0150011L) +#define STATUS_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY ((NTSTATUS)0xC0150012L) +#define STATUS_SXS_PROCESS_TERMINATION_REQUESTED ((NTSTATUS)0xC0150013L) +#define STATUS_CLUSTER_INVALID_NODE ((NTSTATUS)0xC0130001L) +#define STATUS_CLUSTER_NODE_EXISTS ((NTSTATUS)0xC0130002L) +#define STATUS_CLUSTER_JOIN_IN_PROGRESS ((NTSTATUS)0xC0130003L) +#define STATUS_CLUSTER_NODE_NOT_FOUND ((NTSTATUS)0xC0130004L) +#define STATUS_CLUSTER_LOCAL_NODE_NOT_FOUND ((NTSTATUS)0xC0130005L) +#define STATUS_CLUSTER_NETWORK_EXISTS ((NTSTATUS)0xC0130006L) +#define STATUS_CLUSTER_NETWORK_NOT_FOUND ((NTSTATUS)0xC0130007L) +#define STATUS_CLUSTER_NETINTERFACE_EXISTS ((NTSTATUS)0xC0130008L) +#define STATUS_CLUSTER_NETINTERFACE_NOT_FOUND ((NTSTATUS)0xC0130009L) +#define STATUS_CLUSTER_INVALID_REQUEST ((NTSTATUS)0xC013000AL) +#define STATUS_CLUSTER_INVALID_NETWORK_PROVIDER ((NTSTATUS)0xC013000BL) +#define STATUS_CLUSTER_NODE_DOWN ((NTSTATUS)0xC013000CL) +#define STATUS_CLUSTER_NODE_UNREACHABLE ((NTSTATUS)0xC013000DL) +#define STATUS_CLUSTER_NODE_NOT_MEMBER ((NTSTATUS)0xC013000EL) +#define STATUS_CLUSTER_JOIN_NOT_IN_PROGRESS ((NTSTATUS)0xC013000FL) +#define STATUS_CLUSTER_INVALID_NETWORK ((NTSTATUS)0xC0130010L) +#define STATUS_CLUSTER_NO_NET_ADAPTERS ((NTSTATUS)0xC0130011L) +#define STATUS_CLUSTER_NODE_UP ((NTSTATUS)0xC0130012L) +#define STATUS_CLUSTER_NODE_PAUSED ((NTSTATUS)0xC0130013L) +#define STATUS_CLUSTER_NODE_NOT_PAUSED ((NTSTATUS)0xC0130014L) +#define STATUS_CLUSTER_NO_SECURITY_CONTEXT ((NTSTATUS)0xC0130015L) +#define STATUS_CLUSTER_NETWORK_NOT_INTERNAL ((NTSTATUS)0xC0130016L) +#define STATUS_CLUSTER_POISONED ((NTSTATUS)0xC0130017L) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/platform/visualc/win2k.h b/src/platform/visualc/win2k.h new file mode 100644 index 00000000..deba29b9 --- /dev/null +++ b/src/platform/visualc/win2k.h @@ -0,0 +1,106 @@ +/* + * win2k.h + * + * Definitions only used in Windows 2000 and earlier versions + * + * This file is part of the w32api package. + * + * Contributors: + * Created by Casper S. Hornstrup + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef __WIN2K_H +#define __WIN2K_H + +#if __GNUC__ >=3 +#pragma GCC system_header +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ntddk.h" + +#pragma pack(push,4) + +typedef enum _BUS_DATA_TYPE { + ConfigurationSpaceUndefined = -1, + Cmos, + EisaConfiguration, + Pos, + CbusConfiguration, + PCIConfiguration, + VMEConfiguration, + NuBusConfiguration, + PCMCIAConfiguration, + MPIConfiguration, + MPSAConfiguration, + PNPISAConfiguration, + SgiInternalConfiguration, + MaximumBusDataType +} BUS_DATA_TYPE, *PBUS_DATA_TYPE; + +NTOSAPI +VOID +DDKAPI +ExReleaseResourceForThreadLite( + IN PERESOURCE Resource, + IN ERESOURCE_THREAD ResourceThreadId); + +NTOSAPI +NTSTATUS +DDKAPI +IoReadPartitionTable( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize, + IN BOOLEAN ReturnRecognizedPartitions, + OUT struct _DRIVE_LAYOUT_INFORMATION **PartitionBuffer); + +NTOSAPI +NTSTATUS +DDKAPI +IoSetPartitionInformation( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize, + IN ULONG PartitionNumber, + IN ULONG PartitionType); + +NTOSAPI +NTSTATUS +DDKAPI +IoWritePartitionTable( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize, + IN ULONG SectorsPerTrack, + IN ULONG NumberOfHeads, + IN struct _DRIVE_LAYOUT_INFORMATION *PartitionBuffer); + +/* + * PVOID MmGetSystemAddressForMdl( + * IN PMDL Mdl); + */ +#define MmGetSystemAddressForMdl(Mdl) \ + (((Mdl)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | \ + MDL_SOURCE_IS_NONPAGED_POOL)) ? \ + ((Mdl)->MappedSystemVa) : \ + (MmMapLockedPages((Mdl), KernelMode))) + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif + +#endif /* __WIN2K_H */ diff --git a/src/platform/visualc/winddk.h b/src/platform/visualc/winddk.h new file mode 100644 index 00000000..e02c56e9 --- /dev/null +++ b/src/platform/visualc/winddk.h @@ -0,0 +1,9074 @@ +/* + * winddk.h + * + * Windows Device Driver Kit + * + * This file is part of the w32api package. + * + * Contributors: + * Created by Casper S. Hornstrup + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef __WINDDK_H +#define __WINDDK_H + +#if __GNUC__ >=3 +#pragma GCC system_header +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#pragma pack(push,4) + +/* +** Definitions specific to this Device Driver Kit +*/ +#define DDKAPI __attribute__((stdcall)) +#define DDKFASTAPI __attribute__((fastcall)) +#define DDKCDECLAPI __attribute__((cdecl)) + +#if defined(_NTOSKRNL_) +#ifndef NTOSAPI +#define NTOSAPI DECL_EXPORT +#endif +#define DECLARE_INTERNAL_OBJECT(x) typedef struct _##x; typedef struct _##x *P##x; +#define DECLARE_INTERNAL_OBJECT2(x,y) typedef struct _##x; typedef struct _##x *P##y; +#else +#ifndef NTOSAPI +#define NTOSAPI DECL_IMPORT +#endif +#define DECLARE_INTERNAL_OBJECT(x) struct _##x; typedef struct _##x *P##x; +#define DECLARE_INTERNAL_OBJECT2(x,y) struct _##x; typedef struct _##x *P##y; +#endif + +/* Pseudo modifiers for parameters */ +#define IN +#define OUT +#define OPTIONAL +#define UNALLIGNED + +#define CONST const +#define VOLATILE volatile + +#define RESTRICTED_POINTER +#define POINTER_ALIGNMENT + + + +/* +** Forward declarations +*/ + +struct _IRP; +struct _MDL; +struct _KAPC; +struct _KDPC; +struct _KPCR; +struct _KPRCB; +struct _KTSS; +struct _FILE_OBJECT; +struct _DMA_ADAPTER; +struct _DEVICE_OBJECT; +struct _DRIVER_OBJECT; +struct _SECTION_OBJECT; +struct _IO_STATUS_BLOCK; +struct _DEVICE_DESCRIPTION; +struct _SCATTER_GATHER_LIST; + +DECLARE_INTERNAL_OBJECT(ADAPTER_OBJECT); +DECLARE_INTERNAL_OBJECT(DMA_ADAPTER); +DECLARE_INTERNAL_OBJECT(IO_STATUS_BLOCK); +DECLARE_INTERNAL_OBJECT(SECTION_OBJECT); + +#if 1 +/* FIXME: Unknown definitions */ +struct _SET_PARTITION_INFORMATION_EX; +typedef ULONG WAIT_TYPE; +typedef HANDLE TRACEHANDLE; +typedef PVOID PWMILIB_CONTEXT; +typedef PVOID PSYSCTL_IRP_DISPOSITION; +typedef ULONG LOGICAL; +#endif + +/* +** Routines specific to this DDK +*/ + +#define TAG(_a, _b, _c, _d) (ULONG) \ + (((_a) << 0) + ((_b) << 8) + ((_c) << 16) + ((_d) << 24)) + +static inline struct _KPCR * KeGetCurrentKPCR( + VOID) +{ + ULONG Value; + + __asm__ __volatile__ ("movl %%fs:0x18, %0\n\t" + : "=r" (Value) + : /* no inputs */ + ); + return (struct _KPCR *) Value; +} + +/* +** Simple structures +*/ + +typedef LONG KPRIORITY; +typedef ULONG KIRQL, *PKIRQL; +typedef ULONG_PTR KSPIN_LOCK, *PKSPIN_LOCK; +typedef ULONG KAFFINITY, *PKAFFINITY; +typedef CCHAR KPROCESSOR_MODE; + +typedef enum _MODE { + KernelMode, + UserMode, + MaximumMode +} MODE; + +typedef struct _SINGLE_LIST_ENTRY { + struct _SINGLE_LIST_ENTRY *Next; +} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY; + +#define SLIST_ENTRY SINGLE_LIST_ENTRY +#define PSLIST_ENTRY PSINGLE_LIST_ENTRY + +typedef union _SLIST_HEADER { + ULONGLONG Alignment; + struct { + SLIST_ENTRY Next; + USHORT Depth; + USHORT Sequence; + }; +} SLIST_HEADER, *PSLIST_HEADER; + + +/* Structures not exposed to drivers */ +typedef struct _IO_TIMER *PIO_TIMER; +typedef struct _EPROCESS *PEPROCESS; +typedef struct _ETHREAD *PETHREAD; +typedef struct _KINTERRUPT *PKINTERRUPT; +typedef struct _OBJECT_TYPE *POBJECT_TYPE; +typedef struct _KTHREAD *PKTHREAD, *PRKTHREAD; +typedef struct _COMPRESSED_DATA_INFO *PCOMPRESSED_DATA_INFO; +typedef struct _HAL_DISPATCH_TABLE *PHAL_DISPATCH_TABLE; +typedef struct _HAL_PRIVATE_DISPATCH_TABLE *PHAL_PRIVATE_DISPATCH_TABLE; +typedef struct _DRIVE_LAYOUT_INFORMATION *PDRIVE_LAYOUT_INFORMATION; +typedef struct _DRIVE_LAYOUT_INFORMATION_EX *PDRIVE_LAYOUT_INFORMATION_EX; + +/* Constants */ +#define MAXIMUM_PROCESSORS 32 + +#define MAXIMUM_WAIT_OBJECTS 64 + +#define METHOD_BUFFERED 0 +#define METHOD_IN_DIRECT 1 +#define METHOD_OUT_DIRECT 2 +#define METHOD_NEITHER 3 + +#define LOW_PRIORITY 0 +#define LOW_REALTIME_PRIORITY 16 +#define HIGH_PRIORITY 31 +#define MAXIMUM_PRIORITY 32 + +#define FILE_LIST_DIRECTORY 0x00000001 +#define FILE_READ_DATA 0x00000001 +#define FILE_ADD_FILE 0x00000002 +#define FILE_WRITE_DATA 0x00000002 +#define FILE_ADD_SUBDIRECTORY 0x00000004 +#define FILE_APPEND_DATA 0x00000004 +#define FILE_CREATE_PIPE_INSTANCE 0x00000004 +#define FILE_READ_EA 0x00000008 +#define FILE_WRITE_EA 0x00000010 +#define FILE_EXECUTE 0x00000020 +#define FILE_TRAVERSE 0x00000020 +#define FILE_DELETE_CHILD 0x00000040 +#define FILE_READ_ATTRIBUTES 0x00000080 +#define FILE_WRITE_ATTRIBUTES 0x00000100 + +#define FILE_SUPERSEDED 0x00000000 +#define FILE_OPENED 0x00000001 +#define FILE_CREATED 0x00000002 +#define FILE_OVERWRITTEN 0x00000003 +#define FILE_EXISTS 0x00000004 +#define FILE_DOES_NOT_EXIST 0x00000005 + +#define FILE_SHARE_READ 0x00000001 +#define FILE_SHARE_WRITE 0x00000002 +#define FILE_SHARE_DELETE 0x00000004 +#define FILE_SHARE_VALID_FLAGS 0x00000007 + +#define FILE_ATTRIBUTE_READONLY 0x00000001 +#define FILE_ATTRIBUTE_HIDDEN 0x00000002 +#define FILE_ATTRIBUTE_SYSTEM 0x00000004 +#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 +#define FILE_ATTRIBUTE_ARCHIVE 0x00000020 +#define FILE_ATTRIBUTE_DEVICE 0x00000040 +#define FILE_ATTRIBUTE_NORMAL 0x00000080 +#define FILE_ATTRIBUTE_TEMPORARY 0x00000100 +#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 +#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 +#define FILE_ATTRIBUTE_COMPRESSED 0x00000800 +#define FILE_ATTRIBUTE_OFFLINE 0x00001000 +#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 +#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000 + +#define FILE_ATTRIBUTE_VALID_FLAGS 0x00007fb7 +#define FILE_ATTRIBUTE_VALID_SET_FLAGS 0x000031a7 + +#define FILE_COPY_STRUCTURED_STORAGE 0x00000041 +#define FILE_STRUCTURED_STORAGE 0x00000441 + +#define FILE_VALID_OPTION_FLAGS 0x00ffffff +#define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032 +#define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032 +#define FILE_VALID_SET_FLAGS 0x00000036 + +#define FILE_SUPERSEDE 0x00000000 +#define FILE_OPEN 0x00000001 +#define FILE_CREATE 0x00000002 +#define FILE_OPEN_IF 0x00000003 +#define FILE_OVERWRITE 0x00000004 +#define FILE_OVERWRITE_IF 0x00000005 +#define FILE_MAXIMUM_DISPOSITION 0x00000005 + +#define FILE_DIRECTORY_FILE 0x00000001 +#define FILE_WRITE_THROUGH 0x00000002 +#define FILE_SEQUENTIAL_ONLY 0x00000004 +#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008 +#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010 +#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 +#define FILE_NON_DIRECTORY_FILE 0x00000040 +#define FILE_CREATE_TREE_CONNECTION 0x00000080 +#define FILE_COMPLETE_IF_OPLOCKED 0x00000100 +#define FILE_NO_EA_KNOWLEDGE 0x00000200 +#define FILE_OPEN_FOR_RECOVERY 0x00000400 +#define FILE_RANDOM_ACCESS 0x00000800 +#define FILE_DELETE_ON_CLOSE 0x00001000 +#define FILE_OPEN_BY_FILE_ID 0x00002000 +#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000 +#define FILE_NO_COMPRESSION 0x00008000 +#define FILE_RESERVE_OPFILTER 0x00100000 +#define FILE_OPEN_REPARSE_POINT 0x00200000 +#define FILE_OPEN_NO_RECALL 0x00400000 +#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000 + +#define FILE_ANY_ACCESS 0x00000000 +#define FILE_SPECIAL_ACCESS FILE_ANY_ACCESS +#define FILE_READ_ACCESS 0x00000001 +#define FILE_WRITE_ACCESS 0x00000002 + +#define FILE_ALL_ACCESS \ + (STANDARD_RIGHTS_REQUIRED | \ + SYNCHRONIZE | \ + 0x1FF) + +#define FILE_GENERIC_EXECUTE \ + (STANDARD_RIGHTS_EXECUTE | \ + FILE_READ_ATTRIBUTES | \ + FILE_EXECUTE | \ + SYNCHRONIZE) + +#define FILE_GENERIC_READ \ + (STANDARD_RIGHTS_READ | \ + FILE_READ_DATA | \ + FILE_READ_ATTRIBUTES | \ + FILE_READ_EA | \ + SYNCHRONIZE) + +#define FILE_GENERIC_WRITE \ + (STANDARD_RIGHTS_WRITE | \ + FILE_WRITE_DATA | \ + FILE_WRITE_ATTRIBUTES | \ + FILE_WRITE_EA | \ + FILE_APPEND_DATA | \ + SYNCHRONIZE) + +/* Exported object types */ +extern NTOSAPI POBJECT_TYPE ExDesktopObjectType; +extern NTOSAPI POBJECT_TYPE ExEventObjectType; +extern NTOSAPI POBJECT_TYPE ExSemaphoreObjectType; +extern NTOSAPI POBJECT_TYPE ExWindowStationObjectType; +extern NTOSAPI POBJECT_TYPE IoAdapterObjectType; +extern NTOSAPI ULONG IoDeviceHandlerObjectSize; +extern NTOSAPI POBJECT_TYPE IoDeviceHandlerObjectType; +extern NTOSAPI POBJECT_TYPE IoDeviceObjectType; +extern NTOSAPI POBJECT_TYPE IoDriverObjectType; +extern NTOSAPI POBJECT_TYPE IoFileObjectType; +extern NTOSAPI POBJECT_TYPE LpcPortObjectType; +extern NTOSAPI POBJECT_TYPE MmSectionObjectType; +extern NTOSAPI POBJECT_TYPE SeTokenObjectType; + +extern NTOSAPI CCHAR KeNumberProcessors; +extern NTOSAPI PHAL_DISPATCH_TABLE HalDispatchTable; +extern NTOSAPI PHAL_PRIVATE_DISPATCH_TABLE HalPrivateDispatchTable; + + +/* +** IRP function codes +*/ + +#define IRP_MJ_CREATE 0x00 +#define IRP_MJ_CREATE_NAMED_PIPE 0x01 +#define IRP_MJ_CLOSE 0x02 +#define IRP_MJ_READ 0x03 +#define IRP_MJ_WRITE 0x04 +#define IRP_MJ_QUERY_INFORMATION 0x05 +#define IRP_MJ_SET_INFORMATION 0x06 +#define IRP_MJ_QUERY_EA 0x07 +#define IRP_MJ_SET_EA 0x08 +#define IRP_MJ_FLUSH_BUFFERS 0x09 +#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a +#define IRP_MJ_SET_VOLUME_INFORMATION 0x0b +#define IRP_MJ_DIRECTORY_CONTROL 0x0c +#define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d +#define IRP_MJ_DEVICE_CONTROL 0x0e +#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f +#define IRP_MJ_SCSI 0x0f +#define IRP_MJ_SHUTDOWN 0x10 +#define IRP_MJ_LOCK_CONTROL 0x11 +#define IRP_MJ_CLEANUP 0x12 +#define IRP_MJ_CREATE_MAILSLOT 0x13 +#define IRP_MJ_QUERY_SECURITY 0x14 +#define IRP_MJ_SET_SECURITY 0x15 +#define IRP_MJ_POWER 0x16 +#define IRP_MJ_SYSTEM_CONTROL 0x17 +#define IRP_MJ_DEVICE_CHANGE 0x18 +#define IRP_MJ_QUERY_QUOTA 0x19 +#define IRP_MJ_SET_QUOTA 0x1a +#define IRP_MJ_PNP 0x1b +#define IRP_MJ_PNP_POWER 0x1b +#define IRP_MJ_MAXIMUM_FUNCTION 0x1b + +#define IRP_MN_QUERY_DIRECTORY 0x01 +#define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x02 + +#define IRP_MN_USER_FS_REQUEST 0x00 +#define IRP_MN_MOUNT_VOLUME 0x01 +#define IRP_MN_VERIFY_VOLUME 0x02 +#define IRP_MN_LOAD_FILE_SYSTEM 0x03 +#define IRP_MN_TRACK_LINK 0x04 +#define IRP_MN_KERNEL_CALL 0x04 + +#define IRP_MN_LOCK 0x01 +#define IRP_MN_UNLOCK_SINGLE 0x02 +#define IRP_MN_UNLOCK_ALL 0x03 +#define IRP_MN_UNLOCK_ALL_BY_KEY 0x04 + +#define IRP_MN_NORMAL 0x00 +#define IRP_MN_DPC 0x01 +#define IRP_MN_MDL 0x02 +#define IRP_MN_COMPLETE 0x04 +#define IRP_MN_COMPRESSED 0x08 + +#define IRP_MN_MDL_DPC (IRP_MN_MDL | IRP_MN_DPC) +#define IRP_MN_COMPLETE_MDL (IRP_MN_COMPLETE | IRP_MN_MDL) +#define IRP_MN_COMPLETE_MDL_DPC (IRP_MN_COMPLETE_MDL | IRP_MN_DPC) + +#define IRP_MN_SCSI_CLASS 0x01 + +#define IRP_MN_START_DEVICE 0x00 +#define IRP_MN_QUERY_REMOVE_DEVICE 0x01 +#define IRP_MN_REMOVE_DEVICE 0x02 +#define IRP_MN_CANCEL_REMOVE_DEVICE 0x03 +#define IRP_MN_STOP_DEVICE 0x04 +#define IRP_MN_QUERY_STOP_DEVICE 0x05 +#define IRP_MN_CANCEL_STOP_DEVICE 0x06 + +#define IRP_MN_QUERY_DEVICE_RELATIONS 0x07 +#define IRP_MN_QUERY_INTERFACE 0x08 +#define IRP_MN_QUERY_CAPABILITIES 0x09 +#define IRP_MN_QUERY_RESOURCES 0x0A +#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS 0x0B +#define IRP_MN_QUERY_DEVICE_TEXT 0x0C +#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D + +#define IRP_MN_READ_CONFIG 0x0F +#define IRP_MN_WRITE_CONFIG 0x10 +#define IRP_MN_EJECT 0x11 +#define IRP_MN_SET_LOCK 0x12 +#define IRP_MN_QUERY_ID 0x13 +#define IRP_MN_QUERY_PNP_DEVICE_STATE 0x14 +#define IRP_MN_QUERY_BUS_INFORMATION 0x15 +#define IRP_MN_DEVICE_USAGE_NOTIFICATION 0x16 +#define IRP_MN_SURPRISE_REMOVAL 0x17 +#define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18 + +#define IRP_MN_WAIT_WAKE 0x00 +#define IRP_MN_POWER_SEQUENCE 0x01 +#define IRP_MN_SET_POWER 0x02 +#define IRP_MN_QUERY_POWER 0x03 + +#define IRP_MN_QUERY_ALL_DATA 0x00 +#define IRP_MN_QUERY_SINGLE_INSTANCE 0x01 +#define IRP_MN_CHANGE_SINGLE_INSTANCE 0x02 +#define IRP_MN_CHANGE_SINGLE_ITEM 0x03 +#define IRP_MN_ENABLE_EVENTS 0x04 +#define IRP_MN_DISABLE_EVENTS 0x05 +#define IRP_MN_ENABLE_COLLECTION 0x06 +#define IRP_MN_DISABLE_COLLECTION 0x07 +#define IRP_MN_REGINFO 0x08 +#define IRP_MN_EXECUTE_METHOD 0x09 + +#define IRP_MN_REGINFO_EX 0x0b + +typedef enum _IO_ALLOCATION_ACTION { + KeepObject = 1, + DeallocateObject, + DeallocateObjectKeepRegisters +} IO_ALLOCATION_ACTION, *PIO_ALLOCATION_ACTION; + +typedef IO_ALLOCATION_ACTION DDKAPI +(*PDRIVER_CONTROL)( + IN struct _DEVICE_OBJECT *DeviceObject, + IN struct _IRP *Irp, + IN PVOID MapRegisterBase, + IN PVOID Context); + +typedef VOID DDKAPI +(*PDRIVER_LIST_CONTROL)( + IN struct _DEVICE_OBJECT *DeviceObject, + IN struct _IRP *Irp, + IN struct _SCATTER_GATHER_LIST *ScatterGather, + IN PVOID Context); + +typedef NTSTATUS DDKAPI +(*PDRIVER_ADD_DEVICE)( + IN struct _DRIVER_OBJECT *DriverObject, + IN struct _DEVICE_OBJECT *PhysicalDeviceObject); + +typedef NTSTATUS DDKAPI +(*PIO_COMPLETION_ROUTINE)( + IN struct _DEVICE_OBJECT *DeviceObject, + IN struct _IRP *Irp, + IN PVOID Context); + +typedef VOID DDKAPI +(*PDRIVER_CANCEL)( + IN struct _DEVICE_OBJECT *DeviceObject, + IN struct _IRP *Irp); + +typedef VOID DDKAPI +(*PKDEFERRED_ROUTINE)( + IN struct _KDPC *Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2); + +typedef NTSTATUS DDKAPI +(*PDRIVER_DISPATCH)( + IN struct _DEVICE_OBJECT *DeviceObject, + IN struct _IRP *Irp); + +typedef VOID DDKAPI +(*PIO_DPC_ROUTINE)( + IN struct _KDPC *Dpc, + IN struct _DEVICE_OBJECT *DeviceObject, + IN struct _IRP *Irp, + IN PVOID Context); + +typedef NTSTATUS DDKAPI +(*PMM_DLL_INITIALIZE)( + IN PUNICODE_STRING RegistryPath); + +typedef NTSTATUS DDKAPI +(*PMM_DLL_UNLOAD)( + VOID); + +typedef NTSTATUS DDKAPI +(*PDRIVER_ENTRY)( + IN struct _DRIVER_OBJECT *DriverObject, + IN PUNICODE_STRING RegistryPath); + +typedef NTSTATUS DDKAPI +(*PDRIVER_INITIALIZE)( + IN struct _DRIVER_OBJECT *DriverObject, + IN PUNICODE_STRING RegistryPath); + +typedef BOOLEAN DDKAPI +(*PKSERVICE_ROUTINE)( + IN struct _KINTERRUPT *Interrupt, + IN PVOID ServiceContext); + +typedef VOID DDKAPI +(*PIO_TIMER_ROUTINE)( + IN struct _DEVICE_OBJECT *DeviceObject, + IN PVOID Context); + +typedef VOID DDKAPI +(*PDRIVER_REINITIALIZE)( + IN struct _DRIVER_OBJECT *DriverObject, + IN PVOID Context, + IN ULONG Count); + +typedef NTSTATUS DDKAPI +(*PDRIVER_STARTIO)( + IN struct _DEVICE_OBJECT *DeviceObject, + IN struct _IRP *Irp); + +typedef BOOLEAN DDKAPI +(*PKSYNCHRONIZE_ROUTINE)( + IN PVOID SynchronizeContext); + +typedef VOID DDKAPI +(*PDRIVER_UNLOAD)( + IN struct _DRIVER_OBJECT *DriverObject); + + + +/* +** Plug and Play structures +*/ + +typedef VOID DDKAPI +(*PINTERFACE_REFERENCE)( + PVOID Context); + +typedef VOID DDKAPI +(*PINTERFACE_DEREFERENCE)( + PVOID Context); + +typedef BOOLEAN DDKAPI +(*PTRANSLATE_BUS_ADDRESS)( + IN PVOID Context, + IN PHYSICAL_ADDRESS BusAddress, + IN ULONG Length, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress); + +typedef struct _DMA_ADAPTER* DDKAPI +(*PGET_DMA_ADAPTER)( + IN PVOID Context, + IN struct _DEVICE_DESCRIPTION *DeviceDescriptor, + OUT PULONG NumberOfMapRegisters); + +typedef ULONG DDKAPI +(*PGET_SET_DEVICE_DATA)( + IN PVOID Context, + IN ULONG DataType, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length); + +typedef union _POWER_STATE { + SYSTEM_POWER_STATE SystemState; + DEVICE_POWER_STATE DeviceState; +} POWER_STATE, *PPOWER_STATE; + +typedef enum _POWER_STATE_TYPE { + SystemPowerState, + DevicePowerState +} POWER_STATE_TYPE, *PPOWER_STATE_TYPE; + +typedef struct _BUS_INTERFACE_STANDARD { + USHORT Size; + USHORT Version; + PVOID Context; + PINTERFACE_REFERENCE InterfaceReference; + PINTERFACE_DEREFERENCE InterfaceDereference; + PTRANSLATE_BUS_ADDRESS TranslateBusAddress; + PGET_DMA_ADAPTER GetDmaAdapter; + PGET_SET_DEVICE_DATA SetBusData; + PGET_SET_DEVICE_DATA GetBusData; +} BUS_INTERFACE_STANDARD, *PBUS_INTERFACE_STANDARD; + +typedef struct _DEVICE_CAPABILITIES { + USHORT Size; + USHORT Version; + ULONG DeviceD1 : 1; + ULONG DeviceD2 : 1; + ULONG LockSupported : 1; + ULONG EjectSupported : 1; + ULONG Removable : 1; + ULONG DockDevice : 1; + ULONG UniqueID : 1; + ULONG SilentInstall : 1; + ULONG RawDeviceOK : 1; + ULONG SurpriseRemovalOK : 1; + ULONG WakeFromD0 : 1; + ULONG WakeFromD1 : 1; + ULONG WakeFromD2 : 1; + ULONG WakeFromD3 : 1; + ULONG HardwareDisabled : 1; + ULONG NonDynamic : 1; + ULONG WarmEjectSupported : 1; + ULONG NoDisplayInUI : 1; + ULONG Reserved : 14; + ULONG Address; + ULONG UINumber; + DEVICE_POWER_STATE DeviceState[PowerSystemMaximum]; + SYSTEM_POWER_STATE SystemWake; + DEVICE_POWER_STATE DeviceWake; + ULONG D1Latency; + ULONG D2Latency; + ULONG D3Latency; +} DEVICE_CAPABILITIES, *PDEVICE_CAPABILITIES; + +typedef struct _DEVICE_INTERFACE_CHANGE_NOTIFICATION { + USHORT Version; + USHORT Size; + GUID Event; + GUID InterfaceClassGuid; + PUNICODE_STRING SymbolicLinkName; +} DEVICE_INTERFACE_CHANGE_NOTIFICATION, *PDEVICE_INTERFACE_CHANGE_NOTIFICATION; + +typedef struct _HWPROFILE_CHANGE_NOTIFICATION { + USHORT Version; + USHORT Size; + GUID Event; +} HWPROFILE_CHANGE_NOTIFICATION, *PHWPROFILE_CHANGE_NOTIFICATION; + +#undef INTERFACE + +typedef struct _INTERFACE { + USHORT Size; + USHORT Version; + PVOID Context; + PINTERFACE_REFERENCE InterfaceReference; + PINTERFACE_DEREFERENCE InterfaceDereference; +} INTERFACE, *PINTERFACE; + +typedef struct _PLUGPLAY_NOTIFICATION_HEADER { + USHORT Version; + USHORT Size; + GUID Event; +} PLUGPLAY_NOTIFICATION_HEADER, *PPLUGPLAY_NOTIFICATION_HEADER; + +typedef ULONG PNP_DEVICE_STATE, *PPNP_DEVICE_STATE; + +/* PNP_DEVICE_STATE */ + +#define PNP_DEVICE_DISABLED 0x00000001 +#define PNP_DEVICE_DONT_DISPLAY_IN_UI 0x00000002 +#define PNP_DEVICE_FAILED 0x00000004 +#define PNP_DEVICE_REMOVED 0x00000008 +#define PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED 0x00000010 +#define PNP_DEVICE_NOT_DISABLEABLE 0x00000020 + +typedef struct _TARGET_DEVICE_CUSTOM_NOTIFICATION { + USHORT Version; + USHORT Size; + GUID Event; + struct _FILE_OBJECT *FileObject; + LONG NameBufferOffset; + UCHAR CustomDataBuffer[1]; +} TARGET_DEVICE_CUSTOM_NOTIFICATION, *PTARGET_DEVICE_CUSTOM_NOTIFICATION; + +typedef struct _TARGET_DEVICE_REMOVAL_NOTIFICATION { + USHORT Version; + USHORT Size; + GUID Event; + struct _FILE_OBJECT *FileObject; +} TARGET_DEVICE_REMOVAL_NOTIFICATION, *PTARGET_DEVICE_REMOVAL_NOTIFICATION; + +typedef enum _BUS_QUERY_ID_TYPE { + BusQueryDeviceID, + BusQueryHardwareIDs, + BusQueryCompatibleIDs, + BusQueryInstanceID, + BusQueryDeviceSerialNumber +} BUS_QUERY_ID_TYPE, *PBUS_QUERY_ID_TYPE; + +typedef enum _DEVICE_TEXT_TYPE { + DeviceTextDescription, + DeviceTextLocationInformation +} DEVICE_TEXT_TYPE, *PDEVICE_TEXT_TYPE; + +typedef enum _DEVICE_USAGE_NOTIFICATION_TYPE { + DeviceUsageTypeUndefined, + DeviceUsageTypePaging, + DeviceUsageTypeHibernation, + DeviceUsageTypeDumpFile +} DEVICE_USAGE_NOTIFICATION_TYPE; + +typedef struct _POWER_SEQUENCE { + ULONG SequenceD1; + ULONG SequenceD2; + ULONG SequenceD3; +} POWER_SEQUENCE, *PPOWER_SEQUENCE; + +typedef enum { + DevicePropertyDeviceDescription, + DevicePropertyHardwareID, + DevicePropertyCompatibleIDs, + DevicePropertyBootConfiguration, + DevicePropertyBootConfigurationTranslated, + DevicePropertyClassName, + DevicePropertyClassGuid, + DevicePropertyDriverKeyName, + DevicePropertyManufacturer, + DevicePropertyFriendlyName, + DevicePropertyLocationInformation, + DevicePropertyPhysicalDeviceObjectName, + DevicePropertyBusTypeGuid, + DevicePropertyLegacyBusType, + DevicePropertyBusNumber, + DevicePropertyEnumeratorName, + DevicePropertyAddress, + DevicePropertyUINumber, + DevicePropertyInstallState, + DevicePropertyRemovalPolicy +} DEVICE_REGISTRY_PROPERTY; + +typedef enum _IO_NOTIFICATION_EVENT_CATEGORY { + EventCategoryReserved, + EventCategoryHardwareProfileChange, + EventCategoryDeviceInterfaceChange, + EventCategoryTargetDeviceChange +} IO_NOTIFICATION_EVENT_CATEGORY; + +#define PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES 0x00000001 + +typedef NTSTATUS DDKAPI +(*PDRIVER_NOTIFICATION_CALLBACK_ROUTINE)( + IN PVOID NotificationStructure, + IN PVOID Context); + +typedef VOID DDKAPI +(*PDEVICE_CHANGE_COMPLETE_CALLBACK)( + IN PVOID Context); + + + +/* +** System structures +*/ + +#define SYMBOLIC_LINK_QUERY 0x0001 +#define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1) + +#define DUPLICATE_CLOSE_SOURCE 0x00000001 +#define DUPLICATE_SAME_ACCESS 0x00000002 +#define DUPLICATE_SAME_ATTRIBUTES 0x00000004 + +typedef struct _OBJECT_NAME_INFORMATION { + UNICODE_STRING Name; +} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; + +typedef VOID DDKAPI +(*PIO_APC_ROUTINE)( + IN PVOID ApcContext, + IN PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG Reserved); + +typedef struct _IO_STATUS_BLOCK { + union { + NTSTATUS Status; + PVOID Pointer; + }; + ULONG_PTR Information; +} IO_STATUS_BLOCK; + +typedef VOID DDKAPI +(*PKNORMAL_ROUTINE)( + IN PVOID NormalContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2); + +typedef VOID DDKAPI +(*PKKERNEL_ROUTINE)( + IN struct _KAPC *Apc, + IN OUT PKNORMAL_ROUTINE *NormalRoutine, + IN OUT PVOID *NormalContext, + IN OUT PVOID *SystemArgument1, + IN OUT PVOID *SystemArgument2); + +typedef VOID DDKAPI +(*PKRUNDOWN_ROUTINE)( + IN struct _KAPC *Apc); + +typedef BOOLEAN DDKAPI +(*PKTRANSFER_ROUTINE)( + VOID); + +typedef struct _KAPC { + CSHORT Type; + CSHORT Size; + ULONG Spare0; + struct _KTHREAD *Thread; + LIST_ENTRY ApcListEntry; + PKKERNEL_ROUTINE KernelRoutine; + PKRUNDOWN_ROUTINE RundownRoutine; + PKNORMAL_ROUTINE NormalRoutine; + PVOID NormalContext; + PVOID SystemArgument1; + PVOID SystemArgument2; + CCHAR ApcStateIndex; + KPROCESSOR_MODE ApcMode; + BOOLEAN Inserted; +} KAPC, *PKAPC, *RESTRICTED_POINTER PRKAPC; + +typedef struct _KDEVICE_QUEUE { + CSHORT Type; + CSHORT Size; + LIST_ENTRY DeviceListHead; + KSPIN_LOCK Lock; + BOOLEAN Busy; +} KDEVICE_QUEUE, *PKDEVICE_QUEUE, *RESTRICTED_POINTER PRKDEVICE_QUEUE; + +typedef struct _KDEVICE_QUEUE_ENTRY { + LIST_ENTRY DeviceListEntry; + ULONG SortKey; + BOOLEAN Inserted; +} KDEVICE_QUEUE_ENTRY, *PKDEVICE_QUEUE_ENTRY, +*RESTRICTED_POINTER PRKDEVICE_QUEUE_ENTRY; + +#define LOCK_QUEUE_WAIT 1 +#define LOCK_QUEUE_OWNER 2 + +typedef enum _KSPIN_LOCK_QUEUE_NUMBER { + LockQueueDispatcherLock, + LockQueueContextSwapLock, + LockQueuePfnLock, + LockQueueSystemSpaceLock, + LockQueueVacbLock, + LockQueueMasterLock, + LockQueueNonPagedPoolLock, + LockQueueIoCancelLock, + LockQueueWorkQueueLock, + LockQueueIoVpbLock, + LockQueueIoDatabaseLock, + LockQueueIoCompletionLock, + LockQueueNtfsStructLock, + LockQueueAfdWorkQueueLock, + LockQueueBcbLock, + LockQueueMaximumLock +} KSPIN_LOCK_QUEUE_NUMBER, *PKSPIN_LOCK_QUEUE_NUMBER; + +typedef struct _KSPIN_LOCK_QUEUE { + struct _KSPIN_LOCK_QUEUE *VOLATILE Next; + PKSPIN_LOCK VOLATILE Lock; +} KSPIN_LOCK_QUEUE, *PKSPIN_LOCK_QUEUE; + +typedef struct _KLOCK_QUEUE_HANDLE { + KSPIN_LOCK_QUEUE LockQueue; + KIRQL OldIrql; +} KLOCK_QUEUE_HANDLE, *PKLOCK_QUEUE_HANDLE; + +typedef struct _KDPC { + CSHORT Type; + UCHAR Number; + UCHAR Importance; + LIST_ENTRY DpcListEntry; + PKDEFERRED_ROUTINE DeferredRoutine; + PVOID DeferredContext; + PVOID SystemArgument1; + PVOID SystemArgument2; + PULONG_PTR Lock; +} KDPC, *PKDPC, *RESTRICTED_POINTER PRKDPC; + +typedef struct _WAIT_CONTEXT_BLOCK { + KDEVICE_QUEUE_ENTRY WaitQueueEntry; + struct _DRIVER_CONTROL *DeviceRoutine; + PVOID DeviceContext; + ULONG NumberOfMapRegisters; + PVOID DeviceObject; + PVOID CurrentIrp; + PKDPC BufferChainingDpc; +} WAIT_CONTEXT_BLOCK, *PWAIT_CONTEXT_BLOCK; + +typedef struct _DISPATCHER_HEADER { + UCHAR Type; + UCHAR Absolute; + UCHAR Size; + UCHAR Inserted; + LONG SignalState; + LIST_ENTRY WaitListHead; +} DISPATCHER_HEADER, *PDISPATCHER_HEADER; + +typedef struct _KEVENT { + DISPATCHER_HEADER Header; +} KEVENT, *PKEVENT, *RESTRICTED_POINTER PRKEVENT; + +typedef struct _KSEMAPHORE { + DISPATCHER_HEADER Header; + LONG Limit; +} KSEMAPHORE, *PKSEMAPHORE, *RESTRICTED_POINTER PRKSEMAPHORE; + +typedef struct _FAST_MUTEX { + LONG Count; + struct _KTHREAD *Owner; + ULONG Contention; + KEVENT Event; + ULONG OldIrql; +} FAST_MUTEX, *PFAST_MUTEX; + +typedef struct _KTIMER { + DISPATCHER_HEADER Header; + ULARGE_INTEGER DueTime; + LIST_ENTRY TimerListEntry; + struct _KDPC *Dpc; + LONG Period; +} KTIMER, *PKTIMER, *RESTRICTED_POINTER PRKTIMER; + +typedef struct _KMUTANT { + DISPATCHER_HEADER Header; + LIST_ENTRY MutantListEntry; + struct _KTHREAD *RESTRICTED_POINTER OwnerThread; + BOOLEAN Abandoned; + UCHAR ApcDisable; +} KMUTANT, *PKMUTANT, *RESTRICTED_POINTER PRKMUTANT, KMUTEX, *PKMUTEX, *RESTRICTED_POINTER PRKMUTEX; + +typedef enum _TIMER_TYPE { + NotificationTimer, + SynchronizationTimer +} TIMER_TYPE; + +#define EVENT_INCREMENT 1 +#define IO_NO_INCREMENT 0 +#define IO_CD_ROM_INCREMENT 1 +#define IO_DISK_INCREMENT 1 +#define IO_KEYBOARD_INCREMENT 6 +#define IO_MAILSLOT_INCREMENT 2 +#define IO_MOUSE_INCREMENT 6 +#define IO_NAMED_PIPE_INCREMENT 2 +#define IO_NETWORK_INCREMENT 2 +#define IO_PARALLEL_INCREMENT 1 +#define IO_SERIAL_INCREMENT 2 +#define IO_SOUND_INCREMENT 8 +#define IO_VIDEO_INCREMENT 1 +#define SEMAPHORE_INCREMENT 1 + +typedef struct _IRP { + CSHORT Type; + USHORT Size; + struct _MDL *MdlAddress; + ULONG Flags; + union { + struct _IRP *MasterIrp; + LONG IrpCount; + PVOID SystemBuffer; + } AssociatedIrp; + LIST_ENTRY ThreadListEntry; + IO_STATUS_BLOCK IoStatus; + KPROCESSOR_MODE RequestorMode; + BOOLEAN PendingReturned; + CHAR StackCount; + CHAR CurrentLocation; + BOOLEAN Cancel; + KIRQL CancelIrql; + CCHAR ApcEnvironment; + UCHAR AllocationFlags; + PIO_STATUS_BLOCK UserIosb; + PKEVENT UserEvent; + union { + struct { + PIO_APC_ROUTINE UserApcRoutine; + PVOID UserApcContext; + } AsynchronousParameters; + LARGE_INTEGER AllocationSize; + } Overlay; + PDRIVER_CANCEL CancelRoutine; + PVOID UserBuffer; + union { + struct { + union { + KDEVICE_QUEUE_ENTRY DeviceQueueEntry; + struct { + PVOID DriverContext[4]; + }; + }; + PETHREAD Thread; + PCHAR AuxiliaryBuffer; + struct { + LIST_ENTRY ListEntry; + union { + struct _IO_STACK_LOCATION *CurrentStackLocation; + ULONG PacketType; + }; + }; + struct _FILE_OBJECT *OriginalFileObject; + } Overlay; + KAPC Apc; + PVOID CompletionKey; + } Tail; +} IRP; +typedef struct _IRP *PIRP; + +/* IRP.Flags */ + +#define SL_FORCE_ACCESS_CHECK 0x01 +#define SL_OPEN_PAGING_FILE 0x02 +#define SL_OPEN_TARGET_DIRECTORY 0x04 +#define SL_CASE_SENSITIVE 0x80 + +#define SL_KEY_SPECIFIED 0x01 +#define SL_OVERRIDE_VERIFY_VOLUME 0x02 +#define SL_WRITE_THROUGH 0x04 +#define SL_FT_SEQUENTIAL_WRITE 0x08 + +#define SL_FAIL_IMMEDIATELY 0x01 +#define SL_EXCLUSIVE_LOCK 0x02 + +#define SL_RESTART_SCAN 0x01 +#define SL_RETURN_SINGLE_ENTRY 0x02 +#define SL_INDEX_SPECIFIED 0x04 + +#define SL_WATCH_TREE 0x01 + +#define SL_ALLOW_RAW_MOUNT 0x01 + +#define CTL_CODE(DeviceType, Function, Method, Access)( \ + ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) + +#define DEVICE_TYPE_FROM_CTL_CODE(ctl) (((ULONG) (ctl & 0xffff0000)) >> 16) + + +typedef struct _DRIVE_LAYOUT_INFORMATION_MBR { + ULONG Signature; +} DRIVE_LAYOUT_INFORMATION_MBR, *PDRIVE_LAYOUT_INFORMATION_MBR; + +typedef struct _DRIVE_LAYOUT_INFORMATION_GPT { + GUID DiskId; + LARGE_INTEGER StartingUsableOffset; + LARGE_INTEGER UsableLength; + ULONG MaxPartitionCount; +} DRIVE_LAYOUT_INFORMATION_GPT, *PDRIVE_LAYOUT_INFORMATION_GPT; + +typedef struct _PARTITION_INFORMATION_MBR { + UCHAR PartitionType; + BOOLEAN BootIndicator; + BOOLEAN RecognizedPartition; + ULONG HiddenSectors; +} PARTITION_INFORMATION_MBR, *PPARTITION_INFORMATION_MBR; + + +typedef struct _BOOTDISK_INFORMATION { + LONGLONG BootPartitionOffset; + LONGLONG SystemPartitionOffset; + ULONG BootDeviceSignature; + ULONG SystemDeviceSignature; +} BOOTDISK_INFORMATION, *PBOOTDISK_INFORMATION; + +typedef struct _BOOTDISK_INFORMATION_EX { + LONGLONG BootPartitionOffset; + LONGLONG SystemPartitionOffset; + ULONG BootDeviceSignature; + ULONG SystemDeviceSignature; + GUID BootDeviceGuid; + GUID SystemDeviceGuid; + BOOLEAN BootDeviceIsGpt; + BOOLEAN SystemDeviceIsGpt; +} BOOTDISK_INFORMATION_EX, *PBOOTDISK_INFORMATION_EX; + +typedef struct _EISA_MEMORY_TYPE { + UCHAR ReadWrite : 1; + UCHAR Cached : 1; + UCHAR Reserved0 : 1; + UCHAR Type : 2; + UCHAR Shared : 1; + UCHAR Reserved1 : 1; + UCHAR MoreEntries : 1; +} EISA_MEMORY_TYPE, *PEISA_MEMORY_TYPE; + +typedef struct _EISA_MEMORY_CONFIGURATION { + EISA_MEMORY_TYPE ConfigurationByte; + UCHAR DataSize; + USHORT AddressLowWord; + UCHAR AddressHighByte; + USHORT MemorySize; +} EISA_MEMORY_CONFIGURATION, *PEISA_MEMORY_CONFIGURATION; + +typedef struct _EISA_IRQ_DESCRIPTOR { + UCHAR Interrupt : 4; + UCHAR Reserved : 1; + UCHAR LevelTriggered : 1; + UCHAR Shared : 1; + UCHAR MoreEntries : 1; +} EISA_IRQ_DESCRIPTOR, *PEISA_IRQ_DESCRIPTOR; + +typedef struct _EISA_IRQ_CONFIGURATION { + EISA_IRQ_DESCRIPTOR ConfigurationByte; + UCHAR Reserved; +} EISA_IRQ_CONFIGURATION, *PEISA_IRQ_CONFIGURATION; + +typedef struct _DMA_CONFIGURATION_BYTE0 { + UCHAR Channel : 3; + UCHAR Reserved : 3; + UCHAR Shared : 1; + UCHAR MoreEntries : 1; +} DMA_CONFIGURATION_BYTE0; + +typedef struct _DMA_CONFIGURATION_BYTE1 { + UCHAR Reserved0 : 2; + UCHAR TransferSize : 2; + UCHAR Timing : 2; + UCHAR Reserved1 : 2; +} DMA_CONFIGURATION_BYTE1; + +typedef struct _EISA_DMA_CONFIGURATION { + DMA_CONFIGURATION_BYTE0 ConfigurationByte0; + DMA_CONFIGURATION_BYTE1 ConfigurationByte1; +} EISA_DMA_CONFIGURATION, *PEISA_DMA_CONFIGURATION; + +typedef struct _EISA_PORT_DESCRIPTOR { + UCHAR NumberPorts : 5; + UCHAR Reserved : 1; + UCHAR Shared : 1; + UCHAR MoreEntries : 1; +} EISA_PORT_DESCRIPTOR, *PEISA_PORT_DESCRIPTOR; + +typedef struct _EISA_PORT_CONFIGURATION { + EISA_PORT_DESCRIPTOR Configuration; + USHORT PortAddress; +} EISA_PORT_CONFIGURATION, *PEISA_PORT_CONFIGURATION; + +typedef struct _CM_EISA_FUNCTION_INFORMATION { + ULONG CompressedId; + UCHAR IdSlotFlags1; + UCHAR IdSlotFlags2; + UCHAR MinorRevision; + UCHAR MajorRevision; + UCHAR Selections[26]; + UCHAR FunctionFlags; + UCHAR TypeString[80]; + EISA_MEMORY_CONFIGURATION EisaMemory[9]; + EISA_IRQ_CONFIGURATION EisaIrq[7]; + EISA_DMA_CONFIGURATION EisaDma[4]; + EISA_PORT_CONFIGURATION EisaPort[20]; + UCHAR InitializationData[60]; +} CM_EISA_FUNCTION_INFORMATION, *PCM_EISA_FUNCTION_INFORMATION; + +/* CM_EISA_FUNCTION_INFORMATION.FunctionFlags */ + +#define EISA_FUNCTION_ENABLED 0x80 +#define EISA_FREE_FORM_DATA 0x40 +#define EISA_HAS_PORT_INIT_ENTRY 0x20 +#define EISA_HAS_PORT_RANGE 0x10 +#define EISA_HAS_DMA_ENTRY 0x08 +#define EISA_HAS_IRQ_ENTRY 0x04 +#define EISA_HAS_MEMORY_ENTRY 0x02 +#define EISA_HAS_TYPE_ENTRY 0x01 +#define EISA_HAS_INFORMATION \ + EISA_HAS_PORT_RANGE + EISA_HAS_DMA_ENTRY + EISA_HAS_IRQ_ENTRY \ + + EISA_HAS_MEMORY_ENTRY + EISA_HAS_TYPE_ENTRY + +typedef struct _CM_EISA_SLOT_INFORMATION { + UCHAR ReturnCode; + UCHAR ReturnFlags; + UCHAR MajorRevision; + UCHAR MinorRevision; + USHORT Checksum; + UCHAR NumberFunctions; + UCHAR FunctionInformation; + ULONG CompressedId; +} CM_EISA_SLOT_INFORMATION, *PCM_EISA_SLOT_INFORMATION; + +/* CM_EISA_SLOT_INFORMATION.ReturnCode */ + +#define EISA_INVALID_SLOT 0x80 +#define EISA_INVALID_FUNCTION 0x81 +#define EISA_INVALID_CONFIGURATION 0x82 +#define EISA_EMPTY_SLOT 0x83 +#define EISA_INVALID_BIOS_CALL 0x86 + +typedef struct _CM_FLOPPY_DEVICE_DATA { + USHORT Version; + USHORT Revision; + CHAR Size[8]; + ULONG MaxDensity; + ULONG MountDensity; + UCHAR StepRateHeadUnloadTime; + UCHAR HeadLoadTime; + UCHAR MotorOffTime; + UCHAR SectorLengthCode; + UCHAR SectorPerTrack; + UCHAR ReadWriteGapLength; + UCHAR DataTransferLength; + UCHAR FormatGapLength; + UCHAR FormatFillCharacter; + UCHAR HeadSettleTime; + UCHAR MotorSettleTime; + UCHAR MaximumTrackValue; + UCHAR DataTransferRate; +} CM_FLOPPY_DEVICE_DATA, *PCM_FLOPPY_DEVICE_DATA; + +typedef enum _INTERFACE_TYPE { + InterfaceTypeUndefined = -1, + Internal, + Isa, + Eisa, + MicroChannel, + TurboChannel, + PCIBus, + VMEBus, + NuBus, + PCMCIABus, + CBus, + MPIBus, + MPSABus, + ProcessorInternal, + InternalPowerBus, + PNPISABus, + PNPBus, + MaximumInterfaceType +} INTERFACE_TYPE, *PINTERFACE_TYPE; + +typedef struct _PNP_BUS_INFORMATION { + GUID BusTypeGuid; + INTERFACE_TYPE LegacyBusType; + ULONG BusNumber; +} PNP_BUS_INFORMATION, *PPNP_BUS_INFORMATION; + +typedef struct _CM_PARTIAL_RESOURCE_DESCRIPTOR { + UCHAR Type; + UCHAR ShareDisposition; + USHORT Flags; + union { + struct { + PHYSICAL_ADDRESS Start; + ULONG Length; + } Generic; + struct { + PHYSICAL_ADDRESS Start; + ULONG Length; + } Port; + struct { + ULONG Level; + ULONG Vector; + ULONG Affinity; + } Interrupt; + struct { + PHYSICAL_ADDRESS Start; + ULONG Length; + } Memory; + struct { + ULONG Channel; + ULONG Port; + ULONG Reserved1; + } Dma; + struct { + ULONG Data[3]; + } DevicePrivate; + struct { + ULONG Start; + ULONG Length; + ULONG Reserved; + } BusNumber; + struct { + ULONG DataSize; + ULONG Reserved1; + ULONG Reserved2; + } DeviceSpecificData; + } u; +} CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR; + +/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Type */ + +#define CmResourceTypeNull 0 +#define CmResourceTypePort 1 +#define CmResourceTypeInterrupt 2 +#define CmResourceTypeMemory 3 +#define CmResourceTypeDma 4 +#define CmResourceTypeDeviceSpecific 5 +#define CmResourceTypeBusNumber 6 +#define CmResourceTypeMaximum 7 +#define CmResourceTypeNonArbitrated 128 +#define CmResourceTypeConfigData 128 +#define CmResourceTypeDevicePrivate 129 +#define CmResourceTypePcCardConfig 130 +#define CmResourceTypeMfCardConfig 131 + +/* CM_PARTIAL_RESOURCE_DESCRIPTOR.ShareDisposition */ + +typedef enum _CM_SHARE_DISPOSITION { + CmResourceShareUndetermined, + CmResourceShareDeviceExclusive, + CmResourceShareDriverExclusive, + CmResourceShareShared +} CM_SHARE_DISPOSITION; + +/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypePort */ + +#define CM_RESOURCE_PORT_MEMORY 0x0000 +#define CM_RESOURCE_PORT_IO 0x0001 +#define CM_RESOURCE_PORT_10_BIT_DECODE 0x0004 +#define CM_RESOURCE_PORT_12_BIT_DECODE 0x0008 +#define CM_RESOURCE_PORT_16_BIT_DECODE 0x0010 +#define CM_RESOURCE_PORT_POSITIVE_DECODE 0x0020 +#define CM_RESOURCE_PORT_PASSIVE_DECODE 0x0040 +#define CM_RESOURCE_PORT_WINDOW_DECODE 0x0080 + +/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypeInterrupt */ + +#define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE 0x0000 +#define CM_RESOURCE_INTERRUPT_LATCHED 0x0001 + +/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypeMemory */ + +#define CM_RESOURCE_MEMORY_READ_WRITE 0x0000 +#define CM_RESOURCE_MEMORY_READ_ONLY 0x0001 +#define CM_RESOURCE_MEMORY_WRITE_ONLY 0x0002 +#define CM_RESOURCE_MEMORY_PREFETCHABLE 0x0004 +#define CM_RESOURCE_MEMORY_COMBINEDWRITE 0x0008 +#define CM_RESOURCE_MEMORY_24 0x0010 +#define CM_RESOURCE_MEMORY_CACHEABLE 0x0020 + +/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypeDma */ + +#define CM_RESOURCE_DMA_8 0x0000 +#define CM_RESOURCE_DMA_16 0x0001 +#define CM_RESOURCE_DMA_32 0x0002 +#define CM_RESOURCE_DMA_8_AND_16 0x0004 +#define CM_RESOURCE_DMA_BUS_MASTER 0x0008 +#define CM_RESOURCE_DMA_TYPE_A 0x0010 +#define CM_RESOURCE_DMA_TYPE_B 0x0020 +#define CM_RESOURCE_DMA_TYPE_F 0x0040 + +typedef struct _CM_PARTIAL_RESOURCE_LIST { + USHORT Version; + USHORT Revision; + ULONG Count; + CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]; +} CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST; + +typedef struct _CM_FULL_RESOURCE_DESCRIPTOR { + INTERFACE_TYPE InterfaceType; + ULONG BusNumber; + CM_PARTIAL_RESOURCE_LIST PartialResourceList; +} CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR; + +typedef struct _CM_RESOURCE_LIST { + ULONG Count; + CM_FULL_RESOURCE_DESCRIPTOR List[1]; +} CM_RESOURCE_LIST, *PCM_RESOURCE_LIST; + +typedef struct _CM_INT13_DRIVE_PARAMETER { + USHORT DriveSelect; + ULONG MaxCylinders; + USHORT SectorsPerTrack; + USHORT MaxHeads; + USHORT NumberDrives; +} CM_INT13_DRIVE_PARAMETER, *PCM_INT13_DRIVE_PARAMETER; + +typedef struct _CM_KEYBOARD_DEVICE_DATA { + USHORT Version; + USHORT Revision; + UCHAR Type; + UCHAR Subtype; + USHORT KeyboardFlags; +} CM_KEYBOARD_DEVICE_DATA, *PCM_KEYBOARD_DEVICE_DATA; + +#define KEYBOARD_INSERT_ON 0x80 +#define KEYBOARD_CAPS_LOCK_ON 0x40 +#define KEYBOARD_NUM_LOCK_ON 0x20 +#define KEYBOARD_SCROLL_LOCK_ON 0x10 +#define KEYBOARD_ALT_KEY_DOWN 0x08 +#define KEYBOARD_CTRL_KEY_DOWN 0x04 +#define KEYBOARD_LEFT_SHIFT_DOWN 0x02 +#define KEYBOARD_RIGHT_SHIFT_DOWN 0x01 + +typedef struct _CM_MCA_POS_DATA { + USHORT AdapterId; + UCHAR PosData1; + UCHAR PosData2; + UCHAR PosData3; + UCHAR PosData4; +} CM_MCA_POS_DATA, *PCM_MCA_POS_DATA; + +typedef struct CM_Power_Data_s { + ULONG PD_Size; + DEVICE_POWER_STATE PD_MostRecentPowerState; + ULONG PD_Capabilities; + ULONG PD_D1Latency; + ULONG PD_D2Latency; + ULONG PD_D3Latency; + DEVICE_POWER_STATE PD_PowerStateMapping[PowerSystemMaximum]; +} CM_POWER_DATA, *PCM_POWER_DATA; + +#define PDCAP_D0_SUPPORTED 0x00000001 +#define PDCAP_D1_SUPPORTED 0x00000002 +#define PDCAP_D2_SUPPORTED 0x00000004 +#define PDCAP_D3_SUPPORTED 0x00000008 +#define PDCAP_WAKE_FROM_D0_SUPPORTED 0x00000010 +#define PDCAP_WAKE_FROM_D1_SUPPORTED 0x00000020 +#define PDCAP_WAKE_FROM_D2_SUPPORTED 0x00000040 +#define PDCAP_WAKE_FROM_D3_SUPPORTED 0x00000080 +#define PDCAP_WARM_EJECT_SUPPORTED 0x00000100 + +typedef struct _CM_SCSI_DEVICE_DATA { + USHORT Version; + USHORT Revision; + UCHAR HostIdentifier; +} CM_SCSI_DEVICE_DATA, *PCM_SCSI_DEVICE_DATA; + +typedef struct _CM_SERIAL_DEVICE_DATA { + USHORT Version; + USHORT Revision; + ULONG BaudClock; +} CM_SERIAL_DEVICE_DATA, *PCM_SERIAL_DEVICE_DATA; + +/* IO_RESOURCE_DESCRIPTOR.Option */ + +#define IO_RESOURCE_PREFERRED 0x01 +#define IO_RESOURCE_DEFAULT 0x02 +#define IO_RESOURCE_ALTERNATIVE 0x08 + +typedef struct _IO_RESOURCE_DESCRIPTOR { + UCHAR Option; + UCHAR Type; + UCHAR ShareDisposition; + UCHAR Spare1; + USHORT Flags; + USHORT Spare2; + union { + struct { + ULONG Length; + ULONG Alignment; + PHYSICAL_ADDRESS MinimumAddress; + PHYSICAL_ADDRESS MaximumAddress; + } Port; + struct { + ULONG Length; + ULONG Alignment; + PHYSICAL_ADDRESS MinimumAddress; + PHYSICAL_ADDRESS MaximumAddress; + } Memory; + struct { + ULONG MinimumVector; + ULONG MaximumVector; + } Interrupt; + struct { + ULONG MinimumChannel; + ULONG MaximumChannel; + } Dma; + struct { + ULONG Length; + ULONG Alignment; + PHYSICAL_ADDRESS MinimumAddress; + PHYSICAL_ADDRESS MaximumAddress; + } Generic; + struct { + ULONG Data[3]; + } DevicePrivate; + struct { + ULONG Length; + ULONG MinBusNumber; + ULONG MaxBusNumber; + ULONG Reserved; + } BusNumber; + struct { + ULONG Priority; + ULONG Reserved1; + ULONG Reserved2; + } ConfigData; + } u; +} IO_RESOURCE_DESCRIPTOR, *PIO_RESOURCE_DESCRIPTOR; + +typedef struct _IO_RESOURCE_LIST { + USHORT Version; + USHORT Revision; + ULONG Count; + IO_RESOURCE_DESCRIPTOR Descriptors[1]; +} IO_RESOURCE_LIST, *PIO_RESOURCE_LIST; + +typedef struct _IO_RESOURCE_REQUIREMENTS_LIST { + ULONG ListSize; + INTERFACE_TYPE InterfaceType; + ULONG BusNumber; + ULONG SlotNumber; + ULONG Reserved[3]; + ULONG AlternativeLists; + IO_RESOURCE_LIST List[1]; +} IO_RESOURCE_REQUIREMENTS_LIST, *PIO_RESOURCE_REQUIREMENTS_LIST; + +typedef struct _CONTROLLER_OBJECT { + CSHORT Type; + CSHORT Size; + PVOID ControllerExtension; + KDEVICE_QUEUE DeviceWaitQueue; + ULONG Spare1; + LARGE_INTEGER Spare2; +} CONTROLLER_OBJECT, *PCONTROLLER_OBJECT; + +typedef enum _DMA_WIDTH { + Width8Bits, + Width16Bits, + Width32Bits, + MaximumDmaWidth +} DMA_WIDTH, *PDMA_WIDTH; + +typedef enum _DMA_SPEED { + Compatible, + TypeA, + TypeB, + TypeC, + TypeF, + MaximumDmaSpeed +} DMA_SPEED, *PDMA_SPEED; + +/* DEVICE_DESCRIPTION.Version */ + +#define DEVICE_DESCRIPTION_VERSION 0x0000 +#define DEVICE_DESCRIPTION_VERSION1 0x0001 +#define DEVICE_DESCRIPTION_VERSION2 0x0002 + +typedef struct _DEVICE_DESCRIPTION { + ULONG Version; + BOOLEAN Master; + BOOLEAN ScatterGather; + BOOLEAN DemandMode; + BOOLEAN AutoInitialize; + BOOLEAN Dma32BitAddresses; + BOOLEAN IgnoreCount; + BOOLEAN Reserved1; + BOOLEAN Dma64BitAddresses; + ULONG BusNumber; + ULONG DmaChannel; + INTERFACE_TYPE InterfaceType; + DMA_WIDTH DmaWidth; + DMA_SPEED DmaSpeed; + ULONG MaximumLength; + ULONG DmaPort; +} DEVICE_DESCRIPTION, *PDEVICE_DESCRIPTION; + +/* VPB.Flags */ +#define VPB_MOUNTED 0x0001 +#define VPB_LOCKED 0x0002 +#define VPB_PERSISTENT 0x0004 +#define VPB_REMOVE_PENDING 0x0008 +#define VPB_RAW_MOUNT 0x0010 + +#define MAXIMUM_VOLUME_LABEL_LENGTH (32 * sizeof(WCHAR)) + +typedef struct _VPB { + CSHORT Type; + CSHORT Size; + USHORT Flags; + USHORT VolumeLabelLength; + struct _DEVICE_OBJECT *DeviceObject; + struct _DEVICE_OBJECT *RealDevice; + ULONG SerialNumber; + ULONG ReferenceCount; + WCHAR VolumeLabel[MAXIMUM_VOLUME_LABEL_LENGTH / sizeof(WCHAR)]; +} VPB, *PVPB; + +/* DEVICE_OBJECT.Flags */ + +#define DO_VERIFY_VOLUME 0x00000002 +#define DO_BUFFERED_IO 0x00000004 +#define DO_EXCLUSIVE 0x00000008 +#define DO_DIRECT_IO 0x00000010 +#define DO_MAP_IO_BUFFER 0x00000020 +#define DO_DEVICE_HAS_NAME 0x00000040 +#define DO_DEVICE_INITIALIZING 0x00000080 +#define DO_SYSTEM_BOOT_PARTITION 0x00000100 +#define DO_LONG_TERM_REQUESTS 0x00000200 +#define DO_NEVER_LAST_DEVICE 0x00000400 +#define DO_SHUTDOWN_REGISTERED 0x00000800 +#define DO_BUS_ENUMERATED_DEVICE 0x00001000 +#define DO_POWER_PAGABLE 0x00002000 +#define DO_POWER_INRUSH 0x00004000 +#define DO_LOW_PRIORITY_FILESYSTEM 0x00010000 + +/* DEVICE_OBJECT.Characteristics */ + +#define FILE_REMOVABLE_MEDIA 0x00000001 +#define FILE_READ_ONLY_DEVICE 0x00000002 +#define FILE_FLOPPY_DISKETTE 0x00000004 +#define FILE_WRITE_ONCE_MEDIA 0x00000008 +#define FILE_REMOTE_DEVICE 0x00000010 +#define FILE_DEVICE_IS_MOUNTED 0x00000020 +#define FILE_VIRTUAL_VOLUME 0x00000040 +#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080 +#define FILE_DEVICE_SECURE_OPEN 0x00000100 + +/* DEVICE_OBJECT.AlignmentRequirement */ + +#define FILE_BYTE_ALIGNMENT 0x00000000 +#define FILE_WORD_ALIGNMENT 0x00000001 +#define FILE_LONG_ALIGNMENT 0x00000003 +#define FILE_QUAD_ALIGNMENT 0x00000007 +#define FILE_OCTA_ALIGNMENT 0x0000000f +#define FILE_32_BYTE_ALIGNMENT 0x0000001f +#define FILE_64_BYTE_ALIGNMENT 0x0000003f +#define FILE_128_BYTE_ALIGNMENT 0x0000007f +#define FILE_256_BYTE_ALIGNMENT 0x000000ff +#define FILE_512_BYTE_ALIGNMENT 0x000001ff + +/* DEVICE_OBJECT.DeviceType */ + +#define DEVICE_TYPE ULONG + +#define FILE_DEVICE_BEEP 0x00000001 +#define FILE_DEVICE_CD_ROM 0x00000002 +#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 +#define FILE_DEVICE_CONTROLLER 0x00000004 +#define FILE_DEVICE_DATALINK 0x00000005 +#define FILE_DEVICE_DFS 0x00000006 +#define FILE_DEVICE_DISK 0x00000007 +#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 +#define FILE_DEVICE_FILE_SYSTEM 0x00000009 +#define FILE_DEVICE_INPORT_PORT 0x0000000a +#define FILE_DEVICE_KEYBOARD 0x0000000b +#define FILE_DEVICE_MAILSLOT 0x0000000c +#define FILE_DEVICE_MIDI_IN 0x0000000d +#define FILE_DEVICE_MIDI_OUT 0x0000000e +#define FILE_DEVICE_MOUSE 0x0000000f +#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 +#define FILE_DEVICE_NAMED_PIPE 0x00000011 +#define FILE_DEVICE_NETWORK 0x00000012 +#define FILE_DEVICE_NETWORK_BROWSER 0x00000013 +#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 +#define FILE_DEVICE_NULL 0x00000015 +#define FILE_DEVICE_PARALLEL_PORT 0x00000016 +#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 +#define FILE_DEVICE_PRINTER 0x00000018 +#define FILE_DEVICE_SCANNER 0x00000019 +#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a +#define FILE_DEVICE_SERIAL_PORT 0x0000001b +#define FILE_DEVICE_SCREEN 0x0000001c +#define FILE_DEVICE_SOUND 0x0000001d +#define FILE_DEVICE_STREAMS 0x0000001e +#define FILE_DEVICE_TAPE 0x0000001f +#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 +#define FILE_DEVICE_TRANSPORT 0x00000021 +#define FILE_DEVICE_UNKNOWN 0x00000022 +#define FILE_DEVICE_VIDEO 0x00000023 +#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 +#define FILE_DEVICE_WAVE_IN 0x00000025 +#define FILE_DEVICE_WAVE_OUT 0x00000026 +#define FILE_DEVICE_8042_PORT 0x00000027 +#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 +#define FILE_DEVICE_BATTERY 0x00000029 +#define FILE_DEVICE_BUS_EXTENDER 0x0000002a +#define FILE_DEVICE_MODEM 0x0000002b +#define FILE_DEVICE_VDM 0x0000002c +#define FILE_DEVICE_MASS_STORAGE 0x0000002d +#define FILE_DEVICE_SMB 0x0000002e +#define FILE_DEVICE_KS 0x0000002f +#define FILE_DEVICE_CHANGER 0x00000030 +#define FILE_DEVICE_SMARTCARD 0x00000031 +#define FILE_DEVICE_ACPI 0x00000032 +#define FILE_DEVICE_DVD 0x00000033 +#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034 +#define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035 +#define FILE_DEVICE_DFS_VOLUME 0x00000036 +#define FILE_DEVICE_SERENUM 0x00000037 +#define FILE_DEVICE_TERMSRV 0x00000038 +#define FILE_DEVICE_KSEC 0x00000039 +#define FILE_DEVICE_FIPS 0x0000003a + +typedef struct _DEVICE_OBJECT { + CSHORT Type; + USHORT Size; + LONG ReferenceCount; + struct _DRIVER_OBJECT *DriverObject; + struct _DEVICE_OBJECT *NextDevice; + struct _DEVICE_OBJECT *AttachedDevice; + struct _IRP *CurrentIrp; + PIO_TIMER Timer; + ULONG Flags; + ULONG Characteristics; + PVPB Vpb; + PVOID DeviceExtension; + DEVICE_TYPE DeviceType; + CCHAR StackSize; + union { + LIST_ENTRY ListEntry; + WAIT_CONTEXT_BLOCK Wcb; + } Queue; + ULONG AlignmentRequirement; + KDEVICE_QUEUE DeviceQueue; + KDPC Dpc; + ULONG ActiveThreadCount; + PSECURITY_DESCRIPTOR SecurityDescriptor; + KEVENT DeviceLock; + USHORT SectorSize; + USHORT Spare1; + struct _DEVOBJ_EXTENSION *DeviceObjectExtension; + PVOID Reserved; +} DEVICE_OBJECT; +typedef struct _DEVICE_OBJECT *PDEVICE_OBJECT; + +typedef enum _DEVICE_RELATION_TYPE { + BusRelations, + EjectionRelations, + PowerRelations, + RemovalRelations, + TargetDeviceRelation, + SingleBusRelations +} DEVICE_RELATION_TYPE, *PDEVICE_RELATION_TYPE; + +typedef struct _DEVICE_RELATIONS { + ULONG Count; + PDEVICE_OBJECT Objects[1]; +} DEVICE_RELATIONS, *PDEVICE_RELATIONS; + +typedef struct _SCATTER_GATHER_ELEMENT { + PHYSICAL_ADDRESS Address; + ULONG Length; + ULONG_PTR Reserved; +} SCATTER_GATHER_ELEMENT, *PSCATTER_GATHER_ELEMENT; + +typedef struct _SCATTER_GATHER_LIST { + ULONG NumberOfElements; + ULONG_PTR Reserved; + SCATTER_GATHER_ELEMENT Elements[0]; +} SCATTER_GATHER_LIST, *PSCATTER_GATHER_LIST; + +typedef struct _MDL { + struct _MDL *Next; + CSHORT Size; + CSHORT MdlFlags; + struct _EPROCESS *Process; + PVOID MappedSystemVa; + PVOID StartVa; + ULONG ByteCount; + ULONG ByteOffset; +} MDL, *PMDL; + +#define MDL_MAPPED_TO_SYSTEM_VA 0x0001 +#define MDL_PAGES_LOCKED 0x0002 +#define MDL_SOURCE_IS_NONPAGED_POOL 0x0004 +#define MDL_ALLOCATED_FIXED_SIZE 0x0008 +#define MDL_PARTIAL 0x0010 +#define MDL_PARTIAL_HAS_BEEN_MAPPED 0x0020 +#define MDL_IO_PAGE_READ 0x0040 +#define MDL_WRITE_OPERATION 0x0080 +#define MDL_PARENT_MAPPED_SYSTEM_VA 0x0100 +#define MDL_FREE_EXTRA_PTES 0x0200 +#define MDL_IO_SPACE 0x0800 +#define MDL_NETWORK_HEADER 0x1000 +#define MDL_MAPPING_CAN_FAIL 0x2000 +#define MDL_ALLOCATED_MUST_SUCCEED 0x4000 + +#define MDL_MAPPING_FLAGS ( \ + MDL_MAPPED_TO_SYSTEM_VA | \ + MDL_PAGES_LOCKED | \ + MDL_SOURCE_IS_NONPAGED_POOL | \ + MDL_PARTIAL_HAS_BEEN_MAPPED | \ + MDL_PARENT_MAPPED_SYSTEM_VA | \ + MDL_SYSTEM_VA | \ + MDL_IO_SPACE) + +typedef VOID DDKAPI +(*PPUT_DMA_ADAPTER)( + IN PDMA_ADAPTER DmaAdapter); + +typedef PVOID DDKAPI +(*PALLOCATE_COMMON_BUFFER)( + IN PDMA_ADAPTER DmaAdapter, + IN ULONG Length, + OUT PPHYSICAL_ADDRESS LogicalAddress, + IN BOOLEAN CacheEnabled); + +typedef VOID DDKAPI +(*PFREE_COMMON_BUFFER)( + IN PDMA_ADAPTER DmaAdapter, + IN ULONG Length, + IN PHYSICAL_ADDRESS LogicalAddress, + IN PVOID VirtualAddress, + IN BOOLEAN CacheEnabled); + +typedef NTSTATUS DDKAPI +(*PALLOCATE_ADAPTER_CHANNEL)( + IN PDMA_ADAPTER DmaAdapter, + IN PDEVICE_OBJECT DeviceObject, + IN ULONG NumberOfMapRegisters, + IN PDRIVER_CONTROL ExecutionRoutine, + IN PVOID Context); + +typedef BOOLEAN DDKAPI +(*PFLUSH_ADAPTER_BUFFERS)( + IN PDMA_ADAPTER DmaAdapter, + IN PMDL Mdl, + IN PVOID MapRegisterBase, + IN PVOID CurrentVa, + IN ULONG Length, + IN BOOLEAN WriteToDevice); + +typedef VOID DDKAPI +(*PFREE_ADAPTER_CHANNEL)( + IN PDMA_ADAPTER DmaAdapter); + +typedef VOID DDKAPI +(*PFREE_MAP_REGISTERS)( + IN PDMA_ADAPTER DmaAdapter, + PVOID MapRegisterBase, + ULONG NumberOfMapRegisters); + +typedef PHYSICAL_ADDRESS DDKAPI +(*PMAP_TRANSFER)( + IN PDMA_ADAPTER DmaAdapter, + IN PMDL Mdl, + IN PVOID MapRegisterBase, + IN PVOID CurrentVa, + IN OUT PULONG Length, + IN BOOLEAN WriteToDevice); + +typedef ULONG DDKAPI +(*PGET_DMA_ALIGNMENT)( + IN PDMA_ADAPTER DmaAdapter); + +typedef ULONG DDKAPI +(*PREAD_DMA_COUNTER)( + IN PDMA_ADAPTER DmaAdapter); + +typedef NTSTATUS DDKAPI +(*PGET_SCATTER_GATHER_LIST)( + IN PDMA_ADAPTER DmaAdapter, + IN PDEVICE_OBJECT DeviceObject, + IN PMDL Mdl, + IN PVOID CurrentVa, + IN ULONG Length, + IN PDRIVER_LIST_CONTROL ExecutionRoutine, + IN PVOID Context, + IN BOOLEAN WriteToDevice); + +typedef VOID DDKAPI +(*PPUT_SCATTER_GATHER_LIST)( + IN PDMA_ADAPTER DmaAdapter, + IN PSCATTER_GATHER_LIST ScatterGather, + IN BOOLEAN WriteToDevice); + +typedef NTSTATUS DDKAPI +(*PCALCULATE_SCATTER_GATHER_LIST_SIZE)( + IN PDMA_ADAPTER DmaAdapter, + IN PMDL Mdl OPTIONAL, + IN PVOID CurrentVa, + IN ULONG Length, + OUT PULONG ScatterGatherListSize, + OUT PULONG pNumberOfMapRegisters OPTIONAL); + +typedef NTSTATUS DDKAPI +(*PBUILD_SCATTER_GATHER_LIST)( + IN PDMA_ADAPTER DmaAdapter, + IN PDEVICE_OBJECT DeviceObject, + IN PMDL Mdl, + IN PVOID CurrentVa, + IN ULONG Length, + IN PDRIVER_LIST_CONTROL ExecutionRoutine, + IN PVOID Context, + IN BOOLEAN WriteToDevice, + IN PVOID ScatterGatherBuffer, + IN ULONG ScatterGatherLength); + +typedef NTSTATUS DDKAPI +(*PBUILD_MDL_FROM_SCATTER_GATHER_LIST)( + IN PDMA_ADAPTER DmaAdapter, + IN PSCATTER_GATHER_LIST ScatterGather, + IN PMDL OriginalMdl, + OUT PMDL *TargetMdl); + +typedef struct _DMA_OPERATIONS { + ULONG Size; + PPUT_DMA_ADAPTER PutDmaAdapter; + PALLOCATE_COMMON_BUFFER AllocateCommonBuffer; + PFREE_COMMON_BUFFER FreeCommonBuffer; + PALLOCATE_ADAPTER_CHANNEL AllocateAdapterChannel; + PFLUSH_ADAPTER_BUFFERS FlushAdapterBuffers; + PFREE_ADAPTER_CHANNEL FreeAdapterChannel; + PFREE_MAP_REGISTERS FreeMapRegisters; + PMAP_TRANSFER MapTransfer; + PGET_DMA_ALIGNMENT GetDmaAlignment; + PREAD_DMA_COUNTER ReadDmaCounter; + PGET_SCATTER_GATHER_LIST GetScatterGatherList; + PPUT_SCATTER_GATHER_LIST PutScatterGatherList; + PCALCULATE_SCATTER_GATHER_LIST_SIZE CalculateScatterGatherList; + PBUILD_SCATTER_GATHER_LIST BuildScatterGatherList; + PBUILD_MDL_FROM_SCATTER_GATHER_LIST BuildMdlFromScatterGatherList; +} DMA_OPERATIONS, *PDMA_OPERATIONS; + +typedef struct _DMA_ADAPTER { + USHORT Version; + USHORT Size; + PDMA_OPERATIONS DmaOperations; +} DMA_ADAPTER; + +typedef enum _FILE_INFORMATION_CLASS { + FileDirectoryInformation = 1, + FileFullDirectoryInformation, + FileBothDirectoryInformation, + FileBasicInformation, + FileStandardInformation, + FileInternalInformation, + FileEaInformation, + FileAccessInformation, + FileNameInformation, + FileRenameInformation, + FileLinkInformation, + FileNamesInformation, + FileDispositionInformation, + FilePositionInformation, + FileFullEaInformation, + FileModeInformation, + FileAlignmentInformation, + FileAllInformation, + FileAllocationInformation, + FileEndOfFileInformation, + FileAlternateNameInformation, + FileStreamInformation, + FilePipeInformation, + FilePipeLocalInformation, + FilePipeRemoteInformation, + FileMailslotQueryInformation, + FileMailslotSetInformation, + FileCompressionInformation, + FileObjectIdInformation, + FileCompletionInformation, + FileMoveClusterInformation, + FileQuotaInformation, + FileReparsePointInformation, + FileNetworkOpenInformation, + FileAttributeTagInformation, + FileTrackingInformation, + FileIdBothDirectoryInformation, + FileIdFullDirectoryInformation, + FileValidDataLengthInformation, + FileShortNameInformation, + FileMaximumInformation +} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; + +typedef struct _FILE_POSITION_INFORMATION { + LARGE_INTEGER CurrentByteOffset; +} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION; + +typedef struct _FILE_ALIGNMENT_INFORMATION { + ULONG AlignmentRequirement; +} FILE_ALIGNMENT_INFORMATION; + +typedef struct _FILE_NAME_INFORMATION { + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; + +typedef struct FILE_BASIC_INFORMATION { + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + ULONG FileAttributes; +} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; + +typedef struct _FILE_STANDARD_INFORMATION { + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG NumberOfLinks; + BOOLEAN DeletePending; + BOOLEAN Directory; +} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION; + +typedef struct _FILE_NETWORK_OPEN_INFORMATION { + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG FileAttributes; +} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION; + +typedef struct _FILE_ATTRIBUTE_TAG_INFORMATION { + ULONG FileAttributes; + ULONG ReparseTag; +} FILE_ATTRIBUTE_TAG_INFORMATION, *PFILE_ATTRIBUTE_TAG_INFORMATION; + +typedef struct _FILE_DISPOSITION_INFORMATION { + BOOLEAN DoDeleteFile; +} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; + +typedef struct _FILE_END_OF_FILE_INFORMATION { + LARGE_INTEGER EndOfFile; +} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION; + +typedef struct _FILE_VALID_DATA_LENGTH_INFORMATION { + LARGE_INTEGER ValidDataLength; +} FILE_VALID_DATA_LENGTH_INFORMATION, *PFILE_VALID_DATA_LENGTH_INFORMATION; + +typedef enum _FSINFOCLASS { + FileFsVolumeInformation = 1, + FileFsLabelInformation, + FileFsSizeInformation, + FileFsDeviceInformation, + FileFsAttributeInformation, + FileFsControlInformation, + FileFsFullSizeInformation, + FileFsObjectIdInformation, + FileFsDriverPathInformation, + FileFsMaximumInformation +} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS; + +typedef struct _FILE_FS_DEVICE_INFORMATION { + DEVICE_TYPE DeviceType; + ULONG Characteristics; +} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION; + +typedef struct _FILE_FULL_EA_INFORMATION { + ULONG NextEntryOffset; + UCHAR Flags; + UCHAR EaNameLength; + USHORT EaValueLength; + CHAR EaName[1]; +} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION; + +typedef ULONG_PTR ERESOURCE_THREAD; +typedef ERESOURCE_THREAD *PERESOURCE_THREAD; + +typedef struct _OWNER_ENTRY { + ERESOURCE_THREAD OwnerThread; + union { + LONG OwnerCount; + ULONG TableSize; + }; +} OWNER_ENTRY, *POWNER_ENTRY; + +/* ERESOURCE.Flag */ + +#define ResourceNeverExclusive 0x0010 +#define ResourceReleaseByOtherThread 0x0020 +#define ResourceOwnedExclusive 0x0080 + +#define RESOURCE_HASH_TABLE_SIZE 64 + +typedef struct _ERESOURCE { + LIST_ENTRY SystemResourcesList; + POWNER_ENTRY OwnerTable; + SHORT ActiveCount; + USHORT Flag; + PKSEMAPHORE SharedWaiters; + PKEVENT ExclusiveWaiters; + OWNER_ENTRY OwnerThreads[2]; + ULONG ContentionCount; + USHORT NumberOfSharedWaiters; + USHORT NumberOfExclusiveWaiters; + union { + PVOID Address; + ULONG_PTR CreatorBackTraceIndex; + }; + KSPIN_LOCK SpinLock; +} ERESOURCE, *PERESOURCE; + +/* NOTE: PVOID for methods to avoid 'assignment from incompatible pointer type' warning */ +typedef struct _DRIVER_EXTENSION { + struct _DRIVER_OBJECT *DriverObject; + PVOID AddDevice; + ULONG Count; + UNICODE_STRING ServiceKeyName; +} DRIVER_EXTENSION, *PDRIVER_EXTENSION; + +typedef BOOLEAN DDKAPI +(*PFAST_IO_CHECK_IF_POSSIBLE)( + IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + IN BOOLEAN CheckForReadOperation, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_READ)( + IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + OUT PVOID Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_WRITE)( + IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + IN PVOID Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_QUERY_BASIC_INFO)( + IN struct _FILE_OBJECT *FileObject, + IN BOOLEAN Wait, + OUT PFILE_BASIC_INFORMATION Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_QUERY_STANDARD_INFO)( + IN struct _FILE_OBJECT *FileObject, + IN BOOLEAN Wait, + OUT PFILE_STANDARD_INFORMATION Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_LOCK)( + IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + PEPROCESS ProcessId, + ULONG Key, + BOOLEAN FailImmediately, + BOOLEAN ExclusiveLock, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_UNLOCK_SINGLE)( + IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + PEPROCESS ProcessId, + ULONG Key, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_UNLOCK_ALL)( + IN struct _FILE_OBJECT *FileObject, + PEPROCESS ProcessId, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_UNLOCK_ALL_BY_KEY)( + IN struct _FILE_OBJECT *FileObject, + PVOID ProcessId, + ULONG Key, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_DEVICE_CONTROL)( + IN struct _FILE_OBJECT *FileObject, + IN BOOLEAN Wait, + IN PVOID InputBuffer OPTIONAL, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer OPTIONAL, + IN ULONG OutputBufferLength, + IN ULONG IoControlCode, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef VOID DDKAPI +(*PFAST_IO_ACQUIRE_FILE)( + IN struct _FILE_OBJECT *FileObject); + +typedef VOID DDKAPI +(*PFAST_IO_RELEASE_FILE)( + IN struct _FILE_OBJECT *FileObject); + +typedef VOID DDKAPI +(*PFAST_IO_DETACH_DEVICE)( + IN struct _DEVICE_OBJECT *SourceDevice, + IN struct _DEVICE_OBJECT *TargetDevice); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_QUERY_NETWORK_OPEN_INFO)( + IN struct _FILE_OBJECT *FileObject, + IN BOOLEAN Wait, + OUT struct _FILE_NETWORK_OPEN_INFORMATION *Buffer, + OUT struct _IO_STATUS_BLOCK *IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef NTSTATUS DDKAPI +(*PFAST_IO_ACQUIRE_FOR_MOD_WRITE)( + IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER EndingOffset, + OUT struct _ERESOURCE **ResourceToRelease, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_MDL_READ)( + IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_MDL_READ_COMPLETE)( + IN struct _FILE_OBJECT *FileObject, + IN PMDL MdlChain, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_PREPARE_MDL_WRITE)( + IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_MDL_WRITE_COMPLETE)( + IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN PMDL MdlChain, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_READ_COMPRESSED)( + IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + OUT PVOID Buffer, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus, + OUT struct _COMPRESSED_DATA_INFO *CompressedDataInfo, + IN ULONG CompressedDataInfoLength, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_WRITE_COMPRESSED)( + IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + IN PVOID Buffer, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _COMPRESSED_DATA_INFO *CompressedDataInfo, + IN ULONG CompressedDataInfoLength, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_MDL_READ_COMPLETE_COMPRESSED)( + IN struct _FILE_OBJECT *FileObject, + IN PMDL MdlChain, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_MDL_WRITE_COMPLETE_COMPRESSED)( + IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN PMDL MdlChain, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef BOOLEAN DDKAPI +(*PFAST_IO_QUERY_OPEN)( + IN struct _IRP *Irp, + OUT PFILE_NETWORK_OPEN_INFORMATION NetworkInformation, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef NTSTATUS DDKAPI +(*PFAST_IO_RELEASE_FOR_MOD_WRITE)( + IN struct _FILE_OBJECT *FileObject, + IN struct _ERESOURCE *ResourceToRelease, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef NTSTATUS DDKAPI +(*PFAST_IO_ACQUIRE_FOR_CCFLUSH)( + IN struct _FILE_OBJECT *FileObject, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef NTSTATUS DDKAPI +(*PFAST_IO_RELEASE_FOR_CCFLUSH) ( + IN struct _FILE_OBJECT *FileObject, + IN struct _DEVICE_OBJECT *DeviceObject); + +typedef struct _FAST_IO_DISPATCH { + ULONG SizeOfFastIoDispatch; + PFAST_IO_CHECK_IF_POSSIBLE FastIoCheckIfPossible; + PFAST_IO_READ FastIoRead; + PFAST_IO_WRITE FastIoWrite; + PFAST_IO_QUERY_BASIC_INFO FastIoQueryBasicInfo; + PFAST_IO_QUERY_STANDARD_INFO FastIoQueryStandardInfo; + PFAST_IO_LOCK FastIoLock; + PFAST_IO_UNLOCK_SINGLE FastIoUnlockSingle; + PFAST_IO_UNLOCK_ALL FastIoUnlockAll; + PFAST_IO_UNLOCK_ALL_BY_KEY FastIoUnlockAllByKey; + PFAST_IO_DEVICE_CONTROL FastIoDeviceControl; + PFAST_IO_ACQUIRE_FILE AcquireFileForNtCreateSection; + PFAST_IO_RELEASE_FILE ReleaseFileForNtCreateSection; + PFAST_IO_DETACH_DEVICE FastIoDetachDevice; + PFAST_IO_QUERY_NETWORK_OPEN_INFO FastIoQueryNetworkOpenInfo; + PFAST_IO_ACQUIRE_FOR_MOD_WRITE AcquireForModWrite; + PFAST_IO_MDL_READ MdlRead; + PFAST_IO_MDL_READ_COMPLETE MdlReadComplete; + PFAST_IO_PREPARE_MDL_WRITE PrepareMdlWrite; + PFAST_IO_MDL_WRITE_COMPLETE MdlWriteComplete; + PFAST_IO_READ_COMPRESSED FastIoReadCompressed; + PFAST_IO_WRITE_COMPRESSED FastIoWriteCompressed; + PFAST_IO_MDL_READ_COMPLETE_COMPRESSED MdlReadCompleteCompressed; + PFAST_IO_MDL_WRITE_COMPLETE_COMPRESSED MdlWriteCompleteCompressed; + PFAST_IO_QUERY_OPEN FastIoQueryOpen; + PFAST_IO_RELEASE_FOR_MOD_WRITE ReleaseForModWrite; + PFAST_IO_ACQUIRE_FOR_CCFLUSH AcquireForCcFlush; + PFAST_IO_RELEASE_FOR_CCFLUSH ReleaseForCcFlush; +} FAST_IO_DISPATCH, *PFAST_IO_DISPATCH; + +/* NOTE: PVOID for methods to avoid 'assignment from incompatible pointer type' warning */ +typedef struct _DRIVER_OBJECT { + CSHORT Type; + CSHORT Size; + PDEVICE_OBJECT DeviceObject; + ULONG Flags; + PVOID DriverStart; + ULONG DriverSize; + PVOID DriverSection; + PDRIVER_EXTENSION DriverExtension; + UNICODE_STRING DriverName; + PUNICODE_STRING HardwareDatabase; + PVOID FastIoDispatch; + PVOID DriverInit; + PVOID DriverStartIo; + PVOID DriverUnload; + PVOID MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; +} DRIVER_OBJECT; +typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT; + +typedef struct _SECTION_OBJECT_POINTERS { + PVOID DataSectionObject; + PVOID SharedCacheMap; + PVOID ImageSectionObject; +} SECTION_OBJECT_POINTERS, *PSECTION_OBJECT_POINTERS; + +typedef struct _IO_COMPLETION_CONTEXT { + PVOID Port; + PVOID Key; +} IO_COMPLETION_CONTEXT, *PIO_COMPLETION_CONTEXT; + +/* FILE_OBJECT.Flags */ + +#define FO_FILE_OPEN 0x00000001 +#define FO_SYNCHRONOUS_IO 0x00000002 +#define FO_ALERTABLE_IO 0x00000004 +#define FO_NO_INTERMEDIATE_BUFFERING 0x00000008 +#define FO_WRITE_THROUGH 0x00000010 +#define FO_SEQUENTIAL_ONLY 0x00000020 +#define FO_CACHE_SUPPORTED 0x00000040 +#define FO_NAMED_PIPE 0x00000080 +#define FO_STREAM_FILE 0x00000100 +#define FO_MAILSLOT 0x00000200 +#define FO_GENERATE_AUDIT_ON_CLOSE 0x00000400 +#define FO_DIRECT_DEVICE_OPEN 0x00000800 +#define FO_FILE_MODIFIED 0x00001000 +#define FO_FILE_SIZE_CHANGED 0x00002000 +#define FO_CLEANUP_COMPLETE 0x00004000 +#define FO_TEMPORARY_FILE 0x00008000 +#define FO_DELETE_ON_CLOSE 0x00010000 +#define FO_OPENED_CASE_SENSITIVE 0x00020000 +#define FO_HANDLE_CREATED 0x00040000 +#define FO_FILE_FAST_IO_READ 0x00080000 +#define FO_RANDOM_ACCESS 0x00100000 +#define FO_FILE_OPEN_CANCELLED 0x00200000 +#define FO_VOLUME_OPEN 0x00400000 +#define FO_FILE_OBJECT_HAS_EXTENSION 0x00800000 +#define FO_REMOTE_ORIGIN 0x01000000 + +typedef struct _FILE_OBJECT { + CSHORT Type; + CSHORT Size; + PDEVICE_OBJECT DeviceObject; + PVPB Vpb; + PVOID FsContext; + PVOID FsContext2; + PSECTION_OBJECT_POINTERS SectionObjectPointer; + PVOID PrivateCacheMap; + NTSTATUS FinalStatus; + struct _FILE_OBJECT *RelatedFileObject; + BOOLEAN LockOperation; + BOOLEAN DeletePending; + BOOLEAN ReadAccess; + BOOLEAN WriteAccess; + BOOLEAN DeleteAccess; + BOOLEAN SharedRead; + BOOLEAN SharedWrite; + BOOLEAN SharedDelete; + ULONG Flags; + UNICODE_STRING FileName; + LARGE_INTEGER CurrentByteOffset; + ULONG Waiters; + ULONG Busy; + PVOID LastLock; + KEVENT Lock; + KEVENT Event; + PIO_COMPLETION_CONTEXT CompletionContext; +} FILE_OBJECT; +typedef struct _FILE_OBJECT *PFILE_OBJECT; + +typedef enum _SECURITY_OPERATION_CODE { + SetSecurityDescriptor, + QuerySecurityDescriptor, + DeleteSecurityDescriptor, + AssignSecurityDescriptor +} SECURITY_OPERATION_CODE, *PSECURITY_OPERATION_CODE; + +#define INITIAL_PRIVILEGE_COUNT 3 + +typedef struct _INITIAL_PRIVILEGE_SET { + ULONG PrivilegeCount; + ULONG Control; + LUID_AND_ATTRIBUTES Privilege[INITIAL_PRIVILEGE_COUNT]; +} INITIAL_PRIVILEGE_SET, * PINITIAL_PRIVILEGE_SET; + +typedef struct _SECURITY_SUBJECT_CONTEXT { + PACCESS_TOKEN ClientToken; + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; + PACCESS_TOKEN PrimaryToken; + PVOID ProcessAuditId; +} SECURITY_SUBJECT_CONTEXT, *PSECURITY_SUBJECT_CONTEXT; + +typedef struct _ACCESS_STATE { + LUID OperationID; + BOOLEAN SecurityEvaluated; + BOOLEAN GenerateAudit; + BOOLEAN GenerateOnClose; + BOOLEAN PrivilegesAllocated; + ULONG Flags; + ACCESS_MASK RemainingDesiredAccess; + ACCESS_MASK PreviouslyGrantedAccess; + ACCESS_MASK OriginalDesiredAccess; + SECURITY_SUBJECT_CONTEXT SubjectSecurityContext; + PSECURITY_DESCRIPTOR SecurityDescriptor; + PVOID AuxData; + union { + INITIAL_PRIVILEGE_SET InitialPrivilegeSet; + PRIVILEGE_SET PrivilegeSet; + } Privileges; + + BOOLEAN AuditPrivileges; + UNICODE_STRING ObjectName; + UNICODE_STRING ObjectTypeName; +} ACCESS_STATE, *PACCESS_STATE; + +typedef struct _IO_SECURITY_CONTEXT { + PSECURITY_QUALITY_OF_SERVICE SecurityQos; + PACCESS_STATE AccessState; + ACCESS_MASK DesiredAccess; + ULONG FullCreateOptions; +} IO_SECURITY_CONTEXT, *PIO_SECURITY_CONTEXT; + +struct _IO_CSQ; + +typedef struct _IO_CSQ_IRP_CONTEXT { + ULONG Type; + struct _IRP *Irp; + struct _IO_CSQ *Csq; +} IO_CSQ_IRP_CONTEXT, *PIO_CSQ_IRP_CONTEXT; + +typedef VOID DDKAPI +(*PIO_CSQ_INSERT_IRP)( + IN struct _IO_CSQ *Csq, + IN PIRP Irp); + +typedef VOID DDKAPI +(*PIO_CSQ_REMOVE_IRP)( + IN struct _IO_CSQ *Csq, + IN PIRP Irp); + +typedef PIRP DDKAPI +(*PIO_CSQ_PEEK_NEXT_IRP)( + IN struct _IO_CSQ *Csq, + IN PIRP Irp, + IN PVOID PeekContext); + +typedef VOID DDKAPI +(*PIO_CSQ_ACQUIRE_LOCK)( + IN struct _IO_CSQ *Csq, + OUT PKIRQL Irql); + +typedef VOID DDKAPI +(*PIO_CSQ_RELEASE_LOCK)( + IN struct _IO_CSQ *Csq, + IN KIRQL Irql); + +typedef VOID DDKAPI +(*PIO_CSQ_COMPLETE_CANCELED_IRP)( + IN struct _IO_CSQ *Csq, + IN PIRP Irp); + +typedef struct _IO_CSQ { + ULONG Type; + PIO_CSQ_INSERT_IRP CsqInsertIrp; + PIO_CSQ_REMOVE_IRP CsqRemoveIrp; + PIO_CSQ_PEEK_NEXT_IRP CsqPeekNextIrp; + PIO_CSQ_ACQUIRE_LOCK CsqAcquireLock; + PIO_CSQ_RELEASE_LOCK CsqReleaseLock; + PIO_CSQ_COMPLETE_CANCELED_IRP CsqCompleteCanceledIrp; + PVOID ReservePointer; +} IO_CSQ, *PIO_CSQ; + +typedef struct _IO_STACK_LOCATION { + UCHAR MajorFunction; + UCHAR MinorFunction; + UCHAR Flags; + UCHAR Control; + union { + struct { + PIO_SECURITY_CONTEXT SecurityContext; + ULONG Options; + USHORT POINTER_ALIGNMENT FileAttributes; + USHORT ShareAccess; + ULONG POINTER_ALIGNMENT EaLength; + } Create; + struct { + ULONG Length; + ULONG POINTER_ALIGNMENT Key; + LARGE_INTEGER ByteOffset; + } Read; + struct { + ULONG Length; + ULONG POINTER_ALIGNMENT Key; + LARGE_INTEGER ByteOffset; + } Write; + struct { + ULONG Length; + FILE_INFORMATION_CLASS POINTER_ALIGNMENT FileInformationClass; + } QueryFile; + struct { + ULONG Length; + FILE_INFORMATION_CLASS POINTER_ALIGNMENT FileInformationClass; + PFILE_OBJECT FileObject; + union { + struct { + BOOLEAN ReplaceIfExists; + BOOLEAN AdvanceOnly; + }; + ULONG ClusterCount; + HANDLE DeleteHandle; + }; + } SetFile; + struct { + ULONG Length; + FS_INFORMATION_CLASS POINTER_ALIGNMENT FsInformationClass; + } QueryVolume; + struct { + ULONG OutputBufferLength; + ULONG POINTER_ALIGNMENT InputBufferLength; + ULONG POINTER_ALIGNMENT IoControlCode; + PVOID Type3InputBuffer; + } DeviceIoControl; + struct { + SECURITY_INFORMATION SecurityInformation; + ULONG POINTER_ALIGNMENT Length; + } QuerySecurity; + struct { + SECURITY_INFORMATION SecurityInformation; + PSECURITY_DESCRIPTOR SecurityDescriptor; + } SetSecurity; + struct { + PVPB Vpb; + PDEVICE_OBJECT DeviceObject; + } MountVolume; + struct { + PVPB Vpb; + PDEVICE_OBJECT DeviceObject; + } VerifyVolume; + struct { + struct _SCSI_REQUEST_BLOCK *Srb; + } Scsi; + struct { + DEVICE_RELATION_TYPE Type; + } QueryDeviceRelations; + struct { + CONST GUID *InterfaceType; + USHORT Size; + USHORT Version; + PINTERFACE Interface; + PVOID InterfaceSpecificData; + } QueryInterface; + struct { + PDEVICE_CAPABILITIES Capabilities; + } DeviceCapabilities; + struct { + PIO_RESOURCE_REQUIREMENTS_LIST IoResourceRequirementList; + } FilterResourceRequirements; + struct { + ULONG WhichSpace; + PVOID Buffer; + ULONG Offset; + ULONG POINTER_ALIGNMENT Length; + } ReadWriteConfig; + struct { + BOOLEAN Lock; + } SetLock; + struct { + BUS_QUERY_ID_TYPE IdType; + } QueryId; + struct { + DEVICE_TEXT_TYPE DeviceTextType; + LCID POINTER_ALIGNMENT LocaleId; + } QueryDeviceText; + struct { + BOOLEAN InPath; + BOOLEAN Reserved[3]; + DEVICE_USAGE_NOTIFICATION_TYPE POINTER_ALIGNMENT Type; + } UsageNotification; + struct { + SYSTEM_POWER_STATE PowerState; + } WaitWake; + struct { + PPOWER_SEQUENCE PowerSequence; + } PowerSequence; + struct { + ULONG SystemContext; + POWER_STATE_TYPE POINTER_ALIGNMENT Type; + POWER_STATE POINTER_ALIGNMENT State; + POWER_ACTION POINTER_ALIGNMENT ShutdownType; + } Power; + struct { + PCM_RESOURCE_LIST AllocatedResources; + PCM_RESOURCE_LIST AllocatedResourcesTranslated; + } StartDevice; + struct { + ULONG_PTR ProviderId; + PVOID DataPath; + ULONG BufferSize; + PVOID Buffer; + } WMI; + struct { + PVOID Argument1; + PVOID Argument2; + PVOID Argument3; + PVOID Argument4; + } Others; + } Parameters; + PDEVICE_OBJECT DeviceObject; + PFILE_OBJECT FileObject; + PIO_COMPLETION_ROUTINE CompletionRoutine; + PVOID Context; +} IO_STACK_LOCATION, *PIO_STACK_LOCATION; + +/* IO_STACK_LOCATION.Control */ + +#define SL_PENDING_RETURNED 0x01 +#define SL_INVOKE_ON_CANCEL 0x20 +#define SL_INVOKE_ON_SUCCESS 0x40 +#define SL_INVOKE_ON_ERROR 0x80 + +typedef enum _KEY_INFORMATION_CLASS { + KeyBasicInformation, + KeyNodeInformation, + KeyFullInformation, + KeyNameInformation, + KeyCachedInformation, + KeyFlagsInformation +} KEY_INFORMATION_CLASS; + +typedef struct _KEY_BASIC_INFORMATION { + LARGE_INTEGER LastWriteTime; + ULONG TitleIndex; + ULONG NameLength; + WCHAR Name[1]; +} KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION; + +typedef struct _KEY_FULL_INFORMATION { + LARGE_INTEGER LastWriteTime; + ULONG TitleIndex; + ULONG ClassOffset; + ULONG ClassLength; + ULONG SubKeys; + ULONG MaxNameLen; + ULONG MaxClassLen; + ULONG Values; + ULONG MaxValueNameLen; + ULONG MaxValueDataLen; + WCHAR Class[1]; +} KEY_FULL_INFORMATION, *PKEY_FULL_INFORMATION; + +typedef struct _KEY_NODE_INFORMATION { + LARGE_INTEGER LastWriteTime; + ULONG TitleIndex; + ULONG ClassOffset; + ULONG ClassLength; + ULONG NameLength; + WCHAR Name[1]; +} KEY_NODE_INFORMATION, *PKEY_NODE_INFORMATION; + +typedef struct _KEY_VALUE_BASIC_INFORMATION { + ULONG TitleIndex; + ULONG Type; + ULONG NameLength; + WCHAR Name[1]; +} KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION; + +typedef struct _KEY_VALUE_FULL_INFORMATION { + ULONG TitleIndex; + ULONG Type; + ULONG DataOffset; + ULONG DataLength; + ULONG NameLength; + WCHAR Name[1]; +} KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION; + +typedef struct _KEY_VALUE_PARTIAL_INFORMATION { + ULONG TitleIndex; + ULONG Type; + ULONG DataLength; + UCHAR Data[1]; +} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION; + +typedef struct _KEY_VALUE_PARTIAL_INFORMATION_ALIGN64 { + ULONG Type; + ULONG DataLength; + UCHAR Data[1]; +} KEY_VALUE_PARTIAL_INFORMATION_ALIGN64, *PKEY_VALUE_PARTIAL_INFORMATION_ALIGN64; + +typedef struct _KEY_VALUE_ENTRY { + PUNICODE_STRING ValueName; + ULONG DataLength; + ULONG DataOffset; + ULONG Type; +} KEY_VALUE_ENTRY, *PKEY_VALUE_ENTRY; + +typedef enum _KEY_VALUE_INFORMATION_CLASS { + KeyValueBasicInformation, + KeyValueFullInformation, + KeyValuePartialInformation, + KeyValueFullInformationAlign64, + KeyValuePartialInformationAlign64 +} KEY_VALUE_INFORMATION_CLASS; + +/* KEY_VALUE_Xxx.Type */ + +#define REG_NONE 0 +#define REG_SZ 1 +#define REG_EXPAND_SZ 2 +#define REG_BINARY 3 +#define REG_DWORD 4 +#define REG_DWORD_LITTLE_ENDIAN 4 +#define REG_DWORD_BIG_ENDIAN 5 +#define REG_LINK 6 +#define REG_MULTI_SZ 7 +#define REG_RESOURCE_LIST 8 +#define REG_FULL_RESOURCE_DESCRIPTOR 9 +#define REG_RESOURCE_REQUIREMENTS_LIST 10 +#define REG_QWORD 11 +#define REG_QWORD_LITTLE_ENDIAN 11 + +#define PCI_TYPE0_ADDRESSES 6 +#define PCI_TYPE1_ADDRESSES 2 +#define PCI_TYPE2_ADDRESSES 5 + +typedef struct _PCI_COMMON_CONFIG { + USHORT VendorID; + USHORT DeviceID; + USHORT Command; + USHORT Status; + UCHAR RevisionID; + UCHAR ProgIf; + UCHAR SubClass; + UCHAR BaseClass; + UCHAR CacheLineSize; + UCHAR LatencyTimer; + UCHAR HeaderType; + UCHAR BIST; + union { + struct _PCI_HEADER_TYPE_0 { + ULONG BaseAddresses[PCI_TYPE0_ADDRESSES]; + ULONG CIS; + USHORT SubVendorID; + USHORT SubSystemID; + ULONG ROMBaseAddress; + UCHAR CapabilitiesPtr; + UCHAR Reserved1[3]; + ULONG Reserved2; + UCHAR InterruptLine; + UCHAR InterruptPin; + UCHAR MinimumGrant; + UCHAR MaximumLatency; + } type0; + struct _PCI_HEADER_TYPE_1 { + ULONG BaseAddresses[PCI_TYPE1_ADDRESSES]; + UCHAR PrimaryBus; + UCHAR SecondaryBus; + UCHAR SubordinateBus; + UCHAR SecondaryLatency; + UCHAR IOBase; + UCHAR IOLimit; + USHORT SecondaryStatus; + USHORT MemoryBase; + USHORT MemoryLimit; + USHORT PrefetchBase; + USHORT PrefetchLimit; + ULONG PrefetchBaseUpper32; + ULONG PrefetchLimitUpper32; + USHORT IOBaseUpper16; + USHORT IOLimitUpper16; + UCHAR CapabilitiesPtr; + UCHAR Reserved1[3]; + ULONG ROMBaseAddress; + UCHAR InterruptLine; + UCHAR InterruptPin; + USHORT BridgeControl; + } type1; + struct _PCI_HEADER_TYPE_2 { + ULONG SocketRegistersBaseAddress; + UCHAR CapabilitiesPtr; + UCHAR Reserved; + USHORT SecondaryStatus; + UCHAR PrimaryBus; + UCHAR SecondaryBus; + UCHAR SubordinateBus; + UCHAR SecondaryLatency; + struct { + ULONG Base; + ULONG Limit; + } Range[PCI_TYPE2_ADDRESSES - 1]; + UCHAR InterruptLine; + UCHAR InterruptPin; + USHORT BridgeControl; + } type2; + } u; + UCHAR DeviceSpecific[192]; +} PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG; + +/* PCI_COMMON_CONFIG.Command */ + +#define PCI_ENABLE_IO_SPACE 0x0001 +#define PCI_ENABLE_MEMORY_SPACE 0x0002 +#define PCI_ENABLE_BUS_MASTER 0x0004 +#define PCI_ENABLE_SPECIAL_CYCLES 0x0008 +#define PCI_ENABLE_WRITE_AND_INVALIDATE 0x0010 +#define PCI_ENABLE_VGA_COMPATIBLE_PALETTE 0x0020 +#define PCI_ENABLE_PARITY 0x0040 +#define PCI_ENABLE_WAIT_CYCLE 0x0080 +#define PCI_ENABLE_SERR 0x0100 +#define PCI_ENABLE_FAST_BACK_TO_BACK 0x0200 + +/* PCI_COMMON_CONFIG.Status */ + +#define PCI_STATUS_CAPABILITIES_LIST 0x0010 +#define PCI_STATUS_66MHZ_CAPABLE 0x0020 +#define PCI_STATUS_UDF_SUPPORTED 0x0040 +#define PCI_STATUS_FAST_BACK_TO_BACK 0x0080 +#define PCI_STATUS_DATA_PARITY_DETECTED 0x0100 +#define PCI_STATUS_DEVSEL 0x0600 +#define PCI_STATUS_SIGNALED_TARGET_ABORT 0x0800 +#define PCI_STATUS_RECEIVED_TARGET_ABORT 0x1000 +#define PCI_STATUS_RECEIVED_MASTER_ABORT 0x2000 +#define PCI_STATUS_SIGNALED_SYSTEM_ERROR 0x4000 +#define PCI_STATUS_DETECTED_PARITY_ERROR 0x8000 + +/* PCI_COMMON_CONFIG.HeaderType */ + +#define PCI_MULTIFUNCTION 0x80 +#define PCI_DEVICE_TYPE 0x00 +#define PCI_BRIDGE_TYPE 0x01 +#define PCI_CARDBUS_BRIDGE_TYPE 0x02 + +#define PCI_CONFIGURATION_TYPE(PciData) \ + (((PPCI_COMMON_CONFIG) (PciData))->HeaderType & ~PCI_MULTIFUNCTION) + +#define PCI_MULTIFUNCTION_DEVICE(PciData) \ + ((((PPCI_COMMON_CONFIG) (PciData))->HeaderType & PCI_MULTIFUNCTION) != 0) + +typedef struct _PCI_SLOT_NUMBER { + union { + struct { + ULONG DeviceNumber : 5; + ULONG FunctionNumber : 3; + ULONG Reserved : 24; + } bits; + ULONG AsULONG; + } u; +} PCI_SLOT_NUMBER, *PPCI_SLOT_NUMBER; + +typedef enum _POOL_TYPE { + NonPagedPool, + PagedPool, + NonPagedPoolMustSucceed, + DontUseThisType, + NonPagedPoolCacheAligned, + PagedPoolCacheAligned, + NonPagedPoolCacheAlignedMustS, + MaxPoolType, + NonPagedPoolSession = 32, + PagedPoolSession, + NonPagedPoolMustSucceedSession, + DontUseThisTypeSession, + NonPagedPoolCacheAlignedSession, + PagedPoolCacheAlignedSession, + NonPagedPoolCacheAlignedMustSSession +} POOL_TYPE; + +typedef enum _EX_POOL_PRIORITY { + LowPoolPriority, + LowPoolPrioritySpecialPoolOverrun = 8, + LowPoolPrioritySpecialPoolUnderrun = 9, + NormalPoolPriority = 16, + NormalPoolPrioritySpecialPoolOverrun = 24, + NormalPoolPrioritySpecialPoolUnderrun = 25, + HighPoolPriority = 32, + HighPoolPrioritySpecialPoolOverrun = 40, + HighPoolPrioritySpecialPoolUnderrun = 41 +} EX_POOL_PRIORITY; + +/* PRIVILEGE_SET.Control */ + +#define PRIVILEGE_SET_ALL_NECESSARY 1 + +typedef struct _RTL_OSVERSIONINFOW { + ULONG dwOSVersionInfoSize; + ULONG dwMajorVersion; + ULONG dwMinorVersion; + ULONG dwBuildNumber; + ULONG dwPlatformId; + WCHAR szCSDVersion[128]; +} RTL_OSVERSIONINFOW, *PRTL_OSVERSIONINFOW; + +typedef struct _RTL_OSVERSIONINFOEXW { + ULONG dwOSVersionInfoSize; + ULONG dwMajorVersion; + ULONG dwMinorVersion; + ULONG dwBuildNumber; + ULONG dwPlatformId; + WCHAR szCSDVersion[128]; + USHORT wServicePackMajor; + USHORT wServicePackMinor; + USHORT wSuiteMask; + UCHAR wProductType; + UCHAR wReserved; +} RTL_OSVERSIONINFOEXW, *PRTL_OSVERSIONINFOEXW; + +NTOSAPI +ULONGLONG +DDKAPI +VerSetConditionMask( + IN ULONGLONG ConditionMask, + IN ULONG TypeMask, + IN UCHAR Condition); + +#define VER_SET_CONDITION(ConditionMask, TypeBitMask, ComparisonType) \ + ((ConditionMask) = VerSetConditionMask((ConditionMask), \ + (TypeBitMask), (ComparisonType))) + +/* RtlVerifyVersionInfo() TypeMask */ + +#define VER_MINORVERSION 0x0000001 +#define VER_MAJORVERSION 0x0000002 +#define VER_BUILDNUMBER 0x0000004 +#define VER_PLATFORMID 0x0000008 +#define VER_SERVICEPACKMINOR 0x0000010 +#define VER_SERVICEPACKMAJOR 0x0000020 +#define VER_SUITENAME 0x0000040 +#define VER_PRODUCT_TYPE 0x0000080 + +/* RtlVerifyVersionInfo() ComparisonType */ + +#define VER_EQUAL 1 +#define VER_GREATER 2 +#define VER_GREATER_EQUAL 3 +#define VER_LESS 4 +#define VER_LESS_EQUAL 5 +#define VER_AND 6 +#define VER_OR 7 + +#define VER_CONDITION_MASK 7 +#define VER_NUM_BITS_PER_CONDITION_MASK 3 + +typedef struct _RTL_BITMAP { + ULONG SizeOfBitMap; + PULONG Buffer; +} RTL_BITMAP, *PRTL_BITMAP; + +typedef struct _RTL_BITMAP_RUN { + ULONG StartingIndex; + ULONG NumberOfBits; +} RTL_BITMAP_RUN, *PRTL_BITMAP_RUN; + +typedef NTSTATUS DDKAPI +(*PRTL_QUERY_REGISTRY_ROUTINE)( + IN PWSTR ValueName, + IN ULONG ValueType, + IN PVOID ValueData, + IN ULONG ValueLength, + IN PVOID Context, + IN PVOID EntryContext); + +/* RTL_QUERY_REGISTRY_TABLE.Flags */ +#define RTL_QUERY_REGISTRY_SUBKEY 0x00000001 +#define RTL_QUERY_REGISTRY_TOPKEY 0x00000002 +#define RTL_QUERY_REGISTRY_REQUIRED 0x00000004 +#define RTL_QUERY_REGISTRY_NOVALUE 0x00000008 +#define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010 +#define RTL_QUERY_REGISTRY_DIRECT 0x00000020 +#define RTL_QUERY_REGISTRY_DELETE 0x00000040 + +typedef struct _RTL_QUERY_REGISTRY_TABLE { + PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine; + ULONG Flags; + PWSTR Name; + PVOID EntryContext; + ULONG DefaultType; + PVOID DefaultData; + ULONG DefaultLength; +} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE; + +typedef struct _TIME_FIELDS { + CSHORT Year; + CSHORT Month; + CSHORT Day; + CSHORT Hour; + CSHORT Minute; + CSHORT Second; + CSHORT Milliseconds; + CSHORT Weekday; +} TIME_FIELDS, *PTIME_FIELDS; + +typedef PVOID DDKAPI +(*PALLOCATE_FUNCTION)( + IN POOL_TYPE PoolType, + IN SIZE_T NumberOfBytes, + IN ULONG Tag); + +typedef VOID DDKAPI +(*PFREE_FUNCTION)( + IN PVOID Buffer); + +#define GENERAL_LOOKASIDE_S \ + SLIST_HEADER ListHead; \ + USHORT Depth; \ + USHORT MaximumDepth; \ + ULONG TotalAllocates; \ + union { \ + ULONG AllocateMisses; \ + ULONG AllocateHits; \ + }; \ + ULONG TotalFrees; \ + union { \ + ULONG FreeMisses; \ + ULONG FreeHits; \ + }; \ + POOL_TYPE Type; \ + ULONG Tag; \ + ULONG Size; \ + PALLOCATE_FUNCTION Allocate; \ + PFREE_FUNCTION Free; \ + LIST_ENTRY ListEntry; \ + ULONG LastTotalAllocates; \ + union { \ + ULONG LastAllocateMisses; \ + ULONG LastAllocateHits; \ + }; \ + ULONG Future[2]; + +typedef struct _GENERAL_LOOKASIDE { + GENERAL_LOOKASIDE_S; +} GENERAL_LOOKASIDE, *PGENERAL_LOOKASIDE; + +typedef struct _NPAGED_LOOKASIDE_LIST { + GENERAL_LOOKASIDE_S; + KSPIN_LOCK Obsoleted; +} NPAGED_LOOKASIDE_LIST, *PNPAGED_LOOKASIDE_LIST; + +typedef struct _PAGED_LOOKASIDE_LIST { + GENERAL_LOOKASIDE_S; + FAST_MUTEX Obsoleted; +} PAGED_LOOKASIDE_LIST, *PPAGED_LOOKASIDE_LIST; + +typedef struct _CALLBACK_OBJECT *PCALLBACK_OBJECT; + +typedef VOID DDKAPI (*PCALLBACK_FUNCTION)( + IN PVOID CallbackContext, + IN PVOID Argument1, + IN PVOID Argument2); + +typedef enum _EVENT_TYPE { + NotificationEvent, + SynchronizationEvent, +} EVENT_TYPE; + +typedef enum _KWAIT_REASON { + Executive, + FreePage, + PageIn, + PoolAllocation, + DelayExecution, + Suspended, + UserRequest, + WrExecutive, + WrFreePage, + WrPageIn, + WrPoolAllocation, + WrDelayExecution, + WrSuspended, + WrUserRequest, + WrEventPair, + WrQueue, + WrLpcReceive, + WrLpcReply, + WrVirtualMemory, + WrPageOut, + WrRendezvous, + Spare2, + Spare3, + Spare4, + Spare5, + Spare6, + WrKernel, + MaximumWaitReason +} KWAIT_REASON; + +typedef struct _KWAIT_BLOCK { + LIST_ENTRY WaitListEntry; + struct _KTHREAD * RESTRICTED_POINTER Thread; + PVOID Object; + struct _KWAIT_BLOCK * RESTRICTED_POINTER NextWaitBlock; + USHORT WaitKey; + USHORT WaitType; +} KWAIT_BLOCK, *PKWAIT_BLOCK, *RESTRICTED_POINTER PRKWAIT_BLOCK; + +typedef struct _IO_REMOVE_LOCK_TRACKING_BLOCK * PIO_REMOVE_LOCK_TRACKING_BLOCK; + +typedef struct _IO_REMOVE_LOCK_COMMON_BLOCK { + BOOLEAN Removed; + BOOLEAN Reserved[3]; + LONG IoCount; + KEVENT RemoveEvent; +} IO_REMOVE_LOCK_COMMON_BLOCK; + +typedef struct _IO_REMOVE_LOCK_DBG_BLOCK { + LONG Signature; + LONG HighWatermark; + LONGLONG MaxLockedTicks; + LONG AllocateTag; + LIST_ENTRY LockList; + KSPIN_LOCK Spin; + LONG LowMemoryCount; + ULONG Reserved1[4]; + PVOID Reserved2; + PIO_REMOVE_LOCK_TRACKING_BLOCK Blocks; +} IO_REMOVE_LOCK_DBG_BLOCK; + +typedef struct _IO_REMOVE_LOCK { + IO_REMOVE_LOCK_COMMON_BLOCK Common; +#if DBG + IO_REMOVE_LOCK_DBG_BLOCK Dbg; +#endif +} IO_REMOVE_LOCK, *PIO_REMOVE_LOCK; + +typedef struct _IO_WORKITEM *PIO_WORKITEM; + +typedef VOID DDKAPI +(*PIO_WORKITEM_ROUTINE)( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context); + +typedef struct _SHARE_ACCESS { + ULONG OpenCount; + ULONG Readers; + ULONG Writers; + ULONG Deleters; + ULONG SharedRead; + ULONG SharedWrite; + ULONG SharedDelete; +} SHARE_ACCESS, *PSHARE_ACCESS; + +typedef enum _KINTERRUPT_MODE { + LevelSensitive, + Latched +} KINTERRUPT_MODE; + +typedef VOID DDKAPI +(*PKINTERRUPT_ROUTINE)( + VOID); + +typedef enum _KPROFILE_SOURCE { + ProfileTime, + ProfileAlignmentFixup, + ProfileTotalIssues, + ProfilePipelineDry, + ProfileLoadInstructions, + ProfilePipelineFrozen, + ProfileBranchInstructions, + ProfileTotalNonissues, + ProfileDcacheMisses, + ProfileIcacheMisses, + ProfileCacheMisses, + ProfileBranchMispredictions, + ProfileStoreInstructions, + ProfileFpInstructions, + ProfileIntegerInstructions, + Profile2Issue, + Profile3Issue, + Profile4Issue, + ProfileSpecialInstructions, + ProfileTotalCycles, + ProfileIcacheIssues, + ProfileDcacheAccesses, + ProfileMemoryBarrierCycles, + ProfileLoadLinkedIssues, + ProfileMaximum +} KPROFILE_SOURCE; + +typedef enum _CREATE_FILE_TYPE { + CreateFileTypeNone, + CreateFileTypeNamedPipe, + CreateFileTypeMailslot +} CREATE_FILE_TYPE; + +typedef struct _CONFIGURATION_INFORMATION { + ULONG DiskCount; + ULONG FloppyCount; + ULONG CdRomCount; + ULONG TapeCount; + ULONG ScsiPortCount; + ULONG SerialCount; + ULONG ParallelCount; + BOOLEAN AtDiskPrimaryAddressClaimed; + BOOLEAN AtDiskSecondaryAddressClaimed; + ULONG Version; + ULONG MediumChangerCount; +} CONFIGURATION_INFORMATION, *PCONFIGURATION_INFORMATION; + +typedef enum _CONFIGURATION_TYPE { + ArcSystem, + CentralProcessor, + FloatingPointProcessor, + PrimaryIcache, + PrimaryDcache, + SecondaryIcache, + SecondaryDcache, + SecondaryCache, + EisaAdapter, + TcAdapter, + ScsiAdapter, + DtiAdapter, + MultiFunctionAdapter, + DiskController, + TapeController, + CdromController, + WormController, + SerialController, + NetworkController, + DisplayController, + ParallelController, + PointerController, + KeyboardController, + AudioController, + OtherController, + DiskPeripheral, + FloppyDiskPeripheral, + TapePeripheral, + ModemPeripheral, + MonitorPeripheral, + PrinterPeripheral, + PointerPeripheral, + KeyboardPeripheral, + TerminalPeripheral, + OtherPeripheral, + LinePeripheral, + NetworkPeripheral, + SystemMemory, + DockingInformation, + RealModeIrqRoutingTable, + MaximumType +} CONFIGURATION_TYPE, *PCONFIGURATION_TYPE; + +typedef NTSTATUS (*PIO_QUERY_DEVICE_ROUTINE)( + IN PVOID Context, + IN PUNICODE_STRING PathName, + IN INTERFACE_TYPE BusType, + IN ULONG BusNumber, + IN PKEY_VALUE_FULL_INFORMATION *BusInformation, + IN CONFIGURATION_TYPE ControllerType, + IN ULONG ControllerNumber, + IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation, + IN CONFIGURATION_TYPE PeripheralType, + IN ULONG PeripheralNumber, + IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation); + +typedef enum _WORK_QUEUE_TYPE { + CriticalWorkQueue, + DelayedWorkQueue, + HyperCriticalWorkQueue, + MaximumWorkQueue +} WORK_QUEUE_TYPE; + +typedef VOID DDKAPI +(*PWORKER_THREAD_ROUTINE)( + IN PVOID Parameter); + +typedef struct _WORK_QUEUE_ITEM { + LIST_ENTRY List; + PWORKER_THREAD_ROUTINE WorkerRoutine; + PVOID Parameter; +} WORK_QUEUE_ITEM, *PWORK_QUEUE_ITEM; + +typedef enum _KBUGCHECK_BUFFER_DUMP_STATE { + BufferEmpty, + BufferInserted, + BufferStarted, + BufferFinished, + BufferIncomplete +} KBUGCHECK_BUFFER_DUMP_STATE; + +typedef VOID DDKAPI +(*PKBUGCHECK_CALLBACK_ROUTINE)( + IN PVOID Buffer, + IN ULONG Length); + +typedef struct _KBUGCHECK_CALLBACK_RECORD { + LIST_ENTRY Entry; + PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine; + PVOID Buffer; + ULONG Length; + PUCHAR Component; + ULONG_PTR Checksum; + UCHAR State; +} KBUGCHECK_CALLBACK_RECORD, *PKBUGCHECK_CALLBACK_RECORD; + +/* + * VOID + * KeInitializeCallbackRecord( + * IN PKBUGCHECK_CALLBACK_RECORD CallbackRecord) + */ +#define KeInitializeCallbackRecord(CallbackRecord) \ + CallbackRecord->State = BufferEmpty; + +typedef enum _KDPC_IMPORTANCE { + LowImportance, + MediumImportance, + HighImportance +} KDPC_IMPORTANCE; + +typedef enum _MEMORY_CACHING_TYPE_ORIG { + MmFrameBufferCached = 2 +} MEMORY_CACHING_TYPE_ORIG; + +typedef enum _MEMORY_CACHING_TYPE { + MmNonCached = FALSE, + MmCached = TRUE, + MmWriteCombined = MmFrameBufferCached, + MmHardwareCoherentCached, + MmNonCachedUnordered, + MmUSWCCached, + MmMaximumCacheType +} MEMORY_CACHING_TYPE; + +typedef enum _MM_PAGE_PRIORITY { + LowPagePriority, + NormalPagePriority = 16, + HighPagePriority = 32 +} MM_PAGE_PRIORITY; + +typedef enum _LOCK_OPERATION { + IoReadAccess, + IoWriteAccess, + IoModifyAccess +} LOCK_OPERATION; + +typedef enum _MM_SYSTEM_SIZE { + MmSmallSystem, + MmMediumSystem, + MmLargeSystem +} MM_SYSTEM_SIZE; + +typedef struct _OBJECT_HANDLE_INFORMATION { + ULONG HandleAttributes; + ACCESS_MASK GrantedAccess; +} OBJECT_HANDLE_INFORMATION, *POBJECT_HANDLE_INFORMATION; + +typedef struct _CLIENT_ID { + HANDLE UniqueProcess; + HANDLE UniqueThread; +} CLIENT_ID, *PCLIENT_ID; + +typedef VOID DDKAPI +(*PKSTART_ROUTINE)( + IN PVOID StartContext); + +typedef VOID DDKAPI +(*PCREATE_PROCESS_NOTIFY_ROUTINE)( + IN HANDLE ParentId, + IN HANDLE ProcessId, + IN BOOLEAN Create); + +typedef VOID DDKAPI +(*PCREATE_THREAD_NOTIFY_ROUTINE)( + IN HANDLE ProcessId, + IN HANDLE ThreadId, + IN BOOLEAN Create); + +typedef struct _IMAGE_INFO { + union { + ULONG Properties; + struct { + ULONG ImageAddressingMode : 8; + ULONG SystemModeImage : 1; + ULONG ImageMappedToAllPids : 1; + ULONG Reserved : 22; + }; + }; + PVOID ImageBase; + ULONG ImageSelector; + SIZE_T ImageSize; + ULONG ImageSectionNumber; +} IMAGE_INFO, *PIMAGE_INFO; + +#define IMAGE_ADDRESSING_MODE_32BIT 3 + +typedef VOID DDKAPI +(*PLOAD_IMAGE_NOTIFY_ROUTINE)( + IN PUNICODE_STRING FullImageName, + IN HANDLE ProcessId, + IN PIMAGE_INFO ImageInfo); + +typedef enum _PROCESSINFOCLASS { + ProcessBasicInformation, + ProcessQuotaLimits, + ProcessIoCounters, + ProcessVmCounters, + ProcessTimes, + ProcessBasePriority, + ProcessRaisePriority, + ProcessDebugPort, + ProcessExceptionPort, + ProcessAccessToken, + ProcessLdtInformation, + ProcessLdtSize, + ProcessDefaultHardErrorMode, + ProcessIoPortHandlers, + ProcessPooledUsageAndLimits, + ProcessWorkingSetWatch, + ProcessUserModeIOPL, + ProcessEnableAlignmentFaultFixup, + ProcessPriorityClass, + ProcessWx86Information, + ProcessHandleCount, + ProcessAffinityMask, + ProcessPriorityBoost, + ProcessDeviceMap, + ProcessSessionInformation, + ProcessForegroundInformation, + ProcessWow64Information, + ProcessImageFileName, + ProcessLUIDDeviceMapsEnabled, + ProcessBreakOnTermination, + ProcessDebugObjectHandle, + ProcessDebugFlags, + ProcessHandleTracing, + MaxProcessInfoClass +} PROCESSINFOCLASS; + +typedef enum _THREADINFOCLASS { + ThreadBasicInformation, + ThreadTimes, + ThreadPriority, + ThreadBasePriority, + ThreadAffinityMask, + ThreadImpersonationToken, + ThreadDescriptorTableEntry, + ThreadEnableAlignmentFaultFixup, + ThreadEventPair_Reusable, + ThreadQuerySetWin32StartAddress, + ThreadZeroTlsCell, + ThreadPerformanceCount, + ThreadAmILastThread, + ThreadIdealProcessor, + ThreadPriorityBoost, + ThreadSetTlsArrayAddress, + ThreadIsIoPending, + ThreadHideFromDebugger, + ThreadBreakOnTermination, + MaxThreadInfoClass +} THREADINFOCLASS; + +#define ES_SYSTEM_REQUIRED 0x00000001 +#define ES_DISPLAY_REQUIRED 0x00000002 +#define ES_USER_PRESENT 0x00000004 +#define ES_CONTINUOUS 0x80000000 + +typedef ULONG EXECUTION_STATE; + +typedef VOID DDKAPI +(*PREQUEST_POWER_COMPLETE)( + IN PDEVICE_OBJECT DeviceObject, + IN UCHAR MinorFunction, + IN POWER_STATE PowerState, + IN PVOID Context, + IN PIO_STATUS_BLOCK IoStatus); + +typedef enum _TRACE_INFORMATION_CLASS { + TraceIdClass, + TraceHandleClass, + TraceEnableFlagsClass, + TraceEnableLevelClass, + GlobalLoggerHandleClass, + EventLoggerHandleClass, + AllLoggerHandlesClass, + TraceHandleByNameClass +} TRACE_INFORMATION_CLASS; + +typedef NTSTATUS DDKAPI +(*PEX_CALLBACK_FUNCTION)( + IN PVOID CallbackContext, + IN PVOID Argument1, + IN PVOID Argument2); + + + +/* +** Storage structures +*/ +typedef enum _PARTITION_STYLE { + PARTITION_STYLE_MBR, + PARTITION_STYLE_GPT +} PARTITION_STYLE; + +typedef struct _CREATE_DISK_MBR { + ULONG Signature; +} CREATE_DISK_MBR, *PCREATE_DISK_MBR; + +typedef struct _CREATE_DISK_GPT { + GUID DiskId; + ULONG MaxPartitionCount; +} CREATE_DISK_GPT, *PCREATE_DISK_GPT; + +typedef struct _CREATE_DISK { + PARTITION_STYLE PartitionStyle; + union { + CREATE_DISK_MBR Mbr; + CREATE_DISK_GPT Gpt; + }; +} CREATE_DISK, *PCREATE_DISK; + +typedef struct _DISK_SIGNATURE { + ULONG PartitionStyle; + union { + struct { + ULONG Signature; + ULONG CheckSum; + } Mbr; + struct { + GUID DiskId; + } Gpt; + }; +} DISK_SIGNATURE, *PDISK_SIGNATURE; + +typedef VOID DDKFASTAPI +(*PTIME_UPDATE_NOTIFY_ROUTINE)( + IN HANDLE ThreadId, + IN KPROCESSOR_MODE Mode); + +#define DBG_STATUS_CONTROL_C 1 +#define DBG_STATUS_SYSRQ 2 +#define DBG_STATUS_BUGCHECK_FIRST 3 +#define DBG_STATUS_BUGCHECK_SECOND 4 +#define DBG_STATUS_FATAL 5 +#define DBG_STATUS_DEBUG_CONTROL 6 +#define DBG_STATUS_WORKER 7 + +typedef struct _PHYSICAL_MEMORY_RANGE { + PHYSICAL_ADDRESS BaseAddress; + LARGE_INTEGER NumberOfBytes; +} PHYSICAL_MEMORY_RANGE, *PPHYSICAL_MEMORY_RANGE; + +typedef ULONG_PTR +(*PDRIVER_VERIFIER_THUNK_ROUTINE)( + IN PVOID Context); + +typedef struct _DRIVER_VERIFIER_THUNK_PAIRS { + PDRIVER_VERIFIER_THUNK_ROUTINE PristineRoutine; + PDRIVER_VERIFIER_THUNK_ROUTINE NewRoutine; +} DRIVER_VERIFIER_THUNK_PAIRS, *PDRIVER_VERIFIER_THUNK_PAIRS; + +#define DRIVER_VERIFIER_SPECIAL_POOLING 0x0001 +#define DRIVER_VERIFIER_FORCE_IRQL_CHECKING 0x0002 +#define DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES 0x0004 +#define DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS 0x0008 +#define DRIVER_VERIFIER_IO_CHECKING 0x0010 + +#define RTL_RANGE_LIST_ADD_IF_CONFLICT 0x00000001 +#define RTL_RANGE_LIST_ADD_SHARED 0x00000002 + +#define RTL_RANGE_LIST_SHARED_OK 0x00000001 +#define RTL_RANGE_LIST_NULL_CONFLICT_OK 0x00000002 + +#define RTL_RANGE_LIST_SHARED_OK 0x00000001 +#define RTL_RANGE_LIST_NULL_CONFLICT_OK 0x00000002 + +#define RTL_RANGE_LIST_MERGE_IF_CONFLICT RTL_RANGE_LIST_ADD_IF_CONFLICT + +typedef struct _RTL_RANGE { + ULONGLONG Start; + ULONGLONG End; + PVOID UserData; + PVOID Owner; + UCHAR Attributes; + UCHAR Flags; +} RTL_RANGE, *PRTL_RANGE; + +#define RTL_RANGE_SHARED 0x01 +#define RTL_RANGE_CONFLICT 0x02 + +typedef struct _RTL_RANGE_LIST { + LIST_ENTRY ListHead; + ULONG Flags; + ULONG Count; + ULONG Stamp; +} RTL_RANGE_LIST, *PRTL_RANGE_LIST; + +typedef struct _RANGE_LIST_ITERATOR { + PLIST_ENTRY RangeListHead; + PLIST_ENTRY MergedHead; + PVOID Current; + ULONG Stamp; +} RTL_RANGE_LIST_ITERATOR, *PRTL_RANGE_LIST_ITERATOR; + +typedef BOOLEAN +(*PRTL_CONFLICT_RANGE_CALLBACK)( + IN PVOID Context, + IN PRTL_RANGE Range); + +#define HASH_STRING_ALGORITHM_DEFAULT 0 +#define HASH_STRING_ALGORITHM_X65599 1 +#define HASH_STRING_ALGORITHM_INVALID 0xffffffff + +typedef enum _SUITE_TYPE { + SmallBusiness, + Enterprise, + BackOffice, + CommunicationServer, + TerminalServer, + SmallBusinessRestricted, + EmbeddedNT, + DataCenter, + SingleUserTS, + Personal, + Blade, + MaxSuiteType +} SUITE_TYPE; + +typedef VOID DDKAPI +(*PTIMER_APC_ROUTINE)( + IN PVOID TimerContext, + IN ULONG TimerLowValue, + IN LONG TimerHighValue); + + + +/* +** WMI structures +*/ + +typedef VOID DDKAPI +(*WMI_NOTIFICATION_CALLBACK)( + PVOID Wnode, + PVOID Context); + + +/* +** Architecture specific structures +*/ + +#ifdef _X86_ + +typedef ULONG PFN_NUMBER, *PPFN_NUMBER; + +#define PASSIVE_LEVEL 0 +#define LOW_LEVEL 0 +#define APC_LEVEL 1 +#define DISPATCH_LEVEL 2 +#define PROFILE_LEVEL 27 +#define CLOCK1_LEVEL 28 +#define CLOCK2_LEVEL 28 +#define IPI_LEVEL 29 +#define POWER_LEVEL 30 +#define HIGH_LEVEL 31 + +typedef struct _KPCR_TIB { + PVOID ExceptionList; /* 00 */ + PVOID StackBase; /* 04 */ + PVOID StackLimit; /* 08 */ + PVOID SubSystemTib; /* 0C */ + union { + PVOID FiberData; /* 10 */ + DWORD Version; /* 10 */ + }; + PVOID ArbitraryUserPointer; /* 14 */ +} KPCR_TIB, *PKPCR_TIB; /* 18 */ + +#define PCR_MINOR_VERSION 1 +#define PCR_MAJOR_VERSION 1 + +typedef struct _KPCR { + KPCR_TIB Tib; /* 00 */ + struct _KPCR *Self; /* 18 */ + struct _KPRCB *PCRCB; /* 1C */ + KIRQL Irql; /* 20 */ + ULONG IRR; /* 24 */ + ULONG IrrActive; /* 28 */ + ULONG IDR; /* 2C */ + PVOID KdVersionBlock; /* 30 */ PUSHORT IDT; /* 34 */ + PUSHORT GDT; /* 38 */ + struct _KTSS *TSS; /* 3C */ + USHORT MajorVersion; /* 40 */ + USHORT MinorVersion; /* 42 */ + KAFFINITY SetMember; /* 44 */ + ULONG StallScaleFactor; /* 48 */ + UCHAR DebugActive; /* 4C */ + UCHAR ProcessorNumber; /* 4D */ + UCHAR Reserved[2]; /* 4E */ +} KPCR, *PKPCR; /* 50 */ + +typedef struct _KFLOATING_SAVE { + ULONG ControlWord; + ULONG StatusWord; + ULONG ErrorOffset; + ULONG ErrorSelector; + ULONG DataOffset; + ULONG DataSelector; + ULONG Cr0NpxState; + ULONG Spare1; +} KFLOATING_SAVE, *PKFLOATING_SAVE; + +#define PAGE_SIZE 0x1000 +#define PAGE_SHIFT 12L + +extern NTOSAPI PVOID *MmHighestUserAddress; +extern NTOSAPI PVOID *MmSystemRangeStart; +extern NTOSAPI ULONG *MmUserProbeAddress; + +#define MM_HIGHEST_USER_ADDRESS *MmHighestUserAddress +#define MM_SYSTEM_RANGE_START *MmSystemRangeStart +#define MM_USER_PROBE_ADDRESS *MmUserProbeAddress +#define MM_LOWEST_USER_ADDRESS (PVOID)0x10000 +#define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0C00000 + +#define KI_USER_SHARED_DATA 0xffdf0000 +#define SharedUserData ((KUSER_SHARED_DATA * CONST) KI_USER_SHARED_DATA) + +#define EFLAG_SIGN 0x8000 +#define EFLAG_ZERO 0x4000 +#define EFLAG_SELECT (EFLAG_SIGN | EFLAG_ZERO) + +#define RESULT_NEGATIVE ((EFLAG_SIGN & ~EFLAG_ZERO) & EFLAG_SELECT) +#define RESULT_ZERO ((~EFLAG_SIGN & EFLAG_ZERO) & EFLAG_SELECT) +#define RESULT_POSITIVE ((~EFLAG_SIGN & ~EFLAG_ZERO) & EFLAG_SELECT) + +typedef enum _INTERLOCKED_RESULT { + ResultNegative = RESULT_NEGATIVE, + ResultZero = RESULT_ZERO, + ResultPositive = RESULT_POSITIVE +} INTERLOCKED_RESULT; + +NTOSAPI +KIRQL +DDKAPI +KeGetCurrentIrql( + VOID); + +/* + * ULONG + * KeGetCurrentProcessorNumber( + * VOID) + */ +#define KeGetCurrentProcessorNumber() \ + ((ULONG)KeGetCurrentKPCR()->ProcessorNumber) + +#if !defined(__INTERLOCKED_DECLARED) +#define __INTERLOCKED_DECLARED + +NTOSAPI +LONG +DDKFASTAPI +InterlockedIncrement( + IN PLONG VOLATILE Addend); + +NTOSAPI +LONG +DDKFASTAPI +InterlockedDecrement( + IN PLONG VOLATILE Addend); + +NTOSAPI +LONG +DDKFASTAPI +InterlockedCompareExchange( + IN OUT PLONG VOLATILE Destination, + IN LONG Exchange, + IN LONG Comparand); + +NTOSAPI +LONG +DDKFASTAPI +InterlockedExchange( + IN OUT PLONG VOLATILE Target, + IN LONG Value); + +NTOSAPI +LONG +DDKFASTAPI +InterlockedExchangeAdd( + IN OUT PLONG VOLATILE Addend, + IN LONG Value); + +/* + * PVOID + * InterlockedExchangePointer( + * IN OUT PVOID VOLATILE *Target, + * IN PVOID Value) + */ +#define InterlockedExchangePointer(Target, Value) \ + (PVOID) InterlockedExchange((PLONG) Target, (LONG) Value); + +/* + * PVOID + * InterlockedCompareExchangePointer( + * IN OUT PVOID *Destination, + * IN PVOID Exchange, + * IN PVOID Comparand) + */ +#define InterlockedCompareExchangePointer(Destination, Exchange, Comparand) \ + (PVOID) InterlockedCompareExchange((PLONG) Destination, (LONG) Exchange, (LONG) Comparand); + +#endif /* !__INTERLOCKED_DECLARED */ + +NTOSAPI +VOID +DDKFASTAPI +KefAcquireSpinLockAtDpcLevel( + IN PKSPIN_LOCK SpinLock); + +NTOSAPI +VOID +DDKFASTAPI +KefReleaseSpinLockFromDpcLevel( + IN PKSPIN_LOCK SpinLock); + +#define KeAcquireSpinLockAtDpcLevel(SpinLock) KefAcquireSpinLockAtDpcLevel(SpinLock) +#define KeReleaseSpinLockFromDpcLevel(SpinLock) KefReleaseSpinLockFromDpcLevel(SpinLock) + +#define RtlCopyMemoryNonTemporal RtlCopyMemory + +#define KeGetDcacheFillSize() 1L + +#endif /* _X86_ */ + + + +/* +** Utillity functions +*/ + +#define ARGUMENT_PRESENT(ArgumentPointer) \ + (BOOLEAN) ((PVOID)ArgumentPointer != (PVOID)NULL); + +/* + * ULONG + * BYTE_OFFSET( + * IN PVOID Va) + */ +#define BYTE_OFFSET(Va) \ + (ULONG) ((ULONG_PTR) (Va) & (PAGE_SIZE - 1)); + +/* + * ULONG + * BYTES_TO_PAGES( + * IN ULONG Size) + */ +#define BYTES_TO_PAGES(Size) \ + (ULONG) ((ULONG_PTR) (Size) >> PAGE_SHIFT) + (((ULONG) (Size) & (PAGE_SIZE - 1)) != 0); + +/* + * PCHAR + * CONTAINING_RECORD( + * IN PCHAR Address, + * IN TYPE Type, + * IN PCHAR Field); + */ +#ifndef CONTAINING_RECORD +#define CONTAINING_RECORD(Address, Type, Field) \ + ((Type *) (((ULONG_PTR) Address) - FIELD_OFFSET(Type, Field))) +#endif + +/* LONG + * FIELD_OFFSET( + * IN TYPE Type, + * IN PCHAR Field); + */ +#ifndef FIELD_OFFSET +#define FIELD_OFFSET(Type, Field) \ + ((LONG) (&(((Type *) 0)->Field))) +#endif + +/* + * PVOID + * PAGE_ALIGN( + * IN PVOID Va) + */ +#define PAGE_ALIGN(Va) \ + (PVOID) ((ULONG_PTR)(Va) & ~(PAGE_SIZE - 1)); + +/* + * ULONG_PTR + * ROUND_TO_PAGES( + * IN ULONG_PTR Size) + */ +#define ROUND_TO_PAGES(Size) \ + (ULONG_PTR) (((ULONG_PTR) Size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)); + +NTOSAPI +VOID +DDKAPI +RtlAssert( + IN PVOID FailedAssertion, + IN PVOID FileName, + IN ULONG LineNumber, + IN PCHAR Message); + +#if DBG + +#define ASSERT(exp) \ + ((!(exp)) ? \ + (RtlAssert( #exp, __FILE__, __LINE__, NULL ), FALSE) : TRUE) + +#define ASSERTMSG(msg, exp) \ + ((!(exp)) ? \ + (RtlAssert( #exp, __FILE__, __LINE__, msg ), FALSE) : TRUE) + +#define RTL_SOFT_ASSERT(exp) \ + ((!(_exp)) ? \ + (DbgPrint("%s(%d): Soft assertion failed\n Expression: %s\n", __FILE__, __LINE__, #exp), FALSE) : TRUE) + +#define RTL_SOFT_ASSERTMSG(msg, exp) \ + ((!(exp)) ? \ + (DbgPrint("%s(%d): Soft assertion failed\n Expression: %s\n Message: %s\n", __FILE__, __LINE__, #exp, (msg)), FALSE) : TRUE) + +#define RTL_VERIFY(exp) ASSERT(exp) +#define RTL_VERIFYMSG(msg, exp) ASSERT(msg, exp) + +#define RTL_SOFT_VERIFY(exp) RTL_SOFT_ASSERT(exp) +#define RTL_SOFT_VERIFYMSG(msg, exp) RTL_SOFT_ASSERTMSG(msg, exp) + +#else /* !DBG */ + +#define ASSERT(exp) ((VOID) 0) +#define ASSERTMSG(msg, exp) ((VOID) 0) + +#define RTL_SOFT_ASSERT(exp) ((VOID) 0) +#define RTL_SOFT_ASSERTMSG(msg, exp) ((VOID) 0) + +#define RTL_VERIFY(exp) ((exp) ? TRUE : FALSE) +#define RTL_VERIFYMSG(msg, exp) ((exp) ? TRUE : FALSE) + +#define RTL_SOFT_VERIFY(exp) ((exp) ? TRUE : FALSE) +#define RTL_SOFT_VERIFYMSG(msg, exp) ((exp) ? TRUE : FALSE) + +#endif /* DBG */ + +#define assert ASSERT + + +/* +** Driver support routines +*/ + +/** Runtime library routines **/ + +/* + * VOID + * InitializeListHead( + * IN PLIST_ENTRY ListHead) + */ +#define InitializeListHead(_ListHead) \ +{ \ + (_ListHead)->Flink = (_ListHead); \ + (_ListHead)->Blink = (_ListHead); \ +} + +/* + * VOID + * InsertHeadList( + * IN PLIST_ENTRY ListHead, + * IN PLIST_ENTRY Entry) + */ +#define InsertHeadList(_ListHead, \ + _Entry) \ +{ \ + PLIST_ENTRY _OldFlink; \ + _OldFlink = (_ListHead)->Flink; \ + (_Entry)->Flink = _OldFlink; \ + (_Entry)->Blink = (_ListHead); \ + _OldFlink->Blink = (_Entry); \ + (_ListHead)->Flink = (_Entry); \ +} + +/* + * VOID + * InsertTailList( + * IN PLIST_ENTRY ListHead, + * IN PLIST_ENTRY Entry) + */ +#define InsertTailList(_ListHead, \ + _Entry) \ +{ \ + PLIST_ENTRY _OldBlink; \ + _OldBlink = (_ListHead)->Blink; \ + (_Entry)->Flink = (_ListHead); \ + (_Entry)->Blink = _OldBlink; \ + _OldBlink->Flink = (_Entry); \ + (_ListHead)->Blink = (_Entry); \ +} + +/* + * BOOLEAN + * IsListEmpty( + * IN PLIST_ENTRY ListHead) + */ +#define IsListEmpty(_ListHead) \ + ((_ListHead)->Flink == (_ListHead)) + +static inline PSINGLE_LIST_ENTRY +PopEntryList( + IN PSINGLE_LIST_ENTRY ListHead) +{ + PSINGLE_LIST_ENTRY Entry; + + Entry = ListHead->Next; + if (Entry != NULL) + { + ListHead->Next = Entry->Next; + } + return Entry; +} + +/* + * VOID + * PushEntryList( + * IN PSINGLE_LIST_ENTRY ListHead, + * IN PSINGLE_LIST_ENTRY Entry) + */ +#define PushEntryList(_ListHead, \ + _Entry) \ +{ \ + (_Entry)->Next = (_ListHead)->Next; \ + (_ListHead)->Next = (_Entry); \ +} + +/* + * VOID + * RemoveEntryList( + * IN PLIST_ENTRY Entry) + */ +#define RemoveEntryList(_Entry) \ +{ \ + PLIST_ENTRY _OldFlink; \ + PLIST_ENTRY _OldBlink; \ + _OldFlink = (_Entry)->Flink; \ + _OldBlink = (_Entry)->Blink; \ + _OldFlink->Blink = _OldBlink; \ + _OldBlink->Flink = _OldFlink; \ + (_Entry)->Flink = NULL; \ + (_Entry)->Blink = NULL; \ +} + +static inline PLIST_ENTRY +RemoveHeadList( + IN PLIST_ENTRY ListHead) +{ + PLIST_ENTRY OldFlink; + PLIST_ENTRY OldBlink; + PLIST_ENTRY Entry; + + Entry = ListHead->Flink; + OldFlink = ListHead->Flink->Flink; + OldBlink = ListHead->Flink->Blink; + OldFlink->Blink = OldBlink; + OldBlink->Flink = OldFlink; + + if (Entry != ListHead) + { + Entry->Flink = NULL; + Entry->Blink = NULL; + } + + return Entry; +} + +static inline PLIST_ENTRY +RemoveTailList( + IN PLIST_ENTRY ListHead) +{ + PLIST_ENTRY OldFlink; + PLIST_ENTRY OldBlink; + PLIST_ENTRY Entry; + + Entry = ListHead->Blink; + OldFlink = ListHead->Blink->Flink; + OldBlink = ListHead->Blink->Blink; + OldFlink->Blink = OldBlink; + OldBlink->Flink = OldFlink; + + if (Entry != ListHead) + { + Entry->Flink = NULL; + Entry->Blink = NULL; + } + + return Entry; +} + +NTOSAPI +PSLIST_ENTRY +DDKFASTAPI +InterlockedPopEntrySList( + IN PSLIST_HEADER ListHead); + +NTOSAPI +PSLIST_ENTRY +DDKFASTAPI +InterlockedPushEntrySList( + IN PSLIST_HEADER ListHead, + IN PSLIST_ENTRY ListEntry); + +/* + * USHORT + * QueryDepthSList( + * IN PSLIST_HEADER SListHead) + */ +#define QueryDepthSList(_SListHead) \ + ((USHORT) ((_SListHead)->Alignment & 0xffff)) + +#define InterlockedFlushSList(ListHead) ExInterlockedFlushSList(ListHead) + +NTOSAPI +ULONG +DDKAPI +RtlAnsiStringToUnicodeSize( + IN PANSI_STRING AnsiString); + +NTOSAPI +NTSTATUS +DDKAPI +RtlAddRange( + IN OUT PRTL_RANGE_LIST RangeList, + IN ULONGLONG Start, + IN ULONGLONG End, + IN UCHAR Attributes, + IN ULONG Flags, + IN PVOID UserData OPTIONAL, + IN PVOID Owner OPTIONAL); + +NTOSAPI +NTSTATUS +DDKAPI +RtlAnsiStringToUnicodeString( + IN OUT PUNICODE_STRING DestinationString, + IN PANSI_STRING SourceString, + IN BOOLEAN AllocateDestinationString); + +NTOSAPI +NTSTATUS +DDKAPI +RtlAppendUnicodeStringToString( + IN OUT PUNICODE_STRING Destination, + IN PUNICODE_STRING Source); + +NTOSAPI +NTSTATUS +DDKAPI +RtlAppendUnicodeToString( + IN OUT PUNICODE_STRING Destination, + IN PCWSTR Source); + +NTOSAPI +BOOLEAN +DDKAPI +RtlAreBitsClear( + IN PRTL_BITMAP BitMapHeader, + IN ULONG StartingIndex, + IN ULONG Length); + +NTOSAPI +BOOLEAN +DDKAPI +RtlAreBitsSet( + IN PRTL_BITMAP BitMapHeader, + IN ULONG StartingIndex, + IN ULONG Length); + +NTOSAPI +NTSTATUS +DDKAPI +RtlCharToInteger( + IN PCSZ String, + IN ULONG Base OPTIONAL, + IN OUT PULONG Value); + +NTOSAPI +ULONG +DDKAPI +RtlCheckBit( + IN PRTL_BITMAP BitMapHeader, + IN ULONG BitPosition); + +NTOSAPI +NTSTATUS +DDKAPI +RtlCheckRegistryKey( + IN ULONG RelativeTo, + IN PWSTR Path); + +NTOSAPI +VOID +DDKAPI +RtlClearAllBits( + IN PRTL_BITMAP BitMapHeader); + +NTOSAPI +VOID +DDKAPI +RtlClearBit( + PRTL_BITMAP BitMapHeader, + ULONG BitNumber); + +NTOSAPI +VOID +DDKAPI +RtlClearBits( + IN PRTL_BITMAP BitMapHeader, + IN ULONG StartingIndex, + IN ULONG NumberToClear); + +NTOSAPI +SIZE_T +DDKAPI +RtlCompareMemory( + IN CONST VOID *Source1, + IN CONST VOID *Source2, + IN SIZE_T Length); + +NTOSAPI +LONG +DDKAPI +RtlCompareString( + IN PSTRING String1, + IN PSTRING String2, + BOOLEAN CaseInSensitive); + +NTOSAPI +LONG +DDKAPI +RtlCompareUnicodeString( + IN PUNICODE_STRING String1, + IN PUNICODE_STRING String2, + IN BOOLEAN CaseInSensitive); + +NTOSAPI +LARGE_INTEGER +DDKAPI +RtlConvertLongToLargeInteger( + IN LONG SignedInteger); + +NTOSAPI +LUID +DDKAPI +RtlConvertLongToLuid( + IN LONG Long); + +NTOSAPI +LARGE_INTEGER +DDKAPI +RtlConvertUlongToLargeInteger( + IN ULONG UnsignedInteger); + +NTOSAPI +LUID +DDKAPI +RtlConvertUlongToLuid( + ULONG Ulong); + +/* + * VOID + * RtlCopyMemory( + * IN VOID UNALIGNED *Destination, + * IN CONST VOID UNALIGNED *Source, + * IN SIZE_T Length) + */ +#ifndef RtlCopyMemory +#define RtlCopyMemory(Destination, Source, Length) \ + memcpy(Destination, Source, Length); +#endif + +#ifndef RtlCopyBytes +#define RtlCopyBytes RtlCopyMemory +#endif + +NTOSAPI +VOID +DDKAPI +RtlCopyMemory32( + IN VOID UNALIGNED *Destination, + IN CONST VOID UNALIGNED *Source, + IN ULONG Length); + +NTOSAPI +NTSTATUS +DDKAPI +RtlCopyRangeList( + OUT PRTL_RANGE_LIST CopyRangeList, + IN PRTL_RANGE_LIST RangeList); + +NTOSAPI +VOID +DDKAPI +RtlCopyString( + IN OUT PSTRING DestinationString, + IN PSTRING SourceString OPTIONAL); + +NTOSAPI +VOID +DDKAPI +RtlCopyUnicodeString( + IN OUT PUNICODE_STRING DestinationString, + IN PUNICODE_STRING SourceString); + +NTOSAPI +NTSTATUS +DDKAPI +RtlCreateRegistryKey( + IN ULONG RelativeTo, + IN PWSTR Path); + +NTOSAPI +NTSTATUS +DDKAPI +RtlCreateSecurityDescriptor( + IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, + IN ULONG Revision); + +NTOSAPI +NTSTATUS +DDKAPI +RtlDeleteOwnersRanges( + IN OUT PRTL_RANGE_LIST RangeList, + IN PVOID Owner); + +NTOSAPI +NTSTATUS +DDKAPI +RtlDeleteRange( + IN OUT PRTL_RANGE_LIST RangeList, + IN ULONGLONG Start, + IN ULONGLONG End, + IN PVOID Owner); + +NTOSAPI +NTSTATUS +DDKAPI +RtlDeleteRegistryValue( + IN ULONG RelativeTo, + IN PCWSTR Path, + IN PCWSTR ValueName); + +/* + * BOOLEAN + * RtlEqualLuid( + * IN LUID Luid1, + * IN LUID Luid2) + */ +#define RtlEqualLuid(_Luid1, \ + _Luid2) \ + ((Luid1.LowPart == Luid2.LowPart) && (Luid1.HighPart == Luid2.HighPart)) + +/* + * ULONG + * RtlEqualMemory( + * IN VOID UNALIGNED *Destination, + * IN CONST VOID UNALIGNED *Source, + * IN SIZE_T Length) + */ +#define RtlEqualMemory(Destination, Source, Length) (!memcmp(Destination, Source, Length)) + +NTOSAPI +BOOLEAN +DDKAPI +RtlEqualString( + IN PSTRING String1, + IN PSTRING String2, + IN BOOLEAN CaseInSensitive); + +NTOSAPI +BOOLEAN +DDKAPI +RtlEqualUnicodeString( + IN CONST UNICODE_STRING *String1, + IN CONST UNICODE_STRING *String2, + IN BOOLEAN CaseInSensitive); + +/* + * VOID + * RtlFillMemory( + * IN VOID UNALIGNED *Destination, + * IN SIZE_T Length, + * IN UCHAR Fill) + */ +#ifndef RtlFillMemory +#define RtlFillMemory(Destination, Length, Fill) \ + memset(Destination, Fill, Length); +#endif + +#ifndef RtlFillBytes +#define RtlFillBytes RtlFillMemory +#endif + +NTOSAPI +ULONG +DDKAPI +RtlFindClearBits( + IN PRTL_BITMAP BitMapHeader, + IN ULONG NumberToFind, + IN ULONG HintIndex); + +NTOSAPI +ULONG +DDKAPI +RtlFindClearBitsAndSet( + IN PRTL_BITMAP BitMapHeader, + IN ULONG NumberToFind, + IN ULONG HintIndex); + +NTOSAPI +ULONG +DDKAPI +RtlFindClearRuns( + IN PRTL_BITMAP BitMapHeader, + OUT PRTL_BITMAP_RUN RunArray, + IN ULONG SizeOfRunArray, + IN BOOLEAN LocateLongestRuns); + +NTOSAPI +ULONG +DDKAPI +RtlFindFirstRunClear( + IN PRTL_BITMAP BitMapHeader, + OUT PULONG StartingIndex); + +NTOSAPI +ULONG +DDKAPI +RtlFindLastBackwardRunClear( + IN PRTL_BITMAP BitMapHeader, + IN ULONG FromIndex, + OUT PULONG StartingRunIndex); + +NTOSAPI +CCHAR +DDKAPI +RtlFindLeastSignificantBit( + IN ULONGLONG Set); + +NTOSAPI +ULONG +DDKAPI +RtlFindLongestRunClear( + IN PRTL_BITMAP BitMapHeader, + OUT PULONG StartingIndex); + +NTOSAPI +CCHAR +DDKAPI +RtlFindMostSignificantBit( + IN ULONGLONG Set); + +NTOSAPI +ULONG +DDKAPI +RtlFindNextForwardRunClear( + IN PRTL_BITMAP BitMapHeader, + IN ULONG FromIndex, + OUT PULONG StartingRunIndex); + +NTOSAPI +NTSTATUS +DDKAPI +RtlFindRange( + IN PRTL_RANGE_LIST RangeList, + IN ULONGLONG Minimum, + IN ULONGLONG Maximum, + IN ULONG Length, + IN ULONG Alignment, + IN ULONG Flags, + IN UCHAR AttributeAvailableMask, + IN PVOID Context OPTIONAL, + IN PRTL_CONFLICT_RANGE_CALLBACK Callback OPTIONAL, + OUT PULONGLONG Start); + +NTOSAPI +ULONG +DDKAPI +RtlFindSetBits( + IN PRTL_BITMAP BitMapHeader, + IN ULONG NumberToFind, + IN ULONG HintIndex); + +NTOSAPI +ULONG +DDKAPI +RtlFindSetBitsAndClear( + IN PRTL_BITMAP BitMapHeader, + IN ULONG NumberToFind, + IN ULONG HintIndex); + +NTOSAPI +VOID +DDKAPI +RtlFreeAnsiString( + IN PANSI_STRING AnsiString); + +NTOSAPI +VOID +DDKAPI +RtlFreeRangeList( + IN PRTL_RANGE_LIST RangeList); + +NTOSAPI +VOID +DDKAPI +RtlFreeUnicodeString( + IN PUNICODE_STRING UnicodeString); + +NTOSAPI +VOID +DDKAPI +RtlGetCallersAddress( + OUT PVOID *CallersAddress, + OUT PVOID *CallersCaller); + +NTOSAPI +NTSTATUS +DDKAPI +RtlGetVersion( + IN OUT PRTL_OSVERSIONINFOW lpVersionInformation); + +NTOSAPI +NTSTATUS +DDKAPI +RtlGetFirstRange( + IN PRTL_RANGE_LIST RangeList, + OUT PRTL_RANGE_LIST_ITERATOR Iterator, + OUT PRTL_RANGE *Range); + +NTOSAPI +NTSTATUS +DDKAPI +RtlGetNextRange( + IN OUT PRTL_RANGE_LIST_ITERATOR Iterator, + OUT PRTL_RANGE *Range, + IN BOOLEAN MoveForwards); + +#define FOR_ALL_RANGES(RangeList, Iterator, Current) \ + for (RtlGetFirstRange((RangeList), (Iterator), &(Current)); \ + (Current) != NULL; \ + RtlGetNextRange((Iterator), &(Current), TRUE)) + +#define FOR_ALL_RANGES_BACKWARDS(RangeList, Iterator, Current) \ + for (RtlGetLastRange((RangeList), (Iterator), &(Current)); \ + (Current) != NULL; \ + RtlGetNextRange((Iterator), &(Current), FALSE)) + +NTOSAPI +NTSTATUS +DDKAPI +RtlGUIDFromString( + IN PUNICODE_STRING GuidString, + OUT GUID *Guid); + +NTOSAPI +NTSTATUS +DDKAPI +RtlHashUnicodeString( + IN CONST UNICODE_STRING *String, + IN BOOLEAN CaseInSensitive, + IN ULONG HashAlgorithm, + OUT PULONG HashValue); + +NTOSAPI +VOID +DDKAPI +RtlInitAnsiString( + IN OUT PANSI_STRING DestinationString, + IN PCSZ SourceString); + +NTOSAPI +VOID +DDKAPI +RtlInitializeBitMap( + IN PRTL_BITMAP BitMapHeader, + IN PULONG BitMapBuffer, + IN ULONG SizeOfBitMap); + +NTOSAPI +VOID +DDKAPI +RtlInitializeRangeList( + IN OUT PRTL_RANGE_LIST RangeList); + +NTOSAPI +VOID +DDKAPI +RtlInitString( + IN OUT PSTRING DestinationString, + IN PCSZ SourceString); + +NTOSAPI +VOID +DDKAPI +RtlInitUnicodeString( + IN OUT PUNICODE_STRING DestinationString, + IN PCWSTR SourceString); + +NTOSAPI +NTSTATUS +DDKAPI +RtlInt64ToUnicodeString( + IN ULONGLONG Value, + IN ULONG Base OPTIONAL, + IN OUT PUNICODE_STRING String); + +NTOSAPI +NTSTATUS +DDKAPI +RtlIntegerToUnicodeString( + IN ULONG Value, + IN ULONG Base OPTIONAL, + IN OUT PUNICODE_STRING String); + +NTOSAPI +NTSTATUS +DDKAPI +RtlIntPtrToUnicodeString( + PLONG Value, + ULONG Base OPTIONAL, + PUNICODE_STRING String); + +NTOSAPI +NTSTATUS +DDKAPI +RtlInvertRangeList( + OUT PRTL_RANGE_LIST InvertedRangeList, + IN PRTL_RANGE_LIST RangeList); + +NTOSAPI +NTSTATUS +DDKAPI +RtlIsRangeAvailable( + IN PRTL_RANGE_LIST RangeList, + IN ULONGLONG Start, + IN ULONGLONG End, + IN ULONG Flags, + IN UCHAR AttributeAvailableMask, + IN PVOID Context OPTIONAL, + IN PRTL_CONFLICT_RANGE_CALLBACK Callback OPTIONAL, + OUT PBOOLEAN Available); + +/* + * BOOLEAN + * RtlIsZeroLuid( + * IN PLUID L1) + */ +#define RtlIsZeroLuid(_L1) \ + ((BOOLEAN) ((!(_L1)->LowPart) && (!(_L1)->HighPart))) + +NTOSAPI +ULONG +DDKAPI +RtlLengthSecurityDescriptor( + IN PSECURITY_DESCRIPTOR SecurityDescriptor); + +NTOSAPI +VOID +DDKAPI +RtlMapGenericMask( + IN OUT PACCESS_MASK AccessMask, + IN PGENERIC_MAPPING GenericMapping); + +NTOSAPI +NTSTATUS +DDKAPI +RtlMergeRangeLists( + OUT PRTL_RANGE_LIST MergedRangeList, + IN PRTL_RANGE_LIST RangeList1, + IN PRTL_RANGE_LIST RangeList2, + IN ULONG Flags); + +/* + * VOID + * RtlMoveMemory( + * IN VOID UNALIGNED *Destination, + * IN CONST VOID UNALIGNED *Source, + * IN SIZE_T Length) + */ +#define RtlMoveMemory memmove + +NTOSAPI +ULONG +DDKAPI +RtlNumberOfClearBits( + IN PRTL_BITMAP BitMapHeader); + +NTOSAPI +ULONG +DDKAPI +RtlNumberOfSetBits( + IN PRTL_BITMAP BitMapHeader); + +NTOSAPI +VOID +DDKFASTAPI +RtlPrefetchMemoryNonTemporal( + IN PVOID Source, + IN SIZE_T Length); + +NTOSAPI +BOOLEAN +DDKAPI +RtlPrefixUnicodeString( + IN PUNICODE_STRING String1, + IN PUNICODE_STRING String2, + IN BOOLEAN CaseInSensitive); + +NTOSAPI +NTSTATUS +DDKAPI +RtlQueryRegistryValues( + IN ULONG RelativeTo, + IN PCWSTR Path, + IN PRTL_QUERY_REGISTRY_TABLE QueryTable, + IN PVOID Context, + IN PVOID Environment OPTIONAL); + +NTOSAPI +VOID +DDKAPI +RtlRetrieveUlong( + IN OUT PULONG DestinationAddress, + IN PULONG SourceAddress); + +NTOSAPI +VOID +DDKAPI +RtlRetrieveUshort( + IN OUT PUSHORT DestinationAddress, + IN PUSHORT SourceAddress); + +NTOSAPI +VOID +DDKAPI +RtlSetAllBits( + IN PRTL_BITMAP BitMapHeader); + +NTOSAPI +VOID +DDKAPI +RtlSetBit( + PRTL_BITMAP BitMapHeader, + ULONG BitNumber); + +NTOSAPI +VOID +DDKAPI +RtlSetBits( + IN PRTL_BITMAP BitMapHeader, + IN ULONG StartingIndex, + IN ULONG NumberToSet); + +NTOSAPI +NTSTATUS +DDKAPI +RtlSetDaclSecurityDescriptor( + IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, + IN BOOLEAN DaclPresent, + IN PACL Dacl OPTIONAL, + IN BOOLEAN DaclDefaulted OPTIONAL); + +NTOSAPI +VOID +DDKAPI +RtlStoreUlong( + IN PULONG Address, + IN ULONG Value); + +NTOSAPI +VOID +DDKAPI +RtlStoreUlonglong( + IN OUT PULONGLONG Address, + ULONGLONG Value); + +NTOSAPI +VOID +DDKAPI +RtlStoreUlongPtr( + IN OUT PULONG_PTR Address, + IN ULONG_PTR Value); + +NTOSAPI +VOID +DDKAPI +RtlStoreUshort( + IN PUSHORT Address, + IN USHORT Value); + +NTOSAPI +NTSTATUS +DDKAPI +RtlStringFromGUID( + IN REFGUID Guid, + OUT PUNICODE_STRING GuidString); + +NTOSAPI +BOOLEAN +DDKAPI +RtlTestBit( + IN PRTL_BITMAP BitMapHeader, + IN ULONG BitNumber); + +NTOSAPI +BOOLEAN +DDKAPI +RtlTimeFieldsToTime( + IN PTIME_FIELDS TimeFields, + IN PLARGE_INTEGER Time); + +NTOSAPI +VOID +DDKAPI +RtlTimeToTimeFields( + IN PLARGE_INTEGER Time, + IN PTIME_FIELDS TimeFields); + +NTOSAPI +ULONG +DDKFASTAPI +RtlUlongByteSwap( + IN ULONG Source); + +NTOSAPI +ULONGLONG +DDKFASTAPI +RtlUlonglongByteSwap( + IN ULONGLONG Source); + +NTOSAPI +ULONG +DDKAPI +RtlUnicodeStringToAnsiSize( + IN PUNICODE_STRING UnicodeString); + +NTOSAPI +NTSTATUS +DDKAPI +RtlUnicodeStringToAnsiString( + IN OUT PANSI_STRING DestinationString, + IN PUNICODE_STRING SourceString, + IN BOOLEAN AllocateDestinationString); + +NTOSAPI +NTSTATUS +DDKAPI +RtlUnicodeStringToInteger( + IN PUNICODE_STRING String, + IN ULONG Base OPTIONAL, + OUT PULONG Value); + +NTOSAPI +WCHAR +DDKAPI +RtlUpcaseUnicodeChar( + IN WCHAR SourceCharacter); + +NTOSAPI +NTSTATUS +DDKAPI +RtlUpcaseUnicodeString( + IN OUT PUNICODE_STRING DestinationString OPTIONAL, + IN PCUNICODE_STRING SourceString, + IN BOOLEAN AllocateDestinationString); + +NTOSAPI +CHAR +DDKAPI +RtlUpperChar( + IN CHAR Character); + +NTOSAPI +VOID +DDKAPI +RtlUpperString( + IN OUT PSTRING DestinationString, + IN PSTRING SourceString); + +NTOSAPI +USHORT +DDKFASTAPI +RtlUshortByteSwap( + IN USHORT Source); + +NTOSAPI +BOOLEAN +DDKAPI +RtlValidRelativeSecurityDescriptor( + IN PSECURITY_DESCRIPTOR SecurityDescriptorInput, + IN ULONG SecurityDescriptorLength, + IN SECURITY_INFORMATION RequiredInformation); + +NTOSAPI +BOOLEAN +DDKAPI +RtlValidSecurityDescriptor( + IN PSECURITY_DESCRIPTOR SecurityDescriptor); + +NTOSAPI +NTSTATUS +DDKAPI +RtlVerifyVersionInfo( + IN PRTL_OSVERSIONINFOEXW VersionInfo, + IN ULONG TypeMask, + IN ULONGLONG ConditionMask); + +NTOSAPI +NTSTATUS +DDKAPI +RtlVolumeDeviceToDosName( + IN PVOID VolumeDeviceObject, + OUT PUNICODE_STRING DosName); + +NTOSAPI +ULONG +DDKAPI +RtlWalkFrameChain( + OUT PVOID *Callers, + IN ULONG Count, + IN ULONG Flags); + +NTOSAPI +NTSTATUS +DDKAPI +RtlWriteRegistryValue( + IN ULONG RelativeTo, + IN PCWSTR Path, + IN PCWSTR ValueName, + IN ULONG ValueType, + IN PVOID ValueData, + IN ULONG ValueLength); + +NTOSAPI +ULONG +DDKAPI +RtlxUnicodeStringToAnsiSize( + IN PUNICODE_STRING UnicodeString); + +/* + * VOID + * RtlZeroMemory( + * IN VOID UNALIGNED *Destination, + * IN SIZE_T Length) + */ +#ifndef RtlZeroMemory +#define RtlZeroMemory(Destination, Length) \ + memset(Destination, 0, Length); +#endif + +#ifndef RtlZeroBytes +#define RtlZeroBytes RtlZeroMemory +#endif + + +/** Executive support routines **/ + +NTOSAPI +VOID +DDKFASTAPI +ExAcquireFastMutex( + IN PFAST_MUTEX FastMutex); + +NTOSAPI +VOID +DDKFASTAPI +ExAcquireFastMutexUnsafe( + IN PFAST_MUTEX FastMutex); + +NTOSAPI +BOOLEAN +DDKAPI +ExAcquireResourceExclusiveLite( + IN PERESOURCE Resource, + IN BOOLEAN Wait); + +NTOSAPI +BOOLEAN +DDKAPI +ExAcquireResourceSharedLite( + IN PERESOURCE Resource, + IN BOOLEAN Wait); + +NTOSAPI +BOOLEAN +DDKAPI +ExAcquireSharedStarveExclusive( + IN PERESOURCE Resource, + IN BOOLEAN Wait); + +NTOSAPI +BOOLEAN +DDKAPI +ExAcquireSharedWaitForExclusive( + IN PERESOURCE Resource, + IN BOOLEAN Wait); + +static inline PVOID +ExAllocateFromNPagedLookasideList( + IN PNPAGED_LOOKASIDE_LIST Lookaside) +{ + PVOID Entry; + + Lookaside->TotalAllocates++; + Entry = InterlockedPopEntrySList(&Lookaside->ListHead); + if (Entry == NULL) { + Lookaside->AllocateMisses++; + Entry = (Lookaside->Allocate)(Lookaside->Type, Lookaside->Size, Lookaside->Tag); + } + return Entry; +} + +static inline PVOID +ExAllocateFromPagedLookasideList( + IN PPAGED_LOOKASIDE_LIST Lookaside) +{ + PVOID Entry; + + Lookaside->TotalAllocates++; + Entry = InterlockedPopEntrySList(&Lookaside->ListHead); + if (Entry == NULL) { + Lookaside->AllocateMisses++; + Entry = (Lookaside->Allocate)(Lookaside->Type, + Lookaside->Size, Lookaside->Tag); + } + return Entry; +} + +NTOSAPI +PVOID +DDKAPI +ExAllocatePoolWithQuotaTag( + IN POOL_TYPE PoolType, + IN SIZE_T NumberOfBytes, + IN ULONG Tag); + +NTOSAPI +PVOID +DDKAPI +ExAllocatePoolWithTag( + IN POOL_TYPE PoolType, + IN SIZE_T NumberOfBytes, + IN ULONG Tag); + +#ifdef POOL_TAGGING + +#define ExAllocatePoolWithQuota(p,n) ExAllocatePoolWithQuotaTag(p,n,' kdD') +#define ExAllocatePool(p,n) ExAllocatePoolWithTag(p,n,' kdD') + +#else /* !POOL_TAGGING */ + +NTOSAPI +PVOID +DDKAPI +ExAllocatePool( + IN POOL_TYPE PoolType, + IN SIZE_T NumberOfBytes); + +NTOSAPI +PVOID +DDKAPI +ExAllocatePoolWithQuota( + IN POOL_TYPE PoolType, + IN SIZE_T NumberOfBytes); + +#endif /* POOL_TAGGING */ + +NTOSAPI +PVOID +DDKAPI +ExAllocatePoolWithTagPriority( + IN POOL_TYPE PoolType, + IN SIZE_T NumberOfBytes, + IN ULONG Tag, + IN EX_POOL_PRIORITY Priority); + +NTOSAPI +VOID +DDKAPI +ExConvertExclusiveToSharedLite( + IN PERESOURCE Resource); + +NTOSAPI +NTSTATUS +DDKAPI +ExCreateCallback( + OUT PCALLBACK_OBJECT *CallbackObject, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN BOOLEAN Create, + IN BOOLEAN AllowMultipleCallbacks); + +NTOSAPI +VOID +DDKAPI +ExDeleteNPagedLookasideList( + IN PNPAGED_LOOKASIDE_LIST Lookaside); + +NTOSAPI +VOID +DDKAPI +ExDeletePagedLookasideList( + IN PPAGED_LOOKASIDE_LIST Lookaside); + +NTOSAPI +NTSTATUS +DDKAPI +ExDeleteResourceLite( + IN PERESOURCE Resource); + +NTOSAPI +VOID +DDKAPI +ExFreePool( + IN PVOID P); + +#define PROTECTED_POOL 0x80000000 + +#ifdef POOL_TAGGING +#define ExFreePool(P) ExFreePoolWithTag(P, 0) +#endif + +NTOSAPI +VOID +DDKAPI +ExFreePoolWithTag( + IN PVOID P, + IN ULONG Tag); + +#define ExQueryDepthSList(ListHead) QueryDepthSList(ListHead) + +static inline VOID +ExFreeToNPagedLookasideList( + IN PNPAGED_LOOKASIDE_LIST Lookaside, + IN PVOID Entry) +{ + Lookaside->TotalFrees++; + if (ExQueryDepthSList(&Lookaside->ListHead) >= Lookaside->Depth) { + Lookaside->FreeMisses++; + (Lookaside->Free)(Entry); + } else { + InterlockedPushEntrySList(&Lookaside->ListHead, + (PSLIST_ENTRY)Entry); + } +} + +static inline VOID +ExFreeToPagedLookasideList( + IN PPAGED_LOOKASIDE_LIST Lookaside, + IN PVOID Entry) +{ + Lookaside->TotalFrees++; + if (ExQueryDepthSList(&Lookaside->ListHead) >= Lookaside->Depth) { + Lookaside->FreeMisses++; + (Lookaside->Free)(Entry); + } else { + InterlockedPushEntrySList(&Lookaside->ListHead, (PSLIST_ENTRY)Entry); + } +} + +/* + * ERESOURCE_THREAD + * ExGetCurrentResourceThread( + * VOID); + */ +#define ExGetCurrentResourceThread() ((ERESOURCE_THREAD) PsGetCurrentThread()) + +NTOSAPI +ULONG +DDKAPI +ExGetExclusiveWaiterCount( + IN PERESOURCE Resource); + +NTOSAPI +KPROCESSOR_MODE +DDKAPI +ExGetPreviousMode( + VOID); + +NTOSAPI +ULONG +DDKAPI +ExGetSharedWaiterCount( + IN PERESOURCE Resource); + +NTOSAPI +VOID +DDKAPI +KeInitializeEvent( + IN PRKEVENT Event, + IN EVENT_TYPE Type, + IN BOOLEAN State); + +/* + * VOID DDKAPI + * ExInitializeFastMutex( + * IN PFAST_MUTEX FastMutex) + */ +#define ExInitializeFastMutex(_FastMutex) \ +{ \ + (_FastMutex)->Count = 1; \ + (_FastMutex)->Owner = NULL; \ + (_FastMutex)->Contention = 0; \ + KeInitializeEvent(&(_FastMutex)->Event, SynchronizationEvent, FALSE); \ +} + +NTOSAPI +VOID +DDKAPI +ExInitializeNPagedLookasideList( + IN PNPAGED_LOOKASIDE_LIST Lookaside, + IN PALLOCATE_FUNCTION Allocate OPTIONAL, + IN PFREE_FUNCTION Free OPTIONAL, + IN ULONG Flags, + IN SIZE_T Size, + IN ULONG Tag, + IN USHORT Depth); + +NTOSAPI +VOID +DDKAPI +ExInitializePagedLookasideList( + IN PPAGED_LOOKASIDE_LIST Lookaside, + IN PALLOCATE_FUNCTION Allocate OPTIONAL, + IN PFREE_FUNCTION Free OPTIONAL, + IN ULONG Flags, + IN SIZE_T Size, + IN ULONG Tag, + IN USHORT Depth); + +NTOSAPI +NTSTATUS +DDKAPI +ExInitializeResourceLite( + IN PERESOURCE Resource); + +/* + * VOID + * InitializeSListHead( + * IN PSLIST_HEADER SListHead) + */ +#define InitializeSListHead(_SListHead) \ + (_SListHead)->Alignment = 0; + +#define ExInitializeSListHead InitializeSListHead + +NTOSAPI +LARGE_INTEGER +DDKAPI +ExInterlockedAddLargeInteger( + IN PLARGE_INTEGER Addend, + IN LARGE_INTEGER Increment, + IN PKSPIN_LOCK Lock); + +NTOSAPI +VOID +DDKFASTAPI +ExInterlockedAddLargeStatistic( + IN PLARGE_INTEGER Addend, + IN ULONG Increment); + +NTOSAPI +ULONG +DDKFASTAPI +ExInterlockedAddUlong( + IN PULONG Addend, + IN ULONG Increment, + PKSPIN_LOCK Lock); + +NTOSAPI +LONGLONG +DDKFASTAPI +ExInterlockedCompareExchange64( + IN OUT PLONGLONG Destination, + IN PLONGLONG Exchange, + IN PLONGLONG Comparand, + IN PKSPIN_LOCK Lock); + +NTOSAPI +PSINGLE_LIST_ENTRY +DDKFASTAPI +ExInterlockedFlushSList( + IN PSLIST_HEADER ListHead); + +NTOSAPI +PLIST_ENTRY +DDKFASTAPI +ExInterlockedInsertHeadList( + IN PLIST_ENTRY ListHead, + IN PLIST_ENTRY ListEntry, + IN PKSPIN_LOCK Lock); + +NTOSAPI +PLIST_ENTRY +DDKFASTAPI +ExInterlockedInsertTailList( + IN PLIST_ENTRY ListHead, + IN PLIST_ENTRY ListEntry, + IN PKSPIN_LOCK Lock); + +NTOSAPI +PSINGLE_LIST_ENTRY +DDKFASTAPI +ExInterlockedPopEntryList( + IN PSINGLE_LIST_ENTRY ListHead, + IN PKSPIN_LOCK Lock); + +/* + * PSINGLE_LIST_ENTRY + * ExInterlockedPopEntrySList( + * IN PSLIST_HEADER ListHead, + * IN PKSPIN_LOCK Lock) + */ +#define ExInterlockedPopEntrySList(_ListHead, \ + _Lock) \ + InterlockedPopEntrySList(_ListHead) + +NTOSAPI +PSINGLE_LIST_ENTRY +DDKFASTAPI +ExInterlockedPushEntryList( + IN PSINGLE_LIST_ENTRY ListHead, + IN PSINGLE_LIST_ENTRY ListEntry, + IN PKSPIN_LOCK Lock); + +/* + * PSINGLE_LIST_ENTRY FASTCALL + * ExInterlockedPushEntrySList( + * IN PSLIST_HEADER ListHead, + * IN PSINGLE_LIST_ENTRY ListEntry, + * IN PKSPIN_LOCK Lock) + */ +#define ExInterlockedPushEntrySList(_ListHead, \ + _ListEntry, \ + _Lock) \ + InterlockedPushEntrySList(_ListHead, _ListEntry) + +NTOSAPI +PLIST_ENTRY +DDKFASTAPI +ExInterlockedRemoveHeadList( + IN PLIST_ENTRY ListHead, + IN PKSPIN_LOCK Lock); + +NTOSAPI +BOOLEAN +DDKAPI +ExIsProcessorFeaturePresent( + IN ULONG ProcessorFeature); + +NTOSAPI +BOOLEAN +DDKAPI +ExIsResourceAcquiredExclusiveLite( + IN PERESOURCE Resource); + +NTOSAPI +USHORT +DDKAPI +ExIsResourceAcquiredLite( + IN PERESOURCE Resource); + +NTOSAPI +USHORT +DDKAPI +ExIsResourceAcquiredSharedLite( + IN PERESOURCE Resource); + +NTOSAPI +VOID +DDKAPI +ExLocalTimeToSystemTime( + IN PLARGE_INTEGER LocalTime, + OUT PLARGE_INTEGER SystemTime); + +NTOSAPI +VOID +DDKAPI +ExNotifyCallback( + IN PCALLBACK_OBJECT CallbackObject, + IN PVOID Argument1, + IN PVOID Argument2); + +NTOSAPI +VOID +DDKAPI +ExRaiseAccessViolation( + VOID); + +NTOSAPI +VOID +DDKAPI +ExRaiseDatatypeMisalignment( + VOID); + +NTOSAPI +VOID +DDKAPI +ExRaiseStatus( + IN NTSTATUS Status); + +NTOSAPI +PVOID +DDKAPI +ExRegisterCallback( + IN PCALLBACK_OBJECT CallbackObject, + IN PCALLBACK_FUNCTION CallbackFunction, + IN PVOID CallbackContext); + +NTOSAPI +VOID +DDKAPI +ExReinitializeResourceLite( + IN PERESOURCE Resource); + +NTOSAPI +VOID +DDKFASTAPI +ExReleaseFastMutex( + IN PFAST_MUTEX FastMutex); + +NTOSAPI +VOID +DDKFASTAPI +ExReleaseFastMutexUnsafe( + IN PFAST_MUTEX FastMutex); + +NTOSAPI +VOID +DDKAPI +ExReleaseResourceForThreadLite( + IN PERESOURCE Resource, + IN ERESOURCE_THREAD ResourceThreadId); + +NTOSAPI +VOID +DDKFASTAPI +ExReleaseResourceLite( + IN PERESOURCE Resource); + +NTOSAPI +VOID +DDKAPI +ExSetResourceOwnerPointer( + IN PERESOURCE Resource, + IN PVOID OwnerPointer); + +NTOSAPI +ULONG +DDKAPI +ExSetTimerResolution( + IN ULONG DesiredTime, + IN BOOLEAN SetResolution); + +NTOSAPI +VOID +DDKAPI +ExSystemTimeToLocalTime( + IN PLARGE_INTEGER SystemTime, + OUT PLARGE_INTEGER LocalTime); + +NTOSAPI +BOOLEAN +DDKFASTAPI +ExTryToAcquireFastMutex( + IN PFAST_MUTEX FastMutex); + +NTOSAPI +BOOLEAN +DDKAPI +ExTryToAcquireResourceExclusiveLite( + IN PERESOURCE Resource); + +NTOSAPI +VOID +DDKAPI +ExUnregisterCallback( + IN PVOID CbRegistration); + +NTOSAPI +NTSTATUS +DDKAPI +ExUuidCreate( + OUT UUID *Uuid); + +NTOSAPI +BOOLEAN +DDKAPI +ExVerifySuite( + IN SUITE_TYPE SuiteType); + +#if DBG + +#define PAGED_CODE() { \ + if (KeGetCurrentIrql() > APC_LEVEL) { \ + KdPrint( ("NTDDK: Pageable code called at IRQL > APC_LEVEL (%d)\n", KeGetCurrentIrql() )); \ + assert(FALSE); \ + } \ +} + +#else + +#define PAGED_CODE() + +#endif + +NTOSAPI +VOID +DDKAPI +ProbeForRead( + IN CONST VOID *Address, + IN ULONG Length, + IN ULONG Alignment); + +NTOSAPI +VOID +DDKAPI +ProbeForWrite( + IN CONST VOID *Address, + IN ULONG Length, + IN ULONG Alignment); + + + +/** Configuration manager routines **/ + +NTOSAPI +NTSTATUS +DDKAPI +CmRegisterCallback( + IN PEX_CALLBACK_FUNCTION Function, + IN PVOID Context, + IN OUT PLARGE_INTEGER Cookie); + +NTOSAPI +NTSTATUS +DDKAPI +CmUnRegisterCallback( + IN LARGE_INTEGER Cookie); + + + +/** Filesystem runtime library routines **/ + +NTOSAPI +BOOLEAN +DDKAPI +FsRtlIsTotalDeviceFailure( + IN NTSTATUS Status); + + + +/** Hardware abstraction layer routines **/ + +NTOSAPI +VOID +DDKFASTAPI +HalExamineMBR( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize, + IN ULONG MBRTypeIdentifier, + OUT PVOID Buffer); + +NTOSAPI +VOID +DDKAPI +READ_PORT_BUFFER_UCHAR( + IN PUCHAR Port, + IN PUCHAR Buffer, + IN ULONG Count); + +NTOSAPI +VOID +DDKAPI +READ_PORT_BUFFER_ULONG( + IN PULONG Port, + IN PULONG Buffer, + IN ULONG Count); + +NTOSAPI +VOID +DDKAPI +READ_PORT_BUFFER_USHORT( + IN PUSHORT Port, + IN PUSHORT Buffer, + IN ULONG Count); + +NTOSAPI +UCHAR +DDKAPI +READ_PORT_UCHAR( + IN PUCHAR Port); + +NTOSAPI +ULONG +DDKAPI +READ_PORT_ULONG( + IN PULONG Port); + +NTOSAPI +USHORT +DDKAPI +READ_PORT_USHORT( + IN PUSHORT Port); + +NTOSAPI +VOID +DDKAPI +READ_REGISTER_BUFFER_UCHAR( + IN PUCHAR Register, + IN PUCHAR Buffer, + IN ULONG Count); + +NTOSAPI +VOID +DDKAPI +READ_REGISTER_BUFFER_ULONG( + IN PULONG Register, + IN PULONG Buffer, + IN ULONG Count); + +NTOSAPI +VOID +DDKAPI +READ_REGISTER_BUFFER_USHORT( + IN PUSHORT Register, + IN PUSHORT Buffer, + IN ULONG Count); + +NTOSAPI +UCHAR +DDKAPI +READ_REGISTER_UCHAR( + IN PUCHAR Register); + +NTOSAPI +ULONG +DDKAPI +READ_REGISTER_ULONG( + IN PULONG Register); + +NTOSAPI +USHORT +DDKAPI +READ_REGISTER_USHORT( + IN PUSHORT Register); + +NTOSAPI +VOID +DDKAPI +WRITE_PORT_BUFFER_UCHAR( + IN PUCHAR Port, + IN PUCHAR Buffer, + IN ULONG Count); + +NTOSAPI +VOID +DDKAPI +WRITE_PORT_BUFFER_ULONG( + IN PULONG Port, + IN PULONG Buffer, + IN ULONG Count); + +NTOSAPI +VOID +DDKAPI +WRITE_PORT_BUFFER_USHORT( + IN PUSHORT Port, + IN PUSHORT Buffer, + IN ULONG Count); + +NTOSAPI +VOID +DDKAPI +WRITE_PORT_UCHAR( + IN PUCHAR Port, + IN UCHAR Value); + +NTOSAPI +VOID +DDKAPI +WRITE_PORT_ULONG( + IN PULONG Port, + IN ULONG Value); + +NTOSAPI +VOID +DDKAPI +WRITE_PORT_USHORT( + IN PUSHORT Port, + IN USHORT Value); + +NTOSAPI +VOID +DDKAPI +WRITE_REGISTER_BUFFER_UCHAR( + IN PUCHAR Register, + IN PUCHAR Buffer, + IN ULONG Count); + +NTOSAPI +VOID +DDKAPI +WRITE_REGISTER_BUFFER_ULONG( + IN PULONG Register, + IN PULONG Buffer, + IN ULONG Count); + +NTOSAPI +VOID +DDKAPI +WRITE_REGISTER_BUFFER_USHORT( + IN PUSHORT Register, + IN PUSHORT Buffer, + IN ULONG Count); + +NTOSAPI +VOID +DDKAPI +WRITE_REGISTER_UCHAR( + IN PUCHAR Register, + IN UCHAR Value); + +NTOSAPI +VOID +DDKAPI +WRITE_REGISTER_ULONG( + IN PULONG Register, + IN ULONG Value); + +NTOSAPI +VOID +DDKAPI +WRITE_REGISTER_USHORT( + IN PUSHORT Register, + IN USHORT Value); + + + +/** I/O manager routines **/ + +NTOSAPI +VOID +DDKAPI +IoAcquireCancelSpinLock( + OUT PKIRQL Irql); + +NTOSAPI +NTSTATUS +DDKAPI +IoAcquireRemoveLockEx( + IN PIO_REMOVE_LOCK RemoveLock, + IN OPTIONAL PVOID Tag OPTIONAL, + IN PCSTR File, + IN ULONG Line, + IN ULONG RemlockSize); + +/* + * NTSTATUS + * IoAcquireRemoveLock( + * IN PIO_REMOVE_LOCK RemoveLock, + * IN OPTIONAL PVOID Tag) + */ +#define IoAcquireRemoveLock(_RemoveLock, \ + _Tag) \ + IoAcquireRemoveLockEx(_RemoveLock, _Tag, __FILE__, __LINE__, sizeof(IO_REMOVE_LOCK)); + +/* + * VOID + * IoAdjustPagingPathCount( + * IN PLONG Count, + * IN BOOLEAN Increment) + */ +#define IoAdjustPagingPathCount(_Count, \ + _Increment) \ +{ \ + if (_Increment) \ + { \ + InterlockedIncrement(_Count); \ + } \ + else \ + { \ + InterlockedDecrement(_Count); \ + } \ +} + +NTOSAPI +VOID +DDKAPI +IoAllocateController( + IN PCONTROLLER_OBJECT ControllerObject, + IN PDEVICE_OBJECT DeviceObject, + IN PDRIVER_CONTROL ExecutionRoutine, + IN PVOID Context); + +NTOSAPI +NTSTATUS +DDKAPI +IoAllocateDriverObjectExtension( + IN PDRIVER_OBJECT DriverObject, + IN PVOID ClientIdentificationAddress, + IN ULONG DriverObjectExtensionSize, + OUT PVOID *DriverObjectExtension); + +typedef struct _IO_ERROR_LOG_PACKET { + UCHAR MajorFunctionCode; + UCHAR RetryCount; + USHORT DumpDataSize; + USHORT NumberOfStrings; + USHORT StringOffset; + USHORT EventCategory; + NTSTATUS ErrorCode; + ULONG UniqueErrorValue; + NTSTATUS FinalStatus; + ULONG SequenceNumber; + ULONG IoControlCode; + LARGE_INTEGER DeviceOffset; + ULONG DumpData[1]; +} IO_ERROR_LOG_PACKET, *PIO_ERROR_LOG_PACKET; + +NTOSAPI +PVOID +DDKAPI +IoAllocateErrorLogEntry( + IN PVOID IoObject, + IN UCHAR EntrySize); + +NTOSAPI +PIRP +DDKAPI +IoAllocateIrp( + IN CCHAR StackSize, + IN BOOLEAN ChargeQuota); + +NTOSAPI +PMDL +DDKAPI +IoAllocateMdl( + IN PVOID VirtualAddress, + IN ULONG Length, + IN BOOLEAN SecondaryBuffer, + IN BOOLEAN ChargeQuota, + IN OUT PIRP Irp OPTIONAL); + +NTOSAPI +PIO_WORKITEM +DDKAPI +IoAllocateWorkItem( + IN PDEVICE_OBJECT DeviceObject); + +/* + * VOID IoAssignArcName( + * IN PUNICODE_STRING ArcName, + * IN PUNICODE_STRING DeviceName); + */ +#define IoAssignArcName(_ArcName, _DeviceName) ( \ + IoCreateSymbolicLink((_ArcName), (_DeviceName))) + +NTOSAPI +NTSTATUS +DDKAPI +IoAttachDevice( + IN PDEVICE_OBJECT SourceDevice, + IN PUNICODE_STRING TargetDevice, + OUT PDEVICE_OBJECT *AttachedDevice); + +NTOSAPI +PDEVICE_OBJECT +DDKAPI +IoAttachDeviceToDeviceStack( + IN PDEVICE_OBJECT SourceDevice, + IN PDEVICE_OBJECT TargetDevice); + +NTOSAPI +PIRP +DDKAPI +IoBuildAsynchronousFsdRequest( + IN ULONG MajorFunction, + IN PDEVICE_OBJECT DeviceObject, + IN OUT PVOID Buffer OPTIONAL, + IN ULONG Length OPTIONAL, + IN PLARGE_INTEGER StartingOffset OPTIONAL, + IN PIO_STATUS_BLOCK IoStatusBlock OPTIONAL); + +NTOSAPI +PIRP +DDKAPI +IoBuildDeviceIoControlRequest( + IN ULONG IoControlCode, + IN PDEVICE_OBJECT DeviceObject, + IN PVOID InputBuffer OPTIONAL, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer OPTIONAL, + IN ULONG OutputBufferLength, + IN BOOLEAN InternalDeviceIoControl, + IN PKEVENT Event, + OUT PIO_STATUS_BLOCK IoStatusBlock); + +NTOSAPI +VOID +DDKAPI +IoBuildPartialMdl( + IN PMDL SourceMdl, + IN OUT PMDL TargetMdl, + IN PVOID VirtualAddress, + IN ULONG Length); + +NTOSAPI +PIRP +DDKAPI +IoBuildSynchronousFsdRequest( + IN ULONG MajorFunction, + IN PDEVICE_OBJECT DeviceObject, + IN OUT PVOID Buffer OPTIONAL, + IN ULONG Length OPTIONAL, + IN PLARGE_INTEGER StartingOffset OPTIONAL, + IN PKEVENT Event, + OUT PIO_STATUS_BLOCK IoStatusBlock); + +NTOSAPI +NTSTATUS +DDKFASTAPI +IofCallDriver( + IN PDEVICE_OBJECT DeviceObject, + IN OUT PIRP Irp); + +/* + * NTSTATUS + * IoCallDriver( + * IN PDEVICE_OBJECT DeviceObject, + * IN OUT PIRP Irp) + */ +#define IoCallDriver IofCallDriver + +NTOSAPI +VOID +DDKAPI +IoCancelFileOpen( + IN PDEVICE_OBJECT DeviceObject, + IN PFILE_OBJECT FileObject); + +NTOSAPI +BOOLEAN +DDKAPI +IoCancelIrp( + IN PIRP Irp); + +NTOSAPI +NTSTATUS +DDKAPI +IoCheckShareAccess( + IN ACCESS_MASK DesiredAccess, + IN ULONG DesiredShareAccess, + IN OUT PFILE_OBJECT FileObject, + IN OUT PSHARE_ACCESS ShareAccess, + IN BOOLEAN Update); + +NTOSAPI +VOID +DDKFASTAPI +IofCompleteRequest( + IN PIRP Irp, + IN CCHAR PriorityBoost); + +/* + * VOID + * IoCompleteRequest( + * IN PIRP Irp, + * IN CCHAR PriorityBoost) + */ +#define IoCompleteRequest IofCompleteRequest + +NTOSAPI +NTSTATUS +DDKAPI +IoConnectInterrupt( + OUT PKINTERRUPT *InterruptObject, + IN PKSERVICE_ROUTINE ServiceRoutine, + IN PVOID ServiceContext, + IN PKSPIN_LOCK SpinLock OPTIONAL, + IN ULONG Vector, + IN KIRQL Irql, + IN KIRQL SynchronizeIrql, + IN KINTERRUPT_MODE InterruptMode, + IN BOOLEAN ShareVector, + IN KAFFINITY ProcessorEnableMask, + IN BOOLEAN FloatingSave); + +/* + * PIO_STACK_LOCATION + * IoGetCurrentIrpStackLocation( + * IN PIRP Irp) + */ +#define IoGetCurrentIrpStackLocation(_Irp) \ + ((_Irp)->Tail.Overlay.CurrentStackLocation) + +/* + * PIO_STACK_LOCATION + * IoGetNextIrpStackLocation( + * IN PIRP Irp) + */ +#define IoGetNextIrpStackLocation(_Irp) \ + ((_Irp)->Tail.Overlay.CurrentStackLocation - 1) + +/* + * VOID + * IoCopyCurrentIrpStackLocationToNext( + * IN PIRP Irp) + */ +#define IoCopyCurrentIrpStackLocationToNext(_Irp) \ +{ \ + PIO_STACK_LOCATION _IrpSp; \ + PIO_STACK_LOCATION _NextIrpSp; \ + _IrpSp = IoGetCurrentIrpStackLocation(_Irp); \ + _NextIrpSp = IoGetNextIrpStackLocation(_Irp); \ + RtlCopyMemory(_NextIrpSp, _IrpSp, \ + FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine)); \ + _NextIrpSp->Control = 0; \ +} + +NTOSAPI +PCONTROLLER_OBJECT +DDKAPI +IoCreateController( + IN ULONG Size); + +NTOSAPI +NTSTATUS +DDKAPI +IoCreateDevice( + IN PDRIVER_OBJECT DriverObject, + IN ULONG DeviceExtensionSize, + IN PUNICODE_STRING DeviceName OPTIONAL, + IN DEVICE_TYPE DeviceType, + IN ULONG DeviceCharacteristics, + IN BOOLEAN Exclusive, + OUT PDEVICE_OBJECT *DeviceObject); + +NTOSAPI +NTSTATUS +DDKAPI +IoCreateDisk( + IN PDEVICE_OBJECT DeviceObject, + IN PCREATE_DISK Disk); + +NTOSAPI +NTSTATUS +DDKAPI +IoCreateFile( + OUT PHANDLE FileHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PLARGE_INTEGER AllocationSize OPTIONAL, + IN ULONG FileAttributes, + IN ULONG ShareAccess, + IN ULONG Disposition, + IN ULONG CreateOptions, + IN PVOID EaBuffer OPTIONAL, + IN ULONG EaLength, + IN CREATE_FILE_TYPE CreateFileType, + IN PVOID ExtraCreateParameters OPTIONAL, + IN ULONG Options); + +NTOSAPI +PKEVENT +DDKAPI +IoCreateNotificationEvent( + IN PUNICODE_STRING EventName, + OUT PHANDLE EventHandle); + +NTOSAPI +NTSTATUS +DDKAPI +IoCreateSymbolicLink( + IN PUNICODE_STRING SymbolicLinkName, + IN PUNICODE_STRING DeviceName); + +NTOSAPI +PKEVENT +DDKAPI +IoCreateSynchronizationEvent( + IN PUNICODE_STRING EventName, + OUT PHANDLE EventHandle); + +NTOSAPI +NTSTATUS +DDKAPI +IoCreateUnprotectedSymbolicLink( + IN PUNICODE_STRING SymbolicLinkName, + IN PUNICODE_STRING DeviceName); + +NTOSAPI +VOID +DDKAPI +IoCsqInitialize( + PIO_CSQ Csq, + IN PIO_CSQ_INSERT_IRP CsqInsertIrp, + IN PIO_CSQ_REMOVE_IRP CsqRemoveIrp, + IN PIO_CSQ_PEEK_NEXT_IRP CsqPeekNextIrp, + IN PIO_CSQ_ACQUIRE_LOCK CsqAcquireLock, + IN PIO_CSQ_RELEASE_LOCK CsqReleaseLock, + IN PIO_CSQ_COMPLETE_CANCELED_IRP CsqCompleteCanceledIrp); + +NTOSAPI +VOID +DDKAPI +IoCsqInsertIrp( + IN PIO_CSQ Csq, + IN PIRP Irp, + IN PIO_CSQ_IRP_CONTEXT Context); + +NTOSAPI +PIRP +DDKAPI +IoCsqRemoveIrp( + IN PIO_CSQ Csq, + IN PIO_CSQ_IRP_CONTEXT Context); + +NTOSAPI +PIRP +DDKAPI +IoCsqRemoveNextIrp( + IN PIO_CSQ Csq, + IN PVOID PeekContext); + +NTOSAPI +VOID +DDKAPI +IoDeleteController( + IN PCONTROLLER_OBJECT ControllerObject); + +NTOSAPI +VOID +DDKAPI +IoDeleteDevice( + IN PDEVICE_OBJECT DeviceObject); + +NTOSAPI +NTSTATUS +DDKAPI +IoDeleteSymbolicLink( + IN PUNICODE_STRING SymbolicLinkName); + +/* + * VOID + * IoDeassignArcName( + * IN PUNICODE_STRING ArcName) + */ +#define IoDeassignArcName IoDeleteSymbolicLink + +NTOSAPI +VOID +DDKAPI +IoDetachDevice( + IN OUT PDEVICE_OBJECT TargetDevice); + +NTOSAPI +VOID +DDKAPI +IoDisconnectInterrupt( + IN PKINTERRUPT InterruptObject); + +NTOSAPI +BOOLEAN +DDKAPI +IoForwardIrpSynchronously( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +#define IoForwardAndCatchIrp IoForwardIrpSynchronously + +NTOSAPI +VOID +DDKAPI +IoFreeController( + IN PCONTROLLER_OBJECT ControllerObject); + +NTOSAPI +VOID +DDKAPI +IoFreeErrorLogEntry( + PVOID ElEntry); + +NTOSAPI +VOID +DDKAPI +IoFreeIrp( + IN PIRP Irp); + +NTOSAPI +VOID +DDKAPI +IoFreeMdl( + IN PMDL Mdl); + +NTOSAPI +VOID +DDKAPI +IoFreeWorkItem( + IN PIO_WORKITEM pIOWorkItem); + +NTOSAPI +PDEVICE_OBJECT +DDKAPI +IoGetAttachedDevice( + IN PDEVICE_OBJECT DeviceObject); + +NTOSAPI +PDEVICE_OBJECT +DDKAPI +IoGetAttachedDeviceReference( + IN PDEVICE_OBJECT DeviceObject); + +NTOSAPI +NTSTATUS +DDKAPI +IoGetBootDiskInformation( + IN OUT PBOOTDISK_INFORMATION BootDiskInformation, + IN ULONG Size); + +NTOSAPI +PCONFIGURATION_INFORMATION +DDKAPI +IoGetConfigurationInformation( + VOID); + +NTOSAPI +PEPROCESS +DDKAPI +IoGetCurrentProcess( + VOID); + +NTOSAPI +NTSTATUS +DDKAPI +IoGetDeviceInterfaceAlias( + IN PUNICODE_STRING SymbolicLinkName, + IN CONST GUID *AliasInterfaceClassGuid, + OUT PUNICODE_STRING AliasSymbolicLinkName); + +NTOSAPI +NTSTATUS +DDKAPI +IoGetDeviceInterfaces( + IN CONST GUID *InterfaceClassGuid, + IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, + IN ULONG Flags, + OUT PWSTR *SymbolicLinkList); + +NTOSAPI +NTSTATUS +DDKAPI +IoGetDeviceObjectPointer( + IN PUNICODE_STRING ObjectName, + IN ACCESS_MASK DesiredAccess, + OUT PFILE_OBJECT *FileObject, + OUT PDEVICE_OBJECT *DeviceObject); + +NTOSAPI +NTSTATUS +DDKAPI +IoGetDeviceProperty( + IN PDEVICE_OBJECT DeviceObject, + IN DEVICE_REGISTRY_PROPERTY DeviceProperty, + IN ULONG BufferLength, + OUT PVOID PropertyBuffer, + OUT PULONG ResultLength); + +NTOSAPI +PDEVICE_OBJECT +DDKAPI +IoGetDeviceToVerify( + IN PETHREAD Thread); + +NTOSAPI +PDMA_ADAPTER +DDKAPI +IoGetDmaAdapter( + IN PDEVICE_OBJECT PhysicalDeviceObject, + IN PDEVICE_DESCRIPTION DeviceDescription, + IN OUT PULONG NumberOfMapRegisters); + +NTOSAPI +PVOID +DDKAPI +IoGetDriverObjectExtension( + IN PDRIVER_OBJECT DriverObject, + IN PVOID ClientIdentificationAddress); + +NTOSAPI +PGENERIC_MAPPING +DDKAPI +IoGetFileObjectGenericMapping( + VOID); + +/* + * ULONG + * IoGetFunctionCodeFromCtlCode( + * IN ULONG ControlCode) + */ +#define IoGetFunctionCodeFromCtlCode(_ControlCode) \ + (((_ControlCode) >> 2) & 0x00000FFF); + +NTOSAPI +PVOID +DDKAPI +IoGetInitialStack( + VOID); + +NTOSAPI +PDEVICE_OBJECT +DDKAPI +IoGetRelatedDeviceObject( + IN PFILE_OBJECT FileObject); + +NTOSAPI +ULONG +DDKAPI +IoGetRemainingStackSize( + VOID); + +NTOSAPI +VOID +DDKAPI +IoGetStackLimits( + OUT PULONG_PTR LowLimit, + OUT PULONG_PTR HighLimit); + +NTOSAPI +VOID +DDKAPI +KeInitializeDpc( + IN PRKDPC Dpc, + IN PKDEFERRED_ROUTINE DeferredRoutine, + IN PVOID DeferredContext); + +/* + * VOID + * IoInitializeDpcRequest( + * IN PDEVICE_OBJECT DeviceObject, + * IN PIO_DPC_ROUTINE DpcRoutine) + */ +#define IoInitializeDpcRequest(_DeviceObject, \ + _DpcRoutine) \ + KeInitializeDpc(&(_DeviceObject)->Dpc, \ + (PKDEFERRED_ROUTINE) (_DpcRoutine), \ + _DeviceObject); + +NTOSAPI +VOID +DDKAPI +IoInitializeIrp( + IN OUT PIRP Irp, + IN USHORT PacketSize, + IN CCHAR StackSize); + +NTOSAPI +VOID +DDKAPI +IoInitializeRemoveLockEx( + IN PIO_REMOVE_LOCK Lock, + IN ULONG AllocateTag, + IN ULONG MaxLockedMinutes, + IN ULONG HighWatermark, + IN ULONG RemlockSize); + +/* VOID + * IoInitializeRemoveLock( + * IN PIO_REMOVE_LOCK Lock, + * IN ULONG AllocateTag, + * IN ULONG MaxLockedMinutes, + * IN ULONG HighWatermark) + */ +#define IoInitializeRemoveLock( \ + Lock, AllocateTag, MaxLockedMinutes, HighWatermark) \ + IoInitializeRemoveLockEx(Lock, AllocateTag, MaxLockedMinutes, \ + HighWatermark, sizeof(IO_REMOVE_LOCK)); + +NTOSAPI +NTSTATUS +DDKAPI +IoInitializeTimer( + IN PDEVICE_OBJECT DeviceObject, + IN PIO_TIMER_ROUTINE TimerRoutine, + IN PVOID Context); + +NTOSAPI +VOID +DDKAPI +IoInvalidateDeviceRelations( + IN PDEVICE_OBJECT DeviceObject, + IN DEVICE_RELATION_TYPE Type); + +NTOSAPI +VOID +DDKAPI +IoInvalidateDeviceState( + IN PDEVICE_OBJECT PhysicalDeviceObject); + +NTOSAPI +BOOLEAN +DDKAPI +IoIs32bitProcess( + IN PIRP Irp OPTIONAL); + +/* + * BOOLEAN + * IoIsErrorUserInduced( + * IN NTSTATUS Status); + */ +#define IoIsErrorUserInduced(Status) \ + ((BOOLEAN)(((Status) == STATUS_DEVICE_NOT_READY) || \ + ((Status) == STATUS_IO_TIMEOUT) || \ + ((Status) == STATUS_MEDIA_WRITE_PROTECTED) || \ + ((Status) == STATUS_NO_MEDIA_IN_DEVICE) || \ + ((Status) == STATUS_VERIFY_REQUIRED) || \ + ((Status) == STATUS_UNRECOGNIZED_MEDIA) || \ + ((Status) == STATUS_WRONG_VOLUME))) + +NTOSAPI +BOOLEAN +DDKAPI +IoIsWdmVersionAvailable( + IN UCHAR MajorVersion, + IN UCHAR MinorVersion); + +NTOSAPI +PIRP +DDKAPI +IoMakeAssociatedIrp( + IN PIRP Irp, + IN CCHAR StackSize); + +/* + * VOID + * IoMarkIrpPending( + * IN OUT PIRP Irp) + */ +#define IoMarkIrpPending(_Irp) \ + (IoGetCurrentIrpStackLocation(_Irp)->Control |= SL_PENDING_RETURNED) + +NTOSAPI +NTSTATUS +DDKAPI +IoOpenDeviceInterfaceRegistryKey( + IN PUNICODE_STRING SymbolicLinkName, + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE DeviceInterfaceKey); + +NTOSAPI +NTSTATUS +DDKAPI +IoOpenDeviceRegistryKey( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG DevInstKeyType, + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE DevInstRegKey); + +NTOSAPI +NTSTATUS +DDKAPI +IoQueryDeviceDescription( + IN PINTERFACE_TYPE BusType OPTIONAL, + IN PULONG BusNumber OPTIONAL, + IN PCONFIGURATION_TYPE ControllerType OPTIONAL, + IN PULONG ControllerNumber OPTIONAL, + IN PCONFIGURATION_TYPE PeripheralType OPTIONAL, + IN PULONG PeripheralNumber OPTIONAL, + IN PIO_QUERY_DEVICE_ROUTINE CalloutRoutine, + IN PVOID Context); + +NTOSAPI +VOID +DDKAPI +IoQueueWorkItem( + IN PIO_WORKITEM pIOWorkItem, + IN PIO_WORKITEM_ROUTINE Routine, + IN WORK_QUEUE_TYPE QueueType, + IN PVOID Context); + +NTOSAPI +VOID +DDKAPI +IoRaiseHardError( + IN PIRP Irp, + IN PVPB Vpb OPTIONAL, + IN PDEVICE_OBJECT RealDeviceObject); + +NTOSAPI +BOOLEAN +DDKAPI +IoRaiseInformationalHardError( + IN NTSTATUS ErrorStatus, + IN PUNICODE_STRING String OPTIONAL, + IN PKTHREAD Thread OPTIONAL); + +NTOSAPI +NTSTATUS +DDKAPI +IoReadDiskSignature( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG BytesPerSector, + OUT PDISK_SIGNATURE Signature); + +NTOSAPI +NTSTATUS +DDKAPI +IoReadPartitionTableEx( + IN PDEVICE_OBJECT DeviceObject, + IN struct _DRIVE_LAYOUT_INFORMATION_EX **PartitionBuffer); + +NTOSAPI +VOID +DDKAPI +IoRegisterBootDriverReinitialization( + IN PDRIVER_OBJECT DriverObject, + IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, + IN PVOID Context); + +NTOSAPI +VOID +DDKAPI +IoRegisterBootDriverReinitialization( + IN PDRIVER_OBJECT DriverObject, + IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, + IN PVOID Context); + +NTOSAPI +NTSTATUS +DDKAPI +IoRegisterDeviceInterface( + IN PDEVICE_OBJECT PhysicalDeviceObject, + IN CONST GUID *InterfaceClassGuid, + IN PUNICODE_STRING ReferenceString OPTIONAL, + OUT PUNICODE_STRING SymbolicLinkName); + +NTOSAPI +VOID +DDKAPI +IoRegisterDriverReinitialization( + IN PDRIVER_OBJECT DriverObject, + IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, + IN PVOID Context); + +NTOSAPI +NTSTATUS +DDKAPI +IoRegisterPlugPlayNotification( + IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory, + IN ULONG EventCategoryFlags, + IN PVOID EventCategoryData OPTIONAL, + IN PDRIVER_OBJECT DriverObject, + IN PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine, + IN PVOID Context, + OUT PVOID *NotificationEntry); + +NTOSAPI +NTSTATUS +DDKAPI +IoRegisterShutdownNotification( + IN PDEVICE_OBJECT DeviceObject); + +NTOSAPI +VOID +DDKAPI +IoReleaseCancelSpinLock( + IN KIRQL Irql); + +NTOSAPI +VOID +DDKAPI +IoReleaseRemoveLockAndWaitEx( + IN PIO_REMOVE_LOCK RemoveLock, + IN PVOID Tag, + IN ULONG RemlockSize); + +NTOSAPI +VOID +DDKAPI +IoReleaseRemoveLockEx( + IN PIO_REMOVE_LOCK RemoveLock, + IN PVOID Tag, + IN ULONG RemlockSize); + +/* + * VOID + * IoReleaseRemoveLockAndWait( + * IN PIO_REMOVE_LOCK RemoveLock, + * IN PVOID Tag) + */ +#define IoReleaseRemoveLockAndWait(_RemoveLock, \ + _Tag) \ + IoReleaseRemoveLockEx(_RemoveLock, _Tag, sizeof(IO_REMOVE_LOCK)); + +NTOSAPI +VOID +DDKAPI +IoRemoveShareAccess( + IN PFILE_OBJECT FileObject, + IN OUT PSHARE_ACCESS ShareAccess); + +NTOSAPI +NTSTATUS +DDKAPI +IoReportDetectedDevice( + IN PDRIVER_OBJECT DriverObject, + IN INTERFACE_TYPE LegacyBusType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PCM_RESOURCE_LIST ResourceList, + IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements OPTIONAL, + IN BOOLEAN ResourceAssigned, + IN OUT PDEVICE_OBJECT *DeviceObject); + +NTOSAPI +NTSTATUS +DDKAPI +IoReportResourceForDetection( + IN PDRIVER_OBJECT DriverObject, + IN PCM_RESOURCE_LIST DriverList OPTIONAL, + IN ULONG DriverListSize OPTIONAL, + IN PDEVICE_OBJECT DeviceObject OPTIONAL, + IN PCM_RESOURCE_LIST DeviceList OPTIONAL, + IN ULONG DeviceListSize OPTIONAL, + OUT PBOOLEAN ConflictDetected); + +NTOSAPI +NTSTATUS +DDKAPI +IoReportResourceUsage( + IN PUNICODE_STRING DriverClassName OPTIONAL, + IN PDRIVER_OBJECT DriverObject, + IN PCM_RESOURCE_LIST DriverList OPTIONAL, + IN ULONG DriverListSize OPTIONAL, + IN PDEVICE_OBJECT DeviceObject, + IN PCM_RESOURCE_LIST DeviceList OPTIONAL, + IN ULONG DeviceListSize OPTIONAL, + IN BOOLEAN OverrideConflict, + OUT PBOOLEAN ConflictDetected); + +NTOSAPI +NTSTATUS +DDKAPI +IoReportTargetDeviceChange( + IN PDEVICE_OBJECT PhysicalDeviceObject, + IN PVOID NotificationStructure); + +NTOSAPI +NTSTATUS +DDKAPI +IoReportTargetDeviceChangeAsynchronous( + IN PDEVICE_OBJECT PhysicalDeviceObject, + IN PVOID NotificationStructure, + IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL, + IN PVOID Context OPTIONAL); + +NTOSAPI +VOID +DDKAPI +IoRequestDeviceEject( + IN PDEVICE_OBJECT PhysicalDeviceObject); + +/* + * VOID + * IoRequestDpc( + * IN PDEVICE_OBJECT DeviceObject, + * IN PIRP Irp, + * IN PVOID Context); + */ +#define IoRequestDpc(DeviceObject, Irp, Context)( \ + KeInsertQueueDpc(&(DeviceObject)->Dpc, (Irp), (Context))) + +NTOSAPI +VOID +DDKAPI +IoReuseIrp( + IN OUT PIRP Irp, + IN NTSTATUS Status); + +/* + * PDRIVER_CANCEL + * IoSetCancelRoutine( + * IN PIRP Irp, + * IN PDRIVER_CANCEL CancelRoutine) + */ +#define IoSetCancelRoutine(_Irp, \ + _CancelRoutine) \ + (PDRIVER_CANCEL) InterlockedExchangePointer( \ + (PVOID *) &(_Irp)->CancelRoutine, (PVOID) (_CancelRoutine)); + +/* + * VOID + * IoSetCompletionRoutine( + * IN PIRP Irp, + * IN PIO_COMPLETION_ROUTINE CompletionRoutine, + * IN PVOID Context, + * IN BOOLEAN InvokeOnSuccess, + * IN BOOLEAN InvokeOnError, + * IN BOOLEAN InvokeOnCancel) + */ +#define IoSetCompletionRoutine(_Irp, \ + _CompletionRoutine, \ + _Context, \ + _InvokeOnSuccess, \ + _InvokeOnError, \ + _InvokeOnCancel) \ +{ \ + PIO_STACK_LOCATION _IrpSp; \ + assert(_InvokeOnSuccess || _InvokeOnError || _InvokeOnCancel ? \ + _CompletionRoutine != NULL : TRUE); \ + _IrpSp = IoGetNextIrpStackLocation(_Irp); \ + _IrpSp->CompletionRoutine = (_CompletionRoutine); \ + _IrpSp->Context = (_Context); \ + _IrpSp->Control = 0; \ + if (_InvokeOnSuccess) _IrpSp->Control = SL_INVOKE_ON_SUCCESS; \ + if (_InvokeOnError) _IrpSp->Control |= SL_INVOKE_ON_ERROR; \ + if (_InvokeOnCancel) _IrpSp->Control |= SL_INVOKE_ON_CANCEL; \ +} + +NTOSAPI +VOID +DDKAPI +IoSetCompletionRoutineEx( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PIO_COMPLETION_ROUTINE CompletionRoutine, + IN PVOID Context, + IN BOOLEAN InvokeOnSuccess, + IN BOOLEAN InvokeOnError, + IN BOOLEAN InvokeOnCancel); + +NTOSAPI +NTSTATUS +DDKAPI +IoSetDeviceInterfaceState( + IN PUNICODE_STRING SymbolicLinkName, + IN BOOLEAN Enable); + +NTOSAPI +VOID +DDKAPI +IoSetHardErrorOrVerifyDevice( + IN PIRP Irp, + IN PDEVICE_OBJECT DeviceObject); + +/* + * VOID + * IoSetNextIrpStackLocation( + * IN OUT PIRP Irp) + */ +#define IoSetNextIrpStackLocation(_Irp) \ +{ \ + (_Irp)->CurrentLocation--; \ + (_Irp)->Tail.Overlay.CurrentStackLocation--; \ +} + +NTOSAPI +NTSTATUS +DDKAPI +IoSetPartitionInformationEx( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG PartitionNumber, + IN struct _SET_PARTITION_INFORMATION_EX *PartitionInfo); + +NTOSAPI +VOID +DDKAPI +IoSetShareAccess( + IN ACCESS_MASK DesiredAccess, + IN ULONG DesiredShareAccess, + IN OUT PFILE_OBJECT FileObject, + OUT PSHARE_ACCESS ShareAccess); + +NTOSAPI +VOID +DDKAPI +IoSetStartIoAttributes( + IN PDEVICE_OBJECT DeviceObject, + IN BOOLEAN DeferredStartIo, + IN BOOLEAN NonCancelable); + +NTOSAPI +NTSTATUS +DDKAPI +IoSetSystemPartition( + IN PUNICODE_STRING VolumeNameString); + +NTOSAPI +BOOLEAN +DDKAPI +IoSetThreadHardErrorMode( + IN BOOLEAN EnableHardErrors); + +/* + * USHORT + * IoSizeOfIrp( + * IN CCHAR StackSize) + */ +#define IoSizeOfIrp(_StackSize) \ + ((USHORT) (sizeof(IRP) + ((_StackSize) * (sizeof(IO_STACK_LOCATION))))) + +/* + * VOID + * IoSkipCurrentIrpStackLocation( + * IN PIRP Irp) + */ +#define IoSkipCurrentIrpStackLocation(_Irp) \ +{ \ + (_Irp)->CurrentLocation++; \ + (_Irp)->Tail.Overlay.CurrentStackLocation++; \ +} + +NTOSAPI +VOID +DDKAPI +IoStartNextPacket( + IN PDEVICE_OBJECT DeviceObject, + IN BOOLEAN Cancelable); + +NTOSAPI +VOID +DDKAPI +IoStartNextPacketByKey( + IN PDEVICE_OBJECT DeviceObject, + IN BOOLEAN Cancelable, + IN ULONG Key); + +NTOSAPI +VOID +DDKAPI +IoStartPacket( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PULONG Key OPTIONAL, + IN PDRIVER_CANCEL CancelFunction OPTIONAL); + +NTOSAPI +VOID +DDKAPI +IoStartTimer( + IN PDEVICE_OBJECT DeviceObject); + +NTOSAPI +VOID +DDKAPI +IoStopTimer( + IN PDEVICE_OBJECT DeviceObject); + +NTOSAPI +NTSTATUS +DDKAPI +IoUnregisterPlugPlayNotification( + IN PVOID NotificationEntry); + +NTOSAPI +VOID +DDKAPI +IoUnregisterShutdownNotification( + IN PDEVICE_OBJECT DeviceObject); + +NTOSAPI +VOID +DDKAPI +IoUpdateShareAccess( + IN PFILE_OBJECT FileObject, + IN OUT PSHARE_ACCESS ShareAccess); + +NTOSAPI +NTSTATUS +DDKAPI +IoVerifyPartitionTable( + IN PDEVICE_OBJECT DeviceObject, + IN BOOLEAN FixErrors); + +NTOSAPI +NTSTATUS +DDKAPI +IoVolumeDeviceToDosName( + IN PVOID VolumeDeviceObject, + OUT PUNICODE_STRING DosName); + +NTOSAPI +NTSTATUS +DDKAPI +IoWMIAllocateInstanceIds( + IN GUID *Guid, + IN ULONG InstanceCount, + OUT ULONG *FirstInstanceId); + +NTOSAPI +ULONG +DDKAPI +IoWMIDeviceObjectToProviderId( + IN PDEVICE_OBJECT DeviceObject); + +NTOSAPI +NTSTATUS +DDKAPI +IoWMIDeviceObjectToInstanceName( + IN PVOID DataBlockObject, + IN PDEVICE_OBJECT DeviceObject, + OUT PUNICODE_STRING InstanceName); + +NTOSAPI +NTSTATUS +DDKAPI +IoWMIExecuteMethod( + IN PVOID DataBlockObject, + IN PUNICODE_STRING InstanceName, + IN ULONG MethodId, + IN ULONG InBufferSize, + IN OUT PULONG OutBufferSize, + IN OUT PUCHAR InOutBuffer); + +NTOSAPI +NTSTATUS +DDKAPI +IoWMIHandleToInstanceName( + IN PVOID DataBlockObject, + IN HANDLE FileHandle, + OUT PUNICODE_STRING InstanceName); + +NTOSAPI +NTSTATUS +DDKAPI +IoWMIOpenBlock( + IN GUID *DataBlockGuid, + IN ULONG DesiredAccess, + OUT PVOID *DataBlockObject); + +NTOSAPI +NTSTATUS +DDKAPI +IoWMIQueryAllData( + IN PVOID DataBlockObject, + IN OUT ULONG *InOutBufferSize, + OUT PVOID OutBuffer); + +NTOSAPI +NTSTATUS +DDKAPI +IoWMIQueryAllDataMultiple( + IN PVOID *DataBlockObjectList, + IN ULONG ObjectCount, + IN OUT ULONG *InOutBufferSize, + OUT PVOID OutBuffer); + +NTOSAPI +NTSTATUS +DDKAPI +IoWMIQuerySingleInstance( + IN PVOID DataBlockObject, + IN PUNICODE_STRING InstanceName, + IN OUT ULONG *InOutBufferSize, + OUT PVOID OutBuffer); + +NTOSAPI +NTSTATUS +DDKAPI +IoWMIQuerySingleInstanceMultiple( + IN PVOID *DataBlockObjectList, + IN PUNICODE_STRING InstanceNames, + IN ULONG ObjectCount, + IN OUT ULONG *InOutBufferSize, + OUT PVOID OutBuffer); + +NTOSAPI +NTSTATUS +DDKAPI +IoWMIRegistrationControl( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG Action); + +NTOSAPI +NTSTATUS +DDKAPI +IoWMISetNotificationCallback( + IN PVOID Object, + IN WMI_NOTIFICATION_CALLBACK Callback, + IN PVOID Context); + +NTOSAPI +NTSTATUS +DDKAPI +IoWMISetSingleInstance( + IN PVOID DataBlockObject, + IN PUNICODE_STRING InstanceName, + IN ULONG Version, + IN ULONG ValueBufferSize, + IN PVOID ValueBuffer); + +NTOSAPI +NTSTATUS +DDKAPI +IoWMISetSingleItem( + IN PVOID DataBlockObject, + IN PUNICODE_STRING InstanceName, + IN ULONG DataItemId, + IN ULONG Version, + IN ULONG ValueBufferSize, + IN PVOID ValueBuffer); + +NTOSAPI +NTSTATUS +DDKAPI +IoWMISuggestInstanceName( + IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, + IN PUNICODE_STRING SymbolicLinkName OPTIONAL, + IN BOOLEAN CombineNames, + OUT PUNICODE_STRING SuggestedInstanceName); + +NTOSAPI +NTSTATUS +DDKAPI +IoWMIWriteEvent( + IN PVOID WnodeEventItem); + +NTOSAPI +VOID +DDKAPI +IoWriteErrorLogEntry( + IN PVOID ElEntry); + +NTOSAPI +NTSTATUS +DDKAPI +IoWritePartitionTableEx( + IN PDEVICE_OBJECT DeviceObject, + IN struct _DRIVE_LAYOUT_INFORMATION_EX *PartitionBuffer); + + + +/** Kernel routines **/ + +NTOSAPI +VOID +DDKFASTAPI +KeAcquireInStackQueuedSpinLock( + IN PKSPIN_LOCK SpinLock, + IN PKLOCK_QUEUE_HANDLE LockHandle); + +NTOSAPI +VOID +DDKFASTAPI +KeAcquireInStackQueuedSpinLockAtDpcLevel( + IN PKSPIN_LOCK SpinLock, + IN PKLOCK_QUEUE_HANDLE LockHandle); + +NTOSAPI +KIRQL +DDKAPI +KeAcquireInterruptSpinLock( + IN PKINTERRUPT Interrupt); + +NTOSAPI +VOID +DDKAPI +KeAcquireSpinLock( + IN PKSPIN_LOCK SpinLock, + OUT PKIRQL OldIrql); + +/* System Service Dispatch Table */ +typedef struct _SSDT { + ULONG SysCallPtr; +} SSDT, *PSSDT; + +/* System Service Parameters Table */ +typedef struct _SSPT { + ULONG ParamBytes; +} SSPT, *PSSPT; + +typedef struct _SSDT_ENTRY { + PSSDT SSDT; + PULONG ServiceCounterTable; + ULONG NumberOfServices; + PSSPT SSPT; +} SSDT_ENTRY, *PSSDT_ENTRY; + +NTOSAPI +BOOLEAN +DDKAPI +KeAddSystemServiceTable( + IN PSSDT SSDT, + IN PULONG ServiceCounterTable, + IN ULONG NumberOfServices, + IN PSSPT SSPT, + IN ULONG TableIndex); + +NTOSAPI +BOOLEAN +DDKAPI +KeAreApcsDisabled( + VOID); + +NTOSAPI +VOID +DDKAPI +KeAttachProcess( + IN PEPROCESS Process); + +NTOSAPI +VOID +DDKAPI +KeBugCheck( + IN ULONG BugCheckCode); + +NTOSAPI +VOID +DDKAPI +KeBugCheckEx( + IN ULONG BugCheckCode, + IN ULONG_PTR BugCheckParameter1, + IN ULONG_PTR BugCheckParameter2, + IN ULONG_PTR BugCheckParameter3, + IN ULONG_PTR BugCheckParameter4); + +NTOSAPI +BOOLEAN +DDKAPI +KeCancelTimer( + IN PKTIMER Timer); + +NTOSAPI +VOID +DDKAPI +KeClearEvent( + IN PRKEVENT Event); + +NTOSAPI +NTSTATUS +DDKAPI +KeDelayExecutionThread( + IN KPROCESSOR_MODE WaitMode, + IN BOOLEAN Alertable, + IN PLARGE_INTEGER Interval); + +NTOSAPI +BOOLEAN +DDKAPI +KeDeregisterBugCheckCallback( + IN PKBUGCHECK_CALLBACK_RECORD CallbackRecord); + +NTOSAPI +VOID +DDKAPI +KeDetachProcess( + VOID); + +NTOSAPI +VOID +DDKAPI +KeEnterCriticalRegion( + VOID); + +/* + * VOID + * KeFlushIoBuffers( + * IN PMDL Mdl, + * IN BOOLEAN ReadOperation, + * IN BOOLEAN DmaOperation) + */ +#define KeFlushIoBuffers(_Mdl, _ReadOperation, _DmaOperation) + +NTOSAPI +PRKTHREAD +DDKAPI +KeGetCurrentThread( + VOID); + +NTOSAPI +KPROCESSOR_MODE +DDKAPI +KeGetPreviousMode( + VOID); + +NTOSAPI +ULONG +DDKAPI +KeGetRecommendedSharedDataAlignment( + VOID); + +NTOSAPI +VOID +DDKAPI +KeInitializeApc( + IN PKAPC Apc, + IN PKTHREAD Thread, + IN UCHAR StateIndex, + IN PKKERNEL_ROUTINE KernelRoutine, + IN PKRUNDOWN_ROUTINE RundownRoutine, + IN PKNORMAL_ROUTINE NormalRoutine, + IN UCHAR Mode, + IN PVOID Context); + +NTOSAPI +VOID +DDKAPI +KeInitializeDeviceQueue( + IN PKDEVICE_QUEUE DeviceQueue); + +NTOSAPI +VOID +DDKAPI +KeInitializeMutex( + IN PRKMUTEX Mutex, + IN ULONG Level); + +NTOSAPI +VOID +DDKAPI +KeInitializeSemaphore( + IN PRKSEMAPHORE Semaphore, + IN LONG Count, + IN LONG Limit); + +NTOSAPI +VOID +DDKAPI +KeInitializeSpinLock( + IN PKSPIN_LOCK SpinLock); + +NTOSAPI +VOID +DDKAPI +KeInitializeTimer( + IN PKTIMER Timer); + +NTOSAPI +VOID +DDKAPI +KeInitializeTimerEx( + IN PKTIMER Timer, + IN TIMER_TYPE Type); + +NTOSAPI +BOOLEAN +DDKAPI +KeInsertByKeyDeviceQueue( + IN PKDEVICE_QUEUE DeviceQueue, + IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry, + IN ULONG SortKey); + +NTOSAPI +BOOLEAN +DDKAPI +KeInsertDeviceQueue( + IN PKDEVICE_QUEUE DeviceQueue, + IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry); + +NTOSAPI +BOOLEAN +DDKAPI +KeInsertQueueDpc( + IN PRKDPC Dpc, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2); + +NTOSAPI +VOID +DDKAPI +KeLeaveCriticalRegion( + VOID); + +NTOSAPI +VOID +DDKAPI +KeLowerIrql( + IN KIRQL NewIrql); + +NTOSAPI +NTSTATUS +DDKAPI +KePulseEvent( + IN PRKEVENT Event, + IN KPRIORITY Increment, + IN BOOLEAN Wait); + +NTOSAPI +ULONGLONG +DDKAPI +KeQueryInterruptTime( + VOID); + +NTOSAPI +LARGE_INTEGER +DDKAPI +KeQueryPerformanceCounter( + OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL); + +NTOSAPI +KPRIORITY +DDKAPI +KeQueryPriorityThread( + IN PRKTHREAD Thread); + +NTOSAPI +VOID +DDKAPI +KeQuerySystemTime( + OUT PLARGE_INTEGER CurrentTime); + +NTOSAPI +VOID +DDKAPI +KeQueryTickCount( + OUT PLARGE_INTEGER TickCount); + +NTOSAPI +ULONG +DDKAPI +KeQueryTimeIncrement( + VOID); + +NTOSAPI +VOID +DDKAPI +KeRaiseIrql( + IN KIRQL NewIrql, + OUT PKIRQL OldIrql); + +NTOSAPI +KIRQL +DDKAPI +KeRaiseIrqlToDpcLevel( + VOID); + +NTOSAPI +LONG +DDKAPI +KeReadStateEvent( + IN PRKEVENT Event); + +NTOSAPI +LONG +DDKAPI +KeReadStateMutex( + IN PRKMUTEX Mutex); + +NTOSAPI +LONG +DDKAPI +KeReadStateSemaphore( + IN PRKSEMAPHORE Semaphore); + +NTOSAPI +BOOLEAN +DDKAPI +KeReadStateTimer( + IN PKTIMER Timer); + +NTOSAPI +BOOLEAN +DDKAPI +KeRegisterBugCheckCallback( + IN PKBUGCHECK_CALLBACK_RECORD CallbackRecord, + IN PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine, + IN PVOID Buffer, + IN ULONG Length, + IN PUCHAR Component); + +NTOSAPI +VOID +DDKFASTAPI +KeReleaseInStackQueuedSpinLock( + IN PKLOCK_QUEUE_HANDLE LockHandle); + +NTOSAPI +VOID +DDKFASTAPI +KeReleaseInStackQueuedSpinLockFromDpcLevel( + IN PKLOCK_QUEUE_HANDLE LockHandle); + +NTOSAPI +VOID +DDKAPI +KeReleaseInterruptSpinLock( + IN PKINTERRUPT Interrupt, + IN KIRQL OldIrql); + +NTOSAPI +LONG +DDKAPI +KeReleaseMutex( + IN PRKMUTEX Mutex, + IN BOOLEAN Wait); + +NTOSAPI +LONG +DDKAPI +KeReleaseSemaphore( + IN PRKSEMAPHORE Semaphore, + IN KPRIORITY Increment, + IN LONG Adjustment, + IN BOOLEAN Wait); + +NTOSAPI +VOID +DDKAPI +KeReleaseSpinLock( + IN PKSPIN_LOCK SpinLock, + IN KIRQL NewIrql); + +NTOSAPI +PKDEVICE_QUEUE_ENTRY +DDKAPI +KeRemoveByKeyDeviceQueue( + IN PKDEVICE_QUEUE DeviceQueue, + IN ULONG SortKey); + +NTOSAPI +PKDEVICE_QUEUE_ENTRY +DDKAPI +KeRemoveDeviceQueue( + IN PKDEVICE_QUEUE DeviceQueue); + +NTOSAPI +BOOLEAN +DDKAPI +KeRemoveEntryDeviceQueue( + IN PKDEVICE_QUEUE DeviceQueue, + IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry); + +NTOSAPI +BOOLEAN +DDKAPI +KeRemoveQueueDpc( + IN PRKDPC Dpc); + +NTOSAPI +LONG +DDKAPI +KeResetEvent( + IN PRKEVENT Event); + +NTOSAPI +NTSTATUS +DDKAPI +KeRestoreFloatingPointState( + IN PKFLOATING_SAVE FloatSave); + +NTOSAPI +NTSTATUS +DDKAPI +KeSaveFloatingPointState( + OUT PKFLOATING_SAVE FloatSave); + +NTOSAPI +LONG +DDKAPI +KeSetBasePriorityThread( + IN PRKTHREAD Thread, + IN LONG Increment); + +NTOSAPI +LONG +DDKAPI +KeSetEvent( + IN PRKEVENT Event, + IN KPRIORITY Increment, + IN BOOLEAN Wait); + +NTOSAPI +VOID +DDKAPI +KeSetImportanceDpc( + IN PRKDPC Dpc, + IN KDPC_IMPORTANCE Importance); + +NTOSAPI +KPRIORITY +DDKAPI +KeSetPriorityThread( + IN PKTHREAD Thread, + IN KPRIORITY Priority); + +NTOSAPI +VOID +DDKAPI +KeSetTargetProcessorDpc( + IN PRKDPC Dpc, + IN CCHAR Number); + +NTOSAPI +BOOLEAN +DDKAPI +KeSetTimer( + IN PKTIMER Timer, + IN LARGE_INTEGER DueTime, + IN PKDPC Dpc OPTIONAL); + +NTOSAPI +BOOLEAN +DDKAPI +KeSetTimerEx( + IN PKTIMER Timer, + IN LARGE_INTEGER DueTime, + IN LONG Period OPTIONAL, + IN PKDPC Dpc OPTIONAL); + +NTOSAPI +VOID +DDKFASTAPI +KeSetTimeUpdateNotifyRoutine( + IN PTIME_UPDATE_NOTIFY_ROUTINE NotifyRoutine); + +NTOSAPI +VOID +DDKAPI +KeStallExecutionProcessor( + IN ULONG MicroSeconds); + +NTOSAPI +BOOLEAN +DDKAPI +KeSynchronizeExecution( + IN PKINTERRUPT Interrupt, + IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, + IN PVOID SynchronizeContext); + +NTOSAPI +NTSTATUS +DDKAPI +KeWaitForMultipleObjects( + IN ULONG Count, + IN PVOID Object[], + IN WAIT_TYPE WaitType, + IN KWAIT_REASON WaitReason, + IN KPROCESSOR_MODE WaitMode, + IN BOOLEAN Alertable, + IN PLARGE_INTEGER Timeout OPTIONAL, + IN PKWAIT_BLOCK WaitBlockArray OPTIONAL); + +NTOSAPI +NTSTATUS +DDKAPI +KeWaitForMutexObject( + IN PRKMUTEX Mutex, + IN KWAIT_REASON WaitReason, + IN KPROCESSOR_MODE WaitMode, + IN BOOLEAN Alertable, + IN PLARGE_INTEGER Timeout OPTIONAL); + +NTOSAPI +NTSTATUS +DDKAPI +KeWaitForSingleObject( + IN PVOID Object, + IN KWAIT_REASON WaitReason, + IN KPROCESSOR_MODE WaitMode, + IN BOOLEAN Alertable, + IN PLARGE_INTEGER Timeout OPTIONAL); + + + +/** Memory manager routines **/ + +NTOSAPI +NTSTATUS +DDKAPI +MmAdvanceMdl( + IN PMDL Mdl, + IN ULONG NumberOfBytes); + +NTOSAPI +PVOID +DDKAPI +MmAllocateContiguousMemory( + IN ULONG NumberOfBytes, + IN PHYSICAL_ADDRESS HighestAcceptableAddress); + +NTOSAPI +PVOID +DDKAPI +MmAllocateContiguousMemorySpecifyCache( + IN SIZE_T NumberOfBytes, + IN PHYSICAL_ADDRESS LowestAcceptableAddress, + IN PHYSICAL_ADDRESS HighestAcceptableAddress, + IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL, + IN MEMORY_CACHING_TYPE CacheType); + +NTOSAPI +PVOID +DDKAPI +MmAllocateMappingAddress( + IN SIZE_T NumberOfBytes, + IN ULONG PoolTag); + +NTOSAPI +PVOID +DDKAPI +MmAllocateNonCachedMemory( + IN ULONG NumberOfBytes); + +NTOSAPI +PMDL +DDKAPI +MmAllocatePagesForMdl( + IN PHYSICAL_ADDRESS LowAddress, + IN PHYSICAL_ADDRESS HighAddress, + IN PHYSICAL_ADDRESS SkipBytes, + IN SIZE_T TotalBytes); + +NTOSAPI +VOID +DDKAPI +MmBuildMdlForNonPagedPool( + IN OUT PMDL MemoryDescriptorList); + +NTOSAPI +NTSTATUS +DDKAPI +MmCreateSection( + OUT PSECTION_OBJECT *SectionObject, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN PLARGE_INTEGER MaximumSize, + IN ULONG SectionPageProtection, + IN ULONG AllocationAttributes, + IN HANDLE FileHandle OPTIONAL, + IN PFILE_OBJECT File OPTIONAL); + +typedef enum _MMFLUSH_TYPE { + MmFlushForDelete, + MmFlushForWrite +} MMFLUSH_TYPE; + +NTOSAPI +BOOLEAN +DDKAPI +MmFlushImageSection( + IN PSECTION_OBJECT_POINTERS SectionObjectPointer, + IN MMFLUSH_TYPE FlushType); + +NTOSAPI +VOID +DDKAPI +MmFreeContiguousMemory( + IN PVOID BaseAddress); + +NTOSAPI +VOID +DDKAPI +MmFreeContiguousMemorySpecifyCache( + IN PVOID BaseAddress, + IN SIZE_T NumberOfBytes, + IN MEMORY_CACHING_TYPE CacheType); + +NTOSAPI +VOID +DDKAPI +MmFreeMappingAddress( + IN PVOID BaseAddress, + IN ULONG PoolTag); + +NTOSAPI +VOID +DDKAPI +MmFreeNonCachedMemory( + IN PVOID BaseAddress, + IN SIZE_T NumberOfBytes); + +NTOSAPI +VOID +DDKAPI +MmFreePagesFromMdl( + IN PMDL MemoryDescriptorList); + +/* + * ULONG + * MmGetMdlByteCount( + * IN PMDL Mdl) + */ +#define MmGetMdlByteCount(_Mdl) \ + ((_Mdl)->ByteCount) + +/* + * ULONG + * MmGetMdlByteOffset( + * IN PMDL Mdl) + */ +#define MmGetMdlByteOffset(_Mdl) \ + ((_Mdl)->ByteOffset) + +/* + * PPFN_NUMBER + * MmGetMdlPfnArray( + * IN PMDL Mdl) + */ +#define MmGetMdlPfnArray(_Mdl) \ + ((PPFN_NUMBER) ((_Mdl) + 1)) + +/* + * PVOID + * MmGetMdlVirtualAddress( + * IN PMDL Mdl) + */ +#define MmGetMdlVirtualAddress(_Mdl) \ + ((PVOID) ((PCHAR) ((_Mdl)->StartVa) + (_Mdl)->ByteOffset)) + +NTOSAPI +PHYSICAL_ADDRESS +DDKAPI +MmGetPhysicalAddress( + IN PVOID BaseAddress); + +NTOSAPI +PPHYSICAL_MEMORY_RANGE +DDKAPI +MmGetPhysicalMemoryRanges( + VOID); + +NTOSAPI +PVOID +DDKAPI +MmGetVirtualForPhysical( + IN PHYSICAL_ADDRESS PhysicalAddress); + +NTOSAPI +PVOID +DDKAPI +MmMapLockedPagesSpecifyCache( + IN PMDL MemoryDescriptorList, + IN KPROCESSOR_MODE AccessMode, + IN MEMORY_CACHING_TYPE CacheType, + IN PVOID BaseAddress, + IN ULONG BugCheckOnFailure, + IN MM_PAGE_PRIORITY Priority); + +NTOSAPI +PVOID +DDKAPI +MmMapLockedPagesWithReservedMapping( + IN PVOID MappingAddress, + IN ULONG PoolTag, + IN PMDL MemoryDescriptorList, + IN MEMORY_CACHING_TYPE CacheType); + +NTOSAPI +NTSTATUS +DDKAPI +MmMapUserAddressesToPage( + IN PVOID BaseAddress, + IN SIZE_T NumberOfBytes, + IN PVOID PageAddress); + +NTOSAPI +PVOID +DDKAPI +MmMapVideoDisplay( + IN PHYSICAL_ADDRESS PhysicalAddress, + IN SIZE_T NumberOfBytes, + IN MEMORY_CACHING_TYPE CacheType); + +NTOSAPI +NTSTATUS +DDKAPI +MmMapViewInSessionSpace( + IN PVOID Section, + OUT PVOID *MappedBase, + IN OUT PSIZE_T ViewSize); + +NTOSAPI +NTSTATUS +DDKAPI +MmMapViewInSystemSpace( + IN PVOID Section, + OUT PVOID *MappedBase, + IN PSIZE_T ViewSize); + +NTOSAPI +NTSTATUS +DDKAPI +MmMarkPhysicalMemoryAsBad( + IN PPHYSICAL_ADDRESS StartAddress, + IN OUT PLARGE_INTEGER NumberOfBytes); + +NTOSAPI +NTSTATUS +DDKAPI +MmMarkPhysicalMemoryAsGood( + IN PPHYSICAL_ADDRESS StartAddress, + IN OUT PLARGE_INTEGER NumberOfBytes); + +/* + * PVOID + * MmGetSystemAddressForMdlSafe( + * IN PMDL Mdl, + * IN MM_PAGE_PRIORITY Priority) + */ +#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority) \ + ((_Mdl)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA \ + | MDL_SOURCE_IS_NONPAGED_POOL)) ? \ + (_Mdl)->MappedSystemVa : \ + (PVOID) MmMapLockedPagesSpecifyCache((_Mdl), \ + KernelMode, MmCached, NULL, FALSE, _Priority); + +NTOSAPI +PVOID +DDKAPI +MmGetSystemRoutineAddress( + IN PUNICODE_STRING SystemRoutineName); + +/* + * ULONG + * ADDRESS_AND_SIZE_TO_SPAN_PAGES( + * IN PVOID Va, + * IN ULONG Size) + */ +#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, \ + _Size) \ + (ULONG) ((((ULONG_PTR) (_Va) & (PAGE_SIZE - 1)) \ + + (_Size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT) + +/* + * VOID + * MmInitializeMdl( + * IN PMDL MemoryDescriptorList, + * IN PVOID BaseVa, + * IN SIZE_T Length) + */ +#define MmInitializeMdl(_MemoryDescriptorList, \ + _BaseVa, \ + _Length) \ +{ \ + (_MemoryDescriptorList)->Next = (PMDL) NULL; \ + (_MemoryDescriptorList)->Size = (CSHORT) (sizeof(MDL) + \ + (sizeof(PFN_NUMBER) * ADDRESS_AND_SIZE_TO_SPAN_PAGES(_BaseVa, _Length))); \ + (_MemoryDescriptorList)->MdlFlags = 0; \ + (_MemoryDescriptorList)->StartVa = (PVOID) PAGE_ALIGN(_BaseVa); \ + (_MemoryDescriptorList)->ByteOffset = BYTE_OFFSET(_BaseVa); \ + (_MemoryDescriptorList)->ByteCount = (ULONG) _Length; \ +} + +NTOSAPI +BOOLEAN +DDKAPI +MmIsAddressValid( + IN PVOID VirtualAddress); + +NTOSAPI +LOGICAL +DDKAPI +MmIsDriverVerifying( + IN PDRIVER_OBJECT DriverObject); + +NTOSAPI +BOOLEAN +DDKAPI +MmIsThisAnNtAsSystem( + VOID); + +NTOSAPI +NTSTATUS +DDKAPI +MmIsVerifierEnabled( + OUT PULONG VerifierFlags); + +NTOSAPI +PVOID +DDKAPI +MmLockPagableDataSection( + IN PVOID AddressWithinSection); + +NTOSAPI +PVOID +DDKAPI +MmLockPagableImageSection( + IN PVOID AddressWithinSection); + +/* + * PVOID + * MmLockPagableCodeSection( + * IN PVOID AddressWithinSection) + */ +#define MmLockPagableCodeSection MmLockPagableDataSection + +NTOSAPI +VOID +DDKAPI +MmLockPagableSectionByHandle( + IN PVOID ImageSectionHandle); + +NTOSAPI +PVOID +DDKAPI +MmMapIoSpace( + IN PHYSICAL_ADDRESS PhysicalAddress, + IN ULONG NumberOfBytes, + IN MEMORY_CACHING_TYPE CacheEnable); + +NTOSAPI +PVOID +DDKAPI +MmMapLockedPages( + IN PMDL MemoryDescriptorList, + IN KPROCESSOR_MODE AccessMode); + +NTOSAPI +VOID +DDKAPI +MmPageEntireDriver( + IN PVOID AddressWithinSection); + +NTOSAPI +VOID +DDKAPI +MmProbeAndLockProcessPages( + IN OUT PMDL MemoryDescriptorList, + IN PEPROCESS Process, + IN KPROCESSOR_MODE AccessMode, + IN LOCK_OPERATION Operation); + +NTOSAPI +NTSTATUS +DDKAPI +MmProtectMdlSystemAddress( + IN PMDL MemoryDescriptorList, + IN ULONG NewProtect); + +NTOSAPI +VOID +DDKAPI +MmUnmapLockedPages( + IN PVOID BaseAddress, + IN PMDL MemoryDescriptorList); + +NTOSAPI +NTSTATUS +DDKAPI +MmUnmapViewInSessionSpace( + IN PVOID MappedBase); + +NTOSAPI +NTSTATUS +DDKAPI +MmUnmapViewInSystemSpace( + IN PVOID MappedBase); + +NTOSAPI +VOID +DDKAPI +MmUnsecureVirtualMemory( + IN HANDLE SecureHandle); + +/* + * VOID + * MmPrepareMdlForReuse( + * IN PMDL Mdl) + */ +#define MmPrepareMdlForReuse(_Mdl) \ +{ \ + if (((_Mdl)->MdlFlags & MDL_PARTIAL_HAS_BEEN_MAPPED) != 0) { \ + assert(((_Mdl)->MdlFlags & MDL_PARTIAL) != 0); \ + MmUnmapLockedPages((_Mdl)->MappedSystemVa, (_Mdl)); \ + } else if (((_Mdl)->MdlFlags & MDL_PARTIAL) == 0) { \ + assert(((_Mdl)->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) == 0); \ + } \ +} + +NTOSAPI +VOID +DDKAPI +MmProbeAndLockPages( + IN OUT PMDL MemoryDescriptorList, + IN KPROCESSOR_MODE AccessMode, + IN LOCK_OPERATION Operation); + +NTOSAPI +MM_SYSTEM_SIZE +DDKAPI +MmQuerySystemSize( + VOID); + +NTOSAPI +NTSTATUS +DDKAPI +MmRemovePhysicalMemory( + IN PPHYSICAL_ADDRESS StartAddress, + IN OUT PLARGE_INTEGER NumberOfBytes); + +NTOSAPI +VOID +DDKAPI +MmResetDriverPaging( + IN PVOID AddressWithinSection); + +NTOSAPI +HANDLE +DDKAPI +MmSecureVirtualMemory( + IN PVOID Address, + IN SIZE_T Size, + IN ULONG ProbeMode); + +NTOSAPI +ULONG +DDKAPI +MmSizeOfMdl( + IN PVOID Base, + IN SIZE_T Length); + +NTOSAPI +VOID +DDKAPI +MmUnlockPagableImageSection( + IN PVOID ImageSectionHandle); + +NTOSAPI +VOID +DDKAPI +MmUnlockPages( + IN PMDL MemoryDescriptorList); + +NTOSAPI +VOID +DDKAPI +MmUnmapIoSpace( + IN PVOID BaseAddress, + IN SIZE_T NumberOfBytes); + +NTOSAPI +VOID +DDKAPI +MmUnmapReservedMapping( + IN PVOID BaseAddress, + IN ULONG PoolTag, + IN PMDL MemoryDescriptorList); + +NTOSAPI +VOID +DDKAPI +MmUnmapVideoDisplay( + IN PVOID BaseAddress, + IN SIZE_T NumberOfBytes); + + + +/** Object manager routines **/ + +NTOSAPI +NTSTATUS +DDKAPI +ObAssignSecurity( + IN PACCESS_STATE AccessState, + IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN PVOID Object, + IN POBJECT_TYPE Type); + +NTOSAPI +VOID +DDKAPI +ObDereferenceSecurityDescriptor( + PSECURITY_DESCRIPTOR SecurityDescriptor, + ULONG Count); + +NTOSAPI +VOID +DDKFASTAPI +ObfDereferenceObject( + IN PVOID Object); + +/* + * VOID + * ObDereferenceObject( + * IN PVOID Object) + */ +#define ObDereferenceObject ObfDereferenceObject + +NTOSAPI +NTSTATUS +DDKAPI +ObGetObjectSecurity( + IN PVOID Object, + OUT PSECURITY_DESCRIPTOR *SecurityDescriptor, + OUT PBOOLEAN MemoryAllocated); + +NTOSAPI +NTSTATUS +DDKAPI +ObInsertObject( + IN PVOID Object, + IN PACCESS_STATE PassedAccessState OPTIONAL, + IN ACCESS_MASK DesiredAccess, + IN ULONG AdditionalReferences, + OUT PVOID* ReferencedObject OPTIONAL, + OUT PHANDLE Handle); + +NTOSAPI +VOID +DDKFASTAPI +ObfReferenceObject( + IN PVOID Object); + +NTOSAPI +NTSTATUS +DDKAPI +ObLogSecurityDescriptor( + IN PSECURITY_DESCRIPTOR InputSecurityDescriptor, + OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor, + IN ULONG RefBias); +/* + * VOID + * ObReferenceObject( + * IN PVOID Object) + */ +#define ObReferenceObject ObfReferenceObject + +NTOSAPI +VOID +DDKAPI +ObMakeTemporaryObject( + IN PVOID Object); + +NTOSAPI +NTSTATUS +DDKAPI +ObOpenObjectByName( + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN POBJECT_TYPE ObjectType, + IN OUT PVOID ParseContext OPTIONAL, + IN KPROCESSOR_MODE AccessMode, + IN ACCESS_MASK DesiredAccess, + IN PACCESS_STATE PassedAccessState, + OUT PHANDLE Handle); + +NTOSAPI +NTSTATUS +DDKAPI +ObOpenObjectByPointer( + IN PVOID Object, + IN ULONG HandleAttributes, + IN PACCESS_STATE PassedAccessState OPTIONAL, + IN ACCESS_MASK DesiredAccess OPTIONAL, + IN POBJECT_TYPE ObjectType OPTIONAL, + IN KPROCESSOR_MODE AccessMode, + OUT PHANDLE Handle); + +NTOSAPI +NTSTATUS +DDKAPI +ObQueryObjectAuditingByHandle( + IN HANDLE Handle, + OUT PBOOLEAN GenerateOnClose); + +NTOSAPI +NTSTATUS +DDKAPI +ObReferenceObjectByHandle( + IN HANDLE Handle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_TYPE ObjectType OPTIONAL, + IN KPROCESSOR_MODE AccessMode, + OUT PVOID *Object, + OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL); + +NTOSAPI +NTSTATUS +DDKAPI +ObReferenceObjectByName( + IN PUNICODE_STRING ObjectPath, + IN ULONG Attributes, + IN PACCESS_STATE PassedAccessState OPTIONAL, + IN ACCESS_MASK DesiredAccess OPTIONAL, + IN POBJECT_TYPE ObjectType, + IN KPROCESSOR_MODE AccessMode, + IN OUT PVOID ParseContext OPTIONAL, + OUT PVOID *Object); + +NTOSAPI +NTSTATUS +DDKAPI +ObReferenceObjectByPointer( + IN PVOID Object, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_TYPE ObjectType, + IN KPROCESSOR_MODE AccessMode); + +NTOSAPI +VOID +DDKAPI +ObReferenceSecurityDescriptor( + IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN ULONG Count); + +NTOSAPI +VOID +DDKAPI +ObReleaseObjectSecurity( + IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN BOOLEAN MemoryAllocated); + + + +/** Process manager routines **/ + +NTOSAPI +NTSTATUS +DDKAPI +PsCreateSystemProcess( + IN PHANDLE ProcessHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes); + +NTOSAPI +NTSTATUS +DDKAPI +PsCreateSystemThread( + OUT PHANDLE ThreadHandle, + IN ULONG DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN HANDLE ProcessHandle OPTIONAL, + OUT PCLIENT_ID ClientId OPTIONAL, + IN PKSTART_ROUTINE StartRoutine, + IN PVOID StartContext); + +/* + * PEPROCESS + * PsGetCurrentProcess(VOID) + */ +#define PsGetCurrentProcess IoGetCurrentProcess + +NTOSAPI +HANDLE +DDKAPI +PsGetCurrentProcessId( + VOID); + +/* + * PETHREAD + * PsGetCurrentThread(VOID) + */ +#define PsGetCurrentThread() \ + ((PETHREAD) KeGetCurrentThread()) + +NTOSAPI +HANDLE +DDKAPI +PsGetCurrentThreadId( + VOID); + +NTOSAPI +BOOLEAN +DDKAPI +PsGetVersion( + PULONG MajorVersion OPTIONAL, + PULONG MinorVersion OPTIONAL, + PULONG BuildNumber OPTIONAL, + PUNICODE_STRING CSDVersion OPTIONAL); + +NTOSAPI +NTSTATUS +DDKAPI +PsRemoveCreateThreadNotifyRoutine( + IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine); + +NTOSAPI +NTSTATUS +DDKAPI +PsRemoveLoadImageNotifyRoutine( + IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine); + +NTOSAPI +NTSTATUS +DDKAPI +PsSetCreateProcessNotifyRoutine( + IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine, + IN BOOLEAN Remove); + +NTOSAPI +NTSTATUS +DDKAPI +PsSetCreateThreadNotifyRoutine( + IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine); + +NTOSAPI +NTSTATUS +DDKAPI +PsSetLoadImageNotifyRoutine( + IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine); + +NTOSAPI +NTSTATUS +DDKAPI +PsTerminateSystemThread( + IN NTSTATUS ExitStatus); + + + +/** Security reference monitor routines **/ + +NTOSAPI +BOOLEAN +DDKAPI +SeAccessCheck( + IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, + IN BOOLEAN SubjectContextLocked, + IN ACCESS_MASK DesiredAccess, + IN ACCESS_MASK PreviouslyGrantedAccess, + OUT PPRIVILEGE_SET *Privileges OPTIONAL, + IN PGENERIC_MAPPING GenericMapping, + IN KPROCESSOR_MODE AccessMode, + OUT PACCESS_MASK GrantedAccess, + OUT PNTSTATUS AccessStatus); + +NTOSAPI +NTSTATUS +DDKAPI +SeAssignSecurity( + IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, + IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL, + OUT PSECURITY_DESCRIPTOR *NewDescriptor, + IN BOOLEAN IsDirectoryObject, + IN PSECURITY_SUBJECT_CONTEXT SubjectContext, + IN PGENERIC_MAPPING GenericMapping, + IN POOL_TYPE PoolType); + +NTOSAPI +NTSTATUS +DDKAPI +SeAssignSecurityEx( + IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, + IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL, + OUT PSECURITY_DESCRIPTOR *NewDescriptor, + IN GUID *ObjectType OPTIONAL, + IN BOOLEAN IsDirectoryObject, + IN ULONG AutoInheritFlags, + IN PSECURITY_SUBJECT_CONTEXT SubjectContext, + IN PGENERIC_MAPPING GenericMapping, + IN POOL_TYPE PoolType); + +NTOSAPI +NTSTATUS +DDKAPI +SeDeassignSecurity( + IN OUT PSECURITY_DESCRIPTOR *SecurityDescriptor); + +NTOSAPI +BOOLEAN +DDKAPI +SeSinglePrivilegeCheck( + LUID PrivilegeValue, + KPROCESSOR_MODE PreviousMode); + +NTOSAPI +BOOLEAN +DDKAPI +SeValidSecurityDescriptor( + IN ULONG Length, + IN PSECURITY_DESCRIPTOR SecurityDescriptor); + + + +/** NtXxx routines **/ + +NTOSAPI +NTSTATUS +DDKAPI +NtOpenProcess( + OUT PHANDLE ProcessHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN PCLIENT_ID ClientId OPTIONAL); + +NTOSAPI +NTSTATUS +DDKAPI +NtQueryInformationProcess( + IN HANDLE ProcessHandle, + IN PROCESSINFOCLASS ProcessInformationClass, + OUT PVOID ProcessInformation, + IN ULONG ProcessInformationLength, + OUT PULONG ReturnLength OPTIONAL); + + + +/** NtXxx and ZwXxx routines **/ + +NTOSAPI +NTSTATUS +DDKAPI +ZwCancelTimer( + IN HANDLE TimerHandle, + OUT PBOOLEAN CurrentState OPTIONAL); + +NTOSAPI +NTSTATUS +DDKAPI +NtClose( + IN HANDLE Handle); + +NTOSAPI +NTSTATUS +DDKAPI +ZwClose( + IN HANDLE Handle); + +NTOSAPI +NTSTATUS +DDKAPI +ZwCreateDirectoryObject( + OUT PHANDLE DirectoryHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes); + +NTOSAPI +NTSTATUS +DDKAPI +NtCreateEvent( + OUT PHANDLE EventHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN BOOLEAN ManualReset, + IN BOOLEAN InitialState); + +NTOSAPI +NTSTATUS +DDKAPI +ZwCreateEvent( + OUT PHANDLE EventHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN BOOLEAN ManualReset, + IN BOOLEAN InitialState); + +NTOSAPI +NTSTATUS +DDKAPI +ZwCreateFile( + OUT PHANDLE FileHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PLARGE_INTEGER AllocationSize OPTIONAL, + IN ULONG FileAttributes, + IN ULONG ShareAccess, + IN ULONG CreateDisposition, + IN ULONG CreateOptions, + IN PVOID EaBuffer OPTIONAL, + IN ULONG EaLength); + +NTOSAPI +NTSTATUS +DDKAPI +ZwCreateKey( + OUT PHANDLE KeyHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG TitleIndex, + IN PUNICODE_STRING Class OPTIONAL, + IN ULONG CreateOptions, + OUT PULONG Disposition OPTIONAL); + +NTOSAPI +NTSTATUS +DDKAPI +ZwCreateTimer( + OUT PHANDLE TimerHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN TIMER_TYPE TimerType); + +NTOSAPI +NTSTATUS +DDKAPI +ZwDeleteKey( + IN HANDLE KeyHandle); + +NTOSAPI +NTSTATUS +DDKAPI +ZwDeleteValueKey( + IN HANDLE KeyHandle, + IN PUNICODE_STRING ValueName); + +NTOSAPI +NTSTATUS +DDKAPI +NtDeviceIoControlFile( + IN HANDLE DeviceHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL, + IN PVOID UserApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG IoControlCode, + IN PVOID InputBuffer, + IN ULONG InputBufferSize, + OUT PVOID OutputBuffer, + IN ULONG OutputBufferSize); + +NTOSAPI +NTSTATUS +DDKAPI +ZwDeviceIoControlFile( + IN HANDLE DeviceHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL, + IN PVOID UserApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG IoControlCode, + IN PVOID InputBuffer, + IN ULONG InputBufferSize, + OUT PVOID OutputBuffer, + IN ULONG OutputBufferSize); + +NTOSAPI +NTSTATUS +DDKAPI +ZwEnumerateKey( + IN HANDLE KeyHandle, + IN ULONG Index, + IN KEY_INFORMATION_CLASS KeyInformationClass, + OUT PVOID KeyInformation, + IN ULONG Length, + OUT PULONG ResultLength); + +NTOSAPI +NTSTATUS +DDKAPI +ZwEnumerateValueKey( + IN HANDLE KeyHandle, + IN ULONG Index, + IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, + OUT PVOID KeyValueInformation, + IN ULONG Length, + OUT PULONG ResultLength); + +NTOSAPI +NTSTATUS +DDKAPI +ZwFlushKey( + IN HANDLE KeyHandle); + +NTOSAPI +NTSTATUS +DDKAPI +ZwMakeTemporaryObject( + IN HANDLE Handle); + +NTOSAPI +NTSTATUS +DDKAPI +NtMapViewOfSection( + IN HANDLE SectionHandle, + IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN ULONG ZeroBits, + IN ULONG CommitSize, + IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, + IN OUT PSIZE_T ViewSize, + IN SECTION_INHERIT InheritDisposition, + IN ULONG AllocationType, + IN ULONG Protect); + +NTOSAPI +NTSTATUS +DDKAPI +ZwMapViewOfSection( + IN HANDLE SectionHandle, + IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN ULONG ZeroBits, + IN ULONG CommitSize, + IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, + IN OUT PSIZE_T ViewSize, + IN SECTION_INHERIT InheritDisposition, + IN ULONG AllocationType, + IN ULONG Protect); + +NTOSAPI +NTSTATUS +DDKAPI +NtOpenFile( + OUT PHANDLE FileHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG ShareAccess, + IN ULONG OpenOptions); + +NTOSAPI +NTSTATUS +DDKAPI +ZwOpenFile( + OUT PHANDLE FileHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG ShareAccess, + IN ULONG OpenOptions); + +NTOSAPI +NTSTATUS +DDKAPI +ZwOpenKey( + OUT PHANDLE KeyHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes); + +NTOSAPI +NTSTATUS +DDKAPI +ZwOpenSection( + OUT PHANDLE SectionHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes); + +NTOSAPI +NTSTATUS +DDKAPI +ZwOpenSymbolicLinkObject( + OUT PHANDLE LinkHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes); + +NTOSAPI +NTSTATUS +DDKAPI +ZwOpenTimer( + OUT PHANDLE TimerHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes); + +NTOSAPI +NTSTATUS +DDKAPI +ZwQueryInformationFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID FileInformation, + IN ULONG Length, + IN FILE_INFORMATION_CLASS FileInformationClass); + +NTOSAPI +NTSTATUS +DDKAPI +ZwQueryKey( + IN HANDLE KeyHandle, + IN KEY_INFORMATION_CLASS KeyInformationClass, + OUT PVOID KeyInformation, + IN ULONG Length, + OUT PULONG ResultLength); + +NTOSAPI +NTSTATUS +DDKAPI +ZwQuerySymbolicLinkObject( + IN HANDLE LinkHandle, + IN OUT PUNICODE_STRING LinkTarget, + OUT PULONG ReturnedLength OPTIONAL); + +NTOSAPI +NTSTATUS +DDKAPI +ZwQueryValueKey( + IN HANDLE KeyHandle, + IN PUNICODE_STRING ValueName, + IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, + OUT PVOID KeyValueInformation, + IN ULONG Length, + OUT PULONG ResultLength); + +NTOSAPI +NTSTATUS +DDKAPI +NtReadFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID Buffer, + IN ULONG Length, + IN PLARGE_INTEGER ByteOffset OPTIONAL, + IN PULONG Key OPTIONAL); + +NTOSAPI +NTSTATUS +DDKAPI +ZwReadFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID Buffer, + IN ULONG Length, + IN PLARGE_INTEGER ByteOffset OPTIONAL, + IN PULONG Key OPTIONAL); + +NTOSAPI +NTSTATUS +DDKAPI +NtSetEvent( + IN HANDLE EventHandle, + IN PULONG NumberOfThreadsReleased); + +NTOSAPI +NTSTATUS +DDKAPI +ZwSetEvent( + IN HANDLE EventHandle, + IN PULONG NumberOfThreadsReleased); + +NTOSAPI +NTSTATUS +DDKAPI +ZwSetInformationFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PVOID FileInformation, + IN ULONG Length, + IN FILE_INFORMATION_CLASS FileInformationClass); + +NTOSAPI +NTSTATUS +DDKAPI +ZwSetInformationThread( + IN HANDLE ThreadHandle, + IN THREADINFOCLASS ThreadInformationClass, + IN PVOID ThreadInformation, + IN ULONG ThreadInformationLength); + +NTOSAPI +NTSTATUS +DDKAPI +ZwSetTimer( + IN HANDLE TimerHandle, + IN PLARGE_INTEGER DueTime, + IN PTIMER_APC_ROUTINE TimerApcRoutine OPTIONAL, + IN PVOID TimerContext OPTIONAL, + IN BOOLEAN WakeTimer, + IN LONG Period OPTIONAL, + OUT PBOOLEAN PreviousState OPTIONAL); + +NTOSAPI +NTSTATUS +DDKAPI +ZwSetValueKey( + IN HANDLE KeyHandle, + IN PUNICODE_STRING ValueName, + IN ULONG TitleIndex OPTIONAL, + IN ULONG Type, + IN PVOID Data, + IN ULONG DataSize); + +/* [Nt|Zw]MapViewOfSection.InheritDisposition constants */ +#define AT_EXTENDABLE_FILE 0x00002000 +#define SEC_NO_CHANGE 0x00400000 +#define AT_RESERVED 0x20000000 +#define AT_ROUND_TO_PAGE 0x40000000 + +NTOSAPI +NTSTATUS +DDKAPI +NtUnmapViewOfSection( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress); + +NTOSAPI +NTSTATUS +DDKAPI +ZwUnmapViewOfSection( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress); + +NTOSAPI +NTSTATUS +DDKAPI +NtWaitForSingleObject( + IN HANDLE Object, + IN BOOLEAN Alertable, + IN PLARGE_INTEGER Time); + +NTOSAPI +NTSTATUS +DDKAPI +ZwWaitForSingleObject( + IN HANDLE Object, + IN BOOLEAN Alertable, + IN PLARGE_INTEGER Time); + +NTOSAPI +NTSTATUS +DDKAPI +NtWriteFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PVOID Buffer, + IN ULONG Length, + IN PLARGE_INTEGER ByteOffset OPTIONAL, + IN PULONG Key OPTIONAL); + +NTOSAPI +NTSTATUS +DDKAPI +ZwWriteFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PVOID Buffer, + IN ULONG Length, + IN PLARGE_INTEGER ByteOffset OPTIONAL, + IN PULONG Key OPTIONAL); + + + +/** Power management support routines **/ + +NTOSAPI +NTSTATUS +DDKAPI +PoCallDriver( + IN PDEVICE_OBJECT DeviceObject, + IN OUT PIRP Irp); + +NTOSAPI +PULONG +DDKAPI +PoRegisterDeviceForIdleDetection( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG ConservationIdleTime, + IN ULONG PerformanceIdleTime, + IN DEVICE_POWER_STATE State); + +NTOSAPI +PVOID +DDKAPI +PoRegisterSystemState( + IN PVOID StateHandle, + IN EXECUTION_STATE Flags); + +NTOSAPI +NTSTATUS +DDKAPI +PoRequestPowerIrp( + IN PDEVICE_OBJECT DeviceObject, + IN UCHAR MinorFunction, + IN POWER_STATE PowerState, + IN PREQUEST_POWER_COMPLETE CompletionFunction, + IN PVOID Context, + OUT PIRP *Irp OPTIONAL); + +NTOSAPI +NTSTATUS +DDKAPI +PoRequestShutdownEvent( + OUT PVOID *Event); + +NTOSAPI +VOID +DDKAPI +PoSetDeviceBusy( + PULONG IdlePointer); + +NTOSAPI +POWER_STATE +DDKAPI +PoSetPowerState( + IN PDEVICE_OBJECT DeviceObject, + IN POWER_STATE_TYPE Type, + IN POWER_STATE State); + +NTOSAPI +VOID +DDKAPI +PoSetSystemState( + IN EXECUTION_STATE Flags); + +NTOSAPI +VOID +DDKAPI +PoStartNextPowerIrp( + IN PIRP Irp); + +NTOSAPI +VOID +DDKAPI +PoUnregisterSystemState( + IN PVOID StateHandle); + + + +/** WMI library support routines **/ + +NTOSAPI +NTSTATUS +DDKAPI +WmiCompleteRequest( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN NTSTATUS Status, + IN ULONG BufferUsed, + IN CCHAR PriorityBoost); + +NTOSAPI +NTSTATUS +DDKAPI +WmiFireEvent( + IN PDEVICE_OBJECT DeviceObject, + IN LPGUID Guid, + IN ULONG InstanceIndex, + IN ULONG EventDataSize, + IN PVOID EventData); + +NTOSAPI +NTSTATUS +DDKAPI +WmiQueryTraceInformation( + IN TRACE_INFORMATION_CLASS TraceInformationClass, + OUT PVOID TraceInformation, + IN ULONG TraceInformationLength, + OUT PULONG RequiredLength OPTIONAL, + IN PVOID Buffer OPTIONAL); + +NTOSAPI +NTSTATUS +DDKAPI +WmiSystemControl( + IN PWMILIB_CONTEXT WmiLibInfo, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + OUT PSYSCTL_IRP_DISPOSITION IrpDisposition); + +NTOSAPI +NTSTATUS +DDKCDECLAPI +WmiTraceMessage( + IN TRACEHANDLE LoggerHandle, + IN ULONG MessageFlags, + IN LPGUID MessageGuid, + IN USHORT MessageNumber, + IN ...); + +#if 0 +/* FIXME: Get va_list from where? */ +NTOSAPI +NTSTATUS +DDKCDECLAPI +WmiTraceMessageVa( + IN TRACEHANDLE LoggerHandle, + IN ULONG MessageFlags, + IN LPGUID MessageGuid, + IN USHORT MessageNumber, + IN va_list MessageArgList); +#endif + + +/** Kernel debugger routines **/ + +NTOSAPI +VOID +DDKAPI +KdDisableDebugger( + VOID); + +NTOSAPI +VOID +DDKAPI +KdEnableDebugger( + VOID); + +NTOSAPI +VOID +DDKAPI +DbgBreakPoint( + VOID); + +NTOSAPI +VOID +DDKAPI +DbgBreakPointWithStatus( + IN ULONG Status); + +NTOSAPI +ULONG +DDKCDECLAPI +DbgPrint( + IN PCH Format, + IN ...); + +NTOSAPI +ULONG +DDKCDECLAPI +DbgPrintEx( + IN ULONG ComponentId, + IN ULONG Level, + IN PCH Format, + IN ...); + +NTOSAPI +ULONG +DDKCDECLAPI +DbgPrintReturnControlC( + IN PCH Format, + IN ...); + +NTOSAPI +NTSTATUS +DDKAPI +DbgQueryDebugFilterState( + IN ULONG ComponentId, + IN ULONG Level); + +NTOSAPI +NTSTATUS +DDKAPI +DbgSetDebugFilterState( + IN ULONG ComponentId, + IN ULONG Level, + IN BOOLEAN State); + +#if DBG + +#define KdPrint(_x_) DbgPrint _x_ +#define KdPrintEx(_x_) DbgPrintEx _x_ +#define KdBreakPoint() DbgBreakPoint() +#define KdBreakPointWithStatus(s) DbgBreakPointWithStatus(s) + +#else /* !DBG */ + +#define KdPrint(_x_) +#define KdPrintEx(_x_) +#define KdBreakPoint() +#define KdBreakPointWithStatus(s) + +#endif /* !DBG */ + +extern NTOSAPI PBOOLEAN KdDebuggerNotPresent; +extern NTOSAPI PBOOLEAN KdDebuggerEnabled; +#define KD_DEBUGGER_ENABLED *KdDebuggerEnabled +#define KD_DEBUGGER_NOT_PRESENT *KdDebuggerNotPresent + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif + +#endif /* __WINDDK_H */ diff --git a/src/platform/visualc/winnt4.h b/src/platform/visualc/winnt4.h new file mode 100644 index 00000000..bbe8daf5 --- /dev/null +++ b/src/platform/visualc/winnt4.h @@ -0,0 +1,608 @@ +/* + * winnt4.h + * + * Definitions only used in Windows NT 4.0 and earlier versions + * + * This file is part of the w32api package. + * + * Contributors: + * Created by Casper S. Hornstrup + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef __WINNT4_H +#define __WINNT4_H + +#if __GNUC__ >=3 +#pragma GCC system_header +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#pragma pack(push,4) + +typedef struct _ZONE_SEGMENT_HEADER { + SINGLE_LIST_ENTRY SegmentList; + PVOID Reserved; +} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER; + +typedef struct _ZONE_HEADER { + SINGLE_LIST_ENTRY FreeList; + SINGLE_LIST_ENTRY SegmentList; + ULONG BlockSize; + ULONG TotalSegmentSize; +} ZONE_HEADER, *PZONE_HEADER; + +static inline PVOID +ExAllocateFromZone( + IN PZONE_HEADER Zone) +{ + if (Zone->FreeList.Next) + Zone->FreeList.Next = Zone->FreeList.Next->Next; + return (PVOID) Zone->FreeList.Next; +} + +NTOSAPI +NTSTATUS +DDKAPI +ExExtendZone( + IN PZONE_HEADER Zone, + IN PVOID Segment, + IN ULONG SegmentSize); + +static inline PVOID +ExFreeToZone( + IN PZONE_HEADER Zone, + IN PVOID Block) +{ + ((PSINGLE_LIST_ENTRY) Block)->Next = Zone->FreeList.Next; + Zone->FreeList.Next = ((PSINGLE_LIST_ENTRY) Block); + return ((PSINGLE_LIST_ENTRY) Block)->Next; +} + +NTOSAPI +NTSTATUS +DDKAPI +ExInitializeZone( + IN PZONE_HEADER Zone, + IN ULONG BlockSize, + IN PVOID InitialSegment, + IN ULONG InitialSegmentSize); + +/* + * PVOID + * ExInterlockedAllocateFromZone( + * IN PZONE_HEADER Zone, + * IN PKSPIN_LOCK Lock) + */ +#define ExInterlockedAllocateFromZone(Zone, \ + Lock) \ + ((PVOID) ExInterlockedPopEntryList(&Zone->FreeList, Lock)) + +NTOSAPI +NTSTATUS +DDKAPI +ExInterlockedExtendZone( + IN PZONE_HEADER Zone, + IN PVOID Segment, + IN ULONG SegmentSize, + IN PKSPIN_LOCK Lock); + +NTOSAPI +PVOID +DDKAPI +ExInterlockedFreeToZone( + IN PZONE_HEADER Zone, + IN PVOID Block, + IN PKSPIN_LOCK Lock); + +/* + * VOID + * ExInitializeWorkItem( + * IN PWORK_QUEUE_ITEM Item, + * IN PWORKER_THREAD_ROUTINE Routine, + * IN PVOID Context) + */ +#define ExInitializeWorkItem(Item, \ + Routine, \ + Context) \ +{ \ + (Item)->WorkerRoutine = Routine; \ + (Item)->Parameter = Context; \ + (Item)->List.Flink = NULL; \ +} + +/* + * BOOLEAN + * ExIsFullZone( + * IN PZONE_HEADER Zone) + */ +#define ExIsFullZone(Zone) \ + ((Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY) NULL) + +NTOSAPI +VOID +DDKAPI +ExQueueWorkItem( + IN PWORK_QUEUE_ITEM WorkItem, + IN WORK_QUEUE_TYPE QueueType); + +NTOSAPI +BOOLEAN +DDKAPI +ExIsObjectInFirstZoneSegment( + IN PZONE_HEADER Zone, + IN PVOID Object); + +NTOSAPI +VOID +DDKAPI +ExReleaseResource( + IN PERESOURCE Resource); + +#define ExAcquireResourceExclusive ExAcquireResourceExclusiveLite +#define ExAcquireResourceShared ExAcquireResourceSharedLite +#define ExConvertExclusiveToShared ExConvertExclusiveToSharedLite +#define ExDeleteResource ExDeleteResourceLite +#define ExInitializeResource ExInitializeResourceLite +#define ExIsResourceAcquiredExclusive ExIsResourceAcquiredExclusiveLite +#define ExIsResourceAcquiredShared ExIsResourceAcquiredSharedLite +#define ExIsResourceAcquired ExIsResourceAcquiredSharedLite +#define ExReleaseResourceForThread ExReleaseResourceForThreadLite + +NTOSAPI +INTERLOCKED_RESULT +DDKAPI +ExInterlockedDecrementLong( + IN PLONG Addend, + IN PKSPIN_LOCK Lock); + +NTOSAPI +ULONG +DDKAPI +ExInterlockedExchangeUlong( + IN PULONG Target, + IN ULONG Value, + IN PKSPIN_LOCK Lock); + +NTOSAPI +INTERLOCKED_RESULT +DDKAPI +ExInterlockedIncrementLong( + IN PLONG Addend, + IN PKSPIN_LOCK Lock); + +NTOSAPI +PVOID +DDKAPI +HalAllocateCommonBuffer( + IN PADAPTER_OBJECT AdapterObject, + IN ULONG Length, + OUT PPHYSICAL_ADDRESS LogicalAddress, + IN BOOLEAN CacheEnabled); + +NTOSAPI +NTSTATUS +DDKAPI +HalAssignSlotResources( + IN PUNICODE_STRING RegistryPath, + IN PUNICODE_STRING DriverClassName, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject, + IN INTERFACE_TYPE BusType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN OUT PCM_RESOURCE_LIST *AllocatedResources); + +NTOSAPI +VOID +DDKAPI +HalFreeCommonBuffer( + IN PADAPTER_OBJECT AdapterObject, + IN ULONG Length, + IN PHYSICAL_ADDRESS LogicalAddress, + IN PVOID VirtualAddress, + IN BOOLEAN CacheEnabled); + +NTOSAPI +PADAPTER_OBJECT +DDKAPI +HalGetAdapter( + IN PDEVICE_DESCRIPTION DeviceDescription, + IN OUT PULONG NumberOfMapRegisters); + +NTOSAPI +ULONG +DDKAPI +HalGetBusData( + IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Length); + +NTOSAPI +ULONG +DDKAPI +HalGetBusDataByOffset( + IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length); + +NTOSAPI +ULONG +DDKAPI +HalGetDmaAlignmentRequirement( + VOID); + +NTOSAPI +ULONG +DDKAPI +HalGetInterruptVector( + IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity); + +NTOSAPI +ULONG +DDKAPI +HalReadDmaCounter( + IN PADAPTER_OBJECT AdapterObject); + +NTOSAPI +ULONG +DDKAPI +HalSetBusData( + IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Length); + +NTOSAPI +ULONG +DDKAPI +HalSetBusDataByOffset( + IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length); + +NTOSAPI +BOOLEAN +DDKAPI +HalTranslateBusAddress( + IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress); + +NTOSAPI +NTSTATUS +DDKAPI +IoAllocateAdapterChannel( + IN PADAPTER_OBJECT AdapterObject, + IN PDEVICE_OBJECT DeviceObject, + IN ULONG NumberOfMapRegisters, + IN PDRIVER_CONTROL ExecutionRoutine, + IN PVOID Context); + +NTOSAPI +NTSTATUS +DDKAPI +IoAssignResources( + IN PUNICODE_STRING RegistryPath, + IN PUNICODE_STRING DriverClassName OPTIONAL, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject OPTIONAL, + IN PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources, + IN OUT PCM_RESOURCE_LIST *AllocatedResources); + +NTOSAPI +NTSTATUS +DDKAPI +IoAttachDeviceByPointer( + IN PDEVICE_OBJECT SourceDevice, + IN PDEVICE_OBJECT TargetDevice); + +NTOSAPI +BOOLEAN +DDKAPI +IoFlushAdapterBuffers( + IN PADAPTER_OBJECT AdapterObject, + IN PMDL Mdl, + IN PVOID MapRegisterBase, + IN PVOID CurrentVa, + IN ULONG Length, + IN BOOLEAN WriteToDevice); + +NTOSAPI +VOID +DDKAPI +IoFreeAdapterChannel( + IN PADAPTER_OBJECT AdapterObject); + +NTOSAPI +VOID +DDKAPI +IoFreeMapRegisters( + IN PADAPTER_OBJECT AdapterObject, + IN PVOID MapRegisterBase, + IN ULONG NumberOfMapRegisters); + +NTOSAPI +PHYSICAL_ADDRESS +DDKAPI +IoMapTransfer( + IN PADAPTER_OBJECT AdapterObject, + IN PMDL Mdl, + IN PVOID MapRegisterBase, + IN PVOID CurrentVa, + IN OUT PULONG Length, + IN BOOLEAN WriteToDevice); + +NTOSAPI +PMDL +DDKAPI +MmCreateMdl( + IN PMDL MemoryDescriptorList OPTIONAL, + IN PVOID Base, + IN SIZE_T Length); + +NTOSAPI +BOOLEAN +DDKAPI +MmIsNonPagedSystemAddressValid( + IN PVOID VirtualAddress); + +NTOSAPI +LARGE_INTEGER +DDKAPI +RtlEnlargedIntegerMultiply( + IN LONG Multiplicand, + IN LONG Multiplier); + +NTOSAPI +ULONG +DDKAPI +RtlEnlargedUnsignedDivide( + IN ULARGE_INTEGER Dividend, + IN ULONG Divisor, + IN OUT PULONG Remainder); + +NTOSAPI +LARGE_INTEGER +DDKAPI +RtlEnlargedUnsignedMultiply( + IN ULONG Multiplicand, + IN ULONG Multiplier); + +NTOSAPI +LARGE_INTEGER +DDKAPI +RtlExtendedIntegerMultiply( + IN LARGE_INTEGER Multiplicand, + IN LONG Multiplier); + +NTOSAPI +LARGE_INTEGER +DDKAPI +RtlExtendedLargeIntegerDivide( + IN LARGE_INTEGER Dividend, + IN ULONG Divisor, + IN OUT PULONG Remainder); + +NTOSAPI +LARGE_INTEGER +DDKAPI +RtlExtendedMagicDivide( + IN LARGE_INTEGER Dividend, + IN LARGE_INTEGER MagicDivisor, + IN CCHAR ShiftCount); + +NTOSAPI +LARGE_INTEGER +DDKAPI +RtlLargeIntegerAdd( + IN LARGE_INTEGER Addend1, + IN LARGE_INTEGER Addend2); + +NTOSAPI +VOID +DDKAPI +RtlLargeIntegerAnd( + IN OUT LARGE_INTEGER Result, + IN LARGE_INTEGER Source, + IN LARGE_INTEGER Mask); + +NTOSAPI +LARGE_INTEGER +DDKAPI +RtlLargeIntegerArithmeticShift( + IN LARGE_INTEGER LargeInteger, + IN CCHAR ShiftCount); + +NTOSAPI +LARGE_INTEGER +DDKAPI +RtlLargeIntegerDivide( + IN LARGE_INTEGER Dividend, + IN LARGE_INTEGER Divisor, + IN OUT PLARGE_INTEGER Remainder); + +NTOSAPI +BOOLEAN +DDKAPI +RtlLargeIntegerEqualTo( + IN LARGE_INTEGER Operand1, + IN LARGE_INTEGER Operand2); + +NTOSAPI +BOOLEAN +DDKAPI +RtlLargeIntegerEqualToZero( + IN LARGE_INTEGER Operand); + +NTOSAPI +BOOLEAN +DDKAPI +RtlLargeIntegerGreaterOrEqualToZero( + IN LARGE_INTEGER Operand); + +NTOSAPI +BOOLEAN +DDKAPI +RtlLargeIntegerGreaterThan( + IN LARGE_INTEGER Operand1, + IN LARGE_INTEGER Operand2); + +NTOSAPI +BOOLEAN +DDKAPI +RtlLargeIntegerGreaterThanOrEqualTo( + IN LARGE_INTEGER Operand1, + IN LARGE_INTEGER Operand2); + +NTOSAPI +BOOLEAN +DDKAPI +RtlLargeIntegerGreaterThanZero( + IN LARGE_INTEGER Operand); + +NTOSAPI +BOOLEAN +DDKAPI +RtlLargeIntegerLessOrEqualToZero( + IN LARGE_INTEGER Operand); + +NTOSAPI +BOOLEAN +DDKAPI +RtlLargeIntegerLessThan( + IN LARGE_INTEGER Operand1, + IN LARGE_INTEGER Operand2); + +NTOSAPI +BOOLEAN +DDKAPI +RtlLargeIntegerLessThanOrEqualTo( + IN LARGE_INTEGER Operand1, + IN LARGE_INTEGER Operand2); + +NTOSAPI +BOOLEAN +DDKAPI +RtlLargeIntegerLessThanZero( + IN LARGE_INTEGER Operand); + +NTOSAPI +LARGE_INTEGER +DDKAPI +RtlLargeIntegerNegate( + IN LARGE_INTEGER Subtrahend); + +NTOSAPI +BOOLEAN +DDKAPI +RtlLargeIntegerNotEqualTo( + IN LARGE_INTEGER Operand1, + IN LARGE_INTEGER Operand2); + +NTOSAPI +BOOLEAN +DDKAPI +RtlLargeIntegerNotEqualToZero( + IN LARGE_INTEGER Operand); + +NTOSAPI +LARGE_INTEGER +DDKAPI +RtlLargeIntegerShiftLeft( + IN LARGE_INTEGER LargeInteger, + IN CCHAR ShiftCount); + +NTOSAPI +LARGE_INTEGER +DDKAPI +RtlLargeIntegerShiftRight( + IN LARGE_INTEGER LargeInteger, + IN CCHAR ShiftCount); + +NTOSAPI +LARGE_INTEGER +DDKAPI +RtlLargeIntegerSubtract( + IN LARGE_INTEGER Minuend, + IN LARGE_INTEGER Subtrahend); + + +/* + * ULONG + * COMPUTE_PAGES_SPANNED( + * IN PVOID Va, + * IN ULONG Size) + */ +#define COMPUTE_PAGES_SPANNED(Va, \ + Size) \ + (ADDRESS_AND_SIZE_TO_SPAN_PAGES(Va, Size)) + + +/* +** Architecture specific structures +*/ + +#ifdef _X86_ + +NTOSAPI +INTERLOCKED_RESULT +DDKFASTAPI +Exfi386InterlockedIncrementLong( + IN PLONG Addend); + +NTOSAPI +INTERLOCKED_RESULT +DDKFASTAPI +Exfi386InterlockedDecrementLong( + IN PLONG Addend); + +NTOSAPI +ULONG +DDKFASTAPI +Exfi386InterlockedExchangeUlong( + IN PULONG Target, + IN ULONG Value); + +#define ExInterlockedIncrementLong(Addend,Lock) Exfi386InterlockedIncrementLong(Addend) +#define ExInterlockedDecrementLong(Addend,Lock) Exfi386InterlockedDecrementLong(Addend) +#define ExInterlockedExchangeUlong(Target, Value, Lock) Exfi386InterlockedExchangeUlong(Target, Value) + +#endif /* _X86_ */ + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif + +#endif /* __WINNT4_H */ diff --git a/src/platform/visualc/winxp.h b/src/platform/visualc/winxp.h new file mode 100644 index 00000000..28e34a89 --- /dev/null +++ b/src/platform/visualc/winxp.h @@ -0,0 +1,38 @@ +/* + * winxp.h + * + * Definitions only used in Windows XP and earlier versions + * + * This file is part of the w32api package. + * + * Contributors: + * Created by Casper S. Hornstrup + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef __WINXP_H +#define __WINXP_H + +#if __GNUC__ >=3 +#pragma GCC system_header +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __WINXP_H */ From f06e281ba51d8042cbba867530c03098493b545d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 2 Jan 2004 20:46:38 +0000 Subject: [PATCH 1446/4131] Changed visual c assembly startup piece a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1527 --- src/cpu/core_dyn_x86/risc_x86.h | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index b04866ae..9aee4335 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -76,27 +76,22 @@ static BlockReturn gen_runcode(Bit8u * code) { #if defined (_MSC_VER) __asm { /* Prepare the flags */ + mov eax,[code] push ebx push ebp push esi push edi - pushfd mov ebx,[reg_flags] and ebx,FMASK_TEST - pop ecx - and ecx,~FMASK_TEST - or ecx,ebx - push ecx + push ebx popfd - call dword ptr [code]; + call eax /* Restore the flags */ pushfd - mov ebx,[reg_flags] - and ebx,~FMASK_TEST + and dword ptr [reg_flags],~FMASK_TEST pop ecx and ecx,FMASK_TEST - or ebx,ecx - mov [reg_flags],ebx + or [reg_flags],ecx pop edi pop esi pop ebp From 252cc94215d818e2a056f5af541b2565de132753 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 2 Jan 2004 20:49:35 +0000 Subject: [PATCH 1447/4131] Fix pop ss and mov ss,val instruction to release the stack mask registers Fix the mov [mem],seg instruction to only save a short Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1528 --- src/cpu/core_dyn_x86/decoder.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 82e8bf1c..98bc9d57 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -555,10 +555,10 @@ skipsave: static void dyn_mov_ev_seg(void) { dyn_get_modrm(); - gen_load_host(&Segs.val[(SegNames) decode.modrm.reg],DREG(TMPW),2); + gen_load_host(&Segs.val[decode.modrm.reg],DREG(TMPW),2); if (decode.modrm.mod<3) { dyn_fill_ea(); - dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); + dyn_write_word(DREG(EA),DREG(TMPW),false); gen_releasereg(DREG(EA)); } else { gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],DREG(TMPW)); @@ -572,12 +572,13 @@ static void dyn_mov_seg_ev(void) { if (seg==cs) IllegalOption(); if (decode.modrm.mod<3) { dyn_fill_ea(); - dyn_read_word(DREG(EA),DREG(EA),decode.big_op); + dyn_read_word(DREG(EA),DREG(EA),false); gen_call_function((void *)&CPU_SetSegGeneral,"%Id%Drw",seg,DREG(EA)); } else { gen_call_function((void *)&CPU_SetSegGeneral,"%Id%Dw",seg,&DynRegs[decode.modrm.rm]); } gen_releasereg(&DynRegs[G_ES+seg]); + if (seg==ss) gen_releasereg(DREG(SMASK)); } @@ -592,6 +593,7 @@ static void dyn_pop_seg(SegNames seg) { dyn_pop(DREG(TMPW)); gen_call_function((void*)&CPU_SetSegGeneral,"%Id%Drw",seg,DREG(TMPW)); gen_releasereg(&DynRegs[G_ES+seg]); + if (seg==ss) gen_releasereg(DREG(SMASK)); gen_restoreflags(); } @@ -813,7 +815,7 @@ static CacheBlock * CreateCacheBlock(PhysPt start,bool big,Bitu max_opcodes) { decode.code=start; Bitu cycles=0; decode.block=cache_openblock(); - gen_save_host_direct(&core_dyn.lastblock,(Bit32u)decode.block); + gen_save_host_direct(&cache.block.running,(Bit32u)decode.block); for (i=0;i Date: Fri, 2 Jan 2004 20:50:59 +0000 Subject: [PATCH 1448/4131] Changed running block variable Test if someone makes changes to currently running block Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1529 --- src/cpu/core_dyn_x86.cpp | 4 ++-- src/cpu/core_dyn_x86/cache.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 7b27ffe2..901c4f4d 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -145,7 +145,6 @@ static void IllegalOption(void) { static struct { Bitu callback; - CacheBlock * lastblock; } core_dyn; @@ -215,6 +214,7 @@ restart_core: findblock:; CacheBlock * block=chandler->FindCacheBlock(ip_point&4095); if (!block) { + cache.block.running=0; block=CreateCacheBlock(ip_point,cpu.code.big,128); DYN_LOG("Created block size %x type %d",block->cache.size,block->type); chandler->AddCacheBlock(block); @@ -251,7 +251,7 @@ run_block: if (temp_handler->flags & PFLAG_HASCODE) { block=temp_handler->FindCacheBlock(temp_ip & 4095); if (!block) goto restart_core; - cache_linkblocks(core_dyn.lastblock,block,ret==BR_Link2); + cache_linkblocks(cache.block.running,block,ret==BR_Link2); goto run_block; } } diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 92b38f83..d70644f3 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -28,6 +28,7 @@ static struct { CacheBlock * first; CacheBlock * active; CacheBlock * free; + CacheBlock * running; } block; Bit8u * pos; CacheBlock linkblocks[2]; @@ -61,6 +62,7 @@ public: for (Bitu i=block->page.first;i<=block->page.last;i++) write_map[i]--; block->code_page=0; //Else resetblock will do double work count--; + if (block==cache.block.running) LOG_MSG("Writing to current block"); cache_resetblock(block); *where=nextblock; } else { From eb18b71e69375191ca1973bf2fc19b201275c4f7 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 2 Jan 2004 23:09:00 +0000 Subject: [PATCH 1449/4131] changed for better win cdrom compatibility Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1530 --- src/platform/visualc/ntddcdrm.h | 32 -------------------------------- src/platform/visualc/ntddscsi.h | 6 +++--- 2 files changed, 3 insertions(+), 35 deletions(-) diff --git a/src/platform/visualc/ntddcdrm.h b/src/platform/visualc/ntddcdrm.h index e4d830fb..c1ee8c2a 100644 --- a/src/platform/visualc/ntddcdrm.h +++ b/src/platform/visualc/ntddcdrm.h @@ -33,10 +33,6 @@ extern "C" { #pragma pack(push,4) -#include "ntddk.h" -#include "ntddstor.h" - - #define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM #define IOCTL_CDROM_CHECK_VERIFY \ @@ -191,13 +187,6 @@ typedef struct _CDROM_TOC_ATIP_DATA_BLOCK { UCHAR Reserved12; } CDROM_TOC_ATIP_DATA_BLOCK, *PCDROM_TOC_ATIP_DATA_BLOCK; -typedef struct _CDROM_TOC_ATIP_DATA { - UCHAR Length[2]; - UCHAR Reserved1; - UCHAR Reserved2; - CDROM_TOC_ATIP_DATA_BLOCK Descriptors[0]; -} CDROM_TOC_ATIP_DATA, *PCDROM_TOC_ATIP_DATA; - /* CDROM_TOC_CD_TEXT_DATA_BLOCK.PackType constants */ #define CDROM_CD_TEXT_PACK_ALBUM_NAME 0x80 #define CDROM_CD_TEXT_PACK_PERFORMER 0x81 @@ -227,13 +216,6 @@ typedef struct _CDROM_TOC_CD_TEXT_DATA_BLOCK { UCHAR CRC[2]; } CDROM_TOC_CD_TEXT_DATA_BLOCK, *PCDROM_TOC_CD_TEXT_DATA_BLOCK; -typedef struct _CDROM_TOC_CD_TEXT_DATA { - UCHAR Length[2]; - UCHAR Reserved1; - UCHAR Reserved2; - CDROM_TOC_CD_TEXT_DATA_BLOCK Descriptors[0]; -} CDROM_TOC_CD_TEXT_DATA, *PCDROM_TOC_CD_TEXT_DATA; - /* CDROM_TOC_FULL_TOC_DATA_BLOCK.Adr constants */ #define ADR_NO_MODE_INFORMATION 0x0 #define ADR_ENCODES_CURRENT_POSITION 0x1 @@ -251,20 +233,6 @@ typedef struct _CDROM_TOC_FULL_TOC_DATA_BLOCK { UCHAR Msf[3]; } CDROM_TOC_FULL_TOC_DATA_BLOCK, *PCDROM_TOC_FULL_TOC_DATA_BLOCK; -typedef struct _CDROM_TOC_FULL_TOC_DATA { - UCHAR Length[2]; - UCHAR FirstCompleteSession; - UCHAR LastCompleteSession; - CDROM_TOC_FULL_TOC_DATA_BLOCK Descriptors[0]; -} CDROM_TOC_FULL_TOC_DATA, *PCDROM_TOC_FULL_TOC_DATA; - -typedef struct _CDROM_TOC_PMA_DATA { - UCHAR Length[2]; - UCHAR Reserved1; - UCHAR Reserved2; - CDROM_TOC_FULL_TOC_DATA_BLOCK Descriptors[0]; -} CDROM_TOC_PMA_DATA, *PCDROM_TOC_PMA_DATA; - /* SUB_Q_HEADER.AudioStatus constants */ #define AUDIO_STATUS_NOT_SUPPORTED 0x00 #define AUDIO_STATUS_IN_PROGRESS 0x11 diff --git a/src/platform/visualc/ntddscsi.h b/src/platform/visualc/ntddscsi.h index c580ae3c..8342c23e 100644 --- a/src/platform/visualc/ntddscsi.h +++ b/src/platform/visualc/ntddscsi.h @@ -33,8 +33,7 @@ extern "C" { #pragma pack(push,4) -#include "ntddk.h" - +//#include "ntddk.h" #define DD_SCSI_DEVICE_NAME "\\Device\\ScsiPort" #define DD_SCSI_DEVICE_NAME_U L"\\Device\\ScsiPort" @@ -154,6 +153,7 @@ typedef struct _SCSI_INQUIRY_DATA { #define SCSI_IOCTL_DATA_IN 1 #define SCSI_IOCTL_DATA_UNSPECIFIED 2 +/* typedef struct _DUMP_POINTERS { PADAPTER_OBJECT AdapterObject; PVOID MappedRegisterBase; @@ -166,7 +166,7 @@ typedef struct _DUMP_POINTERS { UCHAR Spare1[2]; PVOID DeviceObject; } DUMP_POINTERS, *PDUMP_POINTERS; - +*/ #pragma pack(pop) #ifdef __cplusplus From 02236289ba77eb459a7b8b93d73315b9f6cfa351 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 2 Jan 2004 23:10:31 +0000 Subject: [PATCH 1450/4131] changed to work with new win cdrom header files Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1531 --- src/dos/cdrom_aspi_win32.cpp | 9 ++++++--- src/dos/cdrom_ioctl_win32.cpp | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index 78565f9d..1787e8af 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -16,19 +16,22 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_aspi_win32.cpp,v 1.7 2004-01-02 14:38:30 qbix79 Exp $ */ +/* $Id: cdrom_aspi_win32.cpp,v 1.8 2004-01-02 23:10:31 finsterr Exp $ */ #if defined (WIN32) #include +#include "dosbox.h" #include "cdrom.h" + //Are actually system includes but leave for now +#include "wnaspi32.h" #include "ntddcdrm.h" #include "ntddscsi.h" -//#include "scsi.h" // Aspi stuff #include "scsidefs.h" -#include "dosbox.h" + +#include // ***************************************************************** // Windows ASPI functions (should work for all WIN with ASPI layer) diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index b7eb1ef9..fda4e124 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_ioctl_win32.cpp,v 1.7 2004-01-02 14:38:30 qbix79 Exp $ */ +/* $Id: cdrom_ioctl_win32.cpp,v 1.8 2004-01-02 23:10:31 finsterr Exp $ */ #if defined (WIN32) @@ -27,7 +27,7 @@ #include #include // Ioctl stuff #include -//Actually a system include but leave for now + #include "ntddcdrm.h" // Ioctl stuff #include "cdrom.h" From 19e4adbc5a734f28c7f83b5cf89849de5870e0f3 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 2 Jan 2004 23:14:56 +0000 Subject: [PATCH 1451/4131] removed win cdrom files no longer needed Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1532 --- src/platform/visualc/Makefile.am | 2 +- src/platform/visualc/ntddk.h | 90 - src/platform/visualc/ntddstor.h | 338 -- src/platform/visualc/ntstatus.h | 1105 ---- src/platform/visualc/win2k.h | 106 - src/platform/visualc/winddk.h | 9074 ------------------------------ src/platform/visualc/winnt4.h | 608 -- src/platform/visualc/winxp.h | 38 - 8 files changed, 1 insertion(+), 11360 deletions(-) delete mode 100644 src/platform/visualc/ntddk.h delete mode 100644 src/platform/visualc/ntddstor.h delete mode 100644 src/platform/visualc/ntstatus.h delete mode 100644 src/platform/visualc/win2k.h delete mode 100644 src/platform/visualc/winddk.h delete mode 100644 src/platform/visualc/winnt4.h delete mode 100644 src/platform/visualc/winxp.h diff --git a/src/platform/visualc/Makefile.am b/src/platform/visualc/Makefile.am index b143cad9..1c4a8708 100644 --- a/src/platform/visualc/Makefile.am +++ b/src/platform/visualc/Makefile.am @@ -1 +1 @@ -EXTRA_DIST = dirent.c dirent.h unistd.h config.h ntddscsi.h ntddstor.h ntddcdrm.h ntddk.h ntstatus.h win2k.h winddk.h winnt4.h winxp.h +EXTRA_DIST = dirent.c dirent.h unistd.h config.h ntddscsi.h ntddcdrm.h diff --git a/src/platform/visualc/ntddk.h b/src/platform/visualc/ntddk.h deleted file mode 100644 index 480ff0cc..00000000 --- a/src/platform/visualc/ntddk.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * ntddk.h - * - * Windows Device Driver Kit - * - * This file is part of the w32api package. - * - * Contributors: - * Created by Casper S. Hornstrup - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * DEFINES: - * DBG - Debugging enabled/disabled (0/1) - * POOL_TAGGING - Enable pool tagging - * _X86_ - X86 environment - */ - -#ifndef __NTDDK_H -#define __NTDDK_H - -#if __GNUC__ >=3 -#pragma GCC system_header -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#pragma pack(push,4) - -#include -#include -#include -#include - -/* Base types, structures and definitions */ -typedef short CSHORT; -typedef CONST int CINT; -typedef CONST char *PCSZ; - -#ifndef STATIC -#define STATIC static -#endif - -#ifndef CALLBACK -#define CALLBACK -#endif - -#ifndef DECL_IMPORT -#define DECL_IMPORT __attribute__((dllimport)) -#endif - -#ifndef DECL_EXPORT -#define DECL_EXPORT __attribute__((dllexport)) -#endif - -/* Windows NT status codes */ -#include "ntstatus.h" - -/* Windows NT definitions exported to user mode */ -#include - -/* Windows Device Driver Kit */ -#include "winddk.h" - -/* Definitions only in Windows XP */ -#include "winxp.h" - -/* Definitions only in Windows 2000 */ -#include "win2k.h" - -/* Definitions only in Windows NT 4 */ -#include "winnt4.h" - -#pragma pack(pop) - -#ifdef __cplusplus -} -#endif - -#endif /* __NTDDK_H */ diff --git a/src/platform/visualc/ntddstor.h b/src/platform/visualc/ntddstor.h deleted file mode 100644 index 6875cd19..00000000 --- a/src/platform/visualc/ntddstor.h +++ /dev/null @@ -1,338 +0,0 @@ -/* - * ntddstor.h - * - * Storage class IOCTL interface. - * - * This file is part of the w32api package. - * - * Contributors: - * Created by Casper S. Hornstrup - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - */ - -#ifndef __NTDDSTOR_H -#define __NTDDSTOR_H - -#if __GNUC__ >=3 -#pragma GCC system_header -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#pragma pack(push,4) - -#include "ntddk.h" - - -#define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE - -#define IOCTL_STORAGE_CHECK_VERIFY \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS) - -#define IOCTL_STORAGE_CHECK_VERIFY2 \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define IOCTL_STORAGE_EJECT_MEDIA \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS) - -#define IOCTL_STORAGE_EJECTION_CONTROL \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0250, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define IOCTL_STORAGE_FIND_NEW_DEVICES \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS) - -#define IOCTL_STORAGE_GET_DEVICE_NUMBER \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0420, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0304, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define IOCTL_STORAGE_GET_MEDIA_TYPES \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0300, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define IOCTL_STORAGE_GET_MEDIA_TYPES_EX \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0301, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define IOCTL_STORAGE_LOAD_MEDIA \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_READ_ACCESS) - -#define IOCTL_STORAGE_LOAD_MEDIA2 \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define IOCTL_STORAGE_MCN_CONTROL \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0251, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define IOCTL_STORAGE_MEDIA_REMOVAL \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS) - -#define IOCTL_STORAGE_PREDICT_FAILURE \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0440, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define IOCTL_STORAGE_QUERY_PROPERTY \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define IOCTL_STORAGE_RELEASE \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0205, METHOD_BUFFERED, FILE_READ_ACCESS) - -#define IOCTL_STORAGE_RESERVE \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0204, METHOD_BUFFERED, FILE_READ_ACCESS) - -#define IOCTL_STORAGE_RESET_BUS \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0400, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) - -#define IOCTL_STORAGE_RESET_DEVICE \ - CTL_CODE(IOCTL_STORAGE_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) - - -DEFINE_GUID(GUID_DEVINTERFACE_DISK, - 0x53f56307L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); - -DEFINE_GUID(GUID_DEVINTERFACE_CDROM, - 0x53f56308L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); - -DEFINE_GUID(GUID_DEVINTERFACE_PARTITION, - 0x53f5630aL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); - -DEFINE_GUID(GUID_DEVINTERFACE_TAPE, - 0x53f5630bL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); - -DEFINE_GUID(GUID_DEVINTERFACE_WRITEONCEDISK, - 0x53f5630cL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); - -DEFINE_GUID(GUID_DEVINTERFACE_VOLUME, - 0x53f5630dL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); - -DEFINE_GUID(GUID_DEVINTERFACE_MEDIUMCHANGER, - 0x53f56310L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); - -DEFINE_GUID(GUID_DEVINTERFACE_FLOPPY, - 0x53f56311L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); - -DEFINE_GUID(GUID_DEVINTERFACE_CDCHANGER, - 0x53f56312L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); - -DEFINE_GUID(GUID_DEVINTERFACE_STORAGEPORT, - 0x2accfe60L, 0xc130, 0x11d2, 0xb0, 0x82, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); - - -typedef enum _STORAGE_MEDIA_TYPE { - DDS_4mm = 0x20, - MiniQic, - Travan, - QIC, - MP_8mm, - AME_8mm, - AIT1_8mm, - DLT, - NCTP, - IBM_3480, - IBM_3490E, - IBM_Magstar_3590, - IBM_Magstar_MP, - STK_DATA_D3, - SONY_DTF, - DV_6mm, - DMI, - SONY_D2, - CLEANER_CARTRIDGE, - CD_ROM, - CD_R, - CD_RW, - DVD_ROM, - DVD_R, - DVD_RW, - MO_3_RW, - MO_5_WO, - MO_5_RW, - MO_5_LIMDOW, - PC_5_WO, - PC_5_RW, - PD_5_RW, - ABL_5_WO, - PINNACLE_APEX_5_RW, - SONY_12_WO, - PHILIPS_12_WO, - HITACHI_12_WO, - CYGNET_12_WO, - KODAK_14_WO, - MO_NFR_525, - NIKON_12_RW, - IOMEGA_ZIP, - IOMEGA_JAZ, - SYQUEST_EZ135, - SYQUEST_EZFLYER, - SYQUEST_SYJET, - AVATAR_F2, - MP2_8mm, - DST_S, - DST_M, - DST_L, - VXATape_1, - VXATape_2, - STK_9840, - LTO_Ultrium, - LTO_Accelis, - DVD_RAM, - AIT_8mm, - ADR_1, - ADR_2 -} STORAGE_MEDIA_TYPE, *PSTORAGE_MEDIA_TYPE; - -typedef enum _STORAGE_BUS_TYPE { - BusTypeUnknown = 0x00, - BusTypeScsi, - BusTypeAtapi, - BusTypeAta, - BusType1394, - BusTypeSsa, - BusTypeFibre, - BusTypeUsb, - BusTypeRAID, - BusTypeMaxReserved = 0x7F -} STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE; - -/* DEVICE_MEDIA_INFO.DeviceSpecific.DiskInfo.MediaCharacteristics constants */ -#define MEDIA_ERASEABLE 0x00000001 -#define MEDIA_WRITE_ONCE 0x00000002 -#define MEDIA_READ_ONLY 0x00000004 -#define MEDIA_READ_WRITE 0x00000008 -#define MEDIA_WRITE_PROTECTED 0x00000100 -#define MEDIA_CURRENTLY_MOUNTED 0x80000000 - -typedef struct _DEVICE_MEDIA_INFO { - union { - struct { - LARGE_INTEGER Cylinders; - STORAGE_MEDIA_TYPE MediaType; - ULONG TracksPerCylinder; - ULONG SectorsPerTrack; - ULONG BytesPerSector; - ULONG NumberMediaSides; - ULONG MediaCharacteristics; - } DiskInfo; - struct { - LARGE_INTEGER Cylinders; - STORAGE_MEDIA_TYPE MediaType; - ULONG TracksPerCylinder; - ULONG SectorsPerTrack; - ULONG BytesPerSector; - ULONG NumberMediaSides; - ULONG MediaCharacteristics; - } RemovableDiskInfo; - struct { - STORAGE_MEDIA_TYPE MediaType; - ULONG MediaCharacteristics; - ULONG CurrentBlockSize; - STORAGE_BUS_TYPE BusType; - union { - struct { - UCHAR MediumType; - UCHAR DensityCode; - } ScsiInformation; - } BusSpecificData; - } TapeInfo; - } DeviceSpecific; -} DEVICE_MEDIA_INFO, *PDEVICE_MEDIA_INFO; - -typedef struct _GET_MEDIA_TYPES { - ULONG DeviceType; - ULONG MediaInfoCount; - DEVICE_MEDIA_INFO MediaInfo[1]; -} GET_MEDIA_TYPES, *PGET_MEDIA_TYPES; - -typedef struct _STORAGE_ADAPTER_DESCRIPTOR { - ULONG Version; - ULONG Size; - ULONG MaximumTransferLength; - ULONG MaximumPhysicalPages; - ULONG AlignmentMask; - BOOLEAN AdapterUsesPio; - BOOLEAN AdapterScansDown; - BOOLEAN CommandQueueing; - BOOLEAN AcceleratedTransfer; - STORAGE_BUS_TYPE BusType; - USHORT BusMajorVersion; - USHORT BusMinorVersion; -} STORAGE_ADAPTER_DESCRIPTOR, *PSTORAGE_ADAPTER_DESCRIPTOR; - -typedef struct _STORAGE_BUS_RESET_REQUEST { - UCHAR PathId; -} STORAGE_BUS_RESET_REQUEST, *PSTORAGE_BUS_RESET_REQUEST; - -typedef struct _STORAGE_DESCRIPTOR_HEADER { - ULONG Version; - ULONG Size; -} STORAGE_DESCRIPTOR_HEADER, *PSTORAGE_DESCRIPTOR_HEADER; - -typedef struct _STORAGE_DEVICE_DESCRIPTOR { - ULONG Version; - ULONG Size; - UCHAR DeviceType; - UCHAR DeviceTypeModifier; - BOOLEAN RemovableMedia; - BOOLEAN CommandQueueing; - ULONG VendorIdOffset; - ULONG ProductIdOffset; - ULONG ProductRevisionOffset; - ULONG SerialNumberOffset; - STORAGE_BUS_TYPE BusType; - ULONG RawPropertiesLength; - UCHAR RawDeviceProperties[1]; -} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR; - -typedef struct _STORAGE_DEVICE_ID_DESCRIPTOR { - ULONG Version; - ULONG Size; - ULONG NumberOfIdentifiers; - UCHAR Identifiers[1]; -} STORAGE_DEVICE_ID_DESCRIPTOR, *PSTORAGE_DEVICE_ID_DESCRIPTOR; - -typedef struct _STORAGE_DEVICE_NUMBER { - DEVICE_TYPE DeviceType; - ULONG DeviceNumber; - ULONG PartitionNumber; -} STORAGE_DEVICE_NUMBER, *PSTORAGE_DEVICE_NUMBER; - -typedef struct _STORAGE_PREDICT_FAILURE { - ULONG PredictFailure; - UCHAR VendorSpecific[512]; -} STORAGE_PREDICT_FAILURE, *PSTORAGE_PREDICT_FAILURE; - -typedef enum _STORAGE_PROPERTY_ID { - StorageDeviceProperty = 0, - StorageAdapterProperty, - StorageDeviceIdProperty -} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID; - -typedef enum _STORAGE_QUERY_TYPE { - PropertyStandardQuery = 0, - PropertyExistsQuery, - PropertyMaskQuery, - PropertyQueryMaxDefined -} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE; - -typedef struct _STORAGE_PROPERTY_QUERY { - STORAGE_PROPERTY_ID PropertyId; - STORAGE_QUERY_TYPE QueryType; - UCHAR AdditionalParameters[1]; -} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY; - -#pragma pack(pop) - -#ifdef __cplusplus -} -#endif - -#endif /* __NTDDSTOR_H */ diff --git a/src/platform/visualc/ntstatus.h b/src/platform/visualc/ntstatus.h deleted file mode 100644 index d325d9f1..00000000 --- a/src/platform/visualc/ntstatus.h +++ /dev/null @@ -1,1105 +0,0 @@ -/* - * ntstatus.h - * - * Windows NT status codes - * - * This file is part of the w32api package. - * - * Contributors: - * Created by Casper S. Hornstrup - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - */ - -#ifndef _NTSTATUS_H -#define _NTSTATUS_H - -#if __GNUC__ >=3 -#pragma GCC system_header -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(STATUS_SUCCESS) -#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) -#endif /* !STATUS_SUCCESS */ -#define FACILITY_DEBUGGER 0x1 -#define FACILITY_RPC_RUNTIME 0x2 -#define FACILITY_RPC_STUBS 0x3 -#define FACILITY_IO_ERROR_CODE 0x4 -#define FACILITY_TERMINAL_SERVER 0xA -#define FACILITY_USB_ERROR_CODE 0x10 -#define FACILITY_HID_ERROR_CODE 0x11 -#define FACILITY_FIREWIRE_ERROR_CODE 0x12 -#define FACILITY_CLUSTER_ERROR_CODE 0x13 -#define FACILITY_ACPI_ERROR_CODE 0x14 -#define FACILITY_SXS_ERROR_CODE 0x15 -#define STATUS_SEVERITY_SUCCESS 0x0 -#define STATUS_SEVERITY_INFORMATIONAL 0x1 -#define STATUS_SEVERITY_WARNING 0x2 -#define STATUS_SEVERITY_ERROR 0x3 -#define STATUS_WAIT_0 ((NTSTATUS)0x00000000L) -#define STATUS_WAIT_1 ((NTSTATUS)0x00000001L) -#define STATUS_WAIT_2 ((NTSTATUS)0x00000002L) -#define STATUS_WAIT_3 ((NTSTATUS)0x00000003L) -#define STATUS_WAIT_63 ((NTSTATUS)0x0000003FL) -#define STATUS_ABANDONED ((NTSTATUS)0x00000080L) -#define STATUS_ABANDONED_WAIT_0 ((NTSTATUS)0x00000080L) -#define STATUS_ABANDONED_WAIT_63 ((NTSTATUS)0x000000BFL) -#define STATUS_USER_APC ((NTSTATUS)0x000000C0L) -#define STATUS_KERNEL_APC ((NTSTATUS)0x00000100L) -#define STATUS_ALERTED ((NTSTATUS)0x00000101L) -#define STATUS_TIMEOUT ((NTSTATUS)0x00000102L) -#define STATUS_PENDING ((NTSTATUS)0x00000103L) -#define STATUS_REPARSE ((NTSTATUS)0x00000104L) -#define STATUS_MORE_ENTRIES ((NTSTATUS)0x00000105L) -#define STATUS_NOT_ALL_ASSIGNED ((NTSTATUS)0x00000106L) -#define STATUS_SOME_NOT_MAPPED ((NTSTATUS)0x00000107L) -#define STATUS_OPLOCK_BREAK_IN_PROGRESS ((NTSTATUS)0x00000108L) -#define STATUS_VOLUME_MOUNTED ((NTSTATUS)0x00000109L) -#define STATUS_RXACT_COMMITTED ((NTSTATUS)0x0000010AL) -#define STATUS_NOTIFY_CLEANUP ((NTSTATUS)0x0000010BL) -#define STATUS_NOTIFY_ENUM_DIR ((NTSTATUS)0x0000010CL) -#define STATUS_NO_QUOTAS_FOR_ACCOUNT ((NTSTATUS)0x0000010DL) -#define STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED ((NTSTATUS)0x0000010EL) -#define STATUS_PAGE_FAULT_TRANSITION ((NTSTATUS)0x00000110L) -#define STATUS_PAGE_FAULT_DEMAND_ZERO ((NTSTATUS)0x00000111L) -#define STATUS_PAGE_FAULT_COPY_ON_WRITE ((NTSTATUS)0x00000112L) -#define STATUS_PAGE_FAULT_GUARD_PAGE ((NTSTATUS)0x00000113L) -#define STATUS_PAGE_FAULT_PAGING_FILE ((NTSTATUS)0x00000114L) -#define STATUS_CACHE_PAGE_LOCKED ((NTSTATUS)0x00000115L) -#define STATUS_CRASH_DUMP ((NTSTATUS)0x00000116L) -#define STATUS_BUFFER_ALL_ZEROS ((NTSTATUS)0x00000117L) -#define STATUS_REPARSE_OBJECT ((NTSTATUS)0x00000118L) -#define STATUS_RESOURCE_REQUIREMENTS_CHANGED ((NTSTATUS)0x00000119L) -#define STATUS_TRANSLATION_COMPLETE ((NTSTATUS)0x00000120L) -#define STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY ((NTSTATUS)0x00000121L) -#define STATUS_NOTHING_TO_TERMINATE ((NTSTATUS)0x00000122L) -#define STATUS_PROCESS_NOT_IN_JOB ((NTSTATUS)0x00000123L) -#define STATUS_PROCESS_IN_JOB ((NTSTATUS)0x00000124L) -#define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS)0x40000000L) -#define STATUS_THREAD_WAS_SUSPENDED ((NTSTATUS)0x40000001L) -#define STATUS_WORKING_SET_LIMIT_RANGE ((NTSTATUS)0x40000002L) -#define STATUS_IMAGE_NOT_AT_BASE ((NTSTATUS)0x40000003L) -#define STATUS_RXACT_STATE_CREATED ((NTSTATUS)0x40000004L) -#define STATUS_SEGMENT_NOTIFICATION ((NTSTATUS)0x40000005L) -#define STATUS_LOCAL_USER_SESSION_KEY ((NTSTATUS)0x40000006L) -#define STATUS_BAD_CURRENT_DIRECTORY ((NTSTATUS)0x40000007L) -#define STATUS_SERIAL_MORE_WRITES ((NTSTATUS)0x40000008L) -#define STATUS_REGISTRY_RECOVERED ((NTSTATUS)0x40000009L) -#define STATUS_FT_READ_RECOVERY_FROM_BACKUP ((NTSTATUS)0x4000000AL) -#define STATUS_FT_WRITE_RECOVERY ((NTSTATUS)0x4000000BL) -#define STATUS_SERIAL_COUNTER_TIMEOUT ((NTSTATUS)0x4000000CL) -#define STATUS_NULL_LM_PASSWORD ((NTSTATUS)0x4000000DL) -#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH ((NTSTATUS)0x4000000EL) -#define STATUS_RECEIVE_PARTIAL ((NTSTATUS)0x4000000FL) -#define STATUS_RECEIVE_EXPEDITED ((NTSTATUS)0x40000010L) -#define STATUS_RECEIVE_PARTIAL_EXPEDITED ((NTSTATUS)0x40000011L) -#define STATUS_EVENT_DONE ((NTSTATUS)0x40000012L) -#define STATUS_EVENT_PENDING ((NTSTATUS)0x40000013L) -#define STATUS_CHECKING_FILE_SYSTEM ((NTSTATUS)0x40000014L) -#define STATUS_FATAL_APP_EXIT ((NTSTATUS)0x40000015L) -#define STATUS_PREDEFINED_HANDLE ((NTSTATUS)0x40000016L) -#define STATUS_WAS_UNLOCKED ((NTSTATUS)0x40000017L) -#define STATUS_SERVICE_NOTIFICATION ((NTSTATUS)0x40000018L) -#define STATUS_WAS_LOCKED ((NTSTATUS)0x40000019L) -#define STATUS_LOG_HARD_ERROR ((NTSTATUS)0x4000001AL) -#define STATUS_ALREADY_WIN32 ((NTSTATUS)0x4000001BL) -#define STATUS_WX86_UNSIMULATE ((NTSTATUS)0x4000001CL) -#define STATUS_WX86_CONTINUE ((NTSTATUS)0x4000001DL) -#define STATUS_WX86_SINGLE_STEP ((NTSTATUS)0x4000001EL) -#define STATUS_WX86_BREAKPOINT ((NTSTATUS)0x4000001FL) -#define STATUS_WX86_EXCEPTION_CONTINUE ((NTSTATUS)0x40000020L) -#define STATUS_WX86_EXCEPTION_LASTCHANCE ((NTSTATUS)0x40000021L) -#define STATUS_WX86_EXCEPTION_CHAIN ((NTSTATUS)0x40000022L) -#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE ((NTSTATUS)0x40000023L) -#define STATUS_NO_YIELD_PERFORMED ((NTSTATUS)0x40000024L) -#define STATUS_TIMER_RESUME_IGNORED ((NTSTATUS)0x40000025L) -#define STATUS_ARBITRATION_UNHANDLED ((NTSTATUS)0x40000026L) -#define STATUS_CARDBUS_NOT_SUPPORTED ((NTSTATUS)0x40000027L) -#define STATUS_WX86_CREATEWX86TIB ((NTSTATUS)0x40000028L) -#define STATUS_MP_PROCESSOR_MISMATCH ((NTSTATUS)0x40000029L) -#define STATUS_HIBERNATED ((NTSTATUS)0x4000002AL) -#define STATUS_RESUME_HIBERNATION ((NTSTATUS)0x4000002BL) -#define STATUS_GUARD_PAGE_VIOLATION ((NTSTATUS)0x80000001L) -#define STATUS_DATATYPE_MISALIGNMENT ((NTSTATUS)0x80000002L) -#define STATUS_BREAKPOINT ((NTSTATUS)0x80000003L) -#define STATUS_SINGLE_STEP ((NTSTATUS)0x80000004L) -#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L) -#define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006L) -#define STATUS_WAKE_SYSTEM_DEBUGGER ((NTSTATUS)0x80000007L) -#define STATUS_HANDLES_CLOSED ((NTSTATUS)0x8000000AL) -#define STATUS_NO_INHERITANCE ((NTSTATUS)0x8000000BL) -#define STATUS_GUID_SUBSTITUTION_MADE ((NTSTATUS)0x8000000CL) -#define STATUS_PARTIAL_COPY ((NTSTATUS)0x8000000DL) -#define STATUS_DEVICE_PAPER_EMPTY ((NTSTATUS)0x8000000EL) -#define STATUS_DEVICE_POWERED_OFF ((NTSTATUS)0x8000000FL) -#define STATUS_DEVICE_OFF_LINE ((NTSTATUS)0x80000010L) -#define STATUS_DEVICE_BUSY ((NTSTATUS)0x80000011L) -#define STATUS_NO_MORE_EAS ((NTSTATUS)0x80000012L) -#define STATUS_INVALID_EA_NAME ((NTSTATUS)0x80000013L) -#define STATUS_EA_LIST_INCONSISTENT ((NTSTATUS)0x80000014L) -#define STATUS_INVALID_EA_FLAG ((NTSTATUS)0x80000015L) -#define STATUS_VERIFY_REQUIRED ((NTSTATUS)0x80000016L) -#define STATUS_EXTRANEOUS_INFORMATION ((NTSTATUS)0x80000017L) -#define STATUS_RXACT_COMMIT_NECESSARY ((NTSTATUS)0x80000018L) -#define STATUS_NO_MORE_ENTRIES ((NTSTATUS)0x8000001AL) -#define STATUS_FILEMARK_DETECTED ((NTSTATUS)0x8000001BL) -#define STATUS_MEDIA_CHANGED ((NTSTATUS)0x8000001CL) -#define STATUS_BUS_RESET ((NTSTATUS)0x8000001DL) -#define STATUS_END_OF_MEDIA ((NTSTATUS)0x8000001EL) -#define STATUS_BEGINNING_OF_MEDIA ((NTSTATUS)0x8000001FL) -#define STATUS_MEDIA_CHECK ((NTSTATUS)0x80000020L) -#define STATUS_SETMARK_DETECTED ((NTSTATUS)0x80000021L) -#define STATUS_NO_DATA_DETECTED ((NTSTATUS)0x80000022L) -#define STATUS_REDIRECTOR_HAS_OPEN_HANDLES ((NTSTATUS)0x80000023L) -#define STATUS_SERVER_HAS_OPEN_HANDLES ((NTSTATUS)0x80000024L) -#define STATUS_ALREADY_DISCONNECTED ((NTSTATUS)0x80000025L) -#define STATUS_LONGJUMP ((NTSTATUS)0x80000026L) -#define STATUS_CLEANER_CARTRIDGE_INSTALLED ((NTSTATUS)0x80000027L) -#define STATUS_PLUGPLAY_QUERY_VETOED ((NTSTATUS)0x80000028L) -#define STATUS_UNWIND_CONSOLIDATE ((NTSTATUS)0x80000029L) -#define STATUS_CLUSTER_NODE_ALREADY_UP ((NTSTATUS)0x80130001L) -#define STATUS_CLUSTER_NODE_ALREADY_DOWN ((NTSTATUS)0x80130002L) -#define STATUS_CLUSTER_NETWORK_ALREADY_ONLINE ((NTSTATUS)0x80130003L) -#define STATUS_CLUSTER_NETWORK_ALREADY_OFFLINE ((NTSTATUS)0x80130004L) -#define STATUS_CLUSTER_NODE_ALREADY_MEMBER ((NTSTATUS)0x80130005L) -#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) -#define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L) -#define STATUS_INVALID_INFO_CLASS ((NTSTATUS)0xC0000003L) -#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) -#define STATUS_ACCESS_VIOLATION ((NTSTATUS)0xC0000005L) -#define STATUS_IN_PAGE_ERROR ((NTSTATUS)0xC0000006L) -#define STATUS_PAGEFILE_QUOTA ((NTSTATUS)0xC0000007L) -#define STATUS_INVALID_HANDLE ((NTSTATUS)0xC0000008L) -#define STATUS_BAD_INITIAL_STACK ((NTSTATUS)0xC0000009L) -#define STATUS_BAD_INITIAL_PC ((NTSTATUS)0xC000000AL) -#define STATUS_INVALID_CID ((NTSTATUS)0xC000000BL) -#define STATUS_TIMER_NOT_CANCELED ((NTSTATUS)0xC000000CL) -#define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000DL) -#define STATUS_NO_SUCH_DEVICE ((NTSTATUS)0xC000000EL) -#define STATUS_NO_SUCH_FILE ((NTSTATUS)0xC000000FL) -#define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS)0xC0000010L) -#define STATUS_END_OF_FILE ((NTSTATUS)0xC0000011L) -#define STATUS_WRONG_VOLUME ((NTSTATUS)0xC0000012L) -#define STATUS_NO_MEDIA_IN_DEVICE ((NTSTATUS)0xC0000013L) -#define STATUS_UNRECOGNIZED_MEDIA ((NTSTATUS)0xC0000014L) -#define STATUS_NONEXISTENT_SECTOR ((NTSTATUS)0xC0000015L) -#define STATUS_MORE_PROCESSING_REQUIRED ((NTSTATUS)0xC0000016L) -#define STATUS_NO_MEMORY ((NTSTATUS)0xC0000017L) -#define STATUS_CONFLICTING_ADDRESSES ((NTSTATUS)0xC0000018L) -#define STATUS_NOT_MAPPED_VIEW ((NTSTATUS)0xC0000019L) -#define STATUS_UNABLE_TO_FREE_VM ((NTSTATUS)0xC000001AL) -#define STATUS_UNABLE_TO_DELETE_SECTION ((NTSTATUS)0xC000001BL) -#define STATUS_INVALID_SYSTEM_SERVICE ((NTSTATUS)0xC000001CL) -#define STATUS_ILLEGAL_INSTRUCTION ((NTSTATUS)0xC000001DL) -#define STATUS_INVALID_LOCK_SEQUENCE ((NTSTATUS)0xC000001EL) -#define STATUS_INVALID_VIEW_SIZE ((NTSTATUS)0xC000001FL) -#define STATUS_INVALID_FILE_FOR_SECTION ((NTSTATUS)0xC0000020L) -#define STATUS_ALREADY_COMMITTED ((NTSTATUS)0xC0000021L) -#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L) -#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L) -#define STATUS_OBJECT_TYPE_MISMATCH ((NTSTATUS)0xC0000024L) -#define STATUS_NONCONTINUABLE_EXCEPTION ((NTSTATUS)0xC0000025L) -#define STATUS_INVALID_DISPOSITION ((NTSTATUS)0xC0000026L) -#define STATUS_UNWIND ((NTSTATUS)0xC0000027L) -#define STATUS_BAD_STACK ((NTSTATUS)0xC0000028L) -#define STATUS_INVALID_UNWIND_TARGET ((NTSTATUS)0xC0000029L) -#define STATUS_NOT_LOCKED ((NTSTATUS)0xC000002AL) -#define STATUS_PARITY_ERROR ((NTSTATUS)0xC000002BL) -#define STATUS_UNABLE_TO_DECOMMIT_VM ((NTSTATUS)0xC000002CL) -#define STATUS_NOT_COMMITTED ((NTSTATUS)0xC000002DL) -#define STATUS_INVALID_PORT_ATTRIBUTES ((NTSTATUS)0xC000002EL) -#define STATUS_PORT_MESSAGE_TOO_LONG ((NTSTATUS)0xC000002FL) -#define STATUS_INVALID_PARAMETER_MIX ((NTSTATUS)0xC0000030L) -#define STATUS_INVALID_QUOTA_LOWER ((NTSTATUS)0xC0000031L) -#define STATUS_DISK_CORRUPT_ERROR ((NTSTATUS)0xC0000032L) -#define STATUS_OBJECT_NAME_INVALID ((NTSTATUS)0xC0000033L) -#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L) -#define STATUS_OBJECT_NAME_COLLISION ((NTSTATUS)0xC0000035L) -#define STATUS_PORT_DISCONNECTED ((NTSTATUS)0xC0000037L) -#define STATUS_DEVICE_ALREADY_ATTACHED ((NTSTATUS)0xC0000038L) -#define STATUS_OBJECT_PATH_INVALID ((NTSTATUS)0xC0000039L) -#define STATUS_OBJECT_PATH_NOT_FOUND ((NTSTATUS)0xC000003AL) -#define STATUS_OBJECT_PATH_SYNTAX_BAD ((NTSTATUS)0xC000003BL) -#define STATUS_DATA_OVERRUN ((NTSTATUS)0xC000003CL) -#define STATUS_DATA_LATE_ERROR ((NTSTATUS)0xC000003DL) -#define STATUS_DATA_ERROR ((NTSTATUS)0xC000003EL) -#define STATUS_CRC_ERROR ((NTSTATUS)0xC000003FL) -#define STATUS_SECTION_TOO_BIG ((NTSTATUS)0xC0000040L) -#define STATUS_PORT_CONNECTION_REFUSED ((NTSTATUS)0xC0000041L) -#define STATUS_INVALID_PORT_HANDLE ((NTSTATUS)0xC0000042L) -#define STATUS_SHARING_VIOLATION ((NTSTATUS)0xC0000043L) -#define STATUS_QUOTA_EXCEEDED ((NTSTATUS)0xC0000044L) -#define STATUS_INVALID_PAGE_PROTECTION ((NTSTATUS)0xC0000045L) -#define STATUS_MUTANT_NOT_OWNED ((NTSTATUS)0xC0000046L) -#define STATUS_SEMAPHORE_LIMIT_EXCEEDED ((NTSTATUS)0xC0000047L) -#define STATUS_PORT_ALREADY_SET ((NTSTATUS)0xC0000048L) -#define STATUS_SECTION_NOT_IMAGE ((NTSTATUS)0xC0000049L) -#define STATUS_SUSPEND_COUNT_EXCEEDED ((NTSTATUS)0xC000004AL) -#define STATUS_THREAD_IS_TERMINATING ((NTSTATUS)0xC000004BL) -#define STATUS_BAD_WORKING_SET_LIMIT ((NTSTATUS)0xC000004CL) -#define STATUS_INCOMPATIBLE_FILE_MAP ((NTSTATUS)0xC000004DL) -#define STATUS_SECTION_PROTECTION ((NTSTATUS)0xC000004EL) -#define STATUS_EAS_NOT_SUPPORTED ((NTSTATUS)0xC000004FL) -#define STATUS_EA_TOO_LARGE ((NTSTATUS)0xC0000050L) -#define STATUS_NONEXISTENT_EA_ENTRY ((NTSTATUS)0xC0000051L) -#define STATUS_NO_EAS_ON_FILE ((NTSTATUS)0xC0000052L) -#define STATUS_EA_CORRUPT_ERROR ((NTSTATUS)0xC0000053L) -#define STATUS_FILE_LOCK_CONFLICT ((NTSTATUS)0xC0000054L) -#define STATUS_LOCK_NOT_GRANTED ((NTSTATUS)0xC0000055L) -#define STATUS_DELETE_PENDING ((NTSTATUS)0xC0000056L) -#define STATUS_CTL_FILE_NOT_SUPPORTED ((NTSTATUS)0xC0000057L) -#define STATUS_UNKNOWN_REVISION ((NTSTATUS)0xC0000058L) -#define STATUS_REVISION_MISMATCH ((NTSTATUS)0xC0000059L) -#define STATUS_INVALID_OWNER ((NTSTATUS)0xC000005AL) -#define STATUS_INVALID_PRIMARY_GROUP ((NTSTATUS)0xC000005BL) -#define STATUS_NO_IMPERSONATION_TOKEN ((NTSTATUS)0xC000005CL) -#define STATUS_CANT_DISABLE_MANDATORY ((NTSTATUS)0xC000005DL) -#define STATUS_NO_LOGON_SERVERS ((NTSTATUS)0xC000005EL) -#define STATUS_NO_SUCH_LOGON_SESSION ((NTSTATUS)0xC000005FL) -#define STATUS_NO_SUCH_PRIVILEGE ((NTSTATUS)0xC0000060L) -#define STATUS_PRIVILEGE_NOT_HELD ((NTSTATUS)0xC0000061L) -#define STATUS_INVALID_ACCOUNT_NAME ((NTSTATUS)0xC0000062L) -#define STATUS_USER_EXISTS ((NTSTATUS)0xC0000063L) -#define STATUS_NO_SUCH_USER ((NTSTATUS)0xC0000064L) -#define STATUS_GROUP_EXISTS ((NTSTATUS)0xC0000065L) -#define STATUS_NO_SUCH_GROUP ((NTSTATUS)0xC0000066L) -#define STATUS_MEMBER_IN_GROUP ((NTSTATUS)0xC0000067L) -#define STATUS_MEMBER_NOT_IN_GROUP ((NTSTATUS)0xC0000068L) -#define STATUS_LAST_ADMIN ((NTSTATUS)0xC0000069L) -#define STATUS_WRONG_PASSWORD ((NTSTATUS)0xC000006AL) -#define STATUS_ILL_FORMED_PASSWORD ((NTSTATUS)0xC000006BL) -#define STATUS_PASSWORD_RESTRICTION ((NTSTATUS)0xC000006CL) -#define STATUS_LOGON_FAILURE ((NTSTATUS)0xC000006DL) -#define STATUS_ACCOUNT_RESTRICTION ((NTSTATUS)0xC000006EL) -#define STATUS_INVALID_LOGON_HOURS ((NTSTATUS)0xC000006FL) -#define STATUS_INVALID_WORKSTATION ((NTSTATUS)0xC0000070L) -#define STATUS_PASSWORD_EXPIRED ((NTSTATUS)0xC0000071L) -#define STATUS_ACCOUNT_DISABLED ((NTSTATUS)0xC0000072L) -#define STATUS_NONE_MAPPED ((NTSTATUS)0xC0000073L) -#define STATUS_TOO_MANY_LUIDS_REQUESTED ((NTSTATUS)0xC0000074L) -#define STATUS_LUIDS_EXHAUSTED ((NTSTATUS)0xC0000075L) -#define STATUS_INVALID_SUB_AUTHORITY ((NTSTATUS)0xC0000076L) -#define STATUS_INVALID_ACL ((NTSTATUS)0xC0000077L) -#define STATUS_INVALID_SID ((NTSTATUS)0xC0000078L) -#define STATUS_INVALID_SECURITY_DESCR ((NTSTATUS)0xC0000079L) -#define STATUS_PROCEDURE_NOT_FOUND ((NTSTATUS)0xC000007AL) -#define STATUS_INVALID_IMAGE_FORMAT ((NTSTATUS)0xC000007BL) -#define STATUS_NO_TOKEN ((NTSTATUS)0xC000007CL) -#define STATUS_BAD_INHERITANCE_ACL ((NTSTATUS)0xC000007DL) -#define STATUS_RANGE_NOT_LOCKED ((NTSTATUS)0xC000007EL) -#define STATUS_DISK_FULL ((NTSTATUS)0xC000007FL) -#define STATUS_SERVER_DISABLED ((NTSTATUS)0xC0000080L) -#define STATUS_SERVER_NOT_DISABLED ((NTSTATUS)0xC0000081L) -#define STATUS_TOO_MANY_GUIDS_REQUESTED ((NTSTATUS)0xC0000082L) -#define STATUS_GUIDS_EXHAUSTED ((NTSTATUS)0xC0000083L) -#define STATUS_INVALID_ID_AUTHORITY ((NTSTATUS)0xC0000084L) -#define STATUS_AGENTS_EXHAUSTED ((NTSTATUS)0xC0000085L) -#define STATUS_INVALID_VOLUME_LABEL ((NTSTATUS)0xC0000086L) -#define STATUS_SECTION_NOT_EXTENDED ((NTSTATUS)0xC0000087L) -#define STATUS_NOT_MAPPED_DATA ((NTSTATUS)0xC0000088L) -#define STATUS_RESOURCE_DATA_NOT_FOUND ((NTSTATUS)0xC0000089L) -#define STATUS_RESOURCE_TYPE_NOT_FOUND ((NTSTATUS)0xC000008AL) -#define STATUS_RESOURCE_NAME_NOT_FOUND ((NTSTATUS)0xC000008BL) -#define STATUS_ARRAY_BOUNDS_EXCEEDED ((NTSTATUS)0xC000008CL) -#define STATUS_FLOAT_DENORMAL_OPERAND ((NTSTATUS)0xC000008DL) -#define STATUS_FLOAT_DIVIDE_BY_ZERO ((NTSTATUS)0xC000008EL) -#define STATUS_FLOAT_INEXACT_RESULT ((NTSTATUS)0xC000008FL) -#define STATUS_FLOAT_INVALID_OPERATION ((NTSTATUS)0xC0000090L) -#define STATUS_FLOAT_OVERFLOW ((NTSTATUS)0xC0000091L) -#define STATUS_FLOAT_STACK_CHECK ((NTSTATUS)0xC0000092L) -#define STATUS_FLOAT_UNDERFLOW ((NTSTATUS)0xC0000093L) -#define STATUS_INTEGER_DIVIDE_BY_ZERO ((NTSTATUS)0xC0000094L) -#define STATUS_INTEGER_OVERFLOW ((NTSTATUS)0xC0000095L) -#define STATUS_PRIVILEGED_INSTRUCTION ((NTSTATUS)0xC0000096L) -#define STATUS_TOO_MANY_PAGING_FILES ((NTSTATUS)0xC0000097L) -#define STATUS_FILE_INVALID ((NTSTATUS)0xC0000098L) -#define STATUS_ALLOTTED_SPACE_EXCEEDED ((NTSTATUS)0xC0000099L) -#define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS)0xC000009AL) -#define STATUS_DFS_EXIT_PATH_FOUND ((NTSTATUS)0xC000009BL) -#define STATUS_DEVICE_DATA_ERROR ((NTSTATUS)0xC000009CL) -#define STATUS_DEVICE_NOT_CONNECTED ((NTSTATUS)0xC000009DL) -#define STATUS_DEVICE_POWER_FAILURE ((NTSTATUS)0xC000009EL) -#define STATUS_FREE_VM_NOT_AT_BASE ((NTSTATUS)0xC000009FL) -#define STATUS_MEMORY_NOT_ALLOCATED ((NTSTATUS)0xC00000A0L) -#define STATUS_WORKING_SET_QUOTA ((NTSTATUS)0xC00000A1L) -#define STATUS_MEDIA_WRITE_PROTECTED ((NTSTATUS)0xC00000A2L) -#define STATUS_DEVICE_NOT_READY ((NTSTATUS)0xC00000A3L) -#define STATUS_INVALID_GROUP_ATTRIBUTES ((NTSTATUS)0xC00000A4L) -#define STATUS_BAD_IMPERSONATION_LEVEL ((NTSTATUS)0xC00000A5L) -#define STATUS_CANT_OPEN_ANONYMOUS ((NTSTATUS)0xC00000A6L) -#define STATUS_BAD_VALIDATION_CLASS ((NTSTATUS)0xC00000A7L) -#define STATUS_BAD_TOKEN_TYPE ((NTSTATUS)0xC00000A8L) -#define STATUS_BAD_MASTER_BOOT_RECORD ((NTSTATUS)0xC00000A9L) -#define STATUS_INSTRUCTION_MISALIGNMENT ((NTSTATUS)0xC00000AAL) -#define STATUS_INSTANCE_NOT_AVAILABLE ((NTSTATUS)0xC00000ABL) -#define STATUS_PIPE_NOT_AVAILABLE ((NTSTATUS)0xC00000ACL) -#define STATUS_INVALID_PIPE_STATE ((NTSTATUS)0xC00000ADL) -#define STATUS_PIPE_BUSY ((NTSTATUS)0xC00000AEL) -#define STATUS_ILLEGAL_FUNCTION ((NTSTATUS)0xC00000AFL) -#define STATUS_PIPE_DISCONNECTED ((NTSTATUS)0xC00000B0L) -#define STATUS_PIPE_CLOSING ((NTSTATUS)0xC00000B1L) -#define STATUS_PIPE_CONNECTED ((NTSTATUS)0xC00000B2L) -#define STATUS_PIPE_LISTENING ((NTSTATUS)0xC00000B3L) -#define STATUS_INVALID_READ_MODE ((NTSTATUS)0xC00000B4L) -#define STATUS_IO_TIMEOUT ((NTSTATUS)0xC00000B5L) -#define STATUS_FILE_FORCED_CLOSED ((NTSTATUS)0xC00000B6L) -#define STATUS_PROFILING_NOT_STARTED ((NTSTATUS)0xC00000B7L) -#define STATUS_PROFILING_NOT_STOPPED ((NTSTATUS)0xC00000B8L) -#define STATUS_COULD_NOT_INTERPRET ((NTSTATUS)0xC00000B9L) -#define STATUS_FILE_IS_A_DIRECTORY ((NTSTATUS)0xC00000BAL) -#define STATUS_NOT_SUPPORTED ((NTSTATUS)0xC00000BBL) -#define STATUS_REMOTE_NOT_LISTENING ((NTSTATUS)0xC00000BCL) -#define STATUS_DUPLICATE_NAME ((NTSTATUS)0xC00000BDL) -#define STATUS_BAD_NETWORK_PATH ((NTSTATUS)0xC00000BEL) -#define STATUS_NETWORK_BUSY ((NTSTATUS)0xC00000BFL) -#define STATUS_DEVICE_DOES_NOT_EXIST ((NTSTATUS)0xC00000C0L) -#define STATUS_TOO_MANY_COMMANDS ((NTSTATUS)0xC00000C1L) -#define STATUS_ADAPTER_HARDWARE_ERROR ((NTSTATUS)0xC00000C2L) -#define STATUS_INVALID_NETWORK_RESPONSE ((NTSTATUS)0xC00000C3L) -#define STATUS_UNEXPECTED_NETWORK_ERROR ((NTSTATUS)0xC00000C4L) -#define STATUS_BAD_REMOTE_ADAPTER ((NTSTATUS)0xC00000C5L) -#define STATUS_PRINT_QUEUE_FULL ((NTSTATUS)0xC00000C6L) -#define STATUS_NO_SPOOL_SPACE ((NTSTATUS)0xC00000C7L) -#define STATUS_PRINT_CANCELLED ((NTSTATUS)0xC00000C8L) -#define STATUS_NETWORK_NAME_DELETED ((NTSTATUS)0xC00000C9L) -#define STATUS_NETWORK_ACCESS_DENIED ((NTSTATUS)0xC00000CAL) -#define STATUS_BAD_DEVICE_TYPE ((NTSTATUS)0xC00000CBL) -#define STATUS_BAD_NETWORK_NAME ((NTSTATUS)0xC00000CCL) -#define STATUS_TOO_MANY_NAMES ((NTSTATUS)0xC00000CDL) -#define STATUS_TOO_MANY_SESSIONS ((NTSTATUS)0xC00000CEL) -#define STATUS_SHARING_PAUSED ((NTSTATUS)0xC00000CFL) -#define STATUS_REQUEST_NOT_ACCEPTED ((NTSTATUS)0xC00000D0L) -#define STATUS_REDIRECTOR_PAUSED ((NTSTATUS)0xC00000D1L) -#define STATUS_NET_WRITE_FAULT ((NTSTATUS)0xC00000D2L) -#define STATUS_PROFILING_AT_LIMIT ((NTSTATUS)0xC00000D3L) -#define STATUS_NOT_SAME_DEVICE ((NTSTATUS)0xC00000D4L) -#define STATUS_FILE_RENAMED ((NTSTATUS)0xC00000D5L) -#define STATUS_VIRTUAL_CIRCUIT_CLOSED ((NTSTATUS)0xC00000D6L) -#define STATUS_NO_SECURITY_ON_OBJECT ((NTSTATUS)0xC00000D7L) -#define STATUS_CANT_WAIT ((NTSTATUS)0xC00000D8L) -#define STATUS_PIPE_EMPTY ((NTSTATUS)0xC00000D9L) -#define STATUS_CANT_ACCESS_DOMAIN_INFO ((NTSTATUS)0xC00000DAL) -#define STATUS_CANT_TERMINATE_SELF ((NTSTATUS)0xC00000DBL) -#define STATUS_INVALID_SERVER_STATE ((NTSTATUS)0xC00000DCL) -#define STATUS_INVALID_DOMAIN_STATE ((NTSTATUS)0xC00000DDL) -#define STATUS_INVALID_DOMAIN_ROLE ((NTSTATUS)0xC00000DEL) -#define STATUS_NO_SUCH_DOMAIN ((NTSTATUS)0xC00000DFL) -#define STATUS_DOMAIN_EXISTS ((NTSTATUS)0xC00000E0L) -#define STATUS_DOMAIN_LIMIT_EXCEEDED ((NTSTATUS)0xC00000E1L) -#define STATUS_OPLOCK_NOT_GRANTED ((NTSTATUS)0xC00000E2L) -#define STATUS_INVALID_OPLOCK_PROTOCOL ((NTSTATUS)0xC00000E3L) -#define STATUS_INTERNAL_DB_CORRUPTION ((NTSTATUS)0xC00000E4L) -#define STATUS_INTERNAL_ERROR ((NTSTATUS)0xC00000E5L) -#define STATUS_GENERIC_NOT_MAPPED ((NTSTATUS)0xC00000E6L) -#define STATUS_BAD_DESCRIPTOR_FORMAT ((NTSTATUS)0xC00000E7L) -#define STATUS_INVALID_USER_BUFFER ((NTSTATUS)0xC00000E8L) -#define STATUS_UNEXPECTED_IO_ERROR ((NTSTATUS)0xC00000E9L) -#define STATUS_UNEXPECTED_MM_CREATE_ERR ((NTSTATUS)0xC00000EAL) -#define STATUS_UNEXPECTED_MM_MAP_ERROR ((NTSTATUS)0xC00000EBL) -#define STATUS_UNEXPECTED_MM_EXTEND_ERR ((NTSTATUS)0xC00000ECL) -#define STATUS_NOT_LOGON_PROCESS ((NTSTATUS)0xC00000EDL) -#define STATUS_LOGON_SESSION_EXISTS ((NTSTATUS)0xC00000EEL) -#define STATUS_INVALID_PARAMETER_1 ((NTSTATUS)0xC00000EFL) -#define STATUS_INVALID_PARAMETER_2 ((NTSTATUS)0xC00000F0L) -#define STATUS_INVALID_PARAMETER_3 ((NTSTATUS)0xC00000F1L) -#define STATUS_INVALID_PARAMETER_4 ((NTSTATUS)0xC00000F2L) -#define STATUS_INVALID_PARAMETER_5 ((NTSTATUS)0xC00000F3L) -#define STATUS_INVALID_PARAMETER_6 ((NTSTATUS)0xC00000F4L) -#define STATUS_INVALID_PARAMETER_7 ((NTSTATUS)0xC00000F5L) -#define STATUS_INVALID_PARAMETER_8 ((NTSTATUS)0xC00000F6L) -#define STATUS_INVALID_PARAMETER_9 ((NTSTATUS)0xC00000F7L) -#define STATUS_INVALID_PARAMETER_10 ((NTSTATUS)0xC00000F8L) -#define STATUS_INVALID_PARAMETER_11 ((NTSTATUS)0xC00000F9L) -#define STATUS_INVALID_PARAMETER_12 ((NTSTATUS)0xC00000FAL) -#define STATUS_REDIRECTOR_NOT_STARTED ((NTSTATUS)0xC00000FBL) -#define STATUS_REDIRECTOR_STARTED ((NTSTATUS)0xC00000FCL) -#define STATUS_STACK_OVERFLOW ((NTSTATUS)0xC00000FDL) -#define STATUS_NO_SUCH_PACKAGE ((NTSTATUS)0xC00000FEL) -#define STATUS_BAD_FUNCTION_TABLE ((NTSTATUS)0xC00000FFL) -#define STATUS_VARIABLE_NOT_FOUND ((NTSTATUS)0xC0000100L) -#define STATUS_DIRECTORY_NOT_EMPTY ((NTSTATUS)0xC0000101L) -#define STATUS_FILE_CORRUPT_ERROR ((NTSTATUS)0xC0000102L) -#define STATUS_NOT_A_DIRECTORY ((NTSTATUS)0xC0000103L) -#define STATUS_BAD_LOGON_SESSION_STATE ((NTSTATUS)0xC0000104L) -#define STATUS_LOGON_SESSION_COLLISION ((NTSTATUS)0xC0000105L) -#define STATUS_NAME_TOO_LONG ((NTSTATUS)0xC0000106L) -#define STATUS_FILES_OPEN ((NTSTATUS)0xC0000107L) -#define STATUS_CONNECTION_IN_USE ((NTSTATUS)0xC0000108L) -#define STATUS_MESSAGE_NOT_FOUND ((NTSTATUS)0xC0000109L) -#define STATUS_PROCESS_IS_TERMINATING ((NTSTATUS)0xC000010AL) -#define STATUS_INVALID_LOGON_TYPE ((NTSTATUS)0xC000010BL) -#define STATUS_NO_GUID_TRANSLATION ((NTSTATUS)0xC000010CL) -#define STATUS_CANNOT_IMPERSONATE ((NTSTATUS)0xC000010DL) -#define STATUS_IMAGE_ALREADY_LOADED ((NTSTATUS)0xC000010EL) -#define STATUS_ABIOS_NOT_PRESENT ((NTSTATUS)0xC000010FL) -#define STATUS_ABIOS_LID_NOT_EXIST ((NTSTATUS)0xC0000110L) -#define STATUS_ABIOS_LID_ALREADY_OWNED ((NTSTATUS)0xC0000111L) -#define STATUS_ABIOS_NOT_LID_OWNER ((NTSTATUS)0xC0000112L) -#define STATUS_ABIOS_INVALID_COMMAND ((NTSTATUS)0xC0000113L) -#define STATUS_ABIOS_INVALID_LID ((NTSTATUS)0xC0000114L) -#define STATUS_ABIOS_SELECTOR_NOT_AVAILABLE ((NTSTATUS)0xC0000115L) -#define STATUS_ABIOS_INVALID_SELECTOR ((NTSTATUS)0xC0000116L) -#define STATUS_NO_LDT ((NTSTATUS)0xC0000117L) -#define STATUS_INVALID_LDT_SIZE ((NTSTATUS)0xC0000118L) -#define STATUS_INVALID_LDT_OFFSET ((NTSTATUS)0xC0000119L) -#define STATUS_INVALID_LDT_DESCRIPTOR ((NTSTATUS)0xC000011AL) -#define STATUS_INVALID_IMAGE_NE_FORMAT ((NTSTATUS)0xC000011BL) -#define STATUS_RXACT_INVALID_STATE ((NTSTATUS)0xC000011CL) -#define STATUS_RXACT_COMMIT_FAILURE ((NTSTATUS)0xC000011DL) -#define STATUS_MAPPED_FILE_SIZE_ZERO ((NTSTATUS)0xC000011EL) -#define STATUS_TOO_MANY_OPENED_FILES ((NTSTATUS)0xC000011FL) -#define STATUS_CANCELLED ((NTSTATUS)0xC0000120L) -#define STATUS_CANNOT_DELETE ((NTSTATUS)0xC0000121L) -#define STATUS_INVALID_COMPUTER_NAME ((NTSTATUS)0xC0000122L) -#define STATUS_FILE_DELETED ((NTSTATUS)0xC0000123L) -#define STATUS_SPECIAL_ACCOUNT ((NTSTATUS)0xC0000124L) -#define STATUS_SPECIAL_GROUP ((NTSTATUS)0xC0000125L) -#define STATUS_SPECIAL_USER ((NTSTATUS)0xC0000126L) -#define STATUS_MEMBERS_PRIMARY_GROUP ((NTSTATUS)0xC0000127L) -#define STATUS_FILE_CLOSED ((NTSTATUS)0xC0000128L) -#define STATUS_TOO_MANY_THREADS ((NTSTATUS)0xC0000129L) -#define STATUS_THREAD_NOT_IN_PROCESS ((NTSTATUS)0xC000012AL) -#define STATUS_TOKEN_ALREADY_IN_USE ((NTSTATUS)0xC000012BL) -#define STATUS_PAGEFILE_QUOTA_EXCEEDED ((NTSTATUS)0xC000012CL) -#define STATUS_COMMITMENT_LIMIT ((NTSTATUS)0xC000012DL) -#define STATUS_INVALID_IMAGE_LE_FORMAT ((NTSTATUS)0xC000012EL) -#define STATUS_INVALID_IMAGE_NOT_MZ ((NTSTATUS)0xC000012FL) -#define STATUS_INVALID_IMAGE_PROTECT ((NTSTATUS)0xC0000130L) -#define STATUS_INVALID_IMAGE_WIN_16 ((NTSTATUS)0xC0000131L) -#define STATUS_LOGON_SERVER_CONFLICT ((NTSTATUS)0xC0000132L) -#define STATUS_TIME_DIFFERENCE_AT_DC ((NTSTATUS)0xC0000133L) -#define STATUS_SYNCHRONIZATION_REQUIRED ((NTSTATUS)0xC0000134L) -#define STATUS_DLL_NOT_FOUND ((NTSTATUS)0xC0000135L) -#define STATUS_OPEN_FAILED ((NTSTATUS)0xC0000136L) -#define STATUS_IO_PRIVILEGE_FAILED ((NTSTATUS)0xC0000137L) -#define STATUS_ORDINAL_NOT_FOUND ((NTSTATUS)0xC0000138L) -#define STATUS_ENTRYPOINT_NOT_FOUND ((NTSTATUS)0xC0000139L) -#define STATUS_CONTROL_C_EXIT ((NTSTATUS)0xC000013AL) -#define STATUS_LOCAL_DISCONNECT ((NTSTATUS)0xC000013BL) -#define STATUS_REMOTE_DISCONNECT ((NTSTATUS)0xC000013CL) -#define STATUS_REMOTE_RESOURCES ((NTSTATUS)0xC000013DL) -#define STATUS_LINK_FAILED ((NTSTATUS)0xC000013EL) -#define STATUS_LINK_TIMEOUT ((NTSTATUS)0xC000013FL) -#define STATUS_INVALID_CONNECTION ((NTSTATUS)0xC0000140L) -#define STATUS_INVALID_ADDRESS ((NTSTATUS)0xC0000141L) -#define STATUS_DLL_INIT_FAILED ((NTSTATUS)0xC0000142L) -#define STATUS_MISSING_SYSTEMFILE ((NTSTATUS)0xC0000143L) -#define STATUS_UNHANDLED_EXCEPTION ((NTSTATUS)0xC0000144L) -#define STATUS_APP_INIT_FAILURE ((NTSTATUS)0xC0000145L) -#define STATUS_PAGEFILE_CREATE_FAILED ((NTSTATUS)0xC0000146L) -#define STATUS_NO_PAGEFILE ((NTSTATUS)0xC0000147L) -#define STATUS_INVALID_LEVEL ((NTSTATUS)0xC0000148L) -#define STATUS_WRONG_PASSWORD_CORE ((NTSTATUS)0xC0000149L) -#define STATUS_ILLEGAL_FLOAT_CONTEXT ((NTSTATUS)0xC000014AL) -#define STATUS_PIPE_BROKEN ((NTSTATUS)0xC000014BL) -#define STATUS_REGISTRY_CORRUPT ((NTSTATUS)0xC000014CL) -#define STATUS_REGISTRY_IO_FAILED ((NTSTATUS)0xC000014DL) -#define STATUS_NO_EVENT_PAIR ((NTSTATUS)0xC000014EL) -#define STATUS_UNRECOGNIZED_VOLUME ((NTSTATUS)0xC000014FL) -#define STATUS_SERIAL_NO_DEVICE_INITED ((NTSTATUS)0xC0000150L) -#define STATUS_NO_SUCH_ALIAS ((NTSTATUS)0xC0000151L) -#define STATUS_MEMBER_NOT_IN_ALIAS ((NTSTATUS)0xC0000152L) -#define STATUS_MEMBER_IN_ALIAS ((NTSTATUS)0xC0000153L) -#define STATUS_ALIAS_EXISTS ((NTSTATUS)0xC0000154L) -#define STATUS_LOGON_NOT_GRANTED ((NTSTATUS)0xC0000155L) -#define STATUS_TOO_MANY_SECRETS ((NTSTATUS)0xC0000156L) -#define STATUS_SECRET_TOO_LONG ((NTSTATUS)0xC0000157L) -#define STATUS_INTERNAL_DB_ERROR ((NTSTATUS)0xC0000158L) -#define STATUS_FULLSCREEN_MODE ((NTSTATUS)0xC0000159L) -#define STATUS_TOO_MANY_CONTEXT_IDS ((NTSTATUS)0xC000015AL) -#define STATUS_LOGON_TYPE_NOT_GRANTED ((NTSTATUS)0xC000015BL) -#define STATUS_NOT_REGISTRY_FILE ((NTSTATUS)0xC000015CL) -#define STATUS_NT_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS)0xC000015DL) -#define STATUS_DOMAIN_CTRLR_CONFIG_ERROR ((NTSTATUS)0xC000015EL) -#define STATUS_FT_MISSING_MEMBER ((NTSTATUS)0xC000015FL) -#define STATUS_ILL_FORMED_SERVICE_ENTRY ((NTSTATUS)0xC0000160L) -#define STATUS_ILLEGAL_CHARACTER ((NTSTATUS)0xC0000161L) -#define STATUS_UNMAPPABLE_CHARACTER ((NTSTATUS)0xC0000162L) -#define STATUS_UNDEFINED_CHARACTER ((NTSTATUS)0xC0000163L) -#define STATUS_FLOPPY_VOLUME ((NTSTATUS)0xC0000164L) -#define STATUS_FLOPPY_ID_MARK_NOT_FOUND ((NTSTATUS)0xC0000165L) -#define STATUS_FLOPPY_WRONG_CYLINDER ((NTSTATUS)0xC0000166L) -#define STATUS_FLOPPY_UNKNOWN_ERROR ((NTSTATUS)0xC0000167L) -#define STATUS_FLOPPY_BAD_REGISTERS ((NTSTATUS)0xC0000168L) -#define STATUS_DISK_RECALIBRATE_FAILED ((NTSTATUS)0xC0000169L) -#define STATUS_DISK_OPERATION_FAILED ((NTSTATUS)0xC000016AL) -#define STATUS_DISK_RESET_FAILED ((NTSTATUS)0xC000016BL) -#define STATUS_SHARED_IRQ_BUSY ((NTSTATUS)0xC000016CL) -#define STATUS_FT_ORPHANING ((NTSTATUS)0xC000016DL) -#define STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT ((NTSTATUS)0xC000016EL) -#define STATUS_PARTITION_FAILURE ((NTSTATUS)0xC0000172L) -#define STATUS_INVALID_BLOCK_LENGTH ((NTSTATUS)0xC0000173L) -#define STATUS_DEVICE_NOT_PARTITIONED ((NTSTATUS)0xC0000174L) -#define STATUS_UNABLE_TO_LOCK_MEDIA ((NTSTATUS)0xC0000175L) -#define STATUS_UNABLE_TO_UNLOAD_MEDIA ((NTSTATUS)0xC0000176L) -#define STATUS_EOM_OVERFLOW ((NTSTATUS)0xC0000177L) -#define STATUS_NO_MEDIA ((NTSTATUS)0xC0000178L) -#define STATUS_NO_SUCH_MEMBER ((NTSTATUS)0xC000017AL) -#define STATUS_INVALID_MEMBER ((NTSTATUS)0xC000017BL) -#define STATUS_KEY_DELETED ((NTSTATUS)0xC000017CL) -#define STATUS_NO_LOG_SPACE ((NTSTATUS)0xC000017DL) -#define STATUS_TOO_MANY_SIDS ((NTSTATUS)0xC000017EL) -#define STATUS_LM_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS)0xC000017FL) -#define STATUS_KEY_HAS_CHILDREN ((NTSTATUS)0xC0000180L) -#define STATUS_CHILD_MUST_BE_VOLATILE ((NTSTATUS)0xC0000181L) -#define STATUS_DEVICE_CONFIGURATION_ERROR ((NTSTATUS)0xC0000182L) -#define STATUS_DRIVER_INTERNAL_ERROR ((NTSTATUS)0xC0000183L) -#define STATUS_INVALID_DEVICE_STATE ((NTSTATUS)0xC0000184L) -#define STATUS_IO_DEVICE_ERROR ((NTSTATUS)0xC0000185L) -#define STATUS_DEVICE_PROTOCOL_ERROR ((NTSTATUS)0xC0000186L) -#define STATUS_BACKUP_CONTROLLER ((NTSTATUS)0xC0000187L) -#define STATUS_LOG_FILE_FULL ((NTSTATUS)0xC0000188L) -#define STATUS_TOO_LATE ((NTSTATUS)0xC0000189L) -#define STATUS_NO_TRUST_LSA_SECRET ((NTSTATUS)0xC000018AL) -#define STATUS_NO_TRUST_SAM_ACCOUNT ((NTSTATUS)0xC000018BL) -#define STATUS_TRUSTED_DOMAIN_FAILURE ((NTSTATUS)0xC000018CL) -#define STATUS_TRUSTED_RELATIONSHIP_FAILURE ((NTSTATUS)0xC000018DL) -#define STATUS_EVENTLOG_FILE_CORRUPT ((NTSTATUS)0xC000018EL) -#define STATUS_EVENTLOG_CANT_START ((NTSTATUS)0xC000018FL) -#define STATUS_TRUST_FAILURE ((NTSTATUS)0xC0000190L) -#define STATUS_MUTANT_LIMIT_EXCEEDED ((NTSTATUS)0xC0000191L) -#define STATUS_NETLOGON_NOT_STARTED ((NTSTATUS)0xC0000192L) -#define STATUS_ACCOUNT_EXPIRED ((NTSTATUS)0xC0000193L) -#define STATUS_POSSIBLE_DEADLOCK ((NTSTATUS)0xC0000194L) -#define STATUS_NETWORK_CREDENTIAL_CONFLICT ((NTSTATUS)0xC0000195L) -#define STATUS_REMOTE_SESSION_LIMIT ((NTSTATUS)0xC0000196L) -#define STATUS_EVENTLOG_FILE_CHANGED ((NTSTATUS)0xC0000197L) -#define STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT ((NTSTATUS)0xC0000198L) -#define STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT ((NTSTATUS)0xC0000199L) -#define STATUS_NOLOGON_SERVER_TRUST_ACCOUNT ((NTSTATUS)0xC000019AL) -#define STATUS_DOMAIN_TRUST_INCONSISTENT ((NTSTATUS)0xC000019BL) -#define STATUS_FS_DRIVER_REQUIRED ((NTSTATUS)0xC000019CL) -#define STATUS_NO_USER_SESSION_KEY ((NTSTATUS)0xC0000202L) -#define STATUS_USER_SESSION_DELETED ((NTSTATUS)0xC0000203L) -#define STATUS_RESOURCE_LANG_NOT_FOUND ((NTSTATUS)0xC0000204L) -#define STATUS_INSUFF_SERVER_RESOURCES ((NTSTATUS)0xC0000205L) -#define STATUS_INVALID_BUFFER_SIZE ((NTSTATUS)0xC0000206L) -#define STATUS_INVALID_ADDRESS_COMPONENT ((NTSTATUS)0xC0000207L) -#define STATUS_INVALID_ADDRESS_WILDCARD ((NTSTATUS)0xC0000208L) -#define STATUS_TOO_MANY_ADDRESSES ((NTSTATUS)0xC0000209L) -#define STATUS_ADDRESS_ALREADY_EXISTS ((NTSTATUS)0xC000020AL) -#define STATUS_ADDRESS_CLOSED ((NTSTATUS)0xC000020BL) -#define STATUS_CONNECTION_DISCONNECTED ((NTSTATUS)0xC000020CL) -#define STATUS_CONNECTION_RESET ((NTSTATUS)0xC000020DL) -#define STATUS_TOO_MANY_NODES ((NTSTATUS)0xC000020EL) -#define STATUS_TRANSACTION_ABORTED ((NTSTATUS)0xC000020FL) -#define STATUS_TRANSACTION_TIMED_OUT ((NTSTATUS)0xC0000210L) -#define STATUS_TRANSACTION_NO_RELEASE ((NTSTATUS)0xC0000211L) -#define STATUS_TRANSACTION_NO_MATCH ((NTSTATUS)0xC0000212L) -#define STATUS_TRANSACTION_RESPONDED ((NTSTATUS)0xC0000213L) -#define STATUS_TRANSACTION_INVALID_ID ((NTSTATUS)0xC0000214L) -#define STATUS_TRANSACTION_INVALID_TYPE ((NTSTATUS)0xC0000215L) -#define STATUS_NOT_SERVER_SESSION ((NTSTATUS)0xC0000216L) -#define STATUS_NOT_CLIENT_SESSION ((NTSTATUS)0xC0000217L) -#define STATUS_CANNOT_LOAD_REGISTRY_FILE ((NTSTATUS)0xC0000218L) -#define STATUS_DEBUG_ATTACH_FAILED ((NTSTATUS)0xC0000219L) -#define STATUS_SYSTEM_PROCESS_TERMINATED ((NTSTATUS)0xC000021AL) -#define STATUS_DATA_NOT_ACCEPTED ((NTSTATUS)0xC000021BL) -#define STATUS_NO_BROWSER_SERVERS_FOUND ((NTSTATUS)0xC000021CL) -#define STATUS_VDM_HARD_ERROR ((NTSTATUS)0xC000021DL) -#define STATUS_DRIVER_CANCEL_TIMEOUT ((NTSTATUS)0xC000021EL) -#define STATUS_REPLY_MESSAGE_MISMATCH ((NTSTATUS)0xC000021FL) -#define STATUS_MAPPED_ALIGNMENT ((NTSTATUS)0xC0000220L) -#define STATUS_IMAGE_CHECKSUM_MISMATCH ((NTSTATUS)0xC0000221L) -#define STATUS_LOST_WRITEBEHIND_DATA ((NTSTATUS)0xC0000222L) -#define STATUS_CLIENT_SERVER_PARAMETERS_INVALID ((NTSTATUS)0xC0000223L) -#define STATUS_PASSWORD_MUST_CHANGE ((NTSTATUS)0xC0000224L) -#define STATUS_NOT_FOUND ((NTSTATUS)0xC0000225L) -#define STATUS_NOT_TINY_STREAM ((NTSTATUS)0xC0000226L) -#define STATUS_RECOVERY_FAILURE ((NTSTATUS)0xC0000227L) -#define STATUS_STACK_OVERFLOW_READ ((NTSTATUS)0xC0000228L) -#define STATUS_FAIL_CHECK ((NTSTATUS)0xC0000229L) -#define STATUS_DUPLICATE_OBJECTID ((NTSTATUS)0xC000022AL) -#define STATUS_OBJECTID_EXISTS ((NTSTATUS)0xC000022BL) -#define STATUS_CONVERT_TO_LARGE ((NTSTATUS)0xC000022CL) -#define STATUS_RETRY ((NTSTATUS)0xC000022DL) -#define STATUS_FOUND_OUT_OF_SCOPE ((NTSTATUS)0xC000022EL) -#define STATUS_ALLOCATE_BUCKET ((NTSTATUS)0xC000022FL) -#define STATUS_PROPSET_NOT_FOUND ((NTSTATUS)0xC0000230L) -#define STATUS_MARSHALL_OVERFLOW ((NTSTATUS)0xC0000231L) -#define STATUS_INVALID_VARIANT ((NTSTATUS)0xC0000232L) -#define STATUS_DOMAIN_CONTROLLER_NOT_FOUND ((NTSTATUS)0xC0000233L) -#define STATUS_ACCOUNT_LOCKED_OUT ((NTSTATUS)0xC0000234L) -#define STATUS_HANDLE_NOT_CLOSABLE ((NTSTATUS)0xC0000235L) -#define STATUS_CONNECTION_REFUSED ((NTSTATUS)0xC0000236L) -#define STATUS_GRACEFUL_DISCONNECT ((NTSTATUS)0xC0000237L) -#define STATUS_ADDRESS_ALREADY_ASSOCIATED ((NTSTATUS)0xC0000238L) -#define STATUS_ADDRESS_NOT_ASSOCIATED ((NTSTATUS)0xC0000239L) -#define STATUS_CONNECTION_INVALID ((NTSTATUS)0xC000023AL) -#define STATUS_CONNECTION_ACTIVE ((NTSTATUS)0xC000023BL) -#define STATUS_NETWORK_UNREACHABLE ((NTSTATUS)0xC000023CL) -#define STATUS_HOST_UNREACHABLE ((NTSTATUS)0xC000023DL) -#define STATUS_PROTOCOL_UNREACHABLE ((NTSTATUS)0xC000023EL) -#define STATUS_PORT_UNREACHABLE ((NTSTATUS)0xC000023FL) -#define STATUS_REQUEST_ABORTED ((NTSTATUS)0xC0000240L) -#define STATUS_CONNECTION_ABORTED ((NTSTATUS)0xC0000241L) -#define STATUS_BAD_COMPRESSION_BUFFER ((NTSTATUS)0xC0000242L) -#define STATUS_USER_MAPPED_FILE ((NTSTATUS)0xC0000243L) -#define STATUS_AUDIT_FAILED ((NTSTATUS)0xC0000244L) -#define STATUS_TIMER_RESOLUTION_NOT_SET ((NTSTATUS)0xC0000245L) -#define STATUS_CONNECTION_COUNT_LIMIT ((NTSTATUS)0xC0000246L) -#define STATUS_LOGIN_TIME_RESTRICTION ((NTSTATUS)0xC0000247L) -#define STATUS_LOGIN_WKSTA_RESTRICTION ((NTSTATUS)0xC0000248L) -#define STATUS_IMAGE_MP_UP_MISMATCH ((NTSTATUS)0xC0000249L) -#define STATUS_INSUFFICIENT_LOGON_INFO ((NTSTATUS)0xC0000250L) -#define STATUS_BAD_DLL_ENTRYPOINT ((NTSTATUS)0xC0000251L) -#define STATUS_BAD_SERVICE_ENTRYPOINT ((NTSTATUS)0xC0000252L) -#define STATUS_LPC_REPLY_LOST ((NTSTATUS)0xC0000253L) -#define STATUS_IP_ADDRESS_CONFLICT1 ((NTSTATUS)0xC0000254L) -#define STATUS_IP_ADDRESS_CONFLICT2 ((NTSTATUS)0xC0000255L) -#define STATUS_REGISTRY_QUOTA_LIMIT ((NTSTATUS)0xC0000256L) -#define STATUS_PATH_NOT_COVERED ((NTSTATUS)0xC0000257L) -#define STATUS_NO_CALLBACK_ACTIVE ((NTSTATUS)0xC0000258L) -#define STATUS_LICENSE_QUOTA_EXCEEDED ((NTSTATUS)0xC0000259L) -#define STATUS_PWD_TOO_SHORT ((NTSTATUS)0xC000025AL) -#define STATUS_PWD_TOO_RECENT ((NTSTATUS)0xC000025BL) -#define STATUS_PWD_HISTORY_CONFLICT ((NTSTATUS)0xC000025CL) -#define STATUS_PLUGPLAY_NO_DEVICE ((NTSTATUS)0xC000025EL) -#define STATUS_UNSUPPORTED_COMPRESSION ((NTSTATUS)0xC000025FL) -#define STATUS_INVALID_HW_PROFILE ((NTSTATUS)0xC0000260L) -#define STATUS_INVALID_PLUGPLAY_DEVICE_PATH ((NTSTATUS)0xC0000261L) -#define STATUS_DRIVER_ORDINAL_NOT_FOUND ((NTSTATUS)0xC0000262L) -#define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND ((NTSTATUS)0xC0000263L) -#define STATUS_RESOURCE_NOT_OWNED ((NTSTATUS)0xC0000264L) -#define STATUS_TOO_MANY_LINKS ((NTSTATUS)0xC0000265L) -#define STATUS_QUOTA_LIST_INCONSISTENT ((NTSTATUS)0xC0000266L) -#define STATUS_FILE_IS_OFFLINE ((NTSTATUS)0xC0000267L) -#define STATUS_EVALUATION_EXPIRATION ((NTSTATUS)0xC0000268L) -#define STATUS_ILLEGAL_DLL_RELOCATION ((NTSTATUS)0xC0000269L) -#define STATUS_LICENSE_VIOLATION ((NTSTATUS)0xC000026AL) -#define STATUS_DLL_INIT_FAILED_LOGOFF ((NTSTATUS)0xC000026BL) -#define STATUS_DRIVER_UNABLE_TO_LOAD ((NTSTATUS)0xC000026CL) -#define STATUS_DFS_UNAVAILABLE ((NTSTATUS)0xC000026DL) -#define STATUS_VOLUME_DISMOUNTED ((NTSTATUS)0xC000026EL) -#define STATUS_WX86_INTERNAL_ERROR ((NTSTATUS)0xC000026FL) -#define STATUS_WX86_FLOAT_STACK_CHECK ((NTSTATUS)0xC0000270L) -#define STATUS_VALIDATE_CONTINUE ((NTSTATUS)0xC0000271L) -#define STATUS_NO_MATCH ((NTSTATUS)0xC0000272L) -#define STATUS_NO_MORE_MATCHES ((NTSTATUS)0xC0000273L) -#define STATUS_NOT_A_REPARSE_POINT ((NTSTATUS)0xC0000275L) -#define STATUS_IO_REPARSE_TAG_INVALID ((NTSTATUS)0xC0000276L) -#define STATUS_IO_REPARSE_TAG_MISMATCH ((NTSTATUS)0xC0000277L) -#define STATUS_IO_REPARSE_DATA_INVALID ((NTSTATUS)0xC0000278L) -#define STATUS_IO_REPARSE_TAG_NOT_HANDLED ((NTSTATUS)0xC0000279L) -#define STATUS_REPARSE_POINT_NOT_RESOLVED ((NTSTATUS)0xC0000280L) -#define STATUS_DIRECTORY_IS_A_REPARSE_POINT ((NTSTATUS)0xC0000281L) -#define STATUS_RANGE_LIST_CONFLICT ((NTSTATUS)0xC0000282L) -#define STATUS_SOURCE_ELEMENT_EMPTY ((NTSTATUS)0xC0000283L) -#define STATUS_DESTINATION_ELEMENT_FULL ((NTSTATUS)0xC0000284L) -#define STATUS_ILLEGAL_ELEMENT_ADDRESS ((NTSTATUS)0xC0000285L) -#define STATUS_MAGAZINE_NOT_PRESENT ((NTSTATUS)0xC0000286L) -#define STATUS_REINITIALIZATION_NEEDED ((NTSTATUS)0xC0000287L) -#define STATUS_DEVICE_REQUIRES_CLEANING ((NTSTATUS)0x80000288L) -#define STATUS_DEVICE_DOOR_OPEN ((NTSTATUS)0x80000289L) -#define STATUS_ENCRYPTION_FAILED ((NTSTATUS)0xC000028AL) -#define STATUS_DECRYPTION_FAILED ((NTSTATUS)0xC000028BL) -#define STATUS_RANGE_NOT_FOUND ((NTSTATUS)0xC000028CL) -#define STATUS_NO_RECOVERY_POLICY ((NTSTATUS)0xC000028DL) -#define STATUS_NO_EFS ((NTSTATUS)0xC000028EL) -#define STATUS_WRONG_EFS ((NTSTATUS)0xC000028FL) -#define STATUS_NO_USER_KEYS ((NTSTATUS)0xC0000290L) -#define STATUS_FILE_NOT_ENCRYPTED ((NTSTATUS)0xC0000291L) -#define STATUS_NOT_EXPORT_FORMAT ((NTSTATUS)0xC0000292L) -#define STATUS_FILE_ENCRYPTED ((NTSTATUS)0xC0000293L) -#define STATUS_WAKE_SYSTEM ((NTSTATUS)0x40000294L) -#define STATUS_WMI_GUID_NOT_FOUND ((NTSTATUS)0xC0000295L) -#define STATUS_WMI_INSTANCE_NOT_FOUND ((NTSTATUS)0xC0000296L) -#define STATUS_WMI_ITEMID_NOT_FOUND ((NTSTATUS)0xC0000297L) -#define STATUS_WMI_TRY_AGAIN ((NTSTATUS)0xC0000298L) -#define STATUS_SHARED_POLICY ((NTSTATUS)0xC0000299L) -#define STATUS_POLICY_OBJECT_NOT_FOUND ((NTSTATUS)0xC000029AL) -#define STATUS_POLICY_ONLY_IN_DS ((NTSTATUS)0xC000029BL) -#define STATUS_VOLUME_NOT_UPGRADED ((NTSTATUS)0xC000029CL) -#define STATUS_REMOTE_STORAGE_NOT_ACTIVE ((NTSTATUS)0xC000029DL) -#define STATUS_REMOTE_STORAGE_MEDIA_ERROR ((NTSTATUS)0xC000029EL) -#define STATUS_NO_TRACKING_SERVICE ((NTSTATUS)0xC000029FL) -#define STATUS_SERVER_SID_MISMATCH ((NTSTATUS)0xC00002A0L) -#define STATUS_DS_NO_ATTRIBUTE_OR_VALUE ((NTSTATUS)0xC00002A1L) -#define STATUS_DS_INVALID_ATTRIBUTE_SYNTAX ((NTSTATUS)0xC00002A2L) -#define STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED ((NTSTATUS)0xC00002A3L) -#define STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS ((NTSTATUS)0xC00002A4L) -#define STATUS_DS_BUSY ((NTSTATUS)0xC00002A5L) -#define STATUS_DS_UNAVAILABLE ((NTSTATUS)0xC00002A6L) -#define STATUS_DS_NO_RIDS_ALLOCATED ((NTSTATUS)0xC00002A7L) -#define STATUS_DS_NO_MORE_RIDS ((NTSTATUS)0xC00002A8L) -#define STATUS_DS_INCORRECT_ROLE_OWNER ((NTSTATUS)0xC00002A9L) -#define STATUS_DS_RIDMGR_INIT_ERROR ((NTSTATUS)0xC00002AAL) -#define STATUS_DS_OBJ_CLASS_VIOLATION ((NTSTATUS)0xC00002ABL) -#define STATUS_DS_CANT_ON_NON_LEAF ((NTSTATUS)0xC00002ACL) -#define STATUS_DS_CANT_ON_RDN ((NTSTATUS)0xC00002ADL) -#define STATUS_DS_CANT_MOD_OBJ_CLASS ((NTSTATUS)0xC00002AEL) -#define STATUS_DS_CROSS_DOM_MOVE_FAILED ((NTSTATUS)0xC00002AFL) -#define STATUS_DS_GC_NOT_AVAILABLE ((NTSTATUS)0xC00002B0L) -#define STATUS_DIRECTORY_SERVICE_REQUIRED ((NTSTATUS)0xC00002B1L) -#define STATUS_REPARSE_ATTRIBUTE_CONFLICT ((NTSTATUS)0xC00002B2L) -#define STATUS_CANT_ENABLE_DENY_ONLY ((NTSTATUS)0xC00002B3L) -#define STATUS_FLOAT_MULTIPLE_FAULTS ((NTSTATUS)0xC00002B4L) -#define STATUS_FLOAT_MULTIPLE_TRAPS ((NTSTATUS)0xC00002B5L) -#define STATUS_DEVICE_REMOVED ((NTSTATUS)0xC00002B6L) -#define STATUS_JOURNAL_DELETE_IN_PROGRESS ((NTSTATUS)0xC00002B7L) -#define STATUS_JOURNAL_NOT_ACTIVE ((NTSTATUS)0xC00002B8L) -#define STATUS_NOINTERFACE ((NTSTATUS)0xC00002B9L) -#define STATUS_DS_ADMIN_LIMIT_EXCEEDED ((NTSTATUS)0xC00002C1L) -#define STATUS_DRIVER_FAILED_SLEEP ((NTSTATUS)0xC00002C2L) -#define STATUS_MUTUAL_AUTHENTICATION_FAILED ((NTSTATUS)0xC00002C3L) -#define STATUS_CORRUPT_SYSTEM_FILE ((NTSTATUS)0xC00002C4L) -#define STATUS_DATATYPE_MISALIGNMENT_ERROR ((NTSTATUS)0xC00002C5L) -#define STATUS_WMI_READ_ONLY ((NTSTATUS)0xC00002C6L) -#define STATUS_WMI_SET_FAILURE ((NTSTATUS)0xC00002C7L) -#define STATUS_COMMITMENT_MINIMUM ((NTSTATUS)0xC00002C8L) -#define STATUS_REG_NAT_CONSUMPTION ((NTSTATUS)0xC00002C9L) -#define STATUS_TRANSPORT_FULL ((NTSTATUS)0xC00002CAL) -#define STATUS_DS_SAM_INIT_FAILURE ((NTSTATUS)0xC00002CBL) -#define STATUS_ONLY_IF_CONNECTED ((NTSTATUS)0xC00002CCL) -#define STATUS_DS_SENSITIVE_GROUP_VIOLATION ((NTSTATUS)0xC00002CDL) -#define STATUS_PNP_RESTART_ENUMERATION ((NTSTATUS)0xC00002CEL) -#define STATUS_JOURNAL_ENTRY_DELETED ((NTSTATUS)0xC00002CFL) -#define STATUS_DS_CANT_MOD_PRIMARYGROUPID ((NTSTATUS)0xC00002D0L) -#define STATUS_SYSTEM_IMAGE_BAD_SIGNATURE ((NTSTATUS)0xC00002D1L) -#define STATUS_PNP_REBOOT_REQUIRED ((NTSTATUS)0xC00002D2L) -#define STATUS_POWER_STATE_INVALID ((NTSTATUS)0xC00002D3L) -#define STATUS_DS_INVALID_GROUP_TYPE ((NTSTATUS)0xC00002D4L) -#define STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN ((NTSTATUS)0xC00002D5L) -#define STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN ((NTSTATUS)0xC00002D6L) -#define STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER ((NTSTATUS)0xC00002D7L) -#define STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER ((NTSTATUS)0xC00002D8L) -#define STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER ((NTSTATUS)0xC00002D9L) -#define STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER ((NTSTATUS)0xC00002DAL) -#define STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER ((NTSTATUS)0xC00002DBL) -#define STATUS_DS_HAVE_PRIMARY_MEMBERS ((NTSTATUS)0xC00002DCL) -#define STATUS_WMI_NOT_SUPPORTED ((NTSTATUS)0xC00002DDL) -#define STATUS_INSUFFICIENT_POWER ((NTSTATUS)0xC00002DEL) -#define STATUS_SAM_NEED_BOOTKEY_PASSWORD ((NTSTATUS)0xC00002DFL) -#define STATUS_SAM_NEED_BOOTKEY_FLOPPY ((NTSTATUS)0xC00002E0L) -#define STATUS_DS_CANT_START ((NTSTATUS)0xC00002E1L) -#define STATUS_DS_INIT_FAILURE ((NTSTATUS)0xC00002E2L) -#define STATUS_SAM_INIT_FAILURE ((NTSTATUS)0xC00002E3L) -#define STATUS_DS_GC_REQUIRED ((NTSTATUS)0xC00002E4L) -#define STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY ((NTSTATUS)0xC00002E5L) -#define STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS ((NTSTATUS)0xC00002E6L) -#define STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED ((NTSTATUS)0xC00002E7L) -#define STATUS_MULTIPLE_FAULT_VIOLATION ((NTSTATUS)0xC00002E8L) -#define STATUS_CURRENT_DOMAIN_NOT_ALLOWED ((NTSTATUS)0xC00002E9L) -#define STATUS_CANNOT_MAKE ((NTSTATUS)0xC00002EAL) -#define STATUS_SYSTEM_SHUTDOWN ((NTSTATUS)0xC00002EBL) -#define STATUS_DS_INIT_FAILURE_CONSOLE ((NTSTATUS)0xC00002ECL) -#define STATUS_DS_SAM_INIT_FAILURE_CONSOLE ((NTSTATUS)0xC00002EDL) -#define STATUS_UNFINISHED_CONTEXT_DELETED ((NTSTATUS)0xC00002EEL) -#define STATUS_NO_TGT_REPLY ((NTSTATUS)0xC00002EFL) -#define STATUS_OBJECTID_NOT_FOUND ((NTSTATUS)0xC00002F0L) -#define STATUS_NO_IP_ADDRESSES ((NTSTATUS)0xC00002F1L) -#define STATUS_WRONG_CREDENTIAL_HANDLE ((NTSTATUS)0xC00002F2L) -#define STATUS_CRYPTO_SYSTEM_INVALID ((NTSTATUS)0xC00002F3L) -#define STATUS_MAX_REFERRALS_EXCEEDED ((NTSTATUS)0xC00002F4L) -#define STATUS_MUST_BE_KDC ((NTSTATUS)0xC00002F5L) -#define STATUS_STRONG_CRYPTO_NOT_SUPPORTED ((NTSTATUS)0xC00002F6L) -#define STATUS_TOO_MANY_PRINCIPALS ((NTSTATUS)0xC00002F7L) -#define STATUS_NO_PA_DATA ((NTSTATUS)0xC00002F8L) -#define STATUS_PKINIT_NAME_MISMATCH ((NTSTATUS)0xC00002F9L) -#define STATUS_SMARTCARD_LOGON_REQUIRED ((NTSTATUS)0xC00002FAL) -#define STATUS_KDC_INVALID_REQUEST ((NTSTATUS)0xC00002FBL) -#define STATUS_KDC_UNABLE_TO_REFER ((NTSTATUS)0xC00002FCL) -#define STATUS_KDC_UNKNOWN_ETYPE ((NTSTATUS)0xC00002FDL) -#define STATUS_SHUTDOWN_IN_PROGRESS ((NTSTATUS)0xC00002FEL) -#define STATUS_SERVER_SHUTDOWN_IN_PROGRESS ((NTSTATUS)0xC00002FFL) -#define STATUS_NOT_SUPPORTED_ON_SBS ((NTSTATUS)0xC0000300L) -#define STATUS_WMI_GUID_DISCONNECTED ((NTSTATUS)0xC0000301L) -#define STATUS_WMI_ALREADY_DISABLED ((NTSTATUS)0xC0000302L) -#define STATUS_WMI_ALREADY_ENABLED ((NTSTATUS)0xC0000303L) -#define STATUS_MFT_TOO_FRAGMENTED ((NTSTATUS)0xC0000304L) -#define STATUS_COPY_PROTECTION_FAILURE ((NTSTATUS)0xC0000305L) -#define STATUS_CSS_AUTHENTICATION_FAILURE ((NTSTATUS)0xC0000306L) -#define STATUS_CSS_KEY_NOT_PRESENT ((NTSTATUS)0xC0000307L) -#define STATUS_CSS_KEY_NOT_ESTABLISHED ((NTSTATUS)0xC0000308L) -#define STATUS_CSS_SCRAMBLED_SECTOR ((NTSTATUS)0xC0000309L) -#define STATUS_CSS_REGION_MISMATCH ((NTSTATUS)0xC000030AL) -#define STATUS_CSS_RESETS_EXHAUSTED ((NTSTATUS)0xC000030BL) -#define STATUS_PKINIT_FAILURE ((NTSTATUS)0xC0000320L) -#define STATUS_SMARTCARD_SUBSYSTEM_FAILURE ((NTSTATUS)0xC0000321L) -#define STATUS_NO_KERB_KEY ((NTSTATUS)0xC0000322L) -#define STATUS_HOST_DOWN ((NTSTATUS)0xC0000350L) -#define STATUS_UNSUPPORTED_PREAUTH ((NTSTATUS)0xC0000351L) -#define STATUS_EFS_ALG_BLOB_TOO_BIG ((NTSTATUS)0xC0000352L) -#define STATUS_PORT_NOT_SET ((NTSTATUS)0xC0000353L) -#define STATUS_DEBUGGER_INACTIVE ((NTSTATUS)0xC0000354L) -#define STATUS_DS_VERSION_CHECK_FAILURE ((NTSTATUS)0xC0000355L) -#define STATUS_AUDITING_DISABLED ((NTSTATUS)0xC0000356L) -#define STATUS_PRENT4_MACHINE_ACCOUNT ((NTSTATUS)0xC0000357L) -#define STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER ((NTSTATUS)0xC0000358L) -#define STATUS_INVALID_IMAGE_WIN_32 ((NTSTATUS)0xC0000359L) -#define STATUS_INVALID_IMAGE_WIN_64 ((NTSTATUS)0xC000035AL) -#define STATUS_BAD_BINDINGS ((NTSTATUS)0xC000035BL) -#define STATUS_NETWORK_SESSION_EXPIRED ((NTSTATUS)0xC000035CL) -#define STATUS_APPHELP_BLOCK ((NTSTATUS)0xC000035DL) -#define STATUS_ALL_SIDS_FILTERED ((NTSTATUS)0xC000035EL) -#define STATUS_NOT_SAFE_MODE_DRIVER ((NTSTATUS)0xC000035FL) -#define STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT ((NTSTATUS)0xC0000361L) -#define STATUS_ACCESS_DISABLED_BY_POLICY_PATH ((NTSTATUS)0xC0000362L) -#define STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER ((NTSTATUS)0xC0000363L) -#define STATUS_ACCESS_DISABLED_BY_POLICY_OTHER ((NTSTATUS)0xC0000364L) -#define STATUS_FAILED_DRIVER_ENTRY ((NTSTATUS)0xC0000365L) -#define STATUS_DEVICE_ENUMERATION_ERROR ((NTSTATUS)0xC0000366L) -#define STATUS_WAIT_FOR_OPLOCK ((NTSTATUS)0x00000367L) -#define STATUS_MOUNT_POINT_NOT_RESOLVED ((NTSTATUS)0xC0000368L) -#define STATUS_INVALID_DEVICE_OBJECT_PARAMETER ((NTSTATUS)0xC0000369L) -#define STATUS_MCA_OCCURED ((NTSTATUS)0xC000036AL) -#define STATUS_DRIVER_BLOCKED_CRITICAL ((NTSTATUS)0xC000036BL) -#define STATUS_DRIVER_BLOCKED ((NTSTATUS)0xC000036CL) -#define STATUS_DRIVER_DATABASE_ERROR ((NTSTATUS)0xC000036DL) -#define STATUS_SYSTEM_HIVE_TOO_LARGE ((NTSTATUS)0xC000036EL) -#define STATUS_INVALID_IMPORT_OF_NON_DLL ((NTSTATUS)0xC000036FL) -#define STATUS_DS_SHUTTING_DOWN ((NTSTATUS)0x40000370L) -#define STATUS_SMARTCARD_WRONG_PIN ((NTSTATUS)0xC0000380L) -#define STATUS_SMARTCARD_CARD_BLOCKED ((NTSTATUS)0xC0000381L) -#define STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED ((NTSTATUS)0xC0000382L) -#define STATUS_SMARTCARD_NO_CARD ((NTSTATUS)0xC0000383L) -#define STATUS_SMARTCARD_NO_KEY_CONTAINER ((NTSTATUS)0xC0000384L) -#define STATUS_SMARTCARD_NO_CERTIFICATE ((NTSTATUS)0xC0000385L) -#define STATUS_SMARTCARD_NO_KEYSET ((NTSTATUS)0xC0000386L) -#define STATUS_SMARTCARD_IO_ERROR ((NTSTATUS)0xC0000387L) -#define STATUS_DOWNGRADE_DETECTED ((NTSTATUS)0xC0000388L) -#define STATUS_SMARTCARD_CERT_REVOKED ((NTSTATUS)0xC0000389L) -#define STATUS_ISSUING_CA_UNTRUSTED ((NTSTATUS)0xC000038AL) -#define STATUS_REVOCATION_OFFLINE_C ((NTSTATUS)0xC000038BL) -#define STATUS_PKINIT_CLIENT_FAILURE ((NTSTATUS)0xC000038CL) -#define STATUS_SMARTCARD_CERT_EXPIRED ((NTSTATUS)0xC000038DL) -#define STATUS_DRIVER_FAILED_PRIOR_UNLOAD ((NTSTATUS)0xC000038EL) -#define STATUS_WOW_ASSERTION ((NTSTATUS)0xC0009898L) -#define RPC_NT_INVALID_STRING_BINDING ((NTSTATUS)0xC0020001L) -#define RPC_NT_WRONG_KIND_OF_BINDING ((NTSTATUS)0xC0020002L) -#define RPC_NT_INVALID_BINDING ((NTSTATUS)0xC0020003L) -#define RPC_NT_PROTSEQ_NOT_SUPPORTED ((NTSTATUS)0xC0020004L) -#define RPC_NT_INVALID_RPC_PROTSEQ ((NTSTATUS)0xC0020005L) -#define RPC_NT_INVALID_STRING_UUID ((NTSTATUS)0xC0020006L) -#define RPC_NT_INVALID_ENDPOINT_FORMAT ((NTSTATUS)0xC0020007L) -#define RPC_NT_INVALID_NET_ADDR ((NTSTATUS)0xC0020008L) -#define RPC_NT_NO_ENDPOINT_FOUND ((NTSTATUS)0xC0020009L) -#define RPC_NT_INVALID_TIMEOUT ((NTSTATUS)0xC002000AL) -#define RPC_NT_OBJECT_NOT_FOUND ((NTSTATUS)0xC002000BL) -#define RPC_NT_ALREADY_REGISTERED ((NTSTATUS)0xC002000CL) -#define RPC_NT_TYPE_ALREADY_REGISTERED ((NTSTATUS)0xC002000DL) -#define RPC_NT_ALREADY_LISTENING ((NTSTATUS)0xC002000EL) -#define RPC_NT_NO_PROTSEQS_REGISTERED ((NTSTATUS)0xC002000FL) -#define RPC_NT_NOT_LISTENING ((NTSTATUS)0xC0020010L) -#define RPC_NT_UNKNOWN_MGR_TYPE ((NTSTATUS)0xC0020011L) -#define RPC_NT_UNKNOWN_IF ((NTSTATUS)0xC0020012L) -#define RPC_NT_NO_BINDINGS ((NTSTATUS)0xC0020013L) -#define RPC_NT_NO_PROTSEQS ((NTSTATUS)0xC0020014L) -#define RPC_NT_CANT_CREATE_ENDPOINT ((NTSTATUS)0xC0020015L) -#define RPC_NT_OUT_OF_RESOURCES ((NTSTATUS)0xC0020016L) -#define RPC_NT_SERVER_UNAVAILABLE ((NTSTATUS)0xC0020017L) -#define RPC_NT_SERVER_TOO_BUSY ((NTSTATUS)0xC0020018L) -#define RPC_NT_INVALID_NETWORK_OPTIONS ((NTSTATUS)0xC0020019L) -#define RPC_NT_NO_CALL_ACTIVE ((NTSTATUS)0xC002001AL) -#define RPC_NT_CALL_FAILED ((NTSTATUS)0xC002001BL) -#define RPC_NT_CALL_FAILED_DNE ((NTSTATUS)0xC002001CL) -#define RPC_NT_PROTOCOL_ERROR ((NTSTATUS)0xC002001DL) -#define RPC_NT_UNSUPPORTED_TRANS_SYN ((NTSTATUS)0xC002001FL) -#define RPC_NT_UNSUPPORTED_TYPE ((NTSTATUS)0xC0020021L) -#define RPC_NT_INVALID_TAG ((NTSTATUS)0xC0020022L) -#define RPC_NT_INVALID_BOUND ((NTSTATUS)0xC0020023L) -#define RPC_NT_NO_ENTRY_NAME ((NTSTATUS)0xC0020024L) -#define RPC_NT_INVALID_NAME_SYNTAX ((NTSTATUS)0xC0020025L) -#define RPC_NT_UNSUPPORTED_NAME_SYNTAX ((NTSTATUS)0xC0020026L) -#define RPC_NT_UUID_NO_ADDRESS ((NTSTATUS)0xC0020028L) -#define RPC_NT_DUPLICATE_ENDPOINT ((NTSTATUS)0xC0020029L) -#define RPC_NT_UNKNOWN_AUTHN_TYPE ((NTSTATUS)0xC002002AL) -#define RPC_NT_MAX_CALLS_TOO_SMALL ((NTSTATUS)0xC002002BL) -#define RPC_NT_STRING_TOO_LONG ((NTSTATUS)0xC002002CL) -#define RPC_NT_PROTSEQ_NOT_FOUND ((NTSTATUS)0xC002002DL) -#define RPC_NT_PROCNUM_OUT_OF_RANGE ((NTSTATUS)0xC002002EL) -#define RPC_NT_BINDING_HAS_NO_AUTH ((NTSTATUS)0xC002002FL) -#define RPC_NT_UNKNOWN_AUTHN_SERVICE ((NTSTATUS)0xC0020030L) -#define RPC_NT_UNKNOWN_AUTHN_LEVEL ((NTSTATUS)0xC0020031L) -#define RPC_NT_INVALID_AUTH_IDENTITY ((NTSTATUS)0xC0020032L) -#define RPC_NT_UNKNOWN_AUTHZ_SERVICE ((NTSTATUS)0xC0020033L) -#define EPT_NT_INVALID_ENTRY ((NTSTATUS)0xC0020034L) -#define EPT_NT_CANT_PERFORM_OP ((NTSTATUS)0xC0020035L) -#define EPT_NT_NOT_REGISTERED ((NTSTATUS)0xC0020036L) -#define RPC_NT_NOTHING_TO_EXPORT ((NTSTATUS)0xC0020037L) -#define RPC_NT_INCOMPLETE_NAME ((NTSTATUS)0xC0020038L) -#define RPC_NT_INVALID_VERS_OPTION ((NTSTATUS)0xC0020039L) -#define RPC_NT_NO_MORE_MEMBERS ((NTSTATUS)0xC002003AL) -#define RPC_NT_NOT_ALL_OBJS_UNEXPORTED ((NTSTATUS)0xC002003BL) -#define RPC_NT_INTERFACE_NOT_FOUND ((NTSTATUS)0xC002003CL) -#define RPC_NT_ENTRY_ALREADY_EXISTS ((NTSTATUS)0xC002003DL) -#define RPC_NT_ENTRY_NOT_FOUND ((NTSTATUS)0xC002003EL) -#define RPC_NT_NAME_SERVICE_UNAVAILABLE ((NTSTATUS)0xC002003FL) -#define RPC_NT_INVALID_NAF_ID ((NTSTATUS)0xC0020040L) -#define RPC_NT_CANNOT_SUPPORT ((NTSTATUS)0xC0020041L) -#define RPC_NT_NO_CONTEXT_AVAILABLE ((NTSTATUS)0xC0020042L) -#define RPC_NT_INTERNAL_ERROR ((NTSTATUS)0xC0020043L) -#define RPC_NT_ZERO_DIVIDE ((NTSTATUS)0xC0020044L) -#define RPC_NT_ADDRESS_ERROR ((NTSTATUS)0xC0020045L) -#define RPC_NT_FP_DIV_ZERO ((NTSTATUS)0xC0020046L) -#define RPC_NT_FP_UNDERFLOW ((NTSTATUS)0xC0020047L) -#define RPC_NT_FP_OVERFLOW ((NTSTATUS)0xC0020048L) -#define RPC_NT_NO_MORE_ENTRIES ((NTSTATUS)0xC0030001L) -#define RPC_NT_SS_CHAR_TRANS_OPEN_FAIL ((NTSTATUS)0xC0030002L) -#define RPC_NT_SS_CHAR_TRANS_SHORT_FILE ((NTSTATUS)0xC0030003L) -#define RPC_NT_SS_IN_NULL_CONTEXT ((NTSTATUS)0xC0030004L) -#define RPC_NT_SS_CONTEXT_MISMATCH ((NTSTATUS)0xC0030005L) -#define RPC_NT_SS_CONTEXT_DAMAGED ((NTSTATUS)0xC0030006L) -#define RPC_NT_SS_HANDLES_MISMATCH ((NTSTATUS)0xC0030007L) -#define RPC_NT_SS_CANNOT_GET_CALL_HANDLE ((NTSTATUS)0xC0030008L) -#define RPC_NT_NULL_REF_POINTER ((NTSTATUS)0xC0030009L) -#define RPC_NT_ENUM_VALUE_OUT_OF_RANGE ((NTSTATUS)0xC003000AL) -#define RPC_NT_BYTE_COUNT_TOO_SMALL ((NTSTATUS)0xC003000BL) -#define RPC_NT_BAD_STUB_DATA ((NTSTATUS)0xC003000CL) -#define RPC_NT_CALL_IN_PROGRESS ((NTSTATUS)0xC0020049L) -#define RPC_NT_NO_MORE_BINDINGS ((NTSTATUS)0xC002004AL) -#define RPC_NT_GROUP_MEMBER_NOT_FOUND ((NTSTATUS)0xC002004BL) -#define EPT_NT_CANT_CREATE ((NTSTATUS)0xC002004CL) -#define RPC_NT_INVALID_OBJECT ((NTSTATUS)0xC002004DL) -#define RPC_NT_NO_INTERFACES ((NTSTATUS)0xC002004FL) -#define RPC_NT_CALL_CANCELLED ((NTSTATUS)0xC0020050L) -#define RPC_NT_BINDING_INCOMPLETE ((NTSTATUS)0xC0020051L) -#define RPC_NT_COMM_FAILURE ((NTSTATUS)0xC0020052L) -#define RPC_NT_UNSUPPORTED_AUTHN_LEVEL ((NTSTATUS)0xC0020053L) -#define RPC_NT_NO_PRINC_NAME ((NTSTATUS)0xC0020054L) -#define RPC_NT_NOT_RPC_ERROR ((NTSTATUS)0xC0020055L) -#define RPC_NT_UUID_LOCAL_ONLY ((NTSTATUS)0x40020056L) -#define RPC_NT_SEC_PKG_ERROR ((NTSTATUS)0xC0020057L) -#define RPC_NT_NOT_CANCELLED ((NTSTATUS)0xC0020058L) -#define RPC_NT_INVALID_ES_ACTION ((NTSTATUS)0xC0030059L) -#define RPC_NT_WRONG_ES_VERSION ((NTSTATUS)0xC003005AL) -#define RPC_NT_WRONG_STUB_VERSION ((NTSTATUS)0xC003005BL) -#define RPC_NT_INVALID_PIPE_OBJECT ((NTSTATUS)0xC003005CL) -#define RPC_NT_INVALID_PIPE_OPERATION ((NTSTATUS)0xC003005DL) -#define RPC_NT_WRONG_PIPE_VERSION ((NTSTATUS)0xC003005EL) -#define RPC_NT_PIPE_CLOSED ((NTSTATUS)0xC003005FL) -#define RPC_NT_PIPE_DISCIPLINE_ERROR ((NTSTATUS)0xC0030060L) -#define RPC_NT_PIPE_EMPTY ((NTSTATUS)0xC0030061L) -#define RPC_NT_INVALID_ASYNC_HANDLE ((NTSTATUS)0xC0020062L) -#define RPC_NT_INVALID_ASYNC_CALL ((NTSTATUS)0xC0020063L) -#define RPC_NT_SEND_INCOMPLETE ((NTSTATUS)0x400200AFL) -#define STATUS_ACPI_INVALID_OPCODE ((NTSTATUS)0xC0140001L) -#define STATUS_ACPI_STACK_OVERFLOW ((NTSTATUS)0xC0140002L) -#define STATUS_ACPI_ASSERT_FAILED ((NTSTATUS)0xC0140003L) -#define STATUS_ACPI_INVALID_INDEX ((NTSTATUS)0xC0140004L) -#define STATUS_ACPI_INVALID_ARGUMENT ((NTSTATUS)0xC0140005L) -#define STATUS_ACPI_FATAL ((NTSTATUS)0xC0140006L) -#define STATUS_ACPI_INVALID_SUPERNAME ((NTSTATUS)0xC0140007L) -#define STATUS_ACPI_INVALID_ARGTYPE ((NTSTATUS)0xC0140008L) -#define STATUS_ACPI_INVALID_OBJTYPE ((NTSTATUS)0xC0140009L) -#define STATUS_ACPI_INVALID_TARGETTYPE ((NTSTATUS)0xC014000AL) -#define STATUS_ACPI_INCORRECT_ARGUMENT_COUNT ((NTSTATUS)0xC014000BL) -#define STATUS_ACPI_ADDRESS_NOT_MAPPED ((NTSTATUS)0xC014000CL) -#define STATUS_ACPI_INVALID_EVENTTYPE ((NTSTATUS)0xC014000DL) -#define STATUS_ACPI_HANDLER_COLLISION ((NTSTATUS)0xC014000EL) -#define STATUS_ACPI_INVALID_DATA ((NTSTATUS)0xC014000FL) -#define STATUS_ACPI_INVALID_REGION ((NTSTATUS)0xC0140010L) -#define STATUS_ACPI_INVALID_ACCESS_SIZE ((NTSTATUS)0xC0140011L) -#define STATUS_ACPI_ACQUIRE_GLOBAL_LOCK ((NTSTATUS)0xC0140012L) -#define STATUS_ACPI_ALREADY_INITIALIZED ((NTSTATUS)0xC0140013L) -#define STATUS_ACPI_NOT_INITIALIZED ((NTSTATUS)0xC0140014L) -#define STATUS_ACPI_INVALID_MUTEX_LEVEL ((NTSTATUS)0xC0140015L) -#define STATUS_ACPI_MUTEX_NOT_OWNED ((NTSTATUS)0xC0140016L) -#define STATUS_ACPI_MUTEX_NOT_OWNER ((NTSTATUS)0xC0140017L) -#define STATUS_ACPI_RS_ACCESS ((NTSTATUS)0xC0140018L) -#define STATUS_ACPI_INVALID_TABLE ((NTSTATUS)0xC0140019L) -#define STATUS_ACPI_REG_HANDLER_FAILED ((NTSTATUS)0xC0140020L) -#define STATUS_ACPI_POWER_REQUEST_FAILED ((NTSTATUS)0xC0140021L) -#define STATUS_CTX_WINSTATION_NAME_INVALID ((NTSTATUS)0xC00A0001L) -#define STATUS_CTX_INVALID_PD ((NTSTATUS)0xC00A0002L) -#define STATUS_CTX_PD_NOT_FOUND ((NTSTATUS)0xC00A0003L) -#define STATUS_CTX_CDM_CONNECT ((NTSTATUS)0x400A0004L) -#define STATUS_CTX_CDM_DISCONNECT ((NTSTATUS)0x400A0005L) -#define STATUS_CTX_CLOSE_PENDING ((NTSTATUS)0xC00A0006L) -#define STATUS_CTX_NO_OUTBUF ((NTSTATUS)0xC00A0007L) -#define STATUS_CTX_MODEM_INF_NOT_FOUND ((NTSTATUS)0xC00A0008L) -#define STATUS_CTX_INVALID_MODEMNAME ((NTSTATUS)0xC00A0009L) -#define STATUS_CTX_RESPONSE_ERROR ((NTSTATUS)0xC00A000AL) -#define STATUS_CTX_MODEM_RESPONSE_TIMEOUT ((NTSTATUS)0xC00A000BL) -#define STATUS_CTX_MODEM_RESPONSE_NO_CARRIER ((NTSTATUS)0xC00A000CL) -#define STATUS_CTX_MODEM_RESPONSE_NO_DIALTONE ((NTSTATUS)0xC00A000DL) -#define STATUS_CTX_MODEM_RESPONSE_BUSY ((NTSTATUS)0xC00A000EL) -#define STATUS_CTX_MODEM_RESPONSE_VOICE ((NTSTATUS)0xC00A000FL) -#define STATUS_CTX_TD_ERROR ((NTSTATUS)0xC00A0010L) -#define STATUS_CTX_LICENSE_CLIENT_INVALID ((NTSTATUS)0xC00A0012L) -#define STATUS_CTX_LICENSE_NOT_AVAILABLE ((NTSTATUS)0xC00A0013L) -#define STATUS_CTX_LICENSE_EXPIRED ((NTSTATUS)0xC00A0014L) -#define STATUS_CTX_WINSTATION_NOT_FOUND ((NTSTATUS)0xC00A0015L) -#define STATUS_CTX_WINSTATION_NAME_COLLISION ((NTSTATUS)0xC00A0016L) -#define STATUS_CTX_WINSTATION_BUSY ((NTSTATUS)0xC00A0017L) -#define STATUS_CTX_BAD_VIDEO_MODE ((NTSTATUS)0xC00A0018L) -#define STATUS_CTX_GRAPHICS_INVALID ((NTSTATUS)0xC00A0022L) -#define STATUS_CTX_NOT_CONSOLE ((NTSTATUS)0xC00A0024L) -#define STATUS_CTX_CLIENT_QUERY_TIMEOUT ((NTSTATUS)0xC00A0026L) -#define STATUS_CTX_CONSOLE_DISCONNECT ((NTSTATUS)0xC00A0027L) -#define STATUS_CTX_CONSOLE_CONNECT ((NTSTATUS)0xC00A0028L) -#define STATUS_CTX_SHADOW_DENIED ((NTSTATUS)0xC00A002AL) -#define STATUS_CTX_WINSTATION_ACCESS_DENIED ((NTSTATUS)0xC00A002BL) -#define STATUS_CTX_INVALID_WD ((NTSTATUS)0xC00A002EL) -#define STATUS_CTX_WD_NOT_FOUND ((NTSTATUS)0xC00A002FL) -#define STATUS_CTX_SHADOW_INVALID ((NTSTATUS)0xC00A0030L) -#define STATUS_CTX_SHADOW_DISABLED ((NTSTATUS)0xC00A0031L) -#define STATUS_RDP_PROTOCOL_ERROR ((NTSTATUS)0xC00A0032L) -#define STATUS_CTX_CLIENT_LICENSE_NOT_SET ((NTSTATUS)0xC00A0033L) -#define STATUS_CTX_CLIENT_LICENSE_IN_USE ((NTSTATUS)0xC00A0034L) -#define STATUS_CTX_SHADOW_ENDED_BY_MODE_CHANGE ((NTSTATUS)0xC00A0035L) -#define STATUS_CTX_SHADOW_NOT_RUNNING ((NTSTATUS)0xC00A0036L) -#define STATUS_PNP_BAD_MPS_TABLE ((NTSTATUS)0xC0040035L) -#define STATUS_PNP_TRANSLATION_FAILED ((NTSTATUS)0xC0040036L) -#define STATUS_PNP_IRQ_TRANSLATION_FAILED ((NTSTATUS)0xC0040037L) -#define STATUS_SXS_SECTION_NOT_FOUND ((NTSTATUS)0xC0150001L) -#define STATUS_SXS_CANT_GEN_ACTCTX ((NTSTATUS)0xC0150002L) -#define STATUS_SXS_INVALID_ACTCTXDATA_FORMAT ((NTSTATUS)0xC0150003L) -#define STATUS_SXS_ASSEMBLY_NOT_FOUND ((NTSTATUS)0xC0150004L) -#define STATUS_SXS_MANIFEST_FORMAT_ERROR ((NTSTATUS)0xC0150005L) -#define STATUS_SXS_MANIFEST_PARSE_ERROR ((NTSTATUS)0xC0150006L) -#define STATUS_SXS_ACTIVATION_CONTEXT_DISABLED ((NTSTATUS)0xC0150007L) -#define STATUS_SXS_KEY_NOT_FOUND ((NTSTATUS)0xC0150008L) -#define STATUS_SXS_VERSION_CONFLICT ((NTSTATUS)0xC0150009L) -#define STATUS_SXS_WRONG_SECTION_TYPE ((NTSTATUS)0xC015000AL) -#define STATUS_SXS_THREAD_QUERIES_DISABLED ((NTSTATUS)0xC015000BL) -#define STATUS_SXS_ASSEMBLY_MISSING ((NTSTATUS)0xC015000CL) -#define STATUS_SXS_RELEASE_ACTIVATION_CONTEXT ((NTSTATUS)0x4015000DL) -#define STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET ((NTSTATUS)0xC015000EL) -#define STATUS_SXS_EARLY_DEACTIVATION ((NTSTATUS)0xC015000FL) -#define STATUS_SXS_INVALID_DEACTIVATION ((NTSTATUS)0xC0150010L) -#define STATUS_SXS_MULTIPLE_DEACTIVATION ((NTSTATUS)0xC0150011L) -#define STATUS_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY ((NTSTATUS)0xC0150012L) -#define STATUS_SXS_PROCESS_TERMINATION_REQUESTED ((NTSTATUS)0xC0150013L) -#define STATUS_CLUSTER_INVALID_NODE ((NTSTATUS)0xC0130001L) -#define STATUS_CLUSTER_NODE_EXISTS ((NTSTATUS)0xC0130002L) -#define STATUS_CLUSTER_JOIN_IN_PROGRESS ((NTSTATUS)0xC0130003L) -#define STATUS_CLUSTER_NODE_NOT_FOUND ((NTSTATUS)0xC0130004L) -#define STATUS_CLUSTER_LOCAL_NODE_NOT_FOUND ((NTSTATUS)0xC0130005L) -#define STATUS_CLUSTER_NETWORK_EXISTS ((NTSTATUS)0xC0130006L) -#define STATUS_CLUSTER_NETWORK_NOT_FOUND ((NTSTATUS)0xC0130007L) -#define STATUS_CLUSTER_NETINTERFACE_EXISTS ((NTSTATUS)0xC0130008L) -#define STATUS_CLUSTER_NETINTERFACE_NOT_FOUND ((NTSTATUS)0xC0130009L) -#define STATUS_CLUSTER_INVALID_REQUEST ((NTSTATUS)0xC013000AL) -#define STATUS_CLUSTER_INVALID_NETWORK_PROVIDER ((NTSTATUS)0xC013000BL) -#define STATUS_CLUSTER_NODE_DOWN ((NTSTATUS)0xC013000CL) -#define STATUS_CLUSTER_NODE_UNREACHABLE ((NTSTATUS)0xC013000DL) -#define STATUS_CLUSTER_NODE_NOT_MEMBER ((NTSTATUS)0xC013000EL) -#define STATUS_CLUSTER_JOIN_NOT_IN_PROGRESS ((NTSTATUS)0xC013000FL) -#define STATUS_CLUSTER_INVALID_NETWORK ((NTSTATUS)0xC0130010L) -#define STATUS_CLUSTER_NO_NET_ADAPTERS ((NTSTATUS)0xC0130011L) -#define STATUS_CLUSTER_NODE_UP ((NTSTATUS)0xC0130012L) -#define STATUS_CLUSTER_NODE_PAUSED ((NTSTATUS)0xC0130013L) -#define STATUS_CLUSTER_NODE_NOT_PAUSED ((NTSTATUS)0xC0130014L) -#define STATUS_CLUSTER_NO_SECURITY_CONTEXT ((NTSTATUS)0xC0130015L) -#define STATUS_CLUSTER_NETWORK_NOT_INTERNAL ((NTSTATUS)0xC0130016L) -#define STATUS_CLUSTER_POISONED ((NTSTATUS)0xC0130017L) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/platform/visualc/win2k.h b/src/platform/visualc/win2k.h deleted file mode 100644 index deba29b9..00000000 --- a/src/platform/visualc/win2k.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * win2k.h - * - * Definitions only used in Windows 2000 and earlier versions - * - * This file is part of the w32api package. - * - * Contributors: - * Created by Casper S. Hornstrup - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - */ - -#ifndef __WIN2K_H -#define __WIN2K_H - -#if __GNUC__ >=3 -#pragma GCC system_header -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#include "ntddk.h" - -#pragma pack(push,4) - -typedef enum _BUS_DATA_TYPE { - ConfigurationSpaceUndefined = -1, - Cmos, - EisaConfiguration, - Pos, - CbusConfiguration, - PCIConfiguration, - VMEConfiguration, - NuBusConfiguration, - PCMCIAConfiguration, - MPIConfiguration, - MPSAConfiguration, - PNPISAConfiguration, - SgiInternalConfiguration, - MaximumBusDataType -} BUS_DATA_TYPE, *PBUS_DATA_TYPE; - -NTOSAPI -VOID -DDKAPI -ExReleaseResourceForThreadLite( - IN PERESOURCE Resource, - IN ERESOURCE_THREAD ResourceThreadId); - -NTOSAPI -NTSTATUS -DDKAPI -IoReadPartitionTable( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG SectorSize, - IN BOOLEAN ReturnRecognizedPartitions, - OUT struct _DRIVE_LAYOUT_INFORMATION **PartitionBuffer); - -NTOSAPI -NTSTATUS -DDKAPI -IoSetPartitionInformation( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG SectorSize, - IN ULONG PartitionNumber, - IN ULONG PartitionType); - -NTOSAPI -NTSTATUS -DDKAPI -IoWritePartitionTable( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG SectorSize, - IN ULONG SectorsPerTrack, - IN ULONG NumberOfHeads, - IN struct _DRIVE_LAYOUT_INFORMATION *PartitionBuffer); - -/* - * PVOID MmGetSystemAddressForMdl( - * IN PMDL Mdl); - */ -#define MmGetSystemAddressForMdl(Mdl) \ - (((Mdl)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | \ - MDL_SOURCE_IS_NONPAGED_POOL)) ? \ - ((Mdl)->MappedSystemVa) : \ - (MmMapLockedPages((Mdl), KernelMode))) - -#pragma pack(pop) - -#ifdef __cplusplus -} -#endif - -#endif /* __WIN2K_H */ diff --git a/src/platform/visualc/winddk.h b/src/platform/visualc/winddk.h deleted file mode 100644 index e02c56e9..00000000 --- a/src/platform/visualc/winddk.h +++ /dev/null @@ -1,9074 +0,0 @@ -/* - * winddk.h - * - * Windows Device Driver Kit - * - * This file is part of the w32api package. - * - * Contributors: - * Created by Casper S. Hornstrup - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - */ - -#ifndef __WINDDK_H -#define __WINDDK_H - -#if __GNUC__ >=3 -#pragma GCC system_header -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#pragma pack(push,4) - -/* -** Definitions specific to this Device Driver Kit -*/ -#define DDKAPI __attribute__((stdcall)) -#define DDKFASTAPI __attribute__((fastcall)) -#define DDKCDECLAPI __attribute__((cdecl)) - -#if defined(_NTOSKRNL_) -#ifndef NTOSAPI -#define NTOSAPI DECL_EXPORT -#endif -#define DECLARE_INTERNAL_OBJECT(x) typedef struct _##x; typedef struct _##x *P##x; -#define DECLARE_INTERNAL_OBJECT2(x,y) typedef struct _##x; typedef struct _##x *P##y; -#else -#ifndef NTOSAPI -#define NTOSAPI DECL_IMPORT -#endif -#define DECLARE_INTERNAL_OBJECT(x) struct _##x; typedef struct _##x *P##x; -#define DECLARE_INTERNAL_OBJECT2(x,y) struct _##x; typedef struct _##x *P##y; -#endif - -/* Pseudo modifiers for parameters */ -#define IN -#define OUT -#define OPTIONAL -#define UNALLIGNED - -#define CONST const -#define VOLATILE volatile - -#define RESTRICTED_POINTER -#define POINTER_ALIGNMENT - - - -/* -** Forward declarations -*/ - -struct _IRP; -struct _MDL; -struct _KAPC; -struct _KDPC; -struct _KPCR; -struct _KPRCB; -struct _KTSS; -struct _FILE_OBJECT; -struct _DMA_ADAPTER; -struct _DEVICE_OBJECT; -struct _DRIVER_OBJECT; -struct _SECTION_OBJECT; -struct _IO_STATUS_BLOCK; -struct _DEVICE_DESCRIPTION; -struct _SCATTER_GATHER_LIST; - -DECLARE_INTERNAL_OBJECT(ADAPTER_OBJECT); -DECLARE_INTERNAL_OBJECT(DMA_ADAPTER); -DECLARE_INTERNAL_OBJECT(IO_STATUS_BLOCK); -DECLARE_INTERNAL_OBJECT(SECTION_OBJECT); - -#if 1 -/* FIXME: Unknown definitions */ -struct _SET_PARTITION_INFORMATION_EX; -typedef ULONG WAIT_TYPE; -typedef HANDLE TRACEHANDLE; -typedef PVOID PWMILIB_CONTEXT; -typedef PVOID PSYSCTL_IRP_DISPOSITION; -typedef ULONG LOGICAL; -#endif - -/* -** Routines specific to this DDK -*/ - -#define TAG(_a, _b, _c, _d) (ULONG) \ - (((_a) << 0) + ((_b) << 8) + ((_c) << 16) + ((_d) << 24)) - -static inline struct _KPCR * KeGetCurrentKPCR( - VOID) -{ - ULONG Value; - - __asm__ __volatile__ ("movl %%fs:0x18, %0\n\t" - : "=r" (Value) - : /* no inputs */ - ); - return (struct _KPCR *) Value; -} - -/* -** Simple structures -*/ - -typedef LONG KPRIORITY; -typedef ULONG KIRQL, *PKIRQL; -typedef ULONG_PTR KSPIN_LOCK, *PKSPIN_LOCK; -typedef ULONG KAFFINITY, *PKAFFINITY; -typedef CCHAR KPROCESSOR_MODE; - -typedef enum _MODE { - KernelMode, - UserMode, - MaximumMode -} MODE; - -typedef struct _SINGLE_LIST_ENTRY { - struct _SINGLE_LIST_ENTRY *Next; -} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY; - -#define SLIST_ENTRY SINGLE_LIST_ENTRY -#define PSLIST_ENTRY PSINGLE_LIST_ENTRY - -typedef union _SLIST_HEADER { - ULONGLONG Alignment; - struct { - SLIST_ENTRY Next; - USHORT Depth; - USHORT Sequence; - }; -} SLIST_HEADER, *PSLIST_HEADER; - - -/* Structures not exposed to drivers */ -typedef struct _IO_TIMER *PIO_TIMER; -typedef struct _EPROCESS *PEPROCESS; -typedef struct _ETHREAD *PETHREAD; -typedef struct _KINTERRUPT *PKINTERRUPT; -typedef struct _OBJECT_TYPE *POBJECT_TYPE; -typedef struct _KTHREAD *PKTHREAD, *PRKTHREAD; -typedef struct _COMPRESSED_DATA_INFO *PCOMPRESSED_DATA_INFO; -typedef struct _HAL_DISPATCH_TABLE *PHAL_DISPATCH_TABLE; -typedef struct _HAL_PRIVATE_DISPATCH_TABLE *PHAL_PRIVATE_DISPATCH_TABLE; -typedef struct _DRIVE_LAYOUT_INFORMATION *PDRIVE_LAYOUT_INFORMATION; -typedef struct _DRIVE_LAYOUT_INFORMATION_EX *PDRIVE_LAYOUT_INFORMATION_EX; - -/* Constants */ -#define MAXIMUM_PROCESSORS 32 - -#define MAXIMUM_WAIT_OBJECTS 64 - -#define METHOD_BUFFERED 0 -#define METHOD_IN_DIRECT 1 -#define METHOD_OUT_DIRECT 2 -#define METHOD_NEITHER 3 - -#define LOW_PRIORITY 0 -#define LOW_REALTIME_PRIORITY 16 -#define HIGH_PRIORITY 31 -#define MAXIMUM_PRIORITY 32 - -#define FILE_LIST_DIRECTORY 0x00000001 -#define FILE_READ_DATA 0x00000001 -#define FILE_ADD_FILE 0x00000002 -#define FILE_WRITE_DATA 0x00000002 -#define FILE_ADD_SUBDIRECTORY 0x00000004 -#define FILE_APPEND_DATA 0x00000004 -#define FILE_CREATE_PIPE_INSTANCE 0x00000004 -#define FILE_READ_EA 0x00000008 -#define FILE_WRITE_EA 0x00000010 -#define FILE_EXECUTE 0x00000020 -#define FILE_TRAVERSE 0x00000020 -#define FILE_DELETE_CHILD 0x00000040 -#define FILE_READ_ATTRIBUTES 0x00000080 -#define FILE_WRITE_ATTRIBUTES 0x00000100 - -#define FILE_SUPERSEDED 0x00000000 -#define FILE_OPENED 0x00000001 -#define FILE_CREATED 0x00000002 -#define FILE_OVERWRITTEN 0x00000003 -#define FILE_EXISTS 0x00000004 -#define FILE_DOES_NOT_EXIST 0x00000005 - -#define FILE_SHARE_READ 0x00000001 -#define FILE_SHARE_WRITE 0x00000002 -#define FILE_SHARE_DELETE 0x00000004 -#define FILE_SHARE_VALID_FLAGS 0x00000007 - -#define FILE_ATTRIBUTE_READONLY 0x00000001 -#define FILE_ATTRIBUTE_HIDDEN 0x00000002 -#define FILE_ATTRIBUTE_SYSTEM 0x00000004 -#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 -#define FILE_ATTRIBUTE_ARCHIVE 0x00000020 -#define FILE_ATTRIBUTE_DEVICE 0x00000040 -#define FILE_ATTRIBUTE_NORMAL 0x00000080 -#define FILE_ATTRIBUTE_TEMPORARY 0x00000100 -#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 -#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 -#define FILE_ATTRIBUTE_COMPRESSED 0x00000800 -#define FILE_ATTRIBUTE_OFFLINE 0x00001000 -#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 -#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000 - -#define FILE_ATTRIBUTE_VALID_FLAGS 0x00007fb7 -#define FILE_ATTRIBUTE_VALID_SET_FLAGS 0x000031a7 - -#define FILE_COPY_STRUCTURED_STORAGE 0x00000041 -#define FILE_STRUCTURED_STORAGE 0x00000441 - -#define FILE_VALID_OPTION_FLAGS 0x00ffffff -#define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032 -#define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032 -#define FILE_VALID_SET_FLAGS 0x00000036 - -#define FILE_SUPERSEDE 0x00000000 -#define FILE_OPEN 0x00000001 -#define FILE_CREATE 0x00000002 -#define FILE_OPEN_IF 0x00000003 -#define FILE_OVERWRITE 0x00000004 -#define FILE_OVERWRITE_IF 0x00000005 -#define FILE_MAXIMUM_DISPOSITION 0x00000005 - -#define FILE_DIRECTORY_FILE 0x00000001 -#define FILE_WRITE_THROUGH 0x00000002 -#define FILE_SEQUENTIAL_ONLY 0x00000004 -#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008 -#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010 -#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 -#define FILE_NON_DIRECTORY_FILE 0x00000040 -#define FILE_CREATE_TREE_CONNECTION 0x00000080 -#define FILE_COMPLETE_IF_OPLOCKED 0x00000100 -#define FILE_NO_EA_KNOWLEDGE 0x00000200 -#define FILE_OPEN_FOR_RECOVERY 0x00000400 -#define FILE_RANDOM_ACCESS 0x00000800 -#define FILE_DELETE_ON_CLOSE 0x00001000 -#define FILE_OPEN_BY_FILE_ID 0x00002000 -#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000 -#define FILE_NO_COMPRESSION 0x00008000 -#define FILE_RESERVE_OPFILTER 0x00100000 -#define FILE_OPEN_REPARSE_POINT 0x00200000 -#define FILE_OPEN_NO_RECALL 0x00400000 -#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000 - -#define FILE_ANY_ACCESS 0x00000000 -#define FILE_SPECIAL_ACCESS FILE_ANY_ACCESS -#define FILE_READ_ACCESS 0x00000001 -#define FILE_WRITE_ACCESS 0x00000002 - -#define FILE_ALL_ACCESS \ - (STANDARD_RIGHTS_REQUIRED | \ - SYNCHRONIZE | \ - 0x1FF) - -#define FILE_GENERIC_EXECUTE \ - (STANDARD_RIGHTS_EXECUTE | \ - FILE_READ_ATTRIBUTES | \ - FILE_EXECUTE | \ - SYNCHRONIZE) - -#define FILE_GENERIC_READ \ - (STANDARD_RIGHTS_READ | \ - FILE_READ_DATA | \ - FILE_READ_ATTRIBUTES | \ - FILE_READ_EA | \ - SYNCHRONIZE) - -#define FILE_GENERIC_WRITE \ - (STANDARD_RIGHTS_WRITE | \ - FILE_WRITE_DATA | \ - FILE_WRITE_ATTRIBUTES | \ - FILE_WRITE_EA | \ - FILE_APPEND_DATA | \ - SYNCHRONIZE) - -/* Exported object types */ -extern NTOSAPI POBJECT_TYPE ExDesktopObjectType; -extern NTOSAPI POBJECT_TYPE ExEventObjectType; -extern NTOSAPI POBJECT_TYPE ExSemaphoreObjectType; -extern NTOSAPI POBJECT_TYPE ExWindowStationObjectType; -extern NTOSAPI POBJECT_TYPE IoAdapterObjectType; -extern NTOSAPI ULONG IoDeviceHandlerObjectSize; -extern NTOSAPI POBJECT_TYPE IoDeviceHandlerObjectType; -extern NTOSAPI POBJECT_TYPE IoDeviceObjectType; -extern NTOSAPI POBJECT_TYPE IoDriverObjectType; -extern NTOSAPI POBJECT_TYPE IoFileObjectType; -extern NTOSAPI POBJECT_TYPE LpcPortObjectType; -extern NTOSAPI POBJECT_TYPE MmSectionObjectType; -extern NTOSAPI POBJECT_TYPE SeTokenObjectType; - -extern NTOSAPI CCHAR KeNumberProcessors; -extern NTOSAPI PHAL_DISPATCH_TABLE HalDispatchTable; -extern NTOSAPI PHAL_PRIVATE_DISPATCH_TABLE HalPrivateDispatchTable; - - -/* -** IRP function codes -*/ - -#define IRP_MJ_CREATE 0x00 -#define IRP_MJ_CREATE_NAMED_PIPE 0x01 -#define IRP_MJ_CLOSE 0x02 -#define IRP_MJ_READ 0x03 -#define IRP_MJ_WRITE 0x04 -#define IRP_MJ_QUERY_INFORMATION 0x05 -#define IRP_MJ_SET_INFORMATION 0x06 -#define IRP_MJ_QUERY_EA 0x07 -#define IRP_MJ_SET_EA 0x08 -#define IRP_MJ_FLUSH_BUFFERS 0x09 -#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a -#define IRP_MJ_SET_VOLUME_INFORMATION 0x0b -#define IRP_MJ_DIRECTORY_CONTROL 0x0c -#define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d -#define IRP_MJ_DEVICE_CONTROL 0x0e -#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f -#define IRP_MJ_SCSI 0x0f -#define IRP_MJ_SHUTDOWN 0x10 -#define IRP_MJ_LOCK_CONTROL 0x11 -#define IRP_MJ_CLEANUP 0x12 -#define IRP_MJ_CREATE_MAILSLOT 0x13 -#define IRP_MJ_QUERY_SECURITY 0x14 -#define IRP_MJ_SET_SECURITY 0x15 -#define IRP_MJ_POWER 0x16 -#define IRP_MJ_SYSTEM_CONTROL 0x17 -#define IRP_MJ_DEVICE_CHANGE 0x18 -#define IRP_MJ_QUERY_QUOTA 0x19 -#define IRP_MJ_SET_QUOTA 0x1a -#define IRP_MJ_PNP 0x1b -#define IRP_MJ_PNP_POWER 0x1b -#define IRP_MJ_MAXIMUM_FUNCTION 0x1b - -#define IRP_MN_QUERY_DIRECTORY 0x01 -#define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x02 - -#define IRP_MN_USER_FS_REQUEST 0x00 -#define IRP_MN_MOUNT_VOLUME 0x01 -#define IRP_MN_VERIFY_VOLUME 0x02 -#define IRP_MN_LOAD_FILE_SYSTEM 0x03 -#define IRP_MN_TRACK_LINK 0x04 -#define IRP_MN_KERNEL_CALL 0x04 - -#define IRP_MN_LOCK 0x01 -#define IRP_MN_UNLOCK_SINGLE 0x02 -#define IRP_MN_UNLOCK_ALL 0x03 -#define IRP_MN_UNLOCK_ALL_BY_KEY 0x04 - -#define IRP_MN_NORMAL 0x00 -#define IRP_MN_DPC 0x01 -#define IRP_MN_MDL 0x02 -#define IRP_MN_COMPLETE 0x04 -#define IRP_MN_COMPRESSED 0x08 - -#define IRP_MN_MDL_DPC (IRP_MN_MDL | IRP_MN_DPC) -#define IRP_MN_COMPLETE_MDL (IRP_MN_COMPLETE | IRP_MN_MDL) -#define IRP_MN_COMPLETE_MDL_DPC (IRP_MN_COMPLETE_MDL | IRP_MN_DPC) - -#define IRP_MN_SCSI_CLASS 0x01 - -#define IRP_MN_START_DEVICE 0x00 -#define IRP_MN_QUERY_REMOVE_DEVICE 0x01 -#define IRP_MN_REMOVE_DEVICE 0x02 -#define IRP_MN_CANCEL_REMOVE_DEVICE 0x03 -#define IRP_MN_STOP_DEVICE 0x04 -#define IRP_MN_QUERY_STOP_DEVICE 0x05 -#define IRP_MN_CANCEL_STOP_DEVICE 0x06 - -#define IRP_MN_QUERY_DEVICE_RELATIONS 0x07 -#define IRP_MN_QUERY_INTERFACE 0x08 -#define IRP_MN_QUERY_CAPABILITIES 0x09 -#define IRP_MN_QUERY_RESOURCES 0x0A -#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS 0x0B -#define IRP_MN_QUERY_DEVICE_TEXT 0x0C -#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D - -#define IRP_MN_READ_CONFIG 0x0F -#define IRP_MN_WRITE_CONFIG 0x10 -#define IRP_MN_EJECT 0x11 -#define IRP_MN_SET_LOCK 0x12 -#define IRP_MN_QUERY_ID 0x13 -#define IRP_MN_QUERY_PNP_DEVICE_STATE 0x14 -#define IRP_MN_QUERY_BUS_INFORMATION 0x15 -#define IRP_MN_DEVICE_USAGE_NOTIFICATION 0x16 -#define IRP_MN_SURPRISE_REMOVAL 0x17 -#define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18 - -#define IRP_MN_WAIT_WAKE 0x00 -#define IRP_MN_POWER_SEQUENCE 0x01 -#define IRP_MN_SET_POWER 0x02 -#define IRP_MN_QUERY_POWER 0x03 - -#define IRP_MN_QUERY_ALL_DATA 0x00 -#define IRP_MN_QUERY_SINGLE_INSTANCE 0x01 -#define IRP_MN_CHANGE_SINGLE_INSTANCE 0x02 -#define IRP_MN_CHANGE_SINGLE_ITEM 0x03 -#define IRP_MN_ENABLE_EVENTS 0x04 -#define IRP_MN_DISABLE_EVENTS 0x05 -#define IRP_MN_ENABLE_COLLECTION 0x06 -#define IRP_MN_DISABLE_COLLECTION 0x07 -#define IRP_MN_REGINFO 0x08 -#define IRP_MN_EXECUTE_METHOD 0x09 - -#define IRP_MN_REGINFO_EX 0x0b - -typedef enum _IO_ALLOCATION_ACTION { - KeepObject = 1, - DeallocateObject, - DeallocateObjectKeepRegisters -} IO_ALLOCATION_ACTION, *PIO_ALLOCATION_ACTION; - -typedef IO_ALLOCATION_ACTION DDKAPI -(*PDRIVER_CONTROL)( - IN struct _DEVICE_OBJECT *DeviceObject, - IN struct _IRP *Irp, - IN PVOID MapRegisterBase, - IN PVOID Context); - -typedef VOID DDKAPI -(*PDRIVER_LIST_CONTROL)( - IN struct _DEVICE_OBJECT *DeviceObject, - IN struct _IRP *Irp, - IN struct _SCATTER_GATHER_LIST *ScatterGather, - IN PVOID Context); - -typedef NTSTATUS DDKAPI -(*PDRIVER_ADD_DEVICE)( - IN struct _DRIVER_OBJECT *DriverObject, - IN struct _DEVICE_OBJECT *PhysicalDeviceObject); - -typedef NTSTATUS DDKAPI -(*PIO_COMPLETION_ROUTINE)( - IN struct _DEVICE_OBJECT *DeviceObject, - IN struct _IRP *Irp, - IN PVOID Context); - -typedef VOID DDKAPI -(*PDRIVER_CANCEL)( - IN struct _DEVICE_OBJECT *DeviceObject, - IN struct _IRP *Irp); - -typedef VOID DDKAPI -(*PKDEFERRED_ROUTINE)( - IN struct _KDPC *Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2); - -typedef NTSTATUS DDKAPI -(*PDRIVER_DISPATCH)( - IN struct _DEVICE_OBJECT *DeviceObject, - IN struct _IRP *Irp); - -typedef VOID DDKAPI -(*PIO_DPC_ROUTINE)( - IN struct _KDPC *Dpc, - IN struct _DEVICE_OBJECT *DeviceObject, - IN struct _IRP *Irp, - IN PVOID Context); - -typedef NTSTATUS DDKAPI -(*PMM_DLL_INITIALIZE)( - IN PUNICODE_STRING RegistryPath); - -typedef NTSTATUS DDKAPI -(*PMM_DLL_UNLOAD)( - VOID); - -typedef NTSTATUS DDKAPI -(*PDRIVER_ENTRY)( - IN struct _DRIVER_OBJECT *DriverObject, - IN PUNICODE_STRING RegistryPath); - -typedef NTSTATUS DDKAPI -(*PDRIVER_INITIALIZE)( - IN struct _DRIVER_OBJECT *DriverObject, - IN PUNICODE_STRING RegistryPath); - -typedef BOOLEAN DDKAPI -(*PKSERVICE_ROUTINE)( - IN struct _KINTERRUPT *Interrupt, - IN PVOID ServiceContext); - -typedef VOID DDKAPI -(*PIO_TIMER_ROUTINE)( - IN struct _DEVICE_OBJECT *DeviceObject, - IN PVOID Context); - -typedef VOID DDKAPI -(*PDRIVER_REINITIALIZE)( - IN struct _DRIVER_OBJECT *DriverObject, - IN PVOID Context, - IN ULONG Count); - -typedef NTSTATUS DDKAPI -(*PDRIVER_STARTIO)( - IN struct _DEVICE_OBJECT *DeviceObject, - IN struct _IRP *Irp); - -typedef BOOLEAN DDKAPI -(*PKSYNCHRONIZE_ROUTINE)( - IN PVOID SynchronizeContext); - -typedef VOID DDKAPI -(*PDRIVER_UNLOAD)( - IN struct _DRIVER_OBJECT *DriverObject); - - - -/* -** Plug and Play structures -*/ - -typedef VOID DDKAPI -(*PINTERFACE_REFERENCE)( - PVOID Context); - -typedef VOID DDKAPI -(*PINTERFACE_DEREFERENCE)( - PVOID Context); - -typedef BOOLEAN DDKAPI -(*PTRANSLATE_BUS_ADDRESS)( - IN PVOID Context, - IN PHYSICAL_ADDRESS BusAddress, - IN ULONG Length, - IN OUT PULONG AddressSpace, - OUT PPHYSICAL_ADDRESS TranslatedAddress); - -typedef struct _DMA_ADAPTER* DDKAPI -(*PGET_DMA_ADAPTER)( - IN PVOID Context, - IN struct _DEVICE_DESCRIPTION *DeviceDescriptor, - OUT PULONG NumberOfMapRegisters); - -typedef ULONG DDKAPI -(*PGET_SET_DEVICE_DATA)( - IN PVOID Context, - IN ULONG DataType, - IN PVOID Buffer, - IN ULONG Offset, - IN ULONG Length); - -typedef union _POWER_STATE { - SYSTEM_POWER_STATE SystemState; - DEVICE_POWER_STATE DeviceState; -} POWER_STATE, *PPOWER_STATE; - -typedef enum _POWER_STATE_TYPE { - SystemPowerState, - DevicePowerState -} POWER_STATE_TYPE, *PPOWER_STATE_TYPE; - -typedef struct _BUS_INTERFACE_STANDARD { - USHORT Size; - USHORT Version; - PVOID Context; - PINTERFACE_REFERENCE InterfaceReference; - PINTERFACE_DEREFERENCE InterfaceDereference; - PTRANSLATE_BUS_ADDRESS TranslateBusAddress; - PGET_DMA_ADAPTER GetDmaAdapter; - PGET_SET_DEVICE_DATA SetBusData; - PGET_SET_DEVICE_DATA GetBusData; -} BUS_INTERFACE_STANDARD, *PBUS_INTERFACE_STANDARD; - -typedef struct _DEVICE_CAPABILITIES { - USHORT Size; - USHORT Version; - ULONG DeviceD1 : 1; - ULONG DeviceD2 : 1; - ULONG LockSupported : 1; - ULONG EjectSupported : 1; - ULONG Removable : 1; - ULONG DockDevice : 1; - ULONG UniqueID : 1; - ULONG SilentInstall : 1; - ULONG RawDeviceOK : 1; - ULONG SurpriseRemovalOK : 1; - ULONG WakeFromD0 : 1; - ULONG WakeFromD1 : 1; - ULONG WakeFromD2 : 1; - ULONG WakeFromD3 : 1; - ULONG HardwareDisabled : 1; - ULONG NonDynamic : 1; - ULONG WarmEjectSupported : 1; - ULONG NoDisplayInUI : 1; - ULONG Reserved : 14; - ULONG Address; - ULONG UINumber; - DEVICE_POWER_STATE DeviceState[PowerSystemMaximum]; - SYSTEM_POWER_STATE SystemWake; - DEVICE_POWER_STATE DeviceWake; - ULONG D1Latency; - ULONG D2Latency; - ULONG D3Latency; -} DEVICE_CAPABILITIES, *PDEVICE_CAPABILITIES; - -typedef struct _DEVICE_INTERFACE_CHANGE_NOTIFICATION { - USHORT Version; - USHORT Size; - GUID Event; - GUID InterfaceClassGuid; - PUNICODE_STRING SymbolicLinkName; -} DEVICE_INTERFACE_CHANGE_NOTIFICATION, *PDEVICE_INTERFACE_CHANGE_NOTIFICATION; - -typedef struct _HWPROFILE_CHANGE_NOTIFICATION { - USHORT Version; - USHORT Size; - GUID Event; -} HWPROFILE_CHANGE_NOTIFICATION, *PHWPROFILE_CHANGE_NOTIFICATION; - -#undef INTERFACE - -typedef struct _INTERFACE { - USHORT Size; - USHORT Version; - PVOID Context; - PINTERFACE_REFERENCE InterfaceReference; - PINTERFACE_DEREFERENCE InterfaceDereference; -} INTERFACE, *PINTERFACE; - -typedef struct _PLUGPLAY_NOTIFICATION_HEADER { - USHORT Version; - USHORT Size; - GUID Event; -} PLUGPLAY_NOTIFICATION_HEADER, *PPLUGPLAY_NOTIFICATION_HEADER; - -typedef ULONG PNP_DEVICE_STATE, *PPNP_DEVICE_STATE; - -/* PNP_DEVICE_STATE */ - -#define PNP_DEVICE_DISABLED 0x00000001 -#define PNP_DEVICE_DONT_DISPLAY_IN_UI 0x00000002 -#define PNP_DEVICE_FAILED 0x00000004 -#define PNP_DEVICE_REMOVED 0x00000008 -#define PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED 0x00000010 -#define PNP_DEVICE_NOT_DISABLEABLE 0x00000020 - -typedef struct _TARGET_DEVICE_CUSTOM_NOTIFICATION { - USHORT Version; - USHORT Size; - GUID Event; - struct _FILE_OBJECT *FileObject; - LONG NameBufferOffset; - UCHAR CustomDataBuffer[1]; -} TARGET_DEVICE_CUSTOM_NOTIFICATION, *PTARGET_DEVICE_CUSTOM_NOTIFICATION; - -typedef struct _TARGET_DEVICE_REMOVAL_NOTIFICATION { - USHORT Version; - USHORT Size; - GUID Event; - struct _FILE_OBJECT *FileObject; -} TARGET_DEVICE_REMOVAL_NOTIFICATION, *PTARGET_DEVICE_REMOVAL_NOTIFICATION; - -typedef enum _BUS_QUERY_ID_TYPE { - BusQueryDeviceID, - BusQueryHardwareIDs, - BusQueryCompatibleIDs, - BusQueryInstanceID, - BusQueryDeviceSerialNumber -} BUS_QUERY_ID_TYPE, *PBUS_QUERY_ID_TYPE; - -typedef enum _DEVICE_TEXT_TYPE { - DeviceTextDescription, - DeviceTextLocationInformation -} DEVICE_TEXT_TYPE, *PDEVICE_TEXT_TYPE; - -typedef enum _DEVICE_USAGE_NOTIFICATION_TYPE { - DeviceUsageTypeUndefined, - DeviceUsageTypePaging, - DeviceUsageTypeHibernation, - DeviceUsageTypeDumpFile -} DEVICE_USAGE_NOTIFICATION_TYPE; - -typedef struct _POWER_SEQUENCE { - ULONG SequenceD1; - ULONG SequenceD2; - ULONG SequenceD3; -} POWER_SEQUENCE, *PPOWER_SEQUENCE; - -typedef enum { - DevicePropertyDeviceDescription, - DevicePropertyHardwareID, - DevicePropertyCompatibleIDs, - DevicePropertyBootConfiguration, - DevicePropertyBootConfigurationTranslated, - DevicePropertyClassName, - DevicePropertyClassGuid, - DevicePropertyDriverKeyName, - DevicePropertyManufacturer, - DevicePropertyFriendlyName, - DevicePropertyLocationInformation, - DevicePropertyPhysicalDeviceObjectName, - DevicePropertyBusTypeGuid, - DevicePropertyLegacyBusType, - DevicePropertyBusNumber, - DevicePropertyEnumeratorName, - DevicePropertyAddress, - DevicePropertyUINumber, - DevicePropertyInstallState, - DevicePropertyRemovalPolicy -} DEVICE_REGISTRY_PROPERTY; - -typedef enum _IO_NOTIFICATION_EVENT_CATEGORY { - EventCategoryReserved, - EventCategoryHardwareProfileChange, - EventCategoryDeviceInterfaceChange, - EventCategoryTargetDeviceChange -} IO_NOTIFICATION_EVENT_CATEGORY; - -#define PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES 0x00000001 - -typedef NTSTATUS DDKAPI -(*PDRIVER_NOTIFICATION_CALLBACK_ROUTINE)( - IN PVOID NotificationStructure, - IN PVOID Context); - -typedef VOID DDKAPI -(*PDEVICE_CHANGE_COMPLETE_CALLBACK)( - IN PVOID Context); - - - -/* -** System structures -*/ - -#define SYMBOLIC_LINK_QUERY 0x0001 -#define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1) - -#define DUPLICATE_CLOSE_SOURCE 0x00000001 -#define DUPLICATE_SAME_ACCESS 0x00000002 -#define DUPLICATE_SAME_ATTRIBUTES 0x00000004 - -typedef struct _OBJECT_NAME_INFORMATION { - UNICODE_STRING Name; -} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; - -typedef VOID DDKAPI -(*PIO_APC_ROUTINE)( - IN PVOID ApcContext, - IN PIO_STATUS_BLOCK IoStatusBlock, - IN ULONG Reserved); - -typedef struct _IO_STATUS_BLOCK { - union { - NTSTATUS Status; - PVOID Pointer; - }; - ULONG_PTR Information; -} IO_STATUS_BLOCK; - -typedef VOID DDKAPI -(*PKNORMAL_ROUTINE)( - IN PVOID NormalContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2); - -typedef VOID DDKAPI -(*PKKERNEL_ROUTINE)( - IN struct _KAPC *Apc, - IN OUT PKNORMAL_ROUTINE *NormalRoutine, - IN OUT PVOID *NormalContext, - IN OUT PVOID *SystemArgument1, - IN OUT PVOID *SystemArgument2); - -typedef VOID DDKAPI -(*PKRUNDOWN_ROUTINE)( - IN struct _KAPC *Apc); - -typedef BOOLEAN DDKAPI -(*PKTRANSFER_ROUTINE)( - VOID); - -typedef struct _KAPC { - CSHORT Type; - CSHORT Size; - ULONG Spare0; - struct _KTHREAD *Thread; - LIST_ENTRY ApcListEntry; - PKKERNEL_ROUTINE KernelRoutine; - PKRUNDOWN_ROUTINE RundownRoutine; - PKNORMAL_ROUTINE NormalRoutine; - PVOID NormalContext; - PVOID SystemArgument1; - PVOID SystemArgument2; - CCHAR ApcStateIndex; - KPROCESSOR_MODE ApcMode; - BOOLEAN Inserted; -} KAPC, *PKAPC, *RESTRICTED_POINTER PRKAPC; - -typedef struct _KDEVICE_QUEUE { - CSHORT Type; - CSHORT Size; - LIST_ENTRY DeviceListHead; - KSPIN_LOCK Lock; - BOOLEAN Busy; -} KDEVICE_QUEUE, *PKDEVICE_QUEUE, *RESTRICTED_POINTER PRKDEVICE_QUEUE; - -typedef struct _KDEVICE_QUEUE_ENTRY { - LIST_ENTRY DeviceListEntry; - ULONG SortKey; - BOOLEAN Inserted; -} KDEVICE_QUEUE_ENTRY, *PKDEVICE_QUEUE_ENTRY, -*RESTRICTED_POINTER PRKDEVICE_QUEUE_ENTRY; - -#define LOCK_QUEUE_WAIT 1 -#define LOCK_QUEUE_OWNER 2 - -typedef enum _KSPIN_LOCK_QUEUE_NUMBER { - LockQueueDispatcherLock, - LockQueueContextSwapLock, - LockQueuePfnLock, - LockQueueSystemSpaceLock, - LockQueueVacbLock, - LockQueueMasterLock, - LockQueueNonPagedPoolLock, - LockQueueIoCancelLock, - LockQueueWorkQueueLock, - LockQueueIoVpbLock, - LockQueueIoDatabaseLock, - LockQueueIoCompletionLock, - LockQueueNtfsStructLock, - LockQueueAfdWorkQueueLock, - LockQueueBcbLock, - LockQueueMaximumLock -} KSPIN_LOCK_QUEUE_NUMBER, *PKSPIN_LOCK_QUEUE_NUMBER; - -typedef struct _KSPIN_LOCK_QUEUE { - struct _KSPIN_LOCK_QUEUE *VOLATILE Next; - PKSPIN_LOCK VOLATILE Lock; -} KSPIN_LOCK_QUEUE, *PKSPIN_LOCK_QUEUE; - -typedef struct _KLOCK_QUEUE_HANDLE { - KSPIN_LOCK_QUEUE LockQueue; - KIRQL OldIrql; -} KLOCK_QUEUE_HANDLE, *PKLOCK_QUEUE_HANDLE; - -typedef struct _KDPC { - CSHORT Type; - UCHAR Number; - UCHAR Importance; - LIST_ENTRY DpcListEntry; - PKDEFERRED_ROUTINE DeferredRoutine; - PVOID DeferredContext; - PVOID SystemArgument1; - PVOID SystemArgument2; - PULONG_PTR Lock; -} KDPC, *PKDPC, *RESTRICTED_POINTER PRKDPC; - -typedef struct _WAIT_CONTEXT_BLOCK { - KDEVICE_QUEUE_ENTRY WaitQueueEntry; - struct _DRIVER_CONTROL *DeviceRoutine; - PVOID DeviceContext; - ULONG NumberOfMapRegisters; - PVOID DeviceObject; - PVOID CurrentIrp; - PKDPC BufferChainingDpc; -} WAIT_CONTEXT_BLOCK, *PWAIT_CONTEXT_BLOCK; - -typedef struct _DISPATCHER_HEADER { - UCHAR Type; - UCHAR Absolute; - UCHAR Size; - UCHAR Inserted; - LONG SignalState; - LIST_ENTRY WaitListHead; -} DISPATCHER_HEADER, *PDISPATCHER_HEADER; - -typedef struct _KEVENT { - DISPATCHER_HEADER Header; -} KEVENT, *PKEVENT, *RESTRICTED_POINTER PRKEVENT; - -typedef struct _KSEMAPHORE { - DISPATCHER_HEADER Header; - LONG Limit; -} KSEMAPHORE, *PKSEMAPHORE, *RESTRICTED_POINTER PRKSEMAPHORE; - -typedef struct _FAST_MUTEX { - LONG Count; - struct _KTHREAD *Owner; - ULONG Contention; - KEVENT Event; - ULONG OldIrql; -} FAST_MUTEX, *PFAST_MUTEX; - -typedef struct _KTIMER { - DISPATCHER_HEADER Header; - ULARGE_INTEGER DueTime; - LIST_ENTRY TimerListEntry; - struct _KDPC *Dpc; - LONG Period; -} KTIMER, *PKTIMER, *RESTRICTED_POINTER PRKTIMER; - -typedef struct _KMUTANT { - DISPATCHER_HEADER Header; - LIST_ENTRY MutantListEntry; - struct _KTHREAD *RESTRICTED_POINTER OwnerThread; - BOOLEAN Abandoned; - UCHAR ApcDisable; -} KMUTANT, *PKMUTANT, *RESTRICTED_POINTER PRKMUTANT, KMUTEX, *PKMUTEX, *RESTRICTED_POINTER PRKMUTEX; - -typedef enum _TIMER_TYPE { - NotificationTimer, - SynchronizationTimer -} TIMER_TYPE; - -#define EVENT_INCREMENT 1 -#define IO_NO_INCREMENT 0 -#define IO_CD_ROM_INCREMENT 1 -#define IO_DISK_INCREMENT 1 -#define IO_KEYBOARD_INCREMENT 6 -#define IO_MAILSLOT_INCREMENT 2 -#define IO_MOUSE_INCREMENT 6 -#define IO_NAMED_PIPE_INCREMENT 2 -#define IO_NETWORK_INCREMENT 2 -#define IO_PARALLEL_INCREMENT 1 -#define IO_SERIAL_INCREMENT 2 -#define IO_SOUND_INCREMENT 8 -#define IO_VIDEO_INCREMENT 1 -#define SEMAPHORE_INCREMENT 1 - -typedef struct _IRP { - CSHORT Type; - USHORT Size; - struct _MDL *MdlAddress; - ULONG Flags; - union { - struct _IRP *MasterIrp; - LONG IrpCount; - PVOID SystemBuffer; - } AssociatedIrp; - LIST_ENTRY ThreadListEntry; - IO_STATUS_BLOCK IoStatus; - KPROCESSOR_MODE RequestorMode; - BOOLEAN PendingReturned; - CHAR StackCount; - CHAR CurrentLocation; - BOOLEAN Cancel; - KIRQL CancelIrql; - CCHAR ApcEnvironment; - UCHAR AllocationFlags; - PIO_STATUS_BLOCK UserIosb; - PKEVENT UserEvent; - union { - struct { - PIO_APC_ROUTINE UserApcRoutine; - PVOID UserApcContext; - } AsynchronousParameters; - LARGE_INTEGER AllocationSize; - } Overlay; - PDRIVER_CANCEL CancelRoutine; - PVOID UserBuffer; - union { - struct { - union { - KDEVICE_QUEUE_ENTRY DeviceQueueEntry; - struct { - PVOID DriverContext[4]; - }; - }; - PETHREAD Thread; - PCHAR AuxiliaryBuffer; - struct { - LIST_ENTRY ListEntry; - union { - struct _IO_STACK_LOCATION *CurrentStackLocation; - ULONG PacketType; - }; - }; - struct _FILE_OBJECT *OriginalFileObject; - } Overlay; - KAPC Apc; - PVOID CompletionKey; - } Tail; -} IRP; -typedef struct _IRP *PIRP; - -/* IRP.Flags */ - -#define SL_FORCE_ACCESS_CHECK 0x01 -#define SL_OPEN_PAGING_FILE 0x02 -#define SL_OPEN_TARGET_DIRECTORY 0x04 -#define SL_CASE_SENSITIVE 0x80 - -#define SL_KEY_SPECIFIED 0x01 -#define SL_OVERRIDE_VERIFY_VOLUME 0x02 -#define SL_WRITE_THROUGH 0x04 -#define SL_FT_SEQUENTIAL_WRITE 0x08 - -#define SL_FAIL_IMMEDIATELY 0x01 -#define SL_EXCLUSIVE_LOCK 0x02 - -#define SL_RESTART_SCAN 0x01 -#define SL_RETURN_SINGLE_ENTRY 0x02 -#define SL_INDEX_SPECIFIED 0x04 - -#define SL_WATCH_TREE 0x01 - -#define SL_ALLOW_RAW_MOUNT 0x01 - -#define CTL_CODE(DeviceType, Function, Method, Access)( \ - ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) - -#define DEVICE_TYPE_FROM_CTL_CODE(ctl) (((ULONG) (ctl & 0xffff0000)) >> 16) - - -typedef struct _DRIVE_LAYOUT_INFORMATION_MBR { - ULONG Signature; -} DRIVE_LAYOUT_INFORMATION_MBR, *PDRIVE_LAYOUT_INFORMATION_MBR; - -typedef struct _DRIVE_LAYOUT_INFORMATION_GPT { - GUID DiskId; - LARGE_INTEGER StartingUsableOffset; - LARGE_INTEGER UsableLength; - ULONG MaxPartitionCount; -} DRIVE_LAYOUT_INFORMATION_GPT, *PDRIVE_LAYOUT_INFORMATION_GPT; - -typedef struct _PARTITION_INFORMATION_MBR { - UCHAR PartitionType; - BOOLEAN BootIndicator; - BOOLEAN RecognizedPartition; - ULONG HiddenSectors; -} PARTITION_INFORMATION_MBR, *PPARTITION_INFORMATION_MBR; - - -typedef struct _BOOTDISK_INFORMATION { - LONGLONG BootPartitionOffset; - LONGLONG SystemPartitionOffset; - ULONG BootDeviceSignature; - ULONG SystemDeviceSignature; -} BOOTDISK_INFORMATION, *PBOOTDISK_INFORMATION; - -typedef struct _BOOTDISK_INFORMATION_EX { - LONGLONG BootPartitionOffset; - LONGLONG SystemPartitionOffset; - ULONG BootDeviceSignature; - ULONG SystemDeviceSignature; - GUID BootDeviceGuid; - GUID SystemDeviceGuid; - BOOLEAN BootDeviceIsGpt; - BOOLEAN SystemDeviceIsGpt; -} BOOTDISK_INFORMATION_EX, *PBOOTDISK_INFORMATION_EX; - -typedef struct _EISA_MEMORY_TYPE { - UCHAR ReadWrite : 1; - UCHAR Cached : 1; - UCHAR Reserved0 : 1; - UCHAR Type : 2; - UCHAR Shared : 1; - UCHAR Reserved1 : 1; - UCHAR MoreEntries : 1; -} EISA_MEMORY_TYPE, *PEISA_MEMORY_TYPE; - -typedef struct _EISA_MEMORY_CONFIGURATION { - EISA_MEMORY_TYPE ConfigurationByte; - UCHAR DataSize; - USHORT AddressLowWord; - UCHAR AddressHighByte; - USHORT MemorySize; -} EISA_MEMORY_CONFIGURATION, *PEISA_MEMORY_CONFIGURATION; - -typedef struct _EISA_IRQ_DESCRIPTOR { - UCHAR Interrupt : 4; - UCHAR Reserved : 1; - UCHAR LevelTriggered : 1; - UCHAR Shared : 1; - UCHAR MoreEntries : 1; -} EISA_IRQ_DESCRIPTOR, *PEISA_IRQ_DESCRIPTOR; - -typedef struct _EISA_IRQ_CONFIGURATION { - EISA_IRQ_DESCRIPTOR ConfigurationByte; - UCHAR Reserved; -} EISA_IRQ_CONFIGURATION, *PEISA_IRQ_CONFIGURATION; - -typedef struct _DMA_CONFIGURATION_BYTE0 { - UCHAR Channel : 3; - UCHAR Reserved : 3; - UCHAR Shared : 1; - UCHAR MoreEntries : 1; -} DMA_CONFIGURATION_BYTE0; - -typedef struct _DMA_CONFIGURATION_BYTE1 { - UCHAR Reserved0 : 2; - UCHAR TransferSize : 2; - UCHAR Timing : 2; - UCHAR Reserved1 : 2; -} DMA_CONFIGURATION_BYTE1; - -typedef struct _EISA_DMA_CONFIGURATION { - DMA_CONFIGURATION_BYTE0 ConfigurationByte0; - DMA_CONFIGURATION_BYTE1 ConfigurationByte1; -} EISA_DMA_CONFIGURATION, *PEISA_DMA_CONFIGURATION; - -typedef struct _EISA_PORT_DESCRIPTOR { - UCHAR NumberPorts : 5; - UCHAR Reserved : 1; - UCHAR Shared : 1; - UCHAR MoreEntries : 1; -} EISA_PORT_DESCRIPTOR, *PEISA_PORT_DESCRIPTOR; - -typedef struct _EISA_PORT_CONFIGURATION { - EISA_PORT_DESCRIPTOR Configuration; - USHORT PortAddress; -} EISA_PORT_CONFIGURATION, *PEISA_PORT_CONFIGURATION; - -typedef struct _CM_EISA_FUNCTION_INFORMATION { - ULONG CompressedId; - UCHAR IdSlotFlags1; - UCHAR IdSlotFlags2; - UCHAR MinorRevision; - UCHAR MajorRevision; - UCHAR Selections[26]; - UCHAR FunctionFlags; - UCHAR TypeString[80]; - EISA_MEMORY_CONFIGURATION EisaMemory[9]; - EISA_IRQ_CONFIGURATION EisaIrq[7]; - EISA_DMA_CONFIGURATION EisaDma[4]; - EISA_PORT_CONFIGURATION EisaPort[20]; - UCHAR InitializationData[60]; -} CM_EISA_FUNCTION_INFORMATION, *PCM_EISA_FUNCTION_INFORMATION; - -/* CM_EISA_FUNCTION_INFORMATION.FunctionFlags */ - -#define EISA_FUNCTION_ENABLED 0x80 -#define EISA_FREE_FORM_DATA 0x40 -#define EISA_HAS_PORT_INIT_ENTRY 0x20 -#define EISA_HAS_PORT_RANGE 0x10 -#define EISA_HAS_DMA_ENTRY 0x08 -#define EISA_HAS_IRQ_ENTRY 0x04 -#define EISA_HAS_MEMORY_ENTRY 0x02 -#define EISA_HAS_TYPE_ENTRY 0x01 -#define EISA_HAS_INFORMATION \ - EISA_HAS_PORT_RANGE + EISA_HAS_DMA_ENTRY + EISA_HAS_IRQ_ENTRY \ - + EISA_HAS_MEMORY_ENTRY + EISA_HAS_TYPE_ENTRY - -typedef struct _CM_EISA_SLOT_INFORMATION { - UCHAR ReturnCode; - UCHAR ReturnFlags; - UCHAR MajorRevision; - UCHAR MinorRevision; - USHORT Checksum; - UCHAR NumberFunctions; - UCHAR FunctionInformation; - ULONG CompressedId; -} CM_EISA_SLOT_INFORMATION, *PCM_EISA_SLOT_INFORMATION; - -/* CM_EISA_SLOT_INFORMATION.ReturnCode */ - -#define EISA_INVALID_SLOT 0x80 -#define EISA_INVALID_FUNCTION 0x81 -#define EISA_INVALID_CONFIGURATION 0x82 -#define EISA_EMPTY_SLOT 0x83 -#define EISA_INVALID_BIOS_CALL 0x86 - -typedef struct _CM_FLOPPY_DEVICE_DATA { - USHORT Version; - USHORT Revision; - CHAR Size[8]; - ULONG MaxDensity; - ULONG MountDensity; - UCHAR StepRateHeadUnloadTime; - UCHAR HeadLoadTime; - UCHAR MotorOffTime; - UCHAR SectorLengthCode; - UCHAR SectorPerTrack; - UCHAR ReadWriteGapLength; - UCHAR DataTransferLength; - UCHAR FormatGapLength; - UCHAR FormatFillCharacter; - UCHAR HeadSettleTime; - UCHAR MotorSettleTime; - UCHAR MaximumTrackValue; - UCHAR DataTransferRate; -} CM_FLOPPY_DEVICE_DATA, *PCM_FLOPPY_DEVICE_DATA; - -typedef enum _INTERFACE_TYPE { - InterfaceTypeUndefined = -1, - Internal, - Isa, - Eisa, - MicroChannel, - TurboChannel, - PCIBus, - VMEBus, - NuBus, - PCMCIABus, - CBus, - MPIBus, - MPSABus, - ProcessorInternal, - InternalPowerBus, - PNPISABus, - PNPBus, - MaximumInterfaceType -} INTERFACE_TYPE, *PINTERFACE_TYPE; - -typedef struct _PNP_BUS_INFORMATION { - GUID BusTypeGuid; - INTERFACE_TYPE LegacyBusType; - ULONG BusNumber; -} PNP_BUS_INFORMATION, *PPNP_BUS_INFORMATION; - -typedef struct _CM_PARTIAL_RESOURCE_DESCRIPTOR { - UCHAR Type; - UCHAR ShareDisposition; - USHORT Flags; - union { - struct { - PHYSICAL_ADDRESS Start; - ULONG Length; - } Generic; - struct { - PHYSICAL_ADDRESS Start; - ULONG Length; - } Port; - struct { - ULONG Level; - ULONG Vector; - ULONG Affinity; - } Interrupt; - struct { - PHYSICAL_ADDRESS Start; - ULONG Length; - } Memory; - struct { - ULONG Channel; - ULONG Port; - ULONG Reserved1; - } Dma; - struct { - ULONG Data[3]; - } DevicePrivate; - struct { - ULONG Start; - ULONG Length; - ULONG Reserved; - } BusNumber; - struct { - ULONG DataSize; - ULONG Reserved1; - ULONG Reserved2; - } DeviceSpecificData; - } u; -} CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR; - -/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Type */ - -#define CmResourceTypeNull 0 -#define CmResourceTypePort 1 -#define CmResourceTypeInterrupt 2 -#define CmResourceTypeMemory 3 -#define CmResourceTypeDma 4 -#define CmResourceTypeDeviceSpecific 5 -#define CmResourceTypeBusNumber 6 -#define CmResourceTypeMaximum 7 -#define CmResourceTypeNonArbitrated 128 -#define CmResourceTypeConfigData 128 -#define CmResourceTypeDevicePrivate 129 -#define CmResourceTypePcCardConfig 130 -#define CmResourceTypeMfCardConfig 131 - -/* CM_PARTIAL_RESOURCE_DESCRIPTOR.ShareDisposition */ - -typedef enum _CM_SHARE_DISPOSITION { - CmResourceShareUndetermined, - CmResourceShareDeviceExclusive, - CmResourceShareDriverExclusive, - CmResourceShareShared -} CM_SHARE_DISPOSITION; - -/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypePort */ - -#define CM_RESOURCE_PORT_MEMORY 0x0000 -#define CM_RESOURCE_PORT_IO 0x0001 -#define CM_RESOURCE_PORT_10_BIT_DECODE 0x0004 -#define CM_RESOURCE_PORT_12_BIT_DECODE 0x0008 -#define CM_RESOURCE_PORT_16_BIT_DECODE 0x0010 -#define CM_RESOURCE_PORT_POSITIVE_DECODE 0x0020 -#define CM_RESOURCE_PORT_PASSIVE_DECODE 0x0040 -#define CM_RESOURCE_PORT_WINDOW_DECODE 0x0080 - -/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypeInterrupt */ - -#define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE 0x0000 -#define CM_RESOURCE_INTERRUPT_LATCHED 0x0001 - -/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypeMemory */ - -#define CM_RESOURCE_MEMORY_READ_WRITE 0x0000 -#define CM_RESOURCE_MEMORY_READ_ONLY 0x0001 -#define CM_RESOURCE_MEMORY_WRITE_ONLY 0x0002 -#define CM_RESOURCE_MEMORY_PREFETCHABLE 0x0004 -#define CM_RESOURCE_MEMORY_COMBINEDWRITE 0x0008 -#define CM_RESOURCE_MEMORY_24 0x0010 -#define CM_RESOURCE_MEMORY_CACHEABLE 0x0020 - -/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypeDma */ - -#define CM_RESOURCE_DMA_8 0x0000 -#define CM_RESOURCE_DMA_16 0x0001 -#define CM_RESOURCE_DMA_32 0x0002 -#define CM_RESOURCE_DMA_8_AND_16 0x0004 -#define CM_RESOURCE_DMA_BUS_MASTER 0x0008 -#define CM_RESOURCE_DMA_TYPE_A 0x0010 -#define CM_RESOURCE_DMA_TYPE_B 0x0020 -#define CM_RESOURCE_DMA_TYPE_F 0x0040 - -typedef struct _CM_PARTIAL_RESOURCE_LIST { - USHORT Version; - USHORT Revision; - ULONG Count; - CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]; -} CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST; - -typedef struct _CM_FULL_RESOURCE_DESCRIPTOR { - INTERFACE_TYPE InterfaceType; - ULONG BusNumber; - CM_PARTIAL_RESOURCE_LIST PartialResourceList; -} CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR; - -typedef struct _CM_RESOURCE_LIST { - ULONG Count; - CM_FULL_RESOURCE_DESCRIPTOR List[1]; -} CM_RESOURCE_LIST, *PCM_RESOURCE_LIST; - -typedef struct _CM_INT13_DRIVE_PARAMETER { - USHORT DriveSelect; - ULONG MaxCylinders; - USHORT SectorsPerTrack; - USHORT MaxHeads; - USHORT NumberDrives; -} CM_INT13_DRIVE_PARAMETER, *PCM_INT13_DRIVE_PARAMETER; - -typedef struct _CM_KEYBOARD_DEVICE_DATA { - USHORT Version; - USHORT Revision; - UCHAR Type; - UCHAR Subtype; - USHORT KeyboardFlags; -} CM_KEYBOARD_DEVICE_DATA, *PCM_KEYBOARD_DEVICE_DATA; - -#define KEYBOARD_INSERT_ON 0x80 -#define KEYBOARD_CAPS_LOCK_ON 0x40 -#define KEYBOARD_NUM_LOCK_ON 0x20 -#define KEYBOARD_SCROLL_LOCK_ON 0x10 -#define KEYBOARD_ALT_KEY_DOWN 0x08 -#define KEYBOARD_CTRL_KEY_DOWN 0x04 -#define KEYBOARD_LEFT_SHIFT_DOWN 0x02 -#define KEYBOARD_RIGHT_SHIFT_DOWN 0x01 - -typedef struct _CM_MCA_POS_DATA { - USHORT AdapterId; - UCHAR PosData1; - UCHAR PosData2; - UCHAR PosData3; - UCHAR PosData4; -} CM_MCA_POS_DATA, *PCM_MCA_POS_DATA; - -typedef struct CM_Power_Data_s { - ULONG PD_Size; - DEVICE_POWER_STATE PD_MostRecentPowerState; - ULONG PD_Capabilities; - ULONG PD_D1Latency; - ULONG PD_D2Latency; - ULONG PD_D3Latency; - DEVICE_POWER_STATE PD_PowerStateMapping[PowerSystemMaximum]; -} CM_POWER_DATA, *PCM_POWER_DATA; - -#define PDCAP_D0_SUPPORTED 0x00000001 -#define PDCAP_D1_SUPPORTED 0x00000002 -#define PDCAP_D2_SUPPORTED 0x00000004 -#define PDCAP_D3_SUPPORTED 0x00000008 -#define PDCAP_WAKE_FROM_D0_SUPPORTED 0x00000010 -#define PDCAP_WAKE_FROM_D1_SUPPORTED 0x00000020 -#define PDCAP_WAKE_FROM_D2_SUPPORTED 0x00000040 -#define PDCAP_WAKE_FROM_D3_SUPPORTED 0x00000080 -#define PDCAP_WARM_EJECT_SUPPORTED 0x00000100 - -typedef struct _CM_SCSI_DEVICE_DATA { - USHORT Version; - USHORT Revision; - UCHAR HostIdentifier; -} CM_SCSI_DEVICE_DATA, *PCM_SCSI_DEVICE_DATA; - -typedef struct _CM_SERIAL_DEVICE_DATA { - USHORT Version; - USHORT Revision; - ULONG BaudClock; -} CM_SERIAL_DEVICE_DATA, *PCM_SERIAL_DEVICE_DATA; - -/* IO_RESOURCE_DESCRIPTOR.Option */ - -#define IO_RESOURCE_PREFERRED 0x01 -#define IO_RESOURCE_DEFAULT 0x02 -#define IO_RESOURCE_ALTERNATIVE 0x08 - -typedef struct _IO_RESOURCE_DESCRIPTOR { - UCHAR Option; - UCHAR Type; - UCHAR ShareDisposition; - UCHAR Spare1; - USHORT Flags; - USHORT Spare2; - union { - struct { - ULONG Length; - ULONG Alignment; - PHYSICAL_ADDRESS MinimumAddress; - PHYSICAL_ADDRESS MaximumAddress; - } Port; - struct { - ULONG Length; - ULONG Alignment; - PHYSICAL_ADDRESS MinimumAddress; - PHYSICAL_ADDRESS MaximumAddress; - } Memory; - struct { - ULONG MinimumVector; - ULONG MaximumVector; - } Interrupt; - struct { - ULONG MinimumChannel; - ULONG MaximumChannel; - } Dma; - struct { - ULONG Length; - ULONG Alignment; - PHYSICAL_ADDRESS MinimumAddress; - PHYSICAL_ADDRESS MaximumAddress; - } Generic; - struct { - ULONG Data[3]; - } DevicePrivate; - struct { - ULONG Length; - ULONG MinBusNumber; - ULONG MaxBusNumber; - ULONG Reserved; - } BusNumber; - struct { - ULONG Priority; - ULONG Reserved1; - ULONG Reserved2; - } ConfigData; - } u; -} IO_RESOURCE_DESCRIPTOR, *PIO_RESOURCE_DESCRIPTOR; - -typedef struct _IO_RESOURCE_LIST { - USHORT Version; - USHORT Revision; - ULONG Count; - IO_RESOURCE_DESCRIPTOR Descriptors[1]; -} IO_RESOURCE_LIST, *PIO_RESOURCE_LIST; - -typedef struct _IO_RESOURCE_REQUIREMENTS_LIST { - ULONG ListSize; - INTERFACE_TYPE InterfaceType; - ULONG BusNumber; - ULONG SlotNumber; - ULONG Reserved[3]; - ULONG AlternativeLists; - IO_RESOURCE_LIST List[1]; -} IO_RESOURCE_REQUIREMENTS_LIST, *PIO_RESOURCE_REQUIREMENTS_LIST; - -typedef struct _CONTROLLER_OBJECT { - CSHORT Type; - CSHORT Size; - PVOID ControllerExtension; - KDEVICE_QUEUE DeviceWaitQueue; - ULONG Spare1; - LARGE_INTEGER Spare2; -} CONTROLLER_OBJECT, *PCONTROLLER_OBJECT; - -typedef enum _DMA_WIDTH { - Width8Bits, - Width16Bits, - Width32Bits, - MaximumDmaWidth -} DMA_WIDTH, *PDMA_WIDTH; - -typedef enum _DMA_SPEED { - Compatible, - TypeA, - TypeB, - TypeC, - TypeF, - MaximumDmaSpeed -} DMA_SPEED, *PDMA_SPEED; - -/* DEVICE_DESCRIPTION.Version */ - -#define DEVICE_DESCRIPTION_VERSION 0x0000 -#define DEVICE_DESCRIPTION_VERSION1 0x0001 -#define DEVICE_DESCRIPTION_VERSION2 0x0002 - -typedef struct _DEVICE_DESCRIPTION { - ULONG Version; - BOOLEAN Master; - BOOLEAN ScatterGather; - BOOLEAN DemandMode; - BOOLEAN AutoInitialize; - BOOLEAN Dma32BitAddresses; - BOOLEAN IgnoreCount; - BOOLEAN Reserved1; - BOOLEAN Dma64BitAddresses; - ULONG BusNumber; - ULONG DmaChannel; - INTERFACE_TYPE InterfaceType; - DMA_WIDTH DmaWidth; - DMA_SPEED DmaSpeed; - ULONG MaximumLength; - ULONG DmaPort; -} DEVICE_DESCRIPTION, *PDEVICE_DESCRIPTION; - -/* VPB.Flags */ -#define VPB_MOUNTED 0x0001 -#define VPB_LOCKED 0x0002 -#define VPB_PERSISTENT 0x0004 -#define VPB_REMOVE_PENDING 0x0008 -#define VPB_RAW_MOUNT 0x0010 - -#define MAXIMUM_VOLUME_LABEL_LENGTH (32 * sizeof(WCHAR)) - -typedef struct _VPB { - CSHORT Type; - CSHORT Size; - USHORT Flags; - USHORT VolumeLabelLength; - struct _DEVICE_OBJECT *DeviceObject; - struct _DEVICE_OBJECT *RealDevice; - ULONG SerialNumber; - ULONG ReferenceCount; - WCHAR VolumeLabel[MAXIMUM_VOLUME_LABEL_LENGTH / sizeof(WCHAR)]; -} VPB, *PVPB; - -/* DEVICE_OBJECT.Flags */ - -#define DO_VERIFY_VOLUME 0x00000002 -#define DO_BUFFERED_IO 0x00000004 -#define DO_EXCLUSIVE 0x00000008 -#define DO_DIRECT_IO 0x00000010 -#define DO_MAP_IO_BUFFER 0x00000020 -#define DO_DEVICE_HAS_NAME 0x00000040 -#define DO_DEVICE_INITIALIZING 0x00000080 -#define DO_SYSTEM_BOOT_PARTITION 0x00000100 -#define DO_LONG_TERM_REQUESTS 0x00000200 -#define DO_NEVER_LAST_DEVICE 0x00000400 -#define DO_SHUTDOWN_REGISTERED 0x00000800 -#define DO_BUS_ENUMERATED_DEVICE 0x00001000 -#define DO_POWER_PAGABLE 0x00002000 -#define DO_POWER_INRUSH 0x00004000 -#define DO_LOW_PRIORITY_FILESYSTEM 0x00010000 - -/* DEVICE_OBJECT.Characteristics */ - -#define FILE_REMOVABLE_MEDIA 0x00000001 -#define FILE_READ_ONLY_DEVICE 0x00000002 -#define FILE_FLOPPY_DISKETTE 0x00000004 -#define FILE_WRITE_ONCE_MEDIA 0x00000008 -#define FILE_REMOTE_DEVICE 0x00000010 -#define FILE_DEVICE_IS_MOUNTED 0x00000020 -#define FILE_VIRTUAL_VOLUME 0x00000040 -#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080 -#define FILE_DEVICE_SECURE_OPEN 0x00000100 - -/* DEVICE_OBJECT.AlignmentRequirement */ - -#define FILE_BYTE_ALIGNMENT 0x00000000 -#define FILE_WORD_ALIGNMENT 0x00000001 -#define FILE_LONG_ALIGNMENT 0x00000003 -#define FILE_QUAD_ALIGNMENT 0x00000007 -#define FILE_OCTA_ALIGNMENT 0x0000000f -#define FILE_32_BYTE_ALIGNMENT 0x0000001f -#define FILE_64_BYTE_ALIGNMENT 0x0000003f -#define FILE_128_BYTE_ALIGNMENT 0x0000007f -#define FILE_256_BYTE_ALIGNMENT 0x000000ff -#define FILE_512_BYTE_ALIGNMENT 0x000001ff - -/* DEVICE_OBJECT.DeviceType */ - -#define DEVICE_TYPE ULONG - -#define FILE_DEVICE_BEEP 0x00000001 -#define FILE_DEVICE_CD_ROM 0x00000002 -#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 -#define FILE_DEVICE_CONTROLLER 0x00000004 -#define FILE_DEVICE_DATALINK 0x00000005 -#define FILE_DEVICE_DFS 0x00000006 -#define FILE_DEVICE_DISK 0x00000007 -#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 -#define FILE_DEVICE_FILE_SYSTEM 0x00000009 -#define FILE_DEVICE_INPORT_PORT 0x0000000a -#define FILE_DEVICE_KEYBOARD 0x0000000b -#define FILE_DEVICE_MAILSLOT 0x0000000c -#define FILE_DEVICE_MIDI_IN 0x0000000d -#define FILE_DEVICE_MIDI_OUT 0x0000000e -#define FILE_DEVICE_MOUSE 0x0000000f -#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 -#define FILE_DEVICE_NAMED_PIPE 0x00000011 -#define FILE_DEVICE_NETWORK 0x00000012 -#define FILE_DEVICE_NETWORK_BROWSER 0x00000013 -#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 -#define FILE_DEVICE_NULL 0x00000015 -#define FILE_DEVICE_PARALLEL_PORT 0x00000016 -#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 -#define FILE_DEVICE_PRINTER 0x00000018 -#define FILE_DEVICE_SCANNER 0x00000019 -#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a -#define FILE_DEVICE_SERIAL_PORT 0x0000001b -#define FILE_DEVICE_SCREEN 0x0000001c -#define FILE_DEVICE_SOUND 0x0000001d -#define FILE_DEVICE_STREAMS 0x0000001e -#define FILE_DEVICE_TAPE 0x0000001f -#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 -#define FILE_DEVICE_TRANSPORT 0x00000021 -#define FILE_DEVICE_UNKNOWN 0x00000022 -#define FILE_DEVICE_VIDEO 0x00000023 -#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 -#define FILE_DEVICE_WAVE_IN 0x00000025 -#define FILE_DEVICE_WAVE_OUT 0x00000026 -#define FILE_DEVICE_8042_PORT 0x00000027 -#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 -#define FILE_DEVICE_BATTERY 0x00000029 -#define FILE_DEVICE_BUS_EXTENDER 0x0000002a -#define FILE_DEVICE_MODEM 0x0000002b -#define FILE_DEVICE_VDM 0x0000002c -#define FILE_DEVICE_MASS_STORAGE 0x0000002d -#define FILE_DEVICE_SMB 0x0000002e -#define FILE_DEVICE_KS 0x0000002f -#define FILE_DEVICE_CHANGER 0x00000030 -#define FILE_DEVICE_SMARTCARD 0x00000031 -#define FILE_DEVICE_ACPI 0x00000032 -#define FILE_DEVICE_DVD 0x00000033 -#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034 -#define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035 -#define FILE_DEVICE_DFS_VOLUME 0x00000036 -#define FILE_DEVICE_SERENUM 0x00000037 -#define FILE_DEVICE_TERMSRV 0x00000038 -#define FILE_DEVICE_KSEC 0x00000039 -#define FILE_DEVICE_FIPS 0x0000003a - -typedef struct _DEVICE_OBJECT { - CSHORT Type; - USHORT Size; - LONG ReferenceCount; - struct _DRIVER_OBJECT *DriverObject; - struct _DEVICE_OBJECT *NextDevice; - struct _DEVICE_OBJECT *AttachedDevice; - struct _IRP *CurrentIrp; - PIO_TIMER Timer; - ULONG Flags; - ULONG Characteristics; - PVPB Vpb; - PVOID DeviceExtension; - DEVICE_TYPE DeviceType; - CCHAR StackSize; - union { - LIST_ENTRY ListEntry; - WAIT_CONTEXT_BLOCK Wcb; - } Queue; - ULONG AlignmentRequirement; - KDEVICE_QUEUE DeviceQueue; - KDPC Dpc; - ULONG ActiveThreadCount; - PSECURITY_DESCRIPTOR SecurityDescriptor; - KEVENT DeviceLock; - USHORT SectorSize; - USHORT Spare1; - struct _DEVOBJ_EXTENSION *DeviceObjectExtension; - PVOID Reserved; -} DEVICE_OBJECT; -typedef struct _DEVICE_OBJECT *PDEVICE_OBJECT; - -typedef enum _DEVICE_RELATION_TYPE { - BusRelations, - EjectionRelations, - PowerRelations, - RemovalRelations, - TargetDeviceRelation, - SingleBusRelations -} DEVICE_RELATION_TYPE, *PDEVICE_RELATION_TYPE; - -typedef struct _DEVICE_RELATIONS { - ULONG Count; - PDEVICE_OBJECT Objects[1]; -} DEVICE_RELATIONS, *PDEVICE_RELATIONS; - -typedef struct _SCATTER_GATHER_ELEMENT { - PHYSICAL_ADDRESS Address; - ULONG Length; - ULONG_PTR Reserved; -} SCATTER_GATHER_ELEMENT, *PSCATTER_GATHER_ELEMENT; - -typedef struct _SCATTER_GATHER_LIST { - ULONG NumberOfElements; - ULONG_PTR Reserved; - SCATTER_GATHER_ELEMENT Elements[0]; -} SCATTER_GATHER_LIST, *PSCATTER_GATHER_LIST; - -typedef struct _MDL { - struct _MDL *Next; - CSHORT Size; - CSHORT MdlFlags; - struct _EPROCESS *Process; - PVOID MappedSystemVa; - PVOID StartVa; - ULONG ByteCount; - ULONG ByteOffset; -} MDL, *PMDL; - -#define MDL_MAPPED_TO_SYSTEM_VA 0x0001 -#define MDL_PAGES_LOCKED 0x0002 -#define MDL_SOURCE_IS_NONPAGED_POOL 0x0004 -#define MDL_ALLOCATED_FIXED_SIZE 0x0008 -#define MDL_PARTIAL 0x0010 -#define MDL_PARTIAL_HAS_BEEN_MAPPED 0x0020 -#define MDL_IO_PAGE_READ 0x0040 -#define MDL_WRITE_OPERATION 0x0080 -#define MDL_PARENT_MAPPED_SYSTEM_VA 0x0100 -#define MDL_FREE_EXTRA_PTES 0x0200 -#define MDL_IO_SPACE 0x0800 -#define MDL_NETWORK_HEADER 0x1000 -#define MDL_MAPPING_CAN_FAIL 0x2000 -#define MDL_ALLOCATED_MUST_SUCCEED 0x4000 - -#define MDL_MAPPING_FLAGS ( \ - MDL_MAPPED_TO_SYSTEM_VA | \ - MDL_PAGES_LOCKED | \ - MDL_SOURCE_IS_NONPAGED_POOL | \ - MDL_PARTIAL_HAS_BEEN_MAPPED | \ - MDL_PARENT_MAPPED_SYSTEM_VA | \ - MDL_SYSTEM_VA | \ - MDL_IO_SPACE) - -typedef VOID DDKAPI -(*PPUT_DMA_ADAPTER)( - IN PDMA_ADAPTER DmaAdapter); - -typedef PVOID DDKAPI -(*PALLOCATE_COMMON_BUFFER)( - IN PDMA_ADAPTER DmaAdapter, - IN ULONG Length, - OUT PPHYSICAL_ADDRESS LogicalAddress, - IN BOOLEAN CacheEnabled); - -typedef VOID DDKAPI -(*PFREE_COMMON_BUFFER)( - IN PDMA_ADAPTER DmaAdapter, - IN ULONG Length, - IN PHYSICAL_ADDRESS LogicalAddress, - IN PVOID VirtualAddress, - IN BOOLEAN CacheEnabled); - -typedef NTSTATUS DDKAPI -(*PALLOCATE_ADAPTER_CHANNEL)( - IN PDMA_ADAPTER DmaAdapter, - IN PDEVICE_OBJECT DeviceObject, - IN ULONG NumberOfMapRegisters, - IN PDRIVER_CONTROL ExecutionRoutine, - IN PVOID Context); - -typedef BOOLEAN DDKAPI -(*PFLUSH_ADAPTER_BUFFERS)( - IN PDMA_ADAPTER DmaAdapter, - IN PMDL Mdl, - IN PVOID MapRegisterBase, - IN PVOID CurrentVa, - IN ULONG Length, - IN BOOLEAN WriteToDevice); - -typedef VOID DDKAPI -(*PFREE_ADAPTER_CHANNEL)( - IN PDMA_ADAPTER DmaAdapter); - -typedef VOID DDKAPI -(*PFREE_MAP_REGISTERS)( - IN PDMA_ADAPTER DmaAdapter, - PVOID MapRegisterBase, - ULONG NumberOfMapRegisters); - -typedef PHYSICAL_ADDRESS DDKAPI -(*PMAP_TRANSFER)( - IN PDMA_ADAPTER DmaAdapter, - IN PMDL Mdl, - IN PVOID MapRegisterBase, - IN PVOID CurrentVa, - IN OUT PULONG Length, - IN BOOLEAN WriteToDevice); - -typedef ULONG DDKAPI -(*PGET_DMA_ALIGNMENT)( - IN PDMA_ADAPTER DmaAdapter); - -typedef ULONG DDKAPI -(*PREAD_DMA_COUNTER)( - IN PDMA_ADAPTER DmaAdapter); - -typedef NTSTATUS DDKAPI -(*PGET_SCATTER_GATHER_LIST)( - IN PDMA_ADAPTER DmaAdapter, - IN PDEVICE_OBJECT DeviceObject, - IN PMDL Mdl, - IN PVOID CurrentVa, - IN ULONG Length, - IN PDRIVER_LIST_CONTROL ExecutionRoutine, - IN PVOID Context, - IN BOOLEAN WriteToDevice); - -typedef VOID DDKAPI -(*PPUT_SCATTER_GATHER_LIST)( - IN PDMA_ADAPTER DmaAdapter, - IN PSCATTER_GATHER_LIST ScatterGather, - IN BOOLEAN WriteToDevice); - -typedef NTSTATUS DDKAPI -(*PCALCULATE_SCATTER_GATHER_LIST_SIZE)( - IN PDMA_ADAPTER DmaAdapter, - IN PMDL Mdl OPTIONAL, - IN PVOID CurrentVa, - IN ULONG Length, - OUT PULONG ScatterGatherListSize, - OUT PULONG pNumberOfMapRegisters OPTIONAL); - -typedef NTSTATUS DDKAPI -(*PBUILD_SCATTER_GATHER_LIST)( - IN PDMA_ADAPTER DmaAdapter, - IN PDEVICE_OBJECT DeviceObject, - IN PMDL Mdl, - IN PVOID CurrentVa, - IN ULONG Length, - IN PDRIVER_LIST_CONTROL ExecutionRoutine, - IN PVOID Context, - IN BOOLEAN WriteToDevice, - IN PVOID ScatterGatherBuffer, - IN ULONG ScatterGatherLength); - -typedef NTSTATUS DDKAPI -(*PBUILD_MDL_FROM_SCATTER_GATHER_LIST)( - IN PDMA_ADAPTER DmaAdapter, - IN PSCATTER_GATHER_LIST ScatterGather, - IN PMDL OriginalMdl, - OUT PMDL *TargetMdl); - -typedef struct _DMA_OPERATIONS { - ULONG Size; - PPUT_DMA_ADAPTER PutDmaAdapter; - PALLOCATE_COMMON_BUFFER AllocateCommonBuffer; - PFREE_COMMON_BUFFER FreeCommonBuffer; - PALLOCATE_ADAPTER_CHANNEL AllocateAdapterChannel; - PFLUSH_ADAPTER_BUFFERS FlushAdapterBuffers; - PFREE_ADAPTER_CHANNEL FreeAdapterChannel; - PFREE_MAP_REGISTERS FreeMapRegisters; - PMAP_TRANSFER MapTransfer; - PGET_DMA_ALIGNMENT GetDmaAlignment; - PREAD_DMA_COUNTER ReadDmaCounter; - PGET_SCATTER_GATHER_LIST GetScatterGatherList; - PPUT_SCATTER_GATHER_LIST PutScatterGatherList; - PCALCULATE_SCATTER_GATHER_LIST_SIZE CalculateScatterGatherList; - PBUILD_SCATTER_GATHER_LIST BuildScatterGatherList; - PBUILD_MDL_FROM_SCATTER_GATHER_LIST BuildMdlFromScatterGatherList; -} DMA_OPERATIONS, *PDMA_OPERATIONS; - -typedef struct _DMA_ADAPTER { - USHORT Version; - USHORT Size; - PDMA_OPERATIONS DmaOperations; -} DMA_ADAPTER; - -typedef enum _FILE_INFORMATION_CLASS { - FileDirectoryInformation = 1, - FileFullDirectoryInformation, - FileBothDirectoryInformation, - FileBasicInformation, - FileStandardInformation, - FileInternalInformation, - FileEaInformation, - FileAccessInformation, - FileNameInformation, - FileRenameInformation, - FileLinkInformation, - FileNamesInformation, - FileDispositionInformation, - FilePositionInformation, - FileFullEaInformation, - FileModeInformation, - FileAlignmentInformation, - FileAllInformation, - FileAllocationInformation, - FileEndOfFileInformation, - FileAlternateNameInformation, - FileStreamInformation, - FilePipeInformation, - FilePipeLocalInformation, - FilePipeRemoteInformation, - FileMailslotQueryInformation, - FileMailslotSetInformation, - FileCompressionInformation, - FileObjectIdInformation, - FileCompletionInformation, - FileMoveClusterInformation, - FileQuotaInformation, - FileReparsePointInformation, - FileNetworkOpenInformation, - FileAttributeTagInformation, - FileTrackingInformation, - FileIdBothDirectoryInformation, - FileIdFullDirectoryInformation, - FileValidDataLengthInformation, - FileShortNameInformation, - FileMaximumInformation -} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; - -typedef struct _FILE_POSITION_INFORMATION { - LARGE_INTEGER CurrentByteOffset; -} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION; - -typedef struct _FILE_ALIGNMENT_INFORMATION { - ULONG AlignmentRequirement; -} FILE_ALIGNMENT_INFORMATION; - -typedef struct _FILE_NAME_INFORMATION { - ULONG FileNameLength; - WCHAR FileName[1]; -} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; - -typedef struct FILE_BASIC_INFORMATION { - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - ULONG FileAttributes; -} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; - -typedef struct _FILE_STANDARD_INFORMATION { - LARGE_INTEGER AllocationSize; - LARGE_INTEGER EndOfFile; - ULONG NumberOfLinks; - BOOLEAN DeletePending; - BOOLEAN Directory; -} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION; - -typedef struct _FILE_NETWORK_OPEN_INFORMATION { - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER AllocationSize; - LARGE_INTEGER EndOfFile; - ULONG FileAttributes; -} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION; - -typedef struct _FILE_ATTRIBUTE_TAG_INFORMATION { - ULONG FileAttributes; - ULONG ReparseTag; -} FILE_ATTRIBUTE_TAG_INFORMATION, *PFILE_ATTRIBUTE_TAG_INFORMATION; - -typedef struct _FILE_DISPOSITION_INFORMATION { - BOOLEAN DoDeleteFile; -} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; - -typedef struct _FILE_END_OF_FILE_INFORMATION { - LARGE_INTEGER EndOfFile; -} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION; - -typedef struct _FILE_VALID_DATA_LENGTH_INFORMATION { - LARGE_INTEGER ValidDataLength; -} FILE_VALID_DATA_LENGTH_INFORMATION, *PFILE_VALID_DATA_LENGTH_INFORMATION; - -typedef enum _FSINFOCLASS { - FileFsVolumeInformation = 1, - FileFsLabelInformation, - FileFsSizeInformation, - FileFsDeviceInformation, - FileFsAttributeInformation, - FileFsControlInformation, - FileFsFullSizeInformation, - FileFsObjectIdInformation, - FileFsDriverPathInformation, - FileFsMaximumInformation -} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS; - -typedef struct _FILE_FS_DEVICE_INFORMATION { - DEVICE_TYPE DeviceType; - ULONG Characteristics; -} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION; - -typedef struct _FILE_FULL_EA_INFORMATION { - ULONG NextEntryOffset; - UCHAR Flags; - UCHAR EaNameLength; - USHORT EaValueLength; - CHAR EaName[1]; -} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION; - -typedef ULONG_PTR ERESOURCE_THREAD; -typedef ERESOURCE_THREAD *PERESOURCE_THREAD; - -typedef struct _OWNER_ENTRY { - ERESOURCE_THREAD OwnerThread; - union { - LONG OwnerCount; - ULONG TableSize; - }; -} OWNER_ENTRY, *POWNER_ENTRY; - -/* ERESOURCE.Flag */ - -#define ResourceNeverExclusive 0x0010 -#define ResourceReleaseByOtherThread 0x0020 -#define ResourceOwnedExclusive 0x0080 - -#define RESOURCE_HASH_TABLE_SIZE 64 - -typedef struct _ERESOURCE { - LIST_ENTRY SystemResourcesList; - POWNER_ENTRY OwnerTable; - SHORT ActiveCount; - USHORT Flag; - PKSEMAPHORE SharedWaiters; - PKEVENT ExclusiveWaiters; - OWNER_ENTRY OwnerThreads[2]; - ULONG ContentionCount; - USHORT NumberOfSharedWaiters; - USHORT NumberOfExclusiveWaiters; - union { - PVOID Address; - ULONG_PTR CreatorBackTraceIndex; - }; - KSPIN_LOCK SpinLock; -} ERESOURCE, *PERESOURCE; - -/* NOTE: PVOID for methods to avoid 'assignment from incompatible pointer type' warning */ -typedef struct _DRIVER_EXTENSION { - struct _DRIVER_OBJECT *DriverObject; - PVOID AddDevice; - ULONG Count; - UNICODE_STRING ServiceKeyName; -} DRIVER_EXTENSION, *PDRIVER_EXTENSION; - -typedef BOOLEAN DDKAPI -(*PFAST_IO_CHECK_IF_POSSIBLE)( - IN struct _FILE_OBJECT *FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN BOOLEAN Wait, - IN ULONG LockKey, - IN BOOLEAN CheckForReadOperation, - OUT PIO_STATUS_BLOCK IoStatus, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_READ)( - IN struct _FILE_OBJECT *FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN BOOLEAN Wait, - IN ULONG LockKey, - OUT PVOID Buffer, - OUT PIO_STATUS_BLOCK IoStatus, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_WRITE)( - IN struct _FILE_OBJECT *FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN BOOLEAN Wait, - IN ULONG LockKey, - IN PVOID Buffer, - OUT PIO_STATUS_BLOCK IoStatus, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_QUERY_BASIC_INFO)( - IN struct _FILE_OBJECT *FileObject, - IN BOOLEAN Wait, - OUT PFILE_BASIC_INFORMATION Buffer, - OUT PIO_STATUS_BLOCK IoStatus, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_QUERY_STANDARD_INFO)( - IN struct _FILE_OBJECT *FileObject, - IN BOOLEAN Wait, - OUT PFILE_STANDARD_INFORMATION Buffer, - OUT PIO_STATUS_BLOCK IoStatus, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_LOCK)( - IN struct _FILE_OBJECT *FileObject, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - PEPROCESS ProcessId, - ULONG Key, - BOOLEAN FailImmediately, - BOOLEAN ExclusiveLock, - OUT PIO_STATUS_BLOCK IoStatus, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_UNLOCK_SINGLE)( - IN struct _FILE_OBJECT *FileObject, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - PEPROCESS ProcessId, - ULONG Key, - OUT PIO_STATUS_BLOCK IoStatus, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_UNLOCK_ALL)( - IN struct _FILE_OBJECT *FileObject, - PEPROCESS ProcessId, - OUT PIO_STATUS_BLOCK IoStatus, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_UNLOCK_ALL_BY_KEY)( - IN struct _FILE_OBJECT *FileObject, - PVOID ProcessId, - ULONG Key, - OUT PIO_STATUS_BLOCK IoStatus, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_DEVICE_CONTROL)( - IN struct _FILE_OBJECT *FileObject, - IN BOOLEAN Wait, - IN PVOID InputBuffer OPTIONAL, - IN ULONG InputBufferLength, - OUT PVOID OutputBuffer OPTIONAL, - IN ULONG OutputBufferLength, - IN ULONG IoControlCode, - OUT PIO_STATUS_BLOCK IoStatus, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef VOID DDKAPI -(*PFAST_IO_ACQUIRE_FILE)( - IN struct _FILE_OBJECT *FileObject); - -typedef VOID DDKAPI -(*PFAST_IO_RELEASE_FILE)( - IN struct _FILE_OBJECT *FileObject); - -typedef VOID DDKAPI -(*PFAST_IO_DETACH_DEVICE)( - IN struct _DEVICE_OBJECT *SourceDevice, - IN struct _DEVICE_OBJECT *TargetDevice); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_QUERY_NETWORK_OPEN_INFO)( - IN struct _FILE_OBJECT *FileObject, - IN BOOLEAN Wait, - OUT struct _FILE_NETWORK_OPEN_INFORMATION *Buffer, - OUT struct _IO_STATUS_BLOCK *IoStatus, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef NTSTATUS DDKAPI -(*PFAST_IO_ACQUIRE_FOR_MOD_WRITE)( - IN struct _FILE_OBJECT *FileObject, - IN PLARGE_INTEGER EndingOffset, - OUT struct _ERESOURCE **ResourceToRelease, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_MDL_READ)( - IN struct _FILE_OBJECT *FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN ULONG LockKey, - OUT PMDL *MdlChain, - OUT PIO_STATUS_BLOCK IoStatus, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_MDL_READ_COMPLETE)( - IN struct _FILE_OBJECT *FileObject, - IN PMDL MdlChain, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_PREPARE_MDL_WRITE)( - IN struct _FILE_OBJECT *FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN ULONG LockKey, - OUT PMDL *MdlChain, - OUT PIO_STATUS_BLOCK IoStatus, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_MDL_WRITE_COMPLETE)( - IN struct _FILE_OBJECT *FileObject, - IN PLARGE_INTEGER FileOffset, - IN PMDL MdlChain, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_READ_COMPRESSED)( - IN struct _FILE_OBJECT *FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN ULONG LockKey, - OUT PVOID Buffer, - OUT PMDL *MdlChain, - OUT PIO_STATUS_BLOCK IoStatus, - OUT struct _COMPRESSED_DATA_INFO *CompressedDataInfo, - IN ULONG CompressedDataInfoLength, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_WRITE_COMPRESSED)( - IN struct _FILE_OBJECT *FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN ULONG LockKey, - IN PVOID Buffer, - OUT PMDL *MdlChain, - OUT PIO_STATUS_BLOCK IoStatus, - IN struct _COMPRESSED_DATA_INFO *CompressedDataInfo, - IN ULONG CompressedDataInfoLength, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_MDL_READ_COMPLETE_COMPRESSED)( - IN struct _FILE_OBJECT *FileObject, - IN PMDL MdlChain, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_MDL_WRITE_COMPLETE_COMPRESSED)( - IN struct _FILE_OBJECT *FileObject, - IN PLARGE_INTEGER FileOffset, - IN PMDL MdlChain, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef BOOLEAN DDKAPI -(*PFAST_IO_QUERY_OPEN)( - IN struct _IRP *Irp, - OUT PFILE_NETWORK_OPEN_INFORMATION NetworkInformation, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef NTSTATUS DDKAPI -(*PFAST_IO_RELEASE_FOR_MOD_WRITE)( - IN struct _FILE_OBJECT *FileObject, - IN struct _ERESOURCE *ResourceToRelease, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef NTSTATUS DDKAPI -(*PFAST_IO_ACQUIRE_FOR_CCFLUSH)( - IN struct _FILE_OBJECT *FileObject, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef NTSTATUS DDKAPI -(*PFAST_IO_RELEASE_FOR_CCFLUSH) ( - IN struct _FILE_OBJECT *FileObject, - IN struct _DEVICE_OBJECT *DeviceObject); - -typedef struct _FAST_IO_DISPATCH { - ULONG SizeOfFastIoDispatch; - PFAST_IO_CHECK_IF_POSSIBLE FastIoCheckIfPossible; - PFAST_IO_READ FastIoRead; - PFAST_IO_WRITE FastIoWrite; - PFAST_IO_QUERY_BASIC_INFO FastIoQueryBasicInfo; - PFAST_IO_QUERY_STANDARD_INFO FastIoQueryStandardInfo; - PFAST_IO_LOCK FastIoLock; - PFAST_IO_UNLOCK_SINGLE FastIoUnlockSingle; - PFAST_IO_UNLOCK_ALL FastIoUnlockAll; - PFAST_IO_UNLOCK_ALL_BY_KEY FastIoUnlockAllByKey; - PFAST_IO_DEVICE_CONTROL FastIoDeviceControl; - PFAST_IO_ACQUIRE_FILE AcquireFileForNtCreateSection; - PFAST_IO_RELEASE_FILE ReleaseFileForNtCreateSection; - PFAST_IO_DETACH_DEVICE FastIoDetachDevice; - PFAST_IO_QUERY_NETWORK_OPEN_INFO FastIoQueryNetworkOpenInfo; - PFAST_IO_ACQUIRE_FOR_MOD_WRITE AcquireForModWrite; - PFAST_IO_MDL_READ MdlRead; - PFAST_IO_MDL_READ_COMPLETE MdlReadComplete; - PFAST_IO_PREPARE_MDL_WRITE PrepareMdlWrite; - PFAST_IO_MDL_WRITE_COMPLETE MdlWriteComplete; - PFAST_IO_READ_COMPRESSED FastIoReadCompressed; - PFAST_IO_WRITE_COMPRESSED FastIoWriteCompressed; - PFAST_IO_MDL_READ_COMPLETE_COMPRESSED MdlReadCompleteCompressed; - PFAST_IO_MDL_WRITE_COMPLETE_COMPRESSED MdlWriteCompleteCompressed; - PFAST_IO_QUERY_OPEN FastIoQueryOpen; - PFAST_IO_RELEASE_FOR_MOD_WRITE ReleaseForModWrite; - PFAST_IO_ACQUIRE_FOR_CCFLUSH AcquireForCcFlush; - PFAST_IO_RELEASE_FOR_CCFLUSH ReleaseForCcFlush; -} FAST_IO_DISPATCH, *PFAST_IO_DISPATCH; - -/* NOTE: PVOID for methods to avoid 'assignment from incompatible pointer type' warning */ -typedef struct _DRIVER_OBJECT { - CSHORT Type; - CSHORT Size; - PDEVICE_OBJECT DeviceObject; - ULONG Flags; - PVOID DriverStart; - ULONG DriverSize; - PVOID DriverSection; - PDRIVER_EXTENSION DriverExtension; - UNICODE_STRING DriverName; - PUNICODE_STRING HardwareDatabase; - PVOID FastIoDispatch; - PVOID DriverInit; - PVOID DriverStartIo; - PVOID DriverUnload; - PVOID MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; -} DRIVER_OBJECT; -typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT; - -typedef struct _SECTION_OBJECT_POINTERS { - PVOID DataSectionObject; - PVOID SharedCacheMap; - PVOID ImageSectionObject; -} SECTION_OBJECT_POINTERS, *PSECTION_OBJECT_POINTERS; - -typedef struct _IO_COMPLETION_CONTEXT { - PVOID Port; - PVOID Key; -} IO_COMPLETION_CONTEXT, *PIO_COMPLETION_CONTEXT; - -/* FILE_OBJECT.Flags */ - -#define FO_FILE_OPEN 0x00000001 -#define FO_SYNCHRONOUS_IO 0x00000002 -#define FO_ALERTABLE_IO 0x00000004 -#define FO_NO_INTERMEDIATE_BUFFERING 0x00000008 -#define FO_WRITE_THROUGH 0x00000010 -#define FO_SEQUENTIAL_ONLY 0x00000020 -#define FO_CACHE_SUPPORTED 0x00000040 -#define FO_NAMED_PIPE 0x00000080 -#define FO_STREAM_FILE 0x00000100 -#define FO_MAILSLOT 0x00000200 -#define FO_GENERATE_AUDIT_ON_CLOSE 0x00000400 -#define FO_DIRECT_DEVICE_OPEN 0x00000800 -#define FO_FILE_MODIFIED 0x00001000 -#define FO_FILE_SIZE_CHANGED 0x00002000 -#define FO_CLEANUP_COMPLETE 0x00004000 -#define FO_TEMPORARY_FILE 0x00008000 -#define FO_DELETE_ON_CLOSE 0x00010000 -#define FO_OPENED_CASE_SENSITIVE 0x00020000 -#define FO_HANDLE_CREATED 0x00040000 -#define FO_FILE_FAST_IO_READ 0x00080000 -#define FO_RANDOM_ACCESS 0x00100000 -#define FO_FILE_OPEN_CANCELLED 0x00200000 -#define FO_VOLUME_OPEN 0x00400000 -#define FO_FILE_OBJECT_HAS_EXTENSION 0x00800000 -#define FO_REMOTE_ORIGIN 0x01000000 - -typedef struct _FILE_OBJECT { - CSHORT Type; - CSHORT Size; - PDEVICE_OBJECT DeviceObject; - PVPB Vpb; - PVOID FsContext; - PVOID FsContext2; - PSECTION_OBJECT_POINTERS SectionObjectPointer; - PVOID PrivateCacheMap; - NTSTATUS FinalStatus; - struct _FILE_OBJECT *RelatedFileObject; - BOOLEAN LockOperation; - BOOLEAN DeletePending; - BOOLEAN ReadAccess; - BOOLEAN WriteAccess; - BOOLEAN DeleteAccess; - BOOLEAN SharedRead; - BOOLEAN SharedWrite; - BOOLEAN SharedDelete; - ULONG Flags; - UNICODE_STRING FileName; - LARGE_INTEGER CurrentByteOffset; - ULONG Waiters; - ULONG Busy; - PVOID LastLock; - KEVENT Lock; - KEVENT Event; - PIO_COMPLETION_CONTEXT CompletionContext; -} FILE_OBJECT; -typedef struct _FILE_OBJECT *PFILE_OBJECT; - -typedef enum _SECURITY_OPERATION_CODE { - SetSecurityDescriptor, - QuerySecurityDescriptor, - DeleteSecurityDescriptor, - AssignSecurityDescriptor -} SECURITY_OPERATION_CODE, *PSECURITY_OPERATION_CODE; - -#define INITIAL_PRIVILEGE_COUNT 3 - -typedef struct _INITIAL_PRIVILEGE_SET { - ULONG PrivilegeCount; - ULONG Control; - LUID_AND_ATTRIBUTES Privilege[INITIAL_PRIVILEGE_COUNT]; -} INITIAL_PRIVILEGE_SET, * PINITIAL_PRIVILEGE_SET; - -typedef struct _SECURITY_SUBJECT_CONTEXT { - PACCESS_TOKEN ClientToken; - SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; - PACCESS_TOKEN PrimaryToken; - PVOID ProcessAuditId; -} SECURITY_SUBJECT_CONTEXT, *PSECURITY_SUBJECT_CONTEXT; - -typedef struct _ACCESS_STATE { - LUID OperationID; - BOOLEAN SecurityEvaluated; - BOOLEAN GenerateAudit; - BOOLEAN GenerateOnClose; - BOOLEAN PrivilegesAllocated; - ULONG Flags; - ACCESS_MASK RemainingDesiredAccess; - ACCESS_MASK PreviouslyGrantedAccess; - ACCESS_MASK OriginalDesiredAccess; - SECURITY_SUBJECT_CONTEXT SubjectSecurityContext; - PSECURITY_DESCRIPTOR SecurityDescriptor; - PVOID AuxData; - union { - INITIAL_PRIVILEGE_SET InitialPrivilegeSet; - PRIVILEGE_SET PrivilegeSet; - } Privileges; - - BOOLEAN AuditPrivileges; - UNICODE_STRING ObjectName; - UNICODE_STRING ObjectTypeName; -} ACCESS_STATE, *PACCESS_STATE; - -typedef struct _IO_SECURITY_CONTEXT { - PSECURITY_QUALITY_OF_SERVICE SecurityQos; - PACCESS_STATE AccessState; - ACCESS_MASK DesiredAccess; - ULONG FullCreateOptions; -} IO_SECURITY_CONTEXT, *PIO_SECURITY_CONTEXT; - -struct _IO_CSQ; - -typedef struct _IO_CSQ_IRP_CONTEXT { - ULONG Type; - struct _IRP *Irp; - struct _IO_CSQ *Csq; -} IO_CSQ_IRP_CONTEXT, *PIO_CSQ_IRP_CONTEXT; - -typedef VOID DDKAPI -(*PIO_CSQ_INSERT_IRP)( - IN struct _IO_CSQ *Csq, - IN PIRP Irp); - -typedef VOID DDKAPI -(*PIO_CSQ_REMOVE_IRP)( - IN struct _IO_CSQ *Csq, - IN PIRP Irp); - -typedef PIRP DDKAPI -(*PIO_CSQ_PEEK_NEXT_IRP)( - IN struct _IO_CSQ *Csq, - IN PIRP Irp, - IN PVOID PeekContext); - -typedef VOID DDKAPI -(*PIO_CSQ_ACQUIRE_LOCK)( - IN struct _IO_CSQ *Csq, - OUT PKIRQL Irql); - -typedef VOID DDKAPI -(*PIO_CSQ_RELEASE_LOCK)( - IN struct _IO_CSQ *Csq, - IN KIRQL Irql); - -typedef VOID DDKAPI -(*PIO_CSQ_COMPLETE_CANCELED_IRP)( - IN struct _IO_CSQ *Csq, - IN PIRP Irp); - -typedef struct _IO_CSQ { - ULONG Type; - PIO_CSQ_INSERT_IRP CsqInsertIrp; - PIO_CSQ_REMOVE_IRP CsqRemoveIrp; - PIO_CSQ_PEEK_NEXT_IRP CsqPeekNextIrp; - PIO_CSQ_ACQUIRE_LOCK CsqAcquireLock; - PIO_CSQ_RELEASE_LOCK CsqReleaseLock; - PIO_CSQ_COMPLETE_CANCELED_IRP CsqCompleteCanceledIrp; - PVOID ReservePointer; -} IO_CSQ, *PIO_CSQ; - -typedef struct _IO_STACK_LOCATION { - UCHAR MajorFunction; - UCHAR MinorFunction; - UCHAR Flags; - UCHAR Control; - union { - struct { - PIO_SECURITY_CONTEXT SecurityContext; - ULONG Options; - USHORT POINTER_ALIGNMENT FileAttributes; - USHORT ShareAccess; - ULONG POINTER_ALIGNMENT EaLength; - } Create; - struct { - ULONG Length; - ULONG POINTER_ALIGNMENT Key; - LARGE_INTEGER ByteOffset; - } Read; - struct { - ULONG Length; - ULONG POINTER_ALIGNMENT Key; - LARGE_INTEGER ByteOffset; - } Write; - struct { - ULONG Length; - FILE_INFORMATION_CLASS POINTER_ALIGNMENT FileInformationClass; - } QueryFile; - struct { - ULONG Length; - FILE_INFORMATION_CLASS POINTER_ALIGNMENT FileInformationClass; - PFILE_OBJECT FileObject; - union { - struct { - BOOLEAN ReplaceIfExists; - BOOLEAN AdvanceOnly; - }; - ULONG ClusterCount; - HANDLE DeleteHandle; - }; - } SetFile; - struct { - ULONG Length; - FS_INFORMATION_CLASS POINTER_ALIGNMENT FsInformationClass; - } QueryVolume; - struct { - ULONG OutputBufferLength; - ULONG POINTER_ALIGNMENT InputBufferLength; - ULONG POINTER_ALIGNMENT IoControlCode; - PVOID Type3InputBuffer; - } DeviceIoControl; - struct { - SECURITY_INFORMATION SecurityInformation; - ULONG POINTER_ALIGNMENT Length; - } QuerySecurity; - struct { - SECURITY_INFORMATION SecurityInformation; - PSECURITY_DESCRIPTOR SecurityDescriptor; - } SetSecurity; - struct { - PVPB Vpb; - PDEVICE_OBJECT DeviceObject; - } MountVolume; - struct { - PVPB Vpb; - PDEVICE_OBJECT DeviceObject; - } VerifyVolume; - struct { - struct _SCSI_REQUEST_BLOCK *Srb; - } Scsi; - struct { - DEVICE_RELATION_TYPE Type; - } QueryDeviceRelations; - struct { - CONST GUID *InterfaceType; - USHORT Size; - USHORT Version; - PINTERFACE Interface; - PVOID InterfaceSpecificData; - } QueryInterface; - struct { - PDEVICE_CAPABILITIES Capabilities; - } DeviceCapabilities; - struct { - PIO_RESOURCE_REQUIREMENTS_LIST IoResourceRequirementList; - } FilterResourceRequirements; - struct { - ULONG WhichSpace; - PVOID Buffer; - ULONG Offset; - ULONG POINTER_ALIGNMENT Length; - } ReadWriteConfig; - struct { - BOOLEAN Lock; - } SetLock; - struct { - BUS_QUERY_ID_TYPE IdType; - } QueryId; - struct { - DEVICE_TEXT_TYPE DeviceTextType; - LCID POINTER_ALIGNMENT LocaleId; - } QueryDeviceText; - struct { - BOOLEAN InPath; - BOOLEAN Reserved[3]; - DEVICE_USAGE_NOTIFICATION_TYPE POINTER_ALIGNMENT Type; - } UsageNotification; - struct { - SYSTEM_POWER_STATE PowerState; - } WaitWake; - struct { - PPOWER_SEQUENCE PowerSequence; - } PowerSequence; - struct { - ULONG SystemContext; - POWER_STATE_TYPE POINTER_ALIGNMENT Type; - POWER_STATE POINTER_ALIGNMENT State; - POWER_ACTION POINTER_ALIGNMENT ShutdownType; - } Power; - struct { - PCM_RESOURCE_LIST AllocatedResources; - PCM_RESOURCE_LIST AllocatedResourcesTranslated; - } StartDevice; - struct { - ULONG_PTR ProviderId; - PVOID DataPath; - ULONG BufferSize; - PVOID Buffer; - } WMI; - struct { - PVOID Argument1; - PVOID Argument2; - PVOID Argument3; - PVOID Argument4; - } Others; - } Parameters; - PDEVICE_OBJECT DeviceObject; - PFILE_OBJECT FileObject; - PIO_COMPLETION_ROUTINE CompletionRoutine; - PVOID Context; -} IO_STACK_LOCATION, *PIO_STACK_LOCATION; - -/* IO_STACK_LOCATION.Control */ - -#define SL_PENDING_RETURNED 0x01 -#define SL_INVOKE_ON_CANCEL 0x20 -#define SL_INVOKE_ON_SUCCESS 0x40 -#define SL_INVOKE_ON_ERROR 0x80 - -typedef enum _KEY_INFORMATION_CLASS { - KeyBasicInformation, - KeyNodeInformation, - KeyFullInformation, - KeyNameInformation, - KeyCachedInformation, - KeyFlagsInformation -} KEY_INFORMATION_CLASS; - -typedef struct _KEY_BASIC_INFORMATION { - LARGE_INTEGER LastWriteTime; - ULONG TitleIndex; - ULONG NameLength; - WCHAR Name[1]; -} KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION; - -typedef struct _KEY_FULL_INFORMATION { - LARGE_INTEGER LastWriteTime; - ULONG TitleIndex; - ULONG ClassOffset; - ULONG ClassLength; - ULONG SubKeys; - ULONG MaxNameLen; - ULONG MaxClassLen; - ULONG Values; - ULONG MaxValueNameLen; - ULONG MaxValueDataLen; - WCHAR Class[1]; -} KEY_FULL_INFORMATION, *PKEY_FULL_INFORMATION; - -typedef struct _KEY_NODE_INFORMATION { - LARGE_INTEGER LastWriteTime; - ULONG TitleIndex; - ULONG ClassOffset; - ULONG ClassLength; - ULONG NameLength; - WCHAR Name[1]; -} KEY_NODE_INFORMATION, *PKEY_NODE_INFORMATION; - -typedef struct _KEY_VALUE_BASIC_INFORMATION { - ULONG TitleIndex; - ULONG Type; - ULONG NameLength; - WCHAR Name[1]; -} KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION; - -typedef struct _KEY_VALUE_FULL_INFORMATION { - ULONG TitleIndex; - ULONG Type; - ULONG DataOffset; - ULONG DataLength; - ULONG NameLength; - WCHAR Name[1]; -} KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION; - -typedef struct _KEY_VALUE_PARTIAL_INFORMATION { - ULONG TitleIndex; - ULONG Type; - ULONG DataLength; - UCHAR Data[1]; -} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION; - -typedef struct _KEY_VALUE_PARTIAL_INFORMATION_ALIGN64 { - ULONG Type; - ULONG DataLength; - UCHAR Data[1]; -} KEY_VALUE_PARTIAL_INFORMATION_ALIGN64, *PKEY_VALUE_PARTIAL_INFORMATION_ALIGN64; - -typedef struct _KEY_VALUE_ENTRY { - PUNICODE_STRING ValueName; - ULONG DataLength; - ULONG DataOffset; - ULONG Type; -} KEY_VALUE_ENTRY, *PKEY_VALUE_ENTRY; - -typedef enum _KEY_VALUE_INFORMATION_CLASS { - KeyValueBasicInformation, - KeyValueFullInformation, - KeyValuePartialInformation, - KeyValueFullInformationAlign64, - KeyValuePartialInformationAlign64 -} KEY_VALUE_INFORMATION_CLASS; - -/* KEY_VALUE_Xxx.Type */ - -#define REG_NONE 0 -#define REG_SZ 1 -#define REG_EXPAND_SZ 2 -#define REG_BINARY 3 -#define REG_DWORD 4 -#define REG_DWORD_LITTLE_ENDIAN 4 -#define REG_DWORD_BIG_ENDIAN 5 -#define REG_LINK 6 -#define REG_MULTI_SZ 7 -#define REG_RESOURCE_LIST 8 -#define REG_FULL_RESOURCE_DESCRIPTOR 9 -#define REG_RESOURCE_REQUIREMENTS_LIST 10 -#define REG_QWORD 11 -#define REG_QWORD_LITTLE_ENDIAN 11 - -#define PCI_TYPE0_ADDRESSES 6 -#define PCI_TYPE1_ADDRESSES 2 -#define PCI_TYPE2_ADDRESSES 5 - -typedef struct _PCI_COMMON_CONFIG { - USHORT VendorID; - USHORT DeviceID; - USHORT Command; - USHORT Status; - UCHAR RevisionID; - UCHAR ProgIf; - UCHAR SubClass; - UCHAR BaseClass; - UCHAR CacheLineSize; - UCHAR LatencyTimer; - UCHAR HeaderType; - UCHAR BIST; - union { - struct _PCI_HEADER_TYPE_0 { - ULONG BaseAddresses[PCI_TYPE0_ADDRESSES]; - ULONG CIS; - USHORT SubVendorID; - USHORT SubSystemID; - ULONG ROMBaseAddress; - UCHAR CapabilitiesPtr; - UCHAR Reserved1[3]; - ULONG Reserved2; - UCHAR InterruptLine; - UCHAR InterruptPin; - UCHAR MinimumGrant; - UCHAR MaximumLatency; - } type0; - struct _PCI_HEADER_TYPE_1 { - ULONG BaseAddresses[PCI_TYPE1_ADDRESSES]; - UCHAR PrimaryBus; - UCHAR SecondaryBus; - UCHAR SubordinateBus; - UCHAR SecondaryLatency; - UCHAR IOBase; - UCHAR IOLimit; - USHORT SecondaryStatus; - USHORT MemoryBase; - USHORT MemoryLimit; - USHORT PrefetchBase; - USHORT PrefetchLimit; - ULONG PrefetchBaseUpper32; - ULONG PrefetchLimitUpper32; - USHORT IOBaseUpper16; - USHORT IOLimitUpper16; - UCHAR CapabilitiesPtr; - UCHAR Reserved1[3]; - ULONG ROMBaseAddress; - UCHAR InterruptLine; - UCHAR InterruptPin; - USHORT BridgeControl; - } type1; - struct _PCI_HEADER_TYPE_2 { - ULONG SocketRegistersBaseAddress; - UCHAR CapabilitiesPtr; - UCHAR Reserved; - USHORT SecondaryStatus; - UCHAR PrimaryBus; - UCHAR SecondaryBus; - UCHAR SubordinateBus; - UCHAR SecondaryLatency; - struct { - ULONG Base; - ULONG Limit; - } Range[PCI_TYPE2_ADDRESSES - 1]; - UCHAR InterruptLine; - UCHAR InterruptPin; - USHORT BridgeControl; - } type2; - } u; - UCHAR DeviceSpecific[192]; -} PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG; - -/* PCI_COMMON_CONFIG.Command */ - -#define PCI_ENABLE_IO_SPACE 0x0001 -#define PCI_ENABLE_MEMORY_SPACE 0x0002 -#define PCI_ENABLE_BUS_MASTER 0x0004 -#define PCI_ENABLE_SPECIAL_CYCLES 0x0008 -#define PCI_ENABLE_WRITE_AND_INVALIDATE 0x0010 -#define PCI_ENABLE_VGA_COMPATIBLE_PALETTE 0x0020 -#define PCI_ENABLE_PARITY 0x0040 -#define PCI_ENABLE_WAIT_CYCLE 0x0080 -#define PCI_ENABLE_SERR 0x0100 -#define PCI_ENABLE_FAST_BACK_TO_BACK 0x0200 - -/* PCI_COMMON_CONFIG.Status */ - -#define PCI_STATUS_CAPABILITIES_LIST 0x0010 -#define PCI_STATUS_66MHZ_CAPABLE 0x0020 -#define PCI_STATUS_UDF_SUPPORTED 0x0040 -#define PCI_STATUS_FAST_BACK_TO_BACK 0x0080 -#define PCI_STATUS_DATA_PARITY_DETECTED 0x0100 -#define PCI_STATUS_DEVSEL 0x0600 -#define PCI_STATUS_SIGNALED_TARGET_ABORT 0x0800 -#define PCI_STATUS_RECEIVED_TARGET_ABORT 0x1000 -#define PCI_STATUS_RECEIVED_MASTER_ABORT 0x2000 -#define PCI_STATUS_SIGNALED_SYSTEM_ERROR 0x4000 -#define PCI_STATUS_DETECTED_PARITY_ERROR 0x8000 - -/* PCI_COMMON_CONFIG.HeaderType */ - -#define PCI_MULTIFUNCTION 0x80 -#define PCI_DEVICE_TYPE 0x00 -#define PCI_BRIDGE_TYPE 0x01 -#define PCI_CARDBUS_BRIDGE_TYPE 0x02 - -#define PCI_CONFIGURATION_TYPE(PciData) \ - (((PPCI_COMMON_CONFIG) (PciData))->HeaderType & ~PCI_MULTIFUNCTION) - -#define PCI_MULTIFUNCTION_DEVICE(PciData) \ - ((((PPCI_COMMON_CONFIG) (PciData))->HeaderType & PCI_MULTIFUNCTION) != 0) - -typedef struct _PCI_SLOT_NUMBER { - union { - struct { - ULONG DeviceNumber : 5; - ULONG FunctionNumber : 3; - ULONG Reserved : 24; - } bits; - ULONG AsULONG; - } u; -} PCI_SLOT_NUMBER, *PPCI_SLOT_NUMBER; - -typedef enum _POOL_TYPE { - NonPagedPool, - PagedPool, - NonPagedPoolMustSucceed, - DontUseThisType, - NonPagedPoolCacheAligned, - PagedPoolCacheAligned, - NonPagedPoolCacheAlignedMustS, - MaxPoolType, - NonPagedPoolSession = 32, - PagedPoolSession, - NonPagedPoolMustSucceedSession, - DontUseThisTypeSession, - NonPagedPoolCacheAlignedSession, - PagedPoolCacheAlignedSession, - NonPagedPoolCacheAlignedMustSSession -} POOL_TYPE; - -typedef enum _EX_POOL_PRIORITY { - LowPoolPriority, - LowPoolPrioritySpecialPoolOverrun = 8, - LowPoolPrioritySpecialPoolUnderrun = 9, - NormalPoolPriority = 16, - NormalPoolPrioritySpecialPoolOverrun = 24, - NormalPoolPrioritySpecialPoolUnderrun = 25, - HighPoolPriority = 32, - HighPoolPrioritySpecialPoolOverrun = 40, - HighPoolPrioritySpecialPoolUnderrun = 41 -} EX_POOL_PRIORITY; - -/* PRIVILEGE_SET.Control */ - -#define PRIVILEGE_SET_ALL_NECESSARY 1 - -typedef struct _RTL_OSVERSIONINFOW { - ULONG dwOSVersionInfoSize; - ULONG dwMajorVersion; - ULONG dwMinorVersion; - ULONG dwBuildNumber; - ULONG dwPlatformId; - WCHAR szCSDVersion[128]; -} RTL_OSVERSIONINFOW, *PRTL_OSVERSIONINFOW; - -typedef struct _RTL_OSVERSIONINFOEXW { - ULONG dwOSVersionInfoSize; - ULONG dwMajorVersion; - ULONG dwMinorVersion; - ULONG dwBuildNumber; - ULONG dwPlatformId; - WCHAR szCSDVersion[128]; - USHORT wServicePackMajor; - USHORT wServicePackMinor; - USHORT wSuiteMask; - UCHAR wProductType; - UCHAR wReserved; -} RTL_OSVERSIONINFOEXW, *PRTL_OSVERSIONINFOEXW; - -NTOSAPI -ULONGLONG -DDKAPI -VerSetConditionMask( - IN ULONGLONG ConditionMask, - IN ULONG TypeMask, - IN UCHAR Condition); - -#define VER_SET_CONDITION(ConditionMask, TypeBitMask, ComparisonType) \ - ((ConditionMask) = VerSetConditionMask((ConditionMask), \ - (TypeBitMask), (ComparisonType))) - -/* RtlVerifyVersionInfo() TypeMask */ - -#define VER_MINORVERSION 0x0000001 -#define VER_MAJORVERSION 0x0000002 -#define VER_BUILDNUMBER 0x0000004 -#define VER_PLATFORMID 0x0000008 -#define VER_SERVICEPACKMINOR 0x0000010 -#define VER_SERVICEPACKMAJOR 0x0000020 -#define VER_SUITENAME 0x0000040 -#define VER_PRODUCT_TYPE 0x0000080 - -/* RtlVerifyVersionInfo() ComparisonType */ - -#define VER_EQUAL 1 -#define VER_GREATER 2 -#define VER_GREATER_EQUAL 3 -#define VER_LESS 4 -#define VER_LESS_EQUAL 5 -#define VER_AND 6 -#define VER_OR 7 - -#define VER_CONDITION_MASK 7 -#define VER_NUM_BITS_PER_CONDITION_MASK 3 - -typedef struct _RTL_BITMAP { - ULONG SizeOfBitMap; - PULONG Buffer; -} RTL_BITMAP, *PRTL_BITMAP; - -typedef struct _RTL_BITMAP_RUN { - ULONG StartingIndex; - ULONG NumberOfBits; -} RTL_BITMAP_RUN, *PRTL_BITMAP_RUN; - -typedef NTSTATUS DDKAPI -(*PRTL_QUERY_REGISTRY_ROUTINE)( - IN PWSTR ValueName, - IN ULONG ValueType, - IN PVOID ValueData, - IN ULONG ValueLength, - IN PVOID Context, - IN PVOID EntryContext); - -/* RTL_QUERY_REGISTRY_TABLE.Flags */ -#define RTL_QUERY_REGISTRY_SUBKEY 0x00000001 -#define RTL_QUERY_REGISTRY_TOPKEY 0x00000002 -#define RTL_QUERY_REGISTRY_REQUIRED 0x00000004 -#define RTL_QUERY_REGISTRY_NOVALUE 0x00000008 -#define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010 -#define RTL_QUERY_REGISTRY_DIRECT 0x00000020 -#define RTL_QUERY_REGISTRY_DELETE 0x00000040 - -typedef struct _RTL_QUERY_REGISTRY_TABLE { - PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine; - ULONG Flags; - PWSTR Name; - PVOID EntryContext; - ULONG DefaultType; - PVOID DefaultData; - ULONG DefaultLength; -} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE; - -typedef struct _TIME_FIELDS { - CSHORT Year; - CSHORT Month; - CSHORT Day; - CSHORT Hour; - CSHORT Minute; - CSHORT Second; - CSHORT Milliseconds; - CSHORT Weekday; -} TIME_FIELDS, *PTIME_FIELDS; - -typedef PVOID DDKAPI -(*PALLOCATE_FUNCTION)( - IN POOL_TYPE PoolType, - IN SIZE_T NumberOfBytes, - IN ULONG Tag); - -typedef VOID DDKAPI -(*PFREE_FUNCTION)( - IN PVOID Buffer); - -#define GENERAL_LOOKASIDE_S \ - SLIST_HEADER ListHead; \ - USHORT Depth; \ - USHORT MaximumDepth; \ - ULONG TotalAllocates; \ - union { \ - ULONG AllocateMisses; \ - ULONG AllocateHits; \ - }; \ - ULONG TotalFrees; \ - union { \ - ULONG FreeMisses; \ - ULONG FreeHits; \ - }; \ - POOL_TYPE Type; \ - ULONG Tag; \ - ULONG Size; \ - PALLOCATE_FUNCTION Allocate; \ - PFREE_FUNCTION Free; \ - LIST_ENTRY ListEntry; \ - ULONG LastTotalAllocates; \ - union { \ - ULONG LastAllocateMisses; \ - ULONG LastAllocateHits; \ - }; \ - ULONG Future[2]; - -typedef struct _GENERAL_LOOKASIDE { - GENERAL_LOOKASIDE_S; -} GENERAL_LOOKASIDE, *PGENERAL_LOOKASIDE; - -typedef struct _NPAGED_LOOKASIDE_LIST { - GENERAL_LOOKASIDE_S; - KSPIN_LOCK Obsoleted; -} NPAGED_LOOKASIDE_LIST, *PNPAGED_LOOKASIDE_LIST; - -typedef struct _PAGED_LOOKASIDE_LIST { - GENERAL_LOOKASIDE_S; - FAST_MUTEX Obsoleted; -} PAGED_LOOKASIDE_LIST, *PPAGED_LOOKASIDE_LIST; - -typedef struct _CALLBACK_OBJECT *PCALLBACK_OBJECT; - -typedef VOID DDKAPI (*PCALLBACK_FUNCTION)( - IN PVOID CallbackContext, - IN PVOID Argument1, - IN PVOID Argument2); - -typedef enum _EVENT_TYPE { - NotificationEvent, - SynchronizationEvent, -} EVENT_TYPE; - -typedef enum _KWAIT_REASON { - Executive, - FreePage, - PageIn, - PoolAllocation, - DelayExecution, - Suspended, - UserRequest, - WrExecutive, - WrFreePage, - WrPageIn, - WrPoolAllocation, - WrDelayExecution, - WrSuspended, - WrUserRequest, - WrEventPair, - WrQueue, - WrLpcReceive, - WrLpcReply, - WrVirtualMemory, - WrPageOut, - WrRendezvous, - Spare2, - Spare3, - Spare4, - Spare5, - Spare6, - WrKernel, - MaximumWaitReason -} KWAIT_REASON; - -typedef struct _KWAIT_BLOCK { - LIST_ENTRY WaitListEntry; - struct _KTHREAD * RESTRICTED_POINTER Thread; - PVOID Object; - struct _KWAIT_BLOCK * RESTRICTED_POINTER NextWaitBlock; - USHORT WaitKey; - USHORT WaitType; -} KWAIT_BLOCK, *PKWAIT_BLOCK, *RESTRICTED_POINTER PRKWAIT_BLOCK; - -typedef struct _IO_REMOVE_LOCK_TRACKING_BLOCK * PIO_REMOVE_LOCK_TRACKING_BLOCK; - -typedef struct _IO_REMOVE_LOCK_COMMON_BLOCK { - BOOLEAN Removed; - BOOLEAN Reserved[3]; - LONG IoCount; - KEVENT RemoveEvent; -} IO_REMOVE_LOCK_COMMON_BLOCK; - -typedef struct _IO_REMOVE_LOCK_DBG_BLOCK { - LONG Signature; - LONG HighWatermark; - LONGLONG MaxLockedTicks; - LONG AllocateTag; - LIST_ENTRY LockList; - KSPIN_LOCK Spin; - LONG LowMemoryCount; - ULONG Reserved1[4]; - PVOID Reserved2; - PIO_REMOVE_LOCK_TRACKING_BLOCK Blocks; -} IO_REMOVE_LOCK_DBG_BLOCK; - -typedef struct _IO_REMOVE_LOCK { - IO_REMOVE_LOCK_COMMON_BLOCK Common; -#if DBG - IO_REMOVE_LOCK_DBG_BLOCK Dbg; -#endif -} IO_REMOVE_LOCK, *PIO_REMOVE_LOCK; - -typedef struct _IO_WORKITEM *PIO_WORKITEM; - -typedef VOID DDKAPI -(*PIO_WORKITEM_ROUTINE)( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context); - -typedef struct _SHARE_ACCESS { - ULONG OpenCount; - ULONG Readers; - ULONG Writers; - ULONG Deleters; - ULONG SharedRead; - ULONG SharedWrite; - ULONG SharedDelete; -} SHARE_ACCESS, *PSHARE_ACCESS; - -typedef enum _KINTERRUPT_MODE { - LevelSensitive, - Latched -} KINTERRUPT_MODE; - -typedef VOID DDKAPI -(*PKINTERRUPT_ROUTINE)( - VOID); - -typedef enum _KPROFILE_SOURCE { - ProfileTime, - ProfileAlignmentFixup, - ProfileTotalIssues, - ProfilePipelineDry, - ProfileLoadInstructions, - ProfilePipelineFrozen, - ProfileBranchInstructions, - ProfileTotalNonissues, - ProfileDcacheMisses, - ProfileIcacheMisses, - ProfileCacheMisses, - ProfileBranchMispredictions, - ProfileStoreInstructions, - ProfileFpInstructions, - ProfileIntegerInstructions, - Profile2Issue, - Profile3Issue, - Profile4Issue, - ProfileSpecialInstructions, - ProfileTotalCycles, - ProfileIcacheIssues, - ProfileDcacheAccesses, - ProfileMemoryBarrierCycles, - ProfileLoadLinkedIssues, - ProfileMaximum -} KPROFILE_SOURCE; - -typedef enum _CREATE_FILE_TYPE { - CreateFileTypeNone, - CreateFileTypeNamedPipe, - CreateFileTypeMailslot -} CREATE_FILE_TYPE; - -typedef struct _CONFIGURATION_INFORMATION { - ULONG DiskCount; - ULONG FloppyCount; - ULONG CdRomCount; - ULONG TapeCount; - ULONG ScsiPortCount; - ULONG SerialCount; - ULONG ParallelCount; - BOOLEAN AtDiskPrimaryAddressClaimed; - BOOLEAN AtDiskSecondaryAddressClaimed; - ULONG Version; - ULONG MediumChangerCount; -} CONFIGURATION_INFORMATION, *PCONFIGURATION_INFORMATION; - -typedef enum _CONFIGURATION_TYPE { - ArcSystem, - CentralProcessor, - FloatingPointProcessor, - PrimaryIcache, - PrimaryDcache, - SecondaryIcache, - SecondaryDcache, - SecondaryCache, - EisaAdapter, - TcAdapter, - ScsiAdapter, - DtiAdapter, - MultiFunctionAdapter, - DiskController, - TapeController, - CdromController, - WormController, - SerialController, - NetworkController, - DisplayController, - ParallelController, - PointerController, - KeyboardController, - AudioController, - OtherController, - DiskPeripheral, - FloppyDiskPeripheral, - TapePeripheral, - ModemPeripheral, - MonitorPeripheral, - PrinterPeripheral, - PointerPeripheral, - KeyboardPeripheral, - TerminalPeripheral, - OtherPeripheral, - LinePeripheral, - NetworkPeripheral, - SystemMemory, - DockingInformation, - RealModeIrqRoutingTable, - MaximumType -} CONFIGURATION_TYPE, *PCONFIGURATION_TYPE; - -typedef NTSTATUS (*PIO_QUERY_DEVICE_ROUTINE)( - IN PVOID Context, - IN PUNICODE_STRING PathName, - IN INTERFACE_TYPE BusType, - IN ULONG BusNumber, - IN PKEY_VALUE_FULL_INFORMATION *BusInformation, - IN CONFIGURATION_TYPE ControllerType, - IN ULONG ControllerNumber, - IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation, - IN CONFIGURATION_TYPE PeripheralType, - IN ULONG PeripheralNumber, - IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation); - -typedef enum _WORK_QUEUE_TYPE { - CriticalWorkQueue, - DelayedWorkQueue, - HyperCriticalWorkQueue, - MaximumWorkQueue -} WORK_QUEUE_TYPE; - -typedef VOID DDKAPI -(*PWORKER_THREAD_ROUTINE)( - IN PVOID Parameter); - -typedef struct _WORK_QUEUE_ITEM { - LIST_ENTRY List; - PWORKER_THREAD_ROUTINE WorkerRoutine; - PVOID Parameter; -} WORK_QUEUE_ITEM, *PWORK_QUEUE_ITEM; - -typedef enum _KBUGCHECK_BUFFER_DUMP_STATE { - BufferEmpty, - BufferInserted, - BufferStarted, - BufferFinished, - BufferIncomplete -} KBUGCHECK_BUFFER_DUMP_STATE; - -typedef VOID DDKAPI -(*PKBUGCHECK_CALLBACK_ROUTINE)( - IN PVOID Buffer, - IN ULONG Length); - -typedef struct _KBUGCHECK_CALLBACK_RECORD { - LIST_ENTRY Entry; - PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine; - PVOID Buffer; - ULONG Length; - PUCHAR Component; - ULONG_PTR Checksum; - UCHAR State; -} KBUGCHECK_CALLBACK_RECORD, *PKBUGCHECK_CALLBACK_RECORD; - -/* - * VOID - * KeInitializeCallbackRecord( - * IN PKBUGCHECK_CALLBACK_RECORD CallbackRecord) - */ -#define KeInitializeCallbackRecord(CallbackRecord) \ - CallbackRecord->State = BufferEmpty; - -typedef enum _KDPC_IMPORTANCE { - LowImportance, - MediumImportance, - HighImportance -} KDPC_IMPORTANCE; - -typedef enum _MEMORY_CACHING_TYPE_ORIG { - MmFrameBufferCached = 2 -} MEMORY_CACHING_TYPE_ORIG; - -typedef enum _MEMORY_CACHING_TYPE { - MmNonCached = FALSE, - MmCached = TRUE, - MmWriteCombined = MmFrameBufferCached, - MmHardwareCoherentCached, - MmNonCachedUnordered, - MmUSWCCached, - MmMaximumCacheType -} MEMORY_CACHING_TYPE; - -typedef enum _MM_PAGE_PRIORITY { - LowPagePriority, - NormalPagePriority = 16, - HighPagePriority = 32 -} MM_PAGE_PRIORITY; - -typedef enum _LOCK_OPERATION { - IoReadAccess, - IoWriteAccess, - IoModifyAccess -} LOCK_OPERATION; - -typedef enum _MM_SYSTEM_SIZE { - MmSmallSystem, - MmMediumSystem, - MmLargeSystem -} MM_SYSTEM_SIZE; - -typedef struct _OBJECT_HANDLE_INFORMATION { - ULONG HandleAttributes; - ACCESS_MASK GrantedAccess; -} OBJECT_HANDLE_INFORMATION, *POBJECT_HANDLE_INFORMATION; - -typedef struct _CLIENT_ID { - HANDLE UniqueProcess; - HANDLE UniqueThread; -} CLIENT_ID, *PCLIENT_ID; - -typedef VOID DDKAPI -(*PKSTART_ROUTINE)( - IN PVOID StartContext); - -typedef VOID DDKAPI -(*PCREATE_PROCESS_NOTIFY_ROUTINE)( - IN HANDLE ParentId, - IN HANDLE ProcessId, - IN BOOLEAN Create); - -typedef VOID DDKAPI -(*PCREATE_THREAD_NOTIFY_ROUTINE)( - IN HANDLE ProcessId, - IN HANDLE ThreadId, - IN BOOLEAN Create); - -typedef struct _IMAGE_INFO { - union { - ULONG Properties; - struct { - ULONG ImageAddressingMode : 8; - ULONG SystemModeImage : 1; - ULONG ImageMappedToAllPids : 1; - ULONG Reserved : 22; - }; - }; - PVOID ImageBase; - ULONG ImageSelector; - SIZE_T ImageSize; - ULONG ImageSectionNumber; -} IMAGE_INFO, *PIMAGE_INFO; - -#define IMAGE_ADDRESSING_MODE_32BIT 3 - -typedef VOID DDKAPI -(*PLOAD_IMAGE_NOTIFY_ROUTINE)( - IN PUNICODE_STRING FullImageName, - IN HANDLE ProcessId, - IN PIMAGE_INFO ImageInfo); - -typedef enum _PROCESSINFOCLASS { - ProcessBasicInformation, - ProcessQuotaLimits, - ProcessIoCounters, - ProcessVmCounters, - ProcessTimes, - ProcessBasePriority, - ProcessRaisePriority, - ProcessDebugPort, - ProcessExceptionPort, - ProcessAccessToken, - ProcessLdtInformation, - ProcessLdtSize, - ProcessDefaultHardErrorMode, - ProcessIoPortHandlers, - ProcessPooledUsageAndLimits, - ProcessWorkingSetWatch, - ProcessUserModeIOPL, - ProcessEnableAlignmentFaultFixup, - ProcessPriorityClass, - ProcessWx86Information, - ProcessHandleCount, - ProcessAffinityMask, - ProcessPriorityBoost, - ProcessDeviceMap, - ProcessSessionInformation, - ProcessForegroundInformation, - ProcessWow64Information, - ProcessImageFileName, - ProcessLUIDDeviceMapsEnabled, - ProcessBreakOnTermination, - ProcessDebugObjectHandle, - ProcessDebugFlags, - ProcessHandleTracing, - MaxProcessInfoClass -} PROCESSINFOCLASS; - -typedef enum _THREADINFOCLASS { - ThreadBasicInformation, - ThreadTimes, - ThreadPriority, - ThreadBasePriority, - ThreadAffinityMask, - ThreadImpersonationToken, - ThreadDescriptorTableEntry, - ThreadEnableAlignmentFaultFixup, - ThreadEventPair_Reusable, - ThreadQuerySetWin32StartAddress, - ThreadZeroTlsCell, - ThreadPerformanceCount, - ThreadAmILastThread, - ThreadIdealProcessor, - ThreadPriorityBoost, - ThreadSetTlsArrayAddress, - ThreadIsIoPending, - ThreadHideFromDebugger, - ThreadBreakOnTermination, - MaxThreadInfoClass -} THREADINFOCLASS; - -#define ES_SYSTEM_REQUIRED 0x00000001 -#define ES_DISPLAY_REQUIRED 0x00000002 -#define ES_USER_PRESENT 0x00000004 -#define ES_CONTINUOUS 0x80000000 - -typedef ULONG EXECUTION_STATE; - -typedef VOID DDKAPI -(*PREQUEST_POWER_COMPLETE)( - IN PDEVICE_OBJECT DeviceObject, - IN UCHAR MinorFunction, - IN POWER_STATE PowerState, - IN PVOID Context, - IN PIO_STATUS_BLOCK IoStatus); - -typedef enum _TRACE_INFORMATION_CLASS { - TraceIdClass, - TraceHandleClass, - TraceEnableFlagsClass, - TraceEnableLevelClass, - GlobalLoggerHandleClass, - EventLoggerHandleClass, - AllLoggerHandlesClass, - TraceHandleByNameClass -} TRACE_INFORMATION_CLASS; - -typedef NTSTATUS DDKAPI -(*PEX_CALLBACK_FUNCTION)( - IN PVOID CallbackContext, - IN PVOID Argument1, - IN PVOID Argument2); - - - -/* -** Storage structures -*/ -typedef enum _PARTITION_STYLE { - PARTITION_STYLE_MBR, - PARTITION_STYLE_GPT -} PARTITION_STYLE; - -typedef struct _CREATE_DISK_MBR { - ULONG Signature; -} CREATE_DISK_MBR, *PCREATE_DISK_MBR; - -typedef struct _CREATE_DISK_GPT { - GUID DiskId; - ULONG MaxPartitionCount; -} CREATE_DISK_GPT, *PCREATE_DISK_GPT; - -typedef struct _CREATE_DISK { - PARTITION_STYLE PartitionStyle; - union { - CREATE_DISK_MBR Mbr; - CREATE_DISK_GPT Gpt; - }; -} CREATE_DISK, *PCREATE_DISK; - -typedef struct _DISK_SIGNATURE { - ULONG PartitionStyle; - union { - struct { - ULONG Signature; - ULONG CheckSum; - } Mbr; - struct { - GUID DiskId; - } Gpt; - }; -} DISK_SIGNATURE, *PDISK_SIGNATURE; - -typedef VOID DDKFASTAPI -(*PTIME_UPDATE_NOTIFY_ROUTINE)( - IN HANDLE ThreadId, - IN KPROCESSOR_MODE Mode); - -#define DBG_STATUS_CONTROL_C 1 -#define DBG_STATUS_SYSRQ 2 -#define DBG_STATUS_BUGCHECK_FIRST 3 -#define DBG_STATUS_BUGCHECK_SECOND 4 -#define DBG_STATUS_FATAL 5 -#define DBG_STATUS_DEBUG_CONTROL 6 -#define DBG_STATUS_WORKER 7 - -typedef struct _PHYSICAL_MEMORY_RANGE { - PHYSICAL_ADDRESS BaseAddress; - LARGE_INTEGER NumberOfBytes; -} PHYSICAL_MEMORY_RANGE, *PPHYSICAL_MEMORY_RANGE; - -typedef ULONG_PTR -(*PDRIVER_VERIFIER_THUNK_ROUTINE)( - IN PVOID Context); - -typedef struct _DRIVER_VERIFIER_THUNK_PAIRS { - PDRIVER_VERIFIER_THUNK_ROUTINE PristineRoutine; - PDRIVER_VERIFIER_THUNK_ROUTINE NewRoutine; -} DRIVER_VERIFIER_THUNK_PAIRS, *PDRIVER_VERIFIER_THUNK_PAIRS; - -#define DRIVER_VERIFIER_SPECIAL_POOLING 0x0001 -#define DRIVER_VERIFIER_FORCE_IRQL_CHECKING 0x0002 -#define DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES 0x0004 -#define DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS 0x0008 -#define DRIVER_VERIFIER_IO_CHECKING 0x0010 - -#define RTL_RANGE_LIST_ADD_IF_CONFLICT 0x00000001 -#define RTL_RANGE_LIST_ADD_SHARED 0x00000002 - -#define RTL_RANGE_LIST_SHARED_OK 0x00000001 -#define RTL_RANGE_LIST_NULL_CONFLICT_OK 0x00000002 - -#define RTL_RANGE_LIST_SHARED_OK 0x00000001 -#define RTL_RANGE_LIST_NULL_CONFLICT_OK 0x00000002 - -#define RTL_RANGE_LIST_MERGE_IF_CONFLICT RTL_RANGE_LIST_ADD_IF_CONFLICT - -typedef struct _RTL_RANGE { - ULONGLONG Start; - ULONGLONG End; - PVOID UserData; - PVOID Owner; - UCHAR Attributes; - UCHAR Flags; -} RTL_RANGE, *PRTL_RANGE; - -#define RTL_RANGE_SHARED 0x01 -#define RTL_RANGE_CONFLICT 0x02 - -typedef struct _RTL_RANGE_LIST { - LIST_ENTRY ListHead; - ULONG Flags; - ULONG Count; - ULONG Stamp; -} RTL_RANGE_LIST, *PRTL_RANGE_LIST; - -typedef struct _RANGE_LIST_ITERATOR { - PLIST_ENTRY RangeListHead; - PLIST_ENTRY MergedHead; - PVOID Current; - ULONG Stamp; -} RTL_RANGE_LIST_ITERATOR, *PRTL_RANGE_LIST_ITERATOR; - -typedef BOOLEAN -(*PRTL_CONFLICT_RANGE_CALLBACK)( - IN PVOID Context, - IN PRTL_RANGE Range); - -#define HASH_STRING_ALGORITHM_DEFAULT 0 -#define HASH_STRING_ALGORITHM_X65599 1 -#define HASH_STRING_ALGORITHM_INVALID 0xffffffff - -typedef enum _SUITE_TYPE { - SmallBusiness, - Enterprise, - BackOffice, - CommunicationServer, - TerminalServer, - SmallBusinessRestricted, - EmbeddedNT, - DataCenter, - SingleUserTS, - Personal, - Blade, - MaxSuiteType -} SUITE_TYPE; - -typedef VOID DDKAPI -(*PTIMER_APC_ROUTINE)( - IN PVOID TimerContext, - IN ULONG TimerLowValue, - IN LONG TimerHighValue); - - - -/* -** WMI structures -*/ - -typedef VOID DDKAPI -(*WMI_NOTIFICATION_CALLBACK)( - PVOID Wnode, - PVOID Context); - - -/* -** Architecture specific structures -*/ - -#ifdef _X86_ - -typedef ULONG PFN_NUMBER, *PPFN_NUMBER; - -#define PASSIVE_LEVEL 0 -#define LOW_LEVEL 0 -#define APC_LEVEL 1 -#define DISPATCH_LEVEL 2 -#define PROFILE_LEVEL 27 -#define CLOCK1_LEVEL 28 -#define CLOCK2_LEVEL 28 -#define IPI_LEVEL 29 -#define POWER_LEVEL 30 -#define HIGH_LEVEL 31 - -typedef struct _KPCR_TIB { - PVOID ExceptionList; /* 00 */ - PVOID StackBase; /* 04 */ - PVOID StackLimit; /* 08 */ - PVOID SubSystemTib; /* 0C */ - union { - PVOID FiberData; /* 10 */ - DWORD Version; /* 10 */ - }; - PVOID ArbitraryUserPointer; /* 14 */ -} KPCR_TIB, *PKPCR_TIB; /* 18 */ - -#define PCR_MINOR_VERSION 1 -#define PCR_MAJOR_VERSION 1 - -typedef struct _KPCR { - KPCR_TIB Tib; /* 00 */ - struct _KPCR *Self; /* 18 */ - struct _KPRCB *PCRCB; /* 1C */ - KIRQL Irql; /* 20 */ - ULONG IRR; /* 24 */ - ULONG IrrActive; /* 28 */ - ULONG IDR; /* 2C */ - PVOID KdVersionBlock; /* 30 */ PUSHORT IDT; /* 34 */ - PUSHORT GDT; /* 38 */ - struct _KTSS *TSS; /* 3C */ - USHORT MajorVersion; /* 40 */ - USHORT MinorVersion; /* 42 */ - KAFFINITY SetMember; /* 44 */ - ULONG StallScaleFactor; /* 48 */ - UCHAR DebugActive; /* 4C */ - UCHAR ProcessorNumber; /* 4D */ - UCHAR Reserved[2]; /* 4E */ -} KPCR, *PKPCR; /* 50 */ - -typedef struct _KFLOATING_SAVE { - ULONG ControlWord; - ULONG StatusWord; - ULONG ErrorOffset; - ULONG ErrorSelector; - ULONG DataOffset; - ULONG DataSelector; - ULONG Cr0NpxState; - ULONG Spare1; -} KFLOATING_SAVE, *PKFLOATING_SAVE; - -#define PAGE_SIZE 0x1000 -#define PAGE_SHIFT 12L - -extern NTOSAPI PVOID *MmHighestUserAddress; -extern NTOSAPI PVOID *MmSystemRangeStart; -extern NTOSAPI ULONG *MmUserProbeAddress; - -#define MM_HIGHEST_USER_ADDRESS *MmHighestUserAddress -#define MM_SYSTEM_RANGE_START *MmSystemRangeStart -#define MM_USER_PROBE_ADDRESS *MmUserProbeAddress -#define MM_LOWEST_USER_ADDRESS (PVOID)0x10000 -#define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0C00000 - -#define KI_USER_SHARED_DATA 0xffdf0000 -#define SharedUserData ((KUSER_SHARED_DATA * CONST) KI_USER_SHARED_DATA) - -#define EFLAG_SIGN 0x8000 -#define EFLAG_ZERO 0x4000 -#define EFLAG_SELECT (EFLAG_SIGN | EFLAG_ZERO) - -#define RESULT_NEGATIVE ((EFLAG_SIGN & ~EFLAG_ZERO) & EFLAG_SELECT) -#define RESULT_ZERO ((~EFLAG_SIGN & EFLAG_ZERO) & EFLAG_SELECT) -#define RESULT_POSITIVE ((~EFLAG_SIGN & ~EFLAG_ZERO) & EFLAG_SELECT) - -typedef enum _INTERLOCKED_RESULT { - ResultNegative = RESULT_NEGATIVE, - ResultZero = RESULT_ZERO, - ResultPositive = RESULT_POSITIVE -} INTERLOCKED_RESULT; - -NTOSAPI -KIRQL -DDKAPI -KeGetCurrentIrql( - VOID); - -/* - * ULONG - * KeGetCurrentProcessorNumber( - * VOID) - */ -#define KeGetCurrentProcessorNumber() \ - ((ULONG)KeGetCurrentKPCR()->ProcessorNumber) - -#if !defined(__INTERLOCKED_DECLARED) -#define __INTERLOCKED_DECLARED - -NTOSAPI -LONG -DDKFASTAPI -InterlockedIncrement( - IN PLONG VOLATILE Addend); - -NTOSAPI -LONG -DDKFASTAPI -InterlockedDecrement( - IN PLONG VOLATILE Addend); - -NTOSAPI -LONG -DDKFASTAPI -InterlockedCompareExchange( - IN OUT PLONG VOLATILE Destination, - IN LONG Exchange, - IN LONG Comparand); - -NTOSAPI -LONG -DDKFASTAPI -InterlockedExchange( - IN OUT PLONG VOLATILE Target, - IN LONG Value); - -NTOSAPI -LONG -DDKFASTAPI -InterlockedExchangeAdd( - IN OUT PLONG VOLATILE Addend, - IN LONG Value); - -/* - * PVOID - * InterlockedExchangePointer( - * IN OUT PVOID VOLATILE *Target, - * IN PVOID Value) - */ -#define InterlockedExchangePointer(Target, Value) \ - (PVOID) InterlockedExchange((PLONG) Target, (LONG) Value); - -/* - * PVOID - * InterlockedCompareExchangePointer( - * IN OUT PVOID *Destination, - * IN PVOID Exchange, - * IN PVOID Comparand) - */ -#define InterlockedCompareExchangePointer(Destination, Exchange, Comparand) \ - (PVOID) InterlockedCompareExchange((PLONG) Destination, (LONG) Exchange, (LONG) Comparand); - -#endif /* !__INTERLOCKED_DECLARED */ - -NTOSAPI -VOID -DDKFASTAPI -KefAcquireSpinLockAtDpcLevel( - IN PKSPIN_LOCK SpinLock); - -NTOSAPI -VOID -DDKFASTAPI -KefReleaseSpinLockFromDpcLevel( - IN PKSPIN_LOCK SpinLock); - -#define KeAcquireSpinLockAtDpcLevel(SpinLock) KefAcquireSpinLockAtDpcLevel(SpinLock) -#define KeReleaseSpinLockFromDpcLevel(SpinLock) KefReleaseSpinLockFromDpcLevel(SpinLock) - -#define RtlCopyMemoryNonTemporal RtlCopyMemory - -#define KeGetDcacheFillSize() 1L - -#endif /* _X86_ */ - - - -/* -** Utillity functions -*/ - -#define ARGUMENT_PRESENT(ArgumentPointer) \ - (BOOLEAN) ((PVOID)ArgumentPointer != (PVOID)NULL); - -/* - * ULONG - * BYTE_OFFSET( - * IN PVOID Va) - */ -#define BYTE_OFFSET(Va) \ - (ULONG) ((ULONG_PTR) (Va) & (PAGE_SIZE - 1)); - -/* - * ULONG - * BYTES_TO_PAGES( - * IN ULONG Size) - */ -#define BYTES_TO_PAGES(Size) \ - (ULONG) ((ULONG_PTR) (Size) >> PAGE_SHIFT) + (((ULONG) (Size) & (PAGE_SIZE - 1)) != 0); - -/* - * PCHAR - * CONTAINING_RECORD( - * IN PCHAR Address, - * IN TYPE Type, - * IN PCHAR Field); - */ -#ifndef CONTAINING_RECORD -#define CONTAINING_RECORD(Address, Type, Field) \ - ((Type *) (((ULONG_PTR) Address) - FIELD_OFFSET(Type, Field))) -#endif - -/* LONG - * FIELD_OFFSET( - * IN TYPE Type, - * IN PCHAR Field); - */ -#ifndef FIELD_OFFSET -#define FIELD_OFFSET(Type, Field) \ - ((LONG) (&(((Type *) 0)->Field))) -#endif - -/* - * PVOID - * PAGE_ALIGN( - * IN PVOID Va) - */ -#define PAGE_ALIGN(Va) \ - (PVOID) ((ULONG_PTR)(Va) & ~(PAGE_SIZE - 1)); - -/* - * ULONG_PTR - * ROUND_TO_PAGES( - * IN ULONG_PTR Size) - */ -#define ROUND_TO_PAGES(Size) \ - (ULONG_PTR) (((ULONG_PTR) Size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)); - -NTOSAPI -VOID -DDKAPI -RtlAssert( - IN PVOID FailedAssertion, - IN PVOID FileName, - IN ULONG LineNumber, - IN PCHAR Message); - -#if DBG - -#define ASSERT(exp) \ - ((!(exp)) ? \ - (RtlAssert( #exp, __FILE__, __LINE__, NULL ), FALSE) : TRUE) - -#define ASSERTMSG(msg, exp) \ - ((!(exp)) ? \ - (RtlAssert( #exp, __FILE__, __LINE__, msg ), FALSE) : TRUE) - -#define RTL_SOFT_ASSERT(exp) \ - ((!(_exp)) ? \ - (DbgPrint("%s(%d): Soft assertion failed\n Expression: %s\n", __FILE__, __LINE__, #exp), FALSE) : TRUE) - -#define RTL_SOFT_ASSERTMSG(msg, exp) \ - ((!(exp)) ? \ - (DbgPrint("%s(%d): Soft assertion failed\n Expression: %s\n Message: %s\n", __FILE__, __LINE__, #exp, (msg)), FALSE) : TRUE) - -#define RTL_VERIFY(exp) ASSERT(exp) -#define RTL_VERIFYMSG(msg, exp) ASSERT(msg, exp) - -#define RTL_SOFT_VERIFY(exp) RTL_SOFT_ASSERT(exp) -#define RTL_SOFT_VERIFYMSG(msg, exp) RTL_SOFT_ASSERTMSG(msg, exp) - -#else /* !DBG */ - -#define ASSERT(exp) ((VOID) 0) -#define ASSERTMSG(msg, exp) ((VOID) 0) - -#define RTL_SOFT_ASSERT(exp) ((VOID) 0) -#define RTL_SOFT_ASSERTMSG(msg, exp) ((VOID) 0) - -#define RTL_VERIFY(exp) ((exp) ? TRUE : FALSE) -#define RTL_VERIFYMSG(msg, exp) ((exp) ? TRUE : FALSE) - -#define RTL_SOFT_VERIFY(exp) ((exp) ? TRUE : FALSE) -#define RTL_SOFT_VERIFYMSG(msg, exp) ((exp) ? TRUE : FALSE) - -#endif /* DBG */ - -#define assert ASSERT - - -/* -** Driver support routines -*/ - -/** Runtime library routines **/ - -/* - * VOID - * InitializeListHead( - * IN PLIST_ENTRY ListHead) - */ -#define InitializeListHead(_ListHead) \ -{ \ - (_ListHead)->Flink = (_ListHead); \ - (_ListHead)->Blink = (_ListHead); \ -} - -/* - * VOID - * InsertHeadList( - * IN PLIST_ENTRY ListHead, - * IN PLIST_ENTRY Entry) - */ -#define InsertHeadList(_ListHead, \ - _Entry) \ -{ \ - PLIST_ENTRY _OldFlink; \ - _OldFlink = (_ListHead)->Flink; \ - (_Entry)->Flink = _OldFlink; \ - (_Entry)->Blink = (_ListHead); \ - _OldFlink->Blink = (_Entry); \ - (_ListHead)->Flink = (_Entry); \ -} - -/* - * VOID - * InsertTailList( - * IN PLIST_ENTRY ListHead, - * IN PLIST_ENTRY Entry) - */ -#define InsertTailList(_ListHead, \ - _Entry) \ -{ \ - PLIST_ENTRY _OldBlink; \ - _OldBlink = (_ListHead)->Blink; \ - (_Entry)->Flink = (_ListHead); \ - (_Entry)->Blink = _OldBlink; \ - _OldBlink->Flink = (_Entry); \ - (_ListHead)->Blink = (_Entry); \ -} - -/* - * BOOLEAN - * IsListEmpty( - * IN PLIST_ENTRY ListHead) - */ -#define IsListEmpty(_ListHead) \ - ((_ListHead)->Flink == (_ListHead)) - -static inline PSINGLE_LIST_ENTRY -PopEntryList( - IN PSINGLE_LIST_ENTRY ListHead) -{ - PSINGLE_LIST_ENTRY Entry; - - Entry = ListHead->Next; - if (Entry != NULL) - { - ListHead->Next = Entry->Next; - } - return Entry; -} - -/* - * VOID - * PushEntryList( - * IN PSINGLE_LIST_ENTRY ListHead, - * IN PSINGLE_LIST_ENTRY Entry) - */ -#define PushEntryList(_ListHead, \ - _Entry) \ -{ \ - (_Entry)->Next = (_ListHead)->Next; \ - (_ListHead)->Next = (_Entry); \ -} - -/* - * VOID - * RemoveEntryList( - * IN PLIST_ENTRY Entry) - */ -#define RemoveEntryList(_Entry) \ -{ \ - PLIST_ENTRY _OldFlink; \ - PLIST_ENTRY _OldBlink; \ - _OldFlink = (_Entry)->Flink; \ - _OldBlink = (_Entry)->Blink; \ - _OldFlink->Blink = _OldBlink; \ - _OldBlink->Flink = _OldFlink; \ - (_Entry)->Flink = NULL; \ - (_Entry)->Blink = NULL; \ -} - -static inline PLIST_ENTRY -RemoveHeadList( - IN PLIST_ENTRY ListHead) -{ - PLIST_ENTRY OldFlink; - PLIST_ENTRY OldBlink; - PLIST_ENTRY Entry; - - Entry = ListHead->Flink; - OldFlink = ListHead->Flink->Flink; - OldBlink = ListHead->Flink->Blink; - OldFlink->Blink = OldBlink; - OldBlink->Flink = OldFlink; - - if (Entry != ListHead) - { - Entry->Flink = NULL; - Entry->Blink = NULL; - } - - return Entry; -} - -static inline PLIST_ENTRY -RemoveTailList( - IN PLIST_ENTRY ListHead) -{ - PLIST_ENTRY OldFlink; - PLIST_ENTRY OldBlink; - PLIST_ENTRY Entry; - - Entry = ListHead->Blink; - OldFlink = ListHead->Blink->Flink; - OldBlink = ListHead->Blink->Blink; - OldFlink->Blink = OldBlink; - OldBlink->Flink = OldFlink; - - if (Entry != ListHead) - { - Entry->Flink = NULL; - Entry->Blink = NULL; - } - - return Entry; -} - -NTOSAPI -PSLIST_ENTRY -DDKFASTAPI -InterlockedPopEntrySList( - IN PSLIST_HEADER ListHead); - -NTOSAPI -PSLIST_ENTRY -DDKFASTAPI -InterlockedPushEntrySList( - IN PSLIST_HEADER ListHead, - IN PSLIST_ENTRY ListEntry); - -/* - * USHORT - * QueryDepthSList( - * IN PSLIST_HEADER SListHead) - */ -#define QueryDepthSList(_SListHead) \ - ((USHORT) ((_SListHead)->Alignment & 0xffff)) - -#define InterlockedFlushSList(ListHead) ExInterlockedFlushSList(ListHead) - -NTOSAPI -ULONG -DDKAPI -RtlAnsiStringToUnicodeSize( - IN PANSI_STRING AnsiString); - -NTOSAPI -NTSTATUS -DDKAPI -RtlAddRange( - IN OUT PRTL_RANGE_LIST RangeList, - IN ULONGLONG Start, - IN ULONGLONG End, - IN UCHAR Attributes, - IN ULONG Flags, - IN PVOID UserData OPTIONAL, - IN PVOID Owner OPTIONAL); - -NTOSAPI -NTSTATUS -DDKAPI -RtlAnsiStringToUnicodeString( - IN OUT PUNICODE_STRING DestinationString, - IN PANSI_STRING SourceString, - IN BOOLEAN AllocateDestinationString); - -NTOSAPI -NTSTATUS -DDKAPI -RtlAppendUnicodeStringToString( - IN OUT PUNICODE_STRING Destination, - IN PUNICODE_STRING Source); - -NTOSAPI -NTSTATUS -DDKAPI -RtlAppendUnicodeToString( - IN OUT PUNICODE_STRING Destination, - IN PCWSTR Source); - -NTOSAPI -BOOLEAN -DDKAPI -RtlAreBitsClear( - IN PRTL_BITMAP BitMapHeader, - IN ULONG StartingIndex, - IN ULONG Length); - -NTOSAPI -BOOLEAN -DDKAPI -RtlAreBitsSet( - IN PRTL_BITMAP BitMapHeader, - IN ULONG StartingIndex, - IN ULONG Length); - -NTOSAPI -NTSTATUS -DDKAPI -RtlCharToInteger( - IN PCSZ String, - IN ULONG Base OPTIONAL, - IN OUT PULONG Value); - -NTOSAPI -ULONG -DDKAPI -RtlCheckBit( - IN PRTL_BITMAP BitMapHeader, - IN ULONG BitPosition); - -NTOSAPI -NTSTATUS -DDKAPI -RtlCheckRegistryKey( - IN ULONG RelativeTo, - IN PWSTR Path); - -NTOSAPI -VOID -DDKAPI -RtlClearAllBits( - IN PRTL_BITMAP BitMapHeader); - -NTOSAPI -VOID -DDKAPI -RtlClearBit( - PRTL_BITMAP BitMapHeader, - ULONG BitNumber); - -NTOSAPI -VOID -DDKAPI -RtlClearBits( - IN PRTL_BITMAP BitMapHeader, - IN ULONG StartingIndex, - IN ULONG NumberToClear); - -NTOSAPI -SIZE_T -DDKAPI -RtlCompareMemory( - IN CONST VOID *Source1, - IN CONST VOID *Source2, - IN SIZE_T Length); - -NTOSAPI -LONG -DDKAPI -RtlCompareString( - IN PSTRING String1, - IN PSTRING String2, - BOOLEAN CaseInSensitive); - -NTOSAPI -LONG -DDKAPI -RtlCompareUnicodeString( - IN PUNICODE_STRING String1, - IN PUNICODE_STRING String2, - IN BOOLEAN CaseInSensitive); - -NTOSAPI -LARGE_INTEGER -DDKAPI -RtlConvertLongToLargeInteger( - IN LONG SignedInteger); - -NTOSAPI -LUID -DDKAPI -RtlConvertLongToLuid( - IN LONG Long); - -NTOSAPI -LARGE_INTEGER -DDKAPI -RtlConvertUlongToLargeInteger( - IN ULONG UnsignedInteger); - -NTOSAPI -LUID -DDKAPI -RtlConvertUlongToLuid( - ULONG Ulong); - -/* - * VOID - * RtlCopyMemory( - * IN VOID UNALIGNED *Destination, - * IN CONST VOID UNALIGNED *Source, - * IN SIZE_T Length) - */ -#ifndef RtlCopyMemory -#define RtlCopyMemory(Destination, Source, Length) \ - memcpy(Destination, Source, Length); -#endif - -#ifndef RtlCopyBytes -#define RtlCopyBytes RtlCopyMemory -#endif - -NTOSAPI -VOID -DDKAPI -RtlCopyMemory32( - IN VOID UNALIGNED *Destination, - IN CONST VOID UNALIGNED *Source, - IN ULONG Length); - -NTOSAPI -NTSTATUS -DDKAPI -RtlCopyRangeList( - OUT PRTL_RANGE_LIST CopyRangeList, - IN PRTL_RANGE_LIST RangeList); - -NTOSAPI -VOID -DDKAPI -RtlCopyString( - IN OUT PSTRING DestinationString, - IN PSTRING SourceString OPTIONAL); - -NTOSAPI -VOID -DDKAPI -RtlCopyUnicodeString( - IN OUT PUNICODE_STRING DestinationString, - IN PUNICODE_STRING SourceString); - -NTOSAPI -NTSTATUS -DDKAPI -RtlCreateRegistryKey( - IN ULONG RelativeTo, - IN PWSTR Path); - -NTOSAPI -NTSTATUS -DDKAPI -RtlCreateSecurityDescriptor( - IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, - IN ULONG Revision); - -NTOSAPI -NTSTATUS -DDKAPI -RtlDeleteOwnersRanges( - IN OUT PRTL_RANGE_LIST RangeList, - IN PVOID Owner); - -NTOSAPI -NTSTATUS -DDKAPI -RtlDeleteRange( - IN OUT PRTL_RANGE_LIST RangeList, - IN ULONGLONG Start, - IN ULONGLONG End, - IN PVOID Owner); - -NTOSAPI -NTSTATUS -DDKAPI -RtlDeleteRegistryValue( - IN ULONG RelativeTo, - IN PCWSTR Path, - IN PCWSTR ValueName); - -/* - * BOOLEAN - * RtlEqualLuid( - * IN LUID Luid1, - * IN LUID Luid2) - */ -#define RtlEqualLuid(_Luid1, \ - _Luid2) \ - ((Luid1.LowPart == Luid2.LowPart) && (Luid1.HighPart == Luid2.HighPart)) - -/* - * ULONG - * RtlEqualMemory( - * IN VOID UNALIGNED *Destination, - * IN CONST VOID UNALIGNED *Source, - * IN SIZE_T Length) - */ -#define RtlEqualMemory(Destination, Source, Length) (!memcmp(Destination, Source, Length)) - -NTOSAPI -BOOLEAN -DDKAPI -RtlEqualString( - IN PSTRING String1, - IN PSTRING String2, - IN BOOLEAN CaseInSensitive); - -NTOSAPI -BOOLEAN -DDKAPI -RtlEqualUnicodeString( - IN CONST UNICODE_STRING *String1, - IN CONST UNICODE_STRING *String2, - IN BOOLEAN CaseInSensitive); - -/* - * VOID - * RtlFillMemory( - * IN VOID UNALIGNED *Destination, - * IN SIZE_T Length, - * IN UCHAR Fill) - */ -#ifndef RtlFillMemory -#define RtlFillMemory(Destination, Length, Fill) \ - memset(Destination, Fill, Length); -#endif - -#ifndef RtlFillBytes -#define RtlFillBytes RtlFillMemory -#endif - -NTOSAPI -ULONG -DDKAPI -RtlFindClearBits( - IN PRTL_BITMAP BitMapHeader, - IN ULONG NumberToFind, - IN ULONG HintIndex); - -NTOSAPI -ULONG -DDKAPI -RtlFindClearBitsAndSet( - IN PRTL_BITMAP BitMapHeader, - IN ULONG NumberToFind, - IN ULONG HintIndex); - -NTOSAPI -ULONG -DDKAPI -RtlFindClearRuns( - IN PRTL_BITMAP BitMapHeader, - OUT PRTL_BITMAP_RUN RunArray, - IN ULONG SizeOfRunArray, - IN BOOLEAN LocateLongestRuns); - -NTOSAPI -ULONG -DDKAPI -RtlFindFirstRunClear( - IN PRTL_BITMAP BitMapHeader, - OUT PULONG StartingIndex); - -NTOSAPI -ULONG -DDKAPI -RtlFindLastBackwardRunClear( - IN PRTL_BITMAP BitMapHeader, - IN ULONG FromIndex, - OUT PULONG StartingRunIndex); - -NTOSAPI -CCHAR -DDKAPI -RtlFindLeastSignificantBit( - IN ULONGLONG Set); - -NTOSAPI -ULONG -DDKAPI -RtlFindLongestRunClear( - IN PRTL_BITMAP BitMapHeader, - OUT PULONG StartingIndex); - -NTOSAPI -CCHAR -DDKAPI -RtlFindMostSignificantBit( - IN ULONGLONG Set); - -NTOSAPI -ULONG -DDKAPI -RtlFindNextForwardRunClear( - IN PRTL_BITMAP BitMapHeader, - IN ULONG FromIndex, - OUT PULONG StartingRunIndex); - -NTOSAPI -NTSTATUS -DDKAPI -RtlFindRange( - IN PRTL_RANGE_LIST RangeList, - IN ULONGLONG Minimum, - IN ULONGLONG Maximum, - IN ULONG Length, - IN ULONG Alignment, - IN ULONG Flags, - IN UCHAR AttributeAvailableMask, - IN PVOID Context OPTIONAL, - IN PRTL_CONFLICT_RANGE_CALLBACK Callback OPTIONAL, - OUT PULONGLONG Start); - -NTOSAPI -ULONG -DDKAPI -RtlFindSetBits( - IN PRTL_BITMAP BitMapHeader, - IN ULONG NumberToFind, - IN ULONG HintIndex); - -NTOSAPI -ULONG -DDKAPI -RtlFindSetBitsAndClear( - IN PRTL_BITMAP BitMapHeader, - IN ULONG NumberToFind, - IN ULONG HintIndex); - -NTOSAPI -VOID -DDKAPI -RtlFreeAnsiString( - IN PANSI_STRING AnsiString); - -NTOSAPI -VOID -DDKAPI -RtlFreeRangeList( - IN PRTL_RANGE_LIST RangeList); - -NTOSAPI -VOID -DDKAPI -RtlFreeUnicodeString( - IN PUNICODE_STRING UnicodeString); - -NTOSAPI -VOID -DDKAPI -RtlGetCallersAddress( - OUT PVOID *CallersAddress, - OUT PVOID *CallersCaller); - -NTOSAPI -NTSTATUS -DDKAPI -RtlGetVersion( - IN OUT PRTL_OSVERSIONINFOW lpVersionInformation); - -NTOSAPI -NTSTATUS -DDKAPI -RtlGetFirstRange( - IN PRTL_RANGE_LIST RangeList, - OUT PRTL_RANGE_LIST_ITERATOR Iterator, - OUT PRTL_RANGE *Range); - -NTOSAPI -NTSTATUS -DDKAPI -RtlGetNextRange( - IN OUT PRTL_RANGE_LIST_ITERATOR Iterator, - OUT PRTL_RANGE *Range, - IN BOOLEAN MoveForwards); - -#define FOR_ALL_RANGES(RangeList, Iterator, Current) \ - for (RtlGetFirstRange((RangeList), (Iterator), &(Current)); \ - (Current) != NULL; \ - RtlGetNextRange((Iterator), &(Current), TRUE)) - -#define FOR_ALL_RANGES_BACKWARDS(RangeList, Iterator, Current) \ - for (RtlGetLastRange((RangeList), (Iterator), &(Current)); \ - (Current) != NULL; \ - RtlGetNextRange((Iterator), &(Current), FALSE)) - -NTOSAPI -NTSTATUS -DDKAPI -RtlGUIDFromString( - IN PUNICODE_STRING GuidString, - OUT GUID *Guid); - -NTOSAPI -NTSTATUS -DDKAPI -RtlHashUnicodeString( - IN CONST UNICODE_STRING *String, - IN BOOLEAN CaseInSensitive, - IN ULONG HashAlgorithm, - OUT PULONG HashValue); - -NTOSAPI -VOID -DDKAPI -RtlInitAnsiString( - IN OUT PANSI_STRING DestinationString, - IN PCSZ SourceString); - -NTOSAPI -VOID -DDKAPI -RtlInitializeBitMap( - IN PRTL_BITMAP BitMapHeader, - IN PULONG BitMapBuffer, - IN ULONG SizeOfBitMap); - -NTOSAPI -VOID -DDKAPI -RtlInitializeRangeList( - IN OUT PRTL_RANGE_LIST RangeList); - -NTOSAPI -VOID -DDKAPI -RtlInitString( - IN OUT PSTRING DestinationString, - IN PCSZ SourceString); - -NTOSAPI -VOID -DDKAPI -RtlInitUnicodeString( - IN OUT PUNICODE_STRING DestinationString, - IN PCWSTR SourceString); - -NTOSAPI -NTSTATUS -DDKAPI -RtlInt64ToUnicodeString( - IN ULONGLONG Value, - IN ULONG Base OPTIONAL, - IN OUT PUNICODE_STRING String); - -NTOSAPI -NTSTATUS -DDKAPI -RtlIntegerToUnicodeString( - IN ULONG Value, - IN ULONG Base OPTIONAL, - IN OUT PUNICODE_STRING String); - -NTOSAPI -NTSTATUS -DDKAPI -RtlIntPtrToUnicodeString( - PLONG Value, - ULONG Base OPTIONAL, - PUNICODE_STRING String); - -NTOSAPI -NTSTATUS -DDKAPI -RtlInvertRangeList( - OUT PRTL_RANGE_LIST InvertedRangeList, - IN PRTL_RANGE_LIST RangeList); - -NTOSAPI -NTSTATUS -DDKAPI -RtlIsRangeAvailable( - IN PRTL_RANGE_LIST RangeList, - IN ULONGLONG Start, - IN ULONGLONG End, - IN ULONG Flags, - IN UCHAR AttributeAvailableMask, - IN PVOID Context OPTIONAL, - IN PRTL_CONFLICT_RANGE_CALLBACK Callback OPTIONAL, - OUT PBOOLEAN Available); - -/* - * BOOLEAN - * RtlIsZeroLuid( - * IN PLUID L1) - */ -#define RtlIsZeroLuid(_L1) \ - ((BOOLEAN) ((!(_L1)->LowPart) && (!(_L1)->HighPart))) - -NTOSAPI -ULONG -DDKAPI -RtlLengthSecurityDescriptor( - IN PSECURITY_DESCRIPTOR SecurityDescriptor); - -NTOSAPI -VOID -DDKAPI -RtlMapGenericMask( - IN OUT PACCESS_MASK AccessMask, - IN PGENERIC_MAPPING GenericMapping); - -NTOSAPI -NTSTATUS -DDKAPI -RtlMergeRangeLists( - OUT PRTL_RANGE_LIST MergedRangeList, - IN PRTL_RANGE_LIST RangeList1, - IN PRTL_RANGE_LIST RangeList2, - IN ULONG Flags); - -/* - * VOID - * RtlMoveMemory( - * IN VOID UNALIGNED *Destination, - * IN CONST VOID UNALIGNED *Source, - * IN SIZE_T Length) - */ -#define RtlMoveMemory memmove - -NTOSAPI -ULONG -DDKAPI -RtlNumberOfClearBits( - IN PRTL_BITMAP BitMapHeader); - -NTOSAPI -ULONG -DDKAPI -RtlNumberOfSetBits( - IN PRTL_BITMAP BitMapHeader); - -NTOSAPI -VOID -DDKFASTAPI -RtlPrefetchMemoryNonTemporal( - IN PVOID Source, - IN SIZE_T Length); - -NTOSAPI -BOOLEAN -DDKAPI -RtlPrefixUnicodeString( - IN PUNICODE_STRING String1, - IN PUNICODE_STRING String2, - IN BOOLEAN CaseInSensitive); - -NTOSAPI -NTSTATUS -DDKAPI -RtlQueryRegistryValues( - IN ULONG RelativeTo, - IN PCWSTR Path, - IN PRTL_QUERY_REGISTRY_TABLE QueryTable, - IN PVOID Context, - IN PVOID Environment OPTIONAL); - -NTOSAPI -VOID -DDKAPI -RtlRetrieveUlong( - IN OUT PULONG DestinationAddress, - IN PULONG SourceAddress); - -NTOSAPI -VOID -DDKAPI -RtlRetrieveUshort( - IN OUT PUSHORT DestinationAddress, - IN PUSHORT SourceAddress); - -NTOSAPI -VOID -DDKAPI -RtlSetAllBits( - IN PRTL_BITMAP BitMapHeader); - -NTOSAPI -VOID -DDKAPI -RtlSetBit( - PRTL_BITMAP BitMapHeader, - ULONG BitNumber); - -NTOSAPI -VOID -DDKAPI -RtlSetBits( - IN PRTL_BITMAP BitMapHeader, - IN ULONG StartingIndex, - IN ULONG NumberToSet); - -NTOSAPI -NTSTATUS -DDKAPI -RtlSetDaclSecurityDescriptor( - IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, - IN BOOLEAN DaclPresent, - IN PACL Dacl OPTIONAL, - IN BOOLEAN DaclDefaulted OPTIONAL); - -NTOSAPI -VOID -DDKAPI -RtlStoreUlong( - IN PULONG Address, - IN ULONG Value); - -NTOSAPI -VOID -DDKAPI -RtlStoreUlonglong( - IN OUT PULONGLONG Address, - ULONGLONG Value); - -NTOSAPI -VOID -DDKAPI -RtlStoreUlongPtr( - IN OUT PULONG_PTR Address, - IN ULONG_PTR Value); - -NTOSAPI -VOID -DDKAPI -RtlStoreUshort( - IN PUSHORT Address, - IN USHORT Value); - -NTOSAPI -NTSTATUS -DDKAPI -RtlStringFromGUID( - IN REFGUID Guid, - OUT PUNICODE_STRING GuidString); - -NTOSAPI -BOOLEAN -DDKAPI -RtlTestBit( - IN PRTL_BITMAP BitMapHeader, - IN ULONG BitNumber); - -NTOSAPI -BOOLEAN -DDKAPI -RtlTimeFieldsToTime( - IN PTIME_FIELDS TimeFields, - IN PLARGE_INTEGER Time); - -NTOSAPI -VOID -DDKAPI -RtlTimeToTimeFields( - IN PLARGE_INTEGER Time, - IN PTIME_FIELDS TimeFields); - -NTOSAPI -ULONG -DDKFASTAPI -RtlUlongByteSwap( - IN ULONG Source); - -NTOSAPI -ULONGLONG -DDKFASTAPI -RtlUlonglongByteSwap( - IN ULONGLONG Source); - -NTOSAPI -ULONG -DDKAPI -RtlUnicodeStringToAnsiSize( - IN PUNICODE_STRING UnicodeString); - -NTOSAPI -NTSTATUS -DDKAPI -RtlUnicodeStringToAnsiString( - IN OUT PANSI_STRING DestinationString, - IN PUNICODE_STRING SourceString, - IN BOOLEAN AllocateDestinationString); - -NTOSAPI -NTSTATUS -DDKAPI -RtlUnicodeStringToInteger( - IN PUNICODE_STRING String, - IN ULONG Base OPTIONAL, - OUT PULONG Value); - -NTOSAPI -WCHAR -DDKAPI -RtlUpcaseUnicodeChar( - IN WCHAR SourceCharacter); - -NTOSAPI -NTSTATUS -DDKAPI -RtlUpcaseUnicodeString( - IN OUT PUNICODE_STRING DestinationString OPTIONAL, - IN PCUNICODE_STRING SourceString, - IN BOOLEAN AllocateDestinationString); - -NTOSAPI -CHAR -DDKAPI -RtlUpperChar( - IN CHAR Character); - -NTOSAPI -VOID -DDKAPI -RtlUpperString( - IN OUT PSTRING DestinationString, - IN PSTRING SourceString); - -NTOSAPI -USHORT -DDKFASTAPI -RtlUshortByteSwap( - IN USHORT Source); - -NTOSAPI -BOOLEAN -DDKAPI -RtlValidRelativeSecurityDescriptor( - IN PSECURITY_DESCRIPTOR SecurityDescriptorInput, - IN ULONG SecurityDescriptorLength, - IN SECURITY_INFORMATION RequiredInformation); - -NTOSAPI -BOOLEAN -DDKAPI -RtlValidSecurityDescriptor( - IN PSECURITY_DESCRIPTOR SecurityDescriptor); - -NTOSAPI -NTSTATUS -DDKAPI -RtlVerifyVersionInfo( - IN PRTL_OSVERSIONINFOEXW VersionInfo, - IN ULONG TypeMask, - IN ULONGLONG ConditionMask); - -NTOSAPI -NTSTATUS -DDKAPI -RtlVolumeDeviceToDosName( - IN PVOID VolumeDeviceObject, - OUT PUNICODE_STRING DosName); - -NTOSAPI -ULONG -DDKAPI -RtlWalkFrameChain( - OUT PVOID *Callers, - IN ULONG Count, - IN ULONG Flags); - -NTOSAPI -NTSTATUS -DDKAPI -RtlWriteRegistryValue( - IN ULONG RelativeTo, - IN PCWSTR Path, - IN PCWSTR ValueName, - IN ULONG ValueType, - IN PVOID ValueData, - IN ULONG ValueLength); - -NTOSAPI -ULONG -DDKAPI -RtlxUnicodeStringToAnsiSize( - IN PUNICODE_STRING UnicodeString); - -/* - * VOID - * RtlZeroMemory( - * IN VOID UNALIGNED *Destination, - * IN SIZE_T Length) - */ -#ifndef RtlZeroMemory -#define RtlZeroMemory(Destination, Length) \ - memset(Destination, 0, Length); -#endif - -#ifndef RtlZeroBytes -#define RtlZeroBytes RtlZeroMemory -#endif - - -/** Executive support routines **/ - -NTOSAPI -VOID -DDKFASTAPI -ExAcquireFastMutex( - IN PFAST_MUTEX FastMutex); - -NTOSAPI -VOID -DDKFASTAPI -ExAcquireFastMutexUnsafe( - IN PFAST_MUTEX FastMutex); - -NTOSAPI -BOOLEAN -DDKAPI -ExAcquireResourceExclusiveLite( - IN PERESOURCE Resource, - IN BOOLEAN Wait); - -NTOSAPI -BOOLEAN -DDKAPI -ExAcquireResourceSharedLite( - IN PERESOURCE Resource, - IN BOOLEAN Wait); - -NTOSAPI -BOOLEAN -DDKAPI -ExAcquireSharedStarveExclusive( - IN PERESOURCE Resource, - IN BOOLEAN Wait); - -NTOSAPI -BOOLEAN -DDKAPI -ExAcquireSharedWaitForExclusive( - IN PERESOURCE Resource, - IN BOOLEAN Wait); - -static inline PVOID -ExAllocateFromNPagedLookasideList( - IN PNPAGED_LOOKASIDE_LIST Lookaside) -{ - PVOID Entry; - - Lookaside->TotalAllocates++; - Entry = InterlockedPopEntrySList(&Lookaside->ListHead); - if (Entry == NULL) { - Lookaside->AllocateMisses++; - Entry = (Lookaside->Allocate)(Lookaside->Type, Lookaside->Size, Lookaside->Tag); - } - return Entry; -} - -static inline PVOID -ExAllocateFromPagedLookasideList( - IN PPAGED_LOOKASIDE_LIST Lookaside) -{ - PVOID Entry; - - Lookaside->TotalAllocates++; - Entry = InterlockedPopEntrySList(&Lookaside->ListHead); - if (Entry == NULL) { - Lookaside->AllocateMisses++; - Entry = (Lookaside->Allocate)(Lookaside->Type, - Lookaside->Size, Lookaside->Tag); - } - return Entry; -} - -NTOSAPI -PVOID -DDKAPI -ExAllocatePoolWithQuotaTag( - IN POOL_TYPE PoolType, - IN SIZE_T NumberOfBytes, - IN ULONG Tag); - -NTOSAPI -PVOID -DDKAPI -ExAllocatePoolWithTag( - IN POOL_TYPE PoolType, - IN SIZE_T NumberOfBytes, - IN ULONG Tag); - -#ifdef POOL_TAGGING - -#define ExAllocatePoolWithQuota(p,n) ExAllocatePoolWithQuotaTag(p,n,' kdD') -#define ExAllocatePool(p,n) ExAllocatePoolWithTag(p,n,' kdD') - -#else /* !POOL_TAGGING */ - -NTOSAPI -PVOID -DDKAPI -ExAllocatePool( - IN POOL_TYPE PoolType, - IN SIZE_T NumberOfBytes); - -NTOSAPI -PVOID -DDKAPI -ExAllocatePoolWithQuota( - IN POOL_TYPE PoolType, - IN SIZE_T NumberOfBytes); - -#endif /* POOL_TAGGING */ - -NTOSAPI -PVOID -DDKAPI -ExAllocatePoolWithTagPriority( - IN POOL_TYPE PoolType, - IN SIZE_T NumberOfBytes, - IN ULONG Tag, - IN EX_POOL_PRIORITY Priority); - -NTOSAPI -VOID -DDKAPI -ExConvertExclusiveToSharedLite( - IN PERESOURCE Resource); - -NTOSAPI -NTSTATUS -DDKAPI -ExCreateCallback( - OUT PCALLBACK_OBJECT *CallbackObject, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN BOOLEAN Create, - IN BOOLEAN AllowMultipleCallbacks); - -NTOSAPI -VOID -DDKAPI -ExDeleteNPagedLookasideList( - IN PNPAGED_LOOKASIDE_LIST Lookaside); - -NTOSAPI -VOID -DDKAPI -ExDeletePagedLookasideList( - IN PPAGED_LOOKASIDE_LIST Lookaside); - -NTOSAPI -NTSTATUS -DDKAPI -ExDeleteResourceLite( - IN PERESOURCE Resource); - -NTOSAPI -VOID -DDKAPI -ExFreePool( - IN PVOID P); - -#define PROTECTED_POOL 0x80000000 - -#ifdef POOL_TAGGING -#define ExFreePool(P) ExFreePoolWithTag(P, 0) -#endif - -NTOSAPI -VOID -DDKAPI -ExFreePoolWithTag( - IN PVOID P, - IN ULONG Tag); - -#define ExQueryDepthSList(ListHead) QueryDepthSList(ListHead) - -static inline VOID -ExFreeToNPagedLookasideList( - IN PNPAGED_LOOKASIDE_LIST Lookaside, - IN PVOID Entry) -{ - Lookaside->TotalFrees++; - if (ExQueryDepthSList(&Lookaside->ListHead) >= Lookaside->Depth) { - Lookaside->FreeMisses++; - (Lookaside->Free)(Entry); - } else { - InterlockedPushEntrySList(&Lookaside->ListHead, - (PSLIST_ENTRY)Entry); - } -} - -static inline VOID -ExFreeToPagedLookasideList( - IN PPAGED_LOOKASIDE_LIST Lookaside, - IN PVOID Entry) -{ - Lookaside->TotalFrees++; - if (ExQueryDepthSList(&Lookaside->ListHead) >= Lookaside->Depth) { - Lookaside->FreeMisses++; - (Lookaside->Free)(Entry); - } else { - InterlockedPushEntrySList(&Lookaside->ListHead, (PSLIST_ENTRY)Entry); - } -} - -/* - * ERESOURCE_THREAD - * ExGetCurrentResourceThread( - * VOID); - */ -#define ExGetCurrentResourceThread() ((ERESOURCE_THREAD) PsGetCurrentThread()) - -NTOSAPI -ULONG -DDKAPI -ExGetExclusiveWaiterCount( - IN PERESOURCE Resource); - -NTOSAPI -KPROCESSOR_MODE -DDKAPI -ExGetPreviousMode( - VOID); - -NTOSAPI -ULONG -DDKAPI -ExGetSharedWaiterCount( - IN PERESOURCE Resource); - -NTOSAPI -VOID -DDKAPI -KeInitializeEvent( - IN PRKEVENT Event, - IN EVENT_TYPE Type, - IN BOOLEAN State); - -/* - * VOID DDKAPI - * ExInitializeFastMutex( - * IN PFAST_MUTEX FastMutex) - */ -#define ExInitializeFastMutex(_FastMutex) \ -{ \ - (_FastMutex)->Count = 1; \ - (_FastMutex)->Owner = NULL; \ - (_FastMutex)->Contention = 0; \ - KeInitializeEvent(&(_FastMutex)->Event, SynchronizationEvent, FALSE); \ -} - -NTOSAPI -VOID -DDKAPI -ExInitializeNPagedLookasideList( - IN PNPAGED_LOOKASIDE_LIST Lookaside, - IN PALLOCATE_FUNCTION Allocate OPTIONAL, - IN PFREE_FUNCTION Free OPTIONAL, - IN ULONG Flags, - IN SIZE_T Size, - IN ULONG Tag, - IN USHORT Depth); - -NTOSAPI -VOID -DDKAPI -ExInitializePagedLookasideList( - IN PPAGED_LOOKASIDE_LIST Lookaside, - IN PALLOCATE_FUNCTION Allocate OPTIONAL, - IN PFREE_FUNCTION Free OPTIONAL, - IN ULONG Flags, - IN SIZE_T Size, - IN ULONG Tag, - IN USHORT Depth); - -NTOSAPI -NTSTATUS -DDKAPI -ExInitializeResourceLite( - IN PERESOURCE Resource); - -/* - * VOID - * InitializeSListHead( - * IN PSLIST_HEADER SListHead) - */ -#define InitializeSListHead(_SListHead) \ - (_SListHead)->Alignment = 0; - -#define ExInitializeSListHead InitializeSListHead - -NTOSAPI -LARGE_INTEGER -DDKAPI -ExInterlockedAddLargeInteger( - IN PLARGE_INTEGER Addend, - IN LARGE_INTEGER Increment, - IN PKSPIN_LOCK Lock); - -NTOSAPI -VOID -DDKFASTAPI -ExInterlockedAddLargeStatistic( - IN PLARGE_INTEGER Addend, - IN ULONG Increment); - -NTOSAPI -ULONG -DDKFASTAPI -ExInterlockedAddUlong( - IN PULONG Addend, - IN ULONG Increment, - PKSPIN_LOCK Lock); - -NTOSAPI -LONGLONG -DDKFASTAPI -ExInterlockedCompareExchange64( - IN OUT PLONGLONG Destination, - IN PLONGLONG Exchange, - IN PLONGLONG Comparand, - IN PKSPIN_LOCK Lock); - -NTOSAPI -PSINGLE_LIST_ENTRY -DDKFASTAPI -ExInterlockedFlushSList( - IN PSLIST_HEADER ListHead); - -NTOSAPI -PLIST_ENTRY -DDKFASTAPI -ExInterlockedInsertHeadList( - IN PLIST_ENTRY ListHead, - IN PLIST_ENTRY ListEntry, - IN PKSPIN_LOCK Lock); - -NTOSAPI -PLIST_ENTRY -DDKFASTAPI -ExInterlockedInsertTailList( - IN PLIST_ENTRY ListHead, - IN PLIST_ENTRY ListEntry, - IN PKSPIN_LOCK Lock); - -NTOSAPI -PSINGLE_LIST_ENTRY -DDKFASTAPI -ExInterlockedPopEntryList( - IN PSINGLE_LIST_ENTRY ListHead, - IN PKSPIN_LOCK Lock); - -/* - * PSINGLE_LIST_ENTRY - * ExInterlockedPopEntrySList( - * IN PSLIST_HEADER ListHead, - * IN PKSPIN_LOCK Lock) - */ -#define ExInterlockedPopEntrySList(_ListHead, \ - _Lock) \ - InterlockedPopEntrySList(_ListHead) - -NTOSAPI -PSINGLE_LIST_ENTRY -DDKFASTAPI -ExInterlockedPushEntryList( - IN PSINGLE_LIST_ENTRY ListHead, - IN PSINGLE_LIST_ENTRY ListEntry, - IN PKSPIN_LOCK Lock); - -/* - * PSINGLE_LIST_ENTRY FASTCALL - * ExInterlockedPushEntrySList( - * IN PSLIST_HEADER ListHead, - * IN PSINGLE_LIST_ENTRY ListEntry, - * IN PKSPIN_LOCK Lock) - */ -#define ExInterlockedPushEntrySList(_ListHead, \ - _ListEntry, \ - _Lock) \ - InterlockedPushEntrySList(_ListHead, _ListEntry) - -NTOSAPI -PLIST_ENTRY -DDKFASTAPI -ExInterlockedRemoveHeadList( - IN PLIST_ENTRY ListHead, - IN PKSPIN_LOCK Lock); - -NTOSAPI -BOOLEAN -DDKAPI -ExIsProcessorFeaturePresent( - IN ULONG ProcessorFeature); - -NTOSAPI -BOOLEAN -DDKAPI -ExIsResourceAcquiredExclusiveLite( - IN PERESOURCE Resource); - -NTOSAPI -USHORT -DDKAPI -ExIsResourceAcquiredLite( - IN PERESOURCE Resource); - -NTOSAPI -USHORT -DDKAPI -ExIsResourceAcquiredSharedLite( - IN PERESOURCE Resource); - -NTOSAPI -VOID -DDKAPI -ExLocalTimeToSystemTime( - IN PLARGE_INTEGER LocalTime, - OUT PLARGE_INTEGER SystemTime); - -NTOSAPI -VOID -DDKAPI -ExNotifyCallback( - IN PCALLBACK_OBJECT CallbackObject, - IN PVOID Argument1, - IN PVOID Argument2); - -NTOSAPI -VOID -DDKAPI -ExRaiseAccessViolation( - VOID); - -NTOSAPI -VOID -DDKAPI -ExRaiseDatatypeMisalignment( - VOID); - -NTOSAPI -VOID -DDKAPI -ExRaiseStatus( - IN NTSTATUS Status); - -NTOSAPI -PVOID -DDKAPI -ExRegisterCallback( - IN PCALLBACK_OBJECT CallbackObject, - IN PCALLBACK_FUNCTION CallbackFunction, - IN PVOID CallbackContext); - -NTOSAPI -VOID -DDKAPI -ExReinitializeResourceLite( - IN PERESOURCE Resource); - -NTOSAPI -VOID -DDKFASTAPI -ExReleaseFastMutex( - IN PFAST_MUTEX FastMutex); - -NTOSAPI -VOID -DDKFASTAPI -ExReleaseFastMutexUnsafe( - IN PFAST_MUTEX FastMutex); - -NTOSAPI -VOID -DDKAPI -ExReleaseResourceForThreadLite( - IN PERESOURCE Resource, - IN ERESOURCE_THREAD ResourceThreadId); - -NTOSAPI -VOID -DDKFASTAPI -ExReleaseResourceLite( - IN PERESOURCE Resource); - -NTOSAPI -VOID -DDKAPI -ExSetResourceOwnerPointer( - IN PERESOURCE Resource, - IN PVOID OwnerPointer); - -NTOSAPI -ULONG -DDKAPI -ExSetTimerResolution( - IN ULONG DesiredTime, - IN BOOLEAN SetResolution); - -NTOSAPI -VOID -DDKAPI -ExSystemTimeToLocalTime( - IN PLARGE_INTEGER SystemTime, - OUT PLARGE_INTEGER LocalTime); - -NTOSAPI -BOOLEAN -DDKFASTAPI -ExTryToAcquireFastMutex( - IN PFAST_MUTEX FastMutex); - -NTOSAPI -BOOLEAN -DDKAPI -ExTryToAcquireResourceExclusiveLite( - IN PERESOURCE Resource); - -NTOSAPI -VOID -DDKAPI -ExUnregisterCallback( - IN PVOID CbRegistration); - -NTOSAPI -NTSTATUS -DDKAPI -ExUuidCreate( - OUT UUID *Uuid); - -NTOSAPI -BOOLEAN -DDKAPI -ExVerifySuite( - IN SUITE_TYPE SuiteType); - -#if DBG - -#define PAGED_CODE() { \ - if (KeGetCurrentIrql() > APC_LEVEL) { \ - KdPrint( ("NTDDK: Pageable code called at IRQL > APC_LEVEL (%d)\n", KeGetCurrentIrql() )); \ - assert(FALSE); \ - } \ -} - -#else - -#define PAGED_CODE() - -#endif - -NTOSAPI -VOID -DDKAPI -ProbeForRead( - IN CONST VOID *Address, - IN ULONG Length, - IN ULONG Alignment); - -NTOSAPI -VOID -DDKAPI -ProbeForWrite( - IN CONST VOID *Address, - IN ULONG Length, - IN ULONG Alignment); - - - -/** Configuration manager routines **/ - -NTOSAPI -NTSTATUS -DDKAPI -CmRegisterCallback( - IN PEX_CALLBACK_FUNCTION Function, - IN PVOID Context, - IN OUT PLARGE_INTEGER Cookie); - -NTOSAPI -NTSTATUS -DDKAPI -CmUnRegisterCallback( - IN LARGE_INTEGER Cookie); - - - -/** Filesystem runtime library routines **/ - -NTOSAPI -BOOLEAN -DDKAPI -FsRtlIsTotalDeviceFailure( - IN NTSTATUS Status); - - - -/** Hardware abstraction layer routines **/ - -NTOSAPI -VOID -DDKFASTAPI -HalExamineMBR( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG SectorSize, - IN ULONG MBRTypeIdentifier, - OUT PVOID Buffer); - -NTOSAPI -VOID -DDKAPI -READ_PORT_BUFFER_UCHAR( - IN PUCHAR Port, - IN PUCHAR Buffer, - IN ULONG Count); - -NTOSAPI -VOID -DDKAPI -READ_PORT_BUFFER_ULONG( - IN PULONG Port, - IN PULONG Buffer, - IN ULONG Count); - -NTOSAPI -VOID -DDKAPI -READ_PORT_BUFFER_USHORT( - IN PUSHORT Port, - IN PUSHORT Buffer, - IN ULONG Count); - -NTOSAPI -UCHAR -DDKAPI -READ_PORT_UCHAR( - IN PUCHAR Port); - -NTOSAPI -ULONG -DDKAPI -READ_PORT_ULONG( - IN PULONG Port); - -NTOSAPI -USHORT -DDKAPI -READ_PORT_USHORT( - IN PUSHORT Port); - -NTOSAPI -VOID -DDKAPI -READ_REGISTER_BUFFER_UCHAR( - IN PUCHAR Register, - IN PUCHAR Buffer, - IN ULONG Count); - -NTOSAPI -VOID -DDKAPI -READ_REGISTER_BUFFER_ULONG( - IN PULONG Register, - IN PULONG Buffer, - IN ULONG Count); - -NTOSAPI -VOID -DDKAPI -READ_REGISTER_BUFFER_USHORT( - IN PUSHORT Register, - IN PUSHORT Buffer, - IN ULONG Count); - -NTOSAPI -UCHAR -DDKAPI -READ_REGISTER_UCHAR( - IN PUCHAR Register); - -NTOSAPI -ULONG -DDKAPI -READ_REGISTER_ULONG( - IN PULONG Register); - -NTOSAPI -USHORT -DDKAPI -READ_REGISTER_USHORT( - IN PUSHORT Register); - -NTOSAPI -VOID -DDKAPI -WRITE_PORT_BUFFER_UCHAR( - IN PUCHAR Port, - IN PUCHAR Buffer, - IN ULONG Count); - -NTOSAPI -VOID -DDKAPI -WRITE_PORT_BUFFER_ULONG( - IN PULONG Port, - IN PULONG Buffer, - IN ULONG Count); - -NTOSAPI -VOID -DDKAPI -WRITE_PORT_BUFFER_USHORT( - IN PUSHORT Port, - IN PUSHORT Buffer, - IN ULONG Count); - -NTOSAPI -VOID -DDKAPI -WRITE_PORT_UCHAR( - IN PUCHAR Port, - IN UCHAR Value); - -NTOSAPI -VOID -DDKAPI -WRITE_PORT_ULONG( - IN PULONG Port, - IN ULONG Value); - -NTOSAPI -VOID -DDKAPI -WRITE_PORT_USHORT( - IN PUSHORT Port, - IN USHORT Value); - -NTOSAPI -VOID -DDKAPI -WRITE_REGISTER_BUFFER_UCHAR( - IN PUCHAR Register, - IN PUCHAR Buffer, - IN ULONG Count); - -NTOSAPI -VOID -DDKAPI -WRITE_REGISTER_BUFFER_ULONG( - IN PULONG Register, - IN PULONG Buffer, - IN ULONG Count); - -NTOSAPI -VOID -DDKAPI -WRITE_REGISTER_BUFFER_USHORT( - IN PUSHORT Register, - IN PUSHORT Buffer, - IN ULONG Count); - -NTOSAPI -VOID -DDKAPI -WRITE_REGISTER_UCHAR( - IN PUCHAR Register, - IN UCHAR Value); - -NTOSAPI -VOID -DDKAPI -WRITE_REGISTER_ULONG( - IN PULONG Register, - IN ULONG Value); - -NTOSAPI -VOID -DDKAPI -WRITE_REGISTER_USHORT( - IN PUSHORT Register, - IN USHORT Value); - - - -/** I/O manager routines **/ - -NTOSAPI -VOID -DDKAPI -IoAcquireCancelSpinLock( - OUT PKIRQL Irql); - -NTOSAPI -NTSTATUS -DDKAPI -IoAcquireRemoveLockEx( - IN PIO_REMOVE_LOCK RemoveLock, - IN OPTIONAL PVOID Tag OPTIONAL, - IN PCSTR File, - IN ULONG Line, - IN ULONG RemlockSize); - -/* - * NTSTATUS - * IoAcquireRemoveLock( - * IN PIO_REMOVE_LOCK RemoveLock, - * IN OPTIONAL PVOID Tag) - */ -#define IoAcquireRemoveLock(_RemoveLock, \ - _Tag) \ - IoAcquireRemoveLockEx(_RemoveLock, _Tag, __FILE__, __LINE__, sizeof(IO_REMOVE_LOCK)); - -/* - * VOID - * IoAdjustPagingPathCount( - * IN PLONG Count, - * IN BOOLEAN Increment) - */ -#define IoAdjustPagingPathCount(_Count, \ - _Increment) \ -{ \ - if (_Increment) \ - { \ - InterlockedIncrement(_Count); \ - } \ - else \ - { \ - InterlockedDecrement(_Count); \ - } \ -} - -NTOSAPI -VOID -DDKAPI -IoAllocateController( - IN PCONTROLLER_OBJECT ControllerObject, - IN PDEVICE_OBJECT DeviceObject, - IN PDRIVER_CONTROL ExecutionRoutine, - IN PVOID Context); - -NTOSAPI -NTSTATUS -DDKAPI -IoAllocateDriverObjectExtension( - IN PDRIVER_OBJECT DriverObject, - IN PVOID ClientIdentificationAddress, - IN ULONG DriverObjectExtensionSize, - OUT PVOID *DriverObjectExtension); - -typedef struct _IO_ERROR_LOG_PACKET { - UCHAR MajorFunctionCode; - UCHAR RetryCount; - USHORT DumpDataSize; - USHORT NumberOfStrings; - USHORT StringOffset; - USHORT EventCategory; - NTSTATUS ErrorCode; - ULONG UniqueErrorValue; - NTSTATUS FinalStatus; - ULONG SequenceNumber; - ULONG IoControlCode; - LARGE_INTEGER DeviceOffset; - ULONG DumpData[1]; -} IO_ERROR_LOG_PACKET, *PIO_ERROR_LOG_PACKET; - -NTOSAPI -PVOID -DDKAPI -IoAllocateErrorLogEntry( - IN PVOID IoObject, - IN UCHAR EntrySize); - -NTOSAPI -PIRP -DDKAPI -IoAllocateIrp( - IN CCHAR StackSize, - IN BOOLEAN ChargeQuota); - -NTOSAPI -PMDL -DDKAPI -IoAllocateMdl( - IN PVOID VirtualAddress, - IN ULONG Length, - IN BOOLEAN SecondaryBuffer, - IN BOOLEAN ChargeQuota, - IN OUT PIRP Irp OPTIONAL); - -NTOSAPI -PIO_WORKITEM -DDKAPI -IoAllocateWorkItem( - IN PDEVICE_OBJECT DeviceObject); - -/* - * VOID IoAssignArcName( - * IN PUNICODE_STRING ArcName, - * IN PUNICODE_STRING DeviceName); - */ -#define IoAssignArcName(_ArcName, _DeviceName) ( \ - IoCreateSymbolicLink((_ArcName), (_DeviceName))) - -NTOSAPI -NTSTATUS -DDKAPI -IoAttachDevice( - IN PDEVICE_OBJECT SourceDevice, - IN PUNICODE_STRING TargetDevice, - OUT PDEVICE_OBJECT *AttachedDevice); - -NTOSAPI -PDEVICE_OBJECT -DDKAPI -IoAttachDeviceToDeviceStack( - IN PDEVICE_OBJECT SourceDevice, - IN PDEVICE_OBJECT TargetDevice); - -NTOSAPI -PIRP -DDKAPI -IoBuildAsynchronousFsdRequest( - IN ULONG MajorFunction, - IN PDEVICE_OBJECT DeviceObject, - IN OUT PVOID Buffer OPTIONAL, - IN ULONG Length OPTIONAL, - IN PLARGE_INTEGER StartingOffset OPTIONAL, - IN PIO_STATUS_BLOCK IoStatusBlock OPTIONAL); - -NTOSAPI -PIRP -DDKAPI -IoBuildDeviceIoControlRequest( - IN ULONG IoControlCode, - IN PDEVICE_OBJECT DeviceObject, - IN PVOID InputBuffer OPTIONAL, - IN ULONG InputBufferLength, - OUT PVOID OutputBuffer OPTIONAL, - IN ULONG OutputBufferLength, - IN BOOLEAN InternalDeviceIoControl, - IN PKEVENT Event, - OUT PIO_STATUS_BLOCK IoStatusBlock); - -NTOSAPI -VOID -DDKAPI -IoBuildPartialMdl( - IN PMDL SourceMdl, - IN OUT PMDL TargetMdl, - IN PVOID VirtualAddress, - IN ULONG Length); - -NTOSAPI -PIRP -DDKAPI -IoBuildSynchronousFsdRequest( - IN ULONG MajorFunction, - IN PDEVICE_OBJECT DeviceObject, - IN OUT PVOID Buffer OPTIONAL, - IN ULONG Length OPTIONAL, - IN PLARGE_INTEGER StartingOffset OPTIONAL, - IN PKEVENT Event, - OUT PIO_STATUS_BLOCK IoStatusBlock); - -NTOSAPI -NTSTATUS -DDKFASTAPI -IofCallDriver( - IN PDEVICE_OBJECT DeviceObject, - IN OUT PIRP Irp); - -/* - * NTSTATUS - * IoCallDriver( - * IN PDEVICE_OBJECT DeviceObject, - * IN OUT PIRP Irp) - */ -#define IoCallDriver IofCallDriver - -NTOSAPI -VOID -DDKAPI -IoCancelFileOpen( - IN PDEVICE_OBJECT DeviceObject, - IN PFILE_OBJECT FileObject); - -NTOSAPI -BOOLEAN -DDKAPI -IoCancelIrp( - IN PIRP Irp); - -NTOSAPI -NTSTATUS -DDKAPI -IoCheckShareAccess( - IN ACCESS_MASK DesiredAccess, - IN ULONG DesiredShareAccess, - IN OUT PFILE_OBJECT FileObject, - IN OUT PSHARE_ACCESS ShareAccess, - IN BOOLEAN Update); - -NTOSAPI -VOID -DDKFASTAPI -IofCompleteRequest( - IN PIRP Irp, - IN CCHAR PriorityBoost); - -/* - * VOID - * IoCompleteRequest( - * IN PIRP Irp, - * IN CCHAR PriorityBoost) - */ -#define IoCompleteRequest IofCompleteRequest - -NTOSAPI -NTSTATUS -DDKAPI -IoConnectInterrupt( - OUT PKINTERRUPT *InterruptObject, - IN PKSERVICE_ROUTINE ServiceRoutine, - IN PVOID ServiceContext, - IN PKSPIN_LOCK SpinLock OPTIONAL, - IN ULONG Vector, - IN KIRQL Irql, - IN KIRQL SynchronizeIrql, - IN KINTERRUPT_MODE InterruptMode, - IN BOOLEAN ShareVector, - IN KAFFINITY ProcessorEnableMask, - IN BOOLEAN FloatingSave); - -/* - * PIO_STACK_LOCATION - * IoGetCurrentIrpStackLocation( - * IN PIRP Irp) - */ -#define IoGetCurrentIrpStackLocation(_Irp) \ - ((_Irp)->Tail.Overlay.CurrentStackLocation) - -/* - * PIO_STACK_LOCATION - * IoGetNextIrpStackLocation( - * IN PIRP Irp) - */ -#define IoGetNextIrpStackLocation(_Irp) \ - ((_Irp)->Tail.Overlay.CurrentStackLocation - 1) - -/* - * VOID - * IoCopyCurrentIrpStackLocationToNext( - * IN PIRP Irp) - */ -#define IoCopyCurrentIrpStackLocationToNext(_Irp) \ -{ \ - PIO_STACK_LOCATION _IrpSp; \ - PIO_STACK_LOCATION _NextIrpSp; \ - _IrpSp = IoGetCurrentIrpStackLocation(_Irp); \ - _NextIrpSp = IoGetNextIrpStackLocation(_Irp); \ - RtlCopyMemory(_NextIrpSp, _IrpSp, \ - FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine)); \ - _NextIrpSp->Control = 0; \ -} - -NTOSAPI -PCONTROLLER_OBJECT -DDKAPI -IoCreateController( - IN ULONG Size); - -NTOSAPI -NTSTATUS -DDKAPI -IoCreateDevice( - IN PDRIVER_OBJECT DriverObject, - IN ULONG DeviceExtensionSize, - IN PUNICODE_STRING DeviceName OPTIONAL, - IN DEVICE_TYPE DeviceType, - IN ULONG DeviceCharacteristics, - IN BOOLEAN Exclusive, - OUT PDEVICE_OBJECT *DeviceObject); - -NTOSAPI -NTSTATUS -DDKAPI -IoCreateDisk( - IN PDEVICE_OBJECT DeviceObject, - IN PCREATE_DISK Disk); - -NTOSAPI -NTSTATUS -DDKAPI -IoCreateFile( - OUT PHANDLE FileHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN PLARGE_INTEGER AllocationSize OPTIONAL, - IN ULONG FileAttributes, - IN ULONG ShareAccess, - IN ULONG Disposition, - IN ULONG CreateOptions, - IN PVOID EaBuffer OPTIONAL, - IN ULONG EaLength, - IN CREATE_FILE_TYPE CreateFileType, - IN PVOID ExtraCreateParameters OPTIONAL, - IN ULONG Options); - -NTOSAPI -PKEVENT -DDKAPI -IoCreateNotificationEvent( - IN PUNICODE_STRING EventName, - OUT PHANDLE EventHandle); - -NTOSAPI -NTSTATUS -DDKAPI -IoCreateSymbolicLink( - IN PUNICODE_STRING SymbolicLinkName, - IN PUNICODE_STRING DeviceName); - -NTOSAPI -PKEVENT -DDKAPI -IoCreateSynchronizationEvent( - IN PUNICODE_STRING EventName, - OUT PHANDLE EventHandle); - -NTOSAPI -NTSTATUS -DDKAPI -IoCreateUnprotectedSymbolicLink( - IN PUNICODE_STRING SymbolicLinkName, - IN PUNICODE_STRING DeviceName); - -NTOSAPI -VOID -DDKAPI -IoCsqInitialize( - PIO_CSQ Csq, - IN PIO_CSQ_INSERT_IRP CsqInsertIrp, - IN PIO_CSQ_REMOVE_IRP CsqRemoveIrp, - IN PIO_CSQ_PEEK_NEXT_IRP CsqPeekNextIrp, - IN PIO_CSQ_ACQUIRE_LOCK CsqAcquireLock, - IN PIO_CSQ_RELEASE_LOCK CsqReleaseLock, - IN PIO_CSQ_COMPLETE_CANCELED_IRP CsqCompleteCanceledIrp); - -NTOSAPI -VOID -DDKAPI -IoCsqInsertIrp( - IN PIO_CSQ Csq, - IN PIRP Irp, - IN PIO_CSQ_IRP_CONTEXT Context); - -NTOSAPI -PIRP -DDKAPI -IoCsqRemoveIrp( - IN PIO_CSQ Csq, - IN PIO_CSQ_IRP_CONTEXT Context); - -NTOSAPI -PIRP -DDKAPI -IoCsqRemoveNextIrp( - IN PIO_CSQ Csq, - IN PVOID PeekContext); - -NTOSAPI -VOID -DDKAPI -IoDeleteController( - IN PCONTROLLER_OBJECT ControllerObject); - -NTOSAPI -VOID -DDKAPI -IoDeleteDevice( - IN PDEVICE_OBJECT DeviceObject); - -NTOSAPI -NTSTATUS -DDKAPI -IoDeleteSymbolicLink( - IN PUNICODE_STRING SymbolicLinkName); - -/* - * VOID - * IoDeassignArcName( - * IN PUNICODE_STRING ArcName) - */ -#define IoDeassignArcName IoDeleteSymbolicLink - -NTOSAPI -VOID -DDKAPI -IoDetachDevice( - IN OUT PDEVICE_OBJECT TargetDevice); - -NTOSAPI -VOID -DDKAPI -IoDisconnectInterrupt( - IN PKINTERRUPT InterruptObject); - -NTOSAPI -BOOLEAN -DDKAPI -IoForwardIrpSynchronously( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -#define IoForwardAndCatchIrp IoForwardIrpSynchronously - -NTOSAPI -VOID -DDKAPI -IoFreeController( - IN PCONTROLLER_OBJECT ControllerObject); - -NTOSAPI -VOID -DDKAPI -IoFreeErrorLogEntry( - PVOID ElEntry); - -NTOSAPI -VOID -DDKAPI -IoFreeIrp( - IN PIRP Irp); - -NTOSAPI -VOID -DDKAPI -IoFreeMdl( - IN PMDL Mdl); - -NTOSAPI -VOID -DDKAPI -IoFreeWorkItem( - IN PIO_WORKITEM pIOWorkItem); - -NTOSAPI -PDEVICE_OBJECT -DDKAPI -IoGetAttachedDevice( - IN PDEVICE_OBJECT DeviceObject); - -NTOSAPI -PDEVICE_OBJECT -DDKAPI -IoGetAttachedDeviceReference( - IN PDEVICE_OBJECT DeviceObject); - -NTOSAPI -NTSTATUS -DDKAPI -IoGetBootDiskInformation( - IN OUT PBOOTDISK_INFORMATION BootDiskInformation, - IN ULONG Size); - -NTOSAPI -PCONFIGURATION_INFORMATION -DDKAPI -IoGetConfigurationInformation( - VOID); - -NTOSAPI -PEPROCESS -DDKAPI -IoGetCurrentProcess( - VOID); - -NTOSAPI -NTSTATUS -DDKAPI -IoGetDeviceInterfaceAlias( - IN PUNICODE_STRING SymbolicLinkName, - IN CONST GUID *AliasInterfaceClassGuid, - OUT PUNICODE_STRING AliasSymbolicLinkName); - -NTOSAPI -NTSTATUS -DDKAPI -IoGetDeviceInterfaces( - IN CONST GUID *InterfaceClassGuid, - IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, - IN ULONG Flags, - OUT PWSTR *SymbolicLinkList); - -NTOSAPI -NTSTATUS -DDKAPI -IoGetDeviceObjectPointer( - IN PUNICODE_STRING ObjectName, - IN ACCESS_MASK DesiredAccess, - OUT PFILE_OBJECT *FileObject, - OUT PDEVICE_OBJECT *DeviceObject); - -NTOSAPI -NTSTATUS -DDKAPI -IoGetDeviceProperty( - IN PDEVICE_OBJECT DeviceObject, - IN DEVICE_REGISTRY_PROPERTY DeviceProperty, - IN ULONG BufferLength, - OUT PVOID PropertyBuffer, - OUT PULONG ResultLength); - -NTOSAPI -PDEVICE_OBJECT -DDKAPI -IoGetDeviceToVerify( - IN PETHREAD Thread); - -NTOSAPI -PDMA_ADAPTER -DDKAPI -IoGetDmaAdapter( - IN PDEVICE_OBJECT PhysicalDeviceObject, - IN PDEVICE_DESCRIPTION DeviceDescription, - IN OUT PULONG NumberOfMapRegisters); - -NTOSAPI -PVOID -DDKAPI -IoGetDriverObjectExtension( - IN PDRIVER_OBJECT DriverObject, - IN PVOID ClientIdentificationAddress); - -NTOSAPI -PGENERIC_MAPPING -DDKAPI -IoGetFileObjectGenericMapping( - VOID); - -/* - * ULONG - * IoGetFunctionCodeFromCtlCode( - * IN ULONG ControlCode) - */ -#define IoGetFunctionCodeFromCtlCode(_ControlCode) \ - (((_ControlCode) >> 2) & 0x00000FFF); - -NTOSAPI -PVOID -DDKAPI -IoGetInitialStack( - VOID); - -NTOSAPI -PDEVICE_OBJECT -DDKAPI -IoGetRelatedDeviceObject( - IN PFILE_OBJECT FileObject); - -NTOSAPI -ULONG -DDKAPI -IoGetRemainingStackSize( - VOID); - -NTOSAPI -VOID -DDKAPI -IoGetStackLimits( - OUT PULONG_PTR LowLimit, - OUT PULONG_PTR HighLimit); - -NTOSAPI -VOID -DDKAPI -KeInitializeDpc( - IN PRKDPC Dpc, - IN PKDEFERRED_ROUTINE DeferredRoutine, - IN PVOID DeferredContext); - -/* - * VOID - * IoInitializeDpcRequest( - * IN PDEVICE_OBJECT DeviceObject, - * IN PIO_DPC_ROUTINE DpcRoutine) - */ -#define IoInitializeDpcRequest(_DeviceObject, \ - _DpcRoutine) \ - KeInitializeDpc(&(_DeviceObject)->Dpc, \ - (PKDEFERRED_ROUTINE) (_DpcRoutine), \ - _DeviceObject); - -NTOSAPI -VOID -DDKAPI -IoInitializeIrp( - IN OUT PIRP Irp, - IN USHORT PacketSize, - IN CCHAR StackSize); - -NTOSAPI -VOID -DDKAPI -IoInitializeRemoveLockEx( - IN PIO_REMOVE_LOCK Lock, - IN ULONG AllocateTag, - IN ULONG MaxLockedMinutes, - IN ULONG HighWatermark, - IN ULONG RemlockSize); - -/* VOID - * IoInitializeRemoveLock( - * IN PIO_REMOVE_LOCK Lock, - * IN ULONG AllocateTag, - * IN ULONG MaxLockedMinutes, - * IN ULONG HighWatermark) - */ -#define IoInitializeRemoveLock( \ - Lock, AllocateTag, MaxLockedMinutes, HighWatermark) \ - IoInitializeRemoveLockEx(Lock, AllocateTag, MaxLockedMinutes, \ - HighWatermark, sizeof(IO_REMOVE_LOCK)); - -NTOSAPI -NTSTATUS -DDKAPI -IoInitializeTimer( - IN PDEVICE_OBJECT DeviceObject, - IN PIO_TIMER_ROUTINE TimerRoutine, - IN PVOID Context); - -NTOSAPI -VOID -DDKAPI -IoInvalidateDeviceRelations( - IN PDEVICE_OBJECT DeviceObject, - IN DEVICE_RELATION_TYPE Type); - -NTOSAPI -VOID -DDKAPI -IoInvalidateDeviceState( - IN PDEVICE_OBJECT PhysicalDeviceObject); - -NTOSAPI -BOOLEAN -DDKAPI -IoIs32bitProcess( - IN PIRP Irp OPTIONAL); - -/* - * BOOLEAN - * IoIsErrorUserInduced( - * IN NTSTATUS Status); - */ -#define IoIsErrorUserInduced(Status) \ - ((BOOLEAN)(((Status) == STATUS_DEVICE_NOT_READY) || \ - ((Status) == STATUS_IO_TIMEOUT) || \ - ((Status) == STATUS_MEDIA_WRITE_PROTECTED) || \ - ((Status) == STATUS_NO_MEDIA_IN_DEVICE) || \ - ((Status) == STATUS_VERIFY_REQUIRED) || \ - ((Status) == STATUS_UNRECOGNIZED_MEDIA) || \ - ((Status) == STATUS_WRONG_VOLUME))) - -NTOSAPI -BOOLEAN -DDKAPI -IoIsWdmVersionAvailable( - IN UCHAR MajorVersion, - IN UCHAR MinorVersion); - -NTOSAPI -PIRP -DDKAPI -IoMakeAssociatedIrp( - IN PIRP Irp, - IN CCHAR StackSize); - -/* - * VOID - * IoMarkIrpPending( - * IN OUT PIRP Irp) - */ -#define IoMarkIrpPending(_Irp) \ - (IoGetCurrentIrpStackLocation(_Irp)->Control |= SL_PENDING_RETURNED) - -NTOSAPI -NTSTATUS -DDKAPI -IoOpenDeviceInterfaceRegistryKey( - IN PUNICODE_STRING SymbolicLinkName, - IN ACCESS_MASK DesiredAccess, - OUT PHANDLE DeviceInterfaceKey); - -NTOSAPI -NTSTATUS -DDKAPI -IoOpenDeviceRegistryKey( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG DevInstKeyType, - IN ACCESS_MASK DesiredAccess, - OUT PHANDLE DevInstRegKey); - -NTOSAPI -NTSTATUS -DDKAPI -IoQueryDeviceDescription( - IN PINTERFACE_TYPE BusType OPTIONAL, - IN PULONG BusNumber OPTIONAL, - IN PCONFIGURATION_TYPE ControllerType OPTIONAL, - IN PULONG ControllerNumber OPTIONAL, - IN PCONFIGURATION_TYPE PeripheralType OPTIONAL, - IN PULONG PeripheralNumber OPTIONAL, - IN PIO_QUERY_DEVICE_ROUTINE CalloutRoutine, - IN PVOID Context); - -NTOSAPI -VOID -DDKAPI -IoQueueWorkItem( - IN PIO_WORKITEM pIOWorkItem, - IN PIO_WORKITEM_ROUTINE Routine, - IN WORK_QUEUE_TYPE QueueType, - IN PVOID Context); - -NTOSAPI -VOID -DDKAPI -IoRaiseHardError( - IN PIRP Irp, - IN PVPB Vpb OPTIONAL, - IN PDEVICE_OBJECT RealDeviceObject); - -NTOSAPI -BOOLEAN -DDKAPI -IoRaiseInformationalHardError( - IN NTSTATUS ErrorStatus, - IN PUNICODE_STRING String OPTIONAL, - IN PKTHREAD Thread OPTIONAL); - -NTOSAPI -NTSTATUS -DDKAPI -IoReadDiskSignature( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG BytesPerSector, - OUT PDISK_SIGNATURE Signature); - -NTOSAPI -NTSTATUS -DDKAPI -IoReadPartitionTableEx( - IN PDEVICE_OBJECT DeviceObject, - IN struct _DRIVE_LAYOUT_INFORMATION_EX **PartitionBuffer); - -NTOSAPI -VOID -DDKAPI -IoRegisterBootDriverReinitialization( - IN PDRIVER_OBJECT DriverObject, - IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, - IN PVOID Context); - -NTOSAPI -VOID -DDKAPI -IoRegisterBootDriverReinitialization( - IN PDRIVER_OBJECT DriverObject, - IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, - IN PVOID Context); - -NTOSAPI -NTSTATUS -DDKAPI -IoRegisterDeviceInterface( - IN PDEVICE_OBJECT PhysicalDeviceObject, - IN CONST GUID *InterfaceClassGuid, - IN PUNICODE_STRING ReferenceString OPTIONAL, - OUT PUNICODE_STRING SymbolicLinkName); - -NTOSAPI -VOID -DDKAPI -IoRegisterDriverReinitialization( - IN PDRIVER_OBJECT DriverObject, - IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, - IN PVOID Context); - -NTOSAPI -NTSTATUS -DDKAPI -IoRegisterPlugPlayNotification( - IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory, - IN ULONG EventCategoryFlags, - IN PVOID EventCategoryData OPTIONAL, - IN PDRIVER_OBJECT DriverObject, - IN PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine, - IN PVOID Context, - OUT PVOID *NotificationEntry); - -NTOSAPI -NTSTATUS -DDKAPI -IoRegisterShutdownNotification( - IN PDEVICE_OBJECT DeviceObject); - -NTOSAPI -VOID -DDKAPI -IoReleaseCancelSpinLock( - IN KIRQL Irql); - -NTOSAPI -VOID -DDKAPI -IoReleaseRemoveLockAndWaitEx( - IN PIO_REMOVE_LOCK RemoveLock, - IN PVOID Tag, - IN ULONG RemlockSize); - -NTOSAPI -VOID -DDKAPI -IoReleaseRemoveLockEx( - IN PIO_REMOVE_LOCK RemoveLock, - IN PVOID Tag, - IN ULONG RemlockSize); - -/* - * VOID - * IoReleaseRemoveLockAndWait( - * IN PIO_REMOVE_LOCK RemoveLock, - * IN PVOID Tag) - */ -#define IoReleaseRemoveLockAndWait(_RemoveLock, \ - _Tag) \ - IoReleaseRemoveLockEx(_RemoveLock, _Tag, sizeof(IO_REMOVE_LOCK)); - -NTOSAPI -VOID -DDKAPI -IoRemoveShareAccess( - IN PFILE_OBJECT FileObject, - IN OUT PSHARE_ACCESS ShareAccess); - -NTOSAPI -NTSTATUS -DDKAPI -IoReportDetectedDevice( - IN PDRIVER_OBJECT DriverObject, - IN INTERFACE_TYPE LegacyBusType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN PCM_RESOURCE_LIST ResourceList, - IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements OPTIONAL, - IN BOOLEAN ResourceAssigned, - IN OUT PDEVICE_OBJECT *DeviceObject); - -NTOSAPI -NTSTATUS -DDKAPI -IoReportResourceForDetection( - IN PDRIVER_OBJECT DriverObject, - IN PCM_RESOURCE_LIST DriverList OPTIONAL, - IN ULONG DriverListSize OPTIONAL, - IN PDEVICE_OBJECT DeviceObject OPTIONAL, - IN PCM_RESOURCE_LIST DeviceList OPTIONAL, - IN ULONG DeviceListSize OPTIONAL, - OUT PBOOLEAN ConflictDetected); - -NTOSAPI -NTSTATUS -DDKAPI -IoReportResourceUsage( - IN PUNICODE_STRING DriverClassName OPTIONAL, - IN PDRIVER_OBJECT DriverObject, - IN PCM_RESOURCE_LIST DriverList OPTIONAL, - IN ULONG DriverListSize OPTIONAL, - IN PDEVICE_OBJECT DeviceObject, - IN PCM_RESOURCE_LIST DeviceList OPTIONAL, - IN ULONG DeviceListSize OPTIONAL, - IN BOOLEAN OverrideConflict, - OUT PBOOLEAN ConflictDetected); - -NTOSAPI -NTSTATUS -DDKAPI -IoReportTargetDeviceChange( - IN PDEVICE_OBJECT PhysicalDeviceObject, - IN PVOID NotificationStructure); - -NTOSAPI -NTSTATUS -DDKAPI -IoReportTargetDeviceChangeAsynchronous( - IN PDEVICE_OBJECT PhysicalDeviceObject, - IN PVOID NotificationStructure, - IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL, - IN PVOID Context OPTIONAL); - -NTOSAPI -VOID -DDKAPI -IoRequestDeviceEject( - IN PDEVICE_OBJECT PhysicalDeviceObject); - -/* - * VOID - * IoRequestDpc( - * IN PDEVICE_OBJECT DeviceObject, - * IN PIRP Irp, - * IN PVOID Context); - */ -#define IoRequestDpc(DeviceObject, Irp, Context)( \ - KeInsertQueueDpc(&(DeviceObject)->Dpc, (Irp), (Context))) - -NTOSAPI -VOID -DDKAPI -IoReuseIrp( - IN OUT PIRP Irp, - IN NTSTATUS Status); - -/* - * PDRIVER_CANCEL - * IoSetCancelRoutine( - * IN PIRP Irp, - * IN PDRIVER_CANCEL CancelRoutine) - */ -#define IoSetCancelRoutine(_Irp, \ - _CancelRoutine) \ - (PDRIVER_CANCEL) InterlockedExchangePointer( \ - (PVOID *) &(_Irp)->CancelRoutine, (PVOID) (_CancelRoutine)); - -/* - * VOID - * IoSetCompletionRoutine( - * IN PIRP Irp, - * IN PIO_COMPLETION_ROUTINE CompletionRoutine, - * IN PVOID Context, - * IN BOOLEAN InvokeOnSuccess, - * IN BOOLEAN InvokeOnError, - * IN BOOLEAN InvokeOnCancel) - */ -#define IoSetCompletionRoutine(_Irp, \ - _CompletionRoutine, \ - _Context, \ - _InvokeOnSuccess, \ - _InvokeOnError, \ - _InvokeOnCancel) \ -{ \ - PIO_STACK_LOCATION _IrpSp; \ - assert(_InvokeOnSuccess || _InvokeOnError || _InvokeOnCancel ? \ - _CompletionRoutine != NULL : TRUE); \ - _IrpSp = IoGetNextIrpStackLocation(_Irp); \ - _IrpSp->CompletionRoutine = (_CompletionRoutine); \ - _IrpSp->Context = (_Context); \ - _IrpSp->Control = 0; \ - if (_InvokeOnSuccess) _IrpSp->Control = SL_INVOKE_ON_SUCCESS; \ - if (_InvokeOnError) _IrpSp->Control |= SL_INVOKE_ON_ERROR; \ - if (_InvokeOnCancel) _IrpSp->Control |= SL_INVOKE_ON_CANCEL; \ -} - -NTOSAPI -VOID -DDKAPI -IoSetCompletionRoutineEx( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PIO_COMPLETION_ROUTINE CompletionRoutine, - IN PVOID Context, - IN BOOLEAN InvokeOnSuccess, - IN BOOLEAN InvokeOnError, - IN BOOLEAN InvokeOnCancel); - -NTOSAPI -NTSTATUS -DDKAPI -IoSetDeviceInterfaceState( - IN PUNICODE_STRING SymbolicLinkName, - IN BOOLEAN Enable); - -NTOSAPI -VOID -DDKAPI -IoSetHardErrorOrVerifyDevice( - IN PIRP Irp, - IN PDEVICE_OBJECT DeviceObject); - -/* - * VOID - * IoSetNextIrpStackLocation( - * IN OUT PIRP Irp) - */ -#define IoSetNextIrpStackLocation(_Irp) \ -{ \ - (_Irp)->CurrentLocation--; \ - (_Irp)->Tail.Overlay.CurrentStackLocation--; \ -} - -NTOSAPI -NTSTATUS -DDKAPI -IoSetPartitionInformationEx( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG PartitionNumber, - IN struct _SET_PARTITION_INFORMATION_EX *PartitionInfo); - -NTOSAPI -VOID -DDKAPI -IoSetShareAccess( - IN ACCESS_MASK DesiredAccess, - IN ULONG DesiredShareAccess, - IN OUT PFILE_OBJECT FileObject, - OUT PSHARE_ACCESS ShareAccess); - -NTOSAPI -VOID -DDKAPI -IoSetStartIoAttributes( - IN PDEVICE_OBJECT DeviceObject, - IN BOOLEAN DeferredStartIo, - IN BOOLEAN NonCancelable); - -NTOSAPI -NTSTATUS -DDKAPI -IoSetSystemPartition( - IN PUNICODE_STRING VolumeNameString); - -NTOSAPI -BOOLEAN -DDKAPI -IoSetThreadHardErrorMode( - IN BOOLEAN EnableHardErrors); - -/* - * USHORT - * IoSizeOfIrp( - * IN CCHAR StackSize) - */ -#define IoSizeOfIrp(_StackSize) \ - ((USHORT) (sizeof(IRP) + ((_StackSize) * (sizeof(IO_STACK_LOCATION))))) - -/* - * VOID - * IoSkipCurrentIrpStackLocation( - * IN PIRP Irp) - */ -#define IoSkipCurrentIrpStackLocation(_Irp) \ -{ \ - (_Irp)->CurrentLocation++; \ - (_Irp)->Tail.Overlay.CurrentStackLocation++; \ -} - -NTOSAPI -VOID -DDKAPI -IoStartNextPacket( - IN PDEVICE_OBJECT DeviceObject, - IN BOOLEAN Cancelable); - -NTOSAPI -VOID -DDKAPI -IoStartNextPacketByKey( - IN PDEVICE_OBJECT DeviceObject, - IN BOOLEAN Cancelable, - IN ULONG Key); - -NTOSAPI -VOID -DDKAPI -IoStartPacket( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PULONG Key OPTIONAL, - IN PDRIVER_CANCEL CancelFunction OPTIONAL); - -NTOSAPI -VOID -DDKAPI -IoStartTimer( - IN PDEVICE_OBJECT DeviceObject); - -NTOSAPI -VOID -DDKAPI -IoStopTimer( - IN PDEVICE_OBJECT DeviceObject); - -NTOSAPI -NTSTATUS -DDKAPI -IoUnregisterPlugPlayNotification( - IN PVOID NotificationEntry); - -NTOSAPI -VOID -DDKAPI -IoUnregisterShutdownNotification( - IN PDEVICE_OBJECT DeviceObject); - -NTOSAPI -VOID -DDKAPI -IoUpdateShareAccess( - IN PFILE_OBJECT FileObject, - IN OUT PSHARE_ACCESS ShareAccess); - -NTOSAPI -NTSTATUS -DDKAPI -IoVerifyPartitionTable( - IN PDEVICE_OBJECT DeviceObject, - IN BOOLEAN FixErrors); - -NTOSAPI -NTSTATUS -DDKAPI -IoVolumeDeviceToDosName( - IN PVOID VolumeDeviceObject, - OUT PUNICODE_STRING DosName); - -NTOSAPI -NTSTATUS -DDKAPI -IoWMIAllocateInstanceIds( - IN GUID *Guid, - IN ULONG InstanceCount, - OUT ULONG *FirstInstanceId); - -NTOSAPI -ULONG -DDKAPI -IoWMIDeviceObjectToProviderId( - IN PDEVICE_OBJECT DeviceObject); - -NTOSAPI -NTSTATUS -DDKAPI -IoWMIDeviceObjectToInstanceName( - IN PVOID DataBlockObject, - IN PDEVICE_OBJECT DeviceObject, - OUT PUNICODE_STRING InstanceName); - -NTOSAPI -NTSTATUS -DDKAPI -IoWMIExecuteMethod( - IN PVOID DataBlockObject, - IN PUNICODE_STRING InstanceName, - IN ULONG MethodId, - IN ULONG InBufferSize, - IN OUT PULONG OutBufferSize, - IN OUT PUCHAR InOutBuffer); - -NTOSAPI -NTSTATUS -DDKAPI -IoWMIHandleToInstanceName( - IN PVOID DataBlockObject, - IN HANDLE FileHandle, - OUT PUNICODE_STRING InstanceName); - -NTOSAPI -NTSTATUS -DDKAPI -IoWMIOpenBlock( - IN GUID *DataBlockGuid, - IN ULONG DesiredAccess, - OUT PVOID *DataBlockObject); - -NTOSAPI -NTSTATUS -DDKAPI -IoWMIQueryAllData( - IN PVOID DataBlockObject, - IN OUT ULONG *InOutBufferSize, - OUT PVOID OutBuffer); - -NTOSAPI -NTSTATUS -DDKAPI -IoWMIQueryAllDataMultiple( - IN PVOID *DataBlockObjectList, - IN ULONG ObjectCount, - IN OUT ULONG *InOutBufferSize, - OUT PVOID OutBuffer); - -NTOSAPI -NTSTATUS -DDKAPI -IoWMIQuerySingleInstance( - IN PVOID DataBlockObject, - IN PUNICODE_STRING InstanceName, - IN OUT ULONG *InOutBufferSize, - OUT PVOID OutBuffer); - -NTOSAPI -NTSTATUS -DDKAPI -IoWMIQuerySingleInstanceMultiple( - IN PVOID *DataBlockObjectList, - IN PUNICODE_STRING InstanceNames, - IN ULONG ObjectCount, - IN OUT ULONG *InOutBufferSize, - OUT PVOID OutBuffer); - -NTOSAPI -NTSTATUS -DDKAPI -IoWMIRegistrationControl( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG Action); - -NTOSAPI -NTSTATUS -DDKAPI -IoWMISetNotificationCallback( - IN PVOID Object, - IN WMI_NOTIFICATION_CALLBACK Callback, - IN PVOID Context); - -NTOSAPI -NTSTATUS -DDKAPI -IoWMISetSingleInstance( - IN PVOID DataBlockObject, - IN PUNICODE_STRING InstanceName, - IN ULONG Version, - IN ULONG ValueBufferSize, - IN PVOID ValueBuffer); - -NTOSAPI -NTSTATUS -DDKAPI -IoWMISetSingleItem( - IN PVOID DataBlockObject, - IN PUNICODE_STRING InstanceName, - IN ULONG DataItemId, - IN ULONG Version, - IN ULONG ValueBufferSize, - IN PVOID ValueBuffer); - -NTOSAPI -NTSTATUS -DDKAPI -IoWMISuggestInstanceName( - IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, - IN PUNICODE_STRING SymbolicLinkName OPTIONAL, - IN BOOLEAN CombineNames, - OUT PUNICODE_STRING SuggestedInstanceName); - -NTOSAPI -NTSTATUS -DDKAPI -IoWMIWriteEvent( - IN PVOID WnodeEventItem); - -NTOSAPI -VOID -DDKAPI -IoWriteErrorLogEntry( - IN PVOID ElEntry); - -NTOSAPI -NTSTATUS -DDKAPI -IoWritePartitionTableEx( - IN PDEVICE_OBJECT DeviceObject, - IN struct _DRIVE_LAYOUT_INFORMATION_EX *PartitionBuffer); - - - -/** Kernel routines **/ - -NTOSAPI -VOID -DDKFASTAPI -KeAcquireInStackQueuedSpinLock( - IN PKSPIN_LOCK SpinLock, - IN PKLOCK_QUEUE_HANDLE LockHandle); - -NTOSAPI -VOID -DDKFASTAPI -KeAcquireInStackQueuedSpinLockAtDpcLevel( - IN PKSPIN_LOCK SpinLock, - IN PKLOCK_QUEUE_HANDLE LockHandle); - -NTOSAPI -KIRQL -DDKAPI -KeAcquireInterruptSpinLock( - IN PKINTERRUPT Interrupt); - -NTOSAPI -VOID -DDKAPI -KeAcquireSpinLock( - IN PKSPIN_LOCK SpinLock, - OUT PKIRQL OldIrql); - -/* System Service Dispatch Table */ -typedef struct _SSDT { - ULONG SysCallPtr; -} SSDT, *PSSDT; - -/* System Service Parameters Table */ -typedef struct _SSPT { - ULONG ParamBytes; -} SSPT, *PSSPT; - -typedef struct _SSDT_ENTRY { - PSSDT SSDT; - PULONG ServiceCounterTable; - ULONG NumberOfServices; - PSSPT SSPT; -} SSDT_ENTRY, *PSSDT_ENTRY; - -NTOSAPI -BOOLEAN -DDKAPI -KeAddSystemServiceTable( - IN PSSDT SSDT, - IN PULONG ServiceCounterTable, - IN ULONG NumberOfServices, - IN PSSPT SSPT, - IN ULONG TableIndex); - -NTOSAPI -BOOLEAN -DDKAPI -KeAreApcsDisabled( - VOID); - -NTOSAPI -VOID -DDKAPI -KeAttachProcess( - IN PEPROCESS Process); - -NTOSAPI -VOID -DDKAPI -KeBugCheck( - IN ULONG BugCheckCode); - -NTOSAPI -VOID -DDKAPI -KeBugCheckEx( - IN ULONG BugCheckCode, - IN ULONG_PTR BugCheckParameter1, - IN ULONG_PTR BugCheckParameter2, - IN ULONG_PTR BugCheckParameter3, - IN ULONG_PTR BugCheckParameter4); - -NTOSAPI -BOOLEAN -DDKAPI -KeCancelTimer( - IN PKTIMER Timer); - -NTOSAPI -VOID -DDKAPI -KeClearEvent( - IN PRKEVENT Event); - -NTOSAPI -NTSTATUS -DDKAPI -KeDelayExecutionThread( - IN KPROCESSOR_MODE WaitMode, - IN BOOLEAN Alertable, - IN PLARGE_INTEGER Interval); - -NTOSAPI -BOOLEAN -DDKAPI -KeDeregisterBugCheckCallback( - IN PKBUGCHECK_CALLBACK_RECORD CallbackRecord); - -NTOSAPI -VOID -DDKAPI -KeDetachProcess( - VOID); - -NTOSAPI -VOID -DDKAPI -KeEnterCriticalRegion( - VOID); - -/* - * VOID - * KeFlushIoBuffers( - * IN PMDL Mdl, - * IN BOOLEAN ReadOperation, - * IN BOOLEAN DmaOperation) - */ -#define KeFlushIoBuffers(_Mdl, _ReadOperation, _DmaOperation) - -NTOSAPI -PRKTHREAD -DDKAPI -KeGetCurrentThread( - VOID); - -NTOSAPI -KPROCESSOR_MODE -DDKAPI -KeGetPreviousMode( - VOID); - -NTOSAPI -ULONG -DDKAPI -KeGetRecommendedSharedDataAlignment( - VOID); - -NTOSAPI -VOID -DDKAPI -KeInitializeApc( - IN PKAPC Apc, - IN PKTHREAD Thread, - IN UCHAR StateIndex, - IN PKKERNEL_ROUTINE KernelRoutine, - IN PKRUNDOWN_ROUTINE RundownRoutine, - IN PKNORMAL_ROUTINE NormalRoutine, - IN UCHAR Mode, - IN PVOID Context); - -NTOSAPI -VOID -DDKAPI -KeInitializeDeviceQueue( - IN PKDEVICE_QUEUE DeviceQueue); - -NTOSAPI -VOID -DDKAPI -KeInitializeMutex( - IN PRKMUTEX Mutex, - IN ULONG Level); - -NTOSAPI -VOID -DDKAPI -KeInitializeSemaphore( - IN PRKSEMAPHORE Semaphore, - IN LONG Count, - IN LONG Limit); - -NTOSAPI -VOID -DDKAPI -KeInitializeSpinLock( - IN PKSPIN_LOCK SpinLock); - -NTOSAPI -VOID -DDKAPI -KeInitializeTimer( - IN PKTIMER Timer); - -NTOSAPI -VOID -DDKAPI -KeInitializeTimerEx( - IN PKTIMER Timer, - IN TIMER_TYPE Type); - -NTOSAPI -BOOLEAN -DDKAPI -KeInsertByKeyDeviceQueue( - IN PKDEVICE_QUEUE DeviceQueue, - IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry, - IN ULONG SortKey); - -NTOSAPI -BOOLEAN -DDKAPI -KeInsertDeviceQueue( - IN PKDEVICE_QUEUE DeviceQueue, - IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry); - -NTOSAPI -BOOLEAN -DDKAPI -KeInsertQueueDpc( - IN PRKDPC Dpc, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2); - -NTOSAPI -VOID -DDKAPI -KeLeaveCriticalRegion( - VOID); - -NTOSAPI -VOID -DDKAPI -KeLowerIrql( - IN KIRQL NewIrql); - -NTOSAPI -NTSTATUS -DDKAPI -KePulseEvent( - IN PRKEVENT Event, - IN KPRIORITY Increment, - IN BOOLEAN Wait); - -NTOSAPI -ULONGLONG -DDKAPI -KeQueryInterruptTime( - VOID); - -NTOSAPI -LARGE_INTEGER -DDKAPI -KeQueryPerformanceCounter( - OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL); - -NTOSAPI -KPRIORITY -DDKAPI -KeQueryPriorityThread( - IN PRKTHREAD Thread); - -NTOSAPI -VOID -DDKAPI -KeQuerySystemTime( - OUT PLARGE_INTEGER CurrentTime); - -NTOSAPI -VOID -DDKAPI -KeQueryTickCount( - OUT PLARGE_INTEGER TickCount); - -NTOSAPI -ULONG -DDKAPI -KeQueryTimeIncrement( - VOID); - -NTOSAPI -VOID -DDKAPI -KeRaiseIrql( - IN KIRQL NewIrql, - OUT PKIRQL OldIrql); - -NTOSAPI -KIRQL -DDKAPI -KeRaiseIrqlToDpcLevel( - VOID); - -NTOSAPI -LONG -DDKAPI -KeReadStateEvent( - IN PRKEVENT Event); - -NTOSAPI -LONG -DDKAPI -KeReadStateMutex( - IN PRKMUTEX Mutex); - -NTOSAPI -LONG -DDKAPI -KeReadStateSemaphore( - IN PRKSEMAPHORE Semaphore); - -NTOSAPI -BOOLEAN -DDKAPI -KeReadStateTimer( - IN PKTIMER Timer); - -NTOSAPI -BOOLEAN -DDKAPI -KeRegisterBugCheckCallback( - IN PKBUGCHECK_CALLBACK_RECORD CallbackRecord, - IN PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine, - IN PVOID Buffer, - IN ULONG Length, - IN PUCHAR Component); - -NTOSAPI -VOID -DDKFASTAPI -KeReleaseInStackQueuedSpinLock( - IN PKLOCK_QUEUE_HANDLE LockHandle); - -NTOSAPI -VOID -DDKFASTAPI -KeReleaseInStackQueuedSpinLockFromDpcLevel( - IN PKLOCK_QUEUE_HANDLE LockHandle); - -NTOSAPI -VOID -DDKAPI -KeReleaseInterruptSpinLock( - IN PKINTERRUPT Interrupt, - IN KIRQL OldIrql); - -NTOSAPI -LONG -DDKAPI -KeReleaseMutex( - IN PRKMUTEX Mutex, - IN BOOLEAN Wait); - -NTOSAPI -LONG -DDKAPI -KeReleaseSemaphore( - IN PRKSEMAPHORE Semaphore, - IN KPRIORITY Increment, - IN LONG Adjustment, - IN BOOLEAN Wait); - -NTOSAPI -VOID -DDKAPI -KeReleaseSpinLock( - IN PKSPIN_LOCK SpinLock, - IN KIRQL NewIrql); - -NTOSAPI -PKDEVICE_QUEUE_ENTRY -DDKAPI -KeRemoveByKeyDeviceQueue( - IN PKDEVICE_QUEUE DeviceQueue, - IN ULONG SortKey); - -NTOSAPI -PKDEVICE_QUEUE_ENTRY -DDKAPI -KeRemoveDeviceQueue( - IN PKDEVICE_QUEUE DeviceQueue); - -NTOSAPI -BOOLEAN -DDKAPI -KeRemoveEntryDeviceQueue( - IN PKDEVICE_QUEUE DeviceQueue, - IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry); - -NTOSAPI -BOOLEAN -DDKAPI -KeRemoveQueueDpc( - IN PRKDPC Dpc); - -NTOSAPI -LONG -DDKAPI -KeResetEvent( - IN PRKEVENT Event); - -NTOSAPI -NTSTATUS -DDKAPI -KeRestoreFloatingPointState( - IN PKFLOATING_SAVE FloatSave); - -NTOSAPI -NTSTATUS -DDKAPI -KeSaveFloatingPointState( - OUT PKFLOATING_SAVE FloatSave); - -NTOSAPI -LONG -DDKAPI -KeSetBasePriorityThread( - IN PRKTHREAD Thread, - IN LONG Increment); - -NTOSAPI -LONG -DDKAPI -KeSetEvent( - IN PRKEVENT Event, - IN KPRIORITY Increment, - IN BOOLEAN Wait); - -NTOSAPI -VOID -DDKAPI -KeSetImportanceDpc( - IN PRKDPC Dpc, - IN KDPC_IMPORTANCE Importance); - -NTOSAPI -KPRIORITY -DDKAPI -KeSetPriorityThread( - IN PKTHREAD Thread, - IN KPRIORITY Priority); - -NTOSAPI -VOID -DDKAPI -KeSetTargetProcessorDpc( - IN PRKDPC Dpc, - IN CCHAR Number); - -NTOSAPI -BOOLEAN -DDKAPI -KeSetTimer( - IN PKTIMER Timer, - IN LARGE_INTEGER DueTime, - IN PKDPC Dpc OPTIONAL); - -NTOSAPI -BOOLEAN -DDKAPI -KeSetTimerEx( - IN PKTIMER Timer, - IN LARGE_INTEGER DueTime, - IN LONG Period OPTIONAL, - IN PKDPC Dpc OPTIONAL); - -NTOSAPI -VOID -DDKFASTAPI -KeSetTimeUpdateNotifyRoutine( - IN PTIME_UPDATE_NOTIFY_ROUTINE NotifyRoutine); - -NTOSAPI -VOID -DDKAPI -KeStallExecutionProcessor( - IN ULONG MicroSeconds); - -NTOSAPI -BOOLEAN -DDKAPI -KeSynchronizeExecution( - IN PKINTERRUPT Interrupt, - IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, - IN PVOID SynchronizeContext); - -NTOSAPI -NTSTATUS -DDKAPI -KeWaitForMultipleObjects( - IN ULONG Count, - IN PVOID Object[], - IN WAIT_TYPE WaitType, - IN KWAIT_REASON WaitReason, - IN KPROCESSOR_MODE WaitMode, - IN BOOLEAN Alertable, - IN PLARGE_INTEGER Timeout OPTIONAL, - IN PKWAIT_BLOCK WaitBlockArray OPTIONAL); - -NTOSAPI -NTSTATUS -DDKAPI -KeWaitForMutexObject( - IN PRKMUTEX Mutex, - IN KWAIT_REASON WaitReason, - IN KPROCESSOR_MODE WaitMode, - IN BOOLEAN Alertable, - IN PLARGE_INTEGER Timeout OPTIONAL); - -NTOSAPI -NTSTATUS -DDKAPI -KeWaitForSingleObject( - IN PVOID Object, - IN KWAIT_REASON WaitReason, - IN KPROCESSOR_MODE WaitMode, - IN BOOLEAN Alertable, - IN PLARGE_INTEGER Timeout OPTIONAL); - - - -/** Memory manager routines **/ - -NTOSAPI -NTSTATUS -DDKAPI -MmAdvanceMdl( - IN PMDL Mdl, - IN ULONG NumberOfBytes); - -NTOSAPI -PVOID -DDKAPI -MmAllocateContiguousMemory( - IN ULONG NumberOfBytes, - IN PHYSICAL_ADDRESS HighestAcceptableAddress); - -NTOSAPI -PVOID -DDKAPI -MmAllocateContiguousMemorySpecifyCache( - IN SIZE_T NumberOfBytes, - IN PHYSICAL_ADDRESS LowestAcceptableAddress, - IN PHYSICAL_ADDRESS HighestAcceptableAddress, - IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL, - IN MEMORY_CACHING_TYPE CacheType); - -NTOSAPI -PVOID -DDKAPI -MmAllocateMappingAddress( - IN SIZE_T NumberOfBytes, - IN ULONG PoolTag); - -NTOSAPI -PVOID -DDKAPI -MmAllocateNonCachedMemory( - IN ULONG NumberOfBytes); - -NTOSAPI -PMDL -DDKAPI -MmAllocatePagesForMdl( - IN PHYSICAL_ADDRESS LowAddress, - IN PHYSICAL_ADDRESS HighAddress, - IN PHYSICAL_ADDRESS SkipBytes, - IN SIZE_T TotalBytes); - -NTOSAPI -VOID -DDKAPI -MmBuildMdlForNonPagedPool( - IN OUT PMDL MemoryDescriptorList); - -NTOSAPI -NTSTATUS -DDKAPI -MmCreateSection( - OUT PSECTION_OBJECT *SectionObject, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, - IN PLARGE_INTEGER MaximumSize, - IN ULONG SectionPageProtection, - IN ULONG AllocationAttributes, - IN HANDLE FileHandle OPTIONAL, - IN PFILE_OBJECT File OPTIONAL); - -typedef enum _MMFLUSH_TYPE { - MmFlushForDelete, - MmFlushForWrite -} MMFLUSH_TYPE; - -NTOSAPI -BOOLEAN -DDKAPI -MmFlushImageSection( - IN PSECTION_OBJECT_POINTERS SectionObjectPointer, - IN MMFLUSH_TYPE FlushType); - -NTOSAPI -VOID -DDKAPI -MmFreeContiguousMemory( - IN PVOID BaseAddress); - -NTOSAPI -VOID -DDKAPI -MmFreeContiguousMemorySpecifyCache( - IN PVOID BaseAddress, - IN SIZE_T NumberOfBytes, - IN MEMORY_CACHING_TYPE CacheType); - -NTOSAPI -VOID -DDKAPI -MmFreeMappingAddress( - IN PVOID BaseAddress, - IN ULONG PoolTag); - -NTOSAPI -VOID -DDKAPI -MmFreeNonCachedMemory( - IN PVOID BaseAddress, - IN SIZE_T NumberOfBytes); - -NTOSAPI -VOID -DDKAPI -MmFreePagesFromMdl( - IN PMDL MemoryDescriptorList); - -/* - * ULONG - * MmGetMdlByteCount( - * IN PMDL Mdl) - */ -#define MmGetMdlByteCount(_Mdl) \ - ((_Mdl)->ByteCount) - -/* - * ULONG - * MmGetMdlByteOffset( - * IN PMDL Mdl) - */ -#define MmGetMdlByteOffset(_Mdl) \ - ((_Mdl)->ByteOffset) - -/* - * PPFN_NUMBER - * MmGetMdlPfnArray( - * IN PMDL Mdl) - */ -#define MmGetMdlPfnArray(_Mdl) \ - ((PPFN_NUMBER) ((_Mdl) + 1)) - -/* - * PVOID - * MmGetMdlVirtualAddress( - * IN PMDL Mdl) - */ -#define MmGetMdlVirtualAddress(_Mdl) \ - ((PVOID) ((PCHAR) ((_Mdl)->StartVa) + (_Mdl)->ByteOffset)) - -NTOSAPI -PHYSICAL_ADDRESS -DDKAPI -MmGetPhysicalAddress( - IN PVOID BaseAddress); - -NTOSAPI -PPHYSICAL_MEMORY_RANGE -DDKAPI -MmGetPhysicalMemoryRanges( - VOID); - -NTOSAPI -PVOID -DDKAPI -MmGetVirtualForPhysical( - IN PHYSICAL_ADDRESS PhysicalAddress); - -NTOSAPI -PVOID -DDKAPI -MmMapLockedPagesSpecifyCache( - IN PMDL MemoryDescriptorList, - IN KPROCESSOR_MODE AccessMode, - IN MEMORY_CACHING_TYPE CacheType, - IN PVOID BaseAddress, - IN ULONG BugCheckOnFailure, - IN MM_PAGE_PRIORITY Priority); - -NTOSAPI -PVOID -DDKAPI -MmMapLockedPagesWithReservedMapping( - IN PVOID MappingAddress, - IN ULONG PoolTag, - IN PMDL MemoryDescriptorList, - IN MEMORY_CACHING_TYPE CacheType); - -NTOSAPI -NTSTATUS -DDKAPI -MmMapUserAddressesToPage( - IN PVOID BaseAddress, - IN SIZE_T NumberOfBytes, - IN PVOID PageAddress); - -NTOSAPI -PVOID -DDKAPI -MmMapVideoDisplay( - IN PHYSICAL_ADDRESS PhysicalAddress, - IN SIZE_T NumberOfBytes, - IN MEMORY_CACHING_TYPE CacheType); - -NTOSAPI -NTSTATUS -DDKAPI -MmMapViewInSessionSpace( - IN PVOID Section, - OUT PVOID *MappedBase, - IN OUT PSIZE_T ViewSize); - -NTOSAPI -NTSTATUS -DDKAPI -MmMapViewInSystemSpace( - IN PVOID Section, - OUT PVOID *MappedBase, - IN PSIZE_T ViewSize); - -NTOSAPI -NTSTATUS -DDKAPI -MmMarkPhysicalMemoryAsBad( - IN PPHYSICAL_ADDRESS StartAddress, - IN OUT PLARGE_INTEGER NumberOfBytes); - -NTOSAPI -NTSTATUS -DDKAPI -MmMarkPhysicalMemoryAsGood( - IN PPHYSICAL_ADDRESS StartAddress, - IN OUT PLARGE_INTEGER NumberOfBytes); - -/* - * PVOID - * MmGetSystemAddressForMdlSafe( - * IN PMDL Mdl, - * IN MM_PAGE_PRIORITY Priority) - */ -#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority) \ - ((_Mdl)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA \ - | MDL_SOURCE_IS_NONPAGED_POOL)) ? \ - (_Mdl)->MappedSystemVa : \ - (PVOID) MmMapLockedPagesSpecifyCache((_Mdl), \ - KernelMode, MmCached, NULL, FALSE, _Priority); - -NTOSAPI -PVOID -DDKAPI -MmGetSystemRoutineAddress( - IN PUNICODE_STRING SystemRoutineName); - -/* - * ULONG - * ADDRESS_AND_SIZE_TO_SPAN_PAGES( - * IN PVOID Va, - * IN ULONG Size) - */ -#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, \ - _Size) \ - (ULONG) ((((ULONG_PTR) (_Va) & (PAGE_SIZE - 1)) \ - + (_Size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT) - -/* - * VOID - * MmInitializeMdl( - * IN PMDL MemoryDescriptorList, - * IN PVOID BaseVa, - * IN SIZE_T Length) - */ -#define MmInitializeMdl(_MemoryDescriptorList, \ - _BaseVa, \ - _Length) \ -{ \ - (_MemoryDescriptorList)->Next = (PMDL) NULL; \ - (_MemoryDescriptorList)->Size = (CSHORT) (sizeof(MDL) + \ - (sizeof(PFN_NUMBER) * ADDRESS_AND_SIZE_TO_SPAN_PAGES(_BaseVa, _Length))); \ - (_MemoryDescriptorList)->MdlFlags = 0; \ - (_MemoryDescriptorList)->StartVa = (PVOID) PAGE_ALIGN(_BaseVa); \ - (_MemoryDescriptorList)->ByteOffset = BYTE_OFFSET(_BaseVa); \ - (_MemoryDescriptorList)->ByteCount = (ULONG) _Length; \ -} - -NTOSAPI -BOOLEAN -DDKAPI -MmIsAddressValid( - IN PVOID VirtualAddress); - -NTOSAPI -LOGICAL -DDKAPI -MmIsDriverVerifying( - IN PDRIVER_OBJECT DriverObject); - -NTOSAPI -BOOLEAN -DDKAPI -MmIsThisAnNtAsSystem( - VOID); - -NTOSAPI -NTSTATUS -DDKAPI -MmIsVerifierEnabled( - OUT PULONG VerifierFlags); - -NTOSAPI -PVOID -DDKAPI -MmLockPagableDataSection( - IN PVOID AddressWithinSection); - -NTOSAPI -PVOID -DDKAPI -MmLockPagableImageSection( - IN PVOID AddressWithinSection); - -/* - * PVOID - * MmLockPagableCodeSection( - * IN PVOID AddressWithinSection) - */ -#define MmLockPagableCodeSection MmLockPagableDataSection - -NTOSAPI -VOID -DDKAPI -MmLockPagableSectionByHandle( - IN PVOID ImageSectionHandle); - -NTOSAPI -PVOID -DDKAPI -MmMapIoSpace( - IN PHYSICAL_ADDRESS PhysicalAddress, - IN ULONG NumberOfBytes, - IN MEMORY_CACHING_TYPE CacheEnable); - -NTOSAPI -PVOID -DDKAPI -MmMapLockedPages( - IN PMDL MemoryDescriptorList, - IN KPROCESSOR_MODE AccessMode); - -NTOSAPI -VOID -DDKAPI -MmPageEntireDriver( - IN PVOID AddressWithinSection); - -NTOSAPI -VOID -DDKAPI -MmProbeAndLockProcessPages( - IN OUT PMDL MemoryDescriptorList, - IN PEPROCESS Process, - IN KPROCESSOR_MODE AccessMode, - IN LOCK_OPERATION Operation); - -NTOSAPI -NTSTATUS -DDKAPI -MmProtectMdlSystemAddress( - IN PMDL MemoryDescriptorList, - IN ULONG NewProtect); - -NTOSAPI -VOID -DDKAPI -MmUnmapLockedPages( - IN PVOID BaseAddress, - IN PMDL MemoryDescriptorList); - -NTOSAPI -NTSTATUS -DDKAPI -MmUnmapViewInSessionSpace( - IN PVOID MappedBase); - -NTOSAPI -NTSTATUS -DDKAPI -MmUnmapViewInSystemSpace( - IN PVOID MappedBase); - -NTOSAPI -VOID -DDKAPI -MmUnsecureVirtualMemory( - IN HANDLE SecureHandle); - -/* - * VOID - * MmPrepareMdlForReuse( - * IN PMDL Mdl) - */ -#define MmPrepareMdlForReuse(_Mdl) \ -{ \ - if (((_Mdl)->MdlFlags & MDL_PARTIAL_HAS_BEEN_MAPPED) != 0) { \ - assert(((_Mdl)->MdlFlags & MDL_PARTIAL) != 0); \ - MmUnmapLockedPages((_Mdl)->MappedSystemVa, (_Mdl)); \ - } else if (((_Mdl)->MdlFlags & MDL_PARTIAL) == 0) { \ - assert(((_Mdl)->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) == 0); \ - } \ -} - -NTOSAPI -VOID -DDKAPI -MmProbeAndLockPages( - IN OUT PMDL MemoryDescriptorList, - IN KPROCESSOR_MODE AccessMode, - IN LOCK_OPERATION Operation); - -NTOSAPI -MM_SYSTEM_SIZE -DDKAPI -MmQuerySystemSize( - VOID); - -NTOSAPI -NTSTATUS -DDKAPI -MmRemovePhysicalMemory( - IN PPHYSICAL_ADDRESS StartAddress, - IN OUT PLARGE_INTEGER NumberOfBytes); - -NTOSAPI -VOID -DDKAPI -MmResetDriverPaging( - IN PVOID AddressWithinSection); - -NTOSAPI -HANDLE -DDKAPI -MmSecureVirtualMemory( - IN PVOID Address, - IN SIZE_T Size, - IN ULONG ProbeMode); - -NTOSAPI -ULONG -DDKAPI -MmSizeOfMdl( - IN PVOID Base, - IN SIZE_T Length); - -NTOSAPI -VOID -DDKAPI -MmUnlockPagableImageSection( - IN PVOID ImageSectionHandle); - -NTOSAPI -VOID -DDKAPI -MmUnlockPages( - IN PMDL MemoryDescriptorList); - -NTOSAPI -VOID -DDKAPI -MmUnmapIoSpace( - IN PVOID BaseAddress, - IN SIZE_T NumberOfBytes); - -NTOSAPI -VOID -DDKAPI -MmUnmapReservedMapping( - IN PVOID BaseAddress, - IN ULONG PoolTag, - IN PMDL MemoryDescriptorList); - -NTOSAPI -VOID -DDKAPI -MmUnmapVideoDisplay( - IN PVOID BaseAddress, - IN SIZE_T NumberOfBytes); - - - -/** Object manager routines **/ - -NTOSAPI -NTSTATUS -DDKAPI -ObAssignSecurity( - IN PACCESS_STATE AccessState, - IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN PVOID Object, - IN POBJECT_TYPE Type); - -NTOSAPI -VOID -DDKAPI -ObDereferenceSecurityDescriptor( - PSECURITY_DESCRIPTOR SecurityDescriptor, - ULONG Count); - -NTOSAPI -VOID -DDKFASTAPI -ObfDereferenceObject( - IN PVOID Object); - -/* - * VOID - * ObDereferenceObject( - * IN PVOID Object) - */ -#define ObDereferenceObject ObfDereferenceObject - -NTOSAPI -NTSTATUS -DDKAPI -ObGetObjectSecurity( - IN PVOID Object, - OUT PSECURITY_DESCRIPTOR *SecurityDescriptor, - OUT PBOOLEAN MemoryAllocated); - -NTOSAPI -NTSTATUS -DDKAPI -ObInsertObject( - IN PVOID Object, - IN PACCESS_STATE PassedAccessState OPTIONAL, - IN ACCESS_MASK DesiredAccess, - IN ULONG AdditionalReferences, - OUT PVOID* ReferencedObject OPTIONAL, - OUT PHANDLE Handle); - -NTOSAPI -VOID -DDKFASTAPI -ObfReferenceObject( - IN PVOID Object); - -NTOSAPI -NTSTATUS -DDKAPI -ObLogSecurityDescriptor( - IN PSECURITY_DESCRIPTOR InputSecurityDescriptor, - OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor, - IN ULONG RefBias); -/* - * VOID - * ObReferenceObject( - * IN PVOID Object) - */ -#define ObReferenceObject ObfReferenceObject - -NTOSAPI -VOID -DDKAPI -ObMakeTemporaryObject( - IN PVOID Object); - -NTOSAPI -NTSTATUS -DDKAPI -ObOpenObjectByName( - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN POBJECT_TYPE ObjectType, - IN OUT PVOID ParseContext OPTIONAL, - IN KPROCESSOR_MODE AccessMode, - IN ACCESS_MASK DesiredAccess, - IN PACCESS_STATE PassedAccessState, - OUT PHANDLE Handle); - -NTOSAPI -NTSTATUS -DDKAPI -ObOpenObjectByPointer( - IN PVOID Object, - IN ULONG HandleAttributes, - IN PACCESS_STATE PassedAccessState OPTIONAL, - IN ACCESS_MASK DesiredAccess OPTIONAL, - IN POBJECT_TYPE ObjectType OPTIONAL, - IN KPROCESSOR_MODE AccessMode, - OUT PHANDLE Handle); - -NTOSAPI -NTSTATUS -DDKAPI -ObQueryObjectAuditingByHandle( - IN HANDLE Handle, - OUT PBOOLEAN GenerateOnClose); - -NTOSAPI -NTSTATUS -DDKAPI -ObReferenceObjectByHandle( - IN HANDLE Handle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_TYPE ObjectType OPTIONAL, - IN KPROCESSOR_MODE AccessMode, - OUT PVOID *Object, - OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL); - -NTOSAPI -NTSTATUS -DDKAPI -ObReferenceObjectByName( - IN PUNICODE_STRING ObjectPath, - IN ULONG Attributes, - IN PACCESS_STATE PassedAccessState OPTIONAL, - IN ACCESS_MASK DesiredAccess OPTIONAL, - IN POBJECT_TYPE ObjectType, - IN KPROCESSOR_MODE AccessMode, - IN OUT PVOID ParseContext OPTIONAL, - OUT PVOID *Object); - -NTOSAPI -NTSTATUS -DDKAPI -ObReferenceObjectByPointer( - IN PVOID Object, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_TYPE ObjectType, - IN KPROCESSOR_MODE AccessMode); - -NTOSAPI -VOID -DDKAPI -ObReferenceSecurityDescriptor( - IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN ULONG Count); - -NTOSAPI -VOID -DDKAPI -ObReleaseObjectSecurity( - IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN BOOLEAN MemoryAllocated); - - - -/** Process manager routines **/ - -NTOSAPI -NTSTATUS -DDKAPI -PsCreateSystemProcess( - IN PHANDLE ProcessHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes); - -NTOSAPI -NTSTATUS -DDKAPI -PsCreateSystemThread( - OUT PHANDLE ThreadHandle, - IN ULONG DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, - IN HANDLE ProcessHandle OPTIONAL, - OUT PCLIENT_ID ClientId OPTIONAL, - IN PKSTART_ROUTINE StartRoutine, - IN PVOID StartContext); - -/* - * PEPROCESS - * PsGetCurrentProcess(VOID) - */ -#define PsGetCurrentProcess IoGetCurrentProcess - -NTOSAPI -HANDLE -DDKAPI -PsGetCurrentProcessId( - VOID); - -/* - * PETHREAD - * PsGetCurrentThread(VOID) - */ -#define PsGetCurrentThread() \ - ((PETHREAD) KeGetCurrentThread()) - -NTOSAPI -HANDLE -DDKAPI -PsGetCurrentThreadId( - VOID); - -NTOSAPI -BOOLEAN -DDKAPI -PsGetVersion( - PULONG MajorVersion OPTIONAL, - PULONG MinorVersion OPTIONAL, - PULONG BuildNumber OPTIONAL, - PUNICODE_STRING CSDVersion OPTIONAL); - -NTOSAPI -NTSTATUS -DDKAPI -PsRemoveCreateThreadNotifyRoutine( - IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine); - -NTOSAPI -NTSTATUS -DDKAPI -PsRemoveLoadImageNotifyRoutine( - IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine); - -NTOSAPI -NTSTATUS -DDKAPI -PsSetCreateProcessNotifyRoutine( - IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine, - IN BOOLEAN Remove); - -NTOSAPI -NTSTATUS -DDKAPI -PsSetCreateThreadNotifyRoutine( - IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine); - -NTOSAPI -NTSTATUS -DDKAPI -PsSetLoadImageNotifyRoutine( - IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine); - -NTOSAPI -NTSTATUS -DDKAPI -PsTerminateSystemThread( - IN NTSTATUS ExitStatus); - - - -/** Security reference monitor routines **/ - -NTOSAPI -BOOLEAN -DDKAPI -SeAccessCheck( - IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, - IN BOOLEAN SubjectContextLocked, - IN ACCESS_MASK DesiredAccess, - IN ACCESS_MASK PreviouslyGrantedAccess, - OUT PPRIVILEGE_SET *Privileges OPTIONAL, - IN PGENERIC_MAPPING GenericMapping, - IN KPROCESSOR_MODE AccessMode, - OUT PACCESS_MASK GrantedAccess, - OUT PNTSTATUS AccessStatus); - -NTOSAPI -NTSTATUS -DDKAPI -SeAssignSecurity( - IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, - IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL, - OUT PSECURITY_DESCRIPTOR *NewDescriptor, - IN BOOLEAN IsDirectoryObject, - IN PSECURITY_SUBJECT_CONTEXT SubjectContext, - IN PGENERIC_MAPPING GenericMapping, - IN POOL_TYPE PoolType); - -NTOSAPI -NTSTATUS -DDKAPI -SeAssignSecurityEx( - IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, - IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL, - OUT PSECURITY_DESCRIPTOR *NewDescriptor, - IN GUID *ObjectType OPTIONAL, - IN BOOLEAN IsDirectoryObject, - IN ULONG AutoInheritFlags, - IN PSECURITY_SUBJECT_CONTEXT SubjectContext, - IN PGENERIC_MAPPING GenericMapping, - IN POOL_TYPE PoolType); - -NTOSAPI -NTSTATUS -DDKAPI -SeDeassignSecurity( - IN OUT PSECURITY_DESCRIPTOR *SecurityDescriptor); - -NTOSAPI -BOOLEAN -DDKAPI -SeSinglePrivilegeCheck( - LUID PrivilegeValue, - KPROCESSOR_MODE PreviousMode); - -NTOSAPI -BOOLEAN -DDKAPI -SeValidSecurityDescriptor( - IN ULONG Length, - IN PSECURITY_DESCRIPTOR SecurityDescriptor); - - - -/** NtXxx routines **/ - -NTOSAPI -NTSTATUS -DDKAPI -NtOpenProcess( - OUT PHANDLE ProcessHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN PCLIENT_ID ClientId OPTIONAL); - -NTOSAPI -NTSTATUS -DDKAPI -NtQueryInformationProcess( - IN HANDLE ProcessHandle, - IN PROCESSINFOCLASS ProcessInformationClass, - OUT PVOID ProcessInformation, - IN ULONG ProcessInformationLength, - OUT PULONG ReturnLength OPTIONAL); - - - -/** NtXxx and ZwXxx routines **/ - -NTOSAPI -NTSTATUS -DDKAPI -ZwCancelTimer( - IN HANDLE TimerHandle, - OUT PBOOLEAN CurrentState OPTIONAL); - -NTOSAPI -NTSTATUS -DDKAPI -NtClose( - IN HANDLE Handle); - -NTOSAPI -NTSTATUS -DDKAPI -ZwClose( - IN HANDLE Handle); - -NTOSAPI -NTSTATUS -DDKAPI -ZwCreateDirectoryObject( - OUT PHANDLE DirectoryHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes); - -NTOSAPI -NTSTATUS -DDKAPI -NtCreateEvent( - OUT PHANDLE EventHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN BOOLEAN ManualReset, - IN BOOLEAN InitialState); - -NTOSAPI -NTSTATUS -DDKAPI -ZwCreateEvent( - OUT PHANDLE EventHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN BOOLEAN ManualReset, - IN BOOLEAN InitialState); - -NTOSAPI -NTSTATUS -DDKAPI -ZwCreateFile( - OUT PHANDLE FileHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN PLARGE_INTEGER AllocationSize OPTIONAL, - IN ULONG FileAttributes, - IN ULONG ShareAccess, - IN ULONG CreateDisposition, - IN ULONG CreateOptions, - IN PVOID EaBuffer OPTIONAL, - IN ULONG EaLength); - -NTOSAPI -NTSTATUS -DDKAPI -ZwCreateKey( - OUT PHANDLE KeyHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN ULONG TitleIndex, - IN PUNICODE_STRING Class OPTIONAL, - IN ULONG CreateOptions, - OUT PULONG Disposition OPTIONAL); - -NTOSAPI -NTSTATUS -DDKAPI -ZwCreateTimer( - OUT PHANDLE TimerHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, - IN TIMER_TYPE TimerType); - -NTOSAPI -NTSTATUS -DDKAPI -ZwDeleteKey( - IN HANDLE KeyHandle); - -NTOSAPI -NTSTATUS -DDKAPI -ZwDeleteValueKey( - IN HANDLE KeyHandle, - IN PUNICODE_STRING ValueName); - -NTOSAPI -NTSTATUS -DDKAPI -NtDeviceIoControlFile( - IN HANDLE DeviceHandle, - IN HANDLE Event OPTIONAL, - IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL, - IN PVOID UserApcContext OPTIONAL, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN ULONG IoControlCode, - IN PVOID InputBuffer, - IN ULONG InputBufferSize, - OUT PVOID OutputBuffer, - IN ULONG OutputBufferSize); - -NTOSAPI -NTSTATUS -DDKAPI -ZwDeviceIoControlFile( - IN HANDLE DeviceHandle, - IN HANDLE Event OPTIONAL, - IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL, - IN PVOID UserApcContext OPTIONAL, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN ULONG IoControlCode, - IN PVOID InputBuffer, - IN ULONG InputBufferSize, - OUT PVOID OutputBuffer, - IN ULONG OutputBufferSize); - -NTOSAPI -NTSTATUS -DDKAPI -ZwEnumerateKey( - IN HANDLE KeyHandle, - IN ULONG Index, - IN KEY_INFORMATION_CLASS KeyInformationClass, - OUT PVOID KeyInformation, - IN ULONG Length, - OUT PULONG ResultLength); - -NTOSAPI -NTSTATUS -DDKAPI -ZwEnumerateValueKey( - IN HANDLE KeyHandle, - IN ULONG Index, - IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, - OUT PVOID KeyValueInformation, - IN ULONG Length, - OUT PULONG ResultLength); - -NTOSAPI -NTSTATUS -DDKAPI -ZwFlushKey( - IN HANDLE KeyHandle); - -NTOSAPI -NTSTATUS -DDKAPI -ZwMakeTemporaryObject( - IN HANDLE Handle); - -NTOSAPI -NTSTATUS -DDKAPI -NtMapViewOfSection( - IN HANDLE SectionHandle, - IN HANDLE ProcessHandle, - IN OUT PVOID *BaseAddress, - IN ULONG ZeroBits, - IN ULONG CommitSize, - IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, - IN OUT PSIZE_T ViewSize, - IN SECTION_INHERIT InheritDisposition, - IN ULONG AllocationType, - IN ULONG Protect); - -NTOSAPI -NTSTATUS -DDKAPI -ZwMapViewOfSection( - IN HANDLE SectionHandle, - IN HANDLE ProcessHandle, - IN OUT PVOID *BaseAddress, - IN ULONG ZeroBits, - IN ULONG CommitSize, - IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, - IN OUT PSIZE_T ViewSize, - IN SECTION_INHERIT InheritDisposition, - IN ULONG AllocationType, - IN ULONG Protect); - -NTOSAPI -NTSTATUS -DDKAPI -NtOpenFile( - OUT PHANDLE FileHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN ULONG ShareAccess, - IN ULONG OpenOptions); - -NTOSAPI -NTSTATUS -DDKAPI -ZwOpenFile( - OUT PHANDLE FileHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN ULONG ShareAccess, - IN ULONG OpenOptions); - -NTOSAPI -NTSTATUS -DDKAPI -ZwOpenKey( - OUT PHANDLE KeyHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes); - -NTOSAPI -NTSTATUS -DDKAPI -ZwOpenSection( - OUT PHANDLE SectionHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes); - -NTOSAPI -NTSTATUS -DDKAPI -ZwOpenSymbolicLinkObject( - OUT PHANDLE LinkHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes); - -NTOSAPI -NTSTATUS -DDKAPI -ZwOpenTimer( - OUT PHANDLE TimerHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes); - -NTOSAPI -NTSTATUS -DDKAPI -ZwQueryInformationFile( - IN HANDLE FileHandle, - OUT PIO_STATUS_BLOCK IoStatusBlock, - OUT PVOID FileInformation, - IN ULONG Length, - IN FILE_INFORMATION_CLASS FileInformationClass); - -NTOSAPI -NTSTATUS -DDKAPI -ZwQueryKey( - IN HANDLE KeyHandle, - IN KEY_INFORMATION_CLASS KeyInformationClass, - OUT PVOID KeyInformation, - IN ULONG Length, - OUT PULONG ResultLength); - -NTOSAPI -NTSTATUS -DDKAPI -ZwQuerySymbolicLinkObject( - IN HANDLE LinkHandle, - IN OUT PUNICODE_STRING LinkTarget, - OUT PULONG ReturnedLength OPTIONAL); - -NTOSAPI -NTSTATUS -DDKAPI -ZwQueryValueKey( - IN HANDLE KeyHandle, - IN PUNICODE_STRING ValueName, - IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, - OUT PVOID KeyValueInformation, - IN ULONG Length, - OUT PULONG ResultLength); - -NTOSAPI -NTSTATUS -DDKAPI -NtReadFile( - IN HANDLE FileHandle, - IN HANDLE Event OPTIONAL, - IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, - IN PVOID ApcContext OPTIONAL, - OUT PIO_STATUS_BLOCK IoStatusBlock, - OUT PVOID Buffer, - IN ULONG Length, - IN PLARGE_INTEGER ByteOffset OPTIONAL, - IN PULONG Key OPTIONAL); - -NTOSAPI -NTSTATUS -DDKAPI -ZwReadFile( - IN HANDLE FileHandle, - IN HANDLE Event OPTIONAL, - IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, - IN PVOID ApcContext OPTIONAL, - OUT PIO_STATUS_BLOCK IoStatusBlock, - OUT PVOID Buffer, - IN ULONG Length, - IN PLARGE_INTEGER ByteOffset OPTIONAL, - IN PULONG Key OPTIONAL); - -NTOSAPI -NTSTATUS -DDKAPI -NtSetEvent( - IN HANDLE EventHandle, - IN PULONG NumberOfThreadsReleased); - -NTOSAPI -NTSTATUS -DDKAPI -ZwSetEvent( - IN HANDLE EventHandle, - IN PULONG NumberOfThreadsReleased); - -NTOSAPI -NTSTATUS -DDKAPI -ZwSetInformationFile( - IN HANDLE FileHandle, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN PVOID FileInformation, - IN ULONG Length, - IN FILE_INFORMATION_CLASS FileInformationClass); - -NTOSAPI -NTSTATUS -DDKAPI -ZwSetInformationThread( - IN HANDLE ThreadHandle, - IN THREADINFOCLASS ThreadInformationClass, - IN PVOID ThreadInformation, - IN ULONG ThreadInformationLength); - -NTOSAPI -NTSTATUS -DDKAPI -ZwSetTimer( - IN HANDLE TimerHandle, - IN PLARGE_INTEGER DueTime, - IN PTIMER_APC_ROUTINE TimerApcRoutine OPTIONAL, - IN PVOID TimerContext OPTIONAL, - IN BOOLEAN WakeTimer, - IN LONG Period OPTIONAL, - OUT PBOOLEAN PreviousState OPTIONAL); - -NTOSAPI -NTSTATUS -DDKAPI -ZwSetValueKey( - IN HANDLE KeyHandle, - IN PUNICODE_STRING ValueName, - IN ULONG TitleIndex OPTIONAL, - IN ULONG Type, - IN PVOID Data, - IN ULONG DataSize); - -/* [Nt|Zw]MapViewOfSection.InheritDisposition constants */ -#define AT_EXTENDABLE_FILE 0x00002000 -#define SEC_NO_CHANGE 0x00400000 -#define AT_RESERVED 0x20000000 -#define AT_ROUND_TO_PAGE 0x40000000 - -NTOSAPI -NTSTATUS -DDKAPI -NtUnmapViewOfSection( - IN HANDLE ProcessHandle, - IN PVOID BaseAddress); - -NTOSAPI -NTSTATUS -DDKAPI -ZwUnmapViewOfSection( - IN HANDLE ProcessHandle, - IN PVOID BaseAddress); - -NTOSAPI -NTSTATUS -DDKAPI -NtWaitForSingleObject( - IN HANDLE Object, - IN BOOLEAN Alertable, - IN PLARGE_INTEGER Time); - -NTOSAPI -NTSTATUS -DDKAPI -ZwWaitForSingleObject( - IN HANDLE Object, - IN BOOLEAN Alertable, - IN PLARGE_INTEGER Time); - -NTOSAPI -NTSTATUS -DDKAPI -NtWriteFile( - IN HANDLE FileHandle, - IN HANDLE Event OPTIONAL, - IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, - IN PVOID ApcContext OPTIONAL, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN PVOID Buffer, - IN ULONG Length, - IN PLARGE_INTEGER ByteOffset OPTIONAL, - IN PULONG Key OPTIONAL); - -NTOSAPI -NTSTATUS -DDKAPI -ZwWriteFile( - IN HANDLE FileHandle, - IN HANDLE Event OPTIONAL, - IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, - IN PVOID ApcContext OPTIONAL, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN PVOID Buffer, - IN ULONG Length, - IN PLARGE_INTEGER ByteOffset OPTIONAL, - IN PULONG Key OPTIONAL); - - - -/** Power management support routines **/ - -NTOSAPI -NTSTATUS -DDKAPI -PoCallDriver( - IN PDEVICE_OBJECT DeviceObject, - IN OUT PIRP Irp); - -NTOSAPI -PULONG -DDKAPI -PoRegisterDeviceForIdleDetection( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG ConservationIdleTime, - IN ULONG PerformanceIdleTime, - IN DEVICE_POWER_STATE State); - -NTOSAPI -PVOID -DDKAPI -PoRegisterSystemState( - IN PVOID StateHandle, - IN EXECUTION_STATE Flags); - -NTOSAPI -NTSTATUS -DDKAPI -PoRequestPowerIrp( - IN PDEVICE_OBJECT DeviceObject, - IN UCHAR MinorFunction, - IN POWER_STATE PowerState, - IN PREQUEST_POWER_COMPLETE CompletionFunction, - IN PVOID Context, - OUT PIRP *Irp OPTIONAL); - -NTOSAPI -NTSTATUS -DDKAPI -PoRequestShutdownEvent( - OUT PVOID *Event); - -NTOSAPI -VOID -DDKAPI -PoSetDeviceBusy( - PULONG IdlePointer); - -NTOSAPI -POWER_STATE -DDKAPI -PoSetPowerState( - IN PDEVICE_OBJECT DeviceObject, - IN POWER_STATE_TYPE Type, - IN POWER_STATE State); - -NTOSAPI -VOID -DDKAPI -PoSetSystemState( - IN EXECUTION_STATE Flags); - -NTOSAPI -VOID -DDKAPI -PoStartNextPowerIrp( - IN PIRP Irp); - -NTOSAPI -VOID -DDKAPI -PoUnregisterSystemState( - IN PVOID StateHandle); - - - -/** WMI library support routines **/ - -NTOSAPI -NTSTATUS -DDKAPI -WmiCompleteRequest( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN NTSTATUS Status, - IN ULONG BufferUsed, - IN CCHAR PriorityBoost); - -NTOSAPI -NTSTATUS -DDKAPI -WmiFireEvent( - IN PDEVICE_OBJECT DeviceObject, - IN LPGUID Guid, - IN ULONG InstanceIndex, - IN ULONG EventDataSize, - IN PVOID EventData); - -NTOSAPI -NTSTATUS -DDKAPI -WmiQueryTraceInformation( - IN TRACE_INFORMATION_CLASS TraceInformationClass, - OUT PVOID TraceInformation, - IN ULONG TraceInformationLength, - OUT PULONG RequiredLength OPTIONAL, - IN PVOID Buffer OPTIONAL); - -NTOSAPI -NTSTATUS -DDKAPI -WmiSystemControl( - IN PWMILIB_CONTEXT WmiLibInfo, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - OUT PSYSCTL_IRP_DISPOSITION IrpDisposition); - -NTOSAPI -NTSTATUS -DDKCDECLAPI -WmiTraceMessage( - IN TRACEHANDLE LoggerHandle, - IN ULONG MessageFlags, - IN LPGUID MessageGuid, - IN USHORT MessageNumber, - IN ...); - -#if 0 -/* FIXME: Get va_list from where? */ -NTOSAPI -NTSTATUS -DDKCDECLAPI -WmiTraceMessageVa( - IN TRACEHANDLE LoggerHandle, - IN ULONG MessageFlags, - IN LPGUID MessageGuid, - IN USHORT MessageNumber, - IN va_list MessageArgList); -#endif - - -/** Kernel debugger routines **/ - -NTOSAPI -VOID -DDKAPI -KdDisableDebugger( - VOID); - -NTOSAPI -VOID -DDKAPI -KdEnableDebugger( - VOID); - -NTOSAPI -VOID -DDKAPI -DbgBreakPoint( - VOID); - -NTOSAPI -VOID -DDKAPI -DbgBreakPointWithStatus( - IN ULONG Status); - -NTOSAPI -ULONG -DDKCDECLAPI -DbgPrint( - IN PCH Format, - IN ...); - -NTOSAPI -ULONG -DDKCDECLAPI -DbgPrintEx( - IN ULONG ComponentId, - IN ULONG Level, - IN PCH Format, - IN ...); - -NTOSAPI -ULONG -DDKCDECLAPI -DbgPrintReturnControlC( - IN PCH Format, - IN ...); - -NTOSAPI -NTSTATUS -DDKAPI -DbgQueryDebugFilterState( - IN ULONG ComponentId, - IN ULONG Level); - -NTOSAPI -NTSTATUS -DDKAPI -DbgSetDebugFilterState( - IN ULONG ComponentId, - IN ULONG Level, - IN BOOLEAN State); - -#if DBG - -#define KdPrint(_x_) DbgPrint _x_ -#define KdPrintEx(_x_) DbgPrintEx _x_ -#define KdBreakPoint() DbgBreakPoint() -#define KdBreakPointWithStatus(s) DbgBreakPointWithStatus(s) - -#else /* !DBG */ - -#define KdPrint(_x_) -#define KdPrintEx(_x_) -#define KdBreakPoint() -#define KdBreakPointWithStatus(s) - -#endif /* !DBG */ - -extern NTOSAPI PBOOLEAN KdDebuggerNotPresent; -extern NTOSAPI PBOOLEAN KdDebuggerEnabled; -#define KD_DEBUGGER_ENABLED *KdDebuggerEnabled -#define KD_DEBUGGER_NOT_PRESENT *KdDebuggerNotPresent - -#pragma pack(pop) - -#ifdef __cplusplus -} -#endif - -#endif /* __WINDDK_H */ diff --git a/src/platform/visualc/winnt4.h b/src/platform/visualc/winnt4.h deleted file mode 100644 index bbe8daf5..00000000 --- a/src/platform/visualc/winnt4.h +++ /dev/null @@ -1,608 +0,0 @@ -/* - * winnt4.h - * - * Definitions only used in Windows NT 4.0 and earlier versions - * - * This file is part of the w32api package. - * - * Contributors: - * Created by Casper S. Hornstrup - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - */ - -#ifndef __WINNT4_H -#define __WINNT4_H - -#if __GNUC__ >=3 -#pragma GCC system_header -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#pragma pack(push,4) - -typedef struct _ZONE_SEGMENT_HEADER { - SINGLE_LIST_ENTRY SegmentList; - PVOID Reserved; -} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER; - -typedef struct _ZONE_HEADER { - SINGLE_LIST_ENTRY FreeList; - SINGLE_LIST_ENTRY SegmentList; - ULONG BlockSize; - ULONG TotalSegmentSize; -} ZONE_HEADER, *PZONE_HEADER; - -static inline PVOID -ExAllocateFromZone( - IN PZONE_HEADER Zone) -{ - if (Zone->FreeList.Next) - Zone->FreeList.Next = Zone->FreeList.Next->Next; - return (PVOID) Zone->FreeList.Next; -} - -NTOSAPI -NTSTATUS -DDKAPI -ExExtendZone( - IN PZONE_HEADER Zone, - IN PVOID Segment, - IN ULONG SegmentSize); - -static inline PVOID -ExFreeToZone( - IN PZONE_HEADER Zone, - IN PVOID Block) -{ - ((PSINGLE_LIST_ENTRY) Block)->Next = Zone->FreeList.Next; - Zone->FreeList.Next = ((PSINGLE_LIST_ENTRY) Block); - return ((PSINGLE_LIST_ENTRY) Block)->Next; -} - -NTOSAPI -NTSTATUS -DDKAPI -ExInitializeZone( - IN PZONE_HEADER Zone, - IN ULONG BlockSize, - IN PVOID InitialSegment, - IN ULONG InitialSegmentSize); - -/* - * PVOID - * ExInterlockedAllocateFromZone( - * IN PZONE_HEADER Zone, - * IN PKSPIN_LOCK Lock) - */ -#define ExInterlockedAllocateFromZone(Zone, \ - Lock) \ - ((PVOID) ExInterlockedPopEntryList(&Zone->FreeList, Lock)) - -NTOSAPI -NTSTATUS -DDKAPI -ExInterlockedExtendZone( - IN PZONE_HEADER Zone, - IN PVOID Segment, - IN ULONG SegmentSize, - IN PKSPIN_LOCK Lock); - -NTOSAPI -PVOID -DDKAPI -ExInterlockedFreeToZone( - IN PZONE_HEADER Zone, - IN PVOID Block, - IN PKSPIN_LOCK Lock); - -/* - * VOID - * ExInitializeWorkItem( - * IN PWORK_QUEUE_ITEM Item, - * IN PWORKER_THREAD_ROUTINE Routine, - * IN PVOID Context) - */ -#define ExInitializeWorkItem(Item, \ - Routine, \ - Context) \ -{ \ - (Item)->WorkerRoutine = Routine; \ - (Item)->Parameter = Context; \ - (Item)->List.Flink = NULL; \ -} - -/* - * BOOLEAN - * ExIsFullZone( - * IN PZONE_HEADER Zone) - */ -#define ExIsFullZone(Zone) \ - ((Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY) NULL) - -NTOSAPI -VOID -DDKAPI -ExQueueWorkItem( - IN PWORK_QUEUE_ITEM WorkItem, - IN WORK_QUEUE_TYPE QueueType); - -NTOSAPI -BOOLEAN -DDKAPI -ExIsObjectInFirstZoneSegment( - IN PZONE_HEADER Zone, - IN PVOID Object); - -NTOSAPI -VOID -DDKAPI -ExReleaseResource( - IN PERESOURCE Resource); - -#define ExAcquireResourceExclusive ExAcquireResourceExclusiveLite -#define ExAcquireResourceShared ExAcquireResourceSharedLite -#define ExConvertExclusiveToShared ExConvertExclusiveToSharedLite -#define ExDeleteResource ExDeleteResourceLite -#define ExInitializeResource ExInitializeResourceLite -#define ExIsResourceAcquiredExclusive ExIsResourceAcquiredExclusiveLite -#define ExIsResourceAcquiredShared ExIsResourceAcquiredSharedLite -#define ExIsResourceAcquired ExIsResourceAcquiredSharedLite -#define ExReleaseResourceForThread ExReleaseResourceForThreadLite - -NTOSAPI -INTERLOCKED_RESULT -DDKAPI -ExInterlockedDecrementLong( - IN PLONG Addend, - IN PKSPIN_LOCK Lock); - -NTOSAPI -ULONG -DDKAPI -ExInterlockedExchangeUlong( - IN PULONG Target, - IN ULONG Value, - IN PKSPIN_LOCK Lock); - -NTOSAPI -INTERLOCKED_RESULT -DDKAPI -ExInterlockedIncrementLong( - IN PLONG Addend, - IN PKSPIN_LOCK Lock); - -NTOSAPI -PVOID -DDKAPI -HalAllocateCommonBuffer( - IN PADAPTER_OBJECT AdapterObject, - IN ULONG Length, - OUT PPHYSICAL_ADDRESS LogicalAddress, - IN BOOLEAN CacheEnabled); - -NTOSAPI -NTSTATUS -DDKAPI -HalAssignSlotResources( - IN PUNICODE_STRING RegistryPath, - IN PUNICODE_STRING DriverClassName, - IN PDRIVER_OBJECT DriverObject, - IN PDEVICE_OBJECT DeviceObject, - IN INTERFACE_TYPE BusType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN OUT PCM_RESOURCE_LIST *AllocatedResources); - -NTOSAPI -VOID -DDKAPI -HalFreeCommonBuffer( - IN PADAPTER_OBJECT AdapterObject, - IN ULONG Length, - IN PHYSICAL_ADDRESS LogicalAddress, - IN PVOID VirtualAddress, - IN BOOLEAN CacheEnabled); - -NTOSAPI -PADAPTER_OBJECT -DDKAPI -HalGetAdapter( - IN PDEVICE_DESCRIPTION DeviceDescription, - IN OUT PULONG NumberOfMapRegisters); - -NTOSAPI -ULONG -DDKAPI -HalGetBusData( - IN BUS_DATA_TYPE BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN PVOID Buffer, - IN ULONG Length); - -NTOSAPI -ULONG -DDKAPI -HalGetBusDataByOffset( - IN BUS_DATA_TYPE BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN PVOID Buffer, - IN ULONG Offset, - IN ULONG Length); - -NTOSAPI -ULONG -DDKAPI -HalGetDmaAlignmentRequirement( - VOID); - -NTOSAPI -ULONG -DDKAPI -HalGetInterruptVector( - IN INTERFACE_TYPE InterfaceType, - IN ULONG BusNumber, - IN ULONG BusInterruptLevel, - IN ULONG BusInterruptVector, - OUT PKIRQL Irql, - OUT PKAFFINITY Affinity); - -NTOSAPI -ULONG -DDKAPI -HalReadDmaCounter( - IN PADAPTER_OBJECT AdapterObject); - -NTOSAPI -ULONG -DDKAPI -HalSetBusData( - IN BUS_DATA_TYPE BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN PVOID Buffer, - IN ULONG Length); - -NTOSAPI -ULONG -DDKAPI -HalSetBusDataByOffset( - IN BUS_DATA_TYPE BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN PVOID Buffer, - IN ULONG Offset, - IN ULONG Length); - -NTOSAPI -BOOLEAN -DDKAPI -HalTranslateBusAddress( - IN INTERFACE_TYPE InterfaceType, - IN ULONG BusNumber, - IN PHYSICAL_ADDRESS BusAddress, - IN OUT PULONG AddressSpace, - OUT PPHYSICAL_ADDRESS TranslatedAddress); - -NTOSAPI -NTSTATUS -DDKAPI -IoAllocateAdapterChannel( - IN PADAPTER_OBJECT AdapterObject, - IN PDEVICE_OBJECT DeviceObject, - IN ULONG NumberOfMapRegisters, - IN PDRIVER_CONTROL ExecutionRoutine, - IN PVOID Context); - -NTOSAPI -NTSTATUS -DDKAPI -IoAssignResources( - IN PUNICODE_STRING RegistryPath, - IN PUNICODE_STRING DriverClassName OPTIONAL, - IN PDRIVER_OBJECT DriverObject, - IN PDEVICE_OBJECT DeviceObject OPTIONAL, - IN PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources, - IN OUT PCM_RESOURCE_LIST *AllocatedResources); - -NTOSAPI -NTSTATUS -DDKAPI -IoAttachDeviceByPointer( - IN PDEVICE_OBJECT SourceDevice, - IN PDEVICE_OBJECT TargetDevice); - -NTOSAPI -BOOLEAN -DDKAPI -IoFlushAdapterBuffers( - IN PADAPTER_OBJECT AdapterObject, - IN PMDL Mdl, - IN PVOID MapRegisterBase, - IN PVOID CurrentVa, - IN ULONG Length, - IN BOOLEAN WriteToDevice); - -NTOSAPI -VOID -DDKAPI -IoFreeAdapterChannel( - IN PADAPTER_OBJECT AdapterObject); - -NTOSAPI -VOID -DDKAPI -IoFreeMapRegisters( - IN PADAPTER_OBJECT AdapterObject, - IN PVOID MapRegisterBase, - IN ULONG NumberOfMapRegisters); - -NTOSAPI -PHYSICAL_ADDRESS -DDKAPI -IoMapTransfer( - IN PADAPTER_OBJECT AdapterObject, - IN PMDL Mdl, - IN PVOID MapRegisterBase, - IN PVOID CurrentVa, - IN OUT PULONG Length, - IN BOOLEAN WriteToDevice); - -NTOSAPI -PMDL -DDKAPI -MmCreateMdl( - IN PMDL MemoryDescriptorList OPTIONAL, - IN PVOID Base, - IN SIZE_T Length); - -NTOSAPI -BOOLEAN -DDKAPI -MmIsNonPagedSystemAddressValid( - IN PVOID VirtualAddress); - -NTOSAPI -LARGE_INTEGER -DDKAPI -RtlEnlargedIntegerMultiply( - IN LONG Multiplicand, - IN LONG Multiplier); - -NTOSAPI -ULONG -DDKAPI -RtlEnlargedUnsignedDivide( - IN ULARGE_INTEGER Dividend, - IN ULONG Divisor, - IN OUT PULONG Remainder); - -NTOSAPI -LARGE_INTEGER -DDKAPI -RtlEnlargedUnsignedMultiply( - IN ULONG Multiplicand, - IN ULONG Multiplier); - -NTOSAPI -LARGE_INTEGER -DDKAPI -RtlExtendedIntegerMultiply( - IN LARGE_INTEGER Multiplicand, - IN LONG Multiplier); - -NTOSAPI -LARGE_INTEGER -DDKAPI -RtlExtendedLargeIntegerDivide( - IN LARGE_INTEGER Dividend, - IN ULONG Divisor, - IN OUT PULONG Remainder); - -NTOSAPI -LARGE_INTEGER -DDKAPI -RtlExtendedMagicDivide( - IN LARGE_INTEGER Dividend, - IN LARGE_INTEGER MagicDivisor, - IN CCHAR ShiftCount); - -NTOSAPI -LARGE_INTEGER -DDKAPI -RtlLargeIntegerAdd( - IN LARGE_INTEGER Addend1, - IN LARGE_INTEGER Addend2); - -NTOSAPI -VOID -DDKAPI -RtlLargeIntegerAnd( - IN OUT LARGE_INTEGER Result, - IN LARGE_INTEGER Source, - IN LARGE_INTEGER Mask); - -NTOSAPI -LARGE_INTEGER -DDKAPI -RtlLargeIntegerArithmeticShift( - IN LARGE_INTEGER LargeInteger, - IN CCHAR ShiftCount); - -NTOSAPI -LARGE_INTEGER -DDKAPI -RtlLargeIntegerDivide( - IN LARGE_INTEGER Dividend, - IN LARGE_INTEGER Divisor, - IN OUT PLARGE_INTEGER Remainder); - -NTOSAPI -BOOLEAN -DDKAPI -RtlLargeIntegerEqualTo( - IN LARGE_INTEGER Operand1, - IN LARGE_INTEGER Operand2); - -NTOSAPI -BOOLEAN -DDKAPI -RtlLargeIntegerEqualToZero( - IN LARGE_INTEGER Operand); - -NTOSAPI -BOOLEAN -DDKAPI -RtlLargeIntegerGreaterOrEqualToZero( - IN LARGE_INTEGER Operand); - -NTOSAPI -BOOLEAN -DDKAPI -RtlLargeIntegerGreaterThan( - IN LARGE_INTEGER Operand1, - IN LARGE_INTEGER Operand2); - -NTOSAPI -BOOLEAN -DDKAPI -RtlLargeIntegerGreaterThanOrEqualTo( - IN LARGE_INTEGER Operand1, - IN LARGE_INTEGER Operand2); - -NTOSAPI -BOOLEAN -DDKAPI -RtlLargeIntegerGreaterThanZero( - IN LARGE_INTEGER Operand); - -NTOSAPI -BOOLEAN -DDKAPI -RtlLargeIntegerLessOrEqualToZero( - IN LARGE_INTEGER Operand); - -NTOSAPI -BOOLEAN -DDKAPI -RtlLargeIntegerLessThan( - IN LARGE_INTEGER Operand1, - IN LARGE_INTEGER Operand2); - -NTOSAPI -BOOLEAN -DDKAPI -RtlLargeIntegerLessThanOrEqualTo( - IN LARGE_INTEGER Operand1, - IN LARGE_INTEGER Operand2); - -NTOSAPI -BOOLEAN -DDKAPI -RtlLargeIntegerLessThanZero( - IN LARGE_INTEGER Operand); - -NTOSAPI -LARGE_INTEGER -DDKAPI -RtlLargeIntegerNegate( - IN LARGE_INTEGER Subtrahend); - -NTOSAPI -BOOLEAN -DDKAPI -RtlLargeIntegerNotEqualTo( - IN LARGE_INTEGER Operand1, - IN LARGE_INTEGER Operand2); - -NTOSAPI -BOOLEAN -DDKAPI -RtlLargeIntegerNotEqualToZero( - IN LARGE_INTEGER Operand); - -NTOSAPI -LARGE_INTEGER -DDKAPI -RtlLargeIntegerShiftLeft( - IN LARGE_INTEGER LargeInteger, - IN CCHAR ShiftCount); - -NTOSAPI -LARGE_INTEGER -DDKAPI -RtlLargeIntegerShiftRight( - IN LARGE_INTEGER LargeInteger, - IN CCHAR ShiftCount); - -NTOSAPI -LARGE_INTEGER -DDKAPI -RtlLargeIntegerSubtract( - IN LARGE_INTEGER Minuend, - IN LARGE_INTEGER Subtrahend); - - -/* - * ULONG - * COMPUTE_PAGES_SPANNED( - * IN PVOID Va, - * IN ULONG Size) - */ -#define COMPUTE_PAGES_SPANNED(Va, \ - Size) \ - (ADDRESS_AND_SIZE_TO_SPAN_PAGES(Va, Size)) - - -/* -** Architecture specific structures -*/ - -#ifdef _X86_ - -NTOSAPI -INTERLOCKED_RESULT -DDKFASTAPI -Exfi386InterlockedIncrementLong( - IN PLONG Addend); - -NTOSAPI -INTERLOCKED_RESULT -DDKFASTAPI -Exfi386InterlockedDecrementLong( - IN PLONG Addend); - -NTOSAPI -ULONG -DDKFASTAPI -Exfi386InterlockedExchangeUlong( - IN PULONG Target, - IN ULONG Value); - -#define ExInterlockedIncrementLong(Addend,Lock) Exfi386InterlockedIncrementLong(Addend) -#define ExInterlockedDecrementLong(Addend,Lock) Exfi386InterlockedDecrementLong(Addend) -#define ExInterlockedExchangeUlong(Target, Value, Lock) Exfi386InterlockedExchangeUlong(Target, Value) - -#endif /* _X86_ */ - -#pragma pack(pop) - -#ifdef __cplusplus -} -#endif - -#endif /* __WINNT4_H */ diff --git a/src/platform/visualc/winxp.h b/src/platform/visualc/winxp.h deleted file mode 100644 index 28e34a89..00000000 --- a/src/platform/visualc/winxp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * winxp.h - * - * Definitions only used in Windows XP and earlier versions - * - * This file is part of the w32api package. - * - * Contributors: - * Created by Casper S. Hornstrup - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - */ - -#ifndef __WINXP_H -#define __WINXP_H - -#if __GNUC__ >=3 -#pragma GCC system_header -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __WINXP_H */ From 896f3fa1b9b314856e78ce5787bfcba09e40849d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 2 Jan 2004 23:43:52 +0000 Subject: [PATCH 1452/4131] fix header include differences between mingw and visual c Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1533 --- src/dos/cdrom_aspi_win32.cpp | 16 +++++++++++----- src/dos/cdrom_ioctl_win32.cpp | 11 ++++++++--- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index 1787e8af..156b25e2 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_aspi_win32.cpp,v 1.8 2004-01-02 23:10:31 finsterr Exp $ */ +/* $Id: cdrom_aspi_win32.cpp,v 1.9 2004-01-02 23:43:52 harekiet Exp $ */ #if defined (WIN32) @@ -27,11 +27,17 @@ //Are actually system includes but leave for now #include "wnaspi32.h" -#include "ntddcdrm.h" -#include "ntddscsi.h" -#include "scsidefs.h" -#include +#if defined (_MSC_VER) +#include // Ioctl stuff +#include +#include // Ioctl stuff +#else +#include "ddk/ntddcdrm.h" // Ioctl stuff +#include "ddk/ntddscsi.h" +#endif + +#include "scsidefs.h" // ***************************************************************** // Windows ASPI functions (should work for all WIN with ASPI layer) diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index fda4e124..a3ef30f5 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_ioctl_win32.cpp,v 1.8 2004-01-02 23:10:31 finsterr Exp $ */ +/* $Id: cdrom_ioctl_win32.cpp,v 1.9 2004-01-02 23:43:52 harekiet Exp $ */ #if defined (WIN32) @@ -25,10 +25,15 @@ // ***************************************************************** #include -#include // Ioctl stuff #include -#include "ntddcdrm.h" // Ioctl stuff +#if defined (_MSC_VER) +#include // Ioctl stuff +#include // Ioctl stuff +#else +#include "ddk/ntddcdrm.h" // Ioctl stuff +#endif + #include "cdrom.h" CDROM_Interface_Ioctl::CDROM_Interface_Ioctl() From 395d712a2354eb6a7a31c1450592b1baac1ec49d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 3 Jan 2004 10:33:09 +0000 Subject: [PATCH 1453/4131] Added exception checking for pmode segment loads Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1534 --- src/cpu/core_dyn_x86/decoder.h | 43 +++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 98bc9d57..914aed57 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -566,6 +566,33 @@ static void dyn_mov_ev_seg(void) { gen_releasereg(DREG(TMPW)); } +static void dyn_load_seg(SegNames seg,DynReg * src,bool withpop) { + if (cpu.pmode) { + Bit8u * branch;DynState state; + gen_storeflags(); + gen_call_function((void *)&CPU_SetSegGeneral,"%Rd%Id%Drw",DREG(TMPW),seg,src); + gen_dop_word(DOP_OR,true,DREG(TMPW),DREG(TMPW)); + branch=gen_create_branch(BR_Z); + dyn_savestate(&state); + dyn_reduce_cycles(); + if (withpop) gen_dop_word_imm(DOP_SUB,true,DREG(ESP),decode.big_op ? 4 : 2); + gen_dop_word_imm(DOP_ADD,true,DREG(EIP),decode.op_start-decode.code_start); + dyn_save_flags(true); + dyn_releaseregs(); + gen_call_function((void *)&CPU_StartException,""); + dyn_load_flags(); + gen_return(BR_Normal); + dyn_loadstate(&state); + gen_fill_branch(branch); + gen_restoreflags(); + } else { + //TODO Maybe just calculate the base directly if in realmode + gen_call_function((void *)&CPU_SetSegGeneral,"%Id%Drw",seg,src); + } + gen_releasereg(&DynRegs[G_ES+seg]); + if (seg==ss) gen_releasereg(DREG(SMASK)); +} + static void dyn_mov_seg_ev(void) { dyn_get_modrm(); SegNames seg=(SegNames)decode.modrm.reg; @@ -573,15 +600,13 @@ static void dyn_mov_seg_ev(void) { if (decode.modrm.mod<3) { dyn_fill_ea(); dyn_read_word(DREG(EA),DREG(EA),false); - gen_call_function((void *)&CPU_SetSegGeneral,"%Id%Drw",seg,DREG(EA)); + dyn_load_seg(seg,DREG(EA),false); + gen_releasereg(DREG(EA)); } else { - gen_call_function((void *)&CPU_SetSegGeneral,"%Id%Dw",seg,&DynRegs[decode.modrm.rm]); + dyn_load_seg(seg,&DynRegs[decode.modrm.rm],false); } - gen_releasereg(&DynRegs[G_ES+seg]); - if (seg==ss) gen_releasereg(DREG(SMASK)); } - static void dyn_push_seg(SegNames seg) { gen_load_host(&Segs.val[seg],DREG(TMPW),2); dyn_push(DREG(TMPW)); @@ -591,9 +616,8 @@ static void dyn_push_seg(SegNames seg) { static void dyn_pop_seg(SegNames seg) { gen_storeflags(); dyn_pop(DREG(TMPW)); - gen_call_function((void*)&CPU_SetSegGeneral,"%Id%Drw",seg,DREG(TMPW)); - gen_releasereg(&DynRegs[G_ES+seg]); - if (seg==ss) gen_releasereg(DREG(SMASK)); + dyn_load_seg(seg,DREG(TMPW),true); + gen_releasereg(DREG(TMPW)); gen_restoreflags(); } @@ -1088,8 +1112,9 @@ restart_prefix: //GRP2 Eb/Ev,CL case 0xd2:dyn_grp2_eb(grp2_cl);break; case 0xd3:dyn_grp2_ev(grp2_cl);break; - //IN AL/AX,imm + //Loop's case 0xe2:dyn_loop(LOOP_NONE);return decode.block; + //IN AL/AX,imm case 0xe4:gen_call_function((void*)&IO_ReadB,"%Id%Rl",decode_fetchb(),DREG(EAX));break; case 0xe5: if (decode.big_op) { From 01017af2aee96432cdad0b2eff7efc1e006a58bd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 6 Jan 2004 10:59:34 +0000 Subject: [PATCH 1454/4131] added visualc_net Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1535 --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index cb2acfbb..bfb4714a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ # Main Makefile for DOSBox EXTRA_DIST = autogen.sh -SUBDIRS = src include visualc docs +SUBDIRS = src include visualc docs visualc_net From ca97ad9560a71f44d928129716e070d5ec6ad13a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 6 Jan 2004 11:21:58 +0000 Subject: [PATCH 1455/4131] removed shell_inc.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1536 --- src/shell/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/Makefile.am b/src/shell/Makefile.am index a9476e9d..06f8c5f1 100644 --- a/src/shell/Makefile.am +++ b/src/shell/Makefile.am @@ -1,4 +1,4 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libshell.a -libshell_a_SOURCES = shell.cpp shell_batch.cpp shell_cmds.cpp shell_inc.h shell_misc.cpp +libshell_a_SOURCES = shell.cpp shell_batch.cpp shell_cmds.cpp shell_misc.cpp From 75229246409ea336b528c52af41171992286d9f0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 6 Jan 2004 11:23:32 +0000 Subject: [PATCH 1456/4131] added shell.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1537 --- include/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/include/Makefile.am b/include/Makefile.am index 49e67147..d0ec949f 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -26,6 +26,7 @@ regs.h \ render.h \ serialport.h \ setup.h \ +shell.h \ support.h \ timer.h \ vga.h \ From d17fccc9b9d358a67a9c3a499befa4acdec40e5e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 6 Jan 2004 20:47:42 +0000 Subject: [PATCH 1457/4131] add shld/shrd opcodes fix pmode segment sets Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1538 --- src/cpu/core_dyn_x86/decoder.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 914aed57..c82b1b4c 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -570,8 +570,8 @@ static void dyn_load_seg(SegNames seg,DynReg * src,bool withpop) { if (cpu.pmode) { Bit8u * branch;DynState state; gen_storeflags(); - gen_call_function((void *)&CPU_SetSegGeneral,"%Rd%Id%Drw",DREG(TMPW),seg,src); - gen_dop_word(DOP_OR,true,DREG(TMPW),DREG(TMPW)); + gen_call_function((void *)&CPU_SetSegGeneral,"%Rd%Id%Drw",DREG(TMPB),seg,src); + gen_dop_byte(DOP_OR,DREG(TMPB),0,DREG(TMPB),0); branch=gen_create_branch(BR_Z); dyn_savestate(&state); dyn_reduce_cycles(); @@ -893,6 +893,12 @@ restart_prefix: dyn_branched_exit((BranchTypes)(dual_code&0xf), decode.big_op ? (Bit32s)decode_fetchd() : (Bit16s)decode_fetchw()); return decode.block; + /* SHLD Imm/cl*/ + case 0xa4:dyn_dshift_ev_gv(true,true);break; + case 0xa5:dyn_dshift_ev_gv(true,false);break; + /* SHRD Imm/cl*/ + case 0xac:dyn_dshift_ev_gv(false,true);break; + case 0xad:dyn_dshift_ev_gv(false,false);break; default: DYN_LOG("Unhandled dual opcode 0F%02X",dual_code); goto illegalopcode; From 7b3747769cf1173fff73e9a53260c2807d9c8caf Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 6 Jan 2004 20:48:21 +0000 Subject: [PATCH 1458/4131] fix double shift gen functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1539 --- src/cpu/core_dyn_x86/risc_x86.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 9aee4335..b6d7d8e8 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -498,19 +498,19 @@ static void gen_dshift_imm(bool dword,bool left,DynReg * dr1,DynReg * dr2,Bitu i if (!dword) cache_addb(0x66); if (left) cache_addw(0xa40f); //SHLD IMM else cache_addw(0xac0f); //SHRD IMM - cache_addb(0xc0+gr1->index+(gr2->index<<8)); + cache_addb(0xc0+gr1->index+(gr2->index<<3)); cache_addb(imm); dr1->flags|=DYNFLG_CHANGED; } static void gen_dshift_cl(bool dword,bool left,DynReg * dr1,DynReg * dr2,DynReg * drecx) { + ForceDynReg(x86gen.regs[X86_REG_ECX],drecx); GenReg * gr1=FindDynReg(dr1); GenReg * gr2=FindDynReg(dr2); - ForceDynReg(x86gen.regs[X86_REG_ECX],drecx); if (!dword) cache_addb(0x66); if (left) cache_addw(0xa50f); //SHLD CL else cache_addw(0xad0f); //SHRD CL - cache_addb(0xc0+gr1->index+(gr2->index<<8)); + cache_addb(0xc0+gr1->index+(gr2->index<<3)); dr1->flags|=DYNFLG_CHANGED; } From c663205a59f591629a787d427e0f7929aac4ee34 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 7 Jan 2004 12:18:58 +0000 Subject: [PATCH 1459/4131] fixed pharlab keyboard issues (hopefully) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1540 --- src/hardware/keyboard.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 8f60f903..f3bf93be 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: keyboard.cpp,v 1.18 2004-01-07 12:18:58 qbix79 Exp $ */ + #include #include "dosbox.h" #include "keyboard.h" @@ -66,6 +68,7 @@ struct KeyBlock { bool enabled; bool active; bool scheduled; + bool key_on_60; }; static KeyBlock keyb; @@ -79,6 +82,7 @@ void KEYBOARD_ClrBuffer(void) { keyb.buf.pos=0; keyb.scheduled=false; PIC_DeActivateIRQ(1); + keyb.key_on_60=false; } /* Read an entry from the keycode buffer */ @@ -97,6 +101,7 @@ void KEYBOARD_GetCode(void) { keyb.buf.state=STATE_NORMAL; break; } + keyb.key_on_60=true; if (keyb.enabled) PIC_ActivateIRQ(1); } @@ -253,7 +258,9 @@ static void write_p64(Bit32u port,Bit8u val) { } static Bit8u read_p64(Bit32u port) { - return 0x1c | (keyb.buf.used ? 0x1 : 0x0); + Bit8u status= 0x1c | ((keyb.buf.used ||keyb.key_on_60)? 0x1 : 0x0); + keyb.key_on_60=false; + return status; } void KEYBOARD_AddEvent(Bitu keytype,Bitu state,KEYBOARD_EventHandler * handler) { @@ -421,5 +428,6 @@ void KEYBOARD_Init(Section* sec) { keyb.enabled=true; keyb.command=CMD_NONE; keyb.last_index=0; + keyb.key_on_60=false; KEYBOARD_ClrBuffer(); } From df06393f6422ccafc6378cbed62b1ab238f685f5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 7 Jan 2004 16:10:01 +0000 Subject: [PATCH 1460/4131] Add IMUL Gv,Ev Add LES,LDS,LFS,LGS Add POP FS/GS PUSH FS/GS Add MOVZX/MOVSX Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1541 --- src/cpu/core_dyn_x86/decoder.h | 95 ++++++++++++++++++++++++++++++++- src/cpu/core_dyn_x86/risc_x86.h | 41 ++++++++++++++ 2 files changed, 134 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index c82b1b4c..34318015 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -286,6 +286,24 @@ static void dyn_dop_evgv(DualOps op) { } } +static void dyn_imul_gvev(Bitu immsize) { + dyn_get_modrm();DynReg * src; + DynReg * rm_reg=&DynRegs[decode.modrm.reg]; + if (decode.modrm.mod<3) { + dyn_fill_ea();dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); + src=DREG(TMPW);gen_releasereg(DREG(EA)); + } else { + src=&DynRegs[decode.modrm.rm]; + } + switch (immsize) { + case 0:gen_imul_word(decode.big_op,rm_reg,src);break; + case 1:gen_imul_word_imm(decode.big_op,rm_reg,src,(Bit8s)decode_fetchb());break; + case 2:gen_imul_word_imm(decode.big_op,rm_reg,src,(Bit16s)decode_fetchw());break; + case 4:gen_imul_word_imm(decode.big_op,rm_reg,src,(Bit32s)decode_fetchd());break; + } + gen_releasereg(DREG(TMPW)); +} + static void dyn_dop_gvev(DualOps op) { dyn_get_modrm(); DynReg * rm_reg=&DynRegs[decode.modrm.reg]; @@ -334,6 +352,34 @@ static void dyn_mov_eviv(void) { } } +static void dyn_mov_ev_gb(bool sign) { + dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg]; + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_read_byte(DREG(EA),DREG(TMPB),false); + gen_releasereg(DREG(EA)); + gen_extend_byte(sign,decode.big_op,rm_reg,DREG(TMPB),0); + } else { + gen_extend_byte(sign,decode.big_op,rm_reg,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); + } +} + +static void dyn_mov_ev_gw(bool sign) { + if (!decode.big_op) { + dyn_mov_evgv(); + return; + } + dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg]; + if (decode.modrm.mod<3) { + dyn_fill_ea(); + dyn_read_word(DREG(EA),DREG(TMPW),false); + gen_releasereg(DREG(EA)); + gen_extend_word(sign,rm_reg,DREG(TMPW)); + } else { + gen_extend_word(sign,rm_reg,&DynRegs[decode.modrm.rm]); + } +} + static void dyn_dshift_ev_gv(bool left,bool immediate) { dyn_get_modrm(); DynReg * rm_reg=&DynRegs[decode.modrm.reg]; @@ -552,7 +598,6 @@ skipsave: gen_releasereg(DREG(TMPW));gen_releasereg(DREG(EA)); } - static void dyn_mov_ev_seg(void) { dyn_get_modrm(); gen_load_host(&Segs.val[decode.modrm.reg],DREG(TMPW),2); @@ -593,6 +638,20 @@ static void dyn_load_seg(SegNames seg,DynReg * src,bool withpop) { if (seg==ss) gen_releasereg(DREG(SMASK)); } +static void dyn_load_seg_off_ea(SegNames seg) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(); + gen_lea(DREG(TMPW),DREG(EA),0,0,decode.big_op ? 4:2); + dyn_read_word(DREG(TMPW),DREG(TMPW),false); + dyn_load_seg(seg,DREG(TMPW),false); + dyn_read_word(DREG(EA),&DynRegs[decode.modrm.reg],decode.big_op); + gen_releasereg(DREG(EA)); + } else { + IllegalOption(); + } +} + static void dyn_mov_seg_ev(void) { dyn_get_modrm(); SegNames seg=(SegNames)decode.modrm.reg; @@ -893,12 +952,30 @@ restart_prefix: dyn_branched_exit((BranchTypes)(dual_code&0xf), decode.big_op ? (Bit32s)decode_fetchd() : (Bit16s)decode_fetchw()); return decode.block; + /* PUSH/POP FS */ + case 0xa0:dyn_push_seg(fs);break; + case 0xa1:dyn_pop_seg(fs);break; /* SHLD Imm/cl*/ case 0xa4:dyn_dshift_ev_gv(true,true);break; case 0xa5:dyn_dshift_ev_gv(true,false);break; + /* PUSH/POP GS */ + case 0xa8:dyn_push_seg(gs);break; + case 0xa9:dyn_pop_seg(gs);break; /* SHRD Imm/cl*/ case 0xac:dyn_dshift_ev_gv(false,true);break; - case 0xad:dyn_dshift_ev_gv(false,false);break; + case 0xad:dyn_dshift_ev_gv(false,false);break; + /* Imul Ev,Gv */ + case 0xaf:dyn_imul_gvev(0);break; + /* LFS,LGS */ + case 0xb4:dyn_load_seg_off_ea(fs);break; + case 0xb5:dyn_load_seg_off_ea(gs);break; + /* MOVZX Gv,Eb/Ew */ + case 0xb6:dyn_mov_ev_gb(false);break; + case 0xb7:dyn_mov_ev_gw(false);break; + /* MOVSX Gv,Eb/Ew */ + case 0xbe:dyn_mov_ev_gb(true);break; + case 0xbf:dyn_mov_ev_gw(true);break; + default: DYN_LOG("Unhandled dual opcode 0F%02X",dual_code); goto illegalopcode; @@ -1002,11 +1079,15 @@ restart_prefix: dyn_push(DREG(TMPW)); gen_releasereg(DREG(TMPW)); break; + /* Imul Ivx */ + case 0x69:dyn_imul_gvev(decode.big_op ? 4 : 2);break; case 0x6a: /* PUSH Ibx */ gen_dop_word_imm(DOP_MOV,true,DREG(TMPW),(Bit8s)decode_fetchb()); dyn_push(DREG(TMPW)); gen_releasereg(DREG(TMPW)); break; + /* Imul Ibx */ + case 0x6b:dyn_imul_gvev(1);break; /* 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: @@ -1049,8 +1130,15 @@ restart_prefix: break; /* CBW/CWDE */ case 0x98: + /* if (decode.big_op) gen_extend_word(true,DREG(EAX),DREG(EAX)); else gen_extend_byte(true,false,DREG(EAX),DREG(EAX),0); + */ + gen_cbw(decode.big_op,DREG(EAX)); + break; + /* CWD/CDQ */ + case 0x99: + gen_cwd(decode.big_op,DREG(EAX),DREG(EDX)); break; /* CALL FAR Ip */ case 0x9a:dyn_call_far_imm();return decode.block; @@ -1100,6 +1188,9 @@ restart_prefix: //RET near Iw / Ret case 0xc2:dyn_ret_near(decode_fetchw());return decode.block; case 0xc3:dyn_ret_near(0);return decode.block; + //LES/LDS + case 0xc4:dyn_load_seg_off_ea(es);break; + case 0xc5:dyn_load_seg_off_ea(ds);break; // MOV Eb/Ev,Ib/Iv case 0xc6:dyn_mov_ebib();break; case 0xc7:dyn_mov_eviv();break; diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index b6d7d8e8..f540ce6a 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -423,6 +423,32 @@ static void gen_dop_word_imm(DualOps op,bool dword,DynReg * dr1,Bits imm) { if (dword) cache_addd(imm); else cache_addw(imm); } + +static void gen_imul_word(bool dword,DynReg * dr1,DynReg * dr2) { + GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2); + if (!dword) cache_addb(0x66); + cache_addw(0xaf0f); + cache_addb(0xc0+(gr1->index<<3)+gr2->index); + dr1->flags|=DYNFLG_CHANGED; +} + +static void gen_imul_word_imm(bool dword,DynReg * dr1,DynReg * dr2,Bits imm) { + GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2); + if (!dword) cache_addb(0x66); + if ((imm>=-128 && imm<=127)) { + cache_addb(0x6b); + cache_addb(0xc0+(gr1->index<<3)+gr2->index); + cache_addb(imm); + } else { + cache_addb(0x69); + cache_addb(0xc0+(gr1->index<<3)+gr2->index); + if (dword) cache_addd(imm); + else cache_addw(imm); + } + dr1->flags|=DYNFLG_CHANGED; +} + + static void gen_sop_word(SingleOps op,bool dword,DynReg * dr1) { GenReg * gr1=FindDynReg(dr1); if (!dword) cache_addb(0x66); @@ -472,6 +498,21 @@ static void gen_shift_word(ShiftOps op,DynReg * drecx,bool dword,DynReg * dr1) { dr1->flags|=DYNFLG_CHANGED; } +static void gen_cbw(bool dword,DynReg * dyn_ax) { + ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax); + if (!dword) cache_addb(0x66); + cache_addb(0x98); + dyn_ax->flags|=DYNFLG_CHANGED; +} + +static void gen_cwd(bool dword,DynReg * dyn_ax,DynReg * dyn_dx) { + ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax); + ForceDynReg(x86gen.regs[X86_REG_EDX],dyn_dx); + if (!dword) cache_addb(0x66); + cache_addb(0x99); + dyn_ax->flags|=DYNFLG_CHANGED; + dyn_dx->flags|=DYNFLG_CHANGED; +} static void gen_mul_byte(bool imul,DynReg * dyn_ax,DynReg * dr1,Bit8u di1) { ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax); From 05a4fc6daa48950c5cc18674740c4980c0efa0d3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 7 Jan 2004 20:23:48 +0000 Subject: [PATCH 1461/4131] Revectorred int 5c(wd) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1542 --- src/cpu/callback.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index e5a94cc0..ed9ffdfc 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.18 2003-11-18 20:46:01 harekiet Exp $ */ +/* $Id: callback.cpp,v 1.19 2004-01-07 20:23:48 qbix79 Exp $ */ #include #include @@ -234,6 +234,7 @@ void CALLBACK_Init(Section* sec) { } real_writed(0,0x67*4,CALLBACK_RealPointer(call_default)); + real_writed(0,0x5c*4,CALLBACK_RealPointer(call_default)); //Network stuff //real_writed(0,0xf*4,0); some games don't like it } From 926c1aab65d1efc373374586e91cdbc0771938b9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 7 Jan 2004 20:26:38 +0000 Subject: [PATCH 1462/4131] small typo (wd) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1543 --- src/ints/int10_vesa.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 644c45ae..621bc34d 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: int10_vesa.cpp,v 1.6 2004-01-07 20:26:38 qbix79 Exp $ */ + #include #include @@ -325,7 +327,7 @@ void INT10_SetupVESA(void) { int10.rom.oemstring=RealMake(0xc000,int10.rom.used); Bitu len=strlen(string_oem)+1; for (i=0;i Date: Wed, 7 Jan 2004 21:37:47 +0000 Subject: [PATCH 1463/4131] add option to select cpu core in config file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1544 --- src/cpu/cpu.cpp | 23 +++++++++++++++++++---- src/dosbox.cpp | 6 ++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 4a221399..6e5ea0b3 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.46 2004-01-01 12:26:08 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.47 2004-01-07 21:37:47 harekiet Exp $ */ #include #include "dosbox.h" @@ -26,6 +26,7 @@ #include "keyboard.h" #include "setup.h" #include "paging.h" +#include "support.h" Bitu DEBUG_EnableDebugger(void); @@ -1255,9 +1256,6 @@ void CPU_Init(Section* sec) { #if (C_DYNAMIC_X86) CPU_Core_Dyn_X86_Init(); #endif - cpudecoder=&startcpu_core; - - CPU_JMP(false,0,0); //Setup the first cpu core KEYBOARD_AddEvent(KBD_f11,KBD_MOD_CTRL,CPU_CycleDecrease); KEYBOARD_AddEvent(KBD_f12,KBD_MOD_CTRL,CPU_CycleIncrease); @@ -1266,6 +1264,23 @@ void CPU_Init(Section* sec) { CPU_CycleMax=section->Get_int("cycles");; CPU_CycleUp=section->Get_int("cycleup"); CPU_CycleDown=section->Get_int("cycledown"); + const char * core=section->Get_string("core"); + cpudecoder=&CPU_Core_Normal_Run; + if (!strcasecmp(core,"normal")) { + cpudecoder=&CPU_Core_Normal_Run; + } else if (!strcasecmp(core,"full")) { + cpudecoder=&CPU_Core_Full_Run; + } +#if (C_DYNAMIC_X86) + else if (!strcasecmp(core,"dynamic")) { + cpudecoder=&CPU_Core_Dyn_X86_Run; + } +#endif + else { + LOG_MSG("CPU:Unknown core type %s, switcing back to normal.",core); + } + CPU_JMP(false,0,0); //Setup the first cpu core + if (!CPU_CycleMax) CPU_CycleMax = 1800; if(!CPU_CycleUp) CPU_CycleUp = 500; if(!CPU_CycleDown) CPU_CycleDown = 20; diff --git a/src/dosbox.cpp b/src/dosbox.cpp index a518deb7..ea0d5053 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -221,10 +221,16 @@ void DOSBOX_Init(void) { ); secprop=control->AddSection_prop("cpu",&CPU_Init); + secprop->Add_string("core","normal"); secprop->Add_int("cycles",1800); secprop->Add_int("cycleup",500); secprop->Add_int("cycledown",20); MSG_Add("CPU_CONFIGFILE_HELP", + "core -- CPU Core used in emulation: normal,full" +#if (C_DYNAMIC_X86) + ",dynamic" +#endif + ".\n" "cycles -- Amount of instructions dosbox tries to emulate each millsecond.\n" " Setting this higher than your machine can handle is bad!\n" "cycleup -- Amount of cycles to increase/decrease with keycombo.\n" From eda2ee4b187f02cf9b9b740894579dfbc878ecbf Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 7 Jan 2004 22:22:36 +0000 Subject: [PATCH 1464/4131] increase horizontal retrace delay a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1545 --- src/hardware/vga_misc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 829398f8..2bbc6a77 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -46,8 +46,8 @@ static Bit8u read_p3da(Bit32u port) { } } flip++; - if (flip>10) flip=0; - if (flip>5) return 1; + if (flip>20) flip=0; + if (flip>10) return 1; return 0; /* 0 Either Vertical or Horizontal Retrace active if set From 9785e031971b2cdf22565a6717af6a3ddad25fe0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 8 Jan 2004 11:47:26 +0000 Subject: [PATCH 1465/4131] Added patch 849608 from Jonathan Gray and a patch from Dominik Vogt Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1546 --- include/setup.h | 6 ++++-- src/gui/sdlmain.cpp | 25 +++++++++++++++++++++---- src/misc/setup.cpp | 43 +++++++++++++++++++++++++++++-------------- 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/include/setup.h b/include/setup.h index f66b619c..bbc2cc24 100644 --- a/include/setup.h +++ b/include/setup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: setup.h,v 1.14 2004-01-08 11:45:24 qbix79 Exp $ */ + #ifndef _SETUP_H_ #define _SETUP_H_ @@ -180,7 +182,7 @@ public: void ShutDown(); void StartUp(); void PrintConfig(const char* configfilename); - void ParseConfigFile(const char* configfilename); + bool ParseConfigFile(const char* configfilename); void ParseEnv(char ** envp); std::list sectionlist; diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index d5ac3c4e..7fc8ecb0 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.54 2003-11-12 13:27:39 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.55 2004-01-08 11:47:26 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -28,6 +28,7 @@ #include #include + #include "SDL.h" #include "SDL_thread.h" @@ -56,6 +57,11 @@ extern char** environ; #include #define STDOUT_FILE TEXT("stdout.txt") #define STDERR_FILE TEXT("stderr.txt") +#define DEFAULT_CONFIG_FILE "/dosbox.conf" +#elif defined(MACOSX) +#define DEFAULT_CONFIG_FILE "/Library/Preferences/DOSBox Preferences" +#else /*linux freebsd*/ +#define DEFAULT_CONFIG_FILE "/.dosboxrc" #endif enum SCREEN_TYPES { @@ -759,8 +765,19 @@ int main(int argc, char* argv[]) { } else { config_file="dosbox.conf"; } - /* Parse the config file */ - control->ParseConfigFile(config_file.c_str()); + /* Parse the config file + * try open config file in $HOME if can't open dosbox.conf or specified file + */ + if (control->ParseConfigFile(config_file.c_str()) == false) { + if ((getenv("HOME") != NULL)) { + config_file = (std::string)getenv("HOME") + + (std::string)DEFAULT_CONFIG_FILE; + if (control->ParseConfigFile(config_file.c_str()) == false) { + LOG_MSG("CONFIG: Using default settings. Create a configfile to change them"); + } + + } + } #if (ENVIRON_LINKED) control->ParseEnv(environ); #endif diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 39785d0d..43702295 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: setup.cpp,v 1.18 2004-01-08 11:46:40 qbix79 Exp $ */ + #include "dosbox.h" #include "cross.h" #include "setup.h" @@ -226,36 +228,48 @@ Section* Config::GetSection(const char* _sectionname){ return NULL; } -void Config::ParseConfigFile(const char* configfilename){ +bool Config::ParseConfigFile(const char* configfilename){ ifstream in(configfilename); - if (!in) { - LOG_MSG("CONFIG:Can't find config file %s, using default settings",configfilename); - return; - } - char gegevens[150]; + if (!in) return false; + LOG_MSG("CONFIG:Loading settings from config file %s", configfilename); + char gegevens[1024]; Section* currentsection = NULL; Section* testsec = NULL; while (in) { - in.getline(gegevens,150); + in.getline(gegevens,1024); char* temp; - switch(gegevens[0]){ + char* s; + int len; + s = gegevens; + + /* strip trailing whitespace */ + for (len = strlen(s); len > 0 && isspace(s[len - 1]); len--) { + /* nothing */ + } + s[len] = 0; + + /* strip leading whitespace */ + while (isspace(s[0])) { + s++; + } + switch(s[0]){ case '%': case '\0': - case '\n': - case '#': + case '#': case ' ': + case '\n': continue; break; case '[': - temp = strrchr(gegevens,']'); + temp = strrchr(s,']'); *temp=0; - testsec = GetSection(&gegevens[1]); + testsec = GetSection(&s[1]); if(testsec != NULL ) currentsection = testsec; testsec = NULL; break; default: try{ - currentsection->HandleInputline(gegevens); + currentsection->HandleInputline(s); }catch(const char* message){ message=0; //EXIT with message @@ -263,6 +277,7 @@ void Config::ParseConfigFile(const char* configfilename){ break; } } + return true; } void Config::ParseEnv(char ** envp) { From a5147909b04478c0a04bbdc49e1fa16fd6739d55 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 8 Jan 2004 11:51:08 +0000 Subject: [PATCH 1466/4131] pushed sensible values on the stack (wd) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1547 --- src/dos/dos_execute.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index e1d73073..ad991798 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id */ + #include #include "dosbox.h" #include "mem.h" @@ -118,6 +120,7 @@ bool DOS_Terminate(bool tsr) { /* Set the CS:IP stored in int 0x22 back on the stack */ mem_writew(SegPhys(ss)+reg_sp+0,RealOff(old22)); mem_writew(SegPhys(ss)+reg_sp+2,RealSeg(old22)); + mem_writew(SegPhys(ss)+reg_sp+4,0x200); //stack isn't preserved // Free memory owned by process if (!tsr) DOS_FreeProcessMemory(mempsp); return true; From ddd6c6531ea618d846e985df9871f9324506c0b6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 8 Jan 2004 21:16:25 +0000 Subject: [PATCH 1467/4131] Fix screenshot support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1548 --- src/gui/render.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index fb0cec8e..9621fefb 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.20 2003-11-08 09:53:11 harekiet Exp $ */ +/* $Id: render.cpp,v 1.21 2004-01-08 21:16:25 harekiet Exp $ */ #include #include @@ -92,6 +92,7 @@ static struct { RENDER_Operation type; Bitu pitch; const char * dir; + Bit8u * buffer; } shot; #endif bool screenshot; @@ -111,6 +112,15 @@ static void RENDER_ResetPal(void); #if (C_SSHOT) #include +static void RENDER_ShotDraw(Bit8u * src,Bitu x,Bitu y,Bitu _dx,Bitu _dy) { + Bit8u * dst=render.shot.buffer+render.src.width*y; + for (;_dy>0;_dy--) { + memcpy(dst,src,_dx); + dst+=render.src.width; + src+=render.src.pitch; + } +} + /* Take a screenshot of the data that should be rendered */ static void TakeScreenShot(Bit8u * bitmap) { Bitu last=0;char file_name[CROSS_LEN]; @@ -280,10 +290,10 @@ void RENDER_DoUpdate(void) { static void RENDER_DrawScreen(Bit8u * data,Bitu pitch) { render.op.pitch=pitch; - switch (render.op.type) { #if (C_SSHOT) doagain: #endif + switch (render.op.type) { case OP_None: case OP_Normal2x: case OP_AdvMame2x: @@ -292,13 +302,10 @@ doagain: break; #if (C_SSHOT) case OP_Shot: - render.shot.pitch=render.op.pitch; - render.op.pitch=render.src.width; - render.op.pixels=(Bit8u*)malloc(render.src.width*render.src.height); -// render.src.draw_handler(Normal_DN_8); - TakeScreenShot((Bit8u *)render.op.pixels); - free(render.op.pixels); - render.op.pitch=render.shot.pitch; + render.shot.buffer=(Bit8u*)malloc(render.src.width*render.src.height); + render.src.draw_handler(&RENDER_ShotDraw); + TakeScreenShot(render.shot.buffer); + free(render.shot.buffer); render.op.type=render.shot.type; goto doagain; #endif From c5c064beb29f16ae12ec38c58e1510f23e300ca4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 9 Jan 2004 12:34:53 +0000 Subject: [PATCH 1468/4131] changed setenv to be case insensitive posted at vogons: turrican 2 post Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1549 --- src/misc/programs.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 111699da..968a3f70 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: programs.cpp,v 1.12 2004-01-09 12:34:53 qbix79 Exp $ */ + +#include #include #include #include @@ -164,7 +167,10 @@ bool Program::SetEnv(const char * entry,const char * new_string) { /* TODO Maybe save the program name sometime. not really needed though */ /* Save the new entry */ if (new_string[0]) { - sprintf(env_string,"%s=%s",entry,new_string); + std::string bigentry(entry); + for (std::string::iterator it = bigentry.begin(); it != bigentry.end(); ++it) *it = toupper(*it); + sprintf(env_string,"%s=%s",bigentry.c_str(),new_string); +// sprintf(env_string,"%s=%s",entry,new_string); //oldcode MEM_BlockWrite(env_write,env_string,strlen(env_string)+1); env_write+=strlen(env_string)+1; } From 47227a3fddfdb39c1742604328601ef441bea512 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 9 Jan 2004 16:51:22 +0000 Subject: [PATCH 1469/4131] Oops fixing mistake that broke ultima 7 and 8 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1550 --- src/ints/mouse.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 2354de4e..7ecf0f68 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.28 2004-01-02 18:47:13 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.29 2004-01-09 16:51:22 qbix79 Exp $ */ #include #include "dosbox.h" @@ -127,7 +127,7 @@ INLINE void Mouse_AddEvent(Bit16u type) { * handled backwards (prevents doubleclicks while moving) */ for(Bitu i = mouse.events ; i ; i--) - mouse.event_queue[i-1] = mouse.event_queue[i]; + mouse.event_queue[i] = mouse.event_queue[i-1]; mouse.event_queue[0].type=type; mouse.event_queue[0].buttons=mouse.buttons; mouse.events++; From 76460ed400ad9cb137f18f7d6b7209592ffd0501 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 10 Jan 2004 11:43:41 +0000 Subject: [PATCH 1470/4131] Chuck Yeager timer inits (Srecko) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1551 --- src/hardware/timer.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index df58ded6..1e31770e 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.19 2003-10-14 08:38:36 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.20 2004-01-10 11:43:41 qbix79 Exp $ */ #include "dosbox.h" #include "inout.h" @@ -209,6 +209,8 @@ void TIMER_Init(Section* sect) { pit[0].micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)pit[0].cntr)); pit[2].micro=100; pit[2].read_latch=-1; /* MadTv1 */ + pit[2].write_state = 3; /* Chuck Yeager */ + pit[2].mode=3; PIC_AddEvent(PIT0_Event,pit[0].micro); } From fcbd0fe85419f80a24366b728b3838ff716a8265 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 10 Jan 2004 14:03:36 +0000 Subject: [PATCH 1471/4131] Copyright to 2004 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1552 --- include/bios.h | 2 +- include/callback.h | 2 +- include/cpu.h | 2 +- include/cross.h | 2 +- include/debug.h | 2 +- include/dma.h | 4 ++-- include/dos_inc.h | 2 +- include/dos_system.h | 4 ++-- include/dosbox.h | 2 +- include/fpu.h | 2 +- include/hardware.h | 2 +- include/inout.h | 2 +- include/joystick.h | 2 +- include/keyboard.h | 2 +- include/mem.h | 2 +- include/mixer.h | 2 +- include/mouse.h | 2 +- include/paging.h | 2 +- include/pic.h | 2 +- include/programs.h | 2 +- include/regs.h | 2 +- include/render.h | 2 +- include/serialport.h | 2 +- include/shell.h | 4 ++-- include/support.h | 2 +- include/timer.h | 2 +- include/vga.h | 2 +- include/video.h | 2 +- src/cpu/core_dyn_x86.cpp | 2 +- src/cpu/core_full.cpp | 2 +- src/cpu/core_normal.cpp | 2 +- src/cpu/core_normal/helpers.h | 2 +- src/cpu/core_normal/prefix_0f.h | 2 +- src/cpu/core_normal/prefix_66.h | 2 +- src/cpu/core_normal/prefix_66_0f.h | 2 +- src/cpu/core_normal/prefix_none.h | 2 +- src/cpu/core_normal/support.h | 2 +- src/cpu/core_normal/table_ea.h | 2 +- src/cpu/cpu.cpp | 4 ++-- src/cpu/flags.cpp | 2 +- src/cpu/instructions.h | 2 +- src/cpu/lazyflags.h | 2 +- src/cpu/modrm.cpp | 2 +- src/cpu/modrm.h | 2 +- src/cpu/paging.cpp | 2 +- src/debug/debug.cpp | 4 ++-- src/debug/debug_gui.cpp | 2 +- src/debug/debug_inc.h | 2 +- src/debug/debug_win32.cpp | 2 +- src/debug/disasm_tables.h | 2 +- src/dos/cdrom.cpp | 2 +- src/dos/cdrom_aspi_win32.cpp | 4 ++-- src/dos/cdrom_ioctl_win32.cpp | 4 ++-- src/dos/dev_con.h | 4 ++-- src/dos/dos.cpp | 4 ++-- src/dos/dos_classes.cpp | 4 ++-- src/dos/dos_devices.cpp | 2 +- src/dos/dos_files.cpp | 4 ++-- src/dos/dos_ioctl.cpp | 4 ++-- src/dos/dos_memory.cpp | 2 +- src/dos/dos_misc.cpp | 2 +- src/dos/dos_mscdex.cpp | 2 +- src/dos/dos_programs.cpp | 4 ++-- src/dos/dos_tables.cpp | 2 +- src/dos/drive_cache.cpp | 4 ++-- src/dos/drive_local.cpp | 4 ++-- src/dos/drive_virtual.cpp | 2 +- src/dos/drives.cpp | 2 +- src/dos/drives.h | 4 ++-- src/dosbox.cpp | 2 +- src/fpu/fpu.cpp | 4 ++-- src/fpu/fpu_instructions.h | 4 ++-- src/fpu/fpu_types.h | 2 +- src/gui/midi.cpp | 2 +- src/gui/midi_alsa.h | 4 ++-- src/gui/midi_coreaudio.h | 2 +- src/gui/midi_oss.h | 2 +- src/gui/midi_win32.h | 2 +- src/gui/render.cpp | 4 ++-- src/gui/render_normal.h | 2 +- src/hardware/adlib.cpp | 2 +- src/hardware/cmos.cpp | 2 +- src/hardware/disney.cpp | 2 +- src/hardware/dma.cpp | 2 +- src/hardware/gameblaster.cpp | 2 +- src/hardware/gus.cpp | 2 +- src/hardware/hardware.cpp | 2 +- src/hardware/iohandler.cpp | 2 +- src/hardware/joystick.cpp | 2 +- src/hardware/memory.cpp | 2 +- src/hardware/mixer.cpp | 2 +- src/hardware/pcspeaker.cpp | 2 +- src/hardware/pic.cpp | 4 ++-- src/hardware/sblaster.cpp | 2 +- src/hardware/serialport.cpp | 2 +- src/hardware/softmodem.cpp | 2 +- src/hardware/tandy_sound.cpp | 2 +- src/hardware/vga.cpp | 2 +- src/hardware/vga_attr.cpp | 2 +- src/hardware/vga_crtc.cpp | 2 +- src/hardware/vga_dac.cpp | 2 +- src/hardware/vga_draw.cpp | 2 +- src/hardware/vga_gfx.cpp | 2 +- src/hardware/vga_memory.cpp | 2 +- src/hardware/vga_misc.cpp | 2 +- src/hardware/vga_seq.cpp | 2 +- src/ints/bios.cpp | 4 ++-- src/ints/bios_disk.cpp | 2 +- src/ints/bios_keyboard.cpp | 2 +- src/ints/dpmi.cpp | 2 +- src/ints/ems.cpp | 2 +- src/ints/int10.cpp | 2 +- src/ints/int10.h | 2 +- src/ints/int10_char.cpp | 4 ++-- src/ints/int10_memory.cpp | 2 +- src/ints/int10_misc.cpp | 2 +- src/ints/int10_pal.cpp | 2 +- src/ints/int10_put_pixel.cpp | 2 +- src/ints/xms.cpp | 4 ++-- src/ints/xms.h | 2 +- src/misc/messages.cpp | 2 +- src/misc/support.cpp | 4 ++-- src/shell/shell.cpp | 4 ++-- src/shell/shell_batch.cpp | 2 +- src/shell/shell_cmds.cpp | 4 ++-- src/shell/shell_misc.cpp | 4 ++-- 126 files changed, 154 insertions(+), 154 deletions(-) diff --git a/include/bios.h b/include/bios.h index 61632b69..18e2fb1d 100644 --- a/include/bios.h +++ b/include/bios.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/callback.h b/include/callback.h index e46a8ea3..eb299fc2 100644 --- a/include/callback.h +++ b/include/callback.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/cpu.h b/include/cpu.h index 9b265197..bc2d6765 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/cross.h b/include/cross.h index 730bdc88..135ab1dd 100644 --- a/include/cross.h +++ b/include/cross.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/debug.h b/include/debug.h index 28f02975..bb44a99d 100644 --- a/include/debug.h +++ b/include/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/dma.h b/include/dma.h index ecda6d36..74079295 100644 --- a/include/dma.h +++ b/include/dma.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dma.h,v 1.8 2003-11-26 08:38:23 qbix79 Exp $ */ +/* $Id: dma.h,v 1.9 2004-01-10 14:03:33 qbix79 Exp $ */ #ifndef __DMA_H #define __DMA_H diff --git a/include/dos_inc.h b/include/dos_inc.h index 541c2544..0100c2c3 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/dos_system.h b/include/dos_system.h index d93b19be..5cee5e4e 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.18 2003-11-08 17:59:30 harekiet Exp $ */ +/* $Id: dos_system.h,v 1.19 2004-01-10 14:03:33 qbix79 Exp $ */ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ diff --git a/include/dosbox.h b/include/dosbox.h index 2f47f113..b32184e5 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/fpu.h b/include/fpu.h index a1bfb2e5..a00c091a 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/hardware.h b/include/hardware.h index 514e13ac..d0958f4e 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/inout.h b/include/inout.h index 9bf30192..f4b7c51c 100644 --- a/include/inout.h +++ b/include/inout.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/joystick.h b/include/joystick.h index 6c14091c..b0e13bc6 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/keyboard.h b/include/keyboard.h index db7b0c13..8f7bed4b 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/mem.h b/include/mem.h index ad483275..b039ad36 100644 --- a/include/mem.h +++ b/include/mem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/mixer.h b/include/mixer.h index 3144a8be..9309a7f0 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/mouse.h b/include/mouse.h index 07fce5a6..1851f5cf 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/paging.h b/include/paging.h index c027d407..4640d172 100644 --- a/include/paging.h +++ b/include/paging.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/pic.h b/include/pic.h index 6daa09e3..05566d77 100644 --- a/include/pic.h +++ b/include/pic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/programs.h b/include/programs.h index 3ce261a7..a40090df 100644 --- a/include/programs.h +++ b/include/programs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/regs.h b/include/regs.h index 15d32e46..e97f54a1 100644 --- a/include/regs.h +++ b/include/regs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/render.h b/include/render.h index 8154c422..bfb45ba9 100644 --- a/include/render.h +++ b/include/render.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/serialport.h b/include/serialport.h index 1347ac62..386e7607 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/shell.h b/include/shell.h index e0c4bdd4..4d0bcd03 100644 --- a/include/shell.h +++ b/include/shell.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.1 2003-12-17 21:49:31 qbix79 Exp $ */ +/* $Id: shell.h,v 1.2 2004-01-10 14:03:33 qbix79 Exp $ */ #ifndef SHELL_H_ #define SHELL_H_ diff --git a/include/support.h b/include/support.h index 1e850f14..1b663347 100644 --- a/include/support.h +++ b/include/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/timer.h b/include/timer.h index 6511f932..aada3d51 100644 --- a/include/timer.h +++ b/include/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/vga.h b/include/vga.h index 1faf3c25..3999bfad 100644 --- a/include/vga.h +++ b/include/vga.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/video.h b/include/video.h index 32befb71..72151dcc 100644 --- a/include/video.h +++ b/include/video.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 901c4f4d..62f9584a 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 07017525..455df95f 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 85b7638c..ca04fbfe 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/cpu/core_normal/helpers.h b/src/cpu/core_normal/helpers.h index 97727801..b7acd35b 100644 --- a/src/cpu/core_normal/helpers.h +++ b/src/cpu/core_normal/helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 56a0a65c..23897681 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index f5f58363..22c7b67a 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 3ceb1160..a4439be8 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index cbb7d382..7d9fc2be 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index 7ed92cbe..0ef11b6e 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/cpu/core_normal/table_ea.h b/src/cpu/core_normal/table_ea.h index a93182e4..c6e95fc0 100644 --- a/src/cpu/core_normal/table_ea.h +++ b/src/cpu/core_normal/table_ea.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 6e5ea0b3..3b96079b 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.47 2004-01-07 21:37:47 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.48 2004-01-10 14:03:34 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index a1475523..bb67384f 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 0f2c1e14..3f941135 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index 1069e1cd..897b481d 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/cpu/modrm.cpp b/src/cpu/modrm.cpp index 56a695eb..b9bad896 100644 --- a/src/cpu/modrm.cpp +++ b/src/cpu/modrm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/cpu/modrm.h b/src/cpu/modrm.h index 42a34d09..181d529b 100644 --- a/src/cpu/modrm.h +++ b/src/cpu/modrm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 5ab6c4ca..4db18bda 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 13080006..b3d7325d 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.49 2003-12-29 23:16:46 harekiet Exp $ */ +/* $Id: debug.cpp,v 1.50 2004-01-10 14:03:34 qbix79 Exp $ */ #include "programs.h" diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 11105712..deb45371 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h index e3d5834f..41524aba 100644 --- a/src/debug/debug_inc.h +++ b/src/debug/debug_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/debug/debug_win32.cpp b/src/debug/debug_win32.cpp index cfed35e1..2da75fe4 100644 --- a/src/debug/debug_win32.cpp +++ b/src/debug/debug_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/debug/disasm_tables.h b/src/debug/disasm_tables.h index 0ed79e8f..9a080f28 100644 --- a/src/debug/disasm_tables.h +++ b/src/debug/disasm_tables.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 6d8febea..423b8bc2 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index 156b25e2..2c85add5 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_aspi_win32.cpp,v 1.9 2004-01-02 23:43:52 harekiet Exp $ */ +/* $Id: cdrom_aspi_win32.cpp,v 1.10 2004-01-10 14:03:34 qbix79 Exp $ */ #if defined (WIN32) diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index a3ef30f5..a923344f 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_ioctl_win32.cpp,v 1.9 2004-01-02 23:43:52 harekiet Exp $ */ +/* $Id: cdrom_ioctl_win32.cpp,v 1.10 2004-01-10 14:03:34 qbix79 Exp $ */ #if defined (WIN32) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 8183ce0a..f08ad63b 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.15 2003-10-22 15:48:20 harekiet Exp $ */ +/* $Id: dev_con.h,v 1.16 2004-01-10 14:03:34 qbix79 Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 82815417..2e903e87 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.62 2003-12-30 19:07:42 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.63 2004-01-10 14:03:34 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index b5a8b5be..9fd8e8af 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.32 2003-10-09 13:47:06 finsterr Exp $ */ +/* $Id: dos_classes.cpp,v 1.33 2004-01-10 14:03:34 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 3cab0a7d..1ee2b47b 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index b34e909f..41a03518 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.50 2003-12-18 09:30:48 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.51 2004-01-10 14:03:34 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index a5d14c00..25f93c08 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.17 2003-11-08 18:00:46 harekiet Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.18 2004-01-10 14:03:34 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 2feba966..2279c216 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index 33b56f1e..ddfa2d2f 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index cd1c8da2..5ee7c56f 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index a44f83a7..79425a68 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.21 2003-12-17 21:55:42 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.22 2004-01-10 14:03:34 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index e9035193..68db7bf6 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 66429947..0d2c02fc 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -1,6 +1,6 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.30 2003-12-26 20:39:27 finsterr Exp $ */ +/* $Id: drive_cache.cpp,v 1.31 2004-01-10 14:03:34 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 5e312116..9a285356 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.41 2003-12-29 22:42:23 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.42 2004-01-10 14:03:34 qbix79 Exp $ */ #include #include diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 9dff9f21..d40a9a5c 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index ea712f0e..e5720ff3 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/dos/drives.h b/src/dos/drives.h index 4158507e..1e5f7395 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.18 2003-12-17 21:54:31 qbix79 Exp $ */ +/* $Id: drives.h,v 1.19 2004-01-10 14:03:34 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ diff --git a/src/dosbox.cpp b/src/dosbox.cpp index ea0d5053..16d7288f 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index dbc20d20..2d75e6ba 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu.cpp,v 1.15 2003-11-11 18:28:05 qbix79 Exp $ */ +/* $Id: fpu.cpp,v 1.16 2004-01-10 14:03:34 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 23671e13..3eb4ef58 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.14 2003-10-19 19:21:12 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.15 2004-01-10 14:03:35 qbix79 Exp $ */ static void FPU_FINIT(void) { diff --git a/src/fpu/fpu_types.h b/src/fpu/fpu_types.h index c459feb8..e2295713 100644 --- a/src/fpu/fpu_types.h +++ b/src/fpu/fpu_types.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 8145d7bc..bbbb2d9c 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index fad0d4f7..50acebdb 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_alsa.h,v 1.4 2003-12-10 18:28:25 qbix79 Exp $ */ +/* $Id: midi_alsa.h,v 1.5 2004-01-10 14:03:35 qbix79 Exp $ */ #include #include diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index 8b95418c..0d7f9635 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index 65500a6a..62e1dfaf 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index bdac5ded..b08652b6 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 9621fefb..b435ddde 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.21 2004-01-08 21:16:25 harekiet Exp $ */ +/* $Id: render.cpp,v 1.22 2004-01-10 14:03:35 qbix79 Exp $ */ #include #include diff --git a/src/gui/render_normal.h b/src/gui/render_normal.h index 380fff5a..20aded8d 100644 --- a/src/gui/render_normal.h +++ b/src/gui/render_normal.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index d1de1322..f792f9fb 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index e44933b1..47a63a30 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index e93056a8..4baf3e25 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index f93ac9fa..e951d8ef 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index 29f6568e..f877bf4a 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 1341b2f3..9169abca 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 49cf7226..017ecc40 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index aa8da329..32e6e95c 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index 23536ff0..962bba2c 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 9756befd..dddeb8c4 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 839a312c..2886da24 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index a5361953..68622121 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 47c4dc65..f73ef75d 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.15 2003-12-10 14:55:08 qbix79 Exp $ */ +/* $Id: pic.cpp,v 1.16 2004-01-10 14:03:35 qbix79 Exp $ */ #include diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index cf91e3da..ad27fb21 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/serialport.cpp b/src/hardware/serialport.cpp index c2ba4a94..a5ba389e 100644 --- a/src/hardware/serialport.cpp +++ b/src/hardware/serialport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp index 902996ea..29ab9bff 100644 --- a/src/hardware/softmodem.cpp +++ b/src/hardware/softmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index d7d55fa7..4078540d 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 280db46e..78631c6a 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 1b8a48eb..f86afb58 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index ad7becd1..8152fe31 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index ab3acdd8..4fcb0f82 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 31fb6318..63cc6773 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index 83046519..2498c26f 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index fde8dcc5..e770c919 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 2bbc6a77..16b49632 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 4433f765..1ab8cc1a 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index fc3f0df3..861bd540 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.26 2003-12-17 23:04:40 finsterr Exp $ */ +/* $Id: bios.cpp,v 1.27 2004-01-10 14:03:35 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index afbe92c6..3e7a38f4 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index b5e300c9..09aa5cd1 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp index bc8246e5..dbbe45f2 100644 --- a/src/ints/dpmi.cpp +++ b/src/ints/dpmi.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 9154d786..92bd456e 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 5587041a..37c9da26 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ints/int10.h b/src/ints/int10.h index da3cccd7..ac114d25 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index e4b70950..3e940dcb 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.20 2003-10-22 14:50:28 harekiet Exp $ */ +/* $Id: int10_char.cpp,v 1.21 2004-01-10 14:03:35 qbix79 Exp $ */ /* Character displaying moving functions */ diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index e0358ae3..3466a7e1 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 2f5987f0..3afefc06 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 3c7a0840..f39c7930 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index dd07b596..b44e3590 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 854e099c..e3b1b06a 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.29 2003-12-09 21:10:31 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.30 2004-01-10 14:03:35 qbix79 Exp $ */ #include #include diff --git a/src/ints/xms.h b/src/ints/xms.h index e2170606..56489dcb 100644 --- a/src/ints/xms.h +++ b/src/ints/xms.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 073f2efb..fc9d6ba2 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 2f361783..0eadec29 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.20 2003-10-14 20:39:02 harekiet Exp $ */ +/* $Id: support.cpp,v 1.21 2004-01-10 14:03:35 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index eea7529b..667255ce 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.37 2003-12-17 21:50:59 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.38 2004-01-10 14:03:35 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 735b3f88..f5cf388d 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 32a246ea..43714ed6 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.36 2003-12-17 21:50:59 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.37 2004-01-10 14:03:36 qbix79 Exp $ */ #include diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 4465ffad..efefd63b 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.27 2003-12-17 21:50:59 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.28 2004-01-10 14:03:36 qbix79 Exp $ */ #include #include From 94b8931b783295a83d9f892511298f956bbe924f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 10 Jan 2004 18:42:58 +0000 Subject: [PATCH 1472/4131] Changed default cpu cycles to 2500 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1553 --- src/cpu/cpu.cpp | 6 +++--- src/dosbox.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 3b96079b..0de6c37f 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.48 2004-01-10 14:03:34 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.49 2004-01-10 18:42:28 qbix79 Exp $ */ #include #include "dosbox.h" @@ -41,7 +41,7 @@ Segments Segs; Bits CPU_Cycles = 0; Bits CPU_CycleLeft = 0; -Bits CPU_CycleMax = 1800; +Bits CPU_CycleMax = 2500; Bits CPU_CycleUp = 0; Bits CPU_CycleDown = 0; CPU_Decoder * cpudecoder; @@ -1281,7 +1281,7 @@ void CPU_Init(Section* sec) { } CPU_JMP(false,0,0); //Setup the first cpu core - if (!CPU_CycleMax) CPU_CycleMax = 1800; + if (!CPU_CycleMax) CPU_CycleMax = 2500; if(!CPU_CycleUp) CPU_CycleUp = 500; if(!CPU_CycleDown) CPU_CycleDown = 20; CPU_CycleLeft=0; diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 16d7288f..114ac906 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -222,7 +222,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("cpu",&CPU_Init); secprop->Add_string("core","normal"); - secprop->Add_int("cycles",1800); + secprop->Add_int("cycles",2500); secprop->Add_int("cycleup",500); secprop->Add_int("cycledown",20); MSG_Add("CPU_CONFIGFILE_HELP", From 186b881f15cd0ee4311472c02ae686d358aa939b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 10 Jan 2004 18:45:50 +0000 Subject: [PATCH 1473/4131] disabled aspect Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1554 --- src/dosbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 114ac906..e8637e07 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -210,7 +210,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("render",&RENDER_Init); secprop->Add_int("frameskip",0); secprop->Add_string("snapdir","snaps"); - secprop->Add_bool("aspect",true); + secprop->Add_bool("aspect",false); secprop->Add_string("scaler","normal2x"); MSG_Add("RENDER_CONFIGFILE_HELP", "frameskip -- How many frames dosbox skips before drawing one.\n" From d4274ba2cee449578ec87fd208c366a4d99f89d1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 10 Jan 2004 19:12:45 +0000 Subject: [PATCH 1474/4131] Disable the dynamic core log messages by default Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1555 --- src/cpu/core_dyn_x86.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 62f9584a..c4f96725 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -41,7 +41,7 @@ #define DYN_PAGE_HASH (4096>>DYN_HASH_SHIFT) #define DYN_LINKS (16) -#if 1 +#if 0 #define DYN_LOG LOG_MSG #else #define DYN_LOG @@ -216,7 +216,7 @@ findblock:; if (!block) { cache.block.running=0; block=CreateCacheBlock(ip_point,cpu.code.big,128); - DYN_LOG("Created block size %x type %d",block->cache.size,block->type); +// DYN_LOG("Created block size %x type %d",block->cache.size,block->type); chandler->AddCacheBlock(block); if (block->page.end>=4096) { DYN_LOG("block crosses page boundary"); @@ -259,12 +259,12 @@ run_block: } } else { if (handler->flags & PFLAG_NOCODE) { - LOG_MSG("can't run code in this page"); + LOG_MSG("DYNX86:Can't run code in this page"); return CPU_Core_Normal_Run(); } Bitu phys_page=ip_page; if (!PAGING_MakePhysPage(phys_page)) { - LOG_MSG("Can't find physpage"); + LOG_MSG("DYNX86:Can't find physpage"); return CPU_Core_Normal_Run(); } chandler=new CodePageHandler(handler); From 2f84118e7c725e9abcc1c89dab8d29d3a00f810b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 10 Jan 2004 20:10:31 +0000 Subject: [PATCH 1475/4131] preparing 0.61 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1556 --- VERSION | 2 +- configure.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 08072c18..6e8cb1ef 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.60 +0.61 diff --git a/configure.in b/configure.in index 1a2758f5..f1cd15eb 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Init. -AC_INIT(dosbox,0.60) +AC_INIT(dosbox,0.61) AC_PREREQ(2.50) AC_CONFIG_SRCDIR(README) From c6939434aeb7b8c8ef0ce64c5dfed906d445008b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 10 Jan 2004 20:19:14 +0000 Subject: [PATCH 1476/4131] preparing 0.61 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1557 --- scripts/dosbox-installer.nsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index dbc96be1..66024a97 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -1,5 +1,5 @@ !define VER_MAYOR 0 -!define VER_MINOR 60 +!define VER_MINOR 61 ; The name of the installer Name "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer" @@ -80,4 +80,4 @@ Section "Uninstall" RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}" SectionEnd -; eof \ No newline at end of file +; eof From 05f6c5bf9bcbafafa1630232033c452e7441cf0c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 11 Jan 2004 09:27:52 +0000 Subject: [PATCH 1477/4131] Fix set VESA set CPU window function to only use a bye value Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1558 --- src/ints/int10.cpp | 6 +++++- src/ints/int10.h | 2 +- src/ints/int10_vesa.cpp | 9 ++------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 37c9da26..6bcc2302 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -330,7 +330,7 @@ graphics_chars: break; case 0x05: if (reg_bh==0) { /* Set CPU Window */ - reg_ah=VESA_SetCPUWindow(reg_bl,reg_dx); + reg_ah=VESA_SetCPUWindow(reg_bl,reg_dl); reg_al=0x4f; } else if (reg_bh == 1) { /* Get CPU Window */ reg_ah=VESA_GetCPUWindow(reg_bl,reg_dx); @@ -340,6 +340,10 @@ graphics_chars: reg_ah=0x01; } break; + case 0x06: + reg_al=0x4f; + reg_ah=VESA_ScanLineLength(reg_al,reg_bx,reg_cx,reg_dx); + break; case 0x07: switch (reg_bl) { case 0x80: /* Set Display Start during retrace ?? */ diff --git a/src/ints/int10.h b/src/ints/int10.h index ac114d25..6b544fe2 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -182,7 +182,7 @@ Bit8u VESA_GetSVGAInformation(Bit16u seg,Bit16u off); Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off); Bit8u VESA_SetSVGAMode(Bit16u mode); Bit8u VESA_GetSVGAMode(Bit16u & mode); -Bit8u VESA_SetCPUWindow(Bit8u window,Bit16u address); +Bit8u VESA_SetCPUWindow(Bit8u window,Bit8u address); Bit8u VESA_GetCPUWindow(Bit8u window,Bit16u & address); Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u & bytes,Bit16u & pixels,Bit16u & lines); Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y); diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 621bc34d..358c4e2b 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.6 2004-01-07 20:26:38 qbix79 Exp $ */ +/* $Id: int10_vesa.cpp,v 1.7 2004-01-11 09:27:52 harekiet Exp $ */ #include #include @@ -170,7 +170,7 @@ Bit8u VESA_GetSVGAMode(Bit16u & mode) { return 0x00; } -Bit8u VESA_SetCPUWindow(Bit8u window,Bit16u address) { +Bit8u VESA_SetCPUWindow(Bit8u window,Bit8u address) { if (window) return 0x1; if ((address<32)) { IO_Write(0x3d4,0x6a); @@ -295,12 +295,8 @@ Bit8u VESA_GetDisplayStart(Bit16u & x,Bit16u & y) { return 0x1; } return 0x00; - - } - - static Bitu SetWindowPositionHandler(void) { if (reg_bh) reg_ah=VESA_GetCPUWindow(reg_bl,reg_dx); else reg_ah=VESA_SetCPUWindow(reg_bl,reg_dx); @@ -308,7 +304,6 @@ static Bitu SetWindowPositionHandler(void) { return 0; } - void INT10_SetupVESA(void) { /* Put the mode list somewhere in memory */ Bitu i; From 449d45643c21aae1b3e6ab5c56ef65397eeaa257 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 11 Jan 2004 09:41:52 +0000 Subject: [PATCH 1478/4131] somehow atan translates to atan2(Fizzban) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1559 --- src/fpu/fpu_instructions.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 3eb4ef58..81a65c46 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.15 2004-01-10 14:03:35 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.16 2004-01-11 09:41:52 qbix79 Exp $ */ static void FPU_FINIT(void) { @@ -96,7 +96,7 @@ static void FPU_FSQRT(void){ return; } static void FPU_FPATAN(void){ - fpu.regs[ST(1)].d = atan(fpu.regs[ST(1)].d/fpu.regs[TOP].d); + fpu.regs[ST(1)].d = atan2(fpu.regs[ST(1)].d,fpu.regs[TOP].d); FPU_FPOP(); FPU_SET_C2(0); //flags and such :) From 2394f38514e4c57420cb910b1033e73be1a7f7b4 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 11 Jan 2004 12:24:56 +0000 Subject: [PATCH 1479/4131] Add string operations for MOVS,STOS,LODS Change the way temporary registers are handled with loading and saving Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1560 --- src/cpu/core_dyn_x86.cpp | 7 +- src/cpu/core_dyn_x86/decoder.h | 53 ++++++++-- src/cpu/core_dyn_x86/risc_x86.h | 70 ++++++++++++-- src/cpu/core_dyn_x86/string.h | 165 ++++++++++++++++++++++++++++++++ 4 files changed, 274 insertions(+), 21 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index c4f96725..e6becba8 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -70,7 +70,6 @@ enum DualOps { DOP_AND,DOP_OR, DOP_MOV, DOP_TEST, - DOP_IMUL, DOP_XCHG, }; @@ -108,8 +107,8 @@ enum BlockReturn { #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 //Load value only once because of save -#define DYNFLG_LOADONCE 0x20 //Load value only once because of save +#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; @@ -325,7 +324,7 @@ void CPU_Core_Dyn_X86_Init(void) { 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_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; diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 34318015..cc077ec9 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1,10 +1,32 @@ +/* + * Copyright (C) 2002-2004 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +enum REP_Type { + REP_NONE=0,REP_NZ,REP_Z +}; + static struct DynDecode { PhysPt code; PhysPt code_start; PhysPt op_start; bool big_op; bool big_addr; - bool rep; + REP_Type rep; Bitu cycles; CacheBlock * block; struct { @@ -16,8 +38,6 @@ static struct DynDecode { DynReg * segprefix; } decode; -#include "helpers.h" - static Bit8u INLINE decode_fetchb(void) { return mem_readb(decode.code++); } @@ -49,6 +69,7 @@ static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { else gen_call_function((void *)&mem_writew,"%Dd%Dw",addr,val); } + static void dyn_reduce_cycles(void) { if (!decode.cycles) decode.cycles++; gen_lea(DREG(CYCLES),DREG(CYCLES),0,0,-(Bits)decode.cycles); @@ -209,6 +230,9 @@ static void dyn_fill_ea(bool addseg=true) { } } +#include "helpers.h" +#include "string.h" + static void dyn_dop_ebgb(DualOps op) { dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg&3]; if (decode.modrm.mod<3) { @@ -359,6 +383,7 @@ static void dyn_mov_ev_gb(bool sign) { dyn_read_byte(DREG(EA),DREG(TMPB),false); gen_releasereg(DREG(EA)); gen_extend_byte(sign,decode.big_op,rm_reg,DREG(TMPB),0); + gen_releasereg(DREG(TMPB)); } else { gen_extend_byte(sign,decode.big_op,rm_reg,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); } @@ -644,7 +669,7 @@ static void dyn_load_seg_off_ea(SegNames seg) { dyn_fill_ea(); gen_lea(DREG(TMPW),DREG(EA),0,0,decode.big_op ? 4:2); dyn_read_word(DREG(TMPW),DREG(TMPW),false); - dyn_load_seg(seg,DREG(TMPW),false); + dyn_load_seg(seg,DREG(TMPW),false);gen_releasereg(DREG(TMPW)); dyn_read_word(DREG(EA),&DynRegs[decode.modrm.reg],decode.big_op); gen_releasereg(DREG(EA)); } else { @@ -900,7 +925,7 @@ static CacheBlock * CreateCacheBlock(PhysPt start,bool big,Bitu max_opcodes) { decode.block=cache_openblock(); gen_save_host_direct(&cache.block.running,(Bit32u)decode.block); for (i=0;iflags&=~DYNFLG_CHANGED; dynreg->genreg=this; - if (dynreg->flags & (DYNFLG_LOAD|DYNFLG_LOADONCE)) { - dynreg->flags&=~DYNFLG_LOADONCE; + if (dynreg->flags & (DYNFLG_LOAD|DYNFLG_ACTIVE)) { cache_addw(0x058b+(index << (8+3))); //Mov reg,[data] cache_addd((Bit32u)dynreg->data); } + dynreg->flags|=DYNFLG_ACTIVE; } void Save(void) { if (!dynreg) IllegalOption(); @@ -56,13 +72,12 @@ public: if (dynreg->flags&DYNFLG_CHANGED && dynreg->flags&DYNFLG_SAVE) { Save(); } - dynreg->flags&=~(DYNFLG_CHANGED|DYNFLG_LOADONCE); + dynreg->flags&=~(DYNFLG_CHANGED|DYNFLG_ACTIVE); dynreg->genreg=0;dynreg=0; } void Clear(void) { if (!dynreg) return; if (dynreg->flags&DYNFLG_CHANGED) { - dynreg->flags|=DYNFLG_LOADONCE; Save(); } dynreg->genreg=0;dynreg=0; @@ -176,10 +191,15 @@ static GenReg * ForceDynReg(GenReg * genreg,DynReg * dynreg) { genreg->Load(dynreg); return genreg; } + +static void gen_preloadreg(DynReg * dynreg) { + FindDynReg(dynreg); +} + static void gen_releasereg(DynReg * dynreg) { GenReg * genreg=dynreg->genreg; if (genreg) genreg->Release(); - else dynreg->flags&=~(DYNFLG_LOADONCE|DYNFLG_CHANGED); + else dynreg->flags&=~(DYNFLG_ACTIVE|DYNFLG_CHANGED); } static void gen_setupreg(DynReg * dnew,DynReg * dsetup) { @@ -203,12 +223,12 @@ static void gen_synchreg(DynReg * dnew,DynReg * dsynch) { } } /* Always use the loadonce flag from either state */ - dnew->flags|=(dsynch->flags & dnew->flags&DYNFLG_LOADONCE); + dnew->flags|=(dsynch->flags & dnew->flags&DYNFLG_ACTIVE); if ((dnew->flags ^ dsynch->flags) & DYNFLG_CHANGED) { /* Ensure the changed value gets saved */ if (dnew->flags & DYNFLG_CHANGED) { dnew->genreg->Save(); - } + } else dnew->flags|=DYNFLG_CHANGED; } } @@ -498,6 +518,24 @@ static void gen_shift_word(ShiftOps op,DynReg * drecx,bool dword,DynReg * dr1) { dr1->flags|=DYNFLG_CHANGED; } +static void gen_shift_word_imm(ShiftOps op,bool dword,DynReg * dr1,Bit8u imm) { + GenReg * gr1=FindDynReg(dr1); + if (!dword) cache_addb(0x66); + switch (op) { + case SHIFT_ROL:cache_addw(0xc0c1+((gr1->index)<<8));break; + case SHIFT_ROR:cache_addw(0xc8c1+((gr1->index)<<8));break; + case SHIFT_RCL:cache_addw(0xd0c1+((gr1->index)<<8));break; + case SHIFT_RCR:cache_addw(0xd8c1+((gr1->index)<<8));break; + case SHIFT_SHL:cache_addw(0xe0c1+((gr1->index)<<8));break; + case SHIFT_SHR:cache_addw(0xe8c1+((gr1->index)<<8));break; + case SHIFT_SAR:cache_addw(0xf8c1+((gr1->index)<<8));break; + default: + IllegalOption(); + } + cache_addb(imm); + dr1->flags|=DYNFLG_CHANGED; +} + static void gen_cbw(bool dword,DynReg * dyn_ax) { ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax); if (!dword) cache_addb(0x66); @@ -678,10 +716,22 @@ static Bit8u * gen_create_branch(BranchTypes type) { return (cache.pos-1); } -static void gen_fill_branch(Bit8u * data) { - *data=(cache.pos-data-1); +static void gen_fill_branch(Bit8u * data,Bit8u * from=cache.pos) { + *data=(from-data-1); } +static Bit8u * gen_create_jump(Bit8u * to=0) { + /* First free all registers */ + cache_addb(0xe9); + cache_addd(to-(cache.pos+4)); + return (cache.pos-4); +} + +static void gen_fill_jump(Bit8u * data,Bit8u * to=cache.pos) { + *(Bit32u*)data=(to-data-4); +} + + static void gen_jmp_ptr(void * ptr,Bits imm=0) { cache_addb(0xa1); cache_addd((Bit32u)ptr); diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index e69de29b..ba076c99 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2002-2004 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +enum STRING_OP { + STR_OUTSB=0,STR_OUTSW,STR_OUTSD, + STR_INSB=4,STR_INSW,STR_INSD, + STR_MOVSB=8,STR_MOVSW,STR_MOVSD, + STR_LODSB=12,STR_LODSW,STR_LODSD, + STR_STOSB=16,STR_STOSW,STR_STOSD, + STR_SCASB=20,STR_SCASW,STR_SCASD, + STR_CMPSB=24,STR_CMPSW,STR_CMPSD, +}; + +static void dyn_string(STRING_OP op) { + DynReg * si_base=decode.segprefix ? decode.segprefix : DREG(DS); + DynReg * di_base=DREG(ES); + DynReg * tmp_reg;bool usesi;bool usedi; + gen_storeflags(); + if (decode.rep) { + gen_dop_word_imm(DOP_SUB,true,DREG(CYCLES),decode.cycles); + gen_releasereg(DREG(CYCLES)); + decode.cycles=0; + } + /* Check what each string operation will be using */ + switch (op) { + case STR_MOVSB: case STR_MOVSW: case STR_MOVSD: + case STR_CMPSB: case STR_CMPSW: case STR_CMPSD: + tmp_reg=DREG(TMPB);usesi=true;usedi=true;break; + case STR_LODSB: case STR_LODSW: case STR_LODSD: + tmp_reg=DREG(EAX);usesi=true;usedi=false;break; + case STR_OUTSB: case STR_OUTSW: case STR_OUTSD: + tmp_reg=DREG(TMPB);usesi=true;usedi=false;break; + case STR_SCASB: case STR_SCASW: case STR_SCASD: + case STR_STOSB: case STR_STOSW: case STR_STOSD: + tmp_reg=DREG(EAX);usesi=false;usedi=true;break; + case STR_INSB: case STR_INSW: case STR_INSD: + tmp_reg=DREG(TMPB);usesi=false;usedi=true;break; + default: + IllegalOption(); + } + gen_load_host(&cpu.direction,DREG(TMPW),4); + switch (op & 3) { + case 0:break; + case 1:gen_shift_word_imm(SHIFT_SHL,true,DREG(TMPW),1);break; + case 2:gen_shift_word_imm(SHIFT_SHL,true,DREG(TMPW),2);break; + default: + IllegalOption(); + + } + if (usesi) { + gen_preloadreg(DREG(ESI)); + DynRegs[G_ESI].flags|=DYNFLG_CHANGED; + gen_preloadreg(si_base); + } + if (usedi) { + gen_preloadreg(DREG(EDI)); + DynRegs[G_EDI].flags|=DYNFLG_CHANGED; + gen_preloadreg(di_base); + } + if (decode.rep) { + gen_preloadreg(DREG(ECX)); + DynRegs[G_ECX].flags|=DYNFLG_CHANGED; + } + DynState rep_state; + dyn_savestate(&rep_state); + Bit8u * rep_start=cache.pos; + Bit8u * rep_ecx_jmp; + /* Check if ECX!=zero and decrease it */ + if (decode.rep) { + gen_dop_word(DOP_OR,decode.big_addr,DREG(ECX),DREG(ECX)); + Bit8u * branch_ecx=gen_create_branch(BR_NZ); + rep_ecx_jmp=gen_create_jump(); + gen_fill_branch(branch_ecx); + gen_sop_word(SOP_DEC,decode.big_addr,DREG(ECX)); + } + if (usesi) { + if (!decode.big_addr) { + gen_extend_word(false,DREG(EA),DREG(ESI)); + gen_lea(DREG(EA),si_base,DREG(EA),0,0); + } else { + gen_lea(DREG(EA),si_base,DREG(ESI),0,0); + } + gen_dop_word(DOP_ADD,decode.big_addr,DREG(ESI),DREG(TMPW)); + switch (op&3) { + case 0:dyn_read_byte(DREG(EA),tmp_reg,false);break; + case 1:dyn_read_word(DREG(EA),tmp_reg,false);break; + case 2:dyn_read_word(DREG(EA),tmp_reg,true);break; + } + switch (op) { + case STR_OUTSB: + gen_call_function((void*)&IO_WriteB,"%Id%Dl",DREG(EDX),tmp_reg);break; + case STR_OUTSW: + gen_call_function((void*)&IO_WriteW,"%Id%Dw",DREG(EDX),tmp_reg);break; + case STR_OUTSD: + gen_call_function((void*)&IO_WriteD,"%Id%Dd",DREG(EDX),tmp_reg);break; + } + } + if (usedi) { + if (!decode.big_addr) { + gen_extend_word(false,DREG(EA),DREG(EDI)); + gen_lea(DREG(EA),di_base,DREG(EA),0,0); + } else { + gen_lea(DREG(EA),di_base,DREG(EDI),0,0); + } + gen_dop_word(DOP_ADD,decode.big_addr,DREG(EDI),DREG(TMPW)); + /* Maybe something special to be done to fill the value */ + switch (op) { + case STR_INSB: + gen_call_function((void*)&IO_ReadB,"%Dw%Rl",DREG(EDX),tmp_reg); + case STR_MOVSB: + case STR_STOSB: + dyn_write_byte(DREG(EA),tmp_reg,false); + break; + case STR_INSW: + gen_call_function((void*)&IO_ReadW,"%Dw%Rw",DREG(EDX),tmp_reg); + case STR_MOVSW: + case STR_STOSW: + dyn_write_word(DREG(EA),tmp_reg,false); + break; + case STR_INSD: + gen_call_function((void*)&IO_ReadD,"%Dw%Rd",DREG(EDX),tmp_reg); + case STR_MOVSD: + case STR_STOSD: + dyn_write_word(DREG(EA),tmp_reg,true); + break; + default: + IllegalOption(); + } + } + gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB)); + if (decode.rep) { + DynState cycle_state; + gen_sop_word(SOP_DEC,true,DREG(CYCLES)); + gen_releasereg(DREG(CYCLES)); + dyn_savestate(&cycle_state); + Bit8u * cycle_branch=gen_create_branch(BR_NLE); + gen_lea(DREG(EIP),DREG(EIP),0,0,decode.op_start-decode.code_start); + dyn_releaseregs(); + gen_restoreflags(true); + gen_return(BR_Cycles); + gen_fill_branch(cycle_branch); + dyn_loadstate(&cycle_state); + dyn_synchstate(&rep_state); + /* Jump back to start of ECX check */ + gen_create_jump(rep_start); + gen_fill_jump(rep_ecx_jmp); + } + gen_releasereg(DREG(TMPW)); + gen_restoreflags(); +} \ No newline at end of file From 2b919b0ffec4bbdf85a2ab67c1c8185337bb489d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 11 Jan 2004 12:29:03 +0000 Subject: [PATCH 1480/4131] Keep a global direction flag register Change the push/pop functions for correct 16-bit SP increase/descrease Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1561 --- src/cpu/cpu.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 0de6c37f..c4840659 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.49 2004-01-10 18:42:28 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.50 2004-01-11 12:29:03 harekiet Exp $ */ #include #include "dosbox.h" @@ -67,24 +67,24 @@ void CPU_Core_Dyn_X86_Init(void); void CPU_Push16(Bitu value) { - reg_esp-=2; + reg_esp=(reg_esp&~cpu.stack.mask)|(reg_esp-2)&cpu.stack.mask; mem_writew(SegPhys(ss) + (reg_esp & cpu.stack.mask) ,value); } void CPU_Push32(Bitu value) { - reg_esp-=4; + reg_esp=(reg_esp&~cpu.stack.mask)|(reg_esp-4)&cpu.stack.mask; mem_writed(SegPhys(ss) + (reg_esp & cpu.stack.mask) ,value); } Bitu CPU_Pop16(void) { Bitu val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - reg_esp+=2; + reg_esp=(reg_esp&~cpu.stack.mask)|(reg_esp+2)&cpu.stack.mask; return val; } Bitu CPU_Pop32(void) { Bitu val=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - reg_esp+=4; + reg_esp=(reg_esp&~cpu.stack.mask)|(reg_esp+4)&cpu.stack.mask; return val; } @@ -100,6 +100,7 @@ PhysPt SelBase(Bitu sel) { void CPU_SetFlags(Bitu word,Bitu mask) { reg_flags=(reg_flags & ~mask)|(word & mask)|2; + cpu.direction=1-((reg_flags & FLAG_DF) >> 9); } class TaskStateSegment { From 73879ec6b73ec932bd1c028e12bdf0eb7b036a4e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 11 Jan 2004 12:29:28 +0000 Subject: [PATCH 1481/4131] global direction flag register Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1562 --- include/cpu.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/cpu.h b/include/cpu.h index bc2d6765..f741895b 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -392,6 +392,7 @@ struct CPUBlock { struct { Bitu which,error; } exception; + Bits direction; }; extern CPUBlock cpu; From 4a016f2b4b82cdc3b1fb9b5c143ff473ed66becc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 11 Jan 2004 12:31:12 +0000 Subject: [PATCH 1482/4131] Set and use the global direction flag variable Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1563 --- src/cpu/core_full/load.h | 2 ++ src/cpu/core_full/string.h | 2 +- src/cpu/core_normal/prefix_none.h | 2 ++ src/cpu/core_normal/string.h | 2 +- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 8bcf8744..ab38c4d5 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -404,9 +404,11 @@ l_M_Ed: goto nextopcode; case D_CLD: SETFLAGBIT(DF,false); + cpu.direction=1; goto nextopcode; case D_STD: SETFLAGBIT(DF,true); + cpu.direction=-1; goto nextopcode; case D_WAIT: case D_NOP: diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index 95ce58f6..ea4e5e91 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -34,7 +34,7 @@ count_left=0; } } - add_index=GETFLAG(DF) ? -1 : 1; + add_index=cpu.direction; if (count) switch (inst.code.op) { case R_OUTSB: for (;count>0;count--) { diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 7d9fc2be..99df7d44 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -1064,9 +1064,11 @@ break; CASE_B(0xfc) /* CLD */ SETFLAGBIT(DF,false); + cpu.direction=1; break; CASE_B(0xfd) /* STD */ SETFLAGBIT(DF,true); + cpu.direction=-1; break; CASE_B(0xfe) /* GRP4 Eb */ { diff --git a/src/cpu/core_normal/string.h b/src/cpu/core_normal/string.h index 00d70c0c..c2f3013e 100644 --- a/src/cpu/core_normal/string.h +++ b/src/cpu/core_normal/string.h @@ -46,7 +46,7 @@ static void DoString(STRING_OP type) { count_left=0; } } - add_index=GETFLAG(DF) ? -1 : 1; + add_index=cpu.direction; if (count) switch (type) { case R_OUTSB: for (;count>0;count--) { From b26731075523b9ee0c015c122073340bbc111de8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 11 Jan 2004 12:36:45 +0000 Subject: [PATCH 1483/4131] An amazing newline Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1564 --- src/cpu/core_dyn_x86/string.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index ba076c99..7a713d9e 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -162,4 +162,4 @@ static void dyn_string(STRING_OP op) { } gen_releasereg(DREG(TMPW)); gen_restoreflags(); -} \ No newline at end of file +} From 5919036d4266dfeede312362a22bd782af902a2f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 11 Jan 2004 12:38:28 +0000 Subject: [PATCH 1484/4131] fix assembler warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1565 --- src/cpu/core_dyn_x86/risc_x86.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index cc062d35..ad1e4d74 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -120,7 +120,7 @@ static BlockReturn gen_runcode(Bit8u * code) { "pushl %%ebp \n" "pushl %%esi \n" "popfl \n" - "calll %4 \n" + "calll *%4 \n" "popl %%ebp \n" "pushfl \n" "andl %3,(%1) \n" From 9048b0f14b12200a58775623f074bdab7cd0471a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 11 Jan 2004 12:52:57 +0000 Subject: [PATCH 1485/4131] Remove core selection defines Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1566 --- src/cpu/cpu.cpp | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index c4840659..7ae3381e 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.50 2004-01-11 12:29:03 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.51 2004-01-11 12:52:57 harekiet Exp $ */ #include #include "dosbox.h" @@ -54,18 +54,6 @@ void CPU_Core_Full_Init(void); void CPU_Core_Normal_Init(void); void CPU_Core_Dyn_X86_Init(void); -#if (C_DYNAMIC_X86) - -#define startcpu_core CPU_Core_Dyn_X86_Run - -#else - -#define startcpu_core CPU_Core_Normal_Run -//#define startcpu_core CPU_Core_Full_Run - -#endif - - void CPU_Push16(Bitu value) { reg_esp=(reg_esp&~cpu.stack.mask)|(reg_esp-2)&cpu.stack.mask; mem_writew(SegPhys(ss) + (reg_esp & cpu.stack.mask) ,value); From a4e9443e59176d54d78555c58f369d735a21b808 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 11 Jan 2004 14:00:13 +0000 Subject: [PATCH 1486/4131] Some small compatibility changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1567 --- src/dos/drive_local.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 9a285356..bf356a94 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.42 2004-01-10 14:03:34 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.43 2004-01-11 14:00:13 qbix79 Exp $ */ #include #include @@ -122,6 +122,10 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { strcat(tempDir,_dir); CROSS_FILENAME(tempDir); + if (allocation.mediaid==0xF0 ) { + EmptyCache(); //rescan floppie-content on each findfirst + } + char end[2]={CROSS_FILESPLIT,0}; if (tempDir[strlen(tempDir)-1]!=CROSS_FILESPLIT) strcat(tempDir,end); @@ -137,7 +141,13 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { Bit8u sAttr; dta.GetSearchParams(sAttr,tempDir); if ((sAttr & DOS_ATTR_VOLUME) && (*_dir==0)) { - // Get Volume Label (DOS_ATTR_VOLUME) and only in basedir + // Get Volume Label (DOS_ATTR_VOLUME) and only in basedir + if ( strcmp(dirCache.GetLabel(), "") == 0 ) { + LOG(LOG_DOS,LOG_ERROR)("DRIVELABEL REQUESTED: none present, returned NOLABEL"); + dta.SetResult("NOLABEL",0,0,0,DOS_ATTR_VOLUME); + return true; + } + if (WildFileCmp(dirCache.GetLabel(),tempDir)) { // Get Volume Label dta.SetResult(dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME); From a3a44f588c884fadab3f190be2b5829cfe1eafb1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 11 Jan 2004 16:30:41 +0000 Subject: [PATCH 1487/4131] Use new IO handler functions in ins and outs opcodes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1568 --- src/cpu/core_full/string.h | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index ea4e5e91..036a8f3f 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -38,39 +38,34 @@ if (count) switch (inst.code.op) { case R_OUTSB: for (;count>0;count--) { - IO_Write(reg_dx,LoadMb(si_base+si_index)); + IO_WriteB(reg_dx,LoadMb(si_base+si_index)); si_index=(si_index+add_index) & add_mask; } break; case R_OUTSW: add_index<<=1; for (;count>0;count--) { - IO_Write(reg_dx,LoadMb(si_base+si_index)); - IO_Write(reg_dx+1,LoadMb(si_base+si_index+1)); + IO_WriteW(reg_dx,LoadMw(si_base+si_index)); si_index=(si_index+add_index) & add_mask; } break; case R_OUTSD: add_index<<=2; for (;count>0;count--) { - IO_Write(reg_dx,LoadMb(si_base+si_index)); - IO_Write(reg_dx+1,LoadMb(si_base+si_index+1)); - IO_Write(reg_dx+2,LoadMb(si_base+si_index+2)); - IO_Write(reg_dx+3,LoadMb(si_base+si_index+3)); + IO_WriteD(reg_dx,LoadMd(si_base+si_index)); si_index=(si_index+add_index) & add_mask; } break; case R_INSB: for (;count>0;count--) { - SaveMb(di_base+di_index,IO_Read(reg_dx)); + SaveMb(di_base+di_index,IO_ReadB(reg_dx)); di_index=(di_index+add_index) & add_mask; } break; case R_INSW: add_index<<=1; for (;count>0;count--) { - SaveMb(di_base+di_index,IO_Read(reg_dx)); - SaveMb(di_base+di_index+1,IO_Read(reg_dx+1)); + SaveMw(di_base+di_index,IO_ReadW(reg_dx)); di_index=(di_index+add_index) & add_mask; } break; From 69b007c8338dcbcff4fc543cedaf26e0f6cab290 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 11 Jan 2004 16:31:55 +0000 Subject: [PATCH 1488/4131] Fix XLAT instruction with 32-bit address size Fix BSFw opcode to first load flags Fix 16-bit bit testing opcodes to correct effective address Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1569 --- src/cpu/core_full/load.h | 26 ++++++++++++++++---------- src/cpu/core_full/op.h | 1 + src/cpu/core_full/optable.h | 4 ++-- src/cpu/core_full/support.h | 2 +- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index ab38c4d5..084cc524 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -78,7 +78,7 @@ l_M_Ewx: goto l_M_EwGw; case M_EwGwt: inst.op2.d=reg_16(inst.rm_index); - inst.rm_eaa+=((Bit32s)inst.op2.d >> 4) * 2; + inst.rm_eaa+=((Bit16s)inst.op2.d >> 4) * 2; goto l_M_Ew; l_M_EwGw: case M_EwGw: @@ -247,8 +247,7 @@ l_M_Ed: inst.op1.d=reg_32(inst.code.extra); break; case L_FLG: - FillFlags(); - inst.op1.d = reg_flags; + inst.op1.d = FillFlags(); break; case L_SEG: inst.op1.d=SegValue((SegNames)inst.code.extra); @@ -360,13 +359,20 @@ l_M_Ed: case D_SETALC: reg_al = get_CF() ? 0xFF : 0; goto nextopcode; - case D_XLATw: - if (inst.prefix & PREFIX_SEG) reg_al=LoadMb(inst.seg.base+reg_bx+reg_al); - else reg_al=LoadMb(SegBase(ds)+reg_bx+reg_al); - goto nextopcode; - case D_XLATd: - if (inst.prefix & PREFIX_SEG) reg_al=LoadMb(inst.seg.base+reg_ebx+reg_al); - else reg_al=LoadMb(SegBase(ds)+reg_ebx+reg_al); + case D_XLAT: + if (inst.prefix & PREFIX_SEG) { + if (inst.prefix & PREFIX_ADDR) { + reg_al=LoadMb(inst.seg.base+(Bit32u)(reg_ebx+reg_al)); + } else { + reg_al=LoadMb(inst.seg.base+(Bit16u)(reg_bx+reg_al)); + } + } else { + if (inst.prefix & PREFIX_ADDR) { + reg_al=LoadMb(SegBase(ds)+(Bit32u)(reg_ebx+reg_al)); + } else { + reg_al=LoadMb(SegBase(ds)+(Bit16u)(reg_bx+reg_al)); + } + } goto nextopcode; case D_CBW: reg_ax=(Bit8s)reg_al; diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index f8be1e40..58458806 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -483,6 +483,7 @@ switch (inst.code.op) { break; case O_BSFw: { + FillFlags(); if (!inst.op1.w) { SETFLAGBIT(ZF,true); goto nextopcode; diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index bc9d0a0b..0e86e5dd 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -150,7 +150,7 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,5 ,0 ,M_GRP_1 },{L_MODRM ,6 ,0 ,M_GRP_1 }, {L_MODRM ,5 ,0 ,M_GRP_CL },{L_MODRM ,6 ,0 ,M_GRP_CL }, {L_Ib ,O_AAM ,0 ,0 },{L_Ib ,O_AAD ,0 ,0 }, -{D_SETALC ,0 ,0 ,0 },{D_XLATw ,0 ,0 ,0 }, +{D_SETALC ,0 ,0 ,0 },{D_XLAT ,0 ,0 ,0 }, //TODO FPU /* 0xd8 - 0xdf */ {L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,1 ,0 }, @@ -506,7 +506,7 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,5 ,0 ,M_GRP_1 },{L_MODRM ,7 ,0 ,M_GRP_1 }, {L_MODRM ,5 ,0 ,M_GRP_CL },{L_MODRM ,7 ,0 ,M_GRP_CL }, {L_Ib ,O_AAM ,0 ,0 },{L_Ib ,O_AAD ,0 ,0 }, -{D_SETALC ,0 ,0 ,0 },{D_XLATd ,0 ,0 ,0 }, +{D_SETALC ,0 ,0 ,0 },{D_XLAT ,0 ,0 ,0 }, /* 0x2d8 - 0x2df */ {L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,1 ,0 }, {L_MODRM ,O_FPU ,2 ,0 },{L_MODRM ,O_FPU ,3 ,0 }, diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 27b9419d..26abed8e 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -32,7 +32,7 @@ enum { D_CBW,D_CWDE, D_CWD,D_CDQ, D_SETALC, - D_XLATw,D_XLATd, + D_XLAT, D_CLI,D_STI,D_STC,D_CLC,D_CMC,D_CLD,D_STD, D_NOP,D_WAIT, D_ENTERw,D_ENTERd, From e176cda16afa82cead657db912ca225a61cc54b4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 11 Jan 2004 16:48:32 +0000 Subject: [PATCH 1489/4131] changed LOG_DOS into an existing errortype Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1570 --- src/dos/drive_local.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index bf356a94..9cec7b8b 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.43 2004-01-11 14:00:13 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.44 2004-01-11 16:48:32 qbix79 Exp $ */ #include #include @@ -143,7 +143,7 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { if ((sAttr & DOS_ATTR_VOLUME) && (*_dir==0)) { // Get Volume Label (DOS_ATTR_VOLUME) and only in basedir if ( strcmp(dirCache.GetLabel(), "") == 0 ) { - LOG(LOG_DOS,LOG_ERROR)("DRIVELABEL REQUESTED: none present, returned NOLABEL"); + LOG(LOG_DOSMISC,LOG_ERROR)("DRIVELABEL REQUESTED: none present, returned NOLABEL"); dta.SetResult("NOLABEL",0,0,0,DOS_ATTR_VOLUME); return true; } From d47032feeb2dea04cc4bd46f17f4343fe40840f4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 11 Jan 2004 18:49:59 +0000 Subject: [PATCH 1490/4131] made new window do less and mouse_reset a bit more. Fixes ironseed Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1571 --- src/ints/mouse.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 7ecf0f68..68a21e85 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.29 2004-01-09 16:51:22 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.30 2004-01-11 18:49:59 qbix79 Exp $ */ #include #include "dosbox.h" @@ -418,14 +418,11 @@ static void SetMickeyPixelRate(Bit16s px, Bit16s py) }; static void mouse_reset_hardware(void){ - mouse.sub_mask=0; - mouse.sub_seg=0; - mouse.sub_ofs=0; PIC_SetIRQMask(MOUSE_IRQ,false); }; -static void mouse_reset(void) -{ +void Mouse_NewVideoMode(void) +{ //Does way to much. Many of this stuff should be moved to mouse_reset one day WriteMouseIntVector(); // real_writed(0,(0x74<<2),CALLBACK_RealPointer(call_int74)); @@ -492,14 +489,20 @@ static void mouse_reset(void) mouse.cursorType = 0; mouse.enabled=true; mouse.oldshown=-1; - + SetMickeyPixelRate(8,16); } -void Mouse_NewVideoMode(void) -{ - //mouse.shown = -1; - mouse_reset(); + + +static void mouse_reset(void) { +//Much to empty Mouse_NewVideoMode contains stuff that should be in here + Mouse_NewVideoMode(); + + mouse.sub_mask=0; + mouse.sub_seg=0; + mouse.sub_ofs=0; + //Added this for cd-v19 } From d227299bc132b1678d3742d43bec4c1c384b96b2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 11 Jan 2004 19:39:22 +0000 Subject: [PATCH 1491/4131] Only enable dpmi hos tin debug version Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1572 --- src/dosbox.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index e8637e07..60c6ee7e 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -350,15 +350,18 @@ void DOSBOX_Init(void) { secprop->Add_bool("xms",true); secprop->AddInitFunction(&EMS_Init); secprop->Add_bool("ems",true); +#if (C_DEBUG) secprop->AddInitFunction(&DPMI_Init); secprop->Add_bool("dpmi",false); - +#endif MSG_Add("DOS_CONFIGFILE_HELP", "xms -- Enable XMS support.\n" "ems -- Enable EMS support.\n" +#if (C_DEBUG) "dpmi -- Enable builtin DPMI host support.\n" " This might help in getting some games to work, but might crash others.\n" " So be sure to try both settings.\n" +#endif ); // Mscdex secprop->AddInitFunction(&MSCDEX_Init); From a3bbaacb51fb7b7842541428bbb66aca5f0bdb87 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 12 Jan 2004 10:05:57 +0000 Subject: [PATCH 1492/4131] Fix BTRd instruction, missed a break; Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1573 --- src/cpu/core_full/op.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 58458806..2af8b420 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -586,6 +586,7 @@ switch (inst.code.op) { FillFlags(); SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31)))); inst.op1.d&=~(1 << (inst.op2.d & 31)); + break; case O_BSWAP: BSWAP(inst.op1.d); break; From 9761c009088bab99bc65a69c8d924e5da6fd7d20 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 12 Jan 2004 10:06:40 +0000 Subject: [PATCH 1493/4131] Added segment exceptions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1574 --- src/cpu/core_full/load.h | 14 ++++++++++++++ src/cpu/core_full/optable.h | 20 ++++++++++---------- src/cpu/core_full/save.h | 24 ++++++++++++++++++------ src/cpu/core_full/support.h | 2 +- 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 084cc524..dd7c2db5 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -356,6 +356,20 @@ l_M_Ed: reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32(); goto nextopcode; + case D_POPSEGw: + if (CPU_SetSegGeneral((SegNames)inst.code.extra,Pop_16())) { + LEAVECORE; + reg_eip-=(IPPoint-inst.start);reg_esp-=2; + CPU_StartException();goto restart_core; + } + goto nextopcode; + case D_POPSEGd: + if (CPU_SetSegGeneral((SegNames)inst.code.extra,Pop_32())) { + LEAVECORE; + reg_eip-=(IPPoint-inst.start);reg_esp-=4; + CPU_StartException();goto restart_core; + } + goto nextopcode; case D_SETALC: reg_al = get_CF() ? 0xFF : 0; goto nextopcode; diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 0e86e5dd..7b24e956 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -4,7 +4,7 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,t_ADDb ,S_Eb ,M_EbGb },{L_MODRM ,t_ADDw ,S_Ew ,M_EwGw }, {L_MODRM ,t_ADDb ,S_Gb ,M_GbEb },{L_MODRM ,t_ADDw ,S_Gw ,M_GwEw }, {L_REGbIb ,t_ADDb ,S_REGb ,REGI_AL },{L_REGwIw ,t_ADDw ,S_REGw ,REGI_AX }, -{L_SEG ,0 ,S_PUSHw,es },{L_POPw ,0 ,S_SEGI ,es }, +{L_SEG ,0 ,S_PUSHw,es },{D_POPSEGw,0 ,0 ,es }, /* 0x08 - 0x0f */ {L_MODRM ,t_ORb ,S_Eb ,M_EbGb },{L_MODRM ,t_ORw ,S_Ew ,M_EwGw }, {L_MODRM ,t_ORb ,S_Gb ,M_GbEb },{L_MODRM ,t_ORw ,S_Gw ,M_GwEw }, @@ -15,12 +15,12 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,t_ADCb ,S_Eb ,M_EbGb },{L_MODRM ,t_ADCw ,S_Ew ,M_EwGw }, {L_MODRM ,t_ADCb ,S_Gb ,M_GbEb },{L_MODRM ,t_ADCw ,S_Gw ,M_GwEw }, {L_REGbIb ,t_ADCb ,S_REGb ,REGI_AL },{L_REGwIw ,t_ADCw ,S_REGw ,REGI_AX }, -{L_SEG ,0 ,S_PUSHw,ss },{L_POPw ,0 ,S_SEGI ,ss }, +{L_SEG ,0 ,S_PUSHw,ss },{D_POPSEGw,0 ,0 ,ss }, /* 0x18 - 0x1f */ {L_MODRM ,t_SBBb ,S_Eb ,M_EbGb },{L_MODRM ,t_SBBw ,S_Ew ,M_EwGw }, {L_MODRM ,t_SBBb ,S_Gb ,M_GbEb },{L_MODRM ,t_SBBw ,S_Gw ,M_GwEw }, {L_REGbIb ,t_SBBb ,S_REGb ,REGI_AL },{L_REGwIw ,t_SBBw ,S_REGw ,REGI_AX }, -{L_SEG ,0 ,S_PUSHw,ds },{L_POPw ,0 ,S_SEGI ,ds }, +{L_SEG ,0 ,S_PUSHw,ds },{D_POPSEGw,0 ,0 ,ds }, /* 0x20 - 0x27 */ {L_MODRM ,t_ANDb ,S_Eb ,M_EbGb },{L_MODRM ,t_ANDw ,S_Ew ,M_EwGw }, @@ -293,12 +293,12 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,O_C_LE ,S_C_Eb,0 },{L_MODRM ,O_C_NLE ,S_C_Eb,0 }, /* 0x1a0 - 0x1a7 */ -{L_SEG ,0 ,S_PUSHw ,fs },{L_POPw ,0 ,S_SEGI ,fs }, +{L_SEG ,0 ,S_PUSHw ,fs },{D_POPSEGw,0 ,0 ,fs }, {D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTw ,S_Ew ,M_EwGwt }, {L_MODRM ,O_DSHLw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHLw ,S_Ew ,M_EwGwCL }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x1a8 - 0x1af */ -{L_SEG ,0 ,S_PUSHw ,gs },{L_POPw ,0 ,S_SEGI ,gs }, +{L_SEG ,0 ,S_PUSHw ,gs },{D_POPSEGw,0 ,0 ,gs }, {0 ,0 ,0 ,0 },{L_MODRM ,O_BTSw ,S_Ew ,M_EwGwt }, {L_MODRM ,O_DSHRw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHRw ,S_Ew ,M_EwGwCL }, {0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRw ,S_Gw ,M_EwxGwx }, @@ -363,7 +363,7 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,t_ADDb ,S_Eb ,M_EbGb },{L_MODRM ,t_ADDd ,S_Ed ,M_EdGd }, {L_MODRM ,t_ADDb ,S_Gb ,M_GbEb },{L_MODRM ,t_ADDd ,S_Gd ,M_GdEd }, {L_REGbIb ,t_ADDb ,S_REGb ,REGI_AL },{L_REGdId ,t_ADDd ,S_REGd ,REGI_AX }, -{L_SEG ,0 ,S_PUSHd,es },{L_POPd ,0 ,S_SEGI ,es }, +{L_SEG ,0 ,S_PUSHd,es },{D_POPSEGd,0 ,0 ,es }, /* 0x208 - 0x20f */ {L_MODRM ,t_ORb ,S_Eb ,M_EbGb },{L_MODRM ,t_ORd ,S_Ed ,M_EdGd }, {L_MODRM ,t_ORb ,S_Gb ,M_GbEb },{L_MODRM ,t_ORd ,S_Gd ,M_GdEd }, @@ -374,12 +374,12 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,t_ADCb ,S_Eb ,M_EbGb },{L_MODRM ,t_ADCd ,S_Ed ,M_EdGd }, {L_MODRM ,t_ADCb ,S_Gb ,M_GbEb },{L_MODRM ,t_ADCd ,S_Gd ,M_GdEd }, {L_REGbIb ,t_ADCb ,S_REGb ,REGI_AL },{L_REGdId ,t_ADCd ,S_REGd ,REGI_AX }, -{L_SEG ,0 ,S_PUSHd,ss },{L_POPd ,0 ,S_SEGI ,ss }, +{L_SEG ,0 ,S_PUSHd,ss },{D_POPSEGd,0 ,0 ,ss }, /* 0x218 - 0x21f */ {L_MODRM ,t_SBBb ,S_Eb ,M_EbGb },{L_MODRM ,t_SBBd ,S_Ed ,M_EdGd }, {L_MODRM ,t_SBBb ,S_Gb ,M_GbEb },{L_MODRM ,t_SBBd ,S_Gd ,M_GdEd }, {L_REGbIb ,t_SBBb ,S_REGb ,REGI_AL },{L_REGdId ,t_SBBd ,S_REGd ,REGI_AX }, -{L_SEG ,0 ,S_PUSHd,ds },{L_POPd ,0 ,S_SEGI ,ds }, +{L_SEG ,0 ,S_PUSHd,ds },{D_POPSEGd,0 ,0 ,ds }, /* 0x220 - 0x227 */ {L_MODRM ,t_ANDb ,S_Eb ,M_EbGb },{L_MODRM ,t_ANDd ,S_Ed ,M_EdGd }, @@ -649,12 +649,12 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,O_C_LE ,S_C_Eb,0 },{L_MODRM ,O_C_NLE ,S_C_Eb,0 }, /* 0x3a0 - 0x3a7 */ -{L_SEG ,0 ,S_PUSHd ,fs },{L_POPd ,0 ,S_SEGI ,fs }, +{L_SEG ,0 ,S_PUSHd ,fs },{D_POPSEGd,0 ,0 ,fs }, {D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTd ,S_Ed ,M_EdGdt }, {L_MODRM ,O_DSHLd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHLd ,S_Ed ,M_EdGdCL }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x3a8 - 0x3af */ -{L_SEG ,0 ,S_PUSHd ,gs },{L_POPd ,0 ,S_SEGI ,gs }, +{L_SEG ,0 ,S_PUSHd ,gs },{D_POPSEGd,0 ,0 ,gs }, {0 ,0 ,0 ,0 },{L_MODRM ,O_BTSd ,S_Ed ,M_EdGdt }, {L_MODRM ,O_DSHRd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHRd ,S_Ed ,M_EdGdCL }, {0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdxGdx }, diff --git a/src/cpu/core_full/save.h b/src/cpu/core_full/save.h index a5e97eb1..e732a047 100644 --- a/src/cpu/core_full/save.h +++ b/src/cpu/core_full/save.h @@ -55,19 +55,31 @@ switch (inst.code.save) { case S_REGd: reg_32(inst.code.extra)=inst.op1.d; break; - case S_SEGI: - CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op1.w); - break; case S_SEGm: - CPU_SetSegGeneral((SegNames)inst.rm_index,inst.op1.w); + if (CPU_SetSegGeneral((SegNames)inst.rm_index,inst.op1.w)) { + LEAVECORE; + reg_eip-=(IPPoint-inst.start); + CPU_StartException(); + goto restart_core; + } break; case S_SEGGw: + if (CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w)) { + LEAVECORE; + reg_eip-=(IPPoint-inst.start); + CPU_StartException(); + goto restart_core; + } reg_16(inst.rm_index)=inst.op1.w; - CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w); break; case S_SEGGd: + if (CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w)) { + LEAVECORE; + reg_eip-=(IPPoint-inst.start); + CPU_StartException(); + goto restart_core; + } reg_32(inst.rm_index)=inst.op1.d; - CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w); break; case S_PUSHw: Push_16(inst.op1.w); diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 26abed8e..5d4b2fd4 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -27,6 +27,7 @@ enum { D_IRETw,D_IRETd, D_PUSHAw,D_PUSHAd, D_POPAw,D_POPAd, + D_POPSEGw,D_POPSEGd, D_DAA,D_DAS, D_AAA,D_AAS, D_CBW,D_CWDE, @@ -105,7 +106,6 @@ enum { S_REGb,S_REGw,S_REGd, S_PUSHw,S_PUSHd, - S_SEGI, S_SEGm, S_SEGGw,S_SEGGd, From ec08bdb4684980a77be17049f43be3685c605577 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 12 Jan 2004 10:16:26 +0000 Subject: [PATCH 1494/4131] Fix 16/32 bit IO reads and writes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1575 --- src/cpu/core_full/op.h | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 2af8b420..045180b2 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -348,26 +348,22 @@ switch (inst.code.op) { CPU_SW_Interrupt(inst.op1.b,IPPoint-inst.start); goto restart_core; case O_INb: - reg_al=IO_Read(inst.op1.d); + reg_al=IO_ReadB(inst.op1.d); goto nextopcode; case O_INw: - reg_ax=IO_Read(inst.op1.d) | (IO_Read(inst.op1.d+1) << 8); + reg_ax=IO_ReadW(inst.op1.d); goto nextopcode; case O_INd: - reg_eax=IO_Read(inst.op1.d) | (IO_Read(inst.op1.d+1) << 8) | (IO_Read(inst.op1.d+2) << 16) | (IO_Read(inst.op1.d+3) << 24); + reg_eax=IO_ReadD(inst.op1.d); goto nextopcode; case O_OUTb: - IO_Write(inst.op1.d,reg_al); + IO_WriteB(inst.op1.d,reg_al); goto nextopcode; case O_OUTw: - IO_Write(inst.op1.d+0,(Bit8u)reg_ax); - IO_Write(inst.op1.d+1,(Bit8u)(reg_ax >> 8)); + IO_WriteW(inst.op1.d,reg_ax); goto nextopcode; case O_OUTd: - IO_Write(inst.op1.d+0,(Bit8u)reg_eax); - IO_Write(inst.op1.d+1,(Bit8u)(reg_eax >> 8)); - IO_Write(inst.op1.d+2,(Bit8u)(reg_eax >> 16)); - IO_Write(inst.op1.d+3,(Bit8u)(reg_eax >> 24)); + IO_WriteD(inst.op1.d,reg_eax); goto nextopcode; case O_CBACK: LEAVECORE; From 5d739cb67e1d01017677bc9d1f183688271d4efd Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 12 Jan 2004 20:25:05 +0000 Subject: [PATCH 1495/4131] init a few temporary pointer with 0 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1576 --- src/dos/drive_cache.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 0d2c02fc..256df85f 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.31 2004-01-10 14:03:34 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.32 2004-01-12 20:25:05 finsterr Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -138,7 +138,7 @@ void DOS_Drive_Cache::SetBaseDir(const char* baseDir) Bit16u id; strcpy(basePath,baseDir); if (OpenDir(baseDir,id)) { - char * result; + char* result = 0; ReadDir(id,result); }; // Get Volume Label @@ -478,7 +478,7 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* strcpy(work,basePath); if (OpenDir(curDir,work,id)) { char buffer[CROSS_LEN]; - char * result; + char* result = 0; strcpy(buffer,dirPath); ReadDir(id,result); strcpy(dirPath,buffer); @@ -508,7 +508,7 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* if (!IsCachedIn(curDir)) { if (OpenDir(curDir,expandedPath,id)) { char buffer[CROSS_LEN]; - char * result; + char* result = 0; strcpy(buffer,dirPath); ReadDir(id,result); strcpy(dirPath,buffer); From 00673b9f454fac9f62c7095a6045c547da4c7736 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 12 Jan 2004 20:25:57 +0000 Subject: [PATCH 1496/4131] added constructor for CFileInfo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1577 --- include/dos_system.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/dos_system.h b/include/dos_system.h index 5cee5e4e..594c81c9 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.19 2004-01-10 14:03:33 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.20 2004-01-12 20:25:57 finsterr Exp $ */ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ @@ -117,6 +117,11 @@ public: class CFileInfo { public: + CFileInfo(void) { + orgname[0] = shortname[0] = 0; + nextEntry = shortNr = compareCount = 0; + isDir = false; + } ~CFileInfo(void) { for (Bit32u i=0; i Date: Tue, 13 Jan 2004 08:56:10 +0000 Subject: [PATCH 1497/4131] Add ID bit in flags register to indicate CPUID opcode available Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1578 --- src/cpu/cpu.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 7ae3381e..821e7958 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.51 2004-01-11 12:52:57 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.52 2004-01-13 08:56:10 harekiet Exp $ */ #include #include "dosbox.h" @@ -87,7 +87,7 @@ PhysPt SelBase(Bitu sel) { } void CPU_SetFlags(Bitu word,Bitu mask) { - reg_flags=(reg_flags & ~mask)|(word & mask)|2; + reg_flags=(reg_flags & ~mask)|(word & mask)|2|FLAG_ID; cpu.direction=1-((reg_flags & FLAG_DF) >> 9); } @@ -1229,7 +1229,6 @@ void CPU_Init(Section* sec) { SegSet16(gs,0); SegSet16(ss,0); - reg_flags=0x2; CPU_SetFlags(FLAG_IF,FMASK_ALL); //Enable interrupts cpu.cr0=0xffffffff; CPU_SET_CRX(0,0); //Initialize From 7b1abfca2d7c5270e7a4f26c83baec5d9f3b557d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 13 Jan 2004 08:56:48 +0000 Subject: [PATCH 1498/4131] Add alignment check bit in flags register to allow 486 detection Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1579 --- include/regs.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/regs.h b/include/regs.h index e97f54a1..92eb004a 100644 --- a/include/regs.h +++ b/include/regs.h @@ -35,9 +35,11 @@ #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) +#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 From 3aa903dbfc6590f87256da640c65f5fa01c26ac6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 13 Jan 2004 09:08:24 +0000 Subject: [PATCH 1499/4131] Renamed start variable to opcode_start Fixed EXCEPTION define to us opcode_start Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1580 --- src/cpu/core_full.cpp | 4 ++-- src/cpu/core_full/load.h | 6 +++--- src/cpu/core_full/op.h | 2 +- src/cpu/core_full/save.h | 6 +++--- src/cpu/core_full/string.h | 2 +- src/cpu/core_full/support.h | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 455df95f..f49edb9c 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -61,7 +61,7 @@ typedef PhysPt EAPoint; #define EXCEPTION(blah) \ { \ Bit8u new_num=blah; \ - IPPoint=inst.start_entry; \ + IPPoint=inst.opcode_start; \ LEAVECORE; \ CPU_Exception(new_num,0); \ LoadIP(); \ @@ -93,7 +93,7 @@ restart_core: }; #endif #endif - inst.start=IPPoint; + inst.opcode_start=IPPoint; inst.entry=inst.start_entry; inst.prefix=inst.start_prefix; restartopcode: diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index dd7c2db5..d5b7987b 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -359,14 +359,14 @@ l_M_Ed: case D_POPSEGw: if (CPU_SetSegGeneral((SegNames)inst.code.extra,Pop_16())) { LEAVECORE; - reg_eip-=(IPPoint-inst.start);reg_esp-=2; + reg_eip-=(IPPoint-inst.opcode_start);reg_esp-=2; CPU_StartException();goto restart_core; } goto nextopcode; case D_POPSEGd: if (CPU_SetSegGeneral((SegNames)inst.code.extra,Pop_32())) { LEAVECORE; - reg_eip-=(IPPoint-inst.start);reg_esp-=4; + reg_eip-=(IPPoint-inst.opcode_start);reg_esp-=4; CPU_StartException();goto restart_core; } goto nextopcode; @@ -524,7 +524,7 @@ l_M_Ed: goto nextopcode; case D_HLT: LEAVECORE; - CPU_HLT(IPPoint-inst.start); + CPU_HLT(IPPoint-inst.opcode_start); return CBRET_NONE; default: LOG(LOG_CPU,LOG_ERROR)("LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry); diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 045180b2..5d4ee345 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -345,7 +345,7 @@ switch (inst.code.op) { else if (DEBUG_IntBreakpoint(inst.op1.b)) return debugCallback; #endif - CPU_SW_Interrupt(inst.op1.b,IPPoint-inst.start); + CPU_SW_Interrupt(inst.op1.b,IPPoint-inst.opcode_start); goto restart_core; case O_INb: reg_al=IO_ReadB(inst.op1.d); diff --git a/src/cpu/core_full/save.h b/src/cpu/core_full/save.h index e732a047..157364c6 100644 --- a/src/cpu/core_full/save.h +++ b/src/cpu/core_full/save.h @@ -58,7 +58,7 @@ switch (inst.code.save) { case S_SEGm: if (CPU_SetSegGeneral((SegNames)inst.rm_index,inst.op1.w)) { LEAVECORE; - reg_eip-=(IPPoint-inst.start); + reg_eip-=(IPPoint-inst.opcode_start); CPU_StartException(); goto restart_core; } @@ -66,7 +66,7 @@ switch (inst.code.save) { case S_SEGGw: if (CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w)) { LEAVECORE; - reg_eip-=(IPPoint-inst.start); + reg_eip-=(IPPoint-inst.opcode_start); CPU_StartException(); goto restart_core; } @@ -75,7 +75,7 @@ switch (inst.code.save) { case S_SEGGd: if (CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w)) { LEAVECORE; - reg_eip-=(IPPoint-inst.start); + reg_eip-=(IPPoint-inst.opcode_start); CPU_StartException(); goto restart_core; } diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index 036a8f3f..5556f444 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -28,7 +28,7 @@ count_left=count-CPU_Cycles; count=CPU_Cycles; CPU_Cycles=0; - IPPoint=inst.start; //Reset IP to start of instruction + IPPoint=inst.opcode_start; //Reset IP to start of instruction } else { /* Won't interrupt scas and cmps instruction since they can interrupt themselves */ count_left=0; diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 5d4b2fd4..d3e94623 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -155,7 +155,7 @@ struct OpCode { struct FullData { Bitu entry; - EAPoint start; + EAPoint opcode_start; Bitu rm; EAPoint rm_eaa; Bitu rm_off; From 3a0530ec27f6e2acdecaaf9181f9c91ad6edf478 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 13 Jan 2004 19:02:58 +0000 Subject: [PATCH 1500/4131] typo's Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1581 --- src/dosbox.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 60c6ee7e..593e4788 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: dosbox.cpp,v 1.60 2004-01-13 19:02:58 qbix79 Exp $ */ + #include #include #include @@ -171,7 +173,7 @@ static void DOSBOX_RealInit(Section * sec) { else if (strcasecmp(mtype,"hercules")==0) machine=MCH_HERC; else if (strcasecmp(mtype,"vga")==0) machine=MCH_VGA; else if (strcasecmp(mtype,"auto")==0) machine=MCH_AUTO; - else LOG_MSG("DOSBOX:Unkown machine type %s",mtype); + else LOG_MSG("DOSBOX:Unknown machine type %s",mtype); } @@ -182,7 +184,7 @@ void DOSBOX_Init(void) { /* Setup all the different modules making up DOSBox */ secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit); - secprop->Add_string("language",""); + secprop->Add_string("language",""); secprop->Add_string("machine","auto"); #if C_DEBUG @@ -231,7 +233,7 @@ void DOSBOX_Init(void) { ",dynamic" #endif ".\n" - "cycles -- Amount of instructions dosbox tries to emulate each millsecond.\n" + "cycles -- Amount of instructions dosbox tries to emulate each millisecond.\n" " Setting this higher than your machine can handle is bad!\n" "cycleup -- Amount of cycles to increase/decrease with keycombo.\n" "cycledown Setting it lower than 100 will be a percentage.\n" @@ -306,7 +308,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("gus",&GUS_Init); secprop->Add_bool("gus",true); secprop->Add_int("rate",22050); - secprop->Add_hex("base",0x240); + secprop->Add_hex("base",0x240); secprop->Add_int("irq1",5); secprop->Add_int("irq2",5); secprop->Add_int("dma1",3); @@ -333,7 +335,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&DISNEY_Init); secprop->Add_bool("disney",true); - MSG_Add("SPEAKER_CONFIGFILE_HELP", + MSG_Add("SPEAKER_CONFIGFILE_HELP", "pcspeaker -- Enable PC-Speaker emulation.\n" "pcrate -- Sample rate of the PC-Speaker sound generation.\n" "tandy -- Enable Tandy 3-Voice emulation.\n" From 73943385cd320a92b24bb0331bc587e31a39b9f9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 13 Jan 2004 21:41:58 +0000 Subject: [PATCH 1501/4131] Fix effective address calculation of bittesting opcodes with register operand Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1582 --- src/cpu/core_normal/prefix_0f.h | 12 ++++++++---- src/cpu/core_normal/prefix_66_0f.h | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 23897681..44bb1b24 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -255,7 +255,8 @@ GetEArw; SETFLAGBIT(CF,(*earw & mask)); } else { - GetEAa;Bit16u old=LoadMw(eaa); + GetEAa;eaa+=(((Bit16s)*rmrw)>>4)*2; + Bit16u old=LoadMw(eaa); SETFLAGBIT(CF,(old & mask)); } break; @@ -279,7 +280,8 @@ SETFLAGBIT(CF,(*earw & mask)); *earw|=mask; } else { - GetEAa;Bit16u old=LoadMw(eaa); + GetEAa;eaa+=(((Bit16s)*rmrw)>>4)*2; + Bit16u old=LoadMw(eaa); SETFLAGBIT(CF,(old & mask)); SaveMw(eaa,old | mask); } @@ -311,7 +313,8 @@ SETFLAGBIT(CF,(*earw & mask)); *earw&= ~mask; } else { - GetEAa;Bit16u old=LoadMw(eaa); + GetEAa;eaa+=(((Bit16s)*rmrw)>>4)*2; + Bit16u old=LoadMw(eaa); SETFLAGBIT(CF,(old & mask)); SaveMw(eaa,old & ~mask); } @@ -399,7 +402,8 @@ SETFLAGBIT(CF,(*earw & mask)); *earw^=mask; } else { - GetEAa;Bit16u old=LoadMw(eaa); + GetEAa;eaa+=(((Bit16s)*rmrw)>>4)*2; + Bit16u old=LoadMw(eaa); SETFLAGBIT(CF,(old & mask)); SaveMw(eaa,old ^ mask); } diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index a4439be8..65a10402 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -168,7 +168,8 @@ GetEArd; SETFLAGBIT(CF,(*eard & mask)); } else { - GetEAa;Bit32u old=LoadMd(eaa); + GetEAa;eaa+=(((Bit32s)*rmrd)>>5)*4; + Bit32u old=LoadMd(eaa); SETFLAGBIT(CF,(old & mask)); } break; @@ -192,7 +193,8 @@ SETFLAGBIT(CF,(*eard & mask)); *eard|=mask; } else { - GetEAa;Bit32u old=LoadMd(eaa); + GetEAa;eaa+=(((Bit32s)*rmrd)>>5)*4; + Bit32u old=LoadMd(eaa); SETFLAGBIT(CF,(old & mask)); SaveMd(eaa,old | mask); } @@ -227,7 +229,8 @@ SETFLAGBIT(CF,(*eard & mask)); *eard&= ~mask; } else { - GetEAa;Bit32u old=LoadMd(eaa); + GetEAa;eaa+=(((Bit32s)*rmrd)>>5)*4; + Bit32u old=LoadMd(eaa); SETFLAGBIT(CF,(old & mask)); SaveMd(eaa,old & ~mask); } @@ -317,7 +320,8 @@ SETFLAGBIT(CF,(*eard & mask)); *eard^=mask; } else { - GetEAa;Bit32u old=LoadMd(eaa); + GetEAa;eaa+=(((Bit32s)*rmrd)>>5)*4; + Bit32u old=LoadMd(eaa); SETFLAGBIT(CF,(old & mask)); SaveMd(eaa,old ^ mask); } From 6455ddbd6edbac2569f4064e962647fa43d7a8a2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 14 Jan 2004 17:09:41 +0000 Subject: [PATCH 1502/4131] fix push/pop instructions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1583 --- src/cpu/cpu.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 821e7958..a31c4ac4 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.52 2004-01-13 08:56:10 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.53 2004-01-14 17:09:41 harekiet Exp $ */ #include #include "dosbox.h" @@ -55,24 +55,24 @@ void CPU_Core_Normal_Init(void); void CPU_Core_Dyn_X86_Init(void); void CPU_Push16(Bitu value) { - reg_esp=(reg_esp&~cpu.stack.mask)|(reg_esp-2)&cpu.stack.mask; + reg_esp=(reg_esp&~cpu.stack.mask)|((reg_esp-2)&cpu.stack.mask); mem_writew(SegPhys(ss) + (reg_esp & cpu.stack.mask) ,value); } void CPU_Push32(Bitu value) { - reg_esp=(reg_esp&~cpu.stack.mask)|(reg_esp-4)&cpu.stack.mask; + reg_esp=(reg_esp&~cpu.stack.mask)|((reg_esp-4)&cpu.stack.mask); mem_writed(SegPhys(ss) + (reg_esp & cpu.stack.mask) ,value); } Bitu CPU_Pop16(void) { Bitu val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - reg_esp=(reg_esp&~cpu.stack.mask)|(reg_esp+2)&cpu.stack.mask; + reg_esp=(reg_esp&~cpu.stack.mask)|((reg_esp+2)&cpu.stack.mask); return val; } Bitu CPU_Pop32(void) { Bitu val=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - reg_esp=(reg_esp&~cpu.stack.mask)|(reg_esp+4)&cpu.stack.mask; + reg_esp=(reg_esp&~cpu.stack.mask)|((reg_esp+4)&cpu.stack.mask); return val; } From 33d5b78c13c318fa271c9fb9024d7f711a7143f5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 14 Jan 2004 17:17:01 +0000 Subject: [PATCH 1503/4131] Remove the extra cycle for LSS instructions Remove some comments Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1584 --- src/cpu/core_normal/prefix_0f.h | 3 --- src/cpu/core_normal/prefix_66_0f.h | 1 - src/cpu/core_normal/prefix_none.h | 1 - 3 files changed, 5 deletions(-) diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 44bb1b24..09122714 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -121,10 +121,8 @@ *rmrw=(Bit16u)limit; } break; -#if !(C_DEBUG) CASE_0F_B(0x06) /* CLTS */ break; -#endif CASE_0F_B(0x20) /* MOV Rd.CRx */ { GetRM; @@ -298,7 +296,6 @@ break; CASE_0F_W(0xb2) /* LSS Ew */ { - CPU_Cycles++; GetRMrw;GetEAa; LOADSEG(ss,LoadMw(eaa+2)); *rmrw=LoadMw(eaa); diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 65a10402..d23ab4cc 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -216,7 +216,6 @@ { GetRMrd;GetEAa; LOADSEG(ss,LoadMw(eaa+4)); - CPU_Cycles++; *rmrd=LoadMd(eaa); break; } diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 99df7d44..a819fbda 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -190,7 +190,6 @@ CASE_W(0x53) /* PUSH BX */ Push_16(reg_bx);break; CASE_W(0x54) /* PUSH SP */ -//TODO Check if this is correct i think it's SP+2 or something Push_16(reg_sp);break; CASE_W(0x55) /* PUSH BP */ Push_16(reg_bp);break; From e5cf2a9b40f8c87b141197ed8fd5f1ffcdaa327f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 14 Jan 2004 17:19:43 +0000 Subject: [PATCH 1504/4131] Add entry for CLTS instruction Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1585 --- src/cpu/core_full/load.h | 3 +++ src/cpu/core_full/optable.h | 4 ++-- src/cpu/core_full/support.h | 6 +++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index d5b7987b..74009c6f 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -526,6 +526,9 @@ l_M_Ed: LEAVECORE; CPU_HLT(IPPoint-inst.opcode_start); return CBRET_NONE; + case D_CLTS: + //TODO Really clear it sometime + goto nextopcode; default: LOG(LOG_CPU,LOG_ERROR)("LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry); break; diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 7b24e956..fdd3454a 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -184,7 +184,7 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,O_GRP6w ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7w ,S_Ew ,M_Ew }, {L_MODRM ,O_LAR ,S_Gw ,M_Ew },{L_MODRM ,O_LSL ,S_Gw ,M_Ew }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{D_CLTS ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x108 - 0x10f */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, @@ -540,7 +540,7 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,O_GRP6d ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7d ,S_Ew ,M_Ew }, {L_MODRM ,O_LAR ,S_Gd ,M_Ew },{L_MODRM ,O_LSL ,S_Gd ,M_Ew }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{D_CLTS ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x308 - 0x30f */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index d3e94623..9306928c 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -38,12 +38,12 @@ enum { D_NOP,D_WAIT, D_ENTERw,D_ENTERd, D_LEAVEw,D_LEAVEd, - L_ERROR, - + D_RETFw,D_RETFd, D_RETFwIw,D_RETFdIw, D_CPUID, - D_HLT, + D_HLT,D_CLTS, + L_ERROR, }; From 83711af6713989e98bd0d1c8fc89f1ad68bf69e0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 14 Jan 2004 17:20:28 +0000 Subject: [PATCH 1505/4131] Use CPU_Push/CPU_Pop functions for pushing and popping Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1586 --- src/cpu/core_full/loadwrite.h | 18 +++++++++++++----- src/cpu/core_normal/support.h | 11 +++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/cpu/core_full/loadwrite.h b/src/cpu/core_full/loadwrite.h index 2a9bdb09..d26e7b23 100644 --- a/src/cpu/core_full/loadwrite.h +++ b/src/cpu/core_full/loadwrite.h @@ -27,26 +27,34 @@ static INLINE Bit32u the_Fetchd(EAPoint & loc) { #define Fetchws() (Bit16s)the_Fetchw(IPPoint) #define Fetchds() (Bit32s)the_Fetchd(IPPoint) - +#if 0 static INLINE void Push_16(Bit16u blah) { reg_esp-=2; - SaveMw(SegBase(ss) + (reg_esp & cpu.stack.mask),blah); + SaveMw(SegBase(ss)+(reg_esp & cpu.stack.mask),blah); } static INLINE void Push_32(Bit32u blah) { reg_esp-=4; - SaveMd(SegBase(ss) + (reg_esp & cpu.stack.mask),blah); + SaveMd(SegBase(ss)+(reg_esp & cpu.stack.mask),blah); } static INLINE Bit16u Pop_16(void) { - Bit16u temp=LoadMw(SegBase(ss) + (reg_esp & cpu.stack.mask)); + Bit16u temp=LoadMw(SegBase(ss)+(reg_esp & cpu.stack.mask)); reg_esp+=2; return temp; } static INLINE Bit32u Pop_32(void) { - Bit32u temp=LoadMd(SegBase(ss) + (reg_esp & cpu.stack.mask)); + Bit32u temp=LoadMd(SegBase(ss)+(reg_esp & cpu.stack.mask)); reg_esp+=4; return temp; } +#else + +#define Push_16 CPU_Push16 +#define Push_32 CPU_Push32 +#define Pop_16 CPU_Pop16 +#define Pop_32 CPU_Pop32 + +#endif diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index 0ef11b6e..24470736 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -79,6 +79,8 @@ static INLINE Bit32s Fetchds() { return Fetchd(); } +#if 0 + static INLINE void Push_16(Bit16u blah) { reg_esp-=2; SaveMw(SegBase(ss)+(reg_esp & cpu.stack.mask),blah); @@ -101,6 +103,15 @@ static INLINE Bit32u Pop_32() { return temp; }; +#else + +#define Push_16 CPU_Push16 +#define Push_32 CPU_Push32 +#define Pop_16 CPU_Pop16 +#define Pop_32 CPU_Pop32 + +#endif + #define JumpSIb(blah) \ if (blah) { \ ADDIPFAST(Fetchbs()); \ From 1c84baf8a8698b6afd64874d70bbfe81010f16b0 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 14 Jan 2004 19:54:14 +0000 Subject: [PATCH 1506/4131] improved logging; added logging for ldt, gdt, idt; fixed bug when displaying memory above 8mb Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1587 --- src/debug/debug.cpp | 125 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 116 insertions(+), 9 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index b3d7325d..f21292b9 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.50 2004-01-10 14:03:34 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.51 2004-01-14 19:54:14 finsterr Exp $ */ #include "programs.h" @@ -56,6 +56,9 @@ static void DEBUG_RaiseTimerIrq(void); char* AnalyzeInstruction(char* inst, bool saveSelector); void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num); Bit32u GetHexValue(char* str, char*& hex); +void LogGDT(void); +void LogLDT(void); +void LogIDT(void); class DEBUG; @@ -63,6 +66,13 @@ DEBUG* pDebugcom = 0; bool exitLoop = false; bool logHeavy = false; +// Heavy Debugging Vars for logging +#if C_HEAVY_DEBUG +static FILE* cpuLogFile = 0; +static bool cpuLog = false; +static int cpuLogCounter = 0; +#endif + static struct { Bit32u eax,ebx,ecx,edx,esi,edi,ebp,esp,eip; } oldregs; @@ -592,7 +602,9 @@ static void DrawData(void) { mvwprintw (dbg.win_data,1+y,0,"%04X:%04X ",dataSeg,add); for (int x=0; x<16; x++) { address = GetAddress(dataSeg,add); - if (address<8*1024*1024) ch = mem_readb(address); else ch = 0; + if (!(paging.tlb.handler[address >> 12]->flags & PFLAG_INIT)) { + ch = mem_readb(address); + } else ch = 0; mvwprintw (dbg.win_data,1+y,11+3*x,"%02X",ch); if (ch<32) ch='.'; mvwprintw (dbg.win_data,1+y,60+x,"%c",ch); @@ -991,14 +1003,27 @@ bool ParseCommand(char* str) DEBUG_ShowMsg("DEBUG: Set data overview to %04X:%04X",dataSeg,dataOfs); return true; } +#if C_HEAVY_DEBUG found = strstr(str,"LOG "); if (found) { // Create Cpu log file found+=4; DEBUG_ShowMsg("DEBUG: Starting log"); - DEBUG_Log_Loop(GetHexValue(found,found)); - DEBUG_ShowMsg("DEBUG: Logfile LOGCPU.TXT created."); +// DEBUG_Log_Loop(GetHexValue(found,found)); + cpuLogFile = fopen("LOGCPU.TXT","wt"); + if (!cpuLogFile) { + DEBUG_ShowMsg("DEBUG: Logfile couldnt be created."); + return false; + } + cpuLog = true; + cpuLogCounter = GetHexValue(found,found); + + debugging=false; + CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); + ignoreAddressOnce = SegPhys(cs)+reg_eip; + DOSBOX_SetNormalLoop(); return true; } +#endif found = strstr(str,"SR "); if (found) { // Set register value found+=2; @@ -1056,7 +1081,22 @@ bool ParseCommand(char* str) DEBUG_ShowMsg("%s",out2); }; -/* found = strstr(str,"EXCEPTION "); + found = strstr(str,"GDT"); + if (found) { + LogGDT(); + } + + found = strstr(str,"LDT"); + if (found) { + LogLDT(); + } + + found = strstr(str,"IDT"); + if (found) { + LogIDT(); + } + + /* found = strstr(str,"EXCEPTION "); if (found) { found += 9; Bit8u num = GetHexValue(found,found); @@ -1387,10 +1427,64 @@ void DEBUG_DrawScreen(void) { DrawCode(); DrawRegisters(); } + static void DEBUG_RaiseTimerIrq(void) { PIC_ActivateIRQ(0); } +void LogGDT(void) +{ + char out1[512]; + Descriptor desc; + Bitu length = cpu.gdt.GetLimit(); + PhysPt address = cpu.gdt.GetBase(); + PhysPt max = address + length; + Bitu i = 0; + LOG(LOG_MISC,LOG_ERROR)("GDT Base:%08X Limit:%08X",address,length); + while (address0) { + static char buffer[4096]; + LogInstruction(SegValue(cs),reg_eip,buffer); + fprintf(cpuLogFile,"%s",buffer); + cpuLogCounter--; + } + if (cpuLogCounter<=0) { + fclose(cpuLogFile); + DEBUG_ShowMsg("DEBUG: cpu log LOGCPU.TXT created"); + cpuLog = false; + DEBUG_EnableDebugger(); + return true; + } + } // LogInstruction if (logHeavy) DEBUG_HeavyLogInstruction(); @@ -1734,7 +1842,6 @@ bool DEBUG_HeavyIsBreakpoint(void) return false; } PhysPt where = SegPhys(cs)+reg_eip; - if (CBreakpoint::CheckBreakpoint(SegValue(cs),reg_eip)) { return true; } From c311d0249de72c929c69db0f219190d4c0455264 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 14 Jan 2004 20:54:41 +0000 Subject: [PATCH 1507/4131] added function 0x88 and 0x89 (thanks c2woody) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1588 --- src/ints/xms.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index e3b1b06a..84136250 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.30 2004-01-10 14:03:35 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.31 2004-01-14 20:54:41 finsterr Exp $ */ #include #include @@ -52,6 +52,8 @@ #define XMS_RESIZE_EXTENDED_MEMORY_BLOCK 0x0f #define XMS_ALLOCATE_UMB 0x10 #define XMS_DEALLOCATE_UMB 0x11 +#define XMS_QUERY_ANY_FREE_MEMORY 0x88 +#define XMS_ALLOCATE_ANY_MEMORY 0x89 #define HIGH_MEMORY_NOT_EXIST 0x90 #define HIGH_MEMORY_IN_USE 0x91 @@ -282,6 +284,9 @@ Bitu XMS_Handler(void) { case XMS_QUERY_FREE_EXTENDED_MEMORY: /* 08 */ reg_bl = XMS_QueryFreeMemory(reg_ax,reg_dx); break; + case XMS_ALLOCATE_ANY_MEMORY: /* 89 */ + reg_edx &= 0xffff; + // fall through case XMS_ALLOCATE_EXTENDED_MEMORY: /* 09 */ { Bit16u handle = 0; @@ -326,7 +331,12 @@ Bitu XMS_Handler(void) { case XMS_DEALLOCATE_UMB: /* 11 */ LOG(LOG_MISC,LOG_ERROR)("XMS:Unhandled call %2X",reg_ah); break; - + case XMS_QUERY_ANY_FREE_MEMORY: /* 88 */ + reg_bl = XMS_QueryFreeMemory(reg_ax,reg_dx); + reg_eax &= 0xffff; + reg_edx &= 0xffff; + reg_ecx = (MEM_TotalPages()*MEM_PAGESIZE)-1; // highest known physical memory address + break; } // LOG(LOG_MISC,LOG_ERROR)("XMS: CALL Result: %02X",reg_bl); return CBRET_NONE; From a8041285c4e0b115aab0dd095309b4e538a6e07d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 16 Jan 2004 14:20:03 +0000 Subject: [PATCH 1508/4131] FAQ update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1589 --- README | 51 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/README b/README index 4a7d377f..29066d8e 100644 --- a/README +++ b/README @@ -1,18 +1,18 @@ -DOSBox v0.60 +DOSBox v0.61 ===== NOTE: ===== -While we hope that, one day, DosBox will run virtually all programs -ever made for the PC...we are not there yet. At present, DosBox run on a 1.7 +While we hope that, one day, DOSBox will run virtually all programs +ever made for the PC...we are not there yet. At present, DOSBox run on a 1.7 Gigahertz PC is roughly the equivalent of a 25MHz 386 PC. While the 0.60 release has added support for "protected mode" allowing for more complex and recent programs, but note that this support is early in development and nowhere near as complete as the support for 386 real-mode games (or earlier). Also note that "protected mode" games need substantially more resources and may require a much faster processor for you to run it properly -in DosBox. +in DOSBox. ====== Usage: @@ -63,7 +63,7 @@ In Windows you can also drag directories/files onto the dosbox executable. Internal Programs: ================== -dosbox supports most of the DOS commands found in command.com. +DOSBox supports most of the DOS commands found in command.com. In addition, the following commands are available: MOUNT "Emulated Drive letter" "Real Drive or Directory" @@ -111,13 +111,13 @@ MOUNT -cd Note: It's possible to mount a local directory as cdrom drive. Hardware support is then missing. - Basically, MOUNT allows you to connect real hardware to DosBox's "emulated" - PC. So MOUNT C C:\ tells DosBox to use your real C: drive as drive C: in + Basically, MOUNT allows you to connect real hardware to DOSBox's "emulated" + PC. So MOUNT C C:\ tells DOSBox to use your real C: drive as drive C: in DosBox. It also allows you to change the drive's letter identification for programs that demand specific drive letters. For example: Touche: Adventures of The Fifth Musketeer must be run on your C: - drive. Using DosBox and it's mount command, you can trick into thinking it + drive. Using DOSBox and it's mount command, you can trick into thinking it is on C drive while placing it where you want it. For example, if the game were in D:\TOUCHE, you can use the command MOUNT C D:\ would allow you to run Touche from the D drive. @@ -133,7 +133,7 @@ MOUNT -cd mount d /media/cdrom -t cdrom -usecd 0 4. To mount a drive with 870 mb free diskspace (rarely needed! experts only): mount c d:\ -size 4025,127,16513,1700 - 5. to mount /home/dos/dosgames as drive C in dosbox: + 5. To mount /home/dos/dosgames as drive C in DOSBox: mount c /home/dos/dosgames MEM @@ -143,6 +143,11 @@ CONFIG [-writeconf] [-writelang] localfile Write the current configuration or language settings to file. "localfile" is located on the local drive !!! + Example: + To create a configfile in your current directory: + config -writeconf dosbox.conf + + LOADFIX [-size] [program] [program-parameters] LOADFIX -f Program to "eat up" memory. Useful for old programs which don't expect much @@ -247,6 +252,32 @@ Q: The sound stutters. A: You're using too much cpu power to keep dosbox running at the current speed. You can either lower the cycles or skip frames or get a faster machine. +Q: I can't type \ in DOSBox. +A: This is a known problem. It only occurs if your keyboard layout isn't US- + International. Some possible fixes: + 1. Switch your keyboard layout. + 2. Use / instead. + 3. Add the commands you want to execute in dosbox.conf + +Q: The game/application can't find it's CD-ROM. +A: Be sure to mount the CD-ROM with -t cdrom switch. Also try adding the cor- + rect label (-label LABEL). To enable more low-level cdrom support add + the following switch to mount -usecd #, where # is the number of your CD-ROM + drive reported by mount -cd. If you run Win32 you can specify -ioctl or + -aspi. Look at the description elsewhere in this document for their meaning. + +Q: The game/application runs much too slow! +A: Look at the secion "To run resource-demanding games" for more information + +Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. +A: This is possible! Just create a config file: config -writeconf dosbox.conf . + Startup your favourite editor and look at all the settings present. To + start dosbox with your new settings: dosbox -conf dosbox.conf + +Q: Great README, but I still don't get it. +A: While unlikely this seems to happen. Maybe a look at "The Newbie's + pictorial guide to dosbox" located at + http://vogons.zetafleet.com/viewforum.php?f=39 might help you. For more questions check the site/forum: http://dosbox.sourceforge.net @@ -269,7 +300,7 @@ The Language File: A language file can be generated by CONFIG.COM. Read it and you will hopefully understand how to change it. -Start Dosbox with the -lang switch to use your new language file +Start DOSBox with the -lang switch to use your new language file or you can setup the filename in the config file in the [dosbox] section. There's a language= entry that can be changed with the filename. From 9cf9cce730e6589153550029a29185aa75ee7a70 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 16 Jan 2004 15:57:19 +0000 Subject: [PATCH 1509/4131] changes for 0.61 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1590 --- ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 90cdcdbc..53209bde 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +0.61 + - improved exception handling + - debugger: fixes; logging of gdt,lgt,idt + - 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!) + 0.60 - rewrote memory system for future paging support - fixed several EMS and XMS bugs and rewrite for new memory system From 62864346eb5a045c34328d8de4201c9b0b818cb6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 16 Jan 2004 16:51:12 +0000 Subject: [PATCH 1510/4131] enhanchements suggested by wjp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1591 --- README | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/README b/README index 29066d8e..1db209a7 100644 --- a/README +++ b/README @@ -253,26 +253,27 @@ A: You're using too much cpu power to keep dosbox running at the current speed. You can either lower the cycles or skip frames or get a faster machine. Q: I can't type \ in DOSBox. -A: This is a known problem. It only occurs if your keyboard layout isn't US- - International. Some possible fixes: +A: This is a known problem. It only occurs if your keyboard layout isn't US. + Some possible fixes: 1. Switch your keyboard layout. 2. Use / instead. 3. Add the commands you want to execute in dosbox.conf -Q: The game/application can't find it's CD-ROM. +Q: The game/application can't find its CD-ROM. A: Be sure to mount the CD-ROM with -t cdrom switch. Also try adding the cor- rect label (-label LABEL). To enable more low-level cdrom support add - the following switch to mount -usecd #, where # is the number of your CD-ROM - drive reported by mount -cd. If you run Win32 you can specify -ioctl or - -aspi. Look at the description elsewhere in this document for their meaning. + the following switch to mount: -usecd #, where # is the number of your + CD-ROM drive reported by mount -cd. If you run Win32 you can specify -ioctl + or -aspi. Look at the description elsewhere in this document for their + meaning. Q: The game/application runs much too slow! -A: Look at the secion "To run resource-demanding games" for more information +A: Look at the secion "To run resource-demanding games" for more information. Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. A: This is possible! Just create a config file: config -writeconf dosbox.conf . Startup your favourite editor and look at all the settings present. To - start dosbox with your new settings: dosbox -conf dosbox.conf + start DOSBox with your new settings: dosbox -conf dosbox.conf Q: Great README, but I still don't get it. A: While unlikely this seems to happen. Maybe a look at "The Newbie's From 902533e07943c3ee359980c16e3df7b2c8f7b09a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 16 Jan 2004 16:58:58 +0000 Subject: [PATCH 1511/4131] more suggestions by wjp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1592 --- README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README b/README index 1db209a7..c3380b4e 100644 --- a/README +++ b/README @@ -268,7 +268,7 @@ A: Be sure to mount the CD-ROM with -t cdrom switch. Also try adding the cor- meaning. Q: The game/application runs much too slow! -A: Look at the secion "To run resource-demanding games" for more information. +A: Look at the section "To run resource-demanding games" for more information. Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. A: This is possible! Just create a config file: config -writeconf dosbox.conf . @@ -293,7 +293,7 @@ The file is divided into several sections (the names have [] around it). Some sections have options which you can set. # and % indicate commentlines. The generated configfile contains the current settings. You can alter them and -start dosbox with the -conf switch to load the file and use these settings. +start DOSBox with the -conf switch to load the file and use these settings. ================== The Language File: From ca58b4cf619dc4a7d25fcff71aff471c7c93add2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 17 Jan 2004 09:56:33 +0000 Subject: [PATCH 1512/4131] Fix up hercules graphics mode a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1593 --- src/hardware/vga_draw.cpp | 7 +++---- src/hardware/vga_memory.cpp | 7 ++++++- src/hardware/vga_misc.cpp | 16 +++++++++------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 63cc6773..0843f384 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -28,7 +28,7 @@ #define FIXED_CGA_SIZED 1 static void VGA_HERC_Draw(Bit8u * bitdata,Bitu pitch) { - Bit8u * reader=&vga.mem.linear[(vga.herc.mode_control & 0x80) ? 8*1024 : 0]; + Bit8u * reader=&vga.mem.linear[0]; for (Bitu y=0;y> 7); + mask|=0x80; + VGA_SetupHandlers(); } - vga.herc.mode_control=val; + vga.herc.mode_control=(vga.herc.mode_control & ~mask) | (val&mask); break; case 0x3bf: vga.herc.enable_bits=val; @@ -248,8 +251,6 @@ static Bit8u read_hercules(Bit32u port) { void VGA_SetupMisc(void) { -// if (machine==MCH_HERC) EnableHercules(); - vga.herc.enable_bits=0; IO_RegisterWriteHandler(0x3d8,write_p3d8,"VGA Feature Control Register"); IO_RegisterWriteHandler(0x3d9,write_p3d9,"CGA Color Select Register"); @@ -259,6 +260,7 @@ void VGA_SetupMisc(void) { IO_RegisterReadHandler(0x3cc,read_p3cc,"VGA Misc Output"); if (machine==MCH_HERC || machine==MCH_AUTO) { + vga.herc.mode_control=0x8; IO_RegisterWriteHandler(0x3b8,write_hercules,"Hercules"); IO_RegisterWriteHandler(0x3bf,write_hercules,"Hercules"); } From 755240bdf3db52d2acc917b01ce6b5d987153030 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 18 Jan 2004 15:40:09 +0000 Subject: [PATCH 1513/4131] Fix page not getting selected with hercules Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1594 --- src/hardware/vga_misc.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 1b4439f5..693eed58 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -207,12 +207,11 @@ static Bit8u read_p3cc(Bit32u port) { static void write_hercules(Bit32u port,Bit8u val) { - Bit8u mask; switch (port) { case 0x3b8: - mask=0xff-0x80-0x2;; - if (vga.herc.enable_bits & 1) { - mask|=0x2; + vga.herc.mode_control=(vga.herc.mode_control & ~0x7d) | (val&0x7d); + if ((vga.herc.enable_bits & 1) && ((vga.herc.mode_control ^ val)&0x2)) { + vga.herc.mode_control^=0x2; if (vga.mode != M_HERC || vga.mode != M_TEXT2) { VGA_ATTR_SetPalette(1,0x07); /* Force 0x3b4/5 registers */ @@ -224,11 +223,10 @@ static void write_hercules(Bit32u port,Bit8u val) { if (vga.mode != M_TEXT2) VGA_SetMode(M_TEXT2); } } - if (vga.herc.enable_bits & 0x2) { - mask|=0x80; + if ((vga.herc.enable_bits & 0x2) && ((vga.herc.mode_control ^ val)&0x80)) { + vga.herc.mode_control^=0x80; VGA_SetupHandlers(); } - vga.herc.mode_control=(vga.herc.mode_control & ~mask) | (val&mask); break; case 0x3bf: vga.herc.enable_bits=val; From 6238a9425730ab961736f9e9bc2ce99a1114d659 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 19 Jan 2004 17:51:04 +0000 Subject: [PATCH 1514/4131] Fixed canocialize pathname. Psychic detective Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1595 --- src/dos/dos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 2e903e87..4e70e7a4 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.63 2004-01-10 14:03:34 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.64 2004-01-19 17:51:04 qbix79 Exp $ */ #include #include @@ -763,7 +763,7 @@ static Bitu DOS_21Handler(void) { break; } case 0x60: /* Canonicalize filename or path */ - MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); + MEM_StrCopy(SegPhys(ds)+reg_si,name1,DOSNAMEBUF); if (DOS_Canonicalize(name1,name2)) { MEM_BlockWrite(SegPhys(es)+reg_di,name2,strlen(name2)+1); CALLBACK_SCF(false); From 4976c1fea05bba11fbf6f9aa3b3697ec0211ee33 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 19 Jan 2004 18:54:15 +0000 Subject: [PATCH 1515/4131] changed esc7ea case 5 and 7 to load 64s instead of 32s Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1596 --- src/fpu/fpu.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 2d75e6ba..e8af0880 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu.cpp,v 1.16 2004-01-10 14:03:34 qbix79 Exp $ */ +/* $Id: fpu.cpp,v 1.17 2004-01-19 18:54:15 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU @@ -572,7 +572,7 @@ void FPU_ESC5_Normal(Bitu rm) { void FPU_ESC6_EA(Bitu rm,PhysPt addr) { /* 16 bit (word integer) operants */ Bit16s blah = mem_readw(addr); - fpu.regs[8].d = static_cast(blah); + fpu.regs[8].d = static_cast(blah); EATREE(rm); } @@ -628,7 +628,7 @@ void FPU_ESC7_EA(Bitu rm,PhysPt addr) { case 0x00: /* FILD Bit16s */ { Bit16s blah = mem_readw(addr); - FPU_PUSH( static_cast(blah)); + FPU_PUSH( static_cast(blah)); } break; case 0x01: /* FISTTP Bit16s */ @@ -642,18 +642,25 @@ void FPU_ESC7_EA(Bitu rm,PhysPt addr) { mem_writew(addr,static_cast(FROUND(fpu.regs[TOP].d))); FPU_FPOP(); break; - case 0x05: /* FILD Bit32s */ + case 0x05: /* FILD Bit64s */ { - Bit32s blah = mem_readd(addr); - FPU_PUSH( static_cast(blah)); + FPU_Reg blah; + blah.l.lower = mem_readd(addr); + blah.l.upper = mem_readd(addr+4); + FPU_PUSH(static_cast(blah.ll)); } break; case 0x06: /* FBSTP packed BCD */ FPU_FBST(addr); FPU_FPOP(); break; - case 0x07: /* FISTP Bit32s */ - mem_writed(addr,static_cast(FROUND(fpu.regs[TOP].d))); + case 0x07: /* FISTP Bit64s */ + { + FPU_Reg blah; + blah.ll = static_cast(FROUND(fpu.regs[TOP].d)); + mem_writed(addr,blah.l.lower); + mem_writed(addr+4,blah.l.upper); + } FPU_FPOP(); break; case 0x04: /* FBLD packed BCD */ From 2e8a1efcbd854c50c73a22e728ec0be95cc05380 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 21 Jan 2004 07:43:10 +0000 Subject: [PATCH 1516/4131] Add patch by khalek to add midi command 0xd0 to ALSA driver Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1597 --- src/gui/midi_alsa.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 50acebdb..33ff330d 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_alsa.h,v 1.5 2004-01-10 14:03:35 qbix79 Exp $ */ +/* $Id: midi_alsa.h,v 1.6 2004-01-21 07:43:10 harekiet Exp $ */ #include #include @@ -106,6 +106,10 @@ public: snd_seq_ev_set_pgmchange(&ev, chanID, midiCmd[1]); send_event(0); break; + case 0xD0: + snd_seq_ev_set_chanpress(&ev, chanID, midiCmd[1]); + send_event(0); + break; case 0xE0:{ long theBend = ((long)midiCmd[1] + (long)(midiCmd[2] << 7)) - 0x2000; snd_seq_ev_set_pitchbend(&ev, chanID, theBend); From d38d9a014f68ee8c50cc12c8889348478b22190e Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Thu, 22 Jan 2004 00:32:41 +0000 Subject: [PATCH 1517/4131] Canadacow changes for 0.61 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1598 --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index 53209bde..c2d65928 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,8 @@ - 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) 0.60 - rewrote memory system for future paging support From 143bad813b60e6f9b94338ab86b9b11be6c4fd4d Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Thu, 22 Jan 2004 01:50:51 +0000 Subject: [PATCH 1518/4131] Canadacow changes for 0.61 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1599 --- README | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README b/README index c3380b4e..6937dd94 100644 --- a/README +++ b/README @@ -275,6 +275,33 @@ A: This is possible! Just create a config file: config -writeconf dosbox.conf . Startup your favourite editor and look at all the settings present. To start DOSBox with your new settings: dosbox -conf dosbox.conf +Q: What sound hardware does DosBox presently emulate? +A: DosBox emulates several legacy sound devices: + - Internal PC speaker + This emulation includes both the tone generator and several forms of digital + sound output through the internal speaker. + - Creative CMS/Gameblaster + The is the first card released by Creative Labs(R). The default configuration places + it on port 0x220. It should be noted that enabling this with the Adlib emulation may + result in conflicts. + - Tandy 3 voice + The emulation of this sound hardware is complete with the exception of the noise channel, + which is not very well documented and as such is only a best guess as to the sound's accuracy. + - Adlib + Borrowed from MAME, this emulation is almost perfect and includes the Adlib's ability to almost + play digitized sound. + - SoundBlaster Pro + Coupled with the Adlib, DosBox provides Soundblaster Pro level 8-bit stereo sound. + - Disney Soundsource + Using the printer port, this sound device outputs digital sound only. + - Gravis Ultrasound + The emulation of this hardware is nearly complete, though the MIDI capabilities have been left + out since an MPU-401 has been emulated in other code. + - MPU-401 + A MIDI passthrough interface is also emulated. This method of sound output will only work when + used with a General Midi or MT-32 device. + + Q: Great README, but I still don't get it. A: While unlikely this seems to happen. Maybe a look at "The Newbie's pictorial guide to dosbox" located at From 8b68de7de2dbd7bbfec72cb642358682de8de6f1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 25 Jan 2004 12:53:29 +0000 Subject: [PATCH 1519/4131] Add pmode exceptions for cli/sti/popf Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1600 --- src/cpu/core_normal/prefix_66.h | 9 +++++++-- src/cpu/core_normal/prefix_none.h | 21 ++++++++++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 22c7b67a..4b52dfa5 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -355,6 +355,11 @@ Push_32(reg_flags); break; CASE_D(0x9d) /* POPFD */ + if ((reg_flags & FLAG_VM) && ((reg_flags & FLAG_IOPL)!=FLAG_IOPL)) { + LEAVECORE;reg_eip-=core.ip_lookup-core.op_start; + CPU_Exception(13,0); + goto decode_start; + } SETFLAGSd(Pop_32()) #if CPU_TRAP_CHECK if (GETFLAG(TF)) { @@ -362,7 +367,7 @@ goto decode_end; } #endif -#ifdef CPU_PIC_CHECK +#if CPU_PIC_CHECK if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; #endif @@ -499,7 +504,7 @@ return CBRET_NONE; } #endif -#ifdef CPU_PIC_CHECK +#if CPU_PIC_CHECK if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; #endif //TODO TF check diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index a819fbda..366299d6 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -557,6 +557,11 @@ Push_16(reg_flags); break; CASE_W(0x9d) /* POPF */ + if ((reg_flags & FLAG_VM) && ((reg_flags & FLAG_IOPL)!=FLAG_IOPL)) { + LEAVECORE;reg_eip-=core.ip_lookup-core.op_start; + CPU_Exception(13,0); + goto decode_start; + } SETFLAGSw(Pop_16()); #if CPU_TRAP_CHECK if (GETFLAG(TF)) { @@ -564,7 +569,7 @@ goto decode_end; } #endif -#ifdef CPU_PIC_CHECK +#if CPU_PIC_CHECK if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; #endif break; @@ -787,7 +792,7 @@ { LEAVECORE; CPU_IRET(false); -#ifdef CPU_PIC_CHECK +#if CPU_PIC_CHECK if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; #endif #if CPU_TRAP_CHECK @@ -1053,11 +1058,21 @@ SETFLAGBIT(CF,true); break; CASE_B(0xfa) /* CLI */ + if (cpu.pmode && (GETFLAG_IOPL Date: Mon, 26 Jan 2004 14:08:16 +0000 Subject: [PATCH 1520/4131] Fixed bug with countervalue being signed Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1601 --- src/ints/bios.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 861bd540..4f328978 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.27 2004-01-10 14:03:35 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.28 2004-01-26 14:08:16 qbix79 Exp $ */ #include #include "dosbox.h" @@ -39,7 +39,7 @@ static Bitu INT70_Handler(void) { IO_Write(0x70,0xc); IO_Read(0x71); if (mem_readb(BIOS_WAIT_FLAG_ACTIVE)) { - Bits count=mem_readd(BIOS_WAIT_FLAG_COUNT); + Bit32u count=mem_readd(BIOS_WAIT_FLAG_COUNT); if (count>997) { mem_writed(BIOS_WAIT_FLAG_COUNT,count-997); } else { @@ -204,6 +204,7 @@ static Bitu INT15_Handler(void) { break; case 0x83: /* BIOS - SET EVENT WAIT INTERVAL */ { + if(reg_al == 0x01) LOG(LOG_BIOS,LOG_WARN)("Bios set event interval cancelled: not handled"); if (mem_readb(BIOS_WAIT_FLAG_ACTIVE)) { reg_ah=0x80; CALLBACK_SCF(true); From cd4ac0330983c6eb7cb3b63f040e403b71367bdc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 26 Jan 2004 14:48:58 +0000 Subject: [PATCH 1521/4131] Added fake romsize(Fizzban) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1602 --- src/ints/int10_memory.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 3466a7e1..ceb725f6 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -79,8 +79,9 @@ void INT10_SetupRomMemory(void) { /* This should fill up certain structures inside the Video Bios Rom Area */ PhysPt rom_base=PhysMake(0xc000,0); Bitu i; - int10.rom.used=2; + int10.rom.used=3; // int10.rom.used=2; Size of ROM added phys_writew(rom_base+0,0xaa55); + phys_writeb(rom_base+2,0x40); // Size of ROM: 64 512-blocks = 32KB int10.rom.font_8_first=RealMake(0xC000,int10.rom.used); for (i=0;i<128*8;i++) { phys_writeb(rom_base+int10.rom.used++,int10_font_08[i]); From c3f91386daef559789ad31846270f04132a3f5a2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 26 Jan 2004 15:10:16 +0000 Subject: [PATCH 1522/4131] Added changes suggested by the alsa team Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1603 --- src/gui/midi_alsa.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 33ff330d..988f98b0 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -16,8 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_alsa.h,v 1.6 2004-01-21 07:43:10 harekiet Exp $ */ +/* $Id: midi_alsa.h,v 1.7 2004-01-26 15:10:16 qbix79 Exp $ */ +#define ALSA_PCM_OLD_HW_PARAMS_API +#define ALSA_PCM_OLD_SW_PARAMS_API #include #include From 595d9eaf3b961a266408ac247cfd144a2e4977d4 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Mon, 26 Jan 2004 21:17:35 +0000 Subject: [PATCH 1523/4131] moved indos flag to 0x5f:0x0f (makes pharlap happy) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1604 --- src/dos/dos_tables.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 68db7bf6..93d2554d 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -49,10 +49,11 @@ Bit16u DOS_GetMemory(Bit16u pages) { void DOS_SetupTables(void) { dos_memseg=0xd000; Bit16u seg;Bitu i; - dos.tables.indosflag=RealMake(DOS_GetMemory(1),0); dos.tables.mediaid=RealMake(DOS_GetMemory(2),0); dos.tables.tempdta=RealMake(DOS_GetMemory(4),0); for (i=0;i Date: Tue, 27 Jan 2004 14:26:43 +0000 Subject: [PATCH 1524/4131] don't allow dos it's memory to be freed Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1605 --- src/dos/dos_memory.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 2279c216..e2e3d9d3 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -165,6 +165,11 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { bool DOS_FreeMemory(Bit16u segment) { //TODO Check if allowed to free this segment + if ((segment-1) < MEM_START){ + LOG(LOG_DOSMISC,LOG_ERROR)("Program tried to free %X ---ERROR",segment); + return false; + } + DOS_MCB mcb(segment-1); mcb.SetPSPSeg(MCB_FREE); DOS_CompressMemory(); From 2b88ae212e739ddd847c1994173f8b80c039a429 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 27 Jan 2004 14:52:28 +0000 Subject: [PATCH 1525/4131] 2 new debug commands(Fizzban) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1606 --- src/debug/debug.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index f21292b9..2a4f3d6f 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.51 2004-01-14 19:54:14 finsterr Exp $ */ +/* $Id: debug.cpp,v 1.52 2004-01-27 14:52:28 qbix79 Exp $ */ #include "programs.h" @@ -59,6 +59,7 @@ Bit32u GetHexValue(char* str, char*& hex); void LogGDT(void); void LogLDT(void); void LogIDT(void); +void OutputVecTable(char* filename); class DEBUG; @@ -1096,6 +1097,30 @@ bool ParseCommand(char* str) LogIDT(); } + found = strstr(str,"INTVEC "); + if (found) + { + found += 7; + while (found[0]==' ') found++; + if (found[0] != 0) + OutputVecTable(found); + } + + found = strstr(str,"INTHAND "); + if (found) + { + found += 8; + while (found[0]==' ') found++; + if (found[0] != 0) + { + Bit8u intNr = (Bit8u)GetHexValue(found,found); + DEBUG_ShowMsg("DEBUG: Set code overview to interrupt handler %X",intNr); + codeViewData.useCS = mem_readw(intNr*4+2); + codeViewData.useEIP = mem_readw(intNr*4); + return true; + } + } + /* found = strstr(str,"EXCEPTION "); if (found) { found += 9; @@ -1152,6 +1177,10 @@ bool ParseCommand(char* str) wprintw(dbg.win_out,"MEMDUMP [seg]:[off] [len] - Write memory to file memdump.txt\n"); wprintw(dbg.win_out,"SELINFO [segName] - Show selector info\n"); + + wprintw(dbg.win_out,"INTVEC [filename] - Writes interrupt vector table to file\n"); + wprintw(dbg.win_out,"INTHAND [intNum] - Set code view to interrupt handler\n"); + wprintw(dbg.win_out,"H - Help\n"); wrefresh(dbg.win_out); @@ -1767,6 +1796,22 @@ void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num) DEBUG_ShowMsg("DEBUG: Memory dump success."); }; +void OutputVecTable(char* filename) +{ + FILE* f = fopen(filename, "wt"); + if (!f) + { + DEBUG_ShowMsg("DEBUG: Output of interrupt vector table failed."); + return; + } + + for (int i=0; i<256; i++) + fprintf(f,"INT %02X: %04X:%04X\n", i, mem_readw(i*4+2), mem_readw(i*4)); + + fclose(f); + DEBUG_ShowMsg("DEBUG: Interrupt vector table written to %s.", filename); +} + // HEAVY DEBUGGING STUFF #if C_HEAVY_DEBUG From 3e170dbdcf168bd94fac6b72223ad285979ff8df Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 27 Jan 2004 20:23:13 +0000 Subject: [PATCH 1526/4131] Added patch 884060 from Martin Battig Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1607 --- configure.in | 3 ++ src/dos/Makefile.am | 2 +- src/dos/cdrom.h | 19 +++++++ src/dos/cdrom_ioctl_linux.cpp | 96 +++++++++++++++++++++++++++++++++++ src/dos/dos_mscdex.cpp | 7 +++ 5 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 src/dos/cdrom_ioctl_linux.cpp diff --git a/configure.in b/configure.in index f1cd15eb..12a1512d 100644 --- a/configure.in +++ b/configure.in @@ -166,6 +166,9 @@ case "$target" in AC_DEFINE(MACOSX, 1, [Compiling on Mac OS X]) LIBS="$LIBS -framework AudioUnit" ;; + *-*-linux-gnu*) + AC_DEFINE(LINUX, 1, [Compiling on GNU/Linux]) + ;; esac AC_OUTPUT([ diff --git a/src/dos/Makefile.am b/src/dos/Makefile.am index 14cd2780..7bd9b5af 100644 --- a/src/dos/Makefile.am +++ b/src/dos/Makefile.am @@ -6,4 +6,4 @@ libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioc dos_misc.cpp dos_classes.cpp dos_programs.cpp dos_tables.cpp \ drives.cpp drives.h drive_virtual.cpp drive_local.cpp drive_cache.cpp \ dev_con.h dos_mscdex.cpp \ - cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp + cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp cdrom_ioctl_linux.cpp diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index 3c307cfb..0159d86a 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -5,9 +5,11 @@ #define MAX_ASPI_CDROM 5 #include +#include "dosbox.h" #include "mem.h" #include "SDL.h" + #define RAW_SECTOR_SIZE 2352 #define COOKED_SECTOR_SIZE 2048 @@ -181,4 +183,21 @@ private: #endif /* WIN 32 */ +#if defined (LINUX) + +class CDROM_Interface_Ioctl : public CDROM_Interface_SDL +{ +public: + CDROM_Interface_Ioctl (void); + + bool SetDevice (char* path, int forceCD); + bool GetUPC (unsigned char& attr, char* upc); + bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); + +private: + char device_name[512]; +}; + +#endif /* LINUX */ + #endif /* __CDROM_INTERFACE__ */ diff --git a/src/dos/cdrom_ioctl_linux.cpp b/src/dos/cdrom_ioctl_linux.cpp new file mode 100644 index 00000000..f5050799 --- /dev/null +++ b/src/dos/cdrom_ioctl_linux.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2002-2004 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include +#include "cdrom.h" + +#if defined (LINUX) +#include +#include +#include +#include +#include +#include + +CDROM_Interface_Ioctl::CDROM_Interface_Ioctl(void) : CDROM_Interface_SDL() +{ + strcpy(device_name, ""); +} + +bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc) +{ + int cdrom_fd = open(device_name, O_RDONLY | O_NONBLOCK); + if (cdrom_fd <= 0) return false; + + struct cdrom_mcn cdrom_mcn; + int ret = ioctl(cdrom_fd, CDROM_GET_MCN, &cdrom_mcn); + + close(cdrom_fd); + + if (ret > 0) { + attr = 0; + strncpy(upc, (char*)cdrom_mcn.medium_catalog_number, 14); + } + + return (ret > 0); +} + +bool CDROM_Interface_Ioctl::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) +{ + int cdrom_fd = open(device_name, O_RDONLY | O_NONBLOCK); + if (cdrom_fd <= 0) return false; + + Bitu buflen = raw ? num * CD_FRAMESIZE_RAW : num * CD_FRAMESIZE; + Bit8u* buf = new Bit8u[buflen]; + int ret; + + if (raw) { + struct cdrom_read cdrom_read; + cdrom_read.cdread_lba = sector; + cdrom_read.cdread_bufaddr = (char*)buf; + cdrom_read.cdread_buflen = buflen; + + ret = ioctl(cdrom_fd, CDROMREADRAW, &cdrom_read); + } else { + ret = lseek(cdrom_fd, sector * CD_FRAMESIZE, SEEK_SET); + if (ret >= 0) ret = read(cdrom_fd, buf, buflen); + if (ret != buflen) ret = -1; + } + close(cdrom_fd); + + MEM_BlockWrite(buffer, buf, buflen); + delete[] buf; + + return (ret > 0); +} + +bool CDROM_Interface_Ioctl::SetDevice(char* path, int forceCD) +{ + bool success = CDROM_Interface_SDL::SetDevice(path, forceCD); + + if (success) { + const char* tmp = SDL_CDName(forceCD); + if (tmp) strncpy(device_name, tmp, 512); + else success = false; + } + + return success; +} + +#endif diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 5ee7c56f..f6f93650 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -260,6 +260,13 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) break; } #endif + #if defined (LINUX) + if (useCdromInterface==CDROM_USE_IOCTL) { + cdrom[numDrives] = new CDROM_Interface_Ioctl(); + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface."); + break; + } + #endif cdrom[numDrives] = new CDROM_Interface_SDL(); LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: SDL Interface."); } break; From ab187f3ef593ee22b4264140d7b64c17d3977395 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 28 Jan 2004 11:11:43 +0000 Subject: [PATCH 1527/4131] update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1608 --- ChangeLog | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c2d65928..9511bef9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,11 +1,28 @@ 0.61 - improved exception handling - - debugger: fixes; logging of gdt,lgt,idt + - 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 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 0.60 - rewrote memory system for future paging support From 670928f59061abd0570cfcb3cd5b2280701b41da Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 28 Jan 2004 12:03:07 +0000 Subject: [PATCH 1528/4131] use ioctl interface as default in linux Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1609 --- src/dos/dos_mscdex.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index f6f93650..4559914d 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -27,8 +27,8 @@ #include "cdrom.h" -//#define MSCDEX_LOG LOG(LOG_MISC,LOG_ERROR) -#define MSCDEX_LOG +#define MSCDEX_LOG LOG(LOG_MISC,LOG_ERROR) +//#define MSCDEX_LOG #define MSCDEX_VERSION_HIGH 2 #define MSCDEX_VERSION_LOW 23 @@ -261,11 +261,12 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) } #endif #if defined (LINUX) - if (useCdromInterface==CDROM_USE_IOCTL) { + // Always use IOCTL in Linux +// if (useCdromInterface==CDROM_USE_IOCTL) { cdrom[numDrives] = new CDROM_Interface_Ioctl(); LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface."); break; - } +// } #endif cdrom[numDrives] = new CDROM_Interface_SDL(); LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: SDL Interface."); From 2cfb92f5c6bc64998e9a830b931252c1ba500b49 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 28 Jan 2004 14:23:55 +0000 Subject: [PATCH 1529/4131] Check for opengl support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1610 --- configure.in | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 12a1512d..ad483f7b 100644 --- a/configure.in +++ b/configure.in @@ -132,7 +132,6 @@ 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) @@ -153,6 +152,24 @@ else AC_MSG_WARN([Can't find SDL_net, internal modem disabled]) fi +AH_TEMPLATE(C_OPENGL,[Define to 1 to use opengl display output support]) +AC_ARG_ENABLE(opengl,AC_HELP_STRING([--disable-opengl],[Disable opengl support]),,enable_opengl=yes) +AC_CHECK_LIB(GL, main, have_gl_lib=yes, have_gl_lib=no , ) +AC_CHECK_LIB(opengl32, main, have_opengl32_lib=yes,have_opengl32_lib=no , ) +AC_CHECK_HEADER(GL/gl.h, have_gl_h=yes , have_gl_h=no , ) +AC_MSG_CHECKING(whether opengl display output will be enabled) +if test x$enable_opengl = xyes -a x$have_gl_h = xyes -a x$have_gl_lib = xyes ; then + AC_MSG_RESULT(yes) + LIBS="$LIBS -lGL" + AC_DEFINE(C_OPENGL,1) +elif test x$enable_opengl = xyes -a x$have_gl_h = xyes -a x$have_opengl32_lib = xyes ; then + AC_MSG_RESULT(yes) + LIBS="$LIBS -lopengl32" + AC_DEFINE(C_OPENGL,1) +else + AC_MSG_RESULT(no) +fi + dnl Some host detection and actions for them case "$target" in *-*-cygwin* | *-*-mingw32*) @@ -171,6 +188,7 @@ case "$target" in ;; esac + AC_OUTPUT([ Makefile src/Makefile From 9bf1cd50f58616d9384ebde9a05e22f85cb50edd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 28 Jan 2004 14:39:05 +0000 Subject: [PATCH 1530/4131] Opengl output support in SDL Removed threading support in SDL Rewrite of VGA Drawing to work line for line Rewrite of VGA Text drawing using lookup tables Rewrite of render function to handle the new line for line drawing. Changed CGA/TANDY/Hercules to be more like their original hardware. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1611 --- include/render.h | 17 +- include/vga.h | 36 ++- include/video.h | 23 +- src/gui/render.cpp | 186 +++++++------ src/gui/render_normal.h | 49 ++-- src/gui/render_scale2x.h | 9 +- src/gui/sdlmain.cpp | 433 ++++++++++++++++++++---------- src/hardware/vga.cpp | 59 ++--- src/hardware/vga_crtc.cpp | 2 - src/hardware/vga_draw.cpp | 507 +++++++++++++++--------------------- src/hardware/vga_memory.cpp | 3 + 11 files changed, 714 insertions(+), 610 deletions(-) diff --git a/include/render.h b/include/render.h index bfb45ba9..49369c22 100644 --- a/include/render.h +++ b/include/render.h @@ -16,7 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - +#ifndef __RENDER_H +#define __RENDER_H enum RENDER_Operation { OP_None, @@ -25,11 +26,13 @@ enum RENDER_Operation { OP_AdvMame2x, }; -typedef void (* RENDER_Part_Handler)(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy); -typedef void (* RENDER_Draw_Handler)(RENDER_Part_Handler part_handler); - -void RENDER_DoUpdate(void); - -void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,double ratio,Bitu scalew,Bitu scaleh,RENDER_Draw_Handler draw_handler); +typedef void (* RENDER_Line_Handler)(Bit8u * src); +void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,double ratio,Bitu scalew,Bitu scaleh); +bool RENDER_StartUpdate(void); +void RENDER_EndUpdate(void); void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue); +extern RENDER_Line_Handler RENDER_DrawLine; + +#endif + diff --git a/include/vga.h b/include/vga.h index 3999bfad..c320ac44 100644 --- a/include/vga.h +++ b/include/vga.h @@ -64,9 +64,6 @@ typedef struct { bool chained; /* Enable or Disabled Chain 4 Mode */ bool blinking; /* Attribute bit 7 is blinking */ - bool vline_double; - Bit8u vline_height; - /* Pixel Scrolling */ Bit8u pel_panning; /* Amount of pixels to skip when starting horizontal line */ Bit8u hlines_skip; @@ -94,19 +91,39 @@ typedef struct { typedef struct { bool resizing; + bool drawing; Bitu width; Bitu height; Bitu pitch; - Bitu blank; + Bitu blocks; + Bitu panning; + Bitu address; + Bitu address_add; + Bitu address_line_total; + Bitu address_line; + Bitu lines_total; + Bitu lines_left; + Bitu lines_scaled; + Bitu split_line; + Bitu parts_total; + Bitu parts_lines; + Bitu parts_left; + struct { + Bitu vtotal; + Bitu vstart; + Bitu vend; + Bitu htotal; + Bitu hstart; + Bitu hend; + Bitu parts; + } micro; Bitu scaleh; - bool double_width; - bool double_height; - Bitu lines; + bool double_scan; + bool double_scan_active; Bit8u font_height; Bit8u font[64*1024]; Bitu font1_start; Bitu font2_start; - Bitu rows,cols; struct { Bit8u sline,eline; Bit8u count,delay; @@ -302,6 +319,9 @@ extern Bit32u FillTable[16]; extern Bit32u CGA_2_Table[16]; extern Bit32u CGA_4_Table[256]; extern Bit32u CGA_16_Table[256]; +extern Bit32u TXT_Font_Table[16]; +extern Bit32u TXT_FG_Table[16]; +extern Bit32u TXT_BG_Table[16]; extern Bit32u Expand16Table[4][16]; extern Bit32u Expand16BigTable[0x10000]; diff --git a/include/video.h b/include/video.h index 72151dcc..ced09ad6 100644 --- a/include/video.h +++ b/include/video.h @@ -19,21 +19,8 @@ #ifndef __VIDEO_H #define __VIDEO_H - -enum GFX_MODES { - GFX_8BPP=0, - GFX_15BPP=1, - GFX_16BPP=2, - GFX_24BPP=3, - GFX_32BPP=4, - GFX_YUV=5, - GFX_MODE_SIZE=6 -}; - typedef void (* GFX_ResetCallBack)(void); -typedef void (* GFX_RenderCallBack)(Bit8u * data,Bitu pitch); - struct GFX_PalEntry { Bit8u r; Bit8u g; @@ -46,18 +33,16 @@ struct GFX_PalEntry { void GFX_Events(void); void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries); -GFX_MODES GFX_GetBestMode(Bitu bpp,Bitu & gfx_flags); +Bitu GFX_GetBestMode(Bitu bpp,Bitu & gfx_flags); Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue); -void GFX_SetSize(Bitu width,Bitu height,GFX_MODES gfx_mode,double scalex,double scaley,GFX_ResetCallBack cb_reset, GFX_RenderCallBack cb_render); +void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,double scalex,double scaley,GFX_ResetCallBack cb_reset); void GFX_Start(void); void GFX_Stop(void); void GFX_SwitchFullScreen(void); - -void GFX_Render_Blit(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy); - -void GFX_DoUpdate(void); +bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch); +void GFX_EndUpdate(void); #endif diff --git a/src/gui/render.cpp b/src/gui/render.cpp index b435ddde..2bbfb4b0 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.22 2004-01-10 14:03:35 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.23 2004-01-28 14:39:05 harekiet Exp $ */ #include #include @@ -60,17 +60,17 @@ static struct { Bitu scalew; Bitu scaleh; double ratio; - RENDER_Draw_Handler draw_handler; } src; struct { Bitu width; Bitu height; Bitu pitch; - GFX_MODES gfx_mode; + Bitu line; + Bitu bpp; RENDER_Operation type; RENDER_Operation want_type; - RENDER_Part_Handler part_handler; - Bit8u * dest; + RENDER_Line_Handler line_handler; + Bit8u * draw; Bit8u * buffer; Bit8u * pixels; } op; @@ -90,16 +90,19 @@ static struct { #if (C_SSHOT) struct { RENDER_Operation type; - Bitu pitch; + Bitu bpp,width,height,line; const char * dir; - Bit8u * buffer; + Bit8u * buffer,* draw; + bool usesrc; } shot; #endif - bool screenshot; bool active; bool aspect; + bool updating; } render; +RENDER_Line_Handler RENDER_DrawLine; + /* Forward declerations */ static void RENDER_ResetPal(void); @@ -112,13 +115,11 @@ static void RENDER_ResetPal(void); #if (C_SSHOT) #include -static void RENDER_ShotDraw(Bit8u * src,Bitu x,Bitu y,Bitu _dx,Bitu _dy) { - Bit8u * dst=render.shot.buffer+render.src.width*y; - for (;_dy>0;_dy--) { - memcpy(dst,src,_dx); - dst+=render.src.width; - src+=render.src.pitch; - } +static void RENDER_ShotDraw(Bit8u * src) { + if (render.shot.usesrc) { + memcpy(render.shot.draw,src,render.shot.line); + render.shot.draw+=render.shot.line; + } else render.op.line_handler(src); } /* Take a screenshot of the data that should be rendered */ @@ -177,8 +178,8 @@ static void TakeScreenShot(Bit8u * bitmap) { png_set_compression_method(png_ptr, 8); png_set_compression_buffer_size(png_ptr, 8192); - if (render.src.bpp==8) { - png_set_IHDR(png_ptr, info_ptr, render.src.width, render.src.height, + if (render.shot.bpp==8) { + png_set_IHDR(png_ptr, info_ptr, render.shot.width, render.shot.height, 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); for (i=0;i<256;i++) { @@ -188,14 +189,14 @@ static void TakeScreenShot(Bit8u * bitmap) { } png_set_PLTE(png_ptr, info_ptr, palette,256); } else { - png_set_IHDR(png_ptr, info_ptr, render.src.width, render.src.height, - 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + png_set_IHDR(png_ptr, info_ptr, render.shot.width, render.shot.height, + render.shot.bpp, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); } /*Allocate an array of scanline pointers*/ - row_pointers=(png_bytep*)malloc(render.src.height*sizeof(png_bytep)); - for (i=0;irender.pal.last) return; Bitu i; - switch (render.op.gfx_mode) { - case GFX_8BPP: + switch (render.op.bpp) { + case 8: GFX_SetPalette(render.pal.first,render.pal.last-render.pal.first+1,(GFX_PalEntry *)&render.pal.rgb[render.pal.first]); break; - case GFX_15BPP: - case GFX_16BPP: + case 16: for (i=render.pal.first;i<=render.pal.last;i++) { Bit8u r=render.pal.rgb[i].red; Bit8u g=render.pal.rgb[i].green; @@ -239,8 +238,8 @@ static void Check_Palette(void) { render.pal.lookup.bpp16[i]=GFX_GetRGB(r,g,b); } break; - case GFX_24BPP: - case GFX_32BPP: + case 24: + case 32: for (i=render.pal.first;i<=render.pal.last;i++) { Bit8u r=render.pal.rgb[i].red; Bit8u g=render.pal.rgb[i].green; @@ -248,17 +247,6 @@ static void Check_Palette(void) { render.pal.lookup.bpp32[i]=GFX_GetRGB(r,g,b); } break; - case GFX_YUV: - for (i=render.pal.first;i<=render.pal.last;i++) { - Bit8u r=render.pal.rgb[i].red; - Bit8u g=render.pal.rgb[i].green; - Bit8u b=render.pal.rgb[i].blue; - Bit8u y = ( 9797*(r) + 19237*(g) + 3734*(b) ) >> 15; - Bit8u u = (18492*((b)-(y)) >> 15) + 128; - Bit8u v = (23372*((r)-(y)) >> 15) + 128; - render.pal.lookup.yuv[i]=(u << 0) | (y << 8) | (v << 16) | (y << 24); - } - break; } /* Setup pal index to startup values */ render.pal.first=256; @@ -278,38 +266,74 @@ void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue) { if (render.pal.last1.0) gfx_scaleh*=render.src.ratio; else gfx_scalew*=(1/render.src.ratio); - GFX_MODES gfx_mode;Bitu gfx_flags; - gfx_mode=GFX_GetBestMode(render.src.bpp,gfx_flags); + Bitu gfx_flags; + Bitu bpp=GFX_GetBestMode(render.src.bpp,gfx_flags); Bitu index; - switch (gfx_mode) { - case GFX_8BPP: index=0;break; - case GFX_15BPP: index=1;break; - case GFX_16BPP: index=1;break; - case GFX_24BPP: index=2;break; - case GFX_32BPP: index=3;break; - case GFX_YUV: index=3;break; + switch (bpp) { + case 8: index=0;break; + case 16:index=1;break; + case 24:index=2;break; + case 32:index=3;break; } /* Initial scaler testing */ switch (render.op.want_type) { @@ -358,7 +378,7 @@ normalop: if (gfx_flags & GFX_HASSCALING) { gfx_scalew*=scalew; gfx_scaleh*=scaleh; - render.op.part_handler=Normal_SINGLE_8[index]; + render.op.line_handler=Normal_8[index]; for (Bitu i=0;i1 && (render.op.type==OP_None)) { - render.op.part_handler=Normal_SINGLE_8[index]; + render.op.line_handler=Normal_8[index]; scalew>>=1;gfx_scaleh/=2; } else { - render.op.part_handler=Normal_DOUBLE_8[index]; + render.op.line_handler=Normal_2x_8[index]; } - } else render.op.part_handler=Normal_SINGLE_8[index]; + } else render.op.line_handler=Normal_8[index]; width*=scalew; double lines=0.0; gfx_scaleh=(gfx_scaleh*render.src.height-(double)render.src.height)/(double)render.src.height; @@ -426,24 +446,24 @@ normalop: break; } } - render.op.part_handler=AdvMame2x_8_Table[index]; + render.op.line_handler=AdvMame2x_8_Table[index]; } break; } - render.op.gfx_mode=gfx_mode; + render.op.bpp=bpp; render.op.width=width; render.op.height=height; - GFX_SetSize(width,height,gfx_mode,gfx_scalew,gfx_scaleh,&RENDER_ReInit,RENDER_DrawScreen); + GFX_SetSize(width,height,bpp,gfx_scalew,gfx_scaleh,&RENDER_ReInit); RENDER_ResetPal(); - GFX_Start(); + render.active=true; } -void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,double ratio,Bitu scalew,Bitu scaleh,RENDER_Draw_Handler draw_handler) { +void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,double ratio,Bitu scalew,Bitu scaleh) { if ((!width) || (!height) || (!pitch)) { - render.active=false;return; + render.active=false; + return; } - GFX_Stop(); render.src.width=width; render.src.height=height; render.src.bpp=bpp; @@ -451,9 +471,7 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,double ratio,Bitu render.src.ratio=render.aspect ? ratio : 1.0; render.src.scalew=scalew; render.src.scaleh=scaleh; - render.src.draw_handler=draw_handler; RENDER_ReInit(); - } extern void GFX_SetTitle(Bits cycles, Bits frameskip); @@ -477,8 +495,10 @@ void RENDER_Init(Section * sec) { render.aspect=section->Get_bool("aspect"); render.frameskip.max=section->Get_int("frameskip"); render.frameskip.count=0; + render.updating=true; #if (C_SSHOT) render.shot.dir=section->Get_string("snapdir"); + render.shot.usesrc=true; KEYBOARD_AddEvent(KBD_f5,KBD_MOD_CTRL,EnableScreenShot); #endif const char * scaler;std::string cline; diff --git a/src/gui/render_normal.h b/src/gui/render_normal.h index 20aded8d..95ae4ea9 100644 --- a/src/gui/render_normal.h +++ b/src/gui/render_normal.h @@ -19,46 +19,41 @@ static Bit8u normal_cache[RENDER_MAXWIDTH*2*4]; template -static void Normal(Bit8u * src,Bitu x,Bitu y,Bitu _dx,Bitu _dy) { - Bit8u * dst=render.op.pixels+(render.normal.hindex[y]*render.op.pitch); - Bitu line_size=LineSize(_dx) * (xdouble ? 2 : 1); - src+=x; +static void Normal(Bit8u * src) { + Bitu line_size=LineSize(render.src.width) * (xdouble ? 2 : 1); Bit8u * line; - for (;_dy;_dy--) { - if (sbpp == dbpp && !xdouble) { - line=src; - BituMove(dst,line,line_size); - } else { - Bit8u * line_dst=&normal_cache[0]; - Bit8u * real_dst=dst; - line=line_dst; - Bit8u * temp_src=src; - for (Bitu tempx=_dx;tempx;tempx--) { - Bitu val=ConvBPP(LoadSrc(temp_src)); + if (sbpp == dbpp && !xdouble) { + line=src; + BituMove(render.op.pixels,line,line_size); + } else { + Bit8u * line_dst=&normal_cache[0]; + Bit8u * real_dst=render.op.pixels; + line=line_dst; + Bit8u * temp_src=src; + for (Bitu tempx=render.src.width;tempx;tempx--) { + Bitu val=ConvBPP(LoadSrc(temp_src)); + AddDst(line_dst,val); + AddDst(real_dst,val); + if (xdouble) { AddDst(line_dst,val); AddDst(real_dst,val); - if (xdouble) { - AddDst(line_dst,val); - AddDst(real_dst,val); - } } } - dst+=render.op.pitch; - for (Bitu lines=render.normal.hlines[y++];lines;lines--) { - BituMove(dst,line,line_size); - dst+=render.op.pitch; - } - src+=render.src.pitch; + } + render.op.pixels+=render.op.pitch; + for (Bitu lines=render.normal.hlines[render.op.line++];lines;lines--) { + BituMove(render.op.pixels,line,line_size); + render.op.pixels+=render.op.pitch; } } -static RENDER_Part_Handler Normal_SINGLE_8[4]={ +static RENDER_Line_Handler Normal_8[4]={ Normal<8,8 ,false>,Normal<8,16,false>, Normal<8,24,false>,Normal<8,32,false>, }; -static RENDER_Part_Handler Normal_DOUBLE_8[4]={ +static RENDER_Line_Handler Normal_2x_8[4]={ Normal<8,8 ,true>,Normal<8,16,true>, Normal<8,24,true>,Normal<8,32,true>, }; diff --git a/src/gui/render_scale2x.h b/src/gui/render_scale2x.h index fcbc16f7..fc92a0ae 100644 --- a/src/gui/render_scale2x.h +++ b/src/gui/render_scale2x.h @@ -53,23 +53,24 @@ static void AdvMame2x_line(Bit8u * dst, const Bit8u * src0, const Bit8u * src1, } template -static void AdvMame2x(Bit8u * src,Bitu x,Bitu y,Bitu _dx,Bitu _dy) { +static void AdvMame2x(Bit8u * src) { +#if 0 _dy=render.advmame2x.hindex[y+_dy]; y=render.advmame2x.hindex[y]; Bit8u * dest=render.op.pixels+render.op.pitch*y; src-=render.advmame2x.line_starts[y][0]; - src+=x; for (;y<_dy;y++) { Bit8u * src0=src+render.advmame2x.line_starts[y][0]; Bit8u * src1=src+render.advmame2x.line_starts[y][1]; Bit8u * src2=src+render.advmame2x.line_starts[y][2]; - AdvMame2x_line(dest,src0,src1,src2,_dx); + AdvMame2x_line(dest,src0,src1,src2,render.src.width); dest+=render.op.pitch; } +#endif } -static RENDER_Part_Handler AdvMame2x_8_Table[4]={ +static RENDER_Line_Handler AdvMame2x_8_Table[4]={ AdvMame2x<8,8>,AdvMame2x<8,16>,AdvMame2x<8,24>,AdvMame2x<8,32> }; diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 7fc8ecb0..52336849 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.55 2004-01-08 11:47:26 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.56 2004-01-28 14:39:05 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -28,9 +28,7 @@ #include #include - #include "SDL.h" -#include "SDL_thread.h" #include "dosbox.h" #include "video.h" @@ -40,10 +38,43 @@ #include "pic.h" #include "timer.h" #include "setup.h" +#include "support.h" #include "debug.h" +#if C_OPENGL +#include "SDL_opengl.h" + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif + +#ifdef __WIN32__ +#ifndef WGL_NV_allocate_memory +#define WGL_NV_allocate_memory 1 +typedef void * (APIENTRY * PFNWGLALLOCATEMEMORYNVPROC) (int size, float readfreq, float writefreq, float priority); +typedef void (APIENTRY * PFNWGLFREEMEMORYNVPROC) (void *pointer); +PFNWGLALLOCATEMEMORYNVPROC db_glAllocateMemoryNV = NULL; +PFNWGLFREEMEMORYNVPROC db_glFreeMemoryNV = NULL; +#endif +#else + + +#endif + +#ifndef GL_NV_pixel_data_range +#define GL_NV_pixel_data_range 1 +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer); +typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); +PFNGLPIXELDATARANGENVPROC glPixelDataRangeNV = NULL; +#endif + +#endif //C_OPENGL + //#define DISABLE_JOYSTICK -#define C_GFXTHREADED 1 //Enabled by default #if !(ENVIRON_INCLUDED) extern char** environ; @@ -72,17 +103,14 @@ enum SCREEN_TYPES { struct SDL_Block { - volatile bool active; //If this isn't set don't draw - volatile bool drawing; + bool active; //If this isn't set don't draw + bool updating; struct { Bit32u width; Bit32u height; - GFX_MODES gfx_mode; + Bitu bpp; double scalex,scaley; - struct { - GFX_ResetCallBack reset; - GFX_RenderCallBack render; - } cb; + GFX_ResetCallBack reset; } draw; bool wait_on_error; struct { @@ -91,19 +119,28 @@ struct SDL_Block { bool fullscreen; bool doublebuf; SCREEN_TYPES type; + SCREEN_TYPES want_type; + double hwscale; } desktop; +#if C_OPENGL + struct { + Bitu pitch; + void * framebuf; + GLuint texture; + GLuint displaylist; + GLint max_texsize; + bool packed_pixel; + bool paletted_texture; +#ifdef GL_NV_pixel_data_range + bool pixel_data_range; +#endif + } opengl; +#endif SDL_Rect clip; SDL_Surface * surface; SDL_Overlay * overlay; SDL_Joystick * joy; SDL_cond *cond; -#if C_GFXTHREADED - SDL_mutex *mutex; - SDL_Thread *thread; - SDL_sem *sem; - volatile bool kill_thread; -#endif - struct { bool autolock; bool autoenable; @@ -127,62 +164,59 @@ void GFX_SetTitle(Bits cycles,Bits frameskip){ } /* Reset the screen with current values in the sdl structure */ -GFX_MODES GFX_GetBestMode(Bitu bpp,Bitu & gfx_flags) { - GFX_MODES gfx_mode;gfx_flags=0; - switch (sdl.desktop.type) { +Bitu GFX_GetBestMode(Bitu bpp,Bitu & gfx_flags) { + gfx_flags=0; + switch (sdl.desktop.want_type) { case SCREEN_SURFACE: - Bitu what_bpp; if (sdl.desktop.fullscreen) { - what_bpp=SDL_VideoModeOK(640,480,bpp,SDL_FULLSCREEN|SDL_HWSURFACE | + bpp=SDL_VideoModeOK(640,480,bpp,SDL_FULLSCREEN|SDL_HWSURFACE | (sdl.desktop.doublebuf ? SDL_DOUBLEBUF : 0) | ((bpp==8) ? SDL_HWPALETTE : 0) ); } else { - what_bpp=sdl.desktop.bpp; + bpp=sdl.desktop.bpp; } gfx_flags|=GFX_HASCONVERT; - switch (what_bpp) { - case 8: gfx_mode=GFX_8BPP;break; - case 15: gfx_mode=GFX_15BPP;break; - case 16: gfx_mode=GFX_16BPP;break; - case 24: gfx_mode=GFX_24BPP;break; - case 32: gfx_mode=GFX_32BPP;break; - } break; case SCREEN_OVERLAY: - gfx_mode=GFX_YUV; + bpp=32; gfx_flags|=GFX_HASSCALING; + break; +#if C_OPENGL + case SCREEN_OPENGL: + bpp=32; + gfx_flags|=GFX_HASSCALING; + break; +#endif } - return gfx_mode; + return bpp; } static void ResetScreen(void) { GFX_Stop(); - if (sdl.draw.cb.reset) (sdl.draw.cb.reset)(); + if (sdl.draw.reset) (sdl.draw.reset)(); GFX_Start(); } -void GFX_SetSize(Bitu width,Bitu height,GFX_MODES gfx_mode,double scalex,double scaley,GFX_ResetCallBack cb_reset, GFX_RenderCallBack cb_render) { - GFX_Stop(); +static int int_log2 (int val) { + int log = 0; + while ((val >>= 1) != 0) + log++; + return log; +} + +void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,double scalex,double scaley,GFX_ResetCallBack reset) { + if (sdl.updating) GFX_EndUpdate(); sdl.draw.width=width; sdl.draw.height=height; - sdl.draw.gfx_mode=gfx_mode; - sdl.draw.cb.render=cb_render; - sdl.draw.cb.reset=cb_reset; + sdl.draw.bpp=bpp; + sdl.draw.reset=reset; sdl.draw.scalex=scalex; sdl.draw.scaley=scaley; - Bitu bpp; - switch (gfx_mode) { - case GFX_8BPP:bpp=8;break; - case GFX_15BPP:bpp=15;break; - case GFX_16BPP:bpp=16;break; - case GFX_24BPP:bpp=24;break; - case GFX_32BPP:bpp=32;break; - case GFX_YUV:bpp=0;break; - } - switch (sdl.desktop.type) { + switch (sdl.desktop.want_type) { case SCREEN_SURFACE: dosurface: + sdl.desktop.type=SCREEN_SURFACE; sdl.clip.w=width; sdl.clip.h=height; if (sdl.desktop.fullscreen) { @@ -204,7 +238,7 @@ dosurface: case SCREEN_OVERLAY: if (sdl.overlay) SDL_FreeYUVOverlay(sdl.overlay); sdl.overlay=0; - if (gfx_mode!=GFX_YUV) goto dosurface; + if (bpp!=32) goto dosurface; if (sdl.desktop.fullscreen) { if (sdl.desktop.fixed) { double ratio_w=(double)sdl.desktop.width/(width*scalex); @@ -218,22 +252,132 @@ dosurface: } sdl.clip.x=(Sint16)((sdl.desktop.width-sdl.clip.w)/2); sdl.clip.y=(Sint16)((sdl.desktop.height-sdl.clip.h)/2); - sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,bpp,SDL_FULLSCREEN|SDL_HWSURFACE); + sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,0, + SDL_FULLSCREEN|SDL_HWSURFACE); } else { sdl.clip.x=0;sdl.clip.y=0; sdl.clip.w=(Bit16u)(width*scalex); sdl.clip.h=(Bit16u)(height*scaley); - sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,SDL_FULLSCREEN|SDL_HWSURFACE); + sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,0, + SDL_FULLSCREEN|SDL_HWSURFACE); } } else { sdl.clip.x=0;sdl.clip.y=0; - sdl.clip.w=(Bit16u)(width*scalex); - sdl.clip.h=(Bit16u)(height*scaley); - sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,SDL_HWSURFACE); + sdl.clip.w=(Bit16u)(width*scalex*sdl.desktop.hwscale); + sdl.clip.h=(Bit16u)(height*scaley*sdl.desktop.hwscale); + sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,0,SDL_HWSURFACE); } sdl.overlay=SDL_CreateYUVOverlay(width*2,height,SDL_UYVY_OVERLAY,sdl.surface); + if (!sdl.overlay) { + LOG_MSG("SDL:Failed to create overlay, switching back to surface"); + goto dosurface; + } + sdl.desktop.type=SCREEN_OVERLAY; break; - } +#if C_OPENGL + case SCREEN_OPENGL: + { + if (sdl.opengl.framebuf) db_glFreeMemoryNV(sdl.opengl.framebuf); + sdl.opengl.framebuf=0; + if (bpp!=32) goto dosurface; + int texsize=2 << int_log2(width > height ? width : height); + if (texsize>sdl.opengl.max_texsize) { + LOG_MSG("SDL:OPENGL:No support for texturesize of %d, falling back to surface",texsize); + goto dosurface; + } + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + if (sdl.desktop.fullscreen) { + if (sdl.desktop.fixed) { + double ratio_w=(double)sdl.desktop.width/(width*scalex); + double ratio_h=(double)sdl.desktop.height/(height*scaley); + if ( ratio_w < ratio_h) { + sdl.clip.w=(Bit16u)sdl.desktop.width; + sdl.clip.h=(Bit16u)(height*scaley*ratio_w); + } else { + sdl.clip.w=(Bit16u)(width*scalex*ratio_h); + sdl.clip.h=(Bit16u)sdl.desktop.height; + } + sdl.clip.x=(Sint16)((sdl.desktop.width-sdl.clip.w)/2); + sdl.clip.y=(Sint16)((sdl.desktop.height-sdl.clip.h)/2); + sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,0, + SDL_OPENGL|SDL_FULLSCREEN|SDL_HWSURFACE); + } else { + sdl.clip.x=0;sdl.clip.y=0; + sdl.clip.w=(Bit16u)(width*scalex); + sdl.clip.h=(Bit16u)(height*scaley); + sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,0, + SDL_OPENGL|SDL_FULLSCREEN|SDL_HWSURFACE); + } + } else { + sdl.clip.x=0;sdl.clip.y=0; + sdl.clip.w=(Bit16u)(width*scalex*sdl.desktop.hwscale); + sdl.clip.h=(Bit16u)(height*scaley*sdl.desktop.hwscale); + sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,0, + SDL_OPENGL|SDL_HWSURFACE); + } + if (!sdl.surface || sdl.surface->format->BitsPerPixel<15) { + LOG_MSG("SDL:OPENGL:Can't open drawing surface, are you running in 16bpp(or higher) mode?"); + goto dosurface; + } + /* Create the texture and display list */ +#ifdef GL_NV_pixel_data_range + if (sdl.opengl.pixel_data_range) { + sdl.opengl.framebuf=db_glAllocateMemoryNV(width*height*4,0.0,1.0,1.0); + glPixelDataRangeNV(GL_WRITE_PIXEL_DATA_RANGE_NV,width*height*4,sdl.opengl.framebuf); + glEnableClientState(GL_WRITE_PIXEL_DATA_RANGE_NV); + } else { +#else + { +#endif + sdl.opengl.framebuf=malloc(width*height*4); //32 bit color + } + sdl.opengl.pitch=width*4; + glMatrixMode (GL_PROJECTION); + glDeleteTextures(1,&sdl.opengl.texture); + glGenTextures(1,&sdl.opengl.texture); + glBindTexture(GL_TEXTURE_2D,sdl.opengl.texture); + // No borders + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + // Bilinear filtering + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texsize, texsize, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, 0); + + glClearColor (1.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + glShadeModel (GL_FLAT); + glDisable (GL_DEPTH_TEST); + glDisable (GL_LIGHTING); + glDisable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); + + GLfloat tex_width=((GLfloat)(width)/(GLfloat)texsize); + GLfloat tex_height=((GLfloat)(height)/(GLfloat)texsize); + + if (glIsList(sdl.opengl.displaylist)) glDeleteLists(sdl.opengl.displaylist, 1); + sdl.opengl.displaylist = glGenLists(1); + glNewList(sdl.opengl.displaylist, GL_COMPILE); + glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture); + glBegin(GL_QUADS); + // lower left + glTexCoord2f(0,tex_height); glVertex2f(-1.0f,-1.0f); + // lower right + glTexCoord2f(tex_width,tex_height); glVertex2f(1.0f, -1.0f); + // upper right + glTexCoord2f(tex_width,0); glVertex2f(1.0f, 1.0f); + // upper left + glTexCoord2f(0,0); glVertex2f(-1.0f, 1.0f); + glEnd(); + glEndList(); + sdl.desktop.type=SCREEN_OPENGL; + break; + }//OPENGL +#endif //C_OPENGL + }//CASE GFX_Start(); } @@ -252,7 +396,6 @@ static void CaptureMouse(void) { static void SwitchFullScreen(void) { sdl.desktop.fullscreen=!sdl.desktop.fullscreen; if (sdl.desktop.fullscreen) { -//TODO Give an resize event if (!sdl.mouse.locked) CaptureMouse(); } else { if (sdl.mouse.locked) CaptureMouse(); @@ -264,73 +407,68 @@ void GFX_SwitchFullScreen(void) { SwitchFullScreen(); } - -static void SDL_DrawScreen(void) { - Bit8u * pixels;Bitu pitch; - sdl.drawing=true; +bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) { + if (!sdl.active || sdl.updating) return false; + sdl.updating=true; switch (sdl.desktop.type) { case SCREEN_SURFACE: if (SDL_MUSTLOCK(sdl.surface)) { if (SDL_LockSurface(sdl.surface)) { LOG_MSG("SDL Lock failed"); - sdl.drawing=false; - return; + sdl.updating=false; + return false; } } pixels=(Bit8u *)sdl.surface->pixels; pixels+=sdl.clip.y*sdl.surface->pitch; pixels+=sdl.clip.x*sdl.surface->format->BytesPerPixel; - sdl.draw.cb.render(pixels,sdl.surface->pitch); + pitch=sdl.surface->pitch; + return true; + case SCREEN_OVERLAY: + SDL_LockYUVOverlay(sdl.overlay); + pixels=(Bit8u *)*(sdl.overlay->pixels); + pitch=*(sdl.overlay->pitches); + return true; +#if C_OPENGL + case SCREEN_OPENGL: + pixels=(Bit8u *)sdl.opengl.framebuf; + pitch=sdl.opengl.pitch; + return true; +#endif + } + return false; +} + +void GFX_EndUpdate(void) { + if (!sdl.updating) return; + sdl.updating=false; + switch (sdl.desktop.type) { + case SCREEN_SURFACE: if (SDL_MUSTLOCK(sdl.surface)) { SDL_UnlockSurface(sdl.surface); } SDL_Flip(sdl.surface); break; case SCREEN_OVERLAY: - SDL_LockYUVOverlay(sdl.overlay); - pixels=(Bit8u *)*(sdl.overlay->pixels); - pitch=*(sdl.overlay->pitches); - sdl.draw.cb.render(pixels,pitch); SDL_UnlockYUVOverlay(sdl.overlay); SDL_DisplayYUVOverlay(sdl.overlay,&sdl.clip); - - } - sdl.drawing=false; -} - -#if C_GFXTHREADED -int SDL_DisplayThread(void * data) { - while (!SDL_SemWait(sdl.sem)) { - if (sdl.kill_thread) return 0; - if (!sdl.active) continue; - if (sdl.drawing) continue; - SDL_mutexP(sdl.mutex); - SDL_DrawScreen(); - SDL_mutexV(sdl.mutex); - } - return 0; -} -#endif - -void GFX_DoUpdate(void) { - if (!sdl.active) - return; - if (sdl.drawing)return; -#if C_GFXTHREADED - SDL_SemPost(sdl.sem); -#else - SDL_DrawScreen(); + break; +#if C_OPENGL + case SCREEN_OPENGL: + glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, + sdl.draw.width, sdl.draw.height, GL_BGRA_EXT, + GL_UNSIGNED_INT_8_8_8_8_REV, sdl.opengl.framebuf); + glCallList(sdl.opengl.displaylist); + SDL_GL_SwapBuffers(); + break; #endif + } } void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries) { -#if C_GFXTHREADED - if (SDL_mutexP(sdl.mutex)) { - E_Exit("SDL:Can't lock Mutex"); - }; -#endif /* I should probably not change the GFX_PalEntry :) */ if (sdl.surface->flags & SDL_HWPALETTE) { if (!SDL_SetPalette(sdl.surface,SDL_PHYSPAL,(SDL_Color *)entries,start,count)) { @@ -341,26 +479,29 @@ void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries) { E_Exit("SDL:Can't set palette"); } } -#if C_GFXTHREADED - if (SDL_mutexV(sdl.mutex)) { - E_Exit("SDL:Can't release Mutex"); - }; -#endif } Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue) { - return SDL_MapRGB(sdl.surface->format,red,green,blue); + switch (sdl.desktop.type) { + case SCREEN_SURFACE: + return SDL_MapRGB(sdl.surface->format,red,green,blue); + case SCREEN_OVERLAY: + { + Bit8u y = ( 9797*(red) + 19237*(green) + 3734*(blue) ) >> 15; + Bit8u u = (18492*((blue)-(y)) >> 15) + 128; + Bit8u v = (23372*((red)-(y)) >> 15) + 128; + return (u << 0) | (y << 8) | (v << 16) | (y << 24); + } + case SCREEN_OPENGL: +// return ((red << 0) | (green << 8) | (blue << 16)) | (255 << 24); + //USE BGRA + return ((blue << 0) | (green << 8) | (red << 16)) | (255 << 24); + } + return 0; } void GFX_Stop() { -#if C_GFXTHREADED - SDL_mutexP(sdl.mutex); -#endif sdl.active=false; -#if C_GFXTHREADED - SDL_mutexV(sdl.mutex); -#endif - } void GFX_Start() { @@ -371,14 +512,6 @@ static void GUI_ShutDown(Section * sec) { GFX_Stop(); if (sdl.mouse.locked) CaptureMouse(); if (sdl.desktop.fullscreen) SwitchFullScreen(); -#if C_GFXTHREADED - sdl.kill_thread=true; - SDL_SemPost(sdl.sem); - SDL_WaitThread(sdl.thread,0); - SDL_DestroyMutex(sdl.mutex); - SDL_DestroySemaphore(sdl.sem); -#endif - } static void KillSwitch(void){ @@ -389,6 +522,7 @@ static void GUI_StartUp(Section * sec) { sec->AddDestroyFunction(&GUI_ShutDown); Section_prop * section=static_cast(sec); sdl.active=false; + sdl.updating=false; sdl.desktop.fullscreen=section->Get_bool("fullscreen"); sdl.wait_on_error=section->Get_bool("waitonerror"); sdl.mouse.locked=false; @@ -397,6 +531,7 @@ static void GUI_StartUp(Section * sec) { sdl.desktop.width=section->Get_int("fullwidth"); sdl.desktop.height=section->Get_int("fullheight"); sdl.desktop.doublebuf=section->Get_bool("fulldouble"); + sdl.desktop.hwscale=1.2; if (!sdl.desktop.width) { #ifdef WIN32 sdl.desktop.width=GetSystemMetrics(SM_CXSCREEN); @@ -414,17 +549,39 @@ static void GUI_StartUp(Section * sec) { sdl.mouse.autoenable=section->Get_bool("autolock"); sdl.mouse.autolock=false; sdl.mouse.sensitivity=section->Get_int("sensitivity"); - if (section->Get_bool("overlay")) { - sdl.desktop.type=SCREEN_OVERLAY; + const char * output=section->Get_string("output"); + if (!strcasecmp(output,"surface")) { + sdl.desktop.want_type=SCREEN_SURFACE; + } else if (!strcasecmp(output,"overlay")) { + sdl.desktop.want_type=SCREEN_OVERLAY; +#if C_OPENGL + } else if (!strcasecmp(output,"opengl")) { + sdl.desktop.want_type=SCREEN_OPENGL; +#endif } else { - sdl.desktop.type=SCREEN_SURFACE; + LOG_MSG("SDL:Unsupported output device %s, switching back to surface",output); + sdl.desktop.want_type=SCREEN_SURFACE; } + sdl.overlay=0; -#if C_GFXTHREADED - sdl.kill_thread=false; - sdl.mutex=SDL_CreateMutex(); - sdl.sem=SDL_CreateSemaphore(0); - sdl.thread=SDL_CreateThread(&SDL_DisplayThread,0); +#if C_OPENGL + sdl.surface=SDL_SetVideoMode(640,400,0,SDL_OPENGL); + sdl.opengl.framebuf=0; + sdl.opengl.texture=0; + sdl.opengl.displaylist=0; + glGetIntegerv (GL_MAX_TEXTURE_SIZE, &sdl.opengl.max_texsize); +#if defined(__WIN32__) + glPixelDataRangeNV = (PFNGLPIXELDATARANGENVPROC) wglGetProcAddress("glPixelDataRangeNV"); + db_glAllocateMemoryNV = (PFNWGLALLOCATEMEMORYNVPROC) wglGetProcAddress("wglAllocateMemoryNV"); + db_glFreeMemoryNV = (PFNWGLFREEMEMORYNVPROC) wglGetProcAddress("wglFreeMemoryNV"); +#endif + const char * gl_ext = (const char *)glGetString (GL_EXTENSIONS); + sdl.opengl.packed_pixel=strstr(gl_ext,"EXT_packed_pixels") > 0; + sdl.opengl.paletted_texture=strstr(gl_ext,"EXT_paletted_texture") > 0; +#ifdef GL_NV_pixel_data_range + sdl.opengl.pixel_data_range=strstr(gl_ext,"GL_NV_pixel_data_range") >0 && + glPixelDataRangeNV; +#endif #endif /* Initialize screen for first time */ sdl.surface=SDL_SetVideoMode(640,400,0,0); @@ -432,7 +589,7 @@ static void GUI_StartUp(Section * sec) { if (sdl.desktop.bpp==24) { LOG_MSG("SDL:You are running in 24 bpp mode, this will slow down things!"); } - GFX_SetSize(640,400,GFX_8BPP,1.0,1.0,0,0); + GFX_SetSize(640,400,8,1.0,1.0,0); SDL_EnableKeyRepeat(250,30); SDL_EnableUNICODE(1); /* Get some Keybinds */ @@ -744,20 +901,28 @@ int main(int argc, char* argv[]) { sdl_sec->Add_bool("fullfixed",false); sdl_sec->Add_int("fullwidth",0); sdl_sec->Add_int("fullheight",0); - sdl_sec->Add_bool("overlay",false); + sdl_sec->Add_string("output","surface"); + sdl_sec->Add_string("hwscale","1.0"); sdl_sec->Add_bool("autolock",true); sdl_sec->Add_int("sensitivity",100); sdl_sec->Add_bool("waitonerror",true); - /* Init all the dosbox subsystems */ MSG_Add("SDL_CONFIGFILE_HELP", "fullscreen -- Start dosbox directly in fullscreen.\n" + "fulldouble -- Use double buffering in fullscreen.\n" + "fullfixed -- Don't resize the screen when in fullscreen.\n" + "fullwidth/height -- What resolution to use for fullscreen, use together with fullfixed.\n" + "output -- What to use for output: surface,overlay" +#if C_OPENGL + ",opengl" +#endif + ".\n" + "hwscale -- Extra scaling of window if the output devive supports hardware scaling.\n" "autolock -- Mouse will automatically lock, if you click on the screen.\n" "sensitiviy -- Mouse sensitivity.\n" "waitonerror -- Wait before closing the console if dosbox has an error.\n" ); - - + /* Init all the dosbox subsystems */ DOSBOX_Init(); std::string config_file; if (control->cmdline->FindString("-conf",config_file,true)) { diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 78631c6a..3b9c3255 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -31,10 +31,14 @@ VGA_Type vga; Bit32u CGA_2_Table[16]; Bit32u CGA_4_Table[256]; Bit32u CGA_16_Table[256]; +Bit32u TXT_Font_Table[16]; +Bit32u TXT_FG_Table[16]; +Bit32u TXT_BG_Table[16]; Bit32u ExpandTable[256]; Bit32u Expand16Table[4][16]; -Bit32u Expand16BigTable[0x10000]; Bit32u FillTable[16]; +Bit32u ColorTable[16]; + void VGA_SetMode(VGAModes mode) { @@ -107,18 +111,34 @@ void VGA_Init(Section* sec) { #endif } for (i=0;i<16;i++) { + TXT_FG_Table[i]=i | (i << 8)| (i <<16) | (i << 24); + TXT_BG_Table[i]=i | (i << 8)| (i <<16) | (i << 24); + #ifdef WORDS_BIGENDIAN CGA_2_Table[i]=((i>>0)&1) | (((i>>1)&1) << 8)| (((i>>1)&1) <<16) | (((i>>3)&1) << 24); - FillTable[i]= ((i & 1) ? 0xff000000 : 0) | + FillTable[i]= + ((i & 1) ? 0xff000000 : 0) | ((i & 2) ? 0x00ff0000 : 0) | - ((i & 4) ? 0x0000ff00 : 0) | - ((i & 8) ? 0x000000ff : 0) ; + ((i & 4) ? 0x0000ff00 : 0) | + ((i & 8) ? 0x000000ff : 0) ; + TXT_Font_Table[i]= + ((i & 1) ? 0x000000ff : 0) | + ((i & 2) ? 0x0000ff00 : 0) | + ((i & 4) ? 0x00ff0000 : 0) | + ((i & 8) ? 0xff000000 : 0) ; #else CGA_2_Table[i]=((i>>3)&1) | (((i>>2)&1) << 8)| (((i>>1)&1) <<16) | (((i>>0)&1) << 24); - FillTable[i]= ((i & 1) ? 0x000000ff : 0) | - ((i & 2) ? 0x0000ff00 : 0) | - ((i & 4) ? 0x00ff0000 : 0) | - ((i & 8) ? 0xff000000 : 0) ; + FillTable[i]= + ((i & 1) ? 0x000000ff : 0) | + ((i & 2) ? 0x0000ff00 : 0) | + ((i & 4) ? 0x00ff0000 : 0) | + ((i & 8) ? 0xff000000 : 0) ; + TXT_Font_Table[i]= + ((i & 1) ? 0xff000000 : 0) | + ((i & 2) ? 0x00ff0000 : 0) | + ((i & 4) ? 0x0000ff00 : 0) | + ((i & 8) ? 0x000000ff : 0) ; + #endif } for (j=0;j<4;j++) { @@ -138,28 +158,5 @@ void VGA_Init(Section* sec) { #endif } } - for (i=0;i<0x10000;i++) { - Bit32u val=0; - if (i & 0x1) val|=0x1 << 24; - if (i & 0x2) val|=0x1 << 16; - if (i & 0x4) val|=0x1 << 8; - if (i & 0x8) val|=0x1 << 0; - - if (i & 0x10) val|=0x4 << 24; - if (i & 0x20) val|=0x4 << 16; - if (i & 0x40) val|=0x4 << 8; - if (i & 0x80) val|=0x4 << 0; - - if (i & 0x100) val|=0x2 << 24; - if (i & 0x200) val|=0x2 << 16; - if (i & 0x400) val|=0x2 << 8; - if (i & 0x800) val|=0x2 << 0; - - if (i & 0x1000) val|=0x8 << 24; - if (i & 0x2000) val|=0x8 << 16; - if (i & 0x4000) val|=0x8 << 8; - if (i & 0x8000) val|=0x8 << 0; - Expand16BigTable[i]=val; - } } diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 8152fe31..e957f8ec 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -127,8 +127,6 @@ void write_p3d5(Bit32u port,Bit8u val) { */ break; case 0x09: /* Maximum Scan Line Register */ - vga.config.vline_double=(val & 128)>1; - vga.config.vline_height=(val & 0xf); vga.config.line_compare=(vga.config.line_compare & 0x5ff)|(val&0x40)<<3; if ((vga.crtc.maximum_scan_line ^ val) & 0xbf) { crtc(maximum_scan_line)=val; diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 0843f384..75731ad2 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -17,73 +17,50 @@ */ #include +#include #include "dosbox.h" #include "video.h" #include "render.h" #include "vga.h" #include "pic.h" -//TODO Make the full draw like the vga really does from video memory. +#define VGA_PARTS 4 -#define FIXED_CGA_SIZED 1 +static Bit8u VGA_DrawBuffer[2048]; -static void VGA_HERC_Draw(Bit8u * bitdata,Bitu pitch) { - Bit8u * reader=&vga.mem.linear[0]; - for (Bitu y=0;y>3;x>0;x--) { - Bit8u val=*(tempread++); - *(Bit32u *)(draw+0)=CGA_2_Table[val >> 4]; - *(Bit32u *)(draw+4)=CGA_2_Table[val & 0xf]; - draw+=8; - } - if ((y & 3)==3) reader+=90; - bitdata+=pitch; +typedef Bit8u * (* VGA_Line_Handler)(Bitu vidstart,Bitu panning,Bitu line); + +static VGA_Line_Handler VGA_DrawLine; + +static Bit8u * VGA_HERC_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { + Bit8u * reader=&vga.mem.linear[vidstart+(line * 8 * 1024)]; + Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0]; + for (Bitu x=vga.draw.blocks;x>0;x--) { + Bitu val=*reader++; + *draw++=CGA_2_Table[val >> 4]; + *draw++=CGA_2_Table[val & 0xf]; } + return VGA_DrawBuffer; } -static void VGA_CGA2_Draw(Bit8u * bitdata,Bitu pitch) { - Bit8u * reader=&vga.mem.linear[0]; - Bit8u * flip=&vga.mem.linear[8*1024]; - Bit8u * draw; - for (Bitu y=0;y>3;x>0;x--) { - Bit8u val=*(tempread++); - *(Bit32u *)(draw+0)=CGA_2_Table[val >> 4]; - *(Bit32u *)(draw+4)=CGA_2_Table[val & 0xf]; - draw+=8; - } - bitdata+=pitch; +static Bit8u * VGA_CGA2_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { + Bit8u * reader=&vga.mem.linear[vidstart+(line * 8 * 1024)]; + Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0]; + for (Bitu x=vga.draw.blocks;x>0;x--) { + Bitu val=*reader++; + *draw++=CGA_2_Table[val >> 4]; + *draw++=CGA_2_Table[val & 0xf]; } + return VGA_DrawBuffer; } -static void VGA_CGA4_Draw(Bit8u * bitdata,Bitu pitch) { - Bit8u * reader=&vga.mem.linear[0]; - Bit8u * flip=&vga.mem.linear[8*1024]; - Bit8u * draw; - for (Bitu y=0;y=flip) reader-=8*1024; - } - draw=bitdata; - for (Bitu x=0;x>2;x++) { - Bit8u val=*(tempread++); - *(Bit32u *)draw=CGA_4_Table[val]; - draw+=4; - } - bitdata+=pitch; +static Bit8u * VGA_CGA4_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { + Bit8u * reader=&vga.mem.linear[vidstart+(line * 8 * 1024)]; + Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0]; + for (Bitu x=0;x=flip) reader-=8*1024; - } - draw=bitdata; - for (Bitu x=0;x<80;x++) { - Bit8u val=*(tempread++); - - Bit32u full=convert16[(val & 0xf0) >> 4] | convert16[val & 0xf] << 16; - full|=full<<8; - *(Bit32u *)draw=full; - draw+=4; - } - bitdata+=pitch; +static Bit8u * VGA_CGA16_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { + Bit8u * reader=&vga.mem.linear[vidstart+(line * 8 * 1024)]; + Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0]; + for (Bitu x=0;x> 4] | convert16[val & 0xf] << 16; + *draw++=full|=full<<8; } + return VGA_DrawBuffer; } -static void VGA_TANDY16_Draw(Bit8u * bitdata,Bitu pitch) { - Bit8u * reader=&vga.mem.linear[(vga.tandy.disp_bank << 14) + vga.config.display_start*2]; - - for (Bitu y=0;y>2;x++) { - Bit8u val1=*(tempread++); - Bit8u val2=*(tempread++); - Bit32u full=(val1 & 0x0f) << 8 | - (val1 & 0xf0) >> 4 | - (val2 & 0x0f) << 24 | - (val2 & 0xf0) << 12; - *(Bit32u *)draw=full; - draw+=4; - } - bitdata+=pitch; - if ((y & 3)==3)reader+=160; +static Bit8u * VGA_TANDY16_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { + Bit8u * reader=&vga.mem.linear[(vga.tandy.disp_bank << 14) + vidstart + (line * 8 * 1024)]; + Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0]; + for (Bitu x=0;x> 4 | + (val2 & 0x0f) << 24 | + (val2 & 0xf0) << 12; } + return VGA_DrawBuffer; } +static Bit8u * VGA_EGA_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { + return &vga.mem.linear[512*1024+vidstart*8+panning]; +} +static Bit8u * VGA_VGA_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { + return &vga.mem.linear[vidstart*4+panning/2]; +} -void VGA_TEXT_Draw(Bit8u * bitdata,Bitu start,Bitu panning,Bitu rows) { - Bit8u * reader=&vga.mem.linear[start*2]; - Bit8u * draw_start=bitdata; -/* Todo Blinking and high intensity colors */ - Bitu next_charline=vga.draw.font_height*vga.draw.width; - Bitu next_line=vga.draw.width; - Bitu next_start=(vga.config.scan_len*2)-vga.draw.cols; +static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { + Bit8u * draw=VGA_DrawBuffer; + Bit8u * vidmem=&vga.mem.linear[vidstart]; + for (Bitu cx=0;cx>4]; + Bit32u mask2=TXT_Font_Table[font&0xf]; + Bitu col=vidmem[cx*2+1]; + Bit32u fg=TXT_FG_Table[col&0xf]; + Bit32u bg=TXT_BG_Table[col>>4]; + *(Bit32u*)draw=fg&mask1 | bg&~mask1; + draw+=4; + *(Bit32u*)draw=fg&mask2 | bg&~mask2; + draw+=4; + } + return VGA_DrawBuffer; +} + +void VGA_TEXT_Draw(Bit8u * bitdata,Bitu start,Bitu panning,Bitu lines) { +#if 0 + Bit8u * reader=&vga.mem.linear[start*2];Bitu rows=lines/vga.draw.font_height; for (Bitu cy=rows;cy>0;cy--) { - Bit8u * draw_char=draw_start; - /* Do first character keeping track of panning */ - { - Bit8u c=*(reader++); - Bit8u * findex=&vga.draw.font[c*32]; - Bit8u col=*(reader++); - Bit8u fg=col & 0xF; - Bit8u bg=(col>> 4); - Bit8u * draw_line=draw_char; - Bit8u bit_index=1 << (7-panning); - for (Bitu y=vga.draw.font_height;y>0;y--) { - Bit8u * draw=draw_line; - draw_line+=next_line; - Bit8u bit=bit_index; - Bit8u bit_mask=*findex++; - while (bit) { - if (bit_mask & bit) *draw=fg; - else *draw=bg; - draw++;bit>>=1; - } - } - draw_char+=8-panning; - } - for (Bitu cx=vga.draw.cols-1;cx>0;cx--) { - Bit8u c=*(reader++); - Bit8u * findex=&vga.draw.font[c*32]; - Bit8u col=*(reader++); - Bit8u fg=col & 0xF; - Bit8u bg=(col>> 4); - Bit8u * draw=draw_char; - for (Bitu y=vga.draw.font_height;y>0;y--) { - Bit8u bit_mask=*findex++; - #include "font-switch.h" - draw+=next_line; - } - draw_char+=8; - } - /* Do last character if needed */ - if (panning) { - Bit8u c=*(reader); - Bit8u * findex=&vga.draw.font[c*32]; - Bit8u col=*(reader+1); - Bit8u fg=col & 0xF; - Bit8u bg=(col>> 4); - Bit8u * draw_line=draw_char; - Bit8u bit_index=1 << panning; - for (Bitu y=vga.draw.font_height;y>0;y--) { - Bit8u * draw=draw_line; - draw_line+=next_line; - Bit8u bit=bit_index; - Bit8u bit_mask=*findex++; - while (bit) { - if (bit_mask & bit) *draw=fg; - else *draw=bg; - draw++;bit>>=1; - } + for (Bitu y=0;y>4]; + Bit32u mask2=TXT_Font_Table[font&0xf]; + Bit8u col=reader[cx*2+1]; + Bit32u fg=TXT_FG_Table[col&0xf]; + Bit32u bg=TXT_BG_Table[col>>4]; + *(Bit32u*)draw=fg&mask1 | bg&~mask1; + draw+=4; + *(Bit32u*)draw=fg&mask2 | bg&~mask2; + draw+=4; } } - draw_start+=next_charline; - reader+=next_start; + reader+=(vga.config.scan_len*4); } /* Cursor handling */ - vga.draw.cursor.count++; - if (vga.draw.cursor.count>16) vga.draw.cursor.count=0; - if(vga.draw.cursor.enabled && (vga.draw.cursor.count>8)) { /* Draw a cursor if enabled */ Bits cur_start=vga.config.cursor_start-start; if (cur_start<0) return; @@ -219,8 +150,7 @@ void VGA_TEXT_Draw(Bit8u * bitdata,Bitu start,Bitu panning,Bitu rows) { Bitu row=cur_start / (vga.config.scan_len*2); Bitu col=cur_start % (vga.config.scan_len*2); Bit32u att=vga.mem.linear[vga.config.cursor_start*2+1]&0xf; - att=(att << 8) | att; - att=(att << 16) | att; + att=TXT_BG_Table[att]; if ((col*8)>=vga.draw.width) return; if ((row*vga.draw.font_height)>=vga.draw.height) return; @@ -234,118 +164,60 @@ void VGA_TEXT_Draw(Bit8u * bitdata,Bitu start,Bitu panning,Bitu rows) { cursor_draw+=vga.draw.width; } } +#endif } -static void EndRetrace(void) { - /* start the actual display update now */ - RENDER_DoUpdate(); - vga.config.retrace=false; -} - -static void VGA_BlankTimer() { - PIC_AddEvent(VGA_BlankTimer,vga.draw.blank); - PIC_AddEvent(EndRetrace,667); - /* Setup a timer to destroy the vertical retrace bit in a few microseconds */ - vga.config.real_start=vga.config.display_start; +static void VGA_VerticalDisplayEnd(void) { vga.config.retrace=true; + vga.config.real_start=vga.config.display_start; } -void VGA_DrawHandler(RENDER_Part_Handler part_handler) { - Bit8u * buf,* bufsplit; - /* Draw the current frame */ - if (!vga.draw.resizing) { - if (vga.config.line_compare=vga.draw.height){ - LOG(LOG_VGAGFX,LOG_NORMAL)("Split at %d",stop); - goto drawnormal; - } - switch (vga.mode) { - case M_EGA16: - buf=&vga.mem.linear[512*1024+vga.config.real_start*8+vga.config.pel_panning]; - bufsplit=&vga.mem.linear[512*1024]; - break; - case M_VGA: - case M_LIN8: - buf=&vga.mem.linear[vga.config.real_start*4+vga.config.pel_panning]; - bufsplit=vga.mem.linear; - break; - case M_TEXT2: - case M_TEXT16: - { - Bitu first_rows=stop/vga.draw.font_height; - if (vga.config.hlines_skip) first_rows++; - if (stop%vga.draw.font_height) first_rows++; - Bitu next_rows=(vga.draw.height-stop)/vga.draw.font_height; - if ((vga.draw.height-stop)%vga.draw.font_height) next_rows++; - VGA_TEXT_Draw(&vga.mem.linear[512*1024],vga.config.real_start,vga.config.pel_panning,first_rows); - VGA_TEXT_Draw(&vga.mem.linear[1024*1024],0,0,next_rows); - buf=&vga.mem.linear[512*1024+vga.config.hlines_skip*vga.draw.width]; - bufsplit=&vga.mem.linear[1024*1024]; - } - break; - default: - LOG(LOG_VGAGFX,LOG_NORMAL)("VGA:Unhandled split screen mode %d",vga.mode); - goto norender; - } - if (stop) part_handler(buf,0,0,vga.draw.width,stop); - if (vga.draw.height-stop) part_handler(bufsplit,0,stop,vga.draw.width,vga.draw.height-stop); - } else { -drawnormal: - switch (vga.mode) { - case M_HERC: - VGA_HERC_Draw(&vga.mem.linear[512*1024],vga.draw.width); - buf=&vga.mem.linear[512*1024]; - break; - case M_CGA2: - VGA_CGA2_Draw(&vga.mem.linear[512*1024],vga.draw.width); - buf=&vga.mem.linear[512*1024]; - break; - case M_CGA4: - VGA_CGA4_Draw(&vga.mem.linear[512*1024],vga.draw.width); - buf=&vga.mem.linear[512*1024]; - break; - case M_CGA16: - VGA_CGA16_Draw(&vga.mem.linear[512*1024],vga.draw.width); - buf=&vga.mem.linear[512*1024]; - break; - case M_TANDY16: - VGA_TANDY16_Draw(&vga.mem.linear[512*1024],vga.draw.width); - buf=&vga.mem.linear[512*1024]; - break; - case M_EGA16: - buf=&vga.mem.linear[512*1024+vga.config.real_start*8+vga.config.pel_panning]; - break; - case M_VGA: - case M_LIN8: - buf=&vga.mem.linear[vga.config.real_start*4+vga.config.pel_panning]; - break; - case M_TEXT2: - case M_TEXT16: - { - Bitu rows=vga.draw.rows; - if (vga.config.hlines_skip) rows++; - VGA_TEXT_Draw(&vga.mem.linear[512*1024],vga.config.real_start,vga.config.pel_panning,rows); - buf=&vga.mem.linear[512*1024+vga.config.hlines_skip*vga.draw.width]; - } - break; - default: - return; - } - part_handler(buf,0,0,vga.draw.width,vga.draw.height); +static void VGA_HorizontalTimer(void) { + +} + +static void VGA_DrawPart(void) { + Bitu subline=0;Bitu vidofs=vga.config.real_start; + Bit8u * draw=0; + while (vga.draw.lines_left) { + vga.draw.lines_left--; + Bit8u * data=VGA_DrawLine(vga.draw.address,vga.draw.panning,vga.draw.address_line); + RENDER_DrawLine(data); + vga.draw.address_line++; + if (vga.draw.address_line>=vga.draw.address_line_total) { + vga.draw.address_line=0; + vga.draw.address+=vga.draw.address_add; + } + if (vga.draw.split_line==vga.draw.lines_left) { + vga.draw.address=0;vga.draw.panning=0; } -norender:; } - + RENDER_EndUpdate(); +// vga.draw.parts_left--; +// if (vga.draw.parts_left) PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts); } +static void VGA_VerticalTimer(void) { + vga.config.retrace=false; + vga.draw.cursor.count++;vga.draw.cursor.count&=0xf; + PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal); + PIC_AddEvent(VGA_VerticalDisplayEnd,vga.draw.micro.vend); + vga.draw.parts_left=4; + vga.draw.lines_left=vga.draw.lines_total; + vga.draw.address=vga.config.real_start; + vga.draw.address_line=vga.config.hlines_skip; + vga.draw.split_line=vga.draw.lines_total-(vga.config.line_compare/vga.draw.lines_scaled); + vga.draw.panning=vga.config.pel_panning; + if (RENDER_StartUpdate()) { + VGA_DrawPart(); + } +} void VGA_SetupDrawing(void) { /* Calculate the FPS for this screen */ double fps; Bitu vtotal=2 + vga.crtc.vertical_total | - ((vga.crtc.overflow & 1) << 8) | ((vga.crtc.overflow & 0x20) << 4) - ; + ((vga.crtc.overflow & 1) << 8) | ((vga.crtc.overflow & 0x20) << 4); Bitu htotal=5 + vga.crtc.horizontal_total; Bitu vdispend = 1 + (vga.crtc.vertical_display_end | ((vga.crtc.overflow & 2)<<7) | ((vga.crtc.overflow & 0x40) << 3) | @@ -353,12 +225,16 @@ void VGA_SetupDrawing(void) { Bitu hdispend = 1 + (vga.crtc.horizontal_display_end); Bitu hbstart = vga.crtc.start_horizontal_blanking; - Bitu vbstart = vga.crtc.start_vertical_blanking | ((vga.crtc.overflow & 0x08) << 5) | ((vga.crtc.maximum_scan_line & 0x20) << 4) ; - - if (hbstart> 2) & 3; clock=1000*S3_CLOCK(vga.s3.clk[clock].m,vga.s3.clk[clock].n,vga.s3.clk[clock].r); /* Check for 8 for 9 character clock mode */ @@ -369,11 +245,20 @@ void VGA_SetupDrawing(void) { } /* Check for dual transfer whatever thing,master clock/2 */ if (vga.s3.pll.cmd & 0x10) clock/=2; - LOG(LOG_VGA,LOG_NORMAL)("H total %d, V Total %d",htotal,vtotal); LOG(LOG_VGA,LOG_NORMAL)("H D End %d, V D End %d",hdispend,vdispend); fps=clock/(vtotal*htotal); + double linemicro=(1000000/fps); + vga.draw.parts_total=VGA_PARTS; + vga.draw.micro.vtotal=(Bitu)(linemicro); + linemicro/=vtotal; //Really make it the line_micro + vga.draw.micro.vend=(Bitu)(linemicro*vrstart); + vga.draw.micro.parts=(Bitu)((linemicro*vdispend)/vga.draw.parts_total); + vga.draw.micro.htotal=(Bitu)(linemicro); + vga.draw.micro.hend=(Bitu)((linemicro/htotal)*hrstart); + + double correct_ratio=(100.0/525.0); double aspect_ratio=((double)htotal/((double)vtotal)/correct_ratio); @@ -382,80 +267,113 @@ void VGA_SetupDrawing(void) { Bitu scalew=1; Bitu scaleh=1; - vga.draw.lines=height=vdispend; width=hdispend; - vga.draw.double_height=vga.config.vline_double; - vga.draw.double_width=(vga.seq.clocking_mode & 0x8)>0; - vga.draw.font_height=vga.config.vline_height+1; + height=vdispend; + vga.draw.double_scan=false; + vga.draw.font_height=(vga.crtc.maximum_scan_line&0xf)+1; switch (vga.mode) { case M_VGA: - vga.draw.double_width=true; //Hack since 256 color modes use 2 clocks for a pixel - /* Don't know might do this different sometime, will have to do for now */ + scalew=2; scaleh*=vga.draw.font_height; + if (vga.crtc.maximum_scan_line&0x80) scaleh*=2; + vga.draw.lines_scaled=scaleh; + height/=scaleh; width<<=2; pitch=vga.config.scan_len*8; + vga.draw.address_add=vga.config.scan_len*2; + vga.draw.address_line_total=1; + VGA_DrawLine=VGA_VGA_Draw_Line; break; case M_LIN8: width<<=3; scaleh*=vga.draw.font_height; - pitch=vga.config.scan_len*8; + pitch=vga.config.scan_len*4; + vga.draw.address_add=vga.config.scan_len*2; + vga.draw.lines_scaled=scaleh; + vga.draw.address_line_total=1; + VGA_DrawLine=VGA_VGA_Draw_Line; break; case M_EGA16: width<<=3; pitch=vga.config.scan_len*16; scaleh*=vga.draw.font_height; + if (vga.crtc.maximum_scan_line&0x80) scaleh*=2; + vga.draw.lines_scaled=scaleh; + height/=scaleh; + if (vga.seq.clocking_mode & 0x8) scalew*=2; + vga.draw.address_add=vga.config.scan_len*2; + vga.draw.address_line_total=1; + VGA_DrawLine=VGA_EGA_Draw_Line; break; case M_CGA4: case M_CGA16: //Let is use 320x200 res and double pixels myself - vga.draw.double_width=true; //Hack if there's a runtime switch - vga.draw.double_height=true; //Hack if there's a runtime switch + scaleh=2;scalew=2; + vga.draw.blocks=width; width<<=2; pitch=width; + vga.draw.lines_scaled=1; + vga.draw.address_line_total=2; + vga.draw.address_add=80; //CGA doesn't have an offset reg + VGA_DrawLine=(vga.mode == M_CGA4) ? VGA_CGA4_Draw_Line : VGA_CGA16_Draw_Line; break; case M_CGA2: - vga.draw.double_width=false; //Hack if there's a runtime switch + scaleh=2; + vga.draw.address_line_total=2; + vga.draw.blocks=width; width<<=3; pitch=width; + vga.draw.address_line_total=2; + vga.draw.address_add=80; //CGA doesn't have an offset reg + vga.draw.lines_scaled=1; + VGA_DrawLine=VGA_CGA2_Draw_Line; break; case M_HERC: - vga.draw.double_height=false; //Hack if there's a runtime switch + vga.draw.address_line_total=4; width*=9; + vga.draw.blocks=width/8; + vga.draw.address_add=width/8; + vga.draw.lines_scaled=1; height=348; pitch=width; aspect_ratio=1.5; + VGA_DrawLine=VGA_HERC_Draw_Line; break; case M_TANDY16: - width<<=3; + scaleh=2;scalew=2; + vga.draw.blocks=width*2; + vga.draw.address_add=160; + vga.draw.address_line_total=4; + vga.draw.lines_scaled=1; + width<<=2; pitch=width; + VGA_DrawLine=VGA_TANDY16_Draw_Line; break; case M_TEXT2: case M_TEXT16: aspect_ratio=1.0; - vga.draw.font_height=vga.config.vline_height+1; + vga.draw.address_line_total=vga.draw.font_height; if (vga.draw.font_height<4 && (machine640) width=640; if (height>480) height=480; pitch=width; + VGA_DrawLine=VGA_TEXT_Draw_Line; break; default: LOG(LOG_VGA,LOG_ERROR)("Unhandled VGA type %d while checking for resolution"); }; - if (vga.draw.double_height) { - scaleh*=2; - } - height/=scaleh; - if (vga.draw.double_width) { - /* Double width is dividing main clock, the width should be correct already for this */ - scalew*=2; - } + vga.draw.lines_total=height; if (( width != vga.draw.width) || (height != vga.draw.height) || (pitch != vga.draw.pitch)) { - PIC_RemoveEvents(VGA_BlankTimer); + PIC_RemoveEvents(VGA_VerticalTimer); + PIC_RemoveEvents(VGA_VerticalDisplayEnd); vga.draw.width=width; vga.draw.height=height; vga.draw.pitch=pitch; @@ -463,8 +381,7 @@ void VGA_SetupDrawing(void) { LOG(LOG_VGA,LOG_NORMAL)("Width %d, Height %d, fps %f",width,height,fps); LOG(LOG_VGA,LOG_NORMAL)("Scalew %d, Scaleh %d aspect %f",scalew,scaleh,aspect_ratio); - RENDER_SetSize(width,height,8,pitch,aspect_ratio,scalew,scaleh,&VGA_DrawHandler); - vga.draw.blank=(Bitu)(1000000/fps); - PIC_AddEvent(VGA_BlankTimer,vga.draw.blank); + RENDER_SetSize(width,height,8,pitch,aspect_ratio,scalew,scaleh); + PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal); } }; diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 45d720f2..0842dd15 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -308,6 +308,9 @@ void VGA_SetupHandlers(void) { } switch ((vga.gfx.miscellaneous >> 2) & 3) { case 0: + vgapages.map_base=VGA_PAGE_A0; + MEM_SetPageHandler(VGA_PAGE_A0,32,range_handler); + break; case 1: vgapages.map_base=VGA_PAGE_A0; MEM_SetPageHandler(VGA_PAGE_A0,16,range_handler); From 73340903134e4850f2c1c45c8b3bed5c1ac94182 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 28 Jan 2004 14:40:13 +0000 Subject: [PATCH 1531/4131] Changed CGA/TANDY modes to be 200 lines and 60 hz Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1612 --- src/ints/int10.h | 1 + src/ints/int10_modes.cpp | 61 ++++++++++++++++++++++------------------ 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/ints/int10.h b/src/ints/int10.h index 6b544fe2..417def0c 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -104,6 +104,7 @@ struct VideoModeBlock { Bitu htotal,vtotal; Bitu hdispend,vdispend; + Bitu rate; Bitu special; }; diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index f0f1b0c5..b5d10cab 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,37 +16,37 @@ #define ATT_REGS 0x15 VideoModeBlock ModeList[]={ -/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde ,special flags */ -{ 0x000 ,M_TEXT16 ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_HALF_CLOCK }, -{ 0x001 ,M_TEXT16 ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_HALF_CLOCK }, -{ 0x002 ,M_TEXT16 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, -{ 0x003 ,M_TEXT16 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, -{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,_LINE_DOUBLE }, -{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,_LINE_DOUBLE }, -{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,_LINE_DOUBLE }, -{ 0x007 ,M_TEXT2 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, +/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde ,rate,special flags */ +{ 0x000 ,M_TEXT16 ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,70 ,_HALF_CLOCK }, +{ 0x001 ,M_TEXT16 ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,70 ,_HALF_CLOCK }, +{ 0x002 ,M_TEXT16 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,70 ,0 }, +{ 0x003 ,M_TEXT16 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,70 ,0 }, +{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,224 ,80 ,200 ,60 ,0 }, +{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,224 ,80 ,200 ,60 ,0}, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,224 ,80 ,200 ,60 ,0 }, +{ 0x007 ,M_TEXT2 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,70 ,0 }, /* 8,9,0xa are tandy modes */ -{ 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, +{ 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,50 ,224 ,80 ,200 ,60 ,0}, -{ 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_HALF_CLOCK |_LINE_DOUBLE }, -{ 0x00E ,M_EGA16 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,_LINE_DOUBLE }, -{ 0x00F ,M_EGA2 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,400 ,0 }, -{ 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,1 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, -{ 0x011 ,M_EGA2 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,449 ,80 ,480 ,0 }, -{ 0x012 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, -{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,_VGA_PIXEL_DOUBLE | _VGA_LINE_DOUBLE }, +{ 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,70 ,_HALF_CLOCK |_LINE_DOUBLE }, +{ 0x00E ,M_EGA16 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,70 ,_LINE_DOUBLE }, +{ 0x00F ,M_EGA2 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,400 ,70 ,0 }, +{ 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,1 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,70 ,0 }, +{ 0x011 ,M_EGA2 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,449 ,80 ,480 ,70 ,0 }, +{ 0x012 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,70 ,0 }, +{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,70 ,_VGA_PIXEL_DOUBLE | _VGA_LINE_DOUBLE }, -{ 0x100 ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, -{ 0x101 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, -{ 0x103 ,M_LIN8 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, +{ 0x100 ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,70 ,0 }, +{ 0x101 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,70 ,0 }, +{ 0x103 ,M_LIN8 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,70 ,0 }, -{ 0x150 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE | _VGA_LINE_DOUBLE }, -{ 0x151 ,M_LIN8 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE | _VGA_LINE_DOUBLE }, -{ 0x152 ,M_LIN8 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE }, -{ 0x153 ,M_LIN8 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE }, +{ 0x150 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,70 , _VGA_PIXEL_DOUBLE | _VGA_LINE_DOUBLE }, +{ 0x151 ,M_LIN8 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,70 , _VGA_PIXEL_DOUBLE | _VGA_LINE_DOUBLE }, +{ 0x152 ,M_LIN8 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,70 , _VGA_PIXEL_DOUBLE }, +{ 0x153 ,M_LIN8 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,70 , _VGA_PIXEL_DOUBLE }, -{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, +{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 ,0 }, }; @@ -345,11 +345,16 @@ foundmode: IO_Write(crtc_base,0x11); IO_Write(crtc_base+1,IO_Read(crtc_base+1)|0x80); /* Setup the correct clock */ - if (CurMode->mode<0x100) { + switch (CurMode->type) { + case M_VGA: + case M_TEXT2: + case M_TEXT16: + case M_EGA16: //Stick to 25mhz clock for now - } else { + break; + default: misc_output|=0xef; //Select clock 3 - Bitu clock=CurMode->vtotal*8*CurMode->htotal*70; + Bitu clock=CurMode->vtotal*8*CurMode->htotal*CurMode->rate; VGA_SetClock(3,clock/1000); } /* Write Misc Output */ From 69845fdb29cc69a5be2a418e072a49bfcda7cec3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 28 Jan 2004 14:46:26 +0000 Subject: [PATCH 1532/4131] add opengl32.lib to be linked Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1613 --- visualc_net/dosbox.vcproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index de9ee920..5d30ae35 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -38,7 +38,7 @@ Name="VCCustomBuildTool"/> Date: Wed, 28 Jan 2004 14:48:20 +0000 Subject: [PATCH 1533/4131] Enable C_OPENGL for visualc Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1614 --- src/platform/visualc/config.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index fcd1b404..42aeeeb0 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -8,6 +8,9 @@ /* Define to 1 to enable screenshots, requires libpng */ #define C_SSHOT 1 +/* Define to 1 to use opengl display output support */ +#define C_OPENGL 1 + /* Define to 1 to enable internal modem support, requires SDL_net */ #define C_MODEM 1 From ce6f81a73c792ae512165ba0e2475d5122a36a62 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 28 Jan 2004 15:12:38 +0000 Subject: [PATCH 1534/4131] Fix nvidia pixel data range extension support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1615 --- src/gui/sdlmain.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 52336849..6818ead2 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.56 2004-01-28 14:39:05 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.57 2004-01-28 15:12:38 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -52,6 +52,7 @@ #endif #ifdef __WIN32__ +#define NVIDIA_PixelDataRange 1 #ifndef WGL_NV_allocate_memory #define WGL_NV_allocate_memory 1 typedef void * (APIENTRY * PFNWGLALLOCATEMEMORYNVPROC) (int size, float readfreq, float writefreq, float priority); @@ -61,9 +62,9 @@ PFNWGLFREEMEMORYNVPROC db_glFreeMemoryNV = NULL; #endif #else - #endif +#if defined(NVIDIA_PixelDataRange) #ifndef GL_NV_pixel_data_range #define GL_NV_pixel_data_range 1 #define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 @@ -71,6 +72,7 @@ typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei lengt typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); PFNGLPIXELDATARANGENVPROC glPixelDataRangeNV = NULL; #endif +#endif #endif //C_OPENGL @@ -131,7 +133,7 @@ struct SDL_Block { GLint max_texsize; bool packed_pixel; bool paletted_texture; -#ifdef GL_NV_pixel_data_range +#if defined(NVIDIA_PixelDataRange) bool pixel_data_range; #endif } opengl; @@ -277,7 +279,13 @@ dosurface: #if C_OPENGL case SCREEN_OPENGL: { - if (sdl.opengl.framebuf) db_glFreeMemoryNV(sdl.opengl.framebuf); + if (sdl.opengl.framebuf) { +#if defined(NVIDIA_PixelDataRange) + if (sdl.opengl.pixel_data_range) db_glFreeMemoryNV(sdl.opengl.framebuf); + else +#endif + free(sdl.opengl.framebuf); + } sdl.opengl.framebuf=0; if (bpp!=32) goto dosurface; int texsize=2 << int_log2(width > height ? width : height); @@ -320,7 +328,7 @@ dosurface: goto dosurface; } /* Create the texture and display list */ -#ifdef GL_NV_pixel_data_range +#if defined(NVIDIA_PixelDataRange) if (sdl.opengl.pixel_data_range) { sdl.opengl.framebuf=db_glAllocateMemoryNV(width*height*4,0.0,1.0,1.0); glPixelDataRangeNV(GL_WRITE_PIXEL_DATA_RANGE_NV,width*height*4,sdl.opengl.framebuf); @@ -570,7 +578,7 @@ static void GUI_StartUp(Section * sec) { sdl.opengl.texture=0; sdl.opengl.displaylist=0; glGetIntegerv (GL_MAX_TEXTURE_SIZE, &sdl.opengl.max_texsize); -#if defined(__WIN32__) +#if defined(__WIN32__) && defined(NVIDIA_PixelDataRange) glPixelDataRangeNV = (PFNGLPIXELDATARANGENVPROC) wglGetProcAddress("glPixelDataRangeNV"); db_glAllocateMemoryNV = (PFNWGLALLOCATEMEMORYNVPROC) wglGetProcAddress("wglAllocateMemoryNV"); db_glFreeMemoryNV = (PFNWGLFREEMEMORYNVPROC) wglGetProcAddress("wglFreeMemoryNV"); @@ -578,11 +586,11 @@ static void GUI_StartUp(Section * sec) { const char * gl_ext = (const char *)glGetString (GL_EXTENSIONS); sdl.opengl.packed_pixel=strstr(gl_ext,"EXT_packed_pixels") > 0; sdl.opengl.paletted_texture=strstr(gl_ext,"EXT_paletted_texture") > 0; -#ifdef GL_NV_pixel_data_range +#if defined(NVIDIA_PixelDataRange) sdl.opengl.pixel_data_range=strstr(gl_ext,"GL_NV_pixel_data_range") >0 && - glPixelDataRangeNV; -#endif + glPixelDataRangeNV && db_glAllocateMemoryNV && db_glFreeMemoryNV; #endif +#endif //OPENGL /* Initialize screen for first time */ sdl.surface=SDL_SetVideoMode(640,400,0,0); sdl.desktop.bpp=sdl.surface->format->BitsPerPixel; @@ -590,7 +598,7 @@ static void GUI_StartUp(Section * sec) { LOG_MSG("SDL:You are running in 24 bpp mode, this will slow down things!"); } GFX_SetSize(640,400,8,1.0,1.0,0); - SDL_EnableKeyRepeat(250,30); +// SDL_EnableKeyRepeat(250,30); SDL_EnableUNICODE(1); /* Get some Keybinds */ KEYBOARD_AddEvent(KBD_f9,KBD_MOD_CTRL,KillSwitch); From 5640023e404f45b3cd0f0fda59869445ef4f8ae1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 28 Jan 2004 18:04:18 +0000 Subject: [PATCH 1535/4131] CGA2 Fill and copy row implementation added(Taiken7) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1616 --- src/ints/int10_char.cpp | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 3e940dcb..4a4e97b3 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.21 2004-01-10 14:03:35 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.22 2004-01-28 18:04:18 harekiet Exp $ */ /* Character displaying moving functions */ @@ -26,6 +26,19 @@ #include "inout.h" #include "int10.h" +static INLINE void CGA2_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { + Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); + PhysPt dest=base+((CurMode->twidth*rnew)*(cheight/2)+cleft); + PhysPt src=base+((CurMode->twidth*rold)*(cheight/2)+cleft); + Bitu copy=(cright-cleft); + Bitu nextline=CurMode->twidth; + for (Bitu i=0;itwidth*rnew)*(cheight/2)+cleft)*2; @@ -80,6 +93,22 @@ static INLINE void TEXT_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,P MEM_BlockCopy(dest,src,(cright-cleft)*2); } +static INLINE void CGA2_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { + Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); + PhysPt dest=base+((CurMode->twidth*row)*(cheight/2)+cleft); + Bitu copy=(cright-cleft); + Bitu nextline=CurMode->twidth; + attr=(attr & 0x3) | ((attr & 0x3) << 2) | ((attr & 0x3) << 4) | ((attr & 0x3) << 6); + for (Bitu i=0;itwidth*row)*(cheight/2)+cleft)*2; @@ -178,7 +207,8 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit case M_TEXT2: case M_TEXT16: TEXT_CopyRow(cul,clr,start,start+nlines,base);break; -// case M_CGA2: + case M_CGA2: + CGA2_CopyRow(cul,clr,start,start+nlines,base);break; case M_CGA4: CGA4_CopyRow(cul,clr,start,start+nlines,base);break; case M_TANDY16: @@ -202,7 +232,8 @@ filling: case M_TEXT2: case M_TEXT16: TEXT_FillRow(cul,clr,start,base,attr);break; -// case M_CGA2: + case M_CGA2: + CGA2_FillRow(cul,clr,start,base,attr);break; case M_CGA4: CGA4_FillRow(cul,clr,start,base,attr);break; case M_TANDY16: From 66aa2864764cb931d768989a83d9cbc534e4dcc6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 28 Jan 2004 19:29:29 +0000 Subject: [PATCH 1536/4131] Fix attribute mode control register not always saving value Add blinking text support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1617 --- src/hardware/vga_attr.cpp | 9 +++++++-- src/hardware/vga_draw.cpp | 12 +++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index f86afb58..1be6d23f 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -57,12 +57,16 @@ void write_p3c0(Bit32u port,Bit8u val) { break; case 0x10: /* Mode Control Register */ if ((attr(mode_control) ^ val) & 0x80) { - attr(mode_control)=val; + attr(mode_control)^=0x80; for (Bitu i=0;i<0x10;i++) { VGA_ATTR_SetPalette(i,vga.attr.palette[i]); } } - attr(mode_control)=val; + if ((attr(mode_control) ^ val) & 0x08) { + /* Fill up background text mode color lookup table */ + Bit32u b=(val & 8) ^ 0x8; + for (Bitu i=0;i<8;i++) TXT_BG_Table[i+8]=(b+i) | ((b+i) << 8)| ((b+i) <<16) | ((b+i) << 24); + } /* Special hacks for games programming registers themselves, Doesn't work if they program EGA16 themselves, @@ -73,6 +77,7 @@ void write_p3c0(Bit32u port,Bit8u val) { } else { if (vga.mode==M_VGA) VGA_SetMode(M_EGA16); } + attr(mode_control)=val; //TODO Monochrome mode //TODO 9 bit characters //TODO line wrapping split screen shit see bit 5 diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 75731ad2..343e3b3e 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -100,6 +100,8 @@ static Bit8u * VGA_VGA_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { return &vga.mem.linear[vidstart*4+panning/2]; } + +static Bit32u FontMask[2]={0xffffffff,0x0}; static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { Bit8u * draw=VGA_DrawBuffer; Bit8u * vidmem=&vga.mem.linear[vidstart]; @@ -111,6 +113,7 @@ static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { Bitu col=vidmem[cx*2+1]; Bit32u fg=TXT_FG_Table[col&0xf]; Bit32u bg=TXT_BG_Table[col>>4]; + mask1&=FontMask[col >> 7];mask2&=FontMask[col >> 7]; *(Bit32u*)draw=fg&mask1 | bg&~mask1; draw+=4; *(Bit32u*)draw=fg&mask2 | bg&~mask2; @@ -199,7 +202,6 @@ static void VGA_DrawPart(void) { static void VGA_VerticalTimer(void) { vga.config.retrace=false; - vga.draw.cursor.count++;vga.draw.cursor.count&=0xf; PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal); PIC_AddEvent(VGA_VerticalDisplayEnd,vga.draw.micro.vend); vga.draw.parts_left=4; @@ -208,6 +210,14 @@ static void VGA_VerticalTimer(void) { vga.draw.address_line=vga.config.hlines_skip; vga.draw.split_line=vga.draw.lines_total-(vga.config.line_compare/vga.draw.lines_scaled); vga.draw.panning=vga.config.pel_panning; + switch (vga.mode) { + case M_TEXT2:case M_TEXT16: + vga.draw.cursor.count++; + /* check for blinking and blinking change delay */ + FontMask[1]=(vga.attr.mode_control & (vga.draw.cursor.count >> 1) & 0x8) ? + 0 : 0xffffffff; + break; + } if (RENDER_StartUpdate()) { VGA_DrawPart(); } From 028737db18ec73f03cea1ca6f4287566b6c08210 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 28 Jan 2004 19:42:08 +0000 Subject: [PATCH 1537/4131] added 2 and 3 bit adpcm (Srecko) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1618 --- src/hardware/sblaster.cpp | 116 +++++++++++++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index ad27fb21..93430fe8 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -65,6 +65,8 @@ enum DSP_MODES { enum DMA_MODES { DMA_NONE, DMA_8_SILENCE, + DMA_2_SINGLE, + DMA_3_SINGLE, DMA_4_SINGLE, DMA_8_SINGLE,DMA_8_AUTO, DMA_16_SINGLE,DMA_16_AUTO, @@ -285,6 +287,34 @@ INLINE Bit16s decode_ADPCM_4_sample(Bit8u sample,Bits& reference,Bits& scale) { #endif +INLINE Bit16s decode_ADPCM_2_sample(Bit8u sample,Bits& reference,Bits& scale) { + static Bits scaleMap[8] = { -2, -1, 0, 0, 1, 1, 1, 1 }; + + if (sample & 0x02) { + reference = max(0x00, reference - ((sample & 0x01) << (scale+2))); + } else { + reference = min(0xff, reference + ((sample & 0x01) << (scale+2))); + } + scale = max(2, min(6, scaleMap[sample & 0x07])); + return (((Bit8s)reference)^0x80)<<8; +} + +INLINE Bit16s decode_ADPCM_3_sample(Bit8u sample,Bits& reference,Bits& scale) { + static Bits scaleMap[8] = { -2, -1, 0, 0, 1, 1, 1, 1 }; + + if (sample & 0x04) { + reference = max(0x00, reference - ((sample & 0x03) << (scale+1))); + } else { + reference = min(0xff, reference + ((sample & 0x03) << (scale+1))); + } + scale = max(2, min(6, scaleMap[sample & 0x07])); + return (((Bit8s)reference)^0x80)<<8; +} + + + + + static void GenerateDMASound(Bitu size) { /* Check some variables */ if (!size) return; @@ -296,8 +326,72 @@ static void GenerateDMASound(Bitu size) { #else if (index<2000) size=sb.dma.left; #endif - Bitu read,i; + Bitu read,i,ad; switch (sb.dma.mode) { + case DMA_2_SINGLE: + if (sb.adpcm.reference==0x1000000 && sb.dma.left) { + Bit8u ref; + read=DMA_8_Read(sb.hw.dma8,&ref,1); + if (!read) { sb.mode=MODE_NONE;return; } + sb.dma.left--; + sb.adpcm.reference=0; + sb.adpcm.stepsize=MIN_ADAPTIVE_STEP_SIZE; + } + if (sb.dma.left> 6,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[i*4+1]=decode_ADPCM_2_sample((sb.dma.buf.b8[i] >>4) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[i*4+2]=decode_ADPCM_2_sample((sb.dma.buf.b8[i] >>2)& 0x3,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[i*4+3]=decode_ADPCM_2_sample(sb.dma.buf.b8[i] & 0x3,sb.adpcm.reference,sb.adpcm.stepsize); + } + read*=4; + break; + case DMA_3_SINGLE: + if (sb.adpcm.reference==0x1000000 && sb.dma.left) { + Bit8u ref; + read=DMA_8_Read(sb.hw.dma8,&ref,1); + if (!read) { sb.mode=MODE_NONE;return;} + sb.dma.left--; + sb.adpcm.reference=0; + sb.adpcm.stepsize=MIN_ADAPTIVE_STEP_SIZE; + } + if (sb.dma.left>3)&7, sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[i*8+2]=decode_ADPCM_3_sample(((sb.dma.buf.b8[i*3] >>6)&3)&((sb.dma.buf.b8[i*3+1]&1)<<2),sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[i*8+3]=decode_ADPCM_3_sample((sb.dma.buf.b8[i*3+1]>>1)&7,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[i*8+4]=decode_ADPCM_3_sample((sb.dma.buf.b8[i*3+1]>>4)&7,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[i*8+5]=decode_ADPCM_3_sample(((sb.dma.buf.b8[i*3+1]>>7)&1)&((sb.dma.buf.b8[i*3+2]&3)<<1),sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[i*8+6]=decode_ADPCM_3_sample((sb.dma.buf.b8[i*3+2]>>2)&7,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[i*8+7]=decode_ADPCM_3_sample((sb.dma.buf.b8[i*3+2]>>5)&7,sb.adpcm.reference,sb.adpcm.stepsize); + } + read*=8; + if (ad) { + sb.tmp.buf.m[read]=decode_ADPCM_3_sample((sb.dma.buf.b8[read*3/8])&7,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[read+1]=decode_ADPCM_3_sample((sb.dma.buf.b8[read*3/8]>>3)&7,sb.adpcm.reference,sb.adpcm.stepsize); + read+=2; + if (ad==2) { + sb.tmp.buf.m[read]=decode_ADPCM_3_sample(((sb.dma.buf.b8[(read-2)*3/8-1]>>6)&3)&(sb.dma.buf.b8[read*3/8]&1), sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[read+1]=decode_ADPCM_3_sample((sb.dma.buf.b8[(read-2)*3/8]>>1)&7,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[read+2]=decode_ADPCM_3_sample((sb.dma.buf.b8[(read-2)*3/8]>>4)&7,sb.adpcm.reference,sb.adpcm.stepsize); + read+=3; + } + } + break; case DMA_4_SINGLE: if (sb.adpcm.reference==0x1000000 && sb.dma.left) { //TODO Check this @@ -489,6 +583,14 @@ static void DSP_StartDMATranfser(DMA_MODES mode) { type="4-Bit ADPCM Single Cycle"; sb.tmp.add_index=(sb.dma.rate<<16)/sb.hw.rate; break; + case DMA_3_SINGLE: + type="3-Bit ADPCM Single Cycle"; + sb.tmp.add_index=(sb.dma.rate<<16)/sb.hw.rate; + break; + case DMA_2_SINGLE: + type="2-Bit ADPCM Single Cycle"; + sb.tmp.add_index=(sb.dma.rate<<16)/sb.hw.rate; + break; default: LOG(LOG_SB,LOG_ERROR)("DSP:Illegal transfer mode %d",mode); return; @@ -594,6 +696,18 @@ static void DSP_DoCommand(void) { sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); DSP_StartDMATranfser(DMA_4_SINGLE); break; + case 0x77: /* 074h : Single Cycle 3-bit(2.6bit) ADPCM Reference*/ + sb.adpcm.reference=0x1000000; + case 0x76: /* 074h : Single Cycle 3-bit(2.6bit) ADPCM */ + sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); + DSP_StartDMATranfser(DMA_3_SINGLE); + break; + case 0x17: /* 074h : Single Cycle 2-bit ADPCM Reference*/ + sb.adpcm.reference=0x1000000; + case 0x16: /* 074h : Single Cycle 2-bit ADPCM */ + sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); + DSP_StartDMATranfser(DMA_2_SINGLE); + break; case 0x80: /* Silence DAC */ sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); DSP_StartDMATranfser(DMA_8_SILENCE); From c32e90eabdacaa2834739fe83b9636e1b056e94c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 28 Jan 2004 21:00:42 +0000 Subject: [PATCH 1538/4131] Fix CGA Start address and address range Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1619 --- src/hardware/vga_draw.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 343e3b3e..bc09bb1a 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -44,10 +44,9 @@ static Bit8u * VGA_HERC_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { } static Bit8u * VGA_CGA2_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { - Bit8u * reader=&vga.mem.linear[vidstart+(line * 8 * 1024)]; - Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0]; + line*=8*1024;Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0]; for (Bitu x=vga.draw.blocks;x>0;x--) { - Bitu val=*reader++; + Bitu val=vga.mem.linear[vidstart+line];vidstart=(vidstart+1)&0x1fff; *draw++=CGA_2_Table[val >> 4]; *draw++=CGA_2_Table[val & 0xf]; } @@ -55,10 +54,10 @@ static Bit8u * VGA_CGA2_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { } static Bit8u * VGA_CGA4_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { - Bit8u * reader=&vga.mem.linear[vidstart+(line * 8 * 1024)]; - Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0]; + line*=8*1024;Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0]; for (Bitu x=0;x> 4] | convert16[val & 0xf] << 16; *draw++=full|=full<<8; } @@ -217,6 +215,9 @@ static void VGA_VerticalTimer(void) { FontMask[1]=(vga.attr.mode_control & (vga.draw.cursor.count >> 1) & 0x8) ? 0 : 0xffffffff; break; + case M_CGA4:case M_CGA2:case M_CGA16: + vga.draw.address=(vga.draw.address*2)&0x1fff; + break; } if (RENDER_StartUpdate()) { VGA_DrawPart(); From 2436917d8c419f3e6ea4ec9c158d8b08aa4d75dc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 28 Jan 2004 21:36:48 +0000 Subject: [PATCH 1539/4131] Fix pel panning in 256 color vga mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1620 --- src/hardware/vga_draw.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index bc09bb1a..442147ba 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -95,7 +95,7 @@ static Bit8u * VGA_EGA_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { return &vga.mem.linear[512*1024+vidstart*8+panning]; } static Bit8u * VGA_VGA_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { - return &vga.mem.linear[vidstart*4+panning/2]; + return &vga.mem.linear[vidstart*4+panning]; } @@ -191,6 +191,7 @@ static void VGA_DrawPart(void) { } if (vga.draw.split_line==vga.draw.lines_left) { vga.draw.address=0;vga.draw.panning=0; + vga.draw.address_line=0; } } RENDER_EndUpdate(); @@ -214,6 +215,7 @@ static void VGA_VerticalTimer(void) { /* check for blinking and blinking change delay */ FontMask[1]=(vga.attr.mode_control & (vga.draw.cursor.count >> 1) & 0x8) ? 0 : 0xffffffff; + vga.draw.address=(vga.draw.address*2); break; case M_CGA4:case M_CGA2:case M_CGA16: vga.draw.address=(vga.draw.address*2)&0x1fff; From 0f2a610b63c5ac6d5a118d6c94d00e315050c513 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 29 Jan 2004 09:26:52 +0000 Subject: [PATCH 1540/4131] setup handles floats as well Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1621 --- include/setup.h | 16 ++++++++++++++-- src/gui/sdlmain.cpp | 6 +++--- src/misc/setup.cpp | 25 +++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/include/setup.h b/include/setup.h index bbc2cc24..c5aca20c 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.14 2004-01-08 11:45:24 qbix79 Exp $ */ +/* $Id: setup.h,v 1.15 2004-01-29 09:26:43 qbix79 Exp $ */ #ifndef _SETUP_H_ #define _SETUP_H_ @@ -55,6 +55,7 @@ union Value{ bool _bool; int _int; std::string* _string; + float _float; }; class Property { @@ -77,6 +78,15 @@ public: void GetValuestring(char* str); ~Prop_int(){ } }; +class Prop_float:public Property { +public: + Prop_float(const char* _propname, float _value):Property(_propname){ + __value._float=_value; + } + void SetValue(char* input); + void GetValuestring(char* str); + ~Prop_float(){ } +}; class Prop_bool:public Property { public: @@ -145,11 +155,13 @@ class Section_prop:public Section { void Add_string(const char* _propname, char* _value=NULL); void Add_bool(const char* _propname, bool _value=false); void Add_hex(const char* _propname, int _value=0); + void Add_float(const char* _propname, float _value=0.0); int Get_int(const char* _propname); const char* Get_string(const char* _propname); bool Get_bool(const char* _propname); - int Get_hex(const char* _propname); + int Get_hex(const char* _propname); + float Get_float(const char* _propname); void HandleInputline(char *gegevens); void PrintData(FILE* outfile); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 6818ead2..b653fe3e 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.57 2004-01-28 15:12:38 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.58 2004-01-29 09:26:45 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -539,7 +539,7 @@ static void GUI_StartUp(Section * sec) { sdl.desktop.width=section->Get_int("fullwidth"); sdl.desktop.height=section->Get_int("fullheight"); sdl.desktop.doublebuf=section->Get_bool("fulldouble"); - sdl.desktop.hwscale=1.2; + sdl.desktop.hwscale=section->Get_float("hwscale"); if (!sdl.desktop.width) { #ifdef WIN32 sdl.desktop.width=GetSystemMetrics(SM_CXSCREEN); @@ -910,7 +910,7 @@ int main(int argc, char* argv[]) { sdl_sec->Add_int("fullwidth",0); sdl_sec->Add_int("fullheight",0); sdl_sec->Add_string("output","surface"); - sdl_sec->Add_string("hwscale","1.0"); + sdl_sec->Add_float("hwscale",1.0); sdl_sec->Add_bool("autolock",true); sdl_sec->Add_int("sensitivity",100); sdl_sec->Add_bool("waitonerror",true); diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 43702295..d10582fb 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.18 2004-01-08 11:46:40 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.19 2004-01-29 09:26:52 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -30,6 +30,10 @@ using namespace std; +void Prop_float::SetValue(char* input){ + input=trim(input); + __value._float= atof(input); +} void Prop_int::SetValue(char* input){ input=trim(input); @@ -66,10 +70,20 @@ void Prop_bool::GetValuestring(char* str){ sprintf(str,"%s",__value._bool?"true":"false"); } +void Prop_float::GetValuestring(char* str){ + sprintf(str,"%1.2f",__value._float); +} + void Prop_hex::GetValuestring(char* str){ sprintf(str,"%X",__value._hex); } +void Section_prop::Add_float(const char* _propname, float _value) { + Property* test=new Prop_float(_propname,_value); + properties.push_back(test); +} + + void Section_prop::Add_int(const char* _propname, int _value) { Property* test=new Prop_int(_propname,_value); properties.push_back(test); @@ -105,7 +119,14 @@ bool Section_prop::Get_bool(const char* _propname){ } return false; } - +float Section_prop::Get_float(const char* _propname){ + for(it tel=properties.begin();tel!=properties.end();tel++){ + if((*tel)->propname==_propname){ + return ((*tel)->GetValue())._float; + } + } + return false; +} const char* Section_prop::Get_string(const char* _propname){ for(it tel=properties.begin();tel!=properties.end();tel++){ From b9b3c9b559ab09866c918f4d245a582c1c59731b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 29 Jan 2004 16:58:24 +0000 Subject: [PATCH 1541/4131] Only schedule a key if current one is read Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1622 --- src/hardware/keyboard.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index f3bf93be..c2746183 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.18 2004-01-07 12:18:58 qbix79 Exp $ */ +/* $Id: keyboard.cpp,v 1.19 2004-01-29 16:58:24 qbix79 Exp $ */ #include #include "dosbox.h" @@ -117,13 +117,14 @@ void KEYBOARD_AddCode(Bit8u scancode,Bit8u ascii,Bitu mod,KeyStates state) { keyb.buf.code[start].mod=mod; } /* Start up an event to start the first IRQ */ - if (!keyb.scheduled) { + if (!keyb.scheduled && !keyb.key_on_60) { keyb.scheduled=true; PIC_AddEvent(KEYBOARD_GetCode,KEYDELAY); } } void KEYBOARD_ReadKey(Bitu & scancode,Bitu & ascii,Bitu & mod) { + keyb.key_on_60=false; //else no new keys get scheduled :) switch (keyb.buf.state) { case STATE_NORMAL: if (keyb.buf.used && !keyb.scheduled) { @@ -147,18 +148,21 @@ void KEYBOARD_ReadKey(Bitu & scancode,Bitu & ascii,Bitu & mod) { } static Bit8u read_p60(Bit32u port) { + keyb.key_on_60 = false; switch (keyb.buf.state) { case STATE_NORMAL: - if (keyb.buf.used && !keyb.scheduled) { + if (keyb.buf.used && !keyb.scheduled) { //key60 is false keyb.scheduled=true; PIC_AddEvent(KEYBOARD_GetCode,KEYDELAY); } + return keyb.buf.code[keyb.buf.pos].scancode; case STATE_EXTEND: - if (!keyb.scheduled) { + if (!keyb.scheduled) { keyb.scheduled=true; PIC_AddEvent(KEYBOARD_GetCode,KEYDELAY); } + return 224; } return 0; @@ -187,7 +191,7 @@ static void write_p60(Bit32u port,Bit8u val) { case 0xf4: /* Enable keyboard,clear buffer, start scanning */ keyb.active=true; KEYBOARD_ClrBuffer(); - LOG(LOG_KEYBOARD,LOG_NORMAL)("Activated"); + LOG(LOG_KEYBOARD,LOG_NORMAL)("Activated port 60"); KEYBOARD_AddCode(0xfa,0,0,STATE_NORMAL); /* Acknowledge */ break; case 0xf5: /* Reset keyboard and disable scanning */ @@ -233,11 +237,11 @@ static void write_p64(Bit32u port,Bit8u val) { switch (val) { case 0xae: /* Activate keyboard */ keyb.active=true; - if (keyb.buf.used && !keyb.scheduled) { + if (keyb.buf.used && !keyb.scheduled && !keyb.key_on_60) { keyb.scheduled=true; PIC_AddEvent(KEYBOARD_GetCode,KEYDELAY); } - LOG(LOG_KEYBOARD,LOG_NORMAL)("Activated"); + LOG(LOG_KEYBOARD,LOG_NORMAL)("Activated port 64"); break; case 0xad: /* Deactivate keyboard */ keyb.active=false; From 74df88c3b595907b29495d5755d8120107b0c804 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 29 Jan 2004 17:00:24 +0000 Subject: [PATCH 1542/4131] enabled keyrepeat again at slightly slower interval Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1623 --- src/gui/sdlmain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index b653fe3e..ee2f5144 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.58 2004-01-29 09:26:45 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.59 2004-01-29 17:00:24 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -598,7 +598,7 @@ static void GUI_StartUp(Section * sec) { LOG_MSG("SDL:You are running in 24 bpp mode, this will slow down things!"); } GFX_SetSize(640,400,8,1.0,1.0,0); -// SDL_EnableKeyRepeat(250,30); + SDL_EnableKeyRepeat(250,40); SDL_EnableUNICODE(1); /* Get some Keybinds */ KEYBOARD_AddEvent(KBD_f9,KBD_MOD_CTRL,KillSwitch); From 7146fd91ad13449c0fea4bcfc37cae138bdd2a0d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 29 Jan 2004 20:13:29 +0000 Subject: [PATCH 1543/4131] last bit of port 64 now only depends on data readable and not in buffer. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1624 --- src/hardware/keyboard.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index c2746183..0fcde792 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.19 2004-01-29 16:58:24 qbix79 Exp $ */ +/* $Id: keyboard.cpp,v 1.20 2004-01-29 20:13:29 qbix79 Exp $ */ #include #include "dosbox.h" @@ -262,7 +262,9 @@ static void write_p64(Bit32u port,Bit8u val) { } static Bit8u read_p64(Bit32u port) { - Bit8u status= 0x1c | ((keyb.buf.used ||keyb.key_on_60)? 0x1 : 0x0); +// Bit8u status= 0x1c | ((keyb.buf.used ||keyb.key_on_60)? 0x1 : 0x0); +// Old one. Digitracker 2 doesn't like this. key_on_60 is much more advanged. + Bit8u status= 0x1c | (keyb.key_on_60? 0x1 : 0x0); keyb.key_on_60=false; return status; } From d1f015410768ffb325f3a6ed424cd45c7feafb8d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 30 Jan 2004 09:18:18 +0000 Subject: [PATCH 1544/4131] Added a nice blinking cursor again Added support for cga register to toggle textmode blinking Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1625 --- include/vga.h | 3 ++ src/hardware/vga_attr.cpp | 5 +-- src/hardware/vga_draw.cpp | 83 ++++++++++++++------------------------- src/hardware/vga_misc.cpp | 29 ++++++++++---- 4 files changed, 54 insertions(+), 66 deletions(-) diff --git a/include/vga.h b/include/vga.h index c320ac44..f55b3ff3 100644 --- a/include/vga.h +++ b/include/vga.h @@ -124,6 +124,7 @@ typedef struct { Bit8u font[64*1024]; Bitu font1_start; Bitu font2_start; + Bitu blinking; struct { Bit8u sline,eline; Bit8u count,delay; @@ -161,6 +162,7 @@ typedef struct { } VGA_HERC; typedef struct { + Bit8u mode_control; Bit8u color_select; } VGA_CGA; @@ -311,6 +313,7 @@ void VGA_SetClock(Bitu which,Bitu target); void VGA_DACSetEntirePalette(void); void VGA_StartRetrace(void); void VGA_StartUpdateLFB(void); +void VGA_SetBlinking(Bitu enabled); extern VGA_Type vga; diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 1be6d23f..a486344e 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -22,7 +22,6 @@ #define attr(blah) vga.attr.blah - void VGA_ATTR_SetPalette(Bit8u index,Bit8u val) { vga.attr.palette[index]=val; if (vga.attr.mode_control & 0x80) val=(val&0xf) | (vga.attr.color_select << 4); @@ -63,9 +62,7 @@ void write_p3c0(Bit32u port,Bit8u val) { } } if ((attr(mode_control) ^ val) & 0x08) { - /* Fill up background text mode color lookup table */ - Bit32u b=(val & 8) ^ 0x8; - for (Bitu i=0;i<8;i++) TXT_BG_Table[i+8]=(b+i) | ((b+i) << 8)| ((b+i) <<16) | ((b+i) << 24); + VGA_SetBlinking(val & 0x8); } /* Special hacks for games programming registers themselves, diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 442147ba..e771a504 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -101,7 +101,7 @@ static Bit8u * VGA_VGA_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { static Bit32u FontMask[2]={0xffffffff,0x0}; static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { - Bit8u * draw=VGA_DrawBuffer; + Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0]; Bit8u * vidmem=&vga.mem.linear[vidstart]; for (Bitu cx=0;cx>4]; mask1&=FontMask[col >> 7];mask2&=FontMask[col >> 7]; - *(Bit32u*)draw=fg&mask1 | bg&~mask1; - draw+=4; - *(Bit32u*)draw=fg&mask2 | bg&~mask2; - draw+=4; + *draw++=fg&mask1 | bg&~mask1; + *draw++=fg&mask2 | bg&~mask2; } + if (!vga.draw.cursor.enabled || !(vga.draw.cursor.count&0x8)) goto skip_cursor; + Bits font_addr=(vga.config.cursor_start*2-vidstart)/2; + if (font_addr>=0 && font_addrvga.draw.cursor.eline) goto skip_cursor; + draw=(Bit32u *)&VGA_DrawBuffer[font_addr*8]; + Bit32u att=TXT_FG_Table[vga.mem.linear[vga.config.cursor_start*2+1]&0xf]; + *draw++=att;*draw++=att; + } +skip_cursor: return VGA_DrawBuffer; } -void VGA_TEXT_Draw(Bit8u * bitdata,Bitu start,Bitu panning,Bitu lines) { -#if 0 - Bit8u * reader=&vga.mem.linear[start*2];Bitu rows=lines/vga.draw.font_height; - for (Bitu cy=rows;cy>0;cy--) { - for (Bitu y=0;y>4]; - Bit32u mask2=TXT_Font_Table[font&0xf]; - Bit8u col=reader[cx*2+1]; - Bit32u fg=TXT_FG_Table[col&0xf]; - Bit32u bg=TXT_BG_Table[col>>4]; - *(Bit32u*)draw=fg&mask1 | bg&~mask1; - draw+=4; - *(Bit32u*)draw=fg&mask2 | bg&~mask2; - draw+=4; - } - } - reader+=(vga.config.scan_len*4); - } -/* Cursor handling */ - if(vga.draw.cursor.enabled && (vga.draw.cursor.count>8)) { /* Draw a cursor if enabled */ - Bits cur_start=vga.config.cursor_start-start; - if (cur_start<0) return; - - Bitu row=cur_start / (vga.config.scan_len*2); - Bitu col=cur_start % (vga.config.scan_len*2); - Bit32u att=vga.mem.linear[vga.config.cursor_start*2+1]&0xf; - att=TXT_BG_Table[att]; - - if ((col*8)>=vga.draw.width) return; - if ((row*vga.draw.font_height)>=vga.draw.height) return; - if (vga.draw.cursor.sline>=vga.draw.font_height) return; - if (vga.draw.cursor.sline>vga.draw.cursor.eline) return; - Bit8u * cursor_draw=bitdata+(row*vga.draw.font_height+vga.draw.cursor.sline)*vga.draw.width+col*8; - - for (Bits loop=vga.draw.cursor.eline-vga.draw.cursor.sline;loop>=0;loop--) { - *((Bit32u *)cursor_draw)=att; - *((Bit32u *)(cursor_draw+4))=att; - cursor_draw+=vga.draw.width; - } - } -#endif -} - static void VGA_VerticalDisplayEnd(void) { vga.config.retrace=true; vga.config.real_start=vga.config.display_start; @@ -199,6 +159,21 @@ static void VGA_DrawPart(void) { // if (vga.draw.parts_left) PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts); } +void VGA_SetBlinking(Bitu enabled) { + Bitu b; + LOG_MSG("Blinking %d",enabled); + if (enabled) { + b=0;vga.draw.blinking=-1; + vga.attr.mode_control|=0x08; + vga.cga.mode_control&=~0x20; + } else { + b=8;vga.draw.blinking=0; + vga.attr.mode_control&=~0x08; + vga.cga.mode_control|=0x20; + } + for (Bitu i=0;i<8;i++) TXT_BG_Table[i+8]=(b+i) | ((b+i) << 8)| ((b+i) <<16) | ((b+i) << 24); +} + static void VGA_VerticalTimer(void) { vga.config.retrace=false; PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal); @@ -364,10 +339,10 @@ void VGA_SetupDrawing(void) { case M_TEXT2: case M_TEXT16: aspect_ratio=1.0; - vga.draw.address_line_total=vga.draw.font_height; if (vga.draw.font_height<4 && (machine Date: Fri, 30 Jan 2004 13:36:56 +0000 Subject: [PATCH 1545/4131] Some compile errors Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1626 --- src/hardware/vga_draw.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index e771a504..03bd9ed6 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -115,8 +115,8 @@ static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { *draw++=fg&mask1 | bg&~mask1; *draw++=fg&mask2 | bg&~mask2; } - if (!vga.draw.cursor.enabled || !(vga.draw.cursor.count&0x8)) goto skip_cursor; Bits font_addr=(vga.config.cursor_start*2-vidstart)/2; + if (!vga.draw.cursor.enabled || !(vga.draw.cursor.count&0x8)) goto skip_cursor; if (font_addr>=0 && font_addrvga.draw.cursor.eline) goto skip_cursor; @@ -161,9 +161,9 @@ static void VGA_DrawPart(void) { void VGA_SetBlinking(Bitu enabled) { Bitu b; - LOG_MSG("Blinking %d",enabled); + LOG(LOG_VGA,LOG_NORMAL)("Blinking %d",enabled); if (enabled) { - b=0;vga.draw.blinking=-1; + b=0;vga.draw.blinking=1; //used to -1 but blinking is unsigned vga.attr.mode_control|=0x08; vga.cga.mode_control&=~0x20; } else { From 18b0231f6af6691c1b225157e96727ddfaa2ce1f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 30 Jan 2004 13:40:49 +0000 Subject: [PATCH 1546/4131] fixed compilation when no screenshots Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1627 --- src/gui/render.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 2bbfb4b0..871305de 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.23 2004-01-28 14:39:05 harekiet Exp $ */ +/* $Id: render.cpp,v 1.24 2004-01-30 13:40:49 qbix79 Exp $ */ #include #include @@ -319,6 +319,7 @@ bool RENDER_StartUpdate(void) { void RENDER_EndUpdate(void) { if (!render.updating) return; +#if (C_SSHOT) switch (render.op.type) { case OP_None: case OP_Normal2x: @@ -331,6 +332,7 @@ void RENDER_EndUpdate(void) { render.op.type=render.shot.type; break; } +#endif /* If Things are added to please check the define */ GFX_EndUpdate(); RENDER_DrawLine=RENDER_EmptyLineHandler; render.updating=false; From e22fb1b7bc19135428ed19f2ffb4356fdee66c77 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 30 Jan 2004 21:11:34 +0000 Subject: [PATCH 1547/4131] Add opengl output mode without bilinear filtering Remove the red clearing color Check for valid range of hwscale Fix fullscreen window positioning in opengl mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1628 --- src/gui/sdlmain.cpp | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index ee2f5144..8f7aeafe 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.59 2004-01-29 17:00:24 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.60 2004-01-30 21:11:34 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -131,6 +131,7 @@ struct SDL_Block { GLuint texture; GLuint displaylist; GLint max_texsize; + bool bilinear; bool packed_pixel; bool paletted_texture; #if defined(NVIDIA_PixelDataRange) @@ -340,6 +341,7 @@ dosurface: sdl.opengl.framebuf=malloc(width*height*4); //32 bit color } sdl.opengl.pitch=width*4; + glViewport(sdl.clip.x,sdl.clip.y,sdl.clip.w,sdl.clip.h); glMatrixMode (GL_PROJECTION); glDeleteTextures(1,&sdl.opengl.texture); glGenTextures(1,&sdl.opengl.texture); @@ -347,13 +349,17 @@ dosurface: // No borders glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - // Bilinear filtering - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + if (sdl.opengl.bilinear) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texsize, texsize, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, 0); - glClearColor (1.0, 0.0, 0.0, 1.0); + glClearColor (0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glShadeModel (GL_FLAT); glDisable (GL_DEPTH_TEST); @@ -540,6 +546,10 @@ static void GUI_StartUp(Section * sec) { sdl.desktop.height=section->Get_int("fullheight"); sdl.desktop.doublebuf=section->Get_bool("fulldouble"); sdl.desktop.hwscale=section->Get_float("hwscale"); + if (sdl.desktop.hwscale<0.1f) { + LOG_MSG("SDL:Can't hwscale lower than 0.1"); + sdl.desktop.hwscale=0.1f; + } if (!sdl.desktop.width) { #ifdef WIN32 sdl.desktop.width=GetSystemMetrics(SM_CXSCREEN); @@ -565,6 +575,10 @@ static void GUI_StartUp(Section * sec) { #if C_OPENGL } else if (!strcasecmp(output,"opengl")) { sdl.desktop.want_type=SCREEN_OPENGL; + sdl.opengl.bilinear=true; + } else if (!strcasecmp(output,"openglnb")) { + sdl.desktop.want_type=SCREEN_OPENGL; + sdl.opengl.bilinear=false; #endif } else { LOG_MSG("SDL:Unsupported output device %s, switching back to surface",output); @@ -922,10 +936,10 @@ int main(int argc, char* argv[]) { "fullwidth/height -- What resolution to use for fullscreen, use together with fullfixed.\n" "output -- What to use for output: surface,overlay" #if C_OPENGL - ",opengl" + ",opengl,openglnb" #endif ".\n" - "hwscale -- Extra scaling of window if the output devive supports hardware scaling.\n" + "hwscale -- Extra scaling of window if the output device supports hardware scaling.\n" "autolock -- Mouse will automatically lock, if you click on the screen.\n" "sensitiviy -- Mouse sensitivity.\n" "waitonerror -- Wait before closing the console if dosbox has an error.\n" From 5993407d53bc5dfca5ab750636a3e55c7f3816c9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 31 Jan 2004 08:46:42 +0000 Subject: [PATCH 1548/4131] Remove extra cpu_cycles check Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1629 --- src/cpu/core_full.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index f49edb9c..9d7868cc 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -71,7 +71,6 @@ typedef PhysPt EAPoint; Bits CPU_Core_Full_Run(void) { FullData inst; restart_core: - if (CPU_Cycles<=0) return CBRET_NONE; if (!cpu.code.big) { inst.start_prefix=0x0;; inst.start_entry=0x0; From dc174a489739b8471b6ea9bd8317349d87cf5c04 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 31 Jan 2004 09:17:03 +0000 Subject: [PATCH 1549/4131] Fix small jumps forcing eip to 16bit in 32bit mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1630 --- src/cpu/core_normal/prefix_0f.h | 34 ++++++++-------- src/cpu/core_normal/prefix_66.h | 32 +++++++++++++++ src/cpu/core_normal/prefix_66_0f.h | 32 +++++++-------- src/cpu/core_normal/prefix_none.h | 64 +++++++++++++++--------------- src/cpu/core_normal/support.h | 20 +++++++--- 5 files changed, 112 insertions(+), 70 deletions(-) diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 09122714..c3509448 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -154,7 +154,7 @@ Bitu which=(rm >> 3) & 7; if (rm >= 0xc0 ) { GetEArd; - if (!CPU_SET_CRX(which,*eard)) goto decode_end; + CPU_SET_CRX(which,*eard); } else { GetEAa; LOG(LOG_CPU,LOG_ERROR)("MOV CR%,XXX with non-register",which); @@ -174,37 +174,37 @@ } break; CASE_0F_W(0x80) /* JO */ - JumpSIw(TFLG_O);break; + JumpCond16_w(TFLG_O);break; CASE_0F_W(0x81) /* JNO */ - JumpSIw(TFLG_NO);break; + JumpCond16_w(TFLG_NO);break; CASE_0F_W(0x82) /* JB */ - JumpSIw(TFLG_B);break; + JumpCond16_w(TFLG_B);break; CASE_0F_W(0x83) /* JNB */ - JumpSIw(TFLG_NB);break; + JumpCond16_w(TFLG_NB);break; CASE_0F_W(0x84) /* JZ */ - JumpSIw(TFLG_Z);break; + JumpCond16_w(TFLG_Z);break; CASE_0F_W(0x85) /* JNZ */ - JumpSIw(TFLG_NZ);break; + JumpCond16_w(TFLG_NZ);break; CASE_0F_W(0x86) /* JBE */ - JumpSIw(TFLG_BE);break; + JumpCond16_w(TFLG_BE);break; CASE_0F_W(0x87) /* JNBE */ - JumpSIw(TFLG_NBE);break; + JumpCond16_w(TFLG_NBE);break; CASE_0F_W(0x88) /* JS */ - JumpSIw(TFLG_S);break; + JumpCond16_w(TFLG_S);break; CASE_0F_W(0x89) /* JNS */ - JumpSIw(TFLG_NS);break; + JumpCond16_w(TFLG_NS);break; CASE_0F_W(0x8a) /* JP */ - JumpSIw(TFLG_P);break; + JumpCond16_w(TFLG_P);break; CASE_0F_W(0x8b) /* JNP */ - JumpSIw(TFLG_NP);break; + JumpCond16_w(TFLG_NP);break; CASE_0F_W(0x8c) /* JL */ - JumpSIw(TFLG_L);break; + JumpCond16_w(TFLG_L);break; CASE_0F_W(0x8d) /* JNL */ - JumpSIw(TFLG_NL);break; + JumpCond16_w(TFLG_NL);break; CASE_0F_W(0x8e) /* JLE */ - JumpSIw(TFLG_LE);break; + JumpCond16_w(TFLG_LE);break; CASE_0F_W(0x8f) /* JNLE */ - JumpSIw(TFLG_NLE);break; + JumpCond16_w(TFLG_NLE);break; CASE_0F_B(0x90) /* SETO */ SETcc(TFLG_O);break; CASE_0F_B(0x91) /* SETNO */ diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 4b52dfa5..df16c9a3 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -190,6 +190,38 @@ CASE_D(0x6b) /* IMUL Gd,Ed,Ib */ RMGdEdOp3(DIMULD,Fetchbs()); break; + CASE_D(0x70) /* JO */ + JumpCond32_b(TFLG_O);break; + CASE_D(0x71) /* JNO */ + JumpCond32_b(TFLG_NO);break; + CASE_D(0x72) /* JB */ + JumpCond32_b(TFLG_B);break; + CASE_D(0x73) /* JNB */ + JumpCond32_b(TFLG_NB);break; + CASE_D(0x74) /* JZ */ + JumpCond32_b(TFLG_Z);break; + CASE_D(0x75) /* JNZ */ + JumpCond32_b(TFLG_NZ);break; + CASE_D(0x76) /* JBE */ + JumpCond32_b(TFLG_BE);break; + CASE_D(0x77) /* JNBE */ + JumpCond32_b(TFLG_NBE);break; + CASE_D(0x78) /* JS */ + JumpCond32_b(TFLG_S);break; + CASE_D(0x79) /* JNS */ + JumpCond32_b(TFLG_NS);break; + CASE_D(0x7a) /* JP */ + JumpCond32_b(TFLG_P);break; + CASE_D(0x7b) /* JNP */ + JumpCond32_b(TFLG_NP);break; + CASE_D(0x7c) /* JL */ + JumpCond32_b(TFLG_L);break; + CASE_D(0x7d) /* JNL */ + JumpCond32_b(TFLG_NL);break; + CASE_D(0x7e) /* JLE */ + JumpCond32_b(TFLG_LE);break; + CASE_D(0x7f) /* JNLE */ + JumpCond32_b(TFLG_NLE);break; CASE_D(0x81) /* Grpl Ed,Id */ { GetRM;Bitu which=(rm>>3)&7; diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index d23ab4cc..39be74ba 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -124,37 +124,37 @@ } break; CASE_0F_D(0x80) /* JO */ - JumpSId(TFLG_O);break; + JumpCond32_d(TFLG_O);break; CASE_0F_D(0x81) /* JNO */ - JumpSId(TFLG_NO);break; + JumpCond32_d(TFLG_NO);break; CASE_0F_D(0x82) /* JB */ - JumpSId(TFLG_B);break; + JumpCond32_d(TFLG_B);break; CASE_0F_D(0x83) /* JNB */ - JumpSId(TFLG_NB);break; + JumpCond32_d(TFLG_NB);break; CASE_0F_D(0x84) /* JZ */ - JumpSId(TFLG_Z);break; + JumpCond32_d(TFLG_Z);break; CASE_0F_D(0x85) /* JNZ */ - JumpSId(TFLG_NZ);break; + JumpCond32_d(TFLG_NZ);break; CASE_0F_D(0x86) /* JBE */ - JumpSId(TFLG_BE);break; + JumpCond32_d(TFLG_BE);break; CASE_0F_D(0x87) /* JNBE */ - JumpSId(TFLG_NBE);break; + JumpCond32_d(TFLG_NBE);break; CASE_0F_D(0x88) /* JS */ - JumpSId(TFLG_S);break; + JumpCond32_d(TFLG_S);break; CASE_0F_D(0x89) /* JNS */ - JumpSId(TFLG_NS);break; + JumpCond32_d(TFLG_NS);break; CASE_0F_D(0x8a) /* JP */ - JumpSId(TFLG_P);break; + JumpCond32_d(TFLG_P);break; CASE_0F_D(0x8b) /* JNP */ - JumpSId(TFLG_NP);break; + JumpCond32_d(TFLG_NP);break; CASE_0F_D(0x8c) /* JL */ - JumpSId(TFLG_L);break; + JumpCond32_d(TFLG_L);break; CASE_0F_D(0x8d) /* JNL */ - JumpSId(TFLG_NL);break; + JumpCond32_d(TFLG_NL);break; CASE_0F_D(0x8e) /* JLE */ - JumpSId(TFLG_LE);break; + JumpCond32_d(TFLG_LE);break; CASE_0F_D(0x8f) /* JNLE */ - JumpSId(TFLG_NLE);break; + JumpCond32_d(TFLG_NLE);break; CASE_0F_D(0xa0) /* PUSH FS */ Push_32(SegValue(fs));break; diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 366299d6..6d79d972 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -278,38 +278,38 @@ DoString(R_OUTSB);break; CASE_W(0x6f) /* OUTSW */ DoString(R_OUTSW);break; - CASE_B(0x70) /* JO */ - JumpSIb(TFLG_O);break; - CASE_B(0x71) /* JNO */ - JumpSIb(TFLG_NO);break; - CASE_B(0x72) /* JB */ - JumpSIb(TFLG_B);break; - CASE_B(0x73) /* JNB */ - JumpSIb(TFLG_NB);break; - CASE_B(0x74) /* JZ */ - JumpSIb(TFLG_Z);break; - CASE_B(0x75) /* JNZ */ - JumpSIb(TFLG_NZ);break; - CASE_B(0x76) /* JBE */ - JumpSIb(TFLG_BE);break; - CASE_B(0x77) /* JNBE */ - JumpSIb(TFLG_NBE);break; - CASE_B(0x78) /* JS */ - JumpSIb(TFLG_S);break; - CASE_B(0x79) /* JNS */ - JumpSIb(TFLG_NS);break; - CASE_B(0x7a) /* JP */ - JumpSIb(TFLG_P);break; - CASE_B(0x7b) /* JNP */ - JumpSIb(TFLG_NP);break; - CASE_B(0x7c) /* JL */ - JumpSIb(TFLG_L);break; - CASE_B(0x7d) /* JNL */ - JumpSIb(TFLG_NL);break; - CASE_B(0x7e) /* JLE */ - JumpSIb(TFLG_LE);break; - CASE_B(0x7f) /* JNLE */ - JumpSIb(TFLG_NLE);break; + CASE_W(0x70) /* JO */ + JumpCond16_b(TFLG_O);break; + CASE_W(0x71) /* JNO */ + JumpCond16_b(TFLG_NO);break; + CASE_W(0x72) /* JB */ + JumpCond16_b(TFLG_B);break; + CASE_W(0x73) /* JNB */ + JumpCond16_b(TFLG_NB);break; + CASE_W(0x74) /* JZ */ + JumpCond16_b(TFLG_Z);break; + CASE_W(0x75) /* JNZ */ + JumpCond16_b(TFLG_NZ);break; + CASE_W(0x76) /* JBE */ + JumpCond16_b(TFLG_BE);break; + CASE_W(0x77) /* JNBE */ + JumpCond16_b(TFLG_NBE);break; + CASE_W(0x78) /* JS */ + JumpCond16_b(TFLG_S);break; + CASE_W(0x79) /* JNS */ + JumpCond16_b(TFLG_NS);break; + CASE_W(0x7a) /* JP */ + JumpCond16_b(TFLG_P);break; + CASE_W(0x7b) /* JNP */ + JumpCond16_b(TFLG_NP);break; + CASE_W(0x7c) /* JL */ + JumpCond16_b(TFLG_L);break; + CASE_W(0x7d) /* JNL */ + JumpCond16_b(TFLG_NL);break; + CASE_W(0x7e) /* JLE */ + JumpCond16_b(TFLG_LE);break; + CASE_W(0x7f) /* JNLE */ + JumpCond16_b(TFLG_NLE);break; CASE_B(0x80) /* Grpl Eb,Ib */ CASE_B(0x82) /* Grpl Eb,Ib Mirror instruction*/ { diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index 24470736..2f81d039 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -37,9 +37,11 @@ static INLINE void ADDIPd(Bits add) { LOADIP; } - static INLINE void ADDIPFAST(Bits blah) { core.ip_lookup+=blah; +// SAVEIP; +// reg_eip=(reg_eip+blah); +// LOADIP; } #define EXCEPTION(blah) \ @@ -112,14 +114,22 @@ static INLINE Bit32u Pop_32() { #endif -#define JumpSIb(blah) \ +//TODO Could probably make all byte operands fast? +#define JumpCond16_b(blah) \ if (blah) { \ - ADDIPFAST(Fetchbs()); \ + ADDIPw(Fetchbs()); \ } else { \ ADDIPFAST(1); \ } -#define JumpSIw(blah) \ +#define JumpCond32_b(blah) \ + if (blah) { \ + ADDIPd(Fetchbs()); \ + } else { \ + ADDIPFAST(1); \ + } + +#define JumpCond16_w(blah) \ if (blah) { \ ADDIPw(Fetchws()); \ } else { \ @@ -127,7 +137,7 @@ static INLINE Bit32u Pop_32() { } -#define JumpSId(blah) \ +#define JumpCond32_d(blah) \ if (blah) { \ ADDIPd(Fetchds()); \ } else { \ From 7a33b04eabe67e9b391a489dcedfb0c2e9cf5f80 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 31 Jan 2004 12:13:43 +0000 Subject: [PATCH 1550/4131] Use the slower version of adding eip in some define Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1631 --- src/cpu/core_normal/support.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index 2f81d039..e9ce3c8e 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -38,10 +38,10 @@ static INLINE void ADDIPd(Bits add) { } static INLINE void ADDIPFAST(Bits blah) { - core.ip_lookup+=blah; -// SAVEIP; -// reg_eip=(reg_eip+blah); -// LOADIP; +// core.ip_lookup+=blah; + SAVEIP; + reg_eip=(reg_eip+blah); + LOADIP; } #define EXCEPTION(blah) \ From 1f0493d050303d65531b36b2c53039f1ca9222be Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 31 Jan 2004 20:01:01 +0000 Subject: [PATCH 1551/4131] Made goto accept spaces between : and label Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1632 --- src/shell/shell_batch.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index f5cf388d..4642a2b7 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -125,7 +125,8 @@ again: } while (c!='\n' && n); *cmd_write++=0; if (cmd[0]==':') { - if (strcasecmp(cmd+1,where)==0) return true; + char *nospace = trim(cmd+1); + if (strcasecmp(nospace,where)==0) return true; } if (!n) { delete this; From 8a0520845e5120726ae32f3f0774a6bc5eeb190d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 31 Jan 2004 22:38:27 +0000 Subject: [PATCH 1552/4131] Fixed advmame2x scaler to work with new line mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1633 --- include/render.h | 2 ++ src/gui/render.cpp | 49 ++++++++++++------------------ src/gui/render_scale2x.h | 64 ++++++++++++++++++++++++++++++++-------- 3 files changed, 73 insertions(+), 42 deletions(-) diff --git a/include/render.h b/include/render.h index 49369c22..dd1adfc7 100644 --- a/include/render.h +++ b/include/render.h @@ -33,6 +33,8 @@ bool RENDER_StartUpdate(void); void RENDER_EndUpdate(void); void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue); extern RENDER_Line_Handler RENDER_DrawLine; +extern Bit8u * RENDER_TempLine; + #endif diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 871305de..7061bc0c 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.24 2004-01-30 13:40:49 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.25 2004-01-31 22:38:27 harekiet Exp $ */ #include #include @@ -81,12 +81,7 @@ static struct { PalData pal; struct { Bit8u hlines[RENDER_MAXHEIGHT]; - Bit16u hindex[RENDER_MAXHEIGHT]; } normal; - struct { - Bit16u hindex[RENDER_MAXHEIGHT]; - Bitu line_starts[RENDER_MAXHEIGHT][3]; - } advmame2x; #if (C_SSHOT) struct { RENDER_Operation type; @@ -101,7 +96,9 @@ static struct { bool updating; } render; +Bit8u render_line_cache[4][RENDER_MAXWIDTH*4]; //Bit32u pixels RENDER_Line_Handler RENDER_DrawLine; +Bit8u * RENDER_TempLine; /* Forward declerations */ static void RENDER_ResetPal(void); @@ -279,10 +276,12 @@ bool RENDER_StartUpdate(void) { render.frameskip.count=0; if (render.src.bpp==8) Check_Palette(); render.op.line=0; + RENDER_TempLine=render_line_cache[0]; switch (render.op.type) { case OP_None: case OP_Normal2x: case OP_AdvMame2x: + am2x.cmd_index=am2x.cmd_data; if (!GFX_StartUpdate(render.op.pixels,render.op.pitch)) return false; RENDER_DrawLine=render.op.line_handler;; break; @@ -338,16 +337,6 @@ void RENDER_EndUpdate(void) { render.updating=false; } -static void SetAdvMameTable(Bitu index,Bits src0,Bits src1,Bits src2) { - if (src0<0) src0=0; - if ((Bitu)src0>=render.src.height) src0=render.src.height-1; - if ((Bitu)src1>=render.src.height) src1=render.src.height-1; - if ((Bitu)src2>=render.src.height) src2=render.src.height-1; - render.advmame2x.line_starts[index][0]=src0*render.src.pitch; - render.advmame2x.line_starts[index][1]=src1*render.src.pitch; - render.advmame2x.line_starts[index][2]=src2*render.src.pitch; -} - void RENDER_ReInit(void) { if (render.updating) RENDER_EndUpdate(); Bitu width=render.src.width; @@ -382,7 +371,6 @@ normalop: gfx_scaleh*=scaleh; render.op.line_handler=Normal_8[index]; for (Bitu i=0;i0) ? temp_lines-1 : 0; height+=temp_lines; } } @@ -424,29 +411,31 @@ normalop: double src_add=(double)height/(double)render.src.height; double src_index=0; double src_lines=0; + Bitu src_done=0; Bitu height=0; + am2x.cmd_index=am2x.cmd_data; + am2x.buf_pos=0;am2x.buf_used=0; for (i=0;i<=(Bits)render.src.height;i++) { - render.advmame2x.hindex[i]=(Bitu)src_index; + src_lines+=src_add; Bitu lines=(Bitu)src_lines; src_lines-=lines; - src_index+=src_add; - src_lines+=src_add; switch (lines) { case 0: break; case 1: - SetAdvMameTable(height++,i,i,i); + AdvMame2x_AddLine(i,i,i); break; case 2: - SetAdvMameTable(height++,i-1,i,i+1); - SetAdvMameTable(height++,i+1,i,i-1); + AdvMame2x_AddLine(i-1,i,i+1); + AdvMame2x_AddLine(i+1,i,i-1); break; default: - SetAdvMameTable(height++,i-1,i,i+1); - for (lines-=2;lines>0;lines--) SetAdvMameTable(height++,i,i,i); - SetAdvMameTable(height++,i+1,i,i-1); + AdvMame2x_AddLine(i-1,i,i+1); + for (lines-=2;lines>0;lines--) AdvMame2x_AddLine(i,i,i); + AdvMame2x_AddLine(i+1,i,i-1); break; } + AdvMame2x_CheckLines(i); } render.op.line_handler=AdvMame2x_8_Table[index]; } diff --git a/src/gui/render_scale2x.h b/src/gui/render_scale2x.h index fc92a0ae..00705f41 100644 --- a/src/gui/render_scale2x.h +++ b/src/gui/render_scale2x.h @@ -36,6 +36,48 @@ #ifndef __SCALE2X_H #define __SCALE2X_H +#define AM2XBUF 16 + +static struct { + Bits buf[AM2XBUF][4]; + Bitu buf_used;Bitu buf_pos; + Bit8u cmd_data[4096]; //1024 lines should be enough? + Bit8u * cmd_index; + Bit8u * cache[4]; + Bitu cache_index; +} am2x; + + +static void AdvMame2x_AddLine(Bits s0,Bits s1,Bits s2) { + if (s0<0) s0=0; + if (s1<0) s1=0; + if (s2<0) s2=0; + if (s0>=(Bits)render.src.height) s0=render.src.height-1; + if (s1>=(Bits)render.src.height) s1=render.src.height-1; + if (s2>=(Bits)render.src.height) s2=render.src.height-1; + Bitu pos=(am2x.buf_used+am2x.buf_pos)&(AM2XBUF-1); + am2x.buf[pos][0]=s0; + am2x.buf[pos][1]=s1; + am2x.buf[pos][2]=s2; + s0=s0 > s1 ? s0 : s1; + s0=s0 > s2 ? s0 : s2; + am2x.buf[pos][3]=s0; + am2x.buf_used++; +} + +static void AdvMame2x_CheckLines(Bits last) { + Bitu lines=0;Bit8u * line_count=am2x.cmd_index++; + while (am2x.buf_used) { + if (am2x.buf[am2x.buf_pos][3]>last) break; + *am2x.cmd_index++=am2x.buf[am2x.buf_pos][0]&3; + *am2x.cmd_index++=am2x.buf[am2x.buf_pos][1]&3; + *am2x.cmd_index++=am2x.buf[am2x.buf_pos][2]&3; + am2x.buf_used--;lines++; + am2x.buf_pos=(am2x.buf_pos+1)&(AM2XBUF-1); + } + *line_count=lines; +} + template static void AdvMame2x_line(Bit8u * dst, const Bit8u * src0, const Bit8u * src1, const Bit8u * src2, Bitu count) { AddDst(dst,ConvBPP(src1[0])); @@ -54,19 +96,17 @@ static void AdvMame2x_line(Bit8u * dst, const Bit8u * src0, const Bit8u * src1, template static void AdvMame2x(Bit8u * src) { -#if 0 - _dy=render.advmame2x.hindex[y+_dy]; - y=render.advmame2x.hindex[y]; - Bit8u * dest=render.op.pixels+render.op.pitch*y; - src-=render.advmame2x.line_starts[y][0]; - for (;y<_dy;y++) { - Bit8u * src0=src+render.advmame2x.line_starts[y][0]; - Bit8u * src1=src+render.advmame2x.line_starts[y][1]; - Bit8u * src2=src+render.advmame2x.line_starts[y][2]; - AdvMame2x_line(dest,src0,src1,src2,render.src.width); - dest+=render.op.pitch; + RENDER_TempLine=render_line_cache[render.op.line&3]; + am2x.cache[render.op.line&3]=src; + Bitu lines=*am2x.cmd_index++; + while (lines--) { + Bit8u * src0=am2x.cache[*am2x.cmd_index++]; + Bit8u * src1=am2x.cache[*am2x.cmd_index++]; + Bit8u * src2=am2x.cache[*am2x.cmd_index++]; + AdvMame2x_line(render.op.pixels,src0,src1,src2,render.src.width); + render.op.pixels+=render.op.pitch; } -#endif + render.op.line++; } From ae0a2db4d197c8b07fa5cb22e6abcb2950584911 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 31 Jan 2004 22:40:02 +0000 Subject: [PATCH 1553/4131] Use a temporary buffer provided by render functions Fix the cga aspect ration Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1634 --- src/hardware/vga_draw.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 03bd9ed6..050c99f2 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -26,40 +26,38 @@ #define VGA_PARTS 4 -static Bit8u VGA_DrawBuffer[2048]; - typedef Bit8u * (* VGA_Line_Handler)(Bitu vidstart,Bitu panning,Bitu line); static VGA_Line_Handler VGA_DrawLine; static Bit8u * VGA_HERC_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { Bit8u * reader=&vga.mem.linear[vidstart+(line * 8 * 1024)]; - Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0]; + Bit32u * draw=(Bit32u *)RENDER_TempLine; for (Bitu x=vga.draw.blocks;x>0;x--) { Bitu val=*reader++; *draw++=CGA_2_Table[val >> 4]; *draw++=CGA_2_Table[val & 0xf]; } - return VGA_DrawBuffer; + return RENDER_TempLine; } static Bit8u * VGA_CGA2_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { - line*=8*1024;Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0]; + line*=8*1024;Bit32u * draw=(Bit32u *)RENDER_TempLine; for (Bitu x=vga.draw.blocks;x>0;x--) { Bitu val=vga.mem.linear[vidstart+line];vidstart=(vidstart+1)&0x1fff; *draw++=CGA_2_Table[val >> 4]; *draw++=CGA_2_Table[val & 0xf]; } - return VGA_DrawBuffer; + return RENDER_TempLine; } static Bit8u * VGA_CGA4_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { - line*=8*1024;Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0]; + line*=8*1024;Bit32u * draw=(Bit32u *)RENDER_TempLine; for (Bitu x=0;x> 4] | convert16[val & 0xf] << 16; *draw++=full|=full<<8; } - return VGA_DrawBuffer; + return RENDER_TempLine; } static Bit8u * VGA_TANDY16_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { Bit8u * reader=&vga.mem.linear[(vga.tandy.disp_bank << 14) + vidstart + (line * 8 * 1024)]; - Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0]; + Bit32u * draw=(Bit32u *)RENDER_TempLine; for (Bitu x=0;x=0 && font_addrvga.draw.cursor.eline) goto skip_cursor; - draw=(Bit32u *)&VGA_DrawBuffer[font_addr*8]; + draw=(Bit32u *)&RENDER_TempLine[font_addr*8]; Bit32u att=TXT_FG_Table[vga.mem.linear[vga.config.cursor_start*2+1]&0xf]; *draw++=att;*draw++=att; } skip_cursor: - return VGA_DrawBuffer; + return RENDER_TempLine; } static void VGA_VerticalDisplayEnd(void) { @@ -295,6 +293,7 @@ void VGA_SetupDrawing(void) { break; case M_CGA4: case M_CGA16: //Let is use 320x200 res and double pixels myself + aspect_ratio/=2; //Hack for half the vtotal in cga mode scaleh=2;scalew=2; vga.draw.blocks=width; width<<=2; @@ -305,6 +304,7 @@ void VGA_SetupDrawing(void) { VGA_DrawLine=(vga.mode == M_CGA4) ? VGA_CGA4_Draw_Line : VGA_CGA16_Draw_Line; break; case M_CGA2: + aspect_ratio/=2; //Hack for half the vtotal in cga mode scaleh=2; vga.draw.address_line_total=2; vga.draw.blocks=width; From 2b1535319a76898dd38753ddbc6a52ee86d841e5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 31 Jan 2004 22:41:13 +0000 Subject: [PATCH 1554/4131] Don't use cga mode control register in tandy mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1635 --- src/hardware/vga_misc.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index ddbfbbba..8f1b98dc 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -65,12 +65,10 @@ static void write_p3d8(Bit32u port,Bit8u val) { case M_CGA2: case M_CGA4: case M_CGA16: - case M_TANDY16: goto m_cga; } break; case MCH_CGA: - case MCH_TANDY: VGA_SetBlinking((val & 0x20)); m_cga: if (val & 0x2) { From bd451f9df4ce887dc8a0dfcb80142dc5eaa5780a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 31 Jan 2004 22:42:49 +0000 Subject: [PATCH 1555/4131] Fix mouse cursor in monochrome text mode...... Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1636 --- src/ints/mouse.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 68a21e85..5f64534c 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.30 2004-01-11 18:49:59 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.31 2004-01-31 22:42:49 harekiet Exp $ */ #include #include "dosbox.h" @@ -283,7 +283,7 @@ void DrawCursor() { // Get Clipping ranges // In Textmode ? - if (CurMode->type==M_TEXT16) { + if (CurMode->type<=M_TEXT16) { DrawCursorText(); return; } @@ -526,7 +526,7 @@ static Bitu INT33_Handler(void) { break; case 0x02: /* Hide Mouse */ { - if (CurMode->type!=M_TEXT16) RestoreCursorBackground(); + if (CurMode->type>M_TEXT16) RestoreCursorBackground(); else RestoreCursorBackgroundText(); mouse.shown--; } From 79dfccf1200ff9888a6d458fbbf963ebc7d0e01f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 2 Feb 2004 09:25:50 +0000 Subject: [PATCH 1556/4131] Add some new tandy registers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1637 --- include/vga.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/vga.h b/include/vga.h index f55b3ff3..b2186477 100644 --- a/include/vga.h +++ b/include/vga.h @@ -170,7 +170,10 @@ typedef struct { Bit8u mem_bank; Bit8u disp_bank; Bit8u reg_index; - bool set_reg; + Bit8u mode_control1; + Bit8u palette_mask; + Bit8u border_color; + Bit8u mode_control2; } VGA_TANDY; typedef struct { From 3c2770a8f065a527798f70ad1bc7c58170d2d8d5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 2 Feb 2004 09:26:13 +0000 Subject: [PATCH 1557/4131] Add tandy palette changing registers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1638 --- src/hardware/vga_misc.cpp | 47 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 8f1b98dc..650d56ad 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -33,7 +33,6 @@ static void write_p3d9(Bit32u port,Bit8u val); static Bit8u read_p3da(Bit32u port) { vga.internal.attrindex=false; - vga.tandy.set_reg=true; if (vga.config.retrace) { switch (vga.mode) { case M_HERC: @@ -55,7 +54,6 @@ static Bit8u read_p3da(Bit32u port) { */ } - static void write_p3d8(Bit32u port,Bit8u val) { /* Check if someone changes the blinking/hi intensity bit */ switch (machine) { @@ -131,6 +129,47 @@ static void write_p3d9(Bit32u port,Bit8u val) { } } +static void write_p3da(Bit32u port,Bit8u val) { + if (machine==MCH_TANDY) goto tandy_3da; + switch (vga.mode) { + case M_TANDY16: +tandy_3da: + vga.tandy.reg_index=val; + break; + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to %X in mode %d",val,port,vga.mode); + break; + + } +} + + +static void write_p3de(Bit32u port,Bit8u val) { + if (machine==MCH_TANDY) goto tandy_3de; + switch (vga.mode) { + case M_TANDY16: +tandy_3de: + switch (vga.tandy.reg_index) { + case 0x2: /* Border color */ + vga.tandy.border_color=val; + break; + /* palette colors */ + case 0x10: case 0x11: case 0x12: case 0x13: + case 0x14: case 0x15: case 0x16: case 0x17: + case 0x18: case 0x19: case 0x1a: case 0x1b: + case 0x1c: case 0x1d: case 0x1e: case 0x1f: + VGA_ATTR_SetPalette(vga.tandy.reg_index-0x10,val & 0xf); + break; + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index); + } + break; + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to %X in mode %d",val,port,vga.mode); + break; + } +} + static void write_p3df(Bit32u port,Bit8u val) { if (machine==MCH_TANDY) goto tandy_3df; switch (vga.mode) { @@ -273,7 +312,9 @@ void VGA_SetupMisc(void) { IO_RegisterWriteHandler(0x3b8,write_hercules,"Hercules"); IO_RegisterWriteHandler(0x3bf,write_hercules,"Hercules"); } - IO_RegisterWriteHandler(0x3df,write_p3df,"PCJR Setting"); + IO_RegisterWriteHandler(0x3de,write_p3de,"PCJR Reg Write"); + IO_RegisterWriteHandler(0x3df,write_p3df,"PCJR Bank Select"); + IO_RegisterWriteHandler(0x3da,write_p3da,"PCJR Reg Select"); } From f449c47830ca878ab7e3cc8193608a08f0845400 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 2 Feb 2004 09:27:34 +0000 Subject: [PATCH 1558/4131] Let CGA Modes use vga timings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1639 --- src/hardware/vga_draw.cpp | 7 +++--- src/ints/int10_modes.cpp | 45 ++++++++++++++++++--------------------- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 050c99f2..103b8212 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -293,10 +293,10 @@ void VGA_SetupDrawing(void) { break; case M_CGA4: case M_CGA16: //Let is use 320x200 res and double pixels myself - aspect_ratio/=2; //Hack for half the vtotal in cga mode scaleh=2;scalew=2; vga.draw.blocks=width; width<<=2; + height/=2; pitch=width; vga.draw.lines_scaled=1; vga.draw.address_line_total=2; @@ -304,8 +304,7 @@ void VGA_SetupDrawing(void) { VGA_DrawLine=(vga.mode == M_CGA4) ? VGA_CGA4_Draw_Line : VGA_CGA16_Draw_Line; break; case M_CGA2: - aspect_ratio/=2; //Hack for half the vtotal in cga mode - scaleh=2; + scaleh=2;height/=2; vga.draw.address_line_total=2; vga.draw.blocks=width; width<<=3; @@ -332,7 +331,7 @@ void VGA_SetupDrawing(void) { vga.draw.address_add=160; vga.draw.address_line_total=4; vga.draw.lines_scaled=1; - width<<=2; + width<<=2;height/=2; pitch=width; VGA_DrawLine=VGA_TANDY16_Draw_Line; break; diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index b5d10cab..b8ba1dd8 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -6,10 +6,8 @@ #include "int10.h" #include "mouse.h" -#define _HALF_CLOCK 0x0001 -#define _LINE_DOUBLE 0x0002 -#define _VGA_LINE_DOUBLE 0x0004 -#define _VGA_PIXEL_DOUBLE 0x0008 +#define _EGA_HALF_CLOCK 0x0001 +#define _EGA_LINE_DOUBLE 0x0002 #define SEQ_REGS 0x05 #define GFX_REGS 0x09 @@ -17,34 +15,34 @@ VideoModeBlock ModeList[]={ /* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde ,rate,special flags */ -{ 0x000 ,M_TEXT16 ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,70 ,_HALF_CLOCK }, -{ 0x001 ,M_TEXT16 ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,70 ,_HALF_CLOCK }, +{ 0x000 ,M_TEXT16 ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,70 ,_EGA_HALF_CLOCK }, +{ 0x001 ,M_TEXT16 ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,70 ,_EGA_HALF_CLOCK }, { 0x002 ,M_TEXT16 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,70 ,0 }, { 0x003 ,M_TEXT16 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,70 ,0 }, -{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,224 ,80 ,200 ,60 ,0 }, -{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,224 ,80 ,200 ,60 ,0}, -{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,224 ,80 ,200 ,60 ,0 }, +{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,60 ,0 }, +{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,60 ,0}, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,60 ,0 }, { 0x007 ,M_TEXT2 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,70 ,0 }, /* 8,9,0xa are tandy modes */ -{ 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,50 ,224 ,80 ,200 ,60 ,0}, +{ 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,50 ,449 ,40 ,400 ,60 ,0}, -{ 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,70 ,_HALF_CLOCK |_LINE_DOUBLE }, -{ 0x00E ,M_EGA16 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,70 ,_LINE_DOUBLE }, +{ 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,70 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, +{ 0x00E ,M_EGA16 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,70 ,_EGA_LINE_DOUBLE }, { 0x00F ,M_EGA2 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,400 ,70 ,0 }, { 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,1 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,70 ,0 }, { 0x011 ,M_EGA2 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,449 ,80 ,480 ,70 ,0 }, { 0x012 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,70 ,0 }, -{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,70 ,_VGA_PIXEL_DOUBLE | _VGA_LINE_DOUBLE }, +{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,70 ,0 }, { 0x100 ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,70 ,0 }, { 0x101 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,70 ,0 }, { 0x103 ,M_LIN8 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,70 ,0 }, -{ 0x150 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,70 , _VGA_PIXEL_DOUBLE | _VGA_LINE_DOUBLE }, -{ 0x151 ,M_LIN8 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,70 , _VGA_PIXEL_DOUBLE | _VGA_LINE_DOUBLE }, -{ 0x152 ,M_LIN8 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,70 , _VGA_PIXEL_DOUBLE }, -{ 0x153 ,M_LIN8 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,70 , _VGA_PIXEL_DOUBLE }, +{ 0x150 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,70 , 0}, +{ 0x151 ,M_LIN8 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,70 , 0}, +{ 0x152 ,M_LIN8 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,70 , 0 }, +{ 0x153 ,M_LIN8 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,70 , 0 }, {0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 ,0 }, @@ -177,7 +175,7 @@ foundmode: memset(seq_data,0,SEQ_REGS); seq_data[1]|=1; //8 dot fonts by default seq_data[1]|= //Check for half clock - (CurMode->special & _HALF_CLOCK) ? 0x08 : 0x00; + (CurMode->special & _EGA_HALF_CLOCK) ? 0x08 : 0x00; seq_data[4]|=0x02; //More than 64kb switch (CurMode->type) { case M_TEXT2: @@ -219,7 +217,7 @@ foundmode: hor_overflow|=((CurMode->hdispend) & 0x100) >> 6; /* End horizontal Blanking */ Bitu blank_end; - if (CurMode->special & _HALF_CLOCK) { + if (CurMode->special & _EGA_HALF_CLOCK) { blank_end = (CurMode->htotal-1) & 0x7f; } else { blank_end = (CurMode->htotal-2) & 0x7f; @@ -229,7 +227,7 @@ foundmode: /* Start Horizontal Retrace */ Bitu ret_start; - if (CurMode->special & _HALF_CLOCK) { + if (CurMode->special & _EGA_HALF_CLOCK) { ret_start = (CurMode->hdispend+2); } else { ret_start = (CurMode->hdispend+4); @@ -238,7 +236,7 @@ foundmode: hor_overflow|=(ret_start & 0x100) >> 4; /* End Horizontal Retrace */ Bitu ret_end; - if (CurMode->special & _HALF_CLOCK) { + if (CurMode->special & _EGA_HALF_CLOCK) { ret_end = (CurMode->htotal-2) & 0x3f; } else { ret_end = (CurMode->htotal-4) & 0x3f; @@ -286,7 +284,7 @@ foundmode: ver_overflow|=(line_compare & 0x400) >> 4; Bit8u underline=0; /* Maximum scanline / Underline Location */ - if (CurMode->special & _LINE_DOUBLE) max_scanline|=0x80; + if (CurMode->special & _EGA_LINE_DOUBLE) max_scanline|=0x80; switch (CurMode->type) { case M_TEXT2: case M_TEXT16: @@ -295,12 +293,11 @@ foundmode: break; case M_VGA: underline=0x40; - if (CurMode->special & _VGA_LINE_DOUBLE) max_scanline|=1; max_scanline|=1; //Vga doesn't use double line but this break; case M_LIN8: underline=0x60; //Seems to enable the every 4th clock on my s3 - if (CurMode->special & _VGA_LINE_DOUBLE) max_scanline|=1; +// if (CurMode->special & _VGA_LINE_DOUBLE) max_scanline|=1; break; } IO_Write(crtc_base,0x09);IO_Write(crtc_base+1,max_scanline); From ba726f38b09d0ec7b13c538ee2e0be8515b02c59 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 2 Feb 2004 11:38:44 +0000 Subject: [PATCH 1559/4131] undocumented feature in fileattributes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1640 --- src/dos/dos.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 4e70e7a4..128e41df 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.64 2004-01-19 17:51:04 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.65 2004-02-02 11:38:44 qbix79 Exp $ */ #include #include @@ -519,6 +519,7 @@ static Bitu DOS_21Handler(void) { case 0x00: /* Get */ { if (DOS_GetFileAttr(name1,®_cx)) { + reg_ax=reg_cx; /* Undocumented */ CALLBACK_SCF(false); } else { CALLBACK_SCF(true); From e3ec474dfb82d866b0274e3698de8313a2a8c53d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 2 Feb 2004 15:13:17 +0000 Subject: [PATCH 1560/4131] Some more changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1641 --- ChangeLog | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9511bef9..7554a2fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,14 @@ 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) @@ -14,7 +24,7 @@ - Enabled internal modem - Made the DOS parsing routines a bit more flexible - Added Subst (Srecko) - - Added ioctl support for linux (prompt) + - 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) From 78577673d9b54240db953ae1f8de961a3d4911d4 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 2 Feb 2004 15:42:38 +0000 Subject: [PATCH 1561/4131] Added a -machine command line option and changed the config help a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1642 --- src/dosbox.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 593e4788..a9284d82 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.60 2004-01-13 19:02:58 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.61 2004-02-02 15:42:38 harekiet Exp $ */ #include #include @@ -166,8 +166,10 @@ static void DOSBOX_RealInit(Section * sec) { DOSBOX_SetLoop(&Normal_Loop); MSG_Init(section); - machine=MCH_AUTO; - const char * mtype=section->Get_string("machine"); + machine=MCH_AUTO;std::string cmd_machine; + const char * mtype; + if (control->cmdline->FindString("-machine",cmd_machine,true)) mtype=cmd_machine.c_str(); + else mtype=section->Get_string("machine"); if (strcasecmp(mtype,"cga")==0) machine=MCH_CGA; else if (strcasecmp(mtype,"tandy")==0) machine=MCH_TANDY; else if (strcasecmp(mtype,"hercules")==0) machine=MCH_HERC; @@ -205,8 +207,8 @@ void DOSBOX_Init(void) { MSG_Add("DOSBOX_CONFIGFILE_HELP", "language -- Select another language file.\n" "memsize -- Amount of memory dosbox has in megabytes.\n" - "machine -- The type of machine tries to emulate.\n" - " You can select from auto,hercules,tandy,vga.\n" + "machine -- The type of machine tries to emulate:auto,hercules,cga,tandy,vga.\n" + " Try a specific type if your game has problems with auto.\n" ); secprop=control->AddSection_prop("render",&RENDER_Init); From c4f0db2384c9a17bf5236dbafbf6bd70be34c8a8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 2 Feb 2004 18:18:46 +0000 Subject: [PATCH 1562/4131] A bit more information about the config.com and config files Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1643 --- README | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README b/README index 6937dd94..661cd0e0 100644 --- a/README +++ b/README @@ -315,10 +315,13 @@ http://dosbox.sourceforge.net The Config File: ================ -A config file can be generated by CONFIG.COM. Edit it to customize DOSBox. +A config file can be generated by CONFIG.COM, which can be found on the +internal dosbox Z: drive when you start up dosbox. Look in the internal +programs section of the readme for usage of CONFIG.COM. +You can edit the generated configfile to customize DOSBox. The file is divided into several sections (the names have [] around it). Some sections have options which you can set. -# and % indicate commentlines. +# and % indicate comment-lines. The generated configfile contains the current settings. You can alter them and start DOSBox with the -conf switch to load the file and use these settings. From 87e2d68e244ca6ee1818d9fd06df8dceabf58889 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 2 Feb 2004 19:20:38 +0000 Subject: [PATCH 1563/4131] empty filenames return file not found Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1644 --- src/dos/dos_files.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 41a03518..a85decb5 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.51 2004-01-10 14:03:34 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.52 2004-02-02 19:20:38 qbix79 Exp $ */ #include #include @@ -53,6 +53,11 @@ void DOS_SetDefaultDrive(Bit8u drive) { } bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { + if(strlen(name) == 0) { + DOS_SetError(DOSERR_FILE_NOT_FOUND); + return false; + } + char tempdir[DOS_PATHLENGTH]; char upname[DOS_PATHLENGTH]; Bitu r,w; From 1b371a6a00f726fb3c940d92a46ee6b80dff4e1d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 2 Feb 2004 19:22:23 +0000 Subject: [PATCH 1564/4131] Cross_filename does something on Win32 too :) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1645 --- include/cross.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/cross.h b/include/cross.h index 135ab1dd..c2e830b5 100644 --- a/include/cross.h +++ b/include/cross.h @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: cross.h,v 1.7 2004-02-02 19:22:23 qbix79 Exp $ */ + #ifndef _CROSS_H #define _CROSS_H @@ -37,7 +39,7 @@ #if defined (WIN32) /* Win 32 */ -#define CROSS_FILENAME(blah) +#define CROSS_FILENAME(blah) {if(blah && *blah && (blah[strlen(blah)-1] == '\\')) strcat(blah,".");} #define CROSS_FILESPLIT '\\' #define F_OK 0 #else From 79ff8b1c8f146e267651371cb6a09cb536287bc9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 2 Feb 2004 20:23:54 +0000 Subject: [PATCH 1565/4131] added very basic vdma handler(Srecko) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1646 --- src/ints/ems.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 92bd456e..65cdd3a5 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: ems.cpp,v 1.31 2004-02-02 20:23:54 qbix79 Exp $ */ #include #include @@ -92,7 +93,7 @@ struct EMM_Handle { static EMM_Handle emm_handles[EMM_MAX_HANDLES]; static EMM_Mapping emm_mappings[EMM_MAX_PHYS]; -static Bitu call_int67; +static Bitu call_int67,call_vdma; struct MoveRegion { Bit32u bytes; @@ -582,8 +583,25 @@ static Bitu INT67_Handler(void) { return CBRET_NONE; } +static Bitu INT4B_Handler() { + switch (reg_ah) { + case 0x81: + CALLBACK_SCF(true); + reg_ax=0x1; + break; + default: + LOG(LOG_MISC,LOG_WARN)("Unhandled interrupt 4B function %x",reg_ah); + break; + } + return CBRET_NONE; +} void EMS_Init(Section* sec) { + /* Virtual DMA interrupt callback */ + call_vdma=CALLBACK_Allocate(); + CALLBACK_Setup(call_vdma,&INT4B_Handler,CB_IRET); + RealSetVec(0x4b,CALLBACK_RealPointer(call_vdma)); + Section_prop * section=static_cast(sec); if (!section->Get_bool("ems")) return; BIOS_ZeroExtendedSize(); From 331151e204b45bd3e2a3d5dc0fffabbdf881c7ae Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 2 Feb 2004 21:03:32 +0000 Subject: [PATCH 1566/4131] ChangeLog updated a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1647 --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7554a2fe..a01db8e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -33,6 +33,8 @@ - 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 From a16e5d7cabe4c6fa399efa451b2a30a1c6f4327e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 3 Feb 2004 08:24:42 +0000 Subject: [PATCH 1567/4131] README and Thanks now thank for some services provided by others Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1648 --- README | 21 +++++++++++++++++---- THANKS | 3 +++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/README b/README index 661cd0e0..fedaf568 100644 --- a/README +++ b/README @@ -5,8 +5,8 @@ NOTE: ===== While we hope that, one day, DOSBox will run virtually all programs -ever made for the PC...we are not there yet. At present, DOSBox run on a 1.7 -Gigahertz PC is roughly the equivalent of a 25MHz 386 PC. While the 0.60 +ever made for the PC...we are not there yet. At present, DOSBox run on a high- +end machine will roughly be the equivalent of a lowend 486 PC. While the 0.60 release has added support for "protected mode" allowing for more complex and recent programs, but note that this support is early in development and nowhere near as complete as the support for 386 real-mode games (or @@ -19,7 +19,7 @@ Usage: ====== dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] - [-lang languagefile] + [-lang languagefile] [-machine machinetype] [-noconsole] name If "name" is a directory it'll mount that as the C: drive. @@ -45,6 +45,11 @@ dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] -noconsole (Windows Only) Start dosbox without showing the console window, output will be redirected to stdout.txt and stderr.txt + + -machine machinetype + Setup dosbox to emulate a specific type of machine. Valid choices are: + auto,hercules,cga,tandy,vga. + Note: If a name/command/configfile/languagefile contains a space in it, put the whole name/command/configfile/languagefile between quotes("example"). @@ -323,7 +328,13 @@ The file is divided into several sections (the names have [] around it). Some sections have options which you can set. # and % indicate comment-lines. The generated configfile contains the current settings. You can alter them and -start DOSBox with the -conf switch to load the file and use these settings. +start DOSBox with the -conf switch to load the file and use these settings. + +DOSBox will if no configfile is specified with the -conf switch look in the +current directory for dosbox.conf. Then it will look for ~/.dosboxrc (linux), +~\dosbox.conf (win32) or "~/Library/Preferences/DOSBox Preferences" (MACOSX). + + ================== The Language File: @@ -351,6 +362,8 @@ Vlad R. of the vdmsound project for excellent sound blaster info. Tatsuyuki Satoh of the Mame Team for making an excellent FM emulator. The Bochs and DOSemu projects which I used for information. Freedos for ideas in making my shell. +Pierre-Yves Gérardy for hosting the old Beta Board. +Colin Snover for hosting our forum. The Beta Testers. ======== diff --git a/THANKS b/THANKS index 9a46546f..7bb1097c 100644 --- a/THANKS +++ b/THANKS @@ -8,5 +8,8 @@ Jarek Burczynski for the new OPL emulator. The Bochs and DOSemu projects which I used for information. Freedos for ideas in making my shell. +Pierre-Yves Gérardy for hosting the old Beta Board. +Colin Snover for hosting our forum. + All the people who submitted a bug. The Beta Testers. From 68f39d8e916533e0a51f2063c8491fc50b826e30 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 3 Feb 2004 08:35:29 +0000 Subject: [PATCH 1568/4131] Some more hints Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1649 --- src/shell/shell.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 667255ce..2688a1d2 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.38 2004-01-10 14:03:35 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.39 2004-02-03 08:35:29 qbix79 Exp $ */ #include #include @@ -294,6 +294,7 @@ void SHELL_Init() { "This version runs some protected mode games!\n" "For supported shell commands type: HELP\n" "For a short introduction type: INTRO\n\n" + "If you want more speed, try ctrl-F8 and ctrl-F12.\n" "For more information read the README file in DOSBox directory.\n" "\nHAVE FUN!\nThe DOSBox Team\n\n" ); From 1504058b61dc78c6dbf8e9f3107469bd8c1a0939 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 3 Feb 2004 08:36:17 +0000 Subject: [PATCH 1569/4131] Fix horitzontal timings for tandy modes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1650 --- src/ints/int10_modes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index b8ba1dd8..0f17c4e0 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -24,7 +24,7 @@ VideoModeBlock ModeList[]={ { 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,60 ,0 }, { 0x007 ,M_TEXT2 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,70 ,0 }, /* 8,9,0xa are tandy modes */ -{ 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,50 ,449 ,40 ,400 ,60 ,0}, +{ 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,100 ,449 ,80 ,400 ,60 ,0}, { 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,70 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, { 0x00E ,M_EGA16 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,70 ,_EGA_LINE_DOUBLE }, From 3e18970196a756ff9eb70e2b093182a39d958cdb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 3 Feb 2004 08:54:33 +0000 Subject: [PATCH 1570/4131] Final Update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1651 --- NEWS | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/NEWS b/NEWS index 7e7c1e57..d3f4b516 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,41 @@ +0.61 + - Added a beta dynamic cpu for x86 hosts (very unstable) + - Added opengl and hardware overlay display output + - Rewrote the vga screen updates to go in lines + - Added paging and v86 support to cpu emulation + - Added a config option to simulate a certain type of machine + - Added hercules graphics emulation + - Made CGA/TANDY modes more compatible + - Updated textmode drawing routines to support blinking colors + - Fixed VESA set page function that was documented wrong + - Fixed some wrongly emulated cpu opcodes. + - improved exception handling + - debugger: fixes; logging of gdt,lgt,idt, new commands(Fizzban) + - fixed some mscdex issues (drive letter header error, added get directory entry) + - added/fixed some bios funcs + - added some rarely used xms functions (thanks c2woody!) + - implemented GUS emulation + - Added 16-bit DMA support (for GUS and eventually SB16) + - Fixed many small bugs in filehandling routines + - Many small FPU fixes (c2woody/Fizzban) + - Some keyboard improvements (pharlab games) + - Some Timer and cmos/rtc fixes (Mirek/Srecko/Others) + - Lot's of mouse fixes (Help from various people) + - Enabled internal modem + - Made the DOS parsing routines a bit more flexible + - Added Subst (Srecko) + - Added cdrom ioctl support for linux (prompt) + - Many internal DOS fixes: memory/files/datastructures. + - Got some help from c2woody in allowing more than 1 irq being served + - Disabled DPMI (not needed anymore. DOSBox handles almost every extender) + - Search configfile in $HOME directory if none present in current directory + - Added another way to switch to protected mode. (Thanks Morten Eriksen!) + - Fixed some odd badly documented behaviour with PSP/DTA + - Added some warnings on opening of readonly files in writemode(DOS default). + - Many shell enhanchements + - Fixed a win32 specific bug dealing with filenames starting with a "." + - Fixed some bugs with the directory structure: not found/can't save errors + 0.60 - rewrote memory system for future paging support - fixed several EMS and XMS bugs and rewrite for new memory system From 631eff19be7afe5106e3b62da867b3f5ce8c6c0c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 3 Feb 2004 10:35:15 +0000 Subject: [PATCH 1571/4131] Remove some logging messages Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1652 --- src/hardware/gus.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 9169abca..b5a1e513 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -31,6 +31,7 @@ #define GUS_BASE myGUS.portbase #define GUS_RATE myGUS.rate +#define LOG_GUS static MIXER_Channel * gus_chan; @@ -126,7 +127,7 @@ static void pushIRQ(Bit8u channum, bool WaveIRQ, bool RampIRQ) { } else { - LOG_MSG("GUS IRQ Fifo full!"); + LOG_GUS("GUS IRQ Fifo full!"); } } @@ -333,7 +334,7 @@ public: // Debug routine to show current channel position void ShowAddr(void) { - LOG_MSG("Chan %d Start %d End %d Current %d", channum, StartAddr>>9, EndAddr>>9, CurAddr>>9); + LOG_GUS("Chan %d Start %d End %d Current %d", channum, StartAddr>>9, EndAddr>>9, CurAddr>>9); } @@ -613,7 +614,7 @@ static Bit16u ExecuteReadRegister(void) { return (Bit16u)(temp << 8); default: - LOG_MSG("Read Register num 0x%x", myGUS.gRegSelect); + LOG_GUS("Read Register num 0x%x", myGUS.gRegSelect); return myGUS.gRegData; } } @@ -714,7 +715,7 @@ static void ExecuteGlobRegister(void) { simple = (1.0 / (float)GUS_RATE) / 0.000001; myGUS.mupersamp = (Bit32s)simple*1024; myGUS.muperchan = (Bit32s)((float)1.6 * (float)myGUS.activechan * 1024); - LOG_MSG("GUS set to %d channels", myGUS.activechan); + LOG_GUS("GUS set to %d channels", myGUS.activechan); for(i=0;iUpdateFreqCtrl(); } @@ -767,7 +768,7 @@ static void ExecuteGlobRegister(void) { GUSReset(); break; default: - LOG_MSG("Unimplemented global register %x -- %x", myGUS.gRegSelect, myGUS.gRegData); + LOG_GUS("Unimplemented global register %x -- %x", myGUS.gRegSelect, myGUS.gRegData); } return; } @@ -825,7 +826,7 @@ static Bit8u read_gus(Bit32u port) { return 0; } default: - LOG_MSG("Read GUS at port 0x%x", port); + LOG_GUS("Read GUS at port 0x%x", port); break; } @@ -853,14 +854,14 @@ static void write_gus(Bit32u port,Bit8u val) { Bit8u temp = val & 0x7; // Select GF1 irq if(myGUS.irq1 == irqtable[temp]) { } else { - LOG_MSG("Attempt to assign GUS to wrong IRQ - at %x set to %x", myGUS.irq1, irqtable[temp]); + LOG_GUS("Attempt to assign GUS to wrong IRQ - at %x set to %x", myGUS.irq1, irqtable[temp]); } } else { // DMA configuration Bit8u temp = val & 0x7; // Select playback IRQ if(myGUS.dma1 == dmatable[temp]) { } else { - LOG_MSG("Attempt to assign GUS to wrong DMA - at %x, assigned %x", myGUS.dma1, dmatable[temp]); + LOG_GUS("Attempt to assign GUS to wrong DMA - at %x, assigned %x", myGUS.dma1, dmatable[temp]); } } @@ -887,7 +888,7 @@ static void write_gus(Bit32u port,Bit8u val) { if(myGUS.gDramAddr < sizeof(GUSRam)) GUSRam[myGUS.gDramAddr] = val; break; default: - LOG_MSG("Write GUS at port 0x%x with %x", port, val); + LOG_GUS("Write GUS at port 0x%x with %x", port, val); break; } From 0ec99d746cfa9c089b514fc62d87a0e3360256ed Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 3 Feb 2004 14:55:22 +0000 Subject: [PATCH 1572/4131] Added patch [ 889714 ] Structure of the DIB (Fizzban) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1654 --- include/dos_inc.h | 4 ++-- src/dos/dos_classes.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 0100c2c3..860f84c5 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -349,8 +349,8 @@ public: #pragma pack(1) #endif struct sDIB { - Bit8u stuff1[22]; // -0x18 some stuff, hopefully never used.... - Bit16u firstMCB; // -0x2 first memory control block + Bit8u stuff1[20]; // -0x18 some stuff, hopefully never used.... + RealPt firstMCB; // -0x04 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 diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 9fd8e8af..9f1e25b9 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.33 2004-01-10 14:03:34 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.34 2004-02-03 14:54:36 finsterr Exp $ */ #include #include @@ -68,7 +68,7 @@ void DOS_InfoBlock::SetLocation(Bit16u segment) void DOS_InfoBlock::SetFirstMCB(Bit16u _firstmcb) { - sSave(sDIB,firstMCB,_firstmcb); + sSave(sDIB,firstMCB,RealMake(_firstmcb,0)); } void DOS_InfoBlock::SetfirstFileTable(RealPt _first_table){ From 00b7c5122e0b9f63c6b644e95a525c80883248bf Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 3 Feb 2004 14:57:12 +0000 Subject: [PATCH 1573/4131] Added patch [ 889704 ] Proper TPA setup (fizzban) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1655 --- src/dos/dos_memory.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index e2e3d9d3..0eef6c1f 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -180,11 +180,17 @@ bool DOS_FreeMemory(Bit16u segment) { void DOS_SetupMemory(void) { - DOS_MCB mcb((Bit16u)MEM_START); + // Create a dummy device MCB with PSPSeg=0x0008 + DOS_MCB mcb_devicedummy((Bit16u)MEM_START); + mcb_devicedummy.SetPSPSeg(0x0008); // Devices + mcb_devicedummy.SetSize(1); + mcb_devicedummy.SetType(0x4d); // More blocks will follow + + DOS_MCB mcb((Bit16u)MEM_START+2); mcb.SetPSPSeg(MCB_FREE); //Free - mcb.SetSize(0x9FFE - MEM_START); + mcb.SetSize(0x9FFE - MEM_START - 2); mcb.SetType(0x5a); //Last Block + dos.firstMCB=MEM_START; dos_infoblock.SetFirstMCB(MEM_START); } - From 3001a346b29974b80048aab90c55ad62531084b7 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Tue, 3 Feb 2004 14:59:58 +0000 Subject: [PATCH 1574/4131] made interface destructors virtual Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1656 --- src/dos/cdrom.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index 0159d86a..cdfe7ab8 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -52,7 +52,7 @@ class CDROM_Interface_SDL : public CDROM_Interface { public: CDROM_Interface_SDL (void); - ~CDROM_Interface_SDL (void); + virtual ~CDROM_Interface_SDL(void); bool SetDevice (char* path, int forceCD); bool GetUPC (unsigned char& attr, char* upc) { attr = 0; strcpy(upc,"UPC"); return true; }; @@ -104,7 +104,7 @@ class CDROM_Interface_Aspi : public CDROM_Interface { public: CDROM_Interface_Aspi (void); - ~CDROM_Interface_Aspi (void); + virtual ~CDROM_Interface_Aspi(void); bool SetDevice (char* path, int forceCD); @@ -151,7 +151,7 @@ class CDROM_Interface_Ioctl : public CDROM_Interface { public: CDROM_Interface_Ioctl (void); - ~CDROM_Interface_Ioctl (void); + virtual ~CDROM_Interface_Ioctl(void); bool SetDevice (char* path, int forceCD); From 44464a2a53892cec1d3f38996cc2474ef7e3c57c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 7 Feb 2004 18:37:16 +0000 Subject: [PATCH 1575/4131] Changed event and ticker handlers. Removed the micro timers. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1657 --- include/pic.h | 4 +- include/timer.h | 14 ++---- include/vga.h | 3 +- src/hardware/cmos.cpp | 2 +- src/hardware/keyboard.cpp | 4 +- src/hardware/mixer.cpp | 10 ++-- src/hardware/pic.cpp | 103 ++++++++++++-------------------------- src/hardware/sblaster.cpp | 4 +- src/hardware/timer.cpp | 4 +- 9 files changed, 51 insertions(+), 97 deletions(-) diff --git a/include/pic.h b/include/pic.h index 05566d77..35b0d7a8 100644 --- a/include/pic.h +++ b/include/pic.h @@ -26,7 +26,7 @@ extern Bits CPU_CycleLeft; extern Bits CPU_CycleMax; typedef void (PIC_EOIHandler) (void); -typedef void (* PIC_EventHandler)(void); +typedef void (* PIC_EventHandler)(Bitu val); #define PIC_MAXIRQ 15 @@ -59,7 +59,7 @@ void PIC_RegisterIRQ(Bitu irq,PIC_EOIHandler handler,char * name); void PIC_FreeIRQ(Bitu irq); bool PIC_RunQueue(void); -void PIC_AddEvent(PIC_EventHandler handler,Bitu delay); +void PIC_AddEvent(PIC_EventHandler handler,Bitu delay,Bitu val=0); void PIC_RemoveEvents(PIC_EventHandler handler); diff --git a/include/timer.h b/include/timer.h index aada3d51..22bcbfb0 100644 --- a/include/timer.h +++ b/include/timer.h @@ -25,19 +25,11 @@ #define GetTicks() SDL_GetTicks() -typedef void (*TIMER_TickHandler)(Bitu ticks); -typedef void (*TIMER_MicroHandler)(void); - -typedef void TIMER_Block; - +typedef void (*TIMER_TickHandler)(void); /* Register a function that gets called everytime if 1 or more ticks pass */ -TIMER_Block * TIMER_RegisterTickHandler(TIMER_TickHandler handler); -/* Register a function to be called every x microseconds */ -TIMER_Block * TIMER_RegisterMicroHandler(TIMER_MicroHandler handler,Bitu micro); - -/* Set the microseconds value to a new value */ -void TIMER_SetNewMicro(TIMER_Block * block,Bitu micro); +void TIMER_AddTickHandler(TIMER_TickHandler handler); +void TIMER_DelTickHandler(TIMER_TickHandler handler); /* This will add 1 milliscond to all timers */ void TIMER_AddTick(void); diff --git a/include/vga.h b/include/vga.h index b2186477..f836a610 100644 --- a/include/vga.h +++ b/include/vga.h @@ -94,7 +94,6 @@ typedef struct { bool drawing; Bitu width; Bitu height; - Bitu pitch; Bitu blocks; Bitu panning; Bitu address; @@ -296,7 +295,7 @@ typedef struct { void VGA_SetMode(VGAModes mode); void VGA_SetupHandlers(void); void VGA_StartResize(void); -void VGA_SetupDrawing(void); +void VGA_SetupDrawing(Bitu val); /* Some DAC/Attribute functions */ void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal); diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 47a63a30..58096871 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -43,7 +43,7 @@ static struct { bool update_ended; } cmos; -static void cmos_timerevent(void) { +static void cmos_timerevent(Bitu val) { PIC_ActivateIRQ(8); if(cmos.timer.enabled) PIC_AddEvent(cmos_timerevent,cmos.timer.micro); if (cmos.ack) { diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 0fcde792..cab7daf6 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.20 2004-01-29 20:13:29 qbix79 Exp $ */ +/* $Id: keyboard.cpp,v 1.21 2004-02-07 18:35:24 harekiet Exp $ */ #include #include "dosbox.h" @@ -86,7 +86,7 @@ void KEYBOARD_ClrBuffer(void) { } /* Read an entry from the keycode buffer */ -void KEYBOARD_GetCode(void) { +void KEYBOARD_GetCode(Bitu val) { keyb.scheduled=false; switch (keyb.buf.state) { case STATE_NORMAL: diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 2886da24..2c62ddc6 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -208,7 +208,7 @@ static void MIXER_MixData(Bit32u samples) { } } -static void MIXER_Mix(Bitu ticks) { +static void MIXER_Mix(void) { mixer.tick_remain+=mixer.tick_add; Bitu count=mixer.tick_remain>>MIXER_SHIFT; mixer.tick_remain&=((1<>MIXER_SHIFT; mixer.tick_remain&=((1< @@ -58,7 +58,7 @@ static IRQ_Block irqs[16]; static PIC_Controller pics[2]; struct PICEntry { - Bitu index; + Bitu index;Bitu value; PIC_EventHandler event; PICEntry * next; }; @@ -305,7 +305,7 @@ static void AddEntry(PICEntry * entry) { } } -void PIC_AddEvent(PIC_EventHandler handler,Bitu delay) { +void PIC_AddEvent(PIC_EventHandler handler,Bitu delay,Bitu val) { if (!pic.free_entry) { LOG(LOG_PIC,LOG_ERROR)("Event queue full"); return; @@ -314,6 +314,7 @@ void PIC_AddEvent(PIC_EventHandler handler,Bitu delay) { Bitu index=delay+PIC_Index(); entry->index=index; entry->event=handler; + entry->value=val; pic.free_entry=pic.free_entry->next; AddEntry(entry); } @@ -357,7 +358,7 @@ bool PIC_RunQueue(void) { while (pic.next_entry && pic.next_entry->index<=index) { PICEntry * entry=pic.next_entry; pic.next_entry=entry->next; - (entry->event)(); + (entry->event)(entry->value); /* Put the entry in the free list */ entry->next=pic.free_entry; pic.free_entry=entry; @@ -378,90 +379,52 @@ bool PIC_RunQueue(void) { } /* The TIMER Part */ - -enum { T_TICK,T_MICRO,T_DELAY}; - -struct Timer { - Bitu type; - union { - struct { - TIMER_TickHandler handler; - } tick; - struct{ - Bits left; - Bits total; - TIMER_MicroHandler handler; - } micro; - }; +struct TickerBlock { + TIMER_TickHandler handler; + TickerBlock * next; }; -static Timer * first_timer=0; -static std::list Timers; +static TickerBlock * firstticker=0; -TIMER_Block * TIMER_RegisterTickHandler(TIMER_TickHandler handler) { - Timer * new_timer=new(Timer); - new_timer->type=T_TICK; - new_timer->tick.handler=handler; - Timers.push_front(new_timer); - return (TIMER_Block *)new_timer; -} -TIMER_Block * TIMER_RegisterMicroHandler(TIMER_MicroHandler handler,Bitu micro) { - Timer * new_timer=new(Timer); - new_timer->type=T_MICRO; - new_timer->micro.handler=handler; - Timers.push_front(new_timer); - TIMER_SetNewMicro(new_timer,micro); - return (TIMER_Block *)new_timer; -} - -void TIMER_SetNewMicro(TIMER_Block * block,Bitu micro) { - Timer * timer=(Timer *)block; - if (timer->type!=T_MICRO) E_Exit("TIMER:Illegal handler type"); - timer->micro.total=micro; - Bitu index=PIC_Index(); - while ((1000-index)>micro) { - PIC_AddEvent(timer->micro.handler,micro); - micro+=micro; - index+=micro; +void TIMER_DelTickHandler(TIMER_TickHandler handler) { + TickerBlock * ticker=firstticker; + TickerBlock * * where=&firstticker; + while (ticker) { + if (ticker->handler==handler) { + *where=ticker->next; + return; + } + where=&ticker->next; + ticker=ticker->next; } - timer->micro.left=timer->micro.total-(1000-index); +} + +void TIMER_AddTickHandler(TIMER_TickHandler handler) { + TickerBlock * newticker=new TickerBlock; + newticker->next=firstticker; + newticker->handler=handler; + firstticker=newticker; } void TIMER_AddTick(void) { /* Setup new amount of cycles for PIC */ - CPU_CycleLeft=CPU_CycleMax; CPU_Cycles=0; PIC_Ticks++; - /* Go through the list of scheduled irq's and lower their index with 1000 */ + /* Go through the list of scheduled events and lower their index with 1000 */ PICEntry * entry=pic.next_entry; while (entry) { if (entry->index>1000) entry->index-=1000; else entry->index=0; entry=entry->next; } - Bits index; - /* Check if there are timer handlers that need to be called */ - std::list::iterator i; - for(i=Timers.begin(); i != Timers.end(); ++i) { - Timer * timers=(*i); - switch (timers->type) { - case T_TICK: - timers->tick.handler(1); - break; - case T_MICRO: - index=1000; - while (index>=timers->micro.left) { - PIC_AddEvent(timers->micro.handler,timers->micro.left); - index-=timers->micro.left; - timers->micro.left=timers->micro.total; - } - timers->micro.left-=index; - break; - default: - E_Exit("TIMER:Illegal handler type"); - } + /* Call our list of ticker handlers */ + TickerBlock * ticker=firstticker; + while (ticker) { + TickerBlock * nextticker=ticker->next; + ticker->handler(); + ticker=nextticker; } } diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 93430fe8..7a28c284 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -525,7 +525,7 @@ static void GenerateSound(Bitu size) { } } -static void END_DMA_Event(void) { +static void END_DMA_Event(Bitu val) { GenerateDMASound(sb.dma.left); } @@ -551,7 +551,7 @@ static void DSP_ChangeMode(DSP_MODES mode) { sb.mode=mode; } -static void DSP_RaiseIRQEvent(void) { +static void DSP_RaiseIRQEvent(Bitu val) { SB_RaiseIRQ(SB_IRQ_8); } diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 1e31770e..b60e8dd3 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.20 2004-01-10 11:43:41 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.21 2004-02-07 18:34:03 harekiet Exp $ */ #include "dosbox.h" #include "inout.h" @@ -43,7 +43,7 @@ struct PIT_Block { static PIT_Block pit[3]; -static void PIT0_Event(void) { +static void PIT0_Event(Bitu val) { PIC_ActivateIRQ(0); if (pit[0].mode!=0) PIC_AddEvent(PIT0_Event,pit[0].micro); } From ca4be6fe4371b37d9dede22d6e1349bf9d053bda Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 7 Feb 2004 18:48:51 +0000 Subject: [PATCH 1576/4131] Changed event and ticker handlers. Removed the micro timers. Removed the pitch calculation Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1658 --- src/hardware/vga_draw.cpp | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 103b8212..5643bfca 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -126,7 +126,7 @@ skip_cursor: return RENDER_TempLine; } -static void VGA_VerticalDisplayEnd(void) { +static void VGA_VerticalDisplayEnd(Bitu val) { vga.config.retrace=true; vga.config.real_start=vga.config.display_start; } @@ -172,7 +172,7 @@ void VGA_SetBlinking(Bitu enabled) { for (Bitu i=0;i<8;i++) TXT_BG_Table[i+8]=(b+i) | ((b+i) << 8)| ((b+i) <<16) | ((b+i) << 24); } -static void VGA_VerticalTimer(void) { +static void VGA_VerticalTimer(Bitu val) { vga.config.retrace=false; PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal); PIC_AddEvent(VGA_VerticalDisplayEnd,vga.draw.micro.vend); @@ -199,7 +199,7 @@ static void VGA_VerticalTimer(void) { } } -void VGA_SetupDrawing(void) { +void VGA_SetupDrawing(Bitu val) { /* Calculate the FPS for this screen */ double fps; Bitu vtotal=2 + vga.crtc.vertical_total | @@ -249,7 +249,7 @@ void VGA_SetupDrawing(void) { double aspect_ratio=((double)htotal/((double)vtotal)/correct_ratio); vga.draw.resizing=false; - Bitu width,height,pitch; + Bitu width,height; Bitu scalew=1; Bitu scaleh=1; @@ -265,7 +265,6 @@ void VGA_SetupDrawing(void) { vga.draw.lines_scaled=scaleh; height/=scaleh; width<<=2; - pitch=vga.config.scan_len*8; vga.draw.address_add=vga.config.scan_len*2; vga.draw.address_line_total=1; VGA_DrawLine=VGA_VGA_Draw_Line; @@ -273,7 +272,6 @@ void VGA_SetupDrawing(void) { case M_LIN8: width<<=3; scaleh*=vga.draw.font_height; - pitch=vga.config.scan_len*4; vga.draw.address_add=vga.config.scan_len*2; vga.draw.lines_scaled=scaleh; vga.draw.address_line_total=1; @@ -281,7 +279,6 @@ void VGA_SetupDrawing(void) { break; case M_EGA16: width<<=3; - pitch=vga.config.scan_len*16; scaleh*=vga.draw.font_height; if (vga.crtc.maximum_scan_line&0x80) scaleh*=2; vga.draw.lines_scaled=scaleh; @@ -297,7 +294,6 @@ void VGA_SetupDrawing(void) { vga.draw.blocks=width; width<<=2; height/=2; - pitch=width; vga.draw.lines_scaled=1; vga.draw.address_line_total=2; vga.draw.address_add=80; //CGA doesn't have an offset reg @@ -308,7 +304,6 @@ void VGA_SetupDrawing(void) { vga.draw.address_line_total=2; vga.draw.blocks=width; width<<=3; - pitch=width; vga.draw.address_line_total=2; vga.draw.address_add=80; //CGA doesn't have an offset reg vga.draw.lines_scaled=1; @@ -321,7 +316,6 @@ void VGA_SetupDrawing(void) { vga.draw.address_add=width/8; vga.draw.lines_scaled=1; height=348; - pitch=width; aspect_ratio=1.5; VGA_DrawLine=VGA_HERC_Draw_Line; break; @@ -332,7 +326,6 @@ void VGA_SetupDrawing(void) { vga.draw.address_line_total=4; vga.draw.lines_scaled=1; width<<=2;height/=2; - pitch=width; VGA_DrawLine=VGA_TANDY16_Draw_Line; break; case M_TEXT2: @@ -351,24 +344,22 @@ void VGA_SetupDrawing(void) { width<<=3; /* 8 bit wide text font */ if (width>640) width=640; if (height>480) height=480; - pitch=width; VGA_DrawLine=VGA_TEXT_Draw_Line; break; default: LOG(LOG_VGA,LOG_ERROR)("Unhandled VGA type %d while checking for resolution"); }; vga.draw.lines_total=height; - if (( width != vga.draw.width) || (height != vga.draw.height) || (pitch != vga.draw.pitch)) { + if (( width != vga.draw.width) || (height != vga.draw.height)) { PIC_RemoveEvents(VGA_VerticalTimer); PIC_RemoveEvents(VGA_VerticalDisplayEnd); vga.draw.width=width; vga.draw.height=height; - vga.draw.pitch=pitch; vga.draw.scaleh=scaleh; LOG(LOG_VGA,LOG_NORMAL)("Width %d, Height %d, fps %f",width,height,fps); LOG(LOG_VGA,LOG_NORMAL)("Scalew %d, Scaleh %d aspect %f",scalew,scaleh,aspect_ratio); - RENDER_SetSize(width,height,8,pitch,aspect_ratio,scalew,scaleh); + RENDER_SetSize(width,height,8,aspect_ratio,scalew,scaleh); PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal); } }; From 6118a57ffc159f42487f716842b4ae860bebc041 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 7 Feb 2004 18:49:28 +0000 Subject: [PATCH 1577/4131] Changing scanline length doesn't start a screen resize Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1659 --- src/hardware/vga_crtc.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index e957f8ec..c8b8950f 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -219,12 +219,9 @@ void write_p3d5(Bit32u port,Bit8u val) { */ break; case 0x13: /* Offset register */ - if (val!=crtc(offset)) { - crtc(offset)=val; - vga.config.scan_len&=0x300; - vga.config.scan_len|=val; - VGA_StartResize(); - } + crtc(offset)=val; + vga.config.scan_len&=0x300; + vga.config.scan_len|=val; /* 0-7 Number of bytes in a scanline / K. Where K is 2 for byte mode, 4 for word mode and 8 for Double Word mode. From 26eca9f1dcc8beebbf068c7135a5fa7fc1810acd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 7 Feb 2004 18:50:27 +0000 Subject: [PATCH 1578/4131] No longer use pitch when setting size Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1660 --- include/render.h | 2 +- src/gui/render.cpp | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/include/render.h b/include/render.h index dd1adfc7..9782f6a8 100644 --- a/include/render.h +++ b/include/render.h @@ -28,7 +28,7 @@ enum RENDER_Operation { typedef void (* RENDER_Line_Handler)(Bit8u * src); -void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,double ratio,Bitu scalew,Bitu scaleh); +void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,Bitu scalew,Bitu scaleh); bool RENDER_StartUpdate(void); void RENDER_EndUpdate(void); void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue); diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 7061bc0c..2fcaab42 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.25 2004-01-31 22:38:27 harekiet Exp $ */ +/* $Id: render.cpp,v 1.26 2004-02-07 18:50:10 harekiet Exp $ */ #include #include @@ -56,7 +56,6 @@ static struct { Bitu width; Bitu height; Bitu bpp; - Bitu pitch; Bitu scalew; Bitu scaleh; double ratio; @@ -450,15 +449,14 @@ normalop: } -void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,double ratio,Bitu scalew,Bitu scaleh) { - if ((!width) || (!height) || (!pitch)) { +void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,Bitu scalew,Bitu scaleh) { + if (!width || !height) { render.active=false; return; } render.src.width=width; render.src.height=height; render.src.bpp=bpp; - render.src.pitch=pitch; render.src.ratio=render.aspect ? ratio : 1.0; render.src.scalew=scalew; render.src.scaleh=scaleh; From 297bcf0e7306f6f06c8d8da2ba8d911dd4bbaf51 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 7 Feb 2004 18:50:38 +0000 Subject: [PATCH 1579/4131] Changed event and ticker handlers. Removed the micro timers. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1661 --- src/hardware/softmodem.cpp | 47 ++++++++++++++----------------------- src/hardware/vga_memory.cpp | 2 +- 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp index 29ab9bff..39466c93 100644 --- a/src/hardware/softmodem.cpp +++ b/src/hardware/softmodem.cpp @@ -44,7 +44,6 @@ #define CONNECTED (M_CTS | M_DSR | M_DCD ) #define DISCONNECTED (M_CTS | M_DSR ) - /* DTMF tone generator */ float col[] = { 1209.0, 1336.0, 1477.0, 1633.0 }; float row[] = { 697.0, 770.0, 852.0, 941.0 }; @@ -299,11 +298,23 @@ static void DoCommand() { static void MC_Changed(Bitu new_mc) { - + LOG_MSG("DTR %d RTS %d",new_mc & 1,new_mc & 2); + if (!(new_mc & 1) && mhd.socket) { + sendStr("\nNO CARRIER\n"); + SDLNet_TCP_DelSocket(mhd.socketset,mhd.socket); + SDLNet_TCP_Close(mhd.socket); + mhd.socket=0; + mhd.commandmode = true; + } + mdm->setmodemstatus( + ((new_mc & 1 ) ? M_DSR : 0) | + ((new_mc & 2) ? M_CTS : 0) | + (mhd.socket ? M_DCD : 0) + ); } -static void MODEM_Hardware(Bitu ticks) { +static void MODEM_Hardware(void) { int result =0; unsigned long args = 1; bool sendbyte = true; @@ -345,6 +356,7 @@ static void MODEM_Hardware(Bitu ticks) { if(txval == '+') { mhd.plusinc++; if(mhd.plusinc>=3) { + LOG_MSG("Entering command mode"); mhd.commandmode = true; sendStr("\nOK\n"); mhd.plusinc = 0; @@ -369,7 +381,7 @@ static void MODEM_Hardware(Bitu ticks) { SDLNet_CheckSockets(mhd.socketset,0); /* Handle outgoing to the serial port */ if(!mhd.commandmode && mhd.socket && mdm->rx_free() && SDLNet_SocketReady(mhd.socket)) { - usesize = mdm->rx_free(); + usesize = mdm->rx_free(); result = SDLNet_TCP_Recv(mhd.socket, tmpbuf, usesize); if (result>0) { mdm->rx_adds(tmpbuf,result); @@ -427,31 +439,6 @@ static void MODEM_Hardware(Bitu ticks) { } -/* -03F8 -W serial port, transmitter holding register (THR), which contains the - character to be sent. Bit 0 is sent first. - bit 7-0 data bits when DLAB=0 (Divisor Latch Access Bit) -03F8 R- receiver buffer register (RBR), which contains the received - character. Bit 0 is received first - bit 7-0 data bits when DLAB=0 (Divisor Latch Access Bit) -03F8 RW divisor latch low byte (DLL) when DLAB=1 (see #P0876) -03F9 RW divisor latch high byte (DLM) when DLAB=1 (see #P0876) -03F9 RW interrupt enable register (IER) when DLAB=0 (see #P0877) -03FA R- interrupt identification register (see #P0878) - Information about a pending interrupt is stored here. When the ID - register is addressed, thehighest priority interrupt is held, and - no other interrupts are acknowledged until the CPU services that - interrupt. -03FA -W 16650 FIFO Control Register (FCR) (see #P0879) -03FB RW line control register (LCR) (see #P0880) -03FC RW modem control register (see #P0881) -03FD R- line status register (LSR) (see #P0882) -03FE R- modem status register (MSR) (see #P0883) -03FF RW scratch register (SCR) - (not used for serial I/O; available to any application using 16450, - 16550) (not present on original 8250) -*/ - static void MODEM_CallBack(Bit8u * stream,Bit32u len) { char *cp; float ci,ri; @@ -613,7 +600,7 @@ void MODEM_Init(Section* sec) { mdm->setmodemstatus(DISCONNECTED); mdm->SetMCHandler(&MC_Changed); - TIMER_RegisterTickHandler(&MODEM_Hardware); + TIMER_AddTickHandler(&MODEM_Hardware); /* Initialize the sockets and setup the listening port */ mhd.socketset = SDLNet_AllocSocketSet(1); diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 0842dd15..a0ade8be 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -336,7 +336,7 @@ range_b800: bool lfb_update; -static void VGA_DoUpdateLFB(void) { +static void VGA_DoUpdateLFB(Bitu val) { lfb_update=false; MEM_SetLFB(vga.s3.la_window << 4 ,sizeof(vga.mem.linear)/4096,&vga.mem.linear[0]); } From 3d938579ef0e904a566371785c4f7d782fdf3a2b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 7 Feb 2004 22:22:19 +0000 Subject: [PATCH 1580/4131] Add the 3rd cga palette Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1662 --- src/hardware/vga_misc.cpp | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 650d56ad..9ee6148f 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -106,14 +106,29 @@ static void write_p3d9(Bit32u port,Bit8u val) { { VGA_ATTR_SetPalette(0,(val & 0xf)); Bit8u pal_base=(val & 0x10) ? 0x08 : 0; - if (val & 0x020) { - VGA_ATTR_SetPalette(1,0x03+pal_base); - VGA_ATTR_SetPalette(2,0x05+pal_base); - VGA_ATTR_SetPalette(3,0x07+pal_base); + /* Check for BW Mode */ + if (vga.cga.mode_control & 0x4) { + if (val & 0x20) { + VGA_ATTR_SetPalette(1,0x03+pal_base); + VGA_ATTR_SetPalette(2,0x04+pal_base); + VGA_ATTR_SetPalette(3,0x07+pal_base); + } else { + //TODO Maybe? will anyone ever use, + //will also need to setup a BW palette,but could put it behind normal cga... + VGA_ATTR_SetPalette(1,0x02+pal_base); + VGA_ATTR_SetPalette(2,0x04+pal_base); + VGA_ATTR_SetPalette(3,0x06+pal_base); + } } else { - VGA_ATTR_SetPalette(1,0x02+pal_base); - VGA_ATTR_SetPalette(2,0x04+pal_base); - VGA_ATTR_SetPalette(3,0x06+pal_base); + if (val & 0x20) { + VGA_ATTR_SetPalette(1,0x03+pal_base); + VGA_ATTR_SetPalette(2,0x05+pal_base); + VGA_ATTR_SetPalette(3,0x07+pal_base); + } else { + VGA_ATTR_SetPalette(1,0x02+pal_base); + VGA_ATTR_SetPalette(2,0x04+pal_base); + VGA_ATTR_SetPalette(3,0x06+pal_base); + } } } break; From e6be5f493cfb750124f6717e064644c53d1154eb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 7 Feb 2004 22:23:07 +0000 Subject: [PATCH 1581/4131] Set the black/white bit for cga when setting mode 0x5 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1663 --- src/ints/int10_modes.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 0f17c4e0..a6807919 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -423,6 +423,8 @@ att_text16: real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x7); goto skipatt; case M_CGA4: + //Set Bit 2 in black/white mode 0x5 + IO_Write(0x3d8,0xa+(CurMode->mode==0x5) ? 0x4 : 0); IO_Write(0x3d9,0x30); //Setup using CGA color select register real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x30); goto skipatt; From 7ca20ac50fc73f77f6f937f7fc07b1b6b0c2dd32 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 7 Feb 2004 23:36:33 +0000 Subject: [PATCH 1582/4131] Only use 6 bit dac values Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1664 --- src/hardware/vga_dac.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index 4fcb0f82..1c8c1250 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -81,6 +81,7 @@ static void write_p3c8(Bit32u port,Bit8u val) { } static void write_p3c9(Bit32u port,Bit8u val) { + val&=0x3f; switch (vga.dac.pel_index) { case 0: vga.dac.rgb[vga.dac.write_index].red=val; From 84058c007beee11078ba32d32839759e44e714af Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 7 Feb 2004 23:40:46 +0000 Subject: [PATCH 1583/4131] New function to recalculate some values after a scanline length change Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1665 --- include/vga.h | 1 + src/hardware/vga_crtc.cpp | 5 +++-- src/hardware/vga_draw.cpp | 32 ++++++++++++++++++++++++-------- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/include/vga.h b/include/vga.h index f836a610..9046683a 100644 --- a/include/vga.h +++ b/include/vga.h @@ -296,6 +296,7 @@ void VGA_SetMode(VGAModes mode); void VGA_SetupHandlers(void); void VGA_StartResize(void); void VGA_SetupDrawing(Bitu val); +void VGA_CheckScanLength(void); /* Some DAC/Attribute functions */ void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal); diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index c8b8950f..23ca0959 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -222,6 +222,7 @@ void write_p3d5(Bit32u port,Bit8u val) { crtc(offset)=val; vga.config.scan_len&=0x300; vga.config.scan_len|=val; + VGA_CheckScanLength(); /* 0-7 Number of bytes in a scanline / K. Where K is 2 for byte mode, 4 for word mode and 8 for Double Word mode. @@ -330,7 +331,7 @@ void write_p3d5(Bit32u port,Bit8u val) { if (((val & 0x4) ^ (vga.config.scan_len >> 6)) & 0x4) { vga.config.scan_len&=0x2ff; vga.config.scan_len|=(val & 0x4) << 6; - VGA_StartResize(); + VGA_CheckScanLength(); } break; /* @@ -351,7 +352,7 @@ void write_p3d5(Bit32u port,Bit8u val) { if (((val & 0x30) ^ (vga.config.scan_len >> 4)) & 0x30) { vga.config.scan_len&=0xff; vga.config.scan_len|=(val & 0x30) << 4; - VGA_StartResize(); + VGA_CheckScanLength(); } break; /* diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 5643bfca..90c65a91 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -199,6 +199,29 @@ static void VGA_VerticalTimer(Bitu val) { } } +void VGA_CheckScanLength(void) { + switch (vga.mode) { + case M_EGA16: + case M_VGA: + case M_LIN8: + vga.draw.address_add=vga.config.scan_len*2; + break; + case M_CGA2:case M_CGA4:case M_CGA16: + vga.draw.address_add=80; + break; + case M_TANDY16: + vga.draw.address_add=160; + break; + case M_TEXT16: + case M_TEXT2: + vga.draw.address_add=vga.config.scan_len*4; + break; + case M_HERC: + vga.draw.address_add=vga.draw.blocks; + break; + } +} + void VGA_SetupDrawing(Bitu val) { /* Calculate the FPS for this screen */ double fps; @@ -265,14 +288,12 @@ void VGA_SetupDrawing(Bitu val) { vga.draw.lines_scaled=scaleh; height/=scaleh; width<<=2; - vga.draw.address_add=vga.config.scan_len*2; vga.draw.address_line_total=1; VGA_DrawLine=VGA_VGA_Draw_Line; break; case M_LIN8: width<<=3; scaleh*=vga.draw.font_height; - vga.draw.address_add=vga.config.scan_len*2; vga.draw.lines_scaled=scaleh; vga.draw.address_line_total=1; VGA_DrawLine=VGA_VGA_Draw_Line; @@ -284,7 +305,6 @@ void VGA_SetupDrawing(Bitu val) { vga.draw.lines_scaled=scaleh; height/=scaleh; if (vga.seq.clocking_mode & 0x8) scalew*=2; - vga.draw.address_add=vga.config.scan_len*2; vga.draw.address_line_total=1; VGA_DrawLine=VGA_EGA_Draw_Line; break; @@ -296,7 +316,6 @@ void VGA_SetupDrawing(Bitu val) { height/=2; vga.draw.lines_scaled=1; vga.draw.address_line_total=2; - vga.draw.address_add=80; //CGA doesn't have an offset reg VGA_DrawLine=(vga.mode == M_CGA4) ? VGA_CGA4_Draw_Line : VGA_CGA16_Draw_Line; break; case M_CGA2: @@ -305,7 +324,6 @@ void VGA_SetupDrawing(Bitu val) { vga.draw.blocks=width; width<<=3; vga.draw.address_line_total=2; - vga.draw.address_add=80; //CGA doesn't have an offset reg vga.draw.lines_scaled=1; VGA_DrawLine=VGA_CGA2_Draw_Line; break; @@ -313,7 +331,6 @@ void VGA_SetupDrawing(Bitu val) { vga.draw.address_line_total=4; width*=9; vga.draw.blocks=width/8; - vga.draw.address_add=width/8; vga.draw.lines_scaled=1; height=348; aspect_ratio=1.5; @@ -322,7 +339,6 @@ void VGA_SetupDrawing(Bitu val) { case M_TANDY16: scaleh=2;scalew=2; vga.draw.blocks=width*2; - vga.draw.address_add=160; vga.draw.address_line_total=4; vga.draw.lines_scaled=1; width<<=2;height/=2; @@ -336,7 +352,6 @@ void VGA_SetupDrawing(Bitu val) { }; vga.draw.address_line_total=vga.draw.font_height; vga.draw.blocks=width; - vga.draw.address_add=vga.config.scan_len*4; if (vga.seq.clocking_mode & 0x8) scalew*=2; if (vga.crtc.maximum_scan_line&0x80) scaleh*=2; vga.draw.lines_scaled=scaleh; @@ -349,6 +364,7 @@ void VGA_SetupDrawing(Bitu val) { default: LOG(LOG_VGA,LOG_ERROR)("Unhandled VGA type %d while checking for resolution"); }; + VGA_CheckScanLength(); vga.draw.lines_total=height; if (( width != vga.draw.width) || (height != vga.draw.height)) { PIC_RemoveEvents(VGA_VerticalTimer); From c27159214cf95e3c227730feaf7c586b14bc6231 Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Sun, 8 Feb 2004 08:28:00 +0000 Subject: [PATCH 1584/4131] Added config support for building with IPX Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1666 --- configure.in | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/configure.in b/configure.in index ad483f7b..7142bb0d 100644 --- a/configure.in +++ b/configure.in @@ -152,6 +152,16 @@ else AC_MSG_WARN([Can't find SDL_net, internal modem disabled]) fi +AH_TEMPLATE(C_IPX,[Define to 1 to enable IPX over Internet networking, requires SDL_net]) +AC_CHECK_HEADER(SDL/SDL_net.h,have_sdl_net_h=yes,) +AC_CHECK_LIB(SDL_net, SDLNet_Init, have_sdl_net_lib=yes, , ) +if test x$have_sdl_net_lib = xyes -a x$have_sdl_net_h = xyes ; then + LIBS="$LIBS -lSDL_net" + AC_DEFINE(C_IPX,1) +else + AC_MSG_WARN([Can't find SDL_net, IPX networking disabled]) +fi + AH_TEMPLATE(C_OPENGL,[Define to 1 to use opengl display output support]) AC_ARG_ENABLE(opengl,AC_HELP_STRING([--disable-opengl],[Disable opengl support]),,enable_opengl=yes) AC_CHECK_LIB(GL, main, have_gl_lib=yes, have_gl_lib=no , ) From 8dda3577a974e57dc6f74a1eab5960bb2b87a967 Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Sun, 8 Feb 2004 08:34:27 +0000 Subject: [PATCH 1585/4131] Added external SDLNetInited variable so the modem and IPX stuff don't cause problems when both enabled. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1667 --- include/dosbox.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dosbox.h b/include/dosbox.h index b32184e5..718a6130 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -68,6 +68,7 @@ enum MachineType { }; extern MachineType machine; +extern bool SDLNetInited; #ifndef __LOGGING_H_ #include "logging.h" From 7ee4be6fd8c2ae5057e895cce2519e3b87d794dc Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Sun, 8 Feb 2004 08:36:32 +0000 Subject: [PATCH 1586/4131] Added initial IPX support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1668 --- include/ipx.h | 91 +++ include/ipxserver.h | 49 ++ src/dosbox.cpp | 23 +- src/hardware/ipx.cpp | 1187 ++++++++++++++++++++++++++++++++++++ src/hardware/ipxserver.cpp | 235 +++++++ 5 files changed, 1580 insertions(+), 5 deletions(-) create mode 100644 include/ipx.h create mode 100644 include/ipxserver.h create mode 100644 src/hardware/ipx.cpp create mode 100644 src/hardware/ipxserver.cpp diff --git a/include/ipx.h b/include/ipx.h new file mode 100644 index 00000000..2e002653 --- /dev/null +++ b/include/ipx.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _IPX_H_ +#define _IPX_H_ + +// In Use Flag codes +#define USEFLAG_AVAILABLE 0x00 +#define USEFLAG_AESTEMP 0xe0 +#define USEFLAG_IPXCRIT 0xf8 +#define USEFLAG_SPXLISTEN 0xf9 +#define USEFLAG_PROCESSING 0xfa +#define USEFLAG_HOLDING 0xfb +#define USEFLAG_AESWAITING 0xfc +#define USEFLAG_AESCOUNT 0xfd +#define USEFLAG_LISTENING 0xfe +#define USEFLAG_SENDING 0xff + + +// Completion codes +#define COMP_SUCCESS 0x00 +#define COMP_REMOTETERM 0xec +#define COMP_DISCONNECT 0xed +#define COMP_INVALIDID 0xee +#define COMP_SPXTABLEFULL 0xef +#define COMP_EVENTNOTCANCELED 0xf9 +#define COMP_NOCONNECTION 0xfa +#define COMP_CANCELLED 0xfc +#define COMP_MALFORMED 0xfd +#define COMP_UNDELIVERABLE 0xfe +#define COMP_HARDWAREERROR 0xff + +#ifdef _MSC_VER +#pragma pack(1) +#endif + +// For Uint8 type +#include "SDL_net.h" + + +struct PackedIP { + Uint32 host; + Uint16 port; +} GCC_ATTRIBUTE(packed); + +struct nodeType { + Uint8 node[6]; +}GCC_ATTRIBUTE(packed) ; + +struct IPXHeader { + Uint8 checkSum[2]; + Uint8 length[2]; + Uint8 transControl; // Transport control + Uint8 pType; // Packet type + + struct transport { + Uint8 network[4]; + union addrtype { + nodeType byNode; + PackedIP byIP ; + } GCC_ATTRIBUTE(packed) addr; + Uint8 socket[2]; + } dest, src; +} GCC_ATTRIBUTE(packed); + +// The following routines may not be needed on all systems. On my build of SDL the IPaddress structure is 8 octects +// and therefore screws up my IPXheader structure since it needs to be packed. + +void UnpackIP(PackedIP ipPack, IPaddress * ipAddr); +void PackIP(IPaddress ipAddr, PackedIP *ipPack); + +#ifdef _MSC_VER +#pragma pack() +#endif + +#endif diff --git a/include/ipxserver.h b/include/ipxserver.h new file mode 100644 index 00000000..4877cfb2 --- /dev/null +++ b/include/ipxserver.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2002 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _IPXSERVER_H_ +#define _IPXSERVER_H_ + +#if C_IPX + +#include "SDL_net.h" + +struct packetBuffer { + Bit8u buffer[1024]; + Bit16s packetSize; // Packet size remaining in read + Bit16s packetRead; // Bytes read of total packet + bool inPacket; // In packet reception flag + bool connected; // Connected flag + bool waitsize; +}; + +#define SOCKETTABLESIZE 16 +#define IPXBUFFERSIZE 1024 +#define CONVIP(hostvar) hostvar & 0xff, (hostvar >> 8) & 0xff, (hostvar >> 16) & 0xff, (hostvar >> 24) & 0xff +#define CONVIPX(hostvar) hostvar[0], hostvar[1], hostvar[2], hostvar[3], hostvar[4], hostvar[5] + + +void IPX_StopServer(); +bool IPX_StartServer(Bit16u portnum); +bool IPX_isConnectedToServer(Bits tableNum, IPaddress ** ptrAddr); + +Bit8u packetCRC(Bit8u *buffer, Bit16u bufSize); + +#endif + +#endif \ No newline at end of file diff --git a/src/dosbox.cpp b/src/dosbox.cpp index a9284d82..5dcb3f74 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.61 2004-02-02 15:42:38 harekiet Exp $ */ +/* $Id: dosbox.cpp,v 1.62 2004-02-08 08:35:59 canadacow Exp $ */ #include #include @@ -80,6 +80,7 @@ void CMS_Init(Section*); void DISNEY_Init(Section*); void SERIAL_Init(Section*); void MODEM_Init(Section*); +void IPX_Init(Section*); void PIC_Init(Section*); void TIMER_Init(Section*); @@ -101,6 +102,8 @@ void INT10_Init(Section*); static LoopHandler * loop; +bool SDLNetInited; + Bits RemainTicks;; Bits LastTicks; @@ -183,10 +186,12 @@ void DOSBOX_Init(void) { Section_prop * secprop; Section_line * secline; + SDLNetInited = false; + /* Setup all the different modules making up DOSBox */ secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit); - secprop->Add_string("language",""); + secprop->Add_string("language",""); secprop->Add_string("machine","auto"); #if C_DEBUG @@ -251,7 +256,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("mixer",&MIXER_Init); secprop->Add_bool("nosound",false); - secprop->Add_int("rate",22050); + secprop->Add_int("rate",32000); secprop->Add_int("blocksize",2048); secprop->Add_string("wavedir","waves"); @@ -310,7 +315,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("gus",&GUS_Init); secprop->Add_bool("gus",true); secprop->Add_int("rate",22050); - secprop->Add_hex("base",0x240); + secprop->Add_hex("base",0x240); secprop->Add_int("irq1",5); secprop->Add_int("irq2",5); secprop->Add_int("dma1",3); @@ -337,7 +342,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&DISNEY_Init); secprop->Add_bool("disney",true); - MSG_Add("SPEAKER_CONFIGFILE_HELP", + MSG_Add("SPEAKER_CONFIGFILE_HELP", "pcspeaker -- Enable PC-Speaker emulation.\n" "pcrate -- Sample rate of the PC-Speaker sound generation.\n" "tandy -- Enable Tandy 3-Voice emulation.\n" @@ -383,6 +388,14 @@ void DOSBOX_Init(void) { ); #endif +#if C_IPX + secprop=control->AddSection_prop("ipx",&IPX_Init); + secprop->Add_bool("ipx", true); + MSG_Add("IPX_CONFIGFILE_HELP", + "ipx -- Enable ipx over UDP/IP emulation.\n" + ); +#endif + secline=control->AddSection_line("autoexec",&AUTOEXEC_Init); diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp new file mode 100644 index 00000000..26b9eb08 --- /dev/null +++ b/src/hardware/ipx.cpp @@ -0,0 +1,1187 @@ +/* + * 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. + */ + +#include "dosbox.h" + +#if C_IPX + +#include +#include +#include +#include "cpu.h" +#include "SDL_net.h" +#include "regs.h" +#include "inout.h" +#include "setup.h" +#include "debug.h" +#include "callback.h" +#include "dos_system.h" +#include "mem.h" +#include "ipx.h" +#include "ipxserver.h" +#include "timer.h" +#include "SDL_net.h" +#include "programs.h" + +#define SOCKTABLESIZE 150 // DOS IPX driver was limited to 150 open sockets +#define DOS_MEMSEG 0xd000; + +Bit32u tcpPort; +bool isIpxServer; +bool isIpxConnected; +IPaddress ipxClientIp; // IPAddress for client connection to server +IPaddress ipxServConnIp; // IPAddress for client connection to server +TCPsocket ipxTCPClientSocket; +UDPsocket ipxClientSocket; +int UDPChannel; // Channel used by UDP connection +Bit8u recvBuffer[IPXBUFFERSIZE]; // Incoming packet buffer +Bitu call_ipx; // Callback of RETF entrypoint +Bitu call_ipxint; // Callback of INT 7A entrypoint +Bitu call_ipxesr1; // Callback of ESR init routine +Bitu call_ipxesr2; // Callback of ESR return routine +Bit16u dospage; +static RealPt ipx_callback; +static RealPt ipx_intcallback; +static RealPt ipx_esrcallback; +static RealPt ipx_esrptraddr; +static RealPt processedECB; + +SDLNet_SocketSet clientSocketSet; +static bool inESR; + +struct ipxnetaddr { + Uint8 netnum[4]; // Both are big endian + Uint8 netnode[6]; +} localIpxAddr; + +struct fragmentDescriptor { + Bit16u offset; + Bit16u segment; + Bit16u size; +}; + +packetBuffer incomingPacket; + +static Bit16u swapByte(Bit16u sockNum) { + return (((sockNum>> 8)) | (sockNum << 8)); +} + +void UnpackIP(PackedIP ipPack, IPaddress * ipAddr) { + ipAddr->host = ipPack.host; + ipAddr->port = ipPack.port; +} + +void PackIP(IPaddress ipAddr, PackedIP *ipPack) { + ipPack->host = ipAddr.host; + ipPack->port = ipAddr.port; +} + +class ECBClass { +public: + RealPt ECBAddr; + + ECBClass *prevECB; + ECBClass *nextECB; + + Bit16u getSocket(void) { + return swapByte(real_readw(RealSeg(ECBAddr), RealOff(ECBAddr) + 0xa)); + } + + Bit8u getInUseFlag(void) { + return real_readb(RealSeg(ECBAddr), RealOff(ECBAddr) + 0x8); + } + + void setInUseFlag(Bit8u flagval) { + real_writeb(RealSeg(ECBAddr), RealOff(ECBAddr) + 0x8, flagval); + } + + void setCompletionFlag(Bit8u flagval) { + real_writeb(RealSeg(ECBAddr), RealOff(ECBAddr) + 0x9, flagval); + } + + Bit16u getFragCount(void) { + return real_readw(RealSeg(ECBAddr), RealOff(ECBAddr) + 34); + } + + void getFragDesc(Bit16u descNum, fragmentDescriptor *fragDesc) { + Bit16u memoff = RealOff(ECBAddr) + 30 + ((descNum+1) * 6); + fragDesc->offset = real_readw(RealSeg(ECBAddr), memoff); + memoff+=2; + fragDesc->segment = real_readw(RealSeg(ECBAddr), memoff); + memoff+=2; + fragDesc->size = real_readw(RealSeg(ECBAddr), memoff); + } + + RealPt getESRAddr(void) { + return RealMake(real_readw(RealSeg(ECBAddr), RealOff(ECBAddr)+6), real_readw(RealSeg(ECBAddr), RealOff(ECBAddr)+4)); + } + + void NotifyESR(void) { + RealPt tmpAddr = getESRAddr(); + if(tmpAddr == 0) return; + if(!inESR) { + //LOG_MSG("Calling ESR"); + processedECB = ECBAddr; + inESR = true; + //LOG_MSG("Write %x to %x", real_readd(RealSeg(ECBAddr), RealOff(ECBAddr)+4), RealMake(RealSeg(ipx_esrptraddr), RealOff(ipx_esrptraddr))); + real_writed(RealSeg(ipx_esrptraddr), RealOff(ipx_esrptraddr),real_readd(RealSeg(ECBAddr), RealOff(ECBAddr)+4)); + CPU_CALL(false, RealSeg(ipx_esrcallback), RealOff(ipx_esrcallback)); + + } + } + + void setImmAddress(Bit8u *immAddr) { + Bits i; + for(i=0;i<6;i++) { + real_writeb(RealSeg(ECBAddr), RealOff(ECBAddr)+28, immAddr[i]); + } + } + +}; + +ECBClass *ECBList; // Linked list of ECB's + +ECBClass * CreateECB(RealPt useAddr) { + ECBClass *tmpECB; + tmpECB = new ECBClass(); + + tmpECB->ECBAddr = useAddr; + tmpECB->prevECB = NULL; + tmpECB->nextECB = NULL; + + if (ECBList == NULL) { + ECBList = tmpECB; + } else { + // Transverse the list until we hit the end + ECBClass *useECB; + useECB = ECBList; + while(useECB->nextECB != NULL) { + useECB = useECB->nextECB; + } + useECB->nextECB = tmpECB; + tmpECB->prevECB = useECB; + } + + return tmpECB; +} + +void DeleteECB(ECBClass * useECB) { + if(useECB == NULL) return; + + if(useECB->prevECB == NULL) { + ECBList = useECB->nextECB; + if(ECBList != NULL) ECBList->prevECB = NULL; + } else { + useECB->prevECB->nextECB = useECB->nextECB; + if(useECB->nextECB != NULL) useECB->nextECB->prevECB = useECB->prevECB; + } + delete useECB; +} + +Bit16u socketCount; +Bit16u opensockets[SOCKTABLESIZE]; + +static bool sockInUse(Bit16u sockNum) { + Bit16u i; + for(i=0;i= SOCKTABLESIZE) { + reg_al = 0xfe; // Socket table full + return; + } + + if(sockNum == 0x0000) { + // Dynamic socket allocation + sockAlloc = 0x4002; + while(sockInUse(sockAlloc) && (sockAlloc < 0x7fff)) sockAlloc++; + if(sockAlloc > 0x7fff) { + // I have no idea how this could happen if the IPX driver is limited to 150 open sockets at a time + LOG_MSG("IPX: Out of dynamic sockets"); + } + sockNum = sockAlloc; + } else { + if(sockInUse(sockNum)) { + reg_al = 0xff; // Socket already open + return; + } + } + + opensockets[socketCount] = sockNum; + socketCount++; + + reg_al = 0x00; // Success + reg_dx = swapByte(sockNum); // Convert back to big-endian + +} + +static void CloseSocket(void) { + Bit16u sockNum, i; + + sockNum = swapByte(reg_dx); + if(!sockInUse(sockNum)) return; + + for(i=0;isetInUseFlag(USEFLAG_AVAILABLE); + tmpECB->setCompletionFlag(COMP_UNDELIVERABLE); + DeleteECB(tmpECB); + reg_al = 0xff; // Failure + } else { + tmpECB = CreateECB(RealMake(SegValue(es), reg_si)); + tmpECB->setInUseFlag(USEFLAG_SENDING); + reg_al = 0x00; // Success + } + //LOG_MSG("IPX: Sending packet on %4x", tmpECB->getSocket()); + break; + case 0x0004: // Listen for packet + tmpECB = CreateECB(RealMake(SegValue(es), reg_si)); + if(!sockInUse(tmpECB->getSocket())) { + reg_al = 0xff; // Socket is not open + tmpECB->setInUseFlag(USEFLAG_AVAILABLE); + tmpECB->setCompletionFlag(COMP_HARDWAREERROR); + DeleteECB(tmpECB); + } else { + reg_al = 0x00; // Success + tmpECB->setInUseFlag(USEFLAG_LISTENING); + //LOG_MSG("IPX: Listen for packet on 0x%4x - ESR address %4x:%4x", tmpECB->getSocket(), RealSeg(tmpECB->getESRAddr()), RealOff(tmpECB->getESRAddr())); + } + + + break; + case 0x0008: // Get interval marker + // ???? + break; + case 0x0009: // Get internetwork address + { + LOG_MSG("IPX: Get internetwork address %2x:%2x:%2x:%2x:%2x:%2x", localIpxAddr.netnode[5], localIpxAddr.netnode[4], localIpxAddr.netnode[3], localIpxAddr.netnode[2], localIpxAddr.netnode[1], localIpxAddr.netnode[0]); + Bit8u * addrptr; + Bits i; + + addrptr = (Bit8u *)&localIpxAddr; + for(i=0;i<10;i++) { + real_writeb(SegValue(es),reg_si+i,addrptr[i]); + } + break; + } + case 0x000a: // Relinquish control + // Idle thingy + break; + default: + LOG_MSG("Unhandled IPX function: %4x", reg_bx); + break; + } + +} + +// Entrypoint handler +Bitu IPX_Handler(void) { + handleIpxRequest(); + return CBRET_NONE; +} + +// INT 7A handler +Bitu IPX_IntHandler(void) { + handleIpxRequest(); + return CBRET_NONE; +} + +static void disconnectServer(bool unexpected) { + + // There is no Timer remove code, hence this has to be done manually + incomingPacket.connected = false; + + if(unexpected) LOG_MSG("IPX: Server disconnected unexpectedly"); + +} + +static void pingAck(IPaddress retAddr) { + IPXHeader regHeader; + UDPpacket regPacket; + Bits result; + + SDLNet_Write16(0xffff, regHeader.checkSum); + SDLNet_Write16(sizeof(regHeader), regHeader.length); + + SDLNet_Write32(0, regHeader.dest.network); + PackIP(retAddr, ®Header.dest.addr.byIP); + SDLNet_Write16(0x2, regHeader.dest.socket); + + SDLNet_Write32(0, regHeader.src.network); + memcpy(regHeader.src.addr.byNode.node, localIpxAddr.netnode, sizeof(localIpxAddr)); + SDLNet_Write16(0x2, regHeader.src.socket); + regHeader.transControl = 0; + regHeader.pType = 0x0; + + regPacket.data = (Uint8 *)®Header; + regPacket.len = sizeof(regHeader); + regPacket.maxlen = sizeof(regHeader); + regPacket.channel = UDPChannel; + + result = SDLNet_UDP_Send(ipxClientSocket, regPacket.channel, ®Packet); + +} + +static void pingSend(void) { + IPXHeader regHeader; + UDPpacket regPacket; + Bits result; + + SDLNet_Write16(0xffff, regHeader.checkSum); + SDLNet_Write16(sizeof(regHeader), regHeader.length); + + SDLNet_Write32(0, regHeader.dest.network); + regHeader.dest.addr.byIP.host = 0xffffffff; + regHeader.dest.addr.byIP.port = 0xffff; + SDLNet_Write16(0x2, regHeader.dest.socket); + + SDLNet_Write32(0, regHeader.src.network); + memcpy(regHeader.src.addr.byNode.node, localIpxAddr.netnode, sizeof(localIpxAddr)); + SDLNet_Write16(0x2, regHeader.src.socket); + regHeader.transControl = 0; + regHeader.pType = 0x0; + + regPacket.data = (Uint8 *)®Header; + regPacket.len = sizeof(regHeader); + regPacket.maxlen = sizeof(regHeader); + regPacket.channel = UDPChannel; + + result = SDLNet_UDP_Send(ipxClientSocket, regPacket.channel, ®Packet); + if(!result) { + LOG_MSG("IPX: SDLNet_UDP_Send: %s\n", SDLNet_GetError()); + } + +} + +static void receivePacket(Bit8u *buffer, Bit16s bufSize) { + ECBClass *useECB; + ECBClass *nextECB; + fragmentDescriptor tmpFrag; + Bit16u i, fragCount,t; + Bit16s bufoffset; + Bit16u *bufword = (Bit16u *)buffer; + Bit16u useSocket = swapByte(bufword[8]); + Bit32u hostaddr; + IPXHeader * tmpHeader; + tmpHeader = (IPXHeader *)buffer; + + // Check to see if ping packet + if(useSocket == 0x2) { + // Is this a broadcast? + if((tmpHeader->dest.addr.byIP.host == 0xffffffff) && (tmpHeader->dest.addr.byIP.port = 0xffff)) { + // Yes. We should return the ping back to the sender + IPaddress tmpAddr; + UnpackIP(tmpHeader->src.addr.byIP, &tmpAddr); + pingAck(tmpAddr); + return; + } + } + + + useECB = ECBList; + while(useECB != NULL) { + nextECB = useECB->nextECB; + if(useECB->getInUseFlag() == USEFLAG_LISTENING) { + if(useECB->getSocket() == useSocket) { + useECB->setInUseFlag(USEFLAG_AVAILABLE); + fragCount = useECB->getFragCount(); + bufoffset = 0; + for(i=0;igetFragDesc(i,&tmpFrag); + for(t=0;t=bufSize) { + useECB->setCompletionFlag(COMP_SUCCESS); + useECB->setImmAddress(&buffer[22]); // Write in source node + hostaddr = *((Bit32u *)&buffer[24]); + + //LOG_MSG("IPX: Received packet of %d bytes from %d.%d.%d.%d (%x CRC)", bufSize, CONVIP(hostaddr), packetCRC(&buffer[30], bufSize-30)); + useECB->NotifyESR(); + DeleteECB(useECB); + return; + } + } + } + if(bufoffset < bufSize) { + useECB->setCompletionFlag(COMP_MALFORMED); + useECB->NotifyESR(); + DeleteECB(useECB); + return; + } + } + } + useECB = nextECB; + } + +} + +static void sendPacketsTCP(void) { + ECBClass *useECB; + ECBClass *nextECB; + char outbuffer[IPXBUFFERSIZE]; + fragmentDescriptor tmpFrag; + Bit16u i, fragCount,t; + Bit16s packetsize; + Bit16u *wordptr; + Bits result; + + useECB = ECBList; + while(useECB != NULL) { + nextECB = useECB->nextECB; + if(useECB->getInUseFlag() == USEFLAG_SENDING) { + useECB->setInUseFlag(USEFLAG_AVAILABLE); + packetsize = 0; + fragCount = useECB->getFragCount(); + for(i=0;igetFragDesc(i,&tmpFrag); + if(i==0) { + // Fragment containing IPX header + // Must put source address into header + Bit8u * addrptr; + Bits m; + + addrptr = (Bit8u *)&localIpxAddr.netnode; + for(m=0;m<6;m++) { + real_writeb(tmpFrag.segment,tmpFrag.offset+m+22,addrptr[m]); + } + } + for(t=0;t=IPXBUFFERSIZE) { + LOG_MSG("IPX: Packet size to be sent greater than %d bytes.", IPXBUFFERSIZE); + useECB->setCompletionFlag(COMP_MALFORMED); + useECB->NotifyESR(); + DeleteECB(useECB); + goto nextECB; + } + } + } + result = SDLNet_TCP_Send(ipxTCPClientSocket, &packetsize, 2); + if(result != 2) { + useECB->setCompletionFlag(COMP_UNDELIVERABLE); + useECB->NotifyESR(); + DeleteECB(useECB); + disconnectServer(true); + return; + } + + // Add length and source socket to IPX header + wordptr = (Bit16u *)&outbuffer[0]; + // Blank CRC + wordptr[0] = 0xffff; + // Length + wordptr[1] = swapByte(packetsize); + // Source socket + wordptr[14] = swapByte(useECB->getSocket()); + + result = SDLNet_TCP_Send(ipxTCPClientSocket, &outbuffer[0], packetsize); + if(result != packetsize) { + useECB->setCompletionFlag(COMP_UNDELIVERABLE); + useECB->NotifyESR(); + DeleteECB(useECB); + disconnectServer(true); + return; + } + useECB->setInUseFlag(USEFLAG_AVAILABLE); + useECB->setCompletionFlag(COMP_SUCCESS); + useECB->NotifyESR(); + DeleteECB(useECB); + + } +nextECB: + + useECB = nextECB; + } + +} + + +static void IPX_TCPClientLoop(void) { + Bits result; + + // Check for incoming packets + SDLNet_CheckSockets(clientSocketSet,0); + + if(SDLNet_SocketReady(ipxClientSocket)) { + if(!incomingPacket.inPacket) { + if(!incomingPacket.waitsize) { + result = SDLNet_TCP_Recv(ipxTCPClientSocket, &incomingPacket.packetSize, 2); + if(result!=2) { + if(result>0) { + incomingPacket.waitsize = true; + goto finishReceive; + } else { + disconnectServer(true); + goto finishReceive; + } + } + incomingPacket.packetRead = 0; + } else { + Bit8u * nextchar; + nextchar = (Bit8u *)&incomingPacket.packetSize; + nextchar++; + result = SDLNet_TCP_Recv(ipxTCPClientSocket, nextchar, 1); + if(result!=1) { + if(result>0) { + LOG_MSG("IPX: Packet overrun"); + } else { + disconnectServer(true); + goto finishReceive; + } + } + incomingPacket.waitsize = false; + incomingPacket.packetRead = 0; + } + incomingPacket.inPacket = true; + } + result = SDLNet_TCP_Recv(ipxTCPClientSocket, &incomingPacket.buffer[incomingPacket.packetRead], incomingPacket.packetSize); + if (result>0) { + incomingPacket.packetRead+=result; + incomingPacket.packetSize-=result; + if(incomingPacket.packetSize<=0) { + // IPX packet is complete. Now interpret IPX header and try to match to listening ECB + receivePacket(&incomingPacket.buffer[0], incomingPacket.packetRead); + incomingPacket.inPacket = false; + } + } else { + // Clost active socket + disconnectServer(true); + } + + } + +finishReceive:; + + +} + +static void IPX_UDPClientLoop(void) { + int numrecv; + UDPpacket inPacket; + inPacket.data = (Uint8 *)recvBuffer; + inPacket.maxlen = IPXBUFFERSIZE; + inPacket.channel = UDPChannel; + + // Its amazing how much simpler UDP is than TCP + numrecv = SDLNet_UDP_Recv(ipxClientSocket, &inPacket); + if(numrecv) { + receivePacket(inPacket.data, inPacket.len); + } + +} + +static void sendPackets() { + ECBClass *useECB; + ECBClass *nextECB; + char outbuffer[IPXBUFFERSIZE]; + fragmentDescriptor tmpFrag; + Bit16u i, fragCount,t; + Bit16s packetsize; + Bit16u *wordptr; + Bits result; + UDPpacket outPacket; + + useECB = ECBList; + while(useECB != NULL) { + nextECB = useECB->nextECB; + if(useECB->getInUseFlag() == USEFLAG_SENDING) { + useECB->setInUseFlag(USEFLAG_AVAILABLE); + packetsize = 0; + fragCount = useECB->getFragCount(); + for(i=0;igetFragDesc(i,&tmpFrag); + if(i==0) { + // Fragment containing IPX header + // Must put source address into header + Bit8u * addrptr; + Bits m; + + addrptr = (Bit8u *)&localIpxAddr.netnode; + for(m=0;m<6;m++) { + real_writeb(tmpFrag.segment,tmpFrag.offset+m+22,addrptr[m]); + } + } + for(t=0;t=IPXBUFFERSIZE) { + LOG_MSG("IPX: Packet size to be sent greater than %d bytes.", IPXBUFFERSIZE); + useECB->setCompletionFlag(COMP_UNDELIVERABLE); + useECB->NotifyESR(); + DeleteECB(useECB); + goto nextECB; + } + } + } + + // Add length and source socket to IPX header + wordptr = (Bit16u *)&outbuffer[0]; + // Blank CRC + wordptr[0] = 0xffff; + // Length + wordptr[1] = swapByte(packetsize); + // Source socket + wordptr[14] = swapByte(useECB->getSocket()); + + outPacket.channel = UDPChannel; + outPacket.data = (Uint8 *)&outbuffer[0]; + outPacket.len = packetsize; + outPacket.maxlen = packetsize; + // Since we're using a channel, we won't send the IP address again + result = SDLNet_UDP_Send(ipxClientSocket, UDPChannel, &outPacket); + if(result == 0) { + LOG_MSG("IPX: Could not send packet: %s", SDLNet_GetError()); + useECB->setCompletionFlag(COMP_UNDELIVERABLE); + useECB->NotifyESR(); + DeleteECB(useECB); + disconnectServer(true); + return; + } + useECB->setInUseFlag(USEFLAG_AVAILABLE); + useECB->setCompletionFlag(COMP_SUCCESS); + useECB->NotifyESR(); + DeleteECB(useECB); + + } +nextECB: + + useECB = nextECB; + } + +} + +static void IPX_ClientLoop(void) { + IPX_UDPClientLoop(); + + // Send outgoing packets + sendPackets(); +} + + +static bool pingCheck(IPXHeader * outHeader) { + char buffer[1024]; + Bits result; + UDPpacket regPacket; + + IPXHeader *regHeader; + regPacket.data = (Uint8 *)buffer; + regPacket.maxlen = sizeof(buffer); + regPacket.channel = UDPChannel; + regHeader = (IPXHeader *)buffer; + + result = SDLNet_UDP_Recv(ipxClientSocket, ®Packet); + if (result != 0) { + memcpy(outHeader, regHeader, sizeof(IPXHeader)); + return true; + } + return false; + + +} + +bool ConnectToServer(char *strAddr) { + int numsent; + UDPpacket regPacket; + IPXHeader regHeader; + + if(!SDLNet_ResolveHost(&ipxServConnIp, strAddr, (Bit16u)tcpPort)) { + + // Select an anonymous UDP port + ipxClientSocket = SDLNet_UDP_Open(0); + if(ipxClientSocket) { + // Bind UDP port to address to channel + UDPChannel = SDLNet_UDP_Bind(ipxClientSocket,-1,&ipxServConnIp); + //ipxClientSocket = SDLNet_TCP_Open(&ipxServConnIp); + SDLNet_Write16(0xffff, regHeader.checkSum); + SDLNet_Write16(sizeof(regHeader), regHeader.length); + + // Echo packet with zeroed dest and src is a server registration packet + SDLNet_Write32(0, regHeader.dest.network); + regHeader.dest.addr.byIP.host = 0x0; + regHeader.dest.addr.byIP.port = 0x0; + SDLNet_Write16(0x2, regHeader.dest.socket); + + SDLNet_Write32(0, regHeader.src.network); + regHeader.src.addr.byIP.host = 0x0; + regHeader.src.addr.byIP.port = 0x0; + SDLNet_Write16(0x2, regHeader.src.socket); + regHeader.transControl = 0; + + regPacket.data = (Uint8 *)®Header; + regPacket.len = sizeof(regHeader); + regPacket.maxlen = sizeof(regHeader); + regPacket.channel = UDPChannel; + // Send registration string to server. If server doesn't get this, client will not be registered + numsent = SDLNet_UDP_Send(ipxClientSocket, regPacket.channel, ®Packet); + + if(!numsent) { + LOG_MSG("IPX: Unable to connect to server: %s", SDLNet_GetError()); + SDLNet_UDP_Close(ipxClientSocket); + return false; + } else { + // Wait for return packet from server. This will contain our IPX address and port num + Bits result; + Bit32u ticks, elapsed; + ticks = GetTicks(); + + while(true) { + elapsed = GetTicks() - ticks; + if(elapsed > 5000) { + LOG_MSG("Timeout connecting to server at %s", strAddr); + SDLNet_UDP_Close(ipxClientSocket); + + return false; + } + CALLBACK_Idle(); + result = SDLNet_UDP_Recv(ipxClientSocket, ®Packet); + if (result != 0) { + memcpy(localIpxAddr.netnode, regHeader.dest.addr.byNode.node, sizeof(localIpxAddr.netnode)); + memcpy(localIpxAddr.netnum, regHeader.dest.network, sizeof(localIpxAddr.netnum)); + break; + } + + } + + LOG_MSG("IPX: Connected to server. IPX address is %d:%d:%d:%d:%d:%d", CONVIPX(localIpxAddr.netnode)); + + + incomingPacket.connected = true; + TIMER_AddTickHandler(&IPX_ClientLoop); + return true; + } + } else { + LOG_MSG("IPX: Unable to open socket"); + + } + } else { + LOG_MSG("IPX: Unable resolve connection to server"); + } + return false; +} + +void DisconnectFromServer(void) { + + if(incomingPacket.connected) { + incomingPacket.connected = false; + TIMER_DelTickHandler(&IPX_ClientLoop); + SDLNet_UDP_Close(ipxClientSocket); + } +} + +bool IPX_NetworkInit() { + + localIpxAddr.netnum[0] = 0x0; localIpxAddr.netnum[1] = 0x0; localIpxAddr.netnum[2] = 0x0; localIpxAddr.netnum[3] = 0x1; + + /* + if(SDLNet_ResolveHost(&ipxClientIp, localhostname, tcpPort)) { + LOG_MSG("IPX: Unable to resolve localname: \"%s\". IPX disabled.", localhostname); + return false; + } else { + LOG_MSG("IPX: Using localname: %s IP is: %d.%d.%d.%d", localhostname, CONVIP(ipxClientIp.host)); + } + */ + + // Generate the MAC address. This is made by zeroing out the first two octets and then using the actual IP address for + // the last 4 octets. This idea is from the IPX over IP implementation as specified in RFC 1234: + // http://www.faqs.org/rfcs/rfc1234.html + localIpxAddr.netnode[0] = 0x00; + localIpxAddr.netnode[1] = 0x00; + //localIpxAddr.netnode[5] = (ipxClientIp.host >> 24) & 0xff; + //localIpxAddr.netnode[4] = (ipxClientIp.host >> 16) & 0xff; + //localIpxAddr.netnode[3] = (ipxClientIp.host >> 8) & 0xff; + //localIpxAddr.netnode[2] = (ipxClientIp.host & 0xff); + //To be filled in on response from server + localIpxAddr.netnode[2] = 0x00; + localIpxAddr.netnode[3] = 0x00; + localIpxAddr.netnode[4] = 0x00; + localIpxAddr.netnode[5] = 0x00; + + socketCount = 0; + return true; +} + +class IPXNET : public Program { +public: + void HelpCommand(const char *helpStr) { + // Help on connect command + if(stricmp("connect", helpStr) == 0) { + WriteOut("IPXNET CONNECT opens a connection to an IPX tunneling server running on another\n"); + WriteOut("DosBox session. The \"address\" parameter specifies the IP address or host name\n"); + WriteOut("of the server computer. One can also specify the UDP port to use. By default\n"); + WriteOut("IPXNET uses port 213, the assigned IANA port for IPX tunneling, for its\nconnection.\n\n"); + WriteOut("The syntax for IPXNET CONNECT is:\n\n"); + WriteOut("IPXNET CONNECT address \n\n"); + return; + } + // Help on the disconnect command + if(stricmp("disconnect", helpStr) == 0) { + WriteOut("IPXNET DISCONNECT closes the connection to the IPX tunneling server.\n\n"); + WriteOut("The syntax for IPXNET DISCONNECT is:\n\n"); + WriteOut("IPXNET DISCONNECT\n\n"); + return; + } + // Help on the startserver command + if(stricmp("startserver", helpStr) == 0) { + WriteOut("IPXNET STARTSERVER starts and IPX tunneling server on this DosBox session. By\n"); + WriteOut("default, the server will accept connections on UDP port 213, though this can be\n"); + WriteOut("changed. Once the server is started, DosBox will automatically start a client\n"); + WriteOut("connection to the IPX tunneling server.\n\n"); + WriteOut("The syntax for IPXNET STARTSERVER is:\n\n"); + WriteOut("IPXNET STARTSERVER \n\n"); + return; + } + // Help on the stop server command + if(stricmp("stopserver", helpStr) == 0) { + WriteOut("IPXNET STOPSERVER stops the IPX tunneling server running on this DosBox\nsession."); + WriteOut(" Care should be taken to ensure that all other connections have\nterminated "); + WriteOut("as well sinnce stoping the server may cause lockups on other\nmachines still using "); + WriteOut("the IPX tunneling server.\n\n"); + WriteOut("The syntax for IPXNET STOPSERVER is:\n\n"); + WriteOut("IPXNET STOPSERVER\n\n"); + return; + } + // Help on the ping command + if(stricmp("ping", helpStr) == 0) { + WriteOut("IPXNET PING broadcasts a ping request through the IPX tunneled network. In \n"); + WriteOut("response, all other connected computers will respond to the ping and report\n"); + WriteOut("the time it took to receive and send the ping message.\n\n"); + WriteOut("The syntax for IPXNET PING is:\n\n"); + WriteOut("IPXNET PING\n\n"); + return; + } + // Help on the status command + if(stricmp("status", helpStr) == 0) { + WriteOut("IPXNET STATUS reports the current state of this DosBox's sessions IPX tunneling\n"); + WriteOut("network. For a list of the computers connected to the network use the IPXNET \n"); + WriteOut("PING command.\n\n"); + WriteOut("The syntax for IPXNET STATUS is:\n\n"); + WriteOut("IPXNET STATUS\n\n"); + return; + } + } + + void Run(void) + { + WriteOut("IPX Tunneling utility for DosBox\n\n"); + if(!cmd->GetCount()) { + WriteOut("The syntax of this command is:\n\n"); + WriteOut("IPXNET [ CONNECT | DISCONNECT | STARTSERVER | STOPSERVER | PING | HELP |\n STATUS ]\n\n"); + return; + } + + if(cmd->FindCommand(1, temp_line)) { + if(stricmp("help", temp_line.c_str()) == 0) { + if(!cmd->FindCommand(2, temp_line)) { + WriteOut("The following are valid IPXNET commands:\n\n"); + WriteOut("IPXNET CONNECT IPXNET DISCONNECT IPXNET STARTSERVER\n"); + WriteOut("IPXNET STOPSERVER IPXNET PING IPXNET STATUS\n\n"); + WriteOut("To get help on a specific command, type:\n\n"); + WriteOut("IPXNET HELP command\n\n"); + + } else { + HelpCommand(temp_line.c_str()); + return; + } + return; + } + if(stricmp("startserver", temp_line.c_str()) == 0) { + if(!isIpxServer) { + if(incomingPacket.connected) { + WriteOut("IPX Tunneling Client alreadu connected to another server. Disconnect first.\n"); + return; + } + bool startsuccess; + if(!cmd->FindCommand(2, temp_line)) { + tcpPort = 213; + } else { + tcpPort = strtol(temp_line.c_str(), NULL, 10); + } + startsuccess = IPX_StartServer((Bit16u)tcpPort); + if(startsuccess) { + WriteOut("IPX Tunneling Server started\n"); + isIpxServer = true; + ConnectToServer("localhost"); + } else { + WriteOut("IPX Tunneling Server failed to start\n"); + } + } else { + WriteOut("IPX Tunneling Server already started\n"); + } + return; + } + if(stricmp("stopserver", temp_line.c_str()) == 0) { + if(!isIpxServer) { + WriteOut("IPX Tunneling Server not running in this DosBox session.\n"); + } else { + isIpxServer = false; + DisconnectFromServer(); + IPX_StopServer(); + WriteOut("IPX Tunneling Server stopped."); + // Don't know how to stop the timer just yet. + } + return; + } + if(stricmp("connect", temp_line.c_str()) == 0) { + char strHost[1024]; + if(incomingPacket.connected) { + WriteOut("IPX Tunneling Client already connected.\n"); + return; + } + if(!cmd->FindCommand(2, temp_line)) { + WriteOut("IPX Server address not specified.\n"); + return; + } + strcpy(strHost, temp_line.c_str()); + + if(!cmd->FindCommand(3, temp_line)) { + tcpPort = 213; + } else { + tcpPort = strtol(temp_line.c_str(), NULL, 10); + } + + if(ConnectToServer(strHost)) { + WriteOut("IPX Tunneling Client connected to server at %s.\n", strHost); + } else { + WriteOut("IPX Tunneling Client failed to connect to server at %s.\n", strHost); + } + return; + } + + if(stricmp("disconnect", temp_line.c_str()) == 0) { + if(!incomingPacket.connected) { + WriteOut("IPX Tunneling Client not connected.\n"); + return; + } + // TODO: Send a packet to the server notifying of disconnect + + WriteOut("IPX Tunneling Client disconnected from server.\n"); + DisconnectFromServer(); + return; + } + + if(stricmp("status", temp_line.c_str()) == 0) { + WriteOut("IPX Tunneling Status:\n\n"); + WriteOut("Server status: "); + if(isIpxServer) WriteOut("ACTIVE\n"); else WriteOut("INACTIVE\n"); + WriteOut("Client status: "); + if(incomingPacket.connected) { + WriteOut("CONNECTED -- Server at %d.%d.%d.%d port %d\n", CONVIP(ipxServConnIp.host), tcpPort); + } else { + WriteOut("DISCONNECTED\n"); + } + if(isIpxServer) { + WriteOut("List of active connections:\n\n"); + int i; + IPaddress *ptrAddr; + for(i=0;ihost), SDLNet_Read16(&ptrAddr->port)); + } + } + WriteOut("\n"); + } + return; + } + + if(stricmp("ping", temp_line.c_str()) == 0) { + Bit32u ticks; + IPXHeader pingHead; + + if(!incomingPacket.connected) { + WriteOut("IPX Tunneling Client not connected.\n"); + return; + } + + WriteOut("Sending broadcast ping:\n\n"); + pingSend(); + ticks = GetTicks(); + while((GetTicks() - ticks) < 1500) { + CALLBACK_Idle(); + if(pingCheck(&pingHead)) { + WriteOut("Response from %d.%d.%d.%d, port %d time=%dms\n", CONVIP(pingHead.src.addr.byIP.host), SDLNet_Read16(&pingHead.src.addr.byIP.port), GetTicks() - ticks); + } + } + return; + } + + + + } + + /* + WriteOut("IPX Status\n\n"); + if(!incomingPacket.connected) { + WriteOut("IPX tunneling client not presently connected"); + return; + } + if(isIpxServer) { + WriteOut("This DosBox session is an IPX tunneling server running on port %d", tcpPort); + } else { + WriteOut("This DosBox session is an IPX tunneling client connected to: %s",SDLNet_ResolveIP(&ipxServConnIp)); + } + */ + } +}; + +static void IPXNET_ProgramStart(Program * * make) { + *make=new IPXNET; +} + +Bitu IPX_ESRHandler1(void) { + CPU_Push32(reg_flags); + CPU_Push32(reg_eax);CPU_Push32(reg_ecx);CPU_Push32(reg_edx);CPU_Push32(reg_ebx); + CPU_Push32(reg_ebp);CPU_Push32(reg_esi);CPU_Push32(reg_edi); + CPU_Push16(SegValue(ds)); CPU_Push16(SegValue(es)); + + SegSet16(es, RealSeg(processedECB)); + reg_si = RealOff(processedECB); + reg_al = 0xff; + //LOG_MSG("ESR Callback 1"); + + return CBRET_NONE; +} + +Bitu IPX_ESRHandler2(void) { + SegSet16(es, CPU_Pop16()); SegSet16(ds, CPU_Pop16()); + reg_edi=CPU_Pop32();reg_esi=CPU_Pop32();reg_ebp=CPU_Pop32(); + reg_ebx=CPU_Pop32();reg_edx=CPU_Pop32();reg_ecx=CPU_Pop32();reg_eax=CPU_Pop32(); + reg_flags=CPU_Pop32(); + + //LOG_MSG("Leaving ESR"); + inESR = false; + + return CBRET_NONE; +} + +bool IPX_ESRSetupHook(Bitu callback1, CallBack_Handler handler1, Bitu callback2, CallBack_Handler handler2, RealPt *ptrAddr) { + PhysPt phyDospage; + phyDospage = PhysMake(dospage,0); + + // Inital callback routine (should save registers, etc.) + phys_writeb(phyDospage+0,(Bit8u)0xFA); //CLI + phys_writeb(phyDospage+1,(Bit8u)0xFE); //GRP 4 + phys_writeb(phyDospage+2,(Bit8u)0x38); //Extra Callback instruction + phys_writew(phyDospage+3,callback1); //The immediate word + phys_writeb(phyDospage+5,(Bit8u)0x9a); //CALL Ap + // 0x6, 0x7, 0x8, 0x9 = address of called routine + *ptrAddr = RealMake(dospage, 6); + phys_writed(phyDospage+6,(Bit32u)0x00000000); // Called address + phys_writeb(phyDospage+0xa,(Bit8u)0xFE); //GRP 4 + phys_writeb(phyDospage+0xb,(Bit8u)0x38); //Extra Callback instruction + phys_writew(phyDospage+0xc,callback2); //The immediate word + phys_writeb(phyDospage+0xe,(Bit8u)0xFB); //STI + phys_writeb(phyDospage+0xf,(Bit8u)0xCB); //A RETF Instruction + + CallBack_Handlers[callback1]=handler1; + CallBack_Handlers[callback2]=handler2; + return true; +} + +void IPX_Init(Section* sec) { + Section_prop * section=static_cast(sec); + + if(!section->Get_bool("ipx")) return; + + if(!SDLNetInited) { + if(SDLNet_Init()==-1) { + LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); + return; + } + SDLNetInited = true; + } + + ECBList = NULL; + + isIpxServer = false; + isIpxConnected = false; + + IPX_NetworkInit(); + + inESR = false; + + DOS_AddMultiplexHandler(IPX_Multiplex); + call_ipx=CALLBACK_Allocate(); + CALLBACK_Setup(call_ipx,&IPX_Handler,CB_RETF); + ipx_callback=CALLBACK_RealPointer(call_ipx); + + call_ipxint=CALLBACK_Allocate(); + CALLBACK_Setup(call_ipxint,&IPX_IntHandler,CB_IRET); + ipx_intcallback=CALLBACK_RealPointer(call_ipxint); + + call_ipxesr1=CALLBACK_Allocate(); + call_ipxesr2=CALLBACK_Allocate(); + //CALLBACK_SetupFarCall(call_ipxesr1, &IPX_ESRHandler1, call_ipxesr2, &IPX_ESRHandler2, &ipx_esrptraddr); + dospage = DOS_GetMemory(1); + IPX_ESRSetupHook(call_ipxesr1, &IPX_ESRHandler1, call_ipxesr2, &IPX_ESRHandler2, &ipx_esrptraddr); + // Allocate 16 bytes of memory from the DOS system area at 0xd000 + ipx_esrcallback=RealMake(dospage,0); + //CALLBACK_RealPointer(call_ipxesr1); + + RealSetVec(0x7a,ipx_intcallback); + PROGRAMS_MakeFile("IPXNET.COM",IPXNET_ProgramStart); + + //if(isIpxServer) { + // Auto-connect to server + // ConnectToServer("localhost"); + //} + +} + +#endif diff --git a/src/hardware/ipxserver.cpp b/src/hardware/ipxserver.cpp new file mode 100644 index 00000000..174aa1b3 --- /dev/null +++ b/src/hardware/ipxserver.cpp @@ -0,0 +1,235 @@ +/* + * 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. + */ + +#include "dosbox.h" + +#if C_IPX + +#include "dosbox.h" +#include "ipxserver.h" +#include "timer.h" +#include +#include +#include "ipx.h" + +IPaddress ipxServerIp; // IPAddress for server's listening port +UDPsocket ipxServerSocket; // Listening server socket + +packetBuffer connBuffer[SOCKETTABLESIZE]; + +Bit8u inBuffer[IPXBUFFERSIZE]; +IPaddress ipconn[SOCKETTABLESIZE]; // Active TCP/IP connection +UDPsocket tcpconn[SOCKETTABLESIZE]; // Active TCP/IP connections +SDLNet_SocketSet serverSocketSet; +TIMER_TickHandler* serverTimer; + +Bit8u packetCRC(Bit8u *buffer, Bit16u bufSize) { + Bit8u tmpCRC = 0; + Bit16u i; + for(i=0;isrc.addr.byIP.host; + desthost = tmpHeader->dest.addr.byIP.host; + + srcport = tmpHeader->src.addr.byIP.port; + destport = tmpHeader->dest.addr.byIP.port; + + + if(desthost == 0xffffffff) { + // Broadcast + for(i=0;i= SOCKETTABLESIZE) return false; + *ptrAddr = &ipconn[tableNum]; + return connBuffer[tableNum].connected; +} + +static void ackClient(IPaddress clientAddr) { + IPXHeader regHeader; + UDPpacket regPacket; + Bits result; + + SDLNet_Write16(0xffff, regHeader.checkSum); + SDLNet_Write16(sizeof(regHeader), regHeader.length); + + SDLNet_Write32(0, regHeader.dest.network); + PackIP(clientAddr, ®Header.dest.addr.byIP); + SDLNet_Write16(0x2, regHeader.dest.socket); + + SDLNet_Write32(0, regHeader.src.network); + PackIP(ipxServerIp, ®Header.src.addr.byIP); + SDLNet_Write16(0x2, regHeader.src.socket); + regHeader.transControl = 0; + + regPacket.data = (Uint8 *)®Header; + regPacket.len = sizeof(regHeader); + regPacket.maxlen = sizeof(regHeader); + regPacket.address = clientAddr; + // Send registration string to client. If client doesn't get this, client will not be registered + result = SDLNet_UDP_Send(ipxServerSocket,-1,®Packet); + +} + +static void IPX_ServerLoop() { + UDPpacket inPacket; + IPaddress tmpAddr; + + //char regString[] = "IPX Register\0"; + + Bit16u i; + Bit32u host; + Bits result; + + inPacket.channel = -1; + inPacket.data = &inBuffer[0]; + inPacket.maxlen = IPXBUFFERSIZE; + + + result = SDLNet_UDP_Recv(ipxServerSocket, &inPacket); + if (result != 0) { + // Check to see if incoming packet is a registration packet + // For this, I just spoofed the echo protocol packet designation 0x02 + IPXHeader *tmpHeader; + tmpHeader = (IPXHeader *)&inBuffer[0]; + + // Check to see if echo packet + if(SDLNet_Read16(tmpHeader->dest.socket) == 0x2) { + + + // Null destination node means its a server registration packet + if(tmpHeader->dest.addr.byIP.host == 0x0) { + UnpackIP(tmpHeader->src.addr.byIP, &tmpAddr); + for(i=0;i Date: Sun, 8 Feb 2004 08:38:40 +0000 Subject: [PATCH 1587/4131] Fixed modem to work with the Telnet protocol. Integrated fizzban's code to dial a striing of numbers as an IP. This release should work with Xmodem and Ymodem protocols. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1669 --- src/hardware/serialport.cpp | 6 +- src/hardware/softmodem.cpp | 177 +++++++++++++++++++++++++++++++++++- 2 files changed, 177 insertions(+), 6 deletions(-) diff --git a/src/hardware/serialport.cpp b/src/hardware/serialport.cpp index a5ba389e..3b7b55be 100644 --- a/src/hardware/serialport.cpp +++ b/src/hardware/serialport.cpp @@ -231,7 +231,7 @@ skipreset: break; case 0xE: // modem status register lowerint(INT_MS); - LOG_UART("Read from %X %X",port,outval); +// LOG_UART("Read from %X %X",port,outval); outval=mstatus; mstatus&=0xf0; return outval; @@ -279,7 +279,7 @@ Bitu CSerial::rx_size() { } void CSerial::rx_addb(Bit8u data) { - LOG_UART("RX add %c",data); +// LOG_UART("RX add %c",data); if (rx_fifo.used=FIFO_SIZE) where-=FIFO_SIZE; @@ -306,7 +306,7 @@ void CSerial::rx_adds(Bit8u * data,Bitu size) { } void CSerial::tx_addb(Bit8u data) { - LOG_UART("TX add %c",data); +// LOG_UART("TX add %c",data); if (tx_fifo.used=FIFO_SIZE) where-=FIFO_SIZE; diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp index 39466c93..937df31d 100644 --- a/src/hardware/softmodem.cpp +++ b/src/hardware/softmodem.cpp @@ -60,12 +60,12 @@ struct ModemHd { bool incomingcall; bool autoanswer; bool echo; + bool telnetmode; Bitu cmdpause; Bits ringcounter; Bit16u plusinc; Bit16u cmdpos; - TCPsocket socket; TCPsocket listensocket; SDLNet_SocketSet socketset; @@ -85,8 +85,25 @@ struct ModemHd { MIXER_Channel * chan; }; +#define TEL_CLIENT 0 +#define TEL_SERVER 1 + +struct telnetClient { + bool binary[2]; + bool echo[2]; + bool supressGA[2]; + bool timingMark[2]; + + bool inIAC; + bool recCommand; + + Bit8u command; + +}; + static CSerial * mdm; static ModemHd mhd; +static telnetClient telClient; static void sendStr(const char *usestr) { if (!mhd.echo) return; @@ -110,6 +127,10 @@ static void sendError() { sendStr("\nERROR\n"); } +void InitTelnet() { + memset(&telClient, 0, sizeof(telClient)); +} + static void toUpcase(char *buffer) { Bitu i=0; while (buffer[i] != 0) { @@ -130,6 +151,7 @@ static void openConnection() { sendStr("\nCONNECT 57600\n"); mhd.commandmode = false; mdm->setmodemstatus(CONNECTED); + InitTelnet(); } else { sendStr("\nNO DIALTONE\n"); } @@ -197,7 +219,7 @@ static void DoCommand() { result = 0; - /* Just for kicks */ + /* AT command set interpretation */ if ((mhd.cmdbuf[0] == 'A') && (mhd.cmdbuf[1] == 'T')) foundat = true; if (foundat) { if (strstr(mhd.cmdbuf,"I3")) { @@ -223,6 +245,14 @@ static void DoCommand() { mhd.echo = true; } + if (strstr(mhd.cmdbuf,"NET0")) { + mhd.telnetmode = false; + } + if (strstr(mhd.cmdbuf,"NET1")) { + mhd.telnetmode = true; + } + + if (strstr(mhd.cmdbuf,"ATH")) { /* Check if we're actually connected */ if (mhd.socket) { @@ -251,6 +281,36 @@ static void DoCommand() { if (!foundstr[0]) { result=2; } else { + if (strlen(foundstr) >= 12) + { + // Check if supplied parameter only consists of digits + bool isNum = true; + for (int i=0; i '9') + isNum = false; + + if (isNum) + { + // Parameter is a number with at least 12 digits => this cannot be a valid IP/name + // Transform by adding dots + char buffer[128]; + int j = 0; + for (int i=0; i12) + buffer[j++] = ':'; + } + buffer[j] = 0; + foundstr = buffer; + } + } connResult = Dial(foundstr); result=3; } @@ -314,6 +374,97 @@ static void MC_Changed(Bitu new_mc) { ); } +static void TelnetEmulation(Bit8u * data, Bitu size) { + int i; + Bit8u c; + for(i=0;i250) { + /* Reject anything we don't recognize */ + mdm->tx_addb(0xff); mdm->tx_addb(252); mdm->tx_addb(c); /* We won't do crap! */ + } + } + + switch(telClient.command) { + case 251: /* Will */ + if(c == 0) telClient.binary[TEL_SERVER] = true; + if(c == 1) telClient.echo[TEL_SERVER] = true; + if(c == 3) telClient.supressGA[TEL_SERVER] = true; + break; + case 252: /* Won't */ + if(c == 0) telClient.binary[TEL_SERVER] = false; + if(c == 1) telClient.echo[TEL_SERVER] = false; + if(c == 3) telClient.supressGA[TEL_SERVER] = false; + break; + case 253: /* Do */ + if(c == 0) { + telClient.binary[TEL_CLIENT] = true; + mdm->tx_addb(0xff); mdm->tx_addb(251); mdm->tx_addb(0); /* Will do binary transfer */ + } + if(c == 1) { + telClient.echo[TEL_CLIENT] = false; + mdm->tx_addb(0xff); mdm->tx_addb(252); mdm->tx_addb(1); /* Won't echo (too lazy) */ + } + if(c == 3) { + telClient.supressGA[TEL_CLIENT] = true; + mdm->tx_addb(0xff); mdm->tx_addb(251); mdm->tx_addb(3); /* Will Suppress GA */ + } + break; + case 254: /* Don't */ + if(c == 0) { + telClient.binary[TEL_CLIENT] = false; + mdm->tx_addb(0xff); mdm->tx_addb(252); mdm->tx_addb(0); /* Won't do binary transfer */ + } + if(c == 1) { + telClient.echo[TEL_CLIENT] = false; + mdm->tx_addb(0xff); mdm->tx_addb(252); mdm->tx_addb(1); /* Won't echo (fine by me) */ + } + if(c == 3) { + telClient.supressGA[TEL_CLIENT] = true; + mdm->tx_addb(0xff); mdm->tx_addb(251); mdm->tx_addb(3); /* Will Suppress GA (too lazy) */ + } + break; + default: + LOG_MSG("MODEM: Telnet client sent IAC %d", telClient.command); + break; + } + + telClient.inIAC = false; + telClient.recCommand = false; + continue; + + } else { + if(c==249) { + /* Go Ahead received */ + telClient.inIAC = false; + continue; + } + telClient.command = c; + telClient.recCommand = true; + + if((telClient.binary[TEL_SERVER]) && (c == 0xff)) { + /* Binary data with value of 255 */ + telClient.inIAC = false; + telClient.recCommand = false; + mdm->rx_addb(0xff); + continue; + } + + } + } else { + if(c == 0xff) { + telClient.inIAC = true; + continue; + } + mdm->rx_addb(c); + } + } +} + static void MODEM_Hardware(void) { int result =0; unsigned long args = 1; @@ -380,11 +531,18 @@ static void MODEM_Hardware(void) { SDLNet_CheckSockets(mhd.socketset,0); /* Handle outgoing to the serial port */ + if(mdm->rx_size() == 0) { if(!mhd.commandmode && mhd.socket && mdm->rx_free() && SDLNet_SocketReady(mhd.socket)) { usesize = mdm->rx_free(); result = SDLNet_TCP_Recv(mhd.socket, tmpbuf, usesize); if (result>0) { - mdm->rx_adds(tmpbuf,result); + if(mhd.telnetmode) { + /* Filter telnet commands */ + TelnetEmulation(tmpbuf, result); + + } else { + mdm->rx_adds(tmpbuf,result); + } mhd.cmdpause = 0; } else { /* Error close the socket and disconnect */ @@ -396,6 +554,7 @@ static void MODEM_Hardware(void) { mhd.socket=0; } } + } /* Check for incoming calls */ if (!mhd.socket && !mhd.incomingcall && mhd.listensocket) { @@ -500,6 +659,7 @@ static void MODEM_CallBack(Bit8u * stream,Bit32u len) { MIXER_Enable(mhd.chan,false); mhd.dialing = false; openConnection(); + return; } else { @@ -584,6 +744,14 @@ void MODEM_Init(Section* sec) { return; } + if(!SDLNetInited) { + if(SDLNet_Init()==-1) { + LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); + return; + } + SDLNetInited = true; + } + mhd.cmdpos = 0; mhd.commandmode = true; mhd.plusinc = 0; @@ -593,6 +761,9 @@ void MODEM_Init(Section* sec) { mhd.cmdpause = 0; mhd.echo = true; + /* Default to direct null modem connection. Telnet mode interprets IAC codes */ + mhd.telnetmode = false; + /* Bind the modem to the correct serial port */ mhd.comport=section->Get_int("comport"); strcpy(mhd.remotestr, section->Get_string("remote")); From 45e55eb8d5abfbf3b80b1654a7631870db451eff Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Sun, 8 Feb 2004 08:53:53 +0000 Subject: [PATCH 1588/4131] Added config support for building with IPX Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1670 --- src/platform/visualc/config.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 42aeeeb0..c3260199 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -14,6 +14,9 @@ /* Define to 1 to enable internal modem support, requires SDL_net */ #define C_MODEM 1 +/* Define to 1 to enable IPX networking support, requires SDL_net */ +#define C_IPX 1 + /* Enable some heavy debugging options */ #define C_HEAVY_DEBUG 0 From 4fd8006811a4080f41c24751b19e7ea323954543 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 8 Feb 2004 10:10:16 +0000 Subject: [PATCH 1589/4131] Changed configure to combine modem and ipx sdl_net test Include ipx source file in makefile Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1671 --- configure.in | 12 ++---------- src/hardware/Makefile.am | 2 +- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/configure.in b/configure.in index 7142bb0d..ee1041c5 100644 --- a/configure.in +++ b/configure.in @@ -143,23 +143,15 @@ else fi AH_TEMPLATE(C_MODEM,[Define to 1 to enable internal modem support, requires SDL_net]) -AC_CHECK_HEADER(SDL/SDL_net.h,have_sdl_net_h=yes,) -AC_CHECK_LIB(SDL_net, SDLNet_Init, have_sdl_net_lib=yes, , ) -if test x$have_sdl_net_lib = xyes -a x$have_sdl_net_h = xyes ; then - LIBS="$LIBS -lSDL_net" - AC_DEFINE(C_MODEM,1) -else - AC_MSG_WARN([Can't find SDL_net, internal modem disabled]) -fi - AH_TEMPLATE(C_IPX,[Define to 1 to enable IPX over Internet networking, requires SDL_net]) AC_CHECK_HEADER(SDL/SDL_net.h,have_sdl_net_h=yes,) AC_CHECK_LIB(SDL_net, SDLNet_Init, have_sdl_net_lib=yes, , ) if test x$have_sdl_net_lib = xyes -a x$have_sdl_net_h = xyes ; then LIBS="$LIBS -lSDL_net" + AC_DEFINE(C_MODEM,1) AC_DEFINE(C_IPX,1) else - AC_MSG_WARN([Can't find SDL_net, IPX networking disabled]) + 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]) diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index d5bb84f2..ccc692d2 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -8,5 +8,5 @@ libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp \ vga_memory.cpp vga_misc.cpp vga_seq.cpp font-switch.h ega-switch.h cmos.cpp disney.cpp \ - gus.cpp mpu401.cpp serialport.cpp softmodem.cpp + gus.cpp mpu401.cpp serialport.cpp softmodem.cpp ipx.cpp ipxserver.cpp From 5ff76622ca1d64a149bf0f8f48b329d7b384a060 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 8 Feb 2004 10:18:29 +0000 Subject: [PATCH 1590/4131] Add ipx.cpp and ipxserver.cpp to hardware subgroup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1672 --- visualc_net/dosbox.vcproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 5d30ae35..48d971ce 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -426,6 +426,12 @@ + + + + From 4e169beaa300c71e9ab3564ea25cdc3a370e9f91 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 8 Feb 2004 13:04:34 +0000 Subject: [PATCH 1591/4131] nooo a memory leak Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1673 --- src/hardware/pic.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 4e30c798..3cdd7380 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.17 2004-02-07 18:35:17 harekiet Exp $ */ +/* $Id: pic.cpp,v 1.18 2004-02-08 13:04:34 harekiet Exp $ */ #include @@ -393,6 +393,7 @@ void TIMER_DelTickHandler(TIMER_TickHandler handler) { while (ticker) { if (ticker->handler==handler) { *where=ticker->next; + delete ticker; return; } where=&ticker->next; From a8e431cc6d47d6a5dfa44570ee5db83fd41bafd2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 10 Feb 2004 16:25:17 +0000 Subject: [PATCH 1592/4131] made it crossplatform Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1674 --- src/hardware/ipx.cpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index 26b9eb08..f0626241 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -23,6 +23,8 @@ #include #include #include +#include "cross.h" +#include "support.h" #include "cpu.h" #include "SDL_net.h" #include "regs.h" @@ -861,7 +863,7 @@ class IPXNET : public Program { public: void HelpCommand(const char *helpStr) { // Help on connect command - if(stricmp("connect", helpStr) == 0) { + if(strcasecmp("connect", helpStr) == 0) { WriteOut("IPXNET CONNECT opens a connection to an IPX tunneling server running on another\n"); WriteOut("DosBox session. The \"address\" parameter specifies the IP address or host name\n"); WriteOut("of the server computer. One can also specify the UDP port to use. By default\n"); @@ -871,14 +873,14 @@ public: return; } // Help on the disconnect command - if(stricmp("disconnect", helpStr) == 0) { + if(strcasecmp("disconnect", helpStr) == 0) { WriteOut("IPXNET DISCONNECT closes the connection to the IPX tunneling server.\n\n"); WriteOut("The syntax for IPXNET DISCONNECT is:\n\n"); WriteOut("IPXNET DISCONNECT\n\n"); return; } // Help on the startserver command - if(stricmp("startserver", helpStr) == 0) { + if(strcasecmp("startserver", helpStr) == 0) { WriteOut("IPXNET STARTSERVER starts and IPX tunneling server on this DosBox session. By\n"); WriteOut("default, the server will accept connections on UDP port 213, though this can be\n"); WriteOut("changed. Once the server is started, DosBox will automatically start a client\n"); @@ -888,7 +890,7 @@ public: return; } // Help on the stop server command - if(stricmp("stopserver", helpStr) == 0) { + if(strcasecmp("stopserver", helpStr) == 0) { WriteOut("IPXNET STOPSERVER stops the IPX tunneling server running on this DosBox\nsession."); WriteOut(" Care should be taken to ensure that all other connections have\nterminated "); WriteOut("as well sinnce stoping the server may cause lockups on other\nmachines still using "); @@ -898,7 +900,7 @@ public: return; } // Help on the ping command - if(stricmp("ping", helpStr) == 0) { + if(strcasecmp("ping", helpStr) == 0) { WriteOut("IPXNET PING broadcasts a ping request through the IPX tunneled network. In \n"); WriteOut("response, all other connected computers will respond to the ping and report\n"); WriteOut("the time it took to receive and send the ping message.\n\n"); @@ -907,7 +909,7 @@ public: return; } // Help on the status command - if(stricmp("status", helpStr) == 0) { + if(strcasecmp("status", helpStr) == 0) { WriteOut("IPXNET STATUS reports the current state of this DosBox's sessions IPX tunneling\n"); WriteOut("network. For a list of the computers connected to the network use the IPXNET \n"); WriteOut("PING command.\n\n"); @@ -927,7 +929,7 @@ public: } if(cmd->FindCommand(1, temp_line)) { - if(stricmp("help", temp_line.c_str()) == 0) { + if(strcasecmp("help", temp_line.c_str()) == 0) { if(!cmd->FindCommand(2, temp_line)) { WriteOut("The following are valid IPXNET commands:\n\n"); WriteOut("IPXNET CONNECT IPXNET DISCONNECT IPXNET STARTSERVER\n"); @@ -941,7 +943,7 @@ public: } return; } - if(stricmp("startserver", temp_line.c_str()) == 0) { + if(strcasecmp("startserver", temp_line.c_str()) == 0) { if(!isIpxServer) { if(incomingPacket.connected) { WriteOut("IPX Tunneling Client alreadu connected to another server. Disconnect first.\n"); @@ -966,7 +968,7 @@ public: } return; } - if(stricmp("stopserver", temp_line.c_str()) == 0) { + if(strcasecmp("stopserver", temp_line.c_str()) == 0) { if(!isIpxServer) { WriteOut("IPX Tunneling Server not running in this DosBox session.\n"); } else { @@ -978,7 +980,7 @@ public: } return; } - if(stricmp("connect", temp_line.c_str()) == 0) { + if(strcasecmp("connect", temp_line.c_str()) == 0) { char strHost[1024]; if(incomingPacket.connected) { WriteOut("IPX Tunneling Client already connected.\n"); @@ -1004,7 +1006,7 @@ public: return; } - if(stricmp("disconnect", temp_line.c_str()) == 0) { + if(strcasecmp("disconnect", temp_line.c_str()) == 0) { if(!incomingPacket.connected) { WriteOut("IPX Tunneling Client not connected.\n"); return; @@ -1016,7 +1018,7 @@ public: return; } - if(stricmp("status", temp_line.c_str()) == 0) { + if(strcasecmp("status", temp_line.c_str()) == 0) { WriteOut("IPX Tunneling Status:\n\n"); WriteOut("Server status: "); if(isIpxServer) WriteOut("ACTIVE\n"); else WriteOut("INACTIVE\n"); @@ -1040,7 +1042,7 @@ public: return; } - if(stricmp("ping", temp_line.c_str()) == 0) { + if(strcasecmp("ping", temp_line.c_str()) == 0) { Bit32u ticks; IPXHeader pingHead; From b5697eb1f77995fe0cb391efccde50f83bfbcf6e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 10 Feb 2004 16:32:10 +0000 Subject: [PATCH 1593/4131] slightly more valid dates/compilation warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1675 --- include/ipx.h | 3 ++- include/ipxserver.h | 5 +++-- src/hardware/ipx.cpp | 2 +- src/hardware/ipxserver.cpp | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/include/ipx.h b/include/ipx.h index 2e002653..624ea8bc 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -89,3 +89,4 @@ void PackIP(IPaddress ipAddr, PackedIP *ipPack); #endif #endif + diff --git a/include/ipxserver.h b/include/ipxserver.h index 4877cfb2..9a4441b6 100644 --- a/include/ipxserver.h +++ b/include/ipxserver.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -46,4 +46,5 @@ Bit8u packetCRC(Bit8u *buffer, Bit16u bufSize); #endif -#endif \ No newline at end of file +#endif + diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index f0626241..38da62e2 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/hardware/ipxserver.cpp b/src/hardware/ipxserver.cpp index 174aa1b3..b2471d00 100644 --- a/src/hardware/ipxserver.cpp +++ b/src/hardware/ipxserver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -232,4 +232,4 @@ bool IPX_StartServer(Bit16u portnum) { } -#endif \ No newline at end of file +#endif From fdd235c89697b6548817d27cd42d5d17e70851e5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 10 Feb 2004 16:35:02 +0000 Subject: [PATCH 1594/4131] initial opengl seperation Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1676 --- src/gui/sdlmain.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 8f7aeafe..55cb8ff7 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.60 2004-01-30 21:11:34 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.61 2004-02-10 16:35:02 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -587,6 +587,7 @@ static void GUI_StartUp(Section * sec) { sdl.overlay=0; #if C_OPENGL + if(sdl.desktop.want_type==SCREEN_OPENGL){ /* OPENGL is requested */ sdl.surface=SDL_SetVideoMode(640,400,0,SDL_OPENGL); sdl.opengl.framebuf=0; sdl.opengl.texture=0; @@ -598,12 +599,18 @@ static void GUI_StartUp(Section * sec) { db_glFreeMemoryNV = (PFNWGLFREEMEMORYNVPROC) wglGetProcAddress("wglFreeMemoryNV"); #endif const char * gl_ext = (const char *)glGetString (GL_EXTENSIONS); - sdl.opengl.packed_pixel=strstr(gl_ext,"EXT_packed_pixels") > 0; - sdl.opengl.paletted_texture=strstr(gl_ext,"EXT_paletted_texture") > 0; + if(gl_ext && *gl_ext){ + sdl.opengl.packed_pixel=(strstr(gl_ext,"EXT_packed_pixels") > 0); + sdl.opengl.paletted_texture=(strstr(gl_ext,"EXT_paletted_texture") > 0); #if defined(NVIDIA_PixelDataRange) - sdl.opengl.pixel_data_range=strstr(gl_ext,"GL_NV_pixel_data_range") >0 && - glPixelDataRangeNV && db_glAllocateMemoryNV && db_glFreeMemoryNV; + sdl.opengl.pixel_data_range=(strstr(gl_ext,"GL_NV_pixel_data_range") >0 )&& + glPixelDataRangeNV && db_glAllocateMemoryNV && db_glFreeMemoryNV; #endif + } else { + sdl.opengl.packed_pixel=sdl.opengl.paletted_texture=false; + } + } /* OPENGL is requested end */ + #endif //OPENGL /* Initialize screen for first time */ sdl.surface=SDL_SetVideoMode(640,400,0,0); From 9d242404d5c269683d7d051d63d0f7e1ba97f766 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 12 Feb 2004 20:57:36 +0000 Subject: [PATCH 1595/4131] changed ega_2 into ega_16 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1677 --- src/ints/int10_modes.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index a6807919..d0a4d475 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -28,9 +28,9 @@ VideoModeBlock ModeList[]={ { 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,70 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, { 0x00E ,M_EGA16 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,70 ,_EGA_LINE_DOUBLE }, -{ 0x00F ,M_EGA2 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,400 ,70 ,0 }, +{ 0x00F ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,400 ,70 ,0 },/*was EGA_2*/ { 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,1 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,70 ,0 }, -{ 0x011 ,M_EGA2 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,449 ,80 ,480 ,70 ,0 }, +{ 0x011 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,449 ,80 ,480 ,70 ,0 },/*was EGA_2 */ { 0x012 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,70 ,0 }, { 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,70 ,0 }, From d348bcf043667e9068e3cb03f2f982f87bd500f7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 12 Feb 2004 21:38:35 +0000 Subject: [PATCH 1596/4131] Setup rom areas Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1678 --- src/hardware/memory.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index dddeb8c4..03045ebe 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -102,6 +102,15 @@ public: ROMPageHandler() { flags=PFLAG_READABLE|PFLAG_HASROM; } + void writeb(PhysPt addr,Bitu val){ + LOG_MSG("Write %x to rom at %x",val,addr); + } + void writew(PhysPt addr,Bitu val){ + LOG_MSG("Write %x to rom at %x",val,addr); + } + void writed(PhysPt addr,Bitu val){ + LOG_MSG("Write %x to rom at %x",val,addr); + } }; class LFBPageHandler : public RAMPageHandler { @@ -569,6 +578,14 @@ void MEM_Init(Section * sec) { memory.phandlers[i]=&ram_page_handler; memory.mhandles[i]=0; //Set to 0 for memory allocation } + /* Setup rom at 0xc0000-0xc8000 */ + for (i=0xc0;i<0xc8;i++) { + memory.phandlers[i]=&rom_page_handler; + } + /* Setup rom at 0xf0000-0x0x100000 */ + for (i=0xf0;i<0x100;i++) { + memory.phandlers[i]=&rom_page_handler; + } /* Reset some links */ memory.links.used=0; // A20 Line - PS/2 system control port A From 5cd2ec2005a75fd4241d3748bd1d2d50824613aa Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 12 Feb 2004 21:39:27 +0000 Subject: [PATCH 1597/4131] Use rom compatbile memory write Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1679 --- src/ints/int10.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 6bcc2302..0e5bc636 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -437,7 +437,7 @@ static void SetupTandyBios(void) { 0x64, 0x2e, 0x0d, 0x0a, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x61, 0x6e, 0x64, 0x79 }; Bitu i; - real_writeb(0xffff,0xe,0xff); + phys_writeb(0xffffe,0xff); for(i=0;i<130;i++) { phys_writeb(0xf0000+i+0xc000, TandyConfig[i]); } From 3f70b1d37e7d883ec4204916a3cbb8ef16e089cc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 17 Feb 2004 12:44:11 +0000 Subject: [PATCH 1598/4131] Added new ipxheaders Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1680 --- include/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/Makefile.am b/include/Makefile.am index d0ec949f..83985517 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -12,6 +12,8 @@ fpu.h \ hardware.h \ inout.h \ joystick.h \ +ipx.h \ +ipxserver.h \ keyboard.h \ logging.h \ mem.h \ From a165df8acbd304ebdd9b6c77fd78ff021c61f5c6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 18 Feb 2004 13:02:55 +0000 Subject: [PATCH 1599/4131] added temporary filename output(c2woody) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1681 --- src/dos/dos.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 128e41df..337ba574 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.65 2004-02-02 11:38:44 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.66 2004-02-18 13:02:55 qbix79 Exp $ */ #include #include @@ -736,6 +736,7 @@ static Bitu DOS_21Handler(void) { MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_CreateTempFile(name1,&handle)) { reg_ax=handle; + MEM_BlockWrite(SegPhys(ds)+reg_dx,name1,strlen(name1)+1); CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; From 2a1cee61e17a4e573e34b8615d2c524f445d85e6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 18 Feb 2004 15:31:13 +0000 Subject: [PATCH 1600/4131] fixed tab problems when parsing commands (bug: #897177) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1682 --- include/shell.h | 4 ++-- src/misc/support.cpp | 17 +++++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/include/shell.h b/include/shell.h index 4d0bcd03..202b90b9 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.2 2004-01-10 14:03:33 qbix79 Exp $ */ +/* $Id: shell.h,v 1.3 2004-02-18 15:31:13 qbix79 Exp $ */ #ifndef SHELL_H_ #define SHELL_H_ @@ -119,7 +119,7 @@ struct SHELL_Cmd { static inline void StripSpaces(char*&args) { - while(*args && (*args == ' ')) + while(*args && ((*args == ' ') || (*args == '\t'))) args++; } diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 0eadec29..eb95fbb5 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.21 2004-01-10 14:03:35 qbix79 Exp $ */ +/* $Id: support.cpp,v 1.22 2004-02-18 15:31:13 qbix79 Exp $ */ #include #include @@ -90,7 +90,7 @@ bool ScanCMDBool(char * cmd,char * check) { while ((scan=strchr(scan,'/'))) { /* found a / now see behind it */ scan++; - if (strncasecmp(scan,check,c_len)==0 && (scan[c_len]==' ' || scan[c_len]=='/' || scan[c_len]==0)) { + if (strncasecmp(scan,check,c_len)==0 && (scan[c_len]==' ' || scan[c_len]=='\t' || scan[c_len]=='/' || scan[c_len]==0)) { /* Found a math now remove it from the string */ memmove(scan-1,scan+c_len,strlen(scan+c_len)+1); trim(scan-1); @@ -106,7 +106,7 @@ bool ScanCMDHex(char * cmd,char * check,Bits * result) { while ((scan=strchr(scan,'/'))) { /* found a / now see behind it */ scan++; - if (strncasecmp(scan,check,c_len)==0 && (scan[c_len]==' ' || scan[c_len]==0)) { + if (strncasecmp(scan,check,c_len)==0 && (scan[c_len]==' ' || scan[c_len]=='\t' || scan[c_len]==0)) { /* Found a match now find the number and remove it from the string */ char * begin=scan-1; scan=ltrim(scan+c_len); @@ -128,7 +128,7 @@ bool ScanCMDHex(char * cmd,char * check,Bits * result) { char * ScanCMDRemain(char * cmd) { char * scan,*found;; if ((scan=found=strchr(cmd,'/'))) { - while (*scan!=' ' && *scan!=0) scan++; + while (*scan!=' ' && *scan!='\t' && *scan!=0) scan++; *scan=0; return found; } else return 0; @@ -141,11 +141,16 @@ char * StripWord(char * cmd) { quoted=true; cmd++; } - char * end; + char * end = 0; if (quoted) { end=strchr(cmd,'"'); } else { - end=strchr(cmd,' '); + for(char* in=cmd;*in;in++){ + if(*in==' '||*in=='\t'){ + end=in; + break; + } + } } if (!end) { return cmd+strlen(cmd); From bd02cf869e21749ab709fdb61cb15ec0e4922297 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 19 Feb 2004 12:00:38 +0000 Subject: [PATCH 1601/4131] fixed batchfile handling as startup argument Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1683 --- ChangeLog | 5 +++++ src/shell/shell.cpp | 12 ++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a01db8e8..b1c06c19 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +0.62 + - Fixed commandline parsing when .bat files involved (fixes -exit) + - Fixed issues with tabs in commandline not being processed correctly + - Returned filename in ds:dx in create-random-file (c2woody) + 0.61 - Added a beta dynamic cpu for x86 hosts (very unstable) - Added opengl and hardware overlay display output diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 2688a1d2..fdf828fd 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.39 2004-02-03 08:35:29 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.40 2004-02-19 12:00:38 qbix79 Exp $ */ #include #include @@ -244,7 +244,15 @@ void AUTOEXEC_Init(Section * sec) { if (access(buffer,F_OK)) goto nomount; SHELL_AddAutoexec("MOUNT C \"%s\"",buffer); SHELL_AddAutoexec("C:"); - SHELL_AddAutoexec(name); + upcase(name); + if(strstr(name,".BAT")==0) { + SHELL_AddAutoexec(name); + } else { + char call[CROSS_LEN] = { 0 }; + strcpy(call,"CALL "); + strcat(call,name); + SHELL_AddAutoexec(call); + } if(addexit) SHELL_AddAutoexec("exit"); } } From f8a42011ea7bdadf70a4c9f7b988e161bd1cb054 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 19 Feb 2004 12:24:51 +0000 Subject: [PATCH 1602/4131] cleaned up shutdown sequence. Added SDL_Quit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1684 --- src/gui/sdlmain.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 55cb8ff7..d01b1714 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.61 2004-02-10 16:35:02 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.62 2004-02-19 12:24:51 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -526,6 +526,7 @@ static void GUI_ShutDown(Section * sec) { GFX_Stop(); if (sdl.mouse.locked) CaptureMouse(); if (sdl.desktop.fullscreen) SwitchFullScreen(); + SDL_Quit(); //Becareful this should be removed if on the fly renderchanges are allowed } static void KillSwitch(void){ @@ -995,8 +996,6 @@ int main(int argc, char* argv[]) { control->StartUp(); /* Shutdown everything */ } catch (char * error) { - if (sdl.desktop.fullscreen) SwitchFullScreen(); - if (sdl.mouse.locked) CaptureMouse(); LOG_MSG("Exit to error: %s",error); if(sdl.wait_on_error) { //TODO Maybe look for some way to show message in linux? @@ -1010,8 +1009,11 @@ int main(int argc, char* argv[]) { } catch (int){ - if (sdl.desktop.fullscreen) SwitchFullScreen(); - if (sdl.mouse.locked) CaptureMouse(); + ;//nothing pressed killswitch } + catch(...){ + throw;//dunno what happened. rethrow for sdl to catch + } + return 0; }; From aee86bd8fb2809e5e716c46750d067706687b09d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 24 Feb 2004 09:27:29 +0000 Subject: [PATCH 1603/4131] added patch 902595 from Giovanni Giacobbi Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1685 --- src/shell/shell_cmds.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 43714ed6..bef3633b 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.37 2004-01-10 14:03:36 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.38 2004-02-24 09:27:29 qbix79 Exp $ */ #include @@ -185,13 +185,9 @@ void DOS_Shell::CMD_CHDIR(char * args) { char dir[DOS_PATHLENGTH]; DOS_GetCurrentDir(0,dir); WriteOut("%c:\\%s\n",drive,dir); + } else if (!DOS_ChangeDir(args)) { + WriteOut(MSG_Get("SHELL_CMD_CHDIR_ERROR"),args); } - if (DOS_ChangeDir(args)) { - - } else { - WriteOut(MSG_Get("SHELL_CMD_CHDIR_ERROR"),args); - } - }; void DOS_Shell::CMD_MKDIR(char * args) { From 5555bd0ed94cf1f4919d7866b30f657afbc5d0e5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 26 Feb 2004 07:42:53 +0000 Subject: [PATCH 1604/4131] Add some new exceptions Add some new cases to LAR and LSL Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1686 --- src/cpu/cpu.cpp | 69 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 18 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index a31c4ac4..fa0ab6b2 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.53 2004-01-14 17:09:41 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.54 2004-02-26 07:42:53 harekiet Exp $ */ #include #include "dosbox.h" @@ -345,7 +345,7 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu opLen) { Bitu gate_off=gate.GetOffset(); cpu.gdt.GetDescriptor(gate_sel,cs_desc); Bitu cs_dpl=cs_desc.DPL(); - if (cs_dpl>cpu.cpl) E_Exit("Interrupt to higher privilege"); + if (cs_dpl>cpu.cpl) E_Exit("Interrupt to higher privilege"); switch (cs_desc.Type()) { case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: @@ -410,7 +410,7 @@ do_interrupt: E_Exit("INT:Gate Selector points to illegal descriptor with type %x",cs_desc.Type()); } if (!(gate.Type()&1)) - SETFLAGBIT(IF,false); + SETFLAGBIT(IF,false); SETFLAGBIT(TF,false); SETFLAGBIT(NT,false); SETFLAGBIT(VM,false); @@ -506,7 +506,7 @@ realmode_iret: Bitu n_cs_rpl=n_cs_sel & 3; Descriptor n_cs_desc; cpu.gdt.GetDescriptor(n_cs_sel,n_cs_desc); - if (n_cs_rpl0; Segs.val[cs]=n_cs_sel; reg_eip=n_eip; + CPU_SetFlagsd(n_flags); LOG(LOG_CPU,LOG_NORMAL)("IRET:Same level:%X:%X big %d",n_cs_sel,n_eip,cpu.code.big); } else { @@ -545,9 +546,11 @@ realmode_iret: Segs.phys[cs]=n_cs_desc.GetBase(); cpu.code.big=n_cs_desc.Big()>0; Segs.val[cs]=n_cs_sel; + + CPU_SetFlagsd(n_flags); + cpu.cpl=n_cs_rpl; reg_eip=n_eip; - CPU_SetFlagsd(n_flags); Bitu n_ss,n_esp; if (use32) { n_esp=CPU_Pop32(); @@ -562,8 +565,9 @@ realmode_iret: } else { reg_sp=n_esp; } + //TODO Maybe validate other segments, but why would anyone use them? - LOG(LOG_CPU,LOG_NORMAL)("IRET:Outer level:%X:X big %d",n_cs_sel,n_eip,cpu.code.big); + LOG(LOG_CPU,LOG_NORMAL)("IRET:Outer level:%X:%X big %d",n_cs_sel,n_eip,cpu.code.big); } return; } @@ -592,8 +596,7 @@ void CPU_JMP(bool use32,Bitu selector,Bitu offset,Bitu opLen) { case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: if (rpl>cpu.cpl) E_Exit("JMP:NC:RPL>CPL"); - if (rpl!=desc.DPL()) E_Exit("JMP:NC:RPL != DPL"); - cpu.cpl=desc.DPL(); + if (cpu.cpl!=desc.DPL()) E_Exit("JMP:NC:RPL != DPL"); LOG(LOG_CPU,LOG_NORMAL)("JMP:Code:NC to %X:%X big %d",selector,offset,desc.Big()); goto CODE_jmp; case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: @@ -709,19 +712,22 @@ call_code: if (call.Type()==DESC_386_CALL_GATE) { CPU_Push32(o_ss); //save old stack CPU_Push32(o_esp); - for (Bitu i=0;i<(call.saved.gate.paramcount&31);i++) - CPU_Push32(mem_readd(o_stack+i*4)); + if (call.saved.gate.paramcount&31>0) + for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--) + CPU_Push32(mem_readd(o_stack+i*4)); CPU_Push32(SegValue(cs)); CPU_Push32(reg_eip); } else { CPU_Push16(o_ss); //save old stack CPU_Push16(o_esp); - for (Bitu i=0;i<(call.saved.gate.paramcount&31);i++) - CPU_Push16(mem_readw(o_stack+i*2)); + if (call.saved.gate.paramcount&31>0) + for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--) + CPU_Push16(mem_readw(o_stack+i*2)); CPU_Push16(SegValue(cs)); CPU_Push16(reg_eip); } + cpu.cpl = n_cs_desc.DPL(); /* Switch to new CS:EIP */ Segs.phys[cs] = n_cs_desc.GetBase(); Segs.val[cs] = (n_cs_sel & 0xfffc) | cpu.cpl; @@ -775,7 +781,11 @@ void CPU_RET(bool use32,Bitu bytes,Bitu opLen) { Descriptor desc; Bitu rpl=selector & 3; - if (rpl0; - Segs.val[cs]=selector; + Segs.val[cs]=(selector&0xfffc) | cpu.cpl; reg_eip=offset; + // LOG(LOG_MISC,LOG_ERROR)("RET - Higher level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL()); return; } @@ -964,6 +977,10 @@ void CPU_ARPL(Bitu & dest_sel,Bitu src_sel) { } void CPU_LAR(Bitu selector,Bitu & ar) { + if (selector == 0) { + SETFLAGBIT(ZF,false); + return; + } Descriptor desc;Bitu rpl=selector & 3; ar=0; if (!cpu.gdt.GetDescriptor(selector,desc)){ @@ -975,15 +992,19 @@ void CPU_LAR(Bitu selector,Bitu & ar) { case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: break; + case DESC_286_INT_GATE: case DESC_286_TRAP_GATE: { + case DESC_386_INT_GATE: case DESC_386_TRAP_GATE: + SETFLAGBIT(ZF,false); + return; + } + case DESC_LDT: case DESC_TASK_GATE: case DESC_286_TSS_A: case DESC_286_TSS_B: - case DESC_286_INT_GATE: case DESC_286_TRAP_GATE: case DESC_286_CALL_GATE: case DESC_386_TSS_A: case DESC_386_TSS_B: - case DESC_386_INT_GATE: case DESC_386_TRAP_GATE: case DESC_386_CALL_GATE: @@ -1008,6 +1029,10 @@ void CPU_LAR(Bitu selector,Bitu & ar) { } void CPU_LSL(Bitu selector,Bitu & limit) { + if (selector == 0) { + SETFLAGBIT(ZF,false); + return; + } Descriptor desc;Bitu rpl=selector & 3; limit=0; if (!cpu.gdt.GetDescriptor(selector,desc)){ @@ -1018,7 +1043,7 @@ void CPU_LSL(Bitu selector,Bitu & limit) { case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: break; - + case DESC_LDT: case DESC_286_TSS_A: case DESC_286_TSS_B: @@ -1047,6 +1072,10 @@ void CPU_LSL(Bitu selector,Bitu & limit) { } void CPU_VERR(Bitu selector) { + if (selector == 0) { + SETFLAGBIT(ZF,false); + return; + } Descriptor desc;Bitu rpl=selector & 3; if (!cpu.gdt.GetDescriptor(selector,desc)){ SETFLAGBIT(ZF,false); @@ -1075,6 +1104,10 @@ void CPU_VERR(Bitu selector) { } void CPU_VERW(Bitu selector) { + if (selector == 0) { + SETFLAGBIT(ZF,false); + return; + } Descriptor desc;Bitu rpl=selector & 3; if (!cpu.gdt.GetDescriptor(selector,desc)){ SETFLAGBIT(ZF,false); From e8913d4dd2ff79b6581dfd39873f5c5092a8c951 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 26 Feb 2004 07:43:36 +0000 Subject: [PATCH 1605/4131] Save the old value for LAR and LSL instructions.(c2woody) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1687 --- src/cpu/core_normal/prefix_0f.h | 4 ++-- src/cpu/core_normal/prefix_66_0f.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index c3509448..bbe95b9c 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -100,7 +100,7 @@ CASE_0F_W(0x02) /* LAR Gw,Ew */ { FillFlags(); - GetRMrw;Bitu ar; + GetRMrw;Bitu ar=*rmrw; if (rm >= 0xc0) { GetEArw;CPU_LAR(*earw,ar); } else { @@ -112,7 +112,7 @@ CASE_0F_W(0x03) /* LSL Gw,Ew */ { FillFlags(); - GetRMrw;Bitu limit; + GetRMrw;Bitu limit=*rmrw; if (rm >= 0xc0) { GetEArw;CPU_LSL(*earw,limit); } else { diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 39be74ba..8c53663c 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -101,7 +101,7 @@ CASE_0F_D(0x02) /* LAR Gd,Ed */ { FillFlags(); - GetRMrd;Bitu ar; + GetRMrd;Bitu ar=*rmrd; if (rm >= 0xc0) { GetEArw;CPU_LAR(*earw,ar); } else { @@ -113,7 +113,7 @@ CASE_0F_D(0x03) /* LSL Gd,Ew */ { FillFlags(); - GetRMrd;Bitu limit; + GetRMrd;Bitu limit=*rmrd; /* Just load 16-bit values for selectors */ if (rm >= 0xc0) { GetEArw;CPU_LSL(*earw,limit); From 410b9f72d21afa1687aba2fa35a7d7bfd22ecb67 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 28 Feb 2004 09:21:02 +0000 Subject: [PATCH 1606/4131] Added some exceptions for illegal opcodes. Double 0x67 prefixes should work now. Thnx c2woody Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1688 --- src/cpu/core_normal.cpp | 12 +++++++++--- src/cpu/core_normal/prefix_66.h | 1 + src/cpu/core_normal/prefix_none.h | 1 + 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index ca04fbfe..e4128d9c 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -94,8 +94,8 @@ extern Bitu cycle_count; core.seg_prefix_base=SegBase(_SEG); \ goto restart_prefix; -#define DO_PREFIX_ADDR() \ - core.prefixes^=PREFIX_ADDR; \ +#define DO_PREFIX_ADDR() \ + core.prefixes|=(core.prefix_default ^ PREFIX_ADDR) & PREFIX_ADDR; \ goto restart_prefix; #define DO_PREFIX_REP(_ZERO) \ @@ -194,9 +194,15 @@ restart_opcode: #endif } } - decode_end: +decode_end: LEAVECORE; return CBRET_NONE; + +illegal_opcode: + LEAVECORE; + reg_eip-=core.ip_lookup-core.op_start; + CPU_Exception(6,0); + goto decode_start; } Bits CPU_Core_Normal_Trap_Run(void) { diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index df16c9a3..3e10ce47 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -167,6 +167,7 @@ break; CASE_D(0x63) /* ARPL Ed,Rd */ { + if (((cpu.pmode) && (reg_flags & FLAG_VM)) || (!cpu.pmode)) goto illegal_opcode; FillFlags(); GetRMrw; if (rm >= 0xc0 ) { diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 6d79d972..f5354374 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -237,6 +237,7 @@ break; CASE_W(0x63) /* ARPL Ew,Rw */ { + if (((cpu.pmode) && (reg_flags & FLAG_VM)) || (!cpu.pmode)) goto illegal_opcode; FillFlags(); GetRMrw; if (rm >= 0xc0 ) { From e05d508f81a58e6828021284ec1ed94902be0d6e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 28 Feb 2004 16:35:42 +0000 Subject: [PATCH 1607/4131] dos changes c2woody Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1689 --- include/dos_inc.h | 36 ++++++++++++++++++++++++++++-------- src/dos/dos.cpp | 7 +++++-- src/dos/dos_classes.cpp | 29 +++++++++++++++++++++++++++-- src/dos/dos_execute.cpp | 5 ++++- src/dos/dos_ioctl.cpp | 6 +++++- src/dos/dos_tables.cpp | 3 +++ 6 files changed, 72 insertions(+), 14 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 860f84c5..d35e28d8 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: dos_inc.h,v 1.38 2004-02-28 16:35:42 qbix79 Exp $ */ + #ifndef DOS_H_ #define DOS_H_ @@ -349,19 +351,37 @@ public: #pragma pack(1) #endif struct sDIB { - Bit8u stuff1[20]; // -0x18 some stuff, hopefully never used.... - RealPt firstMCB; // -0x04 first memory control block - RealPt firstDPB; // 0x00 first drive parameter block + 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 stuff1[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 + RealPt activeCon; // 0x0c active console device header Bit16u maxSectorLength; // 0x10 maximum bytes per sector of any block device; RealPt discInfoBuffer; // 0x12 pointer to disc info buffer RealPt curDirStructure; // 0x16 pointer to current array of directory structure - RealPt fcbTable; // 0x1a pointer to system FCB table - Bit8u stuff2[0x21]; // 0x1e more stuff - Bit16u buffers_x; // x in BUFFERS x,y - Bit16u buffers_y; // y in BUFFERS x,y + RealPt fcbTable; // 0x1a pointer to system FCB table + Bit16u protFCBs; // 0x1e protected fcbs + Bit8u blockDevices; // 0x20 installed block devices + Bit8u lastdrive; // 0x21 lastdrive + Bit8u stuff2[0x12]; // 0x22 NUL driver + Bit8u joindedDrives; // 0x34 joined drives + Bit16u specialCodeSeg; // 0x35 special code segment + RealPt setverPtr; // 0x37 pointer to setver + Bit16u a20FixOfs; // 0x3b a20 fix routine offset + Bit16u pspLastIfHMA; // 0x3d psp of last program (if dos in hma) + Bit16u buffers_x; // 0x3f x in BUFFERS x,y + Bit16u buffers_y; // 0x41 y in BUFFERS x,y + Bit8u bootDrive; // 0x43 boot drive + Bit8u useDwordMov; // 0x44 use dword moves + Bit16u extendedSize; // 0x45 size of extended memory // some more stuff, hopefully never used. } GCC_ATTRIBUTE(packed); #ifdef _MSC_VER diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 337ba574..35f14aaa 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.66 2004-02-18 13:02:55 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.67 2004-02-28 16:35:14 qbix79 Exp $ */ #include #include @@ -764,6 +764,10 @@ static Bitu DOS_21Handler(void) { } break; } + case 0x5f: /* Network redirection */ + reg_ax=0x0001; //Failing it + CALLBACK_SCF(true); + break; case 0x60: /* Canonicalize filename or path */ MEM_StrCopy(SegPhys(ds)+reg_si,name1,DOSNAMEBUF); if (DOS_Canonicalize(name1,name2)) { @@ -872,7 +876,6 @@ static Bitu DOS_21Handler(void) { case 0x32: /* Get drive parameter block for specific drive */ case 0x5c: /* FLOCK File region locking */ case 0x5e: /* More Network Functions */ - case 0x5f: /* And Even More Network Functions */ default: LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Unhandled call %02X al=%02X. Set al to default of 0",reg_ah,reg_al); reg_al=0x00; /* default value */ diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 9f1e25b9..62ebdf95 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.34 2004-02-03 14:54:36 finsterr Exp $ */ +/* $Id: dos_classes.cpp,v 1.35 2004-02-28 16:35:14 qbix79 Exp $ */ #include #include @@ -64,11 +64,36 @@ void DOS_InfoBlock::SetLocation(Bit16u segment) pt=PhysMake(seg,0); /* Clear the initual Block */ for(Bitu i=0;i16mb + + sSave(sDIB,sharingCount,(Bit16u)0); + sSave(sDIB,sharingDelay,(Bit16u)0); + } void DOS_InfoBlock::SetFirstMCB(Bit16u _firstmcb) { - sSave(sDIB,firstMCB,RealMake(_firstmcb,0)); + sSave(sDIB,firstMCB,_firstmcb); //c2woody } void DOS_InfoBlock::SetfirstFileTable(RealPt _first_table){ diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index ad991798..a8a17dc2 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id */ +/* $Id: dos_execute.cpp,v 1.35 2004-02-28 16:35:14 qbix79 Exp $ */ #include #include "dosbox.h" @@ -298,6 +298,9 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { else memsize=maxsize; if (!DOS_AllocateMemory(&pspseg,&memsize)) E_Exit("DOS:Exec error in memory"); loadseg=pspseg+16; + if ((!iscom) & (head.minmemory == 0) & (head.maxmemory == 0)) + loadseg = (0x9fed0 - imagesize)/16; //c2woody + } else loadseg=block.overlay.loadseg; /* Load the executable */ Bit8u * loadbuf=(Bit8u *)new Bit8u[0x10000]; diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 25f93c08..c733044d 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.18 2004-01-10 14:03:34 qbix79 Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.19 2004-02-28 16:35:14 qbix79 Exp $ */ #include #include "dosbox.h" @@ -97,6 +97,10 @@ bool DOS_IOCTL(void) { mem_writew(ptr+2,drive>=2); // nonremovable ? mem_writew(ptr+4,0x0000); // num of cylinders mem_writeb(ptr+6,0x00); // media type (00=other type) + // drive parameter block following + mem_writeb(ptr+7,drive); // drive + mem_writeb(ptr+8,0x00); // unit number + mem_writed(ptr+0x1f,0xffffffff); // next parameter block break; default : LOG(LOG_IOCTL,LOG_ERROR)("DOS:IOCTL Call 0D:%2X Drive %2X unhandled",reg_cl,drive); diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 93d2554d..3dadda1b 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -57,6 +57,9 @@ void DOS_SetupTables(void) { mem_writeb(Real2Phys(dos.tables.indosflag),0); /* Create the DOS Info Block */ dos_infoblock.SetLocation(DOS_GetMemory(1+(sizeof(DOS_InfoBlock::sDIB)/16))); +// dos_infoblock.SetLocation(0x4e); //c2woody +/* The above lines might be switched around when working on certain programs */ + /* Create a fake SFT, so programs think there are 100 file handles */ seg=DOS_GetMemory(1); real_writed(seg,0,0xffffffff); //Last File Table From 5ec076438e2fbea5e5a8dd45cb8dc1c382b74ecb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 29 Feb 2004 21:55:49 +0000 Subject: [PATCH 1608/4131] Setup correct equipment list for different machine types Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1690 --- src/ints/bios.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 4f328978..65e5ecc6 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.28 2004-01-26 14:08:16 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.29 2004-02-29 21:55:49 harekiet Exp $ */ #include #include "dosbox.h" @@ -396,11 +396,22 @@ void BIOS_Init(Section* sec) { if (IO_Read(0x3f8)!=0xff) real_writew(0x40,(index++)*2,0x3f8); if (IO_Read(0x2f8)!=0xff) real_writew(0x40,(index++)*2,0x2f8); /* Setup equipment list */ + Bitu config=0x4400; //1 Floppy, 2 serial and 1 parrallel #if (C_FPU) - mem_writew(BIOS_CONFIGURATION,0xc823); //1 Floppy,FPU,2 serial, 1 parallel -#else - mem_writew(BIOS_CONFIGURATION,0xc821); //1 Floppy,FPU,2 serial, 1 parallel + config|=0x2; #endif + switch (machine) { + case MCH_HERC: + config|=0x30; //Startup monochrome + break; + case MCH_CGA: case MCH_TANDY: + config|=0x20; //STartup 80x25 color + break; + default: + config|=0; //EGA VGA + break; + } + mem_writew(BIOS_CONFIGURATION,config); /* Setup extended memory size */ IO_Write(0x70,0x30); size_extended=IO_Read(0x71); From f7c4b4699159a66faa0275aedde185d1fa8b8317 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 29 Feb 2004 22:18:24 +0000 Subject: [PATCH 1609/4131] Added MC6845 display controller support for hercules,cga,tandy machine modes. Added cga,tandy,text modes. Added some new tandy modes. Added better tandy register support. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1691 --- include/vga.h | 38 ++- src/hardware/Makefile.am | 2 +- src/hardware/vga.cpp | 56 ++++- src/hardware/vga_attr.cpp | 19 +- src/hardware/vga_crtc.cpp | 11 +- src/hardware/vga_dac.cpp | 36 ++- src/hardware/vga_draw.cpp | 283 +++++++++++++--------- src/hardware/vga_gfx.cpp | 27 ++- src/hardware/vga_memory.cpp | 47 ++-- src/hardware/vga_misc.cpp | 270 ++------------------- src/hardware/vga_other.cpp | 308 ++++++++++++++++++++++++ src/hardware/vga_seq.cpp | 11 +- src/ints/int10.cpp | 2 +- src/ints/int10.h | 3 +- src/ints/int10_char.cpp | 19 +- src/ints/int10_memory.cpp | 6 +- src/ints/int10_misc.cpp | 4 +- src/ints/int10_modes.cpp | 464 +++++++++++++++++++++--------------- src/ints/int10_vesa.cpp | 14 +- 19 files changed, 953 insertions(+), 667 deletions(-) create mode 100644 src/hardware/vga_other.cpp diff --git a/include/vga.h b/include/vga.h index 9046683a..ad35b712 100644 --- a/include/vga.h +++ b/include/vga.h @@ -23,13 +23,13 @@ #include "dosbox.h" enum VGAModes { - M_TEXT2,M_TEXT16, - M_HERC, - M_CGA2,M_CGA4,M_CGA16, - M_TANDY16, - M_EGA2,M_EGA4,M_EGA16, + M_TEXT, + M_HERC_GFX,M_HERC_TEXT, + M_CGA2,M_CGA4, + M_EGA16, M_VGA, M_LIN8, + M_CGA16,M_TANDY2,M_TANDY4,M_TANDY16,M_TANDY_TEXT, M_ERROR, }; @@ -161,18 +161,28 @@ typedef struct { } VGA_HERC; typedef struct { - Bit8u mode_control; - Bit8u color_select; -} VGA_CGA; + Bit8u index; + Bit8u htotal; + Bit8u hdend; + Bit8u hsyncp; + Bit8u hsyncw; + Bit8u vtotal; + Bit8u vdend; + Bit8u vadjust; + Bit8u vsyncp; + Bit8u vsyncw; + Bit8u max_scanline; +} VGA_OTHER; typedef struct { + Bit8u mode_control; + Bit8u color_select; Bit8u mem_bank; Bit8u disp_bank; Bit8u reg_index; - Bit8u mode_control1; + Bit8u gfx_control; Bit8u palette_mask; Bit8u border_color; - Bit8u mode_control2; } VGA_TANDY; typedef struct { @@ -255,7 +265,6 @@ typedef struct { Bit8u read_index; Bitu first_changed; RGBEntry rgb[0x100]; - Bit8u attr[16]; } VGA_Dac; union VGA_Latch { @@ -284,8 +293,8 @@ typedef struct { VGA_Latch latch; VGA_S3 s3; VGA_HERC herc; - VGA_CGA cga; VGA_TANDY tandy; + VGA_OTHER other; VGA_Memory mem; } VGA_Type; @@ -293,6 +302,7 @@ typedef struct { /* Functions for different resolutions */ void VGA_SetMode(VGAModes mode); +void VGA_DetermineMode(void); void VGA_SetupHandlers(void); void VGA_StartResize(void); void VGA_SetupDrawing(Bitu val); @@ -300,6 +310,7 @@ void VGA_CheckScanLength(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 */ @@ -310,6 +321,7 @@ void VGA_SetupCRTC(void); void VGA_SetupMisc(void); void VGA_SetupGFX(void); void VGA_SetupSEQ(void); +void VGA_SetupOther(void); /* Some Support Functions */ void VGA_SetClock(Bitu which,Bitu target); @@ -317,6 +329,8 @@ 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); extern VGA_Type vga; diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index ccc692d2..6335846b 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -6,7 +6,7 @@ noinst_LIBRARIES = libhardware.a libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler.cpp joystick.cpp keyboard.cpp \ memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ - vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp \ + vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp vga_other.cpp \ vga_memory.cpp vga_misc.cpp vga_seq.cpp font-switch.h ega-switch.h cmos.cpp disney.cpp \ gus.cpp mpu401.cpp serialport.cpp softmodem.cpp ipx.cpp ipxserver.cpp diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 3b9c3255..bf06e9e3 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -48,6 +48,20 @@ void VGA_SetMode(VGAModes mode) { VGA_StartResize(); } +void VGA_DetermineMode(void) { + /* Test for graphics or alphanumeric mode */ + if (vga.attr.mode_control & 1) { + if (!(vga.crtc.mode_control & 0x1)) { + if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4); + else VGA_SetMode(M_CGA2); + } else if (vga.attr.mode_control & 0x40) { + VGA_SetMode(M_VGA); + } else VGA_SetMode(M_EGA16); + } else { + VGA_SetMode(M_TEXT); + } +} + void VGA_StartResize(void) { if (!vga.draw.resizing) { vga.draw.resizing=true; @@ -88,34 +102,56 @@ void VGA_SetClock(Bitu which,Bitu target) { VGA_StartResize(); } +void VGA_SetCGA2Table(Bit8u val0,Bit8u val1) { + Bit8u total[2]={ val0,val1}; + for (Bitu i=0;i<16;i++) { + CGA_2_Table[i]= +#ifdef WORDS_BIGENDIAN + (total[(i >> 0) & 1] << 0 ) | (total[(i >> 1) & 1] << 8 ) | + (total[(i >> 2) & 1] << 16 ) | (total[(i >> 3) & 1] << 24 ); +#else + (total[(i >> 3) & 1] << 0 ) | (total[(i >> 2) & 1] << 8 ) | + (total[(i >> 1) & 1] << 16 ) | (total[(i >> 0) & 1] << 24 ); +#endif + } +} + +void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3) { + Bit8u total[4]={ val0,val1,val2,val3}; + for (Bitu i=0;i<256;i++) { + CGA_4_Table[i]= +#ifdef WORDS_BIGENDIAN + (total[(i >> 0) & 3] << 0 ) | (total[(i >> 2) & 3] << 8 ) | + (total[(i >> 4) & 3] << 16 ) | (total[(i >> 6) & 3] << 24 ); +#else + (total[(i >> 6) & 3] << 0 ) | (total[(i >> 4) & 3] << 8 ) | + (total[(i >> 2) & 3] << 16 ) | (total[(i >> 0) & 3] << 24 ); +#endif + } +} void VGA_Init(Section* sec) { vga.draw.resizing=false; + vga.mode=M_ERROR; //For first init VGA_SetupMemory(); VGA_SetupMisc(); VGA_SetupDAC(); VGA_SetupGFX(); VGA_SetupSEQ(); VGA_SetupAttr(); + VGA_SetupOther(); VGA_SetClock(0,CLK_25); VGA_SetClock(1,CLK_28); /* Generate tables */ + VGA_SetCGA2Table(0,1); + VGA_SetCGA4Table(0,1,2,3); Bitu i,j; for (i=0;i<256;i++) { ExpandTable[i]=i | (i << 8)| (i <<16) | (i << 24); -#ifdef WORDS_BIGENDIAN - CGA_4_Table[i]=((i>>0)&3) | (((i>>2)&3) << 8)| (((i>>4)&3) <<16) | (((i>>6)&3) << 24); -#else - CGA_4_Table[i]=((i>>6)&3) | (((i>>4)&3) << 8)| (((i>>2)&3) <<16) | (((i>>0)&3) << 24); - - -#endif } for (i=0;i<16;i++) { TXT_FG_Table[i]=i | (i << 8)| (i <<16) | (i << 24); TXT_BG_Table[i]=i | (i << 8)| (i <<16) | (i << 24); - #ifdef WORDS_BIGENDIAN - CGA_2_Table[i]=((i>>0)&1) | (((i>>1)&1) << 8)| (((i>>1)&1) <<16) | (((i>>3)&1) << 24); FillTable[i]= ((i & 1) ? 0xff000000 : 0) | ((i & 2) ? 0x00ff0000 : 0) | @@ -127,7 +163,6 @@ void VGA_Init(Section* sec) { ((i & 4) ? 0x00ff0000 : 0) | ((i & 8) ? 0xff000000 : 0) ; #else - CGA_2_Table[i]=((i>>3)&1) | (((i>>2)&1) << 8)| (((i>>1)&1) <<16) | (((i>>0)&1) << 24); FillTable[i]= ((i & 1) ? 0x000000ff : 0) | ((i & 2) ? 0x0000ff00 : 0) | @@ -138,7 +173,6 @@ void VGA_Init(Section* sec) { ((i & 2) ? 0x00ff0000 : 0) | ((i & 4) ? 0x0000ff00 : 0) | ((i & 8) ? 0x000000ff : 0) ; - #endif } for (j=0;j<4;j++) { diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index a486344e..b57e9ca4 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -23,7 +23,6 @@ #define attr(blah) vga.attr.blah void VGA_ATTR_SetPalette(Bit8u index,Bit8u val) { - vga.attr.palette[index]=val; if (vga.attr.mode_control & 0x80) val=(val&0xf) | (vga.attr.color_select << 4); else val|=(vga.attr.color_select & 0xc) << 4; VGA_DAC_CombineColor(index,val); @@ -69,16 +68,9 @@ void write_p3c0(Bit32u port,Bit8u val) { Doesn't work if they program EGA16 themselves, but haven't encountered that yet */ - if (val&0x40) { - if (vga.mode0x7) vga.config.pel_panning=0; else vga.config.pel_panning=val+1; @@ -196,8 +187,10 @@ Bit8u read_p3c1(Bit32u port) { void VGA_SetupAttr(void) { - IO_RegisterWriteHandler(0x3c0,write_p3c0,"VGA Attribute controller"); - IO_RegisterReadHandler(0x3c1,read_p3c1,"VGA Attribute Read"); + if (machine==MCH_VGA) { + IO_RegisterWriteHandler(0x3c0,write_p3c0,"VGA Attribute controller"); + IO_RegisterReadHandler(0x3c1,read_p3c1,"VGA Attribute Read"); + } } diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 23ca0959..d9f0b1fb 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -22,19 +22,17 @@ #include "debug.h" #include "cpu.h" - #define crtc(blah) vga.crtc.blah -void write_p3d4(Bit32u port,Bit8u val) { +void write_p3d4_vga(Bit32u port,Bit8u val) { crtc(index)=val; } -Bit8u read_p3d4(Bit32u port) { +Bit8u read_p3d4_vga(Bit32u port) { return crtc(index); } - -void write_p3d5(Bit32u port,Bit8u val) { +void write_p3d5_vga(Bit32u port,Bit8u val) { // if (crtc(index)>0x18) LOG_MSG("VGA CRCT write %X to reg %X",val,crtc(index)); switch(crtc(index)) { case 0x00: /* Horizontal Total Register */ @@ -256,6 +254,7 @@ void write_p3d5(Bit32u port,Bit8u val) { break; case 0x17: /* Mode Control Register */ crtc(mode_control)=val; + VGA_DetermineMode(); /* 0 If clear use CGA compatible memory addressing system by substituting character row scan counter bit 0 for address bit 13, @@ -495,7 +494,7 @@ void write_p3d5(Bit32u port,Bit8u val) { } } -Bit8u read_p3d5(Bit32u port) { +Bit8u read_p3d5_vga(Bit32u port) { // LOG_MSG("VGA CRCT read from reg %X",crtc(index)); switch(crtc(index)) { case 0x00: /* Horizontal Total Register */ diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index 1c8c1250..bddd699c 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -105,7 +105,7 @@ static void write_p3c9(Bit32u port,Bit8u val) { default: /* Check for attributes and DAC entry link */ for (Bitu i=0;i<16;i++) { - if (vga.dac.attr[i]==vga.dac.write_index) { + if (vga.attr.palette[i]==vga.dac.write_index) { RENDER_SetPal(i, vga.dac.rgb[vga.dac.write_index].red << 2, vga.dac.rgb[vga.dac.write_index].green << 2, @@ -145,7 +145,7 @@ static Bit8u read_p3c9(Bit32u port) { void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal) { /* Check if this is a new color */ - vga.dac.attr[attr]=pal; + vga.attr.palette[attr]=pal; switch (vga.mode) { case M_VGA: case M_LIN8: @@ -159,6 +159,20 @@ void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal) { } } +void VGA_DAC_SetEntry(Bitu entry,Bit8u red,Bit8u green,Bit8u blue) { + vga.dac.rgb[entry].red=red; + vga.dac.rgb[entry].green=green; + vga.dac.rgb[entry].blue=blue; + switch (vga.mode) { + case M_VGA: + case M_LIN8: + return; + } + for (Bitu i=0;i<16;i++) + if (vga.attr.palette[i]==entry) + RENDER_SetPal(i,red << 2,green << 2,blue << 2); +} + void VGA_SetupDAC(void) { vga.dac.first_changed=256; vga.dac.bits=6; @@ -167,14 +181,16 @@ void VGA_SetupDAC(void) { vga.dac.state=DAC_READ; vga.dac.read_index=0; vga.dac.write_index=0; - /* Setup the DAC IO port Handlers */ - IO_RegisterWriteHandler(0x3c6,write_p3c6,"PEL Mask"); - IO_RegisterReadHandler(0x3c6,read_p3c6,"PEL Mask"); - IO_RegisterWriteHandler(0x3c7,write_p3c7,"PEL Read Mode"); - IO_RegisterReadHandler(0x3c7,read_p3c7,"PEL Status Mode"); - IO_RegisterWriteHandler(0x3c8,write_p3c8,"PEL Write Mode"); - IO_RegisterWriteHandler(0x3c9,write_p3c9,"PEL Data"); - IO_RegisterReadHandler(0x3c9,read_p3c9,"PEL Data"); + if (machine==MCH_VGA) { + /* Setup the DAC IO port Handlers */ + IO_RegisterWriteHandler(0x3c6,write_p3c6,"PEL Mask"); + IO_RegisterReadHandler(0x3c6,read_p3c6,"PEL Mask"); + IO_RegisterWriteHandler(0x3c7,write_p3c7,"PEL Read Mode"); + IO_RegisterReadHandler(0x3c7,read_p3c7,"PEL Status Mode"); + IO_RegisterWriteHandler(0x3c8,write_p3c8,"PEL Write Mode"); + IO_RegisterWriteHandler(0x3c9,write_p3c9,"PEL Data"); + IO_RegisterReadHandler(0x3c9,read_p3c9,"PEL Data"); + } }; diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 90c65a91..85308500 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -30,18 +30,8 @@ typedef Bit8u * (* VGA_Line_Handler)(Bitu vidstart,Bitu panning,Bitu line); static VGA_Line_Handler VGA_DrawLine; -static Bit8u * VGA_HERC_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { - Bit8u * reader=&vga.mem.linear[vidstart+(line * 8 * 1024)]; - Bit32u * draw=(Bit32u *)RENDER_TempLine; - for (Bitu x=vga.draw.blocks;x>0;x--) { - Bitu val=*reader++; - *draw++=CGA_2_Table[val >> 4]; - *draw++=CGA_2_Table[val & 0xf]; - } - return RENDER_TempLine; -} -static Bit8u * VGA_CGA2_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { +static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { line*=8*1024;Bit32u * draw=(Bit32u *)RENDER_TempLine; for (Bitu x=vga.draw.blocks;x>0;x--) { Bitu val=vga.mem.linear[vidstart+line];vidstart=(vidstart+1)&0x1fff; @@ -51,7 +41,7 @@ static Bit8u * VGA_CGA2_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { return RENDER_TempLine; } -static Bit8u * VGA_CGA4_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { +static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { line*=8*1024;Bit32u * draw=(Bit32u *)RENDER_TempLine; for (Bitu x=0;x> 4] | convert16[val & 0xf] << 16; - *draw++=full|=full<<8; - } - return RENDER_TempLine; -} - -static Bit8u * VGA_TANDY16_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { +static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { Bit8u * reader=&vga.mem.linear[(vga.tandy.disp_bank << 14) + vidstart + (line * 8 * 1024)]; Bit32u * draw=(Bit32u *)RENDER_TempLine; for (Bitu x=0;x> 4 | + (val2 & 0x0f) << 24 | + (val2 & 0xf0) << 12; + } + return RENDER_TempLine; +} + + +static Bit8u * VGA_Draw_EGA_Line(Bitu vidstart,Bitu panning,Bitu line) { return &vga.mem.linear[512*1024+vidstart*8+panning]; } -static Bit8u * VGA_VGA_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { +static Bit8u * VGA_Draw_VGA_Line(Bitu vidstart,Bitu panning,Bitu line) { return &vga.mem.linear[vidstart*4+panning]; } @@ -163,11 +156,11 @@ void VGA_SetBlinking(Bitu enabled) { if (enabled) { b=0;vga.draw.blinking=1; //used to -1 but blinking is unsigned vga.attr.mode_control|=0x08; - vga.cga.mode_control&=~0x20; + vga.tandy.mode_control&=~0x20; } else { b=8;vga.draw.blinking=0; vga.attr.mode_control&=~0x08; - vga.cga.mode_control|=0x20; + vga.tandy.mode_control|=0x20; } for (Bitu i=0;i<8;i++) TXT_BG_Table[i+8]=(b+i) | ((b+i) << 8)| ((b+i) <<16) | ((b+i) << 24); } @@ -183,7 +176,7 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.split_line=vga.draw.lines_total-(vga.config.line_compare/vga.draw.lines_scaled); vga.draw.panning=vga.config.pel_panning; switch (vga.mode) { - case M_TEXT2:case M_TEXT16: + case M_TEXT: vga.draw.cursor.count++; /* check for blinking and blinking change delay */ FontMask[1]=(vga.attr.mode_control & (vga.draw.cursor.count >> 1) & 0x8) ? @@ -206,57 +199,98 @@ void VGA_CheckScanLength(void) { case M_LIN8: vga.draw.address_add=vga.config.scan_len*2; break; - case M_CGA2:case M_CGA4:case M_CGA16: - vga.draw.address_add=80; - break; - case M_TANDY16: - vga.draw.address_add=160; - break; - case M_TEXT16: - case M_TEXT2: + case M_TEXT: vga.draw.address_add=vga.config.scan_len*4; break; - case M_HERC: + case M_CGA2: + case M_CGA4: + vga.draw.address_add=80; + return; + case M_TANDY2: + vga.draw.address_add=vga.draw.blocks/4; + break; + case M_TANDY4: + vga.draw.address_add=vga.draw.blocks/2; + break; + case M_CGA16: + vga.draw.address_add=vga.draw.blocks/2; + return; + case M_TANDY16: + vga.draw.address_add=vga.draw.blocks; + break; + case M_TANDY_TEXT: + vga.draw.address_add=vga.draw.blocks*2; + break; + case M_HERC_TEXT: + vga.draw.address_add=vga.draw.blocks*2; + break; + case M_HERC_GFX: vga.draw.address_add=vga.draw.blocks; break; } } void VGA_SetupDrawing(Bitu val) { - /* Calculate the FPS for this screen */ - double fps; - Bitu vtotal=2 + vga.crtc.vertical_total | - ((vga.crtc.overflow & 1) << 8) | ((vga.crtc.overflow & 0x20) << 4); - Bitu htotal=5 + vga.crtc.horizontal_total; - Bitu vdispend = 1 + (vga.crtc.vertical_display_end | - ((vga.crtc.overflow & 2)<<7) | ((vga.crtc.overflow & 0x40) << 3) | - ((vga.s3.ex_ver_overflow & 0x2) << 9)); - Bitu hdispend = 1 + (vga.crtc.horizontal_display_end); - - Bitu hbstart = vga.crtc.start_horizontal_blanking; - Bitu vbstart = vga.crtc.start_vertical_blanking | ((vga.crtc.overflow & 0x08) << 5) | - ((vga.crtc.maximum_scan_line & 0x20) << 4) ; - - Bitu hrstart = vga.crtc.start_horizontal_retrace; - Bitu vrstart = vga.crtc.vertical_retrace_start + ((vga.crtc.overflow & 0x04) << 6) | - ((vga.crtc.overflow & 0x80) << 2); - - if (hbstart> 2) & 3; - clock=1000*S3_CLOCK(vga.s3.clk[clock].m,vga.s3.clk[clock].n,vga.s3.clk[clock].r); - /* Check for 8 for 9 character clock mode */ - if (vga.seq.clocking_mode & 1 ) clock/=8; else clock/=9; - /* Check for pixel doubling, master clock/2 */ - if (vga.seq.clocking_mode & 0x8) { - htotal*=2; + if (vga.mode==M_ERROR) { + PIC_RemoveEvents(VGA_VerticalTimer); + PIC_RemoveEvents(VGA_VerticalDisplayEnd); + return; + } + /* Calculate the FPS for this screen */ + double fps;Bitu clock; + Bitu htotal,hdispend,hbstart,hrstart; + Bitu vtotal,vdispend,vbstart,vrstart; + if (machine==MCH_VGA) { + vtotal=2 + vga.crtc.vertical_total | + ((vga.crtc.overflow & 1) << 8) | ((vga.crtc.overflow & 0x20) << 4); + htotal=5 + vga.crtc.horizontal_total; + vdispend = 1 + (vga.crtc.vertical_display_end | + ((vga.crtc.overflow & 2)<<7) | ((vga.crtc.overflow & 0x40) << 3) | + ((vga.s3.ex_ver_overflow & 0x2) << 9)); + hdispend = 1 + (vga.crtc.horizontal_display_end); + hbstart = vga.crtc.start_horizontal_blanking; + vbstart = vga.crtc.start_vertical_blanking | ((vga.crtc.overflow & 0x08) << 5) | + ((vga.crtc.maximum_scan_line & 0x20) << 4) ; + hrstart = vga.crtc.start_horizontal_retrace; + vrstart = vga.crtc.vertical_retrace_start + ((vga.crtc.overflow & 0x04) << 6) | + ((vga.crtc.overflow & 0x80) << 2); + if (hbstart> 2) & 3; + clock=1000*S3_CLOCK(vga.s3.clk[clock].m,vga.s3.clk[clock].n,vga.s3.clk[clock].r); + /* Check for 8 for 9 character clock mode */ + if (vga.seq.clocking_mode & 1 ) clock/=8; else clock/=9; + /* Check for pixel doubling, master clock/2 */ + if (vga.seq.clocking_mode & 0x8) { + htotal*=2; + } + vga.draw.font_height=(vga.crtc.maximum_scan_line&0xf)+1; + /* Check for dual transfer whatever thing,master clock/2 */ + if (vga.s3.pll.cmd & 0x10) clock/=2; + } else { + vga.draw.font_height=vga.other.max_scanline+1; + htotal=vga.other.htotal; + hdispend=vga.other.hdend; + hrstart=vga.other.hsyncp; + vtotal=vga.draw.font_height*vga.other.vtotal+vga.other.vadjust; + vdispend=vga.draw.font_height*vga.other.vdend; + vrstart=vga.draw.font_height*vga.other.vsyncp; + switch (machine) { + case MCH_CGA: + case MCH_TANDY: + clock=((vga.tandy.mode_control & 1) ? 14318180 : (14318180/2))/8; + break; + case MCH_HERC: + if (vga.herc.mode_control & 0x2) clock=14318180/16; + else clock=14318180/8; + break; + } } - /* Check for dual transfer whatever thing,master clock/2 */ - if (vga.s3.pll.cmd & 0x10) clock/=2; - LOG(LOG_VGA,LOG_NORMAL)("H total %d, V Total %d",htotal,vtotal); LOG(LOG_VGA,LOG_NORMAL)("H D End %d, V D End %d",hdispend,vdispend); + if (!htotal) return; + if (!vtotal) return; fps=clock/(vtotal*htotal); double linemicro=(1000000/fps); vga.draw.parts_total=VGA_PARTS; @@ -279,86 +313,103 @@ void VGA_SetupDrawing(Bitu val) { width=hdispend; height=vdispend; vga.draw.double_scan=false; - vga.draw.font_height=(vga.crtc.maximum_scan_line&0xf)+1; switch (vga.mode) { case M_VGA: - scalew=2; - scaleh*=vga.draw.font_height; + scalew=2;scaleh*=vga.draw.font_height; if (vga.crtc.maximum_scan_line&0x80) scaleh*=2; vga.draw.lines_scaled=scaleh; - height/=scaleh; - width<<=2; vga.draw.address_line_total=1; - VGA_DrawLine=VGA_VGA_Draw_Line; + height/=scaleh;width<<=2; + VGA_DrawLine=VGA_Draw_VGA_Line; break; case M_LIN8: - width<<=3; scaleh*=vga.draw.font_height; vga.draw.lines_scaled=scaleh; vga.draw.address_line_total=1; - VGA_DrawLine=VGA_VGA_Draw_Line; + width<<=3; + VGA_DrawLine=VGA_Draw_VGA_Line; break; case M_EGA16: - width<<=3; scaleh*=vga.draw.font_height; if (vga.crtc.maximum_scan_line&0x80) scaleh*=2; vga.draw.lines_scaled=scaleh; - height/=scaleh; if (vga.seq.clocking_mode & 0x8) scalew*=2; + width<<=3;height/=scaleh; vga.draw.address_line_total=1; - VGA_DrawLine=VGA_EGA_Draw_Line; + VGA_DrawLine=VGA_Draw_EGA_Line; break; case M_CGA4: - case M_CGA16: //Let is use 320x200 res and double pixels myself - scaleh=2;scalew=2; - vga.draw.blocks=width; - width<<=2; - height/=2; + scaleh=2;scalew*=2; + vga.draw.blocks=width*2; vga.draw.lines_scaled=1; vga.draw.address_line_total=2; - VGA_DrawLine=(vga.mode == M_CGA4) ? VGA_CGA4_Draw_Line : VGA_CGA16_Draw_Line; + width<<=3;height/=2; + VGA_DrawLine=VGA_Draw_2BPP_Line; break; case M_CGA2: - scaleh=2;height/=2; - vga.draw.address_line_total=2; + scaleh=2; vga.draw.blocks=width; - width<<=3; + vga.draw.lines_scaled=1; vga.draw.address_line_total=2; - vga.draw.lines_scaled=1; - VGA_DrawLine=VGA_CGA2_Draw_Line; + width<<=4;height/=2; + VGA_DrawLine=VGA_Draw_1BPP_Line; break; - case M_HERC: - vga.draw.address_line_total=4; - width*=9; - vga.draw.blocks=width/8; - vga.draw.lines_scaled=1; - height=348; - aspect_ratio=1.5; - VGA_DrawLine=VGA_HERC_Draw_Line; - break; - case M_TANDY16: - scaleh=2;scalew=2; - vga.draw.blocks=width*2; - vga.draw.address_line_total=4; - vga.draw.lines_scaled=1; - width<<=2;height/=2; - VGA_DrawLine=VGA_TANDY16_Draw_Line; - break; - case M_TEXT2: - case M_TEXT16: + case M_TEXT: aspect_ratio=1.0; - if (vga.draw.font_height<4 && (machine640) width=640; - if (height>480) height=480; + VGA_DrawLine=VGA_TEXT_Draw_Line; + break; + case M_HERC_GFX: + aspect_ratio=1.5; + vga.draw.address_line_total=vga.draw.font_height; + vga.draw.blocks=width*2; + vga.draw.lines_scaled=1; + width*=16; + VGA_DrawLine=VGA_Draw_1BPP_Line; + break; + case M_TANDY2: + scaleh=2;aspect_ratio=1.2; + scalew=(vga.tandy.mode_control & 0x10) ? 1 : 2; + vga.draw.blocks=width*8/scalew; + vga.draw.address_line_total=vga.draw.font_height; + vga.draw.lines_scaled=1; + width=vga.draw.blocks*2; + VGA_DrawLine=VGA_Draw_1BPP_Line; + break; + case M_TANDY4: + scaleh=2;aspect_ratio=1.2; + scalew=(vga.tandy.mode_control & 0x10) ? 1 : 2; + vga.draw.blocks=width*8/scalew; + vga.draw.address_line_total=vga.draw.font_height; + vga.draw.lines_scaled=1; + width=vga.draw.blocks*2; + VGA_DrawLine=VGA_Draw_2BPP_Line; + break; + case M_TANDY16: + scaleh=2;aspect_ratio=1.2; + scalew=(vga.tandy.mode_control & 0x10) ? 1 : 2; + vga.draw.blocks=width*4/scalew; + vga.draw.address_line_total=vga.draw.font_height; + vga.draw.lines_scaled=1; + width=vga.draw.blocks*2; + VGA_DrawLine=VGA_Draw_4BPP_Line; + break; + case M_TANDY_TEXT: + scalew=(vga.tandy.mode_control & 0x1) ? 1 : 2; + case M_HERC_TEXT: + aspect_ratio=1; + scaleh=(vga.mode==M_HERC_TEXT) ? 1 : 2; + vga.draw.lines_scaled=1; + vga.draw.address_line_total=vga.draw.font_height; + vga.draw.blocks=width; + vga.draw.lines_scaled=1; + width<<=3; VGA_DrawLine=VGA_TEXT_Draw_Line; break; default: diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index 2498c26f..3af56b43 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -20,19 +20,18 @@ #include "inout.h" #include "vga.h" - #define gfx(blah) vga.gfx.blah static bool index9warned=false; -void write_p3ce(Bit32u port,Bit8u val) { +static void write_p3ce(Bit32u port,Bit8u val) { gfx(index)=val & 0x0f; } -Bit8u read_p3ce(Bit32u port) { +static Bit8u read_p3ce(Bit32u port) { return gfx(index); } -void write_p3cf(Bit32u port,Bit8u val) { +static void write_p3cf(Bit32u port,Bit8u val) { switch (gfx(index)) { case 0: /* Set/Reset Register */ gfx(set_reset)=val & 0x0f; @@ -92,8 +91,11 @@ void write_p3cf(Bit32u port,Bit8u val) { vga.config.read_map_select=val & 0x03; // LOG_DEBUG("Read Map %2X",val); break; - case 5: /* Mode Register */ /* Important one very */ - gfx(mode)=val; + case 5: /* Mode Register */ + if ((gfx(mode) ^ val) & 0xf0) { + gfx(mode)=val; + VGA_DetermineMode(); + } else gfx(mode)=val; vga.config.write_mode=val & 3; vga.config.read_mode=(val >> 3) & 1; // LOG_DEBUG("Write Mode %d Read Mode %d val %d",vga.config.write_mode,vga.config.read_mode,val); @@ -134,7 +136,6 @@ void write_p3cf(Bit32u port,Bit8u val) { 4 Enables Odd/Even mode if set (See 3C4h index 4 bit 2). 5 Enables CGA style 4 color pixels using even/odd bit pairs if set. 6 Enables 256 color mode if set. - */ break; case 6: /* Miscellaneous Register */ @@ -183,7 +184,7 @@ void write_p3cf(Bit32u port,Bit8u val) { } } -Bit8u read_p3cf(Bit32u port) { +static Bit8u read_p3cf(Bit32u port) { switch (gfx(index)) { case 0: /* Set/Reset Register */ return gfx(set_reset); @@ -212,10 +213,12 @@ Bit8u read_p3cf(Bit32u port) { void VGA_SetupGFX(void) { - IO_RegisterWriteHandler(0x3ce,write_p3ce,"VGA Graphics Index"); - IO_RegisterWriteHandler(0x3cf,write_p3cf,"VGA Graphics Data"); - IO_RegisterReadHandler(0x3ce,read_p3ce,"Vga Graphics Index"); - IO_RegisterReadHandler(0x3cf,read_p3cf,"Vga Graphics Data"); + if (machine==MCH_VGA) { + IO_RegisterWriteHandler(0x3ce,write_p3ce,"VGA Graphics Index"); + IO_RegisterWriteHandler(0x3cf,write_p3cf,"VGA Graphics Data"); + IO_RegisterReadHandler(0x3ce,read_p3ce,"Vga Graphics Index"); + IO_RegisterReadHandler(0x3cf,read_p3cf,"Vga Graphics Data"); + } } diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index a0ade8be..b26679b8 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -247,11 +247,17 @@ public: class VGA_TANDY_PageHandler : public PageHandler { public: VGA_TANDY_PageHandler() { - flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; + flags=PFLAG_READABLE|PFLAG_WRITEABLE; +// |PFLAG_NOCODE; } HostPt GetHostPt(Bitu phys_page) { - phys_page-=vgapages.map_base; - return &vga.mem.linear[(vga.tandy.mem_bank << 14)+(phys_page * 4096)]; + if (phys_page>=0xb8) { + phys_page-=0xb8; + return &vga.mem.linear[(vga.tandy.mem_bank << 14)+(phys_page * 4096)]; + } else { + phys_page-=0x80; + return &vga.mem.linear[phys_page * 4096]; + } } }; @@ -268,7 +274,22 @@ static struct { void VGA_SetupHandlers(void) { PageHandler * range_handler; + switch (machine) { + case MCH_CGA: + range_handler=&vgaph.hmap; + goto range_b800; + case MCH_HERC: + range_handler=&vgaph.hmap; + if (vga.herc.mode_control&0x80) goto range_b800; + else goto range_b000; + case MCH_TANDY: + range_handler=&vgaph.htandy; + MEM_SetPageHandler(0x80,32,range_handler); + goto range_b800; + } switch (vga.mode) { + case M_ERROR: + return; case M_LIN8: range_handler=&vgaph.hmap; break; @@ -282,29 +303,15 @@ void VGA_SetupHandlers(void) { case M_EGA16: range_handler=&vgaph.h16; break; - case M_TEXT2: - case M_TEXT16: + case M_TEXT: /* Check if we're not in odd/even mode */ - if (vga.gfx.miscellaneous & 0x2) { - range_handler=&vgaph.hmap; - } else { - range_handler=&vgaph.htext; - } + if (vga.gfx.miscellaneous & 0x2) range_handler=&vgaph.hmap; + else range_handler=&vgaph.htext; break; - case M_TANDY16: - range_handler=&vgaph.htandy; - break; - case M_CGA16: case M_CGA4: case M_CGA2: range_handler=&vgaph.hmap; break; - case M_HERC: - range_handler=&vgaph.hmap; - if (vga.herc.mode_control&0x80) goto range_b800; - else goto range_b000; - default: - LOG_MSG("Unhandled vga mode %X",vga.mode); } switch ((vga.gfx.miscellaneous >> 2) & 3) { case 0: diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 9ee6148f..012647ca 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -20,26 +20,25 @@ #include "inout.h" #include "pic.h" #include "vga.h" -#include "../ints/int10.h" static Bit8u flip=0; -void write_p3d4(Bit32u port,Bit8u val); -Bit8u read_p3d4(Bit32u port); -void write_p3d5(Bit32u port,Bit8u val); -Bit8u read_p3d5(Bit32u port); +void write_p3d4_vga(Bit32u port,Bit8u val); +Bit8u read_p3d4_vga(Bit32u port); +void write_p3d5_vga(Bit32u port,Bit8u val); +Bit8u read_p3d5_vga(Bit32u port); -static void write_p3d9(Bit32u port,Bit8u val); +void write_p3d4_cga(Bit32u port,Bit8u val); +Bit8u read_p3d4_cga(Bit32u port); +void write_p3d5_cga(Bit32u port,Bit8u val); +Bit8u read_p3d5_cga(Bit32u port); static Bit8u read_p3da(Bit32u port) { vga.internal.attrindex=false; if (vga.config.retrace) { - switch (vga.mode) { - case M_HERC: + switch (machine) { + case MCH_HERC: return 0x81; - case M_TEXT2: - if (machine==MCH_HERC) return 0x81; - if (machine==MCH_AUTO) return 0x89; default: return 9; } @@ -54,182 +53,14 @@ static Bit8u read_p3da(Bit32u port) { */ } -static void write_p3d8(Bit32u port,Bit8u val) { - /* Check if someone changes the blinking/hi intensity bit */ - switch (machine) { - case MCH_AUTO: - VGA_SetBlinking((val & 0x20)); - switch (vga.mode) { - case M_CGA2: - case M_CGA4: - case M_CGA16: - goto m_cga; - } - break; - case MCH_CGA: - VGA_SetBlinking((val & 0x20)); -m_cga: - if (val & 0x2) { - if (val & 0x10) { - if (val & 0x8) { - VGA_SetMode(M_CGA16); //Video burst 16 160x200 color mode - } else { - VGA_SetMode(M_CGA2); - } - } else VGA_SetMode(M_CGA4); - write_p3d9(0x3d9,vga.cga.color_select); //Setup the correct palette - } else { - VGA_SetMode(M_TEXT16); - } - vga.cga.mode_control=val; - break; - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("Write %2X to 3d8 in mode %d",val,vga.mode); - } - /* - 3 Vertical Sync Select. If set Vertical Sync to the monitor is the - logical OR of the vertical sync and the vertical display enable. - */ -} - -static void write_p3d9(Bit32u port,Bit8u val) { - Bitu i; - vga.cga.color_select=val; - switch (vga.mode) { - case M_CGA2: - /* changes attribute 1 */ - VGA_ATTR_SetPalette(0,0); - VGA_ATTR_SetPalette(1,val & 0xf); - break; - case M_CGA4: - /* changes attribute 0 */ - { - VGA_ATTR_SetPalette(0,(val & 0xf)); - Bit8u pal_base=(val & 0x10) ? 0x08 : 0; - /* Check for BW Mode */ - if (vga.cga.mode_control & 0x4) { - if (val & 0x20) { - VGA_ATTR_SetPalette(1,0x03+pal_base); - VGA_ATTR_SetPalette(2,0x04+pal_base); - VGA_ATTR_SetPalette(3,0x07+pal_base); - } else { - //TODO Maybe? will anyone ever use, - //will also need to setup a BW palette,but could put it behind normal cga... - VGA_ATTR_SetPalette(1,0x02+pal_base); - VGA_ATTR_SetPalette(2,0x04+pal_base); - VGA_ATTR_SetPalette(3,0x06+pal_base); - } - } else { - if (val & 0x20) { - VGA_ATTR_SetPalette(1,0x03+pal_base); - VGA_ATTR_SetPalette(2,0x05+pal_base); - VGA_ATTR_SetPalette(3,0x07+pal_base); - } else { - VGA_ATTR_SetPalette(1,0x02+pal_base); - VGA_ATTR_SetPalette(2,0x04+pal_base); - VGA_ATTR_SetPalette(3,0x06+pal_base); - } - } - } - break; - case M_CGA16: - for(i=0;i<0x10;i++) VGA_ATTR_SetPalette(i,i); - break; - case M_TEXT16: - /* Assume a normal text palette has been set */ -// VGA_ATTR_SetPalette(0,(val & 0x8) ? ((val & 7)+32) : (val &7)); - break; - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to %X in mode %d",val,port,vga.mode); - } -} - -static void write_p3da(Bit32u port,Bit8u val) { - if (machine==MCH_TANDY) goto tandy_3da; - switch (vga.mode) { - case M_TANDY16: -tandy_3da: - vga.tandy.reg_index=val; - break; - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to %X in mode %d",val,port,vga.mode); - break; - - } -} - - -static void write_p3de(Bit32u port,Bit8u val) { - if (machine==MCH_TANDY) goto tandy_3de; - switch (vga.mode) { - case M_TANDY16: -tandy_3de: - switch (vga.tandy.reg_index) { - case 0x2: /* Border color */ - vga.tandy.border_color=val; - break; - /* palette colors */ - case 0x10: case 0x11: case 0x12: case 0x13: - case 0x14: case 0x15: case 0x16: case 0x17: - case 0x18: case 0x19: case 0x1a: case 0x1b: - case 0x1c: case 0x1d: case 0x1e: case 0x1f: - VGA_ATTR_SetPalette(vga.tandy.reg_index-0x10,val & 0xf); - break; - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index); - } - break; - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to %X in mode %d",val,port,vga.mode); - break; - } -} - -static void write_p3df(Bit32u port,Bit8u val) { - if (machine==MCH_TANDY) goto tandy_3df; - switch (vga.mode) { - case M_TANDY16: -tandy_3df: - vga.tandy.disp_bank=val & ((val & 0x80) ? 0x6 : 0x7); - vga.tandy.mem_bank=(val >> 3) & ((val & 0x80) ? 0x6 : 0x7); - VGA_SetupHandlers(); - break; - /* - 0-2 Identifies the page of main memory being displayed in units of 16K. - 0: 0K, 1: 16K...7: 112K. In 32K modes (bits 6-7 = 2) only 0,2,4 and - 6 are valid, as the next page will also be used. - 3-5 Identifies the page of main memory that can be read/written at B8000h - in units of 16K. 0: 0K, 1: 16K...7: 112K. In 32K modes (bits 6-7 = 2) - only 0,2,4 and 6 are valid, as the next page will also be used. - 6-7 Display mode. 0: Text, 1: 16K graphics mode (4,5,6,8) - 2: 32K graphics mode (9,Ah) - */ - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to %X in mode %d",val,port,vga.mode); - break; - } -} - -static Bit8u read_p3d9(Bit32u port) { - switch (machine) { - case MCH_AUTO: - case MCH_CGA: - case MCH_TANDY: - return vga.cga.color_select; - default: - return 0xff; - }; -} - static void write_p3c2(Bit32u port,Bit8u val) { vga.misc_output=val; - if (val & 0x1) { - IO_RegisterWriteHandler(0x3d4,write_p3d4,"VGA:CRTC Index Select"); - IO_RegisterReadHandler(0x3d4,read_p3d4,"VGA:CRTC Index Select"); - IO_RegisterWriteHandler(0x3d5,write_p3d5,"VGA:CRTC Data Register"); - IO_RegisterReadHandler(0x3d5,read_p3d5,"VGA:CRTC Data Register"); + IO_RegisterWriteHandler(0x3d4,write_p3d4_vga,"VGA:CRTC Index Select"); + IO_RegisterReadHandler(0x3d4,read_p3d4_vga,"VGA:CRTC Index Select"); + IO_RegisterWriteHandler(0x3d5,write_p3d5_vga,"VGA:CRTC Data Register"); + IO_RegisterReadHandler(0x3d5,read_p3d5_vga,"VGA:CRTC Data Register"); IO_RegisterReadHandler(0x3da,read_p3da,"VGA Input Status 1"); IO_FreeWriteHandler(0x3b4); @@ -238,10 +69,10 @@ static void write_p3c2(Bit32u port,Bit8u val) { IO_FreeReadHandler(0x3b5); IO_FreeReadHandler(0x3ba); } else { - IO_RegisterWriteHandler(0x3b4,write_p3d4,"VGA:CRTC Index Select"); - IO_RegisterReadHandler(0x3b4,read_p3d4,"VGA:CRTC Index Select"); - IO_RegisterWriteHandler(0x3b5,write_p3d5,"VGA:CRTC Data Register"); - IO_RegisterReadHandler(0x3b5,read_p3d5,"VGA:CRTC Data Register"); + IO_RegisterWriteHandler(0x3b4,write_p3d4_vga,"VGA:CRTC Index Select"); + IO_RegisterReadHandler(0x3b4,read_p3d4_vga,"VGA:CRTC Index Select"); + IO_RegisterWriteHandler(0x3b5,write_p3d5_vga,"VGA:CRTC Data Register"); + IO_RegisterReadHandler(0x3b5,read_p3d5_vga,"VGA:CRTC Data Register"); IO_RegisterReadHandler(0x3ba,read_p3da,"VGA Input Status 1"); IO_FreeWriteHandler(0x3d4); @@ -269,67 +100,16 @@ static Bit8u read_p3cc(Bit32u port) { } -static void write_hercules(Bit32u port,Bit8u val) { - switch (port) { - case 0x3b8: - vga.herc.mode_control=(vga.herc.mode_control & ~0x7d) | (val&0x7d); - if ((vga.herc.enable_bits & 1) && ((vga.herc.mode_control ^ val)&0x2)) { - vga.herc.mode_control^=0x2; - if (vga.mode != M_HERC || vga.mode != M_TEXT2) { - VGA_ATTR_SetPalette(0,0x00); - VGA_ATTR_SetPalette(1,0x07); - - /* Force 0x3b4/5 registers */ - if (vga.misc_output & 1) write_p3c2(0,vga.misc_output & ~1); - } - if (val & 0x2) { - if (vga.mode != M_HERC) VGA_SetMode(M_HERC); - } else { - if (vga.mode != M_TEXT2) VGA_SetMode(M_TEXT2); - } - } - if ((vga.herc.enable_bits & 0x2) && ((vga.herc.mode_control ^ val)&0x80)) { - vga.herc.mode_control^=0x80; - VGA_SetupHandlers(); - } - break; - case 0x3bf: - vga.herc.enable_bits=val; - break; - default: - LOG_MSG("write %x to Herc port %x",val,port); - } -} - -static Bit8u read_hercules(Bit32u port) { - switch (port) { - case 0x3b8: - default: - LOG_MSG("read from Herc port %x",port); - } - return 0; -} - - - void VGA_SetupMisc(void) { - vga.herc.enable_bits=0; - IO_RegisterWriteHandler(0x3d8,write_p3d8,"VGA Feature Control Register"); - IO_RegisterWriteHandler(0x3d9,write_p3d9,"CGA Color Select Register"); - IO_RegisterReadHandler(0x3d9,read_p3d9,"CGA Color Select Register"); - - IO_RegisterWriteHandler(0x3c2,write_p3c2,"VGA Misc Output"); - IO_RegisterReadHandler(0x3cc,read_p3cc,"VGA Misc Output"); - - if (machine==MCH_HERC || machine==MCH_AUTO) { - vga.herc.mode_control=0x8; - IO_RegisterWriteHandler(0x3b8,write_hercules,"Hercules"); - IO_RegisterWriteHandler(0x3bf,write_hercules,"Hercules"); + if (machine==MCH_VGA) { + IO_RegisterWriteHandler(0x3c2,write_p3c2,"VGA Misc Output"); + IO_RegisterReadHandler(0x3cc,read_p3cc,"VGA Misc Output"); + } else if (machine==MCH_CGA || machine==MCH_TANDY) { + IO_RegisterReadHandler(0x3da,read_p3da,"VGA Input Status 1"); + } else if (machine==MCH_HERC) { + IO_RegisterReadHandler(0x3ba,read_p3da,"VGA Input Status 1"); } - IO_RegisterWriteHandler(0x3de,write_p3de,"PCJR Reg Write"); - IO_RegisterWriteHandler(0x3df,write_p3df,"PCJR Bank Select"); - IO_RegisterWriteHandler(0x3da,write_p3da,"PCJR Reg Select"); } diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp new file mode 100644 index 00000000..da3fe693 --- /dev/null +++ b/src/hardware/vga_other.cpp @@ -0,0 +1,308 @@ +/* + * Copyright (C) 2002-2004 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include "dosbox.h" +#include "inout.h" +#include "vga.h" + +static void write_crtc_index_other(Bit32u port,Bit8u val) { + vga.other.index=val; +} + +static Bit8u read_crtc_index_other(Bit32u port) { + return vga.other.index; +} + +static void write_crtc_data_other(Bit32u port,Bit8u val) { + switch (vga.other.index) { + case 0x00: //Horizontal total + if (vga.other.htotal ^ val) VGA_StartResize(); + vga.other.htotal=val; + break; + case 0x01: //Horizontal displayed chars + if (vga.other.hdend ^ val) VGA_StartResize(); + vga.other.hdend=val; + break; + case 0x02: //Horizontal sync position + vga.other.hsyncp=val; + break; + case 0x03: //Horizontal sync width + vga.other.hsyncw=val; + break; + case 0x04: //Vertical total + if (vga.other.vtotal ^ val) VGA_StartResize(); + vga.other.vtotal=val; + break; + case 0x05: //Vertical display adjust + if (vga.other.vadjust ^ val) VGA_StartResize(); + vga.other.vadjust=val; + break; + case 0x06: //Vertical rows + if (vga.other.vdend ^ val) VGA_StartResize(); + vga.other.vdend=val; + break; + case 0x07: //Vertical sync position + vga.other.vsyncp=val; + break; + case 0x09: //Max scanline + if (vga.other.max_scanline ^ val) VGA_StartResize(); + vga.other.max_scanline=val; + break; + vga.config.display_start=(vga.config.display_start & 0xFF00FF)| (val << 8); + break; + case 0x0C: /* Start Address High Register */ + vga.config.display_start=(vga.config.display_start & 0xFF00FF)| (val << 8); + break; + case 0x0D: /* Start Address Low Register */ + vga.config.display_start=(vga.config.display_start & 0xFFFF00)| val; + break; + case 0x0E: /*Cursor Location High Register */ + vga.config.cursor_start&=0xff00ff; + vga.config.cursor_start|=val << 8; + break; + case 0x0F: /* Cursor Location Low Register */ + vga.config.cursor_start&=0xffff00; + vga.config.cursor_start|=val; + break; + default: + LOG_MSG("Write %X to illgal index %x",val,vga.other.index); + } +} +static Bit8u read_crtc_data_other(Bit32u port) { + switch (vga.other.index) { + case 0x00: //Horizontal total + return vga.other.htotal; + case 0x01: //Horizontal displayed chars + return vga.other.hdend; + case 0x02: //Horizontal sync position + return vga.other.hsyncp; + case 0x03: //Horizontal sync width + return vga.other.hsyncw; + case 0x04: //Vertical total + return vga.other.vtotal; + case 0x05: //Vertical display adjust + return vga.other.vadjust; + case 0x06: //Vertical rows + return vga.other.vdend; + case 0x07: //Vertical sync position + return vga.other.vsyncp; + case 0x09: //Max scanline + return vga.other.max_scanline; + case 0x0C: /* Start Address High Register */ + return vga.config.display_start >> 8; + case 0x0D: /* Start Address Low Register */ + return vga.config.display_start; + case 0x0E: /*Cursor Location High Register */ + return vga.config.cursor_start>>8; + case 0x0F: /* Cursor Location Low Register */ + return vga.config.cursor_start; + default: + LOG_MSG("Read from illgal index %x",vga.other.index); + } +} + +static void write_color_select(Bit8u val) { + vga.tandy.color_select=val; + switch (vga.mode) { + case M_TANDY2: + VGA_SetCGA2Table(0,val & 0xf); + break; + case M_TANDY4: + { + if (machine == MCH_TANDY && (vga.tandy.gfx_control & 0x8)) { + VGA_SetCGA4Table(0,1,2,3); + return; + } + Bit8u base=(val & 0x10) ? 0x08 : 0; + /* Check for BW Mode */ + if (vga.tandy.mode_control & 0x4) { + if (val & 0x20) VGA_SetCGA4Table(val & 0xf,3+base,4+base,7+base); + else VGA_SetCGA4Table(val & 0xf,2+base,4+base,6+base); + } else { + if (val & 0x20) VGA_SetCGA4Table(val & 0xf,3+base,5+base,7+base); + else VGA_SetCGA4Table(val & 0xf,2+base,4+base,6+base); + } + } + break; + case M_CGA16: + case M_TEXT: + case M_TANDY16: + break; + } +} + +static void write_mode_control(Bit8u val) { + /* Check if someone changes the blinking/hi intensity bit */ + vga.tandy.mode_control=val; + VGA_SetBlinking((val & 0x20)); + if (val & 0x2) { + if (val & 0x10) { + if (val & 0x8) { + VGA_SetMode(M_CGA16); //Video burst 16 160x200 color mode + } else { + VGA_SetMode(M_CGA2); + } + } else VGA_SetMode(M_CGA4); + write_color_select(vga.tandy.color_select); //Setup the correct palette + } else { + VGA_SetMode(M_TEXT); + } +} + +static void TANDY_FindMode(void) { + if (vga.tandy.mode_control & 0x2) { + if (vga.tandy.gfx_control & 0x10) VGA_SetMode(M_TANDY16); + else if (vga.tandy.gfx_control & 0x08) VGA_SetMode(M_TANDY4); + else if (vga.tandy.mode_control & 0x10) VGA_SetMode(M_TANDY2); + else VGA_SetMode(M_TANDY4); + write_color_select(vga.tandy.color_select); + } else { + VGA_SetMode(M_TANDY_TEXT); + } +} + +static void write_tandy_reg(Bit8u val) { + switch (vga.tandy.reg_index) { + case 0x2: /* Border color */ + vga.tandy.border_color=val; + break; + case 0x3: /* More control */ + vga.tandy.gfx_control=val; + TANDY_FindMode(); + break; + /* palette colors */ + case 0x10: case 0x11: case 0x12: case 0x13: + case 0x14: case 0x15: case 0x16: case 0x17: + case 0x18: case 0x19: case 0x1a: case 0x1b: + case 0x1c: case 0x1d: case 0x1e: case 0x1f: + VGA_ATTR_SetPalette(vga.tandy.reg_index-0x10,val & 0xf); + break; + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index); + } +} + +static void write_cga(Bit32u port,Bit8u val) { + switch (port) { + case 0x3d8: + vga.tandy.mode_control=val; + if (vga.tandy.mode_control & 0x2) { + if (vga.tandy.mode_control & 0x10) { + VGA_SetMode(M_TANDY2); + } else VGA_SetMode(M_TANDY4); + write_color_select(vga.tandy.color_select); + } else { + VGA_SetMode(M_TANDY_TEXT); + } + break; + case 0x3d9: + write_color_select(val); + break; + } +} + +static void write_tandy(Bit32u port,Bit8u val) { + switch (port) { + case 0x3d8: + vga.tandy.mode_control=val; + TANDY_FindMode(); + break; + case 0x3d9: + write_color_select(val); + break; + case 0x3da: + vga.tandy.reg_index=val; + break; + case 0x3de: + write_tandy_reg(val); + break; + case 0x3df: + vga.tandy.disp_bank=val & ((val & 0x80) ? 0x6 : 0x7); + vga.tandy.mem_bank=(val >> 3) & ((val & 0x80) ? 0x6 : 0x7); + VGA_SetupHandlers(); + break; + } +} + +static void write_hercules(Bit32u port,Bit8u val) { + switch (port) { + case 0x3b8: + if (vga.herc.enable_bits & 1) { + vga.herc.mode_control&=~0x2; + vga.herc.mode_control|=(val&0x2); + if (val & 0x2) { + VGA_SetMode(M_HERC_GFX); + } else { + VGA_SetMode(M_HERC_TEXT); + } + } + if ((vga.herc.enable_bits & 0x2) && ((vga.herc.mode_control ^ val)&0x80)) { + vga.herc.mode_control^=0x80; + VGA_SetupHandlers(); + } + break; + case 0x3bf: + vga.herc.enable_bits=val; + break; + } +} + +static Bit8u read_hercules(Bit32u port) { + LOG_MSG("read from Herc port %x",port); + return 0; +} + + +void VGA_SetupOther(void) { + Bitu i; + if (machine==MCH_CGA || machine==MCH_TANDY) { + extern Bit8u int10_font_08[256 * 8]; + for (i=0;i<256;i++) memcpy(&vga.draw.font[i*32],&int10_font_08[i*8],8); + } + if (machine==MCH_HERC) { + extern Bit8u int10_font_14[256 * 14]; + for (i=0;i<256;i++) memcpy(&vga.draw.font[i*32],&int10_font_14[i*14],14); + } + if (machine==MCH_CGA) { + IO_RegisterWriteBHandler(0x3d8,write_cga); + IO_RegisterWriteBHandler(0x3d9,write_cga); + } + if (machine==MCH_HERC) { + vga.herc.enable_bits=0; + vga.herc.mode_control=0x8; + IO_RegisterWriteBHandler(0x3b8,write_hercules); + IO_RegisterWriteBHandler(0x3bf,write_hercules); + } + if (machine==MCH_TANDY) { + IO_RegisterWriteBHandler(0x3d8,write_tandy); + IO_RegisterWriteBHandler(0x3d9,write_tandy); + IO_RegisterWriteBHandler(0x3de,write_tandy); + IO_RegisterWriteBHandler(0x3df,write_tandy); + IO_RegisterWriteBHandler(0x3da,write_tandy); + } + if (machine==MCH_CGA || machine==MCH_HERC || machine==MCH_TANDY) { + Bitu base=machine==MCH_HERC ? 0x3b4 : 0x3d4; + IO_RegisterWriteBHandler(base,write_crtc_index_other); + IO_RegisterWriteBHandler(base+1,write_crtc_data_other); + IO_RegisterReadBHandler(base,read_crtc_index_other); + IO_RegisterReadBHandler(base+1,read_crtc_data_other); + } + +} + diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 1ab8cc1a..53b284a4 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -167,10 +167,11 @@ Bit8u read_p3c5(Bit32u port) { void VGA_SetupSEQ(void) { - IO_RegisterWriteHandler(0x3c4,write_p3c4,"VGA:Sequencer Index"); - IO_RegisterWriteHandler(0x3c5,write_p3c5,"VGA:Sequencer Data"); - IO_RegisterReadHandler(0x3c4,read_p3c4,"VGA:Sequencer Index"); - IO_RegisterReadHandler(0x3c5,read_p3c5,"VGA:Sequencer Data"); - + if (machine==MCH_VGA) { + IO_RegisterWriteHandler(0x3c4,write_p3c4,"VGA:Sequencer Index"); + IO_RegisterWriteHandler(0x3c5,write_p3c5,"VGA:Sequencer Data"); + IO_RegisterReadHandler(0x3c4,read_p3c4,"VGA:Sequencer Index"); + IO_RegisterReadHandler(0x3c5,read_p3c5,"VGA:Sequencer Data"); + } } diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 0e5bc636..2c362415 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -445,7 +445,7 @@ static void SetupTandyBios(void) { void INT10_Init(Section* sec) { INT10_InitVGA(); - if (machine==MCH_TANDY || machine==MCH_AUTO) SetupTandyBios(); + if (machine==MCH_TANDY) SetupTandyBios(); /* Setup the INT 10 vector */ call_10=CALLBACK_Allocate(); CALLBACK_Setup(call_10,&INT10_Handler,CB_IRET); diff --git a/src/ints/int10.h b/src/ints/int10.h index 417def0c..3172fe38 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -104,11 +104,10 @@ struct VideoModeBlock { Bitu htotal,vtotal; Bitu hdispend,vdispend; - Bitu rate; Bitu special; }; -extern VideoModeBlock ModeList[]; +extern VideoModeBlock ModeList_VGA[]; extern VideoModeBlock * CurMode; typedef struct { diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 4a4e97b3..64e2a0f2 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.22 2004-01-28 18:04:18 harekiet Exp $ */ +/* $Id: int10_char.cpp,v 1.23 2004-02-29 22:18:24 harekiet Exp $ */ /* Character displaying moving functions */ @@ -174,7 +174,7 @@ static INLINE void TEXT_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,B void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit8u attr,Bit8u page) { /* Do some range checking */ - if (CurMode->type>M_TEXT16) page=0xff; + if (CurMode->type!=M_TEXT) page=0xff; BIOS_NCOLS;BIOS_NROWS; if(rul>rlr) return; if(cul>clr) return; @@ -204,8 +204,7 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit while (start!=end) { start+=next; switch (CurMode->type) { - case M_TEXT2: - case M_TEXT16: + case M_TEXT: TEXT_CopyRow(cul,clr,start,start+nlines,base);break; case M_CGA2: CGA2_CopyRow(cul,clr,start,start+nlines,base);break; @@ -229,8 +228,7 @@ filling: } for (;nlines>0;nlines--) { switch (CurMode->type) { - case M_TEXT2: - case M_TEXT16: + case M_TEXT: TEXT_FillRow(cul,clr,start,base,attr);break; case M_CGA2: CGA2_FillRow(cul,clr,start,base,attr);break; @@ -363,8 +361,7 @@ static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool Bitu x,y; Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); switch (CurMode->type) { - case M_TEXT2: - case M_TEXT16: + case M_TEXT: { // Compute the address Bit16u address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); @@ -410,7 +407,7 @@ static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) { //TODO Check if this page thing is correct - if (CurMode->type>M_TEXT16) page=0xff; + if (CurMode->type!=M_TEXT) page=0xff; if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); @@ -474,12 +471,12 @@ void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr) { void INT10_TeletypeOutput(Bit8u chr,Bit8u attr) { - INT10_TeletypeOutputAttr(chr,attr,CurMode->type>M_TEXT16); + INT10_TeletypeOutputAttr(chr,attr,CurMode->type!=M_TEXT); } void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,Bit16u count,Bit8u page) { //TODO Check if this page thing is correct - if (CurMode->type>M_TEXT16) page=0xff; + if (CurMode->type!=M_TEXT) page=0xff; if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); BIOS_NCOLS;BIOS_NROWS; diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index ceb725f6..fc686fda 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -80,8 +80,10 @@ void INT10_SetupRomMemory(void) { PhysPt rom_base=PhysMake(0xc000,0); Bitu i; int10.rom.used=3; // int10.rom.used=2; Size of ROM added - phys_writew(rom_base+0,0xaa55); - phys_writeb(rom_base+2,0x40); // Size of ROM: 64 512-blocks = 32KB + if (machine==MCH_VGA) { + phys_writew(rom_base+0,0xaa55); + phys_writeb(rom_base+2,0x40); // Size of ROM: 64 512-blocks = 32KB + } int10.rom.font_8_first=RealMake(0xC000,int10.rom.used); for (i=0;i<128*8;i++) { phys_writeb(rom_base+int10.rom.used++,int10_font_08[i]); diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 3afefc06..b6a25ec9 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -91,10 +91,8 @@ void INT10_GetFuncStateInformation(PhysPt save) { mem_writeb(save+0x25,real_readb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX)); Bit16u col_count=0; switch (CurMode->type) { - case M_TEXT16: + case M_TEXT: col_count=16;break; - case M_TEXT2: - col_count=2;break; // ?? case M_CGA2: col_count=2;break; case M_CGA4: diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index d0a4d475..afb07a62 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -5,6 +5,7 @@ #include "inout.h" #include "int10.h" #include "mouse.h" +#include "vga.h" #define _EGA_HALF_CLOCK 0x0001 #define _EGA_LINE_DOUBLE 0x0002 @@ -13,41 +14,55 @@ #define GFX_REGS 0x09 #define ATT_REGS 0x15 -VideoModeBlock ModeList[]={ -/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde ,rate,special flags */ -{ 0x000 ,M_TEXT16 ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,70 ,_EGA_HALF_CLOCK }, -{ 0x001 ,M_TEXT16 ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,70 ,_EGA_HALF_CLOCK }, -{ 0x002 ,M_TEXT16 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,70 ,0 }, -{ 0x003 ,M_TEXT16 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,70 ,0 }, -{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,60 ,0 }, -{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,60 ,0}, -{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,60 ,0 }, -{ 0x007 ,M_TEXT2 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,70 ,0 }, -/* 8,9,0xa are tandy modes */ -{ 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,100 ,449 ,80 ,400 ,60 ,0}, - -{ 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,70 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, -{ 0x00E ,M_EGA16 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,70 ,_EGA_LINE_DOUBLE }, -{ 0x00F ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,400 ,70 ,0 },/*was EGA_2*/ -{ 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,1 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,70 ,0 }, -{ 0x011 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,449 ,80 ,480 ,70 ,0 },/*was EGA_2 */ -{ 0x012 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,70 ,0 }, -{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,70 ,0 }, +VideoModeBlock ModeList_VGA[]={ +/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */ +{ 0x000 ,M_TEXT ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, +{ 0x001 ,M_TEXT ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, +{ 0x002 ,M_TEXT ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x003 ,M_TEXT ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, +{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, +{ 0x007 ,M_TEXT ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, -{ 0x100 ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,70 ,0 }, -{ 0x101 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,70 ,0 }, -{ 0x103 ,M_LIN8 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,70 ,0 }, +{ 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, +{ 0x00E ,M_EGA16 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE }, +{ 0x00F ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,400 ,0 },/*was EGA_2*/ +{ 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,1 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, +{ 0x011 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,449 ,80 ,480 ,0 },/*was EGA_2 */ +{ 0x012 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, +{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x100 ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, +{ 0x101 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, +{ 0x103 ,M_LIN8 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, -{ 0x150 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,70 , 0}, -{ 0x151 ,M_LIN8 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,70 , 0}, -{ 0x152 ,M_LIN8 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,70 , 0 }, -{ 0x153 ,M_LIN8 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,70 , 0 }, - -{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 ,0 }, +{ 0x150 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , 0}, +{ 0x151 ,M_LIN8 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , 0}, +{ 0x152 ,M_LIN8 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , 0 }, +{ 0x153 ,M_LIN8 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , 0 }, +{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, }; +VideoModeBlock ModeList_OTHER[]={ +/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde ,special flags */ +{ 0x000 ,M_TEXT ,320 ,400 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x0800 ,56 ,31 ,40 ,25 ,0 }, +{ 0x001 ,M_TEXT ,320 ,400 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x0800 ,56 ,31 ,40 ,25 ,0 }, +{ 0x002 ,M_TEXT ,640 ,400 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x1000 ,113 ,31 ,80 ,25 ,0 }, +{ 0x003 ,M_TEXT ,640 ,400 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x1000 ,113 ,31 ,80 ,25 ,0 }, +{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,56 ,127 ,40 ,100 ,0 }, +{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,56 ,127 ,40 ,100 ,0 }, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,56 ,127 ,40 ,100 ,0 }, +{ 0x008 ,M_TANDY16,160 ,200 ,20 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,56 ,127 ,40 ,100 ,0 }, +{ 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,113 ,63 ,80 ,50 ,0 }, +{ 0x00A ,M_CGA4 ,640 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,113 ,63 ,80 ,50 ,0 }, +{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, +}; + +VideoModeBlock Hercules_Mode= +{ 0x007 ,M_TEXT ,640 ,400 ,80 ,25 ,8 ,14 ,4 ,0xB0000 ,0x1000 ,97 ,25 ,80 ,25 ,0 }; + static Bit8u text_palette[64][3]= { {0x00,0x00,0x00},{0x00,0x00,0x2a},{0x00,0x2a,0x00},{0x00,0x2a,0x2a},{0x2a,0x00,0x00},{0x2a,0x00,0x2a},{0x2a,0x2a,0x00},{0x2a,0x2a,0x2a}, @@ -72,18 +87,10 @@ static Bit8u ega_palette[64][3]= {0x15,0x15,0x15}, {0x15,0x15,0x3f}, {0x15,0x3f,0x15}, {0x15,0x3f,0x3f}, {0x3f,0x15,0x15}, {0x3f,0x15,0x3f}, {0x3f,0x3f,0x15}, {0x3f,0x3f,0x3f} }; -#if 0 -static Bit8u cga_palette[64][3]= { - {0x00,0x00,0x00}, {0x00,0x00,0x1f}, {0x00,0x1f,0x00}, {0x00,0x1f,0x1f}, {0x1f,0x00,0x00}, {0x1f,0x00,0x1f}, {0x1f,0x1f,0x00}, {0x1f,0x1f,0x1f}, - {0x0f,0x0f,0x0f}, {0x00,0x00,0x3f}, {0x00,0x3f,0x00}, {0x00,0x3f,0x3f}, {0x3f,0x00,0x00}, {0x3f,0x00,0x3f}, {0x3f,0x3f,0x00}, {0x3f,0x3f,0x3f}, -}; -#else static Bit8u cga_palette[16][3]= { {0x00,0x00,0x00}, {0x00,0x00,0x2a}, {0x00,0x2a,0x00}, {0x00,0x2a,0x2a}, {0x2a,0x00,0x00}, {0x2a,0x00,0x2a}, {0x2a,0x15,0x00}, {0x2a,0x2a,0x2a}, {0x15,0x15,0x15}, {0x15,0x15,0x3f}, {0x15,0x3f,0x15}, {0x15,0x3f,0x3f}, {0x3f,0x15,0x15}, {0x3f,0x15,0x3f}, {0x3f,0x3f,0x15}, {0x3f,0x3f,0x3f}, }; -#endif - static Bit8u vga_palette[256][3]= { @@ -126,31 +133,205 @@ static Bit8u vga_palette[256][3]= VideoModeBlock * CurMode; -bool INT10_SetVideoMode(Bitu mode) { - - - bool clearmem=true; - Bit8u modeset_ctl,video_ctl,vga_switches; - - if (mode<256) { - if (mode & 128) { - clearmem=false; - mode-=128; - } - } else { - /* Check for special vesa mode bits */ - mode&=0xfff; - } - LOG(LOG_INT10,LOG_NORMAL)("Set Video Mode %X",mode); +static bool SetCurMode(VideoModeBlock modeblock[],Bitu mode) { Bitu i=0; - while (ModeList[i].mode!=0xffff) { - if (ModeList[i].mode==mode) goto foundmode; + while ( modeblock[i].mode!=0xffff) { + if ( modeblock[i].mode==mode) goto foundmode; i++; } - LOG(LOG_INT10,LOG_ERROR)("Trying to set illegal mode %X",mode); return false; foundmode: - CurMode=&ModeList[i]; + CurMode=&modeblock[i]; + return true; +} + + +static void FinishSetMode(bool clearmem) { + Bitu i; + /* Clear video memory if needs be */ + if (clearmem) { + switch (CurMode->type) { + case M_CGA4: + case M_CGA2: + for (i=0;i<16*1024;i++) { + real_writew(0xb800,i*2,0x0000); + } + break; + case M_TEXT: + if (CurMode->mode==7) for (i=0;i<16*1024;i++) { + real_writew(0xb000,i*2,0x0120); + } else for (i=0;i<16*1024;i++) { + real_writew(0xb800,i*2,0x0720); + } + break; + case M_EGA16: + case M_VGA: + case M_LIN8: + /* Just clear the whole 2 mb of memory */ + for (i=0;i<2*1024*1024/4;i++) { + mem_writed(S3_LFB_BASE+i*4,0); + } + } + } + /* Setup the BIOS */ + if (CurMode->mode<128) real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,CurMode->mode); + else real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,CurMode->mode-0x98); //Looks like the s3 bios + real_writew(BIOSMEM_SEG,BIOSMEM_NB_COLS,CurMode->twidth); + real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,CurMode->plength); + real_writew(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,CurMode->mode==7 ? 0x3b4 : 0x3d4); + real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,CurMode->theight-1); + real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,CurMode->cheight); + real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem << 7))); + real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0x09); + real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); + + // FIXME We nearly have the good tables. to be reworked + real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08); // 8 is VGA should be ok for now + real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER,0x00); + real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2,0x00); + + // Set cursor shape + if(CurMode->type==M_TEXT) { + INT10_SetCursorShape(0x06,07); + } + // Set cursor pos for page 0..7 + for(i=0;i<8;i++) INT10_SetCursorPos(0,0,(Bit8u)i); + // Set active page 0 + INT10_SetActivePage(0); + /* Set some interrupt vectors */ + switch (CurMode->cheight) { + case 8:RealSetVec(0x43,int10.rom.font_8_first);break; + case 14:RealSetVec(0x43,int10.rom.font_14);break; + case 16:RealSetVec(0x43,int10.rom.font_16);break; + } + /* Tell mouse resolution change */ + Mouse_NewVideoMode(); +} + +bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { + Bitu i; + switch (machine) { + case MCH_CGA: + if (mode>6) return false; + case MCH_TANDY: + if (mode>0xa) return false; + if (!SetCurMode(ModeList_OTHER,mode)) { + LOG(LOG_INT10,LOG_ERROR)("Trying to set illegal mode %X",mode); + return false; + } + break; + case MCH_HERC: + if (mode!=7) return false; + CurMode=&Hercules_Mode; + break; + } + LOG(LOG_INT10,LOG_NORMAL)("Set Video Mode %X",mode); + + /* Setup the VGA to the correct mode */ +// VGA_SetMode(CurMode->type); + /* Setup the CRTC */ + Bitu crtc_base=machine==MCH_HERC ? 0x3b4 : 0x3d4; + //Horizontal total + IO_WriteW(crtc_base,0x00 | (CurMode->htotal) << 8); + //Horizontal displayed + IO_WriteW(crtc_base,0x01 | (CurMode->hdispend) << 8); + //Horizontal sync position + IO_WriteW(crtc_base,0x02 | (CurMode->hdispend+1) << 8); + //Horizontal sync width, seems to be fixed to 0xa, for cga at least, hercules has 0xf + IO_WriteW(crtc_base,0x03 | (0xa) << 8); + ////Vertical total + IO_WriteW(crtc_base,0x04 | (CurMode->vtotal) << 8); + //Vertical total adjust, 6 for cga,hercules,tandy + IO_WriteW(crtc_base,0x05 | (6) << 8); + //Vertical displayed + IO_WriteW(crtc_base,0x06 | (CurMode->vdispend) << 8); + //Vertical sync position + IO_WriteW(crtc_base,0x07 | (CurMode->vdispend+1) << 8); + //Maximum scanline + Bit8u scanline; + switch(CurMode->type) { + case M_TEXT: + if (machine==MCH_HERC) scanline=14; + else scanline=8; + break; + case M_CGA2: + scanline=2; + case M_CGA4: + if (CurMode->mode!=0xa) scanline=2; + else scanline=4; + case M_TANDY16: + if (CurMode->mode!=0x9) scanline=2; + else scanline=4; + break; + } + IO_WriteW(crtc_base,0x09 | (scanline-1) << 8); + //Setup the CGA palette using VGA DAC palette + for (i=0;i<16;i++) VGA_DAC_SetEntry(i,cga_palette[i][0],cga_palette[i][1],cga_palette[i][2]); + //Setup the tandy palette + for (i=0;i<16;i++) VGA_DAC_CombineColor(i,i); + //Setup the special registers for each machine type + Bit8u mode_control_list[0xa+1]={ + 0x2c,0x28,0x2d,0x29, //0-3 + 0x2a,0x2e,0x1e,0x29, //4-7 + 0x2a,0x2b,0x3b //8-a + }; + Bit8u mode_control,color_select; + switch (machine) { + case MCH_HERC: + IO_WriteB(0x3bf,0x3); //Enable changing all bits + IO_WriteB(0x3b8,0x8); //TEXT mode and non-blinking characters + IO_WriteB(0x3bf,0x0); //Disable changing all bits + VGA_DAC_CombineColor(1,0xf); + break; + case MCH_CGA: + mode_control=mode_control_list[CurMode->mode]; + if (CurMode->mode == 0x6) color_select=0x3f; + else color_select=0x30; + IO_WriteB(0x3d8,mode_control); + IO_WriteB(0x3d9,color_select); + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,mode_control); + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select); + break; + case MCH_TANDY: + /* Init some registers */ + IO_WriteB(0x3da,0x1);IO_WriteB(0x3de,0xf); //Palette mask always 0xf + IO_WriteB(0x3da,0x2);IO_WriteB(0x3de,0x0); //block border + IO_WriteB(0x3da,0x3); //Tandy color overrides? + switch (CurMode->mode) { + case 0x8: case 0x9: + IO_WriteB(0x3de,0x14);break; + case 0xa: + IO_WriteB(0x3de,0x0c);break; + default: + IO_WriteB(0x3de,0x0);break; + } + mode_control=mode_control_list[CurMode->mode]; + if (CurMode->mode == 0x6 || CurMode->mode==0xa) color_select=0x3f; + else color_select=0x30; + IO_WriteB(0x3d8,mode_control); + IO_WriteB(0x3d9,color_select); + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,mode_control); + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select); + break; + } + FinishSetMode(clearmem); + return true; +} + + +bool INT10_SetVideoMode(Bitu mode) { + bool clearmem=true;Bitu i; + if ((mode<256) && (mode & 128)) { + clearmem=false; + mode-=128; + } + LOG(LOG_INT10,LOG_NORMAL)("Set Video Mode %X",mode); + if (machine!=MCH_VGA) return INT10_SetVideoMode_OTHER(mode,clearmem); + Bit8u modeset_ctl,video_ctl,vga_switches; + if (!SetCurMode(ModeList_VGA,mode)){ + LOG(LOG_INT10,LOG_ERROR)("Trying to set illegal mode %X",mode); + return false; + } /* First read mode setup settings from bios area */ video_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL); @@ -158,15 +339,12 @@ foundmode: modeset_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); /* Setup the VGA to the correct mode */ - VGA_SetMode(CurMode->type); +// VGA_SetMode(CurMode->type); Bit16u crtc_base; - bool mono_mode=CurMode->type == M_TEXT2; - if (mono_mode) { - crtc_base=0x3b4; - } else { - crtc_base=0x3d4; - } + bool mono_mode=(CurMode->type == M_TEXT && machine==MCH_HERC); + if (mono_mode) crtc_base=0x3b4; + else crtc_base=0x3d4; /* Setup MISC Output Register */ Bit8u misc_output=0x2 | (mono_mode ? 0x0 : 0x1); IO_Write(0x3c2,misc_output); //Setup for 3b4 or 3d4 @@ -178,8 +356,7 @@ foundmode: (CurMode->special & _EGA_HALF_CLOCK) ? 0x08 : 0x00; seq_data[4]|=0x02; //More than 64kb switch (CurMode->type) { - case M_TEXT2: - case M_TEXT16: + case M_TEXT: seq_data[2]|=0x3; //Enable plane 0 and 1 seq_data[4]|=0x05; //Alpanumeric and odd/even enabled break; @@ -223,28 +400,17 @@ foundmode: blank_end = (CurMode->htotal-2) & 0x7f; } IO_Write(crtc_base,0x03);IO_Write(crtc_base+1,0x80|(blank_end & 0x1f)); -// hor_overflow|=(blank_end & 0x40) >> 3; - /* Start Horizontal Retrace */ Bitu ret_start; - if (CurMode->special & _EGA_HALF_CLOCK) { - ret_start = (CurMode->hdispend+2); - } else { - ret_start = (CurMode->hdispend+4); - } + if (CurMode->special & _EGA_HALF_CLOCK) ret_start = (CurMode->hdispend+2); + else ret_start = (CurMode->hdispend+4); IO_Write(crtc_base,0x04);IO_Write(crtc_base+1,ret_start); hor_overflow|=(ret_start & 0x100) >> 4; /* End Horizontal Retrace */ Bitu ret_end; - if (CurMode->special & _EGA_HALF_CLOCK) { - ret_end = (CurMode->htotal-2) & 0x3f; - } else { - ret_end = (CurMode->htotal-4) & 0x3f; - } + if (CurMode->special & _EGA_HALF_CLOCK) ret_end = (CurMode->htotal-2) & 0x3f; + else ret_end = (CurMode->htotal-4) & 0x3f; IO_Write(crtc_base,0x05);IO_Write(crtc_base+1,(ret_end & 0x1f) | (blank_end & 0x20) << 2); -// hor_overflow|=(ret_end & 0x20); -//TODO Be sure about these ending values in extended overflow of s3 - /* Vertical Total */ IO_Write(crtc_base,0x06);IO_Write(crtc_base+1,(CurMode->vtotal-2)); overflow|=((CurMode->vtotal-2) & 0x100) >> 8; @@ -286,8 +452,7 @@ foundmode: /* Maximum scanline / Underline Location */ if (CurMode->special & _EGA_LINE_DOUBLE) max_scanline|=0x80; switch (CurMode->type) { - case M_TEXT2: - case M_TEXT16: + case M_TEXT: max_scanline|=CurMode->cheight-1; underline=0x1f; break; @@ -297,7 +462,6 @@ foundmode: break; case M_LIN8: underline=0x60; //Seems to enable the every 4th clock on my s3 -// if (CurMode->special & _VGA_LINE_DOUBLE) max_scanline|=1; break; } IO_Write(crtc_base,0x09);IO_Write(crtc_base+1,max_scanline); @@ -328,8 +492,7 @@ foundmode: case M_EGA16: mode_control=0xe3; break; - case M_TEXT2: - case M_TEXT16: + case M_TEXT: case M_VGA: mode_control=0xa3; break; @@ -342,16 +505,9 @@ foundmode: IO_Write(crtc_base,0x11); IO_Write(crtc_base+1,IO_Read(crtc_base+1)|0x80); /* Setup the correct clock */ - switch (CurMode->type) { - case M_VGA: - case M_TEXT2: - case M_TEXT16: - case M_EGA16: - //Stick to 25mhz clock for now - break; - default: + if (CurMode->mode>=0x100) { misc_output|=0xef; //Select clock 3 - Bitu clock=CurMode->vtotal*8*CurMode->htotal*CurMode->rate; + Bitu clock=CurMode->vtotal*8*CurMode->htotal*70; VGA_SetClock(3,clock/1000); } /* Write Misc Output */ @@ -363,13 +519,9 @@ foundmode: gfx_data[0x7]=0xf; /* Color don't care */ gfx_data[0x8]=0xff; /* BitMask */ switch (CurMode->type) { - case M_TEXT2: + case M_TEXT: gfx_data[0x5]|=0x10; //Odd-Even Mode - gfx_data[0x6]|=0x0a; //alphanumeric mode at 0xb000=0x7fff - break; - case M_TEXT16: - gfx_data[0x5]|=0x10; //Odd-Even Mode - gfx_data[0x6]|=0x0e; //alphanumeric mode at 0xb800=0xbfff + gfx_data[0x6]|=mono_mode ? 0x0a : 0x0e; //Either b800 or b000 break; case M_LIN8: case M_VGA: @@ -393,7 +545,7 @@ foundmode: Bit8u att_data[ATT_REGS]; memset(att_data,0,ATT_REGS); att_data[0x12]=0xf; //Always have all color planes enabled - /* Porgram Attribute Controller */ + /* Program Attribute Controller */ switch (CurMode->type) { case M_EGA16: if (CurMode->mode>0xe) goto att_text16; @@ -401,15 +553,13 @@ foundmode: att_data[i]=i; att_data[i+8]=i+0x10; } + att_data[0x10]=0x01; //Color Graphics break; case M_TANDY16: att_data[0x10]=0x01; //Color Graphics - for (i=0;i<16;i++) { - att_data[i]=i; - } + for (i=0;i<16;i++) att_data[i]=i; break; - case M_TEXT2: - case M_TEXT16: + case M_TEXT: att_data[0x13]=0x08; //Pel panning on 8, although we don't have 9 dot text mode att_data[0x10]=0x0C; //Color Text with blinking att_text16: @@ -419,30 +569,31 @@ att_text16: } break; case M_CGA2: - IO_Write(0x3d9,0x7); //Setup using CGA color select register - real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x7); - goto skipatt; + att_data[0x10]=0x01; //Color Graphics + att_data[0]=0x0; + att_data[1]=0xf; + att_data[0x12]=0x1; //Only enable 1 plane + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x3f); + break; case M_CGA4: - //Set Bit 2 in black/white mode 0x5 - IO_Write(0x3d8,0xa+(CurMode->mode==0x5) ? 0x4 : 0); - IO_Write(0x3d9,0x30); //Setup using CGA color select register + att_data[0x10]=0x01; //Color Graphics + att_data[0]=0x0; + att_data[1]=0x3; + att_data[2]=0x5; + att_data[3]=0x7; real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x30); - goto skipatt; + break; case M_VGA: case M_LIN8: - for (i=0;i<16;i++) { - att_data[i]=i; - } + for (i=0;i<16;i++) att_data[i]=i; att_data[0x10]=0x41; //Color Graphics 8-bit break; } - IO_Read(mono_mode ? 0x3ba : 0x3da); for (i=0;itype) { @@ -463,8 +614,7 @@ skipatt: IO_Write(0x3c9,cga_palette[i][2]); } break; - case M_TEXT2: - case M_TEXT16: + case M_TEXT: dac_text16: for (i=0;i<64;i++) { IO_Write(0x3c9,text_palette[i][0]); @@ -486,22 +636,16 @@ dac_text16: switch (CurMode->type) { case M_CGA2: feature=(feature&~0x30)|0x20; - IO_Write(0x3d8,0x12); //Setup using CGA color select register real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x12); break; case M_CGA4: feature=(feature&~0x30)|0x20; - IO_Write(0x3d8,0x2); //Setup using CGA color select register real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x2); break; case M_TANDY16: feature=(feature&~0x30)|0x20; - IO_Write(0x3df,0x80); //Enter 32k mode and banks on 0 break; - case M_TEXT2: - feature=(feature&~0x30)|0x30; - break; - case M_TEXT16: + case M_TEXT: feature=(feature&~0x30)|0x20; break; case M_EGA16: @@ -527,70 +671,10 @@ dac_text16: IO_Write(crtc_base,0x39);IO_Write(crtc_base+1,0xa5); //Register lock 2 /* Load text mode font */ - if (CurMode->type<=M_TEXT16) { + if (CurMode->type==M_TEXT) { INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); } - /* Clear video memory if needs be */ - if (clearmem) { - switch (CurMode->type) { - case M_CGA4: - case M_CGA2: - for (i=0;i<16*1024;i++) { - real_writew(0xb800,i*2,0x0000); - } - break; - case M_TEXT2: - for (i=0;i<16*1024;i++) { - real_writew(0xb000,i*2,0x0120); - } - break; - case M_TEXT16: - for (i=0;i<16*1024;i++) { - real_writew(0xb800,i*2,0x0720); - } - break; - case M_EGA16: - case M_VGA: - case M_LIN8: - /* Just clear the whole 2 mb of memory */ - for (i=0;i<2*1024*1024/4;i++) { - mem_writed(S3_LFB_BASE+i*4,0); - } - } - } - /* Setup the BIOS */ - if (mode<128) real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode); - else real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode-0x98); //Looks like the s3 bios - real_writew(BIOSMEM_SEG,BIOSMEM_NB_COLS,CurMode->twidth); - real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,CurMode->plength); - real_writew(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_base); - real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,CurMode->theight-1); - real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,CurMode->cheight); - real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem << 7))); - real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0x09); - real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); - - // FIXME We nearly have the good tables. to be reworked - real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08); // 8 is VGA should be ok for now - real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER,0x00); - real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2,0x00); - - // Set cursor shape - if(CurMode->type<=M_TEXT16) { - INT10_SetCursorShape(0x06,07); - } - // Set cursor pos for page 0..7 - for(i=0;i<8;i++) INT10_SetCursorPos(0,0,(Bit8u)i); - // Set active page 0 - INT10_SetActivePage(0); - /* Set some interrupt vectors */ - switch (CurMode->cheight) { - case 8:RealSetVec(0x43,int10.rom.font_8_first);break; - case 14:RealSetVec(0x43,int10.rom.font_14);break; - case 16:RealSetVec(0x43,int10.rom.font_16);break; - } - /* Tell mouse resolution change */ - Mouse_NewVideoMode(); + FinishSetMode(clearmem); return true; } diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 358c4e2b..64c9c13b 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.7 2004-01-11 09:27:52 harekiet Exp $ */ +/* $Id: int10_vesa.cpp,v 1.8 2004-02-29 22:18:24 harekiet Exp $ */ #include #include @@ -125,12 +125,12 @@ Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off) { Bitu i=0; if (mode<0x100) return 0x01; - while (ModeList[i].mode!=0xffff) { - if (mode==ModeList[i].mode) goto foundit; else i++; + while (ModeList_VGA[i].mode!=0xffff) { + if (mode==ModeList_VGA[i].mode) goto foundit; else i++; } return 0x01; foundit: - VideoModeBlock * mblock=&ModeList[i]; + VideoModeBlock * mblock=&ModeList_VGA[i]; switch (mblock->type) { case M_LIN8: //Linear 8-bit WLE(minfo.ModeAttributes,0x9b); @@ -310,9 +310,9 @@ void INT10_SetupVESA(void) { i=0; int10.rom.vesa_modes=RealMake(0xc000,int10.rom.used); //TODO Maybe add normal vga modes too, but only seems to complicate things - while (ModeList[i].mode!=0xffff) { - if (ModeList[i].mode>=0x100){ - phys_writew(PhysMake(0xc000,int10.rom.used),ModeList[i].mode); + while (ModeList_VGA[i].mode!=0xffff) { + if (ModeList_VGA[i].mode>=0x100){ + phys_writew(PhysMake(0xc000,int10.rom.used),ModeList_VGA[i].mode); int10.rom.used+=2; } i++; From 96b66f1d45c6daf180ab058b8bf135c8a590ca6a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 29 Feb 2004 22:22:56 +0000 Subject: [PATCH 1610/4131] Added new modes vertical resolution Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1692 --- src/ints/mouse.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 5f64534c..b5eea37d 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.31 2004-01-31 22:42:49 harekiet Exp $ */ +/* $Id: mouse.cpp,v 1.32 2004-02-29 22:22:56 harekiet Exp $ */ #include #include "dosbox.h" @@ -283,7 +283,7 @@ void DrawCursor() { // Get Clipping ranges // In Textmode ? - if (CurMode->type<=M_TEXT16) { + if (CurMode->type==M_TEXT) { DrawCursorText(); return; } @@ -444,6 +444,9 @@ void Mouse_NewVideoMode(void) case 0x05: case 0x06: case 0x07: + case 0x08: + case 0x09: + case 0x0a: case 0x0d: case 0x0e: case 0x13: @@ -526,7 +529,7 @@ static Bitu INT33_Handler(void) { break; case 0x02: /* Hide Mouse */ { - if (CurMode->type>M_TEXT16) RestoreCursorBackground(); + if (CurMode->type!=M_TEXT) RestoreCursorBackground(); else RestoreCursorBackgroundText(); mouse.shown--; } From 1d070676ee9d792e5ce730b569cb2d578ddf346f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 29 Feb 2004 22:29:31 +0000 Subject: [PATCH 1611/4131] Remove auto machine type Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1693 --- include/dosbox.h | 3 +-- src/dosbox.cpp | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/include/dosbox.h b/include/dosbox.h index 718a6130..a1061790 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -63,8 +63,7 @@ enum MachineType { MCH_HERC, MCH_CGA, MCH_TANDY, - MCH_VGA, - MCH_AUTO + MCH_VGA }; extern MachineType machine; diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 5dcb3f74..52ead45d 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.62 2004-02-08 08:35:59 canadacow Exp $ */ +/* $Id: dosbox.cpp,v 1.63 2004-02-29 22:29:31 harekiet Exp $ */ #include #include @@ -169,7 +169,7 @@ static void DOSBOX_RealInit(Section * sec) { DOSBOX_SetLoop(&Normal_Loop); MSG_Init(section); - machine=MCH_AUTO;std::string cmd_machine; + machine=MCH_VGA;std::string cmd_machine; const char * mtype; if (control->cmdline->FindString("-machine",cmd_machine,true)) mtype=cmd_machine.c_str(); else mtype=section->Get_string("machine"); @@ -177,7 +177,6 @@ static void DOSBOX_RealInit(Section * sec) { else if (strcasecmp(mtype,"tandy")==0) machine=MCH_TANDY; else if (strcasecmp(mtype,"hercules")==0) machine=MCH_HERC; else if (strcasecmp(mtype,"vga")==0) machine=MCH_VGA; - else if (strcasecmp(mtype,"auto")==0) machine=MCH_AUTO; else LOG_MSG("DOSBOX:Unknown machine type %s",mtype); } @@ -310,7 +309,7 @@ void DOSBOX_Init(void) { "cms -- Enable the Creative Music System/Gameblaster emulation.\n" " Enabling both the adlib and cms might give conflicts!\n" "cmsrate -- Sample rate of cms emulation.\n" - ); + ); secprop=control->AddSection_prop("gus",&GUS_Init); secprop->Add_bool("gus",true); From 2c8d03d6b6fe0dac9b5e55bb00bb0f997038bf75 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 1 Mar 2004 18:27:03 +0000 Subject: [PATCH 1612/4131] Fixed overlay problems at debian/ppc(Marcin Kurek) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1694 --- src/gui/sdlmain.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index d01b1714..7a2cfc63 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.62 2004-02-19 12:24:51 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.63 2004-03-01 18:27:03 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -504,7 +504,11 @@ Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue) { Bit8u y = ( 9797*(red) + 19237*(green) + 3734*(blue) ) >> 15; Bit8u u = (18492*((blue)-(y)) >> 15) + 128; Bit8u v = (23372*((red)-(y)) >> 15) + 128; +#ifdef WORDS_BIGENDIAN + return (y << 0) | (v << 8) | (y << 16) | (u << 24); +#else return (u << 0) | (y << 8) | (v << 16) | (y << 24); +#endif } case SCREEN_OPENGL: // return ((red << 0) | (green << 8) | (blue << 16)) | (255 << 24); From 11b3ee29991795ac7da502492b66398ecbde0080 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 3 Mar 2004 12:37:12 +0000 Subject: [PATCH 1613/4131] added basic BCD counting Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1695 --- src/hardware/timer.cpp | 62 +++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index b60e8dd3..570d7cff 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.21 2004-02-07 18:34:03 harekiet Exp $ */ +/* $Id: timer.cpp,v 1.22 2004-03-03 12:37:12 qbix79 Exp $ */ #include "dosbox.h" #include "inout.h" @@ -27,6 +27,17 @@ #include "mixer.h" #include "timer.h" +static INLINE void BIN2BCD(Bit16u& val) { + Bit16u temp=val%10 + (((val/10)%10)<<4)+ (((val/100)%10)<<8) + (((val/1000)%10)<<12); + val=temp; +} + +static INLINE void BCD2BIN(Bit16u& val) { + Bit16u temp= (val&0x0f) +((val>>4)&0x0f) *10 +((val>>8)&0x0f) *100 +((val>>12)&0x0f) *1000; + val=temp; +} + + struct PIT_Block { Bit8u mode; /* Current Counter Mode */ @@ -36,9 +47,11 @@ struct PIT_Block { Bit8u latch_mode; Bit8u read_state; - Bit16s read_latch; + Bit16u read_latch; Bit8u write_state; Bit16u write_latch; + bool bcd; + bool go_read_latch; }; static PIT_Block pit[3]; @@ -51,6 +64,7 @@ static void PIT0_Event(Bitu val) { static void counter_latch(Bitu counter) { /* Fill the read_latch of the selected counter with current count */ PIT_Block * p=&pit[counter]; + p->go_read_latch=false; Bit64s micro=PIC_MicroCount()-p->start; @@ -91,6 +105,8 @@ static void counter_latch(Bitu counter) { static void write_latch(Bit32u port,Bit8u val) { Bitu counter=port-0x40; PIT_Block * p=&pit[counter]; + if(p->bcd == true) BIN2BCD(p->write_latch); + switch (p->write_state) { case 0: p->write_latch = p->write_latch | ((val & 0xff) << 8); @@ -106,9 +122,14 @@ static void write_latch(Bit32u port,Bit8u val) { case 2: p->write_latch = (val & 0xff) << 8; break; - } + } + if(p->bcd==true) BCD2BIN(p->write_latch); + if (p->write_state != 0) { - if (p->write_latch == 0) p->cntr = 0x10000; + if (p->write_latch == 0) { + if(p->bcd == false) {p->cntr = 0x10000;} else {p->cntr=9999;} + } + else p->cntr = p->write_latch; p->start=PIC_MicroCount(); p->micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)p->cntr)); @@ -130,14 +151,16 @@ static void write_latch(Bit32u port,Bit8u val) { static Bit8u read_latch(Bit32u port) { Bit32u counter=port-0x40; - if (pit[counter].read_latch == -1) + if (pit[counter].go_read_latch == true) counter_latch(counter); Bit8u ret; + if( pit[counter].bcd == true) BIN2BCD(pit[counter].read_latch); + switch (pit[counter].read_state) { case 0: /* read MSB & return to state 3 */ ret=(pit[counter].read_latch >> 8) & 0xff; pit[counter].read_state = 3; - pit[counter].read_latch = -1; + pit[counter].go_read_latch = true; break; case 3: /* read LSB followed by MSB */ ret = (pit[counter].read_latch & 0xff); @@ -147,17 +170,19 @@ static Bit8u read_latch(Bit32u port) { break; case 1: /* read LSB */ ret = (pit[counter].read_latch & 0xff); - pit[counter].read_latch = -1; + pit[counter].go_read_latch = true; break; case 2: /* read MSB */ ret = (pit[counter].read_latch >> 8) & 0xff; - pit[counter].read_latch = -1; + pit[counter].go_read_latch = true; break; default: ret=0; E_Exit("Timer.cpp: error in readlatch"); break; - } + } + if( pit[counter].bcd == true) BCD2BIN(pit[counter].read_latch); + return ret; } @@ -167,7 +192,10 @@ static void write_p43(Bit32u port,Bit8u val) { case 0: case 1: case 2: - if (val & 1) E_Exit("PIT:Timer %d set to unsupported bcd mode",latch); + pit[latch].bcd = (val&1)>0; + if (val & 1) if(pit[latch].cntr>=9999) pit[latch].cntr=9999; + + if ((val & 0x30) == 0) { /* Counter latch command */ counter_latch(latch); @@ -201,16 +229,24 @@ void TIMER_Init(Section* sect) { pit[0].cntr=0x10000; pit[0].write_state = 3; pit[0].read_state = 3; - pit[0].read_latch=-1; + pit[0].read_latch=0; pit[0].write_latch=0; pit[0].mode=3; - + pit[0].bcd = false; + pit[0].go_read_latch = true; + + pit[1].bcd = false; + pit[1].go_read_latch = true; + pit[1].mode = 3; + pit[1].write_state = 3; pit[0].micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)pit[0].cntr)); pit[2].micro=100; - pit[2].read_latch=-1; /* MadTv1 */ + pit[2].read_latch=0; /* MadTv1 */ pit[2].write_state = 3; /* Chuck Yeager */ pit[2].mode=3; + pit[2].bcd=false; + pit[2].go_read_latch=true; PIC_AddEvent(PIT0_Event,pit[0].micro); } From ea42447455b2ed4e1adba7a4c9cea8afde3ca098 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 3 Mar 2004 12:40:59 +0000 Subject: [PATCH 1614/4131] moved windows.h under STL (suggested by almightyjustin) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1696 --- src/dos/drive_cache.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 256df85f..848827ec 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,23 +17,23 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.32 2004-01-12 20:25:05 finsterr Exp $ */ +/* $Id: drive_cache.cpp,v 1.33 2004-03-03 12:40:59 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" #include "dirent.h" #include "support.h" -#if defined (WIN32) /* Win 32 */ -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from -#include -#endif - // STL stuff #include #include #include +#if defined (WIN32) /* Win 32 */ +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from +#include +#endif + int fileInfoCounter = 0; bool SortByName(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b) From 74b2f10fe6f93cbfd1fc37e14b5d5b615d0d746e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 3 Mar 2004 15:44:20 +0000 Subject: [PATCH 1615/4131] Add new config options for different soundblaster types Add new config options for different opl emulations Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1697 --- src/dosbox.cpp | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 52ead45d..ee019d89 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.63 2004-02-29 22:29:31 harekiet Exp $ */ +/* $Id: dosbox.cpp,v 1.64 2004-03-03 15:44:20 harekiet Exp $ */ #include #include @@ -73,10 +73,8 @@ void MOUSE_Init(Section*); void SBLASTER_Init(Section*); void GUS_Init(Section*); void MPU401_Init(Section*); -void ADLIB_Init(Section*); void PCSPEAKER_Init(Section*); void TANDYSOUND_Init(Section*); -void CMS_Init(Section*); void DISNEY_Init(Section*); void SERIAL_Init(Section*); void MODEM_Init(Section*); @@ -286,29 +284,22 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("debug",&DEBUG_Init); #endif secprop=control->AddSection_prop("sblaster",&SBLASTER_Init); - secprop->Add_bool("sblaster",true); + secprop->Add_string("type","sb16"); secprop->Add_hex("base",0x220); secprop->Add_int("irq",7); secprop->Add_int("dma",1); -// secprop->Add_int("hdma",5); + secprop->Add_int("hdma",5); secprop->Add_int("sbrate",22050); - secprop->AddInitFunction(&ADLIB_Init); - secprop->Add_bool("adlib",true); - secprop->Add_int("adlibrate",22050); - secprop->Add_string("adlibmode","adlib"); - secprop->AddInitFunction(&CMS_Init); - secprop->Add_bool("cms",false); - secprop->Add_int("cmsrate",22050); + secprop->Add_string("oplmode","auto"); + secprop->Add_int("oplrate",22050); MSG_Add("SBLASTER_CONFIGFILE_HELP", - "sblaster -- Enable the soundblaster emulation.\n" - "base,irq,dma -- The IO/IRQ/DMA address of the soundblaster.\n" + "type -- Type of sblaster to emulate:none,sb1,sb2,sbpro1,sbpro2,sb16.\n" + "base,irq,dma,hdma -- The IO/IRQ/DMA/High DMA address of the soundblaster.\n" "sbrate -- Sample rate of soundblaster emulation.\n" - "adlib -- Enable the adlib emulation.\n" - "adlibrate -- Sample rate of adlib emulation.\n" - "cms -- Enable the Creative Music System/Gameblaster emulation.\n" - " Enabling both the adlib and cms might give conflicts!\n" - "cmsrate -- Sample rate of cms emulation.\n" + "oplmode -- Type of OPL emulation: auto,cms,opl2,dualopl2,opl3.\n" + " On auto the mode is determined by sblaster type.\n" + "oplrate -- Sample rate of OPL music emulation.\n" ); secprop=control->AddSection_prop("gus",&GUS_Init); From 30e64fda9be6aca60453ba310d06f601c03e544b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 3 Mar 2004 15:47:06 +0000 Subject: [PATCH 1616/4131] Added init functions for opl and cms subsystems Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1698 --- include/hardware.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/hardware.h b/include/hardware.h index d0958f4e..17bc85a5 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -19,8 +19,13 @@ #ifndef _HARDWARE_H_ #define _HARDWARE_H_ +class Section; +enum OPL_Mode { + OPL_none,OPL_cms,OPL_opl2,OPL_dualopl2,OPL_opl3 +}; - +void OPL_Init(Section* sec,OPL_Mode,Bitu rate); +void CMS_Init(Section* sec,Bitu rate); #endif From 9d26cef41ce92c7c67b2d99befb9184bd2756894 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 3 Mar 2004 15:47:07 +0000 Subject: [PATCH 1617/4131] Added dual opl2 and opl3 emulation. Fixed the sample rate config option not being used. Added different soundblaster type options. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1699 --- src/hardware/Makefile.am | 5 +- src/hardware/adlib.cpp | 253 ++-- src/hardware/fmopl.c | 259 ++-- src/hardware/fmopl.h | 2 +- src/hardware/gameblaster.cpp | 6 +- src/hardware/sblaster.cpp | 63 +- src/hardware/ymf262.c | 2778 ++++++++++++++++++++++++++++++++++ src/hardware/ymf262.h | 53 + 8 files changed, 3168 insertions(+), 251 deletions(-) create mode 100644 src/hardware/ymf262.c create mode 100644 src/hardware/ymf262.h diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index 6335846b..b200390e 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -1,6 +1,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -EXTRA_DIST = fmopl.c fmopl.h +EXTRA_DIST = fmopl.c fmopl.h ymf262.h ymf262.c noinst_LIBRARIES = libhardware.a @@ -10,3 +10,6 @@ libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler vga_memory.cpp vga_misc.cpp vga_seq.cpp font-switch.h ega-switch.h cmos.cpp disney.cpp \ gus.cpp mpu401.cpp serialport.cpp softmodem.cpp ipx.cpp ipxserver.cpp + + + diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index f792f9fb..d0f99720 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -29,9 +29,7 @@ Thanks to vdmsound for nice simple way to implement this */ -namespace MAME { - /* Defines */ -# define logerror(x) +# define logerror #ifdef _MSC_VER /* Disable recurring warnings */ @@ -39,166 +37,137 @@ namespace MAME { # pragma warning ( disable : 4244 ) #endif - /* Work around ANSI compliance problem (see driver.h) */ - struct __MALLOCPTR { - void* m_ptr; +struct __MALLOCPTR { + void* m_ptr; - __MALLOCPTR(void) : m_ptr(NULL) { } - __MALLOCPTR(void* src) : m_ptr(src) { } - void* operator=(void* rhs) { return (m_ptr = rhs); } - operator int*() const { return (int*)m_ptr; } - operator int**() const { return (int**)m_ptr; } - operator char*() const { return (char*)m_ptr; } - }; - - /* Bring in the MAME OPL emulation */ -# define HAS_YM3812 1 -# include "fmopl.c" - -} - - -struct OPLTimer_t { - bool isEnabled; - bool isMasked; - bool isOverflowed; - Bit64u count; - Bit64u base; + __MALLOCPTR(void) : m_ptr(NULL) { } + __MALLOCPTR(void* src) : m_ptr(src) { } + void* operator=(void* rhs) { return (m_ptr = rhs); } + operator int*() const { return (int*)m_ptr; } + operator int**() const { return (int**)m_ptr; } + operator char*() const { return (char*)m_ptr; } }; -static OPLTimer_t timer1,timer2; -static Bit8u regsel; +namespace OPL2 { + #define HAS_YM3812 1 + #include "fmopl.c" + void TimerOver(Bitu val){ + YM3812TimerOver(val>>8,val & 0xff); + } + void TimerHandler(int channel,double interval_Sec) { + PIC_AddEvent(TimerOver,1000000*interval_Sec,channel); + } +} +#undef OSD_CPU_H +#undef TL_TAB_LEN +namespace OPL3 { + #define HAS_YMF262 1 + #include "ymf262.c" + void TimerOver(Bitu val){ + YMF262TimerOver(val>>8,val & 0xff); + } + void TimerHandler(int channel,double interval_Sec) { + PIC_AddEvent(TimerOver,1000000*interval_Sec,channel); + } +} -#define OPL_INTERNAL_FREQ 3600000 // The OPL operates at 3.6MHz -#define OPL_NUM_CHIPS 1 // Number of OPL chips -#define OPL_CHIP0 0 +#define OPL2_INTERNAL_FREQ 3600000 // The OPL2 operates at 3.6MHz +#define OPL3_INTERNAL_FREQ 14400000 // The OPL3 operates at 14.4MHz -static MIXER_Channel * adlib_chan; +static struct { + bool active; + OPL_Mode mode; + MIXER_Channel * chan; + Bit32u last_used; + Bit16s mixbuf[2][128]; +} opl; -static void ADLIB_CallBack(Bit8u *stream, Bit32u len) { +static void OPL_CallBack(Bit8u *stream, Bit32u len) { /* Check for size to update and check for 1 ms updates to the opl registers */ /* Calculate teh machine ms we are at now */ /* update 1 ms of data */ - MAME::YM3812UpdateOne(0,(MAME::INT16 *)stream,len); -} + Bitu i; + switch(opl.mode) { + case OPL_opl2: + OPL2::YM3812UpdateOne(0,(OPL2::INT16 *)stream,len); + break; + case OPL_opl3: + OPL3::YMF262UpdateOne(0,(OPL2::INT16 *)stream,len); + break; + case OPL_dualopl2: + OPL2::YM3812UpdateOne(0,(OPL2::INT16 *)opl.mixbuf[0],len); + OPL2::YM3812UpdateOne(1,(OPL2::INT16 *)opl.mixbuf[1],len); + for (i=0;itimer1.count) { - timer1.isOverflowed=true; - timer1.base=micro; - } - if (timer1.isOverflowed || !timer1.isMasked) { - ret|=0xc0; - } } - if (timer2.isEnabled) { - if ((micro-timer2.base)>timer2.count) { - timer2.isOverflowed=true; - timer2.base=micro; - } - if (timer2.isOverflowed || !timer2.isMasked) { - ret|=0xA0; - } - } - return ret; -} - -static void write_p388(Bit32u port,Bit8u val) { - regsel=val; - - // The following writes this value to ultrasounds equivalent register. - // I don't know of any other way to do this - IO_Write(0x248,val); -} - -static void write_p389(Bit32u port,Bit8u val) { - switch (regsel) { - case 0x02: /* Timer 1 */ - timer1.count=val*80; - return; - case 0x03: /* Timer 2 */ - timer2.count=val*320; - return; - case 0x04: /* IRQ clear / mask and Timer enable */ - if (val&0x80) { - timer1.isOverflowed=false; - timer2.isOverflowed=false; - return; - } - if (val&0x40) timer1.isMasked=true; - else timer1.isMasked=false; - - if (val&1) { - timer1.isEnabled=true; - timer1.base=PIC_MicroCount(); - } else timer1.isEnabled=false; - if (val&0x20) timer2.isMasked=true; - else timer2.isMasked=false; - if (val&2) { - timer2.isEnabled=true; - timer2.base=PIC_MicroCount(); - } else timer2.isEnabled=false; - return; - default: /* Normal OPL call queue it */ - /* Use a little hack to directly write to the register */ - MAME::OPLWriteReg(MAME::OPL_YM3812[0],regsel,val); + if ((PIC_Ticks-opl.last_used)>1000) { + MIXER_Enable(opl.chan,false); + opl.active=false; } } -static bool adlib_enabled; +Bit8u OPL_Read(Bit32u port) { + Bitu addr=port & 3; + switch (opl.mode) { + case OPL_opl2: + return OPL2::YM3812Read(0,addr); + case OPL_dualopl2: + return OPL2::YM3812Read(addr>>1,addr); + case OPL_opl3: + return OPL3::YMF262Read(0,addr); + } + return 0xff; +} -static void ADLIB_Enable(bool enable) { - if (enable) { - adlib_enabled=true; - MIXER_Enable(adlib_chan,true); - IO_RegisterWriteHandler(0x388,write_p388,"ADLIB Register select"); - IO_RegisterWriteHandler(0x389,write_p389,"ADLIB Data Write"); - IO_RegisterReadHandler(0x388,read_p388,"ADLIB Status"); - - IO_RegisterWriteHandler(0x220,write_p388,"ADLIB Register select"); - IO_RegisterWriteHandler(0x221,write_p389,"ADLIB Data Write"); - IO_RegisterReadHandler(0x220,read_p388,"ADLIB Status"); - } else { - adlib_enabled=false; - MIXER_Enable(adlib_chan,false); - IO_FreeWriteHandler(0x220); - IO_FreeWriteHandler(0x221); - IO_FreeReadHandler(0x220); - IO_FreeWriteHandler(0x388); - IO_FreeWriteHandler(0x389); - IO_FreeReadHandler(0x388); +void OPL_Write(Bit32u port,Bit8u val) { + opl.last_used=PIC_Ticks; + if (!opl.active) { + opl.active=true; + MIXER_Enable(opl.chan,true); + } + Bitu addr=port & 3; + switch (opl.mode) { + case OPL_opl2: + OPL2::YM3812Write(0,addr,val); + break; + case OPL_opl3: + OPL3::YMF262Write(0,addr,val); + break; + case OPL_dualopl2: + OPL2::YM3812Write(addr>>1,addr,val); + break; } } - -void ADLIB_Init(Section* sec) { +void OPL_Init(Section* sec,OPL_Mode oplmode,Bitu rate) { + Bitu i; Section_prop * section=static_cast(sec); - if(!section->Get_bool("adlib")) return; - - timer1.isMasked=true; - timer1.base=0; - timer1.count=0; - timer1.isEnabled=false; - timer1.isOverflowed=false; - - timer2.isMasked=true; - timer2.base=0; - timer2.count=0; - timer2.isEnabled=false; - timer2.isOverflowed=false; - - #define ADLIB_FREQ 22050 - if (MAME::YM3812Init(OPL_NUM_CHIPS,OPL_INTERNAL_FREQ,ADLIB_FREQ)) { - E_Exit("Can't create adlib OPL Emulator"); + if (OPL2::YM3812Init(2,OPL2_INTERNAL_FREQ,rate)) { + E_Exit("Can't create OPL2 Emulator"); }; + OPL2::YM3812SetTimerHandler(0,OPL2::TimerHandler,0); + OPL2::YM3812SetTimerHandler(1,OPL2::TimerHandler,256); + if (OPL3::YMF262Init(1,OPL3_INTERNAL_FREQ,rate)) { + E_Exit("Can't create OPL3 Emulator"); + }; + OPL3::YMF262SetTimerHandler(0,OPL3::TimerHandler,0); + for (i=0;i<4;i++) { + IO_RegisterWriteHandler(0x388+i,OPL_Write,"OPL Write"); + IO_RegisterReadHandler(0x388+i,OPL_Read,"OPL read"); + IO_RegisterWriteHandler(0x220+i,OPL_Write,"OPL Write"); + IO_RegisterReadHandler(0x220+i,OPL_Read,"OPL read"); + } + opl.active=false; + opl.last_used=0; + opl.mode=oplmode; - - adlib_chan=MIXER_AddChannel(ADLIB_CallBack,ADLIB_FREQ,"ADLIB"); - MIXER_SetMode(adlib_chan,MIXER_16MONO); - ADLIB_Enable(true); + opl.chan=MIXER_AddChannel(OPL_CallBack,rate,"ADLIB"); + MIXER_SetMode(opl.chan,(opl.mode>OPL_opl2) ? MIXER_16STEREO : MIXER_16MONO); + MIXER_Enable(opl.chan,false); }; diff --git a/src/hardware/fmopl.c b/src/hardware/fmopl.c index b4d7c8e4..5a838eb5 100644 --- a/src/hardware/fmopl.c +++ b/src/hardware/fmopl.c @@ -3,14 +3,23 @@ ** File: fmopl.c - software implementation of FM sound generator ** types OPL and OPL2 ** +** Copyright (C) 2002,2003 Jarek Burczynski (bujar at mame dot net) ** Copyright (C) 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmulator development -** Copyright (C) 2002 Jarek Burczynski ** -** Version 0.60 +** Version 0.70 ** Revision History: +14-06-2003 Jarek Burczynski: + - implemented all of the status register flags in Y8950 emulation + - renamed Y8950SetDeltaTMemory() parameters from _rom_ to _mem_ since + they can be either RAM or ROM + +08-10-2002 Jarek Burczynski (thanks to Dox for the YM3526 chip) + - corrected YM3526Read() to always set bit 2 and bit 1 + to HIGH state - identical to YM3812Read (verified on real YM3526) + 04-28-2002 Jarek Burczynski: - binary exact Envelope Generator (verified on real YM3812); compared to YM2151: the EG clock is equal to internal_clock, @@ -51,9 +60,8 @@ Revision History: #include #include -#include -#include #include + //#include "driver.h" /* use M.A.M.E. */ #include "fmopl.h" @@ -117,10 +125,45 @@ Revision History: /*#define SAVE_SAMPLE*/ #ifdef SAVE_SAMPLE +INLINE signed int acc_calc(signed int value) +{ + if (value>=0) + { + if (value < 0x0200) + return (value & ~0); + if (value < 0x0400) + return (value & ~1); + if (value < 0x0800) + return (value & ~3); + if (value < 0x1000) + return (value & ~7); + if (value < 0x2000) + return (value & ~15); + if (value < 0x4000) + return (value & ~31); + return (value & ~63); + } + /*else value < 0*/ + if (value > -0x0200) + return (~abs(value) & ~0); + if (value > -0x0400) + return (~abs(value) & ~1); + if (value > -0x0800) + return (~abs(value) & ~3); + if (value > -0x1000) + return (~abs(value) & ~7); + if (value > -0x2000) + return (~abs(value) & ~15); + if (value > -0x4000) + return (~abs(value) & ~31); + return (~abs(value) & ~63); +} + + static FILE *sample[1]; #if 1 /*save to MONO file */ #define SAVE_ALL_CHANNELS \ - { signed int pom = lt; \ + { signed int pom = acc_calc(lt); \ fputc((unsigned short)pom&0xff,sample[0]); \ fputc(((unsigned short)pom>>8)&0xff,sample[0]); \ } @@ -155,8 +198,6 @@ static FILE *sample[1]; -/* Saving is necessary for member of the 'R' mark for suspend/resume */ - typedef struct{ UINT32 ar; /* attack rate: AR<<2 */ UINT32 dr; /* decay rate: DR<<2 */ @@ -181,14 +222,12 @@ typedef struct{ INT32 TLL; /* adjusted now TL */ INT32 volume; /* envelope counter */ UINT32 sl; /* sustain level: sl_tab[SL] */ - UINT8 eg_sh_ar; /* (attack state) */ UINT8 eg_sel_ar; /* (attack state) */ UINT8 eg_sh_dr; /* (decay state) */ UINT8 eg_sel_dr; /* (decay state) */ UINT8 eg_sh_rr; /* (release state) */ UINT8 eg_sel_rr; /* (release state) */ - UINT32 key; /* 0 = KEY OFF, >0 = KEY ON */ /* LFO */ @@ -244,7 +283,7 @@ typedef struct fm_opl_f { YM_DELTAT *deltat; - /* Keyboard / I/O interface unit*/ + /* Keyboard and I/O ports interface */ UINT8 portDirection; UINT8 portLatch; OPL_PORTHANDLER_R porthandler_r; @@ -375,7 +414,7 @@ static const unsigned char eg_inc[15*RATE_STEPS]={ /*note that there is no O(13) in this table - it's directly in the code */ static const unsigned char eg_rate_select[16+64+16]={ /* Envelope Generator rates (16 + 64 rates + 16 RKS) */ -/* 16 dummy (infinite time) rates */ +/* 16 infinite time rates */ O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), @@ -410,13 +449,13 @@ O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12), }; #undef O -//rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 -//shift 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0 -//mask 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0, 0 +/*rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 */ +/*shift 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0 */ +/*mask 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0, 0 */ #define O(a) (a*1) static const unsigned char eg_rate_shift[16+64+16]={ /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */ -/* 16 dummy (infinite time) rates */ +/* 16 infinite time rates */ O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), @@ -586,15 +625,15 @@ static const INT8 lfo_pm_table[8*8*2] = { /* lock level of common table */ static int num_lock = 0; -/* work table */ -static void *cur_chip = NULL; /* current chip point */ -OPL_SLOT *SLOT7_1,*SLOT7_2,*SLOT8_1,*SLOT8_2; -static signed int phase_modulation; /* phase modulation input (SLOT 2) */ +static void *cur_chip = NULL; /* current chip pointer */ +static OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2; + +static signed int phase_modulation; /* phase modulation input (SLOT 2) */ static signed int output[1]; #if BUILD_Y8950 -static INT32 output_deltat[4]; /* for Y8950 DELTA-T */ +static INT32 output_deltat[4]; /* for Y8950 DELTA-T, chip is mono, that 4 here is just for safety */ #endif static UINT32 LFO_AM; @@ -699,8 +738,6 @@ INLINE void advance(FM_OPL *OPL) switch(op->state) { case EG_ATT: /* attack phase */ - { - if ( !(OPL->eg_cnt & ((1<eg_sh_ar)-1) ) ) { op->volume += (~op->volume * @@ -714,8 +751,6 @@ INLINE void advance(FM_OPL *OPL) } } - - } break; case EG_DEC: /* decay phase */ @@ -792,7 +827,7 @@ INLINE void advance(FM_OPL *OPL) { block_fnum += lfo_fn_table_index_offset; block = (block_fnum&0x1c00) >> 10; - op->Cnt += (OPL->fn_tab[block_fnum&0x03ff] >> (7-block)) * op->mul;//ok + op->Cnt += (OPL->fn_tab[block_fnum&0x03ff] >> (7-block)) * op->mul; } else /* LFO phase modulation = zero */ { @@ -857,15 +892,8 @@ INLINE signed int op_calc(UINT32 phase, unsigned int env, signed int pm, unsigne INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab) { UINT32 p; - INT32 i; - i = (phase & ~FREQ_MASK) + pm; - -/*logerror("i=%08x (i>>16)&511=%8i phase=%i [pm=%08x] ",i, (i>>16)&511, phase>>FREQ_SH, pm);*/ - - p = (env<<4) + sin_tab[ wave_tab + ((i>>FREQ_SH) & SIN_MASK)]; - -/*logerror("(p&255=%i p>>8=%i) out= %i\n", p&255,p>>8, tl_tab[p&255]>>(p>>8) );*/ + p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + pm )) >> FREQ_SH ) & SIN_MASK) ]; if (p >= TL_TAB_LEN) return 0; @@ -966,7 +994,7 @@ INLINE void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) if (!SLOT->CON) phase_modulation = SLOT->op1_out[0]; - //else ignore output of operator 1 + /* else ignore output of operator 1 */ SLOT->op1_out[1] = 0; if( env < ENV_QUIET ) @@ -984,16 +1012,16 @@ INLINE void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) /* Phase generation is based on: */ - // HH (13) channel 7->slot 1 combined with channel 8->slot 2 (same combination as TOP CYMBAL but different output phases) - // SD (16) channel 7->slot 1 - // TOM (14) channel 8->slot 1 - // TOP (17) channel 7->slot 1 combined with channel 8->slot 2 (same combination as HIGH HAT but different output phases) + /* HH (13) channel 7->slot 1 combined with channel 8->slot 2 (same combination as TOP CYMBAL but different output phases) */ + /* SD (16) channel 7->slot 1 */ + /* TOM (14) channel 8->slot 1 */ + /* TOP (17) channel 7->slot 1 combined with channel 8->slot 2 (same combination as HIGH HAT but different output phases) */ /* Envelope generation based on: */ - // HH channel 7->slot1 - // SD channel 7->slot2 - // TOM channel 8->slot1 - // TOP channel 8->slot2 + /* HH channel 7->slot1 */ + /* SD channel 7->slot2 */ + /* TOM channel 8->slot1 */ + /* TOP channel 8->slot2 */ /* The following formulas can be well optimized. @@ -1048,7 +1076,7 @@ INLINE void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) phase = 0xd0>>2; } - output[0] += op_calc(phase<wavetable) * 2; + output[0] += op_calc(phase<wavetable) * 2; } /* Snare Drum (verified on real YM3812) */ @@ -1069,13 +1097,13 @@ INLINE void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) if (noise) phase ^= 0x100; - output[0] += op_calc(phase<wavetable) * 2; + output[0] += op_calc(phase<wavetable) * 2; } /* Tom Tom (verified on real YM3812) */ env = volume_calc(SLOT8_1); if( env < ENV_QUIET ) - output[0] += op_calc(SLOT8_1->Cnt, env, 0, SLOT->wavetable) * 2; + output[0] += op_calc(SLOT8_1->Cnt, env, 0, SLOT8_1->wavetable) * 2; /* Top Cymbal (verified on real YM3812) */ env = volume_calc(SLOT8_2); @@ -1102,7 +1130,7 @@ INLINE void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) if (res2) phase = 0x300; - output[0] += op_calc(phase<wavetable) * 2; + output[0] += op_calc(phase<wavetable) * 2; } } @@ -1229,13 +1257,14 @@ static void OPL_initalize(FM_OPL *OPL) int i; /* frequency base */ -#if 1 OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / 72.0) / OPL->rate : 0; -#else +#if 0 OPL->rate = (double)OPL->clock / 72.0; OPL->freqbase = 1.0; #endif + /*logerror("freqbase=%f\n", OPL->freqbase);*/ + /* Timer base time */ OPL->TimerBase = 1.0 / ((double)OPL->clock / 72.0 ); @@ -1458,9 +1487,11 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v) { /* set IRQ mask ,timer enable*/ UINT8 st1 = v&1; UINT8 st2 = (v>>1)&1; + /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */ - OPL_STATUS_RESET(OPL,v&0x78); - OPL_STATUSMASK_SET(OPL,((~v)&0x78)|0x01); + OPL_STATUS_RESET(OPL, v & 0x78 ); + OPL_STATUSMASK_SET(OPL, (~v) & 0x78 ); + /* timer 2 */ if(OPL->st[1] != st2) { @@ -1484,34 +1515,43 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v) if(OPL->keyboardhandler_w) OPL->keyboardhandler_w(OPL->keyboard_param,v); else - logerror("OPL:write unmapped KEYBOARD port\n"); + logerror("Y8950: write unmapped KEYBOARD port\n"); } break; - case 0x07: /* DELTA-T controll : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */ + case 0x07: /* DELTA-T control 1 : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */ if(OPL->type&OPL_TYPE_ADPCM) YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v); break; - case 0x08: /* MODE,DELTA-T : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */ +#endif + case 0x08: /* MODE,DELTA-T control 2 : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */ OPL->mode = v; - v&=0x1f; /* for DELTA-T unit */ +#if BUILD_Y8950 + if(OPL->type&OPL_TYPE_ADPCM) + YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v&0x0f); /* mask 4 LSBs in register 08 for DELTA-T unit */ +#endif + break; + +#if BUILD_Y8950 case 0x09: /* START ADD */ case 0x0a: case 0x0b: /* STOP ADD */ case 0x0c: case 0x0d: /* PRESCALE */ case 0x0e: - case 0x0f: /* ADPCM data */ + case 0x0f: /* ADPCM data write */ case 0x10: /* DELTA-N */ case 0x11: /* DELTA-N */ - case 0x12: /* EG-CTRL */ + case 0x12: /* ADPCM volume */ if(OPL->type&OPL_TYPE_ADPCM) YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v); break; -#if 0 - case 0x15: /* DAC data */ - case 0x16: - case 0x17: /* SHIFT */ + + case 0x15: /* DAC data high 8 bits (F7,F6...F2) */ + case 0x16: /* DAC data low 2 bits (F1, F0 in bits 7,6) */ + case 0x17: /* DAC data shift (S2,S1,S0 in bits 2,1,0) */ + logerror("FMOPL.C: DAC data register written, but not implemented reg=%02x val=%02x\n",r,v); break; + case 0x18: /* I/O CTRL (Direction) */ if(OPL->type&OPL_TYPE_IO) OPL->portDirection = v&0x0f; @@ -1524,10 +1564,10 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v) OPL->porthandler_w(OPL->port_param,v&OPL->portDirection); } break; - case 0x1a: /* PCM data */ +#endif + default: + logerror("FMOPL.C: write to unknown register: %02x\n",r); break; -#endif -#endif } break; case 0x20: /* am ON, vib ON, ksr, eg_type, mul */ @@ -1773,7 +1813,7 @@ static void OPLResetChip(FM_OPL *OPL) #endif } -/* Create one of virtual YM3812 */ +/* Create one of virtual YM3812/YM3526/Y8950 */ /* 'clock' is chip clock in Hz */ /* 'rate' is sampling rate */ static FM_OPL *OPLCreate(int type, int clock, int rate) @@ -1806,7 +1846,9 @@ static FM_OPL *OPLCreate(int type, int clock, int rate) #if BUILD_Y8950 if (type&OPL_TYPE_ADPCM) + { OPL->deltat = (YM_DELTAT *)ptr; + } ptr += sizeof(YM_DELTAT); #endif @@ -1817,8 +1859,6 @@ static FM_OPL *OPLCreate(int type, int clock, int rate) /* init global tables */ OPL_initalize(OPL); - /* reset chip */ - OPLResetChip(OPL); return OPL; } @@ -1829,7 +1869,7 @@ static void OPLDestroy(FM_OPL *OPL) free(OPL); } -/* Option handlers */ +/* Optional handlers */ static void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset) { @@ -1847,7 +1887,6 @@ static void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int OPL->UpdateParam = param; } -/* YM3812 I/O interface */ static int OPLWrite(FM_OPL *OPL,int a,int v) { if( !(a&1) ) @@ -1867,6 +1906,17 @@ static unsigned char OPLRead(FM_OPL *OPL,int a) if( !(a&1) ) { /* status port */ + + #if BUILD_Y8950 + + if(OPL->type&OPL_TYPE_ADPCM) /* Y8950 */ + { + return (OPL->status & (OPL->statusmask|0x80)) | (OPL->deltat->PCM_BSY&1); + } + + #endif + + /* OPL and OPL2 */ return OPL->status & (OPL->statusmask|0x80); } @@ -1880,23 +1930,36 @@ static unsigned char OPLRead(FM_OPL *OPL,int a) if(OPL->keyboardhandler_r) return OPL->keyboardhandler_r(OPL->keyboard_param); else - logerror("OPL:read unmapped KEYBOARD port\n"); + logerror("Y8950: read unmapped KEYBOARD port\n"); } return 0; -#if 0 + case 0x0f: /* ADPCM-DATA */ + if(OPL->type&OPL_TYPE_ADPCM) + { + UINT8 val; + + val = YM_DELTAT_ADPCM_Read(OPL->deltat); + /*logerror("Y8950: read ADPCM value read=%02x\n",val);*/ + return val; + } return 0; -#endif + case 0x19: /* I/O DATA */ if(OPL->type&OPL_TYPE_IO) { if(OPL->porthandler_r) return OPL->porthandler_r(OPL->port_param); else - logerror("OPL:read unmapped I/O port\n"); + logerror("Y8950:read unmapped I/O port\n"); } return 0; case 0x1a: /* PCM-DATA */ + if(OPL->type&OPL_TYPE_ADPCM) + { + logerror("Y8950 A/D convertion is accessed but not implemented !\n"); + return 0x80; /* 2's complement PCM data - result from A/D convertion */ + } return 0; } #endif @@ -1968,6 +2031,8 @@ int YM3812Init(int num, int clock, int rate) YM3812NumChips = 0; return -1; } + /* reset */ + YM3812ResetChip(i); } return 0; @@ -2076,7 +2141,10 @@ void YM3812UpdateOne(int which, INT16 *buffer, int length) lt = limit( lt , MAXOUT, MINOUT ); #ifdef SAVE_SAMPLE + if (which==0) + { SAVE_ALL_CHANNELS + } #endif /* store to sound buffer */ @@ -2114,6 +2182,8 @@ int YM3526Init(int num, int clock, int rate) YM3526NumChips = 0; return -1; } + /* reset */ + YM3526ResetChip(i); } return 0; @@ -2143,7 +2213,8 @@ int YM3526Write(int which, int a, int v) unsigned char YM3526Read(int which, int a) { - return OPLRead(OPL_YM3526[which], a); + /* YM3526 always returns bit2 and bit1 in HIGH state */ + return OPLRead(OPL_YM3526[which], a) | 0x06 ; } int YM3526TimerOver(int which, int c) { @@ -2221,7 +2292,10 @@ void YM3526UpdateOne(int which, INT16 *buffer, int length) lt = limit( lt , MAXOUT, MINOUT ); #ifdef SAVE_SAMPLE + if (which==0) + { SAVE_ALL_CHANNELS + } #endif /* store to sound buffer */ @@ -2241,6 +2315,15 @@ void YM3526UpdateOne(int which, INT16 *buffer, int length) static FM_OPL *OPL_Y8950[MAX_OPL_CHIPS]; /* array of pointers to the Y8950's */ static int Y8950NumChips = 0; /* number of chips */ +static void Y8950_deltat_status_set(UINT8 which, UINT8 changebits) +{ + OPL_STATUS_SET(OPL_Y8950[which], changebits); +} +static void Y8950_deltat_status_reset(UINT8 which, UINT8 changebits) +{ + OPL_STATUS_RESET(OPL_Y8950[which], changebits); +} + int Y8950Init(int num, int clock, int rate) { int i; @@ -2260,6 +2343,13 @@ int Y8950Init(int num, int clock, int rate) Y8950NumChips = 0; return -1; } + OPL_Y8950[i]->deltat->status_set_handler = Y8950_deltat_status_set; + OPL_Y8950[i]->deltat->status_reset_handler = Y8950_deltat_status_reset; + OPL_Y8950[i]->deltat->status_change_which_chip = i; + OPL_Y8950[i]->deltat->status_change_EOS_bit = 0x10; /* status flag: set bit4 on End Of Sample */ + OPL_Y8950[i]->deltat->status_change_BRDY_bit = 0x08; /* status flag: set bit3 on BRDY (End Of: ADPCM analysis/synthesis, memory reading/writing) */ + /* reset */ + Y8950ResetChip(i); } return 0; @@ -2309,11 +2399,11 @@ void Y8950SetUpdateHandler(int which,OPL_UPDATEHANDLER UpdateHandler,int param) OPLSetUpdateHandler(OPL_Y8950[which], UpdateHandler, param); } -void Y8950SetDeltaTMemory(int which, void * deltat_rom, int deltat_rom_size ) +void Y8950SetDeltaTMemory(int which, void * deltat_mem_ptr, int deltat_mem_size ) { FM_OPL *OPL = OPL_Y8950[which]; - OPL->deltat->memory = (UINT8 *)(deltat_rom); - OPL->deltat->memory_size = deltat_rom_size; + OPL->deltat->memory = (UINT8 *)(deltat_mem_ptr); + OPL->deltat->memory_size = deltat_mem_size; } /* @@ -2331,9 +2421,6 @@ void Y8950UpdateOne(int which, INT16 *buffer, int length) YM_DELTAT *DELTAT = OPL->deltat; OPLSAMPLE *buf = buffer; - /* setup DELTA-T unit */ - YM_DELTAT_DECODE_PRESET(DELTAT); - if( (void *)OPL != cur_chip ){ cur_chip = (void *)OPL; /* rhythm slots */ @@ -2353,7 +2440,7 @@ void Y8950UpdateOne(int which, INT16 *buffer, int length) advance_lfo(OPL); /* deltaT ADPCM */ - if( DELTAT->portstate ) + if( DELTAT->portstate&0x80 ) YM_DELTAT_ADPCM_CALC(DELTAT); /* FM part */ @@ -2383,7 +2470,10 @@ void Y8950UpdateOne(int which, INT16 *buffer, int length) lt = limit( lt , MAXOUT, MINOUT ); #ifdef SAVE_SAMPLE + if (which==0) + { SAVE_ALL_CHANNELS + } #endif /* store to sound buffer */ @@ -2392,15 +2482,6 @@ void Y8950UpdateOne(int which, INT16 *buffer, int length) advance(OPL); } - /* deltaT START flag */ - if( !DELTAT->portstate ) - OPL->status &= 0xfe; - - if( DELTAT->eos ) //AT: set bit 4 of OPL status register on EOS - { - DELTAT->eos = 0; - OPL->status |= 0x10; - } } void Y8950SetPortHandler(int which,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param) diff --git a/src/hardware/fmopl.h b/src/hardware/fmopl.h index 4ba2b6b8..5a605fce 100644 --- a/src/hardware/fmopl.h +++ b/src/hardware/fmopl.h @@ -91,7 +91,7 @@ void YM3526SetUpdateHandler(int which, OPL_UPDATEHANDLER UpdateHandler, int para /* Y8950 port handlers */ void Y8950SetPortHandler(int which, OPL_PORTHANDLER_W PortHandler_w, OPL_PORTHANDLER_R PortHandler_r, int param); void Y8950SetKeyboardHandler(int which, OPL_PORTHANDLER_W KeyboardHandler_w, OPL_PORTHANDLER_R KeyboardHandler_r, int param); -void Y8950SetDeltaTMemory(int which, void * deltat_rom, int deltat_rom_size ); +void Y8950SetDeltaTMemory(int which, void * deltat_mem_ptr, int deltat_mem_size ); int Y8950Init (int num, int clock, int rate); void Y8950Shutdown (void); diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index f877bf4a..5bb1dcd4 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -420,10 +420,10 @@ static void write_cms(Bit32u port,Bit8u val) { } -void CMS_Init(Section* sec) { + void CMS_Init(Section* sec,Bitu rate) { Section_prop * section=static_cast(sec); if(!section->Get_bool("cms")) return; - sample_rate=section->Get_int("cmsrate"); + sample_rate=rate; IO_RegisterWriteHandler(0x220,write_cms,"CMS"); IO_RegisterWriteHandler(0x221,write_cms,"CMS"); @@ -432,7 +432,7 @@ void CMS_Init(Section* sec) { /* Register the Mixer CallBack */ - cms_chan=MIXER_AddChannel(CMS_CallBack,CMS_RATE,"CMS"); + cms_chan=MIXER_AddChannel(CMS_CallBack,rate,"CMS"); MIXER_SetMode(cms_chan,MIXER_16STEREO); MIXER_Enable(cms_chan,true); last_command=PIC_Ticks; diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 7a28c284..742fcc1f 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -25,6 +25,7 @@ #include "pic.h" #include "hardware.h" #include "setup.h" +#include "support.h" #include "programs.h" #define SB_PIC_EVENTS 0 @@ -53,9 +54,9 @@ #define SB_BUF_SIZE 8096 enum {DSP_S_RESET,DSP_S_NORMAL,DSP_S_HIGHSPEED}; +enum SB_TYPES {SBT_NONE=0,SBT_1=1,SBT_PRO1=2,SBT_2=3,SBT_PRO2=4,SBT_16=6}; enum SB_IRQS {SB_IRQ_8,SB_IRQ_16,SB_IRQ_MPU}; - enum DSP_MODES { MODE_NONE,MODE_DAC, MODE_SILENCE, @@ -94,6 +95,8 @@ struct SB_INFO { Bit8u time_constant; bool use_time_constant; DSP_MODES mode; + SB_TYPES type; + OPL_Mode oplmode; struct { bool pending_8bit; bool pending_16bit; @@ -907,9 +910,6 @@ static Bit8u read_sb(Bit32u port) { return 0xff; } return 0xff; -/* For now loop FM Stuff to 0x388 */ - case 0x00: case 0x02: case 0x08: - return IO_Read(0x388); case DSP_RESET: return 0xff; default: @@ -933,14 +933,6 @@ static void write_sb(Bit32u port,Bit8u val) { case MIXER_DATA: MIXER_Write(val); break; -/* For now loop FM Stuff to 0x388 */ - case 0x00: case 0x02: case 0x08: - IO_Write(0x388,val); - break; - case 0x01: case 0x03: case 0x09: - IO_Write(0x389,val); - break; - default: LOG(LOG_SB,LOG_NORMAL)("Unhandled write to SB Port %4X",port); break; @@ -964,7 +956,48 @@ static void SBLASTER_CallBack(Bit8u * stream,Bit32u len) { void SBLASTER_Init(Section* sec) { Bitu i; Section_prop * section=static_cast(sec); - if(!section->Get_bool("sblaster")) return; + const char * sbtype=section->Get_string("type"); + if (!strcasecmp(sbtype,"sb1")) sb.type=SBT_1; + else if (!strcasecmp(sbtype,"sb2")) sb.type=SBT_2; + else if (!strcasecmp(sbtype,"sbpro1")) sb.type=SBT_PRO1; + else if (!strcasecmp(sbtype,"sbpro2")) sb.type=SBT_PRO2; + else if (!strcasecmp(sbtype,"sb16")) sb.type=SBT_16; + else if (!strcasecmp(sbtype,"none")) sb.type=SBT_NONE; + else sb.type=SBT_16; + + /* OPL/CMS Init */ + const char * omode=section->Get_string("oplmode"); + Bitu oplrate=section->Get_int("oplrate"); + OPL_Mode opl_mode; + if (!strcasecmp(omode,"none")) opl_mode=OPL_none; + else if (!strcasecmp(omode,"cms")) opl_mode=OPL_cms; + else if (!strcasecmp(omode,"opl2")) opl_mode=OPL_opl2; + else if (!strcasecmp(omode,"dualopl2")) opl_mode=OPL_dualopl2; + else if (!strcasecmp(omode,"opl3")) opl_mode=OPL_opl3; + /* Else assume auto */ + else { + switch (sb.type) { + case SBT_NONE:opl_mode=OPL_none;break; + case SBT_1:opl_mode=OPL_cms;break; + case SBT_2:opl_mode=OPL_opl2;break; + case SBT_PRO1:opl_mode=OPL_dualopl2;break; + case SBT_PRO2: + case SBT_16: + opl_mode=OPL_opl3;break; + } + } + switch (opl_mode) { + case OPL_none: + break; + case OPL_cms: + CMS_Init(section,oplrate); + break; + case OPL_opl2: + case OPL_dualopl2: + case OPL_opl3: + OPL_Init(section,opl_mode,oplrate); + break; + } sb.chan=MIXER_AddChannel(&SBLASTER_CallBack,22050,"SBLASTER"); MIXER_Enable(sb.chan,false); sb.dsp.state=DSP_S_NORMAL; @@ -982,6 +1015,6 @@ void SBLASTER_Init(Section* sec) { } PIC_RegisterIRQ(sb.hw.irq,0,"SB"); DSP_Reset(); - - SHELL_AddAutoexec("SET BLASTER=A%3X I%d D%d T4",sb.hw.base,sb.hw.irq,sb.hw.dma8); + SHELL_AddAutoexec("SET BLASTER=A%3X I%d D%d T%d",sb.hw.base,sb.hw.irq,sb.hw.dma8,sb.type); } + diff --git a/src/hardware/ymf262.c b/src/hardware/ymf262.c new file mode 100644 index 00000000..5ecaa05f --- /dev/null +++ b/src/hardware/ymf262.c @@ -0,0 +1,2778 @@ +/* +** +** File: ymf262.c - software implementation of YMF262 +** FM sound generator type OPL3 +** +** Copyright (C) 2003 Jarek Burczynski +** +** Version 0.2 +** + +Revision History: + +03-03-2003: initial release + - thanks to Olivier Galibert and Chris Hardy for YMF262 and YAC512 chips + - thanks to Stiletto for the datasheets + + + +differences between OPL2 and OPL3 not documented in Yamaha datahasheets: +- sinus table is a little different: the negative part is off by one... + +- in order to enable selection of four different waveforms on OPL2 + one must set bit 5 in register 0x01(test). + on OPL3 this bit is ignored and 4-waveform select works *always*. + (Don't confuse this with OPL3's 8-waveform select.) + +- Envelope Generator: all 15 x rates take zero time on OPL3 + (on OPL2 15 0 and 15 1 rates take some time while 15 2 and 15 3 rates + take zero time) + +- channel calculations: output of operator 1 is in perfect sync with + output of operator 2 on OPL3; on OPL and OPL2 output of operator 1 + is always delayed by one sample compared to output of operator 2 + + +differences between OPL2 and OPL3 shown in datasheets: +- YMF262 does not support CSM mode + + +*/ + +#include +#include +#include + +//#include "driver.h" /* use M.A.M.E. */ +#include "ymf262.h" + +#ifndef PI +#define PI 3.14159265358979323846 +#endif + + + +/* output final shift */ +#if (OPL3_SAMPLE_BITS==16) + #define FINAL_SH (0) + #define MAXOUT (+32767) + #define MINOUT (-32768) +#else + #define FINAL_SH (8) + #define MAXOUT (+127) + #define MINOUT (-128) +#endif + + +#define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */ +#define EG_SH 16 /* 16.16 fixed point (EG timing) */ +#define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */ +#define TIMER_SH 16 /* 16.16 fixed point (timers calculations) */ + +#define FREQ_MASK ((1<>8)&0xff,sample[0]); \ + } + #else /*save to STEREO file */ + #define SAVE_ALL_CHANNELS \ + { signed int pom = a; \ + fputc((unsigned short)pom&0xff,sample[0]); \ + fputc(((unsigned short)pom>>8)&0xff,sample[0]); \ + pom = b; \ + fputc((unsigned short)pom&0xff,sample[0]); \ + fputc(((unsigned short)pom>>8)&0xff,sample[0]); \ + } + #endif +#endif + +/*#define LOG_CYM_FILE*/ +#ifdef LOG_CYM_FILE + FILE * cymfile = NULL; +#endif + + + + + +#define OPL3_TYPE_YMF262 (0) /* 36 operators, 8 waveforms */ + + +typedef struct{ + UINT32 ar; /* attack rate: AR<<2 */ + UINT32 dr; /* decay rate: DR<<2 */ + UINT32 rr; /* release rate:RR<<2 */ + UINT8 KSR; /* key scale rate */ + UINT8 ksl; /* keyscale level */ + UINT8 ksr; /* key scale rate: kcode>>KSR */ + UINT8 mul; /* multiple: mul_tab[ML] */ + + /* Phase Generator */ + UINT32 Cnt; /* frequency counter */ + UINT32 Incr; /* frequency counter step */ + UINT8 FB; /* feedback shift value */ + INT32 *connect; /* slot output pointer */ + INT32 op1_out[2]; /* slot1 output for feedback */ + UINT8 CON; /* connection (algorithm) type */ + + /* Envelope Generator */ + UINT8 eg_type; /* percussive/non-percussive mode */ + UINT8 state; /* phase type */ + UINT32 TL; /* total level: TL << 2 */ + INT32 TLL; /* adjusted now TL */ + INT32 volume; /* envelope counter */ + UINT32 sl; /* sustain level: sl_tab[SL] */ + + UINT32 eg_m_ar; /* (attack state) */ + UINT8 eg_sh_ar; /* (attack state) */ + UINT8 eg_sel_ar; /* (attack state) */ + UINT32 eg_m_dr; /* (decay state) */ + UINT8 eg_sh_dr; /* (decay state) */ + UINT8 eg_sel_dr; /* (decay state) */ + UINT32 eg_m_rr; /* (release state) */ + UINT8 eg_sh_rr; /* (release state) */ + UINT8 eg_sel_rr; /* (release state) */ + + UINT32 key; /* 0 = KEY OFF, >0 = KEY ON */ + + /* LFO */ + UINT32 AMmask; /* LFO Amplitude Modulation enable mask */ + UINT8 vib; /* LFO Phase Modulation enable flag (active high)*/ + + /* waveform select */ + UINT8 waveform_number; + unsigned int wavetable; + +//unsigned char reserved[128-84];//speedup: pump up the struct size to power of 2 +unsigned char reserved[128-100];//speedup: pump up the struct size to power of 2 + +} OPL3_SLOT; + +typedef struct{ + OPL3_SLOT SLOT[2]; + + UINT32 block_fnum; /* block+fnum */ + UINT32 fc; /* Freq. Increment base */ + UINT32 ksl_base; /* KeyScaleLevel Base step */ + UINT8 kcode; /* key code (for key scaling) */ + + /* + there are 12 2-operator channels which can be combined in pairs + to form six 4-operator channel, they are: + 0 and 3, + 1 and 4, + 2 and 5, + 9 and 12, + 10 and 13, + 11 and 14 + */ + UINT8 extended; /* set to 1 if this channel forms up a 4op channel with another channel(only used by first of pair of channels, ie 0,1,2 and 9,10,11) */ + +unsigned char reserved[512-272];//speedup:pump up the struct size to power of 2 + +} OPL3_CH; + +/* OPL3 state */ +typedef struct { + OPL3_CH P_CH[18]; /* OPL3 chips have 18 channels */ + + UINT32 pan[18*4]; /* channels output masks (0xffffffff = enable); 4 masks per one channel */ + UINT32 pan_ctrl_value[18]; /* output control values 1 per one channel (1 value contains 4 masks) */ + + UINT32 eg_cnt; /* global envelope generator counter */ + UINT32 eg_timer; /* global envelope generator counter works at frequency = chipclock/288 (288=8*36) */ + UINT32 eg_timer_add; /* step of eg_timer */ + UINT32 eg_timer_overflow; /* envelope generator timer overlfows every 1 sample (on real chip) */ + + UINT32 fn_tab[1024]; /* fnumber->increment counter */ + + /* LFO */ + UINT8 lfo_am_depth; + UINT8 lfo_pm_depth_range; + UINT32 lfo_am_cnt; + UINT32 lfo_am_inc; + UINT32 lfo_pm_cnt; + UINT32 lfo_pm_inc; + + UINT32 noise_rng; /* 23 bit noise shift register */ + UINT32 noise_p; /* current noise 'phase' */ + UINT32 noise_f; /* current noise period */ + + UINT8 OPL3_mode; /* OPL3 extension enable flag */ + + UINT8 rhythm; /* Rhythm mode */ + + int T[2]; /* timer counters */ + UINT8 st[2]; /* timer enable */ + + UINT32 address; /* address register */ + UINT8 status; /* status flag */ + UINT8 statusmask; /* status mask */ + + UINT8 nts; /* NTS (note select) */ + + /* external event callback handlers */ + OPL3_TIMERHANDLER TimerHandler;/* TIMER handler */ + int TimerParam; /* TIMER parameter */ + OPL3_IRQHANDLER IRQHandler; /* IRQ handler */ + int IRQParam; /* IRQ parameter */ + OPL3_UPDATEHANDLER UpdateHandler;/* stream update handler */ + int UpdateParam; /* stream update parameter */ + + UINT8 type; /* chip type */ + int clock; /* master clock (Hz) */ + int rate; /* sampling rate (Hz) */ + double freqbase; /* frequency base */ + double TimerBase; /* Timer base time (==sampling time)*/ +} OPL3; + + + +/* mapping of register number (offset) to slot number used by the emulator */ +static const int slot_array[32]= +{ + 0, 2, 4, 1, 3, 5,-1,-1, + 6, 8,10, 7, 9,11,-1,-1, + 12,14,16,13,15,17,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1 +}; + +/* key scale level */ +/* table is 3dB/octave , DV converts this into 6dB/octave */ +/* 0.1875 is bit 0 weight of the envelope counter (volume) expressed in the 'decibel' scale */ +#define DV (0.1875/2.0) +static const UINT32 ksl_tab[8*16]= +{ + /* OCT 0 */ + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + /* OCT 1 */ + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.750/DV, 1.125/DV, 1.500/DV, + 1.875/DV, 2.250/DV, 2.625/DV, 3.000/DV, + /* OCT 2 */ + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 1.125/DV, 1.875/DV, 2.625/DV, + 3.000/DV, 3.750/DV, 4.125/DV, 4.500/DV, + 4.875/DV, 5.250/DV, 5.625/DV, 6.000/DV, + /* OCT 3 */ + 0.000/DV, 0.000/DV, 0.000/DV, 1.875/DV, + 3.000/DV, 4.125/DV, 4.875/DV, 5.625/DV, + 6.000/DV, 6.750/DV, 7.125/DV, 7.500/DV, + 7.875/DV, 8.250/DV, 8.625/DV, 9.000/DV, + /* OCT 4 */ + 0.000/DV, 0.000/DV, 3.000/DV, 4.875/DV, + 6.000/DV, 7.125/DV, 7.875/DV, 8.625/DV, + 9.000/DV, 9.750/DV,10.125/DV,10.500/DV, + 10.875/DV,11.250/DV,11.625/DV,12.000/DV, + /* OCT 5 */ + 0.000/DV, 3.000/DV, 6.000/DV, 7.875/DV, + 9.000/DV,10.125/DV,10.875/DV,11.625/DV, + 12.000/DV,12.750/DV,13.125/DV,13.500/DV, + 13.875/DV,14.250/DV,14.625/DV,15.000/DV, + /* OCT 6 */ + 0.000/DV, 6.000/DV, 9.000/DV,10.875/DV, + 12.000/DV,13.125/DV,13.875/DV,14.625/DV, + 15.000/DV,15.750/DV,16.125/DV,16.500/DV, + 16.875/DV,17.250/DV,17.625/DV,18.000/DV, + /* OCT 7 */ + 0.000/DV, 9.000/DV,12.000/DV,13.875/DV, + 15.000/DV,16.125/DV,16.875/DV,17.625/DV, + 18.000/DV,18.750/DV,19.125/DV,19.500/DV, + 19.875/DV,20.250/DV,20.625/DV,21.000/DV +}; +#undef DV + +/* sustain level table (3dB per step) */ +/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ +#define SC(db) (UINT32) ( db * (2.0/ENV_STEP) ) +static const UINT32 sl_tab[16]={ + SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7), + SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31) +}; +#undef SC + + +#define RATE_STEPS (8) +static const unsigned char eg_inc[15*RATE_STEPS]={ + +/*cycle:0 1 2 3 4 5 6 7*/ + +/* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..12 0 (increment by 0 or 1) */ +/* 1 */ 0,1, 0,1, 1,1, 0,1, /* rates 00..12 1 */ +/* 2 */ 0,1, 1,1, 0,1, 1,1, /* rates 00..12 2 */ +/* 3 */ 0,1, 1,1, 1,1, 1,1, /* rates 00..12 3 */ + +/* 4 */ 1,1, 1,1, 1,1, 1,1, /* rate 13 0 (increment by 1) */ +/* 5 */ 1,1, 1,2, 1,1, 1,2, /* rate 13 1 */ +/* 6 */ 1,2, 1,2, 1,2, 1,2, /* rate 13 2 */ +/* 7 */ 1,2, 2,2, 1,2, 2,2, /* rate 13 3 */ + +/* 8 */ 2,2, 2,2, 2,2, 2,2, /* rate 14 0 (increment by 2) */ +/* 9 */ 2,2, 2,4, 2,2, 2,4, /* rate 14 1 */ +/*10 */ 2,4, 2,4, 2,4, 2,4, /* rate 14 2 */ +/*11 */ 2,4, 4,4, 2,4, 4,4, /* rate 14 3 */ + +/*12 */ 4,4, 4,4, 4,4, 4,4, /* rates 15 0, 15 1, 15 2, 15 3 for decay */ +/*13 */ 8,8, 8,8, 8,8, 8,8, /* rates 15 0, 15 1, 15 2, 15 3 for attack (zero time) */ +/*14 */ 0,0, 0,0, 0,0, 0,0, /* infinity rates for attack and decay(s) */ +}; + + +#define O(a) (a*RATE_STEPS) + +/* note that there is no O(13) in this table - it's directly in the code */ +static const unsigned char eg_rate_select[16+64+16]={ /* Envelope Generator rates (16 + 64 rates + 16 RKS) */ +/* 16 infinite time rates */ +O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), +O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), + +/* rates 00-12 */ +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), + +/* rate 13 */ +O( 4),O( 5),O( 6),O( 7), + +/* rate 14 */ +O( 8),O( 9),O(10),O(11), + +/* rate 15 */ +O(12),O(12),O(12),O(12), + +/* 16 dummy rates (same as 15 3) */ +O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12), +O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12), + +}; +#undef O + +/*rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 */ +/*shift 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0 */ +/*mask 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0, 0 */ + +#define O(a) (a*1) +static const unsigned char eg_rate_shift[16+64+16]={ /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */ +/* 16 infinite time rates */ +O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), +O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), + +/* rates 00-12 */ +O(12),O(12),O(12),O(12), +O(11),O(11),O(11),O(11), +O(10),O(10),O(10),O(10), +O( 9),O( 9),O( 9),O( 9), +O( 8),O( 8),O( 8),O( 8), +O( 7),O( 7),O( 7),O( 7), +O( 6),O( 6),O( 6),O( 6), +O( 5),O( 5),O( 5),O( 5), +O( 4),O( 4),O( 4),O( 4), +O( 3),O( 3),O( 3),O( 3), +O( 2),O( 2),O( 2),O( 2), +O( 1),O( 1),O( 1),O( 1), +O( 0),O( 0),O( 0),O( 0), + +/* rate 13 */ +O( 0),O( 0),O( 0),O( 0), + +/* rate 14 */ +O( 0),O( 0),O( 0),O( 0), + +/* rate 15 */ +O( 0),O( 0),O( 0),O( 0), + +/* 16 dummy rates (same as 15 3) */ +O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), +O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), + +}; +#undef O + + +/* multiple table */ +#define ML 2 +static const UINT8 mul_tab[16]= { +/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,10,12,12,15,15 */ + 0.50*ML, 1.00*ML, 2.00*ML, 3.00*ML, 4.00*ML, 5.00*ML, 6.00*ML, 7.00*ML, + 8.00*ML, 9.00*ML,10.00*ML,10.00*ML,12.00*ML,12.00*ML,15.00*ML,15.00*ML +}; +#undef ML + +/* TL_TAB_LEN is calculated as: + +* (12+1)=13 - sinus amplitude bits (Y axis) +* additional 1: to compensate for calculations of negative part of waveform +* (if we don't add it then the greatest possible _negative_ value would be -2 +* and we really need -1 for waveform #7) +* 2 - sinus sign bit (Y axis) +* TL_RES_LEN - sinus resolution (X axis) +*/ +#define TL_TAB_LEN (13*2*TL_RES_LEN) +static signed int tl_tab[TL_TAB_LEN]; + +#define ENV_QUIET (TL_TAB_LEN>>4) + +/* sin waveform table in 'decibel' scale */ +/* there are eight waveforms on OPL3 chips */ +static unsigned int sin_tab[SIN_LEN * 8]; + + +/* LFO Amplitude Modulation table (verified on real YM3812) + 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples + + Length: 210 elements. + + Each of the elements has to be repeated + exactly 64 times (on 64 consecutive samples). + The whole table takes: 64 * 210 = 13440 samples. + + When AM = 1 data is used directly + When AM = 0 data is divided by 4 before being used (loosing precision is important) +*/ + +#define LFO_AM_TAB_ELEMENTS 210 + +static const UINT8 lfo_am_table[LFO_AM_TAB_ELEMENTS] = { +0,0,0,0,0,0,0, +1,1,1,1, +2,2,2,2, +3,3,3,3, +4,4,4,4, +5,5,5,5, +6,6,6,6, +7,7,7,7, +8,8,8,8, +9,9,9,9, +10,10,10,10, +11,11,11,11, +12,12,12,12, +13,13,13,13, +14,14,14,14, +15,15,15,15, +16,16,16,16, +17,17,17,17, +18,18,18,18, +19,19,19,19, +20,20,20,20, +21,21,21,21, +22,22,22,22, +23,23,23,23, +24,24,24,24, +25,25,25,25, +26,26,26, +25,25,25,25, +24,24,24,24, +23,23,23,23, +22,22,22,22, +21,21,21,21, +20,20,20,20, +19,19,19,19, +18,18,18,18, +17,17,17,17, +16,16,16,16, +15,15,15,15, +14,14,14,14, +13,13,13,13, +12,12,12,12, +11,11,11,11, +10,10,10,10, +9,9,9,9, +8,8,8,8, +7,7,7,7, +6,6,6,6, +5,5,5,5, +4,4,4,4, +3,3,3,3, +2,2,2,2, +1,1,1,1 +}; + +/* LFO Phase Modulation table (verified on real YM3812) */ +static const INT8 lfo_pm_table[8*8*2] = { + +/* FNUM2/FNUM = 00 0xxxxxxx (0x0000) */ +0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/ +0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 00 1xxxxxxx (0x0080) */ +0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/ +1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 01 0xxxxxxx (0x0100) */ +1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/ +2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 01 1xxxxxxx (0x0180) */ +1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/ +3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 10 0xxxxxxx (0x0200) */ +2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/ +4, 2, 0,-2,-4,-2, 0, 2, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 10 1xxxxxxx (0x0280) */ +2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/ +5, 2, 0,-2,-5,-2, 0, 2, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 11 0xxxxxxx (0x0300) */ +3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/ +6, 3, 0,-3,-6,-3, 0, 3, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 11 1xxxxxxx (0x0380) */ +3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/ +7, 3, 0,-3,-7,-3, 0, 3 /*LFO PM depth = 1*/ +}; + + +/* lock level of common table */ +static int num_lock = 0; + +/* work table */ +static void *cur_chip = NULL; /* current chip point */ +static OPL3_SLOT *SLOT7_1,*SLOT7_2,*SLOT8_1,*SLOT8_2; + +static signed int phase_modulation; /* phase modulation input (SLOT 2) */ +static signed int phase_modulation2; /* phase modulation input (SLOT 3 in 4 operator channels) */ +static signed int chanout[18]; /* 18 channels */ + + +static UINT32 LFO_AM; +static INT32 LFO_PM; + + + +INLINE int limit( int val, int max, int min ) { + if ( val > max ) + val = max; + else if ( val < min ) + val = min; + + return val; +} + + +/* status set and IRQ handling */ +INLINE void OPL3_STATUS_SET(OPL3 *chip,int flag) +{ + /* set status flag masking out disabled IRQs */ + chip->status |= (flag & chip->statusmask); + if(!(chip->status & 0x80)) + { + if(chip->status & 0x7f) + { /* IRQ on */ + chip->status |= 0x80; + /* callback user interrupt handler (IRQ is OFF to ON) */ + if(chip->IRQHandler) (chip->IRQHandler)(chip->IRQParam,1); + } + } +} + +/* status reset and IRQ handling */ +INLINE void OPL3_STATUS_RESET(OPL3 *chip,int flag) +{ + /* reset status flag */ + chip->status &= ~flag; + if(chip->status & 0x80) + { + if (!(chip->status & 0x7f)) + { + chip->status &= 0x7f; + /* callback user interrupt handler (IRQ is ON to OFF) */ + if(chip->IRQHandler) (chip->IRQHandler)(chip->IRQParam,0); + } + } +} + +/* IRQ mask set */ +INLINE void OPL3_STATUSMASK_SET(OPL3 *chip,int flag) +{ + chip->statusmask = flag; + /* IRQ handling check */ + OPL3_STATUS_SET(chip,0); + OPL3_STATUS_RESET(chip,0); +} + + +/* advance LFO to next sample */ +INLINE void advance_lfo(OPL3 *chip) +{ + UINT8 tmp; + + /* LFO */ + chip->lfo_am_cnt += chip->lfo_am_inc; + if (chip->lfo_am_cnt >= (LFO_AM_TAB_ELEMENTS<lfo_am_cnt -= (LFO_AM_TAB_ELEMENTS<lfo_am_cnt >> LFO_SH ]; + + if (chip->lfo_am_depth) + LFO_AM = tmp; + else + LFO_AM = tmp>>2; + + chip->lfo_pm_cnt += chip->lfo_pm_inc; + LFO_PM = ((chip->lfo_pm_cnt>>LFO_SH) & 7) | chip->lfo_pm_depth_range; +} + +/* advance to next sample */ +INLINE void advance(OPL3 *chip) +{ + OPL3_CH *CH; + OPL3_SLOT *op; + int i; + +//profiler_mark(PROFILER_USER3); + chip->eg_timer += chip->eg_timer_add; + + while (chip->eg_timer >= chip->eg_timer_overflow) + { + chip->eg_timer -= chip->eg_timer_overflow; + + chip->eg_cnt++; + + for (i=0; i<9*2*2; i++) + { + CH = &chip->P_CH[i/2]; + op = &CH->SLOT[i&1]; +#if 1 + /* Envelope Generator */ + switch(op->state) + { + case EG_ATT: /* attack phase */ +// if ( !(chip->eg_cnt & ((1<eg_sh_ar)-1) ) ) + if ( !(chip->eg_cnt & op->eg_m_ar) ) + { + op->volume += (~op->volume * + (eg_inc[op->eg_sel_ar + ((chip->eg_cnt>>op->eg_sh_ar)&7)]) + ) >>3; + + if (op->volume <= MIN_ATT_INDEX) + { + op->volume = MIN_ATT_INDEX; + op->state = EG_DEC; + } + + } + break; + + case EG_DEC: /* decay phase */ +// if ( !(chip->eg_cnt & ((1<eg_sh_dr)-1) ) ) + if ( !(chip->eg_cnt & op->eg_m_dr) ) + { + op->volume += eg_inc[op->eg_sel_dr + ((chip->eg_cnt>>op->eg_sh_dr)&7)]; + + if ( op->volume >= op->sl ) + op->state = EG_SUS; + + } + break; + + case EG_SUS: /* sustain phase */ + + /* this is important behaviour: + one can change percusive/non-percussive modes on the fly and + the chip will remain in sustain phase - verified on real YM3812 */ + + if(op->eg_type) /* non-percussive mode */ + { + /* do nothing */ + } + else /* percussive mode */ + { + /* during sustain phase chip adds Release Rate (in percussive mode) */ +// if ( !(chip->eg_cnt & ((1<eg_sh_rr)-1) ) ) + if ( !(chip->eg_cnt & op->eg_m_rr) ) + { + op->volume += eg_inc[op->eg_sel_rr + ((chip->eg_cnt>>op->eg_sh_rr)&7)]; + + if ( op->volume >= MAX_ATT_INDEX ) + op->volume = MAX_ATT_INDEX; + } + /* else do nothing in sustain phase */ + } + break; + + case EG_REL: /* release phase */ +// if ( !(chip->eg_cnt & ((1<eg_sh_rr)-1) ) ) + if ( !(chip->eg_cnt & op->eg_m_rr) ) + { + op->volume += eg_inc[op->eg_sel_rr + ((chip->eg_cnt>>op->eg_sh_rr)&7)]; + + if ( op->volume >= MAX_ATT_INDEX ) + { + op->volume = MAX_ATT_INDEX; + op->state = EG_OFF; + } + + } + break; + + default: + break; + } +#endif + } + } +//profiler_mark(PROFILER_END); + +//profiler_mark(PROFILER_USER4); + for (i=0; i<9*2*2; i++) + { + CH = &chip->P_CH[i/2]; + op = &CH->SLOT[i&1]; + + /* Phase Generator */ + if(op->vib) + { + UINT8 block; + unsigned int block_fnum = CH->block_fnum; + + unsigned int fnum_lfo = (block_fnum&0x0380) >> 7; + + signed int lfo_fn_table_index_offset = lfo_pm_table[LFO_PM + 16*fnum_lfo ]; + + if (lfo_fn_table_index_offset) /* LFO phase modulation active */ + { + block_fnum += lfo_fn_table_index_offset; + block = (block_fnum&0x1c00) >> 10; + op->Cnt += (chip->fn_tab[block_fnum&0x03ff] >> (7-block)) * op->mul; + } + else /* LFO phase modulation = zero */ + { + op->Cnt += op->Incr; + } + } + else /* LFO phase modulation disabled for this operator */ + { + op->Cnt += op->Incr; + } + } +//profiler_mark(PROFILER_END); + + /* The Noise Generator of the YM3812 is 23-bit shift register. + * Period is equal to 2^23-2 samples. + * Register works at sampling frequency of the chip, so output + * can change on every sample. + * + * Output of the register and input to the bit 22 is: + * bit0 XOR bit14 XOR bit15 XOR bit22 + * + * Simply use bit 22 as the noise output. + */ + + chip->noise_p += chip->noise_f; + i = chip->noise_p >> FREQ_SH; /* number of events (shifts of the shift register) */ + chip->noise_p &= FREQ_MASK; + while (i) + { + /* + UINT32 j; + j = ( (chip->noise_rng) ^ (chip->noise_rng>>14) ^ (chip->noise_rng>>15) ^ (chip->noise_rng>>22) ) & 1; + chip->noise_rng = (j<<22) | (chip->noise_rng>>1); + */ + + /* + Instead of doing all the logic operations above, we + use a trick here (and use bit 0 as the noise output). + The difference is only that the noise bit changes one + step ahead. This doesn't matter since we don't know + what is real state of the noise_rng after the reset. + */ + + if (chip->noise_rng & 1) chip->noise_rng ^= 0x800302; + chip->noise_rng >>= 1; + + i--; + } +} + + +INLINE signed int op_calc(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab) +{ + UINT32 p; + + p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + (pm<<16))) >> FREQ_SH ) & SIN_MASK) ]; + + if (p >= TL_TAB_LEN) + return 0; + return tl_tab[p]; +} + +INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab) +{ + UINT32 p; + + p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + pm))>>FREQ_SH) & SIN_MASK)]; + + if (p >= TL_TAB_LEN) + return 0; + return tl_tab[p]; +} + + +#define volume_calc(OP) ((OP)->TLL + ((UINT32)(OP)->volume) + (LFO_AM & (OP)->AMmask)) + +/* calculate output of a standard 2 operator channel + (or 1st part of a 4-op channel) */ +INLINE void chan_calc( OPL3_CH *CH ) +{ + OPL3_SLOT *SLOT; + unsigned int env; + signed int out; + + phase_modulation = 0; + phase_modulation2= 0; + + /* SLOT 1 */ + SLOT = &CH->SLOT[SLOT1]; + env = volume_calc(SLOT); + out = SLOT->op1_out[0] + SLOT->op1_out[1]; + SLOT->op1_out[0] = SLOT->op1_out[1]; + SLOT->op1_out[1] = 0; + if( env < ENV_QUIET ) + { + if (!SLOT->FB) + out = 0; + SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB), SLOT->wavetable ); + } + *SLOT->connect += SLOT->op1_out[1]; +//logerror("out0=%5i vol0=%4i ", SLOT->op1_out[1], env ); + + /* SLOT 2 */ + SLOT++; + env = volume_calc(SLOT); + if( env < ENV_QUIET ) + *SLOT->connect += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable); + +//logerror("out1=%5i vol1=%4i\n", op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable), env ); + +} + +/* calculate output of a 2nd part of 4-op channel */ +INLINE void chan_calc_ext( OPL3_CH *CH ) +{ + OPL3_SLOT *SLOT; + unsigned int env; + + phase_modulation = 0; + + /* SLOT 1 */ + SLOT = &CH->SLOT[SLOT1]; + env = volume_calc(SLOT); + if( env < ENV_QUIET ) + *SLOT->connect += op_calc(SLOT->Cnt, env, phase_modulation2, SLOT->wavetable ); + + /* SLOT 2 */ + SLOT++; + env = volume_calc(SLOT); + if( env < ENV_QUIET ) + *SLOT->connect += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable); + +} + +/* + operators used in the rhythm sounds generation process: + + Envelope Generator: + +channel operator register number Bass High Snare Tom Top +/ slot number TL ARDR SLRR Wave Drum Hat Drum Tom Cymbal + 6 / 0 12 50 70 90 f0 + + 6 / 1 15 53 73 93 f3 + + 7 / 0 13 51 71 91 f1 + + 7 / 1 16 54 74 94 f4 + + 8 / 0 14 52 72 92 f2 + + 8 / 1 17 55 75 95 f5 + + + Phase Generator: + +channel operator register number Bass High Snare Tom Top +/ slot number MULTIPLE Drum Hat Drum Tom Cymbal + 6 / 0 12 30 + + 6 / 1 15 33 + + 7 / 0 13 31 + + + + 7 / 1 16 34 ----- n o t u s e d ----- + 8 / 0 14 32 + + 8 / 1 17 35 + + + +channel operator register number Bass High Snare Tom Top +number number BLK/FNUM2 FNUM Drum Hat Drum Tom Cymbal + 6 12,15 B6 A6 + + + 7 13,16 B7 A7 + + + + + 8 14,17 B8 A8 + + + + +*/ + +/* calculate rhythm */ + +INLINE void chan_calc_rhythm( OPL3_CH *CH, unsigned int noise ) +{ + OPL3_SLOT *SLOT; + signed int out; + unsigned int env; + + + /* Bass Drum (verified on real YM3812): + - depends on the channel 6 'connect' register: + when connect = 0 it works the same as in normal (non-rhythm) mode (op1->op2->out) + when connect = 1 _only_ operator 2 is present on output (op2->out), operator 1 is ignored + - output sample always is multiplied by 2 + */ + + phase_modulation = 0; + + /* SLOT 1 */ + SLOT = &CH[6].SLOT[SLOT1]; + env = volume_calc(SLOT); + + out = SLOT->op1_out[0] + SLOT->op1_out[1]; + SLOT->op1_out[0] = SLOT->op1_out[1]; + + if (!SLOT->CON) + phase_modulation = SLOT->op1_out[0]; + //else ignore output of operator 1 + + SLOT->op1_out[1] = 0; + if( env < ENV_QUIET ) + { + if (!SLOT->FB) + out = 0; + SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB), SLOT->wavetable ); + } + + /* SLOT 2 */ + SLOT++; + env = volume_calc(SLOT); + if( env < ENV_QUIET ) + chanout[6] += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable) * 2; + + + /* Phase generation is based on: */ + // HH (13) channel 7->slot 1 combined with channel 8->slot 2 (same combination as TOP CYMBAL but different output phases) + // SD (16) channel 7->slot 1 + // TOM (14) channel 8->slot 1 + // TOP (17) channel 7->slot 1 combined with channel 8->slot 2 (same combination as HIGH HAT but different output phases) + + /* Envelope generation based on: */ + // HH channel 7->slot1 + // SD channel 7->slot2 + // TOM channel 8->slot1 + // TOP channel 8->slot2 + + + /* The following formulas can be well optimized. + I leave them in direct form for now (in case I've missed something). + */ + + /* High Hat (verified on real YM3812) */ + env = volume_calc(SLOT7_1); + if( env < ENV_QUIET ) + { + + /* high hat phase generation: + phase = d0 or 234 (based on frequency only) + phase = 34 or 2d0 (based on noise) + */ + + /* base frequency derived from operator 1 in channel 7 */ + unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1; + unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1; + unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1; + + unsigned char res1 = (bit2 ^ bit7) | bit3; + + /* when res1 = 0 phase = 0x000 | 0xd0; */ + /* when res1 = 1 phase = 0x200 | (0xd0>>2); */ + UINT32 phase = res1 ? (0x200|(0xd0>>2)) : 0xd0; + + /* enable gate based on frequency of operator 2 in channel 8 */ + unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1; + unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1; + + unsigned char res2 = (bit3e ^ bit5e); + + /* when res2 = 0 pass the phase from calculation above (res1); */ + /* when res2 = 1 phase = 0x200 | (0xd0>>2); */ + if (res2) + phase = (0x200|(0xd0>>2)); + + + /* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */ + /* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */ + if (phase&0x200) + { + if (noise) + phase = 0x200|0xd0; + } + else + /* when phase & 0x200 is clear and noise=1 then phase = 0xd0>>2 */ + /* when phase & 0x200 is clear and noise=0 then phase = 0xd0, ie no change */ + { + if (noise) + phase = 0xd0>>2; + } + + chanout[7] += op_calc(phase<wavetable) * 2; + } + + /* Snare Drum (verified on real YM3812) */ + env = volume_calc(SLOT7_2); + if( env < ENV_QUIET ) + { + /* base frequency derived from operator 1 in channel 7 */ + unsigned char bit8 = ((SLOT7_1->Cnt>>FREQ_SH)>>8)&1; + + /* when bit8 = 0 phase = 0x100; */ + /* when bit8 = 1 phase = 0x200; */ + UINT32 phase = bit8 ? 0x200 : 0x100; + + /* Noise bit XOR'es phase by 0x100 */ + /* when noisebit = 0 pass the phase from calculation above */ + /* when noisebit = 1 phase ^= 0x100; */ + /* in other words: phase ^= (noisebit<<8); */ + if (noise) + phase ^= 0x100; + + chanout[7] += op_calc(phase<wavetable) * 2; + } + + /* Tom Tom (verified on real YM3812) */ + env = volume_calc(SLOT8_1); + if( env < ENV_QUIET ) + chanout[8] += op_calc(SLOT8_1->Cnt, env, 0, SLOT8_1->wavetable) * 2; + + /* Top Cymbal (verified on real YM3812) */ + env = volume_calc(SLOT8_2); + if( env < ENV_QUIET ) + { + /* base frequency derived from operator 1 in channel 7 */ + unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1; + unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1; + unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1; + + unsigned char res1 = (bit2 ^ bit7) | bit3; + + /* when res1 = 0 phase = 0x000 | 0x100; */ + /* when res1 = 1 phase = 0x200 | 0x100; */ + UINT32 phase = res1 ? 0x300 : 0x100; + + /* enable gate based on frequency of operator 2 in channel 8 */ + unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1; + unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1; + + unsigned char res2 = (bit3e ^ bit5e); + /* when res2 = 0 pass the phase from calculation above (res1); */ + /* when res2 = 1 phase = 0x200 | 0x100; */ + if (res2) + phase = 0x300; + + chanout[8] += op_calc(phase<wavetable) * 2; + } + +} + + +/* generic table initialize */ +static int init_tables(void) +{ + signed int i,x; + signed int n; + double o,m; + + + for (x=0; x>= 4; /* 12 bits here */ + if (n&1) /* round to nearest */ + n = (n>>1)+1; + else + n = n>>1; + /* 11 bits here (rounded) */ + n <<= 1; /* 12 bits here (as in real chip) */ + tl_tab[ x*2 + 0 ] = n; + tl_tab[ x*2 + 1 ] = ~tl_tab[ x*2 + 0 ]; /* this *is* different from OPL2 (verified on real YMF262) */ + + for (i=1; i<13; i++) + { + tl_tab[ x*2+0 + i*2*TL_RES_LEN ] = tl_tab[ x*2+0 ]>>i; + tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = ~tl_tab[ x*2+0 + i*2*TL_RES_LEN ]; /* this *is* different from OPL2 (verified on real YMF262) */ + } + #if 0 + logerror("tl %04i", x*2); + for (i=0; i<13; i++) + logerror(", [%02i] %5i", i*2, tl_tab[ x*2 +0 + i*2*TL_RES_LEN ] ); /* positive */ + logerror("\n"); + + logerror("tl %04i", x*2); + for (i=0; i<13; i++) + logerror(", [%02i] %5i", i*2, tl_tab[ x*2 +1 + i*2*TL_RES_LEN ] ); /* negative */ + logerror("\n"); + #endif + } + + for (i=0; i0.0) + o = 8*log(1.0/m)/log(2.0); /* convert to 'decibels' */ + else + o = 8*log(-1.0/m)/log(2.0); /* convert to 'decibels' */ + + o = o / (ENV_STEP/4); + + n = (int)(2.0*o); + if (n&1) /* round to nearest */ + n = (n>>1)+1; + else + n = n>>1; + + sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 ); + + /*logerror("YMF262.C: sin [%4i (hex=%03x)]= %4i (tl_tab value=%5i)\n", i, i, sin_tab[i], tl_tab[sin_tab[i]] );*/ + } + + for (i=0; i>1) ]; + + /* waveform 3: _ _ _ _ */ + /* / |_/ |_/ |_/ |_*/ + /* abs(output only first quarter of the sinus waveform) */ + + if (i & (1<<(SIN_BITS-2)) ) + sin_tab[3*SIN_LEN+i] = TL_TAB_LEN; + else + sin_tab[3*SIN_LEN+i] = sin_tab[i & (SIN_MASK>>2)]; + + /* waveform 4: */ + /* /\ ____/\ ____*/ + /* \/ \/ */ + /* output whole sinus waveform in half the cycle(step=2) and output 0 on the other half of cycle */ + + if (i & (1<<(SIN_BITS-1)) ) + sin_tab[4*SIN_LEN+i] = TL_TAB_LEN; + else + sin_tab[4*SIN_LEN+i] = sin_tab[i*2]; + + /* waveform 5: */ + /* /\/\____/\/\____*/ + /* */ + /* output abs(whole sinus) waveform in half the cycle(step=2) and output 0 on the other half of cycle */ + + if (i & (1<<(SIN_BITS-1)) ) + sin_tab[5*SIN_LEN+i] = TL_TAB_LEN; + else + sin_tab[5*SIN_LEN+i] = sin_tab[(i*2) & (SIN_MASK>>1) ]; + + /* waveform 6: ____ ____ */ + /* */ + /* ____ ____*/ + /* output maximum in half the cycle and output minimum on the other half of cycle */ + + if (i & (1<<(SIN_BITS-1)) ) + sin_tab[6*SIN_LEN+i] = 1; /* negative */ + else + sin_tab[6*SIN_LEN+i] = 0; /* positive */ + + /* waveform 7: */ + /* |\____ |\____ */ + /* \| \|*/ + /* output sawtooth waveform */ + + if (i & (1<<(SIN_BITS-1)) ) + x = ((SIN_LEN-1)-i)*16 + 1; /* negative: from 8177 to 1 */ + else + x = i*16; /*positive: from 0 to 8176 */ + + if (x > TL_TAB_LEN) + x = TL_TAB_LEN; /* clip to the allowed range */ + + sin_tab[7*SIN_LEN+i] = x; + + //logerror("YMF262.C: sin1[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[1*SIN_LEN+i], tl_tab[sin_tab[1*SIN_LEN+i]] ); + //logerror("YMF262.C: sin2[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[2*SIN_LEN+i], tl_tab[sin_tab[2*SIN_LEN+i]] ); + //logerror("YMF262.C: sin3[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[3*SIN_LEN+i], tl_tab[sin_tab[3*SIN_LEN+i]] ); + //logerror("YMF262.C: sin4[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[4*SIN_LEN+i], tl_tab[sin_tab[4*SIN_LEN+i]] ); + //logerror("YMF262.C: sin5[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[5*SIN_LEN+i], tl_tab[sin_tab[5*SIN_LEN+i]] ); + //logerror("YMF262.C: sin6[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[6*SIN_LEN+i], tl_tab[sin_tab[6*SIN_LEN+i]] ); + //logerror("YMF262.C: sin7[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[7*SIN_LEN+i], tl_tab[sin_tab[7*SIN_LEN+i]] ); + } + /*logerror("YMF262.C: ENV_QUIET= %08x (dec*8=%i)\n", ENV_QUIET, ENV_QUIET*8 );*/ + +#ifdef SAVE_SAMPLE + sample[0]=fopen("sampsum.pcm","wb"); +#endif + + return 1; +} + +static void OPLCloseTable( void ) +{ +#ifdef SAVE_SAMPLE + fclose(sample[0]); +#endif +} + + + +static void OPL3_initalize(OPL3 *chip) +{ + int i; + + /* frequency base */ + chip->freqbase = (chip->rate) ? ((double)chip->clock / (8.0*36)) / chip->rate : 0; +#if 0 + chip->rate = (double)chip->clock / (8.0*36); + chip->freqbase = 1.0; +#endif + + /* logerror("YMF262: freqbase=%f\n", chip->freqbase); */ + + /* Timer base time */ + chip->TimerBase = 1.0 / ((double)chip->clock / (8.0*36) ); + + /* make fnumber -> increment counter table */ + for( i=0 ; i < 1024 ; i++ ) + { + /* opn phase increment counter = 20bit */ + chip->fn_tab[i] = (UINT32)( (double)i * 64 * chip->freqbase * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */ +#if 0 + logerror("YMF262.C: fn_tab[%4i] = %08x (dec=%8i)\n", + i, chip->fn_tab[i]>>6, chip->fn_tab[i]>>6 ); +#endif + } + +#if 0 + for( i=0 ; i < 16 ; i++ ) + { + logerror("YMF262.C: sl_tab[%i] = %08x\n", + i, sl_tab[i] ); + } + for( i=0 ; i < 8 ; i++ ) + { + int j; + logerror("YMF262.C: ksl_tab[oct=%2i] =",i); + for (j=0; j<16; j++) + { + logerror("%08x ", ksl_tab[i*16+j] ); + } + logerror("\n"); + } +#endif + + + /* Amplitude modulation: 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */ + /* One entry from LFO_AM_TABLE lasts for 64 samples */ + chip->lfo_am_inc = (1.0 / 64.0 ) * (1<freqbase; + + /* Vibrato: 8 output levels (triangle waveform); 1 level takes 1024 samples */ + chip->lfo_pm_inc = (1.0 / 1024.0) * (1<freqbase; + + /*logerror ("chip->lfo_am_inc = %8x ; chip->lfo_pm_inc = %8x\n", chip->lfo_am_inc, chip->lfo_pm_inc);*/ + + /* Noise generator: a step takes 1 sample */ + chip->noise_f = (1.0 / 1.0) * (1<freqbase; + + chip->eg_timer_add = (1<freqbase; + chip->eg_timer_overflow = ( 1 ) * (1<eg_timer_add, chip->eg_timer_overflow);*/ + +} + +INLINE void FM_KEYON(OPL3_SLOT *SLOT, UINT32 key_set) +{ + if( !SLOT->key ) + { + /* restart Phase Generator */ + SLOT->Cnt = 0; + /* phase -> Attack */ + SLOT->state = EG_ATT; + } + SLOT->key |= key_set; +} + +INLINE void FM_KEYOFF(OPL3_SLOT *SLOT, UINT32 key_clr) +{ + if( SLOT->key ) + { + SLOT->key &= key_clr; + + if( !SLOT->key ) + { + /* phase -> Release */ + if (SLOT->state>EG_REL) + SLOT->state = EG_REL; + } + } +} + +/* update phase increment counter of operator (also update the EG rates if necessary) */ +INLINE void CALC_FCSLOT(OPL3_CH *CH,OPL3_SLOT *SLOT) +{ + int ksr; + + /* (frequency) phase increment counter */ + SLOT->Incr = CH->fc * SLOT->mul; + ksr = CH->kcode >> SLOT->KSR; + + if( SLOT->ksr != ksr ) + { + SLOT->ksr = ksr; + + /* calculate envelope generator rates */ + if ((SLOT->ar + SLOT->ksr) < 16+60) + { + SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; + SLOT->eg_m_ar = (1<eg_sh_ar)-1; + SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; + } + else + { + SLOT->eg_sh_ar = 0; + SLOT->eg_m_ar = (1<eg_sh_ar)-1; + SLOT->eg_sel_ar = 13*RATE_STEPS; + } + SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; + SLOT->eg_m_dr = (1<eg_sh_dr)-1; + SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; + SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; + SLOT->eg_m_rr = (1<eg_sh_rr)-1; + SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; + } +} + +/* set multi,am,vib,EG-TYP,KSR,mul */ +INLINE void set_mul(OPL3 *chip,int slot,int v) +{ + OPL3_CH *CH = &chip->P_CH[slot/2]; + OPL3_SLOT *SLOT = &CH->SLOT[slot&1]; + + SLOT->mul = mul_tab[v&0x0f]; + SLOT->KSR = (v&0x10) ? 0 : 2; + SLOT->eg_type = (v&0x20); + SLOT->vib = (v&0x40); + SLOT->AMmask = (v&0x80) ? ~0 : 0; + + if (chip->OPL3_mode & 1) + { + int chan_no = slot/2; + + /* in OPL3 mode */ + //DO THIS: + //if this is one of the slots of 1st channel forming up a 4-op channel + //do normal operation + //else normal 2 operator function + //OR THIS: + //if this is one of the slots of 2nd channel forming up a 4-op channel + //update it using channel data of 1st channel of a pair + //else normal 2 operator function + switch(chan_no) + { + case 0: case 1: case 2: + case 9: case 10: case 11: + if (CH->extended) + { + /* normal */ + CALC_FCSLOT(CH,SLOT); + } + else + { + /* normal */ + CALC_FCSLOT(CH,SLOT); + } + break; + case 3: case 4: case 5: + case 12: case 13: case 14: + if ((CH-3)->extended) + { + /* update this SLOT using frequency data for 1st channel of a pair */ + CALC_FCSLOT(CH-3,SLOT); + } + else + { + /* normal */ + CALC_FCSLOT(CH,SLOT); + } + break; + default: + /* normal */ + CALC_FCSLOT(CH,SLOT); + break; + } + } + else + { + /* in OPL2 mode */ + CALC_FCSLOT(CH,SLOT); + } +} + +/* set ksl & tl */ +INLINE void set_ksl_tl(OPL3 *chip,int slot,int v) +{ + OPL3_CH *CH = &chip->P_CH[slot/2]; + OPL3_SLOT *SLOT = &CH->SLOT[slot&1]; + + int ksl = v>>6; /* 0 / 1.5 / 3.0 / 6.0 dB/OCT */ + + SLOT->ksl = ksl ? 3-ksl : 31; + SLOT->TL = (v&0x3f)<<(ENV_BITS-1-7); /* 7 bits TL (bit 6 = always 0) */ + + if (chip->OPL3_mode & 1) + { + int chan_no = slot/2; + + /* in OPL3 mode */ + //DO THIS: + //if this is one of the slots of 1st channel forming up a 4-op channel + //do normal operation + //else normal 2 operator function + //OR THIS: + //if this is one of the slots of 2nd channel forming up a 4-op channel + //update it using channel data of 1st channel of a pair + //else normal 2 operator function + switch(chan_no) + { + case 0: case 1: case 2: + case 9: case 10: case 11: + if (CH->extended) + { + /* normal */ + SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); + } + else + { + /* normal */ + SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); + } + break; + case 3: case 4: case 5: + case 12: case 13: case 14: + if ((CH-3)->extended) + { + /* update this SLOT using frequency data for 1st channel of a pair */ + SLOT->TLL = SLOT->TL + ((CH-3)->ksl_base>>SLOT->ksl); + } + else + { + /* normal */ + SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); + } + break; + default: + /* normal */ + SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); + break; + } + } + else + { + /* in OPL2 mode */ + SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); + } + +} + +/* set attack rate & decay rate */ +INLINE void set_ar_dr(OPL3 *chip,int slot,int v) +{ + OPL3_CH *CH = &chip->P_CH[slot/2]; + OPL3_SLOT *SLOT = &CH->SLOT[slot&1]; + + SLOT->ar = (v>>4) ? 16 + ((v>>4) <<2) : 0; + + if ((SLOT->ar + SLOT->ksr) < 16+60) /* verified on real YMF262 - all 15 x rates take "zero" time */ + { + SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; + SLOT->eg_m_ar = (1<eg_sh_ar)-1; + SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; + } + else + { + SLOT->eg_sh_ar = 0; + SLOT->eg_m_ar = (1<eg_sh_ar)-1; + SLOT->eg_sel_ar = 13*RATE_STEPS; + } + + SLOT->dr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; + SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; + SLOT->eg_m_dr = (1<eg_sh_dr)-1; + SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; +} + +/* set sustain level & release rate */ +INLINE void set_sl_rr(OPL3 *chip,int slot,int v) +{ + OPL3_CH *CH = &chip->P_CH[slot/2]; + OPL3_SLOT *SLOT = &CH->SLOT[slot&1]; + + SLOT->sl = sl_tab[ v>>4 ]; + + SLOT->rr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; + SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; + SLOT->eg_m_rr = (1<eg_sh_rr)-1; + SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; +} + + +static void update_channels(OPL3 *chip, OPL3_CH *CH) +{ + /* update channel passed as a parameter and a channel at CH+=3; */ + if (CH->extended) + { /* we've just switched to combined 4 operator mode */ + + } + else + { /* we've just switched to normal 2 operator mode */ + + } + +} + +/* write a value v to register r on OPL chip */ +static void OPL3WriteReg(OPL3 *chip, int r, int v) +{ + OPL3_CH *CH; + unsigned int ch_offset = 0; + int slot; + int block_fnum; + + + +#ifdef LOG_CYM_FILE + if ((cymfile) && ((r&255)!=0) && (r!=255) ) + { + if (r>0xff) + fputc( (unsigned char)0xff, cymfile );/*mark writes to second register set*/ + + fputc( (unsigned char)r&0xff, cymfile ); + fputc( (unsigned char)v, cymfile ); + } +#endif + + if(r&0x100) + { + switch(r) + { + case 0x101: /* test register */ + return; + break; + case 0x104: /* 6 channels enable */ + { + UINT8 prev; + + CH = &chip->P_CH[0]; /* channel 0 */ + prev = CH->extended; + CH->extended = (v>>0) & 1; + if(prev != CH->extended) + update_channels(chip, CH); + CH++; /* channel 1 */ + prev = CH->extended; + CH->extended = (v>>1) & 1; + if(prev != CH->extended) + update_channels(chip, CH); + CH++; /* channel 2 */ + prev = CH->extended; + CH->extended = (v>>2) & 1; + if(prev != CH->extended) + update_channels(chip, CH); + + + CH = &chip->P_CH[9]; /* channel 9 */ + prev = CH->extended; + CH->extended = (v>>3) & 1; + if(prev != CH->extended) + update_channels(chip, CH); + CH++; /* channel 10 */ + prev = CH->extended; + CH->extended = (v>>4) & 1; + if(prev != CH->extended) + update_channels(chip, CH); + CH++; /* channel 11 */ + prev = CH->extended; + CH->extended = (v>>5) & 1; + if(prev != CH->extended) + update_channels(chip, CH); + + } + return; + break; + case 0x105: /* OPL3 extensions enable register */ + + chip->OPL3_mode = v&0x01; /* OPL3 mode when bit0=1 otherwise it is OPL2 mode */ + + /* following behaviour was tested on real YMF262, + switching OPL3/OPL2 modes on the fly: + - does not change the waveform previously selected (unless when ....) + - does not update CH.A, CH.B, CH.C and CH.D output selectors (registers c0-c8) (unless when ....) + - does not disable channels 9-17 on OPL3->OPL2 switch + - does not switch 4 operator channels back to 2 operator channels + */ + + return; + break; + + default: + if (r < 0x120) + logerror("YMF262: write to unknown register (set#2): %03x value=%02x\n",r,v); + break; + } + + ch_offset = 9; /* register page #2 starts from channel 9 (counting from 0) */ + } + + /* adjust bus to 8 bits */ + r &= 0xff; + v &= 0xff; + + + switch(r&0xe0) + { + case 0x00: /* 00-1f:control */ + switch(r&0x1f) + { + case 0x01: /* test register */ + break; + case 0x02: /* Timer 1 */ + chip->T[0] = (256-v)*4; + break; + case 0x03: /* Timer 2 */ + chip->T[1] = (256-v)*16; + break; + case 0x04: /* IRQ clear / mask and Timer enable */ + if(v&0x80) + { /* IRQ flags clear */ + OPL3_STATUS_RESET(chip,0x60); + } + else + { /* set IRQ mask ,timer enable */ + UINT8 st1 = v & 1; + UINT8 st2 = (v>>1) & 1; + + /* IRQRST,T1MSK,t2MSK,x,x,x,ST2,ST1 */ + OPL3_STATUS_RESET(chip, v & 0x60); + OPL3_STATUSMASK_SET(chip, (~v) & 0x60 ); + + /* timer 2 */ + if(chip->st[1] != st2) + { + double interval = st2 ? (double)chip->T[1]*chip->TimerBase : 0.0; + chip->st[1] = st2; + if (chip->TimerHandler) (chip->TimerHandler)(chip->TimerParam+1,interval); + } + /* timer 1 */ + if(chip->st[0] != st1) + { + double interval = st1 ? (double)chip->T[0]*chip->TimerBase : 0.0; + chip->st[0] = st1; + if (chip->TimerHandler) (chip->TimerHandler)(chip->TimerParam+0,interval); + } + } + break; + case 0x08: /* x,NTS,x,x, x,x,x,x */ + chip->nts = v; + break; + + default: + logerror("YMF262: write to unknown register: %02x value=%02x\n",r,v); + break; + } + break; + case 0x20: /* am ON, vib ON, ksr, eg_type, mul */ + slot = slot_array[r&0x1f]; + if(slot < 0) return; + set_mul(chip, slot + ch_offset*2, v); + break; + case 0x40: + slot = slot_array[r&0x1f]; + if(slot < 0) return; + set_ksl_tl(chip, slot + ch_offset*2, v); + break; + case 0x60: + slot = slot_array[r&0x1f]; + if(slot < 0) return; + set_ar_dr(chip, slot + ch_offset*2, v); + break; + case 0x80: + slot = slot_array[r&0x1f]; + if(slot < 0) return; + set_sl_rr(chip, slot + ch_offset*2, v); + break; + case 0xa0: + if (r == 0xbd) /* am depth, vibrato depth, r,bd,sd,tom,tc,hh */ + { + if (ch_offset != 0) /* 0xbd register is present in set #1 only */ + return; + + chip->lfo_am_depth = v & 0x80; + chip->lfo_pm_depth_range = (v&0x40) ? 8 : 0; + + chip->rhythm = v&0x3f; + + if(chip->rhythm&0x20) + { + /* BD key on/off */ + if(v&0x10) + { + FM_KEYON (&chip->P_CH[6].SLOT[SLOT1], 2); + FM_KEYON (&chip->P_CH[6].SLOT[SLOT2], 2); + } + else + { + FM_KEYOFF(&chip->P_CH[6].SLOT[SLOT1],~2); + FM_KEYOFF(&chip->P_CH[6].SLOT[SLOT2],~2); + } + /* HH key on/off */ + if(v&0x01) FM_KEYON (&chip->P_CH[7].SLOT[SLOT1], 2); + else FM_KEYOFF(&chip->P_CH[7].SLOT[SLOT1],~2); + /* SD key on/off */ + if(v&0x08) FM_KEYON (&chip->P_CH[7].SLOT[SLOT2], 2); + else FM_KEYOFF(&chip->P_CH[7].SLOT[SLOT2],~2); + /* TOM key on/off */ + if(v&0x04) FM_KEYON (&chip->P_CH[8].SLOT[SLOT1], 2); + else FM_KEYOFF(&chip->P_CH[8].SLOT[SLOT1],~2); + /* TOP-CY key on/off */ + if(v&0x02) FM_KEYON (&chip->P_CH[8].SLOT[SLOT2], 2); + else FM_KEYOFF(&chip->P_CH[8].SLOT[SLOT2],~2); + } + else + { + /* BD key off */ + FM_KEYOFF(&chip->P_CH[6].SLOT[SLOT1],~2); + FM_KEYOFF(&chip->P_CH[6].SLOT[SLOT2],~2); + /* HH key off */ + FM_KEYOFF(&chip->P_CH[7].SLOT[SLOT1],~2); + /* SD key off */ + FM_KEYOFF(&chip->P_CH[7].SLOT[SLOT2],~2); + /* TOM key off */ + FM_KEYOFF(&chip->P_CH[8].SLOT[SLOT1],~2); + /* TOP-CY off */ + FM_KEYOFF(&chip->P_CH[8].SLOT[SLOT2],~2); + } + return; + } + + /* keyon,block,fnum */ + if( (r&0x0f) > 8) return; + CH = &chip->P_CH[(r&0x0f) + ch_offset]; + + if(!(r&0x10)) + { /* a0-a8 */ + block_fnum = (CH->block_fnum&0x1f00) | v; + } + else + { /* b0-b8 */ + block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff); + + if (chip->OPL3_mode & 1) + { + int chan_no = (r&0x0f) + ch_offset; + + /* in OPL3 mode */ + //DO THIS: + //if this is 1st channel forming up a 4-op channel + //ALSO keyon/off slots of 2nd channel forming up 4-op channel + //else normal 2 operator function keyon/off + //OR THIS: + //if this is 2nd channel forming up 4-op channel just do nothing + //else normal 2 operator function keyon/off + switch(chan_no) + { + case 0: case 1: case 2: + case 9: case 10: case 11: + if (CH->extended) + { + //if this is 1st channel forming up a 4-op channel + //ALSO keyon/off slots of 2nd channel forming up 4-op channel + if(v&0x20) + { + FM_KEYON (&CH->SLOT[SLOT1], 1); + FM_KEYON (&CH->SLOT[SLOT2], 1); + FM_KEYON (&(CH+3)->SLOT[SLOT1], 1); + FM_KEYON (&(CH+3)->SLOT[SLOT2], 1); + } + else + { + FM_KEYOFF(&CH->SLOT[SLOT1],~1); + FM_KEYOFF(&CH->SLOT[SLOT2],~1); + FM_KEYOFF(&(CH+3)->SLOT[SLOT1],~1); + FM_KEYOFF(&(CH+3)->SLOT[SLOT2],~1); + } + } + else + { + //else normal 2 operator function keyon/off + if(v&0x20) + { + FM_KEYON (&CH->SLOT[SLOT1], 1); + FM_KEYON (&CH->SLOT[SLOT2], 1); + } + else + { + FM_KEYOFF(&CH->SLOT[SLOT1],~1); + FM_KEYOFF(&CH->SLOT[SLOT2],~1); + } + } + break; + + case 3: case 4: case 5: + case 12: case 13: case 14: + if ((CH-3)->extended) + { + //if this is 2nd channel forming up 4-op channel just do nothing + } + else + { + //else normal 2 operator function keyon/off + if(v&0x20) + { + FM_KEYON (&CH->SLOT[SLOT1], 1); + FM_KEYON (&CH->SLOT[SLOT2], 1); + } + else + { + FM_KEYOFF(&CH->SLOT[SLOT1],~1); + FM_KEYOFF(&CH->SLOT[SLOT2],~1); + } + } + break; + + default: + if(v&0x20) + { + FM_KEYON (&CH->SLOT[SLOT1], 1); + FM_KEYON (&CH->SLOT[SLOT2], 1); + } + else + { + FM_KEYOFF(&CH->SLOT[SLOT1],~1); + FM_KEYOFF(&CH->SLOT[SLOT2],~1); + } + break; + } + } + else + { + if(v&0x20) + { + FM_KEYON (&CH->SLOT[SLOT1], 1); + FM_KEYON (&CH->SLOT[SLOT2], 1); + } + else + { + FM_KEYOFF(&CH->SLOT[SLOT1],~1); + FM_KEYOFF(&CH->SLOT[SLOT2],~1); + } + } + } + /* update */ + if(CH->block_fnum != block_fnum) + { + UINT8 block = block_fnum >> 10; + + CH->block_fnum = block_fnum; + + CH->ksl_base = ksl_tab[block_fnum>>6]; + CH->fc = chip->fn_tab[block_fnum&0x03ff] >> (7-block); + + /* BLK 2,1,0 bits -> bits 3,2,1 of kcode */ + CH->kcode = (CH->block_fnum&0x1c00)>>9; + + /* the info below is actually opposite to what is stated in the Manuals (verifed on real YMF262) */ + /* if notesel == 0 -> lsb of kcode is bit 10 (MSB) of fnum */ + /* if notesel == 1 -> lsb of kcode is bit 9 (MSB-1) of fnum */ + if (chip->nts&0x40) + CH->kcode |= (CH->block_fnum&0x100)>>8; /* notesel == 1 */ + else + CH->kcode |= (CH->block_fnum&0x200)>>9; /* notesel == 0 */ + + if (chip->OPL3_mode & 1) + { + int chan_no = (r&0x0f) + ch_offset; + /* in OPL3 mode */ + //DO THIS: + //if this is 1st channel forming up a 4-op channel + //ALSO update slots of 2nd channel forming up 4-op channel + //else normal 2 operator function keyon/off + //OR THIS: + //if this is 2nd channel forming up 4-op channel just do nothing + //else normal 2 operator function keyon/off + switch(chan_no) + { + case 0: case 1: case 2: + case 9: case 10: case 11: + if (CH->extended) + { + //if this is 1st channel forming up a 4-op channel + //ALSO update slots of 2nd channel forming up 4-op channel + + /* refresh Total Level in FOUR SLOTs of this channel and channel+3 using data from THIS channel */ + CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); + CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); + (CH+3)->SLOT[SLOT1].TLL = (CH+3)->SLOT[SLOT1].TL + (CH->ksl_base>>(CH+3)->SLOT[SLOT1].ksl); + (CH+3)->SLOT[SLOT2].TLL = (CH+3)->SLOT[SLOT2].TL + (CH->ksl_base>>(CH+3)->SLOT[SLOT2].ksl); + + /* refresh frequency counter in FOUR SLOTs of this channel and channel+3 using data from THIS channel */ + CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); + CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); + CALC_FCSLOT(CH,&(CH+3)->SLOT[SLOT1]); + CALC_FCSLOT(CH,&(CH+3)->SLOT[SLOT2]); + } + else + { + //else normal 2 operator function + /* refresh Total Level in both SLOTs of this channel */ + CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); + CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); + + /* refresh frequency counter in both SLOTs of this channel */ + CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); + CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); + } + break; + + case 3: case 4: case 5: + case 12: case 13: case 14: + if ((CH-3)->extended) + { + //if this is 2nd channel forming up 4-op channel just do nothing + } + else + { + //else normal 2 operator function + /* refresh Total Level in both SLOTs of this channel */ + CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); + CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); + + /* refresh frequency counter in both SLOTs of this channel */ + CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); + CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); + } + break; + + default: + /* refresh Total Level in both SLOTs of this channel */ + CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); + CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); + + /* refresh frequency counter in both SLOTs of this channel */ + CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); + CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); + break; + } + } + else + { + /* in OPL2 mode */ + + /* refresh Total Level in both SLOTs of this channel */ + CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); + CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); + + /* refresh frequency counter in both SLOTs of this channel */ + CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); + CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); + } + } + break; + + case 0xc0: + /* CH.D, CH.C, CH.B, CH.A, FB(3bits), C */ + if( (r&0xf) > 8) return; + + CH = &chip->P_CH[(r&0xf) + ch_offset]; + + if( chip->OPL3_mode & 1 ) + { + int base = ((r&0xf) + ch_offset) * 4; + + /* OPL3 mode */ + chip->pan[ base ] = (v & 0x10) ? ~0 : 0; /* ch.A */ + chip->pan[ base +1 ] = (v & 0x20) ? ~0 : 0; /* ch.B */ + chip->pan[ base +2 ] = (v & 0x40) ? ~0 : 0; /* ch.C */ + chip->pan[ base +3 ] = (v & 0x80) ? ~0 : 0; /* ch.D */ + } + else + { + int base = ((r&0xf) + ch_offset) * 4; + + /* OPL2 mode - always enabled */ + chip->pan[ base ] = ~0; /* ch.A */ + chip->pan[ base +1 ] = ~0; /* ch.B */ + chip->pan[ base +2 ] = ~0; /* ch.C */ + chip->pan[ base +3 ] = ~0; /* ch.D */ + } + + chip->pan_ctrl_value[ (r&0xf) + ch_offset ] = v; /* store control value for OPL3/OPL2 mode switching on the fly */ + + CH->SLOT[SLOT1].FB = (v>>1)&7 ? ((v>>1)&7) + 7 : 0; + CH->SLOT[SLOT1].CON = v&1; + + if( chip->OPL3_mode & 1 ) + { + int chan_no = (r&0x0f) + ch_offset; + + switch(chan_no) + { + case 0: case 1: case 2: + case 9: case 10: case 11: + if (CH->extended) + { + UINT8 conn = (CH->SLOT[SLOT1].CON<<1) || ((CH+3)->SLOT[SLOT1].CON<<0); + switch(conn) + { + case 0: + /* 1 -> 2 -> 3 -> 4 - out */ + + CH->SLOT[SLOT1].connect = &phase_modulation; + CH->SLOT[SLOT2].connect = &phase_modulation2; + (CH+3)->SLOT[SLOT1].connect = &phase_modulation; + (CH+3)->SLOT[SLOT2].connect = &chanout[ chan_no + 3 ]; + break; + case 1: + /* 1 -> 2 -\ + 3 -> 4 -+- out */ + + CH->SLOT[SLOT1].connect = &phase_modulation; + CH->SLOT[SLOT2].connect = &chanout[ chan_no ]; + (CH+3)->SLOT[SLOT1].connect = &phase_modulation; + (CH+3)->SLOT[SLOT2].connect = &chanout[ chan_no + 3 ]; + break; + case 2: + /* 1 -----------\ + 2 -> 3 -> 4 -+- out */ + + CH->SLOT[SLOT1].connect = &chanout[ chan_no ]; + CH->SLOT[SLOT2].connect = &phase_modulation2; + (CH+3)->SLOT[SLOT1].connect = &phase_modulation; + (CH+3)->SLOT[SLOT2].connect = &chanout[ chan_no + 3 ]; + break; + case 3: + /* 1 ------\ + 2 -> 3 -+- out + 4 ------/ */ + CH->SLOT[SLOT1].connect = &chanout[ chan_no ]; + CH->SLOT[SLOT2].connect = &phase_modulation2; + (CH+3)->SLOT[SLOT1].connect = &chanout[ chan_no + 3 ]; + (CH+3)->SLOT[SLOT2].connect = &chanout[ chan_no + 3 ]; + break; + } + } + else + { + /* 2 operators mode */ + CH->SLOT[SLOT1].connect = CH->SLOT[SLOT1].CON ? &chanout[(r&0xf)+ch_offset] : &phase_modulation; + CH->SLOT[SLOT2].connect = &chanout[(r&0xf)+ch_offset]; + } + break; + + case 3: case 4: case 5: + case 12: case 13: case 14: + if ((CH-3)->extended) + { + UINT8 conn = ((CH-3)->SLOT[SLOT1].CON<<1) || (CH->SLOT[SLOT1].CON<<0); + switch(conn) + { + case 0: + /* 1 -> 2 -> 3 -> 4 - out */ + + (CH-3)->SLOT[SLOT1].connect = &phase_modulation; + (CH-3)->SLOT[SLOT2].connect = &phase_modulation2; + CH->SLOT[SLOT1].connect = &phase_modulation; + CH->SLOT[SLOT2].connect = &chanout[ chan_no ]; + break; + case 1: + /* 1 -> 2 -\ + 3 -> 4 -+- out */ + + (CH-3)->SLOT[SLOT1].connect = &phase_modulation; + (CH-3)->SLOT[SLOT2].connect = &chanout[ chan_no - 3 ]; + CH->SLOT[SLOT1].connect = &phase_modulation; + CH->SLOT[SLOT2].connect = &chanout[ chan_no ]; + break; + case 2: + /* 1 -----------\ + 2 -> 3 -> 4 -+- out */ + + (CH-3)->SLOT[SLOT1].connect = &chanout[ chan_no - 3 ]; + (CH-3)->SLOT[SLOT2].connect = &phase_modulation2; + CH->SLOT[SLOT1].connect = &phase_modulation; + CH->SLOT[SLOT2].connect = &chanout[ chan_no ]; + break; + case 3: + /* 1 ------\ + 2 -> 3 -+- out + 4 ------/ */ + (CH-3)->SLOT[SLOT1].connect = &chanout[ chan_no - 3 ]; + (CH-3)->SLOT[SLOT2].connect = &phase_modulation2; + CH->SLOT[SLOT1].connect = &chanout[ chan_no ]; + CH->SLOT[SLOT2].connect = &chanout[ chan_no ]; + break; + } + } + else + { + /* 2 operators mode */ + CH->SLOT[SLOT1].connect = CH->SLOT[SLOT1].CON ? &chanout[(r&0xf)+ch_offset] : &phase_modulation; + CH->SLOT[SLOT2].connect = &chanout[(r&0xf)+ch_offset]; + } + break; + + default: + /* 2 operators mode */ + CH->SLOT[SLOT1].connect = CH->SLOT[SLOT1].CON ? &chanout[(r&0xf)+ch_offset] : &phase_modulation; + CH->SLOT[SLOT2].connect = &chanout[(r&0xf)+ch_offset]; + break; + } + } + else + { + /* OPL2 mode - always 2 operators mode */ + CH->SLOT[SLOT1].connect = CH->SLOT[SLOT1].CON ? &chanout[(r&0xf)+ch_offset] : &phase_modulation; + CH->SLOT[SLOT2].connect = &chanout[(r&0xf)+ch_offset]; + } + break; + + case 0xe0: /* waveform select */ + slot = slot_array[r&0x1f]; + if(slot < 0) return; + + slot += ch_offset*2; + + CH = &chip->P_CH[slot/2]; + + + /* store 3-bit value written regardless of current OPL2 or OPL3 mode... (verified on real YMF262) */ + v &= 7; + CH->SLOT[slot&1].waveform_number = v; + + /* ... but select only waveforms 0-3 in OPL2 mode */ + if( !(chip->OPL3_mode & 1) ) + { + v &= 3; /* we're in OPL2 mode */ + } + CH->SLOT[slot&1].wavetable = v * SIN_LEN; + break; + } +} + +#ifdef LOG_CYM_FILE +static void cymfile_callback (int n) +{ + if (cymfile) + { + fputc( (unsigned char)0, cymfile ); + } +} +#endif + +/* lock/unlock for common table */ +static int OPL3_LockTable(void) +{ + num_lock++; + if(num_lock>1) return 0; + + /* first time */ + + cur_chip = NULL; + + if( !init_tables() ) + { + num_lock--; + return -1; + } + +#ifdef LOG_CYM_FILE + cymfile = fopen("ymf262_.cym","wb"); + if (cymfile) + timer_pulse ( TIME_IN_HZ(110), 0, cymfile_callback); /*110 Hz pulse timer*/ + else + logerror("Could not create ymf262_.cym file\n"); +#endif + + return 0; +} + +static void OPL3_UnLockTable(void) +{ + if(num_lock) num_lock--; + if(num_lock) return; + + /* last time */ + + cur_chip = NULL; + OPLCloseTable(); + +#ifdef LOG_CYM_FILE + fclose (cymfile); + cymfile = NULL; +#endif + +} + +static void OPL3ResetChip(OPL3 *chip) +{ + int c,s; + + chip->eg_timer = 0; + chip->eg_cnt = 0; + + chip->noise_rng = 1; /* noise shift register */ + chip->nts = 0; /* note split */ + OPL3_STATUS_RESET(chip,0x60); + + /* reset with register write */ + OPL3WriteReg(chip,0x01,0); /* test register */ + OPL3WriteReg(chip,0x02,0); /* Timer1 */ + OPL3WriteReg(chip,0x03,0); /* Timer2 */ + OPL3WriteReg(chip,0x04,0); /* IRQ mask clear */ + + +//FIX IT registers 101, 104 and 105 + + +//FIX IT (dont change CH.D, CH.C, CH.B and CH.A in C0-C8 registers) + for(c = 0xff ; c >= 0x20 ; c-- ) + OPL3WriteReg(chip,c,0); +//FIX IT (dont change CH.D, CH.C, CH.B and CH.A in C0-C8 registers) + for(c = 0x1ff ; c >= 0x120 ; c-- ) + OPL3WriteReg(chip,c,0); + + + + /* reset operator parameters */ + for( c = 0 ; c < 9*2 ; c++ ) + { + OPL3_CH *CH = &chip->P_CH[c]; + for(s = 0 ; s < 2 ; s++ ) + { + CH->SLOT[s].state = EG_OFF; + CH->SLOT[s].volume = MAX_ATT_INDEX; + } + } +} + +/* Create one of virtual YMF262 */ +/* 'clock' is chip clock in Hz */ +/* 'rate' is sampling rate */ +static OPL3 *OPL3Create(int type, int clock, int rate) +{ + OPL3 *chip; + + if (OPL3_LockTable() ==-1) return NULL; + + /* allocate memory block */ + chip = (OPL3 *)malloc(sizeof(OPL3)); + + if (chip==NULL) + return NULL; + + /* clear */ + memset(chip, 0, sizeof(OPL3)); + + chip->type = type; + chip->clock = clock; + chip->rate = rate; + + /* init global tables */ + OPL3_initalize(chip); + + /* reset chip */ + OPL3ResetChip(chip); + return chip; +} + +/* Destroy one of virtual YMF262 */ +static void OPL3Destroy(OPL3 *chip) +{ + OPL3_UnLockTable(); + free(chip); +} + + +/* Optional handlers */ + +static void OPL3SetTimerHandler(OPL3 *chip,OPL3_TIMERHANDLER TimerHandler,int channelOffset) +{ + chip->TimerHandler = TimerHandler; + chip->TimerParam = channelOffset; +} +static void OPL3SetIRQHandler(OPL3 *chip,OPL3_IRQHANDLER IRQHandler,int param) +{ + chip->IRQHandler = IRQHandler; + chip->IRQParam = param; +} +static void OPL3SetUpdateHandler(OPL3 *chip,OPL3_UPDATEHANDLER UpdateHandler,int param) +{ + chip->UpdateHandler = UpdateHandler; + chip->UpdateParam = param; +} + +/* YMF262 I/O interface */ +static int OPL3Write(OPL3 *chip, int a, int v) +{ + /* data bus is 8 bits */ + v &= 0xff; + + switch(a&3) + { + case 0: /* address port 0 (register set #1) */ + chip->address = v; + break; + + case 1: /* data port - ignore A1 */ + case 3: /* data port - ignore A1 */ + if(chip->UpdateHandler) chip->UpdateHandler(chip->UpdateParam,0); + OPL3WriteReg(chip,chip->address,v); + break; + + case 2: /* address port 1 (register set #2) */ + + /* verified on real YMF262: + in OPL3 mode: + address line A1 is stored during *address* write and ignored during *data* write. + + in OPL2 mode: + register set#2 writes go to register set#1 (ignoring A1) + verified on registers from set#2: 0x01, 0x04, 0x20-0xef + The only exception is register 0x05. + */ + if( chip->OPL3_mode & 1 ) + { + /* OPL3 mode */ + chip->address = v | 0x100; + } + else + { + /* in OPL2 mode the only accessible in set #2 is register 0x05 */ + if( v==5 ) + chip->address = v | 0x100; + else + chip->address = v; /* verified range: 0x01, 0x04, 0x20-0xef(set #2 becomes set #1 in opl2 mode) */ + } + break; + } + + return chip->status>>7; +} + +static unsigned char OPL3Read(OPL3 *chip,int a) +{ + if( a==0 ) + { + /* status port */ + return chip->status; + } + + return 0x00; /* verified on real YMF262 */ +} + + + +static int OPL3TimerOver(OPL3 *chip,int c) +{ + if( c ) + { /* Timer B */ + OPL3_STATUS_SET(chip,0x20); + } + else + { /* Timer A */ + OPL3_STATUS_SET(chip,0x40); + } + /* reload timer */ + if (chip->TimerHandler) (chip->TimerHandler)(chip->TimerParam+c,(double)chip->T[c]*chip->TimerBase); + return chip->status>>7; +} + + + + +#if (BUILD_YMF262) + +#define MAX_OPL3_CHIPS 2 + +static OPL3 *YMF262[MAX_OPL3_CHIPS]; /* array of pointers to the YMF262's */ +static int YMF262NumChips = 0; /* number of chips */ + +int YMF262Init(int num, int clock, int rate) +{ + int i; + + if (YMF262NumChips) + return -1; /* duplicate init. */ + + YMF262NumChips = num; + + for (i = 0;i < YMF262NumChips; i++) + { + /* emulator create */ + YMF262[i] = OPL3Create(OPL3_TYPE_YMF262,clock,rate); + if(YMF262[i] == NULL) + { + /* it's really bad - we run out of memeory */ + YMF262NumChips = 0; + return -1; + } + } + + return 0; +} + +void YMF262Shutdown(void) +{ + int i; + + for (i = 0;i < YMF262NumChips; i++) + { + /* emulator shutdown */ + OPL3Destroy(YMF262[i]); + YMF262[i] = NULL; + } + YMF262NumChips = 0; +} +void YMF262ResetChip(int which) +{ + OPL3ResetChip(YMF262[which]); +} + +int YMF262Write(int which, int a, int v) +{ + return OPL3Write(YMF262[which], a, v); +} + +unsigned char YMF262Read(int which, int a) +{ + /* Note on status register: */ + + /* YM3526(OPL) and YM3812(OPL2) return bit2 and bit1 in HIGH state */ + + /* YMF262(OPL3) always returns bit2 and bit1 in LOW state */ + /* which can be used to identify the chip */ + + /* YMF278(OPL4) returns bit2 in LOW and bit1 in HIGH state ??? info from manual - not verified */ + + return OPL3Read(YMF262[which], a); +} +int YMF262TimerOver(int which, int c) +{ + return OPL3TimerOver(YMF262[which], c); +} + +void YMF262SetTimerHandler(int which, OPL3_TIMERHANDLER TimerHandler, int channelOffset) +{ + OPL3SetTimerHandler(YMF262[which], TimerHandler, channelOffset); +} +void YMF262SetIRQHandler(int which,OPL3_IRQHANDLER IRQHandler,int param) +{ + OPL3SetIRQHandler(YMF262[which], IRQHandler, param); +} +void YMF262SetUpdateHandler(int which,OPL3_UPDATEHANDLER UpdateHandler,int param) +{ + OPL3SetUpdateHandler(YMF262[which], UpdateHandler, param); +} + + +/* +** Generate samples for one of the YMF262's +** +** 'which' is the virtual YMF262 number +** '**buffers' is table of 4 pointers to the buffers: CH.A, CH.B, CH.C and CH.D +** 'length' is the number of samples that should be generated +*/ +#if 0 +void YMF262UpdateOne(int which, INT16 **buffers, int length) +#else +void YMF262UpdateOne(int which, INT16 *buffer, int length) +#endif +{ + OPL3 *chip = YMF262[which]; + UINT8 rhythm = chip->rhythm&0x20; +#if 0 + OPL3SAMPLE *ch_a = buffers[0]; + OPL3SAMPLE *ch_b = buffers[1]; + OPL3SAMPLE *ch_c = buffers[2]; + OPL3SAMPLE *ch_d = buffers[3]; +#endif + int i; + + if( (void *)chip != cur_chip ){ + cur_chip = (void *)chip; + /* rhythm slots */ + SLOT7_1 = &chip->P_CH[7].SLOT[SLOT1]; + SLOT7_2 = &chip->P_CH[7].SLOT[SLOT2]; + SLOT8_1 = &chip->P_CH[8].SLOT[SLOT1]; + SLOT8_2 = &chip->P_CH[8].SLOT[SLOT2]; + } + for( i=0; i < length ; i++ ) + { + int a,b,c,d; + + + advance_lfo(chip); + + /* clear channel outputs */ + memset(chanout, 0, sizeof(signed int) * 18); + +//profiler_mark(PROFILER_USER1); + +#if 1 + /* register set #1 */ + chan_calc(&chip->P_CH[0]); /* extended 4op ch#0 part 1 or 2op ch#0 */ + if (chip->P_CH[0].extended) + chan_calc_ext(&chip->P_CH[3]); /* extended 4op ch#0 part 2 */ + else + chan_calc(&chip->P_CH[3]); /* standard 2op ch#3 */ + + + chan_calc(&chip->P_CH[1]); /* extended 4op ch#1 part 1 or 2op ch#1 */ + if (chip->P_CH[1].extended) + chan_calc_ext(&chip->P_CH[4]); /* extended 4op ch#1 part 2 */ + else + chan_calc(&chip->P_CH[4]); /* standard 2op ch#4 */ + + + chan_calc(&chip->P_CH[2]); /* extended 4op ch#2 part 1 or 2op ch#2 */ + if (chip->P_CH[2].extended) + chan_calc_ext(&chip->P_CH[5]); /* extended 4op ch#2 part 2 */ + else + chan_calc(&chip->P_CH[5]); /* standard 2op ch#5 */ + + + if(!rhythm) + { + chan_calc(&chip->P_CH[6]); + chan_calc(&chip->P_CH[7]); + chan_calc(&chip->P_CH[8]); + } + else /* Rhythm part */ + { + chan_calc_rhythm(&chip->P_CH[0], (chip->noise_rng>>0)&1 ); + } + + /* register set #2 */ + chan_calc(&chip->P_CH[ 9]); + if (chip->P_CH[9].extended) + chan_calc_ext(&chip->P_CH[12]); + else + chan_calc(&chip->P_CH[12]); + + + chan_calc(&chip->P_CH[10]); + if (chip->P_CH[10].extended) + chan_calc_ext(&chip->P_CH[13]); + else + chan_calc(&chip->P_CH[13]); + + + chan_calc(&chip->P_CH[11]); + if (chip->P_CH[11].extended) + chan_calc_ext(&chip->P_CH[14]); + else + chan_calc(&chip->P_CH[14]); + + + /* channels 15,16,17 are fixed 2-operator channels only */ + chan_calc(&chip->P_CH[15]); + chan_calc(&chip->P_CH[16]); + chan_calc(&chip->P_CH[17]); +#endif +//profiler_mark(PROFILER_END); + + + +//profiler_mark(PROFILER_USER2); + /* accumulator register set #1 */ + a = chanout[0] & chip->pan[0]; + b = chanout[0] & chip->pan[1]; + c = chanout[0] & chip->pan[2]; + d = chanout[0] & chip->pan[3]; +#if 1 + a += chanout[1] & chip->pan[4]; + b += chanout[1] & chip->pan[5]; + c += chanout[1] & chip->pan[6]; + d += chanout[1] & chip->pan[7]; + a += chanout[2] & chip->pan[8]; + b += chanout[2] & chip->pan[9]; + c += chanout[2] & chip->pan[10]; + d += chanout[2] & chip->pan[11]; + + a += chanout[3] & chip->pan[12]; + b += chanout[3] & chip->pan[13]; + c += chanout[3] & chip->pan[14]; + d += chanout[3] & chip->pan[15]; + a += chanout[4] & chip->pan[16]; + b += chanout[4] & chip->pan[17]; + c += chanout[4] & chip->pan[18]; + d += chanout[4] & chip->pan[19]; + a += chanout[5] & chip->pan[20]; + b += chanout[5] & chip->pan[21]; + c += chanout[5] & chip->pan[22]; + d += chanout[5] & chip->pan[23]; + + a += chanout[6] & chip->pan[24]; + b += chanout[6] & chip->pan[25]; + c += chanout[6] & chip->pan[26]; + d += chanout[6] & chip->pan[27]; + a += chanout[7] & chip->pan[28]; + b += chanout[7] & chip->pan[29]; + c += chanout[7] & chip->pan[30]; + d += chanout[7] & chip->pan[31]; + a += chanout[8] & chip->pan[32]; + b += chanout[8] & chip->pan[33]; + c += chanout[8] & chip->pan[34]; + d += chanout[8] & chip->pan[35]; + + /* accumulator register set #2 */ + a += chanout[9] & chip->pan[36]; + b += chanout[9] & chip->pan[37]; + c += chanout[9] & chip->pan[38]; + d += chanout[9] & chip->pan[39]; + a += chanout[10] & chip->pan[40]; + b += chanout[10] & chip->pan[41]; + c += chanout[10] & chip->pan[42]; + d += chanout[10] & chip->pan[43]; + a += chanout[11] & chip->pan[44]; + b += chanout[11] & chip->pan[45]; + c += chanout[11] & chip->pan[46]; + d += chanout[11] & chip->pan[47]; + + a += chanout[12] & chip->pan[48]; + b += chanout[12] & chip->pan[49]; + c += chanout[12] & chip->pan[50]; + d += chanout[12] & chip->pan[51]; + a += chanout[13] & chip->pan[52]; + b += chanout[13] & chip->pan[53]; + c += chanout[13] & chip->pan[54]; + d += chanout[13] & chip->pan[55]; + a += chanout[14] & chip->pan[56]; + b += chanout[14] & chip->pan[57]; + c += chanout[14] & chip->pan[58]; + d += chanout[14] & chip->pan[59]; + + a += chanout[15] & chip->pan[60]; + b += chanout[15] & chip->pan[61]; + c += chanout[15] & chip->pan[62]; + d += chanout[15] & chip->pan[63]; + a += chanout[16] & chip->pan[64]; + b += chanout[16] & chip->pan[65]; + c += chanout[16] & chip->pan[66]; + d += chanout[16] & chip->pan[67]; + a += chanout[17] & chip->pan[68]; + b += chanout[17] & chip->pan[69]; + c += chanout[17] & chip->pan[70]; + d += chanout[17] & chip->pan[71]; +#endif + a >>= FINAL_SH; + b >>= FINAL_SH; + c >>= FINAL_SH; + d >>= FINAL_SH; + + /* limit check */ + a = limit( a+c , MAXOUT, MINOUT ); + b = limit( b+d , MAXOUT, MINOUT ); +// c = limit( c , MAXOUT, MINOUT ); +// d = limit( d , MAXOUT, MINOUT ); + + #ifdef SAVE_SAMPLE + if (which==0) + { + SAVE_ALL_CHANNELS + } + #endif + + /* store to sound buffer */ + *buffer++=(INT16)a; + *buffer++=(INT16)b; +#if 0 + ch_a[i] = a; + ch_b[i] = b; + ch_c[i] = c; + ch_d[i] = d; +#endif +//profiler_mark(PROFILER_END); + + advance(chip); + } + +} +#endif /* BUILD_YMF262 */ diff --git a/src/hardware/ymf262.h b/src/hardware/ymf262.h new file mode 100644 index 00000000..1ab2fa11 --- /dev/null +++ b/src/hardware/ymf262.h @@ -0,0 +1,53 @@ +#ifndef YMF262_H +#define YMF262_H + + +#define BUILD_YMF262 (HAS_YMF262) + + +/* select number of output bits: 8 or 16 */ +#define OPL3_SAMPLE_BITS 16 + +/* compiler dependence */ +#ifndef OSD_CPU_H +#define OSD_CPU_H +typedef unsigned char UINT8; /* unsigned 8bit */ +typedef unsigned short UINT16; /* unsigned 16bit */ +typedef unsigned int UINT32; /* unsigned 32bit */ +typedef signed char INT8; /* signed 8bit */ +typedef signed short INT16; /* signed 16bit */ +typedef signed int INT32; /* signed 32bit */ +#endif + +#if (OPL3_SAMPLE_BITS==16) +typedef INT16 OPL3SAMPLE; +#endif +#if (OPL3_SAMPLE_BITS==8) +typedef INT8 OPL3SAMPLE; +#endif + + +typedef void (*OPL3_TIMERHANDLER)(int channel,double interval_Sec); +typedef void (*OPL3_IRQHANDLER)(int param,int irq); +typedef void (*OPL3_UPDATEHANDLER)(int param,int min_interval_us); + + + +#if BUILD_YMF262 + +int YMF262Init(int num, int clock, int rate); +void YMF262Shutdown(void); +void YMF262ResetChip(int which); +int YMF262Write(int which, int a, int v); +unsigned char YMF262Read(int which, int a); +int YMF262TimerOver(int which, int c); +void YMF262UpdateOne(int which, INT16 **buffers, int length); + +void YMF262SetTimerHandler(int which, OPL3_TIMERHANDLER TimerHandler, int channelOffset); +void YMF262SetIRQHandler(int which, OPL3_IRQHANDLER IRQHandler, int param); +void YMF262SetUpdateHandler(int which, OPL3_UPDATEHANDLER UpdateHandler, int param); + +#endif + + +#endif /* YMF262_H */ From b2def2f86b8977550427dbfd2d10ae2baf287f41 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 3 Mar 2004 15:57:07 +0000 Subject: [PATCH 1618/4131] Rename the opl3 namespace for gcc Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1700 --- src/hardware/adlib.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index d0f99720..86d1fd7a 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -60,7 +60,7 @@ namespace OPL2 { } #undef OSD_CPU_H #undef TL_TAB_LEN -namespace OPL3 { +namespace THEOPL3 { #define HAS_YMF262 1 #include "ymf262.c" void TimerOver(Bitu val){ @@ -93,7 +93,7 @@ static void OPL_CallBack(Bit8u *stream, Bit32u len) { OPL2::YM3812UpdateOne(0,(OPL2::INT16 *)stream,len); break; case OPL_opl3: - OPL3::YMF262UpdateOne(0,(OPL2::INT16 *)stream,len); + THEOPL3::YMF262UpdateOne(0,(OPL2::INT16 *)stream,len); break; case OPL_dualopl2: OPL2::YM3812UpdateOne(0,(OPL2::INT16 *)opl.mixbuf[0],len); @@ -119,7 +119,7 @@ Bit8u OPL_Read(Bit32u port) { case OPL_dualopl2: return OPL2::YM3812Read(addr>>1,addr); case OPL_opl3: - return OPL3::YMF262Read(0,addr); + return THEOPL3::YMF262Read(0,addr); } return 0xff; } @@ -136,7 +136,7 @@ void OPL_Write(Bit32u port,Bit8u val) { OPL2::YM3812Write(0,addr,val); break; case OPL_opl3: - OPL3::YMF262Write(0,addr,val); + THEOPL3::YMF262Write(0,addr,val); break; case OPL_dualopl2: OPL2::YM3812Write(addr>>1,addr,val); @@ -152,10 +152,10 @@ void OPL_Init(Section* sec,OPL_Mode oplmode,Bitu rate) { }; OPL2::YM3812SetTimerHandler(0,OPL2::TimerHandler,0); OPL2::YM3812SetTimerHandler(1,OPL2::TimerHandler,256); - if (OPL3::YMF262Init(1,OPL3_INTERNAL_FREQ,rate)) { + if (THEOPL3::YMF262Init(1,OPL3_INTERNAL_FREQ,rate)) { E_Exit("Can't create OPL3 Emulator"); }; - OPL3::YMF262SetTimerHandler(0,OPL3::TimerHandler,0); + THEOPL3::YMF262SetTimerHandler(0,THEOPL3::TimerHandler,0); for (i=0;i<4;i++) { IO_RegisterWriteHandler(0x388+i,OPL_Write,"OPL Write"); IO_RegisterReadHandler(0x388+i,OPL_Read,"OPL read"); From 2579cf1c6a2e2341db873c4625cb7acb7b02cbcd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 3 Mar 2004 16:59:38 +0000 Subject: [PATCH 1619/4131] Fix high res ega modes from being detected as text modes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1701 --- src/ints/int10_modes.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index afb07a62..8225ab85 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -339,10 +339,9 @@ bool INT10_SetVideoMode(Bitu mode) { modeset_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); /* Setup the VGA to the correct mode */ -// VGA_SetMode(CurMode->type); - + Bit16u crtc_base; - bool mono_mode=(CurMode->type == M_TEXT && machine==MCH_HERC); + bool mono_mode=(mode == 7); if (mono_mode) crtc_base=0x3b4; else crtc_base=0x3d4; /* Setup MISC Output Register */ @@ -548,12 +547,12 @@ bool INT10_SetVideoMode(Bitu mode) { /* Program Attribute Controller */ switch (CurMode->type) { case M_EGA16: + att_data[0x10]=0x01; //Color Graphics if (CurMode->mode>0xe) goto att_text16; for (i=0;i<8;i++) { att_data[i]=i; att_data[i+8]=i+0x10; } - att_data[0x10]=0x01; //Color Graphics break; case M_TANDY16: att_data[0x10]=0x01; //Color Graphics From fe74bebe4d8a3f5dec5588ba5b9752e8c680c790 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 4 Mar 2004 10:34:32 +0000 Subject: [PATCH 1620/4131] Slight bug in cms still checking some old config option Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1702 --- src/hardware/gameblaster.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index 5bb1dcd4..0f98d8ae 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -422,7 +422,6 @@ static void write_cms(Bit32u port,Bit8u val) { void CMS_Init(Section* sec,Bitu rate) { Section_prop * section=static_cast(sec); - if(!section->Get_bool("cms")) return; sample_rate=rate; IO_RegisterWriteHandler(0x220,write_cms,"CMS"); From f86f45110c6639fa9a407d4b33393ba54f6e0043 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 4 Mar 2004 19:49:21 +0000 Subject: [PATCH 1621/4131] fixed a memleak, fixed a bug in get date and time on a openfilehandle Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1703 --- include/dos_system.h | 5 +++-- src/dos/dos_files.cpp | 15 ++++----------- src/dos/drive_local.cpp | 18 +++++++++++++++++- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 594c81c9..0ef54455 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.20 2004-01-12 20:25:57 finsterr Exp $ */ +/* $Id: dos_system.h,v 1.21 2004-03-04 19:49:14 qbix79 Exp $ */ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ @@ -54,7 +54,7 @@ class DOS_DTA; class DOS_File { public: DOS_File():flags(0) { name=0; refCtr = 0; }; - virtual ~DOS_File(){}; + virtual ~DOS_File(){if(name) delete [] name;}; virtual bool Read(Bit8u * data,Bit16u * size)=0; virtual bool Write(Bit8u * data,Bit16u * size)=0; virtual bool Seek(Bit32u * pos,Bit32u type)=0; @@ -66,6 +66,7 @@ public: virtual bool IsName(const char* _name) { if (!name) return false; return strcmp(name,_name)==0; }; virtual void AddRef() { refCtr++; }; virtual Bits RemoveRef() { return --refCtr; }; + virtual bool UpdateDateTimeFromHost() { return true; } Bit8u type; Bit32u flags; Bit16u time; diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index a85decb5..4d313d4c 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.52 2004-02-02 19:20:38 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.53 2004-03-04 19:49:14 qbix79 Exp $ */ #include #include @@ -966,19 +966,12 @@ bool DOS_GetFileDate(Bit16u entry, Bit16u* otime, Bit16u* odate) DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; - struct stat stat_block; - if (fstat(handle, &stat_block)!=0) { + if (!Files[handle]->UpdateDateTimeFromHost()) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; } - struct tm *time; - if ((time=localtime(&stat_block.st_mtime))!=0) { - *otime = (time->tm_hour<<11)+(time->tm_min<<5)+(time->tm_sec/2); /* standard way. */ - *odate = ((time->tm_year-80)<<9)+((time->tm_mon+1)<<5)+(time->tm_mday); - } else { - *otime = 6; - *odate = 4; - } + *otime = Files[handle]->time; + *odate = Files[handle]->date; return true; }; diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 9cec7b8b..a3509725 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.44 2004-01-11 16:48:32 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.45 2004-03-04 19:49:21 qbix79 Exp $ */ #include #include @@ -39,6 +39,7 @@ public: bool Seek(Bit32u * pos,Bit32u type); bool Close(); Bit16u GetInformation(void); + bool UpdateDateTimeFromHost(void); private: FILE * fhandle; enum { NONE,READ,WRITE } last_action; @@ -437,6 +438,21 @@ localFile::localFile(const char* _name, FILE * handle,Bit16u devinfo) { SetName(_name); } +bool localFile::UpdateDateTimeFromHost(void) { + if(!open) return false; + struct stat temp_stat; + fstat(fileno(fhandle),&temp_stat); + struct tm * ltime; + if((ltime=localtime(&temp_stat.st_mtime))!=0) { + time=DOS_PackTime(ltime->tm_hour,ltime->tm_min,ltime->tm_sec); + date=DOS_PackDate(ltime->tm_year+1900,ltime->tm_mon+1,ltime->tm_mday); + } else { + time=1;date=1; + } + return true; +} + + // ******************************************** // CDROM DRIVE // ******************************************** From 0064c46add162bb533d316187c4fa219d3443d58 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 6 Mar 2004 23:18:50 +0000 Subject: [PATCH 1622/4131] Add VGA copy and fill row functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1704 --- src/ints/int10_char.cpp | 43 +++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 64e2a0f2..a834ffdd 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.23 2004-02-29 22:18:24 harekiet Exp $ */ +/* $Id: int10_char.cpp,v 1.24 2004-03-06 23:18:50 harekiet Exp $ */ /* Character displaying moving functions */ @@ -68,8 +68,8 @@ static INLINE void TANDY16_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rne static INLINE void EGA16_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { PhysPt src,dest;Bitu copy; Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); - dest=base+(CurMode->twidth*rnew)*cheight+cleft; - src=base+(CurMode->twidth*rold)*cheight+cleft; + dest=base+(CurMode->twidth*rnew)*cheight+cleft; + src=base+(CurMode->twidth*rold)*cheight+cleft; Bitu nextline=CurMode->twidth; /* Setup registers correctly */ IO_Write(0x3ce,5);IO_Write(0x3cf,1); /* Memory transfer mode */ @@ -85,6 +85,19 @@ static INLINE void EGA16_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew, IO_Write(0x3ce,5);IO_Write(0x3cf,0); /* Normal transfer mode */ } +static INLINE void VGA_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { + PhysPt src,dest;Bitu copy; + Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); + dest=base+8*((CurMode->twidth*rnew)*cheight+cleft); + src=base+8*((CurMode->twidth*rold)*cheight+cleft); + Bitu nextline=8*CurMode->twidth; + Bitu rowsize=8*(cright-cleft); + copy=cheight; + for (;copy>0;copy--) { + for (Bitu x=0;xtwidth*row)*cheight+cleft; + PhysPt dest=base+(CurMode->twidth*row)*cheight+cleft; Bitu nextline=CurMode->twidth; - Bitu copy = cheight; Bitu rowsize=(cright-cleft); + Bitu copy = cheight;Bitu rowsize=(cright-cleft); for (;copy>0;copy--) { for (Bitu x=0;xtwidth*row)*cheight+cleft); + Bitu nextline=8*CurMode->twidth; + Bitu copy = cheight;Bitu rowsize=8*(cright-cleft); + for (;copy>0;copy--) { + for (Bitu x=0;xtype); } @@ -238,6 +263,8 @@ filling: TANDY16_FillRow(cul,clr,start,base,attr);break; case M_EGA16: EGA16_FillRow(cul,clr,start,base,attr);break; + case M_VGA: + VGA_FillRow(cul,clr,start,base,attr);break; default: LOG(LOG_INT10,LOG_ERROR)("Unhandled mode %d for scroll",CurMode->type); } From b91b041f3f2008f0fb5e15d3d09ad00d797578f6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 7 Mar 2004 08:16:20 +0000 Subject: [PATCH 1623/4131] Fix writing characters in 0x13 mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1705 --- src/ints/int10_char.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index a834ffdd..3008a131 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.24 2004-03-06 23:18:50 harekiet Exp $ */ +/* $Id: int10_char.cpp,v 1.25 2004-03-07 08:16:20 harekiet Exp $ */ /* Character displaying moving functions */ @@ -404,10 +404,10 @@ static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool case M_CGA4: case M_CGA2: case M_TANDY16: - if (chr<128) fontdata=Real2Phys(RealGetVec(0x43))+chr*cheight; //was plain 8 + if (chr<128) fontdata=Real2Phys(RealGetVec(0x43))+chr*cheight; else { chr-=128; - fontdata=Real2Phys(RealGetVec(0x1F))+(chr)*cheight; //was plain 8 + fontdata=Real2Phys(RealGetVec(0x1F))+(chr)*cheight; } break; default: @@ -415,7 +415,7 @@ static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool break; } x=8*col; - y=cheight*row; + y=cheight*row;Bit8u xor_mask=(CurMode->type == M_VGA) ? 0x0 : 0x80; //TODO Check for out of bounds for (Bit8u h=0;h>=1; } From 4acb824303a61ec93ea283248140bcbda4b3742a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 7 Mar 2004 10:30:15 +0000 Subject: [PATCH 1624/4131] Fix filling of rows in tandy 16 color mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1706 --- src/ints/int10_char.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 3008a131..a5ff6f1f 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.25 2004-03-07 08:16:20 harekiet Exp $ */ +/* $Id: int10_char.cpp,v 1.26 2004-03-07 10:30:15 harekiet Exp $ */ /* Character displaying moving functions */ @@ -138,7 +138,7 @@ static INLINE void CGA4_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,B static INLINE void TANDY16_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); - PhysPt dest=base+((CurMode->twidth*row)*cheight+cleft)*4; + PhysPt dest=base+((CurMode->twidth*row)*(cheight/4)+cleft)*4; Bitu copy=(cright-cleft)*4;Bitu nextline=CurMode->twidth*4; attr=(attr & 0xf) | (attr & 0xf) << 4; for (Bitu i=0;i Date: Mon, 8 Mar 2004 13:27:13 +0000 Subject: [PATCH 1625/4131] changed machine default from auto to vga Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1707 --- src/dosbox.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index ee019d89..6bd8c8f9 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.64 2004-03-03 15:44:20 harekiet Exp $ */ +/* $Id: dosbox.cpp,v 1.65 2004-03-08 13:27:13 qbix79 Exp $ */ #include #include @@ -189,7 +189,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit); secprop->Add_string("language",""); - secprop->Add_string("machine","auto"); + secprop->Add_string("machine","vga"); #if C_DEBUG LOG_StartUp(); From e9d22fa895123fa46f77be47e36bd9d9bf3c42c6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 9 Mar 2004 20:13:44 +0000 Subject: [PATCH 1626/4131] Some changes to make the driver conform the specs more closely Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1708 --- src/ints/xms.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 84136250..5dec72c6 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.31 2004-01-14 20:54:41 finsterr Exp $ */ +/* $Id: xms.cpp,v 1.32 2004-03-09 20:13:44 qbix79 Exp $ */ #include #include @@ -128,7 +128,7 @@ Bitu XMS_AllocateMemory(Bitu size, Bit16u& handle) } Bitu pages=(size/4) + ((size & 3) ? 1 : 0); MemHandle mem=MEM_AllocatePages(pages,true); - if (!mem) return XMS_OUT_OF_SPACE; + if ((!mem) && (size != 0)) return XMS_OUT_OF_SPACE; xms_handles[index].free=false; xms_handles[index].mem=mem; xms_handles[index].locked=0; @@ -305,11 +305,11 @@ Bitu XMS_Handler(void) { case XMS_LOCK_EXTENDED_MEMORY_BLOCK: { /* 0c */ Bit32u address; reg_bl = XMS_LockMemory(reg_dx, address); + reg_ax = (reg_bl==0); if (reg_bl==0) { // success reg_bx=(Bit16u)(address & 0xFFFF); reg_dx=(Bit16u)(address >> 16); }; - reg_ax = (reg_bl==0); }; break; case XMS_UNLOCK_EXTENDED_MEMORY_BLOCK: /* 0d */ reg_bl = XMS_UnlockMemory(reg_dx); @@ -350,8 +350,20 @@ void XMS_Init(Section* sec) { BIOS_ZeroExtendedSize(); DOS_AddMultiplexHandler(multiplex_xms); call_xms=CALLBACK_Allocate(); - CALLBACK_Setup(call_xms,&XMS_Handler,CB_RETF); + CALLBACK_Setup(call_xms,&XMS_Handler,CB_RETF, "XMS Handler"); xms_callback=CALLBACK_RealPointer(call_xms); + + /* Overide the callback with one that can be hooked */ + phys_writeb(CB_BASE+(call_xms<<4)+0,(Bit8u)0xeb); //jump near + phys_writeb(CB_BASE+(call_xms<<4)+1,(Bit8u)0x03); //offset + phys_writeb(CB_BASE+(call_xms<<4)+2,(Bit8u)0x90); //NOP + phys_writeb(CB_BASE+(call_xms<<4)+3,(Bit8u)0x90); //NOP + phys_writeb(CB_BASE+(call_xms<<4)+4,(Bit8u)0x90); //NOP + phys_writeb(CB_BASE+(call_xms<<4)+5,(Bit8u)0xFE); //GRP 4 + phys_writeb(CB_BASE+(call_xms<<4)+6,(Bit8u)0x38); //Extra Callback instruction + phys_writew(CB_BASE+(call_xms<<4)+7,call_xms); //The immediate word + phys_writeb(CB_BASE+(call_xms<<4)+9,(Bit8u)0xCB); //A RETF Instruction + for (i=0;i Date: Wed, 10 Mar 2004 13:35:03 +0000 Subject: [PATCH 1627/4131] Added patch 909837 from JAL Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1709 --- include/shell.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/shell.h b/include/shell.h index 202b90b9..6e4b6d25 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.3 2004-02-18 15:31:13 qbix79 Exp $ */ +/* $Id: shell.h,v 1.4 2004-03-10 13:35:03 qbix79 Exp $ */ #ifndef SHELL_H_ #define SHELL_H_ @@ -139,7 +139,8 @@ static inline char* ExpandDot(char*args, char* buffer) buffer[1]=0; strcat(buffer,args); return buffer; - } + } else + strcpy (buffer, args); } else strcpy(buffer,args); return buffer; From 4ef54d59ab64b8519ca6ffd5d11e1ee242fb1941 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Mar 2004 13:49:30 +0000 Subject: [PATCH 1628/4131] some config explanations regarding machina state. First part of patch 897288 by Srecko Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1710 --- src/dosbox.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 6bd8c8f9..69bce9c4 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.65 2004-03-08 13:27:13 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.66 2004-03-10 13:49:30 qbix79 Exp $ */ #include #include @@ -209,8 +209,7 @@ void DOSBOX_Init(void) { MSG_Add("DOSBOX_CONFIGFILE_HELP", "language -- Select another language file.\n" "memsize -- Amount of memory dosbox has in megabytes.\n" - "machine -- The type of machine tries to emulate:auto,hercules,cga,tandy,vga.\n" - " Try a specific type if your game has problems with auto.\n" + "machine -- The type of machine tries to emulate:hercules,cga,tandy,vga.\n" ); secprop=control->AddSection_prop("render",&RENDER_Init); @@ -270,14 +269,16 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("midi",&MIDI_Init); secprop->AddInitFunction(&MPU401_Init); secprop->Add_bool("mpu401",true); + secprop->Add_bool("intelligent",false); secprop->Add_string("device","default"); secprop->Add_string("config",""); MSG_Add("MIDI_CONFIGFILE_HELP", - "mpu401 -- Enable MPU-401 Emulation.\n" - "device -- Device that will receive the MIDI data from MPU-401.\n" - " This can be default,alsa,oss,win32,coreaudio,none.\n" - "config -- Special configuration options for the device.\n" + "mpu401 -- Enable MPU-401 Emulation.\n" + "device -- Device that will receive the MIDI data from MPU-401.\n" + " This can be default,alsa,oss,win32,coreaudio,none.\n" + "intelligent -- Operate in Intelligent mode.\n" + "config -- Special configuration options for the device.\n" ); #if C_DEBUG From b6ae52df7ac4981ff31af7077f1f6cbd8114cf54 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Mar 2004 13:53:40 +0000 Subject: [PATCH 1629/4131] Changed priority tables a bit to reflect a real machine better(hopefully). Second part of patch 897288 by Srecko Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1711 --- src/hardware/pic.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 3cdd7380..43895d2c 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.18 2004-02-08 13:04:34 harekiet Exp $ */ +/* $Id: pic.cpp,v 1.19 2004-03-10 13:53:40 qbix79 Exp $ */ #include @@ -74,7 +74,7 @@ static void write_command(Bit32u port,Bit8u val) { Bitu irq_base=port==0x20 ? 0 : 8; Bitu i; Bit16u IRQ_priority_table[16] = - { 0,1,8,9,10,11,12,13,14,15,2,3,4,5,6,7 }; + { 0,1,2,9,10,11,12,13,14,15,3,4,5,6,7,8 }; switch (val) { case 0x0A: /* select read interrupt request register */ pic->request_issr=false; @@ -240,22 +240,21 @@ void PIC_runIRQs(void) { if (!GETFLAG(IF)) return; if (!PIC_IRQCheck) return; Bit16u IRQ_priority_lookup[17] = - { 0,1,10,11,12,13,14,15,2,3,4,5,6,7,8,9,16 }; + { 0,1,2,11,12,13,14,15,3,4,5,6,7,8,9,10,16 }; Bit16u activeIRQ = PIC_IRQActive; if (activeIRQ==PIC_NOIRQ) activeIRQ = 16; for (i=0;i<=15;i++) { - if (IRQ_priority_lookup[i] Date: Wed, 10 Mar 2004 14:08:18 +0000 Subject: [PATCH 1630/4131] Some subst fixes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1712 --- src/shell/shell_cmds.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index bef3633b..8d5267a5 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.38 2004-02-24 09:27:29 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.39 2004-03-10 14:08:18 qbix79 Exp $ */ #include @@ -616,11 +616,13 @@ void DOS_Shell::CMD_SUBST (char * args) { if( ( ldp=dynamic_cast(Drives[drive])) == 0 ) throw 0; char newname[CROSS_LEN]; - strcpy(newname, ldp->basedir); + strcpy(newname, ldp->basedir); strcat(newname,fulldir); CROSS_FILENAME(newname); ldp->dirCache.ExpandName(newname); + strcat(mountstring,"\""); strcat(mountstring, newname); + strcat(mountstring,"\""); this->ParseLine(mountstring); } catch(int a){ @@ -631,7 +633,11 @@ void DOS_Shell::CMD_SUBST (char * args) { } return; } - + catch(...) { //dynamic cast failed =>so no localdrive + WriteOut(MSG_Get("SHELL_CMD_SUBST_FAILURE")); + return; + } + return; } From 64c81ef898d5d7a5139e5587699b645807775270 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 10 Mar 2004 22:50:51 +0000 Subject: [PATCH 1631/4131] Fix compilation with sdl 1.2.7 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1713 --- src/gui/sdlmain.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 7a2cfc63..d4784940 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.63 2004-03-01 18:27:03 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.64 2004-03-10 22:50:51 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -41,6 +41,8 @@ #include "support.h" #include "debug.h" +//#define DISABLE_JOYSTICK + #if C_OPENGL #include "SDL_opengl.h" @@ -53,30 +55,35 @@ #ifdef __WIN32__ #define NVIDIA_PixelDataRange 1 + #ifndef WGL_NV_allocate_memory #define WGL_NV_allocate_memory 1 typedef void * (APIENTRY * PFNWGLALLOCATEMEMORYNVPROC) (int size, float readfreq, float writefreq, float priority); typedef void (APIENTRY * PFNWGLFREEMEMORYNVPROC) (void *pointer); +#endif + PFNWGLALLOCATEMEMORYNVPROC db_glAllocateMemoryNV = NULL; PFNWGLFREEMEMORYNVPROC db_glFreeMemoryNV = NULL; -#endif + #else #endif #if defined(NVIDIA_PixelDataRange) + #ifndef GL_NV_pixel_data_range #define GL_NV_pixel_data_range 1 #define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer); typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); -PFNGLPIXELDATARANGENVPROC glPixelDataRangeNV = NULL; #endif + +PFNGLPIXELDATARANGENVPROC glPixelDataRangeNV = NULL; + #endif #endif //C_OPENGL -//#define DISABLE_JOYSTICK #if !(ENVIRON_INCLUDED) extern char** environ; @@ -608,7 +615,7 @@ static void GUI_StartUp(Section * sec) { sdl.opengl.packed_pixel=(strstr(gl_ext,"EXT_packed_pixels") > 0); sdl.opengl.paletted_texture=(strstr(gl_ext,"EXT_paletted_texture") > 0); #if defined(NVIDIA_PixelDataRange) - sdl.opengl.pixel_data_range=(strstr(gl_ext,"GL_NV_pixel_data_range") >0 )&& + sdl.opengl.pixel_data_range=(strstr(gl_ext,"GL_NV_pixel_data_range") >0 ) && glPixelDataRangeNV && db_glAllocateMemoryNV && db_glFreeMemoryNV; #endif } else { From acc1373574e6f00092d309a8513160eef506309e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 11 Mar 2004 10:45:53 +0000 Subject: [PATCH 1632/4131] Final part of patch 897288 by Srecko Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1714 --- src/hardware/mpu401.cpp | 526 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 478 insertions(+), 48 deletions(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index d68e0a35..ea60b8bb 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -1,19 +1,25 @@ #include #include "dosbox.h" #include "inout.h" -#include "mixer.h" -#include "dma.h" #include "pic.h" -#include "hardware.h" #include "setup.h" -#include "programs.h" +#include "cpu.h" +#include "callback.h" void MIDI_RawOutByte(Bit8u data); bool MIDI_Available(void); -#define MPU_QUEUE 32 -enum MpuMode { M_UART,M_INTELLIGENT } ; +static Bitu call_irq9; +static void MPU401_Event(Bitu); +static void MPU401_Reset(void); +static void MPU401_EOIHandler(void); +#define MPU_QUEUE 32 +#define MPU_RQ_QUEUE 64 +#define TIMECONSTANT 60000000 + +enum MpuMode { M_UART,M_INTELLIGENT } ; +enum MpuDataType {UNSET,OVERFLOW,MARK,MIDI_SYS,MIDI_NORM,MIDI_DATA,COMMAND}; ///////////////////////////////////////////////////////////////////////////// // I/O @@ -45,6 +51,9 @@ enum MpuMode { M_UART,M_INTELLIGENT } ; Larry Troxler, Compuserve 73520,1736 + + 15.02.2004: updated and implemented intelligent mode + ****************************************************************************/ // Start/Stop Commands @@ -64,6 +73,7 @@ enum MpuMode { M_UART,M_INTELLIGENT } ; #define CMD_DISABLE_ALL_NOTES_OFF 0x30 #define CMD_DISABLE_REAL_TIME_OUT 0x32 +#define CMD_DISABLE_ALL_THRU_OFF 0x33 #define CMD_TIMING_BYTE_ALWAYS 0x34 #define CMD_MODE_MESS_ON 0x35 #define CMD_EXCLUSIVE_THRU_ON 0x37 @@ -116,21 +126,21 @@ enum MpuMode { M_UART,M_INTELLIGENT } ; #define CMD_RELATIVE_TEMPO_GRADUATION 0xe2 #define CMD_MIDI_METRONOME 0xe4 #define CMD_MEASURE_LENGTH 0xe6 -#define CMD_INTERNAL_CLOCK_LENGTH_TO_HOST /* ? */ +#define CMD_INTERNAL_CLOCK_LENGTH_TO_HOST 0xe7 #define CMD_ACTIVE_TRACK_MASK 0xec #define CMD_SEND_PLAY_COUNTER_MASK 0xed #define CMD_MIDI_CHANNEL_MASK_LO 0xee #define CMD_MIDI_CHANNEL_MASK_HI 0xef -#define CMD_EOX 0xf7 -#define CMD_TIMING_OVERFLOW 0xf8 -#define CMD_MPU_MARK 0xfc +#define CMD_EOX 0xf7 +#define CMD_TIMING_OVERFLOW 0xf8 +#define CMD_MPU_MARK 0xfc #define CMD_RESET 0xff // Commands that return data -#define CMD_REQUEST_PLAY_COUNTER 0xa0 -#define CMD_REQUEST_AND_CLEAR_PLAY_COUNTER 0xab +#define CMD_REQUEST_PLAY_COUNTER 0xa0 /* + track # */ +#define CMD_REQUEST_AND_CLEAR_REC_COUNTER 0xab #define CMD_REQUEST_VERSION 0xac #define CMD_REQUEST_REVISION 0xad #define CMD_REQUEST_TEMPO 0xaf @@ -140,21 +150,59 @@ enum MpuMode { M_UART,M_INTELLIGENT } ; // Messages ///////////////////////////////////////////////////////////////////////////// +#define MSG_TIMING_OVERFLOW 0xf8 +#define MSG_ALL_END 0xfc +#define MSG_CLOCK_TO_HOST 0xfd #define MSG_CMD_ACK 0xfe +#define MSG_REQUEST_DATA 0xf0 +#define MSG_REQUEST_COMMAND 0xf9 +#define MPU_VERSION 0x15 +#define MPU_REVISION 0x01 +///////////////////////////////////////////////////////////////////////////// static struct { + bool intelligent; MpuMode mode; + Bitu irq; Bit8u queue[MPU_QUEUE]; Bitu queue_pos,queue_used; - Bitu cmd; - + struct type_t{ + Bits counter; + Bit8u value[8]; + Bit8u vlength; + MpuDataType type; + } playbuf[8],condbuf; + struct { + bool conductor,cond_req,cond_set; + bool allnotes,realtime,allthru; + bool playing; + bool wsd,wsm; + bool midi_thru; + bool run_irq,irq_pending; + Bits data_onoff; + Bitu command_byte; + Bit8u tmask,cmask,amask; + Bit16u midi_mask; + Bit16u req_mask; + Bit8u channel; + } state; + struct { + Bit8u timebase,old_timebase; + Bit8u tempo,old_tempo; + Bit8u tempo_rel,old_tempo_rel; + Bit8u tempo_grad; + Bit8u cth_rate,cth_counter; + bool clock_to_host,cth_active; + } clock; } mpu; + static void QueueByte(Bit8u data) { if (mpu.queue_used=MPU_QUEUE) mpu.queue_pos-=MPU_QUEUE; if (pos>=MPU_QUEUE) pos-=MPU_QUEUE; mpu.queue_used++; mpu.queue[pos]=data; @@ -166,54 +214,429 @@ static void ClrQueue(void) { mpu.queue_pos=0; } -static void MPU401_WriteCommand(Bit32u port,Bit8u val) { - switch (val) { - case CMD_UART_MODE: /* Switch to UART Mode */ - mpu.mode=M_UART; - QueueByte(MSG_CMD_ACK); - break; - case CMD_RESET: /* Reset Commmand */ - mpu.mode=M_INTELLIGENT; - ClrQueue(); - QueueByte(MSG_CMD_ACK); - break; - - case CMD_REQUEST_TO_SEND_DATA: - case CMD_REQUEST_TO_SEND_SYSTEM_MSG: - QueueByte(MSG_CMD_ACK); - break; - - default: - LOG(LOG_MISC,LOG_NORMAL)("MPU401:Unhandled command %X",val); - QueueByte(MSG_CMD_ACK); - break; - } - -} - static Bit8u MPU401_ReadStatus(Bit32u port) { - - Bit8u ret=0x3f; /* Bith 6 and 7 clear */ + Bit8u ret=0x3f; /* Bits 6 and 7 clear */ if (!mpu.queue_used) ret|=0x80; return ret; } - -static void MPU401_WriteData(Bit32u port,Bit8u val) { - MIDI_RawOutByte(val); +static void MPU401_WriteCommand(Bit32u port,Bit8u val) { + LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Command %x",val); + if (val && val<=0x2f) { + switch (val&3) { + case 1: {MIDI_RawOutByte(0xfc);break;} + case 2: {MIDI_RawOutByte(0xfa);break;} + case 3: {MIDI_RawOutByte(0xfb);break;} + } + if (val&0x20) LOG(LOG_MISC,LOG_ERROR)("MPU-401:Unhandled Recording Command %x",val); + switch (val&0xc) { + case 0x4: /* Stop */ + PIC_RemoveEvents(MPU401_Event); + mpu.state.playing=false; + ClrQueue(); + break; + case 0x8: /* Play */ + mpu.state.playing=true; + PIC_RemoveEvents(MPU401_Event); + PIC_AddEvent(MPU401_Event,TIMECONSTANT/(mpu.clock.tempo*mpu.clock.timebase)); + mpu.state.irq_pending=false; + break; + } + } + else if (val>=0xa0 && val<=0xa7) {/* Request play counter */ + if (mpu.state.cmask&(1<<(val&7))) QueueByte(mpu.playbuf[val&7].counter); + } + else if (val>=0xd0 && val<=0xd7) { /* Request to send data */ + mpu.state.channel=val&7; + //if (!mpu.playbuf[mpu.state.channel].active) + mpu.state.wsd=true; + mpu.state.wsm=false; + } + else + switch (val) { + case CMD_REQUEST_TO_SEND_SYSTEM_MSG: + mpu.state.wsd=false; + mpu.state.wsm=true; + break; + case CMD_CONDUCTOR_ON: + mpu.state.cond_set=true; + break; + case CMD_CONDUCTOR_OFF: + mpu.state.cond_set=false; + break; + case CMD_CLOCK_TO_HOST_OFF: + mpu.clock.clock_to_host=false; + break; + case CMD_CLOCK_TO_HOST_ON: + mpu.clock.clock_to_host=true; + break; + case CMD_REAL_TIME_AFFECTION_OFF: + break; + case CMD_REAL_TIME_AFFECTION_ON: + LOG(LOG_MISC,LOG_ERROR)("MPU401:Unimplemented:Realtime affection:ON"); + break; + case CMD_MIDI_THRU_OFF: + mpu.state.midi_thru=false; + break; + case CMD_MIDI_THRU_ON: + mpu.state.midi_thru=true; + break; + case CMD_TIMEBASE_48: /* Internal clock resolution per beat */ + mpu.clock.timebase=48; + break; + case CMD_TIMEBASE_72: + mpu.clock.timebase=72; + break; + case CMD_TIMEBASE_96: + mpu.clock.timebase=96; + break; + case CMD_TIMEBASE_120: + mpu.clock.timebase=120; + break; + case CMD_TIMEBASE_144: + mpu.clock.timebase=144; + break; + case CMD_TIMEBASE_168: + mpu.clock.timebase=168; + break; + case CMD_TIMEBASE_192: + mpu.clock.timebase=192; + break; + /* Commands with data byte */ + case CMD_MIDI_METRONOME: + case CMD_MEASURE_LENGTH: + case CMD_RELATIVE_TEMPO: + case CMD_SET_TEMPO: + case CMD_RELATIVE_TEMPO_GRADUATION: + case CMD_INTERNAL_CLOCK_LENGTH_TO_HOST: + case CMD_ACTIVE_TRACK_MASK: + case CMD_SEND_PLAY_COUNTER_MASK: + case CMD_MIDI_CHANNEL_MASK_LO: + case CMD_MIDI_CHANNEL_MASK_HI: + mpu.state.command_byte=val; + break; + /* Commands Returning Data */ + case CMD_REQUEST_VERSION: + QueueByte(MSG_CMD_ACK); + QueueByte(MPU_VERSION); + return; + case CMD_REQUEST_REVISION: + QueueByte(MSG_CMD_ACK); + QueueByte(MPU_REVISION); + return; + case CMD_REQUEST_TEMPO: + QueueByte(MSG_CMD_ACK); + QueueByte(mpu.clock.tempo); + return; + case CMD_REQUEST_AND_CLEAR_REC_COUNTER: + QueueByte(MSG_CMD_ACK); + QueueByte(0); + return; + case CMD_RESET_RELATIVE_TEMPO: + mpu.clock.tempo_rel=40; + break; + case CMD_CLEAR_PLAY_MAP: + mpu.state.tmask=0; + case CMD_CLEAR_PLAY_COUNTERS: + for (Bitu i=0xb0;i<0xbf;i++) {//All notes off + MIDI_RawOutByte(i); + MIDI_RawOutByte(0x7b); + MIDI_RawOutByte(0); + } + for (Bitu i=0;i<8;i++) { + mpu.playbuf[i].counter=0; + mpu.playbuf[i].type=UNSET; + } + mpu.condbuf.counter=0; + mpu.condbuf.type=OVERFLOW; + if (!(mpu.state.conductor=mpu.state.cond_set)) mpu.state.cond_req=0; + mpu.state.amask=mpu.state.tmask; + mpu.state.req_mask=0; + break; + case CMD_RESET: /* Reset MPU401 */ + MPU401_Reset(); + if (mpu.intelligent) { + QueueByte(MSG_CMD_ACK); //additional ACK for interrupt routine + mpu.state.irq_pending=true; + PIC_ActivateIRQ(mpu.irq); //UNDOCUMENTED + } + break; + /* Initialization Commands */ + case CMD_UART_MODE: + mpu.mode=M_UART; + break; + case CMD_DISABLE_ALL_NOTES_OFF: + mpu.state.allnotes=false; + break; + case CMD_DISABLE_REAL_TIME_OUT: + mpu.state.realtime=false; + break; + case CMD_DISABLE_ALL_THRU_OFF: + mpu.state.allthru=false; + break; + default: + LOG(LOG_MISC,LOG_NORMAL)("MPU401:Unhandled command %X",val); + } + QueueByte(MSG_CMD_ACK); } static Bit8u MPU401_ReadData(Bit32u port) { Bit8u ret=MSG_CMD_ACK; if (mpu.queue_used) { ret=mpu.queue[mpu.queue_pos]; - mpu.queue_pos++; if (mpu.queue_pos>=MPU_QUEUE) mpu.queue_pos-=MPU_QUEUE; - mpu.queue_used--; + mpu.queue_pos++;mpu.queue_used--; + } + if (ret>=0xf0 && ret<=0xf7) { + mpu.state.channel=ret&7; + mpu.state.data_onoff=0; + mpu.state.cond_req=false; + mpu.playbuf[mpu.state.channel].counter=0; + } + if (ret==MSG_REQUEST_COMMAND) { + mpu.state.data_onoff=0; + mpu.state.cond_req=true; + mpu.condbuf.counter=0; + } + if (ret==MSG_ALL_END || ret==MSG_CLOCK_TO_HOST) { + mpu.state.data_onoff=-1; } return ret; } +static void MPU401_WriteData(Bit32u port,Bit8u val) { + if (mpu.mode==M_UART) {MIDI_RawOutByte(val);return;} + switch (mpu.state.command_byte) { + case 0: + break; + case CMD_SET_TEMPO: + mpu.state.command_byte=0; + mpu.clock.tempo=val; + return; + case CMD_INTERNAL_CLOCK_LENGTH_TO_HOST: + mpu.state.command_byte=0; + mpu.clock.cth_rate=val>>2; + return; + case CMD_ACTIVE_TRACK_MASK: + mpu.state.command_byte=0; + mpu.state.tmask=val; + return; + case CMD_SEND_PLAY_COUNTER_MASK: + mpu.state.command_byte=0; + mpu.state.cmask=val; + return; + case CMD_MIDI_CHANNEL_MASK_LO: + mpu.state.command_byte=0; + mpu.state.midi_mask&=0xff00; + mpu.state.midi_mask|=val; + return; + case CMD_MIDI_CHANNEL_MASK_HI: + mpu.state.command_byte=0; + mpu.state.midi_mask&=0x00ff; + mpu.state.midi_mask|=((Bit16u)val)<<8; + return; + //case CMD_RELATIVE_TEMPO: + //case CMD_RELATIVE_TEMPO_GRADUATION: + //case CMD_MIDI_METRONOME: + //case CMD_MIDI_MEASURE: + default: + mpu.state.command_byte=0; + return; + } + if (mpu.state.wsd) { + if (val>=0xf0 && !mpu.state.allthru) return; + MIDI_RawOutByte(val); + mpu.state.wsd=0; + return; + } + if (mpu.state.wsm) { + if (val==CMD_EOX) {mpu.state.wsm=0;return;} + if (val>=0xf0 && !mpu.state.allthru) return; + MIDI_RawOutByte(val); + return; + } + if (mpu.state.cond_req) { /* Command */ + switch (mpu.state.data_onoff) { + case 0: /* Timing byte */ + mpu.condbuf.vlength=0; + if (val<0xf0) mpu.state.data_onoff=1; + else if (val==0xf8) { + mpu.state.data_onoff=-1; + mpu.condbuf.type=OVERFLOW; + } else return; + mpu.condbuf.counter=val; + break; + case 1: + mpu.condbuf.type=COMMAND; + if ((val&0xd0)==0xd0) + LOG(LOG_MISC,LOG_ERROR)("'Want to send data' used with conductor"); + mpu.condbuf.value[mpu.condbuf.vlength]=val; + mpu.condbuf.vlength++; + default: + break; + } + return; + } + Bitu posd; + switch (mpu.state.data_onoff) { /* Data */ + case -1: + return; + case 0: /* Timing byte */ + mpu.playbuf[mpu.state.channel].vlength=0; + if (val<0xf0) {mpu.state.data_onoff=1;} + else if (val==0xf8) { + mpu.state.data_onoff=-1; + mpu.playbuf[mpu.state.channel].type=OVERFLOW; + } else { + mpu.playbuf[mpu.state.channel].counter=0xf8; + mpu.state.data_onoff=-1; + return; + } + mpu.playbuf[mpu.state.channel].counter=val; + break; + case 1: + mpu.playbuf[mpu.state.channel].vlength++; + if ((posd=mpu.playbuf[mpu.state.channel].vlength)>8) return; + mpu.playbuf[mpu.state.channel].value[posd-1]=val; + if (posd==1) { + switch (val&0xf0) { + case 0xf0: + mpu.playbuf[mpu.state.channel].type=(val>0xf7 ? MARK : MIDI_SYS); + break; + case 0xe0: case 0xd0: case 0xc0: case 0xb0: case 0xa0: case 0x90: case 0x80: + mpu.playbuf[mpu.state.channel].type=MIDI_NORM; + break; + default: + mpu.playbuf[mpu.state.channel].type=MIDI_DATA; + } + } + } +} + +static void MPU401_IntelligentOut(Bit8u chan) { + Bitu val; + switch (mpu.playbuf[chan].type) { + case UNSET: + case OVERFLOW: + break; + case MARK: + val=mpu.playbuf[chan].value[0]; + if (val==0xfc) {MIDI_RawOutByte(val);mpu.state.amask&=~(1<= mpu.clock.cth_rate) { + mpu.clock.cth_counter=0; + mpu.state.req_mask|=(1<<13); + } + } + if (!mpu.state.irq_pending && mpu.state.req_mask) MPU401_EOIHandler(); + + PIC_RemoveEvents(MPU401_Event); + Bitu new_time; + if ((new_time=mpu.clock.tempo*mpu.clock.timebase)==0) return; + PIC_AddEvent(MPU401_Event,TIMECONSTANT/new_time); +} + + +static void MPU401_EOIHandler(void) +{ + mpu.state.irq_pending=false; + if (!mpu.state.req_mask) return; + ClrQueue(); + Bitu i=0; + do { + if (mpu.state.req_mask&(1<(sec); @@ -228,6 +651,13 @@ void MPU401_Init(Section* sec) { mpu.queue_used=0; mpu.queue_pos=0; + mpu.mode=M_UART; + + if (!(mpu.intelligent=section->Get_bool("intelligent"))) return; + mpu.irq=2; + PIC_RegisterIRQ(mpu.irq,0,"MPU401"); + call_irq9=CALLBACK_Allocate(); //allocate handler for irq 9 + CALLBACK_Setup(call_irq9,&INT71_Handler,CB_IRET); + RealSetVec(0x71,CALLBACK_RealPointer(call_irq9)); + MPU401_Reset(); } - - From 1561e03647085cc19c5ca9f081f8382b813dcb7f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 11 Mar 2004 20:35:25 +0000 Subject: [PATCH 1633/4131] Changes of Srecko in the parts he coded Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1715 --- src/hardware/mpu401.cpp | 43 ++++++++++++++++++++++++++++++++------- src/hardware/sblaster.cpp | 14 ++++++------- 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index ea60b8bb..409adb97 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -178,7 +178,7 @@ static struct { bool conductor,cond_req,cond_set; bool allnotes,realtime,allthru; bool playing; - bool wsd,wsm; + bool wsd,wsm,wsd_start; bool midi_thru; bool run_irq,irq_pending; Bits data_onoff; @@ -245,18 +245,20 @@ static void MPU401_WriteCommand(Bit32u port,Bit8u val) { } else if (val>=0xa0 && val<=0xa7) {/* Request play counter */ if (mpu.state.cmask&(1<<(val&7))) QueueByte(mpu.playbuf[val&7].counter); - } + } else if (val>=0xd0 && val<=0xd7) { /* Request to send data */ mpu.state.channel=val&7; //if (!mpu.playbuf[mpu.state.channel].active) mpu.state.wsd=true; mpu.state.wsm=false; + mpu.state.wsd_start=true; } else switch (val) { case CMD_REQUEST_TO_SEND_SYSTEM_MSG: mpu.state.wsd=false; mpu.state.wsm=true; + mpu.state.wsd_start=true; break; case CMD_CONDUCTOR_ON: mpu.state.cond_set=true; @@ -443,16 +445,43 @@ static void MPU401_WriteData(Bit32u port,Bit8u val) { mpu.state.command_byte=0; return; } + static Bitu length,cnt; if (mpu.state.wsd) { - if (val>=0xf0 && !mpu.state.allthru) return; - MIDI_RawOutByte(val); - mpu.state.wsd=0; + if (mpu.state.wsd_start) { + mpu.state.wsd_start=0; + cnt=0; + switch (val&0xf0) { + case 0xc0: + case 0xd0: + length=2; + break; + case 0xf0: + if (!mpu.state.allthru) {mpu.state.wsd=0;return;} + else {length=1;break;} + default: + length=3; + } + } + if (cnt=0xf0 && !mpu.state.allthru) return; - MIDI_RawOutByte(val); + if (mpu.state.wsd_start) { + mpu.state.wsd_start=0; + cnt=0; + switch (val) { + case 0xf2:{ length=3; break;} + case 0xf3:{ length=2; break;} + case 0xf6:{ length=1; break;} + case 0xf0:{ length=0; break;} + default: + length=0; + } + } + if (!length || cnt>3)&7,sb.adpcm.reference,sb.adpcm.stepsize); read+=2; if (ad==2) { - sb.tmp.buf.m[read]=decode_ADPCM_3_sample(((sb.dma.buf.b8[(read-2)*3/8-1]>>6)&3)&(sb.dma.buf.b8[read*3/8]&1), sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[read]=decode_ADPCM_3_sample(((sb.dma.buf.b8[(read-2)*3/8-1]>>6)&3)&(sb.dma.buf.b8[(read-2)*3/8]&1), sb.adpcm.reference,sb.adpcm.stepsize); sb.tmp.buf.m[read+1]=decode_ADPCM_3_sample((sb.dma.buf.b8[(read-2)*3/8]>>1)&7,sb.adpcm.reference,sb.adpcm.stepsize); sb.tmp.buf.m[read+2]=decode_ADPCM_3_sample((sb.dma.buf.b8[(read-2)*3/8]>>4)&7,sb.adpcm.reference,sb.adpcm.stepsize); read+=3; @@ -693,21 +693,21 @@ static void DSP_DoCommand(void) { //TODO Maybe check limit for new irq? sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); break; - case 0x75: /* 075h : Single Cycle 4-bit ADPCM Reference */ + case 0x75: /* 075h : Single Cycle 4-bit ADPCM Reference */ sb.adpcm.reference=0x1000000; - case 0x74: /* 074h : Single Cycle 4-bit ADPCM */ + case 0x74: /* 074h : Single Cycle 4-bit ADPCM */ sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); DSP_StartDMATranfser(DMA_4_SINGLE); break; - case 0x77: /* 074h : Single Cycle 3-bit(2.6bit) ADPCM Reference*/ + case 0x77: /* 077h : Single Cycle 3-bit(2.6bit) ADPCM Reference*/ sb.adpcm.reference=0x1000000; - case 0x76: /* 074h : Single Cycle 3-bit(2.6bit) ADPCM */ + case 0x76: /* 076h : Single Cycle 3-bit(2.6bit) ADPCM */ sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); DSP_StartDMATranfser(DMA_3_SINGLE); break; - case 0x17: /* 074h : Single Cycle 2-bit ADPCM Reference*/ + case 0x17: /* 017h : Single Cycle 2-bit ADPCM Reference*/ sb.adpcm.reference=0x1000000; - case 0x16: /* 074h : Single Cycle 2-bit ADPCM */ + case 0x16: /* 016h : Single Cycle 2-bit ADPCM */ sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); DSP_StartDMATranfser(DMA_2_SINGLE); break; From 44bafe6a291ccfba309c886909fb03e4fb4a35e1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 12 Mar 2004 09:06:28 +0000 Subject: [PATCH 1634/4131] Fix switching from 32 to 16 address lookups with a prefix Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1716 --- src/cpu/core_normal.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index e4128d9c..84076958 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -94,8 +94,9 @@ extern Bitu cycle_count; core.seg_prefix_base=SegBase(_SEG); \ goto restart_prefix; -#define DO_PREFIX_ADDR() \ - core.prefixes|=(core.prefix_default ^ PREFIX_ADDR) & PREFIX_ADDR; \ +#define DO_PREFIX_ADDR() \ + core.prefixes=(core.prefixes & ~PREFIX_ADDR) | \ + (core.prefix_default ^ PREFIX_ADDR) & PREFIX_ADDR; \ goto restart_prefix; #define DO_PREFIX_REP(_ZERO) \ From 1ceeb2c5cee6944fe9ef62aac077bdab587768ad Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 12 Mar 2004 09:06:45 +0000 Subject: [PATCH 1635/4131] Always calculate all flags with mul,imul Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1717 --- src/cpu/instructions.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 3f941135..07f1a277 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -548,7 +548,7 @@ } #define MULB(op1,load,save) \ - lflags.type=t_MUL; \ + FillFlags(); \ reg_ax=reg_al*load(op1); \ if (reg_ax & 0xff00) { \ SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ @@ -558,10 +558,10 @@ #define MULW(op1,load,save) \ { \ + FillFlags(); \ Bitu tempu=(Bitu)reg_ax*(Bitu)(load(op1)); \ reg_ax=(Bit16u)(tempu); \ reg_dx=(Bit16u)(tempu >> 16); \ - lflags.type=t_MUL; \ if (reg_dx) { \ SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ } else { \ @@ -571,10 +571,10 @@ #define MULD(op1,load,save) \ { \ + FillFlags(); \ Bit64u tempu=(Bit64u)reg_eax*(Bit64u)(load(op1)); \ reg_eax=(Bit32u)(tempu); \ reg_edx=(Bit32u)(tempu >> 32); \ - lflags.type=t_MUL; \ if (reg_edx) { \ SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ } else { \ @@ -651,7 +651,7 @@ #define IMULB(op1,load,save) \ { \ - lflags.type=t_MUL; \ + FillFlags(); \ reg_ax=((Bit8s)reg_al) * ((Bit8s)(load(op1))); \ if ((reg_ax & 0xff80)==0xff80 || \ (reg_ax & 0xff80)==0x0000) { \ @@ -664,10 +664,10 @@ #define IMULW(op1,load,save) \ { \ + FillFlags(); \ Bits temps=((Bit16s)reg_ax)*((Bit16s)(load(op1))); \ reg_ax=(Bit16s)(temps); \ reg_dx=(Bit16s)(temps >> 16); \ - lflags.type=t_MUL; \ if (((temps & 0xffff8000)==0xffff8000 || \ (temps & 0xffff8000)==0x0000)) { \ SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ @@ -678,11 +678,11 @@ #define IMULD(op1,load,save) \ { \ + FillFlags(); \ Bit64s temps=((Bit64s)((Bit32s)reg_eax))* \ ((Bit64s)((Bit32s)(load(op1)))); \ reg_eax=(Bit32u)(temps); \ reg_edx=(Bit32u)(temps >> 32); \ - lflags.type=t_MUL; \ if ((reg_edx==0xffffffff) && \ (reg_eax & 0x80000000) ) { \ SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ @@ -696,10 +696,10 @@ #define DIMULW(op1,op2,op3,load,save) \ { \ + FillFlags(); \ Bits res; \ res=((Bit16s)op2) * ((Bit16s)op3); \ save(op1,res & 0xffff); \ - lflags.type=t_MUL; \ if ((res> -32768) && (res<32767)) { \ SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ } else { \ @@ -709,9 +709,9 @@ #define DIMULD(op1,op2,op3,load,save) \ { \ + FillFlags(); \ Bit64s res=((Bit64s)((Bit32s)op2))*((Bit64s)((Bit32s)op3)); \ save(op1,(Bit32s)res); \ - lflags.type=t_MUL; \ if ((res>-((Bit64s)(2147483647)+1)) && \ (res<(Bit64s)2147483647)) { \ SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ From 6905301089a4545e58333a4946a66f1d6e841120 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 12 Mar 2004 14:21:33 +0000 Subject: [PATCH 1636/4131] Dos stack size change. added kernel idle call Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1718 --- src/dos/dos.cpp | 4 ++-- src/dos/dos_execute.cpp | 6 +++--- src/dos/dos_misc.cpp | 3 +++ 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 35f14aaa..aae802b5 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.67 2004-02-28 16:35:14 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.68 2004-03-12 14:21:33 qbix79 Exp $ */ #include #include @@ -46,7 +46,7 @@ void DOS_SetError(Bit16u code) { static Bitu DOS_21Handler(void) { if (((reg_ah != 0x50) && (reg_ah != 0x51) && (reg_ah != 0x62) && (reg_ah != 0x64)) && (reg_ah<0x6c)) { DOS_PSP psp(dos.psp); - psp.SetStack(RealMake(SegValue(ss),reg_sp-20)); + psp.SetStack(RealMake(SegValue(ss),reg_sp-18)); } char name1[DOSNAMEBUF+1]; char name2[DOSNAMEBUF+1]; diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index a8a17dc2..d781d976 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.35 2004-02-28 16:35:14 qbix79 Exp $ */ +/* $Id: dos_execute.cpp,v 1.36 2004-03-12 14:21:33 qbix79 Exp $ */ #include #include "dosbox.h" @@ -65,7 +65,7 @@ struct EXE_Header { static void SaveRegisters(void) { - reg_sp-=20; + reg_sp-=18; mem_writew(SegPhys(ss)+reg_sp+ 0,reg_ax); mem_writew(SegPhys(ss)+reg_sp+ 2,reg_cx); mem_writew(SegPhys(ss)+reg_sp+ 4,reg_dx); @@ -87,7 +87,7 @@ static void RestoreRegisters(void) { reg_bp=mem_readw(SegPhys(ss)+reg_sp+12); SegSet16(ds,mem_readw(SegPhys(ss)+reg_sp+14)); SegSet16(es,mem_readw(SegPhys(ss)+reg_sp+16)); - reg_sp+=20; + reg_sp+=18; } diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index ddfa2d2f..c559f037 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -60,6 +60,9 @@ static bool DOS_MultiplexFunctions(void) { //TODO Maybe do some idling but could screw up other systems :) reg_al=0; return true; + case 0x1689: /* Kernel IDLE CALL */ + reg_al=0; //Likely. Please check !!!!!!!!!!!!!!! + return true; case 0x168f: /* Close awareness crap */ return true; } From 5de58e54bc614eb23f9d87b6b130b7d1b0d0a3a6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 12 Mar 2004 17:34:48 +0000 Subject: [PATCH 1637/4131] Add the SDL_CFLAGS to CPP_FLAGS Test for sdl_net.h instead of sdl/sdl_net.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1719 --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index ee1041c5..657a3015 100644 --- a/configure.in +++ b/configure.in @@ -26,7 +26,7 @@ AM_PATH_SDL($SDL_VERSION, AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!]) ) LIBS="$LIBS $SDL_LIBS" -CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" +CPPFLAGS="$CPPFLAGS $SDL_CFLAGS" dnl Checks for header files. @@ -144,7 +144,7 @@ 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/SDL_net.h,have_sdl_net_h=yes,) +AC_CHECK_HEADER(SDL_net.h,have_sdl_net_h=yes,) AC_CHECK_LIB(SDL_net, SDLNet_Init, have_sdl_net_lib=yes, , ) if test x$have_sdl_net_lib = xyes -a x$have_sdl_net_h = xyes ; then LIBS="$LIBS -lSDL_net" From 7deaa068a58e5262c0f6563adc2f72f974c6670a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 14 Mar 2004 13:39:45 +0000 Subject: [PATCH 1638/4131] PS2 mouse bios emulation (c2woody) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1720 --- include/mouse.h | 9 +++++ src/ints/bios.cpp | 58 ++++++++++++++++++++++++++----- src/ints/mouse.cpp | 86 ++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 138 insertions(+), 15 deletions(-) diff --git a/include/mouse.h b/include/mouse.h index 1851f5cf..4407b04c 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -16,9 +16,16 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: mouse.h,v 1.6 2004-03-14 13:39:45 qbix79 Exp $ */ + +#ifndef _MOUSE_H_ +#define _MOUSE_H_ + void Mouse_ShowCursor(void); void Mouse_HideCursor(void); +void Mouse_SetPS2State(bool use); +void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs); void Mouse_CursorMoved(float x,float y); void Mouse_CursorSet(float x,float y); @@ -28,3 +35,5 @@ void Mouse_ButtonReleased(Bit8u button); void Mouse_AutoLock(bool enable); void Mouse_NewVideoMode(void); +#endif + diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 65e5ecc6..4c6e2137 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.29 2004-02-29 21:55:49 harekiet Exp $ */ +/* $Id: bios.cpp,v 1.30 2004-03-14 13:39:45 qbix79 Exp $ */ #include #include "dosbox.h" @@ -29,6 +29,7 @@ #include "pic.h" #include "joystick.h" #include "dos_inc.h" +#include "mouse.h" static Bitu call_int1a,call_int11,call_int8,call_int17,call_int12,call_int15,call_int1c; static Bitu call_int1,call_int70; @@ -303,12 +304,50 @@ static Bitu INT15_Handler(void) { CALLBACK_SCF(true); break; case 0xc2: /* BIOS PS2 Pointing Device Support */ - case 0xc4: /* BIOS POS Programma option Select */ - /* - Damn programs should use the mouse drivers - So let's fail these calls - */ - LOG(LOG_BIOS,LOG_NORMAL)("INT15:Function %X called,bios mouse not supported",reg_ah); + switch (reg_al) { + case 0x00: // enable/disable + if (reg_bh==0) { // disable + Mouse_SetPS2State(false); + reg_ah=0; + CALLBACK_SCF(false); + } else if (reg_bh==0x01) { //enable + Mouse_SetPS2State(true); + reg_ah=0; + CALLBACK_SCF(false); + } else CALLBACK_SCF(true); + break; + case 0x01: // reset + reg_bx=0x00aa; // mouse + CALLBACK_SCF(false); + break; + case 0x02: // set sampling rate + CALLBACK_SCF(false); + break; + case 0x03: // set resolution + CALLBACK_SCF(false); + break; + case 0x04: // get type + reg_bh=0; // ID + CALLBACK_SCF(false); + break; + case 0x05: // initialize + CALLBACK_SCF(false); + break; + case 0x06: // extended commands + if ((reg_bh==0x01) || (reg_bh==0x02)) CALLBACK_SCF(false); + else CALLBACK_SCF(true); + break; + case 0x07: // set callback + Mouse_ChangePS2Callback(SegValue(es),reg_bx); + CALLBACK_SCF(false); + break; + default: + CALLBACK_SCF(true); + break; + } + break; + case 0xc4: /* BIOS POS Programm option Select */ + LOG(LOG_BIOS,LOG_NORMAL)("INT15:Function %X called, bios mouse not supported",reg_ah); CALLBACK_SCF(true); break; default: @@ -398,19 +437,20 @@ void BIOS_Init(Section* sec) { /* Setup equipment list */ Bitu config=0x4400; //1 Floppy, 2 serial and 1 parrallel #if (C_FPU) - config|=0x2; + config|=0x2; //FPU #endif switch (machine) { case MCH_HERC: config|=0x30; //Startup monochrome break; case MCH_CGA: case MCH_TANDY: - config|=0x20; //STartup 80x25 color + config|=0x20; //Startup 80x25 color break; default: config|=0; //EGA VGA break; } + config |= 0x04; // PS2 mouse mem_writew(BIOS_CONFIGURATION,config); /* Setup extended memory size */ IO_Write(0x70,0x30); diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index b5eea37d..d4ef2b09 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.32 2004-02-29 22:22:56 harekiet Exp $ */ +/* $Id: mouse.cpp,v 1.33 2004-03-14 13:39:45 qbix79 Exp $ */ #include #include "dosbox.h" @@ -28,9 +28,71 @@ #include "inout.h" #include "int10.h" #include "bios.h" +#include "cpu.h" static Bitu call_int33,call_int74; +static Bit16u ps2cbseg, ps2cbofs; +static bool useps2callback; +static Bit16u call_ps2; +static RealPt ps2_callback; +static Bit16s oldmouseX, oldmouseY; + +void Mouse_SetPS2State(bool use) { + if ((SegValue(es)!=0) && (reg_bx!=0)) useps2callback = use; + else useps2callback = false; + Mouse_AutoLock(useps2callback); +} + +void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs) { + if ((pseg==0) && (pofs==0)) useps2callback = false; + else useps2callback = true; + ps2cbseg = pseg; + ps2cbofs = pofs; + Mouse_AutoLock(useps2callback); +} + +void DoPS2Callback(Bit16u data, Bit16s mouseX, Bit16s mouseY) { + if (useps2callback) { + Bit16u mdat = (data & 0x03) | 0x08; + Bit16s xdiff = mouseX-oldmouseX; + Bit16s ydiff = oldmouseY-mouseY; + oldmouseX = mouseX; + oldmouseY = mouseY; + + if ((xdiff>0xff) || (xdiff<-0xff)) mdat |= 0x40; // x overflow + if ((ydiff>0xff) || (ydiff<-0xff)) mdat |= 0x80; // y overflow + + xdiff %= 256; + ydiff %= 256; + + if (xdiff<0) { + xdiff = (0x100+xdiff); + mdat |= 0x10; + } + if (ydiff<0) { + ydiff = (0x100+ydiff); + mdat |= 0x20; + } + + CPU_Push16((Bit16u)mdat); + CPU_Push16((Bit16u)(xdiff % 256)); + CPU_Push16((Bit16u)(ydiff % 256)); + CPU_Push16((Bit16u)0); + + CPU_Push16(RealSeg(ps2_callback)); + CPU_Push16(RealOff(ps2_callback)); + SegSet16(cs, ps2cbseg); + reg_ip = ps2cbofs; + } +} + +Bitu PS2_Handler(void) { + reg_sp += 8; // remove the 4 words + return CBRET_NONE; +} + + // forward void WriteMouseIntVector(void); @@ -352,11 +414,16 @@ void Mouse_CursorMoved(float x,float y) { mouse.mickey_y += dy; mouse.x += dx; - if (mouse.x>mouse.max_x) mouse.x=mouse.max_x; - if (mouse.xmouse.max_y) mouse.y=mouse.max_y; - if (mouse.y mouse.max_x) mouse.x = mouse.max_x; + if (mouse.x < mouse.min_x) mouse.x = mouse.min_x; + if (mouse.y > mouse.max_y) mouse.y = mouse.max_y; + if (mouse.y < mouse.min_y) mouse.y = mouse.min_y; + } + Mouse_AddEvent(MOUSE_MOVED); DrawCursor(); } @@ -762,6 +829,7 @@ static Bitu INT74_Handler(void) { SegSet16(ds,oldds); SegSet16(es,oldes); SegSet16(ss,oldss); // Save segments } + DoPS2Callback(mouse.event_queue[mouse.events].buttons, POS_X, POS_Y); } IO_Write(0xa0,0x20); IO_Write(0x20,0x20); @@ -783,7 +851,7 @@ void CreateMouseCallback(void) { // Create callback call_int33=CALLBACK_Allocate(); - CALLBACK_Setup(call_int33,&INT33_Handler,CB_IRET); + CALLBACK_Setup(call_int33,&INT33_Handler,CB_IRET,"Mouse"); // Create a mouse vector with weird address // for strange mouse detection routines in Sim City & Wasteland Bit16u ofs = call_int33<<4; @@ -809,6 +877,12 @@ void MOUSE_Init(Section* sec) { real_writed(0,((0x8+MOUSE_IRQ)<<2),CALLBACK_RealPointer(call_int74)); } + useps2callback = false; + + call_ps2=CALLBACK_Allocate(); + CALLBACK_Setup(call_ps2,&PS2_Handler,CB_IRET,"ps2 bios callback"); + ps2_callback=CALLBACK_RealPointer(call_ps2); + memset(&mouse,0,sizeof(mouse)); mouse_reset_hardware(); mouse_reset(); From 83c1c025ab40afa190dc6960f95dfa6ed61a46b1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 14 Mar 2004 16:21:10 +0000 Subject: [PATCH 1639/4131] Added some HMA queries Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1721 --- src/dos/dos_misc.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index c559f037..afd5df77 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: dos_misc.cpp,v 1.9 2004-03-14 16:21:10 qbix79 Exp $ */ + #include "dosbox.h" #include "callback.h" #include "mem.h" @@ -60,10 +62,17 @@ static bool DOS_MultiplexFunctions(void) { //TODO Maybe do some idling but could screw up other systems :) reg_al=0; return true; - case 0x1689: /* Kernel IDLE CALL */ - reg_al=0; //Likely. Please check !!!!!!!!!!!!!!! - return true; + case 0x1689: /* Kernel IDLE CALL */ case 0x168f: /* Close awareness crap */ + /* Removing warning */ + return true; + case 0x4a01: /* Query free hma space */ + case 0x4a02: /* ALLOCATE HMA SPACE */ + LOG(LOG_DOSMISC,LOG_WARN)("INT 2f:4a HMA. DOSBox reports none available."); + reg_bx=0; //number of bytes available in HMA or amount succesfully allocated + //ESDI=ffff:ffff Location of HMA/Allocated memory + SegSet16(es,0xffff); + reg_di=0xffff; return true; } @@ -74,12 +83,12 @@ void DOS_SetupMisc(void) { /* Setup the dos multiplex interrupt */ first_multiplex=0; call_int2f=CALLBACK_Allocate(); - CALLBACK_Setup(call_int2f,&INT2F_Handler,CB_IRET); + CALLBACK_Setup(call_int2f,&INT2F_Handler,CB_IRET,"DOS Int 2f"); RealSetVec(0x2f,CALLBACK_RealPointer(call_int2f)); DOS_AddMultiplexHandler(DOS_MultiplexFunctions); /* Setup the dos network interrupt */ call_int2a=CALLBACK_Allocate(); CALLBACK_Setup(call_int2a,&INT2A_Handler,CB_IRET); - RealSetVec(0x2A,CALLBACK_RealPointer(call_int2a)); + RealSetVec(0x2A,CALLBACK_RealPointer(call_int2a,"DOS Int 2a")); }; From c462ea28c3369aa41c9a022cf7b25cc34774f4e4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 14 Mar 2004 16:54:21 +0000 Subject: [PATCH 1640/4131] Added basic, but real int 29 support (pkzip2.X seems to want it) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1722 --- src/dos/dos.cpp | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index aae802b5..82ec9481 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.68 2004-03-12 14:21:33 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.69 2004-03-14 16:54:21 qbix79 Exp $ */ #include #include @@ -929,8 +929,14 @@ static Bitu DOS_28Handler(void) { } static Bitu DOS_29Handler(void) { - LOG(LOG_DOSMISC,LOG_ERROR)("int 29 called"); - return CBRET_NONE; + static bool int29warn=false; + if(!int29warn) { + LOG(LOG_DOSMISC,LOG_WARN)("Int 29 called. Redirecting to int 10:0x0e"); + int29warn=true; + } + reg_ah=0x0e; + CALLBACK_RunRealInt(0x10); + return CBRET_NONE; } static Bitu DOS_CaseMapFunc(void) { @@ -946,32 +952,32 @@ void DOS_ShutDown(Section* sec) void DOS_Init(Section* sec) { call_20=CALLBACK_Allocate(); - CALLBACK_Setup(call_20,DOS_20Handler,CB_IRET); + CALLBACK_Setup(call_20,DOS_20Handler,CB_IRET,"DOS Int 20"); RealSetVec(0x20,CALLBACK_RealPointer(call_20)); call_21=CALLBACK_Allocate(); - CALLBACK_Setup(call_21,DOS_21Handler,CB_IRET_STI); + CALLBACK_Setup(call_21,DOS_21Handler,CB_IRET_STI,"DOS Int 21"); RealSetVec(0x21,CALLBACK_RealPointer(call_21)); call_25=CALLBACK_Allocate(); - CALLBACK_Setup(call_25,DOS_25Handler,CB_RETF); + CALLBACK_Setup(call_25,DOS_25Handler,CB_RETF,"DOS Int 25"); RealSetVec(0x25,CALLBACK_RealPointer(call_25)); call_26=CALLBACK_Allocate(); - CALLBACK_Setup(call_26,DOS_26Handler,CB_RETF); + CALLBACK_Setup(call_26,DOS_26Handler,CB_RETF,"DOS Int 26"); RealSetVec(0x26,CALLBACK_RealPointer(call_26)); call_27=CALLBACK_Allocate(); - CALLBACK_Setup(call_27,DOS_27Handler,CB_IRET); + CALLBACK_Setup(call_27,DOS_27Handler,CB_IRET,"DOS Int 27"); RealSetVec(0x27,CALLBACK_RealPointer(call_27)); - call_28=CALLBACK_Allocate(); - CALLBACK_Setup(call_28,DOS_28Handler,CB_IRET); - RealSetVec(0x28,CALLBACK_RealPointer(call_28)); + call_28=CALLBACK_Allocate(); + CALLBACK_Setup(call_28,DOS_28Handler,CB_IRET,"DOS Int 28"); + RealSetVec(0x28,CALLBACK_RealPointer(call_28)); - call_29=CALLBACK_Allocate(); - CALLBACK_Setup(call_29,DOS_29Handler,CB_IRET); - RealSetVec(0x29,CALLBACK_RealPointer(call_29)); + call_29=CALLBACK_Allocate(); + CALLBACK_Setup(call_29,DOS_29Handler,CB_IRET,"CON Output Int 29"); + RealSetVec(0x29,CALLBACK_RealPointer(call_29)); DOS_SetupFiles(); /* Setup system File tables */ DOS_SetupDevices(); /* Setup dos devices */ @@ -999,6 +1005,6 @@ void DOS_Init(Section* sec) { /* case map routine INT 0x21 0x38 */ call_casemap = CALLBACK_Allocate(); - CALLBACK_Setup(call_casemap,DOS_CaseMapFunc,CB_RETF); + CALLBACK_Setup(call_casemap,DOS_CaseMapFunc,CB_RETF,"DOS CaseMap"); } From db45414323069f8c4cf67e2f86ad81fa9d854469 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 14 Mar 2004 19:05:41 +0000 Subject: [PATCH 1641/4131] Support s3 pixel format register, 8bpp only for now Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1723 --- include/vga.h | 1 + src/hardware/vga.cpp | 7 ++++++- src/hardware/vga_crtc.cpp | 17 +++++++++++++++++ src/hardware/vga_draw.cpp | 4 +++- 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/include/vga.h b/include/vga.h index ad35b712..7623504e 100644 --- a/include/vga.h +++ b/include/vga.h @@ -144,6 +144,7 @@ typedef struct { Bit8u ex_hor_overflow; Bit8u ex_ver_overflow; Bit16u la_window; + Bit8u misc_control_2; struct { Bit8u r; Bit8u n; diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index bf06e9e3..536af5e5 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -49,8 +49,13 @@ void VGA_SetMode(VGAModes mode) { } void VGA_DetermineMode(void) { + /* Test for VGA output active or direct color modes */ + if (vga.s3.misc_control_2 & 0xf0) { + switch (vga.s3.misc_control_2 >> 4) { + case 1:VGA_SetMode(M_LIN8);break; + } /* Test for graphics or alphanumeric mode */ - if (vga.attr.mode_control & 1) { + } else if (vga.attr.mode_control & 1) { if (!(vga.crtc.mode_control & 0x1)) { if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4); else VGA_SetMode(M_CGA2); diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index d9f0b1fb..615b6bab 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -478,6 +478,21 @@ void write_p3d5_vga(Bit32u port,Bit8u val) { (3d4h index 18h). Bit 8 is in 3d4h index 7 bit 4 and bit 9 in 3d4h index 9 bit 6. */ + case 0x67: /* Extended Miscellaneous Control 2 */ + /* + 0 VCLK PHS. VCLK Phase With Respect to DCLK. If clear VLKC is inverted + DCLK, if set VCLK = DCLK. + 4-7 Pixel format. + 0 Mode 0: 8bit (1 pixel/VCLK) + 1 Mode 8: 8bit (2 pixels/VCLK) + 3 Mode 9: 15bit (1 pixel/VCLK) + 5 Mode 10: 16bit (1 pixel/VCLK) + 7 Mode 11: 24/32bit (2 VCLKs/pixel) + 13 (732/764) 32bit (1 pixel/VCLK) + */ + vga.s3.misc_control_2=val; + VGA_DetermineMode(); + break; case 0x69: /* Extended System Control 3 */ if (((vga.config.display_start & 0x1f0000)>>16) ^ (val & 0x1f)) { vga.config.display_start&=0xffff; @@ -590,6 +605,8 @@ Bit8u read_p3d5_vga(Bit32u port) { return vga.s3.ex_hor_overflow; case 0x5e: /* Extended Vertical Overflow */ return vga.s3.ex_ver_overflow; + case 0x67: /* Extended Miscellaneous Control 2 */ + return vga.s3.misc_control_2; case 0x69: /* Extended System Control 3 */ return (Bit8u)((vga.config.display_start & 0x1f0000)>>16); case 0x6a: /* Extended System Control 4 */ diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 85308500..5625f626 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -184,6 +184,7 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.address=(vga.draw.address*2); break; case M_CGA4:case M_CGA2:case M_CGA16: + case M_TANDY2:case M_TANDY4:case M_TANDY16: vga.draw.address=(vga.draw.address*2)&0x1fff; break; } @@ -324,9 +325,10 @@ void VGA_SetupDrawing(Bitu val) { break; case M_LIN8: scaleh*=vga.draw.font_height; + if (vga.crtc.maximum_scan_line&0x80) scaleh*=2; vga.draw.lines_scaled=scaleh; vga.draw.address_line_total=1; - width<<=3; + height/=scaleh;width<<=3; VGA_DrawLine=VGA_Draw_VGA_Line; break; case M_EGA16: From b3b1a0b003c4554bcb372b78a0b3c77183a522da Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 14 Mar 2004 19:07:10 +0000 Subject: [PATCH 1642/4131] Support s3 pixel format register, 8bpp only for now Clear videomemory directly Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1724 --- src/ints/int10_modes.cpp | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 8225ab85..0d3230f8 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -31,16 +31,16 @@ VideoModeBlock ModeList_VGA[]={ { 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,1 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, { 0x011 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,449 ,80 ,480 ,0 },/*was EGA_2 */ { 0x012 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, -{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,0 }, { 0x100 ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, { 0x101 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, { 0x103 ,M_LIN8 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, -{ 0x150 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , 0}, -{ 0x151 ,M_LIN8 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , 0}, -{ 0x152 ,M_LIN8 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , 0 }, -{ 0x153 ,M_LIN8 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , 0 }, +{ 0x150 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _EGA_LINE_DOUBLE }, +{ 0x151 ,M_LIN8 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _EGA_LINE_DOUBLE }, +{ 0x152 ,M_LIN8 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , 0 }, +{ 0x153 ,M_LIN8 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , 0 }, {0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, }; @@ -167,10 +167,8 @@ static void FinishSetMode(bool clearmem) { case M_EGA16: case M_VGA: case M_LIN8: - /* Just clear the whole 2 mb of memory */ - for (i=0;i<2*1024*1024/4;i++) { - mem_writed(S3_LFB_BASE+i*4,0); - } + /* Hack we just acess the memory directly */ + memset(&vga.mem,0,sizeof(vga.mem)); } } /* Setup the BIOS */ @@ -509,9 +507,20 @@ bool INT10_SetVideoMode(Bitu mode) { Bitu clock=CurMode->vtotal*8*CurMode->htotal*70; VGA_SetClock(3,clock/1000); } + Bit8u misc_control_2; + /* Setup Pixel format */ + switch (CurMode->type) { + case M_LIN8: + if (CurMode->swidth < 640) misc_control_2=0x0; //Use single pixel mode,M_VGA then + else misc_control_2=0x10; + break; + default: + misc_control_2=0x0; + break; + } + IO_WriteB(0x3d4,0x67);IO_WriteB(0x3d5,misc_control_2); /* Write Misc Output */ IO_Write(0x3c2,misc_output); - /* Program Graphics controller */ Bit8u gfx_data[GFX_REGS]; memset(gfx_data,0,GFX_REGS); @@ -668,12 +677,12 @@ dac_text16: IO_Write(crtc_base,0x58);IO_Write(crtc_base+1,0x3); //Enable 8 mb of linear addressing IO_Write(crtc_base,0x38);IO_Write(crtc_base+1,0x48); //Register lock 1 IO_Write(crtc_base,0x39);IO_Write(crtc_base+1,0xa5); //Register lock 2 - + + FinishSetMode(clearmem); /* Load text mode font */ if (CurMode->type==M_TEXT) { INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); } - FinishSetMode(clearmem); return true; } From 0ec286c9d0064a4ee3c604ec0e2ba2d77eeaacc3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 14 Mar 2004 19:41:04 +0000 Subject: [PATCH 1643/4131] typo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1725 --- src/dos/dos_misc.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index afd5df77..eebf2348 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_misc.cpp,v 1.9 2004-03-14 16:21:10 qbix79 Exp $ */ +/* $Id: dos_misc.cpp,v 1.10 2004-03-14 19:41:04 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" @@ -88,7 +88,7 @@ void DOS_SetupMisc(void) { DOS_AddMultiplexHandler(DOS_MultiplexFunctions); /* Setup the dos network interrupt */ call_int2a=CALLBACK_Allocate(); - CALLBACK_Setup(call_int2a,&INT2A_Handler,CB_IRET); - RealSetVec(0x2A,CALLBACK_RealPointer(call_int2a,"DOS Int 2a")); + CALLBACK_Setup(call_int2a,&INT2A_Handler,CB_IRET,"DOS Int 2a"); + RealSetVec(0x2A,CALLBACK_RealPointer(call_int2a)); }; From 12e1f8a18bc57255e3acc79a5736e1478e3949cb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 15 Mar 2004 13:58:27 +0000 Subject: [PATCH 1644/4131] Changed OPL and CMS functions to also use the soundblaster base Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1726 --- include/hardware.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/hardware.h b/include/hardware.h index 17bc85a5..af8be44a 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -24,8 +24,8 @@ enum OPL_Mode { OPL_none,OPL_cms,OPL_opl2,OPL_dualopl2,OPL_opl3 }; -void OPL_Init(Section* sec,OPL_Mode,Bitu rate); -void CMS_Init(Section* sec,Bitu rate); +void OPL_Init(Section* sec,Bitu base,OPL_Mode mode,Bitu rate); +void CMS_Init(Section* sec,Bitu base,Bitu rate); #endif From 8b3fd8a4aeddaf00e61aa5532e17a54be3636ec3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 15 Mar 2004 14:54:09 +0000 Subject: [PATCH 1645/4131] New DMA routines Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1727 --- include/dma.h | 185 +++---------- src/hardware/dma.cpp | 603 ++++++++++++++----------------------------- 2 files changed, 233 insertions(+), 555 deletions(-) diff --git a/include/dma.h b/include/dma.h index 74079295..8e8328c3 100644 --- a/include/dma.h +++ b/include/dma.h @@ -16,180 +16,77 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dma.h,v 1.9 2004-01-10 14:03:33 qbix79 Exp $ */ +/* $Id: dma.h,v 1.10 2004-03-15 14:53:32 harekiet Exp $ */ #ifndef __DMA_H #define __DMA_H -#include "mem.h" +enum DMAEvent { + DMA_REACHED_TC, + DMA_MASKED, + DMA_UNMASKED, +}; -#define DMA_MODE_DEMAND 0 -#define DMA_MODE_SINGLE 1 -#define DMA_MODE_BLOCK 2 -#define DMA_MODE_CASCADE 3 - -#define DMA_BASEADDR 0 -#define DMA_TRANSCOUNT 1 -#define DMA_PAGEREG 2 - -#define DMA_CMDREG 0 -#define DMA_MODEREG 1 -#define DMA_CLEARREG 2 -#define DMA_DMACREG 3 -#define DMA_CLRMASKREG 4 -#define DMA_SINGLEREG 5 -#define DMA_WRITEALLREG 6 - -static Bit8u ChannelPorts [3][8] = { 0x00, 0x02, 0x04, 0x06, 0xff, 0xc4, 0xc8, 0xcc, - 0x01, 0x03, 0x05, 0x07, 0xff, 0xc6, 0xca, 0xce, - 0x87, 0x83, 0x81, 0x82, 0xff, 0x8b, 0x89, 0x8a }; - -static Bit8u ControllerPorts [2][7] = { 0x08, 0x0b, 0x0c, 0x0d, 0x0e, 0x0a, 0xf, - 0xd0, 0xd6, 0xd8, 0xda, 0xdc, 0xd4, 0xde }; - - -typedef void (* DMA_EnableCallBack)(bool enable); - -typedef void (* DMA_NewCallBack)(void *useChannel, bool tc); - -void DMA_SetEnableCallBack(Bitu channel,DMA_EnableCallBack callback); - -void DMA_CheckEnabled(void * usechan); - -Bitu DMA_8_Read(Bitu channel,Bit8u * buffer,Bitu count); -Bitu DMA_8_Write(Bitu dmachan,Bit8u * buffer,Bitu count); - -Bitu DMA_16_Read(Bitu channel,Bit8u * buffer,Bitu count); -Bitu DMA_16_Write(Bitu dmachan,Bit8u * buffer,Bitu count); - -extern Bit8u read_dmaB(Bit32u port); -extern Bit16u read_dmaW(Bit32u port); - -extern void write_dmaB(Bit32u port,Bit8u val); -extern void write_dmaW(Bit32u port,Bit16u val); +class DmaChannel; +typedef void (* DMA_CallBack)(DmaChannel * chan,DMAEvent event); class DmaController { public: bool flipflop; Bit8u ctrlnum; + Bit8u chanbase; public: - DmaController(Bit8u num) { - int i; - for(i=0;i<7;i++) { - IO_RegisterReadBHandler(ControllerPorts[num][i],read_dmaB); - IO_RegisterReadWHandler(ControllerPorts[num][i],read_dmaW); - - IO_RegisterWriteBHandler(ControllerPorts[num][i],write_dmaB); - IO_RegisterWriteWHandler(ControllerPorts[num][i],write_dmaW); - } - flipflop = true; + flipflop = false; ctrlnum = num; + chanbase = num * 4; } - - Bit16u portRead(Bit32u port, bool eightbit); - void portWrite(Bit32u port, Bit16u val, bool eightbit); - }; - - class DmaChannel { public: - - Bit8u channum; + Bit32u pagebase; Bit16u baseaddr; - Bit16u current_addr; - Bit16u pageaddr; - PhysPt physaddr; - PhysPt curraddr; - Bit32s transcnt; - Bit32s currcnt; - DmaController *myController; - bool DMA16; - bool addr_changed; -public: - Bit8u dmamode; - bool dir; + Bit16u curraddr; + Bit16u basecnt; + Bit16u currcnt; + Bit8u channum; + Bit8u pagenum; + Bit8u DMA16; + bool increment; bool autoinit; Bit8u trantype; bool masked; - bool enabled; - DMA_EnableCallBack enable_callback; - DMA_NewCallBack newcallback; + bool tcount; + DMA_CallBack callback; - DmaChannel(Bit8u num, DmaController *useController, bool sb) { - int i; - masked = true; - enabled = false; - enable_callback = NULL; - newcallback = NULL; - if(num == 4) return; - addr_changed=false; - - for(i=0;i<3;i++) { - IO_RegisterReadBHandler(ChannelPorts[i][num],read_dmaB); - IO_RegisterReadWHandler(ChannelPorts[i][num],read_dmaW); - - IO_RegisterWriteBHandler(ChannelPorts[i][num],write_dmaB); - IO_RegisterWriteWHandler(ChannelPorts[i][num],write_dmaW); - } - myController = useController; - channum = num; - DMA16 = sb; - baseaddr = 0; - pageaddr = 0; - physaddr = 0; - curraddr = 0; - transcnt = 0; - currcnt = 0; - dir = false; - autoinit = false; + DmaChannel(Bit8u num, bool dma16); + void DoCallBack(DMAEvent event) { + if (callback) (*callback)(this,event); } - - void RegisterCallback(DMA_NewCallBack useCallBack) { newcallback = useCallBack; } - - void reset(void) { - addr_changed=false; - curraddr = physaddr; - currcnt = transcnt+1; - current_addr = baseaddr; - //LOG(LOG_DMA,LOG_NORMAL)("Setup at address %X:%X count %X",pageaddr,baseaddr,currcnt); + void SetMask(bool _mask) { + masked=_mask; + DoCallBack(masked ? DMA_MASKED : DMA_UNMASKED); } - - void MakeCallback(bool tc) { - if (newcallback != NULL) { - if(tc) { - (*newcallback)(this, true); - } else { - if ((enabled) && (!masked) && (transcnt!=0)) { - (*newcallback)(this, false); - } - } - - } + void Register_Callback(DMA_CallBack _cb) { + callback = _cb; + SetMask(masked); } - - Bit32u Read(Bit32s requestsize, Bit8u * buffer); - - Bit32u Write(Bit32s requestsize, Bit8u * buffer); - - void calcPhys(void); - - Bit16u portRead(Bit32u port, bool eightbit); - - void portWrite(Bit32u port, Bit16u val, bool eightbit); - - // Notify channel when mask changes - void Notify(void); - + void ReachedTC(void) { + tcount=true; + DoCallBack(DMA_REACHED_TC); + } + void SetPage(Bit8u val) { + pagenum=val; + pagebase=(pagenum >> DMA16) << (16+DMA16); + } + Bitu Read(Bitu size, Bit8u * buffer); + Bitu Write(Bitu size, Bit8u * buffer); }; - extern DmaChannel *DmaChannels[8]; extern DmaController *DmaControllers[2]; - - #endif + diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index e951d8ef..dc0a8d56 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -30,445 +30,226 @@ DmaChannel *DmaChannels[8]; DmaController *DmaControllers[2]; - -Bit16u DmaController::portRead(Bit32u port, bool eightbit) { - LOG_MSG("Reading DMA controller at %x", port); - return 0xffff; +static void DMA_WriteControllerReg(DmaController * cont,Bitu reg,Bitu val,Bitu len) { + DmaChannel * chan;Bitu i; + Bitu base=cont->chanbase; + switch (reg) { + case 0x0:case 0x2:case 0x4:case 0x6: + chan=DmaChannels[base+(reg >> 1)]; + cont->flipflop=!cont->flipflop; + if (cont->flipflop) { + chan->baseaddr=(chan->baseaddr&0xff00)|val; + chan->curraddr=(chan->curraddr&0xff00)|val; + } else { + chan->baseaddr=(chan->baseaddr&0x00ff)|(val << 8); + chan->curraddr=(chan->curraddr&0x00ff)|(val << 8); + } + break; + case 0x1:case 0x3:case 0x5:case 0x7: + chan=DmaChannels[base+(reg >> 1)]; + cont->flipflop=!cont->flipflop; + if (cont->flipflop) { + chan->basecnt=(chan->basecnt&0xff00)|val; + chan->currcnt=(chan->currcnt&0xff00)|val; + } else { + chan->basecnt=(chan->basecnt&0x00ff)|(val << 8); + chan->currcnt=(chan->currcnt&0x00ff)|(val << 8); + } + break; + case 0x8: /* Comand reg not used */ + break; + case 0x9: /* Request registers, memory to memory */ + //TODO Warning? + break; + case 0xa: /* Mask Register */ + chan=DmaChannels[base+(val & 3 )]; + chan->SetMask((val & 0x4)>0); + break; + case 0xb: /* Mode Register */ + chan=DmaChannels[base+(val & 3 )]; + chan->autoinit=(val & 0x10) > 0; + chan->increment=(val & 0x20) > 0; + //TODO Maybe other bits? + break; + case 0xc: /* Clear Flip/Flip */ + cont->flipflop=false; + break; + case 0xd: /* Master Clear/Reset */ + for (i=0;i<4;i++) { + DmaChannels[base+i]->SetMask(true); + DmaChannels[base+i]->tcount=false; + } + cont->flipflop=false; + break; + case 0xe: /* Clear Mask register */ + for (i=0;i<4;i++) { + DmaChannels[base+i]->SetMask(false); + } + break; + case 0xf: /* Multiple Mask register */ + for (i=0;i<4;i++) { + DmaChannels[base+i]->SetMask(val & 1); + val>>=1; + } + break; + } } -void DmaController::portWrite(Bit32u port, Bit16u val, bool eightbit) { - bool found; - found = false; - if(port == ControllerPorts[ctrlnum][DMA_CLRMASKREG]) { - found = true; - flipflop = true; - // Disable DMA requests - // Clear command and status registers - } - if(port == ControllerPorts[ctrlnum][DMA_SINGLEREG]) { - found = true; - int dmachan; - dmachan = (ctrlnum * 2) + (val & 0x3); - DmaChannels[dmachan]->masked = ((val & 0x4) == 0x4); - DmaChannels[dmachan]->Notify(); - } - if(port == ControllerPorts[ctrlnum][DMA_WRITEALLREG]) { - found = true; - int dmachan,i,r; - dmachan = (ctrlnum * 2); - r = 0; - for(i=dmachan;imasked = (((val >> r) & 0x1) == 0x1); - DmaChannels[i]->Notify(); - r++; +static Bitu DMA_ReadControllerReg(DmaController * cont,Bitu reg,Bitu len) { + DmaChannel * chan;Bitu i,ret; + Bitu base=cont->chanbase; + switch (reg) { + case 0x0:case 0x2:case 0x4:case 0x6: + chan=DmaChannels[base+(reg >> 1)]; + cont->flipflop=!cont->flipflop; + if (cont->flipflop) { + return chan->curraddr & 0xff; + } else { + return (chan->curraddr >> 8) & 0xff; } - + case 0x1:case 0x3:case 0x5:case 0x7: + chan=DmaChannels[base+(reg >> 1)]; + cont->flipflop=!cont->flipflop; + if (cont->flipflop) { + return chan->currcnt & 0xff; + } else { + return (chan->currcnt >> 8) & 0xff; + } + case 0x8: + ret=0; + for (i=0;i<4;i++) { + chan=DmaChannels[base+i]; + if (chan->tcount) ret|=1 << i; + chan->tcount=false; + if (chan->callback) ret|=1 << (i+4); + } + return ret; + default: + LOG_MSG("Trying to read undefined DMA Red %x",reg); } - if(port == ControllerPorts[ctrlnum][DMA_CLEARREG]) { - found = true; - flipflop = true; - } - if(port == ControllerPorts[ctrlnum][DMA_MODEREG]) { - found = true; - int dmachan; - dmachan = (ctrlnum * 2) + (val & 0x3); - DmaChannels[dmachan]->trantype = (val >> 2) & 0x3; - DmaChannels[dmachan]->autoinit = ((val & 0x10) == 0x10); - DmaChannels[dmachan]->dir = ((val & 0x20) == 0x20); - DmaChannels[dmachan]->dmamode = (val >> 6) & 0x3; - DmaChannels[dmachan]->Notify(); - } - if(!found) LOG_MSG("Write to DMA port %x with %x", port, val); - + return 0xffffffff; } -Bit32u DmaChannel::Read(Bit32s requestsize, Bit8u * buffer) { - Bit32s bytesread; - bytesread = 0; - if(autoinit) { - while(requestsize>0) { - if(currcnt>=requestsize) { - MEM_BlockRead(curraddr,buffer,requestsize); - curraddr+=requestsize; - buffer+=requestsize; - currcnt-=requestsize; - bytesread+=requestsize; - requestsize=0; - break; - } else { - MEM_BlockRead(curraddr,buffer,currcnt); - bytesread+=currcnt; - buffer+=currcnt; - requestsize-=currcnt; - reset(); - MakeCallback(true); - } - } - if(currcnt==0) { - reset(); - MakeCallback(true); - } - return bytesread; +static void DMA_Write_PortB(Bit32u port,Bit8u val) { + if (port<0x10) { + DMA_WriteControllerReg(DmaControllers[0],port,val,1); + } else if (port>=0xc0 && port <=0xdf) { + DMA_WriteControllerReg(DmaControllers[1],(port-0xc0) >> 1,val,1); + } else switch (port) { + case 0x81:DmaChannels[2]->SetPage(val);break; + case 0x82:DmaChannels[3]->SetPage(val);break; + case 0x83:DmaChannels[1]->SetPage(val);break; + case 0x89:DmaChannels[6]->SetPage(val);break; + case 0x8a:DmaChannels[7]->SetPage(val);break; + case 0x8b:DmaChannels[5]->SetPage(val);break; + } +} +static Bit8u DMA_Read_PortB(Bit32u port) { + if (port<0x10) { + return DMA_ReadControllerReg(DmaControllers[0],port,1); + } else if (port>=0xc0 && port <=0xdf) { + return DMA_ReadControllerReg(DmaControllers[1],(port-0xc0) >> 1,1); + } +} + +DmaChannel::DmaChannel(Bit8u num, bool dma16) { + masked = true; + callback = NULL; + if(num == 4) return; + channum = num; + DMA16 = dma16 ? 0x1 : 0x0; + pagenum = 0; + pagebase = 0; + baseaddr = 0; + curraddr = 0; + basecnt = 0; + currcnt = 0; + increment = true; + autoinit = false; + tcount = false; +} + +Bitu DmaChannel::Read(Bitu want, Bit8u * buffer) { + Bitu done=0; +again: + Bitu left=(currcnt+1); + if (want=requestsize) { - MEM_BlockRead(curraddr,buffer,requestsize); - curraddr+=requestsize; - buffer+=requestsize; - currcnt-=requestsize; - bytesread+=requestsize; + MEM_BlockRead(pagebase+(curraddr << DMA16),buffer,left << DMA16); + buffer+=left << DMA16; + want-=left; + done+=left; + ReachedTC(); + if (autoinit) { + currcnt=basecnt; + curraddr=baseaddr; + if (want) goto again; } else { - MEM_BlockRead(curraddr,buffer,currcnt); - buffer+=currcnt; - requestsize-=currcnt; - bytesread+=currcnt; - currcnt=0; + curraddr+=left; + currcnt=0xffff; + SetMask(true); } } - if(currcnt==0) MakeCallback(true); - return bytesread; + return done; } - -Bit32u DmaChannel::Write(Bit32s requestsize, Bit8u * buffer) { - Bit32s byteswrite; - byteswrite = 0; - if(autoinit) { - while(requestsize>0) { - if(currcnt>=requestsize) { - MEM_BlockWrite(curraddr,buffer,requestsize); - curraddr+=requestsize; - buffer+=requestsize; - currcnt-=requestsize; - byteswrite+=requestsize; - requestsize=0; - break; - } else { - MEM_BlockWrite(curraddr,buffer,currcnt); - byteswrite+=currcnt; - buffer+=currcnt; - requestsize-=currcnt; - reset(); - MakeCallback(true); - } - } - if(currcnt==0) { - reset(); - MakeCallback(true); - } - return byteswrite; - +Bitu DmaChannel::Write(Bitu want, Bit8u * buffer) { + Bitu done=0; +again: + Bitu left=(currcnt+1); + if (want=requestsize) { - MEM_BlockWrite(curraddr,buffer,requestsize); - curraddr+=requestsize; - buffer+=requestsize; - currcnt-=requestsize; - byteswrite+=requestsize; + MEM_BlockWrite(pagebase+(curraddr << DMA16),buffer,left << DMA16); + buffer+=left << DMA16; + want-=left; + done+=left; + ReachedTC(); + if (autoinit) { + currcnt=basecnt; + curraddr=baseaddr; + if (want) goto again; } else { - MEM_BlockWrite(curraddr,buffer,currcnt); - buffer+=currcnt; - requestsize-=currcnt; - byteswrite+=currcnt; - currcnt=0; + curraddr+=left; + currcnt=0xffff; + SetMask(true); } } - if(currcnt==0) MakeCallback(true); - return byteswrite; + return done; } -void DmaChannel::calcPhys(void) { - if (DMA16) { - physaddr = (baseaddr << 1) | ((pageaddr >> 1) << 17); - } else { - physaddr = (baseaddr) | (pageaddr << 16); - } - curraddr = physaddr; - current_addr = baseaddr; -} - -#define ff myController->flipflop - -Bit16u DmaChannel::portRead(Bit32u port, bool eightbit) { - if (port == ChannelPorts[DMA_BASEADDR][channum]) { - if(eightbit) { - if(ff) { - ff = !ff; - return current_addr & 0xff; - } else { - ff = !ff; - return current_addr >> 8; - } - } else { - return current_addr; - } - } - if (port == ChannelPorts[DMA_TRANSCOUNT][channum]) { - if(eightbit) { - if(ff) { - ff = !ff; - return (Bit8u)(currcnt-1); - } else { - ff = !ff; - return (Bit8u)((currcnt-1) >> 8); - } - } else { - return (Bit16u)currcnt; - } - } - if (port == ChannelPorts[DMA_PAGEREG][channum]) return pageaddr; - return 0xffff; -} - -void DmaChannel::portWrite(Bit32u port, Bit16u val, bool eightbit) { - if (port == ChannelPorts[DMA_BASEADDR][channum]) { - if(eightbit) { - if(ff) { - baseaddr = (baseaddr & 0xff00) | (Bit8u)val; - } else { - baseaddr = (baseaddr & 0xff) | (val << 8); - } - ff = !ff; - } else { - baseaddr = val; - } - calcPhys(); - addr_changed = true; - } - if (port == ChannelPorts[DMA_TRANSCOUNT][channum]) { - if(eightbit) { - if(ff) { - transcnt = (transcnt & 0xff00) | (Bit8u)val; - } else { - transcnt = (transcnt & 0xff) | (val << 8); - } - ff = !ff; - } else { - transcnt = val; - } - currcnt = transcnt+1; - addr_changed = true; - DMA_CheckEnabled(this); - MakeCallback(false); - - } - if (port == ChannelPorts[DMA_PAGEREG][channum]) { - pageaddr = val; - calcPhys(); - reset(); - } - -} - -#undef ff - -// Notify channel when mask changes -void DmaChannel::Notify(void) { - if(!masked) { - DMA_CheckEnabled(this); - MakeCallback(false); - } -} - - -static Bit16u readDMAPorts(Bit32u port, bool eightbit) { - int i,j; - - // Check for controller access - for(i=0;i<2;i++) { - for(j=0;j<7;j++) { - if(ControllerPorts[i][j] == port) { - return DmaControllers[i]->portRead(port, eightbit); - } - } - } - - // Check for DMA access - for(i=0;i<8;i++) { - for(j=0;j<3;j++) { - if(ChannelPorts[j][i] == port) { - return DmaChannels[i]->portRead(port, eightbit); - } - } - } - - LOG_MSG("Unmatched read port %x", port); - - return 0xffff; - -} - -static void writeDMAPorts(Bit32u port, Bit16u val, bool eightbit) { - int i,j; - - // Check for controller access - for(i=0;i<2;i++) { - for(j=0;j<7;j++) { - if(ControllerPorts[i][j] == port) { - DmaControllers[i]->portWrite(port,val,eightbit); - return; - } - } - } - - // Check for DMA access - for(i=0;i<8;i++) { - for(j=0;j<3;j++) { - if(ChannelPorts[j][i] == port) { - DmaChannels[i]->portWrite(port,val,eightbit); - return; - } - } - } - - LOG_MSG("Unmatched write port %x - val %x", port, val); - -} - -Bit8u read_dmaB(Bit32u port) { return (Bit8u)readDMAPorts(port,true); } - -Bit16u read_dmaW(Bit32u port) { return readDMAPorts(port,false); } - -void write_dmaB(Bit32u port,Bit8u val) { writeDMAPorts(port,val,true); } - -void write_dmaW(Bit32u port,Bit16u val) { writeDMAPorts(port,val,false); } - - -// Deprecated DMA read/write routines -- Keep compatibility with Sound Blaster -Bitu DMA_8_Read(Bitu dmachan,Bit8u * buffer,Bitu count) { - DmaChannel *chan=DmaChannels[dmachan]; - - if (chan->masked) return 0; - if (!count) return 0; - if (chan->addr_changed) chan->reset(); - - if (chan->currcnt>(Bits)count) { - MEM_BlockRead(chan->curraddr,buffer,count); - chan->curraddr+=count; - chan->current_addr+=count; - chan->currcnt-=count; - return count; - } else { - // Copy remaining piece of first buffer - MEM_BlockRead(chan->curraddr,buffer,chan->currcnt); - if (!chan->autoinit) { - // Set the end of counter bit - //dma[0].status_reg|=(1 << dmachan); - count=chan->currcnt; - chan->curraddr+=count; - chan->current_addr+=count; - chan->currcnt=0; - chan->enabled=false; - LOG(LOG_DMA,LOG_NORMAL)("8-bit Channel %d reached terminal count",chan->channum); - return count; - } else { - buffer+=chan->currcnt; - Bitu left=count-(Bit16u)chan->currcnt; - // Autoinit reset the dma channel - chan->reset(); - // Copy the rest of the buffer - MEM_BlockRead(chan->curraddr,buffer,left); - chan->curraddr+=left; - chan->current_addr+=left; - chan->currcnt-=left; - return count; - } - } -} - -Bitu DMA_8_Write(Bitu dmachan,Bit8u * buffer,Bitu count) { - DmaChannel *chan=DmaChannels[dmachan]; - - if (chan->masked) return 0; - if (!count) return 0; - if (chan->currcnt>(Bits)count) { - MEM_BlockWrite(chan->curraddr,buffer,count); - chan->curraddr+=count; - chan->currcnt-=count; - return count; - } else { - // Copy remaining piece of first buffer - MEM_BlockWrite(chan->curraddr,buffer,chan->currcnt); - if (!chan->autoinit) { - // Set the end of counter bit - //dma[0].status_reg|=(1 << dmachan); - count=chan->currcnt; - chan->curraddr+=count;; - chan->currcnt=0; - return count; - } else { - buffer+=chan->currcnt; - Bitu left=count-(Bit16u)chan->currcnt; - // Autoinit reset the dma channel - chan->reset(); - // Copy the rest of the buffer - MEM_BlockWrite(chan->curraddr,buffer,left); - chan->curraddr+=left; - chan->currcnt-=left; - return count; - } - } -} - - -Bitu DMA_16_Read(Bitu dmachan,Bit8u * buffer,Bitu count) { - - return 0; -} - -Bitu DMA_16_Write(Bitu dmachan,Bit8u * buffer,Bitu count) { - - - return 0; -} - -void DMA_SetEnabled(void * usechan,bool enabled) { - DmaChannel * chan; - chan = (DmaChannel *)usechan; - - if (chan->enabled == enabled) return; - chan->enabled=enabled; - if (chan->enable_callback) (*chan->enable_callback)(enabled); -} - -void DMA_CheckEnabled(void * usechan) { - DmaChannel * chan; - chan = (DmaChannel *)usechan; - - bool enabled; - if (chan->masked) enabled=false; - else { - if (chan->autoinit) enabled=true; - else if (chan->currcnt) enabled=true; - else enabled=false; - } - DMA_SetEnabled(chan,enabled); -} - - -void DMA_SetEnableCallBack(Bitu channel,DMA_EnableCallBack callback) { - DmaChannel * chan; - chan = DmaChannels[channel]; - chan->enabled=false; - chan->enable_callback=callback; - DMA_CheckEnabled(chan); -} - void DMA_Init(Section* sec) { - Bitu i; - DmaControllers[0] = new DmaController(0); DmaControllers[1] = new DmaController(1); - for(i=0;i<4;i++) { - DmaChannels[i] = new DmaChannel(i,DmaControllers[0],false); + for(i=0;i<8;i++) { + DmaChannels[i] = new DmaChannel(i,i>=4); } - for(i=4;i<8;i++) { - DmaChannels[i] = new DmaChannel(i,DmaControllers[1],true); + for (i=0;i<0x10;i++) { + IO_RegisterWriteBHandler(i,DMA_Write_PortB); + IO_RegisterReadBHandler(i,DMA_Read_PortB); + if (machine==MCH_VGA) { + IO_RegisterWriteBHandler(0xc0+i*2,DMA_Write_PortB); + IO_RegisterReadBHandler(0xc0+i*2,DMA_Read_PortB); + } } + IO_RegisterWriteBHandler(0x81,DMA_Write_PortB); + IO_RegisterWriteBHandler(0x82,DMA_Write_PortB); + IO_RegisterWriteBHandler(0x83,DMA_Write_PortB); + IO_RegisterWriteBHandler(0x89,DMA_Write_PortB); + IO_RegisterWriteBHandler(0x8a,DMA_Write_PortB); + IO_RegisterWriteBHandler(0x8b,DMA_Write_PortB); } From d7cd5717d6725ba9aa887f3c24971083e0d0741a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 15 Mar 2004 14:54:48 +0000 Subject: [PATCH 1646/4131] Changes for new dma routines Changes for 16-bit register access Changes for 32-bit internal mixing Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1728 --- src/hardware/gus.cpp | 177 ++++++++++++++++++++----------------------- 1 file changed, 84 insertions(+), 93 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index b5a1e513..e4d19991 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -22,7 +22,6 @@ #include "mixer.h" #include "dma.h" #include "pic.h" -#include "hardware.h" #include "setup.h" #include "programs.h" #include "math.h" @@ -44,6 +43,8 @@ static Bit8u dmatable[6] = { 3, 1, 5, 5, 6, 7 }; static Bit8u GUSRam[1024*1024]; // 1024K of GUS Ram +Bit32s AutoAmp=1024; + struct GFGus { Bit8u gRegSelect; Bit16u gRegData; @@ -62,7 +63,7 @@ struct GFGus { Bit32s muperchan; - Bit16u timerReg; + Bit8u timerReg; struct GusTimer { Bit16u bytetimer; Bit32s countdown; @@ -99,8 +100,6 @@ struct GFGus { #define GUSFIFOSIZE 1024 -static void UseDMA(DmaChannel *useDMA); - struct IRQFifoEntry { Bit8u channum; bool WaveIRQ; @@ -112,6 +111,7 @@ struct IRQFifoDef { Bit16s stackpos; } IRQFifo; +static void GUS_DMA_Callback(DmaChannel * chan,DMAEvent event); // Routines to manage IRQ requests coming from the GUS static void pushIRQ(Bit8u channum, bool WaveIRQ, bool RampIRQ) { @@ -151,7 +151,7 @@ static void popIRQ(IRQFifoEntry * tmpentry) { // Returns a single 16-bit sample from the Gravis's RAM -INLINE Bit16s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { +static INLINE Bit16s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { Bit32u useAddr; Bit32u holdAddr; useAddr = CurAddr >> 9; @@ -164,10 +164,10 @@ INLINE Bit16s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { // Interpolate Bit8s b1 = (Bit8s)GUSRam[useAddr]; Bit8s b2 = (Bit8s)GUSRam[useAddr+1]; - Bit16s w1 = b1 << 7; - Bit16s w2 = b2 << 7; - Bit16s diff = w2 - w1; - return (Bit16s)(w1 + (((Bit32s)diff * (Bit32s)(CurAddr & 0x3fe)) >> 10)); + Bit32s w1 = b1 << 8; + Bit32s w2 = b2 << 8; + Bit32s diff = w2 - w1; + return (Bit16s)(w1+((diff*(CurAddr&511))>>9)); } } else { @@ -188,9 +188,8 @@ INLINE Bit16s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { // Interpolate Bit16s w1 = (Bit16s)((Bit16u)GUSRam[useAddr] | ((Bit16u)GUSRam[useAddr+1] << 8)); Bit16s w2 = (Bit16s)((Bit16u)GUSRam[useAddr+2] | ((Bit16u)GUSRam[useAddr+3] << 8)); - Bit16s diff = w2 - w1; - return (Bit16s)(w1 + (((Bit32s)diff * (Bit32s)((CurAddr) & 0x3fe)) >> 10)) >> 2; - + Bit32s diff = w2 - w1; + return (Bit16s)(w1+((diff*(CurAddr&511))>>9)); } } } @@ -377,7 +376,7 @@ public: if((voiceCont & 0x10) != 0) { dir = !dir; } else { - CurAddr = EndAddr; + CurAddr = EndAddr - (512-(CurAddr & 511)); } } else { @@ -404,7 +403,7 @@ public: if((voiceCont & 0x10) != 0) { dir = !dir; } else { - CurAddr = StartAddr; + CurAddr = StartAddr+(CurAddr & 511); } } else { @@ -561,7 +560,7 @@ static Bit16u ExecuteReadRegister(void) { myGUS.irq.DMATC = false; PIC_DeActivateIRQ(myGUS.irq1); - //LOG_MSG("Read sampling status, returned 0x%x", tmpreg); + //LOG_GUS("Read sampling status, returned 0x%x", tmpreg); return (Bit16u)(tmpreg << 8); case 0x80: // Channel voice control read register @@ -575,24 +574,24 @@ static Bit16u ExecuteReadRegister(void) { case 0x82: // Channel MSB address register if(curchan != NULL) { - return (curchan->StartAddr >> 16); + return (Bit16u)(curchan->StartAddr >> 16); } else return 0x0000; case 0x83: // Channel LSW address register if(curchan != NULL) { - return (curchan->StartAddr & 0xffff); + return (Bit16u)(curchan->StartAddr & 0xffff); } else return 0x0000; case 0x89: // Channel volume register if(curchan != NULL) { - return (curchan->CurVolume << 4); + return ((Bit16u)curchan->CurVolume << 4); } else return 0x0000; case 0x8a: // Channel MSB current address register if(curchan != NULL) { - return (curchan->CurAddr >> 16); + return (Bit16u)(curchan->CurAddr >> 16); } else return 0x0000; case 0x8b: // Channel LSW current address register if(curchan != NULL) { - return (curchan->CurAddr & 0xFFFF); + return (Bit16u)(curchan->CurAddr & 0xFFFF); } else return 0x0000; case 0x8d: // Channel volume control register if(curchan != NULL) { @@ -622,11 +621,11 @@ static Bit16u ExecuteReadRegister(void) { static void ExecuteGlobRegister(void) { int i; - //LOG_MSG("Access global register %x with %x", myGUS.gRegSelect, myGUS.gRegData); + //LOG_GUS("Access global register %x with %x", myGUS.gRegSelect, myGUS.gRegData); switch(myGUS.gRegSelect) { case 0x0: // Channel voice control register if(curchan != NULL) { - curchan->WriteVoiceCtrl((Bit8u)myGUS.gRegData); + curchan->WriteVoiceCtrl((Bit16u)myGUS.gRegData>>8); } break; case 0x1: // Channel frequency control register @@ -660,20 +659,20 @@ static void ExecuteGlobRegister(void) { break; case 0x6: // Channel volume ramp rate register if(curchan != NULL) { - Bit8u tmpdata = (Bit8u)myGUS.gRegData; + Bit8u tmpdata = (Bit16u)myGUS.gRegData>>8; curchan->VolRampRate = tmpdata; } break; case 0x7: // Channel volume ramp start register EEEEMMMM if(curchan != NULL) { - Bit8u tmpdata = (Bit8u)myGUS.gRegData; + Bit8u tmpdata = (Bit16u)myGUS.gRegData >> 8; curchan->VolRampStart = vol8bit[tmpdata]; curchan->VolRampStartOrg = tmpdata << 4; } break; case 0x8: // Channel volume ramp end register EEEEMMMM if(curchan != NULL) { - Bit8u tmpdata = (Bit8u)myGUS.gRegData; + Bit8u tmpdata = (Bit16u)myGUS.gRegData >> 8; curchan->VolRampEnd = vol8bit[tmpdata]; curchan->VolRampEndOrg = tmpdata << 4; } @@ -686,7 +685,8 @@ static void ExecuteGlobRegister(void) { break; case 0xA: // Channel MSB current address register if(curchan != NULL) { - curchan->CurAddr = (curchan->CurAddr & 0xFFFF) | ((Bit32u)myGUS.gRegData << 16); + Bit32u tmpaddr = ((Bit32u)myGUS.gRegData & 0x1fff) << 16; + curchan->CurAddr = (curchan->CurAddr & 0xFFFF) | tmpaddr; } break; case 0xB: // Channel LSW current address register @@ -696,73 +696,68 @@ static void ExecuteGlobRegister(void) { break; case 0xC: // Channel pan pot register if(curchan != NULL) { - curchan->WritePanPot((Bit8u)myGUS.gRegData); + curchan->WritePanPot((Bit16u)myGUS.gRegData>>8); } break; case 0xD: // Channel volume control register if(curchan != NULL) { - curchan->WriteVolControl((Bit8u)myGUS.gRegData); + curchan->WriteVolControl((Bit16u)myGUS.gRegData>>8); } break; case 0xE: // Set active channel register - myGUS.activechan = (myGUS.gRegData & 31) +1; - if(myGUS.activechan < 14) myGUS.activechan = 14; - if(myGUS.activechan > 32) myGUS.activechan = 32; + myGUS.activechan = (myGUS.gRegData>>8) & 63; + if(myGUS.activechan < 13) myGUS.activechan = 13; + if(myGUS.activechan > 31) myGUS.activechan = 31; MIXER_Enable(gus_chan,true); - myGUS.basefreq = (Bit32u)((float)1000000/(1.619695497*(float)myGUS.activechan)); + myGUS.basefreq = (Bit32u)((float)1000000/(1.619695497*(float)(myGUS.activechan+1))); float simple; - simple = (1.0 / (float)GUS_RATE) / 0.000001; + simple = (1.0f / (float)GUS_RATE) / 0.000001f; myGUS.mupersamp = (Bit32s)simple*1024; myGUS.muperchan = (Bit32s)((float)1.6 * (float)myGUS.activechan * 1024); LOG_GUS("GUS set to %d channels", myGUS.activechan); - for(i=0;iUpdateFreqCtrl(); } + for(i=0;i<=myGUS.activechan;i++) { if(guschan[i] != NULL) guschan[i]->UpdateFreqCtrl(); } break; case 0x10: // Undocumented register used in Fast Tracker 2 break; case 0x41: // Dma control register - myGUS.DMAControl = (Bit8u)myGUS.gRegData; - if ((myGUS.DMAControl & 0x1) != 0) { - //LOG_MSG("GUS request DMA transfer"); - if(DmaChannels[myGUS.dma1]->enabled) UseDMA(DmaChannels[myGUS.dma1]); - } + myGUS.DMAControl = (Bit8u)(myGUS.gRegData>>8); + DmaChannels[myGUS.dma1]->Register_Callback( + (myGUS.DMAControl & 0x1) ? GUS_DMA_Callback : 0); break; case 0x42: // Gravis DRAM DMA address register myGUS.dmaAddr = myGUS.gRegData; break; case 0x43: // MSB Peek/poke DRAM position - myGUS.gDramAddr = (0xff0000 & myGUS.gDramAddr) | ((Bit32u)myGUS.gRegData); break; case 0x44: // LSW Peek/poke DRAM position - myGUS.gDramAddr = (0xffff & myGUS.gDramAddr) | ((Bit32u)myGUS.gRegData) << 16; + myGUS.gDramAddr = (0xffff & myGUS.gDramAddr) | ((Bit32u)myGUS.gRegData>>8) << 16; break; case 0x45: // Timer control register. Identical in operation to Adlib's timer - myGUS.TimerControl = (Bit8u)myGUS.gRegData; + myGUS.TimerControl = (Bit8u)(myGUS.gRegData>>8); if((myGUS.TimerControl & 0x08) !=0) myGUS.timers[1].countdown = myGUS.timers[1].setting; if((myGUS.TimerControl & 0x04) !=0) myGUS.timers[0].countdown = myGUS.timers[0].setting; myGUS.irq.T1 = false; myGUS.irq.T2 = false; PIC_DeActivateIRQ(myGUS.irq1); break; - case 0x46: // Timer 1 control - myGUS.timers[0].bytetimer = (Bit8u)myGUS.gRegData; + myGUS.timers[0].bytetimer = (Bit8u)(myGUS.gRegData>>8); myGUS.timers[0].setting = ((Bit32s)0xff - (Bit32s)myGUS.timers[0].bytetimer) * ((Bit32s)80 << 10); myGUS.timers[0].countdown = myGUS.timers[0].setting; break; case 0x47: // Timer 2 control - myGUS.timers[1].bytetimer = (Bit8u)myGUS.gRegData; + myGUS.timers[1].bytetimer = (Bit8u)(myGUS.gRegData>>8); myGUS.timers[1].setting = ((Bit32s)0xff - (Bit32s)myGUS.timers[1].bytetimer) * ((Bit32s)360 << 10); myGUS.timers[1].countdown = myGUS.timers[1].setting; break; case 0x49: // DMA sampling control register - myGUS.SampControl = (Bit8u)myGUS.gRegData; - if ((myGUS.SampControl & 0x1) != 0) { - if(DmaChannels[myGUS.dma1]->enabled) UseDMA(DmaChannels[myGUS.dma1]); - } + myGUS.SampControl = (Bit8u)(myGUS.gRegData>>8); + DmaChannels[myGUS.dma1]->Register_Callback( + (myGUS.SampControl & 0x1) ? GUS_DMA_Callback : 0); break; case 0x4c: // GUS reset register GUSReset(); @@ -775,7 +770,6 @@ static void ExecuteGlobRegister(void) { static Bit16u read_gus16(Bit32u port) { - return ExecuteReadRegister(); } @@ -835,7 +829,6 @@ static Bit8u read_gus(Bit32u port) { static void write_gus(Bit32u port,Bit8u val) { - switch(port - GUS_BASE) { case 0x200: myGUS.mixControl = val; @@ -846,7 +839,6 @@ static void write_gus(Bit32u port,Bit8u val) { case 0x209: myGUS.timers[0].active = ((val & 0x1) > 0); myGUS.timers[1].active = ((val & 0x2) > 0); - break; case 0x20b: if((myGUS.mixControl & 0x40) != 0) { @@ -876,11 +868,11 @@ static void write_gus(Bit32u port,Bit8u val) { myGUS.gRegData = 0; break; case 0x304: - myGUS.gRegData = (0x00ff & myGUS.gRegData) | val << 8; + myGUS.gRegData = (0xff00 & myGUS.gRegData) | val; ExecuteGlobRegister(); break; case 0x305: - myGUS.gRegData = (0xff00 & myGUS.gRegData) | val; + myGUS.gRegData = (0x00ff & myGUS.gRegData) | val << 8; ExecuteGlobRegister(); break; @@ -891,51 +883,38 @@ static void write_gus(Bit32u port,Bit8u val) { LOG_GUS("Write GUS at port 0x%x with %x", port, val); break; } - - } -static void UseDMA(DmaChannel *useDMA) { - Bit32s dmaaddr = myGUS.dmaAddr << 4; +static void GUS_DMA_Callback(DmaChannel * chan,DMAEvent event) { + if (event!=DMA_UNMASKED) return; + Bitu dmaaddr = myGUS.dmaAddr << 4; if((myGUS.DMAControl & 0x2) == 0) { - //Write data into UltraSound - Bit32s comsize = useDMA->currcnt; - - useDMA->Read(useDMA->currcnt,&GUSRam[dmaaddr]); + Bitu read=chan->Read(chan->currcnt+1,&GUSRam[dmaaddr]); + //Check for 16 or 8bit channel + read*=(chan->DMA16+1); if((myGUS.DMAControl & 0x80) != 0) { //Invert the MSB to convert twos compliment form - - int i; + Bitu i; if((myGUS.DMAControl & 0x40) == 0) { // 8-bit data - for(i=dmaaddr;i<(dmaaddr+comsize);i++) GUSRam[i] ^= 0x80; + for(i=dmaaddr;i<(dmaaddr+read);i++) GUSRam[i] ^= 0x80; } else { // 16-bit data - for(i=dmaaddr+1;i<(dmaaddr+comsize-1);i+=2) GUSRam[i] ^= 0x80; + for(i=dmaaddr+1;i<(dmaaddr+read-1);i+=2) GUSRam[i] ^= 0x80; } } } else { //Read data out of UltraSound - useDMA->Write(useDMA->currcnt,&GUSRam[dmaaddr]); - + chan->Write(chan->currcnt+1,&GUSRam[dmaaddr]); } + /* Raise the TC irq if needed */ + if((myGUS.DMAControl & 0x20) != 0) { + myGUS.irq.DMATC = true; + PIC_ActivateIRQ(myGUS.irq1); + } + chan->Register_Callback(0); } -static void GUS_DMA_Callback(void *useChannel, bool tc) { - DmaChannel *myDMA; - myDMA = (DmaChannel *)useChannel; - - if(tc) { - if((myGUS.DMAControl & 0x20) != 0) { - myGUS.irq.DMATC = true; - PIC_ActivateIRQ(myGUS.irq2); - } - } else { - if ((myGUS.DMAControl & 0x1) != 0) UseDMA(myDMA); - } - - -} static void GUS_CallBack(Bit8u * stream,Bit32u len) { @@ -946,11 +925,10 @@ static void GUS_CallBack(Bit8u * stream,Bit32u len) { memset(&buffer[0],0,len*4); memset(&tmpbuf[0],0,len*8); - int i,t; - for(i=0;iplaying) { guschan[i]->generateSamples(&buffer[0],len); - for(t=0;t>9; + if (sample>32767) + { + sample=32767; + AutoAmp--; + } else if (sample<-32768) + { + sample=-32768; + AutoAmp--; + } + bufptr[i] = (Bit16s)(sample); + } } @@ -1005,7 +998,7 @@ void MakeTables(void) for(i=0;i<256;i++) { float a,b; a = pow(2.0f,(float)(i >> 4)); - b = 1.0+((float)(i & 0xf))/(float)16; + b = 1.0f+((float)(i & 0xf))/(float)16; a *= b; a /= 16; vol8bit[i] = (Bit16u)a; @@ -1013,7 +1006,7 @@ void MakeTables(void) for(i=0;i<4096;i++) { float a,b; a = pow(2.0f,(float)(i >> 8)); - b = 1.0+((float)(i & 0xff))/(float)256; + b = 1.0f+((float)(i & 0xff))/(float)256; a *= b; a /= 16; vol16bit[i] = (Bit16u)a; @@ -1089,7 +1082,7 @@ void GUS_Init(Section* sec) { PIC_RegisterIRQ(myGUS.irq1,0,"GUS"); PIC_RegisterIRQ(myGUS.irq2,0,"GUS"); - DmaChannels[myGUS.dma1]->RegisterCallback(GUS_DMA_Callback); +// DmaChannels[myGUS.dma1]->Register_TC_Callback(GUS_DMA_TC_Callback); MakeTables(); @@ -1108,8 +1101,6 @@ void GUS_Init(Section* sec) { // ULTRASND=Port,DMA1,DMA2,IRQ1,IRQ2 SHELL_AddAutoexec("SET ULTRASND=%3X,%d,%d,%d,%d",portat,myGUS.dma1,myGUS.dma2,myGUS.irq1,myGUS.irq2); SHELL_AddAutoexec("SET ULTRADIR=%s", myGUS.ultradir); - - } From c07cd52717c29edb3df10e621fd632ec0cf522f6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 15 Mar 2004 14:54:59 +0000 Subject: [PATCH 1647/4131] Changed OPL and CMS functions to also use the soundblaster base Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1729 --- src/hardware/adlib.cpp | 12 +++++++++--- src/hardware/gameblaster.cpp | 10 +++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 86d1fd7a..40505abf 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -144,7 +144,7 @@ void OPL_Write(Bit32u port,Bit8u val) { } } -void OPL_Init(Section* sec,OPL_Mode oplmode,Bitu rate) { +void OPL_Init(Section* sec,Bitu base,OPL_Mode oplmode,Bitu rate) { Bitu i; Section_prop * section=static_cast(sec); if (OPL2::YM3812Init(2,OPL2_INTERNAL_FREQ,rate)) { @@ -159,9 +159,15 @@ void OPL_Init(Section* sec,OPL_Mode oplmode,Bitu rate) { for (i=0;i<4;i++) { IO_RegisterWriteHandler(0x388+i,OPL_Write,"OPL Write"); IO_RegisterReadHandler(0x388+i,OPL_Read,"OPL read"); - IO_RegisterWriteHandler(0x220+i,OPL_Write,"OPL Write"); - IO_RegisterReadHandler(0x220+i,OPL_Read,"OPL read"); + IO_RegisterWriteHandler(base+i,OPL_Write,"OPL Write"); + IO_RegisterReadHandler(base+i,OPL_Read,"OPL read"); } + IO_RegisterWriteHandler(base+8,OPL_Write,"OPL Write"); + IO_RegisterWriteHandler(base+9,OPL_Write,"OPL Write"); + IO_RegisterReadHandler(base+8,OPL_Read,"OPL read"); + IO_RegisterReadHandler(base+9,OPL_Read,"OPL read"); + + opl.active=false; opl.last_used=0; opl.mode=oplmode; diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index 0f98d8ae..a051a870 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -420,14 +420,14 @@ static void write_cms(Bit32u port,Bit8u val) { } - void CMS_Init(Section* sec,Bitu rate) { + void CMS_Init(Section* sec,Bitu base,Bitu rate) { Section_prop * section=static_cast(sec); sample_rate=rate; - IO_RegisterWriteHandler(0x220,write_cms,"CMS"); - IO_RegisterWriteHandler(0x221,write_cms,"CMS"); - IO_RegisterWriteHandler(0x222,write_cms,"CMS"); - IO_RegisterWriteHandler(0x223,write_cms,"CMS"); + IO_RegisterWriteHandler(base+0x0,write_cms,"CMS"); + IO_RegisterWriteHandler(base+0x1,write_cms,"CMS"); + IO_RegisterWriteHandler(base+0x2,write_cms,"CMS"); + IO_RegisterWriteHandler(base+0x3,write_cms,"CMS"); /* Register the Mixer CallBack */ From 31439632f307c5a652f2af6c53c626dac77fad50 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 15 Mar 2004 14:57:45 +0000 Subject: [PATCH 1648/4131] Added initial sb16 support Rewrote the DMA handling Give base address to cms and opl emulators Fix unaligned stereo transfers No set blaster line with sblaster disabled Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1730 --- src/hardware/sblaster.cpp | 429 ++++++++++++++++++++------------------ 1 file changed, 231 insertions(+), 198 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index bd37d7ed..a54fff56 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -64,13 +64,9 @@ enum DSP_MODES { }; enum DMA_MODES { - DMA_NONE, - DMA_8_SILENCE, - DMA_2_SINGLE, - DMA_3_SINGLE, - DMA_4_SINGLE, - DMA_8_SINGLE,DMA_8_AUTO, - DMA_16_SINGLE,DMA_16_AUTO, + DSP_DMA_NONE, + DSP_DMA_2,DSP_DMA_3,DSP_DMA_4,DSP_DMA_8, + DSP_DMA_16,DSP_DMA_16_ALIASED, }; enum { @@ -80,8 +76,10 @@ enum { struct SB_INFO { Bit16u freq; struct { - bool active,stereo,filtered; + bool active,stereo,filtered,sign,autoinit; + bool stereoremain; DMA_MODES mode; + Bitu previous; Bitu total,left; Bitu rate,rate_mul; Bitu index,add_index; @@ -90,10 +88,15 @@ struct SB_INFO { Bit8u b8[DMA_BUFSIZE]; Bit16s b16[DMA_BUFSIZE]; } buf; + Bitu bits; + DmaChannel * chan; + struct { + Bit16s stereo; + } remain; + } dma; bool speaker; Bit8u time_constant; - bool use_time_constant; DSP_MODES mode; SB_TYPES type; OPL_Mode oplmode; @@ -132,7 +135,7 @@ struct SB_INFO { struct { Bitu base; Bit8u irq; - Bit8u dma8; + Bit8u dma8,dma16; Bitu rate; Bitu rate_conv; } hw; @@ -145,6 +148,7 @@ struct SB_INFO { Bit16s m[DMA_BUFSIZE]; Bit16s s[DMA_BUFSIZE][2]; } buf; + Bitu index,add_index; } tmp; struct { @@ -218,6 +222,7 @@ static INLINE void SB_RaiseIRQ(SB_IRQS type) { } } + static INLINE void DSP_FlushData(void) { sb.dsp.out.used=0; sb.dsp.out.pos=0; @@ -228,17 +233,18 @@ static void DSP_StopDMA(void) { sb.dma.left=0; } -static void DMA_Enable(bool enable) { - sb.dma.active=enable; - if (sb.mode==MODE_DMA_WAIT && enable) { - LOG(LOG_SB,LOG_NORMAL)("DMA enabled,starting output"); +static void DSP_DMA_CallBack(DmaChannel * chan, DMAEvent event) { + if (event==DMA_MASKED) sb.dma.active=false; + if (event==DMA_UNMASKED) sb.dma.active=true; + if (sb.mode==MODE_DMA_WAIT && sb.dma.active) { + LOG(LOG_SB,LOG_NORMAL)("DMA Activated,starting output"); DSP_ChangeMode(MODE_DMA); CheckDMAEnd(); return; } - if (sb.mode==MODE_DMA && !enable) { + if (sb.mode==MODE_DMA && !sb.dma.active) { DSP_ChangeMode(MODE_DMA_WAIT); - LOG(LOG_SB,LOG_NORMAL)("DMA disabled,stopping output"); + LOG(LOG_SB,LOG_NORMAL)("DMA deactivated,stopping output"); return; } } @@ -248,14 +254,14 @@ static void DMA_Enable(bool enable) { #define MAX_ADAPTIVE_STEP_SIZE 32767 #define DC_OFFSET_FADE 254 -INLINE Bits Clip(Bits sample) { +static INLINE Bits Clip(Bits sample) { if (sample>MAX_AUDIO) return MAX_AUDIO; if (sampleRead(size,sb.dma.buf.b8); + sb.dma.left-=read; + Bitu skip=0;Bitu i;Bitu rem;Bitu done=0; + if (!read) { + sb.mode=MODE_DMA_WAIT; + return; + } + if (sb.dma.stereoremain) { + sb.dma.stereoremain=false; + sb.tmp.buf.m[done++]=sb.dma.remain.stereo; + } switch (sb.dma.mode) { - case DMA_2_SINGLE: - if (sb.adpcm.reference==0x1000000 && sb.dma.left) { - Bit8u ref; - read=DMA_8_Read(sb.hw.dma8,&ref,1); - if (!read) { sb.mode=MODE_NONE;return; } - sb.dma.left--; + case DSP_DMA_2: + if (sb.adpcm.reference==0x1000000) { sb.adpcm.reference=0; sb.adpcm.stepsize=MIN_ADAPTIVE_STEP_SIZE; - } - if (sb.dma.left> 6,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[i*4+1]=decode_ADPCM_2_sample((sb.dma.buf.b8[i] >>4) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[i*4+2]=decode_ADPCM_2_sample((sb.dma.buf.b8[i] >>2)& 0x3,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[i*4+3]=decode_ADPCM_2_sample(sb.dma.buf.b8[i] & 0x3,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[done++]=decode_ADPCM_2_sample((sb.dma.buf.b8[skip+i] >> 6) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[done++]=decode_ADPCM_2_sample((sb.dma.buf.b8[skip+i] >> 4) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[done++]=decode_ADPCM_2_sample((sb.dma.buf.b8[skip+i] >> 2) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[done++]=decode_ADPCM_2_sample((sb.dma.buf.b8[skip+i] >> 0) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize); } - read*=4; break; - case DMA_3_SINGLE: - if (sb.adpcm.reference==0x1000000 && sb.dma.left) { - Bit8u ref; - read=DMA_8_Read(sb.hw.dma8,&ref,1); - if (!read) { sb.mode=MODE_NONE;return;} - sb.dma.left--; + case DSP_DMA_3: + if (sb.adpcm.reference==0x1000000) { sb.adpcm.reference=0; sb.adpcm.stepsize=MIN_ADAPTIVE_STEP_SIZE; + skip++;read--; } - if (sb.dma.left>3)&7, sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[i*8+2]=decode_ADPCM_3_sample(((sb.dma.buf.b8[i*3] >>6)&3)&((sb.dma.buf.b8[i*3+1]&1)<<2),sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[i*8+3]=decode_ADPCM_3_sample((sb.dma.buf.b8[i*3+1]>>1)&7,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[i*8+4]=decode_ADPCM_3_sample((sb.dma.buf.b8[i*3+1]>>4)&7,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[i*8+5]=decode_ADPCM_3_sample(((sb.dma.buf.b8[i*3+1]>>7)&1)&((sb.dma.buf.b8[i*3+2]&3)<<1),sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[i*8+6]=decode_ADPCM_3_sample((sb.dma.buf.b8[i*3+2]>>2)&7,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[i*8+7]=decode_ADPCM_3_sample((sb.dma.buf.b8[i*3+2]>>5)&7,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[done++]=decode_ADPCM_3_sample( (sb.dma.buf.b8[skip+i*3] )&7,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[done++]=decode_ADPCM_3_sample( (sb.dma.buf.b8[skip+i*3] >>3)&7,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[done++]=decode_ADPCM_3_sample(((sb.dma.buf.b8[skip+i*3] >>6)&3)&((sb.dma.buf.b8[i*3+1]&1)<<2),sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[done++]=decode_ADPCM_3_sample( (sb.dma.buf.b8[skip+i*3+1]>>1)&7,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[done++]=decode_ADPCM_3_sample( (sb.dma.buf.b8[skip+i*3+1]>>4)&7,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[done++]=decode_ADPCM_3_sample(((sb.dma.buf.b8[skip+i*3+1]>>7)&1)&((sb.dma.buf.b8[i*3+2]&3)<<1),sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[done++]=decode_ADPCM_3_sample( (sb.dma.buf.b8[skip+i*3+2]>>2)&7,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[done++]=decode_ADPCM_3_sample( (sb.dma.buf.b8[skip+i*3+2]>>5)&7,sb.adpcm.reference,sb.adpcm.stepsize); } - read*=8; - if (ad) { - sb.tmp.buf.m[read]=decode_ADPCM_3_sample((sb.dma.buf.b8[read*3/8])&7,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[read+1]=decode_ADPCM_3_sample((sb.dma.buf.b8[read*3/8]>>3)&7,sb.adpcm.reference,sb.adpcm.stepsize); - read+=2; - if (ad==2) { - sb.tmp.buf.m[read]=decode_ADPCM_3_sample(((sb.dma.buf.b8[(read-2)*3/8-1]>>6)&3)&(sb.dma.buf.b8[(read-2)*3/8]&1), sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[read+1]=decode_ADPCM_3_sample((sb.dma.buf.b8[(read-2)*3/8]>>1)&7,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[read+2]=decode_ADPCM_3_sample((sb.dma.buf.b8[(read-2)*3/8]>>4)&7,sb.adpcm.reference,sb.adpcm.stepsize); - read+=3; + if (rem) { + sb.tmp.buf.m[done++]=decode_ADPCM_3_sample((sb.dma.buf.b8[skip+read*3])&7,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[done++]=decode_ADPCM_3_sample((sb.dma.buf.b8[skip+read*3]>>3)&7,sb.adpcm.reference,sb.adpcm.stepsize); + if (rem==2) { + sb.tmp.buf.m[done++]=decode_ADPCM_3_sample(((sb.dma.buf.b8[skip+read*3+1]>>6)&3)&(sb.dma.buf.b8[read*3/8]&1), sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[done++]=decode_ADPCM_3_sample((sb.dma.buf.b8[skip+read*3+1]>>1)&7,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[done++]=decode_ADPCM_3_sample((sb.dma.buf.b8[skip+read*3+1]>>4)&7,sb.adpcm.reference,sb.adpcm.stepsize); } } break; - case DMA_4_SINGLE: - if (sb.adpcm.reference==0x1000000 && sb.dma.left) { -//TODO Check this - Bit8u ref; - read=DMA_8_Read(sb.hw.dma8,&ref,1); - if (!read) { sb.mode=MODE_NONE;return; } //TODO warnings? - sb.dma.left--; + case DSP_DMA_4: + if (sb.adpcm.reference==0x1000000) { sb.adpcm.reference=0; sb.adpcm.stepsize=MIN_ADAPTIVE_STEP_SIZE; + skip++;read--; } if (sb.dma.leftRead(size,sb.dma.buf.b8); sb.dma.left-=read; - if (sb.dma.left==0 || !read) { - sb.mode=MODE_NONE; - SB_RaiseIRQ(SB_IRQ_8); - } for (i=0;i> 4,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[i*2+1]=decode_ADPCM_4_sample(sb.dma.buf.b8[i] & 0xf,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[done++]=decode_ADPCM_4_sample(sb.dma.buf.b8[skip+i] >> 4,sb.adpcm.reference,sb.adpcm.stepsize); + sb.tmp.buf.m[done++]=decode_ADPCM_4_sample(sb.dma.buf.b8[skip+i]& 0xf,sb.adpcm.reference,sb.adpcm.stepsize); } read*=2; break; - case DMA_8_SINGLE: - if (sb.dma.leftread) { - sb.dma.left-=read; - } else { - sb.dma.left=(sb.dma.total+sb.dma.left)-read; - SB_RaiseIRQ(SB_IRQ_8); -// LOG_MSG("SB DMA AUTO IRQ Raised"); - } - for (i=0;i= DSP_DMA_16) SB_RaiseIRQ(SB_IRQ_16); + else SB_RaiseIRQ(SB_IRQ_8); + } Bit16s * stream=&sb.out.buf[sb.out.pos][0]; if (!sb.dma.stereo) { Bitu pos; - while (read>(pos=sb.tmp.index>>16)) { + while (done>(pos=sb.tmp.index>>16)) { (*stream++)=sb.tmp.buf.m[pos]; (*stream++)=sb.tmp.buf.m[pos]; sb.tmp.index+=sb.tmp.add_index; @@ -461,18 +429,18 @@ static void GenerateDMASound(Bitu size) { } sb.tmp.index&=0xffff; } else { - if (read&1){ - LOG_MSG("DMA Unaligned"); - } else { - Bitu pos;read>>=1;Bitu index_add=sb.tmp.add_index >> 1; - while (read>(pos=sb.tmp.index>>16)) { - (*stream++)=sb.tmp.buf.s[pos][1]; //SB default seems to be swapped - (*stream++)=sb.tmp.buf.s[pos][0]; - sb.tmp.index+=index_add; - sb.out.pos++; - } - sb.tmp.index&=0xffff; + if (done&1){ + sb.dma.remain.stereo=sb.tmp.buf.m[done-1]; + sb.dma.stereoremain=true; } + Bitu pos;done>>=1;Bitu index_add=sb.tmp.add_index >> 1; + while (done>(pos=sb.tmp.index>>16)) { + (*stream++)=sb.tmp.buf.s[pos][0]; + (*stream++)=sb.tmp.buf.s[pos][1]; + sb.tmp.index+=index_add; + sb.out.pos++; + } + sb.tmp.index&=0xffff; } } @@ -558,54 +526,61 @@ static void DSP_RaiseIRQEvent(Bitu val) { SB_RaiseIRQ(SB_IRQ_8); } -static void DSP_StartDMATranfser(DMA_MODES mode) { - char * type; - /* First fill with current whatever is playing */ +static void DSP_DoDMATranfser(DMA_MODES mode) { + Bitu bits; DSP_ChangeMode(MODE_NONE); sb.dma.left=sb.dma.total; - if (sb.use_time_constant) { - sb.dma.rate=(1000000 / (256 - sb.time_constant)); - }; - sb.dma.rate_mul=(sb.dma.rate<<16)/sb.hw.rate; sb.dma.mode=mode; sb.tmp.index=0; + sb.dma.rate_mul=(sb.dma.rate<<16)/sb.hw.rate; + sb.tmp.add_index=(sb.dma.rate<<16)/sb.hw.rate; switch (mode) { - case DMA_8_SILENCE: - PIC_AddEvent(&DSP_RaiseIRQEvent,((1000000*sb.dma.left)/sb.dma.rate)); - sb.dma.mode=DMA_NONE; - return; - case DMA_8_SINGLE: - type="8-Bit Single Cycle"; - sb.tmp.add_index=(sb.dma.rate<<16)/sb.hw.rate; - break; - case DMA_8_AUTO: - type="8-Bit Auto Init"; - sb.tmp.add_index=(sb.dma.rate<<16)/sb.hw.rate; - break; - case DMA_4_SINGLE: - type="4-Bit ADPCM Single Cycle"; - sb.tmp.add_index=(sb.dma.rate<<16)/sb.hw.rate; - break; - case DMA_3_SINGLE: - type="3-Bit ADPCM Single Cycle"; - sb.tmp.add_index=(sb.dma.rate<<16)/sb.hw.rate; - break; - case DMA_2_SINGLE: - type="2-Bit ADPCM Single Cycle"; - sb.tmp.add_index=(sb.dma.rate<<16)/sb.hw.rate; - break; + case DSP_DMA_2:bits=2;break; + case DSP_DMA_3:bits=3;break; + case DSP_DMA_4:bits=4;break; + case DSP_DMA_8:bits=8;break; + case DSP_DMA_16_ALIASED: + case DSP_DMA_16: + bits=16;break; default: LOG(LOG_SB,LOG_ERROR)("DSP:Illegal transfer mode %d",mode); return; } - //TODO Use the 16-bit dma for 16-bit transfers DSP_ChangeMode(MODE_DMA_WAIT); sb.dma.mode=mode; - DMA_SetEnableCallBack(sb.hw.dma8,DMA_Enable); - //TODO with stereo divide add_index - LOG(LOG_SB,LOG_NORMAL)("DMA Transfer:%s rate %d size %d",type,sb.dma.rate,sb.dma.total); + sb.dma.chan->Register_Callback(DSP_DMA_CallBack); + LOG(LOG_SB,LOG_NORMAL)("DMA Transfer:%d-bits %s %s dma-rate %d size %d", + bits, + sb.dma.stereo ? "Stereo" : "Mono", + sb.dma.autoinit ? "Auto-Init" : "Single-Cycle", + sb.dma.rate,sb.dma.total + ); } +static void DSP_PrepareDMA_Old(DMA_MODES mode,bool autoinit) { + sb.dma.autoinit=autoinit; + if (!autoinit) sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); + sb.dma.rate=sb.freq; + sb.dma.chan=DmaChannels[sb.hw.dma8]; + DSP_DoDMATranfser(mode); +} + +static void DSP_PrepareDMA_New(DMA_MODES mode,bool autoinit,Bitu length) { + sb.dma.total=length; + sb.dma.rate=sb.freq * (sb.dma.stereo ? 2 : 1); + sb.dma.rate_mul=(sb.dma.rate<<16)/sb.hw.rate; + sb.dma.autoinit=autoinit; + if (mode==DSP_DMA_16) { + if (sb.hw.dma16!=0xff) sb.dma.chan=DmaChannels[sb.hw.dma16]; + else { + sb.dma.chan=DmaChannels[sb.hw.dma8]; + mode=DSP_DMA_16_ALIASED; + } + } else sb.dma.chan=DmaChannels[sb.hw.dma8]; + DSP_DoDMATranfser(mode); +} + + static void DSP_AddData(Bit8u val) { if (sb.dsp.out.usedRegister_Callback(0); + DmaChannels[sb.hw.dma8]->Write(1,&val); } } @@ -678,16 +652,17 @@ static void DSP_DoCommand(void) { case 0x24: /* Singe Cycle 8-Bit DMA ADC */ case 0x14: /* Singe Cycle 8-Bit DMA DAC */ case 0x91: /* Singe Cycle 8-Bit DMA High speed DAC */ - sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); - DSP_StartDMATranfser(DMA_8_SINGLE); + DSP_PrepareDMA_Old(DSP_DMA_8,false); break; case 0x90: /* Auto Init 8-bit DMA High Speed */ case 0x1c: /* Auto Init 8-bit DMA */ - DSP_StartDMATranfser(DMA_8_AUTO); + DSP_PrepareDMA_Old(DSP_DMA_8,true); break; case 0x40: /* Set Timeconstant */ - sb.use_time_constant=true; - sb.time_constant=sb.dsp.in.data[0]; + sb.freq=(1000000 / (256 - sb.dsp.in.data[0])); + break; + case 0x41: /* Set Output Samplerate */ + sb.freq=(sb.dsp.in.data[0] << 8) | sb.dsp.in.data[1]; break; case 0x48: /* Set DMA Block Size */ //TODO Maybe check limit for new irq? @@ -695,27 +670,35 @@ static void DSP_DoCommand(void) { break; case 0x75: /* 075h : Single Cycle 4-bit ADPCM Reference */ sb.adpcm.reference=0x1000000; - case 0x74: /* 074h : Single Cycle 4-bit ADPCM */ - sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); - DSP_StartDMATranfser(DMA_4_SINGLE); + case 0x74: /* 074h : Single Cycle 4-bit ADPCM */ + DSP_PrepareDMA_Old(DSP_DMA_4,false); break; case 0x77: /* 077h : Single Cycle 3-bit(2.6bit) ADPCM Reference*/ sb.adpcm.reference=0x1000000; - case 0x76: /* 076h : Single Cycle 3-bit(2.6bit) ADPCM */ - sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); - DSP_StartDMATranfser(DMA_3_SINGLE); + case 0x76: /* 074h : Single Cycle 3-bit(2.6bit) ADPCM */ + DSP_PrepareDMA_Old(DSP_DMA_3,false); break; case 0x17: /* 017h : Single Cycle 2-bit ADPCM Reference*/ sb.adpcm.reference=0x1000000; - case 0x16: /* 016h : Single Cycle 2-bit ADPCM */ - sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); - DSP_StartDMATranfser(DMA_2_SINGLE); + case 0x16: /* 074h : Single Cycle 2-bit ADPCM */ + DSP_PrepareDMA_Old(DSP_DMA_2,false); break; case 0x80: /* Silence DAC */ - sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); - DSP_StartDMATranfser(DMA_8_SILENCE); + PIC_AddEvent(&DSP_RaiseIRQEvent, + (1000000*(1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8))/sb.freq)); + break; + case 0xb0: case 0xb2: case 0xb4: case 0xb6: + case 0xc0: case 0xc2: case 0xc4: case 0xc6: + /* Generic 8/16 bit DMA */ + sb.dma.stereo=(sb.dsp.in.data[0] & 0x20) > 0; + sb.dma.sign=(sb.dsp.in.data[0] & 0x10) > 0; + DSP_PrepareDMA_New((sb.dsp.cmd & 0x10) ? DSP_DMA_16 : DSP_DMA_8, + (sb.dsp.cmd & 0x4)>0, + 1+sb.dsp.in.data[1]+(sb.dsp.in.data[2] << 8) + ); break; case 0xd0: /* Halt 8-bit DMA */ + case 0xd5: /* Halt 16-bit DMA */ if (sb.dma.left) { DSP_ChangeMode(MODE_DMA_PAUSE); #if SB_PIC_EVENTS @@ -731,11 +714,11 @@ static void DSP_DoCommand(void) { break; case 0xd4: /* Continue DMA */ DSP_ChangeMode(MODE_DMA_WAIT); - DMA_SetEnableCallBack(sb.hw.dma8,DMA_Enable); + sb.dma.chan->Register_Callback(DSP_DMA_CallBack); break; case 0xda: /* Exit Autoinitialize 8-bit */ /* Set mode to single transfer so it ends with current block */ - if (sb.dma.mode==DMA_8_AUTO) sb.dma.mode=DMA_8_SINGLE; + sb.dma.autoinit=false; //Should stop itself break; case 0xe0: /* DSP Identification - SB2.0+ */ DSP_FlushData(); @@ -743,8 +726,18 @@ static void DSP_DoCommand(void) { break; case 0xe1: /* Get DSP Version */ DSP_FlushData(); - DSP_AddData(DSP_MAJOR); - DSP_AddData(DSP_MINOR); + switch (sb.type) { + case SBT_1: + DSP_AddData(0x1);DSP_AddData(0x1);break; + case SBT_2: + DSP_AddData(0x2);DSP_AddData(0x1);break; + case SBT_PRO1: + DSP_AddData(0x3);DSP_AddData(0x0);break; + case SBT_PRO2: + DSP_AddData(0x3);DSP_AddData(0x2);break; + case SBT_16: + DSP_AddData(0x4);DSP_AddData(0x5);break; + } break; case 0xe2: /* Weird DMA identification write routine */ { @@ -753,7 +746,7 @@ static void DSP_DoCommand(void) { if ((sb.dsp.in.data[0] >> i) & 0x01) sb.e2.value += E2_incr_table[sb.e2.count % 4][i]; sb.e2.value += E2_incr_table[sb.e2.count % 4][8]; sb.e2.count++; - DMA_SetEnableCallBack(sb.hw.dma8,DMA_E2_Enable); + DmaChannels[sb.hw.dma8]->Register_Callback(DSP_E2_DMA_CallBack); } break; case 0xe3: /* DSP Copyright */ @@ -845,6 +838,23 @@ static void MIXER_Write(Bit8u val) { sb.mixer.lin.left= (val & 0xf) << 1; sb.mixer.lin.right=(val >> 4) << 1; break; + case 0x80: /* IRQ Select */ + sb.hw.irq=0xff; + if (val & 0x1) sb.hw.irq=2; + else if (val & 0x2) sb.hw.irq=5; + else if (val & 0x4) sb.hw.irq=7; + else if (val & 0x8) sb.hw.irq=10; + break; + case 0x81: /* DMA Select */ + sb.hw.dma8=0xff; + sb.hw.dma16=0xff; + if (val & 0x1) sb.hw.dma8=0; + else if (val & 0x2) sb.hw.dma8=1; + else if (val & 0x8) sb.hw.dma8=3; + if (val & 0x20) sb.hw.dma16=5; + else if (val & 0x40) sb.hw.dma16=6; + else if (val & 0x80) sb.hw.dma16=7; + break; default: LOG(LOG_SB,LOG_WARN)("MIXER:Write %X to unhandled index %X",val,sb.mixer.index); } @@ -876,6 +886,26 @@ static Bit8u MIXER_Read(void) { case 0x2e: /* Line-IN Volume (SBPRO) */ return ((sb.mixer.lin.left & 0x1e) >> 1) | ((sb.mixer.lin.right & 0x1e) << 3); + case 0x80: /* IRQ Select */ + switch (sb.hw.irq) { + case 2: return 0x1; + case 5: return 0x2; + case 7: return 0x4; + case 10: return 0x8; + } + case 0x81: /* DMA Select */ + ret=0; + switch (sb.hw.dma8) { + case 0:ret|=0x1;break; + case 1:ret|=0x2;break; + case 3:ret|=0x8;break; + } + switch (sb.hw.dma16) { + case 5:ret|=0x20;break; + case 6:ret|=0x40;break; + case 7:ret|=0x80;break; + } + return ret; case 0x82: return (sb.irq.pending_8bit ? 0x1 : 0) | (sb.irq.pending_16bit ? 0x2 : 0); @@ -957,6 +987,12 @@ void SBLASTER_Init(Section* sec) { Bitu i; Section_prop * section=static_cast(sec); const char * sbtype=section->Get_string("type"); + sb.hw.base=section->Get_hex("base"); + sb.hw.irq=section->Get_int("irq"); + sb.hw.dma8=section->Get_int("dma"); + sb.hw.dma16=section->Get_int("hdma"); + sb.hw.rate=section->Get_int("sbrate"); + sb.hw.rate_conv=(sb.hw.rate<<16)/1000000; if (!strcasecmp(sbtype,"sb1")) sb.type=SBT_1; else if (!strcasecmp(sbtype,"sb2")) sb.type=SBT_2; else if (!strcasecmp(sbtype,"sbpro1")) sb.type=SBT_PRO1; @@ -990,28 +1026,25 @@ void SBLASTER_Init(Section* sec) { case OPL_none: break; case OPL_cms: - CMS_Init(section,oplrate); + CMS_Init(section,sb.hw.base,oplrate); break; case OPL_opl2: case OPL_dualopl2: case OPL_opl3: - OPL_Init(section,opl_mode,oplrate); + OPL_Init(section,sb.hw.base,opl_mode,oplrate); break; } + if (sb.type==SBT_NONE) return; sb.chan=MIXER_AddChannel(&SBLASTER_CallBack,22050,"SBLASTER"); MIXER_Enable(sb.chan,false); sb.dsp.state=DSP_S_NORMAL; - sb.hw.base=section->Get_hex("base"); - sb.hw.irq=section->Get_int("irq"); - sb.hw.dma8=section->Get_int("dma"); - sb.hw.rate=section->Get_int("sbrate"); - sb.hw.rate_conv=(sb.hw.rate<<16)/1000000; MIXER_SetFreq(sb.chan,sb.hw.rate); MIXER_SetMode(sb.chan,MIXER_16STEREO); - for (i=sb.hw.base+4;i Date: Mon, 15 Mar 2004 15:04:18 +0000 Subject: [PATCH 1649/4131] Remove ega_switch.h and font_switch.h files Make some big log message in sblaster only work in debug mode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1731 --- src/hardware/Makefile.am | 2 +- src/hardware/ega-switch.h | 9730 ------------------------------------ src/hardware/font-switch.h | 2562 ---------- src/hardware/sblaster.cpp | 2 + 4 files changed, 3 insertions(+), 12293 deletions(-) delete mode 100644 src/hardware/ega-switch.h delete mode 100644 src/hardware/font-switch.h diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index b200390e..4259ac3c 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -7,7 +7,7 @@ noinst_LIBRARIES = libhardware.a libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler.cpp joystick.cpp keyboard.cpp \ memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp vga_other.cpp \ - vga_memory.cpp vga_misc.cpp vga_seq.cpp font-switch.h ega-switch.h cmos.cpp disney.cpp \ + vga_memory.cpp vga_misc.cpp vga_seq.cpp cmos.cpp disney.cpp \ gus.cpp mpu401.cpp serialport.cpp softmodem.cpp ipx.cpp ipxserver.cpp diff --git a/src/hardware/ega-switch.h b/src/hardware/ega-switch.h deleted file mode 100644 index b4dff453..00000000 --- a/src/hardware/ega-switch.h +++ /dev/null @@ -1,9730 +0,0 @@ -switch (bit_mask) { - case 0: - break; - case 1: - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 2: - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 3: - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 4: - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 5: - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 6: - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 7: - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 8: - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - break; - case 9: - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 10: - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 11: - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 12: - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 13: - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 14: - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 15: - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 16: - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - break; - case 17: - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 18: - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 19: - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 20: - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 21: - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 22: - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 23: - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 24: - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - break; - case 25: - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 26: - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 27: - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 28: - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 29: - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 30: - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 31: - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 32: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - break; - case 33: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 34: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 35: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 36: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 37: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 38: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 39: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 40: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - break; - case 41: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 42: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 43: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 44: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 45: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 46: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 47: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 48: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - break; - case 49: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 50: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 51: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 52: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 53: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 54: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 55: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 56: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - break; - case 57: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 58: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 59: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 60: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 61: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 62: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 63: - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 64: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - break; - case 65: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 66: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 67: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 68: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 69: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 70: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 71: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 72: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - break; - case 73: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 74: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 75: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 76: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 77: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 78: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 79: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 80: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - break; - case 81: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 82: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 83: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 84: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 85: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 86: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 87: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 88: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - break; - case 89: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 90: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 91: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 92: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 93: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 94: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 95: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 96: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - break; - case 97: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 98: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 99: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 100: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 101: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 102: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 103: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 104: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - break; - case 105: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 106: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 107: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 108: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 109: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 110: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 111: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 112: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - break; - case 113: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 114: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 115: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 116: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 117: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 118: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 119: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 120: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - break; - case 121: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 122: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 123: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 124: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 125: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 126: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 127: - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 128: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - break; - case 129: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 130: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 131: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 132: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 133: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 134: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 135: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 136: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - break; - case 137: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 138: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 139: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 140: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 141: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 142: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 143: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 144: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - break; - case 145: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 146: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 147: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 148: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 149: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 150: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 151: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 152: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - break; - case 153: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 154: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 155: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 156: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 157: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 158: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 159: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 160: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - break; - case 161: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 162: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 163: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 164: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 165: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 166: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 167: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 168: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - break; - case 169: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 170: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 171: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 172: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 173: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 174: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 175: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 176: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - break; - case 177: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 178: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 179: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 180: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 181: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 182: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 183: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 184: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - break; - case 185: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 186: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 187: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 188: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 189: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 190: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 191: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 192: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - break; - case 193: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 194: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 195: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 196: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 197: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 198: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 199: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 200: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - break; - case 201: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 202: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 203: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 204: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 205: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 206: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 207: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 208: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - break; - case 209: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 210: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 211: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 212: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 213: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 214: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 215: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 216: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - break; - case 217: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 218: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 219: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 220: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 221: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 222: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 223: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 224: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - break; - case 225: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 226: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 227: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 228: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 229: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 230: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 231: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 232: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - break; - case 233: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 234: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 235: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 236: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 237: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 238: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 239: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 240: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - break; - case 241: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 242: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 243: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 244: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 245: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 246: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 247: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 248: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - break; - case 249: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 250: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 251: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 252: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - break; - case 253: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; - case 254: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - break; - case 255: - { - Bit8u color=0; - if (pixels.b[0] & 128) color|=1; - if (pixels.b[1] & 128) color|=2; - if (pixels.b[2] & 128) color|=4; - if (pixels.b[3] & 128) color|=8; - *(write_pixels+0)=color; - *(write_pixels+0+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 64) color|=1; - if (pixels.b[1] & 64) color|=2; - if (pixels.b[2] & 64) color|=4; - if (pixels.b[3] & 64) color|=8; - *(write_pixels+1)=color; - *(write_pixels+1+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 32) color|=1; - if (pixels.b[1] & 32) color|=2; - if (pixels.b[2] & 32) color|=4; - if (pixels.b[3] & 32) color|=8; - *(write_pixels+2)=color; - *(write_pixels+2+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 16) color|=1; - if (pixels.b[1] & 16) color|=2; - if (pixels.b[2] & 16) color|=4; - if (pixels.b[3] & 16) color|=8; - *(write_pixels+3)=color; - *(write_pixels+3+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 8) color|=1; - if (pixels.b[1] & 8) color|=2; - if (pixels.b[2] & 8) color|=4; - if (pixels.b[3] & 8) color|=8; - *(write_pixels+4)=color; - *(write_pixels+4+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 4) color|=1; - if (pixels.b[1] & 4) color|=2; - if (pixels.b[2] & 4) color|=4; - if (pixels.b[3] & 4) color|=8; - *(write_pixels+5)=color; - *(write_pixels+5+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 2) color|=1; - if (pixels.b[1] & 2) color|=2; - if (pixels.b[2] & 2) color|=4; - if (pixels.b[3] & 2) color|=8; - *(write_pixels+6)=color; - *(write_pixels+6+512*1024)=color; - } - { - Bit8u color=0; - if (pixels.b[0] & 1) color|=1; - if (pixels.b[1] & 1) color|=2; - if (pixels.b[2] & 1) color|=4; - if (pixels.b[3] & 1) color|=8; - *(write_pixels+7)=color; - *(write_pixels+7+512*1024)=color; - } - break; -} diff --git a/src/hardware/font-switch.h b/src/hardware/font-switch.h deleted file mode 100644 index 80a3adfd..00000000 --- a/src/hardware/font-switch.h +++ /dev/null @@ -1,2562 +0,0 @@ -switch (bit_mask) { - case 0: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 1: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 2: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 3: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 4: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 5: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 6: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 7: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 8: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 9: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 10: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 11: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 12: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 13: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 14: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 15: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 16: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 17: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 18: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 19: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 20: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 21: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 22: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 23: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 24: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 25: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 26: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 27: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 28: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 29: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 30: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 31: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 32: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 33: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 34: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 35: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 36: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 37: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 38: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 39: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 40: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 41: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 42: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 43: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 44: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 45: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 46: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 47: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 48: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 49: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 50: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 51: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 52: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 53: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 54: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 55: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 56: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 57: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 58: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 59: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 60: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 61: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 62: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 63: - *(draw+0)=bg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 64: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 65: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 66: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 67: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 68: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 69: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 70: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 71: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 72: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 73: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 74: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 75: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 76: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 77: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 78: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 79: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 80: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 81: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 82: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 83: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 84: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 85: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 86: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 87: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 88: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 89: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 90: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 91: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 92: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 93: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 94: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 95: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 96: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 97: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 98: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 99: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 100: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 101: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 102: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 103: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 104: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 105: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 106: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 107: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 108: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 109: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 110: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 111: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 112: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 113: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 114: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 115: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 116: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 117: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 118: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 119: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 120: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 121: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 122: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 123: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 124: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 125: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 126: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 127: - *(draw+0)=bg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 128: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 129: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 130: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 131: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 132: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 133: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 134: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 135: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 136: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 137: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 138: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 139: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 140: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 141: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 142: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 143: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 144: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 145: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 146: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 147: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 148: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 149: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 150: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 151: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 152: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 153: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 154: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 155: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 156: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 157: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 158: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 159: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 160: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 161: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 162: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 163: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 164: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 165: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 166: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 167: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 168: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 169: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 170: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 171: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 172: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 173: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 174: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 175: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 176: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 177: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 178: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 179: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 180: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 181: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 182: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 183: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 184: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 185: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 186: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 187: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 188: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 189: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 190: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 191: - *(draw+0)=fg; - *(draw+1)=bg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 192: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 193: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 194: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 195: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 196: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 197: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 198: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 199: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 200: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 201: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 202: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 203: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 204: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 205: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 206: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 207: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 208: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 209: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 210: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 211: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 212: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 213: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 214: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 215: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 216: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 217: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 218: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 219: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 220: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 221: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 222: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 223: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=bg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 224: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 225: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 226: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 227: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 228: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 229: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 230: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 231: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 232: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 233: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 234: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 235: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 236: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 237: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 238: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 239: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=bg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 240: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 241: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 242: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 243: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 244: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 245: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 246: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 247: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=bg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 248: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 249: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 250: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 251: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=bg; - *(draw+6)=fg; - *(draw+7)=fg; - break; - case 252: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=bg; - break; - case 253: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=bg; - *(draw+7)=fg; - break; - case 254: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=bg; - break; - case 255: - *(draw+0)=fg; - *(draw+1)=fg; - *(draw+2)=fg; - *(draw+3)=fg; - *(draw+4)=fg; - *(draw+5)=fg; - *(draw+6)=fg; - *(draw+7)=fg; - break; -} diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index a54fff56..7eb553a3 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -549,12 +549,14 @@ static void DSP_DoDMATranfser(DMA_MODES mode) { DSP_ChangeMode(MODE_DMA_WAIT); sb.dma.mode=mode; sb.dma.chan->Register_Callback(DSP_DMA_CallBack); +#if (C_DEBUG) LOG(LOG_SB,LOG_NORMAL)("DMA Transfer:%d-bits %s %s dma-rate %d size %d", bits, sb.dma.stereo ? "Stereo" : "Mono", sb.dma.autoinit ? "Auto-Init" : "Single-Cycle", sb.dma.rate,sb.dma.total ); +#endif } static void DSP_PrepareDMA_Old(DMA_MODES mode,bool autoinit) { From dc8179439a1c63c5bb81e8f3d9eedb6194319647 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 18 Mar 2004 16:21:04 +0000 Subject: [PATCH 1650/4131] Additions to mp401 suggested by Screcko. Legend games are now working. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1732 --- src/hardware/mpu401.cpp | 225 ++++++++++++++++++++++++---------------- 1 file changed, 138 insertions(+), 87 deletions(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 409adb97..1c3662b0 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -15,11 +15,10 @@ static void MPU401_Reset(void); static void MPU401_EOIHandler(void); #define MPU_QUEUE 32 -#define MPU_RQ_QUEUE 64 #define TIMECONSTANT 60000000 enum MpuMode { M_UART,M_INTELLIGENT } ; -enum MpuDataType {UNSET,OVERFLOW,MARK,MIDI_SYS,MIDI_NORM,MIDI_DATA,COMMAND}; +enum MpuDataType {OVERFLOW,MARK,MIDI_SYS,MIDI_NORM,COMMAND}; ///////////////////////////////////////////////////////////////////////////// // I/O @@ -168,10 +167,10 @@ static struct { Bitu irq; Bit8u queue[MPU_QUEUE]; Bitu queue_pos,queue_used; - struct type_t{ + struct track { Bits counter; Bit8u value[8]; - Bit8u vlength; + Bit8u vlength,length; MpuDataType type; } playbuf[8],condbuf; struct { @@ -181,6 +180,7 @@ static struct { bool wsd,wsm,wsd_start; bool midi_thru; bool run_irq,irq_pending; + bool send_now; Bits data_onoff; Bitu command_byte; Bit8u tmask,cmask,amask; @@ -233,6 +233,11 @@ static void MPU401_WriteCommand(Bit32u port,Bit8u val) { case 0x4: /* Stop */ PIC_RemoveEvents(MPU401_Event); mpu.state.playing=false; + for (Bitu i=0xb0;i<0xbf;i++) {//All notes off + MIDI_RawOutByte(i); + MIDI_RawOutByte(0x7b); + MIDI_RawOutByte(0); + } ClrQueue(); break; case 0x8: /* Play */ @@ -248,7 +253,6 @@ static void MPU401_WriteCommand(Bit32u port,Bit8u val) { } else if (val>=0xd0 && val<=0xd7) { /* Request to send data */ mpu.state.channel=val&7; - //if (!mpu.playbuf[mpu.state.channel].active) mpu.state.wsd=true; mpu.state.wsm=false; mpu.state.wsd_start=true; @@ -347,7 +351,7 @@ static void MPU401_WriteCommand(Bit32u port,Bit8u val) { } for (Bitu i=0;i<8;i++) { mpu.playbuf[i].counter=0; - mpu.playbuf[i].type=UNSET; + mpu.playbuf[i].type=OVERFLOW; } mpu.condbuf.counter=0; mpu.condbuf.type=OVERFLOW; @@ -377,7 +381,7 @@ static void MPU401_WriteCommand(Bit32u port,Bit8u val) { mpu.state.allthru=false; break; default: - LOG(LOG_MISC,LOG_NORMAL)("MPU401:Unhandled command %X",val); + LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Unhandled command %X",val); } QueueByte(MSG_CMD_ACK); } @@ -393,21 +397,21 @@ static Bit8u MPU401_ReadData(Bit32u port) { mpu.state.channel=ret&7; mpu.state.data_onoff=0; mpu.state.cond_req=false; - mpu.playbuf[mpu.state.channel].counter=0; } if (ret==MSG_REQUEST_COMMAND) { mpu.state.data_onoff=0; mpu.state.cond_req=true; - mpu.condbuf.counter=0; } if (ret==MSG_ALL_END || ret==MSG_CLOCK_TO_HOST) { mpu.state.data_onoff=-1; + MPU401_EOIHandler(); } return ret; } static void MPU401_WriteData(Bit32u port,Bit8u val) { if (mpu.mode==M_UART) {MIDI_RawOutByte(val);return;} + if (mpu.state.command_byte) MPU401_EOIHandler(); /* S101, Time Quest */ switch (mpu.state.command_byte) { case 0: break; @@ -445,22 +449,28 @@ static void MPU401_WriteData(Bit32u port,Bit8u val) { mpu.state.command_byte=0; return; } - static Bitu length,cnt; + static Bitu length,cnt,posd; if (mpu.state.wsd) { if (mpu.state.wsd_start) { mpu.state.wsd_start=0; cnt=0; - switch (val&0xf0) { - case 0xc0: - case 0xd0: - length=2; - break; - case 0xf0: - if (!mpu.state.allthru) {mpu.state.wsd=0;return;} - else {length=1;break;} - default: - length=3; - } + switch (val&0xf0) { + case 0xc0:case 0xd0: + mpu.playbuf[mpu.state.channel].value[0]=val; + length=2; + break; + case 0x80:case 0x90:case 0xa0:case 0xb0:case 0xe0: + mpu.playbuf[mpu.state.channel].value[0]=val; + length=3; + break; + case 0xf0: + LOG(LOG_MISC,LOG_ERROR)("MPU-401:Illegal WSD byte"); + mpu.state.wsd=0; + return; + default: /* MIDI with running status */ + cnt++; + MIDI_RawOutByte(mpu.playbuf[mpu.state.channel].value[0]); + } } if (cnt8) return; - mpu.playbuf[mpu.state.channel].value[posd-1]=val; + posd=mpu.playbuf[mpu.state.channel].vlength; if (posd==1) { switch (val&0xf0) { - case 0xf0: - mpu.playbuf[mpu.state.channel].type=(val>0xf7 ? MARK : MIDI_SYS); + case 0xf0: /* System message or mark */ + if (val>0xf7) { + mpu.playbuf[mpu.state.channel].type=MARK; + length=1; + } else { + LOG(LOG_MISC,LOG_ERROR)("MPU-401:Illegal message"); + mpu.playbuf[mpu.state.channel].type=MIDI_SYS; + length=1; + } break; - case 0xe0: case 0xd0: case 0xc0: case 0xb0: case 0xa0: case 0x90: case 0x80: + case 0xc0: case 0xd0: /* MIDI Message */ mpu.playbuf[mpu.state.channel].type=MIDI_NORM; + length=mpu.playbuf[mpu.state.channel].length=2; + break; + case 0x80: case 0x90: case 0xa0: case 0xb0: case 0xe0: + mpu.playbuf[mpu.state.channel].type=MIDI_NORM; + length=mpu.playbuf[mpu.state.channel].length=3; + break; + default: /* MIDI data with running status */ + posd++; + mpu.playbuf[mpu.state.channel].vlength++; + mpu.playbuf[mpu.state.channel].type=MIDI_NORM; + length=mpu.playbuf[mpu.state.channel].length; break; - default: - mpu.playbuf[mpu.state.channel].type=MIDI_DATA; } } + mpu.playbuf[mpu.state.channel].value[posd-1]=val; + if (posd==length) MPU401_EOIHandler(); } } static void MPU401_IntelligentOut(Bit8u chan) { Bitu val; switch (mpu.playbuf[chan].type) { - case UNSET: case OVERFLOW: break; case MARK: val=mpu.playbuf[chan].value[0]; - if (val==0xfc) {MIDI_RawOutByte(val);mpu.state.amask&=~(1<=500) { + CPU_CycleLeft+=CPU_Cycles-500; + CPU_Cycles=500; + } #endif PIC_ActivateIRQ(mpu.irq); mpu.state.irq_pending=true; @@ -630,7 +681,6 @@ static void MPU401_EOIHandler(void) static Bitu INT71_Handler() { CALLBACK_RunRealInt(0xa); IO_Write(0xa0,0x61); - MPU401_EOIHandler(); return CBRET_NONE; } @@ -653,7 +703,7 @@ static void MPU401_Reset(void) { mpu.state.midi_mask=0xffff; mpu.state.data_onoff=0; mpu.state.command_byte=0; - mpu.clock.tempo=mpu.clock.old_tempo=160; + mpu.clock.tempo=mpu.clock.old_tempo=100; mpu.clock.timebase=mpu.clock.old_timebase=120; mpu.clock.tempo_rel=mpu.clock.old_tempo_rel=40; mpu.clock.tempo_grad=0; @@ -664,10 +714,14 @@ static void MPU401_Reset(void) { mpu.state.req_mask=0; mpu.condbuf.counter=0; mpu.condbuf.type=OVERFLOW; - for (Bitu i=0;i<8;i++) {mpu.playbuf[i].type=UNSET;mpu.playbuf[i].counter=0;} + for (Bitu i=0;i<8;i++) {mpu.playbuf[i].type=OVERFLOW;mpu.playbuf[i].counter=0;} } void MPU401_Init(Section* sec) { + call_irq9=CALLBACK_Allocate(); //allocate handler for irq 9 + CALLBACK_Setup(call_irq9,&INT71_Handler,CB_IRET); + RealSetVec(0x71,CALLBACK_RealPointer(call_irq9)); + Section_prop * section=static_cast(sec); if(!section->Get_bool("mpu401")) return; @@ -685,8 +739,5 @@ void MPU401_Init(Section* sec) { if (!(mpu.intelligent=section->Get_bool("intelligent"))) return; mpu.irq=2; PIC_RegisterIRQ(mpu.irq,0,"MPU401"); - call_irq9=CALLBACK_Allocate(); //allocate handler for irq 9 - CALLBACK_Setup(call_irq9,&INT71_Handler,CB_IRET); - RealSetVec(0x71,CALLBACK_RealPointer(call_irq9)); MPU401_Reset(); } From 416fbac8e3ddc3400a54850735121fc754c537d6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 18 Mar 2004 19:53:08 +0000 Subject: [PATCH 1651/4131] Fix relative motion when mode switching and ps2callback is used Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1733 --- src/ints/mouse.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index d4ef2b09..eb0ee483 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.33 2004-03-14 13:39:45 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.34 2004-03-18 19:53:08 qbix79 Exp $ */ #include #include "dosbox.h" @@ -561,6 +561,9 @@ void Mouse_NewVideoMode(void) mouse.oldshown=-1; SetMickeyPixelRate(8,16); + oldmouseX = static_cast(mouse.x); + oldmouseY = static_cast(mouse.y); + } From ce758f85f553f6be3f0386f5cc97c2a9770ec54d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 23 Mar 2004 18:24:05 +0000 Subject: [PATCH 1652/4131] improve some odd table for msd.exe (c2woody) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1734 --- src/dos/dos.cpp | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 82ec9481..1782b5ff 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.69 2004-03-14 16:54:21 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.70 2004-03-23 18:24:05 qbix79 Exp $ */ #include #include @@ -792,10 +792,23 @@ static Bitu DOS_21Handler(void) { switch (reg_al) { case 1: mem_writeb(data,reg_al); - mem_writew(data+1,4); - mem_writew(data+3,1); - mem_writew(data+5,37); - reg_cx=4; + mem_writew(data+0x01,0x1c); + mem_writew(data+0x03,1); + mem_writew(data+0x05,0x01b5); + mem_writew(data+0x07,0x0000); // date format + mem_writeb(data+0x08,0x24); // currency symbol + mem_writew(data+0x0a,0x0000); + mem_writew(data+0x0c,0x0000); + mem_writew(data+0x0e,0x002c); // thousands separator + mem_writew(data+0x10,0x002e); // decimal separator + mem_writew(data+0x12,0x002d); // date separator + mem_writew(data+0x14,0x003a); // time separator + mem_writeb(data+0x16,0x00); // currency format + mem_writeb(data+0x17,0x02); // digits after decimal in currency + mem_writeb(data+0x18,0x00); // time format + mem_writed(data+0x19,CALLBACK_RealPointer(call_casemap)); + mem_writew(data+0x1d,0x002c); // list separator + reg_cx=0x1f; CALLBACK_SCF(false); break; case 2: // Get pointer to uppercase table @@ -804,9 +817,10 @@ static Bitu DOS_21Handler(void) { case 5: // Get pointer to filename terminator table case 6: // Get pointer to collating sequence table case 7: // Get pointer to double byte char set table - mem_writew(data ,0x0000); // We dont have this table... - mem_writew(data+2,0x0000); // End of table - reg_cx=4; + mem_writeb(data,reg_al); + mem_writew(data+1,0x0000); // We dont have this table... + mem_writew(data+3,0x0000); // End of table + reg_cx=5; CALLBACK_SCF(false); break; default: From 2c9077f9e2a1822870811de920832d59a119d143 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 23 Mar 2004 18:51:21 +0000 Subject: [PATCH 1653/4131] Moved Dos infotable to another location. Added some odd files>20 detection Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1735 --- src/dos/dos_tables.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 3dadda1b..30122508 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: dos_tables.cpp,v 1.9 2004-03-23 18:51:21 qbix79 Exp $ */ + #include "dosbox.h" #include "mem.h" #include "dos_inc.h" @@ -56,9 +58,7 @@ void DOS_SetupTables(void) { dos.tables.indosflag = RealMake(0x5f,0xf); mem_writeb(Real2Phys(dos.tables.indosflag),0); /* Create the DOS Info Block */ - dos_infoblock.SetLocation(DOS_GetMemory(1+(sizeof(DOS_InfoBlock::sDIB)/16))); -// dos_infoblock.SetLocation(0x4e); //c2woody -/* The above lines might be switched around when working on certain programs */ + dos_infoblock.SetLocation(0x4e); //c2woody /* Create a fake SFT, so programs think there are 100 file handles */ seg=DOS_GetMemory(1); @@ -67,4 +67,17 @@ void DOS_SetupTables(void) { dos_infoblock.SetfirstFileTable(RealMake(seg,0)); /* Set buffers to a nice value */ dos_infoblock.SetBuffers(50,50); + + /* Some weird files >20 detection routine */ + /* Possibly obselete when SFT is properly handled */ + // CON string + real_writew(0x54,0x00+0x00, (Bit16u) 0x4f43); + real_writew(0x54,0x00+0x02, (Bit16u) 0x204e); + // CON string + real_writew(0x54,0x10+0x00, (Bit16u) 0x4f43); + real_writew(0x54,0x10+0x02, (Bit16u) 0x204e); + //CON string + real_writew(0x54,0x20+0x00, (Bit16u) 0x4f43); + real_writew(0x54,0x20+0x02, (Bit16u) 0x204e); + } From 2b1e4671e46982d562b8bba241c9501b8f3b82cc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 23 Mar 2004 20:02:45 +0000 Subject: [PATCH 1654/4131] Default all unhandled opcodes to be illegal opcodes Print the illegal/unhandled opcode in debug mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1736 --- src/cpu/core_normal.cpp | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 84076958..89fa9316 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include #include "dosbox.h" #include "mem.h" @@ -187,23 +188,29 @@ restart_opcode: #include "core_normal/prefix_66.h" #include "core_normal/prefix_66_0f.h" default: - ADDIPFAST(-1); -#if C_DEBUG - LOG_MSG("Unhandled code %X",core.opcode_index+Fetchb()); -#else - E_Exit("Unhandled CPU opcode"); + illegal_opcode: + LEAVECORE; + reg_eip-=core.ip_lookup-core.op_start; +#if C_DEBUG + { + Bitu len=core.ip_lookup-core.op_start; + if (len>16) len=16; + char tempcode[16*2+1];char * writecode=tempcode; + for (;len>0;len--) { + sprintf(writecode,"%X",mem_readb(core.op_start++)); + writecode+=2; + } + LOG(LOG_CPU,LOG_ERROR)("Illegal/Unhandled opcode %s",tempcode); + } #endif + CPU_Exception(6,0); + goto decode_start; + } } decode_end: LEAVECORE; return CBRET_NONE; - -illegal_opcode: - LEAVECORE; - reg_eip-=core.ip_lookup-core.op_start; - CPU_Exception(6,0); - goto decode_start; } Bits CPU_Core_Normal_Trap_Run(void) { From 76d89159c967e0572c5327dd430c24747ecc46d7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 23 Mar 2004 20:25:41 +0000 Subject: [PATCH 1655/4131] changed sensitivity settings. makes master of orion 2 playable Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1737 --- src/ints/mouse.cpp | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index eb0ee483..73079851 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,9 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.34 2004-03-18 19:53:08 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.35 2004-03-23 20:25:41 qbix79 Exp $ */ #include +#include #include "dosbox.h" #include "callback.h" #include "mem.h" @@ -162,6 +163,8 @@ static struct { float mickeysPerPixel_y; float pixelPerMickey_x; float pixelPerMickey_y; + float senv_x; + float senv_y; Bit16u updateRegion_x[2]; Bit16u updateRegion_y[2]; Bit16u page; @@ -406,16 +409,15 @@ void DrawCursor() { } void Mouse_CursorMoved(float x,float y) { - float dx = x * mouse.pixelPerMickey_x; float dy = y * mouse.pixelPerMickey_y; + if((fabs(x) > 1.0) || (mouse.senv_y < 1.0)) dx=mouse.senv_x*x; + if((fabs(y) > 1.0) || (mouse.senv_y < 1.0)) dy=mouse.senv_y*y; mouse.mickey_x += dx; mouse.mickey_y += dy; - mouse.x += dx; mouse.y += dy; - /* ignore constraints if using PS2 mouse callback in the bios */ if (!useps2callback) { if (mouse.x > mouse.max_x) mouse.x = mouse.max_x; @@ -474,8 +476,7 @@ void Mouse_ButtonReleased(Bit8u button) { mouse.last_released_y[button]=POS_Y; } -static void SetMickeyPixelRate(Bit16s px, Bit16s py) -{ +static void SetMickeyPixelRate(Bit16s px, Bit16s py){ if ((px!=0) && (py!=0)) { mouse.mickeysPerPixel_x = (float)px/X_MICKEY; mouse.mickeysPerPixel_y = (float)py/Y_MICKEY; @@ -483,6 +484,14 @@ static void SetMickeyPixelRate(Bit16s px, Bit16s py) mouse.pixelPerMickey_y = Y_MICKEY/(float)py; } }; +static void SetSensitivity(Bit16s px, Bit16s py){ + if ((px!=0) && (py!=0)) { + px--; //Inspired by cutemouse + py--; //Although their cursor update routine is far more complex then ours + mouse.senv_x=(static_cast(px)*px)/3600.0 +1.0/3.0; + mouse.senv_y=(static_cast(py)*py)/3600.0 +1.0/3.0; + } +}; static void mouse_reset_hardware(void){ PIC_SetIRQMask(MOUSE_IRQ,false); @@ -575,6 +584,8 @@ static void mouse_reset(void) { mouse.sub_mask=0; mouse.sub_seg=0; mouse.sub_ofs=0; + mouse.senv_x=1.0; + mouse.senv_y=1.0; //Added this for cd-v19 } @@ -738,12 +749,14 @@ static Bitu INT33_Handler(void) { } break; case 0x1a: /* Set mouse sensitivity */ - SetMickeyPixelRate(reg_bx,reg_cx); + SetSensitivity(reg_bx,reg_cx); + LOG(LOG_MOUSE,LOG_WARN)("Set sensitivity used with %d %d",reg_bx,reg_cx); // ToDo : double mouse speed value break; case 0x1b: /* Get mouse sensitivity */ - reg_bx = Bit16s(X_MICKEY * mouse.mickeysPerPixel_x); - reg_cx = Bit16s(Y_MICKEY * mouse.mickeysPerPixel_y); + reg_bx = Bit16s((60.0* sqrt(mouse.senv_x- (1.0/3.0)) ) +1.0); + reg_cx = Bit16s((60.0* sqrt(mouse.senv_y- (1.0/3.0)) ) +1.0); + LOG(LOG_MOUSE,LOG_WARN)("Get sensitivity %d %d",reg_bx,reg_cx); // ToDo : double mouse speed value reg_dx = 64; break; From a07aad49c89d4f833c68f35361bd041bb920dcc4 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 23 Mar 2004 21:00:42 +0000 Subject: [PATCH 1656/4131] New write map to handle write protection New flag handling New linking handling of blocks Better handling of cache resetting Some bug fixes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1738 --- src/cpu/core_dyn_x86.cpp | 140 +++++------- src/cpu/core_dyn_x86/cache.h | 371 +++++++++++++++++++------------- src/cpu/core_dyn_x86/decoder.h | 333 ++++++++++++++++------------ src/cpu/core_dyn_x86/risc_x86.h | 77 +++---- src/cpu/core_dyn_x86/string.h | 4 +- 5 files changed, 509 insertions(+), 416 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index e6becba8..4fa737f2 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -33,10 +33,11 @@ #include "paging.h" #include "inout.h" -#define CACHE_TOTAL (1024*1024*2) +#define CACHE_TOTAL (512*1024) #define CACHE_MAXSIZE (4096) -#define CACHE_BLOCKS (50*1024) +#define CACHE_BLOCKS (32*1024) #define CACHE_ALIGN (16) +#define CACHE_PAGES (128) #define DYN_HASH_SHIFT (4) #define DYN_PAGE_HASH (4096>>DYN_HASH_SHIFT) #define DYN_LINKS (16) @@ -68,8 +69,8 @@ enum DualOps { DOP_SUB,DOP_SBB, DOP_CMP,DOP_XOR, DOP_AND,DOP_OR, - DOP_MOV, DOP_TEST, + DOP_MOV, DOP_XCHG, }; @@ -87,19 +88,15 @@ enum BranchTypes { BR_L,BR_NL,BR_LE,BR_NLE }; -enum BlockType { - BT_Free=0, - BT_Normal, - BT_SingleLink, - BT_DualLink, - BT_CheckFlags, -}; enum BlockReturn { BR_Normal=0, BR_Cycles, BR_Link1,BR_Link2, BR_Opcode, +#if (C_DEBUG) + BR_OpcodeFull, +#endif BR_CallBack, }; @@ -165,9 +162,9 @@ static void dyn_load_flags(void) { gen_releasereg(DREG(FLAGS)); } -static void dyn_save_flags(bool stored=false) { +static void dyn_save_flags(void) { /* Store the host flags back in emulated ones */ - gen_save_flags(DREG(EXIT),stored); + 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 @@ -201,80 +198,61 @@ Bits CPU_Core_Dyn_X86_Run(void) { restart_core: PhysPt ip_point=SegPhys(cs)+reg_eip; Bitu ip_page=ip_point>>12; - mem_readb(ip_point); //Init whatever page we are in - PageHandler * handler=paging.tlb.handler[ip_page]; - CodePageHandler * chandler=0; #if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) return debugCallback; + if (DEBUG_HeavyIsBreakpoint()) return debugCallback; #endif - if (handler->flags & PFLAG_HASCODE) { - /* Find correct Dynamic Block to run */ - chandler=(CodePageHandler *)handler; -findblock:; - CacheBlock * block=chandler->FindCacheBlock(ip_point&4095); - if (!block) { - cache.block.running=0; - block=CreateCacheBlock(ip_point,cpu.code.big,128); -// DYN_LOG("Created block size %x type %d",block->cache.size,block->type); - chandler->AddCacheBlock(block); - if (block->page.end>=4096) { - DYN_LOG("block crosses page boundary"); - } - } -run_block: - BlockReturn ret=gen_runcode(block->cache.start); - switch (ret) { - case BR_Normal: - /* Maybe check if we staying in the same page? */ -#if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) return debugCallback; -#endif - goto restart_core; - case BR_Cycles: -#if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) return debugCallback; -#endif - return CBRET_NONE; - case BR_CallBack: - return core_dyn.callback; - case BR_Opcode: - CPU_CycleLeft+=CPU_Cycles; - CPU_Cycles=1; - return CPU_Core_Normal_Run(); - case BR_Link1: - case BR_Link2: - { - Bitu temp_ip=SegPhys(cs)+reg_eip; - Bitu temp_page=temp_ip >> 12; - CodePageHandler * temp_handler=(CodePageHandler *)paging.tlb.handler[temp_page]; - if (temp_handler->flags & PFLAG_HASCODE) { - block=temp_handler->FindCacheBlock(temp_ip & 4095); - if (!block) goto restart_core; - cache_linkblocks(cache.block.running,block,ret==BR_Link2); - goto run_block; - } - } - goto restart_core; - } - } else { - if (handler->flags & PFLAG_NOCODE) { - LOG_MSG("DYNX86:Can't run code in this page"); - return CPU_Core_Normal_Run(); - } - Bitu phys_page=ip_page; - if (!PAGING_MakePhysPage(phys_page)) { - LOG_MSG("DYNX86:Can't find physpage"); - return CPU_Core_Normal_Run(); - } - chandler=new CodePageHandler(handler); - MEM_SetPageHandler(phys_page,1,chandler); //Setup the handler - PAGING_UnlinkPages(ip_page,1); - goto findblock; + CodePageHandler * chandler=MakeCodePage(ip_page); + if (!chandler) return CPU_Core_Normal_Run(); + /* Find correct Dynamic Block to run */ + CacheBlock * block=chandler->FindCacheBlock(ip_point&4095); + if (!block) { + block=CreateCacheBlock(chandler,ip_point,32); } - return 0; +run_block: + cache.block.running=0; + BlockReturn ret=gen_runcode(block->cache.start); + switch (ret) { + case BR_Normal: + /* Maybe check if we staying in the same page? */ +#if C_HEAVY_DEBUG + if (DEBUG_HeavyIsBreakpoint()) return debugCallback; +#endif + goto restart_core; + case BR_Cycles: +#if C_HEAVY_DEBUG + if (DEBUG_HeavyIsBreakpoint()) return debugCallback; +#endif + return CBRET_NONE; + case BR_CallBack: + return core_dyn.callback; + case BR_Opcode: + CPU_CycleLeft+=CPU_Cycles; + CPU_Cycles=1; + return CPU_Core_Normal_Run(); +#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: + { + Bitu temp_ip=SegPhys(cs)+reg_eip; + Bitu temp_page=temp_ip >> 12; + CodePageHandler * temp_handler=(CodePageHandler *)paging.tlb.handler[temp_page]; + if (temp_handler->flags & PFLAG_HASCODE) { + block=temp_handler->FindCacheBlock(temp_ip & 4095); + if (!block) goto restart_core; + cache.block.running->LinkTo(ret==BR_Link2,block); + goto run_block; + } + } + goto restart_core; + } +return 0; } - void CPU_Core_Dyn_X86_Init(void) { Bits i; /* Setup the global registers and their flags */ diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index d70644f3..348021d1 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -1,28 +1,34 @@ -struct CacheBlock { +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 { - Bit16s start,end; //Where the page is the original code - Bitu first,last; + 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; } cache; - BlockType type; - CodePageHandler * code_page; //Page containing this code - CacheBlock * page_link; //For code crossing a page boundary struct { + Bitu index; CacheBlock * next; } hash; - CacheBlock * list_next; struct { - CacheBlock * to[2]; - CacheBlock * from[DYN_LINKS]; - Bitu index; - } link; - CacheBlock * links[2]; + CacheBlock * to; + CacheBlock * next; + CacheBlock * from; + } link[2]; + CacheBlock * crossblock; }; +class CacheBlock; static struct { struct { CacheBlock * first; @@ -31,96 +37,124 @@ static struct { CacheBlock * running; } block; Bit8u * pos; - CacheBlock linkblocks[2]; + CodePageHandler * free_pages; + CodePageHandler * used_pages; + CodePageHandler * last_page; } cache; static Bit8u cache_code_link_blocks[2][16]; static Bit8u cache_code[CACHE_TOTAL+CACHE_MAXSIZE]; static CacheBlock cache_blocks[CACHE_BLOCKS]; - -static void cache_resetblock(CacheBlock * block); - +static CacheBlock link_blocks[2]; class CodePageHandler :public PageHandler { public: - CodePageHandler(PageHandler * _old_pagehandler) { + CodePageHandler() {} + 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)); } - void InvalidateRange(Bits start,Bits end) { - Bits maps=start>>DYN_HASH_SHIFT; - Bits map=maps; - Bits count=write_map[maps]; - while (map>=0 && count>0) { - CacheBlock * block=hash_map[map]; - CacheBlock * * where=&hash_map[map]; + void InvalidateRange(Bitu start,Bitu end) { + Bits index=1+(start>>DYN_HASH_SHIFT); + while (index>=0) { + Bitu map=0; + for (Bitu count=start;count<=end;count++) map+=write_map[count]; + if (!map) return; + CacheBlock * block=hash_map[index]; while (block) { CacheBlock * nextblock=block->hash.next; - if (start<=block->page.end && end>=block->page.start) { - for (Bitu i=block->page.first;i<=block->page.last;i++) write_map[i]--; - block->code_page=0; //Else resetblock will do double work - count--; - if (block==cache.block.running) LOG_MSG("Writing to current block"); - cache_resetblock(block); - *where=nextblock; - } else { - where=&block->hash.next; - } + if (start<=block->page.end && end>=block->page.start) + block->Clear(); block=nextblock; } - map--; + index--; } } void writeb(PhysPt addr,Bitu val){ - if (val!=host_readb(hostmem+(addr&4095))) { - InvalidateRange(addr&4095,addr&4095); - host_writeb(hostmem+(addr&4095),val); - } + addr&=4095; + host_writeb(hostmem+addr,val); + if (!*(Bit8u*)&write_map[addr]) { + if (active_blocks) return; + active_count--; + if (!active_count) Release(); + } else InvalidateRange(addr,addr); } void writew(PhysPt addr,Bitu val){ - if (val!=host_readw(hostmem+(addr&4095))) { - InvalidateRange(addr&4095,(addr&4095)+1); - host_writew(hostmem+(addr&4095),val); - } + addr&=4095; + host_writew(hostmem+addr,val); + if (!*(Bit16u*)&write_map[addr]) { + if (active_blocks) return; + active_count--; + if (!active_count) Release(); + } else InvalidateRange(addr,addr+1); } void writed(PhysPt addr,Bitu val){ - if (val!=host_readd(hostmem+(addr&4095))) { - InvalidateRange(addr&4095,(addr&4095)+3); - host_writed(hostmem+(addr&4095),val); - } + addr&=4095; + host_writed(hostmem+addr,val); + if (!*(Bit32u*)&write_map[addr]) { + if (active_blocks) return; + active_count--; + if (!active_count) Release(); + } else InvalidateRange(addr,addr+3); } void AddCacheBlock(CacheBlock * block) { - Bit16u first,last; - if (block->page.start<0) first=0; - else first=block->page.start>>DYN_HASH_SHIFT; - block->hash.next=hash_map[first]; - hash_map[first]=block; - if (block->page.end>=4096) last=DYN_PAGE_HASH-1; - else last=block->page.end>>DYN_HASH_SHIFT; - block->page.first=first; - block->page.last=last; - for (;first<=last;first++) { - write_map[first]++; - } - block->code_page=this; + 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) { - CacheBlock * * where=&hash_map[block->page.first]; - while (*where) { - if (*where==block) { - *where=block->hash.next; - break; - } + 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. } - for (Bitu i=block->page.first;i<=block->page.last;i++) { - write_map[i]--; + *where=block->hash.next; + 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[start>>DYN_HASH_SHIFT]; + CacheBlock * block=hash_map[1+(start>>DYN_HASH_SHIFT)]; while (block) { if (block->page.start==start) return block; block=block->hash.next; @@ -131,133 +165,153 @@ public: hostmem=old_pagehandler->GetHostPt(phys_page); return hostmem; } +public: + Bit8u write_map[4096]; + CodePageHandler * next, * prev; private: PageHandler * old_pagehandler; - CacheBlock * hash_map[DYN_PAGE_HASH]; - Bit8u write_map[DYN_PAGE_HASH]; + CacheBlock * hash_map[1+DYN_PAGE_HASH]; + Bitu active_blocks; + Bitu active_count; HostPt hostmem; + Bitu phys_page; }; +static CodePageHandler * MakeCodePage(Bitu lin_page) { + mem_readb(lin_page << 12); //Ensure page contains memory + PageHandler * handler=paging.tlb.handler[lin_page]; + if (handler->flags & PFLAG_HASCODE) return ( CodePageHandler *)handler; + if (handler->flags & PFLAG_NOCODE) { + LOG_MSG("DYNX86:Can't run code in this page"); + return 0; + } + Bitu phys_page=lin_page; + if (!PAGING_MakePhysPage(phys_page)) { + LOG_MSG("DYNX86:Can't find physpage"); + return 0; + } + /* Find a free CodePage */ + if (!cache.free_pages) { + cache.used_pages->ClearRelease(); + } + CodePageHandler * cpagehandler=cache.free_pages; + cache.free_pages=cache.free_pages->next; + cpagehandler->prev=cache.last_page; + cpagehandler->next=0; + if (cache.last_page) cache.last_page->next=cpagehandler; + cache.last_page=cpagehandler; + if (!cache.used_pages) cache.used_pages=cpagehandler; + cpagehandler->SetupAt(phys_page,handler); + MEM_SetPageHandler(phys_page,1,cpagehandler); + PAGING_UnlinkPages(lin_page,1); + return cpagehandler; +} + static INLINE void cache_addunsedblock(CacheBlock * block) { - block->list_next=cache.block.free; + 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->list_next; + cache.block.free=ret->cache.next; + ret->cache.next=0; return ret; } -static INLINE void cache_clearlinkfrom(CacheBlock * block,CacheBlock * from) { - for (Bitu i=0;ilink.from[i]==from) block->link.from[i]=0; +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)->link[ind].next; + } + *wherelink=(*wherelink)->link[ind].next; + } + } else + cache_addunsedblock(this); + if (crossblock) { + crossblock->crossblock=0; + crossblock->Clear(); + crossblock=0; + } + if (page.handler) { + page.handler->DelCacheBlock(this); + page.handler=0; } } -static INLINE void cache_clearlinkto(CacheBlock * block,CacheBlock * to) { - if (block->link.to[0]==to) block->link.to[0]=&cache.linkblocks[0]; - if (block->link.to[1]==to) block->link.to[1]=&cache.linkblocks[1]; -} - -static void cache_linkblocks(CacheBlock * from,CacheBlock * to,Bitu link) { - from->link.to[link]=to; - CacheBlock * clear=to->link.from[to->link.index]; - if (clear) { - DYN_LOG("backlink buffer full"); - cache_clearlinkto(to->link.from[to->link.index],to); - } - to->link.from[to->link.index]=from; - to->link.index++; - if (to->link.index>=DYN_LINKS) to->link.index=0; -} - -static void cache_resetblock(CacheBlock * block) { - Bits i; - DYN_LOG("Resetted block"); - block->type=BT_Free; - /* Clear all links to this block from other blocks */ - for (i=0;ilink.from[i]) cache_clearlinkto(block->link.from[i],block); - block->link.from[i]=0; - } - /* Clear all links from this block to other blocks */ - if (block->link.to[0]!=&cache.linkblocks[0]) { - cache_clearlinkfrom(block->link.to[0],block); - block->link.to[0]=&cache.linkblocks[0]; - } - if (block->link.to[1]!=&cache.linkblocks[1]) { - cache_clearlinkfrom(block->link.to[1],block); - block->link.to[1]=&cache.linkblocks[1]; - } - block->link.index=0; - if (block->code_page) block->code_page->DelCacheBlock(block); -} static CacheBlock * cache_openblock(void) { CacheBlock * block=cache.block.active; /* check for enough space in this block */ Bitu size=block->cache.size; - CacheBlock * nextblock=block->list_next; + CacheBlock * nextblock=block->cache.next; + if (block->page.handler) + block->Clear(); while (sizecache.size; - CacheBlock * tempblock=nextblock->list_next; - if (nextblock->type!=BT_Free) cache_resetblock(nextblock); + CacheBlock * tempblock=nextblock->cache.next; + if (nextblock->page.handler) + nextblock->Clear(); cache_addunsedblock(nextblock); nextblock=tempblock; } skipresize: block->cache.size=size; - block->list_next=nextblock; + block->cache.next=nextblock; cache.pos=block->cache.start; return block; } -static void cache_closeblock(BlockType type) { +static void cache_closeblock(void) { CacheBlock * block=cache.block.active; - /* Setup some structures in the block determined by type */ - block->type=type; - switch (type) { - case BT_Normal: - break; - case BT_SingleLink: - block->link.to[0]=&cache.linkblocks[0]; - break; - case BT_DualLink: - block->link.to[0]=&cache.linkblocks[0]; - block->link.to[1]=&cache.linkblocks[1]; - break; - } + 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->list_next) { - if (written>block->cache.size+CACHE_MAXSIZE) E_Exit("CacheBlock overrun"); - } else E_Exit("CacheBlock overrun"); + 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; - } else new_size=block->cache.size; - CacheBlock * newblock=cache_getblock(); - newblock->cache.start=block->cache.start+new_size; - newblock->cache.size=block->cache.size-new_size; - newblock->list_next=block->list_next; - newblock->type=BT_Free; - block->cache.size=new_size; - block->list_next=newblock; + 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->list_next) { - DYN_LOG("Cache full restarting"); + if (!block->cache.next) { +// LOG_MSG("Cache full restarting"); cache.block.active=cache.block.first; } else { - cache.block.active=block->list_next; + cache.block.active=block->cache.next; } } @@ -283,20 +337,29 @@ static void cache_init(void) { memset(&cache_blocks,0,sizeof(cache_blocks)); cache.block.free=&cache_blocks[0]; for (i=0;icache.start=&cache_code[0]; block->cache.size=CACHE_TOTAL; - block->list_next=0; //Last block in the list + block->cache.next=0; //Last block in the list cache.pos=&cache_code_link_blocks[0][0]; - cache.linkblocks[0].cache.start=cache.pos; + link_blocks[0].cache.start=cache.pos; gen_return(BR_Link1); cache.pos=&cache_code_link_blocks[1][0]; - cache.linkblocks[1].cache.start=cache.pos; + link_blocks[1].cache.start=cache.pos; gen_return(BR_Link2); -} \ No newline at end of file + cache.free_pages=0; + cache.last_page=0; + cache.used_pages=0; + /* Setup the code pages */ + for (i=0;inext=cache.free_pages; + cache.free_pages=newpage; + } +} diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index cc077ec9..4212f92e 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -29,6 +29,13 @@ static struct DynDecode { REP_Type rep; Bitu cycles; CacheBlock * block; + CacheBlock * active_block; + struct { + CodePageHandler * code; + Bitu index; + Bit8u * wmap; + Bitu first; + } page; struct { Bitu val; Bitu mod; @@ -38,15 +45,46 @@ static struct DynDecode { DynReg * segprefix; } decode; -static Bit8u INLINE decode_fetchb(void) { - return mem_readb(decode.code++); +static Bit8u decode_fetchb(void) { + if (decode.page.index>=4096) { + /* Advance to the next page */ + decode.active_block->page.end=4095; + decode.page.code=MakeCodePage(++decode.page.first); + CacheBlock * newblock=cache_getblock(); + decode.active_block->crossblock=newblock; + newblock->crossblock=decode.active_block; + decode.active_block=newblock; + decode.active_block->page.start=0; + decode.page.code->AddCrossBlock(decode.active_block); + decode.page.wmap=decode.page.code->write_map; + decode.page.index=0; + } + decode.page.wmap[decode.page.index]+=0x01; + decode.page.index++; + decode.code+=1; + return mem_readb(decode.code-1); } -static Bit16u INLINE decode_fetchw(void) { - decode.code+=2; +static Bit16u decode_fetchw(void) { + if (decode.page.index>=4095) { + Bit16u val=decode_fetchb(); + val|=decode_fetchb() << 8; + return val; + } + *(Bit16u *)&decode.page.wmap[decode.page.index]+=0x0101; + decode.code+=2;decode.page.index+=2; return mem_readw(decode.code-2); } -static Bit32u INLINE decode_fetchd(void) { - decode.code+=4; +static Bit32u decode_fetchd(void) { + if (decode.page.index>=4093) { + Bit32u val=decode_fetchb(); + val|=decode_fetchb() << 8; + val|=decode_fetchb() << 16; + val|=decode_fetchb() << 24; + return val; + /* Advance to the next page */ + } + *(Bit32u *)&decode.page.wmap[decode.page.index]+=0x01010101; + decode.code+=4;decode.page.index+=4; return mem_readd(decode.code-4); } @@ -71,13 +109,14 @@ static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { static void dyn_reduce_cycles(void) { + if (!decode.cycles) decode.cycles++; gen_lea(DREG(CYCLES),DREG(CYCLES),0,0,-(Bits)decode.cycles); gen_releasereg(DREG(CYCLES)); } static void dyn_push(DynReg * dynreg) { - gen_storeflags(); + gen_protectflags(); if (decode.big_op) { gen_dop_word_imm(DOP_SUB,true,DREG(ESP),4); } else { @@ -93,11 +132,10 @@ static void dyn_push(DynReg * dynreg) { gen_call_function((void *)&mem_writew,"%Drd%Dd",DREG(STACK),dynreg); } gen_releasereg(DREG(STACK)); - gen_restoreflags(); } static void dyn_pop(DynReg * dynreg) { - gen_storeflags(); + gen_protectflags(); gen_dop_word(DOP_MOV,true,DREG(STACK),DREG(ESP)); gen_dop_word(DOP_AND,true,DREG(STACK),DREG(SMASK)); gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); @@ -114,7 +152,6 @@ static void dyn_pop(DynReg * dynreg) { } } gen_releasereg(DREG(STACK)); - gen_restoreflags(); } static void INLINE dyn_get_modrm(void) { @@ -238,10 +275,12 @@ static void dyn_dop_ebgb(DualOps op) { if (decode.modrm.mod<3) { dyn_fill_ea(); dyn_read_byte(DREG(EA),DREG(TMPB),false); + if (op<=DOP_TEST) gen_needflags(); gen_dop_byte(op,DREG(TMPB),0,rm_reg,decode.modrm.reg&4); dyn_write_byte(DREG(EA),DREG(TMPB),false); gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB)); } else { + if (op<=DOP_TEST) gen_needflags(); gen_dop_byte(op,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,rm_reg,decode.modrm.reg&4); } } @@ -252,9 +291,11 @@ static void dyn_dop_gbeb(DualOps op) { if (decode.modrm.mod<3) { dyn_fill_ea(); dyn_read_byte(DREG(EA),DREG(TMPB),false); + if (op<=DOP_TEST) gen_needflags(); gen_dop_byte(op,rm_reg,decode.modrm.reg&4,DREG(TMPB),0); gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB)); } else { + if (op<=DOP_TEST) gen_needflags(); gen_dop_byte(op,rm_reg,decode.modrm.reg&4,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); } } @@ -302,10 +343,12 @@ static void dyn_dop_evgv(DualOps op) { if (decode.modrm.mod<3) { dyn_fill_ea(); dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); + if (op<=DOP_TEST) gen_needflags(); gen_dop_word(op,decode.big_op,DREG(TMPW),rm_reg); dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPW)); } else { + if (op<=DOP_TEST) gen_needflags(); gen_dop_word(op,decode.big_op,&DynRegs[decode.modrm.rm],rm_reg); } } @@ -319,6 +362,7 @@ static void dyn_imul_gvev(Bitu immsize) { } else { src=&DynRegs[decode.modrm.rm]; } + gen_needflags(); switch (immsize) { case 0:gen_imul_word(decode.big_op,rm_reg,src);break; case 1:gen_imul_word_imm(decode.big_op,rm_reg,src,(Bit8s)decode_fetchb());break; @@ -334,9 +378,11 @@ static void dyn_dop_gvev(DualOps op) { if (decode.modrm.mod<3) { dyn_fill_ea(); dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); + if (op<=DOP_TEST) gen_needflags(); gen_dop_word(op,decode.big_op,rm_reg,DREG(TMPW)); gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPW)); } else { + if (op<=DOP_TEST) gen_needflags(); gen_dop_word(op,decode.big_op,rm_reg,&DynRegs[decode.modrm.rm]); } } @@ -413,6 +459,7 @@ static void dyn_dshift_ev_gv(bool left,bool immediate) { dyn_fill_ea();ea_reg=DREG(TMPW); dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); } else ea_reg=&DynRegs[decode.modrm.rm]; + gen_needflags(); if (immediate) gen_dshift_imm(decode.big_op,left,ea_reg,rm_reg,decode_fetchb()); else gen_dshift_cl(decode.big_op,left,ea_reg,rm_reg,DREG(ECX)); if (decode.modrm.mod<3) { @@ -428,10 +475,12 @@ static void dyn_grp1_eb_ib(void) { if (decode.modrm.mod<3) { dyn_fill_ea(); dyn_read_byte(DREG(EA),DREG(TMPB),false); + gen_needflags(); gen_dop_byte_imm(grp1_table[decode.modrm.reg],DREG(TMPB),0,decode_fetchb()); if (grp1_table[decode.modrm.reg]!=DOP_CMP) dyn_write_byte(DREG(EA),DREG(TMPB),false); gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB)); } else { + gen_needflags(); gen_dop_byte_imm(grp1_table[decode.modrm.reg],&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,decode_fetchb()); } } @@ -442,11 +491,13 @@ static void dyn_grp1_ev_ivx(bool withbyte) { dyn_fill_ea(); dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); Bits imm=withbyte ? (Bit8s)decode_fetchb() : (decode.big_op ? decode_fetchd(): decode_fetchw()); + gen_needflags(); gen_dop_word_imm(grp1_table[decode.modrm.reg],decode.big_op,DREG(TMPW),imm); dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPW)); } else { Bits imm=withbyte ? (Bit8s)decode_fetchb() : (decode.big_op ? decode_fetchd(): decode_fetchw()); + gen_needflags(); gen_dop_word_imm(grp1_table[decode.modrm.reg],decode.big_op,&DynRegs[decode.modrm.rm],imm); } } @@ -472,6 +523,7 @@ static void dyn_grp2_eb(grp2_types type) { case grp2_1:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,1);break; case grp2_imm:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,decode_fetchb());break; } + gen_needflags(); gen_shift_byte(grp2_table[decode.modrm.reg],shift,DREG(TMPB),0); dyn_write_byte(DREG(EA),DREG(TMPB),false); gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB));gen_releasereg(DREG(SHIFT)); @@ -482,6 +534,7 @@ static void dyn_grp2_eb(grp2_types type) { case grp2_1:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,1);break; case grp2_imm:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,decode_fetchb());break; } + gen_needflags(); gen_shift_byte(grp2_table[decode.modrm.reg],shift,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); gen_releasereg(DREG(SHIFT)); } @@ -498,6 +551,7 @@ static void dyn_grp2_ev(grp2_types type) { case grp2_1:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,1);break; case grp2_imm:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,decode_fetchb());break; } + gen_needflags(); gen_shift_word(grp2_table[decode.modrm.reg],shift,decode.big_op,DREG(TMPW)); dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPW));gen_releasereg(DREG(SHIFT)); @@ -508,6 +562,7 @@ static void dyn_grp2_ev(grp2_types type) { case grp2_1:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,1);break; case grp2_imm:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,decode_fetchb());break; } + gen_needflags(); gen_shift_word(grp2_table[decode.modrm.reg],shift,decode.big_op,&DynRegs[decode.modrm.rm]); gen_releasereg(DREG(SHIFT)); } @@ -526,26 +581,26 @@ static void dyn_grp3_eb(void) { } switch (decode.modrm.reg) { case 0x0: /* test eb,ib */ - gen_dop_byte_imm(DOP_TEST,src,src_i,decode_fetchb()); + gen_needflags();gen_dop_byte_imm(DOP_TEST,src,src_i,decode_fetchb()); goto skipsave; case 0x2: /* NOT Eb */ - gen_sop_byte(SOP_NOT,src,src_i); + gen_needflags();gen_sop_byte(SOP_NOT,src,src_i); break; case 0x3: /* NEG Eb */ - gen_sop_byte(SOP_NEG,src,src_i); + gen_needflags();gen_sop_byte(SOP_NEG,src,src_i); break; case 0x4: /* mul Eb */ - gen_mul_byte(false,DREG(EAX),src,src_i); + gen_needflags();gen_mul_byte(false,DREG(EAX),src,src_i); goto skipsave; case 0x5: /* imul Eb */ - gen_mul_byte(true,DREG(EAX),src,src_i); + gen_needflags();gen_mul_byte(true,DREG(EAX),src,src_i); goto skipsave; case 0x6: /* div Eb */ case 0x7: /* idiv Eb */ /* EAX could be used, so precache it */ if (decode.modrm.mod==3) gen_dop_byte(DOP_MOV,DREG(TMPB),0,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); - gen_storeflags();gen_releasereg(DREG(EAX)); + gen_releasereg(DREG(EAX)); gen_call_function((decode.modrm.reg==6) ? (void *)&dyn_helper_divb : (void *)&dyn_helper_idivb, "%Rd%Drl",DREG(TMPB),DREG(TMPB)); gen_dop_word(DOP_OR,true,DREG(TMPB),DREG(TMPB)); @@ -553,14 +608,13 @@ static void dyn_grp3_eb(void) { dyn_savestate(&state); dyn_reduce_cycles(); gen_lea(DREG(EIP),DREG(EIP),0,0,decode.op_start-decode.code_start); - dyn_save_flags(true); + dyn_save_flags(); dyn_releaseregs(); gen_call_function((void *)&CPU_Exception,"%Id%Id",0,0); dyn_load_flags(); gen_return(BR_Normal); dyn_loadstate(&state); gen_fill_branch(branch); - gen_restoreflags(); goto skipsave; } /* Save the result if memory op */ @@ -578,26 +632,26 @@ static void dyn_grp3_ev(void) { } else src=&DynRegs[decode.modrm.rm]; switch (decode.modrm.reg) { case 0x0: /* test ev,iv */ - gen_dop_word_imm(DOP_TEST,decode.big_op,src,decode.big_op ? decode_fetchd() : decode_fetchw()); + gen_needflags();gen_dop_word_imm(DOP_TEST,decode.big_op,src,decode.big_op ? decode_fetchd() : decode_fetchw()); goto skipsave; case 0x2: /* NOT Ev */ - gen_sop_word(SOP_NOT,decode.big_op,src); + gen_needflags();gen_sop_word(SOP_NOT,decode.big_op,src); break; case 0x3: /* NEG Eb */ - gen_sop_word(SOP_NEG,decode.big_op,src); + gen_needflags();gen_sop_word(SOP_NEG,decode.big_op,src); break; case 0x4: /* mul Eb */ - gen_mul_word(false,DREG(EAX),DREG(EDX),decode.big_op,src); + gen_needflags();gen_mul_word(false,DREG(EAX),DREG(EDX),decode.big_op,src); goto skipsave; case 0x5: /* imul Eb */ - gen_mul_word(true,DREG(EAX),DREG(EDX),decode.big_op,src); + gen_needflags();gen_mul_word(true,DREG(EAX),DREG(EDX),decode.big_op,src); goto skipsave; case 0x6: /* div Eb */ case 0x7: /* idiv Eb */ /* EAX could be used, so precache it */ if (decode.modrm.mod==3) gen_dop_word(DOP_MOV,decode.big_op,DREG(TMPW),&DynRegs[decode.modrm.rm]); - gen_storeflags();gen_releasereg(DREG(EAX));gen_releasereg(DREG(EDX)); + gen_releasereg(DREG(EAX));gen_releasereg(DREG(EDX)); void * func=(decode.modrm.reg==6) ? (decode.big_op ? (void *)&dyn_helper_divd : (void *)&dyn_helper_divw) : (decode.big_op ? (void *)&dyn_helper_idivd : (void *)&dyn_helper_idivw); @@ -607,14 +661,13 @@ static void dyn_grp3_ev(void) { dyn_savestate(&state); dyn_reduce_cycles(); gen_lea(DREG(EIP),DREG(EIP),0,0,decode.op_start-decode.code_start); - dyn_save_flags(true); + dyn_save_flags(); dyn_releaseregs(); gen_call_function((void *)&CPU_Exception,"%Id%Id",0,0); dyn_load_flags(); gen_return(BR_Normal); dyn_loadstate(&state); gen_fill_branch(branch); - gen_restoreflags(); goto skipsave; } /* Save the result if memory op */ @@ -639,7 +692,7 @@ static void dyn_mov_ev_seg(void) { static void dyn_load_seg(SegNames seg,DynReg * src,bool withpop) { if (cpu.pmode) { Bit8u * branch;DynState state; - gen_storeflags(); + gen_protectflags(); gen_call_function((void *)&CPU_SetSegGeneral,"%Rd%Id%Drw",DREG(TMPB),seg,src); gen_dop_byte(DOP_OR,DREG(TMPB),0,DREG(TMPB),0); branch=gen_create_branch(BR_Z); @@ -647,14 +700,13 @@ static void dyn_load_seg(SegNames seg,DynReg * src,bool withpop) { dyn_reduce_cycles(); if (withpop) gen_dop_word_imm(DOP_SUB,true,DREG(ESP),decode.big_op ? 4 : 2); gen_dop_word_imm(DOP_ADD,true,DREG(EIP),decode.op_start-decode.code_start); - dyn_save_flags(true); + dyn_save_flags(); dyn_releaseregs(); gen_call_function((void *)&CPU_StartException,""); dyn_load_flags(); gen_return(BR_Normal); dyn_loadstate(&state); gen_fill_branch(branch); - gen_restoreflags(); } else { //TODO Maybe just calculate the base directly if in realmode gen_call_function((void *)&CPU_SetSegGeneral,"%Id%Drw",seg,src); @@ -698,15 +750,12 @@ static void dyn_push_seg(SegNames seg) { } static void dyn_pop_seg(SegNames seg) { - gen_storeflags(); dyn_pop(DREG(TMPW)); dyn_load_seg(seg,DREG(TMPW),true); gen_releasereg(DREG(TMPW)); - gen_restoreflags(); } static void dyn_pop_ev(void) { - gen_storeflags(); dyn_pop(DREG(TMPW)); dyn_get_modrm(); if (decode.modrm.mod<3) { @@ -717,11 +766,10 @@ static void dyn_pop_ev(void) { gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],DREG(TMPW)); } gen_releasereg(DREG(TMPW)); - gen_restoreflags(); } static void dyn_leave(void) { - gen_storeflags(); + gen_protectflags(); gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(SMASK)); gen_sop_word(SOP_NOT,true,DREG(TMPW)); gen_dop_word(DOP_AND,true,DREG(ESP),DREG(TMPW)); @@ -730,7 +778,6 @@ static void dyn_leave(void) { gen_dop_word(DOP_OR,true,DREG(ESP),DREG(TMPW)); dyn_pop(DREG(EBP)); gen_releasereg(DREG(TMPW)); - gen_restoreflags(); } static void dyn_segprefix(SegNames seg) { @@ -738,14 +785,10 @@ static void dyn_segprefix(SegNames seg) { decode.segprefix=&DynRegs[G_ES+seg]; } -static void dyn_closeblock(BlockType type) { +static void dyn_closeblock(void) { //Shouldn't create empty block normally but let's do it like this - if (decode.code>decode.code_start) decode.code--; - Bitu start_page=decode.code_start >> 12; - Bitu end_page=decode.code>>12; - decode.block->page.start=(Bit16s)decode.code_start & 4095; - decode.block->page.end=(Bit16s)((end_page-start_page)*4096+(decode.code&4095)); - cache_closeblock(type); + gen_protectflags(); + cache_closeblock(); } static void dyn_normal_exit(BlockReturn code) { @@ -753,36 +796,35 @@ static void dyn_normal_exit(BlockReturn code) { dyn_reduce_cycles(); dyn_releaseregs(); gen_return(code); - dyn_closeblock(BT_Normal); + dyn_closeblock(); } static void dyn_exit_link(bool dword,Bits eip_change) { + gen_protectflags(); gen_lea(DREG(EIP),DREG(EIP),0,0,(decode.code-decode.code_start)+eip_change); if (!dword) gen_extend_word(false,DREG(EIP),DREG(EIP)); dyn_reduce_cycles(); dyn_releaseregs(); -// gen_return(BR_Normal); - gen_jmp_ptr(&decode.block->link.to[0],offsetof(CacheBlock,cache.start)); - dyn_closeblock(BT_SingleLink); + gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); + dyn_closeblock(); } static void dyn_branched_exit(BranchTypes btype,Bit32s eip_add) { dyn_reduce_cycles(); dyn_releaseregs(); Bitu eip_base=decode.code-decode.code_start; + gen_needflags();gen_protectflags(); Bit8u * data=gen_create_branch(btype); /* Branch not taken */ gen_lea(DREG(EIP),DREG(EIP),0,0,eip_base); gen_releasereg(DREG(EIP)); -// gen_return(BR_Normal); - gen_jmp_ptr(&decode.block->link.to[0],offsetof(CacheBlock,cache.start)); + gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); gen_fill_branch(data); /* Branch taken */ gen_lea(DREG(EIP),DREG(EIP),0,0,eip_base+eip_add); gen_releasereg(DREG(EIP)); -// gen_return(BR_Normal); - gen_jmp_ptr(&decode.block->link.to[1],offsetof(CacheBlock,cache.start)); - dyn_closeblock(BT_DualLink); + gen_jmp_ptr(&decode.block->link[1].to,offsetof(CacheBlock,cache.start)); + dyn_closeblock(); } enum LoopTypes { @@ -790,16 +832,15 @@ enum LoopTypes { }; static void dyn_loop(LoopTypes type) { + gen_protectflags(); Bits eip_add=(Bit8s)decode_fetchb(); Bitu eip_base=decode.code-decode.code_start; - gen_storeflags(); dyn_reduce_cycles(); Bit8u * branch1; Bit8u * branch2=0; gen_sop_word(SOP_DEC,decode.big_addr,DREG(ECX)); dyn_releaseregs(); branch1=gen_create_branch(BR_Z); - gen_restoreflags(true); switch (type) { case LOOP_NONE: break; @@ -812,30 +853,29 @@ static void dyn_loop(LoopTypes type) { } gen_lea(DREG(EIP),DREG(EIP),0,0,eip_base+eip_add); gen_releasereg(DREG(EIP)); - gen_jmp_ptr(&decode.block->link.to[0],offsetof(CacheBlock,cache.start)); + gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); gen_fill_branch(branch1); if (branch2) gen_fill_branch(branch2); /* Branch taken */ - gen_restoreflags(); gen_lea(DREG(EIP),DREG(EIP),0,0,eip_base); gen_releasereg(DREG(EIP)); - gen_jmp_ptr(&decode.block->link.to[1],offsetof(CacheBlock,cache.start)); - dyn_closeblock(BT_DualLink); + gen_jmp_ptr(&decode.block->link[1].to,offsetof(CacheBlock,cache.start)); + dyn_closeblock(); } static void dyn_ret_near(Bitu bytes) { + gen_protectflags(); dyn_reduce_cycles(); //TODO maybe AND eip 0xffff, but shouldn't be needed - gen_storeflags(); dyn_pop(DREG(EIP)); if (bytes) gen_dop_word_imm(DOP_ADD,true,DREG(ESP),bytes); dyn_releaseregs(); - gen_restoreflags(); gen_return(BR_Normal); - dyn_closeblock(BT_Normal); + dyn_closeblock(); } static void dyn_ret_far(Bitu bytes) { + gen_protectflags(); dyn_reduce_cycles(); //TODO maybe AND eip 0xffff, but shouldn't be needed gen_lea(DREG(EIP),DREG(EIP),0,0,decode.code-decode.code_start); @@ -845,7 +885,7 @@ static void dyn_ret_far(Bitu bytes) { dyn_load_flags(); dyn_releaseregs();; gen_return(BR_Normal); - dyn_closeblock(BT_Normal); + dyn_closeblock(); } static void dyn_call_near_imm(void) { @@ -858,13 +898,14 @@ static void dyn_call_near_imm(void) { if (!decode.big_op) gen_extend_word(false,DREG(EIP),DREG(EIP)); dyn_reduce_cycles(); dyn_releaseregs(); - gen_return(BR_Normal); -// gen_jmp_ptr(&decode.block->link.to[0],offsetof(CacheBlock,cache.start)); - dyn_closeblock(BT_SingleLink); +// gen_return(BR_Normal); + gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); + dyn_closeblock(); } static void dyn_call_far_imm(void) { Bitu sel,off; + gen_protectflags(); off=decode.big_op ? decode_fetchd() : decode_fetchw(); sel=decode_fetchw(); dyn_reduce_cycles(); @@ -875,11 +916,12 @@ static void dyn_call_far_imm(void) { dyn_load_flags(); dyn_releaseregs(); gen_return(BR_Normal); - dyn_closeblock(BT_Normal); + dyn_closeblock(); } static void dyn_jmp_far_imm(void) { Bitu sel,off; + gen_protectflags(); off=decode.big_op ? decode_fetchd() : decode_fetchw(); sel=decode_fetchw(); dyn_reduce_cycles(); @@ -890,10 +932,11 @@ static void dyn_jmp_far_imm(void) { dyn_load_flags(); dyn_releaseregs(); gen_return(BR_Normal); - dyn_closeblock(BT_Normal); + dyn_closeblock(); } static void dyn_iret(void) { + gen_protectflags(); dyn_save_flags(); dyn_reduce_cycles(); gen_dop_word_imm(DOP_ADD,true,DREG(EIP),decode.code-decode.code_start); @@ -902,10 +945,11 @@ static void dyn_iret(void) { dyn_load_flags(); dyn_releaseregs(); gen_return(BR_Normal); - dyn_closeblock(BT_CheckFlags); + dyn_closeblock(); } static void dyn_interrupt(Bitu num) { + gen_protectflags(); dyn_save_flags(); dyn_reduce_cycles(); gen_dop_word_imm(DOP_ADD,true,DREG(EIP),decode.code-decode.code_start); @@ -914,15 +958,23 @@ static void dyn_interrupt(Bitu num) { dyn_load_flags(); dyn_releaseregs(); gen_return(BR_Normal); - dyn_closeblock(BT_Normal); + dyn_closeblock(); } -static CacheBlock * CreateCacheBlock(PhysPt start,bool big,Bitu max_opcodes) { +static CacheBlock * CreateCacheBlock(CodePageHandler * codepage,PhysPt start,Bitu max_opcodes) { Bits i; +/* Init a load of variables */ decode.code_start=start; decode.code=start; Bitu cycles=0; - decode.block=cache_openblock(); + decode.page.code=codepage; + decode.page.index=start&4095; + decode.page.wmap=codepage->write_map; + decode.page.first=start >> 12; + decode.active_block=decode.block=cache_openblock(); + decode.block->page.start=decode.page.index; + codepage->AddCacheBlock(decode.block); + gen_save_host_direct(&cache.block.running,(Bit32u)decode.block); for (i=0;i=G_EAX;i--) { dyn_pop((i!=G_ESP) ? &DynRegs[i] : DREG(TMPW)); } - gen_restoreflags();gen_releasereg(DREG(TMPW)); + gen_releasereg(DREG(TMPW)); break; //segprefix FS,GS case 0x64:dyn_segprefix(fs);goto restart_prefix; case 0x65:dyn_segprefix(gs);goto restart_prefix; //Push immediates //Operand size - case 0x66:decode.big_op=!big;goto restart_prefix; + case 0x66:decode.big_op=!cpu.code.big;;goto restart_prefix; //Address size - case 0x67:decode.big_addr=!big;goto restart_prefix; + case 0x67:decode.big_addr=!cpu.code.big;goto restart_prefix; case 0x68: /* PUSH Iv */ gen_dop_word_imm(DOP_MOV,decode.big_op,DREG(TMPW),decode.big_op ? decode_fetchd() : decode_fetchw()); dyn_push(DREG(TMPW)); @@ -1117,7 +1163,7 @@ restart_prefix: 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()); - return decode.block; + goto finish_block; /* Group 1 */ case 0x80:dyn_grp1_eb_ib();break; case 0x81:dyn_grp1_ev_ivx(false);break; @@ -1155,10 +1201,6 @@ restart_prefix: break; /* CBW/CWDE */ case 0x98: - /* - if (decode.big_op) gen_extend_word(true,DREG(EAX),DREG(EAX)); - else gen_extend_byte(true,false,DREG(EAX),DREG(EAX),0); - */ gen_cbw(decode.big_op,DREG(EAX)); break; /* CWD/CDQ */ @@ -1166,7 +1208,7 @@ restart_prefix: gen_cwd(decode.big_op,DREG(EAX),DREG(EDX)); break; /* CALL FAR Ip */ - case 0x9a:dyn_call_far_imm();return decode.block; + case 0x9a:dyn_call_far_imm();goto finish_block; /* MOV AL,direct addresses */ case 0xa0: gen_lea(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),0,0, @@ -1199,8 +1241,8 @@ restart_prefix: case 0xa4:dyn_string(STR_MOVSB);break; case 0xa5:dyn_string(decode.big_op ? STR_MOVSD : STR_MOVSW);break; /* TEST AL,AX Imm */ - case 0xa8:gen_dop_byte_imm(DOP_TEST,DREG(EAX),0,decode_fetchb());break; - case 0xa9:gen_dop_word_imm(DOP_TEST,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; + case 0xa8:gen_needflags();gen_dop_byte_imm(DOP_TEST,DREG(EAX),0,decode_fetchb());break; + case 0xa9:gen_needflags();gen_dop_word_imm(DOP_TEST,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; /* STOSB/W/D*/ case 0xaa:dyn_string(STR_STOSB);break; case 0xab:dyn_string(decode.big_op ? STR_STOSD : STR_STOSW);break; @@ -1215,12 +1257,13 @@ restart_prefix: case 0xb8:case 0xb9:case 0xba:case 0xbb:case 0xbc:case 0xbd:case 0xbe:case 0xbf: gen_dop_word_imm(DOP_MOV,decode.big_op,&DynRegs[opcode&7],decode.big_op ? decode_fetchd() : decode_fetchw());break; break; + //GRP2 Eb/Ev,Ib case 0xc0:dyn_grp2_eb(grp2_imm);break; case 0xc1:dyn_grp2_ev(grp2_imm);break; //RET near Iw / Ret - case 0xc2:dyn_ret_near(decode_fetchw());return decode.block; - case 0xc3:dyn_ret_near(0);return decode.block; + case 0xc2:dyn_ret_near(decode_fetchw());goto finish_block; + case 0xc3:dyn_ret_near(0);goto finish_block; //LES/LDS case 0xc4:dyn_load_seg_off_ea(es);break; case 0xc5:dyn_load_seg_off_ea(ds);break; @@ -1230,12 +1273,12 @@ restart_prefix: // LEAVE case 0xc9:dyn_leave();break; //RET far Iw / Ret - case 0xca:dyn_ret_far(decode_fetchw());return decode.block; - case 0xcb:dyn_ret_far(0);return decode.block; + case 0xca:dyn_ret_far(decode_fetchw());goto finish_block; + case 0xcb:dyn_ret_far(0);goto finish_block; /* Interrupt */ - case 0xcd:dyn_interrupt(decode_fetchb());return decode.block; + case 0xcd:dyn_interrupt(decode_fetchb());goto finish_block; /* IRET */ - case 0xcf:dyn_iret();return decode.block; + case 0xcf:dyn_iret();goto finish_block; //GRP2 Eb/Ev,1 case 0xd0:dyn_grp2_eb(grp2_1);break; case 0xd1:dyn_grp2_ev(grp2_1);break; @@ -1243,7 +1286,7 @@ restart_prefix: case 0xd2:dyn_grp2_eb(grp2_cl);break; case 0xd3:dyn_grp2_ev(grp2_cl);break; //Loop's - case 0xe2:dyn_loop(LOOP_NONE);return decode.block; + case 0xe2:dyn_loop(LOOP_NONE);goto finish_block; //IN AL/AX,imm case 0xe4:gen_call_function((void*)&IO_ReadB,"%Id%Rl",decode_fetchb(),DREG(EAX));break; case 0xe5: @@ -1264,14 +1307,15 @@ restart_prefix: break; case 0xe8: /* CALL Ivx */ dyn_call_near_imm(); - return decode.block; + goto finish_block; case 0xe9: /* Jmp Ivx */ dyn_exit_link(decode.big_op,decode.big_op ? (Bit32s)decode_fetchd() : (Bit16s)decode_fetchw()); - return decode.block; - /* CALL FAR Ip */ - case 0xea:dyn_jmp_far_imm();return decode.block; - /* Jmp Ibx */ - case 0xeb:dyn_exit_link(decode.big_op,(Bit8s)decode_fetchb());return decode.block; + goto finish_block; + case 0xea: /* JMP FAR Ip */ + dyn_jmp_far_imm(); + goto finish_block; + /* Jmp Ibx */ + case 0xeb:dyn_exit_link(decode.big_op,(Bit8s)decode_fetchb());goto finish_block; /* IN AL/AX,DX*/ case 0xec:gen_call_function((void*)&IO_ReadB,"%Dw%Rl",DREG(EDX),DREG(EAX));break; case 0xed: @@ -1290,6 +1334,7 @@ restart_prefix: gen_call_function((void*)&IO_WriteW,"%Dw%Dw",DREG(EDX),DREG(EAX)); } break; + case 0xf2: //REPNE/NZ decode.rep=REP_NZ; goto restart_prefix; @@ -1300,20 +1345,19 @@ restart_prefix: case 0xf5: //CMC case 0xf8: //CLC case 0xf9: //STC + gen_needflags(); cache_addb(opcode);break; /* GRP 3 Eb/EV */ case 0xf6:dyn_grp3_eb();break; case 0xf7:dyn_grp3_ev();break; /* Change interrupt flag */ case 0xfa: //CLI - gen_storeflags(); + gen_protectflags(); gen_dop_word_imm(DOP_AND,true,DREG(FLAGS),~FLAG_IF); - gen_restoreflags(); break; case 0xfb: //STI - gen_storeflags(); + gen_protectflags(); gen_dop_word_imm(DOP_OR,true,DREG(FLAGS),FLAG_IF); - gen_restoreflags(); if (max_opcodes<=0) max_opcodes=1; //Allow 1 extra opcode break; /* GRP 4 Eb and callback's */ @@ -1324,10 +1368,12 @@ restart_prefix: case 0x1://DEC Eb if (decode.modrm.mod<3) { dyn_fill_ea();dyn_read_byte(DREG(EA),DREG(TMPB),false); + gen_needflags(); gen_sop_byte(decode.modrm.reg==0 ? SOP_INC : SOP_DEC,DREG(TMPB),0); dyn_write_byte(DREG(EA),DREG(TMPB),false); gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB)); } else { + gen_needflags(); gen_sop_byte(decode.modrm.reg==0 ? SOP_INC : SOP_DEC, &DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); } @@ -1338,10 +1384,11 @@ restart_prefix: dyn_reduce_cycles(); dyn_releaseregs(); gen_return(BR_CallBack); - dyn_closeblock(BT_Normal); - return decode.block; + dyn_closeblock(); + goto finish_block; } break; + case 0xff: { dyn_get_modrm();DynReg * src; @@ -1353,6 +1400,7 @@ restart_prefix: switch (decode.modrm.reg) { case 0x0://INC Ev case 0x1://DEC Ev + gen_needflags(); gen_sop_word(decode.modrm.reg==0 ? SOP_INC : SOP_DEC,decode.big_op,src); if (decode.modrm.mod<3){ dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); @@ -1398,14 +1446,27 @@ core_close_block: dyn_reduce_cycles(); dyn_releaseregs(); gen_return(BR_Normal); - dyn_closeblock(BT_Normal); - return decode.block; + dyn_closeblock(); + goto finish_block; illegalopcode: - decode.code=decode.op_start; - gen_lea(DREG(EIP),DREG(EIP),0,0,decode.code-decode.code_start); + gen_lea(DREG(EIP),DREG(EIP),0,0,decode.op_start-decode.code_start); dyn_reduce_cycles(); dyn_releaseregs(); gen_return(BR_Opcode); - dyn_closeblock(BT_Normal); + dyn_closeblock(); + goto finish_block; +#if (C_DEBUG) +illegalopcodefull: + gen_lea(DREG(EIP),DREG(EIP),0,0,decode.op_start-decode.code_start); + dyn_reduce_cycles(); + dyn_releaseregs(); + gen_return(BR_OpcodeFull); + dyn_closeblock(); + goto finish_block; +#endif +finish_block: + /* Setup the correct end-address */ + decode.active_block->page.end=--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; } diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index ad1e4d74..9611e0ea 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -32,8 +32,8 @@ static void gen_init(void); #define X86_REG_MASK(_REG_) (1 << X86_REG_ ## _REG_) static struct { + bool flagsactive; Bitu last_used; - Bitu stored_flags; GenReg * regs[X86_REGS]; } x86gen; @@ -98,13 +98,13 @@ static BlockReturn gen_runcode(Bit8u * code) { push edi mov ebx,[reg_flags] and ebx,FMASK_TEST + push offset(return_address) push ebx - popfd - call eax + jmp eax /* Restore the flags */ - pushfd +return_address: + /* return here with flags in ecx */ and dword ptr [reg_flags],~FMASK_TEST - pop ecx and ecx,FMASK_TEST or [reg_flags],ecx pop edi @@ -114,23 +114,17 @@ static BlockReturn gen_runcode(Bit8u * code) { mov [retval],eax } #else + register Bit32u tempflags=reg_flags & FMASK_TEST; __asm__ volatile ( - "movl %1,%%esi \n" - "andl %2,%%esi \n" - "pushl %%ebp \n" - "pushl %%esi \n" - "popfl \n" - "calll *%4 \n" - "popl %%ebp \n" - "pushfl \n" - "andl %3,(%1) \n" - "popl %%esi \n" - "andl %2,%%esi \n" - "orl %%esi,(%1) \n" - :"=a" (retval) - :"m" (reg_flags), "n" (FMASK_TEST),"n" (~FMASK_TEST),"r" (code) - :"%ecx","%edx","%ebx","%edi","%esi","cc","memory" + "pushl $(run_return_adress) \n" + "pushl %2 \n" + "jmp *%3 \n" + "run_return_adress: \n" + :"=a" (retval), "=c" (tempflags) + :"r" (tempflags),"r" (code) + :"%edx","%ebx","%edi","%esi","cc","memory" ); + reg_flags=(reg_flags & ~FMASK_TEST) | (tempflags & FMASK_TEST); #endif return retval; } @@ -232,28 +226,23 @@ static void gen_synchreg(DynReg * dnew,DynReg * dsynch) { } } -static void gen_storeflags(void) { - if (!x86gen.stored_flags) { - cache_addb(0x9c); //PUSHFD +static void gen_needflags(void) { + if (!x86gen.flagsactive) { + x86gen.flagsactive=true; + cache_addb(0x9d); //POPFD } - x86gen.stored_flags++; } -static void gen_restoreflags(bool noreduce=false) { - if (noreduce) { - cache_addb(0x9d); - return; +static void gen_protectflags(void) { + if (x86gen.flagsactive) { + x86gen.flagsactive=false; + cache_addb(0x9c); //PUSHFD } - if (x86gen.stored_flags) { - x86gen.stored_flags--; - if (!x86gen.stored_flags) - cache_addb(0x9d); //POPFD - } else IllegalOption(); } static void gen_reinit(void) { x86gen.last_used=0; - x86gen.stored_flags=0; + x86gen.flagsactive=false; for (Bitu i=0;idynreg=0; } @@ -604,7 +593,7 @@ static void gen_call_function(void * func,char * ops,...) { x86gen.regs[X86_REG_EAX]->Clear(); x86gen.regs[X86_REG_EAX]->notusable=true;; /* Save the flags */ - gen_storeflags(); + gen_protectflags(); /* Scan for the amount of params */ if (ops) { va_list params; @@ -704,7 +693,6 @@ static void gen_call_function(void * func,char * ops,...) { } dynreg->flags|=DYNFLG_CHANGED; } - gen_restoreflags(); /* Restore EAX registers to be used again */ x86gen.regs[X86_REG_EAX]->notusable=false; } @@ -747,17 +735,20 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { } } -static void gen_save_flags(DynReg * dynreg,bool stored) { +static void gen_save_flags(DynReg * dynreg) { + if (x86gen.flagsactive) IllegalOption(); GenReg * genreg=FindDynReg(dynreg); - if (!stored) cache_addb(0x9c); //Pushfd - cache_addb(0x58+genreg->index); //POP 32 REG + cache_addb(0x8b); //MOV REG,[esp] + cache_addw(0x2404+(genreg->index << 3)); dynreg->flags|=DYNFLG_CHANGED; } static void gen_load_flags(DynReg * dynreg) { + if (x86gen.flagsactive) IllegalOption(); + cache_addw(0xc483); //ADD ESP,4 + cache_addb(0x4); GenReg * genreg=FindDynReg(dynreg); cache_addb(0x50+genreg->index); //PUSH 32 - cache_addb(0x9d); //POPFD } static void gen_save_host_direct(void * data,Bits imm) { @@ -781,9 +772,11 @@ static void gen_load_host(void * data,DynReg * dr1,Bitu size) { } static void gen_return(BlockReturn retcode) { - cache_addb(0xb8); + gen_protectflags(); + cache_addb(0x59); //POP ECX, the flags + cache_addb(0xb8); //MOV EAX, retcode cache_addd(retcode); - cache_addb(0xc3); + cache_addb(0xc3); //RET } static void gen_init(void) { diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index 7a713d9e..443b9af0 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -30,7 +30,7 @@ static void dyn_string(STRING_OP op) { DynReg * si_base=decode.segprefix ? decode.segprefix : DREG(DS); DynReg * di_base=DREG(ES); DynReg * tmp_reg;bool usesi;bool usedi; - gen_storeflags(); + gen_protectflags(); if (decode.rep) { gen_dop_word_imm(DOP_SUB,true,DREG(CYCLES),decode.cycles); gen_releasereg(DREG(CYCLES)); @@ -151,7 +151,6 @@ static void dyn_string(STRING_OP op) { Bit8u * cycle_branch=gen_create_branch(BR_NLE); gen_lea(DREG(EIP),DREG(EIP),0,0,decode.op_start-decode.code_start); dyn_releaseregs(); - gen_restoreflags(true); gen_return(BR_Cycles); gen_fill_branch(cycle_branch); dyn_loadstate(&cycle_state); @@ -161,5 +160,4 @@ static void dyn_string(STRING_OP op) { gen_fill_jump(rep_ecx_jmp); } gen_releasereg(DREG(TMPW)); - gen_restoreflags(); } From 872f5726d0c3d323e5040dd877223737ccd5fca8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 23 Mar 2004 22:17:55 +0000 Subject: [PATCH 1657/4131] Save ebp during dynamic block execution Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1739 --- src/cpu/core_dyn_x86/risc_x86.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 9611e0ea..c74be278 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -116,13 +116,15 @@ return_address: #else register Bit32u tempflags=reg_flags & FMASK_TEST; __asm__ volatile ( + "pushl %%ebp \n" "pushl $(run_return_adress) \n" "pushl %2 \n" "jmp *%3 \n" "run_return_adress: \n" + "popl %%ebp \n" :"=a" (retval), "=c" (tempflags) :"r" (tempflags),"r" (code) - :"%edx","%ebx","%edi","%esi","cc","memory" + :"%edx","%ebx","%edi","%esi","%ebp","cc","memory" ); reg_flags=(reg_flags & ~FMASK_TEST) | (tempflags & FMASK_TEST); #endif From 5b602247685132472b623faebbc98a9e9a9db2ee Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 24 Mar 2004 19:26:49 +0000 Subject: [PATCH 1658/4131] update dx instead of x. duh Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1740 --- src/ints/mouse.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 73079851..416d8b10 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.35 2004-03-23 20:25:41 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.36 2004-03-24 19:26:49 qbix79 Exp $ */ #include #include @@ -411,8 +411,8 @@ void DrawCursor() { void Mouse_CursorMoved(float x,float y) { float dx = x * mouse.pixelPerMickey_x; float dy = y * mouse.pixelPerMickey_y; - if((fabs(x) > 1.0) || (mouse.senv_y < 1.0)) dx=mouse.senv_x*x; - if((fabs(y) > 1.0) || (mouse.senv_y < 1.0)) dy=mouse.senv_y*y; + if((fabs(x) > 1.0) || (mouse.senv_y < 1.0)) dx *= mouse.senv_x; + if((fabs(y) > 1.0) || (mouse.senv_y < 1.0)) dy *= mouse.senv_y; mouse.mickey_x += dx; mouse.mickey_y += dy; From 1c2bf685d7fed0d1059b25b4941d56f57fd8ae6c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 28 Mar 2004 13:04:45 +0000 Subject: [PATCH 1659/4131] Fix some adlib detection issues when cycles is too high Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1741 --- src/hardware/adlib.cpp | 6 ++++-- src/hardware/fmopl.c | 43 +++++++++++++++++++++++++++--------------- src/hardware/ymf262.c | 42 +++++++++++++++++++++++++++-------------- 3 files changed, 60 insertions(+), 31 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 40505abf..74815639 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -55,7 +55,8 @@ namespace OPL2 { YM3812TimerOver(val>>8,val & 0xff); } void TimerHandler(int channel,double interval_Sec) { - PIC_AddEvent(TimerOver,1000000*interval_Sec,channel); + if (interval_Sec==0.0) return; + PIC_AddEvent(TimerOver,(Bitu)(1000000.0*interval_Sec),channel); } } #undef OSD_CPU_H @@ -67,7 +68,8 @@ namespace THEOPL3 { YMF262TimerOver(val>>8,val & 0xff); } void TimerHandler(int channel,double interval_Sec) { - PIC_AddEvent(TimerOver,1000000*interval_Sec,channel); + if (interval_Sec==0.0) return; + PIC_AddEvent(TimerOver,(Bitu)(1000000.0*interval_Sec),channel); } } diff --git a/src/hardware/fmopl.c b/src/hardware/fmopl.c index 5a838eb5..94274475 100644 --- a/src/hardware/fmopl.c +++ b/src/hardware/fmopl.c @@ -276,6 +276,7 @@ typedef struct fm_opl_f { UINT8 wavesel; /* waveform select enable flag */ int T[2]; /* timer counters */ + int TC[2]; UINT8 st[2]; /* timer enable */ #if BUILD_Y8950 @@ -1485,27 +1486,27 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v) } else { /* set IRQ mask ,timer enable*/ - UINT8 st1 = v&1; - UINT8 st2 = (v>>1)&1; + OPL->st[0] = v&1; + OPL->st[1] = (v>>1)&1; /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */ OPL_STATUS_RESET(OPL, v & 0x78 ); OPL_STATUSMASK_SET(OPL, (~v) & 0x78 ); - /* timer 2 */ - if(OPL->st[1] != st2) - { - double interval = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0; - OPL->st[1] = st2; - if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval); - } /* timer 1 */ - if(OPL->st[0] != st1) + if(OPL->st[0]) { - double interval = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0; - OPL->st[0] = st1; + OPL->TC[0]=OPL->T[0]*20; + double interval = (double)OPL->T[0]*OPL->TimerBase; if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval); } + /* timer 2 */ + if(OPL->st[1]) + { + OPL->TC[1]=OPL->T[1]*20; + double interval =(double)OPL->T[1]*OPL->TimerBase; + if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval); + } } break; #if BUILD_Y8950 @@ -1915,8 +1916,20 @@ static unsigned char OPLRead(FM_OPL *OPL,int a) } #endif - - /* OPL and OPL2 */ + if (OPL->st[0]) { + if (OPL->TC[0]) OPL->TC[0]--; + else { + OPL->TC[0]=OPL->T[0]*20; + OPL_STATUS_SET(OPL,0x40); + } + } + if (OPL->st[1]) { + if (OPL->TC[1]) OPL->TC[1]--; + else { + OPL->TC[1]=OPL->T[1]*20; + OPL_STATUS_SET(OPL,0x40); + } + } return OPL->status & (OPL->statusmask|0x80); } @@ -1999,7 +2012,7 @@ static int OPLTimerOver(FM_OPL *OPL,int c) } } /* reload timer */ - if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase); +// if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase); return OPL->status>>7; } diff --git a/src/hardware/ymf262.c b/src/hardware/ymf262.c index 5ecaa05f..e9bd41f2 100644 --- a/src/hardware/ymf262.c +++ b/src/hardware/ymf262.c @@ -242,6 +242,7 @@ typedef struct { UINT8 rhythm; /* Rhythm mode */ int T[2]; /* timer counters */ + int TC[2]; UINT8 st[2]; /* timer enable */ UINT32 address; /* address register */ @@ -1726,27 +1727,27 @@ static void OPL3WriteReg(OPL3 *chip, int r, int v) } else { /* set IRQ mask ,timer enable */ - UINT8 st1 = v & 1; - UINT8 st2 = (v>>1) & 1; + chip->st[0] = v & 1; + chip->st[1] = (v>>1) & 1; /* IRQRST,T1MSK,t2MSK,x,x,x,ST2,ST1 */ OPL3_STATUS_RESET(chip, v & 0x60); OPL3_STATUSMASK_SET(chip, (~v) & 0x60 ); - /* timer 2 */ - if(chip->st[1] != st2) - { - double interval = st2 ? (double)chip->T[1]*chip->TimerBase : 0.0; - chip->st[1] = st2; - if (chip->TimerHandler) (chip->TimerHandler)(chip->TimerParam+1,interval); - } /* timer 1 */ - if(chip->st[0] != st1) + if(chip->st[0]) { - double interval = st1 ? (double)chip->T[0]*chip->TimerBase : 0.0; - chip->st[0] = st1; + chip->TC[0]=chip->T[0]*20; + double interval = (double)chip->T[0]*chip->TimerBase; if (chip->TimerHandler) (chip->TimerHandler)(chip->TimerParam+0,interval); } + /* timer 2 */ + if(chip->st[1]) + { + chip->TC[1]=chip->T[1]*20; + double interval =(double)chip->T[1]*chip->TimerBase; + if (chip->TimerHandler) (chip->TimerHandler)(chip->TimerParam+1,interval); + } } break; case 0x08: /* x,NTS,x,x, x,x,x,x */ @@ -2440,7 +2441,20 @@ static unsigned char OPL3Read(OPL3 *chip,int a) { if( a==0 ) { - /* status port */ + if (chip->st[0]) { + if (chip->TC[0]) chip->TC[0]--; + else { + chip->TC[0]=chip->T[0]*20; + OPL3_STATUS_SET(chip,0x40); + } + } + if (chip->st[1]) { + if (chip->TC[1]) chip->TC[1]--; + else { + chip->TC[1]=chip->T[1]*20; + OPL3_STATUS_SET(chip,0x40); + } + } return chip->status; } @@ -2460,7 +2474,7 @@ static int OPL3TimerOver(OPL3 *chip,int c) OPL3_STATUS_SET(chip,0x40); } /* reload timer */ - if (chip->TimerHandler) (chip->TimerHandler)(chip->TimerParam+c,(double)chip->T[c]*chip->TimerBase); +// if (chip->TimerHandler) (chip->TimerHandler)(chip->TimerParam+c,(double)chip->T[c]*chip->TimerBase); return chip->status>>7; } From 9cae461d023e5ef5efca8edad6f437328f5f4330 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 29 Mar 2004 18:03:02 +0000 Subject: [PATCH 1660/4131] Lets .... Play .... Quake cvs diff -u fpu.cppcvs diff -u fpu.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1742 --- src/fpu/fpu.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index e8af0880..c2ce3a4a 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu.cpp,v 1.17 2004-01-19 18:54:15 qbix79 Exp $ */ +/* $Id: fpu.cpp,v 1.18 2004-03-29 18:03:02 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU @@ -109,7 +109,7 @@ INLINE Bitu FPU_GET_C3(void){ /* WATCHIT : ALWAYS UPDATE REGISTERS BEFORE AND AFTER USING THEM STATUS WORD => FPU_SET_TOP(TOP) BEFORE a read - TOP=FPU_GET_TOP() after a write; + TOP=FPU_GET_TOP() after a write; */ static void EATREE(Bitu _rm){ Bitu group=(_rm >> 3) & 7; @@ -152,7 +152,7 @@ void FPU_ESC0_EA(Bitu rm,PhysPt addr) { float f; Bit32u l; } blah; - blah.l = mem_readd(addr); + blah.l = mem_readd(addr); fpu.regs[8].d = static_cast(blah.f); EATREE(rm); } @@ -391,7 +391,22 @@ void FPU_ESC2_EA(Bitu rm,PhysPt addr) { void FPU_ESC2_Normal(Bitu rm) { Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); - LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",group,sub); + switch(group){ + case 0x05: + switch(sub){ + case 0x01: /* FUCOMPP Almost the same as FCOMPP */ + FPU_FCOM(TOP,ST(1)); + FPU_FPOP(); + FPU_FPOP(); + break; + default: + LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",group,sub); + break; + } + default: + LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",group,sub); + break; + } } From 91795c0af4a9eaa8d550cb849e3353b113f16f00 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 31 Mar 2004 14:42:08 +0000 Subject: [PATCH 1661/4131] Give all parameters for cpu_ functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1743 --- src/ints/bios.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 4c6e2137..2a10b0e5 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.30 2004-03-14 13:39:45 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.31 2004-03-31 14:42:08 harekiet Exp $ */ #include #include "dosbox.h" @@ -288,7 +288,7 @@ static Bitu INT15_Handler(void) { reg_sp+=6; //Clear stack of interrupt frame CPU_SetFlags(0,FMASK_ALL); reg_ax=0; - CPU_JMP(false,0x30,reg_cx); + CPU_JMP(false,0x30,reg_cx,0); } break; case 0x90: /* OS HOOK - DEVICE BUSY */ From f0998e650479b01cdc5f9b85fbe1a823bdede7cb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 31 Mar 2004 14:43:50 +0000 Subject: [PATCH 1662/4131] internal dpmi not needed anymore Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1744 --- src/dosbox.cpp | 12 +- src/ints/dpmi.cpp | 3233 --------------------------------------------- 2 files changed, 1 insertion(+), 3244 deletions(-) delete mode 100644 src/ints/dpmi.cpp diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 69bce9c4..88c1fc1f 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.66 2004-03-10 13:49:30 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.67 2004-03-31 14:43:50 harekiet Exp $ */ #include #include @@ -91,7 +91,6 @@ void MSCDEX_Init(Section*); /* Dos Internal mostly */ void EMS_Init(Section*); void XMS_Init(Section*); -void DPMI_Init(Section*); void AUTOEXEC_Init(Section*); void SHELL_Init(void); @@ -350,18 +349,9 @@ void DOSBOX_Init(void) { secprop->Add_bool("xms",true); secprop->AddInitFunction(&EMS_Init); secprop->Add_bool("ems",true); -#if (C_DEBUG) - secprop->AddInitFunction(&DPMI_Init); - secprop->Add_bool("dpmi",false); -#endif MSG_Add("DOS_CONFIGFILE_HELP", "xms -- Enable XMS support.\n" "ems -- Enable EMS support.\n" -#if (C_DEBUG) - "dpmi -- Enable builtin DPMI host support.\n" - " This might help in getting some games to work, but might crash others.\n" - " So be sure to try both settings.\n" -#endif ); // Mscdex secprop->AddInitFunction(&MSCDEX_Init); diff --git a/src/ints/dpmi.cpp b/src/ints/dpmi.cpp deleted file mode 100644 index dbbe45f2..00000000 --- a/src/ints/dpmi.cpp +++ /dev/null @@ -1,3233 +0,0 @@ -/* - * Copyright (C) 2002-2004 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -// Pharlap Special Infos: -// - Dont hook hardware ints -// - CMOS Memory Size has to return 0 otherwise it tries to map physical memory -// - Set PM Int Vector : Use it on current idt, not only dpmi one (ultima 8 mouse check fails otherwise) -// - Ultima 8 wants 40 Files (Hack in PSP::SetNumFiles -// - Ultima 8 and Bioforge work with DPL 3 -// - Crusaders 1+2 seem to need DPL 0, which is bad... -// - Bioforge uses more than 2048 descriptos in ldt (4096) - -#include -#include -#include -#include "dosbox.h" -#include "dos_inc.h" -#include "callback.h" -#include "mem.h" -#include "regs.h" -#include "dos_system.h" -#include "setup.h" -#include "inout.h" -#include "cpu.h" -#include "bios.h" -#include "paging.h" - -#include "debug.h" - -//#define DPMI_LOG LOG(LOG_MISC,LOG_ERROR) -#define DPMI_LOG - -#define DPMI_LOG_ERROR LOG(LOG_MISC,LOG_ERROR) -//#define DPMI_LOG_ERROR - -#define DPMI_ALLOC_NEEDEDMEM_HIGH 1 - -#define DPMI_DPL 3 - -#define GDT_ZERO 0 -#define GDT_LDT ((0x1 << 3) | DPMI_DPL) -#define GDT_CODE ((0x2 << 3) | DPMI_DPL) -#define GDT_PROTCODE ((0x3 << 3) | DPMI_DPL) -#define GDT_DOSDATA ((0x4 << 3) | DPMI_DPL) -#define GDT_ENVIRONMENT ((0x5 << 3) | DPMI_DPL) - -#define GDT_DOSSEG40 (0x40) - -/* Amount of descriptors in each table */ -#define GDT_SIZE 32 -#define IDT_SIZE 256 -#define LDT_SIZE 4096 -#define INT_SIZE 256 - -#define TOTAL_SIZE ((GDT_SIZE+IDT_SIZE+LDT_SIZE+INT_SIZE)*8) - -#define LDT_ENTRY(BLAH_) (BLAH_ << 3) - -#define LDT_FIRSTSELECTOR 16 - -#define DPMI_ERROR_UNSUPPORTED 0x8001 -#define DPMI_ERROR_DESCRIPTOR_UNAVAILABLE 0x8011 -#define DPMI_ERROR_LINEAR_MEMORY_UNAVAILABLE 0x8012 -#define DPMI_ERROR_PHYSICAL_MEMORY_UNAVAILABLE 0x8013 -#define DPMI_ERROR_CALLBACK_UNAVAILABLE 0x8015 -#define DPMI_ERROR_INVALID_SELECTOR 0x8022 -#define DPMI_ERROR_INVALID_VALUE 0x8022 -#define DPMI_ERROR_INVALID_HANDLE 0x8023 -#define DPMI_ERROR_INVALID_CALLBACK 0x8024 -#define DPMI_ERROR_INVALID_LINEAR_ADDRESS 0x8025 - -#define DPMI_XMSHANDLES_MAX 256 -#define DPMI_XMSHANDLE_FREE 0xFFFF -#define DPMI_EXCEPTION_MAX 0x20 -#define DPMI_PAGE_SIZE (4*1024) -#define DPMI_REALMODE_CALLBACK_MAX 32 -#define DPMI_REALMODE_STACKSIZE 4096 -#define DPMI_PROTMODE_STACK_MAX 3 -#define DPMI_PROTMODE_STACKSIZE (4*1024) -#define DPMI_REALVEC_MAX 17 -#define DPMI_SAVESTACK_MAX 1024 - -#define DPMI_CB_APIMSDOSENTRY_OFFSET 256*8 -#define DPMI_CB_ENTERREALMODE_OFFSET 257*8 -#define DPMI_CB_SAVESTATE_OFFSET 258*8 -#define DPMI_CB_EXCEPTION_OFFSET 259*8 -#define DPMI_CB_EXCEPTIONRETURN_OFFSET 260*8 -#define DPMI_CB_VENDORENTRY_OFFSET 261*8 - -static bool g_hookHardwareInts = true; - -void CMOS_SetRegister(Bitu regNr, Bit8u val); - -static Bitu rmIndexToInt[DPMI_REALVEC_MAX] = -{ 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x1C }; - -// General functions -void CALLBACK32_SCF(bool val) -{ - Bitu v_esp = 0; - if (cpu.stack.big) v_esp = reg_esp; else v_esp = reg_sp; - Bit32u tempf=mem_readd(SegPhys(ss)+v_esp+8) & 0xFFFFFFFE; - Bit32u newCF=(val==true); - mem_writed(SegPhys(ss)+v_esp+8,(tempf | newCF)); -}; - -#define DPMI_CALLBACK_SCF(b) if (dpmi.client.bit32) CALLBACK32_SCF(b); else CALLBACK_SCF(b) - -// ********************************************** -// SetDescriptor Class -// ********************************************** - -#pragma pack(1) -class SetDescriptor : public Descriptor { -public: - void Save(PhysPt address) { - Bit32u* data = (Bit32u*)&saved; - mem_writed(address,*data); - mem_writed(address+4,*(data+1)); - } - - void SetBase(Bitu _base) { - saved.seg.base_24_31=_base >> 24; - saved.seg.base_16_23=_base >> 16; - saved.seg.base_0_15=_base; - } - void SetLimit (Bitu _limit) { - if (_limit<1048576) saved.seg.g=false; - else { - saved.seg.g=true; - _limit>>=12; - } - saved.seg.limit_0_15=_limit; - saved.seg.limit_16_19=_limit>>16; - } - void SetOffset(Bitu _offset) { - saved.gate.offset_0_15=_offset; - saved.gate.offset_16_31=(_offset>>16); - } - void SetSelector(Bitu _selector) { - saved.gate.selector=_selector; - } - void SetType(Bitu _type) { - saved.seg.type=_type; - } - void Clear(void) { - saved.fill[0]=saved.fill[1]=0; - } -}; -#pragma pack() - -// ********************************************** -// Shared Memory -// ********************************************** - -typedef struct SSharedMem { - - std::string name; - Bitu handle; - Bitu pages; - -} TSharedMem; - -std::list g_sharedMemList; - -// ********************************************** -// DPMI Class -// ********************************************** - -class DPMI { - -public: - DPMI (void); - ~DPMI (void); - - // Settp/Startup methods - void Setup (void); - Bitu Entrypoint (void); - RealPt HookInterrupt (Bitu num, Bitu intHandler); - void RestoreHookedInterrupt (Bitu num, RealPt oldVec); - void CreateStackSpace (void); - bool HasClient (void) { return dpmi.client.have; }; - void Terminate (void); - void Reactivate (void); - - // DPMI Services - Bitu AllocateLDTDescriptor (Bitu count,Bitu & base); - Bitu AllocateLDTDescriptor2 (Bitu count,Bitu & base); // TEMP - bool AllocateMem (Bitu size, Bitu& outHandle, Bitu& linear); - Bitu CreateAlias (Bitu selector, Bit16u& alias); - void ReloadSegments (Bitu selector); - bool SetAccessRights (Bitu selector, SetDescriptor& desc, Bitu rights); - bool SetProtInterrupt (Bitu num, Bitu selector, Bitu offset); - - // Special Interrupt handlers - Bitu Int2fHandler (void); - Bitu Int31Handler (void); - - // Exceptions - Bitu CreateException (void); - void CreateException (Bitu num, Bitu errorCode); - Bitu ExceptionReturn (void); - - // Realmode callbacks - bool AllocateRealModeCallback(Bitu codeSel,Bitu codeOff,Bitu dataSel, Bitu dataOff, Bitu& segment, Bitu& offset); - Bitu RealModeCallback (void); - Bitu RealModeCallbackReturn (void); - - // Real mode reflection callbacks - void PrepareReflectToReal (Bitu num); - Bitu CallRealIRETFrame (bool callAsInt); - Bitu CallRealIRETFrameReturn (void); - Bitu SimulateInt (void); - Bitu SimulateIntReturn (void); - Bitu ptorHandler (void); - Bitu ptorHandlerReturn (void); - Bitu Int21Handler (void); - Bitu Int21HandlerReturn (void); - Bitu HWIntDefaultHandler (void); - void RemoveIntCallbacks (void); - void RestoreIntCallbacks (void); - - // Switching modes - void SaveRegisterState (Bitu num); - void LoadRegisterState (Bitu num); - Bitu EnterProtMode (void); - Bitu EnterRealMode (void); - Bitu RealSaveState (void); - Bitu ProtSaveState (void); - - // virtual interrupt flag - bool GetVirtualIntFlag (void); - void SetVirtualIntFlag (bool on); - - // Internal Stack for saving processor status - void PushStack (Bitu val) { saveStack[savePtr++] = val; }; - Bitu PopStack (void) { return saveStack[--savePtr]; }; - void SaveSegments (void); - void SaveRegister (void); - void RestoreSegments (void); - void RestoreRegister (void); - - void CopyRegistersToBuffer (PhysPt data); - void LoadRegistersFromBuffer (PhysPt data); - - void ProvideRealModeStack (PhysPt prStack, Bitu toCopy); - void UpdateRealModeStack (void); - - // xms handle information - void SetXMSHandle (Bitu handle); - void ClearXMSHandles (void); - void FreeXMSHandle (Bitu handle); - - // shared memory - void SetSharedMem (const char* name, Bitu handle, Bitu pages); - bool GetSharedMem (const char* name, Bitu& handle, Bitu& pages); - bool IsSharedMem (Bitu handle); - bool RemoveSharedMem (Bitu handle); - - // special msdos api stuff - void SetupPharlapSelectors (void); - bool Pharlap_AllocateMem (Bitu size, Bitu& outHandle, Bitu& linear); - Bitu GetSegmentFromSelector (Bitu selector); - bool GetMsdosSelector (Bitu realseg, Bitu realoff, Bitu &protsel, Bitu &protoff); - void API_Init_MSDOS (void); - Bitu API_Entry_MSDOS (void); - Bitu API_Int21_MSDOS (void); - - // debug - void Debug_ShowDescriptors (void); - -private: - Bitu Mask (Bitu value); - - Bitu saveStack[DPMI_SAVESTACK_MAX]; - Bitu savePtr; - Bitu rm_ss, rm_sp; - - struct { - struct { - bool have; - bool bit32; - Bitu psp; - } client; - Bit32s mem_handle; /* Handle for GDT/IDT */ - Bitu idtBase,idtLimit; - struct { - PhysPt base; - Bitu limit; - } gdt,idt,ldt; - struct { - bool inCall; - bool inUse; - bool stop; - Bitu callCount; - Bitu id; - Bitu dataSelector,dataOffset; - Bitu codeSelector,codeOffset; - Bitu realSegment ,realOffset; - } rmCallback[DPMI_REALMODE_CALLBACK_MAX]; - - RealPt realModeVec [DPMI_REALVEC_MAX]; - Bitu oldRealVec [DPMI_REALVEC_MAX]; - Bitu defaultHWIntFromProtMode[DPMI_REALVEC_MAX]; - - PhysPt ptorint_base; /* Base of pmode int handlers that reflect to realmode */ - Bitu exceptionSelector[DPMI_EXCEPTION_MAX],exceptionOffset[DPMI_EXCEPTION_MAX]; - - Bitu xmsHandles[DPMI_XMSHANDLES_MAX]; - Bitu protStack; - - Bitu protStackSelector[DPMI_PROTMODE_STACK_MAX]; - Bitu realStackSelector[DPMI_PROTMODE_STACK_MAX]; - Bitu dataSelector [DPMI_PROTMODE_STACK_MAX]; - Bitu protStackCurrent; - - Bitu vIntFlag; - - bool pharlap; - bool suppressRMCB; - - // Pharlap stuff - Bitu initialcs,initialds; - Bitu initialenv; - } dpmi; - - Bit32u* modIntTable; - DPMI* prevDPMI; - std::vector dosSelectorList; - - Bitu dtaAddress; - Bitu save_cs[2],save_ds[2],save_es[2],save_fs[2],save_gs[2],save_ss[2]; - Bitu save_eax[2],save_ebx[2],save_ecx[2],save_edx[2],save_esi[2],save_edi[2]; - Bitu save_ebp[2],save_esp[2],save_eip[2],save_fl[2]; -}; - -struct { - Bitu entry; - Bitu ptorint; - Bitu ptorintReturn; - Bitu int31; - Bitu int21; - Bitu int21Return; - Bitu int2f; - Bitu enterpmode; - Bitu enterrmode; - Bitu protsavestate; - Bitu realsavestate; - Bitu simint; - Bitu simintReturn; - Bitu rmIntFrame; - Bitu rmIntFrameReturn; - Bitu rmCallbackReturn; - Bitu exception; - Bitu exceptionret; - // Special callbacks for special dos extenders - Bitu apimsdosentry; - Bitu int21msdos; -} callback; - -// ************************************************ -// DPMI static functions -// ************************************************ - -#define SWITCH_TO_REALMODE CPU_SET_CRX(0,cpu.cr0 & ~CR0_PROTECTION); \ - CPU_SIDT(dpmi.idtLimit,dpmi.idtBase); \ - CPU_LIDT(256*4,0); - -#define SWITCH_TO_PROTMODE CPU_SET_CRX(0,cpu.cr0 | CR0_PROTECTION); \ - CPU_LIDT(dpmi.idtLimit,dpmi.idtBase); - - -static DPMI* activeDPMI = 0; -static Bit32u originalIntTable[256]; - -bool DPMI_IsActive(void) -{ - return (cpu.cr0 & CR0_PROTECTION) && activeDPMI && activeDPMI->HasClient(); -} - -void DPMI_SetVirtualIntFlag(bool on) -{ - if (activeDPMI) activeDPMI->SetVirtualIntFlag(on); -} - -void DPMI_CreateException(Bitu num, Bitu errorCode) -{ - if (activeDPMI) activeDPMI->CreateException(num,errorCode); -} - -// ************************************************ -// DPMI Methods -// ************************************************ - -DPMI::DPMI(void) -{ - memset(&dpmi,0,sizeof(dpmi)); - savePtr = 0; - dtaAddress = 0; - rm_ss = rm_sp = 0; - modIntTable = 0; - prevDPMI = activeDPMI; -}; - -DPMI::~DPMI(void) -{ - MEM_ReleasePages(dpmi.mem_handle); - dosSelectorList.clear(); - // TODO: Free all memory allocated with DOS_GetMemory - // Activate previous dpmi - activeDPMI = prevDPMI; - // Restore hookHardwareInts ability which may be changed by a pharlap program - if (!activeDPMI) g_hookHardwareInts = true; -}; - -void DPMI::ClearXMSHandles(void) -{ - for (Bitu i=0; iname = name; - smem->handle= handle; - smem->pages = pages; - g_sharedMemList.push_back(smem); -}; - -bool DPMI::GetSharedMem(const char* name, Bitu& handle, Bitu& pages) -{ - TSharedMem* smem; - std::list::iterator i; - for(i = g_sharedMemList.begin(); i != g_sharedMemList.end(); i++) { - smem = static_cast(*i); - if (smem->name.compare(name)==0) { - handle = smem->handle; - pages = smem->pages; - return true; - } - - }; - return false; -}; - -bool DPMI::IsSharedMem(Bitu handle) -{ - std::list::iterator i; - for(i = g_sharedMemList.begin(); i != g_sharedMemList.end(); i++) { - if ((*i)->handle==handle) return true; - }; - return false; -}; - -bool DPMI::RemoveSharedMem(Bitu handle) -{ - TSharedMem* smem; - std::list::iterator i; - for(i = g_sharedMemList.begin(); i != g_sharedMemList.end(); i++) { - smem = static_cast(*i); - if (smem->handle==handle) { - g_sharedMemList.remove(*i); - delete smem; - return true; - } - - }; - return false; -}; - -void DPMI::SetXMSHandle(Bitu handle) { - for (Bitu i=0; i=DPMI_SAVESTACK_MAX) E_Exit("DPMI: Stack too small."); - saveStack[savePtr++] = SegValue(ds); - saveStack[savePtr++] = SegValue(es); - saveStack[savePtr++] = SegValue(fs); - saveStack[savePtr++] = SegValue(gs); - saveStack[savePtr++] = SegValue(ss); -} - -void DPMI::SaveRegister(void) -{ - SaveSegments(); - if (savePtr+8>=DPMI_SAVESTACK_MAX) E_Exit("DPMI: Stack too small."); - saveStack[savePtr++] = reg_eax; - saveStack[savePtr++] = reg_ebx; - saveStack[savePtr++] = reg_ecx; - saveStack[savePtr++] = reg_edx; - saveStack[savePtr++] = reg_esi; - saveStack[savePtr++] = reg_edi; - saveStack[savePtr++] = reg_ebp; - saveStack[savePtr++] = reg_esp; -}; - -void DPMI::RestoreSegments(void) -{ - CPU_SetSegGeneral(ss,saveStack[--savePtr]); - CPU_SetSegGeneral(gs,saveStack[--savePtr]); - CPU_SetSegGeneral(fs,saveStack[--savePtr]); - CPU_SetSegGeneral(es,saveStack[--savePtr]); - CPU_SetSegGeneral(ds,saveStack[--savePtr]); -}; - -void DPMI::RestoreRegister(void) -{ - reg_esp = saveStack[--savePtr]; - reg_ebp = saveStack[--savePtr]; - reg_edi = saveStack[--savePtr]; - reg_esi = saveStack[--savePtr]; - reg_edx = saveStack[--savePtr]; - reg_ecx = saveStack[--savePtr]; - reg_ebx = saveStack[--savePtr]; - reg_eax = saveStack[--savePtr]; - RestoreSegments(); -}; - -void DPMI::CopyRegistersToBuffer(PhysPt data) -{ - // Save Values in structure - mem_writed(data+0x00, reg_edi); - mem_writed(data+0x04, reg_esi); - mem_writed(data+0x08, reg_ebp); - mem_writed(data+0x0C, 0x0000); - mem_writed(data+0x10, reg_ebx); - mem_writed(data+0x14, reg_edx); - mem_writed(data+0x18, reg_ecx); - mem_writed(data+0x1C, reg_eax); - mem_writew(data+0x20, reg_flags); - mem_writew(data+0x22, SegValue(es)); - mem_writew(data+0x24, SegValue(ds)); - mem_writew(data+0x26, SegValue(fs)); - mem_writew(data+0x28, SegValue(gs)); - mem_writew(data+0x2A, reg_ip); - mem_writew(data+0x2C, SegValue(cs)); - mem_writew(data+0x2E, reg_sp); - mem_writew(data+0x30, SegValue(ss)); -} - -void DPMI::LoadRegistersFromBuffer(PhysPt data) -{ - reg_edi = mem_readd(data+0x00); - reg_esi = mem_readd(data+0x04); - reg_ebp = mem_readd(data+0x08); - reg_ebx = mem_readd(data+0x10); - reg_edx = mem_readd(data+0x14); - reg_ecx = mem_readd(data+0x18); - reg_eax = mem_readd(data+0x1C); - CPU_SetFlagsw(mem_readw(data+0x20)); - SegSet16(es,mem_readw(data+0x22)); - SegSet16(ds,mem_readw(data+0x24)); - SegSet16(fs,mem_readw(data+0x26)); - SegSet16(gs,mem_readw(data+0x28)); - reg_esp = mem_readw(data+0x2E); - SegSet16(ss,mem_readw(data+0x30)); - if (!dpmi.client.bit32) { - reg_eax &= 0xFFFF; - reg_ebx &= 0xFFFF; - reg_ecx &= 0xFFFF; - reg_edx &= 0xFFFF; - reg_edi &= 0xFFFF; - reg_esi &= 0xFFFF; - reg_ebp &= 0xFFFF; - reg_esp &= 0xFFFF; - }; -}; - -void DPMI::ProvideRealModeStack(PhysPt prStack, Bitu toCopy) -{ - // Check stack, if zero provide it - if ((SegValue(ss)==0) && (reg_sp==0)) { - SegSet16(ss,rm_ss); - reg_esp = rm_sp; - } else { - if (SegValue(ss)==rm_ss) reg_esp = rm_sp; - }; - // We have to be in realmode here - if (toCopy>0) { - Bitu numBytes = toCopy*2; - if (reg_espDPMI_REALMODE_STACKSIZE) E_Exit("DPMI:Realmode stack out of range: %04X",reg_esp); - rm_sp = reg_sp; - } -}; - -Bitu DPMI::AllocateLDTDescriptor(Bitu count,Bitu & base) { - - SetDescriptor test; - Bitu i=16, found=0; - PhysPt address = dpmi.ldt.base + LDT_FIRSTSELECTOR*8; - while (i0;found--) { - test.Save(address); - address+=8; - } - return true; - } - } - return false; -} - -Bitu DPMI::AllocateLDTDescriptor2(Bitu count,Bitu & base) { - - static Bitu allocated = 0; - - SetDescriptor desc; - Bitu nr = LDT_FIRSTSELECTOR + allocated; - if (nr+count < LDT_SIZE) { - desc.Clear(); - desc.SetType(DESC_DATA_EU_RW_NA); - desc.saved.seg.p = 1; - desc.saved.seg.big = dpmi.client.bit32; - desc.saved.seg.dpl = DPMI_DPL; - base = (nr << 3)|(4|DPMI_DPL); /* Make it an LDT Entry */ - allocated += count; - Bitu address = dpmi.ldt.base+(base & ~7); - for (;count>0;count--) { - desc.Save(address); - address+=8; - } - return true; - }; - return false; -} - -Bitu DPMI::CreateAlias(Bitu selector, Bit16u& alias) -{ - Descriptor oldDesc; - Bitu base; - if (!cpu.gdt.GetDescriptor(selector,oldDesc)) { alias = DPMI_ERROR_INVALID_SELECTOR; return false; }; - if (!AllocateLDTDescriptor(1,base)) { alias = DPMI_ERROR_DESCRIPTOR_UNAVAILABLE; return false; }; - SetDescriptor desc; - desc.Clear(); - desc.SetLimit(oldDesc.GetLimit()); - desc.SetBase (oldDesc.GetBase()); - desc.SetType (DESC_DATA_ED_RW_A); - desc.saved.seg.p=1; - desc.saved.seg.dpl = DPMI_DPL; - desc.Save (dpmi.ldt.base+(base & ~7)); - alias = base; - return true; -}; - -void DPMI::ReloadSegments(Bitu selector) -{ - if (SegValue(cs)==selector) CPU_SetSegGeneral(cs,selector); - if (SegValue(ds)==selector) CPU_SetSegGeneral(ds,selector); - if (SegValue(es)==selector) CPU_SetSegGeneral(es,selector); - if (SegValue(fs)==selector) CPU_SetSegGeneral(fs,selector); - if (SegValue(gs)==selector) CPU_SetSegGeneral(gs,selector); - if (SegValue(ss)==selector) CPU_SetSegGeneral(ss,selector); -}; - -Bitu DPMI::CreateException(void) -{ - // Division by Zero - CreateException(0,0); - return CBRET_NONE; -}; - -void DPMI::CreateException(Bitu num, Bitu errorCode) -{ - // Assuming Stack looks like a int has occured - Bitu stack_eip,stack_cs,stack_flags; - if (dpmi.client.bit32) { - // Clean up stack - stack_eip = CPU_Pop32(); - stack_cs = CPU_Pop32(); - stack_flags = CPU_Pop32(); - // Push values for exception handler - CPU_Push32(SegValue(ss)); - CPU_Push32(reg_esp); - CPU_Push32(stack_flags); - CPU_Push32(stack_cs); - CPU_Push32(stack_eip); - CPU_Push32(errorCode); - CPU_Push32(GDT_PROTCODE); // return cs - CPU_Push32(DPMI_CB_EXCEPTIONRETURN_OFFSET); // return eip - } else { - // Clean up stack - stack_eip = CPU_Pop16(); - stack_cs = CPU_Pop16(); - stack_flags = CPU_Pop16(); - // Push values for exception handler - CPU_Push16(SegValue(ss)); - CPU_Push16(reg_sp); - CPU_Push16(stack_flags); - CPU_Push16(stack_cs); - CPU_Push16(stack_eip); - CPU_Push16(errorCode); - CPU_Push16(GDT_PROTCODE); // return cs - CPU_Push16(DPMI_CB_EXCEPTIONRETURN_OFFSET); // return eip - }; - DPMI_LOG("DPMI: Exception occured : %04X (%04X:%08X)",num,dpmi.exceptionSelector[num],dpmi.exceptionOffset[num]); - CPU_JMP(dpmi.client.bit32,dpmi.exceptionSelector[num],dpmi.exceptionOffset[num]); -}; - -Bitu DPMI::ExceptionReturn(void) -{ - Bitu error; - // Restore Registers - Bitu newcs; - if (dpmi.client.bit32) { - error = CPU_Pop32(); - reg_eip = CPU_Pop32(); - newcs = CPU_Pop32(); - CPU_SetFlagsd(CPU_Pop32()); - reg_esp = CPU_Pop32(); - CPU_SetSegGeneral(ss,CPU_Pop32()); - } else { - error = CPU_Pop16(); - reg_eip = CPU_Pop16(); - newcs = CPU_Pop16(); - CPU_SetFlagsw(CPU_Pop16()); - reg_esp = CPU_Pop16(); - CPU_SetSegGeneral(ss,CPU_Pop16()); - }; - DPMI_LOG("DPMI: Return from Exception. Jump to %04X:%08X",SegValue(cs),reg_eip); - CPU_JMP(dpmi.client.bit32,newcs,reg_eip); - return 0; -}; - -void DPMI::RemoveIntCallbacks() -// When switching dpmi clients, remove active callbacks from hardware int -{ - Bitu i; - modIntTable = new Bit32u[256]; - // read and store interrupt table - for (i=0; i<256; i++) modIntTable[i] = mem_readd(i*4); - // set a clean interrupt table - for (i=0; i<256; i++) mem_writed(i*4,originalIntTable[i]); -}; - -void DPMI::RestoreIntCallbacks() -{ - if (modIntTable) { - // restore modified interrupt table - for (int i=0; i<256; i++) mem_writed(i*4,modIntTable[i]); - delete[] modIntTable; modIntTable = 0; - } -}; - -bool DPMI::AllocateRealModeCallback(Bitu codeSel,Bitu codeOff,Bitu dataSel, Bitu dataOff, Bitu& segment, Bitu& offset) -{ - Bitu num = 0; - for (Bitu i=0; i=DPMI_REALMODE_CALLBACK_MAX) || !dpmi.rmCallback[num].inUse) E_Exit("DPMI: Illegal Realmode callback %02X.",num); - - if (dpmi.rmCallback[num].inCall) DPMI_LOG("DPMI: Recursive Realmode callback %02X",num); - if (dpmi.protStackCurrent>DPMI_PROTMODE_STACK_MAX) E_Exit("DPMI: Too many recursive Realmode callbacks. Stack failure."); - - PushStack(num); - - DPMI_LOG("DPMI: Realmode Callback %02X (%04X:%08X) enter",num,dpmi.rmCallback[num].codeSelector,dpmi.rmCallback[num].codeOffset); - dpmi.rmCallback[num].inCall= true; - dpmi.rmCallback[num].callCount++; - - // Important! Update realmode stack - UpdateRealModeStack(); - // Setup stack selector of real mode stack - SetDescriptor desc; - if (cpu.gdt.GetDescriptor(dpmi.realStackSelector[dpmi.protStackCurrent],desc)) { - desc.SetBase (SegValue(ss)<<4); - desc.SetLimit(0xFFFF); - desc.Save (dpmi.ldt.base+(dpmi.realStackSelector[dpmi.protStackCurrent] & ~7)); - } else E_Exit("DPMI: RealmodeCB: Could not provide real mode stack descriptor."); - /* Switch to protected mode */ - SWITCH_TO_PROTMODE - // Setup dataSelector - Descriptor data; - Bitu dataSelector; - if (dpmi.rmCallback[num].dataSelector==0x0000) dataSelector = dpmi.dataSelector[dpmi.protStackCurrent]; - else dataSelector = dpmi.rmCallback[num].dataSelector; - if (!cpu.gdt.GetDescriptor(dataSelector,data)) E_Exit("DPMI: Init RM-Callback failed."); - - DPMI_LOG("DPMI: CB: Writing RegData at = %04X:%04X",dataSelector,dpmi.rmCallback[num].dataOffset); - // Prepare data buffer - CopyRegistersToBuffer(PhysPt(data.GetBase()+dpmi.rmCallback[num].dataOffset)); - DPMI_LOG("DPMI: CB: Stored cs:ip = %04X:%04X",SegValue(cs),reg_ip); - // setup registers for protected mode func - CPU_SetSegGeneral(ds,dpmi.realStackSelector[dpmi.protStackCurrent]); // DS:ESI = RM Stack - reg_esi = reg_esp; - CPU_SetSegGeneral(es,dataSelector); // ES:EDI = RM Register data - reg_edi = dpmi.rmCallback[num].dataOffset; - // SS:ESP = API stack - CPU_SetSegGeneral(ss,dpmi.protStackSelector[dpmi.protStackCurrent++]); - reg_esp = DPMI_PROTMODE_STACKSIZE; - // prepare stack for iret - if (dpmi.client.bit32) CPU_Push32(reg_flags); else CPU_Push16(reg_flags); - // Setup cs:ip to return to DPMI_ReturnFromRealModeCallback - CPU_SetSegGeneral(cs,GDT_CODE); - reg_eip = RealOff(CALLBACK_RealPointer(callback.rmCallbackReturn)); - // call protected mode func - SetVirtualIntFlag(false); - SETFLAGBIT(IF,false); - SETFLAGBIT(TF,false); - CPU_Push32(reg_flags); - CPU_CALL(dpmi.client.bit32,dpmi.rmCallback[num].codeSelector,dpmi.rmCallback[num].codeOffset); - return 0; -}; - -Bitu DPMI::RealModeCallbackReturn(void) -{ - // returning from protected mode function, now back to real mode - Bitu num = PopStack(); - DPMI_LOG("DPMI: Realmode Callback leave %02X",num); - dpmi.suppressRMCB = false; - dpmi.rmCallback[num].inCall = false; - dpmi.rmCallback[num].stop = false; - dpmi.rmCallback[num].callCount--; - PhysPt data = PhysPt(SegPhys(es)+reg_edi); - DPMI_LOG("DPMI: CB: Reading RegData at = %04X:%04X",SegValue(es),reg_edi); - /* Swtich to real mode */ - SWITCH_TO_REALMODE - dpmi.protStackCurrent--; - // Restore Registers - LoadRegistersFromBuffer(data); - Bitu newCS = mem_readw(data+0x2C); - Bitu newIP = mem_readw(data+0x2A); - UpdateRealModeStack(); - SetVirtualIntFlag(true); - DPMI_LOG("DPMI: CB: Retored cs:ip = %04X:%04X (%d)",newCS,newIP); - CPU_JMP(false,newCS,newIP); - return 0; -}; - -static Bitu count = 0; - -Bitu DPMI::CallRealIRETFrame(bool callAsInt) -{ - Bitu calledIP = mem_readd(SegPhys(ss)+reg_esp); - Bitu calledCS = mem_readd(SegPhys(ss)+reg_esp+4); - DPMI_LOG("DPMI: ENTER REAL PROC IRETF %04X:%08X",calledCS,calledIP); - // Save changed registers - PushStack(SegValue(cs)); - SaveRegister(); - Bitu toCopy = reg_cx; - // Load Registers - PhysPt data = SegPhys(es) + reg_edi; - PhysPt prStack = SegPhys(ss) + reg_esp; - LoadRegistersFromBuffer(data); - PushStack(data); - /* Switch to real mode */ - SWITCH_TO_REALMODE - // Provide Stack - ProvideRealModeStack(prStack,toCopy); - // Push flags - if (callAsInt) CPU_Push16(reg_flags); - // Setup IP - Bitu newCS = mem_readw(data+0x2C); - Bitu newIP = mem_readw(data+0x2A); - // Setup cs:ip to return to DPMI_CallRealIRETFrame callback - SegSet16(cs,RealSeg(CALLBACK_RealPointer(callback.rmIntFrameReturn))); - reg_ip = RealOff(CALLBACK_RealPointer(callback.rmIntFrameReturn)); - SetVirtualIntFlag(false); - SETFLAGBIT(IF,false); - SETFLAGBIT(TF,false); - CPU_CALL(false,newCS,newIP); - return 0; -} - -Bitu DPMI::CallRealIRETFrameReturn(void) -{ - UpdateRealModeStack(); - // returning from realmode func - DPMI_LOG("DPMI: LEAVE REAL PROC IRETF %d",count); - /* Switch to protected mode */ - SWITCH_TO_PROTMODE - // Save registers into real mode structure - CopyRegistersToBuffer(PopStack()); - // Restore changed Resgisters - RestoreRegister(); - Bitu newcs = PopStack(); - - CPU_JMP(dpmi.client.bit32,newcs,reg_eip); - - SetVirtualIntFlag(true); - DPMI_CALLBACK_SCF(false); - return 0; -}; - -Bitu DPMI::SimulateInt(void) -{ - Bitu num = reg_bl; - DPMI_LOG("DPMI: SIM INT %02X %04X called. cs = %04X",num,reg_ax,SegValue(cs)); - // Save changed registers - PushStack(SegValue(cs)); - SaveRegister(); - Bitu toCopy = reg_cx; - // Load Registers - PhysPt data = SegPhys(es) + reg_edi; - PhysPt prStack = SegPhys(ss) + reg_esp; - LoadRegistersFromBuffer(data); - PushStack(data); - /* Switch to real mode */ - SWITCH_TO_REALMODE - // Provide Stack - ProvideRealModeStack(prStack,toCopy); - // prepare for return - SegSet16(cs,RealSeg(CALLBACK_RealPointer(callback.simintReturn))); - reg_ip = RealOff(CALLBACK_RealPointer(callback.simintReturn)); - // Push flags from structure on stack - DPMI_LOG("DPMI: SimInt1: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_esp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); - reg_flags = mem_readw(data+0x20); - CPU_SW_Interrupt(num,0); - DPMI_LOG("DPMI: SimInt2: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_esp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); - return 0; -}; - -Bitu DPMI::SimulateIntReturn(void) -{ - // returning from realmode func - DPMI_LOG("DPMI: SIM INT return"); - DPMI_LOG("DPMI: SimIntRet1: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_esp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); - - UpdateRealModeStack(); - /* Switch to protected mode */ - SWITCH_TO_PROTMODE - // Save registers into real mode structure - CopyRegistersToBuffer(PopStack()); - // Restore changed Resgisters - RestoreRegister(); - Bitu newcs = PopStack(); - DPMI_LOG("DPMI: SimIntRet: JUMP to %04X:%08X",newcs,reg_eip); - CPU_JMP(dpmi.client.bit32,newcs,reg_eip); - SetVirtualIntFlag(true); - // Free last realmode stack - DPMI_CALLBACK_SCF(false); - DPMI_LOG("DPMI: SimIntRet2: StackInfo %04X:%04X (%02X %02X)",SegValue(ss),reg_esp,mem_readb(0xD0100+0x01FA),mem_readb(0xD0100+0x01FB)); - return 0; -}; - -void DPMI::PrepareReflectToReal(Bitu num) -{ - // Save segment and stack register - SaveSegments(); - PushStack(reg_esp); - PushStack(num); - PushStack(reg_eip); - PushStack(SegValue(cs)); - /* Swtich to real mode */ - SWITCH_TO_REALMODE - // Setup cs:ip to return to intreturn - Bitu retcs = RealSeg(CALLBACK_RealPointer(callback.ptorintReturn)); - Bitu retip = RealOff(CALLBACK_RealPointer(callback.ptorintReturn)); - - SegSet16(cs,RealSeg(CALLBACK_RealPointer(callback.ptorintReturn))); - reg_ip = RealOff(CALLBACK_RealPointer(callback.ptorintReturn)); - // setup stack - SegSet16(ss,rm_ss); - reg_esp = rm_sp; -} - -Bitu DPMI::ptorHandler(void) -{ - /* Pmode interrupt handler that maps the interrupt to realmode */ - Bitu num = reg_eip >> 3; -// if (!dpmi.vIntFlag) { -// if ((num>=0x08) && (num<=0x0F)) return 0; -// if ((num>=0x70) && (num<=0x77)) return 0; -// }; - PrepareReflectToReal(num); -// if (num==0x0F) - DPMI_LOG("DPMI: INT %02X %04X called.",num,reg_ax); - // Prepare flags for real int - // CPU_SetFlagsw(reg_flags & 0x3ED5); // 0011111011010101b - CPU_SW_Interrupt(num,0); - return 0; -} - -Bitu DPMI::ptorHandlerReturn(void) -// Return from reflected real mode int -{ - UpdateRealModeStack(); - /* Switch to protected mode */ - SWITCH_TO_PROTMODE - // Restore Registers - Bitu newcs = PopStack(); - reg_eip = PopStack(); - Bitu num = PopStack(); - reg_esp = PopStack(); - RestoreSegments(); -// if (num==0x0F) - DPMI_LOG("DPMI: INT %02X RETURN",num); - // hardware ints exit here - if (((num>=0x08) && (num<=0x0F)) || ((num>=0x70) && (num<=0x77))) { - SetVirtualIntFlag(true); - CPU_JMP(dpmi.client.bit32,newcs,reg_eip); - return 0; - } - // Change flags on stack to reflect possible results from ints - if (dpmi.client.bit32) { - Bit32u oldFlags = mem_readd(SegPhys(ss)+reg_esp+8) & ~FMASK_TEST; // leave only flags that cannot be changed by int - Bit32u userFlags = reg_flags & FMASK_NORMAL; // Mask out illegal flags not to change by int (0011111011010101b) - mem_writed(SegPhys(ss)+reg_esp+8,oldFlags|userFlags); - } else { - Bit16u oldFlags = mem_readw(SegPhys(ss)+reg_sp+4) & ~FMASK_TEST; // leave only flags that cannot be changed by int - Bit16u userFlags = reg_flags & FMASK_NORMAL; // Mask out illegal flags not to change by int (0011111011010101b) - mem_writew(SegPhys(ss)+reg_sp+4,oldFlags|userFlags); - }; - SetVirtualIntFlag(true); - CPU_JMP(dpmi.client.bit32,newcs,reg_eip); - return 0; -} - -Bitu DPMI::Int21Handler(void) -{ - // Check for exit - if (reg_ah==0x4C) { - DPMI_LOG("DPMI: INT 21: Terminating."); - Terminate(); - } - // Save segment and stack register - PushStack(SegValue(ss)); - PushStack(reg_esp); - PushStack(SegValue(ds)); - PushStack(SegValue(es)); - PushStack(SegValue(cs)); - - /* Swtich to real mode */ - SWITCH_TO_REALMODE - // Setup cs:ip to return to intreturn - SegSet16(cs,RealSeg(CALLBACK_RealPointer(callback.int21Return))); - reg_ip = RealOff(CALLBACK_RealPointer(callback.int21Return)); - // setup stack - SegSet16(ss,rm_ss); - reg_esp = rm_sp; - // Call realmode interrupt - DPMI_LOG("DPMI: INT 21 %04X called.",reg_ax); - CPU_SW_Interrupt(0x21,0); - if (reg_ah==0x4C) { - // Shut doen dpmi and restore previous one - delete this; - if (activeDPMI) activeDPMI->Reactivate(); - } - return 0; -}; - -Bitu DPMI::Int21HandlerReturn(void) -{ - UpdateRealModeStack(); - /* Switch to protected mode */ - SWITCH_TO_PROTMODE - // Restore Registers - Bitu newcs = PopStack(); - CPU_SetSegGeneral(es,PopStack()); - CPU_SetSegGeneral(ds,PopStack()); - reg_esp = PopStack(); - CPU_SetSegGeneral(ss,PopStack()); - // Set carry flag - DPMI_CALLBACK_SCF(reg_flags & 1); - DPMI_LOG("DPMI: INT 21 RETURN"); - SetVirtualIntFlag(true); - CPU_JMP(dpmi.client.bit32,newcs,reg_eip); - return 0; -} - -Bitu DPMI::HWIntDefaultHandler() -// Wir sind hier im Protected mode -// a) durch einen INTerrupt im protected mode -// b) durch einen INTerrupt im real mode (durch RMCB) -{ - Bitu index = mem_readw(PhysPt(SegPhys(cs)+reg_eip-2)) - dpmi.defaultHWIntFromProtMode[0]; - if (index>=DPMI_REALVEC_MAX) E_Exit("DPMI: Illegal realmode interrupt callback: %02X",index); - Bitu num = rmIndexToInt[index]; - - RealPt vec = RealGetVec(num); - - if (dpmi.rmCallback[index].callCount==0) { - // INT PROT (Use Handler is already done). - // Wenn rmcb noch in Realmode Int table installiert, dann originalMethode aufrufef - if (vec==dpmi.realModeVec[index]) { - // originalroutine aufrufen - dpmi.rmCallback[index].stop = false; - PrepareReflectToReal(num); - CPU_Push16(reg_flags); - SetVirtualIntFlag(false); - SETFLAGBIT(IF,false); - SETFLAGBIT(TF,false); - CPU_CALL(false,RealSeg(dpmi.oldRealVec[index]),RealOff(dpmi.oldRealVec[index])); - } else { - // user real mode handler in real mode int table aktiv. - // Moeglich, dass dieser den RMCB von Hand noch aufruft - // dann wird aber callCount>0 sein (da RMCB aktiv) und - // dann die alte Routine aufgerufen... - // RMCB sperren, um einen erneuten Aufruf des User Handlers zu vermeiden,.. - - // This is a hack for cybermage wich wont work otherwise. But why ? - if (num==0x0F) { - if (dpmi.suppressRMCB) { - dpmi.suppressRMCB = false; - return 0; - } else { - dpmi.suppressRMCB = true; - } - }; - PrepareReflectToReal(num); - SetVirtualIntFlag(false); - SETFLAGBIT(IF,false); - SETFLAGBIT(TF,false); - CPU_Push16(reg_flags); - CPU_CALL(false,RealSeg(vec),RealOff(vec)); - } - } else { - // INT REAL (vom RMCB aktiviert) - // Falls user handler schon aktiv war (int von prot->reflected to real) - // rufe original routine auf - if (dpmi.rmCallback[index].stop) { - dpmi.rmCallback[index].stop = false; - PrepareReflectToReal(num); - CPU_Push16(reg_flags); - SetVirtualIntFlag(false); - SETFLAGBIT(IF,false); - SETFLAGBIT(TF,false); - CPU_CALL(false,RealSeg(dpmi.oldRealVec[index]),RealOff(dpmi.oldRealVec[index])); - } else { - // User routine wurde noch nicht aktiviert, callback aber ausgeführt - // falls spezieller protected mode handler aktiviert wurde, - // wird dieser jetzt aufgerufen (user routine im protected mode) - Descriptor gate; - gate.Load(dpmi.idt.base+num*8); - if ((gate.GetSelector()!=GDT_CODE) || (gate.GetOffset()!=RealOff(dpmi.defaultHWIntFromProtMode[index]))) { - dpmi.rmCallback[index].stop = true; // vermeide rekursion - CPU_JMP(dpmi.client.bit32,gate.GetSelector(),gate.GetOffset()); - } else { - // kein spezieller Protmode handler - Rufe originalroutine auf - PrepareReflectToReal(num); - CPU_Push16(reg_flags); - SetVirtualIntFlag(false); - SETFLAGBIT(IF,false); - SETFLAGBIT(TF,false); - CPU_CALL(false,RealSeg(dpmi.oldRealVec[index]),RealOff(dpmi.oldRealVec[index])); - }; - }; - } - return 0; -}; - -void DPMI::SaveRegisterState(Bitu num) -// Copy Current Registers to structure -{ - return; - save_cs[num] = SegValue(cs); - save_ds[num] = SegValue(ds); - save_es[num] = SegValue(es); - save_fs[num] = SegValue(fs); - save_gs[num] = SegValue(gs); - save_ss[num] = SegValue(ss); - save_eip[num] = reg_eip; - save_eax[num] = reg_eax; - save_ebx[num] = reg_ebx; - save_ecx[num] = reg_ecx; - save_edx[num] = reg_edx; - save_esi[num] = reg_esi; - save_edi[num] = reg_edi; - save_ebp[num] = reg_ebp; - save_esp[num] = reg_esp; - save_fl [num] = reg_flags; -}; - -void DPMI::LoadRegisterState(Bitu num) -// Copy Current Registers to structure -{ - return; - CPU_SetSegGeneral(fs,save_fs[num]); - CPU_SetSegGeneral(gs,save_gs[num]); - reg_eax = save_eax[num]; - reg_ebx = save_ebx[num]; - reg_ecx = save_ecx[num]; - reg_edx = save_edx[num]; - reg_esi = save_esi[num]; - reg_edi = save_edi[num]; - reg_flags = save_fl [num]; -}; - -Bitu DPMI::EnterProtMode(void) { - - /* Save real mode register state */ - SaveRegisterState(0); - - /* Switch to protected mode */ - SWITCH_TO_PROTMODE - - CPU_SetSegGeneral(ds,reg_ax); - CPU_SetSegGeneral(es,reg_cx); - CPU_SetSegGeneral(ss,reg_dx); - CPU_SetSegGeneral(ds,reg_ax); - - if (dpmi.client.bit32) { - reg_esp = reg_ebx; - CPU_JMP(true,reg_si,reg_edi); - } else { - reg_sp = reg_bx; - CPU_JMP(false,reg_si,reg_di); - }; - - /* Load prot mode register state (all other unchanged registers */ - LoadRegisterState(1); - - DPMI_LOG("DPMI: Switch to protected mode."); - return 0; -} - -Bitu DPMI::EnterRealMode(void) { - - /* Save Prot Mode Registers */ - SaveRegisterState(1); - - /* Swtich to real mode */ - SWITCH_TO_REALMODE - // (E)BP will be preserved across the mode switch call so it can be used as a pointer. - // TODO: If interrupts are disabled when the mode switch procedure is invoked, - // they will not be re-enabled by the DPMI host (even temporarily). - SegSet16(ds,reg_ax); - SegSet16(es,reg_cx); - SegSet16(ss,reg_dx); - SegSet16(fs,0); - SegSet16(gs,0); - if (dpmi.client.bit32) { - reg_esp = reg_ebx; - CPU_JMP(true,reg_si,reg_edi); - } else { - reg_sp = reg_bx; - CPU_JMP(false,reg_si,reg_di); - }; - - /* Load real mode register state (all other unchanged registers) */ - LoadRegisterState(0); - DPMI_LOG("DPMI: Switch to real mode."); - return CBRET_NONE; -}; - -Bitu DPMI::RealSaveState(void) -{ - return CBRET_NONE; - /* Save Protected mode state */ - if (reg_al==0) { - PhysPt data = SegPhys(es) + reg_edi; - mem_writew(data+ 0,save_cs[1]); - mem_writew(data+ 2,save_ds[1]); - mem_writew(data+ 4,save_es[1]); - mem_writew(data+ 6,save_fs[1]); - mem_writew(data+ 8,save_gs[1]); - mem_writew(data+10,save_ss[1]); - mem_writed(data+12,save_eax[1]); - mem_writed(data+16,save_ebx[1]); - mem_writed(data+20,save_ecx[1]); - mem_writed(data+24,save_edx[1]); - mem_writed(data+28,save_esi[1]); - mem_writed(data+32,save_edi[1]); - mem_writed(data+36,save_ebp[1]); - mem_writed(data+40,save_esp[1]); - mem_writed(data+44,save_fl [1]); - DPMI_LOG("DPMI: Prot Save State."); - } else if (reg_al==1) { - /* restore state of prot mode registers */ - PhysPt data = SegPhys(es) + reg_edi; - save_cs [1] = mem_readw(data+ 0); - save_ds [1] = mem_readw(data+ 2); - save_es [1] = mem_readw(data+ 4); - save_fs [1] = mem_readw(data+ 6); - save_gs [1] = mem_readw(data+ 8); - save_ss [1] = mem_readw(data+10); - save_eax[1] = mem_readd(data+12); - save_ebx[1] = mem_readd(data+16); - save_ecx[1] = mem_readd(data+20); - save_edx[1] = mem_readd(data+24); - save_edi[1] = mem_readd(data+28); - save_esi[1] = mem_readd(data+32); - save_ebp[1] = mem_readd(data+36); - save_esp[1] = mem_readd(data+40); -// save_eip[1] = mem_readd(data+44); - save_fl [1] = mem_readd(data+44); - DPMI_LOG("DPMI: Prot Restore State."); - }; - return CBRET_NONE; -}; - -Bitu DPMI::ProtSaveState(void) -{ - return CBRET_NONE; - if (reg_al==0) { - /* Save State of real mode registers */ - PhysPt data = SegPhys(es) + reg_edi; - mem_writew(data+ 0,save_cs[0]); - mem_writew(data+ 2,save_ds[0]); - mem_writew(data+ 4,save_es[0]); - mem_writew(data+ 6,save_fs[0]); - mem_writew(data+ 8,save_gs[0]); - mem_writew(data+10,save_ss[0]); - mem_writed(data+12,save_eax[0]); - mem_writed(data+16,save_ebx[0]); - mem_writed(data+20,save_ecx[0]); - mem_writed(data+24,save_edx[0]); - mem_writed(data+28,save_esi[0]); - mem_writed(data+32,save_edi[0]); - mem_writed(data+36,save_ebp[0]); - mem_writed(data+40,save_esp[0]); - mem_writed(data+44,save_eip[0]); - mem_writed(data+48,save_fl [0]); - DPMI_LOG("DPMI: Real Save State."); - } else if (reg_al==1) { - /* restore state of real mode registers */ - PhysPt data = SegPhys(es) + reg_edi; - save_cs [0] = mem_readw(data+ 0); - save_ds [0] = mem_readw(data+ 2); - save_es [0] = mem_readw(data+ 4); - save_fs [0] = mem_readw(data+ 6); - save_gs [0] = mem_readw(data+ 8); - save_ss [0] = mem_readw(data+10); - save_eax[0] = mem_readd(data+12); - save_ebx[0] = mem_readd(data+16); - save_ecx[0] = mem_readd(data+20); - save_edx[0] = mem_readd(data+24); - save_edi[0] = mem_readd(data+28); - save_esi[0] = mem_readd(data+32); - save_ebp[0] = mem_readd(data+36); - save_esp[0] = mem_readd(data+40); - save_eip[0] = mem_readd(data+44); - save_fl [0] = mem_readd(data+48); - DPMI_LOG("DPMI: Real Restore State."); - }; - return CBRET_NONE; -}; - -bool DPMI::GetVirtualIntFlag(void) -// only to call from int 31 cos it uses the pushed flags on int stack -{ - if (dpmi.client.bit32) return (mem_readd(SegPhys(ss)+reg_esp+8) & FLAG_IF)>0; - else return (mem_readd(SegPhys(ss)+reg_sp+4) & FLAG_IF)>0; -}; - -void DPMI::SetVirtualIntFlag(bool on) -{ - dpmi.vIntFlag = 1; //on; -}; - -bool DPMI::AllocateMem(Bitu size, Bitu& outHandle, Bitu& linear) -{ - Bitu pages = (size/DPMI_PAGE_SIZE) + ((size%DPMI_PAGE_SIZE)>0); // Convert to 4KB pages - outHandle = MEM_AllocatePages(pages,true); - linear = outHandle*DPMI_PAGE_SIZE; - if (outHandle!=0) SetXMSHandle(outHandle); - return (outHandle!=0); -}; - -bool DPMI::SetAccessRights(Bitu selector, SetDescriptor& desc, Bitu rights) -{ - // must equal caller DPL - if (((rights & 0x60)>>5)!=DPMI_DPL) { - DPMI_LOG("DPMI: Set Rights %04X : %04X failure (dpl=%02X)",selector,rights,(rights & 0x60)>>5); -// return false; - } - // must be 1 - if ((rights & 0x10)==0) { - DPMI_LOG_ERROR("DPMI: Set Rights %04X : %04X failure (must be 1)",selector,rights); - return false; - }; - // must be 0 - if (dpmi.client.bit32 && desc.saved.seg.p && (rights & 0x2000)) { - DPMI_LOG_ERROR("DPMI: Set Rights %04X : %04X failure (must be 0)",selector,rights); - return false; - }; - // all tests passed, set rights for 16 + 32 Bit - desc.SetType (rights&0x1F); - desc.saved.seg.dpl = (rights&0x60)>>5; - desc.saved.seg.dpl = DPMI_DPL; - desc.saved.seg.p = (rights&0x80)>0; - // extended rights for 32 Bit apps - if (dpmi.client.bit32) { - desc.saved.seg.avl = (rights&0x1000)>0; - desc.saved.seg.r = (rights&0x2000)>0; - desc.saved.seg.big = (rights&0x4000)>0; - desc.saved.seg.g = (rights&0x8000)>0; - }; - return true; -}; - -Bitu DPMI::Int31Handler(void) -{ - switch (reg_ax) { - - case 0x0000:{// Allocate LDT Descriptors - Bitu base; - Descriptor desc; - if (AllocateLDTDescriptor(reg_cx,base)) { - reg_ax = base; - DPMI_LOG("DPMI: 0000: Allocate %d descriptors: %04X",reg_cx,base); - DPMI_CALLBACK_SCF(false); - } else { - DPMI_LOG_ERROR("DPMI: 0000: Allocate %d descriptors failure",reg_cx); - reg_ax = DPMI_ERROR_DESCRIPTOR_UNAVAILABLE; - DPMI_CALLBACK_SCF(true); - }; - }; break; - case 0x0001:{// Free Descriptor - SetDescriptor desc; - if (cpu.gdt.GetDescriptor(reg_bx,desc)) { - desc.saved.seg.p = 0; - desc.Save (dpmi.ldt.base+(reg_bx & ~7)); - DPMI_LOG("DPMI: 0001: Free Descriptor: %04X",reg_bx); - DPMI_CALLBACK_SCF(false); - } else { - DPMI_LOG_ERROR("DPMI: 0001: Free Descriptor failure : %04X",reg_bx); - reg_ax = DPMI_ERROR_INVALID_SELECTOR; - DPMI_CALLBACK_SCF(true); - }; - }; break; - case 0x0002:{// Segment to Descriptor - SetDescriptor desc; Bitu base; - if (AllocateLDTDescriptor(1,base)) { - desc.Load (dpmi.ldt.base+(base & ~7)); - desc.SetLimit(0xFFFF); - desc.SetBase (reg_bx<<4); - desc.saved.seg.dpl=3; - desc.Save (dpmi.ldt.base+(base & ~7)); - reg_ax = base; - DPMI_LOG("DPMI: 0000: Seg %04X to Desc: %04X",reg_bx,base); - DPMI_CALLBACK_SCF(false); - } else { - // No more Descriptors available - DPMI_LOG_ERROR("DPMI: 0002: No more Descriptors available."); - reg_ax = DPMI_ERROR_DESCRIPTOR_UNAVAILABLE; - DPMI_CALLBACK_SCF(true); - }; - }; break; - case 0x0003:// Get Next Selector Increment Value - reg_ax = 8; - DPMI_LOG("DPMI: 0003: Get Selector Inc Value: %04X",reg_ax); - DPMI_CALLBACK_SCF(false); - break; - case 0x0004:// undocumented (reserved) lock selector - case 0x0005:// undocumented (reserved) unlock selector - DPMI_LOG("DPMI: 0004: Undoc: (un)lock selector",reg_ax); - DPMI_CALLBACK_SCF(true); - break; - case 0x0006:{ // Get Segment Base Address - SetDescriptor desc; - if (cpu.gdt.GetDescriptor(reg_bx,desc)) { - DPMI_LOG("DPMI: 0006: Get Base %04X : B:%08X",reg_bx,desc.GetBase()); - reg_cx = (Bit16u)(desc.GetBase()>>16); - reg_dx = (Bit16u)(desc.GetBase()&0xFFFF); - DPMI_CALLBACK_SCF(false); - } else { - DPMI_LOG_ERROR("DPMI: 0006: Invalid Selector: %04X",reg_bx); - reg_ax = DPMI_ERROR_INVALID_SELECTOR; - DPMI_CALLBACK_SCF(true); - }; - }; break; - case 0x0007:{// Set Segment base address - SetDescriptor desc; - if (cpu.gdt.GetDescriptor(reg_bx,desc)) { - Bitu base; - if (!dpmi.client.bit32) base = (reg_cl<<16)+reg_dx; - else base = (reg_cx<<16)+reg_dx; - desc.SetBase(base); - desc.Save (dpmi.ldt.base+(reg_bx & ~7)); - ReloadSegments(reg_bx); - DPMI_CALLBACK_SCF(false); - DPMI_LOG("DPMI: 0007: Set Base %04X : B:%08X",reg_bx,base); - } else { - DPMI_LOG_ERROR("DPMI: 0007: Invalid Selector: %04X",reg_bx); - reg_ax = DPMI_ERROR_INVALID_SELECTOR; - DPMI_CALLBACK_SCF(true); - }; - }; break; - case 0x0008:{// Set Segment limit - SetDescriptor desc; - if ((!dpmi.client.bit32) && (reg_cx!=0)) { - // 16-bit DPMI implementations can not set segment limits greater - // than 0FFFFh (64K) so CX must be zero when calling - DPMI_LOG_ERROR("DPMI: 0008: Set Segment Limit invalid: %04X (%04X%04X)",reg_bx,reg_cx,reg_dx); - reg_ax = DPMI_ERROR_INVALID_VALUE; - DPMI_CALLBACK_SCF(true); - } else if (cpu.gdt.GetDescriptor(reg_bx,desc)) { - desc.SetLimit((reg_cx<<16)+reg_dx); - desc.Save (dpmi.ldt.base+(reg_bx & ~7)); - ReloadSegments(reg_bx); - DPMI_CALLBACK_SCF(false); - DPMI_LOG("DPMI: 0008: Set Limit %08X",(reg_cx<<16)+reg_dx); - } else { - DPMI_LOG_ERROR("DPMI: 0008: Invalid Selector: %04X",reg_bx); - reg_ax = DPMI_ERROR_INVALID_SELECTOR; - DPMI_CALLBACK_SCF(true); - }; - }; break; - case 0x0009:{// Set Descriptor Access Rights - SetDescriptor desc; - Bit8u rcl = reg_cl; - Bit8u rch = reg_ch; - if (cpu.gdt.GetDescriptor(reg_bx,desc)) { - if (!SetAccessRights(reg_bx,desc,reg_cx)) { - DPMI_LOG_ERROR("DPMI: 0009: Set Rights %04X : failure",reg_bx); - reg_ax = DPMI_ERROR_INVALID_VALUE; - DPMI_CALLBACK_SCF(true); - break; - }; - desc.Save(dpmi.ldt.base+(reg_bx & ~7)); - ReloadSegments(reg_bx); - DPMI_CALLBACK_SCF(false); - DPMI_LOG("DPMI: 0009: Set Rights %04X : %04X",reg_bx,reg_cx); - } else { - DPMI_LOG_ERROR("DPMI: 0009: Set Rights %04X : invalid selector",reg_bx); - reg_ax = DPMI_ERROR_DESCRIPTOR_UNAVAILABLE; - DPMI_CALLBACK_SCF(true); - }; - }; break; - case 0x000A:{// Create Alias Descriptor - Descriptor desc; - if (CreateAlias(reg_bx, reg_ax)) { - DPMI_LOG("DPMI: 000A: Create Alias : %04X - %04X",reg_bx,reg_ax); - DPMI_CALLBACK_SCF(false); - } else { - DPMI_CALLBACK_SCF(true); - DPMI_LOG_ERROR("DPMI: 000A: Invalid Selector: %04X",reg_bx); - }; }; break; - case 0x000B:{//Get Descriptor - SetDescriptor desc; - if (cpu.gdt.GetDescriptor(reg_bx,desc)) { - desc.Save(SegPhys(es)+Mask(reg_edi)); - DPMI_CALLBACK_SCF(false); - DPMI_LOG("DPMI: 000B: Get Descriptor %04X : B:%08X L:%08X",reg_bx,desc.GetBase(),desc.GetLimit()); - } else { - DPMI_LOG_ERROR("DPMI: 000B: Get Descriptor %04X : failure",reg_bx); - reg_ax = DPMI_ERROR_DESCRIPTOR_UNAVAILABLE; - DPMI_CALLBACK_SCF(true); - }; - }; break; - case 0x000C:{//Set Descriptor - SetDescriptor desc; - if (cpu.gdt.GetDescriptor(reg_bx,desc)) { - desc.Load (SegPhys(es)+Mask(reg_edi)); - Bitu rights = (mem_readb(SegPhys(es)+Mask(reg_edi)+6)<<8) + mem_readb(SegPhys(es)+Mask(reg_edi)+5); - if (!SetAccessRights(reg_bx,desc,rights)) { - DPMI_LOG_ERROR("DPMI: 000C: Set Rights %04X : failure",reg_bx); - reg_ax = DPMI_ERROR_INVALID_VALUE; - DPMI_CALLBACK_SCF(true); - break; - }; - // TEMP : Test -/* if (!dpmi.client.bit32) { - if (desc.GetLimit()>0xFFFF) { - DPMI_LOG_ERROR("DPMI: 000C: Set Limit %04X : failure (%08X)",reg_bx,desc.GetLimit()); - desc.SetLimit(0xFFFF); - } - if (desc.GetBase ()>0xFFFFFF) { - DPMI_LOG_ERROR("DPMI: 000C: Set Base %04X : failure (%08X)",reg_bx,desc.GetBase()); - desc.SetBase(desc.GetBase() % 0xFFFFFF); - } - }*/ - desc.Save(dpmi.ldt.base+(reg_bx & ~7)); - ReloadSegments(reg_bx); - DPMI_LOG("DPMI: 000B: Set Descriptor %04X : B:%08X L:%08X : P %01X",reg_bx,desc.GetBase(),desc.GetLimit(),desc.saved.seg.p); - DPMI_CALLBACK_SCF(false); - } else { - DPMI_LOG_ERROR("DPMI: 000C: Set Descriptor %04X failed",reg_bx); - reg_ax = DPMI_ERROR_DESCRIPTOR_UNAVAILABLE; - DPMI_CALLBACK_SCF(true); - }; - }; break; - case 0x000D:{ // Allocate specific LDT Descriptor : TODO: Support it - DPMI_LOG("DPMI: 000D: Alloc Specific LDT Selector: %04X",reg_bx); - SetDescriptor desc; - if (cpu.gdt.GetDescriptor(reg_bx,desc)) { -// if (!desc.saved.seg.p) { - desc.saved.seg.p = 1; -// desc.SetLimit(0xDEADAAAA); -// desc.SetBase (0xDEADBBBB); - desc.Save (dpmi.ldt.base+(reg_bx & ~7)); - DPMI_CALLBACK_SCF(false); - break; -// } else { -// DPMI_LOG_ERROR("DPMI: 000D: Invalid Selector: %04X",reg_bx); -// reg_ax = DPMI_ERROR_DESCRIPTOR_UNAVAILABLE; -// }; - } else reg_ax = DPMI_ERROR_INVALID_SELECTOR; - DPMI_CALLBACK_SCF(true); - }; break; - case 0x0100:{// Allocate DOS Memory Block - Bit16u blocks = reg_bx; - DPMI_LOG("DPMI: 0100: Allocate DOS Mem: (%04X Blocks)",blocks); - if (DOS_AllocateMemory(®_ax,&blocks)) { - // Allocate Selector for block - SetDescriptor desc; Bitu base; Bitu numDesc; - numDesc = reg_bx/0x1000 + ((reg_bx%0x1000)>0); - if (AllocateLDTDescriptor(numDesc,base)) { - reg_dx = base; - // First selector - if (numDesc>1) { - Bitu descBase = reg_ax*16; - Bitu length = reg_bx*16; - desc.Load (dpmi.ldt.base+(base & ~7)); - desc.SetBase (descBase); - desc.SetLimit(dpmi.client.bit32?length:0xFFFF); - desc.Save (dpmi.ldt.base+(base & ~7)); - for (Bitu i=1; i>4; - DOS_MCB mcb(seg-1); - Bitu size = mcb.GetSize()*16; - if (DOS_FreeMemory(seg)) { - while (size>0) { - desc.Load(dpmi.ldt.base+(sel & ~7)); - desc.saved.seg.p = 0; - desc.Save(dpmi.ldt.base+(sel & ~7)); - size -= (size>=0x10000)?0x10000:size; - sel+=8; - }; - DPMI_CALLBACK_SCF(false); - DPMI_LOG("DPMI: 0101: Free Dos Mem: %04X",reg_dx); - break; - } - } - DPMI_LOG_ERROR("DPMI: 0101: Invalid Selector: %04X",reg_bx); - reg_ax = DPMI_ERROR_INVALID_SELECTOR; - DPMI_CALLBACK_SCF(true); - };break; - case 0x0200:{// Get Real Mode Interrupt Vector - RealPt vec = RealGetVec(reg_bl); - reg_cx = RealSeg(vec); - reg_dx = RealOff(vec); - DPMI_LOG("DPMI: 0200: Get Real Int Vector %02X (%04X:%04X)",reg_bl,reg_cx,reg_dx); - DPMI_CALLBACK_SCF(false); - }; break; - case 0x0201:{// Set Real Mode Interrupt Vector - DPMI_LOG("DPMI: 0201: Set Real Int Vector %02X (%04X:%04X)",reg_bl,reg_cx,reg_dx); - RealSetVec(reg_bl,RealMake(reg_cx,reg_dx)); - DPMI_CALLBACK_SCF(false); - }; break; - case 0x0202:// Get Processor Exception Handler Vector - if (reg_bl>16; - reg_di = handle&0xFFFF; - reg_bx = linear>>16; - reg_cx = linear&0xFFFF; - DPMI_CALLBACK_SCF(false); - // TEMP -// Bitu total = MEM_FreeLargest(); // in KB -// DPMI_LOG_ERROR("DPMI: 0501: Allocation success: H:%04X%04X (%d KB) (R:%d KB)",reg_si,reg_di,length/1024 + ((length%1024)>0),total*4); - } else { - reg_ax = DPMI_ERROR_PHYSICAL_MEMORY_UNAVAILABLE; - DPMI_CALLBACK_SCF(true); - // TEMP - Bitu total = MEM_FreeLargest(); // in KB - DPMI_LOG("DPMI: 0501: Allocation failure (%d KB) (R:%d KB)",length/1024 + ((length%1024)>0),total*4); - }; - }; break; - case 0x0502://Free Memory Block - DPMI_LOG("DPMI: 0502: Free Mem: H:%04X%04X",reg_si,reg_di); - MEM_ReleasePages((reg_si<<16)+reg_di); - FreeXMSHandle((reg_si<<16)+reg_di); - DPMI_CALLBACK_SCF(false); - break; - case 0x0503:{//Resize Memory Block - Bitu linear,newHandle; - Bitu newByte = (reg_bx<<16)+reg_cx; - Bitu newSize = (newByte/DPMI_PAGE_SIZE)+((newByte & (DPMI_PAGE_SIZE-1))>0); - MemHandle handle = (reg_si<<16)+reg_di; - DPMI_LOG("DPMI: 0503: Resize Memory: H:%08X (%d KB)",handle,newSize*4); - if (MEM_ReAllocatePages(handle,newSize,true)) { - linear = handle * DPMI_PAGE_SIZE; - reg_si = (Bit16u)(handle>>16); - reg_di = (Bit16u)(handle&0xFFFF); - reg_bx = (Bit16u)(linear>>16); - reg_cx = (Bit16u)(linear&0xFFFF); - DPMI_CALLBACK_SCF(false); - } else if (AllocateMem(newByte,newHandle,linear)) { - // Not possible, try to allocate - DPMI_LOG("DPMI: 0503: Reallocated Memory: %d KB",newSize*4); - reg_si = (Bit16u)(newHandle>>16); - reg_di = (Bit16u)(newHandle&0xFFFF); - reg_bx = (Bit16u)(linear>>16); - reg_cx = (Bit16u)(linear&0xFFFF); - // copy contents - Bitu size = MEM_AllocatedPages(handle); - if (newSize>16; - reg_cx = linear & 0xFFFF; - DPMI_LOG_ERROR("DPMI: 0800: Phys-adr-map not supported : Start:%08X (Size:%08X) - Linear:%08X.",phys,size,linear); - DPMI_CALLBACK_SCF(false); - }; break; - case 0x0801:// Free physical address mapping - DPMI_LOG("DPMI: 0801: Free physical address mapping"); - DPMI_CALLBACK_SCF(false); - break; - case 0x0900://Get and Disable Virtual Interrupt State - reg_al = dpmi.vIntFlag; - dpmi.vIntFlag = 0; - DPMI_LOG("DPMI: 0900: Get and disbale vi : %01X",reg_al); - DPMI_CALLBACK_SCF(false); - break; - case 0x0901://Get and Enable Virtual Interrupt State - reg_al = dpmi.vIntFlag; - dpmi.vIntFlag = 1; - DPMI_LOG("DPMI: 0901: Get and enable vi : %01X",reg_al); - DPMI_CALLBACK_SCF(false); - break; - case 0x0902:{//Get Virtual Interrupt State - reg_al = 0; //dpmi.vIntFlag; - DPMI_LOG("DPMI: 0902: Get vi : %01X",reg_al); - DPMI_CALLBACK_SCF(false); - }; break; - case 0x0A00:{//Get Vendor Specific API Entry Point - char name[256]; - MEM_StrCopy(SegPhys(ds)+Mask(reg_esi),name,255); - LOG(LOG_MISC,LOG_WARN)("DPMI: Get API: %s",name); - if (strcmp(name,"MS-DOS")==0) { - CPU_SetSegGeneral(es,GDT_PROTCODE); - if (dpmi.client.bit32) reg_edi = DPMI_CB_APIMSDOSENTRY_OFFSET; - else reg_di = DPMI_CB_APIMSDOSENTRY_OFFSET; - API_Init_MSDOS(); - DPMI_CALLBACK_SCF(false); - } else if (strstr(name,"HWINT_SUPPORT")!=0) { - reg_ax = DPMI_ERROR_UNSUPPORTED; - DPMI_CALLBACK_SCF(true); - } else if (strstr(name,"CE_SUPPORT")!=0) { - reg_ax = DPMI_ERROR_UNSUPPORTED; - DPMI_CALLBACK_SCF(true); - } else if (strstr(name,"PHARLAP")!=0) { - CPU_SetSegGeneral(es,GDT_PROTCODE); - if (dpmi.client.bit32) reg_edi = DPMI_CB_APIMSDOSENTRY_OFFSET; - else reg_di = DPMI_CB_APIMSDOSENTRY_OFFSET; - API_Init_MSDOS(); - DPMI_CALLBACK_SCF(false); - dpmi.pharlap = true; - } else { - reg_ax = DPMI_ERROR_UNSUPPORTED; - DPMI_CALLBACK_SCF(true); - } - }; break; - case 0x0D00:{//Allocate Shared Memory - char name[256]; - PhysPt data = SegPhys(es)+Mask(reg_edi); - Bitu length = mem_readd(data); - Bitu pages = (length/DPMI_PAGE_SIZE)+((length%DPMI_PAGE_SIZE)>0); - Bitu handle = mem_readd(data+0x08); - Bitu linear = mem_readd(data+0x0C); - Bitu strOffset = mem_readd(data+0x10); - Bitu strSelect = mem_readw(data+0x14); - - Descriptor desc; - if (!cpu.gdt.GetDescriptor(strSelect,desc)) { - DPMI_LOG_ERROR("DPMI: 0D00: shared memory: invalid name selector"); - reg_ax = DPMI_ERROR_INVALID_VALUE; - DPMI_CALLBACK_SCF(true); - return false; - }; - MEM_StrCopy(desc.GetBase()+strOffset,name,256); - - // Already allocated ? - if (!GetSharedMem(name,handle,pages)) { - if (!AllocateMem(length,handle,linear)) { - DPMI_LOG_ERROR("DPMI: 0D00: Allocation shared failure %s (%d KB)",name,pages*4); - reg_ax = DPMI_ERROR_PHYSICAL_MEMORY_UNAVAILABLE; - DPMI_CALLBACK_SCF(true); - break; - }; - // Init first paragraph with zeros - for (Bitu i=0; i<16; i++) mem_writeb(linear+i,0); - SetSharedMem(name,handle,pages); - DPMI_LOG("DPMI: 0D00: Allocate shared memory %s (%d KB) ",name,pages*4); - } else { - linear = handle*DPMI_PAGE_SIZE; - DPMI_LOG("DPMI: 0D00: Reuse shared memory %s (%d KB) ",name,pages*4); - }; - - mem_writed(data+0x04,pages*DPMI_PAGE_SIZE); - mem_writed(data+0x08,handle); - mem_writed(data+0x0C,linear); - DPMI_CALLBACK_SCF(false); - }; break; - case 0x0B00:// Set debug watchpoint - case 0x0B01:// Clear debug watchpoint - DPMI_CALLBACK_SCF(true); - break; - case 0x0E00:// Get Coprocessor Status - DPMI_LOG("DPMI: 0E00: Get Coprocessor status"); - reg_ax = 0x45; // nope, no coprocessor - DPMI_CALLBACK_SCF(false); - break; - case 0x0E01:// Set Coprocessor Emulation - DPMI_LOG("DPMI: 0E01: Set Coprocessor emulation"); - DPMI_CALLBACK_SCF(true); // failure - break; - default :LOG(LOG_MISC,LOG_ERROR)("DPMI: Unsupported func %04X",reg_ax); - reg_ax = DPMI_ERROR_UNSUPPORTED; - DPMI_CALLBACK_SCF(true); // failure - break; - }; - return 0; -} - -Bitu DPMI::Int2fHandler(void) -{ - // Only available in ProtectedMode - // LOG(LOG_MISC,LOG_WARN)("DPMI: 0x2F %04x",reg_ax); - switch (reg_ax) { - case 0x1686: /* Get CPU Mode */ - reg_ax = 0; - break; - case 0x168A: // Only available in protected mode - // Get Vendor-Specific API Entry Point - char name[256]; - MEM_StrCopy(SegPhys(ds)+Mask(reg_esi),name,255); - LOG(LOG_MISC,LOG_WARN)("DPMI: 0x2F 0x168A: Get Specific API :%s",name); - if (strcmp(name,"MS-DOS")==0) { - CPU_SetSegGeneral(es,GDT_PROTCODE); - if (dpmi.client.bit32) reg_edi = DPMI_CB_APIMSDOSENTRY_OFFSET; - else reg_di = DPMI_CB_APIMSDOSENTRY_OFFSET; - reg_al = 0x00; // Success, whatever they want... - API_Init_MSDOS(); - }; - break; - default : // reflect to real - ptorHandler(); - break; - } - return 0; -}; - -// ********************************************************************* -// Callbacks and Callback-Returns -// ********************************************************************* - -static Bitu DPMI_Exception(void) { if (activeDPMI) return activeDPMI->CreateException(); return 0;}; -static Bitu DPMI_ExceptionReturn(void) { if (activeDPMI) return activeDPMI->ExceptionReturn(); return 0;}; -static Bitu DPMI_RealModeCallback(void) { if (activeDPMI) return activeDPMI->RealModeCallback(); return 0;}; -static Bitu DPMI_RealModeCallbackReturn(void) { if (activeDPMI) return activeDPMI->RealModeCallbackReturn(); return 0;}; -static Bitu DPMI_CallRealIRETFrame(void) { if (activeDPMI) return activeDPMI->CallRealIRETFrame(true); return 0;}; -static Bitu DPMI_CallRealIRETFrameReturn(void) { if (activeDPMI) return activeDPMI->CallRealIRETFrameReturn(); return 0;}; -static Bitu DPMI_SimulateInt(void) { if (activeDPMI) return activeDPMI->SimulateInt(); return 0;}; -static Bitu DPMI_SimulateIntReturn(void) { if (activeDPMI) return activeDPMI->SimulateIntReturn(); return 0;}; -static Bitu DPMI_ptorHandler(void) { if (activeDPMI) return activeDPMI->ptorHandler(); return 0;}; -static Bitu DPMI_ptorHandlerReturn(void) { if (activeDPMI) return activeDPMI->ptorHandlerReturn(); return 0;}; -static Bitu DPMI_Int21Handler(void) { if (activeDPMI) return activeDPMI->Int21Handler(); return 0;}; -static Bitu DPMI_Int21HandlerReturn(void) { if (activeDPMI) return activeDPMI->Int21HandlerReturn(); return 0;}; -static Bitu DPMI_HWIntDefaultHandler(void) { if (activeDPMI) return activeDPMI->HWIntDefaultHandler(); return 0;}; -static Bitu DPMI_EnterProtMode(void) { if (activeDPMI) return activeDPMI->EnterProtMode(); return 0;}; -static Bitu DPMI_EnterRealMode(void) { if (activeDPMI) return activeDPMI->EnterRealMode(); return 0;}; -static Bitu DPMI_RealSaveState(void) { if (activeDPMI) return activeDPMI->RealSaveState(); return 0;}; -static Bitu DPMI_ProtSaveState(void) { if (activeDPMI) return activeDPMI->ProtSaveState(); return 0;}; -static Bitu DPMI_Int2fHandler(void) { if (activeDPMI) return activeDPMI->Int2fHandler(); return 0;}; -static Bitu DPMI_Int31Handler(void) { if (activeDPMI) return activeDPMI->Int31Handler(); return 0;}; -static Bitu DPMI_API_Int21_MSDOS(void) { if (activeDPMI) return activeDPMI->API_Int21_MSDOS(); return 0;}; -static Bitu DPMI_API_Entry_MSDOS(void) { if (activeDPMI) return activeDPMI->API_Entry_MSDOS(); return 0;}; - - -// **************************************************************** -// Setup stuff -// **************************************************************** - -bool DPMI::SetProtInterrupt(Bitu num, Bitu selector, Bitu offset) -{ - // Nobody messes with the div0 vector - if (num==0) return true; - - SetDescriptor gate; - gate.Clear(); - gate.saved.seg.p=1; - gate.SetSelector(selector); - gate.SetOffset (Mask(offset)); - gate.SetType (dpmi.client.bit32?DESC_386_INT_GATE:DESC_286_INT_GATE); - gate.saved.seg.dpl = DPMI_DPL; - gate.Save(dpmi.idt.base+num*8); - // Special Pharlap stuff - if (dpmi.pharlap) { - gate.Save(cpu.idt.GetBase()+num*8); - DPMI_LOG("DPMI: 0205: Pharlap: Set Prot Int Vector %02X (%04X:%08X)",reg_bl,reg_cx,reg_edx); - } - return true; -}; - -RealPt DPMI::HookInterrupt(Bitu num, Bitu intHandler) -{ - // Setup realmode hook - RealPt oldVec; - Bitu segment, offset; - // Allocate Realmode callback - RealPt func = CALLBACK_RealPointer(intHandler); - if (AllocateRealModeCallback(GDT_CODE,RealOff(func),0x0000,0x0000,segment,offset)) { - oldVec = RealGetVec(num); - RealSetVec(num,RealMake(segment,offset)); - } else E_Exit("DPMI: Couldnt allocate Realmode-Callback for INT %04X",num); - // Setup protmode hook - func = CALLBACK_RealPointer(intHandler); - SetProtInterrupt(num,GDT_CODE,RealOff(func)); - return oldVec; -} - -void DPMI::RestoreHookedInterrupt(Bitu num, RealPt oldVec) -{ - //.Restore hooked int - RealSetVec(num,oldVec); - RealPt func = CALLBACK_RealPointer(callback.ptorint); - SetDescriptor gate; - gate.Load (dpmi.idt.base+num*8); - gate.SetSelector(GDT_CODE); - gate.SetOffset (RealOff(func)); - gate.Save (dpmi.idt.base+num*8); -} - -void DPMI::Debug_ShowDescriptors(void) -{ - char out1[512]; - SetDescriptor desc; - Bitu i=0; - PhysPt address = dpmi.ldt.base; - while (iRemoveIntCallbacks(); - } - activeDPMI = new DPMI(); - return activeDPMI->Entrypoint(); -} - -Bitu DPMI::Entrypoint(void) -{ - /* This should switch to pmode */ - if (dpmi.client.have) E_Exit("DPMI:Already have a client"); - - LOG(LOG_MISC,LOG_ERROR)("DPMI: Entrypoint (%d Bit)",(reg_ax & 1) ? 32:16); - - MEM_A20_Enable(true); - // Create gdt, ldt, idt and other stuff - Setup(); - - // Save Realmode Registers - SaveRegisterState(0); - - dpmi.client.have = true; - dpmi.client.bit32 = reg_ax & 1; - - // Clear XMS Handles - ClearXMSHandles(); - /* Clear the LDT */ - Bitu i; - for (i=0;i::iterator i; - for(i=g_sharedMemList.begin(); i != g_sharedMemList.end(); i++) - delete static_cast(*i); - (g_sharedMemList.clear)(); -}; - -void DPMI_Init(Section* sec) -{ - Section_prop * section=static_cast(sec); - if (!section->Get_bool("dpmi")) return; - - BIOS_ZeroExtendedSize(); - memset(&callback,0,sizeof(callback)); - - /* setup Real mode Callbacks */ - callback.entry=CALLBACK_Allocate(); - CALLBACK_Setup(callback.entry,DPMI_EntryPoint,CB_RETF,"Entrypoint"); - callback.enterpmode=CALLBACK_Allocate(); - CALLBACK_Setup(callback.enterpmode,DPMI_EnterProtMode,CB_RETF,"Enter PMode"); - callback.realsavestate=CALLBACK_Allocate(); - CALLBACK_Setup(callback.realsavestate,DPMI_RealSaveState,CB_RETF,"Save RealState"); - callback.simint=CALLBACK_Allocate(); - CALLBACK_Setup(callback.simint,DPMI_SimulateInt,CB_IRET,"Sim INT"); - callback.simintReturn=CALLBACK_Allocate(); - CALLBACK_Setup(callback.simintReturn,DPMI_SimulateIntReturn,CB_IRET,"Sim INT RET"); - callback.rmIntFrame=CALLBACK_Allocate(); - CALLBACK_Setup(callback.rmIntFrame,DPMI_CallRealIRETFrame,CB_IRET,"Call REAL IRET"); - callback.rmIntFrameReturn=CALLBACK_Allocate(); - CALLBACK_Setup(callback.rmIntFrameReturn,DPMI_CallRealIRETFrameReturn,CB_IRET,"Call REAL IRET RET"); - callback.ptorint=CALLBACK_Allocate(); - CALLBACK_Setup(callback.ptorint,DPMI_ptorHandler,CB_IRET,"INT Handler"); - callback.ptorintReturn=CALLBACK_Allocate(); - CALLBACK_Setup(callback.ptorintReturn,DPMI_ptorHandlerReturn,CB_IRET,"INT Handler RET"); - callback.int21Return=CALLBACK_Allocate(); - CALLBACK_Setup(callback.int21Return,DPMI_Int21HandlerReturn,CB_IRET,"INT 21 RET"); - callback.rmCallbackReturn=CALLBACK_Allocate(); - CALLBACK_Setup(callback.rmCallbackReturn,DPMI_RealModeCallbackReturn,CB_IRET,"RMCB RET"); - callback.int21msdos=CALLBACK_Allocate(); - CALLBACK_Setup(callback.int21msdos,DPMI_API_Int21_MSDOS,CB_IRET,"MSDOS INT 21 API"); - - /* Setup multiplex */ - DOS_AddMultiplexHandler(DPMI_Multiplex); - - /* shutdown function */ - sec->AddDestroyFunction(&DPMI_ShutDown); -} - -void DPMI::Reactivate() -{ - /* Load GDT and IDT */ - CPU_LIDT(dpmi.idt.limit,dpmi.idt.base); - CPU_LGDT(dpmi.gdt.limit,dpmi.gdt.base); - CPU_LLDT(GDT_LDT); - cpu.cpl = DPMI_DPL; - RestoreIntCallbacks(); -}; - -void DPMI::Setup() -{ - Bitu i; - Bitu xmssize = (TOTAL_SIZE|(DPMI_PAGE_SIZE-1))+1; - Bitu protStackSize = ((DPMI_PROTMODE_STACK_MAX*DPMI_PROTMODE_STACKSIZE)|(DPMI_PAGE_SIZE-1))+1; - Bitu numPages = ((xmssize+protStackSize) >> 12); - -#if DPMI_ALLOC_NEEDEDMEM_HIGH - // Allocate the GDT,LDT,IDT Stack space (High Mem) - Bitu max = MEM_FreeLargest(); - Bitu temphandle = MEM_AllocatePages(max-numPages,true); - dpmi.mem_handle = MEM_AllocatePages(numPages,true); - if (dpmi.mem_handle==0) { - LOG_MSG("DPMI:Can't allocate XMS memory, disabling dpmi support."); - return; - } - Bitu address = dpmi.mem_handle*DPMI_PAGE_SIZE;; - MEM_ReleasePages(temphandle); -#else - // load LDT and stuff in low mem ( - Bit16u segment; - Bit16u blocks = numPages*4096/16; - if (!DOS_AllocateMemory(&segment,&blocks)) { - LOG_MSG("DPMI:Can't allocate XMS memory, disabling dpmi support."); - return; - }; - Bitu address = segment * 16; -#endif - // Allocate real mode stack space - rm_ss = DOS_GetMemory(DPMI_REALMODE_STACKSIZE/16); - rm_sp = DPMI_REALMODE_STACKSIZE; - // Get Begin of protected mode stack - dpmi.protStack = address + xmssize; - /* Clear the memory */ - PhysPt w; - for (w=address;w0); // Convert to 4KB pages - Bitu maxPages = MEM_FreeLargest(); - if (maxPages0xFFFFF) || (base & 0x0F)) E_Exit("DPMI:MSDOS: Invalid Selector (convert to segment not possible)"); - base >>= 4; - } else E_Exit("DPMI:MSDOS: Invalid Selector (not found)"); - return base; -}; - -bool DPMI::GetMsdosSelector(Bitu realseg, Bitu realoff, Bitu &protsel, Bitu &protoff) -{ - // Check if selector is already in list - for (Bitu i=0; i0xFFFF) E_Exit("DPMI:DOS: Read file size > 0xffff"); - - Bit16u toread = Mask(reg_ecx); - dos.echo = true; - if (DOS_ReadFile(reg_bx,dos_copybuf,&toread)) { - MEM_BlockWrite(SegPhys(ds)+Mask(reg_edx),dos_copybuf,toread); - if (dpmi.client.bit32) reg_eax=toread; else reg_ax=toread; -// LOG(LOG_MISC,LOG_ERROR)("READ FILE Handle:%d Size:%d Read:%d",reg_bx,toread,reg_eax); - DPMI_CALLBACK_SCF(false); - - } else { - LOG(LOG_MISC,LOG_ERROR)("DOS: Read file %d failed",reg_bx); - reg_ax=dos.errorcode; - DPMI_CALLBACK_SCF(true); - } - dos.echo=false; - break; - } - case 0x40: {/* WRITE Write to file or device */ - Bit16u towrite = Mask(reg_ecx); - MEM_BlockRead(SegPhys(ds)+Mask(reg_edx),dos_copybuf,towrite); -// if (reg_bx<=5) LOG(LOG_MISC,LOG_ERROR)("INT 21 40: %s",(char *)dos_copybuf); - if (DOS_WriteFile(reg_bx,dos_copybuf,&towrite)) { - if (dpmi.client.bit32) reg_eax=towrite; - else reg_ax =towrite; - DPMI_CALLBACK_SCF(false); - } else { - DPMI_LOG("DPMI:MSDOS:Write %d file failure.",reg_bx); - reg_ax=dos.errorcode; - DPMI_CALLBACK_SCF(true); - } - }; break; - case 0x41: { /* UNLINK Delete file */ - char name1[256]; - MEM_StrCopy(SegPhys(ds)+Mask(reg_edx),name1,255); - if (DOS_UnlinkFile(name1)) { - DPMI_CALLBACK_SCF(false); - } else { - reg_ax=dos.errorcode; - DPMI_CALLBACK_SCF(true); - } - }; break; - case 0x42: /* LSEEK Set current file position */ - { - Bit32u pos=(reg_cx<<16) + reg_dx; - Bit32u topos = pos; - if (DOS_SeekFile(reg_bx,&pos,reg_al)) { - reg_dx=(Bit16u)(pos >> 16); - reg_ax=(Bit16u)(pos & 0xFFFF); - DPMI_CALLBACK_SCF(false); - if ((reg_al==0) && (topos!=pos)) { - LOG(LOG_MISC,LOG_ERROR)("SEEK FILE Handle:%d Seek:%d Pos:%d",reg_bx,topos,pos); - LOG(LOG_MISC,LOG_ERROR)("SEEK FILE ERROR : Pos differs"); - } - } else { - LOG(LOG_MISC,LOG_ERROR)("DOS: Seek file %d failed",reg_bx); - reg_ax=dos.errorcode; - DPMI_CALLBACK_SCF(true); - } - break; - } - case 0x43: { /* Get/Set file attributes */ - char name1[256]; - MEM_StrCopy(SegPhys(ds)+Mask(reg_edx),name1,255); - switch (reg_al) - case 0x00: /* Get */ - { - if (DOS_GetFileAttr(name1,®_cx)) { - DPMI_CALLBACK_SCF(false); - } else { - DPMI_CALLBACK_SCF(true); - reg_ax=dos.errorcode; - } - break; - case 0x01: /* Set */ - DPMI_LOG("DOS:Set File Attributes for %s not supported",name1); - DPMI_CALLBACK_SCF(false); - break; - default: - E_Exit("DOS:0x43:Illegal subfunction %2X",reg_al); - } - }; break; - - case 0x47: { /* CWD Get current directory */ - char name1[256]; - if (DOS_GetCurrentDir(reg_dl,name1)) { - MEM_BlockWrite(SegPhys(ds)+Mask(reg_esi),name1,strlen(name1)+1); - LOG(LOG_MISC,LOG_ERROR)("DOS: Get Dir %s ",name1); - reg_ax=0x0100; - CALLBACK_SCF(false); - } else { - LOG(LOG_MISC,LOG_ERROR)("DOS: Get Dir failed %s ",name1); - reg_ax=dos.errorcode; - CALLBACK_SCF(true); - } - }; break; - - case 0x4E: {/* Get first dir entry */ - char name1[256]; - MEM_StrCopy(SegPhys(ds)+Mask(reg_edx),name1,255); - if (DOS_FindFirst(name1,reg_cx)) { - LOG(LOG_MISC,LOG_ERROR)("DOS: Find Dir entry %s success",name1); - DPMI_CALLBACK_SCF(false); - // Copy result to internal dta - if (dtaAddress) MEM_BlockCopy(dtaAddress,PhysMake(RealSeg(dos.dta),RealOff(dos.dta)),dpmi.pharlap?43:128); - reg_ax=0; /* Undocumented */ - } else { - LOG(LOG_MISC,LOG_ERROR)("DOS: Find Dir entry %s failure",name1); - reg_ax=dos.errorcode; - DPMI_CALLBACK_SCF(true); - }; - }; break; - case 0x4f: /* FINDNEXT Find next matching file */ - // Copy data to dos dta - if (dtaAddress) MEM_BlockCopy(PhysMake(RealSeg(dos.dta),RealOff(dos.dta)),dtaAddress,dpmi.pharlap?43:128); - if (DOS_FindNext()) { - LOG(LOG_MISC,LOG_ERROR)("DOS: FindNext Dir entry success"); - CALLBACK_SCF(false); - // Copy result to internal dta - if (dtaAddress) MEM_BlockCopy(dtaAddress,PhysMake(RealSeg(dos.dta),RealOff(dos.dta)),dpmi.pharlap?43:128); - reg_ax=0xffff; /* Undocumented */ - } else { - LOG(LOG_MISC,LOG_ERROR)("DOS: FindNext Dir entry failure"); - reg_ax=dos.errorcode; - CALLBACK_SCF(true); - }; - break; - case 0x50: /* Set current PSP */ - if (dpmi.pharlap) dos.psp = reg_bx; // pharlap uses real mode paragraph address - else - dos.psp = GetSegmentFromSelector(reg_bx); - DPMI_LOG("DPMI:MSDOS:0x50:Set current psp:%04X",reg_bx); - break; - case 0x51: /* Get current PSP */ - if (dpmi.pharlap) reg_bx = dos.psp; // pharlap uses real mode paragraph address - else { - GetMsdosSelector(dos.psp,0x0000,protsel,protoff); - reg_bx = protsel; - }; - DPMI_LOG("DPMI:MSDOS:0x51:Get current psp:%04X",reg_bx); - break; - case 0x55 : { // Neuen PSP erstellen - Bitu segment = GetSegmentFromSelector(reg_dx); - DOS_ChildPSP(segment,reg_si); - dos.psp = segment; - DPMI_LOG("DPMI:MSDOS:0x55:Create new psp:%04X",segment); - }; break; - case 0x56: { /* RENAME Rename file */ - char name1[256+1]; - char name2[256+1]; - MEM_StrCopy(SegPhys(ds)+Mask(reg_edx),name1,256); - MEM_StrCopy(SegPhys(es)+Mask(reg_edi),name2,256); - if (DOS_Rename(name1,name2)) { - DPMI_CALLBACK_SCF(false); - } else { - reg_ax=dos.errorcode; - DPMI_CALLBACK_SCF(true); - } - }; break; - case 0x5D : // Get Address of dos swappable area - // FIXME: This is totally faked... - // FIXME: Add size in bytes (at least pharlap) - // FIXME: Depending on al, two functions (pharlap) - GetMsdosSelector(0xDEAD,0xDEAD,protsel,protoff); - CPU_SetSegGeneral(ds,protsel); - reg_si = protoff; - DPMI_LOG("DPMI:MSDOS:0x5D:Get Addres of DOS SwapArea:%04X",reg_si); - break; - case 0x62 : /* Get Current PSP Address */ - GetMsdosSelector(dos.psp,0x0000,protsel,protoff); - reg_bx = protsel; - DPMI_LOG("DPMI:MSDOS:0x62:Get current psp:%04X",reg_bx); - break; - case 0x68: // Flush file to disc - DPMI_CALLBACK_SCF(false); - break; - - case 0x09: - case 0x0A: - case 0x0C: - case 0x1B: - case 0x1C: - case 0x26: // Pharlap != MS-DOS -// case 0x30: // Pharlap extended information - case 0x31: - case 0x32: - case 0x3A: - case 0x48: // Pharlap = 4KB mem pages - case 0x49: - case 0x4A: // Pharlap = 4KB mem pages - case 0x4B: - case 0x52: - case 0x53: - case 0x59: - case 0x5A: - case 0x5B: - case 0x5E: - case 0x5F: - case 0x60: -// case 0x62: - case 0x65: - case 0x6C: - E_Exit("DPMI:MSDOS-API:function %04X not yet supported.",reg_ax); - break; - - // *** PASS THROUGH *** - case 0x44: if ((reg_al==0x02) || (reg_al==0x03) || (reg_al==0x04) || (reg_al==0x05) || (reg_al==0x0C) || (reg_al==0x0D)) { - E_Exit("DPMI:MSDOS-API:function %04X not yet supported.",reg_ax); - }; - case 0x07: case 0x0B: case 0x0E: case 0x19: case 0x2A: case 0x2C: case 0x2D: case 0x30: - case 0x36: case 0x3E: case 0x4C: case 0x58: case 0x67: - { - // reflect to real mode - DPMI_Int21Handler(); - }; - break; - default: E_Exit("DPMI:MSDOS-API:Missing function %04X",reg_ax); - - }; - return 0; -}; From 2f32a834482f15f0b8ceef902d6a50ecc4b38c9b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 31 Mar 2004 15:41:58 +0000 Subject: [PATCH 1663/4131] internal dpmi not needed anymore Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1745 --- src/ints/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/Makefile.am b/src/ints/Makefile.am index e1ffaba2..7330a855 100644 --- a/src/ints/Makefile.am +++ b/src/ints/Makefile.am @@ -1,7 +1,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libints.a -libints_a_SOURCES = mouse.cpp xms.cpp xms.h ems.cpp dpmi.cpp \ +libints_a_SOURCES = mouse.cpp xms.cpp xms.h ems.cpp \ int10.cpp int10.h int10_char.cpp int10_memory.cpp int10_misc.cpp int10_modes.cpp \ int10_vesa.cpp int10_pal.cpp int10_put_pixel.cpp \ bios.cpp bios_disk.cpp bios_keyboard.cpp From 988633017d61f94c00fe8f413343cb87f7ace36d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 31 Mar 2004 17:23:46 +0000 Subject: [PATCH 1664/4131] Changed some cpu functions to get opcode length as parameter Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1746 --- include/cpu.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index f741895b..3225738e 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -66,15 +66,18 @@ 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 opLen=0); -void CPU_CALL(bool use32,Bitu selector,Bitu offset,Bitu opLen=0); -void CPU_RET(bool use32,Bitu bytes,Bitu opLen=0); +void CPU_JMP(bool use32,Bitu selector,Bitu offset,Bitu opLen); +void CPU_CALL(bool use32,Bitu selector,Bitu offset,Bitu opLen); +void CPU_RET(bool use32,Bitu bytes,Bitu opLen); +void CPU_IRET(bool use32,Bitu opLen); + +bool CPU_CLI(Bitu opLen); +bool CPU_STI(Bitu opLen); #define CPU_INT_SOFTWARE 0x1 #define CPU_INT_EXCEPTION 0x2 #define CPU_INT_HAS_ERROR 0x4 - void CPU_Interrupt(Bitu num,Bitu type,Bitu opLen=0); INLINE void CPU_HW_Interrupt(Bitu num) { CPU_Interrupt(num,0); @@ -87,7 +90,6 @@ void CPU_Exception(Bitu which,Bitu error=0); void CPU_StartException(void); void CPU_SetupException(Bitu which,Bitu error=0); -void CPU_IRET(bool use32); bool CPU_SetSegGeneral(SegNames seg,Bitu value); void CPU_HLT(Bitu opLen); From cd5f7c966643928071a30e86e97acbe27322611c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 31 Mar 2004 17:27:31 +0000 Subject: [PATCH 1665/4131] Changed some cpu functions to get opcode length as parameter Added cli and sti functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1747 --- src/cpu/core_normal/prefix_66.h | 7 +++--- src/cpu/core_normal/prefix_none.h | 18 +++++---------- src/cpu/cpu.cpp | 38 +++++++++++++++++++++++-------- 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 3e10ce47..94d99c07 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -380,7 +380,7 @@ { Bit32u newip=Fetchd();Bit16u newcs=Fetchw(); LEAVECORE; - CPU_CALL(true,newcs,newip); + CPU_CALL(true,newcs,newip,core.ip_lookup-core.op_start); goto decode_start; } CASE_D(0x9c) /* PUSHFD */ @@ -530,7 +530,7 @@ CASE_D(0xcf) /* IRET */ { LEAVECORE; - CPU_IRET(true); + CPU_IRET(true,core.ip_lookup-core.op_start); #if CPU_TRAP_CHECK if (GETFLAG(TF)) { cpudecoder=CPU_Core_Normal_Trap_Run; @@ -540,7 +540,6 @@ #if CPU_PIC_CHECK if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; #endif -//TODO TF check goto decode_start; } CASE_D(0xd1) /* GRP2 Ed,1 */ @@ -641,7 +640,7 @@ Bit32u newip=LoadMd(eaa); Bit16u newcs=LoadMw(eaa+4); LEAVECORE; - CPU_CALL(true,newcs,newip); + CPU_CALL(true,newcs,newip,core.ip_lookup-core.op_start); goto decode_start; } break; diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index f5354374..9e8a1b58 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -237,7 +237,7 @@ break; CASE_W(0x63) /* ARPL Ew,Rw */ { - if (((cpu.pmode) && (reg_flags & FLAG_VM)) || (!cpu.pmode)) goto illegal_opcode; + if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; FillFlags(); GetRMrw; if (rm >= 0xc0 ) { @@ -792,7 +792,7 @@ CASE_W(0xcf) /* IRET */ { LEAVECORE; - CPU_IRET(false); + CPU_IRET(false,core.ip_lookup-core.op_start); #if CPU_PIC_CHECK if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; #endif @@ -1059,20 +1059,14 @@ SETFLAGBIT(CF,true); break; CASE_B(0xfa) /* CLI */ - if (cpu.pmode && (GETFLAG_IOPL #include "dosbox.h" @@ -91,6 +91,28 @@ void CPU_SetFlags(Bitu word,Bitu mask) { cpu.direction=1-((reg_flags & FLAG_DF) >> 9); } +bool CPU_CLI(Bitu opLen) { + if (cpu.pmode && ((!GETFLAG(VM) && (GETFLAG_IOPL0) + if (call.saved.gate.paramcount&31) for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--) CPU_Push32(mem_readd(o_stack+i*4)); CPU_Push32(SegValue(cs)); @@ -720,7 +742,7 @@ call_code: } else { CPU_Push16(o_ss); //save old stack CPU_Push16(o_esp); - if (call.saved.gate.paramcount&31>0) + if (call.saved.gate.paramcount&31) for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--) CPU_Push16(mem_readw(o_stack+i*2)); CPU_Push16(SegValue(cs)); @@ -982,7 +1004,6 @@ void CPU_LAR(Bitu selector,Bitu & ar) { return; } Descriptor desc;Bitu rpl=selector & 3; - ar=0; if (!cpu.gdt.GetDescriptor(selector,desc)){ SETFLAGBIT(ZF,false); return; @@ -991,7 +1012,7 @@ void CPU_LAR(Bitu selector,Bitu & ar) { case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: break; - + case DESC_286_INT_GATE: case DESC_286_TRAP_GATE: { case DESC_386_INT_GATE: case DESC_386_TRAP_GATE: SETFLAGBIT(ZF,false); @@ -1034,7 +1055,6 @@ void CPU_LSL(Bitu selector,Bitu & limit) { return; } Descriptor desc;Bitu rpl=selector & 3; - limit=0; if (!cpu.gdt.GetDescriptor(selector,desc)){ SETFLAGBIT(ZF,false); return; @@ -1300,7 +1320,7 @@ void CPU_Init(Section* sec) { else { LOG_MSG("CPU:Unknown core type %s, switcing back to normal.",core); } - CPU_JMP(false,0,0); //Setup the first cpu core + CPU_JMP(false,0,0,0); //Setup the first cpu core if (!CPU_CycleMax) CPU_CycleMax = 2500; if(!CPU_CycleUp) CPU_CycleUp = 500; From 410ceedaba3f341c29cfd7a811fc39a142374164 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 31 Mar 2004 17:28:16 +0000 Subject: [PATCH 1666/4131] Changed some cpu functions to get opcode length as parameter Added cli and sti functions Changed LAR/LSL opcodes to preload the value incase it doesn't get changed Added some support illegal opcodes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1748 --- src/cpu/core_full.cpp | 6 ++++- src/cpu/core_full/load.h | 50 +++++++++++++++++++++++++++---------- src/cpu/core_full/op.h | 15 ++++++----- src/cpu/core_full/optable.h | 8 +++--- src/cpu/core_full/save.h | 14 ----------- src/cpu/core_full/support.h | 4 ++- 6 files changed, 58 insertions(+), 39 deletions(-) diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 9d7868cc..9fdc76be 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -103,9 +103,13 @@ restartopcode: #include "core_full/save.h" nextopcode:; } -exit_core: LEAVECORE; return CBRET_NONE; +illegalopcode: + LEAVECORE; + reg_eip-=(IPPoint-inst.opcode_start); + CPU_Exception(0x6,0); + goto restart_core; } diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 74009c6f..fc009821 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -206,6 +206,30 @@ l_M_Ed: inst.op1.d = Pop_32(); inst.op2.d = Pop_16(); break; + case L_PFLGw: + if ((reg_flags & FLAG_VM) && ((reg_flags & FLAG_IOPL)!=FLAG_IOPL)) { + LEAVECORE;reg_eip-=IPPoint-inst.opcode_start; + CPU_Exception(13,0); + goto restart_core; + } + SETFLAGSw(Pop_16()); + if (GETFLAG(IF) && PIC_IRQCheck) { + SaveIP(); + return CBRET_NONE; + } + break; + case L_PFLGd: + if ((reg_flags & FLAG_VM) && ((reg_flags & FLAG_IOPL)!=FLAG_IOPL)) { + LEAVECORE;reg_eip-=IPPoint-inst.opcode_start; + CPU_Exception(13,0); + goto restart_core; + } + SETFLAGSd(Pop_32()); + if (GETFLAG(IF) && PIC_IRQCheck) { + SaveIP(); + return CBRET_NONE; + } + break; case L_Ib: inst.op1.d=Fetchb(); break; @@ -296,14 +320,14 @@ l_M_Ed: break; case D_IRETw: LEAVECORE; - CPU_IRET(false); + CPU_IRET(false,IPPoint-inst.opcode_start); if (GETFLAG(IF) && PIC_IRQCheck) { return CBRET_NONE; } goto restart_core; case D_IRETd: LEAVECORE; - CPU_IRET(true); + CPU_IRET(true,IPPoint-inst.opcode_start); if (GETFLAG(IF) && PIC_IRQCheck) { return CBRET_NONE; } @@ -312,23 +336,23 @@ l_M_Ed: { Bitu words=Fetchw(); LEAVECORE; - CPU_RET(false,words); + CPU_RET(false,words,IPPoint-inst.opcode_start); goto restart_core; } case D_RETFw: LEAVECORE; - CPU_RET(false,0); + CPU_RET(false,0,IPPoint-inst.opcode_start); goto restart_core; case D_RETFdIw: { Bitu words=Fetchw(); LEAVECORE; - CPU_RET(true,words); + CPU_RET(true,words,IPPoint-inst.opcode_start); goto restart_core; } case D_RETFd: LEAVECORE; - CPU_RET(true,0); + CPU_RET(true,0,IPPoint-inst.opcode_start); goto restart_core; /* Direct operations */ case L_STRING: @@ -403,14 +427,14 @@ l_M_Ed: else reg_edx=0; goto nextopcode; case D_CLI: - SETFLAGBIT(IF,false); + LEAVECORE; + if (CPU_CLI(IPPoint-inst.opcode_start)) + goto restart_core; goto nextopcode; case D_STI: - SETFLAGBIT(IF,true); - if (GETFLAG(IF) && PIC_IRQCheck) { - LEAVECORE; - return CBRET_NONE; - } + LEAVECORE; + if (CPU_STI(IPPoint-inst.opcode_start)) + goto restart_core; goto nextopcode; case D_STC: FillFlags();SETFLAGBIT(CF,true); @@ -531,6 +555,6 @@ l_M_Ed: goto nextopcode; default: LOG(LOG_CPU,LOG_ERROR)("LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry); - break; + goto illegalopcode; } diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 5d4ee345..977ad670 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -323,19 +323,19 @@ switch (inst.code.op) { break; case O_CALLFw: LEAVECORE; - CPU_CALL(false,inst.op2.d,inst.op1.d); + CPU_CALL(false,inst.op2.d,inst.op1.d,IPPoint-inst.opcode_start); goto restart_core; case O_CALLFd: LEAVECORE; - CPU_CALL(true,inst.op2.d,inst.op1.d); + CPU_CALL(true,inst.op2.d,inst.op1.d,IPPoint-inst.opcode_start); goto restart_core; case O_JMPFw: LEAVECORE; - CPU_JMP(false,inst.op2.d,inst.op1.d); + CPU_JMP(false,inst.op2.d,inst.op1.d,IPPoint-inst.opcode_start); goto restart_core; case O_JMPFd: LEAVECORE; - CPU_JMP(true,inst.op2.d,inst.op1.d); + CPU_JMP(true,inst.op2.d,inst.op1.d,IPPoint-inst.opcode_start); goto restart_core; case O_INT: LEAVECORE; @@ -458,19 +458,22 @@ switch (inst.code.op) { case O_LAR: { FillFlags(); - Bitu ar;CPU_LAR(inst.op1.d,ar); + Bitu ar=inst.op2.d; + CPU_LAR(inst.op1.w,ar); inst.op1.d=(Bit32u)ar; } break; case O_LSL: { FillFlags(); - Bitu limit;CPU_LSL(inst.op1.d,limit); + Bitu limit=inst.op2.d; + CPU_LSL(inst.op1.w,limit); inst.op1.d=(Bit32u)limit; } break; case O_ARPL: { + if ((reg_flags & FLAG_VM) || !cpu.pmode) goto illegalopcode; FillFlags(); Bitu new_sel=inst.op1.d; CPU_ARPL(new_sel,inst.op2.d); diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index fdd3454a..2a2877ea 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -110,7 +110,7 @@ static OpCode OpCodeTable[1024]={ /* 0x98 - 0x9f */ {D_CBW ,0 ,0 ,0 },{D_CWD ,0 ,0 ,0 }, {L_Ifw ,O_CALLFw ,0 ,0 },{D_WAIT ,0 ,0 ,0 }, -{L_FLG ,0 ,S_PUSHw,0 },{L_POPw ,0 ,S_FLGw ,0 }, +{L_FLG ,0 ,S_PUSHw,0 },{L_PFLGw ,0 ,0 ,0 }, {L_REGb ,0 ,S_FLGb ,REGI_AH},{L_FLG ,0 ,S_REGb ,REGI_AH}, /* 0xa0 - 0xa7 */ @@ -182,7 +182,7 @@ static OpCode OpCodeTable[1024]={ /* 0x100 - 0x107 */ {L_MODRM ,O_GRP6w ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7w ,S_Ew ,M_Ew }, -{L_MODRM ,O_LAR ,S_Gw ,M_Ew },{L_MODRM ,O_LSL ,S_Gw ,M_Ew }, +{L_MODRM ,O_LAR ,S_Gw ,M_EwGw },{L_MODRM ,O_LSL ,S_Gw ,M_EwGw }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {D_CLTS ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x108 - 0x10f */ @@ -466,7 +466,7 @@ static OpCode OpCodeTable[1024]={ /* 0x298 - 0x29f */ {D_CWDE ,0 ,0 ,0 },{D_CDQ ,0 ,0 ,0 }, {L_Ifd ,O_CALLFd ,0 ,0 },{D_WAIT ,0 ,0 ,0 }, -{L_FLG ,0 ,S_PUSHd,0 },{L_POPd ,0 ,S_FLGd ,0 }, +{L_FLG ,0 ,S_PUSHd,0 },{L_PFLGw ,0 ,0 ,0 }, {L_REGb ,0 ,S_FLGb ,REGI_AH},{L_FLG ,0 ,S_REGb ,REGI_AH}, /* 0x2a0 - 0x2a7 */ @@ -538,7 +538,7 @@ static OpCode OpCodeTable[1024]={ /* 0x300 - 0x307 */ {L_MODRM ,O_GRP6d ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7d ,S_Ew ,M_Ew }, -{L_MODRM ,O_LAR ,S_Gd ,M_Ew },{L_MODRM ,O_LSL ,S_Gd ,M_Ew }, +{L_MODRM ,O_LAR ,S_Gd ,M_EdGd },{L_MODRM ,O_LSL ,S_Gd ,M_EdGd }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {D_CLTS ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x308 - 0x30f */ diff --git a/src/cpu/core_full/save.h b/src/cpu/core_full/save.h index 157364c6..fb90a49f 100644 --- a/src/cpu/core_full/save.h +++ b/src/cpu/core_full/save.h @@ -113,20 +113,6 @@ switch (inst.code.save) { case S_FLGb: SETFLAGSb(inst.op1.b); break; - case S_FLGw: - SETFLAGSw(inst.op1.w); - if (GETFLAG(IF) && PIC_IRQCheck) { - SaveIP(); - return CBRET_NONE; - } - break; - case S_FLGd: - SETFLAGSd(inst.op1.d); - if (GETFLAG(IF) && PIC_IRQCheck) { - SaveIP(); - return CBRET_NONE; - } - break; case 0: break; default: diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 9306928c..36651094 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -13,10 +13,12 @@ enum { L_REGbIb,L_REGwIw,L_REGdId, L_POPw,L_POPd, L_POPfw,L_POPfd, + L_PFLGw,L_PFLGd, L_SEG, L_FLG,L_INTO, + L_VAL, L_PRESEG, L_DOUBLE, @@ -113,7 +115,7 @@ enum { S_AIPw,S_C_AIPw, S_AIPd,S_C_AIPd, - S_FLGb,S_FLGw,S_FLGd, + S_FLGb, S_IP,S_IPIw, }; From 611666165e91609bf3832ad42e7d9abdeb5d0879 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 31 Mar 2004 17:31:17 +0000 Subject: [PATCH 1667/4131] Changed some cpu functions to get opcode length as parameter Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1749 --- src/hardware/ipx.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index 38da62e2..6af46646 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -142,8 +142,7 @@ public: inESR = true; //LOG_MSG("Write %x to %x", real_readd(RealSeg(ECBAddr), RealOff(ECBAddr)+4), RealMake(RealSeg(ipx_esrptraddr), RealOff(ipx_esrptraddr))); real_writed(RealSeg(ipx_esrptraddr), RealOff(ipx_esrptraddr),real_readd(RealSeg(ECBAddr), RealOff(ECBAddr)+4)); - CPU_CALL(false, RealSeg(ipx_esrcallback), RealOff(ipx_esrcallback)); - + CPU_CALL(false, RealSeg(ipx_esrcallback), RealOff(ipx_esrcallback),0); } } From 111dc4f5915ed8d1d9ad03a6a53e8f26250c3950 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 31 Mar 2004 21:53:24 +0000 Subject: [PATCH 1668/4131] Fake soundblaster recording to help some detection routines. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1750 --- src/hardware/sblaster.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 7eb553a3..c779b84f 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -238,6 +238,7 @@ static void DSP_DMA_CallBack(DmaChannel * chan, DMAEvent event) { if (event==DMA_UNMASKED) sb.dma.active=true; if (sb.mode==MODE_DMA_WAIT && sb.dma.active) { LOG(LOG_SB,LOG_NORMAL)("DMA Activated,starting output"); +// LOG_MSG("DMA Size %x base %x Addr %x",chan->currcnt,chan->pagebase,chan->curraddr); DSP_ChangeMode(MODE_DMA); CheckDMAEnd(); return; @@ -638,6 +639,18 @@ static void DSP_E2_DMA_CallBack(DmaChannel * chan, DMAEvent event) { } } +static void DSP_ADC_CallBack(DmaChannel * chan, DMAEvent event) { + if (event!=DMA_UNMASKED) return; + Bit8u val=128; + while (sb.dma.left--) { + DmaChannels[sb.hw.dma8]->Write(1,&val); + } + SB_RaiseIRQ(SB_IRQ_8); + DmaChannels[sb.hw.dma8]->Register_Callback(0); +} + +Bitu DEBUG_EnableDebugger(void); + static void DSP_DoCommand(void) { // LOG_MSG("DSP Command %X",sb.dsp.cmd); switch (sb.dsp.cmd) { @@ -652,6 +665,10 @@ static void DSP_DoCommand(void) { } break; case 0x24: /* Singe Cycle 8-Bit DMA ADC */ + sb.dma.left=sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); + LOG(LOG_SB,LOG_ERROR)("DSP:Faked ADC for %d bytes",sb.dma.total); + DmaChannels[sb.hw.dma8]->Register_Callback(DSP_ADC_CallBack); + break; case 0x14: /* Singe Cycle 8-Bit DMA DAC */ case 0x91: /* Singe Cycle 8-Bit DMA High speed DAC */ DSP_PrepareDMA_Old(DSP_DMA_8,false); From 229e81304ba78bc2f46fd7b899f524b59bb0952e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 31 Mar 2004 22:01:22 +0000 Subject: [PATCH 1669/4131] Added functions 5a-00 for all the warlords 2 deluxe fans Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1751 --- src/ints/ems.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 65cdd3a5..0430fdf1 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.31 2004-02-02 20:23:54 qbix79 Exp $ */ +/* $Id: ems.cpp,v 1.32 2004-03-31 22:01:22 harekiet Exp $ */ #include #include @@ -571,6 +571,14 @@ static Bitu INT67_Handler(void) { reg_cx = EMM_MAX_PHYS; reg_ah = EMM_NO_ERROR; break; + case 0x5A: /* Allocate standard/raw Pages */ + if (reg_al==0x00) { + reg_ah=EMM_AllocateMemory(reg_bx,reg_dx); + } else { + LOG(LOG_MISC,LOG_ERROR)("EMS:Call 5A subfct %2X not supported",reg_al); + reg_ah=EMM_FUNC_NOSUP; + }; + break; case 0xDE: /* VCPI Functions */ LOG(LOG_MISC,LOG_ERROR)("EMS:VCPI Call %2X not supported",reg_al); reg_ah=EMM_FUNC_NOSUP; From c7ab4990a0b55f880de48decd28438d55fdf5bbb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 1 Apr 2004 08:57:33 +0000 Subject: [PATCH 1670/4131] FLDENV FSTENV FSTOR FSAVE added.status word can now be examined. closes #998201 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1752 --- src/fpu/fpu.cpp | 39 ++++++++++++++++++++--- src/fpu/fpu_instructions.h | 63 +++++++++++++++++++++++++++++++++----- 2 files changed, 90 insertions(+), 12 deletions(-) diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index c2ce3a4a..169c61ad 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu.cpp,v 1.18 2004-03-29 18:03:02 qbix79 Exp $ */ +/* $Id: fpu.cpp,v 1.19 2004-04-01 08:57:33 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU @@ -61,6 +61,20 @@ INLINE void FPU_SetCW(Bitu word) { fpu.ex_mask = word & 0x3f; } +static Bit16u FPU_GetTag(void){ + Bit16u tag=0; + for(Bitu i=0;i<8;i++) + tag |= ( (fpu.tags[i]&3) <<(2*i)); + return tag; +} + +static void FPU_SetTag(Bit16u tag) +{ + for(Bitu i=0;i<8;i++) + fpu.tags[i]= static_cast((tag >>(2*i))&3); +} + + INLINE Bitu FPU_GET_TOP(void){ @@ -234,12 +248,18 @@ void FPU_ESC1_EA(Bitu rm,PhysPt addr) { } FPU_FPOP(); break; - case 0x05: /*FLDCW */ + case 0x04: /* FLDENV */ + FPU_FLDENV(addr); + break; + case 0x05: /* FLDCW */ { Bit16u temp =mem_readw(addr); FPU_SetCW(temp); } break; + case 0x06: /* FSTENV */ + FPU_FSTENV(addr); + break; case 0x07: /* FNSTCW*/ mem_writew(addr,fpu.cw); break; @@ -432,10 +452,13 @@ void FPU_ESC3_EA(Bitu rm,PhysPt addr) { FPU_FPOP(); break; case 0x05: /* FLD 80 Bits Real */ - FPU_FLD80(addr); + { + Real64 val = FPU_FLD80(addr); + FPU_PUSH(val); + } break; case 0x07: /* FSTP 80 Bits Real */ - FPU_ST80(addr); + FPU_ST80(addr,TOP); FPU_FPOP(); break; default: @@ -461,7 +484,7 @@ void FPU_ESC3_Normal(Bitu rm) { break; case 0x04: //FNSETPM case 0x05: //FRSTPM - LOG(LOG_FPU,LOG_ERROR)("80267 protected mode (un)set. Nothing done"); +// LOG(LOG_FPU,LOG_ERROR)("80267 protected mode (un)set. Nothing done"); FPU_FNOP(); break; default: @@ -543,6 +566,12 @@ void FPU_ESC5_EA(Bitu rm,PhysPt addr) { mem_writed(addr+4,fpu.regs[TOP].l.upper); FPU_FPOP(); break; + case 0x04: /* FSTOR */ + FPU_FSTOR(addr); + break; + case 0x06: /* FSAVE */ + FPU_FSAVE(addr); + break; case 0x07: /*FNSTSW NG DISAGREES ON THIS*/ FPU_SET_TOP(TOP); mem_writew(addr,fpu.sw); diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 81a65c46..bc2a7e0c 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.16 2004-01-11 09:41:52 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.17 2004-04-01 08:57:33 qbix79 Exp $ */ static void FPU_FINIT(void) { @@ -265,7 +265,7 @@ static void FPU_FBST(PhysPt addr) #define BIAS80 16383 #define BIAS64 1023 -static void FPU_FLD80(PhysPt addr) +static Real64 FPU_FLD80(PhysPt addr) { struct{ Bit16s begin; @@ -283,20 +283,21 @@ static void FPU_FLD80(PhysPt addr) Bit64s sign = (test.begin &0x8000)?1:0; FPU_Reg result; result.ll= (sign <<63)|(exp64final << 52)| mant64; - FPU_PUSH(result.d); + return result.d; + //mant64= test.mant80/2***64 * 2 **53 } -static void FPU_ST80(PhysPt addr) +static void FPU_ST80(PhysPt addr,Bitu reg) { struct{ Bit16s begin; FPU_Reg eind; } test; - Bit64s sign80= (fpu.regs[TOP].ll&LONGTYPE(0x8000000000000000))?1:0; - Bit64s exp80 = fpu.regs[TOP].ll&LONGTYPE(0x7ff0000000000000); + Bit64s sign80= (fpu.regs[reg].ll&LONGTYPE(0x8000000000000000))?1:0; + Bit64s exp80 = fpu.regs[reg].ll&LONGTYPE(0x7ff0000000000000); Bit64s exp80final= (exp80>>52) - BIAS64 + BIAS80; - Bit64s mant80 = fpu.regs[TOP].ll&LONGTYPE(0x000fffffffffffff); + Bit64s mant80 = fpu.regs[reg].ll&LONGTYPE(0x000fffffffffffff); Bit64s mant80final= (mant80 << 11) | LONGTYPE(0x8000000000000000); test.begin= (static_cast(sign80)<<15)| static_cast(exp80final); test.eind.ll=mant80final; @@ -320,3 +321,51 @@ static void FPU_FSCALE(void){ return; //2^x where x is chopped. } +static void FPU_FSTENV(PhysPt addr){ + if(!cpu.code.big) { + mem_writew(addr+0,static_cast(fpu.cw)); + mem_writew(addr+2,static_cast(fpu.sw)); + mem_writew(addr+4,static_cast(FPU_GetTag())); + } else { + mem_writed(addr+0,static_cast(fpu.cw)); + mem_writed(addr+4,static_cast(fpu.sw)); + mem_writed(addr+8,static_cast(FPU_GetTag())); + } +} + +static void FPU_FLDENV(PhysPt addr){ + Bit16u tag; + Bit32u tagbig; + Bitu cw; + if(!cpu.code.big) { + cw = mem_readw(addr+0); + fpu.sw = mem_readw(addr+2); + tag = mem_readw(addr+4); + } else { + cw = mem_readd(addr+0); + fpu.sw = mem_readd(addr+4); + tagbig = mem_readd(addr+8); + tag = static_cast(tagbig); + } + FPU_SetTag(tag); + FPU_SetCW(cw); +} + +static void FPU_FSAVE(PhysPt addr){ + FPU_FSTENV(addr); + Bitu start=(cpu.code.big?28:14); + for(Bitu i=0;i<8;i++){ + FPU_ST80(addr+start,i); + start+=10; + } +} + +static void FPU_FSTOR(PhysPt addr){ + FPU_FLDENV(addr); + Bitu start=(cpu.code.big?28:14); + for(Bitu i=0;i<8;i++){ + fpu.regs[i].d=FPU_FLD80(addr+start); + start+=10; + } +} + From 74f0e5290c531907ba1552291a74698b302218b1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 1 Apr 2004 13:00:05 +0000 Subject: [PATCH 1671/4131] exist searched for too much Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1753 --- src/shell/shell_cmds.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 8d5267a5..a9eb3f9b 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.39 2004-03-10 14:08:18 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.40 2004-04-01 13:00:05 qbix79 Exp $ */ #include @@ -502,7 +502,7 @@ void DOS_Shell::CMD_IF(char * args) { return; }; - if (DOS_FindFirst(word,0xFFFF)==(!has_not)) DoCommand(args); + if (DOS_FindFirst(word,0xffff & ~DOS_ATTR_VOLUME)==(!has_not)) DoCommand(args); return; } if (strcasecmp(word,"ERRORLEVEL")==0) { From dfeec430b850f7dbce13588c0ca1fea4cb938171 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 3 Apr 2004 06:58:13 +0000 Subject: [PATCH 1672/4131] Add reading of dma page register Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1754 --- src/hardware/dma.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index dc0a8d56..cda40dd4 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -16,10 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* - Based the port handling from the bochs dma code. -*/ - #include #include "dosbox.h" #include "mem.h" @@ -146,11 +142,22 @@ static void DMA_Write_PortB(Bit32u port,Bit8u val) { } } + +static void DMA_Write_PortW(Bit32u port,Bit16u val) { + LOG_MSG("Ahh 16bit write port %x val %x",port,val); +} static Bit8u DMA_Read_PortB(Bit32u port) { if (port<0x10) { return DMA_ReadControllerReg(DmaControllers[0],port,1); } else if (port>=0xc0 && port <=0xdf) { return DMA_ReadControllerReg(DmaControllers[1],(port-0xc0) >> 1,1); + } else switch (port) { + case 0x81:return DmaChannels[2]->pagenum; + case 0x82:return DmaChannels[3]->pagenum; + case 0x83:return DmaChannels[1]->pagenum; + case 0x89:return DmaChannels[6]->pagenum; + case 0x8a:return DmaChannels[7]->pagenum; + case 0x8b:return DmaChannels[5]->pagenum; } } @@ -238,6 +245,7 @@ void DMA_Init(Section* sec) { } for (i=0;i<0x10;i++) { IO_RegisterWriteBHandler(i,DMA_Write_PortB); + IO_RegisterWriteWHandler(i,DMA_Write_PortW); IO_RegisterReadBHandler(i,DMA_Read_PortB); if (machine==MCH_VGA) { IO_RegisterWriteBHandler(0xc0+i*2,DMA_Write_PortB); @@ -251,6 +259,13 @@ void DMA_Init(Section* sec) { IO_RegisterWriteBHandler(0x8a,DMA_Write_PortB); IO_RegisterWriteBHandler(0x8b,DMA_Write_PortB); + IO_RegisterReadBHandler(0x81,DMA_Read_PortB); + IO_RegisterReadBHandler(0x82,DMA_Read_PortB); + IO_RegisterReadBHandler(0x83,DMA_Read_PortB); + IO_RegisterReadBHandler(0x89,DMA_Read_PortB); + IO_RegisterReadBHandler(0x8a,DMA_Read_PortB); + IO_RegisterReadBHandler(0x8b,DMA_Read_PortB); + } From 28deb2efa4f42c74e7e451450c5eac4fa3acd305 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 3 Apr 2004 10:34:06 +0000 Subject: [PATCH 1673/4131] Fix typo for opcode 0x29d Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1755 --- src/cpu/core_full/optable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 2a2877ea..0620870a 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -466,7 +466,7 @@ static OpCode OpCodeTable[1024]={ /* 0x298 - 0x29f */ {D_CWDE ,0 ,0 ,0 },{D_CDQ ,0 ,0 ,0 }, {L_Ifd ,O_CALLFd ,0 ,0 },{D_WAIT ,0 ,0 ,0 }, -{L_FLG ,0 ,S_PUSHd,0 },{L_PFLGw ,0 ,0 ,0 }, +{L_FLG ,0 ,S_PUSHd,0 },{L_PFLGd ,0 ,0 ,0 }, {L_REGb ,0 ,S_FLGb ,REGI_AH},{L_FLG ,0 ,S_REGb ,REGI_AH}, /* 0x2a0 - 0x2a7 */ From 57a7795ae0aaaa611c7da4bc7b6577c2ad919dc5 Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Sat, 3 Apr 2004 19:01:45 +0000 Subject: [PATCH 1674/4131] Fix default mixer sampling rate. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1756 --- src/dosbox.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 88c1fc1f..862a4e1e 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.67 2004-03-31 14:43:50 harekiet Exp $ */ +/* $Id: dosbox.cpp,v 1.68 2004-04-03 19:01:45 canadacow Exp $ */ #include #include @@ -251,7 +251,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("mixer",&MIXER_Init); secprop->Add_bool("nosound",false); - secprop->Add_int("rate",32000); + secprop->Add_int("rate",22050); secprop->Add_int("blocksize",2048); secprop->Add_string("wavedir","waves"); From d0e2bfa15fe9f7ca7f52ad137f127220eeeaa36f Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Sat, 3 Apr 2004 19:24:59 +0000 Subject: [PATCH 1675/4131] Added FAT image access and DOS booter functionality Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1757 --- include/bios.h | 63 +- include/dos_inc.h | 21 +- src/dos/dos_programs.cpp | 152 ++++- src/dos/drive_fat.cpp | 1271 ++++++++++++++++++++++++++++++++++++++ src/dos/drive_local.cpp | 13 +- src/dos/drives.h | 125 +++- src/ints/bios_disk.cpp | 427 ++++++++++++- 7 files changed, 2024 insertions(+), 48 deletions(-) create mode 100644 src/dos/drive_fat.cpp diff --git a/include/bios.h b/include/bios.h index 18e2fb1d..af1ae858 100644 --- a/include/bios.h +++ b/include/bios.h @@ -16,6 +16,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef _BIOS_H_ +#define _BIOS_H_ + #define BIOS_BASE_ADDRESS_COM1 0x400 #define BIOS_BASE_ADDRESS_COM2 0x402 #define BIOS_BASE_ADDRESS_COM3 0x404 @@ -96,23 +99,57 @@ /* The Section handling Bios Disk Access */ #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; +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 */ }; -class imageDisk : public BIOS_Disk { +extern diskGeo DiskGeometryList[]; + +#include +#include "mem.h" +#include "dos_inc.h" + +class imageDisk { 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; + 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); void BIOS_ZeroExtendedSize(void); void char_out(Bit8u chr,Bit32u att,Bit8u page); @@ -123,4 +160,4 @@ void INT2F_StartUp(void); void INT33_StartUp(void); void INT13_StartUp(void); - +#endif diff --git a/include/dos_inc.h b/include/dos_inc.h index d35e28d8..d5805e3b 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.38 2004-02-28 16:35:42 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.39 2004-04-03 19:19:29 canadacow Exp $ */ #ifndef DOS_H_ #define DOS_H_ @@ -67,6 +67,25 @@ struct DOS_Block { } tables; }; +#ifdef _MSC_VER +#pragma pack (1) +#endif +union bootSector { + struct entries { + 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 { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 79425a68..6fe1e4b8 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.22 2004-01-10 14:03:34 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.23 2004-04-03 19:21:28 canadacow Exp $ */ #include #include @@ -28,9 +28,13 @@ #include "regs.h" #include "callback.h" #include "cdrom.h" +#include "dos_system.h" +#include "dos_inc.h" +#include "bios.h" void MSCDEX_SetCDInterface(int intNr, int forceCD); +void IMGMOUNT_ProgramStart(Program * * make); class MOUNT : public Program { public: @@ -196,6 +200,150 @@ static void MEM_ProgramStart(Program * * make) { *make=new MEM; } +extern Bit32u floppytype; + + + +class BOOT : public Program { +private: + FILE *getFSFile(Bit8u * filename, Bit32u *ksize, Bit32u *bsize) { + Bit8u drive; + FILE *tmpfile; + char fullname[DOS_PATHLENGTH]; + + localDrive* ldp=0; + if (!DOS_MakeName((char *)filename,fullname,&drive)) return NULL; + ldp=(localDrive*)Drives[drive]; + tmpfile = ldp->GetSystemFilePtr(fullname, "r"); + if(tmpfile == NULL) { + WriteOut("Bootdisk file does not exist. Failing.\n"); + return NULL; + } + fclose(tmpfile); + tmpfile = ldp->GetSystemFilePtr(fullname, "rb+"); + if(tmpfile == NULL) { + WriteOut("Cannot open bootdisk file. Failing.\n"); + return NULL; + } + + fseek(tmpfile,0L, SEEK_END); + *ksize = (ftell(tmpfile) / 1024); + *bsize = ftell(tmpfile); + return tmpfile; + } + + void printError(void) { + WriteOut("This command boots DosBox from either a floppy or hard disk image.\n\n"); + WriteOut("For this command, one can specify a succession of floppy disks swappable\n"); + WriteOut("by pressing Ctrl-F4, and -l specifies the mounted drive to boot from. If\n"); + WriteOut("no drive letter is specified, this defaults to booting from the A drive.\n"); + WriteOut("The only bootable drive letters are A, C, and D. For booting from a hard\n"); + WriteOut("drive (C or D), the image should have already been mounted using the\n"); + WriteOut("IMGMOUNT command.\n\n"); + WriteOut("The syntax of this command is:\n\n"); + WriteOut("BOOT [diskimg1.img diskimg2.img] [-l driveletter]\n"); + } + + +public: + + void Run(void) { + FILE *usefile; + Bitu i; + Bit32u floppysize, rombytesize; + Bit8u drive; + + if(!cmd->GetCount()) { + printError(); + return; + } + i=0; + drive = 'A'; + while(iGetCount()) { + if(cmd->FindCommand(i+1, temp_line)) { + if(temp_line == "-l") { + /* Specifying drive... next argument then is the drive */ + i++; + if(cmd->FindCommand(i+1, temp_line)) { + drive=toupper(temp_line[0]); + if ((drive != 'A') && (drive != 'C') && (drive != 'D')) { + printError(); + return; + } + + } else { + printError(); + return; + } + i++; + continue; + } + + WriteOut("Opening image file: %s\n", temp_line.c_str()); + usefile = getFSFile((Bit8u *)temp_line.c_str(), &floppysize, &rombytesize); + if(usefile != NULL) { + if(diskSwap[i] != NULL) delete diskSwap[i]; + diskSwap[i] = new imageDisk(usefile, (Bit8u *)temp_line.c_str(), floppysize, false); + + } else { + WriteOut("Cannot open %s", temp_line.c_str()); + return; + } + + } + i++; + } + + swapPosition = 0; + + swapInDisks(); + + if(imageDiskList[drive-65]==NULL) { + WriteOut("Unable to boot off of drive %c", drive); + return; + } + + WriteOut("Booting from drive %c...\n", drive); + + bootSector bootarea; + imageDiskList[drive-65]->Read_Sector(0,0,1,(Bit8u *)&bootarea); + for(i=0;i<512;i++) real_writeb(0, 0x7c00 + i, bootarea.rawdata[i]); + + + + SegSet16(cs, 0); + reg_ip = 0x7c00; + + + + /* Most likely a PCJr ROM */ + /* Write it to E000:0000 */ + /* Code inoperable at the moment */ + + /* + Bit8u rombuff[65536]; + fseek(tmpfile,512L, SEEK_SET); + rombytesize-=512; + fread(rombuff, 1, rombytesize, tmpfile); + fclose(tmpfile); + for(i=0;i +#include +#include +#include +#include "dosbox.h" +#include "dos_inc.h" +#include "drives.h" +#include "support.h" +#include "cross.h" +#include "bios.h" + +#define IMGTYPE_FLOPPY 0 +#define IMGTYPE_ISO 1 +#define IMGTYPE_HDD 2 + +#define FAT12 0 +#define FAT16 1 +#define FAT32 2 + +class fatFile : public DOS_File { +public: + fatFile(const char* name, Bit32u startCluster, Bit32u fileLen, fatDrive *useDrive); + bool Read(Bit8u * data,Bit16u * size); + bool Write(Bit8u * data,Bit16u * size); + bool Seek(Bit32u * pos,Bit32u type); + bool Close(); + Bit16u GetInformation(void); + bool UpdateDateTimeFromHost(void); +public: + Bit32u firstCluster; + Bit32u seekpos; + Bit32u filelength; + Bit32u currentSector; + Bit32u curSectOff; + Bit8u sectorBuffer[512]; + /* Record of where in the directory structure this file is located */ + Bit32u dirCluster; + Bit32u dirIndex; + + bool loadedSector; + fatDrive *myDrive; +private: + enum { NONE,READ,WRITE } last_action; + Bit16u info; +}; + + +/* IN - char * filename: Name in regular filename format, e.g. bob.txt */ +/* OUT - char * filearray: Name in DOS directory format, eleven char, e.g. bob txt */ +static void convToDirFile(char *filename, char *filearray) { + Bit32u charidx = 0; + Bit32u flen; + int i; + flen = strlen(filename); + memset(filearray, 32, 11); + for(i=0;i= 11) break; + if(filename[i] != '.') { + filearray[charidx] = filename[i]; + charidx++; + } else { + charidx = 8; + } + } + + + +} + +fatFile::fatFile(const char* name, Bit32u startCluster, Bit32u fileLen, fatDrive *useDrive) { + Bit32u seekto = 0; + firstCluster = startCluster; + myDrive = useDrive; + filelength = fileLen; + loadedSector = false; + curSectOff = 0; + seekpos = 0; + memset(§orBuffer[0], 0, sizeof(sectorBuffer)); + + if(filelength > 0) { + Seek(&seekto, DOS_SEEK_SET); + myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); + loadedSector = true; + } +} + +bool fatFile::Read(Bit8u * data, Bit16u *size) { + Bit16u sizedec, sizecount; + if(seekpos >= filelength) { + *size = 0; + return true; + } + + sizedec = *size; + sizecount = 0; + while(sizedec != 0) { + if(seekpos >= filelength) { + *size = sizecount; + return true; + } + data[sizecount] = sectorBuffer[curSectOff]; + curSectOff++; + seekpos++; + if(curSectOff >= myDrive->getSectorSize()) { + currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); + if(currentSector == 0) { + /* EOC reached before EOF */ + LOG_MSG("EOC reached before EOF, seekpos %d, filelen %d", seekpos, filelength); + *size = sizecount; + return true; + } + curSectOff = 0; + myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); + LOG_MSG("Reading absolute sector at %d for seekpos %d", currentSector, seekpos); + } + --sizedec; + sizecount++; + } + *size =sizecount; + return true; +} + +bool fatFile::Write(Bit8u * data, Bit16u *size) { + /* TODO: Check for read-only bit */ + + direntry tmpentry; + Bit16u sizedec, sizecount; + sizedec = *size; + sizecount = 0; + while(sizedec != 0) { + /* Increase filesize if necessary */ + if(seekpos >= filelength) { + if(filelength == 0) { + firstCluster = myDrive->getFirstFreeClust(); + myDrive->allocateCluster(firstCluster, 0); + } + filelength = seekpos+1; + } + sectorBuffer[curSectOff] = data[sizecount]; + curSectOff++; + seekpos++; + if(curSectOff >= myDrive->getSectorSize()) { + if(loadedSector) myDrive->loadedDisk->Write_AbsoluteSector(currentSector, sectorBuffer); + + currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); + if(currentSector == 0) { + /* EOC reached before EOF - try to increase file allocation */ + myDrive->appendCluster(firstCluster); + /* Try getting sector again */ + currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); + if(currentSector == 0) { + /* No can do. lets give up and go home. We must be out of room */ + goto finalizeWrite; + + } + } + curSectOff = 0; + myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); + + loadedSector = true; + } + --sizedec; + sizecount++; + } + +finalizeWrite: + myDrive->directoryBrowse(dirCluster, &tmpentry, dirIndex); + tmpentry.entrysize = filelength; + tmpentry.loFirstClust = firstCluster; + myDrive->directoryChange(dirCluster, &tmpentry, dirIndex); + + *size =sizecount; + return true; + +} + +bool fatFile::Seek(Bit32u *pos, Bit32u type) { + Bit32s seekto; + + switch(type) { + case DOS_SEEK_SET: + seekto = (Bit32s)*pos; + break; + case DOS_SEEK_CUR: + /* Is this relative seek signed? */ + seekto = (Bit32s)*pos + (Bit32s)seekpos; + break; + case DOS_SEEK_END: + seekto = (Bit32s)filelength + (Bit32s)*pos; + break; + } + LOG_MSG("Seek to %d with type %d (absolute value %d)", *pos, type, seekto); + + if((Bit32u)seekto > filelength) seekto = (Bit32s)filelength; + if(seekto<0) seekto = 0; + seekpos = (Bit32u)seekto; + currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); + curSectOff = seekpos % myDrive->getSectorSize(); + myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); + *pos = seekpos; + return true; +} + +bool fatFile::Close() { + /* Flush buffer */ + if (loadedSector) myDrive->loadedDisk->Write_AbsoluteSector(currentSector, sectorBuffer); + + return false; +} + +Bit16u fatFile::GetInformation(void) { + return 0x202; +} + +bool fatFile::UpdateDateTimeFromHost(void) { + return true; +} + +Bit32u fatDrive::getClustFirstSect(Bit32u clustNum) { + return ((clustNum - 2) * bootbuffer.sectorspercluster) + firstDataSector; +} + +Bit32u fatDrive::getClusterValue(Bit32u clustNum) { + Bit32u fatoffset; + Bit32u fatsectnum; + Bit32u fatentoff; + + Bit32u clustValue; + + + /* Load two sectors at once for FAT12 */ + Bit8u sectbuffer[1024]; + + switch(fattype) { + case FAT12: + fatoffset = clustNum + (clustNum / 2); + break; + case FAT16: + fatoffset = clustNum * 2; + break; + case FAT32: + fatoffset = clustNum * 4; + break; + } + fatsectnum = bootbuffer.reservedsectors + (fatoffset / bootbuffer.bytespersector) + partSectOff; + fatentoff = fatoffset % bootbuffer.bytespersector; + + loadedDisk->Read_AbsoluteSector(fatsectnum, §buffer[0]); + loadedDisk->Read_AbsoluteSector(fatsectnum+1, §buffer[512]); + + switch(fattype) { + case FAT12: + clustValue = *((Bit16u *)§buffer[fatentoff]); + if(clustNum & 0x1) { + clustValue >>= 4; + } else { + clustValue &= 0xfff; + } + break; + case FAT16: + clustValue = *((Bit16u *)§buffer[fatentoff]); + break; + case FAT32: + clustValue = *((Bit32u *)§buffer[fatentoff]); + break; + } + + return clustValue; +} + +void fatDrive::setClusterValue(Bit32u clustNum, Bit32u clustValue) { + Bit32u fatoffset; + Bit32u fatsectnum; + Bit32u fatentoff; + Bit32u tmpValue; + + + /* Load two sectors at once for FAT12 */ + Bit8u sectbuffer[1024]; + + switch(fattype) { + case FAT12: + fatoffset = clustNum + (clustNum / 2); + break; + case FAT16: + fatoffset = clustNum * 2; + break; + case FAT32: + fatoffset = clustNum * 4; + break; + } + fatsectnum = bootbuffer.reservedsectors + (fatoffset / bootbuffer.bytespersector) + partSectOff; + fatentoff = fatoffset % bootbuffer.bytespersector; + + loadedDisk->Read_AbsoluteSector(fatsectnum, §buffer[0]); + loadedDisk->Read_AbsoluteSector(fatsectnum+1, §buffer[512]); + + switch(fattype) { + case FAT12: + tmpValue = *((Bit16u *)§buffer[fatentoff]); + if(clustNum & 0x1) { + clustValue &= 0xfff; + clustValue <<= 4; + tmpValue &= 0xf; + tmpValue |= clustValue; + + } else { + clustValue &= 0xfff; + tmpValue &= 0xf000; + tmpValue |= clustValue; + } + *((Bit16u *)§buffer[fatentoff]) = tmpValue; + break; + case FAT16: + *((Bit16u *)§buffer[fatentoff]) = clustValue; + break; + case FAT32: + *((Bit32u *)§buffer[fatentoff]) = clustValue; + break; + } + int fc; + for(fc=0;fcWrite_AbsoluteSector(fatsectnum + (fc * bootbuffer.sectorsperfat), §buffer[0]); + loadedDisk->Write_AbsoluteSector(fatsectnum+1+(fc * bootbuffer.sectorsperfat), §buffer[512]); + } +} + +bool fatDrive::getEntryName(char *fullname, char *entname) { + Bit16u len = strlen(fullname); + char dirtoken[DOS_PATHLENGTH]; + Bit32u currentClust = 0; + + direntry foundEntry; + char * findDir; + char * findFile; + strcpy(dirtoken,fullname); + + LOG_MSG("Testing for filename %s", fullname); + findDir = strtok(dirtoken,"\\"); + findFile = findDir; + while(findDir != NULL) { + findFile = findDir; + findDir = strtok(NULL,"\\"); + } + strcpy(entname, findFile); + return true; +} + +bool fatDrive::getFileDirEntry(char * filename, direntry * useEntry, Bit32u * dirClust, Bit32u * subEntry) { + Bit16u len = strlen(filename); + char dirtoken[DOS_PATHLENGTH]; + Bit32u currentClust = 0; + + direntry foundEntry; + char * findDir; + char * findFile; + strcpy(dirtoken,filename); + + /* Skip if testing in root directory */ + if ((len>0) && (filename[len-1]!='\\')) { + LOG_MSG("Testing for filename %s", filename); + findDir = strtok(dirtoken,"\\"); + findFile = findDir; + while(findDir != NULL) { + imgDTA->SetupSearch(0,DOS_ATTR_DIRECTORY,findDir); + imgDTA->SetDirID(0); + + findFile = findDir; + if(!FindNextInternal(currentClust, *imgDTA, &foundEntry)) break; + currentClust = foundEntry.loFirstClust; + findDir = strtok(NULL,"\\"); + } + } else { + /* Set to root directory */ + } + + /* Search found directory for our file */ + imgDTA->SetupSearch(0,0x5,findFile); + imgDTA->SetDirID(0); + if(!FindNextInternal(currentClust, *imgDTA, &foundEntry)) return false; + + memcpy(useEntry, &foundEntry, sizeof(direntry)); + *dirClust = (Bit32u)currentClust; + *subEntry = ((Bit32u)imgDTA->GetDirID()-1); + + + + return true; +} + +bool fatDrive::getDirClustNum(char *dir, Bit32u *clustNum, bool parDir) { + Bit16u len = strlen(dir); + char dirtoken[DOS_PATHLENGTH]; + Bit32u currentClust = 0; + direntry foundEntry; + char * findDir; + strcpy(dirtoken,dir); + + /* Skip if testing for root directory */ + if ((len>0) && (dir[len-1]!='\\')) { + LOG_MSG("Testing for dir %s", dir); + findDir = strtok(dirtoken,"\\"); + while(findDir != NULL) { + imgDTA->SetupSearch(0,DOS_ATTR_DIRECTORY,findDir); + imgDTA->SetDirID(0); + findDir = strtok(NULL,"\\"); + if(!parDir) { + if(!FindNextInternal(currentClust, *imgDTA, &foundEntry)) return false; + } else { + if(findDir == NULL) break; + if(!FindNextInternal(currentClust, *imgDTA, &foundEntry)) return false; + } + currentClust = foundEntry.loFirstClust; + + } + *clustNum = currentClust; + return true; + } else { + /* Set to root directory */ + *clustNum = 0; + return true; + } + return false; + +} + +Bit32u fatDrive::getSectorSize(void) { + return bootbuffer.bytespersector; +} + +Bit32u fatDrive::getAbsoluteSectFromBytePos(Bit32u startClustNum, Bit32u bytePos) { + return getAbsoluteSectFromChain(startClustNum, bytePos / bootbuffer.bytespersector); +} + +Bit32u fatDrive::getAbsoluteSectFromChain(Bit32u startClustNum, Bit32u logicalSector) { + Bit32s skipClust = logicalSector / bootbuffer.sectorspercluster; + Bit32u sectClust = logicalSector % bootbuffer.sectorspercluster; + + Bit32u currentClust = startClustNum; + Bit32u testvalue; + + while(skipClust!=0) { + bool isEOF = false; + testvalue = getClusterValue(currentClust); + switch(fattype) { + case FAT12: + if(testvalue >= 0xff8) isEOF = true; + break; + case FAT16: + if(testvalue >= 0xfff8) isEOF = true; + break; + case FAT32: + if(testvalue >= 0xfffffff8) isEOF = true; + break; + } + if((isEOF) && (skipClust>1)) { + //LOG_MSG("End of cluster chain reached before end of logical sector seek!"); + return 0; + } + currentClust = testvalue; + --skipClust; + } + return (getClustFirstSect(currentClust) + sectClust); +} + +void fatDrive::deleteClustChain(Bit32u startCluster) { + Bit32u testvalue; + Bit32u currentClust = startCluster; + bool isEOF = false; + while(!isEOF) { + testvalue = getClusterValue(currentClust); + if(testvalue == 0) { + /* What the crap? Cluster is already empty - BAIL! */ + break; + } + /* Mark cluster as empty */ + setClusterValue(currentClust, 0); + switch(fattype) { + case FAT12: + if(testvalue >= 0xff8) isEOF = true; + break; + case FAT16: + if(testvalue >= 0xfff8) isEOF = true; + break; + case FAT32: + if(testvalue >= 0xfffffff8) isEOF = true; + break; + } + if(isEOF) break; + currentClust = testvalue; + } +} + +Bit32u fatDrive::appendCluster(Bit32u startCluster) { + Bit32u testvalue; + Bit32u currentClust = startCluster; + bool isEOF = false; + + while(!isEOF) { + testvalue = getClusterValue(currentClust); + switch(fattype) { + case FAT12: + if(testvalue >= 0xff8) isEOF = true; + break; + case FAT16: + if(testvalue >= 0xfff8) isEOF = true; + break; + case FAT32: + if(testvalue >= 0xfffffff8) isEOF = true; + break; + } + if(isEOF) break; + currentClust = testvalue; + } + + Bit32u newClust = getFirstFreeClust(); + /* Drive is full */ + if(newClust == 0) return 0; + + if(!allocateCluster(newClust, currentClust)) return 0; + + zeroOutCluster(newClust); + + return newClust; + + + + +} + +bool fatDrive::allocateCluster(Bit32u useCluster, Bit32u prevCluster) { + + /* Can't allocate cluster #0 */ + if(useCluster == 0) return false; + + if(prevCluster != 0) { + /* Refuse to allocate cluster if previous cluster value is zero (unallocated) */ + if(!getClusterValue(prevCluster)) return false; + + /* Point cluster to new cluster in chain */ + setClusterValue(prevCluster, useCluster); + } + + switch(fattype) { + case FAT12: + setClusterValue(useCluster, 0xfff); + break; + case FAT16: + setClusterValue(useCluster, 0xffff); + break; + case FAT32: + setClusterValue(useCluster, 0xffffffff); + break; + } + return true; + +} + +fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, Bit32u headscyl, Bit32u cylinders, Bit32u startSector) { + FILE *diskfile; + Bit32u filesize; + struct partTable mbrData; + + if(imgDTASeg == 0) { + imgDTASeg = DOS_GetMemory(2); + imgDTAPtr = RealMake(imgDTASeg, 0); + imgDTA = new DOS_DTA(imgDTAPtr); + } + + diskfile = fopen(sysFilename, "rb+"); + if(!diskfile) return; + fseek(diskfile, 0L, SEEK_END); + filesize = (Bit32u)ftell(diskfile) / 1024L; + + /* Load disk image */ + loadedDisk = new imageDisk(diskfile, (Bit8u *)sysFilename, filesize, (filesize > 2880)); + if(!loadedDisk) { + delete this; + return; + } + + if(filesize > 2880) { + /* Set user specified harddrive parameters */ + loadedDisk->Set_Geometry(headscyl, cylinders,cylsector, bytesector); + + loadedDisk->Read_Sector(0,0,1,&mbrData); + startSector = 63; + int m; + for(m=0;m<4;m++) { + /* Pick the first available partition */ + if(mbrData.pentry[m].partSize != 0x00) { + LOG_MSG("Using partition %d on drive; skipping %d sectors", m, mbrData.pentry[m].absSectStart); + startSector = mbrData.pentry[m].absSectStart; + break; + } + } + + partSectOff = startSector; + } else { + /* Floppy disks don't have partitions */ + partSectOff = 0; + } + + loadedDisk->Read_AbsoluteSector(0+partSectOff,&bootbuffer); + if ((bootbuffer.magic1 != 0x55) || (bootbuffer.magic2 != 0xaa)) { + /* Not a FAT filesystem */ + delete this; + return; + } + + if(!bootbuffer.sectorsperfat) { + /* FAT32 not implemented yet */ + delete this; + return; + } + + + /* Determine FAT format, 12, 16 or 32 */ + + /* Get size of root dir in sectors */ + /* TODO: Get 32-bit total sector count if needed */ + Bit32u RootDirSectors = ((bootbuffer.rootdirentries * 32) + (bootbuffer.bytespersector - 1)) / bootbuffer.bytespersector; + Bit32u DataSectors; + if(bootbuffer.totalsectorcount != 0) { + DataSectors = bootbuffer.totalsectorcount - (bootbuffer.reservedsectors + (bootbuffer.fatcopies * bootbuffer.sectorsperfat) + RootDirSectors); + } else { + DataSectors = bootbuffer.totalsecdword - (bootbuffer.reservedsectors + (bootbuffer.fatcopies * bootbuffer.sectorsperfat) + RootDirSectors); + + } + CountOfClusters = DataSectors / bootbuffer.sectorspercluster; + + firstDataSector = (bootbuffer.reservedsectors + (bootbuffer.fatcopies * bootbuffer.sectorsperfat) + RootDirSectors) + partSectOff; + firstRootDirSect = bootbuffer.reservedsectors + (bootbuffer.fatcopies * bootbuffer.sectorsperfat) + partSectOff; + + if(CountOfClusters < 4085) { + /* Volume is FAT12 */ + LOG_MSG("Mounted FAT volume is FAT12 with %d clusters", CountOfClusters); + fattype = FAT12; + } else if (CountOfClusters < 65525) { + LOG_MSG("Mounted FAT volume is FAT16 with %d clusters", CountOfClusters); + fattype = FAT16; + } else { + LOG_MSG("Mounted FAT volume is FAT32 with %d clusters", CountOfClusters); + fattype = FAT32; + } + + /* There is no cluster 0, this means we are in the root directory */ + cwdDirCluster = 0; + + + + +} + +bool fatDrive::AllocationInfo(Bit16u *_bytes_sector, Bit8u *_sectors_cluster, Bit16u *_total_clusters, Bit16u *_free_clusters) { + Bit32u hs, cy, sect,sectsize; + Bit32u countFree = 0; + int i; + + loadedDisk->Get_Geometry(&hs, &cy, §, §size); + *_bytes_sector = (Bit16u)sectsize; + *_sectors_cluster = bootbuffer.sectorspercluster; + *_total_clusters = CountOfClusters; + for(i=0;iGetBiosType(); } + +bool fatDrive::FileCreate(DOS_File **file, char *name, Bit16u attributes) { + direntry fileEntry; + Bit32u dirClust, subEntry; + char dirName[DOS_NAMELENGTH_ASCII]; + char pathName[11]; + + /* Check if file already exists */ + if(getFileDirEntry(name, &fileEntry, &dirClust, &subEntry)) return false; + + /* Can we even get the name of the file itself? */ + if(!getEntryName(name, &dirName[0])) return false; + convToDirFile(&dirName[0], &pathName[0]); + + /* Can we find the base directory? */ + if(!getDirClustNum(name, &dirClust, true)) return false; + memset(&fileEntry, 0, sizeof(direntry)); + memcpy(&fileEntry.entryname, &pathName[0], 11); + fileEntry.attrib = attributes; + addDirectoryEntry(dirClust, fileEntry); + + /* Check if file exists now */ + if(!getFileDirEntry(name, &fileEntry, &dirClust, &subEntry)) return false; + + /* Empty file created, now lets open it */ + /* TODO: check for read-only flag and requested write access */ + *file = new fatFile(name, fileEntry.loFirstClust, fileEntry.entrysize, this); + ((fatFile *)(*file))->dirCluster = dirClust; + ((fatFile *)(*file))->dirIndex = subEntry; + + return true; +} + +bool fatDrive::FileExists(const char *name) { + direntry fileEntry; + Bit32u dummy1, dummy2; + if(!getFileDirEntry((char *)name, &fileEntry, &dummy1, &dummy2)) return false; + return true; +} + +bool fatDrive::FileOpen(DOS_File **file, char *name, Bit32u flags) { + direntry fileEntry; + Bit32u dirClust, subEntry; + if(!getFileDirEntry(name, &fileEntry, &dirClust, &subEntry)) return false; + /* TODO: check for read-only flag and requested write access */ + *file = new fatFile(name, fileEntry.loFirstClust, fileEntry.entrysize, this); + ((fatFile *)(*file))->dirCluster = dirClust; + ((fatFile *)(*file))->dirIndex = subEntry; + + return true; +} + +bool fatDrive::FileStat(const char *name, FileStat_Block *const stat_block) { + /* TODO: Stub */ + return false; +} + +bool fatDrive::FileUnlink(char * name) { + direntry fileEntry; + Bit32u dirClust, subEntry; + + if(!getFileDirEntry(name, &fileEntry, &dirClust, &subEntry)) return false; + + fileEntry.entryname[0] = 0xe5; + directoryChange(dirClust, &fileEntry, subEntry); + + if(fileEntry.loFirstClust != 0) deleteClustChain(fileEntry.loFirstClust); + + return true; +} + +bool fatDrive::FindFirst(char *_dir, DOS_DTA &dta) { + direntry dummyClust; + + if(!getDirClustNum(_dir, &cwdDirCluster, false)) return false; + dta.SetDirID(0); + return FindNextInternal(cwdDirCluster, dta, &dummyClust); +} + +char* removeTrailingSpaces(char* str) +{ + char* end = str + strlen(str); + while(*--end == ' ' && end > str); + *++end = '\0'; + return str; +} + +char* removeLeadingSpaces(char* str) +{ + size_t len = strlen(str); + size_t pos = strspn(str," "); + memmove(str,str + pos,len - pos + 1); + return str; +} + +char* trimString(char* str) +{ + return removeTrailingSpaces(removeLeadingSpaces(str)); +} + +bool fatDrive::FindNextInternal(Bit32u dirClustNumber, DOS_DTA &dta, direntry *foundEntry) { + direntry sectbuf[16]; /* 16 directory entries per sector */ + Bit32u logentsector; /* Logical entry sector */ + Bit32u entryoffset; /* Index offset within sector */ + Bit32u tmpsector; + Bit8u attrs; + Bit16u dirPos; + char srch_pattern[DOS_NAMELENGTH_ASCII]; + char find_name[DOS_NAMELENGTH_ASCII]; + char extension[4]; + + dta.GetSearchParams(attrs, srch_pattern); + dirPos = dta.GetDirID(); + +nextfile: + logentsector = dirPos / 16; + entryoffset = dirPos % 16; + + if(dirClustNumber==0) { + loadedDisk->Read_AbsoluteSector(firstRootDirSect+logentsector,sectbuf); + } else { + tmpsector = getAbsoluteSectFromChain(dirClustNumber, logentsector); + /* A zero sector number can't happen */ + if(tmpsector == 0) return false; + loadedDisk->Read_AbsoluteSector(tmpsector,sectbuf); + } + dirPos++; + dta.SetDirID(dirPos); + + /* Deleted file entry */ + if (sectbuf[entryoffset].entryname[0] == 0xe5) goto nextfile; + + /* End of directory list */ + if (sectbuf[entryoffset].entryname[0] == 0x00) return false; + + memset(find_name,0,DOS_NAMELENGTH_ASCII); + memset(extension,0,4); + memcpy(find_name,§buf[entryoffset].entryname[0],8); + memcpy(extension,§buf[entryoffset].entryname[8],3); + trimString(&find_name[0]); + trimString(&extension[0]); + if(!(sectbuf[entryoffset].attrib & DOS_ATTR_DIRECTORY)) { + strcat(find_name, "."); + strcat(find_name, extension); + } + + if((attrs & (sectbuf[entryoffset].attrib | 0x21)) == 0) goto nextfile; + if(!WildFileCmp(find_name,srch_pattern)) goto nextfile; + + dta.SetResult(find_name, sectbuf[entryoffset].entrysize, sectbuf[entryoffset].crtDate, sectbuf[entryoffset].crtTime, sectbuf[entryoffset].attrib); + memcpy(foundEntry, §buf[entryoffset], sizeof(direntry)); + + return true; + +} + +bool fatDrive::FindNext(DOS_DTA &dta) { + direntry dummyClust; + + return FindNextInternal(cwdDirCluster, dta, &dummyClust); +} + +bool fatDrive::GetFileAttr(char *name, Bit16u *attr) { + /* TODO: Stub */ + return false; +} + +bool fatDrive::directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum) { + direntry sectbuf[16]; /* 16 directory entries per sector */ + Bit32u logentsector; /* Logical entry sector */ + Bit32u entryoffset; /* Index offset within sector */ + Bit32u tmpsector; + Bit8u attrs; + Bit16u dirPos = 0; + char srch_pattern[DOS_NAMELENGTH_ASCII]; + char find_name[DOS_NAMELENGTH_ASCII]; + char extension[4]; + + while(entNum>=0) { + + logentsector = dirPos / 16; + entryoffset = dirPos % 16; + + if(dirClustNumber==0) { + if(dirPos >= bootbuffer.rootdirentries) return false; + tmpsector = firstRootDirSect+logentsector; + loadedDisk->Read_AbsoluteSector(tmpsector,sectbuf); + } else { + tmpsector = getAbsoluteSectFromChain(dirClustNumber, logentsector); + /* A zero sector number can't happen */ + if(tmpsector == 0) return false; + loadedDisk->Read_AbsoluteSector(tmpsector,sectbuf); + } + dirPos++; + + + /* End of directory list */ + if (sectbuf[entryoffset].entryname[0] == 0x00) return false; + --entNum; + } + + memcpy(useEntry, §buf[entryoffset],sizeof(direntry)); + return true; +} + +bool fatDrive::directoryChange(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum) { + direntry sectbuf[16]; /* 16 directory entries per sector */ + Bit32u logentsector; /* Logical entry sector */ + Bit32u entryoffset; /* Index offset within sector */ + Bit32u tmpsector = 0; + Bit8u attrs; + Bit16u dirPos = 0; + char srch_pattern[DOS_NAMELENGTH_ASCII]; + char find_name[DOS_NAMELENGTH_ASCII]; + char extension[4]; + + while(entNum>=0) { + + logentsector = dirPos / 16; + entryoffset = dirPos % 16; + + if(dirClustNumber==0) { + if(dirPos >= bootbuffer.rootdirentries) return false; + tmpsector = firstRootDirSect+logentsector; + loadedDisk->Read_AbsoluteSector(tmpsector,sectbuf); + } else { + tmpsector = getAbsoluteSectFromChain(dirClustNumber, logentsector); + /* A zero sector number can't happen */ + if(tmpsector == 0) return false; + loadedDisk->Read_AbsoluteSector(tmpsector,sectbuf); + } + dirPos++; + + + /* End of directory list */ + if (sectbuf[entryoffset].entryname[0] == 0x00) return false; + --entNum; + } + if(tmpsector != 0) { + memcpy(§buf[entryoffset], useEntry, sizeof(direntry)); + loadedDisk->Write_AbsoluteSector(tmpsector, sectbuf); + return true; + } else { + return false; + } +} + +bool fatDrive::addDirectoryEntry(Bit32u dirClustNumber, direntry useEntry) { + direntry sectbuf[16]; /* 16 directory entries per sector */ + Bit32u logentsector; /* Logical entry sector */ + Bit32u entryoffset; /* Index offset within sector */ + Bit32u tmpsector; + Bit8u attrs; + Bit16u dirPos = 0; + char srch_pattern[DOS_NAMELENGTH_ASCII]; + char find_name[DOS_NAMELENGTH_ASCII]; + char extension[4]; + + while(true) { + + logentsector = dirPos / 16; + entryoffset = dirPos % 16; + + if(dirClustNumber==0) { + if(dirPos >= bootbuffer.rootdirentries) return false; + tmpsector = firstRootDirSect+logentsector; + loadedDisk->Read_AbsoluteSector(tmpsector,sectbuf); + } else { + tmpsector = getAbsoluteSectFromChain(dirClustNumber, logentsector); + /* A zero sector number can't happen - we need to allocate more room for this directory*/ + if(tmpsector == 0) { + Bit32u newClust; + newClust = appendCluster(dirClustNumber); + if(newClust == 0) return false; + /* Try again to get tmpsector */ + tmpsector = getAbsoluteSectFromChain(dirClustNumber, logentsector); + if(tmpsector == 0) return false; /* Give up if still can't get more room for directory */ + } + loadedDisk->Read_AbsoluteSector(tmpsector,sectbuf); + } + dirPos++; + + /* Deleted file entry or end of directory list */ + if ((sectbuf[entryoffset].entryname[0] == 0xe5) || (sectbuf[entryoffset].entryname[0] == 0x00)) { + sectbuf[entryoffset] = useEntry; + loadedDisk->Write_AbsoluteSector(tmpsector,sectbuf); + return true; + } + } + + + return false; +} + +void fatDrive::zeroOutCluster(Bit32u clustNumber) { + Bit8u secBuffer[512]; + + memset(&secBuffer[0], 0, 512); + + int i; + for(i=0;iWrite_AbsoluteSector(getAbsoluteSectFromChain(clustNumber,i), &secBuffer[0]); + } + +} + +bool fatDrive::MakeDir(char *dir) { + Bit32u dummyClust, dirClust; + direntry tmpentry; + char dirName[DOS_NAMELENGTH_ASCII]; + char pathName[11]; + + /* Can we even get the name of the directory itself? */ + if(!getEntryName(dir, &dirName[0])) return false; + convToDirFile(&dirName[0], &pathName[0]); + + /* Fail to make directory if already exists */ + if(getDirClustNum(dir, &dummyClust, false)) return false; + + dummyClust = getFirstFreeClust(); + /* No more space */ + if(dummyClust == 0) return false; + + if(!allocateCluster(dummyClust, 0)) return false; + + zeroOutCluster(dummyClust); + + /* Can we find the base directory? */ + if(!getDirClustNum(dir, &dirClust, true)) return false; + + /* Add the new directory to the base directory */ + memset(&tmpentry,0, sizeof(direntry)); + memcpy(&tmpentry.entryname, &pathName[0], 11); + tmpentry.loFirstClust = (Bit16u)(dummyClust & 0xffff); + tmpentry.hiFirstClust = (Bit16u)(dummyClust >> 16); + tmpentry.attrib = DOS_ATTR_DIRECTORY; + addDirectoryEntry(dirClust, tmpentry); + + /* Add the [.] and [..] entries to our new directory*/ + /* [.] entry */ + memset(&tmpentry,0, sizeof(direntry)); + memcpy(&tmpentry.entryname, ". ", 11); + tmpentry.loFirstClust = (Bit16u)(dummyClust & 0xffff); + tmpentry.hiFirstClust = (Bit16u)(dummyClust >> 16); + tmpentry.attrib = DOS_ATTR_DIRECTORY; + addDirectoryEntry(dummyClust, tmpentry); + + /* [..] entry */ + memset(&tmpentry,0, sizeof(direntry)); + memcpy(&tmpentry.entryname, ".. ", 11); + tmpentry.loFirstClust = (Bit16u)(dirClust & 0xffff); + tmpentry.hiFirstClust = (Bit16u)(dirClust >> 16); + tmpentry.attrib = DOS_ATTR_DIRECTORY; + addDirectoryEntry(dummyClust, tmpentry); + + return true; + +} + +bool fatDrive::RemoveDir(char *dir) { + Bit32u dummyClust, dirClust; + direntry tmpentry; + char dirName[DOS_NAMELENGTH_ASCII]; + char pathName[11]; + + /* Can we even get the name of the directory itself? */ + if(!getEntryName(dir, &dirName[0])) return false; + convToDirFile(&dirName[0], &pathName[0]); + + /* Get directory starting cluster */ + if(!getDirClustNum(dir, &dummyClust, false)) return false; + + /* Can't remove root directory */ + if(dummyClust == 0) return false; + + /* Get parent directory starting cluster */ + if(!getDirClustNum(dir, &dirClust, true)) return false; + + /* Check to make sure directory is empty */ + Bit32u filecount = 0; + /* Set to 2 to skip first 2 entries, [.] and [..] */ + Bit32s fileidx = 2; + while(directoryBrowse(dummyClust, &tmpentry, fileidx)) { + /* Check for non-deleted files */ + if(tmpentry.entryname[0] != 0xe5) filecount++; + fileidx++; + } + + /* Return if directory is not empty */ + if(filecount > 0) return false; + + /* Find directory entry in parent directory */ + fileidx = 2; + bool found = false; + while(directoryBrowse(dirClust, &tmpentry, fileidx)) { + if(memcmp(&tmpentry.entryname, &pathName[0], 11) == 0) { + found = true; + tmpentry.entryname[0] = 0xe5; + directoryChange(dirClust, &tmpentry, fileidx); + deleteClustChain(dummyClust); + + break; + } + fileidx++; + } + + if(!found) return false; + + return true; +} + +bool fatDrive::Rename(char *oldname, char*newname) { + + return false; +} + +bool fatDrive::TestDir(char *dir) { + Bit32u dummyClust; + return getDirClustNum(dir, &dummyClust, false); +} + + +class IMGMOUNT : public Program { +public: + void Run(void) + { + DOS_Drive * newdrive; + imageDisk * newImage; + Bit32u imagesize; + char drive; + std::string label; + + std::string type="hdd"; + std::string fstype="fat"; + cmd->FindString("-t",type,true); + cmd->FindString("-fs",fstype,true); + Bit8u mediaid; + if (type=="floppy" || type=="hdd" || type=="iso") { + Bit16u sizes[4]; + + std::string str_size; + mediaid=0xF8; + + if (type=="floppy") { + mediaid=0xF0; + } else if (type=="cdrom") { + str_size="650,127,16513,1700"; + mediaid=0xF8; + } + cmd->FindString("-size",str_size,true); + if ((type=="hdd") && (str_size.size()==0)) { + WriteOut("Must specify drive geometry for hard drives:\n"); + WriteOut("bytes_per_sector, sectors_per_cylinder, heads_per_cylinder, cylinder_count\n"); + return; + } + char number[20]; + const char * scan=str_size.c_str(); + Bitu index=0;Bitu count=0; + + while (*scan) { + if (*scan==',') { + number[index]=0;sizes[count++]=atoi(number); + index=0; + } else number[index++]=*scan; + scan++; + } + number[index]=0;sizes[count++]=atoi(number); + + if(fstype=="fat") { + // get the drive letter + cmd->FindCommand(1,temp_line); + if ((temp_line.size() > 2) || ((temp_line.size()>1) && (temp_line[1]!=':'))) { + WriteOut("Must specify drive letter to mount image at.\n"); + return; + } + drive=toupper(temp_line[0]); + if (!isalpha(drive)) { + WriteOut("Must specify drive letter to mount image at.\n"); + return; + } + } else if (fstype=="none") { + cmd->FindCommand(1,temp_line); + if ((temp_line.size() > 1) || (!isdigit(temp_line[0]))) { + WriteOut("Must specify drive number (0 or 3) to mount image at (0,1=fda,fdb;2,3=hda,hdb)\n"); + return; + } + drive=temp_line[0]-'0'; + if(drive>3) { + WriteOut("Must specify drive number (0 or 3) to mount image at (0,1=fda,fdb;2,3=hda,hdb)\n"); + return; + } + } else { + WriteOut("Format \"%s\" is unsupported. Specify \"fat\" or \"none\".\n"); + return; + } + + if (!cmd->FindCommand(2,temp_line)) { + WriteOut("Must specify file image to mount\n"); + return; + } + if (!temp_line.size()) { + WriteOut("Must specify file image to mount\n"); + return; + } + struct stat test; + if (stat(temp_line.c_str(),&test)) { + WriteOut("Image file not found\n"); + return; + } + + if ((test.st_mode & S_IFDIR)) { + WriteOut("To mount directories, use the MOUNT command, not the IMGMOUNT command\n"); + return; + } + + if(fstype=="fat") { + newdrive=new fatDrive(temp_line.c_str(),sizes[0],sizes[1],sizes[2],sizes[3],0); + } else { + FILE *newDisk = fopen(temp_line.c_str(), "rb+"); + fseek(newDisk,0L, SEEK_END); + imagesize = (ftell(newDisk) / 1024); + + newImage = new imageDisk(newDisk, (Bit8u *)temp_line.c_str(), imagesize, (imagesize > 2880)); + if(imagesize>2880) newImage->Set_Geometry(sizes[2],sizes[3],sizes[1],sizes[0]); + } + } + if(fstype=="fat") { + if (Drives[drive-'A']) { + WriteOut("Drive already mounted at that letter\n"); + if (newdrive) delete newdrive; + return; + } + if (!newdrive) WriteOut("Can't create drive from file\n"); + Drives[drive-'A']=newdrive; + // Set the correct media byte in the table + mem_writeb(Real2Phys(dos.tables.mediaid)+drive-'A',mediaid); + WriteOut("Drive %c mounted as %s\n",drive,temp_line.c_str()); + if(((fatDrive *)newdrive)->loadedDisk->hardDrive) { + if(imageDiskList[2] == NULL) { + imageDiskList[2] = ((fatDrive *)newdrive)->loadedDisk; + updateDPT(); + return; + } + if(imageDiskList[3] == NULL) { + imageDiskList[3] = ((fatDrive *)newdrive)->loadedDisk; + updateDPT(); + return; + } + } + if(!((fatDrive *)newdrive)->loadedDisk->hardDrive) { + imageDiskList[0] = ((fatDrive *)newdrive)->loadedDisk; + } + } else if (fstype=="none") { + if(imageDiskList[drive] != NULL) delete imageDiskList[drive]; + imageDiskList[drive] = newImage; + updateDPT(); + WriteOut("Drive number %d mounted as %s\n",drive,temp_line.c_str()); + } + + // check if volume label is given + //if (cmd->FindString("-label",label,true)) newdrive->dirCache.SetLabel(label.c_str()); + return; + } +}; + +void IMGMOUNT_ProgramStart(Program * * make) { + *make=new IMGMOUNT; +} + + diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index a3509725..c395c7ae 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.45 2004-03-04 19:49:21 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.46 2004-04-03 19:23:06 canadacow Exp $ */ #include #include @@ -103,6 +103,17 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { return true; }; +FILE * localDrive::GetSystemFilePtr(char * name, char * type) { + + char newname[CROSS_LEN]; + strcpy(newname,basedir); + strcat(newname,name); + CROSS_FILENAME(newname); + dirCache.ExpandName(newname); + + return fopen(newname,type); +} + bool localDrive::FileUnlink(char * name) { char newname[CROSS_LEN]; strcpy(newname,basedir); diff --git a/src/dos/drives.h b/src/dos/drives.h index 1e5f7395..526386e8 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.19 2004-01-10 14:03:34 qbix79 Exp $ */ +/* $Id: drives.h,v 1.20 2004-04-03 19:22:33 canadacow Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ @@ -24,6 +24,7 @@ #include #include "dos_system.h" #include "shell.h" /* for DOS_Shell */ +#include "bios.h" /* for fatDrive */ bool WildFileCmp(const char * file, const char * wild); @@ -31,6 +32,7 @@ class localDrive : public DOS_Drive { public: localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid); virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags); + virtual FILE *GetSystemFilePtr(char * name, char * type); virtual bool FileCreate(DOS_File * * file,char * name,Bit16u attributes); virtual bool FileUnlink(char * name); virtual bool RemoveDir(char * dir); @@ -61,6 +63,127 @@ private: } allocation; }; +#ifdef _MSC_VER +#pragma pack (1) +#endif +struct bootstrap { + Bit8u nearjmp[3]; + Bit8u oemname[8]; + Bit16u bytespersector; + Bit8u sectorspercluster; + Bit16u reservedsectors; + Bit8u fatcopies; + Bit16u rootdirentries; + Bit16u totalsectorcount; + Bit8u mediadescriptor; + Bit16u sectorsperfat; + Bit16u sectorspertrack; + Bit16u headcount; + /* 32-bit FAT extensions */ + Bit32u hiddensectorcount; + Bit32u totalsecdword; + Bit8u bootcode[474]; + Bit8u magic1; /* 0x55 */ + Bit8u magic2; /* 0xaa */ +} GCC_ATTRIBUTE(packed); + +struct direntry { + Bit8u entryname[11]; + Bit8u attrib; + Bit8u NTRes; + Bit8u milliSecondStamp; + Bit16u crtTime; + Bit16u crtDate; + Bit16u accessDate; + Bit16u hiFirstClust; + Bit16u modTime; + Bit16u modDate; + Bit16u loFirstClust; + Bit32u entrysize; +} GCC_ATTRIBUTE(packed); + +struct partTable { + Bit8u booter[446]; + struct { + Bit8u bootflag; + Bit8u beginchs[3]; + Bit8u parttype; + Bit8u endchs[3]; + Bit32u absSectStart; + Bit32u partSize; + } pentry[4]; + Bit8u magic1; /* 0x55 */ + Bit8u magic2; /* 0xaa */ +} GCC_ATTRIBUTE(packed); + +#ifdef _MSC_VER +#pragma pack () +#endif + +class fatDrive : public DOS_Drive { +public: + fatDrive(const char * sysFilename, Bit32u bytesector, Bit32u cylsector, Bit32u headscyl, Bit32u cylinders, Bit32u startSector); + virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags); + virtual bool FileCreate(DOS_File * * file,char * name,Bit16u attributes); + virtual bool FileUnlink(char * name); + virtual bool RemoveDir(char * dir); + virtual bool MakeDir(char * dir); + virtual bool TestDir(char * dir); + virtual bool FindFirst(char * _dir,DOS_DTA & dta); + virtual bool FindNext(DOS_DTA & dta); + virtual bool GetFileAttr(char * name,Bit16u * attr); + virtual bool Rename(char * oldname,char * newname); + virtual bool AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters); + virtual bool FileExists(const char* name); + virtual bool FileStat(const char* name, FileStat_Block * const stat_block); + virtual Bit8u GetMediaByte(void); + virtual bool isRemote(void); +public: + Bit32u getAbsoluteSectFromBytePos(Bit32u startClustNum, Bit32u bytePos); + Bit32u getSectorSize(void); + Bit32u getAbsoluteSectFromChain(Bit32u startClustNum, Bit32u logicalSector); + bool allocateCluster(Bit32u useCluster, Bit32u prevCluster); + Bit32u appendCluster(Bit32u startCluster); + void deleteClustChain(Bit32u startCluster); + Bit32u getFirstFreeClust(void); + bool directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum); + bool directoryChange(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum); + imageDisk *loadedDisk; +private: + Bit32u getClusterValue(Bit32u clustNum); + void setClusterValue(Bit32u clustNum, Bit32u clustValue); + Bit32u getClustFirstSect(Bit32u clustNum); + bool FindNextInternal(Bit32u dirClustNumber, DOS_DTA & dta, direntry *foundEntry); + bool getDirClustNum(char * dir, Bit32u * clustNum, bool parDir); + bool getFileDirEntry(char * filename, direntry * useEntry, Bit32u * dirClust, Bit32u * subEntry); + bool addDirectoryEntry(Bit32u dirClustNumber, direntry useEntry); + void zeroOutCluster(Bit32u clustNumber); + bool getEntryName(char *fullname, char *entname); + friend void DOS_Shell::CMD_SUBST(char* args); + struct { + char srch_dir[CROSS_LEN]; + } srchInfo[MAX_OPENDIRS]; + + struct { + Bit16u bytes_sector; + Bit8u sectors_cluster; + Bit16u total_clusters; + Bit16u free_clusters; + Bit8u mediaid; + } allocation; + + bootstrap bootbuffer; + Bit8u fattype; + Bit32u CountOfClusters; + Bit32u partSectOff; + Bit32u firstDataSector; + Bit32u firstRootDirSect; + + Bit32u cwdDirCluster; + Bit32u dirPosition; /* Position in directory search */ +}; + + class cdromDrive : public localDrive { public: diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 3e7a38f4..9bbc85f7 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -21,60 +21,425 @@ #include "bios.h" #include "regs.h" #include "mem.h" +#include "keyboard.h" #include "dos_inc.h" /* for Drives[] */ -static Bitu call_int13; -static BIOS_Disk * Floppys[2]; -static BIOS_Disk * Harddisks[BIOS_MAX_DISK]; +#define MAX_SWAPPABLE_DISKS 20 + +diskGeo DiskGeometryList[] = { + {160, 8, 1, 40, 0}, + {180, 9, 1, 40, 0}, + {320, 8, 2, 40, 1}, + {360, 9, 2, 40, 1}, + {720, 9, 2, 80, 3}, + {1200, 15, 2, 80, 2}, + {1440, 18, 2, 80, 4}, + {2880, 36, 2, 80, 6}, + {0, 0, 0 , 0}, +}; + +Bitu call_int13; +Bitu diskparm0, diskparm1; static Bit8u last_status; +static Bit8u last_drive; +Bit16u imgDTASeg; +RealPt imgDTAPtr; +DOS_DTA *imgDTA; +bool killRead; + +/* 2 floppys and 2 harddrives, max */ +imageDisk *imageDiskList[4]; +imageDisk *diskSwap[MAX_SWAPPABLE_DISKS]; +Bits swapPosition; + +void updateDPT(void) { + Bit32u tmpheads, tmpcyl, tmpsect, tmpsize; + if(imageDiskList[2] != NULL) { + imageDiskList[2]->Get_Geometry(&tmpheads, &tmpcyl, &tmpsect, &tmpsize); + real_writew(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0)),tmpcyl); + real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+2,tmpheads); + real_writew(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0x3,0); + real_writew(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0x5,-1); + real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0x7,0); + real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0x8,(0xc0 | (((imageDiskList[2]->heads) > 8) << 3))); + real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0x9,0); + real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0xa,0); + real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0xb,0); + real_writew(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0xc,tmpcyl); + real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0xe,tmpsect); + + + + } + if(imageDiskList[3] != NULL) { + imageDiskList[3]->Get_Geometry(&tmpheads, &tmpcyl, &tmpsect, &tmpsize); + real_writew(RealSeg(CALLBACK_RealPointer(diskparm1)),RealOff(CALLBACK_RealPointer(diskparm1)),tmpcyl); + real_writeb(RealSeg(CALLBACK_RealPointer(diskparm1)),RealOff(CALLBACK_RealPointer(diskparm1))+2,tmpheads); + real_writeb(RealSeg(CALLBACK_RealPointer(diskparm1)),RealOff(CALLBACK_RealPointer(diskparm1))+0xe,tmpsect); + } -static Bitu INT13_SmallHandler(void) { - switch (reg_ah) { +} + +void swapInDisks(void) { + bool allNull = true; + Bits diskcount = 0; + Bits swapPos = swapPosition; + int i; + + /* Check to make sure there's atleast one setup image */ + for(i=0;idiskname); + imageDiskList[diskcount] = diskSwap[swapPos]; + diskcount++; + } + swapPos++; + if(swapPos>=MAX_SWAPPABLE_DISKS) swapPos=0; + } +} + +static void swapInNextDisk(void) { + swapPosition++; + if(diskSwap[swapPosition] == NULL) swapPosition = 0; + swapInDisks(); +} + + +Bit8u imageDisk::Read_Sector(Bit32u head,Bit32u cylinder,Bit32u sector,void * data) { + Bit32u sectnum; + + sectnum = ( (cylinder * heads + head) * sectors ) + sector - 1L; + + return Read_AbsoluteSector(sectnum, data); +} + +Bit8u imageDisk::Read_AbsoluteSector(Bit32u sectnum, void * data) { + Bit32u bytenum; + + bytenum = sectnum * sector_size; + + fseek(diskimg,bytenum,SEEK_SET); + fread(data, 1, sector_size, diskimg); + + return 0x00; +} + +Bit8u imageDisk::Write_Sector(Bit32u head,Bit32u cylinder,Bit32u sector,void * data) { + Bit32u sectnum; + + sectnum = ( (cylinder * heads + head) * sectors ) + sector - 1L; + + return Write_AbsoluteSector(sectnum, data); + +} + + +Bit8u imageDisk::Write_AbsoluteSector(Bit32u sectnum, void *data) { + Bit32u bytenum; + + bytenum = sectnum * sector_size; + + //LOG_MSG("Writing sectors to %ld at bytenum %d", sectnum, bytenum); + + fseek(diskimg,bytenum,SEEK_SET); + fwrite(data, sector_size, 1, diskimg); + + return 0x00; + +} + +imageDisk::imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHardDisk) { + heads = 0; + cylinders = 0; + sectors = 0; + sector_size = 512; + diskimg = imgFile; + + memset(diskname,0,512); + if(strlen((const char *)imgName) > 511) { + memcpy(diskname, imgName, 511); + } else { + strcpy((char *)diskname, (const char *)imgName); + } + + active = false; + hardDrive = isHardDisk; + if(!isHardDisk) { + Bitu i=0; + bool founddisk = false; + while (DiskGeometryList[i].ksize!=0x0) { + if (DiskGeometryList[i].ksize==imgSizeK) { + founddisk = true; + active = true; + floppytype = i; + heads = DiskGeometryList[i].headscyl; + cylinders = DiskGeometryList[i].cylcount; + sectors = DiskGeometryList[i].secttrack; + break; + } + i++; + } + if(!founddisk) { + active = false; + } + } +} + +void imageDisk::Set_Geometry(Bit32u setHeads, Bit32u setCyl, Bit32u setSect, Bit32u setSectSize) { + heads = setHeads; + cylinders = setCyl; + sectors = setSect; + sector_size = setSectSize; + active = true; +} + +void imageDisk::Get_Geometry(Bit32u * getHeads, Bit32u *getCyl, Bit32u *getSect, Bit32u *getSectSize) { + *getHeads = heads; + *getCyl = cylinders; + *getSect = sectors; + *getSectSize = sector_size; +} + +Bit8u imageDisk::GetBiosType(void) { + if(!hardDrive) { + return DiskGeometryList[floppytype].biosval; + } else return 0; +} + +Bit32u imageDisk::getSectSize(void) { + return sector_size; +} + +static Bitu GetDosDriveNumber(Bitu biosNum) { + switch(biosNum) { case 0x0: - reg_ah=0x00; + return 0x0; + case 0x1: + return 0x1; + case 0x80: + return 0x2; + case 0x81: + return 0x3; + case 0x82: + return 0x4; + case 0x83: + return 0x5; + default: + return 0x7f; + } +} + +static bool driveInactive(Bitu driveNum) { + if(driveNum>=(2 + MAX_HDD_IMAGES)) { + LOG_MSG("Disk %d non-existant", driveNum); + last_status = 0x01; + CALLBACK_SCF(true); + return true; + } + if(imageDiskList[driveNum] == NULL) { + LOG_MSG("Disk %d not active", driveNum); + last_status = 0x01; + CALLBACK_SCF(true); + return true; + } + if(!imageDiskList[driveNum]->active) { + LOG_MSG("Disk %d not active", driveNum); + last_status = 0x01; + CALLBACK_SCF(true); + return true; + } + return false; +} + + +static Bitu INT13_DiskHandler(void) { + Bit16u segat, bufptr; + Bit8u sectbuf[512]; + Bitu drivenum; + Bits readcnt; + int i,t; + last_drive = reg_dl; + drivenum = GetDosDriveNumber(reg_dl); + //drivenum = 0; + //LOG_MSG("INT13: Function %x called on drive %x (dos drive %d)", reg_ah, reg_dl, drivenum); + switch(reg_ah) { + case 0x0: /* Reset disk */ + if(driveInactive(drivenum)) return CBRET_NONE; + last_status = 0x00; CALLBACK_SCF(false); - LOG(LOG_BIOS,LOG_NORMAL)("reset disk return succesfull"); break; - case 0x02: /* Read Disk Sectors */ - LOG(LOG_BIOS,LOG_NORMAL)("INT13:02:Read Disk Sectors not supported failing"); - reg_ah=0x80; + case 0x1: /* Get status of last operation */ + + if(last_status != 0x00) { + reg_ah = last_status; CALLBACK_SCF(true); + } else { + reg_ah = 0x00; + CALLBACK_SCF(false); + } break; - case 0x04: - if(Drives[reg_dl]!=NULL) { - reg_ah=0; + case 0x2: /* Read sectors */ + if(driveInactive(drivenum)) { + reg_ah = 0xff; + CALLBACK_SCF(true); + return CBRET_NONE; + } + + segat = SegValue(es); + bufptr = reg_bx; + for(i=0;iRead_Sector((Bit32u)reg_dh, (Bit32u)(reg_ch | ((reg_cl & 0xc0)<< 2)), (Bit32u)((reg_cl & 63)+i), sectbuf); + if((last_status != 0x00) || (killRead)) { + LOG_MSG("Error in disk read"); + killRead = false; + reg_ah = 0x04; + CALLBACK_SCF(true); + return CBRET_NONE; + } + for(t=0;t<512;t++) { + real_writeb(segat,bufptr,sectbuf[t]); + bufptr++; + } + } + reg_ah = 0x00; CALLBACK_SCF(false); - } - else{ - reg_ah=0x80; - CALLBACK_SCF(true); - } - LOG(LOG_BIOS,LOG_NORMAL)("INT 13:04 Verify sector used on %d, with result %d",reg_dl,reg_ah); - break; - - case 0x08: /* Get Drive Parameters */ - LOG(LOG_BIOS,LOG_NORMAL)("INT13:08:Get Drive parameters not supported failing"); - reg_ah=0xff; - CALLBACK_SCF(true); break; - case 0xff: + case 0x3: /* Write sectors */ + + if(driveInactive(drivenum)) { + reg_ah = 0xff; + CALLBACK_SCF(true); + return CBRET_NONE; + } + + + bufptr = reg_bx; + for(i=0;igetSectSize();t++) { + sectbuf[t] = real_readb(SegValue(es),bufptr); + bufptr++; + } + + last_status = imageDiskList[drivenum]->Write_Sector((Bit32u)reg_dh, (Bit32u)(reg_ch | ((reg_cl & 0xc0) << 2)), (Bit32u)((reg_cl & 63) + i), §buf[0]); + if(last_status != 0x00) { + CALLBACK_SCF(true); + return CBRET_NONE; + } + } + CALLBACK_SCF(false); + break; + case 0x04: /* Verify sectors */ + if(driveInactive(drivenum)) return CBRET_NONE; + + /* TODO: Finish coding this section */ + /* + segat = SegValue(es); + bufptr = reg_bx; + for(i=0;iRead_Sector((Bit32u)reg_dh, (Bit32u)(reg_ch | ((reg_cl & 0xc0)<< 2)), (Bit32u)((reg_cl & 63)+i), sectbuf); + if(last_status != 0x00) { + LOG_MSG("Error in disk read"); + CALLBACK_SCF(true); + return CBRET_NONE; + } + for(t=0;t<512;t++) { + real_writeb(segat,bufptr,sectbuf[t]); + bufptr++; + } + }*/ + reg_ah = 0x00; + //reg_al = 0x10; /* CRC verify failed */ + reg_al = 0x00; /* CRC verify succeeded */ + CALLBACK_SCF(false); + + break; + case 0x08: /* Get drive parameters */ + if(driveInactive(drivenum)) { + last_status = 0x07; + reg_ah = last_status; + CALLBACK_SCF(true); + return CBRET_NONE; + } + reg_ax = 0x00; + reg_bl = imageDiskList[drivenum]->GetBiosType(); + Bit32u tmpheads, tmpcyl, tmpsect, tmpsize; + imageDiskList[drivenum]->Get_Geometry(&tmpheads, &tmpcyl, &tmpsect, &tmpsize); + reg_ch = tmpcyl; + reg_cl = tmpsect; + reg_dh = tmpheads-1; + last_status = 0x00; + reg_dl = 0; + if(imageDiskList[2] != NULL) reg_dl++; + if(imageDiskList[3] != NULL) reg_dl++; + CALLBACK_SCF(false); + break; + case 0x11: /* Recalibrate drive */ + reg_ah = 0x00; + CALLBACK_SCF(false); + break; + case 0x17: /* Set disk type for format */ + /* Pirates! needs this to load */ + killRead = true; + reg_ah = 0x00; + CALLBACK_SCF(false); + break; default: - LOG(LOG_BIOS,LOG_ERROR)("Illegal int 13h call %2X Fail it",reg_ah); + LOG_MSG("INT13: Function %x called on drive %x (dos drive %d)", reg_ah, reg_dl, drivenum); reg_ah=0xff; CALLBACK_SCF(true); } return CBRET_NONE; } + void BIOS_SetupDisks(void) { /* TODO Start the time correctly */ call_int13=CALLBACK_Allocate(); - CALLBACK_Setup(call_int13,&INT13_SmallHandler,CB_IRET); + //CALLBACK_Setup(call_int13,&INT13_SmallHandler,CB_IRET); + CALLBACK_Setup(call_int13,&INT13_DiskHandler,CB_IRET); RealSetVec(0x13,CALLBACK_RealPointer(call_int13)); -/* Init the Disk Tables */ - last_status=0; + int i; + for(i=0;i<4;i++) { + imageDiskList[i] = NULL; + } + + for(i=0;i Date: Sat, 3 Apr 2004 19:35:34 +0000 Subject: [PATCH 1676/4131] New io handler functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1758 --- include/inout.h | 61 ++++++------ include/serialport.h | 8 +- src/hardware/adlib.cpp | 22 ++--- src/hardware/cmos.cpp | 19 ++-- src/hardware/disney.cpp | 16 +--- src/hardware/dma.cpp | 47 +++++---- src/hardware/gameblaster.cpp | 7 +- src/hardware/iohandler.cpp | 178 ++++++++++++++--------------------- src/hardware/joystick.cpp | 8 +- src/hardware/keyboard.cpp | 26 ++--- src/hardware/memory.cpp | 8 +- src/hardware/mpu401.cpp | 20 ++-- src/hardware/pic.cpp | 26 ++--- src/hardware/sblaster.cpp | 8 +- src/hardware/tandy_sound.cpp | 4 +- src/hardware/timer.cpp | 20 ++-- src/hardware/vga_attr.cpp | 8 +- src/hardware/vga_crtc.cpp | 8 +- src/hardware/vga_dac.cpp | 28 +++--- src/hardware/vga_gfx.cpp | 16 ++-- src/hardware/vga_misc.cpp | 67 ++++++------- src/hardware/vga_other.cpp | 55 ++++++----- src/hardware/vga_seq.cpp | 16 ++-- 23 files changed, 309 insertions(+), 367 deletions(-) diff --git a/include/inout.h b/include/inout.h index f4b7c51c..717fdbe1 100644 --- a/include/inout.h +++ b/include/inout.h @@ -16,30 +16,44 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -typedef Bit8u (IO_ReadBHandler)(Bit32u port); -typedef Bit16u (IO_ReadWHandler)(Bit32u port); -typedef Bit32u (IO_ReadDHandler)(Bit32u port); -typedef void (IO_WriteBHandler)(Bit32u port,Bit8u value); -typedef void (IO_WriteWHandler)(Bit32u port,Bit16u value); -typedef void (IO_WriteDHandler)(Bit32u port,Bit32u value); +#define IO_MAX (64*1024+3) -void IO_RegisterReadBHandler(Bitu port,IO_ReadBHandler * handler); -void IO_RegisterReadWHandler(Bitu port,IO_ReadWHandler * handler); -void IO_RegisterReadDHandler(Bitu port,IO_ReadDHandler * handler); +#define IO_MB 0x1 +#define IO_MW 0x2 +#define IO_MD 0x4 +#define IO_MA (IO_MB | IO_MW | IO_MD ) -void IO_RegisterWriteBHandler(Bitu port,IO_WriteBHandler * handler); -void IO_RegisterWriteWHandler(Bitu port,IO_WriteWHandler * handler); -void IO_RegisterWriteDHandler(Bitu port,IO_WriteDHandler * handler); +typedef Bitu IO_ReadHandler(Bitu port,Bitu iolen); +typedef void IO_WriteHandler(Bitu port,Bitu val,Bitu iolen); -void IO_FreeReadHandler(Bitu port); -void IO_FreeWriteHandler(Bitu port); +extern IO_WriteHandler * io_writehandlers[3][IO_MAX]; +extern IO_ReadHandler * io_readhandlers[3][IO_MAX]; -void IO_WriteB(Bitu port,Bit8u val); -Bit8u IO_ReadB(Bitu port); -void IO_WriteW(Bitu port,Bit16u val); -Bit16u IO_ReadW(Bitu port); -void IO_WriteD(Bitu port,Bit32u val); -Bit32u IO_ReadD(Bitu port); +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=0); +void IO_FreeWriteHandler(Bitu port,Bitu mask,Bitu range=0); + +INLINE void IO_WriteB(Bitu port,Bitu val) { + io_writehandlers[0][port](port,val,1); +}; +INLINE void IO_WriteW(Bitu port,Bitu val) { + io_writehandlers[1][port](port,val,2); +}; +INLINE void IO_WriteD(Bitu port,Bitu val) { + io_writehandlers[2][port](port,val,4); +}; + +INLINE Bitu IO_ReadB(Bitu port) { + return io_readhandlers[0][port](port,1); +} +INLINE Bitu IO_ReadW(Bitu port) { + return io_readhandlers[1][port](port,2); +} +INLINE Bitu IO_ReadD(Bitu port) { + return io_readhandlers[2][port](port,4); +} INLINE void IO_Write(Bitu port,Bit8u val) { IO_WriteB(port,val); @@ -48,11 +62,4 @@ INLINE Bit8u IO_Read(Bitu port){ return IO_ReadB(port); } -INLINE void IO_RegisterReadHandler(Bitu port,IO_ReadBHandler * handler,char * name) { - IO_RegisterReadBHandler(port,handler); -} -INLINE void IO_RegisterWriteHandler(Bitu port,IO_WriteBHandler * handler,char * name) { - IO_RegisterWriteBHandler(port,handler); -} - diff --git a/include/serialport.h b/include/serialport.h index 386e7607..78a3952e 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -50,11 +50,11 @@ public: virtual ~CSerial(); // External port functions for IOHandlers // - void write_port(Bit32u port, Bit8u val); - Bit8u read_port(Bit32u port); + void write_port(Bitu port, Bitu val); + Bitu read_port(Bitu port); - static void write_serial(Bit32u port,Bit8u val); - static Bit8u read_serial(Bit32u port); + static void write_serial(Bitu port,Bitu val,Bitu iolen); + static Bitu read_serial(Bitu port,Bitu iolen); void SetMCHandler(MControl_Handler * mcontrol); diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 74815639..d763aafb 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -113,7 +113,7 @@ static void OPL_CallBack(Bit8u *stream, Bit32u len) { } } -Bit8u OPL_Read(Bit32u port) { +static Bitu OPL_Read(Bitu port,Bitu iolen) { Bitu addr=port & 3; switch (opl.mode) { case OPL_opl2: @@ -126,7 +126,7 @@ Bit8u OPL_Read(Bit32u port) { return 0xff; } -void OPL_Write(Bit32u port,Bit8u val) { +void OPL_Write(Bitu port,Bitu val,Bitu iolen) { opl.last_used=PIC_Ticks; if (!opl.active) { opl.active=true; @@ -147,7 +147,6 @@ void OPL_Write(Bit32u port,Bit8u val) { } void OPL_Init(Section* sec,Bitu base,OPL_Mode oplmode,Bitu rate) { - Bitu i; Section_prop * section=static_cast(sec); if (OPL2::YM3812Init(2,OPL2_INTERNAL_FREQ,rate)) { E_Exit("Can't create OPL2 Emulator"); @@ -158,16 +157,13 @@ void OPL_Init(Section* sec,Bitu base,OPL_Mode oplmode,Bitu rate) { E_Exit("Can't create OPL3 Emulator"); }; THEOPL3::YMF262SetTimerHandler(0,THEOPL3::TimerHandler,0); - for (i=0;i<4;i++) { - IO_RegisterWriteHandler(0x388+i,OPL_Write,"OPL Write"); - IO_RegisterReadHandler(0x388+i,OPL_Read,"OPL read"); - IO_RegisterWriteHandler(base+i,OPL_Write,"OPL Write"); - IO_RegisterReadHandler(base+i,OPL_Read,"OPL read"); - } - IO_RegisterWriteHandler(base+8,OPL_Write,"OPL Write"); - IO_RegisterWriteHandler(base+9,OPL_Write,"OPL Write"); - IO_RegisterReadHandler(base+8,OPL_Read,"OPL read"); - IO_RegisterReadHandler(base+9,OPL_Read,"OPL read"); + IO_RegisterWriteHandler(0x388,OPL_Write,IO_MB,4); + IO_RegisterReadHandler(0x388,OPL_Read,IO_MB,4); + IO_RegisterWriteHandler(base,OPL_Write,IO_MB,4); + IO_RegisterReadHandler(base,OPL_Read,IO_MB,4); + + IO_RegisterWriteHandler(base+8,OPL_Write,IO_MB,2); + IO_RegisterReadHandler(base+8,OPL_Read,IO_MB,2); opl.active=false; diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 58096871..954e11b6 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -62,12 +62,12 @@ static void cmos_checktimer(void) { PIC_AddEvent(cmos_timerevent,cmos.timer.micro); } -void cmos_selreg(Bit32u port,Bit8u val) { +void cmos_selreg(Bitu port,Bitu val,Bitu iolen) { cmos.reg=val & 0x3f; cmos.nmi=(val & 0x80)>0; } -static void cmos_writereg(Bit32u port,Bit8u val) { +static void cmos_writereg(Bitu port,Bitu val,Bitu iolen) { switch (cmos.reg) { case 0x00: /* Seconds */ case 0x02: /* Minutes */ @@ -84,10 +84,9 @@ static void cmos_writereg(Bit32u port,Bit8u val) { LOG(LOG_BIOS,LOG_NORMAL)("CMOS:Trying to set alarm"); cmos.regs[cmos.reg]=val; break; - case 0x0a: /* Status reg A */ cmos.regs[cmos.reg]=val & 0x7f; - if (val & 0x70!=0x20) LOG(LOG_BIOS,LOG_ERROR)("CMOS Illegal 22 stage divider value"); + if ((val & 0x70)!=0x20) LOG(LOG_BIOS,LOG_ERROR)("CMOS Illegal 22 stage divider value"); cmos.timer.div=(val & 0xf); cmos_checktimer(); break; @@ -110,7 +109,7 @@ static void cmos_writereg(Bit32u port,Bit8u val) { #define MAKE_RETURN(_VAL) (cmos.bcd ? (((_VAL / 10) << 4) | (_VAL % 10)) : _VAL); -static Bit8u cmos_readreg(Bit32u port) { +static Bitu cmos_readreg(Bitu port,Bitu iolen) { if (cmos.reg>0x3f) { LOG(LOG_BIOS,LOG_ERROR)("CMOS:Read from illegal register %x",cmos.reg); return 0xff; @@ -189,14 +188,14 @@ void CMOS_SetRegister(Bitu regNr, Bit8u val) }; void CMOS_Init(Section* sec) { - IO_RegisterWriteHandler(0x70,cmos_selreg,"CMOS"); - IO_RegisterWriteHandler(0x71,cmos_writereg,"CMOS"); - IO_RegisterReadHandler(0x71,cmos_readreg,"CMOS"); + IO_RegisterWriteHandler(0x70,cmos_selreg,IO_MB); + IO_RegisterWriteHandler(0x71,cmos_writereg,IO_MB); + IO_RegisterReadHandler(0x71,cmos_readreg,IO_MB); cmos.timer.enabled=false; cmos.reg=0xa; - cmos_writereg(0x71,0x26); + cmos_writereg(0x71,0x26,1); cmos.reg=0xb; - cmos_writereg(0x71,0); + cmos_writereg(0x71,0,1); /* Fill in extended memory size */ Bitu exsize=(MEM_TotalPages()*4)-1024; cmos.regs[0x17]=(Bit8u)exsize; diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 4baf3e25..7247ad72 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -20,9 +20,7 @@ #include "dosbox.h" #include "inout.h" #include "mixer.h" -#include "dma.h" #include "pic.h" -#include "hardware.h" #include "setup.h" #include "programs.h" @@ -41,7 +39,7 @@ static struct { MIXER_Channel * chan; } disney; -static void disney_write(Bit32u port,Bit8u val) { +static void disney_write(Bitu port,Bitu val,Bitu iolen) { switch (port-DISNEY_BASE) { case 0: /* Data Port */ disney.data=val; @@ -62,8 +60,7 @@ static void disney_write(Bit32u port,Bit8u val) { } } -static Bit8u disney_read(Bit32u port) { - +static Bitu disney_read(Bitu port,Bitu iolen) { switch (port-DISNEY_BASE) { case 0: /* Data Port */ // LOG(LOG_MISC,LOG_NORMAL)("DISNEY:Read from data port"); @@ -103,13 +100,8 @@ void DISNEY_Init(Section* sec) { Section_prop * section=static_cast(sec); if(!section->Get_bool("disney")) return; - IO_RegisterWriteHandler(DISNEY_BASE,disney_write,"DISNEY"); - IO_RegisterWriteHandler(DISNEY_BASE+1,disney_write,"DISNEY"); - IO_RegisterWriteHandler(DISNEY_BASE+2,disney_write,"DISNEY"); - - IO_RegisterReadHandler(DISNEY_BASE,disney_read,"DISNEY"); - IO_RegisterReadHandler(DISNEY_BASE+1,disney_read,"DISNEY"); - IO_RegisterReadHandler(DISNEY_BASE+2,disney_read,"DISNEY"); + IO_RegisterWriteHandler(DISNEY_BASE,disney_write,IO_MB,3); + IO_RegisterReadHandler(DISNEY_BASE,disney_read,IO_MB,3); disney.chan=MIXER_AddChannel(&DISNEY_CallBack,7000,"DISNEY"); MIXER_SetMode(disney.chan,MIXER_8MONO); diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index cda40dd4..83cb6b90 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -127,7 +127,7 @@ static Bitu DMA_ReadControllerReg(DmaController * cont,Bitu reg,Bitu len) { } -static void DMA_Write_PortB(Bit32u port,Bit8u val) { +static void DMA_Write_Port(Bitu port,Bitu val,Bitu iolen) { if (port<0x10) { DMA_WriteControllerReg(DmaControllers[0],port,val,1); } else if (port>=0xc0 && port <=0xdf) { @@ -142,15 +142,11 @@ static void DMA_Write_PortB(Bit32u port,Bit8u val) { } } - -static void DMA_Write_PortW(Bit32u port,Bit16u val) { - LOG_MSG("Ahh 16bit write port %x val %x",port,val); -} -static Bit8u DMA_Read_PortB(Bit32u port) { +static Bitu DMA_Read_Port(Bitu port,Bitu iolen) { if (port<0x10) { - return DMA_ReadControllerReg(DmaControllers[0],port,1); + return DMA_ReadControllerReg(DmaControllers[0],port,iolen); } else if (port>=0xc0 && port <=0xdf) { - return DMA_ReadControllerReg(DmaControllers[1],(port-0xc0) >> 1,1); + return DMA_ReadControllerReg(DmaControllers[1],(port-0xc0) >> 1,iolen); } else switch (port) { case 0x81:return DmaChannels[2]->pagenum; case 0x82:return DmaChannels[3]->pagenum; @@ -159,6 +155,7 @@ static Bit8u DMA_Read_PortB(Bit32u port) { case 0x8a:return DmaChannels[7]->pagenum; case 0x8b:return DmaChannels[5]->pagenum; } + return 0; } DmaChannel::DmaChannel(Bit8u num, bool dma16) { @@ -244,27 +241,27 @@ void DMA_Init(Section* sec) { DmaChannels[i] = new DmaChannel(i,i>=4); } for (i=0;i<0x10;i++) { - IO_RegisterWriteBHandler(i,DMA_Write_PortB); - IO_RegisterWriteWHandler(i,DMA_Write_PortW); - IO_RegisterReadBHandler(i,DMA_Read_PortB); + Bitu mask=i<8 ? (IO_MB|IO_MW) : IO_MB; + IO_RegisterWriteHandler(i,DMA_Write_Port,mask); + IO_RegisterReadHandler(i,DMA_Read_Port,mask); if (machine==MCH_VGA) { - IO_RegisterWriteBHandler(0xc0+i*2,DMA_Write_PortB); - IO_RegisterReadBHandler(0xc0+i*2,DMA_Read_PortB); + IO_RegisterWriteHandler(0xc0+i*2,DMA_Write_Port,mask); + IO_RegisterReadHandler(0xc0+i*2,DMA_Read_Port,mask); } } - IO_RegisterWriteBHandler(0x81,DMA_Write_PortB); - IO_RegisterWriteBHandler(0x82,DMA_Write_PortB); - IO_RegisterWriteBHandler(0x83,DMA_Write_PortB); - IO_RegisterWriteBHandler(0x89,DMA_Write_PortB); - IO_RegisterWriteBHandler(0x8a,DMA_Write_PortB); - IO_RegisterWriteBHandler(0x8b,DMA_Write_PortB); + IO_RegisterWriteHandler(0x81,DMA_Write_Port,IO_MB); + IO_RegisterWriteHandler(0x82,DMA_Write_Port,IO_MB); + IO_RegisterWriteHandler(0x83,DMA_Write_Port,IO_MB); + IO_RegisterWriteHandler(0x89,DMA_Write_Port,IO_MB); + IO_RegisterWriteHandler(0x8a,DMA_Write_Port,IO_MB); + IO_RegisterWriteHandler(0x8b,DMA_Write_Port,IO_MB); - IO_RegisterReadBHandler(0x81,DMA_Read_PortB); - IO_RegisterReadBHandler(0x82,DMA_Read_PortB); - IO_RegisterReadBHandler(0x83,DMA_Read_PortB); - IO_RegisterReadBHandler(0x89,DMA_Read_PortB); - IO_RegisterReadBHandler(0x8a,DMA_Read_PortB); - IO_RegisterReadBHandler(0x8b,DMA_Read_PortB); + IO_RegisterReadHandler(0x81,DMA_Read_Port,IO_MB); + IO_RegisterReadHandler(0x82,DMA_Read_Port,IO_MB); + IO_RegisterReadHandler(0x83,DMA_Read_Port,IO_MB); + IO_RegisterReadHandler(0x89,DMA_Read_Port,IO_MB); + IO_RegisterReadHandler(0x8a,DMA_Read_Port,IO_MB); + IO_RegisterReadHandler(0x8b,DMA_Read_Port,IO_MB); } diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index a051a870..16ff8772 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -363,7 +363,7 @@ static void saa1099_write_port_w( int chip, int offset, int data ) } -static void write_cms(Bit32u port,Bit8u val) { +static void write_cms(Bitu port,Bitu val,Bitu iolen) { if (last_command + 100 < PIC_Ticks) MIXER_Enable(cms_chan,true); last_command = PIC_Ticks; switch (port) { @@ -424,10 +424,7 @@ static void write_cms(Bit32u port,Bit8u val) { Section_prop * section=static_cast(sec); sample_rate=rate; - IO_RegisterWriteHandler(base+0x0,write_cms,"CMS"); - IO_RegisterWriteHandler(base+0x1,write_cms,"CMS"); - IO_RegisterWriteHandler(base+0x2,write_cms,"CMS"); - IO_RegisterWriteHandler(base+0x3,write_cms,"CMS"); + IO_RegisterWriteHandler(base,write_cms,IO_MB,4); /* Register the Mixer CallBack */ diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 32e6e95c..229a0f47 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -19,130 +19,90 @@ #include "dosbox.h" #include "inout.h" -#define IO_MAX 1024 +IO_WriteHandler * io_writehandlers[3][IO_MAX]; +IO_ReadHandler * io_readhandlers[3][IO_MAX]; -static struct IO_Block { - IO_WriteBHandler * write_b[IO_MAX]; - IO_WriteWHandler * write_w[IO_MAX]; - IO_WriteDHandler * write_d[IO_MAX]; - - IO_ReadBHandler * read_b[IO_MAX]; - IO_ReadWHandler * read_w[IO_MAX]; - IO_ReadDHandler * read_d[IO_MAX]; -} io; - -void IO_WriteB(Bitu port,Bit8u val) { - if (port> 0) & 0xff,1); + io_writehandlers[0][port+1](port+1,(val >> 8) & 0xff,1); + break; + case 4: + io_writehandlers[1][port+0](port+0,(val >> 0 ) & 0xffff,2); + io_writehandlers[1][port+2](port+2,(val >> 16) & 0xffff,2); + break; + } } -static Bit8u IO_ReadDefaultB(Bit32u port) { - LOG(LOG_IO,LOG_WARN)("Reading from undefined port %04X",port); - io.read_b[port]=IO_ReadBBlocked; - return 0xff; +void IO_RegisterReadHandler(Bitu port,IO_ReadHandler * handler,Bitu mask,Bitu range) { + while (range--) { + if (mask&IO_MB) io_readhandlers[0][port]=handler; + if (mask&IO_MW) io_readhandlers[1][port]=handler; + if (mask&IO_MD) io_readhandlers[2][port]=handler; + port++; + } } -static Bit16u IO_ReadDefaultW(Bit32u port) { - return io.read_b[port](port) | (io.read_b[port+1](port+1) << 8); -} -static Bit32u IO_ReadDefaultD(Bit32u port) { - return io.read_b[port](port) | (io.read_b[port+1](port+1) << 8) | - (io.read_b[port+2](port+2) << 16) | (io.read_b[port+3](port+3) << 24); +void IO_RegisterWriteHandler(Bitu port,IO_WriteHandler * handler,Bitu mask,Bitu range) { + while (range--) { + if (mask&IO_MB) io_writehandlers[0][port]=handler; + if (mask&IO_MW) io_writehandlers[1][port]=handler; + if (mask&IO_MD) io_writehandlers[2][port]=handler; + port++; + } } -void IO_WriteDefaultB(Bit32u port,Bit8u val) { - LOG(LOG_IO,LOG_WARN)("Writing %02X to undefined port %04X",static_cast(val),port); - io.write_b[port]=IO_WriteBBlocked; -} -void IO_WriteDefaultW(Bit32u port,Bit16u val) { - io.write_b[port](port,(Bit8u)val); - io.write_b[port+1](port+1,(Bit8u)(val>>8)); -} -void IO_WriteDefaultD(Bit32u port,Bit32u val) { - io.write_b[port](port,(Bit8u)val); - io.write_b[port+1](port+1,(Bit8u)(val>>8)); - io.write_b[port+2](port+2,(Bit8u)(val>>16)); - io.write_b[port+3](port+3,(Bit8u)(val>>24)); +void IO_FreeReadHandler(Bitu port,Bitu mask,Bitu range) { + while (range--) { + if (mask&IO_MB) io_readhandlers[0][port]=IO_ReadDefault; + if (mask&IO_MW) io_readhandlers[1][port]=IO_ReadDefault; + if (mask&IO_MD) io_readhandlers[2][port]=IO_ReadDefault; + port++; + } } -void IO_RegisterReadBHandler(Bitu port,IO_ReadBHandler * handler) { - if (port>=IO_MAX) return; - io.read_b[port]=handler; -} -void IO_RegisterReadWHandler(Bitu port,IO_ReadWHandler * handler) { - if (port>=IO_MAX) return; - io.read_w[port]=handler; -} -void IO_RegisterReadDHandler(Bitu port,IO_ReadDHandler * handler) { - if (port>=IO_MAX) return; - io.read_d[port]=handler; -} -void IO_RegisterWriteBHandler(Bitu port,IO_WriteBHandler * handler) { - if (port>=IO_MAX) return; - io.write_b[port]=handler; -} -void IO_RegisterWriteWHandler(Bitu port,IO_WriteWHandler * handler) { - if (port>=IO_MAX) return; - io.write_w[port]=handler; -} -void IO_RegisterWriteDHandler(Bitu port,IO_WriteDHandler * handler) { - if (port>=IO_MAX) return; - io.write_d[port]=handler; -} - - -void IO_FreeReadHandler(Bitu port) { - if (port>=IO_MAX) return; - io.read_b[port]=IO_ReadDefaultB; - io.read_w[port]=IO_ReadDefaultW; - io.read_d[port]=IO_ReadDefaultD; -} -void IO_FreeWriteHandler(Bitu port) { - if (port>=IO_MAX) return; - io.write_b[port]=IO_WriteDefaultB; - io.write_w[port]=IO_WriteDefaultW; - io.write_d[port]=IO_WriteDefaultD; -} - -void IO_Init(Section * sect) { - for (Bitu i=0;i #include "dosbox.h" @@ -147,7 +147,7 @@ void KEYBOARD_ReadKey(Bitu & scancode,Bitu & ascii,Bitu & mod) { } } -static Bit8u read_p60(Bit32u port) { +static Bitu read_p60(Bitu port,Bitu iolen) { keyb.key_on_60 = false; switch (keyb.buf.state) { case STATE_NORMAL: @@ -168,7 +168,7 @@ static Bit8u read_p60(Bit32u port) { return 0; } -static void write_p60(Bit32u port,Bit8u val) { +static void write_p60(Bitu port,Bitu val,Bitu iolen) { switch (keyb.command) { case CMD_NONE: /* None */ KEYBOARD_ClrBuffer(); @@ -217,13 +217,13 @@ static void write_p60(Bit32u port,Bit8u val) { } } -static Bit8u read_p61(Bit32u port) { +static Bitu read_p61(Bitu port,Bitu iolen) { port_61_data^=0x20; port_61_data^=0x10; return port_61_data; } -static void write_p61(Bit32u port,Bit8u val) { +static void write_p61(Bitu port,Bitu val,Bitu iolen) { /* if (val & 128) if (!keyb.read_active) KEYBOARD_ReadBuffer(); Keys should get acknowledged just by reading 0x60. @@ -233,7 +233,7 @@ static void write_p61(Bit32u port,Bit8u val) { port_61_data=val; } -static void write_p64(Bit32u port,Bit8u val) { +static void write_p64(Bitu port,Bitu val,Bitu iolen) { switch (val) { case 0xae: /* Activate keyboard */ keyb.active=true; @@ -261,7 +261,7 @@ static void write_p64(Bit32u port,Bit8u val) { } } -static Bit8u read_p64(Bit32u port) { +static Bitu read_p64(Bitu port,Bitu iolen) { // Bit8u status= 0x1c | ((keyb.buf.used ||keyb.key_on_60)? 0x1 : 0x0); // Old one. Digitracker 2 doesn't like this. key_on_60 is much more advanged. Bit8u status= 0x1c | (keyb.key_on_60? 0x1 : 0x0); @@ -420,12 +420,12 @@ void KEYBOARD_AddKey(KBD_KEYS keytype,Bitu unicode,Bitu mod,bool pressed) { } void KEYBOARD_Init(Section* sec) { - IO_RegisterWriteHandler(0x60,write_p60,"Keyboard"); - IO_RegisterReadHandler(0x60,read_p60,"Keyboard"); - IO_RegisterWriteHandler(0x61,write_p61,"Keyboard"); - IO_RegisterReadHandler(0x61,read_p61,"Keyboard"); - IO_RegisterWriteHandler(0x64,write_p64,"Keyboard"); - IO_RegisterReadHandler(0x64,read_p64,"Keyboard"); + IO_RegisterWriteHandler(0x60,write_p60,IO_MB); + IO_RegisterReadHandler(0x60,read_p60,IO_MB); + IO_RegisterWriteHandler(0x61,write_p61,IO_MB); + IO_RegisterReadHandler(0x61,read_p61,IO_MB); + IO_RegisterWriteHandler(0x64,write_p64,IO_MB); + IO_RegisterReadHandler(0x64,read_p64,IO_MB); port_61_data=0; /* Direct Speaker control and output disabled */ // memset(&event_handlers,0,sizeof(event_handlers)); diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 03045ebe..49e5da46 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -512,14 +512,14 @@ void MEM_PhysWriteD(Bitu addr,Bit32u val) { } -static void write_p92(Bit32u port,Bit8u val) { +static void write_p92(Bitu port,Bitu val,Bitu iolen) { // Bit 0 = system reset (switch back to real mode) if (val&1) E_Exit("XMS: CPU reset via port 0x92 not supported."); memory.a20.controlport = val & ~2; MEM_A20_Enable((val & 2)>0); } -static Bit8u read_p92(Bit32u port) { +static Bitu read_p92(Bitu port,Bitu iolen) { return memory.a20.controlport | (memory.a20.enabled ? 0x02 : 0); } @@ -589,8 +589,8 @@ void MEM_Init(Section * sec) { /* Reset some links */ memory.links.used=0; // A20 Line - PS/2 system control port A - IO_RegisterWriteHandler(0x92,write_p92,"Control Port"); - IO_RegisterReadHandler(0x92,read_p92,"Control Port"); + IO_RegisterWriteHandler(0x92,write_p92,IO_MB); + IO_RegisterReadHandler(0x92,read_p92,IO_MB); MEM_A20_Enable(false); /* shutdown function */ sec->AddDestroyFunction(&MEM_ShutDown); diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 1c3662b0..795a102b 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -214,13 +214,13 @@ static void ClrQueue(void) { mpu.queue_pos=0; } -static Bit8u MPU401_ReadStatus(Bit32u port) { +static Bitu MPU401_ReadStatus(Bitu port,Bitu iolen) { Bit8u ret=0x3f; /* Bits 6 and 7 clear */ if (!mpu.queue_used) ret|=0x80; return ret; } -static void MPU401_WriteCommand(Bit32u port,Bit8u val) { +static void MPU401_WriteCommand(Bitu port,Bitu val,Bitu iolen) { LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Command %x",val); if (val && val<=0x2f) { switch (val&3) { @@ -386,7 +386,7 @@ static void MPU401_WriteCommand(Bit32u port,Bit8u val) { QueueByte(MSG_CMD_ACK); } -static Bit8u MPU401_ReadData(Bit32u port) { +static Bitu MPU401_ReadData(Bitu port,Bitu iolen) { Bit8u ret=MSG_CMD_ACK; if (mpu.queue_used) { ret=mpu.queue[mpu.queue_pos]; @@ -409,7 +409,7 @@ static Bit8u MPU401_ReadData(Bit32u port) { return ret; } -static void MPU401_WriteData(Bit32u port,Bit8u val) { +static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) { if (mpu.mode==M_UART) {MIDI_RawOutByte(val);return;} if (mpu.state.command_byte) MPU401_EOIHandler(); /* S101, Time Quest */ switch (mpu.state.command_byte) { @@ -613,8 +613,8 @@ static void UpdateTrack(Bit8u chan) { static void UpdateConductor(void) { if (mpu.condbuf.type!=OVERFLOW) { - MPU401_WriteCommand(0x331,mpu.condbuf.value[0]); - if (mpu.state.command_byte) MPU401_WriteData(0x330,mpu.condbuf.value[1]); + MPU401_WriteCommand(0x331,mpu.condbuf.value[0],1); + if (mpu.state.command_byte) MPU401_WriteData(0x330,mpu.condbuf.value[1],1); } mpu.condbuf.vlength=0; mpu.condbuf.type=OVERFLOW; @@ -727,10 +727,10 @@ void MPU401_Init(Section* sec) { if (!MIDI_Available()) return; - IO_RegisterWriteHandler(0x330,&MPU401_WriteData,"MPU401"); - IO_RegisterWriteHandler(0x331,&MPU401_WriteCommand,"MPU401"); - IO_RegisterReadHandler(0x330,&MPU401_ReadData,"MPU401"); - IO_RegisterReadHandler(0x331,&MPU401_ReadStatus,"MPU401"); + IO_RegisterWriteHandler(0x330,&MPU401_WriteData,IO_MB); + IO_RegisterWriteHandler(0x331,&MPU401_WriteCommand,IO_MB); + IO_RegisterReadHandler(0x330,&MPU401_ReadData,IO_MB); + IO_RegisterReadHandler(0x331,&MPU401_ReadStatus,IO_MB); mpu.queue_used=0; mpu.queue_pos=0; diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 43895d2c..65ce55c9 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.19 2004-03-10 13:53:40 qbix79 Exp $ */ +/* $Id: pic.cpp,v 1.20 2004-04-03 19:34:10 harekiet Exp $ */ #include @@ -69,7 +69,7 @@ static struct { PICEntry * next_entry; } pic; -static void write_command(Bit32u port,Bit8u val) { +static void write_command(Bitu port,Bitu val,Bitu iolen) { PIC_Controller * pic=&pics[port==0x20 ? 0 : 1]; Bitu irq_base=port==0x20 ? 0 : 8; Bitu i; @@ -125,7 +125,7 @@ static void write_command(Bit32u port,Bit8u val) { } } -static void write_data(Bit32u port,Bit8u val) { +static void write_data(Bitu port,Bitu val,Bitu iolen) { PIC_Controller * pic=&pics[port==0x21 ? 0 : 1]; Bitu irq_base=(port==0x21) ? 0 : 8; Bitu i; @@ -175,7 +175,7 @@ static void write_data(Bit32u port,Bit8u val) { } -static Bit8u read_command(Bit32u port) { +static Bitu read_command(Bitu port,Bitu iolen) { PIC_Controller * pic=&pics[port==0x20 ? 0 : 1]; Bitu irq_base=(port==0x20) ? 0 : 8; Bitu i;Bit8u ret=0;Bit8u b=1; @@ -193,7 +193,7 @@ static Bit8u read_command(Bit32u port) { return ret; } -static Bit8u read_data(Bit32u port) { +static Bitu read_data(Bitu port,Bitu iolen) { PIC_Controller * pic=&pics[port==0x21 ? 0 : 1]; Bitu irq_base=(port==0x21) ? 0 : 8; Bitu i;Bit8u ret=0;Bit8u b=1; @@ -460,14 +460,14 @@ void PIC_Init(Section* sec) { irqs[1].masked=false; /* Enable Keyboard IRQ */ irqs[8].masked=false; /* Enable RTC IRQ */ /* irqs[12].masked=false; moved to mouse.cpp */ /* Enable Mouse IRQ */ - IO_RegisterReadHandler(0x20,read_command,"Master PIC Command"); - IO_RegisterReadHandler(0x21,read_data,"Master PIC Data"); - IO_RegisterWriteHandler(0x20,write_command,"Master PIC Command"); - IO_RegisterWriteHandler(0x21,write_data,"Master PIC Data"); - IO_RegisterReadHandler(0xa0,read_command,"Slave PIC Command"); - IO_RegisterReadHandler(0xa1,read_data,"Slave PIC Data"); - IO_RegisterWriteHandler(0xa0,write_command,"Slave PIC Command"); - IO_RegisterWriteHandler(0xa1,write_data,"Slave PIC Data"); + IO_RegisterReadHandler(0x20,read_command,IO_MB); + IO_RegisterReadHandler(0x21,read_data,IO_MB); + IO_RegisterWriteHandler(0x20,write_command,IO_MB); + IO_RegisterWriteHandler(0x21,write_data,IO_MB); + IO_RegisterReadHandler(0xa0,read_command,IO_MB); + IO_RegisterReadHandler(0xa1,read_data,IO_MB); + IO_RegisterWriteHandler(0xa0,write_command,IO_MB); + IO_RegisterWriteHandler(0xa1,write_data,IO_MB); /* Initialize the pic queue */ for (i=0;i(sec); if(!section->Get_bool("tandy")) return; - IO_RegisterWriteHandler(0xc0,SN76496Write,"Tandy Sound"); + IO_RegisterWriteHandler(0xc0,SN76496Write,IO_MB); Bit32u sample_rate = section->Get_int("tandyrate"); tandy.chan=MIXER_AddChannel(&SN76496Update,sample_rate,"TANDY"); diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 570d7cff..942bc6b6 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.22 2004-03-03 12:37:12 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.23 2004-04-03 19:34:10 harekiet Exp $ */ #include "dosbox.h" #include "inout.h" @@ -102,7 +102,7 @@ static void counter_latch(Bitu counter) { } -static void write_latch(Bit32u port,Bit8u val) { +static void write_latch(Bitu port,Bitu val,Bitu iolen) { Bitu counter=port-0x40; PIT_Block * p=&pit[counter]; if(p->bcd == true) BIN2BCD(p->write_latch); @@ -149,7 +149,7 @@ static void write_latch(Bit32u port,Bit8u val) { } } -static Bit8u read_latch(Bit32u port) { +static Bitu read_latch(Bitu port,Bitu iolen) { Bit32u counter=port-0x40; if (pit[counter].go_read_latch == true) counter_latch(counter); @@ -186,7 +186,7 @@ static Bit8u read_latch(Bit32u port) { return ret; } -static void write_p43(Bit32u port,Bit8u val) { +static void write_p43(Bitu port,Bitu val,Bitu iolen) { Bitu latch=(val >> 6) & 0x03; switch (latch) { case 0: @@ -219,12 +219,12 @@ static void write_p43(Bit32u port,Bit8u val) { void TIMER_Init(Section* sect) { - IO_RegisterWriteHandler(0x40,write_latch,"PIT Timer 0"); - IO_RegisterWriteHandler(0x42,write_latch,"PIT Timer 2"); - IO_RegisterWriteHandler(0x43,write_p43,"PIT Mode Control"); - IO_RegisterReadHandler(0x40,read_latch,"PIT Timer 0"); -// IO_RegisterReadHandler(0x41,read_p41,"PIT Timer 1"); - IO_RegisterReadHandler(0x42,read_latch,"PIT Timer 2"); + IO_RegisterWriteHandler(0x40,write_latch,IO_MB); + IO_RegisterWriteHandler(0x42,write_latch,IO_MB); + IO_RegisterWriteHandler(0x43,write_p43,IO_MB); + IO_RegisterReadHandler(0x40,read_latch,IO_MB); +// IO_RegisterReadHandler(0x41,read_p41,IO_MB); + IO_RegisterReadHandler(0x42,read_latch,IO_MB); /* Setup Timer 0 */ pit[0].cntr=0x10000; pit[0].write_state = 3; diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index b57e9ca4..e6a4545e 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -28,7 +28,7 @@ void VGA_ATTR_SetPalette(Bit8u index,Bit8u val) { VGA_DAC_CombineColor(index,val); } -void write_p3c0(Bit32u port,Bit8u val) { +void write_p3c0(Bitu port,Bitu val,Bitu iolen) { if (!vga.internal.attrindex) { attr(index)=val & 0x1F; vga.internal.attrindex=true; @@ -156,7 +156,7 @@ void write_p3c0(Bit32u port,Bit8u val) { } } -Bit8u read_p3c1(Bit32u port) { +Bitu read_p3c1(Bitu port,Bitu iolen) { vga.internal.attrindex=false; switch (attr(index)) { /* Palette */ @@ -188,8 +188,8 @@ Bit8u read_p3c1(Bit32u port) { void VGA_SetupAttr(void) { if (machine==MCH_VGA) { - IO_RegisterWriteHandler(0x3c0,write_p3c0,"VGA Attribute controller"); - IO_RegisterReadHandler(0x3c1,read_p3c1,"VGA Attribute Read"); + IO_RegisterWriteHandler(0x3c0,write_p3c0,IO_MB); + IO_RegisterReadHandler(0x3c1,read_p3c1,IO_MB); } } diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 615b6bab..2becbde4 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -24,15 +24,15 @@ #define crtc(blah) vga.crtc.blah -void write_p3d4_vga(Bit32u port,Bit8u val) { +void write_p3d4_vga(Bitu port,Bitu val,Bitu iolen) { crtc(index)=val; } -Bit8u read_p3d4_vga(Bit32u port) { +Bitu read_p3d4_vga(Bitu port,Bitu iolen) { return crtc(index); } -void write_p3d5_vga(Bit32u port,Bit8u val) { +void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen) { // if (crtc(index)>0x18) LOG_MSG("VGA CRCT write %X to reg %X",val,crtc(index)); switch(crtc(index)) { case 0x00: /* Horizontal Total Register */ @@ -509,7 +509,7 @@ void write_p3d5_vga(Bit32u port,Bit8u val) { } } -Bit8u read_p3d5_vga(Bit32u port) { +Bitu read_p3d5_vga(Bitu port,Bitu iolen) { // LOG_MSG("VGA CRCT read from reg %X",crtc(index)); switch(crtc(index)) { case 0x00: /* Horizontal Total Register */ diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index bddd699c..30f0ee14 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -51,36 +51,36 @@ Note: Each read or write of this register will cycle through first the enum {DAC_READ,DAC_WRITE}; -static void write_p3c6(Bit32u port,Bit8u val) { +static void write_p3c6(Bitu port,Bitu val,Bitu iolen) { if (val!=0xff) LOG(LOG_VGAGFX,LOG_NORMAL)("VGA:Pel Mask not 0xff"); vga.dac.pel_mask=val; } -static Bit8u read_p3c6(Bit32u port) { +static Bitu read_p3c6(Bitu port,Bitu iolen) { return vga.dac.pel_mask; } -static void write_p3c7(Bit32u port,Bit8u val) { +static void write_p3c7(Bitu port,Bitu val,Bitu iolen) { vga.dac.read_index=val; vga.dac.pel_index=0; vga.dac.state=DAC_READ; } -static Bit8u read_p3c7(Bit32u port) { +static Bitu read_p3c7(Bitu port,Bitu iolen) { if (vga.dac.state==DAC_READ) return 0x3; else return 0x0; } -static void write_p3c8(Bit32u port,Bit8u val) { +static void write_p3c8(Bitu port,Bitu val,Bitu iolen) { vga.dac.write_index=val; vga.dac.pel_index=0; vga.dac.state=DAC_WRITE; } -static void write_p3c9(Bit32u port,Bit8u val) { +static void write_p3c9(Bitu port,Bitu val,Bitu iolen) { val&=0x3f; switch (vga.dac.pel_index) { case 0: @@ -121,7 +121,7 @@ static void write_p3c9(Bit32u port,Bit8u val) { }; } -static Bit8u read_p3c9(Bit32u port) { +static Bitu read_p3c9(Bitu port,Bitu iolen) { Bit8u ret; switch (vga.dac.pel_index) { case 0: @@ -183,13 +183,13 @@ void VGA_SetupDAC(void) { vga.dac.write_index=0; if (machine==MCH_VGA) { /* Setup the DAC IO port Handlers */ - IO_RegisterWriteHandler(0x3c6,write_p3c6,"PEL Mask"); - IO_RegisterReadHandler(0x3c6,read_p3c6,"PEL Mask"); - IO_RegisterWriteHandler(0x3c7,write_p3c7,"PEL Read Mode"); - IO_RegisterReadHandler(0x3c7,read_p3c7,"PEL Status Mode"); - IO_RegisterWriteHandler(0x3c8,write_p3c8,"PEL Write Mode"); - IO_RegisterWriteHandler(0x3c9,write_p3c9,"PEL Data"); - IO_RegisterReadHandler(0x3c9,read_p3c9,"PEL Data"); + IO_RegisterWriteHandler(0x3c6,write_p3c6,IO_MB); + IO_RegisterReadHandler(0x3c6,read_p3c6,IO_MB); + IO_RegisterWriteHandler(0x3c7,write_p3c7,IO_MB); + IO_RegisterReadHandler(0x3c7,read_p3c7,IO_MB); + IO_RegisterWriteHandler(0x3c8,write_p3c8,IO_MB); + IO_RegisterWriteHandler(0x3c9,write_p3c9,IO_MB); + IO_RegisterReadHandler(0x3c9,read_p3c9,IO_MB); } }; diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index 3af56b43..1e3415ae 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -23,15 +23,15 @@ #define gfx(blah) vga.gfx.blah static bool index9warned=false; -static void write_p3ce(Bit32u port,Bit8u val) { +static void write_p3ce(Bitu port,Bitu val,Bitu iolen) { gfx(index)=val & 0x0f; } -static Bit8u read_p3ce(Bit32u port) { +static Bitu read_p3ce(Bitu port,Bitu iolen) { return gfx(index); } -static void write_p3cf(Bit32u port,Bit8u val) { +static void write_p3cf(Bitu port,Bitu val,Bitu iolen) { switch (gfx(index)) { case 0: /* Set/Reset Register */ gfx(set_reset)=val & 0x0f; @@ -184,7 +184,7 @@ static void write_p3cf(Bit32u port,Bit8u val) { } } -static Bit8u read_p3cf(Bit32u port) { +static Bitu read_p3cf(Bitu port,Bitu iolen) { switch (gfx(index)) { case 0: /* Set/Reset Register */ return gfx(set_reset); @@ -214,10 +214,10 @@ static Bit8u read_p3cf(Bit32u port) { void VGA_SetupGFX(void) { if (machine==MCH_VGA) { - IO_RegisterWriteHandler(0x3ce,write_p3ce,"VGA Graphics Index"); - IO_RegisterWriteHandler(0x3cf,write_p3cf,"VGA Graphics Data"); - IO_RegisterReadHandler(0x3ce,read_p3ce,"Vga Graphics Index"); - IO_RegisterReadHandler(0x3cf,read_p3cf,"Vga Graphics Data"); + IO_RegisterWriteHandler(0x3ce,write_p3ce,IO_MB); + IO_RegisterWriteHandler(0x3cf,write_p3cf,IO_MB); + IO_RegisterReadHandler(0x3ce,read_p3ce,IO_MB); + IO_RegisterReadHandler(0x3cf,read_p3cf,IO_MB); } } diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 012647ca..71e4968a 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -23,17 +23,12 @@ static Bit8u flip=0; -void write_p3d4_vga(Bit32u port,Bit8u val); -Bit8u read_p3d4_vga(Bit32u port); -void write_p3d5_vga(Bit32u port,Bit8u val); -Bit8u read_p3d5_vga(Bit32u port); +void write_p3d4_vga(Bitu port,Bitu val,Bitu iolen); +Bitu read_p3d4_vga(Bitu port,Bitu iolen); +void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen); +Bitu read_p3d5_vga(Bitu port,Bitu iolen); -void write_p3d4_cga(Bit32u port,Bit8u val); -Bit8u read_p3d4_cga(Bit32u port); -void write_p3d5_cga(Bit32u port,Bit8u val); -Bit8u read_p3d5_cga(Bit32u port); - -static Bit8u read_p3da(Bit32u port) { +static Bitu read_p3da(Bitu port,Bitu iolen) { vga.internal.attrindex=false; if (vga.config.retrace) { switch (machine) { @@ -54,32 +49,32 @@ static Bit8u read_p3da(Bit32u port) { } -static void write_p3c2(Bit32u port,Bit8u val) { +static void write_p3c2(Bitu port,Bitu val,Bitu iolen) { vga.misc_output=val; if (val & 0x1) { - IO_RegisterWriteHandler(0x3d4,write_p3d4_vga,"VGA:CRTC Index Select"); - IO_RegisterReadHandler(0x3d4,read_p3d4_vga,"VGA:CRTC Index Select"); - IO_RegisterWriteHandler(0x3d5,write_p3d5_vga,"VGA:CRTC Data Register"); - IO_RegisterReadHandler(0x3d5,read_p3d5_vga,"VGA:CRTC Data Register"); - IO_RegisterReadHandler(0x3da,read_p3da,"VGA Input Status 1"); + IO_RegisterWriteHandler(0x3d4,write_p3d4_vga,IO_MB); + IO_RegisterReadHandler(0x3d4,read_p3d4_vga,IO_MB); + IO_RegisterWriteHandler(0x3d5,write_p3d5_vga,IO_MB); + IO_RegisterReadHandler(0x3d5,read_p3d5_vga,IO_MB); + IO_RegisterReadHandler(0x3da,read_p3da,IO_MB); - IO_FreeWriteHandler(0x3b4); - IO_FreeReadHandler(0x3b4); - IO_FreeWriteHandler(0x3b5); - IO_FreeReadHandler(0x3b5); - IO_FreeReadHandler(0x3ba); + IO_FreeWriteHandler(0x3b4,IO_MB); + IO_FreeReadHandler(0x3b4,IO_MB); + IO_FreeWriteHandler(0x3b5,IO_MB); + IO_FreeReadHandler(0x3b5,IO_MB); + IO_FreeReadHandler(0x3ba,IO_MB); } else { - IO_RegisterWriteHandler(0x3b4,write_p3d4_vga,"VGA:CRTC Index Select"); - IO_RegisterReadHandler(0x3b4,read_p3d4_vga,"VGA:CRTC Index Select"); - IO_RegisterWriteHandler(0x3b5,write_p3d5_vga,"VGA:CRTC Data Register"); - IO_RegisterReadHandler(0x3b5,read_p3d5_vga,"VGA:CRTC Data Register"); - IO_RegisterReadHandler(0x3ba,read_p3da,"VGA Input Status 1"); + IO_RegisterWriteHandler(0x3b4,write_p3d4_vga,IO_MB); + IO_RegisterReadHandler(0x3b4,read_p3d4_vga,IO_MB); + IO_RegisterWriteHandler(0x3b5,write_p3d5_vga,IO_MB); + IO_RegisterReadHandler(0x3b5,read_p3d5_vga,IO_MB); + IO_RegisterReadHandler(0x3ba,read_p3da,IO_MB); - IO_FreeWriteHandler(0x3d4); - IO_FreeReadHandler(0x3d4); - IO_FreeWriteHandler(0x3d5); - IO_FreeReadHandler(0x3d5); - IO_FreeReadHandler(0x3da); + IO_FreeWriteHandler(0x3d4,IO_MB); + IO_FreeReadHandler(0x3d4,IO_MB); + IO_FreeWriteHandler(0x3d5,IO_MB); + IO_FreeReadHandler(0x3d5,IO_MB); + IO_FreeReadHandler(0x3da,IO_MB); } /* 0 If set Color Emulation. Base Address=3Dxh else Mono Emulation. Base Address=3Bxh. @@ -95,7 +90,7 @@ static void write_p3c2(Bit32u port,Bit8u val) { } -static Bit8u read_p3cc(Bit32u port) { +static Bitu read_p3cc(Bitu port,Bitu iolen) { return vga.misc_output; } @@ -103,12 +98,12 @@ static Bit8u read_p3cc(Bit32u port) { void VGA_SetupMisc(void) { if (machine==MCH_VGA) { - IO_RegisterWriteHandler(0x3c2,write_p3c2,"VGA Misc Output"); - IO_RegisterReadHandler(0x3cc,read_p3cc,"VGA Misc Output"); + IO_RegisterWriteHandler(0x3c2,write_p3c2,IO_MB); + IO_RegisterReadHandler(0x3cc,read_p3cc,IO_MB); } else if (machine==MCH_CGA || machine==MCH_TANDY) { - IO_RegisterReadHandler(0x3da,read_p3da,"VGA Input Status 1"); + IO_RegisterReadHandler(0x3da,read_p3da,IO_MB); } else if (machine==MCH_HERC) { - IO_RegisterReadHandler(0x3ba,read_p3da,"VGA Input Status 1"); + IO_RegisterReadHandler(0x3ba,read_p3da,IO_MB); } } diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index da3fe693..bf2a7444 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -21,15 +21,15 @@ #include "inout.h" #include "vga.h" -static void write_crtc_index_other(Bit32u port,Bit8u val) { +static void write_crtc_index_other(Bitu port,Bitu val,Bitu iolen) { vga.other.index=val; } -static Bit8u read_crtc_index_other(Bit32u port) { +static Bitu read_crtc_index_other(Bitu port,Bitu iolen) { return vga.other.index; } -static void write_crtc_data_other(Bit32u port,Bit8u val) { +static void write_crtc_data_other(Bitu port,Bitu val,Bitu iolen) { switch (vga.other.index) { case 0x00: //Horizontal total if (vga.other.htotal ^ val) VGA_StartResize(); @@ -84,7 +84,7 @@ static void write_crtc_data_other(Bit32u port,Bit8u val) { LOG_MSG("Write %X to illgal index %x",val,vga.other.index); } } -static Bit8u read_crtc_data_other(Bit32u port) { +static Bitu read_crtc_data_other(Bitu port,Bitu iolen) { switch (vga.other.index) { case 0x00: //Horizontal total return vga.other.htotal; @@ -115,6 +115,7 @@ static Bit8u read_crtc_data_other(Bit32u port) { default: LOG_MSG("Read from illgal index %x",vga.other.index); } + return (Bitu)-1; } static void write_color_select(Bit8u val) { @@ -140,7 +141,6 @@ static void write_color_select(Bit8u val) { } } break; - case M_CGA16: case M_TEXT: case M_TANDY16: break; @@ -153,11 +153,6 @@ static void write_mode_control(Bit8u val) { VGA_SetBlinking((val & 0x20)); if (val & 0x2) { if (val & 0x10) { - if (val & 0x8) { - VGA_SetMode(M_CGA16); //Video burst 16 160x200 color mode - } else { - VGA_SetMode(M_CGA2); - } } else VGA_SetMode(M_CGA4); write_color_select(vga.tandy.color_select); //Setup the correct palette } else { @@ -198,13 +193,17 @@ static void write_tandy_reg(Bit8u val) { } } -static void write_cga(Bit32u port,Bit8u val) { +static void write_cga(Bitu port,Bitu val,Bitu iolen) { switch (port) { case 0x3d8: vga.tandy.mode_control=val; if (vga.tandy.mode_control & 0x2) { if (vga.tandy.mode_control & 0x10) { - VGA_SetMode(M_TANDY2); + if (val & 0x8 && machine==MCH_CGA) { + VGA_SetMode(M_CGA16); //Video burst 16 160x200 color mode + } else { + VGA_SetMode(M_TANDY2); + } } else VGA_SetMode(M_TANDY4); write_color_select(vga.tandy.color_select); } else { @@ -217,7 +216,7 @@ static void write_cga(Bit32u port,Bit8u val) { } } -static void write_tandy(Bit32u port,Bit8u val) { +static void write_tandy(Bitu port,Bitu val,Bitu iolen) { switch (port) { case 0x3d8: vga.tandy.mode_control=val; @@ -240,7 +239,7 @@ static void write_tandy(Bit32u port,Bit8u val) { } } -static void write_hercules(Bit32u port,Bit8u val) { +static void write_hercules(Bitu port,Bitu val,Bitu iolen) { switch (port) { case 0x3b8: if (vga.herc.enable_bits & 1) { @@ -263,7 +262,7 @@ static void write_hercules(Bit32u port,Bit8u val) { } } -static Bit8u read_hercules(Bit32u port) { +static Bitu read_hercules(Bitu port,Bitu iolen) { LOG_MSG("read from Herc port %x",port); return 0; } @@ -280,28 +279,28 @@ void VGA_SetupOther(void) { for (i=0;i<256;i++) memcpy(&vga.draw.font[i*32],&int10_font_14[i*14],14); } if (machine==MCH_CGA) { - IO_RegisterWriteBHandler(0x3d8,write_cga); - IO_RegisterWriteBHandler(0x3d9,write_cga); + IO_RegisterWriteHandler(0x3d8,write_cga,IO_MB); + IO_RegisterWriteHandler(0x3d9,write_cga,IO_MB); } if (machine==MCH_HERC) { vga.herc.enable_bits=0; vga.herc.mode_control=0x8; - IO_RegisterWriteBHandler(0x3b8,write_hercules); - IO_RegisterWriteBHandler(0x3bf,write_hercules); + IO_RegisterWriteHandler(0x3b8,write_hercules,IO_MB); + IO_RegisterWriteHandler(0x3bf,write_hercules,IO_MB); } if (machine==MCH_TANDY) { - IO_RegisterWriteBHandler(0x3d8,write_tandy); - IO_RegisterWriteBHandler(0x3d9,write_tandy); - IO_RegisterWriteBHandler(0x3de,write_tandy); - IO_RegisterWriteBHandler(0x3df,write_tandy); - IO_RegisterWriteBHandler(0x3da,write_tandy); + IO_RegisterWriteHandler(0x3d8,write_tandy,IO_MB); + IO_RegisterWriteHandler(0x3d9,write_tandy,IO_MB); + IO_RegisterWriteHandler(0x3de,write_tandy,IO_MB); + IO_RegisterWriteHandler(0x3df,write_tandy,IO_MB); + IO_RegisterWriteHandler(0x3da,write_tandy,IO_MB); } if (machine==MCH_CGA || machine==MCH_HERC || machine==MCH_TANDY) { Bitu base=machine==MCH_HERC ? 0x3b4 : 0x3d4; - IO_RegisterWriteBHandler(base,write_crtc_index_other); - IO_RegisterWriteBHandler(base+1,write_crtc_data_other); - IO_RegisterReadBHandler(base,read_crtc_index_other); - IO_RegisterReadBHandler(base+1,read_crtc_data_other); + IO_RegisterWriteHandler(base,write_crtc_index_other,IO_MB); + IO_RegisterWriteHandler(base+1,write_crtc_data_other,IO_MB); + IO_RegisterReadHandler(base,read_crtc_index_other,IO_MB); + IO_RegisterReadHandler(base+1,read_crtc_data_other,IO_MB); } } diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 53b284a4..c8e5f0b2 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -22,15 +22,15 @@ #define seq(blah) vga.seq.blah -Bit8u read_p3c4(Bit32u port) { +Bitu read_p3c4(Bitu port,Bitu iolen) { return seq(index); } -void write_p3c4(Bit32u port,Bit8u val) { +void write_p3c4(Bitu port,Bitu val,Bitu iolen) { seq(index)=val; }; -void write_p3c5(Bit32u port,Bit8u val) { +void write_p3c5(Bitu port,Bitu val,Bitu iolen) { if (seq(index)>0x8 && vga.s3.pll.lock!=0x6) return; // LOG_MSG("SEQ WRITE reg %X val %X",seq(index),val); switch(seq(index)) { @@ -127,7 +127,7 @@ void write_p3c5(Bit32u port,Bit8u val) { }; -Bit8u read_p3c5(Bit32u port) { +Bitu read_p3c5(Bitu port,Bitu iolen) { // LOG_MSG("VGA:SEQ:Read from index %2X",seq(index)); if (seq(index)>0x8 && vga.s3.pll.lock!=0x6) return seq(index); switch(seq(index)) { @@ -168,10 +168,10 @@ Bit8u read_p3c5(Bit32u port) { void VGA_SetupSEQ(void) { if (machine==MCH_VGA) { - IO_RegisterWriteHandler(0x3c4,write_p3c4,"VGA:Sequencer Index"); - IO_RegisterWriteHandler(0x3c5,write_p3c5,"VGA:Sequencer Data"); - IO_RegisterReadHandler(0x3c4,read_p3c4,"VGA:Sequencer Index"); - IO_RegisterReadHandler(0x3c5,read_p3c5,"VGA:Sequencer Data"); + IO_RegisterWriteHandler(0x3c4,write_p3c4,IO_MB); + IO_RegisterWriteHandler(0x3c5,write_p3c5,IO_MB); + IO_RegisterReadHandler(0x3c4,read_p3c4,IO_MB); + IO_RegisterReadHandler(0x3c5,read_p3c5,IO_MB); } } From 9d9a964dd06cb5fd5e2f214e9f2d9f1c65f0a474 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 3 Apr 2004 19:46:00 +0000 Subject: [PATCH 1677/4131] New io handler functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1759 --- src/hardware/gus.cpp | 51 ++++++++++++++----------------------- src/hardware/serialport.cpp | 13 +++++----- 2 files changed, 25 insertions(+), 39 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index e4d19991..2184ba51 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -769,17 +769,7 @@ static void ExecuteGlobRegister(void) { } -static Bit16u read_gus16(Bit32u port) { - return ExecuteReadRegister(); -} - -static void write_gus16(Bit32u port,Bit16u val) { - myGUS.gRegData = val; - ExecuteGlobRegister(); -} - - -static Bit8u read_gus(Bit32u port) { +static Bitu read_gus(Bitu port,Bitu iolen) { switch(port - GUS_BASE) { case 0x206: @@ -828,7 +818,7 @@ static Bit8u read_gus(Bit32u port) { } -static void write_gus(Bit32u port,Bit8u val) { +static void write_gus(Bitu port,Bitu val,Bitu iolen) { switch(port - GUS_BASE) { case 0x200: myGUS.mixControl = val; @@ -1048,36 +1038,33 @@ void GUS_Init(Section* sec) { // GF1 Synthesizer - IO_RegisterWriteHandler(0x302 + GUS_BASE,write_gus,"GF1 Page Register"); - IO_RegisterReadHandler(0x302 + GUS_BASE,read_gus,"GF1 Page Register"); + IO_RegisterWriteHandler(0x302 + GUS_BASE,write_gus,IO_MB); + IO_RegisterReadHandler(0x302 + GUS_BASE,read_gus,IO_MB); - IO_RegisterWriteHandler(0x303 + GUS_BASE,write_gus,"GF1 Global Register Select"); - IO_RegisterReadHandler(0x303 + GUS_BASE,read_gus,"GF1 Global Register Select"); + IO_RegisterWriteHandler(0x303 + GUS_BASE,write_gus,IO_MB); + IO_RegisterReadHandler(0x303 + GUS_BASE,read_gus,IO_MB); - IO_RegisterWriteHandler(0x304 + GUS_BASE,write_gus,"GF1 Global Data Low Byte"); - IO_RegisterReadHandler(0x304 + GUS_BASE,read_gus,"GF1 Global Data Low Byte"); + IO_RegisterWriteHandler(0x304 + GUS_BASE,write_gus,IO_MB|IO_MW); + IO_RegisterReadHandler(0x304 + GUS_BASE,read_gus,IO_MB|IO_MW); - IO_RegisterWriteWHandler(0x304 + GUS_BASE,write_gus16); - IO_RegisterReadWHandler(0x304 + GUS_BASE,read_gus16); + IO_RegisterWriteHandler(0x305 + GUS_BASE,write_gus,IO_MB); + IO_RegisterReadHandler(0x305 + GUS_BASE,read_gus,IO_MB); - IO_RegisterWriteHandler(0x305 + GUS_BASE,write_gus,"GF1 Global Data High Byte"); - IO_RegisterReadHandler(0x305 + GUS_BASE,read_gus,"GF1 Global Data High Byte"); + IO_RegisterReadHandler(0x206 + GUS_BASE,read_gus,IO_MB); - IO_RegisterReadHandler(0x206 + GUS_BASE,read_gus,"GF1 IRQ Status Register"); + IO_RegisterWriteHandler(0x208 + GUS_BASE,write_gus,IO_MB); + IO_RegisterReadHandler(0x208 + GUS_BASE,read_gus,IO_MB); - IO_RegisterWriteHandler(0x208 + GUS_BASE,write_gus,"Timer Control Reg"); - IO_RegisterReadHandler(0x208 + GUS_BASE,read_gus,"Timer Control Reg"); + IO_RegisterWriteHandler(0x209 + GUS_BASE,write_gus,IO_MB); - IO_RegisterWriteHandler(0x209 + GUS_BASE,write_gus,"Timer Data IO"); - - IO_RegisterWriteHandler(0x307 + GUS_BASE,write_gus,"DRAM IO"); - IO_RegisterReadHandler(0x307 + GUS_BASE,read_gus,"DRAM IO"); + IO_RegisterWriteHandler(0x307 + GUS_BASE,write_gus,IO_MB); + IO_RegisterReadHandler(0x307 + GUS_BASE,read_gus,IO_MB); // Board Only - IO_RegisterWriteHandler(0x200 + GUS_BASE,write_gus,"Mix Control Register"); - IO_RegisterReadHandler(0x20A + GUS_BASE,read_gus,"GUS Undocumented"); - IO_RegisterWriteHandler(0x20B + GUS_BASE,write_gus,"IRQ/DMA Control Register"); + IO_RegisterWriteHandler(0x200 + GUS_BASE,write_gus,IO_MB); + IO_RegisterReadHandler(0x20A + GUS_BASE,read_gus,IO_MB); + IO_RegisterWriteHandler(0x20B + GUS_BASE,write_gus,IO_MB); PIC_RegisterIRQ(myGUS.irq1,0,"GUS"); PIC_RegisterIRQ(myGUS.irq2,0,"GUS"); diff --git a/src/hardware/serialport.cpp b/src/hardware/serialport.cpp index 3b7b55be..1baccaef 100644 --- a/src/hardware/serialport.cpp +++ b/src/hardware/serialport.cpp @@ -70,7 +70,7 @@ void CSerial::lowerint(INT_TYPES type){ } -void CSerial::write_port(Bit32u port, Bit8u val) { +void CSerial::write_port(Bitu port, Bitu val) { port-=base; // LOG_UART("Serial write %X val %x %c",port,val,val); @@ -152,7 +152,7 @@ void CSerial::write_port(Bit32u port, Bit8u val) { } } -void CSerial::write_serial(Bit32u port, Bit8u val) { +void CSerial::write_serial(Bitu port, Bitu val,Bitu iolen) { int i; for(i=0;i> 8, initdiv & 0x0f); for (i=8;i<=0xf;i++) { - - IO_RegisterWriteHandler(initbase+i,write_serial,"Serial Port"); - IO_RegisterReadHandler(initbase+i,read_serial,"Serial Port"); + IO_RegisterWriteHandler(initbase+i,write_serial,IO_MB); + IO_RegisterReadHandler(initbase+i,read_serial,IO_MB); } PIC_RegisterIRQ(irq,0,"SERIAL"); From 49861b6364026599397afbf15b724977abd62dc5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 3 Apr 2004 19:53:17 +0000 Subject: [PATCH 1678/4131] Fix some warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1760 --- src/ints/bios_disk.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 9bbc85f7..dfed6e05 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -59,7 +59,7 @@ void updateDPT(void) { real_writew(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0)),tmpcyl); real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+2,tmpheads); real_writew(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0x3,0); - real_writew(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0x5,-1); + real_writew(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0x5,(Bit16u)-1); real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0x7,0); real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0x8,(0xc0 | (((imageDiskList[2]->heads) > 8) << 3))); real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0x9,0); @@ -110,7 +110,7 @@ void swapInDisks(void) { } } -static void swapInNextDisk(void) { +void swapInNextDisk(void) { swapPosition++; if(diskSwap[swapPosition] == NULL) swapPosition = 0; swapInDisks(); From ac367177e7979070fe99cde028da7dd647aae480 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 3 Apr 2004 19:53:30 +0000 Subject: [PATCH 1679/4131] add drive_fat to makefile Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1761 --- src/dos/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/Makefile.am b/src/dos/Makefile.am index 7bd9b5af..3659aba3 100644 --- a/src/dos/Makefile.am +++ b/src/dos/Makefile.am @@ -4,6 +4,6 @@ noinst_LIBRARIES = libdos.a EXTRA_DIST = scsidefs.h wnaspi32.h libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioctl.cpp dos_memory.cpp \ dos_misc.cpp dos_classes.cpp dos_programs.cpp dos_tables.cpp \ - drives.cpp drives.h drive_virtual.cpp drive_local.cpp drive_cache.cpp \ + drives.cpp drives.h drive_virtual.cpp drive_local.cpp drive_cache.cpp drive_fat.cpp \ dev_con.h dos_mscdex.cpp \ cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp cdrom_ioctl_linux.cpp From f8410817099c56b9a17c0b269f1391c987974a5b Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Sat, 3 Apr 2004 19:59:07 +0000 Subject: [PATCH 1680/4131] Added FAT image access and DOS booter functionality Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1762 --- src/hardware/cmos.cpp | 82 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 954e11b6..031155f3 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -23,6 +23,7 @@ #include "pic.h" #include "inout.h" #include "mem.h" +#include "bios.h" static struct { Bit8u regs[0x40]; @@ -114,6 +115,8 @@ static Bitu cmos_readreg(Bitu port,Bitu iolen) { LOG(LOG_BIOS,LOG_ERROR)("CMOS:Read from illegal register %x",cmos.reg); return 0xff; } + Bitu drive_a, drive_b; + Bit8u hdparm; time_t curtime; struct tm *loctime; @@ -168,6 +171,85 @@ static Bitu cmos_readreg(Bitu port,Bitu iolen) { } return val; } + case 0x10: /* Floppy size */ + drive_a = 0; + drive_b = 0; + if(imageDiskList[0] != NULL) drive_a = imageDiskList[0]->GetBiosType(); + if(imageDiskList[1] != NULL) drive_b = imageDiskList[1]->GetBiosType(); + return ((drive_a << 4) | (drive_b)); + /* First harddrive info */ + case 0x12: + hdparm = 0; + if(imageDiskList[2] != NULL) hdparm |= 0xf; + if(imageDiskList[3] != NULL) hdparm |= 0xf0; + return hdparm; + case 0x19: + if(imageDiskList[2] != NULL) return 47; /* User defined type */ + return 0; + case 0x1b: + if(imageDiskList[2] != NULL) return (imageDiskList[2]->cylinders & 0xff); + return 0; + case 0x1c: + if(imageDiskList[2] != NULL) return ((imageDiskList[2]->cylinders & 0xff00)>>8); + return 0; + case 0x1d: + if(imageDiskList[2] != NULL) return (imageDiskList[2]->heads); + return 0; + case 0x1e: + if(imageDiskList[2] != NULL) return 0xff; + return 0; + case 0x1f: + if(imageDiskList[2] != NULL) return 0xff; + return 0; + case 0x20: + if(imageDiskList[2] != NULL) return (0xc0 | (((imageDiskList[2]->heads) > 8) << 3)); + return 0; + case 0x21: + if(imageDiskList[2] != NULL) return (imageDiskList[2]->cylinders & 0xff); + return 0; + case 0x22: + if(imageDiskList[2] != NULL) return ((imageDiskList[2]->cylinders & 0xff00)>>8); + return 0; + case 0x23: + if(imageDiskList[2] != NULL) return (imageDiskList[2]->sectors); + return 0; + /* Second harddrive info */ + case 0x1a: + if(imageDiskList[3] != NULL) return 47; /* User defined type */ + return 0; + case 0x24: + if(imageDiskList[3] != NULL) return (imageDiskList[3]->cylinders & 0xff); + return 0; + case 0x25: + if(imageDiskList[3] != NULL) return ((imageDiskList[3]->cylinders & 0xff00)>>8); + return 0; + case 0x26: + if(imageDiskList[3] != NULL) return (imageDiskList[3]->heads); + return 0; + case 0x27: + if(imageDiskList[3] != NULL) return 0xff; + return 0; + case 0x28: + if(imageDiskList[3] != NULL) return 0xff; + return 0; + case 0x29: + if(imageDiskList[3] != NULL) return (0xc0 | (((imageDiskList[3]->heads) > 8) << 3)); + return 0; + case 0x2a: + if(imageDiskList[3] != NULL) return (imageDiskList[3]->cylinders & 0xff); + return 0; + case 0x2b: + if(imageDiskList[3] != NULL) return ((imageDiskList[3]->cylinders & 0xff00)>>8); + return 0; + case 0x2c: + if(imageDiskList[3] != NULL) return (imageDiskList[3]->sectors); + return 0; + case 0x39: + return 0; + case 0x3a: + return 0; + + case 0x0b: /* Status register B */ case 0x0f: /* Shutdown status byte */ case 0x17: /* Extended memory in KB Low Byte */ From bc1ef408051e758bc29941c150bf9c39338371a7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 3 Apr 2004 20:04:38 +0000 Subject: [PATCH 1681/4131] Add/remove some new project files Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1763 --- visualc_net/dosbox.vcproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 48d971ce..c0b6522f 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -344,6 +344,9 @@ + + @@ -533,9 +536,6 @@ - - From a48880d4e49d05a0bdaf663cb54e044f5db4742a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 7 Apr 2004 09:36:59 +0000 Subject: [PATCH 1682/4131] set keyb.scheduled to false if the events are removed. Handle numlock scrollock capslock and insert. Produce proper codes for extended arrow keys. Make shift and capslock/numlock mutually exclusive. Handle the numeric keyboard. Update int 16 to handle the extended arrow keys. Implemented Alt-numeric. Made keyboard vitualazation under win3.x possible. Handle Some more keyboard flags. Fixed flags when 2 alts/ctrl were presed and one was released. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1764 --- src/hardware/keyboard.cpp | 7 +- src/ints/bios_keyboard.cpp | 223 ++++++++++++++++++++++++++----------- 2 files changed, 161 insertions(+), 69 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 4d0c8927..0e919b55 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.22 2004-04-03 19:35:34 harekiet Exp $ */ +/* $Id: keyboard.cpp,v 1.23 2004-04-07 09:36:59 qbix79 Exp $ */ #include #include "dosbox.h" @@ -83,6 +83,7 @@ void KEYBOARD_ClrBuffer(void) { keyb.scheduled=false; PIC_DeActivateIRQ(1); keyb.key_on_60=false; +/* maybe remove PIC_EVENTS */ } /* Read an entry from the keycode buffer */ @@ -122,7 +123,7 @@ void KEYBOARD_AddCode(Bit8u scancode,Bit8u ascii,Bitu mod,KeyStates state) { PIC_AddEvent(KEYBOARD_GetCode,KEYDELAY); } } - +/* Disabled as it's not used anymore. Left in here incase new code fails void KEYBOARD_ReadKey(Bitu & scancode,Bitu & ascii,Bitu & mod) { keyb.key_on_60=false; //else no new keys get scheduled :) switch (keyb.buf.state) { @@ -146,6 +147,7 @@ void KEYBOARD_ReadKey(Bitu & scancode,Bitu & ascii,Bitu & mod) { break; } } +*/ static Bitu read_p60(Bitu port,Bitu iolen) { keyb.key_on_60 = false; @@ -247,6 +249,7 @@ static void write_p64(Bitu port,Bitu val,Bitu iolen) { keyb.active=false; PIC_DeActivateIRQ(1); PIC_RemoveEvents(KEYBOARD_GetCode); + keyb.scheduled=false; LOG(LOG_KEYBOARD,LOG_NORMAL)("De-Activated"); break; case 0xd0: /* Outport on buffer */ diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 09aa5cd1..4b52b6e5 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -27,7 +27,6 @@ static Bitu call_int16,call_irq1; - /* Nice table from BOCHS i should feel bad for ripping this */ #define none 0 #define MAX_SCAN_CODE 0x53 @@ -108,18 +107,18 @@ static struct { { 0x4400, 0x5d00, 0x6700, 0x7100 }, /* F10 */ { none, none, none, none }, /* Num Lock */ { none, none, none, none }, /* Scroll Lock */ - { 0x4700, 0x4737, 0x7700, none }, /* 7 Home */ - { 0x4800, 0x4838, none, none }, /* 8 UP */ - { 0x4900, 0x4939, 0x8400, none }, /* 9 PgUp */ + { 0x4700, 0x4737, 0x7700, 0x0007 }, /* 7 Home */ + { 0x4800, 0x4838, none, 0x0008 }, /* 8 UP */ + { 0x4900, 0x4939, 0x8400, 0x0009 }, /* 9 PgUp */ { 0x4a2d, 0x4a2d, none, none }, /* - */ - { 0x4b00, 0x4b34, 0x7300, none }, /* 4 Left */ - { 0x4c00, 0x4c35, none, none }, /* 5 */ - { 0x4d00, 0x4d36, 0x7400, none }, /* 6 Right */ + { 0x4b00, 0x4b34, 0x7300, 0x0004 }, /* 4 Left */ + { 0x4c00, 0x4c35, none, 0x0005 }, /* 5 */ + { 0x4d00, 0x4d36, 0x7400, 0x0006 }, /* 6 Right */ { 0x4e2b, 0x4e2b, none, none }, /* + */ - { 0x4f00, 0x4f31, 0x7500, none }, /* 1 End */ - { 0x5000, 0x5032, none, none }, /* 2 Down */ - { 0x5100, 0x5133, 0x7600, none }, /* 3 PgDn */ - { 0x5200, 0x5230, none, none }, /* 0 Ins */ + { 0x4f00, 0x4f31, 0x7500, 0x0001 }, /* 1 End */ + { 0x5000, 0x5032, none, 0x0002 }, /* 2 Down */ + { 0x5100, 0x5133, 0x7600, 0x0003 }, /* 3 PgDn */ + { 0x5200, 0x5230, none, 0x0000 }, /* 0 Ins */ { 0x5300, 0x532e, none, none } /* Del */ }; @@ -143,7 +142,7 @@ static void add_key(Bit16u code) { static Bit16u get_key(void) { Bit16u start,end,head,tail,thead; start=mem_readw(BIOS_KEYBOARD_BUFFER_START); - end =mem_readw(BIOS_KEYBOARD_BUFFER_END); + end =mem_readw(BIOS_KEYBOARD_BUFFER_END); head =mem_readw(BIOS_KEYBOARD_BUFFER_HEAD); tail =mem_readw(BIOS_KEYBOARD_BUFFER_TAIL); @@ -162,7 +161,6 @@ static Bit16u check_key(void) { return real_readw(0x40,head); } - /* Flag Byte 1 bit 7 =1 INSert active bit 6 =1 Caps Lock active @@ -196,107 +194,180 @@ static Bit16u check_key(void) { */ + static Bitu IRQ1_Handler(void) { +/* handling of the locks key is difficult as sdl only gives states for + * numlock capslock. + */ +/* in reg_al is the scancode */ + /* Read the code */ - Bitu scancode,ascii,mod; -#if 0 - scancode=IO_Read(0x60); - ascii=0; - mod=0; + Bitu scancode; //,ascii,mod; +#if 1 + scancode=reg_al; //IO_Read(0x60); moved out of handler +// ascii=0; +// mod=0; #else + /* Old code capable of unicode keys. Dropped Readkey disabled in keyboard.cpp */ KEYBOARD_ReadKey(scancode,ascii,mod); -// LOG(0,"Got code %X ascii %C mod %X",scancode,ascii,mod); + LOG_MSG("Got code %X ascii %C mod %X",scancode,ascii,mod); #endif Bit16u old_ax=reg_ax; reg_flags|=1; reg_ah=0x4f;reg_al=scancode; CALLBACK_RunRealInt(0x15); - reg_ax=old_ax;Bit8u flags1,flags2,flags3; + reg_ax=old_ax;Bit8u flags1,flags2,flags3,leds; if (!(reg_flags&1)) goto irq1_return; //TODO maybe implement the int 0x15 ah=4f scancode lookup hook flags1=mem_readb(BIOS_KEYBOARD_FLAGS1); flags2=mem_readb(BIOS_KEYBOARD_FLAGS2); flags3=mem_readb(BIOS_KEYBOARD_FLAGS3); + leds =mem_readb(BIOS_KEYBOARD_LEDS); + flags2&=~(0x40+0x20);//remove numlock/capslock pressed (hack for sdl only reporting states) switch (scancode) { /* First the hard ones */ - case 0xe0: /* Extended key */ - flags3|=2; + case 0xfa: /* ack. Do nothing for now */ break; - case 29: /* Ctrl Pressed */ - flags1|=4; - if (flags3 & 2) flags3|=4; - else flags2|=1; + case 0xe1: /* Extended key special. Only pause uses this */ + LOG(LOG_KEYBOARD,LOG_ERROR)("someone is putting the pause key in the keyboard buffer"); break; - case 157: /* Ctrl Released */ - flags1&=~4; - if (flags3 & 2) flags3&=~4; - else flags2&=~1; + case 0xe0: /* Extended key */ + flags3 |=0x02; break; - case 42: /* Left Shift Pressed */ - flags1|=2; + case 0x1d: /* Ctrl Pressed */ + flags1 |=0x04; + if (flags3 &0x02) flags3 |=0x04; + else flags2 |=0x01; break; - case 170: /* Left Shift Released */ - flags1&=~2; + case 0x9d: /* Ctrl Released */ + if (flags3 &0x02) flags3 &=~0x04; + else flags2 &=~0x01; + if( !( (flags3 &0x04) || (flags2 &0x01) ) ) flags1 &=~0x04; break; - case 54: /* Right Shift Pressed */ - flags1|=1; + case 0x2a: /* Left Shift Pressed */ + flags1 |=0x02; break; - case 182: /* Right Shift Released */ - flags1&=~1; + case 0xaa: /* Left Shift Released */ + flags1 &=~0x02; break; - case 56: /* Alt Pressed */ - flags1|=8; - if (flags3 & 2) flags3|=8; - else flags2|=2; + case 0x36: /* Right Shift Pressed */ + flags1 |=0x01; break; - case 184: /* Alt Released */ - flags1&=~8; - if (flags3 & 2) flags3&=~8; - else flags2&=~2; + case 0xb6: /* Right Shift Released */ + flags1 &=~0x01; + break; + case 0x38: /* Alt Pressed */ + flags1 |=0x08; + if (flags3 &0x02) flags3 |=0x08; + else flags2 |=0x02; + break; + case 0xb8: /* Alt Released */ + if (flags3 &0x02) flags3 &= ~0x08; + else flags2 &= ~0x02; + if( !( (flags3 &0x08) || (flags2 &0x02) ) ) { /* Both alt released */ + flags1 &= ~0x08; + Bit16u token =mem_readb(BIOS_KEYBOARD_TOKEN); + if(token != 0){ + add_key(token); + mem_writeb(BIOS_KEYBOARD_TOKEN,0); + } + } break; -#if 0 - case 58:p_capslock=true;break; /* Caps Lock */ - case 186:p_capslock=false;break; - case 69:p_numlock=true;break; /* Num Lock */ - case 197:p_numlock=false;break; - case 70:p_scrolllock=true;break; /* Scroll Lock */ - case 198:p_scrolllock=false;break; - case 82:p_insert=true;break; /* Insert */ - case 210:p_insert=false;a_insert=!a_insert;break; -#endif - default: /* Normal Key */ + + case 0x3a:flags2 |=0x40;flags1 |=0x40;leds |=0x04;break; //SDL gives only the state instead of the toggle /* Caps Lock */ + case 0xba:flags1 &=~0x40;leds &=~0x04;break; + case 0x45:flags2 |=0x20;flags1 |=0x20;leds |=0x02;break; /* Num Lock */ + case 0xc5:flags1 &=~0x20;leds &=~0x02;break; + case 0x46:flags2 |=0x10;break; /* Scroll Lock SDL Seems to do this one fine (so break and make codes) */ + case 0xc6:flags1 ^=0x10;flags2 &=~0x10;leds ^=0x01;break; +// case 0x52:flags2|=128;break;//See numpad /* Insert */ + case 0xd2: + if(flags3&0x02) { + flags1^=0x80; + flags2&=~0x80; + break; + } else { + goto irq1_end;/*Normal release*/ + } + case 0x47: /* Numpad */ + case 0x48: + case 0x49: + case 0x4b: + case 0x4c: + case 0x4d: + case 0x4f: + case 0x50: + case 0x51: + case 0x52: + if(flags3 &0x02) { /*extend key. e.g key above arrows or arrows*/ + if(scancode == 0x52) { /* press insert */ + flags2 |=0x80; + break; + } + add_key((scancode <<8)|0xe0); + break; + } + if(flags1 &0x08) { + Bit8u token = mem_readb(BIOS_KEYBOARD_TOKEN); + token= token*10 + scan_to_scanascii[scancode].alt; + mem_writeb(BIOS_KEYBOARD_TOKEN,token); + } else if( ((flags1 &0x3)!=0) ^ ((flags1 &0x20) !=0) ) { + add_key(scan_to_scanascii[scancode].shift); + } else if (flags1 &0x04) { + add_key(scan_to_scanascii[scancode].control); + } else add_key(scan_to_scanascii[scancode].normal); + break; + + default: /* Normal Key */ Bit16u asciiscan; /* Now Handle the releasing of keys and see if they match up for a code */ - flags3&=~2; //Reset 0xE0 Flag /* Handle the actual scancode */ if (scancode & 0x80) goto irq1_end; if (scancode > MAX_SCAN_CODE) goto irq1_end; - if (mod & KBD_MOD_ALT) { /* Alt is being pressed */ + if (flags1 & 0x08) { /* Alt is being pressed */ asciiscan=scan_to_scanascii[scancode].alt; +#if 0 /* old unicode support disabled*/ } else if (ascii) { asciiscan=(scancode << 8) | ascii; - } else if (mod & KBD_MOD_CTRL) { /* Ctrl is being pressed */ +#endif + } else if (flags1 & 0x04) { /* Ctrl is being pressed */ asciiscan=scan_to_scanascii[scancode].control; - } else if (mod & KBD_MOD_SHIFT) { /* Either shift is being pressed */ + } else if (flags1 & 0x03) { /* Either shift is being pressed */ asciiscan=scan_to_scanascii[scancode].shift; } else { asciiscan=scan_to_scanascii[scancode].normal; } + /* cancel shift is letter and capslock active */ + if(flags1&64) { + if(flags1&3) { + /*cancel shift */ + if(((asciiscan&0x00ff) >0x40) && ((asciiscan&0x00ff) <0x5b)) + asciiscan=scan_to_scanascii[scancode].normal; + } else { + /* add shift */ + if(((asciiscan&0x00ff) >0x60) && ((asciiscan&0x00ff) <0x7b)) + asciiscan=scan_to_scanascii[scancode].shift; + } + } add_key(asciiscan); + break; }; irq1_end: + if(scancode !=0xe0) flags3 &=~0x02; //Reset 0xE0 Flag mem_writeb(BIOS_KEYBOARD_FLAGS1,flags1); mem_writeb(BIOS_KEYBOARD_FLAGS2,flags2); mem_writeb(BIOS_KEYBOARD_FLAGS3,flags3); + mem_writeb(BIOS_KEYBOARD_LEDS,leds); irq1_return: - IO_Write(0x20,0x20); +/* IO_Write(0x20,0x20); moved out of handler to be virtualizable */ #if 0 - /* Signal the keyboard for next code */ +/* Signal the keyboard for next code */ +/* In dosbox port 60 reads do this as well */ Bit8u old61=IO_Read(0x61); IO_Write(0x61,old61 | 128); - IO_Write(0x61,old61 & 127); + IO_Write(0x64,0xae); #endif return CBRET_NONE; } @@ -313,6 +384,7 @@ static Bitu INT16_Handler(void) { if (temp==0) { CALLBACK_Idle();}; } while (temp==0); reg_ax=temp; + if(reg_al==0xe0) reg_al=0; //extended key break; } case 0x01: /* CHECK FOR KEYSTROKE */ @@ -323,13 +395,14 @@ static Bitu INT16_Handler(void) { } else { CALLBACK_SZF(false); reg_ax=temp; + if(reg_al==0xe0) reg_al=0; //extended key } break; case 0x02: /* GET SHIFT FlAGS */ reg_al=mem_readb(BIOS_KEYBOARD_FLAGS1); break; case 0x03: /* SET TYPEMATIC RATE AND DELAY */ - LOG(LOG_BIOS,LOG_ERROR)("INT16:Unhandled Typematic Rate Call %2X",reg_al); + LOG(LOG_BIOS,LOG_ERROR)("INT16:Unhandled Typematic Rate Call %2X BX=%X",reg_al,reg_bx); break; case 0x05: /* STORE KEYSTROKE IN KEYBOARD BUFFER */ //TODO make add_key bool :) @@ -362,6 +435,8 @@ static void InitBiosSegment(void) { mem_writeb(BIOS_KEYBOARD_FLAGS1,0); mem_writeb(BIOS_KEYBOARD_FLAGS2,0); mem_writeb(BIOS_KEYBOARD_FLAGS3,16); /* Enhanced keyboard installed */ + mem_writeb(BIOS_KEYBOARD_TOKEN,0); + mem_writeb(BIOS_KEYBOARD_LEDS,16); } void BIOS_SetupKeyboard(void) { @@ -370,9 +445,23 @@ void BIOS_SetupKeyboard(void) { /* Allocate a callback for int 0x16 and for standard IRQ 1 handler */ call_int16=CALLBACK_Allocate(); call_irq1=CALLBACK_Allocate(); - CALLBACK_Setup(call_int16,&INT16_Handler,CB_IRET_STI); + CALLBACK_Setup(call_int16,&INT16_Handler,CB_IRET_STI,"keyboard"); RealSetVec(0x16,CALLBACK_RealPointer(call_int16)); - CALLBACK_Setup(call_irq1,&IRQ1_Handler,CB_IRET); + CALLBACK_Setup(call_irq1,&IRQ1_Handler,CB_IRET,"keyboard irq"); RealSetVec(0x9,CALLBACK_RealPointer(call_irq1)); + + /* bring the all port operations outside the callback */ + phys_writeb(CB_BASE+(call_irq1<<4)+0x00,(Bit8u)0x50); // push ax + phys_writeb(CB_BASE+(call_irq1<<4)+0x01,(Bit8u)0xe4); // in al, 0x60 + phys_writeb(CB_BASE+(call_irq1<<4)+0x02,(Bit8u)0x60); + phys_writeb(CB_BASE+(call_irq1<<4)+0x03,(Bit8u)0xFE); //GRP 4 + phys_writeb(CB_BASE+(call_irq1<<4)+0x04,(Bit8u)0x38); //Extra Callback instruction + phys_writew(CB_BASE+(call_irq1<<4)+0x05,call_irq1); //The immediate word + phys_writeb(CB_BASE+(call_irq1<<4)+0x07,(Bit8u)0xb0); // mov al, 0x20 + phys_writeb(CB_BASE+(call_irq1<<4)+0x08,(Bit8u)0x20); + phys_writeb(CB_BASE+(call_irq1<<4)+0x09,(Bit8u)0xe6); // out 0x20, al + phys_writeb(CB_BASE+(call_irq1<<4)+0x0a,(Bit8u)0x20); + phys_writeb(CB_BASE+(call_irq1<<4)+0x0b,(Bit8u)0x58); // pop ax + phys_writeb(CB_BASE+(call_irq1<<4)+0x0c,(Bit8u)0xcf); // iret } From 5e144aa1d6e2a8ae862a339456a200bc57b3f01c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 12 Apr 2004 08:13:48 +0000 Subject: [PATCH 1683/4131] Work around vs.net optimzing bug Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1765 --- src/hardware/dma.cpp | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 83cb6b90..306457be 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -240,8 +240,10 @@ void DMA_Init(Section* sec) { for(i=0;i<8;i++) { DmaChannels[i] = new DmaChannel(i,i>=4); } + for (i=0;i<0x10;i++) { - Bitu mask=i<8 ? (IO_MB|IO_MW) : IO_MB; + Bitu mask=IO_MB; + if (i<8) mask|=IO_MW; IO_RegisterWriteHandler(i,DMA_Write_Port,mask); IO_RegisterReadHandler(i,DMA_Read_Port,mask); if (machine==MCH_VGA) { @@ -249,20 +251,11 @@ void DMA_Init(Section* sec) { IO_RegisterReadHandler(0xc0+i*2,DMA_Read_Port,mask); } } - IO_RegisterWriteHandler(0x81,DMA_Write_Port,IO_MB); - IO_RegisterWriteHandler(0x82,DMA_Write_Port,IO_MB); - IO_RegisterWriteHandler(0x83,DMA_Write_Port,IO_MB); - IO_RegisterWriteHandler(0x89,DMA_Write_Port,IO_MB); - IO_RegisterWriteHandler(0x8a,DMA_Write_Port,IO_MB); - IO_RegisterWriteHandler(0x8b,DMA_Write_Port,IO_MB); - - IO_RegisterReadHandler(0x81,DMA_Read_Port,IO_MB); - IO_RegisterReadHandler(0x82,DMA_Read_Port,IO_MB); - IO_RegisterReadHandler(0x83,DMA_Read_Port,IO_MB); - IO_RegisterReadHandler(0x89,DMA_Read_Port,IO_MB); - IO_RegisterReadHandler(0x8a,DMA_Read_Port,IO_MB); - IO_RegisterReadHandler(0x8b,DMA_Read_Port,IO_MB); + IO_RegisterWriteHandler(0x81,DMA_Write_Port,IO_MB,3); + IO_RegisterWriteHandler(0x89,DMA_Write_Port,IO_MB,3); + IO_RegisterReadHandler(0x81,DMA_Read_Port,IO_MB,3); + IO_RegisterReadHandler(0x89,DMA_Read_Port,IO_MB,3); } From ed0fa4263189ff4e6f64c2a597b43228f0b77ee0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 13 Apr 2004 12:08:43 +0000 Subject: [PATCH 1684/4131] Removed dta check from findfirst in drive_cache. Caching now 2048 searches per drive. Clearing all when full. Changed dta to reflect specs better. Changed fcb to reflect specs better. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1766 --- include/dos_inc.h | 9 ++++--- include/dos_system.h | 31 +++++++++++------------ src/dos/drive_cache.cpp | 55 +++++++++++++++++++---------------------- src/dos/drive_local.cpp | 4 +-- 4 files changed, 48 insertions(+), 51 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index d5805e3b..8d733600 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.39 2004-04-03 19:19:29 canadacow Exp $ */ +/* $Id: dos_inc.h,v 1.40 2004-04-13 12:08:43 qbix79 Exp $ */ #ifndef DOS_H_ #define DOS_H_ @@ -428,9 +428,9 @@ private: #endif struct sDTA { Bit8u sdrive; /* The Drive the search is taking place */ - Bit8u sattr; /* The Attributes that need to be found */ Bit8u sname[8]; /* The Search pattern for the filename */ Bit8u 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 */ Bit8u fill[6]; Bit8u attr; @@ -477,8 +477,11 @@ private: Bit16u date; Bit16u time; /* Reserved Block should be 8 bytes */ + Bit8u sft_entries; + Bit8u share_attributes; + Bit8u extra_info; Bit8u file_handle; - Bit8u reserved[7]; + Bit8u reserved[4]; /* end */ Bit8u cur_rec; /* Current record in current block */ Bit32u rndm; /* Current relative record number */ diff --git a/include/dos_system.h b/include/dos_system.h index 0ef54455..6eb0b4d6 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.21 2004-03-04 19:49:14 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.22 2004-04-13 12:08:43 qbix79 Exp $ */ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ @@ -86,8 +86,8 @@ public: Bit8u fhandle; }; -#define MAX_OPENDIRS 16 - +#define MAX_OPENDIRS 2048 +//Can be high as it's only storage (16 bit variable) class DOS_Drive_Cache { public: DOS_Drive_Cache (void); @@ -105,7 +105,7 @@ public: char* GetExpandName (const char* path); bool GetShortName (const char* fullname, char* shortname); - bool FindFirst (char* path, Bitu dtaAddress, Bitu& id); + bool FindFirst (char* path, Bitu& id); bool FindNext (Bitu id, char* &result); void CacheOut (const char* path, bool ignoreLastDir = false); @@ -120,21 +120,19 @@ public: public: CFileInfo(void) { orgname[0] = shortname[0] = 0; - nextEntry = shortNr = compareCount = 0; + nextEntry = shortNr = 0; isDir = false; } ~CFileInfo(void) { for (Bit32u i=0; i fileList; std::vector longNameList; @@ -143,18 +141,18 @@ public: private: bool RemoveTrailingDot (char* shortname); - Bits GetLongName (CFileInfo* info, char* shortname); + Bits GetLongName (CFileInfo* info, char* shortname); void CreateShortName (CFileInfo* dir, CFileInfo* info); Bit16u CreateShortNameID (CFileInfo* dir, const char* name); - int CompareShortname (const char* compareName, const char* shortName); - bool SetResult (CFileInfo* dir, char * &result, Bit16u entryNr); - bool IsCachedIn (CFileInfo* dir); - CFileInfo* FindDirInfo (const char* path, char* expandedPath); + int CompareShortname (const char* compareName, const char* shortName); + bool SetResult (CFileInfo* dir, char * &result, Bit16u entryNr); + bool IsCachedIn (CFileInfo* dir); + CFileInfo* FindDirInfo (const char* path, char* expandedPath); bool RemoveSpaces (char* str); - bool OpenDir (CFileInfo* dir, const char* path, Bit16u& id); - void CreateEntry (CFileInfo* dir, const char* name); - Bit16u GetFreeID (CFileInfo* dir); - void Clear (void); + bool OpenDir (CFileInfo* dir, const char* path, Bit16u& id); + void CreateEntry (CFileInfo* dir, const char* name); + Bit16u GetFreeID (CFileInfo* dir); + void Clear (void); CFileInfo* dirBase; char dirPath [CROSS_LEN]; @@ -170,6 +168,7 @@ private: char dirSearchName [MAX_OPENDIRS]; bool free [MAX_OPENDIRS]; CFileInfo* dirFindFirst [MAX_OPENDIRS]; + Bitu nextFreeFindFirst; char label [CROSS_LEN]; }; diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 848827ec..e977c90f 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.33 2004-03-03 12:40:59 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.34 2004-04-13 12:08:43 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -62,20 +62,22 @@ bool SortByDirNameRev(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFi DOS_Drive_Cache::DOS_Drive_Cache(void) { - dirBase = new CFileInfo; - save_dir = 0; - srchNr = 0; - label[0] = 0; + dirBase = new CFileInfo; + save_dir = 0; + srchNr = 0; + label[0] = 0; + nextFreeFindFirst = 0; for (Bit32u i=0; ishortname,"~"); strcat(info->shortname,buffer); - // Create compare Count -// info->compareCount = tocopy; // Add (and cut) Extension, if available if (pos) { // Step to last extension... @@ -635,35 +636,29 @@ bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bit16u entryNr) }; // FindFirst / FindNext -bool DOS_Drive_Cache::FindFirst(char* path, Bitu dtaAddress, Bitu& id) +bool DOS_Drive_Cache::FindFirst(char* path, Bitu& id) { Bit16u dirID; - Bitu dirFindFirstID = 0xffff; + Bitu dirFindFirstID = this->nextFreeFindFirst++; //increase it for the next search // Cache directory in if (!OpenDir(path,dirID)) return false; - // Seacrh if dta was already used before - for (Bitu n=0; ncompareCount == dtaAddress) { - // Reuse old dta - dirFindFirstID = n; break; - } - } else if (dirFindFirstID==0xffff) { - dirFindFirstID = n; - } - } - if (dirFindFirstID==0xffff) { + + if (dirFindFirstID == MAX_OPENDIRS) { // no free slot found... - LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst/Next failure : All slots full."); - // always use first then + LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst/Next: All slots full. Resetting"); + // Clear the internal list then. dirFindFirstID = 0; + this->nextFreeFindFirst = 1; //the next free one after this search + for(Bitu n=0; n nextEntry = 0; - dirFindFirst[dirFindFirstID]-> compareCount = dtaAddress; // Copy entries to use with FindNext for (Bitu i=0; ifileList.size(); i++) { diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index c395c7ae..8d54929a 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.46 2004-04-03 19:23:06 canadacow Exp $ */ +/* $Id: drive_local.cpp,v 1.47 2004-04-13 12:08:43 qbix79 Exp $ */ #include #include @@ -142,7 +142,7 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { if (tempDir[strlen(tempDir)-1]!=CROSS_FILESPLIT) strcat(tempDir,end); Bitu id; - if (!dirCache.FindFirst(tempDir,(Bitu)dos.dta,id)) + if (!dirCache.FindFirst(tempDir,id)) { DOS_SetError(DOSERR_PATH_NOT_FOUND); return false; From 93d4681df6b4f7bcc7e38c926cf3d0d121bc0d79 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 13 Apr 2004 13:35:48 +0000 Subject: [PATCH 1685/4131] Fixed bug reported by Cliff Wright. An unterminated string in Drive_Cache::Setlabel could cause buserrors on at least NetBSD 1.6.1 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1767 --- src/dos/drive_cache.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index e977c90f..6b2a9d46 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.34 2004-04-13 12:08:43 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.35 2004-04-13 13:35:48 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -116,8 +116,7 @@ void DOS_Drive_Cache::SetLabel(const char* vname) while (togo>0) { if (vname[vnamePos]==0) break; if (!point && (vname[vnamePos]=='.')) { togo=4; point=true; } - label[labelPos] = vname[vnamePos]; - label[labelPos] = *upcase(&label[labelPos]); + label[labelPos] = toupper(vname[vnamePos]); labelPos++; vnamePos++; togo--; if ((togo==0) && !point) { From 7c67adc360829b10d23ba57ce8350994706e11ff Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 14 Apr 2004 20:50:50 +0000 Subject: [PATCH 1686/4131] Correctly support 16 bit write again Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1768 --- src/hardware/gus.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 2184ba51..9c319651 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -800,7 +800,8 @@ static Bitu read_gus(Bitu port,Bitu iolen) { case 0x303: return myGUS.gRegSelect; case 0x304: - return ExecuteReadRegister() & 0xff; + if (iolen==2) return ExecuteReadRegister() & 0xffff; + else return ExecuteReadRegister() & 0xff; case 0x305: return ExecuteReadRegister() >> 8; case 0x307: @@ -858,7 +859,8 @@ static void write_gus(Bitu port,Bitu val,Bitu iolen) { myGUS.gRegData = 0; break; case 0x304: - myGUS.gRegData = (0xff00 & myGUS.gRegData) | val; + if (iolen==2) myGUS.gRegData=val; + else myGUS.gRegData = (0xff00 & myGUS.gRegData) | val; ExecuteGlobRegister(); break; case 0x305: From 55b9530a569d90e604087da67bcdb16742fecffd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 18 Apr 2004 10:36:28 +0000 Subject: [PATCH 1687/4131] some odd devices stuff. (fizzban). Fcb findfirst/next fixes for drive(cw2oody) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1769 --- src/dos/dos_files.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 4d313d4c..121a9eae 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.53 2004-03-04 19:49:14 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.54 2004-04-18 10:36:28 qbix79 Exp $ */ #include #include @@ -329,6 +329,11 @@ bool DOS_CloseFile(Bit16u entry) { } bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { + // Creation of a device is the same as opening it + // Tc201 installer + if (DOS_FindDevice(name) != 255) + return DOS_OpenFile(name, 0, entry); + char fullname[DOS_PATHLENGTH];Bit8u drive; DOS_PSP psp(dos.psp); if (!DOS_MakeName(name,fullname,&drive)) return false; @@ -711,7 +716,7 @@ static void SaveFindResult(DOS_FCB & find_fcb) { char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr;Bit8u drive; char file_name[9];char ext[4]; find_dta.GetResult(name,size,date,time,attr); - drive=find_fcb.GetDrive(); + drive=find_fcb.GetDrive()+1; /* Create a correct file and extention */ DTAExtendName(name,file_name,ext); DOS_FCB fcb(RealSeg(dos.dta),RealOff(dos.dta)); From 67253f9e9b005456a4bfc4d25a7e572519a4c54f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 18 Apr 2004 14:49:50 +0000 Subject: [PATCH 1688/4131] Added support for attribute searching with extend fcbs. Added support for volume label searching on Virtual Drives. Added warnings for volume searching on Drive Fat. Improved support for Filelabel searching on drive_local to include fcbfinds Added Drivelabel "DOSBOX" to Virtual Drives. Changed default Label for localdrives to "NO_LABEL". Made DOS_FindFirst fcb finds aware. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1770 --- include/dos_inc.h | 6 ++++-- include/dos_system.h | 4 ++-- src/dos/dos_classes.cpp | 9 ++++++++- src/dos/dos_files.cpp | 11 +++++++---- src/dos/drive_fat.cpp | 7 +++++-- src/dos/drive_local.cpp | 11 ++++++----- src/dos/drive_virtual.cpp | 8 +++++++- src/dos/drives.h | 10 +++++----- 8 files changed, 44 insertions(+), 22 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 8d733600..6724f168 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.40 2004-04-13 12:08:43 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.41 2004-04-18 14:49:48 qbix79 Exp $ */ #ifndef DOS_H_ #define DOS_H_ @@ -121,7 +121,7 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry); bool DOS_OpenFileExtended(char *name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status); bool DOS_CreateFile(char * name,Bit16u attribute,Bit16u * entry); bool DOS_UnlinkFile(char * name); -bool DOS_FindFirst(char *search,Bit16u attr); +bool DOS_FindFirst(char *search,Bit16u attr,bool fcb_findfirst=false); bool DOS_FindNext(void); bool DOS_Canonicalize(char * name,char * big); bool DOS_CreateTempFile(char * name,Bit16u * entry); @@ -461,6 +461,8 @@ public: void SetRandom(Bit32u _random); Bit8u GetDrive(void); bool Extended(void); + void GetAttr(Bit8u & attr); + void SetAttr(Bit8u attr); private: bool extended; PhysPt real_pt; diff --git a/include/dos_system.h b/include/dos_system.h index 6eb0b4d6..d3f0d772 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.22 2004-04-13 12:08:43 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.23 2004-04-18 14:49:48 qbix79 Exp $ */ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ @@ -217,7 +217,7 @@ public: virtual bool RemoveDir(char * _dir)=0; virtual bool MakeDir(char * _dir)=0; virtual bool TestDir(char * _dir)=0; - virtual bool FindFirst(char * _dir,DOS_DTA & dta)=0; + virtual bool FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst=false)=0; virtual bool FindNext(DOS_DTA & dta)=0; virtual bool GetFileAttr(char * name,Bit16u * attr)=0; virtual bool Rename(char * oldname,char * newname)=0; diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 62ebdf95..38b79d28 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.35 2004-02-28 16:35:14 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.36 2004-04-18 14:49:48 qbix79 Exp $ */ #include #include @@ -428,3 +428,10 @@ void DOS_FCB::GetName(char * fillname) { fillname[14]=0; } +void DOS_FCB::GetAttr(Bit8u& attr) { + if(extended) attr=mem_readb(pt - 1); +} + +void DOS_FCB::SetAttr(Bit8u attr) { + if(extended) mem_writeb(pt - 1,attr); +} diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 121a9eae..6b3ad232 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.54 2004-04-18 10:36:28 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.55 2004-04-18 14:49:48 qbix79 Exp $ */ #include #include @@ -217,7 +217,7 @@ bool DOS_Rename(char * oldname,char * newname) { return false; } -bool DOS_FindFirst(char * search,Bit16u attr) { +bool DOS_FindFirst(char * search,Bit16u attr,bool fcb_findfirst) { DOS_DTA dta(dos.dta); Bit8u drive;char fullsearch[DOS_PATHLENGTH]; char dir[DOS_PATHLENGTH];char pattern[DOS_PATHLENGTH]; @@ -234,7 +234,7 @@ bool DOS_FindFirst(char * search,Bit16u attr) { strcpy(dir,fullsearch); } dta.SetupSearch(drive,(Bit8u)attr,pattern); - if (Drives[drive]->FindFirst(dir,dta)) return true; + if (Drives[drive]->FindFirst(dir,dta,fcb_findfirst)) return true; return false; } @@ -722,6 +722,7 @@ static void SaveFindResult(DOS_FCB & find_fcb) { DOS_FCB fcb(RealSeg(dos.dta),RealOff(dos.dta)); fcb.Create(find_fcb.Extended()); fcb.SetName(drive,file_name,ext); + fcb.SetAttr(attr); /* Only adds attribute if fcb is extended */ fcb.SetSizeDateTime(size,date,time); } @@ -777,7 +778,9 @@ bool DOS_FCBFindFirst(Bit16u seg,Bit16u offset) DOS_FCB fcb(seg,offset); RealPt old_dta=dos.dta;dos.dta=dos.tables.tempdta; char name[DOS_FCBNAME];fcb.GetName(name); - bool ret=DOS_FindFirst(name,DOS_ATTR_ARCHIVE); + Bit8u attr = DOS_ATTR_ARCHIVE; + fcb.GetAttr(attr); /* Gets search attributes if extended */ + bool ret=DOS_FindFirst(name,attr,true); dos.dta=old_dta; if (ret) SaveFindResult(fcb); return ret; diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 845bdeee..e9cb8577 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -770,9 +770,12 @@ bool fatDrive::FileUnlink(char * name) { return true; } -bool fatDrive::FindFirst(char *_dir, DOS_DTA &dta) { +bool fatDrive::FindFirst(char *_dir, DOS_DTA &dta,bool fcb_findfirst) { direntry dummyClust; - + Bit8u attr;char pattern[DOS_NAMELENGTH_ASCII]; + dta.GetSearchParams(attr,pattern); + if(attr & DOS_ATTR_VOLUME) //check for root dir or fcb_findfirst + LOG(LOG_DOSMISC,LOG_WARN)("findfirst for volumelabel used on fatDrive. Unhandled!!!!!"); if(!getDirClustNum(_dir, &cwdDirCluster, false)) return false; dta.SetDirID(0); return FindNextInternal(cwdDirCluster, dta, &dummyClust); diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 8d54929a..7d50886d 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.47 2004-04-13 12:08:43 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.48 2004-04-18 14:49:50 qbix79 Exp $ */ #include #include @@ -127,7 +127,7 @@ bool localDrive::FileUnlink(char * name) { }; -bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { +bool localDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) { char tempDir[CROSS_LEN]; strcpy(tempDir,basedir); @@ -152,11 +152,12 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { Bit8u sAttr; dta.GetSearchParams(sAttr,tempDir); - if ((sAttr & DOS_ATTR_VOLUME) && (*_dir==0)) { + if ( (sAttr & DOS_ATTR_VOLUME) && ( (*_dir==0) || fcb_findfirst ) ) { // Get Volume Label (DOS_ATTR_VOLUME) and only in basedir + // or it's a fcb findfirst as that always returns label if ( strcmp(dirCache.GetLabel(), "") == 0 ) { LOG(LOG_DOSMISC,LOG_ERROR)("DRIVELABEL REQUESTED: none present, returned NOLABEL"); - dta.SetResult("NOLABEL",0,0,0,DOS_ATTR_VOLUME); + dta.SetResult("NO_LABEL",0,0,0,DOS_ATTR_VOLUME); return true; } @@ -532,7 +533,7 @@ bool cdromDrive::GetFileAttr(char * name,Bit16u * attr) return result; }; -bool cdromDrive::FindFirst(char * _dir,DOS_DTA & dta) +bool cdromDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) { // If media has changed, reInit drivecache. if (MSCDEX_HasMediaChanged(subUnit)) { diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index d40a9a5c..ccd2aa86 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -185,8 +185,14 @@ bool Virtual_Drive::FileExists(const char* name){ return false; } -bool Virtual_Drive::FindFirst(char * _dir,DOS_DTA & dta) { +bool Virtual_Drive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) { search_file=first_file; + Bit8u attr;char pattern[DOS_NAMELENGTH_ASCII]; + dta.GetSearchParams(attr,pattern); + if(attr & DOS_ATTR_VOLUME) { + dta.SetResult("DOSBOX",0,0,0,DOS_ATTR_ARCHIVE); + return true; + } return FindNext(dta); } diff --git a/src/dos/drives.h b/src/dos/drives.h index 526386e8..ba6eb569 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.20 2004-04-03 19:22:33 canadacow Exp $ */ +/* $Id: drives.h,v 1.21 2004-04-18 14:49:50 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ @@ -38,7 +38,7 @@ public: virtual bool RemoveDir(char * dir); virtual bool MakeDir(char * dir); virtual bool TestDir(char * dir); - virtual bool FindFirst(char * _dir,DOS_DTA & dta); + virtual bool FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst=false); virtual bool FindNext(DOS_DTA & dta); virtual bool GetFileAttr(char * name,Bit16u * attr); virtual bool Rename(char * oldname,char * newname); @@ -129,7 +129,7 @@ public: virtual bool RemoveDir(char * dir); virtual bool MakeDir(char * dir); virtual bool TestDir(char * dir); - virtual bool FindFirst(char * _dir,DOS_DTA & dta); + virtual bool FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst=false); virtual bool FindNext(DOS_DTA & dta); virtual bool GetFileAttr(char * name,Bit16u * attr); virtual bool Rename(char * oldname,char * newname); @@ -195,7 +195,7 @@ public: virtual bool MakeDir(char * dir); virtual bool Rename(char * oldname,char * newname); virtual bool GetFileAttr(char * name,Bit16u * attr); - virtual bool FindFirst(char * _dir,DOS_DTA & dta); + virtual bool FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst=false); virtual void SetDir(const char* path); virtual bool isRemote(void); private: @@ -213,7 +213,7 @@ public: bool RemoveDir(char * dir); bool MakeDir(char * dir); bool TestDir(char * dir); - bool FindFirst(char * _dir,DOS_DTA & dta); + bool FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst); bool FindNext(DOS_DTA & dta); bool GetFileAttr(char * name,Bit16u * attr); bool Rename(char * oldname,char * newname); From c1a88974e0fac777d621c79944000c76a1f0e252 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 20 Apr 2004 06:53:36 +0000 Subject: [PATCH 1689/4131] Detect sizeof the dosbox data types Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1771 --- acinclude.m4 | 47 ++++++++++++++++++++++++++++++++++- configure.in | 7 +++++- include/dosbox.h | 19 -------------- src/platform/visualc/config.h | 14 +++++++++++ 4 files changed, 66 insertions(+), 21 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index f0a8266b..9ea0d7a2 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -305,7 +305,7 @@ AC_SUBST(ALSA_LIBS) AH_TOP([ /* - * Copyright (C) 2002-2003 The DOSBox Team + * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -331,4 +331,49 @@ AH_BOTTOM([#if C_HAS_ATTRIBUTE #define GCC_ATTRIBUTE(x) /* attribute not supported */ #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 + +]) \ No newline at end of file diff --git a/configure.in b/configure.in index 657a3015..0cc5ca58 100644 --- a/configure.in +++ b/configure.in @@ -35,7 +35,12 @@ AC_C_CONST AC_C_INLINE AC_TYPE_SIZE_T AC_STRUCT_TM - +AC_CHECK_SIZEOF(unsigned char) +AC_CHECK_SIZEOF(unsigned short) +AC_CHECK_SIZEOF(unsigned int) +AC_CHECK_SIZEOF(unsigned long) +AC_CHECK_SIZEOF(unsigned long long) +AC_CHECK_SIZEOF(int *) AC_MSG_CHECKING(if environ can be included) AC_TRY_LINK([#include diff --git a/include/dosbox.h b/include/dosbox.h index a1061790..afb93bb4 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -24,25 +24,6 @@ void E_Exit(char * message,...); void MSG_Add(const char*,const char*); //add messages to the internal langaugefile const char* MSG_Get(char const *); //get messages from the internal langaugafile -/* The internal types */ -typedef unsigned char Bit8u; -typedef signed char Bit8s; -typedef unsigned short Bit16u; -typedef signed short Bit16s; -typedef unsigned long Bit32u; -typedef signed long Bit32s; -typedef double Real64; -#if defined(_MSC_VER) -typedef unsigned __int64 Bit64u; -typedef signed __int64 Bit64s; -#else -typedef unsigned long long Bit64u; -typedef signed long long Bit64s; -#endif - -typedef unsigned int Bitu; -typedef signed int Bits; - #include #include "config.h" diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index c3260199..78ccbefc 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -39,3 +39,17 @@ #define ENVIRON_LINKED 1 #define GCC_ATTRIBUTE(x) /* attribute not supported */ + +typedef double Real64; +/* The internal types */ +typedef unsigned char Bit8u; +typedef signed char Bit8s; +typedef unsigned short Bit16u; +typedef signed short Bit16s; +typedef unsigned long Bit32u; +typedef signed long Bit32s; +typedef unsigned __int64 Bit64u; +typedef signed __int64 Bit64s; +typedef unsigned int Bitu; +typedef signed int Bits; + From 2bccfd7a228cddf51f4d62ed091848a9fefc0032 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 21 Apr 2004 08:21:47 +0000 Subject: [PATCH 1690/4131] Fix 4-bit adpcm transfers from doing extra dma tranfers causing sounds to play to fast Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1772 --- src/hardware/sblaster.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 09222590..bb6d1e9c 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -390,9 +390,6 @@ static void GenerateDMASound(Bitu size) { sb.adpcm.stepsize=MIN_ADAPTIVE_STEP_SIZE; skip++;read--; } - if (sb.dma.leftRead(size,sb.dma.buf.b8); - sb.dma.left-=read; for (i=0;i> 4,sb.adpcm.reference,sb.adpcm.stepsize); sb.tmp.buf.m[done++]=decode_ADPCM_4_sample(sb.dma.buf.b8[skip+i]& 0xf,sb.adpcm.reference,sb.adpcm.stepsize); From 5460def6342b1127f453e7db680c6958561e7605 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 22 Apr 2004 22:40:46 +0000 Subject: [PATCH 1691/4131] Changes to cpu cores. Save/Load eip after each opcode Handle IO exceptions Handle protection exception for protected opcodes with too less privilege Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1773 --- include/cpu.h | 35 ++-- src/cpu/core_full.cpp | 41 ++--- src/cpu/core_full/load.h | 187 ++++++------------- src/cpu/core_full/loadwrite.h | 48 ++--- src/cpu/core_full/op.h | 38 ++-- src/cpu/core_full/optable.h | 9 +- src/cpu/core_full/save.h | 33 +--- src/cpu/core_full/string.h | 2 +- src/cpu/core_full/support.h | 15 +- src/cpu/core_normal.cpp | 64 +++---- src/cpu/core_normal/helpers.h | 14 -- src/cpu/core_normal/prefix_0f.h | 27 ++- src/cpu/core_normal/prefix_66.h | 198 +++++++++++--------- src/cpu/core_normal/prefix_66_0f.h | 12 +- src/cpu/core_normal/prefix_none.h | 281 ++++++++++++++--------------- src/cpu/core_normal/string.h | 19 +- src/cpu/core_normal/support.h | 127 ++++--------- src/cpu/cpu.cpp | 181 ++++++++++++------- 18 files changed, 589 insertions(+), 742 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 3225738e..b30aabfb 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -52,7 +52,6 @@ void CPU_SLDT(Bitu & selector); void CPU_SIDT(Bitu & limit,Bitu & base); void CPU_SGDT(Bitu & limit,Bitu & base); - void CPU_ARPL(Bitu & dest_sel,Bitu src_sel); void CPU_LAR(Bitu selector,Bitu & ar); void CPU_LSL(Bitu selector,Bitu & limit); @@ -61,37 +60,43 @@ bool CPU_SET_CRX(Bitu cr,Bitu value); Bitu CPU_GET_CRX(Bitu cr); void CPU_SMSW(Bitu & word); -bool CPU_LMSW(Bitu word); +Bitu CPU_LMSW(Bitu word); void CPU_VERR(Bitu selector); void CPU_VERW(Bitu selector); -void CPU_JMP(bool use32,Bitu selector,Bitu offset,Bitu opLen); -void CPU_CALL(bool use32,Bitu selector,Bitu offset,Bitu opLen); -void CPU_RET(bool use32,Bitu bytes,Bitu opLen); -void CPU_IRET(bool use32,Bitu opLen); +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_CLI(Bitu opLen); -bool CPU_STI(Bitu opLen); +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 -void CPU_Interrupt(Bitu num,Bitu type,Bitu opLen=0); +void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip); INLINE void CPU_HW_Interrupt(Bitu num) { - CPU_Interrupt(num,0); + CPU_Interrupt(num,0,reg_eip); } -INLINE void CPU_SW_Interrupt(Bitu num,Bitu OpLen) { - CPU_Interrupt(num,CPU_INT_SOFTWARE,OpLen); +INLINE void CPU_SW_Interrupt(Bitu num,Bitu oldeip) { + CPU_Interrupt(num,CPU_INT_SOFTWARE,oldeip); } void CPU_Exception(Bitu which,Bitu error=0); -void CPU_StartException(void); -void CPU_SetupException(Bitu which,Bitu error=0); bool CPU_SetSegGeneral(SegNames seg,Bitu value); -void CPU_HLT(Bitu opLen); +bool CPU_PopSeg(SegNames seg,bool use32); void CPU_CPUID(void); Bitu CPU_Pop16(void); diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 9fdc76be..54cea6fe 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -54,47 +54,28 @@ typedef PhysPt EAPoint; #include "core_full/optable.h" #include "instructions.h" -#define LEAVECORE \ - SaveIP(); \ - FillFlags(); - #define EXCEPTION(blah) \ { \ Bit8u new_num=blah; \ - IPPoint=inst.opcode_start; \ - LEAVECORE; \ CPU_Exception(new_num,0); \ - LoadIP(); \ - goto nextopcode; \ + continue; \ } Bits CPU_Core_Full_Run(void) { FullData inst; -restart_core: - if (!cpu.code.big) { - inst.start_prefix=0x0;; - inst.start_entry=0x0; - } else { - inst.start_prefix=PREFIX_ADDR; - inst.start_entry=0x200; - } - EAPoint IPPoint; - LoadIP(); - lflags.type=t_UNKNOWN; while (CPU_Cycles-->0) { #if C_DEBUG cycle_count++; #if C_HEAVY_DEBUG - SaveIP(); if (DEBUG_HeavyIsBreakpoint()) { LEAVECORE; return debugCallback; }; #endif #endif - inst.opcode_start=IPPoint; - inst.entry=inst.start_entry; - inst.prefix=inst.start_prefix; + LoadIP(); + inst.entry=cpu.code.big*0x200; + inst.prefix=cpu.code.big; restartopcode: inst.entry=(inst.entry & 0xffffff00) | Fetchb(); inst.code=OpCodeTable[inst.entry]; @@ -102,14 +83,14 @@ restartopcode: #include "core_full/op.h" #include "core_full/save.h" nextopcode:; - } - LEAVECORE; - return CBRET_NONE; + SaveIP(); + continue; illegalopcode: - LEAVECORE; - reg_eip-=(IPPoint-inst.opcode_start); - CPU_Exception(0x6,0); - goto restart_core; + LOG_MSG("Illegal opcode"); + CPU_Exception(0x6,0); + } + FillFlags(); + return CBRET_NONE; } diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index fc009821..3a63a3de 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -144,18 +144,12 @@ l_M_Ed: inst.op1.d=SegValue((SegNames)inst.rm_index); break; case M_Efw: - if (inst.rm>=0xC0) { - LOG(LOG_CPU,LOG_ERROR)("MODRM:Illegal M_Efw "); - goto nextopcode; - } + if (inst.rm>=0xc0) goto illegalopcode; inst.op1.d=LoadMw(inst.rm_eaa); inst.op2.d=LoadMw(inst.rm_eaa+2); break; case M_Efd: - if (inst.rm>=0xc0) { - LOG(LOG_CPU,LOG_ERROR)("MODRM:Illegal M_Efw "); - goto nextopcode; - } + if (inst.rm>=0xc0) goto illegalopcode; inst.op1.d=LoadMd(inst.rm_eaa); inst.op2.d=LoadMw(inst.rm_eaa+4); break; @@ -183,8 +177,6 @@ l_M_Ed: inst.op2.d=1; inst.code=Groups[inst.code.op][inst.rm_index]; goto l_MODRMswitch; - - /* Should continue with normal handler afterwards */ case 0: break; default: @@ -206,30 +198,6 @@ l_M_Ed: inst.op1.d = Pop_32(); inst.op2.d = Pop_16(); break; - case L_PFLGw: - if ((reg_flags & FLAG_VM) && ((reg_flags & FLAG_IOPL)!=FLAG_IOPL)) { - LEAVECORE;reg_eip-=IPPoint-inst.opcode_start; - CPU_Exception(13,0); - goto restart_core; - } - SETFLAGSw(Pop_16()); - if (GETFLAG(IF) && PIC_IRQCheck) { - SaveIP(); - return CBRET_NONE; - } - break; - case L_PFLGd: - if ((reg_flags & FLAG_VM) && ((reg_flags & FLAG_IOPL)!=FLAG_IOPL)) { - LEAVECORE;reg_eip-=IPPoint-inst.opcode_start; - CPU_Exception(13,0); - goto restart_core; - } - SETFLAGSd(Pop_32()); - if (GETFLAG(IF) && PIC_IRQCheck) { - SaveIP(); - return CBRET_NONE; - } - break; case L_Ib: inst.op1.d=Fetchb(); break; @@ -270,9 +238,6 @@ l_M_Ed: case L_REGd: inst.op1.d=reg_32(inst.code.extra); break; - case L_FLG: - inst.op1.d = FillFlags(); - break; case L_SEG: inst.op1.d=SegValue((SegNames)inst.code.extra); break; @@ -306,10 +271,10 @@ l_M_Ed: inst.repz=true; goto restartopcode; case L_PREOP: - inst.entry=inst.start_entry ^ 0x200; + inst.entry=(cpu.code.big ^1) * 0x200; goto restartopcode; case L_PREADD: - inst.prefix^=PREFIX_ADDR; + inst.prefix=(inst.prefix & ~1) | (cpu.code.big ^ 1); goto restartopcode; case L_VAL: inst.op1.d=inst.code.extra; @@ -319,41 +284,40 @@ l_M_Ed: inst.op1.d=4; break; case D_IRETw: - LEAVECORE; - CPU_IRET(false,IPPoint-inst.opcode_start); + FillFlags(); + CPU_IRET(false,GetIP()); if (GETFLAG(IF) && PIC_IRQCheck) { return CBRET_NONE; } - goto restart_core; + continue; case D_IRETd: - LEAVECORE; - CPU_IRET(true,IPPoint-inst.opcode_start); - if (GETFLAG(IF) && PIC_IRQCheck) { + FillFlags(); + CPU_IRET(true,GetIP()); + if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; - } - goto restart_core; + continue; case D_RETFwIw: { Bitu words=Fetchw(); - LEAVECORE; - CPU_RET(false,words,IPPoint-inst.opcode_start); - goto restart_core; + FillFlags(); + CPU_RET(false,words,GetIP()); + continue; } case D_RETFw: - LEAVECORE; - CPU_RET(false,0,IPPoint-inst.opcode_start); - goto restart_core; + FillFlags(); + CPU_RET(false,0,GetIP()); + continue; case D_RETFdIw: { Bitu words=Fetchw(); - LEAVECORE; - CPU_RET(true,words,IPPoint-inst.opcode_start); - goto restart_core; + FillFlags(); + CPU_RET(true,words,GetIP()); + continue; } case D_RETFd: - LEAVECORE; - CPU_RET(true,0,IPPoint-inst.opcode_start); - goto restart_core; + FillFlags(); + CPU_RET(true,0,GetIP()); + continue; /* Direct operations */ case L_STRING: #include "string.h" @@ -381,18 +345,10 @@ l_M_Ed: reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32(); goto nextopcode; case D_POPSEGw: - if (CPU_SetSegGeneral((SegNames)inst.code.extra,Pop_16())) { - LEAVECORE; - reg_eip-=(IPPoint-inst.opcode_start);reg_esp-=2; - CPU_StartException();goto restart_core; - } + if (CPU_PopSeg((SegNames)inst.code.extra,false)) RunException(); goto nextopcode; case D_POPSEGd: - if (CPU_SetSegGeneral((SegNames)inst.code.extra,Pop_32())) { - LEAVECORE; - reg_eip-=(IPPoint-inst.opcode_start);reg_esp-=4; - CPU_StartException();goto restart_core; - } + if (CPU_PopSeg((SegNames)inst.code.extra,true)) RunException(); goto nextopcode; case D_SETALC: reg_al = get_CF() ? 0xFF : 0; @@ -427,14 +383,10 @@ l_M_Ed: else reg_edx=0; goto nextopcode; case D_CLI: - LEAVECORE; - if (CPU_CLI(IPPoint-inst.opcode_start)) - goto restart_core; + if (CPU_CLI()) RunException(); goto nextopcode; case D_STI: - LEAVECORE; - if (CPU_STI(IPPoint-inst.opcode_start)) - goto restart_core; + if (CPU_STI()) RunException(); goto nextopcode; case D_STC: FillFlags();SETFLAGBIT(CF,true); @@ -454,71 +406,40 @@ l_M_Ed: SETFLAGBIT(DF,true); cpu.direction=-1; goto nextopcode; + case D_PUSHF: + FillFlags(); + if (CPU_PUSHF(inst.code.extra)) RunException(); + goto nextopcode; + case D_POPF: + if (CPU_POPF(inst.code.extra)) RunException(); + lflags.type=t_UNKNOWN; + if (GETFLAG(IF) && PIC_IRQCheck) { + SaveIP(); + return CBRET_NONE; + } + goto nextopcode; + case D_SAHF: + SETFLAGSb(reg_ah); + goto nextopcode; + case D_LAHF: + FillFlags(); + reg_ah=reg_flags&0xff; + goto nextopcode; case D_WAIT: case D_NOP: goto nextopcode; case D_ENTERw: { - Bitu bytes=Fetchw();Bitu level=Fetchb() & 0x1f; - Bitu frame_ptr=reg_esp-2; - if (cpu.stack.big) { - reg_esp-=2; - mem_writew(SegBase(ss)+reg_esp,reg_bp); - for (Bitu i=1;i0) { - core.op_start=core.ip_lookup; - core.opcode_index=core.index_default; - core.prefixes=core.prefix_default; + LOADIP; + core.opcode_index=cpu.code.big*0x200; + core.prefixes=cpu.code.big; #if C_DEBUG - cycle_count++; #if C_HEAVY_DEBUG - SAVEIP; if (DEBUG_HeavyIsBreakpoint()) { - LEAVECORE; + FillFlags(); return debugCallback; }; #endif + cycle_count++; #endif restart_prefix: core.ea_table=EAPrefixTable[core.prefixes]; @@ -189,27 +177,29 @@ restart_opcode: #include "core_normal/prefix_66_0f.h" default: illegal_opcode: - LEAVECORE; - reg_eip-=core.ip_lookup-core.op_start; #if C_DEBUG { - Bitu len=core.ip_lookup-core.op_start; + Bitu len=(GETIP-reg_eip); + LOADIP; if (len>16) len=16; char tempcode[16*2+1];char * writecode=tempcode; for (;len>0;len--) { - sprintf(writecode,"%X",mem_readb(core.op_start++)); + sprintf(writecode,"%X",mem_readb(core.cseip++)); writecode+=2; } LOG(LOG_CPU,LOG_ERROR)("Illegal/Unhandled opcode %s",tempcode); } #endif CPU_Exception(6,0); - goto decode_start; - + continue; } + SAVEIP; } + FillFlags(); + return CBRET_NONE; decode_end: - LEAVECORE; + SAVEIP; + FillFlags(); return CBRET_NONE; } @@ -220,7 +210,7 @@ Bits CPU_Core_Normal_Trap_Run(void) { core.trap.skip=false; Bits ret=CPU_Core_Normal_Run(); - if (!core.trap.skip) CPU_SW_Interrupt(1,0); + if (!core.trap.skip) CPU_SW_Interrupt(1,reg_eip); CPU_Cycles = oldCycles-1; cpudecoder = &CPU_Core_Normal_Run; diff --git a/src/cpu/core_normal/helpers.h b/src/cpu/core_normal/helpers.h index b7acd35b..d7326488 100644 --- a/src/cpu/core_normal/helpers.h +++ b/src/cpu/core_normal/helpers.h @@ -141,17 +141,3 @@ } \ } -#define POPSEG(_SEG_,_VAL_,_ESP_CHANGE_) \ - if (CPU_SetSegGeneral(_SEG_,_VAL_)) { \ - LEAVECORE; \ - reg_eip-=(core.ip_lookup-core.op_start);reg_esp-=_ESP_CHANGE_; \ - CPU_StartException();goto decode_start; \ - } - -#define LOADSEG(_SEG_,_SEG_VAL_) \ - if (CPU_SetSegGeneral(_SEG_,_SEG_VAL_)) { \ - LEAVECORE; \ - reg_eip-=(core.ip_lookup-core.op_start); \ - CPU_StartException();goto decode_start; \ - } \ - diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index bbe95b9c..f562d051 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -45,7 +45,7 @@ } break; default: - LOG(LOG_CPU,LOG_ERROR)("GRP6:Illegal call %2X",which); + goto illegal_opcode; } } break; @@ -77,7 +77,7 @@ break; case 0x06: /* LMSW */ limit=LoadMw(eaa); - if (!CPU_LMSW(limit)) goto decode_end; + if (CPU_LMSW(limit)) RUNEXCEPTION(); break; } } else { @@ -88,11 +88,10 @@ *earw=limit; break; case 0x06: /* LMSW */ - if (!CPU_LMSW(*earw)) goto decode_end; + if (CPU_LMSW(*earw)) RUNEXCEPTION(); break; default: - LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which); - break; + goto illegal_opcode; } } } @@ -154,11 +153,8 @@ Bitu which=(rm >> 3) & 7; if (rm >= 0xc0 ) { GetEArd; - CPU_SET_CRX(which,*eard); - } else { - GetEAa; - LOG(LOG_CPU,LOG_ERROR)("MOV CR%,XXX with non-register",which); - } + if (CPU_SET_CRX(which,*eard)) RUNEXCEPTION(); + } else goto illegal_opcode; } break; CASE_0F_B(0x23) /* MOV DRx,Rd */ @@ -241,7 +237,7 @@ CASE_0F_W(0xa0) /* PUSH FS */ Push_16(SegValue(fs));break; CASE_0F_W(0xa1) /* POP FS */ - POPSEG(fs,Pop_16(),2); + if (CPU_PopSeg(fs,false)) RUNEXCEPTION(); break; CASE_0F_B(0xa2) /* CPUID */ CPU_CPUID();break; @@ -268,7 +264,8 @@ CASE_0F_W(0xa8) /* PUSH GS */ Push_16(SegValue(gs));break; CASE_0F_W(0xa9) /* POP GS */ - POPSEG(gs,Pop_16(),2);break; + if (CPU_PopSeg(gs,false)) RUNEXCEPTION(); + break; CASE_0F_W(0xab) /* BTS Ew,Gw */ { FillFlags();GetRMrw; @@ -297,7 +294,7 @@ CASE_0F_W(0xb2) /* LSS Ew */ { GetRMrw;GetEAa; - LOADSEG(ss,LoadMw(eaa+2)); + if (CPU_SetSegGeneral(ss,LoadMw(eaa+2))) RUNEXCEPTION(); *rmrw=LoadMw(eaa); break; } @@ -320,14 +317,14 @@ CASE_0F_W(0xb4) /* LFS Ew */ { GetRMrw;GetEAa; - LOADSEG(fs,LoadMw(eaa+2)); + if (CPU_SetSegGeneral(fs,LoadMw(eaa+2))) RUNEXCEPTION(); *rmrw=LoadMw(eaa); break; } CASE_0F_W(0xb5) /* LGS Ew */ { GetRMrw;GetEAa; - LOADSEG(gs,LoadMw(eaa+2)); + if (CPU_SetSegGeneral(gs,LoadMw(eaa+2))) RUNEXCEPTION(); *rmrw=LoadMw(eaa); break; } diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 94d99c07..28cd7ccd 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -25,7 +25,8 @@ CASE_D(0x06) /* PUSH ES */ Push_32(SegValue(es));break; CASE_D(0x07) /* POP ES */ - POPSEG(es,Pop_32(),4);break; + if (CPU_PopSeg(es,true)) RUNEXCEPTION(); + break; CASE_D(0x09) /* OR Ed,Gd */ RMEdGd(ORD);break; CASE_D(0x0b) /* OR Gd,Ed */ @@ -43,7 +44,7 @@ CASE_D(0x16) /* PUSH SS */ Push_32(SegValue(ss));break; CASE_D(0x17) /* POP SS */ - POPSEG(ss,Pop_32(),4); + if (CPU_PopSeg(ss,true)) RUNEXCEPTION(); CPU_Cycles++; break; CASE_D(0x19) /* SBB Ed,Gd */ @@ -55,7 +56,8 @@ CASE_D(0x1e) /* PUSH DS */ Push_32(SegValue(ds));break; CASE_D(0x1f) /* POP DS */ - POPSEG(ds,Pop_32(),4);break; + if (CPU_PopSeg(ds,true)) RUNEXCEPTION(); + break; CASE_D(0x21) /* AND Ed,Gd */ RMEdGd(ANDD);break; CASE_D(0x23) /* AND Gd,Ed */ @@ -191,6 +193,12 @@ CASE_D(0x6b) /* IMUL Gd,Ed,Ib */ RMGdEdOp3(DIMULD,Fetchbs()); break; + CASE_D(0x6d) /* INSD */ + if (CPU_IO_Exception(reg_dx,4)) RUNEXCEPTION(); + DoString(R_INSD);break; + CASE_D(0x6f) /* OUTSD */ + if (CPU_IO_Exception(reg_dx,4)) RUNEXCEPTION(); + DoString(R_OUTSD);break; CASE_D(0x70) /* JO */ JumpCond32_b(TFLG_O);break; CASE_D(0x71) /* JNO */ @@ -379,21 +387,17 @@ CASE_D(0x9a) /* CALL FAR Ad */ { Bit32u newip=Fetchd();Bit16u newcs=Fetchw(); - LEAVECORE; - CPU_CALL(true,newcs,newip,core.ip_lookup-core.op_start); - goto decode_start; + FillFlags(); + CPU_CALL(true,newcs,newip,GETIP); + continue; } CASE_D(0x9c) /* PUSHFD */ FillFlags(); - Push_32(reg_flags); + if (CPU_PUSHF(true)) RUNEXCEPTION(); break; CASE_D(0x9d) /* POPFD */ - if ((reg_flags & FLAG_VM) && ((reg_flags & FLAG_IOPL)!=FLAG_IOPL)) { - LEAVECORE;reg_eip-=core.ip_lookup-core.op_start; - CPU_Exception(13,0); - goto decode_start; - } - SETFLAGSd(Pop_32()) + if (CPU_POPF(true)) RUNEXCEPTION(); + lflags.type=t_UNKNOWN; #if CPU_TRAP_CHECK if (GETFLAG(TF)) { cpudecoder=CPU_Core_Normal_Trap_Run; @@ -403,7 +407,6 @@ #if CPU_PIC_CHECK if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; #endif - break; CASE_D(0xa1) /* MOV EAX,Od */ { @@ -448,25 +451,23 @@ CASE_D(0xc1) /* GRP2 Ed,Ib */ GRP2D(Fetchb());break; CASE_D(0xc2) /* RETN Iw */ - { - Bit16u addsp=Fetchw(); - SETIP(Pop_32());reg_esp+=addsp; - break; - } + reg_eip=Pop_32(); + reg_esp+=Fetchw(); + continue; CASE_D(0xc3) /* RETN */ - SETIP(Pop_32()); - break; + reg_eip=Pop_32(); + continue; CASE_D(0xc4) /* LES */ { GetRMrd;GetEAa; - LOADSEG(es,LoadMw(eaa+4)); + if (CPU_SetSegGeneral(es,LoadMw(eaa+4))) RUNEXCEPTION(); *rmrd=LoadMd(eaa); break; } CASE_D(0xc5) /* LDS */ { GetRMrd;GetEAa; - LOADSEG(ds,LoadMw(eaa+4)); + if (CPU_SetSegGeneral(ds,LoadMw(eaa+4))) RUNEXCEPTION(); *rmrd=LoadMd(eaa); break; } @@ -479,36 +480,11 @@ } CASE_D(0xc8) /* ENTER Iw,Ib */ { - Bitu bytes=Fetchw();Bitu level=Fetchb() & 0x1f; - Bitu frame_ptr=reg_esp-4; - if (cpu.stack.big) { - reg_esp-=4; - mem_writed(SegBase(ss)+reg_esp,reg_ebp); - for (Bitu i=1;i= 0xc0 ) {GetEArd;Push_32(GETIP);SETIP(*eard);} - else {GetEAa;Push_32(GETIP);SETIP(LoadMd(eaa));} - break; + if (rm >= 0xc0 ) {GetEArd;reg_eip=*eard;} + else {GetEAa;reg_eip=LoadMd(eaa);} + Push_32(GETIP); + continue; case 0x03: /* CALL FAR Ed */ { GetEAa; Bit32u newip=LoadMd(eaa); Bit16u newcs=LoadMw(eaa+4); - LEAVECORE; - CPU_CALL(true,newcs,newip,core.ip_lookup-core.op_start); - goto decode_start; + FillFlags(); + CPU_CALL(true,newcs,newip,GETIP); + continue; } - break; case 0x04: /* JMP NEAR Ed */ - if (rm >= 0xc0 ) {GetEArd;SETIP(*eard);} - else {GetEAa;SETIP(LoadMd(eaa));} - break; + if (rm >= 0xc0 ) {GetEArd;reg_eip=*eard;} + else {GetEAa;reg_eip=LoadMd(eaa);} + continue; case 0x05: /* JMP FAR Ed */ { GetEAa; Bit32u newip=LoadMd(eaa); Bit16u newcs=LoadMw(eaa+4); - LEAVECORE; - CPU_JMP(true,newcs,newip,core.ip_lookup-core.op_start); - goto decode_start; + FillFlags(); + CPU_JMP(true,newcs,newip,GETIP); + continue; } break; case 0x06: /* Push Ed */ diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 8c53663c..d9be36f5 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -159,7 +159,8 @@ CASE_0F_D(0xa0) /* PUSH FS */ Push_32(SegValue(fs));break; CASE_0F_D(0xa1) /* POP FS */ - POPSEG(fs,Pop_32(),4);break; + if (CPU_PopSeg(fs,true)) RUNEXCEPTION(); + break; CASE_0F_D(0xa3) /* BT Ed,Gd */ { FillFlags();GetRMrd; @@ -183,7 +184,8 @@ CASE_0F_D(0xa8) /* PUSH GS */ Push_32(SegValue(gs));break; CASE_0F_D(0xa9) /* POP GS */ - POPSEG(gs,Pop_32(),4);break; + if (CPU_PopSeg(gs,true)) RUNEXCEPTION(); + break; CASE_0F_D(0xab) /* BTS Ed,Gd */ { FillFlags();GetRMrd; @@ -215,7 +217,7 @@ CASE_0F_D(0xb2) /* LSS Ed */ { GetRMrd;GetEAa; - LOADSEG(ss,LoadMw(eaa+4)); + if (CPU_SetSegGeneral(ss,LoadMw(eaa+4))) RUNEXCEPTION(); *rmrd=LoadMd(eaa); break; } @@ -238,14 +240,14 @@ CASE_0F_D(0xb4) /* LFS Ed */ { GetRMrd;GetEAa; - LOADSEG(fs,LoadMw(eaa+4)); + if (CPU_SetSegGeneral(fs,LoadMw(eaa+4))) RUNEXCEPTION(); *rmrd=LoadMd(eaa); break; } CASE_0F_D(0xb5) /* LGS Ed */ { GetRMrd;GetEAa; - LOADSEG(gs,LoadMw(eaa+4)); + if (CPU_SetSegGeneral(gs,LoadMw(eaa+4))) RUNEXCEPTION(); *rmrd=LoadMd(eaa); break; } diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 9e8a1b58..287254ec 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -31,7 +31,8 @@ CASE_W(0x06) /* PUSH ES */ Push_16(SegValue(es));break; CASE_W(0x07) /* POP ES */ - POPSEG(es,Pop_16(),2);break; + if (CPU_PopSeg(es,false)) RUNEXCEPTION(); + break; CASE_B(0x08) /* OR Eb,Gb */ RMEbGb(ORB);break; CASE_W(0x09) /* OR Ew,Gw */ @@ -65,7 +66,7 @@ CASE_W(0x16) /* PUSH SS */ Push_16(SegValue(ss));break; CASE_W(0x17) /* POP SS */ - POPSEG(ss,Pop_16(),2); + if (CPU_PopSeg(ss,false)) RUNEXCEPTION(); CPU_Cycles++; //Always do another instruction break; CASE_B(0x18) /* SBB Eb,Gb */ @@ -83,7 +84,7 @@ CASE_W(0x1e) /* PUSH DS */ Push_16(SegValue(ds));break; CASE_W(0x1f) /* POP DS */ - POPSEG(ds,Pop_16(),2); + if (CPU_PopSeg(ds,false)) RUNEXCEPTION(); break; CASE_B(0x20) /* AND Eb,Gb */ RMEbGb(ANDB);break; @@ -256,7 +257,7 @@ CASE_B(0x65) /* SEG GS: */ DO_PREFIX_SEG(gs);break; CASE_B(0x66) /* Operand Size Prefix */ - core.opcode_index=core.index_default^OPCODE_SIZE; + core.opcode_index=(cpu.code.big^0x1)*0x200; goto restart_opcode; CASE_B(0x67) /* Address Size Prefix */ DO_PREFIX_ADDR(); @@ -272,12 +273,16 @@ RMGwEwOp3(DIMULW,Fetchbs()); break; CASE_B(0x6c) /* INSB */ + if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION(); DoString(R_INSB);break; CASE_W(0x6d) /* INSW */ + if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION(); DoString(R_INSW);break; CASE_B(0x6e) /* OUTSB */ + if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION(); DoString(R_OUTSB);break; CASE_W(0x6f) /* OUTSW */ + if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION(); DoString(R_OUTSW);break; CASE_W(0x70) /* JO */ JumpCond16_b(TFLG_O);break; @@ -498,13 +503,10 @@ case 0x03: /* MOV DS,Ew */ case 0x05: /* MOV GS,Ew */ case 0x04: /* MOV FS,Ew */ - LOADSEG((SegNames)which,val); - break; - case 0x01: /* MOV CS,Ew Illegal*/ - E_Exit("CPU:Illegal MOV CS Call"); + if (CPU_SetSegGeneral((SegNames)which,val)) RUNEXCEPTION(); break; default: - E_Exit("CPU:8E:Illegal RM Byte"); + goto illegal_opcode; } break; } @@ -546,24 +548,20 @@ break; CASE_W(0x9a) /* CALL Ap */ { + FillFlags(); Bit16u newip=Fetchw();Bit16u newcs=Fetchw(); - LEAVECORE; - CPU_CALL(false,newcs,newip,core.ip_lookup-core.op_start); - goto decode_start; + CPU_CALL(false,newcs,newip,GETIP); + continue; } CASE_B(0x9b) /* WAIT */ break; /* No waiting here */ CASE_W(0x9c) /* PUSHF */ FillFlags(); - Push_16(reg_flags); + if (CPU_PUSHF(false)) RUNEXCEPTION(); break; CASE_W(0x9d) /* POPF */ - if ((reg_flags & FLAG_VM) && ((reg_flags & FLAG_IOPL)!=FLAG_IOPL)) { - LEAVECORE;reg_eip-=core.ip_lookup-core.op_start; - CPU_Exception(13,0); - goto decode_start; - } - SETFLAGSw(Pop_16()); + if (CPU_POPF(false)) RUNEXCEPTION(); + lflags.type=t_UNKNOWN; #if CPU_TRAP_CHECK if (GETFLAG(TF)) { cpudecoder=CPU_Core_Normal_Trap_Run; @@ -666,25 +664,23 @@ CASE_W(0xc1) /* GRP2 Ew,Ib */ GRP2W(Fetchb());break; CASE_W(0xc2) /* RETN Iw */ - { - Bit16u addsp=Fetchw(); - SETIP(Pop_16());reg_esp+=addsp; - break; - } + reg_eip=Pop_16(); + reg_esp+=Fetchw(); + continue; CASE_W(0xc3) /* RETN */ - SETIP(Pop_16()); - break; + reg_eip=Pop_16(); + continue; CASE_W(0xc4) /* LES */ { GetRMrw;GetEAa; - LOADSEG(es,LoadMw(eaa+2)); + if (CPU_SetSegGeneral(es,LoadMw(eaa+2))) RUNEXCEPTION(); *rmrw=LoadMw(eaa); break; } CASE_W(0xc5) /* LDS */ { GetRMrw;GetEAa; - LOADSEG(ds,LoadMw(eaa+2)); + if (CPU_SetSegGeneral(ds,LoadMw(eaa+2))) RUNEXCEPTION(); *rmrw=LoadMw(eaa); break; } @@ -704,36 +700,11 @@ } CASE_W(0xc8) /* ENTER Iw,Ib */ { - Bitu bytes=Fetchw();Bitu level=Fetchb() & 0x1f; - Bitu frame_ptr=reg_esp-2; - if (cpu.stack.big) { - reg_esp-=2; - mem_writew(SegBase(ss)+reg_esp,reg_bp); - for (Bitu i=1;i= 0xc0 ) {GetEArw;Push_16((Bit16u)GETIP);SETIP(*earw);} - else {GetEAa;Push_16((Bit16u)GETIP);SETIP(LoadMw(eaa));} - break; + if (rm >= 0xc0 ) {GetEArw;reg_eip=*earw;} + else {GetEAa;reg_eip=LoadMw(eaa);} + Push_16(GETIP); + continue; case 0x03: /* CALL Ep */ { GetEAa; Bit16u newip=LoadMw(eaa); Bit16u newcs=LoadMw(eaa+2); - LEAVECORE; - CPU_CALL(false,newcs,newip,core.ip_lookup-core.op_start); - goto decode_start; + FillFlags(); + CPU_CALL(false,newcs,newip,GETIP); + continue; } break; case 0x04: /* JMP Ev */ - if (rm >= 0xc0 ) {GetEArw;SETIP(*earw);} - else {GetEAa;SETIP(LoadMw(eaa));} - break; + if (rm >= 0xc0 ) {GetEArw;reg_eip=*earw;} + else {GetEAa;reg_eip=LoadMw(eaa);} + continue; case 0x05: /* JMP Ep */ { GetEAa; Bit16u newip=LoadMw(eaa); Bit16u newcs=LoadMw(eaa+2); - LEAVECORE; - CPU_JMP(false,newcs,newip,core.ip_lookup-core.op_start); - goto decode_start; + FillFlags(); + CPU_JMP(false,newcs,newip,GETIP); + continue; } break; case 0x06: /* PUSH Ev */ diff --git a/src/cpu/core_normal/string.h b/src/cpu/core_normal/string.h index c2f3013e..45a61474 100644 --- a/src/cpu/core_normal/string.h +++ b/src/cpu/core_normal/string.h @@ -20,18 +20,11 @@ static void DoString(STRING_OP type) { if (TEST_PREFIX_SEG) si_base=core.seg_prefix_base; else si_base=SegBase(ds); di_base=SegBase(es); - if (TEST_PREFIX_ADDR) { - add_mask=0xFFFFFFFF; - si_index=reg_esi; - di_index=reg_edi; - count=reg_ecx; - } else { - add_mask=0xFFFF; - si_index=reg_si; - di_index=reg_di; - count=reg_cx; - } - if (!(TEST_PREFIX_REP)) { + add_mask=AddrMaskTable[core.prefixes& PREFIX_ADDR]; + si_index=reg_esi & add_mask; + di_index=reg_edi & add_mask; + count=reg_ecx & add_mask; + if (!TEST_PREFIX_REP) { count=1; } else { CPU_Cycles++; @@ -40,7 +33,7 @@ static void DoString(STRING_OP type) { count_left=count-CPU_Cycles; count=CPU_Cycles; CPU_Cycles=0; - core.ip_lookup=core.op_start; //Reset IP to start of instruction + LOADIP; //RESET IP to the start } else { /* Won't interrupt scas and cmps instruction since they can interrupt themselves */ count_left=0; diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index e9ce3c8e..8f25ef4c 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -16,57 +16,36 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define SETIP(_a_) (core.ip_lookup=SegBase(cs)+_a_) -#define GETIP (Bit32u)(core.ip_lookup-SegBase(cs)) -#define SAVEIP {reg_eip=GETIP;} -#define LOADIP {core.ip_lookup=(SegBase(cs)+reg_eip);} +#define GETIP (core.cseip-SegBase(cs)) +#define SAVEIP reg_eip=GETIP; +#define LOADIP core.cseip=(SegBase(cs)+reg_eip); -#define LEAVECORE \ - SAVEIP; \ - FillFlags(); - -static INLINE void ADDIPw(Bits add) { - SAVEIP; - reg_eip=(Bit16u)(reg_eip+add); - LOADIP; -} - -static INLINE void ADDIPd(Bits add) { - SAVEIP; - reg_eip=(reg_eip+add); - LOADIP; -} - -static INLINE void ADDIPFAST(Bits blah) { -// core.ip_lookup+=blah; - SAVEIP; - reg_eip=(reg_eip+blah); - LOADIP; +#define RUNEXCEPTION() { \ + FillFlags(); \ + CPU_Exception(cpu.exception.which,cpu.exception.error); \ + continue; \ } #define EXCEPTION(blah) \ { \ - Bit8u new_num=blah; \ - core.ip_lookup=core.op_start; \ - LEAVECORE; \ - CPU_Exception(new_num); \ - goto decode_start; \ + CPU_Exception(blah); \ + continue; \ } static INLINE Bit8u Fetchb() { - Bit8u temp=LoadMb(core.ip_lookup); - core.ip_lookup+=1; + Bit8u temp=LoadMb(core.cseip); + core.cseip+=1; return temp; } static INLINE Bit16u Fetchw() { - Bit16u temp=LoadMw(core.ip_lookup); - core.ip_lookup+=2; + Bit16u temp=LoadMw(core.cseip); + core.cseip+=2; return temp; } static INLINE Bit32u Fetchd() { - Bit32u temp=LoadMd(core.ip_lookup); - core.ip_lookup+=4; + Bit32u temp=LoadMd(core.cseip); + core.cseip+=4; return temp; } @@ -81,68 +60,40 @@ static INLINE Bit32s Fetchds() { return Fetchd(); } -#if 0 - -static INLINE void Push_16(Bit16u blah) { - reg_esp-=2; - SaveMw(SegBase(ss)+(reg_esp & cpu.stack.mask),blah); -}; - -static INLINE void Push_32(Bit32u blah) { - reg_esp-=4; - SaveMd(SegBase(ss)+(reg_esp & cpu.stack.mask),blah); -}; - -static INLINE Bit16u Pop_16() { - Bit16u temp=LoadMw(SegBase(ss)+(reg_esp & cpu.stack.mask)); - reg_esp+=2; - return temp; -}; - -static INLINE Bit32u Pop_32() { - Bit32u temp=LoadMd(SegBase(ss)+(reg_esp & cpu.stack.mask)); - reg_esp+=4; - return temp; -}; - -#else - #define Push_16 CPU_Push16 #define Push_32 CPU_Push32 #define Pop_16 CPU_Pop16 #define Pop_32 CPU_Pop32 -#endif - //TODO Could probably make all byte operands fast? -#define JumpCond16_b(blah) \ - if (blah) { \ - ADDIPw(Fetchbs()); \ - } else { \ - ADDIPFAST(1); \ - } +#define JumpCond16_b(COND) { \ + SAVEIP; \ + if (COND) reg_ip+=Fetchbs(); \ + reg_ip+=1; \ + continue; \ +} -#define JumpCond32_b(blah) \ - if (blah) { \ - ADDIPd(Fetchbs()); \ - } else { \ - ADDIPFAST(1); \ - } +#define JumpCond16_w(COND) { \ + SAVEIP; \ + if (COND) reg_ip+=Fetchws(); \ + reg_ip+=2; \ + continue; \ +} -#define JumpCond16_w(blah) \ - if (blah) { \ - ADDIPw(Fetchws()); \ - } else { \ - ADDIPFAST(2); \ - } +#define JumpCond32_b(COND) { \ + SAVEIP; \ + if (COND) reg_eip+=Fetchbs(); \ + reg_eip+=1; \ + continue; \ +} +#define JumpCond32_d(COND) { \ + SAVEIP; \ + if (COND) reg_eip+=Fetchds(); \ + reg_eip+=4; \ + continue; \ +} -#define JumpCond32_d(blah) \ - if (blah) { \ - ADDIPd(Fetchds()); \ - } else { \ - ADDIPFAST(4); \ - } #define SETcc(cc) \ { \ diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 546022b4..097e3ce0 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.55 2004-03-31 17:24:30 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.56 2004-04-22 22:40:45 harekiet Exp $ */ #include #include "dosbox.h" @@ -46,10 +46,6 @@ Bits CPU_CycleUp = 0; Bits CPU_CycleDown = 0; CPU_Decoder * cpudecoder; -static struct { - Bitu which,errorcode; -} exception; - void CPU_Core_Full_Init(void); void CPU_Core_Normal_Init(void); void CPU_Core_Dyn_X86_Init(void); @@ -91,28 +87,48 @@ void CPU_SetFlags(Bitu word,Bitu mask) { cpu.direction=1-((reg_flags & FLAG_DF) >> 9); } -bool CPU_CLI(Bitu opLen) { +static bool CPU_PrepareException(Bitu which,Bitu error) { + cpu.exception.which=which; + cpu.exception.error=error; + return true; +} + +bool CPU_CLI(void) { if (cpu.pmode && ((!GETFLAG(VM) && (GETFLAG_IOPL=8) ? CPU_INT_HAS_ERROR : 0)); -} - -void CPU_SetupException(Bitu which,Bitu error) { - cpu.exception.which=which; - cpu.exception.error=error; +bool CPU_IO_Exception(Bitu port,Bitu size) { + if (cpu.pmode && ((GETFLAG_IOPLcpu_tss.limit) goto doexception; + where=cpu_tss.base+ofs+(port/8); + Bitu map=mem_readw(where); + Bitu mask=(0xffff>>(16-size)) << (port&7); + if (map & mask) goto doexception; + } + return false; +doexception: + LOG_MSG("Exception"); + return CPU_PrepareException(13,0); } void CPU_Exception(Bitu which,Bitu error ) { -// LOG_MSG("Exception %d CS:%X IP:%X FLAGS:%X",num,SegValue(cs),reg_eip,reg_flags); - CPU_SetupException(which,error); - CPU_StartException(); + LOG_MSG("Exception %d error %x",which,error); + cpu.exception.error=error; + CPU_Interrupt(which,CPU_INT_EXCEPTION | ((which>=8) ? CPU_INT_HAS_ERROR : 0),reg_eip); } Bit8u lastint; -void CPU_Interrupt(Bitu num,Bitu type,Bitu opLen) { +void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { lastint=num; #if C_DEBUG switch (num) { @@ -324,10 +348,10 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu opLen) { }; #endif if (!cpu.pmode) { - /* Save everything on a 16-bit stack */ + /* Save everything on a 16-bit stack */ CPU_Push16(reg_flags & 0xffff); CPU_Push16(SegValue(cs)); - CPU_Push16(reg_ip); + CPU_Push16(oldeip); SETFLAGBIT(IF,false); SETFLAGBIT(TF,false); /* Get the new CS:IP from vector table */ @@ -345,7 +369,6 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu opLen) { if ((reg_flags & FLAG_VM) && (type&CPU_INT_SOFTWARE)) { // LOG_MSG("Software int in v86, AH %X IOPL %x",reg_ah,(reg_flags & FLAG_IOPL) >>12); if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) { - reg_eip-=opLen; CPU_Exception(13,0); return; } @@ -354,7 +377,6 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu opLen) { //TODO Check for software interrupt and check gate's dpl=0;i--) CPU_Push32(mem_readd(o_stack+i*4)); CPU_Push32(SegValue(cs)); - CPU_Push32(reg_eip); + CPU_Push32(oldeip); } else { CPU_Push16(o_ss); //save old stack CPU_Push16(o_esp); @@ -746,7 +764,7 @@ call_code: for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--) CPU_Push16(mem_readw(o_stack+i*2)); CPU_Push16(SegValue(cs)); - CPU_Push16(reg_eip); + CPU_Push16(oldeip); } cpu.cpl = n_cs_desc.DPL(); @@ -770,7 +788,7 @@ call_gate_same_privilege: if (call.DPL()DESC_DATA_ED_RW_A)) { - CPU_SetupException(0x0D,value & 0xfffc); - return true; + return CPU_PrepareException(0x0D,value & 0xfffc); } } } @@ -1191,6 +1205,14 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) { } } +bool CPU_PopSeg(SegNames seg,bool use32) { + Bitu val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); + if (CPU_SetSegGeneral(seg,val)) return true; + Bitu addsp=2 << use32; + reg_esp=(reg_esp&~cpu.stack.mask)|((reg_esp+addsp)&cpu.stack.mask); + return false; +} + void CPU_CPUID(void) { switch (reg_eax) { case 0: /* Vendor ID String and maximum level? */ @@ -1221,12 +1243,12 @@ static Bits HLT_Decode(void) { return 0; } -void CPU_HLT(Bitu opLen) { +void CPU_HLT(Bitu oldeip) { if (cpu.cpl) { - reg_eip-=opLen; CPU_Exception(13,0); return; } + reg_eip=oldeip; CPU_Cycles=0; cpu.hlt.cs=SegValue(cs); cpu.hlt.eip=reg_eip; @@ -1235,6 +1257,38 @@ void CPU_HLT(Bitu opLen) { return; } +void CPU_ENTER(bool use32,Bitu bytes,Bitu level) { + level&=0x1f; + Bitu sp_index=reg_esp&cpu.stack.mask; + Bitu bp_index=reg_ebp&cpu.stack.mask; + if (!use32) { + sp_index-=2; + mem_writew(SegPhys(ss)+sp_index,reg_bp); + reg_bp=(Bit16u)(reg_esp-2); + if (level) { + for (Bitu i=1;i(sec); reg_eax=0; From db7e1ea4da34dc3f49c07ff03241c5d61fb19d08 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 22 Apr 2004 22:41:46 +0000 Subject: [PATCH 1692/4131] Some changes for the new handler functions Added some more opcodes to dynamic generator Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1774 --- src/cpu/core_dyn_x86.cpp | 21 +- src/cpu/core_dyn_x86/decoder.h | 444 +++++++++++++++++++------------- src/cpu/core_dyn_x86/risc_x86.h | 58 ++--- src/cpu/core_dyn_x86/string.h | 4 +- 4 files changed, 293 insertions(+), 234 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 4fa737f2..a4e87ce1 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -78,7 +78,7 @@ enum ShiftOps { SHIFT_ROL,SHIFT_ROR, SHIFT_RCL,SHIFT_RCR, SHIFT_SHL,SHIFT_SHR, - SHIFT_SAR, + SHIFT_SAL,SHIFT_SAR, }; enum BranchTypes { @@ -150,28 +150,23 @@ struct DynState { DynReg regs[G_MAX]; }; -static void dyn_releaseregs(void) { - for (Bitu i=0;iregs[i].flags=DynRegs[i].flags; diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 4212f92e..519f44c3 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -107,14 +107,42 @@ static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { else gen_call_function((void *)&mem_writew,"%Dd%Dw",addr,val); } - static void dyn_reduce_cycles(void) { - + gen_protectflags(); if (!decode.cycles) decode.cycles++; - gen_lea(DREG(CYCLES),DREG(CYCLES),0,0,-(Bits)decode.cycles); + gen_dop_word_imm(DOP_SUB,true,DREG(CYCLES),decode.cycles); +} + +static void dyn_save_critical_regs(void) { + gen_releasereg(DREG(EAX)); + gen_releasereg(DREG(ECX)); + gen_releasereg(DREG(EDX)); + gen_releasereg(DREG(EBX)); + gen_releasereg(DREG(ESP)); + gen_releasereg(DREG(EBP)); + gen_releasereg(DREG(ESI)); + gen_releasereg(DREG(EDI)); + gen_releasereg(DREG(FLAGS)); + gen_releasereg(DREG(EIP)); gen_releasereg(DREG(CYCLES)); } +static void dyn_set_eip_last_end(DynReg * endreg) { + gen_protectflags(); + gen_lea(endreg,DREG(EIP),0,0,decode.code-decode.code_start); + gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),decode.op_start-decode.code_start); +} + +static INLINE void dyn_set_eip_end(void) { + gen_protectflags(); + gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),decode.code-decode.code_start); +} + +static INLINE void dyn_set_eip_last(void) { + gen_protectflags(); + gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),decode.op_start-decode.code_start); +} + static void dyn_push(DynReg * dynreg) { gen_protectflags(); if (decode.big_op) { @@ -502,69 +530,61 @@ static void dyn_grp1_ev_ivx(bool withbyte) { } } - -static ShiftOps grp2_table[8]={ - SHIFT_ROL,SHIFT_ROR,SHIFT_RCL,SHIFT_RCR, - SHIFT_SHL,SHIFT_SHR,SHIFT_SHL,SHIFT_SAR -}; - enum grp2_types { grp2_1,grp2_imm,grp2_cl, }; static void dyn_grp2_eb(grp2_types type) { - dyn_get_modrm(); + dyn_get_modrm();DynReg * src;Bit8u src_i; if (decode.modrm.mod<3) { - dyn_fill_ea(); - dyn_read_byte(DREG(EA),DREG(TMPB),false); - DynReg * shift; - switch (type) { - case grp2_cl:shift=DREG(ECX);break; - case grp2_1:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,1);break; - case grp2_imm:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,decode_fetchb());break; - } - gen_needflags(); - gen_shift_byte(grp2_table[decode.modrm.reg],shift,DREG(TMPB),0); - dyn_write_byte(DREG(EA),DREG(TMPB),false); - gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB));gen_releasereg(DREG(SHIFT)); + dyn_fill_ea();dyn_read_byte(DREG(EA),DREG(TMPB),false); + src=DREG(TMPB); + src_i=0; } else { - DynReg * shift; - switch (type) { - case grp2_cl:shift=DREG(ECX);break; - case grp2_1:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,1);break; - case grp2_imm:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,decode_fetchb());break; - } - gen_needflags(); - gen_shift_byte(grp2_table[decode.modrm.reg],shift,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); - gen_releasereg(DREG(SHIFT)); + src=&DynRegs[decode.modrm.rm&3]; + src_i=decode.modrm.rm&4; + } + gen_needflags(); + switch (type) { + case grp2_1: + gen_shift_byte_imm(decode.modrm.reg,src,src_i,1); + break; + case grp2_imm: + gen_shift_byte_imm(decode.modrm.reg,src,src_i,decode_fetchb()); + break; + case grp2_cl: + gen_shift_byte_cl (decode.modrm.reg,src,src_i,DREG(ECX)); + break; + } + if (decode.modrm.mod<3) { + dyn_write_byte(DREG(EA),src,false); + gen_releasereg(DREG(EA));gen_releasereg(src); } } static void dyn_grp2_ev(grp2_types type) { - dyn_get_modrm(); + dyn_get_modrm();DynReg * src; if (decode.modrm.mod<3) { - dyn_fill_ea(); - dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); - DynReg * shift; - switch (type) { - case grp2_cl:shift=DREG(ECX);break; - case grp2_1:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,1);break; - case grp2_imm:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,decode_fetchb());break; - } - gen_needflags(); - gen_shift_word(grp2_table[decode.modrm.reg],shift,decode.big_op,DREG(TMPW)); - dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); - gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPW));gen_releasereg(DREG(SHIFT)); + dyn_fill_ea();dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); + src=DREG(TMPW); } else { - DynReg * shift; - switch (type) { - case grp2_cl:shift=DREG(ECX);break; - case grp2_1:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,1);break; - case grp2_imm:shift=DREG(SHIFT);gen_dop_byte_imm(DOP_MOV,DREG(SHIFT),0,decode_fetchb());break; - } - gen_needflags(); - gen_shift_word(grp2_table[decode.modrm.reg],shift,decode.big_op,&DynRegs[decode.modrm.rm]); - gen_releasereg(DREG(SHIFT)); + src=&DynRegs[decode.modrm.rm]; + } + gen_needflags(); + switch (type) { + case grp2_1: + gen_shift_word_imm(decode.modrm.reg,decode.big_op,src,1); + break; + case grp2_imm: + gen_shift_word_imm(decode.modrm.reg,decode.big_op,src,decode_fetchb()); + break; + case grp2_cl: + gen_shift_word_cl (decode.modrm.reg,decode.big_op,src,DREG(ECX)); + break; + } + if (decode.modrm.mod<3) { + dyn_write_word(DREG(EA),src,decode.big_op); + gen_releasereg(DREG(EA));gen_releasereg(src); } } @@ -607,11 +627,11 @@ static void dyn_grp3_eb(void) { branch=gen_create_branch(BR_Z); dyn_savestate(&state); dyn_reduce_cycles(); - gen_lea(DREG(EIP),DREG(EIP),0,0,decode.op_start-decode.code_start); - dyn_save_flags(); - dyn_releaseregs(); + dyn_set_eip_last(); + dyn_flags_gen_to_host(); + dyn_save_critical_regs(); gen_call_function((void *)&CPU_Exception,"%Id%Id",0,0); - dyn_load_flags(); + dyn_flags_host_to_gen(); gen_return(BR_Normal); dyn_loadstate(&state); gen_fill_branch(branch); @@ -660,11 +680,11 @@ static void dyn_grp3_ev(void) { branch=gen_create_branch(BR_Z); dyn_savestate(&state); dyn_reduce_cycles(); - gen_lea(DREG(EIP),DREG(EIP),0,0,decode.op_start-decode.code_start); - dyn_save_flags(); - dyn_releaseregs(); + dyn_set_eip_last(); + dyn_flags_gen_to_host(); + dyn_save_critical_regs(); gen_call_function((void *)&CPU_Exception,"%Id%Id",0,0); - dyn_load_flags(); + dyn_flags_host_to_gen(); gen_return(BR_Normal); dyn_loadstate(&state); gen_fill_branch(branch); @@ -689,28 +709,34 @@ static void dyn_mov_ev_seg(void) { gen_releasereg(DREG(TMPW)); } -static void dyn_load_seg(SegNames seg,DynReg * src,bool withpop) { +static void dyn_synch_eip(void) { + gen_protectflags(); + gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),decode.code-decode.code_start); +} + +static void DynRunException(void) { + CPU_Exception(cpu.exception.which,cpu.exception.error); +} +static void dyn_check_bool_exception(DynReg * check) { + Bit8u * branch;DynState state; + gen_dop_byte(DOP_OR,check,0,check,0); + branch=gen_create_branch(BR_Z); + dyn_savestate(&state); + dyn_flags_gen_to_host(); + dyn_reduce_cycles(); + dyn_set_eip_last(); + dyn_save_critical_regs(); + gen_call_function(&DynRunException,""); + gen_return(BR_Normal); + dyn_loadstate(&state); + gen_fill_branch(branch); +} + +static void dyn_load_seg(SegNames seg,DynReg * src) { if (cpu.pmode) { - Bit8u * branch;DynState state; - gen_protectflags(); gen_call_function((void *)&CPU_SetSegGeneral,"%Rd%Id%Drw",DREG(TMPB),seg,src); - gen_dop_byte(DOP_OR,DREG(TMPB),0,DREG(TMPB),0); - branch=gen_create_branch(BR_Z); - dyn_savestate(&state); - dyn_reduce_cycles(); - if (withpop) gen_dop_word_imm(DOP_SUB,true,DREG(ESP),decode.big_op ? 4 : 2); - gen_dop_word_imm(DOP_ADD,true,DREG(EIP),decode.op_start-decode.code_start); - dyn_save_flags(); - dyn_releaseregs(); - gen_call_function((void *)&CPU_StartException,""); - dyn_load_flags(); - gen_return(BR_Normal); - dyn_loadstate(&state); - gen_fill_branch(branch); - } else { - //TODO Maybe just calculate the base directly if in realmode - gen_call_function((void *)&CPU_SetSegGeneral,"%Id%Drw",seg,src); - } + dyn_check_bool_exception(DREG(TMPB)); + } else gen_call_function((void *)CPU_SetSegGeneral,"%Id%Drw",seg,src); gen_releasereg(&DynRegs[G_ES+seg]); if (seg==ss) gen_releasereg(DREG(SMASK)); } @@ -721,7 +747,7 @@ static void dyn_load_seg_off_ea(SegNames seg) { dyn_fill_ea(); gen_lea(DREG(TMPW),DREG(EA),0,0,decode.big_op ? 4:2); dyn_read_word(DREG(TMPW),DREG(TMPW),false); - dyn_load_seg(seg,DREG(TMPW),false);gen_releasereg(DREG(TMPW)); + dyn_load_seg(seg,DREG(TMPW));gen_releasereg(DREG(TMPW)); dyn_read_word(DREG(EA),&DynRegs[decode.modrm.reg],decode.big_op); gen_releasereg(DREG(EA)); } else { @@ -736,10 +762,10 @@ static void dyn_mov_seg_ev(void) { if (decode.modrm.mod<3) { dyn_fill_ea(); dyn_read_word(DREG(EA),DREG(EA),false); - dyn_load_seg(seg,DREG(EA),false); + dyn_load_seg(seg,DREG(EA)); gen_releasereg(DREG(EA)); } else { - dyn_load_seg(seg,&DynRegs[decode.modrm.rm],false); + dyn_load_seg(seg,&DynRegs[decode.modrm.rm]); } } @@ -750,9 +776,18 @@ static void dyn_push_seg(SegNames seg) { } static void dyn_pop_seg(SegNames seg) { - dyn_pop(DREG(TMPW)); - dyn_load_seg(seg,DREG(TMPW),true); - gen_releasereg(DREG(TMPW)); + if (!cpu.pmode) { + dyn_pop(DREG(TMPW)); + dyn_load_seg(seg,DREG(TMPW)); + gen_releasereg(DREG(TMPW)); + } else { + gen_releasereg(DREG(ESP)); + gen_call_function((void *)&CPU_PopSeg,"%Rd%Id%Id",DREG(TMPB),seg,decode.big_op); + dyn_check_bool_exception(DREG(TMPB)); + gen_releasereg(&DynRegs[G_ES+seg]); + gen_releasereg(DREG(ESP)); + if (seg==ss) gen_releasereg(DREG(SMASK)); + } } static void dyn_pop_ev(void) { @@ -768,6 +803,14 @@ static void dyn_pop_ev(void) { gen_releasereg(DREG(TMPW)); } +static void dyn_enter(void) { + gen_releasereg(DREG(ESP)); + gen_releasereg(DREG(EBP)); + Bitu bytes=decode_fetchw(); + Bitu level=decode_fetchb(); + gen_call_function(&CPU_ENTER,"%Id%Id%Id",decode.big_op,bytes,level); +} + static void dyn_leave(void) { gen_protectflags(); gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(SMASK)); @@ -792,71 +835,87 @@ static void dyn_closeblock(void) { } static void dyn_normal_exit(BlockReturn code) { - gen_lea(DREG(EIP),DREG(EIP),0,0,decode.code-decode.code_start); + gen_protectflags(); dyn_reduce_cycles(); - dyn_releaseregs(); + dyn_set_eip_last(); + dyn_save_critical_regs(); gen_return(code); dyn_closeblock(); } -static void dyn_exit_link(bool dword,Bits eip_change) { +static void dyn_exit_link(Bits eip_change) { gen_protectflags(); - gen_lea(DREG(EIP),DREG(EIP),0,0,(decode.code-decode.code_start)+eip_change); - if (!dword) gen_extend_word(false,DREG(EIP),DREG(EIP)); + gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),(decode.code-decode.code_start)+eip_change); dyn_reduce_cycles(); - dyn_releaseregs(); + dyn_save_critical_regs(); gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); dyn_closeblock(); } static void dyn_branched_exit(BranchTypes btype,Bit32s eip_add) { - dyn_reduce_cycles(); - dyn_releaseregs(); Bitu eip_base=decode.code-decode.code_start; - gen_needflags();gen_protectflags(); + dyn_reduce_cycles(); + dyn_save_critical_regs(); + gen_needflags(); + gen_protectflags(); Bit8u * data=gen_create_branch(btype); /* Branch not taken */ - gen_lea(DREG(EIP),DREG(EIP),0,0,eip_base); + gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),eip_base); gen_releasereg(DREG(EIP)); gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); gen_fill_branch(data); /* Branch taken */ - gen_lea(DREG(EIP),DREG(EIP),0,0,eip_base+eip_add); + gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),eip_base+eip_add); gen_releasereg(DREG(EIP)); gen_jmp_ptr(&decode.block->link[1].to,offsetof(CacheBlock,cache.start)); dyn_closeblock(); } enum LoopTypes { - LOOP_NONE,LOOP_NE,LOOP_E, + LOOP_NONE,LOOP_NE,LOOP_E,LOOP_JCXZ }; static void dyn_loop(LoopTypes type) { - gen_protectflags(); + dyn_reduce_cycles(); Bits eip_add=(Bit8s)decode_fetchb(); Bitu eip_base=decode.code-decode.code_start; - dyn_reduce_cycles(); - Bit8u * branch1; - Bit8u * branch2=0; - gen_sop_word(SOP_DEC,decode.big_addr,DREG(ECX)); - dyn_releaseregs(); - branch1=gen_create_branch(BR_Z); + Bit8u * branch1=0;Bit8u * branch2=0; + dyn_save_critical_regs(); switch (type) { - case LOOP_NONE: - break; case LOOP_E: - branch2=gen_create_branch(BR_NZ); + gen_needflags(); + branch1=gen_create_branch(BR_NZ); break; case LOOP_NE: + gen_needflags(); + branch1=gen_create_branch(BR_Z); + break; + } + gen_protectflags(); + switch (type) { + case LOOP_E: + case LOOP_NE: + case LOOP_NONE: + gen_sop_word(SOP_DEC,decode.big_addr,DREG(ECX)); + gen_releasereg(DREG(ECX)); branch2=gen_create_branch(BR_Z); break; + case LOOP_JCXZ: + gen_dop_word(DOP_OR,decode.big_addr,DREG(ECX),DREG(ECX)); + gen_releasereg(DREG(ECX)); + branch2=gen_create_branch(BR_NZ); + break; } gen_lea(DREG(EIP),DREG(EIP),0,0,eip_base+eip_add); gen_releasereg(DREG(EIP)); gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); - gen_fill_branch(branch1); - if (branch2) gen_fill_branch(branch2); + if (branch1) { + gen_fill_branch(branch1); + gen_sop_word(SOP_DEC,decode.big_addr,DREG(ECX)); + gen_releasereg(DREG(ECX)); + } /* Branch taken */ + gen_fill_branch(branch2); gen_lea(DREG(EIP),DREG(EIP),0,0,eip_base); gen_releasereg(DREG(EIP)); gen_jmp_ptr(&decode.block->link[1].to,offsetof(CacheBlock,cache.start)); @@ -866,24 +925,9 @@ static void dyn_loop(LoopTypes type) { static void dyn_ret_near(Bitu bytes) { gen_protectflags(); dyn_reduce_cycles(); -//TODO maybe AND eip 0xffff, but shouldn't be needed dyn_pop(DREG(EIP)); if (bytes) gen_dop_word_imm(DOP_ADD,true,DREG(ESP),bytes); - dyn_releaseregs(); - gen_return(BR_Normal); - dyn_closeblock(); -} - -static void dyn_ret_far(Bitu bytes) { - gen_protectflags(); - dyn_reduce_cycles(); -//TODO maybe AND eip 0xffff, but shouldn't be needed - gen_lea(DREG(EIP),DREG(EIP),0,0,decode.code-decode.code_start); - dyn_save_flags(); - dyn_releaseregs(); - gen_call_function((void*)&CPU_RET,"%Id%Id%Id",decode.big_op,bytes,decode.code-decode.op_start); - dyn_load_flags(); - dyn_releaseregs();; + dyn_save_critical_regs(); gen_return(BR_Normal); dyn_closeblock(); } @@ -892,29 +936,37 @@ static void dyn_call_near_imm(void) { Bits imm; if (decode.big_op) imm=(Bit32s)decode_fetchd(); else imm=(Bit16s)decode_fetchw(); - gen_lea(DREG(EIP),DREG(EIP),0,0,decode.code-decode.code_start); + dyn_set_eip_end(); dyn_push(DREG(EIP)); - gen_lea(DREG(EIP),DREG(EIP),0,0,imm); - if (!decode.big_op) gen_extend_word(false,DREG(EIP),DREG(EIP)); + gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),imm); dyn_reduce_cycles(); - dyn_releaseregs(); -// gen_return(BR_Normal); + dyn_save_critical_regs(); gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); dyn_closeblock(); } +static void dyn_ret_far(Bitu bytes) { + gen_protectflags(); + dyn_reduce_cycles(); + dyn_set_eip_last_end(DREG(TMPW)); + dyn_flags_gen_to_host(); + dyn_save_critical_regs(); + gen_call_function((void*)&CPU_RET,"%Id%Id%Drd",decode.big_op,bytes,DREG(TMPW)); + dyn_flags_host_to_gen(); + gen_return(BR_Normal); + dyn_closeblock(); +} + static void dyn_call_far_imm(void) { Bitu sel,off; - gen_protectflags(); off=decode.big_op ? decode_fetchd() : decode_fetchw(); sel=decode_fetchw(); dyn_reduce_cycles(); - gen_lea(DREG(EIP),DREG(EIP),0,0,decode.code-decode.code_start); - dyn_save_flags(); - dyn_releaseregs(); - gen_call_function((void*)&CPU_CALL,"%Id%Id%Id%Id",decode.big_op,sel,off,decode.code-decode.op_start); - dyn_load_flags(); - dyn_releaseregs(); + dyn_set_eip_last_end(DREG(TMPW)); + dyn_flags_gen_to_host(); + dyn_save_critical_regs(); + gen_call_function((void*)&CPU_CALL,"%Id%Id%Id%Drd",decode.big_op,sel,off,DREG(TMPW)); + dyn_flags_host_to_gen(); gen_return(BR_Normal); dyn_closeblock(); } @@ -925,42 +977,41 @@ static void dyn_jmp_far_imm(void) { off=decode.big_op ? decode_fetchd() : decode_fetchw(); sel=decode_fetchw(); dyn_reduce_cycles(); - gen_lea(DREG(EIP),DREG(EIP),0,0,decode.code-decode.code_start); - dyn_save_flags(); - dyn_releaseregs(); - gen_call_function((void*)&CPU_JMP,"%Id%Id%Id%Id",decode.big_op,sel,off,decode.code-decode.op_start); - dyn_load_flags(); - dyn_releaseregs(); + dyn_set_eip_last_end(DREG(TMPW)); + dyn_flags_gen_to_host(); + dyn_save_critical_regs(); + gen_call_function((void*)&CPU_JMP,"%Id%Id%Id%Drd",decode.big_op,sel,off,DREG(TMPW)); + dyn_flags_host_to_gen(); gen_return(BR_Normal); dyn_closeblock(); } static void dyn_iret(void) { gen_protectflags(); - dyn_save_flags(); + dyn_flags_gen_to_host(); dyn_reduce_cycles(); - gen_dop_word_imm(DOP_ADD,true,DREG(EIP),decode.code-decode.code_start); - dyn_releaseregs(); - gen_call_function((void*)&CPU_IRET,"%Id%Id",decode.big_op,decode.code-decode.op_start); - dyn_load_flags(); - dyn_releaseregs(); + dyn_set_eip_last_end(DREG(TMPW)); + dyn_save_critical_regs(); + gen_call_function((void*)&CPU_IRET,"%Id%Drd",decode.big_op,DREG(TMPW)); + dyn_flags_host_to_gen(); gen_return(BR_Normal); dyn_closeblock(); } static void dyn_interrupt(Bitu num) { gen_protectflags(); - dyn_save_flags(); + dyn_flags_gen_to_host(); dyn_reduce_cycles(); - gen_dop_word_imm(DOP_ADD,true,DREG(EIP),decode.code-decode.code_start); - dyn_releaseregs(); - gen_call_function((void*)&CPU_Interrupt,"%Id%Id%Id",num,CPU_INT_SOFTWARE,decode.code-decode.op_start); - dyn_load_flags(); - dyn_releaseregs(); + dyn_set_eip_last_end(DREG(TMPW)); + dyn_save_critical_regs(); + gen_call_function((void*)&CPU_Interrupt,"%Id%Id%Drd",num,CPU_INT_SOFTWARE,DREG(TMPW)); + dyn_flags_host_to_gen(); gen_return(BR_Normal); dyn_closeblock(); } +static counter=0; + static CacheBlock * CreateCacheBlock(CodePageHandler * codepage,PhysPt start,Bitu max_opcodes) { Bits i; /* Init a load of variables */ @@ -1000,6 +1051,7 @@ static CacheBlock * CreateCacheBlock(CodePageHandler * codepage,PhysPt start,Bit restart_prefix: Bitu opcode=decode_fetchb(); switch (opcode) { + case 0x00:dyn_dop_ebgb(DOP_ADD);break; case 0x01:dyn_dop_evgv(DOP_ADD);break; case 0x02:dyn_dop_gbeb(DOP_ADD);break; @@ -1209,7 +1261,22 @@ restart_prefix: break; /* CALL FAR Ip */ case 0x9a:dyn_call_far_imm();goto finish_block; - /* MOV AL,direct addresses */ + case 0x9c: //PUSHF + gen_protectflags(); + gen_releasereg(DREG(ESP)); + dyn_flags_gen_to_host(); + gen_call_function(&CPU_PUSHF,"%Rd%Id",DREG(TMPB),decode.big_op); + if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); + gen_releasereg(DREG(TMPB)); + break; + case 0x9d: //POPF + gen_releasereg(DREG(ESP)); + gen_call_function(&CPU_POPF,"%Rd%Id",DREG(TMPB),decode.big_op); + if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); + dyn_flags_host_to_gen(); + gen_releasereg(DREG(TMPB)); + break; + /* MOV AL,direct addresses */ case 0xa0: gen_lea(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),0,0, decode.big_addr ? decode_fetchd() : decode_fetchw()); @@ -1257,7 +1324,6 @@ restart_prefix: case 0xb8:case 0xb9:case 0xba:case 0xbb:case 0xbc:case 0xbd:case 0xbe:case 0xbf: gen_dop_word_imm(DOP_MOV,decode.big_op,&DynRegs[opcode&7],decode.big_op ? decode_fetchd() : decode_fetchw());break; break; - //GRP2 Eb/Ev,Ib case 0xc0:dyn_grp2_eb(grp2_imm);break; case 0xc1:dyn_grp2_ev(grp2_imm);break; @@ -1270,7 +1336,8 @@ restart_prefix: // MOV Eb/Ev,Ib/Iv case 0xc6:dyn_mov_ebib();break; case 0xc7:dyn_mov_eviv();break; - // LEAVE + //ENTER and LEAVE + case 0xc8:dyn_enter();break; case 0xc9:dyn_leave();break; //RET far Iw / Ret case 0xca:dyn_ret_far(decode_fetchw());goto finish_block; @@ -1279,15 +1346,19 @@ restart_prefix: case 0xcd:dyn_interrupt(decode_fetchb());goto finish_block; /* IRET */ case 0xcf:dyn_iret();goto finish_block; + //GRP2 Eb/Ev,1 case 0xd0:dyn_grp2_eb(grp2_1);break; case 0xd1:dyn_grp2_ev(grp2_1);break; //GRP2 Eb/Ev,CL case 0xd2:dyn_grp2_eb(grp2_cl);break; case 0xd3:dyn_grp2_ev(grp2_cl);break; + //Loop's case 0xe2:dyn_loop(LOOP_NONE);goto finish_block; + case 0xe3:dyn_loop(LOOP_JCXZ);goto finish_block; //IN AL/AX,imm + case 0xe4:gen_call_function((void*)&IO_ReadB,"%Id%Rl",decode_fetchb(),DREG(EAX));break; case 0xe5: if (decode.big_op) { @@ -1309,13 +1380,13 @@ restart_prefix: dyn_call_near_imm(); goto finish_block; case 0xe9: /* Jmp Ivx */ - dyn_exit_link(decode.big_op,decode.big_op ? (Bit32s)decode_fetchd() : (Bit16s)decode_fetchw()); + dyn_exit_link(decode.big_op ? (Bit32s)decode_fetchd() : (Bit16s)decode_fetchw()); goto finish_block; case 0xea: /* JMP FAR Ip */ dyn_jmp_far_imm(); goto finish_block; /* Jmp Ibx */ - case 0xeb:dyn_exit_link(decode.big_op,(Bit8s)decode_fetchb());goto finish_block; + case 0xeb:dyn_exit_link((Bit8s)decode_fetchb());goto finish_block; /* IN AL/AX,DX*/ case 0xec:gen_call_function((void*)&IO_ReadB,"%Dw%Rl",DREG(EDX),DREG(EAX));break; case 0xed: @@ -1352,14 +1423,24 @@ restart_prefix: case 0xf7:dyn_grp3_ev();break; /* Change interrupt flag */ case 0xfa: //CLI - gen_protectflags(); - gen_dop_word_imm(DOP_AND,true,DREG(FLAGS),~FLAG_IF); + gen_call_function(&CPU_CLI,"%Rd",DREG(TMPB)); + if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); break; case 0xfb: //STI - gen_protectflags(); - gen_dop_word_imm(DOP_OR,true,DREG(FLAGS),FLAG_IF); + gen_call_function(&CPU_STI,"%Rd",DREG(TMPB)); + if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); if (max_opcodes<=0) max_opcodes=1; //Allow 1 extra opcode break; + case 0xfc: //CLD + gen_protectflags(); + gen_dop_word_imm(DOP_AND,true,DREG(FLAGS),~FLAG_DF); + gen_save_host_direct(&cpu.direction,1); + break; + case 0xfd: //STD + gen_protectflags(); + gen_dop_word_imm(DOP_OR,true,DREG(FLAGS),FLAG_DF); + gen_save_host_direct(&cpu.direction,-1); + break; /* GRP 4 Eb and callback's */ case 0xfe: dyn_get_modrm(); @@ -1380,9 +1461,9 @@ restart_prefix: break; case 0x7: //CALBACK Iw gen_save_host_direct(&core_dyn.callback,decode_fetchw()); - gen_lea(DREG(EIP),DREG(EIP),0,0,decode.code-decode.code_start); + dyn_set_eip_end(); dyn_reduce_cycles(); - dyn_releaseregs(); + dyn_save_critical_regs(); gen_return(BR_CallBack); dyn_closeblock(); goto finish_block; @@ -1417,16 +1498,17 @@ restart_prefix: goto core_close_block; case 0x3: /* CALL Ep */ case 0x5: /* JMP Ep */ - dyn_save_flags(); + gen_protectflags(); + dyn_flags_gen_to_host(); gen_lea(DREG(EA),DREG(EA),0,0,decode.big_op ? 4: 2); - gen_lea(DREG(EIP),DREG(EIP),0,0,decode.code-decode.code_start); + dyn_set_eip_last_end(DREG(TMPB)); dyn_read_word(DREG(EA),DREG(EA),false); - for (Bitu i=0;iflags|=DYNFLG_CHANGED; } -static void gen_shift_byte(ShiftOps op,DynReg * drecx,DynReg * dr1,Bit8u di1) { +static void gen_shift_byte_cl(Bitu op,DynReg * dr1,Bit8u di1,DynReg * drecx) { ForceDynReg(x86gen.regs[X86_REG_ECX],drecx); GenReg * gr1=FindDynReg(dr1); - switch (op) { - case SHIFT_ROL:cache_addw(0xc0d2+((gr1->index+di1)<<8));break; - case SHIFT_ROR:cache_addw(0xc8d2+((gr1->index+di1)<<8));break; - case SHIFT_RCL:cache_addw(0xd0d2+((gr1->index+di1)<<8));break; - case SHIFT_RCR:cache_addw(0xd8d2+((gr1->index+di1)<<8));break; - case SHIFT_SHL:cache_addw(0xe0d2+((gr1->index+di1)<<8));break; - case SHIFT_SHR:cache_addw(0xe8d2+((gr1->index+di1)<<8));break; - case SHIFT_SAR:cache_addw(0xf8d2+((gr1->index+di1)<<8));break; - default: - IllegalOption(); - } + cache_addw(0xc0d2+(((Bit16u)op) << 11)+ ((gr1->index+di1)<<8)); dr1->flags|=DYNFLG_CHANGED; } -static void gen_shift_word(ShiftOps op,DynReg * drecx,bool dword,DynReg * dr1) { - ForceDynReg(x86gen.regs[X86_REG_ECX],drecx); +static void gen_shift_byte_imm(Bitu op,DynReg * dr1,Bit8u di1,Bit8u imm) { GenReg * gr1=FindDynReg(dr1); - if (!dword) cache_addb(0x66); - switch (op) { - case SHIFT_ROL:cache_addw(0xc0d3+((gr1->index)<<8));break; - case SHIFT_ROR:cache_addw(0xc8d3+((gr1->index)<<8));break; - case SHIFT_RCL:cache_addw(0xd0d3+((gr1->index)<<8));break; - case SHIFT_RCR:cache_addw(0xd8d3+((gr1->index)<<8));break; - case SHIFT_SHL:cache_addw(0xe0d3+((gr1->index)<<8));break; - case SHIFT_SHR:cache_addw(0xe8d3+((gr1->index)<<8));break; - case SHIFT_SAR:cache_addw(0xf8d3+((gr1->index)<<8));break; - default: - IllegalOption(); - } + cache_addw(0xc0c0+(((Bit16u)op) << 11) + ((gr1->index+di1)<<8)); + cache_addb(imm); dr1->flags|=DYNFLG_CHANGED; } -static void gen_shift_word_imm(ShiftOps op,bool dword,DynReg * dr1,Bit8u imm) { +static void gen_shift_word_cl(Bitu op,bool dword,DynReg * dr1,DynReg * drecx) { + ForceDynReg(x86gen.regs[X86_REG_ECX],drecx); GenReg * gr1=FindDynReg(dr1); if (!dword) cache_addb(0x66); - switch (op) { - case SHIFT_ROL:cache_addw(0xc0c1+((gr1->index)<<8));break; - case SHIFT_ROR:cache_addw(0xc8c1+((gr1->index)<<8));break; - case SHIFT_RCL:cache_addw(0xd0c1+((gr1->index)<<8));break; - case SHIFT_RCR:cache_addw(0xd8c1+((gr1->index)<<8));break; - case SHIFT_SHL:cache_addw(0xe0c1+((gr1->index)<<8));break; - case SHIFT_SHR:cache_addw(0xe8c1+((gr1->index)<<8));break; - case SHIFT_SAR:cache_addw(0xf8c1+((gr1->index)<<8));break; - default: - IllegalOption(); - } + cache_addw(0xc0d3+(((Bit16u)op) << 11) + ((gr1->index)<<8)); + dr1->flags|=DYNFLG_CHANGED; +} + +static void gen_shift_word_imm(Bitu op,bool dword,DynReg * dr1,Bit8u imm) { + GenReg * gr1=FindDynReg(dr1); + if (!dword) cache_addb(0x66); + cache_addw(0xc0c1+(((Bit16u)op) << 11) + ((gr1->index)<<8)); cache_addb(imm); dr1->flags|=DYNFLG_CHANGED; } @@ -707,6 +684,11 @@ static Bit8u * gen_create_branch(BranchTypes type) { } static void gen_fill_branch(Bit8u * data,Bit8u * from=cache.pos) { +#if C_DEBUG + Bits len=from-data; + if (len<0) len=-len; + if (len>126) LOG_MSG("BIg jump %d",len); +#endif *data=(from-data-1); } diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index 443b9af0..4182dbd5 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -149,8 +149,8 @@ static void dyn_string(STRING_OP op) { gen_releasereg(DREG(CYCLES)); dyn_savestate(&cycle_state); Bit8u * cycle_branch=gen_create_branch(BR_NLE); - gen_lea(DREG(EIP),DREG(EIP),0,0,decode.op_start-decode.code_start); - dyn_releaseregs(); + gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),decode.op_start-decode.code_start); + dyn_save_critical_regs(); gen_return(BR_Cycles); gen_fill_branch(cycle_branch); dyn_loadstate(&cycle_state); From 48a86f7e97b03cf7e73f6f42c4e93aa5eb3decbd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 22 Apr 2004 22:47:04 +0000 Subject: [PATCH 1693/4131] Added some (void *) casts to make gcc happy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1775 --- src/cpu/core_dyn_x86/decoder.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 519f44c3..c7326058 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -726,7 +726,7 @@ static void dyn_check_bool_exception(DynReg * check) { dyn_reduce_cycles(); dyn_set_eip_last(); dyn_save_critical_regs(); - gen_call_function(&DynRunException,""); + gen_call_function((void *)&DynRunException,""); gen_return(BR_Normal); dyn_loadstate(&state); gen_fill_branch(branch); @@ -808,7 +808,7 @@ static void dyn_enter(void) { gen_releasereg(DREG(EBP)); Bitu bytes=decode_fetchw(); Bitu level=decode_fetchb(); - gen_call_function(&CPU_ENTER,"%Id%Id%Id",decode.big_op,bytes,level); + gen_call_function((void *)&CPU_ENTER,"%Id%Id%Id",decode.big_op,bytes,level); } static void dyn_leave(void) { @@ -1010,8 +1010,6 @@ static void dyn_interrupt(Bitu num) { dyn_closeblock(); } -static counter=0; - static CacheBlock * CreateCacheBlock(CodePageHandler * codepage,PhysPt start,Bitu max_opcodes) { Bits i; /* Init a load of variables */ @@ -1265,13 +1263,13 @@ restart_prefix: gen_protectflags(); gen_releasereg(DREG(ESP)); dyn_flags_gen_to_host(); - gen_call_function(&CPU_PUSHF,"%Rd%Id",DREG(TMPB),decode.big_op); + gen_call_function((void *)&CPU_PUSHF,"%Rd%Id",DREG(TMPB),decode.big_op); if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); gen_releasereg(DREG(TMPB)); break; case 0x9d: //POPF gen_releasereg(DREG(ESP)); - gen_call_function(&CPU_POPF,"%Rd%Id",DREG(TMPB),decode.big_op); + gen_call_function((void *)&CPU_POPF,"%Rd%Id",DREG(TMPB),decode.big_op); if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); dyn_flags_host_to_gen(); gen_releasereg(DREG(TMPB)); @@ -1423,11 +1421,11 @@ restart_prefix: case 0xf7:dyn_grp3_ev();break; /* Change interrupt flag */ case 0xfa: //CLI - gen_call_function(&CPU_CLI,"%Rd",DREG(TMPB)); + gen_call_function((void *)&CPU_CLI,"%Rd",DREG(TMPB)); if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); break; case 0xfb: //STI - gen_call_function(&CPU_STI,"%Rd",DREG(TMPB)); + gen_call_function((void *)&CPU_STI,"%Rd",DREG(TMPB)); if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); if (max_opcodes<=0) max_opcodes=1; //Allow 1 extra opcode break; From 498ed26525d50daeff5dadabe82ce218066d61a0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 24 Apr 2004 09:16:08 +0000 Subject: [PATCH 1694/4131] Fix branches getting out of range with div/idiv exceptions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1776 --- src/cpu/core_dyn_x86/decoder.h | 67 +++++++++++----------------------- src/cpu/core_dyn_x86/helpers.h | 48 ++++++++++++------------ 2 files changed, 46 insertions(+), 69 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index c7326058..36794259 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -298,6 +298,25 @@ static void dyn_fill_ea(bool addseg=true) { #include "helpers.h" #include "string.h" +static void DynRunException(void) { + CPU_Exception(cpu.exception.which,cpu.exception.error); +} + +static void dyn_check_bool_exception(DynReg * check) { + Bit8u * branch;DynState state; + gen_dop_byte(DOP_OR,check,0,check,0); + branch=gen_create_branch(BR_Z); + dyn_savestate(&state); + dyn_flags_gen_to_host(); + dyn_reduce_cycles(); + dyn_set_eip_last(); + dyn_save_critical_regs(); + gen_call_function(&DynRunException,""); + gen_return(BR_Normal); + dyn_loadstate(&state); + gen_fill_branch(branch); +} + static void dyn_dop_ebgb(DualOps op) { dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg&3]; if (decode.modrm.mod<3) { @@ -589,7 +608,6 @@ static void dyn_grp2_ev(grp2_types type) { } static void dyn_grp3_eb(void) { - DynState state;Bit8u * branch; dyn_get_modrm();DynReg * src;Bit8u src_i; if (decode.modrm.mod<3) { dyn_fill_ea(); @@ -623,18 +641,7 @@ static void dyn_grp3_eb(void) { gen_releasereg(DREG(EAX)); gen_call_function((decode.modrm.reg==6) ? (void *)&dyn_helper_divb : (void *)&dyn_helper_idivb, "%Rd%Drl",DREG(TMPB),DREG(TMPB)); - gen_dop_word(DOP_OR,true,DREG(TMPB),DREG(TMPB)); - branch=gen_create_branch(BR_Z); - dyn_savestate(&state); - dyn_reduce_cycles(); - dyn_set_eip_last(); - dyn_flags_gen_to_host(); - dyn_save_critical_regs(); - gen_call_function((void *)&CPU_Exception,"%Id%Id",0,0); - dyn_flags_host_to_gen(); - gen_return(BR_Normal); - dyn_loadstate(&state); - gen_fill_branch(branch); + dyn_check_bool_exception(DREG(TMPB)); goto skipsave; } /* Save the result if memory op */ @@ -644,7 +651,6 @@ skipsave: } static void dyn_grp3_ev(void) { - DynState state;Bit8u * branch; dyn_get_modrm();DynReg * src; if (decode.modrm.mod<3) { dyn_fill_ea();src=DREG(TMPW); @@ -675,19 +681,8 @@ static void dyn_grp3_ev(void) { void * func=(decode.modrm.reg==6) ? (decode.big_op ? (void *)&dyn_helper_divd : (void *)&dyn_helper_divw) : (decode.big_op ? (void *)&dyn_helper_idivd : (void *)&dyn_helper_idivw); - gen_call_function(func,"%Rd%Drd",DREG(TMPW),DREG(TMPW)); - gen_dop_word(DOP_OR,true,DREG(TMPW),DREG(TMPW)); - branch=gen_create_branch(BR_Z); - dyn_savestate(&state); - dyn_reduce_cycles(); - dyn_set_eip_last(); - dyn_flags_gen_to_host(); - dyn_save_critical_regs(); - gen_call_function((void *)&CPU_Exception,"%Id%Id",0,0); - dyn_flags_host_to_gen(); - gen_return(BR_Normal); - dyn_loadstate(&state); - gen_fill_branch(branch); + gen_call_function(func,"%Rd%Drd",DREG(TMPB),DREG(TMPW)); + dyn_check_bool_exception(DREG(TMPB)); goto skipsave; } /* Save the result if memory op */ @@ -714,24 +709,6 @@ static void dyn_synch_eip(void) { gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),decode.code-decode.code_start); } -static void DynRunException(void) { - CPU_Exception(cpu.exception.which,cpu.exception.error); -} -static void dyn_check_bool_exception(DynReg * check) { - Bit8u * branch;DynState state; - gen_dop_byte(DOP_OR,check,0,check,0); - branch=gen_create_branch(BR_Z); - dyn_savestate(&state); - dyn_flags_gen_to_host(); - dyn_reduce_cycles(); - dyn_set_eip_last(); - dyn_save_critical_regs(); - gen_call_function((void *)&DynRunException,""); - gen_return(BR_Normal); - dyn_loadstate(&state); - gen_fill_branch(branch); -} - static void dyn_load_seg(SegNames seg,DynReg * src) { if (cpu.pmode) { gen_call_function((void *)&CPU_SetSegGeneral,"%Rd%Id%Drw",DREG(TMPB),seg,src); diff --git a/src/cpu/core_dyn_x86/helpers.h b/src/cpu/core_dyn_x86/helpers.h index 7986540b..6fa75b3a 100644 --- a/src/cpu/core_dyn_x86/helpers.h +++ b/src/cpu/core_dyn_x86/helpers.h @@ -1,57 +1,57 @@ -static Bitu dyn_helper_divb(Bit8u val) { - if (!val) return 1; +static bool dyn_helper_divb(Bit8u val) { + if (!val) return CPU_PrepareException(0,0); Bitu quo=reg_ax / val; reg_ah=(Bit8u)(reg_ax % val); reg_al=(Bit8u)quo; - if (quo>0xff) return 1; - return 0; + if (quo>0xff) return CPU_PrepareException(0,0); + return false; } -static Bitu dyn_helper_idivb(Bit8s val) { - if (!val) return 1; +static bool dyn_helper_idivb(Bit8s val) { + if (!val) return CPU_PrepareException(0,0); Bits quo=(Bit16s)reg_ax / val; reg_ah=(Bit8s)((Bit16s)reg_ax % val); reg_al=(Bit8s)quo; - if (quo!=(Bit8s)reg_al) return 1; - return 0; + if (quo!=(Bit8s)reg_al) return CPU_PrepareException(0,0); + return false; } -static Bitu dyn_helper_divw(Bit16u val) { - if (!val) return 1; +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; reg_dx=(Bit16u)(num % val); reg_ax=(Bit16u)quo; - if (quo!=reg_ax) return 1; - return 0; + if (quo!=reg_ax) return CPU_PrepareException(0,0); + return false; } -static Bitu dyn_helper_idivw(Bit16s val) { - if (!val) return 1; +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; reg_dx=(Bit16s)(num % val); reg_ax=(Bit16s)quo; - if (quo!=(Bit16s)reg_ax) return 1; - return 0; + if (quo!=(Bit16s)reg_ax) return CPU_PrepareException(0,0); + return false; } -static Bitu dyn_helper_divd(Bit32u val) { - if (!val) return 1; +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; reg_edx=(Bit32u)(num % val); reg_eax=(Bit32u)quo; - if (quo!=(Bit64u)reg_eax) return 1; - return 0; + if (quo!=(Bit64u)reg_eax) return CPU_PrepareException(0,0); + return false; } -static Bitu dyn_helper_idivd(Bit32s val) { - if (!val) return 1; +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; reg_edx=(Bit32s)(num % val); reg_eax=(Bit32s)(quo); - if (quo!=(Bit64s)((Bit32s)reg_eax)) return 1; - return 0; + if (quo!=(Bit64s)((Bit32s)reg_eax)) return CPU_PrepareException(0,0); + return false; } From de5dd0de7cb3b2c731b141a81cc8d28744ca9edb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 24 Apr 2004 09:17:00 +0000 Subject: [PATCH 1695/4131] make prepare exception function global Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1777 --- include/cpu.h | 1 + src/cpu/cpu.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index b30aabfb..7e3f613a 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -93,6 +93,7 @@ INLINE void CPU_SW_Interrupt(Bitu num,Bitu oldeip) { CPU_Interrupt(num,CPU_INT_SOFTWARE,oldeip); } +bool CPU_PrepareException(Bitu which,Bitu error); void CPU_Exception(Bitu which,Bitu error=0); bool CPU_SetSegGeneral(SegNames seg,Bitu value); diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 097e3ce0..74f1069a 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.56 2004-04-22 22:40:45 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.57 2004-04-24 09:16:42 harekiet Exp $ */ #include #include "dosbox.h" @@ -87,7 +87,7 @@ void CPU_SetFlags(Bitu word,Bitu mask) { cpu.direction=1-((reg_flags & FLAG_DF) >> 9); } -static bool CPU_PrepareException(Bitu which,Bitu error) { +bool CPU_PrepareException(Bitu which,Bitu error) { cpu.exception.which=which; cpu.exception.error=error; return true; From bd884098b17f7092bd8c9acaa614ffd07207117e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 24 Apr 2004 09:20:11 +0000 Subject: [PATCH 1696/4131] Fix breakpoints with new cpu cores Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1778 --- src/debug/debug.cpp | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 2a4f3d6f..5b251c03 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.52 2004-01-27 14:52:28 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.53 2004-04-24 09:20:11 harekiet Exp $ */ #include "programs.h" @@ -535,35 +535,26 @@ void CBreakpoint::ShowList(void) bool DEBUG_Breakpoint(void) { /* First get the phyiscal address and check for a set Breakpoint */ -// PhysPt where=SegPhys(cs)+reg_eip-1; - PhysPt where=GetAddress(SegValue(cs),reg_eip-1); - if (!CBreakpoint::CheckBreakpoint(SegValue(cs),reg_eip-1)) return false; + PhysPt where=GetAddress(SegValue(cs),reg_eip); + if (!CBreakpoint::CheckBreakpoint(SegValue(cs),reg_eip)) return false; // Found. Breakpoint is valid - reg_eip -= 1; CBreakpoint::ActivateBreakpoints(where,false); // Deactivate all breakpoints -// exitLoop = true; -// DEBUG_Enable(); return true; }; bool DEBUG_IntBreakpoint(Bit8u intNum) { /* First get the phyiscal address and check for a set Breakpoint */ -// PhysPt where=SegPhys(cs)+reg_eip-2; - PhysPt where=GetAddress(SegValue(cs),reg_eip-2); + PhysPt where=GetAddress(SegValue(cs),reg_eip); if (!CBreakpoint::CheckIntBreakpoint(where,intNum,reg_ah)) return false; // Found. Breakpoint is valid - reg_eip -= 2; CBreakpoint::ActivateBreakpoints(where,false); // Deactivate all breakpoints -// exitLoop = true; -// DEBUG_Enable(); return true; }; static bool StepOver() { exitLoop = false; -// PhysPt start=SegPhys(cs)+reg_eip; PhysPt start=GetAddress(SegValue(cs),reg_eip); char dline[200];Bitu size; size=DasmI386(dline, start, reg_eip, cpu.code.big); From a19612510912353e2d78678a2ce49bb25397f2c7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 24 Apr 2004 12:43:54 +0000 Subject: [PATCH 1697/4131] Don't commit shit with a zillion newlines Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1779 --- src/ints/mouse.cpp | 78 ++++------------------------------------------ 1 file changed, 6 insertions(+), 72 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 416d8b10..6d39647a 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.36 2004-03-24 19:26:49 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.37 2004-04-24 12:43:54 harekiet Exp $ */ #include #include @@ -32,68 +32,10 @@ #include "cpu.h" static Bitu call_int33,call_int74; - -static Bit16u ps2cbseg, ps2cbofs; -static bool useps2callback; -static Bit16u call_ps2; -static RealPt ps2_callback; -static Bit16s oldmouseX, oldmouseY; - -void Mouse_SetPS2State(bool use) { - if ((SegValue(es)!=0) && (reg_bx!=0)) useps2callback = use; - else useps2callback = false; - Mouse_AutoLock(useps2callback); -} - -void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs) { - if ((pseg==0) && (pofs==0)) useps2callback = false; - else useps2callback = true; - ps2cbseg = pseg; - ps2cbofs = pofs; - Mouse_AutoLock(useps2callback); -} - -void DoPS2Callback(Bit16u data, Bit16s mouseX, Bit16s mouseY) { - if (useps2callback) { - Bit16u mdat = (data & 0x03) | 0x08; - Bit16s xdiff = mouseX-oldmouseX; - Bit16s ydiff = oldmouseY-mouseY; - oldmouseX = mouseX; - oldmouseY = mouseY; - - if ((xdiff>0xff) || (xdiff<-0xff)) mdat |= 0x40; // x overflow - if ((ydiff>0xff) || (ydiff<-0xff)) mdat |= 0x80; // y overflow - - xdiff %= 256; - ydiff %= 256; - - if (xdiff<0) { - xdiff = (0x100+xdiff); - mdat |= 0x10; - } - if (ydiff<0) { - ydiff = (0x100+ydiff); - mdat |= 0x20; - } - - CPU_Push16((Bit16u)mdat); - CPU_Push16((Bit16u)(xdiff % 256)); - CPU_Push16((Bit16u)(ydiff % 256)); - CPU_Push16((Bit16u)0); - - CPU_Push16(RealSeg(ps2_callback)); - CPU_Push16(RealOff(ps2_callback)); - SegSet16(cs, ps2cbseg); - reg_ip = ps2cbofs; - } -} - -Bitu PS2_Handler(void) { - reg_sp += 8; // remove the 4 words - return CBRET_NONE; -} - - +static Bit16u ps2cbseg, ps2cbofs; static bool useps2callback; static Bit16u call_ps2; static RealPt ps2_callback; static Bit16s oldmouseX, oldmouseY; +void Mouse_SetPS2State(bool use) { if ((SegValue(es)!=0) && (reg_bx!=0)) useps2callback = use; else useps2callback = false; Mouse_AutoLock(useps2callback); } +void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs) { if ((pseg==0) && (pofs==0)) useps2callback = false; else useps2callback = true; ps2cbseg = pseg; ps2cbofs = pofs; Mouse_AutoLock(useps2callback); } +void DoPS2Callback(Bit16u data, Bit16s mouseX, Bit16s mouseY) { if (useps2callback) { Bit16u mdat = (data & 0x03) | 0x08; Bit16s xdiff = mouseX-oldmouseX; Bit16s ydiff = oldmouseY-mouseY; oldmouseX = mouseX; oldmouseY = mouseY; if ((xdiff>0xff) || (xdiff<-0xff)) mdat |= 0x40; // x overflow if ((ydiff>0xff) || (ydiff<-0xff)) mdat |= 0x80; // y overflow xdiff %= 256; ydiff %= 256; if (xdiff<0) { xdiff = (0x100+xdiff); mdat |= 0x10; } if (ydiff<0) { ydiff = (0x100+ydiff); mdat |= 0x20; } CPU_Push16((Bit16u)mdat); CPU_Push16((Bit16u)(xdiff % 256)); CPU_Push16((Bit16u)(ydiff % 256)); CPU_Push16((Bit16u)0); CPU_Push16(RealSeg(ps2_callback)); CPU_Push16(RealOff(ps2_callback)); SegSet16(cs, ps2cbseg); reg_ip = ps2cbofs; } } Bitu PS2_Handler(void) { reg_sp += 8; // remove the 4 words return CBRET_NONE; } // forward void WriteMouseIntVector(void); @@ -884,7 +826,6 @@ void MOUSE_Init(Section* sec) { // Callback 0x33 CreateMouseCallback(); - call_int74=CALLBACK_Allocate(); CALLBACK_Setup(call_int74,&INT74_Handler,CB_IRET); if(MOUSE_IRQ > 7) { @@ -892,14 +833,7 @@ void MOUSE_Init(Section* sec) { } else { real_writed(0,((0x8+MOUSE_IRQ)<<2),CALLBACK_RealPointer(call_int74)); } - - useps2callback = false; - - call_ps2=CALLBACK_Allocate(); - CALLBACK_Setup(call_ps2,&PS2_Handler,CB_IRET,"ps2 bios callback"); - ps2_callback=CALLBACK_RealPointer(call_ps2); - - memset(&mouse,0,sizeof(mouse)); + useps2callback = false; call_ps2=CALLBACK_Allocate(); CALLBACK_Setup(call_ps2,&PS2_Handler,CB_IRET,"ps2 bios callback"); ps2_callback=CALLBACK_RealPointer(call_ps2); memset(&mouse,0,sizeof(mouse)); mouse_reset_hardware(); mouse_reset(); } From 8c427c4aa0edf8b1d3a2df543576bbb0ba587e8b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 24 Apr 2004 17:57:38 +0000 Subject: [PATCH 1698/4131] Mysterious line endings in 0xd 0xd 0xa Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1780 --- src/ints/mouse.cpp | 163 +++++++++++++++++++++++++++++++++------------ 1 file changed, 122 insertions(+), 41 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 6d39647a..04b4f9d1 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,26 +16,30 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.37 2004-04-24 12:43:54 harekiet Exp $ */ +/* $Id: mouse.cpp,v 1.38 2004-04-24 17:57:38 harekiet Exp $ */ #include -#include +#include + + #include "dosbox.h" #include "callback.h" #include "mem.h" #include "regs.h" +#include "cpu.h" #include "mouse.h" #include "pic.h" #include "inout.h" #include "int10.h" #include "bios.h" -#include "cpu.h" + static Bitu call_int33,call_int74; -static Bit16u ps2cbseg, ps2cbofs; static bool useps2callback; static Bit16u call_ps2; static RealPt ps2_callback; static Bit16s oldmouseX, oldmouseY; -void Mouse_SetPS2State(bool use) { if ((SegValue(es)!=0) && (reg_bx!=0)) useps2callback = use; else useps2callback = false; Mouse_AutoLock(useps2callback); } -void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs) { if ((pseg==0) && (pofs==0)) useps2callback = false; else useps2callback = true; ps2cbseg = pseg; ps2cbofs = pofs; Mouse_AutoLock(useps2callback); } -void DoPS2Callback(Bit16u data, Bit16s mouseX, Bit16s mouseY) { if (useps2callback) { Bit16u mdat = (data & 0x03) | 0x08; Bit16s xdiff = mouseX-oldmouseX; Bit16s ydiff = oldmouseY-mouseY; oldmouseX = mouseX; oldmouseY = mouseY; if ((xdiff>0xff) || (xdiff<-0xff)) mdat |= 0x40; // x overflow if ((ydiff>0xff) || (ydiff<-0xff)) mdat |= 0x80; // y overflow xdiff %= 256; ydiff %= 256; if (xdiff<0) { xdiff = (0x100+xdiff); mdat |= 0x10; } if (ydiff<0) { ydiff = (0x100+ydiff); mdat |= 0x20; } CPU_Push16((Bit16u)mdat); CPU_Push16((Bit16u)(xdiff % 256)); CPU_Push16((Bit16u)(ydiff % 256)); CPU_Push16((Bit16u)0); CPU_Push16(RealSeg(ps2_callback)); CPU_Push16(RealOff(ps2_callback)); SegSet16(cs, ps2cbseg); reg_ip = ps2cbofs; } } Bitu PS2_Handler(void) { reg_sp += 8; // remove the 4 words return CBRET_NONE; } +static Bit16u ps2cbseg,ps2cbofs; +static bool useps2callback; +static Bit16u call_ps2; +static RealPt ps2_callback; +static Bit16s oldmouseX, oldmouseY; // forward void WriteMouseIntVector(void); @@ -105,8 +109,8 @@ static struct { float mickeysPerPixel_y; float pixelPerMickey_x; float pixelPerMickey_y; - float senv_x; - float senv_y; + float senv_x; + float senv_y; Bit16u updateRegion_x[2]; Bit16u updateRegion_y[2]; Bit16u page; @@ -117,6 +121,56 @@ static struct { Bit16s oldshown; } mouse; +void Mouse_SetPS2State(bool use) { + if ((SegValue(es)!=0) && (reg_bx!=0)) useps2callback = use; + else useps2callback = false; + Mouse_AutoLock(useps2callback); +} + +void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs) { + if ((pseg==0) && (pofs==0)) useps2callback = false; + else useps2callback = true; + ps2cbseg = pseg; + ps2cbofs = pofs; + Mouse_AutoLock(useps2callback); +} + +void DoPS2Callback(Bit16u data, Bit16s mouseX, Bit16s mouseY) { + if (useps2callback) { + Bit16u mdat = (data & 0x03) | 0x08; + Bit16s xdiff = mouseX-oldmouseX; + Bit16s ydiff = oldmouseY-mouseY; + oldmouseX = mouseX; + oldmouseY = mouseY; + if ((xdiff>0xff) || (xdiff<-0xff)) mdat |= 0x40; // x overflow + if ((ydiff>0xff) || (ydiff<-0xff)) mdat |= 0x80; // y overflow + xdiff %= 256; + ydiff %= 256; + if (xdiff<0) { + xdiff = (0x100+xdiff); + mdat |= 0x10; + } + if (ydiff<0) { + ydiff = (0x100+ydiff); + mdat |= 0x20; + } + CPU_Push16((Bit16u)mdat); + CPU_Push16((Bit16u)(xdiff % 256)); + CPU_Push16((Bit16u)(ydiff % 256)); + CPU_Push16((Bit16u)0); + CPU_Push16(RealSeg(ps2_callback)); + CPU_Push16(RealOff(ps2_callback)); + SegSet16(cs, ps2cbseg); + reg_ip = ps2cbofs; + } +} + +Bitu PS2_Handler(void) { + reg_sp += 8; // remove the 4 words + return CBRET_NONE; +} + + #define X_MICKEY 8 #define Y_MICKEY 8 @@ -353,21 +407,23 @@ void DrawCursor() { void Mouse_CursorMoved(float x,float y) { float dx = x * mouse.pixelPerMickey_x; float dy = y * mouse.pixelPerMickey_y; - if((fabs(x) > 1.0) || (mouse.senv_y < 1.0)) dx *= mouse.senv_x; - if((fabs(y) > 1.0) || (mouse.senv_y < 1.0)) dy *= mouse.senv_y; + if((fabs(x) > 1.0) || (mouse.senv_y < 1.0)) dx *= mouse.senv_x; + + if((fabs(y) > 1.0) || (mouse.senv_y < 1.0)) dy *= mouse.senv_y; + mouse.mickey_x += dx; mouse.mickey_y += dy; mouse.x += dx; mouse.y += dy; - /* ignore constraints if using PS2 mouse callback in the bios */ - if (!useps2callback) { - if (mouse.x > mouse.max_x) mouse.x = mouse.max_x; - if (mouse.x < mouse.min_x) mouse.x = mouse.min_x; - if (mouse.y > mouse.max_y) mouse.y = mouse.max_y; - if (mouse.y < mouse.min_y) mouse.y = mouse.min_y; - } - + /* ignore constraints if using PS2 mouse callback in the bios */ + + if (!useps2callback) { + if (mouse.x > mouse.max_x) mouse.x = mouse.max_x; + if (mouse.x < mouse.min_x) mouse.x = mouse.min_x; + if (mouse.y > mouse.max_y) mouse.y = mouse.max_y; + if (mouse.y < mouse.min_y) mouse.y = mouse.min_y; + } Mouse_AddEvent(MOUSE_MOVED); DrawCursor(); } @@ -418,7 +474,8 @@ void Mouse_ButtonReleased(Bit8u button) { mouse.last_released_y[button]=POS_Y; } -static void SetMickeyPixelRate(Bit16s px, Bit16s py){ +static void SetMickeyPixelRate(Bit16s px, Bit16s py){ + if ((px!=0) && (py!=0)) { mouse.mickeysPerPixel_x = (float)px/X_MICKEY; mouse.mickeysPerPixel_y = (float)py/Y_MICKEY; @@ -426,14 +483,22 @@ static void SetMickeyPixelRate(Bit16s px, Bit16s py){ mouse.pixelPerMickey_y = Y_MICKEY/(float)py; } }; -static void SetSensitivity(Bit16s px, Bit16s py){ - if ((px!=0) && (py!=0)) { - px--; //Inspired by cutemouse - py--; //Although their cursor update routine is far more complex then ours - mouse.senv_x=(static_cast(px)*px)/3600.0 +1.0/3.0; - mouse.senv_y=(static_cast(py)*py)/3600.0 +1.0/3.0; - } -}; +static void SetSensitivity(Bit16s px, Bit16s py){ + + if ((px!=0) && (py!=0)) { + + px--; //Inspired by cutemouse + + py--; //Although their cursor update routine is far more complex then ours + + mouse.senv_x=(static_cast(px)*px)/3600.0 +1.0/3.0; + + mouse.senv_y=(static_cast(py)*py)/3600.0 +1.0/3.0; + + } + +}; + static void mouse_reset_hardware(void){ PIC_SetIRQMask(MOUSE_IRQ,false); @@ -512,9 +577,12 @@ void Mouse_NewVideoMode(void) mouse.oldshown=-1; SetMickeyPixelRate(8,16); - oldmouseX = static_cast(mouse.x); - oldmouseY = static_cast(mouse.y); - + oldmouseX = static_cast(mouse.x); + + oldmouseY = static_cast(mouse.y); + + + } @@ -526,8 +594,10 @@ static void mouse_reset(void) { mouse.sub_mask=0; mouse.sub_seg=0; mouse.sub_ofs=0; - mouse.senv_x=1.0; - mouse.senv_y=1.0; + mouse.senv_x=1.0; + + mouse.senv_y=1.0; + //Added this for cd-v19 } @@ -691,14 +761,19 @@ static Bitu INT33_Handler(void) { } break; case 0x1a: /* Set mouse sensitivity */ - SetSensitivity(reg_bx,reg_cx); - LOG(LOG_MOUSE,LOG_WARN)("Set sensitivity used with %d %d",reg_bx,reg_cx); + SetSensitivity(reg_bx,reg_cx); + + LOG(LOG_MOUSE,LOG_WARN)("Set sensitivity used with %d %d",reg_bx,reg_cx); + // ToDo : double mouse speed value break; case 0x1b: /* Get mouse sensitivity */ - reg_bx = Bit16s((60.0* sqrt(mouse.senv_x- (1.0/3.0)) ) +1.0); - reg_cx = Bit16s((60.0* sqrt(mouse.senv_y- (1.0/3.0)) ) +1.0); - LOG(LOG_MOUSE,LOG_WARN)("Get sensitivity %d %d",reg_bx,reg_cx); + reg_bx = Bit16s((60.0* sqrt(mouse.senv_x- (1.0/3.0)) ) +1.0); + + reg_cx = Bit16s((60.0* sqrt(mouse.senv_y- (1.0/3.0)) ) +1.0); + + LOG(LOG_MOUSE,LOG_WARN)("Get sensitivity %d %d",reg_bx,reg_cx); + // ToDo : double mouse speed value reg_dx = 64; break; @@ -787,7 +862,8 @@ static Bitu INT74_Handler(void) { SegSet16(ds,oldds); SegSet16(es,oldes); SegSet16(ss,oldss); // Save segments } - DoPS2Callback(mouse.event_queue[mouse.events].buttons, POS_X, POS_Y); + DoPS2Callback(mouse.event_queue[mouse.events].buttons, POS_X, POS_Y); + } IO_Write(0xa0,0x20); IO_Write(0x20,0x20); @@ -809,7 +885,8 @@ void CreateMouseCallback(void) { // Create callback call_int33=CALLBACK_Allocate(); - CALLBACK_Setup(call_int33,&INT33_Handler,CB_IRET,"Mouse"); + CALLBACK_Setup(call_int33,&INT33_Handler,CB_IRET,"Mouse"); + // Create a mouse vector with weird address // for strange mouse detection routines in Sim City & Wasteland Bit16u ofs = call_int33<<4; @@ -833,7 +910,11 @@ void MOUSE_Init(Section* sec) { } else { real_writed(0,((0x8+MOUSE_IRQ)<<2),CALLBACK_RealPointer(call_int74)); } - useps2callback = false; call_ps2=CALLBACK_Allocate(); CALLBACK_Setup(call_ps2,&PS2_Handler,CB_IRET,"ps2 bios callback"); ps2_callback=CALLBACK_RealPointer(call_ps2); memset(&mouse,0,sizeof(mouse)); + useps2callback = false; + call_ps2=CALLBACK_Allocate(); + CALLBACK_Setup(call_ps2,&PS2_Handler,CB_IRET,"ps2 bios callback"); + ps2_callback=CALLBACK_RealPointer(call_ps2); + memset(&mouse,0,sizeof(mouse)); mouse_reset_hardware(); mouse_reset(); } From a117b44fbb0270ec098ad41fd22565055ed5f458 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 25 Apr 2004 13:41:03 +0000 Subject: [PATCH 1699/4131] Fix annoying gcc warning Fix exceptions not restoring flags Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1781 --- src/cpu/core_dyn_x86/decoder.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 36794259..7711e488 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -311,7 +311,8 @@ static void dyn_check_bool_exception(DynReg * check) { dyn_reduce_cycles(); dyn_set_eip_last(); dyn_save_critical_regs(); - gen_call_function(&DynRunException,""); + gen_call_function((void *)&DynRunException,""); + dyn_flags_host_to_gen(); gen_return(BR_Normal); dyn_loadstate(&state); gen_fill_branch(branch); From 5db36f043f9102e56b791316f34bcdf1b5f2ab2d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 25 Apr 2004 15:08:54 +0000 Subject: [PATCH 1700/4131] Go back to the old 4bit-adpcm decoding Setup the high dma parameter in the set blaster line Change some debug messages Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1782 --- src/hardware/sblaster.cpp | 85 ++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 51 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index bb6d1e9c..2c052599 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -29,8 +29,6 @@ #include "programs.h" #define SB_PIC_EVENTS 0 -#define SB_NEW_ADPCM 1 - #define DSP_MAJOR 3 #define DSP_MINOR 1 @@ -130,7 +128,9 @@ struct SB_INFO { Bit8u mic; } mixer; struct { - Bits reference,stepsize; + Bit8u reference; + Bits stepsize; + bool haveref; } adpcm; struct { Bitu base; @@ -261,29 +261,7 @@ static INLINE Bits Clip(Bits sample) { return sample; } -#if SB_NEW_ADCM -static INLINE Bit16s decode_ADPCM_4_sample(Bit8u adpcm,Bits& reference,Bits& stepsize) { - static Bits quantize[] = { 230, 230, 230, 230, 307, 409, 512, 614 }; - - Bits scale=0; - - if (adpcm & 4 ) scale += stepsize; - if (adpcm & 2 ) scale = Clip(scale + (stepsize >> 1)); - if (adpcm & 1 ) scale = Clip(scale + (stepsize >> 2)); - scale = Clip(stepsize >> 3); - if (adpcm & 8) scale = -scale; - - reference=Clip(scale+((reference * DC_OFFSET_FADE) >> 8)); - // compute the next step size - stepsize=(stepsize * quantize[adpcm & 0x7]) >> 8; - if (stepsize < MIN_ADAPTIVE_STEP_SIZE) stepsize=MIN_ADAPTIVE_STEP_SIZE; - else if (stepsize > MAX_ADAPTIVE_STEP_SIZE) stepsize=MAX_ADAPTIVE_STEP_SIZE; - - return (Bit16s)reference; -} - -#else -static INLINE Bit16s decode_ADPCM_4_sample(Bit8u sample,Bits& reference,Bits& scale) { +static INLINE Bit16s decode_ADPCM_4_sample(Bit8u sample,Bit8u & reference,Bits& scale) { static Bits scaleMap[8] = { -2, -1, 0, 0, 1, 1, 1, 1 }; if (sample & 0x08) { @@ -295,9 +273,7 @@ static INLINE Bit16s decode_ADPCM_4_sample(Bit8u sample,Bits& reference,Bits& sc return (((Bit8s)reference)^0x80)<<8; } -#endif - -static INLINE Bit16s decode_ADPCM_2_sample(Bit8u sample,Bits& reference,Bits& scale) { +static INLINE Bit16s decode_ADPCM_2_sample(Bit8u sample,Bit8u & reference,Bits& scale) { static Bits scaleMap[8] = { -2, -1, 0, 0, 1, 1, 1, 1 }; if (sample & 0x02) { @@ -309,7 +285,7 @@ static INLINE Bit16s decode_ADPCM_2_sample(Bit8u sample,Bits& reference,Bits& sc return (((Bit8s)reference)^0x80)<<8; } -INLINE Bit16s decode_ADPCM_3_sample(Bit8u sample,Bits& reference,Bits& scale) { +INLINE Bit16s decode_ADPCM_3_sample(Bit8u sample,Bit8u & reference,Bits& scale) { static Bits scaleMap[8] = { -2, -1, 0, 0, 1, 1, 1, 1 }; if (sample & 0x04) { @@ -345,8 +321,9 @@ static void GenerateDMASound(Bitu size) { } switch (sb.dma.mode) { case DSP_DMA_2: - if (sb.adpcm.reference==0x1000000) { - sb.adpcm.reference=0; + if (sb.adpcm.haveref) { + sb.adpcm.haveref=false; + sb.adpcm.reference=sb.dma.buf.b8[0]; sb.adpcm.stepsize=MIN_ADAPTIVE_STEP_SIZE; skip++;read--; } @@ -358,8 +335,9 @@ static void GenerateDMASound(Bitu size) { } break; case DSP_DMA_3: - if (sb.adpcm.reference==0x1000000) { - sb.adpcm.reference=0; + if (sb.adpcm.haveref) { + sb.adpcm.haveref=false; + sb.adpcm.reference=sb.dma.buf.b8[0]; sb.adpcm.stepsize=MIN_ADAPTIVE_STEP_SIZE; skip++;read--; } @@ -385,8 +363,9 @@ static void GenerateDMASound(Bitu size) { } break; case DSP_DMA_4: - if (sb.adpcm.reference==0x1000000) { - sb.adpcm.reference=0; + if (sb.adpcm.haveref) { + sb.adpcm.haveref=false; + sb.adpcm.reference=sb.dma.buf.b8[0]; sb.adpcm.stepsize=MIN_ADAPTIVE_STEP_SIZE; skip++;read--; } @@ -525,7 +504,7 @@ static void DSP_RaiseIRQEvent(Bitu val) { } static void DSP_DoDMATranfser(DMA_MODES mode) { - Bitu bits; + char * type; DSP_ChangeMode(MODE_NONE); sb.dma.left=sb.dma.total; sb.dma.mode=mode; @@ -533,13 +512,12 @@ static void DSP_DoDMATranfser(DMA_MODES mode) { sb.dma.rate_mul=(sb.dma.rate<<16)/sb.hw.rate; sb.tmp.add_index=(sb.dma.rate<<16)/sb.hw.rate; switch (mode) { - case DSP_DMA_2:bits=2;break; - case DSP_DMA_3:bits=3;break; - case DSP_DMA_4:bits=4;break; - case DSP_DMA_8:bits=8;break; - case DSP_DMA_16_ALIASED: - case DSP_DMA_16: - bits=16;break; + case DSP_DMA_2:type="2-bits ADPCM";break; + case DSP_DMA_3:type="3-bits ADPCM";break; + case DSP_DMA_4:type="4-bits ADPCM";break; + case DSP_DMA_8:type="8-bits PCM";break; + case DSP_DMA_16_ALIASED:type="16-bits(aliased) PCM";break; + case DSP_DMA_16:type="16-bits PCM";break; default: LOG(LOG_SB,LOG_ERROR)("DSP:Illegal transfer mode %d",mode); return; @@ -548,8 +526,8 @@ static void DSP_DoDMATranfser(DMA_MODES mode) { sb.dma.mode=mode; sb.dma.chan->Register_Callback(DSP_DMA_CallBack); #if (C_DEBUG) - LOG(LOG_SB,LOG_NORMAL)("DMA Transfer:%d-bits %s %s dma-rate %d size %d", - bits, + LOG(LOG_SB,LOG_NORMAL)("DMA Transfer:%s %s %s dma-rate %d size %d", + type, sb.dma.stereo ? "Stereo" : "Mono", sb.dma.autoinit ? "Auto-Init" : "Single-Cycle", sb.dma.rate,sb.dma.total @@ -678,24 +656,25 @@ static void DSP_DoCommand(void) { sb.freq=(1000000 / (256 - sb.dsp.in.data[0])); break; case 0x41: /* Set Output Samplerate */ + case 0x42: /* Set Input Samplerate */ sb.freq=(sb.dsp.in.data[0] << 8) | sb.dsp.in.data[1]; break; case 0x48: /* Set DMA Block Size */ //TODO Maybe check limit for new irq? sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); break; - case 0x75: /* 075h : Single Cycle 4-bit ADPCM Reference */ - sb.adpcm.reference=0x1000000; + case 0x75: /* 075h : Single Cycle 4-bit ADPCM Reference */ + sb.adpcm.haveref=true; case 0x74: /* 074h : Single Cycle 4-bit ADPCM */ DSP_PrepareDMA_Old(DSP_DMA_4,false); break; case 0x77: /* 077h : Single Cycle 3-bit(2.6bit) ADPCM Reference*/ - sb.adpcm.reference=0x1000000; + sb.adpcm.haveref=true; case 0x76: /* 074h : Single Cycle 3-bit(2.6bit) ADPCM */ DSP_PrepareDMA_Old(DSP_DMA_3,false); break; case 0x17: /* 017h : Single Cycle 2-bit ADPCM Reference*/ - sb.adpcm.reference=0x1000000; + sb.adpcm.haveref=true; case 0x16: /* 074h : Single Cycle 2-bit ADPCM */ DSP_PrepareDMA_Old(DSP_DMA_2,false); break; @@ -1064,6 +1043,10 @@ void SBLASTER_Init(Section* sec) { } PIC_RegisterIRQ(sb.hw.irq,0,"SB"); DSP_Reset(); - SHELL_AddAutoexec("SET BLASTER=A%3X I%d D%d T%d",sb.hw.base,sb.hw.irq,sb.hw.dma8,sb.type); + char hdma[8]=""; + if (sb.type==SBT_16) { + sprintf(hdma,"H%d ",sb.hw.dma16); + } + SHELL_AddAutoexec("SET BLASTER=A%3X I%d D%d %sT%d",sb.hw.base,sb.hw.irq,sb.hw.dma8,hdma,sb.type); } From 64b34126ce5ec9eec67e5d0d164eb4c6200c4fe8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 25 Apr 2004 15:47:03 +0000 Subject: [PATCH 1701/4131] fixed heavy debug compilation Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1783 --- src/cpu/core_full.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 54cea6fe..59e9fc45 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -68,7 +68,7 @@ Bits CPU_Core_Full_Run(void) { cycle_count++; #if C_HEAVY_DEBUG if (DEBUG_HeavyIsBreakpoint()) { - LEAVECORE; + FillFlags(); return debugCallback; }; #endif From 4e3edae44ce3ae3f6fe9f8ad4e328f1d3f446269 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 26 Apr 2004 07:53:17 +0000 Subject: [PATCH 1702/4131] Copy the filename from the current's psp mcb to new allocated ones Reduce available memory in tandy mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1784 --- src/dos/dos_memory.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 0eef6c1f..6be519af 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -72,6 +72,9 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { Bit16u bigsize=0;Bit16u mcb_segment=dos.firstMCB; DOS_MCB mcb(0); DOS_MCB mcb_next(0); + DOS_MCB psp_mcb(dos.psp-1); + char psp_name[9]; + psp_mcb.GetFileName(psp_name); bool stop=false; while(!stop) { mcb.SetPt(mcb_segment); @@ -97,6 +100,7 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { mcb.SetSize(*blocks); mcb.SetType(0x4d); mcb.SetPSPSeg(dos.psp); + mcb.SetFileName(psp_name); //TODO Filename *segment=mcb_segment+1; return true; @@ -108,6 +112,7 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { mcb_next.SetSize(*blocks); mcb_next.SetType(mcb.GetType()); mcb_next.SetPSPSeg(dos.psp); + mcb_next.SetFileName(psp_name); // Old Block mcb.SetSize(block_size-*blocks-1); mcb.SetPSPSeg(MCB_FREE); @@ -188,7 +193,9 @@ void DOS_SetupMemory(void) { DOS_MCB mcb((Bit16u)MEM_START+2); mcb.SetPSPSeg(MCB_FREE); //Free - mcb.SetSize(0x9FFE - MEM_START - 2); + if (machine!=MCH_TANDY) { + mcb.SetSize(0x9FFE - MEM_START - 2); + } else mcb.SetSize(0x7FFE - MEM_START - 2); mcb.SetType(0x5a); //Last Block dos.firstMCB=MEM_START; From 2773c37c542a4dd85155a96c44e55a214ce132bf Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 26 Apr 2004 07:54:37 +0000 Subject: [PATCH 1703/4131] Copy the stripped filename to the mcb of the new executed program Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1785 --- src/dos/dos_execute.cpp | 47 ++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index d781d976..0bf12cd6 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.36 2004-03-12 14:21:33 qbix79 Exp $ */ +/* $Id: dos_execute.cpp,v 1.37 2004-04-26 07:54:37 harekiet Exp $ */ #include #include "dosbox.h" @@ -26,6 +26,8 @@ #include "callback.h" #include "debug.h" +const char * RunningProgram="DOSBOX"; + #ifdef _MSC_VER #pragma pack(1) #endif @@ -90,6 +92,15 @@ static void RestoreRegisters(void) { reg_sp+=18; } +extern void GFX_SetTitle(Bits cycles,Bits frameskip); +void DOS_UpdatePSPName(void) { + DOS_MCB mcb(dos.psp-1); + static char name[9]; + mcb.GetFileName(name); + if (!strlen(name)) strcpy(name,"DOSBOX"); + RunningProgram=name; + GFX_SetTitle(-1,-1); +} bool DOS_Terminate(bool tsr) { @@ -123,13 +134,11 @@ bool DOS_Terminate(bool tsr) { mem_writew(SegPhys(ss)+reg_sp+4,0x200); //stack isn't preserved // Free memory owned by process if (!tsr) DOS_FreeProcessMemory(mempsp); + DOS_UpdatePSPName(); return true; } - - static bool MakeEnv(char * name,Bit16u * segment) { - /* If segment to copy environment is 0 copy the caller's environment */ DOS_PSP psp(dos.psp); PhysPt envread,envwrite; @@ -173,8 +182,7 @@ static bool MakeEnv(char * name,Bit16u * segment) { } else return false; } -bool DOS_NewPSP(Bit16u segment, Bit16u size) -{ +bool DOS_NewPSP(Bit16u segment, Bit16u size) { DOS_PSP psp(segment); psp.MakeNew(size); DOS_PSP psp_parent(psp.GetParent()); @@ -182,8 +190,7 @@ bool DOS_NewPSP(Bit16u segment, Bit16u size) return true; }; -bool DOS_ChildPSP(Bit16u segment, Bit16u size) -{ +bool DOS_ChildPSP(Bit16u segment, Bit16u size) { DOS_PSP psp(segment); psp.MakeNew(size); DOS_PSP psp_parent(psp.GetParent()); @@ -194,7 +201,6 @@ bool DOS_ChildPSP(Bit16u segment, Bit16u size) }; static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { - /* Fix the PSP for psp and environment MCB's */ DOS_MCB mcb((Bit16u)(pspseg-1)); mcb.SetPSPSeg(pspseg); @@ -227,8 +233,7 @@ static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { dos.dta=RealMake(pspseg,0x80); } -static void SetupCMDLine(Bit16u pspseg,DOS_ParamBlock & block) -{ +static void SetupCMDLine(Bit16u pspseg,DOS_ParamBlock & block) { DOS_PSP psp(pspseg); // if cmdtail==0 it will inited as empty in SetCommandTail psp.SetCommandTail(block.exec.cmdtail); @@ -356,7 +361,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { csip=RealMake(loadseg+head.initCS,head.initIP); sssp=RealMake(loadseg+head.initSS,head.initSP); } - + if (flags==LOAD) { DOS_PSP callpsp(dos.psp); /* Save the SS:SP on the PSP of calling program */ @@ -402,6 +407,24 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { /* Started from debug.com, then set breakpoint at start */ DEBUG_CheckExecuteBreakpoint(RealSeg(csip),RealOff(csip)); #endif + /* Add the filename to PSP and environment MCB's */ + char stripname[8];Bitu index=0; + while (char chr=*name++) { + switch (chr) { + case ':':case '\\':case '/':index=0;break; + default:if (index<8) stripname[index++]=toupper(chr); + } + } + index=0; + while (index<8) { + if (stripname[index]=='.') break; + if (!stripname[index]) break; + index++; + } + memset(&stripname[index],0,8-index); + DOS_MCB pspmcb(dos.psp-1); + pspmcb.SetFileName(stripname); + DOS_UpdatePSPName(); return true; } return false; From afbc7f882861b6eb404cb410421799bc04838bde Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 29 Apr 2004 06:10:28 +0000 Subject: [PATCH 1704/4131] Blah Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1786 --- src/dos/dos_execute.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 0bf12cd6..9c30a5f9 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,9 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.37 2004-04-26 07:54:37 harekiet Exp $ */ +/* $Id: dos_execute.cpp,v 1.38 2004-04-29 06:10:28 harekiet Exp $ */ #include +#include #include "dosbox.h" #include "mem.h" #include "dos_inc.h" From e3a7a4868763fa0d8b80b3ab6cdb47bf9a444aaf Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 4 May 2004 18:34:08 +0000 Subject: [PATCH 1705/4131] Added SDA. Update DTA/PSP to use SDA. Added some more pic commands. Cleaned dos.cpp up a bit. Handled some more calls in dos.cpp. Changed execute and terminate to mess less with the dta. Removed all dta references and changes in PSP. Added some messages to messagefile for mount. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1787 --- ChangeLog | 13 +++++ include/dos_inc.h | 105 ++++++++++++++++++++++++---------- src/dos/dos.cpp | 116 ++++++++++++++++++++++---------------- src/dos/dos_classes.cpp | 18 ++++-- src/dos/dos_execute.cpp | 63 ++++++++------------- src/dos/dos_files.cpp | 50 ++++++++-------- src/dos/dos_memory.cpp | 8 +-- src/dos/dos_programs.cpp | 8 ++- src/dos/dos_tables.cpp | 13 +++-- src/hardware/pic.cpp | 20 ++++++- src/misc/programs.cpp | 8 +-- src/shell/shell.cpp | 7 ++- src/shell/shell_batch.cpp | 2 + src/shell/shell_cmds.cpp | 8 +-- src/shell/shell_misc.cpp | 12 ++-- 15 files changed, 271 insertions(+), 180 deletions(-) diff --git a/ChangeLog b/ChangeLog index b1c06c19..6807255e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,19 @@ - Fixed commandline parsing when .bat files involved (fixes -exit) - Fixed issues with tabs in commandline not being processed correctly - Returned filename in ds:dx in create-random-file (c2woody) + - Cleaned/improved shutdown sequence. + - Fixed a bug with date and time used on open files. + - Added ps2 mouse-emulation in bios interrupts. (c2woody) + - Made our XMS driver conform the specs better. (c2woody) + - Added intelligent mpu401 emulation. (Srecko) + - Changed sensitivity settings of the mouse. + - 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 + - Changed OpenGL so that it is initialized only when used. + - Added basic SDA. + - Changed psp and dta functions to use dta. + - Added some more PIC commands. (c2woody) 0.61 - Added a beta dynamic cpu for x86 hosts (very unstable) diff --git a/include/dos_inc.h b/include/dos_inc.h index 6724f168..7771d2d4 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.41 2004-04-18 14:49:48 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.42 2004-05-04 18:34:07 qbix79 Exp $ */ #ifndef DOS_H_ #define DOS_H_ @@ -45,27 +45,6 @@ struct DOS_Version { Bit8u major,minor,revision; }; -struct DOS_Block { - DOS_Date date; - DOS_Version version; - Bit16u firstMCB; - Bit16u errorcode; - Bit16u psp; - Bit16u env; - RealPt cpmentry; - RealPt dta; - Bit8u return_code,return_mode; - - Bit8u current_drive; - bool verify; - bool breakcheck; - bool echo; // if set to true dev_con::read will echo input - struct { - RealPt indosflag; - RealPt mediaid; - RealPt tempdta; - } tables; -}; #ifdef _MSC_VER #pragma pack (1) @@ -93,7 +72,7 @@ enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; #define DOS_DRIVES 26 /* internal Dos Tables */ -extern DOS_Block dos; + extern DOS_File * Files[DOS_FILES]; extern DOS_Drive * Drives[DOS_DRIVES]; extern Bit8u dos_copybuf[0x10000]; @@ -273,8 +252,6 @@ public: void RestoreVectors (void); void SetSize (Bit16u size) { sSave(sPSP,next_seg,size); }; Bit16u GetSize (void) { return sGet(sPSP,next_seg); }; - void SetDTA (RealPt ptdta) { sSave(sPSP,dta,ptdta); }; - RealPt GetDTA (void) { return sGet(sPSP,dta); }; void SetEnvironment (Bit16u envseg) { sSave(sPSP,environment,envseg); }; Bit16u GetEnvironment (void) { return sGet(sPSP,environment); }; Bit16u GetSegment (void) { return seg; }; @@ -312,8 +289,11 @@ private: 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 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 */ @@ -520,10 +500,77 @@ private: #endif }; -extern DOS_InfoBlock dos_infoblock;; +extern Bit16u sdaseg; +#define DOS_SDA_SEG sdaseg +#define DOS_SDA_OFS 0 + + +class DOS_SDA : public MemStruct { +public: + DOS_SDA(Bit16u _seg,Bit16u _offs) { SetPt(_seg,_offs); } + void Init(); + void SetDrive(Bit8u _drive) { sSave(sSDA,current_drive, _drive); } + void SetDTA(Bit32u _dta) { sSave(sSDA,current_dta, _dta); } + void SetPSP(Bit16u _psp) { sSave(sSDA,current_psp, _psp); } + Bit8u GetDrive(void) { return sGet(sSDA,current_drive); } + Bit16u GetPSP(void) { return sGet(sSDA,current_psp); } + Bit32u GetDTA(void) { return sGet(sSDA,current_dta); } + + +private: + #ifdef _MSC_VER + #pragma pack (1) + #endif + struct sSDA { + Bit8u crit_error_flag; /* 0x00 Critical Error Flag */ + Bit8u inDOS_flag; /* 0x01 InDOS flag (count of active INT 21 calls) */ + Bit8u drive_crit_error; /* 0x02 Drive on which current critical error occurred or FFh */ + Bit8u locus_of_last_error; /* 0x03 locus of last error */ + Bit16u extended_error_code; /* 0x04 extended error code of last error */ + Bit8u suggested_action; /* 0x06 suggested action for last error */ + Bit8u error_class; /* 0x07 class of last error*/ + Bit32u last_error_pointer; /* 0x08 ES:DI pointer for last error */ + Bit32u current_dta; /* 0x0C current DTA (Disk Transfer Address) */ + Bit16u current_psp; /* 0x10 current PSP */ + Bit16u sp_int_23; /* 0x12 stores SP across an INT 23 */ + Bit16u return_code; /* 0x14 return code from last process termination (zerod after reading with AH=4Dh) */ + Bit8u current_drive; /* 0x16 current drive */ + Bit8u extended_break_flag; /* 0x17 extended break flag */ + Bit8u fill[2]; /* 0x18 flag: code page switching || flag: copy of previous byte in case of INT 24 Abort*/ + } GCC_ATTRIBUTE(packed); + #ifdef _MSC_VER + #pragma pack() + #endif +}; +extern DOS_InfoBlock dos_infoblock; + +struct DOS_Block { + DOS_Date date; + DOS_Version version; + Bit16u firstMCB; + Bit16u errorcode; + Bit16u psp(){return DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).GetPSP();}; + void psp(Bit16u _seg){ DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetPSP(_seg);}; + Bit16u env; + RealPt cpmentry; + RealPt dta(){return DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).GetDTA();}; + void dta(RealPt _dta){DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetDTA(_dta);}; + Bit8u return_code,return_mode; + + Bit8u current_drive; + bool verify; + bool breakcheck; + bool echo; // if set to true dev_con::read will echo input + struct { + RealPt mediaid; + RealPt tempdta; + } tables; +}; + +extern DOS_Block dos; INLINE Bit8u RealHandle(Bit16u handle) { - DOS_PSP psp(dos.psp); + DOS_PSP psp(dos.psp()); return psp.GetFileHandle(handle); } diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 1782b5ff..3a9928f9 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.70 2004-03-23 18:24:05 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.71 2004-05-04 18:34:07 qbix79 Exp $ */ #include #include @@ -45,20 +45,20 @@ void DOS_SetError(Bit16u code) { #define DOSNAMEBUF 256 static Bitu DOS_21Handler(void) { if (((reg_ah != 0x50) && (reg_ah != 0x51) && (reg_ah != 0x62) && (reg_ah != 0x64)) && (reg_ah<0x6c)) { - DOS_PSP psp(dos.psp); + DOS_PSP psp(dos.psp()); psp.SetStack(RealMake(SegValue(ss),reg_sp-18)); } + char name1[DOSNAMEBUF+1]; char name2[DOSNAMEBUF+1]; switch (reg_ah) { case 0x01: /* Read character from STDIN, with echo */ { Bit8u c;Bit16u n=1; - dos.echo=true; + dos.echo=true; DOS_ReadFile(STDIN,&c,&n); reg_al=c; - dos.echo=false; - + dos.echo=false; } break; case 0x02: /* Write character to STDOUT */ @@ -181,7 +181,7 @@ static Bitu DOS_21Handler(void) { break; case 0x10: /* Close File using FCB */ if(DOS_FCBClose(SegValue(ds),reg_dx)){ - reg_al=0; + reg_al=0; }else{ reg_al=0xff; } @@ -189,7 +189,7 @@ static Bitu DOS_21Handler(void) { break; case 0x11: /* Find First Matching File using FCB */ if(DOS_FCBFindFirst(SegValue(ds),reg_dx)){ - reg_al=0; + reg_al=0; }else{ reg_al=0xff; } @@ -197,7 +197,7 @@ static Bitu DOS_21Handler(void) { break; case 0x12: /* Find Next Matching File using FCB */ if(DOS_FCBFindNext(SegValue(ds),reg_dx)){ - reg_al=0; + reg_al=0; }else{ reg_al=0xff; } @@ -254,29 +254,26 @@ static Bitu DOS_21Handler(void) { LOG(LOG_FCB,LOG_NORMAL)("DOS:0x28 FCB-Random(block) write used, result:al=%d",reg_al); break; case 0x29: /* Parse filename into FCB */ - { Bit8u difference; - char string[1024]; - MEM_StrCopy(SegPhys(ds)+reg_si,string,1024); - reg_al=FCB_Parsename(SegValue(es),reg_di,reg_al ,string, &difference); - reg_si+=difference; - } + { + Bit8u difference; + char string[1024]; + MEM_StrCopy(SegPhys(ds)+reg_si,string,1024); + reg_al=FCB_Parsename(SegValue(es),reg_di,reg_al ,string, &difference); + reg_si+=difference; + } LOG(LOG_FCB,LOG_NORMAL)("DOS:29:FCB Parse Filename, result:al=%d",reg_al); - break; + break; case 0x19: /* Get current default drive */ reg_al=DOS_GetDefaultDrive(); break; case 0x1a: /* Set Disk Transfer Area Address */ - { - dos.dta=RealMakeSeg(ds,reg_dx); - DOS_PSP psp(dos.psp); - psp.SetDTA(dos.dta); - } + dos.dta(RealMakeSeg(ds,reg_dx)); break; case 0x25: /* Set Interrupt Vector */ RealSetVec(reg_al,RealMakeSeg(ds,reg_dx)); break; case 0x26: /* Create new PSP */ - DOS_NewPSP(reg_dx,DOS_PSP(dos.psp).GetSize()); + DOS_NewPSP(reg_dx,DOS_PSP(dos.psp()).GetSize()); break; case 0x2a: /* Get System Date */ { @@ -319,29 +316,43 @@ static Bitu DOS_21Handler(void) { dos.verify=(reg_al==1); break; case 0x2f: /* Get Disk Transfer Area */ - SegSet16(es,RealSeg(dos.dta)); - reg_bx=RealOff(dos.dta); + SegSet16(es,RealSeg(dos.dta())); + reg_bx=RealOff(dos.dta()); break; case 0x30: /* Get DOS Version */ if (reg_al==0) reg_bh=0xFF; /* Fake Microsoft DOS */ if (reg_al==1) reg_bh=0x10; /* DOS is in HMA */ reg_al=dos.version.major; reg_ah=dos.version.minor; + /* Serialnumber */ + reg_bl=0x00; + reg_cx=0x0000; break; case 0x31: /* Terminate and stay resident */ //TODO First get normal files executing // Important: This service does not set the carry flag! - DOS_ResizeMemory(dos.psp,®_dx); + DOS_ResizeMemory(dos.psp(),®_dx); DOS_Terminate(true); - dos.return_code=reg_al; + dos.return_code=reg_al; //Officially a field in the SDA dos.return_mode=RETURN_TSR; break; + case 0x32: /* Get drive parameter block for specific drive */ + { /* Officially a dpb should be returned as well. The disk detection part is implemented */ + Bitu drive=reg_dl;if(!drive) drive=dos.current_drive;else drive--; + if(Drives[drive]) { + reg_al=0x00; + LOG(LOG_DOSMISC,LOG_ERROR)("Get drive parameter block."); + } else { + reg_al=0xff; + } + } + break; case 0x33: /* Extended Break Checking */ switch (reg_al) { case 0:reg_dl=dos.breakcheck;break; /* Get the breakcheck flag */ case 1:dos.breakcheck=(reg_dl>0);break; /* Set the breakcheck flag */ case 2:{bool old=dos.breakcheck;dos.breakcheck=(reg_dl>0);reg_dl=old;}break; - case 5:reg_dl=3;break; /* Always boot from c: :) */ + case 5:reg_dl=3;break;//TODO should be z /* Always boot from c: :) */ case 6: /* Get true version number */ reg_bl=dos.version.major; reg_bh=dos.version.minor; @@ -353,8 +364,8 @@ static Bitu DOS_21Handler(void) { } break; case 0x34: /* Get INDos Flag */ - SegSet16(es,RealSeg(dos.tables.indosflag)); - reg_bx=RealOff(dos.tables.indosflag); + SegSet16(es,DOS_SDA_SEG); + reg_bx=DOS_SDA_OFS + 0x01; break; case 0x35: /* Get interrupt vector */ reg_bx=real_readw(0,((Bit16u)reg_al)*4); @@ -363,8 +374,8 @@ static Bitu DOS_21Handler(void) { case 0x36: /* Get Free Disk Space */ { Bit16u bytes,clusters,free; - Bit8u sectors; - if (DOS_GetFreeDiskSpace(reg_dl,&bytes,§ors,&clusters,&free)) { + Bit8u sectors; + if(DOS_GetFreeDiskSpace(reg_dl,&bytes,§ors,&clusters,&free)) { reg_ax=sectors; reg_bx=free; reg_cx=bytes; @@ -466,7 +477,7 @@ static Bitu DOS_21Handler(void) { case 0x3f: /* READ Read from file or device */ { Bit16u toread=reg_cx; - dos.echo=true; + dos.echo=true; if (DOS_ReadFile(reg_bx,dos_copybuf,&toread)) { MEM_BlockWrite(SegPhys(ds)+reg_dx,dos_copybuf,toread); reg_ax=toread; @@ -475,7 +486,7 @@ static Bitu DOS_21Handler(void) { reg_ax=dos.errorcode; CALLBACK_SCF(true); } - dos.echo=false; + dos.echo=false; break; } case 0x40: /* WRITE Write to file or device */ @@ -621,7 +632,7 @@ static Bitu DOS_21Handler(void) { break; //TODO Check for use of execution state AL=5 case 0x00: - reg_ax=0x4c00; /* Terminate Program */ + reg_ax=0x4c00; /* Terminate Program */ case 0x4c: /* EXIT Terminate with return code */ { @@ -634,7 +645,7 @@ static Bitu DOS_21Handler(void) { break; } case 0x4d: /* Get Return code */ - reg_al=dos.return_code; + reg_al=dos.return_code;/* Officially read from SDA and clear when read */ reg_ah=dos.return_mode; break; case 0x4e: /* FINDFIRST Find first matching file */ @@ -657,10 +668,10 @@ static Bitu DOS_21Handler(void) { }; break; case 0x50: /* Set current PSP */ - dos.psp=reg_bx; + dos.psp(reg_bx); break; case 0x51: /* Get current PSP */ - reg_bx=dos.psp; + reg_bx=dos.psp(); break; case 0x52: { /* Get list of lists */ RealPt addr=dos_infoblock.GetPointer(); @@ -671,14 +682,14 @@ static Bitu DOS_21Handler(void) { //TODO Think hard how shit this is gonna be //And will any game ever use this :) case 0x53: /* Translate BIOS parameter block to drive parameter block */ - E_Exit("Unhandled Dos 21 call %02X",reg_ah); - break; + E_Exit("Unhandled Dos 21 call %02X",reg_ah); + break; case 0x54: /* Get verify flag */ - reg_al=dos.verify?1:0; + reg_al=dos.verify?1:0; break; case 0x55: /* Create Child PSP*/ DOS_ChildPSP(reg_dx,reg_si); - dos.psp = reg_dx; + dos.psp(reg_dx); break; case 0x56: /* RENAME Rename file */ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); @@ -764,6 +775,15 @@ static Bitu DOS_21Handler(void) { } break; } + case 0x5d: /* Network Functions */ + if(reg_al == 0x06) { + SegSet16(ds,DOS_SDA_SEG); + reg_si = DOS_SDA_OFS; + reg_cx = 0x80; // swap if in dos + reg_dx = 0x1a; // swap always + LOG(LOG_DOSMISC,LOG_ERROR)("Get SDA, Let's hope for the best!"); + } + break; case 0x5f: /* Network redirection */ reg_ax=0x0001; //Failing it CALLBACK_SCF(true); @@ -779,7 +799,7 @@ static Bitu DOS_21Handler(void) { } break; case 0x62: /* Get Current PSP Address */ - reg_bx=dos.psp; + reg_bx=dos.psp(); break; case 0x64: /* Set device driver lookahead flag */ E_Exit("Unhandled Dos 21 call %02X",reg_ah); @@ -840,7 +860,7 @@ static Bitu DOS_21Handler(void) { case 0x67: /* Set handle count */ /* Weird call to increase amount of file handles needs to allocate memory if >20 */ { - DOS_PSP psp(dos.psp); + DOS_PSP psp(dos.psp()); psp.SetNumFiles(reg_bx); CALLBACK_SCF(false); break; @@ -873,6 +893,7 @@ static Bitu DOS_21Handler(void) { CALLBACK_SCF(true); LOG(LOG_DOSMISC,LOG_NORMAL)("DOS:Windows long file name support call %2X",reg_al); break; + case 0x68: /* FFLUSH Commit file */ case 0x63: /* Weirdo double byte stuff (fails but say it succeeded) available only in MSDOS 2.25 */ CALLBACK_SCF(false); //mirek @@ -884,10 +905,8 @@ static Bitu DOS_21Handler(void) { case 0x6b: /* NULL Function */ case 0x61: /* UNUSED */ case 0xEF: /* Used in Ancient Art Of War CGA */ - case 0x5d: /* Network Functions ||HMMM seems to critical error info and return 1!! Maybe implement it.??*/ - /* al=06 clears cf and leaves al=6 and returns crit error flag location*/ case 0x1f: /* Get drive parameter block for default drive */ - case 0x32: /* Get drive parameter block for specific drive */ + case 0x5c: /* FLOCK File region locking */ case 0x5e: /* More Network Functions */ default: @@ -912,7 +931,7 @@ static Bitu DOS_27Handler(void) { // Terminate & stay resident Bit16u para = (reg_dx/16)+((reg_dx % 16)>0); - if (DOS_ResizeMemory(dos.psp,¶)) DOS_Terminate(true); + if (DOS_ResizeMemory(dos.psp(),¶)) DOS_Terminate(true); return CBRET_NONE; } static Bitu DOS_25Handler(void) { @@ -921,9 +940,10 @@ static Bitu DOS_25Handler(void) { SETFLAGBIT(CF,true); }else{ SETFLAGBIT(CF,false); - reg_ax=0; if((reg_cx != 1) ||(reg_dx != 1)) - LOG(LOG_DOSMISC,LOG_NORMAL)("int 25 called but not as diskdetection"); + LOG(LOG_DOSMISC,LOG_NORMAL)("int 25 called but not as diskdetection drive %X",reg_al); + + reg_ax=0; } return CBRET_NONE; } diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 38b79d28..733b4dc5 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.36 2004-04-18 14:49:48 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.37 2004-05-04 18:34:08 qbix79 Exp $ */ #include #include @@ -119,7 +119,7 @@ Bit16u DOS_PSP::rootpsp = 0; void DOS_PSP::MakeNew(Bit16u mem_size) { /* get previous */ - DOS_PSP prevpsp(dos.psp); + DOS_PSP prevpsp(dos.psp()); /* Clear it first */ Bitu i; for (i=0;i #include @@ -95,7 +95,7 @@ static void RestoreRegisters(void) { extern void GFX_SetTitle(Bits cycles,Bits frameskip); void DOS_UpdatePSPName(void) { - DOS_MCB mcb(dos.psp-1); + DOS_MCB mcb(dos.psp()-1); static char name[9]; mcb.GetFileName(name); if (!strlen(name)) strcpy(name,"DOSBOX"); @@ -108,10 +108,10 @@ bool DOS_Terminate(bool tsr) { dos.return_code=reg_al; dos.return_mode=RETURN_EXIT; - Bit16u mempsp = dos.psp; + Bit16u mempsp = dos.psp(); - DOS_PSP curpsp(dos.psp); - if (dos.psp==curpsp.GetParent()) return true; + DOS_PSP curpsp(mempsp); + if (mempsp==curpsp.GetParent()) return true; /* Free Files owned by process */ if (!tsr) curpsp.CloseFiles(); @@ -120,10 +120,9 @@ bool DOS_Terminate(bool tsr) { /* Restore vector 22,23,24 */ curpsp.RestoreVectors(); /* Set the parent PSP */ - dos.psp = curpsp.GetParent(); + dos.psp(curpsp.GetParent()); DOS_PSP parentpsp(curpsp.GetParent()); - /* Restore the DTA of the parent psp */ - dos.dta = parentpsp.GetDTA(); + /* Restore the SS:SP to the previous one */ SegSet16(ss,RealSeg(parentpsp.GetStack())); reg_sp = RealOff(parentpsp.GetStack()); @@ -141,7 +140,7 @@ bool DOS_Terminate(bool tsr) { static bool MakeEnv(char * name,Bit16u * segment) { /* If segment to copy environment is 0 copy the caller's environment */ - DOS_PSP psp(dos.psp); + DOS_PSP psp(dos.psp()); PhysPt envread,envwrite; Bit16u envsize=1; bool parentenv=true; @@ -211,27 +210,11 @@ static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { DOS_PSP psp(pspseg); psp.MakeNew(memsize); psp.SetEnvironment(envseg); - /* Copy file handles //QBIX::ALWAYS COPY BUT LEFT ORIGINAL INCASE OF MISTAKES -/* if (DOS_PSP::rootpsp!=dos.psp) { */ - // TODO: Improve this - // If prog wasnt started from commandline copy file table (California Games 2) -/* DOS_PSP oldpsp(dos.psp); - psp.CopyFileTable(&oldpsp); - } else { - psp.SetFileHandle(STDIN ,DOS_FindDevice("CON")); - psp.SetFileHandle(STDOUT,DOS_FindDevice("CON")); - psp.SetFileHandle(STDERR,DOS_FindDevice("CON")); - psp.SetFileHandle(STDAUX,DOS_FindDevice("CON")); - psp.SetFileHandle(STDNUL,DOS_FindDevice("CON")); - psp.SetFileHandle(STDPRN,DOS_FindDevice("CON")); - } */ - /* Save old DTA in psp */ - DOS_PSP oldpsp(dos.psp); - psp.CopyFileTable(&oldpsp,true); - psp.SetDTA(dos.dta); - /* Setup the DTA */ - dos.dta=RealMake(pspseg,0x80); + /* Copy file handles */ + DOS_PSP oldpsp(dos.psp()); + psp.CopyFileTable(&oldpsp,true); + } static void SetupCMDLine(Bit16u pspseg,DOS_ParamBlock & block) { @@ -311,12 +294,13 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { /* Load the executable */ Bit8u * loadbuf=(Bit8u *)new Bit8u[0x10000]; loadaddress=PhysMake(loadseg,0); + if (iscom) { /* COM Load 64k - 256 bytes max */ pos=0;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET); readsize=0xffff-256; DOS_ReadFile(fhandle,loadbuf,&readsize); MEM_BlockWrite(loadaddress,loadbuf,readsize); - } else { /* EXE Load in 32kb blocks and then relocate */ + } else { /* EXE Load in 32kb blocks and then relocate */ pos=headersize;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET); while (imagesize>0x7FFF) { readsize=0x8000;DOS_ReadFile(fhandle,loadbuf,&readsize); @@ -350,7 +334,6 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { SetupPSP(pspseg,memsize,envseg); SetupCMDLine(pspseg,block); }; - CALLBACK_SCF(false); /* Carry flag cleared for caller if successfull */ if (flags==OVERLAY) return true; /* Everything done for overlays */ RealPt csip,sssp; @@ -364,12 +347,13 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { } if (flags==LOAD) { - DOS_PSP callpsp(dos.psp); + DOS_PSP callpsp(dos.psp()); /* Save the SS:SP on the PSP of calling program */ callpsp.SetStack(RealMakeSeg(ss,reg_sp)); /* Switch the psp's */ - dos.psp=pspseg; - + dos.psp(pspseg); + DOS_PSP newpsp(dos.psp()); + dos.dta(RealMake(newpsp.GetSegment(),0x80)); block.exec.initsssp = sssp; block.exec.initcsip = csip; block.SaveData(); @@ -380,14 +364,13 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { /* Get Caller's program CS:IP of the stack and set termination address to that */ RealSetVec(0x22,RealMake(mem_readw(SegPhys(ss)+reg_sp+2),mem_readw(SegPhys(ss)+reg_sp))); SaveRegisters(); - DOS_PSP callpsp(dos.psp); + DOS_PSP callpsp(dos.psp()); /* Save the SS:SP on the PSP of calling program */ callpsp.SetStack(RealMakeSeg(ss,reg_sp)); /* Switch the psp's and set new DTA */ - dos.psp=pspseg; - DOS_PSP newpsp(dos.psp); - newpsp.SetDTA(dos.dta); /* Original: change this and line below. This way seems better(zone66 and unpack) */ - //dos.dta=newpsp.GetDTA(); + dos.psp(pspseg); + DOS_PSP newpsp(dos.psp()); + dos.dta(RealMake(newpsp.GetSegment(),0x80)); /* save vectors */ newpsp.SaveVectors(); /* copy fcbs */ @@ -423,7 +406,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { index++; } memset(&stripname[index],0,8-index); - DOS_MCB pspmcb(dos.psp-1); + DOS_MCB pspmcb(dos.psp()-1); pspmcb.SetFileName(stripname); DOS_UpdatePSPName(); return true; diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 6b3ad232..9f4d74a0 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.55 2004-04-18 14:49:48 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.56 2004-05-04 18:34:08 qbix79 Exp $ */ #include #include @@ -218,7 +218,7 @@ bool DOS_Rename(char * oldname,char * newname) { } bool DOS_FindFirst(char * search,Bit16u attr,bool fcb_findfirst) { - DOS_DTA dta(dos.dta); + DOS_DTA dta(dos.dta()); Bit8u drive;char fullsearch[DOS_PATHLENGTH]; char dir[DOS_PATHLENGTH];char pattern[DOS_PATHLENGTH]; if (!DOS_MakeName(search,fullsearch,&drive)) return false; @@ -240,7 +240,7 @@ bool DOS_FindFirst(char * search,Bit16u attr,bool fcb_findfirst) { } bool DOS_FindNext(void) { - DOS_DTA dta(dos.dta); + DOS_DTA dta(dos.dta()); if (Drives[dta.GetSearchDrive()]->FindNext(dta)) return true; return false; } @@ -318,7 +318,7 @@ bool DOS_CloseFile(Bit16u entry) { /* Devices won't allow themselves to be closed or killed */ if (Files[handle]->Close()) { //if close succesfull => delete file/update psp - DOS_PSP psp(dos.psp); + DOS_PSP psp(dos.psp()); psp.SetFileHandle(entry,0xff); if (Files[handle]->RemoveRef()<=0) { delete Files[handle]; @@ -335,7 +335,7 @@ bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { return DOS_OpenFile(name, 0, entry); char fullname[DOS_PATHLENGTH];Bit8u drive; - DOS_PSP psp(dos.psp); + DOS_PSP psp(dos.psp()); if (!DOS_MakeName(name,fullname,&drive)) return false; /* Check for a free file handle */ Bit8u handle=DOS_FILES;Bit8u i; @@ -378,7 +378,7 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { } } - DOS_PSP psp(dos.psp); + DOS_PSP psp(dos.psp()); Bit8u handle=DOS_FindDevice((char *)name); bool device=false;char fullname[DOS_PATHLENGTH];Bit8u drive;Bit8u i; if (handle!=255) { @@ -519,7 +519,7 @@ bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; - DOS_PSP psp(dos.psp); + DOS_PSP psp(dos.psp()); *newentry = psp.FindFreeFileEntry(); if (*newentry==0xff) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); @@ -556,7 +556,7 @@ bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry) { DOS_CloseFile(newentry); return false; }; - DOS_PSP psp(dos.psp); + DOS_PSP psp(dos.psp()); Files[orig]->AddRef(); psp.SetFileHandle(newentry,(Bit8u)entry); return true; @@ -719,7 +719,7 @@ static void SaveFindResult(DOS_FCB & find_fcb) { drive=find_fcb.GetDrive()+1; /* Create a correct file and extention */ DTAExtendName(name,file_name,ext); - DOS_FCB fcb(RealSeg(dos.dta),RealOff(dos.dta)); + DOS_FCB fcb(RealSeg(dos.dta()),RealOff(dos.dta()));//TODO fcb.Create(find_fcb.Extended()); fcb.SetName(drive,file_name,ext); fcb.SetAttr(attr); /* Only adds attribute if fcb is extended */ @@ -747,7 +747,7 @@ bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { /* Check, if file is already opened */ for (Bit8u i=0;iIsOpen() && Files[i]->IsName(fullname)) { handle = psp.FindEntryByHandle(i); if (handle==0xFF) { @@ -773,25 +773,23 @@ bool DOS_FCBClose(Bit16u seg,Bit16u offset) { return true; } -bool DOS_FCBFindFirst(Bit16u seg,Bit16u offset) -{ +bool DOS_FCBFindFirst(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); - RealPt old_dta=dos.dta;dos.dta=dos.tables.tempdta; + RealPt old_dta=dos.dta();dos.dta(dos.tables.tempdta); char name[DOS_FCBNAME];fcb.GetName(name); Bit8u attr = DOS_ATTR_ARCHIVE; fcb.GetAttr(attr); /* Gets search attributes if extended */ bool ret=DOS_FindFirst(name,attr,true); - dos.dta=old_dta; + dos.dta(old_dta); if (ret) SaveFindResult(fcb); return ret; } -bool DOS_FCBFindNext(Bit16u seg,Bit16u offset) -{ +bool DOS_FCBFindNext(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); - RealPt old_dta=dos.dta;dos.dta=dos.tables.tempdta; + RealPt old_dta=dos.dta();dos.dta(dos.tables.tempdta); bool ret=DOS_FindNext(); - dos.dta=old_dta; + dos.dta(old_dta); if (ret) SaveFindResult(fcb); return ret; } @@ -807,11 +805,11 @@ Bit8u DOS_FCBRead(Bit16u seg,Bit16u offset,Bit16u recno) { if (!DOS_ReadFile(fhandle,dos_copybuf,&toread)) return FCB_READ_NODATA; if (toread==0) return FCB_READ_NODATA; if (toread0;i--) mem_writeb(fill++,0); } - MEM_BlockWrite(Real2Phys(dos.dta)+recno*rec_size,dos_copybuf,rec_size); + MEM_BlockWrite(Real2Phys(dos.dta())+recno*rec_size,dos_copybuf,rec_size); if (++cur_rec>127) { cur_block++;cur_rec=0; } fcb.SetRecord(cur_block,cur_rec); if (toread==rec_size) return FCB_SUCCESS; @@ -827,7 +825,7 @@ Bit8u DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u recno) fcb.GetRecord(cur_block,cur_rec); Bit32u pos=((cur_block*128)+cur_rec)*rec_size; if (!DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET)) return FCB_ERR_WRITE; - MEM_BlockRead(Real2Phys(dos.dta)+recno*rec_size,dos_copybuf,rec_size); + MEM_BlockRead(Real2Phys(dos.dta())+recno*rec_size,dos_copybuf,rec_size); Bit16u towrite=rec_size; if (!DOS_WriteFile(fhandle,dos_copybuf,&towrite)) return FCB_ERR_WRITE; Bit32u size;Bit16u date,time; @@ -863,7 +861,7 @@ Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { /* Set the correct record from the random data */ fcb.GetRandom(random); fcb.SetRecord((Bit16u)(random / 128),(Bit8u)(random & 127)); - if (restore) fcb.GetRecord(old_block,old_rec);//store this for after the read. + if (restore) fcb.GetRecord(old_block,old_rec);//store this for after the read. // Read records for (int i=0; i #include @@ -46,7 +46,7 @@ public: // Show list of cdroms if (cmd->FindExist("-cd",false)) { int num = SDL_CDNumDrives(); - WriteOut("CDROMs found: %d\n",num); + WriteOut(MSG_Get("PROGRAM_MOUNT_CDROMS_FOUND"),num); for (int i=0; iGetMediaByte()); - WriteOut("Drive %c mounted as %s\n",drive,newdrive->GetInfo()); + WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,newdrive->GetInfo()); /* check if volume label is given */ if (cmd->FindString("-label",label,true)) newdrive->dirCache.SetLabel(label.c_str()); return; @@ -443,6 +443,8 @@ static void INTRO_ProgramStart(Program * * make) { void DOS_SetupPrograms(void) { /*Add Messages */ + + MSG_Add("PROGRAM_MOUNT_CDROMS_FOUND","CDROMs found: %d\n"); MSG_Add("PROGRAM_MOUNT_STATUS_2","Drive %c is mounted as %s\n"); MSG_Add("PROGRAM_MOUNT_STATUS_1","Current mounted drives are:\n"); MSG_Add("PROGRAM_MOUNT_ERROR_1","Directory %s doesn't exist.\n"); diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 30122508..d54c3139 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.9 2004-03-23 18:51:21 qbix79 Exp $ */ +/* $Id: dos_tables.cpp,v 1.10 2004-05-04 18:34:08 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -38,6 +38,8 @@ RealPt DOS_TableUpCase; RealPt DOS_TableLowCase; static Bit16u dos_memseg; +Bit16u sdaseg; + Bit16u DOS_GetMemory(Bit16u pages) { if (pages+dos_memseg>=0xe000) { E_Exit("DOS:Not enough memory for internal tables"); @@ -54,9 +56,6 @@ void DOS_SetupTables(void) { dos.tables.mediaid=RealMake(DOS_GetMemory(2),0); dos.tables.tempdta=RealMake(DOS_GetMemory(4),0); for (i=0;i @@ -44,6 +44,7 @@ struct PIC_Controller { Bitu active; Bitu inservice; + bool special; bool auto_eoi; bool request_issr; Bit8u vector_base; @@ -103,6 +104,11 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { } } //TODO Warnings? break; + case 0x4a: /* OCW3 select read interrupt request register */ + LOG(LOG_PIC,LOG_NORMAL)("port %X : special OFF",port); + pic->special = false; + pic->request_issr = false; + break; case 0x60:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:case 0x67: /* Spefific EOI 0-7 */ if (PIC_IRQActive==(irq_base+val-0x60U)) { @@ -117,6 +123,15 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { } }//TODO Warnings? break; + case 0x68:/* OCW3 select */ + pic->special=true; + LOG(LOG_PIC,LOG_NORMAL)("port %X : special ON",port); + break; + case 0x6b: /* OCW3 select read interrupt in-service register */ + LOG(LOG_PIC,LOG_NORMAL)("port %X : special ON",port); + pic->special = true; + pic->request_issr = true; + break; case 0xC0:case 0xC1:case 0xC2:case 0xC3:case 0xC4:case 0xC5:case 0xC6:case 0xC7: /* Priority order, no need for it */ break; @@ -244,7 +259,7 @@ void PIC_runIRQs(void) { Bit16u activeIRQ = PIC_IRQActive; if (activeIRQ==PIC_NOIRQ) activeIRQ = 16; for (i=0;i<=15;i++) { - if (IRQ_priority_lookup[i] #include @@ -65,7 +65,7 @@ static Bitu PROGRAMS_Handler(void) { PROGRAMS_Main * handler=0; //It will get sneakily itinialized Bitu size=sizeof(PROGRAMS_Main *); /* Read the handler from program code in memory */ - PhysPt reader=PhysMake(dos.psp,256+sizeof(exe_block)); + PhysPt reader=PhysMake(dos.psp(),256+sizeof(exe_block)); HostPt writer=(HostPt)&handler; for (;size>0;size--) *writer++=mem_readb(reader++); Program * new_program; @@ -81,13 +81,13 @@ static Bitu PROGRAMS_Handler(void) { Program::Program() { /* Find the command line and setup the PSP */ - psp = new DOS_PSP(dos.psp); + psp = new DOS_PSP(dos.psp()); /* Scan environment for filename */ PhysPt envscan=PhysMake(psp->GetEnvironment(),0); while (mem_readb(envscan)) envscan+=mem_strlen(envscan)+1; envscan+=3; CommandTail tail; - MEM_BlockRead(PhysMake(dos.psp,128),&tail,128); + MEM_BlockRead(PhysMake(dos.psp(),128),&tail,128); if (tail.count<127) tail.buffer[tail.count]=0; else tail.buffer[126]=0; char filename[256]; diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index fdf828fd..e9789547 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.40 2004-02-19 12:00:38 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.41 2004-05-04 18:34:08 qbix79 Exp $ */ #include #include @@ -376,8 +376,9 @@ void SHELL_Init() { strcpy(tail.buffer,init_line); MEM_BlockWrite(PhysMake(psp_seg,128),&tail,128); /* Setup internal DOS Variables */ - dos.dta=psp.GetDTA(); - dos.psp=psp_seg; + + dos.dta(RealMake(psp_seg,0x80)); + dos.psp(psp_seg); Program * new_program; SHELL_ProgramStart(&new_program); diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 4642a2b7..a506e676 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: shell_batch.cpp,v 1.13 2004-05-04 18:34:08 qbix79 Exp $ */ + #include #include diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index a9eb3f9b..7294c7bf 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.40 2004-04-01 13:00:05 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.41 2004-05-04 18:34:08 qbix79 Exp $ */ #include @@ -121,7 +121,7 @@ void DOS_Shell::CMD_DELETE(char * args) { //end can't be 0, but if it is we'll get a nice crash, who cares :) char * end=strrchr(full,'\\')+1;*end=0; char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u time,date;Bit8u attr; - DOS_DTA dta(dos.dta); + DOS_DTA dta(dos.dta()); while (res) { dta.GetResult(name,size,date,time,attr); if (!(attr & (DOS_ATTR_DIRECTORY|DOS_ATTR_READ_ONLY))) { @@ -286,7 +286,7 @@ void DOS_Shell::CMD_DIR(char * args) { *(strrchr(path,'\\')+1)=0; WriteOut(MSG_Get("SHELL_CMD_DIR_INTRO"),path); - DOS_DTA dta(dos.dta); + DOS_DTA dta(dos.dta()); bool ret=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME); if (!ret) { WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); @@ -359,7 +359,7 @@ void DOS_Shell::CMD_DIR(char * args) { void DOS_Shell::CMD_COPY(char * args) { StripSpaces(args); - DOS_DTA dta(dos.dta); + DOS_DTA dta(dos.dta()); Bit32u size;Bit16u date;Bit16u time;Bit8u attr; char name[DOS_NAMELENGTH_ASCII]; diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index efefd63b..b890e9ca 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.28 2004-01-10 14:03:36 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.29 2004-05-04 18:34:08 qbix79 Exp $ */ #include #include @@ -196,7 +196,7 @@ void DOS_Shell::InputCommand(char * line) { bool res = DOS_FindFirst(mask, 0xffff & ~DOS_ATTR_VOLUME); if (!res) break; // TODO: beep - DOS_DTA dta(dos.dta); + DOS_DTA dta(dos.dta()); char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr; while (res) { @@ -369,10 +369,10 @@ void DOS_Shell::Execute(char * name,char * args) { MEM_BlockWrite(SegPhys(ss)+reg_sp+0x100,&cmd,128); /* Parse FCB (first two parameters) and put them into the current DOS_PSP */ Bit8u add; - FCB_Parsename(dos.psp,0x5C,0x00,cmd.buffer,&add); - FCB_Parsename(dos.psp,0x6C,0x00,&cmd.buffer[add],&add); - block.exec.fcb1=RealMake(dos.psp,0x5C); - block.exec.fcb2=RealMake(dos.psp,0x6C); + FCB_Parsename(dos.psp(),0x5C,0x00,cmd.buffer,&add); + FCB_Parsename(dos.psp(),0x6C,0x00,&cmd.buffer[add],&add); + block.exec.fcb1=RealMake(dos.psp(),0x5C); + block.exec.fcb2=RealMake(dos.psp(),0x6C); /* Set the command line in the block and save it */ block.exec.cmdtail=RealMakeSeg(ss,reg_sp+0x100); block.SaveData(); From 862d958ecb54d9439d91b0e4daa3677da2fbec93 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 5 May 2004 21:56:04 +0000 Subject: [PATCH 1706/4131] fix some amd64 compilation warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1788 --- include/dos_inc.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 7771d2d4..8dbfe6d2 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.42 2004-05-04 18:34:07 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.43 2004-05-05 21:56:04 harekiet Exp $ */ #ifndef DOS_H_ #define DOS_H_ @@ -208,10 +208,9 @@ INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) { /* Remains some classes used to access certain things */ - -#define sGet(s,m) GetIt(((s *)0)->m,(PhysPt)&(((s *)0)->m)) -#define sSave(s,m,val) SaveIt(((s *)0)->m,(PhysPt)&(((s *)0)->m),val) - +#define sOffset(s,m) ((char*)&(((s*)NULL)->m)-(char*)NULL) +#define sGet(s,m) GetIt(((s *)0)->m,(PhysPt)sOffset(s,m)) +#define sSave(s,m,val) SaveIt(((s *)0)->m,(PhysPt)sOffset(s,m),val) class MemStruct { public: From 7cc6fa6b8f45ad66f0d312a6b330734de4360a96 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 7 May 2004 23:20:00 +0000 Subject: [PATCH 1707/4131] Some ems weirdness(c2woody) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1789 --- src/ints/ems.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 0430fdf1..509accb5 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.32 2004-03-31 22:01:22 harekiet Exp $ */ +/* $Id: ems.cpp,v 1.33 2004-05-07 23:20:00 qbix79 Exp $ */ #include #include @@ -150,9 +150,20 @@ static Bit8u EMM_MapPage(Bitu phys_page,Bit16u handle,Bit16u log_page) { // LOG_MSG("EMS MapPage handle %d phys %d log %d",handle,phys_page,log_page); /* Check for too high physical page */ if (phys_page>=EMM_MAX_PHYS) return EMM_ILL_PHYS; + + /* unmapping doesn't need valid handle (as handle isn't used) */ + if (log_page==NULL_PAGE) { + /* Unmapping */ + emm_mappings[phys_page].handle=NULL_HANDLE; + emm_mappings[phys_page].page=NULL_PAGE; + for (Bitu i=0;i<4;i++) + PAGING_MapPage(EMM_PAGEFRAME4K+phys_page*4+i,EMM_PAGEFRAME4K+phys_page*4+i); + PAGING_ClearTLB(); + return EMM_NO_ERROR; + } /* Check for valid handle */ if (!ValidHandle(handle)) return EMM_INVALID_HANDLE; - /* Check to do unmapping or mappning */ + if (log_page Date: Tue, 11 May 2004 18:42:37 +0000 Subject: [PATCH 1708/4131] Add a soundblaster option to support soundblaster mixer changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1790 --- src/dosbox.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 862a4e1e..993540d9 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.68 2004-04-03 19:01:45 canadacow Exp $ */ +/* $Id: dosbox.cpp,v 1.69 2004-05-11 18:42:37 harekiet Exp $ */ #include #include @@ -101,7 +101,7 @@ static LoopHandler * loop; bool SDLNetInited; -Bits RemainTicks;; +Bits RemainTicks; Bits LastTicks; static Bitu Normal_Loop(void) { @@ -289,6 +289,7 @@ void DOSBOX_Init(void) { secprop->Add_int("irq",7); secprop->Add_int("dma",1); secprop->Add_int("hdma",5); + secprop->Add_bool("mixer",true); secprop->Add_int("sbrate",22050); secprop->Add_string("oplmode","auto"); secprop->Add_int("oplrate",22050); @@ -296,6 +297,7 @@ void DOSBOX_Init(void) { MSG_Add("SBLASTER_CONFIGFILE_HELP", "type -- Type of sblaster to emulate:none,sb1,sb2,sbpro1,sbpro2,sb16.\n" "base,irq,dma,hdma -- The IO/IRQ/DMA/High DMA address of the soundblaster.\n" + "mixer -- Allow the soundblaster mixer to modify the dosbox mixer.\n" "sbrate -- Sample rate of soundblaster emulation.\n" "oplmode -- Type of OPL emulation: auto,cms,opl2,dualopl2,opl3.\n" " On auto the mode is determined by sblaster type.\n" From af4ee165df2514ed65fa4980e86e80838c49f268 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 11 May 2004 18:48:32 +0000 Subject: [PATCH 1709/4131] Rename the channel name for the mixer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1791 --- src/hardware/adlib.cpp | 2 +- src/hardware/pcspeaker.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index d763aafb..0a967a3f 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -170,7 +170,7 @@ void OPL_Init(Section* sec,Bitu base,OPL_Mode oplmode,Bitu rate) { opl.last_used=0; opl.mode=oplmode; - opl.chan=MIXER_AddChannel(OPL_CallBack,rate,"ADLIB"); + opl.chan=MIXER_AddChannel(OPL_CallBack,rate,"FM"); MIXER_SetMode(opl.chan,(opl.mode>OPL_opl2) ? MIXER_16STEREO : MIXER_16MONO); MIXER_Enable(opl.chan,false); }; diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 68622121..6c9b6ba7 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -223,7 +223,7 @@ void PCSPEAKER_Init(Section* sec) { spkr.wave.count.half=spkr.wave.new_count.half=(0x10000 << SPKR_SHIFT)/2; /* Register the sound channel */ - spkr.chan=MIXER_AddChannel(&PCSPEAKER_CallBack,spkr.hw.rate,"PC-SPEAKER"); + spkr.chan=MIXER_AddChannel(&PCSPEAKER_CallBack,spkr.hw.rate,"SPKR"); MIXER_Enable(spkr.chan,false); MIXER_SetMode(spkr.chan,MIXER_16MONO); } From 2339e11d9c1350073129a9853574bea308ccd09a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 11 May 2004 18:55:33 +0000 Subject: [PATCH 1710/4131] Fix warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1792 --- src/ints/int10_char.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index a5ff6f1f..cffff625 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.26 2004-03-07 10:30:15 harekiet Exp $ */ +/* $Id: int10_char.cpp,v 1.27 2004-05-11 18:55:33 harekiet Exp $ */ /* Character displaying moving functions */ @@ -524,7 +524,7 @@ void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,B attr=mem_readb(string); string++; } else attr=7; - INT10_TeletypeOutputAttr(chr,attr,flag & 2); + INT10_TeletypeOutputAttr(chr,attr,(flag & 2)>0); count--; } if (flag & 1) { From c7e25e08b7b197fcef5c3418fb121182073cf32c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 11 May 2004 18:58:18 +0000 Subject: [PATCH 1711/4131] Add some new function and clean up Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1793 --- include/shell.h | 12 +++--------- include/support.h | 17 ++++++++++------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/include/shell.h b/include/shell.h index 6e4b6d25..9e1f336d 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.4 2004-03-10 13:35:03 qbix79 Exp $ */ +/* $Id: shell.h,v 1.5 2004-05-11 18:58:18 harekiet Exp $ */ #ifndef SHELL_H_ #define SHELL_H_ @@ -57,9 +57,7 @@ public: }; class DOS_Shell : public Program { - private: - std::list l_history, l_completion; char *completion_start; @@ -117,15 +115,12 @@ struct SHELL_Cmd { const char * help; /* String with command help */ }; -static inline void StripSpaces(char*&args) -{ +static inline void StripSpaces(char*&args) { while(*args && ((*args == ' ') || (*args == '\t'))) args++; } - -static inline char* ExpandDot(char*args, char* buffer) -{ +static inline char* ExpandDot(char*args, char* buffer) { if(*args=='.') { if(*(args+1)==0) @@ -146,5 +141,4 @@ static inline char* ExpandDot(char*args, char* buffer) return buffer; } - #endif diff --git a/include/support.h b/include/support.h index 1b663347..a8ffdc1d 100644 --- a/include/support.h +++ b/include/support.h @@ -19,11 +19,11 @@ #if !defined __SUPPORT_H #define __SUPPORT_H - -#include #include #include +#include "dosbox.h" + #if defined (_MSC_VER) /* MS Visual C++ */ #define strcasecmp(a,b) stricmp(a,b) #define strncasecmp(a,b,n) _strnicmp(a,b,n) @@ -38,14 +38,17 @@ #endif void strreplace(char * str,char o,char n); -char *ltrim(char *str); -void rtrim(char * const str); -char *trim(char *str); +char *ltrim(const char *str); +char *rtrim(const char *str); +char *trim(const char *str); bool ScanCMDBool(char * cmd,char * check); char * ScanCMDRemain(char * cmd); -bool ScanCMDHex(char * cmd,char * check,Bits * result); -char * StripWord(char * cmd); +char * StripWord(char *&cmd); +bool IsDecWord(char * word); +bool IsHexWord(char * word); +Bits ConvDecWord(char * word); +Bits ConvHexWord(char * word); INLINE char * upcase(char * str) { for (char* idx = str; *idx ; idx++) *idx = toupper(*idx); From 90a1e8494313a0ccf822929214df6626ee72c582 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 11 May 2004 18:59:32 +0000 Subject: [PATCH 1712/4131] Use new support functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1794 --- src/shell/shell_cmds.cpp | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 7294c7bf..217af2ad 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.41 2004-05-04 18:34:08 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.42 2004-05-11 18:59:32 harekiet Exp $ */ #include @@ -147,8 +147,8 @@ void DOS_Shell::CMD_RENAME(char * args){ StripSpaces(args); if(!*args) {SyntaxError();return;} if((strchr(args,'*')!=NULL) || (strchr(args,'?')!=NULL) ) { WriteOut(MSG_Get("SHELL_CMD_NO_WILD"));return;} - char * arg2 =StripWord(args); - DOS_Rename(args,arg2); + char * arg1=StripWord(args); + DOS_Rename(arg1,args); } void DOS_Shell::CMD_ECHO(char * args){ @@ -369,8 +369,8 @@ void DOS_Shell::CMD_COPY(char * args) { return; } // source/target - char* source = args; - char* target = StripWord(source); + char* source = StripWord(args); + char* target = StripWord(args); // Target and Source have to be there if (!source || !strlen(source)) { @@ -487,16 +487,13 @@ void DOS_Shell::CMD_IF(char * args) { *comp++=' '; *comp++=' '; }; - char * word; - word=args; - args=StripWord(word); + char * word=StripWord(args); if (strcasecmp(word,"NOT")==0) { - word=args; + word=StripWord(args); has_not=true; - args=StripWord(word); } if (strcasecmp(word,"EXIST")==0) { - word=args;args=StripWord(word); + word=StripWord(args); if (!*word) { WriteOut(MSG_Get("SHELL_CMD_IF_EXIST_MISSING_FILENAME")); return; @@ -506,7 +503,7 @@ void DOS_Shell::CMD_IF(char * args) { return; } if (strcasecmp(word,"ERRORLEVEL")==0) { - word=args;args=StripWord(word); + word=StripWord(args); if(!isdigit(*word)) { WriteOut(MSG_Get("SHELL_CMD_IF_ERRORLEVEL_MISSING_NUMBER")); return; @@ -525,8 +522,7 @@ void DOS_Shell::CMD_IF(char * args) { } /* Normal if string compare */ if (!*args) { SyntaxError();return;}; - char * word2=args; - args=StripWord(word2); + char * word2=StripWord(args); if ((strcmp(word,word2)==0)==(!has_not)) DoCommand(args); } @@ -554,8 +550,7 @@ void DOS_Shell::CMD_TYPE(char * args) { Bit16u handle; char * word; nextfile: - word=args; - args=StripWord(word); + word=StripWord(args); if (!DOS_OpenFile(word,0,&handle)) { WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),word); return; From bfb6e5b4e44b5eebe9c4137593e8507cf8da073c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 11 May 2004 19:00:32 +0000 Subject: [PATCH 1713/4131] new support functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1795 --- src/misc/support.cpp | 132 +++++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 75 deletions(-) diff --git a/src/misc/support.cpp b/src/misc/support.cpp index eb95fbb5..4b19768a 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.22 2004-02-18 15:31:13 qbix79 Exp $ */ +/* $Id: support.cpp,v 1.23 2004-05-11 19:00:32 harekiet Exp $ */ #include #include @@ -47,41 +47,21 @@ void strreplace(char * str,char o,char n) { str++; } } -/* - * Name: ltrim() - left trims a string by removing leading spaces - * Input: str - a pointer to a string - * Output: returns a trimmed copy of str - */ -char *ltrim(char *str) { - char c; - assert(str); - - while ((c = *str++) != '\0' && isspace(c)); - return str - 1; +char *ltrim(const char *str) { + while (*str && (*str==' ' || *str=='\t')) str++; + return (char*)str; } -/* - * Name: rtrim() - right trims a string by removing trailing spaces - * Input: str - a pointer to a string - * Output: str will have all spaces removed from the right. - */ -void rtrim(char * const str) { +char *rtrim(const char *str) { char *p; - - assert(str); - p = strchr(str, '\0'); while (--p >= str && isspace(*p)); p[1] = '\0'; + return (char*)str; } -/* - * Combines ltrim() & rtrim() - */ -char *trim(char *str) { - assert(str); - rtrim(str); - return ltrim(str); +char *trim(const char *str) { + return ltrim(rtrim(str)); } @@ -100,30 +80,6 @@ bool ScanCMDBool(char * cmd,char * check) { return false; } - -bool ScanCMDHex(char * cmd,char * check,Bits * result) { - char * scan=cmd;size_t c_len=strlen(check); - while ((scan=strchr(scan,'/'))) { - /* found a / now see behind it */ - scan++; - if (strncasecmp(scan,check,c_len)==0 && (scan[c_len]==' ' || scan[c_len]=='\t' || scan[c_len]==0)) { - /* Found a match now find the number and remove it from the string */ - char * begin=scan-1; - scan=ltrim(scan+c_len); - bool res=true; - *result=-1; - if (!sscanf(scan,"%X",result)) res=false; - scan=strrchr(scan,'/'); - if (scan) memmove(begin,scan,strlen(scan)+1); - else *begin=0; - trim(begin); - return res; - } - } - return false; - -} - /* This scans the command line for a remaining switch and reports it else returns 0*/ char * ScanCMDRemain(char * cmd) { char * scan,*found;; @@ -134,34 +90,60 @@ char * ScanCMDRemain(char * cmd) { } else return 0; } -char * StripWord(char * cmd) { +char * StripWord(char *&line) { bool quoted=false; - char * begin=cmd; - if (*cmd=='"') { - quoted=true; - cmd++; + char * scan=line; + scan=ltrim(scan); + if (*scan=='"') { + char * end_quote=strchr(scan+1,'"'); + if (end_quote) { + *end_quote=0; + line=ltrim(++end_quote); + return (scan+1); + } } - char * end = 0; - if (quoted) { - end=strchr(cmd,'"'); - } else { - for(char* in=cmd;*in;in++){ - if(*in==' '||*in=='\t'){ - end=in; - break; - } - } + char * begin=scan; + for (;char c=*scan;scan++) { + if (c==' ' || c=='\t') { + *scan++=0; + break; + } } - if (!end) { - return cmd+strlen(cmd); - } - *end=0; - if (quoted) { - memmove(begin,cmd,end-begin+1); - } - return trim(cmd+strlen(begin)+1); + line=scan; + return begin; } +Bits ConvDecWord(char * word) { + bool negative=false;Bitu ret=0; + if (*word=='-') { + negative=true; + word++; + } + while (char c=*word) { + ret*=10; + ret+=c-'0'; + word++; + } + if (negative) return 0-ret; + else return ret; +} + +Bits ConvHexWord(char * word) { + Bitu ret=0; + while (char c=toupper(*word)) { + ret*=16; + if (c>='0' && c<='9') ret+=c-'0'; + else if (c>='A' && c<='F') ret+=10+(c-'A'); + word++; + } + return ret; +} + +double ConvDblWord(char * word) { + return 0.0f; +} + + static char buf[1024]; //greater scope as else it doesn't always gets thrown right (linux/gcc2.95) void E_Exit(char * format,...) { #if C_DEBUG && C_HEAVY_DEBUG From 8e598829e832b9d392228d9485ee2dda8a989a61 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 12 May 2004 08:20:52 +0000 Subject: [PATCH 1714/4131] Add new functions for finding specific channels Changed the setting of channel volume Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1796 --- include/mixer.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/include/mixer.h b/include/mixer.h index 9309a7f0..4b839ac7 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -26,14 +26,12 @@ typedef void (*MIXER_MixHandler)(Bit8u * sampdate,Bit32u len); #define MAX_AUDIO ((1<<(16-1))-1) #define MIN_AUDIO -(1<<(16-1)) - - struct MIXER_Channel; - -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); +MIXER_Channel * MIXER_AddChannel(MIXER_MixHandler handler,Bitu freq,char * name); +MIXER_Channel * MIXER_FindChannel(const char * name); +void MIXER_SetVolume(MIXER_Channel * chan,float left,float right); +void MIXER_SetFreq(MIXER_Channel * chan,Bitu freq); void MIXER_SetMode(MIXER_Channel * chan,Bit8u mode); void MIXER_Enable(MIXER_Channel * chan,bool enable); From 54f7d437ec5be2c3ba24126cf8eb0bffba3ad1c9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 12 May 2004 08:21:30 +0000 Subject: [PATCH 1715/4131] Added mixer program on z: to change volumes Add new functions for finding specific channels Changed the setting of channel volume Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1797 --- src/hardware/mixer.cpp | 159 ++++++++++++++++++++++++++++++----------- 1 file changed, 117 insertions(+), 42 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 2c62ddc6..647dcd11 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "SDL.h" #include "mem.h" @@ -34,6 +35,7 @@ #include "cross.h" #include "support.h" #include "keyboard.h" +#include "programs.h" #define MIXER_MAXCHAN 8 #define MIXER_BUFSIZE (16*1024) @@ -41,6 +43,7 @@ #define MIXER_SHIFT 16 #define MIXER_REMAIN ((1<MAX_AUDIO) ? (Bit16s)MAX_AUDIO : (SAMPhandler)(((Bit8u*)&mixer.temp)+sizeof(mixer.temp.TYPE[0]),sample_toread); \ + (chan->handler)(((Bit8u*)&mixer.temp)+sizeof(mixer.temp.TYPE[0]),sample_toread); \ Bitu sample_index=(1 << MIXER_SHIFT) - chan->sample_left; \ - Bit32s newsample; \ for (Bitu mix=0;mix> MIXER_SHIFT;sample_index+=chan->sample_add; \ - newsample=mixer.work[mix][0]+MAKE_##TYPE( LCHAN ); \ - mixer.work[mix][0]=MIXER_CLIP(newsample); \ - newsample=mixer.work[mix][1]+MAKE_##TYPE( RCHAN ); \ - mixer.work[mix][1]=MIXER_CLIP(newsample); \ + mixer.work[mix][0]+=chan->vol_mul[LCHAN]*MAKE_##TYPE( LCHAN ); \ + mixer.work[mix][1]+=chan->vol_mul[RCHAN]*MAKE_##TYPE( RCHAN ); \ } \ - chan->remain=*(Bitu *)&mixer.temp.TYPE[sample_index>>MIXER_SHIFT]; \ + chan->remain=*(Bitu *)&mixer.temp.TYPE[sample_index>>MIXER_SHIFT]; \ chan->sample_left=sample_total-sample_index; \ break; \ } struct MIXER_Channel { - Bit8u volume; + double vol_main[2]; + Bits vol_mul[2]; Bit8u mode; Bitu freq; char * name; @@ -92,7 +93,7 @@ static struct { Bit16s data[MIXER_BUFSIZE][2]; Bitu read,write; } out; - Bit16s work[MIXER_BUFSIZE][2]; + Bit32s work[MIXER_BUFSIZE][2]; union { Bit16s m16[MIXER_BUFSIZE][1]; Bit16s s16[MIXER_BUFSIZE][2]; @@ -107,18 +108,17 @@ static struct { struct { FILE * handle; const char * dir; - Bit8u buf[MIXER_WAVESIZE]; + Bit16s buf[MIXER_WAVESIZE][2]; Bitu used; Bit32u length; } wave; } mixer; -MIXER_Channel * MIXER_AddChannel(MIXER_MixHandler handler,Bit32u freq,char * name) { +MIXER_Channel * MIXER_AddChannel(MIXER_MixHandler handler,Bitu freq,char * name) { //TODO Find a free channel MIXER_Channel * chan=new MIXER_Channel; if (!chan) return 0; chan->playing=false; - chan->volume=255; chan->mode=MIXER_16STEREO; chan->handler=handler; chan->name=name; @@ -126,38 +126,53 @@ MIXER_Channel * MIXER_AddChannel(MIXER_MixHandler handler,Bit32u freq,char * nam chan->sample_left=0; chan->next=mixer.channels; mixer.channels=chan; + MIXER_SetVolume(chan,1,1); return chan; -}; +} -void MIXER_SetFreq(MIXER_Channel * chan,Bit32u freq) { - if (chan) { - chan->freq=freq; - /* Calculate the new addition value */ - chan->sample_add=(freq<name,name)) break; + chan=chan->next; + } + return chan; +} + +void MIXER_SetFreq(MIXER_Channel * chan,Bitu freq) { + if (!chan) return; + chan->freq=freq; + chan->sample_add=(freq<mode=mode; -}; +} -void MIXER_SetVolume(MIXER_Channel * chan,Bit8u vol) { - if (chan) chan->volume=vol; +void MIXER_SetVolume(MIXER_Channel * chan,float left,float right) { + if (!chan) return; + if (left>=0) { + chan->vol_main[0]=left; + chan->vol_mul[0]=(Bits)((1 << MIXER_VOLSHIFT)*chan->vol_main[0]); + } + if (right>=0) { + chan->vol_main[1]=right; + chan->vol_mul[1]=(Bits)((1 << MIXER_VOLSHIFT)*chan->vol_main[1]); + } + LOG_MSG("%-8s %3.0f:%-3.0f %+3.2f:%-+3.2f",chan->name, + chan->vol_main[0]*100,chan->vol_main[1]*100, + 20*log(chan->vol_main[0])/log(10.0f),20*log(chan->vol_main[1])/log(10.0f) + ); } void MIXER_Enable(MIXER_Channel * chan,bool enable) { if (chan) chan->playing=enable; } - - /* Mix a certain amount of new samples */ -static void MIXER_MixData(Bit32u samples) { -/* This Should mix the channels */ +static void MIXER_MixData(Bitu samples) { if (!samples) return; if (samples>MIXER_BUFSIZE) samples=MIXER_BUFSIZE; - /* Clear work buffer */ - memset(mixer.work,0,samples*MIXER_SSIZE); MIXER_Channel * chan=mixer.channels; while (chan) { if (chan->playing) { @@ -187,22 +202,27 @@ static void MIXER_MixData(Bit32u samples) { } chan=chan->next; } - Bitu buf_remain=MIXER_BUFSIZE-mixer.out.write; - /* Fill the samples size buffer with 0's */ - if (buf_remain>samples) { - memcpy(&mixer.out.data[mixer.out.write][0],&mixer.work[0][0],samples*MIXER_SSIZE); - mixer.out.write+=samples; - } else { - memcpy(&mixer.out.data[mixer.out.write][0],&mixer.work[0][0],buf_remain*MIXER_SSIZE); - memcpy(&mixer.out.data[0][0],&mixer.work[buf_remain][0],(samples-buf_remain)*MIXER_SSIZE); - mixer.out.write=(mixer.out.write+samples)-MIXER_BUFSIZE; + Bitu index=mixer.out.write; + for (Bitu read=0;read> MIXER_VOLSHIFT; + mixer.out.data[index][0]=MIXER_CLIP(temp); + mixer.work[read][0]=0; + temp=mixer.work[read][1] >> MIXER_VOLSHIFT; + mixer.out.data[index][1]=MIXER_CLIP(temp); + mixer.work[read][1]=0; + index=(index+1)&(MIXER_BUFSIZE-1); } + mixer.out.write=index; if (mixer.wave.handle) { - memcpy(&mixer.wave.buf[mixer.wave.used],&mixer.work[0][0],samples*MIXER_SSIZE); - mixer.wave.length+=samples*MIXER_SSIZE; - mixer.wave.used+=samples*MIXER_SSIZE; + index=(MIXER_BUFSIZE+mixer.out.write-samples); + while (samples--) { + index=index&(MIXER_BUFSIZE-1); + mixer.wave.buf[mixer.wave.used][0]=mixer.out.data[index][0]; + mixer.wave.buf[mixer.wave.used][1]=mixer.out.data[index][1]; + index++;mixer.wave.used++; + } if (mixer.wave.used>(MIXER_WAVESIZE-1024)){ - fwrite(mixer.wave.buf,1,mixer.wave.used,mixer.wave.handle); + fwrite(mixer.wave.buf,1,mixer.wave.used*MIXER_SSIZE,mixer.wave.handle); mixer.wave.used=0; } } @@ -255,7 +275,7 @@ static void MIXER_WaveEvent(void) { if (mixer.wave.handle) { LOG_MSG("Stopped recording"); /* Write last piece of audio in buffer */ - fwrite(mixer.wave.buf,1,mixer.wave.used,mixer.wave.handle); + fwrite(mixer.wave.buf,1,mixer.wave.used*MIXER_SSIZE,mixer.wave.handle); /* Fill in the header with useful information */ host_writed(&wavheader[4],mixer.wave.length+sizeof(wavheader)-8); host_writed(&wavheader[0x18],mixer.freq); @@ -294,6 +314,7 @@ static void MIXER_WaveEvent(void) { return; } mixer.wave.length=0; + mixer.wave.used=0; LOG_MSG("Started recording to file %s",file_name); fwrite(wavheader,1,sizeof(wavheader),mixer.wave.handle); } @@ -302,6 +323,59 @@ static void MIXER_Stop(Section* sec) { if (mixer.wave.handle) MIXER_WaveEvent(); } +class MIXER : public Program { +public: + void Run(void) { + MIXER_Channel * chan=mixer.channels; + while (chan) { + if (cmd->FindString(chan->name,temp_line,false)) { + char * scan=(char *)temp_line.c_str(); + Bitu w=0; + while (char c=*scan) { + bool db=(toupper(c)=='D'); + if (db) { + c=*++scan; + } + if (c==':') { + c=*++scan;w=1; + } + char * before=scan; + double val=strtod(scan,&scan); + if (before==scan) { + ++scan;continue; + } + if (!db) val/=100; + else val=powf(10.0f,(float)val/20.0f); + if (val<0) val=1.0f; + if (!w) { + chan->vol_main[0]=float(val); + } else { + chan->vol_main[1]=float(val); + } + } + if (!w) chan->vol_main[1]=chan->vol_main[0]; + chan->vol_mul[0]=(Bits)((1 << MIXER_VOLSHIFT)*chan->vol_main[0]); + chan->vol_mul[1]=(Bits)((1 << MIXER_VOLSHIFT)*chan->vol_main[1]); + } + chan=chan->next; + } + if (cmd->FindExist("/NOSHOW")) return; + chan=mixer.channels; + WriteOut("Channel Main Main(dB)\n"); + while (chan) { + WriteOut("%-8s %3.0f:%-3.0f %+3.2f:%-+3.2f \n",chan->name, + chan->vol_main[0]*100,chan->vol_main[1]*100, + 20*log(chan->vol_main[0])/log(10.0f),20*log(chan->vol_main[1])/log(10.0f) + ); + chan=chan->next; + } + } +}; + +static void MIXER_ProgramStart(Program * * make) { + *make=new MIXER; +} + void MIXER_Init(Section* sec) { sec->AddDestroyFunction(&MIXER_Stop); Section_prop * section=static_cast(sec); @@ -347,4 +421,5 @@ void MIXER_Init(Section* sec) { SDL_PauseAudio(0); } KEYBOARD_AddEvent(KBD_f6,KBD_MOD_CTRL,MIXER_WaveEvent); + PROGRAMS_MakeFile("MIXER.COM",MIXER_ProgramStart); } From 9b6401446e7840c335e480b341678abadb599380 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 12 May 2004 12:48:46 +0000 Subject: [PATCH 1716/4131] Forward changes to the soundblaster mixer to the dosbox mixer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1798 --- src/hardware/sblaster.cpp | 81 ++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 30 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 2c052599..d0c0db88 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -18,6 +18,7 @@ #include #include +#include #include "dosbox.h" #include "inout.h" #include "mixer.h" @@ -122,10 +123,9 @@ struct SB_INFO { } dac; struct { Bit8u index; - struct { - Bit8u left,right; - } dac,fm,cda,master,lin; + Bit8u dac[2],fm[2],cda[2],master[2],lin[2]; Bit8u mic; + bool enabled; } mixer; struct { Bit8u reference; @@ -797,20 +797,41 @@ static Bit8u DSP_ReadData(void) { return data; } -static void MIXER_Write(Bit8u val) { +//The soundblaster manual says 2.0 Db steps but we'll go for a bit less +#define CALCVOL(_VAL) (float)pow(10.0f,((float)(31-_VAL)*-1.3f)/20) +static void CTMIXER_UpdateVolumes(void) { + if (!sb.mixer.enabled) return; + MIXER_SetVolume(MIXER_FindChannel("SB"),CALCVOL(sb.mixer.dac[0]),CALCVOL(sb.mixer.dac[1])); + MIXER_SetVolume(MIXER_FindChannel("FM"),CALCVOL(sb.mixer.fm[0]),CALCVOL(sb.mixer.fm[1])); +} + +static void CTMIXER_Reset(void) { + sb.mixer.fm[0]= + sb.mixer.fm[1]= + sb.mixer.dac[0]= + sb.mixer.dac[1]=31; + CTMIXER_UpdateVolumes(); +} + +#define SETPROVOL(_WHICH_,_VAL_) \ + _WHICH_[0]= 0x1 | ((_VAL_ & 0xf0) >> 3); \ + _WHICH_[1]= 0x1 | ((_VAL_ & 0x0f) << 1); + +static void CTMIXER_Write(Bit8u val) { + LOG_MSG("Write mixer %x %x",sb.mixer.index,val); switch (sb.mixer.index) { case 0x02: /* Master Voulme (SBPRO) Obsolete? */ case 0x22: /* Master Volume (SBPRO) */ - sb.mixer.master.left= (val & 0xf) << 1; - sb.mixer.master.right=(val >> 4) << 1; + SETPROVOL(sb.mixer.master,val); break; case 0x04: /* DAC Volume (SBPRO) */ - sb.mixer.dac.left= (val & 0xf) << 1; - sb.mixer.dac.right=(val >> 4) << 1; + SETPROVOL(sb.mixer.dac,val); + CTMIXER_UpdateVolumes(); break; case 0x06: /* FM output selection, Somewhat obsolete with dual OPL SBpro */ - sb.mixer.fm.left= (val & 0xf) << 1; - sb.mixer.fm.right=(val & 0xf) << 1; + SETPROVOL(sb.mixer.fm,val); + sb.mixer.fm[1]=sb.mixer.fm[0]; + CTMIXER_UpdateVolumes(); //TODO Change FM Mode if only 1 fm channel is selected break; case 0x0a: /* Mic Level */ @@ -822,16 +843,14 @@ static void MIXER_Write(Bit8u val) { LOG(LOG_SB,LOG_WARN)("Mixer set to %s",sb.dma.stereo ? "STEREO" : "MONO"); break; case 0x26: /* FM Volume (SBPRO) */ - sb.mixer.fm.left= (val & 0xf) << 1; - sb.mixer.fm.right=(val >> 4) << 1; + SETPROVOL(sb.mixer.fm,val); + CTMIXER_UpdateVolumes(); break; case 0x28: /* CD Audio Volume (SBPRO) */ - sb.mixer.cda.left= (val & 0xf) << 1; - sb.mixer.cda.right=(val >> 4) << 1; + SETPROVOL(sb.mixer.cda,val); break; case 0x2e: /* Line-IN Volume (SBPRO) */ - sb.mixer.lin.left= (val & 0xf) << 1; - sb.mixer.lin.right=(val >> 4) << 1; + SETPROVOL(sb.mixer.lin,val); break; case 0x80: /* IRQ Select */ sb.hw.irq=0xff; @@ -849,38 +868,38 @@ static void MIXER_Write(Bit8u val) { if (val & 0x20) sb.hw.dma16=5; else if (val & 0x40) sb.hw.dma16=6; else if (val & 0x80) sb.hw.dma16=7; + LOG(LOG_SB,LOG_NORMAL)("Mixer select dma8:%x dma16:%x",sb.hw.dma8,sb.hw.dma16); break; default: LOG(LOG_SB,LOG_WARN)("MIXER:Write %X to unhandled index %X",val,sb.mixer.index); } } -static Bit8u MIXER_Read(void) { +#define MAKEPROVOL(_WHICH_) \ + (((_WHICH_[0] & 0x1e) << 3) | ((_WHICH_[1] & 0x1e) >> 1)) + +static Bit8u CTMIXER_Read(void) { Bit8u ret; + if ( sb.mixer.index< 0x80) LOG_MSG("Read mixer %x",sb.mixer.index); switch (sb.mixer.index) { case 0x00: /* RESET */ return 0x00; case 0x02: /* Master Voulme (SBPRO) Obsolete? */ case 0x22: /* Master Volume (SBPRO) */ - return ((sb.mixer.master.left & 0x1e) >> 1) | - ((sb.mixer.master.right & 0x1e) << 3); + return MAKEPROVOL(sb.mixer.master); case 0x04: /* DAC Volume (SBPRO) */ - return ((sb.mixer.dac.left & 0x1e) >> 1) | - ((sb.mixer.dac.right & 0x1e) << 3); + return MAKEPROVOL(sb.mixer.dac); // case 0x06: /* FM output selection, Somewhat obsolete with dual OPL SBpro */ case 0x0a: /* Mic Level (SBPRO) */ return (sb.mixer.mic >> 1); case 0x0e: /* Output/Stereo Select */ return 0x11|(sb.dma.stereo ? 0x02 : 0x00)|(sb.dma.filtered ? 0x20 : 0x00); case 0x26: /* FM Volume (SBPRO) */ - return ((sb.mixer.fm.left & 0x1e) >> 1) | - ((sb.mixer.fm.right & 0x1e) << 3); + return MAKEPROVOL(sb.mixer.fm); case 0x28: /* CD Audio Volume (SBPRO) */ - return ((sb.mixer.cda.left & 0x1e) >> 1) | - ((sb.mixer.cda.right & 0x1e) << 3); + return MAKEPROVOL(sb.mixer.cda); case 0x2e: /* Line-IN Volume (SBPRO) */ - return ((sb.mixer.lin.left & 0x1e) >> 1) | - ((sb.mixer.lin.right & 0x1e) << 3); + return MAKEPROVOL(sb.mixer.lin); case 0x80: /* IRQ Select */ switch (sb.hw.irq) { case 2: return 0x1; @@ -917,7 +936,7 @@ static Bitu read_sb(Bitu port,Bitu iolen) { case MIXER_INDEX: return sb.mixer.index; case MIXER_DATA: - return MIXER_Read(); + return CTMIXER_Read(); case DSP_READ_DATA: return DSP_ReadData(); case DSP_READ_STATUS: @@ -956,7 +975,7 @@ static void write_sb(Bitu port,Bitu val,Bitu iolen) { sb.mixer.index=val; break; case MIXER_DATA: - MIXER_Write(val); + CTMIXER_Write(val); break; default: LOG(LOG_SB,LOG_NORMAL)("Unhandled write to SB Port %4X",port); @@ -986,6 +1005,7 @@ void SBLASTER_Init(Section* sec) { sb.hw.irq=section->Get_int("irq"); sb.hw.dma8=section->Get_int("dma"); sb.hw.dma16=section->Get_int("hdma"); + sb.mixer.enabled=section->Get_bool("mixer"); sb.hw.rate=section->Get_int("sbrate"); sb.hw.rate_conv=(sb.hw.rate<<16)/1000000; if (!strcasecmp(sbtype,"sb1")) sb.type=SBT_1; @@ -1030,7 +1050,7 @@ void SBLASTER_Init(Section* sec) { break; } if (sb.type==SBT_NONE) return; - sb.chan=MIXER_AddChannel(&SBLASTER_CallBack,22050,"SBLASTER"); + sb.chan=MIXER_AddChannel(&SBLASTER_CallBack,22050,"SB"); MIXER_Enable(sb.chan,false); sb.dsp.state=DSP_S_NORMAL; MIXER_SetFreq(sb.chan,sb.hw.rate); @@ -1043,6 +1063,7 @@ void SBLASTER_Init(Section* sec) { } PIC_RegisterIRQ(sb.hw.irq,0,"SB"); DSP_Reset(); + CTMIXER_Reset(); char hdma[8]=""; if (sb.type==SBT_16) { sprintf(hdma,"H%d ",sb.hw.dma16); From 5e9dd89b5645d57f8ec44ad098e36449548102f3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 13 May 2004 07:11:15 +0000 Subject: [PATCH 1717/4131] Added a master volume setting Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1799 --- src/hardware/mixer.cpp | 95 ++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 647dcd11..16a3e954 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -100,6 +100,7 @@ static struct { Bit8u m8[MIXER_BUFSIZE][1]; Bit8u s8[MIXER_BUFSIZE][2]; } temp; + double mastervol[2]; MIXER_Channel * channels; bool nosound; Bitu freq; @@ -149,20 +150,16 @@ void MIXER_SetMode(MIXER_Channel * chan,Bit8u mode) { if (chan) chan->mode=mode; } +void MIXER_UpdateVolume(MIXER_Channel * chan) { + chan->vol_mul[0]=(Bits)((1 << MIXER_VOLSHIFT)*chan->vol_main[0]*mixer.mastervol[0]); + chan->vol_mul[1]=(Bits)((1 << MIXER_VOLSHIFT)*chan->vol_main[1]*mixer.mastervol[1]); +} + void MIXER_SetVolume(MIXER_Channel * chan,float left,float right) { if (!chan) return; - if (left>=0) { - chan->vol_main[0]=left; - chan->vol_mul[0]=(Bits)((1 << MIXER_VOLSHIFT)*chan->vol_main[0]); - } - if (right>=0) { - chan->vol_main[1]=right; - chan->vol_mul[1]=(Bits)((1 << MIXER_VOLSHIFT)*chan->vol_main[1]); - } - LOG_MSG("%-8s %3.0f:%-3.0f %+3.2f:%-+3.2f",chan->name, - chan->vol_main[0]*100,chan->vol_main[1]*100, - 20*log(chan->vol_main[0])/log(10.0f),20*log(chan->vol_main[1])/log(10.0f) - ); + if (left>=0) chan->vol_main[0]=left; + if (right>=0) chan->vol_main[1]=right; + MIXER_UpdateVolume(chan); } void MIXER_Enable(MIXER_Channel * chan,bool enable) { @@ -325,50 +322,54 @@ static void MIXER_Stop(Section* sec) { class MIXER : public Program { public: + void MakeVolume(char * scan,double & vol0,double & vol1) { + Bitu w=0; + bool db=(toupper(*scan)=='D'); + if (db) scan++; + while (*scan) { + if (*scan==':') { + ++scan;w=1; + } + char * before=scan; + double val=strtod(scan,&scan); + if (before==scan) { + ++scan;continue; + } + if (!db) val/=100; + else val=powf(10.0f,(float)val/20.0f); + if (val<0) val=1.0f; + if (!w) { + vol0=val; + } else { + vol1=val; + } + } + if (!w) vol1=vol0; + } + void ShowVolume(char * name,double vol0,double vol1) { + WriteOut("%-8s %3.0f:%-3.0f %+3.2f:%-+3.2f \n",name, + vol0*100,vol1*100, + 20*log(vol0)/log(10.0f),20*log(vol1)/log(10.0f) + ); + } void Run(void) { + if (cmd->FindString("MASTER",temp_line,false)) { + MakeVolume((char *)temp_line.c_str(),mixer.mastervol[0],mixer.mastervol[1]); + } MIXER_Channel * chan=mixer.channels; while (chan) { if (cmd->FindString(chan->name,temp_line,false)) { - char * scan=(char *)temp_line.c_str(); - Bitu w=0; - while (char c=*scan) { - bool db=(toupper(c)=='D'); - if (db) { - c=*++scan; - } - if (c==':') { - c=*++scan;w=1; - } - char * before=scan; - double val=strtod(scan,&scan); - if (before==scan) { - ++scan;continue; - } - if (!db) val/=100; - else val=powf(10.0f,(float)val/20.0f); - if (val<0) val=1.0f; - if (!w) { - chan->vol_main[0]=float(val); - } else { - chan->vol_main[1]=float(val); - } - } - if (!w) chan->vol_main[1]=chan->vol_main[0]; - chan->vol_mul[0]=(Bits)((1 << MIXER_VOLSHIFT)*chan->vol_main[0]); - chan->vol_mul[1]=(Bits)((1 << MIXER_VOLSHIFT)*chan->vol_main[1]); + MakeVolume((char *)temp_line.c_str(),chan->vol_main[0],chan->vol_main[1]); } + MIXER_UpdateVolume(chan); chan=chan->next; } if (cmd->FindExist("/NOSHOW")) return; chan=mixer.channels; WriteOut("Channel Main Main(dB)\n"); - while (chan) { - WriteOut("%-8s %3.0f:%-3.0f %+3.2f:%-+3.2f \n",chan->name, - chan->vol_main[0]*100,chan->vol_main[1]*100, - 20*log(chan->vol_main[0])/log(10.0f),20*log(chan->vol_main[1])/log(10.0f) - ); - chan=chan->next; - } + ShowVolume("MASTER",mixer.mastervol[0],mixer.mastervol[1]); + for (chan=mixer.channels;chan;chan=chan->next) + ShowVolume(chan->name,chan->vol_main[0],chan->vol_main[1]); } }; @@ -392,6 +393,8 @@ void MIXER_Init(Section* sec) { memset(mixer.out.data,0,sizeof(mixer.out.data)); mixer.wave.handle=0; mixer.wave.used=0; + mixer.mastervol[0]=1.0f; + mixer.mastervol[1]=1.0f; /* Start the Mixer using SDL Sound at 22 khz */ SDL_AudioSpec spec; From 239e9b3b5a7d153de264a7fd889df8f7c7656be6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 15 May 2004 07:57:04 +0000 Subject: [PATCH 1718/4131] Fix some gcc 3.4 issues. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1800 --- include/dos_inc.h | 14 +++++++------- src/cpu/core_dyn_x86/risc_x86.h | 2 +- src/dos/dos_classes.cpp | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 8dbfe6d2..579471d5 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.43 2004-05-05 21:56:04 harekiet Exp $ */ +/* $Id: dos_inc.h,v 1.44 2004-05-15 07:57:02 harekiet Exp $ */ #ifndef DOS_H_ #define DOS_H_ @@ -214,22 +214,22 @@ INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) { class MemStruct { public: - INLINE Bit8u GetIt(Bit8u&,PhysPt addr) { + INLINE Bit8u GetIt(Bit8u,PhysPt addr) { return mem_readb(pt+addr); } - INLINE Bit16u GetIt(Bit16u&,PhysPt addr) { + INLINE Bit16u GetIt(Bit16u,PhysPt addr) { return mem_readw(pt+addr); } - INLINE Bit32u GetIt(Bit32u&,PhysPt addr) { + INLINE Bit32u GetIt(Bit32u,PhysPt addr) { return mem_readd(pt+addr); } - INLINE void SaveIt(Bit8u&,PhysPt addr,Bit8u val) { + INLINE void SaveIt(Bit8u,PhysPt addr,Bit8u val) { mem_writeb(pt+addr,val); } - INLINE void SaveIt(Bit16u&,PhysPt addr,Bit16u val) { + INLINE void SaveIt(Bit16u,PhysPt addr,Bit16u val) { mem_writew(pt+addr,val); } - INLINE void SaveIt(Bit32u&,PhysPt addr,Bit32u val) { + INLINE void SaveIt(Bit32u,PhysPt addr,Bit32u val) { mem_writed(pt+addr,val); } INLINE void SetPt(Bit16u seg) { pt=PhysMake(seg,0);} diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 4c230d2c..1ed9bcd5 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -124,7 +124,7 @@ return_address: "popl %%ebp \n" :"=a" (retval), "=c" (tempflags) :"r" (tempflags),"r" (code) - :"%edx","%ebx","%edi","%esi","%ebp","cc","memory" + :"%edx","%ebx","%edi","%esi","cc","memory" ); reg_flags=(reg_flags & ~FMASK_TEST) | (tempflags & FMASK_TEST); #endif diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 733b4dc5..a2bb9481 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.37 2004-05-04 18:34:08 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.38 2004-05-15 07:57:04 harekiet Exp $ */ #include #include @@ -146,7 +146,7 @@ void DOS_PSP::MakeNew(Bit16u mem_size) /* FCBs are filled with 0 */ // .... /* Init file pointer and max_files */ - sSave(sPSP,file_table,RealMake(seg,offsetof(sPSP,files[0]))); + sSave(sPSP,file_table,RealMake(seg,offsetof(sPSP,files))); sSave(sPSP,max_files,20); for (i=0;i<20;i++) SetFileHandle(i,0xff); @@ -243,7 +243,7 @@ void DOS_PSP::SetCommandTail(RealPt src) MEM_BlockCopy(pt+offsetof(sPSP,cmdtail),Real2Phys(src),128); } else { // empty sSave(sPSP,cmdtail.count,0x00); - mem_writeb(pt+offsetof(sPSP,cmdtail.buffer[0]),0x0d); + mem_writeb(pt+offsetof(sPSP,cmdtail.buffer),0x0d); }; }; From eb944f78034baf6d48ca8d06d77a9953e4bd7e5a Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Wed, 19 May 2004 11:42:48 +0000 Subject: [PATCH 1719/4131] Fixed cd change issue with ioctl interface (windows system message) improved mscdex support (thanx SaPu) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1801 --- src/dos/dos_mscdex.cpp | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 4559914d..5016003a 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -35,6 +35,7 @@ #define MSCDEX_MAX_DRIVES 5 // Error Codes +#define MSCDEX_ERROR_BAD_FORMAT 11 #define MSCDEX_ERROR_UNKNOWN_DRIVE 15 #define MSCDEX_ERROR_DRIVE_NOT_READY 21 @@ -95,6 +96,7 @@ public: Bit8u GetSubUnit (Bit16u _drive); bool GetUPC (Bit8u subUnit, Bit8u& attr, char* upc); + void InitNewMedia (Bit8u subUnit); bool PlayAudioSector (Bit8u subUnit, Bit32u start, Bit32u length); bool PlayAudioMSF (Bit8u subUnit, Bit32u start, Bit32u length); bool StopAudio (Bit8u subUnit); @@ -324,6 +326,8 @@ bool CMscdex::GetCDInfo(Bit8u subUnit, Bit8u& tr1, Bit8u& tr2, TMSF& leadOut) { if (subUnit>=numDrives) return false; int tr1i,tr2i; + // Assume Media change + cdrom[subUnit]->InitNewMedia(); dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioTracks(tr1i,tr2i,leadOut); if (!dinfo[subUnit].lastResult) { tr1 = tr2 = 0; @@ -452,8 +456,19 @@ Bit32u CMscdex::GetVolumeSize(Bit8u subUnit) bool CMscdex::ReadVTOC(Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error) { - ReadSectors(GetSubUnit(drive),false,/*150+*/16,1,data) ? error=0:error=MSCDEX_ERROR_DRIVE_NOT_READY; - return (error==0); + if (!ReadSectors(GetSubUnit(drive),false,16+volume,1,data)) { + error=MSCDEX_ERROR_DRIVE_NOT_READY; + return false; + } + char id[5]; + MEM_BlockRead(data + 1, id, 5); + if (strncmp("CD001",id, 5)!=0) { + error = MSCDEX_ERROR_BAD_FORMAT; + return false; + } + Bit8u type = mem_readb(data); + error = (type == 1) ? 1 : (type == 0xFF) ? 0xFF : 0; + return true; }; bool CMscdex::GetVolumeName(Bit8u subUnit, char* data) @@ -708,6 +723,14 @@ Bit16u CMscdex::GetStatusWord(Bit8u subUnit) return status; }; +void CMscdex::InitNewMedia(Bit8u subUnit) +{ + if (subUnitInitNewMedia(); + } +}; + static CMscdex* mscdex = 0; static Bitu MSCDEX_Strategy_Handler(void) @@ -1011,9 +1034,12 @@ bool MSCDEX_HasMediaChanged(Bit8u subUnit) Bit8u tr1,tr2; if (mscdex->GetCDInfo(subUnit,tr1,tr2,leadnew)) { bool changed = (leadOut[subUnit].min!=leadnew.min) || (leadOut[subUnit].sec!=leadnew.sec) || (leadOut[subUnit].fr!=leadnew.fr); - leadOut[subUnit].min = leadnew.min; - leadOut[subUnit].sec = leadnew.sec; - leadOut[subUnit].fr = leadnew.fr; + if (changed) { + leadOut[subUnit].min = leadnew.min; + leadOut[subUnit].sec = leadnew.sec; + leadOut[subUnit].fr = leadnew.fr; + mscdex->InitNewMedia(subUnit); + } return changed; }; if (subUnit Date: Wed, 19 May 2004 11:44:48 +0000 Subject: [PATCH 1720/4131] improved aspi support (thanx SaPu) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1802 --- src/dos/cdrom.h | 27 +-- src/dos/cdrom_aspi_win32.cpp | 375 +++++++++++++++++++---------------- 2 files changed, 217 insertions(+), 185 deletions(-) diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index cdfe7ab8..fe710f0c 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -46,6 +46,8 @@ public: virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0; virtual bool LoadUnloadMedia (bool unload) = 0; + + virtual void InitNewMedia (void) {}; }; class CDROM_Interface_SDL : public CDROM_Interface @@ -54,18 +56,18 @@ public: CDROM_Interface_SDL (void); virtual ~CDROM_Interface_SDL(void); - bool SetDevice (char* path, int forceCD); - bool GetUPC (unsigned char& attr, char* upc) { attr = 0; strcpy(upc,"UPC"); return true; }; - bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); - bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr); - bool GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); - bool GetAudioStatus (bool& playing, bool& pause); - bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); - bool PlayAudioSector (unsigned long start,unsigned long len); - bool PauseAudio (bool resume); - bool StopAudio (void); - bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) { return false; }; - bool LoadUnloadMedia (bool unload); + virtual bool SetDevice (char* path, int forceCD); + virtual bool GetUPC (unsigned char& attr, char* upc) { attr = 0; strcpy(upc,"UPC"); return true; }; + virtual bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); + virtual bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr); + virtual bool GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); + virtual bool GetAudioStatus (bool& playing, bool& pause); + virtual bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); + virtual bool PlayAudioSector (unsigned long start,unsigned long len); + virtual bool PauseAudio (bool resume); + virtual bool StopAudio (void); + virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) { return false; }; + virtual bool LoadUnloadMedia (bool unload); private: bool Open (void); @@ -171,6 +173,7 @@ public: bool LoadUnloadMedia (bool unload); + void InitNewMedia (void) { Close(); Open(); }; private: bool Open (void); diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index 2c85add5..a38b75e5 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_aspi_win32.cpp,v 1.10 2004-01-10 14:03:34 qbix79 Exp $ */ +/* $Id: cdrom_aspi_win32.cpp,v 1.11 2004-05-19 11:44:48 finsterr Exp $ */ #if defined (WIN32) @@ -39,6 +39,19 @@ #include "scsidefs.h" +// always use a buffer of the maximum struct size (like the union of all 'SRB_*' struct types) +// Thanx SaPu +typedef union { + SRB_HAInquiry hainquiry; + SRB_GDEVBlock gdevblock; + SRB_ExecSCSICmd execscsicmd; + SRB_Abort abort; + SRB_BusDeviceReset busdevicereset; + SRB_GetDiskInfo getdiskinfo; + SRB_RescanPort rescanport; + SRB_GetSetTimeouts getsettimeouts; +} ASPI_SRB; + // ***************************************************************** // Windows ASPI functions (should work for all WIN with ASPI layer) // ***************************************************************** @@ -78,34 +91,34 @@ bool GetRegistryValue(HKEY& hKey,char* valueName, char* buffer, ULONG bufferSize BYTE CDROM_Interface_Aspi::GetHostAdapter(char* hardwareID) { - SRB_HAInquiry sh; - SRB_GDEVBlock sd; + ASPI_SRB sh; + ASPI_SRB sd; DWORD d = pGetASPI32SupportInfo(); int cnt = LOBYTE(LOWORD(d)); int i,j,k,max; for(i=0; i> 24) & 0xFF); - s.CDBByte[3] = (unsigned char)((start >> 16) & 0xFF); - s.CDBByte[4] = (unsigned char)((start >> 8) & 0xFF); - s.CDBByte[5] = (unsigned char)((start & 0xFF)); - s.CDBByte[6] = (unsigned char)((len >> 24) & 0xFF); - s.CDBByte[7] = (unsigned char)((len >> 16) & 0xFF); - s.CDBByte[8] = (unsigned char)((len >> 8) & 0xFF); - s.CDBByte[9] = (unsigned char)(len & 0xFF); + s.execscsicmd.CDBByte[0] = SCSI_PLAYAUD_12; + s.execscsicmd.CDBByte[1] = lun << 5; + s.execscsicmd.CDBByte[2] = (unsigned char)((start >> 24) & 0xFF); + s.execscsicmd.CDBByte[3] = (unsigned char)((start >> 16) & 0xFF); + s.execscsicmd.CDBByte[4] = (unsigned char)((start >> 8) & 0xFF); + s.execscsicmd.CDBByte[5] = (unsigned char)((start & 0xFF)); + s.execscsicmd.CDBByte[6] = (unsigned char)((len >> 24) & 0xFF); + s.execscsicmd.CDBByte[7] = (unsigned char)((len >> 16) & 0xFF); + s.execscsicmd.CDBByte[8] = (unsigned char)((len >> 8) & 0xFF); + s.execscsicmd.CDBByte[9] = (unsigned char)(len & 0xFF); ResetEvent(hEvent); @@ -441,7 +459,7 @@ bool CDROM_Interface_Aspi::PlayAudioSector(unsigned long start,unsigned long len CloseHandle(hEvent); - return s.SRB_Status==SS_COMP; + return s.execscsicmd.SRB_Status==SS_COMP; } bool CDROM_Interface_Aspi::StopAudio(void) @@ -451,23 +469,25 @@ bool CDROM_Interface_Aspi::StopAudio(void) bool CDROM_Interface_Aspi::PauseAudio(bool resume) { - SRB_ExecSCSICmd s;DWORD dwStatus; + //SRB_ExecSCSICmd s; + ASPI_SRB s; + DWORD dwStatus; hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); memset(&s,0,sizeof(s)); - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = 0x00; - s.SRB_SenseLen = SENSE_LEN; - s.SRB_CDBLen = 0x0A; - s.SRB_PostProc = (LPVOID)hEvent; - s.CDBByte[0] = 0x4B; - s.CDBByte[8] = (unsigned char)resume; // Pause + s.execscsicmd.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.execscsicmd.SRB_HaId = haId; + s.execscsicmd.SRB_Target = target; + s.execscsicmd.SRB_Lun = lun; + s.execscsicmd.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.execscsicmd.SRB_BufLen = 0x00; + s.execscsicmd.SRB_SenseLen = SENSE_LEN; + s.execscsicmd.SRB_CDBLen = 0x0A; + s.execscsicmd.SRB_PostProc = (LPVOID)hEvent; + s.execscsicmd.CDBByte[0] = 0x4B; + s.execscsicmd.CDBByte[8] = (unsigned char)resume; // Pause ResetEvent(hEvent); dwStatus=pSendASPI32Command((LPSRB)&s); @@ -476,37 +496,39 @@ bool CDROM_Interface_Aspi::PauseAudio(bool resume) CloseHandle(hEvent); - return (s.SRB_Status==SS_COMP); + return (s.execscsicmd.SRB_Status==SS_COMP); }; bool CDROM_Interface_Aspi::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) { SUB_Q_CURRENT_POSITION pos; - SRB_ExecSCSICmd s;DWORD dwStatus; +// SRB_ExecSCSICmd s; + ASPI_SRB s; + DWORD dwStatus; hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); memset(&s,0,sizeof(s)); - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_SenseLen = SENSE_LEN; + s.execscsicmd.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.execscsicmd.SRB_HaId = haId; + s.execscsicmd.SRB_Target = target; + s.execscsicmd.SRB_Lun = lun; + s.execscsicmd.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.execscsicmd.SRB_SenseLen = SENSE_LEN; - s.SRB_BufLen = sizeof(pos); - s.SRB_BufPointer = (BYTE FAR *)&pos; - s.SRB_CDBLen = 10; - s.SRB_PostProc = (LPVOID)hEvent; + s.execscsicmd.SRB_BufLen = sizeof(pos); + s.execscsicmd.SRB_BufPointer = (BYTE FAR *)&pos; + s.execscsicmd.SRB_CDBLen = 10; + s.execscsicmd.SRB_PostProc = (LPVOID)hEvent; - s.CDBByte[0] = SCSI_SUBCHANNEL; - s.CDBByte[1] = (lun<<5)|2; // lun & msf - s.CDBByte[2] = 0x40; // subq - s.CDBByte[3] = 0x01; // curr pos info - s.CDBByte[6] = 0; // track number (only in isrc mode, ignored) - s.CDBByte[7] = 0; // alloc len - s.CDBByte[8] = sizeof(pos); + s.execscsicmd.CDBByte[0] = SCSI_SUBCHANNEL; + s.execscsicmd.CDBByte[1] = (lun<<5)|2; // lun & msf + s.execscsicmd.CDBByte[2] = 0x40; // subq + s.execscsicmd.CDBByte[3] = 0x01; // curr pos info + s.execscsicmd.CDBByte[6] = 0; // track number (only in isrc mode, ignored) + s.execscsicmd.CDBByte[7] = 0; // alloc len + s.execscsicmd.CDBByte[8] = sizeof(pos); ResetEvent(hEvent); @@ -516,7 +538,7 @@ bool CDROM_Interface_Aspi::GetAudioSub(unsigned char& attr, unsigned char& track CloseHandle(hEvent); - if (s.SRB_Status!=SS_COMP) return false; + if (s.execscsicmd.SRB_Status!=SS_COMP) return false; attr = (pos.Control<<4) &0xEF; track = pos.TrackNumber; @@ -534,31 +556,33 @@ bool CDROM_Interface_Aspi::GetAudioSub(unsigned char& attr, unsigned char& track bool CDROM_Interface_Aspi::GetUPC(unsigned char& attr, char* upcdata) { SUB_Q_MEDIA_CATALOG_NUMBER upc; - SRB_ExecSCSICmd s;DWORD dwStatus; + ASPI_SRB s; + //SRB_ExecSCSICmd s; + DWORD dwStatus; hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); memset(&s,0,sizeof(s)); - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_SenseLen = SENSE_LEN; + s.execscsicmd.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.execscsicmd.SRB_HaId = haId; + s.execscsicmd.SRB_Target = target; + s.execscsicmd.SRB_Lun = lun; + s.execscsicmd.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.execscsicmd.SRB_SenseLen = SENSE_LEN; - s.SRB_BufLen = sizeof(upc); - s.SRB_BufPointer = (BYTE FAR *)&upc; - s.SRB_CDBLen = 10; - s.SRB_PostProc = (LPVOID)hEvent; + s.execscsicmd.SRB_BufLen = sizeof(upc); + s.execscsicmd.SRB_BufPointer = (BYTE FAR *)&upc; + s.execscsicmd.SRB_CDBLen = 10; + s.execscsicmd.SRB_PostProc = (LPVOID)hEvent; - s.CDBByte[0] = SCSI_SUBCHANNEL; - s.CDBByte[1] = (lun<<5)|2; // lun & msf - s.CDBByte[2] = 0x40; // subq - s.CDBByte[3] = 0x02; // get upc - s.CDBByte[6] = 0; // track number (only in isrc mode, ignored) - s.CDBByte[7] = 0; // alloc len - s.CDBByte[8] = sizeof(upc); + s.execscsicmd.CDBByte[0] = SCSI_SUBCHANNEL; + s.execscsicmd.CDBByte[1] = (lun<<5)|2; // lun & msf + s.execscsicmd.CDBByte[2] = 0x40; // subq + s.execscsicmd.CDBByte[3] = 0x02; // get upc + s.execscsicmd.CDBByte[6] = 0; // track number (only in isrc mode, ignored) + s.execscsicmd.CDBByte[7] = 0; // alloc len + s.execscsicmd.CDBByte[8] = sizeof(upc); ResetEvent(hEvent); @@ -568,15 +592,14 @@ bool CDROM_Interface_Aspi::GetUPC(unsigned char& attr, char* upcdata) CloseHandle(hEvent); - if (s.SRB_Status!=SS_COMP) return false; + if (s.execscsicmd.SRB_Status!=SS_COMP) return false; // attr = (upc.ADR<<4) | upc.Control; attr = 0; int pos = 0; // Convert to mscdex format -// for (int i=0; i<6; i++) upcdata[i] = (upc.MediaCatalog[pos++]<<4)+(upc.MediaCatalog[pos++]&0x0F); -// upcdata[6] = (upc.MediaCatalog[pos++]<<4); for (int i=0; i<7; i++) upcdata[i] = upc.MediaCatalog[i]; + for (int i=0; i<7; i++) upcdata[i] = (upc.MediaCatalog[i*2] << 4) | (upc.MediaCatalog[i*2+1] & 0x0F); return true; }; @@ -586,31 +609,33 @@ bool CDROM_Interface_Aspi::GetAudioStatus(bool& playing, bool& pause) playing = pause = false; SUB_Q_HEADER sub; - SRB_ExecSCSICmd s;DWORD dwStatus; +// SRB_ExecSCSICmd s; + ASPI_SRB s; + DWORD dwStatus; hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); memset(&s,0,sizeof(s)); - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_SenseLen = SENSE_LEN; + s.execscsicmd.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.execscsicmd.SRB_HaId = haId; + s.execscsicmd.SRB_Target = target; + s.execscsicmd.SRB_Lun = lun; + s.execscsicmd.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.execscsicmd.SRB_SenseLen = SENSE_LEN; - s.SRB_BufLen = sizeof(sub); - s.SRB_BufPointer = (BYTE FAR *)⊂ - s.SRB_CDBLen = 10; - s.SRB_PostProc = (LPVOID)hEvent; + s.execscsicmd.SRB_BufLen = sizeof(sub); + s.execscsicmd.SRB_BufPointer = (BYTE FAR *)⊂ + s.execscsicmd.SRB_CDBLen = 10; + s.execscsicmd.SRB_PostProc = (LPVOID)hEvent; - s.CDBByte[0] = SCSI_SUBCHANNEL; - s.CDBByte[1] = (lun<<5)|2; // lun & msf - s.CDBByte[2] = 0x00; // no subq - s.CDBByte[3] = 0x00; // dont care - s.CDBByte[6] = 0; // track number (only in isrc mode, ignored) - s.CDBByte[7] = 0; // alloc len - s.CDBByte[8] = sizeof(sub); + s.execscsicmd.CDBByte[0] = SCSI_SUBCHANNEL; + s.execscsicmd.CDBByte[1] = (lun<<5)|2; // lun & msf + s.execscsicmd.CDBByte[2] = 0x00; // no subq + s.execscsicmd.CDBByte[3] = 0x00; // dont care + s.execscsicmd.CDBByte[6] = 0; // track number (only in isrc mode, ignored) + s.execscsicmd.CDBByte[7] = 0; // alloc len + s.execscsicmd.CDBByte[8] = sizeof(sub); ResetEvent(hEvent); @@ -620,7 +645,7 @@ bool CDROM_Interface_Aspi::GetAudioStatus(bool& playing, bool& pause) CloseHandle(hEvent); - if (s.SRB_Status!=SS_COMP) return false; + if (s.execscsicmd.SRB_Status!=SS_COMP) return false; playing = (sub.AudioStatus==0x11); pause = (sub.AudioStatus==0x12); @@ -630,27 +655,29 @@ bool CDROM_Interface_Aspi::GetAudioStatus(bool& playing, bool& pause) bool CDROM_Interface_Aspi::LoadUnloadMedia(bool unload) { - SRB_ExecSCSICmd s;DWORD dwStatus; + //SRB_ExecSCSICmd s; + ASPI_SRB s; + DWORD dwStatus; hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); memset(&s,0,sizeof(s)); - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_SenseLen = SENSE_LEN; + s.execscsicmd.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.execscsicmd.SRB_HaId = haId; + s.execscsicmd.SRB_Target = target; + s.execscsicmd.SRB_Lun = lun; + s.execscsicmd.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.execscsicmd.SRB_SenseLen = SENSE_LEN; - s.SRB_BufLen = 0; - s.SRB_BufPointer = 0; - s.SRB_CDBLen = 14; - s.SRB_PostProc = (LPVOID)hEvent; + s.execscsicmd.SRB_BufLen = 0; + s.execscsicmd.SRB_BufPointer = 0; + s.execscsicmd.SRB_CDBLen = 6; // 14; + s.execscsicmd.SRB_PostProc = (LPVOID)hEvent; - s.CDBByte[0] = SCSI_LOAD_UN; - s.CDBByte[1] = (lun<<5)|1; // lun & immediate - s.CDBByte[4] = (unload ? 0x02:0x03); // unload/load media + s.execscsicmd.CDBByte[0] = SCSI_LOAD_UN; + s.execscsicmd.CDBByte[1] = (lun<<5)|1; // lun & immediate + s.execscsicmd.CDBByte[4] = (unload ? 0x02:0x03); // unload/load media ResetEvent(hEvent); @@ -660,7 +687,7 @@ bool CDROM_Interface_Aspi::LoadUnloadMedia(bool unload) CloseHandle(hEvent); - if (s.SRB_Status!=SS_COMP) return false; + if (s.execscsicmd.SRB_Status!=SS_COMP) return false; return true; }; @@ -684,7 +711,9 @@ bool CDROM_Interface_Aspi::GetMediaTrayStatus(bool& mediaPresent, bool& mediaCha bool CDROM_Interface_Aspi::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) { - SRB_ExecSCSICmd s;DWORD dwStatus; + //SRB_ExecSCSICmd s; + ASPI_SRB s; + DWORD dwStatus; hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); @@ -693,27 +722,27 @@ bool CDROM_Interface_Aspi::ReadSectors(PhysPt buffer, bool raw, unsigned long se Bitu buflen = raw?2352*num:2048*num; Bit8u* bufdata = new Bit8u[buflen]; - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_SenseLen = SENSE_LEN; + s.execscsicmd.SRB_Cmd = SC_EXEC_SCSI_CMD; + s.execscsicmd.SRB_HaId = haId; + s.execscsicmd.SRB_Target = target; + s.execscsicmd.SRB_Lun = lun; + s.execscsicmd.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; + s.execscsicmd.SRB_SenseLen = SENSE_LEN; - s.SRB_BufLen = buflen; - s.SRB_BufPointer = (BYTE FAR*)bufdata; - s.SRB_CDBLen = 12; - s.SRB_PostProc = (LPVOID)hEvent; + s.execscsicmd.SRB_BufLen = buflen; + s.execscsicmd.SRB_BufPointer = (BYTE FAR*)bufdata; + s.execscsicmd.SRB_CDBLen = 12; + s.execscsicmd.SRB_PostProc = (LPVOID)hEvent; - s.CDBByte[0] = 0xBE; - s.CDBByte[2] = (unsigned char)((sector >> 24) & 0xFF); - s.CDBByte[3] = (unsigned char)((sector >> 16) & 0xFF); - s.CDBByte[4] = (unsigned char)((sector >> 8) & 0xFF); - s.CDBByte[5] = (unsigned char)((sector & 0xFF)); - s.CDBByte[6] = (unsigned char)((num >> 16) & 0xFF); - s.CDBByte[7] = (unsigned char)((num >> 8) & 0xFF); - s.CDBByte[8] = (unsigned char) (num & 0xFF); - s.CDBByte[9] = (raw?0xF0:0x10); + s.execscsicmd.CDBByte[0] = 0xBE; + s.execscsicmd.CDBByte[2] = (unsigned char)((sector >> 24) & 0xFF); + s.execscsicmd.CDBByte[3] = (unsigned char)((sector >> 16) & 0xFF); + s.execscsicmd.CDBByte[4] = (unsigned char)((sector >> 8) & 0xFF); + s.execscsicmd.CDBByte[5] = (unsigned char)((sector & 0xFF)); + s.execscsicmd.CDBByte[6] = (unsigned char)((num >> 16) & 0xFF); + s.execscsicmd.CDBByte[7] = (unsigned char)((num >> 8) & 0xFF); + s.execscsicmd.CDBByte[8] = (unsigned char) (num & 0xFF); + s.execscsicmd.CDBByte[9] = (raw?0xF0:0x10); ResetEvent(hEvent); @@ -728,7 +757,7 @@ bool CDROM_Interface_Aspi::ReadSectors(PhysPt buffer, bool raw, unsigned long se delete[] bufdata; - return (s.SRB_Status==SS_COMP); + return (s.execscsicmd.SRB_Status==SS_COMP); }; #endif From ca50c591ce5998125792cc518d032d687ac49466 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 19 May 2004 19:46:28 +0000 Subject: [PATCH 1721/4131] line end corrections and some reg_ah zeroing on succes with ps2 mouse Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1803 --- src/ints/bios.cpp | 110 ++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 53 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 2a10b0e5..ebce07c1 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.31 2004-03-31 14:42:08 harekiet Exp $ */ +/* $Id: bios.cpp,v 1.32 2004-05-19 19:46:28 qbix79 Exp $ */ #include #include "dosbox.h" @@ -29,7 +29,7 @@ #include "pic.h" #include "joystick.h" #include "dos_inc.h" -#include "mouse.h" +#include "mouse.h" static Bitu call_int1a,call_int11,call_int8,call_int17,call_int12,call_int15,call_int1c; static Bitu call_int1,call_int70; @@ -299,55 +299,59 @@ static Bitu INT15_Handler(void) { CALLBACK_SCF(false); reg_ah=0; break; - case 0xc3: /* set carry flag so BorlandRTM doesn't assume a VECTRA/PS2 */ - reg_ah=0x86; - CALLBACK_SCF(true); - break; + case 0xc3: /* set carry flag so BorlandRTM doesn't assume a VECTRA/PS2 */ + reg_ah=0x86; + CALLBACK_SCF(true); + break; case 0xc2: /* BIOS PS2 Pointing Device Support */ - switch (reg_al) { - case 0x00: // enable/disable - if (reg_bh==0) { // disable - Mouse_SetPS2State(false); - reg_ah=0; - CALLBACK_SCF(false); - } else if (reg_bh==0x01) { //enable - Mouse_SetPS2State(true); - reg_ah=0; - CALLBACK_SCF(false); - } else CALLBACK_SCF(true); - break; - case 0x01: // reset - reg_bx=0x00aa; // mouse - CALLBACK_SCF(false); - break; - case 0x02: // set sampling rate - CALLBACK_SCF(false); - break; - case 0x03: // set resolution - CALLBACK_SCF(false); - break; - case 0x04: // get type - reg_bh=0; // ID - CALLBACK_SCF(false); - break; - case 0x05: // initialize - CALLBACK_SCF(false); - break; - case 0x06: // extended commands - if ((reg_bh==0x01) || (reg_bh==0x02)) CALLBACK_SCF(false); - else CALLBACK_SCF(true); - break; - case 0x07: // set callback - Mouse_ChangePS2Callback(SegValue(es),reg_bx); - CALLBACK_SCF(false); - break; - default: - CALLBACK_SCF(true); - break; - } - break; - case 0xc4: /* BIOS POS Programm option Select */ - LOG(LOG_BIOS,LOG_NORMAL)("INT15:Function %X called, bios mouse not supported",reg_ah); + switch (reg_al) { + case 0x00: // enable/disable + if (reg_bh==0) { // disable + Mouse_SetPS2State(false); + reg_ah=0; + CALLBACK_SCF(false); + } else if (reg_bh==0x01) { //enable + Mouse_SetPS2State(true); + reg_ah=0; + CALLBACK_SCF(false); + } else CALLBACK_SCF(true); + break; + case 0x01: // reset + reg_bx=0x00aa; // mouse + CALLBACK_SCF(false); + break; + case 0x02: // set sampling rate + CALLBACK_SCF(false); + reg_ah=0; + break; + case 0x03: // set resolution + CALLBACK_SCF(false); + reg_ah=0; + break; + case 0x04: // get type + reg_bh=0; // ID + CALLBACK_SCF(false); + reg_ah=0; + break; + case 0x05: // initialize + CALLBACK_SCF(false); + reg_ah=0; + break; + case 0x06: // extended commands + if ((reg_bh==0x01) || (reg_bh==0x02)) { CALLBACK_SCF(false); reg_ah=0;} + else CALLBACK_SCF(true); + break; + case 0x07: // set callback + Mouse_ChangePS2Callback(SegValue(es),reg_bx); + CALLBACK_SCF(false); + break; + default: + CALLBACK_SCF(true); + break; + } + break; + case 0xc4: /* BIOS POS Programm option Select */ + LOG(LOG_BIOS,LOG_NORMAL)("INT15:Function %X called, bios mouse not supported",reg_ah); CALLBACK_SCF(true); break; default: @@ -437,20 +441,20 @@ void BIOS_Init(Section* sec) { /* Setup equipment list */ Bitu config=0x4400; //1 Floppy, 2 serial and 1 parrallel #if (C_FPU) - config|=0x2; //FPU + config|=0x2; //FPU #endif switch (machine) { case MCH_HERC: config|=0x30; //Startup monochrome break; case MCH_CGA: case MCH_TANDY: - config|=0x20; //Startup 80x25 color + config|=0x20; //Startup 80x25 color break; default: config|=0; //EGA VGA break; } - config |= 0x04; // PS2 mouse + config |= 0x04; // PS2 mouse mem_writew(BIOS_CONFIGURATION,config); /* Setup extended memory size */ IO_Write(0x70,0x30); From 4fc5d29b5efbecb1aeafdd142e1af3871f5a1ea5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 20 May 2004 11:11:45 +0000 Subject: [PATCH 1722/4131] added freesize to mount Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1804 --- README | 12 +++++++++--- src/dos/dos_programs.cpp | 11 ++++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/README b/README index fedaf568..46484459 100644 --- a/README +++ b/README @@ -73,7 +73,7 @@ In addition, the following commands are available: MOUNT "Emulated Drive letter" "Real Drive or Directory" [-t type] [-aspi] [-ioctl] [-usecd number] [-size drivesize] - [-label drivelabel] + [-label drivelabel] [-freesize sizemb] MOUNT -cd Program to mount local directories as drives inside DOSBox. @@ -93,6 +93,10 @@ MOUNT -cd -size drivesize Sets the size of the drive. + -freesize sizemb + Sets the amount of freespace avaiable on a drive in MB's. This + is a more simple version of -size. + -label drivelabel Sets the name of the drive to "drivelabel". Needed on some systems if the cd label isn't read correctly. Useful when a @@ -136,9 +140,11 @@ MOUNT -cd 3. To mount system cdrom drive at mountpoint /media/cdrom as cdrom drive D in dosbox: mount d /media/cdrom -t cdrom -usecd 0 - 4. To mount a drive with 870 mb free diskspace (rarely needed! experts only): + 4. To mount a drive with 870 mb free diskspace (simple version): + mount c d:\ -freesize 870 + 5. To mount a drive with 870 mb free diskspace (experts only, full control): mount c d:\ -size 4025,127,16513,1700 - 5. To mount /home/dos/dosgames as drive C in DOSBox: + 6. To mount /home/dos/dosgames as drive C in DOSBox: mount c /home/dos/dosgames MEM diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 58f13873..6c91e723 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.24 2004-05-04 18:34:08 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.25 2004-05-20 11:11:45 qbix79 Exp $ */ #include #include @@ -84,6 +84,15 @@ public: WriteOut(MSG_Get("PROGAM_MOUNT_ILL_TYPE"),type.c_str()); return; } + /* Parse the free space in mb's */ + std::string mb_size; + if(cmd->FindString("-freesize",mb_size,true)) { + char teststr[1024]; + Bit16u sizemb = static_cast(atoi(mb_size.c_str())); + sprintf(teststr,"512,127,16513,%d",sizemb*1024*1024/(512*127)); + str_size=teststr; + } + cmd->FindString("-size",str_size,true); char number[20];const char * scan=str_size.c_str(); Bitu index=0;Bitu count=0; From aec929e387d1e646cfd4eb570e5b2b938c7643f5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 20 May 2004 13:17:27 +0000 Subject: [PATCH 1723/4131] Fixed copy after new support functions fixed a bug with long commandlines crashing dosbox. fixed size not being updated when deleting characters in shell fixed a bug which caused stack corruption when editing commands (wjp) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1805 --- src/shell/shell.cpp | 7 ++----- src/shell/shell_cmds.cpp | 6 +++--- src/shell/shell_misc.cpp | 34 ++++++++++++++++++++++------------ 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index e9789547..b51013d7 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.41 2004-05-04 18:34:08 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.42 2004-05-20 13:17:27 qbix79 Exp $ */ #include #include @@ -108,7 +108,6 @@ Bitu DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn,bool * append) { } void DOS_Shell::ParseLine(char * line) { - /* Check for a leading @ */ if (line[0]=='@') line[0]=' '; line=trim(line); @@ -138,7 +137,6 @@ void DOS_Shell::ParseLine(char * line) { free(out); } #endif - DoCommand(line); } @@ -167,7 +165,6 @@ void DOS_Shell::RunInternal(void) void DOS_Shell::Run(void) { char input_line[CMD_MAXLINE]; std::string line; - if (cmd->FindStringRemain("/C",line)) { strcpy(input_line,line.c_str()); DOS_Shell temp; @@ -188,7 +185,7 @@ void DOS_Shell::Run(void) { if(bf->ReadLine(input_line)) { if (echo) { if (input_line[0]!='@') { - ShowPrompt(); + ShowPrompt(); WriteOut(input_line); WriteOut("\n"); }; diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 217af2ad..061f2466 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.42 2004-05-11 18:59:32 harekiet Exp $ */ +/* $Id: shell_cmds.cpp,v 1.43 2004-05-20 13:17:27 qbix79 Exp $ */ #include @@ -59,7 +59,7 @@ static SHELL_Cmd cmd_list[]={ void DOS_Shell::DoCommand(char * line) { /* First split the line into command and arguments */ line=trim(line); - char cmd[255]; + char cmd[CMD_MAXLINE]; char * cmd_write=cmd; while (*line) { if (*line==32) break; @@ -406,7 +406,7 @@ void DOS_Shell::CMD_COPY(char * args) { } }; - bool ret=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME); + bool ret=DOS_FindFirst(source,0xffff & ~DOS_ATTR_VOLUME); if (!ret) { WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); return; diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index b890e9ca..6e29221f 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.29 2004-05-04 18:34:08 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.30 2004-05-20 13:17:27 qbix79 Exp $ */ #include #include @@ -42,7 +42,7 @@ static void outs(char * str) { } void DOS_Shell::InputCommand(char * line) { - Bitu size=CMD_MAXLINE-1; + Bitu size=CMD_MAXLINE-2; //lastcharacter+0 Bit8u c;Bit16u n=1; Bitu str_len=0;Bitu str_index=0; Bit16u len; @@ -52,7 +52,7 @@ void DOS_Shell::InputCommand(char * line) { std::list::iterator it_history = l_history.begin(), it_completion = l_completion.begin(); while (size) { - dos.echo=false; + dos.echo=false; DOS_ReadFile(input_handle,&c,&n); if (!n) { size=0; //Kill the while loop @@ -74,7 +74,7 @@ void DOS_Shell::InputCommand(char * line) { DOS_WriteFile(STDOUT,&c,&n); } str_len = str_index = it_history->length(); - size = CMD_MAXLINE - str_index - 1; + size = CMD_MAXLINE - str_index - 2; } break; @@ -101,7 +101,7 @@ void DOS_Shell::InputCommand(char * line) { strcpy(line, it_history->c_str()); len = it_history->length(); str_len = str_index = len; - size = CMD_MAXLINE - str_index - 1; + size = CMD_MAXLINE - str_index - 2; DOS_WriteFile(STDOUT, (Bit8u *)line, &len); it_history ++; @@ -125,7 +125,7 @@ void DOS_Shell::InputCommand(char * line) { strcpy(line, it_history->c_str()); len = it_history->length(); str_len = str_index = len; - size = CMD_MAXLINE - str_index - 1; + size = CMD_MAXLINE - str_index - 2; DOS_WriteFile(STDOUT, (Bit8u *)line, &len); it_history ++; @@ -140,6 +140,7 @@ void DOS_Shell::InputCommand(char * line) { if (str_index) { outc(8); Bit32u str_remain=str_len - str_index; + size++; if (str_remain) { memmove(&line[str_index-1],&line[str_index],str_remain); line[--str_len]=0; @@ -228,7 +229,7 @@ void DOS_Shell::InputCommand(char * line) { strcpy(&line[completion_index], it_completion->c_str()); len = it_completion->length(); str_len = str_index = completion_index + len; - size = CMD_MAXLINE - str_index - 1; + size = CMD_MAXLINE - str_index - 2; DOS_WriteFile(STDOUT, (Bit8u *)it_completion->c_str(), &len); } } @@ -247,9 +248,12 @@ void DOS_Shell::InputCommand(char * line) { if (l_completion.size()) l_completion.clear(); line[str_index]=c; str_index ++; - if (str_index > str_len) line[str_index] = '\0'; - str_len++;//This should depend on insert being active - size--; + if (str_index > str_len){ + line[str_index] = '\0'; + str_len++;//This should depend on insert being active + size--; + } + DOS_WriteFile(STDOUT,&c,&n); break; } @@ -265,7 +269,7 @@ void DOS_Shell::InputCommand(char * line) { void DOS_Shell::Execute(char * name,char * args) { char * fullname; - char line[255]; + char line[CMD_MAXLINE]; if(strlen(args)!= 0){ if(*args != ' '){ //put a space in front line[0]=' ';line[1]=0; @@ -409,11 +413,14 @@ void DOS_Shell::Execute(char * name,char * args) { static char * bat_ext=".BAT"; static char * com_ext=".COM"; static char * exe_ext=".EXE"; -static char which_ret[DOS_PATHLENGTH]; +static char which_ret[DOS_PATHLENGTH+4]; char * DOS_Shell::Which(char * name) { + if(strlen(name) >= DOS_PATHLENGTH) return 0; + /* Parse through the Path to find the correct entry */ /* Check if name is already ok but just misses an extension */ + if (DOS_FileExists(name)) return name; /* try to find .com .exe .bat */ strcpy(which_ret,name); @@ -453,6 +460,9 @@ char * DOS_Shell::Which(char * name) { if(Bitu len=strlen(path)){ if(path[strlen(path)-1]!='\\') strcat(path,"\\"); strcat(path,name); + //If name too long =>next + if(strlen(path) >= DOS_PATHLENGTH) continue; + strcpy(which_ret,path); if (DOS_FileExists(which_ret)) return which_ret; strcpy(which_ret,path); From 9bd827965c9fc46b0c64137761882d727b48f523 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 25 May 2004 19:35:14 +0000 Subject: [PATCH 1724/4131] Add function to reset the screen Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1806 --- include/video.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/video.h b/include/video.h index ced09ad6..9ccc0e89 100644 --- a/include/video.h +++ b/include/video.h @@ -38,6 +38,7 @@ Bitu GFX_GetBestMode(Bitu bpp,Bitu & gfx_flags); Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue); void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,double scalex,double scaley,GFX_ResetCallBack cb_reset); +void GFX_ResetScreen(void); void GFX_Start(void); void GFX_Stop(void); void GFX_SwitchFullScreen(void); From a856ff1a06f4ed32009ae82f12a1a73034469410 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 25 May 2004 19:37:18 +0000 Subject: [PATCH 1725/4131] Fix some string parsing function to allow to remove the found string Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1807 --- src/misc/setup.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index d10582fb..a0e78b53 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.19 2004-01-29 09:26:52 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.20 2004-05-25 19:37:18 harekiet Exp $ */ #include "dosbox.h" #include "cross.h" @@ -385,6 +385,7 @@ bool CommandLine::FindStringBegin(char * begin,std::string & value, bool remove) for (it=cmds.begin();it!=cmds.end();it++) { if (strncmp(begin,(*it).c_str(),strlen(begin))==0) { value=((*it).c_str()+strlen(begin)); + if (remove) cmds.erase(it); return true; } } From ed76cb83a085a38b54e983044167344ac74af804 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 5 Jun 2004 11:17:23 +0000 Subject: [PATCH 1726/4131] Added -version to dosbox. Updated Readme(added -version. removed auto from machinetype) Updated Manpage(added freesize, version and machinetype) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1808 --- ChangeLog | 3 ++- README | 6 +++++- docs/dosbox.1 | 20 +++++++++++++++++--- src/gui/sdlmain.cpp | 13 +++++++++---- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6807255e..710c1bff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,11 +10,12 @@ - Changed sensitivity settings of the mouse. - 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 support for attribute-searching with fcb's. - Changed OpenGL so that it is initialized only when used. - Added basic SDA. - Changed psp and dta functions to use dta. - Added some more PIC commands. (c2woody) + - Added the -version switch, which makes dosbox report its version. 0.61 - Added a beta dynamic cpu for x86 hosts (very unstable) diff --git a/README b/README index 46484459..e7adaa3b 100644 --- a/README +++ b/README @@ -20,6 +20,8 @@ Usage: dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] [-lang languagefile] [-machine machinetype] [-noconsole] + +dosbox -version name If "name" is a directory it'll mount that as the C: drive. @@ -48,8 +50,10 @@ dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] -machine machinetype Setup dosbox to emulate a specific type of machine. Valid choices are: - auto,hercules,cga,tandy,vga. + hercules, cga, tandy, vga (default). + -version + output version information and exit. Useful for frontends. Note: If a name/command/configfile/languagefile contains a space in it, put the whole name/command/configfile/languagefile between quotes("example"). diff --git a/docs/dosbox.1 b/docs/dosbox.1 index a140290c..b19b7993 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -1,5 +1,5 @@ .\" Hey, EMACS: -*- nroff -*- -.TH DOSBOX 1 "October 5, 2003" +.TH DOSBOX 1 "June 5, 2004" .\" Please adjust this date whenever revising the manpage. .SH NAME dosbox \- an x86/DOS emulator with sound/graphics @@ -11,6 +11,9 @@ dosbox \- an x86/DOS emulator with sound/graphics .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." @@ -38,6 +41,13 @@ A summary of options is included below. .TP .B \-exit .BR dosbox " will exit after running the program specified by " file . +.TP +.BI \-machine " machinetype +.RB "Setup " dosbox " to emulate a specific type of machine." +.RI "Valid choices are: " "hercules, cga, tandy, vga(default)". +.TP +.B \-version +Output version information and exit. Useful for frontends. .SH "INTERNAL COMMANDS" .B dosbox supports most of the DOS commands found in command.com. In addition, the @@ -46,7 +56,7 @@ following extra commands are available: .BI "MOUNT [\-t " type "] [\-size " size ] .I driveletter sourcedirectory .B [\-aspi] [\-ioctl] -.BI "[\-usecd " number "] [\-label " drivelabel ] +.BI "[\-usecd " number "] [\-label " drivelabel "] [\-freesize " freesize ] .LP .B MOUNT \-cd .LP @@ -63,7 +73,11 @@ The local directory you want to have inside dosbox. Type of the mounted directory. Supported are: dir (standard), floppy, cdrom. .TP .BI \-size " drivesize" -Sets the size of the drive. +Sets the size of the drive. See the examples in the README for details. +.TP +.BI \-freesize " freesize" +Sets the amount of free space available on a drive in MB's. This is a more +.RB "simple version of " \-size . .TP .BI \-label " drivelabel" .RI "Sets the name of the drive to " drivelabel ". Needed on some" diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index d4784940..95c04792 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.64 2004-03-10 22:50:51 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.65 2004-06-05 11:17:23 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -904,6 +904,12 @@ int main(int argc, char* argv[]) { CommandLine com_line(argc,argv); Config myconf(&com_line); control=&myconf; + if (control->cmdline->FindExist("-version") || + control->cmdline->FindExist("--version") ) { + printf(VERSION "\n"); + return 0; + } + /* Can't disable the console with debugger enabled */ #if defined(WIN32) && !(C_DEBUG) @@ -930,7 +936,7 @@ int main(int argc, char* argv[]) { DEBUG_SetupConsole(); #endif - if ( SDL_Init( SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM + if ( SDL_Init( SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM #ifndef DISABLE_JOYSTICK |SDL_INIT_JOYSTICK @@ -1011,7 +1017,7 @@ int main(int argc, char* argv[]) { if(sdl.wait_on_error) { //TODO Maybe look for some way to show message in linux? #if (C_DEBUG) - LOG_MSG("Press enter to continue",error); + LOG_MSG("Press enter to continue"); fgetc(stdin); #elif defined(WIN32) Sleep(5000); @@ -1025,6 +1031,5 @@ int main(int argc, char* argv[]) { catch(...){ throw;//dunno what happened. rethrow for sdl to catch } - return 0; }; From 5acc5f9082fb6dde025afc57602b24420cfb1336 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 6 Jun 2004 18:23:10 +0000 Subject: [PATCH 1727/4131] Increase the mixer disable shutdown delay Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1809 --- src/hardware/adlib.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 0a967a3f..9e6b3c24 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -107,7 +107,7 @@ static void OPL_CallBack(Bit8u *stream, Bit32u len) { break; } - if ((PIC_Ticks-opl.last_used)>1000) { + if ((PIC_Ticks-opl.last_used)>5000) { MIXER_Enable(opl.chan,false); opl.active=false; } From f4f869a2cb22041af648bd678bf114876c81d03b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 6 Jun 2004 19:37:38 +0000 Subject: [PATCH 1728/4131] Don't allow backcounts to get below zero (acces violations). Fixes melee mode of starcon2 with gus enabled Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1810 --- src/hardware/gus.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 9c319651..61672a97 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -364,9 +364,9 @@ public: if(dir) { - // Increment backwards - if (moving) CurAddr -= RealDelta; - + // Increment backwards but don't let it get below zero. + if (moving) { if(CurAddr > RealDelta) CurAddr -= RealDelta; else CurAddr = 0; } + //Thought 16-bit needed this //if ((!eightbit) && (moving)) CurAddr -= RealDelta; From 464bba5819c72b52d5a0b10880d71073f664cd82 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 7 Jun 2004 14:40:40 +0000 Subject: [PATCH 1729/4131] Increase CMS mixer channel delay Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1811 --- src/hardware/gameblaster.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index 16ff8772..f9818097 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -383,7 +383,6 @@ static void write_cms(Bitu port,Bitu val,Bitu iolen) { break; case 0x223: saa1099[1].selected_reg = val & 0x1f; - if (saa1099[1].selected_reg == 0x18 || saa1099[1].selected_reg == 0x19) { /* clock the envelope channels */ if (saa1099[1].env_clock[0]) saa1099_envelope(1,0); @@ -416,7 +415,7 @@ static void write_cms(Bitu port,Bitu val,Bitu iolen) { else *(Bit16s *)stream=(Bit16s)right; stream+=2; } - if (last_command + 1000 < PIC_Ticks) MIXER_Enable(cms_chan,false); + if (last_command + 5000 < PIC_Ticks) MIXER_Enable(cms_chan,false); } @@ -435,7 +434,6 @@ static void write_cms(Bitu port,Bitu val,Bitu iolen) { for (int s=0;s<2;s++) { struct SAA1099 *saa = &saa1099[s]; - memset(saa, 0, sizeof(struct SAA1099)); } } From f6938602bd86fcf78ac457087bbe9af721051647 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 7 Jun 2004 14:41:20 +0000 Subject: [PATCH 1730/4131] Add an adlib command register to the gus Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1812 --- include/hardware.h | 1 + src/hardware/gus.cpp | 20 +++++++++----------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/include/hardware.h b/include/hardware.h index af8be44a..94f2ffac 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -26,6 +26,7 @@ enum OPL_Mode { void OPL_Init(Section* sec,Bitu base,OPL_Mode mode,Bitu rate); void CMS_Init(Section* sec,Bitu base,Bitu rate); +extern Bit8u adlib_commandreg; #endif diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 61672a97..5da89a9d 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -43,7 +43,9 @@ static Bit8u dmatable[6] = { 3, 1, 5, 5, 6, 7 }; static Bit8u GUSRam[1024*1024]; // 1024K of GUS Ram -Bit32s AutoAmp=1024; +static Bit32s AutoAmp=1024; + +Bit8u adlib_commandreg; struct GFGus { Bit8u gRegSelect; @@ -62,16 +64,12 @@ struct GFGus { Bit32s mupersamp; Bit32s muperchan; - - Bit8u timerReg; struct GusTimer { Bit16u bytetimer; Bit32s countdown; Bit32s setting; bool active; } timers[2]; - - Bit32u rate; Bit16u portbase; Bit16u dma1; @@ -511,7 +509,7 @@ static void GUSReset(void) { if((myGUS.gRegData & 0x1) == 0x1) { // Reset - myGUS.timerReg = 85; + adlib_commandreg = 85; memset(&myGUS.irq, 0, sizeof(myGUS.irq)); } if((myGUS.gRegData & 0x4) != 0) { @@ -770,7 +768,6 @@ static void ExecuteGlobRegister(void) { static Bitu read_gus(Bitu port,Bitu iolen) { - switch(port - GUS_BASE) { case 0x206: Bit8u temp; @@ -788,13 +785,12 @@ static Bitu read_gus(Bitu port,Bitu iolen) { case 0x208: Bit8u tmptime; tmptime = 0; - if(myGUS.irq.T1) tmptime |= (1 << 6); if(myGUS.irq.T2) tmptime |= (1 << 5); if((myGUS.irq.T1) || (myGUS.irq.T2)) tmptime |= (1 << 7); return tmptime; case 0x20a: - return myGUS.timerReg; + return adlib_commandreg; case 0x302: return (Bit8u)myGUS.gCurChannel; case 0x303: @@ -825,12 +821,14 @@ static void write_gus(Bitu port,Bitu val,Bitu iolen) { myGUS.mixControl = val; break; case 0x208: - myGUS.timerReg = val; + adlib_commandreg = val; break; case 0x209: +//TODO adlib_commandreg should be 4 for this to work else it should just latch the value myGUS.timers[0].active = ((val & 0x1) > 0); myGUS.timers[1].active = ((val & 0x2) > 0); break; +//TODO Check if 0x20a register is also available on the gus like on the interwave case 0x20b: if((myGUS.mixControl & 0x40) != 0) { // IRQ configuration @@ -1025,7 +1023,7 @@ void GUS_Init(Section* sec) { myGUS.irq2 = section->Get_int("irq2"); strcpy(&myGUS.ultradir[0], section->Get_string("ultradir")); - myGUS.timerReg = 85; + adlib_commandreg = 85; myGUS.timers[0].active = false; myGUS.timers[1].active = false; From 70914f545ebd5002e4eb903766f5b7661c318999 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 7 Jun 2004 14:42:36 +0000 Subject: [PATCH 1731/4131] forward data to adlib command register of the gus Don't use the cms ports when in opl2 mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1813 --- src/hardware/adlib.cpp | 9 +++++---- src/hardware/sblaster.cpp | 9 ++++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 9e6b3c24..5c276768 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -28,7 +28,6 @@ /* Thanks to vdmsound for nice simple way to implement this */ - # define logerror #ifdef _MSC_VER @@ -133,6 +132,7 @@ void OPL_Write(Bitu port,Bitu val,Bitu iolen) { MIXER_Enable(opl.chan,true); } Bitu addr=port & 3; + if (!addr) adlib_commandreg=val; switch (opl.mode) { case OPL_opl2: OPL2::YM3812Write(0,addr,val); @@ -159,13 +159,14 @@ void OPL_Init(Section* sec,Bitu base,OPL_Mode oplmode,Bitu rate) { THEOPL3::YMF262SetTimerHandler(0,THEOPL3::TimerHandler,0); IO_RegisterWriteHandler(0x388,OPL_Write,IO_MB,4); IO_RegisterReadHandler(0x388,OPL_Read,IO_MB,4); - IO_RegisterWriteHandler(base,OPL_Write,IO_MB,4); - IO_RegisterReadHandler(base,OPL_Read,IO_MB,4); + if (oplmode>=OPL_dualopl2) { + IO_RegisterWriteHandler(base,OPL_Write,IO_MB,4); + IO_RegisterReadHandler(base,OPL_Read,IO_MB,4); + } IO_RegisterWriteHandler(base+8,OPL_Write,IO_MB,2); IO_RegisterReadHandler(base+8,OPL_Read,IO_MB,2); - opl.active=false; opl.last_used=0; opl.mode=oplmode; diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index d0c0db88..5ffae9a8 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -983,6 +983,10 @@ static void write_sb(Bitu port,Bitu val,Bitu iolen) { } } +static void adlib_gusforward(Bitu port,Bitu val,Bitu iolen) { + adlib_commandreg=val; +} + static void SBLASTER_CallBack(Bit8u * stream,Bit32u len) { if (!len) return; GenerateSound(len); @@ -1029,7 +1033,7 @@ void SBLASTER_Init(Section* sec) { else { switch (sb.type) { case SBT_NONE:opl_mode=OPL_none;break; - case SBT_1:opl_mode=OPL_cms;break; + case SBT_1:opl_mode=OPL_opl2;break; case SBT_2:opl_mode=OPL_opl2;break; case SBT_PRO1:opl_mode=OPL_dualopl2;break; case SBT_PRO2: @@ -1039,11 +1043,14 @@ void SBLASTER_Init(Section* sec) { } switch (opl_mode) { case OPL_none: + IO_RegisterWriteHandler(0x388,adlib_gusforward,IO_MB); break; case OPL_cms: + IO_RegisterWriteHandler(0x388,adlib_gusforward,IO_MB); CMS_Init(section,sb.hw.base,oplrate); break; case OPL_opl2: + CMS_Init(section,sb.hw.base,oplrate); case OPL_dualopl2: case OPL_opl3: OPL_Init(section,sb.hw.base,opl_mode,oplrate); From 6e373ca48972f7c339b54c723cf1eb1dce7b1753 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 9 Jun 2004 09:11:55 +0000 Subject: [PATCH 1732/4131] moved default buffer into dosbox reservered memory Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1814 --- src/dos/dos_mscdex.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 5016003a..335584ba 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: dos_mscdex.cpp,v 1.21 2004-06-09 09:11:55 qbix79 Exp $ */ + #include #include #include "regs.h" @@ -306,9 +308,8 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) PhysPt CMscdex::GetDefaultBuffer(void) { if (defaultBuffer==0) { - Bit16u seg,size = 128; - if (!DOS_AllocateMemory(&seg,&size)) E_Exit("MSCDEX: cannot allocate default buffer."); - defaultBuffer = PhysMake(seg,0); + Bit16u size = 128; //Size in block is size in pages ? + defaultBuffer = DOS_GetMemory(size); }; return defaultBuffer; }; From de831a5899e2cc6493ad53a88137943a7eedaa74 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 10 Jun 2004 07:13:02 +0000 Subject: [PATCH 1733/4131] Remove exception warning Use new mapper functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1815 --- src/cpu/cpu.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 74f1069a..c162cede 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,14 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.57 2004-04-24 09:16:42 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.58 2004-06-10 07:13:02 harekiet Exp $ */ #include #include "dosbox.h" #include "cpu.h" #include "memory.h" #include "debug.h" -#include "keyboard.h" +#include "mapper.h" #include "setup.h" #include "paging.h" #include "support.h" @@ -324,7 +324,7 @@ doexception: } void CPU_Exception(Bitu which,Bitu error ) { - LOG_MSG("Exception %d error %x",which,error); +// LOG_MSG("Exception %d error %x",which,error); cpu.exception.error=error; CPU_Interrupt(which,CPU_INT_EXCEPTION | ((which>=8) ? CPU_INT_HAS_ERROR : 0),reg_eip); } @@ -1350,10 +1350,8 @@ void CPU_Init(Section* sec) { #if (C_DYNAMIC_X86) CPU_Core_Dyn_X86_Init(); #endif - - KEYBOARD_AddEvent(KBD_f11,KBD_MOD_CTRL,CPU_CycleDecrease); - KEYBOARD_AddEvent(KBD_f12,KBD_MOD_CTRL,CPU_CycleIncrease); - + MAPPER_AddHandler(CPU_CycleDecrease,MK_f11,MMOD1,"cycledown","Dec Cycles"); + MAPPER_AddHandler(CPU_CycleIncrease,MK_f12,MMOD1,"cycleup" ,"Inc Cycles"); CPU_Cycles=0; CPU_CycleMax=section->Get_int("cycles");; CPU_CycleUp=section->Get_int("cycleup"); From 7dcfa9c70ac44a4d520b7699f0945f98f4bdabd3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 10 Jun 2004 07:15:11 +0000 Subject: [PATCH 1734/4131] New stuff added for some hardware acceleration functions of the S3 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1816 --- include/vga.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/include/vga.h b/include/vga.h index 7623504e..f2b19b9d 100644 --- a/include/vga.h +++ b/include/vga.h @@ -101,7 +101,7 @@ typedef struct { Bitu address_line_total; Bitu address_line; Bitu lines_total; - Bitu lines_left; + Bitu lines_done; Bitu lines_scaled; Bitu split_line; Bitu parts_total; @@ -131,13 +131,26 @@ typedef struct { } cursor; } 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 bank; Bit8u reg_lock1; Bit8u reg_lock2; Bit8u reg_31; Bit8u reg_35; + Bit8u reg_40; // 8415/A functionality register Bit8u reg_43; + Bit8u reg_45; // Hardware graphics cursor Bit8u reg_58; Bit8u reg_51; Bit8u reg_55; @@ -145,6 +158,7 @@ typedef struct { Bit8u ex_ver_overflow; Bit16u la_window; Bit8u misc_control_2; + Bit8u ext_mem_ctrl; struct { Bit8u r; Bit8u n; @@ -154,6 +168,7 @@ typedef struct { Bit8u lock; Bit8u cmd; } pll; + VGA_HWCURSOR hgc; } VGA_S3; typedef struct { @@ -323,6 +338,7 @@ 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); From 9213fd5bd6d5429c13b9d8dedec9bbfc0dd10ca8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 10 Jun 2004 07:18:53 +0000 Subject: [PATCH 1735/4131] New rendering changes New mapper changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1817 --- include/render.h | 14 +- include/video.h | 25 +- src/gui/Makefile.am | 4 +- src/gui/render.cpp | 308 ++++------ src/gui/render_normal.h | 59 -- src/gui/render_scale2x.h | 118 ---- src/gui/render_scalers.cpp | 121 ++++ src/gui/render_scalers.h | 51 ++ src/gui/render_templates.h | 325 ++++++++-- src/gui/sdl_mapper.cpp | 1187 ++++++++++++++++++++++++++++++++++++ src/gui/sdlmain.cpp | 297 +++------ 11 files changed, 1858 insertions(+), 651 deletions(-) delete mode 100644 src/gui/render_normal.h delete mode 100644 src/gui/render_scale2x.h create mode 100644 src/gui/render_scalers.cpp create mode 100644 src/gui/render_scalers.h create mode 100644 src/gui/sdl_mapper.cpp diff --git a/include/render.h b/include/render.h index 9782f6a8..1c25a5c2 100644 --- a/include/render.h +++ b/include/render.h @@ -19,22 +19,14 @@ #ifndef __RENDER_H #define __RENDER_H -enum RENDER_Operation { - OP_None, - OP_Shot, - OP_Normal2x, - OP_AdvMame2x, -}; +typedef void (* RENDER_Line_Handler)(const Bit8u * src); -typedef void (* RENDER_Line_Handler)(Bit8u * src); - -void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,Bitu scalew,Bitu scaleh); +void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,bool dblw,bool dblh); bool RENDER_StartUpdate(void); void RENDER_EndUpdate(void); void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue); extern RENDER_Line_Handler RENDER_DrawLine; -extern Bit8u * RENDER_TempLine; - + #endif diff --git a/include/video.h b/include/video.h index 9ccc0e89..9caa2bef 100644 --- a/include/video.h +++ b/include/video.h @@ -28,15 +28,32 @@ struct GFX_PalEntry { Bit8u unused; }; -#define GFX_HASSCALING 0x0001 -#define GFX_HASCONVERT 0x0002 +#define CAN_8 0x0001 +#define CAN_16 0x0002 +#define CAN_32 0x0004 + +#define CAN_ALL (CAN_8|CAN_16|CAN_32) + +#define LOVE_8 0x0010 +#define LOVE_16 0x0020 +#define LOVE_32 0x0040 + +#define NEED_RGB 0x0100 +#define DONT_ASPECT 0x0200 + +#define HAVE_SCALING 0x1000 + + +enum GFX_Modes { + GFX_8,GFX_15,GFX_16,GFX_32,GFX_NONE, +}; void GFX_Events(void); void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries); -Bitu GFX_GetBestMode(Bitu bpp,Bitu & gfx_flags); +Bitu GFX_GetBestMode(Bitu flags); Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue); -void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,double scalex,double scaley,GFX_ResetCallBack cb_reset); +GFX_Modes GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_ResetCallBack cb_reset); void GFX_ResetScreen(void); void GFX_Start(void); diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 0aea3749..8d76e38d 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -1,7 +1,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libgui.a -libgui_a_SOURCES = sdlmain.cpp \ - render.cpp render_normal.h render_scale2x.h render_templates.h \ +libgui_a_SOURCES = sdlmain.cpp sdl_mapper.cpp \ + render.cpp render_scalers.cpp render_scalers.h render_templates.h \ midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h midi_alsa.h diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 2fcaab42..65ea4341 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.26 2004-02-07 18:50:10 harekiet Exp $ */ +/* $Id: render.cpp,v 1.27 2004-06-10 07:18:19 harekiet Exp $ */ #include #include @@ -27,12 +27,11 @@ #include "video.h" #include "render.h" #include "setup.h" -#include "keyboard.h" +#include "mapper.h" #include "cross.h" #include "support.h" -#define RENDER_MAXWIDTH 1280 -#define RENDER_MAXHEIGHT 1024 +#include "render_scalers.h" struct PalData { struct { @@ -43,51 +42,36 @@ struct PalData { } rgb[256]; volatile Bitu first; volatile Bitu last; - union { - Bit32u bpp32[256]; - Bit16u bpp16[256]; - Bit32u yuv[256]; - } lookup; }; - static struct { struct { Bitu width; Bitu height; Bitu bpp; - Bitu scalew; - Bitu scaleh; + bool dblw,dblh; double ratio; } src; struct { Bitu width; Bitu height; Bitu pitch; - Bitu line; - Bitu bpp; + GFX_Modes mode; RENDER_Operation type; RENDER_Operation want_type; RENDER_Line_Handler line_handler; - Bit8u * draw; - Bit8u * buffer; - Bit8u * pixels; } op; struct { Bitu count; Bitu max; } frameskip; PalData pal; - struct { - Bit8u hlines[RENDER_MAXHEIGHT]; - } normal; #if (C_SSHOT) struct { - RENDER_Operation type; - Bitu bpp,width,height,line; + Bitu bpp,width,height,rowlen; const char * dir; Bit8u * buffer,* draw; - bool usesrc; + bool take,taking; } shot; #endif bool active; @@ -95,27 +79,15 @@ static struct { bool updating; } render; -Bit8u render_line_cache[4][RENDER_MAXWIDTH*4]; //Bit32u pixels RENDER_Line_Handler RENDER_DrawLine; -Bit8u * RENDER_TempLine; - -/* Forward declerations */ -static void RENDER_ResetPal(void); - -/* Include the different rendering routines */ -#include "render_templates.h" -#include "render_normal.h" -#include "render_scale2x.h" - #if (C_SSHOT) #include -static void RENDER_ShotDraw(Bit8u * src) { - if (render.shot.usesrc) { - memcpy(render.shot.draw,src,render.shot.line); - render.shot.draw+=render.shot.line; - } else render.op.line_handler(src); +static void RENDER_ShotDraw(const Bit8u * src) { + memcpy(render.shot.draw,src,render.shot.rowlen); + render.shot.draw+=render.shot.rowlen; + render.op.line_handler(src); } /* Take a screenshot of the data that should be rendered */ @@ -153,7 +125,6 @@ static void TakeScreenShot(Bit8u * bitmap) { LOG_MSG("Can't open file %s for snapshot",file_name); return; } - /* First try to alloacte the png structures */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL, NULL); if (!png_ptr) return; @@ -192,7 +163,7 @@ static void TakeScreenShot(Bit8u * bitmap) { /*Allocate an array of scanline pointers*/ row_pointers=(png_bytep*)malloc(render.shot.height*sizeof(png_bytep)); for (i=0;irender.pal.last) return; Bitu i; - switch (render.op.bpp) { - case 8: + switch (render.op.mode) { + case GFX_8: GFX_SetPalette(render.pal.first,render.pal.last-render.pal.first+1,(GFX_PalEntry *)&render.pal.rgb[render.pal.first]); break; - case 16: + case GFX_15: + case GFX_16: for (i=render.pal.first;i<=render.pal.last;i++) { Bit8u r=render.pal.rgb[i].red; Bit8u g=render.pal.rgb[i].green; Bit8u b=render.pal.rgb[i].blue; - render.pal.lookup.bpp16[i]=GFX_GetRGB(r,g,b); + Scaler_PaletteLut.b16[i]=GFX_GetRGB(r,g,b); } break; - case 24: - case 32: + case GFX_32: for (i=render.pal.first;i<=render.pal.last;i++) { Bit8u r=render.pal.rgb[i].red; Bit8u g=render.pal.rgb[i].green; Bit8u b=render.pal.rgb[i].blue; - render.pal.lookup.bpp32[i]=GFX_GetRGB(r,g,b); + Scaler_PaletteLut.b32[i]=GFX_GetRGB(r,g,b); } break; } @@ -262,7 +232,7 @@ void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue) { if (render.pal.last=miny) { + Bitu templines=(Bitu)lines; + lines-=templines; + linesadded+=templines; + Scaler_Data[i]=templines-miny; + } else Scaler_Data[i]=0; + } + return linesadded; } void RENDER_ReInit(void) { if (render.updating) RENDER_EndUpdate(); Bitu width=render.src.width; Bitu height=render.src.height; - - Bitu scalew=render.src.scalew; - Bitu scaleh=render.src.scaleh; + bool dblw=render.src.dblw; + bool dblh=render.src.dblh; double gfx_scalew=1.0; double gfx_scaleh=1.0; @@ -351,105 +318,59 @@ void RENDER_ReInit(void) { else gfx_scalew*=(1/render.src.ratio); Bitu gfx_flags; - Bitu bpp=GFX_GetBestMode(render.src.bpp,gfx_flags); - Bitu index; - switch (bpp) { - case 8: index=0;break; - case 16:index=1;break; - case 24:index=2;break; - case 32:index=3;break; - } - /* Initial scaler testing */ - switch (render.op.want_type) { - case OP_Normal2x: - case OP_None: + ScalerBlock * block; + if (dblh && dblw) { render.op.type=render.op.want_type; -normalop: - if (gfx_flags & GFX_HASSCALING) { - gfx_scalew*=scalew; - gfx_scaleh*=scaleh; - render.op.line_handler=Normal_8[index]; - for (Bitu i=0;i1 && (render.op.type==OP_None)) { - render.op.line_handler=Normal_8[index]; - scalew>>=1;gfx_scaleh/=2; - } else { - render.op.line_handler=Normal_2x_8[index]; - } - } else render.op.line_handler=Normal_8[index]; - width*=scalew; - double lines=0.0; - height=0; - for (Bitu i=0;i0) ? temp_lines-1 : 0; - height+=temp_lines; - } - } - break; - case OP_AdvMame2x: - if (scalew!=2){ - render.op.type=OP_Normal2x; - goto normalop; - } - if (gfx_flags & GFX_HASSCALING) { - height=scaleh*height; - } else { - height=(Bitu)(gfx_scaleh*scaleh*height); - } - width<<=1; - { - Bits i; - double src_add=(double)height/(double)render.src.height; - double src_index=0; - double src_lines=0; - Bitu src_done=0; - Bitu height=0; - am2x.cmd_index=am2x.cmd_data; - am2x.buf_pos=0;am2x.buf_used=0; - for (i=0;i<=(Bits)render.src.height;i++) { - src_lines+=src_add; - Bitu lines=(Bitu)src_lines; - src_lines-=lines; - switch (lines) { - case 0: - break; - case 1: - AdvMame2x_AddLine(i,i,i); - break; - case 2: - AdvMame2x_AddLine(i-1,i,i+1); - AdvMame2x_AddLine(i+1,i,i-1); - break; - default: - AdvMame2x_AddLine(i-1,i,i+1); - for (lines-=2;lines>0;lines--) AdvMame2x_AddLine(i,i,i); - AdvMame2x_AddLine(i+1,i,i-1); - break; - } - AdvMame2x_CheckLines(i); - } - render.op.line_handler=AdvMame2x_8_Table[index]; - } - break; + } else if (dblw) { + render.op.type=OP_Normal2x; + } else if (dblh) { + render.op.type=OP_Normal; + gfx_scaleh*=2; + } else { +forcenormal: + render.op.type=OP_Normal; } - render.op.bpp=bpp; + switch (render.op.type) { + case OP_Normal:block=&Normal_8;break; + case OP_Normal2x:block=(dblh) ? &Normal2x_8 : &NormalDbl_8;break; + case OP_AdvMame2x:block=&AdvMame2x_8;break; + case OP_AdvMame3x:block=&AdvMame3x_8;break; + case OP_Interp2x:block=&Interp2x_8;break; + case OP_AdvInterp2x:block=&AdvInterp2x_8;break; + case OP_TV2x:block=&TV2x_8;break; + } + gfx_flags=GFX_GetBestMode(block->flags); + if (!gfx_flags) { + if (render.op.type==OP_Normal) E_Exit("Failed to create a rendering output"); + else goto forcenormal; + } + /* Special test for normal2x to switch to normal with hardware scaling */ + if (gfx_flags & HAVE_SCALING && render.op.type==OP_Normal2x) { + if (dblw) gfx_scalew*=2; + if (dblh) gfx_scaleh*=2; + block=&Normal_8; + render.op.type=OP_Normal; + } + width*=block->xscale; + if (gfx_flags & HAVE_SCALING) { + height=MakeAspectTable(render.src.height,block->yscale,block->miny); + } else { + gfx_scaleh*=block->yscale; + height=MakeAspectTable(render.src.height,gfx_scaleh,block->miny); + } +/* Setup the scaler variables */ + render.op.mode=GFX_SetSize(width,height,gfx_flags,gfx_scalew,gfx_scaleh,&RENDER_ReInit);; + if (render.op.mode==GFX_NONE) E_Exit("Failed to create a rendering output"); + render.op.line_handler=block->handlers[render.op.mode]; render.op.width=width; render.op.height=height; - GFX_SetSize(width,height,bpp,gfx_scalew,gfx_scaleh,&RENDER_ReInit); + Scaler_SrcWidth=render.src.width; + Scaler_SrcHeight=render.src.height; RENDER_ResetPal(); render.active=true; } - -void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,Bitu scalew,Bitu scaleh) { +void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,bool dblw,bool dblh) { if (!width || !height) { render.active=false; return; @@ -457,9 +378,9 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,Bitu scalew,Bit render.src.width=width; render.src.height=height; render.src.bpp=bpp; + render.src.dblw=dblw; + render.src.dblh=dblh; render.src.ratio=render.aspect ? ratio : 1.0; - render.src.scalew=scalew; - render.src.scaleh=scaleh; RENDER_ReInit(); } @@ -487,8 +408,7 @@ void RENDER_Init(Section * sec) { render.updating=true; #if (C_SSHOT) render.shot.dir=section->Get_string("snapdir"); - render.shot.usesrc=true; - KEYBOARD_AddEvent(KBD_f5,KBD_MOD_CTRL,EnableScreenShot); + MAPPER_AddHandler(EnableScreenShot,MK_f5,MMOD1,"scrshot","Screenshot"); #endif const char * scaler;std::string cline; if (control->cmdline->FindString("-scaler",cline,false)) { @@ -496,15 +416,19 @@ void RENDER_Init(Section * sec) { } else { scaler=section->Get_string("scaler"); } - if (!strcasecmp(scaler,"none")) render.op.want_type=OP_None; + if (!strcasecmp(scaler,"none")) render.op.want_type=OP_Normal; else if (!strcasecmp(scaler,"normal2x")) render.op.want_type=OP_Normal2x; else if (!strcasecmp(scaler,"advmame2x")) render.op.want_type=OP_AdvMame2x; + else if (!strcasecmp(scaler,"advmame3x")) render.op.want_type=OP_AdvMame3x; + else if (!strcasecmp(scaler,"advinterp2x")) render.op.want_type=OP_AdvInterp2x; + else if (!strcasecmp(scaler,"interp2x")) render.op.want_type=OP_Interp2x; + else if (!strcasecmp(scaler,"tv2x")) render.op.want_type=OP_TV2x; else { - render.op.want_type=OP_None; - LOG_MSG("Illegal scaler type %s,falling back to none.",scaler); + render.op.want_type=OP_Normal; + LOG_MSG("Illegal scaler type %s,falling back to normal.",scaler); } - KEYBOARD_AddEvent(KBD_f7,KBD_MOD_CTRL,DecreaseFrameSkip); - KEYBOARD_AddEvent(KBD_f8,KBD_MOD_CTRL,IncreaseFrameSkip); + MAPPER_AddHandler(DecreaseFrameSkip,MK_f7,MMOD1,"decfskip","Dec Fskip"); + MAPPER_AddHandler(IncreaseFrameSkip,MK_f8,MMOD1,"incfskip","Inc Fskip"); GFX_SetTitle(-1,render.frameskip.max); } diff --git a/src/gui/render_normal.h b/src/gui/render_normal.h deleted file mode 100644 index 95ae4ea9..00000000 --- a/src/gui/render_normal.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2002-2004 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -static Bit8u normal_cache[RENDER_MAXWIDTH*2*4]; - -template -static void Normal(Bit8u * src) { - Bitu line_size=LineSize(render.src.width) * (xdouble ? 2 : 1); - Bit8u * line; - if (sbpp == dbpp && !xdouble) { - line=src; - BituMove(render.op.pixels,line,line_size); - } else { - Bit8u * line_dst=&normal_cache[0]; - Bit8u * real_dst=render.op.pixels; - line=line_dst; - Bit8u * temp_src=src; - for (Bitu tempx=render.src.width;tempx;tempx--) { - Bitu val=ConvBPP(LoadSrc(temp_src)); - AddDst(line_dst,val); - AddDst(real_dst,val); - if (xdouble) { - AddDst(line_dst,val); - AddDst(real_dst,val); - } - } - } - render.op.pixels+=render.op.pitch; - for (Bitu lines=render.normal.hlines[render.op.line++];lines;lines--) { - BituMove(render.op.pixels,line,line_size); - render.op.pixels+=render.op.pitch; - } -} - - -static RENDER_Line_Handler Normal_8[4]={ - Normal<8,8 ,false>,Normal<8,16,false>, - Normal<8,24,false>,Normal<8,32,false>, -}; - -static RENDER_Line_Handler Normal_2x_8[4]={ - Normal<8,8 ,true>,Normal<8,16,true>, - Normal<8,24,true>,Normal<8,32,true>, -}; diff --git a/src/gui/render_scale2x.h b/src/gui/render_scale2x.h deleted file mode 100644 index 00705f41..00000000 --- a/src/gui/render_scale2x.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * This file is part of the Scale2x project. - * - * Copyright (C) 2001-2002 Andrea Mazzoleni - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * In addition, as a special exception, Andrea Mazzoleni - * gives permission to link the code of this program with - * the MAME library (or with modified versions of MAME that use the - * same license as MAME), and distribute linked combinations including - * the two. You must obey the GNU General Public License in all - * respects for all of the code used other than MAME. If you modify - * this file, you may extend this exception to your version of the - * file, but you are not obligated to do so. If you do not wish to - * do so, delete this exception statement from your version. - */ - -/* - * This algorithm was based on the scale2x/advmame2x effect. - * http://scale2x.sourceforge.net/scale2x.html - */ - -#ifndef __SCALE2X_H -#define __SCALE2X_H - -#define AM2XBUF 16 - -static struct { - Bits buf[AM2XBUF][4]; - Bitu buf_used;Bitu buf_pos; - Bit8u cmd_data[4096]; //1024 lines should be enough? - Bit8u * cmd_index; - Bit8u * cache[4]; - Bitu cache_index; -} am2x; - - -static void AdvMame2x_AddLine(Bits s0,Bits s1,Bits s2) { - if (s0<0) s0=0; - if (s1<0) s1=0; - if (s2<0) s2=0; - if (s0>=(Bits)render.src.height) s0=render.src.height-1; - if (s1>=(Bits)render.src.height) s1=render.src.height-1; - if (s2>=(Bits)render.src.height) s2=render.src.height-1; - Bitu pos=(am2x.buf_used+am2x.buf_pos)&(AM2XBUF-1); - am2x.buf[pos][0]=s0; - am2x.buf[pos][1]=s1; - am2x.buf[pos][2]=s2; - s0=s0 > s1 ? s0 : s1; - s0=s0 > s2 ? s0 : s2; - am2x.buf[pos][3]=s0; - am2x.buf_used++; -} - -static void AdvMame2x_CheckLines(Bits last) { - Bitu lines=0;Bit8u * line_count=am2x.cmd_index++; - while (am2x.buf_used) { - if (am2x.buf[am2x.buf_pos][3]>last) break; - *am2x.cmd_index++=am2x.buf[am2x.buf_pos][0]&3; - *am2x.cmd_index++=am2x.buf[am2x.buf_pos][1]&3; - *am2x.cmd_index++=am2x.buf[am2x.buf_pos][2]&3; - am2x.buf_used--;lines++; - am2x.buf_pos=(am2x.buf_pos+1)&(AM2XBUF-1); - } - *line_count=lines; -} - -template -static void AdvMame2x_line(Bit8u * dst, const Bit8u * src0, const Bit8u * src1, const Bit8u * src2, Bitu count) { - AddDst(dst,ConvBPP(src1[0])); - AddDst(dst,ConvBPP((src1[1] == src0[0] && src2[0] != src0[0]) ? src0[0] : src1[0])); - src0++;src1++;src2++;count-=2; - /* central pixels */ - while (count) { - AddDst(dst,ConvBPP((src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0]) ? src0[0] : src1[0])); - AddDst(dst,ConvBPP((src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0]) ? src0[0] : src1[0])); - src0++;src1++;src2++;count--; - } - /* last pixel */ - AddDst(dst,ConvBPP((src1[-1] == src0[0] && src2[0] != src0[0]) ? src0[0] : src1[0])); - AddDst(dst,ConvBPP(src1[0])); -} - -template -static void AdvMame2x(Bit8u * src) { - RENDER_TempLine=render_line_cache[render.op.line&3]; - am2x.cache[render.op.line&3]=src; - Bitu lines=*am2x.cmd_index++; - while (lines--) { - Bit8u * src0=am2x.cache[*am2x.cmd_index++]; - Bit8u * src1=am2x.cache[*am2x.cmd_index++]; - Bit8u * src2=am2x.cache[*am2x.cmd_index++]; - AdvMame2x_line(render.op.pixels,src0,src1,src2,render.src.width); - render.op.pixels+=render.op.pitch; - } - render.op.line++; -} - - -static RENDER_Line_Handler AdvMame2x_8_Table[4]={ - AdvMame2x<8,8>,AdvMame2x<8,16>,AdvMame2x<8,24>,AdvMame2x<8,32> -}; - - -#endif diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp new file mode 100644 index 00000000..a0cedbc3 --- /dev/null +++ b/src/gui/render_scalers.cpp @@ -0,0 +1,121 @@ +#include "dosbox.h" +#include "render_scalers.h" + +Bitu Scaler_Line; +Bitu Scaler_SrcWidth; +Bitu Scaler_SrcHeight; +Bitu Scaler_DstPitch; +Bit8u * Scaler_DstWrite; +Bit8u * Scaler_Index; +Bit8u Scaler_Data[SCALER_MAXHEIGHT*5]; //5cmds/line +PaletteLut Scaler_PaletteLut; + +static union { + Bit32u b32 [4][SCALER_MAXWIDTH]; + Bit16u b16 [4][SCALER_MAXWIDTH]; + Bit8u b8 [4][SCALER_MAXWIDTH]; +} line_cache; +static union { + Bit32u b32 [4][SCALER_MAXWIDTH*3]; + Bit16u b16 [4][SCALER_MAXWIDTH*3]; + Bit8u b8 [4][SCALER_MAXWIDTH*3]; +} write_cache; + +static Bit8u * ln[3]; + +#define _conc2(A,B) A ## B +#define _conc3(A,B,C) A ## B ## C +#define _conc4(A,B,C,D) A ## B ## C ## D +#define _conc5(A,B,C,D,E) A ## B ## C ## D ## E + +#define conc2(A,B) _conc2(A,B) +#define conc3(A,B,C) _conc3(A,B,C) +#define conc4(A,B,C,D) _conc4(A,B,C,D) +#define conc2d(A,B) _conc3(A,_,B) +#define conc3d(A,B,C) _conc5(A,_,B,_,C) + +#define BituMove(_DST,_SRC,_SIZE) \ +{ \ + Bitu bsize=(_SIZE)/sizeof(Bitu); \ + Bitu * bdst=(Bitu *)(_DST); \ + Bitu * bsrc=(Bitu *)(_SRC); \ + while (bsize--) *bdst++=*bsrc++; \ +} + +#define interp_w2(P0,P1,W0,W1) \ + ((((P0&redblueMask)*W0+(P1&redblueMask)*W1)/(W0+W1)) & redblueMask) | \ + ((((P0& greenMask)*W0+(P1& greenMask)*W1)/(W0+W1)) & greenMask) +#define interp_w3(P0,P1,P2,W0,W1,W2) \ + ((((P0&redblueMask)*W0+(P1&redblueMask)*W1+(P2&redblueMask)*W2)/(W0+W1+W2)) & redblueMask) | \ + ((((P0& greenMask)*W0+(P1& greenMask)*W1+(P2& greenMask)*W2)/(W0+W1+W2)) & greenMask) +#define interp_w4(P0,P1,P2,P3,W0,W1,W2,W3) \ + ((((P0&redblueMask)*W0+(P1&redblueMask)*W1+(P2&redblueMask)*W2+(P3&redblueMask)*W3)/(W0+W1+W2+W3)) & redblueMask) | \ + ((((P0& greenMask)*W0+(P1& greenMask)*W1+(P2& greenMask)*W2+(P3& greenMask)*W3)/(W0+W1+W2+W3)) & greenMask) + +/* Include the different rendering routines */ +#define SBPP 8 +#define DBPP 8 +#include "render_templates.h" +#undef DBPP +#define DBPP 15 +#include "render_templates.h" +#undef DBPP +#define DBPP 16 +#include "render_templates.h" +#undef DBPP +#define DBPP 32 +#include "render_templates.h" +#undef SBPP +#undef DBPP + + + +ScalerBlock Normal_8={ + CAN_8|CAN_16|CAN_32|LOVE_8, + 1,1,1, + Normal_8_8,Normal_8_16,Normal_8_16,Normal_8_32 +}; + +ScalerBlock NormalDbl_8= { + CAN_8|CAN_16|CAN_32|LOVE_8, + 2,1,1, + Normal2x_8_8,Normal2x_8_16,Normal2x_8_16,Normal2x_8_32 +}; + +ScalerBlock Normal2x_8={ + CAN_8|CAN_16|CAN_32|LOVE_8, + 2,2,1, + Normal2x_8_8,Normal2x_8_16,Normal2x_8_16,Normal2x_8_32 +}; + +ScalerBlock AdvMame2x_8={ + CAN_8|CAN_16|CAN_32|LOVE_8, + 2,2,1, + AdvMame2x_8_8,AdvMame2x_8_16,AdvMame2x_8_16,AdvMame2x_8_32 +}; + +ScalerBlock AdvMame3x_8={ + CAN_8|CAN_16|CAN_32|LOVE_8, + 3,3,2, + AdvMame3x_8_8,AdvMame3x_8_16,AdvMame3x_8_16,AdvMame3x_8_32 +}; + +ScalerBlock Interp2x_8={ + CAN_16|CAN_32|LOVE_32|NEED_RGB, + 2,2,1, + 0,Interp2x_8_16,Interp2x_8_16,Interp2x_8_32 +}; + +ScalerBlock AdvInterp2x_8={ + CAN_16|CAN_32|LOVE_32|NEED_RGB, + 2,2,1, + 0,AdvInterp2x_8_16,AdvInterp2x_8_16,AdvInterp2x_8_32 +}; + +ScalerBlock TV2x_8={ + CAN_16|CAN_32|LOVE_32|NEED_RGB, + 2,2,1, + 0,TV2x_8_16,TV2x_8_16,TV2x_8_32 +}; + + diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h new file mode 100644 index 00000000..bb6de83d --- /dev/null +++ b/src/gui/render_scalers.h @@ -0,0 +1,51 @@ +#ifndef _RENDER_SCALERS_H +#define _RENDER_SCALERS_H + +#include "render.h" +#include "video.h" + +#define SCALER_MAXWIDTH 1280 +#define SCALER_MAXHEIGHT 1024 + +extern Bitu Scaler_Line; +extern Bitu Scaler_SrcWidth; +extern Bitu Scaler_SrcHeight; +extern Bitu Scaler_DstPitch; +extern Bit8u * Scaler_DstWrite; +extern Bit8u Scaler_Data[]; +extern Bit8u * Scaler_Index; + +union PaletteLut { + Bit16u b16[256]; + Bit32u b32[256]; +}; + +extern PaletteLut Scaler_PaletteLut; + +enum RENDER_Operation { + OP_Normal, + OP_Normal2x, + OP_AdvMame2x, + OP_AdvMame3x, + OP_AdvInterp2x, + OP_Interp2x, + OP_TV2x, +}; + +struct ScalerBlock { + Bitu flags; + Bitu xscale,yscale,miny; + RENDER_Line_Handler handlers[4]; +}; + +extern ScalerBlock Normal_8; +extern ScalerBlock NormalDbl_8; +extern ScalerBlock Normal2x_8; +extern ScalerBlock AdvMame2x_8; +extern ScalerBlock AdvMame3x_8; +extern ScalerBlock AdvInterp2x_8; +extern ScalerBlock Interp2x_8; +extern ScalerBlock TV2x_8; + + +#endif diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index d5228cdb..67d181ed 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -1,59 +1,294 @@ -#ifdef __GNUC__ -template static INLINE void AddDst(Bit8u * & dst,Bitu val) __attribute__ ((always_inline)); -template static INLINE Bitu LineSize(Bitu pixels) __attribute__ ((always_inline)); -template static INLINE Bitu LoadSrc(Bit8u * & src) __attribute__ ((always_inline)); -template static INLINE Bitu ConvBPP(Bitu val) __attribute__ ((always_inline)); +#if DBPP == 8 +#define PSIZE 1 +#define PTYPE Bit8u +#define WC write_cache.b8 +#define LC line_cache.b8 +#define redblueMask 0 +#define greenMask 0 +#elif DBPP == 15 || DBPP == 16 +#define PSIZE 2 +#define PTYPE Bit16u +#define WC write_cache.b16 +#define LC line_cache.b16 +#if DBPP == 15 +#define redblueMask 0x7C1F +#define greenMask 0x03E0 +#elif DBPP == 16 +#define redblueMask 0xF81F +#define greenMask 0x07E0 +#endif +#elif DBPP == 32 +#define PSIZE 4 +#define PTYPE Bit32u +#define WC write_cache.b32 +#define LC line_cache.b32 +#define redblueMask 0xff00ff +#define greenMask 0xff00 #endif -template static INLINE void AddDst(Bit8u * & dst,Bitu val) { - switch (dbpp) { - case 8: *(Bit8u*)dst=val;dst+=1;break; - case 16:*(Bit16u*)dst=val;dst+=2;break; - case 24:*(Bit32u*)dst=val;dst+=3;break; - case 32:*(Bit32u*)dst=val;dst+=4;break; +#if SBPP == 8 +#if DBPP == 8 +#define PMAKE(_VAL) _VAL +#elif DBPP == 15 +#define PMAKE(_VAL) Scaler_PaletteLut.b16[_VAL] +#elif DBPP == 16 +#define PMAKE(_VAL) Scaler_PaletteLut.b16[_VAL] +#elif DBPP == 32 +#define PMAKE(_VAL) Scaler_PaletteLut.b32[_VAL] +#endif +#endif + +#define C0 LC[0][x-1] +#define C1 LC[0][x+0] +#define C2 LC[0][x+1] +#define C3 LC[1][x-1] +#define C4 LC[1][x+0] +#define C5 LC[1][x+1] +#define C6 LC[2][x-1] +#define C7 LC[2][x+0] +#define C8 LC[2][x+1] + +static void conc3d(Normal,SBPP,DBPP) (const Bit8u * src) { + const Bit8u * line; +#if SBPP == DBPP + line=src; + BituMove(Scaler_DstWrite,line,Scaler_SrcWidth*PSIZE); +#else + PTYPE * dst=(PTYPE *)Scaler_DstWrite; + line=line_cache.b8[0]; + for (Bitu x=0;x -static INLINE Bitu LineSize(Bitu pixels) { - switch (bpp) { - case 8:return pixels; - case 16:return pixels*2; - case 24:return pixels*3; - case 32:return pixels*4; +static void conc3d(Normal2x,SBPP,DBPP) (const Bit8u * src) { + PTYPE * dst=(PTYPE *)Scaler_DstWrite; + for (Bitu x=0;x -static INLINE Bitu LoadSrc(Bit8u * & src) { - Bitu val; - switch (sbpp) { - case 8:val=*(Bit8u *) src;src+=1;break; - case 16:val=*(Bit16u *) src;src+=2;break; - case 24:val=(*(Bit32u *)src)&0xffffff;src+=3;break; - case 32:val=*(Bit32u *)src;src+=4;break; +#if (DBPP > 8) +static void conc3d(TV2x,SBPP,DBPP) (const Bit8u * src) { + PTYPE * dst=(PTYPE *)Scaler_DstWrite; + for (Bitu x=0;x> 3) & redblueMask; + halfpixel|=(((pixel & greenMask) * 7) >> 3) & greenMask; + dst[x*2+0]=dst[x*2+1]=halfpixel; + LC[0][x*2+0]=LC[0][x*2+1]=pixel; + } + Scaler_DstWrite+=Scaler_DstPitch; + for (Bitu lines=*Scaler_Index++;lines;lines--) { + BituMove(Scaler_DstWrite,LC[0],Scaler_SrcWidth*2*PSIZE); + Scaler_DstWrite+=Scaler_DstPitch; } - return val; } - -template -static INLINE Bitu ConvBPP(Bitu val) { - if (sbpp==8) switch (dbpp) { - case 8:return val; - case 16:return render.pal.lookup.bpp16[val]; - case 24:return render.pal.lookup.bpp32[val]; - case 32:return render.pal.lookup.bpp32[val]; +static void conc3d(Interp2x,SBPP,DBPP) (const Bit8u * src) { + if (!Scaler_Line) { + Scaler_Line++; + for (Bitu tempx=Scaler_SrcWidth;tempx>0;tempx--) { + LC[1][tempx] = LC[2][tempx] = PMAKE(src[tempx]); + } + return; } - return 0; +lastagain: + Bitu x=0; + PTYPE * dst=(PTYPE *)Scaler_DstWrite; + C1=C4;C4=C7;C7=PMAKE(src[x]); + C2=C5;C5=C8;C8=PMAKE(src[x+1]); + dst[0] = interp_w2(C4,C1,3,1); + dst[1] = interp_w4(C4,C1,C2,C5,5,1,1,1); + WC[1][0] = interp_w2(C4,C7,3,1); + WC[1][1] = interp_w4(C4,C5,C8,C7,5,1,1,1); + for (x=1;x0;tempx--) { + LC[1][tempx]=LC[2][tempx]=PMAKE(src[tempx]); + } + return; + } +lastagain: + Bitu x=0; + PTYPE * dst=(PTYPE *)Scaler_DstWrite; + C1=C4;C4=C7;C7=PMAKE(src[x]); + C2=C5;C5=C8;C8=PMAKE(src[x+1]); + dst[0]=C4; + WC[1][0]=C4; + dst[1] = C5 == C1 && C7 != C1 ? C2 : C4; + WC[1][1]= C5 == C7 && C1 != C7 ? C7 : C4; + for (x=1;x0;lines--) { + BituMove(Scaler_DstWrite,&WC[1],2*Scaler_SrcWidth*PSIZE); + Scaler_DstWrite+=Scaler_DstPitch; + } + if (++Scaler_Line==Scaler_SrcHeight) goto lastagain; +} + +#endif //DBPP > 8 + +static void conc3d(AdvMame2x,SBPP,DBPP) (const Bit8u * src) { + if (!Scaler_Line) { + Scaler_Line++; + for (Bitu tempx=Scaler_SrcWidth;tempx>0;tempx--) { + LC[1][tempx]=LC[2][tempx]=PMAKE(src[tempx]); + } + return; + } +lastagain: + Bitu x=0; + PTYPE * dst=(PTYPE *)Scaler_DstWrite; + C1=C4;C4=C7;C7=PMAKE(src[x]); + C2=C5;C5=C8;C8=PMAKE(src[x+1]); + dst[0]=C4; + WC[1][0]=C4; + dst[1] = C5 == C1 && C7 != C1 ? C2 : C4; + WC[1][1]= C5 == C7 && C1 != C7 ? C7 : C4; + for (x=1;x0;lines--) { + BituMove(Scaler_DstWrite,&WC[1],2*Scaler_SrcWidth*PSIZE); + Scaler_DstWrite+=Scaler_DstPitch; + } + if (++Scaler_Line==Scaler_SrcHeight) goto lastagain; +} + +static void conc3d(AdvMame3x,SBPP,DBPP) (const Bit8u * src) { + if (!Scaler_Line) { + Scaler_Line++; + for (Bitu tempx=Scaler_SrcWidth;tempx>0;tempx--) { + LC[1][tempx]=LC[2][tempx]=PMAKE(src[tempx]); + } + return; + } +lastagain: + PTYPE * dst=(PTYPE *)Scaler_DstWrite; + LC[0][0]=LC[1][0];LC[1][0]=LC[2][0];LC[2][0]=PMAKE(src[0]); + LC[0][1]=LC[1][1];LC[1][1]=LC[2][1];LC[2][1]=PMAKE(src[1]); + /* first pixel */ + dst[0] = LC[1][0]; + dst[1] = LC[1][0]; + dst[2] = (LC[1][1] == LC[0][0] && LC[2][0] != LC[0][0]) ? LC[0][0] : LC[1][0]; + WC[1][0] = LC[1][0]; + WC[1][1] = LC[1][0]; + WC[1][2] = (LC[0][0] != LC[2][0]) ? (((LC[1][1] == LC[0][0] && LC[1][0] != LC[2][1]) || (LC[1][1] == LC[2][0] && LC[1][0] != LC[0][1])) ? LC[1][1] : LC[1][0]) : LC[1][0]; + WC[2][0] = LC[1][0]; + WC[2][1] = LC[1][0]; + WC[2][2] = (LC[1][1] == LC[2][0] && LC[0][0] != LC[2][0]) ? LC[2][0] : LC[1][0]; + Bitu x; + for (x=1;x0;lines--) { + BituMove(Scaler_DstWrite,&WC[2],3*Scaler_SrcWidth*PSIZE); + Scaler_DstWrite+=Scaler_DstPitch; + } + if (++Scaler_Line==Scaler_SrcHeight) goto lastagain; +} + +#undef PSIZE +#undef PTYPE +#undef PMAKE +#undef WC +#undef LC +#undef greenMask +#undef redblueMask + + diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp new file mode 100644 index 00000000..92bc9eda --- /dev/null +++ b/src/gui/sdl_mapper.cpp @@ -0,0 +1,1187 @@ +/* + * Copyright (C) 2002-2004 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + + +#include "SDL.h" +#include "SDL_thread.h" + +#include "dosbox.h" +#include "video.h" +#include "keyboard.h" +#include "joystick.h" +#include "support.h" +#include "mapper.h" +#include "setup.h" + +enum { + CLR_BLACK=0, + CLR_WHITE=1, + CLR_RED=2, +}; + +enum BB_Types { + BB_Next,BB_Prev,BB_Add,BB_Del, + BB_Save,BB_Reset +}; + +enum BC_Types { + BC_Mod1,BC_Mod2,BC_Mod3, + BC_Hold, +}; + +#define BMOD_Mod1 0x0001 +#define BMOD_Mod2 0x0002 +#define BMOD_Mod3 0x0004 + +#define BFLG_Hold 0x0001 +#define BFLG_Repeat 0x0004 + + +#define MAXSTICKS 8 +#define MAXACTIVE 16 + +class CEvent; +class CHandlerEvent; +class CButton; +class CBind; +class CBindGroup; + +static void SetActiveEvent(CEvent * event); +static void SetActiveBind(CBind * _bind); +extern Bit8u int10_font_14[256 * 14]; + +static std::vector events; +static std::vector buttons; +static std::vector bindgroups; +static std::vector handlergroup; +typedef std::list CBindList; +typedef std::list::iterator CEventList_it; +typedef std::list::iterator CBindList_it; +typedef std::vector::iterator CButton_it; +typedef std::vector::iterator CEventVector_it; +typedef std::vector::iterator CHandlerEventVector_it; +typedef std::vector::iterator CBindGroup_it; + +static CBindList holdlist; + + +class CEvent { +public: + CEvent(char * _entry) { + strncpy(entry,_entry,16); + events.push_back(this); + bindlist.clear(); + activity=0; + } + void AddBind(CBind * bind); + virtual ~CEvent() {} + virtual void Active(bool yesno)=0; + INLINE void Activate(void) { + if (!activity) Active(true); + activity++; + } + INLINE void DeActivate(void) { + activity--; + if (!activity) Active(false); + } + void DeActivateAll(void); + void SetValue(Bits value){ + }; + char * GetName(void) { return entry;} + CBindList bindlist; +protected: + Bitu activity; + char entry[16]; +}; + +class CBind { +public: + virtual ~CBind () { + list->remove(this); +// event->bindlist.remove(this); + } + CBind(CBindList * _list) { + list=_list; + _list->push_back(this); + mods=flags=0; + event=0; + active=holding=false; + } + void AddFlags(char * buf) { + if (mods & BMOD_Mod1) strcat(buf," mod1"); + if (mods & BMOD_Mod2) strcat(buf," mod2"); + if (mods & BMOD_Mod3) strcat(buf," mod3"); + if (flags & BFLG_Hold) strcat(buf," hold"); + } + void SetFlags(char * buf) { + char * word; + while (*(word=StripWord(buf))) { + if (!strcasecmp(word,"mod1")) mods|=BMOD_Mod1; + if (!strcasecmp(word,"mod2")) mods|=BMOD_Mod2; + if (!strcasecmp(word,"mod3")) mods|=BMOD_Mod2; + if (!strcasecmp(word,"hold")) flags|=BFLG_Hold; + } + } + void Activate(Bits value) { + event->SetValue(value); + if (active) return; + event->Activate(); + active=true; + } + void DeActivate(void) { + if (!active) return; + active=false; + if (flags & BFLG_Hold) { + if (!holding) { + holdlist.push_back(this); + holding=true; + return; + } else { + holdlist.remove(this); + holding=false; + } + } + event->DeActivate(); + } + virtual void ConfigName(char * buf)=0; + virtual void BindName(char * buf)=0; + Bitu mods,flags; + Bit16s value; + CEvent * event; + CBindList * list; + bool active,holding; +}; + + +void CEvent::AddBind(CBind * bind) { + bindlist.push_front(bind); + bind->event=this; +} +void CEvent::DeActivateAll(void) { + for (CBindList_it bit=bindlist.begin();bit!=bindlist.end();bit++) { + (*bit)->DeActivate(); + } +} + + + +class CBindGroup { +public: + CBindGroup() { + bindgroups.push_back(this); + } + void ActivateBindList(CBindList * list,Bits value); + void DeactivateBindList(CBindList * list); + virtual CBind * CreateConfigBind(char *&buf)=0; + virtual CBind * CreateEventBind(SDL_Event * event)=0; + + virtual bool CheckEvent(SDL_Event * event)=0; + virtual char * ConfigStart(void)=0; + virtual char * BindStart(void)=0; +protected: + +}; + +class CKeyBind; +class CKeyBindGroup; + +class CKeyBind : public CBind { +public: + CKeyBind(CBindList * _list,SDLKey _key) : CBind(_list) { + key = _key; + } + void BindName(char * buf) { + sprintf(buf,"Key %s%",SDL_GetKeyName(key)); + } + void ConfigName(char * buf) { + sprintf(buf,"key %d",key); + } +public: + SDLKey key; +}; + +class CKeyBindGroup : public CBindGroup { +public: + CKeyBindGroup(Bitu _keys) : CBindGroup (){ + lists=new CBindList[_keys]; + for (Bitu i=0;i<_keys;i++) lists[i].clear(); + keys=_keys; + configname="key"; + } + ~CKeyBindGroup() { delete[] lists; } + CBind * CreateConfigBind(char *& buf) { + if (strncasecmp(buf,configname,strlen(configname))) return 0; + StripWord(buf);char * num=StripWord(buf); + CBind * bind=CreateKeyBind((SDLKey)ConvDecWord(num)); + return bind; + } + CBind * CreateEventBind(SDL_Event * event) { + if (event->type!=SDL_KEYDOWN) return 0; + return CreateKeyBind(event->key.keysym.sym); + }; + bool CheckEvent(SDL_Event * event) { + if (event->type!=SDL_KEYDOWN && event->type!=SDL_KEYUP) return false; + Bitu key=(Bitu)event->key.keysym.sym; + assert(keytype==SDL_KEYDOWN) ActivateBindList(&lists[key],0x7fff); + else DeactivateBindList(&lists[key]); + return 0; + } +private: + CBind * CreateKeyBind(SDLKey _key) { + assert((Bitu)_keyConfigStart(),axis,positive ? 1 : 0); + } + void BindName(char * buf) { + sprintf(buf,"%s Axis %d%s",group->BindStart(),axis,positive ? "+" : "-"); + } +protected: + CBindGroup * group; + Bitu axis; + bool positive; +}; + +class CJButtonBind : public CBind { +public: + CJButtonBind(CBindList * _list,CBindGroup * _group,Bitu _button) : CBind(_list) { + group = _group; + button=_button; + } + void ConfigName(char * buf) { + sprintf(buf,"%s button %d",group->ConfigStart(),button); + } + void BindName(char * buf) { + sprintf(buf,"%s Button %d",group->BindStart(),button); + } +protected: + CBindGroup * group; + Bitu button; +}; + +class CJHatBind : public CBind { +public: + CJHatBind(CBindList * _list,CBindGroup * _group,Bitu _hat) : CBind(_list) { + group = _group; + hat=_hat; + } + void ConfigName(char * buf) { + sprintf(buf,"%s hat %d",group->ConfigStart(),hat); + } + void BindName(char * buf) { + sprintf(buf,"%s hat %d",group->BindStart(),hat); + } +protected: + CBindGroup * group; + Bitu hat; + Bitu mask; +}; + +class CStickBindGroup : public CBindGroup { +public: + CStickBindGroup(Bitu _stick) : CBindGroup (){ + stick=_stick; + sprintf(configname,"stick_%d",stick); + assert(sdl_joystick=SDL_JoystickOpen(stick)); + axes=SDL_JoystickNumAxes(sdl_joystick); + buttons=SDL_JoystickNumButtons(sdl_joystick); + hats=SDL_JoystickNumHats(sdl_joystick); + pos_axis_lists=new CBindList[axes]; + neg_axis_lists=new CBindList[axes]; + button_lists=new CBindList[buttons]; + hat_lists=new CBindList[hats]; + } + ~CStickBindGroup() { + SDL_JoystickClose(sdl_joystick); + delete[] pos_axis_lists; + delete[] neg_axis_lists; + delete[] button_lists; + delete[] hat_lists; + } + CBind * CreateConfigBind(char *& buf) { + if (strncasecmp(configname,buf,strlen(configname))) return 0; + StripWord(buf);char * type=StripWord(buf); + CBind * bind=0; + if (!strcasecmp(type,"axis")) { + Bitu ax=ConvDecWord(StripWord(buf)); + bool pos=ConvDecWord(StripWord(buf)) > 0; + bind=CreateAxisBind(ax,pos); + } else if (!strcasecmp(type,"button")) { + Bitu but=ConvDecWord(StripWord(buf)); + bind=CreateButtonBind(but); + } + return bind; + } + CBind * CreateEventBind(SDL_Event * event) { + if (event->type==SDL_JOYAXISMOTION) { + if (event->jaxis .which!=stick) return 0; + if (abs(event->jaxis.value)<25000) return 0; + return CreateAxisBind(event->jaxis.axis,event->jaxis.value>0); + } else if (event->type==SDL_JOYBUTTONDOWN) { + if (event->jaxis .which!=stick) return 0; + return CreateButtonBind(event->jbutton.button); + } else return 0; + } + bool CheckEvent(SDL_Event * event) { + + return false; + } +private: + CBind * CreateAxisBind(Bitu axis,bool positive) { + assert(axisbegin();it!=list->end();it++) { + if (((*it)->mods & mapper.mods) == (*it)->mods) { + if (validmod<(*it)->mods) validmod=(*it)->mods; + } + } + for (it=list->begin();it!=list->end();it++) { + if (validmod==(*it)->mods) (*it)->Activate(value); + } +} + +void CBindGroup::DeactivateBindList(CBindList * list) { + Bitu validmod=0; + CBindList_it it; + for (it=list->begin();it!=list->end();it++) { + (*it)->DeActivate(); + } +} + +static void DrawText(Bitu x,Bitu y,const char * text,Bit8u color) { + Bit8u * draw=((Bit8u *)mapper.surface->pixels)+(y*mapper.surface->pitch)+x; + while (*text) { + Bit8u * font=&int10_font_14[(*text)*14]; + Bitu i,j;Bit8u * draw_line=draw; + for (i=0;i<14;i++) { + Bit8u map=*font++; + for (j=0;j<8;j++) { + if (map & 0x80) *(draw_line+j)=color; + else *(draw_line+j)=CLR_BLACK; + map<<=1; + } + draw_line+=mapper.surface->pitch; + } + text++;draw+=8; + } +} + +class CButton { +public: + virtual ~CButton(){}; + CButton(Bitu _x,Bitu _y,Bitu _dx,Bitu _dy) { + x=_x;y=_y;dx=_dx;dy=_dy; + buttons.push_back(this); + color=CLR_WHITE; + enabled=true; + } + virtual void Draw(void) { + if (!enabled) return; + Bit8u * point=((Bit8u *)mapper.surface->pixels)+(y*mapper.surface->pitch)+x; + for (Bitu lines=0;linespitch; + } + } + virtual bool OnTop(Bitu _x,Bitu _y) { + return ( enabled && (_x>=x) && (_x=y) && (_ybindlist.end()) { + delete (*mapper.abindit); + mapper.abindit=mapper.aevent->bindlist.erase(mapper.abindit); + if (mapper.abindit==mapper.aevent->bindlist.end()) + mapper.abindit=mapper.aevent->bindlist.begin(); + } + if (mapper.abindit!=mapper.aevent->bindlist.end()) SetActiveBind(*(mapper.abindit)); + else SetActiveBind(0); + break; + case BB_Next: + if (mapper.abindit!=mapper.aevent->bindlist.end()) + mapper.abindit++; + if (mapper.abindit==mapper.aevent->bindlist.end()) + mapper.abindit=mapper.aevent->bindlist.begin(); + SetActiveBind(*(mapper.abindit)); + break; + case BB_Save: + MAPPER_SaveBinds(); + break; + } + } +protected: + BB_Types type; +}; + +class CCheckButton : public CTextButton { +public: + CCheckButton(Bitu _x,Bitu _y,Bitu _dx,Bitu _dy,const char * _text,BC_Types _type) + : CTextButton(_x,_y,_dx,_dy,_text) { + type=_type; + } + void Draw(void) { + if (!enabled) return; + bool checked; + switch (type) { + case BC_Mod1: + checked=(mapper.abind->mods&BMOD_Mod1)>0; + break; + case BC_Mod2: + checked=(mapper.abind->mods&BMOD_Mod2)>0; + break; + case BC_Mod3: + checked=(mapper.abind->mods&BMOD_Mod3)>0; + break; + case BC_Hold: + checked=(mapper.abind->flags&BFLG_Hold)>0; + break; + } + if (checked) { + Bit8u * point=((Bit8u *)mapper.surface->pixels)+((y+2)*mapper.surface->pitch)+x+dx-dy+2; + for (Bitu lines=0;lines<(dy-4);lines++) { + memset(point,color,dy-4); + point+=mapper.surface->pitch; + } + } + CTextButton::Draw(); + } + void Click(void) { + switch (type) { + case BC_Mod1: + mapper.abind->mods^=BMOD_Mod1; + break; + case BC_Mod2: + mapper.abind->mods^=BMOD_Mod2; + break; + case BC_Mod3: + mapper.abind->mods^=BMOD_Mod3; + break; + case BC_Hold: + mapper.abind->flags^=BFLG_Hold; + break; + } + mapper.redraw=true; + } +protected: + BC_Types type; +}; + +class CKeyEvent : public CEvent { +public: + CKeyEvent(char * _entry,KBD_KEYS _key) : CEvent(_entry) { + key=_key; + } + void Active(bool yesno) { + KEYBOARD_AddKey(key,yesno); + }; + KBD_KEYS key; +}; + +class CJAxisEvent : public CEvent { +public: + CJAxisEvent(char * _entry,Bitu _stick,bool _yaxis,bool _positive) : CEvent(_entry) { + stick=_stick; + yaxis=_yaxis; + positive=_positive; + } + void Active(bool yesno) { + }; + Bitu stick; + bool yaxis,positive; +}; + +class CJButtonEvent : public CEvent { +public: + CJButtonEvent(char * _entry,Bitu _stick,Bitu _button) : CEvent(_entry) { + stick=_stick; + button=_button; + } + void Active(bool yesno) { + }; + Bitu stick,button; +}; + + +class CModEvent : public CEvent { +public: + CModEvent(char * _entry,Bitu _wmod) : CEvent(_entry) { + wmod=_wmod; + } + void Active(bool yesno) { + if (yesno) mapper.mods|=(1 << (wmod-1)); + else mapper.mods&=~(1 << (wmod-1)); + }; +protected: + Bitu wmod; +}; + +class CHandlerEvent : public CEvent { +public: + CHandlerEvent(char * _entry,MAPPER_Handler * _handler,MapKeys _key,Bitu _mod,char * _buttonname) : CEvent(_entry) { + handler=_handler; + defmod=_mod; + defkey=_key; + buttonname=_buttonname; + handlergroup.push_back(this); + } + void Active(bool yesno) { + if (yesno) (*handler)(); + }; + char * ButtonName(void) { + return buttonname; + } + void MakeDefaultBind(char * buf) { + Bitu key=0; + switch (defkey) { + case MK_f1:case MK_f2:case MK_f3:case MK_f4: + case MK_f5:case MK_f6:case MK_f7:case MK_f8: + case MK_f9:case MK_f10:case MK_f11:case MK_f12: + key=SDLK_F1+(defkey-MK_f1); + break; + case MK_return: + key=SDLK_RETURN; + break; + case MK_kpminus: + key=SDLK_KP_MINUS; + break; + } + sprintf(buf,"%s \"key %d%s%s%s\"", + entry, + key, + defmod & 1 ? " mod1" : "", + defmod & 2 ? " mod2" : "", + defmod & 4 ? " mod3" : "" + ); + } +protected: + MapKeys defkey; + Bitu defmod; + char * buttonname; + MAPPER_Handler * handler; +}; + + +struct { + CCaptionButton * event_title; + CCaptionButton * bind_title; + CCaptionButton * selected; + CCaptionButton * action; + CBindButton * save; + CBindButton * add; + CBindButton * del; + CBindButton * next; + CBindButton * prev; + CCheckButton * mod1,* mod2,* mod3,* hold; +} bind_but; + +static void SetActiveBind(CBind * _bind) { + mapper.abind=_bind; + if (_bind) { + bind_but.bind_title->Enable(true); + char buf[256];_bind->BindName(buf); + bind_but.bind_title->Change("BIND:%s",buf); + bind_but.del->Enable(true); + bind_but.next->Enable(true); + bind_but.mod1->Enable(true); + bind_but.mod2->Enable(true); + bind_but.mod3->Enable(true); + bind_but.hold->Enable(true); + } else { + bind_but.bind_title->Enable(false); + bind_but.del->Enable(false); + bind_but.prev->Enable(false); + bind_but.next->Enable(false); + bind_but.mod1->Enable(false); + bind_but.mod2->Enable(false); + bind_but.mod3->Enable(false); + bind_but.hold->Enable(false); + } +} + +static void SetActiveEvent(CEvent * event) { + mapper.aevent=event; + mapper.redraw=true; + mapper.addbind=false; + bind_but.event_title->Change("EVENT:%s",event ? event->GetName(): "none"); + if (!event) { + bind_but.action->Change("Select an event to change"); + bind_but.add->Enable(false); + SetActiveBind(0); + } else { + mapper.abindit=event->bindlist.begin(); + if (mapper.abindit!=event->bindlist.end()) { + SetActiveBind(*(mapper.abindit)); + } else SetActiveBind(0); + bind_but.add->Enable(true); + } +} + +static void DrawButtons(void) { + SDL_FillRect(mapper.surface,0,0); + SDL_LockSurface(mapper.surface); + for (CButton_it but_it = buttons.begin();but_it!=buttons.end();but_it++) { + (*but_it)->Draw(); + } + SDL_UnlockSurface(mapper.surface); + SDL_Flip(mapper.surface); +} + +static void AddKeyButtonEvent(Bitu x,Bitu y,Bitu dx,Bitu dy,const char * title,const char * entry,KBD_KEYS key) { + char buf[64]; + strcpy(buf,"key_"); + strcat(buf,entry); + CKeyEvent * event=new CKeyEvent(buf,key); + CButton * button=new CEventButton(x,y,dx,dy,title,event); +} + +static void AddJAxisButton(Bitu x,Bitu y,Bitu dx,Bitu dy,const char * title,Bitu stick,bool yaxis,bool positive) { + char buf[64]; + sprintf(buf,"jaxis_%d%s%s",stick,yaxis ? "Y":"X",positive ? "+" : "-"); + CJAxisEvent * event=new CJAxisEvent(buf,stick,yaxis,positive); + CButton * button=new CEventButton(x,y,dx,dy,title,event); +} + +static void AddJButtonButton(Bitu x,Bitu y,Bitu dx,Bitu dy,const char * title,Bitu _stick,Bitu _button) { + char buf[64]; + sprintf(buf,"jbutton_%d_%d",_stick,_button); + CJButtonEvent * event=new CJButtonEvent(buf,_stick,_button); + CButton * button=new CEventButton(x,y,dx,dy,title,event); +} + + +static void AddModButton(Bitu x,Bitu y,Bitu dx,Bitu dy,const char * title,Bitu _mod) { + char buf[64]; + sprintf(buf,"mod_%d",_mod); + CModEvent * event=new CModEvent(buf,_mod); + CButton * button=new CEventButton(x,y,dx,dy,title,event); +} + +struct KeyBlock { + const char * title; + const char * entry; + KBD_KEYS key; +}; +static KeyBlock combo_f[12]={ + {"F1","f1",KBD_f1}, {"F2","f2",KBD_f2}, {"F3","f3",KBD_f3}, + {"F4","f4",KBD_f4}, {"F5","f5",KBD_f5}, {"F6","f6",KBD_f6}, + {"F7","f7",KBD_f7}, {"F8","f8",KBD_f8}, {"F9","f9",KBD_f9}, + {"F10","f10",KBD_f10}, {"F11","f11",KBD_f11}, {"F12","f12",KBD_f12}, +}; + +static KeyBlock combo_1[14]={ + {"`~","grave",KBD_grave}, {"1!","1",KBD_1}, {"2@","2",KBD_2}, + {"3#","3",KBD_3}, {"4$","4",KBD_4}, {"5%","5",KBD_5}, + {"6^","6",KBD_6}, {"7&","7",KBD_7}, {"8*","8",KBD_8}, + {"9(","9",KBD_9}, {"0)","0",KBD_0}, {"-_","minus",KBD_minus}, + {"=+","equals",KBD_equals}, {"\x1B","bspace",KBD_backspace}, +}; + +static KeyBlock combo_2[12]={ + {"q","q",KBD_q}, {"w","w",KBD_w}, {"e","e",KBD_e}, + {"r","r",KBD_r}, {"t","t",KBD_t}, {"y","y",KBD_y}, + {"u","u",KBD_u}, {"i","i",KBD_i}, {"o","o",KBD_o}, + {"p","p",KBD_p}, {"[","lbracket",KBD_leftbracket}, + {"]","rbracket",KBD_rightbracket}, +}; + +static KeyBlock combo_3[12]={ + {"a","a",KBD_a}, {"s","s",KBD_s}, {"d","d",KBD_d}, + {"f","f",KBD_f}, {"g","g",KBD_g}, {"h","h",KBD_h}, + {"j","j",KBD_j}, {"k","k",KBD_k}, {"l","l",KBD_l}, + {";","semicolon",KBD_semicolon}, {"'","quote",KBD_quote}, + {"\\","backslash",KBD_backslash}, +}; + +static KeyBlock combo_4[10]={ + {"z","z",KBD_z}, {"x","x",KBD_x}, {"c","c",KBD_c}, + {"v","v",KBD_v}, {"b","b",KBD_b}, {"n","n",KBD_n}, + {"m","m",KBD_m}, {",","comma",KBD_comma}, + {".","period",KBD_period}, {"/","slash",KBD_slash}, +}; + + +static void CreateLayout(void) { + Bitu i; + /* Create the buttons for the Keyboard */ +#define BW 28 +#define BH 20 +#define PX(_X_) ((_X_)*BW) +#define PY(_Y_) (30+(_Y_)*BH) + AddKeyButtonEvent(PX(0),PY(0),BW,BH,"ESC","esc",KBD_esc); + for (i=0;i<12;i++) AddKeyButtonEvent(PX(2+i),PY(0),BW,BH,combo_f[i].title,combo_f[i].entry,combo_f[i].key); + for (i=0;i<14;i++) AddKeyButtonEvent(PX( i),PY(1),BW,BH,combo_1[i].title,combo_1[i].entry,combo_1[i].key); + + AddKeyButtonEvent(PX(0),PY(2),BW*2,BH,"TAB","tab",KBD_tab); + for (i=0;i<12;i++) AddKeyButtonEvent(PX(2+i),PY(2),BW,BH,combo_2[i].title,combo_2[i].entry,combo_2[i].key); + + AddKeyButtonEvent(PX(14),PY(2),BW*2,BH*2,"ENTER","enter",KBD_enter); + + AddKeyButtonEvent(PX(0),PY(3),BW*2,BH,"CLCK","capslock",KBD_capslock); + for (i=0;i<12;i++) AddKeyButtonEvent(PX(2+i),PY(3),BW,BH,combo_3[i].title,combo_3[i].entry,combo_3[i].key); + + AddKeyButtonEvent(0,PY(4),BW*3,BH,"SHIFT","lshift",KBD_leftshift); + for (i=0;i<10;i++) AddKeyButtonEvent(PX(3+i),PY(4),BW,BH,combo_4[i].title,combo_4[i].entry,combo_4[i].key); + AddKeyButtonEvent(PX(13),PY(4),BW*3,BH,"SHIFT","rshift",KBD_rightshift); + + /* Last Row */ + AddKeyButtonEvent(PX(0) ,PY(5),BW*2,BH,"CTRL","lctrl",KBD_leftctrl); + AddKeyButtonEvent(PX(3) ,PY(5),BW*2,BH,"ALT","lalt",KBD_leftalt); + AddKeyButtonEvent(PX(5) ,PY(5),BW*6,BH,"SPACE","space",KBD_space); + AddKeyButtonEvent(PX(11),PY(5),BW*2,BH,"ALT","ralt",KBD_rightalt); + AddKeyButtonEvent(PX(14),PY(5),BW*2,BH,"CTRL","rctrl",KBD_rightctrl); + + /* Arrow Keys */ + AddKeyButtonEvent(PX(0),PY(7),BW,BH,"INS","insert",KBD_insert); + AddKeyButtonEvent(PX(1),PY(7),BW,BH,"HOM","home",KBD_home); + AddKeyButtonEvent(PX(2),PY(7),BW,BH,"PUP","pageup",KBD_pageup); + AddKeyButtonEvent(PX(0),PY(8),BW,BH,"DEL","delete",KBD_delete); + AddKeyButtonEvent(PX(1),PY(8),BW,BH,"END","end",KBD_end); + AddKeyButtonEvent(PX(2),PY(8),BW,BH,"PDN","pagedown",KBD_pagedown); + AddKeyButtonEvent(PX(1),PY(10),BW,BH,"\x18","up",KBD_up); + AddKeyButtonEvent(PX(0),PY(11),BW,BH,"\x1B","left",KBD_left); + AddKeyButtonEvent(PX(1),PY(11),BW,BH,"\x19","down",KBD_down); + AddKeyButtonEvent(PX(2),PY(11),BW,BH,"\x1A","right",KBD_right); + /* Numeric KeyPad */ + AddKeyButtonEvent(PX(4),PY(7),BW,BH,"NUM","numlock",KBD_numlock); + AddKeyButtonEvent(PX(5),PY(7),BW,BH,"/","kp_divide",KBD_kpdivide); + AddKeyButtonEvent(PX(6),PY(7),BW,BH,"*","kp_multiply",KBD_kpmultiply); + AddKeyButtonEvent(PX(7),PY(7),BW,BH,"-","kp_minus",KBD_kpminus); + AddKeyButtonEvent(PX(4),PY(8),BW,BH,"7","kp_7",KBD_kp7); + AddKeyButtonEvent(PX(5),PY(8),BW,BH,"8","kp_8",KBD_kp8); + AddKeyButtonEvent(PX(6),PY(8),BW,BH,"9","kp_9",KBD_kp9); + AddKeyButtonEvent(PX(7),PY(8),BW,BH*2,"+","kp_plus",KBD_kpplus); + AddKeyButtonEvent(PX(4),PY(9),BW,BH,"4","kp_4",KBD_kp4); + AddKeyButtonEvent(PX(5),PY(9),BW,BH,"5","kp_5",KBD_kp5); + AddKeyButtonEvent(PX(6),PY(9),BW,BH,"6","kp_6",KBD_kp6); + AddKeyButtonEvent(PX(4),PY(10),BW,BH,"1","kp_1",KBD_kp1); + AddKeyButtonEvent(PX(5),PY(10),BW,BH,"2","kp_2",KBD_kp2); + AddKeyButtonEvent(PX(6),PY(10),BW,BH,"3","kp_3",KBD_kp3); + AddKeyButtonEvent(PX(7),PY(10),BW,BH*2,"ENT","kp_enter",KBD_kpenter); + AddKeyButtonEvent(PX(4),PY(11),BW*2,BH,"0","kp_0",KBD_kp0); + AddKeyButtonEvent(PX(6),PY(11),BW,BH,".","kp_period",KBD_kpperiod); + + + /* Joystick Buttons/Texts */ + AddJButtonButton(PX(17),PY(0),BW,BH,"1" ,0,0); + AddJAxisButton (PX(18),PY(0),BW,BH,"Y-",0,true,false); + AddJButtonButton(PX(19),PY(0),BW,BH,"2" ,0,1); + AddJAxisButton (PX(17),PY(1),BW,BH,"X-",0,false,false); + AddJAxisButton (PX(18),PY(1),BW,BH,"Y+",0,true,true); + AddJAxisButton (PX(19),PY(1),BW,BH,"X+",0,false,true); + + AddJButtonButton(PX(17),PY(3),BW,BH,"1" ,1,0); + AddJAxisButton (PX(18),PY(3),BW,BH,"Y-",1,true,false); + AddJButtonButton(PX(19),PY(3),BW,BH,"2" ,1,1); + AddJAxisButton (PX(17),PY(4),BW,BH,"X-",1,false,false); + AddJAxisButton (PX(18),PY(4),BW,BH,"Y+",1,true,true); + AddJAxisButton (PX(19),PY(4),BW,BH,"X+",1,false,true); /* The modifier buttons */ + AddModButton(PX(0),PY(13),50,20,"Mod1",1); + AddModButton(PX(2),PY(13),50,20,"Mod2",2); + AddModButton(PX(4),PY(13),50,20,"Mod3",3); + /* Create Handler buttons */ + Bitu xpos=3;Bitu ypos=7; + for (CHandlerEventVector_it hit=handlergroup.begin();hit!=handlergroup.end();hit++) { + new CEventButton(PX(xpos*3),PY(ypos),BW*3,BH,(*hit)->ButtonName(),(*hit)); + xpos++; + if (xpos>6) { + xpos=3;ypos++; + } + } + /* Create some text buttons */ + new CTextButton(200,00,124,20,"Keyboard Layout"); + + bind_but.action=new CCaptionButton(200,330,0,0); + + bind_but.event_title=new CCaptionButton(0,350,0,0); + bind_but.bind_title=new CCaptionButton(00,365,0,0); + + /* Create binding support buttons */ + + bind_but.mod1=new CCheckButton(20,410,60,20, "mod1",BC_Mod1); + bind_but.mod2=new CCheckButton(20,432,60,20, "mod2",BC_Mod2); + bind_but.mod3=new CCheckButton(20,454,60,20, "mod3",BC_Mod3); + bind_but.hold=new CCheckButton(100,410,60,20,"hold",BC_Hold); + + bind_but.prev=new CBindButton(200,400,50,20,"Prev",BB_Prev); + bind_but.next=new CBindButton(250,400,50,20,"Next",BB_Next); + + bind_but.add=new CBindButton(250,380,50,20,"Add",BB_Add); + bind_but.del=new CBindButton(300,380,50,20,"Del",BB_Del); + + bind_but.save=new CBindButton(400,450,50,20,"Save",BB_Save); + + bind_but.bind_title->Change("Bind Title"); +} + +static SDL_Color map_pal[4]={ + {0x00,0x00,0x00,0x00}, //0=black + {0xff,0xff,0xff,0x00}, //1=white + {0xff,0x00,0x00,0x00}, //2=red +}; + +static void CreateStringBind(char * line) { + line=trim(line); + char * eventname=StripWord(line); + CEvent * event; + for (CEventVector_it ev_it=events.begin();ev_it!=events.end();ev_it++) { + if (!strcasecmp((*ev_it)->GetName(),eventname)) { + event=*ev_it; + goto foundevent; + } + } + LOG_MSG("Can't find matching event for %s",eventname); + return ; +foundevent: + CBind * bind; + for (char * bindline=StripWord(line);*bindline;bindline=StripWord(line)) { + for (CBindGroup_it it=bindgroups.begin();it!=bindgroups.end();it++) { + bind=(*it)->CreateConfigBind(bindline); + if (bind) { + event->AddBind(bind); + bind->SetFlags(bindline); + break; + } + } + } +} + +static struct { + char * eventend; + Bitu key; +} DefaultKeys[]={ + {"f1",SDLK_F1}, {"f2",SDLK_F2}, {"f3",SDLK_F3}, {"f4",SDLK_F4}, + {"f5",SDLK_F1}, {"f6",SDLK_F6}, {"f7",SDLK_F7}, {"f8",SDLK_F8}, + {"f9",SDLK_F9}, {"f10",SDLK_F10}, {"f11",SDLK_F11}, {"f12",SDLK_F12}, + + {"1",SDLK_1}, {"2",SDLK_2}, {"3",SDLK_3}, {"4",SDLK_4}, + {"5",SDLK_5}, {"6",SDLK_6}, {"7",SDLK_7}, {"8",SDLK_8}, + {"9",SDLK_9}, {"0",SDLK_0}, + + {"a",SDLK_a}, {"b",SDLK_b}, {"c",SDLK_c}, {"d",SDLK_d}, + {"e",SDLK_e}, {"f",SDLK_f}, {"g",SDLK_g}, {"h",SDLK_h}, + {"i",SDLK_i}, {"j",SDLK_j}, {"k",SDLK_k}, {"l",SDLK_l}, + {"m",SDLK_m}, {"n",SDLK_n}, {"o",SDLK_o}, {"p",SDLK_p}, + {"q",SDLK_q}, {"r",SDLK_r}, {"s",SDLK_s}, {"t",SDLK_t}, + {"u",SDLK_u}, {"v",SDLK_v}, {"w",SDLK_w}, {"x",SDLK_x}, + {"y",SDLK_y}, {"z",SDLK_z}, {"space",SDLK_SPACE}, + {"esc",SDLK_ESCAPE}, {"equals",SDLK_EQUALS}, {"grave",SDLK_BACKQUOTE}, + {"tab",SDLK_TAB}, {"enter",SDLK_RETURN}, {"bspace",SDLK_BACKSPACE}, + {"lbracket",SDLK_LEFTBRACKET}, {"rbracket",SDLK_RIGHTBRACKET}, + {"minus",SDLK_MINUS}, {"capslock",SDLK_CAPSLOCK}, {"semicolon",SDLK_SEMICOLON}, + {"quote", SDLK_QUOTE}, {"backslash",SDLK_BACKSLASH}, {"lshift",SDLK_LSHIFT}, + {"rshift",SDLK_RSHIFT}, {"lalt",SDLK_LALT}, {"ralt",SDLK_RALT}, + {"lctrl",SDLK_LCTRL}, {"rctrl",SDLK_RCTRL}, {"comma",SDLK_COMMA}, + {"period",SDLK_PERIOD}, {"slash",SDLK_SLASH}, {"pagedown",SDLK_PAGEDOWN}, + {"pageup",SDLK_PAGEUP}, {"insert",SDLK_INSERT}, {"home",SDLK_HOME}, + {"delete",SDLK_DELETE}, {"end",SDLK_END}, {"up",SDLK_UP}, + {"left",SDLK_LEFT}, {"down",SDLK_DOWN}, {"right",SDLK_RIGHT}, + {"kp_0",SDLK_KP0}, {"kp_1",SDLK_KP1}, {"kp_2",SDLK_KP2}, {"kp_3",SDLK_KP3}, + {"kp_4",SDLK_KP4}, {"kp_5",SDLK_KP5}, {"kp_6",SDLK_KP6}, {"kp_7",SDLK_KP7}, + {"kp_8",SDLK_KP8}, {"kp_9",SDLK_KP9}, {"numlock",SDLK_NUMLOCK}, + {"kp_divide",SDLK_KP_DIVIDE}, {"kp_multiply",SDLK_KP_MULTIPLY}, + {"kp_minus",SDLK_KP_MINUS}, {"kp_plus",SDLK_KP_PLUS}, + {"kp_period",SDLK_KP_PERIOD}, {"kp_enter",SDLK_KP_ENTER}, + {0,0} +}; + +static void CreateDefaultBinds(void) { + char buffer[512]; + Bitu i=0; + while (DefaultKeys[i].eventend) { + sprintf(buffer,"key_%s \"key %d\"",DefaultKeys[i].eventend,DefaultKeys[i].key); + CreateStringBind(buffer); + i++; + } + sprintf(buffer,"mod_1 \"key %d\"",SDLK_RCTRL);CreateStringBind(buffer); + sprintf(buffer,"mod_1 \"key %d\"",SDLK_LCTRL);CreateStringBind(buffer); + sprintf(buffer,"mod_2 \"key %d\"",SDLK_LALT);CreateStringBind(buffer); + for (CHandlerEventVector_it hit=handlergroup.begin();hit!=handlergroup.end();hit++) { + (*hit)->MakeDefaultBind(buffer); + CreateStringBind(buffer); + } +} + +void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char * eventname,char * buttonname) { + char tempname[17]; + strcpy(tempname,"hand_"); + strcat(tempname,eventname); + new CHandlerEvent(tempname,handler,key,mods,buttonname); +} + +static void MAPPER_SaveBinds(void) { + FILE * savefile=fopen(mapper.filename,"wb+"); + if (!savefile) { + LOG_MSG("Can't open %s for saving the mappings",mapper.filename); + return; + } + char buf[128]; + for (CEventVector_it event_it=events.begin();event_it!=events.end();event_it++) { + CEvent * event=*(event_it); + fprintf(savefile,"%s ",event->GetName()); + for (CBindList_it bind_it=event->bindlist.begin();bind_it!=event->bindlist.end();bind_it++) { + CBind * bind=*(bind_it); + bind->ConfigName(buf); + bind->AddFlags(buf); + fprintf(savefile,"\"%s\" ",buf); + } + fprintf(savefile,"\n"); + } + fclose(savefile); +} + +static bool MAPPER_LoadBinds(void) { + FILE * loadfile=fopen(mapper.filename,"rb+"); + if (!loadfile) return false; + char linein[512]; + while (fgets(linein,512,loadfile)) { + CreateStringBind(linein); + } + fclose(loadfile); + return true; +} + +void MAPPER_CheckEvent(SDL_Event * event) { + for (CBindGroup_it it=bindgroups.begin();it!=bindgroups.end();it++) { + if ((*it)->CheckEvent(event)) return; + } +} + +void BIND_MappingEvents(void) { + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_MOUSEBUTTONDOWN: + /* Check the press */ + for (CButton_it but_it = buttons.begin();but_it!=buttons.end();but_it++) { + if ((*but_it)->OnTop(event.button.x,event.button.y)) { + (*but_it)->Click(); + } + } + break; + case SDL_QUIT: + mapper.exit=true; + break; + default: + if (mapper.addbind) for (CBindGroup_it it=bindgroups.begin();it!=bindgroups.end();it++) { + CBind * newbind=(*it)->CreateEventBind(&event); + if (!newbind) continue; + mapper.aevent->AddBind(newbind); + SetActiveEvent(mapper.aevent); + mapper.addbind=false; + break; + } + } + } +} + +static void CreateBindGroups(void) { + bindgroups.clear(); + new CKeyBindGroup(SDLK_LAST); + Bitu numsticks=SDL_NumJoysticks(); + if (numsticks) SDL_JoystickEventState(SDL_ENABLE); + for (Bitu i=0;iDeActivateAll(); + } + mapper.surface=SDL_SetVideoMode(640,480,8,0); + /* Set some palette entries */ + SDL_SetPalette(mapper.surface, SDL_LOGPAL|SDL_PHYSPAL, map_pal, 0, 4); + /* Go in the event loop */ + mapper.exit=false; + mapper.redraw=true; + SetActiveEvent(0); + while (!mapper.exit) { + if (mapper.redraw) { + mapper.redraw=false; + DrawButtons(); + } + BIND_MappingEvents(); + SDL_Delay(1); + } + GFX_ResetScreen(); +} + +void MAPPER_Init(void) { + CreateLayout(); + CreateBindGroups(); + if (!MAPPER_LoadBinds()) CreateDefaultBinds(); +} + +void MAPPER_StartUp(Section * sec) { + Section_prop * section=static_cast(sec); + mapper.filename=section->Get_string("mapperfile"); + MAPPER_AddHandler(&MAPPER_Run,MK_f1,MMOD1,"mapper","Mapper"); +} + diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 95c04792..e02e4525 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.65 2004-06-05 11:17:23 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.66 2004-06-10 07:18:19 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -32,14 +32,13 @@ #include "dosbox.h" #include "video.h" -#include "keyboard.h" #include "mouse.h" -#include "joystick.h" #include "pic.h" #include "timer.h" #include "setup.h" #include "support.h" #include "debug.h" +#include "mapper.h" //#define DISABLE_JOYSTICK @@ -104,6 +103,9 @@ extern char** environ; #define DEFAULT_CONFIG_FILE "/.dosboxrc" #endif +void MAPPER_Init(void); +void MAPPER_StartUp(Section * sec); + enum SCREEN_TYPES { SCREEN_SURFACE, SCREEN_OVERLAY, @@ -117,7 +119,8 @@ struct SDL_Block { struct { Bit32u width; Bit32u height; - Bitu bpp; + Bitu flags; + GFX_Modes mode; double scalex,scaley; GFX_ResetCallBack reset; } draw; @@ -149,7 +152,6 @@ struct SDL_Block { SDL_Rect clip; SDL_Surface * surface; SDL_Overlay * overlay; - SDL_Joystick * joy; SDL_cond *cond; struct { bool autolock; @@ -163,45 +165,63 @@ struct SDL_Block { static SDL_Block sdl; static void CaptureMouse(void); +extern const char * RunningProgram; void GFX_SetTitle(Bits cycles,Bits frameskip){ char title[200]={0}; static Bits internal_cycles=0; static Bits internal_frameskip=0; if(cycles != -1) internal_cycles = cycles; if(frameskip != -1) internal_frameskip = frameskip; - sprintf(title,"DOSBox %s, Cpu Cycles: %8d, Frameskip %2d",VERSION,internal_cycles,internal_frameskip); + sprintf(title,"DOSBox %s,Cpu Cycles: %8d, Frameskip %2d, Program: %s",VERSION,internal_cycles,internal_frameskip,RunningProgram); SDL_WM_SetCaption(title,VERSION); } /* Reset the screen with current values in the sdl structure */ -Bitu GFX_GetBestMode(Bitu bpp,Bitu & gfx_flags) { - gfx_flags=0; +Bitu GFX_GetBestMode(Bitu flags) { + Bitu testbpp,gotbpp,setflags; switch (sdl.desktop.want_type) { case SCREEN_SURFACE: - if (sdl.desktop.fullscreen) { - bpp=SDL_VideoModeOK(640,480,bpp,SDL_FULLSCREEN|SDL_HWSURFACE | - (sdl.desktop.doublebuf ? SDL_DOUBLEBUF : 0) | ((bpp==8) ? SDL_HWPALETTE : 0) ); - } else { - bpp=sdl.desktop.bpp; +check_surface: + /* Check if we can satisfy the depth it loves */ + if (flags & LOVE_8) testbpp=8; + else if (flags & LOVE_16) testbpp=16; + else if (flags & LOVE_32) testbpp=32; + if (sdl.desktop.fullscreen) gotbpp=SDL_VideoModeOK(640,480,testbpp,SDL_FULLSCREEN|SDL_HWSURFACE|SDL_HWPALETTE); + else gotbpp=sdl.desktop.bpp; + /* If we can't get our favorite mode check for another working one */ + switch (gotbpp) { + case 8: + if (flags & CAN_8) flags&=~(CAN_16|CAN_32); + break; + case 15: + case 16: + if (flags & CAN_16) flags&=~(CAN_8|CAN_32); + break; + case 24: + case 32: + if (flags & CAN_32) flags&=~(CAN_8|CAN_16); + break; } - gfx_flags|=GFX_HASCONVERT; + /* Not a valid display depth found? Let's just hope sdl provides conversions */ break; case SCREEN_OVERLAY: - bpp=32; - gfx_flags|=GFX_HASSCALING; + if (flags & NEED_RGB || !(flags&CAN_32)) goto check_surface; + flags|=HAVE_SCALING; + flags&=~(CAN_8,CAN_16); break; #if C_OPENGL case SCREEN_OPENGL: - bpp=32; - gfx_flags|=GFX_HASSCALING; + if (flags & NEED_RGB || !(flags&CAN_32)) goto check_surface; + flags|=HAVE_SCALING; + flags&=~(CAN_8,CAN_16); break; #endif } - return bpp; + return flags; } -static void ResetScreen(void) { +void GFX_ResetScreen(void) { GFX_Stop(); if (sdl.draw.reset) (sdl.draw.reset)(); GFX_Start(); @@ -214,18 +234,23 @@ static int int_log2 (int val) { return log; } -void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,double scalex,double scaley,GFX_ResetCallBack reset) { +GFX_Modes GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_ResetCallBack reset) { if (sdl.updating) GFX_EndUpdate(); sdl.draw.width=width; sdl.draw.height=height; - sdl.draw.bpp=bpp; + sdl.draw.flags=flags; + sdl.draw.mode=GFX_NONE; sdl.draw.reset=reset; sdl.draw.scalex=scalex; sdl.draw.scaley=scaley; + Bitu bpp; switch (sdl.desktop.want_type) { case SCREEN_SURFACE: dosurface: + if (flags & CAN_8) bpp=8; + if (flags & CAN_16) bpp=16; + if (flags & CAN_32) bpp=32; sdl.desktop.type=SCREEN_SURFACE; sdl.clip.w=width; sdl.clip.h=height; @@ -234,21 +259,29 @@ dosurface: sdl.clip.x=(Sint16)((sdl.desktop.width-width)/2); sdl.clip.y=(Sint16)((sdl.desktop.height-height)/2); sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,bpp, - SDL_FULLSCREEN|SDL_HWSURFACE|(sdl.desktop.doublebuf ? SDL_DOUBLEBUF : 0)|SDL_HWPALETTE); + SDL_FULLSCREEN|SDL_HWSURFACE|(sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0)|SDL_HWPALETTE); } else { sdl.clip.x=0;sdl.clip.y=0; sdl.surface=SDL_SetVideoMode(width,height,bpp, - SDL_FULLSCREEN|SDL_HWSURFACE|(sdl.desktop.doublebuf ? SDL_DOUBLEBUF : 0)|SDL_HWPALETTE); + SDL_FULLSCREEN|SDL_HWSURFACE|(sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0)|SDL_HWPALETTE); } } else { sdl.clip.x=0;sdl.clip.y=0; sdl.surface=SDL_SetVideoMode(width,height,bpp,SDL_HWSURFACE); } + if (sdl.surface) switch (sdl.surface->format->BitsPerPixel) { + case 8:sdl.draw.mode=GFX_8;break; + case 15:sdl.draw.mode=GFX_15;break; + case 16:sdl.draw.mode=GFX_16;break; + case 32:sdl.draw.mode=GFX_32;break; + default: + break; + } break; case SCREEN_OVERLAY: if (sdl.overlay) SDL_FreeYUVOverlay(sdl.overlay); sdl.overlay=0; - if (bpp!=32) goto dosurface; + if (!(flags&CAN_32) || (flags & NEED_RGB)) goto dosurface; if (sdl.desktop.fullscreen) { if (sdl.desktop.fixed) { double ratio_w=(double)sdl.desktop.width/(width*scalex); @@ -283,6 +316,7 @@ dosurface: goto dosurface; } sdl.desktop.type=SCREEN_OVERLAY; + sdl.draw.mode=GFX_32; break; #if C_OPENGL case SCREEN_OPENGL: @@ -295,7 +329,7 @@ dosurface: free(sdl.opengl.framebuf); } sdl.opengl.framebuf=0; - if (bpp!=32) goto dosurface; + if (!(flags&CAN_32) || (flags & NEED_RGB)) goto dosurface; int texsize=2 << int_log2(width > height ? width : height); if (texsize>sdl.opengl.max_texsize) { LOG_MSG("SDL:OPENGL:No support for texturesize of %d, falling back to surface",texsize); @@ -368,6 +402,8 @@ dosurface: glClearColor (0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); + SDL_GL_SwapBuffers(); + glClear(GL_COLOR_BUFFER_BIT); glShadeModel (GL_FLAT); glDisable (GL_DEPTH_TEST); glDisable (GL_LIGHTING); @@ -395,11 +431,13 @@ dosurface: glEnd(); glEndList(); sdl.desktop.type=SCREEN_OPENGL; + sdl.draw.mode=GFX_32; break; }//OPENGL #endif //C_OPENGL }//CASE - GFX_Start(); + if (sdl.draw.mode!=GFX_NONE) GFX_Start(); + return sdl.draw.mode; } @@ -421,7 +459,7 @@ static void SwitchFullScreen(void) { } else { if (sdl.mouse.locked) CaptureMouse(); } - ResetScreen(); + GFX_ResetScreen(); } void GFX_SwitchFullScreen(void) { @@ -630,14 +668,11 @@ static void GUI_StartUp(Section * sec) { if (sdl.desktop.bpp==24) { LOG_MSG("SDL:You are running in 24 bpp mode, this will slow down things!"); } - GFX_SetSize(640,400,8,1.0,1.0,0); - SDL_EnableKeyRepeat(250,40); - SDL_EnableUNICODE(1); -/* Get some Keybinds */ - KEYBOARD_AddEvent(KBD_f9,KBD_MOD_CTRL,KillSwitch); - KEYBOARD_AddEvent(KBD_f10,KBD_MOD_CTRL,CaptureMouse); - KEYBOARD_AddEvent(KBD_enter,KBD_MOD_ALT,SwitchFullScreen); - + GFX_Stop(); +/* Get some Event handlers */ + MAPPER_AddHandler(KillSwitch,MK_f9,MMOD1,"shutdown","ShutDown"); + MAPPER_AddHandler(CaptureMouse,MK_f10,MMOD1,"capmouse","Cap Mouse"); + MAPPER_AddHandler(SwitchFullScreen,MK_return,MMOD2,"fullscr","Fullscreen"); } void Mouse_AutoLock(bool enable) { @@ -646,143 +681,6 @@ void Mouse_AutoLock(bool enable) { else sdl.mouse.requestlock=false; } -static void HandleKey(SDL_KeyboardEvent * key) { - KBD_KEYS code; - switch (key->keysym.sym) { - case SDLK_1:code=KBD_1;break; - case SDLK_2:code=KBD_2;break; - case SDLK_3:code=KBD_3;break; - case SDLK_4:code=KBD_4;break; - case SDLK_5:code=KBD_5;break; - case SDLK_6:code=KBD_6;break; - case SDLK_7:code=KBD_7;break; - case SDLK_8:code=KBD_8;break; - case SDLK_9:code=KBD_9;break; - case SDLK_0:code=KBD_0;break; - - case SDLK_q:code=KBD_q;break; - case SDLK_w:code=KBD_w;break; - case SDLK_e:code=KBD_e;break; - case SDLK_r:code=KBD_r;break; - case SDLK_t:code=KBD_t;break; - case SDLK_y:code=KBD_y;break; - case SDLK_u:code=KBD_u;break; - case SDLK_i:code=KBD_i;break; - case SDLK_o:code=KBD_o;break; - case SDLK_p:code=KBD_p;break; - - case SDLK_a:code=KBD_a;break; - case SDLK_s:code=KBD_s;break; - case SDLK_d:code=KBD_d;break; - case SDLK_f:code=KBD_f;break; - case SDLK_g:code=KBD_g;break; - case SDLK_h:code=KBD_h;break; - case SDLK_j:code=KBD_j;break; - case SDLK_k:code=KBD_k;break; - case SDLK_l:code=KBD_l;break; - - case SDLK_z:code=KBD_z;break; - case SDLK_x:code=KBD_x;break; - case SDLK_c:code=KBD_c;break; - case SDLK_v:code=KBD_v;break; - case SDLK_b:code=KBD_b;break; - case SDLK_n:code=KBD_n;break; - case SDLK_m:code=KBD_m;break; - - - case SDLK_F1:code=KBD_f1;break; - case SDLK_F2:code=KBD_f2;break; - case SDLK_F3:code=KBD_f3;break; - case SDLK_F4:code=KBD_f4;break; - case SDLK_F5:code=KBD_f5;break; - case SDLK_F6:code=KBD_f6;break; - case SDLK_F7:code=KBD_f7;break; - case SDLK_F8:code=KBD_f8;break; - case SDLK_F9:code=KBD_f9;break; - case SDLK_F10:code=KBD_f10;break; - case SDLK_F11:code=KBD_f11;break; - case SDLK_F12:code=KBD_f12;break; - - case SDLK_ESCAPE:code=KBD_esc;break; - case SDLK_TAB:code=KBD_tab;break; - case SDLK_BACKSPACE:code=KBD_backspace;break; - case SDLK_RETURN:code=KBD_enter;break; - case SDLK_SPACE:code=KBD_space;break; - - case SDLK_LALT:code=KBD_leftalt;break; - case SDLK_RALT:code=KBD_rightalt;break; - case SDLK_LCTRL:code=KBD_leftctrl;break; - case SDLK_RCTRL:code=KBD_rightctrl;break; - case SDLK_LSHIFT:code=KBD_leftshift;break; - case SDLK_RSHIFT:code=KBD_rightshift;break; - - case SDLK_CAPSLOCK:code=KBD_capslock;break; - case SDLK_SCROLLOCK:code=KBD_scrolllock;break; - case SDLK_NUMLOCK:code=KBD_numlock;break; - - case SDLK_BACKQUOTE:code=KBD_grave;break; - case SDLK_MINUS:code=KBD_minus;break; - case SDLK_EQUALS:code=KBD_equals;break; - case SDLK_BACKSLASH:code=KBD_backslash;break; - case SDLK_LEFTBRACKET:code=KBD_leftbracket;break; - case SDLK_RIGHTBRACKET:code=KBD_rightbracket;break; - - case SDLK_SEMICOLON:code=KBD_semicolon;break; - case SDLK_QUOTE:code=KBD_quote;break; - case SDLK_PERIOD:code=KBD_period;break; - case SDLK_COMMA:code=KBD_comma;break; - case SDLK_SLASH:code=KBD_slash;break; - - case SDLK_INSERT:code=KBD_insert;break; - case SDLK_HOME:code=KBD_home;break; - case SDLK_PAGEUP:code=KBD_pageup;break; - case SDLK_DELETE:code=KBD_delete;break; - case SDLK_END:code=KBD_end;break; - case SDLK_PAGEDOWN:code=KBD_pagedown;break; - case SDLK_LEFT:code=KBD_left;break; - case SDLK_UP:code=KBD_up;break; - case SDLK_DOWN:code=KBD_down;break; - case SDLK_RIGHT:code=KBD_right;break; - - case SDLK_KP1:code=KBD_kp1;break; - case SDLK_KP2:code=KBD_kp2;break; - case SDLK_KP3:code=KBD_kp3;break; - case SDLK_KP4:code=KBD_kp4;break; - case SDLK_KP5:code=KBD_kp5;break; - case SDLK_KP6:code=KBD_kp6;break; - case SDLK_KP7:code=KBD_kp7;break; - case SDLK_KP8:code=KBD_kp8;break; - case SDLK_KP9:code=KBD_kp9;break; - case SDLK_KP0:code=KBD_kp0;break; - - case SDLK_KP_DIVIDE:code=KBD_kpslash;break; - case SDLK_KP_MULTIPLY:code=KBD_kpmultiply;break; - case SDLK_KP_MINUS:code=KBD_kpminus;break; - case SDLK_KP_PLUS:code=KBD_kpplus;break; - case SDLK_KP_ENTER:code=KBD_kpenter;break; - case SDLK_KP_PERIOD:code=KBD_kpperiod;break; - - /* Special Keys */ - default: - code=KBD_1; - LOG(LOG_KEYBOARD,LOG_ERROR)("Unhandled SDL keysym %d",key->keysym.sym); - break; - } - /* Check the modifiers */ - Bitu mod= - ((key->keysym.mod & KMOD_CTRL) ? KBD_MOD_CTRL : 0) | - ((key->keysym.mod & KMOD_ALT) ? KBD_MOD_ALT : 0) | - ((key->keysym.mod & KMOD_SHIFT) ? KBD_MOD_SHIFT : 0); - Bitu ascii=key->keysym.unicode<128 ? key->keysym.unicode : 0; -#ifdef MACOSX - // HACK: Fix backspace on Mac OS X - // REMOVE ME oneday - if (code==KBD_backspace) - ascii=8; -#endif - KEYBOARD_AddKey(code,ascii,mod,(key->state==SDL_PRESSED)); -} - static void HandleMouseMotion(SDL_MouseMotionEvent * motion) { if (sdl.mouse.locked) Mouse_CursorMoved((float)motion->xrel*sdl.mouse.sensitivity/100,(float)motion->yrel*sdl.mouse.sensitivity/100); @@ -824,30 +722,7 @@ static void HandleMouseButton(SDL_MouseButtonEvent * button) { } } -static void HandleJoystickAxis(SDL_JoyAxisEvent * jaxis) { - switch (jaxis->axis) { - case 0: - JOYSTICK_Move_X(0,(float)(jaxis->value/32768.0)); - break; - case 1: - JOYSTICK_Move_Y(0,(float)(jaxis->value/32768.0)); - break; - } -} - -static void HandleJoystickButton(SDL_JoyButtonEvent * jbutton) { - bool state; - state=jbutton->type==SDL_JOYBUTTONDOWN; - if (jbutton->button<2) { - JOYSTICK_Button(0,jbutton->button,state); - } -} - - -static Bit8u laltstate = SDL_KEYUP; - void GFX_Events() { - SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { @@ -858,13 +733,6 @@ void GFX_Events() { } } break; - case SDL_KEYDOWN: - case SDL_KEYUP: - // ignore event lalt+tab - if (event.key.keysym.sym==SDLK_LALT) laltstate = event.key.type; - if ((event.key.keysym.sym==SDLK_TAB) && (laltstate==SDL_KEYDOWN)) break; - HandleKey(&event.key); - break; case SDL_MOUSEMOTION: HandleMouseMotion(&event.motion); break; @@ -872,19 +740,15 @@ void GFX_Events() { case SDL_MOUSEBUTTONUP: HandleMouseButton(&event.button); break; - case SDL_JOYAXISMOTION: - HandleJoystickAxis(&event.jaxis); - break; - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - HandleJoystickButton(&event.jbutton); - break; case SDL_VIDEORESIZE: // HandleVideoResize(&event.resize); break; case SDL_QUIT: throw(0); break; + default: + void MAPPER_CheckEvent(SDL_Event * event); + MAPPER_CheckEvent(&event); } } } @@ -931,11 +795,9 @@ int main(int argc, char* argv[]) { } } #endif //defined(WIN32) && !(C_DEBUG) - #if C_DEBUG DEBUG_SetupConsole(); #endif - if ( SDL_Init( SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM #ifndef DISABLE_JOYSTICK |SDL_INIT_JOYSTICK @@ -943,6 +805,7 @@ int main(int argc, char* argv[]) { #endif ) < 0 ) E_Exit("Can't init SDL %s",SDL_GetError()); Section_prop * sdl_sec=control->AddSection_prop("sdl",&GUI_StartUp); + sdl_sec->AddInitFunction(&MAPPER_StartUp); sdl_sec->Add_bool("fullscreen",false); sdl_sec->Add_bool("fulldouble",false); sdl_sec->Add_bool("fullfixed",false); @@ -953,6 +816,7 @@ int main(int argc, char* argv[]) { sdl_sec->Add_bool("autolock",true); sdl_sec->Add_int("sensitivity",100); sdl_sec->Add_bool("waitonerror",true); + sdl_sec->Add_string("mapperfile","mapper.txt"); MSG_Add("SDL_CONFIGFILE_HELP", "fullscreen -- Start dosbox directly in fullscreen.\n" @@ -996,19 +860,12 @@ int main(int argc, char* argv[]) { /* Init all the sections */ control->Init(); /* Some extra SDL Functions */ -#ifndef DISABLE_JOYSTICK - if (SDL_NumJoysticks()>0) { - SDL_JoystickEventState(SDL_ENABLE); - sdl.joy=SDL_JoystickOpen(0); - LOG_MSG("Using joystick %s with %d axes and %d buttons",SDL_JoystickName(0),SDL_JoystickNumAxes(sdl.joy),SDL_JoystickNumButtons(sdl.joy)); - JOYSTICK_Enable(0,true); - } -#endif if (control->cmdline->FindExist("-fullscreen") || sdl_sec->Get_bool("fullscreen")) { if(!sdl.desktop.fullscreen) { //only switch if not allready in fullscreen SwitchFullScreen(); } } + MAPPER_Init(); /* Start up main machine */ control->StartUp(); /* Shutdown everything */ From ae2dd7711e0468f1fb46349ad3485149702a92f7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 10 Jun 2004 07:21:02 +0000 Subject: [PATCH 1736/4131] Slight change in vga to support the new rendering Added some hardware acceleration functionality Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1818 --- src/hardware/Makefile.am | 2 +- src/hardware/vga.cpp | 1 + src/hardware/vga_crtc.cpp | 76 +++++- src/hardware/vga_draw.cpp | 99 +++++-- src/hardware/vga_gfx.cpp | 2 +- src/hardware/vga_memory.cpp | 81 +++++- src/hardware/vga_xga.cpp | 530 ++++++++++++++++++++++++++++++++++++ 7 files changed, 761 insertions(+), 30 deletions(-) create mode 100644 src/hardware/vga_xga.cpp diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index 4259ac3c..c4201d96 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -7,7 +7,7 @@ noinst_LIBRARIES = libhardware.a libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler.cpp joystick.cpp keyboard.cpp \ memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp vga_other.cpp \ - vga_memory.cpp vga_misc.cpp vga_seq.cpp cmos.cpp disney.cpp \ + vga_memory.cpp vga_misc.cpp vga_seq.cpp vga_xga.cpp cmos.cpp disney.cpp \ gus.cpp mpu401.cpp serialport.cpp softmodem.cpp ipx.cpp ipxserver.cpp diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 536af5e5..706d89a2 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -144,6 +144,7 @@ void VGA_Init(Section* sec) { VGA_SetupSEQ(); VGA_SetupAttr(); VGA_SetupOther(); + VGA_SetupXGA(); VGA_SetClock(0,CLK_25); VGA_SetClock(1,CLK_28); /* Generate tables */ diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 2becbde4..29dceccf 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -24,6 +24,13 @@ #define crtc(blah) vga.crtc.blah + +void VGA_MapMMIO(void); +void VGA_UnmapMMIO(void); + +void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen); +Bitu DEBUG_EnableDebugger(void); + void write_p3d4_vga(Bitu port,Bitu val,Bitu iolen) { crtc(index)=val; } @@ -325,6 +332,9 @@ void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen) { case 0x39: /* CR39 Register Lock 2 */ vga.s3.reg_lock2=val; break; + case 0x40: /* CR40 System Config */ + vga.s3.reg_40 = val; + break; case 0x43: /* CR43 Extended Mode */ vga.s3.reg_43=val & ~0x4; if (((val & 0x4) ^ (vga.config.scan_len >> 6)) & 0x4) { @@ -338,6 +348,43 @@ void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen) { (3d4h index 13h). (801/5,928) Only active if 3d4h index 51h bits 4-5 are 0 */ + case 0x45: /* Hardware cursor mode */ + vga.s3.hgc.curmode = val; + break; + case 0x46: + vga.s3.hgc.originx = (vga.s3.hgc.originx & 0x00ff) | (val << 8); + break; + case 0x47: /* HGC orgX */ + vga.s3.hgc.originx = (vga.s3.hgc.originx & 0xff00) | val; + break; + case 0x48: + vga.s3.hgc.originy = (vga.s3.hgc.originy & 0x00ff) | (val << 8); + break; + case 0x49: /* HGC orgY */ + vga.s3.hgc.originy = (vga.s3.hgc.originy & 0xff00) | val; + break; + case 0x4A: /* HGC foreground stack */ + if (vga.s3.hgc.fstackpos > 2) vga.s3.hgc.fstackpos = 0; + vga.s3.hgc.forestack[vga.s3.hgc.fstackpos] = val; + vga.s3.hgc.fstackpos++; + break; + case 0x4B: /* HGC background stack */ + if (vga.s3.hgc.bstackpos > 2) vga.s3.hgc.bstackpos = 0; + vga.s3.hgc.backstack[vga.s3.hgc.bstackpos] = val; + vga.s3.hgc.bstackpos++; + break; + case 0x4c: /* HGC start address high byte*/ + vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | ((val & 0xff) << 8); + break; + case 0x4d: /* HGC start address low byte*/ + vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | (val & 0xff); + break; + case 0x4e: /* HGC pattern start X */ + vga.s3.hgc.posx = val; + break; + case 0x4f: /* HGC pattern start X */ + vga.s3.hgc.posy = val; + break; case 0x51: /* Extended System Control 2 */ vga.s3.reg_51=val & 0xc0; //Only store bits 6,7 //TODO Display start @@ -374,6 +421,18 @@ void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen) { 7 (not 864/964) Enable EPROM Write. If set enables flash memory write control to the BIOS ROM address */ + case 0x53: + if((val & 0x10) != (vga.s3.ext_mem_ctrl & 0x10)) { + /* Map or unmap MMIO */ + if ((val & 0x10) != 0) { + LOG_MSG("VGA: Mapping Memory Mapped I/O to 0xA0000"); + VGA_MapMMIO(); + } else { + VGA_UnmapMMIO(); + } + } + vga.s3.ext_mem_ctrl = val; + break; case 0x55: /* Extended Video DAC Control */ vga.s3.reg_55=val; break; @@ -572,7 +631,7 @@ Bitu read_p3d5_vga(Bitu port,Bitu iolen) { return 0x11; //Trio 64 id case 0x2f: /* Revision */ - return 0x80; + return 0x00; case 0x30: /* CR30 Chip ID/REV register */ return 0xe0; //Trio+ dual byte // Trio32/64 has 0xe0. extended @@ -582,7 +641,8 @@ Bitu read_p3d5_vga(Bitu port,Bitu iolen) { case 0x35: /* CR35 CRT Register Lock */ return vga.s3.reg_35|(vga.s3.bank & 0xf); case 0x36: /* CR36 Reset State Read 1 */ - return 0x8f; + //return 0x8f; + return 0x8e; /* PCI version */ //2 Mb PCI and some bios settings case 0x37: /* Reset state read 2 */ return 0x2b; @@ -590,17 +650,29 @@ Bitu read_p3d5_vga(Bitu port,Bitu iolen) { return vga.s3.reg_lock1; case 0x39: /* CR39 Register Lock 2 */ return vga.s3.reg_lock2; + case 0x40: /* CR40 system config */ + return vga.s3.reg_40; case 0x43: /* CR43 Extended Mode */ return vga.s3.reg_43|((vga.config.scan_len>>6)&0x4); + case 0x45: /* Hardware cursor mode */ + vga.s3.hgc.bstackpos = 0; + vga.s3.hgc.fstackpos = 0; + return vga.s3.hgc.curmode; case 0x51: /* Extended System Control 2 */ return ((vga.config.display_start >> 16) & 3 ) | ((vga.s3.bank & 0x30) >> 2) | ((vga.config.scan_len & 0x300) >> 4) | vga.s3.reg_51; + case 0x53: + return vga.s3.ext_mem_ctrl; case 0x55: /* Extended Video DAC Control */ return vga.s3.reg_55; case 0x58: /* Linear Address Window Control */ return vga.s3.reg_58; + case 0x59: /* Linear Address Window Position High */ + return (vga.s3.la_window >> 8); + case 0x5a: /* Linear Address Window Position Low */ + return (vga.s3.la_window & 0xff); case 0x5D: /* Extended Horizontal Overflow */ return vga.s3.ex_hor_overflow; case 0x5e: /* Extended Vertical Overflow */ diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 5625f626..8d1c9036 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -29,25 +29,26 @@ typedef Bit8u * (* VGA_Line_Handler)(Bitu vidstart,Bitu panning,Bitu line); static VGA_Line_Handler VGA_DrawLine; +static Bit8u TempLine[1280]; static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { - line*=8*1024;Bit32u * draw=(Bit32u *)RENDER_TempLine; + line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; for (Bitu x=vga.draw.blocks;x>0;x--) { Bitu val=vga.mem.linear[vidstart+line];vidstart=(vidstart+1)&0x1fff; *draw++=CGA_2_Table[val >> 4]; *draw++=CGA_2_Table[val & 0xf]; } - return RENDER_TempLine; + return TempLine; } static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { - line*=8*1024;Bit32u * draw=(Bit32u *)RENDER_TempLine; + line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; for (Bitu x=0;x (vga.s3.hgc.originy + 63))) { + return VGA_Draw_VGA_Line(vidstart, panning, line); + } else { + memcpy(TempLine, VGA_Draw_VGA_Line(vidstart, panning, line), 640); + /* Draw mouse cursor */ + Bits moff = ((Bits)lineat - (Bits)vga.s3.hgc.originy) + (Bits)vga.s3.hgc.posy; + if(moff>63) moff=moff-64; + if(moff<0) moff+=64; + Bitu xat = vga.s3.hgc.originx; + Bitu m, mat; + mat = vga.s3.hgc.posx; + + for(m=0;m<64;m++) { + switch(vga.s3.hgc.mc[moff][mat]) { + case 0: + TempLine[xat] = vga.s3.hgc.backstack[0]; + break; + case 1: + TempLine[xat] = vga.s3.hgc.forestack[0]; + break; + case 2: + //Transparent + break; + case 3: + break; + } + xat++; + mat++; + if(mat>63) mat=0; + } + return TempLine; + } + } else { + /* HW Mouse not enabled, use the tried and true call */ + return VGA_Draw_VGA_Line(vidstart, panning, line); + } +} + + static Bit32u FontMask[2]={0xffffffff,0x0}; static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { - Bit32u * draw=(Bit32u *)RENDER_TempLine; + Bit32u * draw=(Bit32u *)TempLine; Bit8u * vidmem=&vga.mem.linear[vidstart]; for (Bitu cx=0;cx=0 && font_addrvga.draw.cursor.eline) goto skip_cursor; - draw=(Bit32u *)&RENDER_TempLine[font_addr*8]; + draw=(Bit32u *)&TempLine[font_addr*8]; Bit32u att=TXT_FG_Table[vga.mem.linear[vga.config.cursor_start*2+1]&0xf]; *draw++=att;*draw++=att; } skip_cursor: - return RENDER_TempLine; + return TempLine; } static void VGA_VerticalDisplayEnd(Bitu val) { @@ -128,11 +171,11 @@ static void VGA_HorizontalTimer(void) { } -static void VGA_DrawPart(void) { +static void VGA_DrawPart(Bitu lines) { Bitu subline=0;Bitu vidofs=vga.config.real_start; Bit8u * draw=0; - while (vga.draw.lines_left) { - vga.draw.lines_left--; + while (lines--) { + vga.draw.lines_done++; Bit8u * data=VGA_DrawLine(vga.draw.address,vga.draw.panning,vga.draw.address_line); RENDER_DrawLine(data); vga.draw.address_line++; @@ -140,14 +183,15 @@ static void VGA_DrawPart(void) { vga.draw.address_line=0; vga.draw.address+=vga.draw.address_add; } - if (vga.draw.split_line==vga.draw.lines_left) { + if (vga.draw.split_line==vga.draw.lines_done) { vga.draw.address=0;vga.draw.panning=0; vga.draw.address_line=0; } } - RENDER_EndUpdate(); -// vga.draw.parts_left--; -// if (vga.draw.parts_left) PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts); + vga.draw.parts_left--; + if (vga.draw.parts_left) { + PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts,vga.draw.parts_lines); + } else RENDER_EndUpdate(); } void VGA_SetBlinking(Bitu enabled) { @@ -169,11 +213,11 @@ static void VGA_VerticalTimer(Bitu val) { vga.config.retrace=false; PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal); PIC_AddEvent(VGA_VerticalDisplayEnd,vga.draw.micro.vend); - vga.draw.parts_left=4; - vga.draw.lines_left=vga.draw.lines_total; + vga.draw.parts_left=vga.draw.parts_total; + vga.draw.lines_done=0; vga.draw.address=vga.config.real_start; vga.draw.address_line=vga.config.hlines_skip; - vga.draw.split_line=vga.draw.lines_total-(vga.config.line_compare/vga.draw.lines_scaled); + vga.draw.split_line=(vga.config.line_compare/vga.draw.lines_scaled); vga.draw.panning=vga.config.pel_panning; switch (vga.mode) { case M_TEXT: @@ -189,7 +233,7 @@ static void VGA_VerticalTimer(Bitu val) { break; } if (RENDER_StartUpdate()) { - VGA_DrawPart(); + PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts,vga.draw.parts_lines); } } @@ -310,7 +354,6 @@ void VGA_SetupDrawing(Bitu val) { Bitu width,height; Bitu scalew=1; Bitu scaleh=1; - width=hdispend; height=vdispend; vga.draw.double_scan=false; @@ -329,7 +372,12 @@ void VGA_SetupDrawing(Bitu val) { vga.draw.lines_scaled=scaleh; vga.draw.address_line_total=1; height/=scaleh;width<<=3; - VGA_DrawLine=VGA_Draw_VGA_Line; + /* Use HW mouse cursor drawer if enabled */ + if(vga.s3.hgc.curmode & 0x1) { + VGA_DrawLine=VGA_Draw_VGA_Line_HWMouse; + } else { + VGA_DrawLine=VGA_Draw_VGA_Line; + } break; case M_EGA16: scaleh*=vga.draw.font_height; @@ -419,6 +467,7 @@ void VGA_SetupDrawing(Bitu val) { }; VGA_CheckScanLength(); vga.draw.lines_total=height; + vga.draw.parts_lines=vga.draw.lines_total/vga.draw.parts_total; if (( width != vga.draw.width) || (height != vga.draw.height)) { PIC_RemoveEvents(VGA_VerticalTimer); PIC_RemoveEvents(VGA_VerticalDisplayEnd); @@ -428,7 +477,7 @@ void VGA_SetupDrawing(Bitu val) { LOG(LOG_VGA,LOG_NORMAL)("Width %d, Height %d, fps %f",width,height,fps); LOG(LOG_VGA,LOG_NORMAL)("Scalew %d, Scaleh %d aspect %f",scalew,scaleh,aspect_ratio); - RENDER_SetSize(width,height,8,aspect_ratio,scalew,scaleh); + RENDER_SetSize(width,height,8,aspect_ratio,scalew>1,scaleh>1); PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal); } }; diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index 1e3415ae..cddd3ea9 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -93,7 +93,7 @@ static void write_p3cf(Bitu port,Bitu val,Bitu iolen) { break; case 5: /* Mode Register */ if ((gfx(mode) ^ val) & 0xf0) { - gfx(mode)=val; + gfx(mode)=val; VGA_DetermineMode(); } else gfx(mode)=val; vga.config.write_mode=val & 3; diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index b26679b8..df8d4b41 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -26,6 +26,9 @@ #include "vga.h" #include "paging.h" #include "pic.h" +#include "inout.h" + +void VGA_MapMMIO(void); static Bitu VGA_NormalReadHandler(PhysPt start) { vga.latch.d=vga.mem.latched[start].d; @@ -233,6 +236,7 @@ public: } }; + class VGA_MAP_PageHandler : public PageHandler { public: VGA_MAP_PageHandler() { @@ -244,6 +248,66 @@ public: } }; +class VGA_MMIO_PageHandler : public PageHandler { +public: + Bit16u regmem[16384]; + + VGA_MMIO_PageHandler() { + flags=PFLAG_NOCODE; + //memset(®mem[0], 0, sizeof(regmem)); + } + void writeb(PhysPt addr,Bitu val) { + Bitu port = addr & 0xffff; + if(port >= 0x82E8) IO_WriteB(port, val); + LOG_MSG("MMIO: Write byte to %x with %x", addr, val); + } + void writew(PhysPt addr,Bitu val) { + Bitu port = addr & 0xffff; + if(port >= 0x82E8) IO_WriteW(port, val); + if(port == 0x8118) IO_WriteW(0x9ae8, val); + if(port <= 0x0020) { + IO_WriteW(0xe2e8, val); + } + + LOG_MSG("MMIO: Write word to %x with %x", addr, val); + } + void writed(PhysPt addr,Bitu val) { + Bitu port = addr & 0xffff; + if(port >= 0x82E8) IO_WriteD(port, val); + if(port == 0x8100) { + IO_WriteW(0x86e8, (val >> 16)); + IO_WriteW(0x82e8, (val & 0xffff)); + } + if(port == 0x8148) { + IO_WriteW(0x96e8, (val >> 16)); + IO_WriteW(0xbee8, (val & 0xffff)); + } + if(port <= 0x0020) { + IO_WriteW(0xe2e8, (val & 0xffff)); + IO_WriteW(0xe2e8, (val >> 16)); + } + + LOG_MSG("MMIO: Write dword to %x with %x", addr, val); + } + + Bitu readb(PhysPt addr) { + LOG_MSG("MMIO: Read byte from %x", addr); + + return 0x00; + } + Bitu readw(PhysPt addr) { + Bitu port = addr & 0xffff; + if(port >= 0x82E8) return IO_ReadW(port); + LOG_MSG("MMIO: Read word from %x", addr); + return 0x00; + } + Bitu readd(PhysPt addr) { + LOG_MSG("MMIO: Read dword from %x", addr); + return 0x00; + } + +}; + class VGA_TANDY_PageHandler : public PageHandler { public: VGA_TANDY_PageHandler() { @@ -262,13 +326,14 @@ public: }; -static struct { +static struct vg { VGA_RAM_PageHandler hram; VGA_MAP_PageHandler hmap; VGA_TEXT_PageHandler htext; VGA_TANDY_PageHandler htandy; VGA_256_PageHandler h256; VGA_16_PageHandler h16; + VGA_MMIO_PageHandler mmio; } vgaph; @@ -338,6 +403,9 @@ range_b800: MEM_SetPageHandler(VGA_PAGE_B0,8,&vgaph.hram); break; } + + if(((vga.s3.ext_mem_ctrl & 0x10) != 0x00) && (vga.mode == M_LIN8)) MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio); + PAGING_ClearTLB(); } @@ -346,6 +414,7 @@ bool lfb_update; static void VGA_DoUpdateLFB(Bitu val) { lfb_update=false; MEM_SetLFB(vga.s3.la_window << 4 ,sizeof(vga.mem.linear)/4096,&vga.mem.linear[0]); + LOG_MSG("LIN: Reconfiguing linear page address"); } void VGA_StartUpdateLFB(void) { @@ -355,6 +424,16 @@ void VGA_StartUpdateLFB(void) { } } +void VGA_MapMMIO(void) { + MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio); + +} + +void VGA_UnmapMMIO(void) { + //MEM_SetPageHandler(VGA_PAGE_A0, &ram_page_handler); +} + + void VGA_SetupMemory() { memset((void *)&vga.mem,0,512*1024*4); } diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp new file mode 100644 index 00000000..6440b500 --- /dev/null +++ b/src/hardware/vga_xga.cpp @@ -0,0 +1,530 @@ +/* + * Copyright (C) 2002-2004 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include "dosbox.h" +#include "inout.h" +#include "vga.h" +#include + +struct XGAStatus { + struct scissorreg { + Bit16u x1, y1, x2, y2; + } scissors; + + Bit32u readmask; + Bit32u writemask; + + Bit32u forecolor; + Bit32u backcolor; + + Bit16u foremix; + + Bit16u curx, cury; + Bit16u destx, desty; + + Bit16u MIPcount; + Bit16u MAPcount; + + Bit16u pix_cntl; + Bit16u read_sel; + + struct XGA_WaitCmd { + bool wait; + Bit16u cmd; + Bit16u curx, cury; + Bit16u x1, y1, x2, y2; + } waitcmd; + +} xga; + +Bit8u tmpvram[2048 * 1024]; + +void XGA_Write_Multifunc(Bitu val, Bitu len) { + Bitu regselect = val >> 12; + Bitu dataval = val & 0xfff; + switch(regselect) { + case 0: + xga.MIPcount = dataval; + break; + case 1: + xga.scissors.y1 = dataval; + break; + case 2: + xga.scissors.x1 = dataval; + break; + case 3: + xga.scissors.y2 = dataval; + break; + case 4: + xga.scissors.x2 = dataval; + break; + case 0xa: + xga.pix_cntl = dataval; + break; + case 0xf: + xga.read_sel = dataval; + break; + default: + LOG_MSG("XGA: Unhandled multifunction command %x", regselect); + break; + } +} + +void XGA_DrawPoint8(Bitu x, Bitu y, Bit8u c) { + Bit32u memaddr = (y * 640) + x; + vga.mem.linear[memaddr] = c; + +} + +Bit8u XGA_GetPoint8(Bitu x, Bitu y) { + Bit32u memaddr = (y * 640) + x; + return vga.mem.linear[memaddr]; + + +} + +void XGA_DrawPoint16(Bitu x, Bitu y, Bit16u c) { + Bit16u *memptr; + Bit32u memaddr = (y * 640) + x; + memptr = (Bit16u *)&vga.mem.linear[memaddr]; + *memptr = c; +} + +void XGA_DrawRectangle(Bitu x1, Bitu y1, Bitu x2, Bitu y2) { + Bit32u xat, yat; + Bit32u xmass, xmod, xdist; + Bit32u *memptr; + Bit8u *smallptr; + Bit32u c; + Bit8u smallc; + + xdist = (x2 -x1); + xmass = (xdist) & 0xfffffffb; + xmod = (xdist) & 0x3; + + smallc = (xga.forecolor & 0xff); + c = (smallc) | ((smallc) << 8) | ((smallc) << 16) | ((smallc) << 24); + + for(yat=y1;yat<=y2;yat++) { + Bit32u memaddr = (yat * (Bit32u)640) + x1; + smallptr = &vga.mem.linear[memaddr]; + for(xat=0;xat xga.waitcmd.x2) { + xga.waitcmd.curx = xga.waitcmd.x1; + xga.waitcmd.cury++; + newline = true; + if(xga.waitcmd.cury > xga.waitcmd.y2) xga.waitcmd.wait = false; + } + return newline; +} + +void XGA_DrawWait(Bitu val, Bitu len) { + if(!xga.waitcmd.wait) return; + Bitu mixmode = (xga.pix_cntl >> 6) & 0x3; + + switch(xga.waitcmd.cmd) { + case 2: /* Rectangle */ + if(mixmode == 0) { /* FOREMIX always used */ + switch(len) { + case 1: + XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, val); + break; + case 2: + XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, (val & 0xff)); + XGA_CheckX(); + XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, (val >> 8)); + break; + case 4: + XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, (val & 0xff)); + XGA_CheckX(); + XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, ((val >> 8) & 0xff)); + XGA_CheckX(); + XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, ((val >> 16) & 0xff)); + XGA_CheckX(); + XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, ((val >> 24) & 0xff)); + break; + } + XGA_CheckX(); + } + if(mixmode == 2) { /* Data from PIX_TRANS selects the mix */ + Bitu bitcount; + int i; + switch(len) { + case 1: + bitcount = 8; + break; + case 2: + bitcount = 16; + val = ((val & 0xff) << 8) | ((val >> 8) & 0xff); + break; + case 4: + bitcount = 32; + break; + } + + + Bits bitneed = ((Bits)xga.waitcmd.x2 - (Bits)xga.waitcmd.x1) + 1; + xga.waitcmd.curx = xga.waitcmd.x1; + i = 15; + for(;bitneed>=0;--bitneed) { + Bitu bitval = (val >> i) & 0x1; + //XGA_DrawPoint8(xga.waitcmd.curx, xga.waitcmd.cury, i); + if(bitval != 0) XGA_DrawPoint8(xga.waitcmd.curx, xga.waitcmd.cury, xga.forecolor); + --i; + xga.waitcmd.curx++; + } + xga.waitcmd.cury++; + + + if(xga.waitcmd.cury > xga.waitcmd.y2) xga.waitcmd.wait = false; + } + break; + default: + LOG_MSG("XGA: Unhandled draw command %x", xga.waitcmd.cmd); + break; + } + +} + +void XGA_BlitRect(Bitu val) { + Bit32u xat, yat; + Bit32u xmass, xmod, xdist, memrec; + Bit8u *srcptr; + Bit8u *destptr; + Bit8u *destline; + Bit8u *srcline; + + Bit32u c; + Bit8u smallc; + Bit8u tmpclr; + bool incx = false; + bool incy = false; + + if((val >> 5) != 0) incx = true; + if((val >> 7) != 0) incy = true; + + xdist = xga.MAPcount; + + smallc = (xga.forecolor & 0xff); + memrec = 0; + Bit32u srcaddr = (xga.cury * (Bit32u)640) + xga.curx; + Bit32u destaddr = (xga.desty * (Bit32u)640) + xga.destx; + + srcptr = &vga.mem.linear[srcaddr]; + destptr = &vga.mem.linear[destaddr]; + + /* Copy source to video ram */ + for(yat=0;yat<=xga.MIPcount ;yat++) { + srcline = srcptr; + destline = destptr; + for(xat=0;xat7) addx=0; + } + addy++; + if(addy>7) addy=0; + } + +} + +void XGA_DrawCmd(Bitu val, Bitu len) { + Bit16u cmd; + cmd = val >> 13; + LOG_MSG("XGA: Draw command %x", cmd); + switch(cmd) { + case 2: /* Rectangle fill */ + if((val & 0x100) == 0) { + xga.waitcmd.wait = false; + XGA_DrawRectangle(xga.curx, xga.cury, xga.curx + xga.MAPcount, xga.cury + xga.MIPcount); + } else { + xga.waitcmd.wait = true; + xga.waitcmd.curx = xga.curx; + xga.waitcmd.cury = xga.cury; + xga.waitcmd.x1 = xga.curx; + xga.waitcmd.y1 = xga.cury; + xga.waitcmd.x2 = xga.curx + xga.MAPcount; + xga.waitcmd.y2 = xga.cury + xga.MIPcount; + xga.waitcmd.cmd = 2; + LOG_MSG("XGA: Draw wait rect (%d, %d)-(%d, %d)", xga.waitcmd.x1, xga.waitcmd.y1, xga.waitcmd.x2, xga.waitcmd.y2); + } + break; + case 6: /* BitBLT */ + XGA_BlitRect(val); + break; + case 7: /* Pattern fill */ + XGA_DrawPattern(); + LOG_MSG("XGA: Pattern fill (%d, %d)-(%d, %d) to (%d, %d)-(%d, %d)", xga.curx, xga.cury, xga.curx + 8, xga.cury + 8, xga.destx, xga.desty, xga.destx + xga.MAPcount, xga.desty + xga.MIPcount); + break; + default: + LOG_MSG("XGA: Unhandled draw command %x", cmd); + break; + + } +} + +void XGA_Write(Bitu port, Bitu val, Bitu len) { + switch(port) { + case 0x96e8: + xga.MAPcount = val; + break; + case 0x9ae8: + XGA_DrawCmd(val, len); + break; + case 0xa2e8: + xga.backcolor = val; + break; + case 0xa6e8: + xga.forecolor = val; + break; + case 0xaae8: + xga.writemask = val; + break; + case 0xaee8: + xga.readmask = val; + break; + case 0x82e8: + xga.cury = val; + break; + case 0x86e8: + xga.curx = val; + break; + case 0x8ae8: + xga.desty = val; + break; + case 0x8ee8: + xga.destx = val; + break; + case 0xbae8: + xga.foremix = val; + break; + case 0xbee8: + XGA_Write_Multifunc(val, len); + break; + case 0xe2e8: + XGA_DrawWait(val, len); + break; + default: + LOG_MSG("XGA: Wrote to port %x with %x, len %x", port, val, len); + break; + } + +} + +Bitu XGA_Read(Bitu port, Bitu len) { + LOG_MSG("XGA: Read from port %x, len %x", port, len); + switch(port) { + case 0x9ae8: + return 0x0; + case 0x9ae9: + if(xga.waitcmd.wait) { + return 0x4; + } else { + return 0x0; + } + case 0xa2e8: + return xga.backcolor; + default: + LOG_MSG("XGA: Read from port %x, len %x", port, len); + return 0x0; + } +} + +void XGA_UpdateHWC(void) { + Bitu mouseaddr = (Bit32u)vga.s3.hgc.startaddr * (Bit32u)1024; + Bits x, y, t, m, xat, r, z; + x = vga.s3.hgc.originx; + y = vga.s3.hgc.originy; + Bit16u bitsA, bitsB; + Bit16u ab, bb; + + /* Read mouse cursor */ + for(t=0;t<64;t++) { + xat = 0; + for(m=0;m<4;m++) { + bitsA = *(Bit16u *)&vga.mem.linear[mouseaddr]; + mouseaddr+=2; + bitsB = *(Bit16u *)&vga.mem.linear[mouseaddr]; + mouseaddr+=2; + z = 7; + for(r=15;r>=0;--r) { + vga.s3.hgc.mc[t][xat] = (((bitsA >> z) & 0x1) << 1) | ((bitsB >> z) & 0x1); + xat++; + --z; + if(z<0) z=15; + } + } + } + +} + +void VGA_SetupXGA(void) { + if (machine!=MCH_VGA) return; + + memset(&xga, 0, sizeof(XGAStatus)); + + IO_RegisterWriteHandler(0x42e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x42e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0x46e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0x4ae8,&XGA_Write,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0x82e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x82e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0x82e9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x82e9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0x86e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x86e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0x86e9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x86e9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0x8ae8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x8ae8,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0x8ee8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x8ee8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0x8ee9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x8ee9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0x92e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x92e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0x92e9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x92e9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0x96e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x96e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0x96e9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x96e9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0x9ae8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x9ae8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0x9ae9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x9ae9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0x9ee8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x9ee8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0x9ee9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x9ee9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xa2e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xa2e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xa6e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xa6e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0xa6e9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xa6e9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xaae8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xaae8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0xaae9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xaae9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xaee8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xaee8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0xaee9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xaee9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xb2e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xb2e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0xb2e9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xb2e9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xb6e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xb6e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xbee8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xbee8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0xbee9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xbee9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xbae8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xbae8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0xbae9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xbae9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xe2e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xe2e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xe2ea,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xe2ea,&XGA_Read,IO_MB | IO_MW | IO_MD); + + + +} + From c94459d6d3f72ded9f00a0255e1a0fde093bb635 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 10 Jun 2004 07:23:01 +0000 Subject: [PATCH 1737/4131] New mapper changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1819 --- include/Makefile.am | 1 + include/keyboard.h | 16 +-- include/mapper.h | 34 +++++ src/debug/debug.cpp | 7 +- src/hardware/keyboard.cpp | 290 ++++++++++++++------------------------ src/hardware/mixer.cpp | 4 +- src/ints/bios_disk.cpp | 14 +- 7 files changed, 155 insertions(+), 211 deletions(-) create mode 100644 include/mapper.h diff --git a/include/Makefile.am b/include/Makefile.am index 83985517..ce2c03c0 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -16,6 +16,7 @@ ipx.h \ ipxserver.h \ keyboard.h \ logging.h \ +mapper.h \ mem.h \ mixer.h \ modules.h \ diff --git a/include/keyboard.h b/include/keyboard.h index 8f7bed4b..dc3574e4 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -20,6 +20,7 @@ #define _KEYBOARD_H_ enum KBD_KEYS { + KBD_NONE, KBD_1, KBD_2, KBD_3, KBD_4, KBD_5, KBD_6, KBD_7, KBD_8, KBD_9, KBD_0, KBD_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, @@ -39,21 +40,12 @@ enum KBD_KEYS { 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_kpslash,KBD_kpmultiply,KBD_kpminus,KBD_kpplus,KBD_kpenter,KBD_kpperiod, + KBD_kpdivide,KBD_kpmultiply,KBD_kpminus,KBD_kpplus,KBD_kpenter,KBD_kpperiod, + KBD_LAST }; -typedef void(KEYBOARD_EventHandler)(void); - -void KEYBOARD_AddEvent(Bitu keytype,Bitu state,KEYBOARD_EventHandler * handler); -void KEYBOARD_AddKey(KBD_KEYS key,Bitu ascii,Bitu mod,bool pressed); -void KEYBOARD_ReadKey(Bitu & scancode,Bitu & ascii,Bitu & mod); - - -#define KBD_MOD_ALT 0x1 -#define KBD_MOD_CTRL 0x2 -#define KBD_MOD_SHIFT 0x4 - +void KEYBOARD_AddKey(KBD_KEYS keytype,bool pressed); #endif diff --git a/include/mapper.h b/include/mapper.h new file mode 100644 index 00000000..24951ec4 --- /dev/null +++ b/include/mapper.h @@ -0,0 +1,34 @@ + /* + * Copyright (C) 2002-2004 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef MAPPER_H_ +#define MAPPER_H_ + +enum MapKeys { + MK_f1,MK_f2,MK_f3,MK_f4,MK_f5,MK_f6,MK_f7,MK_f8,MK_f9,MK_f10,MK_f11,MK_f12, + MK_return,MK_kpminus, + +}; + +typedef void (MAPPER_Handler)(void); +void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char * eventname,char * buttonname); + +#define MMOD1 0x1 +#define MMOD2 0x2 + +#endif diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 5b251c03..21e18ea3 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.53 2004-04-24 09:20:11 harekiet Exp $ */ +/* $Id: debug.cpp,v 1.54 2004-06-10 07:23:01 harekiet Exp $ */ #include "programs.h" @@ -29,7 +29,7 @@ #include "cpu.h" #include "video.h" #include "pic.h" -#include "keyboard.h" +#include "mapper.h" #include "cpu.h" #include "callback.h" #include "inout.h" @@ -1672,8 +1672,7 @@ void DEBUG_Init(Section* sec) { MSG_Add("DEBUG_CONFIGFILE_HELP","Nothing to setup yet!\n"); DEBUG_DrawScreen(); /* Add some keyhandlers */ - KEYBOARD_AddEvent(KBD_kpminus,0,DEBUG_Enable); - KEYBOARD_AddEvent(KBD_kpplus,0,DEBUG_RaiseTimerIrq); + MAPPER_AddHandler(DEBUG_Enable,MK_kpminus,0,"debugger","Debugger"); /* Clear the TBreakpoint list */ memset((void*)&codeViewData,0,sizeof(codeViewData)); /* setup debug.com */ diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 0e919b55..15f7b86e 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -16,9 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.23 2004-04-07 09:36:59 qbix79 Exp $ */ +/* $Id: keyboard.cpp,v 1.24 2004-06-10 07:19:46 harekiet Exp $ */ #include +#include +#include + #include "dosbox.h" #include "keyboard.h" #include "inout.h" @@ -27,7 +30,7 @@ #include "mixer.h" #define KEYBUFSIZE 32 -#define KEYDELAY 150 +#define KEYDELAY 300 //Considering 20-30 khz serial clock and 11 bits/char enum KeyCommands { CMD_NONE, @@ -36,189 +39,131 @@ enum KeyCommands { CMD_SETOUTPORT }; -enum KeyStates { - STATE_NORMAL, - STATE_EXTEND, -}; - -struct KeyCode { - Bit8u scancode; - Bit8u ascii; - KeyStates state; - Bitu mod; -}; - -struct KeyEvent { - Bits type; - Bitu state; - KEYBOARD_EventHandler * handler; - KeyEvent * next; -}; - -struct KeyBlock { +static struct { + Bit8u buffer[KEYBUFSIZE]; + Bitu used; + Bitu pos; struct { - KeyCode code[KEYBUFSIZE]; - Bitu used; - Bitu pos; - KeyStates state; - } buf; - Bitu write_state; - Bit64u last_index; + KBD_KEYS key; + Bitu wait; + Bitu pause,rate; + } repeat; KeyCommands command; - bool enabled; + Bit8u p60data; + bool p60changed; bool active; + bool scanning; bool scheduled; - bool key_on_60; -}; +} keyb; -static KeyBlock keyb; -static Bit8u cur_scancode; -static Bit8u port_61_data; -//TODO Are these initialized at 0 at startup? Hope so :) -static KeyEvent * event_handlers[KBD_LAST]; - -void KEYBOARD_ClrBuffer(void) { - keyb.buf.used=0; - keyb.buf.pos=0; - keyb.scheduled=false; - PIC_DeActivateIRQ(1); - keyb.key_on_60=false; -/* maybe remove PIC_EVENTS */ +static void KEYBOARD_SetPort60(Bit8u val) { + keyb.p60changed=true; + keyb.p60data=val; + PIC_ActivateIRQ(1); } -/* Read an entry from the keycode buffer */ -void KEYBOARD_GetCode(Bitu val) { +static void KEYBOARD_TransferBuffer(Bitu val) { keyb.scheduled=false; - switch (keyb.buf.state) { - case STATE_NORMAL: - /* Check for a next key */ - if (!keyb.buf.used) return; - keyb.buf.used--; - keyb.buf.pos++; - if (keyb.buf.pos>=KEYBUFSIZE) keyb.buf.pos-=KEYBUFSIZE; - keyb.buf.state=keyb.buf.code[keyb.buf.pos].state; - break; - case STATE_EXTEND: - keyb.buf.state=STATE_NORMAL; - break; + if (!keyb.used) { + LOG(LOG_KEYBOARD,LOG_NORMAL)("Transfer started with empty buffer"); + return; } - keyb.key_on_60=true; - if (keyb.enabled) PIC_ActivateIRQ(1); + Bit8u data=keyb.buffer[keyb.pos]; + KEYBOARD_SetPort60(keyb.buffer[keyb.pos]); + if (++keyb.pos>=KEYBUFSIZE) keyb.pos-=KEYBUFSIZE; + keyb.used--; } -void KEYBOARD_AddCode(Bit8u scancode,Bit8u ascii,Bitu mod,KeyStates state) { -// LOG_MSG("Add key scan %d ascii %c",scancode,ascii); - if (keyb.buf.used=KEYBUFSIZE) start-=KEYBUFSIZE; - keyb.buf.code[start].scancode=scancode; - keyb.buf.code[start].ascii=ascii; - keyb.buf.code[start].state=state; - keyb.buf.code[start].mod=mod; + +static void KEYBOARD_ClrBuffer(void) { + keyb.used=0; + keyb.pos=0; + PIC_RemoveEvents(KEYBOARD_TransferBuffer); + keyb.scheduled=false; +} + +static void KEYBOARD_AddBuffer(Bit8u data) { + if (keyb.used>=KEYBUFSIZE) { + LOG(LOG_KEYBOARD,LOG_NORMAL)("Buffer full, dropping code"); + return; } + Bitu start=keyb.pos+keyb.used; + if (start>=KEYBUFSIZE) start-=KEYBUFSIZE; + keyb.buffer[start]=data; + keyb.used++; /* Start up an event to start the first IRQ */ - if (!keyb.scheduled && !keyb.key_on_60) { + if (!keyb.scheduled && !keyb.p60changed) { keyb.scheduled=true; - PIC_AddEvent(KEYBOARD_GetCode,KEYDELAY); + PIC_AddEvent(KEYBOARD_TransferBuffer,KEYDELAY); } } -/* Disabled as it's not used anymore. Left in here incase new code fails -void KEYBOARD_ReadKey(Bitu & scancode,Bitu & ascii,Bitu & mod) { - keyb.key_on_60=false; //else no new keys get scheduled :) - switch (keyb.buf.state) { - case STATE_NORMAL: - if (keyb.buf.used && !keyb.scheduled) { - keyb.scheduled=true; - PIC_AddEvent(KEYBOARD_GetCode,KEYDELAY); - } - scancode=keyb.buf.code[keyb.buf.pos].scancode; - ascii=keyb.buf.code[keyb.buf.pos].ascii; - mod=keyb.buf.code[keyb.buf.pos].mod; - break; - case STATE_EXTEND: - scancode=224; - mod=0; - ascii=0; - if (!keyb.scheduled) { - keyb.scheduled=true; - PIC_AddEvent(KEYBOARD_GetCode,KEYDELAY); - } - break; - } -} -*/ + static Bitu read_p60(Bitu port,Bitu iolen) { - keyb.key_on_60 = false; - switch (keyb.buf.state) { - case STATE_NORMAL: - if (keyb.buf.used && !keyb.scheduled) { //key60 is false - keyb.scheduled=true; - PIC_AddEvent(KEYBOARD_GetCode,KEYDELAY); - } - - return keyb.buf.code[keyb.buf.pos].scancode; - case STATE_EXTEND: - if (!keyb.scheduled) { - keyb.scheduled=true; - PIC_AddEvent(KEYBOARD_GetCode,KEYDELAY); - } - - return 224; + keyb.p60changed=false; + if (!keyb.scheduled && keyb.used) { + keyb.scheduled=true; + PIC_AddEvent(KEYBOARD_TransferBuffer,KEYDELAY); } - return 0; + return keyb.p60data; } static void write_p60(Bitu port,Bitu val,Bitu iolen) { + LOG_MSG("write port 60 %x",val); switch (keyb.command) { case CMD_NONE: /* None */ + /* No active command this would normally get sent to the keyboard then */ KEYBOARD_ClrBuffer(); switch (val) { case 0xed: /* Set Leds */ keyb.command=CMD_SETLEDS; - KEYBOARD_AddCode(0xfa,0,0,STATE_NORMAL); /* Acknowledge */ + KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ break; case 0xee: /* Echo */ - KEYBOARD_AddCode(0xee,0,0,STATE_NORMAL); + KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ break; case 0xf2: /* Identify keyboard */ /* AT's just send acknowledge */ - KEYBOARD_AddCode(0xfa,0,0,STATE_NORMAL); /* Acknowledge */ + KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ break; case 0xf3: /* Typematic rate programming */ keyb.command=CMD_SETTYPERATE; - KEYBOARD_AddCode(0xfa,0,0,STATE_NORMAL); /* Acknowledge */ + KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ break; case 0xf4: /* Enable keyboard,clear buffer, start scanning */ - keyb.active=true; - KEYBOARD_ClrBuffer(); - LOG(LOG_KEYBOARD,LOG_NORMAL)("Activated port 60"); - KEYBOARD_AddCode(0xfa,0,0,STATE_NORMAL); /* Acknowledge */ + LOG(LOG_KEYBOARD,LOG_NORMAL)("Clear buffer,enable Scaning"); + KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ + keyb.scanning=true; break; case 0xf5: /* Reset keyboard and disable scanning */ + LOG(LOG_KEYBOARD,LOG_NORMAL)("Reset, disable scanning"); + keyb.scanning=false; + KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ + break; case 0xf6: /* Reset keyboard and enable scanning */ - LOG(LOG_KEYBOARD,LOG_NORMAL)("Reset"); - KEYBOARD_AddCode(0xfa,0,0,STATE_NORMAL); /* Acknowledge */ + LOG(LOG_KEYBOARD,LOG_NORMAL)("Reset, enable scanning"); + KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ + keyb.scanning=false; break; default: /* Just always acknowledge strange commands */ LOG(LOG_KEYBOARD,LOG_ERROR)("60:Unhandled command %X",val); - KEYBOARD_AddCode(0xfa,0,0,STATE_NORMAL); /* Acknowledge */ + KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ } return; case CMD_SETOUTPORT: MEM_A20_Enable((val & 2)>0); break; - case CMD_SETTYPERATE: case CMD_SETLEDS: keyb.command=CMD_NONE; - KEYBOARD_AddCode(0xfa,0,0,STATE_NORMAL); /* Acknowledge */ + KEYBOARD_ClrBuffer(); + KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ break; } } +static Bit8u port_61_data; static Bitu read_p61(Bitu port,Bitu iolen) { port_61_data^=0x20; port_61_data^=0x10; @@ -226,12 +171,7 @@ static Bitu read_p61(Bitu port,Bitu iolen) { } static void write_p61(Bitu port,Bitu val,Bitu iolen) { -/* - if (val & 128) if (!keyb.read_active) KEYBOARD_ReadBuffer(); - Keys should get acknowledged just by reading 0x60. - Perhaps disable controller when bit 7=1 -*/ - if ((port_61_data ^val) & 3) PCSPEAKER_SetType(val & 3); + if ((port_61_data ^ val) & 3) PCSPEAKER_SetType(val & 3); port_61_data=val; } @@ -239,21 +179,18 @@ static void write_p64(Bitu port,Bitu val,Bitu iolen) { switch (val) { case 0xae: /* Activate keyboard */ keyb.active=true; - if (keyb.buf.used && !keyb.scheduled && !keyb.key_on_60) { + if (keyb.used && !keyb.scheduled && !keyb.p60changed) { keyb.scheduled=true; - PIC_AddEvent(KEYBOARD_GetCode,KEYDELAY); + PIC_AddEvent(KEYBOARD_TransferBuffer,KEYDELAY); } - LOG(LOG_KEYBOARD,LOG_NORMAL)("Activated port 64"); + LOG(LOG_KEYBOARD,LOG_NORMAL)("Activated"); break; case 0xad: /* Deactivate keyboard */ keyb.active=false; - PIC_DeActivateIRQ(1); - PIC_RemoveEvents(KEYBOARD_GetCode); - keyb.scheduled=false; LOG(LOG_KEYBOARD,LOG_NORMAL)("De-Activated"); break; case 0xd0: /* Outport on buffer */ - KEYBOARD_AddCode(MEM_A20_Enabled() ? 0x02 : 0,0,0,STATE_NORMAL); + KEYBOARD_SetPort60(MEM_A20_Enabled() ? 0x02 : 0); break; case 0xd1: /* Write to outport */ keyb.command=CMD_SETOUTPORT; @@ -265,28 +202,11 @@ static void write_p64(Bitu port,Bitu val,Bitu iolen) { } static Bitu read_p64(Bitu port,Bitu iolen) { -// Bit8u status= 0x1c | ((keyb.buf.used ||keyb.key_on_60)? 0x1 : 0x0); -// Old one. Digitracker 2 doesn't like this. key_on_60 is much more advanged. - Bit8u status= 0x1c | (keyb.key_on_60? 0x1 : 0x0); - keyb.key_on_60=false; + Bit8u status= 0x1c | (keyb.p60changed? 0x1 : 0x0); return status; } -void KEYBOARD_AddEvent(Bitu keytype,Bitu state,KEYBOARD_EventHandler * handler) { - KeyEvent * newevent=new KeyEvent; -/* Add the event in the correct key structure */ - if (keytype>=KBD_LAST) { - LOG(LOG_KEYBOARD,LOG_ERROR)("Illegal key %d for handler",keytype); - } - newevent->next=event_handlers[keytype]; - event_handlers[keytype]=newevent; - newevent->type=keytype; - newevent->state=state; - newevent->handler=handler; -} - - -void KEYBOARD_AddKey(KBD_KEYS keytype,Bitu unicode,Bitu mod,bool pressed) { +void KEYBOARD_AddKey(KBD_KEYS keytype,bool pressed) { Bit8u ret=0;bool extend=false; switch (keytype) { case KBD_esc:ret=1;break; @@ -389,7 +309,7 @@ void KEYBOARD_AddKey(KBD_KEYS keytype,Bitu unicode,Bitu mod,bool pressed) { case KBD_kpenter:extend=true;ret=28;break; case KBD_rightctrl:extend=true;ret=29;break; - case KBD_kpslash:extend=true;ret=53;break; + case KBD_kpdivide:extend=true;ret=53;break; case KBD_rightalt:extend=true;ret=56;break; case KBD_home:extend=true;ret=71;break; case KBD_up:extend=true;ret=72;break; @@ -405,21 +325,25 @@ void KEYBOARD_AddKey(KBD_KEYS keytype,Bitu unicode,Bitu mod,bool pressed) { E_Exit("Unsupported key press"); break; } - /* check for active key events */ - KeyEvent * checkevent=event_handlers[keytype]; - while (checkevent) { - if ((mod & checkevent->state)==checkevent->state) { - if (checkevent->type==keytype && pressed) { - (*checkevent->handler)(); - return; - } - if (checkevent->type==keytype) return; - } - checkevent=checkevent->next; - } /* Add the actual key in the keyboard queue */ - if (!pressed) ret+=128; - KEYBOARD_AddCode(ret,(Bit8u)unicode,mod,extend ? STATE_EXTEND : STATE_NORMAL); + if (pressed) { + if (keyb.repeat.key==keytype) keyb.repeat.wait=keyb.repeat.rate; + else keyb.repeat.wait=keyb.repeat.pause; + keyb.repeat.key=keytype; + } else { + keyb.repeat.key=KBD_NONE; + keyb.repeat.wait=0; + ret+=128; + } + if (extend) KEYBOARD_AddBuffer(0xe0); + KEYBOARD_AddBuffer(ret); +} + +static void KEYBOARD_TickHandler(void) { + if (keyb.repeat.wait) { + keyb.repeat.wait--; + if (!keyb.repeat.wait) KEYBOARD_AddKey(keyb.repeat.key,true); + } } void KEYBOARD_Init(Section* sec) { @@ -429,14 +353,16 @@ void KEYBOARD_Init(Section* sec) { IO_RegisterReadHandler(0x61,read_p61,IO_MB); IO_RegisterWriteHandler(0x64,write_p64,IO_MB); IO_RegisterReadHandler(0x64,read_p64,IO_MB); - - port_61_data=0; /* Direct Speaker control and output disabled */ -// memset(&event_handlers,0,sizeof(event_handlers)); - /* Clear the keyb struct */ + TIMER_AddTickHandler(&KEYBOARD_TickHandler); + write_p61(0,0,0); + /* Init the keyb struct */ keyb.active=true; - keyb.enabled=true; + keyb.scanning=true; keyb.command=CMD_NONE; - keyb.last_index=0; - keyb.key_on_60=false; + keyb.p60changed=false; + keyb.repeat.key=KBD_NONE; + keyb.repeat.pause=500; + keyb.repeat.rate=33; + keyb.repeat.wait=0; KEYBOARD_ClrBuffer(); } diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 16a3e954..421be8d7 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -34,7 +34,7 @@ #include "setup.h" #include "cross.h" #include "support.h" -#include "keyboard.h" +#include "mapper.h" #include "programs.h" #define MIXER_MAXCHAN 8 @@ -423,6 +423,6 @@ void MIXER_Init(Section* sec) { TIMER_AddTickHandler(MIXER_Mix); SDL_PauseAudio(0); } - KEYBOARD_AddEvent(KBD_f6,KBD_MOD_CTRL,MIXER_WaveEvent); + MAPPER_AddHandler(MIXER_WaveEvent,MK_f6,MMOD1,"recwave","Rec Wave"); PROGRAMS_MakeFile("MIXER.COM",MIXER_ProgramStart); } diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index dfed6e05..6327227e 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -21,8 +21,8 @@ #include "bios.h" #include "regs.h" #include "mem.h" -#include "keyboard.h" #include "dos_inc.h" /* for Drives[] */ +#include "mapper.h" #define MAX_SWAPPABLE_DISKS 20 @@ -67,9 +67,6 @@ void updateDPT(void) { real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0xb,0); real_writew(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0xc,tmpcyl); real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0xe,tmpsect); - - - } if(imageDiskList[3] != NULL) { imageDiskList[3]->Get_Geometry(&tmpheads, &tmpcyl, &tmpsect, &tmpsize); @@ -77,8 +74,6 @@ void updateDPT(void) { real_writeb(RealSeg(CALLBACK_RealPointer(diskparm1)),RealOff(CALLBACK_RealPointer(diskparm1))+2,tmpheads); real_writeb(RealSeg(CALLBACK_RealPointer(diskparm1)),RealOff(CALLBACK_RealPointer(diskparm1))+0xe,tmpsect); } - - } void swapInDisks(void) { @@ -436,10 +431,7 @@ void BIOS_SetupDisks(void) { /* Setup the Bios Area */ mem_writeb(BIOS_HARDDISK_COUNT,2); - KEYBOARD_AddEvent(KBD_f4,KBD_MOD_CTRL, swapInNextDisk); - + MAPPER_AddHandler(swapInNextDisk,MK_f4,MMOD1,"swapimg","Swap Image"); killRead = false; - - -}; +} From b7fb90dbd59e9e25aace2d46373cff0468498c6f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 10 Jun 2004 08:48:53 +0000 Subject: [PATCH 1738/4131] Added double byte stuff the proper way (empty table) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1820 --- include/dos_inc.h | 3 ++- src/dos/dos.cpp | 11 +++++++++-- src/dos/dos_tables.cpp | 8 ++++++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 579471d5..fed50e6d 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.44 2004-05-15 07:57:02 harekiet Exp $ */ +/* $Id: dos_inc.h,v 1.45 2004-06-10 08:48:53 qbix79 Exp $ */ #ifndef DOS_H_ #define DOS_H_ @@ -563,6 +563,7 @@ struct DOS_Block { struct { RealPt mediaid; RealPt tempdta; + RealPt dcbs; } tables; }; diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 3a9928f9..eab79ba4 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.71 2004-05-04 18:34:07 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.72 2004-06-10 08:48:53 qbix79 Exp $ */ #include #include @@ -801,6 +801,14 @@ static Bitu DOS_21Handler(void) { case 0x62: /* Get Current PSP Address */ reg_bx=dos.psp(); break; + case 0x63: /* DOUBLE BYTE CHARACTER SET */ + if(reg_al == 0) { + SegSet16(ds,RealSeg(dos.tables.dcbs)); + reg_si=RealOff(dos.tables.dcbs); + reg_al = 0; + CALLBACK_SCF(false); //undocumented + } else reg_al = 0xff; //Doesn't officially touch carry flag + break; case 0x64: /* Set device driver lookahead flag */ E_Exit("Unhandled Dos 21 call %02X",reg_ah); break; @@ -895,7 +903,6 @@ static Bitu DOS_21Handler(void) { break; case 0x68: /* FFLUSH Commit file */ - case 0x63: /* Weirdo double byte stuff (fails but say it succeeded) available only in MSDOS 2.25 */ CALLBACK_SCF(false); //mirek case 0xE0: case 0x18: /* NULL Function for CP/M compatibility or Extended rename FCB */ diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index d54c3139..e45fa3f3 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.10 2004-05-04 18:34:08 qbix79 Exp $ */ +/* $Id: dos_tables.cpp,v 1.11 2004-06-10 08:48:53 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -78,9 +78,13 @@ void DOS_SetupTables(void) { //CON string real_writew(0x54,0x20+0x00, (Bit16u) 0x4f43); real_writew(0x54,0x20+0x02, (Bit16u) 0x204e); + + /* Allocate DCBS DOUBLE BYTE CHARACTER SET LEAD-BYTE TABLE */ + dos.tables.dcbs=RealMake(DOS_GetMemory(3),0); + mem_writew(Real2Phys(dos.tables.dcbs),0); //empty table + /* Allocate some fake memory else pharlab doesn't like the indos pointer */ sdaseg=DOS_GetMemory(12); - sdaseg=DOS_GetMemory(3); DOS_SDA(sdaseg,0).Init(); } From 56de26f7df6b98ff7ceb92393c3552a9f55f06d8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 10 Jun 2004 17:57:42 +0000 Subject: [PATCH 1739/4131] Handle terminal count event to prevent repeated loop Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1821 --- src/hardware/sblaster.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 5ffae9a8..c585a571 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -234,6 +234,7 @@ static void DSP_StopDMA(void) { } static void DSP_DMA_CallBack(DmaChannel * chan, DMAEvent event) { + if (event==DMA_REACHED_TC) return; if (event==DMA_MASKED) sb.dma.active=false; if (event==DMA_UNMASKED) sb.dma.active=true; if (sb.mode==MODE_DMA_WAIT && sb.dma.active) { From 0cfdcda3b1db19a25fca728cd5e4342bc4ebb264 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 10 Jun 2004 19:31:20 +0000 Subject: [PATCH 1740/4131] Added a missing break. Saves lot's of debug messages :) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1822 --- src/fpu/fpu.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 169c61ad..8898c2fd 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu.cpp,v 1.19 2004-04-01 08:57:33 qbix79 Exp $ */ +/* $Id: fpu.cpp,v 1.20 2004-06-10 19:31:20 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU @@ -423,6 +423,7 @@ void FPU_ESC2_Normal(Bitu rm) { 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; From c6b9969e8aae09ccd4b88c1b3a92fc394a1f7efd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 10 Jun 2004 20:21:05 +0000 Subject: [PATCH 1741/4131] Add new dma ransferend event Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1823 --- include/dma.h | 3 ++- src/hardware/dma.cpp | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/dma.h b/include/dma.h index 8e8328c3..46bd5524 100644 --- a/include/dma.h +++ b/include/dma.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dma.h,v 1.10 2004-03-15 14:53:32 harekiet Exp $ */ +/* $Id: dma.h,v 1.11 2004-06-10 20:20:28 harekiet Exp $ */ #ifndef __DMA_H #define __DMA_H @@ -25,6 +25,7 @@ enum DMAEvent { DMA_REACHED_TC, DMA_MASKED, DMA_UNMASKED, + DMA_TRANSFEREND }; class DmaChannel; diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 306457be..8eb17442 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -189,7 +189,7 @@ again: buffer+=left << DMA16; want-=left; done+=left; - ReachedTC(); +// ReachedTC(); //No module uses it so disable if (autoinit) { currcnt=basecnt; curraddr=baseaddr; @@ -197,7 +197,8 @@ again: } else { curraddr+=left; currcnt=0xffff; - SetMask(true); + masked=true; + DoCallBack(DMA_TRANSFEREND); } } return done; @@ -224,7 +225,8 @@ again: } else { curraddr+=left; currcnt=0xffff; - SetMask(true); + masked=true; + DoCallBack(DMA_TRANSFEREND); } } return done; From 08003231f98ca2a5d6a8d9a6e0211d773d67e90d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 10 Jun 2004 20:22:31 +0000 Subject: [PATCH 1742/4131] Add new dma transferend event Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1824 --- src/hardware/sblaster.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index c585a571..fb399522 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -75,7 +75,7 @@ enum { struct SB_INFO { Bit16u freq; struct { - bool active,stereo,filtered,sign,autoinit; + bool stereo,filtered,sign,autoinit; bool stereoremain; DMA_MODES mode; Bitu previous; @@ -235,19 +235,19 @@ static void DSP_StopDMA(void) { static void DSP_DMA_CallBack(DmaChannel * chan, DMAEvent event) { if (event==DMA_REACHED_TC) return; - if (event==DMA_MASKED) sb.dma.active=false; - if (event==DMA_UNMASKED) sb.dma.active=true; - if (sb.mode==MODE_DMA_WAIT && sb.dma.active) { - LOG(LOG_SB,LOG_NORMAL)("DMA Activated,starting output"); -// LOG_MSG("DMA Size %x base %x Addr %x",chan->currcnt,chan->pagebase,chan->curraddr); - DSP_ChangeMode(MODE_DMA); - CheckDMAEnd(); - return; - } - if (sb.mode==MODE_DMA && !sb.dma.active) { - DSP_ChangeMode(MODE_DMA_WAIT); - LOG(LOG_SB,LOG_NORMAL)("DMA deactivated,stopping output"); - return; + else if (event==DMA_MASKED) { + if (sb.mode==MODE_DMA) { + DSP_ChangeMode(MODE_DMA_WAIT); + LOG(LOG_SB,LOG_NORMAL)("DMA deactivated,stopping output"); + } + } else if (event==DMA_UNMASKED) { + if (sb.mode==MODE_DMA_WAIT) { + DSP_ChangeMode(MODE_DMA); + CheckDMAEnd(); + LOG(LOG_SB,LOG_NORMAL)("DMA Activated,starting output"); + } else if (event==DMA_TRANSFEREND) { + if (sb.mode==MODE_DMA) sb.mode=MODE_DMA_WAIT; + } } } From 50a0f440b7b812f0e957e06db858e64d5e6a924f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 10 Jun 2004 20:23:50 +0000 Subject: [PATCH 1743/4131] Fix setting vesa modes to ignore the higher bits Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1825 --- src/ints/int10_vesa.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 64c9c13b..6898cbc4 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.8 2004-02-29 22:18:24 harekiet Exp $ */ +/* $Id: int10_vesa.cpp,v 1.9 2004-06-10 20:23:50 harekiet Exp $ */ #include #include @@ -161,7 +161,7 @@ foundit: Bit8u VESA_SetSVGAMode(Bit16u mode) { - if (INT10_SetVideoMode(mode)) return 0x00; + if (INT10_SetVideoMode(mode & 0xfff)) return 0x00; return 0x01; }; From ad89c1c4deb60fbf4f4bf470cf57883264998d2e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 10 Jun 2004 20:24:14 +0000 Subject: [PATCH 1744/4131] Fix vesa subfunction 06 from getting the wrong subfunction Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1826 --- src/ints/int10.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 2c362415..94284d9d 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -342,7 +342,7 @@ graphics_chars: break; case 0x06: reg_al=0x4f; - reg_ah=VESA_ScanLineLength(reg_al,reg_bx,reg_cx,reg_dx); + reg_ah=VESA_ScanLineLength(reg_bl,reg_bx,reg_cx,reg_dx); break; case 0x07: switch (reg_bl) { From 99f8e7208aae1032fbe4023a7791cfdec49c0457 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 11 Jun 2004 11:05:55 +0000 Subject: [PATCH 1745/4131] Fixed a typo (mod2 =>mod3). added right-alt as alt modifier. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1827 --- src/gui/sdl_mapper.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 92bc9eda..c5204be3 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -141,7 +141,7 @@ public: while (*(word=StripWord(buf))) { if (!strcasecmp(word,"mod1")) mods|=BMOD_Mod1; if (!strcasecmp(word,"mod2")) mods|=BMOD_Mod2; - if (!strcasecmp(word,"mod3")) mods|=BMOD_Mod2; + if (!strcasecmp(word,"mod3")) mods|=BMOD_Mod3; if (!strcasecmp(word,"hold")) flags|=BFLG_Hold; } } @@ -1062,6 +1062,7 @@ static void CreateDefaultBinds(void) { } sprintf(buffer,"mod_1 \"key %d\"",SDLK_RCTRL);CreateStringBind(buffer); sprintf(buffer,"mod_1 \"key %d\"",SDLK_LCTRL);CreateStringBind(buffer); + sprintf(buffer,"mod_2 \"key %d\"",SDLK_RALT);CreateStringBind(buffer); sprintf(buffer,"mod_2 \"key %d\"",SDLK_LALT);CreateStringBind(buffer); for (CHandlerEventVector_it hit=handlergroup.begin();hit!=handlergroup.end();hit++) { (*hit)->MakeDefaultBind(buffer); From 8643400dc4b332e20330b84b158aa3bfc19ab117 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 11 Jun 2004 11:50:32 +0000 Subject: [PATCH 1746/4131] Remove language file from commandline if found, so that other commands will work Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1828 --- src/misc/messages.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index fc9d6ba2..9e61ef9a 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -130,7 +130,7 @@ void MSG_Write(const char * location) { void MSG_Init(Section_prop * section) { std::string file_name; - if (control->cmdline->FindString("-lang",file_name)) { + if (control->cmdline->FindString("-lang",file_name,true)) { LoadMessageFile(file_name.c_str()); } else LoadMessageFile(section->Get_string("language")); } From 0d72ebd7f61eb31eceea4d230e90e29d3a8fc940 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 11 Jun 2004 12:09:50 +0000 Subject: [PATCH 1747/4131] Switched fake memory allocation. Makes pharlab happy again Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1829 --- src/dos/dos_tables.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index e45fa3f3..d3f55ff8 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.11 2004-06-10 08:48:53 qbix79 Exp $ */ +/* $Id: dos_tables.cpp,v 1.12 2004-06-11 12:09:50 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -79,12 +79,12 @@ void DOS_SetupTables(void) { real_writew(0x54,0x20+0x00, (Bit16u) 0x4f43); real_writew(0x54,0x20+0x02, (Bit16u) 0x204e); - /* Allocate DCBS DOUBLE BYTE CHARACTER SET LEAD-BYTE TABLE */ - dos.tables.dcbs=RealMake(DOS_GetMemory(3),0); - mem_writew(Real2Phys(dos.tables.dcbs),0); //empty table - /* Allocate some fake memory else pharlab doesn't like the indos pointer */ - sdaseg=DOS_GetMemory(12); + /* Pharlab seems to real picky. So don't change this unless needed (the amount of allocated memory that is) */ + /* Allocate DCBS DOUBLE BYTE CHARACTER SET LEAD-BYTE TABLE */ + dos.tables.dcbs=RealMake(DOS_GetMemory(12),0); + mem_writew(Real2Phys(dos.tables.dcbs),0); //empty table + sdaseg=DOS_GetMemory(3); DOS_SDA(sdaseg,0).Init(); } From 01c317b35593abc4c7de3ed98025fc929b3dc0c0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 11 Jun 2004 16:18:42 +0000 Subject: [PATCH 1748/4131] Add 2nd font table support to text output Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1830 --- include/vga.h | 3 +-- src/hardware/vga_draw.cpp | 9 +++++---- src/hardware/vga_seq.cpp | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/vga.h b/include/vga.h index f2b19b9d..e2504997 100644 --- a/include/vga.h +++ b/include/vga.h @@ -121,8 +121,7 @@ typedef struct { bool double_scan_active; Bit8u font_height; Bit8u font[64*1024]; - Bitu font1_start; - Bitu font2_start; + Bit8u * font_tables[2]; Bitu blinking; struct { Bit8u sline,eline; diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 8d1c9036..19cb9cce 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -133,19 +133,20 @@ static Bit8u * VGA_Draw_VGA_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) + + static Bit32u FontMask[2]={0xffffffff,0x0}; static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { Bit32u * draw=(Bit32u *)TempLine; Bit8u * vidmem=&vga.mem.linear[vidstart]; for (Bitu cx=0;cx>4]; - Bit32u mask2=TXT_Font_Table[font&0xf]; Bitu col=vidmem[cx*2+1]; + Bitu font=vga.draw.font_tables[(col >> 3)&1][chr*32+line]; + Bit32u mask1=TXT_Font_Table[font>>4] & FontMask[col >> 7]; + Bit32u mask2=TXT_Font_Table[font&0xf] & FontMask[col >> 7]; Bit32u fg=TXT_FG_Table[col&0xf]; Bit32u bg=TXT_BG_Table[col>>4]; - mask1&=FontMask[col >> 7];mask2&=FontMask[col >> 7]; *draw++=fg&mask1 | bg&~mask1; *draw++=fg&mask2 | bg&~mask2; } diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index c8e5f0b2..ab35b6c2 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -69,10 +69,10 @@ void write_p3c5(Bitu port,Bitu val,Bitu iolen) { case 3: /* Character Map Select */ { seq(character_map_select)=val; - Bit8u font1=(val & 0x3) | ((val & 0x10) >> 2); - vga.draw.font1_start=((font1&3) * 16*1024) + ((font1 > 4) ? (8*1024) : 0); - Bit8u font2=((val & 0xc) >> 2) | ((val & 0x20) >> 3); - vga.draw.font2_start=((font2&3) * 16*1024) + ((font2 > 4) ? (8*1024) : 0); + Bit8u font1=((val & 0x3) << 1) | ((val & 0x10) >> 4); + vga.draw.font_tables[0]=&vga.draw.font[font1*8*1024]; + Bit8u font2=((val & 0xc) >> 1) | ((val & 0x20) >> 5); + vga.draw.font_tables[1]=&vga.draw.font[font2*8*1024]; } /* 0,1,4 Selects VGA Character Map (0..7) if bit 3 of the character From 2743aca6104943bae37fc4075861c7f572e770e4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 13 Jun 2004 12:10:08 +0000 Subject: [PATCH 1749/4131] Fixed problems with mouse locked and switching to mapper. Added and exit button Changed the way the mapper behaves if you want to add a new bind to a key. Now it clears the screen so it's more clear that you pressed the add-key. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1831 --- include/video.h | 4 ++++ src/gui/sdl_mapper.cpp | 18 ++++++++++++++++-- src/gui/sdlmain.cpp | 10 ++++++++-- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/include/video.h b/include/video.h index 9caa2bef..c586b796 100644 --- a/include/video.h +++ b/include/video.h @@ -62,5 +62,9 @@ void GFX_SwitchFullScreen(void); bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch); void GFX_EndUpdate(void); +/* Mouse related */ +void GFX_CaptureMouse(void); +extern bool mouselocked; //true if mouse is confined to window + #endif diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index c5204be3..e6444e56 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -44,7 +44,7 @@ enum { enum BB_Types { BB_Next,BB_Prev,BB_Add,BB_Del, - BB_Save,BB_Reset + BB_Save,BB_Reset,BB_Exit }; enum BC_Types { @@ -554,6 +554,7 @@ public: switch (type) { case BB_Add: mapper.addbind=true; + SetActiveBind(0); break; case BB_Del: if (mapper.abindit!=mapper.aevent->bindlist.end()) { @@ -568,13 +569,16 @@ public: case BB_Next: if (mapper.abindit!=mapper.aevent->bindlist.end()) mapper.abindit++; - if (mapper.abindit==mapper.aevent->bindlist.end()) + if (mapper.abindit==mapper.aevent->bindlist.end()) mapper.abindit=mapper.aevent->bindlist.begin(); SetActiveBind(*(mapper.abindit)); break; case BB_Save: MAPPER_SaveBinds(); break; + case BB_Exit: + mapper.exit=true; + break; } } protected: @@ -735,6 +739,7 @@ struct { CCaptionButton * selected; CCaptionButton * action; CBindButton * save; + CBindButton * exit; CBindButton * add; CBindButton * del; CBindButton * next; @@ -977,6 +982,7 @@ static void CreateLayout(void) { bind_but.del=new CBindButton(300,380,50,20,"Del",BB_Del); bind_but.save=new CBindButton(400,450,50,20,"Save",BB_Save); + bind_but.exit=new CBindButton(450,450,50,20,"Exit",BB_Exit); bind_but.bind_title->Change("Bind Title"); } @@ -1156,6 +1162,13 @@ void MAPPER_Run(void) { for (CEventVector_it evit=events.begin();evit!=events.end();evit++) { (*evit)->DeActivateAll(); } + + bool mousetoggle=false; + if(mouselocked) { + mousetoggle=true; + GFX_CaptureMouse(); + } + mapper.surface=SDL_SetVideoMode(640,480,8,0); /* Set some palette entries */ SDL_SetPalette(mapper.surface, SDL_LOGPAL|SDL_PHYSPAL, map_pal, 0, 4); @@ -1171,6 +1184,7 @@ void MAPPER_Run(void) { BIND_MappingEvents(); SDL_Delay(1); } + if(mousetoggle) GFX_CaptureMouse(); GFX_ResetScreen(); } diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index e02e4525..9ed5448c 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.66 2004-06-10 07:18:19 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.67 2004-06-13 12:10:08 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -440,7 +440,7 @@ dosurface: return sdl.draw.mode; } - +bool mouselocked; //Global variable for mapper static void CaptureMouse(void) { sdl.mouse.locked=!sdl.mouse.locked; if (sdl.mouse.locked) { @@ -450,6 +450,11 @@ static void CaptureMouse(void) { SDL_WM_GrabInput(SDL_GRAB_OFF); SDL_ShowCursor(SDL_ENABLE); } + mouselocked=sdl.mouse.locked; +} + +void GFX_CaptureMouse(void) { + CaptureMouse(); } static void SwitchFullScreen(void) { @@ -590,6 +595,7 @@ static void GUI_StartUp(Section * sec) { sdl.desktop.fullscreen=section->Get_bool("fullscreen"); sdl.wait_on_error=section->Get_bool("waitonerror"); sdl.mouse.locked=false; + mouselocked=false; //Global for mapper sdl.mouse.requestlock=false; sdl.desktop.fixed=section->Get_bool("fullfixed"); sdl.desktop.width=section->Get_int("fullwidth"); From d1febd670aa6b706525b1f8a155fe572465bd75b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 13 Jun 2004 13:16:17 +0000 Subject: [PATCH 1750/4131] typo in default mapping Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1832 --- src/gui/sdl_mapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index e6444e56..1afa0eb1 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -1024,7 +1024,7 @@ static struct { Bitu key; } DefaultKeys[]={ {"f1",SDLK_F1}, {"f2",SDLK_F2}, {"f3",SDLK_F3}, {"f4",SDLK_F4}, - {"f5",SDLK_F1}, {"f6",SDLK_F6}, {"f7",SDLK_F7}, {"f8",SDLK_F8}, + {"f5",SDLK_F5}, {"f6",SDLK_F6}, {"f7",SDLK_F7}, {"f8",SDLK_F8}, {"f9",SDLK_F9}, {"f10",SDLK_F10}, {"f11",SDLK_F11}, {"f12",SDLK_F12}, {"1",SDLK_1}, {"2",SDLK_2}, {"3",SDLK_3}, {"4",SDLK_4}, From 31fe898cf556cb481c4061f14a54e265aaf08218 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jun 2004 11:46:32 +0000 Subject: [PATCH 1751/4131] Add 32bit internal mixing Speed it up a bit Clean it up a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1833 --- src/hardware/gus.cpp | 110 ++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 69 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 5da89a9d..38f47a0b 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -121,9 +121,6 @@ static void pushIRQ(Bit8u channum, bool WaveIRQ, bool RampIRQ) { IRQFifo.entry[IRQFifo.stackpos].channum = channum; IRQFifo.entry[IRQFifo.stackpos].RampIRQ = RampIRQ; IRQFifo.entry[IRQFifo.stackpos].WaveIRQ = WaveIRQ; - - - } else { LOG_GUS("GUS IRQ Fifo full!"); } @@ -149,27 +146,23 @@ static void popIRQ(IRQFifoEntry * tmpentry) { // Returns a single 16-bit sample from the Gravis's RAM -static INLINE Bit16s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { +static INLINE Bit32s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { Bit32u useAddr; Bit32u holdAddr; useAddr = CurAddr >> 9; if(eightbit) { if(Delta >= 1024) { - Bit8s tmpsmall = (Bit8s)GUSRam[useAddr]; - return (Bit16s)(tmpsmall << 7); + Bit32s tmpsmall = (Bit8s)GUSRam[useAddr]; +// return tmpsmall << 7; + return tmpsmall << 8; } else { - // Interpolate - Bit8s b1 = (Bit8s)GUSRam[useAddr]; - Bit8s b2 = (Bit8s)GUSRam[useAddr+1]; - Bit32s w1 = b1 << 8; - Bit32s w2 = b2 << 8; + Bit32s w1 = ((Bit8s)GUSRam[useAddr+0]) << 8; + Bit32s w2 = ((Bit8s)GUSRam[useAddr+1]) << 8; Bit32s diff = w2 - w1; - return (Bit16s)(w1+((diff*(CurAddr&511))>>9)); - + return (w1+((diff*(Bit32s)(CurAddr&511))>>9)); } } else { - // Formula used to convert addresses for use with 16-bit samples holdAddr = useAddr & 0xc0000L; useAddr = useAddr & 0x1ffffL; @@ -177,17 +170,14 @@ static INLINE Bit16s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { useAddr = (holdAddr | useAddr); if(Delta >= 1024) { - - return (Bit16s)((Bit16u)GUSRam[useAddr] | ((Bit16u)GUSRam[useAddr+1] << 8)) >> 2 - ; - +// return (GUSRam[useAddr+0] | (((Bit8s)GUSRam[useAddr+1]) << 8)) >> 2; + return (GUSRam[useAddr+0] | (((Bit8s)GUSRam[useAddr+1]) << 8)); } else { - // Interpolate - Bit16s w1 = (Bit16s)((Bit16u)GUSRam[useAddr] | ((Bit16u)GUSRam[useAddr+1] << 8)); - Bit16s w2 = (Bit16s)((Bit16u)GUSRam[useAddr+2] | ((Bit16u)GUSRam[useAddr+3] << 8)); + Bit32s w1 = (GUSRam[useAddr+0] | (((Bit8s)GUSRam[useAddr+1]) << 8)); + Bit32s w2 = (GUSRam[useAddr+2] | (((Bit8s)GUSRam[useAddr+3]) << 8)); Bit32s diff = w2 - w1; - return (Bit16s)(w1+((diff*(CurAddr&511))>>9)); + return (w1+((diff*(Bit32s)(CurAddr&511))>>9)); } } } @@ -339,9 +329,9 @@ public: // It should be noted that unless a channel is stopped, it will // continue to return the sample it is pointing to, regardless // of whether or not the channel is moving or ramping. - void generateSamples(Bit16s * stream,Bit32u len) { + void generateSamples(Bit32s * stream,Bit32u len) { int i; - Bit16s tmpsamp; + Bit32s tmpsamp; bool eightbit; eightbit = ((voiceCont & 0x4) == 0); @@ -357,11 +347,9 @@ public: tmpsamp = (tmpsamp * vol16bit[CurVolume]) >> 12; // Output stereo sample - stream[i<<1] = (Bit16s)(((Bit32s)tmpsamp * (Bit32s)leftvol)>>8) ; - stream[(i<<1)+1] = (Bit16s)(((Bit32s)tmpsamp * rightvol)>>8); - - - if(dir) { + stream[i<<1]+= tmpsamp * leftvol; + stream[(i<<1)+1]+= tmpsamp * rightvol; + if (dir) { // Increment backwards but don't let it get below zero. if (moving) { if(CurAddr > RealDelta) CurAddr -= RealDelta; else CurAddr = 0; } @@ -383,11 +371,8 @@ public: NotifyEndSamp(); } else { NotifyEndSamp(); - } - } - } else { // Increment forwards @@ -465,8 +450,10 @@ public: } } - - +#if 1 + static Bit32u rampmultable[4]={1,8,64,512}; + nextramp += myGUS.muperchan*rampmultable[VolRampRate >> 6]; +#else switch(VolRampRate >> 6) { case 0: nextramp += myGUS.muperchan; @@ -483,14 +470,12 @@ public: default: nextramp += myGUS.muperchan * 512; break; - } - +#endif } } - } @@ -905,25 +890,32 @@ static void GUS_DMA_Callback(DmaChannel * chan,DMAEvent event) { chan->Register_Callback(0); } - static void GUS_CallBack(Bit8u * stream,Bit32u len) { - Bit16s *bufptr; - Bit16s buffer[4096]; - Bit32s tmpbuf[4096]; - - memset(&buffer[0],0,len*4); - memset(&tmpbuf[0],0,len*8); - - Bitu i,t; + Bit32s buffer[4096]; + memset(&buffer[0],0,len*8); + Bitu i; for(i=0;i<=myGUS.activechan;i++) { if (guschan[i]->playing) { guschan[i]->generateSamples(&buffer[0],len); - for(t=0;t> 8)*AutoAmp)>>9; + if (sample>32767) { + sample=32767; + AutoAmp--; + } else if (sample<-32768) + { + sample=-32768; + AutoAmp--; + } + bufptr[i] = (Bit16s)(sample); + } if(myGUS.irqenabled) { if(IRQFifo.stackpos >= 0) { @@ -957,26 +949,6 @@ static void GUS_CallBack(Bit8u * stream,Bit32u len) { } } } - - - Bit32s sample; - bufptr = (Bit16s *)stream; -// LOG_GUS("AutoAmp: %i\n",AutoAmp); - for(i=0;i>9; - if (sample>32767) - { - sample=32767; - AutoAmp--; - } else if (sample<-32768) - { - sample=-32768; - AutoAmp--; - } - bufptr[i] = (Bit16s)(sample); - } - } From 38cb5b88cabfad79bfd28ce61db8a1f28821f048 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jun 2004 18:34:03 +0000 Subject: [PATCH 1752/4131] Fixes to the gus timers More accurate timing using dosbox internal events Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1834 --- src/hardware/gus.cpp | 130 ++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 70 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 38f47a0b..5d0d2aba 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -65,10 +65,12 @@ struct GFGus { Bit32s muperchan; struct GusTimer { - Bit16u bytetimer; - Bit32s countdown; - Bit32s setting; - bool active; + Bit8u value; + bool reached; + bool raiseirq; + bool masked; + bool running; + Bit32u delay; } timers[2]; Bit32u rate; Bit16u portbase; @@ -86,8 +88,7 @@ struct GFGus { struct IRQStat { bool MIDITx; bool MIDIRx; - bool T1; - bool T2; + bool T[2]; bool Resv; bool WaveTable; bool VolRamp; @@ -503,19 +504,22 @@ static void GUSReset(void) myGUS.irqenabled = false; } - myGUS.timers[0].active = false; - myGUS.timers[1].active = false; - myGUS.timers[0].bytetimer = 0x0; - myGUS.timers[1].bytetimer = 0x0; + myGUS.timers[0].raiseirq = false; + myGUS.timers[1].raiseirq = false; + myGUS.timers[0].reached = false; + myGUS.timers[1].reached = false; + myGUS.timers[0].running = false; + myGUS.timers[1].running = false; + + myGUS.timers[0].value = 0xff; + myGUS.timers[1].value = 0xff; // Stop all channels int i; for(i=0;i<32;i++) { guschan[i]->WriteVoiceCtrl(0x3); - } IRQFifo.stackpos = -1; - } @@ -601,6 +605,15 @@ static Bit16u ExecuteReadRegister(void) { } } +static void GUS_TimerEvent(Bitu val) { + if (!myGUS.timers[val].masked) myGUS.timers[val].reached=true; + if (myGUS.timers[val].raiseirq) { + myGUS.irq.T[val]=true; + PIC_ActivateIRQ(myGUS.irq1); + } + if (myGUS.timers[val].running) PIC_AddEvent(GUS_TimerEvent,myGUS.timers[val].delay,val); +}; + static void ExecuteGlobRegister(void) { int i; @@ -721,21 +734,18 @@ static void ExecuteGlobRegister(void) { break; case 0x45: // Timer control register. Identical in operation to Adlib's timer myGUS.TimerControl = (Bit8u)(myGUS.gRegData>>8); - if((myGUS.TimerControl & 0x08) !=0) myGUS.timers[1].countdown = myGUS.timers[1].setting; - if((myGUS.TimerControl & 0x04) !=0) myGUS.timers[0].countdown = myGUS.timers[0].setting; - myGUS.irq.T1 = false; - myGUS.irq.T2 = false; - PIC_DeActivateIRQ(myGUS.irq1); + myGUS.timers[0].raiseirq=(myGUS.TimerControl & 0x04)>0; + if (!myGUS.timers[0].raiseirq) myGUS.irq.T[0]=false; + myGUS.timers[1].raiseirq=(myGUS.TimerControl & 0x08)>0; + if (!myGUS.timers[1].raiseirq) myGUS.irq.T[1]=false; break; case 0x46: // Timer 1 control - myGUS.timers[0].bytetimer = (Bit8u)(myGUS.gRegData>>8); - myGUS.timers[0].setting = ((Bit32s)0xff - (Bit32s)myGUS.timers[0].bytetimer) * ((Bit32s)80 << 10); - myGUS.timers[0].countdown = myGUS.timers[0].setting; + myGUS.timers[0].value = (Bit8u)(myGUS.gRegData>>8); + myGUS.timers[0].delay = (0x100 - myGUS.timers[0].value) * 80; break; case 0x47: // Timer 2 control - myGUS.timers[1].bytetimer = (Bit8u)(myGUS.gRegData>>8); - myGUS.timers[1].setting = ((Bit32s)0xff - (Bit32s)myGUS.timers[1].bytetimer) * ((Bit32s)360 << 10); - myGUS.timers[1].countdown = myGUS.timers[1].setting; + myGUS.timers[1].value = (Bit8u)(myGUS.gRegData>>8); + myGUS.timers[1].delay = (0x100 - myGUS.timers[1].value) * 320; break; case 0x49: // DMA sampling control register myGUS.SampControl = (Bit8u)(myGUS.gRegData>>8); @@ -759,8 +769,8 @@ static Bitu read_gus(Bitu port,Bitu iolen) { temp = 0; if(myGUS.irq.MIDITx) temp |= 1; if(myGUS.irq.MIDIRx) temp |= 2; - if(myGUS.irq.T1) temp |= 4; - if(myGUS.irq.T2) temp |= 8; + if(myGUS.irq.T[0]) temp |= 4; + if(myGUS.irq.T[1]) temp |= 8; if(myGUS.irq.Resv) temp |= 16; if(myGUS.irq.WaveTable) temp |= 32; if(myGUS.irq.VolRamp) temp |= 64; @@ -770,9 +780,11 @@ static Bitu read_gus(Bitu port,Bitu iolen) { case 0x208: Bit8u tmptime; tmptime = 0; - if(myGUS.irq.T1) tmptime |= (1 << 6); - if(myGUS.irq.T2) tmptime |= (1 << 5); - if((myGUS.irq.T1) || (myGUS.irq.T2)) tmptime |= (1 << 7); + if (myGUS.timers[0].reached) tmptime |= (1 << 6); + if (myGUS.timers[1].reached) tmptime |= (1 << 5); + if (tmptime & 0x60) tmptime |= (1 << 7); + if (myGUS.irq.T[0]) tmptime|=(1 << 2); + if (myGUS.irq.T[1]) tmptime|=(1 << 1); return tmptime; case 0x20a: return adlib_commandreg; @@ -810,8 +822,25 @@ static void write_gus(Bitu port,Bitu val,Bitu iolen) { break; case 0x209: //TODO adlib_commandreg should be 4 for this to work else it should just latch the value - myGUS.timers[0].active = ((val & 0x1) > 0); - myGUS.timers[1].active = ((val & 0x2) > 0); + if (val & 0x80) { + myGUS.timers[0].reached=false; + myGUS.timers[1].reached=false; + return; + } + myGUS.timers[0].masked=(val & 0x40)>0; + myGUS.timers[1].masked=(val & 0x20)>0; + if (val & 0x1) { + if (!myGUS.timers[0].running) { + PIC_AddEvent(GUS_TimerEvent,myGUS.timers[0].delay,0); + myGUS.timers[0].running=true; + } + } else myGUS.timers[0].running=false; + if (val & 0x2) { + if (!myGUS.timers[1].running) { + PIC_AddEvent(GUS_TimerEvent,myGUS.timers[1].delay,1); + myGUS.timers[1].running=true; + } + } else myGUS.timers[1].running=false; break; //TODO Check if 0x20a register is also available on the gus like on the interwave case 0x20b: @@ -830,7 +859,6 @@ static void write_gus(Bitu port,Bitu val,Bitu iolen) { LOG_GUS("Attempt to assign GUS to wrong DMA - at %x, assigned %x", myGUS.dma1, dmatable[temp]); } } - break; case 0x302: myGUS.gCurChannel = val ; @@ -850,7 +878,6 @@ static void write_gus(Bitu port,Bitu val,Bitu iolen) { myGUS.gRegData = (0x00ff & myGUS.gRegData) | val << 8; ExecuteGlobRegister(); break; - case 0x307: if(myGUS.gDramAddr < sizeof(GUSRam)) GUSRam[myGUS.gDramAddr] = val; break; @@ -916,39 +943,11 @@ static void GUS_CallBack(Bit8u * stream,Bit32u len) { } bufptr[i] = (Bit16s)(sample); } - if(myGUS.irqenabled) { if(IRQFifo.stackpos >= 0) { PIC_ActivateIRQ(myGUS.irq1); } } - - if(myGUS.timers[0].active) { - myGUS.timers[0].countdown-=(len * (Bit32u)myGUS.mupersamp); - if(!myGUS.irq.T1) { - // Expire Timer 1 - if(myGUS.timers[0].countdown < 0) { - if((myGUS.TimerControl & 0x04) !=0) { - PIC_ActivateIRQ(myGUS.irq1); - } - myGUS.irq.T1 = true; - //LOG_GUS("T1 timer expire"); - //myGUS.timers[0].countdown = myGUS.timers[0].setting; - } - } - } - if(myGUS.timers[1].active) { - if(!myGUS.irq.T2) { - myGUS.timers[1].countdown-=(len * (Bit32u)myGUS.mupersamp); - // Expire Timer 2 - if(myGUS.timers[1].countdown < 0) { - if((myGUS.TimerControl & 0x08) !=0) { - PIC_ActivateIRQ(myGUS.irq1); - } - myGUS.irq.T2 = true; - } - } - } } @@ -979,8 +978,6 @@ void MakeTables(void) void GUS_Init(Section* sec) { - - memset(&myGUS,0,sizeof(myGUS)); memset(GUSRam,0,1024*1024); @@ -995,11 +992,6 @@ void GUS_Init(Section* sec) { myGUS.irq2 = section->Get_int("irq2"); strcpy(&myGUS.ultradir[0], section->Get_string("ultradir")); - adlib_commandreg = 85; - myGUS.timers[0].active = false; - myGUS.timers[1].active = false; - - memset(&myGUS.irq, 0, sizeof(myGUS.irq)); IRQFifo.stackpos = -1; myGUS.irqenabled = false; @@ -1049,13 +1041,11 @@ void GUS_Init(Section* sec) { for(i=0;i<=32;i++) { guschan[i] = new GUSChannels(i); } - // Register the Mixer CallBack - gus_chan=MIXER_AddChannel(GUS_CallBack,GUS_RATE,"GUS"); MIXER_SetMode(gus_chan,MIXER_16STEREO); MIXER_Enable(gus_chan,false); - + GUSReset(); int portat = 0x200+GUS_BASE; // ULTRASND=Port,DMA1,DMA2,IRQ1,IRQ2 SHELL_AddAutoexec("SET ULTRASND=%3X,%d,%d,%d,%d",portat,myGUS.dma1,myGUS.dma2,myGUS.irq1,myGUS.irq2); From 3e6947cb8728db582a31e9d6da5d8b3f317f19ac Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 17 Jun 2004 07:27:55 +0000 Subject: [PATCH 1753/4131] Add reading of timer 1 and give it the value xt bios gives it Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1835 --- src/hardware/timer.cpp | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 942bc6b6..1abd002b 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.23 2004-04-03 19:34:10 harekiet Exp $ */ +/* $Id: timer.cpp,v 1.24 2004-06-17 07:27:55 harekiet Exp $ */ #include "dosbox.h" #include "inout.h" @@ -128,9 +128,7 @@ static void write_latch(Bitu port,Bitu val,Bitu iolen) { if (p->write_state != 0) { if (p->write_latch == 0) { if(p->bcd == false) {p->cntr = 0x10000;} else {p->cntr=9999;} - } - - else p->cntr = p->write_latch; + } else p->cntr = p->write_latch; p->start=PIC_MicroCount(); p->micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)p->cntr)); switch (counter) { @@ -193,9 +191,10 @@ static void write_p43(Bitu port,Bitu val,Bitu iolen) { case 1: case 2: pit[latch].bcd = (val&1)>0; - if (val & 1) if(pit[latch].cntr>=9999) pit[latch].cntr=9999; - - + if (val & 1) { + if(pit[latch].cntr>=9999) pit[latch].cntr=9999; + } + if ((val & 0x30) == 0) { /* Counter latch command */ counter_latch(latch); @@ -220,10 +219,11 @@ static void write_p43(Bitu port,Bitu val,Bitu iolen) { void TIMER_Init(Section* sect) { IO_RegisterWriteHandler(0x40,write_latch,IO_MB); +// IO_RegisterWriteHandler(0x41,write_latch,IO_MB); IO_RegisterWriteHandler(0x42,write_latch,IO_MB); IO_RegisterWriteHandler(0x43,write_p43,IO_MB); IO_RegisterReadHandler(0x40,read_latch,IO_MB); -// IO_RegisterReadHandler(0x41,read_p41,IO_MB); + IO_RegisterReadHandler(0x41,read_latch,IO_MB); IO_RegisterReadHandler(0x42,read_latch,IO_MB); /* Setup Timer 0 */ pit[0].cntr=0x10000; @@ -236,18 +236,26 @@ void TIMER_Init(Section* sect) { pit[0].go_read_latch = true; pit[1].bcd = false; + pit[1].write_state = 1; + pit[1].read_state = 1; pit[1].go_read_latch = true; - pit[1].mode = 3; + pit[1].cntr = 18; + pit[1].mode = 2; pit[1].write_state = 3; - pit[0].micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)pit[0].cntr)); - pit[2].micro=100; pit[2].read_latch=0; /* MadTv1 */ pit[2].write_state = 3; /* Chuck Yeager */ + pit[2].read_state = 3; pit[2].mode=3; pit[2].bcd=false; + pit[2].cntr=1320; pit[2].go_read_latch=true; + pit[0].micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)pit[0].cntr)); + pit[1].micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)pit[1].cntr)); + pit[2].micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)pit[2].cntr)); + + PIC_AddEvent(PIT0_Event,pit[0].micro); } From 1d72b82abc1b5672bba4f7eeebc70fd545de1c40 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 17 Jun 2004 07:28:51 +0000 Subject: [PATCH 1754/4131] Fill the text font tables for tandy,cga and hercules machine modes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1836 --- src/hardware/vga_other.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index bf2a7444..f5425645 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -273,10 +273,12 @@ void VGA_SetupOther(void) { if (machine==MCH_CGA || machine==MCH_TANDY) { extern Bit8u int10_font_08[256 * 8]; for (i=0;i<256;i++) memcpy(&vga.draw.font[i*32],&int10_font_08[i*8],8); + vga.draw.font_tables[0]=vga.draw.font_tables[1]=vga.draw.font; } if (machine==MCH_HERC) { extern Bit8u int10_font_14[256 * 14]; for (i=0;i<256;i++) memcpy(&vga.draw.font[i*32],&int10_font_14[i*14],14); + vga.draw.font_tables[0]=vga.draw.font_tables[1]=vga.draw.font; } if (machine==MCH_CGA) { IO_RegisterWriteHandler(0x3d8,write_cga,IO_MB); From 59fffaf3cdd31afa1d7b33a618797e1821b14806 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 17 Jun 2004 17:40:02 +0000 Subject: [PATCH 1755/4131] Only use the pages in file entry from the exe header to determine size to load Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1837 --- src/dos/dos_execute.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 3352fdc7..54885eb6 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.39 2004-05-04 18:34:08 qbix79 Exp $ */ +/* $Id: dos_execute.cpp,v 1.40 2004-06-17 17:40:02 harekiet Exp $ */ #include #include @@ -252,14 +252,8 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { if (len Date: Fri, 18 Jun 2004 07:37:38 +0000 Subject: [PATCH 1756/4131] Only give dos 32kb less memory in tandy mode instead of the old 128kb Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1838 --- src/dos/dos_memory.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 36d6dc32..87461754 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -193,9 +193,9 @@ void DOS_SetupMemory(void) { DOS_MCB mcb((Bit16u)MEM_START+2); mcb.SetPSPSeg(MCB_FREE); //Free - if (machine!=MCH_TANDY) { - mcb.SetSize(0x9FFE - MEM_START - 2); - } else mcb.SetSize(0x7FFE - MEM_START - 2); + if (machine==MCH_TANDY) { + mcb.SetSize(0x97FE - MEM_START - 2); + } else mcb.SetSize(0x9FFE - MEM_START - 2); mcb.SetType(0x5a); //Last Block dos.firstMCB=MEM_START; From 35b0cc060ca113e3ad29e111016ba7511e45c0a5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Jun 2004 08:16:43 +0000 Subject: [PATCH 1757/4131] Fix the tandy crt page register to also work in text modes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1839 --- src/hardware/vga_draw.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 19cb9cce..e8714d61 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -35,7 +35,8 @@ static Bit8u TempLine[1280]; static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; for (Bitu x=vga.draw.blocks;x>0;x--) { - Bitu val=vga.mem.linear[vidstart+line];vidstart=(vidstart+1)&0x1fff; + Bitu val=vga.mem.linear[vidstart+line]; + vidstart=(vidstart+1)&0x1dfff; *draw++=CGA_2_Table[val >> 4]; *draw++=CGA_2_Table[val & 0xf]; } @@ -45,7 +46,8 @@ static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; for (Bitu x=0;x Date: Fri, 18 Jun 2004 08:24:05 +0000 Subject: [PATCH 1758/4131] Setup the Tandy CRT/CPU page register Add the Tandy set CRT/CPU page functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1840 --- src/ints/int10.cpp | 21 ++++++++++++++++++++- src/ints/int10.h | 1 + src/ints/int10_modes.cpp | 11 ++++++++--- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 94284d9d..6f9ab72d 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -72,7 +72,26 @@ static Bitu INT10_Handler(void) { reg_ah=0; break; case 0x05: /* Set Active Page */ - if (reg_al & 0x80) LOG(LOG_INT10,LOG_NORMAL)("Tandy set CRT/CPU Page Func %x",reg_al); + if (reg_al & 0x80 && machine==MCH_TANDY) { + Bit8u crtcpu=real_readb(BIOSMEM_SEG, BIOSMEM_CRTCPU_PAGE); + switch (reg_al) { + case 0x80: + reg_bh=crtcpu & 7; + reg_bl=(crtcpu >> 3) & 0x7; + break; + case 0x81: + crtcpu=(crtcpu & 0xc7) | ((reg_bl & 7) << 3); + break; + case 0x82: + crtcpu=(crtcpu & 0xf8) | (reg_bh & 7); + break; + case 0x83: + crtcpu=(crtcpu & 0xc0) | (reg_bh & 7) | ((reg_bl & 7) << 3); + break; + } + IO_WriteB(0x3df,crtcpu); + real_writeb(BIOSMEM_SEG, BIOSMEM_CRTCPU_PAGE,crtcpu); + } else INT10_SetActivePage(reg_al); break; case 0x06: /* Scroll Up */ diff --git a/src/ints/int10.h b/src/ints/int10.h index 3172fe38..28782832 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -39,6 +39,7 @@ #define BIOSMEM_SWITCHES 0x88 #define BIOSMEM_MODESET_CTL 0x89 #define BIOSMEM_DCC_INDEX 0x8A +#define BIOSMEM_CRTCPU_PAGE 0x8A #define BIOSMEM_VS_POINTER 0xA8 diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 0d3230f8..2d273480 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -184,7 +184,7 @@ static void FinishSetMode(bool clearmem) { real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); // FIXME We nearly have the good tables. to be reworked - real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08); // 8 is VGA should be ok for now + if (machine==MCH_VGA) real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08); // 8 is VGA should be ok for now real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER,0x00); real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2,0x00); @@ -246,7 +246,7 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { //Vertical sync position IO_WriteW(crtc_base,0x07 | (CurMode->vdispend+1) << 8); //Maximum scanline - Bit8u scanline; + Bit8u scanline,crtpage; switch(CurMode->type) { case M_TEXT: if (machine==MCH_HERC) scanline=14; @@ -296,13 +296,18 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { IO_WriteB(0x3da,0x2);IO_WriteB(0x3de,0x0); //block border IO_WriteB(0x3da,0x3); //Tandy color overrides? switch (CurMode->mode) { - case 0x8: case 0x9: + case 0x8: + IO_WriteB(0x3de,0x14);break; + case 0x9: IO_WriteB(0x3de,0x14);break; case 0xa: IO_WriteB(0x3de,0x0c);break; default: IO_WriteB(0x3de,0x0);break; } + crtpage=(CurMode->mode>=0x9) ? 0xf6 : 0x3f; + IO_WriteB(0x3df,crtpage); + real_writeb(BIOSMEM_SEG,BIOSMEM_CRTCPU_PAGE,crtpage); mode_control=mode_control_list[CurMode->mode]; if (CurMode->mode == 0x6 || CurMode->mode==0xa) color_select=0x3f; else color_select=0x30; From 865a5ff015e044bc02debf3d99dfa73e3862879f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Jun 2004 20:24:04 +0000 Subject: [PATCH 1759/4131] Fix row count in mode 11h/12h, Fix timing for mode 11h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1841 --- src/ints/int10_modes.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 2d273480..b8aa3cd1 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -29,8 +29,8 @@ VideoModeBlock ModeList_VGA[]={ { 0x00E ,M_EGA16 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE }, { 0x00F ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,400 ,0 },/*was EGA_2*/ { 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,1 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, -{ 0x011 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,449 ,80 ,480 ,0 },/*was EGA_2 */ -{ 0x012 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, +{ 0x011 ,M_EGA16 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 },/*was EGA_2 */ +{ 0x012 ,M_EGA16 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, { 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,0 }, { 0x100 ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, From d627af5bc37fd2bec9f8360afd554d32c194e2a4 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 18 Jun 2004 20:27:10 +0000 Subject: [PATCH 1760/4131] Fix set scanline length vesa function Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1842 --- src/ints/int10_vesa.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 6898cbc4..56db545a 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.9 2004-06-10 20:23:50 harekiet Exp $ */ +/* $Id: int10_vesa.cpp,v 1.10 2004-06-18 20:27:10 harekiet Exp $ */ #include #include @@ -231,8 +231,8 @@ Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u & bytes,Bit16u & pixels,Bit16u & case 0x00: /* Set in pixels */ bytes=(pixels*bpp); case 0x02: /* Set in bytes */ - scan_len=bytes/4; - if (bytes % 4) scan_len++; + scan_len=bytes/8; + if (bytes % 8) scan_len++; vga.config.scan_len=scan_len; VGA_StartResize(); break; @@ -246,8 +246,8 @@ Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u & bytes,Bit16u & pixels,Bit16u & return 0x1; //Illegal call } /* Write the scan line to video card the simple way */ - pixels=(vga.config.scan_len*4)/bpp; - bytes=vga.config.scan_len*4; + pixels=(vga.config.scan_len*8)/bpp; + bytes=vga.config.scan_len*8; return 0x0; } From b542452e12f83982f05e352f482abcfd15b1fb34 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Jun 2004 16:55:29 +0000 Subject: [PATCH 1761/4131] New define for bios wait flag function Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1843 --- include/bios.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/bios.h b/include/bios.h index af1ae858..afd25bca 100644 --- a/include/bios.h +++ b/include/bios.h @@ -91,6 +91,8 @@ #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 From 180af29a1e913627e066d1826e7efbc5b00182f0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Jun 2004 16:56:55 +0000 Subject: [PATCH 1762/4131] Add int 15, bios wait function Add first function to int 14 for some serial port detection Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1844 --- src/ints/bios.cpp | 54 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index ebce07c1..43240562 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.32 2004-05-19 19:46:28 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.33 2004-06-20 16:56:55 harekiet Exp $ */ #include #include "dosbox.h" @@ -32,7 +32,7 @@ #include "mouse.h" static Bitu call_int1a,call_int11,call_int8,call_int17,call_int12,call_int15,call_int1c; -static Bitu call_int1,call_int70; +static Bitu call_int1,call_int70,call_int14; static Bit16u size_extended; static Bitu INT70_Handler(void) { @@ -48,6 +48,7 @@ static Bitu INT70_Handler(void) { PhysPt where=Real2Phys(mem_readd(BIOS_WAIT_FLAG_POINTER)); mem_writeb(where,mem_readb(where)|0x80); mem_writeb(BIOS_WAIT_FLAG_ACTIVE,0); + mem_writed(BIOS_WAIT_FLAG_POINTER,RealMake(0,BIOS_WAIT_FLAG_TEMP)); IO_Write(0x70,0xb); IO_Write(0x71,IO_Read(0x71)&~0x40); } @@ -95,7 +96,9 @@ static Bitu INT1A_Handler(void) { LOG(LOG_BIOS,LOG_ERROR)("INT1A:80:Setup tandy sound multiplexer to %d",reg_al); break; case 0x81: /* Tandy sound system checks */ - LOG(LOG_BIOS,LOG_ERROR)("INT1A:81:Tandy DAC Check failing"); + if (machine!=MCH_TANDY) break; + reg_ax=0xc4; + CALLBACK_SCF(false); break; /* INT 1A - Tandy 2500, Tandy 1000L series - DIGITAL SOUND - INSTALLATION CHECK @@ -168,15 +171,29 @@ static Bitu INT17_Handler(void) { break; default: E_Exit("Unhandled INT 17 call %2X",reg_ah); - }; return CBRET_NONE; } +static Bitu INT14_Handler(void) { + switch (reg_ah) { + case 0x00: /* Init port */ + { + Bitu port=real_readw(0x40,reg_dx*2); + reg_ah=IO_ReadB(port+5); + reg_al=IO_ReadB(port+6); + LOG_MSG("AX %X DX %X",reg_ax,reg_dx); + } + break; + default: + LOG_MSG("Unhandled INT 14 call %2X",reg_ah); + + } + return CBRET_NONE; +} static Bitu INT15_Handler(void) { static Bitu biosConfigSeg=0; - switch (reg_ah) { case 0x06: LOG(LOG_BIOS,LOG_NORMAL)("INT15 Unkown Function 6"); @@ -252,6 +269,21 @@ static Bitu INT15_Handler(void) { { //TODO Perhaps really wait :) Bit32u micro=(reg_cx<<16)|reg_dx; + if (mem_readb(BIOS_WAIT_FLAG_ACTIVE)) { + reg_ah=0x83; + CALLBACK_SCF(true); + break; + } + Bit32u count=(reg_cx<<16)|reg_dx; + mem_writed(BIOS_WAIT_FLAG_POINTER,RealMake(0,BIOS_WAIT_FLAG_TEMP)); + mem_writed(BIOS_WAIT_FLAG_COUNT,count); + mem_writeb(BIOS_WAIT_FLAG_ACTIVE,1); + /* Reprogram RTC to start */ + IO_Write(0x70,0xb); + IO_Write(0x71,IO_Read(0x71)|0x40); + while (mem_readd(BIOS_WAIT_FLAG_COUNT)) { + CALLBACK_Idle(); + } CALLBACK_SCF(false); } case 0x87: /* Copy extended memory */ @@ -390,8 +422,6 @@ void BIOS_Init(Section* sec) { CALLBACK_Setup(call_int8,&INT8_Handler,CB_IRET); mem_writed(BIOS_TIMER,0); //Calculate the correct time RealSetVec(0x8,CALLBACK_RealPointer(call_int8)); - /* INT10 Video Bios */ - /* INT 11 Get equipment list */ call_int11=CALLBACK_Allocate(); CALLBACK_Setup(call_int11,&INT11_Handler,CB_IRET); @@ -403,6 +433,9 @@ void BIOS_Init(Section* sec) { mem_writew(BIOS_MEMORY_SIZE,640); /* INT 13 Bios Disk Support */ BIOS_SetupDisks(); + call_int14=CALLBACK_Allocate(); + CALLBACK_Setup(call_int14,&INT14_Handler,CB_IRET); + RealSetVec(0x14,CALLBACK_RealPointer(call_int14)); /* INT 15 Misc Calls */ call_int15=CALLBACK_Allocate(); CALLBACK_Setup(call_int15,&INT15_Handler,CB_IRET); @@ -436,8 +469,8 @@ void BIOS_Init(Section* sec) { if (IO_Read(0x378)!=0xff) real_writew(0x40,0x08,0x378); /* Test for serial port */ Bitu index=0; - if (IO_Read(0x3f8)!=0xff) real_writew(0x40,(index++)*2,0x3f8); - if (IO_Read(0x2f8)!=0xff) real_writew(0x40,(index++)*2,0x2f8); + if (IO_Read(0x3fa)!=0xff) real_writew(0x40,(index++)*2,0x3f8); + if (IO_Read(0x2fa)!=0xff) real_writew(0x40,(index++)*2,0x2f8); /* Setup equipment list */ Bitu config=0x4400; //1 Floppy, 2 serial and 1 parrallel #if (C_FPU) @@ -461,9 +494,6 @@ void BIOS_Init(Section* sec) { size_extended=IO_Read(0x71); IO_Write(0x70,0x31); size_extended|=(IO_Read(0x71) << 8); - } - - From 21e775be7499eadc4954f24127cdfdf9daebc29a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Jun 2004 16:58:09 +0000 Subject: [PATCH 1763/4131] Fix int10 ah=0x13 write string to support attributes and correctly update the cursor Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1845 --- src/ints/int10_char.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index cffff625..48d2bef8 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.27 2004-05-11 18:55:33 harekiet Exp $ */ +/* $Id: int10_char.cpp,v 1.28 2004-06-20 16:58:09 harekiet Exp $ */ /* Character displaying moving functions */ @@ -344,7 +344,6 @@ dowrite: IO_Write(base,0xb);IO_Write(base+1,last); } - void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page) { Bit16u address; @@ -382,7 +381,6 @@ void INT10_ReadCharAttr(Bit16u * result,Bit8u page) { *result=mem_readw(where); } - static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useattr) { PhysPt fontdata; Bitu x,y; @@ -429,7 +427,6 @@ static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool } y++; } - } void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) { @@ -456,7 +453,6 @@ void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr) { BIOS_NCOLS;BIOS_NROWS; Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); - switch (chr) { case 7: //TODO BEEP @@ -496,7 +492,6 @@ void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr) { INT10_SetCursorPos(cur_row,cur_col,page); } - void INT10_TeletypeOutput(Bit8u chr,Bit8u attr) { INT10_TeletypeOutputAttr(chr,attr,CurMode->type!=M_TEXT); } @@ -515,7 +510,6 @@ void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,B row=cur_row; col=cur_col; } - INT10_SetCursorPos(row,col,page); while (count>0) { Bit8u chr=mem_readb(string); @@ -523,11 +517,11 @@ void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,B if (flag&2) { attr=mem_readb(string); string++; - } else attr=7; - INT10_TeletypeOutputAttr(chr,attr,(flag & 2)>0); + }; + INT10_TeletypeOutputAttr(chr,attr,true); count--; } - if (flag & 1) { + if (!(flag&1)) { INT10_SetCursorPos(cur_row,cur_col,page); } } From 55cf4510c9aab143cd4ae4149c5b26c6411c9ce9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Jun 2004 16:59:29 +0000 Subject: [PATCH 1764/4131] Remove blinking variable from config Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1846 --- include/vga.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/vga.h b/include/vga.h index e2504997..bd6dd84f 100644 --- a/include/vga.h +++ b/include/vga.h @@ -60,9 +60,7 @@ typedef struct { /* Some other screen related variables */ Bitu line_compare; - bool chained; /* Enable or Disabled Chain 4 Mode */ - bool blinking; /* Attribute bit 7 is blinking */ /* Pixel Scrolling */ Bit8u pel_panning; /* Amount of pixels to skip when starting horizontal line */ From 13d4604573a46b2c25a6134003d9885a1b94fd40 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Jun 2004 17:01:58 +0000 Subject: [PATCH 1765/4131] Check that timers don't get 0 microseconds intervals Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1847 --- src/hardware/timer.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 1abd002b..0e450ebc 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.24 2004-06-17 07:27:55 harekiet Exp $ */ +/* $Id: timer.cpp,v 1.25 2004-06-20 17:01:58 harekiet Exp $ */ #include "dosbox.h" #include "inout.h" @@ -36,8 +36,6 @@ static INLINE void BCD2BIN(Bit16u& val) { Bit16u temp= (val&0x0f) +((val>>4)&0x0f) *10 +((val>>8)&0x0f) *100 +((val>>12)&0x0f) *1000; val=temp; } - - struct PIT_Block { Bit8u mode; /* Current Counter Mode */ @@ -131,6 +129,7 @@ static void write_latch(Bitu port,Bitu val,Bitu iolen) { } else p->cntr = p->write_latch; p->start=PIC_MicroCount(); p->micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)p->cntr)); + if (!p->micro) p->micro=1; switch (counter) { case 0x00: /* Timer hooked to IRQ 0 */ PIC_RemoveEvents(PIT0_Event); @@ -180,8 +179,7 @@ static Bitu read_latch(Bitu port,Bitu iolen) { break; } if( pit[counter].bcd == true) BCD2BIN(pit[counter].read_latch); - - return ret; + return ret; } static void write_p43(Bitu port,Bitu val,Bitu iolen) { @@ -255,7 +253,6 @@ void TIMER_Init(Section* sect) { pit[1].micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)pit[1].cntr)); pit[2].micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)pit[2].cntr)); - PIC_AddEvent(PIT0_Event,pit[0].micro); } From 0c11281b190f4bb403a8db81bf02f52f0cefd89e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Jun 2004 17:02:37 +0000 Subject: [PATCH 1766/4131] remove debug message Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1848 --- src/hardware/vga_memory.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index df8d4b41..b93939cd 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -409,12 +409,11 @@ range_b800: PAGING_ClearTLB(); } -bool lfb_update; +static bool lfb_update; static void VGA_DoUpdateLFB(Bitu val) { lfb_update=false; MEM_SetLFB(vga.s3.la_window << 4 ,sizeof(vga.mem.linear)/4096,&vga.mem.linear[0]); - LOG_MSG("LIN: Reconfiguing linear page address"); } void VGA_StartUpdateLFB(void) { From 1de427249f3d073fb0181367ee3f26e781e7f24d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Jun 2004 17:02:59 +0000 Subject: [PATCH 1767/4131] Handle text blinking bit for cga/tandy mode control register Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1849 --- src/hardware/vga_other.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index f5425645..f50cc949 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -209,6 +209,7 @@ static void write_cga(Bitu port,Bitu val,Bitu iolen) { } else { VGA_SetMode(M_TANDY_TEXT); } + VGA_SetBlinking(val & 0x20); break; case 0x3d9: write_color_select(val); @@ -220,6 +221,7 @@ static void write_tandy(Bitu port,Bitu val,Bitu iolen) { switch (port) { case 0x3d8: vga.tandy.mode_control=val; + VGA_SetBlinking(val & 0x20); TANDY_FindMode(); break; case 0x3d9: From 5fa83f5e8d7e0698916aeca3a1b459e1bd6fe103 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Jun 2004 17:04:16 +0000 Subject: [PATCH 1768/4131] Handle text blinking for cga/tandy Clear some more events on resolution changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1850 --- src/hardware/vga_draw.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index e8714d61..ce14ddc2 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -190,7 +190,9 @@ static void VGA_DrawPart(Bitu lines) { vga.draw.parts_left--; if (vga.draw.parts_left) { PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts,vga.draw.parts_lines); - } else RENDER_EndUpdate(); + } else { + RENDER_EndUpdate(); + } } void VGA_SetBlinking(Bitu enabled) { @@ -199,11 +201,11 @@ void VGA_SetBlinking(Bitu enabled) { if (enabled) { b=0;vga.draw.blinking=1; //used to -1 but blinking is unsigned vga.attr.mode_control|=0x08; - vga.tandy.mode_control&=~0x20; + vga.tandy.mode_control|=0x20; } else { b=8;vga.draw.blinking=0; vga.attr.mode_control&=~0x08; - vga.tandy.mode_control|=0x20; + vga.tandy.mode_control&=~0x20; } for (Bitu i=0;i<8;i++) TXT_BG_Table[i+8]=(b+i) | ((b+i) << 8)| ((b+i) <<16) | ((b+i) << 24); } @@ -220,11 +222,12 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.panning=vga.config.pel_panning; switch (vga.mode) { case M_TEXT: + vga.draw.address=(vga.draw.address*2); + case M_TANDY_TEXT: vga.draw.cursor.count++; /* check for blinking and blinking change delay */ - FontMask[1]=(vga.attr.mode_control & (vga.draw.cursor.count >> 1) & 0x8) ? + FontMask[1]=(vga.draw.blinking & (vga.draw.cursor.count >> 4)) ? 0 : 0xffffffff; - vga.draw.address=(vga.draw.address*2); break; case M_CGA4:case M_CGA2:case M_CGA16: case M_TANDY2:case M_TANDY4:case M_TANDY16: @@ -471,6 +474,7 @@ void VGA_SetupDrawing(Bitu val) { if (( width != vga.draw.width) || (height != vga.draw.height)) { PIC_RemoveEvents(VGA_VerticalTimer); PIC_RemoveEvents(VGA_VerticalDisplayEnd); + PIC_RemoveEvents(VGA_DrawPart); vga.draw.width=width; vga.draw.height=height; vga.draw.scaleh=scaleh; From 802d1137d58dd97e14e0cf030a168c7694525207 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 20 Jun 2004 19:13:10 +0000 Subject: [PATCH 1769/4131] Moved sr and sm above the breakpoint section so you can use BP as register. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1851 --- src/debug/debug.cpp | 50 ++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 21e18ea3..e06baeb0 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.54 2004-06-10 07:23:01 harekiet Exp $ */ +/* $Id: debug.cpp,v 1.55 2004-06-20 19:13:10 qbix79 Exp $ */ #include "programs.h" @@ -902,6 +902,30 @@ bool ParseCommand(char* str) else DEBUG_ShowMsg("DEBUG: Variable list load (%s) : failure",name); return true; } + found = strstr(str,"SR "); + if (found) { // Set register value + found+=2; + if (ChangeRegister(found)) DEBUG_ShowMsg("DEBUG: Set Register success."); + else DEBUG_ShowMsg("DEBUG: Set Register failure."); + return true; + } + found = strstr(str,"SM "); + if (found) { // Set memory with following values + found+=3; + Bit16u seg = (Bit16u)GetHexValue(found,found); found++; + Bit32u ofs = GetHexValue(found,found); found++; + Bit16u count = 0; + while (*found) { + while (*found==' ') found++; + if (*found) { + Bit8u value = (Bit8u)GetHexValue(found,found); found++; + mem_writeb(GetAddress(seg,ofs+count),value); + count++; + } + }; + DEBUG_ShowMsg("DEBUG: Memory changed."); + return true; + } found = strstr(str,"BP "); if (found) { // Add new breakpoint @@ -1016,30 +1040,6 @@ bool ParseCommand(char* str) return true; } #endif - found = strstr(str,"SR "); - if (found) { // Set register value - found+=2; - if (ChangeRegister(found)) DEBUG_ShowMsg("DEBUG: Set Register success."); - else DEBUG_ShowMsg("DEBUG: Set Register failure."); - return true; - } - found = strstr(str,"SM "); - if (found) { // Set memory with following values - found+=3; - Bit16u seg = (Bit16u)GetHexValue(found,found); found++; - Bit32u ofs = GetHexValue(found,found); found++; - Bit16u count = 0; - while (*found) { - while (*found==' ') found++; - if (*found) { - Bit8u value = (Bit8u)GetHexValue(found,found); found++; - mem_writeb(GetAddress(seg,ofs+count),value); - count++; - } - }; - DEBUG_ShowMsg("DEBUG: Memory changed."); - return true; - } found = strstr(str,"INTT "); if (found) { // Create Cpu log file found+=4; From 24123486b8f08f2efe16ddcf32769f79ed2cf65e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Jun 2004 22:03:10 +0000 Subject: [PATCH 1770/4131] Disable the gus from loading if machine != vga Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1852 --- src/hardware/gus.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 5d0d2aba..97ac3503 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -978,11 +978,13 @@ void MakeTables(void) void GUS_Init(Section* sec) { + if(machine!=MCH_VGA) return; + Section_prop * section=static_cast(sec); + if(!section->Get_bool("gus")) return; + memset(&myGUS,0,sizeof(myGUS)); memset(GUSRam,0,1024*1024); - Section_prop * section=static_cast(sec); - if(!section->Get_bool("gus")) return; myGUS.rate=section->Get_int("rate"); myGUS.portbase = section->Get_hex("base") - 0x200; From 7b8fb0982bbeac44fb2525afbbb12747352942c6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 20 Jun 2004 22:03:34 +0000 Subject: [PATCH 1771/4131] Remove debug message Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1853 --- src/hardware/keyboard.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 15f7b86e..1c7e31fb 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.24 2004-06-10 07:19:46 harekiet Exp $ */ +/* $Id: keyboard.cpp,v 1.25 2004-06-20 22:03:34 harekiet Exp $ */ #include #include @@ -109,7 +109,6 @@ static Bitu read_p60(Bitu port,Bitu iolen) { } static void write_p60(Bitu port,Bitu val,Bitu iolen) { - LOG_MSG("write port 60 %x",val); switch (keyb.command) { case CMD_NONE: /* None */ /* No active command this would normally get sent to the keyboard then */ From c3ccb8febd524ec15131b8042c86fcc9d5be3790 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 22 Jun 2004 14:05:08 +0000 Subject: [PATCH 1772/4131] lowcased true and false parsing. Fixes bugs with blah=False (got true) and such. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1854 --- src/misc/setup.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index a0e78b53..e2017e9e 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.20 2004-05-25 19:37:18 harekiet Exp $ */ +/* $Id: setup.cpp,v 1.21 2004-06-22 14:05:08 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -46,8 +46,9 @@ void Prop_string::SetValue(char* input){ } void Prop_bool::SetValue(char* input){ - input=trim(input); - if((input[0]=='0') ||(input[0]=='D')||( (input[0]=='O') && (input[0]=='F'))||(input[0]=='f')){ + input=lowcase(trim(input)); + /* valid false entries: 0 ,d*, of* ,f* everything else gets true */ + if((input[0]=='0') || (input[0]=='d') || ( (input[0]=='o') && (input[1]=='f')) || (input[0]=='f')){ __value._bool=false; }else{ __value._bool=true; From 44aa1939006cce3fe3df1062da76b332b81e5838 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 22 Jun 2004 22:38:29 +0000 Subject: [PATCH 1773/4131] change line compare to always be 1023 for any low res mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1855 --- src/ints/int10_modes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index b8aa3cd1..2ef66b04 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -445,7 +445,7 @@ bool INT10_SetVideoMode(Bitu mode) { /* Vertical Retrace End */ IO_Write(crtc_base,0x16);IO_Write(crtc_base+1,(CurMode->vtotal-8)); /* Line Compare */ - Bitu line_compare=(mode>=256) ? 2047 : 1023; + Bitu line_compare=(CurMode->vtotal < 1024) ? 1023 : 2047; IO_Write(crtc_base,0x18);IO_Write(crtc_base+1,line_compare&0xff); overflow|=(line_compare & 0x100) >> 4; max_scanline|=(line_compare & 0x200) >> 3; From 62d78d6715d7b5fa598fcad20c998727bfb6bbc7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 24 Jun 2004 21:21:48 +0000 Subject: [PATCH 1774/4131] New sGet/sSave handling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1856 --- include/dos_inc.h | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index fed50e6d..f4a7f685 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.45 2004-06-10 08:48:53 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.46 2004-06-24 21:21:48 harekiet Exp $ */ #ifndef DOS_H_ #define DOS_H_ @@ -209,28 +209,25 @@ INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) { /* Remains some classes used to access certain things */ #define sOffset(s,m) ((char*)&(((s*)NULL)->m)-(char*)NULL) -#define sGet(s,m) GetIt(((s *)0)->m,(PhysPt)sOffset(s,m)) -#define sSave(s,m,val) SaveIt(((s *)0)->m,(PhysPt)sOffset(s,m),val) +#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: - INLINE Bit8u GetIt(Bit8u,PhysPt addr) { - return mem_readb(pt+addr); + INLINE Bitu GetIt(Bitu size,PhysPt addr) { + switch (size) { + case 1:return mem_readb(pt+addr); + case 2:return mem_readw(pt+addr); + case 4:return mem_readd(pt+addr); + } + return 0; } - INLINE Bit16u GetIt(Bit16u,PhysPt addr) { - return mem_readw(pt+addr); - } - INLINE Bit32u GetIt(Bit32u,PhysPt addr) { - return mem_readd(pt+addr); - } - INLINE void SaveIt(Bit8u,PhysPt addr,Bit8u val) { - mem_writeb(pt+addr,val); - } - INLINE void SaveIt(Bit16u,PhysPt addr,Bit16u val) { - mem_writew(pt+addr,val); - } - INLINE void SaveIt(Bit32u,PhysPt addr,Bit32u val) { - mem_writed(pt+addr,val); + INLINE void SaveIt(Bitu size,PhysPt addr,Bitu val) { + switch (size) { + case 1:mem_writeb(pt+addr,val);break; + case 2:mem_writew(pt+addr,val);break; + case 4:mem_writed(pt+addr,val);break; + } } INLINE void SetPt(Bit16u seg) { pt=PhysMake(seg,0);} INLINE void SetPt(Bit16u seg,Bit16u off) { pt=PhysMake(seg,off);} From c7f47743ba15c0300df1832b5bf924022ce23fd2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 25 Jun 2004 14:46:48 +0000 Subject: [PATCH 1775/4131] Add more precision to volume ramp and frequency adding. Rewrite the volume handling Rewrite the panning handling Rewrite channel irq event system Fix dma selection table Fix bug with dual 8bit io writes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1857 --- src/hardware/gus.cpp | 946 +++++++++++++++++-------------------------- 1 file changed, 375 insertions(+), 571 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 97ac3503..cdf1d614 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -27,25 +27,37 @@ #include "math.h" #include "regs.h" +//Extra bits of precision over normal gus +#define WAVE_BITS 2 +#define WAVE_FRACT (9+WAVE_BITS) +#define WAVE_FRACT_MASK ((1 << WAVE_FRACT)-1) +#define WAVE_MSWMASK ((1 << (16+WAVE_BITS))-1) +#define WAVE_LSWMASK (0xffffffff ^ WAVE_MSWMASK) + +//Amount of precision the volume has +#define RAMP_FRACT (10) +#define RAMP_FRACT_MASK ((1 << RAMP_FRACT)-1) + +#define USEVOLTABLE 1 #define GUS_BASE myGUS.portbase #define GUS_RATE myGUS.rate #define LOG_GUS -static MIXER_Channel * gus_chan; - -static Bit16u vol8bit[256]; -static Bit16s vol16bit[4096]; - -static Bit8u irqtable[8] = { 0, 2, 5, 3, 7, 11, 12, 15 }; - -static Bit8u dmatable[6] = { 3, 1, 5, 5, 6, 7 }; - -static Bit8u GUSRam[1024*1024]; // 1024K of GUS Ram - -static Bit32s AutoAmp=1024; - Bit8u adlib_commandreg; +static MIXER_Channel * gus_chan; +static Bit8u irqtable[8] = { 0, 2, 5, 3, 7, 11, 12, 15 }; +static Bit8u dmatable[8] = { 0, 1, 3, 5, 6, 7, 0, 0 }; +static Bit8u GUSRam[1024*1024]; // 1024K of GUS Ram +static Bit32s AutoAmp=512; +#if USEVOLTABLE +static Bit16u vol16bit[4096]; +#endif +static Bit32u pantable[16]; + +static Bitu show_test=0; +class GUSChannels; +static void CheckVoiceIrq(void); struct GFGus { Bit8u gRegSelect; @@ -58,11 +70,8 @@ struct GFGus { Bit8u TimerControl; Bit8u SampControl; Bit8u mixControl; - + Bit8u ActiveChannels; Bit32u basefreq; - Bit16u activechan; - Bit32s mupersamp; - Bit32s muperchan; struct GusTimer { Bit8u value; @@ -81,87 +90,35 @@ struct GFGus { Bit16u irq2; char ultradir[512]; - bool irqenabled; - + bool ChangeIRQDMA; // IRQ status register values - struct IRQStat { - bool MIDITx; - bool MIDIRx; - bool T[2]; - bool Resv; - bool WaveTable; - bool VolRamp; - bool DMATC; - } irq; - + Bit8u IRQStatus; + Bit32u ActiveMask; + Bit8u IRQChan; + Bit32u RampIRQ; + Bit32u WaveIRQ; } myGUS; -#define GUSFIFOSIZE 1024 - -struct IRQFifoEntry { - Bit8u channum; - bool WaveIRQ; - bool RampIRQ; -}; - -struct IRQFifoDef { - IRQFifoEntry entry[GUSFIFOSIZE]; - Bit16s stackpos; -} IRQFifo; +Bitu DEBUG_EnableDebugger(void); static void GUS_DMA_Callback(DmaChannel * chan,DMAEvent event); -// Routines to manage IRQ requests coming from the GUS -static void pushIRQ(Bit8u channum, bool WaveIRQ, bool RampIRQ) { - IRQFifo.stackpos++; - if(IRQFifo.stackpos < GUSFIFOSIZE) { - myGUS.irq.WaveTable = WaveIRQ; - myGUS.irq.VolRamp = RampIRQ; - - IRQFifo.entry[IRQFifo.stackpos].channum = channum; - IRQFifo.entry[IRQFifo.stackpos].RampIRQ = RampIRQ; - IRQFifo.entry[IRQFifo.stackpos].WaveIRQ = WaveIRQ; - } else { - LOG_GUS("GUS IRQ Fifo full!"); - } -} - -static void popIRQ(IRQFifoEntry * tmpentry) { - if(IRQFifo.stackpos<0) { - tmpentry->channum = 0; - tmpentry->RampIRQ = false; - tmpentry->WaveIRQ = false; - return; - } - memcpy(tmpentry, &IRQFifo.entry[IRQFifo.stackpos], sizeof(IRQFifoEntry)); - --IRQFifo.stackpos; - if(IRQFifo.stackpos >= 0) { - myGUS.irq.WaveTable = IRQFifo.entry[IRQFifo.stackpos].WaveIRQ; - myGUS.irq.VolRamp = IRQFifo.entry[IRQFifo.stackpos].RampIRQ; - } else { - myGUS.irq.WaveTable = false; - myGUS.irq.VolRamp = false; - } -} - - // Returns a single 16-bit sample from the Gravis's RAM static INLINE Bit32s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { Bit32u useAddr; Bit32u holdAddr; - useAddr = CurAddr >> 9; - if(eightbit) { - if(Delta >= 1024) { + useAddr = CurAddr >> WAVE_FRACT; + if (eightbit) { + if (Delta >= (1 << WAVE_FRACT)) { Bit32s tmpsmall = (Bit8s)GUSRam[useAddr]; -// return tmpsmall << 7; return tmpsmall << 8; } else { // Interpolate Bit32s w1 = ((Bit8s)GUSRam[useAddr+0]) << 8; Bit32s w2 = ((Bit8s)GUSRam[useAddr+1]) << 8; Bit32s diff = w2 - w1; - return (w1+((diff*(Bit32s)(CurAddr&511))>>9)); + return (w1+((diff*(Bit32s)(CurAddr&WAVE_FRACT_MASK ))>>WAVE_FRACT)); } } else { // Formula used to convert addresses for use with 16-bit samples @@ -170,371 +127,294 @@ static INLINE Bit32s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { useAddr = useAddr << 1; useAddr = (holdAddr | useAddr); - if(Delta >= 1024) { -// return (GUSRam[useAddr+0] | (((Bit8s)GUSRam[useAddr+1]) << 8)) >> 2; + if(Delta >= (1 << WAVE_FRACT)) { return (GUSRam[useAddr+0] | (((Bit8s)GUSRam[useAddr+1]) << 8)); } else { // Interpolate Bit32s w1 = (GUSRam[useAddr+0] | (((Bit8s)GUSRam[useAddr+1]) << 8)); Bit32s w2 = (GUSRam[useAddr+2] | (((Bit8s)GUSRam[useAddr+3]) << 8)); Bit32s diff = w2 - w1; - return (w1+((diff*(Bit32s)(CurAddr&511))>>9)); + return (w1+((diff*(Bit32s)(CurAddr&WAVE_FRACT_MASK ))>>WAVE_FRACT)); } } } class GUSChannels { public: - Bit8u voiceCont; - Bit16u FreqCont; - Bit32u RealDelta; - Bit32u StartAddr; - Bit32u EndAddr; - Bit8s VolRampRate; - Bit16s VolRampStart; - Bit16s VolRampEnd; - Bit8u VolRampStartOrg; - Bit8u VolRampEndOrg; - Bit32s CurVolume; - Bit32u CurAddr; + Bit32u WaveStart; + Bit32u WaveEnd; + Bit32u WaveAddr; + Bit32u WaveAdd; + Bit8u WaveCtrl; + Bit16u WaveFreq; + + Bit32u RampStart; + Bit32u RampEnd; + Bit32u RampVol; + Bit32u RampAdd; + Bit32u RampAddReal; + + Bit8u RampRate; + Bit8u RampCtrl; + Bit8u PanPot; - Bit8u VolControl; Bit8u channum; - - bool moving; - bool playing; - bool ramping; - bool dir; - bool voldir; - -public: - bool notifyonce; - Bit32s leftvol; - Bit32s rightvol; - Bit32s nextramp; + Bit32u irqmask; + Bit32u PanLeft; + Bit32u PanRight; + Bit32s VolLeft; + Bit32s VolRight; GUSChannels(Bit8u num) { channum = num; - playing = true; - ramping = false; - moving = false; - dir = false; - voldir = false; - StartAddr = 0; - EndAddr = 0; - CurAddr = 0; - VolRampRate = 0; - VolRampStart = 0; - VolRampEnd = 0; - leftvol = 255; - rightvol = 255; - nextramp = 0; - + irqmask = 1 << num; + WaveStart = 0; + WaveEnd = 0; + WaveAddr = 0; + WaveAdd = 0; + WaveFreq = 0; + WaveCtrl = 3; + RampRate = 0; + RampStart = 0; + RampEnd = 0; + RampCtrl = 3; + RampAdd = 0; + RampVol = 0; + VolLeft = 0; + VolRight = 0; + PanLeft = 0; + PanRight = 0; + PanPot = 0x7; }; - - // Voice control register - void WriteVoiceCtrl(Bit8u val) { - voiceCont = val; - if (val & 0x3) moving = false; - if ((val & 0x3) == 0) { - //playing = true; - moving = true; - } - dir = false; - if((val & 0x40) !=0) dir = true; - + void WriteWaveFreq(Bit16u val) { + WaveFreq = val; + double frameadd = double(val >> 1)/512.0; //Samples / original gus frame + double realadd = (frameadd*(double)myGUS.basefreq/(double)GUS_RATE) * (double)(1 << WAVE_FRACT); + WaveAdd = (Bit32u)realadd; } - Bit8u ReadVoiceCtrl(void) { - Bit8u tmpval = voiceCont & 0xfe; - if(!playing) tmpval++; - return tmpval; + void WriteWaveCtrl(Bit8u val) { + Bit32u oldirq=myGUS.WaveIRQ; + WaveCtrl = val & 0x7f; + if ((val & 0xa0)==0xa0) myGUS.WaveIRQ|=irqmask; + else myGUS.WaveIRQ&=~irqmask; + if (oldirq != myGUS.WaveIRQ) + CheckVoiceIrq(); } - - // Frequency control register - void WriteFreqCtrl(Bit16u val) { - FreqCont = val; - int fc; - fc = val; - fc = fc >> 1; - fc = fc * myGUS.basefreq; - fc = fc - (myGUS.basefreq >> 1); - fc = fc / 512; - float simple; - - simple = ((float)fc / (float)GUS_RATE) * 512; - RealDelta = (Bit32u)simple; + INLINE Bit8u ReadWaveCtrl(void) { + Bit8u ret=WaveCtrl; + if (myGUS.WaveIRQ & irqmask) ret|=0x80; + return ret; } - Bit16u ReadFreqCtrl(void) { - return FreqCont; + void UpdateWaveRamp(void) { + WriteWaveFreq(WaveFreq); + WriteRampRate(RampRate); } - - // Used when GUS changes channel numbers during playback - void UpdateFreqCtrl() { WriteFreqCtrl(FreqCont); } - - // Pan position register void WritePanPot(Bit8u val) { - if(val<8) { - leftvol = 255; - rightvol = val << 5; - } else { - rightvol = 255; - leftvol = (8-(val-8)) << 5; - } PanPot = val; + PanLeft = pantable[0x0f-(val & 0xf)]; + PanRight = pantable[(val & 0xf)]; + UpdateVolumes(); } Bit8u ReadPanPot(void) { return PanPot; } - - // Volume ramping control register - void WriteVolControl(Bit8u val) { - VolControl = val; - if (val & 0x3) ramping = false; - if ((val & 0x3) == 0) ramping = true; - voldir = false; - if((val & 0x40) !=0) voldir = true; - + void WriteRampCtrl(Bit8u val) { + Bit32u old=myGUS.RampIRQ; + RampCtrl = val & 0x7f; + if ((val & 0xa0)==0xa0) myGUS.RampIRQ|=irqmask; + else myGUS.RampIRQ&=~irqmask; + if (old != myGUS.RampIRQ) CheckVoiceIrq(); } - Bit8u ReadVolControl(void) { - Bit8u tmpval = VolControl & 0xfe; - if(!ramping) tmpval++; - return tmpval; + INLINE Bit8u ReadRampCtrl(void) { + Bit8u ret=RampCtrl; + if (myGUS.RampIRQ & irqmask) ret|=0x80; + return ret; } - - - // Methods to queue IRQ on ramp or sample end - void NotifyEndSamp(void) { - if(!notifyonce) { - if((voiceCont & 0x20) != 0) { - pushIRQ(channum,true,false); - notifyonce = true; - } + void WriteRampRate(Bit8u val) { + RampRate = val; + double frameadd = (double)(RampRate & 63)/(double)(1 << (3*(val >> 6))); + double realadd = (frameadd*(double)myGUS.basefreq/(double)GUS_RATE) * (double)(1 << RAMP_FRACT); + RampAdd = (Bit32u)realadd; + } + void ShowWave(void) { + LOG_GUS("Wave %2d Ctrl %02x Current %d Start %d End %d Add %3.3f ", + channum, + ReadWaveCtrl(), + WaveAddr>>WAVE_FRACT, + WaveStart>>WAVE_FRACT, + WaveEnd>>WAVE_FRACT, + (float)WaveAdd/(float)(1 << WAVE_FRACT) + ); + } + void ShowRamp(void) { + LOG_GUS("Ramp %2d Ctrl %02X Current %d Start %d End %d Add %d", + channum, + ReadRampCtrl(), + RampVol >> RAMP_FRACT, + RampStart >> RAMP_FRACT, + RampEnd >> RAMP_FRACT, + RampAdd >> RAMP_FRACT + ); + } + INLINE void WaveUpdate(void) { + if (WaveCtrl & 0x3) return; + Bit32s WaveLeft; + if (WaveCtrl & 0x40) { + WaveAddr-=WaveAdd; + WaveLeft=WaveStart-WaveAddr; + } else { + WaveAddr+=WaveAdd; + WaveLeft=WaveAddr-WaveEnd; + } + if (WaveLeft<0) return; + /* Generate an IRQ if needed */ + if (WaveCtrl & 0x20) { + myGUS.WaveIRQ|=irqmask; + } + /* Check for not being in PCM operation */ + if (RampCtrl & 0x04) return; + /* Check for looping */ + if (WaveCtrl & 0x08) { + /* Bi-directional looping */ + if (WaveCtrl & 0x10) WaveCtrl^=0x40; + WaveAddr = (WaveCtrl & 0x40) ? (WaveEnd-WaveLeft) : (WaveStart+WaveLeft); + } else { + WaveCtrl|=1; //Stop the channel + WaveAddr = (WaveCtrl & 0x40) ? WaveStart : WaveEnd; } } - void NotifyEndRamp(void) { - if(!notifyonce) { - if((VolControl & 0x20) != 0) { - pushIRQ(channum,false,true); - notifyonce = true; - } + INLINE void UpdateVolumes(void) { + Bit32s templeft=RampVol - PanLeft; + templeft&=~(templeft >> 31); + Bit32s tempright=RampVol - PanRight; + tempright&=~(tempright >> 31); +#if USEVOLTABLE + VolLeft=vol16bit[templeft >> RAMP_FRACT]; + VolRight=vol16bit[tempright >> RAMP_FRACT]; +#else + +#endif + } + INLINE void RampUpdate(void) { + /* Check if ramping enabled */ + if (RampCtrl & 0x3) return; + Bit32s RampLeft; + if (RampCtrl & 0x40) { + RampVol-=RampAdd; + RampLeft=RampStart-RampVol; + } else { + RampVol+=RampAdd; + RampLeft=RampVol-RampEnd; } + if (RampLeft<0) { + UpdateVolumes(); + return; + } + /* Generate an IRQ if needed */ + if (RampCtrl & 0x20) { + myGUS.RampIRQ|=irqmask; + } + /* Check for looping */ + if (RampCtrl & 0x08) { + /* Bi-directional looping */ + if (RampCtrl & 0x10) RampCtrl^=0x40; + RampVol = (RampCtrl & 0x40) ? (RampEnd-RampLeft) : (RampStart+RampLeft); + } else { + RampCtrl|=1; //Stop the channel + RampVol = (RampCtrl & 0x40) ? RampStart : RampEnd; + } + UpdateVolumes(); } - - // Debug routine to show current channel position - void ShowAddr(void) { - LOG_GUS("Chan %d Start %d End %d Current %d", channum, StartAddr>>9, EndAddr>>9, CurAddr>>9); - } - - - // Generate the samples required by the callback routine - // It should be noted that unless a channel is stopped, it will - // continue to return the sample it is pointing to, regardless - // of whether or not the channel is moving or ramping. void generateSamples(Bit32s * stream,Bit32u len) { int i; Bit32s tmpsamp; bool eightbit; - eightbit = ((voiceCont & 0x4) == 0); - - notifyonce = false; - + if (RampCtrl & WaveCtrl & 3) return; + eightbit = ((WaveCtrl & 0x4) == 0); +#if 0 + if (!(show_test & 1023)) { + ShowWave(); + ShowRamp(); + } +#endif for(i=0;i<(int)len;i++) { // Get sample - tmpsamp = GetSample(RealDelta, CurAddr, eightbit); - - // Clip and convert log scale to PCM scale - if(CurVolume>4095) CurVolume = 4095; - if(CurVolume<0) CurVolume = 0; - tmpsamp = (tmpsamp * vol16bit[CurVolume]) >> 12; - + tmpsamp = GetSample(WaveAdd, WaveAddr, eightbit); // Output stereo sample - stream[i<<1]+= tmpsamp * leftvol; - stream[(i<<1)+1]+= tmpsamp * rightvol; - if (dir) { - // Increment backwards but don't let it get below zero. - if (moving) { if(CurAddr > RealDelta) CurAddr -= RealDelta; else CurAddr = 0; } - - //Thought 16-bit needed this - //if ((!eightbit) && (moving)) CurAddr -= RealDelta; - - if(CurAddr <= StartAddr) { - if((VolControl & 0x4) == 0) { - if((voiceCont & 0x8) != 0) { - if((voiceCont & 0x10) != 0) { - dir = !dir; - } else { - CurAddr = EndAddr - (512-(CurAddr & 511)); - } - - } else { - moving = false; - } - NotifyEndSamp(); - } else { - NotifyEndSamp(); - } - } - } else { - - // Increment forwards - if (moving) CurAddr += RealDelta; - - //Thought 16-bit needed this - //if ((!eightbit) && (moving)) CurAddr += RealDelta; - if(CurAddr >= EndAddr) { - if((VolControl & 0x4) == 0) { - if((voiceCont & 0x8) != 0) { - if((voiceCont & 0x10) != 0) { - dir = !dir; - } else { - CurAddr = StartAddr+(CurAddr & 511); - } - - } else { - moving = false; - } - NotifyEndSamp(); - } else { - NotifyEndSamp(); - } - } - } - - // Update volume - if(ramping) { - - // Subtract ramp counter by elapsed microseconds - nextramp -= myGUS.mupersamp; - bool flagged; - flagged = false; - - // Ramp volume until nextramp is a positive integer - while(nextramp <= 0) { - if(voldir) { - CurVolume -= (VolRampRate & 0x3f); - if (CurVolume <= 0) { - CurVolume = 0; - flagged = true; - } - - if((vol16bit[CurVolume]<=VolRampStart) || (flagged)){ - if((VolControl & 0x8) != 0) { - if((VolControl & 0x10) != 0) { - voldir = !voldir; - } else { - CurVolume = VolRampEndOrg; - } - } else { - ramping = false; - } - NotifyEndRamp(); - } - - } else { - CurVolume += (VolRampRate & 0x3f); - if (CurVolume >= 4095) { - CurVolume = 4095; - flagged = true; - } - - if((vol16bit[CurVolume]>=VolRampEnd) || (flagged)){ - if((VolControl & 0x8) != 0) { - if((VolControl & 0x10) != 0) { - voldir = !voldir; - } else { - CurVolume = VolRampStartOrg; - } - } else { - ramping = false; - } - NotifyEndRamp(); - } - - } -#if 1 - static Bit32u rampmultable[4]={1,8,64,512}; - nextramp += myGUS.muperchan*rampmultable[VolRampRate >> 6]; -#else - switch(VolRampRate >> 6) { - case 0: - nextramp += myGUS.muperchan; - break; - case 1: - nextramp += myGUS.muperchan* 8; - break; - case 2: - nextramp += myGUS.muperchan * 64; - break; - case 3: - nextramp += myGUS.muperchan * 512; - break; - default: - nextramp += myGUS.muperchan * 512; - break; - } -#endif - } - - } - + stream[i<<1]+= tmpsamp * VolLeft; + stream[(i<<1)+1]+= tmpsamp * VolRight; + WaveUpdate(); + RampUpdate(); } - - } - - }; +static GUSChannels *guschan[32]; +static GUSChannels *curchan; -GUSChannels *guschan[33]; - -GUSChannels *curchan; - - -static void GUSReset(void) -{ +static void GUSReset(void) { if((myGUS.gRegData & 0x1) == 0x1) { // Reset adlib_commandreg = 85; - memset(&myGUS.irq, 0, sizeof(myGUS.irq)); + myGUS.IRQStatus = 0; + myGUS.timers[0].raiseirq = false; + myGUS.timers[1].raiseirq = false; + myGUS.timers[0].reached = false; + myGUS.timers[1].reached = false; + myGUS.timers[0].running = false; + myGUS.timers[1].running = false; + + myGUS.timers[0].value = 0xff; + myGUS.timers[1].value = 0xff; + myGUS.timers[0].delay = 80; + myGUS.timers[1].delay = 320; + myGUS.ChangeIRQDMA = false; + // Stop all channels + int i; + for(i=0;i<32;i++) { + guschan[i]->RampVol=0; + guschan[i]->WriteWaveCtrl(0x1); + guschan[i]->WriteRampCtrl(0x1); + guschan[i]->WritePanPot(0x7); + } + myGUS.IRQChan = 0; } - if((myGUS.gRegData & 0x4) != 0) { + if ((myGUS.gRegData & 0x4) != 0) { myGUS.irqenabled = true; } else { myGUS.irqenabled = false; } - - myGUS.timers[0].raiseirq = false; - myGUS.timers[1].raiseirq = false; - myGUS.timers[0].reached = false; - myGUS.timers[1].reached = false; - myGUS.timers[0].running = false; - myGUS.timers[1].running = false; - - myGUS.timers[0].value = 0xff; - myGUS.timers[1].value = 0xff; - - // Stop all channels - int i; - for(i=0;i<32;i++) { - guschan[i]->WriteVoiceCtrl(0x3); - } - IRQFifo.stackpos = -1; } +static INLINE void GUS_CheckIRQ(void) { + if (myGUS.IRQStatus && (myGUS.mixControl & 0x08)) + PIC_ActivateIRQ(myGUS.irq1); +} + +static void CheckVoiceIrq(void) { + myGUS.IRQStatus&=0x9f; + Bitu totalmask=(myGUS.RampIRQ|myGUS.WaveIRQ) & myGUS.ActiveMask; + if (!totalmask) return; + if (myGUS.RampIRQ) myGUS.IRQStatus|=0x40; + if (myGUS.WaveIRQ) myGUS.IRQStatus|=0x20; + GUS_CheckIRQ(); + while (1) { + Bit32u check=(1 << myGUS.IRQChan); + if (totalmask & check) return; + myGUS.IRQChan++; + if (myGUS.IRQChan>=myGUS.ActiveChannels) myGUS.IRQChan=0; + } +} static Bit16u ExecuteReadRegister(void) { Bit8u tmpreg; - +// LOG_MSG("Read global reg %x",myGUS.gRegSelect); switch (myGUS.gRegSelect) { case 0x41: // Dma control register - read acknowledges DMA IRQ tmpreg = myGUS.DMAControl & 0xbf; - if(myGUS.irq.DMATC) tmpreg |= 0x40; - - myGUS.irq.DMATC = false; - PIC_DeActivateIRQ(myGUS.irq1); - + tmpreg |= (myGUS.IRQStatus & 0x80) >> 1; + myGUS.IRQStatus&=0x7f; return (Bit16u)(tmpreg << 8); case 0x42: // Dma address register return myGUS.dmaAddr; @@ -543,62 +423,42 @@ static Bit16u ExecuteReadRegister(void) { break; case 0x49: // Dma sample register tmpreg = myGUS.DMAControl & 0xbf; - if(myGUS.irq.DMATC) tmpreg |= 0x40; - - myGUS.irq.DMATC = false; - PIC_DeActivateIRQ(myGUS.irq1); - //LOG_GUS("Read sampling status, returned 0x%x", tmpreg); - + tmpreg |= (myGUS.IRQStatus & 0x80) >> 1; return (Bit16u)(tmpreg << 8); case 0x80: // Channel voice control read register - if(curchan != NULL) { - Bit8u sndout; - sndout = curchan->voiceCont & 0xFC; - if(!curchan->moving) sndout |= 0x3; + if (curchan) return curchan->ReadWaveCtrl() << 8; + else return 0x0300; - return (Bit16u)(sndout<< 8); - } else return 0x0300; + case 0x82: // Channel MSB start address register + if (curchan) return (Bit16u)(curchan->WaveStart >> (WAVE_BITS+16)); + else return 0x0000; + case 0x83: // Channel LSW start address register + if (curchan) return (Bit16u)(curchan->WaveStart >> WAVE_BITS); + else return 0x0000; - case 0x82: // Channel MSB address register - if(curchan != NULL) { - return (Bit16u)(curchan->StartAddr >> 16); - } else return 0x0000; - case 0x83: // Channel LSW address register - if(curchan != NULL) { - return (Bit16u)(curchan->StartAddr & 0xffff); - } else return 0x0000; case 0x89: // Channel volume register - if(curchan != NULL) { - return ((Bit16u)curchan->CurVolume << 4); - } else return 0x0000; + if (curchan) return (Bit16u)((curchan->RampVol >> RAMP_FRACT) << 4); + else return 0x0000; case 0x8a: // Channel MSB current address register - if(curchan != NULL) { - return (Bit16u)(curchan->CurAddr >> 16); - } else return 0x0000; - + if (curchan) return (Bit16u)(curchan->WaveAddr >> (WAVE_BITS+16)); + else return 0x0000; case 0x8b: // Channel LSW current address register - if(curchan != NULL) { - return (Bit16u)(curchan->CurAddr & 0xFFFF); - } else return 0x0000; + if (curchan) return (Bit16u)(curchan->WaveAddr >> WAVE_BITS); + else return 0x0000; + case 0x8d: // Channel volume control register - if(curchan != NULL) { - Bit8u volout; - volout = curchan->VolControl & 0xFC; - if(!curchan->ramping) volout |= 0x3; - return (volout << 8); - } else return 0x0300; - + if (curchan) return curchan->ReadRampCtrl() << 8; + else return 0x0300; case 0x8f: // General channel IRQ status register - Bit8u temp; - temp = 0x20; - IRQFifoEntry tmpentry; - PIC_DeActivateIRQ(myGUS.irq1); - popIRQ(&tmpentry); - if(!tmpentry.WaveIRQ) temp |= 0x80; - if(!tmpentry.RampIRQ) temp |= 0x40; - temp |= tmpentry.channum; - - return (Bit16u)(temp << 8); + tmpreg=myGUS.IRQChan|0x20; + Bit32u mask; + mask=1 << myGUS.IRQChan; + if (!(myGUS.RampIRQ & mask)) tmpreg|=0x40; + if (!(myGUS.WaveIRQ & mask)) tmpreg|=0x80; + myGUS.RampIRQ&=~mask; + myGUS.WaveIRQ&=~mask; + CheckVoiceIrq(); + return (Bit16u)(tmpreg << 8); default: LOG_GUS("Read Register num 0x%x", myGUS.gRegSelect); return myGUS.gRegData; @@ -608,113 +468,100 @@ static Bit16u ExecuteReadRegister(void) { static void GUS_TimerEvent(Bitu val) { if (!myGUS.timers[val].masked) myGUS.timers[val].reached=true; if (myGUS.timers[val].raiseirq) { - myGUS.irq.T[val]=true; - PIC_ActivateIRQ(myGUS.irq1); + myGUS.IRQStatus|=0x4 << val; + GUS_CheckIRQ(); } if (myGUS.timers[val].running) PIC_AddEvent(GUS_TimerEvent,myGUS.timers[val].delay,val); }; - + static void ExecuteGlobRegister(void) { int i; - //LOG_GUS("Access global register %x with %x", myGUS.gRegSelect, myGUS.gRegData); +// if (myGUS.gRegSelect|1!=0x44) LOG_MSG("write global register %x with %x", myGUS.gRegSelect, myGUS.gRegData); switch(myGUS.gRegSelect) { case 0x0: // Channel voice control register - if(curchan != NULL) { - curchan->WriteVoiceCtrl((Bit16u)myGUS.gRegData>>8); - } + if(curchan) curchan->WriteWaveCtrl((Bit16u)myGUS.gRegData>>8); break; case 0x1: // Channel frequency control register - if(curchan != NULL) { - curchan->WriteFreqCtrl(myGUS.gRegData); + if(curchan) curchan->WriteWaveFreq(myGUS.gRegData); + break; + case 0x2: // Channel MSW start address register + if (curchan) { + Bit32u tmpaddr = (Bit32u)(myGUS.gRegData & 0x1fff) << (16+WAVE_BITS); + curchan->WaveStart = (curchan->WaveStart & WAVE_MSWMASK) | tmpaddr; } break; - case 0x2: // Channel MSB start address register + case 0x3: // Channel LSW start address register if(curchan != NULL) { - Bit32u tmpaddr = myGUS.gRegData << 16; - curchan->StartAddr = (curchan->StartAddr & 0xFFFF) | tmpaddr; + Bit32u tmpaddr = (Bit32u)(myGUS.gRegData) << WAVE_BITS; + curchan->WaveStart = (curchan->WaveStart & WAVE_LSWMASK) | tmpaddr; } break; - case 0x3: // Channel LSB start address register + case 0x4: // Channel MSW end address register if(curchan != NULL) { - Bit32u tmpaddr = (Bit32u)(myGUS.gRegData); - curchan->StartAddr = (curchan->StartAddr & 0x1FFF0000) | tmpaddr; + Bit32u tmpaddr = (Bit32u)(myGUS.gRegData & 0x1fff) << (16+WAVE_BITS); + curchan->WaveEnd = (curchan->WaveEnd & WAVE_MSWMASK) | tmpaddr; } break; - case 0x4: // Channel MSB end address register + case 0x5: // Channel MSW end address register if(curchan != NULL) { - Bit32u tmpaddr = (Bit32u)myGUS.gRegData << 16; - curchan->EndAddr = (curchan->EndAddr & 0xFFFF) | tmpaddr; - } - break; - case 0x5: // Channel MSB end address register - if(curchan != NULL) { - Bit32u tmpaddr = (Bit32u)(myGUS.gRegData); - curchan->EndAddr = (curchan->EndAddr & 0x1FFF0000) | tmpaddr; + Bit32u tmpaddr = (Bit32u)(myGUS.gRegData) << WAVE_BITS; + curchan->WaveEnd = (curchan->WaveEnd & WAVE_LSWMASK) | tmpaddr; } break; case 0x6: // Channel volume ramp rate register if(curchan != NULL) { Bit8u tmpdata = (Bit16u)myGUS.gRegData>>8; - curchan->VolRampRate = tmpdata; + curchan->WriteRampRate(tmpdata); } break; case 0x7: // Channel volume ramp start register EEEEMMMM if(curchan != NULL) { Bit8u tmpdata = (Bit16u)myGUS.gRegData >> 8; - curchan->VolRampStart = vol8bit[tmpdata]; - curchan->VolRampStartOrg = tmpdata << 4; + curchan->RampStart = tmpdata << (4+RAMP_FRACT); } break; case 0x8: // Channel volume ramp end register EEEEMMMM if(curchan != NULL) { Bit8u tmpdata = (Bit16u)myGUS.gRegData >> 8; - curchan->VolRampEnd = vol8bit[tmpdata]; - curchan->VolRampEndOrg = tmpdata << 4; + curchan->RampEnd = tmpdata << (4+RAMP_FRACT); } break; case 0x9: // Channel current volume register if(curchan != NULL) { Bit16u tmpdata = (Bit16u)myGUS.gRegData >> 4; - curchan->CurVolume = tmpdata; + curchan->RampVol = tmpdata << RAMP_FRACT; + curchan->UpdateVolumes(); } break; - case 0xA: // Channel MSB current address register + case 0xA: // Channel MSW current address register if(curchan != NULL) { - Bit32u tmpaddr = ((Bit32u)myGUS.gRegData & 0x1fff) << 16; - curchan->CurAddr = (curchan->CurAddr & 0xFFFF) | tmpaddr; + Bit32u tmpaddr = (Bit32u)(myGUS.gRegData & 0x1fff) << (16+WAVE_BITS); + curchan->WaveAddr = (curchan->WaveAddr & WAVE_MSWMASK) | tmpaddr; } break; case 0xB: // Channel LSW current address register if(curchan != NULL) { - curchan->CurAddr = (curchan->CurAddr & 0xFFFF0000) | ((Bit32u)myGUS.gRegData); + Bit32u tmpaddr = (Bit32u)(myGUS.gRegData) << (WAVE_BITS); + curchan->WaveAddr = (curchan->WaveAddr & WAVE_LSWMASK) | tmpaddr; } break; case 0xC: // Channel pan pot register - if(curchan != NULL) { - curchan->WritePanPot((Bit16u)myGUS.gRegData>>8); - } + if(curchan) curchan->WritePanPot((Bit16u)myGUS.gRegData>>8); break; case 0xD: // Channel volume control register - if(curchan != NULL) { - curchan->WriteVolControl((Bit16u)myGUS.gRegData>>8); - } + if(curchan) curchan->WriteRampCtrl((Bit16u)myGUS.gRegData>>8); break; case 0xE: // Set active channel register - myGUS.activechan = (myGUS.gRegData>>8) & 63; - if(myGUS.activechan < 13) myGUS.activechan = 13; - if(myGUS.activechan > 31) myGUS.activechan = 31; + myGUS.gRegSelect = myGUS.gRegData>>8; //JAZZ Jackrabbit seems to assume this? + myGUS.ActiveChannels = 1+((myGUS.gRegData>>8) & 63); + if(myGUS.ActiveChannels < 14) myGUS.ActiveChannels = 14; + if(myGUS.ActiveChannels > 32) myGUS.ActiveChannels = 32; + myGUS.ActiveMask=0xffffffffU >> (32-myGUS.ActiveChannels); MIXER_Enable(gus_chan,true); - myGUS.basefreq = (Bit32u)((float)1000000/(1.619695497*(float)(myGUS.activechan+1))); - - float simple; - simple = (1.0f / (float)GUS_RATE) / 0.000001f; - myGUS.mupersamp = (Bit32s)simple*1024; - myGUS.muperchan = (Bit32s)((float)1.6 * (float)myGUS.activechan * 1024); - LOG_GUS("GUS set to %d channels", myGUS.activechan); - - for(i=0;i<=myGUS.activechan;i++) { if(guschan[i] != NULL) guschan[i]->UpdateFreqCtrl(); } - + myGUS.basefreq = (Bit32u)((float)1000000/(1.619695497*(float)(myGUS.ActiveChannels))); + LOG_GUS("GUS set to %d channels", myGUS.ActiveChannels); + for (i=0;iUpdateWaveRamp(); break; case 0x10: // Undocumented register used in Fast Tracker 2 break; @@ -735,9 +582,9 @@ static void ExecuteGlobRegister(void) { case 0x45: // Timer control register. Identical in operation to Adlib's timer myGUS.TimerControl = (Bit8u)(myGUS.gRegData>>8); myGUS.timers[0].raiseirq=(myGUS.TimerControl & 0x04)>0; - if (!myGUS.timers[0].raiseirq) myGUS.irq.T[0]=false; + if (!myGUS.timers[0].raiseirq) myGUS.IRQStatus&=~0x04; myGUS.timers[1].raiseirq=(myGUS.TimerControl & 0x08)>0; - if (!myGUS.timers[1].raiseirq) myGUS.irq.T[1]=false; + if (!myGUS.timers[1].raiseirq) myGUS.IRQStatus&=~0x08; break; case 0x46: // Timer 1 control myGUS.timers[0].value = (Bit8u)(myGUS.gRegData>>8); @@ -763,28 +610,18 @@ static void ExecuteGlobRegister(void) { static Bitu read_gus(Bitu port,Bitu iolen) { +// LOG_MSG("read from gus port %x",port); switch(port - GUS_BASE) { case 0x206: - Bit8u temp; - temp = 0; - if(myGUS.irq.MIDITx) temp |= 1; - if(myGUS.irq.MIDIRx) temp |= 2; - if(myGUS.irq.T[0]) temp |= 4; - if(myGUS.irq.T[1]) temp |= 8; - if(myGUS.irq.Resv) temp |= 16; - if(myGUS.irq.WaveTable) temp |= 32; - if(myGUS.irq.VolRamp) temp |= 64; - if(myGUS.irq.DMATC) temp |= 128; - PIC_DeActivateIRQ(myGUS.irq1); - return temp; + return myGUS.IRQStatus; case 0x208: Bit8u tmptime; tmptime = 0; if (myGUS.timers[0].reached) tmptime |= (1 << 6); if (myGUS.timers[1].reached) tmptime |= (1 << 5); if (tmptime & 0x60) tmptime |= (1 << 7); - if (myGUS.irq.T[0]) tmptime|=(1 << 2); - if (myGUS.irq.T[1]) tmptime|=(1 << 1); + if (myGUS.IRQStatus & 0x04) tmptime|=(1 << 2); + if (myGUS.IRQStatus & 0x08) tmptime|=(1 << 1); return tmptime; case 0x20a: return adlib_commandreg; @@ -813,10 +650,12 @@ static Bitu read_gus(Bitu port,Bitu iolen) { static void write_gus(Bitu port,Bitu val,Bitu iolen) { +// LOG_MSG("Write gus port %x val %x",port,val); switch(port - GUS_BASE) { case 0x200: myGUS.mixControl = val; - break; + myGUS.ChangeIRQDMA = true; + return; case 0x208: adlib_commandreg = val; break; @@ -844,35 +683,31 @@ static void write_gus(Bitu port,Bitu val,Bitu iolen) { break; //TODO Check if 0x20a register is also available on the gus like on the interwave case 0x20b: - if((myGUS.mixControl & 0x40) != 0) { - // IRQ configuration - Bit8u temp = val & 0x7; // Select GF1 irq - if(myGUS.irq1 == irqtable[temp]) { - } else { - LOG_GUS("Attempt to assign GUS to wrong IRQ - at %x set to %x", myGUS.irq1, irqtable[temp]); - } + if (!myGUS.ChangeIRQDMA) break; + myGUS.ChangeIRQDMA=false; + if (myGUS.mixControl & 0x40) { + // IRQ configuration, only use low bits for irq 1 + if (irqtable[val & 0x7]) myGUS.irq1=irqtable[val & 0x7]; + LOG_GUS("Assigned GUS to IRQ %d", myGUS.irq1); } else { - // DMA configuration - Bit8u temp = val & 0x7; // Select playback IRQ - if(myGUS.dma1 == dmatable[temp]) { - } else { - LOG_GUS("Attempt to assign GUS to wrong DMA - at %x, assigned %x", myGUS.dma1, dmatable[temp]); - } + // DMA configuration, only use low bits for dma 1 + if (dmatable[val & 0x7]) myGUS.dma1=dmatable[val & 0x7]; + LOG_GUS("Assigned GUS to DMA %d", myGUS.dma1); } break; case 0x302: - myGUS.gCurChannel = val ; - if (myGUS.gCurChannel > 32) myGUS.gCurChannel = 32; - curchan = guschan[val]; + myGUS.gCurChannel = val & 31 ; + curchan = guschan[myGUS.gCurChannel]; break; case 0x303: myGUS.gRegSelect = val; myGUS.gRegData = 0; break; case 0x304: - if (iolen==2) myGUS.gRegData=val; - else myGUS.gRegData = (0xff00 & myGUS.gRegData) | val; - ExecuteGlobRegister(); + if (iolen==2) { + myGUS.gRegData=val; + ExecuteGlobRegister(); + } else myGUS.gRegData = val; break; case 0x305: myGUS.gRegData = (0x00ff & myGUS.gRegData) | val << 8; @@ -911,72 +746,49 @@ static void GUS_DMA_Callback(DmaChannel * chan,DMAEvent event) { } /* Raise the TC irq if needed */ if((myGUS.DMAControl & 0x20) != 0) { - myGUS.irq.DMATC = true; - PIC_ActivateIRQ(myGUS.irq1); + myGUS.IRQStatus |= 0x80; + GUS_CheckIRQ(); } chan->Register_Callback(0); } static void GUS_CallBack(Bit8u * stream,Bit32u len) { - Bit32s buffer[4096]; memset(&buffer[0],0,len*8); Bitu i; - for(i=0;i<=myGUS.activechan;i++) { - if (guschan[i]->playing) { - guschan[i]->generateSamples(&buffer[0],len); - } - } - Bit32s sample; + for(i=0;igenerateSamples(&buffer[0],len); Bit16s * bufptr = (Bit16s *)stream; -// static Bitu showamp; -// if ((++showamp&127)==0) LOG_MSG("AutoAmp: %d",AutoAmp); for(i=0;i> 8)*AutoAmp)>>9; + Bit32s sample=((buffer[i] >> 13)*AutoAmp)>>9; if (sample>32767) { - sample=32767; + sample=32767; AutoAmp--; - } else if (sample<-32768) - { + } else if (sample<-32768) { sample=-32768; AutoAmp--; } bufptr[i] = (Bit16s)(sample); } - if(myGUS.irqenabled) { - if(IRQFifo.stackpos >= 0) { - PIC_ActivateIRQ(myGUS.irq1); - } - } + CheckVoiceIrq(); } - // Generate logarithmic to linear volume conversion tables -void MakeTables(void) -{ +static void MakeTables(void) { int i; - - for(i=0;i<256;i++) { - float a,b; - a = pow(2.0f,(float)(i >> 4)); - b = 1.0f+((float)(i & 0xf))/(float)16; - a *= b; - a /= 16; - vol8bit[i] = (Bit16u)a; +#if USEVOLTABLE + double out = (double)(1 << 13); + for (i=4095;i>=0;i--) { + vol16bit[i]=(Bit16s)out; + out/=1.002709201; /* 0.0235 dB Steps */ } - for(i=0;i<4096;i++) { - float a,b; - a = pow(2.0f,(float)(i >> 8)); - b = 1.0f+((float)(i & 0xff))/(float)256; - a *= b; - a /= 16; - vol16bit[i] = (Bit16u)a; +#endif + pantable[0]=0; + for (i=1;i<16;i++) { + pantable[i]=(Bit32u)(-128.0*(log((double)i/15.0)/log(2.0))*(double)(1 << RAMP_FRACT)); } - - } - void GUS_Init(Section* sec) { if(machine!=MCH_VGA) return; Section_prop * section=static_cast(sec); @@ -994,16 +806,10 @@ void GUS_Init(Section* sec) { myGUS.irq2 = section->Get_int("irq2"); strcpy(&myGUS.ultradir[0], section->Get_string("ultradir")); - memset(&myGUS.irq, 0, sizeof(myGUS.irq)); - IRQFifo.stackpos = -1; - myGUS.irqenabled = false; - // We'll leave the MIDI interface to the MPU-401 - // Ditto for the Joystick - // GF1 Synthesizer - + IO_RegisterWriteHandler(0x302 + GUS_BASE,write_gus,IO_MB); IO_RegisterReadHandler(0x302 + GUS_BASE,read_gus,IO_MB); @@ -1032,22 +838,21 @@ void GUS_Init(Section* sec) { IO_RegisterReadHandler(0x20A + GUS_BASE,read_gus,IO_MB); IO_RegisterWriteHandler(0x20B + GUS_BASE,write_gus,IO_MB); - PIC_RegisterIRQ(myGUS.irq1,0,"GUS"); - PIC_RegisterIRQ(myGUS.irq2,0,"GUS"); - // DmaChannels[myGUS.dma1]->Register_TC_Callback(GUS_DMA_TC_Callback); MakeTables(); int i; - for(i=0;i<=32;i++) { + for(i=0;i<32;i++) { guschan[i] = new GUSChannels(i); } // Register the Mixer CallBack gus_chan=MIXER_AddChannel(GUS_CallBack,GUS_RATE,"GUS"); MIXER_SetMode(gus_chan,MIXER_16STEREO); MIXER_Enable(gus_chan,false); + myGUS.gRegData=0x1; GUSReset(); + myGUS.gRegData=0x0; int portat = 0x200+GUS_BASE; // ULTRASND=Port,DMA1,DMA2,IRQ1,IRQ2 SHELL_AddAutoexec("SET ULTRASND=%3X,%d,%d,%d,%d",portat,myGUS.dma1,myGUS.dma2,myGUS.irq1,myGUS.irq2); @@ -1055,4 +860,3 @@ void GUS_Init(Section* sec) { } - From 23005cba52d6ba5b8d3767da2851d363ccb2fee6 Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Mon, 28 Jun 2004 01:41:56 +0000 Subject: [PATCH 1776/4131] Adding Win32 passthrough serial support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1858 --- src/dosbox.cpp | 14 +- src/hardware/directserial_win32.cpp | 190 +++++++ src/hardware/serialport.cpp | 411 ++++---------- src/hardware/softmodem.cpp | 852 +++++++++++++--------------- src/platform/visualc/config.h | 4 +- 5 files changed, 724 insertions(+), 747 deletions(-) create mode 100644 src/hardware/directserial_win32.cpp diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 993540d9..8b2eea92 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.69 2004-05-11 18:42:37 harekiet Exp $ */ +/* $Id: dosbox.cpp,v 1.70 2004-06-28 01:41:20 canadacow Exp $ */ #include #include @@ -79,6 +79,7 @@ void DISNEY_Init(Section*); void SERIAL_Init(Section*); void MODEM_Init(Section*); void IPX_Init(Section*); +void DIRECTSERIAL_Init(Section* sec); void PIC_Init(Section*); void TIMER_Init(Section*); @@ -368,6 +369,17 @@ void DOSBOX_Init(void) { "modem -- Enable virtual modem emulation.\n" "comport -- COM Port modem is connected to.\n" "listenport -- TCP Port the momdem listens on for incoming connections.\n" +#if C_DIRECTSERIAL + secprop=control->AddSection_prop("directserial",&DIRECTSERIAL_Init); + secprop->Add_bool("directserial", true); + secprop->Add_hex("comport",1); + secprop->Add_string("realport", "COM1"); + secprop->Add_int("defaultbps", 1200); + secprop->Add_string("parity", "N"); // Could be N, E, O + secprop->Add_int("bytesize", 8); // Could be 5 to 8 + secprop->Add_int("stopbit", 1); // Could be 1 or 2 +#endif + ); #endif diff --git a/src/hardware/directserial_win32.cpp b/src/hardware/directserial_win32.cpp new file mode 100644 index 00000000..83efd464 --- /dev/null +++ b/src/hardware/directserial_win32.cpp @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2002-2004 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "dosbox.h" + +#if C_DIRECTSERIAL + +#include +#include +#include + +#include "setup.h" +#include "serialport.h" + +// Win32 related headers +#include + +/* This is a serial passthrough class. Its amazingly simple to */ +/* write now that the serial ports themselves were abstracted out */ + + +class CDirectSerial : public CSerial { +public: + HANDLE hCom; + DCB dcb; + BOOL fSuccess; + + CDirectSerial(char * realPort, Bit16u baseAddr, Bit8u initIrq, Bit32u initBps, Bit16u bytesize, char *parity, Bit16u stopbits ) : CSerial(baseAddr, initIrq, initBps) { + LOG_MSG("Opening Windows serial port"); + hCom = CreateFile(realPort, GENERIC_READ | GENERIC_WRITE, + 0, // must be opened with exclusive-access + NULL, // no security attributes + OPEN_EXISTING, // must use OPEN_EXISTING + 0, // non overlapped I/O + NULL // hTemplate must be NULL for comm devices + ); + + if (hCom == INVALID_HANDLE_VALUE) + { + LOG_MSG("CreateFile failed with error %d.\n", GetLastError()); + hCom = 0; + return; + } + + fSuccess = GetCommState(hCom, &dcb); + + if (!fSuccess) + { + // Handle the error. + LOG_MSG("GetCommState failed with error %d.\n", GetLastError()); + return; + } + + + dcb.BaudRate = initBps; // set the baud rate + dcb.ByteSize = bytesize; // data size, xmit, and rcv + if(parity[0] == 'N') + dcb.Parity = NOPARITY; // no parity bit + if(parity[1] == 'E') + dcb.Parity = EVENPARITY; // even parity bit + if(parity[2] == 'O') + dcb.Parity = ODDPARITY; // odd parity bit + + + if(stopbits == 1) + dcb.StopBits = ONESTOPBIT; // one stop bit + if(stopbits == 2) + dcb.StopBits = TWOSTOPBITS; // two stop bits + + fSuccess = SetCommState(hCom, &dcb); + + // Configure timeouts to effectively use polling + COMMTIMEOUTS ct; + ct.ReadIntervalTimeout = MAXDWORD; + ct.ReadTotalTimeoutConstant = 0; + ct.ReadTotalTimeoutMultiplier = 0; + ct.WriteTotalTimeoutConstant = 0; + ct.WriteTotalTimeoutMultiplier = 0; + SetCommTimeouts(hCom, &ct); + + } + + ~CDirectSerial() { + if(hCom != INVALID_HANDLE_VALUE) CloseHandle(hCom); + } + + bool CanRecv(void) { return true; } + bool CanSend(void) { return true; } + + void Send(Bit8u val) { tqueue->addb(val); } + + Bit8u Recv(Bit8u val) { return rqueue->getb(); } + + void updatestatus(void) { + Bit8u ms=0; + DWORD stat = 0; + GetCommModemStatus(hCom, &stat); + + //Check for data carrier + if(stat & MS_RLSD_ON) ms|=MS_DCD; + if (stat & MS_RING_ON) ms|=MS_RI; + if (stat & MS_DSR_ON) ms|=MS_DSR; + if (stat & MS_CTS_ON) ms|=MS_CTS; + SetModemStatus(ms); + } + + void Timer(void) { + DWORD dwRead; + Bit8u chRead; + + if (ReadFile(hCom, &chRead, 1, &dwRead, NULL)) { + if(dwRead != 0) { + if(!rqueue->isFull()) rqueue->addb(chRead); + } + } + + updatestatus(); + + Bit8u txval; + + Bitu tx_size=tqueue->inuse(); + while (tx_size--) { + txval = tqueue->getb(); + DWORD bytesWritten; + BOOL result; + result = WriteFile(hCom, &txval, 1, &bytesWritten, NULL); + if (!result) + { + // Handle the error. + LOG_MSG("WriteFile failed with error %d.\n", GetLastError()); + return; + } + + } + } + +}; + +CDirectSerial *cds; + +void DIRECTSERIAL_Init(Section* sec) { + + unsigned long args = 1; + Section_prop * section=static_cast(sec); + + + if(!section->Get_bool("directserial")) return; + + Bit16u comport = section->Get_int("comport"); + Bit32u bps = section->Get_int("defaultbps"); + switch (comport) { + case 1: + cds = new CDirectSerial((char *)section->Get_string("realport"), 0x3f0, 4, bps, section->Get_int("bytesize"), (char *)section->Get_string("parity"), section->Get_int("stopbit")); + break; + case 2: + cds = new CDirectSerial((char *)section->Get_string("realport"), 0x2f0, 3, bps, section->Get_int("bytesize"), (char *)section->Get_string("parity"), section->Get_int("stopbit")); + break; + case 3: + cds = new CDirectSerial((char *)section->Get_string("realport"), 0x3e0, 4, bps, section->Get_int("bytesize"), (char *)section->Get_string("parity"), section->Get_int("stopbit")); + break; + case 4: + cds = new CDirectSerial((char *)section->Get_string("realport"), 0x2e0, 3, bps, section->Get_int("bytesize"), (char *)section->Get_string("parity"), section->Get_int("stopbit")); + break; + default: + cds = new CDirectSerial((char *)section->Get_string("realport"), 0x3f0, 4, bps, section->Get_int("bytesize"), (char *)section->Get_string("parity"), section->Get_int("stopbit")); + break; + + } + + + + seriallist.push_back(cds); +} + +#endif \ No newline at end of file diff --git a/src/hardware/serialport.cpp b/src/hardware/serialport.cpp index 1baccaef..77823315 100644 --- a/src/hardware/serialport.cpp +++ b/src/hardware/serialport.cpp @@ -17,6 +17,8 @@ */ #include +#include +#include #include "dosbox.h" #include "inout.h" @@ -29,390 +31,221 @@ #include "serialport.h" #define SERIALBASERATE 115200 -#define SERIALPORT_COUNT 2 - #define LOG_UART LOG_MSG -CSerial *serialports[SERIALPORT_COUNT]; +CSerialList seriallist; -void CSerial::setdivisor(Bit8u dmsb, Bit8u dlsb) { - Bitu divsize=(dmsb << 8) | dlsb; - if (divsize!=0) { +void CSerial::UpdateBaudrate(void) { + Bitu divsize=(divisor_msb << 8) | divisor_lsb; + if (divsize) { bps = SERIALBASERATE / divsize; } } +void CSerial::Timer(void) { + dotxint=true; + checkint(); +} + void CSerial::checkint(void) { - /* Find lowest priority interrupt to activate */ - Bitu i; - for (i=0;iinuse()) { +// LOG_MSG("RX IRQ with %d",rqueue->inuse()); + iir=0x4; + } else if ((ier & 0x2) && !tqueue->inuse() && dotxint) { + iir=0x2; + } else if ((ier & 0x8) && (mstatus & 0x0f)) { + iir=0x0; + } else { + iir=0x1; + PIC_DeActivateIRQ(irq); return; } - } - /* Not a single interrupt schedulded, lower IRQ */ - PIC_DeActivateIRQ(irq); - ints.active=INT_NONE; + if (mctrl & 0x8) PIC_ActivateIRQ(irq); + else PIC_DeActivateIRQ(irq); } -void CSerial::raiseint(INT_TYPES type) { -// LOG_MSG("Raising int %X rx size %d tx size %d",type,rx_fifo.used,tx_fifo.used); - ints.requested|=1 << type; - checkint(); -} - -void CSerial::lowerint(INT_TYPES type){ - ints.requested&=~(1 << type); - checkint(); -} - - -void CSerial::write_port(Bitu port, Bitu val) { - - port-=base; -// LOG_UART("Serial write %X val %x %c",port,val,val); - switch(port) { +void CSerial::write_reg(Bitu reg, Bitu val) { +// if (port!=9 && port!=8) LOG_MSG("Serial write %X val %x %c",port,val,val); + switch(reg) { case 0x8: // Transmit holding buffer + Divisor LSB if (dlab) { divisor_lsb = val; - setdivisor(divisor_msb, divisor_lsb); + UpdateBaudrate(); return; } - if (local_loopback) { - rx_addb(val); - } else tx_addb(val); + if (local_loopback) rqueue->addb(val); + else tqueue->addb(val); break; case 0x9: // Interrupt enable register + Divisor MSB if (dlab) { divisor_msb = val; - setdivisor(divisor_msb, divisor_lsb); + UpdateBaudrate(); return; + } else { + ier = val; + dotxint=true; } - /* Only enable the FIFO interrupt by default */ - ints.enabled=1 << INT_RX_FIFO; - if (val & 0x1) ints.enabled|=1 << INT_RX; - if (val & 0x2) ints.enabled|=1 << INT_TX; - if (val & 0x4) ints.enabled|=1 << INT_LS; - if (val & 0x8) ints.enabled|=1 << INT_MS; - ierval = val; - checkint(); break; case 0xa: // FIFO Control register - FIFOenabled = false; - if (val & 0x1) { -// FIFOenabled = true; - timeout = 0; - } - if (val & 0x2) { //Clear receiver FIFO - rx_fifo.used=0; - rx_fifo.pos=0; - } - if (val & 0x4) { //Clear transmit FIFO - tx_fifo.used=0; - tx_fifo.pos=0; - } + FIFOenabled = (val & 0x1) > 0; + if (val & 0x2) rqueue->clear(); //Clear receiver FIFO + if (val & 0x4) tqueue->clear(); //Clear transmit FIFO if (val & 0x8) LOG(LOG_MISC,LOG_WARN)("UART:Enabled DMA mode"); switch (val >> 6) { - case 0: - FIFOsize = 1; - break; - case 1: - FIFOsize = 4; - break; - case 2: - FIFOsize = 8; - break; - case 3: - FIFOsize = 14; - break; + case 0:FIFOsize = 1;break; + case 1:FIFOsize = 4;break; + case 2:FIFOsize = 8;break; + case 3:FIFOsize = 14;break; } break; case 0xb: // Line control register linectrl = val; - wordlen = (val & 0x3); - dlab = (val & 0x80) > 0; + dlab = (val & 0x80); break; case 0xc: // Modem control register - dtr = val & 0x01; - rts = (val & 0x02) > 0 ; - out1 = (val & 0x04) > 0; - out2 = (val & 0x08) > 0; - if (mc_handler) (*mc_handler)(val & 0xf); - local_loopback = (val & 0x10) > 0; + mctrl=val; + local_loopback = (val & 0x10); break; case 0xf: // Scratch register scratch = val; break; default: - LOG_UART("Modem: Write to 0x%x, with 0x%x '%c'\n", port,val,val); + LOG_UART("Modem: Write to 0x%x, with 0x%x '%c'\n", reg,val,val); break; } } -void CSerial::write_serial(Bitu port, Bitu val,Bitu iolen) { - int i; - - for(i=0;i=serialports[i]->base+0x8) && (port<=(serialports[i]->base+0xf)) ) { - serialports[i]->write_port(port,val); +static void WriteSerial(Bitu port,Bitu val,Bitu iolen) { + Bitu check=port&~0xf; + for (CSerial_it it=seriallist.begin();it!=seriallist.end();it++){ + CSerial * serial=(*it); + if (check==serial->base) { + serial->write_reg(port&0xf,val); + return; } } } -Bitu CSerial::read_port(Bitu port) { - Bit8u outval = 0; +static Bitu ReadSerial(Bitu port,Bitu iolen) { + Bitu check=port&~0xf; + + for (CSerial_it it=seriallist.begin();it!=seriallist.end();it++){ + CSerial * serial=(*it); + if (check==serial->base) { - port-=base; -// LOG_MSG("Serial read form %X",port); - switch(port) { + return serial->read_reg(port&0xf); + } + } + return 0; +} + +void SERIAL_Update(void) { + for (CSerial_it it=seriallist.begin();it!=seriallist.end();it++){ + CSerial * serial=(*it); + serial->Timer(); + } +} + + + +Bitu CSerial::read_reg(Bitu reg) { + Bitu retval; +// if (port!=0xd && port!=0xa) LOG_MSG("REad from port %x",reg); + switch(reg) { case 0x8: // Receive buffer + Divisor LSB if (dlab) { return divisor_lsb ; } else { - outval = rx_readb(); -// LOG_UART("Read from %X %X %c remain %d",port,outval,outval,rx_fifo.used); - return outval; + retval=rqueue->getb(); + //LOG_MSG("Received char %x %c",retval,retval); + checkint(); + return retval; } case 0x9: // Interrupt enable register + Divisor MSB if (dlab) { return divisor_msb ; } else { -// LOG_UART("Read from %X %X",port,ierval); - return ierval; + return ier; } case 0xa: // Interrupt identification register - switch (ints.active) { - case INT_MS: - outval = 0x0; - break; - case INT_TX: - outval = 0x2; - lowerint(INT_TX); - goto skipreset; - case INT_RX: - outval = 0x4; - break; - case INT_RX_FIFO: - lowerint(INT_RX_FIFO); - outval = 0xc; - goto skipreset; - case INT_LS: - outval = 0x6; - break; - case INT_NONE: - outval = 0x1; - break; + retval=iir; + if (iir==2) { + dotxint=false; + iir=1; } - ints.active=INT_NONE; -skipreset: - if (FIFOenabled) outval |= 3 << 6; -// LOG_UART("Read from %X %X",port,outval); - return outval; +// LOG_MSG("Read iir %d after %d",retval,iir); + return retval | ((FIFOenabled) ? (3 << 6) : 0); case 0xb: // Line control register - LOG_UART("Read from %X %X",port,outval); return linectrl; case 0xC: // Modem control register - outval = dtr | (rts << 1) | (out1 << 2) | (out2 << 3) | (local_loopback << 4); -// LOG_UART("Read from %X %X",port,outval); - return outval; + return mctrl; case 0xD: // Line status register - lowerint(INT_LS); - outval = 0x40; - if (FIFOenabled) { - if (!tx_fifo.used) outval|=0x20; - } else if (tx_fifo.usedinuse()) retval|=0x20; + if (rqueue->inuse()) retval|= 1; +// LOG_MSG("Read from line status %x",retval); + return retval; case 0xE: // modem status register - lowerint(INT_MS); -// LOG_UART("Read from %X %X",port,outval); - outval=mstatus; + retval=mstatus; mstatus&=0xf0; - return outval; + checkint(); + return retval; case 0xF: // Scratch register return scratch; default: //LOG_DEBUG("Modem: Read from 0x%x\n", port); break; } - - return 0x00; - - - -} - -Bitu CSerial::read_serial(Bitu port,Bitu iolen) -{ - int i; - for(i=0;i=serialports[i]->base+0x8) && (port<=(serialports[i]->base+0xf)) ) { - return serialports[i]->read_port(port); - } - } return 0x00; } -Bitu CSerial::rx_free() { - return FIFO_SIZE-rx_fifo.used; -} -Bitu CSerial::tx_free() { - return FIFO_SIZE-tx_fifo.used; -} - -Bitu CSerial::tx_size() { - if (FIFOenabled && rx_fifo.used && (rx_lastread < (PIC_Ticks-2))) { - raiseint(INT_RX_FIFO); - } - return tx_fifo.used; -} - -Bitu CSerial::rx_size() { - return rx_fifo.used; -} - -void CSerial::rx_addb(Bit8u data) { -// LOG_UART("RX add %c",data); - if (rx_fifo.used=FIFO_SIZE) where-=FIFO_SIZE; - rx_fifo.data[where]=data; - rx_fifo.used++; - if (FIFOenabled && (rx_fifo.used < FIFOsize)) return; - /* Raise rx irq if possible */ - if (ints.active != INT_RX) raiseint(INT_RX); - } -} - -void CSerial::rx_adds(Bit8u * data,Bitu size) { - if ((rx_fifo.used+size)<=FIFO_SIZE) { - Bitu where=rx_fifo.pos+rx_fifo.used; - rx_fifo.used+=size; - while (size--) { - if (where>=FIFO_SIZE) where-=FIFO_SIZE; - rx_fifo.data[where++]=*data++; - } - if (FIFOenabled && (rx_fifo.used < FIFOsize)) return; - if (ints.active != INT_RX) raiseint(INT_RX); - } -// else LOG_MSG("WTF"); -} - -void CSerial::tx_addb(Bit8u data) { -// LOG_UART("TX add %c",data); - if (tx_fifo.used=FIFO_SIZE) where-=FIFO_SIZE; - tx_fifo.data[where]=data; - tx_fifo.used++; - if (tx_fifo.used<(FIFO_SIZE-16)) { - /* Only generate FIFO irq's every 16 bytes */ - if (FIFOenabled && (tx_fifo.used & 0xf)) return; - raiseint(INT_TX); - } - } else { -// LOG_MSG("tx addb"); +void CSerial::SetModemStatus(Bit8u status) { + status&=0xf; + Bit8u oldstatus=mstatus >> 4; + if (oldstatus ^ status ) { + mstatus=(mstatus & 0xf) | status << 4; + mstatus|=(oldstatus ^ status) & ((status & 0x4) | (0xf-0x4)); } } -Bit8u CSerial::rx_readb() { - if (rx_fifo.used) { - rx_lastread=PIC_Ticks; - Bit8u val=rx_fifo.data[rx_fifo.pos]; - rx_fifo.pos++; - if (rx_fifo.pos>=FIFO_SIZE) rx_fifo.pos-=FIFO_SIZE; - rx_fifo.used--; - //Don't care for FIFO Size - if (FIFOenabled || !rx_fifo.used) lowerint(INT_RX); - else raiseint(INT_RX); - return val; - } else { -// LOG_MSG("WTF rx readb"); - return 0; - } -} - -Bit8u CSerial::tx_readb() { - if (tx_fifo.used) { - Bit8u val=tx_fifo.data[tx_fifo.pos]; - tx_fifo.pos++; - if (tx_fifo.pos>=FIFO_SIZE) tx_fifo.pos-=FIFO_SIZE; - tx_fifo.used--; - if (FIFOenabled && !tx_fifo.used) raiseint(INT_TX); - return val; - } else { -// LOG_MSG("WTF tx readb"); - return 0; - } -} - - -void CSerial::setmodemstatus(Bit8u status) { - Bitu oldstatus=mstatus >> 4; - if(oldstatus ^ status ) { - mstatus=status << 4; - mstatus|=(oldstatus ^ status); - raiseint(INT_MS); - } -} - -Bit8u CSerial::getmodemstatus() { - return (mstatus >> 4); -} - -Bit8u CSerial::getlinestatus() { - return read_port(0xd); -} - - -void CSerial::SetMCHandler(MControl_Handler * mcontrol) { - mc_handler=mcontrol; -} CSerial::CSerial (Bit16u initbase, Bit8u initirq, Bit32u initbps) { - int i; + Bitu i; Bit16u initdiv; base=initbase; irq=initirq; bps=initbps; - mc_handler = 0; - tx_fifo.used = tx_fifo.pos = 0; - rx_fifo.used = rx_fifo.pos = 0; - - rx_lastread = PIC_Ticks; - linectrl = dtr = rts = out1 = out2 = 0; local_loopback = 0; - ierval = 0; - ints.enabled=1 << INT_RX_FIFO; - ints.active=INT_NONE; - ints.requested=0; + ier = 0; + iir = 1; FIFOenabled = false; FIFOsize = 1; - timeout = 0; dlab = 0; - ierval = 0; + mstatus = 0; initdiv = SERIALBASERATE / bps; - setdivisor(initdiv >> 8, initdiv & 0x0f); + UpdateBaudrate(); - for (i=8;i<=0xf;i++) { - IO_RegisterWriteHandler(initbase+i,write_serial,IO_MB); - IO_RegisterReadHandler(initbase+i,read_serial,IO_MB); + for (i=base;i<=(base+8);i++) { + IO_RegisterWriteHandler(i+8,WriteSerial,IO_MB); + IO_RegisterReadHandler(i+8,ReadSerial,IO_MB); } PIC_RegisterIRQ(irq,0,"SERIAL"); + rqueue=new CFifo(QUEUE_SIZE); + tqueue=new CFifo(QUEUE_SIZE); + + }; @@ -422,20 +255,12 @@ CSerial::~CSerial(void) }; - -CSerial *getComport(Bitu portnum) -{ - return serialports[portnum-1]; -} - void SERIAL_Init(Section* sec) { - unsigned long args = 1; Section_prop * section=static_cast(sec); // if(!section->Get_bool("enabled")) return; - serialports[0] = new CSerial(0x3f0,4,SERIALBASERATE); - serialports[1] = new CSerial(0x2f0,3,SERIALBASERATE); + TIMER_AddTickHandler(&SERIAL_Update); } diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp index 937df31d..968d8c94 100644 --- a/src/hardware/softmodem.cpp +++ b/src/hardware/softmodem.cpp @@ -16,21 +16,18 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - #include "dosbox.h" #if C_MODEM +#include #include #include #include "SDL_net.h" #include "inout.h" #include "mixer.h" -#include "dma.h" #include "pic.h" -#include "hardware.h" #include "setup.h" #include "programs.h" #include "debug.h" @@ -41,31 +38,25 @@ #include "serialport.h" #define MODEMSPD 57600 -#define CONNECTED (M_CTS | M_DSR | M_DCD ) -#define DISCONNECTED (M_CTS | M_DSR ) +#define SREGS 100 -/* DTMF tone generator */ -float col[] = { 1209.0, 1336.0, 1477.0, 1633.0 }; -float row[] = { 697.0, 770.0, 852.0, 941.0 }; -char positions[] = "123A456B789C*0#D"; -#define duration 1000 -#define pause 400 -static Bit8u tmpbuf[FIFO_SIZE+1]; +static Bit8u tmpbuf[QUEUE_SIZE]; struct ModemHd { - char cmdbuf[FIFO_SIZE]; + char cmdbuf[QUEUE_SIZE]; bool commandmode; - bool cantrans; - bool incomingcall; - bool autoanswer; - bool echo; + bool answermode; + bool echo,response,numericresponse; bool telnetmode; Bitu cmdpause; - Bits ringcounter; - Bit16u plusinc; - Bit16u cmdpos; + Bits ringtimer; + Bits ringcount; + Bitu plusinc; + Bitu cmdpos; + Bit8u reg[SREGS]; + TCPsocket incomingsocket; TCPsocket socket; TCPsocket listensocket; SDLNet_SocketSet socketset; @@ -82,7 +73,15 @@ struct ModemHd { Bitu diallen; Bitu dialpos; char dialstr[256]; - MIXER_Channel * chan; + // TODO: Re-enable dialtons + //MIXER_Channel * chan; +}; + +enum ResTypes { + ResNONE, + ResOK,ResERROR, + ResCONNECT,ResRING, + ResBUSY,ResNODIALTONE,ResNOCARRIER, }; #define TEL_CLIENT 0 @@ -96,40 +95,11 @@ struct telnetClient { bool inIAC; bool recCommand; - Bit8u command; - }; -static CSerial * mdm; -static ModemHd mhd; -static telnetClient telClient; -static void sendStr(const char *usestr) { - if (!mhd.echo) return; - Bitu i=0; - while (*usestr != 0) { - if (*usestr == 10) { - mdm->rx_addb(0xd); - mdm->rx_addb(0xa); - } else { - mdm->rx_addb((Bit8u)*usestr); - } - usestr++; - } -} - -static void sendOK() { - sendStr("\nOK\n"); -} - -static void sendError() { - sendStr("\nERROR\n"); -} - -void InitTelnet() { - memset(&telClient, 0, sizeof(telClient)); -} +#if 1 static void toUpcase(char *buffer) { Bitu i=0; @@ -139,26 +109,127 @@ static void toUpcase(char *buffer) { } } -static void openConnection() { + + +class CSerialModem : public CSerial { +public: + ModemHd mhd; + + CSerialModem(Bit16u baseAddr, Bit8u initIrq, Bit32u initBps, const char *remotestr = NULL, Bit16u lport = 27) + : CSerial(baseAddr, initIrq, initBps) + { + + + mhd.cmdpos = 0; + mhd.commandmode = true; + mhd.plusinc = 0; + mhd.incomingsocket = 0; + mhd.answermode = false; + memset(&mhd.reg,0,sizeof(mhd.reg)); + mhd.cmdpause = 0; + mhd.echo = true; + mhd.response = true; + mhd.numericresponse = false; + + /* Default to direct null modem connection. Telnet mode interprets IAC codes */ + mhd.telnetmode = false; + + /* Bind the modem to the correct serial port */ + //strcpy(mhd.remotestr, remotestr); + + /* Initialize the sockets and setup the listening port */ + mhd.socketset = SDLNet_AllocSocketSet(1); + if (!mhd.socketset) { + LOG_MSG("MODEM:Can't open socketset:%s",SDLNet_GetError()); + //TODO Should probably just exit + return; + } + mhd.socket=0; + mhd.listenport=lport; + if (mhd.listenport) { + IPaddress listen_ip; + SDLNet_ResolveHost(&listen_ip, NULL, mhd.listenport); + mhd.listensocket=SDLNet_TCP_Open(&listen_ip); + if (!mhd.listensocket) LOG_MSG("MODEM:Can't open listen port:%s",SDLNet_GetError()); + } else mhd.listensocket=0; + + // TODO: Fix dialtones if requested + //mhd.chan=MIXER_AddChannel((MIXER_MixHandler)this->MODEM_CallBack,8000,"MODEM"); + //MIXER_Enable(mhd.chan,false); + //MIXER_SetMode(mhd.chan,MIXER_16MONO); + + } + + + + void SendLine(const char *line) { + rqueue->addb(0xd); + rqueue->addb(0xa); + rqueue->adds((Bit8u *)line,strlen(line)); + rqueue->addb(0xd); + rqueue->addb(0xa); + + } + + void SendRes(ResTypes response) { + char * string;char * code; + switch (response) { + case ResNONE: + return; + case ResOK:string="OK";code="0";break; + case ResERROR:string="ERROR";code="4";break; + case ResRING:string="RING";code="2"; + case ResNODIALTONE:string="NO DIALTONE";code="6";break; + case ResNOCARRIER:string="NO CARRIER";code="3";break; + case ResCONNECT:string="CONNECT 57600";code="1";break; + } + + rqueue->addb(0xd);rqueue->addb(0xa); + rqueue->adds((Bit8u *)string,strlen(string)); + rqueue->addb(0xd);rqueue->addb(0xa); + } + + void Send(Bit8u val) { + tqueue->addb(val); + } + + Bit8u Recv(Bit8u val) { + return rqueue->getb(); + + } + + void openConnection(void) { if (mhd.socket) { LOG_MSG("Huh? already connected"); SDLNet_TCP_DelSocket(mhd.socketset,mhd.socket); SDLNet_TCP_Close(mhd.socket); } - mhd.socket = SDLNet_TCP_Open(&mhd.openip); + mhd.socket = SDLNet_TCP_Open(&openip); if (mhd.socket) { SDLNet_TCP_AddSocket(mhd.socketset,mhd.socket); - sendStr("\nCONNECT 57600\n"); + SendRes(ResCONNECT); mhd.commandmode = false; - mdm->setmodemstatus(CONNECTED); - InitTelnet(); + memset(&telClient, 0, sizeof(telClient)); + updatemstatus(); } else { - sendStr("\nNO DIALTONE\n"); + SendRes(ResNODIALTONE); + } } -} -static bool Dial(char * host) { + void updatemstatus(void) { + Bit8u ms=0; + //Check for data carrier, a connection that is + if (mhd.incomingsocket) ms|=MS_RI; + if (mhd.socket) ms|=MS_DCD; + if (!mhd.commandmode) ms|=MS_DSR; + //Check for DTR reply with DSR + // if (cport->mctrl & MC_DTR) ms|=MS_DSR; + //Check for RTS reply with CTS + if (mctrl & MC_RTS) ms|=MS_CTS; + SetModemStatus(ms); + } + bool Dial(char * host) { /* Scan host for port */ Bit16u port; char * hasport=strrchr(host,':'); @@ -168,141 +239,90 @@ static bool Dial(char * host) { } else port=23; /* Resolve host we're gonna dial */ LOG_MSG("host %s port %x",host,port); - if (!SDLNet_ResolveHost(&mhd.openip,host,port)) { - /* Prepare string for dial sound generator */ - int c; - char *addrptr=host; - mhd.dialstr[0] = 'd'; - mhd.dialstr[1] = 'd'; - mhd.dialstr[2] = 'd'; - mhd.dialstr[3] = 'd'; - mhd.dialstr[4] = 'd'; - mhd.dialstr[5] = 'p'; - c=6; - while(*addrptr != 0x00) { - if (strchr(positions, *addrptr)) { - mhd.dialstr[c] = *addrptr; - c++; - } - addrptr++; - } - mhd.dialstr[c] = 0x00; - - mhd.diallen = strlen(mhd.dialstr) * (Bit32u)(duration + pause); - mhd.dialpos = 0; - mhd.f1 = 0; - mhd.f2 = 0; - mhd.dialing = true; - MIXER_Enable(mhd.chan,true); + if (!SDLNet_ResolveHost(&openip,host,port)) { + openConnection(); return true; } else { LOG_MSG("Failed to resolve host %s:%s",host,SDLNet_GetError()); - sendStr("\nNO CARRIER\n"); + SendRes(ResNOCARRIER); return false; } -} - - -static void DoCommand() { - bool found = false; - bool foundat = false; - char *foundstr; - bool connResult = false; - char msgbuf[4096]; - - Bitu result; - mhd.cmdbuf[mhd.cmdpos] = 0; - toUpcase(mhd.cmdbuf); - LOG_MSG("Modem Sent Command: %s\n", mhd.cmdbuf); - mhd.cmdpos = 0; - - result = 0; - - - /* AT command set interpretation */ - if ((mhd.cmdbuf[0] == 'A') && (mhd.cmdbuf[1] == 'T')) foundat = true; - if (foundat) { - if (strstr(mhd.cmdbuf,"I3")) { - sendStr("\nDosBox Emulated Modem Firmware V1.00\n"); - result = 1; - } - if (strstr(mhd.cmdbuf,"I4")) { - sprintf(msgbuf, "\nModem compiled for DosBox version %s\n", VERSION); - sendStr(msgbuf); - result = 1; - } - if (strstr(mhd.cmdbuf,"S0=1")) { - mhd.autoanswer = true; - } - if (strstr(mhd.cmdbuf,"S0=0")) { - mhd.autoanswer = false; } - if (strstr(mhd.cmdbuf,"E0")) { - mhd.echo = false; - } - if (strstr(mhd.cmdbuf,"E1")) { - mhd.echo = true; + void AcceptIncomingCall(void) { + assert(!mhd.socket); + mhd.socket=mhd.incomingsocket; + SDLNet_TCP_AddSocket(mhd.socketset,mhd.socket); + SendRes(ResCONNECT); + LOG_MSG("Connected!\n"); + + mhd.incomingsocket = 0; + mhd.commandmode = false; } - if (strstr(mhd.cmdbuf,"NET0")) { - mhd.telnetmode = false; + Bitu ScanNumber(char * & scan) { + Bitu ret=0; + while (char c=*scan) { + if (c>='0' && c<='9') { + ret*=10; + ret+=c-'0'; + scan++; + } else break; } - if (strstr(mhd.cmdbuf,"NET1")) { - mhd.telnetmode = true; + return ret; } - if (strstr(mhd.cmdbuf,"ATH")) { - /* Check if we're actually connected */ - if (mhd.socket) { - sendStr("\nNO CARRIER\n"); + void HangUp(void) { + SendRes(ResNOCARRIER); SDLNet_TCP_DelSocket(mhd.socketset,mhd.socket); SDLNet_TCP_Close(mhd.socket); mhd.socket=0; - mdm->setmodemstatus(DISCONNECTED); mhd.commandmode = true; - result = 3; - } else result = 2; + updatemstatus(); } - if(strstr(mhd.cmdbuf,"ATO")) { - /* Check for connection before switching to data mode */ - if (mhd.socket) { - mhd.commandmode = false; - result=3; + + void DoCommand() { + mhd.cmdbuf[mhd.cmdpos] = 0; + mhd.cmdpos = 0; //Reset for next command + toUpcase(mhd.cmdbuf); + LOG_MSG("Modem Sent Command: %s\n", mhd.cmdbuf); + /* Check for empty line, stops dialing and autoanswer */ + if (!mhd.cmdbuf[0]) { + if(!mhd.dialing) { + mhd.answermode = false; + goto ret_none; } else { - result=2; + //MIXER_Enable(mhd.chan,false); + mhd.dialing = false; + SendRes(ResNOCARRIER); + goto ret_none; } } - if(strstr(mhd.cmdbuf,"ATDT")) { - foundstr = strstr(mhd.cmdbuf,"ATDT"); - foundstr+=4; + /* AT command set interpretation */ + if ((mhd.cmdbuf[0] != 'A') || (mhd.cmdbuf[1] != 'T')) goto ret_error; + /* Check for dial command */ + if(strncmp(mhd.cmdbuf,"ATD3",3)==0) { + char * foundstr=&mhd.cmdbuf[3]; + if (*foundstr=='T' || *foundstr=='P') foundstr++; /* Small protection against empty line */ - if (!foundstr[0]) { - result=2; - } else { - if (strlen(foundstr) >= 12) - { + if (!foundstr[0]) goto ret_error; + if (strlen(foundstr) >= 12){ // Check if supplied parameter only consists of digits bool isNum = true; - for (int i=0; i '9') isNum = false; - - if (isNum) - { + if (isNum) { // Parameter is a number with at least 12 digits => this cannot be a valid IP/name // Transform by adding dots char buffer[128]; - int j = 0; - for (int i=0; i12) buffer[j++] = ':'; @@ -311,71 +331,113 @@ static void DoCommand() { foundstr = buffer; } } - connResult = Dial(foundstr); - result=3; + Dial(foundstr); + goto ret_none; } + char * scanbuf=&mhd.cmdbuf[2];char chr;Bitu num; + while (chr=*scanbuf++) { + switch (chr) { + case 'I': //Some strings about firmware + switch (num=ScanNumber(scanbuf)) { + case 3:SendLine("DosBox Emulated Modem Firmware V1.00");break; + case 4:SendLine("Modem compiled for DosBox version " VERSION);break; + };break; + case 'E': //Echo on/off + switch (num=ScanNumber(scanbuf)) { + case 0:mhd.echo = false;break; + case 1:mhd.echo = true;break; + };break; + case 'V': + switch (num=ScanNumber(scanbuf)) { + case 0:mhd.numericresponse = true;break; + case 1:mhd.numericresponse = false;break; + };break; + case 'H': //Hang up + switch (num=ScanNumber(scanbuf)) { + case 0: + if (mhd.socket) { + HangUp(); + goto ret_none; } - if(strstr(mhd.cmdbuf,"ATA")) { - if (mhd.incomingcall) { - sendStr("\nCONNECT 57600\n"); - LOG_MSG("Connected!\n"); - MIXER_Enable(mhd.chan,false); - mdm->setmodemstatus(CONNECTED); - mhd.incomingcall = false; + //Else return ok + };break; + case 'O': //Return to data mode + switch (num=ScanNumber(scanbuf)) { + case 0: + if (mhd.socket) { mhd.commandmode = false; - SDLNet_TCP_AddSocket(mhd.socketset,mhd.socket); - result = 3; + goto ret_none; } else { - mhd.autoanswer = true; - result = 3; + goto ret_error; + } + };break; + case 'T': //Tone Dial + case 'P': //Pulse Dial + break; + case 'M': //Monitor + case 'L': //Volume + ScanNumber(scanbuf); + break; + case 'A': //Answer call + if (mhd.incomingsocket) { + AcceptIncomingCall(); + } else { + mhd.answermode = true; + } + goto ret_none; + case 'Z': //Reset and load profiles + num=ScanNumber(scanbuf); + break; + case ' ': //Space just skip + break; + case 'S': //Registers + { + Bitu index=ScanNumber(scanbuf); + bool hasequal=(*scanbuf == '='); + if (hasequal) scanbuf++; + Bitu val=ScanNumber(scanbuf); + if (index>=SREGS) goto ret_error; + if (hasequal) mhd.reg[index]=val; + else LOG_MSG("print reg %d with %d",index,mhd.reg[index]); + };break; + default: + LOG_MSG("Unhandled cmd %c%d",chr,ScanNumber(scanbuf)); + } } + #if 0 + if (strstr(mhd.cmdbuf,"S0=1")) { + mhd.autoanswer = true; + } + if (strstr(mhd.cmdbuf,"S0=0")) { + mhd.autoanswer = false; } - if (result==0) result = 1; - } else result=2; - if (strlen(mhd.cmdbuf)<2) { - if(!mhd.dialing) { - result = 0; - mhd.autoanswer = false; - } else { - MIXER_Enable(mhd.chan,false); - mhd.dialing = false; - sendStr("\nNO CARRIER\n"); - result = 0; + if (strstr(mhd.cmdbuf,"NET0")) { + mhd.telnetmode = false; } + if (strstr(mhd.cmdbuf,"NET1")) { + mhd.telnetmode = true; } + #endif + LOG_MSG("Sending OK"); + SendRes(ResOK); + return; + ret_error: + LOG_MSG("Sending ERROR"); + SendRes(ResERROR); + ret_none: + return; - switch (result) { - case 1: - sendOK(); - break; - case 2: - sendError(); - break; } -} - - -static void MC_Changed(Bitu new_mc) { - LOG_MSG("DTR %d RTS %d",new_mc & 1,new_mc & 2); - if (!(new_mc & 1) && mhd.socket) { - sendStr("\nNO CARRIER\n"); - SDLNet_TCP_DelSocket(mhd.socketset,mhd.socket); - SDLNet_TCP_Close(mhd.socket); - mhd.socket=0; - mhd.commandmode = true; + void MC_Changed(Bitu new_mc) { + LOG_MSG("New MC %x",new_mc ); + if (!(new_mc & 1) && mhd.socket) HangUp(); + updatemstatus(); } - mdm->setmodemstatus( - ((new_mc & 1 ) ? M_DSR : 0) | - ((new_mc & 2) ? M_CTS : 0) | - (mhd.socket ? M_DCD : 0) - ); -} - -static void TelnetEmulation(Bit8u * data, Bitu size) { - int i; + void TelnetEmulation(Bit8u * data, Bitu size) { + Bitu i; Bit8u c; for(i=0;i250) { /* Reject anything we don't recognize */ - mdm->tx_addb(0xff); mdm->tx_addb(252); mdm->tx_addb(c); /* We won't do crap! */ + tqueue->addb(0xff); + tqueue->addb(252); + tqueue->addb(c); /* We won't do crap! */ } } - switch(telClient.command) { case 251: /* Will */ if(c == 0) telClient.binary[TEL_SERVER] = true; @@ -403,29 +466,41 @@ static void TelnetEmulation(Bit8u * data, Bitu size) { case 253: /* Do */ if(c == 0) { telClient.binary[TEL_CLIENT] = true; - mdm->tx_addb(0xff); mdm->tx_addb(251); mdm->tx_addb(0); /* Will do binary transfer */ + tqueue->addb(0xff); + tqueue->addb(251); + tqueue->addb(0); /* Will do binary transfer */ } if(c == 1) { telClient.echo[TEL_CLIENT] = false; - mdm->tx_addb(0xff); mdm->tx_addb(252); mdm->tx_addb(1); /* Won't echo (too lazy) */ + tqueue->addb(0xff); + tqueue->addb(252); + tqueue->addb(1); /* Won't echo (too lazy) */ } if(c == 3) { telClient.supressGA[TEL_CLIENT] = true; - mdm->tx_addb(0xff); mdm->tx_addb(251); mdm->tx_addb(3); /* Will Suppress GA */ + tqueue->addb(0xff); + tqueue->addb(251); + tqueue->addb(3); /* Will Suppress GA */ } break; case 254: /* Don't */ if(c == 0) { telClient.binary[TEL_CLIENT] = false; - mdm->tx_addb(0xff); mdm->tx_addb(252); mdm->tx_addb(0); /* Won't do binary transfer */ + tqueue->addb(0xff); + tqueue->addb(252); + tqueue->addb(0); /* Won't do binary transfer */ } if(c == 1) { telClient.echo[TEL_CLIENT] = false; - mdm->tx_addb(0xff); mdm->tx_addb(252); mdm->tx_addb(1); /* Won't echo (fine by me) */ + tqueue->addb(0xff); + tqueue->addb(252); + tqueue->addb(1); /* Won't echo (fine by me) */ } if(c == 3) { telClient.supressGA[TEL_CLIENT] = true; - mdm->tx_addb(0xff); mdm->tx_addb(251); mdm->tx_addb(3); /* Will Suppress GA (too lazy) */ + tqueue->addb(0xff); + tqueue->addb(251); + tqueue->addb(3); /* Will Suppress GA (too lazy) */ } break; default: @@ -450,7 +525,7 @@ static void TelnetEmulation(Bit8u * data, Bitu size) { /* Binary data with value of 255 */ telClient.inIAC = false; telClient.recCommand = false; - mdm->rx_addb(0xff); + rqueue->addb(0xff); continue; } @@ -460,12 +535,12 @@ static void TelnetEmulation(Bit8u * data, Bitu size) { telClient.inIAC = true; continue; } - mdm->rx_addb(c); + rqueue->addb(c); + } } } -} -static void MODEM_Hardware(void) { + void Timer(void) { int result =0; unsigned long args = 1; bool sendbyte = true; @@ -475,32 +550,20 @@ static void MODEM_Hardware(void) { /* Check for eventual break command */ if (!mhd.commandmode) mhd.cmdpause++; /* Handle incoming data from serial port, read as much as available */ - Bitu tx_size=mdm->tx_size(); + Bitu tx_size=tqueue->inuse(); while (tx_size--) { - txval = mdm->tx_readb(); + txval = tqueue->getb(); if (mhd.commandmode) { - if(txval != 0xd) { - if(txval == 0x8) { - if (mhd.cmdpos > 0) { - --mhd.cmdpos; - } - } else { - if (txval != '+') { - if(mhd.cmdposaddb(txval); + if (txval==0xa) continue; //Real modem doesn't seem to skip this? + else if (txval==0x8 && (mhd.cmdpos > 0)) --mhd.cmdpos; + else if (txval==0xd) DoCommand(); + else if (txval != '+') { + if(mhd.cmdposrx_addb(txval); - } else if (mhd.echo) { - mdm->rx_addb(10); - mdm->rx_addb(13); - } - } else { - DoCommand(); - } } else { /* 1000 ticks have passed, can check for pause command */ if (mhd.cmdpause > 1000) { @@ -509,14 +572,14 @@ static void MODEM_Hardware(void) { if(mhd.plusinc>=3) { LOG_MSG("Entering command mode"); mhd.commandmode = true; - sendStr("\nOK\n"); + SendRes(ResOK); mhd.plusinc = 0; } sendbyte=false; } else { mhd.plusinc=0; } -//If not a special pause command, should go for bigger blocks to send + //If not a special pause command, should go for bigger blocks to send } tmpbuf[0] = txval; @@ -530,207 +593,106 @@ static void MODEM_Hardware(void) { } SDLNet_CheckSockets(mhd.socketset,0); - /* Handle outgoing to the serial port */ - if(mdm->rx_size() == 0) { - if(!mhd.commandmode && mhd.socket && mdm->rx_free() && SDLNet_SocketReady(mhd.socket)) { - usesize = mdm->rx_free(); + /* Handle incoming to the serial port */ + if(!mhd.commandmode && mhd.socket) { + if(rqueue->left() && SDLNet_SocketReady(mhd.socket) && (mctrl & MC_RTS)) { + usesize = rqueue->left(); + if (usesize>16) usesize=16; result = SDLNet_TCP_Recv(mhd.socket, tmpbuf, usesize); if (result>0) { if(mhd.telnetmode) { /* Filter telnet commands */ TelnetEmulation(tmpbuf, result); - } else { - mdm->rx_adds(tmpbuf,result); + rqueue->adds(tmpbuf,result); } mhd.cmdpause = 0; - } else { - /* Error close the socket and disconnect */ - mdm->setmodemstatus(DISCONNECTED); - mhd.commandmode = true; - sendStr("\nNO CARRIER\n"); - SDLNet_TCP_DelSocket(mhd.socketset,mhd.socket); - SDLNet_TCP_Close(mhd.socket); - mhd.socket=0; + } else HangUp(); } } - } - /* Check for incoming calls */ - if (!mhd.socket && !mhd.incomingcall && mhd.listensocket) { - mhd.socket = SDLNet_TCP_Accept(mhd.listensocket); - if (mhd.socket) { - mhd.dialpos = 0; - mhd.incomingcall = true; + if (!mhd.socket && !mhd.incomingsocket && mhd.listensocket) { + mhd.incomingsocket = SDLNet_TCP_Accept(mhd.listensocket); + if (mhd.incomingsocket) { mhd.diallen = 12000; mhd.dialpos = 0; -//TODO Set ring in Modemstatus? - sendStr("\nRING\n"); - MIXER_Enable(mhd.chan,true); - mhd.ringcounter = 24000; + SendRes(ResRING); + //MIXER_Enable(mhd.chan,true); + mhd.ringtimer = 3000; + mhd.reg[1] = 0; //Reset ring counter reg } } - - if (mhd.incomingcall) { - if (mhd.ringcounter <= 0) { - if (mhd.autoanswer) { - mhd.incomingcall = false; - sendStr("\nCONNECT 57600\n"); - MIXER_Enable(mhd.chan,false); - mdm->setmodemstatus(CONNECTED); - mhd.incomingcall = false; - mhd.commandmode = false; - SDLNet_TCP_AddSocket(mhd.socketset,mhd.socket); + if (mhd.incomingsocket) { + if (mhd.ringtimer <= 0) { + mhd.reg[1]++; + if (mhd.answermode || (mhd.reg[0]==mhd.reg[1])) { + AcceptIncomingCall(); return; } - sendStr("\nRING\n"); + SendRes(ResRING); mhd.diallen = 12000; mhd.dialpos = 0; - - MIXER_Enable(mhd.chan,true); - - mhd.ringcounter = 3000; /* Ring every three seconds for accurate emulation */ - + //MIXER_Enable(mhd.chan,true); + mhd.ringtimer = 3000; } - if (mhd.ringcounter > 0) --mhd.ringcounter; - + --mhd.ringtimer; + } + updatemstatus(); } -} + bool CanSend(void) { + return true; + } -static void MODEM_CallBack(Bit8u * stream,Bit32u len) { - char *cp; - float ci,ri; - int innum, splitnum, quad, eighth, sixth, amp; - Bit8u curchar; - Bit32s buflen = (Bit32s)len; - if(mhd.incomingcall) { + bool CanRecv(void) { + return true; + } + + +protected: + char cmdbuf[QUEUE_SIZE]; + bool commandmode; + bool answermode; + bool echo; + bool telnetmode; + Bitu cmdpause; + Bits ringtimer; + Bits ringcount; + Bitu plusinc; + Bitu cmdpos; - if(mhd.dialpos>=mhd.diallen) { - MIXER_Enable(mhd.chan,false); - return; - } else { - quad = (mhd.diallen/14); - eighth = quad / 2; - sixth = eighth /2; + Bit8u reg[SREGS]; + IPaddress openip; + TCPsocket incomingsocket; + TCPsocket socket; + TCPsocket listensocket; + SDLNet_SocketSet socketset; - while ((buflen>0) && (mhd.dialpos=mhd.diallen) { - while(len-->0) { - *(Bit16s*)(stream) = 0; - stream+=2; - } - MIXER_Enable(mhd.chan,false); - mhd.dialing = false; - openConnection(); - return; - } else { +CSerialModem *csm; - while ((buflen>0) && (mhd.dialposGet_int("comport"); - /* Default to direct null modem connection. Telnet mode interprets IAC codes */ - mhd.telnetmode = false; + csm = NULL; - /* Bind the modem to the correct serial port */ - mhd.comport=section->Get_int("comport"); - strcpy(mhd.remotestr, section->Get_string("remote")); - mdm = getComport(mhd.comport); - mdm->setmodemstatus(DISCONNECTED); - mdm->SetMCHandler(&MC_Changed); + switch (comport) { + case 1: + csm = new CSerialModem(0x3f0, 4, 57600, section->Get_string("remote"), section->Get_int("listenport")); + break; + case 2: + csm = new CSerialModem(0x2f0, 3, 57600, section->Get_string("remote"), section->Get_int("listenport")); + break; + case 3: + csm = new CSerialModem(0x3e0, 4, 57600, section->Get_string("remote"), section->Get_int("listenport")); + break; + case 4: + csm = new CSerialModem(0x2e0, 3, 57600, section->Get_string("remote"), section->Get_int("listenport")); + break; + default: + // Default to COM2 + csm = new CSerialModem(0x2f0, 3, 57600, section->Get_string("remote"), section->Get_int("listenport")); + break; - TIMER_AddTickHandler(&MODEM_Hardware); - - /* Initialize the sockets and setup the listening port */ - mhd.socketset = SDLNet_AllocSocketSet(1); - if (!mhd.socketset) { - LOG_MSG("MODEM:Can't open socketset:%s",SDLNet_GetError()); -//TODO Should probably just exit - return; } - mhd.socket=0; - mhd.listenport=section->Get_int("listenport"); - if (mhd.listenport) { - IPaddress listen_ip; - SDLNet_ResolveHost(&listen_ip, NULL, mhd.listenport); - mhd.listensocket=SDLNet_TCP_Open(&listen_ip); - if (!mhd.listensocket) LOG_MSG("MODEM:Can't open listen port:%s",SDLNet_GetError()); - } else mhd.listensocket=0; - mhd.chan=MIXER_AddChannel(&MODEM_CallBack,8000,"MODEM"); - MIXER_Enable(mhd.chan,false); - MIXER_SetMode(mhd.chan,MIXER_16MONO); + if(csm != NULL) seriallist.push_back(csm); } + #endif diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 78ccbefc..1751d54f 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -1,6 +1,8 @@ #define INLINE __forceinline -#define VERSION "0.60" +#define VERSION "0.61" + +#define C_DIRECTSERIAL 1 /* Define to 1 to enable internal debugger, requires libcurses */ #define C_DEBUG 1 From 7a1ab977c10abc9abdc0f5ef6333376b438745a5 Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Tue, 29 Jun 2004 18:28:39 +0000 Subject: [PATCH 1777/4131] Adding Win32 passthrough serial support (late) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1859 --- include/serialport.h | 179 ++++++++++++++++++++++++------------------- 1 file changed, 99 insertions(+), 80 deletions(-) diff --git a/include/serialport.h b/include/serialport.h index 78a3952e..67035282 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -19,118 +19,137 @@ #if !defined __SERIALPORT_H #define __SERIALPORT_H -#include +#include + +#include "dosbox.h" //If it's too high you overflow terminal clients buffers i think -#define FIFO_SIZE (1024) +#define QUEUE_SIZE 1024 // Serial port interface // -#define M_CTS 0x01 -#define M_DSR 0x02 -#define M_RI 0x04 -#define M_DCD 0x08 +#define MS_CTS 0x01 +#define MS_DSR 0x02 +#define MS_RI 0x04 +#define MS_DCD 0x08 -enum INT_TYPES { - INT_MS, - INT_TX, - INT_RX, - INT_RX_FIFO, - INT_LS, - INT_NONE, +#define MC_DTR 0x1 +#define MC_RTS 0x2 + + +class CFifo { +public: + CFifo(Bitu _size) { + size=_size; + pos=used=0; + data=new Bit8u[size]; + } + ~CFifo() { + delete[] data; + } + INLINE Bitu left(void) { + return size-used; + } + INLINE Bitu inuse(void) { + return used; + } + void clear(void) { + used=pos=0; + } + bool isFull() { + return (used >= size); + } + void addb(Bit8u _val) { + assert(used=size) where-=size; + data[where]=_val; + used++; + } + void adds(Bit8u * _str,Bitu _len) { + assert((used+_len)<=size); + Bitu where=pos+used; + used+=_len; + while (_len--) { + if (where>=size) where-=size; + data[where++]=*_str++; + } + } + Bit8u getb(void) { + if (!used) return data[pos]; + Bitu where=pos; + if (++pos>=size) pos-=size; + used--; + return data[where]; + } + void gets(Bit8u * _str,Bitu _len) { + assert(used>=_len); + used-=_len; + while (_len--) { + *_str++=data[pos]; + if (++pos>=size) pos-=size; + } + } +private: + Bit8u * data; + Bitu size,pos,used; }; -typedef void MControl_Handler(Bitu mc); - class CSerial { public: + CSerial() { + + } // Constructor takes base port (0x3f0, 0x2f0, 0x2e0, etc.), IRQ, and initial bps // CSerial (Bit16u initbase, Bit8u initirq, Bit32u initbps); virtual ~CSerial(); - // External port functions for IOHandlers // - void write_port(Bitu port, Bitu val); - Bitu read_port(Bitu port); + void write_reg(Bitu reg, Bitu val); + Bitu read_reg(Bitu reg); - static void write_serial(Bitu port,Bitu val,Bitu iolen); - static Bitu read_serial(Bitu port,Bitu iolen); - - void SetMCHandler(MControl_Handler * mcontrol); - - /* Allow the modem to change the modem status bits */ - void setmodemstatus(Bit8u status); - Bit8u getmodemstatus(void); - Bit8u getlinestatus(void); + void SetModemStatus(Bit8u status); + virtual bool CanRecv(void)=0; + virtual bool CanSend(void)=0; + virtual void Send(Bit8u val)=0; + virtual Bit8u Recv(Bit8u val)=0; + virtual void Timer(void); void checkint(void); - void raiseint(INT_TYPES type); - void lowerint(INT_TYPES type); - /* Access to the receive fifo */ - Bitu rx_free(); - void rx_addb(Bit8u byte); - void rx_adds(Bit8u * data,Bitu size); - Bitu rx_size(); - Bit8u rx_readb(void); + Bitu base; + Bitu irq; + Bitu bps; + Bit8u mctrl; - /* Access to the transmit fifo */ - Bitu tx_free(); - void tx_addb(Bit8u byte); - Bitu tx_size(); - Bit8u tx_readb(void); - - - // These variables maintain the status of the serial port - Bit16u base; - Bit16u irq; - Bit32u bps; - - bool FIFOenabled; - Bit16u FIFOsize; + CFifo *rqueue; + CFifo *tqueue; private: - - void setdivisor(Bit8u dmsb, Bit8u dlsb); - void checkforirq(void); - struct { - Bitu used; - Bitu pos; - Bit8u data[FIFO_SIZE]; - } rx_fifo,tx_fifo; - struct { - Bitu requested; - Bitu enabled; - INT_TYPES active; - } ints; - - Bitu rx_lastread; - Bit8u irq_pending; + void UpdateBaudrate(void); + bool FIFOenabled; + Bit8u FIFOsize; + bool dotxint; Bit8u scratch; Bit8u dlab; Bit8u divisor_lsb; Bit8u divisor_msb; - Bit8u wordlen; - Bit8u dtr; - Bit8u rts; - Bit8u out1; - Bit8u out2; Bit8u local_loopback; - Bit8u linectrl; - Bit8u intid; - Bit8u ierval; + Bit8u iir; + Bit8u ier; Bit8u mstatus; - Bit8u txval; - Bit8u timeout; - - MControl_Handler * mc_handler; - char remotestr[4096]; + Bit8u linectrl; + Bit8u errors; }; -// This function returns the CSerial objects for ports 1-4 // -CSerial *getComport(Bitu portnum); +#include + +typedef std::list CSerialList; +typedef std::list::iterator CSerial_it; + +extern CSerialList seriallist; #endif From 4b8a13bdc1e25c75cae748752bf4d9ebb42d24f0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 29 Jun 2004 21:20:08 +0000 Subject: [PATCH 1778/4131] Fix gcc compilation error Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1860 --- src/hardware/softmodem.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp index 968d8c94..489bf616 100644 --- a/src/hardware/softmodem.cpp +++ b/src/hardware/softmodem.cpp @@ -334,7 +334,8 @@ public: Dial(foundstr); goto ret_none; } - char * scanbuf=&mhd.cmdbuf[2];char chr;Bitu num; + char * scanbuf; + scanbuf=&mhd.cmdbuf[2];char chr;Bitu num; while (chr=*scanbuf++) { switch (chr) { case 'I': //Some strings about firmware From 8f472fb66af189d21aa1ef0ace23ea18ad4a0b83 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 30 Jun 2004 14:40:08 +0000 Subject: [PATCH 1779/4131] Some sanity checks on strings for the cdrom. Changed E_Exit to warning when direct copyflag is used. Added printscreen/scrollock/pause to the keymapper. Ignoring printscreen and pause in keyboard (can be used to map special keys to). Added some binds so you can bind special keys to them (MK_scrolllock and MK_pause). Updated headers to support those new keys and MK_keys. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1861 --- include/keyboard.h | 1 + include/mapper.h | 2 +- src/dos/dos_mscdex.cpp | 16 +++++++----- src/gui/sdl_mapper.cpp | 52 +++++++++++++++++++++++++++++---------- src/hardware/keyboard.cpp | 6 ++++- 5 files changed, 56 insertions(+), 21 deletions(-) diff --git a/include/keyboard.h b/include/keyboard.h index dc3574e4..da8037dc 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -36,6 +36,7 @@ enum KBD_KEYS { KBD_grave,KBD_minus,KBD_equals,KBD_backslash,KBD_leftbracket,KBD_rightbracket, 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_left,KBD_up,KBD_down,KBD_right, diff --git a/include/mapper.h b/include/mapper.h index 24951ec4..27835661 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -21,7 +21,7 @@ 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_return,MK_kpminus,MK_scrolllock,MK_printscreen,MK_pause, }; diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 335584ba..d33f0d8b 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.21 2004-06-09 09:11:55 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.22 2004-06-30 14:40:07 qbix79 Exp $ */ #include #include @@ -601,9 +601,12 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph if (!ReadSectors(GetSubUnit(drive),false,dirEntrySector,1,defBuffer)) return false; // Get string part foundName = false; - useName = searchPos; - searchPos = strchr(searchPos,'\\'); - if (searchPos) { *searchPos = 0; searchPos++; } + if (searchPos) { + useName = searchPos; + searchPos = strchr(searchPos,'\\'); + } + + if (searchPos) { *searchPos = 0; searchPos++; } else foundComplete = true; do { @@ -622,7 +625,7 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph if (foundName) { // TO DO : name gefunden, Daten in den Buffer kopieren if (foundComplete) { - if (copyFlag) E_Exit("MSCDEX: GetDirEntry: Unsupported copyflag"); + if (copyFlag) LOG(LOG_MISC,LOG_ERROR)("MSCDEX: GetDirEntry: Unsupported copyflag. (result structure should be different"); // Direct copy MEM_BlockCopy(buffer,defBuffer+index,entryLength); error = iso ? 1:0; @@ -917,7 +920,7 @@ static bool MSCDEX_Handler(void) if (reg_ah!=0x15) return false; PhysPt data = PhysMake(SegValue(es),reg_bx); - MSCDEX_LOG("MSCDEX: INT 2F %04X",reg_ax); + MSCDEX_LOG("MSCDEX: INT 2F %04X BX= %04X CX=%04X",reg_ax,reg_bx,reg_bx); switch (reg_ax) { case 0x1500: /* Install check */ @@ -994,6 +997,7 @@ static bool MSCDEX_Handler(void) case 0x1510: /* Device driver request */ mscdex->SendDriverRequest(reg_cx,data); return true; + default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unknwon call : %04X",reg_ax); return true; diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 1afa0eb1..95b3f44e 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: sdl_mapper.cpp,v 1.5 2004-06-30 14:40:08 qbix79 Exp $ */ + #include #include #include @@ -432,6 +434,7 @@ void CBindGroup::ActivateBindList(CBindList * list,Bits value) { } } for (it=list->begin();it!=list->end();it++) { + /*BUG:CRASH if keymapper key is removed*/ if (validmod==(*it)->mods) (*it)->Activate(value); } } @@ -716,6 +719,15 @@ public: case MK_kpminus: key=SDLK_KP_MINUS; break; + case MK_scrolllock: + key=SDLK_SCROLLOCK; + break; + case MK_pause: + key=SDLK_PAUSE; + break; + case MK_printscreen: + key=SDLK_PRINT; + break; } sprintf(buf,"%s \"key %d%s%s%s\"", entry, @@ -878,7 +890,8 @@ static void CreateLayout(void) { /* Create the buttons for the Keyboard */ #define BW 28 #define BH 20 -#define PX(_X_) ((_X_)*BW) +#define DX 5 +#define PX(_X_) ((_X_)*BW + DX) #define PY(_Y_) (30+(_Y_)*BH) AddKeyButtonEvent(PX(0),PY(0),BW,BH,"ESC","esc",KBD_esc); for (i=0;i<12;i++) AddKeyButtonEvent(PX(2+i),PY(0),BW,BH,combo_f[i].title,combo_f[i].entry,combo_f[i].key); @@ -892,7 +905,7 @@ static void CreateLayout(void) { AddKeyButtonEvent(PX(0),PY(3),BW*2,BH,"CLCK","capslock",KBD_capslock); for (i=0;i<12;i++) AddKeyButtonEvent(PX(2+i),PY(3),BW,BH,combo_3[i].title,combo_3[i].entry,combo_3[i].key); - AddKeyButtonEvent(0,PY(4),BW*3,BH,"SHIFT","lshift",KBD_leftshift); + AddKeyButtonEvent(PX(0),PY(4),BW*3,BH,"SHIFT","lshift",KBD_leftshift); for (i=0;i<10;i++) AddKeyButtonEvent(PX(3+i),PY(4),BW,BH,combo_4[i].title,combo_4[i].entry,combo_4[i].key); AddKeyButtonEvent(PX(13),PY(4),BW*3,BH,"SHIFT","rshift",KBD_rightshift); @@ -904,12 +917,16 @@ static void CreateLayout(void) { AddKeyButtonEvent(PX(14),PY(5),BW*2,BH,"CTRL","rctrl",KBD_rightctrl); /* Arrow Keys */ - AddKeyButtonEvent(PX(0),PY(7),BW,BH,"INS","insert",KBD_insert); - AddKeyButtonEvent(PX(1),PY(7),BW,BH,"HOM","home",KBD_home); - AddKeyButtonEvent(PX(2),PY(7),BW,BH,"PUP","pageup",KBD_pageup); - AddKeyButtonEvent(PX(0),PY(8),BW,BH,"DEL","delete",KBD_delete); - AddKeyButtonEvent(PX(1),PY(8),BW,BH,"END","end",KBD_end); - AddKeyButtonEvent(PX(2),PY(8),BW,BH,"PDN","pagedown",KBD_pagedown); + + AddKeyButtonEvent(PX(0),PY(7),BW,BH,"PRT","printscreen",KBD_printscreen); + AddKeyButtonEvent(PX(1),PY(7),BW,BH,"SCL","scrolllock",KBD_scrolllock); + AddKeyButtonEvent(PX(2),PY(7),BW,BH,"PAU","pause",KBD_pause); + AddKeyButtonEvent(PX(0),PY(8),BW,BH,"INS","insert",KBD_insert); + AddKeyButtonEvent(PX(1),PY(8),BW,BH,"HOM","home",KBD_home); + AddKeyButtonEvent(PX(2),PY(8),BW,BH,"PUP","pageup",KBD_pageup); + AddKeyButtonEvent(PX(0),PY(9),BW,BH,"DEL","delete",KBD_delete); + AddKeyButtonEvent(PX(1),PY(9),BW,BH,"END","end",KBD_end); + AddKeyButtonEvent(PX(2),PY(9),BW,BH,"PDN","pagedown",KBD_pagedown); AddKeyButtonEvent(PX(1),PY(10),BW,BH,"\x18","up",KBD_up); AddKeyButtonEvent(PX(0),PY(11),BW,BH,"\x1B","left",KBD_left); AddKeyButtonEvent(PX(1),PY(11),BW,BH,"\x19","down",KBD_down); @@ -947,7 +964,9 @@ static void CreateLayout(void) { AddJButtonButton(PX(19),PY(3),BW,BH,"2" ,1,1); AddJAxisButton (PX(17),PY(4),BW,BH,"X-",1,false,false); AddJAxisButton (PX(18),PY(4),BW,BH,"Y+",1,true,true); - AddJAxisButton (PX(19),PY(4),BW,BH,"X+",1,false,true); /* The modifier buttons */ + AddJAxisButton (PX(19),PY(4),BW,BH,"X+",1,false,true); + + /* The modifier buttons */ AddModButton(PX(0),PY(13),50,20,"Mod1",1); AddModButton(PX(2),PY(13),50,20,"Mod2",2); AddModButton(PX(4),PY(13),50,20,"Mod3",3); @@ -961,8 +980,9 @@ static void CreateLayout(void) { } } /* Create some text buttons */ - new CTextButton(200,00,124,20,"Keyboard Layout"); - + new CTextButton(PX(6),00,124,20,"Keyboard Layout"); + new CTextButton(PX(16),00,124,20,"Joystick Layout"); + bind_but.action=new CCaptionButton(200,330,0,0); bind_but.event_title=new CCaptionButton(0,350,0,0); @@ -1045,7 +1065,8 @@ static struct { {"quote", SDLK_QUOTE}, {"backslash",SDLK_BACKSLASH}, {"lshift",SDLK_LSHIFT}, {"rshift",SDLK_RSHIFT}, {"lalt",SDLK_LALT}, {"ralt",SDLK_RALT}, {"lctrl",SDLK_LCTRL}, {"rctrl",SDLK_RCTRL}, {"comma",SDLK_COMMA}, - {"period",SDLK_PERIOD}, {"slash",SDLK_SLASH}, {"pagedown",SDLK_PAGEDOWN}, + {"period",SDLK_PERIOD}, {"slash",SDLK_SLASH}, {"printscreen",SDLK_PRINT}, + {"scrolllock",SDLK_SCROLLOCK}, {"pause",SDLK_PAUSE}, {"pagedown",SDLK_PAGEDOWN}, {"pageup",SDLK_PAGEUP}, {"insert",SDLK_INSERT}, {"home",SDLK_HOME}, {"delete",SDLK_DELETE}, {"end",SDLK_END}, {"up",SDLK_UP}, {"left",SDLK_LEFT}, {"down",SDLK_DOWN}, {"right",SDLK_RIGHT}, @@ -1074,6 +1095,11 @@ static void CreateDefaultBinds(void) { (*hit)->MakeDefaultBind(buffer); CreateStringBind(buffer); } + /* JOYSTICK */ + if (SDL_NumJoysticks()>0) { +// default mapping + } + } void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char * eventname,char * buttonname) { @@ -1162,7 +1188,7 @@ void MAPPER_Run(void) { for (CEventVector_it evit=events.begin();evit!=events.end();evit++) { (*evit)->DeActivateAll(); } - + bool mousetoggle=false; if(mouselocked) { mousetoggle=true; diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 1c7e31fb..fca75a50 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.25 2004-06-20 22:03:34 harekiet Exp $ */ +/* $Id: keyboard.cpp,v 1.26 2004-06-30 14:40:08 qbix79 Exp $ */ #include #include @@ -320,6 +320,10 @@ void KEYBOARD_AddKey(KBD_KEYS keytype,bool pressed) { case KBD_pagedown:extend=true;ret=81;break; case KBD_insert:extend=true;ret=82;break; case KBD_delete:extend=true;ret=83;break; + case KBD_pause: + case KBD_printscreen: + /* Not handled yet. But usuable in mapper for special events */ + return; default: E_Exit("Unsupported key press"); break; From ba9a2cc5465f69a7b23d2e4bb288a70d26a0ff1f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 4 Jul 2004 21:01:55 +0000 Subject: [PATCH 1780/4131] Remove pic_registerirq calls Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1862 --- src/hardware/mpu401.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 795a102b..5c5e06c3 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -738,6 +738,5 @@ void MPU401_Init(Section* sec) { if (!(mpu.intelligent=section->Get_bool("intelligent"))) return; mpu.irq=2; - PIC_RegisterIRQ(mpu.irq,0,"MPU401"); MPU401_Reset(); } From b1cebeed4e97374f427b213be286173a1251657a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 4 Jul 2004 21:02:22 +0000 Subject: [PATCH 1781/4131] Changes for 1 global capture directory Support for capturing raw midi Support for capturing raw opl Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1863 --- include/hardware.h | 4 ++++ src/dosbox.cpp | 23 ++++++-------------- src/hardware/hardware.cpp | 45 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/include/hardware.h b/include/hardware.h index 94f2ffac..878affef 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -19,6 +19,8 @@ #ifndef _HARDWARE_H_ #define _HARDWARE_H_ +#include + class Section; enum OPL_Mode { OPL_none,OPL_cms,OPL_opl2,OPL_dualopl2,OPL_opl3 @@ -27,6 +29,8 @@ enum OPL_Mode { void OPL_Init(Section* sec,Bitu base,OPL_Mode mode,Bitu rate); void CMS_Init(Section* sec,Bitu base,Bitu rate); extern Bit8u adlib_commandreg; +FILE * OpenCaptureFile(const char * type,const char * ext); + #endif diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 8b2eea92..49f9c819 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.70 2004-06-28 01:41:20 canadacow Exp $ */ +/* $Id: dosbox.cpp,v 1.71 2004-07-04 20:59:38 harekiet Exp $ */ #include #include @@ -50,7 +50,7 @@ void PAGING_Init(Section *); void IO_Init(Section * ); void CALLBACK_Init(Section*); void PROGRAMS_Init(Section*); - +void CREDITS_Init(Section*); void RENDER_Init(Section*); void VGA_Init(Section*); @@ -190,6 +190,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit); secprop->Add_string("language",""); secprop->Add_string("machine","vga"); + secprop->Add_string("captures","capture"); #if C_DEBUG LOG_StartUp(); @@ -198,6 +199,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&IO_Init); secprop->AddInitFunction(&PAGING_Init); secprop->AddInitFunction(&MEM_Init); + secprop->AddInitFunction(&HARDWARE_Init); secprop->Add_int("memsize",16); secprop->AddInitFunction(&CALLBACK_Init); secprop->AddInitFunction(&PIC_Init); @@ -210,16 +212,15 @@ void DOSBOX_Init(void) { "language -- Select another language file.\n" "memsize -- Amount of memory dosbox has in megabytes.\n" "machine -- The type of machine tries to emulate:hercules,cga,tandy,vga.\n" + "captures -- Directory where things like wave,midi,screenshot get captured.\n" ); secprop=control->AddSection_prop("render",&RENDER_Init); secprop->Add_int("frameskip",0); - secprop->Add_string("snapdir","snaps"); secprop->Add_bool("aspect",false); secprop->Add_string("scaler","normal2x"); MSG_Add("RENDER_CONFIGFILE_HELP", "frameskip -- How many frames dosbox skips before drawing one.\n" - "snapdir -- Directory where screenshots get saved.\n" "aspect -- Do aspect correction.\n" "scaler -- Scaler used to enlarge/enhance low resolution modes.\n" " Supported are none,normal2x,advmame2x\n" @@ -254,7 +255,6 @@ void DOSBOX_Init(void) { secprop->Add_bool("nosound",false); secprop->Add_int("rate",22050); secprop->Add_int("blocksize",2048); - secprop->Add_string("wavedir","waves"); MSG_Add("MIXER_CONFIGFILE_HELP", "nosound -- Enable silent mode, sound is still emulated though.\n" @@ -262,8 +262,6 @@ void DOSBOX_Init(void) { " probably lower their sound quality.\n" "blocksize -- Mixer block size, larger blocks might help sound stuttering\n" " but sound will also be more lagged.\n" - "wavedir -- Directory where saved sound output goes when you use the\n" - " sound record key-combination, check README file.\n" ); secprop=control->AddSection_prop("midi",&MIDI_Init); @@ -358,7 +356,6 @@ void DOSBOX_Init(void) { ); // Mscdex secprop->AddInitFunction(&MSCDEX_Init); - #if C_MODEM secprop=control->AddSection_prop("modem",&MODEM_Init); secprop->Add_bool("modem",true); @@ -369,6 +366,8 @@ void DOSBOX_Init(void) { "modem -- Enable virtual modem emulation.\n" "comport -- COM Port modem is connected to.\n" "listenport -- TCP Port the momdem listens on for incoming connections.\n" + ); +#endif #if C_DIRECTSERIAL secprop=control->AddSection_prop("directserial",&DIRECTSERIAL_Init); secprop->Add_bool("directserial", true); @@ -379,10 +378,6 @@ void DOSBOX_Init(void) { secprop->Add_int("bytesize", 8); // Could be 5 to 8 secprop->Add_int("stopbit", 1); // Could be 1 or 2 #endif - - ); -#endif - #if C_IPX secprop=control->AddSection_prop("ipx",&IPX_Init); secprop->Add_bool("ipx", true); @@ -390,14 +385,10 @@ void DOSBOX_Init(void) { "ipx -- Enable ipx over UDP/IP emulation.\n" ); #endif - - secline=control->AddSection_line("autoexec",&AUTOEXEC_Init); - MSG_Add("AUTOEXEC_CONFIGFILE_HELP", "Lines in this section will be run at startup.\n" ); - control->SetStartUp(&SHELL_Init); } diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 017ecc40..e0a39ac9 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -20,14 +20,55 @@ This could do with a serious revision :) */ +#include #include #include "dosbox.h" -#include "programs.h" #include "hardware.h" #include "setup.h" +#include "support.h" + +static char * capturedir; +extern char * RunningProgram; + +FILE * OpenCaptureFile(const char * type,const char * ext) { + Bitu last=0; + char file_name[CROSS_LEN]; + char file_start[16]; + DIR * dir;struct dirent * dir_ent; + /* Find a filename to open */ + dir=opendir(capturedir); + if (!dir) { + LOG_MSG("Can't open dir %s for capturing %s",capturedir,type); + return 0; + } + strcpy(file_start,RunningProgram); + strcat(file_start,"_"); + while ((dir_ent=readdir(dir))) { + char tempname[CROSS_LEN]; + strcpy(tempname,dir_ent->d_name); + char * test=strstr(tempname,ext); + if (!test || strlen(test)!=strlen(ext)) continue; + *test=0; + if (strncasecmp(tempname,file_start,strlen(file_start))!=0) continue; + Bitu num=atoi(&tempname[strlen(file_start)]); + if (num>=last) last=num+1; + } + closedir(dir); + sprintf(file_name,"%s%c%s%03d%s",capturedir,CROSS_FILESPLIT,file_start,last,ext); + lowcase(file_name); + /* Open the actual file */ + FILE * handle=fopen(file_name,"wb"); + if (handle) { + LOG_MSG("Capturing %s to %s",type,file_name); + } else { + LOG_MSG("Failed to open %s for capturing %s",file_name,type); + } + return handle; +} void HARDWARE_Init(Section * sec) { - + Section_prop * section=static_cast(sec); + capturedir=(char *)section->Get_string("captures"); } From dc6e126a719217b14de43c02eb34b11eea97fc6a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 4 Jul 2004 21:07:45 +0000 Subject: [PATCH 1782/4131] Changes for 1 global capture directory Support for capturing raw midi Support for capturing raw opl Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1864 --- src/hardware/adlib.cpp | 156 ++++++++++++++++++++++++++++++++++++++--- src/hardware/mixer.cpp | 34 +-------- 2 files changed, 151 insertions(+), 39 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 5c276768..f5237aff 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -19,16 +19,23 @@ #include #include #include +#include +#include + #include "dosbox.h" #include "inout.h" #include "mixer.h" #include "pic.h" #include "hardware.h" #include "setup.h" +#include "mapper.h" +#include "mem.h" + /* Thanks to vdmsound for nice simple way to implement this */ -# define logerror + +#define logerror #ifdef _MSC_VER /* Disable recurring warnings */ @@ -75,12 +82,24 @@ namespace THEOPL3 { #define OPL2_INTERNAL_FREQ 3600000 // The OPL2 operates at 3.6MHz #define OPL3_INTERNAL_FREQ 14400000 // The OPL3 operates at 14.4MHz +#define RAW_SIZE 1024 static struct { bool active; OPL_Mode mode; MIXER_Channel * chan; Bit32u last_used; Bit16s mixbuf[2][128]; + struct { + FILE * handle; + Bit32u start; + Bit32u last; + Bit8u index; + Bit8u buffer[RAW_SIZE+8]; + Bit8u regs[2][256]; + Bit32u used; + Bit32u done; + Bit8u cmd[2]; + } raw; } opl; static void OPL_CallBack(Bit8u *stream, Bit32u len) { @@ -104,7 +123,6 @@ static void OPL_CallBack(Bit8u *stream, Bit32u len) { ((Bit16u *)stream)[i*2+1]=opl.mixbuf[1][i]; } break; - } if ((PIC_Ticks-opl.last_used)>5000) { MIXER_Enable(opl.chan,false); @@ -125,27 +143,147 @@ static Bitu OPL_Read(Bitu port,Bitu iolen) { return 0xff; } +static void OPL_RawAdd(Bitu index,Bitu val); void OPL_Write(Bitu port,Bitu val,Bitu iolen) { opl.last_used=PIC_Ticks; if (!opl.active) { opl.active=true; MIXER_Enable(opl.chan,true); } - Bitu addr=port & 3; - if (!addr) adlib_commandreg=val; + port&=3; + if (port&1) { + Bitu index=port>>1; + opl.raw.regs[index][opl.raw.cmd[index]]=val; + if (opl.raw.handle) OPL_RawAdd(index,val); + } else opl.raw.cmd[port>>1]=val; + if (!port) adlib_commandreg=val; switch (opl.mode) { case OPL_opl2: - OPL2::YM3812Write(0,addr,val); + OPL2::YM3812Write(0,port,val); break; case OPL_opl3: - THEOPL3::YMF262Write(0,addr,val); + THEOPL3::YMF262Write(0,port,val); break; case OPL_dualopl2: - OPL2::YM3812Write(addr>>1,addr,val); + OPL2::YM3812Write(port>>1,port,val); break; } } +static Bit8u dro_header[]={ + 'D','B','R','A', /* Bit32u ID */ + 'W','O','P','L', /* Bit32u ID */ + 0x0,0x0,0x0,0x0, /* Bit32u total milliseconds */ + 0x0,0x0,0x0,0x0, /* Bit32u total data */ + 0x0, /* Type 0=opl2,1=opl3,2=dual-opl2 */ +}; +/* Commands + 0x00 Bit8u, millisecond delay+1 + 0x01 Bit16u, millisecond delay+1 + 0x02 none, Use the low index/data pair + 0x03 none, Use the high index/data pair + 0xxx Bit8u, send command and data to current index/data pair +*/ + +static void OPL_RawEmptyBuffer(void) { + fwrite(opl.raw.buffer,1,opl.raw.used,opl.raw.handle); + opl.raw.done+=opl.raw.used; + opl.raw.used=0; +} + +#define ADDBUF(_VAL_) opl.raw.buffer[opl.raw.used++]=_VAL_; +static void OPL_RawAdd(Bitu index,Bitu val) { + /* Check if we have yet to start */ + if (!opl.raw.start) { + Bitu i; + opl.raw.last=PIC_Ticks; + opl.raw.start=PIC_Ticks; + /* Check the registers to add */ + for (i=4;i<256;i++) { + if (!opl.raw.regs[0][i]) continue; + if ((i &0xe0)==0xb0) continue; + ADDBUF((Bit8u)i); + ADDBUF(opl.raw.regs[0][i]); + } + bool donesecond=false; + for (i=4;i<256;i++) { + if (!opl.raw.regs[0][i]) continue; + if ((i&0xe0)==0xb0) continue; + if (!donesecond) { + donesecond=true; + ADDBUF(0x3); + } + ADDBUF((Bit8u)i); + ADDBUF(opl.raw.regs[0][i]); + } + if (donesecond) ADDBUF(0x2); + } + /* Check how much time has passed, Allow an extra 5 milliseconds? */ + if (PIC_Ticks>(opl.raw.last+5)) { + Bitu passed=PIC_Ticks-opl.raw.last; + opl.raw.last=PIC_Ticks; + while (passed) { + passed-=1; + if (passed<256) { + ADDBUF(0x00); //8bit delay + ADDBUF((Bit8u)passed); //8bit delay + passed=0; + } else if (passed<0x10000) { + ADDBUF(0x01); //16bit delay + ADDBUF((Bit8u)(passed & 0xff)); //lo-byte + ADDBUF((Bit8u)(passed >> 8)); //hi-byte + passed=0; + } else { + ADDBUF(0x01); //16bit delay + ADDBUF(0xff); //lo-byte + ADDBUF(0xff); //hi-byte + passed-=0xffff; + } + } + } + /* Check if we're still sending to the correct index */ + if (opl.raw.index != index) { + opl.raw.index=index; + ADDBUF(opl.raw.index ? 0x3 : 0x2); + } + ADDBUF(opl.raw.cmd[opl.raw.index]); + ADDBUF(val); + if (opl.raw.used>=RAW_SIZE) OPL_RawEmptyBuffer(); +} + +static void OPL_SaveRawEvent(void) { + /* Check for previously opened wave file */ + if (opl.raw.handle) { + LOG_MSG("Stopping Raw OPL capturing."); + OPL_RawEmptyBuffer(); + /* Fill in the header with useful information */ + host_writed(&dro_header[0x08],opl.raw.last-opl.raw.start); + host_writed(&dro_header[0x0c],opl.raw.done); + switch (opl.mode) { + case OPL_opl2:host_writeb(&dro_header[0x10],0x0);break; + case OPL_opl3:host_writeb(&dro_header[0x10],0x1);break; + case OPL_dualopl2:host_writeb(&dro_header[0x10],0x2);break; + } + fseek(opl.raw.handle,0,0); + fwrite(dro_header,1,sizeof(dro_header),opl.raw.handle); + fclose(opl.raw.handle); + opl.raw.handle=0; + return; + } + opl.raw.handle=OpenCaptureFile("Raw Opl",".dro"); + opl.raw.index=0; + opl.raw.used=0; + opl.raw.done=0; + opl.raw.start=0; + opl.raw.last=0; + memset(opl.raw.buffer,0,sizeof(opl.raw.buffer)); + fwrite(dro_header,1,sizeof(dro_header),opl.raw.handle); +} + +static void OPL_Stop(Section* sec) { + if (opl.raw.handle) OPL_SaveRawEvent(); +} + void OPL_Init(Section* sec,Bitu base,OPL_Mode oplmode,Bitu rate) { Section_prop * section=static_cast(sec); if (OPL2::YM3812Init(2,OPL2_INTERNAL_FREQ,rate)) { @@ -170,9 +308,11 @@ void OPL_Init(Section* sec,Bitu base,OPL_Mode oplmode,Bitu rate) { opl.active=false; opl.last_used=0; opl.mode=oplmode; - + memset(opl.raw.regs,0,sizeof(opl.raw.regs)); opl.chan=MIXER_AddChannel(OPL_CallBack,rate,"FM"); MIXER_SetMode(opl.chan,(opl.mode>OPL_opl2) ? MIXER_16STEREO : MIXER_16MONO); MIXER_Enable(opl.chan,false); + MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL"); + sec->AddDestroyFunction(&OPL_Stop); }; diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 421be8d7..d32852df 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -35,6 +35,7 @@ #include "cross.h" #include "support.h" #include "mapper.h" +#include "hardware.h" #include "programs.h" #define MIXER_MAXCHAN 8 @@ -108,7 +109,6 @@ static struct { Bitu tick_add,tick_remain; struct { FILE * handle; - const char * dir; Bit16s buf[MIXER_WAVESIZE][2]; Bitu used; Bit32u length; @@ -265,9 +265,6 @@ static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { } static void MIXER_WaveEvent(void) { - Bitu last=0;char file_name[CROSS_LEN]; - DIR * dir;struct dirent * dir_ent; - /* Check for previously opened wave file */ if (mixer.wave.handle) { LOG_MSG("Stopped recording"); @@ -285,34 +282,10 @@ static void MIXER_WaveEvent(void) { mixer.wave.handle=0; return; } - /* Find a filename to open */ - dir=opendir(mixer.wave.dir); - if (!dir) { - LOG_MSG("Can't open waveout dir %s",mixer.wave.dir); - return; - } - while ((dir_ent=readdir(dir))) { - char tempname[CROSS_LEN]; - strcpy(tempname,dir_ent->d_name); - char * test=strstr(tempname,".wav"); - if (!test) continue; - *test=0; - if (strlen(tempname)<5) continue; - if (strncmp(tempname,"wave",4)!=0) continue; - Bitu num=atoi(&tempname[4]); - if (num>=last) last=num+1; - } - closedir(dir); - sprintf(file_name,"%s%cwave%04d.wav",mixer.wave.dir,CROSS_FILESPLIT,last); - /* Open the actual file */ - mixer.wave.handle=fopen(file_name,"wb"); - if (!mixer.wave.handle) { - LOG_MSG("Can't open file %s for waveout",file_name); - return; - } + mixer.wave.handle=OpenCaptureFile("Wave Outut",".wav"); + if (!mixer.wave.handle) return; mixer.wave.length=0; mixer.wave.used=0; - LOG_MSG("Started recording to file %s",file_name); fwrite(wavheader,1,sizeof(wavheader),mixer.wave.handle); } @@ -384,7 +357,6 @@ void MIXER_Init(Section* sec) { mixer.freq=section->Get_int("rate"); mixer.nosound=section->Get_bool("nosound"); mixer.blocksize=section->Get_int("blocksize"); - mixer.wave.dir=section->Get_string("wavedir"); /* Initialize the internal stuff */ mixer.channels=0; From a18b3cafd0d1233fc4cfea80a34066cc6a4552d1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 4 Jul 2004 21:08:08 +0000 Subject: [PATCH 1783/4131] Changes for 1 global capture directory Support for capturing raw midi Support for capturing raw opl Slight rewrite of the midi output classes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1865 --- src/gui/midi.cpp | 132 +++++++++++++++++++++++++++++++-------- src/gui/midi_alsa.h | 33 ++++------ src/gui/midi_coreaudio.h | 8 +-- src/gui/midi_oss.h | 6 +- src/gui/midi_win32.h | 4 +- 5 files changed, 126 insertions(+), 57 deletions(-) diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index bbbb2d9c..ebc8550e 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -24,8 +24,12 @@ #include "cross.h" #include "support.h" #include "setup.h" +#include "mapper.h" +#include "pic.h" +#include "hardware.h" #define SYSEX_SIZE 1024 +#define RAWBUF 1024 Bit8u MIDI_evt_len[256] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00 @@ -47,7 +51,7 @@ Bit8u MIDI_evt_len[256] = { 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xe0 - 0,2,3,2, 0,0,1,1, 1,0,1,1, 1,0,1,1 // 0xf0 + 0,2,3,2, 0,0,1,0, 1,0,1,1, 1,0,1,1 // 0xf0 }; class MidiHandler; @@ -62,7 +66,7 @@ public: }; virtual bool Open(const char * conf) { return true; }; virtual void Close(void) {}; - virtual void PlayMsg(Bit32u msg) {}; + virtual void PlayMsg(Bit8u * msg) {}; virtual void PlaySysex(Bit8u * sysex,Bitu len) {}; virtual char * GetName(void) { return "none"; }; MidiHandler * next; @@ -96,49 +100,117 @@ static struct { Bitu status; Bitu cmd_len; Bitu cmd_pos; - - Bit32u cmd_msg; - Bit8u data[4]; + Bit8u cmd_buf[8]; struct { Bit8u buf[SYSEX_SIZE]; Bitu used; - bool active; } sysex; bool available; MidiHandler * handler; + struct { + FILE * handle; + Bit8u buffer[RAWBUF+SYSEX_SIZE]; + Bitu used,done; + Bit32u last; + } raw; } midi; +static Bit8u midi_header[]={ + 'M','T','h','d', /* Bit32u, Header Chunk */ + 0x0,0x0,0x0,0x6, /* Bit32u, Chunk Length */ + 0x0,0x0, /* Bit16u, Format, 0=single track */ + 0x0,0x1, /* Bit16u, Track Count, 1 track */ + 0x01,0xf4, /* Bit16u, Timing, 2 beats/second with 500 frames */ + 'M','T','r','k', /* Bit32u, Track Chunk */ + 0x0,0x0,0x0,0x0, /* Bit32u, Chunk Length */ + //Track data +}; + +#define ADDBUF(_VAL_) midi.raw.buffer[midi.raw.used++]=(Bit8u)(_VAL_); +static INLINE void RawAddNumber(Bit32u val) { + if (val & 0xfe00000) ADDBUF(0x80|((val >> 21) & 0x7f)); + if (val & 0xfffc000) ADDBUF(0x80|((val >> 14) & 0x7f)); + if (val & 0xfffff80) ADDBUF(0x80|((val >> 7) & 0x7f)); + ADDBUF(val & 0x7f); +} +static INLINE void RawAddDelta(void) { + if (!midi.raw.last) midi.raw.last=PIC_Ticks; + Bit32u delta=PIC_Ticks-midi.raw.last; + midi.raw.last=PIC_Ticks; + RawAddNumber(delta); +} + +static INLINE void RawAddData(Bit8u * data,Bitu len) { + for (Bitu i=0;i=RAWBUF) { + fwrite(midi.raw.buffer,1,midi.raw.used,midi.raw.handle); + midi.raw.done+=midi.raw.used; + midi.raw.used=0; + } +} + +static void MIDI_SaveRawEvent(void) { + /* Check for previously opened wave file */ + if (midi.raw.handle) { + LOG_MSG("Stopping raw midi saving."); + ADDBUF(0x00);//Delta time + ADDBUF(0xff);ADDBUF(0x2F);ADDBUF(0x00); //End of track event + fwrite(midi.raw.buffer,1,midi.raw.used,midi.raw.handle); + midi.raw.done+=midi.raw.used; + fseek(midi.raw.handle,18, SEEK_SET); + Bit8u size[4]; + size[0]=(Bit8u)(midi.raw.done >> 24); + size[1]=(Bit8u)(midi.raw.done >> 16); + size[2]=(Bit8u)(midi.raw.done >> 8); + size[3]=(Bit8u)(midi.raw.done >> 0); + fwrite(&size,1,4,midi.raw.handle); + fclose(midi.raw.handle); + midi.raw.handle=0; + } else { + midi.raw.handle=OpenCaptureFile("Raw Midi",".mid"); + if (!midi.raw.handle) return; + fwrite(midi_header,1,sizeof(midi_header),midi.raw.handle); + midi.raw.used=0; + midi.raw.done=0; + } +} + + void MIDI_RawOutByte(Bit8u data) { - /* Test for a new status byte */ - if (midi.sysex.active && !(data&0x80)) { - if (midi.sysex.used<(SYSEX_SIZE-1)) midi.sysex.buf[midi.sysex.used++]=data; - return; - } else if (data&0x80) { - if (midi.sysex.active) { - /* Play a sysex message */ + /* Test for a active sysex tranfer */ + if (midi.status==0xf0) { + if (!(data&0x80)) { + if (midi.sysex.used<(SYSEX_SIZE-1)) midi.sysex.buf[midi.sysex.used++]=data; + return; + } else { midi.sysex.buf[midi.sysex.used++]=0xf7; midi.handler->PlaySysex(midi.sysex.buf,midi.sysex.used); LOG(LOG_ALL,LOG_NORMAL)("Sysex message size %d",midi.sysex.used); - midi.sysex.active=false; - if (data==0xf7) return; + if (midi.raw.handle) { + RawAddDelta(); + ADDBUF(0xf0); + RawAddNumber(midi.sysex.used-1); + RawAddData(&midi.sysex.buf[1],midi.sysex.used-1); + } } + } + if (data&0x80) { midi.status=data; midi.cmd_pos=0; - midi.cmd_msg=0; + midi.cmd_len=MIDI_evt_len[data]; if (midi.status==0xf0) { - midi.sysex.active=true; midi.sysex.buf[0]=0xf0; midi.sysex.used=1; - return; } - midi.cmd_len=MIDI_evt_len[data]; } - midi.cmd_msg|=data << (8 * midi.cmd_pos); - midi.cmd_pos++; - if (midi.cmd_pos >= midi.cmd_len) { - midi.handler->PlayMsg(midi.cmd_msg); - midi.cmd_msg=midi.status; - midi.cmd_pos=1; + midi.cmd_buf[midi.cmd_pos++]=data; + if (midi.cmd_len && midi.cmd_pos >= midi.cmd_len) { + if (midi.raw.handle) { + RawAddDelta(); + RawAddData(midi.cmd_buf,midi.cmd_len); + } + midi.handler->PlayMsg(midi.cmd_buf); + midi.cmd_pos=1; //Use Running status } } @@ -146,12 +218,21 @@ bool MIDI_Available(void) { return midi.available; } +static void MIDI_Stop(Section* sec) { + if (midi.raw.handle) MIDI_SaveRawEvent(); +} + void MIDI_Init(Section * sec) { Section_prop * section=static_cast(sec); const char * dev=section->Get_string("device"); const char * conf=section->Get_string("config"); /* If device = "default" go for first handler that works */ MidiHandler * handler; + MAPPER_AddHandler(MIDI_SaveRawEvent,MK_f8,MMOD1|MMOD2,"caprawmidi","Cap MIDI"); + sec->AddDestroyFunction(&MIDI_Stop); + midi.status=0x00; + midi.cmd_pos=0; + midi.cmd_len=0; if (!strcasecmp(dev,"default")) goto getdefault; handler=handler_list; while (handler) { @@ -180,6 +261,5 @@ getdefault: handler=handler->next; } /* This shouldn't be possible */ - midi.available=false; } diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 988f98b0..7a10910a 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_alsa.h,v 1.7 2004-01-26 15:10:16 qbix79 Exp $ */ +/* $Id: midi_alsa.h,v 1.8 2004-07-04 21:08:08 harekiet Exp $ */ #define ALSA_PCM_OLD_HW_PARAMS_API #define ALSA_PCM_OLD_SW_PARAMS_API @@ -75,45 +75,38 @@ public: send_event(1); } - void PlayMsg(Bit32u msg) { + void PlayMsg(Bit8u * msg) { unsigned int midiCmd[4]; ev.type = SND_SEQ_EVENT_OSS; - if (msg == 247) // to accomadate lure of the temptress - return; + ev.data.raw32.d[0] = msg[0]; + ev.data.raw32.d[1] = msg[1]; + ev.data.raw32.d[2] = msg[2]; - midiCmd[3] = (msg & 0xFF000000) >> 24; - midiCmd[2] = (msg & 0x00FF0000) >> 16; - midiCmd[1] = (msg & 0x0000FF00) >> 8; - midiCmd[0] = (msg & 0x000000FF); - ev.data.raw32.d[0] = midiCmd[0]; - ev.data.raw32.d[1] = midiCmd[1]; - ev.data.raw32.d[2] = midiCmd[2]; - - unsigned char chanID = midiCmd[0] & 0x0F; - switch (midiCmd[0] & 0xF0) { + unsigned char chanID = msg[0] & 0x0F; + switch (msg[0] & 0xF0) { case 0x80: - snd_seq_ev_set_noteoff(&ev, chanID, midiCmd[1], midiCmd[2]); + snd_seq_ev_set_noteoff(&ev, chanID, msg[1], msg[2]); send_event(1); break; case 0x90: - snd_seq_ev_set_noteon(&ev, chanID, midiCmd[1], midiCmd[2]); + snd_seq_ev_set_noteon(&ev, chanID, msg[1], msg[2]); send_event(1); break; case 0xB0: - snd_seq_ev_set_controller(&ev, chanID, midiCmd[1], midiCmd[2]); + snd_seq_ev_set_controller(&ev, chanID, msg[1], msg[2]); send_event(1); break; case 0xC0: - snd_seq_ev_set_pgmchange(&ev, chanID, midiCmd[1]); + snd_seq_ev_set_pgmchange(&ev, chanID, msg[1]); send_event(0); break; case 0xD0: - snd_seq_ev_set_chanpress(&ev, chanID, midiCmd[1]); + snd_seq_ev_set_chanpress(&ev, chanID, msg[1]); send_event(0); break; case 0xE0:{ - long theBend = ((long)midiCmd[1] + (long)(midiCmd[2] << 7)) - 0x2000; + long theBend = ((long)msg[1] + (long)(msg[2] << 7)) - 0x2000; snd_seq_ev_set_pitchbend(&ev, chanID, theBend); send_event(1); } diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index 0d7f9635..349c6da3 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -76,12 +76,8 @@ public: } } - void PlayMsg(Bit32u msg) { - MusicDeviceMIDIEvent(m_musicDevice, - (msg & 0x000000FF), - (msg & 0x0000FF00) >> 8, - (msg & 0x00FF0000) >> 16, - 0); + void PlayMsg(Bit8u * msg) { + MusicDeviceMIDIEvent(m_musicDevice,msg[0],msg[1],msg[2],0); } void PlaySysex(Bit8u * sysex, Bitu len) { diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index 62e1dfaf..d770a12a 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -45,15 +45,15 @@ public: if (!isOpen) return; if (device>0) close(device); }; - void PlayMsg(Bit32u msg) { + void PlayMsg(Bit8u * msg) { Bit8u buf[128];Bitu pos=0; Bitu len=MIDI_evt_len[msg & 0xff]; for (;len>0;len--) { buf[pos++] = SEQ_MIDIPUTC; - buf[pos++] = msg & 0xff; + buf[pos++] = *msg; buf[pos++] = device_num; buf[pos++] = 0; - msg >>=8; + msg++; } write(device,buf,pos); }; diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index b08652b6..e9a8651f 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -42,8 +42,8 @@ public: midiOutClose(m_out); CloseHandle (m_event); }; - void PlayMsg(Bit32u msg) { - midiOutShortMsg(m_out, msg); + void PlayMsg(Bit8u * msg) { + midiOutShortMsg(m_out, *(Bit32u*)msg); }; void PlaySysex(Bit8u * sysex,Bitu len) { if (WaitForSingleObject (m_event, 2000) == WAIT_TIMEOUT) { From 0a13f2d0ed2400c58608cb0a73d4727fb2dc3acb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 4 Jul 2004 21:18:05 +0000 Subject: [PATCH 1784/4131] Changes for 1 global capture directory Support for capturing raw midi Support for capturing raw opl Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1866 --- src/gui/render.cpp | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 65ea4341..1e1abda6 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.27 2004-06-10 07:18:19 harekiet Exp $ */ +/* $Id: render.cpp,v 1.28 2004-07-04 21:18:05 harekiet Exp $ */ #include #include @@ -29,6 +29,7 @@ #include "setup.h" #include "mapper.h" #include "cross.h" +#include "hardware.h" #include "support.h" #include "render_scalers.h" @@ -69,7 +70,6 @@ static struct { #if (C_SSHOT) struct { Bitu bpp,width,height,rowlen; - const char * dir; Bit8u * buffer,* draw; bool take,taking; } shot; @@ -92,8 +92,6 @@ static void RENDER_ShotDraw(const Bit8u * src) { /* Take a screenshot of the data that should be rendered */ static void TakeScreenShot(Bit8u * bitmap) { - Bitu last=0;char file_name[CROSS_LEN]; - DIR * dir;struct dirent * dir_ent; png_structp png_ptr; png_infop info_ptr; png_bytep * row_pointers; @@ -101,30 +99,9 @@ static void TakeScreenShot(Bit8u * bitmap) { Bitu i; /* Find a filename to open */ - dir=opendir(render.shot.dir); - if (!dir) { - LOG_MSG("Can't open snapshot directory %s",render.shot.dir); - return; - } - while (dir_ent=readdir(dir)) { - char tempname[CROSS_LEN]; - strcpy(tempname,dir_ent->d_name); - char * test=strstr(tempname,".png"); - if (!test) continue; - *test=0; - if (strlen(tempname)<5) continue; - if (strncmp(tempname,"snap",4)!=0) continue; - Bitu num=atoi(&tempname[4]); - if (num>=last) last=num+1; - } - closedir(dir); - sprintf(file_name,"%s%csnap%04d.png",render.shot.dir,CROSS_FILESPLIT,last); /* Open the actual file */ - FILE * fp=fopen(file_name,"wb"); - if (!fp) { - LOG_MSG("Can't open file %s for snapshot",file_name); - return; - } + FILE * fp=OpenCaptureFile("Screenshot",".png"); + if (!fp) return; /* First try to alloacte the png structures */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL, NULL); if (!png_ptr) return; @@ -179,7 +156,6 @@ static void TakeScreenShot(Bit8u * bitmap) { /*clean up dynamically allocated RAM.*/ free(row_pointers); - LOG_MSG("Took snapshot in file %s",file_name); } static void EnableScreenShot(void) { @@ -407,7 +383,6 @@ void RENDER_Init(Section * sec) { render.frameskip.count=0; render.updating=true; #if (C_SSHOT) - render.shot.dir=section->Get_string("snapdir"); MAPPER_AddHandler(EnableScreenShot,MK_f5,MMOD1,"scrshot","Screenshot"); #endif const char * scaler;std::string cline; From 82b5755fb23444ad43304d75551b0fa9e63ebabc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 4 Jul 2004 21:18:12 +0000 Subject: [PATCH 1785/4131] Check if capture file fails to open Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1867 --- src/hardware/adlib.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index f5237aff..faffc3a2 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -268,16 +268,17 @@ static void OPL_SaveRawEvent(void) { fwrite(dro_header,1,sizeof(dro_header),opl.raw.handle); fclose(opl.raw.handle); opl.raw.handle=0; - return; + } else { + opl.raw.handle=OpenCaptureFile("Raw Opl",".dro"); + if (!opl.raw.handle) return; + opl.raw.index=0; + opl.raw.used=0; + opl.raw.done=0; + opl.raw.start=0; + opl.raw.last=0; + memset(opl.raw.buffer,0,sizeof(opl.raw.buffer)); + fwrite(dro_header,1,sizeof(dro_header),opl.raw.handle); } - opl.raw.handle=OpenCaptureFile("Raw Opl",".dro"); - opl.raw.index=0; - opl.raw.used=0; - opl.raw.done=0; - opl.raw.start=0; - opl.raw.last=0; - memset(opl.raw.buffer,0,sizeof(opl.raw.buffer)); - fwrite(dro_header,1,sizeof(dro_header),opl.raw.handle); } static void OPL_Stop(Section* sec) { From af71d40be2750eace9b7269a750f88d079c0b3c4 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 4 Jul 2004 21:33:06 +0000 Subject: [PATCH 1786/4131] Don't allow 16-bit soundblaster if machine!=vga Disable the mixer ports for lower than sbpro version Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1868 --- src/hardware/sblaster.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index fb399522..3b935f7d 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -244,7 +244,7 @@ static void DSP_DMA_CallBack(DmaChannel * chan, DMAEvent event) { if (sb.mode==MODE_DMA_WAIT) { DSP_ChangeMode(MODE_DMA); CheckDMAEnd(); - LOG(LOG_SB,LOG_NORMAL)("DMA Activated,starting output"); + LOG(LOG_SB,LOG_NORMAL)("DMA Activated,starting output, block %X",chan->basecnt); } else if (event==DMA_TRANSFEREND) { if (sb.mode==MODE_DMA) sb.mode=MODE_DMA_WAIT; } @@ -458,7 +458,7 @@ static void GenerateSound(Bitu size) { } case MODE_DMA: { - Bitu len=size*sb.dma.rate_mul; + Bitu len=samples*sb.dma.rate_mul; if (len & 0xffff) len=1+(len>>16); else len>>=16; if (sb.dma.stereo && (len & 1)) len++; @@ -1020,6 +1020,8 @@ void SBLASTER_Init(Section* sec) { else if (!strcasecmp(sbtype,"sb16")) sb.type=SBT_16; else if (!strcasecmp(sbtype,"none")) sb.type=SBT_NONE; else sb.type=SBT_16; + + if (machine!=MCH_VGA && sb.type==SBT_16) sb.type=SBT_PRO2; /* OPL/CMS Init */ const char * omode=section->Get_string("oplmode"); @@ -1066,10 +1068,11 @@ void SBLASTER_Init(Section* sec) { for (i=4;i<0xf;i++) { if (i==8 || i==9) continue; + //Disable mixer ports for lower soundblaster + if (sb.type Date: Mon, 5 Jul 2004 08:36:26 +0000 Subject: [PATCH 1787/4131] fix compilation bug Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1869 --- src/gui/midi_oss.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index d770a12a..e7c66bde 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -47,7 +47,7 @@ public: }; void PlayMsg(Bit8u * msg) { Bit8u buf[128];Bitu pos=0; - Bitu len=MIDI_evt_len[msg & 0xff]; + Bitu len=MIDI_evt_len[*msg]; for (;len>0;len--) { buf[pos++] = SEQ_MIDIPUTC; buf[pos++] = *msg; From 39de9f88c6424ed8519a20e62d513152159d6b0a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 5 Jul 2004 11:54:53 +0000 Subject: [PATCH 1788/4131] change const char * to char * Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1870 --- src/dos/dos_execute.cpp | 4 ++-- src/gui/sdlmain.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 54885eb6..b0d0c54a 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.40 2004-06-17 17:40:02 harekiet Exp $ */ +/* $Id: dos_execute.cpp,v 1.41 2004-07-05 11:54:44 harekiet Exp $ */ #include #include @@ -27,7 +27,7 @@ #include "callback.h" #include "debug.h" -const char * RunningProgram="DOSBOX"; +char * RunningProgram="DOSBOX"; #ifdef _MSC_VER #pragma pack(1) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 9ed5448c..9171947d 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.67 2004-06-13 12:10:08 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.68 2004-07-05 11:54:53 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -165,7 +165,7 @@ struct SDL_Block { static SDL_Block sdl; static void CaptureMouse(void); -extern const char * RunningProgram; +extern char * RunningProgram; void GFX_SetTitle(Bits cycles,Bits frameskip){ char title[200]={0}; static Bits internal_cycles=0; From e4a18c55744fec3f618f035dd2b6f3d95b5e4144 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 5 Jul 2004 11:57:53 +0000 Subject: [PATCH 1789/4131] Only allow valid midi commands with length>0 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1871 --- src/gui/midi.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index ebc8550e..c4ce0ea2 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -203,14 +203,16 @@ void MIDI_RawOutByte(Bit8u data) { midi.sysex.used=1; } } - midi.cmd_buf[midi.cmd_pos++]=data; - if (midi.cmd_len && midi.cmd_pos >= midi.cmd_len) { - if (midi.raw.handle) { - RawAddDelta(); - RawAddData(midi.cmd_buf,midi.cmd_len); + if (midi.cmd_len) { + midi.cmd_buf[midi.cmd_pos++]=data; + if (midi.cmd_pos >= midi.cmd_len) { + if (midi.raw.handle) { + RawAddDelta(); + RawAddData(midi.cmd_buf,midi.cmd_len); + } + midi.handler->PlayMsg(midi.cmd_buf); + midi.cmd_pos=1; //Use Running status } - midi.handler->PlayMsg(midi.cmd_buf); - midi.cmd_pos=1; //Use Running status } } From b3e0ba59e59ebbb3ae5f346a507721d6a19ee9cc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 5 Jul 2004 12:00:26 +0000 Subject: [PATCH 1790/4131] change const char * to char * for the trim functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1872 --- include/support.h | 6 +++--- src/misc/support.cpp | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/support.h b/include/support.h index a8ffdc1d..f0973328 100644 --- a/include/support.h +++ b/include/support.h @@ -38,9 +38,9 @@ #endif void strreplace(char * str,char o,char n); -char *ltrim(const char *str); -char *rtrim(const char *str); -char *trim(const char *str); +char *ltrim(char *str); +char *rtrim(char *str); +char *trim(char * str); bool ScanCMDBool(char * cmd,char * check); char * ScanCMDRemain(char * cmd); diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 4b19768a..c6da6166 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.23 2004-05-11 19:00:32 harekiet Exp $ */ +/* $Id: support.cpp,v 1.24 2004-07-05 12:00:22 harekiet Exp $ */ #include #include @@ -47,20 +47,20 @@ void strreplace(char * str,char o,char n) { str++; } } -char *ltrim(const char *str) { +char *ltrim(char *str) { while (*str && (*str==' ' || *str=='\t')) str++; - return (char*)str; + return str; } -char *rtrim(const char *str) { +char *rtrim(char *str) { char *p; p = strchr(str, '\0'); while (--p >= str && isspace(*p)); p[1] = '\0'; - return (char*)str; + return str; } -char *trim(const char *str) { +char *trim(char *str) { return ltrim(rtrim(str)); } From 5ca7ccb6104a99b3150fce54accc9bd17afcef8b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 5 Jul 2004 12:03:15 +0000 Subject: [PATCH 1791/4131] Remove pic_reqisterirq,pic_freeirq calls Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1873 --- include/pic.h | 5 ----- src/hardware/pic.cpp | 20 +------------------- src/hardware/serialport.cpp | 5 ----- 3 files changed, 1 insertion(+), 29 deletions(-) diff --git a/include/pic.h b/include/pic.h index 35b0d7a8..aadab912 100644 --- a/include/pic.h +++ b/include/pic.h @@ -50,17 +50,12 @@ INLINE Bit64u PIC_MicroCount(void) { } void PIC_ActivateIRQ(Bitu irq); - void PIC_DeActivateIRQ(Bitu irq); void PIC_runIRQs(void); - -void PIC_RegisterIRQ(Bitu irq,PIC_EOIHandler handler,char * name); -void PIC_FreeIRQ(Bitu irq); bool PIC_RunQueue(void); void PIC_AddEvent(PIC_EventHandler handler,Bitu delay,Bitu val=0); - void PIC_RemoveEvents(PIC_EventHandler handler); void PIC_SetIRQMask(Bitu irq, bool masked); diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 8b4efe0d..cc2a99a9 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.21 2004-05-04 18:34:08 qbix79 Exp $ */ +/* $Id: pic.cpp,v 1.22 2004-07-05 12:02:40 harekiet Exp $ */ #include @@ -33,8 +33,6 @@ struct IRQ_Block { bool active; bool inservice; Bitu vector; - char * name; - PIC_EOIHandler * handler; }; struct PIC_Controller { @@ -94,7 +92,6 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { case 0x20:case 0x21:case 0x22:case 0x23:case 0x24:case 0x25:case 0x26:case 0x27: if (PIC_IRQActive<(irq_base+8)) { irqs[PIC_IRQActive].inservice=false; - if (irqs[PIC_IRQActive].handler!=0) irqs[PIC_IRQActive].handler(); PIC_IRQActive=PIC_NOIRQ; for (i=0; i<=15; i++){ if(irqs[IRQ_priority_table[i]].inservice) { @@ -113,7 +110,6 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { /* Spefific EOI 0-7 */ if (PIC_IRQActive==(irq_base+val-0x60U)) { irqs[PIC_IRQActive].inservice=false; - if (irqs[PIC_IRQActive].handler!=0) irqs[PIC_IRQActive].handler(); PIC_IRQActive=PIC_NOIRQ; for (i=0; i<=15; i++) { if (irqs[IRQ_priority_table[i]].inservice) { @@ -219,20 +215,6 @@ static Bitu read_data(Bitu port,Bitu iolen) { return ret; } -void PIC_RegisterIRQ(Bitu irq,PIC_EOIHandler handler,char * name) { - if (irq>15) E_Exit("PIC:Illegal IRQ"); - irqs[irq].name=name; - irqs[irq].handler=handler; -} - -void PIC_FreeIRQ(Bitu irq) { - if (irq>15) E_Exit("PIC:Illegal IRQ"); - irqs[irq].name=0; - irqs[irq].handler=0; - irqs[irq].active=0; - irqs[irq].inservice=0; - PIC_IRQCheck&=~(1 << irq); -} void PIC_ActivateIRQ(Bitu irq) { if (irq<16) { diff --git a/src/hardware/serialport.cpp b/src/hardware/serialport.cpp index 77823315..56c6a400 100644 --- a/src/hardware/serialport.cpp +++ b/src/hardware/serialport.cpp @@ -240,13 +240,8 @@ CSerial::CSerial (Bit16u initbase, Bit8u initirq, Bit32u initbps) { IO_RegisterReadHandler(i+8,ReadSerial,IO_MB); } - PIC_RegisterIRQ(irq,0,"SERIAL"); - rqueue=new CFifo(QUEUE_SIZE); tqueue=new CFifo(QUEUE_SIZE); - - - }; CSerial::~CSerial(void) From d70c5b1f8fc996f6655b1908efa2984d7032fe39 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 5 Jul 2004 16:00:22 +0000 Subject: [PATCH 1792/4131] Fix wave capturing not keeping track of length of data Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1874 --- src/hardware/mixer.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index d32852df..1031fc18 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -220,6 +220,7 @@ static void MIXER_MixData(Bitu samples) { } if (mixer.wave.used>(MIXER_WAVESIZE-1024)){ fwrite(mixer.wave.buf,1,mixer.wave.used*MIXER_SSIZE,mixer.wave.handle); + mixer.wave.length+=mixer.wave.used*MIXER_SSIZE; mixer.wave.used=0; } } @@ -267,11 +268,12 @@ static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { static void MIXER_WaveEvent(void) { /* Check for previously opened wave file */ if (mixer.wave.handle) { - LOG_MSG("Stopped recording"); + LOG_MSG("Stopped capturing wave output."); /* Write last piece of audio in buffer */ fwrite(mixer.wave.buf,1,mixer.wave.used*MIXER_SSIZE,mixer.wave.handle); + mixer.wave.length+=mixer.wave.used*MIXER_SSIZE; /* Fill in the header with useful information */ - host_writed(&wavheader[4],mixer.wave.length+sizeof(wavheader)-8); + host_writed(&wavheader[0x04],mixer.wave.length+sizeof(wavheader)-8); host_writed(&wavheader[0x18],mixer.freq); host_writed(&wavheader[0x1C],mixer.freq*4); host_writed(&wavheader[0x28],mixer.wave.length); @@ -280,13 +282,13 @@ static void MIXER_WaveEvent(void) { fwrite(wavheader,1,sizeof(wavheader),mixer.wave.handle); fclose(mixer.wave.handle); mixer.wave.handle=0; - return; + } else { + mixer.wave.handle=OpenCaptureFile("Wave Output",".wav"); + if (!mixer.wave.handle) return; + mixer.wave.length=0; + mixer.wave.used=0; + fwrite(wavheader,1,sizeof(wavheader),mixer.wave.handle); } - mixer.wave.handle=OpenCaptureFile("Wave Outut",".wav"); - if (!mixer.wave.handle) return; - mixer.wave.length=0; - mixer.wave.used=0; - fwrite(wavheader,1,sizeof(wavheader),mixer.wave.handle); } static void MIXER_Stop(Section* sec) { From 7d03a1a0d8f63647f79b00ffc7a3d978ad7d2ba8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 6 Jul 2004 07:50:30 +0000 Subject: [PATCH 1793/4131] Improve raw adlib capturing to start with first note played Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1875 --- src/hardware/adlib.cpp | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index faffc3a2..7080707d 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -91,6 +91,7 @@ static struct { Bit16s mixbuf[2][128]; struct { FILE * handle; + bool capturing; Bit32u start; Bit32u last; Bit8u index; @@ -154,7 +155,7 @@ void OPL_Write(Bitu port,Bitu val,Bitu iolen) { if (port&1) { Bitu index=port>>1; opl.raw.regs[index][opl.raw.cmd[index]]=val; - if (opl.raw.handle) OPL_RawAdd(index,val); + if (opl.raw.capturing) OPL_RawAdd(index,val); } else opl.raw.cmd[port>>1]=val; if (!port) adlib_commandreg=val; switch (opl.mode) { @@ -194,21 +195,32 @@ static void OPL_RawEmptyBuffer(void) { #define ADDBUF(_VAL_) opl.raw.buffer[opl.raw.used++]=_VAL_; static void OPL_RawAdd(Bitu index,Bitu val) { /* Check if we have yet to start */ - if (!opl.raw.start) { + Bit8u cmd=opl.raw.cmd[index]; + if (cmd<=3) return; + if (!opl.raw.handle) { + if (cmd<0xb0 || cmd>0xb8) return; + if (!(val&0x20)) return; Bitu i; opl.raw.last=PIC_Ticks; opl.raw.start=PIC_Ticks; + opl.raw.handle=OpenCaptureFile("Raw Opl",".dro"); + if (!opl.raw.handle) { + opl.raw.capturing=false; + return; + } + memset(opl.raw.buffer,0,sizeof(opl.raw.buffer)); + fwrite(dro_header,1,sizeof(dro_header),opl.raw.handle); /* Check the registers to add */ for (i=4;i<256;i++) { if (!opl.raw.regs[0][i]) continue; - if ((i &0xe0)==0xb0) continue; + if (i>=0xb0 && i<=0xb8) continue; ADDBUF((Bit8u)i); ADDBUF(opl.raw.regs[0][i]); } bool donesecond=false; for (i=4;i<256;i++) { if (!opl.raw.regs[0][i]) continue; - if ((i&0xe0)==0xb0) continue; + if (i>=0xb0 && i<=0xb8) continue; if (!donesecond) { donesecond=true; ADDBUF(0x3); @@ -246,7 +258,7 @@ static void OPL_RawAdd(Bitu index,Bitu val) { opl.raw.index=index; ADDBUF(opl.raw.index ? 0x3 : 0x2); } - ADDBUF(opl.raw.cmd[opl.raw.index]); + ADDBUF(cmd); ADDBUF(val); if (opl.raw.used>=RAW_SIZE) OPL_RawEmptyBuffer(); } @@ -254,7 +266,6 @@ static void OPL_RawAdd(Bitu index,Bitu val) { static void OPL_SaveRawEvent(void) { /* Check for previously opened wave file */ if (opl.raw.handle) { - LOG_MSG("Stopping Raw OPL capturing."); OPL_RawEmptyBuffer(); /* Fill in the header with useful information */ host_writed(&dro_header[0x08],opl.raw.last-opl.raw.start); @@ -268,16 +279,18 @@ static void OPL_SaveRawEvent(void) { fwrite(dro_header,1,sizeof(dro_header),opl.raw.handle); fclose(opl.raw.handle); opl.raw.handle=0; + } + if (opl.raw.capturing) { + opl.raw.capturing=false; + LOG_MSG("Stopping Raw OPL capturing."); } else { - opl.raw.handle=OpenCaptureFile("Raw Opl",".dro"); - if (!opl.raw.handle) return; + LOG_MSG("Preparing to capture Raw OPL, will start with first note played."); + opl.raw.capturing=true; opl.raw.index=0; opl.raw.used=0; opl.raw.done=0; opl.raw.start=0; opl.raw.last=0; - memset(opl.raw.buffer,0,sizeof(opl.raw.buffer)); - fwrite(dro_header,1,sizeof(dro_header),opl.raw.handle); } } @@ -309,7 +322,7 @@ void OPL_Init(Section* sec,Bitu base,OPL_Mode oplmode,Bitu rate) { opl.active=false; opl.last_used=0; opl.mode=oplmode; - memset(opl.raw.regs,0,sizeof(opl.raw.regs)); + memset(&opl.raw,0,sizeof(opl.raw)); opl.chan=MIXER_AddChannel(OPL_CallBack,rate,"FM"); MIXER_SetMode(opl.chan,(opl.mode>OPL_opl2) ? MIXER_16STEREO : MIXER_16MONO); MIXER_Enable(opl.chan,false); From 53fa77866ad84923a4eed565d88cc0626ac2ddf5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 6 Jul 2004 17:12:28 +0000 Subject: [PATCH 1794/4131] Allow timer to be virtualized. (c2woody) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1876 --- src/ints/bios.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 43240562..e5817e2a 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.33 2004-06-20 16:56:55 harekiet Exp $ */ +/* $Id: bios.cpp,v 1.34 2004-07-06 17:12:28 qbix79 Exp $ */ #include #include "dosbox.h" @@ -139,7 +139,6 @@ static Bitu INT8_Handler(void) { Bit16u oldax = reg_ax; // run int 1c CALLBACK_RunRealInt(0x1c); - IO_Write(0x20,0x20); // restore old values SegSet16(ds,oldds); reg_dx = olddx; @@ -420,6 +419,17 @@ void BIOS_Init(Section* sec) { //a new system call_int8=CALLBACK_Allocate(); CALLBACK_Setup(call_int8,&INT8_Handler,CB_IRET); + phys_writeb(CB_BASE+(call_int8<<4)+0,(Bit8u)0xFE); //GRP 4 + phys_writeb(CB_BASE+(call_int8<<4)+1,(Bit8u)0x38); //Extra Callback instruction + phys_writew(CB_BASE+(call_int8<<4)+2,call_int8); //The immediate word + phys_writeb(CB_BASE+(call_int8<<4)+4,(Bit8u)0x50); // push ax + phys_writeb(CB_BASE+(call_int8<<4)+5,(Bit8u)0xb0); // mov al, 0x20 + phys_writeb(CB_BASE+(call_int8<<4)+6,(Bit8u)0x20); + phys_writeb(CB_BASE+(call_int8<<4)+7,(Bit8u)0xe6); // out 0x20, al + phys_writeb(CB_BASE+(call_int8<<4)+8,(Bit8u)0x20); + phys_writeb(CB_BASE+(call_int8<<4)+9,(Bit8u)0x58); // pop ax + phys_writeb(CB_BASE+(call_int8<<4)+10,(Bit8u)0xcf); // iret + mem_writed(BIOS_TIMER,0); //Calculate the correct time RealSetVec(0x8,CALLBACK_RealPointer(call_int8)); /* INT 11 Get equipment list */ From 08b6d96b7bf43b1bb84028d4bb51ca8673cb7cc3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 6 Jul 2004 19:12:28 +0000 Subject: [PATCH 1795/4131] Little hack for larry 6 mouse stuck at right side Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1877 --- src/ints/mouse.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 04b4f9d1..fb64f0d0 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.38 2004-04-24 17:57:38 harekiet Exp $ */ +/* $Id: mouse.cpp,v 1.39 2004-07-06 19:12:28 qbix79 Exp $ */ #include #include @@ -705,6 +705,7 @@ static Bitu INT33_Handler(void) { mouse.sub_mask=reg_cx; mouse.sub_seg=SegValue(es); mouse.sub_ofs=reg_dx; + mouse.max_x=CurMode->swidth;//Larry 6 break; case 0x0f: /* Define mickey/pixel rate */ SetMickeyPixelRate(reg_cx,reg_dx); From 8126b4002c170702d8bded4d6b6c2054cc34a040 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 8 Jul 2004 07:09:30 +0000 Subject: [PATCH 1796/4131] Change the way the callback_idle call wastes cpu power Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1878 --- src/cpu/callback.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index ed9ffdfc..d12eb49e 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.19 2004-01-07 20:23:48 qbix79 Exp $ */ +/* $Id: callback.cpp,v 1.20 2004-07-08 07:09:30 harekiet Exp $ */ #include #include @@ -67,8 +67,7 @@ void CALLBACK_Idle(void) { reg_eip=oldeip; SegSet16(cs,oldcs); SETFLAGBIT(IF,oldIF); - if (CPU_CycleLeft<300) CPU_CycleLeft=1; - else CPU_CycleLeft-=300; + if (CPU_Cycles>0) CPU_Cycles=0; } static Bitu default_handler(void) { From f84843769bc79d8b8004c7f2ff5928ae8ddcf2f7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 8 Jul 2004 17:13:10 +0000 Subject: [PATCH 1797/4131] Enable double scan for cga videomodes in vga Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1879 --- src/ints/int10_modes.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 2ef66b04..8732f5bf 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -20,9 +20,9 @@ VideoModeBlock ModeList_VGA[]={ { 0x001 ,M_TEXT ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, { 0x002 ,M_TEXT ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, { 0x003 ,M_TEXT ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, -{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, -{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, -{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, +{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, { 0x007 ,M_TEXT ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, { 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, @@ -465,6 +465,9 @@ bool INT10_SetVideoMode(Bitu mode) { case M_LIN8: underline=0x60; //Seems to enable the every 4th clock on my s3 break; + case M_CGA4: + max_scanline|=1; + break; } IO_Write(crtc_base,0x09);IO_Write(crtc_base+1,max_scanline); IO_Write(crtc_base,0x14);IO_Write(crtc_base+1,underline); From 36d07f2f46914ef4ba2257692e909a5fcb88330e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 8 Jul 2004 17:20:59 +0000 Subject: [PATCH 1798/4131] Handle width and height doubling slightly better and allow vga height stretching again Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1880 --- include/vga.h | 8 +-- src/hardware/vga_draw.cpp | 133 +++++++++++++++++--------------------- 2 files changed, 63 insertions(+), 78 deletions(-) diff --git a/include/vga.h b/include/vga.h index bd6dd84f..af45a822 100644 --- a/include/vga.h +++ b/include/vga.h @@ -23,12 +23,12 @@ #include "dosbox.h" enum VGAModes { - M_TEXT, - M_HERC_GFX,M_HERC_TEXT, M_CGA2,M_CGA4, M_EGA16, M_VGA, M_LIN8, + M_TEXT, + M_HERC_GFX,M_HERC_TEXT, M_CGA16,M_TANDY2,M_TANDY4,M_TANDY16,M_TANDY_TEXT, M_ERROR, }; @@ -114,10 +114,8 @@ typedef struct { Bitu hend; Bitu parts; } micro; - Bitu scaleh; bool double_scan; - bool double_scan_active; - Bit8u font_height; + bool doublewidth,doubleheight; Bit8u font[64*1024]; Bit8u * font_tables[2]; Bitu blinking; diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index ce14ddc2..891a2895 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -31,7 +31,6 @@ typedef Bit8u * (* VGA_Line_Handler)(Bitu vidstart,Bitu panning,Bitu line); static VGA_Line_Handler VGA_DrawLine; static Bit8u TempLine[1280]; - static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; for (Bitu x=vga.draw.blocks;x>0;x--) { @@ -171,8 +170,6 @@ static void VGA_HorizontalTimer(void) { } static void VGA_DrawPart(Bitu lines) { - Bitu subline=0;Bitu vidofs=vga.config.real_start; - Bit8u * draw=0; while (lines--) { vga.draw.lines_done++; Bit8u * data=VGA_DrawLine(vga.draw.address,vga.draw.panning,vga.draw.address_line); @@ -187,10 +184,11 @@ static void VGA_DrawPart(Bitu lines) { vga.draw.address_line=0; } } - vga.draw.parts_left--; - if (vga.draw.parts_left) { - PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts,vga.draw.parts_lines); + if (--vga.draw.parts_left) { + PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts, + (vga.draw.parts_left!=1) ? vga.draw.parts_lines : (vga.draw.lines_total - vga.draw.lines_done)); } else { + vga.draw.drawing=false; RENDER_EndUpdate(); } } @@ -235,7 +233,8 @@ static void VGA_VerticalTimer(Bitu val) { break; } if (machine==MCH_TANDY) vga.draw.address+=vga.tandy.disp_bank << 14; - if (RENDER_StartUpdate()) { + if (!vga.draw.drawing && RENDER_StartUpdate()) { + vga.draw.drawing=true; PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts,vga.draw.parts_lines); } } @@ -313,17 +312,19 @@ void VGA_SetupDrawing(Bitu val) { if (vga.seq.clocking_mode & 0x8) { htotal*=2; } - vga.draw.font_height=(vga.crtc.maximum_scan_line&0xf)+1; + vga.draw.address_line_total=(vga.crtc.maximum_scan_line&0xf)+1; /* Check for dual transfer whatever thing,master clock/2 */ if (vga.s3.pll.cmd & 0x10) clock/=2; + vga.draw.double_scan=(vga.crtc.maximum_scan_line&0x80)>0; } else { - vga.draw.font_height=vga.other.max_scanline+1; + vga.draw.address_line_total=vga.other.max_scanline+1; htotal=vga.other.htotal; hdispend=vga.other.hdend; hrstart=vga.other.hsyncp; - vtotal=vga.draw.font_height*vga.other.vtotal+vga.other.vadjust; - vdispend=vga.draw.font_height*vga.other.vdend; - vrstart=vga.draw.font_height*vga.other.vsyncp; + vtotal=vga.draw.address_line_total*vga.other.vtotal+vga.other.vadjust; + vdispend=vga.draw.address_line_total*vga.other.vdend; + vrstart=vga.draw.address_line_total*vga.other.vsyncp; + vga.draw.double_scan=false; switch (machine) { case MCH_CGA: case MCH_TANDY: @@ -352,29 +353,20 @@ void VGA_SetupDrawing(Bitu val) { double correct_ratio=(100.0/525.0); double aspect_ratio=((double)htotal/((double)vtotal)/correct_ratio); - + vga.draw.resizing=false; - Bitu width,height; - Bitu scalew=1; - Bitu scaleh=1; - width=hdispend; - height=vdispend; - vga.draw.double_scan=false; + Bitu width=hdispend; + Bitu height=vdispend; + bool doubleheight=false; + bool doublewidth=false; switch (vga.mode) { case M_VGA: - scalew=2;scaleh*=vga.draw.font_height; - if (vga.crtc.maximum_scan_line&0x80) scaleh*=2; - vga.draw.lines_scaled=scaleh; - vga.draw.address_line_total=1; - height/=scaleh;width<<=2; + doublewidth=true; + width<<=2; VGA_DrawLine=VGA_Draw_VGA_Line; break; case M_LIN8: - scaleh*=vga.draw.font_height; - if (vga.crtc.maximum_scan_line&0x80) scaleh*=2; - vga.draw.lines_scaled=scaleh; - vga.draw.address_line_total=1; - height/=scaleh;width<<=3; + width<<=3; /* Use HW mouse cursor drawer if enabled */ if(vga.s3.hgc.curmode & 0x1) { VGA_DrawLine=VGA_Draw_VGA_Line_HWMouse; @@ -383,85 +375,65 @@ void VGA_SetupDrawing(Bitu val) { } break; case M_EGA16: - scaleh*=vga.draw.font_height; - if (vga.crtc.maximum_scan_line&0x80) scaleh*=2; - vga.draw.lines_scaled=scaleh; - if (vga.seq.clocking_mode & 0x8) scalew*=2; - width<<=3;height/=scaleh; - vga.draw.address_line_total=1; + doublewidth=(vga.seq.clocking_mode & 0x8) > 0; + width<<=3; VGA_DrawLine=VGA_Draw_EGA_Line; break; case M_CGA4: - scaleh=2;scalew*=2; + doublewidth=true; vga.draw.blocks=width*2; - vga.draw.lines_scaled=1; - vga.draw.address_line_total=2; - width<<=3;height/=2; + width<<=3; VGA_DrawLine=VGA_Draw_2BPP_Line; break; case M_CGA2: - scaleh=2; + doubleheight=true; vga.draw.blocks=width; - vga.draw.lines_scaled=1; - vga.draw.address_line_total=2; - width<<=4;height/=2; + width<<=4; VGA_DrawLine=VGA_Draw_1BPP_Line; break; case M_TEXT: aspect_ratio=1.0; - vga.draw.address_line_total=vga.draw.font_height; vga.draw.blocks=width; - if (vga.seq.clocking_mode & 0x8) scalew*=2; - if (vga.crtc.maximum_scan_line&0x80) scaleh*=2; - height/=scaleh; - vga.draw.lines_scaled=scaleh; + doublewidth=(vga.seq.clocking_mode & 0x8) > 0; width<<=3; /* 8 bit wide text font */ VGA_DrawLine=VGA_TEXT_Draw_Line; break; case M_HERC_GFX: aspect_ratio=1.5; - vga.draw.address_line_total=vga.draw.font_height; vga.draw.blocks=width*2; - vga.draw.lines_scaled=1; width*=16; VGA_DrawLine=VGA_Draw_1BPP_Line; break; case M_TANDY2: - scaleh=2;aspect_ratio=1.2; - scalew=(vga.tandy.mode_control & 0x10) ? 1 : 2; - vga.draw.blocks=width*8/scalew; - vga.draw.address_line_total=vga.draw.font_height; - vga.draw.lines_scaled=1; + aspect_ratio=1.2; + doubleheight=true; + doublewidth=(vga.tandy.mode_control & 0x10)==0; + vga.draw.blocks=width * (doublewidth ? 4:8); width=vga.draw.blocks*2; VGA_DrawLine=VGA_Draw_1BPP_Line; break; case M_TANDY4: - scaleh=2;aspect_ratio=1.2; - scalew=(vga.tandy.mode_control & 0x10) ? 1 : 2; - vga.draw.blocks=width*8/scalew; - vga.draw.address_line_total=vga.draw.font_height; - vga.draw.lines_scaled=1; + aspect_ratio=1.2; + doubleheight=true; + doublewidth=(vga.tandy.mode_control & 0x10)==0; + vga.draw.blocks=width * (doublewidth ? 4:8); width=vga.draw.blocks*2; VGA_DrawLine=VGA_Draw_2BPP_Line; break; case M_TANDY16: - scaleh=2;aspect_ratio=1.2; - scalew=(vga.tandy.mode_control & 0x10) ? 1 : 2; - vga.draw.blocks=width*4/scalew; - vga.draw.address_line_total=vga.draw.font_height; - vga.draw.lines_scaled=1; + aspect_ratio=1.2; + doubleheight=true; + doublewidth=(vga.tandy.mode_control & 0x10)==0; + vga.draw.blocks=width * (doublewidth ? 2:4); width=vga.draw.blocks*2; VGA_DrawLine=VGA_Draw_4BPP_Line; break; case M_TANDY_TEXT: - scalew=(vga.tandy.mode_control & 0x1) ? 1 : 2; + doublewidth=(vga.tandy.mode_control & 0x1)==0; case M_HERC_TEXT: aspect_ratio=1; - scaleh=(vga.mode==M_HERC_TEXT) ? 1 : 2; - vga.draw.lines_scaled=1; - vga.draw.address_line_total=vga.draw.font_height; + doubleheight=(vga.mode!=M_HERC_TEXT); vga.draw.blocks=width; - vga.draw.lines_scaled=1; width<<=3; VGA_DrawLine=VGA_TEXT_Draw_Line; break; @@ -469,19 +441,34 @@ void VGA_SetupDrawing(Bitu val) { LOG(LOG_VGA,LOG_ERROR)("Unhandled VGA type %d while checking for resolution"); }; VGA_CheckScanLength(); + if (vga.draw.double_scan) { + height/=2; + doubleheight=true; + } + //Only check for exra double heigh in vga modes + if (!doubleheight && (vga.mode1,scaleh>1); + LOG(LOG_VGA,LOG_NORMAL)("%s width, %s height aspect %f", + doublewidth ? "double":"normal",doubleheight ? "double":"normal",aspect_ratio); + RENDER_SetSize(width,height,8,aspect_ratio,doublewidth,doubleheight); PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal); } }; From 3a98ced52cad0b37b6a2f970ccba78a1f0afd3d5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 8 Jul 2004 17:44:20 +0000 Subject: [PATCH 1799/4131] Fix annoying bugs with our crap log system Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1881 --- src/hardware/vga_draw.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 891a2895..6cc13fa9 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -464,10 +464,11 @@ void VGA_SetupDrawing(Bitu val) { vga.draw.doubleheight=doubleheight; if (doubleheight) vga.draw.lines_scaled=2; else vga.draw.lines_scaled=1; - +#if C_DEBUG LOG(LOG_VGA,LOG_NORMAL)("Width %d, Height %d, fps %f",width,height,fps); LOG(LOG_VGA,LOG_NORMAL)("%s width, %s height aspect %f", doublewidth ? "double":"normal",doubleheight ? "double":"normal",aspect_ratio); +#endif RENDER_SetSize(width,height,8,aspect_ratio,doublewidth,doubleheight); PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal); } From a5f73e86a571280320e5f4f6255a132ac04eb088 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 8 Jul 2004 20:08:52 +0000 Subject: [PATCH 1800/4131] Lot's of doschanges for enchanced mode. Thank you c2woody. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1882 --- include/dos_inc.h | 15 +++++--- src/dos/dos_classes.cpp | 35 +++++++++++++++++-- src/dos/dos_execute.cpp | 4 +-- src/dos/dos_memory.cpp | 2 +- src/dos/dos_misc.cpp | 37 +++++++++++++++++++- src/dos/dos_tables.cpp | 76 ++++++++++++++++++++++++++++------------- 6 files changed, 134 insertions(+), 35 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index f4a7f685..d566e819 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.46 2004-06-24 21:21:48 harekiet Exp $ */ +/* $Id: dos_inc.h,v 1.47 2004-07-08 20:08:52 qbix79 Exp $ */ #ifndef DOS_H_ #define DOS_H_ @@ -340,6 +340,10 @@ public: void SetFirstMCB(Bit16u _first_mcb); void SetfirstFileTable(RealPt _first_table); void SetBuffers(Bit16u x,Bit16u y); + void SetCurDirStruct(Bit32u _curdirstruct); + void SetFCBTable(Bit32u _fcbtable); + void SetDeviceChainStart(Bit32u _devchain); + void SetDiskInfoBuffer(Bit32u _dinfobuf); RealPt GetPointer (void); #ifdef _MSC_VER @@ -349,7 +353,7 @@ public: 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 stuff1[6]; // -0x12 some stuff, hopefully never used.... + 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 @@ -360,13 +364,16 @@ public: 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 discInfoBuffer; // 0x12 pointer to disc info buffer + RealPt diskInfoBuffer; // 0x12 pointer to disk info buffer RealPt curDirStructure; // 0x16 pointer to current array of directory structure RealPt fcbTable; // 0x1a pointer to system FCB table Bit16u protFCBs; // 0x1e protected fcbs Bit8u blockDevices; // 0x20 installed block devices Bit8u lastdrive; // 0x21 lastdrive - Bit8u stuff2[0x12]; // 0x22 NUL driver + 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 diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index a2bb9481..d81a55a8 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.38 2004-05-15 07:57:04 harekiet Exp $ */ +/* $Id: dos_classes.cpp,v 1.39 2004-07-08 20:08:52 qbix79 Exp $ */ #include #include @@ -65,8 +65,6 @@ void DOS_InfoBlock::SetLocation(Bit16u segment) /* Clear the initual Block */ for(Bitu i=0;i #include @@ -282,7 +282,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { if (!DOS_AllocateMemory(&pspseg,&memsize)) E_Exit("DOS:Exec error in memory"); loadseg=pspseg+16; if ((!iscom) & (head.minmemory == 0) & (head.maxmemory == 0)) - loadseg = (0x9fed0 - imagesize)/16; //c2woody + loadseg = (0x9e000 - imagesize)/16; //c2woody } else loadseg=block.overlay.loadseg; /* Load the executable */ diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 87461754..993af873 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -21,7 +21,7 @@ #include "dos_inc.h" -#define MEM_START 0x60 //First Segment that DOS can use +#define MEM_START 0x68 //First Segment that DOS can use //#define MEM_START 4000 //First Segment that DOS can use static Bit16u memAllocStrategy = 0x00; diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index eebf2348..428907bb 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_misc.cpp,v 1.10 2004-03-14 19:41:04 qbix79 Exp $ */ +/* $Id: dos_misc.cpp,v 1.11 2004-07-08 20:08:52 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" @@ -58,6 +58,41 @@ static Bitu INT2A_Handler(void) { static bool DOS_MultiplexFunctions(void) { switch (reg_ax) { + case 0x1607: + if (reg_bx == 0x15) { + switch (reg_cx) { + case 0x0000: // query instance + reg_cx = 0x0001; + reg_dx = 0x50; // dos driver segment + SegSet16(es,0x50); // patch table seg + reg_bx = 0x60; // patch table ofs + return true; + case 0x0001: // set patches + reg_ax = 0xb97c; + reg_bx = (reg_dx & 0x16); + reg_dx = 0xa2ab; + return true; + case 0x0003: // get size of data struc + if (reg_dx==0x0001) { + // CDS size requested + reg_ax = 0xb97c; + reg_dx = 0xa2ab; + reg_cx = 0x000e; // size + } + return true; + case 0x0004: // instanced data + reg_dx = 0; // none + return true; + case 0x0005: // get device driver size + reg_ax = 0; + reg_dx = 0; + return true; + default: + return false; + } + } + else if (reg_bx == 0x18) return true; // idle callout + else return false; case 0x1680: /* RELEASE CURRENT VIRTUAL MACHINE TIME-SLICE */ //TODO Maybe do some idling but could screw up other systems :) reg_al=0; diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index d3f55ff8..5411d1b6 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.12 2004-06-11 12:09:50 qbix79 Exp $ */ +/* $Id: dos_tables.cpp,v 1.13 2004-07-08 20:08:52 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -52,39 +52,67 @@ Bit16u DOS_GetMemory(Bit16u pages) { void DOS_SetupTables(void) { dos_memseg=0xd000; - Bit16u seg;Bitu i; + Bit16u seg,seg2;Bitu i; dos.tables.mediaid=RealMake(DOS_GetMemory(2),0); dos.tables.tempdta=RealMake(DOS_GetMemory(4),0); for (i=0;i20 detection routine */ /* Possibly obselete when SFT is properly handled */ - // CON string - real_writew(0x54,0x00+0x00, (Bit16u) 0x4f43); - real_writew(0x54,0x00+0x02, (Bit16u) 0x204e); - // CON string - real_writew(0x54,0x10+0x00, (Bit16u) 0x4f43); - real_writew(0x54,0x10+0x02, (Bit16u) 0x204e); - //CON string - real_writew(0x54,0x20+0x00, (Bit16u) 0x4f43); - real_writew(0x54,0x20+0x02, (Bit16u) 0x204e); + real_writed(0x5d,0x0a,0x204e4f43); + real_writed(0x5d,0x1a,0x204e4f43); + real_writed(0x5d,0x2a,0x204e4f43); + + /* create a CON device driver */ + seg=0x60; + real_writed(seg,0x00,0xffffffff); // next ptr + real_writew(seg,0x04,0x8013); // attributes + real_writed(seg,0x06,0xffffffff); // strategy routine + real_writed(seg,0x0a,0x204e4f43); // driver name + real_writed(seg,0x0e,0x20202020); // driver name + dos_infoblock.SetDeviceChainStart(RealMake(seg,0)); + + /* Create a fake SFT, so programs think there are 100 file handles */ + seg=0x62; + seg2=0x63; + real_writed(seg,0,seg2<<16); //Next File Table + real_writew(seg,4,100); //File Table supports 100 files + real_writed(seg2,0,0xffffffff); //Last File Table + real_writew(seg2,4,100); //File Table supports 100 files + dos_infoblock.SetfirstFileTable(RealMake(seg,0)); + + /* Create a fake CDS */ + seg=0x64; + real_writed(seg,0x00,0x005c3a43); + dos_infoblock.SetCurDirStruct(RealMake(seg,0)); + + - /* Allocate some fake memory else pharlab doesn't like the indos pointer */ - /* Pharlab seems to real picky. So don't change this unless needed (the amount of allocated memory that is) */ /* Allocate DCBS DOUBLE BYTE CHARACTER SET LEAD-BYTE TABLE */ dos.tables.dcbs=RealMake(DOS_GetMemory(12),0); mem_writew(Real2Phys(dos.tables.dcbs),0); //empty table - sdaseg=DOS_GetMemory(3); - DOS_SDA(sdaseg,0).Init(); + + /* Create a fake FCB SFT */ + seg=DOS_GetMemory(4); + real_writed(seg,0,0xffffffff); //Last File Table + real_writew(seg,4,100); //File Table supports 100 files + dos_infoblock.SetFCBTable(RealMake(seg,0)); + + /* Create a fake disk info buffer */ + seg=DOS_GetMemory(6); + seg2=DOS_GetMemory(6); + real_writed(seg,0x00,seg2<<16); + real_writed(seg2,0x00,0xffffffff); + real_writed(seg2,0x0d,0xffffffff); + dos_infoblock.SetDiskInfoBuffer(RealMake(seg,0)); + + /* Set buffers to a nice value */ + dos_infoblock.SetBuffers(50,50); } From ad67e9420cf2c1792ee3e01f2679af596f25beb7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 8 Jul 2004 20:50:10 +0000 Subject: [PATCH 1801/4131] Make sure that drawing related variables only get changed when an actual screen update can take place Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1883 --- src/hardware/vga_draw.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 6cc13fa9..d378224d 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -188,7 +188,6 @@ static void VGA_DrawPart(Bitu lines) { PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts, (vga.draw.parts_left!=1) ? vga.draw.parts_lines : (vga.draw.lines_total - vga.draw.lines_done)); } else { - vga.draw.drawing=false; RENDER_EndUpdate(); } } @@ -212,12 +211,15 @@ static void VGA_VerticalTimer(Bitu val) { vga.config.retrace=false; PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal); PIC_AddEvent(VGA_VerticalDisplayEnd,vga.draw.micro.vend); - vga.draw.parts_left=vga.draw.parts_total; - vga.draw.lines_done=0; - vga.draw.address=vga.config.real_start; - vga.draw.address_line=vga.config.hlines_skip; - vga.draw.split_line=(vga.config.line_compare/vga.draw.lines_scaled); - vga.draw.panning=vga.config.pel_panning; + if (RENDER_StartUpdate()) { + vga.draw.parts_left=vga.draw.parts_total; + vga.draw.lines_done=0; + vga.draw.address=vga.config.real_start; + vga.draw.address_line=vga.config.hlines_skip; + vga.draw.split_line=(vga.config.line_compare/vga.draw.lines_scaled); + vga.draw.panning=vga.config.pel_panning; + PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts,vga.draw.parts_lines); + } switch (vga.mode) { case M_TEXT: vga.draw.address=(vga.draw.address*2); @@ -233,10 +235,6 @@ static void VGA_VerticalTimer(Bitu val) { break; } if (machine==MCH_TANDY) vga.draw.address+=vga.tandy.disp_bank << 14; - if (!vga.draw.drawing && RENDER_StartUpdate()) { - vga.draw.drawing=true; - PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts,vga.draw.parts_lines); - } } void VGA_CheckScanLength(void) { @@ -457,7 +455,6 @@ void VGA_SetupDrawing(Bitu val) { PIC_RemoveEvents(VGA_VerticalTimer); PIC_RemoveEvents(VGA_VerticalDisplayEnd); PIC_RemoveEvents(VGA_DrawPart); - vga.draw.drawing=false; vga.draw.width=width; vga.draw.height=height; vga.draw.doublewidth=doublewidth; From 6d0bdfc5437776b8e2891baf1dbc4184e283ef00 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 9 Jul 2004 15:46:37 +0000 Subject: [PATCH 1802/4131] Fix mixer also being disabled for soundblaster v2.0 Add 16 bit irq acknowledgement Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1884 --- src/hardware/sblaster.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 3b935f7d..30934d5d 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -42,6 +42,7 @@ #define DSP_WRITE_DATA 0x0C #define DSP_WRITE_STATUS 0x0C #define DSP_READ_STATUS 0x0E +#define DSP_ACK_16BIT 0x0f #define DSP_NO_COMMAND 0 @@ -512,6 +513,8 @@ static void DSP_DoDMATranfser(DMA_MODES mode) { sb.tmp.index=0; sb.dma.rate_mul=(sb.dma.rate<<16)/sb.hw.rate; sb.tmp.add_index=(sb.dma.rate<<16)/sb.hw.rate; + sb.irq.pending_8bit=false; + sb.irq.pending_16bit=false; switch (mode) { case DSP_DMA_2:type="2-bits ADPCM";break; case DSP_DMA_3:type="3-bits ADPCM";break; @@ -945,6 +948,9 @@ static Bitu read_sb(Bitu port,Bitu iolen) { sb.irq.pending_8bit=false; if (sb.dsp.out.used) return 0xff; else return 0x7f; + case DSP_ACK_16BIT: + sb.irq.pending_16bit=false; + break; case DSP_WRITE_STATUS: switch (sb.dsp.state) { case DSP_S_NORMAL: @@ -1066,10 +1072,10 @@ void SBLASTER_Init(Section* sec) { MIXER_SetFreq(sb.chan,sb.hw.rate); MIXER_SetMode(sb.chan,MIXER_16STEREO); - for (i=4;i<0xf;i++) { + for (i=4;i<=0xf;i++) { if (i==8 || i==9) continue; //Disable mixer ports for lower soundblaster - if (sb.type Date: Sun, 11 Jul 2004 20:02:08 +0000 Subject: [PATCH 1803/4131] Removed larry 6 hack. Added some more information on the mode limits stuff. Added fix for wayne's World (ignoring set limit if limit_min is limit_max) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1885 --- src/ints/mouse.cpp | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index fb64f0d0..120d5983 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.39 2004-07-06 19:12:28 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.40 2004-07-11 20:02:08 qbix79 Exp $ */ #include #include @@ -508,13 +508,11 @@ void Mouse_NewVideoMode(void) { //Does way to much. Many of this stuff should be moved to mouse_reset one day WriteMouseIntVector(); -// real_writed(0,(0x74<<2),CALLBACK_RealPointer(call_int74)); if(MOUSE_IRQ > 7) { real_writed(0,((0x70+MOUSE_IRQ-8)<<2),CALLBACK_RealPointer(call_int74)); } else { real_writed(0,((0x8+MOUSE_IRQ)<<2),CALLBACK_RealPointer(call_int74)); } - mouse.shown=-1; /* Get the correct resolution from the current video mode */ Bitu mode=mem_readb(BIOS_VIDEO_MODE); @@ -548,15 +546,15 @@ void Mouse_NewVideoMode(void) LOG(LOG_MOUSE,LOG_ERROR)("Unhandled videomode %X on reset",mode); break; } - mouse.max_x=639; - mouse.min_x=0; - mouse.min_y=0; + mouse.max_x = 639; + mouse.min_x = 0; + mouse.min_y = 0; // Dont set max coordinates here. it is done by SetResolution! - mouse.x=0; // civ wont work otherwise - mouse.y=static_cast(mouse.max_y/2); - mouse.events=0; - mouse.mickey_x=0; - mouse.mickey_y=0; + mouse.x = 0; // civ wont work otherwise + mouse.y = static_cast(mouse.max_y / 2); + mouse.events = 0; + mouse.mickey_x = 0; + mouse.mickey_y = 0; mouse.hotx = 0; mouse.hoty = 0; @@ -661,10 +659,12 @@ static Bitu INT33_Handler(void) { } case 0x07: /* Define horizontal cursor range */ { //lemmings set 1-640 and wants that. iron seeds set 0-640 but doesn't like 640 + //Iron seed works if newvideo mode with mode 13 sets 0-639 + //Larry 6 actually wants newvideo mode with mode 13 to set it to 0-319 Bits max,min; if ((Bit16s)reg_cx<(Bit16s)reg_dx) { min=(Bit16s)reg_cx;max=(Bit16s)reg_dx;} else { min=(Bit16s)reg_dx;max=(Bit16s)reg_cx;} - //if(max - min + 1 > 640) max = min + 640 - 1; + if(min == max) break; //Wayne's World mouse.min_x=min; mouse.max_x=max; LOG(LOG_MOUSE,LOG_NORMAL)("Define Hortizontal range min:%d max:%d",min,max); @@ -677,7 +677,7 @@ static Bitu INT33_Handler(void) { Bits max,min; if ((Bit16s)reg_cx<(Bit16s)reg_dx) { min=(Bit16s)reg_cx;max=(Bit16s)reg_dx;} else { min=(Bit16s)reg_dx;max=(Bit16s)reg_cx;} - // if(static_cast(max - min + 1) > CurMode->sheight) max = min + CurMode->sheight - 1; + if(min == max) break; //Wayne's World mouse.min_y=min; mouse.max_y=max; LOG(LOG_MOUSE,LOG_NORMAL)("Define Vertical range min:%d max:%d",min,max); @@ -705,7 +705,6 @@ static Bitu INT33_Handler(void) { mouse.sub_mask=reg_cx; mouse.sub_seg=SegValue(es); mouse.sub_ofs=reg_dx; - mouse.max_x=CurMode->swidth;//Larry 6 break; case 0x0f: /* Define mickey/pixel rate */ SetMickeyPixelRate(reg_cx,reg_dx); @@ -905,7 +904,7 @@ void MOUSE_Init(Section* sec) { // Callback 0x33 CreateMouseCallback(); call_int74=CALLBACK_Allocate(); - CALLBACK_Setup(call_int74,&INT74_Handler,CB_IRET); + CALLBACK_Setup(call_int74,&INT74_Handler,CB_IRET,"int 74"); if(MOUSE_IRQ > 7) { real_writed(0,((0x70+MOUSE_IRQ-8)<<2),CALLBACK_RealPointer(call_int74)); } else { From 94795e0fd4882933fce8b8ab9a2ee397402765a8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 12 Jul 2004 12:42:20 +0000 Subject: [PATCH 1804/4131] Changed debugger key to Pause (was -)!!!! If non-debug mode => pause pauses dosbox. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1886 --- src/cpu/cpu.cpp | 10 +++++----- src/debug/debug.cpp | 4 ++-- src/dos/dos_execute.cpp | 6 +++--- src/gui/render.cpp | 10 +++++----- src/gui/sdlmain.cpp | 37 ++++++++++++++++++++++++++++++++++--- 5 files changed, 49 insertions(+), 18 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index c162cede..8a63b905 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.58 2004-06-10 07:13:02 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.59 2004-07-12 12:42:19 qbix79 Exp $ */ #include #include "dosbox.h" @@ -1290,7 +1290,7 @@ void CPU_ENTER(bool use32,Bitu bytes,Bitu level) { reg_esp=(reg_esp&~cpu.stack.mask)|((sp_index)&cpu.stack.mask); } -extern void GFX_SetTitle(Bits cycles ,Bits frameskip); +extern void GFX_SetTitle(Bits cycles ,Bits frameskip,bool paused); static void CPU_CycleIncrease(void) { Bits old_cycles=CPU_CycleMax; if(CPU_CycleUp < 100){ @@ -1302,7 +1302,7 @@ static void CPU_CycleIncrease(void) { CPU_CycleLeft=0;CPU_Cycles=0; if (CPU_CycleMax==old_cycles) CPU_CycleMax++; LOG_MSG("CPU:%d cycles",CPU_CycleMax); - GFX_SetTitle(CPU_CycleMax,-1); + GFX_SetTitle(CPU_CycleMax,-1,false); } static void CPU_CycleDecrease(void) { @@ -1314,7 +1314,7 @@ static void CPU_CycleDecrease(void) { CPU_CycleLeft=0;CPU_Cycles=0; if (CPU_CycleMax <= 0) CPU_CycleMax=1; LOG_MSG("CPU:%d cycles",CPU_CycleMax); - GFX_SetTitle(CPU_CycleMax,-1); + GFX_SetTitle(CPU_CycleMax,-1,false); } void CPU_Init(Section* sec) { @@ -1377,6 +1377,6 @@ void CPU_Init(Section* sec) { if(!CPU_CycleUp) CPU_CycleUp = 500; if(!CPU_CycleDown) CPU_CycleDown = 20; CPU_CycleLeft=0; - GFX_SetTitle(CPU_CycleMax,-1); + GFX_SetTitle(CPU_CycleMax,-1,false); } diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index e06baeb0..7528f506 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.55 2004-06-20 19:13:10 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.56 2004-07-12 12:42:19 qbix79 Exp $ */ #include "programs.h" @@ -1672,7 +1672,7 @@ void DEBUG_Init(Section* sec) { MSG_Add("DEBUG_CONFIGFILE_HELP","Nothing to setup yet!\n"); DEBUG_DrawScreen(); /* Add some keyhandlers */ - MAPPER_AddHandler(DEBUG_Enable,MK_kpminus,0,"debugger","Debugger"); + MAPPER_AddHandler(DEBUG_Enable,MK_pause,0,"debugger","Debugger"); /* Clear the TBreakpoint list */ memset((void*)&codeViewData,0,sizeof(codeViewData)); /* setup debug.com */ diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 5ebe6417..0d0622e5 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.42 2004-07-08 20:08:52 qbix79 Exp $ */ +/* $Id: dos_execute.cpp,v 1.43 2004-07-12 12:42:20 qbix79 Exp $ */ #include #include @@ -93,14 +93,14 @@ static void RestoreRegisters(void) { reg_sp+=18; } -extern void GFX_SetTitle(Bits cycles,Bits frameskip); +extern void GFX_SetTitle(Bits cycles,Bits frameskip,bool paused); void DOS_UpdatePSPName(void) { DOS_MCB mcb(dos.psp()-1); static char name[9]; mcb.GetFileName(name); if (!strlen(name)) strcpy(name,"DOSBOX"); RunningProgram=name; - GFX_SetTitle(-1,-1); + GFX_SetTitle(-1,-1,false); } bool DOS_Terminate(bool tsr) { diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 1e1abda6..50bdc749 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.28 2004-07-04 21:18:05 harekiet Exp $ */ +/* $Id: render.cpp,v 1.29 2004-07-12 12:42:20 qbix79 Exp $ */ #include #include @@ -360,17 +360,17 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,bool dblw,bool RENDER_ReInit(); } -extern void GFX_SetTitle(Bits cycles, Bits frameskip); +extern void GFX_SetTitle(Bits cycles, Bits frameskip,bool paused); static void IncreaseFrameSkip(void) { if (render.frameskip.max<10) render.frameskip.max++; LOG_MSG("Frame Skip at %d",render.frameskip.max); - GFX_SetTitle(-1,render.frameskip.max); + GFX_SetTitle(-1,render.frameskip.max,false); } static void DecreaseFrameSkip(void) { if (render.frameskip.max>0) render.frameskip.max--; LOG_MSG("Frame Skip at %d",render.frameskip.max); - GFX_SetTitle(-1,render.frameskip.max); + GFX_SetTitle(-1,render.frameskip.max,false); } void RENDER_Init(Section * sec) { @@ -404,6 +404,6 @@ void RENDER_Init(Section * sec) { } MAPPER_AddHandler(DecreaseFrameSkip,MK_f7,MMOD1,"decfskip","Dec Fskip"); MAPPER_AddHandler(IncreaseFrameSkip,MK_f8,MMOD1,"incfskip","Inc Fskip"); - GFX_SetTitle(-1,render.frameskip.max); + GFX_SetTitle(-1,render.frameskip.max,false); } diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 9171947d..87acd4f2 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.68 2004-07-05 11:54:53 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.69 2004-07-12 12:42:20 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -166,16 +166,42 @@ static SDL_Block sdl; static void CaptureMouse(void); extern char * RunningProgram; -void GFX_SetTitle(Bits cycles,Bits frameskip){ +void GFX_SetTitle(Bits cycles,Bits frameskip,bool paused){ char title[200]={0}; static Bits internal_cycles=0; static Bits internal_frameskip=0; if(cycles != -1) internal_cycles = cycles; if(frameskip != -1) internal_frameskip = frameskip; - sprintf(title,"DOSBox %s,Cpu Cycles: %8d, Frameskip %2d, Program: %s",VERSION,internal_cycles,internal_frameskip,RunningProgram); + if(paused) + sprintf(title,"DOSBox %s,Cpu Cycles: %8d, Frameskip %2d, Program: %8s PAUSED",VERSION,internal_cycles,internal_frameskip,RunningProgram); + else + sprintf(title,"DOSBox %s,Cpu Cycles: %8d, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram); SDL_WM_SetCaption(title,VERSION); } +static void PauseDOSBox(void) { + GFX_SetTitle(-1,-1,true); + bool paused = true; + SDL_Delay(500); + SDL_Event event; + while (SDL_PollEvent(&event)) { + // flush event queue. + } + while (paused) { + SDL_WaitEvent(&event); // since we're not polling, cpu usage drops to 0. + switch (event.type) { + case SDL_KEYDOWN: // Must use Pause/Break Key to resume. + case SDL_KEYUP: + if(event.key.keysym.sym==SDLK_PAUSE){ + paused=false; + GFX_SetTitle(-1,-1,false); + break; + } + } + } +} + + /* Reset the screen with current values in the sdl structure */ Bitu GFX_GetBestMode(Bitu flags) { Bitu testbpp,gotbpp,setflags; @@ -679,6 +705,11 @@ static void GUI_StartUp(Section * sec) { MAPPER_AddHandler(KillSwitch,MK_f9,MMOD1,"shutdown","ShutDown"); MAPPER_AddHandler(CaptureMouse,MK_f10,MMOD1,"capmouse","Cap Mouse"); MAPPER_AddHandler(SwitchFullScreen,MK_return,MMOD2,"fullscr","Fullscreen"); +#if C_DEBUG + /* Pause binds with activate-debugger */ +#else + MAPPER_AddHandler(PauseDOSBox,MK_pause,0,"pause","Pause"); +#endif } void Mouse_AutoLock(bool enable) { From 519aeb3d973a971e1a28a5f0654a27fa650c7552 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 13 Jul 2004 16:56:06 +0000 Subject: [PATCH 1805/4131] New larry 6 hack. Renders Wayne's world hack obselete (Thank you c2woody!) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1887 --- src/ints/mouse.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 120d5983..17430a02 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.40 2004-07-11 20:02:08 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.41 2004-07-13 16:56:06 qbix79 Exp $ */ #include #include @@ -484,19 +484,12 @@ static void SetMickeyPixelRate(Bit16s px, Bit16s py){ } }; static void SetSensitivity(Bit16s px, Bit16s py){ - if ((px!=0) && (py!=0)) { - px--; //Inspired by cutemouse - py--; //Although their cursor update routine is far more complex then ours - mouse.senv_x=(static_cast(px)*px)/3600.0 +1.0/3.0; - mouse.senv_y=(static_cast(py)*py)/3600.0 +1.0/3.0; - } - }; @@ -550,7 +543,7 @@ void Mouse_NewVideoMode(void) mouse.min_x = 0; mouse.min_y = 0; // Dont set max coordinates here. it is done by SetResolution! - mouse.x = 0; // civ wont work otherwise + mouse.x = static_cast(mouse.max_x / 2); mouse.y = static_cast(mouse.max_y / 2); mouse.events = 0; mouse.mickey_x = 0; @@ -664,7 +657,6 @@ static Bitu INT33_Handler(void) { Bits max,min; if ((Bit16s)reg_cx<(Bit16s)reg_dx) { min=(Bit16s)reg_cx;max=(Bit16s)reg_dx;} else { min=(Bit16s)reg_dx;max=(Bit16s)reg_cx;} - if(min == max) break; //Wayne's World mouse.min_x=min; mouse.max_x=max; LOG(LOG_MOUSE,LOG_NORMAL)("Define Hortizontal range min:%d max:%d",min,max); @@ -677,7 +669,6 @@ static Bitu INT33_Handler(void) { Bits max,min; if ((Bit16s)reg_cx<(Bit16s)reg_dx) { min=(Bit16s)reg_cx;max=(Bit16s)reg_dx;} else { min=(Bit16s)reg_dx;max=(Bit16s)reg_cx;} - if(min == max) break; //Wayne's World mouse.min_y=min; mouse.max_y=max; LOG(LOG_MOUSE,LOG_NORMAL)("Define Vertical range min:%d max:%d",min,max); From ff403934504e7f726b651eaee12f05feafc1214a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 14 Jul 2004 20:25:35 +0000 Subject: [PATCH 1806/4131] Minor change in the DIB. Makes windoes installer happy :) (it now installs without a warning) (c2woody) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1888 --- src/dos/dos_classes.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index d81a55a8..ecadfd28 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.39 2004-07-08 20:08:52 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.40 2004-07-14 20:25:35 qbix79 Exp $ */ #include #include @@ -72,7 +72,7 @@ void DOS_InfoBlock::SetLocation(Bit16u segment) sSave(sDIB,protFCBs,(Bit16u)0); sSave(sDIB,specialCodeSeg,(Bit16u)0); sSave(sDIB,joindedDrives,(Bit8u)0); - sSave(sDIB,lastdrive,(Bit8u)0x18); + sSave(sDIB,lastdrive,(Bit8u)0x01);//increase this if you add drives to cds-chain sSave(sDIB,setverPtr,(Bit32u)0); From c75cb24491f08d674b4c8b02f624a75e3cd1d041 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 18 Jul 2004 15:35:11 +0000 Subject: [PATCH 1807/4131] made aclocal/automake 1.8 a bit more happy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1889 --- acinclude.m4 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 9ea0d7a2..5e72516a 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1,7 +1,7 @@ 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, +AC_DEFUN([AM_PATH_SDL], [dnl dnl Get the cflags and libraries from the sdl-config script dnl @@ -174,7 +174,7 @@ 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, +AC_DEFUN([AM_PATH_ALSA], [dnl Save the original CFLAGS, LDFLAGS, and LIBS alsa_save_CFLAGS="$CFLAGS" alsa_save_LDFLAGS="$LDFLAGS" @@ -376,4 +376,4 @@ typedef double Real64; typedef Bit64s Bits; #endif -]) \ No newline at end of file +]) From 0725a9353b4d41b65988da07c6b12a88925da8ac Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 18 Jul 2004 16:56:07 +0000 Subject: [PATCH 1808/4131] removed config.guess Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1890 --- config.guess | 1368 -------------------------------------------------- 1 file changed, 1368 deletions(-) delete mode 100644 config.guess diff --git a/config.guess b/config.guess deleted file mode 100644 index 71de137a..00000000 --- a/config.guess +++ /dev/null @@ -1,1368 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -# Free Software Foundation, Inc. - -timestamp='2001-03-16' - -# This file 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. -# -# 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. - -# Written by Per Bothner . -# Please send patches to . -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 99, 2000 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; - --version | -v ) - echo "$version" ; exit 0 ;; - --help | --h* | -h ) - echo "$usage"; exit 0 ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - - -dummy=dummy-$$ -trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int dummy(){}" > $dummy.c - for c in cc gcc c89 ; do - ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 - if test $? = 0 ; then - CC_FOR_BUILD="$c"; break - fi - done - rm -f $dummy.c $dummy.o $dummy.rel - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 8/24/94.) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # Netbsd (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # Determine the machine/vendor (is the vendor relevant). - case "${UNAME_MACHINE}" in - amiga) machine=m68k-unknown ;; - arm32) machine=arm-unknown ;; - atari*) machine=m68k-atari ;; - sun3*) machine=m68k-sun ;; - mac68k) machine=m68k-apple ;; - macppc) machine=powerpc-apple ;; - hp3[0-9][05]) machine=m68k-hp ;; - ibmrt|romp-ibm) machine=romp-ibm ;; - *) machine=${UNAME_MACHINE}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE}" in - i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k) - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit 0 ;; - alpha:OSF1:*:*) - if test $UNAME_RELEASE = "V4.0"; then - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - fi - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - cat <$dummy.s - .data -\$Lformat: - .byte 37,100,45,37,120,10,0 # "%d-%x\n" - - .text - .globl main - .align 4 - .ent main -main: - .frame \$30,16,\$26,0 - ldgp \$29,0(\$27) - .prologue 1 - .long 0x47e03d80 # implver \$0 - lda \$2,-1 - .long 0x47e20c21 # amask \$2,\$1 - lda \$16,\$Lformat - mov \$0,\$17 - not \$1,\$18 - jsr \$26,printf - ldgp \$29,0(\$26) - mov 0,\$16 - jsr \$26,exit - .end main -EOF - $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null - if test "$?" = 0 ; then - case `./$dummy` in - 0-0) - UNAME_MACHINE="alpha" - ;; - 1-0) - UNAME_MACHINE="alphaev5" - ;; - 1-1) - UNAME_MACHINE="alphaev56" - ;; - 1-101) - UNAME_MACHINE="alphapca56" - ;; - 2-303) - UNAME_MACHINE="alphaev6" - ;; - 2-307) - UNAME_MACHINE="alphaev67" - ;; - esac - fi - rm -f $dummy.s $dummy - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit 0 ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit 0 ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit 0 ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit 0;; - amiga:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit 0 ;; - arc64:OpenBSD:*:*) - echo mips64el-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - arc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - hkmips:OpenBSD:*:*) - echo mips-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - pmax:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sgi:OpenBSD:*:*) - echo mips-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - wgrisc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit 0 ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit 0;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit 0;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit 0 ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit 0 ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit 0 ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit 0 ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit 0 ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit 0 ;; - atari*:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit 0 ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit 0 ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit 0 ;; - sun3*:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mac68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme88k:OpenBSD:*:*) - echo m88k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit 0 ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit 0 ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit 0 ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit 0 ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit 0 ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD $dummy.c -o $dummy \ - && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ - && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo mips-mips-riscos${UNAME_RELEASE} - exit 0 ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit 0 ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit 0 ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit 0 ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit 0 ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit 0 ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit 0 ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit 0 ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit 0 ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit 0 ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit 0 ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i?86:AIX:*:*) - echo i386-ibm-aix - exit 0 ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit 0 ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo rs6000-ibm-aix3.2.5 - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit 0 ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit 0 ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit 0 ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit 0 ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit 0 ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit 0 ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit 0 ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit 0 ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit 0 ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - case "${HPUX_REV}" in - 11.[0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - esac ;; - esac - fi ;; - esac - if [ "${HP_ARCH}" = "" ]; then - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` - if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi - rm -f $dummy.c $dummy - fi ;; - esac - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit 0 ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit 0 ;; - 3050*:HI-UX:*:*) - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo unknown-hitachi-hiuxwe2 - exit 0 ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit 0 ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit 0 ;; - *9??*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit 0 ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit 0 ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit 0 ;; - i?86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit 0 ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit 0 ;; - hppa*:OpenBSD:*:*) - echo hppa-unknown-openbsd - exit 0 ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit 0 ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit 0 ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit 0 ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit 0 ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit 0 ;; - CRAY*X-MP:*:*:*) - echo xmp-cray-unicos - exit 0 ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} - exit 0 ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ - exit 0 ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3D:*:*:*) - echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY-2:*:*:*) - echo cray2-cray-unicos - exit 0 ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit 0 ;; - hp300:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit 0 ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit 0 ;; - *:OpenBSD:*:*) - echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - exit 0 ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit 0 ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit 0 ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit 0 ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i386-pc-interix - exit 0 ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit 0 ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit 0 ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - *:GNU:*:*) - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit 0 ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit 0 ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux - exit 0 ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - mips:Linux:*:*) - cat >$dummy.c < /* for printf() prototype */ -int main (int argc, char *argv[]) { -#else -int main (argc, argv) int argc; char *argv[]; { -#endif -#ifdef __MIPSEB__ - printf ("%s-unknown-linux-gnu\n", argv[1]); -#endif -#ifdef __MIPSEL__ - printf ("%sel-unknown-linux-gnu\n", argv[1]); -#endif - return 0; -} -EOF - $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - ;; - ppc:Linux:*:*) - # Determine Lib Version - cat >$dummy.c < -#if defined(__GLIBC__) -extern char __libc_version[]; -extern char __libc_release[]; -#endif -main(argc, argv) - int argc; - char *argv[]; -{ -#if defined(__GLIBC__) - printf("%s %s\n", __libc_version, __libc_release); -#else - printf("unknown\n"); -#endif - return 0; -} -EOF - LIBC="" - $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null - if test "$?" = 0 ; then - ./$dummy | grep 1\.99 > /dev/null - if test "$?" = 0 ; then LIBC="libc1" ; fi - fi - rm -f $dummy.c $dummy - echo powerpc-unknown-linux-gnu${LIBC} - exit 0 ;; - alpha:Linux:*:*) - cat <$dummy.s - .data - \$Lformat: - .byte 37,100,45,37,120,10,0 # "%d-%x\n" - .text - .globl main - .align 4 - .ent main - main: - .frame \$30,16,\$26,0 - ldgp \$29,0(\$27) - .prologue 1 - .long 0x47e03d80 # implver \$0 - lda \$2,-1 - .long 0x47e20c21 # amask \$2,\$1 - lda \$16,\$Lformat - mov \$0,\$17 - not \$1,\$18 - jsr \$26,printf - ldgp \$29,0(\$26) - mov 0,\$16 - jsr \$26,exit - .end main -EOF - LIBC="" - $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null - if test "$?" = 0 ; then - case `./$dummy` in - 0-0) UNAME_MACHINE="alpha" ;; - 1-0) UNAME_MACHINE="alphaev5" ;; - 1-1) UNAME_MACHINE="alphaev56" ;; - 1-101) UNAME_MACHINE="alphapca56" ;; - 2-303) UNAME_MACHINE="alphaev6" ;; - 2-307) UNAME_MACHINE="alphaev67" ;; - esac - objdump --private-headers $dummy | \ - grep ld.so.1 > /dev/null - if test "$?" = 0 ; then - LIBC="libc1" - fi - fi - rm -f $dummy.s $dummy - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit 0 ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit 0 ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit 0 ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit 0 ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit 0 ;; - i?86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - ld_supported_emulations=`cd /; ld --help 2>&1 \ - | sed -ne '/supported emulations:/!d - s/[ ][ ]*/ /g - s/.*supported emulations: *// - s/ .*// - p'` - case "$ld_supported_emulations" in - i?86linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit 0 - ;; - elf_i?86) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - i?86coff) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit 0 - ;; - esac - # Either a pre-BFD a.out linker (linux-gnuoldld) - # or one that does not give us useful --help. - # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. - # If ld does not provide *any* "supported emulations:" - # that means it is gnuoldld. - test -z "$ld_supported_emulations" && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 - case "${UNAME_MACHINE}" in - i?86) - VENDOR=pc; - ;; - *) - VENDOR=unknown; - ;; - esac - # Determine whether the default compiler is a.out or elf - cat >$dummy.c < -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif -#ifdef __ELF__ -# ifdef __GLIBC__ -# if __GLIBC__ >= 2 - printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); -# else - printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); -# endif -# else - printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); -# endif -#else - printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); -#endif - return 0; -} -EOF - $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 - ;; -# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions -# are messed up and put the nodename in both sysname and nodename. - i?86:DYNIX/ptx:4*:*) - echo i386-sequent-sysv4 - exit 0 ;; - i?86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit 0 ;; - i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit 0 ;; - i?86:*:5:7*) - # Fixed at (any) Pentium or better - UNAME_MACHINE=i586 - if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then - echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} - fi - exit 0 ;; - i?86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` - (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit 0 ;; - i?86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit 0 ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit 0 ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit 0 ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit 0 ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit 0 ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit 0 ;; - M68*:*:R3V[567]*:*) - test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4.3${OS_REL} && exit 0 - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4 && exit 0 ;; - m68*:LynxOS:2.*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit 0 ;; - i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit 0 ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit 0 ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit 0 ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit 0 ;; - PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit 0 ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit 0 ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit 0 ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit 0 ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit 0 ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit 0 ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit 0 ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit 0 ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit 0 ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit 0 ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit 0 ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; - *:Darwin:*:*) - echo `uname -p`-apple-darwin${UNAME_RELEASE} - exit 0 ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - if test "${UNAME_MACHINE}" = "x86pc"; then - UNAME_MACHINE=pc - fi - echo `uname -p`-${UNAME_MACHINE}-nto-qnx - exit 0 ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit 0 ;; - NSR-[KW]:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit 0 ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit 0 ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit 0 ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit 0 ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit 0 ;; - i?86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit 0 ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit 0 ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit 0 ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit 0 ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit 0 ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit 0 ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit 0 ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 -rm -f $dummy.c $dummy - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit 0 ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit 0 ;; - c34*) - echo c34-convex-bsd - exit 0 ;; - c38*) - echo c38-convex-bsd - exit 0 ;; - c4*) - echo c4-convex-bsd - exit 0 ;; - esac -fi - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: From 65fb00fd3dc0cfbbfa280dd99ffd6dd58ef0eb57 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 18 Jul 2004 17:18:40 +0000 Subject: [PATCH 1809/4131] Add new files to vs.net project file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1891 --- visualc_net/dosbox.vcproj | 46 +++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index c0b6522f..66a4c046 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -393,6 +393,9 @@ + + @@ -405,6 +408,12 @@ + + + + @@ -429,12 +438,6 @@ - - - - @@ -462,9 +465,15 @@ + + + + + + + + + + + + - - - - - - - - Date: Thu, 22 Jul 2004 08:26:49 +0000 Subject: [PATCH 1810/4131] change return value of ax of findnext. Fixes Willy Beamish showing up only the first savegame Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1892 --- src/dos/dos.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index eab79ba4..4e5a028b 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.72 2004-06-10 08:48:53 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.73 2004-07-22 08:26:49 qbix79 Exp $ */ #include #include @@ -661,7 +661,8 @@ static Bitu DOS_21Handler(void) { case 0x4f: /* FINDNEXT Find next matching file */ if (DOS_FindNext()) { CALLBACK_SCF(false); - reg_ax=0xffff; /* Undocumented */ + /* reg_ax=0xffff;*/ /* Undocumented */ + reg_ax=0; /* Undocumented:Qbix Willy beamish */ } else { reg_ax=dos.errorcode; CALLBACK_SCF(true); From e40d2a6f354cbae5a5ce5eb19dd111df78bcd360 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 24 Jul 2004 18:50:10 +0000 Subject: [PATCH 1811/4131] Add ddraw.h available define Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1893 --- src/platform/visualc/config.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 1751d54f..55025203 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -40,6 +40,9 @@ /* environ can be linked */ #define ENVIRON_LINKED 1 +/* Define to 1 if you have the header file. */ +#define HAVE_DDRAW_H 1 + #define GCC_ATTRIBUTE(x) /* attribute not supported */ typedef double Real64; From 7f29fe4b5a4fda1b8255f63dda20a1c38da7146a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 24 Jul 2004 18:52:03 +0000 Subject: [PATCH 1812/4131] Check for ddraw header availability Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1894 --- configure.in | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.in b/configure.in index 0cc5ca58..3f04af1e 100644 --- a/configure.in +++ b/configure.in @@ -181,6 +181,7 @@ dnl Some host detection and actions for them case "$target" in *-*-cygwin* | *-*-mingw32*) LIBS="$LIBS -lwinmm" + AC_CHECK_HEADERS(ddraw.h) ;; *-*-darwin*) dnl We have a problem here: both MacOS X and Darwin report From b45019218ec244135132ac072969f85eaa3f0f60 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 24 Jul 2004 20:41:09 +0000 Subject: [PATCH 1813/4131] Add special win32 output handler using directdraw scaled blits Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1895 --- src/gui/sdlmain.cpp | 187 +++++++++++++++++++++++++++++--------------- 1 file changed, 124 insertions(+), 63 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 87acd4f2..a3312b00 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.69 2004-07-12 12:42:20 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.70 2004-07-24 20:41:09 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -88,12 +88,19 @@ PFNGLPIXELDATARANGENVPROC glPixelDataRangeNV = NULL; extern char** environ; #endif - #ifdef WIN32 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include +#if defined(HAVE_DDRAW_H) +#include +struct private_hwdata { + LPDIRECTDRAWSURFACE3 dd_surface; + LPDIRECTDRAWSURFACE3 dd_writebuf; +}; +#endif + #define STDOUT_FILE TEXT("stdout.txt") #define STDERR_FILE TEXT("stderr.txt") #define DEFAULT_CONFIG_FILE "/dosbox.conf" @@ -108,6 +115,7 @@ void MAPPER_StartUp(Section * sec); enum SCREEN_TYPES { SCREEN_SURFACE, + SCREEN_SURFACE_DDRAW, SCREEN_OVERLAY, SCREEN_OPENGL }; @@ -148,6 +156,12 @@ struct SDL_Block { bool pixel_data_range; #endif } opengl; +#endif +#if defined(HAVE_DDRAW_H) && defined(WIN32) + struct { + SDL_Surface * surface; + RECT rect; + } blit; #endif SDL_Rect clip; SDL_Surface * surface; @@ -204,7 +218,7 @@ static void PauseDOSBox(void) { /* Reset the screen with current values in the sdl structure */ Bitu GFX_GetBestMode(Bitu flags) { - Bitu testbpp,gotbpp,setflags; + Bitu testbpp,gotbpp; switch (sdl.desktop.want_type) { case SCREEN_SURFACE: check_surface: @@ -212,6 +226,7 @@ check_surface: if (flags & LOVE_8) testbpp=8; else if (flags & LOVE_16) testbpp=16; else if (flags & LOVE_32) testbpp=32; +check_gotbpp: if (sdl.desktop.fullscreen) gotbpp=SDL_VideoModeOK(640,480,testbpp,SDL_FULLSCREEN|SDL_HWSURFACE|SDL_HWPALETTE); else gotbpp=sdl.desktop.bpp; /* If we can't get our favorite mode check for another working one */ @@ -230,6 +245,14 @@ check_surface: } /* Not a valid display depth found? Let's just hope sdl provides conversions */ break; +#if defined(HAVE_DDRAW_H) && defined(WIN32) + case SCREEN_SURFACE_DDRAW: + if (!(flags&CAN_32|CAN_16)) goto check_surface; + if (flags & LOVE_16) testbpp=16; + else if (flags & LOVE_32) testbpp=32; + flags|=HAVE_SCALING; + goto check_gotbpp; +#endif case SCREEN_OVERLAY: if (flags & NEED_RGB || !(flags&CAN_32)) goto check_surface; flags|=HAVE_SCALING; @@ -260,6 +283,36 @@ static int int_log2 (int val) { return log; } + +static SDL_Surface * GFX_SetupSurfaceScaled(Bit32u sdl_flags,Bit32u bpp) { + if (sdl.desktop.fullscreen) { + if (sdl.desktop.fixed) { + double ratio_w=(double)sdl.desktop.width/(sdl.draw.width*sdl.draw.scalex); + double ratio_h=(double)sdl.desktop.height/(sdl.draw.height*sdl.draw.scaley); + if ( ratio_w < ratio_h) { + sdl.clip.w=(Bit16u)sdl.desktop.width; + sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley*ratio_w); + } else { + sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex*ratio_h); + sdl.clip.h=(Bit16u)sdl.desktop.height; + } + sdl.clip.x=(Sint16)((sdl.desktop.width-sdl.clip.w)/2); + sdl.clip.y=(Sint16)((sdl.desktop.height-sdl.clip.h)/2); + return sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,bpp,sdl_flags|SDL_FULLSCREEN|SDL_HWSURFACE); + } else { + sdl.clip.x=0;sdl.clip.y=0; + sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex); + sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley); + return sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags|SDL_FULLSCREEN|SDL_HWSURFACE); + } + } else { + sdl.clip.x=0;sdl.clip.y=0; + sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex*sdl.desktop.hwscale); + sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley*sdl.desktop.hwscale); + return sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags|SDL_HWSURFACE); + } +} + GFX_Modes GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_ResetCallBack reset) { if (sdl.updating) GFX_EndUpdate(); sdl.draw.width=width; @@ -304,38 +357,46 @@ dosurface: break; } break; - case SCREEN_OVERLAY: - if (sdl.overlay) SDL_FreeYUVOverlay(sdl.overlay); - sdl.overlay=0; - if (!(flags&CAN_32) || (flags & NEED_RGB)) goto dosurface; - if (sdl.desktop.fullscreen) { - if (sdl.desktop.fixed) { - double ratio_w=(double)sdl.desktop.width/(width*scalex); - double ratio_h=(double)sdl.desktop.height/(height*scaley); - if ( ratio_w < ratio_h) { - sdl.clip.w=(Bit16u)sdl.desktop.width; - sdl.clip.h=(Bit16u)(height*scaley*ratio_w); - } else { - sdl.clip.w=(Bit16u)(width*scalex*ratio_h); - sdl.clip.h=(Bit16u)sdl.desktop.height; - } - sdl.clip.x=(Sint16)((sdl.desktop.width-sdl.clip.w)/2); - sdl.clip.y=(Sint16)((sdl.desktop.height-sdl.clip.h)/2); - sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,0, - SDL_FULLSCREEN|SDL_HWSURFACE); - } else { - sdl.clip.x=0;sdl.clip.y=0; - sdl.clip.w=(Bit16u)(width*scalex); - sdl.clip.h=(Bit16u)(height*scaley); - sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,0, - SDL_FULLSCREEN|SDL_HWSURFACE); - } - } else { - sdl.clip.x=0;sdl.clip.y=0; - sdl.clip.w=(Bit16u)(width*scalex*sdl.desktop.hwscale); - sdl.clip.h=(Bit16u)(height*scaley*sdl.desktop.hwscale); - sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,0,SDL_HWSURFACE); +#if defined(HAVE_DDRAW_H) && defined(WIN32) + case SCREEN_SURFACE_DDRAW: + if (flags & CAN_16) bpp=16; + if (flags & CAN_32) bpp=32; + if (sdl.blit.surface) { + SDL_FreeSurface(sdl.blit.surface); + sdl.blit.surface=0; } + if (!GFX_SetupSurfaceScaled(0,bpp)) goto dosurface; + sdl.blit.rect.top=sdl.clip.x; + sdl.blit.rect.left=sdl.clip.y; + sdl.blit.rect.right=sdl.clip.x+sdl.clip.w-1; + sdl.blit.rect.bottom=sdl.clip.y+sdl.clip.h-1; + sdl.blit.surface=SDL_CreateRGBSurface(SDL_HWSURFACE,sdl.draw.width,sdl.draw.height, + sdl.surface->format->BitsPerPixel, + sdl.surface->format->Rmask, + sdl.surface->format->Gmask, + sdl.surface->format->Bmask, + 0); + if (!sdl.blit.surface || (!sdl.blit.surface->flags&SDL_HWSURFACE)) { + LOG_MSG("Failed to create ddraw surface, back to normal surface."); + goto dosurface; + } + switch (sdl.surface->format->BitsPerPixel) { + case 15:sdl.draw.mode=GFX_15;break; + case 16:sdl.draw.mode=GFX_16;break; + case 32:sdl.draw.mode=GFX_32;break; + default: + break; + } + sdl.desktop.type=SCREEN_SURFACE_DDRAW; + break; +#endif + case SCREEN_OVERLAY: + if (sdl.overlay) { + SDL_FreeYUVOverlay(sdl.overlay); + sdl.overlay=0; + } + if (!(flags&CAN_32) || (flags & NEED_RGB)) goto dosurface; + if (!GFX_SetupSurfaceScaled(0,0)) goto dosurface; sdl.overlay=SDL_CreateYUVOverlay(width*2,height,SDL_UYVY_OVERLAY,sdl.surface); if (!sdl.overlay) { LOG_MSG("SDL:Failed to create overlay, switching back to surface"); @@ -362,35 +423,7 @@ dosurface: goto dosurface; } SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); - if (sdl.desktop.fullscreen) { - if (sdl.desktop.fixed) { - double ratio_w=(double)sdl.desktop.width/(width*scalex); - double ratio_h=(double)sdl.desktop.height/(height*scaley); - if ( ratio_w < ratio_h) { - sdl.clip.w=(Bit16u)sdl.desktop.width; - sdl.clip.h=(Bit16u)(height*scaley*ratio_w); - } else { - sdl.clip.w=(Bit16u)(width*scalex*ratio_h); - sdl.clip.h=(Bit16u)sdl.desktop.height; - } - sdl.clip.x=(Sint16)((sdl.desktop.width-sdl.clip.w)/2); - sdl.clip.y=(Sint16)((sdl.desktop.height-sdl.clip.h)/2); - sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,0, - SDL_OPENGL|SDL_FULLSCREEN|SDL_HWSURFACE); - } else { - sdl.clip.x=0;sdl.clip.y=0; - sdl.clip.w=(Bit16u)(width*scalex); - sdl.clip.h=(Bit16u)(height*scaley); - sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,0, - SDL_OPENGL|SDL_FULLSCREEN|SDL_HWSURFACE); - } - } else { - sdl.clip.x=0;sdl.clip.y=0; - sdl.clip.w=(Bit16u)(width*scalex*sdl.desktop.hwscale); - sdl.clip.h=(Bit16u)(height*scaley*sdl.desktop.hwscale); - sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,0, - SDL_OPENGL|SDL_HWSURFACE); - } + GFX_SetupSurfaceScaled(SDL_OPENGL,0); if (!sdl.surface || sdl.surface->format->BitsPerPixel<15) { LOG_MSG("SDL:OPENGL:Can't open drawing surface, are you running in 16bpp(or higher) mode?"); goto dosurface; @@ -514,6 +547,17 @@ bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) { pixels+=sdl.clip.x*sdl.surface->format->BytesPerPixel; pitch=sdl.surface->pitch; return true; +#if defined(HAVE_DDRAW_H) && defined(WIN32) + case SCREEN_SURFACE_DDRAW: + if (SDL_LockSurface(sdl.blit.surface)) { + LOG_MSG("SDL Lock failed"); + sdl.updating=false; + return false; + } + pixels=(Bit8u *)sdl.blit.surface->pixels; + pitch=sdl.blit.surface->pitch; + return true; +#endif case SCREEN_OVERLAY: SDL_LockYUVOverlay(sdl.overlay); pixels=(Bit8u *)*(sdl.overlay->pixels); @@ -539,6 +583,18 @@ void GFX_EndUpdate(void) { } SDL_Flip(sdl.surface); break; +#if defined(HAVE_DDRAW_H) && defined(WIN32) + case SCREEN_SURFACE_DDRAW: + if (SDL_MUSTLOCK(sdl.blit.surface)) { + SDL_UnlockSurface(sdl.blit.surface); + } + IDirectDrawSurface3_Blt( + sdl.surface->hwdata->dd_surface,&sdl.blit.rect, + sdl.blit.surface->hwdata->dd_surface,0, + DDBLT_WAIT, NULL); + SDL_Flip(sdl.surface); + break; +#endif case SCREEN_OVERLAY: SDL_UnlockYUVOverlay(sdl.overlay); SDL_DisplayYUVOverlay(sdl.overlay,&sdl.clip); @@ -574,6 +630,7 @@ void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries) { Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue) { switch (sdl.desktop.type) { case SCREEN_SURFACE: + case SCREEN_SURFACE_DDRAW: return SDL_MapRGB(sdl.surface->format,red,green,blue); case SCREEN_OVERLAY: { @@ -652,6 +709,10 @@ static void GUI_StartUp(Section * sec) { const char * output=section->Get_string("output"); if (!strcasecmp(output,"surface")) { sdl.desktop.want_type=SCREEN_SURFACE; +#if defined(HAVE_DDRAW_H) && defined(WIN32) + } else if (!strcasecmp(output,"ddraw")) { + sdl.desktop.want_type=SCREEN_SURFACE_DDRAW; +#endif } else if (!strcasecmp(output,"overlay")) { sdl.desktop.want_type=SCREEN_OVERLAY; #if C_OPENGL From 9deb278528741210a9c3a44668ad5ec08cef38fb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 25 Jul 2004 11:47:57 +0000 Subject: [PATCH 1814/4131] Disable the saving of raw realtime reset midi commands. Only open the raw file on first data. Add WIN32_LEAN_AND_MEAN for fhr win32 midi handler Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1896 --- src/gui/midi.cpp | 28 ++++++++++++++++++++-------- src/gui/midi_win32.h | 3 +++ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index c4ce0ea2..baddb839 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -51,7 +51,7 @@ Bit8u MIDI_evt_len[256] = { 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xe0 - 0,2,3,2, 0,0,1,0, 1,0,1,1, 1,0,1,1 // 0xf0 + 0,2,3,2, 0,0,1,0, 1,0,1,1, 1,0,1,0 // 0xf0 }; class MidiHandler; @@ -110,6 +110,7 @@ static struct { struct { FILE * handle; Bit8u buffer[RAWBUF+SYSEX_SIZE]; + bool capturing; Bitu used,done; Bit32u last; } raw; @@ -134,7 +135,15 @@ static INLINE void RawAddNumber(Bit32u val) { ADDBUF(val & 0x7f); } static INLINE void RawAddDelta(void) { - if (!midi.raw.last) midi.raw.last=PIC_Ticks; + if (!midi.raw.handle) { + midi.raw.handle=OpenCaptureFile("Raw Midi",".mid"); + if (!midi.raw.handle) { + midi.raw.capturing=false; + return; + } + fwrite(midi_header,1,sizeof(midi_header),midi.raw.handle); + midi.raw.last=PIC_Ticks; + } Bit32u delta=PIC_Ticks-midi.raw.last; midi.raw.last=PIC_Ticks; RawAddNumber(delta); @@ -151,8 +160,10 @@ static INLINE void RawAddData(Bit8u * data,Bitu len) { static void MIDI_SaveRawEvent(void) { /* Check for previously opened wave file */ - if (midi.raw.handle) { + if (midi.raw.capturing) { LOG_MSG("Stopping raw midi saving."); + midi.raw.capturing=false; + if (!midi.raw.handle) return; ADDBUF(0x00);//Delta time ADDBUF(0xff);ADDBUF(0x2F);ADDBUF(0x00); //End of track event fwrite(midi.raw.buffer,1,midi.raw.used,midi.raw.handle); @@ -167,11 +178,11 @@ static void MIDI_SaveRawEvent(void) { fclose(midi.raw.handle); midi.raw.handle=0; } else { - midi.raw.handle=OpenCaptureFile("Raw Midi",".mid"); - if (!midi.raw.handle) return; - fwrite(midi_header,1,sizeof(midi_header),midi.raw.handle); + LOG_MSG("Preparing for raw midi capture, will start with first data."); midi.raw.used=0; midi.raw.done=0; + midi.raw.handle=0; + midi.raw.capturing=true; } } @@ -186,7 +197,7 @@ void MIDI_RawOutByte(Bit8u data) { midi.sysex.buf[midi.sysex.used++]=0xf7; midi.handler->PlaySysex(midi.sysex.buf,midi.sysex.used); LOG(LOG_ALL,LOG_NORMAL)("Sysex message size %d",midi.sysex.used); - if (midi.raw.handle) { + if (midi.raw.capturing) { RawAddDelta(); ADDBUF(0xf0); RawAddNumber(midi.sysex.used-1); @@ -206,7 +217,7 @@ void MIDI_RawOutByte(Bit8u data) { if (midi.cmd_len) { midi.cmd_buf[midi.cmd_pos++]=data; if (midi.cmd_pos >= midi.cmd_len) { - if (midi.raw.handle) { + if (midi.raw.capturing) { RawAddDelta(); RawAddData(midi.cmd_buf,midi.cmd_len); } @@ -235,6 +246,7 @@ void MIDI_Init(Section * sec) { midi.status=0x00; midi.cmd_pos=0; midi.cmd_len=0; + midi.raw.capturing=false; if (!strcasecmp(dev,"default")) goto getdefault; handler=handler_list; while (handler) { diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index e9a8651f..4e0b49b9 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -16,6 +16,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif #include #include From 83d6b619cad4bb704b79c00f5137d47f80d25bd9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 30 Jul 2004 01:41:10 +0000 Subject: [PATCH 1815/4131] Doing Stuff some people don't seem to care about. Added Directserial to makefile (else it will not be in the source archive and thus not in the builds) Enabled it on win32 hosts. Made it only compilable for win32 target hosts. dosbox.cpp: Added help for the configfile for directserial! (Users don't read the source.) ifdef some more stuff enable MPU-intelligent-mode by default. disable Directserial by default. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1897 --- configure.in | 1 + src/dosbox.cpp | 36 ++++++++++++++++++++++------- src/hardware/Makefile.am | 3 ++- src/hardware/directserial_win32.cpp | 10 +++++++- src/platform/visualc/config.h | 4 +++- 5 files changed, 43 insertions(+), 11 deletions(-) diff --git a/configure.in b/configure.in index 3f04af1e..10a097bc 100644 --- a/configure.in +++ b/configure.in @@ -182,6 +182,7 @@ 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 only).]) ;; *-*-darwin*) dnl We have a problem here: both MacOS X and Darwin report diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 49f9c819..cfa235cb 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.71 2004-07-04 20:59:38 harekiet Exp $ */ +/* $Id: dosbox.cpp,v 1.72 2004-07-30 01:41:10 qbix79 Exp $ */ #include #include @@ -58,9 +58,11 @@ void DOS_Init(Section*); void CPU_Init(Section*); + #if C_FPU void FPU_Init(Section*); #endif + void DMA_Init(Section*); void MIXER_Init(Section*); void MIDI_Init(Section*); @@ -77,9 +79,18 @@ void PCSPEAKER_Init(Section*); void TANDYSOUND_Init(Section*); void DISNEY_Init(Section*); void SERIAL_Init(Section*); + +#if C_MODEM void MODEM_Init(Section*); +#endif + +#if C_IPX void IPX_Init(Section*); +#endif + +#if C_DIRECTSERIAL void DIRECTSERIAL_Init(Section* sec); +#endif void PIC_Init(Section*); void TIMER_Init(Section*); @@ -188,7 +199,7 @@ void DOSBOX_Init(void) { /* Setup all the different modules making up DOSBox */ secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit); - secprop->Add_string("language",""); + secprop->Add_string("language",""); secprop->Add_string("machine","vga"); secprop->Add_string("captures","capture"); @@ -267,7 +278,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("midi",&MIDI_Init); secprop->AddInitFunction(&MPU401_Init); secprop->Add_bool("mpu401",true); - secprop->Add_bool("intelligent",false); + secprop->Add_bool("intelligent",true); secprop->Add_string("device","default"); secprop->Add_string("config",""); @@ -284,7 +295,7 @@ void DOSBOX_Init(void) { #endif secprop=control->AddSection_prop("sblaster",&SBLASTER_Init); secprop->Add_string("type","sb16"); - secprop->Add_hex("base",0x220); + secprop->Add_hex("base",0x220); secprop->Add_int("irq",7); secprop->Add_int("dma",1); secprop->Add_int("hdma",5); @@ -306,7 +317,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("gus",&GUS_Init); secprop->Add_bool("gus",true); secprop->Add_int("rate",22050); - secprop->Add_hex("base",0x240); + secprop->Add_hex("base",0x240); secprop->Add_int("irq1",5); secprop->Add_int("irq2",5); secprop->Add_int("dma1",3); @@ -333,7 +344,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&DISNEY_Init); secprop->Add_bool("disney",true); - MSG_Add("SPEAKER_CONFIGFILE_HELP", + MSG_Add("SPEAKER_CONFIGFILE_HELP", "pcspeaker -- Enable PC-Speaker emulation.\n" "pcrate -- Sample rate of the PC-Speaker sound generation.\n" "tandy -- Enable Tandy 3-Voice emulation.\n" @@ -350,7 +361,7 @@ void DOSBOX_Init(void) { secprop->Add_bool("xms",true); secprop->AddInitFunction(&EMS_Init); secprop->Add_bool("ems",true); - MSG_Add("DOS_CONFIGFILE_HELP", + MSG_Add("DOS_CONFIGFILE_HELP", "xms -- Enable XMS support.\n" "ems -- Enable EMS support.\n" ); @@ -370,13 +381,22 @@ void DOSBOX_Init(void) { #endif #if C_DIRECTSERIAL secprop=control->AddSection_prop("directserial",&DIRECTSERIAL_Init); - secprop->Add_bool("directserial", true); + secprop->Add_bool("directserial", false); secprop->Add_hex("comport",1); secprop->Add_string("realport", "COM1"); secprop->Add_int("defaultbps", 1200); secprop->Add_string("parity", "N"); // Could be N, E, O secprop->Add_int("bytesize", 8); // Could be 5 to 8 secprop->Add_int("stopbit", 1); // Could be 1 or 2 + MSG_Add("DIRECTSERIAL_CONFIGFILE_HELP", + "directserial -- Enable serial passthrough support.\n" + "comport -- COM Port inside DOSBox.\n" + "realport -- COM Port on the Host.\n" + "defaultbps -- Default BPS.\n" + "parity -- Parity of the packets. This can be N, E or O.\n" + "bytesize -- Size of each packet. This can be 5 or 8.\n" + "stopbit -- The number of stopbits. This can be 1 or 2.\n" + ); #endif #if C_IPX secprop=control->AddSection_prop("ipx",&IPX_Init); diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index c4201d96..f51dc2a0 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -8,7 +8,8 @@ libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp vga_other.cpp \ vga_memory.cpp vga_misc.cpp vga_seq.cpp vga_xga.cpp cmos.cpp disney.cpp \ - gus.cpp mpu401.cpp serialport.cpp softmodem.cpp ipx.cpp ipxserver.cpp + gus.cpp mpu401.cpp serialport.cpp softmodem.cpp ipx.cpp ipxserver.cpp \ + directserial_win32.cpp diff --git a/src/hardware/directserial_win32.cpp b/src/hardware/directserial_win32.cpp index 83efd464..14bd0d99 100644 --- a/src/hardware/directserial_win32.cpp +++ b/src/hardware/directserial_win32.cpp @@ -16,10 +16,15 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: directserial_win32.cpp,v 1.2 2004-07-30 01:41:10 qbix79 Exp $ */ + #include "dosbox.h" #if C_DIRECTSERIAL +/* Windows version */ +#ifdef __WIN32__ + #include #include #include @@ -186,5 +191,8 @@ void DIRECTSERIAL_Init(Section* sec) { seriallist.push_back(cds); } +#else /*linux and others oneday maybe */ + +#endif +#endif -#endif \ No newline at end of file diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 55025203..d03023f9 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -2,7 +2,6 @@ #define VERSION "0.61" -#define C_DIRECTSERIAL 1 /* Define to 1 to enable internal debugger, requires libcurses */ #define C_DEBUG 1 @@ -43,6 +42,9 @@ /* Define to 1 if you have the header file. */ #define HAVE_DDRAW_H 1 +/* Define to 1 if you want serial passthrough support (Win32 only). */ +#define C_DIRECTSERIAL 1 + #define GCC_ATTRIBUTE(x) /* attribute not supported */ typedef double Real64; From e455b0442f67045394e8b82ca4fdd67c3b7eaf12 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 3 Aug 2004 19:37:04 +0000 Subject: [PATCH 1816/4131] Added option AD for dir Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1898 --- src/shell/shell_cmds.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 061f2466..c31fcb8f 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.43 2004-05-20 13:17:27 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.44 2004-08-03 19:37:04 qbix79 Exp $ */ #include @@ -239,6 +239,7 @@ void DOS_Shell::CMD_DIR(char * args) { bool optW=ScanCMDBool(args,"W"); bool optS=ScanCMDBool(args,"S"); bool optP=ScanCMDBool(args,"P"); + bool optAD=ScanCMDBool(args,"AD"); char * rem=ScanCMDRemain(args); if (rem) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); @@ -292,11 +293,14 @@ void DOS_Shell::CMD_DIR(char * args) { WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); return; } - while (ret) { -/* File name and extension */ + + do { /* File name and extension */ char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr; dta.GetResult(name,size,date,time,attr); + /* Skip non-directories if option AD is present */ + if(optAD && !(attr&DOS_ATTR_DIRECTORY) ) continue; + char * ext=""; if (!optW && (name[0] != '.')) { ext = strrchr(name, '.'); @@ -331,13 +335,12 @@ void DOS_Shell::CMD_DIR(char * args) { if (optW) { w_count++; } - ret=DOS_FindNext(); if(optP) { if(!(++p_count%(22*w_size))) { CMD_PAUSE(args); } } - } + } while ( (ret=DOS_FindNext()) ); if (optW) { if (w_count%5) WriteOut("\n"); } From ca409fd57cdfb62149f6801f0104af286cab91e9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 4 Aug 2004 09:12:57 +0000 Subject: [PATCH 1817/4131] Typo in preamble Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1899 --- include/bios.h | 2 +- include/callback.h | 2 +- include/cpu.h | 2 +- include/cross.h | 4 ++-- include/debug.h | 2 +- include/dma.h | 4 ++-- include/dos_inc.h | 4 ++-- include/dos_system.h | 4 ++-- include/dosbox.h | 2 +- include/fpu.h | 2 +- include/hardware.h | 2 +- include/inout.h | 2 +- include/ipx.h | 2 +- include/ipxserver.h | 2 +- include/joystick.h | 2 +- include/keyboard.h | 2 +- include/mapper.h | 2 +- include/mem.h | 2 +- include/mixer.h | 2 +- include/mouse.h | 4 ++-- include/paging.h | 2 +- include/pic.h | 2 +- include/programs.h | 2 +- include/regs.h | 2 +- include/render.h | 2 +- include/serialport.h | 2 +- include/setup.h | 4 ++-- include/shell.h | 4 ++-- include/support.h | 2 +- include/timer.h | 2 +- include/vga.h | 2 +- include/video.h | 2 +- src/cpu/callback.cpp | 4 ++-- src/cpu/core_dyn_x86.cpp | 2 +- src/cpu/core_dyn_x86/decoder.h | 2 +- src/cpu/core_dyn_x86/risc_x86.h | 2 +- src/cpu/core_dyn_x86/string.h | 2 +- src/cpu/core_full.cpp | 2 +- src/cpu/core_normal.cpp | 2 +- src/cpu/core_normal/helpers.h | 2 +- src/cpu/core_normal/prefix_0f.h | 2 +- src/cpu/core_normal/prefix_66.h | 2 +- src/cpu/core_normal/prefix_66_0f.h | 2 +- src/cpu/core_normal/prefix_none.h | 2 +- src/cpu/core_normal/support.h | 2 +- src/cpu/core_normal/table_ea.h | 2 +- src/cpu/cpu.cpp | 4 ++-- src/cpu/flags.cpp | 2 +- src/cpu/instructions.h | 2 +- src/cpu/lazyflags.h | 2 +- src/cpu/modrm.cpp | 2 +- src/cpu/modrm.h | 2 +- src/cpu/paging.cpp | 2 +- src/debug/debug.cpp | 4 ++-- src/debug/debug_gui.cpp | 2 +- src/debug/debug_inc.h | 2 +- src/debug/debug_win32.cpp | 2 +- src/debug/disasm_tables.h | 2 +- src/dos/cdrom.cpp | 2 +- src/dos/cdrom_aspi_win32.cpp | 4 ++-- src/dos/cdrom_ioctl_linux.cpp | 2 +- src/dos/cdrom_ioctl_win32.cpp | 4 ++-- src/dos/dev_con.h | 4 ++-- src/dos/dos.cpp | 4 ++-- src/dos/dos_classes.cpp | 4 ++-- src/dos/dos_devices.cpp | 2 +- src/dos/dos_execute.cpp | 4 ++-- src/dos/dos_files.cpp | 4 ++-- src/dos/dos_ioctl.cpp | 4 ++-- src/dos/dos_memory.cpp | 2 +- src/dos/dos_misc.cpp | 4 ++-- src/dos/dos_mscdex.cpp | 4 ++-- src/dos/dos_programs.cpp | 4 ++-- src/dos/dos_tables.cpp | 4 ++-- src/dos/drive_cache.cpp | 4 ++-- src/dos/drive_fat.cpp | 2 +- src/dos/drive_local.cpp | 4 ++-- src/dos/drive_virtual.cpp | 2 +- src/dos/drives.cpp | 2 +- src/dos/drives.h | 4 ++-- src/dosbox.cpp | 4 ++-- src/fpu/fpu.cpp | 4 ++-- src/fpu/fpu_instructions.h | 4 ++-- src/fpu/fpu_types.h | 2 +- src/gui/midi.cpp | 2 +- src/gui/midi_alsa.h | 4 ++-- src/gui/midi_coreaudio.h | 2 +- src/gui/midi_oss.h | 2 +- src/gui/midi_win32.h | 2 +- src/gui/render.cpp | 4 ++-- src/gui/sdl_mapper.cpp | 4 ++-- src/gui/sdlmain.cpp | 4 ++-- src/hardware/adlib.cpp | 2 +- src/hardware/cmos.cpp | 2 +- src/hardware/directserial_win32.cpp | 4 ++-- src/hardware/disney.cpp | 2 +- src/hardware/dma.cpp | 2 +- src/hardware/gameblaster.cpp | 2 +- src/hardware/gus.cpp | 2 +- src/hardware/hardware.cpp | 2 +- src/hardware/iohandler.cpp | 2 +- src/hardware/ipx.cpp | 2 +- src/hardware/ipxserver.cpp | 2 +- src/hardware/joystick.cpp | 2 +- src/hardware/keyboard.cpp | 4 ++-- src/hardware/memory.cpp | 2 +- src/hardware/mixer.cpp | 2 +- src/hardware/pcspeaker.cpp | 2 +- src/hardware/pic.cpp | 4 ++-- src/hardware/sblaster.cpp | 2 +- src/hardware/serialport.cpp | 2 +- src/hardware/softmodem.cpp | 2 +- src/hardware/tandy_sound.cpp | 2 +- src/hardware/timer.cpp | 4 ++-- src/hardware/vga.cpp | 2 +- src/hardware/vga_attr.cpp | 2 +- src/hardware/vga_crtc.cpp | 2 +- src/hardware/vga_dac.cpp | 2 +- src/hardware/vga_draw.cpp | 2 +- src/hardware/vga_gfx.cpp | 2 +- src/hardware/vga_memory.cpp | 2 +- src/hardware/vga_misc.cpp | 2 +- src/hardware/vga_other.cpp | 2 +- src/hardware/vga_seq.cpp | 2 +- src/hardware/vga_xga.cpp | 2 +- src/ints/bios.cpp | 4 ++-- src/ints/bios_disk.cpp | 2 +- src/ints/bios_keyboard.cpp | 2 +- src/ints/ems.cpp | 4 ++-- src/ints/int10.cpp | 2 +- src/ints/int10.h | 2 +- src/ints/int10_char.cpp | 4 ++-- src/ints/int10_memory.cpp | 2 +- src/ints/int10_misc.cpp | 2 +- src/ints/int10_pal.cpp | 2 +- src/ints/int10_put_pixel.cpp | 2 +- src/ints/int10_vesa.cpp | 4 ++-- src/ints/mouse.cpp | 4 ++-- src/ints/xms.cpp | 4 ++-- src/ints/xms.h | 2 +- src/misc/messages.cpp | 2 +- src/misc/programs.cpp | 4 ++-- src/misc/setup.cpp | 4 ++-- src/misc/support.cpp | 4 ++-- src/shell/shell.cpp | 4 ++-- src/shell/shell_batch.cpp | 4 ++-- src/shell/shell_cmds.cpp | 4 ++-- src/shell/shell_misc.cpp | 4 ++-- 148 files changed, 197 insertions(+), 197 deletions(-) diff --git a/include/bios.h b/include/bios.h index afd25bca..e80bc067 100644 --- a/include/bios.h +++ b/include/bios.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/callback.h b/include/callback.h index eb299fc2..ca919ab6 100644 --- a/include/callback.h +++ b/include/callback.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/cpu.h b/include/cpu.h index 7e3f613a..cc015857 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/cross.h b/include/cross.h index c2e830b5..d92930e2 100644 --- a/include/cross.h +++ b/include/cross.h @@ -9,14 +9,14 @@ * 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. + * 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: cross.h,v 1.7 2004-02-02 19:22:23 qbix79 Exp $ */ +/* $Id: cross.h,v 1.8 2004-08-04 09:12:50 qbix79 Exp $ */ #ifndef _CROSS_H #define _CROSS_H diff --git a/include/debug.h b/include/debug.h index bb44a99d..337e8497 100644 --- a/include/debug.h +++ b/include/debug.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/dma.h b/include/dma.h index 46bd5524..294bfd28 100644 --- a/include/dma.h +++ b/include/dma.h @@ -9,14 +9,14 @@ * 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. + * 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: dma.h,v 1.11 2004-06-10 20:20:28 harekiet Exp $ */ +/* $Id: dma.h,v 1.12 2004-08-04 09:12:50 qbix79 Exp $ */ #ifndef __DMA_H #define __DMA_H diff --git a/include/dos_inc.h b/include/dos_inc.h index d566e819..a634119d 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -9,14 +9,14 @@ * 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. + * 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: dos_inc.h,v 1.47 2004-07-08 20:08:52 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.48 2004-08-04 09:12:50 qbix79 Exp $ */ #ifndef DOS_H_ #define DOS_H_ diff --git a/include/dos_system.h b/include/dos_system.h index d3f0d772..1f273b8b 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -9,14 +9,14 @@ * 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. + * 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: dos_system.h,v 1.23 2004-04-18 14:49:48 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.24 2004-08-04 09:12:50 qbix79 Exp $ */ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ diff --git a/include/dosbox.h b/include/dosbox.h index afb93bb4..0bd156a3 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/fpu.h b/include/fpu.h index a00c091a..50f50e08 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/hardware.h b/include/hardware.h index 878affef..638e5979 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/inout.h b/include/inout.h index 717fdbe1..bb83949b 100644 --- a/include/inout.h +++ b/include/inout.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/ipx.h b/include/ipx.h index 624ea8bc..5a3e4c1e 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/ipxserver.h b/include/ipxserver.h index 9a4441b6..7b9f1cce 100644 --- a/include/ipxserver.h +++ b/include/ipxserver.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/joystick.h b/include/joystick.h index b0e13bc6..8476525f 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/keyboard.h b/include/keyboard.h index da8037dc..614f031a 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/mapper.h b/include/mapper.h index 27835661..1be123b2 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/mem.h b/include/mem.h index b039ad36..b1ccb82e 100644 --- a/include/mem.h +++ b/include/mem.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/mixer.h b/include/mixer.h index 4b839ac7..feeec3a6 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/mouse.h b/include/mouse.h index 4407b04c..8082f0e0 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -9,14 +9,14 @@ * 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. + * 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: mouse.h,v 1.6 2004-03-14 13:39:45 qbix79 Exp $ */ +/* $Id: mouse.h,v 1.7 2004-08-04 09:12:51 qbix79 Exp $ */ #ifndef _MOUSE_H_ #define _MOUSE_H_ diff --git a/include/paging.h b/include/paging.h index 4640d172..29f8ddde 100644 --- a/include/paging.h +++ b/include/paging.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/pic.h b/include/pic.h index aadab912..c2a8a525 100644 --- a/include/pic.h +++ b/include/pic.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/programs.h b/include/programs.h index a40090df..b5a7a3bb 100644 --- a/include/programs.h +++ b/include/programs.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/regs.h b/include/regs.h index 92eb004a..1c859b1e 100644 --- a/include/regs.h +++ b/include/regs.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/render.h b/include/render.h index 1c25a5c2..8a313866 100644 --- a/include/render.h +++ b/include/render.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/serialport.h b/include/serialport.h index 67035282..3aac5224 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/setup.h b/include/setup.h index c5aca20c..686fcdf9 100644 --- a/include/setup.h +++ b/include/setup.h @@ -9,14 +9,14 @@ * 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. + * 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: setup.h,v 1.15 2004-01-29 09:26:43 qbix79 Exp $ */ +/* $Id: setup.h,v 1.16 2004-08-04 09:12:51 qbix79 Exp $ */ #ifndef _SETUP_H_ #define _SETUP_H_ diff --git a/include/shell.h b/include/shell.h index 9e1f336d..c58156dd 100644 --- a/include/shell.h +++ b/include/shell.h @@ -9,14 +9,14 @@ * 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. + * 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.5 2004-05-11 18:58:18 harekiet Exp $ */ +/* $Id: shell.h,v 1.6 2004-08-04 09:12:51 qbix79 Exp $ */ #ifndef SHELL_H_ #define SHELL_H_ diff --git a/include/support.h b/include/support.h index f0973328..5127d15d 100644 --- a/include/support.h +++ b/include/support.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/timer.h b/include/timer.h index 22bcbfb0..a807884a 100644 --- a/include/timer.h +++ b/include/timer.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/vga.h b/include/vga.h index af45a822..893834db 100644 --- a/include/vga.h +++ b/include/vga.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/include/video.h b/include/video.h index c586b796..4c3b8075 100644 --- a/include/video.h +++ b/include/video.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index d12eb49e..55687744 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -9,14 +9,14 @@ * 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. + * 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: callback.cpp,v 1.20 2004-07-08 07:09:30 harekiet Exp $ */ +/* $Id: callback.cpp,v 1.21 2004-08-04 09:12:51 qbix79 Exp $ */ #include #include diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index a4e87ce1..1cda8ba5 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 7711e488..1e7570d5 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 1ed9bcd5..bc15b74b 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index 4182dbd5..10abb19a 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 59e9fc45..d1ee2820 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 3789f9c2..663c6d9f 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/core_normal/helpers.h b/src/cpu/core_normal/helpers.h index d7326488..556645a6 100644 --- a/src/cpu/core_normal/helpers.h +++ b/src/cpu/core_normal/helpers.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index f562d051..6bea18d3 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 28cd7ccd..fb698a81 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index d9be36f5..512117c5 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 287254ec..e8abf78f 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index 8f25ef4c..311a9eba 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/core_normal/table_ea.h b/src/cpu/core_normal/table_ea.h index c6e95fc0..d2772a65 100644 --- a/src/cpu/core_normal/table_ea.h +++ b/src/cpu/core_normal/table_ea.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 8a63b905..1b72c7f6 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -9,14 +9,14 @@ * 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. + * 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: cpu.cpp,v 1.59 2004-07-12 12:42:19 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.60 2004-08-04 09:12:51 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index bb67384f..1ac9000f 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 07f1a277..a53ae3e6 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index 897b481d..9cf2a735 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/modrm.cpp b/src/cpu/modrm.cpp index b9bad896..e726f79f 100644 --- a/src/cpu/modrm.cpp +++ b/src/cpu/modrm.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/modrm.h b/src/cpu/modrm.h index 181d529b..b51e0f2a 100644 --- a/src/cpu/modrm.h +++ b/src/cpu/modrm.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 4db18bda..2a9809c6 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 7528f506..fc15273b 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -9,14 +9,14 @@ * 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. + * 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: debug.cpp,v 1.56 2004-07-12 12:42:19 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.57 2004-08-04 09:12:53 qbix79 Exp $ */ #include "programs.h" diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index deb45371..ab3998f0 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h index 41524aba..378b2df0 100644 --- a/src/debug/debug_inc.h +++ b/src/debug/debug_inc.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/debug/debug_win32.cpp b/src/debug/debug_win32.cpp index 2da75fe4..d1302f91 100644 --- a/src/debug/debug_win32.cpp +++ b/src/debug/debug_win32.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/debug/disasm_tables.h b/src/debug/disasm_tables.h index 9a080f28..ac1798ad 100644 --- a/src/debug/disasm_tables.h +++ b/src/debug/disasm_tables.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 423b8bc2..77da894d 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index a38b75e5..d6a09fbe 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -9,14 +9,14 @@ * 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. + * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_aspi_win32.cpp,v 1.11 2004-05-19 11:44:48 finsterr Exp $ */ +/* $Id: cdrom_aspi_win32.cpp,v 1.12 2004-08-04 09:12:53 qbix79 Exp $ */ #if defined (WIN32) diff --git a/src/dos/cdrom_ioctl_linux.cpp b/src/dos/cdrom_ioctl_linux.cpp index f5050799..fe5eac34 100644 --- a/src/dos/cdrom_ioctl_linux.cpp +++ b/src/dos/cdrom_ioctl_linux.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index a923344f..09ea8fd4 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -9,14 +9,14 @@ * 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. + * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_ioctl_win32.cpp,v 1.10 2004-01-10 14:03:34 qbix79 Exp $ */ +/* $Id: cdrom_ioctl_win32.cpp,v 1.11 2004-08-04 09:12:53 qbix79 Exp $ */ #if defined (WIN32) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index f08ad63b..97835ac0 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -9,14 +9,14 @@ * 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. + * 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: dev_con.h,v 1.16 2004-01-10 14:03:34 qbix79 Exp $ */ +/* $Id: dev_con.h,v 1.17 2004-08-04 09:12:53 qbix79 Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 4e5a028b..9d618924 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -9,14 +9,14 @@ * 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. + * 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: dos.cpp,v 1.73 2004-07-22 08:26:49 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.74 2004-08-04 09:12:53 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index ecadfd28..8fd40fbb 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -9,14 +9,14 @@ * 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. + * 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: dos_classes.cpp,v 1.40 2004-07-14 20:25:35 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.41 2004-08-04 09:12:53 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 1ee2b47b..aad4cc79 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 0d0622e5..27fc72d1 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -9,14 +9,14 @@ * 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. + * 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: dos_execute.cpp,v 1.43 2004-07-12 12:42:20 qbix79 Exp $ */ +/* $Id: dos_execute.cpp,v 1.44 2004-08-04 09:12:53 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 9f4d74a0..6bff5047 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -9,14 +9,14 @@ * 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. + * 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: dos_files.cpp,v 1.56 2004-05-04 18:34:08 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.57 2004-08-04 09:12:53 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index c733044d..d50cc386 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -9,14 +9,14 @@ * 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. + * 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: dos_ioctl.cpp,v 1.19 2004-02-28 16:35:14 qbix79 Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.20 2004-08-04 09:12:53 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 993af873..d292db69 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index 428907bb..c0a3dd94 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -9,14 +9,14 @@ * 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. + * 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: dos_misc.cpp,v 1.11 2004-07-08 20:08:52 qbix79 Exp $ */ +/* $Id: dos_misc.cpp,v 1.12 2004-08-04 09:12:53 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index d33f0d8b..827cbbc9 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -9,14 +9,14 @@ * 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. + * 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: dos_mscdex.cpp,v 1.22 2004-06-30 14:40:07 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.23 2004-08-04 09:12:53 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 6c91e723..1b6a03e9 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -9,14 +9,14 @@ * 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. + * 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: dos_programs.cpp,v 1.25 2004-05-20 11:11:45 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.26 2004-08-04 09:12:53 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 5411d1b6..cd04163f 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -9,14 +9,14 @@ * 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. + * 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: dos_tables.cpp,v 1.13 2004-07-08 20:08:52 qbix79 Exp $ */ +/* $Id: dos_tables.cpp,v 1.14 2004-08-04 09:12:53 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 6b2a9d46..16d8e957 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -10,14 +10,14 @@ * 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. + * 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: drive_cache.cpp,v 1.35 2004-04-13 13:35:48 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.36 2004-08-04 09:12:53 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index e9cb8577..e3901572 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 7d50886d..29ebaf9a 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -9,14 +9,14 @@ * 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. + * 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: drive_local.cpp,v 1.48 2004-04-18 14:49:50 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.49 2004-08-04 09:12:53 qbix79 Exp $ */ #include #include diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index ccd2aa86..9a97833b 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index e5720ff3..d0c0cfb6 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/dos/drives.h b/src/dos/drives.h index ba6eb569..b10fa7c4 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -9,14 +9,14 @@ * 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. + * 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: drives.h,v 1.21 2004-04-18 14:49:50 qbix79 Exp $ */ +/* $Id: drives.h,v 1.22 2004-08-04 09:12:53 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ diff --git a/src/dosbox.cpp b/src/dosbox.cpp index cfa235cb..17bb93cd 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -9,14 +9,14 @@ * 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. + * 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: dosbox.cpp,v 1.72 2004-07-30 01:41:10 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.73 2004-08-04 09:12:51 qbix79 Exp $ */ #include #include diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 8898c2fd..a6b587e8 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -9,14 +9,14 @@ * 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. + * 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: fpu.cpp,v 1.20 2004-06-10 19:31:20 qbix79 Exp $ */ +/* $Id: fpu.cpp,v 1.21 2004-08-04 09:12:54 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index bc2a7e0c..c10ce6df 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -9,14 +9,14 @@ * 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. + * 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: fpu_instructions.h,v 1.17 2004-04-01 08:57:33 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.18 2004-08-04 09:12:54 qbix79 Exp $ */ static void FPU_FINIT(void) { diff --git a/src/fpu/fpu_types.h b/src/fpu/fpu_types.h index e2295713..16a4d746 100644 --- a/src/fpu/fpu_types.h +++ b/src/fpu/fpu_types.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index baddb839..80cb3cf6 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 7a10910a..785f7f29 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -9,14 +9,14 @@ * 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. + * 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: midi_alsa.h,v 1.8 2004-07-04 21:08:08 harekiet Exp $ */ +/* $Id: midi_alsa.h,v 1.9 2004-08-04 09:12:54 qbix79 Exp $ */ #define ALSA_PCM_OLD_HW_PARAMS_API #define ALSA_PCM_OLD_SW_PARAMS_API diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index 349c6da3..cb519d4f 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index e7c66bde..e0bfc0de 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index 4e0b49b9..514f498b 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 50bdc749..1ccfe926 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -9,14 +9,14 @@ * 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. + * 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: render.cpp,v 1.29 2004-07-12 12:42:20 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.30 2004-08-04 09:12:54 qbix79 Exp $ */ #include #include diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 95b3f44e..d124ee4e 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -9,14 +9,14 @@ * 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. + * 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: sdl_mapper.cpp,v 1.5 2004-06-30 14:40:08 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.6 2004-08-04 09:12:54 qbix79 Exp $ */ #include #include diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index a3312b00..3f3594a3 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -9,14 +9,14 @@ * 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. + * 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: sdlmain.cpp,v 1.70 2004-07-24 20:41:09 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.71 2004-08-04 09:12:54 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 7080707d..ef0e74ba 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 031155f3..cd878a98 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/directserial_win32.cpp b/src/hardware/directserial_win32.cpp index 14bd0d99..a3e778cc 100644 --- a/src/hardware/directserial_win32.cpp +++ b/src/hardware/directserial_win32.cpp @@ -9,14 +9,14 @@ * 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. + * 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: directserial_win32.cpp,v 1.2 2004-07-30 01:41:10 qbix79 Exp $ */ +/* $Id: directserial_win32.cpp,v 1.3 2004-08-04 09:12:55 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 7247ad72..70fb4453 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 8eb17442..7005f811 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index f9818097..567be28e 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index cdf1d614..2a325158 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index e0a39ac9..39c6bf80 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 229a0f47..904af71f 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index 6af46646..a60ac385 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/ipxserver.cpp b/src/hardware/ipxserver.cpp index b2471d00..5e9f956c 100644 --- a/src/hardware/ipxserver.cpp +++ b/src/hardware/ipxserver.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index cc10c07c..1013d25d 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index fca75a50..301876c3 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -9,14 +9,14 @@ * 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. + * 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: keyboard.cpp,v 1.26 2004-06-30 14:40:08 qbix79 Exp $ */ +/* $Id: keyboard.cpp,v 1.27 2004-08-04 09:12:55 qbix79 Exp $ */ #include #include diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 49e5da46..cc57d417 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 1031fc18..36ad2ecd 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 6c9b6ba7..51b626c9 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index cc2a99a9..54480114 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -9,14 +9,14 @@ * 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. + * 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: pic.cpp,v 1.22 2004-07-05 12:02:40 harekiet Exp $ */ +/* $Id: pic.cpp,v 1.23 2004-08-04 09:12:55 qbix79 Exp $ */ #include diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 30934d5d..f23b9eb2 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/serialport.cpp b/src/hardware/serialport.cpp index 56c6a400..6020b541 100644 --- a/src/hardware/serialport.cpp +++ b/src/hardware/serialport.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp index 489bf616..2fcbe055 100644 --- a/src/hardware/softmodem.cpp +++ b/src/hardware/softmodem.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 6fcb013f..bad2feca 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 0e450ebc..6a37be6f 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -9,14 +9,14 @@ * 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. + * 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: timer.cpp,v 1.25 2004-06-20 17:01:58 harekiet Exp $ */ +/* $Id: timer.cpp,v 1.26 2004-08-04 09:12:56 qbix79 Exp $ */ #include "dosbox.h" #include "inout.h" diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 706d89a2..010fe8a9 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index e6a4545e..d97fbc59 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 29dceccf..f7647817 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index 30f0ee14..cae4696b 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index d378224d..83eff326 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index cddd3ea9..5a1725e6 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index b93939cd..e3c8ced2 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 71e4968a..037a581d 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index f50cc949..1303d9ca 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index ab35b6c2..12db7b63 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index 6440b500..0abb4bae 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index e5817e2a..7069b6ea 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -9,14 +9,14 @@ * 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. + * 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: bios.cpp,v 1.34 2004-07-06 17:12:28 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.35 2004-08-04 09:12:56 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 6327227e..d22cb2aa 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 4b52b6e5..e5a466f1 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 509accb5..6ce72413 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -9,14 +9,14 @@ * 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. + * 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: ems.cpp,v 1.33 2004-05-07 23:20:00 qbix79 Exp $ */ +/* $Id: ems.cpp,v 1.34 2004-08-04 09:12:56 qbix79 Exp $ */ #include #include diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 6f9ab72d..de170ea3 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/ints/int10.h b/src/ints/int10.h index 28782832..a0bed3ac 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 48d2bef8..fa2b8971 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -9,14 +9,14 @@ * 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. + * 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: int10_char.cpp,v 1.28 2004-06-20 16:58:09 harekiet Exp $ */ +/* $Id: int10_char.cpp,v 1.29 2004-08-04 09:12:56 qbix79 Exp $ */ /* Character displaying moving functions */ diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index fc686fda..2a788068 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index b6a25ec9..99f0e25b 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index f39c7930..44cdf0a8 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index b44e3590..13c5bfee 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 56db545a..1acf9f76 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -9,14 +9,14 @@ * 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. + * 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: int10_vesa.cpp,v 1.10 2004-06-18 20:27:10 harekiet Exp $ */ +/* $Id: int10_vesa.cpp,v 1.11 2004-08-04 09:12:56 qbix79 Exp $ */ #include #include diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 17430a02..9341c260 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -9,14 +9,14 @@ * 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. + * 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: mouse.cpp,v 1.41 2004-07-13 16:56:06 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.42 2004-08-04 09:12:56 qbix79 Exp $ */ #include #include diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 5dec72c6..9bba09a0 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -9,14 +9,14 @@ * 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. + * 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: xms.cpp,v 1.32 2004-03-09 20:13:44 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.33 2004-08-04 09:12:56 qbix79 Exp $ */ #include #include diff --git a/src/ints/xms.h b/src/ints/xms.h index 56489dcb..3ee5d5c1 100644 --- a/src/ints/xms.h +++ b/src/ints/xms.h @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 9e61ef9a..8a75a357 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -9,7 +9,7 @@ * 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. + * 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 diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 7e9b96e5..42bd9382 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -9,14 +9,14 @@ * 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. + * 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: programs.cpp,v 1.13 2004-05-04 18:34:08 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.14 2004-08-04 09:12:56 qbix79 Exp $ */ #include #include diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index e2017e9e..23171e4e 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -9,14 +9,14 @@ * 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. + * 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: setup.cpp,v 1.21 2004-06-22 14:05:08 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.22 2004-08-04 09:12:56 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" diff --git a/src/misc/support.cpp b/src/misc/support.cpp index c6da6166..e544d882 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -9,14 +9,14 @@ * 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. + * 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: support.cpp,v 1.24 2004-07-05 12:00:22 harekiet Exp $ */ +/* $Id: support.cpp,v 1.25 2004-08-04 09:12:56 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index b51013d7..3038b8a2 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -9,14 +9,14 @@ * 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. + * 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.cpp,v 1.42 2004-05-20 13:17:27 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.43 2004-08-04 09:12:57 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index a506e676..724b5210 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -9,14 +9,14 @@ * 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. + * 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_batch.cpp,v 1.13 2004-05-04 18:34:08 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.14 2004-08-04 09:12:57 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index c31fcb8f..c50cf9e6 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -9,14 +9,14 @@ * 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. + * 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_cmds.cpp,v 1.44 2004-08-03 19:37:04 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.45 2004-08-04 09:12:57 qbix79 Exp $ */ #include diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 6e29221f..c4b13bf7 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -9,14 +9,14 @@ * 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. + * 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_misc.cpp,v 1.30 2004-05-20 13:17:27 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.31 2004-08-04 09:12:57 qbix79 Exp $ */ #include #include From 2b661d5648a136c394958f82daab3bf08261b26d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 4 Aug 2004 13:15:56 +0000 Subject: [PATCH 1818/4131] some newbie help Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1900 --- src/shell/shell.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 3038b8a2..428555dc 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.43 2004-08-04 09:12:57 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.44 2004-08-04 13:15:56 qbix79 Exp $ */ #include #include @@ -286,7 +286,7 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_DIR_INTRO","Directory of %s.\n"); MSG_Add("SHELL_CMD_DIR_BYTES_USED","%5d File(s) %17s Bytes\n"); MSG_Add("SHELL_CMD_DIR_BYTES_FREE","%5d Dir(s) %17s Bytes free\n"); - MSG_Add("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\n"); + MSG_Add("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\nYou must mount it first. Type intro for more information.\n"); MSG_Add("SHELL_EXECUTE_ILLEGAL_COMMAND","Illegal command: %s.\n"); MSG_Add("SHELL_CMD_PAUSE","Press any key to continue.\n"); MSG_Add("SHELL_CMD_PAUSE_HELP","Waits for 1 keystroke to continue.\n"); From b699da3acfbcd15185dced34c0621b322b034f43 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 4 Aug 2004 13:21:20 +0000 Subject: [PATCH 1819/4131] another define for win32 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1901 --- src/hardware/directserial_win32.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/directserial_win32.cpp b/src/hardware/directserial_win32.cpp index a3e778cc..56f029ad 100644 --- a/src/hardware/directserial_win32.cpp +++ b/src/hardware/directserial_win32.cpp @@ -16,14 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_win32.cpp,v 1.3 2004-08-04 09:12:55 qbix79 Exp $ */ +/* $Id: directserial_win32.cpp,v 1.4 2004-08-04 13:21:20 qbix79 Exp $ */ #include "dosbox.h" #if C_DIRECTSERIAL /* Windows version */ -#ifdef __WIN32__ +#if defined (WIN32) #include #include From f14aaadc09c1bbb5eabeb8657751a17a7bfda534 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 4 Aug 2004 14:21:58 +0000 Subject: [PATCH 1820/4131] extended insert gets in the bios buffer as well Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1902 --- src/ints/bios_keyboard.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index e5a466f1..e6342a66 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -284,7 +284,7 @@ static Bitu IRQ1_Handler(void) { case 0xc6:flags1 ^=0x10;flags2 &=~0x10;leds ^=0x01;break; // case 0x52:flags2|=128;break;//See numpad /* Insert */ case 0xd2: - if(flags3&0x02) { + if(flags3&0x02) { /* Maybe honour the insert on keypad as well */ flags1^=0x80; flags2&=~0x80; break; @@ -302,10 +302,7 @@ static Bitu IRQ1_Handler(void) { case 0x51: case 0x52: if(flags3 &0x02) { /*extend key. e.g key above arrows or arrows*/ - if(scancode == 0x52) { /* press insert */ - flags2 |=0x80; - break; - } + if(scancode == 0x52) flags2 |=0x80; /* press insert */ add_key((scancode <<8)|0xe0); break; } From 18f13c2b60b86e913a7949de5726bd17ecd79afc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 8 Aug 2004 12:39:54 +0000 Subject: [PATCH 1821/4131] Ignore requested drive_label when searching for it. Fixes pandaro. (Thank you prompt) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1903 --- src/dos/drive_local.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 29ebaf9a..dffa7cf9 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.49 2004-08-04 09:12:53 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.50 2004-08-08 12:39:54 qbix79 Exp $ */ #include #include @@ -160,12 +160,9 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) { dta.SetResult("NO_LABEL",0,0,0,DOS_ATTR_VOLUME); return true; } - - if (WildFileCmp(dirCache.GetLabel(),tempDir)) { - // Get Volume Label - dta.SetResult(dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME); - return true; - } + // Get Volume Label && ignore search string (pandora) + dta.SetResult(dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME); + return true; } return FindNext(dta); } From 02ff2737d7aa87f2fe1d2869b4d664beac96944c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 13 Aug 2004 19:43:02 +0000 Subject: [PATCH 1822/4131] Add Patch 1001897 by Martin. Disabled modem and ipx networking by default as they depend on libraries not everybody may have. Reduces alarmed firewall people and is nicer on unix hosts as port 23 is a bit tricky Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1904 --- configure.in | 10 + src/dos/Makefile.am | 4 +- src/dos/cdrom.cpp | 10 +- src/dos/cdrom.h | 107 +++++++ src/dos/cdrom_image.cpp | 653 ++++++++++++++++++++++++++++++++++++++++ src/dos/dos_mscdex.cpp | 10 +- src/dos/drive_fat.cpp | 53 +++- src/dos/drive_iso.cpp | 435 ++++++++++++++++++++++++++ src/dos/drive_local.cpp | 11 +- src/dos/drives.h | 110 ++++++- src/dosbox.cpp | 6 +- 11 files changed, 1390 insertions(+), 19 deletions(-) create mode 100644 src/dos/cdrom_image.cpp create mode 100644 src/dos/drive_iso.cpp diff --git a/configure.in b/configure.in index 10a097bc..fa8be44d 100644 --- a/configure.in +++ b/configure.in @@ -177,6 +177,16 @@ else AC_MSG_RESULT(no) fi +AH_TEMPLATE(C_SDL_SOUND,[Define to 1 to enable SDL_sound support]) +AC_CHECK_HEADER(SDL/SDL_sound.h,have_SDL_sound_h=yes,) +AC_CHECK_LIB(SDL_sound, Sound_Init, have_SDL_sound_lib=yes,,) +if test x$have_SDL_sound_h = xyes -a x$have_SDL_sound_lib = xyes ; then + LIBS="$LIBS -lSDL_sound" + AC_DEFINE(C_SDL_SOUND,1) +else + AC_MSG_WARN([Can't find libSDL_sound, libSDL_sound support disabled]) +fi + dnl Some host detection and actions for them case "$target" in *-*-cygwin* | *-*-mingw32*) diff --git a/src/dos/Makefile.am b/src/dos/Makefile.am index 3659aba3..4d206c7b 100644 --- a/src/dos/Makefile.am +++ b/src/dos/Makefile.am @@ -5,5 +5,5 @@ EXTRA_DIST = scsidefs.h wnaspi32.h libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioctl.cpp dos_memory.cpp \ dos_misc.cpp dos_classes.cpp dos_programs.cpp dos_tables.cpp \ drives.cpp drives.h drive_virtual.cpp drive_local.cpp drive_cache.cpp drive_fat.cpp \ - dev_con.h dos_mscdex.cpp \ - cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp cdrom_ioctl_linux.cpp + drive_iso.cpp dev_con.h dos_mscdex.cpp \ + cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp cdrom_ioctl_linux.cpp cdrom_image.cpp diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 77da894d..ecad2179 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -21,6 +21,7 @@ // SDL CDROM // ****************************************************** +#include #include "SDL.h" #include "support.h" #include "cdrom.h" @@ -175,8 +176,13 @@ int CDROM_GetMountType(char* path, int forceCD) cdName = SDL_CDName(i); if (strcmp(buffer,cdName)==0) return 0; }; - // TODO: Detect ISO - return 2; + + // Detect ISO + struct stat file_stat; + stat(path, &file_stat); + if (S_ISREG(file_stat.st_mode)) return 1; + + return 2; }; // ****************************************************** diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index fe710f0c..bd81474d 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -5,10 +5,17 @@ #define MAX_ASPI_CDROM 5 #include +#include +#include #include "dosbox.h" #include "mem.h" +#include "mixer.h" #include "SDL.h" +#include "SDL_thread.h" +#if defined(C_SDL_SOUND) +#include "SDL_sound.h" +#endif #define RAW_SECTOR_SIZE 2352 #define COOKED_SECTOR_SIZE 2048 @@ -95,6 +102,106 @@ public: bool LoadUnloadMedia (bool unload) { return true; }; }; +class CDROM_Interface_Image : public CDROM_Interface +{ +private: + class TrackFile { + public: + virtual bool read(Bit8u *buffer, int seek, int count) = 0; + virtual int getLength() = 0; + }; + + class BinaryFile : public TrackFile { + public: + BinaryFile(const char *filename, bool &error); + ~BinaryFile(); + bool read(Bit8u *buffer, int seek, int count); + int getLength(); + private: + BinaryFile(); + std::ifstream *file; + }; + + #if defined(C_SDL_SOUND) + class AudioFile : public TrackFile { + public: + AudioFile(const char *filename, bool &error); + ~AudioFile(); + bool read(Bit8u *buffer, int seek, int count); + int getLength(); + private: + AudioFile(); + Sound_Sample *sample; + int lastCount; + int lastSeek; + }; + #endif + + struct Track { + int number; + int attr; + int start; + int length; + int skip; + int sectorSize; + bool mode2; + TrackFile *file; + }; + +public: + CDROM_Interface_Image (Bit8u subUnit); + virtual ~CDROM_Interface_Image (void); + void InitNewMedia (void); + bool SetDevice (char* path, int forceCD); + bool GetUPC (unsigned char& attr, char* upc); + bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); + bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr); + bool GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); + bool GetAudioStatus (bool& playing, bool& pause); + bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); + bool PlayAudioSector (unsigned long start,unsigned long len); + bool PauseAudio (bool resume); + bool StopAudio (void); + bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); + bool LoadUnloadMedia (bool unload); + bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector); + +static CDROM_Interface_Image* images[26]; + +private: + // player +static void CDAudioCallBack(Bit8u *stream, Bit32u len); + int GetTrack(int sector); + +static struct imagePlayer { + CDROM_Interface_Image *cd; + MIXER_Channel *channel; + SDL_mutex *mutex; + Bit8u buffer[8192]; + int bufLen; + int currFrame; + int targetFrame; + bool isPlaying; + bool isPaused; + } player; + + void ClearTracks(); + bool LoadIsoFile(char *filename); + bool CanReadPVD(TrackFile *file, int sectorSize, bool mode2); + // cue sheet processing + bool LoadCueSheet(char *cuefile); + bool GetRealFileName(std::string& filename, std::string& pathname); + bool GetCueKeyword(std::string &keyword, std::istream &in); + bool GetCueFrame(int &frames, std::istream &in); + bool GetCueString(std::string &str, std::istream &in); + bool AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap); + +static int refCount; + std::vector tracks; + std::string mcn; + Bit8u subUnit; +}; + #if defined (WIN32) /* Win 32 */ #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp new file mode 100644 index 00000000..ce2a6f0a --- /dev/null +++ b/src/dos/cdrom_image.cpp @@ -0,0 +1,653 @@ +/* + * Copyright (C) 2002-2004 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* $Id: cdrom_image.cpp,v 1.1 2004-08-13 19:43:02 qbix79 Exp $ */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cdrom.h" +#include "drives.h" + +#if not defined(WIN32) +#include +#endif + +using namespace std; + +#define MAX_LINE_LENGTH 512 +#define MAX_FILENAME_LENGTH 256 + +CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) +{ + file = new ifstream(filename, ios::in | ios::binary); + error = (file == NULL) || (file->fail()); +} + +CDROM_Interface_Image::BinaryFile::~BinaryFile() +{ + delete file; +} + +bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count) +{ + file->seekg(seek, ios::beg); + file->read((char*)buffer, count); + return !(file->fail()); +} + +int CDROM_Interface_Image::BinaryFile::getLength() +{ + file->seekg(0, ios::end); + int length = file->tellg(); + if (file->fail()) return -1; + return length; +} + +#if defined(C_SDL_SOUND) +CDROM_Interface_Image::AudioFile::AudioFile(const char *filename, bool &error) +{ + Sound_AudioInfo desired = {AUDIO_S16, 2, 44100}; + sample = Sound_NewSampleFromFile(filename, &desired, RAW_SECTOR_SIZE); + lastCount = RAW_SECTOR_SIZE; + lastSeek = 0; + error = (sample == NULL); +} + +CDROM_Interface_Image::AudioFile::~AudioFile() +{ + Sound_FreeSample(sample); +} + +bool CDROM_Interface_Image::AudioFile::read(Bit8u *buffer, int seek, int count) +{ + if (lastCount != count) { + int success = Sound_SetBufferSize(sample, count); + if (!success) return false; + } + if (lastSeek != (seek - count)) { + int success = Sound_Seek(sample, (int)((double)(seek) / 176.4f)); + if (!success) return false; + } + lastSeek = seek; + int bytes = Sound_Decode(sample); + if (bytes < count) { + memcpy(buffer, sample->buffer, bytes); + memset(buffer + bytes, 0, count - bytes); + } else { + memcpy(buffer, sample->buffer, count); + } + + return !(sample->flags & SOUND_SAMPLEFLAG_ERROR); +} + +int CDROM_Interface_Image::AudioFile::getLength() +{ + int time = 1; + int shift = 0; + if (!(sample->flags & SOUND_SAMPLEFLAG_CANSEEK)) return -1; + + while (true) { + int success = Sound_Seek(sample, (unsigned int)(shift + time)); + if (!success) { + if (time == 1) return lround((double)shift * 176.4f); + shift += time >> 1; + time = 1; + } else { + if (time > ((numeric_limits::max() - shift) / 2)) return -1; + time = time << 1; + } + } +} +#endif + +// initialize static members +int CDROM_Interface_Image::refCount = 0; +CDROM_Interface_Image* CDROM_Interface_Image::images[26]; +CDROM_Interface_Image::imagePlayer CDROM_Interface_Image::player = { + NULL, NULL, NULL, 0, 0, 0, 0, 0, false, false }; + + +CDROM_Interface_Image::CDROM_Interface_Image(Bit8u subUnit) +{ + images[subUnit] = this; + if (refCount == 0) { +#if defined(C_SDL_SOUND) + Sound_Init(); +#endif + player.mutex = SDL_CreateMutex(); + if (!player.channel) { + player.channel = MIXER_AddChannel(&CDAudioCallBack, 44100, "CDAUDIO"); + MIXER_SetMode(player.channel, MIXER_16STEREO); + } + MIXER_Enable(player.channel, true); + } + refCount++; +} + +CDROM_Interface_Image::~CDROM_Interface_Image() +{ + refCount--; + if (player.cd == this) player.cd = NULL; + ClearTracks(); + if (refCount == 0) { +#if defined(C_SDL_SOUND) + Sound_Quit(); +#endif + SDL_DestroyMutex(player.mutex); + MIXER_Enable(player.channel, false); + } +} + +void CDROM_Interface_Image::InitNewMedia() +{ +} + +bool CDROM_Interface_Image::SetDevice(char* path, int forceCD) +{ + if (LoadCueSheet(path)) return true; + if (LoadIsoFile(path)) return true; + + // print error message on dosbox console + char buf[MAX_LINE_LENGTH]; + snprintf(buf, MAX_LINE_LENGTH, "Could not load image file: %s\n", path); + Bit16u size = strlen(buf); + DOS_WriteFile(STDOUT, (Bit8u*)buf, &size); + return false; +} + +bool CDROM_Interface_Image::GetUPC(unsigned char& attr, char* upc) +{ + attr = 0; + strcpy(upc, this->mcn.c_str()); + return true; +} + +bool CDROM_Interface_Image::GetAudioTracks(int& stTrack, int& end, TMSF& leadOut) +{ + stTrack = 1; + end = tracks.size() - 1; + FRAMES_TO_MSF(tracks[tracks.size() - 1].start + 150, &leadOut.min, &leadOut.sec, &leadOut.fr); + return true; +} + +bool CDROM_Interface_Image::GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr) +{ + if (track < 1 || track > tracks.size()) return false; + FRAMES_TO_MSF(tracks[track - 1].start + 150, &start.min, &start.sec, &start.fr); + attr = tracks[track - 1].attr; + return true; +} + +bool CDROM_Interface_Image::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) +{ + track = GetTrack(player.currFrame); + if (track < 1) return false; + attr = tracks[track - 1].attr; + index = 1; + FRAMES_TO_MSF(player.currFrame + 150, &absPos.min, &absPos.sec, &absPos.fr); + FRAMES_TO_MSF(player.currFrame - tracks[track - 1].start + 150, &relPos.min, &relPos.sec, &relPos.fr); + return true; +} + +bool CDROM_Interface_Image::GetAudioStatus(bool& playing, bool& pause) +{ + playing = player.isPlaying; + pause = player.isPaused; + return true; +} + +bool CDROM_Interface_Image::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) +{ + mediaPresent = true; + mediaChanged = false; + trayOpen = false; + return true; +} + +bool CDROM_Interface_Image::PlayAudioSector(unsigned long start,unsigned long len) +{ + SDL_mutexP(player.mutex); + player.cd = this; + player.currFrame = start; + player.targetFrame = start + len; + player.isPlaying = true; + player.isPaused = false; + SDL_mutexV(player.mutex); + return true; +} + +bool CDROM_Interface_Image::PauseAudio(bool resume) +{ + player.isPaused = !resume; + return true; +} + +bool CDROM_Interface_Image::StopAudio(void) +{ + player.isPlaying = false; + player.isPaused = false; + return true; +} + +bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) +{ + int sectorSize = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; + Bitu buflen = num * sectorSize; + Bit8u* buf = new Bit8u[buflen]; + + bool success; + for(int i = 0; i < num; i++) { + success = ReadSector(&buf[i * sectorSize], raw, sector); + if (!success) break; + } + + MEM_BlockWrite(buffer, buf, buflen); + delete[] buf; + + return success; +} + +bool CDROM_Interface_Image::LoadUnloadMedia(bool unload) +{ + return true; +} + +int CDROM_Interface_Image::GetTrack(int sector) +{ + vector::iterator i = tracks.begin(); + vector::iterator end = tracks.end() - 1; + + while(i != end) { + Track &curr = *i; + Track &next = *(i + 1); + if (curr.start <= sector && sector < next.start) return curr.number; + i++; + } + return -1; +} + +bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long sector) +{ + int track = GetTrack(sector) - 1; + if (track < 0) return false; + + int seek = tracks[track].skip + (sector - tracks[track].start) * tracks[track].sectorSize; + int length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE); + if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false; + if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16; + if (tracks[track].mode2 && !raw) seek += 24; + + return tracks[track].file->read(buffer, seek, length); +} + +void CDROM_Interface_Image::CDAudioCallBack(Bit8u *stream, Bit32u len) +{ + len *= 4; // 16 bit, stereo + if (!len) return; + if (!player.isPlaying || player.isPaused) { + memset(stream, 0, len); + return; + } + + SDL_mutexP(player.mutex); + while (player.bufLen < len) { + bool success; + if (player.targetFrame > player.currFrame) + success = player.cd->ReadSector(&player.buffer[player.bufLen], true, player.currFrame); + else success = false; + + if (success) { + player.currFrame++; + player.bufLen += RAW_SECTOR_SIZE; + } else { + memset(&player.buffer[player.bufLen], 0, len - player.bufLen); + player.bufLen = len; + player.isPlaying = false; + } + } + SDL_mutexV(player.mutex); + + memcpy(stream, player.buffer, len); + memmove(player.buffer, &player.buffer[len], player.bufLen - len); + player.bufLen -= len; +} + +bool CDROM_Interface_Image::LoadIsoFile(char* filename) +{ + tracks.clear(); + + // data track + Track track = {0, 0, 0, 0, 0, 0, false, NULL}; + bool error; + track.file = new BinaryFile(filename, error); + if (error) { + delete track.file; + return false; + } + track.number = 1; + track.attr = 4; + + // try to detect iso type + if (CanReadPVD(track.file, COOKED_SECTOR_SIZE, false)) { + track.sectorSize = COOKED_SECTOR_SIZE; + track.mode2 = false; + } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, false)) { + track.sectorSize = RAW_SECTOR_SIZE; + track.mode2 = false; + } else if (CanReadPVD(track.file, 2336, true)) { + track.sectorSize = 2336; + track.mode2 = true; + } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, true)) { + track.sectorSize = RAW_SECTOR_SIZE; + track.mode2 = true; + } else return false; + + track.length = track.file->getLength() / track.sectorSize; + tracks.push_back(track); + + // leadout track + track.number = 2; + track.attr = 0; + track.start = track.length; + track.length = 0; + track.file = NULL; + tracks.push_back(track); + + return true; +} + +bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mode2) +{ + Bit8u pvd[COOKED_SECTOR_SIZE]; + int seek = 16 * sectorSize; // first vd is located at sector 16 + if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16; + if (mode2) seek += 24; + file->read(pvd, seek, COOKED_SECTOR_SIZE); + // pvd[0] = descriptor type, pvd[1..5] = standard identifier, pvd[6] = iso version + return (pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1); +} + +bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) +{ + Track track = {0, 0, 0, 0, 0, 0, false, NULL}; + tracks.clear(); + int shift = 0; + int currPregap = 0; + int totalPregap = 0; + int prestart = 0; + bool success; + bool canAddTrack = false; + char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument + strncpy(tmp, cuefile, MAX_FILENAME_LENGTH); +#if defined(WIN32) + string pathname(""); +#else + string pathname(dirname(tmp)); +#endif + ifstream in; + in.open(cuefile, ios::in); + if (in.fail()) return false; + + while(!in.eof()) { + // get next line + char buf[MAX_LINE_LENGTH]; + in.getline(buf, MAX_LINE_LENGTH); + if (in.fail() && !in.eof()) return false; // probably a binary file + istringstream line(buf); + + string command; + GetCueKeyword(command, line); + + if (command == "TRACK") { + if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); + else success = true; + + track.start = 0; + track.skip = 0; + currPregap = 0; + prestart = 0; + + line >> track.number; + string type; + GetCueKeyword(type, line); + + if (type == "AUDIO") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = 0; + track.mode2 = false; + } else if (type == "MODE1/2048") { + track.sectorSize = COOKED_SECTOR_SIZE; + track.attr = 4; + track.mode2 = false; + } else if (type == "MODE1/2352") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = 4; + track.mode2 = false; + } else if (type == "MODE2/2336") { + track.sectorSize = 2336; + track.attr = 4; + track.mode2 = true; + } else if (type == "MODE2/2352") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = 4; + track.mode2 = true; + } else success = false; + + canAddTrack = true; + } + else if (command == "INDEX") { + int index; + line >> index; + int frame; + success = GetCueFrame(frame, line); + + if (index == 1) track.start = frame; + else if (index == 0) prestart = frame; + // ignore other indices + } + else if (command == "FILE") { + if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); + else success = true; + canAddTrack = false; + + string filename; + GetCueString(filename, line); + GetRealFileName(filename, pathname); + string type; + GetCueKeyword(type, line); + + track.file = NULL; + bool error = true; + if (type == "BINARY") { + track.file = new BinaryFile(filename.c_str(), error); + } +#if defined(C_SDL_SOUND) + else if (type == "WAVE" || type == "AIFF" || type == "MP3") { + track.file = new AudioFile(filename.c_str(), error); + } +#endif + if (error) { + delete track.file; + success = false; + } + } + else if (command == "PREGAP") success = GetCueFrame(currPregap, line); + else if (command == "CATALOG") success = GetCueString(mcn, line); + // ignored commands + else if (command == "CDTEXTFILE" || command == "FLAGS" || command == "ISRC" + || command == "PERFORMER" || command == "POSTGAP" || command == "REM" + || command == "SONGWRITER" || command == "TITLE" || command == "") success = true; + // failure + else success = false; + + if (!success) return false; + } + // add last track + if (!AddTrack(track, shift, prestart, totalPregap, currPregap)) return false; + + // add leadout track + track.number++; + track.start = 0; + track.length = 0; + track.file = NULL; + if(!AddTrack(track, shift, 0, totalPregap, 0)) return false; + + return true; +} + +bool CDROM_Interface_Image::AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap) +{ + // frames between index 0(prestart) and 1(curr.start) must be skipped + int skip; + if (prestart > 0) { + if (prestart > curr.start) return false; + skip = curr.start - prestart; + } else skip = 0; + + // first track (track number must be 1) + if (tracks.empty()) { + if (curr.number != 1) return false; + curr.skip = skip * curr.sectorSize; + curr.start += currPregap; + totalPregap = currPregap; + tracks.push_back(curr); + return true; + } + + Track &prev = *(tracks.end() - 1); + + // current track consumes data from the same file as the previous + if (prev.file == curr.file) { + curr.start += shift; + prev.length = curr.start + totalPregap - prev.start - skip; + curr.skip += prev.skip + prev.length * prev.sectorSize + skip * curr.sectorSize; + totalPregap += currPregap; + curr.start += totalPregap; + // current track uses a different file as the previous track + } else { + int tmp = prev.file->getLength() - prev.skip; + prev.length = tmp / prev.sectorSize; + if (tmp % prev.sectorSize != 0) prev.length++; // padding + + curr.start += prev.start + prev.length + currPregap; + curr.skip = skip * curr.sectorSize; + shift += prev.start + prev.length; + totalPregap = currPregap; + } + + // error checks + if (curr.number <= 1) return false; + if (prev.number + 1 != curr.number) return false; + if (curr.start < prev.start + prev.length) return false; + if (curr.length < 0) return false; + + tracks.push_back(curr); + return true; +} + +bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) +{ + // check if file exists + struct stat test; + if (stat(filename.c_str(), &test) == 0) return true; + + // check if file with path relative to cue file exists +#if not defined(WIN32) + string tmpstr(pathname + "/" + filename); + if (stat(tmpstr.c_str(), &test) == 0) { + filename = tmpstr; + return true; + } +#endif + // finally check if file is in a dosbox local drive + char fullname[CROSS_LEN]; + char tmp[CROSS_LEN]; + strncpy(tmp, filename.c_str(), CROSS_LEN); + Bit8u drive; + if (!DOS_MakeName(tmp, fullname, &drive)) return false; + + localDrive *ldp = (localDrive*)Drives[drive]; + ldp->GetSystemFilename(tmp, fullname); + if (stat(tmp, &test) == 0) { + filename = tmp; + return true; + } + + return false; +} + +bool CDROM_Interface_Image::GetCueKeyword(string &keyword, istream &in) +{ + in >> keyword; + for(int i = 0; i < keyword.size(); i++) keyword[i] = toupper(keyword[i]); + + return true; +} + +bool CDROM_Interface_Image::GetCueFrame(int &frames, istream &in) +{ + string msf; + in >> msf; + int min, sec, fr; + bool success = sscanf(msf.c_str(), "%d:%d:%d", &min, &sec, &fr) == 3; + frames = MSF_TO_FRAMES(min, sec, fr); + + return success; +} + +bool CDROM_Interface_Image::GetCueString(string &str, istream &in) +{ + int pos = in.tellg(); + in >> str; + if (str[0] == '\"') { + if (str[str.size() - 1] == '\"') { + str.assign(str, 1, str.size() - 2); + } else { + in.seekg(pos, ios::beg); + char buffer[MAX_FILENAME_LENGTH]; + in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); // skip + in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); + str = buffer; + } + } + return true; +} + +void CDROM_Interface_Image::ClearTracks() +{ + vector::iterator i = tracks.begin(); + vector::iterator end = tracks.end(); + + TrackFile* last = NULL; + while(i != end) { + Track &curr = *i; + if (curr.file != last) { + delete curr.file; + last = curr.file; + } + i++; + } + tracks.clear(); +} diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 827cbbc9..c57c8a26 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.23 2004-08-04 09:12:53 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.24 2004-08-13 19:43:02 qbix79 Exp $ */ #include #include @@ -275,11 +275,9 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) cdrom[numDrives] = new CDROM_Interface_SDL(); LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: SDL Interface."); } break; - case 0x01 : // iso cdrom interface - // FIXME: Not yet supported - LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Mounting iso file as cdrom: %s" ,physicalPath); - cdrom[numDrives] = new CDROM_Interface_Fake; - return 2; + case 0x01 : // iso cdrom interface + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting iso file as cdrom: %s", physicalPath); + cdrom[numDrives] = new CDROM_Interface_Image((Bit8u)numDrives); break; case 0x02 : // fake cdrom interface (directories) cdrom[numDrives] = new CDROM_Interface_Fake; diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index e3901572..4c169bff 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -1147,9 +1147,10 @@ public: if (type=="floppy") { mediaid=0xF0; - } else if (type=="cdrom") { + } else if (type=="cdrom" || type=="iso") { str_size="650,127,16513,1700"; mediaid=0xF8; + fstype = "iso"; } cmd->FindString("-size",str_size,true); if ((type=="hdd") && (str_size.size()==0)) { @@ -1170,7 +1171,7 @@ public: } number[index]=0;sizes[count++]=atoi(number); - if(fstype=="fat") { + if(fstype=="fat" || fstype=="iso") { // get the drive letter cmd->FindCommand(1,temp_line); if ((temp_line.size() > 2) || ((temp_line.size()>1) && (temp_line[1]!=':'))) { @@ -1208,8 +1209,25 @@ public: } struct stat test; if (stat(temp_line.c_str(),&test)) { - WriteOut("Image file not found\n"); - return; + // convert dosbox filename to system filename + char fullname[CROSS_LEN]; + char tmp[CROSS_LEN]; + strncpy(tmp, temp_line.c_str(), CROSS_LEN); + + Bit8u drive; + if (!DOS_MakeName(tmp, fullname, &drive)) { + WriteOut("Image file not found\n"); + return; + } + + localDrive *ldp = (localDrive*)Drives[drive]; + ldp->GetSystemFilename(tmp, fullname); + temp_line = tmp; + + if (stat(temp_line.c_str(),&test)) { + WriteOut("Image file not found\n"); + return; + } } if ((test.st_mode & S_IFDIR)) { @@ -1219,6 +1237,22 @@ public: if(fstype=="fat") { newdrive=new fatDrive(temp_line.c_str(),sizes[0],sizes[1],sizes[2],sizes[3],0); + } else if (fstype=="iso") { + int error; + newdrive = new isoDrive(drive, temp_line.c_str(), mediaid, error); + switch (error) { + case 0 : WriteOut(MSG_Get("MSCDEX_SUCCESS")); break; + case 1 : WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS")); break; + case 2 : WriteOut(MSG_Get("MSCDEX_ERROR_NOT_SUPPORTED")); break; + case 3 : WriteOut(MSG_Get("MSCDEX_ERROR_PATH")); break; + case 4 : WriteOut(MSG_Get("MSCDEX_TOO_MANY_DRIVES")); break; + case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break; + default : WriteOut(MSG_Get("MSCDEX_UNKNOWN_ERROR")); break; + }; + if (error) { + delete newdrive; + return; + } } else { FILE *newDisk = fopen(temp_line.c_str(), "rb+"); fseek(newDisk,0L, SEEK_END); @@ -1254,6 +1288,17 @@ public: if(!((fatDrive *)newdrive)->loadedDisk->hardDrive) { imageDiskList[0] = ((fatDrive *)newdrive)->loadedDisk; } + } else if (fstype=="iso") { + if (Drives[drive-'A']) { + WriteOut("Drive already mounted at that letter\n"); + if (newdrive) delete newdrive; + return; + } + if (!newdrive) WriteOut("Can't create drive from file\n"); + Drives[drive-'A']=newdrive; + // Set the correct media byte in the table + mem_writeb(Real2Phys(dos.tables.mediaid)+drive-'A',mediaid); + WriteOut("Drive %c mounted as %s\n",drive,temp_line.c_str()); } else if (fstype=="none") { if(imageDiskList[drive] != NULL) delete imageDiskList[drive]; imageDiskList[drive] = newImage; diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp new file mode 100644 index 00000000..d58ec954 --- /dev/null +++ b/src/dos/drive_iso.cpp @@ -0,0 +1,435 @@ +/* + * Copyright (C) 2002-2004 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* $Id: drive_iso.cpp,v 1.1 2004-08-13 19:43:02 qbix79 Exp $ */ + +#include +#include +#include "cdrom.h" +#include "dosbox.h" +#include "dos_system.h" +#include "drives.h" + +using namespace std; + +class isoFile : public DOS_File { +public: + isoFile(isoDrive *drive, const char *name, FileStat_Block *stat, Bit32u offset, Bit16u info); + bool Read(Bit8u *data, Bit16u *size); + bool Write(Bit8u *data, Bit16u *size); + bool Seek(Bit32u *pos, Bit32u type); + bool Close(); + Bit16u GetInformation(void); +private: + isoDrive *drive; + Bit8u buffer[ISO_FRAMESIZE]; + int cachedSector; + Bit32u fileBegin; + Bit32u filePos; + Bit32u fileEnd; + Bit16u info; +}; + +isoFile::isoFile(isoDrive *drive, const char *name, FileStat_Block *stat, Bit32u offset, Bit16u info) +{ + this->drive = drive; + time = stat->time; + date = stat->date; + attr = stat->attr; + size = stat->size; + fileBegin = offset; + filePos = fileBegin; + fileEnd = fileBegin + size; + cachedSector = -1; + open = true; + info = info; + this->name = NULL; + SetName(name); +} + +bool isoFile::Read(Bit8u *data, Bit16u *size) +{ + if (filePos + *size > fileEnd) + *size = fileEnd - filePos; + + Bit16u nowSize = 0; + int sector = filePos / ISO_FRAMESIZE; + Bit16u sectorPos = filePos % ISO_FRAMESIZE; + + if (sector != cachedSector) { + if (drive->readSector(buffer, sector)) cachedSector = sector; + else { *size = 0; cachedSector = -1; } + } + while (nowSize < *size) { + Bit16u remSector = ISO_FRAMESIZE - sectorPos; + Bit16u remSize = *size - nowSize; + if(remSector < remSize) { + memcpy(&data[nowSize], &buffer[sectorPos], remSector); + nowSize += remSector; + sectorPos = 0; + sector++; + cachedSector++; + if (!drive->readSector(buffer, sector)) { + *size = nowSize; + cachedSector = -1; + } + } else { + memcpy(&data[nowSize], &buffer[sectorPos], remSize); + nowSize += remSize; + } + + } + + *size = nowSize; + filePos += *size; + return true; +} + +bool isoFile::Write(Bit8u *data, Bit16u *size) +{ + return false; +} + +bool isoFile::Seek(Bit32u *pos, Bit32u type) +{ + switch (type) { + case DOS_SEEK_SET: + filePos = fileBegin + *pos; + break; + case DOS_SEEK_CUR: + filePos += *pos; + break; + case DOS_SEEK_END: + filePos = fileEnd + *pos; + break; + default: + return false; + } + if (filePos > fileEnd || filePos < fileBegin) + filePos = fileEnd; + + *pos = filePos - fileBegin; + return true; +} + +bool isoFile::Close() +{ + if (refCtr == 1) open = false; + return true; +} + +Bit16u isoFile::GetInformation(void) +{ + return info; +} + +int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit); +bool MSCDEX_HasMediaChanged(Bit8u subUnit); +bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name); + +isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &error) +{ + error = MSCDEX_AddDrive(driveLetter, fileName, subUnit); + + if (!error) { + if (loadImage()) { + strcpy(info, "isoDrive"); + searchCache.clear(); + dirIter = searchCache.end(); + this->mediaid = mediaid; + if (!MSCDEX_GetVolumeName(subUnit, discLabel)) strcpy(discLabel, ""); + } else error = 6; + } +} + +isoDrive::~isoDrive() { } + +bool isoDrive::FileOpen(DOS_File **file, char *name, Bit32u flags) +{ + if (flags == OPEN_WRITE) { + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; + } + + isoDirEntry de; + bool success = lookup(&de, name) && !IS_DIR(de.fileFlags); + + if (success) { + FileStat_Block file_stat; + file_stat.size = DATA_LENGTH(de); + file_stat.attr = DOS_ATTR_ARCHIVE | DOS_ATTR_READ_ONLY; + file_stat.date = DOS_PackDate(1900 + de.dateYear, de.dateMonth, de.dateDay); + file_stat.time = DOS_PackTime(de.timeHour, de.timeMin, de.timeSec); + *file = new isoFile(this, name, &file_stat, EXTENT_LOCATION(de) * ISO_FRAMESIZE, 0x202); + (*file)->flags = flags; + } + return success; +} + +bool isoDrive::FileCreate(DOS_File **file, char *name, Bit16u attributes) +{ + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; +} + +bool isoDrive::FileUnlink(char *name) +{ + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; +} + +bool isoDrive::RemoveDir(char *dir) +{ + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; +} + +bool isoDrive::MakeDir(char *dir) +{ + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; +} + +bool isoDrive::TestDir(char *dir) +{ + isoDirEntry de; + return (lookup(&de, dir) && IS_DIR(de.fileFlags)); +} + +bool isoDrive::FindFirst(char *dir, DOS_DTA &dta, bool fcb_findfirst) +{ + isoDirEntry de; + if (!lookup(&de, dir)) { + DOS_SetError(DOSERR_PATH_NOT_FOUND); + return false; + } + + Bit32u sectorStart = EXTENT_LOCATION(de); + Bit32u sectorEnd = sectorStart + DATA_LENGTH(de) / ISO_FRAMESIZE; + if (DATA_LENGTH(de) % ISO_FRAMESIZE != 0) sectorEnd++; + searchCache.clear(); + + for(Bit32u sector = sectorStart; sector < sectorEnd; sector++) { + Bit8u block[ISO_FRAMESIZE]; + readSector(block, sector); + + Bit32u pos = 0; + while (pos < ISO_FRAMESIZE && block[pos] != 0) { + isoDirEntry tmp; + int length = readDirEntry(&tmp, &block[pos]); + if (length < 0) return false; + searchCache.push_back(tmp); + pos += length; + } + } + dirIter = searchCache.begin(); + + Bit8u attr; + char pattern[ISO_MAXPATHNAME]; + dta.GetSearchParams(attr, pattern); + if ((attr & DOS_ATTR_VOLUME) && ((*dir == 0) || fcb_findfirst)) { + // Get Volume Label (DOS_ATTR_VOLUME) and only in basedir + dta.SetResult(discLabel, 0, 0, 0, DOS_ATTR_VOLUME); + return true; + } + return FindNext(dta); +} + +bool isoDrive::FindNext(DOS_DTA &dta) +{ + Bit8u attr; + char pattern[DOS_NAMELENGTH_ASCII]; + dta.GetSearchParams(attr, pattern); + + while (dirIter != searchCache.end()) { + isoDirEntry &de = *dirIter; + Bit8u findAttr; + if (IS_DIR(de.fileFlags)) findAttr = DOS_ATTR_DIRECTORY; + else findAttr = DOS_ATTR_ARCHIVE; + + if (WildFileCmp((char*)de.ident, pattern) + && !(~attr & findAttr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM))) { + + /* file is okay, setup everything to be copied in DTA Block */ + char findName[DOS_NAMELENGTH_ASCII]; + if(strlen((char*)de.ident) < DOS_NAMELENGTH_ASCII) { + strcpy(findName, (char*)de.ident); + upcase(findName); + } + Bit32u findSize = DATA_LENGTH(de); + Bit16u findDate = DOS_PackDate(1900 + de.dateYear, de.dateMonth, de.dateDay); + Bit16u findTime = DOS_PackTime(de.timeHour, de.timeMin, de.timeSec); + dta.SetResult(findName, findSize, findDate, findTime, findAttr); + + dirIter++; + return true; + } + dirIter++; + } + + DOS_SetError(DOSERR_NO_MORE_FILES); + return false; +} + +bool isoDrive::Rename(char *oldname, char *newname) +{ + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; +} + +bool isoDrive::GetFileAttr(char *name, Bit16u *attr) +{ + *attr = 0; + isoDirEntry de; + bool success = lookup(&de, name); + if (success) { + *attr = DOS_ATTR_ARCHIVE | DOS_ATTR_READ_ONLY; + if (IS_DIR(de.fileFlags)) *attr |= DOS_ATTR_DIRECTORY; + } + return success; +} + +bool isoDrive::AllocationInfo(Bit16u *bytes_sector, Bit8u *sectors_cluster, Bit16u *total_clusters, Bit16u *free_clusters) +{ + *bytes_sector = 2048; + *sectors_cluster = 1; // cluster size for cdroms ? + *total_clusters = 60000; + *free_clusters = 0; + return true; +} + +bool isoDrive::FileExists(const char *name) +{ + isoDirEntry de; + return (lookup(&de, name) && !IS_DIR(de.fileFlags)); +} + +bool isoDrive::FileStat(const char *name, FileStat_Block *const stat_block) +{ + isoDirEntry de; + bool success = lookup(&de, name); + + if (success) { + stat_block->date = DOS_PackDate(1900 + de.dateYear, de.dateMonth, de.dateDay); + stat_block->time = DOS_PackTime(de.timeHour, de.timeMin, de.timeSec); + stat_block->size = DATA_LENGTH(de); + stat_block->attr = DOS_ATTR_ARCHIVE | DOS_ATTR_READ_ONLY; + if (IS_DIR(de.fileFlags)) stat_block->attr |= DOS_ATTR_DIRECTORY; + } + + return success; +} + +Bit8u isoDrive::GetMediaByte(void) +{ + return mediaid; +} + +bool isoDrive::isRemote(void) +{ + return true; +} + +inline bool isoDrive :: readSector(Bit8u *buffer, Bit32u sector) +{ + return CDROM_Interface_Image::images[subUnit]->ReadSector(buffer, false, sector); +} + +int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) +{ + // copy data into isoDirEntry struct, data[0] = length of DirEntry + memcpy(de, data, data[0]); + + // xa not supported + if (de->extAttrLength != 0) return -1; + // interleaved mode not supported + if (de->fileUnitSize != 0 || de->interleaveGapSize != 0) return -1; + + // modify file identifier for use with dosbox + if (IS_DIR(de->fileFlags)) { + if (de->fileIdentLength == 1 && de->ident[0] == 0) strcpy((char*)de->ident, "."); + else if (de->fileIdentLength == 1 && de->ident[0] == 1) strcpy((char*)de->ident, ".."); + else { + if (de->fileIdentLength > 31) return -1; + de->ident[de->fileIdentLength] = 0; + } + } else { + if (de->fileIdentLength > 37) return -1; + de->ident[de->fileIdentLength] = 0; + // remove any file version identifiers as there are some cdroms that don't have them + strreplace((char*)de->ident, ';', 0); + // if file has no extension remove the trailing dot + int tmp = strlen((char*)de->ident); + if (tmp > 0 && de->ident[tmp - 1] == '.') de->ident[tmp - 1] = 0; + } + return de->length; +} + +bool isoDrive :: loadImage() +{ + isoPVD pvd; + readSector((Bit8u*)(&pvd), ISO_FIRST_VD); + if (pvd.type != 1 || strncmp((char*)pvd.standardIdent, "CD001", 5) || pvd.version != 1) return false; + return (readDirEntry(&this->rootEntry, pvd.rootEntry)); +} + +bool isoDrive :: lookupSingle(isoDirEntry *de, const char *name, Bit32u start, Bit32u length) +{ + Bit32u end = start + length / ISO_FRAMESIZE; + if (length % ISO_FRAMESIZE != 0) end++; + + for(Bit32u i = start; i < end; i++) { + Bit8u sector[ISO_FRAMESIZE]; + if (!readSector(sector, i)) return false; + + int pos = 0; + while (sector[pos] != 0 && pos < ISO_FRAMESIZE) { + int deLength = readDirEntry(de, §or[pos]); + if (deLength < 1) return false; + pos += deLength; + int tmp = strncasecmp((char*)de->ident, name, 38); + if (tmp == 0) return true; + } + } + return false; +} + +bool isoDrive :: lookup(isoDirEntry *de, const char *path) +{ + *de = this->rootEntry; + if (!strcmp(path, "")) return true; + + char isoPath[ISO_MAXPATHNAME]; + strncpy(isoPath, path, ISO_MAXPATHNAME); + strreplace(isoPath, '\\', '/'); + + int beginPos = 0; + int pos = 0; + while (isoPath[pos] != 0) { + if (isoPath[pos] == '/') { + char name[38]; + strncpy(name, &isoPath[beginPos], pos - beginPos); + name[pos - beginPos] = 0; + beginPos = pos + 1; + if (!IS_DIR(de->fileFlags)) return false; + if (!lookupSingle(de, name, EXTENT_LOCATION(*de), DATA_LENGTH(*de))) return false; + } + pos++; + } + return lookupSingle(de, &isoPath[beginPos], EXTENT_LOCATION(*de), DATA_LENGTH(*de)); +} diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index dffa7cf9..f4fa8b93 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.50 2004-08-08 12:39:54 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.51 2004-08-13 19:43:02 qbix79 Exp $ */ #include #include @@ -114,6 +114,15 @@ FILE * localDrive::GetSystemFilePtr(char * name, char * type) { return fopen(newname,type); } +bool localDrive::GetSystemFilename(char *sysName, char *dosName) { + + strcpy(sysName, basedir); + strcat(sysName, dosName); + CROSS_FILENAME(sysName); + dirCache.ExpandName(sysName); + return true; +} + bool localDrive::FileUnlink(char * name) { char newname[CROSS_LEN]; strcpy(newname,basedir); diff --git a/src/dos/drives.h b/src/dos/drives.h index b10fa7c4..ecde6b4e 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -16,11 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.22 2004-08-04 09:12:53 qbix79 Exp $ */ +/* $Id: drives.h,v 1.23 2004-08-13 19:43:02 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ +#include #include #include "dos_system.h" #include "shell.h" /* for DOS_Shell */ @@ -33,6 +34,7 @@ public: localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid); virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags); virtual FILE *GetSystemFilePtr(char * name, char * type); + virtual bool GetSystemFilename(char *sysName, char *dosName); virtual bool FileCreate(DOS_File * * file,char * name,Bit16u attributes); virtual bool FileUnlink(char * name); virtual bool RemoveDir(char * dir); @@ -202,6 +204,112 @@ private: Bit8u subUnit; }; +#ifdef _MSC_VER +#pragma pack (1) +#endif +struct isoPVD { + Bit8u type; + Bit8u standardIdent[5]; + Bit8u version; + Bit8u unused1; + Bit8u systemIdent[32]; + Bit8u volumeIdent[32]; + Bit8u unused2[8]; + Bit32u volumeSpaceSizeL; + Bit32u volumeSpaceSizeM; + Bit8u unused3[32]; + Bit16u volumeSetSizeL; + Bit16u volumeSetSizeM; + Bit16u volumeSeqNumberL; + Bit16u volumeSeqNumberM; + Bit16u logicBlockSizeL; + Bit16u logicBlockSizeM; + Bit32u pathTableSizeL; + Bit32u pathTableSizeM; + Bit32u locationPathTableL; + Bit32u locationOptPathTableL; + Bit32u locationPathTableM; + Bit32u locationOptPathTableM; + Bit8u rootEntry[34]; + Bit32u unused4[1858]; +} GCC_ATTRIBUTE(packed); + +struct isoDirEntry { + Bit8u length; + Bit8u extAttrLength; + Bit32u extentLocationL; + Bit32u extentLocationM; + Bit32u dataLengthL; + Bit32u dataLengthM; + Bit8u dateYear; + Bit8u dateMonth; + Bit8u dateDay; + Bit8u timeHour; + Bit8u timeMin; + Bit8u timeSec; + Bit8u timeZone; + Bit8u fileFlags; + Bit8u fileUnitSize; + Bit8u interleaveGapSize; + Bit16u VolumeSeqNumberL; + Bit16u VolumeSeqNumberM; + Bit8u fileIdentLength; + Bit8u ident[38]; // can be smaller +} GCC_ATTRIBUTE(packed); + +#ifdef _MSC_VER +#pragma pack () +#endif + +#if defined (WORD_BIGENDIAN) +#define EXTENT_LOCATION(de) ((de).extentLocationM) +#define DATA_LENGTH(de) ((de).dataLengthM) +#else +#define EXTENT_LOCATION(de) ((de).extentLocationL) +#define DATA_LENGTH(de) ((de).dataLengthL) +#endif + +#define ISO_FRAMESIZE 2048 +#define ISO_DIRECTORY 2 +#define ISO_MAXPATHNAME 256 +#define ISO_FIRST_VD 16 +#define IS_DIR(fileFlags) (fileFlags & ISO_DIRECTORY) + +class isoDrive : public DOS_Drive { +public: + isoDrive(char driveLetter, const char* device_name, Bit8u mediaid, int &error); + ~isoDrive(); + virtual bool FileOpen(DOS_File **file, char *name, Bit32u flags); + virtual bool FileCreate(DOS_File **file, char *name, Bit16u attributes); + virtual bool FileUnlink(char *name); + virtual bool RemoveDir(char *dir); + virtual bool MakeDir(char *dir); + virtual bool TestDir(char *dir); + virtual bool FindFirst(char *_dir, DOS_DTA &dta, bool fcb_findfirst); + virtual bool FindNext(DOS_DTA &dta); + virtual bool GetFileAttr(char *name, Bit16u *attr); + virtual bool Rename(char * oldname,char * newname); + virtual bool AllocationInfo(Bit16u *bytes_sector, Bit8u *sectors_cluster, Bit16u *total_clusters, Bit16u *free_clusters); + virtual bool FileExists(const char *name); + virtual bool FileStat(const char *name, FileStat_Block *const stat_block); + virtual Bit8u GetMediaByte(void); + virtual void EmptyCache(void){} + virtual bool isRemote(void); + bool readSector(Bit8u *buffer, Bit32u sector); +private: + int readDirEntry(isoDirEntry *de, Bit8u *data); + bool loadImage(); + bool lookupSingle(isoDirEntry *de, const char *name, Bit32u sectorStart, Bit32u length); + bool lookup(isoDirEntry *de, const char *path); + + std::vector searchCache; + std::vector::iterator dirIter; + isoDirEntry rootEntry; + Bit8u mediaid; + Bit8u subUnit; + char discLabel[32]; +}; + struct VFILE_Block; class Virtual_Drive: public DOS_Drive { diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 17bb93cd..7a395993 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.73 2004-08-04 09:12:51 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.74 2004-08-13 19:43:02 qbix79 Exp $ */ #include #include @@ -369,7 +369,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&MSCDEX_Init); #if C_MODEM secprop=control->AddSection_prop("modem",&MODEM_Init); - secprop->Add_bool("modem",true); + secprop->Add_bool("modem",false); secprop->Add_hex("comport",2); secprop->Add_int("listenport",23); @@ -400,7 +400,7 @@ void DOSBOX_Init(void) { #endif #if C_IPX secprop=control->AddSection_prop("ipx",&IPX_Init); - secprop->Add_bool("ipx", true); + secprop->Add_bool("ipx", false); MSG_Add("IPX_CONFIGFILE_HELP", "ipx -- Enable ipx over UDP/IP emulation.\n" ); From 5e41bcac32c29c8e82a8899edde7ebb8e4539297 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 19 Aug 2004 10:18:11 +0000 Subject: [PATCH 1823/4131] Add config option to run dosbox in high priority, defaults to enabled Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1905 --- src/gui/sdlmain.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 3f3594a3..9b81b2ee 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.71 2004-08-04 09:12:54 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.72 2004-08-19 10:18:11 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -677,6 +677,14 @@ static void GUI_StartUp(Section * sec) { sdl.updating=false; sdl.desktop.fullscreen=section->Get_bool("fullscreen"); sdl.wait_on_error=section->Get_bool("waitonerror"); + if (section->Get_bool("highpriority")) { +#ifdef WIN32 + LOG_MSG("SEtting priority %d", + SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS) + ); +//TODO add more platforms, with configure checks for get/setpriority +#endif + } sdl.mouse.locked=false; mouselocked=false; //Global for mapper sdl.mouse.requestlock=false; @@ -914,6 +922,7 @@ int main(int argc, char* argv[]) { sdl_sec->Add_bool("autolock",true); sdl_sec->Add_int("sensitivity",100); sdl_sec->Add_bool("waitonerror",true); + sdl_sec->Add_bool("highpriority",true); sdl_sec->Add_string("mapperfile","mapper.txt"); MSG_Add("SDL_CONFIGFILE_HELP", @@ -930,6 +939,7 @@ int main(int argc, char* argv[]) { "autolock -- Mouse will automatically lock, if you click on the screen.\n" "sensitiviy -- Mouse sensitivity.\n" "waitonerror -- Wait before closing the console if dosbox has an error.\n" + "highpriority -- Run dosbox in high prioty, helps sound output alot.\n" ); /* Init all the dosbox subsystems */ DOSBOX_Init(); From c88ea6a3aa6d7d10d586e9c0f4ca3ed8bf964e76 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 22 Aug 2004 18:33:57 +0000 Subject: [PATCH 1824/4131] Attempt from linux to update visual C.net project files :) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1906 --- visualc_net/dosbox.vcproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 66a4c046..56d6239e 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -305,6 +305,9 @@ + + @@ -353,6 +356,9 @@ + + From 1e54741e616ca3a8a22d85bb86de432afe057016 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 22 Aug 2004 18:48:31 +0000 Subject: [PATCH 1825/4131] Added some includes for stat Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1907 --- src/dos/cdrom.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index ecad2179..96633136 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -21,7 +21,11 @@ // SDL CDROM // ****************************************************** +#include #include +#include +#include +#include "dosbox.h" #include "SDL.h" #include "support.h" #include "cdrom.h" From 27a331e73d2c7242290cdd1dfd748d2b7bb8370c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 23 Aug 2004 08:04:25 +0000 Subject: [PATCH 1826/4131] New interpolating mixer routines Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1908 --- include/mixer.h | 53 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/include/mixer.h b/include/mixer.h index feeec3a6..cf8fafd3 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -17,23 +17,54 @@ */ typedef void (*MIXER_MixHandler)(Bit8u * sampdate,Bit32u len); +typedef void (*MIXER_Handler)(Bitu len); -#define MIXER_8MONO 0 -#define MIXER_8STEREO 1 -#define MIXER_16MONO 2 -#define MIXER_16STEREO 3 +enum BlahModes { + MIXER_8MONO,MIXER_8STEREO, + MIXER_16MONO,MIXER_16STEREO +}; + +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 MIN_AUDIO -(1<<(16-1)) -struct MIXER_Channel; +class MixerChannel { +public: + void SetVolume(float _left,float _right); + void UpdateVolume(void); + void SetFreq(Bitu _freq); + void Mix(Bitu _needed); + void AddSilence(void); //Fill up until needed + template + void AddSamples(Bitu len,void * data); + void AddSamples_m8(Bitu len,Bit8u * data); + void AddSamples_s8(Bitu len,Bit8u * data); + void AddSamples_m16(Bitu len,Bit16s * data); + void AddSamples_s16(Bitu len,Bit16s * data); + void AddStretched(Bitu len,Bit16s * data); //Strech block up into needed data + void FillUp(void); + void Enable(bool _yesno); + MIXER_Handler handler; + float volmain[2]; + Bit32s volmul[2]; + Bitu freq_add,freq_index; + Bitu done,needed; + Bits last[2]; + char * name; + bool enabled; + MixerChannel * next; +}; -MIXER_Channel * MIXER_AddChannel(MIXER_MixHandler handler,Bitu freq,char * name); -MIXER_Channel * MIXER_FindChannel(const char * name); -void MIXER_SetVolume(MIXER_Channel * chan,float left,float right); -void MIXER_SetFreq(MIXER_Channel * chan,Bitu freq); -void MIXER_SetMode(MIXER_Channel * chan,Bit8u mode); -void MIXER_Enable(MIXER_Channel * chan,bool enable); +MixerChannel * MIXER_AddChannel(MIXER_Handler handler,Bitu freq,char * name); +MixerChannel * MIXER_FindChannel(const char * name); /* PC Speakers functions, tightly related to the timer functions */ From 7bbec56bedaab155142b3c35a0ca1502bf3ee2d6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 23 Aug 2004 08:11:58 +0000 Subject: [PATCH 1827/4131] New interpolating mixer routines Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1909 --- src/hardware/adlib.cpp | 24 ++++++++++------------ src/hardware/disney.cpp | 27 +++++++++++++----------- src/hardware/gameblaster.cpp | 29 +++++++++++++------------- src/hardware/gus.cpp | 21 +++++++++---------- src/hardware/softmodem.cpp | 1 - src/hardware/tandy_sound.cpp | 40 +++++++++++++++++++++++------------- 6 files changed, 76 insertions(+), 66 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index ef0e74ba..10a9d690 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -86,7 +86,7 @@ namespace THEOPL3 { static struct { bool active; OPL_Mode mode; - MIXER_Channel * chan; + MixerChannel * chan; Bit32u last_used; Bit16s mixbuf[2][128]; struct { @@ -103,30 +103,30 @@ static struct { } raw; } opl; -static void OPL_CallBack(Bit8u *stream, Bit32u len) { +static void OPL_CallBack(Bitu len) { /* Check for size to update and check for 1 ms updates to the opl registers */ - /* Calculate teh machine ms we are at now */ - - /* update 1 ms of data */ Bitu i; switch(opl.mode) { case OPL_opl2: - OPL2::YM3812UpdateOne(0,(OPL2::INT16 *)stream,len); + OPL2::YM3812UpdateOne(0,(OPL2::INT16 *)MixTemp,len); + opl.chan->AddSamples_m16(len,(Bit16s*)MixTemp); break; case OPL_opl3: - THEOPL3::YMF262UpdateOne(0,(OPL2::INT16 *)stream,len); + THEOPL3::YMF262UpdateOne(0,(OPL2::INT16 *)MixTemp,len); + opl.chan->AddSamples_s16(len,(Bit16s*)MixTemp); break; case OPL_dualopl2: OPL2::YM3812UpdateOne(0,(OPL2::INT16 *)opl.mixbuf[0],len); OPL2::YM3812UpdateOne(1,(OPL2::INT16 *)opl.mixbuf[1],len); for (i=0;iAddSamples_s16(len,(Bit16s*)MixTemp); break; } if ((PIC_Ticks-opl.last_used)>5000) { - MIXER_Enable(opl.chan,false); + opl.chan->Enable(false); opl.active=false; } } @@ -149,7 +149,7 @@ void OPL_Write(Bitu port,Bitu val,Bitu iolen) { opl.last_used=PIC_Ticks; if (!opl.active) { opl.active=true; - MIXER_Enable(opl.chan,true); + opl.chan->Enable(true); } port&=3; if (port&1) { @@ -324,8 +324,6 @@ void OPL_Init(Section* sec,Bitu base,OPL_Mode oplmode,Bitu rate) { opl.mode=oplmode; memset(&opl.raw,0,sizeof(opl.raw)); opl.chan=MIXER_AddChannel(OPL_CallBack,rate,"FM"); - MIXER_SetMode(opl.chan,(opl.mode>OPL_opl2) ? MIXER_16STEREO : MIXER_16MONO); - MIXER_Enable(opl.chan,false); MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL"); sec->AddDestroyFunction(&OPL_Stop); }; diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 70fb4453..36d36efb 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -22,9 +22,6 @@ #include "mixer.h" #include "pic.h" #include "setup.h" -#include "programs.h" - - #define DISNEY_BASE 0x0378 @@ -35,11 +32,15 @@ static struct { Bit8u status; Bit8u control; Bit8u buffer[DISNEY_SIZE]; - Bitu used; - MIXER_Channel * chan; + Bitu used;Bitu last_used; + MixerChannel * chan; } disney; static void disney_write(Bitu port,Bitu val,Bitu iolen) { + if (!disney.last_used) { + disney.chan->Enable(true); + } + disney.last_used=PIC_Ticks; switch (port-DISNEY_BASE) { case 0: /* Data Port */ disney.data=val; @@ -80,18 +81,21 @@ static Bitu disney_read(Bitu port,Bitu iolen) { } -static void DISNEY_CallBack(Bit8u * stream,Bit32u len) { +static void DISNEY_CallBack(Bitu len) { if (!len) return; if (disney.used>len) { - memcpy(stream,disney.buffer,len); + disney.chan->AddSamples_m8(len,disney.buffer); memmove(disney.buffer,&disney.buffer[len],disney.used-len); disney.used-=len; - return; } else { - memcpy(stream,disney.buffer,disney.used); - memset(stream+disney.used,0x80,len-disney.used); + disney.chan->AddSamples_m8(disney.used,disney.buffer); + disney.chan->AddSilence(); disney.used=0; } + if (disney.last_used+5000Enable(false); + } } @@ -104,11 +108,10 @@ void DISNEY_Init(Section* sec) { IO_RegisterReadHandler(DISNEY_BASE,disney_read,IO_MB,3); disney.chan=MIXER_AddChannel(&DISNEY_CallBack,7000,"DISNEY"); - MIXER_SetMode(disney.chan,MIXER_8MONO); - MIXER_Enable(disney.chan,true); disney.status=0x84; disney.control=0; disney.used=0; + disney.last_used=0; } diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index 567be28e..5ef52c79 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -131,7 +131,7 @@ static int amplitude_lookup[16] = { /* global parameters */ static double sample_rate; static SAA1099 saa1099[2]; -static MIXER_Channel * cms_chan; +static MixerChannel * cms_chan; static Bit16s cms_buffer[2][2][CMS_BUFFER_SIZE]; static Bit16s * cms_buf_point[4] = { cms_buffer[0][0],cms_buffer[0][1],cms_buffer[1][0],cms_buffer[1][1] }; @@ -364,7 +364,7 @@ static void saa1099_write_port_w( int chip, int offset, int data ) static void write_cms(Bitu port,Bitu val,Bitu iolen) { - if (last_command + 100 < PIC_Ticks) MIXER_Enable(cms_chan,true); + if (last_command + 1000 < PIC_Ticks) cms_chan->Enable(true); last_command = PIC_Ticks; switch (port) { case 0x0220: @@ -390,32 +390,33 @@ static void write_cms(Bitu port,Bitu val,Bitu iolen) { } break; } - if (last_command > PIC_Ticks+1000) MIXER_Enable(cms_chan,true); } - static void CMS_CallBack(Bit8u * stream,Bit32u len) { + static void CMS_CallBack(Bitu len) { if (len > CMS_BUFFER_SIZE) return; saa1099_update(0, &cms_buf_point[0], (int)len); saa1099_update(1, &cms_buf_point[2], (int)len); + Bit16s * stream=(Bit16s *) MixTemp; /* Mix chip outputs */ for (Bitu l=0;lMAX_AUDIO) *(Bit16s *)stream=MAX_AUDIO; - else if (leftMAX_AUDIO) *stream=MAX_AUDIO; + else if (leftMAX_AUDIO) *(Bit16s *)stream=MAX_AUDIO; - else if (rightMAX_AUDIO) *stream=MAX_AUDIO; + else if (rightAddSamples_s16(len,(Bit16s *)MixTemp); + if (last_command + 10000 < PIC_Ticks) cms_chan->Enable(false); } @@ -428,8 +429,6 @@ static void write_cms(Bitu port,Bitu val,Bitu iolen) { /* Register the Mixer CallBack */ cms_chan=MIXER_AddChannel(CMS_CallBack,rate,"CMS"); - MIXER_SetMode(cms_chan,MIXER_16STEREO); - MIXER_Enable(cms_chan,true); last_command=PIC_Ticks; for (int s=0;s<2;s++) { diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 2a325158..40ff9785 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -45,7 +45,7 @@ #define LOG_GUS Bit8u adlib_commandreg; -static MIXER_Channel * gus_chan; +static MixerChannel * gus_chan; static Bit8u irqtable[8] = { 0, 2, 5, 3, 7, 11, 12, 15 }; static Bit8u dmatable[8] = { 0, 1, 3, 5, 6, 7, 0, 0 }; static Bit8u GUSRam[1024*1024]; // 1024K of GUS Ram @@ -558,7 +558,7 @@ static void ExecuteGlobRegister(void) { if(myGUS.ActiveChannels < 14) myGUS.ActiveChannels = 14; if(myGUS.ActiveChannels > 32) myGUS.ActiveChannels = 32; myGUS.ActiveMask=0xffffffffU >> (32-myGUS.ActiveChannels); - MIXER_Enable(gus_chan,true); + gus_chan->Enable(true); myGUS.basefreq = (Bit32u)((float)1000000/(1.619695497*(float)(myGUS.ActiveChannels))); LOG_GUS("GUS set to %d channels", myGUS.ActiveChannels); for (i=0;iUpdateWaveRamp(); @@ -752,15 +752,15 @@ static void GUS_DMA_Callback(DmaChannel * chan,DMAEvent event) { chan->Register_Callback(0); } -static void GUS_CallBack(Bit8u * stream,Bit32u len) { - Bit32s buffer[4096]; - memset(&buffer[0],0,len*8); +static void GUS_CallBack(Bitu len) { + memset(&MixTemp,0,len*8); Bitu i; + Bit16s * buf16 = (Bit16s *)MixTemp; + Bit32s * buf32 = (Bit32s *)MixTemp; for(i=0;igenerateSamples(&buffer[0],len); - Bit16s * bufptr = (Bit16s *)stream; + guschan[i]->generateSamples(buf32,len); for(i=0;i> 13)*AutoAmp)>>9; + Bit32s sample=((buf32[i] >> 13)*AutoAmp)>>9; if (sample>32767) { sample=32767; AutoAmp--; @@ -768,8 +768,9 @@ static void GUS_CallBack(Bit8u * stream,Bit32u len) { sample=-32768; AutoAmp--; } - bufptr[i] = (Bit16s)(sample); + buf16[i] = (Bit16s)(sample); } + gus_chan->AddSamples_s16(len,buf16); CheckVoiceIrq(); } @@ -848,8 +849,6 @@ void GUS_Init(Section* sec) { } // Register the Mixer CallBack gus_chan=MIXER_AddChannel(GUS_CallBack,GUS_RATE,"GUS"); - MIXER_SetMode(gus_chan,MIXER_16STEREO); - MIXER_Enable(gus_chan,false); myGUS.gRegData=0x1; GUSReset(); myGUS.gRegData=0x0; diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp index 2fcbe055..0db28141 100644 --- a/src/hardware/softmodem.cpp +++ b/src/hardware/softmodem.cpp @@ -684,7 +684,6 @@ protected: double f1, f2; Bitu len,pos; char str[256]; - MIXER_Channel * chan; } dial; }; diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index bad2feca..4ba44264 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -28,6 +28,7 @@ #include "setup.h" #include "pic.h" +#define DAC_CLOCK 3570000 #define MAX_OUTPUT 0x7fff #define STEP 0x10000 @@ -70,20 +71,22 @@ struct SN76496 static struct SN76496 sn; static struct { - MIXER_Channel * chan; + MixerChannel * chan; bool enabled; Bitu last_write; + struct { + bool playing; + Bitu rate; + } dac; } tandy; - -static void SN76496Write(Bitu port,Bitu data,Bitu iolen) -{ +static void SN76496Write(Bitu port,Bitu data,Bitu iolen) { struct SN76496 *R = &sn; tandy.last_write=PIC_Ticks; if (!tandy.enabled) { - MIXER_Enable(tandy.chan,true); + tandy.chan->Enable(true); tandy.enabled=true; } @@ -155,15 +158,15 @@ static void SN76496Write(Bitu port,Bitu data,Bitu iolen) } } -static void SN76496Update(Bit8u * stream,Bit32u length) +static void SN76496Update(Bitu length) { - if ((tandy.last_write+1000)Enable(false); } int i; struct SN76496 *R = &sn; - Bit16s * buffer=(Bit16s *)stream; + Bit16s * buffer=(Bit16s *)MixTemp; /* If the volume is 0, increase the counter */ for (i = 0;i < 4;i++) @@ -177,7 +180,8 @@ static void SN76496Update(Bit8u * stream,Bit32u length) } } - while (length > 0) + Bitu count=length; + while (count) { int vol[4]; unsigned int out; @@ -246,8 +250,9 @@ static void SN76496Update(Bit8u * stream,Bit32u length) *(buffer++) = out / STEP; - length--; + count--; } + tandy.chan->AddSamples_m16(length,(Bit16s *)MixTemp); } @@ -267,6 +272,12 @@ static void SN76496_set_clock(int clock) } +static void TandyDACWrite(Bitu port,Bitu data,Bitu iolen) { + LOG_MSG("Write tandy dac %X val %X",port,data); + + +} + static void SN76496_set_gain(int gain) { @@ -298,17 +309,18 @@ static void SN76496_set_gain(int gain) void TANDYSOUND_Init(Section* sec) { + if (machine!=MCH_TANDY) return; Section_prop * section=static_cast(sec); if(!section->Get_bool("tandy")) return; - IO_RegisterWriteHandler(0xc0,SN76496Write,IO_MB); + IO_RegisterWriteHandler(0xc0,SN76496Write,IO_MB,2); + IO_RegisterWriteHandler(0xc4,TandyDACWrite,IO_MB,4); + Bit32u sample_rate = section->Get_int("tandyrate"); tandy.chan=MIXER_AddChannel(&SN76496Update,sample_rate,"TANDY"); - MIXER_Enable(tandy.chan,false); tandy.enabled=false; - MIXER_SetMode(tandy.chan,MIXER_16MONO); Bitu i; struct SN76496 *R = &sn; From a10d8f9bf04674f7fd94dfa1caa7e23ac729b923 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 23 Aug 2004 08:24:07 +0000 Subject: [PATCH 1828/4131] New mixer config options and removed some Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1910 --- src/dosbox.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 7a395993..24a542e0 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.74 2004-08-13 19:43:02 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.75 2004-08-23 08:24:07 harekiet Exp $ */ #include #include @@ -91,6 +91,7 @@ void IPX_Init(Section*); #if C_DIRECTSERIAL void DIRECTSERIAL_Init(Section* sec); #endif +void SID_Init(Section* sec); void PIC_Init(Section*); void TIMER_Init(Section*); @@ -266,6 +267,7 @@ void DOSBOX_Init(void) { secprop->Add_bool("nosound",false); secprop->Add_int("rate",22050); secprop->Add_int("blocksize",2048); + secprop->Add_int("prebuffer",10); MSG_Add("MIXER_CONFIGFILE_HELP", "nosound -- Enable silent mode, sound is still emulated though.\n" @@ -273,6 +275,7 @@ void DOSBOX_Init(void) { " probably lower their sound quality.\n" "blocksize -- Mixer block size, larger blocks might help sound stuttering\n" " but sound will also be more lagged.\n" + "prebuffer -- How many milliseconds of data to keep on top of the blocksize.\n" ); secprop=control->AddSection_prop("midi",&MIDI_Init); @@ -300,7 +303,6 @@ void DOSBOX_Init(void) { secprop->Add_int("dma",1); secprop->Add_int("hdma",5); secprop->Add_bool("mixer",true); - secprop->Add_int("sbrate",22050); secprop->Add_string("oplmode","auto"); secprop->Add_int("oplrate",22050); @@ -308,7 +310,6 @@ void DOSBOX_Init(void) { "type -- Type of sblaster to emulate:none,sb1,sb2,sbpro1,sbpro2,sb16.\n" "base,irq,dma,hdma -- The IO/IRQ/DMA/High DMA address of the soundblaster.\n" "mixer -- Allow the soundblaster mixer to modify the dosbox mixer.\n" - "sbrate -- Sample rate of soundblaster emulation.\n" "oplmode -- Type of OPL emulation: auto,cms,opl2,dualopl2,opl3.\n" " On auto the mode is determined by sblaster type.\n" "oplrate -- Sample rate of OPL music emulation.\n" From b77308510dc92e78574a5089122a98ea10452bf9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 23 Aug 2004 08:25:20 +0000 Subject: [PATCH 1829/4131] New mixer code with interpolation. New prebuffering scheme. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1911 --- src/hardware/mixer.cpp | 361 ++++++++++++++++++++++++----------------- 1 file changed, 210 insertions(+), 151 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 36ad2ecd..ec6af869 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -9,7 +9,7 @@ * 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. + * 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 @@ -28,6 +28,7 @@ #include "SDL.h" #include "mem.h" +#include "pic.h" #include "dosbox.h" #include "mixer.h" #include "timer.h" @@ -38,34 +39,14 @@ #include "hardware.h" #include "programs.h" -#define MIXER_MAXCHAN 8 -#define MIXER_BUFSIZE (16*1024) #define MIXER_SSIZE 4 -#define MIXER_SHIFT 16 +#define MIXER_SHIFT 14 #define MIXER_REMAIN ((1<MAX_AUDIO) ? (Bit16s)MAX_AUDIO : (SAMPhandler)(((Bit8u*)&mixer.temp)+sizeof(mixer.temp.TYPE[0]),sample_toread); \ - Bitu sample_index=(1 << MIXER_SHIFT) - chan->sample_left; \ - for (Bitu mix=0;mix> MIXER_SHIFT;sample_index+=chan->sample_add; \ - mixer.work[mix][0]+=chan->vol_mul[LCHAN]*MAKE_##TYPE( LCHAN ); \ - mixer.work[mix][1]+=chan->vol_mul[RCHAN]*MAKE_##TYPE( RCHAN ); \ - } \ - chan->remain=*(Bitu *)&mixer.temp.TYPE[sample_index>>MIXER_SHIFT]; \ - chan->sample_left=sample_total-sample_index; \ - break; \ -} - struct MIXER_Channel { double vol_main[2]; Bits vol_mul[2]; @@ -90,19 +71,11 @@ static Bit8u wavheader[]={ }; static struct { - struct { - Bit16s data[MIXER_BUFSIZE][2]; - Bitu read,write; - } out; Bit32s work[MIXER_BUFSIZE][2]; - union { - Bit16s m16[MIXER_BUFSIZE][1]; - Bit16s s16[MIXER_BUFSIZE][2]; - Bit8u m8[MIXER_BUFSIZE][1]; - Bit8u s8[MIXER_BUFSIZE][2]; - } temp; - double mastervol[2]; - MIXER_Channel * channels; + Bitu pos,done; + Bitu needed,min_needed; + float mastervol[2]; + MixerChannel * channels; bool nosound; Bitu freq; Bitu blocksize; @@ -115,24 +88,22 @@ static struct { } wave; } mixer; -MIXER_Channel * MIXER_AddChannel(MIXER_MixHandler handler,Bitu freq,char * name) { -//TODO Find a free channel - MIXER_Channel * chan=new MIXER_Channel; - if (!chan) return 0; - chan->playing=false; - chan->mode=MIXER_16STEREO; +Bit8u MixTemp[MIXER_BUFSIZE]; + +MixerChannel * MIXER_AddChannel(MIXER_Handler handler,Bitu freq,char * name) { + MixerChannel * chan=new MixerChannel(); chan->handler=handler; chan->name=name; - chan->sample_add=(freq<sample_left=0; + chan->SetFreq(freq); chan->next=mixer.channels; + chan->SetVolume(1,1); + chan->enabled=false; mixer.channels=chan; - MIXER_SetVolume(chan,1,1); return chan; } -MIXER_Channel * MIXER_FindChannel(const char * name) { - MIXER_Channel * chan=mixer.channels; +MixerChannel * MIXER_FindChannel(const char * name) { + MixerChannel * chan=mixer.channels; while (chan) { if (!strcasecmp(chan->name,name)) break; chan=chan->next; @@ -140,129 +111,212 @@ MIXER_Channel * MIXER_FindChannel(const char * name) { return chan; } -void MIXER_SetFreq(MIXER_Channel * chan,Bitu freq) { - if (!chan) return; - chan->freq=freq; - chan->sample_add=(freq<mode=mode; +void MixerChannel::UpdateVolume(void) { + volmul[0]=(Bits)((1 << MIXER_VOLSHIFT)*volmain[0]*mixer.mastervol[0]); + volmul[1]=(Bits)((1 << MIXER_VOLSHIFT)*volmain[1]*mixer.mastervol[1]); } -void MIXER_UpdateVolume(MIXER_Channel * chan) { - chan->vol_mul[0]=(Bits)((1 << MIXER_VOLSHIFT)*chan->vol_main[0]*mixer.mastervol[0]); - chan->vol_mul[1]=(Bits)((1 << MIXER_VOLSHIFT)*chan->vol_main[1]*mixer.mastervol[1]); +void MixerChannel::SetVolume(float _left,float _right) { + volmain[0]=_left; + volmain[1]=_right; + UpdateVolume(); } -void MIXER_SetVolume(MIXER_Channel * chan,float left,float right) { - if (!chan) return; - if (left>=0) chan->vol_main[0]=left; - if (right>=0) chan->vol_main[1]=right; - MIXER_UpdateVolume(chan); +void MixerChannel::Enable(bool _yesno) { + if (_yesno==enabled) return; + enabled=_yesno; + if (enabled) { + freq_index=MIXER_REMAIN; + SDL_LockAudio(); + if (doneplaying=enable; +void MixerChannel::SetFreq(Bitu _freq) { + freq_add=(_freq<done) { + Bitu todo=needed-done; + todo*=freq_add; + if (todo & MIXER_REMAIN) { + todo=(todo >> MIXER_SHIFT) + 1; + } else { + todo=(todo >> MIXER_SHIFT); + } + handler(todo); + } +} + +void MixerChannel::AddSilence(void) { + if (done +INLINE void MixerChannel::AddSamples(Bitu len,void * data) { + Bits diff[2]; + Bit8u * data8=(Bit8u*)data; + Bit16s * data16=(Bit16s*)data; + Bitu mixpos=mixer.pos+done; + freq_index&=MIXER_REMAIN; + Bitu pos=0; + goto thestart; + while (1) { + Bitu new_pos=freq_index >> MIXER_SHIFT; + if (pos=len) return; + if (_8bits) { + if (stereo) { + diff[0]=(((Bit8s)(data8[pos*2+0] ^ 0x80)) << 8)-last[0]; + diff[1]=(((Bit8s)(data8[pos*2+1] ^ 0x80)) << 8)-last[1]; + } else { + diff[0]=(((Bit8s)(data8[pos] ^ 0x80)) << 8)-last[0]; + } + } else { + if (stereo) { + diff[0]=data16[pos*2+0]-last[0]; + diff[1]=data16[pos*2+1]-last[1]; + } else { + diff[0]=data16[pos]-last[0]; + } + } + } + Bits diff_mul=freq_index & MIXER_REMAIN; + freq_index+=freq_add; + mixpos&=MIXER_BUFMASK; + Bits sample=last[0]+((diff[0]*diff_mul) >> MIXER_SHIFT); + mixer.work[mixpos][0]+=sample*volmul[0]; + if (stereo) sample=last[1]+((diff[1]*diff_mul) >> MIXER_SHIFT); + mixer.work[mixpos][1]+=sample*volmul[1]; + mixpos++;done++; + } +} + +void MixerChannel::AddStretched(Bitu len,Bit16s * data) { + if (done>=needed) { + LOG_MSG("Can't add, buffer full"); + return; + } + Bitu outlen=needed-done;Bits diff; + freq_index=0; + Bitu temp_add=(len << MIXER_SHIFT)/outlen; + Bitu mixpos=mixer.pos+done;done=needed; + Bitu pos=0; + diff=data[0]-last[0]; + while (outlen--) { + Bitu new_pos=freq_index >> MIXER_SHIFT; + if (pos> MIXER_SHIFT); + mixer.work[mixpos][0]+=sample*volmul[0]; + mixer.work[mixpos][1]+=sample*volmul[1]; + mixpos++; + } +}; + +void MixerChannel::AddSamples_m8(Bitu len,Bit8u * data) { + AddSamples(len,data); +} +void MixerChannel::AddSamples_s8(Bitu len,Bit8u * data) { + AddSamples(len,data); +} +void MixerChannel::AddSamples_m16(Bitu len,Bit16s * data) { + AddSamples(len,data); +} +void MixerChannel::AddSamples_s16(Bitu len,Bit16s * data) { + AddSamples(len,data); +} + +void MixerChannel::FillUp(void) { + SDL_LockAudio(); + if (!enabled || doneMIXER_BUFSIZE) samples=MIXER_BUFSIZE; - MIXER_Channel * chan=mixer.channels; +static void MIXER_MixData(Bitu needed) { + MixerChannel * chan=mixer.channels; while (chan) { - if (chan->playing) { - /* This should always allocate 1 extra sample */ - Bitu sample_total=(samples*chan->sample_add)-chan->sample_left; - Bitu sample_toread=sample_total >> MIXER_SHIFT; - if (sample_total & MIXER_REMAIN) sample_toread++; - sample_total=(sample_toread+1)<remain; - switch (chan->mode) { - case MIXER_8MONO: - MIX_NORMAL(m8,0,0); - break; - case MIXER_8STEREO: - MIX_NORMAL(m8,0,1); - break; - case MIXER_16MONO: - MIX_NORMAL(m16,0,0); - break; - case MIXER_16STEREO: - MIX_NORMAL(s16,0,1); - break; - default: - E_Exit("MIXER:Illegal sound mode %2X",chan->mode); - break; - } - } + chan->Mix(needed); chan=chan->next; } - Bitu index=mixer.out.write; - for (Bitu read=0;read> MIXER_VOLSHIFT; - mixer.out.data[index][0]=MIXER_CLIP(temp); - mixer.work[read][0]=0; - temp=mixer.work[read][1] >> MIXER_VOLSHIFT; - mixer.out.data[index][1]=MIXER_CLIP(temp); - mixer.work[read][1]=0; - index=(index+1)&(MIXER_BUFSIZE-1); - } - mixer.out.write=index; - if (mixer.wave.handle) { - index=(MIXER_BUFSIZE+mixer.out.write-samples); - while (samples--) { - index=index&(MIXER_BUFSIZE-1); - mixer.wave.buf[mixer.wave.used][0]=mixer.out.data[index][0]; - mixer.wave.buf[mixer.wave.used][1]=mixer.out.data[index][1]; - index++;mixer.wave.used++; - } - if (mixer.wave.used>(MIXER_WAVESIZE-1024)){ - fwrite(mixer.wave.buf,1,mixer.wave.used*MIXER_SSIZE,mixer.wave.handle); - mixer.wave.length+=mixer.wave.used*MIXER_SSIZE; - mixer.wave.used=0; - } - } + mixer.done=needed; } static void MIXER_Mix(void) { + SDL_LockAudio(); + MIXER_MixData(mixer.needed); mixer.tick_remain+=mixer.tick_add; - Bitu count=mixer.tick_remain>>MIXER_SHIFT; - mixer.tick_remain&=((1<=MIXER_BUFSIZE) size-=MIXER_BUFSIZE; - if (size>mixer.blocksize*2) return; - MIXER_MixData(count); + mixer.needed+=(mixer.tick_remain>>MIXER_SHIFT); + mixer.tick_remain&=MIXER_REMAIN; + SDL_UnlockAudio(); } static void MIXER_Mix_NoSound(void) { + mixer.done=0; mixer.tick_remain+=mixer.tick_add; Bitu count=mixer.tick_remain>>MIXER_SHIFT; - mixer.tick_remain&=((1<=MIXER_BUFSIZE) size-=MIXER_BUFSIZE; - if (size*MIXER_SSIZE<(Bitu)len) { -// LOG(0,"Buffer underrun"); - /* When there's a buffer underrun, keep the data so there will be more next time */ + Bitu need=(Bitu)len/MIXER_SSIZE; + if (need>mixer.done) { +// LOG_MSG("Buffer underrun"); return; } - Bitu remain=MIXER_BUFSIZE-mixer.out.read; - if (remain>=(Bitu)len/MIXER_SSIZE) { - memcpy((void *)stream,(void *)&mixer.out.data[mixer.out.read][0],len); - } else { - memcpy((void *)stream,(void *)&mixer.out.data[mixer.out.read][0],remain*MIXER_SSIZE); - stream+=remain*MIXER_SSIZE; - memcpy((void *)stream,(void *)&mixer.out.data[0][0],(len)-remain*MIXER_SSIZE); + /* Reduce done count in all channels */ + for (MixerChannel * chan=mixer.channels;chan;chan=chan->next) { + if (chan->done>need) chan->done-=need; + else chan->done=0; + } + mixer.done-=need; + mixer.needed-=need; + if (mixer.done>mixer.min_needed) { + Bitu diff=mixer.done-mixer.min_needed; + mixer.tick_add=((mixer.freq-(diff>>2)) << MIXER_SHIFT)/1000; + } else { + Bitu diff=mixer.needed-mixer.done; + mixer.tick_add=((mixer.freq+diff*3) << MIXER_SHIFT)/1000; + } + Bit16s * output=(Bit16s *)stream; + while (need--) { + mixer.work[mixer.pos][0]>>=MIXER_VOLSHIFT; + *output++=MIXER_CLIP(mixer.work[mixer.pos][0]); + mixer.work[mixer.pos][0]=0; + mixer.work[mixer.pos][1]>>=MIXER_VOLSHIFT; + *output++=MIXER_CLIP(mixer.work[mixer.pos][1]); + mixer.work[mixer.pos][1]=0; + mixer.pos=(mixer.pos+1)&MIXER_BUFMASK; } - mixer.out.read+=(len/MIXER_SSIZE); - if (mixer.out.read>=MIXER_BUFSIZE) mixer.out.read-=MIXER_BUFSIZE; } static void MIXER_WaveEvent(void) { @@ -297,7 +351,7 @@ static void MIXER_Stop(Section* sec) { class MIXER : public Program { public: - void MakeVolume(char * scan,double & vol0,double & vol1) { + void MakeVolume(char * scan,float & vol0,float & vol1) { Bitu w=0; bool db=(toupper(*scan)=='D'); if (db) scan++; @@ -306,7 +360,7 @@ public: ++scan;w=1; } char * before=scan; - double val=strtod(scan,&scan); + float val=(float)strtod(scan,&scan); if (before==scan) { ++scan;continue; } @@ -321,7 +375,7 @@ public: } if (!w) vol1=vol0; } - void ShowVolume(char * name,double vol0,double vol1) { + void ShowVolume(char * name,float vol0,float vol1) { WriteOut("%-8s %3.0f:%-3.0f %+3.2f:%-+3.2f \n",name, vol0*100,vol1*100, 20*log(vol0)/log(10.0f),20*log(vol1)/log(10.0f) @@ -329,14 +383,14 @@ public: } void Run(void) { if (cmd->FindString("MASTER",temp_line,false)) { - MakeVolume((char *)temp_line.c_str(),mixer.mastervol[0],mixer.mastervol[1]); + MakeVolume((char *)temp_line.c_str(),mixer.mastervol[0],mixer.mastervol[1]); } - MIXER_Channel * chan=mixer.channels; + MixerChannel * chan=mixer.channels; while (chan) { if (cmd->FindString(chan->name,temp_line,false)) { - MakeVolume((char *)temp_line.c_str(),chan->vol_main[0],chan->vol_main[1]); + MakeVolume((char *)temp_line.c_str(),chan->volmain[0],chan->volmain[1]); } - MIXER_UpdateVolume(chan); + chan->UpdateVolume(); chan=chan->next; } if (cmd->FindExist("/NOSHOW")) return; @@ -344,7 +398,7 @@ public: WriteOut("Channel Main Main(dB)\n"); ShowVolume("MASTER",mixer.mastervol[0],mixer.mastervol[1]); for (chan=mixer.channels;chan;chan=chan->next) - ShowVolume(chan->name,chan->vol_main[0],chan->vol_main[1]); + ShowVolume(chan->name,chan->volmain[0],chan->volmain[1]); } }; @@ -362,9 +416,9 @@ void MIXER_Init(Section* sec) { /* Initialize the internal stuff */ mixer.channels=0; - mixer.out.write=0; - mixer.out.read=0; - memset(mixer.out.data,0,sizeof(mixer.out.data)); + mixer.pos=0; + mixer.done=0; + memset(mixer.work,0,sizeof(mixer.work)); mixer.wave.handle=0; mixer.wave.used=0; mixer.mastervol[0]=1.0f; @@ -393,10 +447,15 @@ void MIXER_Init(Section* sec) { } else { mixer.freq=obtained.freq; mixer.blocksize=obtained.samples; - mixer.tick_add=((mixer.freq+100) << MIXER_SHIFT)/1000; + mixer.tick_add=(mixer.freq << MIXER_SHIFT)/1000; TIMER_AddTickHandler(MIXER_Mix); SDL_PauseAudio(0); } + mixer.min_needed=section->Get_int("prebuffer"); + if (mixer.min_needed>100) mixer.min_needed=100; + mixer.min_needed=(mixer.freq*mixer.min_needed)/1000; + MAPPER_AddHandler(MIXER_WaveEvent,MK_f6,MMOD1,"recwave","Rec Wave"); PROGRAMS_MakeFile("MIXER.COM",MIXER_ProgramStart); } + From 322373756cd121f181703b9cbd2994dcd5f4576e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 23 Aug 2004 08:30:51 +0000 Subject: [PATCH 1830/4131] Total rewrite of the pcspeaker sound Better support for pit mode 2/4 en speaker on/off bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1912 --- src/hardware/pcspeaker.cpp | 395 ++++++++++++++++++++++--------------- 1 file changed, 241 insertions(+), 154 deletions(-) diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 51b626c9..3166bf2e 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -28,202 +28,289 @@ #define PI 3.14159265358979323846 #endif -#define SPKR_BUF 4096 -#define SPKR_RATE 22050 +#define SPKR_ENTRIES 1024 #define SPKR_VOLUME 5000 +#define SPKR_SHIFT 8 +#define SPKR_SPEED ((SPKR_VOLUME*2)/70) -#define SPKR_SHIFT 10 - -enum SPKR_MODE { - MODE_NONE,MODE_WAVE,MODE_DELAY,MODE_ONOFF,MODE_REAL, +enum SPKR_MODES { + SPKR_OFF,SPKR_ON,SPKR_PIT_OFF,SPKR_PIT_ON }; -/* TODO - Maybe interpolate at the moment we switch between on/off - Keep track of postion of speaker conus in ONOFF mode -*/ +struct DelayEntry { + Bitu index; + Bits vol; +}; static struct { - Bit16s volume; - MIXER_Channel * chan; - Bit16u buffer[SPKR_BUF]; - SPKR_MODE mode; - SPKR_MODE pit_mode; - struct { - Bit16s buf[SPKR_BUF]; - Bitu used; - } real; - struct { - Bitu index; - struct { - Bitu max,half; - } count,new_count; - } wave; - struct { - Bit16s buf[SPKR_BUF]; - Bitu pos; - } out; - struct { - Bitu index; - Bitu max; - } delay; - struct { - Bitu vol; - Bitu rate; - Bitu rate_conv; - Bitu tick_add; - } hw; - bool onoff,enabled; - Bitu buf_pos; + MixerChannel * chan; + SPKR_MODES mode; + Bitu pit_mode; + Bitu rate; + + Bits pit_last; + Bitu pit_new_max,pit_new_half; + Bitu pit_max,pit_half; + Bitu pit_index; + Bits volwant,volcur; + Bitu last_ticks; + Bitu last_index; + DelayEntry entries[SPKR_ENTRIES]; + Bitu used; } spkr; -static void GenerateSound(Bitu size) { - while (spkr.out.pos=spkr.wave.count.max) { - *stream++=+spkr.volume; - spkr.wave.index-=spkr.wave.count.max; - spkr.wave.count.max=spkr.wave.new_count.max; - spkr.wave.count.half=spkr.wave.new_count.half; - } else if (spkr.wave.index>spkr.wave.count.half) { - *stream++=-spkr.volume; - } else { - *stream++=+spkr.volume; - } +static void AddDelayEntry(Bitu index,Bits vol) { + if (spkr.used==SPKR_ENTRIES) { + return; + } + spkr.entries[spkr.used].index=index; + spkr.entries[spkr.used].vol=vol; + spkr.used++; +} + + +static void ForwardPIT(Bitu newindex) { + Bitu micro=(newindex-spkr.last_index) << SPKR_SHIFT; + Bitu delay_base=spkr.last_index << SPKR_SHIFT; + spkr.last_index=newindex; + switch (spkr.pit_mode) { + case 0: + return; + case 2: + while (micro) { + /* passed the initial low cycle? */ + if (spkr.pit_index>=spkr.pit_half) { + /* Start a new low cycle */ + if ((spkr.pit_index+micro)>=spkr.pit_max) { + Bitu delay=spkr.pit_max-spkr.pit_index; + delay_base+=delay;micro-=delay; + spkr.pit_last=-SPKR_VOLUME; + if (spkr.mode==SPKR_PIT_ON) AddDelayEntry(delay_base,spkr.pit_last); + spkr.pit_index=0; + } else { + spkr.pit_index+=micro; + return; } - spkr.out.pos+=samples; - } - break; - case MODE_ONOFF: - { - Bit16s val=spkr.onoff ? spkr.volume : -spkr.volume; - for (Bitu i=0;i> 16]; - buf_pos+=buf_add; + } else { + if ((spkr.pit_index+micro)>=spkr.pit_half) { + Bitu delay=spkr.pit_half-spkr.pit_index; + delay_base+=delay;micro-=delay; + spkr.pit_last=SPKR_VOLUME; + if (spkr.mode==SPKR_PIT_ON) AddDelayEntry(delay_base,spkr.pit_last); + spkr.pit_index=spkr.pit_half; + } else { + /* Didn't reach end, forward index */ + spkr.pit_index+=micro; + return; } - spkr.out.pos+=samples; - break; } - case MODE_DELAY: - { - for (Bitu i=0;i=spkr.pit_half) { + if ((spkr.pit_index+micro)>=spkr.pit_max) { + Bitu delay=spkr.pit_max-spkr.pit_index; + delay_base+=delay;micro-=delay; + spkr.pit_last=SPKR_VOLUME; + if (spkr.mode==SPKR_PIT_ON) AddDelayEntry(delay_base,spkr.pit_last); + spkr.pit_index=0; + /* Load the new count */ + spkr.pit_half=spkr.pit_new_half; + spkr.pit_max=spkr.pit_new_max; + } else { + /* Didn't reach end, forward index */ + spkr.pit_index+=micro; + return; + } + } else { + if ((spkr.pit_index+micro)>=spkr.pit_half) { + Bitu delay=spkr.pit_half-spkr.pit_index; + delay_base+=delay;micro-=delay; + spkr.pit_last=-SPKR_VOLUME; + if (spkr.mode==SPKR_PIT_ON) AddDelayEntry(delay_base,spkr.pit_last); + spkr.pit_index=spkr.pit_half; + } else { + /* Didn't reach end, forward index */ + spkr.pit_index+=micro; + return; + } + } + } + break; + //END CASE 3 + case 4: + if (spkr.pit_index=spkr.pit_max) { + Bitu delay=spkr.pit_max-spkr.pit_index; + delay_base+=delay;micro-=delay; + spkr.pit_last=-SPKR_VOLUME; + if (spkr.mode==SPKR_PIT_ON) AddDelayEntry(delay_base,spkr.pit_last); //No new events unless reprogrammed + spkr.pit_index=spkr.pit_max; + } else spkr.pit_index+=micro; + } + break; + //END CASE 4 } } void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode) { - Bitu index=PIC_Index(); - Bitu len=(spkr.hw.rate_conv*index)>>16; - if (spkr.mode==MODE_NONE) MIXER_Enable(spkr.chan,true); + if (!spkr.last_ticks) { + spkr.chan->Enable(true); + spkr.last_index=0; + } + spkr.last_ticks=PIC_Ticks; + Bitu newindex=PIC_Index(); + ForwardPIT(newindex); switch (mode) { case 0: /* Mode 0 one shot, used with realsound */ - if (!spkr.enabled) return; - if (cntr>72) cntr=72; - if (spkr.mode!=MODE_REAL) GenerateSound(len); - spkr.pit_mode=MODE_REAL; - if (spkr.real.used80) { + cntr=80; + } + spkr.pit_last=(cntr-40)*SPKR_SPEED; + AddDelayEntry(newindex << SPKR_SHIFT,spkr.pit_last); + spkr.pit_index=0; + break; + case 2: /* Single cycle low, rest low high generator */ + spkr.pit_index=0; + spkr.pit_last=-SPKR_VOLUME; + AddDelayEntry(newindex << SPKR_SHIFT,spkr.pit_last); + spkr.pit_half=(Bitu)(((double)(1000000 << SPKR_SHIFT)/PIT_TICK_RATE)*1); + spkr.pit_max=(Bitu)(((double)(1000000 << SPKR_SHIFT)/PIT_TICK_RATE)*cntr); break; case 3: /* Square wave generator */ - GenerateSound(len); - spkr.pit_mode=MODE_WAVE; - spkr.wave.new_count.max=cntr << SPKR_SHIFT; - spkr.wave.new_count.half=(cntr/2) << SPKR_SHIFT; + if (cntr<=40) { + /* Makes DIGGER sound better */ + spkr.pit_last=0; + spkr.pit_mode=0; + return; + } + spkr.pit_new_max=(Bitu)(((double)(1000000 << SPKR_SHIFT)/PIT_TICK_RATE)*cntr); + spkr.pit_new_half=spkr.pit_new_max/2; break; - case 4: /* Keep high till end of count */ - GenerateSound(len); - spkr.delay.max=cntr << SPKR_SHIFT; - spkr.delay.index=0; - spkr.pit_mode=MODE_DELAY; + case 4: /* Software triggered strobe */ + spkr.pit_last=SPKR_VOLUME; + AddDelayEntry(newindex << SPKR_SHIFT,spkr.pit_last); + spkr.pit_index=0; + spkr.pit_max=(Bitu)(((double)(1000000 << SPKR_SHIFT)/PIT_TICK_RATE)*cntr); break; + default: +#if C_DEBUG + LOG_MSG("Unhandled speaker mode %d",mode); +#endif + return; } - if (spkr.enabled) spkr.mode=spkr.pit_mode; + spkr.pit_mode=mode; } void PCSPEAKER_SetType(Bitu mode) { - Bitu index=PIC_Index(); - Bitu len=(spkr.hw.rate_conv*index)>>16; - GenerateSound(len); - if (spkr.mode==MODE_NONE) MIXER_Enable(spkr.chan,true); + if (!spkr.last_ticks) { + spkr.chan->Enable(true); + spkr.last_index=0; + } + spkr.last_ticks=PIC_Ticks; + Bitu newindex=PIC_Index(); + ForwardPIT(newindex); switch (mode) { case 0: - if (spkr.mode==MODE_ONOFF && spkr.onoff) spkr.onoff=false; - else spkr.mode=MODE_NONE; - spkr.enabled=false; + spkr.mode=SPKR_OFF; + AddDelayEntry(newindex << SPKR_SHIFT,-SPKR_VOLUME); break; case 1: - spkr.mode=MODE_ONOFF; - spkr.enabled=false; - spkr.onoff=false; + spkr.mode=SPKR_PIT_OFF; + AddDelayEntry(newindex << SPKR_SHIFT,-SPKR_VOLUME); break; case 2: - spkr.enabled=false; - spkr.onoff=true; - spkr.mode=MODE_ONOFF; + spkr.mode=SPKR_ON; + AddDelayEntry(newindex << SPKR_SHIFT,SPKR_VOLUME); break; case 3: - spkr.onoff=true; - spkr.enabled=true; - spkr.mode=spkr.pit_mode; + if (spkr.mode!=SPKR_PIT_ON) { + AddDelayEntry(newindex << SPKR_SHIFT,spkr.pit_last); + } + spkr.mode=SPKR_PIT_ON; break; }; } -static void PCSPEAKER_CallBack(Bit8u * stream,Bit32u len) { - if (spkr.out.pos> SPKR_SHIFT)*vol_len)/2; + spkr.volcur-=(SPKR_SPEED*vol_len) >> SPKR_SHIFT; + } else { + value+=(((SPKR_SPEED*vol_len) >> SPKR_SHIFT)*vol_len)/2; + spkr.volcur+=(SPKR_SPEED*vol_len) >> SPKR_SHIFT; + } + index+=vol_len; + } + } + } + *stream++=value/micro_add; + } + spkr.chan->AddSamples_m16(len,(Bit16s*)MixTemp); + if ((spkr.last_ticks+10000)Enable(false); + } } void PCSPEAKER_Init(Section* sec) { Section_prop * section=static_cast(sec); if(!section->Get_bool("pcspeaker")) return; - spkr.volume=SPKR_VOLUME; - spkr.mode=MODE_NONE; - spkr.pit_mode=MODE_WAVE; - spkr.real.used=0; - spkr.out.pos=0; - spkr.onoff=false; -// spkr.hw.vol=section->Get_int("volume"); - spkr.hw.rate=section->Get_int("pcrate"); - spkr.hw.rate_conv=(spkr.hw.rate<<16)/1000000; - spkr.hw.tick_add=(Bitu)((double)PIT_TICK_RATE*(double)(1 << SPKR_SHIFT)/(double)spkr.hw.rate); - spkr.wave.index=0; - spkr.wave.count.max=spkr.wave.new_count.max=0x10000 << SPKR_SHIFT; - spkr.wave.count.half=spkr.wave.new_count.half=(0x10000 << SPKR_SHIFT)/2; - + spkr.mode=SPKR_OFF; + spkr.last_ticks=0; + spkr.last_index=0; + spkr.rate=section->Get_int("pcrate"); + spkr.pit_max=(Bitu)(((double)(1000000 << SPKR_SHIFT)/PIT_TICK_RATE)*65535); + spkr.pit_half=spkr.pit_max/2; + spkr.pit_new_max=spkr.pit_max; + spkr.pit_new_half=spkr.pit_half; + spkr.pit_index=0; + spkr.used=0; /* Register the sound channel */ - spkr.chan=MIXER_AddChannel(&PCSPEAKER_CallBack,spkr.hw.rate,"SPKR"); - MIXER_Enable(spkr.chan,false); - MIXER_SetMode(spkr.chan,MIXER_16MONO); + spkr.chan=MIXER_AddChannel(&PCSPEAKER_CallBack,spkr.rate,"SPKR"); } From 609ed8b02d66d6ee15783e6f4a38ad7384a6955c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 23 Aug 2004 08:32:00 +0000 Subject: [PATCH 1831/4131] Lot's of changes for new mixer routines Added a silent dma player for when speaker is disabled Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1913 --- src/hardware/sblaster.cpp | 467 ++++++++++++++++++-------------------- 1 file changed, 222 insertions(+), 245 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index f23b9eb2..e429c433 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -46,21 +46,23 @@ #define DSP_NO_COMMAND 0 -#define DMA_BUFSIZE 4096 +#define DMA_BUFSIZE 1024 #define DSP_BUFSIZE 64 -#define DSP_DACSIZE 4096 +#define DSP_DACSIZE 512 //Should be enough for sound generated in millisecond blocks #define SB_BUF_SIZE 8096 +#define SB_SH 14 +#define SB_SH_MASK ((1 << SB_SH)-1) enum {DSP_S_RESET,DSP_S_NORMAL,DSP_S_HIGHSPEED}; enum SB_TYPES {SBT_NONE=0,SBT_1=1,SBT_PRO1=2,SBT_2=3,SBT_PRO2=4,SBT_16=6}; enum SB_IRQS {SB_IRQ_8,SB_IRQ_16,SB_IRQ_MPU}; enum DSP_MODES { - MODE_NONE,MODE_DAC, - MODE_SILENCE, - MODE_DMA,MODE_DMA_PAUSE,MODE_DMA_WAIT, + MODE_NONE, + MODE_DAC, + MODE_DMA,MODE_DMA_PAUSE }; enum DMA_MODES { @@ -74,15 +76,12 @@ enum { }; struct SB_INFO { - Bit16u freq; + Bitu freq; struct { - bool stereo,filtered,sign,autoinit; - bool stereoremain; + bool stereo,sign,autoinit; DMA_MODES mode; - Bitu previous; - Bitu total,left; - Bitu rate,rate_mul; - Bitu index,add_index; + Bitu rate,mul; + Bitu total,left,min; Bit64u start; union { Bit8u b8[DMA_BUFSIZE]; @@ -90,10 +89,7 @@ struct SB_INFO { } buf; Bitu bits; DmaChannel * chan; - struct { - Bit16s stereo; - } remain; - + Bitu remain_size; } dma; bool speaker; Bit8u time_constant; @@ -118,7 +114,7 @@ struct SB_INFO { Bitu write_busy; } dsp; struct { - Bit16s data[DSP_DACSIZE]; + Bit16s data[DSP_DACSIZE+1]; Bitu used; Bit16s last; } dac; @@ -126,7 +122,9 @@ struct SB_INFO { Bit8u index; Bit8u dac[2],fm[2],cda[2],master[2],lin[2]; Bit8u mic; + bool stereo; bool enabled; + bool filtered; } mixer; struct { Bit8u reference; @@ -137,26 +135,12 @@ struct SB_INFO { Bitu base; Bit8u irq; Bit8u dma8,dma16; - Bitu rate; - Bitu rate_conv; } hw; - struct { - Bit16s buf[SB_BUF_SIZE][2]; - Bitu pos; - } out; - struct { - union { - Bit16s m[DMA_BUFSIZE]; - Bit16s s[DMA_BUFSIZE][2]; - } buf; - - Bitu index,add_index; - } tmp; struct { Bits value; Bitu count; } e2; - MIXER_Channel * chan; + MixerChannel * chan; }; @@ -202,12 +186,20 @@ static int E2_incr_table[4][9] = { #endif static void DSP_ChangeMode(DSP_MODES mode); -static void CheckDMAEnd(void); -static void END_DMA_Event(void); +static void CheckDMAEnd(); +static void END_DMA_Event(Bitu); +static void DMA_Silent_Event(Bitu val); static void DSP_SetSpeaker(bool how) { - MIXER_Enable(sb.chan,how); + if (sb.speaker==how) return; sb.speaker=how; + sb.chan->Enable(how); + if (sb.speaker) { + PIC_RemoveEvents(DMA_Silent_Event); + CheckDMAEnd(); + } else { + + } } static INLINE void SB_RaiseIRQ(SB_IRQS type) { @@ -223,36 +215,27 @@ static INLINE void SB_RaiseIRQ(SB_IRQS type) { } } - static INLINE void DSP_FlushData(void) { sb.dsp.out.used=0; sb.dsp.out.pos=0; } -static void DSP_StopDMA(void) { - DSP_ChangeMode(MODE_NONE); - sb.dma.left=0; -} - static void DSP_DMA_CallBack(DmaChannel * chan, DMAEvent event) { if (event==DMA_REACHED_TC) return; else if (event==DMA_MASKED) { if (sb.mode==MODE_DMA) { - DSP_ChangeMode(MODE_DMA_WAIT); + DSP_ChangeMode(MODE_NONE); LOG(LOG_SB,LOG_NORMAL)("DMA deactivated,stopping output"); } } else if (event==DMA_UNMASKED) { - if (sb.mode==MODE_DMA_WAIT) { + if (sb.mode!=MODE_DMA && sb.dma.mode!=DSP_DMA_NONE) { DSP_ChangeMode(MODE_DMA); CheckDMAEnd(); - LOG(LOG_SB,LOG_NORMAL)("DMA Activated,starting output, block %X",chan->basecnt); - } else if (event==DMA_TRANSFEREND) { - if (sb.mode==MODE_DMA) sb.mode=MODE_DMA_WAIT; + LOG(LOG_SB,LOG_NORMAL)("DMA Activated,starting output, auto %d block %X",chan->autoinit,chan->basecnt); } } } - #define MIN_ADAPTIVE_STEP_SIZE 511 #define MAX_ADAPTIVE_STEP_SIZE 32767 #define DC_OFFSET_FADE 254 @@ -263,7 +246,7 @@ static INLINE Bits Clip(Bits sample) { return sample; } -static INLINE Bit16s decode_ADPCM_4_sample(Bit8u sample,Bit8u & reference,Bits& scale) { +static INLINE Bit8u decode_ADPCM_4_sample(Bit8u sample,Bit8u & reference,Bits& scale) { static Bits scaleMap[8] = { -2, -1, 0, 0, 1, 1, 1, 1 }; if (sample & 0x08) { @@ -272,10 +255,10 @@ static INLINE Bit16s decode_ADPCM_4_sample(Bit8u sample,Bit8u & reference,Bits& reference = min(0xff, reference + ((sample & 0x07) << scale)); } scale = max(2, min(6, scaleMap[sample & 0x07])); - return (((Bit8s)reference)^0x80)<<8; + return reference; } -static INLINE Bit16s decode_ADPCM_2_sample(Bit8u sample,Bit8u & reference,Bits& scale) { +static INLINE Bit8u decode_ADPCM_2_sample(Bit8u sample,Bit8u & reference,Bits& scale) { static Bits scaleMap[8] = { -2, -1, 0, 0, 1, 1, 1, 1 }; if (sample & 0x02) { @@ -284,10 +267,10 @@ static INLINE Bit16s decode_ADPCM_2_sample(Bit8u sample,Bit8u & reference,Bits& reference = min(0xff, reference + ((sample & 0x01) << (scale+2))); } scale = max(2, min(6, scaleMap[sample & 0x07])); - return (((Bit8s)reference)^0x80)<<8; + return reference; } -INLINE Bit16s decode_ADPCM_3_sample(Bit8u sample,Bit8u & reference,Bits& scale) { +INLINE Bit8u decode_ADPCM_3_sample(Bit8u sample,Bit8u & reference,Bits& scale) { static Bits scaleMap[8] = { -2, -1, 0, 0, 1, 1, 1, 1 }; if (sample & 0x04) { @@ -296,183 +279,148 @@ INLINE Bit16s decode_ADPCM_3_sample(Bit8u sample,Bit8u & reference,Bits& scale) reference = min(0xff, reference + ((sample & 0x03) << (scale+1))); } scale = max(2, min(6, scaleMap[sample & 0x07])); - return (((Bit8s)reference)^0x80)<<8; + return reference; } static void GenerateDMASound(Bitu size) { - /* Check some variables */ - if (!size) return; - if (!sb.dma.rate) return; - /* First check if this transfer is gonna end in the next 2 milliseconds */ - Bitu index=(Bitu)(((float)sb.dma.left*(float)1000000)/(float)sb.dma.rate); -#if (SB_PIC_EVENTS) - if (index-PIC_Index()<1000) PIC_AddEvent(END_DMA_Event,index); -#else - if (index<2000) size=sb.dma.left; -#endif - Bitu read=sb.dma.chan->Read(size,sb.dma.buf.b8); - sb.dma.left-=read; - Bitu skip=0;Bitu i;Bitu rem;Bitu done=0; - if (!read) { - sb.mode=MODE_DMA_WAIT; - return; - } - if (sb.dma.stereoremain) { - sb.dma.stereoremain=false; - sb.tmp.buf.m[done++]=sb.dma.remain.stereo; + Bitu read;Bitu done=0;Bitu i=0; + if (sb.dma.left<=sb.dma.min) { + size=sb.dma.left; } switch (sb.dma.mode) { case DSP_DMA_2: - if (sb.adpcm.haveref) { + read=sb.dma.chan->Read(size,sb.dma.buf.b8); + if (read && sb.adpcm.haveref) { sb.adpcm.haveref=false; sb.adpcm.reference=sb.dma.buf.b8[0]; sb.adpcm.stepsize=MIN_ADAPTIVE_STEP_SIZE; - skip++;read--; + i++; } - for (i=0;i> 6) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[done++]=decode_ADPCM_2_sample((sb.dma.buf.b8[skip+i] >> 4) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[done++]=decode_ADPCM_2_sample((sb.dma.buf.b8[skip+i] >> 2) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[done++]=decode_ADPCM_2_sample((sb.dma.buf.b8[skip+i] >> 0) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize); + for (;i> 6) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize); + MixTemp[done++]=decode_ADPCM_2_sample((sb.dma.buf.b8[i] >> 4) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize); + MixTemp[done++]=decode_ADPCM_2_sample((sb.dma.buf.b8[i] >> 2) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize); + MixTemp[done++]=decode_ADPCM_2_sample((sb.dma.buf.b8[i] >> 0) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize); } + sb.chan->AddSamples_m8(done,MixTemp); break; case DSP_DMA_3: - if (sb.adpcm.haveref) { + read=sb.dma.chan->Read(size,sb.dma.buf.b8); + if (read && sb.adpcm.haveref) { sb.adpcm.haveref=false; sb.adpcm.reference=sb.dma.buf.b8[0]; sb.adpcm.stepsize=MIN_ADAPTIVE_STEP_SIZE; - skip++;read--; + i++; } - rem=read%3;read/=3; - for (i=0;i>3)&7,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[done++]=decode_ADPCM_3_sample(((sb.dma.buf.b8[skip+i*3] >>6)&3)&((sb.dma.buf.b8[i*3+1]&1)<<2),sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[done++]=decode_ADPCM_3_sample( (sb.dma.buf.b8[skip+i*3+1]>>1)&7,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[done++]=decode_ADPCM_3_sample( (sb.dma.buf.b8[skip+i*3+1]>>4)&7,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[done++]=decode_ADPCM_3_sample(((sb.dma.buf.b8[skip+i*3+1]>>7)&1)&((sb.dma.buf.b8[i*3+2]&3)<<1),sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[done++]=decode_ADPCM_3_sample( (sb.dma.buf.b8[skip+i*3+2]>>2)&7,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[done++]=decode_ADPCM_3_sample( (sb.dma.buf.b8[skip+i*3+2]>>5)&7,sb.adpcm.reference,sb.adpcm.stepsize); - } - if (rem) { - sb.tmp.buf.m[done++]=decode_ADPCM_3_sample((sb.dma.buf.b8[skip+read*3])&7,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[done++]=decode_ADPCM_3_sample((sb.dma.buf.b8[skip+read*3]>>3)&7,sb.adpcm.reference,sb.adpcm.stepsize); - if (rem==2) { - sb.tmp.buf.m[done++]=decode_ADPCM_3_sample(((sb.dma.buf.b8[skip+read*3+1]>>6)&3)&(sb.dma.buf.b8[read*3/8]&1), sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[done++]=decode_ADPCM_3_sample((sb.dma.buf.b8[skip+read*3+1]>>1)&7,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[done++]=decode_ADPCM_3_sample((sb.dma.buf.b8[skip+read*3+1]>>4)&7,sb.adpcm.reference,sb.adpcm.stepsize); - } + for (;i> 5) & 0x7,sb.adpcm.reference,sb.adpcm.stepsize); + MixTemp[done++]=decode_ADPCM_3_sample((sb.dma.buf.b8[i] >> 2) & 0x7,sb.adpcm.reference,sb.adpcm.stepsize); + MixTemp[done++]=decode_ADPCM_2_sample((sb.dma.buf.b8[i] >> 0) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize); } + sb.chan->AddSamples_m8(done,MixTemp); break; case DSP_DMA_4: - if (sb.adpcm.haveref) { + read=sb.dma.chan->Read(size,sb.dma.buf.b8); + if (read && sb.adpcm.haveref) { sb.adpcm.haveref=false; sb.adpcm.reference=sb.dma.buf.b8[0]; sb.adpcm.stepsize=MIN_ADAPTIVE_STEP_SIZE; - skip++;read--; + i++; } - for (i=0;i> 4,sb.adpcm.reference,sb.adpcm.stepsize); - sb.tmp.buf.m[done++]=decode_ADPCM_4_sample(sb.dma.buf.b8[skip+i]& 0xf,sb.adpcm.reference,sb.adpcm.stepsize); + for (;i> 4,sb.adpcm.reference,sb.adpcm.stepsize); + MixTemp[done++]=decode_ADPCM_4_sample(sb.dma.buf.b8[i]& 0xf,sb.adpcm.reference,sb.adpcm.stepsize); } - read*=2; + sb.chan->AddSamples_m8(done,MixTemp); break; case DSP_DMA_8: - for (i=0;iRead(size,&sb.dma.buf.b8[sb.dma.remain_size]); + read+=sb.dma.remain_size; + sb.chan->AddSamples_s8(read>>1,sb.dma.buf.b8); + if (read&1) { + sb.dma.remain_size=1; + sb.dma.buf.b8[0]=sb.dma.buf.b8[read-1]; + } else sb.dma.remain_size=0; + } else { + read=sb.dma.chan->Read(size,sb.dma.buf.b8); + sb.chan->AddSamples_m8(read,sb.dma.buf.b8); + } break; case DSP_DMA_16: - for (i=0;iRead(size,(Bit8u *)&sb.dma.buf.b16[sb.dma.remain_size]); + read+=sb.dma.remain_size; + sb.chan->AddSamples_s16(read>>1,sb.dma.buf.b16); + if (read&1) { + sb.dma.remain_size=1; + sb.dma.buf.b16[0]=sb.dma.buf.b16[read-1]; + } else sb.dma.remain_size=0; + } else { + read=sb.dma.chan->Read(size,sb.dma.buf.b8); + sb.chan->AddSamples_m16(read,sb.dma.buf.b16); + } break; case DSP_DMA_16_ALIASED: - for (i=0;iAddSamples_s16(read>>2,sb.dma.buf.b16); + } else { + sb.chan->AddSamples_m16(read>>1,sb.dma.buf.b16); + } break; default: LOG_MSG("Unhandled dma mode %d",sb.dma.mode); sb.mode=MODE_NONE; return; } + sb.dma.left-=read; if (!sb.dma.left) { - if (!sb.dma.autoinit) sb.mode=MODE_NONE; + PIC_RemoveEvents(END_DMA_Event); + if (!sb.dma.autoinit) { + sb.mode=MODE_NONE; + sb.dma.mode=DSP_DMA_NONE; + } else sb.dma.left=sb.dma.total; if (sb.dma.mode >= DSP_DMA_16) SB_RaiseIRQ(SB_IRQ_16); else SB_RaiseIRQ(SB_IRQ_8); } - Bit16s * stream=&sb.out.buf[sb.out.pos][0]; - if (!sb.dma.stereo) { - Bitu pos; - while (done>(pos=sb.tmp.index>>16)) { - (*stream++)=sb.tmp.buf.m[pos]; - (*stream++)=sb.tmp.buf.m[pos]; - sb.tmp.index+=sb.tmp.add_index; - sb.out.pos++; - } - sb.tmp.index&=0xffff; - } else { - if (done&1){ - sb.dma.remain.stereo=sb.tmp.buf.m[done-1]; - sb.dma.stereoremain=true; - } - Bitu pos;done>>=1;Bitu index_add=sb.tmp.add_index >> 1; - while (done>(pos=sb.tmp.index>>16)) { - (*stream++)=sb.tmp.buf.s[pos][0]; - (*stream++)=sb.tmp.buf.s[pos][1]; - sb.tmp.index+=index_add; - sb.out.pos++; - } - sb.tmp.index&=0xffff; - } } -static void GenerateSound(Bitu size) { - while (sb.out.pos>16)]; + dac_pos+=dac_add; + } + sb.dac.used=0; + sb.chan->AddSamples_m16(len,(Bit16s *)MixTemp); +} - Bit16s * stream=&sb.out.buf[sb.out.pos][0]; - if (sb.dac.used) { - Bitu dac_add=(sb.dac.used<<16)/samples; - Bitu dac_pos=0; - Bitu len=samples; - while (len-->0) { - *(stream++)=sb.dac.data[dac_pos>>16]; - *(stream++)=sb.dac.data[dac_pos>>16]; - dac_pos+=dac_add; - } - dac_pos-=dac_add; - sb.dac.last=sb.dac.data[dac_pos>>16]; - sb.dac.used=0; - } else { - memset(stream,sb.dac.last,samples); - sb.mode=MODE_NONE; - } - sb.out.pos+=samples; - break; - } - case MODE_DMA: - { - Bitu len=samples*sb.dma.rate_mul; - if (len & 0xffff) len=1+(len>>16); - else len>>=16; - if (sb.dma.stereo && (len & 1)) len++; - GenerateDMASound(len); - break; - } - +static void DMA_Silent_Event(Bitu val) { + if (sb.dma.leftRead(val,sb.dma.buf.b8); + sb.dma.left-=read; + if (!sb.dma.left) { + if (sb.dma.mode >= DSP_DMA_16) SB_RaiseIRQ(SB_IRQ_16); + else SB_RaiseIRQ(SB_IRQ_8); + if (sb.dma.autoinit) sb.dma.left=sb.dma.total; + else { + sb.mode=MODE_NONE; + sb.dma.mode=DSP_DMA_NONE; } } - if (sb.out.pos>SB_BUF_SIZE) { - LOG(LOG_SB,LOG_ERROR)("Generation Buffer Full!!!!"); - sb.out.pos=0; + if (sb.dma.left) { + Bitu bigger=(sb.dma.left > sb.dma.min) ? sb.dma.min : sb.dma.left; + Bitu index=(bigger*1000000)/sb.dma.rate; + PIC_AddEvent(DMA_Silent_Event,index,bigger); } + } static void END_DMA_Event(Bitu val) { @@ -480,24 +428,22 @@ static void END_DMA_Event(Bitu val) { } static void CheckDMAEnd(void) { - if (!sb.dma.rate) return; - Bitu index=(Bitu)(((float)sb.dma.left*(float)1000000)/(float)sb.dma.rate); - if (index<(1000-PIC_Index())) { -#if 1 + if (!sb.dma.left) return; + if (!sb.speaker) { + Bitu bigger=(sb.dma.left > sb.dma.min) ? sb.dma.min : sb.dma.left; + Bitu index=(bigger*1000000)/sb.dma.rate; + PIC_AddEvent(DMA_Silent_Event,index,bigger); + LOG(LOG_SB,LOG_NORMAL)("Silent DMA Transfer scheduling IRQ in %d microseconds",index); + } else if (sb.dma.left>16); + if (sb.mode==mode) return; + else sb.chan->FillUp(); sb.mode=mode; } @@ -505,36 +451,56 @@ static void DSP_RaiseIRQEvent(Bitu val) { SB_RaiseIRQ(SB_IRQ_8); } -static void DSP_DoDMATranfser(DMA_MODES mode) { +static void DSP_DoDMATranfser(DMA_MODES mode,Bitu freq,bool stereo) { char * type; - DSP_ChangeMode(MODE_NONE); + sb.chan->FillUp(); sb.dma.left=sb.dma.total; sb.dma.mode=mode; - sb.tmp.index=0; - sb.dma.rate_mul=(sb.dma.rate<<16)/sb.hw.rate; - sb.tmp.add_index=(sb.dma.rate<<16)/sb.hw.rate; + sb.dma.stereo=stereo; sb.irq.pending_8bit=false; sb.irq.pending_16bit=false; switch (mode) { - case DSP_DMA_2:type="2-bits ADPCM";break; - case DSP_DMA_3:type="3-bits ADPCM";break; - case DSP_DMA_4:type="4-bits ADPCM";break; - case DSP_DMA_8:type="8-bits PCM";break; - case DSP_DMA_16_ALIASED:type="16-bits(aliased) PCM";break; - case DSP_DMA_16:type="16-bits PCM";break; + case DSP_DMA_2: + type="2-bits ADPCM"; + sb.dma.mul=(1 << SB_SH)/4; + break; + case DSP_DMA_3: + type="3-bits ADPCM"; + sb.dma.mul=(1 << SB_SH)/3; + break; + case DSP_DMA_4: + type="4-bits ADPCM"; + sb.dma.mul=(1 << SB_SH)/2; + break; + case DSP_DMA_8: + type="8-bits PCM"; + sb.dma.mul=(1 << SB_SH); + break; + case DSP_DMA_16_ALIASED: + type="16-bits(aliased) PCM"; + sb.dma.mul=(1 << SB_SH)*2; + break; + case DSP_DMA_16: + type="16-bits PCM"; + sb.dma.mul=(1 << SB_SH); + break; default: LOG(LOG_SB,LOG_ERROR)("DSP:Illegal transfer mode %d",mode); return; } - DSP_ChangeMode(MODE_DMA_WAIT); + if (sb.dma.stereo) sb.dma.mul*=2; + sb.dma.rate=(sb.freq*sb.dma.mul) >> SB_SH; + sb.dma.min=(sb.dma.rate*3)/1000; + sb.chan->SetFreq(freq); sb.dma.mode=mode; + PIC_RemoveEvents(END_DMA_Event); sb.dma.chan->Register_Callback(DSP_DMA_CallBack); #if (C_DEBUG) - LOG(LOG_SB,LOG_NORMAL)("DMA Transfer:%s %s %s dma-rate %d size %d", + LOG(LOG_SB,LOG_NORMAL)("DMA Transfer:%s %s %s freq %d rate %d size %d", type, sb.dma.stereo ? "Stereo" : "Mono", sb.dma.autoinit ? "Auto-Init" : "Single-Cycle", - sb.dma.rate,sb.dma.total + freq,sb.dma.rate,sb.dma.total ); #endif } @@ -542,24 +508,23 @@ static void DSP_DoDMATranfser(DMA_MODES mode) { static void DSP_PrepareDMA_Old(DMA_MODES mode,bool autoinit) { sb.dma.autoinit=autoinit; if (!autoinit) sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); - sb.dma.rate=sb.freq; sb.dma.chan=DmaChannels[sb.hw.dma8]; - DSP_DoDMATranfser(mode); + DSP_DoDMATranfser(mode,sb.freq / (sb.mixer.stereo ? 2 : 1),sb.mixer.stereo); } -static void DSP_PrepareDMA_New(DMA_MODES mode,bool autoinit,Bitu length) { +static void DSP_PrepareDMA_New(DMA_MODES mode,Bitu length,bool autoinit,bool stereo) { + Bitu freq=sb.freq; sb.dma.total=length; - sb.dma.rate=sb.freq * (sb.dma.stereo ? 2 : 1); - sb.dma.rate_mul=(sb.dma.rate<<16)/sb.hw.rate; sb.dma.autoinit=autoinit; if (mode==DSP_DMA_16) { if (sb.hw.dma16!=0xff) sb.dma.chan=DmaChannels[sb.hw.dma16]; else { sb.dma.chan=DmaChannels[sb.hw.dma8]; mode=DSP_DMA_16_ALIASED; + freq/=2; } } else sb.dma.chan=DmaChannels[sb.hw.dma8]; - DSP_DoDMATranfser(mode); + DSP_DoDMATranfser(mode,freq,stereo); } @@ -586,6 +551,8 @@ static void DSP_Reset(void) { sb.dma.total=0; sb.dma.stereo=false; sb.dma.autoinit=false; + sb.dma.mode=DSP_DMA_NONE; + sb.dma.remain_size=0; sb.freq=22050; sb.time_constant=45; sb.dac.used=0; @@ -594,7 +561,9 @@ static void DSP_Reset(void) { sb.e2.count=0; sb.irq.pending_8bit=false; sb.irq.pending_16bit=false; + sb.chan->SetFreq(22050); DSP_SetSpeaker(false); + PIC_RemoveEvents(END_DMA_Event); } @@ -641,6 +610,7 @@ static void DSP_DoCommand(void) { DSP_ChangeMode(MODE_DAC); if (sb.dac.used 0; sb.dma.sign=(sb.dsp.in.data[0] & 0x10) > 0; DSP_PrepareDMA_New((sb.dsp.cmd & 0x10) ? DSP_DMA_16 : DSP_DMA_8, + 1+sb.dsp.in.data[1]+(sb.dsp.in.data[2] << 8), (sb.dsp.cmd & 0x4)>0, - 1+sb.dsp.in.data[1]+(sb.dsp.in.data[2] << 8) + (sb.dsp.in.data[0] & 0x20) > 0 ); break; case 0xd0: /* Halt 8-bit DMA */ case 0xd5: /* Halt 16-bit DMA */ - if (sb.dma.left) { - DSP_ChangeMode(MODE_DMA_PAUSE); -#if SB_PIC_EVENTS - PIC_RemoveEvents(END_DMA_Event); -#endif - } else DSP_ChangeMode(MODE_NONE); +// DSP_ChangeMode(MODE_NONE); +// Games sometimes already program a new dma before stopping, gives noise + sb.mode=MODE_DMA; + PIC_RemoveEvents(END_DMA_Event); break; case 0xd1: /* Enable Speaker */ DSP_SetSpeaker(true); @@ -712,7 +680,6 @@ static void DSP_DoCommand(void) { DSP_SetSpeaker(false); break; case 0xd4: /* Continue DMA */ - DSP_ChangeMode(MODE_DMA_WAIT); sb.dma.chan->Register_Callback(DSP_DMA_CallBack); break; case 0xda: /* Exit Autoinitialize 8-bit */ @@ -805,8 +772,11 @@ static Bit8u DSP_ReadData(void) { #define CALCVOL(_VAL) (float)pow(10.0f,((float)(31-_VAL)*-1.3f)/20) static void CTMIXER_UpdateVolumes(void) { if (!sb.mixer.enabled) return; - MIXER_SetVolume(MIXER_FindChannel("SB"),CALCVOL(sb.mixer.dac[0]),CALCVOL(sb.mixer.dac[1])); - MIXER_SetVolume(MIXER_FindChannel("FM"),CALCVOL(sb.mixer.fm[0]),CALCVOL(sb.mixer.fm[1])); + MixerChannel * chan; + chan=MIXER_FindChannel("SB"); + if (chan) chan->SetVolume(CALCVOL(sb.mixer.dac[0]),CALCVOL(sb.mixer.dac[1])); + chan=MIXER_FindChannel("FM"); + if (chan) chan->SetVolume(CALCVOL(sb.mixer.fm[0]),CALCVOL(sb.mixer.fm[1])); } static void CTMIXER_Reset(void) { @@ -822,7 +792,6 @@ static void CTMIXER_Reset(void) { _WHICH_[1]= 0x1 | ((_VAL_ & 0x0f) << 1); static void CTMIXER_Write(Bit8u val) { - LOG_MSG("Write mixer %x %x",sb.mixer.index,val); switch (sb.mixer.index) { case 0x02: /* Master Voulme (SBPRO) Obsolete? */ case 0x22: /* Master Volume (SBPRO) */ @@ -842,8 +811,8 @@ static void CTMIXER_Write(Bit8u val) { sb.mixer.mic=(val & 0xf) << 1; break; case 0x0e: /* Output/Stereo Select */ - sb.dma.stereo=(val & 0x2) > 0; - sb.dma.filtered=(val & 0x20) > 0; + sb.mixer.stereo=(val & 0x2) > 0; + sb.mixer.filtered=(val & 0x20) > 0; LOG(LOG_SB,LOG_WARN)("Mixer set to %s",sb.dma.stereo ? "STEREO" : "MONO"); break; case 0x26: /* FM Volume (SBPRO) */ @@ -884,7 +853,7 @@ static void CTMIXER_Write(Bit8u val) { static Bit8u CTMIXER_Read(void) { Bit8u ret; - if ( sb.mixer.index< 0x80) LOG_MSG("Read mixer %x",sb.mixer.index); +// if ( sb.mixer.index< 0x80) LOG_MSG("Read mixer %x",sb.mixer.index); switch (sb.mixer.index) { case 0x00: /* RESET */ return 0x00; @@ -897,7 +866,7 @@ static Bit8u CTMIXER_Read(void) { case 0x0a: /* Mic Level (SBPRO) */ return (sb.mixer.mic >> 1); case 0x0e: /* Output/Stereo Select */ - return 0x11|(sb.dma.stereo ? 0x02 : 0x00)|(sb.dma.filtered ? 0x20 : 0x00); + return 0x11|(sb.mixer.stereo ? 0x02 : 0x00)|(sb.mixer.filtered ? 0x20 : 0x00); case 0x26: /* FM Volume (SBPRO) */ return MAKEPROVOL(sb.mixer.fm); case 0x28: /* CD Audio Volume (SBPRO) */ @@ -994,20 +963,32 @@ static void adlib_gusforward(Bitu port,Bitu val,Bitu iolen) { adlib_commandreg=val; } -static void SBLASTER_CallBack(Bit8u * stream,Bit32u len) { - if (!len) return; - GenerateSound(len); - memcpy(stream,sb.out.buf,len*4); - if (sb.out.pos>=len) { - memcpy(sb.out.buf,&sb.out.buf[len],(sb.out.pos-len)*4); - sb.out.pos-=len; +static void SBLASTER_CallBack(Bitu len) { + switch (sb.mode) { + case MODE_NONE: + case MODE_DMA_PAUSE: + sb.chan->AddSilence(); + break; + case MODE_DAC: +// GenerateDACSound(len); +// break; + if (!sb.dac.used) { + sb.mode=MODE_NONE; + return; + } + sb.chan->AddStretched(sb.dac.used,sb.dac.data); + sb.dac.used=0; + break; + case MODE_DMA: + len*=sb.dma.mul; + if (len&SB_SH_MASK) len+=1 << SB_SH; + len>>=SB_SH; + if (len>sb.dma.left) len=sb.dma.left; + GenerateDMASound(len); + break; } - else sb.out.pos=0; - if (sb.mode==MODE_NONE) DSP_SetSpeaker(false); - return; } - void SBLASTER_Init(Section* sec) { Bitu i; Section_prop * section=static_cast(sec); @@ -1017,8 +998,7 @@ void SBLASTER_Init(Section* sec) { sb.hw.dma8=section->Get_int("dma"); sb.hw.dma16=section->Get_int("hdma"); sb.mixer.enabled=section->Get_bool("mixer"); - sb.hw.rate=section->Get_int("sbrate"); - sb.hw.rate_conv=(sb.hw.rate<<16)/1000000; + sb.mixer.stereo=false; if (!strcasecmp(sbtype,"sb1")) sb.type=SBT_1; else if (!strcasecmp(sbtype,"sb2")) sb.type=SBT_2; else if (!strcasecmp(sbtype,"sbpro1")) sb.type=SBT_PRO1; @@ -1067,10 +1047,7 @@ void SBLASTER_Init(Section* sec) { } if (sb.type==SBT_NONE) return; sb.chan=MIXER_AddChannel(&SBLASTER_CallBack,22050,"SB"); - MIXER_Enable(sb.chan,false); sb.dsp.state=DSP_S_NORMAL; - MIXER_SetFreq(sb.chan,sb.hw.rate); - MIXER_SetMode(sb.chan,MIXER_16STEREO); for (i=4;i<=0xf;i++) { if (i==8 || i==9) continue; From dbde36bfe1fbefca9e0876675b7a4ff832a26906 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 23 Aug 2004 09:18:58 +0000 Subject: [PATCH 1832/4131] Keep GCC happy! Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1914 --- src/hardware/mixer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index ec6af869..360507d2 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -166,10 +166,10 @@ INLINE void MixerChannel::AddSamples(Bitu len,void * data) { Bit16s * data16=(Bit16s*)data; Bitu mixpos=mixer.pos+done; freq_index&=MIXER_REMAIN; - Bitu pos=0; + Bitu pos=0;Bitu new_pos; goto thestart; while (1) { - Bitu new_pos=freq_index >> MIXER_SHIFT; + new_pos=freq_index >> MIXER_SHIFT; if (pos Date: Mon, 23 Aug 2004 09:22:23 +0000 Subject: [PATCH 1833/4131] Use new mixer code for cd image audio Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1915 --- src/dos/cdrom.h | 4 ++-- src/dos/cdrom_image.cpp | 14 ++++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index bd81474d..c4382092 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -170,12 +170,12 @@ static CDROM_Interface_Image* images[26]; private: // player -static void CDAudioCallBack(Bit8u *stream, Bit32u len); +static void CDAudioCallBack(Bitu len); int GetTrack(int sector); static struct imagePlayer { CDROM_Interface_Image *cd; - MIXER_Channel *channel; + MixerChannel *channel; SDL_mutex *mutex; Bit8u buffer[8192]; int bufLen; diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index ce2a6f0a..a68ede99 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.1 2004-08-13 19:43:02 qbix79 Exp $ */ +/* $Id: cdrom_image.cpp,v 1.2 2004-08-23 09:22:23 harekiet Exp $ */ #include #include @@ -139,9 +139,8 @@ CDROM_Interface_Image::CDROM_Interface_Image(Bit8u subUnit) player.mutex = SDL_CreateMutex(); if (!player.channel) { player.channel = MIXER_AddChannel(&CDAudioCallBack, 44100, "CDAUDIO"); - MIXER_SetMode(player.channel, MIXER_16STEREO); } - MIXER_Enable(player.channel, true); + player.channel->Enable(true); } refCount++; } @@ -156,7 +155,7 @@ CDROM_Interface_Image::~CDROM_Interface_Image() Sound_Quit(); #endif SDL_DestroyMutex(player.mutex); - MIXER_Enable(player.channel, false); + player.channel->Enable(false); } } @@ -302,12 +301,12 @@ bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long se return tracks[track].file->read(buffer, seek, length); } -void CDROM_Interface_Image::CDAudioCallBack(Bit8u *stream, Bit32u len) +void CDROM_Interface_Image::CDAudioCallBack(Bitu len) { len *= 4; // 16 bit, stereo if (!len) return; if (!player.isPlaying || player.isPaused) { - memset(stream, 0, len); + player.channel->AddSilence(); return; } @@ -328,8 +327,7 @@ void CDROM_Interface_Image::CDAudioCallBack(Bit8u *stream, Bit32u len) } } SDL_mutexV(player.mutex); - - memcpy(stream, player.buffer, len); + player.channel->AddSamples_s16(len/4,(Bit16s *)player.buffer); memmove(player.buffer, &player.buffer[len], player.bufLen - len); player.bufLen -= len; } From dae79d087916c304f0140fe2d3658a8330f59cbc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 23 Aug 2004 09:34:21 +0000 Subject: [PATCH 1834/4131] added snprintf define for visual c++ Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1916 --- include/cross.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/cross.h b/include/cross.h index d92930e2..f4c106b0 100644 --- a/include/cross.h +++ b/include/cross.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.h,v 1.8 2004-08-04 09:12:50 qbix79 Exp $ */ +/* $Id: cross.h,v 1.9 2004-08-23 09:34:21 harekiet Exp $ */ #ifndef _CROSS_H #define _CROSS_H @@ -29,6 +29,7 @@ #include #include #define LONGTYPE(a) a##i64 +#define snprintf _snprintf #else /* LINUX / GCC */ #include #include From f7f7f9f4c84fe97b4cf1fa9e5804720d0847e7b2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 23 Aug 2004 09:35:15 +0000 Subject: [PATCH 1835/4131] Fix preprocessor directive Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1917 --- src/dos/cdrom_image.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index a68ede99..ad6686e2 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.2 2004-08-23 09:22:23 harekiet Exp $ */ +/* $Id: cdrom_image.cpp,v 1.3 2004-08-23 09:35:15 harekiet Exp $ */ #include #include @@ -30,7 +30,7 @@ #include "cdrom.h" #include "drives.h" -#if not defined(WIN32) +#if !defined(WIN32) #include #endif From dc0be652246f5d73def927c5249a64f7f65abe9f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 23 Aug 2004 10:06:09 +0000 Subject: [PATCH 1836/4131] Improve timing between sequential dma transfers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1918 --- src/hardware/sblaster.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index e429c433..fca0ee63 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -224,14 +224,15 @@ static void DSP_DMA_CallBack(DmaChannel * chan, DMAEvent event) { if (event==DMA_REACHED_TC) return; else if (event==DMA_MASKED) { if (sb.mode==MODE_DMA) { - DSP_ChangeMode(MODE_NONE); - LOG(LOG_SB,LOG_NORMAL)("DMA deactivated,stopping output"); + sb.mode=MODE_DMA_PAUSE; +// DSP_ChangeMode(MODE_DMA_PAUSE); + LOG(LOG_SB,LOG_NORMAL)("DMA masked,stopping output"); } } else if (event==DMA_UNMASKED) { - if (sb.mode!=MODE_DMA && sb.dma.mode!=DSP_DMA_NONE) { + if (sb.mode==MODE_DMA_PAUSE && sb.dma.mode!=DSP_DMA_NONE) { DSP_ChangeMode(MODE_DMA); CheckDMAEnd(); - LOG(LOG_SB,LOG_NORMAL)("DMA Activated,starting output, auto %d block %X",chan->autoinit,chan->basecnt); + LOG(LOG_SB,LOG_NORMAL)("DMA unmasked,starting output, auto %d block %X",chan->autoinit,chan->basecnt); } } } @@ -453,6 +454,7 @@ static void DSP_RaiseIRQEvent(Bitu val) { static void DSP_DoDMATranfser(DMA_MODES mode,Bitu freq,bool stereo) { char * type; + sb.mode=MODE_DMA_PAUSE; sb.chan->FillUp(); sb.dma.left=sb.dma.total; sb.dma.mode=mode; @@ -670,7 +672,7 @@ static void DSP_DoCommand(void) { case 0xd5: /* Halt 16-bit DMA */ // DSP_ChangeMode(MODE_NONE); // Games sometimes already program a new dma before stopping, gives noise - sb.mode=MODE_DMA; + sb.mode=MODE_DMA_PAUSE; PIC_RemoveEvents(END_DMA_Event); break; case 0xd1: /* Enable Speaker */ From fc8d4d89c26eceffeebfb4fccc0e10ed40aebd51 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 23 Aug 2004 12:17:30 +0000 Subject: [PATCH 1837/4131] Add new cpu core simple Changes for new memory handling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1919 --- src/cpu/core_normal.cpp | 104 ++++----- src/cpu/core_normal/helpers.h | 19 ++ src/cpu/core_normal/prefix_66.h | 6 +- src/cpu/core_normal/prefix_none.h | 20 +- src/cpu/core_normal/string.h | 5 +- src/cpu/core_normal/support.h | 54 ++--- src/cpu/core_normal/table_ea.h | 359 ++++++++---------------------- src/cpu/core_simple.cpp | 203 +++++++++++++++++ src/cpu/cpu.cpp | 6 +- src/cpu/paging.cpp | 37 +-- 10 files changed, 420 insertions(+), 393 deletions(-) create mode 100644 src/cpu/core_simple.cpp diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 663c6d9f..9aa0db94 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -31,43 +31,23 @@ #include "debug.h" #endif - -#define SegBase(c) SegPhys(c) #if (!C_CORE_INLINE) - #define LoadMb(off) mem_readb(off) #define LoadMw(off) mem_readw(off) #define LoadMd(off) mem_readd(off) - #define SaveMb(off,val) mem_writeb(off,val) #define SaveMw(off,val) mem_writew(off,val) #define SaveMd(off,val) mem_writed(off,val) - #else - #include "paging.h" #define LoadMb(off) mem_readb_inline(off) #define LoadMw(off) mem_readw_inline(off) #define LoadMd(off) mem_readd_inline(off) - #define SaveMb(off,val) mem_writeb_inline(off,val) #define SaveMw(off,val) mem_writew_inline(off,val) #define SaveMd(off,val) mem_writed_inline(off,val) - #endif -#define LoadMbs(off) (Bit8s)(LoadMb(off)) -#define LoadMws(off) (Bit16s)(LoadMw(off)) -#define LoadMds(off) (Bit32s)(LoadMd(off)) - -#define LoadRb(reg) reg -#define LoadRw(reg) reg -#define LoadRd(reg) reg - -#define SaveRb(reg,val) reg=val -#define SaveRw(reg,val) reg=val -#define SaveRd(reg,val) reg=val - extern Bitu cycle_count; #if C_FPU @@ -82,81 +62,88 @@ extern Bitu cycle_count; #define OPCODE_SIZE 0x200 #define PREFIX_ADDR 0x1 -#define PREFIX_SEG 0x2 -#define PREFIX_SEG_ADDR (PREFIX_ADDR|PREFIX_SEG) -#define PREFIX_REP 0x4 +#define PREFIX_REP 0x2 -#define TEST_PREFIX_SEG (core.prefixes & PREFIX_SEG) #define TEST_PREFIX_ADDR (core.prefixes & PREFIX_ADDR) #define TEST_PREFIX_REP (core.prefixes & PREFIX_REP) #define DO_PREFIX_SEG(_SEG) \ - core.prefixes|=PREFIX_SEG; \ - core.seg_prefix_base=SegBase(_SEG); \ - goto restart_prefix; + BaseDS=SegBase(_SEG); \ + BaseSS=SegBase(_SEG); \ + goto restart_opcode; #define DO_PREFIX_ADDR() \ core.prefixes=(core.prefixes & ~PREFIX_ADDR) | \ (cpu.code.big ^ PREFIX_ADDR); \ - goto restart_prefix; + core.ea_table=&EATable[(core.prefixes&1) * 256]; \ + goto restart_opcode; #define DO_PREFIX_REP(_ZERO) \ core.prefixes|=PREFIX_REP; \ core.rep_zero=_ZERO; \ - goto restart_prefix; + goto restart_opcode; -typedef PhysPt (*GetEATable[256])(void); +typedef PhysPt (*GetEAHandler)(void); static const Bit32u AddrMaskTable[2]={0x0000ffff,0xffffffff}; static struct { Bitu opcode_index; PhysPt cseip; - PhysPt seg_prefix_base; + PhysPt base_ds,base_ss; bool rep_zero; Bitu prefixes; - GetEATable * ea_table; + GetEAHandler * ea_table; struct { bool skip; } trap; } core; +#define GETIP (core.cseip-SegBase(cs)) +#define SAVEIP reg_eip=GETIP; +#define LOADIP core.cseip=(SegBase(cs)+reg_eip); + +#define SegBase(c) SegPhys(c) +#define BaseDS core.base_ds +#define BaseSS core.base_ss + +static INLINE Bit8u Fetchb() { + Bit8u temp=LoadMb(core.cseip); + core.cseip+=1; + return temp; +} + +static INLINE Bit16u Fetchw() { + Bit16u temp=LoadMw(core.cseip); + core.cseip+=2; + return temp; +} +static INLINE Bit32u Fetchd() { + Bit32u temp=LoadMd(core.cseip); + core.cseip+=4; + return temp; +} + +#define Push_16 CPU_Push16 +#define Push_32 CPU_Push32 +#define Pop_16 CPU_Pop16 +#define Pop_32 CPU_Pop32 + #include "instructions.h" #include "core_normal/support.h" #include "core_normal/string.h" -static GetEATable * EAPrefixTable[8] = { - &GetEA_NONE,&GetEA_ADDR,&GetEA_SEG,&GetEA_SEG_ADDR, - &GetEA_NONE,&GetEA_ADDR,&GetEA_SEG,&GetEA_SEG_ADDR, -}; -#define CASE_W(_WHICH) \ - case (OPCODE_NONE+_WHICH): - -#define CASE_D(_WHICH) \ - case (OPCODE_SIZE+_WHICH): - -#define CASE_B(_WHICH) \ - CASE_W(_WHICH) \ - CASE_D(_WHICH) - -#define CASE_0F_W(_WHICH) \ - case ((OPCODE_0F|OPCODE_NONE)+_WHICH): - -#define CASE_0F_D(_WHICH) \ - case ((OPCODE_0F|OPCODE_SIZE)+_WHICH): - -#define CASE_0F_B(_WHICH) \ - CASE_0F_W(_WHICH) \ - CASE_0F_D(_WHICH) - -#define EALookupTable (*(core.ea_table)) +#define EALookupTable (core.ea_table) Bits CPU_Core_Normal_Run(void) { while (CPU_Cycles-->0) { LOADIP; core.opcode_index=cpu.code.big*0x200; core.prefixes=cpu.code.big; + core.ea_table=&EATable[cpu.code.big*256]; + BaseDS=SegBase(ds); + BaseSS=SegBase(ss); #if C_DEBUG #if C_HEAVY_DEBUG if (DEBUG_HeavyIsBreakpoint()) { @@ -166,11 +153,8 @@ Bits CPU_Core_Normal_Run(void) { #endif cycle_count++; #endif -restart_prefix: - core.ea_table=EAPrefixTable[core.prefixes]; restart_opcode: switch (core.opcode_index+Fetchb()) { - #include "core_normal/prefix_none.h" #include "core_normal/prefix_0f.h" #include "core_normal/prefix_66.h" diff --git a/src/cpu/core_normal/helpers.h b/src/cpu/core_normal/helpers.h index 556645a6..9f18fb24 100644 --- a/src/cpu/core_normal/helpers.h +++ b/src/cpu/core_normal/helpers.h @@ -141,3 +141,22 @@ } \ } +#define CASE_W(_WHICH) \ + case (OPCODE_NONE+_WHICH): + +#define CASE_D(_WHICH) \ + case (OPCODE_SIZE+_WHICH): + +#define CASE_B(_WHICH) \ + CASE_W(_WHICH) \ + CASE_D(_WHICH) + +#define CASE_0F_W(_WHICH) \ + case ((OPCODE_0F|OPCODE_NONE)+_WHICH): + +#define CASE_0F_D(_WHICH) \ + case ((OPCODE_0F|OPCODE_SIZE)+_WHICH): + +#define CASE_0F_B(_WHICH) \ + CASE_0F_W(_WHICH) \ + CASE_0F_D(_WHICH) diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index fb698a81..07c55b57 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -341,12 +341,12 @@ CASE_D(0x8d) /* LEA Gd */ { //Little hack to always use segprefixed version - core.seg_prefix_base=0; GetRMrd; + BaseDS=BaseSS=0; if (TEST_PREFIX_ADDR) { - *rmrd=(Bit32u)(*GetEA_SEG_ADDR[rm])(); + *rmrd=(Bit32u)(*EATable[256+rm])(); } else { - *rmrd=(Bit32u)(*GetEA_SEG[rm])(); + *rmrd=(Bit32u)(*EATable[rm])(); } break; } diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index e8abf78f..0cc2c35b 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -482,12 +482,12 @@ CASE_W(0x8d) /* LEA Gw */ { //Little hack to always use segprefixed version - core.seg_prefix_base=0; + BaseDS=BaseSS=0; GetRMrw; if (TEST_PREFIX_ADDR) { - *rmrw=(Bit16u)(*GetEA_SEG_ADDR[rm])(); + *rmrw=(Bit16u)(*EATable[256+rm])(); } else { - *rmrw=(Bit16u)(*GetEA_SEG[rm])(); + *rmrw=(Bit16u)(*EATable[rm])(); } break; } @@ -788,18 +788,10 @@ reg_al = get_CF() ? 0xFF : 0; break; CASE_B(0xd7) /* XLAT */ - if (TEST_PREFIX_SEG) { - if (TEST_PREFIX_ADDR) { - reg_al=LoadMb(core.seg_prefix_base+(Bit32u)(reg_ebx+reg_al)); - } else { - reg_al=LoadMb(core.seg_prefix_base+(Bit16u)(reg_bx+reg_al)); - } + if (TEST_PREFIX_ADDR) { + reg_al=LoadMb(BaseDS+(Bit32u)(reg_ebx+reg_al)); } else { - if (TEST_PREFIX_ADDR) { - reg_al=LoadMb(SegBase(ds)+(Bit32u)(reg_ebx+reg_al)); - } else { - reg_al=LoadMb(SegBase(ds)+(Bit16u)(reg_bx+reg_al)); - } + reg_al=LoadMb(BaseDS+(Bit16u)(reg_bx+reg_al)); } break; #ifdef CPU_FPU diff --git a/src/cpu/core_normal/string.h b/src/cpu/core_normal/string.h index 45a61474..33ce3d58 100644 --- a/src/cpu/core_normal/string.h +++ b/src/cpu/core_normal/string.h @@ -17,10 +17,9 @@ static void DoString(STRING_OP type) { Bitu count,count_left; Bits add_index; - if (TEST_PREFIX_SEG) si_base=core.seg_prefix_base; - else si_base=SegBase(ds); + si_base=BaseDS; di_base=SegBase(es); - add_mask=AddrMaskTable[core.prefixes& PREFIX_ADDR]; + add_mask=AddrMaskTable[core.prefixes & PREFIX_ADDR]; si_index=reg_esi & add_mask; di_index=reg_edi & add_mask; count=reg_ecx & add_mask; diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index 311a9eba..910f1677 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -16,38 +16,18 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define GETIP (core.cseip-SegBase(cs)) -#define SAVEIP reg_eip=GETIP; -#define LOADIP core.cseip=(SegBase(cs)+reg_eip); -#define RUNEXCEPTION() { \ - FillFlags(); \ - CPU_Exception(cpu.exception.which,cpu.exception.error); \ - continue; \ -} +#define LoadMbs(off) (Bit8s)(LoadMb(off)) +#define LoadMws(off) (Bit16s)(LoadMw(off)) +#define LoadMds(off) (Bit32s)(LoadMd(off)) -#define EXCEPTION(blah) \ - { \ - CPU_Exception(blah); \ - continue; \ - } +#define LoadRb(reg) reg +#define LoadRw(reg) reg +#define LoadRd(reg) reg -static INLINE Bit8u Fetchb() { - Bit8u temp=LoadMb(core.cseip); - core.cseip+=1; - return temp; -} - -static INLINE Bit16u Fetchw() { - Bit16u temp=LoadMw(core.cseip); - core.cseip+=2; - return temp; -} -static INLINE Bit32u Fetchd() { - Bit32u temp=LoadMd(core.cseip); - core.cseip+=4; - return temp; -} +#define SaveRb(reg,val) reg=val +#define SaveRw(reg,val) reg=val +#define SaveRd(reg,val) reg=val static INLINE Bit8s Fetchbs() { return Fetchb(); @@ -60,10 +40,18 @@ static INLINE Bit32s Fetchds() { return Fetchd(); } -#define Push_16 CPU_Push16 -#define Push_32 CPU_Push32 -#define Pop_16 CPU_Pop16 -#define Pop_32 CPU_Pop32 + +#define RUNEXCEPTION() { \ + FillFlags(); \ + CPU_Exception(cpu.exception.which,cpu.exception.error); \ + continue; \ +} + +#define EXCEPTION(blah) \ + { \ + CPU_Exception(blah); \ + continue; \ + } //TODO Could probably make all byte operands fast? #define JumpCond16_b(COND) { \ diff --git a/src/cpu/core_normal/table_ea.h b/src/cpu/core_normal/table_ea.h index d2772a65..990cc318 100644 --- a/src/cpu/core_normal/table_ea.h +++ b/src/cpu/core_normal/table_ea.h @@ -16,136 +16,35 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -typedef PhysPt (*GetEATable[256])(void); typedef PhysPt (*EA_LookupHandler)(void); - /* The MOD/RM Decoder for EA for this decoder's addressing modes */ -static PhysPt EA_16_00_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si); } -static PhysPt EA_16_01_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di); } -static PhysPt EA_16_02_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si); } -static PhysPt EA_16_03_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di); } -static PhysPt EA_16_04_n(void) { return SegBase(ds)+(Bit16u)(reg_si); } -static PhysPt EA_16_05_n(void) { return SegBase(ds)+(Bit16u)(reg_di); } -static PhysPt EA_16_06_n(void) { return SegBase(ds)+(Bit16u)(Fetchw());} -static PhysPt EA_16_07_n(void) { return SegBase(ds)+(Bit16u)(reg_bx); } +static PhysPt EA_16_00_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_si); } +static PhysPt EA_16_01_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_di); } +static PhysPt EA_16_02_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_si); } +static PhysPt EA_16_03_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di); } +static PhysPt EA_16_04_n(void) { return BaseDS+(Bit16u)(reg_si); } +static PhysPt EA_16_05_n(void) { return BaseDS+(Bit16u)(reg_di); } +static PhysPt EA_16_06_n(void) { return BaseDS+(Bit16u)(Fetchw());} +static PhysPt EA_16_07_n(void) { return BaseDS+(Bit16u)(reg_bx); } -static PhysPt EA_16_40_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); } -static PhysPt EA_16_41_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); } -static PhysPt EA_16_42_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); } -static PhysPt EA_16_43_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); } -static PhysPt EA_16_44_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchbs()); } -static PhysPt EA_16_45_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchbs()); } -static PhysPt EA_16_46_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchbs()); } -static PhysPt EA_16_47_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchbs()); } +static PhysPt EA_16_40_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); } +static PhysPt EA_16_41_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); } +static PhysPt EA_16_42_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); } +static PhysPt EA_16_43_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); } +static PhysPt EA_16_44_n(void) { return BaseDS+(Bit16u)(reg_si+Fetchbs()); } +static PhysPt EA_16_45_n(void) { return BaseDS+(Bit16u)(reg_di+Fetchbs()); } +static PhysPt EA_16_46_n(void) { return BaseSS+(Bit16u)(reg_bp+Fetchbs()); } +static PhysPt EA_16_47_n(void) { return BaseDS+(Bit16u)(reg_bx+Fetchbs()); } -static PhysPt EA_16_80_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); } -static PhysPt EA_16_81_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); } -static PhysPt EA_16_82_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); } -static PhysPt EA_16_83_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); } -static PhysPt EA_16_84_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchws()); } -static PhysPt EA_16_85_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchws()); } -static PhysPt EA_16_86_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchws()); } -static PhysPt EA_16_87_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchws()); } - -static GetEATable GetEA_NONE={ -/* 00 */ - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, -/* 01 */ - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, -/* 10 */ - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, -/* 11 These are illegal so make em 0 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - - - -static PhysPt EA_16_00_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_si); } -static PhysPt EA_16_01_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_di); } -static PhysPt EA_16_02_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_si); } -static PhysPt EA_16_03_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_di); } -static PhysPt EA_16_04_s(void) { return core.seg_prefix_base+(Bit16u)(reg_si); } -static PhysPt EA_16_05_s(void) { return core.seg_prefix_base+(Bit16u)(reg_di); } -static PhysPt EA_16_06_s(void) { return core.seg_prefix_base+(Bit16u)(Fetchw()); } -static PhysPt EA_16_07_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx); } - -static PhysPt EA_16_40_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); } -static PhysPt EA_16_41_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); } -static PhysPt EA_16_42_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); } -static PhysPt EA_16_43_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); } -static PhysPt EA_16_44_s(void) { return core.seg_prefix_base+(Bit16u)(reg_si+Fetchbs()); } -static PhysPt EA_16_45_s(void) { return core.seg_prefix_base+(Bit16u)(reg_di+Fetchbs()); } -static PhysPt EA_16_46_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+Fetchbs()); } -static PhysPt EA_16_47_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+Fetchbs()); } - -static PhysPt EA_16_80_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); } -static PhysPt EA_16_81_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); } -static PhysPt EA_16_82_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); } -static PhysPt EA_16_83_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); } -static PhysPt EA_16_84_s(void) { return core.seg_prefix_base+(Bit16u)(reg_si+Fetchws()); } -static PhysPt EA_16_85_s(void) { return core.seg_prefix_base+(Bit16u)(reg_di+Fetchws()); } -static PhysPt EA_16_86_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+Fetchws()); } -static PhysPt EA_16_87_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+Fetchws()); } - -static GetEATable GetEA_SEG={ -/* 00 */ - EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, - EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, - EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, - EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, - EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, - EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, - EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, - EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s, -/* 01 */ - EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, - EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, - EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, - EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, - EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, - EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, - EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, - EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s, -/* 10 */ - EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, - EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, - EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, - EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, - EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, - EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, - EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, - EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s, -/* 11 These are illegal so make em 0 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; +static PhysPt EA_16_80_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); } +static PhysPt EA_16_81_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); } +static PhysPt EA_16_82_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); } +static PhysPt EA_16_83_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); } +static PhysPt EA_16_84_n(void) { return BaseDS+(Bit16u)(reg_si+Fetchws()); } +static PhysPt EA_16_85_n(void) { return BaseDS+(Bit16u)(reg_di+Fetchws()); } +static PhysPt EA_16_86_n(void) { return BaseSS+(Bit16u)(reg_bp+Fetchws()); } +static PhysPt EA_16_87_n(void) { return BaseDS+(Bit16u)(reg_bx+Fetchws()); } static Bit32u SIBZero=0; static Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi }; @@ -155,61 +54,92 @@ INLINE PhysPt Sib(Bitu mode) { PhysPt base; switch (sib&7) { case 0: /* EAX Base */ - base=SegBase(ds)+reg_eax;break; + base=BaseDS+reg_eax;break; case 1: /* ECX Base */ - base=SegBase(ds)+reg_ecx;break; + base=BaseDS+reg_ecx;break; case 2: /* EDX Base */ - base=SegBase(ds)+reg_edx;break; + base=BaseDS+reg_edx;break; case 3: /* EBX Base */ - base=SegBase(ds)+reg_ebx;break; + base=BaseDS+reg_ebx;break; case 4: /* ESP Base */ - base=SegBase(ss)+reg_esp;break; + base=BaseSS+reg_esp;break; case 5: /* #1 Base */ if (!mode) { - base=SegBase(ds)+Fetchd();break; + base=BaseDS+Fetchd();break; } else { - base=SegBase(ss)+reg_ebp;break; + base=BaseSS+reg_ebp;break; } case 6: /* ESI Base */ - base=SegBase(ds)+reg_esi;break; + base=BaseDS+reg_esi;break; case 7: /* EDI Base */ - base=SegBase(ds)+reg_edi;break; + base=BaseDS+reg_edi;break; } base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6); return base; }; - -static PhysPt EA_32_00_n(void) { return SegBase(ds)+reg_eax; } -static PhysPt EA_32_01_n(void) { return SegBase(ds)+reg_ecx; } -static PhysPt EA_32_02_n(void) { return SegBase(ds)+reg_edx; } -static PhysPt EA_32_03_n(void) { return SegBase(ds)+reg_ebx; } +static PhysPt EA_32_00_n(void) { return BaseDS+reg_eax; } +static PhysPt EA_32_01_n(void) { return BaseDS+reg_ecx; } +static PhysPt EA_32_02_n(void) { return BaseDS+reg_edx; } +static PhysPt EA_32_03_n(void) { return BaseDS+reg_ebx; } static PhysPt EA_32_04_n(void) { return Sib(0);} -static PhysPt EA_32_05_n(void) { return SegBase(ds)+Fetchd(); } -static PhysPt EA_32_06_n(void) { return SegBase(ds)+reg_esi; } -static PhysPt EA_32_07_n(void) { return SegBase(ds)+reg_edi; } +static PhysPt EA_32_05_n(void) { return BaseDS+Fetchd(); } +static PhysPt EA_32_06_n(void) { return BaseDS+reg_esi; } +static PhysPt EA_32_07_n(void) { return BaseDS+reg_edi; } -static PhysPt EA_32_40_n(void) { return SegBase(ds)+reg_eax+Fetchbs(); } -static PhysPt EA_32_41_n(void) { return SegBase(ds)+reg_ecx+Fetchbs(); } -static PhysPt EA_32_42_n(void) { return SegBase(ds)+reg_edx+Fetchbs(); } -static PhysPt EA_32_43_n(void) { return SegBase(ds)+reg_ebx+Fetchbs(); } +static PhysPt EA_32_40_n(void) { return BaseDS+reg_eax+Fetchbs(); } +static PhysPt EA_32_41_n(void) { return BaseDS+reg_ecx+Fetchbs(); } +static PhysPt EA_32_42_n(void) { return BaseDS+reg_edx+Fetchbs(); } +static PhysPt EA_32_43_n(void) { return BaseDS+reg_ebx+Fetchbs(); } static PhysPt EA_32_44_n(void) { PhysPt temp=Sib(1);return temp+Fetchbs();} //static PhysPt EA_32_44_n(void) { return Sib(1)+Fetchbs();} -static PhysPt EA_32_45_n(void) { return SegBase(ss)+reg_ebp+Fetchbs(); } -static PhysPt EA_32_46_n(void) { return SegBase(ds)+reg_esi+Fetchbs(); } -static PhysPt EA_32_47_n(void) { return SegBase(ds)+reg_edi+Fetchbs(); } +static PhysPt EA_32_45_n(void) { return BaseSS+reg_ebp+Fetchbs(); } +static PhysPt EA_32_46_n(void) { return BaseDS+reg_esi+Fetchbs(); } +static PhysPt EA_32_47_n(void) { return BaseDS+reg_edi+Fetchbs(); } -static PhysPt EA_32_80_n(void) { return SegBase(ds)+reg_eax+Fetchds(); } -static PhysPt EA_32_81_n(void) { return SegBase(ds)+reg_ecx+Fetchds(); } -static PhysPt EA_32_82_n(void) { return SegBase(ds)+reg_edx+Fetchds(); } -static PhysPt EA_32_83_n(void) { return SegBase(ds)+reg_ebx+Fetchds(); } +static PhysPt EA_32_80_n(void) { return BaseDS+reg_eax+Fetchds(); } +static PhysPt EA_32_81_n(void) { return BaseDS+reg_ecx+Fetchds(); } +static PhysPt EA_32_82_n(void) { return BaseDS+reg_edx+Fetchds(); } +static PhysPt EA_32_83_n(void) { return BaseDS+reg_ebx+Fetchds(); } static PhysPt EA_32_84_n(void) { PhysPt temp=Sib(2);return temp+Fetchds();} //static PhysPt EA_32_84_n(void) { return Sib(2)+Fetchds();} -static PhysPt EA_32_85_n(void) { return SegBase(ss)+reg_ebp+Fetchds(); } -static PhysPt EA_32_86_n(void) { return SegBase(ds)+reg_esi+Fetchds(); } -static PhysPt EA_32_87_n(void) { return SegBase(ds)+reg_edi+Fetchds(); } +static PhysPt EA_32_85_n(void) { return BaseSS+reg_ebp+Fetchds(); } +static PhysPt EA_32_86_n(void) { return BaseDS+reg_esi+Fetchds(); } +static PhysPt EA_32_87_n(void) { return BaseDS+reg_edi+Fetchds(); } -static GetEATable GetEA_ADDR={ +static GetEAHandler EATable[512]={ +/* 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, /* 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, @@ -244,113 +174,12 @@ static GetEATable GetEA_ADDR={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -INLINE PhysPt Sib_s(Bitu mode) { - Bit8u sib=Fetchb(); - PhysPt base; - switch (sib&7) { - case 0: /* EAX Base */ - base=reg_eax;break; - case 1: /* ECX Base */ - base=reg_ecx;break; - case 2: /* EDX Base */ - base=reg_edx;break; - case 3: /* EBX Base */ - base=reg_ebx;break; - case 4: /* ESP Base */ - base=reg_esp;break; - case 5: /* #1 Base */ - if (!mode) { - base=Fetchd();break; - } else { - base=reg_ebp;break; - } - case 6: /* ESI Base */ - base=reg_esi;break; - case 7: /* EDI Base */ - base=reg_edi;break; - } - base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6); - return base; -}; - - -static PhysPt EA_32_00_s(void) { return core.seg_prefix_base+(Bit32u)(reg_eax); } -static PhysPt EA_32_01_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ecx); } -static PhysPt EA_32_02_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edx); } -static PhysPt EA_32_03_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebx); } -static PhysPt EA_32_04_s(void) { return core.seg_prefix_base+(Bit32u)(Sib_s(0));} -static PhysPt EA_32_05_s(void) { return core.seg_prefix_base+(Bit32u)(Fetchd()); } -static PhysPt EA_32_06_s(void) { return core.seg_prefix_base+(Bit32u)(reg_esi); } -static PhysPt EA_32_07_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edi); } - -static PhysPt EA_32_40_s(void) { return core.seg_prefix_base+(Bit32u)(reg_eax+Fetchbs()); } -static PhysPt EA_32_41_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ecx+Fetchbs()); } -static PhysPt EA_32_42_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edx+Fetchbs()); } -static PhysPt EA_32_43_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebx+Fetchbs()); } -static PhysPt EA_32_44_s(void) { PhysPt temp=Sib_s(1);return core.seg_prefix_base+(Bit32u)(temp+Fetchbs());} -static PhysPt EA_32_45_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebp+Fetchbs()); } -static PhysPt EA_32_46_s(void) { return core.seg_prefix_base+(Bit32u)(reg_esi+Fetchbs()); } -static PhysPt EA_32_47_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edi+Fetchbs()); } - -static PhysPt EA_32_80_s(void) { return core.seg_prefix_base+(Bit32u)(reg_eax+Fetchds()); } -static PhysPt EA_32_81_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ecx+Fetchds()); } -static PhysPt EA_32_82_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edx+Fetchds()); } -static PhysPt EA_32_83_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebx+Fetchds()); } -static PhysPt EA_32_84_s(void) { PhysPt temp=Sib_s(2);return core.seg_prefix_base+(Bit32u)(temp+Fetchds());} -static PhysPt EA_32_85_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebp+Fetchds()); } -static PhysPt EA_32_86_s(void) { return core.seg_prefix_base+(Bit32u)(reg_esi+Fetchds()); } -static PhysPt EA_32_87_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edi+Fetchds()); } - - -static GetEATable GetEA_SEG_ADDR={ -/* 00 */ - EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, - EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, - EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, - EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, - EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, - EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, - EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, - EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s, -/* 01 */ - EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, - EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, - EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, - EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, - EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, - EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, - EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, - EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s, -/* 10 */ - EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, - EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, - EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, - EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, - EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, - EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, - EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, - EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s, -/* 11 These are illegal so make em 0 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -#define GetEADirect \ - PhysPt eaa; \ - if (TEST_PREFIX_SEG) { \ - if (TEST_PREFIX_ADDR) { \ - eaa=core.seg_prefix_base+Fetchd(); \ - } else { \ - eaa=core.seg_prefix_base+Fetchw(); \ - } \ - } else { \ - if (TEST_PREFIX_ADDR) { \ - eaa=SegBase(ds)+Fetchd(); \ - } else { \ - eaa=SegBase(ds)+Fetchw(); \ - } \ - } +#define GetEADirect \ + PhysPt eaa; \ + if (TEST_PREFIX_ADDR) { \ + eaa=BaseDS+Fetchd(); \ + } else { \ + eaa=BaseDS+Fetchw(); \ + } \ diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp new file mode 100644 index 00000000..7ff744e6 --- /dev/null +++ b/src/cpu/core_simple.cpp @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2002-2004 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include + +#include "dosbox.h" +#include "mem.h" +#include "cpu.h" +#include "lazyflags.h" +#include "inout.h" +#include "callback.h" +#include "pic.h" +#include "fpu.h" + +#if C_DEBUG +#include "debug.h" +#endif + +#include "paging.h" +#define SegBase(c) SegPhys(c) +#define LoadMb(off) mem_readb(off) +#define LoadMw(off) mem_readw(off) +#define LoadMd(off) mem_readd(off) + +#define SaveMb(off,val) mem_writeb(off,val) +#define SaveMw(off,val) mem_writew(off,val) +#define SaveMd(off,val) mem_writed(off,val) + +extern Bitu cycle_count; + +#if C_FPU +#define CPU_FPU 1 //Enable FPU escape instructions +#endif + +#define CPU_PIC_CHECK 1 +#define CPU_TRAP_CHECK 1 + +#define OPCODE_NONE 0x000 +#define OPCODE_0F 0x100 +#define OPCODE_SIZE 0x200 + +#define PREFIX_ADDR 0x1 +#define PREFIX_REP 0x2 + +#define TEST_PREFIX_ADDR (core.prefixes & PREFIX_ADDR) +#define TEST_PREFIX_REP (core.prefixes & PREFIX_REP) + +#define DO_PREFIX_SEG(_SEG) \ + BaseDS=SegBase(_SEG); \ + BaseSS=SegBase(_SEG); \ + goto restart_opcode; + +#define DO_PREFIX_ADDR() \ + core.prefixes=(core.prefixes & ~PREFIX_ADDR) | \ + (cpu.code.big ^ PREFIX_ADDR); \ + core.ea_table=&EATable[(core.prefixes&1) * 256]; \ + goto restart_opcode; + +#define DO_PREFIX_REP(_ZERO) \ + core.prefixes|=PREFIX_REP; \ + core.rep_zero=_ZERO; \ + goto restart_opcode; + +typedef PhysPt (*GetEAHandler)(void); + +static const Bit32u AddrMaskTable[2]={0x0000ffff,0xffffffff}; + +static struct { + Bitu opcode_index; + HostPt cseip; + PhysPt base_ds,base_ss; + bool rep_zero; + Bitu prefixes; + GetEAHandler * ea_table; + struct { + bool skip; + } trap; +} core; + +#define GETIP (core.cseip-SegBase(cs)-MemBase) +#define SAVEIP reg_eip=GETIP; +#define LOADIP core.cseip=(MemBase+SegBase(cs)+reg_eip); + +#define SegBase(c) SegPhys(c) +#define BaseDS core.base_ds +#define BaseSS core.base_ss + +static INLINE Bit8u Fetchb() { + Bit8u temp=host_readb(core.cseip); + core.cseip+=1; + return temp; +} + +static INLINE Bit16u Fetchw() { + Bit16u temp=host_readw(core.cseip); + core.cseip+=2; + return temp; +} +static INLINE Bit32u Fetchd() { + Bit32u temp=host_readd(core.cseip); + core.cseip+=4; + return temp; +} + +#define Push_16 CPU_Push16 +#define Push_32 CPU_Push32 +#define Pop_16 CPU_Pop16 +#define Pop_32 CPU_Pop32 + +#include "instructions.h" +#include "core_normal/support.h" +#include "core_normal/string.h" + + +#define EALookupTable (core.ea_table) + +Bits CPU_Core_Simple_Run(void) { + while (CPU_Cycles-->0) { + LOADIP; + core.opcode_index=cpu.code.big*0x200; + core.prefixes=cpu.code.big; + core.ea_table=&EATable[cpu.code.big*256]; + BaseDS=SegBase(ds); + BaseSS=SegBase(ss); +#if C_DEBUG +#if C_HEAVY_DEBUG + if (DEBUG_HeavyIsBreakpoint()) { + FillFlags(); + return debugCallback; + }; +#endif + cycle_count++; +#endif +restart_opcode: + switch (core.opcode_index+Fetchb()) { + + #include "core_normal/prefix_none.h" + #include "core_normal/prefix_0f.h" + #include "core_normal/prefix_66.h" + #include "core_normal/prefix_66_0f.h" + default: + illegal_opcode: +#if C_DEBUG + { + Bitu len=(GETIP-reg_eip); + LOADIP; + if (len>16) len=16; + char tempcode[16*2+1];char * writecode=tempcode; + for (;len>0;len--) { +// sprintf(writecode,"%X",mem_readb(core.cseip++)); + writecode+=2; + } + LOG(LOG_CPU,LOG_ERROR)("Illegal/Unhandled opcode %s",tempcode); + } +#endif + CPU_Exception(6,0); + continue; + } + SAVEIP; + } + FillFlags(); + return CBRET_NONE; +decode_end: + SAVEIP; + FillFlags(); + return CBRET_NONE; +} + +Bits CPU_Core_Simple_Trap_Run(void) { + + Bits oldCycles = CPU_Cycles; + CPU_Cycles = 1; + core.trap.skip=false; + + Bits ret=CPU_Core_Normal_Run(); + if (!core.trap.skip) CPU_SW_Interrupt(1,reg_eip); + CPU_Cycles = oldCycles-1; + cpudecoder = &CPU_Core_Normal_Run; + + return ret; +} + + + +void CPU_Core_Simple_Init(void) { + +} + diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 1b72c7f6..32f32830 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.60 2004-08-04 09:12:51 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.61 2004-08-23 12:17:29 harekiet Exp $ */ #include #include "dosbox.h" @@ -48,6 +48,7 @@ CPU_Decoder * cpudecoder; void CPU_Core_Full_Init(void); void CPU_Core_Normal_Init(void); +void CPU_Core_Simple_Init(void); void CPU_Core_Dyn_X86_Init(void); void CPU_Push16(Bitu value) { @@ -1346,6 +1347,7 @@ void CPU_Init(Section* sec) { /* Init the cpu cores */ CPU_Core_Normal_Init(); + CPU_Core_Simple_Init(); CPU_Core_Full_Init(); #if (C_DYNAMIC_X86) CPU_Core_Dyn_X86_Init(); @@ -1360,6 +1362,8 @@ void CPU_Init(Section* sec) { cpudecoder=&CPU_Core_Normal_Run; if (!strcasecmp(core,"normal")) { cpudecoder=&CPU_Core_Normal_Run; + } else if (!strcasecmp(core,"simple")) { + cpudecoder=&CPU_Core_Simple_Run; } else if (!strcasecmp(core,"full")) { cpudecoder=&CPU_Core_Full_Run; } diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 2a9809c6..a77a9a11 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -93,7 +93,7 @@ static Bits PageFaultCore(void) { if (!pf_queue.used) E_Exit("PF Core without PF"); PF_Entry * entry=&pf_queue.entries[pf_queue.used-1]; X86PageEntry pentry; - pentry.load=MEM_PhysReadD(entry->page_addr); + pentry.load=phys_readd(entry->page_addr); if (pentry.block.p && entry->cs == SegValue(cs) && entry->eip==reg_eip) return -1; return 0; @@ -102,6 +102,8 @@ static Bits PageFaultCore(void) { Bitu DEBUG_EnableDebugger(void); #endif +bool first=false; + void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu type) { /* Save the state of the cpu cores */ LazyFlags old_lflags; @@ -112,6 +114,8 @@ void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu type) { paging.cr2=lin_addr; PF_Entry * entry=&pf_queue.entries[pf_queue.used++]; LOG(LOG_PAGING,LOG_NORMAL)("PageFault at %X type %d queue %d",lin_addr,type,pf_queue.used); +// LOG_MSG("EAX:%04X ECX:%04X EDX:%04X EBX:%04X",reg_eax,reg_ecx,reg_edx,reg_ebx); +// LOG_MSG("CS:%04X EIP:%08X SS:%04x SP:%08X",SegValue(cs),reg_eip,SegValue(ss),reg_esp); entry->cs=SegValue(cs); entry->eip=reg_eip; entry->page_addr=page_addr; @@ -125,10 +129,9 @@ void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu type) { LOG(LOG_PAGING,LOG_NORMAL)("Left PageFault for %x queue %d",lin_addr,pf_queue.used); memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); cpudecoder=old_cpudecoder; +// LOG_MSG("SS:%04x SP:%08X",SegValue(ss),reg_esp); } - -void MEM_PhysWriteD(Bitu addr,Bit32u val); class InitPageHandler : public PageHandler { public: InitPageHandler() {flags=PFLAG_INIT|PFLAG_NOCODE;} @@ -164,28 +167,28 @@ public: Bitu t_index=lin_page & 0x3ff; Bitu table_addr=(paging.base.page<<12)+d_index*4; X86PageEntry table; - table.load=MEM_PhysReadD(table_addr); + table.load=phys_readd(table_addr); if (!table.block.p) { LOG(LOG_PAGING,LOG_ERROR)("NP Table"); PAGING_PageFault(lin_addr,table_addr,0); - table.load=MEM_PhysReadD(table_addr); + table.load=phys_readd(table_addr); if (!table.block.p) E_Exit("Pagefault didn't correct table"); } table.block.a=table.block.d=1; //Set access/Dirty - MEM_PhysWriteD(table_addr,table.load); + phys_writed(table_addr,table.load); X86PageEntry entry; Bitu entry_addr=(table.block.base<<12)+t_index*4; - entry.load=MEM_PhysReadD(entry_addr); + entry.load=phys_readd(entry_addr); if (!entry.block.p) { LOG(LOG_PAGING,LOG_ERROR)("NP Page"); PAGING_PageFault(lin_addr,entry_addr,0); - entry.load=MEM_PhysReadD(entry_addr); + entry.load=phys_readd(entry_addr); if (!entry.block.p) E_Exit("Pagefault didn't correct page"); } entry.block.a=entry.block.d=1; //Set access/Dirty - MEM_PhysWriteD(entry_addr,entry.load); + phys_writed(entry_addr,entry.load); phys_page=entry.block.base; } else { if (lin_page> 10; Bitu t_index=page & 0x3ff; X86PageEntry table; - table.load=MEM_PhysReadD((paging.base.page<<12)+d_index*4); + table.load=phys_readd((paging.base.page<<12)+d_index*4); if (!table.block.p) return false; X86PageEntry entry; - entry.load=MEM_PhysReadD((table.block.base<<12)+t_index*4); + entry.load=phys_readd((table.block.base<<12)+t_index*4); if (!entry.block.p) return false; page=entry.block.base; } else { @@ -281,7 +284,7 @@ void PAGING_SetDirBase(Bitu cr3) { paging.base.page=cr3 >> 12; paging.base.addr=cr3 & ~4095; - LOG(LOG_PAGING,LOG_NORMAL)("CR3:%X Base %X",cr3,paging.base.page); +// LOG(LOG_PAGING,LOG_NORMAL)("CR3:%X Base %X",cr3,paging.base.page); if (paging.enabled) { PAGING_ClearTLB(); } @@ -292,9 +295,15 @@ void PAGING_Enable(bool enabled) { if (paging.enabled==enabled) return; paging.enabled=enabled; if (!enabled) { - LOG(LOG_PAGING,LOG_NORMAL)("Disabled"); +// LOG(LOG_PAGING,LOG_NORMAL)("Disabled"); } else { - LOG(LOG_PAGING,LOG_NORMAL)("Enabled"); + if (cpudecoder==CPU_Core_Simple_Run) { + LOG_MSG("CPU core simple won't run this game,switching to normal"); + cpudecoder=CPU_Core_Normal_Run; + CPU_CycleLeft+=CPU_Cycles; + CPU_Cycles=0; + } +// LOG(LOG_PAGING,LOG_NORMAL)("Enabled"); PAGING_SetDirBase(paging.cr3); } PAGING_ClearTLB(); From f7a6317328ef7e8238a29d2397aae0853506c48d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 23 Aug 2004 12:19:17 +0000 Subject: [PATCH 1838/4131] New memory handling using 1 big block of memory Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1920 --- include/mem.h | 26 ++++++++--- include/paging.h | 5 --- src/hardware/memory.cpp | 97 +++-------------------------------------- 3 files changed, 27 insertions(+), 101 deletions(-) diff --git a/include/mem.h b/include/mem.h index b1ccb82e..f213305b 100644 --- a/include/mem.h +++ b/include/mem.h @@ -20,8 +20,6 @@ #define __MEM_H #include -#define bmemcpy(mem1,mem2,size) memcpy((void *)mem1,(void *)mem2,size) - typedef Bit32u PhysPt; typedef Bit8u * HostPt; typedef Bit32u RealPt; @@ -30,6 +28,8 @@ typedef Bit32s MemHandle; #define MEM_PAGESIZE 4096 +extern HostPt MemBase; + bool MEM_A20_Enabled(void); void MEM_A20_Enable(bool enable); @@ -123,9 +123,25 @@ void mem_writeb(PhysPt pt,Bit8u val); void mem_writew(PhysPt pt,Bit16u val); void mem_writed(PhysPt pt,Bit32u val); -void phys_writeb(PhysPt addr,Bit8u val); -void phys_writew(PhysPt addr,Bit16u val); -void phys_writed(PhysPt addr,Bit32u val); +INLINE void phys_writeb(PhysPt addr,Bit8u val) { + host_writeb(MemBase+addr,val); +} +INLINE void phys_writew(PhysPt addr,Bit16u val){ + host_writew(MemBase+addr,val); +} +INLINE void phys_writed(PhysPt addr,Bit32u val){ + host_writed(MemBase+addr,val); +} + +INLINE Bit8u phys_readb(PhysPt addr) { + return host_readb(MemBase+addr); +} +INLINE Bit16u phys_readw(PhysPt addr){ + return host_readw(MemBase+addr); +} +INLINE Bit32u phys_readd(PhysPt addr){ + return host_readd(MemBase+addr); +} /* These don't check for alignment, better be sure it's correct */ diff --git a/include/paging.h b/include/paging.h index 29f8ddde..169731e9 100644 --- a/include/paging.h +++ b/include/paging.h @@ -70,11 +70,6 @@ bool PAGING_MakePhysPage(Bitu & page); void MEM_SetLFB(Bitu _page,Bitu _pages,HostPt _pt); void MEM_SetPageHandler(Bitu phys_page,Bitu pages,PageHandler * handler); -Bit32u MEM_PhysReadD(Bitu addr); - - - - #pragma pack(1) typedef struct { Bit32u p:1; diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index cc57d417..2a511d38 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -34,11 +34,6 @@ #define LFB_PAGES 512 #define MAX_LINKS ((MAX_MEMORY*1024/4)+4096) //Hopefully enough -struct AllocBlock { - Bit8u data[PAGES_IN_BLOCK*4096]; - AllocBlock * next; -}; - struct LinkBlock { Bitu used; Bit32u pages[MAX_LINKS]; @@ -47,14 +42,8 @@ struct LinkBlock { static struct MemoryBlock { Bitu pages; PageHandler * * phandlers; - HostPt * hostpts; MemHandle * mhandles; LinkBlock links; - struct { - Bitu pages; - HostPt cur_page; - AllocBlock *cur_block; - } block; struct { Bitu start_page; Bitu end_page; @@ -67,6 +56,8 @@ static struct MemoryBlock { } a20; } memory; +HostPt MemBase; + class IllegalPageHandler : public PageHandler { public: IllegalPageHandler() { @@ -90,10 +81,7 @@ public: flags=PFLAG_READABLE|PFLAG_WRITEABLE; } HostPt GetHostPt(Bitu phys_page) { - if (!memory.hostpts[phys_page]) { - memory.hostpts[phys_page]=MEM_GetBlockPage(); - } - return memory.hostpts[phys_page]; + return MemBase+phys_page*MEM_PAGESIZE; } }; @@ -467,51 +455,6 @@ void mem_writed(PhysPt address,Bit32u val) { mem_writed_inline(address,val); } -void phys_writeb(PhysPt addr,Bit8u val) { - HostPt block=memory.hostpts[addr >> 12]; - if (!block) { - block=memory.hostpts[addr >> 12]=MEM_GetBlockPage(); - } - host_writeb(block+(addr & 4095),val); -} - -void phys_writew(PhysPt addr,Bit16u val) { - phys_writeb(addr,(Bit8u)val); - phys_writeb(addr+1,(Bit8u)(val >> 8)); -} - -void phys_writed(PhysPt addr,Bit32u val) { - phys_writeb(addr,(Bit8u)val); - phys_writeb(addr+1,(Bit8u)(val >> 8)); - phys_writeb(addr+2,(Bit8u)(val >> 16)); - phys_writeb(addr+3,(Bit8u)(val >> 24)); -} - -Bit32u MEM_PhysReadD(Bitu addr) { - Bitu page=addr >> 12; - Bitu index=(addr & 4095); - if (page>memory.pages) - E_Exit("Reading from illegal page"); - HostPt block=memory.hostpts[page]; - if (!block) { - E_Exit("Reading from empty page"); - } - return host_readd(block+index); -} - -void MEM_PhysWriteD(Bitu addr,Bit32u val) { - Bitu page=addr >> 12; - Bitu index=(addr & 4095); - if (page>memory.pages) - E_Exit("Writing from illegal page"); - HostPt block=memory.hostpts[page]; - if (!block) { - E_Exit("Writing to empty page"); - } - host_writed(block+index,val); -} - - static void write_p92(Bitu port,Bitu val,Bitu iolen) { // Bit 0 = system reset (switch back to real mode) if (val&1) E_Exit("XMS: CPU reset via port 0x92 not supported."); @@ -524,42 +467,14 @@ static Bitu read_p92(Bitu port,Bitu iolen) { } -HostPt MEM_GetBlockPage(void) { - HostPt ret; - if (memory.block.pages) { - ret=memory.block.cur_page; - memory.block.pages--; - memory.block.cur_page+=4096; - } else { - AllocBlock * newblock=new AllocBlock; - memset(newblock,0,sizeof(AllocBlock)); //zero new allocated memory - newblock->next=memory.block.cur_block; - memory.block.cur_block=newblock; - - memory.block.pages=PAGES_IN_BLOCK-1; - ret=&newblock->data[0]; - memory.block.cur_page=&newblock->data[4096]; - } - return ret; -} - static void MEM_ShutDown(Section * sec) { - AllocBlock * theblock=memory.block.cur_block; - while (theblock) { - AllocBlock * next=theblock->next; - delete theblock; - theblock=next; - } + free(MemBase); } void MEM_Init(Section * sec) { Bitu i; Section_prop * section=static_cast(sec); - /* Setup Memory Block */ - memory.block.pages=0; - memory.block.cur_block=0; - /* Setup the Physical Page Links */ Bitu memsize=section->Get_int("memsize"); @@ -568,13 +483,13 @@ void MEM_Init(Section * sec) { LOG_MSG("Maximum memory size is %d MB",MAX_MEMORY); memsize=MAX_MEMORY; } + MemBase=(HostPt)malloc(memsize*1024*1024); + if (!MemBase) E_Exit("Can't allocate main memory of %d MB",memsize); memory.pages=(memsize*1024*1024)/4096; /* Allocate the data for the different page information blocks */ - memory.hostpts=new HostPt[memory.pages]; memory.phandlers=new PageHandler * [memory.pages]; memory.mhandles=new MemHandle [memory.pages]; for (i=0;i Date: Mon, 23 Aug 2004 12:19:52 +0000 Subject: [PATCH 1839/4131] added core_simple Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1921 --- include/cpu.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/cpu.h b/include/cpu.h index cc015857..9fd9bfe3 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -35,6 +35,7 @@ extern CPU_Decoder * cpudecoder; 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); @@ -415,5 +416,6 @@ INLINE void CPU_SetFlagsw(Bitu word) { CPU_SetFlags(word,mask); }; + #endif From 0da2fd2d36355482f5f36bd016fb91a1d279bedb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 23 Aug 2004 12:25:34 +0000 Subject: [PATCH 1840/4131] added core_simple Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1922 --- src/cpu/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/Makefile.am b/src/cpu/Makefile.am index 261369fb..62cc988d 100644 --- a/src/cpu/Makefile.am +++ b/src/cpu/Makefile.am @@ -3,5 +3,5 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libcpu.a libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h core_full.cpp instructions.h \ - paging.cpp lazyflags.h core_normal.cpp \ + paging.cpp lazyflags.h core_normal.cpp core_simple.cpp \ core_dyn_x86.cpp \ No newline at end of file From 3641ea7beb1487138566cb9587ea35a898f13a97 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 24 Aug 2004 10:52:06 +0000 Subject: [PATCH 1841/4131] Fx nosound mode and wave recording Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1923 --- src/hardware/mixer.cpp | 44 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 360507d2..e8dbc67d 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -266,6 +266,22 @@ static void MIXER_MixData(Bitu needed) { chan->Mix(needed); chan=chan->next; } + if (mixer.wave.handle) { + Bitu added=needed-mixer.done; + Bitu readpos=(mixer.pos+mixer.done-added)&MIXER_BUFMASK; + while (added--) { + Bits sample=mixer.work[readpos][0] >> MIXER_VOLSHIFT; + mixer.wave.buf[mixer.wave.used][0]=MIXER_CLIP(sample); + sample=mixer.work[readpos][1] >> MIXER_VOLSHIFT; + mixer.wave.buf[mixer.wave.used][1]=MIXER_CLIP(sample); + readpos=(readpos+1)&MIXER_BUFMASK; + if (++mixer.wave.used==MIXER_WAVESIZE) { + mixer.wave.length+=MIXER_WAVESIZE*MIXER_SSIZE; + mixer.wave.used=0; + fwrite(mixer.wave.buf,MIXER_WAVESIZE*MIXER_SSIZE,1,mixer.wave.handle); + } + } + } mixer.done=needed; } @@ -279,11 +295,23 @@ static void MIXER_Mix(void) { } static void MIXER_Mix_NoSound(void) { - mixer.done=0; + MIXER_MixData(mixer.needed); + /* Clear piece we've just generated */ + for (Bitu i=0;inext) { + if (chan->done>mixer.needed) chan->done-=mixer.needed; + else chan->done=0; + } + /* Set values for next tick */ mixer.tick_remain+=mixer.tick_add; - Bitu count=mixer.tick_remain>>MIXER_SHIFT; + mixer.needed=mixer.tick_remain>>MIXER_SHIFT; mixer.tick_remain&=MIXER_REMAIN; - MIXER_MixData(count); + mixer.done=0; } @@ -309,11 +337,11 @@ static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { } Bit16s * output=(Bit16s *)stream; while (need--) { - mixer.work[mixer.pos][0]>>=MIXER_VOLSHIFT; - *output++=MIXER_CLIP(mixer.work[mixer.pos][0]); + Bits sample=mixer.work[mixer.pos][0]>>MIXER_VOLSHIFT; + *output++=MIXER_CLIP(sample); mixer.work[mixer.pos][0]=0; - mixer.work[mixer.pos][1]>>=MIXER_VOLSHIFT; - *output++=MIXER_CLIP(mixer.work[mixer.pos][1]); + sample=mixer.work[mixer.pos][1]>>MIXER_VOLSHIFT; + *output++=MIXER_CLIP(sample); mixer.work[mixer.pos][1]=0; mixer.pos=(mixer.pos+1)&MIXER_BUFMASK; } @@ -454,7 +482,7 @@ void MIXER_Init(Section* sec) { mixer.min_needed=section->Get_int("prebuffer"); if (mixer.min_needed>100) mixer.min_needed=100; mixer.min_needed=(mixer.freq*mixer.min_needed)/1000; - + mixer.needed=mixer.min_needed+1; MAPPER_AddHandler(MIXER_WaveEvent,MK_f6,MMOD1,"recwave","Rec Wave"); PROGRAMS_MakeFile("MIXER.COM",MIXER_ProgramStart); } From 6d82d7192a0ce169a71a943d0f77c511e854c1d5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 24 Aug 2004 10:53:15 +0000 Subject: [PATCH 1842/4131] Force the speaker to enable when starting a sb16 command byte transfer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1924 --- src/hardware/sblaster.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index fca0ee63..2dc8dd34 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -661,6 +661,7 @@ static void DSP_DoCommand(void) { case 0xb0: case 0xb2: case 0xb4: case 0xb6: case 0xc0: case 0xc2: case 0xc4: case 0xc6: /* Generic 8/16 bit DMA */ + DSP_SetSpeaker(true); //SB16 always has speaker enabled sb.dma.sign=(sb.dsp.in.data[0] & 0x10) > 0; DSP_PrepareDMA_New((sb.dsp.cmd & 0x10) ? DSP_DMA_16 : DSP_DMA_8, 1+sb.dsp.in.data[1]+(sb.dsp.in.data[2] << 8), From 670ecd2ba1e4df95fe85c25706b2f1fb0a93b2f8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 25 Aug 2004 09:19:12 +0000 Subject: [PATCH 1843/4131] Add check for nice priority changing Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1925 --- configure.in | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/configure.in b/configure.in index fa8be44d..c7325bef 100644 --- a/configure.in +++ b/configure.in @@ -187,6 +187,16 @@ else AC_MSG_WARN([Can't find libSDL_sound, libSDL_sound support disabled]) fi +AH_TEMPLATE(C_PRIORITY_NICE,[Define to 1 if you have nice priority changing support]) +AC_MSG_CHECKING(for nice priority changing) +AC_LINK_IFELSE([ +#include +int main(int argc,char * argv[]) { + return nice(10); +}; +],AC_MSG_RESULT(yes);AC_DEFINE(C_PRIORITY_NICE,1),AC_MSG_RESULT(no)) + + dnl Some host detection and actions for them case "$target" in *-*-cygwin* | *-*-mingw32*) From 5d3260ab2913df5d1a2ddb81433694ca6b0f6648 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 26 Aug 2004 19:41:20 +0000 Subject: [PATCH 1844/4131] Added Blinking and Reverse. spaces2tabs Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1926 --- src/dos/dev_con.h | 523 ++++++++++++++++++++++------------------------ 1 file changed, 253 insertions(+), 270 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 97835ac0..8f2f9604 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.17 2004-08-04 09:12:53 qbix79 Exp $ */ +/* $Id: dev_con.h,v 1.18 2004-08-26 19:41:20 qbix79 Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" @@ -31,22 +31,22 @@ public: bool Write(Bit8u * data,Bit16u * size); bool Seek(Bit32u * pos,Bit32u type); bool Close(); - void ClearAnsi(void); + void ClearAnsi(void); Bit16u GetInformation(void); private: Bit8u cache; - struct ansi { /* should create a constructor which fills them with the appriorate values */ - bool esc; - bool sci; + struct ansi { /* should create a constructor which fills them with the appriorate values */ + bool esc; + bool sci; bool enabled; - Bit8u attr; - Bit8u data[NUMBER_ANSI_DATA]; - Bit8u numberofarg; - Bit16u nrows; - Bit16u ncols; - Bit8s savecol; - Bit8s saverow; - } ansi; + Bit8u attr; + Bit8u data[NUMBER_ANSI_DATA]; + Bit8u numberofarg; + Bit16u nrows; + Bit16u ncols; + Bit8s savecol; + Bit8s saverow; + } ansi; }; @@ -55,11 +55,8 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { Bit16u count=0; if ((cache) && (*size)) { data[count++]=cache; - if(dos.echo) { - INT10_TeletypeOutput(cache,7); - } - cache=0; - + if(dos.echo) INT10_TeletypeOutput(cache,7); + cache=0; } while (*size>count) { reg_ah=0; @@ -68,25 +65,24 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { case 13: data[count++]=0x0D; if (*size>count) data[count++]=0x0A; // it's only expanded if there is room for it. (NO cache) - *size=count; + *size=count; reg_ax=oldax; - if(dos.echo) { - INT10_TeletypeOutput(13,7); //maybe don't do this ( no need for it actually ) (but it's compatible) - INT10_TeletypeOutput(10,7); - } + if(dos.echo) { + INT10_TeletypeOutput(13,7); //maybe don't do this ( no need for it actually ) (but it's compatible) + INT10_TeletypeOutput(10,7); + } return true; - break; - case 8: - if(*size==1) data[count++]=reg_al; //one char at the time so give back that BS - else if(count) { //Remove data if it exists (extended keys don't go right) - data[count--]=0; - INT10_TeletypeOutput(8,7); - INT10_TeletypeOutput(' ',7); - } else { - continue; //no data read yet so restart whileloop. - } - - break; + break; + case 8: + if(*size==1) data[count++]=reg_al; //one char at the time so give back that BS + else if(count) { //Remove data if it exists (extended keys don't go right) + data[count--]=0; + INT10_TeletypeOutput(8,7); + INT10_TeletypeOutput(' ',7); + } else { + continue; //no data read yet so restart whileloop. + } + break; default: data[count++]=reg_al; break; @@ -95,11 +91,10 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { if (*size>count) data[count++]=reg_ah; else cache=reg_ah; break; - - } - if(dos.echo) { //what to do if *size==1 and character is BS ????? - INT10_TeletypeOutput(reg_al,7); - } + } + if(dos.echo) { //what to do if *size==1 and character is BS ????? + INT10_TeletypeOutput(reg_al,7); + } } *size=count; reg_ax=oldax; @@ -109,243 +104,235 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { bool device_CON::Write(Bit8u * data,Bit16u * size) { Bit16u count=0; - Bitu i; - Bit8u col,row; + Bitu i; + Bit8u col,row; Bit8u tempdata; - while (*size>count) { - if (!ansi.esc){ - if(data[count]=='\033') { - /*clear the datastructure */ - ClearAnsi(); - /* start the sequence */ - ansi.esc=true; - count++; - continue; - - } else { - // pass attribute only if ansi is enabled + while (*size>count) { + if (!ansi.esc){ + if(data[count]=='\033') { + /*clear the datastructure */ + ClearAnsi(); + /* start the sequence */ + ansi.esc=true; + count++; + continue; + } else { + /* pass attribute only if ansi is enabled */ INT10_TeletypeOutputAttr(data[count],ansi.attr,ansi.enabled); count++; continue; - }; - }; + } + } - if(!ansi.sci){ + if(!ansi.sci){ - switch(data[count]){ - case '[': - ansi.sci=true; - break; - case '7': /* save cursor pos +attr */ - case '8': /* restore this (Wonder if this is actually used) */ - case 'D':/* scrolling DOWN*/ - case 'M':/* scrolling UP*/ - default: - LOG(LOG_IOCTL,LOG_NORMAL)("ANSI: unknown char %c after a esc",data[count]); /*prob () */ - ClearAnsi(); - break; - } - count++; - continue; - - } - /*ansi.esc and ansi.sci are true */ - switch(data[count]){ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - ansi.data[ansi.numberofarg]=10*ansi.data[ansi.numberofarg]+(data[count]-'0'); - break; - case ';': /* till a max of NUMBER_ANSI_DATA */ - ansi.numberofarg++; - break; - case 'm': /* SGR */ - for(i=0;i<=ansi.numberofarg;i++){ + switch(data[count]){ + case '[': + ansi.sci=true; + break; + case '7': /* save cursor pos +attr */ + case '8': /* restore this (Wonder if this is actually used) */ + case 'D':/* scrolling DOWN*/ + case 'M':/* scrolling UP*/ + default: + LOG(LOG_IOCTL,LOG_NORMAL)("ANSI: unknown char %c after a esc",data[count]); /*prob () */ + ClearAnsi(); + break; + } + count++; + continue; + } + /*ansi.esc and ansi.sci are true */ + switch(data[count]){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + ansi.data[ansi.numberofarg]=10*ansi.data[ansi.numberofarg]+(data[count]-'0'); + break; + case ';': /* till a max of NUMBER_ANSI_DATA */ + ansi.numberofarg++; + break; + case 'm': /* SGR */ + for(i=0;i<=ansi.numberofarg;i++){ ansi.enabled=true; - switch(ansi.data[i]){ - case 0: /* normal */ - ansi.attr=0x7; + switch(ansi.data[i]){ + case 0: /* normal */ + ansi.attr=0x07;//Real ansi does this as well. (should do current defaults) ansi.enabled=false; - break; - case 1: /* bold mode on*/ - ansi.attr|=0x8; - break; - case 4: /* underline */ - LOG(LOG_IOCTL,LOG_NORMAL)("ANSI:no support for underline yet"); - break; - case 5: /* blinking */ - LOG(LOG_IOCTL,LOG_NORMAL)("ANSI:no support for blinking yet"); - break; - case 7: /* reverse */ - LOG(LOG_IOCTL,LOG_NORMAL)("ANSI:no support for reverse yet"); - break; - case 30: /* fg color black */ - ansi.attr&=0xf8; - ansi.attr|=0x0; - break; - case 31: /* fg color red */ - ansi.attr&=0xf8; - ansi.attr|=0x4; - break; - case 32: /* fg color green */ - ansi.attr&=0xf8; - ansi.attr|=0x2; - break; - case 33: /* fg color yellow */ - ansi.attr&=0xf8; - ansi.attr|=0x6; - break; - case 34: /* fg color blue */ - ansi.attr&=0xf8; - ansi.attr|=0x1; - break; - case 35: /* fg color magenta */ - ansi.attr&=0xf8; - ansi.attr|=0x5; - break; - case 36: /* fg color cyan */ - ansi.attr&=0xf8; - ansi.attr|=0x3; - break; - case 37: /* fg color white */ - ansi.attr&=0xf8; - ansi.attr|=0x7; - break; - case 40: - ansi.attr&=0x8f; - ansi.attr|=0x0; - break; - case 41: - ansi.attr&=0x8f; - ansi.attr|=0x40; - break; - case 42: - ansi.attr&=0x8f; - ansi.attr|=0x20; - break; - case 43: - ansi.attr&=0x8f; - ansi.attr|=0x60; - break; - case 44: - ansi.attr&=0x8f; - ansi.attr|=0x10; - break; - case 45: - ansi.attr&=0x8f; - ansi.attr|=0x50; - break; - case 46: - ansi.attr&=0x8f; - ansi.attr|=0x30; - break; - case 47: - ansi.attr&=0x8f; - ansi.attr|=0x70; - break; - default: - break; + break; + case 1: /* bold mode on*/ + ansi.attr|=0x08; + break; + case 4: /* underline */ + LOG(LOG_IOCTL,LOG_NORMAL)("ANSI:no support for underline yet"); + break; + case 5: /* blinking */ + ansi.attr|=0x80; + break; + case 7: /* reverse */ + ansi.attr=0x70;//Just like real ansi. (should do use current colors reversed) + break; + case 30: /* fg color black */ + ansi.attr&=0xf8; + ansi.attr|=0x0; + break; + case 31: /* fg color red */ + ansi.attr&=0xf8; + ansi.attr|=0x4; + break; + case 32: /* fg color green */ + ansi.attr&=0xf8; + ansi.attr|=0x2; + break; + case 33: /* fg color yellow */ + ansi.attr&=0xf8; + ansi.attr|=0x6; + break; + case 34: /* fg color blue */ + ansi.attr&=0xf8; + ansi.attr|=0x1; + break; + case 35: /* fg color magenta */ + ansi.attr&=0xf8; + ansi.attr|=0x5; + break; + case 36: /* fg color cyan */ + ansi.attr&=0xf8; + ansi.attr|=0x3; + break; + case 37: /* fg color white */ + ansi.attr&=0xf8; + ansi.attr|=0x7; + break; + case 40: + ansi.attr&=0x8f; + ansi.attr|=0x0; + break; + case 41: + ansi.attr&=0x8f; + ansi.attr|=0x40; + break; + case 42: + ansi.attr&=0x8f; + ansi.attr|=0x20; + break; + case 43: + ansi.attr&=0x8f; + ansi.attr|=0x60; + break; + case 44: + ansi.attr&=0x8f; + ansi.attr|=0x10; + break; + case 45: + ansi.attr&=0x8f; + ansi.attr|=0x50; + break; + case 46: + ansi.attr&=0x8f; + ansi.attr|=0x30; + break; + case 47: + ansi.attr&=0x8f; + ansi.attr|=0x70; + break; + default: + break; + } + } + ClearAnsi(); + break; + case 'f': + case 'H':/* Cursor Pos*/ + if(ansi.data[0]==0) ansi.data[0]=1; + if(ansi.data[1]==0) ansi.data[1]=1; + INT10_SetCursorPos(--(ansi.data[0]),--(ansi.data[1]),0); /*ansi=1 based, int10 is 0 based */ + ClearAnsi(); + break; - } - } - ClearAnsi(); - break; - case 'f': - case 'H':/* Cursor Pos*/ - if(ansi.data[0]==0) ansi.data[0]=1; - if(ansi.data[1]==0) ansi.data[1]=1; - INT10_SetCursorPos(--(ansi.data[0]),--(ansi.data[1]),0); /*ansi=1 based, int10 is 0 based */ - ClearAnsi(); - break; /* cursor up down and forward and backward only change the row or the col not both */ - case 'A': /* cursor up*/ - col=CURSOR_POS_COL(0) ; - row=CURSOR_POS_ROW(0) ; + case 'A': /* cursor up*/ + col=CURSOR_POS_COL(0) ; + row=CURSOR_POS_ROW(0) ; tempdata = (ansi.data[0]? ansi.data[0] : 1); - if(tempdata > row) - { row=0; } - else - { row-=tempdata;} + if(tempdata > row) { row=0; } + else { row-=tempdata;} INT10_SetCursorPos(row,col,0); - ClearAnsi(); - break; + ClearAnsi(); + break; case 'B': /*cursor Down */ col=CURSOR_POS_COL(0) ; - row=CURSOR_POS_ROW(0) ; + row=CURSOR_POS_ROW(0) ; tempdata = (ansi.data[0]? ansi.data[0] : 1); if(tempdata + static_cast(row) >= ansi.nrows) - { row = ansi.nrows - 1;} - else - { row += tempdata; } - INT10_SetCursorPos(row,col,0); - ClearAnsi(); + { row = ansi.nrows - 1;} + else { row += tempdata; } + INT10_SetCursorPos(row,col,0); + ClearAnsi(); break; - case 'C': /*cursor forward */ - col=CURSOR_POS_COL(0); + case 'C': /*cursor forward */ + col=CURSOR_POS_COL(0); row=CURSOR_POS_ROW(0); - tempdata=(ansi.data[0]? ansi.data[0] : 1); - if(tempdata + static_cast(col) >= ansi.ncols) - { col = ansi.ncols - 1;} - else - { col += tempdata;} - INT10_SetCursorPos(row,col,0); - ClearAnsi(); - break; - case 'D': /*Cursor Backward */ - col=CURSOR_POS_COL(0); - row=CURSOR_POS_ROW(0); tempdata=(ansi.data[0]? ansi.data[0] : 1); - if(tempdata > col) - {col = 0;} - else - { col -= tempdata;} - INT10_SetCursorPos(row,col,0); - ClearAnsi(); - break; - case 'J': /*erase screen and move cursor home*/ - if(ansi.data[0]==0) ansi.data[0]=2; - if(ansi.data[0]!=2) {/* only number 2 (the standard one supported) */ - LOG(LOG_IOCTL,LOG_NORMAL)("ANSI: esc[%dJ called : not supported",ansi.data[0]); - break; - } - for(i=0;i<(Bitu)ansi.ncols*ansi.nrows;i++) INT10_TeletypeOutputAttr(' ',ansi.attr,true); - ClearAnsi(); - INT10_SetCursorPos(0,0,0); - break; - case 'h': /* set MODE (if code =7 enable linewrap) */ - case 'I': /*RESET MODE */ - LOG(LOG_IOCTL,LOG_NORMAL)("ANSI: set/reset mode called(not supported)"); - ClearAnsi(); - break; - case 'u': /* Restore Cursor Pos */ - INT10_SetCursorPos(ansi.saverow,ansi.savecol,0); - ClearAnsi(); - break; - case 's': /* SAVE CURSOR POS */ - ansi.savecol=CURSOR_POS_COL(0); - ansi.saverow=CURSOR_POS_ROW(0); - ClearAnsi(); - break; - case 'K':/* erase till end of line */ - for(i = CURSOR_POS_COL(0);i<(Bitu) ansi.ncols; i++) INT10_TeletypeOutputAttr(' ',ansi.attr,true); - ClearAnsi(); /* maybe set cursor back to starting place ???? */ + if(tempdata + static_cast(col) >= ansi.ncols) + { col = ansi.ncols - 1;} + else { col += tempdata;} + INT10_SetCursorPos(row,col,0); + ClearAnsi(); break; - case 'l':/* (if code =7) disable linewrap */ - case 'p':/* reassign keys (needs strings) */ - case 'i':/* printer stuff */ - default: - LOG(LOG_IOCTL,LOG_NORMAL)("ANSI: unhandled char %c in esc[",data[count]); - ClearAnsi(); - break; - } - count++; + case 'D': /*Cursor Backward */ + col=CURSOR_POS_COL(0); + row=CURSOR_POS_ROW(0); + tempdata=(ansi.data[0]? ansi.data[0] : 1); + if(tempdata > col) {col = 0;} + else { col -= tempdata;} + INT10_SetCursorPos(row,col,0); + ClearAnsi(); + break; + case 'J': /*erase screen and move cursor home*/ + if(ansi.data[0]==0) ansi.data[0]=2; + if(ansi.data[0]!=2) {/* only number 2 (the standard one supported) */ + LOG(LOG_IOCTL,LOG_NORMAL)("ANSI: esc[%dJ called : not supported",ansi.data[0]); + break; + } + for(i=0;i<(Bitu)ansi.ncols*ansi.nrows;i++) INT10_TeletypeOutputAttr(' ',ansi.attr,true); + ClearAnsi(); + INT10_SetCursorPos(0,0,0); + break; + case 'h': /* set MODE (if code =7 enable linewrap) */ + case 'I': /*RESET MODE */ + LOG(LOG_IOCTL,LOG_NORMAL)("ANSI: set/reset mode called(not supported)"); + ClearAnsi(); + break; + case 'u': /* Restore Cursor Pos */ + INT10_SetCursorPos(ansi.saverow,ansi.savecol,0); + ClearAnsi(); + break; + case 's': /* SAVE CURSOR POS */ + ansi.savecol=CURSOR_POS_COL(0); + ansi.saverow=CURSOR_POS_ROW(0); + ClearAnsi(); + break; + case 'K':/* erase till end of line */ + for(i = CURSOR_POS_COL(0);i<(Bitu) ansi.ncols; i++) INT10_TeletypeOutputAttr(' ',ansi.attr,true); + ClearAnsi(); /* maybe set cursor back to starting place ???? */ + break; + case 'l':/* (if code =7) disable linewrap */ + case 'p':/* reassign keys (needs strings) */ + case 'i':/* printer stuff */ + default: + LOG(LOG_IOCTL,LOG_NORMAL)("ANSI: unhandled char %c in esc[",data[count]); + ClearAnsi(); + break; + } + count++; } *size=count; return true; @@ -372,22 +359,18 @@ Bit16u device_CON::GetInformation(void) { device_CON::device_CON() { name="CON"; cache=0; - ansi.esc=false; - ansi.sci=false; ansi.enabled=false; - ansi.attr=0x7; - ansi.numberofarg=0; - for(Bit8u i=0; i Date: Thu, 26 Aug 2004 19:43:46 +0000 Subject: [PATCH 1845/4131] Change color 6 in palet. Fixes bug 998455 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1927 --- src/ints/int10_modes.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 8732f5bf..795e07f1 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -583,6 +583,7 @@ att_text16: att_data[i]=i; att_data[i+8]=i+0x38; } + att_data[0x06]=0x14; //Odd Color 6 yellow/brown. break; case M_CGA2: att_data[0x10]=0x01; //Color Graphics From 89bb2a37ccda4187ae6181632acb02689b5dc823 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 26 Aug 2004 19:49:26 +0000 Subject: [PATCH 1846/4131] Fixed colors. spaces2tabs Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1928 --- src/shell/shell.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 428555dc..2b25e857 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.44 2004-08-04 13:15:56 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.45 2004-08-26 19:49:26 qbix79 Exp $ */ #include #include @@ -286,7 +286,7 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_DIR_INTRO","Directory of %s.\n"); MSG_Add("SHELL_CMD_DIR_BYTES_USED","%5d File(s) %17s Bytes\n"); MSG_Add("SHELL_CMD_DIR_BYTES_FREE","%5d Dir(s) %17s Bytes free\n"); - MSG_Add("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\nYou must mount it first. Type intro for more information.\n"); + MSG_Add("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\nYou must mount it first. Type intro for more information.\n"); MSG_Add("SHELL_EXECUTE_ILLEGAL_COMMAND","Illegal command: %s.\n"); MSG_Add("SHELL_CMD_PAUSE","Press any key to continue.\n"); MSG_Add("SHELL_CMD_PAUSE_HELP","Waits for 1 keystroke to continue.\n"); @@ -297,26 +297,26 @@ void SHELL_Init() { MSG_Add("SHELL_STARTUP","DOSBox Shell v" VERSION "\n" "This version runs some protected mode games!\n" - "For supported shell commands type: HELP\n" - "For a short introduction type: INTRO\n\n" + "For supported shell commands type: HELP\n" + "For a short introduction type: INTRO\n\n" "If you want more speed, try ctrl-F8 and ctrl-F12.\n" "For more information read the README file in DOSBox directory.\n" "\nHAVE FUN!\nThe DOSBox Team\n\n" ); MSG_Add("SHELL_CMD_CHDIR_HELP","Change Directory.\n"); - MSG_Add("SHELL_CMD_CLS_HELP","Clear screen.\n"); - MSG_Add("SHELL_CMD_DIR_HELP","Directory View.\n"); - MSG_Add("SHELL_CMD_ECHO_HELP","Display messages and enable/disable command echoing.\n"); - MSG_Add("SHELL_CMD_EXIT_HELP","Exit from the shell.\n"); - MSG_Add("SHELL_CMD_HELP_HELP","Show help.\n"); - MSG_Add("SHELL_CMD_MKDIR_HELP","Make Directory.\n"); - MSG_Add("SHELL_CMD_RMDIR_HELP","Remove Directory.\n"); - MSG_Add("SHELL_CMD_SET_HELP","Change environment variables.\n"); - MSG_Add("SHELL_CMD_IF_HELP","Performs conditional processing in batch programs.\n"); - MSG_Add("SHELL_CMD_GOTO_HELP","Jump to a labeled line in a batch script.\n"); - MSG_Add("SHELL_CMD_TYPE_HELP","Display the contents of a text-file.\n"); - MSG_Add("SHELL_CMD_REM_HELP","Add comments in a batch file.\n"); + MSG_Add("SHELL_CMD_CLS_HELP","Clear screen.\n"); + MSG_Add("SHELL_CMD_DIR_HELP","Directory View.\n"); + MSG_Add("SHELL_CMD_ECHO_HELP","Display messages and enable/disable command echoing.\n"); + MSG_Add("SHELL_CMD_EXIT_HELP","Exit from the shell.\n"); + MSG_Add("SHELL_CMD_HELP_HELP","Show help.\n"); + MSG_Add("SHELL_CMD_MKDIR_HELP","Make Directory.\n"); + MSG_Add("SHELL_CMD_RMDIR_HELP","Remove Directory.\n"); + MSG_Add("SHELL_CMD_SET_HELP","Change environment variables.\n"); + MSG_Add("SHELL_CMD_IF_HELP","Performs conditional processing in batch programs.\n"); + MSG_Add("SHELL_CMD_GOTO_HELP","Jump to a labeled line in a batch script.\n"); + MSG_Add("SHELL_CMD_TYPE_HELP","Display the contents of a text-file.\n"); + MSG_Add("SHELL_CMD_REM_HELP","Add comments in a batch file.\n"); MSG_Add("SHELL_CMD_NO_WILD","This is a simple version of the command, no wildcards allowed!\n"); MSG_Add("SHELL_CMD_RENAME_HELP","Renames files.\n"); MSG_Add("SHELL_CMD_DELETE_HELP","Removes files.\n"); @@ -325,7 +325,7 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_SUBST_HELP","Assign an internal directory to a drive\n"); MSG_Add("SHELL_CMD_LOADHIGH_HELP","Run a program. For batch file compatibility only.\n"); - /* Regular startup */ + /* Regular startup */ call_shellstop=CALLBACK_Allocate(); /* Setup the startup CS:IP to kill the last running machine when exitted */ RealPt newcsip=CALLBACK_RealPointer(call_shellstop); From 98254ac2095acbf3bee9cc954703f9da18d94d38 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 27 Aug 2004 13:32:52 +0000 Subject: [PATCH 1847/4131] Change check for setpriority slightly Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1929 --- configure.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.in b/configure.in index c7325bef..c7820e4d 100644 --- a/configure.in +++ b/configure.in @@ -187,14 +187,14 @@ else AC_MSG_WARN([Can't find libSDL_sound, libSDL_sound support disabled]) fi -AH_TEMPLATE(C_PRIORITY_NICE,[Define to 1 if you have nice priority changing support]) -AC_MSG_CHECKING(for nice priority changing) +AH_TEMPLATE(C_SET_PRIORITY,[Define to 1 if you have setpriority support]) +AC_MSG_CHECKING(for setpriority support) AC_LINK_IFELSE([ #include int main(int argc,char * argv[]) { - return nice(10); + return setpriority (PRIO_PROCESS, 0,PRIO_MIN+PRIO_MAX); }; -],AC_MSG_RESULT(yes);AC_DEFINE(C_PRIORITY_NICE,1),AC_MSG_RESULT(no)) +],AC_MSG_RESULT(yes);AC_DEFINE(C_SET_PRIORITY,1),AC_MSG_RESULT(no)) dnl Some host detection and actions for them From 069753046f91b10a35de9164986b9ae8c5c71bfd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 27 Aug 2004 13:41:34 +0000 Subject: [PATCH 1848/4131] Add different priority levels for focused and non focused mode Add priority support for non-win32 Fix ddraw output fullscreen window positioning Fix ddraw also supporting double buffering. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1930 --- src/gui/sdlmain.cpp | 140 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 116 insertions(+), 24 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 9b81b2ee..a9516226 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.72 2004-08-19 10:18:11 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.73 2004-08-27 13:41:34 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -83,7 +83,6 @@ PFNGLPIXELDATARANGENVPROC glPixelDataRangeNV = NULL; #endif //C_OPENGL - #if !(ENVIRON_INCLUDED) extern char** environ; #endif @@ -110,6 +109,11 @@ struct private_hwdata { #define DEFAULT_CONFIG_FILE "/.dosboxrc" #endif +#if C_SET_PRIORITY +#include +#define PRIO_TOTAL (PRIO_MAX-PRIO_MIN) +#endif + void MAPPER_Init(void); void MAPPER_StartUp(Section * sec); @@ -120,6 +124,13 @@ enum SCREEN_TYPES { SCREEN_OPENGL }; +enum PRIORITY_LEVELS { + PRIORITY_LEVEL_LOWER, + PRIORITY_LEVEL_NORMAL, + PRIORITY_LEVEL_HIGHER, + PRIORITY_LEVEL_HIGHEST +}; + struct SDL_Block { bool active; //If this isn't set don't draw @@ -161,8 +172,13 @@ struct SDL_Block { struct { SDL_Surface * surface; RECT rect; + DDBLTFX fx; } blit; #endif + struct { + PRIORITY_LEVELS focus; + PRIORITY_LEVELS nofocus; + } priority; SDL_Rect clip; SDL_Surface * surface; SDL_Overlay * overlay; @@ -250,6 +266,7 @@ check_gotbpp: if (!(flags&CAN_32|CAN_16)) goto check_surface; if (flags & LOVE_16) testbpp=16; else if (flags & LOVE_32) testbpp=32; + else testbpp=0; flags|=HAVE_SCALING; goto check_gotbpp; #endif @@ -365,11 +382,13 @@ dosurface: SDL_FreeSurface(sdl.blit.surface); sdl.blit.surface=0; } - if (!GFX_SetupSurfaceScaled(0,bpp)) goto dosurface; - sdl.blit.rect.top=sdl.clip.x; - sdl.blit.rect.left=sdl.clip.y; - sdl.blit.rect.right=sdl.clip.x+sdl.clip.w-1; - sdl.blit.rect.bottom=sdl.clip.y+sdl.clip.h-1; + memset(&sdl.blit.fx,0,sizeof(DDBLTFX)); + sdl.blit.fx.dwSize=sizeof(DDBLTFX); + if (!GFX_SetupSurfaceScaled((sdl.desktop.doublebuf && sdl.desktop.fullscreen) ? SDL_DOUBLEBUF : 0,bpp)) goto dosurface; + sdl.blit.rect.top=sdl.clip.y; + sdl.blit.rect.left=sdl.clip.x; + sdl.blit.rect.right=sdl.clip.x+sdl.clip.w; + sdl.blit.rect.bottom=sdl.clip.y+sdl.clip.h; sdl.blit.surface=SDL_CreateRGBSurface(SDL_HWSURFACE,sdl.draw.width,sdl.draw.height, sdl.surface->format->BitsPerPixel, sdl.surface->format->Rmask, @@ -537,7 +556,7 @@ bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) { case SCREEN_SURFACE: if (SDL_MUSTLOCK(sdl.surface)) { if (SDL_LockSurface(sdl.surface)) { - LOG_MSG("SDL Lock failed"); +// LOG_MSG("SDL Lock failed"); sdl.updating=false; return false; } @@ -550,7 +569,7 @@ bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) { #if defined(HAVE_DDRAW_H) && defined(WIN32) case SCREEN_SURFACE_DDRAW: if (SDL_LockSurface(sdl.blit.surface)) { - LOG_MSG("SDL Lock failed"); +// LOG_MSG("SDL Lock failed"); sdl.updating=false; return false; } @@ -574,6 +593,7 @@ bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) { } void GFX_EndUpdate(void) { + int ret; if (!sdl.updating) return; sdl.updating=false; switch (sdl.desktop.type) { @@ -588,10 +608,19 @@ void GFX_EndUpdate(void) { if (SDL_MUSTLOCK(sdl.blit.surface)) { SDL_UnlockSurface(sdl.blit.surface); } - IDirectDrawSurface3_Blt( - sdl.surface->hwdata->dd_surface,&sdl.blit.rect, + ret=IDirectDrawSurface3_Blt( + sdl.surface->hwdata->dd_writebuf,&sdl.blit.rect, sdl.blit.surface->hwdata->dd_surface,0, DDBLT_WAIT, NULL); + switch (ret) { + case DD_OK: + break; + case DDERR_SURFACELOST: + IDirectDrawSurface3_Restore(sdl.blit.surface->hwdata->dd_surface); + break; + default: + LOG_MSG("DDRAW:Failed to blit, error %X",ret); + } SDL_Flip(sdl.surface); break; #endif @@ -652,6 +681,7 @@ Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue) { } void GFX_Stop() { + if (sdl.updating) GFX_EndUpdate(); sdl.active=false; } @@ -670,6 +700,40 @@ static void KillSwitch(void){ throw 1; } +static void SetPriority(PRIORITY_LEVELS level) { + switch (level) { +#ifdef WIN32 + case PRIORITY_LEVEL_LOWER: + SetPriorityClass(GetCurrentProcess(),BELOW_NORMAL_PRIORITY_CLASS); + break; + case PRIORITY_LEVEL_NORMAL: + SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS); + break; + case PRIORITY_LEVEL_HIGHER: + SetPriorityClass(GetCurrentProcess(),ABOVE_NORMAL_PRIORITY_CLASS); + break; + case PRIORITY_LEVEL_HIGHEST: + SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS); + break; +#elif C_SET_PRIORITY + case PRIORITY_LEVEL_LOWER: + setpriority (PRIO_PROCESS, 0,PRIO_MIN+(PRIO_TOTAL/3)); + break; + case PRIORITY_LEVEL_NORMAL: + setpriority (PRIO_PROCESS, 0,PRIO_MIN+(PRIO_TOTAL/2)); + break; + case PRIORITY_LEVEL_HIGHER: + setpriority (PRIO_PROCESS, 0,PRIO_MIN+((3*PRIO_TOTAL)/5))); + break; + case PRIORITY_LEVEL_HIGHEST: + setpriority (PRIO_PROCESS, 0,PRIO_MIN+((3*PRIO_TOTAL)/4))); + break; +#endif + default: + break; + } +} + static void GUI_StartUp(Section * sec) { sec->AddDestroyFunction(&GUI_ShutDown); Section_prop * section=static_cast(sec); @@ -677,13 +741,38 @@ static void GUI_StartUp(Section * sec) { sdl.updating=false; sdl.desktop.fullscreen=section->Get_bool("fullscreen"); sdl.wait_on_error=section->Get_bool("waitonerror"); - if (section->Get_bool("highpriority")) { -#ifdef WIN32 - LOG_MSG("SEtting priority %d", - SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS) - ); -//TODO add more platforms, with configure checks for get/setpriority -#endif + const char * priority=section->Get_string("priority"); + if (priority && priority[0]) { + Bitu next; + if (!strncasecmp(priority,"lower",5)) { + sdl.priority.focus=PRIORITY_LEVEL_LOWER;next=5; + } else if (!strncasecmp(priority,"normal",6)) { + sdl.priority.focus=PRIORITY_LEVEL_NORMAL;next=6; + } else if (!strncasecmp(priority,"higher",6)) { + sdl.priority.focus=PRIORITY_LEVEL_HIGHER;next=6; + } else if (!strncasecmp(priority,"highest",7)) { + sdl.priority.focus=PRIORITY_LEVEL_HIGHEST;next=7; + } else { + next=0;sdl.priority.focus=PRIORITY_LEVEL_HIGHER; + } + priority=&priority[next]; + if (next && priority[0]==',' && priority[1]) { + priority++; + if (!strncasecmp(priority,"lower",5)) { + sdl.priority.nofocus=PRIORITY_LEVEL_LOWER; + } else if (!strncasecmp(priority,"normal",6)) { + sdl.priority.nofocus=PRIORITY_LEVEL_NORMAL; + } else if (!strncasecmp(priority,"higher",6)) { + sdl.priority.nofocus=PRIORITY_LEVEL_HIGHER; + } else if (!strncasecmp(priority,"highest",7)) { + sdl.priority.nofocus=PRIORITY_LEVEL_HIGHEST; + } else { + sdl.priority.nofocus=PRIORITY_LEVEL_NORMAL; + } + } else sdl.priority.nofocus=sdl.priority.focus; + } else { + sdl.priority.focus=PRIORITY_LEVEL_HIGHER; + sdl.priority.nofocus=PRIORITY_LEVEL_NORMAL; } sdl.mouse.locked=false; mouselocked=false; //Global for mapper @@ -834,9 +923,10 @@ void GFX_Events() { switch (event.type) { case SDL_ACTIVEEVENT: if (event.active.state & SDL_APPINPUTFOCUS) { - if (!event.active.gain && sdl.mouse.locked) { - CaptureMouse(); - } + if (event.active.gain) { + if (sdl.mouse.locked) CaptureMouse(); + SetPriority(sdl.priority.focus); + } else SetPriority(sdl.priority.nofocus); } break; case SDL_MOUSEMOTION: @@ -922,7 +1012,7 @@ int main(int argc, char* argv[]) { sdl_sec->Add_bool("autolock",true); sdl_sec->Add_int("sensitivity",100); sdl_sec->Add_bool("waitonerror",true); - sdl_sec->Add_bool("highpriority",true); + sdl_sec->Add_string("priority","higher,normal"); sdl_sec->Add_string("mapperfile","mapper.txt"); MSG_Add("SDL_CONFIGFILE_HELP", @@ -939,8 +1029,10 @@ int main(int argc, char* argv[]) { "autolock -- Mouse will automatically lock, if you click on the screen.\n" "sensitiviy -- Mouse sensitivity.\n" "waitonerror -- Wait before closing the console if dosbox has an error.\n" - "highpriority -- Run dosbox in high prioty, helps sound output alot.\n" - ); + "priority -- Priority levels for dosbox: lower,normal,higher,highest.\n" + " Second entry behind the comma is for when dosbox is not focused/minimized.\n" + "mapperfile -- File used to load/save the key/event mappings from.\n" + ); /* Init all the dosbox subsystems */ DOSBOX_Init(); std::string config_file; From 6f8e4600d362b8fed28cce9fd28252f8b98afe36 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 27 Aug 2004 14:01:44 +0000 Subject: [PATCH 1849/4131] Fix compilation under linux. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1931 --- src/gui/sdlmain.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index a9516226..e73d8003 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.73 2004-08-27 13:41:34 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.74 2004-08-27 14:01:44 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -723,10 +723,10 @@ static void SetPriority(PRIORITY_LEVELS level) { setpriority (PRIO_PROCESS, 0,PRIO_MIN+(PRIO_TOTAL/2)); break; case PRIORITY_LEVEL_HIGHER: - setpriority (PRIO_PROCESS, 0,PRIO_MIN+((3*PRIO_TOTAL)/5))); + setpriority (PRIO_PROCESS, 0,PRIO_MIN+((3*PRIO_TOTAL)/5) ); break; case PRIORITY_LEVEL_HIGHEST: - setpriority (PRIO_PROCESS, 0,PRIO_MIN+((3*PRIO_TOTAL)/4))); + setpriority (PRIO_PROCESS, 0,PRIO_MIN+((3*PRIO_TOTAL)/4) ); break; #endif default: From 39b528f97a342eabaaa4024e41d4f182de668ce4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 28 Aug 2004 12:51:35 +0000 Subject: [PATCH 1850/4131] Commit patch Gil Megidish. Modified it a bit to work in regular mode debug mode as well. (only updates on breakpoints though). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1932 --- src/debug/debug.cpp | 68 +++++++++++++++++++++++++++++++++-------- src/debug/debug_gui.cpp | 17 +++++++---- src/debug/debug_inc.h | 4 +++ 3 files changed, 71 insertions(+), 18 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index fc15273b..07eb4391 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.57 2004-08-04 09:12:53 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.58 2004-08-28 12:51:35 qbix79 Exp $ */ #include "programs.h" @@ -26,6 +26,7 @@ #include "dosbox.h" #if C_DEBUG #include "debug.h" +#include "cross.h" //snprintf #include "cpu.h" #include "video.h" #include "pic.h" @@ -53,13 +54,17 @@ int old_cursor_state; static void DrawCode(void); static bool DEBUG_Log_Loop(int count); static void DEBUG_RaiseTimerIrq(void); +static void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num); +static void LogGDT(void); +static void LogLDT(void); +static void LogIDT(void); +static void OutputVecTable(char* filename); +static void DrawVariables(void); + char* AnalyzeInstruction(char* inst, bool saveSelector); -void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num); Bit32u GetHexValue(char* str, char*& hex); -void LogGDT(void); -void LogLDT(void); -void LogIDT(void); -void OutputVecTable(char* filename); + + class DEBUG; @@ -67,6 +72,7 @@ DEBUG* pDebugcom = 0; bool exitLoop = false; bool logHeavy = false; + // Heavy Debugging Vars for logging #if C_HEAVY_DEBUG static FILE* cpuLogFile = 0; @@ -74,6 +80,8 @@ static bool cpuLog = false; static int cpuLogCounter = 0; #endif + + static struct { Bit32u eax,ebx,ecx,edx,esi,edi,ebp,esp,eip; } oldregs; @@ -86,6 +94,8 @@ DBGBlock dbg; static Bitu input_count; Bitu cycle_count; static bool debugging; + + static void SetColor(Bitu test) { if (test) { if (has_colors()) { wattrset(dbg.win_reg,COLOR_PAIR(PAIR_BYELLOW_BLACK));} @@ -572,6 +582,10 @@ static bool StepOver() bool DEBUG_ExitLoop(void) { +#if C_HEAVY_DEBUG + DrawVariables(); +#endif + if (exitLoop) { exitLoop = false; return true; @@ -1446,13 +1460,14 @@ void DEBUG_DrawScreen(void) { DrawData(); DrawCode(); DrawRegisters(); + DrawVariables(); } static void DEBUG_RaiseTimerIrq(void) { PIC_ActivateIRQ(0); } -void LogGDT(void) +static void LogGDT(void) { char out1[512]; Descriptor desc; @@ -1471,7 +1486,7 @@ void LogGDT(void) }; }; -void LogLDT(void) +static void LogLDT(void) { char out1[512]; Descriptor desc; @@ -1492,7 +1507,7 @@ void LogLDT(void) }; }; -void LogIDT(void) +static void LogIDT(void) { char out1[512]; Descriptor desc; @@ -1759,7 +1774,7 @@ bool CDebugVar::LoadVars(char* name) return true; }; -void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num) +static void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num) { FILE* f = fopen("MEMDUMP.TXT","wt"); if (!f) { @@ -1786,7 +1801,7 @@ void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num) DEBUG_ShowMsg("DEBUG: Memory dump success."); }; -void OutputVecTable(char* filename) +static void OutputVecTable(char* filename) { FILE* f = fopen(filename, "wt"); if (!f) @@ -1802,6 +1817,35 @@ void OutputVecTable(char* filename) DEBUG_ShowMsg("DEBUG: Interrupt vector table written to %s.", filename); } +#define DEBUG_VAR_BUF_LEN 16 +static void DrawVariables(void) +{ + std::list::iterator i; + CDebugVar *dv; + char buffer[DEBUG_VAR_BUF_LEN]; + + int idx = 0; + for(i=CDebugVar::varList.begin(); i != CDebugVar::varList.end(); i++, idx++) { + + if (idx == 4*3) { + /* too many variables */ + break; + } + + dv = static_cast(*i); + + Bit16u value = mem_readw(dv->GetAdr()); + snprintf(buffer,DEBUG_VAR_BUF_LEN, "0x%04x", value); + + int y = idx / 3; + int x = (idx % 3) * 26; + mvwprintw(dbg.win_var, y, x, dv->GetName()); + mvwprintw(dbg.win_var, y, (x + DEBUG_VAR_BUF_LEN + 1) , buffer); + } + + wrefresh(dbg.win_var); +} +#undef DEBUG_VAR_BUF_LEN // HEAVY DEBUGGING STUFF #if C_HEAVY_DEBUG @@ -1882,9 +1926,9 @@ bool DEBUG_HeavyIsBreakpoint(void) } return false; }; - #endif // HEAVY DEBUG + #endif // DEBUG diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index ab3998f0..268fecfa 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -53,7 +53,7 @@ void DEBUG_ShowMsg(char * format,...) { va_end(msg); wprintw(dbg.win_out,"%10d: %s\n",cycle_count,buf); wrefresh(dbg.win_out); - if(debuglog) fprintf(debuglog,"%10d: %s\n",cycle_count,buf); + if(debuglog) fprintf(debuglog,"%10d: %s\n",cycle_count,buf); } void LOG::operator() (char* format, ...){ @@ -99,13 +99,15 @@ static void DrawBars(void) { attrset(COLOR_PAIR(PAIR_BLACK_BLUE)); } /* Show the Register bar */ - mvaddstr(dbg.win_reg->_begy-1,0,"---[F1](Register Overview)---"); + mvaddstr(dbg.win_reg->_begy-1,0,"---(Register Overview)---"); /* Show the Data Overview bar perhaps with more special stuff in the end */ - mvaddstr(dbg.win_data->_begy-1,0,"---[F2](Data Overview)---"); + mvaddstr(dbg.win_data->_begy-1,0,"---(Data Overview)---"); /* Show the Code Overview perhaps with special stuff in bar too */ - mvaddstr(dbg.win_code->_begy-1,0,"---[F3](Code Overview)---"); + mvaddstr(dbg.win_code->_begy-1,0,"---(Code Overview)---"); + /* Show the Variable Overview bar */ + mvaddstr(dbg.win_var->_begy-1,0,"---(Variable Overview)---"); /* Show the Output OverView */ - mvaddstr(dbg.win_out->_begy-1,0,"---[F4](OutPut/Input)---"); + mvaddstr(dbg.win_out->_begy-1,0,"---(OutPut/Input)---"); attrset(0); } @@ -124,7 +126,10 @@ static void MakeSubWindows(void) { /* The Code Window */ dbg.win_code=subwin(dbg.win_main,11,dbg.win_main->_maxx,outy,0); outy+=12; - /* The output Window */ + /* The Variable Window */ + dbg.win_var=subwin(dbg.win_main,4,dbg.win_main->_maxx,outy,0); + outy+=5; + /* The Output Window */ dbg.win_out=subwin(dbg.win_main,dbg.win_main->_maxy-outy-1,dbg.win_main->_maxx,outy,0); dbg.input_y=dbg.win_main->_maxy-1; scrollok(dbg.win_out,TRUE); diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h index 378b2df0..0435a515 100644 --- a/src/debug/debug_inc.h +++ b/src/debug/debug_inc.h @@ -17,6 +17,9 @@ */ /* Local Debug Function */ + +/* $Id: debug_inc.h,v 1.8 2004-08-28 12:51:35 qbix79 Exp $ */ + #include #include "mem.h" @@ -34,6 +37,7 @@ struct DBGBlock { WINDOW * win_reg; /* Register Window */ WINDOW * win_data; /* Data Output window */ WINDOW * win_code; /* Disassembly/Debug point Window */ + WINDOW * win_var; /* Variable Window */ WINDOW * win_out; /* Text Output Window */ Bit32u active_win; /* Current active window */ Bit32u input_y; From 2c0338404b0633274a4eee24bec3a154c2ffac62 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 29 Aug 2004 11:22:37 +0000 Subject: [PATCH 1851/4131] Added some callback information for the lower numbers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1933 --- src/cpu/callback.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 55687744..87aaa4ac 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.21 2004-08-04 09:12:51 qbix79 Exp $ */ +/* $Id: callback.cpp,v 1.22 2004-08-29 11:22:37 qbix79 Exp $ */ #include #include @@ -203,12 +203,14 @@ void CALLBACK_Init(Section* sec) { /* Setup the Stop Handler */ call_stop=CALLBACK_Allocate(); CallBack_Handlers[call_stop]=stop_handler; + CALLBACK_SetDescription(call_stop,"stop"); phys_writeb(CB_BASE+(call_stop<<4)+0,0xFE); phys_writeb(CB_BASE+(call_stop<<4)+1,0x38); phys_writew(CB_BASE+(call_stop<<4)+2,call_stop); /* Setup the idle handler */ call_idle=CALLBACK_Allocate(); CallBack_Handlers[call_idle]=stop_handler; + CALLBACK_SetDescription(call_idle,"idle"); for (i=0;i<=11;i++) phys_writeb(CB_BASE+(call_idle<<4)+i,0x90); phys_writeb(CB_BASE+(call_idle<<4)+12,0xFE); phys_writeb(CB_BASE+(call_idle<<4)+13,0x38); @@ -216,7 +218,7 @@ void CALLBACK_Init(Section* sec) { /* Setup all Interrupt to point to the default handler */ call_default=CALLBACK_Allocate(); - CALLBACK_Setup(call_default,&default_handler,CB_IRET); + CALLBACK_Setup(call_default,&default_handler,CB_IRET,"default"); /* Only setup default handler for first half of interrupt table */ for (i=0;i<0x40;i++) { real_writed(0,i*4,CALLBACK_RealPointer(call_default)); From f20a8594a8f10eedaef48107e8ec50d5af584c25 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 31 Aug 2004 15:56:10 +0000 Subject: [PATCH 1852/4131] Don't reset the current timer when programming a new unless it's a mode 0 timer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1934 --- src/hardware/timer.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 6a37be6f..4f5d675b 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.26 2004-08-04 09:12:56 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.27 2004-08-31 15:56:10 harekiet Exp $ */ #include "dosbox.h" #include "inout.h" @@ -36,6 +36,8 @@ static INLINE void BCD2BIN(Bit16u& val) { Bit16u temp= (val&0x0f) +((val>>4)&0x0f) *10 +((val>>8)&0x0f) *100 +((val>>12)&0x0f) *1000; val=temp; } + +static bool pit0_scheduled; struct PIT_Block { Bit8u mode; /* Current Counter Mode */ @@ -48,15 +50,17 @@ struct PIT_Block { Bit16u read_latch; Bit8u write_state; Bit16u write_latch; - bool bcd; - bool go_read_latch; + bool bcd; + bool go_read_latch; }; static PIT_Block pit[3]; static void PIT0_Event(Bitu val) { PIC_ActivateIRQ(0); - if (pit[0].mode!=0) PIC_AddEvent(PIT0_Event,pit[0].micro); + if (pit[0].mode!=0) { + PIC_AddEvent(PIT0_Event,pit[0].micro); + } else pit0_scheduled=false; } static void counter_latch(Bitu counter) { @@ -121,19 +125,22 @@ static void write_latch(Bitu port,Bitu val,Bitu iolen) { p->write_latch = (val & 0xff) << 8; break; } - if(p->bcd==true) BCD2BIN(p->write_latch); - - if (p->write_state != 0) { + if (p->bcd==true) BCD2BIN(p->write_latch); + if (p->write_state != 0) { if (p->write_latch == 0) { - if(p->bcd == false) {p->cntr = 0x10000;} else {p->cntr=9999;} + if (p->bcd == false) p->cntr = 0x10000; + else p->cntr=9999; } else p->cntr = p->write_latch; p->start=PIC_MicroCount(); p->micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)p->cntr)); if (!p->micro) p->micro=1; switch (counter) { case 0x00: /* Timer hooked to IRQ 0 */ - PIC_RemoveEvents(PIT0_Event); - PIC_AddEvent(PIT0_Event,p->micro); + if (!p->mode || !pit0_scheduled) { + pit0_scheduled=true; + PIC_RemoveEvents(PIT0_Event); + PIC_AddEvent(PIT0_Event,p->micro); + } LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,(Bit32u)p->mode); break; case 0x02: /* Timer hooked to PC-Speaker */ @@ -253,6 +260,7 @@ void TIMER_Init(Section* sect) { pit[1].micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)pit[1].cntr)); pit[2].micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)pit[2].cntr)); + pit0_scheduled=true; PIC_AddEvent(PIT0_Event,pit[0].micro); } From eb6687ab52317161dee99e960d5d8142f718f77e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 31 Aug 2004 23:11:35 +0000 Subject: [PATCH 1853/4131] Call delay while waiting for input in the debug loop Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1935 --- src/debug/debug.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 07eb4391..4ac98ebc 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,9 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.58 2004-08-28 12:51:35 qbix79 Exp $ */ - -#include "programs.h" +/* $Id: debug.cpp,v 1.59 2004-08-31 23:11:35 harekiet Exp $ */ #include #include @@ -35,11 +33,12 @@ #include "callback.h" #include "inout.h" #include "mixer.h" -#include "debug_inc.h" #include "timer.h" #include "paging.h" -#include "../ints/xms.h" +#include "support.h" #include "shell.h" +#include "programs.h" +#include "debug_inc.h" #ifdef WIN32 void WIN32_Console(); @@ -1438,6 +1437,7 @@ Bitu DEBUG_Loop(void) { Bit16u oldCS = SegValue(cs); Bit32u oldEIP = reg_eip; PIC_runIRQs(); + SDL_Delay(1); if ((oldCS!=SegValue(cs)) || (oldEIP!=reg_eip)) { CBreakpoint::AddBreakpoint(oldCS,oldEIP,true); CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); From ea922b767a4ec3b1eb2179251d45559d90ec31bb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 1 Sep 2004 06:46:49 +0000 Subject: [PATCH 1854/4131] fix mouse not unlocking when losing focus Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1936 --- src/gui/sdlmain.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index e73d8003..0951c7de 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.74 2004-08-27 14:01:44 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.75 2004-09-01 06:46:49 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -924,9 +924,14 @@ void GFX_Events() { case SDL_ACTIVEEVENT: if (event.active.state & SDL_APPINPUTFOCUS) { if (event.active.gain) { - if (sdl.mouse.locked) CaptureMouse(); + if (sdl.desktop.fullscreen && !sdl.mouse.locked) + CaptureMouse(); SetPriority(sdl.priority.focus); - } else SetPriority(sdl.priority.nofocus); + } else { + if (sdl.mouse.locked) + CaptureMouse(); + SetPriority(sdl.priority.nofocus); + } } break; case SDL_MOUSEMOTION: From 7fcfb7d2bc0265834dfeb3a8cb2c9a1035f877a8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 3 Sep 2004 05:10:16 +0000 Subject: [PATCH 1855/4131] Fix setting dac color entries with the high bits not getting cleared before adding color select bits. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1937 --- src/hardware/vga_attr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index d97fbc59..344c91fe 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -24,7 +24,7 @@ void VGA_ATTR_SetPalette(Bit8u index,Bit8u val) { if (vga.attr.mode_control & 0x80) val=(val&0xf) | (vga.attr.color_select << 4); - else val|=(vga.attr.color_select & 0xc) << 4; + else val=(val & 63) | (vga.attr.color_select & 0xc) << 4; VGA_DAC_CombineColor(index,val); } From 4812b35a8245604006ab0df6e3f3a9538ac5efa2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 3 Sep 2004 05:17:39 +0000 Subject: [PATCH 1856/4131] Precache a bit of sound if some game masks the dma channel halfway through a transfer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1938 --- src/hardware/sblaster.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 2dc8dd34..0c316a12 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -62,7 +62,10 @@ enum SB_IRQS {SB_IRQ_8,SB_IRQ_16,SB_IRQ_MPU}; enum DSP_MODES { MODE_NONE, MODE_DAC, - MODE_DMA,MODE_DMA_PAUSE + MODE_DMA, + MODE_DMA_PAUSE, + MODE_DMA_MASKED + }; enum DMA_MODES { @@ -189,6 +192,7 @@ static void DSP_ChangeMode(DSP_MODES mode); static void CheckDMAEnd(); static void END_DMA_Event(Bitu); static void DMA_Silent_Event(Bitu val); +static void GenerateDMASound(Bitu size); static void DSP_SetSpeaker(bool how) { if (sb.speaker==how) return; @@ -224,15 +228,17 @@ static void DSP_DMA_CallBack(DmaChannel * chan, DMAEvent event) { if (event==DMA_REACHED_TC) return; else if (event==DMA_MASKED) { if (sb.mode==MODE_DMA) { - sb.mode=MODE_DMA_PAUSE; -// DSP_ChangeMode(MODE_DMA_PAUSE); - LOG(LOG_SB,LOG_NORMAL)("DMA masked,stopping output"); + GenerateDMASound(sb.dma.min); + sb.mode=MODE_DMA_MASKED; +// DSP_ChangeMode(MODE_DMA_MASKED); + LOG(LOG_SB,LOG_NORMAL)("DMA masked,stopping output, left %d",chan->currcnt); } } else if (event==DMA_UNMASKED) { - if (sb.mode==MODE_DMA_PAUSE && sb.dma.mode!=DSP_DMA_NONE) { + if (sb.mode==MODE_DMA_MASKED && sb.dma.mode!=DSP_DMA_NONE) { DSP_ChangeMode(MODE_DMA); +// sb.mode=MODE_DMA; CheckDMAEnd(); - LOG(LOG_SB,LOG_NORMAL)("DMA unmasked,starting output, auto %d block %X",chan->autoinit,chan->basecnt); + LOG(LOG_SB,LOG_NORMAL)("DMA unmasked,starting output, auto %d block %d",chan->autoinit,chan->basecnt); } } } @@ -378,6 +384,7 @@ static void GenerateDMASound(Bitu size) { if (!sb.dma.left) { PIC_RemoveEvents(END_DMA_Event); if (!sb.dma.autoinit) { + LOG(LOG_SB,LOG_NORMAL)("Single cycle transfer ended"); sb.mode=MODE_NONE; sb.dma.mode=DSP_DMA_NONE; } @@ -454,7 +461,7 @@ static void DSP_RaiseIRQEvent(Bitu val) { static void DSP_DoDMATranfser(DMA_MODES mode,Bitu freq,bool stereo) { char * type; - sb.mode=MODE_DMA_PAUSE; + sb.mode=MODE_DMA_MASKED; sb.chan->FillUp(); sb.dma.left=sb.dma.total; sb.dma.mode=mode; @@ -970,6 +977,7 @@ static void SBLASTER_CallBack(Bitu len) { switch (sb.mode) { case MODE_NONE: case MODE_DMA_PAUSE: + case MODE_DMA_MASKED: sb.chan->AddSilence(); break; case MODE_DAC: From e269c3d2ed5f712d19aca057398bc7f3c6d6ac79 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 5 Sep 2004 14:23:04 +0000 Subject: [PATCH 1857/4131] Moving imgmount to dos_programs Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1939 --- src/dos/dos_programs.cpp | 255 ++++++++++++++++++++++++++++++++++----- src/dos/drive_fat.cpp | 196 +----------------------------- 2 files changed, 230 insertions(+), 221 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 1b6a03e9..48688729 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.26 2004-08-04 09:12:53 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.27 2004-09-05 14:23:04 qbix79 Exp $ */ #include #include @@ -34,7 +34,6 @@ void MSCDEX_SetCDInterface(int intNr, int forceCD); -void IMGMOUNT_ProgramStart(Program * * make); class MOUNT : public Program { public: @@ -125,7 +124,7 @@ public: return; } if (temp_line[temp_line.size()-1]!=CROSS_FILESPLIT) temp_line+=CROSS_FILESPLIT; - Bit8u bit8size=(Bit8u) sizes[1]; + Bit8u bit8size=(Bit8u) sizes[1]; if (type=="cdrom") { int num = -1; cmd->FindInt("-usecd",num,true); @@ -225,13 +224,13 @@ private: ldp=(localDrive*)Drives[drive]; tmpfile = ldp->GetSystemFilePtr(fullname, "r"); if(tmpfile == NULL) { - WriteOut("Bootdisk file does not exist. Failing.\n"); + WriteOut(MSG_Get("PROGRAM_BOOT_NOT_EXIST")); return NULL; } fclose(tmpfile); tmpfile = ldp->GetSystemFilePtr(fullname, "rb+"); if(tmpfile == NULL) { - WriteOut("Cannot open bootdisk file. Failing.\n"); + WriteOut(MSG_Get("PROGRAM_BOOT_NOT_OPEN")); return NULL; } @@ -242,15 +241,7 @@ private: } void printError(void) { - WriteOut("This command boots DosBox from either a floppy or hard disk image.\n\n"); - WriteOut("For this command, one can specify a succession of floppy disks swappable\n"); - WriteOut("by pressing Ctrl-F4, and -l specifies the mounted drive to boot from. If\n"); - WriteOut("no drive letter is specified, this defaults to booting from the A drive.\n"); - WriteOut("The only bootable drive letters are A, C, and D. For booting from a hard\n"); - WriteOut("drive (C or D), the image should have already been mounted using the\n"); - WriteOut("IMGMOUNT command.\n\n"); - WriteOut("The syntax of this command is:\n\n"); - WriteOut("BOOT [diskimg1.img diskimg2.img] [-l driveletter]\n"); + WriteOut(MSG_Get("PROGRAM_BOOT_PRINT_ERROR")); } @@ -288,14 +279,14 @@ public: continue; } - WriteOut("Opening image file: %s\n", temp_line.c_str()); + WriteOut(MSG_Get("PROGRAM_BOOT_IMAGE_OPEN"), temp_line.c_str()); usefile = getFSFile((Bit8u *)temp_line.c_str(), &floppysize, &rombytesize); if(usefile != NULL) { if(diskSwap[i] != NULL) delete diskSwap[i]; diskSwap[i] = new imageDisk(usefile, (Bit8u *)temp_line.c_str(), floppysize, false); } else { - WriteOut("Cannot open %s", temp_line.c_str()); + WriteOut(MSG_Get("PROGRAM_BOOT_IMAGE_NOT_OPEN"), temp_line.c_str()); return; } @@ -308,11 +299,11 @@ public: swapInDisks(); if(imageDiskList[drive-65]==NULL) { - WriteOut("Unable to boot off of drive %c", drive); + WriteOut(MSG_Get("PROGRAM_BOOT_UNABLE"), drive); return; } - WriteOut("Booting from drive %c...\n", drive); + WriteOut(MSG_Get("PROGRAM_BOOT_BOOT"),"Booting from drive %c...\n", drive); bootSector bootarea; imageDiskList[drive-65]->Read_Sector(0,0,1,(Bit8u *)&bootarea); @@ -450,21 +441,214 @@ static void INTRO_ProgramStart(Program * * make) { *make=new INTRO; } +class IMGMOUNT : public Program { +public: + void Run(void) + { + DOS_Drive * newdrive; + imageDisk * newImage; + Bit32u imagesize; + char drive; + std::string label; + + std::string type="hdd"; + std::string fstype="fat"; + cmd->FindString("-t",type,true); + cmd->FindString("-fs",fstype,true); + Bit8u mediaid; + if (type=="floppy" || type=="hdd" || type=="iso") { + Bit16u sizes[4]; + + std::string str_size; + mediaid=0xF8; + + if (type=="floppy") { + mediaid=0xF0; + } else if (type=="cdrom" || type=="iso") { + str_size="650,127,16513,1700"; + mediaid=0xF8; + fstype = "iso"; + } + cmd->FindString("-size",str_size,true); + if ((type=="hdd") && (str_size.size()==0)) { + WriteOut("Must specify drive geometry for hard drives:\n"); + WriteOut("bytes_per_sector, sectors_per_cylinder, heads_per_cylinder, cylinder_count\n"); + return; + } + char number[20]; + const char * scan=str_size.c_str(); + Bitu index=0;Bitu count=0; + + while (*scan) { + if (*scan==',') { + number[index]=0;sizes[count++]=atoi(number); + index=0; + } else number[index++]=*scan; + scan++; + } + number[index]=0;sizes[count++]=atoi(number); + + if(fstype=="fat" || fstype=="iso") { + // get the drive letter + cmd->FindCommand(1,temp_line); + if ((temp_line.size() > 2) || ((temp_line.size()>1) && (temp_line[1]!=':'))) { + WriteOut("Must specify drive letter to mount image at.\n"); + return; + } + drive=toupper(temp_line[0]); + if (!isalpha(drive)) { + WriteOut("Must specify drive letter to mount image at.\n"); + return; + } + } else if (fstype=="none") { + cmd->FindCommand(1,temp_line); + if ((temp_line.size() > 1) || (!isdigit(temp_line[0]))) { + WriteOut("Must specify drive number (0 or 3) to mount image at (0,1=fda,fdb;2,3=hda,hdb)\n"); + return; + } + drive=temp_line[0]-'0'; + if(drive>3) { + WriteOut("Must specify drive number (0 or 3) to mount image at (0,1=fda,fdb;2,3=hda,hdb)\n"); + return; + } + } else { + WriteOut("Format \"%s\" is unsupported. Specify \"fat\" or \"none\".\n"); + return; + } + + if (!cmd->FindCommand(2,temp_line)) { + WriteOut("Must specify file image to mount\n"); + return; + } + if (!temp_line.size()) { + WriteOut("Must specify file image to mount\n"); + return; + } + struct stat test; + if (stat(temp_line.c_str(),&test)) { + // convert dosbox filename to system filename + char fullname[CROSS_LEN]; + char tmp[CROSS_LEN]; + strncpy(tmp, temp_line.c_str(), CROSS_LEN); + + Bit8u drive; + if (!DOS_MakeName(tmp, fullname, &drive)) { + WriteOut("Image file not found\n"); + return; + } + + localDrive *ldp = (localDrive*)Drives[drive]; + ldp->GetSystemFilename(tmp, fullname); + temp_line = tmp; + + if (stat(temp_line.c_str(),&test)) { + WriteOut("Image file not found\n"); + return; + } + } + + if ((test.st_mode & S_IFDIR)) { + WriteOut("To mount directories, use the MOUNT command, not the IMGMOUNT command\n"); + return; + } + + if(fstype=="fat") { + newdrive=new fatDrive(temp_line.c_str(),sizes[0],sizes[1],sizes[2],sizes[3],0); + } else if (fstype=="iso") { + int error; + newdrive = new isoDrive(drive, temp_line.c_str(), mediaid, error); + switch (error) { + case 0 : WriteOut(MSG_Get("MSCDEX_SUCCESS")); break; + case 1 : WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS")); break; + case 2 : WriteOut(MSG_Get("MSCDEX_ERROR_NOT_SUPPORTED")); break; + case 3 : WriteOut(MSG_Get("MSCDEX_ERROR_PATH")); break; + case 4 : WriteOut(MSG_Get("MSCDEX_TOO_MANY_DRIVES")); break; + case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break; + default : WriteOut(MSG_Get("MSCDEX_UNKNOWN_ERROR")); break; + }; + if (error) { + delete newdrive; + return; + } + } else { + FILE *newDisk = fopen(temp_line.c_str(), "rb+"); + fseek(newDisk,0L, SEEK_END); + imagesize = (ftell(newDisk) / 1024); + + newImage = new imageDisk(newDisk, (Bit8u *)temp_line.c_str(), imagesize, (imagesize > 2880)); + if(imagesize>2880) newImage->Set_Geometry(sizes[2],sizes[3],sizes[1],sizes[0]); + } + } + if(fstype=="fat") { + if (Drives[drive-'A']) { + WriteOut("Drive already mounted at that letter\n"); + if (newdrive) delete newdrive; + return; + } + if (!newdrive) WriteOut("Can't create drive from file\n"); + Drives[drive-'A']=newdrive; + // Set the correct media byte in the table + mem_writeb(Real2Phys(dos.tables.mediaid)+drive-'A',mediaid); + WriteOut("Drive %c mounted as %s\n",drive,temp_line.c_str()); + if(((fatDrive *)newdrive)->loadedDisk->hardDrive) { + if(imageDiskList[2] == NULL) { + imageDiskList[2] = ((fatDrive *)newdrive)->loadedDisk; + updateDPT(); + return; + } + if(imageDiskList[3] == NULL) { + imageDiskList[3] = ((fatDrive *)newdrive)->loadedDisk; + updateDPT(); + return; + } + } + if(!((fatDrive *)newdrive)->loadedDisk->hardDrive) { + imageDiskList[0] = ((fatDrive *)newdrive)->loadedDisk; + } + } else if (fstype=="iso") { + if (Drives[drive-'A']) { + WriteOut("Drive already mounted at that letter\n"); + if (newdrive) delete newdrive; + return; + } + if (!newdrive) WriteOut("Can't create drive from file\n"); + Drives[drive-'A']=newdrive; + // Set the correct media byte in the table + mem_writeb(Real2Phys(dos.tables.mediaid)+drive-'A',mediaid); + WriteOut("Drive %c mounted as %s\n",drive,temp_line.c_str()); + } else if (fstype=="none") { + if(imageDiskList[drive] != NULL) delete imageDiskList[drive]; + imageDiskList[drive] = newImage; + updateDPT(); + WriteOut("Drive number %d mounted as %s\n",drive,temp_line.c_str()); + } + + // check if volume label is given + //if (cmd->FindString("-label",label,true)) newdrive->dirCache.SetLabel(label.c_str()); + return; + } +}; + +void IMGMOUNT_ProgramStart(Program * * make) { + *make=new IMGMOUNT; +} + + void DOS_SetupPrograms(void) { - /*Add Messages */ + /*Add Messages */ MSG_Add("PROGRAM_MOUNT_CDROMS_FOUND","CDROMs found: %d\n"); MSG_Add("PROGRAM_MOUNT_STATUS_2","Drive %c is mounted as %s\n"); MSG_Add("PROGRAM_MOUNT_STATUS_1","Current mounted drives are:\n"); - MSG_Add("PROGRAM_MOUNT_ERROR_1","Directory %s doesn't exist.\n"); - MSG_Add("PROGRAM_MOUNT_ERROR_2","%s isn't a directory\n"); + MSG_Add("PROGRAM_MOUNT_ERROR_1","Directory %s doesn't exist.\n"); + MSG_Add("PROGRAM_MOUNT_ERROR_2","%s isn't a directory\n"); MSG_Add("PROGRAM_MOUNT_ILL_TYPE","Illegal type %s\n"); - MSG_Add("PROGRAM_MOUNT_ALLREADY_MOUNTED","Drive %c already mounted with %s\n"); - MSG_Add("PROGRAM_MOUNT_USAGE","Usage MOUNT Drive-Letter Local-Directory\nSo a MOUNT c c:\\windows mounts windows directory as the c: drive in DOSBox\n"); + MSG_Add("PROGRAM_MOUNT_ALLREADY_MOUNTED","Drive %c already mounted with %s\n"); + MSG_Add("PROGRAM_MOUNT_USAGE","Usage MOUNT Drive-Letter Local-Directory\nSo a MOUNT c c:\\windows mounts windows directory as the c: drive in DOSBox\n"); - MSG_Add("PROGRAM_MEM_CONVEN","%10d Kb free conventional memory\n"); - MSG_Add("PROGRAM_MEM_EXTEND","%10d Kb free extended memory\n"); - MSG_Add("PROGRAM_MEM_EXPAND","%10d Kb free expanded memory\n"); + MSG_Add("PROGRAM_MEM_CONVEN","%10d Kb free conventional memory\n"); + MSG_Add("PROGRAM_MEM_EXTEND","%10d Kb free extended memory\n"); + MSG_Add("PROGRAM_MEM_EXPAND","%10d Kb free expanded memory\n"); MSG_Add("PROGRAM_LOADFIX_ALLOC","%d kb allocated.\n"); MSG_Add("PROGRAM_LOADFIX_DEALLOC","%d kb freed.\n"); @@ -504,7 +688,24 @@ void DOS_SetupPrograms(void) { "DOSBox will stop/exit without a warning if an error occured!\n" ); - /*regular setup*/ + MSG_Add("PROGRAM_BOOT_NOT_EXIST","Bootdisk file does not exist. Failing.\n"); + MSG_Add("PROGRAM_BOOT_NOT_OPEN","Cannot open bootdisk file. Failing.\n"); + MSG_Add("PROGRAM_BOOT_PRINT_ERROR","This command boots DosBox from either a floppy or hard disk image.\n\n" + "For this command, one can specify a succession of floppy disks swappable\n" + "by pressing Ctrl-F4, and -l specifies the mounted drive to boot from. If\n" + "no drive letter is specified, this defaults to booting from the A drive.\n" + "The only bootable drive letters are A, C, and D. For booting from a hard\n" + "drive (C or D), the image should have already been mounted using the\n" + "IMGMOUNT command.\n\n" + "The syntax of this command is:\n\n" + "BOOT [diskimg1.img diskimg2.img] [-l driveletter]\n" + ); + MSG_Add("PROGRAM_BOOT_UNABLE","Unable to boot off of drive %c"); + MSG_Add("PROGRAM_BOOT_IMAGE_OPEN","Opening image file: %s\n"); + MSG_Add("PROGRAM_BOOT_IMAGE_NOT_OPEN","Cannot open %s"); + MSG_Add("PROGRAM_BOOT_BOOT","Booting from drive %c...\n"); + + /*regular setup*/ PROGRAMS_MakeFile("MOUNT.COM",MOUNT_ProgramStart); PROGRAMS_MakeFile("MEM.COM",MEM_ProgramStart); PROGRAMS_MakeFile("LOADFIX.COM",LOADFIX_ProgramStart); diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 4c169bff..a0e6d7bb 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: drive_fat.cpp,v 1.5 2004-09-05 14:23:04 qbix79 Exp $ */ + #include #include #include @@ -1123,197 +1125,3 @@ bool fatDrive::TestDir(char *dir) { return getDirClustNum(dir, &dummyClust, false); } - -class IMGMOUNT : public Program { -public: - void Run(void) - { - DOS_Drive * newdrive; - imageDisk * newImage; - Bit32u imagesize; - char drive; - std::string label; - - std::string type="hdd"; - std::string fstype="fat"; - cmd->FindString("-t",type,true); - cmd->FindString("-fs",fstype,true); - Bit8u mediaid; - if (type=="floppy" || type=="hdd" || type=="iso") { - Bit16u sizes[4]; - - std::string str_size; - mediaid=0xF8; - - if (type=="floppy") { - mediaid=0xF0; - } else if (type=="cdrom" || type=="iso") { - str_size="650,127,16513,1700"; - mediaid=0xF8; - fstype = "iso"; - } - cmd->FindString("-size",str_size,true); - if ((type=="hdd") && (str_size.size()==0)) { - WriteOut("Must specify drive geometry for hard drives:\n"); - WriteOut("bytes_per_sector, sectors_per_cylinder, heads_per_cylinder, cylinder_count\n"); - return; - } - char number[20]; - const char * scan=str_size.c_str(); - Bitu index=0;Bitu count=0; - - while (*scan) { - if (*scan==',') { - number[index]=0;sizes[count++]=atoi(number); - index=0; - } else number[index++]=*scan; - scan++; - } - number[index]=0;sizes[count++]=atoi(number); - - if(fstype=="fat" || fstype=="iso") { - // get the drive letter - cmd->FindCommand(1,temp_line); - if ((temp_line.size() > 2) || ((temp_line.size()>1) && (temp_line[1]!=':'))) { - WriteOut("Must specify drive letter to mount image at.\n"); - return; - } - drive=toupper(temp_line[0]); - if (!isalpha(drive)) { - WriteOut("Must specify drive letter to mount image at.\n"); - return; - } - } else if (fstype=="none") { - cmd->FindCommand(1,temp_line); - if ((temp_line.size() > 1) || (!isdigit(temp_line[0]))) { - WriteOut("Must specify drive number (0 or 3) to mount image at (0,1=fda,fdb;2,3=hda,hdb)\n"); - return; - } - drive=temp_line[0]-'0'; - if(drive>3) { - WriteOut("Must specify drive number (0 or 3) to mount image at (0,1=fda,fdb;2,3=hda,hdb)\n"); - return; - } - } else { - WriteOut("Format \"%s\" is unsupported. Specify \"fat\" or \"none\".\n"); - return; - } - - if (!cmd->FindCommand(2,temp_line)) { - WriteOut("Must specify file image to mount\n"); - return; - } - if (!temp_line.size()) { - WriteOut("Must specify file image to mount\n"); - return; - } - struct stat test; - if (stat(temp_line.c_str(),&test)) { - // convert dosbox filename to system filename - char fullname[CROSS_LEN]; - char tmp[CROSS_LEN]; - strncpy(tmp, temp_line.c_str(), CROSS_LEN); - - Bit8u drive; - if (!DOS_MakeName(tmp, fullname, &drive)) { - WriteOut("Image file not found\n"); - return; - } - - localDrive *ldp = (localDrive*)Drives[drive]; - ldp->GetSystemFilename(tmp, fullname); - temp_line = tmp; - - if (stat(temp_line.c_str(),&test)) { - WriteOut("Image file not found\n"); - return; - } - } - - if ((test.st_mode & S_IFDIR)) { - WriteOut("To mount directories, use the MOUNT command, not the IMGMOUNT command\n"); - return; - } - - if(fstype=="fat") { - newdrive=new fatDrive(temp_line.c_str(),sizes[0],sizes[1],sizes[2],sizes[3],0); - } else if (fstype=="iso") { - int error; - newdrive = new isoDrive(drive, temp_line.c_str(), mediaid, error); - switch (error) { - case 0 : WriteOut(MSG_Get("MSCDEX_SUCCESS")); break; - case 1 : WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS")); break; - case 2 : WriteOut(MSG_Get("MSCDEX_ERROR_NOT_SUPPORTED")); break; - case 3 : WriteOut(MSG_Get("MSCDEX_ERROR_PATH")); break; - case 4 : WriteOut(MSG_Get("MSCDEX_TOO_MANY_DRIVES")); break; - case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break; - default : WriteOut(MSG_Get("MSCDEX_UNKNOWN_ERROR")); break; - }; - if (error) { - delete newdrive; - return; - } - } else { - FILE *newDisk = fopen(temp_line.c_str(), "rb+"); - fseek(newDisk,0L, SEEK_END); - imagesize = (ftell(newDisk) / 1024); - - newImage = new imageDisk(newDisk, (Bit8u *)temp_line.c_str(), imagesize, (imagesize > 2880)); - if(imagesize>2880) newImage->Set_Geometry(sizes[2],sizes[3],sizes[1],sizes[0]); - } - } - if(fstype=="fat") { - if (Drives[drive-'A']) { - WriteOut("Drive already mounted at that letter\n"); - if (newdrive) delete newdrive; - return; - } - if (!newdrive) WriteOut("Can't create drive from file\n"); - Drives[drive-'A']=newdrive; - // Set the correct media byte in the table - mem_writeb(Real2Phys(dos.tables.mediaid)+drive-'A',mediaid); - WriteOut("Drive %c mounted as %s\n",drive,temp_line.c_str()); - if(((fatDrive *)newdrive)->loadedDisk->hardDrive) { - if(imageDiskList[2] == NULL) { - imageDiskList[2] = ((fatDrive *)newdrive)->loadedDisk; - updateDPT(); - return; - } - if(imageDiskList[3] == NULL) { - imageDiskList[3] = ((fatDrive *)newdrive)->loadedDisk; - updateDPT(); - return; - } - } - if(!((fatDrive *)newdrive)->loadedDisk->hardDrive) { - imageDiskList[0] = ((fatDrive *)newdrive)->loadedDisk; - } - } else if (fstype=="iso") { - if (Drives[drive-'A']) { - WriteOut("Drive already mounted at that letter\n"); - if (newdrive) delete newdrive; - return; - } - if (!newdrive) WriteOut("Can't create drive from file\n"); - Drives[drive-'A']=newdrive; - // Set the correct media byte in the table - mem_writeb(Real2Phys(dos.tables.mediaid)+drive-'A',mediaid); - WriteOut("Drive %c mounted as %s\n",drive,temp_line.c_str()); - } else if (fstype=="none") { - if(imageDiskList[drive] != NULL) delete imageDiskList[drive]; - imageDiskList[drive] = newImage; - updateDPT(); - WriteOut("Drive number %d mounted as %s\n",drive,temp_line.c_str()); - } - - // check if volume label is given - //if (cmd->FindString("-label",label,true)) newdrive->dirCache.SetLabel(label.c_str()); - return; - } -}; - -void IMGMOUNT_ProgramStart(Program * * make) { - *make=new IMGMOUNT; -} - - From fa3d6daf04c6ab76e55b792110581ba683f37551 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 5 Sep 2004 18:54:59 +0000 Subject: [PATCH 1858/4131] gcc3.4 doesn't really like pragma pack Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1940 --- include/paging.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/include/paging.h b/include/paging.h index 169731e9..c485f231 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,9 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: paging.h,v 1.10 2004-09-05 18:54:59 qbix79 Exp $ */ + #ifndef _PAGING_H_ #define _PAGING_H_ +#include "dosbox.h" #include "mem.h" class PageDirectory; @@ -70,7 +73,9 @@ bool PAGING_MakePhysPage(Bitu & page); void MEM_SetLFB(Bitu _page,Bitu _pages,HostPt _pt); void MEM_SetPageHandler(Bitu phys_page,Bitu pages,PageHandler * handler); -#pragma pack(1) +#ifdef _MSC_VER +#pragma pack (1) +#endif typedef struct { Bit32u p:1; Bit32u wr:1; @@ -84,7 +89,10 @@ typedef struct { Bit32u avl:3; Bit32u base:20; } X86_PageEntryBlock GCC_ATTRIBUTE(packed); -#pragma pack() +#ifdef _MSC_VER +#pragma pack () +#endif + union X86PageEntry { Bit32u load; From b2b03b172fb2183b07091535233e1ea0f8da6e9a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 5 Sep 2004 19:00:52 +0000 Subject: [PATCH 1859/4131] LOG_MSG=> LOG Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1941 --- src/ints/bios_disk.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index d22cb2aa..892701d0 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -238,19 +238,19 @@ static Bitu GetDosDriveNumber(Bitu biosNum) { static bool driveInactive(Bitu driveNum) { if(driveNum>=(2 + MAX_HDD_IMAGES)) { - LOG_MSG("Disk %d non-existant", driveNum); + LOG(LOG_BIOS,LOG_ERROR)("Disk %d non-existant", driveNum); last_status = 0x01; CALLBACK_SCF(true); return true; } if(imageDiskList[driveNum] == NULL) { - LOG_MSG("Disk %d not active", driveNum); + LOG(LOG_BIOS,LOG_ERROR)("Disk %d not active", driveNum); last_status = 0x01; CALLBACK_SCF(true); return true; } if(!imageDiskList[driveNum]->active) { - LOG_MSG("Disk %d not active", driveNum); + LOG(LOG_BIOS,LOG_ERROR)("Disk %d not active", driveNum); last_status = 0x01; CALLBACK_SCF(true); return true; @@ -391,7 +391,7 @@ static Bitu INT13_DiskHandler(void) { CALLBACK_SCF(false); break; default: - LOG_MSG("INT13: Function %x called on drive %x (dos drive %d)", reg_ah, reg_dl, drivenum); + LOG(LOG_BIOS,LOG_ERROR)("INT13: Function %x called on drive %x (dos drive %d)", reg_ah, reg_dl, drivenum); reg_ah=0xff; CALLBACK_SCF(true); } From 1984d40d6da02672eaf39d166893be9038523aa9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 6 Sep 2004 10:56:27 +0000 Subject: [PATCH 1860/4131] Added core_simple Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1942 --- visualc_net/dosbox.vcproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 56d6239e..c79a15cc 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -171,6 +171,9 @@ + + From c96b50cd39387d1a1cdc9e37090a9acd286cde8a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 7 Sep 2004 08:58:02 +0000 Subject: [PATCH 1861/4131] Added old style joystick support.(largely by gulikoza?) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1943 --- src/gui/sdl_mapper.cpp | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index d124ee4e..23a08484 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.6 2004-08-04 09:12:54 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.7 2004-09-07 08:58:02 qbix79 Exp $ */ + +#define OLD_JOYSTICK 1 #include #include @@ -252,11 +254,11 @@ public: else DeactivateBindList(&lists[key]); return 0; } -private: CBind * CreateKeyBind(SDLKey _key) { assert((Bitu)_keytype) { + case SDL_JOYAXISMOTION: + jaxis = &event->jaxis; + if(jaxis->axis == 0) + JOYSTICK_Move_X(stick,(float)(jaxis->value/32768.0)); + else if(jaxis->axis == 1) + JOYSTICK_Move_Y(stick,(float)(jaxis->value/32768.0)); + break; + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + jbutton = &event->jbutton; + bool state; + state=jbutton->type==SDL_JOYBUTTONDOWN; + if (jbutton->button<2) { + JOYSTICK_Button(stick,jbutton->button,state); + } + break; + } +#endif return false; } private: @@ -950,7 +978,7 @@ static void CreateLayout(void) { AddKeyButtonEvent(PX(4),PY(11),BW*2,BH,"0","kp_0",KBD_kp0); AddKeyButtonEvent(PX(6),PY(11),BW,BH,".","kp_period",KBD_kpperiod); - +#if (!OLD_JOYSTICK) /* Joystick Buttons/Texts */ AddJButtonButton(PX(17),PY(0),BW,BH,"1" ,0,0); AddJAxisButton (PX(18),PY(0),BW,BH,"Y-",0,true,false); @@ -965,7 +993,7 @@ static void CreateLayout(void) { AddJAxisButton (PX(17),PY(4),BW,BH,"X-",1,false,false); AddJAxisButton (PX(18),PY(4),BW,BH,"Y+",1,true,true); AddJAxisButton (PX(19),PY(4),BW,BH,"X+",1,false,true); - +#endif /* The modifier buttons */ AddModButton(PX(0),PY(13),50,20,"Mod1",1); AddModButton(PX(2),PY(13),50,20,"Mod2",2); @@ -981,8 +1009,9 @@ static void CreateLayout(void) { } /* Create some text buttons */ new CTextButton(PX(6),00,124,20,"Keyboard Layout"); +#if (!OLD_JOYSTICK) new CTextButton(PX(16),00,124,20,"Joystick Layout"); - +#endif bind_but.action=new CCaptionButton(200,330,0,0); bind_but.event_title=new CCaptionButton(0,350,0,0); @@ -1107,6 +1136,7 @@ void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char * eve strcpy(tempname,"hand_"); strcat(tempname,eventname); new CHandlerEvent(tempname,handler,key,mods,buttonname); + return ; } static void MAPPER_SaveBinds(void) { From 10d9e724d903a2ca229f0b31a08b928cb4127a33 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 7 Sep 2004 10:59:19 +0000 Subject: [PATCH 1862/4131] Fix dsp command 0xd4 continue dma transfer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1944 --- src/hardware/sblaster.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 0c316a12..8c43655d 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -690,7 +690,10 @@ static void DSP_DoCommand(void) { DSP_SetSpeaker(false); break; case 0xd4: /* Continue DMA */ - sb.dma.chan->Register_Callback(DSP_DMA_CallBack); + if (sb.mode==MODE_DMA_PAUSE) { + sb.mode=MODE_DMA_MASKED; + sb.dma.chan->Register_Callback(DSP_DMA_CallBack); + } break; case 0xda: /* Exit Autoinitialize 8-bit */ /* Set mode to single transfer so it ends with current block */ From d94017a7b13480b0d6d4aacd0872c924978bbddc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 7 Sep 2004 11:28:27 +0000 Subject: [PATCH 1863/4131] Add checking if an irq needs to be raised immediatly when programming new timer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1945 --- src/hardware/timer.cpp | 48 ++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 4f5d675b..e5cd75a4 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.27 2004-08-31 15:56:10 harekiet Exp $ */ +/* $Id: timer.cpp,v 1.28 2004-09-07 11:28:27 harekiet Exp $ */ #include "dosbox.h" #include "inout.h" @@ -37,7 +37,6 @@ static INLINE void BCD2BIN(Bit16u& val) { val=temp; } -static bool pit0_scheduled; struct PIT_Block { Bit8u mode; /* Current Counter Mode */ @@ -52,15 +51,37 @@ struct PIT_Block { Bit16u write_latch; bool bcd; bool go_read_latch; + bool new_mode; }; static PIT_Block pit[3]; static void PIT0_Event(Bitu val) { PIC_ActivateIRQ(0); - if (pit[0].mode!=0) { - PIC_AddEvent(PIT0_Event,pit[0].micro); - } else pit0_scheduled=false; + if (pit[0].mode!=0) PIC_AddEvent(PIT0_Event,pit[0].micro); +} + +static bool counter_output(Bitu counter) { + PIT_Block * p=&pit[counter]; + Bit64s micro=PIC_MicroCount()-p->start; + switch (p->mode) { + case 0: + if (p->new_mode) return false; + if (micro>p->micro) return true; + else return false; + break; + case 2: + if (p->new_mode) return true; + micro%=p->micro; + return micro>0; + case 3: + if (p->new_mode) return true; + micro%=p->micro; + return micro*2micro; + default: + LOG(LOG_PIT,LOG_ERROR)("Illegal Mode %d for reading output",p->mode); + return true; + } } static void counter_latch(Bitu counter) { @@ -69,7 +90,6 @@ static void counter_latch(Bitu counter) { p->go_read_latch=false; Bit64s micro=PIC_MicroCount()-p->start; - switch (p->mode) { case 0: /* Interrupt on Terminal Count */ /* Counter keeps on counting after passing terminal count */ @@ -136,11 +156,10 @@ static void write_latch(Bitu port,Bitu val,Bitu iolen) { if (!p->micro) p->micro=1; switch (counter) { case 0x00: /* Timer hooked to IRQ 0 */ - if (!p->mode || !pit0_scheduled) { - pit0_scheduled=true; - PIC_RemoveEvents(PIT0_Event); + if (p->new_mode) { + p->new_mode=false; PIC_AddEvent(PIT0_Event,p->micro); - } + } else LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer set without new control word"); LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,(Bit32u)p->mode); break; case 0x02: /* Timer hooked to PC-Speaker */ @@ -207,6 +226,14 @@ static void write_p43(Bitu port,Bitu val,Bitu iolen) { pit[latch].read_state = (val >> 4) & 0x03; pit[latch].write_state = (val >> 4) & 0x03; pit[latch].mode = (val >> 1) & 0x07; + if (pit[latch].mode>5) + pit[latch].mode-=4; //6,7 become 2 and 3 + if (latch==0) { + PIC_RemoveEvents(PIT0_Event); + if (!counter_output(0) && pit[latch].mode) + PIC_ActivateIRQ(0); + } + pit[latch].new_mode = true; } break; case 3: @@ -260,7 +287,6 @@ void TIMER_Init(Section* sect) { pit[1].micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)pit[1].cntr)); pit[2].micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)pit[2].cntr)); - pit0_scheduled=true; PIC_AddEvent(PIT0_Event,pit[0].micro); } From 78a0e947aef56892ab0a210cdd9bdb5ab2fb66c3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 7 Sep 2004 12:13:38 +0000 Subject: [PATCH 1864/4131] Clear paging link cache when full Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1946 --- src/cpu/paging.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index a77a9a11..6198bafa 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -254,16 +254,21 @@ void PAGING_UnlinkPages(Bitu lin_page,Bitu pages) { void PAGING_LinkPage(Bitu lin_page,Bitu phys_page) { PageHandler * handler=MEM_GetPageHandler(phys_page); Bitu lin_base=lin_page << 12; - if (lin_page>=TLB_SIZE || phys_page>=TLB_SIZE) E_Exit("Illegal page"); + + if (paging.links.used>=PAGING_LINKS) { + LOG(LOG_PAGING,LOG_NORMAL)("Not enough paging links, resetting cache"); + PAGING_ClearTLB(); + } + HostPt host_mem=handler->GetHostPt(phys_page); paging.tlb.phys_page[lin_page]=phys_page; if (handler->flags & PFLAG_READABLE) paging.tlb.read[lin_page]=host_mem-lin_base; else paging.tlb.read[lin_page]=0; if (handler->flags & PFLAG_WRITEABLE) paging.tlb.write[lin_page]=host_mem-lin_base; else paging.tlb.write[lin_page]=0; - if (paging.links.used>=PAGING_LINKS) E_Exit("Not enough paging links"); + paging.links.entries[paging.links.used++]=lin_page; paging.tlb.handler[lin_page]=handler; } From 0e82121c6c0ca86017e93e621bbab6579a4fe31e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 7 Sep 2004 12:23:28 +0000 Subject: [PATCH 1865/4131] Initial redraft of README Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1947 --- README | 327 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 215 insertions(+), 112 deletions(-) diff --git a/README b/README index e7adaa3b..7faa039c 100644 --- a/README +++ b/README @@ -1,4 +1,5 @@ -DOSBox v0.61 +DOSBox v0.62 + ===== NOTE: @@ -14,9 +15,141 @@ earlier). Also note that "protected mode" games need substantially more resources and may require a much faster processor for you to run it properly in DOSBox. + + ====== -Usage: +INDEX: ====== +1. Quickstart +2. FAQ +3. Usage +4. Internal Programs +5. Special Keys +6. System Requirements +7. To run resource-demanding games +8. The config file +9. The language file +10. Building your own version of DOSBox +11. Special thanks +12. Contact + + +============== +1. Quickstart: +============== + +Type INTRO in dosbox. That's it. + + + + +======= +2. FAQ: +======= + +Some Frequently Asked Questions: + +Q: I've got a Z instead of a C at the prompt. +Q: The mouse doesn't work. +Q: The sound stutters. +Q: I can't type \ in DOSBox. +Q: The game/application can't find its CD-ROM. +Q: The game/application runs much too slow! +Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. +Q: What sound hardware does DosBox presently emulate? + + + + + + +Q: I've got a Z instead of a C at the prompt. +A: In DOSBox you can mount directories as drives. + In win32: mount c D:\ would give you a C in DOSBox which points + at D:\ in win32. + In linux: mount c /home/username would give you a C in DOSBox + which points at /home/username in Linux. + +Q: The mouse doesn't work. +A: Normally dosbox detects the mouse being used by a game. If you click on + the screen then it should get locked and work. + Sometimes the dosbox mouse detection doesn't work with certain games. You + might have to force to lock the mouse then with ctrl-F10. + +Q: The sound stutters. +A: You're using too much cpu power to keep dosbox running at the current speed. + You can either lower the cycles or skip frames or get a faster machine. + +Q: I can't type \ in DOSBox. +A: This is a known problem. It only occurs if your keyboard layout isn't US. + Some possible fixes: + 1. Switch your keyboard layout. + 2. Use / instead. + 3. Add the commands you want to execute in dosbox.conf + +Q: The game/application can't find its CD-ROM. +A: Be sure to mount the CD-ROM with -t cdrom switch. Also try adding the cor- + rect label (-label LABEL). To enable more low-level cdrom support add + the following switch to mount: -usecd #, where # is the number of your + CD-ROM drive reported by mount -cd. If you run Win32 you can specify -ioctl + or -aspi. Look at the description elsewhere in this document for their + meaning. + +Q: The game/application runs much too slow! +A: Look at the section "To run resource-demanding games" for more information. + +Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. +A: This is possible! Just create a config file: config -writeconf dosbox.conf . + Startup your favourite editor and look at all the settings present. To + start DOSBox with your new settings: dosbox -conf dosbox.conf + +Q: What sound hardware does DosBox presently emulate? +A: DosBox emulates several legacy sound devices: + - Internal PC speaker + This emulation includes both the tone generator and several forms of + digital sound output through the internal speaker. + - Creative CMS/Gameblaster + The is the first card released by Creative Labs(R). The default + configuration places it on port 0x220. It should be noted that enabling + this with the Adlib emulation may result in conflicts. + - Tandy 3 voice + The emulation of this sound hardware is complete with the exception of + the noise channel, which is not very well documented and as such is only + a best guess as to the sound's accuracy. + - Adlib + Borrowed from MAME, this emulation is almost perfect and includes the + Adlib's ability to almost play digitized sound. + - SoundBlaster Pro + Coupled with the Adlib, DosBox provides Soundblaster Pro level 8-bit + stereo sound. + - Disney Soundsource + Using the printer port, this sound device outputs digital sound only. + - Gravis Ultrasound + The emulation of this hardware is nearly complete, though the MIDI + capabilities have been left out since an MPU-401 has been + emulated in other code. + - MPU-401 + A MIDI passthrough interface is also emulated. This method of sound + output will only work when used with a General Midi or MT-32 device. + + +Q: Great README, but I still don't get it. +A: While unlikely this seems to happen. Maybe a look at "The Newbie's + pictorial guide to dosbox" located at + http://vogons.zetafleet.com/viewforum.php?f=39 might help you. + +For more questions read the remainder of this README and/or check +the site/forum: +http://dosbox.sourceforge.net + + + + +========= +3. Usage: +========= + +An overview of the commandline options you can give to DOSBox: dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] [-lang languagefile] [-machine machinetype] [-noconsole] @@ -68,9 +201,9 @@ In Windows you can also drag directories/files onto the dosbox executable. -================== -Internal Programs: -================== +===================== +4. Internal Programs: +===================== DOSBox supports most of the DOS commands found in command.com. In addition, the following commands are available: @@ -112,7 +245,7 @@ MOUNT -cd -ioctl Forces to use ioctl commands. Only valid if mounting a cdrom under - windows which support them (Win2000/XP/NT). + a Windows OS which support them (Win2000/XP/NT). -usecd number Forces to use SDL cdrom support for drive number. @@ -183,13 +316,54 @@ Examples: 3. To free previous allocated memory : loadfix -f + +RESCAN + Make DOSBox reread the directory structure. Useful if you changed something + on a mounted drive outside of DOSBox. + + +MIXER + Makes DOSBox display it's current volume settings. + You can change this way: + + mixer channel left:right [/NOSHOW] + + channel + Can be one of the following: MASTER, DISNEY, SPKR, GUS, SB, FM. + + left:right + The volume levels in percentages. If you put a D in front it will be + in deciBell (example mixer gus d-10). + + /NOSHOW + Prevents DOSBox from showing the result if you set one + of the volume levels. + + +IMGMOUNT + A utility to mount disk images and cdrom images in DOSBox. + + CDROM: either iso or cue/bin is supported: + IMGMOUNT DRIVE imagefile -t iso + + imagefile + location is inside DOSBox. + + disk image + +IPX + +BOOT + + For more information use the /? command line switch with the programs. -============= -Special Keys: -============= + +================ +5. Special Keys: +================ ALT-ENTER Go full screen and back. CTRL-F5 Save a screenshot. @@ -205,9 +379,11 @@ 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. -==================== -System requirements: -==================== + + +======================= +6. System requirements: +======================= Fast machine. My guess would be pentium-2 400+ to get decent emulation of games written for an 286 machine. @@ -216,9 +392,10 @@ them to run fast though!! Be sure to read the next section on how to speed it up somewhat. -================================ -To run resource-demanding games: -================================ + +=================================== +7. To run resource-demanding games: +=================================== DOSBox emulates the CPU, the sound and graphic cards, and some other stuff, all at the same time. You can overclock DOSBox by using CTRL+F12, but @@ -246,89 +423,10 @@ You can also try to disable the sound through the setup utility of the game to further reduce load on your CPU. -==== -FAQ: -==== -Q: I've got a Z instead of a C at the prompt. -A: In DOSBox you can mount directories as drives. - In win32: mount c D:\ would give you a C in DOSBox which points - at D:\ in win32. - In linux: mount c /home/username would give you a C in DOSBox - which points at /home/username in Linux. - -Q: The mouse doesn't work. -A: Normally dosbox detects the mouse being used by a game. If you click on - the screen then it should get locked and work. - Sometimes the dosbox mouse detection doesn't work with certain games. You - might have to force to lock the mouse then with ctrl-F10. - -Q: The sound stutters. -A: You're using too much cpu power to keep dosbox running at the current speed. - You can either lower the cycles or skip frames or get a faster machine. - -Q: I can't type \ in DOSBox. -A: This is a known problem. It only occurs if your keyboard layout isn't US. - Some possible fixes: - 1. Switch your keyboard layout. - 2. Use / instead. - 3. Add the commands you want to execute in dosbox.conf - -Q: The game/application can't find its CD-ROM. -A: Be sure to mount the CD-ROM with -t cdrom switch. Also try adding the cor- - rect label (-label LABEL). To enable more low-level cdrom support add - the following switch to mount: -usecd #, where # is the number of your - CD-ROM drive reported by mount -cd. If you run Win32 you can specify -ioctl - or -aspi. Look at the description elsewhere in this document for their - meaning. - -Q: The game/application runs much too slow! -A: Look at the section "To run resource-demanding games" for more information. - -Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. -A: This is possible! Just create a config file: config -writeconf dosbox.conf . - Startup your favourite editor and look at all the settings present. To - start DOSBox with your new settings: dosbox -conf dosbox.conf - -Q: What sound hardware does DosBox presently emulate? -A: DosBox emulates several legacy sound devices: - - Internal PC speaker - This emulation includes both the tone generator and several forms of digital - sound output through the internal speaker. - - Creative CMS/Gameblaster - The is the first card released by Creative Labs(R). The default configuration places - it on port 0x220. It should be noted that enabling this with the Adlib emulation may - result in conflicts. - - Tandy 3 voice - The emulation of this sound hardware is complete with the exception of the noise channel, - which is not very well documented and as such is only a best guess as to the sound's accuracy. - - Adlib - Borrowed from MAME, this emulation is almost perfect and includes the Adlib's ability to almost - play digitized sound. - - SoundBlaster Pro - Coupled with the Adlib, DosBox provides Soundblaster Pro level 8-bit stereo sound. - - Disney Soundsource - Using the printer port, this sound device outputs digital sound only. - - Gravis Ultrasound - The emulation of this hardware is nearly complete, though the MIDI capabilities have been left - out since an MPU-401 has been emulated in other code. - - MPU-401 - A MIDI passthrough interface is also emulated. This method of sound output will only work when - used with a General Midi or MT-32 device. - - -Q: Great README, but I still don't get it. -A: While unlikely this seems to happen. Maybe a look at "The Newbie's - pictorial guide to dosbox" located at - http://vogons.zetafleet.com/viewforum.php?f=39 might help you. - -For more questions check the site/forum: -http://dosbox.sourceforge.net - - -================ -The Config File: -================ +=================== +8. The Config File: +=================== A config file can be generated by CONFIG.COM, which can be found on the internal dosbox Z: drive when you start up dosbox. Look in the internal @@ -341,14 +439,14 @@ The generated configfile contains the current settings. You can alter them and start DOSBox with the -conf switch to load the file and use these settings. DOSBox will if no configfile is specified with the -conf switch look in the -current directory for dosbox.conf. Then it will look for ~/.dosboxrc (linux), -~\dosbox.conf (win32) or "~/Library/Preferences/DOSBox Preferences" (MACOSX). +current directory for dosbox.conf. Then it will look for ~/.dosboxrc (Linux), +~\dosbox.conf (Win32) or "~/Library/Preferences/DOSBox Preferences" (MACOSX). -================== -The Language File: -================== +===================== +9. The Language File: +===================== A language file can be generated by CONFIG.COM. Read it and you will hopefully understand how to change it. @@ -357,16 +455,19 @@ or you can setup the filename in the config file in the [dosbox] section. There's a language= entry that can be changed with the filename. -==================================== -Building your own version of DOSBox: -==================================== + +======================================== +10. Building your own version of DOSBox: +======================================== Download the source. Check the INSTALL in the source distribution. -=============== -Special Thanks: -=============== + + +=================== +11. Special Thanks: +=================== Vlad R. of the vdmsound project for excellent sound blaster info. Tatsuyuki Satoh of the Mame Team for making an excellent FM emulator. @@ -376,9 +477,11 @@ Pierre-Yves G Colin Snover for hosting our forum. The Beta Testers. -======== -Contact: -======== -Harekiet harekiet@zophar.net + +============ +12. Contact: +============ + +Dosbox Crew: dosbox.crew@gmail.com http://dosbox.sourceforge.net From 8f64b0944753193733a1b6ba5f47a41026b61a2d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 7 Sep 2004 14:22:48 +0000 Subject: [PATCH 1866/4131] Make the EA Sib function static Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1948 --- src/cpu/core_normal/table_ea.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_normal/table_ea.h b/src/cpu/core_normal/table_ea.h index 990cc318..a7352e8b 100644 --- a/src/cpu/core_normal/table_ea.h +++ b/src/cpu/core_normal/table_ea.h @@ -49,7 +49,7 @@ static PhysPt EA_16_87_n(void) { return BaseDS+(Bit16u)(reg_bx+Fetchws()); } static Bit32u SIBZero=0; static Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi }; -INLINE PhysPt Sib(Bitu mode) { +static INLINE PhysPt Sib(Bitu mode) { Bit8u sib=Fetchb(); PhysPt base; switch (sib&7) { From 4e55ec780612faa3fcaa34b6bc0de22bef25e7b2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 7 Sep 2004 18:21:51 +0000 Subject: [PATCH 1867/4131] packed typedefs. I didn't know they existed. Neither does gcc Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1949 --- include/paging.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/paging.h b/include/paging.h index c485f231..b33df8e6 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.10 2004-09-05 18:54:59 qbix79 Exp $ */ +/* $Id: paging.h,v 1.11 2004-09-07 18:21:51 qbix79 Exp $ */ #ifndef _PAGING_H_ #define _PAGING_H_ @@ -76,7 +76,7 @@ void MEM_SetPageHandler(Bitu phys_page,Bitu pages,PageHandler * handler); #ifdef _MSC_VER #pragma pack (1) #endif -typedef struct { +struct X86_PageEntryBlock{ Bit32u p:1; Bit32u wr:1; Bit32u us:1; @@ -88,7 +88,7 @@ typedef struct { Bit32u g:1; Bit32u avl:3; Bit32u base:20; -} X86_PageEntryBlock GCC_ATTRIBUTE(packed); +} GCC_ATTRIBUTE(packed); #ifdef _MSC_VER #pragma pack () #endif From 93aeccfb4b41ccf4e4704061da17b3eeabc17018 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 8 Sep 2004 08:46:37 +0000 Subject: [PATCH 1868/4131] Added FBLD Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1950 --- src/fpu/fpu.cpp | 8 ++++++-- src/fpu/fpu_instructions.h | 23 ++++++++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index a6b587e8..bce87f7e 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu.cpp,v 1.21 2004-08-04 09:12:54 qbix79 Exp $ */ +/* $Id: fpu.cpp,v 1.22 2004-09-08 08:46:37 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU @@ -709,7 +709,11 @@ void FPU_ESC7_EA(Bitu rm,PhysPt addr) { FPU_FPOP(); break; case 0x04: /* FBLD packed BCD */ - //Don't think anybody will ever use this. + { + Real64 in = FPU_FBLD(addr); + FPU_PUSH(in); + } + break; default: LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); break; diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index c10ce6df..8cb207b0 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.18 2004-08-04 09:12:54 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.19 2004-09-08 08:46:37 qbix79 Exp $ */ static void FPU_FINIT(void) { @@ -262,6 +262,27 @@ static void FPU_FBST(PhysPt addr) mem_writeb(addr+9,p); } +static Real64 FPU_FBLD(PhysPt addr) +{ + Real64 val = 0; + Bitu in = 0; + Bit64u base = 1; + for(Bitu i = 0;i < 9;i++){ + in = mem_readb(addr + i); + val += ( (in&9) * base); + base *= 10; + val += ((( in>>4)&9) * base); + base *= 10; + } + + //last number + in = mem_readb(addr + 9); + val += ( (in&9) * base ); + if(in&0x80) val *= -1.0; + return val; +} + + #define BIAS80 16383 #define BIAS64 1023 From 4807b0f93c3c00fa547513d5611a34b6e58407b0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 8 Sep 2004 09:41:13 +0000 Subject: [PATCH 1869/4131] Removed tandy option Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1951 --- src/dosbox.cpp | 5 ++--- src/hardware/tandy_sound.cpp | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 24a542e0..542d1315 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.75 2004-08-23 08:24:07 harekiet Exp $ */ +/* $Id: dosbox.cpp,v 1.76 2004-09-08 09:41:13 qbix79 Exp $ */ #include #include @@ -340,7 +340,6 @@ void DOSBOX_Init(void) { secprop->Add_bool("pcspeaker",true); secprop->Add_int("pcrate",22050); secprop->AddInitFunction(&TANDYSOUND_Init); - secprop->Add_bool("tandy",true); secprop->Add_int("tandyrate",22050); secprop->AddInitFunction(&DISNEY_Init); secprop->Add_bool("disney",true); @@ -348,8 +347,8 @@ void DOSBOX_Init(void) { MSG_Add("SPEAKER_CONFIGFILE_HELP", "pcspeaker -- Enable PC-Speaker emulation.\n" "pcrate -- Sample rate of the PC-Speaker sound generation.\n" - "tandy -- Enable Tandy 3-Voice emulation.\n" "tandyrate -- Sample rate of the Tandy 3-Voice generation.\n" + " Tandysound emulation is present if machine is set to tandy.\n" "disney -- Enable Disney Sound Source emulation.\n" ); secprop=control->AddSection_prop("bios",&BIOS_Init); diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 4ba44264..0983a28e 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -311,7 +311,6 @@ static void SN76496_set_gain(int gain) void TANDYSOUND_Init(Section* sec) { if (machine!=MCH_TANDY) return; Section_prop * section=static_cast(sec); - if(!section->Get_bool("tandy")) return; IO_RegisterWriteHandler(0xc0,SN76496Write,IO_MB,2); IO_RegisterWriteHandler(0xc4,TandyDACWrite,IO_MB,4); From 77be195aa9192308407b1f3d03a2a009cc1f6fe3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 8 Sep 2004 09:50:27 +0000 Subject: [PATCH 1870/4131] Corrections suggested by wjp and jeremy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1952 --- README | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/README b/README index 7faa039c..a9f2c9fe 100644 --- a/README +++ b/README @@ -7,7 +7,7 @@ NOTE: While we hope that, one day, DOSBox will run virtually all programs ever made for the PC...we are not there yet. At present, DOSBox run on a high- -end machine will roughly be the equivalent of a lowend 486 PC. While the 0.60 +end machine will roughly be the equivalent of a low-end 486 PC. 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 @@ -56,7 +56,7 @@ Q: I can't type \ in DOSBox. Q: The game/application can't find its CD-ROM. Q: The game/application runs much too slow! Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. -Q: What sound hardware does DosBox presently emulate? +Q: What sound hardware does DOSBox presently emulate? @@ -64,20 +64,20 @@ Q: What sound hardware does DosBox presently emulate? Q: I've got a Z instead of a C at the prompt. -A: In DOSBox you can mount directories as drives. - In win32: mount c D:\ would give you a C in DOSBox which points - at D:\ in win32. - In linux: mount c /home/username would give you a C in DOSBox +A: You have to make your directories available as drives in DOSBox by using + the "mount" command. For example, in Windows "mount C D:\" would give + you a C in DOSBox which points at your Windows D:\ drive. + In Linux, "mount c /home/username" would give you a C in DOSBox which points at /home/username in Linux. Q: The mouse doesn't work. -A: Normally dosbox detects the mouse being used by a game. If you click on +A: Normally DOSBox detects the mouse being used by a game. If you click on the screen then it should get locked and work. - Sometimes the dosbox mouse detection doesn't work with certain games. You + Sometimes the DOSBox mouse detection doesn't work with certain games. You might have to force to lock the mouse then with ctrl-F10. Q: The sound stutters. -A: You're using too much cpu power to keep dosbox running at the current speed. +A: You're using too much cpu power to keep DOSBox running at the current speed. You can either lower the cycles or skip frames or get a faster machine. Q: I can't type \ in DOSBox. @@ -85,11 +85,11 @@ A: This is a known problem. It only occurs if your keyboard layout isn't US. Some possible fixes: 1. Switch your keyboard layout. 2. Use / instead. - 3. Add the commands you want to execute in dosbox.conf + 3. Add the commands you want to execute to dosbox.conf Q: The game/application can't find its CD-ROM. -A: Be sure to mount the CD-ROM with -t cdrom switch. Also try adding the cor- - rect label (-label LABEL). To enable more low-level cdrom support add +A: Be sure to mount the CD-ROM with -t cdrom switch. Also try adding the + correct label (-label LABEL). To enable more low-level CD-ROM support add the following switch to mount: -usecd #, where # is the number of your CD-ROM drive reported by mount -cd. If you run Win32 you can specify -ioctl or -aspi. Look at the description elsewhere in this document for their @@ -100,11 +100,11 @@ A: Look at the section "To run resource-demanding games" for more information. Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. A: This is possible! Just create a config file: config -writeconf dosbox.conf . - Startup your favourite editor and look at all the settings present. To + Start your favourite editor and look at all the settings present. To start DOSBox with your new settings: dosbox -conf dosbox.conf -Q: What sound hardware does DosBox presently emulate? -A: DosBox emulates several legacy sound devices: +Q: What sound hardware does DOSBox presently emulate? +A: DOSBox emulates several legacy sound devices: - Internal PC speaker This emulation includes both the tone generator and several forms of digital sound output through the internal speaker. @@ -134,8 +134,8 @@ A: DosBox emulates several legacy sound devices: Q: Great README, but I still don't get it. -A: While unlikely this seems to happen. Maybe a look at "The Newbie's - pictorial guide to dosbox" located at +A: While unlikely, this seems to happen. A look at "The Newbie's + pictorial guide to DOSBox" located at http://vogons.zetafleet.com/viewforum.php?f=39 might help you. For more questions read the remainder of this README and/or check @@ -178,7 +178,7 @@ dosbox -version Start dosbox using the language string specified in "languagefile". -noconsole (Windows Only) - Start dosbox without showing the console window, output will + Start dosbox without showing the console window. Output will be redirected to stdout.txt and stderr.txt -machine machinetype @@ -228,10 +228,10 @@ MOUNT -cd floppy, cdrom. -size drivesize - Sets the size of the drive. + Sets the size of the drive. -freesize sizemb - Sets the amount of freespace avaiable on a drive in MB's. This + Sets the amount of free space available on a drive in MB's. This is a more simple version of -size. -label drivelabel @@ -263,7 +263,7 @@ MOUNT -cd programs that demand specific drive letters. For example: Touche: Adventures of The Fifth Musketeer must be run on your C: - drive. Using DOSBox and it's mount command, you can trick into thinking it + drive. Using DOSBox and its mount command, you can trick into thinking it is on C drive while placing it where you want it. For example, if the game were in D:\TOUCHE, you can use the command MOUNT C D:\ would allow you to run Touche from the D drive. @@ -272,7 +272,7 @@ MOUNT -cd General MOUNT Examples: 1. To mount c:\floppy as a floppy : mount a c:\floppy -t floppy - 2. To mount system cdrom drive E as cdrom drive D in dosbox: + 2. To mount system cdrom drive E as cdrom drive D in DOSBox: mount d e:\ -t cdrom 3. To mount system cdrom drive at mountpoint /media/cdrom as cdrom drive D in dosbox: @@ -323,7 +323,7 @@ RESCAN MIXER - Makes DOSBox display it's current volume settings. + Makes DOSBox display its current volume settings. You can change this way: mixer channel left:right [/NOSHOW] @@ -432,13 +432,14 @@ A config file can be generated by CONFIG.COM, which can be found on the internal dosbox Z: drive when you start up dosbox. Look in the internal programs section of the readme for usage of CONFIG.COM. You can edit the generated configfile to customize DOSBox. + The file is divided into several sections (the names have [] around it). Some sections have options which you can set. # and % indicate comment-lines. The generated configfile contains the current settings. You can alter them and start DOSBox with the -conf switch to load the file and use these settings. -DOSBox will if no configfile is specified with the -conf switch look in the +If no configfile is specified with the -conf switch, DOSBox will look in the current directory for dosbox.conf. Then it will look for ~/.dosboxrc (Linux), ~\dosbox.conf (Win32) or "~/Library/Preferences/DOSBox Preferences" (MACOSX). @@ -483,5 +484,5 @@ The Beta Testers. 12. Contact: ============ -Dosbox Crew: dosbox.crew@gmail.com +DOSBox Crew: dosbox.crew@gmail.com http://dosbox.sourceforge.net From 530946440320d833de1a6696578f306bf7bb0a02 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 8 Sep 2004 10:33:16 +0000 Subject: [PATCH 1871/4131] anding is always bineary Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1953 --- src/fpu/fpu_instructions.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 8cb207b0..3691390c 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.19 2004-09-08 08:46:37 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.20 2004-09-08 10:33:16 qbix79 Exp $ */ static void FPU_FINIT(void) { @@ -269,15 +269,15 @@ static Real64 FPU_FBLD(PhysPt addr) Bit64u base = 1; for(Bitu i = 0;i < 9;i++){ in = mem_readb(addr + i); - val += ( (in&9) * base); + val += ( (in&0xf) * base); //in&0xf shouldn't be higher then 9 base *= 10; - val += ((( in>>4)&9) * base); + val += ((( in>>4)&0xf) * base); base *= 10; } //last number in = mem_readb(addr + 9); - val += ( (in&9) * base ); + val += ( (in&0xf) * base ); if(in&0x80) val *= -1.0; return val; } From 1415b3392bc91d8e9fc8e8f22f89a4ace1f402a3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 8 Sep 2004 14:14:46 +0000 Subject: [PATCH 1872/4131] Removed width and height. Replaced it with resolution Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1954 --- src/gui/sdlmain.cpp | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 0951c7de..02404cff 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.75 2004-09-01 06:46:49 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.76 2004-09-08 14:14:46 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -778,8 +778,25 @@ static void GUI_StartUp(Section * sec) { mouselocked=false; //Global for mapper sdl.mouse.requestlock=false; sdl.desktop.fixed=section->Get_bool("fullfixed"); - sdl.desktop.width=section->Get_int("fullwidth"); - sdl.desktop.height=section->Get_int("fullheight"); + const char* fullresolution=section->Get_string("fullresolution"); + if(fullresolution && *fullresolution) { + char res[100]= { 0 }; + strcpy(res,fullresolution); + fullresolution = lowcase (res);//so x and X are allowed + + char* height = strchr(fullresolution,'x'); + if(height && * height) { + *height = 0; + sdl.desktop.height = atoi(height+1); + sdl.desktop.width = atoi(res); + } else { + sdl.desktop.width = 0; + sdl.desktop.height = 0; + } + } else { + sdl.desktop.width = 0; + sdl.desktop.height = 0; + } sdl.desktop.doublebuf=section->Get_bool("fulldouble"); sdl.desktop.hwscale=section->Get_float("hwscale"); if (sdl.desktop.hwscale<0.1f) { @@ -1010,8 +1027,7 @@ int main(int argc, char* argv[]) { sdl_sec->Add_bool("fullscreen",false); sdl_sec->Add_bool("fulldouble",false); sdl_sec->Add_bool("fullfixed",false); - sdl_sec->Add_int("fullwidth",0); - sdl_sec->Add_int("fullheight",0); + sdl_sec->Add_string("fullresolution","1024x768"); sdl_sec->Add_string("output","surface"); sdl_sec->Add_float("hwscale",1.0); sdl_sec->Add_bool("autolock",true); @@ -1024,7 +1040,7 @@ int main(int argc, char* argv[]) { "fullscreen -- Start dosbox directly in fullscreen.\n" "fulldouble -- Use double buffering in fullscreen.\n" "fullfixed -- Don't resize the screen when in fullscreen.\n" - "fullwidth/height -- What resolution to use for fullscreen, use together with fullfixed.\n" + "fullresolution -- What resolution to use for fullscreen, use together with fullfixed.\n" "output -- What to use for output: surface,overlay" #if C_OPENGL ",opengl,openglnb" From 25ab0c147a2f30dba6fe5f754be55987f1d1738e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 8 Sep 2004 18:58:48 +0000 Subject: [PATCH 1873/4131] First part of patch 1022702 by moe Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1955 --- src/shell/shell_misc.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index c4b13bf7..f82b4838 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.31 2004-08-04 09:12:57 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.32 2004-09-08 18:58:48 qbix79 Exp $ */ #include #include @@ -184,6 +184,10 @@ void DOS_Shell::InputCommand(char * line) { completion_index = 0; } + char *path; + if ((path = strrchr(line+completion_index,'\\'))) completion_index = path-line+1; + if ((path = strrchr(line+completion_index,'/'))) completion_index = path-line+1; + // build the completion list char mask[DOS_PATHLENGTH]; if (completion_start) { From c15193d8f57127876a44966acceaebb8c71ee1df Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 9 Sep 2004 08:39:28 +0000 Subject: [PATCH 1874/4131] mem ->63. List more options Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1956 --- src/dosbox.cpp | 10 +++++----- src/hardware/memory.cpp | 7 ++++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 542d1315..93012cb4 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.76 2004-09-08 09:41:13 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.77 2004-09-09 08:39:28 qbix79 Exp $ */ #include #include @@ -235,16 +235,16 @@ void DOSBOX_Init(void) { "frameskip -- How many frames dosbox skips before drawing one.\n" "aspect -- Do aspect correction.\n" "scaler -- Scaler used to enlarge/enhance low resolution modes.\n" - " Supported are none,normal2x,advmame2x\n" + " Supported are none,normal2x,advmame2x,advmame3x,advinterp2x,tv2x.\n" ); secprop=control->AddSection_prop("cpu",&CPU_Init); secprop->Add_string("core","normal"); - secprop->Add_int("cycles",2500); + secprop->Add_int("cycles",3000); secprop->Add_int("cycleup",500); secprop->Add_int("cycledown",20); MSG_Add("CPU_CONFIGFILE_HELP", - "core -- CPU Core used in emulation: normal,full" + "core -- CPU Core used in emulation: simple,normal,full" #if (C_DYNAMIC_X86) ",dynamic" #endif @@ -288,8 +288,8 @@ void DOSBOX_Init(void) { MSG_Add("MIDI_CONFIGFILE_HELP", "mpu401 -- Enable MPU-401 Emulation.\n" "device -- Device that will receive the MIDI data from MPU-401.\n" - " This can be default,alsa,oss,win32,coreaudio,none.\n" "intelligent -- Operate in Intelligent mode.\n" + " This can be default,alsa,oss,win32,coreaudio,none.\n" "config -- Special configuration options for the device.\n" ); diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 2a511d38..69f86660 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -479,9 +479,10 @@ void MEM_Init(Section * sec) { Bitu memsize=section->Get_int("memsize"); if (memsize<1) memsize=1; - if (memsize>MAX_MEMORY) { - LOG_MSG("Maximum memory size is %d MB",MAX_MEMORY); - memsize=MAX_MEMORY; + /* max 63 to solve problems with certain xms handlers */ + if (memsize>MAX_MEMORY - 1) { + LOG_MSG("Maximum memory size is %d MB",MAX_MEMORY - 1); + memsize=MAX_MEMORY - 1; } MemBase=(HostPt)malloc(memsize*1024*1024); if (!MemBase) E_Exit("Can't allocate main memory of %d MB",memsize); From 3ec0837030c4b71e8567885fe1dba72b608c8e2f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 9 Sep 2004 10:36:45 +0000 Subject: [PATCH 1875/4131] Add startmapper and update documentation Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1957 --- README | 46 +++++++++++++++++++++++++++++++++++++++++---- include/mapper.h | 6 ++++++ src/gui/sdlmain.cpp | 9 +++++---- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/README b/README index a9f2c9fe..3d345039 100644 --- a/README +++ b/README @@ -50,6 +50,7 @@ Type INTRO in dosbox. That's it. Some Frequently Asked Questions: Q: I've got a Z instead of a C at the prompt. +Q: My CD-ROM doesn't work. Q: The mouse doesn't work. Q: The sound stutters. Q: I can't type \ in DOSBox. @@ -70,15 +71,35 @@ A: You have to make your directories available as drives in DOSBox by using In Linux, "mount c /home/username" would give you a C in DOSBox which points at /home/username in Linux. +Q: My CD-ROM doesn't work. +A: To mount your cdrom in DOSBox you have to specify some additional options + when mounting the cdrom. + To enable the most basic cdrom support: + - mount d f:\ -t cdrom + To enable low-level SDL-support: + - mount d f:\ -t cdrom -usecd 0 + To enable low-level ioctl-support(win2k/xp/linux): + - mount d f:\ -t cdrom -usecd 0 -ioctl + To enable low-level aspi-support (win98 with aspi-layer installed): + - mount d f:\ -t cdrom -usecd 0 -apsi + + In the commands: - d driveletter you in DOSBox + - f:\ location of cdrom on your PC. + - 0 The number of the cdrom drive, reported by mount -cd + See also the question: The game/application can't find its CD-ROM. + + Q: The mouse doesn't work. A: Normally DOSBox detects the mouse being used by a game. If you click on the screen then it should get locked and work. Sometimes the DOSBox mouse detection doesn't work with certain games. You might have to force to lock the mouse then with ctrl-F10. + Q: The sound stutters. A: You're using too much cpu power to keep DOSBox running at the current speed. You can either lower the cycles or skip frames or get a faster machine. + You can also increase the prebuffer in the configfile Q: I can't type \ in DOSBox. A: This is a known problem. It only occurs if your keyboard layout isn't US. @@ -86,6 +107,8 @@ A: This is a known problem. It only occurs if your keyboard layout isn't US. 1. Switch your keyboard layout. 2. Use / instead. 3. Add the commands you want to execute to dosbox.conf + 4. Start the keymapper (CTRL-F1 or add -startmapper switch to dosbox) + Q: The game/application can't find its CD-ROM. A: Be sure to mount the CD-ROM with -t cdrom switch. Also try adding the @@ -95,14 +118,17 @@ A: Be sure to mount the CD-ROM with -t cdrom switch. Also try adding the or -aspi. Look at the description elsewhere in this document for their meaning. + Q: The game/application runs much too slow! A: Look at the section "To run resource-demanding games" for more information. + Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. A: This is possible! Just create a config file: config -writeconf dosbox.conf . Start your favourite editor and look at all the settings present. To start DOSBox with your new settings: dosbox -conf dosbox.conf + Q: What sound hardware does DOSBox presently emulate? A: DOSBox emulates several legacy sound devices: - Internal PC speaker @@ -138,6 +164,7 @@ A: While unlikely, this seems to happen. A look at "The Newbie's pictorial guide to DOSBox" located at http://vogons.zetafleet.com/viewforum.php?f=39 might help you. + For more questions read the remainder of this README and/or check the site/forum: http://dosbox.sourceforge.net @@ -153,6 +180,7 @@ An overview of the commandline options you can give to DOSBox: dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] [-lang languagefile] [-machine machinetype] [-noconsole] + [-startmapper] dosbox -version @@ -185,6 +213,10 @@ dosbox -version Setup dosbox to emulate a specific type of machine. Valid choices are: hercules, cga, tandy, vga (default). + -startmapper + Enter the keymapper directly on startup. Useful for people with + keyboard problems. + -version output version information and exit. Useful for frontends. @@ -366,15 +398,21 @@ For more information use the /? command line switch with the programs. ================ ALT-ENTER Go full screen and back. -CTRL-F5 Save a screenshot. -CTRL-F6 Start/Stop recording sound output to a wave file. -CTRL-F7 Decrease frameskip. -CTRL-F8 Increase frameskip. +CTRL-F1 Start the keymapper. +CTRL-F4 Swap mounted disk-image (Only used with imgmount). +CTRL-F5 Save a screenshot. +CTRL-F6 Start/Stop recording sound output to a wave file. +CTRL-ALT-F7 Start/Stop recording of OPL commands. +CTRL-ALT-F8 Start/Stop the recording of raw MIDI commands. +CTRL-F7 Decrease frameskip. +CTRL-F8 Increase frameskip. CTRL-F9 Kill dosbox. CTRL-F10 Capture/Release the mouse. CTRL-F11 Slow down emulation (Decrease DOSBox Cycles). CTRL-F12 Speed up emulation (Increase DOSox Cycles). +These are the default keybindings. They can be changed in the keymapper. + NOTE: Once you increase your DOSBox cycles beyond your computer's maximum capacity, it will produce the same effect as slowing down the emulation. This maximum will vary from computer to computer, there is no standard. diff --git a/include/mapper.h b/include/mapper.h index 1be123b2..79470233 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -27,6 +27,12 @@ enum MapKeys { typedef void (MAPPER_Handler)(void); void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char * eventname,char * buttonname); +void MAPPER_Init(void); +void MAPPER_StartUp(Section * sec); +void MAPPER_Run(void); + + + #define MMOD1 0x1 #define MMOD2 0x2 diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 02404cff..4a6b3e4f 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.76 2004-09-08 14:14:46 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.77 2004-09-09 10:36:45 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -114,9 +114,6 @@ struct private_hwdata { #define PRIO_TOTAL (PRIO_MAX-PRIO_MIN) #endif -void MAPPER_Init(void); -void MAPPER_StartUp(Section * sec); - enum SCREEN_TYPES { SCREEN_SURFACE, SCREEN_SURFACE_DDRAW, @@ -1086,7 +1083,11 @@ int main(int argc, char* argv[]) { SwitchFullScreen(); } } + + /* Init the keyMapper */ MAPPER_Init(); + if (control->cmdline->FindExist("-startmapper")) MAPPER_Run(); + /* Start up main machine */ control->StartUp(); /* Shutdown everything */ From 5c6506d1bfff6cb725494ab295045524bf2b3b22 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 9 Sep 2004 12:34:55 +0000 Subject: [PATCH 1876/4131] Small update to the changelog Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1958 --- ChangeLog | 53 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 710c1bff..58374de4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,21 +1,62 @@ 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 - - Returned filename in ds:dx in create-random-file (c2woody) + - Fixed issues with tabs in commandline not being processed correctly. - Cleaned/improved shutdown sequence. - - Fixed a bug with date and time used on open files. - - Added ps2 mouse-emulation in bios interrupts. (c2woody) + - 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. - - Changed OpenGL so that it is initialized only when used. - Added basic SDA. + - Added TPA and DIB. + - Added Lot's of missing dos tables (c2woody). - Changed psp and dta functions to use dta. - - Added some more PIC commands. (c2woody) + - 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. + - 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) From 30f2bb7612500074dc21db651813583b299819e5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 9 Sep 2004 18:36:50 +0000 Subject: [PATCH 1877/4131] Second part of patch 1022702. (All except addkey). Changed loading of a BCD in the fpu a bit to get more resolution and speed. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1959 --- include/shell.h | 4 ++- src/fpu/fpu_instructions.h | 14 +++++---- src/shell/shell.cpp | 5 +++- src/shell/shell_cmds.cpp | 59 +++++++++++++++++++++++++++++++++++--- 4 files changed, 70 insertions(+), 12 deletions(-) diff --git a/include/shell.h b/include/shell.h index c58156dd..9c16f63f 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.6 2004-08-04 09:12:51 qbix79 Exp $ */ +/* $Id: shell.h,v 1.7 2004-09-09 18:36:50 qbix79 Exp $ */ #ifndef SHELL_H_ #define SHELL_H_ @@ -100,6 +100,8 @@ public: 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); /* The shell's variables */ Bit16u input_handle; BatchFile * bf; diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 3691390c..ff7dc091 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.20 2004-09-08 10:33:16 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.21 2004-09-09 18:36:50 qbix79 Exp $ */ static void FPU_FINIT(void) { @@ -264,7 +264,7 @@ static void FPU_FBST(PhysPt addr) static Real64 FPU_FBLD(PhysPt addr) { - Real64 val = 0; + Bit64u val = 0; Bitu in = 0; Bit64u base = 1; for(Bitu i = 0;i < 9;i++){ @@ -275,11 +275,13 @@ static Real64 FPU_FBLD(PhysPt addr) base *= 10; } - //last number + //last number, only now convert to float in order to get + //the best signification + Real64 temp = static_cast(val); in = mem_readb(addr + 9); - val += ( (in&0xf) * base ); - if(in&0x80) val *= -1.0; - return val; + temp += ( (in&0xf) * base ); + if(in&0x80) temp *= -1.0; + return temp; } diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 2b25e857..c01a5567 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.45 2004-08-26 19:49:26 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.46 2004-09-09 18:36:50 qbix79 Exp $ */ #include #include @@ -108,6 +108,7 @@ Bitu DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn,bool * append) { } void DOS_Shell::ParseLine(char * line) { + LOG(LOG_EXEC,LOG_ERROR)("Parsing command line: %s",line); /* Check for a leading @ */ if (line[0]=='@') line[0]=' '; line=trim(line); @@ -324,6 +325,8 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_CALL_HELP","Start a batch file from within another batch file.\n"); MSG_Add("SHELL_CMD_SUBST_HELP","Assign an internal directory to a drive\n"); MSG_Add("SHELL_CMD_LOADHIGH_HELP","Run a program. For batch file compatibility only.\n"); + MSG_Add("SHELL_CMD_CHOICE_HELP","Waits for a keypress and sets ERRORLEVEL.\n"); + MSG_Add("SHELL_CMD_ATTRIB_HELP","Does nothing. Provided for compatibility.\n"); /* Regular startup */ call_shellstop=CALLBACK_Allocate(); diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index c50cf9e6..3d41a8e0 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,9 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.45 2004-08-04 09:12:57 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.46 2004-09-09 18:36:50 qbix79 Exp $ */ #include +#include #include "shell.h" #include "callback.h" @@ -36,7 +37,7 @@ static SHELL_Cmd cmd_list[]={ { "ERASE", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, { "ECHO", 0, &DOS_Shell::CMD_ECHO, "SHELL_CMD_ECHO_HELP"}, { "EXIT", 0, &DOS_Shell::CMD_EXIT, "SHELL_CMD_EXIT_HELP"}, -{ "HELP", 0, &DOS_Shell::CMD_HELP, "SHELL_CMD_HELP_HELP"}, +{ "HELP", 1, &DOS_Shell::CMD_HELP, "SHELL_CMD_HELP_HELP"}, { "MKDIR", 0, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP"}, { "MD", 1, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP"}, { "RMDIR", 0, &DOS_Shell::CMD_RMDIR, "SHELL_CMD_RMDIR_HELP"}, @@ -53,6 +54,8 @@ static SHELL_Cmd cmd_list[]={ { "SUBST", 0, &DOS_Shell::CMD_SUBST, "SHELL_CMD_SUBST_HELP"}, { "LOADHIGH", 0, &DOS_Shell::CMD_LOADHIGH, "SHELL_CMD_LOADHIGH_HELP"}, { "LH", 1, &DOS_Shell::CMD_LOADHIGH, "SHELL_CMD_LOADHIGH_HELP"}, +{ "CHOICE", 0, &DOS_Shell::CMD_CHOICE, "SHELL_CMD_CHOICE_HELP"}, +{ "ATTRIB", 0, &DOS_Shell::CMD_ATTRIB, "SHELL_CMD_ATTRIB_HELP"}, {0,0,0,0} }; @@ -361,11 +364,16 @@ void DOS_Shell::CMD_DIR(char * args) { } void DOS_Shell::CMD_COPY(char * args) { + static char defaulttarget[] = "."; StripSpaces(args); DOS_DTA dta(dos.dta()); Bit32u size;Bit16u date;Bit16u time;Bit8u attr; char name[DOS_NAMELENGTH_ASCII]; + // ignore /b and /t switches: always copy binary + ScanCMDBool(args,"B"); + ScanCMDBool(args,"T"); + char * rem=ScanCMDRemain(args); if (rem) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); @@ -373,7 +381,9 @@ void DOS_Shell::CMD_COPY(char * args) { } // source/target char* source = StripWord(args); - char* target = StripWord(args); + char* target = NULL; + if (args && *args) target = StripWord(args); + if (!target || !*target) target = defaulttarget; // Target and Source have to be there if (!source || !strlen(source)) { @@ -577,7 +587,6 @@ void DOS_Shell::CMD_PAUSE(char * args){ DOS_ReadFile (STDIN,&c,&n); } - void DOS_Shell::CMD_CALL(char * args){ this->call=true; /* else the old batchfile will be closed first */ this->ParseLine(args); @@ -642,3 +651,45 @@ void DOS_Shell::CMD_SUBST (char * args) { void DOS_Shell::CMD_LOADHIGH(char *args){ this->ParseLine(args); } + +void DOS_Shell::CMD_CHOICE(char * args){ + static char defargs[] = "[YN]"; + static char defchoice[] = "yn"; + char *rem = NULL, *ptr; + bool optN = false; + if (args) { + char *last = strchr(args,0); + StripSpaces(args); + optN=ScanCMDBool(args,"N"); + rem=ScanCMDRemain(args); + if (rem && *rem && (tolower(rem[1]) != 'c' || rem[2] != ':')) { + WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); + return; + } + if (args == rem) args = strchr(rem,0)+1; + if (rem) rem += 3; + if (args > last) args = NULL; + } + if (!args || !*args) args = defargs; + if (!rem || !*rem) rem = defchoice; + ptr = rem; + Bit8u c; + while ((c = *ptr)) *ptr++ = tolower(c); + + WriteOut(args); + if (!optN) WriteOut("\r\n"); + Bit16u n=1; + do { + DOS_ReadFile (STDIN,&c,&n); + } while (!c || !(ptr = strchr(rem,tolower(c)))); + if (optN) { + DOS_WriteFile (STDOUT,&c, &n); + WriteOut("\r\n"); + } + dos.return_code = ptr-rem+1; +} + +void DOS_Shell::CMD_ATTRIB(char *args){ + // No-Op for now. +} + From 52d01cf49af96e95a0942013ff26af7b2fcc085c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 9 Sep 2004 21:12:58 +0000 Subject: [PATCH 1878/4131] Removed yot added canadacow. updated fanskapet Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1960 --- AUTHORS | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/AUTHORS b/AUTHORS index 7d2b32af..23121d5d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,9 +1,8 @@ The DOSBox Team --------------- -Sjoerd v.d. Berg +Sjoerd v.d. Berg Peter Veenstra -Felix Jakschitsch Ulf Wohlers -Tommy Frössman - +Tommy Frössman +Dean Beeler From ad1f331777c0632952e588b2a677d157e63a8839 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 10 Sep 2004 07:44:15 +0000 Subject: [PATCH 1879/4131] forgot to include a few things. (Jeremy) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1961 --- src/dosbox.cpp | 4 ++-- src/gui/sdlmain.cpp | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 93012cb4..2ed8ec4b 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.77 2004-09-09 08:39:28 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.78 2004-09-10 07:44:12 qbix79 Exp $ */ #include #include @@ -235,7 +235,7 @@ void DOSBOX_Init(void) { "frameskip -- How many frames dosbox skips before drawing one.\n" "aspect -- Do aspect correction.\n" "scaler -- Scaler used to enlarge/enhance low resolution modes.\n" - " Supported are none,normal2x,advmame2x,advmame3x,advinterp2x,tv2x.\n" + " Supported are none,normal2x,advmame2x,advmame3x,advinterp2x,interp2x,tv2x.\n" ); secprop=control->AddSection_prop("cpu",&CPU_Init); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 4a6b3e4f..c8dbfaaf 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.77 2004-09-09 10:36:45 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.78 2004-09-10 07:44:15 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1041,6 +1041,9 @@ int main(int argc, char* argv[]) { "output -- What to use for output: surface,overlay" #if C_OPENGL ",opengl,openglnb" +#endif +#if defined(HAVE_DDRAW_H) && defined(WIN32) + ",ddraw" #endif ".\n" "hwscale -- Extra scaling of window if the output device supports hardware scaling.\n" From 388c6abfcb774c2f6f3971393bcca36f8707ff19 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 10 Sep 2004 08:02:50 +0000 Subject: [PATCH 1880/4131] Typo :( (Thanks for telling me, Srecko) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1962 --- src/dosbox.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 2ed8ec4b..6a8e5247 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.78 2004-09-10 07:44:12 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.79 2004-09-10 08:02:50 qbix79 Exp $ */ #include #include @@ -287,8 +287,8 @@ void DOSBOX_Init(void) { MSG_Add("MIDI_CONFIGFILE_HELP", "mpu401 -- Enable MPU-401 Emulation.\n" - "device -- Device that will receive the MIDI data from MPU-401.\n" "intelligent -- Operate in Intelligent mode.\n" + "device -- Device that will receive the MIDI data from MPU-401.\n" " This can be default,alsa,oss,win32,coreaudio,none.\n" "config -- Special configuration options for the device.\n" ); From 9e3a856b8ffd7bad20dc9662ca4749d356c39283 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 10 Sep 2004 17:41:31 +0000 Subject: [PATCH 1881/4131] removed email Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1963 --- README | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README b/README index 3d345039..3520f1e9 100644 --- a/README +++ b/README @@ -373,9 +373,9 @@ MIXER IMGMOUNT - A utility to mount disk images and cdrom images in DOSBox. + A utility to mount disk images and CD-ROM images in DOSBox. - CDROM: either iso or cue/bin is supported: + CD-ROM: either iso or cue/bin is supported: IMGMOUNT DRIVE imagefile -t iso imagefile @@ -522,5 +522,6 @@ The Beta Testers. 12. Contact: ============ -DOSBox Crew: dosbox.crew@gmail.com +See the site: http://dosbox.sourceforge.net +for an emailaddress (The Crew-page). From c002268376c314bc3a7bdf148d76e743072ab3de Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 10 Sep 2004 18:08:23 +0000 Subject: [PATCH 1882/4131] Update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1964 --- src/platform/visualc/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index d03023f9..bf95d649 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -1,6 +1,6 @@ #define INLINE __forceinline -#define VERSION "0.61" +#define VERSION "0.62" /* Define to 1 to enable internal debugger, requires libcurses */ From fefa2162105471c844a3842e527e279381178c62 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 10 Sep 2004 18:57:53 +0000 Subject: [PATCH 1883/4131] Casting bug Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1965 --- src/dos/dos_programs.cpp | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 48688729..325839a5 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.27 2004-09-05 14:23:04 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.28 2004-09-10 18:57:53 qbix79 Exp $ */ #include #include @@ -221,23 +221,32 @@ private: localDrive* ldp=0; if (!DOS_MakeName((char *)filename,fullname,&drive)) return NULL; - ldp=(localDrive*)Drives[drive]; - tmpfile = ldp->GetSystemFilePtr(fullname, "r"); - if(tmpfile == NULL) { - WriteOut(MSG_Get("PROGRAM_BOOT_NOT_EXIST")); - return NULL; + + try { + ldp=dynamic_cast(Drives[drive]); + if(!ldp) return NULL; + + tmpfile = ldp->GetSystemFilePtr(fullname, "r"); + if(tmpfile == NULL) { + WriteOut(MSG_Get("PROGRAM_BOOT_NOT_EXIST")); + return NULL; + } + fclose(tmpfile); + tmpfile = ldp->GetSystemFilePtr(fullname, "rb+"); + if(tmpfile == NULL) { + WriteOut(MSG_Get("PROGRAM_BOOT_NOT_OPEN")); + return NULL; + } + + fseek(tmpfile,0L, SEEK_END); + *ksize = (ftell(tmpfile) / 1024); + *bsize = ftell(tmpfile); + return tmpfile; } - fclose(tmpfile); - tmpfile = ldp->GetSystemFilePtr(fullname, "rb+"); - if(tmpfile == NULL) { - WriteOut(MSG_Get("PROGRAM_BOOT_NOT_OPEN")); + catch(...) { return NULL; } - fseek(tmpfile,0L, SEEK_END); - *ksize = (ftell(tmpfile) / 1024); - *bsize = ftell(tmpfile); - return tmpfile; } void printError(void) { From 8385ace19055c852ac5d6ae9ca12e5c7baeaca40 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 10 Sep 2004 22:08:45 +0000 Subject: [PATCH 1884/4131] cga and tandy machines skip the extended vga cursor shape routine Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1966 --- src/ints/int10_char.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index fa2b8971..7cac4d89 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.29 2004-08-04 09:12:56 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.30 2004-09-10 22:08:45 harekiet Exp $ */ /* Character displaying moving functions */ @@ -298,6 +298,8 @@ void INT10_SetActivePage(Bit8u page) { void INT10_SetCursorShape(Bit8u first,Bit8u last) { real_writew(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE,last|(first<<8)); + if (machine==MCH_CGA) goto dowrite; + if (machine==MCH_TANDY) goto dowrite; /* Skip CGA cursor emulation if EGA/VGA system is active */ if (!(real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL) & 0x8)) { /* Check for CGA type 01, invisible */ @@ -308,7 +310,7 @@ void INT10_SetCursorShape(Bit8u first,Bit8u last) { } /* Check if we need to convert CGA Bios cursor values */ if (!(real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL) & 0x1)) { - if (CurMode->mode>0x3) goto dowrite; //Only mode 0-3 are text modes on cga +// if (CurMode->mode>0x3) goto dowrite; //Only mode 0-3 are text modes on cga if ((first & 0xe0) || (last & 0xe0)) goto dowrite; Bit8u cheight=real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT)-1; /* Creative routine i based of the original ibmvga bios */ From 5c26302fc2f49b9f566ce96b5c09c9ae25a5b799 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 10 Sep 2004 22:09:54 +0000 Subject: [PATCH 1885/4131] Fix a warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1967 --- src/ints/int10_vesa.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 1acf9f76..6bcb87b9 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.11 2004-08-04 09:12:56 qbix79 Exp $ */ +/* $Id: int10_vesa.cpp,v 1.12 2004-09-10 22:09:54 harekiet Exp $ */ #include #include @@ -299,7 +299,7 @@ Bit8u VESA_GetDisplayStart(Bit16u & x,Bit16u & y) { static Bitu SetWindowPositionHandler(void) { if (reg_bh) reg_ah=VESA_GetCPUWindow(reg_bl,reg_dx); - else reg_ah=VESA_SetCPUWindow(reg_bl,reg_dx); + else reg_ah=VESA_SetCPUWindow(reg_bl,(Bit8u)reg_dx); reg_al=0x4f; return 0; } From dfbb19541855c23543d5c01bb7fd8b61abcbc24a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 10 Sep 2004 22:15:20 +0000 Subject: [PATCH 1886/4131] changes for improved timing event system Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1968 --- include/pic.h | 16 ++++---- include/vga.h | 18 ++++---- src/hardware/adlib.cpp | 6 +-- src/hardware/cmos.cpp | 30 ++++++-------- src/hardware/gus.cpp | 13 +++--- src/hardware/keyboard.cpp | 4 +- src/hardware/mixer.cpp | 8 +--- src/hardware/mpu401.cpp | 2 +- src/hardware/pic.cpp | 16 ++++---- src/hardware/sblaster.cpp | 20 ++++----- src/hardware/timer.cpp | 82 ++++++++++++++++++------------------- src/hardware/vga.cpp | 2 +- src/hardware/vga_memory.cpp | 2 +- 13 files changed, 103 insertions(+), 116 deletions(-) diff --git a/include/pic.h b/include/pic.h index c2a8a525..43caaf40 100644 --- a/include/pic.h +++ b/include/pic.h @@ -32,21 +32,20 @@ typedef void (* PIC_EventHandler)(Bitu val); #define PIC_MAXIRQ 15 #define PIC_NOIRQ 0xFF - extern Bitu PIC_IRQCheck; extern Bitu PIC_IRQActive; extern Bitu PIC_Ticks; -INLINE Bitu PIC_Index(void) { - return ((CPU_CycleMax-CPU_CycleLeft-CPU_Cycles)*1000)/CPU_CycleMax; +INLINE float PIC_TickIndex(void) { + return (CPU_CycleMax-CPU_CycleLeft-CPU_Cycles)/(float)CPU_CycleMax; } -INLINE Bits PIC_MakeCycles(Bitu amount) { - return (CPU_CycleMax*amount)/1000; +INLINE Bits PIC_MakeCycles(double amount) { + return (Bits)(CPU_CycleMax*amount); } -INLINE Bit64u PIC_MicroCount(void) { - return PIC_Ticks*1000+PIC_Index(); +INLINE double PIC_FullIndex(void) { + return PIC_Ticks+PIC_TickIndex(); } void PIC_ActivateIRQ(Bitu irq); @@ -55,7 +54,8 @@ void PIC_DeActivateIRQ(Bitu irq); void PIC_runIRQs(void); bool PIC_RunQueue(void); -void PIC_AddEvent(PIC_EventHandler handler,Bitu delay,Bitu val=0); +//Delay in milliseconds +void PIC_AddEvent(PIC_EventHandler handler,float delay,Bitu val=0); void PIC_RemoveEvents(PIC_EventHandler handler); void PIC_SetIRQMask(Bitu irq, bool masked); diff --git a/include/vga.h b/include/vga.h index 893834db..a8814c06 100644 --- a/include/vga.h +++ b/include/vga.h @@ -89,7 +89,6 @@ typedef struct { typedef struct { bool resizing; - bool drawing; Bitu width; Bitu height; Bitu blocks; @@ -106,20 +105,21 @@ typedef struct { Bitu parts_lines; Bitu parts_left; struct { - Bitu vtotal; - Bitu vstart; - Bitu vend; - Bitu htotal; - Bitu hstart; - Bitu hend; - Bitu parts; - } micro; + float vtotal; + float vstart; + float vend; + float htotal; + float hstart; + float hend; + float parts; + } delay; 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; diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 10a9d690..01f62add 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -62,7 +62,7 @@ namespace OPL2 { } void TimerHandler(int channel,double interval_Sec) { if (interval_Sec==0.0) return; - PIC_AddEvent(TimerOver,(Bitu)(1000000.0*interval_Sec),channel); + PIC_AddEvent(TimerOver,1000.0f*interval_Sec,channel); } } #undef OSD_CPU_H @@ -75,7 +75,7 @@ namespace THEOPL3 { } void TimerHandler(int channel,double interval_Sec) { if (interval_Sec==0.0) return; - PIC_AddEvent(TimerOver,(Bitu)(1000000.0*interval_Sec),channel); + PIC_AddEvent(TimerOver,1000.0f*interval_Sec,channel); } } @@ -125,7 +125,7 @@ static void OPL_CallBack(Bitu len) { opl.chan->AddSamples_s16(len,(Bit16s*)MixTemp); break; } - if ((PIC_Ticks-opl.last_used)>5000) { + if ((PIC_Ticks-opl.last_used)>30000) { opl.chan->Enable(false); opl.active=false; } diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index cd878a98..59cf9eb1 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -33,34 +33,28 @@ static struct { struct { bool enabled; Bit8u div; - Bitu micro; + float delay; } timer; struct { - Bit64u timer; - Bit64u ended; - Bit64u alarm; + double timer; + double ended; + double alarm; } last; - bool ack; bool update_ended; } cmos; static void cmos_timerevent(Bitu val) { PIC_ActivateIRQ(8); - if(cmos.timer.enabled) PIC_AddEvent(cmos_timerevent,cmos.timer.micro); - if (cmos.ack) { - PIC_AddEvent(cmos_timerevent,cmos.timer.micro); - cmos.regs[0x0c]|=0x0a0; - cmos.ack=false; - } + if (cmos.timer.enabled) PIC_AddEvent(cmos_timerevent,cmos.timer.delay); } static void cmos_checktimer(void) { PIC_RemoveEvents(cmos_timerevent); if (cmos.timer.div<=2) cmos.timer.div+=7; - cmos.timer.micro=(Bitu) (1000000.0/(32768.0 / (1 << (cmos.timer.div - 1)))); + cmos.timer.delay=(1000.0f/(32768.0f / (1 << (cmos.timer.div - 1)))); if (!cmos.timer.div || !cmos.timer.enabled) return; - LOG(LOG_PIT,LOG_NORMAL)("RTC Timer at %f hz",1000000.0/cmos.timer.micro); - PIC_AddEvent(cmos_timerevent,cmos.timer.micro); + LOG(LOG_PIT,LOG_NORMAL)("RTC Timer at %.2f hz",1000.0/cmos.timer.delay); + PIC_AddEvent(cmos_timerevent,cmos.timer.delay); } void cmos_selreg(Bitu port,Bitu val,Bitu iolen) { @@ -146,7 +140,7 @@ static Bitu cmos_readreg(Bitu port,Bitu iolen) { case 0x05: /* Hours Alarm */ return cmos.regs[cmos.reg]; case 0x0a: /* Status register C */ - if (PIC_Index()<0x2) { + if (PIC_TickIndex()<0.002) { return (cmos.regs[0x0a]&0x7f) | 0x80; } else { return (cmos.regs[0x0a]&0x7f); @@ -160,12 +154,12 @@ static Bitu cmos_readreg(Bitu port,Bitu iolen) { } else { /* Give correct values at certain times */ Bit8u val=0; - Bit64u index=PIC_MicroCount(); - if (index>=(cmos.last.timer+cmos.timer.micro)) { + double index=PIC_FullIndex(); + if (index>=(cmos.last.timer+cmos.timer.delay)) { cmos.last.timer=index; val|=0x40; } - if (index>=(cmos.last.ended+1000000)) { + if (index>=(cmos.last.ended+1000)) { cmos.last.ended=index; val|=0x10; } diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 40ff9785..5da73907 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -79,7 +79,7 @@ struct GFGus { bool raiseirq; bool masked; bool running; - Bit32u delay; + float delay; } timers[2]; Bit32u rate; Bit16u portbase; @@ -366,8 +366,8 @@ static void GUSReset(void) { myGUS.timers[0].value = 0xff; myGUS.timers[1].value = 0xff; - myGUS.timers[0].delay = 80; - myGUS.timers[1].delay = 320; + myGUS.timers[0].delay = 0.080f; + myGUS.timers[1].delay = 0.320f; myGUS.ChangeIRQDMA = false; // Stop all channels int i; @@ -471,7 +471,8 @@ static void GUS_TimerEvent(Bitu val) { myGUS.IRQStatus|=0x4 << val; GUS_CheckIRQ(); } - if (myGUS.timers[val].running) PIC_AddEvent(GUS_TimerEvent,myGUS.timers[val].delay,val); + if (myGUS.timers[val].running) + PIC_AddEvent(GUS_TimerEvent,myGUS.timers[val].delay,val); }; @@ -588,11 +589,11 @@ static void ExecuteGlobRegister(void) { break; case 0x46: // Timer 1 control myGUS.timers[0].value = (Bit8u)(myGUS.gRegData>>8); - myGUS.timers[0].delay = (0x100 - myGUS.timers[0].value) * 80; + myGUS.timers[0].delay = (0x100 - myGUS.timers[0].value) * 0.080f; break; case 0x47: // Timer 2 control myGUS.timers[1].value = (Bit8u)(myGUS.gRegData>>8); - myGUS.timers[1].delay = (0x100 - myGUS.timers[1].value) * 320; + myGUS.timers[1].delay = (0x100 - myGUS.timers[1].value) * 0.320f; break; case 0x49: // DMA sampling control register myGUS.SampControl = (Bit8u)(myGUS.gRegData>>8); diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 301876c3..203d8bca 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.27 2004-08-04 09:12:55 qbix79 Exp $ */ +/* $Id: keyboard.cpp,v 1.28 2004-09-10 22:15:20 harekiet Exp $ */ #include #include @@ -30,7 +30,7 @@ #include "mixer.h" #define KEYBUFSIZE 32 -#define KEYDELAY 300 //Considering 20-30 khz serial clock and 11 bits/char +#define KEYDELAY 0.300f //Considering 20-30 khz serial clock and 11 bits/char enum KeyCommands { CMD_NONE, diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index e8dbc67d..f52b9c3a 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -250,12 +250,8 @@ void MixerChannel::FillUp(void) { SDL_UnlockAudio(); return; } - Bitu filled=(done-mixer.done)*1000/(mixer.needed-mixer.done); - Bitu index=PIC_Index(); - if (filled @@ -57,7 +57,8 @@ static IRQ_Block irqs[16]; static PIC_Controller pics[2]; struct PICEntry { - Bitu index;Bitu value; + float index; + Bitu value; PIC_EventHandler event; PICEntry * next; }; @@ -294,21 +295,20 @@ static void AddEntry(PICEntry * entry) { break; } } - Bits cycles=PIC_MakeCycles(pic.next_entry->index-PIC_Index()); + Bits cycles=PIC_MakeCycles(pic.next_entry->index-PIC_TickIndex()); if (cyclesindex=index; + entry->index=delay+PIC_TickIndex();; entry->event=handler; entry->value=val; pic.free_entry=pic.free_entry->next; @@ -350,7 +350,7 @@ bool PIC_RunQueue(void) { return false; } /* Check the queue for an entry */ - Bitu index=PIC_Index(); + double index=PIC_TickIndex(); while (pic.next_entry && pic.next_entry->index<=index) { PICEntry * entry=pic.next_entry; pic.next_entry=entry->next; @@ -412,7 +412,7 @@ void TIMER_AddTick(void) { /* Go through the list of scheduled events and lower their index with 1000 */ PICEntry * entry=pic.next_entry; while (entry) { - if (entry->index>1000) entry->index-=1000; + if (entry->index>=1) entry->index-=1; else entry->index=0; entry=entry->next; } diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 8c43655d..32a0e35c 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -425,27 +425,27 @@ static void DMA_Silent_Event(Bitu val) { } if (sb.dma.left) { Bitu bigger=(sb.dma.left > sb.dma.min) ? sb.dma.min : sb.dma.left; - Bitu index=(bigger*1000000)/sb.dma.rate; - PIC_AddEvent(DMA_Silent_Event,index,bigger); + float delay=(bigger*1000.0f)/sb.dma.rate; + PIC_AddEvent(DMA_Silent_Event,delay,bigger); } } static void END_DMA_Event(Bitu val) { - GenerateDMASound(sb.dma.left); + GenerateDMASound(val); } static void CheckDMAEnd(void) { if (!sb.dma.left) return; if (!sb.speaker) { Bitu bigger=(sb.dma.left > sb.dma.min) ? sb.dma.min : sb.dma.left; - Bitu index=(bigger*1000000)/sb.dma.rate; - PIC_AddEvent(DMA_Silent_Event,index,bigger); - LOG(LOG_SB,LOG_NORMAL)("Silent DMA Transfer scheduling IRQ in %d microseconds",index); + float delay=(bigger*1000.0f)/sb.dma.rate; + PIC_AddEvent(DMA_Silent_Event,delay,bigger); + LOG(LOG_SB,LOG_NORMAL)("Silent DMA Transfer scheduling IRQ in %.3f milliseconds",delay); } else if (sb.dma.leftstart; + double index=PIC_FullIndex()-p->start; switch (p->mode) { case 0: if (p->new_mode) return false; - if (micro>p->micro) return true; + if (index>p->delay) return true; else return false; break; case 2: if (p->new_mode) return true; - micro%=p->micro; - return micro>0; + index=fmod(index,(double)p->delay); + return index>0; case 3: if (p->new_mode) return true; - micro%=p->micro; - return micro*2micro; + index=fmod(index,(double)p->delay); + return index*2delay; default: LOG(LOG_PIT,LOG_ERROR)("Illegal Mode %d for reading output",p->mode); return true; @@ -88,37 +90,32 @@ static void counter_latch(Bitu counter) { /* Fill the read_latch of the selected counter with current count */ PIT_Block * p=&pit[counter]; p->go_read_latch=false; - - Bit64s micro=PIC_MicroCount()-p->start; + double index=PIC_FullIndex()-p->start; switch (p->mode) { + case 4: /* Software Triggered Strobe */ case 0: /* Interrupt on Terminal Count */ /* Counter keeps on counting after passing terminal count */ - if (micro>p->micro) { - micro-=p->micro; - micro%=(Bit64u)(1000000/((float)PIT_TICK_RATE/(float)0x10000)); - p->read_latch=(Bit16u)(0x10000-(((double)micro/(double)p->micro)*(double)0x10000)); + if (index>p->delay) { + index-=p->delay; + index=fmod(index,(1000.0/PIT_TICK_RATE)*0x1000); + p->read_latch=(Bit16u)(0xffff-index*0xffff); } else { - p->read_latch=(Bit16u)(p->cntr-(((double)micro/(double)p->micro)*(double)p->cntr)); + p->read_latch=(Bit16u)(p->cntr-index*(PIT_TICK_RATE/1000.0)); } break; case 2: /* Rate Generator */ - micro%=p->micro; - p->read_latch=(Bit16u)(p->cntr-(((double)micro/(double)p->micro)*(double)p->cntr)); + index=fmod(index,(double)p->delay); + p->read_latch=(Bit16u)(p->cntr - (index/p->delay)*p->cntr); break; case 3: /* Square Wave Rate Generator */ - micro%=p->micro; - micro*=2; - if (micro>p->micro) micro-=p->micro; - p->read_latch=(Bit16u)(p->cntr-(((double)micro/(double)p->micro)*(double)p->cntr)); - break; - case 4: /* Software Triggered Strobe */ - if (micro>p->micro) p->read_latch=p->write_latch; - else p->read_latch=(Bit16u)(p->cntr-(((double)micro/(double)p->micro)*(double)p->cntr)); + index=fmod(index,(double)p->delay); + index*=2; + if (index>p->delay) index-=p->delay; + p->read_latch=(Bit16u)(p->cntr - (index/p->delay)*p->cntr); break; default: LOG(LOG_PIT,LOG_ERROR)("Illegal Mode %d for reading counter %d",p->mode,counter); - micro%=p->micro; - p->read_latch=(Bit16u)(p->cntr-(((double)micro/(double)p->micro)*(double)p->cntr)); + p->read_latch=0xffff; break; } } @@ -151,16 +148,15 @@ static void write_latch(Bitu port,Bitu val,Bitu iolen) { if (p->bcd == false) p->cntr = 0x10000; else p->cntr=9999; } else p->cntr = p->write_latch; - p->start=PIC_MicroCount(); - p->micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)p->cntr)); - if (!p->micro) p->micro=1; + p->start=PIC_FullIndex(); + p->delay=(1000.0f/((float)PIT_TICK_RATE/(float)p->cntr)); switch (counter) { case 0x00: /* Timer hooked to IRQ 0 */ if (p->new_mode) { p->new_mode=false; - PIC_AddEvent(PIT0_Event,p->micro); + PIC_AddEvent(PIT0_Event,p->delay); } else LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer set without new control word"); - LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,(Bit32u)p->mode); + LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.2f Hz mode %d",1000.0/p->delay,p->mode); break; case 0x02: /* Timer hooked to PC-Speaker */ // LOG(LOG_PIT,"PIT 2 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode); @@ -283,10 +279,10 @@ void TIMER_Init(Section* sect) { pit[2].cntr=1320; pit[2].go_read_latch=true; - pit[0].micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)pit[0].cntr)); - pit[1].micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)pit[1].cntr)); - pit[2].micro=(Bits)(1000000/((float)PIT_TICK_RATE/(float)pit[2].cntr)); + pit[0].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[0].cntr)); + pit[1].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[1].cntr)); + pit[2].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[2].cntr)); - PIC_AddEvent(PIT0_Event,pit[0].micro); + PIC_AddEvent(PIT0_Event,pit[0].delay); } diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 010fe8a9..a5f6d63a 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -71,7 +71,7 @@ void VGA_StartResize(void) { if (!vga.draw.resizing) { vga.draw.resizing=true; /* Start a resize after 50 ms */ - PIC_AddEvent(VGA_SetupDrawing,50000); + PIC_AddEvent(VGA_SetupDrawing,50); } } diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index e3c8ced2..78846035 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -419,7 +419,7 @@ static void VGA_DoUpdateLFB(Bitu val) { void VGA_StartUpdateLFB(void) { if (!lfb_update) { lfb_update=true; - PIC_AddEvent(VGA_DoUpdateLFB,100); //100 microseconds later + PIC_AddEvent(VGA_DoUpdateLFB,0.100f); //100 microseconds later } } From 85079912c9d56806ebfe878553d704ad0105c711 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 10 Sep 2004 22:15:58 +0000 Subject: [PATCH 1887/4131] changes for improved timing event system Now generate output with floating point variables Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1969 --- src/hardware/pcspeaker.cpp | 150 ++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 76 deletions(-) diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 3166bf2e..77ef82a9 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -30,16 +30,16 @@ #define SPKR_ENTRIES 1024 #define SPKR_VOLUME 5000 -#define SPKR_SHIFT 8 -#define SPKR_SPEED ((SPKR_VOLUME*2)/70) +//#define SPKR_SHIFT 8 +#define SPKR_SPEED (float)((SPKR_VOLUME*2)/0.070f) enum SPKR_MODES { SPKR_OFF,SPKR_ON,SPKR_PIT_OFF,SPKR_PIT_ON }; struct DelayEntry { - Bitu index; - Bits vol; + float index; + float vol; }; static struct { @@ -48,18 +48,18 @@ static struct { Bitu pit_mode; Bitu rate; - Bits pit_last; - Bitu pit_new_max,pit_new_half; - Bitu pit_max,pit_half; - Bitu pit_index; - Bits volwant,volcur; + float pit_last; + float pit_new_max,pit_new_half; + float pit_max,pit_half; + float pit_index; + float volwant,volcur; Bitu last_ticks; - Bitu last_index; + float last_index; DelayEntry entries[SPKR_ENTRIES]; Bitu used; } spkr; -static void AddDelayEntry(Bitu index,Bits vol) { +static void AddDelayEntry(float index,float vol) { if (spkr.used==SPKR_ENTRIES) { return; } @@ -69,38 +69,37 @@ static void AddDelayEntry(Bitu index,Bits vol) { } -static void ForwardPIT(Bitu newindex) { - Bitu micro=(newindex-spkr.last_index) << SPKR_SHIFT; - Bitu delay_base=spkr.last_index << SPKR_SHIFT; +static void ForwardPIT(float newindex) { + float passed=(newindex-spkr.last_index); + float delay_base=spkr.last_index; spkr.last_index=newindex; switch (spkr.pit_mode) { case 0: return; case 2: - while (micro) { + while (passed>0) { /* passed the initial low cycle? */ if (spkr.pit_index>=spkr.pit_half) { /* Start a new low cycle */ - if ((spkr.pit_index+micro)>=spkr.pit_max) { - Bitu delay=spkr.pit_max-spkr.pit_index; - delay_base+=delay;micro-=delay; + if ((spkr.pit_index+passed)>=spkr.pit_max) { + float delay=spkr.pit_max-spkr.pit_index; + delay_base+=delay;passed-=delay; spkr.pit_last=-SPKR_VOLUME; if (spkr.mode==SPKR_PIT_ON) AddDelayEntry(delay_base,spkr.pit_last); spkr.pit_index=0; } else { - spkr.pit_index+=micro; + spkr.pit_index+=passed; return; } } else { - if ((spkr.pit_index+micro)>=spkr.pit_half) { - Bitu delay=spkr.pit_half-spkr.pit_index; - delay_base+=delay;micro-=delay; + if ((spkr.pit_index+passed)>=spkr.pit_half) { + float delay=spkr.pit_half-spkr.pit_index; + delay_base+=delay;passed-=delay; spkr.pit_last=SPKR_VOLUME; if (spkr.mode==SPKR_PIT_ON) AddDelayEntry(delay_base,spkr.pit_last); spkr.pit_index=spkr.pit_half; } else { - /* Didn't reach end, forward index */ - spkr.pit_index+=micro; + spkr.pit_index+=passed; return; } } @@ -108,12 +107,12 @@ static void ForwardPIT(Bitu newindex) { break; //END CASE 2 case 3: - while (micro) { + while (passed>0) { /* Determine where in the wave we're located */ if (spkr.pit_index>=spkr.pit_half) { - if ((spkr.pit_index+micro)>=spkr.pit_max) { - Bitu delay=spkr.pit_max-spkr.pit_index; - delay_base+=delay;micro-=delay; + if ((spkr.pit_index+passed)>=spkr.pit_max) { + float delay=spkr.pit_max-spkr.pit_index; + delay_base+=delay;passed-=delay; spkr.pit_last=SPKR_VOLUME; if (spkr.mode==SPKR_PIT_ON) AddDelayEntry(delay_base,spkr.pit_last); spkr.pit_index=0; @@ -121,20 +120,18 @@ static void ForwardPIT(Bitu newindex) { spkr.pit_half=spkr.pit_new_half; spkr.pit_max=spkr.pit_new_max; } else { - /* Didn't reach end, forward index */ - spkr.pit_index+=micro; + spkr.pit_index+=passed; return; } } else { - if ((spkr.pit_index+micro)>=spkr.pit_half) { - Bitu delay=spkr.pit_half-spkr.pit_index; - delay_base+=delay;micro-=delay; + if ((spkr.pit_index+passed)>=spkr.pit_half) { + float delay=spkr.pit_half-spkr.pit_index; + delay_base+=delay;passed-=delay; spkr.pit_last=-SPKR_VOLUME; if (spkr.mode==SPKR_PIT_ON) AddDelayEntry(delay_base,spkr.pit_last); spkr.pit_index=spkr.pit_half; } else { - /* Didn't reach end, forward index */ - spkr.pit_index+=micro; + spkr.pit_index+=passed; return; } } @@ -144,13 +141,13 @@ static void ForwardPIT(Bitu newindex) { case 4: if (spkr.pit_index=spkr.pit_max) { - Bitu delay=spkr.pit_max-spkr.pit_index; - delay_base+=delay;micro-=delay; + if (spkr.pit_index+passed>=spkr.pit_max) { + float delay=spkr.pit_max-spkr.pit_index; + delay_base+=delay;passed-=delay; spkr.pit_last=-SPKR_VOLUME; if (spkr.mode==SPKR_PIT_ON) AddDelayEntry(delay_base,spkr.pit_last); //No new events unless reprogrammed spkr.pit_index=spkr.pit_max; - } else spkr.pit_index+=micro; + } else spkr.pit_index+=passed; } break; //END CASE 4 @@ -163,7 +160,7 @@ void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode) { spkr.last_index=0; } spkr.last_ticks=PIC_Ticks; - Bitu newindex=PIC_Index(); + float newindex=PIC_TickIndex(); ForwardPIT(newindex); switch (mode) { case 0: /* Mode 0 one shot, used with realsound */ @@ -171,16 +168,16 @@ void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode) { if (cntr>80) { cntr=80; } - spkr.pit_last=(cntr-40)*SPKR_SPEED; - AddDelayEntry(newindex << SPKR_SHIFT,spkr.pit_last); + spkr.pit_last=((float)cntr-40)*(SPKR_VOLUME/40.0f); + AddDelayEntry(newindex,spkr.pit_last); spkr.pit_index=0; break; case 2: /* Single cycle low, rest low high generator */ spkr.pit_index=0; spkr.pit_last=-SPKR_VOLUME; - AddDelayEntry(newindex << SPKR_SHIFT,spkr.pit_last); - spkr.pit_half=(Bitu)(((double)(1000000 << SPKR_SHIFT)/PIT_TICK_RATE)*1); - spkr.pit_max=(Bitu)(((double)(1000000 << SPKR_SHIFT)/PIT_TICK_RATE)*cntr); + AddDelayEntry(newindex,spkr.pit_last); + spkr.pit_half=(1000.0f/PIT_TICK_RATE)*1; + spkr.pit_max=(1000.0f/PIT_TICK_RATE)*cntr; break; case 3: /* Square wave generator */ if (cntr<=40) { @@ -189,14 +186,14 @@ void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode) { spkr.pit_mode=0; return; } - spkr.pit_new_max=(Bitu)(((double)(1000000 << SPKR_SHIFT)/PIT_TICK_RATE)*cntr); + spkr.pit_new_max=(1000.0f/PIT_TICK_RATE)*cntr; spkr.pit_new_half=spkr.pit_new_max/2; break; case 4: /* Software triggered strobe */ spkr.pit_last=SPKR_VOLUME; - AddDelayEntry(newindex << SPKR_SHIFT,spkr.pit_last); + AddDelayEntry(newindex,spkr.pit_last); spkr.pit_index=0; - spkr.pit_max=(Bitu)(((double)(1000000 << SPKR_SHIFT)/PIT_TICK_RATE)*cntr); + spkr.pit_max=(1000.0f/PIT_TICK_RATE)*cntr; break; default: #if C_DEBUG @@ -213,24 +210,24 @@ void PCSPEAKER_SetType(Bitu mode) { spkr.last_index=0; } spkr.last_ticks=PIC_Ticks; - Bitu newindex=PIC_Index(); + float newindex=PIC_TickIndex(); ForwardPIT(newindex); switch (mode) { case 0: spkr.mode=SPKR_OFF; - AddDelayEntry(newindex << SPKR_SHIFT,-SPKR_VOLUME); + AddDelayEntry(newindex,-SPKR_VOLUME); break; case 1: spkr.mode=SPKR_PIT_OFF; - AddDelayEntry(newindex << SPKR_SHIFT,-SPKR_VOLUME); + AddDelayEntry(newindex,-SPKR_VOLUME); break; case 2: spkr.mode=SPKR_ON; - AddDelayEntry(newindex << SPKR_SHIFT,SPKR_VOLUME); + AddDelayEntry(newindex,SPKR_VOLUME); break; case 3: if (spkr.mode!=SPKR_PIT_ON) { - AddDelayEntry(newindex << SPKR_SHIFT,spkr.pit_last); + AddDelayEntry(newindex,spkr.pit_last); } spkr.mode=SPKR_PIT_ON; break; @@ -239,16 +236,17 @@ void PCSPEAKER_SetType(Bitu mode) { static void PCSPEAKER_CallBack(Bitu len) { Bit16s * stream=(Bit16s*)MixTemp; - ForwardPIT(1000); + ForwardPIT(1); spkr.last_index=0; Bitu count=len; - Bitu micro=0;Bitu pos=0; - Bits micro_add=(1001 << SPKR_SHIFT)/len; + Bitu pos=0; + float sample_base=0; + float sample_add=(1.0001f)/len; while (count--) { - Bitu index=micro; - micro+=micro_add; - Bitu end=micro; - Bits value=0; + float index=sample_base; + sample_base+=sample_add; + float end=sample_base; + double value=0; while(index> SPKR_SHIFT)*vol_len)/2; - spkr.volcur-=(SPKR_SPEED*vol_len) >> SPKR_SHIFT; + value-=(SPKR_SPEED*vol_len*vol_len)/2; + spkr.volcur-=SPKR_SPEED*vol_len; } else { - value+=(((SPKR_SPEED*vol_len) >> SPKR_SHIFT)*vol_len)/2; - spkr.volcur+=(SPKR_SPEED*vol_len) >> SPKR_SHIFT; + value+=(SPKR_SPEED*vol_len*vol_len)/2; + spkr.volcur+=SPKR_SPEED*vol_len; } index+=vol_len; } } } - *stream++=value/micro_add; + *stream++=(Bit16s)(value/sample_add); } spkr.chan->AddSamples_m16(len,(Bit16s*)MixTemp); if ((spkr.last_ticks+10000)Get_int("pcrate"); - spkr.pit_max=(Bitu)(((double)(1000000 << SPKR_SHIFT)/PIT_TICK_RATE)*65535); + spkr.pit_max=(1000.0f/PIT_TICK_RATE)*65535; spkr.pit_half=spkr.pit_max/2; spkr.pit_new_max=spkr.pit_max; spkr.pit_new_half=spkr.pit_half; From 386461754e17122019268e0763fbc8b332385409 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 10 Sep 2004 22:16:30 +0000 Subject: [PATCH 1888/4131] changes for improved timing event system Fix the cursor in cga,tandy,hercules modes Fix the 160x200 16 color cga mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1970 --- src/hardware/vga_draw.cpp | 68 ++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 83eff326..3fcf67ea 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -57,6 +57,21 @@ static Bit8u convert16[16]={ 0x6,0xa,0x8,0xb,0xd,0xe,0xc,0xf }; +static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart,Bitu panning,Bitu line) { + Bit8u * reader=&vga.mem.linear[vidstart + (line * 8 * 1024)]; + Bit32u * draw=(Bit32u *)TempLine; + for (Bitu x=0;x> 4]; + *draw++=(val1 << 0) | + (val1 << 8) | + (val2 << 16) | + (val2 << 24); + } + return TempLine; +} + static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { Bit8u * reader=&vga.mem.linear[vidstart + (line * 8 * 1024)]; Bit32u * draw=(Bit32u *)TempLine; @@ -147,13 +162,13 @@ static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { *draw++=fg&mask1 | bg&~mask1; *draw++=fg&mask2 | bg&~mask2; } - Bits font_addr=(vga.config.cursor_start*2-vidstart)/2; + Bits font_addr=(vga.draw.cursor.address-vidstart)/2; if (!vga.draw.cursor.enabled || !(vga.draw.cursor.count&0x8)) goto skip_cursor; if (font_addr>=0 && font_addrvga.draw.cursor.eline) goto skip_cursor; draw=(Bit32u *)&TempLine[font_addr*8]; - Bit32u att=TXT_FG_Table[vga.mem.linear[vga.config.cursor_start*2+1]&0xf]; + Bit32u att=TXT_FG_Table[vga.mem.linear[vga.draw.cursor.address+1]&0xf]; *draw++=att;*draw++=att; } skip_cursor: @@ -185,7 +200,7 @@ static void VGA_DrawPart(Bitu lines) { } } if (--vga.draw.parts_left) { - PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts, + PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts, (vga.draw.parts_left!=1) ? vga.draw.parts_lines : (vga.draw.lines_total - vga.draw.lines_done)); } else { RENDER_EndUpdate(); @@ -209,8 +224,8 @@ void VGA_SetBlinking(Bitu enabled) { static void VGA_VerticalTimer(Bitu val) { vga.config.retrace=false; - PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal); - PIC_AddEvent(VGA_VerticalDisplayEnd,vga.draw.micro.vend); + PIC_AddEvent(VGA_VerticalTimer,vga.draw.delay.vtotal); + PIC_AddEvent(VGA_VerticalDisplayEnd,vga.draw.delay.vend); if (RENDER_StartUpdate()) { vga.draw.parts_left=vga.draw.parts_total; vga.draw.lines_done=0; @@ -218,12 +233,14 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.address_line=vga.config.hlines_skip; vga.draw.split_line=(vga.config.line_compare/vga.draw.lines_scaled); vga.draw.panning=vga.config.pel_panning; - PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts,vga.draw.parts_lines); + PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts,vga.draw.parts_lines); } switch (vga.mode) { case M_TEXT: vga.draw.address=(vga.draw.address*2); case M_TANDY_TEXT: + case M_HERC_TEXT: + vga.draw.cursor.address=vga.config.cursor_start*2; vga.draw.cursor.count++; /* check for blinking and blinking change delay */ FontMask[1]=(vga.draw.blinking & (vga.draw.cursor.count >> 4)) ? @@ -234,7 +251,10 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.address=(vga.draw.address*2)&0x1fff; break; } - if (machine==MCH_TANDY) vga.draw.address+=vga.tandy.disp_bank << 14; + if (machine==MCH_TANDY) { + vga.draw.address+=vga.tandy.disp_bank << 14; + vga.draw.cursor.address+=vga.tandy.disp_bank << 14; + } } void VGA_CheckScanLength(void) { @@ -249,6 +269,7 @@ void VGA_CheckScanLength(void) { break; case M_CGA2: case M_CGA4: + case M_CGA16: vga.draw.address_add=80; return; case M_TANDY2: @@ -257,9 +278,6 @@ void VGA_CheckScanLength(void) { case M_TANDY4: vga.draw.address_add=vga.draw.blocks/2; break; - case M_CGA16: - vga.draw.address_add=vga.draw.blocks/2; - return; case M_TANDY16: vga.draw.address_add=vga.draw.blocks; break; @@ -282,7 +300,7 @@ void VGA_SetupDrawing(Bitu val) { return; } /* Calculate the FPS for this screen */ - double fps;Bitu clock; + float fps;Bitu clock; Bitu htotal,hdispend,hbstart,hrstart; Bitu vtotal,vdispend,vbstart,vrstart; if (machine==MCH_VGA) { @@ -338,16 +356,15 @@ void VGA_SetupDrawing(Bitu val) { LOG(LOG_VGA,LOG_NORMAL)("H D End %d, V D End %d",hdispend,vdispend); if (!htotal) return; if (!vtotal) return; - fps=clock/(vtotal*htotal); - double linemicro=(1000000/fps); + fps=(float)clock/(vtotal*htotal); + float linetime=1000.0f/fps; vga.draw.parts_total=VGA_PARTS; - vga.draw.micro.vtotal=(Bitu)(linemicro); - linemicro/=vtotal; //Really make it the line_micro - vga.draw.micro.vend=(Bitu)(linemicro*vrstart); - vga.draw.micro.parts=(Bitu)((linemicro*vdispend)/vga.draw.parts_total); - vga.draw.micro.htotal=(Bitu)(linemicro); - vga.draw.micro.hend=(Bitu)((linemicro/htotal)*hrstart); - + vga.draw.delay.vtotal=linetime; + linetime/=vtotal; //Really make it the line_delay + vga.draw.delay.vend=linetime*vrstart; + vga.draw.delay.parts=(linetime*vdispend)/vga.draw.parts_total; + vga.draw.delay.htotal=linetime; + vga.draw.delay.hend=(linetime/htotal)*hrstart; double correct_ratio=(100.0/525.0); double aspect_ratio=((double)htotal/((double)vtotal)/correct_ratio); @@ -377,6 +394,13 @@ void VGA_SetupDrawing(Bitu val) { width<<=3; VGA_DrawLine=VGA_Draw_EGA_Line; break; + case M_CGA16: + doublewidth=true; + doubleheight=true; + vga.draw.blocks=width*2; + width<<=3; + VGA_DrawLine=VGA_Draw_CGA16_Line; + break; case M_CGA4: doublewidth=true; vga.draw.blocks=width*2; @@ -436,7 +460,7 @@ void VGA_SetupDrawing(Bitu val) { VGA_DrawLine=VGA_TEXT_Draw_Line; break; default: - LOG(LOG_VGA,LOG_ERROR)("Unhandled VGA type %d while checking for resolution"); + LOG(LOG_VGA,LOG_ERROR)("Unhandled VGA mode %d while checking for resolution",vga.mode); }; VGA_CheckScanLength(); if (vga.draw.double_scan) { @@ -467,6 +491,6 @@ void VGA_SetupDrawing(Bitu val) { doublewidth ? "double":"normal",doubleheight ? "double":"normal",aspect_ratio); #endif RENDER_SetSize(width,height,8,aspect_ratio,doublewidth,doubleheight); - PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal); + PIC_AddEvent(VGA_VerticalTimer,vga.draw.delay.vtotal); } }; From 0a2704969e8f3d69cd47018bfd65df05c0c499ed Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 10 Sep 2004 22:31:03 +0000 Subject: [PATCH 1889/4131] Warning Warning. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1971 --- src/hardware/pcspeaker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 77ef82a9..823c1c50 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -266,7 +266,7 @@ static void PCSPEAKER_CallBack(Bitu len) { index+=vol_len; } else { /* Check how long it will take to goto new level */ - float vol_time=abs(vol_diff)/SPKR_SPEED; + float vol_time=fabs(vol_diff)/SPKR_SPEED; if (vol_time<=vol_len) { /* Volume reaches endpoint in this block, calc until that point */ value+=vol_time*spkr.volcur; From 4f558a5ab7c9653b501cbdf68c6c13c0e2bc4bf0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 11 Sep 2004 08:09:25 +0000 Subject: [PATCH 1890/4131] Add pit mode 1 which basically just keeps output high Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1972 --- src/hardware/pcspeaker.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 823c1c50..732d3329 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -76,6 +76,8 @@ static void ForwardPIT(float newindex) { switch (spkr.pit_mode) { case 0: return; + case 1: + return; case 2: while (passed>0) { /* passed the initial low cycle? */ @@ -172,6 +174,11 @@ void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode) { AddDelayEntry(newindex,spkr.pit_last); spkr.pit_index=0; break; + case 1: + if (spkr.mode!=SPKR_PIT_ON) return; + spkr.pit_last=SPKR_VOLUME; + AddDelayEntry(newindex,spkr.pit_last); + break; case 2: /* Single cycle low, rest low high generator */ spkr.pit_index=0; spkr.pit_last=-SPKR_VOLUME; From 2119b82868bdb95cbe21f25c3e4f5d4848e923bd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 11 Sep 2004 09:00:58 +0000 Subject: [PATCH 1891/4131] pop2 irq Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1973 --- src/hardware/dma.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 7005f811..0c63a3a3 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -189,7 +189,7 @@ again: buffer+=left << DMA16; want-=left; done+=left; -// ReachedTC(); //No module uses it so disable + ReachedTC(); if (autoinit) { currcnt=basecnt; curraddr=baseaddr; From fb9761eac0e16b2bf172ec82c37ca1b4340807a6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 11 Sep 2004 10:07:34 +0000 Subject: [PATCH 1892/4131] Next license and add capture Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1974 --- scripts/dosbox-installer.nsi | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index 66024a97..ef214926 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -15,7 +15,7 @@ DirText "This will install DOSBox v${VER_MAYOR}.${VER_MINOR} on your computer. C SetCompressor bzip2 LicenseData COPYING -LicenseText "DOSBox v${VER_MAYOR}.${VER_MINOR} License" +LicenseText "DOSBox v${VER_MAYOR}.${VER_MINOR} License" "Next->" ; The stuff to install Section "ThisNameIsIgnoredSoWhyBother?" @@ -35,8 +35,7 @@ Section "ThisNameIsIgnoredSoWhyBother?" File SDL_net.dll File libpng12.dll - CreateDirectory "$INSTDIR\snaps" - CreateDirectory "$INSTDIR\waves" + CreateDirectory "$INSTDIR\capture" CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}" 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$\"" @@ -74,8 +73,7 @@ Section "Uninstall" Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.conf.lnk" ; remove directories used. - RMDir "$INSTDIR\snaps" - RMDir "$INSTDIR\waves" + RMDir "$INSTDIR\capture" RMDir "$INSTDIR" RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}" SectionEnd From c72e8eb9178c707e167a6034dcd37e7d6cac3d44 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 14 Sep 2004 18:56:11 +0000 Subject: [PATCH 1893/4131] Finally solve that weird windows specific filebug. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1975 --- include/cross.h | 4 ++-- src/dos/drive_cache.cpp | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/cross.h b/include/cross.h index f4c106b0..d6e65d21 100644 --- a/include/cross.h +++ b/include/cross.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.h,v 1.9 2004-08-23 09:34:21 harekiet Exp $ */ +/* $Id: cross.h,v 1.10 2004-09-14 18:56:11 qbix79 Exp $ */ #ifndef _CROSS_H #define _CROSS_H @@ -40,7 +40,7 @@ #if defined (WIN32) /* Win 32 */ -#define CROSS_FILENAME(blah) {if(blah && *blah && (blah[strlen(blah)-1] == '\\')) strcat(blah,".");} +#define CROSS_FILENAME(blah) #define CROSS_FILESPLIT '\\' #define F_OK 0 #else diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 16d8e957..6554876f 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.36 2004-08-04 09:12:53 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.37 2004-09-14 18:56:11 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -176,6 +176,10 @@ char* DOS_Drive_Cache::GetExpandName(const char* path) GetLongName(dirInfo, dir); strcat(work,dir); } + + if(work && *work && ( work[strlen(work)-1] == CROSS_FILESPLIT ) ) + work[strlen(work)-1] = 0; // Remove trailing slashes + return work; }; From 18f7967fee1cef0b96f0c9930234d39b75e3e23f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 15 Sep 2004 08:57:40 +0000 Subject: [PATCH 1894/4131] Fix a popf issue Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1976 --- src/cpu/core_dyn_x86/decoder.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 1e7570d5..7027c650 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -318,6 +318,7 @@ static void dyn_check_bool_exception(DynReg * check) { gen_fill_branch(branch); } + static void dyn_dop_ebgb(DualOps op) { dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg&3]; if (decode.modrm.mod<3) { @@ -1247,6 +1248,7 @@ restart_prefix: break; case 0x9d: //POPF gen_releasereg(DREG(ESP)); + gen_releasereg(DREG(FLAGS)); gen_call_function((void *)&CPU_POPF,"%Rd%Id",DREG(TMPB),decode.big_op); if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); dyn_flags_host_to_gen(); @@ -1319,7 +1321,7 @@ restart_prefix: case 0xca:dyn_ret_far(decode_fetchw());goto finish_block; case 0xcb:dyn_ret_far(0);goto finish_block; /* Interrupt */ - case 0xcd:dyn_interrupt(decode_fetchb());goto finish_block; +// case 0xcd:dyn_interrupt(decode_fetchb());goto finish_block; /* IRET */ case 0xcf:dyn_iret();goto finish_block; From 4530386c35ff3b2c17fded8532afacf74ffbbac9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 15 Sep 2004 10:59:28 +0000 Subject: [PATCH 1895/4131] Fix stereo transfers overflowing the dma counter with remaining bytes Add 16 bit continue dma dsp command Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1977 --- src/hardware/sblaster.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 32a0e35c..a89972e4 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -343,11 +343,11 @@ static void GenerateDMASound(Bitu size) { case DSP_DMA_8: if (sb.dma.stereo) { read=sb.dma.chan->Read(size,&sb.dma.buf.b8[sb.dma.remain_size]); - read+=sb.dma.remain_size; - sb.chan->AddSamples_s8(read>>1,sb.dma.buf.b8); - if (read&1) { + Bitu total=read+sb.dma.remain_size; + sb.chan->AddSamples_s8(total>>1,sb.dma.buf.b8); + if (total&1) { sb.dma.remain_size=1; - sb.dma.buf.b8[0]=sb.dma.buf.b8[read-1]; + sb.dma.buf.b8[0]=sb.dma.buf.b8[total-1]; } else sb.dma.remain_size=0; } else { read=sb.dma.chan->Read(size,sb.dma.buf.b8); @@ -357,11 +357,11 @@ static void GenerateDMASound(Bitu size) { case DSP_DMA_16: if (sb.dma.stereo) { read=sb.dma.chan->Read(size,(Bit8u *)&sb.dma.buf.b16[sb.dma.remain_size]); - read+=sb.dma.remain_size; - sb.chan->AddSamples_s16(read>>1,sb.dma.buf.b16); - if (read&1) { + Bitu total=read+sb.dma.remain_size; + sb.chan->AddSamples_s16(total>>1,sb.dma.buf.b16); + if (total&1) { sb.dma.remain_size=1; - sb.dma.buf.b16[0]=sb.dma.buf.b16[read-1]; + sb.dma.buf.b16[0]=sb.dma.buf.b16[total-1]; } else sb.dma.remain_size=0; } else { read=sb.dma.chan->Read(size,sb.dma.buf.b8); @@ -387,8 +387,13 @@ static void GenerateDMASound(Bitu size) { LOG(LOG_SB,LOG_NORMAL)("Single cycle transfer ended"); sb.mode=MODE_NONE; sb.dma.mode=DSP_DMA_NONE; + } else { + sb.dma.left=sb.dma.total; + if (!sb.dma.left) { + LOG(LOG_SB,LOG_NORMAL)("Auto-init transfer with 0 size"); + sb.mode=MODE_NONE; + } } - else sb.dma.left=sb.dma.total; if (sb.dma.mode >= DSP_DMA_16) SB_RaiseIRQ(SB_IRQ_16); else SB_RaiseIRQ(SB_IRQ_8); } @@ -689,7 +694,8 @@ static void DSP_DoCommand(void) { case 0xd3: /* Disable Speaker */ DSP_SetSpeaker(false); break; - case 0xd4: /* Continue DMA */ + case 0xd4: /* Continue DMA 8-bit*/ + case 0xd6: /* Continue DMA 16-bit */ if (sb.mode==MODE_DMA_PAUSE) { sb.mode=MODE_DMA_MASKED; sb.dma.chan->Register_Callback(DSP_DMA_CallBack); From 8b611eb8177062cc90d21fe134fc8f231a09c7e0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 15 Sep 2004 14:00:13 +0000 Subject: [PATCH 1896/4131] Now Really hopefully finnally fix that directory-caching bug Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1978 --- src/dos/drive_cache.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 6554876f..c5d269fa 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.37 2004-09-14 18:56:11 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.38 2004-09-15 14:00:13 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -176,10 +176,17 @@ char* DOS_Drive_Cache::GetExpandName(const char* path) GetLongName(dirInfo, dir); strcat(work,dir); } - - if(work && *work && ( work[strlen(work)-1] == CROSS_FILESPLIT ) ) - work[strlen(work)-1] = 0; // Remove trailing slashes - + + if(work && *work) { + size_t len = strlen(work); +#if defined (WIN32) + if((work[len-1] == CROSS_FILESPLIT ) && (len >= 2) && (work[len-2] != ':')) { +#else + if((len > 1) && (work[len-1] == CROSS_FILESPLIT )) { +#endif + work[len-1] = 0; // Remove trailing slashes except when in root + } + } return work; }; From b11c036b84d53b8abc1c1ce638a8c3f5e2da04f0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 15 Sep 2004 18:52:00 +0000 Subject: [PATCH 1897/4131] Added NUL Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1979 --- src/dos/dos_devices.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index aad4cc79..a9dad893 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -34,6 +34,27 @@ static DOS_Device * devices[MAX_DEVICES]; static Bit32u device_count; +class device_NUL : public DOS_Device { +public: + device_NUL() { name="NUL"; }; + bool Read(Bit8u * data,Bit16u * size) { + for(Bitu i = 0; i < *size;i++) + data[i]=0; + LOG(LOG_IOCTL,LOG_NORMAL)("NUL:READ"); + return true; + } + bool Write(Bit8u * data,Bit16u * size) { + LOG(LOG_IOCTL,LOG_NORMAL)("NUL:WRITE"); + return true; + } + bool Seek(Bit32u * pos,Bit32u type) { + LOG(LOG_IOCTL,LOG_NORMAL)("NUL:SEEK"); + return true; + } + bool Close() { return true; } + Bit16u GetInformation(void) { return 0x8004; } +}; + Bit8u DOS_FindDevice(char * name) { /* loop through devices */ Bit8u index=0; @@ -73,5 +94,8 @@ void DOS_SetupDevices(void) { DOS_Device * newdev; newdev=new device_CON(); DOS_AddDevice(newdev); + DOS_Device * newdev2; + newdev2=new device_NUL(); + DOS_AddDevice(newdev2); } From f8f90ad0dfa26813359abe4bfd01a6393af9db71 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 15 Sep 2004 20:49:07 +0000 Subject: [PATCH 1898/4131] Updated to include imgmount and spiced intro a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1980 --- src/dos/dos_programs.cpp | 71 +++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 325839a5..9e89a99c 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.28 2004-09-10 18:57:53 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.29 2004-09-15 20:49:07 qbix79 Exp $ */ #include #include @@ -480,8 +480,7 @@ public: } cmd->FindString("-size",str_size,true); if ((type=="hdd") && (str_size.size()==0)) { - WriteOut("Must specify drive geometry for hard drives:\n"); - WriteOut("bytes_per_sector, sectors_per_cylinder, heads_per_cylinder, cylinder_count\n"); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_GEOMETRY")); return; } char number[20]; @@ -501,36 +500,36 @@ public: // get the drive letter cmd->FindCommand(1,temp_line); if ((temp_line.size() > 2) || ((temp_line.size()>1) && (temp_line[1]!=':'))) { - WriteOut("Must specify drive letter to mount image at.\n"); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_DRIVE")); return; } drive=toupper(temp_line[0]); if (!isalpha(drive)) { - WriteOut("Must specify drive letter to mount image at.\n"); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_DRIVE")); return; } } else if (fstype=="none") { cmd->FindCommand(1,temp_line); if ((temp_line.size() > 1) || (!isdigit(temp_line[0]))) { - WriteOut("Must specify drive number (0 or 3) to mount image at (0,1=fda,fdb;2,3=hda,hdb)\n"); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY2")); return; } drive=temp_line[0]-'0'; if(drive>3) { - WriteOut("Must specify drive number (0 or 3) to mount image at (0,1=fda,fdb;2,3=hda,hdb)\n"); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY2")); return; } } else { - WriteOut("Format \"%s\" is unsupported. Specify \"fat\" or \"none\".\n"); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FORMAT_UNSUPPORTED")); return; } if (!cmd->FindCommand(2,temp_line)) { - WriteOut("Must specify file image to mount\n"); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_FILE")); return; } if (!temp_line.size()) { - WriteOut("Must specify file image to mount\n"); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_FILE")); return; } struct stat test; @@ -542,7 +541,7 @@ public: Bit8u drive; if (!DOS_MakeName(tmp, fullname, &drive)) { - WriteOut("Image file not found\n"); + WriteOut(MSG_Get("PROGRAM_IMGMOUNG_FILE_NOT_FOUND")); return; } @@ -551,13 +550,13 @@ public: temp_line = tmp; if (stat(temp_line.c_str(),&test)) { - WriteOut("Image file not found\n"); + WriteOut(MSG_Get("PROGRAM_IMGMOUNG_FILE_NOT_FOUND")); return; } } if ((test.st_mode & S_IFDIR)) { - WriteOut("To mount directories, use the MOUNT command, not the IMGMOUNT command\n"); + WriteOut(MSG_Get("PROGRAM_IMGMOUNG_MOUNT")); return; } @@ -590,15 +589,15 @@ public: } if(fstype=="fat") { if (Drives[drive-'A']) { - WriteOut("Drive already mounted at that letter\n"); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_ALLREADY_MOUNTED")); if (newdrive) delete newdrive; return; } - if (!newdrive) WriteOut("Can't create drive from file\n"); + if (!newdrive) WriteOut(MSG_Get("PROGRAM_IMGMOUNT_CANT_CREATE")); Drives[drive-'A']=newdrive; // Set the correct media byte in the table mem_writeb(Real2Phys(dos.tables.mediaid)+drive-'A',mediaid); - WriteOut("Drive %c mounted as %s\n",drive,temp_line.c_str()); + WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,temp_line.c_str()); if(((fatDrive *)newdrive)->loadedDisk->hardDrive) { if(imageDiskList[2] == NULL) { imageDiskList[2] = ((fatDrive *)newdrive)->loadedDisk; @@ -616,20 +615,20 @@ public: } } else if (fstype=="iso") { if (Drives[drive-'A']) { - WriteOut("Drive already mounted at that letter\n"); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_ALLREADY_MOUNTED")); if (newdrive) delete newdrive; return; } - if (!newdrive) WriteOut("Can't create drive from file\n"); + if (!newdrive) WriteOut(MSG_Get("PROGRAM_IMGMOUNT_CANT_CREATE")); Drives[drive-'A']=newdrive; // Set the correct media byte in the table mem_writeb(Real2Phys(dos.tables.mediaid)+drive-'A',mediaid); - WriteOut("Drive %c mounted as %s\n",drive,temp_line.c_str()); + WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,temp_line.c_str()); } else if (fstype=="none") { if(imageDiskList[drive] != NULL) delete imageDiskList[drive]; imageDiskList[drive] = newImage; updateDPT(); - WriteOut("Drive number %d mounted as %s\n",drive,temp_line.c_str()); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MOUNT_NUMBER"),drive,temp_line.c_str()); } // check if volume label is given @@ -675,26 +674,26 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_RESCAN_SUCCESS","Drive cache cleared.\n"); MSG_Add("PROGRAM_INTRO", - "Welcome to DOSBox, an x86 emulator with sound and graphics.\n" + "Welcome to DOSBox, an x86 emulator with sound and graphics.\n" "DOSBox creates a shell for you which looks like old plain DOS.\n" "\n" "Here are some commands to get you started:\n" "Before you can use the files located on your own filesystem,\n" "You have to mount the directory containing the files.\n" - "For Windows:\n" - "\033[33mmount c c:\\dosprog\033[0m will create a C drive in dosbox with c:\\dosprog as contents.\n" + "For \033[1mWindows\033[0m:\n" + "\033[34;1mmount c c:\\dosprog\033[0m will create a C drive in DOSBox with c:\\dosprog as contents.\n" "\n" - "For other platforms:\n" - "\033[33mmount c /home/user/dosprog\033[0m will do the same.\n" + "For \033[1mother platforms\033[0m:\n" + "\033[34;1mmount c /home/user/dosprog\033[0m will do the same.\n" "\n" - "When the mount has succesfully completed you can type \033[33mc:\033[0m to go to your freshly\n" - "mounted C-drive. Typing \033[33mdir\033[0m there will show its contents." - " \033[33mcd\033[0m will allow you to\n" - "enter a directory (recognised by the [] in a directory listing).\n" + "When the mount has succesfully completed you can type \033[34;1mc:\033[0m to go to your freshly\n" + "mounted C-drive. Typing \033[34;1mdir\033[0m there will show its contents." + " \033[34;1mcd\033[0m will allow you to\n" + "enter a directory (recognised by the \033[1m[]\033[0m in a directory listing).\n" "You can run programs/files which end with .exe .bat and .com.\n" "\n" - "DOSBox will stop/exit without a warning if an error occured!\n" + "DOSBox will stop/exit without a warning if an error occured!\n" ); MSG_Add("PROGRAM_BOOT_NOT_EXIST","Bootdisk file does not exist. Failing.\n"); @@ -714,6 +713,18 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_BOOT_IMAGE_NOT_OPEN","Cannot open %s"); MSG_Add("PROGRAM_BOOT_BOOT","Booting from drive %c...\n"); + MSG_Add("PROGRAM_IMGMOUNT_SPECIFY_DRIVE","Must specify drive letter to mount image at.\n"); + MSG_Add("PROGRAM_IMGMOUNT_SPECIFY2","Must specify drive number (0 or 3) to mount image at (0,1=fda,fdb;2,3=hda,hdb).\n"); + MSG_Add("PROGRAM_IMGMOUNT_SPECIFY_GEOMETRY","Must specify drive geometry for hard drives:\n" + "bytes_per_sector, sectors_per_cylinder, heads_per_cylinder, cylinder_count.\n"); + MSG_Add("PROGRAM_IMGMOUNT_FORMAT_UNSUPPORTED","Format \"%s\" is unsupported. Specify \"fat\" or \"iso\" or \"none\".\n"); + MSG_Add("PROGRAM_IMGMOUNT_SPECIFY_FILE","Must specify file-image to mount.\n"); + MSG_Add("PROGRAM_IMGMOUNG_FILE_NOT_FOUND","Image file not found.\n"); + MSG_Add("PROGRAM_IMGMOUNG_MOUNT","To mount directories, use the MOUNT command, not the IMGMOUNT command.\n"); + MSG_Add("PROGRAM_IMGMOUNT_ALLREADY_MOUNTED","Drive already mounted at that letter.\n"); + MSG_Add("PROGRAM_IMGMOUNT_CANT_CREATE","Can't create drive from file.\n"); + MSG_Add("PROGRAM_IMGMOUNT_MOUNT_NUMBER","Drive number %d mounted as %s\n"); + /*regular setup*/ PROGRAMS_MakeFile("MOUNT.COM",MOUNT_ProgramStart); PROGRAMS_MakeFile("MEM.COM",MEM_ProgramStart); From 7c7b9b0539610c6dcbf76aa166174d68e508a976 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 16 Sep 2004 21:46:03 +0000 Subject: [PATCH 1899/4131] added vsnprintf Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1981 --- include/cross.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/cross.h b/include/cross.h index d6e65d21..dd42a5b5 100644 --- a/include/cross.h +++ b/include/cross.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.h,v 1.10 2004-09-14 18:56:11 qbix79 Exp $ */ +/* $Id: cross.h,v 1.11 2004-09-16 21:46:03 qbix79 Exp $ */ #ifndef _CROSS_H #define _CROSS_H @@ -30,6 +30,7 @@ #include #define LONGTYPE(a) a##i64 #define snprintf _snprintf +#define vsnprintf _vsnprintf #else /* LINUX / GCC */ #include #include From 293535b8e2e7ac166e34979a71daaac54a0105c1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 16 Sep 2004 21:47:39 +0000 Subject: [PATCH 1900/4131] Fix overflows in buffer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1982 --- src/misc/programs.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 42bd9382..a6ffc200 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.14 2004-08-04 09:12:56 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.15 2004-09-16 21:47:39 qbix79 Exp $ */ #include #include @@ -96,11 +96,11 @@ Program::Program() { } void Program::WriteOut(const char * format,...) { - char buf[1024]; + char buf[2048]; va_list msg; va_start(msg,format); - vsprintf(buf,format,msg); + vsnprintf(buf,2047,format,msg); va_end(msg); Bit16u size=strlen(buf); From a0116a00bcb255c7e44ca452ebec57fef2ed0d57 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 16 Sep 2004 22:05:24 +0000 Subject: [PATCH 1901/4131] Colours\!\! Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1983 --- src/dos/dos_programs.cpp | 52 ++++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 9e89a99c..f34802cd 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.29 2004-09-15 20:49:07 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.30 2004-09-16 22:05:24 qbix79 Exp $ */ #include #include @@ -442,6 +442,10 @@ static void RESCAN_ProgramStart(Program * * make) { class INTRO : public Program { public: void Run(void) { + if(cmd->FindExist("cdrom",false)) { + WriteOut(MSG_Get("PROGRAM_INTRO_CDROM")); + return; + } WriteOut(MSG_Get("PROGRAM_INTRO")); } }; @@ -652,7 +656,7 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_MOUNT_ERROR_2","%s isn't a directory\n"); MSG_Add("PROGRAM_MOUNT_ILL_TYPE","Illegal type %s\n"); MSG_Add("PROGRAM_MOUNT_ALLREADY_MOUNTED","Drive %c already mounted with %s\n"); - MSG_Add("PROGRAM_MOUNT_USAGE","Usage MOUNT Drive-Letter Local-Directory\nSo a MOUNT c c:\\windows mounts windows directory as the c: drive in DOSBox\n"); + MSG_Add("PROGRAM_MOUNT_USAGE","Usage \033[34;1mMOUNT Drive-Letter Local-Directory\033[0m\nSo a MOUNT c c:\\windows mounts windows directory as the c: drive in DOSBox\n"); MSG_Add("PROGRAM_MEM_CONVEN","%10d Kb free conventional memory\n"); MSG_Add("PROGRAM_MEM_EXTEND","%10d Kb free extended memory\n"); @@ -674,7 +678,7 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_RESCAN_SUCCESS","Drive cache cleared.\n"); MSG_Add("PROGRAM_INTRO", - "Welcome to DOSBox, an x86 emulator with sound and graphics.\n" + "\033[2J\033[33;1mWelcome to DOSBox\033[0m, an x86 emulator with sound and graphics.\n" "DOSBox creates a shell for you which looks like old plain DOS.\n" "\n" "Here are some commands to get you started:\n" @@ -690,10 +694,35 @@ void DOS_SetupPrograms(void) { "mounted C-drive. Typing \033[34;1mdir\033[0m there will show its contents." " \033[34;1mcd\033[0m will allow you to\n" "enter a directory (recognised by the \033[1m[]\033[0m in a directory listing).\n" - "You can run programs/files which end with .exe .bat and .com.\n" - + "You can run programs/files which end with \033[31m.exe .bat\033[0m and \033[31m.com\033[0m.\n" "\n" - "DOSBox will stop/exit without a warning if an error occured!\n" + "For information about CD-ROM support type \033[34;1mintro cdrom\033[0m\n" + "\n" + "\033[32;1mDOSBox will stop/exit without a warning if an error occured!\033[0m\n" + ); + MSG_Add("PROGRAM_INTRO_CDROM", + "\033[2J\033[32;1mHow to mount a Real/Virtual CD-ROM Drive in DOSBox:\033[0m\n" + "DOSBox provides CD-ROM emulation on several levels.\n" + "\n" + "The \033[33mbasic\033[0m level works on all CD-ROM drives and normal directories.\n" + "It installs MSCDEX and marks the files read-only.\n" + "Usually this is enough for most games:\n" + "\033[34;1mmount d D:\\ -t cdrom\033[0m or \033[34;1mmount d C:\\example -t cdrom\033[0m\n" + "If it doesn't work you might have to tell DOSBox the label of the CD-ROM:\n" + "\033[34;1mmount d C:\\example -t cdrom -label CDLABEL\033[0m\n" + "\n" + "The \033[33mnext\033[0m level adds some low-level support.\n" + "Therefore only works on CD-ROM drives:\n" + "\033[34;1mmount d D:\\ -t cdrom -usecd \033[33m0\033[0m\n" + "\n" + "The \033[33mlast\033[0m level of support depends on your Operating System:\n" + "For \033[1mWindows 2000\033[0m, \033[1mWindows XP\033[0m and \033[1mLinux\033[0m:\n" + "\033[34;1mmount d D:\\ -t cdrom -usecd \033[33m0 \033[34m-ioctl\033[0m\n" + "For \033[1mWindows 9x\033[0m with a ASPI layer installed:\n" + "\033[34;1mmount d D:\\ -t cdrom -usecd \033[33m0 \033[34m-aspi\033[0m\n" + "\n" + "Replace the \033[33;1m0\033[0m in \033[34;1m-usecd \033[33m0\033[0m with the number reported for your CD-ROM if you type:\n" + "\033[34;1mmount -cd\033[0m" ); MSG_Add("PROGRAM_BOOT_NOT_EXIST","Bootdisk file does not exist. Failing.\n"); @@ -704,9 +733,9 @@ void DOS_SetupPrograms(void) { "no drive letter is specified, this defaults to booting from the A drive.\n" "The only bootable drive letters are A, C, and D. For booting from a hard\n" "drive (C or D), the image should have already been mounted using the\n" - "IMGMOUNT command.\n\n" + "\033[34;1mIMGMOUNT\033[0m command.\n\n" "The syntax of this command is:\n\n" - "BOOT [diskimg1.img diskimg2.img] [-l driveletter]\n" + "\033[34;1mBOOT [diskimg1.img diskimg2.img] [-l driveletter]\033[0m\n" ); MSG_Add("PROGRAM_BOOT_UNABLE","Unable to boot off of drive %c"); MSG_Add("PROGRAM_BOOT_IMAGE_OPEN","Opening image file: %s\n"); @@ -715,12 +744,15 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_IMGMOUNT_SPECIFY_DRIVE","Must specify drive letter to mount image at.\n"); MSG_Add("PROGRAM_IMGMOUNT_SPECIFY2","Must specify drive number (0 or 3) to mount image at (0,1=fda,fdb;2,3=hda,hdb).\n"); - MSG_Add("PROGRAM_IMGMOUNT_SPECIFY_GEOMETRY","Must specify drive geometry for hard drives:\n" + MSG_Add("PROGRAM_IMGMOUNT_SPECIFY_GEOMETRY", + "For \033[33mCD-ROM\033[0m images: \033[34;1mimgmount Drive-Letter location-of-image -t iso\033[0m\n" + "\n" + "For \033[33mhardrive\033[0m images: Must specify drive geometry for hard drives:\n" "bytes_per_sector, sectors_per_cylinder, heads_per_cylinder, cylinder_count.\n"); MSG_Add("PROGRAM_IMGMOUNT_FORMAT_UNSUPPORTED","Format \"%s\" is unsupported. Specify \"fat\" or \"iso\" or \"none\".\n"); MSG_Add("PROGRAM_IMGMOUNT_SPECIFY_FILE","Must specify file-image to mount.\n"); MSG_Add("PROGRAM_IMGMOUNG_FILE_NOT_FOUND","Image file not found.\n"); - MSG_Add("PROGRAM_IMGMOUNG_MOUNT","To mount directories, use the MOUNT command, not the IMGMOUNT command.\n"); + MSG_Add("PROGRAM_IMGMOUNG_MOUNT","To mount directories, use the \033[34;1mMOUNT\033[0m command, not the \033[34;1mIMGMOUNT\033[0m command.\n"); MSG_Add("PROGRAM_IMGMOUNT_ALLREADY_MOUNTED","Drive already mounted at that letter.\n"); MSG_Add("PROGRAM_IMGMOUNT_CANT_CREATE","Can't create drive from file.\n"); MSG_Add("PROGRAM_IMGMOUNT_MOUNT_NUMBER","Drive number %d mounted as %s\n"); From 692445523accd2173c9f6b24339f26baa6f06bbf Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 18 Sep 2004 10:20:54 +0000 Subject: [PATCH 1902/4131] Some DIRCMD for XulChris Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1984 --- src/shell/shell_cmds.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 3d41a8e0..62217170 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.46 2004-09-09 18:36:50 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.47 2004-09-18 10:20:54 qbix79 Exp $ */ #include #include @@ -239,6 +239,14 @@ void DOS_Shell::CMD_DIR(char * args) { char numformat[16]; char path[DOS_PATHLENGTH]; + std::string line; + if(GetEnvStr("DIRCMD",line)){ + std::string::size_type idx = line.find('='); + std::string value=line.substr(idx +1 , std::string::npos); + line = std::string(args) + " " + value; + args=const_cast(line.c_str()); + } + bool optW=ScanCMDBool(args,"W"); bool optS=ScanCMDBool(args,"S"); bool optP=ScanCMDBool(args,"P"); From 55c785a7a3997d899dbf1cdd0af9e9c0aca6fb22 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 21 Sep 2004 19:32:15 +0000 Subject: [PATCH 1903/4131] Another typo.... Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1985 --- src/dosbox.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 6a8e5247..33fa139a 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.79 2004-09-10 08:02:50 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.80 2004-09-21 19:32:15 qbix79 Exp $ */ #include #include @@ -376,7 +376,7 @@ void DOSBOX_Init(void) { MSG_Add("MODEM_CONFIGFILE_HELP", "modem -- Enable virtual modem emulation.\n" "comport -- COM Port modem is connected to.\n" - "listenport -- TCP Port the momdem listens on for incoming connections.\n" + "listenport -- TCP Port the modem listens on for incoming connections.\n" ); #endif #if C_DIRECTSERIAL From 25817293d1b526f72d833e3314ff30ad285707e2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 21 Sep 2004 20:04:55 +0000 Subject: [PATCH 1904/4131] Make country info point to an empty table instead of reporting 0:0 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1986 --- src/dos/dos.cpp | 5 ++--- src/dos/dos_tables.cpp | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 9d618924..6ed77c35 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.74 2004-08-04 09:12:53 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.75 2004-09-21 20:04:55 qbix79 Exp $ */ #include #include @@ -847,8 +847,7 @@ static Bitu DOS_21Handler(void) { case 6: // Get pointer to collating sequence table case 7: // Get pointer to double byte char set table mem_writeb(data,reg_al); - mem_writew(data+1,0x0000); // We dont have this table... - mem_writew(data+3,0x0000); // End of table + mem_writed(data+1,dos.tables.dcbs); //used to be 0 reg_cx=5; CALLBACK_SCF(false); break; diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index cd04163f..0d41577b 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.14 2004-08-04 09:12:53 qbix79 Exp $ */ +/* $Id: dos_tables.cpp,v 1.15 2004-09-21 20:04:55 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -96,7 +96,7 @@ void DOS_SetupTables(void) { /* Allocate DCBS DOUBLE BYTE CHARACTER SET LEAD-BYTE TABLE */ dos.tables.dcbs=RealMake(DOS_GetMemory(12),0); - mem_writew(Real2Phys(dos.tables.dcbs),0); //empty table + mem_writed(Real2Phys(dos.tables.dcbs),0); //empty table /* Create a fake FCB SFT */ seg=DOS_GetMemory(4); From 4162c2b7a107206264bfb70d26f6a16fbe3d36f6 Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Wed, 22 Sep 2004 02:38:01 +0000 Subject: [PATCH 1905/4131] Added IMGMOUNT, BOOT and IPX documentation Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1987 --- README | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 110 insertions(+), 6 deletions(-) diff --git a/README b/README index 3520f1e9..057ad766 100644 --- a/README +++ b/README @@ -376,17 +376,121 @@ IMGMOUNT A utility to mount disk images and CD-ROM images in DOSBox. CD-ROM: either iso or cue/bin is supported: - IMGMOUNT DRIVE imagefile -t iso - - imagefile - location is inside DOSBox. + IMGMOUNT DRIVE [imagefile] -t [image_type] -fs [image_format] -size [sectorsbytesize, sectorsperhead, heads, cylinders] + imagefile + location of the image files to mount in DosBox. Path is relative to a mount + point already inside DosBox. + + -t + The following are valid image types: + floppy: Specifies a floppy image or images. DosBox will automatically identify the disk geometry (i.e, 360K + 1.2MB, 720K, 1.44MB, etc.) + iso: Specifies a CD-ROM iso image. The geometry is automatic and set for this size. + hdd: Specifies a harddrive image. The proper CHS geometry must be set for this to work. + + -fs + The following are valid file system formats: + iso: Specifies the ISO 9660 CD-ROM format. + fat: Specifies the image uses the FAT file system. DosBox will attempt to mount this image as a drive + in DosBox and make the files available from inside DosBox. + none: DosBox will make no attempt to read the file system on the disk. This is useful if one needs to + format it or one wants to boot off of the disk using the BOOT command. When using the "none" file + system, one must specify the drive number (2 or 3, where 2 = master, 3 = slave) rather than a drive + letter. For example, to mount a 70MB image as the slave drive device, one would type: + "imgmount 3 d:\test.img -size 512,63,16,142 -fs none" (without the quotes) Compare this with a mount to + read the drive in DosBox, which would read as: "imgmount e: d:\test.img -size 512,63,16,142" + + -size + The Cylinders, Heads and Sectors specification of the drive. Required to mount hard drive images. + +BOOT + Boot will start floppy images or hard disk images independent of the operating system emulation offered by + DosBox. This will allow you to play booter floppies or boot to other operating systems inside DosBox. + + BOOT [diskimg1.img diskimg2.img .. diskimgN.img] [-l driveletter] + + diskimgN.img + This can be any number of floppy disk images one wants mounted after DosBox boots the specified drive letter. + To swap between images, one hits CTRL+F4 to swap out the current disk and swap in the next disk in the list. Once + the last disk in the list is swapped out, the list loops back to the beginning. + [-l driveletter] + This parameter allows one to specify the drive to boot from. The default is the A drive, the floppy drive. One + can also boot off of a hard drive image mounted as master by specifying "-l C" without the quotes, or the drive + as slave by specifying "-l D" - disk image IPX -BOOT + All of the IPX networking is managed through the internal DosBox program + IPXNET. For help on the IPX networking from inside DosBox, type “IPXNET HELP” + (without quotes) and the program will list out the commands and relevant + documentation. + With regard to actually setting up a network, one system needs to be the server. + To set this up, in a DosBox section, one should type “IPXNET STARTSERVER” + (without the quotes). The server DosBox session will automatically add itself + to the virtual IPX network. In turn, for every other computer that should be + part of the virtual IPX network, you’ll need to type “IPXNET CONNECT + ”. For example, if your server is at bob.dosbox.com, + you would type “IPXNET CONNECT bob.dosbox.com” on every non-server system. + + The following is an IPXNET command reference: + + IPXNET CONNECT + + IPXNET CONNECT opens a connection to an IPX tunneling server + running on another DosBox session. The "address" parameter specifies + the IP address or host name of the server computer. One can also + specify the UDP port to use. By default IPXNET uses port 213, the + assigned IANA port for IPX tunneling, for its connection. + + The syntax for IPXNET CONNECT is: + IPXNET CONNECT address + + IPXNET DISCONNECT + + IPXNET DISCONNECT closes the connection to the IPX tunneling server. + + The syntax for IPXNET DISCONNECT is: + IPXNET DISCONNECT + + IPXNET STARTSERVER + + IPXNET STARTSERVER starts and IPX tunneling server on this DosBox + session. By default, the server will accept connections on UDP port + 213, though this can be changed. Once the server is started, DosBox + will automatically start a client connection to the IPX tunneling server. + + The syntax for IPXNET STARTSERVER is: + IPXNET STARTSERVER + + IPXNET STOPSERVER + + IPXNET STOPSERVER stops the IPX tunneling server running on this DosBox + session. Care should be taken to ensure that all other connections have + terminated as well since stopping the server may cause lockups on other + machines still using the IPX tunneling server. + + The syntax for IPXNET STOPSERVER is: + IPXNET STOPSERVER + + IPXNET PING + + IPXNET PING broadcasts a ping request through the IPX tunneled network. + In response, all other connected computers will respond to the ping + and report the time it took to receive and send the ping message. + + The syntax for IPXNET PING is: + IPXNET PING + + IPXNET STATUS + + IPXNET STATUS reports the current state of this DosBox's sessions + IPX tunneling network. For a list of the computers connected to the + network use the IPXNET PING command. + + The syntax for IPXNET STATUS is: + IPXNET STATUS For more information use the /? command line switch with the programs. From d4e222d44030f0330b1381131859c6242389f80a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 22 Sep 2004 14:52:07 +0000 Subject: [PATCH 1906/4131] double message length Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1988 --- src/misc/messages.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 8a75a357..10be4118 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -29,7 +29,7 @@ using namespace std; -#define LINE_IN_MAXLEN 1024 +#define LINE_IN_MAXLEN 2048 struct MessageBlock { string name; From dfe8dc1debe06c2c685ac85addd66b7801690b16 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 22 Sep 2004 17:42:29 +0000 Subject: [PATCH 1907/4131] Spaces to tabs and maxlinelength=80 chars Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1989 --- README | 174 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 100 insertions(+), 74 deletions(-) diff --git a/README b/README index 057ad766..d2731af5 100644 --- a/README +++ b/README @@ -38,7 +38,7 @@ INDEX: 1. Quickstart: ============== -Type INTRO in dosbox. That's it. +Type INTRO in DOSBox. That's it. @@ -146,7 +146,7 @@ A: DOSBox emulates several legacy sound devices: Borrowed from MAME, this emulation is almost perfect and includes the Adlib's ability to almost play digitized sound. - SoundBlaster Pro - Coupled with the Adlib, DosBox provides Soundblaster Pro level 8-bit + Coupled with the Adlib, DOSBox provides Soundblaster Pro level 8-bit stereo sound. - Disney Soundsource Using the printer port, this sound device outputs digital sound only. @@ -291,7 +291,7 @@ MOUNT -cd Basically, MOUNT allows you to connect real hardware to DOSBox's "emulated" PC. So MOUNT C C:\ tells DOSBox to use your real C: drive as drive C: in - DosBox. It also allows you to change the drive's letter identification for + DOSBox. It also allows you to change the drive's letter identification for programs that demand specific drive letters. For example: Touche: Adventures of The Fifth Musketeer must be run on your C: @@ -375,122 +375,148 @@ MIXER IMGMOUNT A utility to mount disk images and CD-ROM images in DOSBox. - CD-ROM: either iso or cue/bin is supported: - IMGMOUNT DRIVE [imagefile] -t [image_type] -fs [image_format] -size [sectorsbytesize, sectorsperhead, heads, cylinders] + IMGMOUNT DRIVE [imagefile] -t [image_type] -fs [image_format] + -size [sectorsbytesize, sectorsperhead, heads, cylinders] + imagefile - location of the image files to mount in DosBox. Path is relative to a mount - point already inside DosBox. + location of the image files to mount in DOSBox. Path is relative to + a mount point already inside DOSBox. CD-ROM images can be mounted + directly as well (path on the host). -t - The following are valid image types: - floppy: Specifies a floppy image or images. DosBox will automatically identify the disk geometry (i.e, 360K - 1.2MB, 720K, 1.44MB, etc.) - iso: Specifies a CD-ROM iso image. The geometry is automatic and set for this size. - hdd: Specifies a harddrive image. The proper CHS geometry must be set for this to work. + The following are valid image types: + floppy: Specifies a floppy image or images. DOSBox will automatically + identify the disk geometry ( 360K, 1.2MB, 720K, 1.44MB, etc). + iso: Specifies a CD-ROM iso image. The geometry is automatic and + set for this size. This can be an iso or a cue/bin. + hdd: Specifies a harddrive image. The proper CHS geometry + must be set for this to work. -fs - The following are valid file system formats: - iso: Specifies the ISO 9660 CD-ROM format. - fat: Specifies the image uses the FAT file system. DosBox will attempt to mount this image as a drive - in DosBox and make the files available from inside DosBox. - none: DosBox will make no attempt to read the file system on the disk. This is useful if one needs to - format it or one wants to boot off of the disk using the BOOT command. When using the "none" file - system, one must specify the drive number (2 or 3, where 2 = master, 3 = slave) rather than a drive - letter. For example, to mount a 70MB image as the slave drive device, one would type: - "imgmount 3 d:\test.img -size 512,63,16,142 -fs none" (without the quotes) Compare this with a mount to - read the drive in DosBox, which would read as: "imgmount e: d:\test.img -size 512,63,16,142" + The following are valid file system formats: + iso: Specifies the ISO 9660 CD-ROM format. + fat: Specifies the image uses the FAT file system. DOSBox will attempt + to mount this image as a drive in DOSBox and make the files + available from inside DOSBox. + none: DOSBox will make no attempt to read the file system on the disk. + This is useful if one needs to format it or one wants to boot + off of the disk using the BOOT command. When using the "none" + filesystem, one must specify the drive number (2 or 3, + where 2 = master, 3 = slave) rather than a drive letter. + For example, to mount a 70MB image as the slave drive device, + one would type: + "imgmount 3 d:\test.img -size 512,63,16,142 -fs none" + (without the quotes) Compare this with a mount to read the + drive in DOSBox, which would read as: + "imgmount e: d:\test.img -size 512,63,16,142" -size - The Cylinders, Heads and Sectors specification of the drive. Required to mount hard drive images. + The Cylinders, Heads and Sectors specification of the drive. + Required to mount hard drive images. + + An example of CD-ROM images: + 1a. mount c /tmp + 1b. mount d c:\myiso.iso -t iso + or (which also works) + 2. mount d /tmp/myiso.iso -t iso + BOOT - Boot will start floppy images or hard disk images independent of the operating system emulation offered by - DosBox. This will allow you to play booter floppies or boot to other operating systems inside DosBox. + Boot will start floppy images or hard disk images independent of the + operating system emulation offered by DOSBox. This will allow you to play + booter floppies or boot to other operating systems inside DOSBox. BOOT [diskimg1.img diskimg2.img .. diskimgN.img] [-l driveletter] diskimgN.img - This can be any number of floppy disk images one wants mounted after DosBox boots the specified drive letter. - To swap between images, one hits CTRL+F4 to swap out the current disk and swap in the next disk in the list. Once - the last disk in the list is swapped out, the list loops back to the beginning. + This can be any number of floppy disk images one wants mounted after + DOSBox boots the specified drive letter. + To swap between images, one hits CTRL+F4 to swap out the current disk + and swap in the next disk in the list. Once the last disk in the list is + swapped out, the list loops back to the beginning. + [-l driveletter] - This parameter allows one to specify the drive to boot from. The default is the A drive, the floppy drive. One - can also boot off of a hard drive image mounted as master by specifying "-l C" without the quotes, or the drive - as slave by specifying "-l D" + This parameter allows one to specify the drive to boot from. + The default is the A drive, the floppy drive. One can also boot off of + a hard drive image mounted as master by specifying "-l C" + without the quotes, or the drive as slave by specifying "-l D" IPX - All of the IPX networking is managed through the internal DosBox program - IPXNET. For help on the IPX networking from inside DosBox, type “IPXNET HELP” - (without quotes) and the program will list out the commands and relevant - documentation. + You need to enable IPX networking in the configuration file of DOSBox. - With regard to actually setting up a network, one system needs to be the server. - To set this up, in a DosBox section, one should type “IPXNET STARTSERVER” - (without the quotes). The server DosBox session will automatically add itself - to the virtual IPX network. In turn, for every other computer that should be - part of the virtual IPX network, you’ll need to type “IPXNET CONNECT - ”. For example, if your server is at bob.dosbox.com, - you would type “IPXNET CONNECT bob.dosbox.com” on every non-server system. + All of the IPX networking is managed through the internal DOSBox program + IPXNET. For help on the IPX networking from inside DOSBox, type + "IPXNET HELP" (without quotes) and the program will list out the commands + and relevant documentation. + + With regard to actually setting up a network, one system needs to be + the server. To set this up, in a DOSBox session, one should type + "IPXNET STARTSERVER" (without the quotes). The server DOSBox session will + automatically add itself to the virtual IPX network. In turn, for every + other computer that should be part of the virtual IPX network, + you'll need to type "IPXNET CONNECT ". + For example, if your server is at bob.dosbox.com, + you would type "IPXNET CONNECT bob.dosbox.com" on every non-server system. The following is an IPXNET command reference: IPXNET CONNECT - IPXNET CONNECT opens a connection to an IPX tunneling server - running on another DosBox session. The "address" parameter specifies - the IP address or host name of the server computer. One can also - specify the UDP port to use. By default IPXNET uses port 213, the - assigned IANA port for IPX tunneling, for its connection. + IPXNET CONNECT opens a connection to an IPX tunneling server + running on another DOSBox session. The "address" parameter specifies + the IP address or host name of the server computer. One can also + specify the UDP port to use. By default IPXNET uses port 213, the + assigned IANA port for IPX tunneling, for its connection. - The syntax for IPXNET CONNECT is: - IPXNET CONNECT address + The syntax for IPXNET CONNECT is: + IPXNET CONNECT address IPXNET DISCONNECT - IPXNET DISCONNECT closes the connection to the IPX tunneling server. + IPXNET DISCONNECT closes the connection to the IPX tunneling server. - The syntax for IPXNET DISCONNECT is: - IPXNET DISCONNECT + The syntax for IPXNET DISCONNECT is: + IPXNET DISCONNECT IPXNET STARTSERVER - IPXNET STARTSERVER starts and IPX tunneling server on this DosBox - session. By default, the server will accept connections on UDP port - 213, though this can be changed. Once the server is started, DosBox - will automatically start a client connection to the IPX tunneling server. + IPXNET STARTSERVER starts and IPX tunneling server on this DOSBox + session. By default, the server will accept connections on UDP port + 213, though this can be changed. Once the server is started, DOSBox + will automatically start a client connection to the IPX tunneling server. - The syntax for IPXNET STARTSERVER is: - IPXNET STARTSERVER + The syntax for IPXNET STARTSERVER is: + IPXNET STARTSERVER IPXNET STOPSERVER - IPXNET STOPSERVER stops the IPX tunneling server running on this DosBox - session. Care should be taken to ensure that all other connections have - terminated as well since stopping the server may cause lockups on other - machines still using the IPX tunneling server. + IPXNET STOPSERVER stops the IPX tunneling server running on this DOSBox + session. Care should be taken to ensure that all other connections have + terminated as well since stopping the server may cause lockups on other + machines still using the IPX tunneling server. - The syntax for IPXNET STOPSERVER is: - IPXNET STOPSERVER + The syntax for IPXNET STOPSERVER is: + IPXNET STOPSERVER IPXNET PING - IPXNET PING broadcasts a ping request through the IPX tunneled network. - In response, all other connected computers will respond to the ping - and report the time it took to receive and send the ping message. + IPXNET PING broadcasts a ping request through the IPX tunneled network. + In response, all other connected computers will respond to the ping + and report the time it took to receive and send the ping message. - The syntax for IPXNET PING is: - IPXNET PING + The syntax for IPXNET PING is: + IPXNET PING IPXNET STATUS - IPXNET STATUS reports the current state of this DosBox's sessions - IPX tunneling network. For a list of the computers connected to the - network use the IPXNET PING command. + IPXNET STATUS reports the current state of this DOSBox's sessions + IPX tunneling network. For a list of the computers connected to the + network use the IPXNET PING command. - The syntax for IPXNET STATUS is: - IPXNET STATUS +The syntax for IPXNET STATUS is: +IPXNET STATUS For more information use the /? command line switch with the programs. From 411f666dcd6cdc78162b476dae36d9828fb1827f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 23 Sep 2004 14:56:59 +0000 Subject: [PATCH 1908/4131] typo's (screcko) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1990 --- README | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README b/README index d2731af5..9f528b1f 100644 --- a/README +++ b/README @@ -7,7 +7,7 @@ NOTE: While we hope that, one day, DOSBox will run virtually all programs ever made for the PC...we are not there yet. At present, DOSBox run on a high- -end machine will roughly be the equivalent of a low-end 486 PC. The 0.60 +end machine will roughly be the equivalent of a 486 PC. The 0.60 release has added support for "protected mode" allowing for more complex and 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 @@ -415,10 +415,10 @@ IMGMOUNT Required to mount hard drive images. An example of CD-ROM images: - 1a. mount c /tmp - 1b. mount d c:\myiso.iso -t iso - or (which also works) - 2. mount d /tmp/myiso.iso -t iso + 1a. mount c /tmp + 1b. imgmount d c:\myiso.iso -t iso + or (which also works): + 2. imgmount d /tmp/myiso.iso -t iso BOOT From 6fb463f5e1d314f08a795b6996d35f8825bb04cb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 23 Sep 2004 18:19:50 +0000 Subject: [PATCH 1909/4131] Spiced up startup message. and corrected a typo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1991 --- src/shell/shell.cpp | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index c01a5567..a833c6cd 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.46 2004-09-09 18:36:50 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.47 2004-09-23 18:19:50 qbix79 Exp $ */ #include #include @@ -47,7 +47,7 @@ void SHELL_AddAutoexec(char * line,...) { size_t auto_len=strlen(autoexec_data); if ((auto_len+strlen(line)+3)>AUTOEXEC_SIZE) { - E_Exit("SYSTEM:Autoexec.bat file overlow"); + E_Exit("SYSTEM:Autoexec.bat file overflow"); } sprintf((autoexec_data+auto_len),"%s\r\n",buf); } @@ -296,13 +296,25 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_SUBST_NO_REMOVE","Removing drive not supported. Doing nothing.\n"); MSG_Add("SHELL_CMD_SUBST_FAILURE","SUBST failed. You either made an error in your commandline or the target drive is already used.\nIt's only possible to use SUBST on Local drives"); - MSG_Add("SHELL_STARTUP","DOSBox Shell v" VERSION "\n" - "This version runs some protected mode games!\n" - "For supported shell commands type: HELP\n" - "For a short introduction type: INTRO\n\n" - "If you want more speed, try ctrl-F8 and ctrl-F12.\n" - "For more information read the README file in DOSBox directory.\n" - "\nHAVE FUN!\nThe DOSBox Team\n\n" + MSG_Add("SHELL_STARTUP", + "\033[44;1m\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n" + "\xBA \033[32mDOSBox Shell v" VERSION "\033[37m \xBA\n" + "\xBA DOSBox runs real and protected mode games. \xBA\n" + "\xBA For supported shell commands type: \033[1;33mHELP\033[37m \xBA\n" + "\xBA For a short introduction type: \033[1;33mINTRO\033[37m \xBA\n" + "\xBA \xBA\n" + "\xBA If you want more speed, try \033[31;1mctrl-F8\033[37m and \033[31;1mctrl-F12\033[37m. \xBA\n" + "\xBA To activate the keymapper \033[31;1mctrl-F1\033[37m. Useful if you have problems. \xBA\n" + "\xBA For more information read the \033[0;44;32mREADME\033[37;1m file in the DOSBox directory. \xBA\n" + "\xBA \xBA\n" + "\xBA \033[32mHAVE FUN!\033[37m \xBA\n" + "\xBA \033[32mThe DOSBox Team\033[37m \xBA\n" + "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC\033[0m\n" + //"\n" //Breaks the startup message if you type a mount and a drive change. ); MSG_Add("SHELL_CMD_CHDIR_HELP","Change Directory.\n"); From 06bca7369fd2a1b9b707843e2bd3524827af5d91 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 23 Sep 2004 19:03:05 +0000 Subject: [PATCH 1910/4131] Enable RTTI in visual.net Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1992 --- visualc_net/dosbox.vcproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index c79a15cc..f397a0f1 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -25,6 +25,7 @@ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" BasicRuntimeChecks="3" RuntimeLibrary="3" + RuntimeTypeInfo="TRUE" PrecompiledHeaderFile=".\Debug/dosbox.pch" AssemblerListingLocation=".\Debug/" ObjectFile=".\Debug/" @@ -97,6 +98,7 @@ RuntimeLibrary="2" BufferSecurityCheck="FALSE" EnableFunctionLevelLinking="TRUE" + RuntimeTypeInfo="TRUE" PrecompiledHeaderFile=".\Release/dosbox.pch" AssemblerOutput="4" AssemblerListingLocation=".\Release/" From 4c8e0fe30cb46d119ea14b1e9e5f41a77935867f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 23 Sep 2004 19:22:28 +0000 Subject: [PATCH 1911/4131] Poor mans update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1993 --- docs/dosbox.1 | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/docs/dosbox.1 b/docs/dosbox.1 index b19b7993..9a885c18 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -1,11 +1,12 @@ .\" Hey, EMACS: -*- nroff -*- -.TH DOSBOX 1 "June 5, 2004" +.TH DOSBOX 1 "Sept 23, 2004" .\" 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] .BI "[\-conf " configfile ] .BI "[\-lang " langfile ] .B [file] @@ -25,6 +26,9 @@ A summary of options is included below. .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 .BI \-c " command" .RI "Runs the specified " command " before running " .BR file . @@ -137,6 +141,30 @@ The amount of memory to eat up (in kb). Example -32, -64 or -128 .B \-f Frees all memory eaten up by loadfix. .RE +.TP +.B IMGMOUNT +.LP +.RB "A utility to mount disk images and CD-ROM images in " DOSBox . +.TP +.RB "Read the " README " of " DOSBox " for the full and correct syntax." +.RE +.TP +.B BOOT +.LP +.RB "Boot will start floppy images or hard disk images independent of the operating system emulation offered by " DOSBox ". This will allow you to play booter floppies or boot to other operating systems inside "DOSBox . +.TP +.RB "Read the " README " of " DOSBox " for the full and correct syntax." +.RE +.TP +.B IPX +.LP +.RB "You need to enable IPX networking in the configuration file of "DOSBox . +.RB "All of the IPX networking is managed through the internal " DOSBox " program +.BR IPXNET ". For help on the IPX networking from inside " DOSBox ", type" +.BR "IPXNET HELP" " and the program will list out the commands and relevant documentation." +.TP +.RB "Read the " README " of " DOSBox " for the full and correct syntax." +.RE .SH FILES Configuration and language files use a format similar to Windows .ini files. If a file named .BR dosbox.conf " is found in the current directory, it will be automatically loaded." @@ -144,10 +172,18 @@ Configuration and language files use a format similar to Windows .ini files. If .TP 12m .IP ALT\-ENTER Go full screen and back. +.IP CTRL\-F1 +Start the keymapper. +.IP CTRL\-F4 +Swap mounted disk-image (Only used with imgmount). .IP CTRL\-F5 Save a screenshot. .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 @@ -161,8 +197,9 @@ Slow down emulation (Increase DOSBox Cycles). .IP CTRL\-F12 Speed up emulation (Decrease DOSBox Cycles). .PP -.B "Note: " -Once you increase your DOSBox cycles beyond your computer's maximum +These are the default keybindings. They can be changed in the keymapper. +.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" From b607b906892f5a775314a68f9f919c78ca34b73d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 23 Sep 2004 19:29:52 +0000 Subject: [PATCH 1912/4131] Tiny update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1994 --- scripts/dosbox-installer.nsi | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index ef214926..cb2e54b9 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -1,5 +1,5 @@ !define VER_MAYOR 0 -!define VER_MINOR 61 +!define VER_MINOR 62 ; The name of the installer Name "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer" @@ -15,7 +15,7 @@ DirText "This will install DOSBox v${VER_MAYOR}.${VER_MINOR} on your computer. C SetCompressor bzip2 LicenseData COPYING -LicenseText "DOSBox v${VER_MAYOR}.${VER_MINOR} License" "Next->" +LicenseText "DOSBox v${VER_MAYOR}.${VER_MINOR} License" "Next >" ; The stuff to install Section "ThisNameIsIgnoredSoWhyBother?" @@ -62,6 +62,9 @@ Section "Uninstall" Delete $INSTDIR\SDL.dll Delete $INSTDIR\SDL_net.dll Delete $INSTDIR\libpng12.dll + ;Files left by sdl taking over the console + Delete $INSTDIR\stdout.txt + Delete $INSTDIR\stderr.txt ; MUST REMOVE UNINSTALLER, too Delete $INSTDIR\uninstall.exe From 6574f599b7ca5e407a9b12be88bf1ecf22e9955b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 25 Sep 2004 09:19:53 +0000 Subject: [PATCH 1913/4131] Readme to lightblue Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1995 --- src/shell/shell.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index a833c6cd..c155441c 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.47 2004-09-23 18:19:50 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.48 2004-09-25 09:19:53 qbix79 Exp $ */ #include #include @@ -307,7 +307,7 @@ void SHELL_Init() { "\xBA \xBA\n" "\xBA If you want more speed, try \033[31;1mctrl-F8\033[37m and \033[31;1mctrl-F12\033[37m. \xBA\n" "\xBA To activate the keymapper \033[31;1mctrl-F1\033[37m. Useful if you have problems. \xBA\n" - "\xBA For more information read the \033[0;44;32mREADME\033[37;1m file in the DOSBox directory. \xBA\n" + "\xBA For more information read the \033[36;1mREADME\033[37m file in the DOSBox directory. \xBA\n" "\xBA \xBA\n" "\xBA \033[32mHAVE FUN!\033[37m \xBA\n" "\xBA \033[32mThe DOSBox Team\033[37m \xBA\n" From 3860c9c948d71d5e1089b69c25694e7cdfe595ee Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Sep 2004 10:39:19 +0000 Subject: [PATCH 1914/4131] Installing documentation. Requested by Khalek Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1996 --- Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index bfb4714a..00c0c28f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,5 +3,6 @@ EXTRA_DIST = autogen.sh SUBDIRS = src include visualc docs visualc_net - +docdir = $(prefix)/share/doc/$(PACKAGE) +doc_DATA = README NEWS THANKS AUTHORS From 7da8b39be54f5991da3aba0d845538b0e499f923 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Sep 2004 15:31:21 +0000 Subject: [PATCH 1915/4131] Some cleanups and some dots Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1997 --- src/shell/shell.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index c155441c..097dcf43 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.48 2004-09-25 09:19:53 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.49 2004-09-28 15:31:21 qbix79 Exp $ */ #include #include @@ -265,17 +265,17 @@ static char * init_line="/INIT AUTOEXEC.BAT"; void SHELL_Init() { /* Add messages */ - MSG_Add("SHELL_ILLEGAL_PATH","Illegal Path\n"); + MSG_Add("SHELL_ILLEGAL_PATH","Illegal Path.\n"); MSG_Add("SHELL_CMD_HELP","supported commands are:\n"); - MSG_Add("SHELL_CMD_ECHO_ON","ECHO is on\n"); - MSG_Add("SHELL_CMD_ECHO_OFF","ECHO is off\n"); - MSG_Add("SHELL_ILLEGAL_SWITCH","Illegal switch: %s\n"); - MSG_Add("SHELL_CMD_CHDIR_ERROR","Unable to change to: %s\n"); - MSG_Add("SHELL_CMD_MKDIR_ERROR","Unable to make: %s\n"); - MSG_Add("SHELL_CMD_RMDIR_ERROR","Unable to remove: %s\n"); - MSG_Add("SHELL_CMD_DEL_ERROR","Unable to delete: %s\n"); + MSG_Add("SHELL_CMD_ECHO_ON","ECHO is on.\n"); + MSG_Add("SHELL_CMD_ECHO_OFF","ECHO is off.\n"); + MSG_Add("SHELL_ILLEGAL_SWITCH","Illegal switch: %s.\n"); + MSG_Add("SHELL_CMD_CHDIR_ERROR","Unable to change to: %s.\n"); + MSG_Add("SHELL_CMD_MKDIR_ERROR","Unable to make: %s.\n"); + MSG_Add("SHELL_CMD_RMDIR_ERROR","Unable to remove: %s.\n"); + MSG_Add("SHELL_CMD_DEL_ERROR","Unable to delete: %s.\n"); MSG_Add("SHELL_SYNTAXERROR","The syntax of the command is incorrect.\n"); - MSG_Add("SHELL_CMD_SET_NOT_SET","Environment variable %s not defined\n"); + MSG_Add("SHELL_CMD_SET_NOT_SET","Environment variable %s not defined.\n"); MSG_Add("SHELL_CMD_SET_OUT_OF_SPACE","Not enough environment space left.\n"); MSG_Add("SHELL_CMD_IF_EXIST_MISSING_FILENAME","IF EXIST: Missing filename.\n"); MSG_Add("SHELL_CMD_IF_ERRORLEVEL_MISSING_NUMBER","IF ERRORLEVEL: Missing number.\n"); @@ -285,9 +285,9 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_FILE_NOT_FOUND","File %s not found.\n"); MSG_Add("SHELL_CMD_FILE_EXISTS","File %s already exists.\n"); MSG_Add("SHELL_CMD_DIR_INTRO","Directory of %s.\n"); - MSG_Add("SHELL_CMD_DIR_BYTES_USED","%5d File(s) %17s Bytes\n"); - MSG_Add("SHELL_CMD_DIR_BYTES_FREE","%5d Dir(s) %17s Bytes free\n"); - MSG_Add("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\nYou must mount it first. Type intro for more information.\n"); + MSG_Add("SHELL_CMD_DIR_BYTES_USED","%5d File(s) %17s Bytes.\n"); + MSG_Add("SHELL_CMD_DIR_BYTES_FREE","%5d Dir(s) %17s Bytes free.\n"); + MSG_Add("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\nYou must \033[31mmount\033[0m it first. Type \033[1;33mintro\033[0m for more information.\n"); MSG_Add("SHELL_EXECUTE_ILLEGAL_COMMAND","Illegal command: %s.\n"); MSG_Add("SHELL_CMD_PAUSE","Press any key to continue.\n"); MSG_Add("SHELL_CMD_PAUSE_HELP","Waits for 1 keystroke to continue.\n"); @@ -303,11 +303,11 @@ void SHELL_Init() { "\xBA \033[32mDOSBox Shell v" VERSION "\033[37m \xBA\n" "\xBA DOSBox runs real and protected mode games. \xBA\n" "\xBA For supported shell commands type: \033[1;33mHELP\033[37m \xBA\n" - "\xBA For a short introduction type: \033[1;33mINTRO\033[37m \xBA\n" + "\xBA For a short introduction type: \033[33mINTRO\033[37m \xBA\n" "\xBA \xBA\n" - "\xBA If you want more speed, try \033[31;1mctrl-F8\033[37m and \033[31;1mctrl-F12\033[37m. \xBA\n" - "\xBA To activate the keymapper \033[31;1mctrl-F1\033[37m. Useful if you have problems. \xBA\n" - "\xBA For more information read the \033[36;1mREADME\033[37m file in the DOSBox directory. \xBA\n" + "\xBA If you want more speed, try \033[31mctrl-F8\033[37m and \033[31mctrl-F12\033[37m. \xBA\n" + "\xBA To activate the keymapper \033[31mctrl-F1\033[37m. \xBA\n" + "\xBA For more information read the \033[36mREADME\033[37m file in the DOSBox directory. \xBA\n" "\xBA \xBA\n" "\xBA \033[32mHAVE FUN!\033[37m \xBA\n" "\xBA \033[32mThe DOSBox Team\033[37m \xBA\n" @@ -335,7 +335,7 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_DELETE_HELP","Removes files.\n"); MSG_Add("SHELL_CMD_COPY_HELP","Copy files.\n"); MSG_Add("SHELL_CMD_CALL_HELP","Start a batch file from within another batch file.\n"); - MSG_Add("SHELL_CMD_SUBST_HELP","Assign an internal directory to a drive\n"); + MSG_Add("SHELL_CMD_SUBST_HELP","Assign an internal directory to a drive.\n"); MSG_Add("SHELL_CMD_LOADHIGH_HELP","Run a program. For batch file compatibility only.\n"); MSG_Add("SHELL_CMD_CHOICE_HELP","Waits for a keypress and sets ERRORLEVEL.\n"); MSG_Add("SHELL_CMD_ATTRIB_HELP","Does nothing. Provided for compatibility.\n"); From 6c6c6f031c326e5d3a47c9ad4b225d91fd5ed4a3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 28 Sep 2004 15:43:31 +0000 Subject: [PATCH 1916/4131] Fix cursor start end line for non-vga card support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1998 --- src/hardware/vga_other.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 1303d9ca..807d7abf 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -64,24 +64,29 @@ static void write_crtc_data_other(Bitu port,Bitu val,Bitu iolen) { if (vga.other.max_scanline ^ val) VGA_StartResize(); vga.other.max_scanline=val; break; - vga.config.display_start=(vga.config.display_start & 0xFF00FF)| (val << 8); + case 0x0A: /* Cursor Start Register */ + vga.draw.cursor.sline = val&0x1f; + vga.draw.cursor.enabled = ((val & 0x60) != 0x20); + break; + case 0x0B: /* Cursor End Register */ + vga.draw.cursor.eline = val&0x1f; break; case 0x0C: /* Start Address High Register */ - vga.config.display_start=(vga.config.display_start & 0xFF00FF)| (val << 8); + vga.config.display_start=(vga.config.display_start & 0x00FF) | (val << 8); break; case 0x0D: /* Start Address Low Register */ - vga.config.display_start=(vga.config.display_start & 0xFFFF00)| val; + vga.config.display_start=(vga.config.display_start & 0xFF00) | val; break; case 0x0E: /*Cursor Location High Register */ - vga.config.cursor_start&=0xff00ff; + vga.config.cursor_start&=0x00ff; vga.config.cursor_start|=val << 8; break; case 0x0F: /* Cursor Location Low Register */ - vga.config.cursor_start&=0xffff00; + vga.config.cursor_start&=0xff00; vga.config.cursor_start|=val; break; default: - LOG_MSG("Write %X to illgal index %x",val,vga.other.index); + LOG(LOG_VGAMISC,LOG_NORMAL)("MC6845:Write %X to illegal index %x",val,vga.other.index); } } static Bitu read_crtc_data_other(Bitu port,Bitu iolen) { @@ -113,7 +118,7 @@ static Bitu read_crtc_data_other(Bitu port,Bitu iolen) { case 0x0F: /* Cursor Location Low Register */ return vga.config.cursor_start; default: - LOG_MSG("Read from illgal index %x",vga.other.index); + LOG(LOG_VGAMISC,LOG_NORMAL)("MC6845:Read from illegal index %x",vga.other.index); } return (Bitu)-1; } From 4848431a5abfc3e611911865dd621be311cc5a97 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Sep 2004 20:11:23 +0000 Subject: [PATCH 1917/4131] Added keymapper documentation Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1999 --- README | 102 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 83 insertions(+), 19 deletions(-) diff --git a/README b/README index 9f528b1f..4779335f 100644 --- a/README +++ b/README @@ -25,13 +25,14 @@ INDEX: 3. Usage 4. Internal Programs 5. Special Keys -6. System Requirements -7. To run resource-demanding games -8. The config file -9. The language file -10. Building your own version of DOSBox -11. Special thanks -12. Contact +6. Keymapper +7. System Requirements +8. To run resource-demanding games +9. The config file +10. The language file +11. Building your own version of DOSBox +12. Special thanks +13. Contact ============== @@ -53,7 +54,7 @@ Q: I've got a Z instead of a C at the prompt. Q: My CD-ROM doesn't work. Q: The mouse doesn't work. Q: The sound stutters. -Q: I can't type \ in DOSBox. +Q: I can't type \ or : in DOSBox. Q: The game/application can't find its CD-ROM. Q: The game/application runs much too slow! Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. @@ -101,14 +102,15 @@ A: You're using too much cpu power to keep DOSBox running at the current speed. You can either lower the cycles or skip frames or get a faster machine. You can also increase the prebuffer in the configfile -Q: I can't type \ in DOSBox. +Q: I can't type \ or : in DOSBox. A: This is a known problem. It only occurs if your keyboard layout isn't US. Some possible fixes: 1. Switch your keyboard layout. 2. Use / instead. 3. Add the commands you want to execute to dosbox.conf 4. Start the keymapper (CTRL-F1 or add -startmapper switch to dosbox) - + 5. for \ try the keys around enter. For : try shift and the keys between + enter and "l" (US keyboard layout). Q: The game/application can't find its CD-ROM. A: Be sure to mount the CD-ROM with -t cdrom switch. Also try adding the @@ -549,8 +551,70 @@ This maximum will vary from computer to computer, there is no standard. +============= +6. Keymapper: +============= + +When you start the keymapper (either with CTRL-F1 or -startmapper as a +commandline argument) you are presented with a virtual keyboard. + +This virtual keyboard corresponds with the keys DOSBox will report to its +applications. If you click on a key with your mouse, you can see in the +lowerleft corner which key on your keyboard corresponds with it. + +Event: EVENT +BIND: BIND + Add Del +mod1 hold Next +mod2 +mod3 + + +EVENT + The key DOSBox will report to the applications being emulated. +BIND + The key on your keyboard (as reported by SDL) which is connected to the + EVENT. +mod1,2,3 + Modfiers. These are keys you need to have pressed as well, while pressing + BIND. mod1 = CTRL and mod2 = ALT. These are generally only used when you + want to change the special keys of DOSBox. +Add + Add a new BIND to this EVENT. Basicly add a key from your keyboard which + will produce the key EVENT in DOSBox. +Del + Delete the BIND to this EVENT. If an EVENT has no BINDS than it's not + possible to type this key in DOSBox. +Next + Cycle through the list of keys(BINDS) which map to this EVENT. + + +Example: +Q1. You want to have the X on your keyboard to type a Z in DOSBox. + A. With your mouse click on the Z on the keyboard mapper. Click "Add". + Now press the X key on your keyboard. + +Q2. If you click "Next" a few times you will notice that the Z on your + keyboard also produces an Z in DOSBox. + A. Therefore select the Z again and click "Next" till you have the Z on + your keyboard. Now click "Del". + +Q3. If you try it out in DOSBox you will notice that pressing X makes ZX + appear. + A. The X on your keyboard is still mapped to the X as well! Click on + the X in the keyboard mapper and search with "Next" till you find the + mapped key X. Click "Del". + + +If you change the default mapping you can save your changes by pressing +"Save". DOSBox will save the mapping to location specified in the configfile +(mapperfile=mapper.txt). At startup DOSBox will load your mapperfile if it's +present in the configfile. + + + ======================= -6. System requirements: +7. System requirements: ======================= Fast machine. My guess would be pentium-2 400+ to get decent emulation @@ -562,7 +626,7 @@ it up somewhat. =================================== -7. To run resource-demanding games: +8. To run resource-demanding games: =================================== DOSBox emulates the CPU, the sound and graphic cards, and some other @@ -593,7 +657,7 @@ to further reduce load on your CPU. =================== -8. The Config File: +9. The Config File: =================== A config file can be generated by CONFIG.COM, which can be found on the @@ -613,9 +677,9 @@ current directory for dosbox.conf. Then it will look for ~/.dosboxrc (Linux), -===================== -9. The Language File: -===================== +====================== +10. The Language File: +====================== A language file can be generated by CONFIG.COM. Read it and you will hopefully understand how to change it. @@ -626,7 +690,7 @@ There's a language= entry that can be changed with the filename. ======================================== -10. Building your own version of DOSBox: +11. Building your own version of DOSBox: ======================================== Download the source. @@ -635,7 +699,7 @@ Check the INSTALL in the source distribution. =================== -11. Special Thanks: +12. Special Thanks: =================== Vlad R. of the vdmsound project for excellent sound blaster info. @@ -649,7 +713,7 @@ The Beta Testers. ============ -12. Contact: +13. Contact: ============ See the site: From 699a6f345e5d9c77e24d382e38bd4e0925fcd696 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Sep 2004 20:17:31 +0000 Subject: [PATCH 1918/4131] Font banks are 64 kb now. updating pagehandler to match. (wjp) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2000 --- src/hardware/vga_memory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 78846035..0d67a8ae 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -213,11 +213,11 @@ public: flags=PFLAG_NOCODE; } Bitu readb(PhysPt addr) { - addr&=0x7fff; + addr&=0xffff; return vga.draw.font[addr]; } void writeb(PhysPt addr,Bitu val){ - addr&=0x7fff; + addr&=0xffff; if (vga.seq.map_mask & 0x4) { vga.draw.font[addr]=(Bit8u)val; } From 833c06aebb09a3ec64e2ff75d1f6d6b4f6272f05 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 29 Sep 2004 18:24:58 +0000 Subject: [PATCH 1919/4131] Added del/. on numeric keyboard Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2001 --- src/ints/bios_keyboard.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index e6342a66..581adcfd 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -205,8 +205,8 @@ static Bitu IRQ1_Handler(void) { Bitu scancode; //,ascii,mod; #if 1 scancode=reg_al; //IO_Read(0x60); moved out of handler -// ascii=0; -// mod=0; + + #else /* Old code capable of unicode keys. Dropped Readkey disabled in keyboard.cpp */ KEYBOARD_ReadKey(scancode,ascii,mod); @@ -219,7 +219,7 @@ static Bitu IRQ1_Handler(void) { reg_ax=old_ax;Bit8u flags1,flags2,flags3,leds; if (!(reg_flags&1)) goto irq1_return; - //TODO maybe implement the int 0x15 ah=4f scancode lookup hook + flags1=mem_readb(BIOS_KEYBOARD_FLAGS1); flags2=mem_readb(BIOS_KEYBOARD_FLAGS2); flags3=mem_readb(BIOS_KEYBOARD_FLAGS3); @@ -301,6 +301,7 @@ static Bitu IRQ1_Handler(void) { case 0x50: case 0x51: case 0x52: + case 0x53: /* del . Not entirely correct, but works fine */ if(flags3 &0x02) { /*extend key. e.g key above arrows or arrows*/ if(scancode == 0x52) flags2 |=0x80; /* press insert */ add_key((scancode <<8)|0xe0); From d046e6b48c1ee41bf178b618b2cf508eb00826f8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 29 Sep 2004 19:04:58 +0000 Subject: [PATCH 1920/4131] Added info about keyb.com of freedos Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2002 --- README | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README b/README index 4779335f..8db24d50 100644 --- a/README +++ b/README @@ -72,6 +72,7 @@ A: You have to make your directories available as drives in DOSBox by using In Linux, "mount c /home/username" would give you a C in DOSBox which points at /home/username in Linux. + Q: My CD-ROM doesn't work. A: To mount your cdrom in DOSBox you have to specify some additional options when mounting the cdrom. @@ -102,6 +103,7 @@ A: You're using too much cpu power to keep DOSBox running at the current speed. You can either lower the cycles or skip frames or get a faster machine. You can also increase the prebuffer in the configfile + Q: I can't type \ or : in DOSBox. A: This is a known problem. It only occurs if your keyboard layout isn't US. Some possible fixes: @@ -109,8 +111,10 @@ A: This is a known problem. It only occurs if your keyboard layout isn't US. 2. Use / instead. 3. Add the commands you want to execute to dosbox.conf 4. Start the keymapper (CTRL-F1 or add -startmapper switch to dosbox) - 5. for \ try the keys around enter. For : try shift and the keys between - enter and "l" (US keyboard layout). + 5. for \ try the keys around "enter". For ":" try shift and the keys between + "enter" and "l" (US keyboard layout). + 6. Use keyb.com for FreeDOS (http://projects.freedos.net/keyb/). + Q: The game/application can't find its CD-ROM. A: Be sure to mount the CD-ROM with -t cdrom switch. Also try adding the From a335e200fca3c9cc7f0a24c8e36b222ce3b574a8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 29 Sep 2004 19:06:01 +0000 Subject: [PATCH 1921/4131] Update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2003 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 6e8cb1ef..36808a54 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.61 +0.62 From 348d0abffc17fa0002eab03a125e12c1848f8cf5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 29 Sep 2004 19:08:21 +0000 Subject: [PATCH 1922/4131] version update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2004 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index c7820e4d..a749e10b 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Init. -AC_INIT(dosbox,0.61) +AC_INIT(dosbox,0.62) AC_PREREQ(2.50) AC_CONFIG_SRCDIR(README) From 75edd6644ffa22b269c16ef5a42aa02f65e9e396 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 29 Sep 2004 19:09:44 +0000 Subject: [PATCH 1923/4131] Added very basic highres textmode support. (wjp) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2005 --- src/ints/int10_modes.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 795e07f1..0968678b 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -32,7 +32,8 @@ VideoModeBlock ModeList_VGA[]={ { 0x011 ,M_EGA16 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 },/*was EGA_2 */ { 0x012 ,M_EGA16 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, { 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,0 }, - +{ 0x054 ,M_TEXT ,1056 ,688, 132,43, 8, 8, 1 ,0xB8000 ,0x4000, 192, 800, 132, 688, 0 }, +{ 0x055 ,M_TEXT ,1056 ,400, 132,25, 8, 16, 1 ,0xB8000 ,0x2000, 192, 449, 132, 400, 0 }, { 0x100 ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, { 0x101 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, { 0x103 ,M_LIN8 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, From ce5fef7e9d5a3809a43dbb58b2b5bf290ae74d9e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 29 Sep 2004 19:14:10 +0000 Subject: [PATCH 1924/4131] Win32 alt-tab fix/hack Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2006 --- src/gui/sdlmain.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index c8dbfaaf..137f7306 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.78 2004-09-10 07:44:15 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.79 2004-09-29 19:14:10 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -931,6 +931,10 @@ static void HandleMouseButton(SDL_MouseButtonEvent * button) { } } +static Bit8u laltstate = SDL_KEYUP; +static Bit8u raltstate = SDL_KEYUP; + + void GFX_Events() { SDL_Event event; while (SDL_PollEvent(&event)) { @@ -961,6 +965,16 @@ void GFX_Events() { case SDL_QUIT: throw(0); break; +#ifdef WIN32 + case SDL_KEYDOWN: + case SDL_KEYUP: + // ignore event alt+tab + if (event.key.keysym.sym==SDLK_LALT) laltstate = event.key.type; + if (event.key.keysym.sym==SDLK_RALT) raltstate = event.key.type; + if (((event.key.keysym.sym==SDLK_TAB)) && + ((laltstate==SDL_KEYDOWN) || (raltstate==SDL_KEYDOWN))) break; +#endif + default: void MAPPER_CheckEvent(SDL_Event * event); MAPPER_CheckEvent(&event); From cc8b2602d81d7791f31d1857095714a7f6e66665 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 29 Sep 2004 19:21:50 +0000 Subject: [PATCH 1925/4131] Updates Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2007 --- ChangeLog | 2 ++ NEWS | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/ChangeLog b/ChangeLog index 58374de4..5500e85b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -54,9 +54,11 @@ - 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) diff --git a/NEWS b/NEWS index d3f4b516..b636030f 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,64 @@ +0.62 + - Added blinking support in the shell and some color fixes. + - Fixed commandline parsing when .bat files involved (fixes -exit) + - Fixed issues with tabs in commandline not being processed correctly. + - Cleaned/improved shutdown sequence. + - Added some more bios functions (wait and delay functions). + - Made our XMS driver conform the specs better. (c2woody) + - Added support for some more ems functions. + - Added intelligent mpu401 emulation. (Srecko) + - Added soundblaster 16 emulation. + - Rewrote GUS emulation to sound more authentic. + - Improved pc speaker emulation. + - Added an internal (programmable) mixer. + - Added support a few soundblaster/adlib detection routines. + - Fixed lot's of bugs related to DMA transfers. + - Added interpolating prebuffering mixer routines. + - Added recording of OPL commands and raw midi. + - Fixed some bugs with the wave recording. + - Changed sensitivity settings of the mouse. + - Added ps2 mouse-emulation in bios interrupts (c2woody). + - Fixed some bugs with mouse emulation limits. + - Fixed a bug with an unterminated string in the drivelabel. + - Changed file search routines a bit to be more compatible. + - Added support for attribute-searching with fcb's. + - Added basic SDA. + - Added TPA and DIB. + - Added Lot's of missing dos tables (c2woody). + - Changed psp and dta functions to use dta. + - Returned filename in ds:dx in create-random-file (c2woody). + - Fixed a bug with date and time used on open files. + - Some mscdex fixes. + - Added the -version switch, which makes dosbox report its version. + - Added a keymapper. + - Added basic IPX emulation. + - Added cdrom iso support and floppy images support. + - Added the possibity to boot another dos version. + - Added Serial passthrough support (win32 only). + - Added the possibility to pause dosbox. + - Changed OpenGL so that it is initialized only when used. + - Make dosbox run at higher priority when active and lower when inactive. + - Added direct draw output support (win32 only). + - Added current running program to title bar. + - Rewrote video emulation to support new scalers. + - Added new graphics scalers like advmame3x,tv2x. + - Added a support for a few anti-debugger tricks. + - Improved the handling of the tab-key. + - Improved support for the numeric keyboard. + - Fixed a few cpu opcodes. + - Added cpu core simple (for lowerend machines) + - Fixed some nasty bugs in the dynamic cpu core. + - Added a few (rarely used) fpu opcodes. + - Fixed various issues with GCC 3.4. + - Many internal timer improvements (PIT and PIC). + - Added some more PIC commands (c2woody). + - Added BCD counting to the timers. + - Fix some vesa functions. + - Add some basic support for 132x25 and 132x45 textmodes. + - Improved Tandy emulation a lot. + - Lowered cpu usage when dosbox is idle. + - Allow virtualisation of some basic IO-ports (c2woody). + 0.61 - Added a beta dynamic cpu for x86 hosts (very unstable) - Added opengl and hardware overlay display output From 55f41cb6781a5da87aac21b93ab6ce0efb66b32b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 2 Oct 2004 11:13:02 +0000 Subject: [PATCH 1926/4131] Made the : optional in subst. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2009 --- src/shell/shell_cmds.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 62217170..d4cdec41 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.47 2004-09-18 10:20:54 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.48 2004-10-02 11:13:02 qbix79 Exp $ */ #include #include @@ -619,7 +619,7 @@ void DOS_Shell::CMD_SUBST (char * args) { if((arg=="/D" ) || (arg=="/d")) throw 1; //No removal (one day) command.FindCommand(1,arg); - if(arg[1] !=':') throw(0); + if( (arg.size()>1) && arg[1] !=':') throw(0); temp_str[0]=toupper(args[0]); if(Drives[temp_str[0]-'A'] ) throw 0; //targetdrive in use strcat(mountstring,temp_str); From fec782775d91793781e9f726830694558add1322 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 2 Oct 2004 11:15:59 +0000 Subject: [PATCH 1927/4131] Fix from c2woody for the sdl issues under win32 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2010 --- src/gui/sdl_mapper.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 23a08484..a1fd01fe 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.7 2004-09-07 08:58:02 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.8 2004-10-02 11:15:59 qbix79 Exp $ */ #define OLD_JOYSTICK 1 @@ -1224,8 +1224,11 @@ void MAPPER_Run(void) { mousetoggle=true; GFX_CaptureMouse(); } - + + /* Be sure that there is no update in progress */ + if (sdl.updating) GFX_EndUpdate(); mapper.surface=SDL_SetVideoMode(640,480,8,0); + /* Set some palette entries */ SDL_SetPalette(mapper.surface, SDL_LOGPAL|SDL_PHYSPAL, map_pal, 0, 4); /* Go in the event loop */ From 9b9b4b3a514440f74c97d12a3847511f5d77d2e9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 2 Oct 2004 11:23:07 +0000 Subject: [PATCH 1928/4131] Whoops Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2011 --- src/gui/sdl_mapper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index a1fd01fe..af3f10d8 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.8 2004-10-02 11:15:59 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.9 2004-10-02 11:23:07 qbix79 Exp $ */ #define OLD_JOYSTICK 1 @@ -1226,7 +1226,7 @@ void MAPPER_Run(void) { } /* Be sure that there is no update in progress */ - if (sdl.updating) GFX_EndUpdate(); + GFX_EndUpdate(); mapper.surface=SDL_SetVideoMode(640,480,8,0); /* Set some palette entries */ From b052d69633128fd9e9f767df86e10674e060fc38 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 2 Oct 2004 11:31:47 +0000 Subject: [PATCH 1929/4131] Changed priority under linux. Only do it when as root or both priorties are the same. Set Priority on startup as well. Reversed scale and use it on all threads under non-w32. Moved SDL_Quit to another location to prevent some sdl exceptions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2012 --- src/gui/sdlmain.cpp | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 137f7306..fe478638 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.79 2004-09-29 19:14:10 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.80 2004-10-02 11:31:47 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -27,6 +27,7 @@ #include #include #include +#include #include "SDL.h" @@ -690,7 +691,6 @@ static void GUI_ShutDown(Section * sec) { GFX_Stop(); if (sdl.mouse.locked) CaptureMouse(); if (sdl.desktop.fullscreen) SwitchFullScreen(); - SDL_Quit(); //Becareful this should be removed if on the fly renderchanges are allowed } static void KillSwitch(void){ @@ -698,6 +698,15 @@ static void KillSwitch(void){ } static void SetPriority(PRIORITY_LEVELS level) { + +#if C_SET_PRIORITY +// Do nothing if priorties are not the same and not root, else the highest +// priority can not be set as users can only lower priority (not restore it) + + if((sdl.priority.focus != sdl.priority.nofocus ) && + (getuid()!=0) ) return; + +#endif switch (level) { #ifdef WIN32 case PRIORITY_LEVEL_LOWER: @@ -713,17 +722,18 @@ static void SetPriority(PRIORITY_LEVELS level) { SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS); break; #elif C_SET_PRIORITY +/* Linux use group as dosbox has mulitple threads under linux */ case PRIORITY_LEVEL_LOWER: - setpriority (PRIO_PROCESS, 0,PRIO_MIN+(PRIO_TOTAL/3)); + setpriority (PRIO_PGRP, 0,PRIO_MAX-(PRIO_TOTAL/3)); break; case PRIORITY_LEVEL_NORMAL: - setpriority (PRIO_PROCESS, 0,PRIO_MIN+(PRIO_TOTAL/2)); + setpriority (PRIO_PGRP, 0,PRIO_MAX-(PRIO_TOTAL/2)); break; case PRIORITY_LEVEL_HIGHER: - setpriority (PRIO_PROCESS, 0,PRIO_MIN+((3*PRIO_TOTAL)/5) ); + setpriority (PRIO_PGRP, 0,PRIO_MAX-((3*PRIO_TOTAL)/5) ); break; case PRIORITY_LEVEL_HIGHEST: - setpriority (PRIO_PROCESS, 0,PRIO_MIN+((3*PRIO_TOTAL)/4) ); + setpriority (PRIO_PGRP, 0,PRIO_MAX-((3*PRIO_TOTAL)/4) ); break; #endif default: @@ -771,6 +781,7 @@ static void GUI_StartUp(Section * sec) { sdl.priority.focus=PRIORITY_LEVEL_HIGHER; sdl.priority.nofocus=PRIORITY_LEVEL_NORMAL; } + SetPriority(sdl.priority.focus); //Assume focus on startup sdl.mouse.locked=false; mouselocked=false; //Global for mapper sdl.mouse.requestlock=false; @@ -1124,8 +1135,9 @@ int main(int argc, char* argv[]) { catch (int){ ;//nothing pressed killswitch } - catch(...){ - throw;//dunno what happened. rethrow for sdl to catch + catch(...){ + throw;//dunno what happened. rethrow for sdl to catch } + SDL_Quit();//Let's hope sdl will quit as well when it catches an exception return 0; }; From 363b366bca2ccfe12f23eb2dced97d97ae716187 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 3 Oct 2004 13:35:05 +0000 Subject: [PATCH 1930/4131] Fix drive label of z:\ sometimes now showing up Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2013 --- src/dos/drive_virtual.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 9a97833b..e12ad737 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -190,7 +190,7 @@ bool Virtual_Drive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) { Bit8u attr;char pattern[DOS_NAMELENGTH_ASCII]; dta.GetSearchParams(attr,pattern); if(attr & DOS_ATTR_VOLUME) { - dta.SetResult("DOSBOX",0,0,0,DOS_ATTR_ARCHIVE); + dta.SetResult("DOSBOX",0,0,0,DOS_ATTR_VOLUME); return true; } return FindNext(dta); From b23bd3a8efd4a09946ae869ad99ca5b0ef5a67bf Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 5 Oct 2004 19:45:27 +0000 Subject: [PATCH 1931/4131] Some warnings if buffer allocation fails Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2014 --- src/dos/dos_mscdex.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index c57c8a26..18e5780f 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.24 2004-08-13 19:43:02 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.25 2004-10-05 19:45:27 qbix79 Exp $ */ #include #include @@ -486,7 +486,7 @@ bool CMscdex::GetVolumeName(Bit8u subUnit, char* data) rtrim(data); }; DOS_FreeMemory(seg); - } + } else { LOG(LOG_MISC,LOG_ERROR)("MSCDEX buffer allocation failed."); }; return success; }; @@ -502,7 +502,7 @@ bool CMscdex::GetCopyrightName(Bit16u drive, PhysPt data) mem_writeb(data+37,0); }; DOS_FreeMemory(seg); - } + } else { LOG(LOG_MISC,LOG_ERROR)("MSCDEX buffer allocation failed."); }; return success; }; @@ -518,7 +518,7 @@ bool CMscdex::GetAbstractName(Bit16u drive, PhysPt data) mem_writeb(data+37,0); }; DOS_FreeMemory(seg); - } + } else { LOG(LOG_MISC,LOG_ERROR)("MSCDEX buffer allocation failed."); }; return success; }; @@ -534,7 +534,7 @@ bool CMscdex::GetDocumentationName(Bit16u drive, PhysPt data) mem_writeb(data+37,0); }; DOS_FreeMemory(seg); - } + } else { LOG(LOG_MISC,LOG_ERROR)("MSCDEX buffer allocation failed."); }; return success; }; From 4327579a14d694d156da7c8de6a4383f2d75be6e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 5 Oct 2004 19:50:03 +0000 Subject: [PATCH 1932/4131] remove trailing dot on labels. only update label on win32 on non-fixed drives Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2015 --- src/dos/drive_cache.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index c5d269fa..92afa5ca 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.38 2004-09-15 14:00:13 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.39 2004-10-05 19:50:03 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -125,6 +125,9 @@ void DOS_Drive_Cache::SetLabel(const char* vname) } }; label[labelPos]=0; + //Remove trailing dot. + if((labelPos > 0) && (label[labelPos-1] == '.')) + label[labelPos-1]=0; // LOG(LOG_ALL,LOG_ERROR)("CACHE: Set volume label to %s",label); }; @@ -145,10 +148,17 @@ void DOS_Drive_Cache::SetBaseDir(const char* baseDir) }; // Get Volume Label #if defined (WIN32) - char label[256]; + char labellocal[256]={ 0 }; char drive[4] = "C:\\"; drive[0] = basePath[0]; - if (GetVolumeInformation(drive,label,256,NULL,NULL,NULL,NULL,0)) SetLabel(label); + UINT type_drive=GetDriveType(drive); + if(type_drive != DRIVE_FIXED) { + //Only add label for non-fixed drives. (so stuff like "mount c c:\piet -t cdrom -label piet" works) + if (GetVolumeInformation(drive,labellocal,256,NULL,NULL,NULL,NULL,0)) { + LOG(LOG_MISC,LOG_NORMAL)("Cache: setting label for (non-fixed localdrive) to %s",labellocal); + SetLabel(labellocal); + } + } #endif }; From 62ad4ff47575865e9b1d311bf51af642439e4894 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 5 Oct 2004 19:55:03 +0000 Subject: [PATCH 1933/4131] Made it gcc2.95 friendly. Fix drivelabels on iso's. Fix Various stability issues with images Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2016 --- src/dos/cdrom.h | 3 +++ src/dos/cdrom_image.cpp | 6 +++--- src/dos/drive_iso.cpp | 35 +++++++++++++++++++++++++++++++---- src/dos/drives.h | 4 ++-- 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index c4382092..173a9c24 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -5,8 +5,11 @@ #define MAX_ASPI_CDROM 5 #include +#include #include #include +#include +#include #include "dosbox.h" #include "mem.h" #include "mixer.h" diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index ad6686e2..e14357c3 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -16,14 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.3 2004-08-23 09:35:15 harekiet Exp $ */ +/* $Id: cdrom_image.cpp,v 1.4 2004-10-05 19:55:03 qbix79 Exp $ */ #include #include #include #include #include -#include +#include #include #include #include @@ -572,7 +572,7 @@ bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) if (stat(filename.c_str(), &test) == 0) return true; // check if file with path relative to cue file exists -#if not defined(WIN32) +#ifndef WIN32 string tmpstr(pathname + "/" + filename); if (stat(tmpstr.c_str(), &test) == 0) { filename = tmpstr; diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index d58ec954..0127ec7c 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.1 2004-08-13 19:43:02 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.2 2004-10-05 19:55:03 qbix79 Exp $ */ #include #include @@ -152,7 +152,29 @@ isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &e searchCache.clear(); dirIter = searchCache.end(); this->mediaid = mediaid; - if (!MSCDEX_GetVolumeName(subUnit, discLabel)) strcpy(discLabel, ""); + char buffer[32] = { 0 }; + if (!MSCDEX_GetVolumeName(subUnit, buffer)) strcpy(buffer, ""); + + //Code Copied from drive_cache. (convert mscdex label to a dos 8.3 file) + Bitu togo = 8; + Bitu bufPos = 0; + Bitu labelPos = 0; + bool point = false; + while (togo>0) { + if (buffer[bufPos]==0) break; + if (!point && (buffer[bufPos]=='.')) { togo=4; point=true; } + discLabel[labelPos] = toupper(buffer[bufPos]); + labelPos++; bufPos++; + togo--; + if ((togo==0) && !point) { + if (buffer[bufPos]=='.') bufPos++; + discLabel[labelPos]='.'; labelPos++; point=true; togo=3; + } + }; + discLabel[labelPos]=0; + //Remove trailing dot. + if((labelPos > 0) && (discLabel[labelPos - 1] == '.')) + discLabel[labelPos - 1] = 0; } else error = 6; } } @@ -229,7 +251,7 @@ bool isoDrive::FindFirst(char *dir, DOS_DTA &dta, bool fcb_findfirst) readSector(block, sector); Bit32u pos = 0; - while (pos < ISO_FRAMESIZE && block[pos] != 0) { + while (block[pos] != 0 && (pos + block[pos]) < ISO_FRAMESIZE) { isoDirEntry tmp; int length = readDirEntry(&tmp, &block[pos]); if (length < 0) return false; @@ -353,6 +375,7 @@ inline bool isoDrive :: readSector(Bit8u *buffer, Bit32u sector) int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) { // copy data into isoDirEntry struct, data[0] = length of DirEntry + if (data[0] > sizeof(isoDirEntry)) return -1; memcpy(de, data, data[0]); // xa not supported @@ -361,6 +384,7 @@ int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) if (de->fileUnitSize != 0 || de->interleaveGapSize != 0) return -1; // modify file identifier for use with dosbox + if ((de->length < 33 + de->fileIdentLength)) return -1; if (IS_DIR(de->fileFlags)) { if (de->fileIdentLength == 1 && de->ident[0] == 0) strcpy((char*)de->ident, "."); else if (de->fileIdentLength == 1 && de->ident[0] == 1) strcpy((char*)de->ident, ".."); @@ -375,6 +399,7 @@ int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) strreplace((char*)de->ident, ';', 0); // if file has no extension remove the trailing dot int tmp = strlen((char*)de->ident); +//if (tmp > 38) return -1; //de->ident can hold 100 if (tmp > 0 && de->ident[tmp - 1] == '.') de->ident[tmp - 1] = 0; } return de->length; @@ -398,7 +423,7 @@ bool isoDrive :: lookupSingle(isoDirEntry *de, const char *name, Bit32u start, B if (!readSector(sector, i)) return false; int pos = 0; - while (sector[pos] != 0 && pos < ISO_FRAMESIZE) { + while (sector[pos] != 0 && (pos + sector[pos]) < ISO_FRAMESIZE) { int deLength = readDirEntry(de, §or[pos]); if (deLength < 1) return false; pos += deLength; @@ -423,6 +448,8 @@ bool isoDrive :: lookup(isoDirEntry *de, const char *path) while (isoPath[pos] != 0) { if (isoPath[pos] == '/') { char name[38]; + if (pos - beginPos >= 38) return false; + if (beginPos >= ISO_MAXPATHNAME) return false; strncpy(name, &isoPath[beginPos], pos - beginPos); name[pos - beginPos] = 0; beginPos = pos + 1; diff --git a/src/dos/drives.h b/src/dos/drives.h index ecde6b4e..e5de809f 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.23 2004-08-13 19:43:02 qbix79 Exp $ */ +/* $Id: drives.h,v 1.24 2004-10-05 19:55:03 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ @@ -254,7 +254,7 @@ struct isoDirEntry { Bit16u VolumeSeqNumberL; Bit16u VolumeSeqNumberM; Bit8u fileIdentLength; - Bit8u ident[38]; // can be smaller + Bit8u ident[100]; } GCC_ATTRIBUTE(packed); #ifdef _MSC_VER From c291c67f5c86d890707752eab37bed29723f7640 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 5 Oct 2004 21:18:48 +0000 Subject: [PATCH 1934/4131] more changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2017 --- src/dos/drive_iso.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 0127ec7c..fb62e694 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.2 2004-10-05 19:55:03 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.3 2004-10-05 21:18:48 qbix79 Exp $ */ #include #include @@ -250,8 +250,8 @@ bool isoDrive::FindFirst(char *dir, DOS_DTA &dta, bool fcb_findfirst) Bit8u block[ISO_FRAMESIZE]; readSector(block, sector); - Bit32u pos = 0; - while (block[pos] != 0 && (pos + block[pos]) < ISO_FRAMESIZE) { + Bit32u pos = 0; + while (pos < ISO_FRAMESIZE && block[pos] != 0 && (pos + block[pos]) <= ISO_FRAMESIZE) { isoDirEntry tmp; int length = readDirEntry(&tmp, &block[pos]); if (length < 0) return false; @@ -399,7 +399,6 @@ int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) strreplace((char*)de->ident, ';', 0); // if file has no extension remove the trailing dot int tmp = strlen((char*)de->ident); -//if (tmp > 38) return -1; //de->ident can hold 100 if (tmp > 0 && de->ident[tmp - 1] == '.') de->ident[tmp - 1] = 0; } return de->length; @@ -423,7 +422,7 @@ bool isoDrive :: lookupSingle(isoDirEntry *de, const char *name, Bit32u start, B if (!readSector(sector, i)) return false; int pos = 0; - while (sector[pos] != 0 && (pos + sector[pos]) < ISO_FRAMESIZE) { + while (pos < ISO_FRAMESIZE && sector[pos] != 0 && (pos + sector[pos]) <= ISO_FRAMESIZE) { int deLength = readDirEntry(de, §or[pos]); if (deLength < 1) return false; pos += deLength; From 608ab6edc7ef837def7df7098ea64752a37eeafe Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 9 Oct 2004 08:41:21 +0000 Subject: [PATCH 1935/4131] Allow changing of the timeconstant during autoinit transfers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2018 --- src/hardware/sblaster.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index a89972e4..319f2b95 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -616,7 +616,7 @@ Bitu DEBUG_EnableDebugger(void); static void DSP_DoCommand(void) { // LOG_MSG("DSP Command %X",sb.dsp.cmd); switch (sb.dsp.cmd) { - case 0x04: /* DSP Statues SB 2.0/pro version */ + case 0x04: /* DSP Status SB 2.0/pro version */ DSP_FlushData(); DSP_AddData(0xff); //Everthing enabled break; @@ -642,6 +642,10 @@ static void DSP_DoCommand(void) { break; case 0x40: /* Set Timeconstant */ sb.freq=(1000000 / (256 - sb.dsp.in.data[0])); + /* Nasty kind of hack to allow runtime changing of frequency */ + if (sb.dma.mode != DSP_DMA_NONE && sb.dma.autoinit) { + DSP_PrepareDMA_Old(sb.dma.mode,sb.dma.autoinit); + } break; case 0x41: /* Set Output Samplerate */ case 0x42: /* Set Input Samplerate */ From 7c32c974c7c0f8b9bbfa4076a67e84c043485f55 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 12 Oct 2004 09:42:25 +0000 Subject: [PATCH 1936/4131] work around some drive_cache corruption in find Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2019 --- src/dos/drive_local.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index f4fa8b93..2b216eed 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.51 2004-08-13 19:43:02 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.52 2004-10-12 09:42:25 qbix79 Exp $ */ #include #include @@ -181,6 +181,7 @@ bool localDrive::FindNext(DOS_DTA & dta) { char * dir_ent; struct stat stat_block; char full_name[CROSS_LEN]; + char dir_entcopy[CROSS_LEN]; Bit8u srch_attr;char srch_pattern[DOS_NAMELENGTH_ASCII]; Bit8u find_attr; @@ -199,8 +200,13 @@ again: strcpy(full_name,srchInfo[id].srch_dir); strcat(full_name,dir_ent); - if (stat(dirCache.GetExpandName(full_name),&stat_block)!=0) { - goto again; + + //GetExpandName might indirectly destroy dir_ent (by caching in a new directory + //and due to its design dir_ent might be lost.) + //Copying dir_ent first + strcpy(dir_entcopy,dir_ent); + if (stat(dirCache.GetExpandName(full_name),&stat_block)!=0) { + goto again;//No symlinks and such } if(S_ISDIR(stat_block.st_mode)) find_attr=DOS_ATTR_DIRECTORY; @@ -214,20 +220,20 @@ again: /*file is okay, setup everything to be copied in DTA Block */ char find_name[DOS_NAMELENGTH_ASCII];Bit16u find_date,find_time;Bit32u find_size; - if(strlen(dir_ent)tm_year+1900,time->tm_mon+1,time->tm_mday); find_time=DOS_PackTime(time->tm_hour,time->tm_min,time->tm_sec); - }else { - find_time=6; - find_date=4; - } + } else { + find_time=6; + find_date=4; + } dta.SetResult(find_name,find_size,find_date,find_time,find_attr); return true; } From 93a8163a4d56dc18ce7829780b510aec62eb2a37 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 12 Oct 2004 10:45:11 +0000 Subject: [PATCH 1937/4131] New call to reset page handlers Change the vga font text page handler and rewrite for reset page handler call. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2020 --- include/paging.h | 5 ++-- src/hardware/memory.cpp | 7 ++++++ src/hardware/vga_memory.cpp | 48 +++++++++++++------------------------ 3 files changed, 27 insertions(+), 33 deletions(-) diff --git a/include/paging.h b/include/paging.h index b33df8e6..1366babb 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.11 2004-09-07 18:21:51 qbix79 Exp $ */ +/* $Id: paging.h,v 1.12 2004-10-12 10:45:10 harekiet Exp $ */ #ifndef _PAGING_H_ #define _PAGING_H_ @@ -42,7 +42,6 @@ class PageDirectory; //Allow 128 mb of memory to be linked #define PAGING_LINKS (128*1024/4) - class PageHandler { public: virtual Bitu readb(PhysPt addr); @@ -72,6 +71,8 @@ bool PAGING_MakePhysPage(Bitu & page); void MEM_SetLFB(Bitu _page,Bitu _pages,HostPt _pt); void MEM_SetPageHandler(Bitu phys_page,Bitu pages,PageHandler * handler); +void MEM_ResetPageHandler(Bitu phys_page, Bitu pages); + #ifdef _MSC_VER #pragma pack (1) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 69f86660..a4e206c9 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -141,6 +141,13 @@ void MEM_SetPageHandler(Bitu phys_page,Bitu pages,PageHandler * handler) { } } +void MEM_ResetPageHandler(Bitu phys_page, Bitu pages) { + for (;pages>0;pages--) { + memory.phandlers[phys_page]=&ram_page_handler; + phys_page++; + } +} + Bitu mem_strlen(PhysPt pt) { Bitu x=0; while (x<1024) { diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 0d67a8ae..490297f8 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -15,9 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - - #include #include @@ -135,8 +132,7 @@ static void VGA_GFX_256U_WriteHandler(PhysPt start,Bit8u val) { #define VGA_PAGE_B8 (0xB8000/4096) static struct { - Bit8u ram_area[VGA_PAGES*4096]; - Bitu map_base; + Bitu base,mask; } vgapages; class VGARead_PageHandler : public PageHandler { @@ -213,37 +209,24 @@ public: flags=PFLAG_NOCODE; } Bitu readb(PhysPt addr) { - addr&=0xffff; + addr&=vgapages.mask; return vga.draw.font[addr]; } void writeb(PhysPt addr,Bitu val){ - addr&=0xffff; + addr&=vgapages.mask; if (vga.seq.map_mask & 0x4) { vga.draw.font[addr]=(Bit8u)val; } } }; - -class VGA_RAM_PageHandler : public PageHandler { -public: - VGA_RAM_PageHandler() { - flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; - } - HostPt GetHostPt(Bitu phys_page) { - phys_page-=VGA_PAGE_A0; - return &vgapages.ram_area[phys_page*4096]; - } -}; - - class VGA_MAP_PageHandler : public PageHandler { public: VGA_MAP_PageHandler() { flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; } HostPt GetHostPt(Bitu phys_page) { - phys_page-=vgapages.map_base; + phys_page-=vgapages.base; return &vga.mem.linear[vga.s3.bank*64*1024+phys_page*4096]; } }; @@ -327,7 +310,6 @@ public: static struct vg { - VGA_RAM_PageHandler hram; VGA_MAP_PageHandler hmap; VGA_TEXT_PageHandler htext; VGA_TANDY_PageHandler htandy; @@ -380,27 +362,31 @@ void VGA_SetupHandlers(void) { } switch ((vga.gfx.miscellaneous >> 2) & 3) { case 0: - vgapages.map_base=VGA_PAGE_A0; + vgapages.base=VGA_PAGE_A0; + vgapages.mask=0x1ffff; MEM_SetPageHandler(VGA_PAGE_A0,32,range_handler); break; case 1: - vgapages.map_base=VGA_PAGE_A0; + vgapages.base=VGA_PAGE_A0; + vgapages.mask=0xffff; MEM_SetPageHandler(VGA_PAGE_A0,16,range_handler); - MEM_SetPageHandler(VGA_PAGE_B0,16,&vgaph.hram); + MEM_ResetPageHandler(VGA_PAGE_B0,16); break; case 2: range_b000: - vgapages.map_base=VGA_PAGE_B0; + vgapages.base=VGA_PAGE_B0; + vgapages.mask=0x7fff; MEM_SetPageHandler(VGA_PAGE_B0,8,range_handler); - MEM_SetPageHandler(VGA_PAGE_A0,16,&vgaph.hram); - MEM_SetPageHandler(VGA_PAGE_B8,8,&vgaph.hram); + MEM_ResetPageHandler(VGA_PAGE_A0,16); + MEM_ResetPageHandler(VGA_PAGE_B8,8); break; case 3: range_b800: - vgapages.map_base=VGA_PAGE_B8; + vgapages.base=VGA_PAGE_B8; + vgapages.mask=0x7fff; MEM_SetPageHandler(VGA_PAGE_B8,8,range_handler); - MEM_SetPageHandler(VGA_PAGE_A0,16,&vgaph.hram); - MEM_SetPageHandler(VGA_PAGE_B0,8,&vgaph.hram); + MEM_ResetPageHandler(VGA_PAGE_A0,16); + MEM_ResetPageHandler(VGA_PAGE_B0,8); break; } From b00484d130552c871cde1ccb60bfa794502444d0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 12 Oct 2004 16:19:45 +0000 Subject: [PATCH 1938/4131] basic FXTRACT support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2021 --- src/fpu/fpu.cpp | 5 ++++- src/fpu/fpu_instructions.h | 13 ++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index bce87f7e..0d5d154f 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu.cpp,v 1.22 2004-09-08 08:46:37 qbix79 Exp $ */ +/* $Id: fpu.cpp,v 1.23 2004-10-12 16:19:45 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU @@ -354,6 +354,9 @@ void FPU_ESC1_Normal(Bitu rm) { case 0x03: /* FPATAN */ FPU_FPATAN(); break; + case 0x04: /* FXTRACT */ + FPU_FXTRACT(); + break; default: LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); break; diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index ff7dc091..a810cebd 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.21 2004-09-09 18:36:50 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.22 2004-10-12 16:19:45 qbix79 Exp $ */ static void FPU_FINIT(void) { @@ -392,3 +392,14 @@ static void FPU_FSTOR(PhysPt addr){ } } +static void FPU_FXTRACT(void) { + // function stores real bias in st and + // pushes the significant number onto the stack + // if double ever uses a different base please correct this function + + FPU_Reg test = fpu.regs[TOP]; + Bit64s exp80 = test.ll&LONGTYPE(0x7ff0000000000000); + Bit64s exp80final = (exp80>>52) - BIAS64; + Real64 mant = test.d / (pow(2.0,static_cast(exp80final))); + FPU_PUSH(mant); +} From bb2d24b0811c66872999ad0c6e84d2b1db3f4819 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 12 Oct 2004 16:21:22 +0000 Subject: [PATCH 1939/4131] small keyboard fix. typerate handling (Moe) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2022 --- src/hardware/keyboard.cpp | 17 ++++++++++++++--- src/ints/bios_keyboard.cpp | 12 ++++++++++-- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 203d8bca..9ebbfeae 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.28 2004-09-10 22:15:20 harekiet Exp $ */ +/* $Id: keyboard.cpp,v 1.29 2004-10-12 16:21:22 qbix79 Exp $ */ #include #include @@ -136,7 +136,7 @@ static void write_p60(Bitu port,Bitu val,Bitu iolen) { break; case 0xf5: /* Reset keyboard and disable scanning */ LOG(LOG_KEYBOARD,LOG_NORMAL)("Reset, disable scanning"); - keyb.scanning=false; + keyb.scanning=false; KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ break; case 0xf6: /* Reset keyboard and enable scanning */ @@ -153,7 +153,18 @@ static void write_p60(Bitu port,Bitu val,Bitu iolen) { case CMD_SETOUTPORT: MEM_A20_Enable((val & 2)>0); break; - case CMD_SETTYPERATE: + case CMD_SETTYPERATE: + { + static const int delay[] = { 250, 500, 750, 1000 }; + static const int repeat[] = + { 33,37,42,46,50,54,58,63,67,75,83,92,100, + 109,118,125,133,149,167,182,200,217,233, + 250,270,303,333,370,400,435,476,500 }; + keyb.repeat.pause = delay[(val>>5)&3]; + keyb.repeat.rate = repeat[val&0x1f]; + keyb.command=CMD_NONE; + } + /* Fallthrough! as setleds does what we want */ case CMD_SETLEDS: keyb.command=CMD_NONE; KEYBOARD_ClrBuffer(); diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 581adcfd..8e30c843 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -400,11 +400,19 @@ static Bitu INT16_Handler(void) { reg_al=mem_readb(BIOS_KEYBOARD_FLAGS1); break; case 0x03: /* SET TYPEMATIC RATE AND DELAY */ - LOG(LOG_BIOS,LOG_ERROR)("INT16:Unhandled Typematic Rate Call %2X BX=%X",reg_al,reg_bx); + if (reg_al == 0x00) { // set default delay and rate + IO_Write(0x60,0xf3); + IO_Write(0x60,0x20); // 500 msec delay, 30 cps + } else if (reg_al == 0x05) { // set repeat rate and delay + IO_Write(0x60,0xf3); + IO_Write(0x60,(reg_bh&3)<<5|(reg_bl&0x1f)); + } else { + LOG(LOG_BIOS,LOG_ERROR)("INT16:Unhandled Typematic Rate Call %2X BX=%X",reg_al,reg_bx); + } break; case 0x05: /* STORE KEYSTROKE IN KEYBOARD BUFFER */ //TODO make add_key bool :) - add_key(reg_ax); + add_key(reg_cx); reg_al=0; break; case 0x12: /* GET EXTENDED SHIFT STATES */ From 82001bc86e6c5ff19f1770a1f784dc872185bef8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 12 Oct 2004 20:14:38 +0000 Subject: [PATCH 1940/4131] forgot one register Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2023 --- src/fpu/fpu_instructions.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index a810cebd..03b9bafc 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.22 2004-10-12 16:19:45 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.23 2004-10-12 20:14:38 qbix79 Exp $ */ static void FPU_FINIT(void) { @@ -401,5 +401,6 @@ static void FPU_FXTRACT(void) { Bit64s exp80 = test.ll&LONGTYPE(0x7ff0000000000000); Bit64s exp80final = (exp80>>52) - BIAS64; Real64 mant = test.d / (pow(2.0,static_cast(exp80final))); + fpu.regs[TOP].d=exp80final; FPU_PUSH(mant); } From 3ee0cef43d0f72da25178e19ef780dff29ed87ab Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 13 Oct 2004 19:26:26 +0000 Subject: [PATCH 1941/4131] Tiny bug in the storing 80 bit reals Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2024 --- src/fpu/fpu_instructions.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 03b9bafc..539f3b10 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.23 2004-10-12 20:14:38 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.24 2004-10-13 19:26:26 qbix79 Exp $ */ static void FPU_FINIT(void) { @@ -321,7 +321,7 @@ static void FPU_ST80(PhysPt addr,Bitu reg) Bit64s exp80 = fpu.regs[reg].ll&LONGTYPE(0x7ff0000000000000); Bit64s exp80final= (exp80>>52) - BIAS64 + BIAS80; Bit64s mant80 = fpu.regs[reg].ll&LONGTYPE(0x000fffffffffffff); - Bit64s mant80final= (mant80 << 11) | LONGTYPE(0x8000000000000000); + Bit64s mant80final= (mant80 << 11); test.begin= (static_cast(sign80)<<15)| static_cast(exp80final); test.eind.ll=mant80final; mem_writed(addr,test.eind.l.lower); From 3602a06de90aca788633f7028f660fc5cedbf47b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 17 Oct 2004 14:45:00 +0000 Subject: [PATCH 1942/4131] Rewrote devices so they can be opened/closed/cloned. Fix Turbo pascal 7 saving bug(wd/mirek). Increase number of files to 127. Remove null device from default handles. Proper creation of the initial psp. (not hacked anymore). Quite some files= bugs should be fixed Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2025 --- include/dos_inc.h | 17 +++++--- include/dos_system.h | 21 +++++++-- src/dos/dev_con.h | 6 +-- src/dos/dos_classes.cpp | 4 +- src/dos/dos_devices.cpp | 96 +++++++++++++++++++++++++++++++---------- src/dos/dos_files.cpp | 92 ++++++++++++++++++++------------------- src/dos/dos_mscdex.cpp | 4 +- src/ints/ems.cpp | 4 +- src/shell/shell.cpp | 15 ++++--- 9 files changed, 165 insertions(+), 94 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index a634119d..6f3bb3a5 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.48 2004-08-04 09:12:50 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.49 2004-10-17 14:44:59 qbix79 Exp $ */ #ifndef DOS_H_ #define DOS_H_ @@ -68,13 +68,16 @@ union bootSector { enum { MCB_FREE=0x0000,MCB_DOS=0x0008 }; enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; -#define DOS_FILES 50 +#define DOS_FILES 127 #define DOS_DRIVES 26 +#define DOS_DEVICES 10 /* internal Dos Tables */ extern DOS_File * Files[DOS_FILES]; extern DOS_Drive * Drives[DOS_DRIVES]; +extern DOS_Device * Devices[DOS_DEVICES]; + extern Bit8u dos_copybuf[0x10000]; @@ -82,7 +85,7 @@ void DOS_SetError(Bit16u code); /* File Handling Routines */ -enum { STDIN=0,STDOUT=1,STDERR=2,STDAUX=3,STDNUL=4,STDPRN=5}; +enum { STDIN=0,STDOUT=1,STDERR=2,STDAUX=3,STDPRN=4}; enum { HAND_NONE=0,HAND_FILE,HAND_DEVICE}; /* Routines for File Class */ @@ -285,10 +288,10 @@ private: 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 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 */ diff --git a/include/dos_system.h b/include/dos_system.h index 1f273b8b..7cb770df 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.24 2004-08-04 09:12:50 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.25 2004-10-17 14:44:59 qbix79 Exp $ */ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ @@ -54,6 +54,8 @@ class DOS_DTA; class DOS_File { public: DOS_File():flags(0) { name=0; refCtr = 0; }; + 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 Write(Bit8u * data,Bit16u * size)=0; @@ -81,9 +83,20 @@ public: class DOS_Device : public DOS_File { public: -/* Some Device Specific Stuff */ - char * name; - Bit8u fhandle; + DOS_Device(const DOS_Device& orig):DOS_File(orig) {devnum=orig.devnum; } + DOS_Device & operator= (const DOS_Device & orig) { + DOS_File::operator=(orig); + devnum=orig.devnum; + } + 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); + void SetDeviceNumber(Bitu num) { devnum=num;} +private: + Bitu devnum; }; #define MAX_OPENDIRS 2048 diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 8f2f9604..6a2bdd0b 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.18 2004-08-26 19:41:20 qbix79 Exp $ */ +/* $Id: dev_con.h,v 1.19 2004-10-17 14:45:00 qbix79 Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" @@ -345,7 +345,7 @@ bool device_CON::Seek(Bit32u * pos,Bit32u type) { } bool device_CON::Close() { - return false; + return true; } Bit16u device_CON::GetInformation(void) { @@ -357,7 +357,7 @@ Bit16u device_CON::GetInformation(void) { }; device_CON::device_CON() { - name="CON"; + SetName("CON"); cache=0; ansi.enabled=false; ansi.attr=0x7; diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 8fd40fbb..14ba6ef7 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.41 2004-08-04 09:12:53 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.42 2004-10-17 14:45:00 qbix79 Exp $ */ #include #include @@ -225,7 +225,7 @@ void DOS_PSP::CopyFileTable(DOS_PSP* srcpsp,bool createchildpsp) Bit8u handle = srcpsp->GetFileHandle(i); if(createchildpsp) { //copy obeying not inherit flag.(but dont duplicate them) - bool allowCopy = (handle==0) || ((handle>0) && (FindEntryByHandle(handle)==0xff)); + bool allowCopy = true;//(handle==0) || ((handle>0) && (FindEntryByHandle(handle)==0xff)); if((handleflags & DOS_NOT_INHERIT) && allowCopy) { Files[handle]->AddRef(); diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index a9dad893..d6eb1128 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: dos_devices.cpp,v 1.6 2004-10-17 14:45:00 qbix79 Exp $ */ + #include #include "dosbox.h" #include "callback.h" @@ -24,19 +26,18 @@ #include "bios.h" #include "dos_inc.h" #include "support.h" - -#define MAX_DEVICES 10 +#include "drives.h" //Wildcmp /* Include all the devices */ #include "dev_con.h" -static DOS_Device * devices[MAX_DEVICES]; -static Bit32u device_count; +DOS_Device * Devices[DOS_DEVICES]; +static Bitu device_count; class device_NUL : public DOS_Device { public: - device_NUL() { name="NUL"; }; + device_NUL() { SetName("NUL"); }; bool Read(Bit8u * data,Bit16u * size) { for(Bitu i = 0; i < *size;i++) data[i]=0; @@ -52,38 +53,87 @@ public: return true; } bool Close() { return true; } - Bit16u GetInformation(void) { return 0x8004; } + Bit16u GetInformation(void) { return 0x8084; } }; +bool DOS_Device::Read(Bit8u * data,Bit16u * size) { + return Devices[devnum]->Read(data,size); +} + +bool DOS_Device::Write(Bit8u * data,Bit16u * size) { + return Devices[devnum]->Write(data,size); +} + +bool DOS_Device::Seek(Bit32u * pos,Bit32u type) { + return Devices[devnum]->Seek(pos,type); +} + +bool DOS_Device::Close() { + return Devices[devnum]->Close(); +} + +Bit16u DOS_Device::GetInformation(void) { + return Devices[devnum]->GetInformation(); +} + +DOS_File::DOS_File(const DOS_File& orig) { + type=orig.type; + flags=orig.flags; + time=orig.time; + date=orig.date; + attr=orig.attr; + size=orig.size; + refCtr=orig.refCtr; + open=orig.open; + name=0; + if(orig.name) { + name=new char [strlen(orig.name)];strcpy(name,orig.name); + } +} + +DOS_File & DOS_File::operator= (const DOS_File & orig) { + type=orig.type; + flags=orig.flags; + time=orig.time; + date=orig.date; + attr=orig.attr; + size=orig.size; + refCtr=orig.refCtr; + open=orig.open; + if(name) { + delete [] name; name=0; + } + if(orig.name) { + name=new char [strlen(orig.name)];strcpy(name,orig.name); + } +} + Bit8u DOS_FindDevice(char * name) { + /* should only check for the names before the dot and spacepadded */ + char temp[CROSS_LEN];//TODOD + if(!(*name)) return DOS_DEVICES; + strcpy(temp,name); + char* dot= strrchr(temp,'.'); + if(dot && *dot) dot=0; //no ext checking + /* loop through devices */ Bit8u index=0; while (indexname)==0) return index; + if (Devices[index]) { + if (WildFileCmp(temp,Devices[index]->name)) return index; } index++; } - return 255; + return DOS_DEVICES; } void DOS_AddDevice(DOS_Device * adddev) { //TODO Give the Device a real handler in low memory that responds to calls - if (device_countSetDeviceNumber(device_count); device_count++; - /* Add the device in the main file Table */ - Bit8u handle=DOS_FILES;Bit8u i; - for (i=0;ifhandle=handle; } else { E_Exit("DOS:Too many devices added"); } @@ -94,7 +144,7 @@ void DOS_SetupDevices(void) { DOS_Device * newdev; newdev=new device_CON(); DOS_AddDevice(newdev); - DOS_Device * newdev2; + DOS_Device * newdev2; newdev2=new device_NUL(); DOS_AddDevice(newdev2); } diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 6bff5047..65953a70 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.57 2004-08-04 09:12:53 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.58 2004-10-17 14:45:00 qbix79 Exp $ */ #include #include @@ -57,7 +57,7 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } - + char tempdir[DOS_PATHLENGTH]; char upname[DOS_PATHLENGTH]; Bitu r,w; @@ -232,7 +232,12 @@ bool DOS_FindFirst(char * search,Bit16u attr,bool fcb_findfirst) { *find_last=0; strcpy(pattern,find_last+1); strcpy(dir,fullsearch); - } + } +//check for devices. first part of filename before the dot +//can be the name of a device. like con.1 +//if(findDevice(pattern) blah blah +// but leading subdirs must exist.... +// dta.SetupSearch(drive,(Bit8u)attr,pattern); if (Drives[drive]->FindFirst(dir,dta,fcb_findfirst)) return true; @@ -315,15 +320,12 @@ bool DOS_CloseFile(Bit16u entry) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; - /* Devices won't allow themselves to be closed or killed */ - if (Files[handle]->Close()) - { //if close succesfull => delete file/update psp - DOS_PSP psp(dos.psp()); - psp.SetFileHandle(entry,0xff); - if (Files[handle]->RemoveRef()<=0) { - delete Files[handle]; - Files[handle]=0; - } + Files[handle]->Close(); + DOS_PSP psp(dos.psp()); + psp.SetFileHandle(entry,0xff); + if (Files[handle]->RemoveRef()<=0) { + delete Files[handle]; + Files[handle]=0; } return true; } @@ -331,7 +333,7 @@ bool DOS_CloseFile(Bit16u entry) { bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { // Creation of a device is the same as opening it // Tc201 installer - if (DOS_FindDevice(name) != 255) + if (DOS_FindDevice(name) != DOS_DEVICES) return DOS_OpenFile(name, 0, entry); char fullname[DOS_PATHLENGTH];Bit8u drive; @@ -370,7 +372,7 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { if (flags>2) LOG(LOG_FILES,LOG_ERROR)("Special file open command %X file %s",flags,name); else LOG(LOG_FILES,LOG_NORMAL)("file open command %X file %s",flags,name); - Bit16u attr; + Bit16u attr = 0; if(DOS_GetFileAttr(name,&attr)){ //DON'T ALLOW directories to be openened if((attr & DOS_ATTR_DIRECTORY) || (attr & DOS_ATTR_VOLUME)){ DOS_SetError(DOSERR_ACCESS_DENIED); @@ -379,40 +381,39 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { } DOS_PSP psp(dos.psp()); - Bit8u handle=DOS_FindDevice((char *)name); - bool device=false;char fullname[DOS_PATHLENGTH];Bit8u drive;Bit8u i; - if (handle!=255) { - device=true; - } else { + Bit8u devnum=DOS_DEVICES; + devnum=DOS_FindDevice((char *)name); + bool device=(devnum!=DOS_DEVICES); + char fullname[DOS_PATHLENGTH];Bit8u drive;Bit8u i; + /* First check if the name is correct */ - if (!DOS_MakeName(name,fullname,&drive)) return false; - - /* Check for a free file handle */ - for (i=0;iFileOpen(&Files[handle],fullname,flags); + if (device) { + Files[handle]=new DOS_Device(*Devices[devnum]); + } else { + exists=Drives[drive]->FileOpen(&Files[handle],fullname,flags); + } if (exists || device ) { - // devices can only be opened once - if (device && (psp.FindEntryByHandle(handle)!=0xff)) { - *entry=psp.FindEntryByHandle(handle); - return true; - } Files[handle]->AddRef(); psp.SetFileHandle(*entry,handle); return true; @@ -451,7 +452,12 @@ bool DOS_OpenFileExtended(char *name, Bit16u flags, Bit16u createAttr, Bit16u ac bool DOS_UnlinkFile(char * name) { char fullname[DOS_PATHLENGTH];Bit8u drive; if (!DOS_MakeName(name,fullname,&drive)) return false; - return Drives[drive]->FileUnlink(fullname); + if(Drives[drive]->FileUnlink(fullname)){ + return true; + } else { + DOS_SetError(DOSERR_FILE_NOT_FOUND); + return false; + } } bool DOS_GetFileAttr(char * name,Bit16u * attr) { @@ -503,13 +509,12 @@ bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit8u * sectors,Bit16u * cl } bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry) { - // Dont duplicate console handles - if (entry<=STDPRN) { +/* if (entry<=STDPRN) { *newentry = entry; return true; }; - +*/ Bit8u handle=RealHandle(entry); if (handle>=DOS_FILES) { DOS_SetError(DOSERR_INVALID_HANDLE); @@ -531,13 +536,12 @@ bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry) { }; bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry) { - // Dont duplicate console handles - if (entry<=STDPRN) { +/* if (entry<=STDPRN) { newentry = entry; return true; }; - +*/ Bit8u orig=RealHandle(entry); if (orig>=DOS_FILES) { DOS_SetError(DOSERR_INVALID_HANDLE); diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 18e5780f..217f96d8 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.25 2004-10-05 19:45:27 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.26 2004-10-17 14:45:00 qbix79 Exp $ */ #include #include @@ -1005,7 +1005,7 @@ static bool MSCDEX_Handler(void) class device_MSCDEX : public DOS_Device { public: - device_MSCDEX() { name="MSCD001"; } + device_MSCDEX() { SetName("MSCD001"); } bool Read (Bit8u * data,Bit16u * size) { return false;} bool Write(Bit8u * data,Bit16u * size) { LOG(LOG_ALL,LOG_NORMAL)("Write to mscdex device"); diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 6ce72413..c0faac71 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.34 2004-08-04 09:12:56 qbix79 Exp $ */ +/* $Id: ems.cpp,v 1.35 2004-10-17 14:45:00 qbix79 Exp $ */ #include #include @@ -65,7 +65,7 @@ class device_EMM : public DOS_Device { public: - device_EMM(){name="EMMXXXX0";} + device_EMM(){SetName("EMMXXXX0");} bool Read(Bit8u * data,Bit16u * size) { return false;} bool Write(Bit8u * data,Bit16u * size){ LOG(LOG_IOCTL,LOG_NORMAL)("EMS:Write to device"); diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 097dcf43..4d38efc5 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.49 2004-09-28 15:31:21 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.50 2004-10-17 14:45:00 qbix79 Exp $ */ #include #include @@ -373,12 +373,13 @@ void SHELL_Init() { DOS_PSP psp(psp_seg); psp.MakeNew(0); - psp.SetFileHandle(STDIN ,DOS_FindDevice("CON")); - psp.SetFileHandle(STDOUT,DOS_FindDevice("CON")); - psp.SetFileHandle(STDERR,DOS_FindDevice("CON")); - psp.SetFileHandle(STDAUX,DOS_FindDevice("CON")); - psp.SetFileHandle(STDNUL,DOS_FindDevice("CON")); - psp.SetFileHandle(STDPRN,DOS_FindDevice("CON")); + dos.psp(psp_seg); + Bit16u dummy=0; + DOS_OpenFile("CON",2,&dummy);/* STDIN */ + DOS_OpenFile("CON",2,&dummy);/* STDOUT */ + DOS_OpenFile("CON",2,&dummy);/* STDERR */ + DOS_OpenFile("CON",2,&dummy);/* STDAUX */ + DOS_OpenFile("CON",2,&dummy);/* STDPRN */ psp.SetParent(psp_seg); /* Set the environment */ psp.SetEnvironment(env_seg); From 365b1a2e4886b04fa464b79f585d7fcfc740c4fa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 17 Oct 2004 14:52:58 +0000 Subject: [PATCH 1943/4131] Removed docs installing. Almost nobody liked it. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2026 --- Makefile.am | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index 00c0c28f..6376bf3a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,3 @@ EXTRA_DIST = autogen.sh SUBDIRS = src include visualc docs visualc_net - -docdir = $(prefix)/share/doc/$(PACKAGE) -doc_DATA = README NEWS THANKS AUTHORS - From 4e69d3bf7a7d5c506c13ac5aaf9f37060c3777f3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 17 Oct 2004 14:54:41 +0000 Subject: [PATCH 1944/4131] Made all string functions more aware of systems with reverse signed unsigned defaults Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2027 --- include/support.h | 4 ++-- src/misc/support.cpp | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/support.h b/include/support.h index 5127d15d..0fab9b27 100644 --- a/include/support.h +++ b/include/support.h @@ -51,12 +51,12 @@ Bits ConvDecWord(char * word); Bits ConvHexWord(char * word); INLINE char * upcase(char * str) { - for (char* idx = str; *idx ; idx++) *idx = toupper(*idx); + for (char* idx = str; *idx ; idx++) *idx = toupper(*reinterpret_cast(idx)); return str; } INLINE char * lowcase(char * str) { - for(char* idx = str; *idx ; idx++) *idx = tolower(*idx); + for(char* idx = str; *idx ; idx++) *idx = tolower(*reinterpret_cast(idx)); return str; } diff --git a/src/misc/support.cpp b/src/misc/support.cpp index e544d882..993477b7 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.25 2004-08-04 09:12:56 qbix79 Exp $ */ +/* $Id: support.cpp,v 1.26 2004-10-17 14:54:41 qbix79 Exp $ */ #include #include @@ -48,14 +48,14 @@ void strreplace(char * str,char o,char n) { } } char *ltrim(char *str) { - while (*str && (*str==' ' || *str=='\t')) str++; + while (*str && isspace(*reinterpret_cast(str))) str++; return str; } char *rtrim(char *str) { char *p; p = strchr(str, '\0'); - while (--p >= str && isspace(*p)); + while (--p >= str && isspace(*reinterpret_cast(p))); p[1] = '\0'; return str; } @@ -84,7 +84,7 @@ bool ScanCMDBool(char * cmd,char * check) { char * ScanCMDRemain(char * cmd) { char * scan,*found;; if ((scan=found=strchr(cmd,'/'))) { - while (*scan!=' ' && *scan!='\t' && *scan!=0) scan++; + while (*scan && isspace(*reinterpret_cast(scan))!=0) scan++; *scan=0; return found; } else return 0; @@ -104,7 +104,7 @@ char * StripWord(char *&line) { } char * begin=scan; for (;char c=*scan;scan++) { - if (c==' ' || c=='\t') { + if (isspace(*reinterpret_cast(&c))) { *scan++=0; break; } @@ -130,7 +130,7 @@ Bits ConvDecWord(char * word) { Bits ConvHexWord(char * word) { Bitu ret=0; - while (char c=toupper(*word)) { + while (char c=toupper(*reinterpret_cast(word))) { ret*=16; if (c>='0' && c<='9') ret+=c-'0'; else if (c>='A' && c<='F') ret+=10+(c-'A'); From 7a096a16ea88c1cd0c191f289538257b2e323409 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Oct 2004 15:33:52 +0000 Subject: [PATCH 1945/4131] Change flag handling of rotate instructions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2028 --- src/cpu/flags.cpp | 116 +------------------ src/cpu/instructions.h | 254 +++++++++++++++++++++-------------------- 2 files changed, 134 insertions(+), 236 deletions(-) diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 1ac9000f..fabc39a9 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -42,9 +42,6 @@ Bitu get_CF(void) { case t_DECw: case t_DECd: case t_MUL: - case t_RCLb: - case t_RCLw: - case t_RCLd: return GETFLAG(CF); break; case t_ADDb: @@ -107,18 +104,6 @@ Bitu get_CF(void) { return lf_var1w; case t_NEGd: return lf_var1d; - case t_ROLb: - return lf_resb & 1; - case t_ROLw: - return lf_resw & 1; - case t_ROLd: - return lf_resd & 1; - case t_RORb: - return (lf_resb & 0x80); - case t_RORw: - return (lf_resw & 0x8000); - case t_RORd: - return (lf_resd & 0x80000000); case t_ORb: case t_ORw: case t_ORd: @@ -148,18 +133,6 @@ Bitu get_AF(void) { Bitu type=lflags.type; switch (type) { case t_UNKNOWN: - case t_ROLb: - case t_RORb: - case t_RCLb: - case t_RCRb: - case t_ROLw: - case t_RORw: - case t_RCLw: - case t_RCRw: - case t_ROLd: - case t_RORd: - case t_RCLd: - case t_RCRd: return GETFLAG(AF); case t_ADDb: case t_ADCb: @@ -238,18 +211,6 @@ Bitu get_ZF(void) { Bitu type=lflags.type; switch (type) { case t_UNKNOWN: - case t_ROLb: - case t_RORb: - case t_RCLb: - case t_RCRb: - case t_ROLw: - case t_RORw: - case t_RCLw: - case t_RCRw: - case t_ROLd: - case t_RORd: - case t_RCLd: - case t_RCRd: return GETFLAG(ZF); case t_ADDb: case t_ORb: @@ -318,18 +279,6 @@ Bitu get_SF(void) { Bitu type=lflags.type; switch (type) { case t_UNKNOWN: - case t_ROLb: - case t_RORb: - case t_RCLb: - case t_RCRb: - case t_ROLw: - case t_RORw: - case t_RCLw: - case t_RCRw: - case t_ROLd: - case t_RORd: - case t_RCLd: - case t_RCRd: return GETFLAG(SF); case t_ADDb: case t_ORb: @@ -437,26 +386,14 @@ Bitu get_OF(void) { return (lf_var1w == 0x8000); case t_NEGd: return (lf_var1d == 0x80000000); - case t_ROLb: - case t_RORb: - case t_RCLb: - case t_RCRb: case t_SHLb: case t_SHRb: return (lf_resb ^ lf_var1b) & 0x80; - case t_ROLw: - case t_RORw: - case t_RCLw: - case t_RCRw: case t_SHLw: case t_SHRw: case t_DSHRw: case t_DSHLw: return (lf_resw ^ lf_var1w) & 0x8000; - case t_ROLd: - case t_RORd: - case t_RCLd: - case t_RCRd: case t_SHLd: case t_SHRd: case t_DSHRd: @@ -507,7 +444,7 @@ Bit16u parity_lookup[256] = { Bitu get_PF(void) { switch (lflags.type) { - case t_UNKNOWN: + case t_UNKNOWN: return GETFLAG(PF); default: return (parity_lookup[lf_resb]);; @@ -832,57 +769,6 @@ Bitu FillFlags(void) { DOFLAG_PF; break; - - case t_ROLb: - SET_FLAG(CF,lf_resb & 1); - SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); - break; - case t_ROLw: - SET_FLAG(CF,lf_resw & 1); - SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); - break; - case t_ROLd: - SET_FLAG(CF,lf_resd & 1); - SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); - break; - - - case t_RORb: - SET_FLAG(CF,(lf_resb & 0x80)); - SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); - break; - case t_RORw: - SET_FLAG(CF,(lf_resw & 0x8000)); - SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); - break; - case t_RORd: - SET_FLAG(CF,(lf_resd & 0x80000000)); - SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); - break; - - case t_RCLb: - SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); - break; - case t_RCLw: - SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); - break; - case t_RCLd: - SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); - break; - - case t_RCRb: - SET_FLAG(CF,(lf_var1b >> (lf_var2b - 1)) & 1); - SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); - break; - case t_RCRw: - SET_FLAG(CF,(lf_var1w >> (lf_var2b - 1)) & 1); - SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); - break; - case t_RCRd: - SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); - SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); - break; - case t_INCb: SET_FLAG(AF,(lf_resb & 0x0f) == 0); DOFLAG_ZFb; diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index a53ae3e6..a69324ff 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -225,150 +225,162 @@ save(op1,lf_resd); \ lflags.type=t_DECd; -#define ROLB(op1,op2,load,save) \ - LoadZF;LoadSF;LoadAF; \ - lf_var1b=load(op1); \ - lf_var2b=op2&0x07; \ - lf_resb=(lf_var1b << lf_var2b) | \ - (lf_var1b >> (8-lf_var2b)); \ - save(op1,lf_resb); \ - lflags.type=t_ROLb; \ -#define ROLW(op1,op2,load,save) \ - LoadZF;LoadSF;LoadAF; \ - lf_var1w=load(op1); \ - lf_var2b=op2&0x0F; \ - lf_resw=(lf_var1w << lf_var2b) | \ - (lf_var1w >> (16-lf_var2b)); \ - save(op1,lf_resw); \ - lflags.type=t_ROLw; \ +#define ROLB(op1,op2,load,save) \ + if (!(op2&0x7)) break; \ + FillFlags(); \ + lf_var1b=load(op1); \ + lf_var2b=op2&0x07; \ + lf_resb=(lf_var1b << lf_var2b) | \ + (lf_var1b >> (8-lf_var2b)); \ + save(op1,lf_resb); \ + SETFLAGBIT(CF,lf_resb & 1); \ + SETFLAGBIT(OF,(lf_resb & 1) ^ (lf_resb >> 7)); + +#define ROLW(op1,op2,load,save) \ + if (!(op2&0xf)) break; \ + FillFlags(); \ + lf_var1w=load(op1); \ + lf_var2b=op2&0xf; \ + lf_resw=(lf_var1w << lf_var2b) | \ + (lf_var1w >> (16-lf_var2b)); \ + save(op1,lf_resw); \ + SETFLAGBIT(CF,lf_resw & 1); \ + SETFLAGBIT(OF,(lf_resw & 1) ^ (lf_resw >> 15)); + +#define ROLD(op1,op2,load,save) \ + if (!op2) break; \ + FillFlags(); \ + lf_var1d=load(op1); \ + lf_var2b=op2; \ + lf_resd=(lf_var1d << lf_var2b) | \ + (lf_var1d >> (32-lf_var2b)); \ + save(op1,lf_resd); \ + SETFLAGBIT(CF,lf_resd & 1); \ + SETFLAGBIT(OF,(lf_resd & 1) ^ (lf_resd >> 31)); -#define ROLD(op1,op2,load,save) \ - LoadZF;LoadSF;LoadAF; \ - lf_var1d=load(op1); \ - lf_var2b=op2; \ - lf_resd=(lf_var1d << lf_var2b) | \ - (lf_var1d >> (32-lf_var2b)); \ - save(op1,lf_resd); \ - lflags.type=t_ROLd; \ +#define RORB(op1,op2,load,save) \ + if (!(op2&0x7)) break; \ + FillFlags(); \ + lf_var1b=load(op1); \ + lf_var2b=op2&0x07; \ + lf_resb=(lf_var1b >> lf_var2b) | \ + (lf_var1b << (8-lf_var2b)); \ + save(op1,lf_resb); \ + SETFLAGBIT(CF,lf_resb & 1); \ + if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resb ^ lf_var1b) & 0x80); + +#define RORW(op1,op2,load,save) \ + if (!(op2&0xf)) break; \ + FillFlags(); \ + lf_var1w=load(op1); \ + lf_var2b=op2&0xf; \ + lf_resw=(lf_var1w >> lf_var2b) | \ + (lf_var1w << (16-lf_var2b)); \ + save(op1,lf_resw); \ + SETFLAGBIT(CF,lf_resw & 1); \ + if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resw ^ lf_var1w) & 0x8000); + +#define RORD(op1,op2,load,save) \ + if (!op2) break; \ + FillFlags(); \ + lf_var1d=load(op1); \ + lf_var2b=op2; \ + lf_resd=(lf_var1d >> lf_var2b) | \ + (lf_var1d << (32-lf_var2b)); \ + save(op1,lf_resd); \ + SETFLAGBIT(CF,lf_resd & 1); \ + if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resd ^ lf_var1d) & 0x80000000); -#define RORB(op1,op2,load,save) \ - LoadZF;LoadSF;LoadAF; \ - lf_var1b=load(op1); \ - lf_var2b=op2&0x07; \ - lf_resb=(lf_var1b >> lf_var2b) | \ - (lf_var1b << (8-lf_var2b)); \ - save(op1,lf_resb); \ - lflags.type=t_RORb; \ - - -#define RORW(op1,op2,load,save) \ - if (op2&0x0F) { \ - LoadZF;LoadSF;LoadAF; \ - lf_var1w=load(op1); \ - lf_var2b=op2&0x0F; \ - lf_resw=(lf_var1w >> lf_var2b) | \ - (lf_var1w << (16-lf_var2b)); \ - save(op1,lf_resw); \ - lflags.type=t_RORw; \ - } - -#define RORD(op1,op2,load,save) \ - if (op2) { \ - LoadZF;LoadSF;LoadAF; \ - lf_var1d=load(op1); \ - lf_var2b=op2; \ - lf_resd=(lf_var1d >> lf_var2b) | \ - (lf_var1d << (32-lf_var2b)); \ - save(op1,lf_resd); \ - lflags.type=t_RORd; \ - } - - -#define RCLB(op1,op2,load,save) \ - if (op2%9) { \ - Bit8u cf=(Bit8u)FillFlags()&0x1; \ - lf_var1b=load(op1); \ - lf_var2b=op2%9; \ - lflags.type=t_RCLb; \ - lf_resb=(lf_var1b << lf_var2b) | \ - (cf << (lf_var2b-1)) | \ - (lf_var1b >> (9-lf_var2b)); \ - SETFLAGBIT(CF,((lf_var1b >> (8-lf_var2b)) & 1)); \ - save(op1,lf_resb); \ - } - -#define RCLW(op1,op2,load,save) \ - if (op2%17) { \ - Bit16u cf=(Bit16u)FillFlags()&0x1; \ - lf_var1w=load(op1); \ - lf_var2b=op2%17; \ - lflags.type=t_RCLw; \ - lf_resw=(lf_var1w << lf_var2b) | \ - (cf << (lf_var2b-1)) | \ - (lf_var1w >> (17-lf_var2b)); \ - SETFLAGBIT(CF,((lf_var1w >> (16-lf_var2b)) & 1)); \ - save(op1,lf_resw); \ - } - -#define RCLD(op1,op2,load,save) \ - if (op2) { \ - Bit32u cf=(Bit32u)FillFlags()&0x1; \ - lf_var1d=load(op1); \ - lf_var2b=op2; \ - lflags.type=t_RCLd; \ - if (lf_var2b==1) { \ - lf_resd=(lf_var1d << 1) | cf; \ - } else { \ - lf_resd=(lf_var1d << lf_var2b) | \ +#define RCLB(op1,op2,load,save) \ + if (!(op2%9)) break; \ +{ Bit8u cf=(Bit8u)FillFlags()&0x1; \ + lf_var1b=load(op1); \ + lf_var2b=op2%9; \ + lf_resb=(lf_var1b << lf_var2b) | \ (cf << (lf_var2b-1)) | \ - (lf_var1d >> (33-lf_var2b)); \ - } \ - SETFLAGBIT(CF,((lf_var1d >> (32-lf_var2b)) & 1)); \ - save(op1,lf_resd); \ - } + (lf_var1b >> (9-lf_var2b)); \ + save(op1,lf_resb); \ + SETFLAGBIT(CF,((lf_var1b >> (8-lf_var2b)) & 1)); \ + SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resb >> 7)); \ +} + +#define RCLW(op1,op2,load,save) \ + if (!(op2%17)) break; \ +{ Bit16u cf=(Bit16u)FillFlags()&0x1; \ + lf_var1w=load(op1); \ + lf_var2b=op2%17; \ + lf_resw=(lf_var1w << lf_var2b) | \ + (cf << (lf_var2b-1)) | \ + (lf_var1w >> (17-lf_var2b)); \ + save(op1,lf_resw); \ + SETFLAGBIT(CF,((lf_var1w >> (16-lf_var2b)) & 1)); \ + SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resw >> 15)); \ +} + +#define RCLD(op1,op2,load,save) \ + if (!op2) break; \ +{ Bit32u cf=(Bit32u)FillFlags()&0x1; \ + lf_var1d=load(op1); \ + lf_var2b=op2; \ + if (lf_var2b==1) { \ + lf_resd=(lf_var1d << 1) | cf; \ + } else { \ + lf_resd=(lf_var1d << lf_var2b) | \ + (cf << (lf_var2b-1)) | \ + (lf_var1d >> (33-lf_var2b)); \ + } \ + save(op1,lf_resd); \ + SETFLAGBIT(CF,((lf_var1d >> (32-lf_var2b)) & 1)); \ + SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resd >> 31)); \ +} + + #define RCRB(op1,op2,load,save) \ if (op2%9) { \ Bit8u cf=(Bit8u)FillFlags()&0x1; \ - lf_var1b=load(op1); \ - lf_var2b=op2%9; \ - lflags.type=t_RCRb; \ - lf_resb=(lf_var1b >> lf_var2b) | \ - (cf << (8-lf_var2b)) | \ - (lf_var1b << (9-lf_var2b)); \ - save(op1,lf_resb); \ + lf_var1b=load(op1); \ + lf_var2b=op2%9; \ + lf_resb=(lf_var1b >> lf_var2b) | \ + (cf << (8-lf_var2b)) | \ + (lf_var1b << (9-lf_var2b)); \ + save(op1,lf_resb); \ + SETFLAGBIT(CF,(lf_var1b >> (lf_var2b - 1)) & 1); \ + SETFLAGBIT(OF,(lf_resb ^ lf_var1b) & 0x80); \ } #define RCRW(op1,op2,load,save) \ if (op2%17) { \ Bit16u cf=(Bit16u)FillFlags()&0x1; \ - lf_var1w=load(op1); \ - lf_var2b=op2%17; \ - lflags.type=t_RCRw; \ - lf_resw=(lf_var1w >> lf_var2b) | \ - (cf << (16-lf_var2b)) | \ - (lf_var1w << (17-lf_var2b)); \ - save(op1,lf_resw); \ + lf_var1w=load(op1); \ + lf_var2b=op2%17; \ + lf_resw=(lf_var1w >> lf_var2b) | \ + (cf << (16-lf_var2b)) | \ + (lf_var1w << (17-lf_var2b)); \ + save(op1,lf_resw); \ + SETFLAGBIT(CF,(lf_var1w >> (lf_var2b - 1)) & 1); \ + SETFLAGBIT(OF,(lf_resw ^ lf_var1w) & 0x8000); \ } #define RCRD(op1,op2,load,save) \ if (op2) { \ Bit32u cf=(Bit32u)FillFlags()&0x1; \ - lf_var1d=load(op1); \ - lf_var2b=op2; \ - lflags.type=t_RCRd; \ - if (lf_var2b==1) { \ - lf_resd=lf_var1d >> 1 | cf << 31; \ + lf_var1d=load(op1); \ + lf_var2b=op2; \ + if (lf_var2b==1) { \ + lf_resd=lf_var1d >> 1 | cf << 31; \ } else { \ - lf_resd=(lf_var1d >> lf_var2b) | \ - (cf << (32-lf_var2b)) | \ - (lf_var1d << (33-lf_var2b)); \ + lf_resd=(lf_var1d >> lf_var2b) | \ + (cf << (32-lf_var2b)) | \ + (lf_var1d << (33-lf_var2b)); \ } \ - save(op1,lf_resd); \ + save(op1,lf_resd); \ + SETFLAGBIT(CF,(lf_var1d >> (lf_var2b - 1)) & 1); \ + SETFLAGBIT(OF,(lf_resd ^ lf_var1d) & 0x80000000); \ } From 96be257ed3f0921a321279b9cc274d6bc00d66a2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 17 Oct 2004 16:00:57 +0000 Subject: [PATCH 1946/4131] Basic unmounting Woot :P Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2029 --- src/dos/dos_programs.cpp | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index f34802cd..773f8c59 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.30 2004-09-16 22:05:24 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.31 2004-10-17 16:00:57 qbix79 Exp $ */ #include #include @@ -41,7 +41,32 @@ public: { DOS_Drive * newdrive;char drive; std::string label; - + std::string umount; + /* Check for unmounting */ + if (cmd->FindString("-u",umount,false)) { + umount[0] = toupper(umount[0]); + int drive = umount[0]-'A'; + if(drive < DOS_DRIVES && Drives[drive]) { + if(drive == DOS_GetDefaultDrive()) { + WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_CURRENT")); + return; + } + try { /* Check if virtualdrive */ + if( dynamic_cast(Drives[drive]) == 0 ) throw 0; + } + catch(...) { + WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NO_VIRTUAL")); + return; + } + WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCES"),umount[0]); + delete Drives[drive]; + Drives[drive] = 0; + } else { + WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED"),umount[0]); + } + return; + } + // Show list of cdroms if (cmd->FindExist("-cd",false)) { int num = SDL_CDNumDrives(); @@ -657,7 +682,11 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_MOUNT_ILL_TYPE","Illegal type %s\n"); MSG_Add("PROGRAM_MOUNT_ALLREADY_MOUNTED","Drive %c already mounted with %s\n"); MSG_Add("PROGRAM_MOUNT_USAGE","Usage \033[34;1mMOUNT Drive-Letter Local-Directory\033[0m\nSo a MOUNT c c:\\windows mounts windows directory as the c: drive in DOSBox\n"); - + MSG_Add("PROGRAM_MOUNT_UMOUNT_CURRENT","You can not unMOUNT the active drive.\n"); + MSG_Add("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED","Drive %c isn't mounted.\n"); + MSG_Add("PROGRAM_MOUNT_UMOUNT_SUCCES","Drive %c has succesfully been removed.\n"); + MSG_Add("PROGRAM_MOUNT_UMOUNT_NO_VIRTUAL","Virtual Drives can not be unMOUNTed.\n"); + MSG_Add("PROGRAM_MEM_CONVEN","%10d Kb free conventional memory\n"); MSG_Add("PROGRAM_MEM_EXTEND","%10d Kb free extended memory\n"); MSG_Add("PROGRAM_MEM_EXPAND","%10d Kb free expanded memory\n"); From 512c2bde936869baa5cd540b968bd5230f950658 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Oct 2004 17:56:53 +0000 Subject: [PATCH 1947/4131] Fix some sdl_sound linking and detection issues Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2030 --- configure.in | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/configure.in b/configure.in index a749e10b..d7b020ae 100644 --- a/configure.in +++ b/configure.in @@ -179,10 +179,15 @@ fi AH_TEMPLATE(C_SDL_SOUND,[Define to 1 to enable SDL_sound support]) AC_CHECK_HEADER(SDL/SDL_sound.h,have_SDL_sound_h=yes,) -AC_CHECK_LIB(SDL_sound, Sound_Init, have_SDL_sound_lib=yes,,) -if test x$have_SDL_sound_h = xyes -a x$have_SDL_sound_lib = xyes ; then - LIBS="$LIBS -lSDL_sound" - AC_DEFINE(C_SDL_SOUND,1) +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 From bced25b89046cab8eb3fc2340297a2d83b598593 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 17 Oct 2004 18:10:06 +0000 Subject: [PATCH 1948/4131] update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2031 --- README | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README b/README index 8db24d50..f32c360c 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -DOSBox v0.62 +DOSBox v0.63 ===== @@ -151,8 +151,8 @@ A: DOSBox emulates several legacy sound devices: - Adlib Borrowed from MAME, this emulation is almost perfect and includes the Adlib's ability to almost play digitized sound. - - SoundBlaster Pro - Coupled with the Adlib, DOSBox provides Soundblaster Pro level 8-bit + - SoundBlaster 16 + Coupled with the Adlib, DOSBox provides Soundblaster 16 level 16-bit stereo sound. - Disney Soundsource Using the printer port, this sound device outputs digital sound only. @@ -250,7 +250,8 @@ MOUNT "Emulated Drive letter" "Real Drive or Directory" [-t type] [-aspi] [-ioctl] [-usecd number] [-size drivesize] [-label drivelabel] [-freesize sizemb] MOUNT -cd - +MOUNT -u "Emulated Drive letter" + Program to mount local directories as drives inside DOSBox. "Emulated Drive letter" @@ -292,6 +293,9 @@ MOUNT -cd -cd Displays all detected cdrom drives and their numbers. Use with -usecd. + -u + Removes the mount. Doesn't work for Z:\. + Note: It's possible to mount a local directory as cdrom drive. Hardware support is then missing. From 8dbbd230dacedbb49d29b8fbf179d611f0ba47ec Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 20 Oct 2004 12:27:19 +0000 Subject: [PATCH 1949/4131] forgot return statement Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2032 --- include/dos_system.h | 3 ++- src/dos/dos_devices.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 7cb770df..ef29576a 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.25 2004-10-17 14:44:59 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.26 2004-10-20 12:27:18 qbix79 Exp $ */ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ @@ -87,6 +87,7 @@ public: DOS_Device & operator= (const DOS_Device & orig) { DOS_File::operator=(orig); devnum=orig.devnum; + return *this; } DOS_Device():DOS_File(),devnum(0){}; virtual bool Read(Bit8u * data,Bit16u * size); diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index d6eb1128..f8b442c0 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_devices.cpp,v 1.6 2004-10-17 14:45:00 qbix79 Exp $ */ +/* $Id: dos_devices.cpp,v 1.7 2004-10-20 12:27:19 qbix79 Exp $ */ #include #include "dosbox.h" @@ -106,6 +106,7 @@ DOS_File & DOS_File::operator= (const DOS_File & orig) { if(orig.name) { name=new char [strlen(orig.name)];strcpy(name,orig.name); } + return *this; } Bit8u DOS_FindDevice(char * name) { From 6793c1b7ac82ca97417ee5524a9919bed2e79402 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 20 Oct 2004 19:53:50 +0000 Subject: [PATCH 1950/4131] shell_misc.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2033 --- src/shell/shell_misc.cpp | 46 +++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index f82b4838..782b6722 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,14 +16,15 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.32 2004-09-08 18:58:48 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.33 2004-10-20 19:53:50 qbix79 Exp $ */ #include #include +#include //std::copy +#include //std::front_inserter #include "shell.h" #include "regs.h" - void DOS_Shell::ShowPrompt(void) { Bit8u drive=DOS_GetDefaultDrive()+'A'; char dir[DOS_PATHLENGTH]; @@ -130,7 +131,21 @@ void DOS_Shell::InputCommand(char * line) { it_history ++; break; - + case 0x53:/* DELETE */ + { + if(str_index>=str_len) break; + Bit16u a=str_len-str_index-1; + Bit8u* text=reinterpret_cast(&line[str_index+1]); + DOS_WriteFile(STDOUT,text,&a);//write buffer to screen + outc(' ');outc(8); + for(Bitu i=str_index;i executable; while (res) { dta.GetResult(name,size,date,time,attr); // add result to completion list @@ -212,15 +228,16 @@ void DOS_Shell::InputCommand(char * line) { if (strcmp(name, ".") && strcmp(name, "..")) { ext = strrchr(name, '.'); if (ext && (strcmp(ext, ".BAT") == 0 || strcmp(ext, ".COM") == 0 || strcmp(ext, ".EXE") == 0)) - // we add executables to the start of the list - l_completion.push_front(name); + // we add executables to the a seperate list and place that list infront of the normal files + executable.push_front(name); else l_completion.push_back(name); } res=DOS_FindNext(); } - + /* Add excutable list to front of completion list. */ + std::copy(executable.begin(),executable.end(),std::front_inserter(l_completion)); it_completion = l_completion.begin(); } @@ -250,14 +267,27 @@ void DOS_Shell::InputCommand(char * line) { break; default: if (l_completion.size()) l_completion.clear(); + if(str_index < str_len && true) { //mem_readb(BIOS_KEYBOARD_FLAGS1)&0x80) dev_con.h ? + outc(' ');//move cursor one to the right. + Bit16u a = str_len - str_index; + Bit8u* text=reinterpret_cast(&line[str_index]); + DOS_WriteFile(STDOUT,text,&a);//write buffer to screen + outc(8);//undo the cursor the right. + for(Bitu i=str_len;i>str_index;i--) { + line[i]=line[i-1]; //move internal buffer + outc(8); //move cursor back (from write buffer to screen) + } + line[++str_len]=0;//new end (as the internal buffer moved one place to the right + size--; + }; + line[str_index]=c; str_index ++; if (str_index > str_len){ line[str_index] = '\0'; - str_len++;//This should depend on insert being active + str_len++; size--; } - DOS_WriteFile(STDOUT,&c,&n); break; } From 71ec900fe013cee7eb00e8f5d8ff4c88e9d7d02b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 21 Oct 2004 15:38:39 +0000 Subject: [PATCH 1951/4131] Let some of the shell commands switch to a private dta. Fixes 1040579 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2034 --- src/shell/shell_cmds.cpp | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index d4cdec41..286312fd 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.48 2004-10-02 11:13:02 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.49 2004-10-21 15:38:39 qbix79 Exp $ */ #include #include @@ -74,7 +74,7 @@ void DOS_Shell::DoCommand(char * line) { while (cmd_list[cmd_index].name) { if (strcasecmp(cmd_list[cmd_index].name,cmd)==0) { (this->*(cmd_list[cmd_index].handler))(line); - return; + return; } cmd_index++; } @@ -103,7 +103,10 @@ void DOS_Shell::CMD_CLS(char * args) { }; void DOS_Shell::CMD_DELETE(char * args) { - + /* Command uses dta so set it to our internal dta */ + RealPt save_dta=dos.dta(); + dos.dta(dos.tables.tempdta); + char * rem=ScanCMDRemain(args); if (rem) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); @@ -119,7 +122,9 @@ void DOS_Shell::CMD_DELETE(char * args) { //TODO Maybe support confirmation for *.* like dos does. bool res=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME); if (!res) { - WriteOut(MSG_Get("SHELL_CMD_DEL_ERROR"),args);return; + WriteOut(MSG_Get("SHELL_CMD_DEL_ERROR"),args); + dos.dta(save_dta); + return; } //end can't be 0, but if it is we'll get a nice crash, who cares :) char * end=strrchr(full,'\\')+1;*end=0; @@ -133,6 +138,7 @@ void DOS_Shell::CMD_DELETE(char * args) { } res=DOS_FindNext(); } + dos.dta(save_dta); } void DOS_Shell::CMD_HELP(char * args){ @@ -298,10 +304,14 @@ void DOS_Shell::CMD_DIR(char * args) { *(strrchr(path,'\\')+1)=0; WriteOut(MSG_Get("SHELL_CMD_DIR_INTRO"),path); + /* Command uses dta so set it to our internal dta */ + RealPt save_dta=dos.dta(); + dos.dta(dos.tables.tempdta); DOS_DTA dta(dos.dta()); bool ret=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME); if (!ret) { WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); + dos.dta(save_dta); return; } @@ -369,11 +379,15 @@ void DOS_Shell::CMD_DIR(char * args) { } FormatNumber(free_space,numformat); WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_FREE"),dir_count,numformat); + dos.dta(save_dta); } void DOS_Shell::CMD_COPY(char * args) { static char defaulttarget[] = "."; StripSpaces(args); + /* Command uses dta so set it to our internal dta */ + RealPt save_dta=dos.dta(); + dos.dta(dos.tables.tempdta); DOS_DTA dta(dos.dta()); Bit32u size;Bit16u date;Bit16u time;Bit8u attr; char name[DOS_NAMELENGTH_ASCII]; @@ -385,6 +399,7 @@ void DOS_Shell::CMD_COPY(char * args) { char * rem=ScanCMDRemain(args); if (rem) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); + dos.dta(save_dta); return; } // source/target @@ -396,6 +411,7 @@ void DOS_Shell::CMD_COPY(char * args) { // Target and Source have to be there if (!source || !strlen(source)) { WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); + dos.dta(save_dta); return; }; @@ -405,6 +421,7 @@ void DOS_Shell::CMD_COPY(char * args) { if (!DOS_Canonicalize(source,pathSource)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); + dos.dta(save_dta); return; } // cut search pattern @@ -413,6 +430,7 @@ void DOS_Shell::CMD_COPY(char * args) { if (!DOS_Canonicalize(target,pathTarget)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); + dos.dta(save_dta); return; } char* temp = strstr(pathTarget,"*.*"); @@ -430,6 +448,7 @@ void DOS_Shell::CMD_COPY(char * args) { bool ret=DOS_FindFirst(source,0xffff & ~DOS_ATTR_VOLUME); if (!ret) { WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); + dos.dta(save_dta); return; } @@ -473,6 +492,7 @@ void DOS_Shell::CMD_COPY(char * args) { ret=DOS_FindNext(); }; WriteOut(MSG_Get("SHELL_CMD_COPY_SUCCESS"),count); + dos.dta(save_dta); } void DOS_Shell::CMD_SET(char * args) { @@ -519,8 +539,14 @@ void DOS_Shell::CMD_IF(char * args) { WriteOut(MSG_Get("SHELL_CMD_IF_EXIST_MISSING_FILENAME")); return; }; - - if (DOS_FindFirst(word,0xffff & ~DOS_ATTR_VOLUME)==(!has_not)) DoCommand(args); + + { /* DOS_FindFirst uses dta so set it to our internal dta */ + RealPt save_dta=dos.dta(); + dos.dta(dos.tables.tempdta); + bool ret=DOS_FindFirst(word,0xffff & ~DOS_ATTR_VOLUME); + dos.dta(save_dta); + if (ret==(!has_not)) DoCommand(args); + } return; } if (strcasecmp(word,"ERRORLEVEL")==0) { From 232541c358c2f1863ed152097e8a36f172f26697 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 23 Oct 2004 15:15:07 +0000 Subject: [PATCH 1952/4131] Added lot's of callback information. Added some useful information on how to use the debugger. Added patch 105158 from Hendrik Jan Visser Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2035 --- include/debug.h | 1 + src/debug/debug.cpp | 251 ++++++++++++++++++++++++++-------------- src/debug/debug_gui.cpp | 54 +++++++-- src/hardware/mpu401.cpp | 2 +- src/ints/bios.cpp | 24 ++-- src/ints/bios_disk.cpp | 2 +- src/ints/ems.cpp | 6 +- src/ints/int10.cpp | 2 +- src/misc/programs.cpp | 4 +- src/shell/shell.cpp | 10 +- 10 files changed, 241 insertions(+), 115 deletions(-) diff --git a/include/debug.h b/include/debug.h index 337e8497..78805b70 100644 --- a/include/debug.h +++ b/include/debug.h @@ -23,6 +23,7 @@ bool DEBUG_IntBreakpoint(Bit8u intNum); void DEBUG_Enable(void); void DEBUG_CheckExecuteBreakpoint(Bit16u seg, Bit32u off); bool DEBUG_ExitLoop(void); +void DEBUG_RefreshPage(char scroll); extern Bitu cycle_count; extern Bitu debugCallback; diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 4ac98ebc..122ba85d 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.59 2004-08-31 23:11:35 harekiet Exp $ */ +/* $Id: debug.cpp,v 1.60 2004-10-23 15:15:06 qbix79 Exp $ */ #include #include @@ -387,7 +387,7 @@ bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off) Bit8u value = mem_readb(address); if (bp->GetValue() != value) { // Yup, memory value changed - DEBUG_ShowMsg("DEBUG: Memory breakpoint %s: %04X:%04X - %02X -> %02X",(bp->GetType()==BKPNT_MEMORY_PROT)?"(Prot)":"",bp->GetSegment(),bp->GetOffset(),bp->GetValue(),value); + DEBUG_ShowMsg("DEBUG: Memory breakpoint %s: %04X:%04X - %02X -> %02X\n",(bp->GetType()==BKPNT_MEMORY_PROT)?"(Prot)":"",bp->GetSegment(),bp->GetOffset(),bp->GetValue(),value); bp->SetValue(value); return true; }; @@ -527,18 +527,17 @@ void CBreakpoint::ShowList(void) for(i=BPoints.begin(); i != BPoints.end(); i++) { CBreakpoint* bp = static_cast(*i); if (bp->GetType()==BKPNT_PHYSICAL) { - wprintw(dbg.win_out,"%02X. BP %04X:%04X\n",nr,bp->GetSegment(),bp->GetOffset()); + DEBUG_ShowMsg("%02X. BP %04X:%04X\n",nr,bp->GetSegment(),bp->GetOffset()); nr++; } else if (bp->GetType()==BKPNT_INTERRUPT) { - if (bp->GetValue()==BPINT_ALL) wprintw(dbg.win_out,"%02X. BPINT %02X\n",nr,bp->GetIntNr()); - else wprintw(dbg.win_out,"%02X. BPINT %02X AH=%02X\n",nr,bp->GetIntNr(),bp->GetValue()); + if (bp->GetValue()==BPINT_ALL) DEBUG_ShowMsg("%02X. BPINT %02X\n",nr,bp->GetIntNr()); + else DEBUG_ShowMsg("%02X. BPINT %02X AH=%02X\n",nr,bp->GetIntNr(),bp->GetValue()); nr++; } else if (bp->GetType()==BKPNT_MEMORY) { - wprintw(dbg.win_out,"%02X. BPMEM %04X:%04X (%02X)\n",nr,bp->GetSegment(),bp->GetOffset(),bp->GetValue()); + DEBUG_ShowMsg("%02X. BPMEM %04X:%04X (%02X)\n",nr,bp->GetSegment(),bp->GetOffset(),bp->GetValue()); nr++; }; } - wrefresh(dbg.win_out); }; bool DEBUG_Breakpoint(void) @@ -883,7 +882,7 @@ bool ParseCommand(char* str) }; name[15] = 0; - DEBUG_ShowMsg("DEBUG: Created debug var %s at %04X:%04X",name,seg,ofs); + DEBUG_ShowMsg("DEBUG: Created debug var %s at %04X:%04X\n",name,seg,ofs); CDebugVar::InsertVariable(name,GetAddress(seg,ofs)); return true; } @@ -897,8 +896,8 @@ bool ParseCommand(char* str) else { name[i] = 0; break; }; }; name[12] = 0; - if (CDebugVar::SaveVars(name)) DEBUG_ShowMsg("DEBUG: Variable list save (%s) : ok.",name); - else DEBUG_ShowMsg("DEBUG: Variable list save (%s) : failure",name); + if (CDebugVar::SaveVars(name)) DEBUG_ShowMsg("DEBUG: Variable list save (%s) : ok.\n",name); + else DEBUG_ShowMsg("DEBUG: Variable list save (%s) : failure\n",name); return true; } @@ -911,15 +910,15 @@ bool ParseCommand(char* str) else { name[i] = 0; break; }; }; name[12] = 0; - if (CDebugVar::LoadVars(name)) DEBUG_ShowMsg("DEBUG: Variable list load (%s) : ok.",name); - else DEBUG_ShowMsg("DEBUG: Variable list load (%s) : failure",name); + if (CDebugVar::LoadVars(name)) DEBUG_ShowMsg("DEBUG: Variable list load (%s) : ok.\n",name); + else DEBUG_ShowMsg("DEBUG: Variable list load (%s) : failure\n",name); return true; } found = strstr(str,"SR "); if (found) { // Set register value found+=2; - if (ChangeRegister(found)) DEBUG_ShowMsg("DEBUG: Set Register success."); - else DEBUG_ShowMsg("DEBUG: Set Register failure."); + if (ChangeRegister(found)) DEBUG_ShowMsg("DEBUG: Set Register success.\n"); + else DEBUG_ShowMsg("DEBUG: Set Register failure.\n"); return true; } found = strstr(str,"SM "); @@ -936,7 +935,7 @@ bool ParseCommand(char* str) count++; } }; - DEBUG_ShowMsg("DEBUG: Memory changed."); + DEBUG_ShowMsg("DEBUG: Memory changed.\n"); return true; } @@ -946,7 +945,7 @@ bool ParseCommand(char* str) Bit16u seg = (Bit16u)GetHexValue(found,found);found++; // skip ":" Bit32u ofs = GetHexValue(found,found); CBreakpoint::AddBreakpoint(seg,ofs,false); - DEBUG_ShowMsg("DEBUG: Set breakpoint at %04X:%04X",seg,ofs); + DEBUG_ShowMsg("DEBUG: Set breakpoint at %04X:%04X\n",seg,ofs); return true; } #if C_HEAVY_DEBUG @@ -956,7 +955,7 @@ bool ParseCommand(char* str) Bit16u seg = (Bit16u)GetHexValue(found,found);found++; // skip ":" Bit32u ofs = GetHexValue(found,found); CBreakpoint::AddMemBreakpoint(seg,ofs); - DEBUG_ShowMsg("DEBUG: Set memory breakpoint at %04X:%04X",seg,ofs); + DEBUG_ShowMsg("DEBUG: Set memory breakpoint at %04X:%04X\n",seg,ofs); return true; } found = strstr(str,"BPPM "); @@ -966,7 +965,7 @@ bool ParseCommand(char* str) Bit32u ofs = GetHexValue(found,found); CBreakpoint* bp = CBreakpoint::AddMemBreakpoint(seg,ofs); if (bp) bp->SetType(BKPNT_MEMORY_PROT); - DEBUG_ShowMsg("DEBUG: Set prot-mode memory breakpoint at %04X:%08X",seg,ofs); + DEBUG_ShowMsg("DEBUG: Set prot-mode memory breakpoint at %04X:%08X\n",seg,ofs); return true; } found = strstr(str,"BPLM "); @@ -975,7 +974,7 @@ bool ParseCommand(char* str) Bitu ofs = GetHexValue(found,found); CBreakpoint* bp = CBreakpoint::AddMemBreakpoint(0,ofs); if (bp) bp->SetType(BKPNT_MEMORY_LINEAR); - DEBUG_ShowMsg("DEBUG: Set linear memory breakpoint at %08X",ofs); + DEBUG_ShowMsg("DEBUG: Set linear memory breakpoint at %08X\n",ofs); return true; } #endif @@ -986,17 +985,17 @@ bool ParseCommand(char* str) Bit8u valAH = (Bit8u)GetHexValue(found,found); if ((valAH==0x00) && (*found=='*')) { CBreakpoint::AddIntBreakpoint(intNr,BPINT_ALL,false); - DEBUG_ShowMsg("DEBUG: Set interrupt breakpoint at INT %02X",intNr); + DEBUG_ShowMsg("DEBUG: Set interrupt breakpoint at INT %02X\n",intNr); } else { CBreakpoint::AddIntBreakpoint(intNr,valAH,false); - DEBUG_ShowMsg("DEBUG: Set interrupt breakpoint at INT %02X AH=%02X",intNr,valAH); + DEBUG_ShowMsg("DEBUG: Set interrupt breakpoint at INT %02X AH=%02X\n",intNr,valAH); } return true; } found = strstr(str,"BPLIST"); if (found) { - wprintw(dbg.win_out,"Breakpoint list:\n"); - wprintw(dbg.win_out,"-------------------------------------------------------------------------\n"); + DEBUG_ShowMsg("Breakpoint list:\n"); + DEBUG_ShowMsg("-------------------------------------------------------------------------\n"); CBreakpoint::ShowList(); return true; }; @@ -1007,7 +1006,7 @@ bool ParseCommand(char* str) Bit8u bpNr = (Bit8u)GetHexValue(found,found); if ((bpNr==0x00) && (*found=='*')) { // Delete all CBreakpoint::DeleteAll(); - DEBUG_ShowMsg("DEBUG: Breakpoints deleted."); + DEBUG_ShowMsg("DEBUG: Breakpoints deleted.\n"); } else { // delete single breakpoint CBreakpoint::DeleteByIndex(bpNr); @@ -1019,7 +1018,7 @@ bool ParseCommand(char* str) found++; Bit16u codeSeg = (Bit16u)GetHexValue(found,found); found++; Bit32u codeOfs = GetHexValue(found,found); - DEBUG_ShowMsg("DEBUG: Set code overview to %04X:%04X",codeSeg,codeOfs); + DEBUG_ShowMsg("DEBUG: Set code overview to %04X:%04X\n",codeSeg,codeOfs); codeViewData.useCS = codeSeg; codeViewData.useEIP = codeOfs; return true; @@ -1029,18 +1028,18 @@ bool ParseCommand(char* str) found++; dataSeg = (Bit16u)GetHexValue(found,found); found++; dataOfs = GetHexValue(found,found); - DEBUG_ShowMsg("DEBUG: Set data overview to %04X:%04X",dataSeg,dataOfs); + DEBUG_ShowMsg("DEBUG: Set data overview to %04X:%04X\n",dataSeg,dataOfs); return true; } #if C_HEAVY_DEBUG found = strstr(str,"LOG "); if (found) { // Create Cpu log file found+=4; - DEBUG_ShowMsg("DEBUG: Starting log"); + DEBUG_ShowMsg("DEBUG: Starting log\n"); // DEBUG_Log_Loop(GetHexValue(found,found)); cpuLogFile = fopen("LOGCPU.TXT","wt"); if (!cpuLogFile) { - DEBUG_ShowMsg("DEBUG: Logfile couldnt be created."); + DEBUG_ShowMsg("DEBUG: Logfile couldnt be created.\n"); return false; } cpuLog = true; @@ -1057,7 +1056,7 @@ bool ParseCommand(char* str) if (found) { // Create Cpu log file found+=4; Bit8u intNr = (Bit8u)GetHexValue(found,found); - DEBUG_ShowMsg("DEBUG: Tracing INT %02X",intNr); + DEBUG_ShowMsg("DEBUG: Tracing INT %02X\n",intNr); CPU_HW_Interrupt(intNr); SetCodeWinStart(); return true; @@ -1066,7 +1065,7 @@ bool ParseCommand(char* str) if (found) { // Create Cpu log file found+=4; Bit8u intNr = (Bit8u)GetHexValue(found,found); - DEBUG_ShowMsg("DEBUG: Starting INT %02X",intNr); + DEBUG_ShowMsg("DEBUG: Starting INT %02X\n",intNr); CBreakpoint::AddBreakpoint (SegValue(cs),reg_eip, true); CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip-1,true); debugging=false; @@ -1081,9 +1080,9 @@ bool ParseCommand(char* str) while (found[0]==' ') found++; char out1[200],out2[200]; GetDescriptorInfo(found,out1,out2); - DEBUG_ShowMsg("SelectorInfo %s:",found); - DEBUG_ShowMsg("%s",out1); - DEBUG_ShowMsg("%s",out2); + DEBUG_ShowMsg("SelectorInfo %s:\n",found); + DEBUG_ShowMsg("%s\n",out1); + DEBUG_ShowMsg("%s\n",out2); }; found = strstr(str,"GDT"); @@ -1118,7 +1117,7 @@ bool ParseCommand(char* str) if (found[0] != 0) { Bit8u intNr = (Bit8u)GetHexValue(found,found); - DEBUG_ShowMsg("DEBUG: Set code overview to interrupt handler %X",intNr); + DEBUG_ShowMsg("DEBUG: Set code overview to interrupt handler %X\n",intNr); codeViewData.useCS = mem_readw(intNr*4+2); codeViewData.useEIP = mem_readw(intNr*4); return true; @@ -1130,7 +1129,7 @@ bool ParseCommand(char* str) found += 9; Bit8u num = GetHexValue(found,found); DPMI_CreateException(num,0xDD); - DEBUG_ShowMsg("Exception %04X",num); + DEBUG_ShowMsg("Exception %04X\n",num); }; */ @@ -1138,56 +1137,55 @@ bool ParseCommand(char* str) found = strstr(str,"HEAVYLOG"); if (found) { // Create Cpu log file logHeavy = !logHeavy; - if (logHeavy) DEBUG_ShowMsg("DEBUG: Heavy cpu logging on."); - else DEBUG_ShowMsg("DEBUG: Heavy cpu logging off."); + if (logHeavy) DEBUG_ShowMsg("DEBUG: Heavy cpu logging on.\n"); + else DEBUG_ShowMsg("DEBUG: Heavy cpu logging off.\n"); return true; } #endif if ((*str=='H') || (*str=='?')) { - wprintw(dbg.win_out,"Debugger keys:\n"); - wprintw(dbg.win_out,"--------------------------------------------------------------------------\n"); - wprintw(dbg.win_out,"F5 - Run\n"); - wprintw(dbg.win_out,"F9 - Set/Remove breakpoint\n"); - wprintw(dbg.win_out,"F10/F11 - Step over / trace into instruction\n"); - wprintw(dbg.win_out,"Up/Down - Move code view cursor\n"); - wprintw(dbg.win_out,"Return - Enable command line input\n"); - wprintw(dbg.win_out,"D/E/S/X/B - Set data view to DS:SI/ES:DI/SS:SP/DS:DX/ES:BX\n"); - wprintw(dbg.win_out,"R/F - Scroll data view\n"); - wprintw(dbg.win_out,"V - Toggle additional info\n"); - wprintw(dbg.win_out,"Debugger commands (enter all values in hex or as register):\n"); - wprintw(dbg.win_out,"--------------------------------------------------------------------------\n"); - wprintw(dbg.win_out,"BP [segment]:[offset] - Set breakpoint\n"); - wprintw(dbg.win_out,"BPINT [intNr] * - Set interrupt breakpoint\n"); - wprintw(dbg.win_out,"BPINT [intNr] [ah] - Set interrupt breakpoint with ah\n"); + DEBUG_ShowMsg("Debugger keys:\n"); + DEBUG_ShowMsg("--------------------------------------------------------------------------\n"); + DEBUG_ShowMsg("F5 - Run.\n"); + DEBUG_ShowMsg("F9 - Set/Remove breakpoint.\n"); + DEBUG_ShowMsg("F10/F11 - Step over / trace into instruction.\n"); + DEBUG_ShowMsg("Up/Down - Move code view cursor.\n"); + DEBUG_ShowMsg("Return - Enable command line input.\n"); + DEBUG_ShowMsg("D/E/S/X/B - Set data view to DS:SI/ES:DI/SS:SP/DS:DX/ES:BX.\n"); + DEBUG_ShowMsg("R/F - Scroll data view.\n"); + DEBUG_ShowMsg("V - Toggle additional info.\n"); + DEBUG_ShowMsg("Debugger commands (enter all values in hex or as register):\n"); + DEBUG_ShowMsg("--------------------------------------------------------------------------\n"); + DEBUG_ShowMsg("BP [segment]:[offset] - Set breakpoint.\n"); + DEBUG_ShowMsg("BPINT [intNr] * - Set interrupt breakpoint.\n"); + DEBUG_ShowMsg("BPINT [intNr] [ah] - Set interrupt breakpoint with ah.\n"); #if C_HEAVY_DEBUG - wprintw(dbg.win_out,"BPM [segment]:[offset] - Set memory breakpoint (memory change)\n"); - wprintw(dbg.win_out,"BPPM [selector]:[offset]- Set pmode-memory breakpoint (memory change)\n"); - wprintw(dbg.win_out,"BPLM [linear address] - Set linear memory breakpoint (memory change)\n"); + DEBUG_ShowMsg("BPM [segment]:[offset] - Set memory breakpoint (memory change).\n"); + DEBUG_ShowMsg("BPPM [selector]:[offset]- Set pmode-memory breakpoint (memory change).\n"); + DEBUG_ShowMsg("BPLM [linear address] - Set linear memory breakpoint (memory change).\n"); #endif - wprintw(dbg.win_out,"BPLIST - List breakpoints\n"); - wprintw(dbg.win_out,"BPDEL [bpNr] / * - Delete breakpoint nr / all\n"); - wprintw(dbg.win_out,"C / D [segment]:[offset] - Set code / data view address\n"); - wprintw(dbg.win_out,"INT [nr] / INTT [nr] - Execute / Trace into Iinterrupt\n"); - wprintw(dbg.win_out,"LOG [num] - Write cpu log file\n"); + DEBUG_ShowMsg("BPLIST - List breakpoints.\n"); + DEBUG_ShowMsg("BPDEL [bpNr] / * - Delete breakpoint nr / all.\n"); + DEBUG_ShowMsg("C / D [segment]:[offset] - Set code / data view address.\n"); + DEBUG_ShowMsg("INT [nr] / INTT [nr] - Execute / Trace into interrupt.\n"); #if C_HEAVY_DEBUG - wprintw(dbg.win_out,"HEAVYLOG - Enable/Disable automatic cpu log for INT CD\n"); + DEBUG_ShowMsg("LOG [num] - Write cpu log file.\n"); + DEBUG_ShowMsg("HEAVYLOG - Enable/Disable automatic cpu when dosbox exits.\n"); #endif - wprintw(dbg.win_out,"SR [reg] [value] - Set register value\n"); - wprintw(dbg.win_out,"SM [seg]:[off] [val] [.]..- Set memory with following values\n"); + DEBUG_ShowMsg("SR [reg] [value] - Set register value.\n"); + DEBUG_ShowMsg("SM [seg]:[off] [val] [.]..- Set memory with following values.\n"); - wprintw(dbg.win_out,"IV [seg]:[off] [name] - Create var name for memory address\n"); - wprintw(dbg.win_out,"SV [filename] - Save var list in file\n"); - wprintw(dbg.win_out,"LV [seg]:[off] [name] - Load var list from file\n"); + DEBUG_ShowMsg("IV [seg]:[off] [name] - Create var name for memory address.\n"); + DEBUG_ShowMsg("SV [filename] - Save var list in file.\n"); + DEBUG_ShowMsg("LV [seg]:[off] [name] - Load var list from file.\n"); - wprintw(dbg.win_out,"MEMDUMP [seg]:[off] [len] - Write memory to file memdump.txt\n"); - wprintw(dbg.win_out,"SELINFO [segName] - Show selector info\n"); + DEBUG_ShowMsg("MEMDUMP [seg]:[off] [len] - Write memory to file memdump.txt.\n"); + DEBUG_ShowMsg("SELINFO [segName] - Show selector info.\n"); - wprintw(dbg.win_out,"INTVEC [filename] - Writes interrupt vector table to file\n"); - wprintw(dbg.win_out,"INTHAND [intNum] - Set code view to interrupt handler\n"); + DEBUG_ShowMsg("INTVEC [filename] - Writes interrupt vector table to file.\n"); + DEBUG_ShowMsg("INTHAND [intNum] - Set code view to interrupt handler.\n"); - wprintw(dbg.win_out,"H - Help\n"); + DEBUG_ShowMsg("H - Help\n"); - wrefresh(dbg.win_out); return TRUE; } return false; @@ -1287,6 +1285,81 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) strcat(inst," ("); strcat(inst,descr); strcat(inst,")"); } }; + // Must be a jump + if (instu[0] == 'J') + { + bool jmp = 0; + switch (instu[1]) { + case 'A' : { jmp = !GETFLAGBOOL(CF) && !GETFLAGBOOL(ZF); // JA + } break; + case 'B' : { if (instu[2] == 'E') { + jmp = GETFLAGBOOL(CF) && GETFLAGBOOL(ZF); // JBE + } else { + jmp = GETFLAGBOOL(CF); // JB + } + } break; + case 'C' : { if (instu[2] == 'X') { + jmp = reg_cx == 0; // JCXZ + } else { + jmp = GETFLAGBOOL(CF); // JC + } + } break; + case 'E' : { jmp = GETFLAGBOOL(ZF); // JE + } break; + case 'G' : { if (instu[2] == 'E') { + jmp = !GETFLAGBOOL(SF); // JGE + } else { + jmp = !GETFLAGBOOL(SF) && !GETFLAGBOOL(ZF); // JG + } + } break; + case 'L' : { if (instu[2] == 'E') { + jmp = GETFLAGBOOL(SF) || GETFLAGBOOL(ZF); // JLE + } else { + jmp = GETFLAGBOOL(SF); // JL + } + } break; + case 'M' : { jmp = true; // JMP + } break; + case 'N' : { switch (instu[2]) { + case 'B' : + case 'C' : { jmp = !GETFLAGBOOL(CF); // JNB / JNC + } break; + case 'E' : { jmp = !GETFLAGBOOL(ZF); // JNE + } break; + case 'O' : { jmp = !GETFLAGBOOL(OF); // JNO + } break; + case 'P' : { jmp = !GETFLAGBOOL(PF); // JNP + } break; + case 'S' : { jmp = !GETFLAGBOOL(SF); // JNS + } break; + case 'Z' : { jmp = !GETFLAGBOOL(ZF); // JNZ + } break; + } + } break; + case 'O' : { jmp = GETFLAGBOOL(OF); // JMP + } break; + case 'P' : { if (instu[2] == 'O') { + jmp = !GETFLAGBOOL(PF); // JPO + } else { + jmp = GETFLAGBOOL(SF); // JP / JPE + } + } break; + case 'S' : { jmp = GETFLAGBOOL(SF); // JS + } break; + case 'Z' : { jmp = GETFLAGBOOL(ZF); // JZ + } break; + } + if (jmp) { + pos = strchr(instu,'+'); + if (pos) { + strcpy(result,"(down)"); + } else { + strcpy(result,"(up)"); + } + } else { + sprintf(result,"(no jmp)"); + } + } return result; }; @@ -1366,7 +1439,7 @@ Bit32u DEBUG_CheckKeys(void) { ParseCommand(codeViewData.inputStr); break; case 'T' : DEBUG_RaiseTimerIrq(); - DEBUG_ShowMsg("Debug: Timer Int started."); + DEBUG_ShowMsg("Debug: Timer Int started.\n"); break; case 'V' : showExtend = !showExtend; break; @@ -1383,6 +1456,12 @@ Bit32u DEBUG_CheckKeys(void) { if (codeViewData.cursorPos>0) codeViewData.cursorPos--; else codeViewData.useEIP -= 1; break; + case KEY_HOME: // Home: scroll log page up + DEBUG_RefreshPage(-1); + break; + case KEY_END: // End: scroll log page down + DEBUG_RefreshPage(1); + break; case KEY_F(5): // Run Programm debugging=false; CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); @@ -1449,11 +1528,15 @@ Bitu DEBUG_Loop(void) { } void DEBUG_Enable(void) { - + static bool showhelp=false; debugging=true; SetCodeWinStart(); DEBUG_DrawScreen(); DOSBOX_SetLoop(&DEBUG_Loop); + if(!showhelp) { + showhelp=true; + DEBUG_ShowMsg("***| PRESS \"H\" TO SHOW ALL COMMANDS. PRESS \"RETURN\" TO ENTER COMMANDMODE. |***\n"); + } } void DEBUG_DrawScreen(void) { @@ -1684,7 +1767,7 @@ Bitu debugCallback; void DEBUG_Init(Section* sec) { - MSG_Add("DEBUG_CONFIGFILE_HELP","Nothing to setup yet!\n"); + MSG_Add("DEBUG_CONFIGFILE_HELP","Debugger related options.\n"); DEBUG_DrawScreen(); /* Add some keyhandlers */ MAPPER_AddHandler(DEBUG_Enable,MK_pause,0,"debugger","Debugger"); @@ -1694,7 +1777,7 @@ void DEBUG_Init(Section* sec) { PROGRAMS_MakeFile("DEBUG.COM",DEBUG_ProgramStart); /* Setup callback */ debugCallback=CALLBACK_Allocate(); - CALLBACK_Setup(debugCallback,DEBUG_EnableDebugger,CB_RETF); + CALLBACK_Setup(debugCallback,DEBUG_EnableDebugger,CB_RETF,"debugger"); /* shutdown function */ sec->AddDestroyFunction(&DEBUG_ShutDown); } @@ -1778,7 +1861,7 @@ static void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num) { FILE* f = fopen("MEMDUMP.TXT","wt"); if (!f) { - DEBUG_ShowMsg("DEBUG: Memory dump failed."); + DEBUG_ShowMsg("DEBUG: Memory dump failed.\n"); return; } @@ -1798,7 +1881,7 @@ static void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num) fprintf(f,"%s\n",buffer); }; fclose(f); - DEBUG_ShowMsg("DEBUG: Memory dump success."); + DEBUG_ShowMsg("DEBUG: Memory dump success.\n"); }; static void OutputVecTable(char* filename) @@ -1806,7 +1889,7 @@ static void OutputVecTable(char* filename) FILE* f = fopen(filename, "wt"); if (!f) { - DEBUG_ShowMsg("DEBUG: Output of interrupt vector table failed."); + DEBUG_ShowMsg("DEBUG: Output of interrupt vector table failed.\n"); return; } @@ -1814,7 +1897,7 @@ static void OutputVecTable(char* filename) fprintf(f,"INT %02X: %04X:%04X\n", i, mem_readw(i*4+2), mem_readw(i*4)); fclose(f); - DEBUG_ShowMsg("DEBUG: Interrupt vector table written to %s.", filename); + DEBUG_ShowMsg("DEBUG: Interrupt vector table written to %s.\n", filename); } #define DEBUG_VAR_BUF_LEN 16 @@ -1876,11 +1959,11 @@ void DEBUG_HeavyWriteLogInstruction(void) logHeavy = false; - DEBUG_ShowMsg("DEBUG: Creating cpu log LOGCPU_INT_CD.TXT"); + DEBUG_ShowMsg("DEBUG: Creating cpu log LOGCPU_INT_CD.TXT\n"); FILE* f = fopen("LOGCPU_INT_CD.TXT","wt"); if (!f) { - DEBUG_ShowMsg("DEBUG: Failed."); + DEBUG_ShowMsg("DEBUG: Failed.\n"); return; } @@ -1893,7 +1976,7 @@ void DEBUG_HeavyWriteLogInstruction(void) fclose(f); - DEBUG_ShowMsg("DEBUG: Done."); + DEBUG_ShowMsg("DEBUG: Done.\n"); }; bool DEBUG_HeavyIsBreakpoint(void) @@ -1907,7 +1990,7 @@ bool DEBUG_HeavyIsBreakpoint(void) } if (cpuLogCounter<=0) { fclose(cpuLogFile); - DEBUG_ShowMsg("DEBUG: cpu log LOGCPU.TXT created"); + DEBUG_ShowMsg("DEBUG: cpu log LOGCPU.TXT created\n"); cpuLog = false; DEBUG_EnableDebugger(); return true; diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 268fecfa..8e16c203 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -39,6 +39,8 @@ struct _LogGroup { static _LogGroup loggrp[LOG_MAX]={{"",true},{0,false}}; static FILE* debuglog; +static std::list logBuff; +static std::list::iterator logBuffPos = logBuff.end(); extern int old_cursor_state; @@ -51,9 +53,45 @@ void DEBUG_ShowMsg(char * format,...) { va_start(msg,format); vsprintf(buf,format,msg); va_end(msg); - wprintw(dbg.win_out,"%10d: %s\n",cycle_count,buf); + + /* Add newline if not present */ + Bitu len=strlen(buf); + if(buf[len-1]!='\n') strcat(buf,"\n"); + + if(debuglog) fprintf(debuglog,"%s",buf); + + char* newLine = new char[strlen(buf) + 1]; + strcpy(newLine, buf); + if (logBuffPos!=logBuff.end()) { + logBuffPos=logBuff.end(); + DEBUG_RefreshPage(0); + mvwprintw(dbg.win_out,dbg.win_out->_maxy, 0, ""); + } + logBuff.push_back(newLine); + if (logBuff.size()>500) { + char * firstline = logBuff.front(); + delete firstline; + logBuff.pop_front(); + } + logBuffPos = logBuff.end(); + wprintw(dbg.win_out,"%s",buf); + wrefresh(dbg.win_out); +} + +void DEBUG_RefreshPage(char scroll) { + if (scroll==-1 && logBuffPos!=logBuff.begin()) logBuffPos--; + else if (scroll==1 && logBuffPos!=logBuff.end()) logBuffPos++; + + std::list::iterator i = logBuffPos; + int rem_lines = dbg.win_out->_maxy; + + wclear(dbg.win_out); + + while (rem_lines > 0 && i!=logBuff.begin()) { + rem_lines -= (int) (strlen(*--i) / dbg.win_out->_maxx) + 1; + mvwprintw(dbg.win_out,rem_lines-1, 0, *i); + } wrefresh(dbg.win_out); - if(debuglog) fprintf(debuglog,"%10d: %s\n",cycle_count,buf); } void LOG::operator() (char* format, ...){ @@ -65,7 +103,7 @@ void LOG::operator() (char* format, ...){ if (d_type>=LOG_MAX) return; if ((d_severity!=LOG_ERROR) && (!loggrp[d_type].enabled)) return; - DEBUG_ShowMsg("%s:%s",loggrp[d_type].front,buf); + DEBUG_ShowMsg("%10d: %s:%s\n",cycle_count,loggrp[d_type].front,buf); } @@ -99,15 +137,15 @@ static void DrawBars(void) { attrset(COLOR_PAIR(PAIR_BLACK_BLUE)); } /* Show the Register bar */ - mvaddstr(dbg.win_reg->_begy-1,0,"---(Register Overview)---"); + mvaddstr(dbg.win_reg->_begy-1,0, "---(Register Overview )---"); /* Show the Data Overview bar perhaps with more special stuff in the end */ - mvaddstr(dbg.win_data->_begy-1,0,"---(Data Overview)---"); + mvaddstr(dbg.win_data->_begy-1,0,"---(Data Overview Scroll: r/f )---"); /* Show the Code Overview perhaps with special stuff in bar too */ - mvaddstr(dbg.win_code->_begy-1,0,"---(Code Overview)---"); + mvaddstr(dbg.win_code->_begy-1,0,"---(Code Overview Scroll: up/down )---"); /* Show the Variable Overview bar */ - mvaddstr(dbg.win_var->_begy-1,0,"---(Variable Overview)---"); + mvaddstr(dbg.win_var->_begy-1,0, "---(Variable Overview )---"); /* Show the Output OverView */ - mvaddstr(dbg.win_out->_begy-1,0,"---(OutPut/Input)---"); + mvaddstr(dbg.win_out->_begy-1,0, "---(OutPut/Input Scroll: home/end )---"); attrset(0); } diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index d3185601..412ef88a 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -719,7 +719,7 @@ static void MPU401_Reset(void) { void MPU401_Init(Section* sec) { call_irq9=CALLBACK_Allocate(); //allocate handler for irq 9 - CALLBACK_Setup(call_irq9,&INT71_Handler,CB_IRET); + CALLBACK_Setup(call_irq9,&INT71_Handler,CB_IRET,"irq 9 mpu"); RealSetVec(0x71,CALLBACK_RealPointer(call_irq9)); Section_prop * section=static_cast(sec); diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 7069b6ea..e617ee36 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.35 2004-08-04 09:12:56 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.36 2004-10-23 15:15:06 qbix79 Exp $ */ #include #include "dosbox.h" @@ -410,7 +410,7 @@ void BIOS_SetupKeyboard(void); void BIOS_SetupDisks(void); void BIOS_Init(Section* sec) { - MSG_Add("BIOS_CONFIGFILE_HELP","Nothing to setup yet!\n"); + MSG_Add("BIOS_CONFIGFILE_HELP","Nothing to setup yet!\n"); /* Clear the Bios Data Area */ for (Bit16u i=0;i<1024;i++) real_writeb(0x40,i,0); /* Setup all the interrupt handlers the bios controls */ @@ -418,7 +418,7 @@ void BIOS_Init(Section* sec) { //TODO Maybe give this a special callback that will also call int 8 instead of starting //a new system call_int8=CALLBACK_Allocate(); - CALLBACK_Setup(call_int8,&INT8_Handler,CB_IRET); + CALLBACK_Setup(call_int8,&INT8_Handler,CB_IRET,"Int 8 Clock"); phys_writeb(CB_BASE+(call_int8<<4)+0,(Bit8u)0xFE); //GRP 4 phys_writeb(CB_BASE+(call_int8<<4)+1,(Bit8u)0x38); //Extra Callback instruction phys_writew(CB_BASE+(call_int8<<4)+2,call_int8); //The immediate word @@ -434,44 +434,44 @@ void BIOS_Init(Section* sec) { RealSetVec(0x8,CALLBACK_RealPointer(call_int8)); /* INT 11 Get equipment list */ call_int11=CALLBACK_Allocate(); - CALLBACK_Setup(call_int11,&INT11_Handler,CB_IRET); + CALLBACK_Setup(call_int11,&INT11_Handler,CB_IRET,"Int 11 Equipment"); RealSetVec(0x11,CALLBACK_RealPointer(call_int11)); /* INT 12 Memory Size default at 640 kb */ call_int12=CALLBACK_Allocate(); - CALLBACK_Setup(call_int12,&INT12_Handler,CB_IRET); + CALLBACK_Setup(call_int12,&INT12_Handler,CB_IRET,"Int 12 Memory"); RealSetVec(0x12,CALLBACK_RealPointer(call_int12)); mem_writew(BIOS_MEMORY_SIZE,640); /* INT 13 Bios Disk Support */ BIOS_SetupDisks(); call_int14=CALLBACK_Allocate(); - CALLBACK_Setup(call_int14,&INT14_Handler,CB_IRET); + CALLBACK_Setup(call_int14,&INT14_Handler,CB_IRET,"Int 14 COM-port"); RealSetVec(0x14,CALLBACK_RealPointer(call_int14)); /* INT 15 Misc Calls */ call_int15=CALLBACK_Allocate(); - CALLBACK_Setup(call_int15,&INT15_Handler,CB_IRET); + CALLBACK_Setup(call_int15,&INT15_Handler,CB_IRET,"Int 15 Bios"); RealSetVec(0x15,CALLBACK_RealPointer(call_int15)); /* INT 16 Keyboard handled in another file */ BIOS_SetupKeyboard(); /* INT 16 Printer Routines */ call_int17=CALLBACK_Allocate(); - CALLBACK_Setup(call_int17,&INT17_Handler,CB_IRET); + CALLBACK_Setup(call_int17,&INT17_Handler,CB_IRET,"Int 17 Printer"); RealSetVec(0x17,CALLBACK_RealPointer(call_int17)); /* INT 1A TIME and some other functions */ call_int1a=CALLBACK_Allocate(); - CALLBACK_Setup(call_int1a,&INT1A_Handler,CB_IRET_STI); + CALLBACK_Setup(call_int1a,&INT1A_Handler,CB_IRET_STI,"Int 1a Time"); RealSetVec(0x1A,CALLBACK_RealPointer(call_int1a)); /* INT 1C System Timer tick called from INT 8 */ call_int1c=CALLBACK_Allocate(); - CALLBACK_Setup(call_int1c,&INT1C_Handler,CB_IRET); + CALLBACK_Setup(call_int1c,&INT1C_Handler,CB_IRET,"Int 1c Timer tick"); RealSetVec(0x1C,CALLBACK_RealPointer(call_int1c)); /* IRQ 8 RTC Handler */ call_int70=CALLBACK_Allocate(); - CALLBACK_Setup(call_int70,&INT70_Handler,CB_IRET); + CALLBACK_Setup(call_int70,&INT70_Handler,CB_IRET,"Int 70 RTC"); RealSetVec(0x70,CALLBACK_RealPointer(call_int70)); /* Some defeault CPU error interrupt handlers */ call_int1=CALLBACK_Allocate(); - CALLBACK_Setup(call_int1,&INT1_Single_Step,CB_IRET); + CALLBACK_Setup(call_int1,&INT1_Single_Step,CB_IRET,"Int 1 Single step"); RealSetVec(0x1,CALLBACK_RealPointer(call_int1)); /* Setup some stuff in 0x40 bios segment */ diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 892701d0..be354e73 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -403,7 +403,7 @@ void BIOS_SetupDisks(void) { /* TODO Start the time correctly */ call_int13=CALLBACK_Allocate(); //CALLBACK_Setup(call_int13,&INT13_SmallHandler,CB_IRET); - CALLBACK_Setup(call_int13,&INT13_DiskHandler,CB_IRET); + CALLBACK_Setup(call_int13,&INT13_DiskHandler,CB_IRET,"Int 13 Bios disk"); RealSetVec(0x13,CALLBACK_RealPointer(call_int13)); int i; for(i=0;i<4;i++) { diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index c0faac71..8389567a 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.35 2004-10-17 14:45:00 qbix79 Exp $ */ +/* $Id: ems.cpp,v 1.36 2004-10-23 15:15:06 qbix79 Exp $ */ #include #include @@ -610,14 +610,14 @@ static Bitu INT4B_Handler() { void EMS_Init(Section* sec) { /* Virtual DMA interrupt callback */ call_vdma=CALLBACK_Allocate(); - CALLBACK_Setup(call_vdma,&INT4B_Handler,CB_IRET); + CALLBACK_Setup(call_vdma,&INT4B_Handler,CB_IRET,"Int 4b vdma"); RealSetVec(0x4b,CALLBACK_RealPointer(call_vdma)); Section_prop * section=static_cast(sec); if (!section->Get_bool("ems")) return; BIOS_ZeroExtendedSize(); call_int67=CALLBACK_Allocate(); - CALLBACK_Setup(call_int67,&INT67_Handler,CB_IRET); + CALLBACK_Setup(call_int67,&INT67_Handler,CB_IRET,"Int 67 ems"); /* Register the ems device */ DOS_Device * newdev = new device_EMM(); DOS_AddDevice(newdev); diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index de170ea3..975d7ac3 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -467,7 +467,7 @@ void INT10_Init(Section* sec) { if (machine==MCH_TANDY) SetupTandyBios(); /* Setup the INT 10 vector */ call_10=CALLBACK_Allocate(); - CALLBACK_Setup(call_10,&INT10_Handler,CB_IRET); + CALLBACK_Setup(call_10,&INT10_Handler,CB_IRET,"Int 10 video"); RealSetVec(0x10,CALLBACK_RealPointer(call_10)); //Init the 0x40 segment and init the datastructures in the the video rom area INT10_SetupRomMemory(); diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index a6ffc200..aafc081b 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.15 2004-09-16 21:47:39 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.16 2004-10-23 15:15:07 qbix79 Exp $ */ #include #include @@ -220,7 +220,7 @@ static void CONFIG_ProgramStart(Program * * make) { void PROGRAMS_Init(Section* sec) { /* Setup a special callback to start virtual programs */ call_program=CALLBACK_Allocate(); - CALLBACK_Setup(call_program,&PROGRAMS_Handler,CB_RETF); + CALLBACK_Setup(call_program,&PROGRAMS_Handler,CB_RETF,"internal program"); PROGRAMS_MakeFile("CONFIG.COM",CONFIG_ProgramStart); MSG_Add("PROGRAM_CONFIG_FILE_ERROR","Can't open file %s\n"); diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 4d38efc5..1b208432 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.50 2004-10-17 14:45:00 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.51 2004-10-23 15:15:07 qbix79 Exp $ */ #include #include @@ -302,13 +302,17 @@ void SHELL_Init() { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n" "\xBA \033[32mDOSBox Shell v" VERSION "\033[37m \xBA\n" "\xBA DOSBox runs real and protected mode games. \xBA\n" - "\xBA For supported shell commands type: \033[1;33mHELP\033[37m \xBA\n" + "\xBA For supported shell commands type: \033[33mHELP\033[37m \xBA\n" "\xBA For a short introduction type: \033[33mINTRO\033[37m \xBA\n" "\xBA \xBA\n" "\xBA If you want more speed, try \033[31mctrl-F8\033[37m and \033[31mctrl-F12\033[37m. \xBA\n" "\xBA To activate the keymapper \033[31mctrl-F1\033[37m. \xBA\n" "\xBA For more information read the \033[36mREADME\033[37m file in the DOSBox directory. \xBA\n" "\xBA \xBA\n" +#if C_DEBUG + "\xBA Press \033[31mPause\033[37m to enter the debugger or start the exe with \033[33mDEBUG\033[37m. \xBA\n" + "\xBA \xBA\n" +#endif "\xBA \033[32mHAVE FUN!\033[37m \xBA\n" "\xBA \033[32mThe DOSBox Team\033[37m \xBA\n" "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" @@ -347,7 +351,7 @@ void SHELL_Init() { SegSet16(cs,RealSeg(newcsip)); reg_ip=RealOff(newcsip); - CALLBACK_Setup(call_shellstop,shellstop_handler,CB_IRET); + CALLBACK_Setup(call_shellstop,shellstop_handler,CB_IRET,"shell stop"); PROGRAMS_MakeFile("COMMAND.COM",SHELL_ProgramStart); /* Now call up the shell for the first time */ From 4d7944fe9c214bf08deab5ef8b25568d31068968 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 23 Oct 2004 15:25:47 +0000 Subject: [PATCH 1953/4131] Fix carry flag for ROR instructions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2036 --- src/cpu/instructions.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index a69324ff..2e27ae5e 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -269,7 +269,7 @@ lf_resb=(lf_var1b >> lf_var2b) | \ (lf_var1b << (8-lf_var2b)); \ save(op1,lf_resb); \ - SETFLAGBIT(CF,lf_resb & 1); \ + SETFLAGBIT(CF,lf_resb & 0x80); \ if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resb ^ lf_var1b) & 0x80); #define RORW(op1,op2,load,save) \ @@ -280,7 +280,7 @@ lf_resw=(lf_var1w >> lf_var2b) | \ (lf_var1w << (16-lf_var2b)); \ save(op1,lf_resw); \ - SETFLAGBIT(CF,lf_resw & 1); \ + SETFLAGBIT(CF,lf_resw & 0x8000); \ if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resw ^ lf_var1w) & 0x8000); #define RORD(op1,op2,load,save) \ @@ -291,7 +291,7 @@ lf_resd=(lf_var1d >> lf_var2b) | \ (lf_var1d << (32-lf_var2b)); \ save(op1,lf_resd); \ - SETFLAGBIT(CF,lf_resd & 1); \ + SETFLAGBIT(CF,lf_resd & 0x80000000); \ if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resd ^ lf_var1d) & 0x80000000); From 32d35dc207ef405f98b066f091ed29dce8bf55ff Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 23 Oct 2004 17:54:36 +0000 Subject: [PATCH 1954/4131] Fix security hole Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2037 --- src/misc/programs.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index aafc081b..e720665a 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -16,8 +16,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.16 2004-10-23 15:15:07 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.17 2004-10-23 17:54:36 qbix79 Exp $ */ +#include #include #include #include @@ -47,14 +48,20 @@ static Bit8u exe_block[]={ #define CB_POS 12 +static std::vector internal_progs; + void PROGRAMS_MakeFile(char * name,PROGRAMS_Main * main) { Bit8u * comdata=(Bit8u *)malloc(128); memcpy(comdata,&exe_block,sizeof(exe_block)); comdata[CB_POS]=call_program&0xff; comdata[CB_POS+1]=(call_program>>8)&0xff; -/* Copy the pointer this should preserve endianes */ - memcpy(&comdata[sizeof(exe_block)],&main,sizeof(main)); - Bit32u size=sizeof(exe_block)+sizeof(main); + + /* Copy save the pointer in the vector and save it's index */ + Bit8u index = internal_progs.size(); + internal_progs.push_back(main); + + memcpy(&comdata[sizeof(exe_block)],&index,sizeof(index)); + Bit32u size=sizeof(exe_block)+sizeof(index); VFILE_Register(name,comdata,size); } @@ -62,13 +69,15 @@ void PROGRAMS_MakeFile(char * name,PROGRAMS_Main * main) { static Bitu PROGRAMS_Handler(void) { /* This sets up everything for a program start up call */ - PROGRAMS_Main * handler=0; //It will get sneakily itinialized - Bitu size=sizeof(PROGRAMS_Main *); - /* Read the handler from program code in memory */ + Bitu size=sizeof(Bit8u); + Bit8u index; + /* Read the index from program code in memory */ PhysPt reader=PhysMake(dos.psp(),256+sizeof(exe_block)); - HostPt writer=(HostPt)&handler; + HostPt writer=(HostPt)&index; for (;size>0;size--) *writer++=mem_readb(reader++); Program * new_program; + if(index > internal_progs.size()) E_Exit("something is messing with the memory"); + PROGRAMS_Main * handler = internal_progs[index]; (*handler)(&new_program); new_program->Run(); delete new_program; From b34e3422af52b2ec7316b1a01635e4d0b688e8f2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 24 Oct 2004 08:54:01 +0000 Subject: [PATCH 1955/4131] Small bugfix by Hendrik Jan Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2038 --- src/debug/debug_gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 8e16c203..d9809ff3 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -65,7 +65,7 @@ void DEBUG_ShowMsg(char * format,...) { if (logBuffPos!=logBuff.end()) { logBuffPos=logBuff.end(); DEBUG_RefreshPage(0); - mvwprintw(dbg.win_out,dbg.win_out->_maxy, 0, ""); + mvwprintw(dbg.win_out,dbg.win_out->_maxy-1, 0, ""); } logBuff.push_back(newLine); if (logBuff.size()>500) { From ee91571aff3789330eb66a85e0a59247e93573a1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 24 Oct 2004 10:03:29 +0000 Subject: [PATCH 1956/4131] messed up one function with the last signed/unsigned things. (Moe) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2039 --- src/misc/support.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 993477b7..4f362477 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.26 2004-10-17 14:54:41 qbix79 Exp $ */ +/* $Id: support.cpp,v 1.27 2004-10-24 10:03:29 qbix79 Exp $ */ #include #include @@ -84,7 +84,7 @@ bool ScanCMDBool(char * cmd,char * check) { char * ScanCMDRemain(char * cmd) { char * scan,*found;; if ((scan=found=strchr(cmd,'/'))) { - while (*scan && isspace(*reinterpret_cast(scan))!=0) scan++; + while ( *scan && !isspace(*reinterpret_cast(scan)) ) scan++; *scan=0; return found; } else return 0; From 6e671b7171852cd22bcab06f6955253f42026663 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 Oct 2004 21:08:47 +0000 Subject: [PATCH 1957/4131] some string size bugs Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2040 --- src/dos/dos_devices.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index f8b442c0..2628568d 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_devices.cpp,v 1.7 2004-10-20 12:27:19 qbix79 Exp $ */ +/* $Id: dos_devices.cpp,v 1.8 2004-10-25 21:08:47 qbix79 Exp $ */ #include #include "dosbox.h" @@ -87,7 +87,7 @@ DOS_File::DOS_File(const DOS_File& orig) { open=orig.open; name=0; if(orig.name) { - name=new char [strlen(orig.name)];strcpy(name,orig.name); + name=new char [strlen(orig.name) + 1];strcpy(name,orig.name); } } @@ -104,7 +104,7 @@ DOS_File & DOS_File::operator= (const DOS_File & orig) { delete [] name; name=0; } if(orig.name) { - name=new char [strlen(orig.name)];strcpy(name,orig.name); + name=new char [strlen(orig.name) + 1];strcpy(name,orig.name); } return *this; } @@ -112,7 +112,7 @@ DOS_File & DOS_File::operator= (const DOS_File & orig) { Bit8u DOS_FindDevice(char * name) { /* should only check for the names before the dot and spacepadded */ char temp[CROSS_LEN];//TODOD - if(!(*name)) return DOS_DEVICES; + if(!name || !(*name)) return DOS_DEVICES; strcpy(temp,name); char* dot= strrchr(temp,'.'); if(dot && *dot) dot=0; //no ext checking From d439d5eb74694d7e89d2006ce1d6c22d23c142d2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 Oct 2004 21:16:30 +0000 Subject: [PATCH 1958/4131] Fix crashes if the first section is non existant Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2041 --- src/misc/setup.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 23171e4e..8f3fe75d 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.22 2004-08-04 09:12:56 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.23 2004-10-25 21:16:30 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -291,7 +291,7 @@ bool Config::ParseConfigFile(const char* configfilename){ break; default: try{ - currentsection->HandleInputline(s); + if(currentsection) currentsection->HandleInputline(s); }catch(const char* message){ message=0; //EXIT with message From 1c44f564ca7471323975a4231eaabd6bdd4d0751 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 26 Oct 2004 18:18:22 +0000 Subject: [PATCH 1959/4131] Clarification Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2042 --- src/dos/dos_programs.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 773f8c59..287fe58c 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.31 2004-10-17 16:00:57 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.32 2004-10-26 18:18:22 qbix79 Exp $ */ #include #include @@ -736,24 +736,24 @@ void DOS_SetupPrograms(void) { "The \033[33mbasic\033[0m level works on all CD-ROM drives and normal directories.\n" "It installs MSCDEX and marks the files read-only.\n" "Usually this is enough for most games:\n" - "\033[34;1mmount d D:\\ -t cdrom\033[0m or \033[34;1mmount d C:\\example -t cdrom\033[0m\n" + "\033[34;1mmount d \033[0;31mD:\\\033[34;1m -t cdrom\033[0m or \033[34;1mmount d C:\\example -t cdrom\033[0m\n" "If it doesn't work you might have to tell DOSBox the label of the CD-ROM:\n" "\033[34;1mmount d C:\\example -t cdrom -label CDLABEL\033[0m\n" "\n" "The \033[33mnext\033[0m level adds some low-level support.\n" "Therefore only works on CD-ROM drives:\n" - "\033[34;1mmount d D:\\ -t cdrom -usecd \033[33m0\033[0m\n" + "\033[34;1mmount d \033[0;31mD:\\\033[34;1m -t cdrom -usecd \033[33m0\033[0m\n" "\n" "The \033[33mlast\033[0m level of support depends on your Operating System:\n" "For \033[1mWindows 2000\033[0m, \033[1mWindows XP\033[0m and \033[1mLinux\033[0m:\n" - "\033[34;1mmount d D:\\ -t cdrom -usecd \033[33m0 \033[34m-ioctl\033[0m\n" + "\033[34;1mmount d \033[0;31mD:\\\033[34;1m -t cdrom -usecd \033[33m0 \033[34m-ioctl\033[0m\n" "For \033[1mWindows 9x\033[0m with a ASPI layer installed:\n" - "\033[34;1mmount d D:\\ -t cdrom -usecd \033[33m0 \033[34m-aspi\033[0m\n" + "\033[34;1mmount d \033[0;31mD:\\\033[34;1m -t cdrom -usecd \033[33m0 \033[34m-aspi\033[0m\n" "\n" + "Replace \033[0;31mD:\\\033[0m with the location of your CD-ROM.\n" "Replace the \033[33;1m0\033[0m in \033[34;1m-usecd \033[33m0\033[0m with the number reported for your CD-ROM if you type:\n" "\033[34;1mmount -cd\033[0m" ); - MSG_Add("PROGRAM_BOOT_NOT_EXIST","Bootdisk file does not exist. Failing.\n"); MSG_Add("PROGRAM_BOOT_NOT_OPEN","Cannot open bootdisk file. Failing.\n"); MSG_Add("PROGRAM_BOOT_PRINT_ERROR","This command boots DosBox from either a floppy or hard disk image.\n\n" From 5ed600377f1a20822d9936cb43694a86c1a7ba8d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 26 Oct 2004 18:28:51 +0000 Subject: [PATCH 1960/4131] more typesafe Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2043 --- include/shell.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/shell.h b/include/shell.h index 9c16f63f..6f0b083f 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.7 2004-09-09 18:36:50 qbix79 Exp $ */ +/* $Id: shell.h,v 1.8 2004-10-26 18:28:51 qbix79 Exp $ */ #ifndef SHELL_H_ #define SHELL_H_ @@ -118,7 +118,7 @@ struct SHELL_Cmd { }; static inline void StripSpaces(char*&args) { - while(*args && ((*args == ' ') || (*args == '\t'))) + while(args && *args && isspace(*reinterpret_cast(args))) args++; } From e4f42ccda589595367bd89ba86d907b97e17a5ad Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 28 Oct 2004 14:46:15 +0000 Subject: [PATCH 1961/4131] changed assertion Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2044 --- src/gui/sdl_mapper.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index af3f10d8..54058f74 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.9 2004-10-02 11:23:07 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.10 2004-10-28 14:46:15 qbix79 Exp $ */ #define OLD_JOYSTICK 1 @@ -335,7 +335,8 @@ public: CStickBindGroup(Bitu _stick) : CBindGroup (){ stick=_stick; sprintf(configname,"stick_%d",stick); - assert(sdl_joystick=SDL_JoystickOpen(stick)); + sdl_joystick=SDL_JoystickOpen(stick); + assert(sdl_joystick); axes=SDL_JoystickNumAxes(sdl_joystick); buttons=SDL_JoystickNumButtons(sdl_joystick); hats=SDL_JoystickNumHats(sdl_joystick); From 53ac3c967d703b0e3733adf4f71e7215da2e18ed Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 30 Oct 2004 12:11:29 +0000 Subject: [PATCH 1962/4131] Change extended key codes (wd) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2045 --- src/ints/bios_keyboard.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 8e30c843..eb3fdb3c 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -304,14 +304,20 @@ static Bitu IRQ1_Handler(void) { case 0x53: /* del . Not entirely correct, but works fine */ if(flags3 &0x02) { /*extend key. e.g key above arrows or arrows*/ if(scancode == 0x52) flags2 |=0x80; /* press insert */ - add_key((scancode <<8)|0xe0); + if(flags1 &0x08) { + add_key(scan_to_scanascii[scancode].normal+0x5000); + } else if( ((flags1 &0x3) != 0) ^ ((flags1 &0x20) != 0) ) { + add_key((scan_to_scanascii[scancode].shift&0xff00)|0xe0); + } else if (flags1 &0x04) { + add_key((scan_to_scanascii[scancode].control&0xff00)|0xe0); + } else add_key((scan_to_scanascii[scancode].normal&0xff00)|0xe0); break; } if(flags1 &0x08) { Bit8u token = mem_readb(BIOS_KEYBOARD_TOKEN); token= token*10 + scan_to_scanascii[scancode].alt; mem_writeb(BIOS_KEYBOARD_TOKEN,token); - } else if( ((flags1 &0x3)!=0) ^ ((flags1 &0x20) !=0) ) { + } else if( ((flags1 &0x3) != 0) ^ ((flags1 &0x20) != 0) ) { add_key(scan_to_scanascii[scancode].shift); } else if (flags1 &0x04) { add_key(scan_to_scanascii[scancode].control); From b089c229972c9213dee2fd276e88e1a339b583a5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 3 Nov 2004 20:13:40 +0000 Subject: [PATCH 1963/4131] don't overwrite allocated buffer in country information (int 21 6501) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2046 --- include/dos_inc.h | 3 +- src/dos/dos.cpp | 64 +++++++++++++----------------------------- src/dos/dos_tables.cpp | 33 ++++++++++++++++++++-- 3 files changed, 53 insertions(+), 47 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 6f3bb3a5..2f81cfe4 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.49 2004-10-17 14:44:59 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.50 2004-11-03 20:13:40 qbix79 Exp $ */ #ifndef DOS_H_ #define DOS_H_ @@ -571,6 +571,7 @@ struct DOS_Block { RealPt mediaid; RealPt tempdta; RealPt dcbs; + Bit8u* country;//Will be copied to dos memory. resides in real mem } tables; }; diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 6ed77c35..58b8175c 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.75 2004-09-21 20:04:55 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.76 2004-11-03 20:13:40 qbix79 Exp $ */ #include #include @@ -36,7 +36,6 @@ DOS_InfoBlock dos_infoblock; Bit8u dos_copybuf[0x10000]; static Bitu call_20,call_21,call_25,call_26,call_27,call_28,call_29; -static Bitu call_casemap; void DOS_SetError(Bit16u code) { dos.errorcode=code; @@ -401,18 +400,8 @@ static Bitu DOS_21Handler(void) { break; case 0x38: /* Set Country Code */ if (reg_al==0) { /* Get country specidic information */ - PhysPt pt = SegPhys(ds)+reg_dx; - mem_writew(pt ,0x00); // USA - mem_writeb(pt+ 2, '$'); mem_writeb(pt+ 3,0x00); - mem_writeb(pt+ 7, '.'); mem_writeb(pt+ 8,0x00); - mem_writeb(pt+ 9, '.'); mem_writeb(pt+10,0x00); - mem_writeb(pt+11, '.'); mem_writeb(pt+12,0x00); - mem_writeb(pt+13, '.'); mem_writeb(pt+14,0x00); - mem_writeb(pt+15,0x01); // currency format - mem_writeb(pt+16,0x02); // num digits - mem_writeb(pt+17,0x00); // time format - mem_writed(pt+18,CALLBACK_RealPointer(call_casemap)); - mem_writew(pt+22,0x00); // data list seperator + PhysPt dest = SegPhys(ds)+reg_dx; + MEM_BlockWrite(dest,dos.tables.country,0x22); reg_bx = 0x01; CALLBACK_SCF(false); break; @@ -634,8 +623,7 @@ static Bitu DOS_21Handler(void) { case 0x00: reg_ax=0x4c00; /* Terminate Program */ case 0x4c: /* EXIT Terminate with return code */ - - { + { if (DOS_Terminate(false)) { /* This can't ever return false normally */ } else { @@ -814,30 +802,25 @@ static Bitu DOS_21Handler(void) { E_Exit("Unhandled Dos 21 call %02X",reg_ah); break; case 0x65: /* Get extented country information and a lot of other useless shit*/ - /* Todo maybe fully support this for now we set it standard for USA */ - { - LOG(LOG_DOSMISC,LOG_ERROR)("DOS:65:Extended country information call"); + { /* Todo maybe fully support this for now we set it standard for USA */ + LOG(LOG_DOSMISC,LOG_ERROR)("DOS:65:Extended country information call %X",reg_ax); + if(reg_cx < 0x05 ) { + DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); + CALLBACK_SCF(true); + break; + } PhysPt data=SegPhys(es)+reg_di; switch (reg_al) { case 1: - mem_writeb(data,reg_al); - mem_writew(data+0x01,0x1c); - mem_writew(data+0x03,1); - mem_writew(data+0x05,0x01b5); - mem_writew(data+0x07,0x0000); // date format - mem_writeb(data+0x08,0x24); // currency symbol - mem_writew(data+0x0a,0x0000); - mem_writew(data+0x0c,0x0000); - mem_writew(data+0x0e,0x002c); // thousands separator - mem_writew(data+0x10,0x002e); // decimal separator - mem_writew(data+0x12,0x002d); // date separator - mem_writew(data+0x14,0x003a); // time separator - mem_writeb(data+0x16,0x00); // currency format - mem_writeb(data+0x17,0x02); // digits after decimal in currency - mem_writeb(data+0x18,0x00); // time format - mem_writed(data+0x19,CALLBACK_RealPointer(call_casemap)); - mem_writew(data+0x1d,0x002c); // list separator - reg_cx=0x1f; + mem_writeb(data + 0x00,reg_al); + mem_writew(data + 0x01,0x26); + mem_writew(data + 0x03,1); + if(reg_cx > 0x06 ) mem_writew(data+0x05,0x01b5); + if(reg_cx > 0x08 ) { + Bitu amount = (reg_cx>=0x29)?0x22:(reg_cx-7); + MEM_BlockWrite(data + 0x07,dos.tables.country,amount); + reg_cx=(reg_cx>=0x29)?0x29:reg_cx; + } CALLBACK_SCF(false); break; case 2: // Get pointer to uppercase table @@ -980,10 +963,6 @@ static Bitu DOS_29Handler(void) { return CBRET_NONE; } -static Bitu DOS_CaseMapFunc(void) { - //LOG(LOG_DOSMISC,LOG_ERROR)("Case map routine called : %c",reg_al); - return CBRET_NONE; -}; void DOS_ShutDown(Section* sec) { @@ -1044,8 +1023,5 @@ void DOS_Init(Section* sec) { /* shutdown function */ sec->AddDestroyFunction(&DOS_ShutDown); - /* case map routine INT 0x21 0x38 */ - call_casemap = CALLBACK_Allocate(); - CALLBACK_Setup(call_casemap,DOS_CaseMapFunc,CB_RETF,"DOS CaseMap"); } diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 0d41577b..3d771449 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,11 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.15 2004-09-21 20:04:55 qbix79 Exp $ */ +/* $Id: dos_tables.cpp,v 1.16 2004-11-03 20:13:40 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" #include "dos_inc.h" +#include "callback.h" #ifdef _MSC_VER #pragma pack(1) @@ -37,6 +38,8 @@ GCC_ATTRIBUTE (packed); RealPt DOS_TableUpCase; RealPt DOS_TableLowCase; +static Bitu call_casemap; + static Bit16u dos_memseg; Bit16u sdaseg; @@ -49,6 +52,26 @@ Bit16u DOS_GetMemory(Bit16u pages) { return page; } +static Bitu DOS_CaseMapFunc(void) { + //LOG(LOG_DOSMISC,LOG_ERROR)("Case map routine called : %c",reg_al); + return CBRET_NONE; +} + +static Bit8u country_info[0x22] = { +/* Date format */ 0x00, 0x00, +/* Currencystring */ 0x24, 0x00, 0x00, 0x00, 0x00, +/* Thousands sep */ 0x2c, 0x00, +/* Decimal sep */ 0x2e, 0x00, +/* Date sep */ 0x2d, 0x00, +/* time sep */ 0x3a, 0x00, +/* currency form */ 0x00, +/* digits after dec */ 0x02, +/* Time format */ 0x00, +/* Casemap */ 0x00, 0x00, 0x00, 0x00, +/* Data sep */ 0x2c, 0x00, +/* Reservered 5 */ 0x00, 0x00, 0x00, 0x00, 0x00, +/* Reservered 5 */ 0x00, 0x00, 0x00, 0x00, 0x00 +}; void DOS_SetupTables(void) { dos_memseg=0xd000; @@ -114,5 +137,11 @@ void DOS_SetupTables(void) { /* Set buffers to a nice value */ dos_infoblock.SetBuffers(50,50); - + + /* case map routine INT 0x21 0x38 */ + call_casemap = CALLBACK_Allocate(); + CALLBACK_Setup(call_casemap,DOS_CaseMapFunc,CB_RETF,"DOS CaseMap"); + /* Add it to country structure */ + host_writed(country_info + 0x12, CALLBACK_RealPointer(call_casemap)); + dos.tables.country=country_info; } From e9df6e56ab0fbdd3b38b6fb64064375c43333c4b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 3 Nov 2004 23:13:55 +0000 Subject: [PATCH 1964/4131] Change fpu for Elvira. Added isRemovable to drive for dott.cd and alike. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2047 --- include/dos_system.h | 3 ++- src/dos/dos_ioctl.cpp | 12 ++++++++---- src/dos/drive_fat.cpp | 5 +++-- src/dos/drive_iso.cpp | 7 ++++++- src/dos/drive_local.cpp | 10 +++++++++- src/dos/drive_virtual.cpp | 4 ++++ src/dos/drives.h | 11 ++++++++--- src/fpu/fpu_instructions.h | 4 +++- 8 files changed, 43 insertions(+), 13 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index ef29576a..66d28cde 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.26 2004-10-20 12:27:18 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.27 2004-11-03 23:13:53 qbix79 Exp $ */ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ @@ -242,6 +242,7 @@ public: 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; char * GetInfo(void); char curdir[DOS_PATHLENGTH]; char info[256]; diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index d50cc386..3c9995a6 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.20 2004-08-04 09:12:53 qbix79 Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.21 2004-11-03 23:13:54 qbix79 Exp $ */ #include #include "dosbox.h" @@ -41,8 +41,9 @@ bool DOS_IOCTL(void) { switch(reg_al) { case 0x00: /* Get Device Information */ reg_dx=Files[handle]->GetInformation(); + reg_ax=reg_dx; //Destroyed officially return true; - case 0x06: /* Get Input Status */ + case 0x06: /* Get Input Status */ if (Files[handle]->GetInformation() & 0x8000) { //Check for device reg_al=(Files[handle]->GetInformation() & 0x40) ? 0x0 : 0xff; } else { // FILE @@ -67,8 +68,11 @@ bool DOS_IOCTL(void) { case 0x08: /* Check if block device removable */ drive=reg_bl;if (!drive) drive=dos.current_drive;else drive--; if (Drives[drive]) { - if (drive<2) reg_ax=0; /* Drive a,b are removable if mounted */ - else reg_ax=1; + /* Drive a,b are removable if mounted * + * So are cdrom drives */ + if (drive < 2 || Drives[drive]->isRemovable()) + reg_ax=0; + else reg_ax=1; return true; } else { DOS_SetError(DOSERR_INVALID_DRIVE); diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index a0e6d7bb..71bfd157 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.5 2004-09-05 14:23:04 qbix79 Exp $ */ +/* $Id: drive_fat.cpp,v 1.6 2004-11-03 23:13:54 qbix79 Exp $ */ #include #include @@ -698,7 +698,8 @@ Bit32u fatDrive::getFirstFreeClust(void) { } -bool fatDrive::isRemote(void) { return false; } +bool fatDrive::isRemote(void) { return false; } +bool fatDrive::isRemovable(void) { return false; } Bit8u fatDrive::GetMediaByte(void) { return loadedDisk->GetBiosType(); } diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index fb62e694..acb549e6 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.3 2004-10-05 21:18:48 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.4 2004-11-03 23:13:55 qbix79 Exp $ */ #include #include @@ -367,6 +367,11 @@ bool isoDrive::isRemote(void) return true; } +bool isoDrive::isRemovable(void) +{ + return true; +} + inline bool isoDrive :: readSector(Bit8u *buffer, Bit32u sector) { return CDROM_Interface_Image::images[subUnit]->ReadSector(buffer, false, sector); diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 2b216eed..9393e4f5 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.52 2004-10-12 09:42:25 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.53 2004-11-03 23:13:55 qbix79 Exp $ */ #include #include @@ -366,6 +366,10 @@ bool localDrive::isRemote(void) { return false; } +bool localDrive::isRemovable(void) { + return false; +} + localDrive::localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid) { strcpy(basedir,startdir); sprintf(info,"local directory %s",startdir); @@ -572,3 +576,7 @@ void cdromDrive::SetDir(const char* path) bool cdromDrive::isRemote(void) { return true; } + +bool cdromDrive::isRemovable(void) { + return true; +} diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index e12ad737..d9321c54 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -236,3 +236,7 @@ Bit8u Virtual_Drive::GetMediaByte(void) { bool Virtual_Drive::isRemote(void) { return false; } + +bool Virtual_Drive::isRemovable(void) { + return false; +} diff --git a/src/dos/drives.h b/src/dos/drives.h index e5de809f..16f6d670 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.24 2004-10-05 19:55:03 qbix79 Exp $ */ +/* $Id: drives.h,v 1.25 2004-11-03 23:13:55 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ @@ -49,6 +49,7 @@ public: virtual bool FileStat(const char* name, FileStat_Block * const stat_block); virtual Bit8u GetMediaByte(void); virtual bool isRemote(void); + virtual bool isRemovable(void); private: char basedir[CROSS_LEN]; friend void DOS_Shell::CMD_SUBST(char* args); @@ -140,6 +141,7 @@ public: virtual bool FileStat(const char* name, FileStat_Block * const stat_block); virtual Bit8u GetMediaByte(void); virtual bool isRemote(void); + virtual bool isRemovable(void); public: Bit32u getAbsoluteSectFromBytePos(Bit32u startClustNum, Bit32u bytePos); Bit32u getSectorSize(void); @@ -200,6 +202,7 @@ public: virtual bool FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst=false); virtual void SetDir(const char* path); virtual bool isRemote(void); + virtual bool isRemovable(void); private: Bit8u subUnit; }; @@ -295,6 +298,7 @@ public: virtual Bit8u GetMediaByte(void); virtual void EmptyCache(void){} virtual bool isRemote(void); + virtual bool isRemovable(void); bool readSector(Bit8u *buffer, Bit32u sector); private: int readDirEntry(isoDirEntry *de, Bit8u *data); @@ -326,11 +330,12 @@ public: bool GetFileAttr(char * name,Bit16u * attr); bool Rename(char * oldname,char * newname); bool AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters); - bool FileExists(const char* name); - bool FileStat(const char* name, FileStat_Block* const stat_block); + bool FileExists(const char* name); + bool FileStat(const char* name, FileStat_Block* const stat_block); Bit8u GetMediaByte(void); void EmptyCache(void){} bool isRemote(void); + virtual bool isRemovable(void); private: VFILE_Block * search_file; }; diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 539f3b10..3f681853 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.24 2004-10-13 19:26:26 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.25 2004-11-03 23:13:55 qbix79 Exp $ */ static void FPU_FINIT(void) { @@ -322,6 +322,8 @@ static void FPU_ST80(PhysPt addr,Bitu reg) Bit64s exp80final= (exp80>>52) - BIAS64 + BIAS80; Bit64s mant80 = fpu.regs[reg].ll&LONGTYPE(0x000fffffffffffff); Bit64s mant80final= (mant80 << 11); + // Elvira wants the 8 and tcalc doesn't + if(fpu.regs[reg].d != 0) mant80final |= LONGTYPE(0x8000000000000000); test.begin= (static_cast(sign80)<<15)| static_cast(exp80final); test.eind.ll=mant80final; mem_writed(addr,test.eind.l.lower); From 767a418daabf1fef7966ac04d4051ebb2d5fbfb2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 9 Nov 2004 20:11:20 +0000 Subject: [PATCH 1965/4131] Updated it. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2048 --- docs/dosbox.1 | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/docs/dosbox.1 b/docs/dosbox.1 index 9a885c18..24768f06 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -1,5 +1,5 @@ .\" Hey, EMACS: -*- nroff -*- -.TH DOSBOX 1 "Sept 23, 2004" +.TH DOSBOX 1 "Nov 9, 2004" .\" Please adjust this date whenever revising the manpage. .SH NAME dosbox \- an x86/DOS emulator with sound/graphics @@ -18,8 +18,14 @@ dosbox \- an x86/DOS emulator with sound/graphics .SH DESCRIPTION This manual page briefly documents .BR "dosbox" ", an x86/DOS emulator." -.TP -.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 +.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 @@ -37,7 +43,8 @@ A summary of options is included below. .TP .BI \-conf " configfile .RB "Start " dosbox " with the options specified in " -.IR configfile . +.IR configfile ". This file has a section in which you can put commands you " +wish to execute on startup. .TP .BI \-lang " langfile .RB "Start " dosbox " with the language specified in " @@ -64,6 +71,8 @@ following extra commands are available: .LP .B MOUNT \-cd .LP +.B MOUNT \-u driveletter +.LP .RB "Program to mount local directories as drives inside " dosbox . .RS .TP @@ -103,6 +112,9 @@ Forces to use SDL cdrom support for drive number. .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:" @@ -121,6 +133,14 @@ Display the amount of free memory .RB "Write the current configuration or language settings to " file , which is located on the local filesystem. Not a mounted drive in .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. .TP .B LOADFIX [\-size] [programname] [parameters] .LP @@ -167,7 +187,8 @@ Frees all memory eaten up by loadfix. .RE .SH FILES Configuration and language files use a format similar to Windows .ini files. If a file named -.BR dosbox.conf " is found in the current directory, it will be automatically loaded." +.BR dosbox.conf " is found in the current directory, it will be" +automatically loaded, else ~/.dosboxrc (if present) will be loaded. .SH "SPECIAL KEYS" .TP 12m .IP ALT\-ENTER From 9df1cb8253cb057e385d367d574a63861a4db543 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 9 Nov 2004 21:35:51 +0000 Subject: [PATCH 1966/4131] Added numlock/capslock state checks on startup of dosbox Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2049 --- src/gui/sdlmain.cpp | 11 +++++++++-- src/ints/bios_keyboard.cpp | 15 ++++++++++++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index fe478638..c11e4750 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.80 2004-10-02 11:31:47 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.81 2004-11-09 21:35:50 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -194,6 +194,9 @@ static SDL_Block sdl; static void CaptureMouse(void); extern char * RunningProgram; +//Globals for keyboard initialisation +bool startup_state_numlock=false; +bool startup_state_capslock=false; void GFX_SetTitle(Bits cycles,Bits frameskip,bool paused){ char title[200]={0}; static Bits internal_cycles=0; @@ -825,7 +828,7 @@ static void GUI_StartUp(Section * sec) { sdl.desktop.height=768; #endif } - sdl.mouse.autoenable=section->Get_bool("autolock"); + sdl.mouse.autoenable=section->Get_bool("autolock"); sdl.mouse.autolock=false; sdl.mouse.sensitivity=section->Get_int("sensitivity"); const char * output=section->Get_string("output"); @@ -893,6 +896,10 @@ static void GUI_StartUp(Section * sec) { #else MAPPER_AddHandler(PauseDOSBox,MK_pause,0,"pause","Pause"); #endif + /* Get Keyboard state of numlock and capslock */ + SDLMod keystate = SDL_GetModState(); + if(keystate&KMOD_NUM) startup_state_numlock = true; + if(keystate&KMOD_CAPS) startup_state_capslock = true; } void Mouse_AutoLock(bool enable) { diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index eb3fdb3c..70f610ff 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -438,17 +438,26 @@ static Bitu INT16_Handler(void) { return CBRET_NONE; } +//Keyboard initialisation. src/gui/sdlmain.cpp +extern bool startup_state_numlock; +extern bool startup_state_capslock; + static void InitBiosSegment(void) { /* Setup the variables for keyboard in the bios data segment */ mem_writew(BIOS_KEYBOARD_BUFFER_START,0x1e); mem_writew(BIOS_KEYBOARD_BUFFER_END,0x3e); mem_writew(BIOS_KEYBOARD_BUFFER_HEAD,0x1e); mem_writew(BIOS_KEYBOARD_BUFFER_TAIL,0x1e); - mem_writeb(BIOS_KEYBOARD_FLAGS1,0); + Bit8u flag1 = 0; + Bit8u leds = 16; /* Ack recieved */ + if(startup_state_capslock) { flag1|=0x40; leds|=0x04;} + if(startup_state_numlock){ flag1|=0x20; leds|=0x02;} + mem_writeb(BIOS_KEYBOARD_FLAGS1,flag1); mem_writeb(BIOS_KEYBOARD_FLAGS2,0); - mem_writeb(BIOS_KEYBOARD_FLAGS3,16); /* Enhanced keyboard installed */ + mem_writeb(BIOS_KEYBOARD_FLAGS3,16); /* Enhanced keyboard installed */ mem_writeb(BIOS_KEYBOARD_TOKEN,0); - mem_writeb(BIOS_KEYBOARD_LEDS,16); + mem_writeb(BIOS_KEYBOARD_LEDS,leds); + } void BIOS_SetupKeyboard(void) { From b7b681a59acc81d5092d65dfa48a9fddb8c25c9e Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 12 Nov 2004 07:29:42 +0000 Subject: [PATCH 1967/4131] Fix wav writing, blah stupid :) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2050 --- src/hardware/mixer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index f52b9c3a..ae763f73 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -43,7 +43,7 @@ #define MIXER_SHIFT 14 #define MIXER_REMAIN ((1<MAX_AUDIO) ? (Bit16s)MAX_AUDIO : (SAMP> MIXER_VOLSHIFT; mixer.wave.buf[mixer.wave.used][0]=MIXER_CLIP(sample); From c68853a3630c04d0c075c50e1799e90bffaad9d4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 12 Nov 2004 22:13:13 +0000 Subject: [PATCH 1968/4131] Document new label support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2051 --- README | 54 ++++++++++++++++++++++++++++++++------------------- docs/dosbox.1 | 23 +++++++++++++++++++--- 2 files changed, 54 insertions(+), 23 deletions(-) diff --git a/README b/README index f32c360c..6c21f36f 100644 --- a/README +++ b/README @@ -151,9 +151,10 @@ A: DOSBox emulates several legacy sound devices: - Adlib Borrowed from MAME, this emulation is almost perfect and includes the Adlib's ability to almost play digitized sound. - - SoundBlaster 16 - Coupled with the Adlib, DOSBox provides Soundblaster 16 level 16-bit - stereo sound. + - SoundBlaster 16/ SoundBlaster Pro I & II /Sound Blaster I & II + Coupled with the Adlib, by default DOSBox provides Soundblaster 16 + level 16-bit stereo sound. You can select a different SoundBlaster + version in the configfile of DOSBox (See Internal Commands: CONFIG). - Disney Soundsource Using the printer port, this sound device outputs digital sound only. - Gravis Ultrasound @@ -276,7 +277,13 @@ MOUNT -u "Emulated Drive letter" -label drivelabel 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. + program can't find its cdrom. If you don't specify a label and no + lowlevel support is selected (-usecd # and/or -ioctl/aspi): + For win32: label is extracted from "Real Drive". + For Linux: label is set to NO_LABEL. + + If you do specify a label this label will be kept as long as the drive + is mounted. It will not be updated !! -aspi Forces to use the aspi layer. Only valid if mounting a cdrom under @@ -331,7 +338,14 @@ MEM CONFIG [-writeconf] [-writelang] localfile Write the current configuration or language settings to file. - "localfile" is located on the local drive !!! + "localfile" is located on the local drive. Not a mounted drive in DOSBox. + + The configuration file controls various settings of DOSBox: The amount + of emulated memory, the emulated soundcards and many more things. It + allows acces to AUTOEXEC.BAT as well. + + The language file controls all visible ouput of the internal commands + and the internal dos. Example: To create a configfile in your current directory: @@ -361,7 +375,7 @@ Examples: RESCAN Make DOSBox reread the directory structure. Useful if you changed something - on a mounted drive outside of DOSBox. + on a mounted drive outside of DOSBox. (CTRL - F4 does this as well!) MIXER @@ -537,19 +551,19 @@ For more information use the /? command line switch with the programs. 5. Special Keys: ================ -ALT-ENTER Go full screen and back. -CTRL-F1 Start the keymapper. -CTRL-F4 Swap mounted disk-image (Only used with imgmount). -CTRL-F5 Save a screenshot. -CTRL-F6 Start/Stop recording sound output to a wave file. -CTRL-ALT-F7 Start/Stop recording of OPL commands. -CTRL-ALT-F8 Start/Stop the recording of raw MIDI commands. -CTRL-F7 Decrease frameskip. -CTRL-F8 Increase frameskip. -CTRL-F9 Kill dosbox. -CTRL-F10 Capture/Release the mouse. -CTRL-F11 Slow down emulation (Decrease DOSBox Cycles). -CTRL-F12 Speed up emulation (Increase DOSox Cycles). +ALT-ENTER Go full screen and back. +CTRL-F1 Start the keymapper. +CTRL-F4 Swap mounted disk-image. Update directory cache for all drives! +CTRL-F5 Save a screenshot. +CTRL-F6 Start/Stop recording sound output to a wave file. +CTRL-ALT-F7 Start/Stop recording of OPL commands. +CTRL-ALT-F8 Start/Stop the recording of raw MIDI commands. +CTRL-F7 Decrease frameskip. +CTRL-F8 Increase frameskip. +CTRL-F9 Kill dosbox. +CTRL-F10 Capture/Release the mouse. +CTRL-F11 Slow down emulation (Decrease DOSBox Cycles). +CTRL-F12 Speed up emulation (Increase DOSox Cycles). These are the default keybindings. They can be changed in the keymapper. @@ -628,7 +642,7 @@ present in the configfile. 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 +them to run fast though! Be sure to read the next section on how to speed it up somewhat. diff --git a/docs/dosbox.1 b/docs/dosbox.1 index 24768f06..2619b6f5 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -1,5 +1,5 @@ .\" Hey, EMACS: -*- nroff -*- -.TH DOSBOX 1 "Nov 9, 2004" +.TH DOSBOX 1 "Nov 12, 2004" .\" Please adjust this date whenever revising the manpage. .SH NAME dosbox \- an x86/DOS emulator with sound/graphics @@ -95,7 +95,17 @@ Sets the amount of free space available on a drive in MB's. This is a more .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. +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 \-aspi Forces to use the aspi layer. Only valid if mounting a cdrom under @@ -162,6 +172,12 @@ The amount of memory to eat up (in kb). Example -32, -64 or -128 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 . @@ -196,7 +212,8 @@ Go full screen and back. .IP CTRL\-F1 Start the keymapper. .IP CTRL\-F4 -Swap mounted disk-image (Only used with imgmount). +Swap mounted disk-image (Only used with imgmount). Update directory cache +for all drives! .IP CTRL\-F5 Save a screenshot. .IP CTRL\-F6 From 76878308d56c9b63ba756fb5d4094a2cf6b2c0ca Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 12 Nov 2004 22:19:20 +0000 Subject: [PATCH 1969/4131] Updated (removed freebsd section and added sdl_sound) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2052 --- INSTALL | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/INSTALL b/INSTALL index 12c4bd97..936cde7d 100644 --- a/INSTALL +++ b/INSTALL @@ -18,7 +18,10 @@ Zlib For win32 get libz (rename to zlib) from http://www.sourceforge.net/projects/gnuwin32 SDL_Net - For modem support(optional). Get it from http://www.libsdl.org + For modem/ipx support(optional). Get it from http://www.libsdl.org + +SDL_Sound + For compressed audio on diskimages. (optional) ALSA_Headers (optional) @@ -37,24 +40,19 @@ In step 1 you could add the following switches: --enable-debug 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 - on numeric keyboard to enter the debugger. + window is active press pause to enter the debugger. --disable-fpu - Will disable the emulated fpu. Although the fpu emulation hasn't finished and isn't - entirely accurate it's advised to leave it on. + Will disable the emulated fpu. Although the fpu emulation code isn't + finished and isn't entirely accurate it's advised to leave it on. --enable-core-inline - enables some memory increasing inlines. This greatly increases compiletime for maybe a increase - in speed. + enables some memory increasing inlines. This greatly increases + compiletime for maybe a increase in speed. Check the src subdir for the binary. -Compiling on FreeBSD might be a problem since SDL has no joystick support there. -To get around this edit sdlmain.cpp to enable some #define. -Let's hope someday the sdl people will just report 0 joysticks in freebsd or get it working some other way :) - - Build instructions for VC++6 Don't use VC++ 6:it creates faulty code in core_normal.cpp From 6613c49267c0bd4ac3f80d547a85471c0929c4de Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 13 Nov 2004 09:50:09 +0000 Subject: [PATCH 1970/4131] CTRL-F4 updates internal cache as well Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2053 --- src/ints/bios_disk.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index be354e73..be65ce66 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -106,6 +106,10 @@ void swapInDisks(void) { } void swapInNextDisk(void) { + /* Hack/feature: rescan all disks as well */ + for(Bitu i=0;iEmptyCache(); + } swapPosition++; if(diskSwap[swapPosition] == NULL) swapPosition = 0; swapInDisks(); From 2ae5a14bcf5ca1390afb540e2697527cafaf3ade Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 13 Nov 2004 11:59:46 +0000 Subject: [PATCH 1971/4131] Handle mode 0 differently Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2054 --- src/hardware/timer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index d5691b1b..b59e8c1e 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.29 2004-09-10 22:15:20 harekiet Exp $ */ +/* $Id: timer.cpp,v 1.30 2004-11-13 11:59:46 qbix79 Exp $ */ #include "dosbox.h" #include "inout.h" @@ -152,7 +152,7 @@ static void write_latch(Bitu port,Bitu val,Bitu iolen) { p->delay=(1000.0f/((float)PIT_TICK_RATE/(float)p->cntr)); switch (counter) { case 0x00: /* Timer hooked to IRQ 0 */ - if (p->new_mode) { + if (p->new_mode || p->mode == 0 ) { p->new_mode=false; PIC_AddEvent(PIT0_Event,p->delay); } else LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer set without new control word"); From fa0f126530dda10dfa888912f2e9c747d3ca9312 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 13 Nov 2004 12:04:47 +0000 Subject: [PATCH 1972/4131] Allow redirection (< and > (also to devices) stuff like mount c c:\ >nul works) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2055 --- src/shell/shell.cpp | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 1b208432..f899dc2e 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.51 2004-10-23 15:15:07 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.52 2004-11-13 12:04:47 qbix79 Exp $ */ #include #include @@ -113,14 +113,13 @@ void DOS_Shell::ParseLine(char * line) { if (line[0]=='@') line[0]=' '; line=trim(line); -#if 1 /* Do redirection and pipe checks */ char * in=0; char * out=0; Bit16u old_in,old_out; - + Bit16u dummy,dummy2; Bitu num=0; /* Number of commands in this line */ bool append; @@ -129,17 +128,33 @@ void DOS_Shell::ParseLine(char * line) { // if (in || num>1) DOS_DuplicateEntry(0,&old_in); if (in) { - LOG_MSG("SHELL:Redirect input from %s",in); + if(DOS_OpenFile(in,2,&dummy)) { //Test if file exists + DOS_CloseFile(dummy); + LOG_MSG("SHELL:Redirect input from %s",in); + DOS_CloseFile(0); //Close stdin + DOS_OpenFile(in,2,&dummy);//Open new stdin + } + } + if (out){ + LOG_MSG("SHELL:Redirect output to %s",out); + DOS_CloseFile(1); + /* Create if not exist. Open if exist. Both in read/write mode */ + if(!DOS_OpenFileExtended(out,2,2,0x11,&dummy,&dummy2)) + DOS_OpenFile("con",2,&dummy); //Read only file, open con again + } + /* Run the actual command */ + DoCommand(line); + /* Restore handles */ + if(in) { DOS_CloseFile(0); + DOS_OpenFile("con",2,&dummy); free(in); } - if (out) { - LOG_MSG("SHELL:Redirect output to %s",out); + if(out) { + DOS_CloseFile(1); + DOS_OpenFile("con",2,&dummy); free(out); } -#endif - DoCommand(line); - } @@ -343,7 +358,8 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_LOADHIGH_HELP","Run a program. For batch file compatibility only.\n"); MSG_Add("SHELL_CMD_CHOICE_HELP","Waits for a keypress and sets ERRORLEVEL.\n"); MSG_Add("SHELL_CMD_ATTRIB_HELP","Does nothing. Provided for compatibility.\n"); - + MSG_Add("SHELL_CMD_PATH_HELP","Provided for compatibility.\n"); + /* Regular startup */ call_shellstop=CALLBACK_Allocate(); /* Setup the startup CS:IP to kill the last running machine when exitted */ From 49cfc19efbb2d577dc3a9a2ee69ddefe1a239aa0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 13 Nov 2004 12:06:39 +0000 Subject: [PATCH 1973/4131] Added path as command Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2056 --- include/shell.h | 3 ++- src/shell/shell_cmds.cpp | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/include/shell.h b/include/shell.h index 6f0b083f..b272615d 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.8 2004-10-26 18:28:51 qbix79 Exp $ */ +/* $Id: shell.h,v 1.9 2004-11-13 12:06:39 qbix79 Exp $ */ #ifndef SHELL_H_ #define SHELL_H_ @@ -102,6 +102,7 @@ public: void CMD_LOADHIGH(char* args); void CMD_CHOICE(char * args); void CMD_ATTRIB(char * args); + void CMD_PATH(char * args); /* The shell's variables */ Bit16u input_handle; BatchFile * bf; diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 286312fd..efe47583 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.49 2004-10-21 15:38:39 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.50 2004-11-13 12:06:39 qbix79 Exp $ */ #include #include @@ -56,6 +56,7 @@ static SHELL_Cmd cmd_list[]={ { "LH", 1, &DOS_Shell::CMD_LOADHIGH, "SHELL_CMD_LOADHIGH_HELP"}, { "CHOICE", 0, &DOS_Shell::CMD_CHOICE, "SHELL_CMD_CHOICE_HELP"}, { "ATTRIB", 0, &DOS_Shell::CMD_ATTRIB, "SHELL_CMD_ATTRIB_HELP"}, +{ "PATH", 1, &DOS_Shell::CMD_PATH, "SHELL_CMD_PATH_HELP"}, {0,0,0,0} }; @@ -68,6 +69,7 @@ void DOS_Shell::DoCommand(char * line) { if (*line==32) break; if (*line=='/') break; if (*line=='\t') break; + if (*line=='=') break; if ((*line=='.') ||(*line =='\\')) { //allow stuff like cd.. and dir.exe cd\kees *cmd_write=0; Bit32u cmd_index=0; @@ -727,3 +729,21 @@ void DOS_Shell::CMD_ATTRIB(char *args){ // No-Op for now. } +void DOS_Shell::CMD_PATH(char *args){ + if(args && *args && strlen(args)){ + char pathstring[DOS_PATHLENGTH+CROSS_LEN+20]={ 0 }; + strcpy(pathstring,"set PATH="); + while(args && *args && (*args=='='|| *args==' ')) + args++; + strcat(pathstring,args); + this->ParseLine(pathstring); + return; + } else { + std::string line; + if(GetEnvStr("PATH",line)) { + WriteOut("%s",line.c_str()); + } else { + WriteOut("PATH=(null)"); + } + } +} From b2c2a02c97b8089c9072e75acd491f9f3cab9ced Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 13 Nov 2004 12:08:43 +0000 Subject: [PATCH 1974/4131] Don't update the drive-label if one was specified at mount time. Be more flexible with directorie mounting (don't care about a trailing slash) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2057 --- include/dos_system.h | 5 +++-- src/dos/dos_programs.cpp | 12 ++++++++---- src/dos/drive_cache.cpp | 24 ++++++++++++++---------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 66d28cde..6ccdaef5 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.27 2004-11-03 23:13:53 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.28 2004-11-13 12:08:42 qbix79 Exp $ */ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ @@ -127,7 +127,7 @@ public: void DeleteEntry (const char* path, bool ignoreLastDir = false); void EmptyCache (void); - void SetLabel (const char* name); + void SetLabel (const char* name,bool allowupdate=true); char* GetLabel (void) { return label; }; class CFileInfo { @@ -185,6 +185,7 @@ private: Bitu nextFreeFindFirst; char label [CROSS_LEN]; + bool updatelabel; }; class DOS_No_Drive_Cache { diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 287fe58c..3148d581 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.32 2004-10-26 18:18:22 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.33 2004-11-13 12:08:43 qbix79 Exp $ */ #include #include @@ -130,7 +130,7 @@ public: } number[index]=0;sizes[count++]=atoi(number); - // get the drive letter + // get the drive letter cmd->FindCommand(1,temp_line); if ((temp_line.size() > 2) || ((temp_line.size()>1) && (temp_line[1]!=':'))) goto showusage; drive=toupper(temp_line[0]); @@ -138,6 +138,10 @@ public: if (!cmd->FindCommand(2,temp_line)) goto showusage; if (!temp_line.size()) goto showusage; +#if defined (WIN32) + /* Removing trailing backslash if not root dir so stat will succeed */ + if(temp_line.size() > 3 && temp_line[temp_line.size()-1]=='\\') temp_line.erase(temp_line.size()-1,1); +#endif struct stat test; if (stat(temp_line.c_str(),&test)) { WriteOut(MSG_Get("PROGRAM_MOUNT_ERROR_1"),temp_line.c_str()); @@ -185,8 +189,8 @@ public: /* Set the correct media byte in the table */ mem_writeb(Real2Phys(dos.tables.mediaid)+drive-'A',newdrive->GetMediaByte()); WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,newdrive->GetInfo()); - /* check if volume label is given */ - if (cmd->FindString("-label",label,true)) newdrive->dirCache.SetLabel(label.c_str()); + /* check if volume label is given and don't allow it to updated in the future */ + if (cmd->FindString("-label",label,true)) newdrive->dirCache.SetLabel(label.c_str(),false); return; showusage: WriteOut(MSG_Get("PROGRAM_MOUNT_USAGE")); diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 92afa5ca..35893b90 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.39 2004-10-05 19:50:03 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.40 2004-11-13 12:08:43 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -69,6 +69,7 @@ DOS_Drive_Cache::DOS_Drive_Cache(void) nextFreeFindFirst = 0; for (Bit32u i=0; iupdatelabel) return; + this->updatelabel = allowupdate; Bitu togo = 8; Bitu vnamePos = 0; Bitu labelPos = 0; @@ -128,7 +136,7 @@ void DOS_Drive_Cache::SetLabel(const char* vname) //Remove trailing dot. if((labelPos > 0) && (label[labelPos-1] == '.')) label[labelPos-1]=0; -// LOG(LOG_ALL,LOG_ERROR)("CACHE: Set volume label to %s",label); + LOG(LOG_DOSMISC,LOG_NORMAL)("DIRCACHE: Set volume label to %s",label); }; Bit16u DOS_Drive_Cache::GetFreeID(CFileInfo* dir) @@ -151,13 +159,9 @@ void DOS_Drive_Cache::SetBaseDir(const char* baseDir) char labellocal[256]={ 0 }; char drive[4] = "C:\\"; drive[0] = basePath[0]; - UINT type_drive=GetDriveType(drive); - if(type_drive != DRIVE_FIXED) { - //Only add label for non-fixed drives. (so stuff like "mount c c:\piet -t cdrom -label piet" works) - if (GetVolumeInformation(drive,labellocal,256,NULL,NULL,NULL,NULL,0)) { - LOG(LOG_MISC,LOG_NORMAL)("Cache: setting label for (non-fixed localdrive) to %s",labellocal); - SetLabel(labellocal); - } + if (GetVolumeInformation(drive,labellocal,256,NULL,NULL,NULL,NULL,0)) { + /* Set label and allow being updated */ + SetLabel(labellocal,true); } #endif }; From 97ac4e4b4d53e87d10f0fe026b3b9e577403c4fe Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 13 Nov 2004 12:19:43 +0000 Subject: [PATCH 1975/4131] Open input in read mode instead of read/write mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2058 --- src/shell/shell.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index f899dc2e..b53a401c 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.52 2004-11-13 12:04:47 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.53 2004-11-13 12:19:43 qbix79 Exp $ */ #include #include @@ -128,11 +128,11 @@ void DOS_Shell::ParseLine(char * line) { // if (in || num>1) DOS_DuplicateEntry(0,&old_in); if (in) { - if(DOS_OpenFile(in,2,&dummy)) { //Test if file exists + if(DOS_OpenFile(in,0,&dummy)) { //Test if file exists DOS_CloseFile(dummy); LOG_MSG("SHELL:Redirect input from %s",in); DOS_CloseFile(0); //Close stdin - DOS_OpenFile(in,2,&dummy);//Open new stdin + DOS_OpenFile(in,0,&dummy);//Open new stdin } } if (out){ From 876470922692575f76aefb8e4a3a981f43b9b869 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 15 Nov 2004 12:46:32 +0000 Subject: [PATCH 1976/4131] Updated for 0.63 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2059 --- ChangeLog | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/ChangeLog b/ChangeLog index 5500e85b..47848019 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +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. + - 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. + 0.62 - Added blinking support in the shell and some color fixes. - Fixed commandline parsing when .bat files involved (fixes -exit) From fbc9a7ec392af2d6b8e28f56bda93775495d22c5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 15 Nov 2004 14:56:55 +0000 Subject: [PATCH 1977/4131] Rotate stuff ignoring for now (7 cities of gold) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2060 --- src/hardware/pic.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 05eb4a48..3a412567 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.24 2004-09-10 22:15:20 harekiet Exp $ */ +/* $Id: pic.cpp,v 1.25 2004-11-15 14:56:55 qbix79 Exp $ */ #include @@ -131,7 +131,11 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { break; case 0xC0:case 0xC1:case 0xC2:case 0xC3:case 0xC4:case 0xC5:case 0xC6:case 0xC7: /* Priority order, no need for it */ - break; + break; + case 0x00:case 0x80: /* Rotate stuff in eoi mode */ + /* We can live without it for now. (7 cities of gold) */ + LOG(LOG_PIC,LOG_NORMAL)("port %X : ignoring rotate stuff.",port); + break; default: E_Exit("PIC:Unhandled command %02X",val); } From 2de28df3fd6ee0e4e39eeacdb7d871dee4967071 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 16 Nov 2004 14:13:46 +0000 Subject: [PATCH 1978/4131] Removed mysterious double code Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2061 --- src/dos/drive_local.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 9393e4f5..51d52e91 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.53 2004-11-03 23:13:55 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.54 2004-11-16 14:13:46 qbix79 Exp $ */ #include #include @@ -209,10 +209,6 @@ again: goto again;//No symlinks and such } - if(S_ISDIR(stat_block.st_mode)) find_attr=DOS_ATTR_DIRECTORY; - else find_attr=DOS_ATTR_ARCHIVE; - if (~srch_attr & find_attr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM)) goto again; - if(S_ISDIR(stat_block.st_mode)) find_attr=DOS_ATTR_DIRECTORY; else find_attr=DOS_ATTR_ARCHIVE; if (~srch_attr & find_attr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM)) goto again; From 7e9dae0b28f043892a74ceec3dee91b9a500c5c5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 16 Nov 2004 14:21:25 +0000 Subject: [PATCH 1979/4131] Updated for 0.63 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2062 --- scripts/dosbox-installer.nsi | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index cb2e54b9..957453c6 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -1,5 +1,5 @@ !define VER_MAYOR 0 -!define VER_MINOR 62 +!define VER_MINOR 63 ; The name of the installer Name "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer" @@ -33,7 +33,10 @@ Section "ThisNameIsIgnoredSoWhyBother?" File dosbox.conf File SDL.dll File SDL_net.dll - File libpng12.dll +; File libpng12.dll + File libogg-0.dll + File libvorbis-0.dll + File libvorbisfile-3.dll CreateDirectory "$INSTDIR\capture" CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}" @@ -61,7 +64,11 @@ Section "Uninstall" Delete $INSTDIR\dosbox.conf Delete $INSTDIR\SDL.dll Delete $INSTDIR\SDL_net.dll - Delete $INSTDIR\libpng12.dll +; Delete $INSTDIR\libpng12.dll + Delete $INSTDIR\libogg-0.dll + Delete $INSTDIR\libvorbis-0.dll + Delete $INSTDIR\libvorbisfile-3.dll + ;Files left by sdl taking over the console Delete $INSTDIR\stdout.txt Delete $INSTDIR\stderr.txt From 011fad1586fbada55142f5c3c07290a42e492d8e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 16 Nov 2004 14:24:52 +0000 Subject: [PATCH 1980/4131] Added some more warnings on failures Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2063 --- src/dos/dos.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 58b8175c..637c91d5 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.76 2004-11-03 20:13:40 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.77 2004-11-16 14:24:52 qbix79 Exp $ */ #include #include @@ -187,24 +187,19 @@ static Bitu DOS_21Handler(void) { LOG(LOG_FCB,LOG_NORMAL)("DOS:0x10 FCB-fileclose used, result:al=%d",reg_al); break; case 0x11: /* Find First Matching File using FCB */ - if(DOS_FCBFindFirst(SegValue(ds),reg_dx)){ - reg_al=0; - }else{ - reg_al=0xff; - } + if(DOS_FCBFindFirst(SegValue(ds),reg_dx)) reg_al = 0x00; + else reg_al = 0xFF; LOG(LOG_FCB,LOG_NORMAL)("DOS:0x11 FCB-FindFirst used, result:al=%d",reg_al); break; case 0x12: /* Find Next Matching File using FCB */ - if(DOS_FCBFindNext(SegValue(ds),reg_dx)){ - reg_al=0; - }else{ - reg_al=0xff; - } + if(DOS_FCBFindNext(SegValue(ds),reg_dx)) reg_al = 0x00; + else reg_al = 0xFF; LOG(LOG_FCB,LOG_NORMAL)("DOS:0x12 FCB-FindNext used, result:al=%d",reg_al); break; case 0x13: /* Delete File using FCB */ if (DOS_FCBDeleteFile(SegValue(ds),reg_dx)) reg_al = 0x00; else reg_al = 0xFF; + LOG(LOG_FCB,LOG_NORMAL)("DOS:0x16 FCB-Delete used, result:al=%d",reg_al); break; case 0x14: /* Sequential read from FCB */ reg_al = DOS_FCBRead(SegValue(ds),reg_dx,0); @@ -426,6 +421,7 @@ static Bitu DOS_21Handler(void) { } else { reg_ax=dos.errorcode; CALLBACK_SCF(true); + LOG(LOG_MISC,LOG_NORMAL)("Remove dir failed on %s with error %X",name1,dos.errorcode); } break; case 0x3b: /* CHDIR Set current directory */ From 95b31b857c3db6b922e010b34a7f8e35df55e1d0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 16 Nov 2004 14:28:16 +0000 Subject: [PATCH 1981/4131] Added failure checks for removedir (requested by mirekluza). Updated fcb-delete so it accepts wildcards by using a private dta.(Fixes Ravenloft) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2064 --- include/dos_inc.h | 3 ++- src/dos/dos_files.cpp | 51 ++++++++++++++++++++++++++++++++++++------ src/dos/dos_tables.cpp | 3 ++- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 2f81cfe4..f216b475 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.50 2004-11-03 20:13:40 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.51 2004-11-16 14:28:15 qbix79 Exp $ */ #ifndef DOS_H_ #define DOS_H_ @@ -570,6 +570,7 @@ struct DOS_Block { struct { RealPt mediaid; RealPt tempdta; + RealPt tempdta_fcbdelete; RealPt dcbs; Bit8u* country;//Will be copied to dos memory. resides in real mem } tables; diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 65953a70..78e615e1 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.58 2004-10-17 14:45:00 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.59 2004-11-16 14:28:15 qbix79 Exp $ */ #include #include @@ -181,7 +181,6 @@ bool DOS_GetCurrentDir(Bit8u drive,char * buffer) { } bool DOS_ChangeDir(char * dir) { - Bit8u drive;char fulldir[DOS_PATHLENGTH]; if (!DOS_MakeName(dir,fulldir,&drive)) return false; @@ -201,9 +200,31 @@ bool DOS_MakeDir(char * dir) { } bool DOS_RemoveDir(char * dir) { +/* We need to do the test before the removal as can not rely on + * the host to forbid removal of the current directory. + * We never change directory. Everything happens in the drives. + */ Bit8u drive;char fulldir[DOS_PATHLENGTH]; if (!DOS_MakeName(dir,fulldir,&drive)) return false; - return Drives[drive]->RemoveDir(fulldir); + /* Check if exists */ + if(!Drives[drive]->TestDir(fulldir)) { + DOS_SetError(DOSERR_PATH_NOT_FOUND); + return false; + } + /* See if it's current directory */ + char currdir[DOS_PATHLENGTH]= { 0 }; + DOS_GetCurrentDir(drive + 1 ,currdir); + if(strcmp(currdir,fulldir) == 0) { + DOS_SetError(DOSERR_REMOVE_CURRENT_DIRECTORY); + return false; + } + + if(Drives[drive]->RemoveDir(fulldir)) return true; + + /* Failed. We know it exists and it's not the current dir */ + /* Assume non empty */ + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; } bool DOS_Rename(char * oldname,char * newname) { @@ -336,6 +357,7 @@ bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { if (DOS_FindDevice(name) != DOS_DEVICES) return DOS_OpenFile(name, 0, entry); + LOG(LOG_FILES,LOG_NORMAL)("file create attributes %X file %s",attributes,name); char fullname[DOS_PATHLENGTH];Bit8u drive; DOS_PSP psp(dos.psp()); if (!DOS_MakeName(name,fullname,&drive)) return false; @@ -916,10 +938,25 @@ bool DOS_FCBGetFileSize(Bit16u seg,Bit16u offset,Bit16u numRec) { } bool DOS_FCBDeleteFile(Bit16u seg,Bit16u offset){ - DOS_FCB fcb(seg,offset); - char shortname[DOS_FCBNAME]; - fcb.GetName(shortname); - return DOS_UnlinkFile(shortname); +/* FCB DELETE honours wildcards. it will return true if one or more + * files get deleted. + * To get this: the dta is set to temporary dta in which found files are + * stored. This can not be the tempdta as that one is used by fcbfindfirst + */ + RealPt old_dta=dos.dta();dos.dta(dos.tables.tempdta_fcbdelete); + DOS_FCB fcb(RealSeg(dos.dta()),RealOff(dos.dta())); + bool nextfile = false; + bool return_value = false; + nextfile = DOS_FCBFindFirst(seg,offset); + while(nextfile) { + char shortname[DOS_FCBNAME] = { 0 }; + fcb.GetName(shortname); + bool res=DOS_UnlinkFile(shortname); + if(!return_value && res) return_value = true; //at least one file deleted + nextfile = DOS_FCBFindNext(seg,offset); + } + dos.dta(old_dta); /*Restore dta */ + return return_value; } bool DOS_FCBRenameFile(Bit16u seg, Bit16u offset){ diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 3d771449..be321389 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.16 2004-11-03 20:13:40 qbix79 Exp $ */ +/* $Id: dos_tables.cpp,v 1.17 2004-11-16 14:28:16 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -78,6 +78,7 @@ void DOS_SetupTables(void) { Bit16u seg,seg2;Bitu i; dos.tables.mediaid=RealMake(DOS_GetMemory(2),0); dos.tables.tempdta=RealMake(DOS_GetMemory(4),0); + dos.tables.tempdta_fcbdelete=RealMake(DOS_GetMemory(4),0); for (i=0;i Date: Thu, 18 Nov 2004 11:07:52 +0000 Subject: [PATCH 1982/4131] Autodetect type op opl data in dro writing Fix opl3 capturing and using wrong indexes for dro data Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2065 --- src/hardware/adlib.cpp | 56 ++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 01f62add..ea6274e0 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -100,6 +100,8 @@ static struct { Bit32u used; Bit32u done; Bit8u cmd[2]; + bool opl3; + bool dualopl2; } raw; } opl; @@ -172,17 +174,19 @@ void OPL_Write(Bitu port,Bitu val,Bitu iolen) { } static Bit8u dro_header[]={ - 'D','B','R','A', /* Bit32u ID */ - 'W','O','P','L', /* Bit32u ID */ - 0x0,0x0,0x0,0x0, /* Bit32u total milliseconds */ - 0x0,0x0,0x0,0x0, /* Bit32u total data */ - 0x0, /* Type 0=opl2,1=opl3,2=dual-opl2 */ + 'D','B','R','A', /* 0x00, Bit32u ID */ + 'W','O','P','L', /* 0x04, Bit32u ID */ + 0x0,0x00, /* 0x08, Bit16u version low */ + 0x1,0x00, /* 0x09, Bit16u version high */ + 0x0,0x0,0x0,0x0, /* 0x0c, Bit32u total milliseconds */ + 0x0,0x0,0x0,0x0, /* 0x10, Bit32u total data */ + 0x0,0x0,0x0,0x0 /* 0x14, Bit32u Type 0=opl2,1=opl3,2=dual-opl2 */ }; /* Commands 0x00 Bit8u, millisecond delay+1 - 0x01 Bit16u, millisecond delay+1 0x02 none, Use the low index/data pair 0x03 none, Use the high index/data pair + 0x10 Bit16u, millisecond delay+1 0xxx Bit8u, send command and data to current index/data pair */ @@ -194,9 +198,13 @@ static void OPL_RawEmptyBuffer(void) { #define ADDBUF(_VAL_) opl.raw.buffer[opl.raw.used++]=_VAL_; static void OPL_RawAdd(Bitu index,Bitu val) { - /* Check if we have yet to start */ Bit8u cmd=opl.raw.cmd[index]; - if (cmd<=3) return; + /* check for cmd's we use for special meaning + These only control timers or are unused + */ + if (cmd == 2 || cmd == 3 || cmd == 0x10) return; + if (cmd == 4 && !index) return; + /* Check if we have yet to start */ if (!opl.raw.handle) { if (cmd<0xb0 || cmd>0xb8) return; if (!(val&0x20)) return; @@ -211,25 +219,37 @@ static void OPL_RawAdd(Bitu index,Bitu val) { memset(opl.raw.buffer,0,sizeof(opl.raw.buffer)); fwrite(dro_header,1,sizeof(dro_header),opl.raw.handle); /* Check the registers to add */ - for (i=4;i<256;i++) { + for (i=0;i<256;i++) { if (!opl.raw.regs[0][i]) continue; if (i>=0xb0 && i<=0xb8) continue; ADDBUF((Bit8u)i); ADDBUF(opl.raw.regs[0][i]); } bool donesecond=false; - for (i=4;i<256;i++) { - if (!opl.raw.regs[0][i]) continue; + /* Check if we already have an opl3 enable bit logged */ + if (opl.raw.regs[1][5] & 1) + opl.raw.opl3 = true; + for (i=0;i<256;i++) { + if (!opl.raw.regs[1][i]) continue; if (i>=0xb0 && i<=0xb8) continue; if (!donesecond) { + /* Or already have dual opl2 */ + opl.raw.dualopl2 = true; donesecond=true; ADDBUF(0x3); } ADDBUF((Bit8u)i); - ADDBUF(opl.raw.regs[0][i]); + ADDBUF(opl.raw.regs[1][i]); } if (donesecond) ADDBUF(0x2); } + /* Check if we enable opl3 or access dual opl2 mode */ + if (cmd == 5 && index && (val & 1)) { + opl.raw.opl3 = true; + } + if (index && val && cmd>=0xb0 && cmd<=0xb8) { + opl.raw.dualopl2 = true; + } /* Check how much time has passed, Allow an extra 5 milliseconds? */ if (PIC_Ticks>(opl.raw.last+5)) { Bitu passed=PIC_Ticks-opl.raw.last; @@ -268,13 +288,11 @@ static void OPL_SaveRawEvent(void) { if (opl.raw.handle) { OPL_RawEmptyBuffer(); /* Fill in the header with useful information */ - host_writed(&dro_header[0x08],opl.raw.last-opl.raw.start); - host_writed(&dro_header[0x0c],opl.raw.done); - switch (opl.mode) { - case OPL_opl2:host_writeb(&dro_header[0x10],0x0);break; - case OPL_opl3:host_writeb(&dro_header[0x10],0x1);break; - case OPL_dualopl2:host_writeb(&dro_header[0x10],0x2);break; - } + host_writed(&dro_header[0x0c],opl.raw.last-opl.raw.start); + host_writed(&dro_header[0x10],opl.raw.done); + if (opl.raw.opl3 && opl.raw.dualopl2) host_writed(&dro_header[0x14],0x1); + else if (opl.raw.dualopl2) host_writed(&dro_header[0x14],0x2); + else host_writed(&dro_header[0x14],0x0); fseek(opl.raw.handle,0,0); fwrite(dro_header,1,sizeof(dro_header),opl.raw.handle); fclose(opl.raw.handle); From 97296864dacaeaebbe6eb4bcf567315d29f2894b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 18 Nov 2004 14:13:09 +0000 Subject: [PATCH 1983/4131] Updates for 0.63 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2066 --- README | 82 ++++++++++++++++++++++++++++++++------------------- configure.in | 2 +- docs/dosbox.1 | 46 ++++++++++++++++++----------- 3 files changed, 81 insertions(+), 49 deletions(-) diff --git a/README b/README index 6c21f36f..e134421e 100644 --- a/README +++ b/README @@ -42,8 +42,6 @@ INDEX: Type INTRO in DOSBox. That's it. - - ======= 2. FAQ: ======= @@ -59,7 +57,8 @@ Q: The game/application can't find its CD-ROM. Q: The game/application runs much too slow! Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. Q: What sound hardware does DOSBox presently emulate? - +Q: DOSBox crashes on startup and I'm running arts +Q: Great README, but I still don't get it. @@ -93,9 +92,9 @@ A: To mount your cdrom in DOSBox you have to specify some additional options Q: The mouse doesn't work. A: Normally DOSBox detects the mouse being used by a game. If you click on - the screen then it should get locked and work. - Sometimes the DOSBox mouse detection doesn't work with certain games. You - might have to force to lock the mouse then with ctrl-F10. + the screen then it should get locked (confined to the DOSBox window) + and work. Sometimes the DOSBox mouse detection doesn't work with certain + games. You might have to force to lock the mouse then with ctrl-F10. Q: The sound stutters. @@ -109,11 +108,11 @@ A: This is a known problem. It only occurs if your keyboard layout isn't US. Some possible fixes: 1. Switch your keyboard layout. 2. Use / instead. - 3. Add the commands you want to execute to dosbox.conf + 3. Add the commands you want to execute to the "configfile". 4. Start the keymapper (CTRL-F1 or add -startmapper switch to dosbox) 5. for \ try the keys around "enter". For ":" try shift and the keys between "enter" and "l" (US keyboard layout). - 6. Use keyb.com for FreeDOS (http://projects.freedos.net/keyb/). + 6. Use keyb.com from FreeDOS (http://projects.freedos.net/keyb/). Q: The game/application can't find its CD-ROM. @@ -130,9 +129,9 @@ A: Look at the section "To run resource-demanding games" for more information. Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. -A: This is possible! Just create a config file: config -writeconf dosbox.conf . +A: This is possible! Just create a config file: config -writeconf configfile . Start your favourite editor and look at all the settings present. To - start DOSBox with your new settings: dosbox -conf dosbox.conf + start DOSBox with your new settings: dosbox -conf configfile Q: What sound hardware does DOSBox presently emulate? @@ -165,11 +164,16 @@ A: DOSBox emulates several legacy sound devices: A MIDI passthrough interface is also emulated. This method of sound output will only work when used with a General Midi or MT-32 device. +Q: DOSBox crashes on startup and I'm running arts +A: This isn't really a DOSBox problem, but the solution is to set the + environment variable SDL_AUDIODRIVER to alsa or oss. Q: Great README, but I still don't get it. A: While unlikely, this seems to happen. A look at "The Newbie's pictorial guide to DOSBox" located at http://vogons.zetafleet.com/viewforum.php?f=39 might help you. + You could also try the wiki of dosbox: + http://dosbox.sourceforge.net/wiki/ For more questions read the remainder of this README and/or check @@ -183,7 +187,11 @@ http://dosbox.sourceforge.net 3. Usage: ========= -An overview of the commandline options you can give to DOSBox: +An overview of the commandline options you can give to DOSBox. +Windows Users must open cmd.exe or command.com or edit the shortcut to +dosbox.exe for this. +The options are valid for all operating systems unless noted in the option +description: dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] [-lang languagefile] [-machine machinetype] [-noconsole] @@ -197,20 +205,23 @@ dosbox -version as the C: drive and execute "name". -exit - dosbox will exit after the "name" has been executed. + dosbox will close itself when the DOS application "name" ends. -c command Runs the specified command before running "name". Multiple commands can be specified. Each command should start with -c though. + A command can be: an Internal Program, a DOS command or an executable + on a mounted drive. -fullscreen Starts dosbox in fullscreen mode. -conf configfile Start dosbox with the options specified in "configfile". + See Chapter 9 for more details. -lang languagefile - Start dosbox using the language string specified in "languagefile". + Start dosbox using the language specified in "languagefile". -noconsole (Windows Only) Start dosbox without showing the console window. Output will @@ -218,7 +229,8 @@ dosbox -version -machine machinetype Setup dosbox to emulate a specific type of machine. Valid choices are: - hercules, cga, tandy, vga (default). + hercules, cga, tandy, vga (default). The machinetype has influence on + both the videocard and the available soundcards. -startmapper Enter the keymapper directly on startup. Useful for people with @@ -228,7 +240,8 @@ dosbox -version output version information and exit. Useful for frontends. Note: If a name/command/configfile/languagefile contains a space in it, put - the whole name/command/configfile/languagefile between quotes("example"). + the whole name/command/configfile/languagefile between quotes + ("command or file name"). For example: @@ -249,7 +262,7 @@ In addition, the following commands are available: MOUNT "Emulated Drive letter" "Real Drive or Directory" [-t type] [-aspi] [-ioctl] [-usecd number] [-size drivesize] - [-label drivelabel] [-freesize sizemb] + [-label drivelabel] [-freesize size_in_mb] MOUNT -cd MOUNT -u "Emulated Drive letter" @@ -270,7 +283,7 @@ MOUNT -u "Emulated Drive letter" -size drivesize Sets the size of the drive. - -freesize sizemb + -freesize size_in_mb Sets the amount of free space available on a drive in MB's. This is a more simple version of -size. @@ -319,8 +332,8 @@ MOUNT -u "Emulated Drive letter" General MOUNT Examples: - 1. To mount c:\floppy as a floppy : - mount a c:\floppy -t floppy + 1. To mount c:\DirX as a floppy : + mount a c:\DirX -t floppy 2. To mount system cdrom drive E as cdrom drive D in DOSBox: mount d e:\ -t cdrom 3. To mount system cdrom drive at mountpoint /media/cdrom as cdrom drive D @@ -330,8 +343,8 @@ MOUNT -u "Emulated Drive letter" mount c d:\ -freesize 870 5. To mount a drive with 870 mb free diskspace (experts only, full control): mount c d:\ -size 4025,127,16513,1700 - 6. To mount /home/dos/dosgames as drive C in DOSBox: - mount c /home/dos/dosgames + 6. To mount /home/user/dirY as drive C in DOSBox: + mount c /home/user/dirY MEM Program to display the amount of free memory. @@ -343,6 +356,7 @@ CONFIG [-writeconf] [-writelang] localfile The configuration file controls various settings of DOSBox: The amount of emulated memory, the emulated soundcards and many more things. It allows acces to AUTOEXEC.BAT as well. + See section 9 (The Config File) for more information. The language file controls all visible ouput of the internal commands and the internal dos. @@ -354,8 +368,8 @@ CONFIG [-writeconf] [-writelang] localfile LOADFIX [-size] [program] [program-parameters] LOADFIX -f - Program to "eat up" memory. Useful for old programs which don't expect much - memory to be free. + Program to reduce the amount of memory available. Useful for old programs + which don't expect much memory to be free. -size number of kb to "eat up", default = 64kb @@ -365,7 +379,8 @@ LOADFIX -f Examples: - 1. To start mm2.exe and allocate 64kb memory : + 1. To start mm2.exe and allocate 64kb memory + (mm2 will have 64 kb less available) : loadfix mm2 2. To start mm2.exe and allocate 32kb memory : loadfix -32 mm2 @@ -403,9 +418,9 @@ IMGMOUNT -size [sectorsbytesize, sectorsperhead, heads, cylinders] imagefile - location of the image files to mount in DOSBox. Path is relative to - a mount point already inside DOSBox. CD-ROM images can be mounted - directly as well (path on the host). + location of the image files to mount in DOSBox. The location is on a + mounted drive inside DOSBox. CD-ROM images can be mounted + directly as well. They don't need to be a mounted drive. -t The following are valid image types: @@ -554,7 +569,7 @@ For more information use the /? command line switch with the programs. ALT-ENTER Go full screen and back. CTRL-F1 Start the keymapper. CTRL-F4 Swap mounted disk-image. Update directory cache for all drives! -CTRL-F5 Save a screenshot. +CTRL-F5 Save a screenshot.(png) CTRL-F6 Start/Stop recording sound output to a wave file. CTRL-ALT-F7 Start/Stop recording of OPL commands. CTRL-ALT-F8 Start/Stop the recording of raw MIDI commands. @@ -563,10 +578,16 @@ CTRL-F8 Increase frameskip. CTRL-F9 Kill dosbox. CTRL-F10 Capture/Release the mouse. CTRL-F11 Slow down emulation (Decrease DOSBox Cycles). -CTRL-F12 Speed up emulation (Increase DOSox Cycles). +CTRL-F12 Speed up emulation (Increase DOSBox Cycles). These are the default keybindings. They can be changed in the keymapper. +Saved/recorded files can be found in current_directory/capture +(can be changed in the configfile). +The directory has to exist prior to starting DOSBox else nothing +gets saved/recorded ! + + 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. @@ -578,7 +599,8 @@ This maximum will vary from computer to computer, there is no standard. ============= When you start the keymapper (either with CTRL-F1 or -startmapper as a -commandline argument) you are presented with a virtual keyboard. +commandline argument to the DOSBox executable) you are presented with +a virtual keyboard. This virtual keyboard corresponds with the keys DOSBox will report to its applications. If you click on a key with your mouse, you can see in the diff --git a/configure.in b/configure.in index d7b020ae..53436924 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Init. -AC_INIT(dosbox,0.62) +AC_INIT(dosbox,0.63) AC_PREREQ(2.50) AC_CONFIG_SRCDIR(README) diff --git a/docs/dosbox.1 b/docs/dosbox.1 index 2619b6f5..7ffa8029 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -1,5 +1,5 @@ .\" Hey, EMACS: -*- nroff -*- -.TH DOSBOX 1 "Nov 12, 2004" +.TH DOSBOX 1 "Nov 18, 2004" .\" Please adjust this date whenever revising the manpage. .SH NAME dosbox \- an x86/DOS emulator with sound/graphics @@ -39,7 +39,8 @@ A summary of options is included below. .RI "Runs the specified " command " before running " .BR file . .RI "Multiple commands can be specified. Each " command " should start with " -.BR \-c " though." +.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 " @@ -51,11 +52,13 @@ wish to execute on startup. .IR langfile . .TP .B \-exit -.BR dosbox " will exit after running the program specified by " file . +.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, 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. @@ -88,7 +91,7 @@ Type of the mounted directory. Supported are: dir (standard), floppy, cdrom. .BI \-size " drivesize" Sets the size of the drive. See the examples in the README for details. .TP -.BI \-freesize " freesize" +.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 @@ -151,12 +154,13 @@ the emulated soundcards and many .LP The language file controls all visible ouput of the internal commands and the internal dos. +.RB "See the secion " FILES " for more information." .TP .B LOADFIX [\-size] [programname] [parameters] .LP .B LOADFIX \-f .LP -Program to eat up memory, Useful for old programs which don't expect much memory to be free. +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] @@ -175,31 +179,32 @@ Frees all memory eaten up by loadfix. .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" +.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 . +.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." +.RB "Read the " README " of " dosbox " for the full and correct syntax." .RE .TP .B BOOT .LP -.RB "Boot will start floppy images or hard disk images independent of the operating system emulation offered by " DOSBox ". This will allow you to play booter floppies or boot to other operating systems inside "DOSBox . +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." +.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" +.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." +.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. If a file named @@ -215,7 +220,7 @@ Start the keymapper. Swap mounted disk-image (Only used with imgmount). Update directory cache for all drives! .IP CTRL\-F5 -Save a screenshot. +Save a screenshot.(png) .IP CTRL\-F6 Start/Stop recording sound output to a wave file. .IP CTRL\-ALT\-F7 @@ -231,13 +236,18 @@ Kill dosbox. .IP CTRL\-F10 Capture/Release the mouse. .IP CTRL\-F11 -Slow down emulation (Increase DOSBox Cycles). +Slow down emulation (Increase dosbox Cycles). .IP CTRL\-F12 -Speed up emulation (Decrease DOSBox Cycles). +Speed up emulation (Decrease dosbox Cycles). .PP These are the default keybindings. They can be changed in the keymapper. .PP -.BR "Note: " "Once you increase your " DOSBox " cycles beyond your computer's maximum +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" From abc4450fb67a0865b7f839105fb905f8bb9eae07 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 18 Nov 2004 14:24:59 +0000 Subject: [PATCH 1984/4131] Updates for 0.63 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2067 --- src/platform/visualc/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index bf95d649..d31afd04 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -1,6 +1,6 @@ #define INLINE __forceinline -#define VERSION "0.62" +#define VERSION "0.63" /* Define to 1 to enable internal debugger, requires libcurses */ From c568ff3dd24888f19afdeabcd2cd1cefa19f44eb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 18 Nov 2004 14:56:48 +0000 Subject: [PATCH 1985/4131] Updates for 0.63 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2068 --- ChangeLog | 4 +++- NEWS | 28 ++++++++++++++++++++++++++++ THANKS | 4 ++++ VERSION | 2 +- 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 47848019..910f4d4c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,7 +15,7 @@ - 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. + - 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. @@ -23,6 +23,8 @@ - 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. diff --git a/NEWS b/NEWS index b636030f..efee9e0d 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,31 @@ +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) diff --git a/THANKS b/THANKS index 7bb1097c..b3454f3a 100644 --- a/THANKS +++ b/THANKS @@ -11,5 +11,9 @@ 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. +c2woody for his debug work. All the people who submitted a bug. The Beta Testers. + diff --git a/VERSION b/VERSION index 36808a54..21b86bac 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.62 +0.63 From b59b4b6795b494598d33838d7e2e81b971529eb4 Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Wed, 24 Nov 2004 23:04:45 +0000 Subject: [PATCH 1986/4131] Fixing fat write access. Still no DOS error codes yet, sorry. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2070 --- src/dos/drive_fat.cpp | 71 +++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 71bfd157..d6bdccd9 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.6 2004-11-03 23:13:54 qbix79 Exp $ */ +/* $Id: drive_fat.cpp,v 1.7 2004-11-24 23:04:45 canadacow Exp $ */ #include #include @@ -37,6 +37,9 @@ #define FAT16 1 #define FAT32 2 +Bit8u fatSectBuffer[1024]; +Bit32u curFatSect; + class fatFile : public DOS_File { public: fatFile(const char* name, Bit32u startCluster, Bit32u fileLen, fatDrive *useDrive); @@ -125,13 +128,13 @@ bool fatFile::Read(Bit8u * data, Bit16u *size) { currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); if(currentSector == 0) { /* EOC reached before EOF */ - LOG_MSG("EOC reached before EOF, seekpos %d, filelen %d", seekpos, filelength); + //LOG_MSG("EOC reached before EOF, seekpos %d, filelen %d", seekpos, filelength); *size = sizecount; return true; } curSectOff = 0; myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); - LOG_MSG("Reading absolute sector at %d for seekpos %d", currentSector, seekpos); + //LOG_MSG("Reading absolute sector at %d for seekpos %d", currentSector, seekpos); } --sizedec; sizecount++; @@ -147,12 +150,16 @@ bool fatFile::Write(Bit8u * data, Bit16u *size) { Bit16u sizedec, sizecount; sizedec = *size; sizecount = 0; + while(sizedec != 0) { /* Increase filesize if necessary */ if(seekpos >= filelength) { if(filelength == 0) { firstCluster = myDrive->getFirstFreeClust(); myDrive->allocateCluster(firstCluster, 0); + currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); + myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); + loadedSector = true; } filelength = seekpos+1; } @@ -248,8 +255,7 @@ Bit32u fatDrive::getClusterValue(Bit32u clustNum) { Bit32u clustValue; - /* Load two sectors at once for FAT12 */ - Bit8u sectbuffer[1024]; + switch(fattype) { case FAT12: @@ -265,12 +271,16 @@ Bit32u fatDrive::getClusterValue(Bit32u clustNum) { fatsectnum = bootbuffer.reservedsectors + (fatoffset / bootbuffer.bytespersector) + partSectOff; fatentoff = fatoffset % bootbuffer.bytespersector; - loadedDisk->Read_AbsoluteSector(fatsectnum, §buffer[0]); - loadedDisk->Read_AbsoluteSector(fatsectnum+1, §buffer[512]); + if(curFatSect != fatsectnum) { + /* Load two sectors at once for FAT12 */ + loadedDisk->Read_AbsoluteSector(fatsectnum, &fatSectBuffer[0]); + loadedDisk->Read_AbsoluteSector(fatsectnum+1, &fatSectBuffer[512]); + curFatSect = fatsectnum; + } switch(fattype) { case FAT12: - clustValue = *((Bit16u *)§buffer[fatentoff]); + clustValue = *((Bit16u *)&fatSectBuffer[fatentoff]); if(clustNum & 0x1) { clustValue >>= 4; } else { @@ -278,10 +288,10 @@ Bit32u fatDrive::getClusterValue(Bit32u clustNum) { } break; case FAT16: - clustValue = *((Bit16u *)§buffer[fatentoff]); + clustValue = *((Bit16u *)&fatSectBuffer[fatentoff]); break; case FAT32: - clustValue = *((Bit32u *)§buffer[fatentoff]); + clustValue = *((Bit32u *)&fatSectBuffer[fatentoff]); break; } @@ -295,9 +305,6 @@ void fatDrive::setClusterValue(Bit32u clustNum, Bit32u clustValue) { Bit32u tmpValue; - /* Load two sectors at once for FAT12 */ - Bit8u sectbuffer[1024]; - switch(fattype) { case FAT12: fatoffset = clustNum + (clustNum / 2); @@ -312,12 +319,16 @@ void fatDrive::setClusterValue(Bit32u clustNum, Bit32u clustValue) { fatsectnum = bootbuffer.reservedsectors + (fatoffset / bootbuffer.bytespersector) + partSectOff; fatentoff = fatoffset % bootbuffer.bytespersector; - loadedDisk->Read_AbsoluteSector(fatsectnum, §buffer[0]); - loadedDisk->Read_AbsoluteSector(fatsectnum+1, §buffer[512]); + if(curFatSect != fatsectnum) { + /* Load two sectors at once for FAT12 */ + loadedDisk->Read_AbsoluteSector(fatsectnum, &fatSectBuffer[0]); + loadedDisk->Read_AbsoluteSector(fatsectnum+1, &fatSectBuffer[512]); + curFatSect = fatsectnum; + } switch(fattype) { case FAT12: - tmpValue = *((Bit16u *)§buffer[fatentoff]); + tmpValue = *((Bit16u *)&fatSectBuffer[fatentoff]); if(clustNum & 0x1) { clustValue &= 0xfff; clustValue <<= 4; @@ -329,19 +340,19 @@ void fatDrive::setClusterValue(Bit32u clustNum, Bit32u clustValue) { tmpValue &= 0xf000; tmpValue |= clustValue; } - *((Bit16u *)§buffer[fatentoff]) = tmpValue; + *((Bit16u *)&fatSectBuffer[fatentoff]) = tmpValue; break; case FAT16: - *((Bit16u *)§buffer[fatentoff]) = clustValue; + *((Bit16u *)&fatSectBuffer[fatentoff]) = clustValue; break; case FAT32: - *((Bit32u *)§buffer[fatentoff]) = clustValue; + *((Bit32u *)&fatSectBuffer[fatentoff]) = clustValue; break; } int fc; for(fc=0;fcWrite_AbsoluteSector(fatsectnum + (fc * bootbuffer.sectorsperfat), §buffer[0]); - loadedDisk->Write_AbsoluteSector(fatsectnum+1+(fc * bootbuffer.sectorsperfat), §buffer[512]); + loadedDisk->Write_AbsoluteSector(fatsectnum + (fc * bootbuffer.sectorsperfat), &fatSectBuffer[0]); + loadedDisk->Write_AbsoluteSector(fatsectnum+1+(fc * bootbuffer.sectorsperfat), &fatSectBuffer[512]); } } @@ -355,7 +366,7 @@ bool fatDrive::getEntryName(char *fullname, char *entname) { char * findFile; strcpy(dirtoken,fullname); - LOG_MSG("Testing for filename %s", fullname); + //LOG_MSG("Testing for filename %s", fullname); findDir = strtok(dirtoken,"\\"); findFile = findDir; while(findDir != NULL) { @@ -378,7 +389,7 @@ bool fatDrive::getFileDirEntry(char * filename, direntry * useEntry, Bit32u * di /* Skip if testing in root directory */ if ((len>0) && (filename[len-1]!='\\')) { - LOG_MSG("Testing for filename %s", filename); + //LOG_MSG("Testing for filename %s", filename); findDir = strtok(dirtoken,"\\"); findFile = findDir; while(findDir != NULL) { @@ -418,7 +429,7 @@ bool fatDrive::getDirClustNum(char *dir, Bit32u *clustNum, bool parDir) { /* Skip if testing for root directory */ if ((len>0) && (dir[len-1]!='\\')) { - LOG_MSG("Testing for dir %s", dir); + //LOG_MSG("Testing for dir %s", dir); findDir = strtok(dirtoken,"\\"); while(findDir != NULL) { imgDTA->SetupSearch(0,DOS_ATTR_DIRECTORY,findDir); @@ -449,7 +460,7 @@ Bit32u fatDrive::getSectorSize(void) { } Bit32u fatDrive::getAbsoluteSectFromBytePos(Bit32u startClustNum, Bit32u bytePos) { - return getAbsoluteSectFromChain(startClustNum, bytePos / bootbuffer.bytespersector); + return getAbsoluteSectFromChain(startClustNum, bytePos / bootbuffer.bytespersector); } Bit32u fatDrive::getAbsoluteSectFromChain(Bit32u startClustNum, Bit32u logicalSector) { @@ -473,13 +484,14 @@ Bit32u fatDrive::getAbsoluteSectFromChain(Bit32u startClustNum, Bit32u logicalSe if(testvalue >= 0xfffffff8) isEOF = true; break; } - if((isEOF) && (skipClust>1)) { + if((isEOF) && (skipClust>=1)) { //LOG_MSG("End of cluster chain reached before end of logical sector seek!"); return 0; } currentClust = testvalue; --skipClust; } + return (getClustFirstSect(currentClust) + sectClust); } @@ -559,6 +571,7 @@ bool fatDrive::allocateCluster(Bit32u useCluster, Bit32u prevCluster) { /* Point cluster to new cluster in chain */ setClusterValue(prevCluster, useCluster); + //LOG_MSG("Chaining cluser %d to %d", prevCluster, useCluster); } switch(fattype) { @@ -667,8 +680,8 @@ fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, /* There is no cluster 0, this means we are in the root directory */ cwdDirCluster = 0; - - + memset(fatSectBuffer,0,1024); + curFatSect = 0xffffffff; } @@ -698,7 +711,7 @@ Bit32u fatDrive::getFirstFreeClust(void) { } -bool fatDrive::isRemote(void) { return false; } +bool fatDrive::isRemote(void) { return false; } bool fatDrive::isRemovable(void) { return false; } Bit8u fatDrive::GetMediaByte(void) { return loadedDisk->GetBiosType(); } From f3156933130e4d01cbe799211d2fae7604200c62 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 29 Nov 2004 21:00:55 +0000 Subject: [PATCH 1987/4131] Added support for int 21 65 20,21,22 (language depended capitalisation) (only english though) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2071 --- src/dos/dos.cpp | 58 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 637c91d5..ef070a20 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.77 2004-11-16 14:24:52 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.78 2004-11-29 21:00:55 qbix79 Exp $ */ #include #include @@ -30,11 +30,14 @@ #include "regs.h" #include "dos_inc.h" #include "setup.h" +#include "support.h" DOS_Block dos; DOS_InfoBlock dos_infoblock; -Bit8u dos_copybuf[0x10000]; +#define DOS_COPYBUFSIZE 0x10000 +Bit8u dos_copybuf[DOS_COPYBUFSIZE]; + static Bitu call_20,call_21,call_25,call_26,call_27,call_28,call_29; void DOS_SetError(Bit16u code) { @@ -89,8 +92,9 @@ static Bitu DOS_21Handler(void) { } default: { - Bit8u c=reg_dl;Bit16u n=1; + Bit8u c = reg_dl;Bit16u n = 1; DOS_WriteFile(STDOUT,&c,&n); + reg_al = reg_dl; } break; }; @@ -800,14 +804,15 @@ static Bitu DOS_21Handler(void) { case 0x65: /* Get extented country information and a lot of other useless shit*/ { /* Todo maybe fully support this for now we set it standard for USA */ LOG(LOG_DOSMISC,LOG_ERROR)("DOS:65:Extended country information call %X",reg_ax); - if(reg_cx < 0x05 ) { + if((reg_al <= 0x07) && (reg_cx < 0x05)) { DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); CALLBACK_SCF(true); break; } + Bitu len = 0; /* For 0x21 and 0x22 */ PhysPt data=SegPhys(es)+reg_di; switch (reg_al) { - case 1: + case 0x01: mem_writeb(data + 0x00,reg_al); mem_writew(data + 0x01,0x26); mem_writew(data + 0x03,1); @@ -819,15 +824,40 @@ static Bitu DOS_21Handler(void) { } CALLBACK_SCF(false); break; - case 2: // Get pointer to uppercase table - case 3: // Get pointer to lowercase table - case 4: // Get pointer to filename uppercase table - case 5: // Get pointer to filename terminator table - case 6: // Get pointer to collating sequence table - case 7: // Get pointer to double byte char set table - mem_writeb(data,reg_al); - mem_writed(data+1,dos.tables.dcbs); //used to be 0 - reg_cx=5; + case 0x02: // Get pointer to uppercase table + case 0x03: // Get pointer to lowercase table + case 0x04: // Get pointer to filename uppercase table + case 0x05: // Get pointer to filename terminator table + case 0x06: // Get pointer to collating sequence table + case 0x07: // Get pointer to double byte char set table + mem_writeb(data + 0x00, reg_al); + mem_writed(data + 0x01, dos.tables.dcbs); //used to be 0 + reg_cx = 5; + CALLBACK_SCF(false); + break; + case 0x20: /* Capitalize Character */ + { + int in = reg_dl; + int out = toupper(in); + reg_dl = out; + } + CALLBACK_SCF(false); + break; + case 0x21: /* Capitalize String (cx=length) */ + case 0x22: /* Capatilize ASCIZ string */ + data = SegPhys(ds) + reg_dx; + if(reg_al == 0x21) len = reg_cx; + else len = mem_strlen(data); /* Is limited to 1024 */ + + if(len > DOS_COPYBUFSIZE - 1) E_Exit("DOS:0x65 Buffer overflow"); + if(len) { + MEM_BlockRead(data,dos_copybuf,len); + dos_copybuf[len] = 0; + //No upcase as String(0x21) might be multiple asciz strings + for(Bitu count = 0; count < len;count++) + dos_copybuf[count] = toupper(*reinterpret_cast(dos_copybuf+count)); + MEM_BlockWrite(data,dos_copybuf,len); + } CALLBACK_SCF(false); break; default: From 0fb7da08014ab58de49c8b238827a53eacbb9972 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 4 Dec 2004 08:02:09 +0000 Subject: [PATCH 1988/4131] Added empty cpsw function Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2072 --- src/dos/dos.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index ef070a20..e0bc2665 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.78 2004-11-29 21:00:55 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.79 2004-12-04 08:02:09 qbix79 Exp $ */ #include #include @@ -350,6 +350,11 @@ static Bitu DOS_21Handler(void) { case 0:reg_dl=dos.breakcheck;break; /* Get the breakcheck flag */ case 1:dos.breakcheck=(reg_dl>0);break; /* Set the breakcheck flag */ case 2:{bool old=dos.breakcheck;dos.breakcheck=(reg_dl>0);reg_dl=old;}break; + case 3: /* Get cpsw */ + /* Fallthrough */ + case 4: /* Set cpsw */ + LOG(LOG_DOSMISC,LOG_ERROR)("Someone playing with cpsw %x",reg_ax); + break; case 5:reg_dl=3;break;//TODO should be z /* Always boot from c: :) */ case 6: /* Get true version number */ reg_bl=dos.version.major; From 688c8f114f13536eeb2ef0e616b74e4ebc62bd64 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 7 Dec 2004 21:29:14 +0000 Subject: [PATCH 1989/4131] better port write decoding(wd) and some changes to run_irq loop Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2073 --- src/hardware/pic.cpp | 133 +++++++++++++++++++++---------------------- 1 file changed, 65 insertions(+), 68 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 3a412567..279b80ce 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.25 2004-11-15 14:56:55 qbix79 Exp $ */ +/* $Id: pic.cpp,v 1.26 2004-12-07 21:29:14 qbix79 Exp $ */ #include @@ -44,6 +44,7 @@ struct PIC_Controller { bool special; bool auto_eoi; + bool rotate_on_auto_eoi; bool request_issr; Bit8u vector_base; }; @@ -75,70 +76,61 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { Bitu i; Bit16u IRQ_priority_table[16] = { 0,1,2,9,10,11,12,13,14,15,3,4,5,6,7,8 }; - switch (val) { - case 0x0A: /* select read interrupt request register */ - pic->request_issr=false; - break; - case 0x0B: /* select read interrupt in-service register */ - pic->request_issr=true; - break; - case 0x10: /* ICW1 */ - pic->icw_index=1; - pic->icw_words=2; - break; - case 0x11: /* ICW1 + need for ICW4 */ - pic->icw_index=1; - pic->icw_words=3; - break; - case 0x20:case 0x21:case 0x22:case 0x23:case 0x24:case 0x25:case 0x26:case 0x27: - if (PIC_IRQActive<(irq_base+8)) { - irqs[PIC_IRQActive].inservice=false; - PIC_IRQActive=PIC_NOIRQ; - for (i=0; i<=15; i++){ - if(irqs[IRQ_priority_table[i]].inservice) { - PIC_IRQActive=IRQ_priority_table[i]; - break; + if (val&0x10) { // ICW1 issued + if (val&0x02) E_Exit("PIC: single mode not handled"); // (would have to skip ICW3) + if (val&0x04) E_Exit("PIC: 4 byte interval not handled"); + if (val&0x08) E_Exit("PIC: level triggered mode not handled"); + if (val&0xe0) E_Exit("PIC: 8080/8085 mode not handled"); + pic->icw_index=1; // next is ICW3 + pic->icw_words=2+val&0x01; // =3 if ICW4 needed + } else if (val&0x08) { // OCW3 issued + if (val&0x04) E_Exit("PIC: poll command not handled"); + if (val&0x02) { // function select + if (val&0x01) pic->request_issr=true; /* select read interrupt in-service register */ + else pic->request_issr=false; /* select read interrupt request register */ + } + if (val&0x40) { // special mask select + if (val&0x20) pic->special=true; + else pic->special=false; + LOG(LOG_PIC,LOG_NORMAL)("port %X : special mask %s",port,(pic->special)?"ON":"OFF"); + } + } else { // OCW2 issued + if (val&0x20) { // EOI commands + if (val&0x80) E_Exit("rotate mode not supported"); + if (val&0x40) { // specific EOI + if (PIC_IRQActive==(irq_base+val-0x60U)) { + irqs[PIC_IRQActive].inservice=false; + PIC_IRQActive=PIC_NOIRQ; + for (i=0; i<=15; i++) { + if (irqs[IRQ_priority_table[i]].inservice) { + PIC_IRQActive=IRQ_priority_table[i]; + break; + } + } } - } - } //TODO Warnings? - break; - case 0x4a: /* OCW3 select read interrupt request register */ - LOG(LOG_PIC,LOG_NORMAL)("port %X : special OFF",port); - pic->special = false; - pic->request_issr = false; - break; - case 0x60:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:case 0x67: - /* Spefific EOI 0-7 */ - if (PIC_IRQActive==(irq_base+val-0x60U)) { - irqs[PIC_IRQActive].inservice=false; - PIC_IRQActive=PIC_NOIRQ; - for (i=0; i<=15; i++) { - if (irqs[IRQ_priority_table[i]].inservice) { - PIC_IRQActive=IRQ_priority_table[i]; - break; + if (val&0x80); // perform rotation + } else { // nonspecific EOI + if (PIC_IRQActive<(irq_base+8)) { + irqs[PIC_IRQActive].inservice=false; + PIC_IRQActive=PIC_NOIRQ; + for (i=0; i<=15; i++){ + if(irqs[IRQ_priority_table[i]].inservice) { + PIC_IRQActive=IRQ_priority_table[i]; + break; + } + } } + if (val&0x80); // perform rotation } - }//TODO Warnings? - break; - case 0x68:/* OCW3 select */ - pic->special=true; - LOG(LOG_PIC,LOG_NORMAL)("port %X : special ON",port); - break; - case 0x6b: /* OCW3 select read interrupt in-service register */ - LOG(LOG_PIC,LOG_NORMAL)("port %X : special ON",port); - pic->special = true; - pic->request_issr = true; - break; - case 0xC0:case 0xC1:case 0xC2:case 0xC3:case 0xC4:case 0xC5:case 0xC6:case 0xC7: - /* Priority order, no need for it */ - break; - case 0x00:case 0x80: /* Rotate stuff in eoi mode */ - /* We can live without it for now. (7 cities of gold) */ - LOG(LOG_PIC,LOG_NORMAL)("port %X : ignoring rotate stuff.",port); - break; - default: - E_Exit("PIC:Unhandled command %02X",val); - } + } else { + if ((val&0x40)==0) { // rotate in auto EOI mode + if (val&0x80) pic->rotate_on_auto_eoi=true; + else pic->rotate_on_auto_eoi=false; + } else if (val&0x80) { + E_Exit("set priority command not handled"); + } // else NOP command + } + } // end OCW2 } static void write_data(Bitu port,Bitu val,Bitu iolen) { @@ -174,7 +166,7 @@ static void write_data(Bitu port,Bitu val,Bitu iolen) { case 3: /* icw 4 */ /* 0 1 8086/8080 0 mcs-8085 mode - 1 1 Auto EOI 1 Normal EOI + 1 1 Auto EOI 0 Normal EOI 2-3 0x Non buffer Mode 10 Buffer Mode Slave 11 Buffer mode Master @@ -183,9 +175,13 @@ static void write_data(Bitu port,Bitu val,Bitu iolen) { pic->auto_eoi=(val & 0x2)>0; LOG(LOG_PIC,LOG_NORMAL)("%d:ICW 4 %X",port==0x21 ? 0 : 1,val); + + if ((val&0x01)==0) E_Exit("PIC:ICW4: %x, 8085 mode not handled",val); + if ((val&0x10)==0) E_Exit("PIC:ICW4: %x, special fully-nested mode not handled",val); + if(pic->icw_index++ >= pic->icw_words) pic->icw_index=0; break; - default: /* icw 3, and 4*/ + default: LOG(LOG_PIC,LOG_NORMAL)("ICW HUH? %X",val); } } @@ -246,15 +242,16 @@ void PIC_runIRQs(void) { Bit16u activeIRQ = PIC_IRQActive; if (activeIRQ==PIC_NOIRQ) activeIRQ = 16; for (i=0;i<=15;i++) { - if ((IRQ_priority_lookup[i] Date: Tue, 7 Dec 2004 21:33:26 +0000 Subject: [PATCH 1990/4131] Irq changed to 9 and unmasking it on startup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2074 --- src/hardware/mpu401.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 412ef88a..a1d55b81 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -6,6 +6,8 @@ #include "cpu.h" #include "callback.h" +/* $Id: mpu401.cpp,v 1.11 2004-12-07 21:33:26 qbix79 Exp $ */ + void MIDI_RawOutByte(Bit8u data); bool MIDI_Available(void); @@ -325,6 +327,8 @@ static void MPU401_WriteCommand(Bitu port,Bitu val,Bitu iolen) { case CMD_REQUEST_VERSION: QueueByte(MSG_CMD_ACK); QueueByte(MPU_VERSION); + mpu.state.irq_pending=true; + PIC_ActivateIRQ(mpu.irq); //timequest return; case CMD_REQUEST_REVISION: QueueByte(MSG_CMD_ACK); @@ -737,6 +741,8 @@ void MPU401_Init(Section* sec) { mpu.mode=M_UART; if (!(mpu.intelligent=section->Get_bool("intelligent"))) return; - mpu.irq=2; + /*Set IRQ and unmask it(for timequest/princess maker 2) */ + mpu.irq=9; + PIC_SetIRQMask(mpu.irq,false); MPU401_Reset(); } From e79fab40ea5fcd414b34e2fc4beb972ad3815c76 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 7 Dec 2004 21:49:13 +0000 Subject: [PATCH 1991/4131] Some changes for legends of valour(hiding cursor on reset) and Grand Prix Unlimited(cursor in the middle of the screen) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2075 --- src/dosbox.cpp | 4 ++-- src/ints/mouse.cpp | 32 +++++++++++++++++++++----------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 33fa139a..98294652 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.80 2004-09-21 19:32:15 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.81 2004-12-07 21:49:06 qbix79 Exp $ */ #include #include @@ -260,7 +260,6 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&DMA_Init); secprop->AddInitFunction(&VGA_Init); secprop->AddInitFunction(&KEYBOARD_Init); - secprop->AddInitFunction(&MOUSE_Init); secprop->AddInitFunction(&JOYSTICK_Init); secprop=control->AddSection_prop("mixer",&MIXER_Init); @@ -353,6 +352,7 @@ void DOSBOX_Init(void) { ); secprop=control->AddSection_prop("bios",&BIOS_Init); secprop->AddInitFunction(&INT10_Init); + secprop->AddInitFunction(&MOUSE_Init); //Must be after int10 as it uses CurMode /* All the DOS Related stuff, which will eventually start up in the shell */ //TODO Maybe combine most of the dos stuff in one section like ems,xms diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 9341c260..1bc91607 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.42 2004-08-04 09:12:56 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.43 2004-12-07 21:49:13 qbix79 Exp $ */ #include #include @@ -407,11 +407,10 @@ void DrawCursor() { void Mouse_CursorMoved(float x,float y) { float dx = x * mouse.pixelPerMickey_x; float dy = y * mouse.pixelPerMickey_y; - if((fabs(x) > 1.0) || (mouse.senv_y < 1.0)) dx *= mouse.senv_x; + if((fabs(x) > 1.0) || (mouse.senv_x < 1.0)) dx *= mouse.senv_x; if((fabs(y) > 1.0) || (mouse.senv_y < 1.0)) dy *= mouse.senv_y; - mouse.mickey_x += dx; mouse.mickey_y += dy; mouse.x += dx; @@ -543,8 +542,8 @@ void Mouse_NewVideoMode(void) mouse.min_x = 0; mouse.min_y = 0; // Dont set max coordinates here. it is done by SetResolution! - mouse.x = static_cast(mouse.max_x / 2); - mouse.y = static_cast(mouse.max_y / 2); + mouse.x = static_cast((mouse.max_x + 1)/ 2); + mouse.y = static_cast((mouse.max_y + 1)/ 2); mouse.events = 0; mouse.mickey_x = 0; mouse.mickey_y = 0; @@ -580,6 +579,12 @@ void Mouse_NewVideoMode(void) static void mouse_reset(void) { //Much to empty Mouse_NewVideoMode contains stuff that should be in here + + /* Remove drawn mouse Legends of Valor */ + if (CurMode->type!=M_TEXT) RestoreCursorBackground(); + else RestoreCursorBackgroundText(); + mouse.shown = -1; + Mouse_NewVideoMode(); mouse.sub_mask=0; @@ -589,8 +594,6 @@ static void mouse_reset(void) { mouse.senv_y=1.0; - - //Added this for cd-v19 } static Bitu INT33_Handler(void) { @@ -613,8 +616,8 @@ static Bitu INT33_Handler(void) { break; case 0x02: /* Hide Mouse */ { - if (CurMode->type!=M_TEXT) RestoreCursorBackground(); - else RestoreCursorBackgroundText(); + if (CurMode->type!=M_TEXT) RestoreCursorBackground(); + else RestoreCursorBackgroundText(); mouse.shown--; } break; @@ -624,8 +627,14 @@ static Bitu INT33_Handler(void) { reg_dx=POS_Y; break; case 0x04: /* Position Mouse */ - mouse.x = static_cast(((reg_cx > mouse.max_x) ? mouse.max_x : reg_cx)); - mouse.y = static_cast(((reg_dx > mouse.max_y) ? mouse.max_y : reg_dx)); + if(reg_cx > mouse.max_x) mouse.x = static_cast(mouse.max_x); + else if (mouse.min_x > reg_cx) mouse.x = static_cast(mouse.min_x); + else mouse.x = static_cast(reg_cx); + + if(reg_dx > mouse.max_y) mouse.y = static_cast(mouse.max_y); + else if (mouse.min_y > reg_dx) mouse.y = static_cast(mouse.min_y); + else mouse.y = static_cast(reg_dx); + DrawCursor(); break; case 0x05: /* Return Button Press Data */ @@ -906,6 +915,7 @@ void MOUSE_Init(Section* sec) { CALLBACK_Setup(call_ps2,&PS2_Handler,CB_IRET,"ps2 bios callback"); ps2_callback=CALLBACK_RealPointer(call_ps2); memset(&mouse,0,sizeof(mouse)); + mouse.shown=-1; //Hide mouse on startup mouse_reset_hardware(); mouse_reset(); } From 2e5c63acec8b647fa6224d5d12a739d72387377f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 8 Dec 2004 22:39:49 +0000 Subject: [PATCH 1992/4131] Add patch 1070612 from Jon Niehof Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2076 --- src/ints/bios.cpp | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index e617ee36..dc343aef 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.36 2004-10-23 15:15:06 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.37 2004-12-08 22:39:49 qbix79 Exp $ */ #include #include "dosbox.h" @@ -238,7 +238,7 @@ static Bitu INT15_Handler(void) { } break; case 0x84: /* BIOS - JOYSTICK SUPPORT (XT after 11/8/82,AT,XT286,PS) */ - if (reg_dx==0x0000) { + if (reg_dx == 0x0000) { // Get Joystick button status if (JOYSTICK_IsEnabled(0) || JOYSTICK_IsEnabled(1)) { reg_al = (JOYSTICK_GetButton(0,0)<<7)|(JOYSTICK_GetButton(0,1)<<6); @@ -249,15 +249,25 @@ static Bitu INT15_Handler(void) { reg_ax = 0x00f0; reg_dx = 0x0201; CALLBACK_SCF(true); } - } else if (reg_dx==0x0001) { - if (JOYSTICK_IsEnabled(0) || JOYSTICK_IsEnabled(1)) { - reg_ax = (Bit16u)JOYSTICK_GetMove_X(0); - reg_bx = (Bit16u)JOYSTICK_GetMove_Y(0); - reg_cx = (Bit16u)JOYSTICK_GetMove_X(1); - reg_dx = (Bit16u)JOYSTICK_GetMove_Y(1); + } else if (reg_dx == 0x0001) { + if (JOYSTICK_IsEnabled(0)) { + reg_ax = (Bit16u)(JOYSTICK_GetMove_X(0)*127+128); + reg_bx = (Bit16u)(JOYSTICK_GetMove_Y(0)*127+128); + if(JOYSTICK_IsEnabled(1)) { + reg_cx = (Bit16u)(JOYSTICK_GetMove_X(1)*127+128); + reg_dx = (Bit16u)(JOYSTICK_GetMove_Y(1)*127+128); + } + else { + reg_cx = reg_dx = 0; + } + CALLBACK_SCF(false); + } else if (JOYSTICK_IsEnabled(1)) { + reg_ax = reg_bx = 0; + reg_cx = (Bit16u)(JOYSTICK_GetMove_X(1)*127+128); + reg_dx = (Bit16u)(JOYSTICK_GetMove_Y(1)*127+128); CALLBACK_SCF(false); } else { - reg_ax=reg_bx=reg_cx=reg_dx=0; + reg_ax = reg_bx = reg_cx = reg_dx = 0; CALLBACK_SCF(true); } } else { From d1faa25ea77ea6203e748b6ab82929b459ab5ba7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 14 Dec 2004 21:02:57 +0000 Subject: [PATCH 1993/4131] Cleanup + fix all known issues Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2077 --- src/hardware/mpu401.cpp | 436 ++++++++++++++-------------------------- 1 file changed, 152 insertions(+), 284 deletions(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index a1d55b81..a7ff9949 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -1,3 +1,23 @@ +/* + * Copyright (C) 2002-2004 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* $Id: mpu401.cpp,v 1.12 2004-12-14 21:02:57 qbix79 Exp $ */ + #include #include "dosbox.h" #include "inout.h" @@ -6,7 +26,6 @@ #include "cpu.h" #include "callback.h" -/* $Id: mpu401.cpp,v 1.11 2004-12-07 21:33:26 qbix79 Exp $ */ void MIDI_RawOutByte(Bit8u data); bool MIDI_Available(void); @@ -16,171 +35,42 @@ static void MPU401_Event(Bitu); static void MPU401_Reset(void); static void MPU401_EOIHandler(void); -#define MPU_QUEUE 32 -#define TIMECONSTANT (60000000/1000.0f) +#define MPU401_VERSION 0x15 +#define MPU401_REVISION 0x01 +#define MPU401_QUEUE 32 +#define MPU401_TIMECONSTANT (60000000/1000.0f) -enum MpuMode { M_UART,M_INTELLIGENT } ; +enum MpuMode { M_UART,M_INTELLIGENT }; enum MpuDataType {OVERFLOW,MARK,MIDI_SYS,MIDI_NORM,COMMAND}; -///////////////////////////////////////////////////////////////////////////// -// I/O -///////////////////////////////////////////////////////////////////////////// +/* Messages sent to MPU-401 from host */ +#define MSG_EOX 0xf7 +#define MSG_OVERFLOW 0xf8 +#define MSG_MARK 0xfc -#define MPU_STATUS_DSR (1 << 7) -#define MPU_STATUS_DRR (1 << 6) -#define MPU_STATUS_PAD (0xff & (~(MPU_STATUS_DRR | MPU_STATUS_DSR))) - -#define MK_MPU_STATUS(dsr, drr)\ - (((dsr) ? 0 : MPU_STATUS_DSR) | ((drr) ? 0 : MPU_STATUS_DRR) | MPU_STATUS_PAD) - - -///////////////////////////////////////////////////////////////////////////// -// Commands -///////////////////////////////////////////////////////////////////////////// - -/** Copyright notice for MPU-401 intelligent-mode command constants ********* - - MPU-401 MIDI Interface Module v1.0 - Copyright (c) 1991, Robin Davies. All Rights Reserved. - - Robin Davies - 224 3rd Avenue - Ottawa, Ontario - Canada. K1S 2K3. - - updated by: - - Larry Troxler, Compuserve 73520,1736 - - - 15.02.2004: updated and implemented intelligent mode - -****************************************************************************/ - -// Start/Stop Commands - -#define CMD_MIDI_STOP 0x01 -#define CMD_MIDI_START 0x02 -#define CMD_MIDI_CONTINUE 0x03 - -#define CMD_PLAY_STOP 0x04 -#define CMD_PLAY_START 0x08 -#define CMD_PLAY_CONTINUE 0x0c - -#define CMD_RECORD_STOP 0x10 -#define CMD_RECORD_START 0x20 - -// Commands - -#define CMD_DISABLE_ALL_NOTES_OFF 0x30 -#define CMD_DISABLE_REAL_TIME_OUT 0x32 -#define CMD_DISABLE_ALL_THRU_OFF 0x33 -#define CMD_TIMING_BYTE_ALWAYS 0x34 -#define CMD_MODE_MESS_ON 0x35 -#define CMD_EXCLUSIVE_THRU_ON 0x37 -#define CMD_COMMON_TO_HOST_ON 0x38 -#define CMD_REAL_TIME_TO_HOST_ON 0x39 -#define CMD_UART_MODE 0x3f - -#define CMD_INT_CLOCK 0x80 -#define CMD_FSK_CLOCK 0x81 -#define CMD_MIDI_CLOCK 0x82 -#define CMD_METRONOME_ON 0x83 -#define CMD_METRONOME_OFF 0x84 -#define CMD_METRONOME_W_ACCENTS 0x85 -#define CMD_BENDER_OFF 0x86 -#define CMD_BENDER_ON 0x87 -#define CMD_MIDI_THRU_OFF 0x88 -#define CMD_MIDI_THRU_ON 0x89 -#define CMD_DATA_IN_STOP_MODE_OFF 0x8a -#define CMD_DATA_IN_STOP_MODE_ON 0x8b -#define CMD_SEND_MEASURE_END_OFF 0x8c -#define CMD_SEND_MEASURE_END_ON 0x8d -#define CMD_CONDUCTOR_OFF 0x8e -#define CMD_CONDUCTOR_ON 0x8f -#define CMD_REAL_TIME_AFFECTION_OFF 0x90 -#define CMD_REAL_TIME_AFFECTION_ON 0x91 -#define CMD_FSK_TO_INTERNAL 0x92 -#define CMD_FSK_TO_MIDI 0x93 -#define CMD_CLOCK_TO_HOST_OFF 0x94 -#define CMD_CLOCK_TO_HOST_ON 0x95 -#define CMD_EXCLUSIVE_TO_HOST_OFF 0x96 -#define CMD_EXCLUSIVE_TO_HOST_ON 0x97 - -#define CMD_RESET_RELATIVE_TEMPO 0xb1 -#define CMD_CLEAR_PLAY_COUNTERS 0xb8 -#define CMD_CLEAR_PLAY_MAP 0xb9 -#define CMD_CLEAR_RECORD_COUNTER 0xba -#define CMD_TIMEBASE_48 0xc2 -#define CMD_TIMEBASE_72 0xc3 -#define CMD_TIMEBASE_96 0xc4 -#define CMD_TIMEBASE_120 0xc5 -#define CMD_TIMEBASE_144 0xc6 -#define CMD_TIMEBASE_168 0xc7 -#define CMD_TIMEBASE_192 0xc8 - -#define CMD_REQUEST_TO_SEND_DATA 0xd0 /* + track #! */ -#define CMD_REQUEST_TO_SEND_SYSTEM_MSG 0xdf - -#define CMD_SET_TEMPO 0xe0 -#define CMD_RELATIVE_TEMPO 0xe1 -#define CMD_RELATIVE_TEMPO_GRADUATION 0xe2 -#define CMD_MIDI_METRONOME 0xe4 -#define CMD_MEASURE_LENGTH 0xe6 -#define CMD_INTERNAL_CLOCK_LENGTH_TO_HOST 0xe7 -#define CMD_ACTIVE_TRACK_MASK 0xec -#define CMD_SEND_PLAY_COUNTER_MASK 0xed -#define CMD_MIDI_CHANNEL_MASK_LO 0xee -#define CMD_MIDI_CHANNEL_MASK_HI 0xef - -#define CMD_EOX 0xf7 -#define CMD_TIMING_OVERFLOW 0xf8 -#define CMD_MPU_MARK 0xfc -#define CMD_RESET 0xff - -// Commands that return data - -#define CMD_REQUEST_PLAY_COUNTER 0xa0 /* + track # */ -#define CMD_REQUEST_AND_CLEAR_REC_COUNTER 0xab -#define CMD_REQUEST_VERSION 0xac -#define CMD_REQUEST_REVISION 0xad -#define CMD_REQUEST_TEMPO 0xaf - - -///////////////////////////////////////////////////////////////////////////// -// Messages -///////////////////////////////////////////////////////////////////////////// - -#define MSG_TIMING_OVERFLOW 0xf8 -#define MSG_ALL_END 0xfc -#define MSG_CLOCK_TO_HOST 0xfd -#define MSG_CMD_ACK 0xfe -#define MSG_REQUEST_DATA 0xf0 -#define MSG_REQUEST_COMMAND 0xf9 - -#define MPU_VERSION 0x15 -#define MPU_REVISION 0x01 - -///////////////////////////////////////////////////////////////////////////// +/* Messages sent to host from MPU-401 */ +#define MSG_MPU_OVERFLOW 0xf8 +#define MSG_MPU_COMMAND_REQ 0xf9 +#define MSG_MPU_END 0xfc +#define MSG_MPU_CLOCK 0xfd +#define MSG_MPU_ACK 0xfe static struct { bool intelligent; MpuMode mode; Bitu irq; - Bit8u queue[MPU_QUEUE]; + Bit8u queue[MPU401_QUEUE]; Bitu queue_pos,queue_used; struct track { Bits counter; - Bit8u value[8]; + Bit8u value[8],sys_val; Bit8u vlength,length; MpuDataType type; } playbuf[8],condbuf; struct { bool conductor,cond_req,cond_set; - bool allnotes,realtime,allthru; - bool playing; + bool playing,reset; bool wsd,wsm,wsd_start; - bool midi_thru; bool run_irq,irq_pending; bool send_now; Bits data_onoff; @@ -188,7 +78,7 @@ static struct { Bit8u tmask,cmask,amask; Bit16u midi_mask; Bit16u req_mask; - Bit8u channel; + Bit8u channel,old_chan; } state; struct { Bit8u timebase,old_timebase; @@ -202,10 +92,14 @@ static struct { static void QueueByte(Bit8u data) { - if (mpu.queue_used=MPU_QUEUE) mpu.queue_pos-=MPU_QUEUE; - if (pos>=MPU_QUEUE) pos-=MPU_QUEUE; + if (mpu.queue_pos>=MPU401_QUEUE) mpu.queue_pos-=MPU401_QUEUE; + if (pos>=MPU401_QUEUE) pos-=MPU401_QUEUE; mpu.queue_used++; mpu.queue[pos]=data; } else LOG(LOG_MISC,LOG_NORMAL)("MPU401:Data queue full"); @@ -223,132 +117,111 @@ static Bitu MPU401_ReadStatus(Bitu port,Bitu iolen) { } static void MPU401_WriteCommand(Bitu port,Bitu val,Bitu iolen) { - LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Command %x",val); + mpu.state.reset=0; if (val && val<=0x2f) { - switch (val&3) { + switch (val&3) { /* MIDI stop, start, continue */ case 1: {MIDI_RawOutByte(0xfc);break;} case 2: {MIDI_RawOutByte(0xfa);break;} case 3: {MIDI_RawOutByte(0xfb);break;} } if (val&0x20) LOG(LOG_MISC,LOG_ERROR)("MPU-401:Unhandled Recording Command %x",val); switch (val&0xc) { - case 0x4: /* Stop */ + case 0x4: /* Stop */ PIC_RemoveEvents(MPU401_Event); mpu.state.playing=false; - for (Bitu i=0xb0;i<0xbf;i++) {//All notes off + for (Bitu i=0xb0;i<0xbf;i++) { /* All notes off */ MIDI_RawOutByte(i); MIDI_RawOutByte(0x7b); MIDI_RawOutByte(0); } - ClrQueue(); break; - case 0x8: /* Play */ + case 0x8: /* Play */ + LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Intelligent mode playback started"); mpu.state.playing=true; PIC_RemoveEvents(MPU401_Event); - PIC_AddEvent(MPU401_Event,TIMECONSTANT/(mpu.clock.tempo*mpu.clock.timebase)); - mpu.state.irq_pending=false; + PIC_AddEvent(MPU401_Event,MPU401_TIMECONSTANT/(mpu.clock.tempo*mpu.clock.timebase)); + ClrQueue(); break; } } - else if (val>=0xa0 && val<=0xa7) {/* Request play counter */ + else if (val>=0xa0 && val<=0xa7) { /* Request play counter */ if (mpu.state.cmask&(1<<(val&7))) QueueByte(mpu.playbuf[val&7].counter); } - else if (val>=0xd0 && val<=0xd7) { /* Request to send data */ + else if (val>=0xd0 && val<=0xd7) { /* Send data */ + mpu.state.old_chan=mpu.state.channel; mpu.state.channel=val&7; mpu.state.wsd=true; mpu.state.wsm=false; mpu.state.wsd_start=true; - } + } else switch (val) { - case CMD_REQUEST_TO_SEND_SYSTEM_MSG: + case 0xdf: /* Send system message */ mpu.state.wsd=false; mpu.state.wsm=true; mpu.state.wsd_start=true; break; - case CMD_CONDUCTOR_ON: - mpu.state.cond_set=true; - break; - case CMD_CONDUCTOR_OFF: + case 0x8e: /* Conductor */ mpu.state.cond_set=false; break; - case CMD_CLOCK_TO_HOST_OFF: + case 0x8f: + mpu.state.cond_set=true; + break; + case 0x94: /* Clock to host */ mpu.clock.clock_to_host=false; break; - case CMD_CLOCK_TO_HOST_ON: + case 0x95: mpu.clock.clock_to_host=true; break; - case CMD_REAL_TIME_AFFECTION_OFF: - break; - case CMD_REAL_TIME_AFFECTION_ON: - LOG(LOG_MISC,LOG_ERROR)("MPU401:Unimplemented:Realtime affection:ON"); - break; - case CMD_MIDI_THRU_OFF: - mpu.state.midi_thru=false; - break; - case CMD_MIDI_THRU_ON: - mpu.state.midi_thru=true; - break; - case CMD_TIMEBASE_48: /* Internal clock resolution per beat */ + case 0xc2: /* Internal timebase */ mpu.clock.timebase=48; break; - case CMD_TIMEBASE_72: + case 0xc3: mpu.clock.timebase=72; break; - case CMD_TIMEBASE_96: + case 0xc4: mpu.clock.timebase=96; break; - case CMD_TIMEBASE_120: + case 0xc5: mpu.clock.timebase=120; break; - case CMD_TIMEBASE_144: + case 0xc6: mpu.clock.timebase=144; break; - case CMD_TIMEBASE_168: + case 0xc7: mpu.clock.timebase=168; break; - case CMD_TIMEBASE_192: + case 0xc8: mpu.clock.timebase=192; break; /* Commands with data byte */ - case CMD_MIDI_METRONOME: - case CMD_MEASURE_LENGTH: - case CMD_RELATIVE_TEMPO: - case CMD_SET_TEMPO: - case CMD_RELATIVE_TEMPO_GRADUATION: - case CMD_INTERNAL_CLOCK_LENGTH_TO_HOST: - case CMD_ACTIVE_TRACK_MASK: - case CMD_SEND_PLAY_COUNTER_MASK: - case CMD_MIDI_CHANNEL_MASK_LO: - case CMD_MIDI_CHANNEL_MASK_HI: + case 0xe0: case 0xe1: case 0xe2: case 0xe4: case 0xe6: + case 0xe7: case 0xec: case 0xed: case 0xee: case 0xef: mpu.state.command_byte=val; break; - /* Commands Returning Data */ - case CMD_REQUEST_VERSION: - QueueByte(MSG_CMD_ACK); - QueueByte(MPU_VERSION); - mpu.state.irq_pending=true; - PIC_ActivateIRQ(mpu.irq); //timequest - return; - case CMD_REQUEST_REVISION: - QueueByte(MSG_CMD_ACK); - QueueByte(MPU_REVISION); - return; - case CMD_REQUEST_TEMPO: - QueueByte(MSG_CMD_ACK); - QueueByte(mpu.clock.tempo); - return; - case CMD_REQUEST_AND_CLEAR_REC_COUNTER: - QueueByte(MSG_CMD_ACK); + /* Commands 0xa# returning data */ + case 0xab: /* Request and clear recording counter */ + QueueByte(MSG_MPU_ACK); QueueByte(0); return; - case CMD_RESET_RELATIVE_TEMPO: + case 0xac: /* Request version */ + QueueByte(MSG_MPU_ACK); + QueueByte(MPU401_VERSION); + return; + case 0xad: /* Request revision */ + QueueByte(MSG_MPU_ACK); + QueueByte(MPU401_REVISION); + return; + case 0xaf: /* Request tempo */ + QueueByte(MSG_MPU_ACK); + QueueByte(mpu.clock.tempo); + return; + case 0xb1: /* Reset relative tempo */ mpu.clock.tempo_rel=40; break; - case CMD_CLEAR_PLAY_MAP: - mpu.state.tmask=0; - case CMD_CLEAR_PLAY_COUNTERS: - for (Bitu i=0xb0;i<0xbf;i++) {//All notes off + case 0xb9: /* Clear play map */ + case 0xb8: /* Clear play counters */ + for (Bitu i=0xb0;i<0xbf;i++) { /* All notes off */ MIDI_RawOutByte(i); MIDI_RawOutByte(0x7b); MIDI_RawOutByte(0); @@ -362,51 +235,42 @@ static void MPU401_WriteCommand(Bitu port,Bitu val,Bitu iolen) { if (!(mpu.state.conductor=mpu.state.cond_set)) mpu.state.cond_req=0; mpu.state.amask=mpu.state.tmask; mpu.state.req_mask=0; + mpu.state.irq_pending=true; break; - case CMD_RESET: /* Reset MPU401 */ + case 0xff: /* Reset MPU-401 */ + LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Reset %X",val); + mpu.state.reset=1; MPU401_Reset(); - if (mpu.intelligent) { - QueueByte(MSG_CMD_ACK); //additional ACK for interrupt routine - mpu.state.irq_pending=true; - PIC_ActivateIRQ(mpu.irq); //UNDOCUMENTED - } break; - /* Initialization Commands */ - case CMD_UART_MODE: + case 0x3f: /* UART mode */ + LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Set UART mode %X",val); mpu.mode=M_UART; break; - case CMD_DISABLE_ALL_NOTES_OFF: - mpu.state.allnotes=false; - break; - case CMD_DISABLE_REAL_TIME_OUT: - mpu.state.realtime=false; - break; - case CMD_DISABLE_ALL_THRU_OFF: - mpu.state.allthru=false; - break; - default: - LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Unhandled command %X",val); + default:; + //LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Unhandled command %X",val); } - QueueByte(MSG_CMD_ACK); + QueueByte(MSG_MPU_ACK); } static Bitu MPU401_ReadData(Bitu port,Bitu iolen) { - Bit8u ret=MSG_CMD_ACK; + Bit8u ret=MSG_MPU_ACK; if (mpu.queue_used) { ret=mpu.queue[mpu.queue_pos]; - if (mpu.queue_pos>=MPU_QUEUE) mpu.queue_pos-=MPU_QUEUE; + if (mpu.queue_pos>=MPU401_QUEUE) mpu.queue_pos-=MPU401_QUEUE; mpu.queue_pos++;mpu.queue_used--; } - if (ret>=0xf0 && ret<=0xf7) { + if (!mpu.intelligent) return ret; + + if (ret>=0xf0 && ret<=0xf7) { /* MIDI data request */ mpu.state.channel=ret&7; mpu.state.data_onoff=0; mpu.state.cond_req=false; } - if (ret==MSG_REQUEST_COMMAND) { + if (ret==MSG_MPU_COMMAND_REQ) { mpu.state.data_onoff=0; mpu.state.cond_req=true; } - if (ret==MSG_ALL_END || ret==MSG_CLOCK_TO_HOST) { + if (ret==MSG_MPU_END || ret==MSG_MPU_CLOCK || ret==MSG_MPU_ACK) { mpu.state.data_onoff=-1; MPU401_EOIHandler(); } @@ -415,46 +279,48 @@ static Bitu MPU401_ReadData(Bitu port,Bitu iolen) { static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) { if (mpu.mode==M_UART) {MIDI_RawOutByte(val);return;} - if (mpu.state.command_byte) MPU401_EOIHandler(); /* S101, Time Quest */ - switch (mpu.state.command_byte) { - case 0: + switch (mpu.state.command_byte) { /* 0xe# command data */ + case 0x00: break; - case CMD_SET_TEMPO: + case 0xe0: /* Set tempo */ mpu.state.command_byte=0; mpu.clock.tempo=val; return; - case CMD_INTERNAL_CLOCK_LENGTH_TO_HOST: + case 0xe1: /* Set relative tempo */ + mpu.state.command_byte=0; + LOG(LOG_MISC,LOG_ERROR)("MPU-401:Relative tempo not implemented"); + return; + case 0xe7: /* Set internal clock to host interval */ mpu.state.command_byte=0; mpu.clock.cth_rate=val>>2; return; - case CMD_ACTIVE_TRACK_MASK: + case 0xec: /* Set active track mask */ mpu.state.command_byte=0; mpu.state.tmask=val; return; - case CMD_SEND_PLAY_COUNTER_MASK: + case 0xed: /* Set play counter mask */ mpu.state.command_byte=0; mpu.state.cmask=val; return; - case CMD_MIDI_CHANNEL_MASK_LO: + case 0xee: /* Set 1-8 MIDI channel mask */ mpu.state.command_byte=0; mpu.state.midi_mask&=0xff00; mpu.state.midi_mask|=val; return; - case CMD_MIDI_CHANNEL_MASK_HI: + case 0xef: /* Set 9-16 MIDI channel mask */ mpu.state.command_byte=0; mpu.state.midi_mask&=0x00ff; mpu.state.midi_mask|=((Bit16u)val)<<8; return; - //case CMD_RELATIVE_TEMPO: - //case CMD_RELATIVE_TEMPO_GRADUATION: - //case CMD_MIDI_METRONOME: - //case CMD_MIDI_MEASURE: + //case 0xe2: /* Set graduation for relative tempo */ + //case 0xe4: /* Set metronome */ + //case 0xe6: /* Set metronome measure length */ default: mpu.state.command_byte=0; return; } static Bitu length,cnt,posd; - if (mpu.state.wsd) { + if (mpu.state.wsd) { /* Directly send MIDI message */ if (mpu.state.wsd_start) { mpu.state.wsd_start=0; cnt=0; @@ -470,6 +336,7 @@ static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) { case 0xf0: LOG(LOG_MISC,LOG_ERROR)("MPU-401:Illegal WSD byte"); mpu.state.wsd=0; + mpu.state.channel=mpu.state.old_chan; return; default: /* MIDI with running status */ cnt++; @@ -477,11 +344,14 @@ static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) { } } if (cnt0xf7) { mpu.playbuf[mpu.state.channel].type=MARK; + mpu.playbuf[mpu.state.channel].sys_val=val; length=1; } else { LOG(LOG_MISC,LOG_ERROR)("MPU-401:Illegal message"); mpu.playbuf[mpu.state.channel].type=MIDI_SYS; + mpu.playbuf[mpu.state.channel].sys_val=val; length=1; } break; @@ -576,7 +447,7 @@ static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) { break; } } - mpu.playbuf[mpu.state.channel].value[posd-1]=val; + if (!(posd==1 && val>=0xf0)) mpu.playbuf[mpu.state.channel].value[posd-1]=val; if (posd==length) MPU401_EOIHandler(); } } @@ -587,14 +458,14 @@ static void MPU401_IntelligentOut(Bit8u chan) { case OVERFLOW: break; case MARK: - val=mpu.playbuf[chan].value[0]; + val=mpu.playbuf[chan].sys_val; if (val==0xfc) { MIDI_RawOutByte(val); mpu.state.amask&=~(1<=500) { - CPU_CycleLeft+=CPU_Cycles-500; - CPU_Cycles=500; - } - #endif - PIC_ActivateIRQ(mpu.irq); - mpu.state.irq_pending=true; } static Bitu INT71_Handler() { + bool signr=0; + if (mpu.state.reset) if (!mpu.queue_used) { // hack for "It came to desert" + signr=1; + mpu.queue_pos=0; + mpu.queue[0]=0xfe; + mpu.queue_used=1; + mpu.state.reset=0; + } CALLBACK_RunRealInt(0xa); IO_Write(0xa0,0x61); + + if (signr) if (mpu.queue_used==1) ClrQueue(); return CBRET_NONE; } @@ -696,9 +567,6 @@ static void MPU401_Reset(void) { mpu.state.conductor=false; mpu.state.cond_req=false; mpu.state.cond_set=false; - mpu.state.allnotes=true; - mpu.state.allthru=true; - mpu.state.realtime=true; mpu.state.playing=false; mpu.state.run_irq=false; mpu.state.irq_pending=false; @@ -722,7 +590,7 @@ static void MPU401_Reset(void) { } void MPU401_Init(Section* sec) { - call_irq9=CALLBACK_Allocate(); //allocate handler for irq 9 + call_irq9=CALLBACK_Allocate(); /* Allocate handler for IRQ 9 */ CALLBACK_Setup(call_irq9,&INT71_Handler,CB_IRET,"irq 9 mpu"); RealSetVec(0x71,CALLBACK_RealPointer(call_irq9)); From ea1d3a5b3c2c190f695e822d5159cf01121935c5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 16 Dec 2004 10:30:15 +0000 Subject: [PATCH 1994/4131] fix compilation on amd64 + gcc4.0 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2078 --- src/dos/drive_cache.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 35893b90..9371f7d7 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.40 2004-11-13 12:08:43 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.41 2004-12-16 10:30:15 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -317,7 +317,8 @@ int DOS_Drive_Cache::CompareShortname(const char* compareName, const char* short { char* cpos = strchr(shortName,'~'); if (cpos) { - Bits compareCount1 = (int)cpos - (int)shortName; +/* the following code is replaced as it's not safe when char* is 64 bits */ +/* Bits compareCount1 = (int)cpos - (int)shortName; char* endPos = strchr(cpos,'.'); Bitu numberSize = endPos ? int(endPos)-int(cpos) : strlen(cpos); @@ -327,6 +328,18 @@ int DOS_Drive_Cache::CompareShortname(const char* compareName, const char* short compareCount2 -= numberSize; if (compareCount2>compareCount1) compareCount1 = compareCount2; +*/ + size_t compareCount1 = strcspn(shortName,"~"); + size_t numberSize = strcspn(cpos,"."); + size_t compareCount2 = strcspn(compareName,"."); + if(compareCount2 > 8) compareCount2 = 8; + /* We want + * compareCount2 -= numberSize; + * if (compareCount2>compareCount1) compareCount1 = compareCount2; + * but to prevent negative numbers: + */ + if(compareCount2 > compareCount1 + numberSize) + compareCount1 = compareCount2 - numberSize; return strncmp(compareName,shortName,compareCount1); } return strcmp(compareName,shortName); From 8b0c095dbfa5767d093e19bb547d40e537389c31 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 16 Dec 2004 11:17:42 +0000 Subject: [PATCH 1995/4131] Make gcc3.4 happy on amd64 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2079 --- src/gui/midi_alsa.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 785f7f29..110fdeea 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_alsa.h,v 1.9 2004-08-04 09:12:54 qbix79 Exp $ */ +/* $Id: midi_alsa.h,v 1.10 2004-12-16 11:17:42 qbix79 Exp $ */ #define ALSA_PCM_OLD_HW_PARAMS_API #define ALSA_PCM_OLD_SW_PARAMS_API @@ -112,7 +112,7 @@ public: } break; default: - LOG(LOG_MISC,LOG_WARN)("ALSA:Unknown Command: %08x", (int)msg); + LOG(LOG_MISC,LOG_WARN)("ALSA:Unknown Command: %08lx", (long)msg); send_event(1); break; } From cb5c3c2619368aaf716baf7e8be74fd38e9e14e3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 16 Dec 2004 19:19:39 +0000 Subject: [PATCH 1996/4131] country table doesn't write reserved bytes (wd) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2080 --- src/dos/dos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index e0bc2665..7546c642 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.79 2004-12-04 08:02:09 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.80 2004-12-16 19:19:39 qbix79 Exp $ */ #include #include @@ -405,7 +405,7 @@ static Bitu DOS_21Handler(void) { case 0x38: /* Set Country Code */ if (reg_al==0) { /* Get country specidic information */ PhysPt dest = SegPhys(ds)+reg_dx; - MEM_BlockWrite(dest,dos.tables.country,0x22); + MEM_BlockWrite(dest,dos.tables.country,0x18); reg_bx = 0x01; CALLBACK_SCF(false); break; From 5ae8051c90c761fead6fcc598824ff239f6426ed Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 16 Dec 2004 19:22:11 +0000 Subject: [PATCH 1997/4131] lot's of pic changes: it now honours irq 2 being masked. Some priority table changes. Some changes in the main irq loop in order to gain some speed. Some small changes by wd in the byte decoding Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2081 --- src/hardware/pic.cpp | 125 ++++++++++++++++++++++++++++++++----------- 1 file changed, 93 insertions(+), 32 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 279b80ce..34806692 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.26 2004-12-07 21:29:14 qbix79 Exp $ */ +/* $Id: pic.cpp,v 1.27 2004-12-16 19:22:11 qbix79 Exp $ */ #include @@ -74,15 +74,15 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { PIC_Controller * pic=&pics[port==0x20 ? 0 : 1]; Bitu irq_base=port==0x20 ? 0 : 8; Bitu i; - Bit16u IRQ_priority_table[16] = - { 0,1,2,9,10,11,12,13,14,15,3,4,5,6,7,8 }; + static Bit16u IRQ_priority_table[16] = + { 0,1,2,8,9,10,11,12,13,14,15,3,4,5,6,7 }; if (val&0x10) { // ICW1 issued if (val&0x02) E_Exit("PIC: single mode not handled"); // (would have to skip ICW3) if (val&0x04) E_Exit("PIC: 4 byte interval not handled"); if (val&0x08) E_Exit("PIC: level triggered mode not handled"); if (val&0xe0) E_Exit("PIC: 8080/8085 mode not handled"); pic->icw_index=1; // next is ICW3 - pic->icw_words=2+val&0x01; // =3 if ICW4 needed + pic->icw_words=2 + (val&0x01); // =3 if ICW4 needed } else if (val&0x08) { // OCW3 issued if (val&0x04) E_Exit("PIC: poll command not handled"); if (val&0x02) { // function select @@ -137,20 +137,31 @@ static void write_data(Bitu port,Bitu val,Bitu iolen) { PIC_Controller * pic=&pics[port==0x21 ? 0 : 1]; Bitu irq_base=(port==0x21) ? 0 : 8; Bitu i; + bool old_irq2_mask = irqs[2].masked; switch(pic->icw_index) { case 0: /* mask register */ LOG(LOG_PIC,LOG_NORMAL)("%d mask %X",port==0x21 ? 0 : 1,val); for (i=0;i<=7;i++) { irqs[i+irq_base].masked=(val&(1<0; - if (irqs[i+irq_base].active && !irqs[i+irq_base].masked) PIC_IRQCheck|=(1 << (i+irq_base)); - else PIC_IRQCheck&=~(1 << (i+irq_base)); - }; -#if 0 + if(port==0x21) { + if (irqs[i+irq_base].active && !irqs[i+irq_base].masked) PIC_IRQCheck|=(1 << (i+irq_base)); + else PIC_IRQCheck&=~(1 << (i+irq_base)); + } else { + if (irqs[i+irq_base].active && !irqs[i+irq_base].masked && !irqs[2].masked) PIC_IRQCheck|=(1 << (i+irq_base)); + else PIC_IRQCheck&=~(1 << (i+irq_base)); + } + } + if(irqs[2].masked != old_irq2_mask) { + /* Irq 2 mask has changed recheck second pic */ + for(i=8;i<=15;i++) { + if (irqs[i].active && !irqs[i].masked && !irqs[2].masked) PIC_IRQCheck|=(1 << (i)); + else PIC_IRQCheck&=~(1 << (i)); + } + } if (PIC_IRQCheck) { CPU_CycleLeft+=CPU_Cycles; CPU_Cycles=0; } -#endif break; case 1: /* icw2 */ LOG(LOG_PIC,LOG_NORMAL)("%d:Base vector %X",port==0x21 ? 0 : 1,val); @@ -177,7 +188,7 @@ static void write_data(Bitu port,Bitu val,Bitu iolen) { LOG(LOG_PIC,LOG_NORMAL)("%d:ICW 4 %X",port==0x21 ? 0 : 1,val); if ((val&0x01)==0) E_Exit("PIC:ICW4: %x, 8085 mode not handled",val); - if ((val&0x10)==0) E_Exit("PIC:ICW4: %x, special fully-nested mode not handled",val); + if ((val&0x10)!=0) E_Exit("PIC:ICW4: %x, special fully-nested mode not handled",val); if(pic->icw_index++ >= pic->icw_words) pic->icw_index=0; break; @@ -220,8 +231,14 @@ static Bitu read_data(Bitu port,Bitu iolen) { void PIC_ActivateIRQ(Bitu irq) { if (irq<16) { irqs[irq].active=true; - if (!irqs[irq].masked) { - PIC_IRQCheck|=(1 << irq); + if( irq < 8 ) { + if (!irqs[irq].masked) { + PIC_IRQCheck|=(1 << irq); + } + } else { + if (!irqs[irq].masked && !irqs[2].masked) { + PIC_IRQCheck|=(1 << irq); + } } } } @@ -232,40 +249,84 @@ void PIC_DeActivateIRQ(Bitu irq) { PIC_IRQCheck&=~(1 << irq); } } +static inline bool PIC_startIRQ(Bitu i) { + /* irqs on second pic only if irq 2 isn't masked */ + if( i > 7 && irqs[2].masked) return false; + irqs[i].active = false; + PIC_IRQCheck&= ~(1 << i); + CPU_HW_Interrupt(irqs[i].vector); + if (!pics[ (i<8)?0:1 ].auto_eoi) { + PIC_IRQActive = i; + irqs[i].inservice = true; + } else if (pics[ (i<8)?0:1 ].rotate_on_auto_eoi) { + E_Exit("rotate on auto EOI not handled"); + } + return true; +} void PIC_runIRQs(void) { - Bitu i; if (!GETFLAG(IF)) return; if (!PIC_IRQCheck) return; - Bit16u IRQ_priority_lookup[17] = + + static Bitu IRQ_priority_order[16] = + { 0,1,2,8,9,10,11,12,13,14,15,3,4,5,6,7 }; + static Bit16u IRQ_priority_lookup[17] = { 0,1,2,11,12,13,14,15,3,4,5,6,7,8,9,10,16 }; Bit16u activeIRQ = PIC_IRQActive; if (activeIRQ==PIC_NOIRQ) activeIRQ = 16; - for (i=0;i<=15;i++) { - if ((IRQ_priority_lookup[i] Date: Sun, 19 Dec 2004 16:46:04 +0000 Subject: [PATCH 1998/4131] Disable mouse on reset. Fixes crash in windows enhanched mode when exiting Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2082 --- src/ints/bios.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index dc343aef..c6d2eb94 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.37 2004-12-08 22:39:49 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.38 2004-12-19 16:46:04 qbix79 Exp $ */ #include #include "dosbox.h" @@ -358,6 +358,7 @@ static Bitu INT15_Handler(void) { } else CALLBACK_SCF(true); break; case 0x01: // reset + Mouse_SetPS2State(false); reg_bx=0x00aa; // mouse CALLBACK_SCF(false); break; From 26062b0e15b7f9201e7ad00bc69f62c511783fc1 Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Wed, 22 Dec 2004 10:46:16 +0000 Subject: [PATCH 1999/4131] Adding serial port FOSSIL driver support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2083 --- src/hardware/softmodem.cpp | 50 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp index 0db28141..0c7f9c6c 100644 --- a/src/hardware/softmodem.cpp +++ b/src/hardware/softmodem.cpp @@ -99,6 +99,8 @@ struct telnetClient { }; +static Bitu call_int14; + #if 1 static void toUpcase(char *buffer) { @@ -548,6 +550,7 @@ public: Bitu usesize; Bit8u txval; + /* Check for eventual break command */ if (!mhd.commandmode) mhd.cmdpause++; /* Handle incoming data from serial port, read as much as available */ @@ -605,6 +608,7 @@ public: /* Filter telnet commands */ TelnetEmulation(tmpbuf, result); } else { + rqueue->adds(tmpbuf,result); } mhd.cmdpause = 0; @@ -646,7 +650,11 @@ public: } bool CanRecv(void) { + if(rqueue->inuse()) { return true; + } else { + return false; + } } @@ -694,6 +702,43 @@ protected: CSerialModem *csm; +static Bitu INT14_FOSSIL(void) { + switch (reg_ah) { + case 0x01: + // Serial - Write character to port + csm->tqueue->addb(reg_al); + reg_ah = csm->read_reg(0xd) & 0x7f; + break; + + case 0x02: + // FOSSIL - Receive character with wait + //LOG_MSG("FOSSIL: Calling get to receive character", reg_ah); + csm->mctrl |= MC_RTS; + while(!csm->rqueue->inuse()) { + // Wait for byte. Yes, I realize that this locks up DosBox, but + // it would an oldskool system as well. + csm->Timer(); + } + reg_al = csm->rqueue->getb(); + reg_ah = 0; + break; + case 0x03: + //LOG_MSG("FOSSIL: Calling get port status", reg_ah); + // Serial - Get port status + csm->mctrl |= MC_RTS; + reg_ah = csm->read_reg(0xd) ; // Line status + if(csm->rqueue->inuse()) reg_ah |= 0x1; + + reg_al = csm->read_reg(0xe); // Modem status + break; + default: + LOG_MSG("FOSSIL: Func 0x%x not handled", reg_ah); + break; + } + return CBRET_NONE; +} + + void MODEM_Init(Section* sec) { unsigned long args = 1; @@ -739,6 +784,11 @@ void MODEM_Init(Section* sec) { } if(csm != NULL) seriallist.push_back(csm); + + //Enable FOSSIL support (GTERM, etc) + call_int14=CALLBACK_Allocate(); + CALLBACK_Setup(call_int14,&INT14_FOSSIL,CB_IRET); + RealSetVec(0x14,CALLBACK_RealPointer(call_int14)); } From 1d46933a6bd478030ab1d0b5a7adfad112c2e552 Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Wed, 22 Dec 2004 10:49:42 +0000 Subject: [PATCH 2000/4131] Completing S3 XGA functionality. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2084 --- include/vga.h | 4 + src/hardware/vga_crtc.cpp | 16 +- src/hardware/vga_draw.cpp | 25 +- src/hardware/vga_memory.cpp | 28 +- src/hardware/vga_xga.cpp | 636 ++++++++++++++++++++++++++++++++---- 5 files changed, 628 insertions(+), 81 deletions(-) diff --git a/include/vga.h b/include/vga.h index a8814c06..c5124914 100644 --- a/include/vga.h +++ b/include/vga.h @@ -343,6 +343,10 @@ 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); + +/* XGA Functionality */ +void XGA_UpdateHWC(void); extern VGA_Type vga; diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index f7647817..c2506ec0 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -21,6 +21,7 @@ #include "vga.h" #include "debug.h" #include "cpu.h" +#include "video.h" #define crtc(blah) vga.crtc.blah @@ -350,40 +351,53 @@ void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen) { */ case 0x45: /* Hardware cursor mode */ vga.s3.hgc.curmode = val; + // Activate hardware cursor code if needed + VGA_ActivateHardwareCursor(); + XGA_UpdateHWC(); break; case 0x46: vga.s3.hgc.originx = (vga.s3.hgc.originx & 0x00ff) | (val << 8); + XGA_UpdateHWC(); break; case 0x47: /* HGC orgX */ vga.s3.hgc.originx = (vga.s3.hgc.originx & 0xff00) | val; + XGA_UpdateHWC(); break; case 0x48: vga.s3.hgc.originy = (vga.s3.hgc.originy & 0x00ff) | (val << 8); + XGA_UpdateHWC(); break; case 0x49: /* HGC orgY */ vga.s3.hgc.originy = (vga.s3.hgc.originy & 0xff00) | val; + XGA_UpdateHWC(); break; case 0x4A: /* HGC foreground stack */ if (vga.s3.hgc.fstackpos > 2) vga.s3.hgc.fstackpos = 0; vga.s3.hgc.forestack[vga.s3.hgc.fstackpos] = val; vga.s3.hgc.fstackpos++; + XGA_UpdateHWC(); break; case 0x4B: /* HGC background stack */ if (vga.s3.hgc.bstackpos > 2) vga.s3.hgc.bstackpos = 0; vga.s3.hgc.backstack[vga.s3.hgc.bstackpos] = val; vga.s3.hgc.bstackpos++; + XGA_UpdateHWC(); break; case 0x4c: /* HGC start address high byte*/ vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | ((val & 0xff) << 8); + XGA_UpdateHWC(); break; case 0x4d: /* HGC start address low byte*/ vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | (val & 0xff); + XGA_UpdateHWC(); break; case 0x4e: /* HGC pattern start X */ vga.s3.hgc.posx = val; + XGA_UpdateHWC(); break; case 0x4f: /* HGC pattern start X */ vga.s3.hgc.posy = val; + XGA_UpdateHWC(); break; case 0x51: /* Extended System Control 2 */ vga.s3.reg_51=val & 0xc0; //Only store bits 6,7 @@ -425,7 +439,7 @@ void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen) { if((val & 0x10) != (vga.s3.ext_mem_ctrl & 0x10)) { /* Map or unmap MMIO */ if ((val & 0x10) != 0) { - LOG_MSG("VGA: Mapping Memory Mapped I/O to 0xA0000"); + //LOG_MSG("VGA: Mapping Memory Mapped I/O to 0xA0000"); VGA_MapMMIO(); } else { VGA_UnmapMMIO(); diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 3fcf67ea..cbbd8aaa 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -108,14 +108,15 @@ static Bit8u * VGA_Draw_VGA_Line(Bitu vidstart,Bitu panning,Bitu line) { static Bit8u * VGA_Draw_VGA_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) { if(vga.s3.hgc.curmode & 0x1) { - Bitu lineat = vidstart / 160; + Bitu lineat = vidstart / ((160 * vga.draw.height) / 640); if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63))) { return VGA_Draw_VGA_Line(vidstart, panning, line); } else { - memcpy(TempLine, VGA_Draw_VGA_Line(vidstart, panning, line), 640); + + memcpy(TempLine, VGA_Draw_VGA_Line(vidstart, panning, line), vga.draw.width); /* Draw mouse cursor */ Bits moff = ((Bits)lineat - (Bits)vga.s3.hgc.originy) + (Bits)vga.s3.hgc.posy; - if(moff>63) moff=moff-64; + if(moff>63) return VGA_Draw_VGA_Line(vidstart, panning, line); if(moff<0) moff+=64; Bitu xat = vga.s3.hgc.originx; Bitu m, mat; @@ -133,11 +134,13 @@ static Bit8u * VGA_Draw_VGA_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) //Transparent break; case 3: + // Invert screen data + TempLine[xat] = ~TempLine[xat]; break; } xat++; mat++; - if(mat>63) mat=0; + if(mat>63) break; } return TempLine; } @@ -293,6 +296,14 @@ void VGA_CheckScanLength(void) { } } +void VGA_ActivateHardwareCursor(void) { + if(vga.s3.hgc.curmode & 0x1) { + VGA_DrawLine=VGA_Draw_VGA_Line_HWMouse; + } else { + VGA_DrawLine=VGA_Draw_VGA_Line; + } +} + void VGA_SetupDrawing(Bitu val) { if (vga.mode==M_ERROR) { PIC_RemoveEvents(VGA_VerticalTimer); @@ -383,11 +394,7 @@ void VGA_SetupDrawing(Bitu val) { case M_LIN8: width<<=3; /* Use HW mouse cursor drawer if enabled */ - if(vga.s3.hgc.curmode & 0x1) { - VGA_DrawLine=VGA_Draw_VGA_Line_HWMouse; - } else { - VGA_DrawLine=VGA_Draw_VGA_Line; - } + VGA_ActivateHardwareCursor(); break; case M_EGA16: doublewidth=(vga.seq.clocking_mode & 0x8) > 0; diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 490297f8..0dbe1da3 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -242,17 +242,28 @@ public: void writeb(PhysPt addr,Bitu val) { Bitu port = addr & 0xffff; if(port >= 0x82E8) IO_WriteB(port, val); - LOG_MSG("MMIO: Write byte to %x with %x", addr, val); + if(port <= 0x0020) { + if(port == 0x0000) { + IO_WriteB(0xe2e0, val); + } else { + IO_WriteB(0xe2e8, val); + } + } + //LOG_MSG("MMIO: Write byte to %x with %x", addr, val); } void writew(PhysPt addr,Bitu val) { Bitu port = addr & 0xffff; if(port >= 0x82E8) IO_WriteW(port, val); if(port == 0x8118) IO_WriteW(0x9ae8, val); if(port <= 0x0020) { + if(port == 0x0000) { + IO_WriteW(0xe2e0, val); + } else { IO_WriteW(0xe2e8, val); } + } - LOG_MSG("MMIO: Write word to %x with %x", addr, val); + //LOG_MSG("MMIO: Write word to %x with %x", addr, val); } void writed(PhysPt addr,Bitu val) { Bitu port = addr & 0xffff; @@ -266,26 +277,31 @@ public: IO_WriteW(0xbee8, (val & 0xffff)); } if(port <= 0x0020) { + if(port == 0x0000) { + IO_WriteW(0xe2e0, (val & 0xffff)); + IO_WriteW(0xe2e8, (val >> 16)); + } else { IO_WriteW(0xe2e8, (val & 0xffff)); IO_WriteW(0xe2e8, (val >> 16)); } + } - LOG_MSG("MMIO: Write dword to %x with %x", addr, val); + //LOG_MSG("MMIO: Write dword to %x with %x", addr, val); } Bitu readb(PhysPt addr) { - LOG_MSG("MMIO: Read byte from %x", addr); + //LOG_MSG("MMIO: Read byte from %x", addr); return 0x00; } Bitu readw(PhysPt addr) { Bitu port = addr & 0xffff; if(port >= 0x82E8) return IO_ReadW(port); - LOG_MSG("MMIO: Read word from %x", addr); + //LOG_MSG("MMIO: Read word from %x", addr); return 0x00; } Bitu readd(PhysPt addr) { - LOG_MSG("MMIO: Read dword from %x", addr); + //LOG_MSG("MMIO: Read dword from %x", addr); return 0x00; } diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index 0abb4bae..ac20cfa1 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,8 +20,11 @@ #include "dosbox.h" #include "inout.h" #include "vga.h" +#include #include +#define XGA_SCREEN_WIDTH vga.draw.width + struct XGAStatus { struct scissorreg { Bit16u x1, y1, x2, y2; @@ -33,11 +36,15 @@ struct XGAStatus { Bit32u forecolor; Bit32u backcolor; + Bitu curcommand; + Bit16u foremix; + Bit16u backmix; Bit16u curx, cury; Bit16u destx, desty; + Bit16u ErrTerm; Bit16u MIPcount; Bit16u MAPcount; @@ -45,6 +52,7 @@ struct XGAStatus { Bit16u read_sel; struct XGA_WaitCmd { + bool newline; bool wait; Bit16u cmd; Bit16u curx, cury; @@ -53,8 +61,6 @@ struct XGAStatus { } xga; -Bit8u tmpvram[2048 * 1024]; - void XGA_Write_Multifunc(Bitu val, Bitu len) { Bitu regselect = val >> 12; Bitu dataval = val & 0xfff; @@ -87,13 +93,21 @@ void XGA_Write_Multifunc(Bitu val, Bitu len) { } void XGA_DrawPoint8(Bitu x, Bitu y, Bit8u c) { - Bit32u memaddr = (y * 640) + x; + + if(!(xga.curcommand & 0x10)) return; + + if(x < xga.scissors.x1) return; + if(x > xga.scissors.x2) return; + if(y < xga.scissors.y1) return; + if(y > xga.scissors.y2) return; + + Bit32u memaddr = (y * XGA_SCREEN_WIDTH) + x; vga.mem.linear[memaddr] = c; } Bit8u XGA_GetPoint8(Bitu x, Bitu y) { - Bit32u memaddr = (y * 640) + x; + Bit32u memaddr = (y * XGA_SCREEN_WIDTH) + x; return vga.mem.linear[memaddr]; @@ -101,43 +115,340 @@ Bit8u XGA_GetPoint8(Bitu x, Bitu y) { void XGA_DrawPoint16(Bitu x, Bitu y, Bit16u c) { Bit16u *memptr; - Bit32u memaddr = (y * 640) + x; + Bit32u memaddr = (y * XGA_SCREEN_WIDTH) + x; memptr = (Bit16u *)&vga.mem.linear[memaddr]; *memptr = c; } +Bitu XGA_GetMixResult(Bitu mixmode, Bitu srcval, Bitu dstdata) { + Bitu destval = 0; + switch(mixmode & 0xf) { + case 0x00: /* not DST */ + destval = ~dstdata; + break; + case 0x01: /* 0 (false) */ + destval = 0; + break; + case 0x02: /* 1 (true) */ + destval = 0xff; + break; + case 0x03: /* 2 DST */ + destval = dstdata; + break; + case 0x04: /* not SRC */ + destval = ~srcval; + break; + case 0x05: /* SRC xor DST */ + destval = srcval ^ dstdata; + break; + case 0x06: /* not (SRC xor DST) */ + destval = ~(srcval ^ dstdata); + break; + case 0x07: /* SRC */ + destval = srcval; + break; + case 0x08: /* not (SRC and DST) */ + destval = ~(srcval & dstdata); + break; + case 0x09: /* (not SRC) or DST */ + destval = (~srcval) | dstdata; + break; + case 0x0a: /* SRC or (not DST) */ + destval = srcval | (~dstdata); + break; + case 0x0b: /* SRC or DST */ + destval = srcval | dstdata; + break; + case 0x0c: /* SRC and DST */ + destval = srcval & dstdata; + break; + case 0x0d: /* SRC and (not DST) */ + destval = srcval & (~dstdata); + break; + case 0x0e: /* (not SRC) and DST */ + destval = (~srcval) & dstdata; + break; + case 0x0f: /* not (SRC or DST) */ + destval = ~(srcval | dstdata); + break; + default: + LOG_MSG("XGA: GetMixResult: Unknown mix. Shouldn't be able to get here!"); + break; + } + return destval; + +} + +void XGA_DrawLineVector(Bitu val) { + Bits xat, yat; + Bit8u srcval; + Bit8u destval; + Bit8u dstdata; + Bits i; + + Bits dx, sx, dy, sy, e; + + dx = xga.MAPcount; + xat = xga.curx; + yat = xga.cury; + + switch((val >> 5) & 0x7) { + case 0x00: /* 0 degrees */ + sx = 1; + sy = 0; + break; + case 0x01: /* 45 degrees */ + sx = 1; + sy = -1; + break; + case 0x02: /* 90 degrees */ + sx = 0; + sy = -1; + break; + case 0x03: /* 135 degrees */ + sx = -1; + sy = -1; + break; + case 0x04: /* 180 degrees */ + sx = -1; + sy = 0; + break; + case 0x05: /* 225 degrees */ + sx = -1; + sy = 1; + break; + case 0x06: /* 270 degrees */ + sx = 0; + sy = 1; + break; + case 0x07: /* 315 degrees */ + sx = 1; + sy = 1; + break; + default: // Should never get here + sx = 0; + sy = 0; + break; + } + + //for(yat=y1;yat<=y2;yat++) { + // for(xat=x1;xat<=x2;xat++) { + for (i=0;i<=dx;i++) { + Bitu mixmode = (xga.pix_cntl >> 6) & 0x3; + switch (mixmode) { + case 0x00: /* FOREMIX always used */ + mixmode = xga.foremix; + switch((mixmode >> 5) & 0x03) { + case 0x00: /* Src is background color */ + srcval = xga.backcolor; + break; + case 0x01: /* Src is foreground color */ + srcval = xga.forecolor; + break; + case 0x02: /* Src is pixel data from PIX_TRANS register */ + //srcval = tmpval; + LOG_MSG("XGA: DrawRect: Wants data from PIX_TRANS register"); + break; + case 0x03: /* Src is bitmap data */ + LOG_MSG("XGA: DrawRect: Wants data from srcdata"); + //srcval = srcdata; + break; + default: + LOG_MSG("XGA: DrawRect: Shouldn't be able to get here!"); + break; + } + dstdata = XGA_GetPoint8(xat,yat); + + destval = XGA_GetMixResult(mixmode, srcval, dstdata); + + XGA_DrawPoint8(xat,yat, destval); + break; + default: + LOG_MSG("XGA: DrawLine: Needs mixmode %x", mixmode); + break; + } + xat += sx; + yat += sy; + } + + xga.curx = xat-1; + xga.cury = yat; + // } + //} + +} + +void XGA_DrawLineBresenham(Bitu val) { + Bits xat, yat; + Bit8u srcval; + Bit8u destval; + Bit8u dstdata; + Bits i; + Bits tmpswap; + bool steep; + +#define SWAP(a,b) tmpswap = a; a = b; b = tmpswap; + + Bits dx, sx, dy, sy, e, dmajor, dminor; + + // Probably a lot easier way to do this, but this works. + + dminor = (Bits)((Bit16s)xga.desty) >> 1; + dmajor = -((Bits)((Bit16s)xga.destx) - (dminor << 1)) >> 1; + + dx = dmajor; + if((val >> 5) & 0x1) { + sx = 1; + } else { + sx = -1; + } + dy = dminor; + if((val >> 7) & 0x1) { + sy = 1; + } else { + sy = -1; + } + e = (Bits)((Bit16s)xga.ErrTerm); + xat = xga.curx; + yat = xga.cury; + + if((val >> 6) & 0x1) { + steep = false; + SWAP(xat, yat); + SWAP(sx, sy); + } else { + steep = true; + } + + //LOG_MSG("XGA: Bresenham: ASC %d, LPDSC %d, sx %d, sy %d, err %d, steep %d, length %d, dmajor %d, dminor %d", dx, dy, sx, sy, e, steep, xga.MAPcount, dmajor, dminor); + + //for(yat=y1;yat<=y2;yat++) { + // for(xat=x1;xat<=x2;xat++) { + for (i=0;i<=xga.MAPcount;i++) { + Bitu mixmode = (xga.pix_cntl >> 6) & 0x3; + switch (mixmode) { + case 0x00: /* FOREMIX always used */ + mixmode = xga.foremix; + switch((mixmode >> 5) & 0x03) { + case 0x00: /* Src is background color */ + srcval = xga.backcolor; + break; + case 0x01: /* Src is foreground color */ + srcval = xga.forecolor; + break; + case 0x02: /* Src is pixel data from PIX_TRANS register */ + //srcval = tmpval; + LOG_MSG("XGA: DrawRect: Wants data from PIX_TRANS register"); + break; + case 0x03: /* Src is bitmap data */ + LOG_MSG("XGA: DrawRect: Wants data from srcdata"); + //srcval = srcdata; + break; + default: + LOG_MSG("XGA: DrawRect: Shouldn't be able to get here!"); + break; + } + + if(steep) { + dstdata = XGA_GetPoint8(xat,yat); + } else { + dstdata = XGA_GetPoint8(yat,xat); + } + + destval = XGA_GetMixResult(mixmode, srcval, dstdata); + + if(steep) { + XGA_DrawPoint8(xat,yat, destval); + } else { + XGA_DrawPoint8(yat,xat, destval); + } + + break; + default: + LOG_MSG("XGA: DrawLine: Needs mixmode %x", mixmode); + break; + } + while (e >= 0) { + yat += sy; + e -= (dx << 1); + } + xat += sx; + e += (dy << 1); + } + + if(steep) { + xga.curx = xat; + xga.cury = yat; + } else { + xga.curx = yat; + xga.cury = xat; + } + // } + //} + +} + void XGA_DrawRectangle(Bitu x1, Bitu y1, Bitu x2, Bitu y2) { Bit32u xat, yat; - Bit32u xmass, xmod, xdist; + Bit32u xmass, xmod, xdist, ydist; Bit32u *memptr; Bit8u *smallptr; Bit32u c; Bit8u smallc; + Bit8u srcval; + Bit8u destval; + Bit8u dstdata; xdist = (x2 -x1); + ydist = (y2 -y1); xmass = (xdist) & 0xfffffffb; xmod = (xdist) & 0x3; smallc = (xga.forecolor & 0xff); + c = (smallc) | ((smallc) << 8) | ((smallc) << 16) | ((smallc) << 24); for(yat=y1;yat<=y2;yat++) { - Bit32u memaddr = (yat * (Bit32u)640) + x1; - smallptr = &vga.mem.linear[memaddr]; - for(xat=0;xat> 6) & 0x3; + switch (mixmode) { + case 0x00: /* FOREMIX always used */ + mixmode = xga.foremix; + switch((mixmode >> 5) & 0x03) { + case 0x00: /* Src is background color */ + srcval = xga.backcolor; + break; + case 0x01: /* Src is foreground color */ + srcval = xga.forecolor; + break; + case 0x02: /* Src is pixel data from PIX_TRANS register */ + //srcval = tmpval; + LOG_MSG("XGA: DrawRect: Wants data from PIX_TRANS register"); + break; + case 0x03: /* Src is bitmap data */ + LOG_MSG("XGA: DrawRect: Wants data from srcdata"); + //srcval = srcdata; + break; + default: + LOG_MSG("XGA: DrawRect: Shouldn't be able to get here!"); + break; + } + dstdata = XGA_GetPoint8(xat,yat); + + destval = XGA_GetMixResult(mixmode, srcval, dstdata); + + XGA_DrawPoint8(xat,yat, destval); + break; + default: + LOG_MSG("XGA: DrawRect: Needs mixmode %x", mixmode); + break; } - /* - for(yat=y1;yat<=y2;yat++) { - Bit32u memaddr = (yat * (Bit32u)640) + x1; - memptr = (Bit32u *)&vga.mem.linear[memaddr]; - for(xat=0;xat xga.waitcmd.y2) xga.waitcmd.wait = false; } return newline; } + void XGA_DrawWait(Bitu val, Bitu len) { if(!xga.waitcmd.wait) return; Bitu mixmode = (xga.pix_cntl >> 6) & 0x3; + Bit8u srcval; + Bit8u destval; + Bit8u dstdata; + Bitu tmpval; + Bits bitneed; switch(xga.waitcmd.cmd) { case 2: /* Rectangle */ - if(mixmode == 0) { /* FOREMIX always used */ - switch(len) { - case 1: - XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, val); + switch(mixmode) { + case 0x00: /* FOREMIX always used */ + mixmode = xga.foremix; + int t; + for(t=0;t> (8 * t)) & 0xff; + switch((mixmode >> 5) & 0x03) { + case 0x00: /* Src is background color */ + srcval = xga.backcolor; + break; + case 0x01: /* Src is foreground color */ + srcval = xga.forecolor; + break; + case 0x02: /* Src is pixel data from PIX_TRANS register */ + srcval = tmpval; + //LOG_MSG("XGA: DrawBlitWait: Wants data from PIX_TRANS register"); break; - case 2: - XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, (val & 0xff)); - XGA_CheckX(); - XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, (val >> 8)); + case 0x03: /* Src is bitmap data */ + LOG_MSG("XGA: DrawBlitWait: Wants data from srcdata"); + //srcval = srcdata; break; - case 4: - XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, (val & 0xff)); - XGA_CheckX(); - XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, ((val >> 8) & 0xff)); - XGA_CheckX(); - XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, ((val >> 16) & 0xff)); - XGA_CheckX(); - XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, ((val >> 24) & 0xff)); + default: + LOG_MSG("XGA: DrawBlitWait: Shouldn't be able to get here!"); break; } - XGA_CheckX(); + + + + dstdata = XGA_GetPoint8(xga.waitcmd.curx, xga.waitcmd.cury); + + destval = XGA_GetMixResult(mixmode, srcval, dstdata); + + //LOG_MSG("XGA: DrawPattern: Mixmode: %x srcval: %x", mixmode, srcval); + + XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, destval); + + //XGA_CheckX(); } - if(mixmode == 2) { /* Data from PIX_TRANS selects the mix */ + break; + case 0x02: /* Data from PIX_TRANS selects the mix */ Bitu bitcount; int i; switch(len) { @@ -196,20 +531,69 @@ void XGA_DrawWait(Bitu val, Bitu len) { } - Bits bitneed = ((Bits)xga.waitcmd.x2 - (Bits)xga.waitcmd.x1) + 1; - xga.waitcmd.curx = xga.waitcmd.x1; - i = 15; + bitneed = ((Bits)xga.waitcmd.x2 - (Bits)xga.waitcmd.curx) ; + //xga.waitcmd.curx = xga.waitcmd.x1; + xga.waitcmd.newline = false; + + + i = bitcount -1 ; + //bitneed = i; + for(;bitneed>=0;--bitneed) { + //for(;i>=0;--i) { Bitu bitval = (val >> i) & 0x1; + //Bitu bitval = (val >> bitneed) & 0x1; + //XGA_DrawPoint8(xga.waitcmd.curx, xga.waitcmd.cury, i); - if(bitval != 0) XGA_DrawPoint8(xga.waitcmd.curx, xga.waitcmd.cury, xga.forecolor); + Bitu mixmode = 0x67; + + if(bitval) { + mixmode = xga.foremix; + } else { + mixmode = xga.backmix; + } + + switch((mixmode >> 5) & 0x03) { + case 0x00: /* Src is background color */ + srcval = xga.backcolor; + break; + case 0x01: /* Src is foreground color */ + srcval = xga.forecolor; + break; + case 0x02: /* Src is pixel data from PIX_TRANS register */ + LOG_MSG("XGA: DrawBlitWait: Wants data from PIX_TRANS register"); + break; + case 0x03: /* Src is bitmap data */ + LOG_MSG("XGA: DrawBlitWait: Wants data from srcdata"); + //srcval = srcdata; + break; + default: + LOG_MSG("XGA: DrawBlitWait: Shouldn't be able to get here!"); + break; + } + + Bit8u dstdata = XGA_GetPoint8(xga.waitcmd.curx, xga.waitcmd.cury); + + destval = XGA_GetMixResult(mixmode, srcval, dstdata); + + XGA_DrawPoint8(xga.waitcmd.curx, xga.waitcmd.cury, destval); + --i; + if(i < 0) break; + //--bitneed; + //if(bitneed < 0) break; + xga.waitcmd.curx++; + XGA_CheckX(); } - xga.waitcmd.cury++; + //xga.waitcmd.cury++; if(xga.waitcmd.cury > xga.waitcmd.y2) xga.waitcmd.wait = false; + break; + default: + LOG_MSG("XGA: DrawBlitWait: Unhandled mixmode: %d", mixmode); + break; } break; default: @@ -233,15 +617,15 @@ void XGA_BlitRect(Bitu val) { bool incx = false; bool incy = false; - if((val >> 5) != 0) incx = true; - if((val >> 7) != 0) incy = true; + if(((val >> 5) & 0x01) != 0) incx = true; + if(((val >> 7) & 0x01) != 0) incy = true; xdist = xga.MAPcount; smallc = (xga.forecolor & 0xff); memrec = 0; - Bit32u srcaddr = (xga.cury * (Bit32u)640) + xga.curx; - Bit32u destaddr = (xga.desty * (Bit32u)640) + xga.destx; + Bit32u srcaddr = (xga.cury * (Bit32u)XGA_SCREEN_WIDTH) + xga.curx; + Bit32u destaddr = (xga.desty * (Bit32u)XGA_SCREEN_WIDTH) + xga.destx; srcptr = &vga.mem.linear[srcaddr]; destptr = &vga.mem.linear[destaddr]; @@ -250,7 +634,7 @@ void XGA_BlitRect(Bitu val) { for(yat=0;yat<=xga.MIPcount ;yat++) { srcline = srcptr; destline = destptr; - for(xat=0;xat7) addx=0; + for(xat=0;xat<=xdist;xat++) { + + Bitu usex = xga.destx + xat; + Bitu usey = yat; + + srcdata = XGA_GetPoint8(sx + (usex & 0x7), sy + (usey & 0x7)); + dstdata = XGA_GetPoint8(usex, usey); + Bitu mixselect = (xga.pix_cntl >> 6) & 0x3; + Bitu mixmode = 0x67; /* Source is bitmap data, mix mode is src */ + switch(mixselect) { + case 0x00: /* Foreground mix is always used */ + mixmode = xga.foremix; + break; + case 0x02: /* CPU Data determines mix used */ + LOG_MSG("XGA: DrawPattern: Mixselect data from PIX_TRANS register"); + break; + case 0x03: /* Video memory determines mix */ + if(srcdata == xga.forecolor) { + mixmode = xga.foremix; + } else { + if(srcdata == xga.backcolor) { + mixmode = xga.backmix; + } else { + /* Best guess otherwise */ + mixmode = 0x67; /* Source is bitmap data, mix mode is src */ + } + } + //LOG_MSG("XGA: Srcdata: %x, Forecolor %x, Backcolor %x, Foremix: %x Backmix: %x", srcdata, xga.forecolor, xga.backcolor, xga.foremix, xga.backmix); + break; + default: + LOG_MSG("XGA: DrawPattern: Unknown mix select register"); + break; + } + switch((mixmode >> 5) & 0x03) { + case 0x00: /* Src is background color */ + srcval = xga.backcolor; + break; + case 0x01: /* Src is foreground color */ + srcval = xga.forecolor; + break; + case 0x02: /* Src is pixel data from PIX_TRANS register */ + LOG_MSG("XGA: DrawPattern: Wants data from PIX_TRANS register"); + break; + case 0x03: /* Src is bitmap data */ + srcval = srcdata; + break; + default: + LOG_MSG("XGA: DrawPattern: Shouldn't be able to get here!"); + break; + } + + destval = XGA_GetMixResult(mixmode, srcval, dstdata); + + //LOG_MSG("XGA: DrawPattern: Mixmode: %x Mixselect: %x", mixmode, mixselect); + + //*smallptr++ = destval; + XGA_DrawPoint8(usex, usey, destval); + + } - addy++; - if(addy>7) addy=0; + } } @@ -306,22 +748,37 @@ void XGA_DrawPattern(void) { void XGA_DrawCmd(Bitu val, Bitu len) { Bit16u cmd; cmd = val >> 13; - LOG_MSG("XGA: Draw command %x", cmd); + //LOG_MSG("XGA: Draw command %x", cmd); + xga.curcommand = val; switch(cmd) { + case 1: /* Draw line */ + if((val & 0x100) == 0) { + if((val & 0x8) == 0) { + //LOG_MSG("XGA: Drawing Bresenham line"); + XGA_DrawLineBresenham(val); + } else { + //LOG_MSG("XGA: Drawing vector line"); + XGA_DrawLineVector(val); + } + } else { + LOG_MSG("XGA: Wants line drawn from PIX_TRANS register!"); + } + break; case 2: /* Rectangle fill */ if((val & 0x100) == 0) { xga.waitcmd.wait = false; XGA_DrawRectangle(xga.curx, xga.cury, xga.curx + xga.MAPcount, xga.cury + xga.MIPcount); } else { + xga.waitcmd.newline = true; xga.waitcmd.wait = true; xga.waitcmd.curx = xga.curx; xga.waitcmd.cury = xga.cury; xga.waitcmd.x1 = xga.curx; xga.waitcmd.y1 = xga.cury; xga.waitcmd.x2 = xga.curx + xga.MAPcount; - xga.waitcmd.y2 = xga.cury + xga.MIPcount; + xga.waitcmd.y2 = xga.cury + xga.MIPcount + 1; xga.waitcmd.cmd = 2; - LOG_MSG("XGA: Draw wait rect (%d, %d)-(%d, %d)", xga.waitcmd.x1, xga.waitcmd.y1, xga.waitcmd.x2, xga.waitcmd.y2); + //LOG_MSG("XGA: Draw wait rect (%d, %d)-(%d, %d)", xga.waitcmd.x1, xga.waitcmd.y1, xga.waitcmd.x2, xga.waitcmd.y2); } break; case 6: /* BitBLT */ @@ -329,7 +786,7 @@ void XGA_DrawCmd(Bitu val, Bitu len) { break; case 7: /* Pattern fill */ XGA_DrawPattern(); - LOG_MSG("XGA: Pattern fill (%d, %d)-(%d, %d) to (%d, %d)-(%d, %d)", xga.curx, xga.cury, xga.curx + 8, xga.cury + 8, xga.destx, xga.desty, xga.destx + xga.MAPcount, xga.desty + xga.MIPcount); + //LOG_MSG("XGA: Pattern fill (%d, %d)-(%d, %d) to (%d, %d)-(%d, %d)", xga.curx, xga.cury, xga.curx + 8, xga.cury + 8, xga.destx, xga.desty, xga.destx + xga.MAPcount, xga.desty + xga.MIPcount); break; default: LOG_MSG("XGA: Unhandled draw command %x", cmd); @@ -340,6 +797,9 @@ void XGA_DrawCmd(Bitu val, Bitu len) { void XGA_Write(Bitu port, Bitu val, Bitu len) { switch(port) { + case 0x92e8: + xga.ErrTerm = val; + break; case 0x96e8: xga.MAPcount = val; break; @@ -370,13 +830,26 @@ void XGA_Write(Bitu port, Bitu val, Bitu len) { case 0x8ee8: xga.destx = val; break; + case 0xb6e8: + xga.backmix = val; + break; case 0xbae8: xga.foremix = val; break; case 0xbee8: XGA_Write_Multifunc(val, len); break; + case 0x0e2e0: + if(!xga.waitcmd.newline) { + xga.waitcmd.curx = xga.waitcmd.x1; + xga.waitcmd.cury++; + xga.waitcmd.newline = true; + } + XGA_DrawWait(val, len); + if(xga.waitcmd.cury > xga.waitcmd.y2) xga.waitcmd.wait = false; + break; case 0xe2e8: + xga.waitcmd.newline = false; XGA_DrawWait(val, len); break; default: @@ -431,6 +904,36 @@ void XGA_UpdateHWC(void) { } } + // Dump the cursor to the log + /* + LOG_MSG("--- New cursor ---"); + for(t=0;t<64;t++) { + char outstr[66]; + memset(outstr,0,66); + for(r=0;r<64;r++) { + switch(vga.s3.hgc.mc[t][r]) { + case 0x00: + outstr[r] = 'o'; + break; + case 0x01: + outstr[r] = 'O'; + break; + case 0x02: + outstr[r] = '.'; + break; + case 0x03: + outstr[r] = '¦'; + break; + default: + outstr[r] = ' '; + break; + + } + } + LOG_MSG("%s", outstr); + } + */ + } void VGA_SetupXGA(void) { @@ -521,6 +1024,9 @@ void VGA_SetupXGA(void) { IO_RegisterWriteHandler(0xe2e8,&XGA_Write,IO_MB | IO_MW | IO_MD); IO_RegisterReadHandler(0xe2e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0xe2e0,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xe2e0,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0xe2ea,&XGA_Write,IO_MB | IO_MW | IO_MD); IO_RegisterReadHandler(0xe2ea,&XGA_Read,IO_MB | IO_MW | IO_MD); From d1d89dc803d9f5ae0f71badb6275d040ff9138e8 Mon Sep 17 00:00:00 2001 From: Dean Beeler Date: Wed, 22 Dec 2004 10:55:33 +0000 Subject: [PATCH 2001/4131] Completing S3 XGA functionality. Fixed minor mouse glitch. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2085 --- src/hardware/vga_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index cbbd8aaa..a351ccc2 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -108,7 +108,7 @@ static Bit8u * VGA_Draw_VGA_Line(Bitu vidstart,Bitu panning,Bitu line) { static Bit8u * VGA_Draw_VGA_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) { if(vga.s3.hgc.curmode & 0x1) { - Bitu lineat = vidstart / ((160 * vga.draw.height) / 640); + Bitu lineat = vidstart / ((220 * vga.draw.height) / 640); if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63))) { return VGA_Draw_VGA_Line(vidstart, panning, line); } else { From fba8482ce10c8f11fd99008ddd72c0fafc4c40b1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 22 Dec 2004 19:49:24 +0000 Subject: [PATCH 2002/4131] Use special physical memory access for dma transfers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2086 --- include/paging.h | 5 +++-- src/cpu/paging.cpp | 11 ++++++----- src/hardware/dma.cpp | 32 +++++++++++++++++++++++++++----- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/include/paging.h b/include/paging.h index 1366babb..3880c1d5 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.12 2004-10-12 10:45:10 harekiet Exp $ */ +/* $Id: paging.h,v 1.13 2004-12-22 19:49:24 harekiet Exp $ */ #ifndef _PAGING_H_ #define _PAGING_H_ @@ -117,7 +117,8 @@ struct PagingBlock { Bitu used; Bit32u entries[PAGING_LINKS]; } links; - bool enabled; + Bit32u firstmb[LINK_START]; + bool enabled; }; extern PagingBlock paging; diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 6198bafa..fa2ccfa3 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -31,7 +31,8 @@ #define LINK_TOTAL (64*1024) PagingBlock paging; -static Bit32u mapfirstmb[LINK_START]; + + Bitu PageHandler::readb(PhysPt addr) { E_Exit("No byte handler for read from %d",addr); @@ -191,7 +192,7 @@ public: phys_writed(entry_addr,entry.load); phys_page=entry.block.base; } else { - if (lin_page> 12; + if (page < LINK_START) + page = paging.firstmb[page]; + *write++=phys_readb(page*4096 + (pt & 4095)); + } +} + +static void DMA_BlockWrite(PhysPt pt,void * data,Bitu size) { + Bit8u * read=(Bit8u *) data; + for ( ; size ; size--, pt++) { + Bitu page = pt >> 12; + if (page < LINK_START) + page = paging.firstmb[page]; + phys_writeb(page*4096 + (pt & 4095), *read++); + } +} + static void DMA_WriteControllerReg(DmaController * cont,Bitu reg,Bitu val,Bitu len) { DmaChannel * chan;Bitu i; Bitu base=cont->chanbase; @@ -121,7 +142,8 @@ static Bitu DMA_ReadControllerReg(DmaController * cont,Bitu reg,Bitu len) { } return ret; default: - LOG_MSG("Trying to read undefined DMA Red %x",reg); + LOG_MSG("Trying to read undefined DMA port %x",reg); + break; } return 0xffffffff; } @@ -180,12 +202,12 @@ Bitu DmaChannel::Read(Bitu want, Bit8u * buffer) { again: Bitu left=(currcnt+1); if (want Date: Fri, 24 Dec 2004 05:35:10 +0000 Subject: [PATCH 2003/4131] Completed S3 XGA compatibility Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2087 --- include/vga.h | 3 - src/hardware/vga_crtc.cpp | 11 -- src/hardware/vga_draw.cpp | 31 ++- src/hardware/vga_memory.cpp | 7 +- src/hardware/vga_xga.cpp | 364 +++++++++++++++++++----------------- 5 files changed, 224 insertions(+), 192 deletions(-) diff --git a/include/vga.h b/include/vga.h index c5124914..f34af2bb 100644 --- a/include/vga.h +++ b/include/vga.h @@ -345,9 +345,6 @@ void VGA_SetCGA2Table(Bit8u val0,Bit8u val1); void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3); void VGA_ActivateHardwareCursor(void); -/* XGA Functionality */ -void XGA_UpdateHWC(void); - extern VGA_Type vga; extern Bit32u ExpandTable[256]; diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index c2506ec0..0f89f663 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -353,51 +353,40 @@ void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen) { vga.s3.hgc.curmode = val; // Activate hardware cursor code if needed VGA_ActivateHardwareCursor(); - XGA_UpdateHWC(); break; case 0x46: vga.s3.hgc.originx = (vga.s3.hgc.originx & 0x00ff) | (val << 8); - XGA_UpdateHWC(); break; case 0x47: /* HGC orgX */ vga.s3.hgc.originx = (vga.s3.hgc.originx & 0xff00) | val; - XGA_UpdateHWC(); break; case 0x48: vga.s3.hgc.originy = (vga.s3.hgc.originy & 0x00ff) | (val << 8); - XGA_UpdateHWC(); break; case 0x49: /* HGC orgY */ vga.s3.hgc.originy = (vga.s3.hgc.originy & 0xff00) | val; - XGA_UpdateHWC(); break; case 0x4A: /* HGC foreground stack */ if (vga.s3.hgc.fstackpos > 2) vga.s3.hgc.fstackpos = 0; vga.s3.hgc.forestack[vga.s3.hgc.fstackpos] = val; vga.s3.hgc.fstackpos++; - XGA_UpdateHWC(); break; case 0x4B: /* HGC background stack */ if (vga.s3.hgc.bstackpos > 2) vga.s3.hgc.bstackpos = 0; vga.s3.hgc.backstack[vga.s3.hgc.bstackpos] = val; vga.s3.hgc.bstackpos++; - XGA_UpdateHWC(); break; case 0x4c: /* HGC start address high byte*/ vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | ((val & 0xff) << 8); - XGA_UpdateHWC(); break; case 0x4d: /* HGC start address low byte*/ vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | (val & 0xff); - XGA_UpdateHWC(); break; case 0x4e: /* HGC pattern start X */ vga.s3.hgc.posx = val; - XGA_UpdateHWC(); break; case 0x4f: /* HGC pattern start X */ vga.s3.hgc.posy = val; - XGA_UpdateHWC(); break; case 0x51: /* Extended System Control 2 */ vga.s3.reg_51=val & 0xc0; //Only store bits 6,7 diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index a351ccc2..90c672b0 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -108,7 +108,7 @@ static Bit8u * VGA_Draw_VGA_Line(Bitu vidstart,Bitu panning,Bitu line) { static Bit8u * VGA_Draw_VGA_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) { if(vga.s3.hgc.curmode & 0x1) { - Bitu lineat = vidstart / ((220 * vga.draw.height) / 640); + Bitu lineat = vidstart / ((160 * vga.draw.height) / 480); if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63))) { return VGA_Draw_VGA_Line(vidstart, panning, line); } else { @@ -119,11 +119,25 @@ static Bit8u * VGA_Draw_VGA_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) if(moff>63) return VGA_Draw_VGA_Line(vidstart, panning, line); if(moff<0) moff+=64; Bitu xat = vga.s3.hgc.originx; - Bitu m, mat; - mat = vga.s3.hgc.posx; + Bitu m, mat, mapat; + Bits r, z; + mapat = 0; - for(m=0;m<64;m++) { - switch(vga.s3.hgc.mc[moff][mat]) { + Bitu mouseaddr = (Bit32u)vga.s3.hgc.startaddr * (Bit32u)1024; + mouseaddr+=(moff * 16); + + Bit16u bitsA, bitsB; + Bit8u mappoint; + for(m=0;m<4;m++) { + bitsA = *(Bit16u *)&vga.mem.linear[mouseaddr]; + mouseaddr+=2; + bitsB = *(Bit16u *)&vga.mem.linear[mouseaddr]; + mouseaddr+=2; + z = 7; + for(r=15;r>=0;--r) { + mappoint = (((bitsA >> z) & 0x1) << 1) | ((bitsB >> z) & 0x1); + if(mapat >= vga.s3.hgc.posx) { + switch(mappoint) { case 0: TempLine[xat] = vga.s3.hgc.backstack[0]; break; @@ -139,8 +153,11 @@ static Bit8u * VGA_Draw_VGA_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) break; } xat++; - mat++; - if(mat>63) break; + } + mapat++; + --z; + if(z<0) z=15; + } } return TempLine; } diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 0dbe1da3..94ad089f 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -242,7 +242,7 @@ public: void writeb(PhysPt addr,Bitu val) { Bitu port = addr & 0xffff; if(port >= 0x82E8) IO_WriteB(port, val); - if(port <= 0x0020) { + if(port <= 0x4000) { if(port == 0x0000) { IO_WriteB(0xe2e0, val); } else { @@ -255,14 +255,13 @@ public: Bitu port = addr & 0xffff; if(port >= 0x82E8) IO_WriteW(port, val); if(port == 0x8118) IO_WriteW(0x9ae8, val); - if(port <= 0x0020) { + if(port <= 0x4000) { if(port == 0x0000) { IO_WriteW(0xe2e0, val); } else { IO_WriteW(0xe2e8, val); } } - //LOG_MSG("MMIO: Write word to %x with %x", addr, val); } void writed(PhysPt addr,Bitu val) { @@ -276,7 +275,7 @@ public: IO_WriteW(0x96e8, (val >> 16)); IO_WriteW(0xbee8, (val & 0xffff)); } - if(port <= 0x0020) { + if(port <= 0x4000) { if(port == 0x0000) { IO_WriteW(0xe2e0, (val & 0xffff)); IO_WriteW(0xe2e8, (val >> 16)); diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index ac20cfa1..f600dda7 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -25,6 +25,8 @@ #define XGA_SCREEN_WIDTH vga.draw.width +#define XGA_SHOW_COMMAND_TRACE 0 + struct XGAStatus { struct scissorreg { Bit16u x1, y1, x2, y2; @@ -56,7 +58,7 @@ struct XGAStatus { bool wait; Bit16u cmd; Bit16u curx, cury; - Bit16u x1, y1, x2, y2; + Bit16u x1, y1, x2, y2, sizex, sizey; } waitcmd; } xga; @@ -94,6 +96,7 @@ void XGA_Write_Multifunc(Bitu val, Bitu len) { void XGA_DrawPoint8(Bitu x, Bitu y, Bit8u c) { + if(!(xga.curcommand & 0x1)) return; if(!(xga.curcommand & 0x10)) return; if(x < xga.scissors.x1) return; @@ -388,28 +391,25 @@ void XGA_DrawLineBresenham(Bitu val) { } -void XGA_DrawRectangle(Bitu x1, Bitu y1, Bitu x2, Bitu y2) { +void XGA_DrawRectangle(Bitu val) { Bit32u xat, yat; - Bit32u xmass, xmod, xdist, ydist; - Bit32u *memptr; - Bit8u *smallptr; - Bit32u c; - Bit8u smallc; Bit8u srcval; Bit8u destval; Bit8u dstdata; - xdist = (x2 -x1); - ydist = (y2 -y1); - xmass = (xdist) & 0xfffffffb; - xmod = (xdist) & 0x3; + Bits srcx, srcy, dx, dy; - smallc = (xga.forecolor & 0xff); + dx = -1; + dy = -1; - c = (smallc) | ((smallc) << 8) | ((smallc) << 16) | ((smallc) << 24); + if(((val >> 5) & 0x01) != 0) dx = 1; + if(((val >> 7) & 0x01) != 0) dy = 1; - for(yat=y1;yat<=y2;yat++) { - for(xat=x1;xat<=x2;xat++) { + srcy = xga.cury; + + for(yat=0;yat<=xga.MIPcount;yat++) { + srcx = xga.curx; + for(xat=0;xat<=xga.MAPcount;xat++) { Bitu mixmode = (xga.pix_cntl >> 6) & 0x3; switch (mixmode) { case 0x00: /* FOREMIX always used */ @@ -433,26 +433,29 @@ void XGA_DrawRectangle(Bitu x1, Bitu y1, Bitu x2, Bitu y2) { LOG_MSG("XGA: DrawRect: Shouldn't be able to get here!"); break; } - dstdata = XGA_GetPoint8(xat,yat); + dstdata = XGA_GetPoint8(srcx,srcy); destval = XGA_GetMixResult(mixmode, srcval, dstdata); - XGA_DrawPoint8(xat,yat, destval); + XGA_DrawPoint8(srcx,srcy, destval); break; default: LOG_MSG("XGA: DrawRect: Needs mixmode %x", mixmode); break; } + srcx += dx; } + srcy += dy; } - xga.curx = xat; - xga.cury = yat; + xga.curx = srcx; + xga.cury = srcy; //LOG_MSG("XGA: Draw rect (%d, %d)-(%d, %d), %d", x1, y1, x2, y2, xga.forecolor); } bool XGA_CheckX(void) { bool newline = false; + if(!xga.waitcmd.newline) { if(xga.waitcmd.curx > xga.waitcmd.x2) { xga.waitcmd.curx = xga.waitcmd.x1; xga.waitcmd.cury++; @@ -460,12 +463,18 @@ bool XGA_CheckX(void) { xga.waitcmd.newline = true; if(xga.waitcmd.cury > xga.waitcmd.y2) xga.waitcmd.wait = false; } + } else { + xga.waitcmd.newline = false; + } return newline; } void XGA_DrawWait(Bitu val, Bitu len) { if(!xga.waitcmd.wait) return; + + //if(!(xga.curcommand & 0x2)) return; + Bitu mixmode = (xga.pix_cntl >> 6) & 0x3; Bit8u srcval; Bit8u destval; @@ -511,7 +520,8 @@ void XGA_DrawWait(Bitu val, Bitu len) { XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, destval); - //XGA_CheckX(); + XGA_CheckX(); + if(xga.waitcmd.newline) break; } break; case 0x02: /* Data from PIX_TRANS selects the mix */ @@ -585,6 +595,7 @@ void XGA_DrawWait(Bitu val, Bitu len) { xga.waitcmd.curx++; XGA_CheckX(); + if(xga.waitcmd.newline) break; } //xga.waitcmd.cury++; @@ -606,87 +617,133 @@ void XGA_DrawWait(Bitu val, Bitu len) { void XGA_BlitRect(Bitu val) { Bit32u xat, yat; Bit32u xmass, xmod, xdist, memrec; - Bit8u *srcptr; - Bit8u *destptr; - Bit8u *destline; - Bit8u *srcline; - - Bit32u c; - Bit8u smallc; - Bit8u tmpclr; - bool incx = false; - bool incy = false; - - if(((val >> 5) & 0x01) != 0) incx = true; - if(((val >> 7) & 0x01) != 0) incy = true; - - xdist = xga.MAPcount; - - smallc = (xga.forecolor & 0xff); - memrec = 0; - Bit32u srcaddr = (xga.cury * (Bit32u)XGA_SCREEN_WIDTH) + xga.curx; - Bit32u destaddr = (xga.desty * (Bit32u)XGA_SCREEN_WIDTH) + xga.destx; - - srcptr = &vga.mem.linear[srcaddr]; - destptr = &vga.mem.linear[destaddr]; - - /* Copy source to video ram */ - for(yat=0;yat<=xga.MIPcount ;yat++) { - srcline = srcptr; - destline = destptr; - for(xat=0;xat<=xga.MAPcount;xat++) { - *destline = *srcline; - //LOG_MSG("Copy (%d, %d) to (%d, %d)", sx, sy, tx, ty); - if(incx) { - destline++; - srcline++; - } else { - --destline; - --srcline; - } - } - if(incy) { - srcptr+=XGA_SCREEN_WIDTH; - destptr+=XGA_SCREEN_WIDTH; - } else { - srcptr-=XGA_SCREEN_WIDTH; - destptr-=XGA_SCREEN_WIDTH; - } - } - - //LOG_MSG("XGA: Blit (%d, %d)-(%d, %d) to (%d, %d)-(%d, %d), incx %d, incy %d", xga.curx, xga.cury, xga.curx + xdist, xga.cury + xga.MIPcount, xga.destx, xga.desty, xga.destx + xdist, xga.desty + xga.MIPcount, incx, incy); - -} - -void XGA_DrawPattern(void) { - Bit32u xat, yat, y1, y2, sx, sy, addx, addy; - Bit32u xmass, xmod, xdist; - Bit32u *memptr; - Bit8u *smallptr; - Bit8u smallc; + //Bit8u *srcptr; + //Bit8u *destptr; + //Bit8u *destline; + //Bit8u *srcline; Bit8u srcdata; Bit8u dstdata; Bit8u srcval; Bit8u destval; - y1 = xga.desty; - y2 = xga.desty + xga.MIPcount; - xdist = xga.MAPcount; - sx = xga.curx; - sy = xga.cury; - addx = 0; - addy = 0; + Bits srcx, srcy, tarx, tary, dx, dy; + //bool incx = false; + //bool incy = false; + + dx = -1; + dy = -1; + + //if(((val >> 5) & 0x01) != 0) incx = true; + //if(((val >> 7) & 0x01) != 0) incy = true; + + if(((val >> 5) & 0x01) != 0) dx = 1; + if(((val >> 7) & 0x01) != 0) dy = 1; + + //Bit32u srcaddr = (xga.cury * (Bit32u)XGA_SCREEN_WIDTH) + xga.curx; + //Bit32u destaddr = (xga.desty * (Bit32u)XGA_SCREEN_WIDTH) + xga.destx; + srcx = xga.curx; + srcy = xga.cury; + tarx = xga.destx; + tary = xga.desty; + + //srcptr = &vga.mem.linear[srcaddr]; + //destptr = &vga.mem.linear[destaddr]; + + Bitu mixselect = (xga.pix_cntl >> 6) & 0x3; + Bitu mixmode = 0x67; /* Source is bitmap data, mix mode is src */ + switch(mixselect) { + case 0x00: /* Foreground mix is always used */ + mixmode = xga.foremix; + break; + case 0x02: /* CPU Data determines mix used */ + LOG_MSG("XGA: DrawPattern: Mixselect data from PIX_TRANS register"); + break; + case 0x03: /* Video memory determines mix */ + //LOG_MSG("XGA: Srcdata: %x, Forecolor %x, Backcolor %x, Foremix: %x Backmix: %x", srcdata, xga.forecolor, xga.backcolor, xga.foremix, xga.backmix); + break; + default: + LOG_MSG("XGA: DrawPattern: Unknown mix select register"); + break; + } - for(yat=y1;yat<=y2;yat++) { - for(xat=0;xat<=xdist;xat++) { + /* Copy source to video ram */ + for(yat=0;yat<=xga.MIPcount ;yat++) { + srcx = xga.curx; + tarx = xga.destx; - Bitu usex = xga.destx + xat; - Bitu usey = yat; + for(xat=0;xat<=xga.MAPcount;xat++) { + srcdata = XGA_GetPoint8(srcx, srcy); + dstdata = XGA_GetPoint8(tarx, tary); + + if(mixselect == 0x3) { + if(srcdata == xga.forecolor) { + mixmode = xga.foremix; + } else { + if(srcdata == xga.backcolor) { + mixmode = xga.backmix; + } else { + /* Best guess otherwise */ + mixmode = 0x67; /* Source is bitmap data, mix mode is src */ + } + } + } + + switch((mixmode >> 5) & 0x03) { + case 0x00: /* Src is background color */ + srcval = xga.backcolor; + break; + case 0x01: /* Src is foreground color */ + srcval = xga.forecolor; + break; + case 0x02: /* Src is pixel data from PIX_TRANS register */ + LOG_MSG("XGA: DrawPattern: Wants data from PIX_TRANS register"); + break; + case 0x03: /* Src is bitmap data */ + srcval = srcdata; + break; + default: + LOG_MSG("XGA: DrawPattern: Shouldn't be able to get here!"); + break; + } + + destval = XGA_GetMixResult(mixmode, srcval, dstdata); + + //LOG_MSG("XGA: DrawPattern: Mixmode: %x Mixselect: %x", mixmode, mixselect); + + //*smallptr++ = destval; + XGA_DrawPoint8(tarx, tary, destval); + + srcx += dx; + tarx += dx; + } + srcy += dy; + tary += dy; + } + +} + +void XGA_DrawPattern(Bitu val) { + Bit8u srcdata; + Bit8u dstdata; + + Bit8u srcval; + Bit8u destval; + + Bits xat, yat, srcx, srcy, tarx, tary, dx, dy; + + dx = -1; + dy = -1; + + if(((val >> 5) & 0x01) != 0) dx = 1; + if(((val >> 7) & 0x01) != 0) dy = 1; + + srcx = xga.curx; + srcy = xga.cury; + + tary = xga.desty; - srcdata = XGA_GetPoint8(sx + (usex & 0x7), sy + (usey & 0x7)); - dstdata = XGA_GetPoint8(usex, usey); Bitu mixselect = (xga.pix_cntl >> 6) & 0x3; Bitu mixmode = 0x67; /* Source is bitmap data, mix mode is src */ switch(mixselect) { @@ -697,6 +754,22 @@ void XGA_DrawPattern(void) { LOG_MSG("XGA: DrawPattern: Mixselect data from PIX_TRANS register"); break; case 0x03: /* Video memory determines mix */ + //LOG_MSG("XGA: Srcdata: %x, Forecolor %x, Backcolor %x, Foremix: %x Backmix: %x", srcdata, xga.forecolor, xga.backcolor, xga.foremix, xga.backmix); + break; + default: + LOG_MSG("XGA: DrawPattern: Unknown mix select register"); + break; + } + + for(yat=0;yat<=xga.MIPcount;yat++) { + tarx = xga.destx; + for(xat=0;xat<=xga.MAPcount;xat++) { + + srcdata = XGA_GetPoint8(srcx + (tarx & 0x7), srcy + (tary & 0x7)); + dstdata = XGA_GetPoint8(tarx, tary); + + + if(mixselect == 0x3) { if(srcdata == xga.forecolor) { mixmode = xga.foremix; } else { @@ -707,12 +780,8 @@ void XGA_DrawPattern(void) { mixmode = 0x67; /* Source is bitmap data, mix mode is src */ } } - //LOG_MSG("XGA: Srcdata: %x, Forecolor %x, Backcolor %x, Foremix: %x Backmix: %x", srcdata, xga.forecolor, xga.backcolor, xga.foremix, xga.backmix); - break; - default: - LOG_MSG("XGA: DrawPattern: Unknown mix select register"); - break; } + switch((mixmode >> 5) & 0x03) { case 0x00: /* Src is background color */ srcval = xga.backcolor; @@ -733,13 +802,11 @@ void XGA_DrawPattern(void) { destval = XGA_GetMixResult(mixmode, srcval, dstdata); - //LOG_MSG("XGA: DrawPattern: Mixmode: %x Mixselect: %x", mixmode, mixselect); - - //*smallptr++ = destval; - XGA_DrawPoint8(usex, usey, destval); - + XGA_DrawPoint8(tarx, tary, destval); + tarx += dx; } + tary += dy; } @@ -748,16 +815,22 @@ void XGA_DrawPattern(void) { void XGA_DrawCmd(Bitu val, Bitu len) { Bit16u cmd; cmd = val >> 13; - //LOG_MSG("XGA: Draw command %x", cmd); +#if XGA_SHOW_COMMAND_TRACE == 1 + LOG_MSG("XGA: Draw command %x", cmd); +#endif xga.curcommand = val; switch(cmd) { case 1: /* Draw line */ if((val & 0x100) == 0) { if((val & 0x8) == 0) { - //LOG_MSG("XGA: Drawing Bresenham line"); +#if XGA_SHOW_COMMAND_TRACE == 1 + LOG_MSG("XGA: Drawing Bresenham line"); +#endif XGA_DrawLineBresenham(val); } else { - //LOG_MSG("XGA: Drawing vector line"); +#if XGA_SHOW_COMMAND_TRACE == 1 + LOG_MSG("XGA: Drawing vector line"); +#endif XGA_DrawLineVector(val); } } else { @@ -767,8 +840,12 @@ void XGA_DrawCmd(Bitu val, Bitu len) { case 2: /* Rectangle fill */ if((val & 0x100) == 0) { xga.waitcmd.wait = false; - XGA_DrawRectangle(xga.curx, xga.cury, xga.curx + xga.MAPcount, xga.cury + xga.MIPcount); + XGA_DrawRectangle(val); +#if XGA_SHOW_COMMAND_TRACE == 1 + LOG_MSG("XGA: Draw immediate rect"); +#endif } else { + xga.waitcmd.newline = true; xga.waitcmd.wait = true; xga.waitcmd.curx = xga.curx; @@ -777,16 +854,26 @@ void XGA_DrawCmd(Bitu val, Bitu len) { xga.waitcmd.y1 = xga.cury; xga.waitcmd.x2 = xga.curx + xga.MAPcount; xga.waitcmd.y2 = xga.cury + xga.MIPcount + 1; + xga.waitcmd.sizex = xga.MAPcount; + xga.waitcmd.sizey = xga.MIPcount + 1; xga.waitcmd.cmd = 2; - //LOG_MSG("XGA: Draw wait rect (%d, %d)-(%d, %d)", xga.waitcmd.x1, xga.waitcmd.y1, xga.waitcmd.x2, xga.waitcmd.y2); + +#if XGA_SHOW_COMMAND_TRACE == 1 + LOG_MSG("XGA: Draw wait rect, width %d, heigth %d", xga.MAPcount, xga.MIPcount+1); +#endif } break; case 6: /* BitBLT */ XGA_BlitRect(val); +#if XGA_SHOW_COMMAND_TRACE == 1 + LOG_MSG("XGA: Blit Rect"); +#endif break; case 7: /* Pattern fill */ - XGA_DrawPattern(); - //LOG_MSG("XGA: Pattern fill (%d, %d)-(%d, %d) to (%d, %d)-(%d, %d)", xga.curx, xga.cury, xga.curx + 8, xga.cury + 8, xga.destx, xga.desty, xga.destx + xga.MAPcount, xga.desty + xga.MIPcount); + XGA_DrawPattern(val); +#if XGA_SHOW_COMMAND_TRACE == 1 + LOG_MSG("XGA: Pattern fill"); +#endif break; default: LOG_MSG("XGA: Unhandled draw command %x", cmd); @@ -845,6 +932,7 @@ void XGA_Write(Bitu port, Bitu val, Bitu len) { xga.waitcmd.cury++; xga.waitcmd.newline = true; } + XGA_DrawWait(val, len); if(xga.waitcmd.cury > xga.waitcmd.y2) xga.waitcmd.wait = false; break; @@ -860,7 +948,7 @@ void XGA_Write(Bitu port, Bitu val, Bitu len) { } Bitu XGA_Read(Bitu port, Bitu len) { - LOG_MSG("XGA: Read from port %x, len %x", port, len); + //LOG_MSG("XGA: Read from port %x, len %x", port, len); switch(port) { case 0x9ae8: return 0x0; @@ -878,64 +966,6 @@ Bitu XGA_Read(Bitu port, Bitu len) { } } -void XGA_UpdateHWC(void) { - Bitu mouseaddr = (Bit32u)vga.s3.hgc.startaddr * (Bit32u)1024; - Bits x, y, t, m, xat, r, z; - x = vga.s3.hgc.originx; - y = vga.s3.hgc.originy; - Bit16u bitsA, bitsB; - Bit16u ab, bb; - - /* Read mouse cursor */ - for(t=0;t<64;t++) { - xat = 0; - for(m=0;m<4;m++) { - bitsA = *(Bit16u *)&vga.mem.linear[mouseaddr]; - mouseaddr+=2; - bitsB = *(Bit16u *)&vga.mem.linear[mouseaddr]; - mouseaddr+=2; - z = 7; - for(r=15;r>=0;--r) { - vga.s3.hgc.mc[t][xat] = (((bitsA >> z) & 0x1) << 1) | ((bitsB >> z) & 0x1); - xat++; - --z; - if(z<0) z=15; - } - } - } - - // Dump the cursor to the log - /* - LOG_MSG("--- New cursor ---"); - for(t=0;t<64;t++) { - char outstr[66]; - memset(outstr,0,66); - for(r=0;r<64;r++) { - switch(vga.s3.hgc.mc[t][r]) { - case 0x00: - outstr[r] = 'o'; - break; - case 0x01: - outstr[r] = 'O'; - break; - case 0x02: - outstr[r] = '.'; - break; - case 0x03: - outstr[r] = '¦'; - break; - default: - outstr[r] = ' '; - break; - - } - } - LOG_MSG("%s", outstr); - } - */ - -} - void VGA_SetupXGA(void) { if (machine!=MCH_VGA) return; From 5a8b59fd75c78f5abe8a11fdd55cd6154edc7163 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Dec 2004 15:10:52 +0000 Subject: [PATCH 2004/4131] Slightly changed the debug display and exit routines to be more compatible with other terminals and languages Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2088 --- src/debug/debug.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 122ba85d..b5518cc3 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,10 +16,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.60 2004-10-23 15:15:06 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.61 2004-12-28 15:10:52 qbix79 Exp $ */ #include #include +#include #include "dosbox.h" #if C_DEBUG @@ -610,8 +611,8 @@ static void DrawData(void) { ch = mem_readb(address); } else ch = 0; mvwprintw (dbg.win_data,1+y,11+3*x,"%02X",ch); - if (ch<32) ch='.'; - mvwprintw (dbg.win_data,1+y,60+x,"%c",ch); + if (ch<32 || !isprint(*reinterpret_cast(&ch))) ch='.'; + mvwprintw (dbg.win_data,1+y,60+x,"%c",ch); add++; }; } @@ -1758,7 +1759,8 @@ static void DEBUG_ShutDown(Section * sec) #ifndef WIN32 curs_set(old_cursor_state); tcsetattr(0, TCSANOW,&consolesettings); - printf("\e[0m\e[2J"); +// printf("\e[0m\e[2J"); //Seems to destroy scrolling + printf("\ec"); fflush(NULL); #endif }; From 16c80d9fb0b19422195bd61141a8bc248809cd41 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Dec 2004 15:56:23 +0000 Subject: [PATCH 2005/4131] Fix playback under win ench Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2089 --- src/hardware/mpu401.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index a7ff9949..339b3155 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.12 2004-12-14 21:02:57 qbix79 Exp $ */ +/* $Id: mpu401.cpp,v 1.13 2004-12-28 15:56:23 qbix79 Exp $ */ #include #include "dosbox.h" @@ -554,6 +554,7 @@ static Bitu INT71_Handler() { } CALLBACK_RunRealInt(0xa); IO_Write(0xa0,0x61); + IO_Write(0x20,0x62); if (signr) if (mpu.queue_used==1) ClrQueue(); return CBRET_NONE; From b2fa2df349ef4d9c1dd09c7d62eeea097527e3ca Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Dec 2004 15:57:31 +0000 Subject: [PATCH 2006/4131] Change irq mask with ps2 callback. Use pops instead of a normal stack adjustment Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2090 --- src/ints/mouse.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 1bc91607..48c7b322 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.43 2004-12-07 21:49:13 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.44 2004-12-28 15:57:31 qbix79 Exp $ */ #include #include @@ -125,6 +125,7 @@ void Mouse_SetPS2State(bool use) { if ((SegValue(es)!=0) && (reg_bx!=0)) useps2callback = use; else useps2callback = false; Mouse_AutoLock(useps2callback); + PIC_SetIRQMask(MOUSE_IRQ,!useps2callback); } void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs) { @@ -166,7 +167,7 @@ void DoPS2Callback(Bit16u data, Bit16s mouseX, Bit16s mouseY) { } Bitu PS2_Handler(void) { - reg_sp += 8; // remove the 4 words + CPU_Pop16();CPU_Pop16();CPU_Pop16();CPU_Pop16();// remove the 4 words return CBRET_NONE; } From d17551ad8c7bfef705f33fce030aa56430b97d63 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Dec 2004 15:58:49 +0000 Subject: [PATCH 2007/4131] added 4 and 5 parameters Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2091 --- include/logging.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/logging.h b/include/logging.h index 570bc7f2..ecac37d9 100644 --- a/include/logging.h +++ b/include/logging.h @@ -45,6 +45,8 @@ struct LOG void operator()(char const* buf, double f1) { return;} void operator()(char const* buf, double f1, double f2) { return;} void operator()(char const* buf, double f1, double f2, double f3) { return;} + void operator()(char const* buf, double f1, double f2, double f3, double f4) { return;} + void operator()(char const* buf, double f1, double f2, double f3, double f4, double f5) { return;} void operator()(char const* buf, char const* s1) { return;} void operator()(char const* buf, char const* s1, double f1) { return;} From 3fd1789b9502b779997de0d139502343890553dd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Dec 2004 16:03:02 +0000 Subject: [PATCH 2008/4131] Seperate read and write faults(wd). And lowered priority a bit of the log messages Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2092 --- src/cpu/paging.cpp | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index fa2ccfa3..4b096581 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -105,7 +105,7 @@ Bitu DEBUG_EnableDebugger(void); bool first=false; -void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu type) { +void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,bool writefault,Bitu faultcode) { /* Save the state of the cpu cores */ LazyFlags old_lflags; memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); @@ -114,14 +114,14 @@ void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu type) { cpudecoder=&PageFaultCore; paging.cr2=lin_addr; PF_Entry * entry=&pf_queue.entries[pf_queue.used++]; - LOG(LOG_PAGING,LOG_NORMAL)("PageFault at %X type %d queue %d",lin_addr,type,pf_queue.used); + LOG(LOG_PAGING,LOG_NORMAL)("PageFault at %X type [%x:%x] queue %d",lin_addr,writefault,faultcode,pf_queue.used); // LOG_MSG("EAX:%04X ECX:%04X EDX:%04X EBX:%04X",reg_eax,reg_ecx,reg_edx,reg_ebx); // LOG_MSG("CS:%04X EIP:%08X SS:%04x SP:%08X",SegValue(cs),reg_eip,SegValue(ss),reg_esp); entry->cs=SegValue(cs); entry->eip=reg_eip; entry->page_addr=page_addr; //Caused by a write by default? - CPU_Exception(14,0x2 ); + CPU_Exception(14,(writefault?0x02:0x00) | faultcode); #if C_DEBUG // DEBUG_EnableDebugger(); #endif @@ -137,30 +137,30 @@ class InitPageHandler : public PageHandler { public: InitPageHandler() {flags=PFLAG_INIT|PFLAG_NOCODE;} Bitu readb(PhysPt addr) { - InitPage(addr); + InitPage(addr,false); return mem_readb(addr); } Bitu readw(PhysPt addr) { - InitPage(addr); + InitPage(addr,false); return mem_readw(addr); } Bitu readd(PhysPt addr) { - InitPage(addr); + InitPage(addr,false); return mem_readd(addr); } void writeb(PhysPt addr,Bitu val) { - InitPage(addr); + InitPage(addr,true); mem_writeb(addr,val); } void writew(PhysPt addr,Bitu val) { - InitPage(addr); + InitPage(addr,true); mem_writew(addr,val); } void writed(PhysPt addr,Bitu val) { - InitPage(addr); + InitPage(addr,true); mem_writed(addr,val); } - void InitPage(Bitu lin_addr) { + void InitPage(Bitu lin_addr,bool writing) { Bitu lin_page=lin_addr >> 12; Bitu phys_page; if (paging.enabled) { @@ -170,25 +170,32 @@ public: X86PageEntry table; table.load=phys_readd(table_addr); if (!table.block.p) { - LOG(LOG_PAGING,LOG_ERROR)("NP Table"); - PAGING_PageFault(lin_addr,table_addr,0); + LOG(LOG_PAGING,LOG_NORMAL)("NP Table"); + PAGING_PageFault(lin_addr,table_addr,false,0); // read fault table.load=phys_readd(table_addr); if (!table.block.p) E_Exit("Pagefault didn't correct table"); } - table.block.a=table.block.d=1; //Set access/Dirty + table.block.a=1; //Set access phys_writed(table_addr,table.load); X86PageEntry entry; Bitu entry_addr=(table.block.base<<12)+t_index*4; entry.load=phys_readd(entry_addr); if (!entry.block.p) { - LOG(LOG_PAGING,LOG_ERROR)("NP Page"); - PAGING_PageFault(lin_addr,entry_addr,0); +// LOG(LOG_PAGING,LOG_NORMAL)("NP Page"); + PAGING_PageFault(lin_addr,entry_addr,false,0); entry.load=phys_readd(entry_addr); if (!entry.block.p) E_Exit("Pagefault didn't correct page"); } - entry.block.a=entry.block.d=1; //Set access/Dirty + entry.block.a=1; //Set access + if (cpu.cpl==3) { + if ((entry.block.us==0) || (table.block.us==0) || (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { + LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); + PAGING_PageFault(lin_addr,entry_addr,writing,0x05); + } + } + entry.block.d=1; //Set dirty phys_writed(entry_addr,entry.load); phys_page=entry.block.base; } else { From 36cc51917020612e12d0625736425dde793b2061 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Dec 2004 16:11:54 +0000 Subject: [PATCH 2009/4131] Changed priority of some messages (Requested by Mirek) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2093 --- src/cpu/core_normal.cpp | 2 +- src/cpu/cpu.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 9aa0db94..13221300 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -171,7 +171,7 @@ restart_opcode: sprintf(writecode,"%X",mem_readb(core.cseip++)); writecode+=2; } - LOG(LOG_CPU,LOG_ERROR)("Illegal/Unhandled opcode %s",tempcode); + LOG(LOG_CPU,LOG_NORMAL)("Illegal/Unhandled opcode %s",tempcode); } #endif CPU_Exception(6,0); diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 32f32830..6deca608 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.61 2004-08-23 12:17:29 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.62 2004-12-28 16:11:54 qbix79 Exp $ */ #include #include "dosbox.h" @@ -320,7 +320,7 @@ bool CPU_IO_Exception(Bitu port,Bitu size) { } return false; doexception: - LOG_MSG("Exception"); + LOG(LOG_CPU,LOG_NORMAL)("IO Exception port %X",port); return CPU_PrepareException(13,0); } From c99f8e8710dbe8a4d71455ce45f5b06fceeca45c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Dec 2004 16:13:26 +0000 Subject: [PATCH 2010/4131] IO Exceptions (wd) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2094 --- include/callback.h | 5 + include/inout.h | 30 ++--- src/cpu/callback.cpp | 21 +++- src/hardware/iohandler.cpp | 237 ++++++++++++++++++++++++++++++++++++- 4 files changed, 272 insertions(+), 21 deletions(-) diff --git a/include/callback.h b/include/callback.h index ca919ab6..291233b3 100644 --- a/include/callback.h +++ b/include/callback.h @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: callback.h,v 1.10 2004-12-28 16:13:26 qbix79 Exp $ */ + #ifndef __CALLBACK_H #define __CALLBACK_H @@ -55,5 +57,8 @@ bool CALLBACK_Free(Bitu callback); void CALLBACK_SCF(bool val); void CALLBACK_SZF(bool val); + +extern Bitu call_priv_io; + #endif diff --git a/include/inout.h b/include/inout.h index bb83949b..54aaf6b8 100644 --- a/include/inout.h +++ b/include/inout.h @@ -16,6 +16,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: inout.h,v 1.6 2004-12-28 16:13:26 qbix79 Exp $ */ + +#ifndef __INOUT_H +#define __INOUT_H + #define IO_MAX (64*1024+3) #define IO_MB 0x1 @@ -35,25 +40,13 @@ void IO_RegisterWriteHandler(Bitu port,IO_WriteHandler * handler,Bitu mask,Bitu void IO_FreeReadHandler(Bitu port,Bitu mask,Bitu range=0); void IO_FreeWriteHandler(Bitu port,Bitu mask,Bitu range=0); -INLINE void IO_WriteB(Bitu port,Bitu val) { - io_writehandlers[0][port](port,val,1); -}; -INLINE void IO_WriteW(Bitu port,Bitu val) { - io_writehandlers[1][port](port,val,2); -}; -INLINE void IO_WriteD(Bitu port,Bitu val) { - io_writehandlers[2][port](port,val,4); -}; +void IO_WriteB(Bitu port,Bitu val); +void IO_WriteW(Bitu port,Bitu val); +void IO_WriteD(Bitu port,Bitu val); -INLINE Bitu IO_ReadB(Bitu port) { - return io_readhandlers[0][port](port,1); -} -INLINE Bitu IO_ReadW(Bitu port) { - return io_readhandlers[1][port](port,2); -} -INLINE Bitu IO_ReadD(Bitu port) { - return io_readhandlers[2][port](port,4); -} +Bitu IO_ReadB(Bitu port); +Bitu IO_ReadW(Bitu port); +Bitu IO_ReadD(Bitu port); INLINE void IO_Write(Bitu port,Bit8u val) { IO_WriteB(port,val); @@ -62,4 +55,5 @@ INLINE Bit8u IO_Read(Bitu port){ return IO_ReadB(port); } +#endif diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 87aaa4ac..5277031d 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.22 2004-08-29 11:22:37 qbix79 Exp $ */ +/* $Id: callback.cpp,v 1.23 2004-12-28 16:13:26 qbix79 Exp $ */ #include #include @@ -38,6 +38,7 @@ CallBack_Handler CallBack_Handlers[CB_MAX]; char* CallBack_Description[CB_MAX]; static Bitu call_stop,call_idle,call_default; +Bitu call_priv_io; static Bitu illegal_handler(void) { E_Exit("Illegal CallBack Called"); @@ -237,6 +238,24 @@ void CALLBACK_Init(Section* sec) { real_writed(0,0x67*4,CALLBACK_RealPointer(call_default)); real_writed(0,0x5c*4,CALLBACK_RealPointer(call_default)); //Network stuff //real_writed(0,0xf*4,0); some games don't like it + + call_priv_io=CALLBACK_Allocate(); + + phys_writeb(CB_BASE+(call_priv_io<<4)+0x00,(Bit8u)0xec); // in al, dx + phys_writeb(CB_BASE+(call_priv_io<<4)+0x01,(Bit8u)0xcb); // retf + phys_writeb(CB_BASE+(call_priv_io<<4)+0x02,(Bit8u)0xed); // in ax, dx + phys_writeb(CB_BASE+(call_priv_io<<4)+0x03,(Bit8u)0xcb); // retf + phys_writeb(CB_BASE+(call_priv_io<<4)+0x04,(Bit8u)0x66); // in eax, dx + phys_writeb(CB_BASE+(call_priv_io<<4)+0x05,(Bit8u)0xed); + phys_writeb(CB_BASE+(call_priv_io<<4)+0x06,(Bit8u)0xcb); // retf + + phys_writeb(CB_BASE+(call_priv_io<<4)+0x08,(Bit8u)0xee); // out dx, al + phys_writeb(CB_BASE+(call_priv_io<<4)+0x09,(Bit8u)0xcb); // retf + phys_writeb(CB_BASE+(call_priv_io<<4)+0x0a,(Bit8u)0xef); // out dx, ax + phys_writeb(CB_BASE+(call_priv_io<<4)+0x0b,(Bit8u)0xcb); // retf + phys_writeb(CB_BASE+(call_priv_io<<4)+0x0c,(Bit8u)0x66); // out dx, eax + phys_writeb(CB_BASE+(call_priv_io<<4)+0x0d,(Bit8u)0xef); + phys_writeb(CB_BASE+(call_priv_io<<4)+0x0e,(Bit8u)0xcb); // retf } diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 904af71f..85874967 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -16,9 +16,16 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: iohandler.cpp,v 1.15 2004-12-28 16:13:26 qbix79 Exp $ */ + #include "dosbox.h" #include "inout.h" +#include +#include "cpu.h" +#include "../src/cpu/lazyflags.h" +#include "callback.h" + IO_WriteHandler * io_writehandlers[3][IO_MAX]; IO_ReadHandler * io_readhandlers[3][IO_MAX]; @@ -99,10 +106,236 @@ void IO_FreeWriteHandler(Bitu port,Bitu mask,Bitu range) { } +struct IOF_Entry { + Bitu cs; + Bitu eip; +}; + +#define IOF_QUEUESIZE 16 +struct { + Bitu used; + IOF_Entry entries[IOF_QUEUESIZE]; +} iof_queue; + +static Bits IOFaultCore(void) { + CPU_CycleLeft+=CPU_Cycles; + CPU_Cycles=1; + Bitu ret=CPU_Core_Full_Run(); + CPU_CycleLeft+=CPU_Cycles; + if (ret<0) E_Exit("Got a dosbox close machine in IO-fault core?"); + if (ret) + return ret; + if (!iof_queue.used) E_Exit("IO-faul Core without IO-faul"); + IOF_Entry * entry=&iof_queue.entries[iof_queue.used-1]; + if (entry->cs == SegValue(cs) && entry->eip==reg_eip) + return -1; + return 0; +} + +Bitu DEBUG_EnableDebugger(); + +void IO_WriteB(Bitu port,Bitu val) { + if (GETFLAG(VM) && (CPU_IO_Exception(port,1))) { + LazyFlags old_lflags; + memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); + CPU_Decoder * old_cpudecoder; + old_cpudecoder=cpudecoder; + cpudecoder=&IOFaultCore; + IOF_Entry * entry=&iof_queue.entries[iof_queue.used++]; + entry->cs=SegValue(cs); + entry->eip=reg_eip; + CPU_Push16(SegValue(cs)); + CPU_Push16(reg_ip); + Bit8u old_al = reg_al; + Bit16u old_dx = reg_dx; + reg_al = val; + reg_dx = port; + RealPt icb = CALLBACK_RealPointer(call_priv_io); + SegSet16(cs,RealSeg(icb)); + reg_eip = RealOff(icb)+0x08; + FillFlags(); + CPU_Exception(cpu.exception.which,cpu.exception.error); + + DOSBOX_RunMachine(); + iof_queue.used--; + + reg_al = old_al; + reg_dx = old_dx; + memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); + cpudecoder=old_cpudecoder; + } + else io_writehandlers[0][port](port,val,1); +}; + +void IO_WriteW(Bitu port,Bitu val) { + if (GETFLAG(VM) && (CPU_IO_Exception(port,2))) { + LazyFlags old_lflags; + memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); + CPU_Decoder * old_cpudecoder; + old_cpudecoder=cpudecoder; + cpudecoder=&IOFaultCore; + IOF_Entry * entry=&iof_queue.entries[iof_queue.used++]; + entry->cs=SegValue(cs); + entry->eip=reg_eip; + CPU_Push16(SegValue(cs)); + CPU_Push16(reg_ip); + Bit16u old_ax = reg_ax; + Bit16u old_dx = reg_dx; + reg_al = val; + reg_dx = port; + RealPt icb = CALLBACK_RealPointer(call_priv_io); + SegSet16(cs,RealSeg(icb)); + reg_eip = RealOff(icb)+0x0a; + FillFlags(); + CPU_Exception(cpu.exception.which,cpu.exception.error); + + DOSBOX_RunMachine(); + iof_queue.used--; + + reg_ax = old_ax; + reg_dx = old_dx; + memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); + cpudecoder=old_cpudecoder; + } + else io_writehandlers[1][port](port,val,2); +}; + +void IO_WriteD(Bitu port,Bitu val) { + if (GETFLAG(VM) && (CPU_IO_Exception(port,4))) { + LazyFlags old_lflags; + memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); + CPU_Decoder * old_cpudecoder; + old_cpudecoder=cpudecoder; + cpudecoder=&IOFaultCore; + IOF_Entry * entry=&iof_queue.entries[iof_queue.used++]; + entry->cs=SegValue(cs); + entry->eip=reg_eip; + CPU_Push16(SegValue(cs)); + CPU_Push16(reg_ip); + Bit32u old_eax = reg_eax; + Bit16u old_dx = reg_dx; + reg_al = val; + reg_dx = port; + RealPt icb = CALLBACK_RealPointer(call_priv_io); + SegSet16(cs,RealSeg(icb)); + reg_eip = RealOff(icb)+0x0c; + FillFlags(); + CPU_Exception(cpu.exception.which,cpu.exception.error); + + DOSBOX_RunMachine(); + iof_queue.used--; + + reg_eax = old_eax; + reg_dx = old_dx; + memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); + cpudecoder=old_cpudecoder; + } + else io_writehandlers[2][port](port,val,4); +}; + +Bitu IO_ReadB(Bitu port) { + if (GETFLAG(VM) && (CPU_IO_Exception(port,1))) { + LazyFlags old_lflags; + memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); + CPU_Decoder * old_cpudecoder; + old_cpudecoder=cpudecoder; + cpudecoder=&IOFaultCore; + IOF_Entry * entry=&iof_queue.entries[iof_queue.used++]; + entry->cs=SegValue(cs); + entry->eip=reg_eip; + CPU_Push16(SegValue(cs)); + CPU_Push16(reg_ip); + Bit16u old_dx = reg_dx; + reg_dx = port; + RealPt icb = CALLBACK_RealPointer(call_priv_io); + SegSet16(cs,RealSeg(icb)); + reg_eip = RealOff(icb)+0x00; + FillFlags(); + CPU_Exception(cpu.exception.which,cpu.exception.error); + + DOSBOX_RunMachine(); + iof_queue.used--; + + Bitu retval = reg_al; + + reg_dx = old_dx; + memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); + cpudecoder=old_cpudecoder; + return retval; + } + else return io_readhandlers[0][port](port,1); +}; + +Bitu IO_ReadW(Bitu port) { + if (GETFLAG(VM) && (CPU_IO_Exception(port,2))) { + LazyFlags old_lflags; + memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); + CPU_Decoder * old_cpudecoder; + old_cpudecoder=cpudecoder; + cpudecoder=&IOFaultCore; + IOF_Entry * entry=&iof_queue.entries[iof_queue.used++]; + entry->cs=SegValue(cs); + entry->eip=reg_eip; + CPU_Push16(SegValue(cs)); + CPU_Push16(reg_ip); + Bit16u old_dx = reg_dx; + reg_dx = port; + RealPt icb = CALLBACK_RealPointer(call_priv_io); + SegSet16(cs,RealSeg(icb)); + reg_eip = RealOff(icb)+0x02; + FillFlags(); + CPU_Exception(cpu.exception.which,cpu.exception.error); + + DOSBOX_RunMachine(); + iof_queue.used--; + + Bitu retval = reg_ax; + + reg_dx = old_dx; + memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); + cpudecoder=old_cpudecoder; + return retval; + } + else return io_readhandlers[1][port](port,2); +}; + +Bitu IO_ReadD(Bitu port) { + if (GETFLAG(VM) && (CPU_IO_Exception(port,4))) { + LazyFlags old_lflags; + memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); + CPU_Decoder * old_cpudecoder; + old_cpudecoder=cpudecoder; + cpudecoder=&IOFaultCore; + IOF_Entry * entry=&iof_queue.entries[iof_queue.used++]; + entry->cs=SegValue(cs); + entry->eip=reg_eip; + CPU_Push16(SegValue(cs)); + CPU_Push16(reg_ip); + Bit16u old_dx = reg_dx; + reg_dx = port; + RealPt icb = CALLBACK_RealPointer(call_priv_io); + SegSet16(cs,RealSeg(icb)); + reg_eip = RealOff(icb)+0x04; + FillFlags(); + CPU_Exception(cpu.exception.which,cpu.exception.error); + + DOSBOX_RunMachine(); + iof_queue.used--; + + Bitu retval = reg_eax; + + reg_dx = old_dx; + memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); + cpudecoder=old_cpudecoder; + return retval; + } + else return io_readhandlers[2][port](port,4); +}; + + void IO_Init(Section * sect) { + iof_queue.used=0; IO_FreeReadHandler(0,IO_MA,IO_MAX); IO_FreeWriteHandler(0,IO_MA,IO_MAX); } - - From 158562ba52eb79145730a9b4a54d6ed24815c5ef Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 11 Jan 2005 21:08:08 +0000 Subject: [PATCH 2011/4131] 2 patches: Backspace always clears cache (xulchris) and switch to private dta while findfirst/next (wd). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2095 --- src/shell/shell_misc.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 782b6722..2c3b99d4 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.33 2004-10-20 19:53:50 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.34 2005-01-11 21:08:08 qbix79 Exp $ */ #include #include @@ -171,7 +171,7 @@ void DOS_Shell::InputCommand(char * line) { // moves the cursor left while (str_remain--) outc(8); } - if (strlen(line) == 0 && l_completion.size()) l_completion.clear(); + if (l_completion.size()) l_completion.clear(); break; case 0x0a: /* New Line not handled */ /* Don't care */ @@ -213,8 +213,14 @@ void DOS_Shell::InputCommand(char * line) { strcpy(mask, "*.*"); } + RealPt save_dta=dos.dta(); + dos.dta(dos.tables.tempdta); + bool res = DOS_FindFirst(mask, 0xffff & ~DOS_ATTR_VOLUME); - if (!res) break; // TODO: beep + if (!res) { + dos.dta(save_dta); + break; // TODO: beep + } DOS_DTA dta(dos.dta()); char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr; @@ -239,6 +245,7 @@ void DOS_Shell::InputCommand(char * line) { /* Add excutable list to front of completion list. */ std::copy(executable.begin(),executable.end(),std::front_inserter(l_completion)); it_completion = l_completion.begin(); + dos.dta(save_dta); } if (l_completion.size() && it_completion->length()) { From 37084d608420f892e20ba07e30b3ff2587675614 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 12 Jan 2005 12:44:48 +0000 Subject: [PATCH 2012/4131] Allocate memory changes handle only on succes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2096 --- src/ints/ems.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 8389567a..3a3aa8ea 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.36 2004-10-23 15:15:06 qbix79 Exp $ */ +/* $Id: ems.cpp,v 1.37 2005-01-12 12:44:48 qbix79 Exp $ */ #include #include @@ -119,20 +119,22 @@ static bool INLINE ValidHandle(Bit16u handle) { return true; } -static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & handle) { +static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & dhandle) { /* Check for 0 page allocation */ if (!pages) return EMM_ZERO_PAGES; /* Check for enough free pages */ - if ((MEM_FreeTotal()/4)=EMM_MAX_HANDLES) {handle=NULL_HANDLE;return EMM_OUT_OF_HANDLES;} + while (emm_handles[handle].pages != NULL_HANDLE) { + if (++handle >= EMM_MAX_HANDLES) {return EMM_OUT_OF_HANDLES;} } - MemHandle mem=MEM_AllocatePages(pages*4,false); + MemHandle mem = MEM_AllocatePages(pages*4,false); if (!mem) E_Exit("EMS:Memory allocation failure"); - emm_handles[handle].pages=pages; - emm_handles[handle].mem=mem; + emm_handles[handle].pages = pages; + emm_handles[handle].mem = mem; + /* Change handle only if there is no error. */ + dhandle = handle; return EMM_NO_ERROR; } From e805d9c05fdeb7bb2e309c0584ae5e508e52b33d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 14 Jan 2005 19:38:19 +0000 Subject: [PATCH 2013/4131] Some "proper" int 24 in psp. Fixes Telarium games. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2097 --- src/shell/shell.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index b53a401c..5e51d9c8 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.53 2004-11-13 12:19:43 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.54 2005-01-14 19:38:19 qbix79 Exp $ */ #include #include @@ -371,11 +371,17 @@ void SHELL_Init() { PROGRAMS_MakeFile("COMMAND.COM",SHELL_ProgramStart); /* Now call up the shell for the first time */ - Bit16u psp_seg=DOS_GetMemory(16+1)+1; + Bit16u psp_seg=DOS_GetMemory(16+3)+1; Bit16u env_seg=DOS_GetMemory(1+(4096/16))+1; Bit16u stack_seg=DOS_GetMemory(2048/16); SegSet16(ss,stack_seg); reg_sp=2046; + + /* Set up int 24 and psp (Telarium games) */ + real_writeb(psp_seg+16+1,0,0xea); /* far jmp */ + real_writed(psp_seg+16+1,1,real_readd(0,0x24*4)); + real_writed(0,0x24*4,((Bit32u)psp_seg<<16) | ((16+1)<<4)); + /* Setup MCB and the environment */ DOS_MCB envmcb((Bit16u)(env_seg-1)); envmcb.SetPSPSeg(psp_seg); From 2e2f007ec2c7108f5eeefec3018ca06dd3905b4b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 18 Jan 2005 12:50:06 +0000 Subject: [PATCH 2014/4131] Huge exceptions addition by wd. Fixes a lot of the segment missing errors with dos4gw. Changed the defaults a bit (IGNORE by default and regular checking in debug mode) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2098 --- src/cpu/cpu.cpp | 905 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 689 insertions(+), 216 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 6deca608..bfbc46fa 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.62 2004-12-28 16:11:54 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.63 2005-01-18 12:50:06 qbix79 Exp $ */ #include #include "dosbox.h" @@ -51,14 +51,59 @@ void CPU_Core_Normal_Init(void); void CPU_Core_Simple_Init(void); void CPU_Core_Dyn_X86_Init(void); + +#define EXCEPTION_TS 10 +#define EXCEPTION_NP 11 +#define EXCEPTION_SS 12 +#define EXCEPTION_GP 13 + + +/* In debug mode exceptions are tested and dosbox exits when + * a unhandled exception state is detected. + * USE CHECK_EXCEPT to raise an exception in that case to see if that exception + * solves the problem. + * + * In non-debug mode dosbox doesn't do detection (and hence doesn't crash at + * that point). (game might crash later due to the unhandled exception) */ + +#if C_DEBUG +// #define CPU_CHECK_EXCEPT 1 +// #define CPU_CHECK_IGNORE 1 + /* Use CHECK_EXCEPT when something doesn't work to see if a exception is + * needed that isn't enabled by default.*/ +#else +/* NORMAL NO CHECKING => More Speed */ +#define CPU_CHECK_IGNORE 1 +#endif /* C_DEBUG */ + +#if defined(CPU_CHECK_IGNORE) +#define CPU_CHECK_COND(cond,msg,exc,sel) { \ + cond; \ +} +#elif defined(CPU_CHECK_EXCEPT) +#define CPU_CHECK_COND(cond,msg,exc,sel) { \ + if (cond) { + CPU_Exception(exc,sel); \ + return; \ + } \ +} +#else +#define CPU_CHECK_COND(cond,msg,exc,sel) { \ + if (cond) E_Exit(msg); \ +} +#endif + + void CPU_Push16(Bitu value) { - reg_esp=(reg_esp&~cpu.stack.mask)|((reg_esp-2)&cpu.stack.mask); - mem_writew(SegPhys(ss) + (reg_esp & cpu.stack.mask) ,value); + Bit32u new_esp=(reg_esp&~cpu.stack.mask)|((reg_esp-2)&cpu.stack.mask); + mem_writew(SegPhys(ss) + (new_esp & cpu.stack.mask) ,value); + reg_esp=new_esp; } void CPU_Push32(Bitu value) { - reg_esp=(reg_esp&~cpu.stack.mask)|((reg_esp-4)&cpu.stack.mask); - mem_writed(SegPhys(ss) + (reg_esp & cpu.stack.mask) ,value); + Bit32u new_esp=(reg_esp&~cpu.stack.mask)|((reg_esp-4)&cpu.stack.mask); + mem_writed(SegPhys(ss) + (new_esp & cpu.stack.mask) ,value); + reg_esp=new_esp; } Bitu CPU_Pop16(void) { @@ -96,7 +141,7 @@ bool CPU_PrepareException(Bitu which,Bitu error) { bool CPU_CLI(void) { if (cpu.pmode && ((!GETFLAG(VM) && (GETFLAG_IOPL0; @@ -321,7 +402,7 @@ bool CPU_IO_Exception(Bitu port,Bitu size) { return false; doexception: LOG(LOG_CPU,LOG_NORMAL)("IO Exception port %X",port); - return CPU_PrepareException(13,0); + return CPU_PrepareException(EXCEPTION_GP,0); } void CPU_Exception(Bitu which,Bitu error ) { @@ -340,7 +421,7 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { LOG(LOG_CPU,LOG_ERROR)("Call to interrupt 0xCD this is BAD"); DEBUG_HeavyWriteLogInstruction(); #endif - E_Exit("Call to interrupt 0xCD this is BAD"); + E_Exit("Call to interrupt 0xCD this is BAD"); case 0x03: if (DEBUG_Breakpoint()) { CPU_Cycles=0; @@ -349,7 +430,7 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { }; #endif if (!cpu.pmode) { - /* Save everything on a 16-bit stack */ + /* Save everything on a 16-bit stack */ CPU_Push16(reg_flags & 0xffff); CPU_Push16(SegValue(cs)); CPU_Push16(oldeip); @@ -364,23 +445,31 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { return; } else { /* Protected Mode Interrupt */ -// if (type&CPU_INT_SOFTWARE && cpu.v86) goto realmode_interrupt; -// DEBUG_EnableDebugger(); -// LOG_MSG("interrupt start CPL %d v86 %d",cpu.cpl,cpu.v86); if ((reg_flags & FLAG_VM) && (type&CPU_INT_SOFTWARE)) { // LOG_MSG("Software int in v86, AH %X IOPL %x",reg_ah,(reg_flags & FLAG_IOPL) >>12); if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) { - CPU_Exception(13,0); + CPU_Exception(EXCEPTION_GP,0); return; } } Descriptor gate; -//TODO Check for software interrupt and check gate's dplcpu.cpl) E_Exit("Interrupt to higher privilege"); + CPU_CHECK_COND(cs_dpl>cpu.cpl, + "Interrupt to higher privilege", + EXCEPTION_GP,(gate_sel & 0xfffc)+(type&CPU_INT_SOFTWARE)?0:1) switch (cs_desc.Type()) { case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: if (cs_dpl0", + EXCEPTION_GP,gate_sel & 0xfffc) + Bitu n_ss,n_esp; Bitu o_ss,o_esp; o_ss=SegValue(ss); o_esp=reg_esp; cpu_tss.Get_SSx_ESPx(cs_dpl,n_ss,n_esp); + CPU_CHECK_COND((n_ss & 0xfffc)==0, + "INT:Gate with SS zero selector", + EXCEPTION_TS,(type&CPU_INT_SOFTWARE)?0:1) Descriptor n_ss_desc; - cpu.gdt.GetDescriptor(n_ss,n_ss_desc); + CPU_CHECK_COND(!cpu.gdt.GetDescriptor(n_ss,n_ss_desc), + "INT:Gate with SS beyond limit", + EXCEPTION_TS,(n_ss & 0xfffc)+(type&CPU_INT_SOFTWARE)?0:1) + CPU_CHECK_COND(((n_ss & 3)!=cs_dpl) || (n_ss_desc.DPL()!=cs_dpl), + "INT:Inner level with CS_DPL!=SS_DPL and SS_RPL", + EXCEPTION_TS,(n_ss & 0xfffc)+(type&CPU_INT_SOFTWARE)?0:1) + + // check if stack segment is a writable data segment + switch (n_ss_desc.Type()) { + case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + break; + default: + E_Exit("INT:Inner level:Stack segment not writable."); // or #TS(ss_sel+EXT) + } + CPU_CHECK_COND(!n_ss_desc.saved.seg.p, + "INT:Inner level with nonpresent SS", + EXCEPTION_SS,(n_ss & 0xfffc)+(type&CPU_INT_SOFTWARE)?0:1) + + // commit point Segs.phys[ss]=n_ss_desc.GetBase(); Segs.val[ss]=n_ss; if (n_ss_desc.Big()) { @@ -412,8 +538,10 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { } else { cpu.stack.big=false; cpu.stack.mask=0xffff; - reg_sp=n_esp; + reg_sp=n_esp & 0xffff; } + + cpu.cpl=cs_dpl; if (gate.Type() & 0x8) { /* 32-bit Gate */ if (reg_flags & FLAG_VM) { CPU_Push32(SegValue(gs));SegSet16(gs,0x0); @@ -429,15 +557,20 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { CPU_Push16(o_esp); } // LOG_MSG("INT:Gate to inner level SS:%X SP:%X",n_ss,n_esp); - cpu.cpl=cs_dpl; goto do_interrupt; } + if (cs_dpl!=cpu.cpl) + E_Exit("Non-conforming intra privilege INT with DPL!=CPL"); case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: - /* Prepare stack for gate to same priviledge */ - if (reg_flags & FLAG_VM) - E_Exit("V86 interrupt doesn't change to pl0"); + /* Prepare stack for gate to same priviledge */ + CPU_CHECK_COND(!cs_desc.saved.seg.p, + "INT:Same level:CS segment not present", + EXCEPTION_NP,(gate_sel & 0xfffc)+(type&CPU_INT_SOFTWARE)?0:1) + if ((reg_flags & FLAG_VM) && (cs_dpl0; + reg_eip=gate_off; + if (!(gate.Type()&1)) SETFLAGBIT(IF,false); SETFLAGBIT(TF,false); SETFLAGBIT(NT,false); SETFLAGBIT(VM,false); - Segs.val[cs]=(gate_sel&0xfffc) | cpu.cpl; - Segs.phys[cs]=cs_desc.GetBase(); - cpu.code.big=cs_desc.Big()>0; LOG(LOG_CPU,LOG_NORMAL)("INT:Gate to %X:%X big %d %s",gate_sel,gate_off,cs_desc.Big(),gate.Type() & 0x8 ? "386" : "286"); - reg_eip=gate_off; return; } case DESC_TASK_GATE: @@ -482,6 +617,7 @@ do_interrupt: return ; // make compiler happy } + void CPU_IRET(bool use32,Bitu oldeip) { if (!cpu.pmode) { /* RealMode IRET */ realmode_iret: @@ -499,102 +635,110 @@ realmode_iret: } else { /* Protected mode IRET */ if (reg_flags & FLAG_VM) { if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) { - CPU_Exception(13,0); + // win3.x e + CPU_Exception(EXCEPTION_GP,0); return; } else goto realmode_iret; } -// DEBUG_EnableDebugger(); -// LOG_MSG("IRET start CPL %d v86 %d",cpu.cpl,cpu.v86); /* Check if this is task IRET */ if (GETFLAG(NT)) { if (GETFLAG(VM)) E_Exit("Pmode IRET with VM bit set"); - if (!cpu_tss.IsValid()) E_Exit("TASK Iret without valid TSS"); + CPU_CHECK_COND(!cpu_tss.IsValid(), + "TASK Iret without valid TSS", + EXCEPTION_TS,cpu_tss.selector & 0xfffc) + // check if busy is set + switch (cpu_tss.desc.Type()) { + case DESC_286_TSS_B: case DESC_386_TSS_B: + break; + default: + E_Exit("TASK Iret:TSS not busy"); // or #TS(sel) + } Bitu back_link=cpu_tss.Get_back(); CPU_SwitchTask(back_link,TSwitch_IRET,oldeip); return; } Bitu n_cs_sel,n_eip,n_flags; if (use32) { + // commit point n_eip=CPU_Pop32(); n_cs_sel=CPU_Pop32() & 0xffff; n_flags=CPU_Pop32(); - if (n_flags & FLAG_VM) { - cpu.cpl=3; - CPU_SetFlags(n_flags,FMASK_ALL | FLAG_VM); + if ((n_flags & FLAG_VM) && (cpu.cpl==0)) { + reg_eip=n_eip & 0xffff; Bitu n_ss,n_esp,n_es,n_ds,n_fs,n_gs; n_esp=CPU_Pop32(); n_ss=CPU_Pop32() & 0xffff; - n_es=CPU_Pop32() & 0xffff; n_ds=CPU_Pop32() & 0xffff; n_fs=CPU_Pop32() & 0xffff; n_gs=CPU_Pop32() & 0xffff; + + CPU_SetFlags(n_flags,FMASK_ALL | FLAG_VM); + cpu.cpl=3; + CPU_SetSegGeneral(ss,n_ss); CPU_SetSegGeneral(es,n_es); CPU_SetSegGeneral(ds,n_ds); CPU_SetSegGeneral(fs,n_fs); CPU_SetSegGeneral(gs,n_gs); - reg_eip=n_eip & 0xffff; reg_esp=n_esp; cpu.code.big=false; SegSet16(cs,n_cs_sel); LOG(LOG_CPU,LOG_NORMAL)("IRET:Back to V86: CS:%X IP %X SS:%X SP %X FLAGS:%X",SegValue(cs),reg_eip,SegValue(ss),reg_esp,reg_flags); return; } + if (n_flags & FLAG_VM) E_Exit("IRET from pmode to v86 with CPL!=0"); } else { n_eip=CPU_Pop16(); n_cs_sel=CPU_Pop16(); n_flags=(reg_flags & 0xffff0000) | CPU_Pop16(); if (n_flags & FLAG_VM) E_Exit("VM Flag in 16-bit iret"); } + CPU_CHECK_COND((n_cs_sel & 0xfffc)==0, + "IRET:CS selector zero", + EXCEPTION_GP,0) Bitu n_cs_rpl=n_cs_sel & 3; Descriptor n_cs_desc; - cpu.gdt.GetDescriptor(n_cs_sel,n_cs_desc); - if (n_cs_rpln_cs_rpl, + "IRET:C:DPL>RPL", + EXCEPTION_GP,n_cs_sel & 0xfffc) + break; + default: + E_Exit("IRET:Illegal descriptor type %X",n_cs_desc.Type()); + } + CPU_CHECK_COND(!n_cs_desc.saved.seg.p, + "IRET with nonpresent code segment", + EXCEPTION_NP,n_cs_sel & 0xfffc) + if (n_cs_rpl==cpu.cpl) { /* Return to same level */ - switch (n_cs_desc.Type()) { - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: - case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (!(cpu.cpl==n_cs_desc.DPL())) E_Exit("IRET:Same Level:NC:DPL!=CPL"); - break; - case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: - case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: - if (!(n_cs_desc.DPL()>=cpu.cpl)) E_Exit("IRET:Same level:C:DPL0; Segs.val[cs]=n_cs_sel; reg_eip=n_eip; - CPU_SetFlagsd(n_flags); + Bitu mask=cpu.cpl ? (FMASK_NORMAL | FLAG_NT) : FMASK_ALL; + if (GETFLAG_IOPL0; - Segs.val[cs]=n_cs_sel; - - CPU_SetFlagsd(n_flags); - - cpu.cpl=n_cs_rpl; - reg_eip=n_eip; Bitu n_ss,n_esp; if (use32) { n_esp=CPU_Pop32(); @@ -603,20 +747,93 @@ realmode_iret: n_esp=CPU_Pop16(); n_ss=CPU_Pop16(); } - CPU_SetSegGeneral(ss,n_ss); - if (cpu.stack.big) { + CPU_CHECK_COND((n_ss & 0xfffc)==0, + "IRET:Outer level:SS selector zero", + EXCEPTION_GP,0) + CPU_CHECK_COND((n_ss & 3)!=n_cs_rpl, + "IRET:Outer level:SS rpl!=CS rpl", + EXCEPTION_GP,n_ss & 0xfffc) + Descriptor n_ss_desc; + CPU_CHECK_COND(!cpu.gdt.GetDescriptor(n_ss,n_ss_desc), + "IRET:Outer level:SS beyond limit", + EXCEPTION_GP,n_ss & 0xfffc) + CPU_CHECK_COND(n_ss_desc.DPL()!=n_cs_rpl, + "IRET:Outer level:SS dpl!=CS rpl", + EXCEPTION_GP,n_ss & 0xfffc) + + // check if stack segment is a writable data segment + switch (n_ss_desc.Type()) { + case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + break; + default: + E_Exit("IRET:Outer level:Stack segment not writable"); // or #GP(ss_sel) + } + CPU_CHECK_COND(!n_ss_desc.saved.seg.p, + "IRET:Outer level:Stack segment not present", + EXCEPTION_NP,n_ss & 0xfffc) + + Segs.phys[cs]=n_cs_desc.GetBase(); + cpu.code.big=n_cs_desc.Big()>0; + Segs.val[cs]=n_cs_sel; + + Bitu mask=cpu.cpl ? (FMASK_NORMAL | FLAG_NT) : FMASK_ALL; + if (GETFLAG_IOPLdesc.DPL()) CPU_SetSegGeneral(es,0); break; + default: break; } + cpu.gdt.GetDescriptor(SegValue(ds),desc); + switch (desc.Type()) { + case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(ds,0); break; + default: break; } + cpu.gdt.GetDescriptor(SegValue(fs),desc); + switch (desc.Type()) { + case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(fs,0); break; + default: break; } + cpu.gdt.GetDescriptor(SegValue(gs),desc); + switch (desc.Type()) { + case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(gs,0); break; + default: break; } + LOG(LOG_CPU,LOG_NORMAL)("IRET:Outer level:%X:%X big %d",n_cs_sel,n_eip,cpu.code.big); } return; } } + void CPU_JMP(bool use32,Bitu selector,Bitu offset,Bitu oldeip) { if (!cpu.pmode || (reg_flags & FLAG_VM)) { if (!use32) { @@ -628,24 +845,38 @@ void CPU_JMP(bool use32,Bitu selector,Bitu offset,Bitu oldeip) { cpu.code.big=false; return; } else { + CPU_CHECK_COND((selector & 0xfffc)==0, + "JMP:CS selector zero", + EXCEPTION_GP,0) Bitu rpl=selector & 3; Descriptor desc; - cpu.gdt.GetDescriptor(selector,desc); - if (!desc.saved.seg.p) { - CPU_Exception(0x0B,selector & 0xfffc); - return; - } + CPU_CHECK_COND(!cpu.gdt.GetDescriptor(selector,desc), + "JMP:CS beyond limits", + EXCEPTION_GP,selector & 0xfffc) switch (desc.Type()) { case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (rpl>cpu.cpl) E_Exit("JMP:NC:RPL>CPL"); - if (cpu.cpl!=desc.DPL()) E_Exit("JMP:NC:RPL != DPL"); + CPU_CHECK_COND(rpl>cpu.cpl, + "JMP:NC:RPL>CPL", + EXCEPTION_GP,selector & 0xfffc) + CPU_CHECK_COND(cpu.cpl!=desc.DPL(), + "JMP:NC:RPL != DPL", + EXCEPTION_GP,selector & 0xfffc) LOG(LOG_CPU,LOG_NORMAL)("JMP:Code:NC to %X:%X big %d",selector,offset,desc.Big()); goto CODE_jmp; case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: LOG(LOG_CPU,LOG_NORMAL)("JMP:Code:C to %X:%X big %d",selector,offset,desc.Big()); + CPU_CHECK_COND(cpu.cpl0; @@ -653,8 +884,12 @@ CODE_jmp: reg_eip=offset; return; case DESC_386_TSS_A: - if (desc.DPL()cpu.cpl) E_Exit("CALL:CODE:NC:RPL>CPL"); - if (call.DPL()!=cpu.cpl) E_Exit("CALL:CODE:NC:DPL!=CPL"); + CPU_CHECK_COND(rpl>cpu.cpl, + "CALL:CODE:NC:RPL>CPL", + EXCEPTION_GP,selector & 0xfffc) + CPU_CHECK_COND(call.DPL()!=cpu.cpl, + "CALL:CODE:NC:DPL!=CPL", + EXCEPTION_GP,selector & 0xfffc) LOG(LOG_CPU,LOG_NORMAL)("CALL:CODE:NC to %X:%X",selector,offset); goto call_code; case DESC_CODE_N_C_A:case DESC_CODE_N_C_NA: case DESC_CODE_R_C_A:case DESC_CODE_R_C_NA: - if (call.DPL()>cpu.cpl) E_Exit("CALL:CODE:C:DPL>CPL"); + CPU_CHECK_COND(call.DPL()>cpu.cpl, + "CALL:CODE:C:DPL>CPL", + EXCEPTION_GP,selector & 0xfffc) LOG(LOG_CPU,LOG_NORMAL)("CALL:CODE:C to %X:%X",selector,offset); call_code: + if (!call.saved.seg.p) { + // borland extender (RTM) + CPU_Exception(EXCEPTION_NP,selector & 0xfffc); + return; + } + // commit point if (!use32) { CPU_Push16(SegValue(cs)); CPU_Push16(oldeip); @@ -718,45 +965,109 @@ call_code: case DESC_386_CALL_GATE: case DESC_286_CALL_GATE: { - if (call.DPL()cpu.cpl, + "CALL:Gate:CS DPL>CPL", + EXCEPTION_GP,n_cs_sel & 0xfffc) Bitu n_cs_rpl = n_cs_sel & 3; Bitu n_eip = call.GetOffset(); switch (n_cs_desc.Type()) { case DESC_CODE_N_NC_A:case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A:case DESC_CODE_R_NC_NA: - /* Check if we goto innter priviledge */ + /* Check if we goto inner priviledge */ if (n_cs_dpl < cpu.cpl) { + CPU_CHECK_COND(!n_cs_desc.saved.seg.p, + "CALL:Gate:CS not present", + EXCEPTION_NP,n_cs_sel & 0xfffc) /* Get new SS:ESP out of TSS */ Bitu n_ss_sel,n_esp; Descriptor n_ss_desc; cpu_tss.Get_SSx_ESPx(n_cs_dpl,n_ss_sel,n_esp); - if (!cpu.gdt.GetDescriptor(n_ss_sel,n_ss_desc)) E_Exit("Call:Gate:Invalid SS selector."); - /* New CPL is new SS DPL */ - cpu.cpl = n_ss_desc.DPL(); + CPU_CHECK_COND((n_ss_sel & 0xfffc)==0, + "CALL:Gate:NC:SS selector zero", + EXCEPTION_TS,0) + CPU_CHECK_COND(!cpu.gdt.GetDescriptor(n_ss_sel,n_ss_desc), + "CALL:Gate:Invalid SS selector", + EXCEPTION_TS,n_ss_sel & 0xfffc) + CPU_CHECK_COND(((n_ss_sel & 3)!=n_cs_desc.DPL()) || (n_ss_desc.DPL()!=n_cs_desc.DPL()), + "CALL:Gate:Invalid SS selector privileges", + EXCEPTION_TS,n_ss_sel & 0xfffc) + + switch (n_ss_desc.Type()) { + case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + // writable data segment + break; + default: + E_Exit("Call:Gate:SS no writable data segment"); // or #TS(ss_sel) + } + CPU_CHECK_COND(!n_ss_desc.saved.seg.p, + "CALL:Gate:Stack segment not present", + EXCEPTION_SS,n_ss_sel & 0xfffc) + /* Load the new SS:ESP and save data on it */ Bitu o_esp = reg_esp; Bitu o_ss = SegValue(ss); PhysPt o_stack = SegPhys(ss)+(reg_esp & cpu.stack.mask); - - CPU_SetSegGeneral(ss,n_ss_sel); - if (cpu.stack.big) reg_esp=n_esp; - else reg_sp=n_esp; + + // catch pagefaults + if (call.saved.gate.paramcount&31) { + if (call.Type()==DESC_386_CALL_GATE) { + for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--) + mem_readd(o_stack+i*4); + } else { + for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--) + mem_readw(o_stack+i*2); + } + } + + // commit point + Segs.val[ss]=n_ss_sel; + Segs.phys[ss]=n_ss_desc.GetBase(); + if (n_ss_desc.Big()) { + cpu.stack.big=true; + cpu.stack.mask=0xffffffff; + reg_esp=n_esp; + } else { + cpu.stack.big=false; + cpu.stack.mask=0xffff; + reg_sp=n_esp & 0xffff; + } + + cpu.cpl = n_cs_desc.DPL(); + Bit16u oldcs = SegValue(cs); + /* Switch to new CS:EIP */ + Segs.phys[cs] = n_cs_desc.GetBase(); + Segs.val[cs] = (n_cs_sel & 0xfffc) | cpu.cpl; + cpu.code.big = n_cs_desc.Big()>0; + reg_eip = n_eip; + if (!use32) reg_eip&=0xffff; + if (call.Type()==DESC_386_CALL_GATE) { CPU_Push32(o_ss); //save old stack CPU_Push32(o_esp); if (call.saved.gate.paramcount&31) for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--) CPU_Push32(mem_readd(o_stack+i*4)); - CPU_Push32(SegValue(cs)); + CPU_Push32(oldcs); CPU_Push32(oldeip); } else { CPU_Push16(o_ss); //save old stack @@ -764,30 +1075,44 @@ call_code: if (call.saved.gate.paramcount&31) for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--) CPU_Push16(mem_readw(o_stack+i*2)); - CPU_Push16(SegValue(cs)); + CPU_Push16(oldcs); CPU_Push16(oldeip); } - cpu.cpl = n_cs_desc.DPL(); - /* Switch to new CS:EIP */ - Segs.phys[cs] = n_cs_desc.GetBase(); - Segs.val[cs] = (n_cs_sel & 0xfffc) | cpu.cpl; - cpu.code.big = n_cs_desc.Big()>0; - reg_eip = n_eip; - if (!use32) reg_eip&=0xffff; break; - } + } else if (n_cs_dpl > cpu.cpl) + E_Exit("CALL:GATE:CS DPL>CPL"); // or #GP(sel) case DESC_CODE_N_C_A:case DESC_CODE_N_C_NA: case DESC_CODE_R_C_A:case DESC_CODE_R_C_NA: -call_gate_same_privilege: - E_Exit("Call gate to same priviledge"); + // zrdx extender + + if (call.Type()==DESC_386_CALL_GATE) { + CPU_Push32(SegValue(cs)); + CPU_Push32(oldeip); + } else { + CPU_Push16(SegValue(cs)); + CPU_Push16(oldeip); + } + + /* Switch to new CS:EIP */ + Segs.phys[cs] = n_cs_desc.GetBase(); + Segs.val[cs] = (n_cs_sel & 0xfffc) | cpu.cpl; + cpu.code.big = n_cs_desc.Big()>0; + reg_eip = n_eip; + if (!use32) reg_eip&=0xffff; break; + default: + E_Exit("CALL:GATE:CS no executable segment"); } } /* Call Gates */ break; case DESC_386_TSS_A: - if (call.DPL()=cpu.cpl)) E_Exit("RET to C segment of higher privilege"); + CPU_CHECK_COND(desc.DPL()>cpu.cpl, + "RET to C segment of higher privilege", + EXCEPTION_GP,selector & 0xfffc) break; default: E_Exit("RET from illegal descriptor type %X",desc.Type()); } RET_same_level: + if (!desc.saved.seg.p) { + // borland extender (RTM) + CPU_Exception(EXCEPTION_NP,selector & 0xfffc); + return; + } + + // commit point + if (!use32) { + offset=CPU_Pop16(); + selector=CPU_Pop16(); + } else { + offset=CPU_Pop32(); + selector=CPU_Pop32() & 0xffff; + } Segs.phys[cs]=desc.GetBase(); cpu.code.big=desc.Big()>0; @@ -870,28 +1206,112 @@ RET_same_level: } else { /* Return to outer level */ if (bytes) E_Exit("RETF outer level with immediate value"); + switch (desc.Type()) { + case DESC_CODE_N_NC_A:case DESC_CODE_N_NC_NA: + case DESC_CODE_R_NC_A:case DESC_CODE_R_NC_NA: + CPU_CHECK_COND(desc.DPL()!=rpl, + "RET to outer NC segment with DPL!=RPL", + EXCEPTION_GP,selector & 0xfffc) + break; + case DESC_CODE_N_C_A:case DESC_CODE_N_C_NA: + case DESC_CODE_R_C_A:case DESC_CODE_R_C_NA: + CPU_CHECK_COND(desc.DPL()>rpl, + "RET to outer C segment with DPL>RPL", + EXCEPTION_GP,selector & 0xfffc) + break; + default: + E_Exit("RET from illegal descriptor type %X",desc.Type()); // or #GP(selector) + } + + CPU_CHECK_COND(!desc.saved.seg.p, + "RET:Outer level:CS not present", + EXCEPTION_NP,selector & 0xfffc) + + // commit point Bitu n_esp,n_ss; if (use32) { + offset=CPU_Pop32(); + selector=CPU_Pop32() & 0xffff; n_esp = CPU_Pop32(); n_ss = CPU_Pop32() & 0xffff; } else { + offset=CPU_Pop16(); + selector=CPU_Pop16(); n_esp = CPU_Pop16(); n_ss = CPU_Pop16(); } - cpu.cpl = rpl; - CPU_SetSegGeneral(ss,n_ss); - if (cpu.stack.big) { - reg_esp = n_esp; - } else { - reg_sp = n_esp; + CPU_CHECK_COND((n_ss & 0xfffc)==0, + "RET to outer level with SS selector zero", + EXCEPTION_GP,0) + + Descriptor n_ss_desc; + CPU_CHECK_COND(!cpu.gdt.GetDescriptor(n_ss,n_ss_desc), + "RET:SS beyond limits", + EXCEPTION_GP,n_ss & 0xfffc) + + CPU_CHECK_COND(((n_ss & 3)!=rpl) || (n_ss_desc.DPL()!=rpl), + "RET to outer segment with invalid SS privileges", + EXCEPTION_GP,n_ss & 0xfffc) + switch (n_ss_desc.Type()) { + case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + break; + default: + E_Exit("RET:SS selector type no writable data segment"); // or #GP(selector) } + CPU_CHECK_COND(!n_ss_desc.saved.seg.p, + "RET:Stack segment not present", + EXCEPTION_SS,n_ss & 0xfffc) + cpu.cpl = rpl; Segs.phys[cs]=desc.GetBase(); cpu.code.big=desc.Big()>0; Segs.val[cs]=(selector&0xfffc) | cpu.cpl; reg_eip=offset; + Segs.val[ss]=n_ss; + Segs.phys[ss]=n_ss_desc.GetBase(); + if (n_ss_desc.Big()) { + cpu.stack.big=true; + cpu.stack.mask=0xffffffff; + reg_esp=n_esp; + } else { + cpu.stack.big=false; + cpu.stack.mask=0xffff; + reg_sp=n_esp & 0xffff; + } + + Descriptor desc; + cpu.gdt.GetDescriptor(SegValue(es),desc); + switch (desc.Type()) { + case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(es,0); break; + default: break; } + cpu.gdt.GetDescriptor(SegValue(ds),desc); + switch (desc.Type()) { + case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(ds,0); break; + default: break; } + cpu.gdt.GetDescriptor(SegValue(fs),desc); + switch (desc.Type()) { + case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(fs,0); break; + default: break; } + cpu.gdt.GetDescriptor(SegValue(gs),desc); + switch (desc.Type()) { + case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(gs,0); break; + default: break; } + // LOG(LOG_MISC,LOG_ERROR)("RET - Higher level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL()); return; } @@ -917,6 +1337,7 @@ void CPU_STR(Bitu & selector) { void CPU_LTR(Bitu selector) { cpu_tss.SetSelector(selector); + cpu_tss.desc.SetBusy(true); } Bitu gdt_count=0; @@ -1176,24 +1597,38 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) { } return false; } else { - Descriptor desc; - cpu.gdt.GetDescriptor(value,desc); - - if (value!=0) { - if (!desc.saved.seg.p) { - if (seg==ss) E_Exit("CPU_SetSegGeneral: Stack segment not present."); - // Throw Exception 0x0B - Segment not present - return CPU_PrepareException(0x0B,value & 0xfffc); - } else if (seg==ss) { - // Stack segment loaded with illegal segment ? - if ((desc.saved.seg.typeDESC_DATA_ED_RW_A)) { - return CPU_PrepareException(0x0D,value & 0xfffc); - } - } - } - Segs.val[seg]=value; - Segs.phys[seg]=desc.GetBase(); if (seg==ss) { + // Stack needs to be non-zero + if ((value & 0xfffc)==0) { + E_Exit("CPU_SetSegGeneral: Stack segment zero"); +// return CPU_PrepareException(EXCEPTION_GP,0); + } + Descriptor desc; + if (!cpu.gdt.GetDescriptor(value,desc)) { + E_Exit("CPU_SetSegGeneral: Stack segment beyond limits"); +// return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); + } + if (((value & 3)!=cpu.cpl) || (desc.DPL()!=cpu.cpl)) { + E_Exit("CPU_SetSegGeneral: Stack segment with invalid privileges"); +// return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); + } + + switch (desc.Type()) { + case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + break; + default: + E_Exit("CPU_SetSegGeneral: Stack segment not writable"); +// return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); + } + + if (!desc.saved.seg.p) { + E_Exit("CPU_SetSegGeneral: Stack segment not present"); // or #SS(sel) +// return CPU_PrepareException(EXCEPTION_SS,value & 0xfffc); + } + + Segs.val[seg]=value; + Segs.phys[seg]=desc.GetBase(); if (desc.Big()) { cpu.stack.big=true; cpu.stack.mask=0xffffffff; @@ -1201,7 +1636,44 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) { cpu.stack.big=false; cpu.stack.mask=0xffff; } + } else { + if ((value & 0xfffc)==0) { + Segs.val[seg]=value; + Segs.phys[seg]=0; // ?? + return false; + } + Descriptor desc; + if (!cpu.gdt.GetDescriptor(value,desc)) { + E_Exit("CPU_SetSegGeneral: Segment beyond limits"); +// return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); + } + switch (desc.Type()) { + case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: + case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: + case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (((value & 3)>desc.DPL()) || (cpu.cpl>desc.DPL())) { + E_Exit("CPU_SetSegGeneral: Invalid privileges"); +// return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); + } + break; + case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: + break; + default: + // gabriel knight + return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); + + } + if (!desc.saved.seg.p) { + // win + return CPU_PrepareException(EXCEPTION_NP,value & 0xfffc); + } + + Segs.val[seg]=value; + Segs.phys[seg]=desc.GetBase(); } + return false; } } @@ -1209,7 +1681,7 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) { bool CPU_PopSeg(SegNames seg,bool use32) { Bitu val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); if (CPU_SetSegGeneral(seg,val)) return true; - Bitu addsp=2 << use32; + Bitu addsp=use32?0x04:0x02; reg_esp=(reg_esp&~cpu.stack.mask)|((reg_esp+addsp)&cpu.stack.mask); return false; } @@ -1217,16 +1689,17 @@ bool CPU_PopSeg(SegNames seg,bool use32) { void CPU_CPUID(void) { switch (reg_eax) { case 0: /* Vendor ID String and maximum level? */ - reg_eax=0; - reg_ebx=('G'<< 24) || ('e' << 16) || ('n' << 8) || 'u'; - reg_edx=('i'<< 24) || ('n' << 16) || ('e' << 8) || 'T'; - reg_ecx=('n'<< 24) || ('t' << 16) || ('e' << 8) || 'l'; + reg_eax=1; + reg_eax=1; /* Maximum level */ + reg_ebx='G' | ('e' << 8) | ('n' << 16) | ('u'<< 24); + reg_edx='i' | ('n' << 8) | ('e' << 16) | ('I'<< 24); + reg_ecx='n' | ('t' << 8) | ('e' << 16) | ('l'<< 24); break; case 1: /* get processor type/family/model/stepping and feature flags */ reg_eax=0x402; /* intel 486 sx? */ reg_ebx=0; /* Not Supported */ reg_ecx=0; /* No features */ - reg_edx=0; /* Nothing either */ + reg_edx=1; /* FPU */ break; default: LOG(LOG_CPU,LOG_ERROR)("Unhandled CPUID Function %x",reg_eax); @@ -1246,7 +1719,7 @@ static Bits HLT_Decode(void) { void CPU_HLT(Bitu oldeip) { if (cpu.cpl) { - CPU_Exception(13,0); + CPU_Exception(EXCEPTION_GP,0); return; } reg_eip=oldeip; From 625b1dab40566897e56fceb2a9b19aa4edf2b345 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 20 Jan 2005 20:35:29 +0000 Subject: [PATCH 2015/4131] Added midi device selection code for windows Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2099 --- README | 8 +++++++- src/dosbox.cpp | 5 +++-- src/gui/midi_win32.h | 21 ++++++++++++++++++++- src/hardware/mixer.cpp | 42 ++++++++++++++++++++++++++++++++++++------ 4 files changed, 66 insertions(+), 10 deletions(-) diff --git a/README b/README index e134421e..666ae326 100644 --- a/README +++ b/README @@ -409,7 +409,13 @@ MIXER /NOSHOW Prevents DOSBox from showing the result if you set one of the volume levels. - + + /LISTMIDI + Lists the available midi devices on your pc (Windows). To select a + device other than the Windows default midi-mapper, add a line + 'config=id' to the [midi] section in the configuration file, where + 'id' is the number for the device as listed by LISTMIDI. + IMGMOUNT A utility to mount disk images and CD-ROM images in DOSBox. diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 98294652..73180920 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.81 2004-12-07 21:49:06 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.82 2005-01-20 20:35:28 qbix79 Exp $ */ #include #include @@ -289,7 +289,8 @@ void DOSBOX_Init(void) { "intelligent -- Operate in Intelligent mode.\n" "device -- Device that will receive the MIDI data from MPU-401.\n" " This can be default,alsa,oss,win32,coreaudio,none.\n" - "config -- Special configuration options for the device.\n" + "config -- Special configuration options for the device. In Windows put\n" + " the id of the device you want to use. See README for details.\n" ); #if C_DEBUG diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index 514f498b..c4979219 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -16,11 +16,15 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: midi_win32.h,v 1.10 2005-01-20 20:35:29 qbix79 Exp $ */ + #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include #include +#include +#include class MidiHandler_win32: public MidiHandler { private: @@ -34,11 +38,26 @@ public: bool Open(const char * conf) { if (isOpen) return false; m_event = CreateEvent (NULL, true, true, NULL); - MMRESULT res = midiOutOpen(&m_out, MIDI_MAPPER, (DWORD)m_event, 0, CALLBACK_EVENT); + MMRESULT res; + if(conf && *conf) { + std::string strconf(conf); + std::istringstream configmidi(strconf); + unsigned int nummer = midiOutGetNumDevs(); + configmidi >> nummer; + if(nummer < midiOutGetNumDevs()){ + MIDIOUTCAPS mididev; + midiOutGetDevCaps(nummer, &mididev, sizeof(MIDIOUTCAPS)); + LOG_MSG("MIDI:win32 selected %s",mididev.szPname); + res = midiOutOpen(&m_out, nummer, (DWORD)m_event, 0, CALLBACK_EVENT); + } + } else { + res = midiOutOpen(&m_out, MIDI_MAPPER, (DWORD)m_event, 0, CALLBACK_EVENT); + } if (res != MMSYSERR_NOERROR) return false; isOpen=true; return true; }; + void Close(void) { if (!isOpen) return; isOpen=false; diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index ae763f73..fa0ff21a 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: mixer.cpp,v 1.28 2005-01-20 20:35:28 qbix79 Exp $ */ + /* Remove the sdl code from here and have it handeld in the sdlmain. That should call the mixer start from there or something. @@ -26,6 +28,15 @@ #include #include +#if defined (WIN32) +//Midi listing +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include +#endif + #include "SDL.h" #include "mem.h" #include "pic.h" @@ -399,13 +410,12 @@ public: } if (!w) vol1=vol0; } - void ShowVolume(char * name,float vol0,float vol1) { - WriteOut("%-8s %3.0f:%-3.0f %+3.2f:%-+3.2f \n",name, - vol0*100,vol1*100, - 20*log(vol0)/log(10.0f),20*log(vol1)/log(10.0f) - ); - } + void Run(void) { + if(cmd->FindExist("/LISTMIDI")) { + ListMidi(); + return; + } if (cmd->FindString("MASTER",temp_line,false)) { MakeVolume((char *)temp_line.c_str(),mixer.mastervol[0],mixer.mastervol[1]); } @@ -424,6 +434,26 @@ public: for (chan=mixer.channels;chan;chan=chan->next) ShowVolume(chan->name,chan->volmain[0],chan->volmain[1]); } +private: + void ShowVolume(char * name,float vol0,float vol1) { + WriteOut("%-8s %3.0f:%-3.0f %+3.2f:%-+3.2f \n",name, + vol0*100,vol1*100, + 20*log(vol0)/log(10.0f),20*log(vol1)/log(10.0f) + ); + } + + void ListMidi(){ +#if defined (WIN32) + unsigned int total = midiOutGetNumDevs(); + for(unsigned int i=0;i Date: Sat, 22 Jan 2005 22:43:30 +0000 Subject: [PATCH 2016/4131] Added exception for win3.x installer(wd/mirek) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2100 --- src/cpu/cpu.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index bfbc46fa..3f779cac 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.63 2005-01-18 12:50:06 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.64 2005-01-22 22:43:30 qbix79 Exp $ */ #include #include "dosbox.h" @@ -1147,9 +1147,11 @@ void CPU_RET(bool use32,Bitu bytes,Bitu oldeip) { Descriptor desc; Bitu rpl=selector & 3; - CPU_CHECK_COND(rpl Date: Mon, 24 Jan 2005 23:11:19 +0000 Subject: [PATCH 2017/4131] Added exception for earth siege 1 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2101 --- src/cpu/cpu.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 3f779cac..ebb44e6c 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.64 2005-01-22 22:43:30 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.65 2005-01-24 23:11:19 qbix79 Exp $ */ #include #include "dosbox.h" @@ -1620,8 +1620,8 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) { case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: break; default: - E_Exit("CPU_SetSegGeneral: Stack segment not writable"); -// return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); + //Earth Siege 1 + return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); } if (!desc.saved.seg.p) { From bdd7b715d0486e54ee22618e062827d6117850c9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 31 Jan 2005 20:12:59 +0000 Subject: [PATCH 2018/4131] Crappy games fix (int 2 revectoring as would stacks!=0,0) wd Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2102 --- src/dos/dos_memory.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index d292db69..1a099b6a 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -187,10 +187,14 @@ bool DOS_FreeMemory(Bit16u segment) { void DOS_SetupMemory(void) { // Create a dummy device MCB with PSPSeg=0x0008 DOS_MCB mcb_devicedummy((Bit16u)MEM_START); - mcb_devicedummy.SetPSPSeg(0x0008); // Devices + mcb_devicedummy.SetPSPSeg(0x0008); // Devices mcb_devicedummy.SetSize(1); - mcb_devicedummy.SetType(0x4d); // More blocks will follow - + mcb_devicedummy.SetType(0x4d); // More blocks will follow + + // BioMenace (segment of int2<0x8000) + mem_writeb((MEM_START+1)<<4,0xcf);// iret + RealSetVec(0x02,(MEM_START+1)<<16); + DOS_MCB mcb((Bit16u)MEM_START+2); mcb.SetPSPSeg(MCB_FREE); //Free if (machine==MCH_TANDY) { From 7711206341133c62c45a79d68e4346ede4ddd56b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 3 Feb 2005 10:17:44 +0000 Subject: [PATCH 2019/4131] Slightly simpeler version of erasing a string. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2103 --- src/misc/messages.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 10be4118..4bcc59b8 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: messages.cpp,v 1.16 2005-02-03 10:17:44 qbix79 Exp $ */ + #include #include #include @@ -56,9 +58,7 @@ void MSG_Replace(const char * _name, const char* _val) { /* Find the message */ for(itmb tel=Lang.begin();tel!=Lang.end();tel++) { if((*tel).name==_name) { - itmb teln=tel; - teln++; - Lang.erase(tel,teln); + Lang.erase(tel); break; } } From 3105209dada7173d7ab91881d346aec8677ecdb9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 3 Feb 2005 10:34:37 +0000 Subject: [PATCH 2020/4131] Only do things with the channel if it actually is present. Fixes some crashes with pcspeaker disabled Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2104 --- src/hardware/pcspeaker.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 732d3329..dc36788f 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -15,6 +15,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + + /* $Id: pcspeaker.cpp,v 1.18 2005-02-03 10:34:37 qbix79 Exp $ */ #include #include "dosbox.h" @@ -158,7 +160,7 @@ static void ForwardPIT(float newindex) { void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode) { if (!spkr.last_ticks) { - spkr.chan->Enable(true); + if(spkr.chan) spkr.chan->Enable(true); spkr.last_index=0; } spkr.last_ticks=PIC_Ticks; @@ -213,7 +215,7 @@ void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode) { void PCSPEAKER_SetType(Bitu mode) { if (!spkr.last_ticks) { - spkr.chan->Enable(true); + if(spkr.chan) spkr.chan->Enable(true); spkr.last_index=0; } spkr.last_ticks=PIC_Ticks; @@ -296,10 +298,10 @@ static void PCSPEAKER_CallBack(Bitu len) { } *stream++=(Bit16s)(value/sample_add); } - spkr.chan->AddSamples_m16(len,(Bit16s*)MixTemp); + if(spkr.chan) spkr.chan->AddSamples_m16(len,(Bit16s*)MixTemp); if ((spkr.last_ticks+10000)Enable(false); + if(spkr.chan) spkr.chan->Enable(false); } } From 959b9b89d5719e6b35788eef5234cd6a327120b9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 7 Feb 2005 19:04:54 +0000 Subject: [PATCH 2021/4131] Change priority of logmessages Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2105 --- src/cpu/core_full.cpp | 2 +- src/cpu/core_simple.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index d1ee2820..4abe9520 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -86,7 +86,7 @@ nextopcode:; SaveIP(); continue; illegalopcode: - LOG_MSG("Illegal opcode"); + LOG(LOG_CPU,LOG_NORMAL)("Illegal opcode"); CPU_Exception(0x6,0); } FillFlags(); diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp index 7ff744e6..a64ecb83 100644 --- a/src/cpu/core_simple.cpp +++ b/src/cpu/core_simple.cpp @@ -165,7 +165,7 @@ restart_opcode: // sprintf(writecode,"%X",mem_readb(core.cseip++)); writecode+=2; } - LOG(LOG_CPU,LOG_ERROR)("Illegal/Unhandled opcode %s",tempcode); + LOG(LOG_CPU,LOG_NORMAL)("Illegal/Unhandled opcode %s",tempcode); } #endif CPU_Exception(6,0); @@ -200,4 +200,3 @@ Bits CPU_Core_Simple_Trap_Run(void) { void CPU_Core_Simple_Init(void) { } - From 2094d8b9854248bb93eadc7f4203b74eb11716f1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 10 Feb 2005 10:21:12 +0000 Subject: [PATCH 2022/4131] Year update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2106 --- acinclude.m4 | 2 +- include/bios.h | 2 +- include/callback.h | 4 ++-- include/cpu.h | 2 +- include/cross.h | 4 ++-- include/debug.h | 2 +- include/dma.h | 4 ++-- include/dos_inc.h | 4 ++-- include/dos_system.h | 4 ++-- include/dosbox.h | 2 +- include/fpu.h | 2 +- include/hardware.h | 2 +- include/inout.h | 4 ++-- include/ipx.h | 2 +- include/ipxserver.h | 2 +- include/joystick.h | 2 +- include/keyboard.h | 2 +- include/mapper.h | 2 +- include/mem.h | 2 +- include/mixer.h | 2 +- include/mouse.h | 4 ++-- include/paging.h | 4 ++-- include/pic.h | 2 +- include/programs.h | 2 +- include/regs.h | 2 +- include/render.h | 2 +- include/serialport.h | 2 +- include/setup.h | 4 ++-- include/shell.h | 4 ++-- include/support.h | 2 +- include/timer.h | 2 +- include/vga.h | 2 +- include/video.h | 2 +- src/cpu/callback.cpp | 4 ++-- src/cpu/core_dyn_x86.cpp | 2 +- src/cpu/core_dyn_x86/decoder.h | 2 +- src/cpu/core_dyn_x86/risc_x86.h | 2 +- src/cpu/core_dyn_x86/string.h | 2 +- src/cpu/core_full.cpp | 2 +- src/cpu/core_normal.cpp | 2 +- src/cpu/core_normal/helpers.h | 2 +- src/cpu/core_normal/prefix_0f.h | 2 +- src/cpu/core_normal/prefix_66.h | 2 +- src/cpu/core_normal/prefix_66_0f.h | 2 +- src/cpu/core_normal/prefix_none.h | 2 +- src/cpu/core_normal/support.h | 2 +- src/cpu/core_normal/table_ea.h | 2 +- src/cpu/core_simple.cpp | 2 +- src/cpu/cpu.cpp | 4 ++-- src/cpu/flags.cpp | 2 +- src/cpu/instructions.h | 2 +- src/cpu/lazyflags.h | 2 +- src/cpu/modrm.cpp | 2 +- src/cpu/modrm.h | 2 +- src/cpu/paging.cpp | 2 +- src/debug/debug.cpp | 4 ++-- src/debug/debug_gui.cpp | 2 +- src/debug/debug_inc.h | 4 ++-- src/debug/debug_win32.cpp | 2 +- src/debug/disasm_tables.h | 2 +- src/dos/cdrom.cpp | 2 +- src/dos/cdrom_aspi_win32.cpp | 4 ++-- src/dos/cdrom_image.cpp | 4 ++-- src/dos/cdrom_ioctl_linux.cpp | 2 +- src/dos/cdrom_ioctl_win32.cpp | 4 ++-- src/dos/dev_con.h | 4 ++-- src/dos/dos.cpp | 4 ++-- src/dos/dos_classes.cpp | 4 ++-- src/dos/dos_devices.cpp | 4 ++-- src/dos/dos_execute.cpp | 4 ++-- src/dos/dos_files.cpp | 4 ++-- src/dos/dos_ioctl.cpp | 4 ++-- src/dos/dos_memory.cpp | 2 +- src/dos/dos_misc.cpp | 4 ++-- src/dos/dos_mscdex.cpp | 4 ++-- src/dos/dos_programs.cpp | 4 ++-- src/dos/dos_tables.cpp | 4 ++-- src/dos/drive_cache.cpp | 4 ++-- src/dos/drive_fat.cpp | 4 ++-- src/dos/drive_iso.cpp | 4 ++-- src/dos/drive_local.cpp | 4 ++-- src/dos/drive_virtual.cpp | 2 +- src/dos/drives.cpp | 2 +- src/dos/drives.h | 4 ++-- src/dosbox.cpp | 4 ++-- src/fpu/fpu.cpp | 4 ++-- src/fpu/fpu_instructions.h | 4 ++-- src/fpu/fpu_types.h | 2 +- src/gui/midi.cpp | 2 +- src/gui/midi_alsa.h | 4 ++-- src/gui/midi_coreaudio.h | 2 +- src/gui/midi_oss.h | 2 +- src/gui/midi_win32.h | 4 ++-- src/gui/render.cpp | 4 ++-- src/gui/render_scalers.cpp | 18 ++++++++++++++++++ src/gui/render_scalers.h | 18 ++++++++++++++++++ src/gui/render_templates.h | 18 ++++++++++++++++++ src/gui/sdl_mapper.cpp | 4 ++-- src/gui/sdlmain.cpp | 4 ++-- src/hardware/adlib.cpp | 2 +- src/hardware/cmos.cpp | 2 +- src/hardware/directserial_win32.cpp | 4 ++-- src/hardware/disney.cpp | 2 +- src/hardware/dma.cpp | 2 +- src/hardware/gameblaster.cpp | 2 +- src/hardware/gus.cpp | 2 +- src/hardware/hardware.cpp | 2 +- src/hardware/iohandler.cpp | 4 ++-- src/hardware/ipx.cpp | 2 +- src/hardware/ipxserver.cpp | 2 +- src/hardware/joystick.cpp | 2 +- src/hardware/keyboard.cpp | 4 ++-- src/hardware/memory.cpp | 2 +- src/hardware/mixer.cpp | 4 ++-- src/hardware/mpu401.cpp | 4 ++-- src/hardware/pcspeaker.cpp | 4 ++-- src/hardware/pic.cpp | 4 ++-- src/hardware/sblaster.cpp | 2 +- src/hardware/serialport.cpp | 2 +- src/hardware/softmodem.cpp | 2 +- src/hardware/tandy_sound.cpp | 2 +- src/hardware/timer.cpp | 4 ++-- src/hardware/vga.cpp | 2 +- src/hardware/vga_attr.cpp | 2 +- src/hardware/vga_crtc.cpp | 2 +- src/hardware/vga_dac.cpp | 2 +- src/hardware/vga_draw.cpp | 2 +- src/hardware/vga_gfx.cpp | 2 +- src/hardware/vga_memory.cpp | 2 +- src/hardware/vga_misc.cpp | 2 +- src/hardware/vga_other.cpp | 2 +- src/hardware/vga_seq.cpp | 2 +- src/ints/bios.cpp | 4 ++-- src/ints/bios_disk.cpp | 2 +- src/ints/bios_keyboard.cpp | 2 +- src/ints/ems.cpp | 4 ++-- src/ints/int10.cpp | 2 +- src/ints/int10.h | 2 +- src/ints/int10_char.cpp | 4 ++-- src/ints/int10_memory.cpp | 2 +- src/ints/int10_misc.cpp | 2 +- src/ints/int10_modes.cpp | 18 ++++++++++++++++++ src/ints/int10_pal.cpp | 2 +- src/ints/int10_put_pixel.cpp | 2 +- src/ints/int10_vesa.cpp | 4 ++-- src/ints/mouse.cpp | 4 ++-- src/ints/xms.cpp | 4 ++-- src/ints/xms.h | 2 +- src/misc/messages.cpp | 4 ++-- src/misc/programs.cpp | 4 ++-- src/misc/setup.cpp | 4 ++-- src/misc/support.cpp | 4 ++-- src/shell/shell.cpp | 4 ++-- src/shell/shell_batch.cpp | 4 ++-- src/shell/shell_cmds.cpp | 4 ++-- src/shell/shell_misc.cpp | 4 ++-- 156 files changed, 287 insertions(+), 215 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 5e72516a..0392bbea 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -305,7 +305,7 @@ AC_SUBST(ALSA_LIBS) AH_TOP([ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/bios.h b/include/bios.h index e80bc067..991a964a 100644 --- a/include/bios.h +++ b/include/bios.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/callback.h b/include/callback.h index 291233b3..37519c7c 100644 --- a/include/callback.h +++ b/include/callback.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.h,v 1.10 2004-12-28 16:13:26 qbix79 Exp $ */ +/* $Id: callback.h,v 1.11 2005-02-10 10:20:47 qbix79 Exp $ */ #ifndef __CALLBACK_H #define __CALLBACK_H diff --git a/include/cpu.h b/include/cpu.h index 9fd9bfe3..75a746ca 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/cross.h b/include/cross.h index dd42a5b5..f68bd5ad 100644 --- a/include/cross.h +++ b/include/cross.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.h,v 1.11 2004-09-16 21:46:03 qbix79 Exp $ */ +/* $Id: cross.h,v 1.12 2005-02-10 10:20:47 qbix79 Exp $ */ #ifndef _CROSS_H #define _CROSS_H diff --git a/include/debug.h b/include/debug.h index 78805b70..804a31d5 100644 --- a/include/debug.h +++ b/include/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/dma.h b/include/dma.h index 294bfd28..e4ffc803 100644 --- a/include/dma.h +++ b/include/dma.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dma.h,v 1.12 2004-08-04 09:12:50 qbix79 Exp $ */ +/* $Id: dma.h,v 1.13 2005-02-10 10:20:47 qbix79 Exp $ */ #ifndef __DMA_H #define __DMA_H diff --git a/include/dos_inc.h b/include/dos_inc.h index f216b475..57521e47 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.51 2004-11-16 14:28:15 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.52 2005-02-10 10:20:47 qbix79 Exp $ */ #ifndef DOS_H_ #define DOS_H_ diff --git a/include/dos_system.h b/include/dos_system.h index 6ccdaef5..0f72ca75 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.28 2004-11-13 12:08:42 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.29 2005-02-10 10:20:47 qbix79 Exp $ */ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ diff --git a/include/dosbox.h b/include/dosbox.h index 0bd156a3..24ea7f9c 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/fpu.h b/include/fpu.h index 50f50e08..409b1520 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/hardware.h b/include/hardware.h index 638e5979..0a72c1ca 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/inout.h b/include/inout.h index 54aaf6b8..1de2b064 100644 --- a/include/inout.h +++ b/include/inout.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: inout.h,v 1.6 2004-12-28 16:13:26 qbix79 Exp $ */ +/* $Id: inout.h,v 1.7 2005-02-10 10:20:47 qbix79 Exp $ */ #ifndef __INOUT_H #define __INOUT_H diff --git a/include/ipx.h b/include/ipx.h index 5a3e4c1e..43f6372c 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/ipxserver.h b/include/ipxserver.h index 7b9f1cce..c8e70126 100644 --- a/include/ipxserver.h +++ b/include/ipxserver.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/joystick.h b/include/joystick.h index 8476525f..88407ad7 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/keyboard.h b/include/keyboard.h index 614f031a..195c3d06 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/mapper.h b/include/mapper.h index 79470233..ca65cd92 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/mem.h b/include/mem.h index f213305b..e719ce48 100644 --- a/include/mem.h +++ b/include/mem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/mixer.h b/include/mixer.h index cf8fafd3..b23366d9 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/mouse.h b/include/mouse.h index 8082f0e0..e8338381 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.h,v 1.7 2004-08-04 09:12:51 qbix79 Exp $ */ +/* $Id: mouse.h,v 1.8 2005-02-10 10:20:47 qbix79 Exp $ */ #ifndef _MOUSE_H_ #define _MOUSE_H_ diff --git a/include/paging.h b/include/paging.h index 3880c1d5..19861ccc 100644 --- a/include/paging.h +++ b/include/paging.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.13 2004-12-22 19:49:24 harekiet Exp $ */ +/* $Id: paging.h,v 1.14 2005-02-10 10:20:47 qbix79 Exp $ */ #ifndef _PAGING_H_ #define _PAGING_H_ diff --git a/include/pic.h b/include/pic.h index 43caaf40..a851aa19 100644 --- a/include/pic.h +++ b/include/pic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/programs.h b/include/programs.h index b5a7a3bb..883b0dbd 100644 --- a/include/programs.h +++ b/include/programs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/regs.h b/include/regs.h index 1c859b1e..b9ab3016 100644 --- a/include/regs.h +++ b/include/regs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/render.h b/include/render.h index 8a313866..0f9169da 100644 --- a/include/render.h +++ b/include/render.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/serialport.h b/include/serialport.h index 3aac5224..8f6df34e 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/setup.h b/include/setup.h index 686fcdf9..7e0160ad 100644 --- a/include/setup.h +++ b/include/setup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.16 2004-08-04 09:12:51 qbix79 Exp $ */ +/* $Id: setup.h,v 1.17 2005-02-10 10:20:47 qbix79 Exp $ */ #ifndef _SETUP_H_ #define _SETUP_H_ diff --git a/include/shell.h b/include/shell.h index b272615d..5bfe3e41 100644 --- a/include/shell.h +++ b/include/shell.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.9 2004-11-13 12:06:39 qbix79 Exp $ */ +/* $Id: shell.h,v 1.10 2005-02-10 10:20:47 qbix79 Exp $ */ #ifndef SHELL_H_ #define SHELL_H_ diff --git a/include/support.h b/include/support.h index 0fab9b27..b9f578ed 100644 --- a/include/support.h +++ b/include/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/timer.h b/include/timer.h index a807884a..68e600f9 100644 --- a/include/timer.h +++ b/include/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/vga.h b/include/vga.h index f34af2bb..98b1edb9 100644 --- a/include/vga.h +++ b/include/vga.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/include/video.h b/include/video.h index 4c3b8075..8846493b 100644 --- a/include/video.h +++ b/include/video.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 5277031d..595e0b82 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.23 2004-12-28 16:13:26 qbix79 Exp $ */ +/* $Id: callback.cpp,v 1.24 2005-02-10 10:20:47 qbix79 Exp $ */ #include #include diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 1cda8ba5..fab89029 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 7027c650..03781b4e 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index bc15b74b..3f50ae83 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index 10abb19a..e59c7077 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 4abe9520..b21d504a 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 13221300..0ccfd14e 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/core_normal/helpers.h b/src/cpu/core_normal/helpers.h index 9f18fb24..38c069c7 100644 --- a/src/cpu/core_normal/helpers.h +++ b/src/cpu/core_normal/helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 6bea18d3..b6218b90 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 07c55b57..a6bfa76e 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 512117c5..3e4e360e 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 0cc2c35b..f6f3a7b2 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index 910f1677..774d0640 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/core_normal/table_ea.h b/src/cpu/core_normal/table_ea.h index a7352e8b..60526f1f 100644 --- a/src/cpu/core_normal/table_ea.h +++ b/src/cpu/core_normal/table_ea.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp index a64ecb83..60ee1e6f 100644 --- a/src/cpu/core_simple.cpp +++ b/src/cpu/core_simple.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index ebb44e6c..819d877e 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.65 2005-01-24 23:11:19 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.66 2005-02-10 10:20:48 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index fabc39a9..c613dd6e 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 2e27ae5e..a6994f5f 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index 9cf2a735..6568acce 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/modrm.cpp b/src/cpu/modrm.cpp index e726f79f..779b5452 100644 --- a/src/cpu/modrm.cpp +++ b/src/cpu/modrm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/modrm.h b/src/cpu/modrm.h index b51e0f2a..697d0ba1 100644 --- a/src/cpu/modrm.h +++ b/src/cpu/modrm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 4b096581..54f316a1 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index b5518cc3..f9b0262e 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.61 2004-12-28 15:10:52 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.62 2005-02-10 10:20:50 qbix79 Exp $ */ #include #include diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index d9809ff3..bfa64dc2 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h index 0435a515..a66d63c6 100644 --- a/src/debug/debug_inc.h +++ b/src/debug/debug_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 @@ -18,7 +18,7 @@ /* Local Debug Function */ -/* $Id: debug_inc.h,v 1.8 2004-08-28 12:51:35 qbix79 Exp $ */ +/* $Id: debug_inc.h,v 1.9 2005-02-10 10:20:50 qbix79 Exp $ */ #include #include "mem.h" diff --git a/src/debug/debug_win32.cpp b/src/debug/debug_win32.cpp index d1302f91..f83ae42d 100644 --- a/src/debug/debug_win32.cpp +++ b/src/debug/debug_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/debug/disasm_tables.h b/src/debug/disasm_tables.h index ac1798ad..60f0d888 100644 --- a/src/debug/disasm_tables.h +++ b/src/debug/disasm_tables.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 96633136..bfd3b8ab 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index d6a09fbe..87861f31 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_aspi_win32.cpp,v 1.12 2004-08-04 09:12:53 qbix79 Exp $ */ +/* $Id: cdrom_aspi_win32.cpp,v 1.13 2005-02-10 10:20:50 qbix79 Exp $ */ #if defined (WIN32) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index e14357c3..378bb56e 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.4 2004-10-05 19:55:03 qbix79 Exp $ */ +/* $Id: cdrom_image.cpp,v 1.5 2005-02-10 10:20:50 qbix79 Exp $ */ #include #include diff --git a/src/dos/cdrom_ioctl_linux.cpp b/src/dos/cdrom_ioctl_linux.cpp index fe5eac34..4aacb3ed 100644 --- a/src/dos/cdrom_ioctl_linux.cpp +++ b/src/dos/cdrom_ioctl_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index 09ea8fd4..ed0b4c72 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_ioctl_win32.cpp,v 1.11 2004-08-04 09:12:53 qbix79 Exp $ */ +/* $Id: cdrom_ioctl_win32.cpp,v 1.12 2005-02-10 10:20:50 qbix79 Exp $ */ #if defined (WIN32) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 6a2bdd0b..d94124ab 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.19 2004-10-17 14:45:00 qbix79 Exp $ */ +/* $Id: dev_con.h,v 1.20 2005-02-10 10:20:50 qbix79 Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 7546c642..73cabafd 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.80 2004-12-16 19:19:39 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.81 2005-02-10 10:20:50 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 14ba6ef7..cb9307ec 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.42 2004-10-17 14:45:00 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.43 2005-02-10 10:20:51 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 2628568d..0691e614 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_devices.cpp,v 1.8 2004-10-25 21:08:47 qbix79 Exp $ */ +/* $Id: dos_devices.cpp,v 1.9 2005-02-10 10:20:51 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 27fc72d1..26c2d407 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.44 2004-08-04 09:12:53 qbix79 Exp $ */ +/* $Id: dos_execute.cpp,v 1.45 2005-02-10 10:20:51 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 78e615e1..63017afb 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.59 2004-11-16 14:28:15 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.60 2005-02-10 10:20:51 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 3c9995a6..9dcf275e 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.21 2004-11-03 23:13:54 qbix79 Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.22 2005-02-10 10:20:51 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 1a099b6a..55972ac3 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index c0a3dd94..b78ff445 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_misc.cpp,v 1.12 2004-08-04 09:12:53 qbix79 Exp $ */ +/* $Id: dos_misc.cpp,v 1.13 2005-02-10 10:20:51 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 217f96d8..bf1d9a00 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.26 2004-10-17 14:45:00 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.27 2005-02-10 10:20:51 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 3148d581..62f61a9b 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.33 2004-11-13 12:08:43 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.34 2005-02-10 10:20:51 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index be321389..d54c008f 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.17 2004-11-16 14:28:16 qbix79 Exp $ */ +/* $Id: dos_tables.cpp,v 1.18 2005-02-10 10:20:51 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 9371f7d7..869756d3 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -1,6 +1,6 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.41 2004-12-16 10:30:15 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.42 2005-02-10 10:20:51 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index d6bdccd9..8a4e734a 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.7 2004-11-24 23:04:45 canadacow Exp $ */ +/* $Id: drive_fat.cpp,v 1.8 2005-02-10 10:20:51 qbix79 Exp $ */ #include #include diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index acb549e6..b30c2f72 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.4 2004-11-03 23:13:55 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.5 2005-02-10 10:20:51 qbix79 Exp $ */ #include #include diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 51d52e91..4a8d6b43 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.54 2004-11-16 14:13:46 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.55 2005-02-10 10:20:51 qbix79 Exp $ */ #include #include diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index d9321c54..a0c4440e 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index d0c0cfb6..11b617c5 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/dos/drives.h b/src/dos/drives.h index 16f6d670..de99e339 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.25 2004-11-03 23:13:55 qbix79 Exp $ */ +/* $Id: drives.h,v 1.26 2005-02-10 10:20:52 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 73180920..d2f95883 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.82 2005-01-20 20:35:28 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.83 2005-02-10 10:20:47 qbix79 Exp $ */ #include #include diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 0d5d154f..05c5ae88 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu.cpp,v 1.23 2004-10-12 16:19:45 qbix79 Exp $ */ +/* $Id: fpu.cpp,v 1.24 2005-02-10 10:20:52 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 3f681853..0c094a41 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.25 2004-11-03 23:13:55 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.26 2005-02-10 10:20:52 qbix79 Exp $ */ static void FPU_FINIT(void) { diff --git a/src/fpu/fpu_types.h b/src/fpu/fpu_types.h index 16a4d746..eeb0ddf9 100644 --- a/src/fpu/fpu_types.h +++ b/src/fpu/fpu_types.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 80cb3cf6..79be6d75 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 110fdeea..ac8caa53 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_alsa.h,v 1.10 2004-12-16 11:17:42 qbix79 Exp $ */ +/* $Id: midi_alsa.h,v 1.11 2005-02-10 10:20:52 qbix79 Exp $ */ #define ALSA_PCM_OLD_HW_PARAMS_API #define ALSA_PCM_OLD_SW_PARAMS_API diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index cb519d4f..1d5b534c 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index e0bfc0de..8a604a04 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index c4979219..f4e4a547 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_win32.h,v 1.10 2005-01-20 20:35:29 qbix79 Exp $ */ +/* $Id: midi_win32.h,v 1.11 2005-02-10 10:21:07 qbix79 Exp $ */ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 1ccfe926..508dc560 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.30 2004-08-04 09:12:54 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.31 2005-02-10 10:21:07 qbix79 Exp $ */ #include #include diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index a0cedbc3..6a723b54 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2005 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" #include "render_scalers.h" diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index bb6de83d..f33036ba 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2005 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 _RENDER_SCALERS_H #define _RENDER_SCALERS_H diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index 67d181ed..9a129328 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2005 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. + */ + #if DBPP == 8 #define PSIZE 1 #define PTYPE Bit8u diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 54058f74..3d100faa 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.10 2004-10-28 14:46:15 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.11 2005-02-10 10:21:07 qbix79 Exp $ */ #define OLD_JOYSTICK 1 diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index c11e4750..c45a0704 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.81 2004-11-09 21:35:50 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.82 2005-02-10 10:21:07 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index ea6274e0..c1246f86 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 59cf9eb1..7319e6ec 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/directserial_win32.cpp b/src/hardware/directserial_win32.cpp index 56f029ad..a04c0ef1 100644 --- a/src/hardware/directserial_win32.cpp +++ b/src/hardware/directserial_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_win32.cpp,v 1.4 2004-08-04 13:21:20 qbix79 Exp $ */ +/* $Id: directserial_win32.cpp,v 1.5 2005-02-10 10:21:08 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 36d36efb..d11a7f18 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index a9e94e32..fc0f3c98 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index 5ef52c79..f061a351 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 5da73907..5d0d525f 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 39c6bf80..9bfe32e6 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 85874967..166c547b 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: iohandler.cpp,v 1.15 2004-12-28 16:13:26 qbix79 Exp $ */ +/* $Id: iohandler.cpp,v 1.16 2005-02-10 10:21:08 qbix79 Exp $ */ #include "dosbox.h" #include "inout.h" diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index a60ac385..d78f9da9 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/ipxserver.cpp b/src/hardware/ipxserver.cpp index 5e9f956c..b0cc6831 100644 --- a/src/hardware/ipxserver.cpp +++ b/src/hardware/ipxserver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index 1013d25d..0f571fdc 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 9ebbfeae..2a87d51c 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.29 2004-10-12 16:21:22 qbix79 Exp $ */ +/* $Id: keyboard.cpp,v 1.30 2005-02-10 10:21:08 qbix79 Exp $ */ #include #include diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index a4e206c9..dfa06a2d 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index fa0ff21a..c0689de5 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.28 2005-01-20 20:35:28 qbix79 Exp $ */ +/* $Id: mixer.cpp,v 1.29 2005-02-10 10:21:08 qbix79 Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 339b3155..74cb7bf4 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.13 2004-12-28 15:56:23 qbix79 Exp $ */ +/* $Id: mpu401.cpp,v 1.14 2005-02-10 10:21:09 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index dc36788f..00d2ea62 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /* $Id: pcspeaker.cpp,v 1.18 2005-02-03 10:34:37 qbix79 Exp $ */ + /* $Id: pcspeaker.cpp,v 1.19 2005-02-10 10:21:09 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 34806692..b294a5ee 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.27 2004-12-16 19:22:11 qbix79 Exp $ */ +/* $Id: pic.cpp,v 1.28 2005-02-10 10:21:09 qbix79 Exp $ */ #include diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 319f2b95..52aef47c 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/serialport.cpp b/src/hardware/serialport.cpp index 6020b541..a6d5cb6c 100644 --- a/src/hardware/serialport.cpp +++ b/src/hardware/serialport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp index 0c7f9c6c..6f171c91 100644 --- a/src/hardware/softmodem.cpp +++ b/src/hardware/softmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 0983a28e..613ee3f4 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index b59e8c1e..d516bffb 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.30 2004-11-13 11:59:46 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.31 2005-02-10 10:21:10 qbix79 Exp $ */ #include "dosbox.h" #include "inout.h" diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index a5f6d63a..cee879e2 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 344c91fe..513e5a53 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 0f89f663..9c7445fb 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index cae4696b..26465d4d 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 90c672b0..4a8187f0 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index 5a1725e6..e49856c5 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 94ad089f..4af354d5 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 037a581d..4af47ffc 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 807d7abf..5c92636a 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 12db7b63..e001ea9a 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index c6d2eb94..9f5f8fac 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.38 2004-12-19 16:46:04 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.39 2005-02-10 10:21:11 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index be65ce66..453d1be4 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 70f610ff..8e579d3e 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 3a3aa8ea..4790310e 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.37 2005-01-12 12:44:48 qbix79 Exp $ */ +/* $Id: ems.cpp,v 1.38 2005-02-10 10:21:11 qbix79 Exp $ */ #include #include diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 975d7ac3..63d8ceca 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/ints/int10.h b/src/ints/int10.h index a0bed3ac..0b3eefc3 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 7cac4d89..9dc5edf9 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.30 2004-09-10 22:08:45 harekiet Exp $ */ +/* $Id: int10_char.cpp,v 1.31 2005-02-10 10:21:11 qbix79 Exp $ */ /* Character displaying moving functions */ diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 2a788068..0ffb3b54 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 99f0e25b..7ec7bb9b 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 0968678b..ddb1669c 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2005 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 #include "dosbox.h" diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 44cdf0a8..06c90622 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 13c5bfee..a1ead666 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 6bcb87b9..86bb3993 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.12 2004-09-10 22:09:54 harekiet Exp $ */ +/* $Id: int10_vesa.cpp,v 1.13 2005-02-10 10:21:11 qbix79 Exp $ */ #include #include diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 48c7b322..a955de88 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.44 2004-12-28 15:57:31 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.45 2005-02-10 10:21:11 qbix79 Exp $ */ #include #include diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 9bba09a0..589670c7 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.33 2004-08-04 09:12:56 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.34 2005-02-10 10:21:11 qbix79 Exp $ */ #include #include diff --git a/src/ints/xms.h b/src/ints/xms.h index 3ee5d5c1..855c8c06 100644 --- a/src/ints/xms.h +++ b/src/ints/xms.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 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 diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 4bcc59b8..f06a9eab 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: messages.cpp,v 1.16 2005-02-03 10:17:44 qbix79 Exp $ */ +/* $Id: messages.cpp,v 1.17 2005-02-10 10:21:11 qbix79 Exp $ */ #include #include diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index e720665a..c9cdb151 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.17 2004-10-23 17:54:36 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.18 2005-02-10 10:21:11 qbix79 Exp $ */ #include #include diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 8f3fe75d..3b8e3bea 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.23 2004-10-25 21:16:30 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.24 2005-02-10 10:21:11 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 4f362477..e5a3a045 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.27 2004-10-24 10:03:29 qbix79 Exp $ */ +/* $Id: support.cpp,v 1.28 2005-02-10 10:21:12 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 5e51d9c8..bd94191c 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.54 2005-01-14 19:38:19 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.55 2005-02-10 10:21:12 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 724b5210..c16f5b5f 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.14 2004-08-04 09:12:57 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.15 2005-02-10 10:21:12 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index efe47583..fbbb252b 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.50 2004-11-13 12:06:39 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.51 2005-02-10 10:21:12 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 2c3b99d4..ccf6bb09 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2004 The DOSBox Team + * Copyright (C) 2002-2005 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.34 2005-01-11 21:08:08 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.35 2005-02-10 10:21:12 qbix79 Exp $ */ #include #include From 4e7c4106476683ab0d6c2113a6bafd9cff5598ab Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 11 Feb 2005 21:17:04 +0000 Subject: [PATCH 2023/4131] Reset disk succeeds if there aren't any images. Fixes ace of aces Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2107 --- src/ints/bios_disk.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 453d1be4..64b01d07 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: bios_disk.cpp,v 1.17 2005-02-11 21:17:04 qbix79 Exp $ */ + #include "dosbox.h" #include "callback.h" #include "bios.h" @@ -25,6 +27,7 @@ #include "mapper.h" #define MAX_SWAPPABLE_DISKS 20 +#define MAX_DISK_IMAGES 4 diskGeo DiskGeometryList[] = { {160, 8, 1, 40, 0}, @@ -48,7 +51,7 @@ DOS_DTA *imgDTA; bool killRead; /* 2 floppys and 2 harddrives, max */ -imageDisk *imageDiskList[4]; +imageDisk *imageDiskList[MAX_DISK_IMAGES]; imageDisk *diskSwap[MAX_SWAPPABLE_DISKS]; Bits swapPosition; @@ -275,15 +278,25 @@ static Bitu INT13_DiskHandler(void) { //LOG_MSG("INT13: Function %x called on drive %x (dos drive %d)", reg_ah, reg_dl, drivenum); switch(reg_ah) { case 0x0: /* Reset disk */ - if(driveInactive(drivenum)) return CBRET_NONE; - last_status = 0x00; - CALLBACK_SCF(false); + { + bool any_images = false; + for(Bitu i = 0;i < MAX_DISK_IMAGES;i++) { + if(imageDiskList[i]) any_images=true; + } + /* if there aren't any diskimages (so only localdrives and virtual drives) + * always succeed on reset disk. If there are diskimages then and only then + * do real checks + */ + if(any_images && driveInactive(drivenum)) return CBRET_NONE; + last_status = 0x00; + CALLBACK_SCF(false); + } break; case 0x1: /* Get status of last operation */ if(last_status != 0x00) { reg_ah = last_status; - CALLBACK_SCF(true); + CALLBACK_SCF(true); } else { reg_ah = 0x00; CALLBACK_SCF(false); @@ -406,7 +419,6 @@ static Bitu INT13_DiskHandler(void) { void BIOS_SetupDisks(void) { /* TODO Start the time correctly */ call_int13=CALLBACK_Allocate(); - //CALLBACK_Setup(call_int13,&INT13_SmallHandler,CB_IRET); CALLBACK_Setup(call_int13,&INT13_DiskHandler,CB_IRET,"Int 13 Bios disk"); RealSetVec(0x13,CALLBACK_RealPointer(call_int13)); int i; @@ -438,4 +450,3 @@ void BIOS_SetupDisks(void) { MAPPER_AddHandler(swapInNextDisk,MK_f4,MMOD1,"swapimg","Swap Image"); killRead = false; } - From 6bb1e22bf0889333c6141a6f0703687186144013 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 13 Feb 2005 13:06:44 +0000 Subject: [PATCH 2024/4131] some changes in the extend keyhandling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2108 --- src/ints/bios_keyboard.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 8e579d3e..bf4f9328 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -377,29 +377,34 @@ irq1_return: } static Bitu INT16_Handler(void) { - Bit16u temp; + Bit16u temp; + bool extended = false; //accept extended keycodes (call 0x10 0x11) switch (reg_ah) { + case 0x10: /* GET KEYSTROKE (extended) */ + extended = true; /* Fallthrough */ case 0x00: /* GET KEYSTROKE */ - case 0x10: + //Officially: the non extended version should skip all extended keys. + //For improved compatibility: clear the extended part (0xe0) { -//TODO find a more elegant way to do this do { + //TODO find a more elegant way to do this temp=get_key(); if (temp==0) { CALLBACK_Idle();}; } while (temp==0); reg_ax=temp; - if(reg_al==0xe0) reg_al=0; //extended key + if(!extended && reg_al==0xe0) reg_al=0; //no extended break; } + case 0x11: /* CHECK FOR KEYSTROKE (extended) */ + extended = true; /* Fallthrough */ case 0x01: /* CHECK FOR KEYSTROKE */ - case 0x11: temp=check_key(); if (temp==0) { CALLBACK_SZF(true); } else { CALLBACK_SZF(false); reg_ax=temp; - if(reg_al==0xe0) reg_al=0; //extended key + if(!extended && reg_al==0xe0) reg_al=0; //no extended } break; case 0x02: /* GET SHIFT FlAGS */ From f441e56f80ab4f4356612d5fb6579e83552a9661 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 14 Feb 2005 15:58:50 +0000 Subject: [PATCH 2025/4131] Some odd files=X detection routine Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2109 --- src/dos/dos_misc.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index b78ff445..70b82c67 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_misc.cpp,v 1.13 2005-02-10 10:20:51 qbix79 Exp $ */ +/* $Id: dos_misc.cpp,v 1.14 2005-02-14 15:58:50 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" @@ -58,6 +58,12 @@ static Bitu INT2A_Handler(void) { static bool DOS_MultiplexFunctions(void) { switch (reg_ax) { + case 0x1216: /* GET ADDRESS OF SYSTEM FILE TABLE ENTRY */ + /* Should do a lot more. Let's see if we can get away with it */ + LOG(LOG_DOSMISC,LOG_ERROR)("Some BAD filetable call used bx=%X",reg_bx); + if(reg_bx <= DOS_FILES) CALLBACK_SCF(false); + else CALLBACK_SCF(true); + return true; case 0x1607: if (reg_bx == 0x15) { switch (reg_cx) { From 4641faa5caa3b121a7e7198532969ffcf35294b5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 14 Feb 2005 16:06:15 +0000 Subject: [PATCH 2026/4131] Added handler for port 3c8 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2110 --- src/hardware/vga_dac.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index 26465d4d..c5181059 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -80,6 +80,10 @@ static void write_p3c8(Bitu port,Bitu val,Bitu iolen) { vga.dac.state=DAC_WRITE; } +static Bitu read_p3c8(Bitu port, Bitu iolen){ + return vga.dac.write_index; +} + static void write_p3c9(Bitu port,Bitu val,Bitu iolen) { val&=0x3f; switch (vga.dac.pel_index) { @@ -187,10 +191,9 @@ void VGA_SetupDAC(void) { IO_RegisterReadHandler(0x3c6,read_p3c6,IO_MB); IO_RegisterWriteHandler(0x3c7,write_p3c7,IO_MB); IO_RegisterReadHandler(0x3c7,read_p3c7,IO_MB); + IO_RegisterReadHandler(0x3c8,read_p3c8,IO_MB); IO_RegisterWriteHandler(0x3c8,write_p3c8,IO_MB); IO_RegisterWriteHandler(0x3c9,write_p3c9,IO_MB); IO_RegisterReadHandler(0x3c9,read_p3c9,IO_MB); } }; - - From 506400755d6dda2b08d57a13f52370bcdcaf9a5b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 14 Feb 2005 16:24:16 +0000 Subject: [PATCH 2027/4131] Added Get DAC Colour page Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2111 --- src/ints/int10.cpp | 5 +++-- src/ints/int10.h | 3 +-- src/ints/int10_pal.cpp | 16 +++++++++++++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 63d8ceca..3315d909 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -177,6 +177,9 @@ static Bitu INT10_Handler(void) { case 0x19: /* undocumented - GET PEL MASK */ INT10_GetPelMask(reg_bl); break; + case 0x1A: /* GET VIDEO DAC COLOR PAGE */ + INT10_GetDACPage(®_bl,®_bh); + break; default: LOG(LOG_INT10,LOG_ERROR)("Function 10:Unhandled EGA/VGA Palette Function %2X",reg_al); } @@ -475,5 +478,3 @@ void INT10_Init(Section* sec) { INT10_SetupVESA(); INT10_SetVideoMode(machine==MCH_HERC ? 0x7 : 0x3); }; - - diff --git a/src/ints/int10.h b/src/ints/int10.h index 0b3eefc3..d64fcfce 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -173,6 +173,7 @@ void INT10_GetSingleDacRegister(Bit8u index,Bit8u * red,Bit8u * green,Bit8u * bl void INT10_SetDACBlock(Bit16u index,Bit16u count,PhysPt data); void INT10_GetDACBlock(Bit16u index,Bit16u count,PhysPt data); void INT10_SelectDACPage(Bit8u function,Bit8u mode); +void INT10_GetDACPage(Bit8u* mode,Bit8u* page); void INT10_SetPelMask(Bit8u mask); void INT10_GetPelMask(Bit8u & mask); @@ -194,5 +195,3 @@ Bit8u VESA_GetPalette(PhysPt data,Bitu index,Bitu count); /* Sup Groups */ void INT10_SetupRomMemory(void); void INT10_SetupVESA(void); - - diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 06c90622..456af7ed 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -147,6 +147,21 @@ void INT10_SelectDACPage(Bit8u function,Bit8u mode) { IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette } +void INT10_GetDACPage(Bit8u* mode,Bit8u* page) { + IO_Read(VGAREG_ACTL_RESET); + IO_Write(VGAREG_ACTL_ADDRESS,0x10); + Bit8u reg10=IO_Read(VGAREG_ACTL_READ_DATA); + *mode=(reg10&0x80)?0x01:0x00; + IO_Write(VGAREG_ACTL_ADDRESS,0x14); + *page=IO_Read(VGAREG_ACTL_READ_DATA); + if(*mode) { + *page&=0xf; + } else { + *page&=0xc; + *page>>=2; + } +} + void INT10_SetPelMask(Bit8u mask) { IO_Write(VGAREG_PEL_MASK,mask); } @@ -168,4 +183,3 @@ void INT10_SetColorSelect(Bit8u val) { real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp); IO_Write(0x3d9,temp); } - From a05b1da47983ea552c60e25781e0d04169ed8c04 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 21 Feb 2005 15:36:14 +0000 Subject: [PATCH 2028/4131] Small changes in the taskswitching code (wd) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2112 --- src/cpu/cpu.cpp | 49 ++++++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 819d877e..88aed219 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.66 2005-02-10 10:20:48 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.67 2005-02-21 15:36:14 qbix79 Exp $ */ #include #include "dosbox.h" @@ -325,25 +325,36 @@ bool CPU_SwitchTask(Bitu new_tss_selector,TSwitchType tstype,Bitu old_eip) { } // cpu.cr0|=CR0_TASKSWITCHED; - /* Setup the new cr3 */ - PAGING_SetDirBase(new_cr3); - - /* Load new context */ - if (new_tss.is386) { - reg_eip=new_eip; - CPU_SetFlags(new_eflags,FMASK_ALL | FLAG_VM); - reg_eax=new_eax; - reg_ecx=new_ecx; - reg_edx=new_edx; - reg_ebx=new_ebx; - reg_esp=new_esp; - reg_ebp=new_ebp; - reg_edi=new_edi; - reg_esi=new_esi; - - new_cs=mem_readw(new_tss.base+offsetof(TSS_32,cs)); + if (new_tss_selector == cpu_tss.selector) { + reg_eip = old_eip; + new_cs = SegValue(cs); + new_ss = SegValue(ss); + new_ds = SegValue(ds); + new_es = SegValue(es); + new_fs = SegValue(fs); + new_gs = SegValue(gs); } else { - E_Exit("286 task switch"); + + /* Setup the new cr3 */ + PAGING_SetDirBase(new_cr3); + + /* Load new context */ + if (new_tss.is386) { + reg_eip=new_eip; + CPU_SetFlags(new_eflags,FMASK_ALL | FLAG_VM); + reg_eax=new_eax; + reg_ecx=new_ecx; + reg_edx=new_edx; + reg_ebx=new_ebx; + reg_esp=new_esp; + reg_ebp=new_ebp; + reg_edi=new_edi; + reg_esi=new_esi; + +// new_cs=mem_readw(new_tss.base+offsetof(TSS_32,cs)); + } else { + E_Exit("286 task switch"); + } } /* Load the new selectors */ if (reg_flags & FLAG_VM) { From fd28399da212cf570b736dc4b5b4d13eff40b5bc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 22 Feb 2005 13:06:07 +0000 Subject: [PATCH 2029/4131] New assembly x86 fpu core + fixing some bugs in the old one (Thanks wd) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2113 --- INSTALL | 8 + configure.in | 18 + src/fpu/Makefile.am | 3 +- src/fpu/fpu.cpp | 379 ++++++--------- src/fpu/fpu_instructions.h | 474 +++++++++++------- src/fpu/fpu_instructions_x86.h | 864 +++++++++++++++++++++++++++++++++ src/fpu/fpu_types.h | 12 +- src/platform/visualc/config.h | 3 + visualc/dosbox.dsp | 4 + visualc_net/dosbox.vcproj | 3 + 10 files changed, 1377 insertions(+), 391 deletions(-) create mode 100644 src/fpu/fpu_instructions_x86.h diff --git a/INSTALL b/INSTALL index 936cde7d..70289563 100644 --- a/INSTALL +++ b/INSTALL @@ -50,6 +50,14 @@ In step 1 you could add the following switches: enables some memory increasing inlines. This greatly increases compiletime for maybe a increase in speed. +--disable-dynamic-x86 + disables the dynamic cpu core. Although it's unstable it can greatly + improve the speed of dosbox on x86 hosts. + +--disable-fpu-x86 + disables the assembly fpu core. Although relatively new the x86 fpu + core has more accuracy then the regular fpu core. + Check the src subdir for the binary. diff --git a/configure.in b/configure.in index 53436924..ae00c5ac 100644 --- a/configure.in +++ b/configure.in @@ -137,6 +137,24 @@ 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_hostcpu = 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_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) diff --git a/src/fpu/Makefile.am b/src/fpu/Makefile.am index 14c2d3d4..d081a682 100644 --- a/src/fpu/Makefile.am +++ b/src/fpu/Makefile.am @@ -1,4 +1,5 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libfpu.a -libfpu_a_SOURCES = fpu.cpp fpu_types.h fpu_instructions.h \ No newline at end of file +libfpu_a_SOURCES = fpu.cpp fpu_types.h fpu_instructions.h \ + fpu_instructions_x86.h diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 05c5ae88..65428abf 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu.cpp,v 1.24 2005-02-10 10:20:52 qbix79 Exp $ */ +/* $Id: fpu.cpp,v 1.25 2005-02-22 13:06:05 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU @@ -31,7 +31,7 @@ typedef PhysPt EAPoint; #define TOP fpu.top -#define ST(i) ( (fpu.top+ (i) ) & 7 ) +#define STV(i) ( (fpu.top+ (i) ) & 7 ) #define LoadMb(off) mem_readb(off) #define LoadMw(off) mem_readw(off) @@ -44,21 +44,19 @@ typedef PhysPt EAPoint; #include "fpu_types.h" struct { - FPU_Reg regs[9]; - FPU_Tag tags[9]; - Bitu cw; - FPU_Round round; - Bitu ex_mask; - Bitu sw; - Bitu top; - + 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; -INLINE void FPU_SetCW(Bitu word) { +INLINE void FPU_SetCW(Bitu word){ fpu.cw = word; + fpu.cw_mask_all = word | 0x3f; fpu.round = (FPU_Round)((word >> 10) & 3); - // word >>8 &3 is precission - fpu.ex_mask = word & 0x3f; } static Bit16u FPU_GetTag(void){ @@ -68,22 +66,17 @@ static Bit16u FPU_GetTag(void){ return tag; } -static void FPU_SetTag(Bit16u tag) -{ +static void FPU_SetTag(Bit16u tag){ for(Bitu i=0;i<8;i++) fpu.tags[i]= static_cast((tag >>(2*i))&3); } - - - INLINE Bitu FPU_GET_TOP(void){ return (fpu.sw & 0x3800)>>11; } INLINE void FPU_SET_TOP(Bitu val){ fpu.sw &= ~0x3800; fpu.sw |= (val&7)<<11; - return; } INLINE void FPU_SET_C0(Bitu C){ @@ -103,71 +96,54 @@ INLINE void FPU_SET_C3(Bitu C){ if(C) fpu.sw |= 0x4000; } -INLINE Bitu FPU_GET_C0(void){ - return (fpu.sw & 0x0100)>>8; -} -INLINE Bitu FPU_GET_C1(void){ - return (fpu.sw & 0x0200)>>9; -} -INLINE Bitu FPU_GET_C2(void){ - return (fpu.sw & 0x0400)>>10; -} -INLINE Bitu FPU_GET_C3(void){ - return (fpu.sw & 0x4000)>>14; -} - +#if C_FPU_X86 +#include "fpu_instructions_x86.h" +#else #include "fpu_instructions.h" - -/* TODO : ESC6normal => esc4normal+pop or a define as well -*/ +#endif /* WATCHIT : ALWAYS UPDATE REGISTERS BEFORE AND AFTER USING THEM STATUS WORD => FPU_SET_TOP(TOP) BEFORE a read TOP=FPU_GET_TOP() after a write; */ + static void EATREE(Bitu _rm){ Bitu group=(_rm >> 3) & 7; /* data will allready be put in register 8 by caller */ switch(group){ - case 0x00: /* FIADD */ + case 0x00: /* FADD */ FPU_FADD(TOP, 8); break; - case 0x01: /* FIMUL */ + case 0x01: /* FMUL */ FPU_FMUL(TOP, 8); break; - case 0x02: /* FICOM */ + case 0x02: /* FCOM */ FPU_FCOM(TOP,8); break; - case 0x03: /* FICOMP */ + case 0x03: /* FCOMP */ FPU_FCOM(TOP,8); FPU_FPOP(); break; - case 0x04: /* FISUB */ + case 0x04: /* FSUB */ FPU_FSUB(TOP,8); break; - case 0x05: /* FISUBR */ + case 0x05: /* FSUBR */ FPU_FSUBR(TOP,8); break; - case 0x06: /* FIDIV */ + case 0x06: /* FDIV */ FPU_FDIV(TOP, 8); break; - case 0x07: /* FIDIVR */ + case 0x07: /* FDIVR */ FPU_FDIVR(TOP,8); break; default: break; } - } void FPU_ESC0_EA(Bitu rm,PhysPt addr) { - /* REGULAR TREE WITH 32 BITS REALS -> float */ - union { - float f; - Bit32u l; - } blah; - blah.l = mem_readd(addr); - fpu.regs[8].d = static_cast(blah.f); + /* REGULAR TREE WITH 32 BITS REALS */ + FPU_FLD_F32(addr,8); EATREE(rm); } @@ -176,33 +152,32 @@ void FPU_ESC0_Normal(Bitu rm) { Bitu sub=(rm & 7); switch (group){ case 0x00: /* FADD ST,STi */ - FPU_FADD(TOP,ST(sub)); + FPU_FADD(TOP,STV(sub)); break; case 0x01: /* FMUL ST,STi */ - FPU_FMUL(TOP,ST(sub)); + FPU_FMUL(TOP,STV(sub)); break; case 0x02: /* FCOM STi */ - FPU_FCOM(TOP,ST(sub)); + FPU_FCOM(TOP,STV(sub)); break; case 0x03: /* FCOMP STi */ - FPU_FCOM(TOP,ST(sub)); + FPU_FCOM(TOP,STV(sub)); FPU_FPOP(); break; case 0x04: /* FSUB ST,STi */ - FPU_FSUB(TOP,ST(sub)); + FPU_FSUB(TOP,STV(sub)); break; case 0x05: /* FSUBR ST,STi */ - FPU_FSUBR(TOP,ST(sub)); + FPU_FSUBR(TOP,STV(sub)); break; case 0x06: /* FDIV ST,STi */ - FPU_FDIV(TOP,ST(sub)); + FPU_FDIV(TOP,STV(sub)); break; case 0x07: /* FDIVR ST,STi */ - FPU_FDIVR(TOP,ST(sub)); + FPU_FDIVR(TOP,STV(sub)); break; default: break; - } } @@ -212,40 +187,17 @@ void FPU_ESC1_EA(Bitu rm,PhysPt addr) { Bitu sub=(rm & 7); switch(group){ case 0x00: /* FLD float*/ - { - union { - float f; - Bit32u l; - } blah; - blah.l = mem_readd(addr); - FPU_PUSH(static_cast(blah.f)); - } + FPU_PREP_PUSH(); + FPU_FLD_F32(addr,TOP); break; - case 0x01: /* UNKNOWN */ LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub); break; case 0x02: /* FST float*/ - { - union { - float f; - Bit32u l; - } blah; - //should depend on rounding method - blah.f = static_cast(fpu.regs[TOP].d); - mem_writed(addr,blah.l); - } + FPU_FST_F32(addr); break; - case 0x03: /* FSTP float*/ - { - union { - float f; - Bit32u l; - } blah; - blah.f = static_cast(fpu.regs[TOP].d); - mem_writed(addr,blah.l); - } + FPU_FST_F32(addr); FPU_FPOP(); break; case 0x04: /* FLDENV */ @@ -253,7 +205,7 @@ void FPU_ESC1_EA(Bitu rm,PhysPt addr) { break; case 0x05: /* FLDCW */ { - Bit16u temp =mem_readw(addr); + Bit16u temp = mem_readw(addr); FPU_SetCW(temp); } break; @@ -267,7 +219,6 @@ void FPU_ESC1_EA(Bitu rm,PhysPt addr) { LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub); break; } - } void FPU_ESC1_Normal(Bitu rm) { @@ -275,33 +226,36 @@ void FPU_ESC1_Normal(Bitu rm) { Bitu sub=(rm & 7); switch (group){ case 0x00: /* FLD STi */ - FPU_PUSH(fpu.regs[ST(sub)].d); - break; + { + Bitu reg_from=STV(sub); + FPU_PREP_PUSH(); + FPU_FST(reg_from, TOP); + break; + } case 0x01: /* FXCH STi */ - FPU_FXCH(TOP,ST(sub)); + FPU_FXCH(TOP,STV(sub)); break; case 0x02: /* FNOP */ - FPU_FNOP(); + FPU_FNOP(); break; case 0x03: /* FSTP STi */ - FPU_FST(TOP,ST(sub)); - FPU_FPOP(); + FPU_FST(TOP,STV(sub)); + FPU_FPOP(); break; case 0x04: switch(sub){ case 0x00: /* FCHS */ - fpu.regs[TOP].d = -1.0*(fpu.regs[TOP].d); + FPU_FCHS(); break; case 0x01: /* FABS */ - fpu.regs[TOP].d = fabs(fpu.regs[TOP].d); + 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 */ - fpu.regs[8].d=0.0; - FPU_FCOM(TOP,8); + FPU_FTST(); break; case 0x05: /* FXAM */ FPU_FXAM(); @@ -315,25 +269,25 @@ void FPU_ESC1_Normal(Bitu rm) { case 0x05: switch(sub){ case 0x00: /* FLD1 */ - FPU_PUSH(1.0); + FPU_FLD1(); break; case 0x01: /* FLDL2T */ - FPU_PUSH(L2T); + FPU_FLDL2T(); break; case 0x02: /* FLDL2E */ - FPU_PUSH(L2E); + FPU_FLDL2E(); break; case 0x03: /* FLDPI */ - FPU_PUSH(PI); + FPU_FLDPI(); break; case 0x04: /* FLDLG2 */ - FPU_PUSH(LG2); + FPU_FLDLG2(); break; case 0x05: /* FLDLN2 */ - FPU_PUSH(LN2); + FPU_FLDLN2(); break; case 0x06: /* FLDZ*/ - FPU_PUSH_ZERO(); + FPU_FLDZ(); break; case 0x07: /* ILLEGAL */ LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); @@ -342,24 +296,33 @@ void FPU_ESC1_Normal(Bitu rm) { break; case 0x06: switch(sub){ - case 0x00: /* F2XM1 */ + case 0x00: /* F2XM1 */ FPU_F2XM1(); break; - case 0x01: /* FYL2X */ + case 0x01: /* FYL2X */ FPU_FYL2X(); break; - case 0x02: /* FPTAN */ + case 0x02: /* FPTAN */ FPU_FPTAN(); break; - case 0x03: /* FPATAN */ + case 0x03: /* FPATAN */ FPU_FPATAN(); break; - case 0x04: /* FXTRACT */ + case 0x04: /* FXTRACT */ FPU_FXTRACT(); break; + case 0x05: /* FPREM1 */ + FPU_FPREM1(); + break; + case 0x06: /* FDECSTP */ + TOP = (TOP - 1) & 7; + break; + case 0x07: /* FINCSTP */ + TOP = (TOP + 1) & 7; + break; default: - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - break; + LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); + break; } break; case 0x07: @@ -367,6 +330,9 @@ void FPU_ESC1_Normal(Bitu rm) { case 0x00: /* FPREM */ FPU_FPREM(); break; + case 0x01: /* FYL2XP1 */ + FPU_FYL2XP1(); + break; case 0x02: /* FSQRT */ FPU_FSQRT(); break; @@ -374,12 +340,7 @@ void FPU_ESC1_Normal(Bitu rm) { FPU_FSINCOS(); break; case 0x04: /* FRNDINT */ - { -//TODO - Bit64s temp= static_cast(FROUND(fpu.regs[TOP].d)); - fpu.regs[TOP].d=static_cast(temp); - } - //TODO + FPU_FRNDINT(); break; case 0x05: /* FSCALE */ FPU_FSCALE(); @@ -390,7 +351,6 @@ void FPU_ESC1_Normal(Bitu rm) { case 0x07: /* FCOS */ FPU_FCOS(); break; - case 0x01: /* FYL2XP1 */ default: LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); break; @@ -399,15 +359,12 @@ void FPU_ESC1_Normal(Bitu rm) { default: LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); } - -// LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); } void FPU_ESC2_EA(Bitu rm,PhysPt addr) { /* 32 bits integer operants */ - Bit32s blah = mem_readd(addr); - fpu.regs[8].d = static_cast(blah); + FPU_FLD_I32(addr,8); EATREE(rm); } @@ -417,8 +374,8 @@ void FPU_ESC2_Normal(Bitu rm) { switch(group){ case 0x05: switch(sub){ - case 0x01: /* FUCOMPP Almost the same as FCOMPP */ - FPU_FCOM(TOP,ST(1)); + case 0x01: /* FUCOMPP */ + FPU_FUCOM(TOP,STV(1)); FPU_FPOP(); FPU_FPOP(); break; @@ -438,31 +395,26 @@ void FPU_ESC3_EA(Bitu rm,PhysPt addr) { Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); switch(group){ - case 0x00: /* FLD */ - { - Bit32s blah = mem_readd(addr); - FPU_PUSH( static_cast(blah)); - } + case 0x00: /* FILD */ + FPU_PREP_PUSH(); + FPU_FLD_I32(addr,TOP); break; - case 0x01: /* FISTTP */ + case 0x01: /* FISTTP */ LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub); break; - - case 0x02: /* FIST */ - mem_writed(addr,static_cast(FROUND(fpu.regs[TOP].d))); + case 0x02: /* FIST */ + FPU_FST_I32(addr); break; - case 0x03: /*FISTP */ - mem_writed(addr,static_cast(FROUND(fpu.regs[TOP].d))); + case 0x03: /* FISTP */ + FPU_FST_I32(addr); FPU_FPOP(); break; case 0x05: /* FLD 80 Bits Real */ - { - Real64 val = FPU_FLD80(addr); - FPU_PUSH(val); - } + FPU_PREP_PUSH(); + FPU_FLD_F80(addr); break; case 0x07: /* FSTP 80 Bits Real */ - FPU_ST80(addr,TOP); + FPU_FST_F80(addr); FPU_FPOP(); break; default: @@ -504,41 +456,40 @@ void FPU_ESC3_Normal(Bitu rm) { void FPU_ESC4_EA(Bitu rm,PhysPt addr) { - /* REGULAR TREE WITH 64 BITS REALS: double */ - fpu.regs[8].l.lower=mem_readd(addr); - fpu.regs[8].l.upper=mem_readd(addr+4); + /* REGULAR TREE WITH 64 BITS REALS */ + FPU_FLD_F64(addr,8); EATREE(rm); } void FPU_ESC4_Normal(Bitu rm) { - //LOOKS LIKE number 6 without popping*/ + /* LOOKS LIKE number 6 without popping */ Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); switch(group){ - case 0x00: /*FADDP STi,ST*/ - FPU_FADD(ST(sub),TOP); + case 0x00: /* FADD STi,ST*/ + FPU_FADD(STV(sub),TOP); break; - case 0x01: /* FMULP STi,ST*/ - FPU_FMUL(ST(sub),TOP); + case 0x01: /* FMUL STi,ST*/ + FPU_FMUL(STV(sub),TOP); break; case 0x02: /* FCOM*/ - FPU_FCOM(TOP,ST(sub)); - break; /* TODO IS THIS ALLRIGHT ????????? (maybe reverse operators) */ + FPU_FCOM(TOP,STV(sub)); + break; case 0x03: /* FCOMP*/ - FPU_FCOM(TOP,ST(sub)); + FPU_FCOM(TOP,STV(sub)); FPU_FPOP(); break; case 0x04: /* FSUBR STi,ST*/ - FPU_FSUBR(ST(sub),TOP); + FPU_FSUBR(STV(sub),TOP); break; case 0x05: /* FSUB STi,ST*/ - FPU_FSUB(ST(sub),TOP); + FPU_FSUB(STV(sub),TOP); break; case 0x06: /* FDIVR STi,ST*/ - FPU_FDIVR(ST(sub),TOP); + FPU_FDIVR(STV(sub),TOP); break; case 0x07: /* FDIV STi,ST*/ - FPU_FDIV(ST(sub),TOP); + FPU_FDIV(STV(sub),TOP); break; default: break; @@ -550,28 +501,21 @@ void FPU_ESC5_EA(Bitu rm,PhysPt addr) { Bitu sub=(rm & 7); switch(group){ case 0x00: /* FLD double real*/ - { - FPU_Reg blah; - blah.l.lower=mem_readd(addr); - blah.l.upper=mem_readd(addr+4); - FPU_PUSH(blah.d); - } + FPU_PREP_PUSH(); + FPU_FLD_F64(addr,TOP); break; case 0x01: /* FISTTP longint*/ LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub); break; - - case 0x02: /* FIST double real*/ - mem_writed(addr,fpu.regs[TOP].l.lower); - mem_writed(addr+4,fpu.regs[TOP].l.upper); + case 0x02: /* FST double real*/ + FPU_FST_F64(addr); break; - case 0x03: /*FISTP double real*/ - mem_writed(addr,fpu.regs[TOP].l.lower); - mem_writed(addr+4,fpu.regs[TOP].l.upper); + case 0x03: /* FSTP double real*/ + FPU_FST_F64(addr); FPU_FPOP(); break; - case 0x04: /* FSTOR */ - FPU_FSTOR(addr); + case 0x04: /* FRSTOR */ + FPU_FRSTOR(addr); break; case 0x06: /* FSAVE */ FPU_FSAVE(addr); @@ -591,23 +535,23 @@ void FPU_ESC5_Normal(Bitu rm) { Bitu sub=(rm & 7); switch(group){ case 0x00: /* FFREE STi */ - fpu.tags[ST(sub)]=TAG_Empty; + fpu.tags[STV(sub)]=TAG_Empty; break; case 0x01: /* FXCH STi*/ - FPU_FXCH(TOP,ST(sub)); + FPU_FXCH(TOP,STV(sub)); break; case 0x02: /* FST STi */ - FPU_FST(TOP,ST(sub)); + FPU_FST(TOP,STV(sub)); break; case 0x03: /* FSTP STi*/ - FPU_FST(TOP,ST(sub)); + FPU_FST(TOP,STV(sub)); FPU_FPOP(); break; case 0x04: /* FUCOM STi */ - FPU_FUCOM(TOP,ST(sub)); + FPU_FUCOM(TOP,STV(sub)); break; case 0x05: /*FUCOMP STi */ - FPU_FUCOM(TOP,ST(sub)); + FPU_FUCOM(TOP,STV(sub)); FPU_FPOP(); break; default: @@ -619,8 +563,7 @@ void FPU_ESC5_Normal(Bitu rm) { void FPU_ESC6_EA(Bitu rm,PhysPt addr) { /* 16 bit (word integer) operants */ - Bit16s blah = mem_readw(addr); - fpu.regs[8].d = static_cast(blah); + FPU_FLD_I16(addr,8); EATREE(rm); } @@ -631,34 +574,33 @@ void FPU_ESC6_Normal(Bitu rm) { Bitu sub=(rm & 7); switch(group){ case 0x00: /*FADDP STi,ST*/ - FPU_FADD(ST(sub),TOP); + FPU_FADD(STV(sub),TOP); break; case 0x01: /* FMULP STi,ST*/ - FPU_FMUL(ST(sub),TOP); + FPU_FMUL(STV(sub),TOP); break; case 0x02: /* FCOMP5*/ - FPU_FCOM(TOP,ST(sub)); - break; /* TODO IS THIS ALLRIGHT ????????? */ - case 0x03: /* weird*/ /*FCOMPP*/ - if(sub != 1){ - LOG(LOG_FPU,LOG_WARN)("ESC 6:Unhandled group %d subfunction %d",group,sub); - ; - break; + FPU_FCOM(TOP,STV(sub)); + 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; } - FPU_FCOM(TOP,ST(1)); + FPU_FCOM(TOP,STV(1)); FPU_FPOP(); /* extra pop at the bottom*/ break; case 0x04: /* FSUBRP STi,ST*/ - FPU_FSUBR(ST(sub),TOP); + FPU_FSUBR(STV(sub),TOP); break; case 0x05: /* FSUBP STi,ST*/ - FPU_FSUB(ST(sub),TOP); + FPU_FSUB(STV(sub),TOP); break; case 0x06: /* FDIVRP STi,ST*/ - FPU_FDIVR(ST(sub),TOP); + FPU_FDIVR(STV(sub),TOP); break; case 0x07: /* FDIVP STi,ST*/ - FPU_FDIV(ST(sub),TOP); + FPU_FDIV(STV(sub),TOP); break; default: break; @@ -668,55 +610,39 @@ void FPU_ESC6_Normal(Bitu rm) { void FPU_ESC7_EA(Bitu rm,PhysPt addr) { - /* ROUNDING*/ - Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); switch(group){ case 0x00: /* FILD Bit16s */ - { - Bit16s blah = mem_readw(addr); - FPU_PUSH( static_cast(blah)); - } + FPU_PREP_PUSH(); + FPU_FLD_I16(addr,TOP); break; - case 0x01: /* FISTTP Bit16s */ + case 0x01: LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); break; - case 0x02: /* FIST Bit16s */ - mem_writew(addr,static_cast(FROUND(fpu.regs[TOP].d))); + FPU_FST_I16(addr); break; case 0x03: /* FISTP Bit16s */ - mem_writew(addr,static_cast(FROUND(fpu.regs[TOP].d))); + FPU_FST_I16(addr); FPU_FPOP(); break; + case 0x04: /* FBLD packed BCD */ + FPU_PREP_PUSH(); + FPU_FBLD(addr,TOP); + break; case 0x05: /* FILD Bit64s */ - { - FPU_Reg blah; - blah.l.lower = mem_readd(addr); - blah.l.upper = mem_readd(addr+4); - FPU_PUSH(static_cast(blah.ll)); - } + FPU_PREP_PUSH(); + FPU_FLD_I64(addr,TOP); break; case 0x06: /* FBSTP packed BCD */ FPU_FBST(addr); FPU_FPOP(); break; case 0x07: /* FISTP Bit64s */ - { - FPU_Reg blah; - blah.ll = static_cast(FROUND(fpu.regs[TOP].d)); - mem_writed(addr,blah.l.lower); - mem_writed(addr+4,blah.l.upper); - } + FPU_FST_I64(addr); FPU_FPOP(); break; - case 0x04: /* FBLD packed BCD */ - { - Real64 in = FPU_FBLD(addr); - FPU_PUSH(in); - } - break; default: LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); break; @@ -728,12 +654,12 @@ void FPU_ESC7_Normal(Bitu rm) { Bitu sub=(rm & 7); switch (group){ case 0x01: /* FXCH STi*/ - FPU_FXCH(TOP,ST(sub)); + FPU_FXCH(TOP,STV(sub)); break; case 0x02: /* FSTP STi*/ case 0x03: /* FSTP STi*/ - FPU_FST(TOP,ST(sub)); - FPU_FPOP(); + FPU_FST(TOP,STV(sub)); + FPU_FPOP(); break; case 0x04: switch(sub){ @@ -742,7 +668,7 @@ void FPU_ESC7_Normal(Bitu rm) { reg_ax = fpu.sw; break; default: - LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub); + LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub); break; } break; @@ -750,7 +676,6 @@ void FPU_ESC7_Normal(Bitu rm) { LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub); break; } - } diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 0c094a41..f7dd9fb0 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,26 +16,27 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.26 2005-02-10 10:20:52 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.27 2005-02-22 13:06:06 qbix79 Exp $ */ static void FPU_FINIT(void) { FPU_SetCW(0x37F); - fpu.sw=0; + fpu.sw = 0; TOP=FPU_GET_TOP(); - fpu.tags[0]=TAG_Empty; - fpu.tags[1]=TAG_Empty; - fpu.tags[2]=TAG_Empty; - fpu.tags[3]=TAG_Empty; - fpu.tags[4]=TAG_Empty; - fpu.tags[5]=TAG_Empty; - fpu.tags[6]=TAG_Empty; - fpu.tags[7]=TAG_Empty; - fpu.tags[8]=TAG_Valid; // is only used by us + fpu.tags[0] = TAG_Empty; + fpu.tags[1] = TAG_Empty; + fpu.tags[2] = TAG_Empty; + fpu.tags[3] = TAG_Empty; + fpu.tags[4] = TAG_Empty; + fpu.tags[5] = TAG_Empty; + fpu.tags[6] = TAG_Empty; + fpu.tags[7] = TAG_Empty; + fpu.tags[8] = TAG_Valid; // is only used by us } + static void FPU_FCLEX(void){ - fpu.sw&=0x7f00; //should clear exceptions -}; + fpu.sw &= 0x7f00; //should clear exceptions +} static void FPU_FNOP(void){ return; @@ -44,15 +45,17 @@ static void FPU_FNOP(void){ static void FPU_PUSH(double in){ TOP = (TOP - 1) &7; //actually check if empty - fpu.tags[TOP]=TAG_Valid; - fpu.regs[TOP].d=in; + fpu.tags[TOP] = TAG_Valid; + fpu.regs[TOP].d = in; // LOG(LOG_FPU,LOG_ERROR)("Pushed at %d %g to the stack",newtop,in); return; } -static void FPU_PUSH_ZERO(void){ - FPU_PUSH(0.0); - return; //maybe oneday needed + +static void FPU_PREP_PUSH(void){ + TOP = (TOP - 1) &7; + fpu.tags[TOP] = TAG_Valid; } + static void FPU_FPOP(void){ fpu.tags[TOP]=TAG_Empty; //maybe set zero in it as well @@ -61,6 +64,192 @@ static void FPU_FPOP(void){ return; } +static double FROUND(double in){ + switch(fpu.round){ + case ROUND_Nearest: + if (in-floor(in)>0.5) return (floor(in)+1); + else if (in-floor(in)<0.5) return (floor(in)); + else return (((static_cast(floor(in)))&1)!=0)?(floor(in)+1):(floor(in)); + break; + case ROUND_Down: + return (floor(in)); + break; + case ROUND_Up: + return (ceil(in)); + break; + case ROUND_Chop: + return in; //the cast afterwards will do it right maybe cast here + break; + default: + return in; + break; + } +} + +#define BIAS80 16383 +#define BIAS64 1023 + +static Real64 FPU_FLD80(PhysPt addr) { + struct { + Bit16s begin; + FPU_Reg eind; + } test; + test.eind.l.lower = mem_readd(addr); + test.eind.l.upper = mem_readd(addr+4); + test.begin = mem_readw(addr+8); + + Bit64s exp64 = (((test.begin&0x7fff) - BIAS80)); + Bit64s blah = ((exp64 >0)?exp64:-exp64)&0x3ff; + Bit64s exp64final = ((exp64 >0)?blah:-blah) +BIAS64; + + Bit64s mant64 = (test.eind.ll >> 11) & LONGTYPE(0xfffffffffffff); + Bit64s sign = (test.begin&0x8000)?1:0; + FPU_Reg result; + result.ll = (sign <<63)|(exp64final << 52)| mant64; + return result.d; + + //mant64= test.mant80/2***64 * 2 **53 +} + +static void FPU_ST80(PhysPt addr,Bitu reg) { + struct { + Bit16s begin; + FPU_Reg eind; + } test; + Bit64s sign80 = (fpu.regs[reg].ll&LONGTYPE(0x8000000000000000))?1:0; + Bit64s exp80 = fpu.regs[reg].ll&LONGTYPE(0x7ff0000000000000); + Bit64s exp80final = (exp80>>52) - BIAS64 + BIAS80; + Bit64s mant80 = fpu.regs[reg].ll&LONGTYPE(0x000fffffffffffff); + Bit64s mant80final = (mant80 << 11); + // Elvira wants the 8 and tcalc doesn't + if(fpu.regs[reg].d != 0) mant80final |= LONGTYPE(0x8000000000000000); + test.begin= (static_cast(sign80)<<15)| static_cast(exp80final); + test.eind.ll = mant80final; + mem_writed(addr,test.eind.l.lower); + mem_writed(addr+4,test.eind.l.upper); + mem_writew(addr+8,test.begin); +} + + +static void FPU_FLD_F32(PhysPt addr,Bitu store_to) { + union { + float f; + Bit32u l; + } blah; + blah.l = mem_readd(addr); + fpu.regs[store_to].d = static_cast(blah.f); +} + +static void FPU_FLD_F64(PhysPt addr,Bitu store_to) { + fpu.regs[store_to].l.lower = mem_readd(addr); + fpu.regs[store_to].l.upper = mem_readd(addr+4); +} + +static void FPU_FLD_F80(PhysPt addr) { + fpu.regs[TOP].d = FPU_FLD80(addr); +} + +static void FPU_FLD_I16(PhysPt addr,Bitu store_to) { + Bit16s blah = mem_readw(addr); + fpu.regs[store_to].d = static_cast(blah); +} + +static void FPU_FLD_I32(PhysPt addr,Bitu store_to) { + Bit32s blah = mem_readd(addr); + fpu.regs[store_to].d = static_cast(blah); +} + +static void FPU_FLD_I64(PhysPt addr,Bitu store_to) { + FPU_Reg blah; + blah.l.lower = mem_readd(addr); + blah.l.upper = mem_readd(addr+4); + fpu.regs[store_to].d = static_cast(blah.ll); +} + +static void FPU_FBLD(PhysPt addr,Bitu store_to) { + Bit64u val = 0; + Bitu in = 0; + Bit64u base = 1; + for(Bitu i = 0;i < 9;i++){ + in = mem_readb(addr + i); + val += ( (in&0xf) * base); //in&0xf shouldn't be higher then 9 + base *= 10; + val += ((( in>>4)&0xf) * base); + base *= 10; + } + + //last number, only now convert to float in order to get + //the best signification + Real64 temp = static_cast(val); + in = mem_readb(addr + 9); + temp += ( (in&0xf) * base ); + if(in&0x80) temp *= -1.0; + fpu.regs[store_to].d = temp; +} + +static void FPU_FST_F32(PhysPt addr) { + union { + float f; + Bit32u l; + } blah; + //should depend on rounding method + blah.f = static_cast(fpu.regs[TOP].d); + mem_writed(addr,blah.l); +} + +static void FPU_FST_F64(PhysPt addr) { + mem_writed(addr,fpu.regs[TOP].l.lower); + mem_writed(addr+4,fpu.regs[TOP].l.upper); +} + +static void FPU_FST_F80(PhysPt addr) { + FPU_ST80(addr,TOP); +} + +static void FPU_FST_I16(PhysPt addr) { + mem_writew(addr,static_cast(FROUND(fpu.regs[TOP].d))); +} + +static void FPU_FST_I32(PhysPt addr) { + mem_writed(addr,static_cast(FROUND(fpu.regs[TOP].d))); +} + +static void FPU_FST_I64(PhysPt addr) { + FPU_Reg blah; + blah.ll = static_cast(FROUND(fpu.regs[TOP].d)); + mem_writed(addr,blah.l.lower); + mem_writed(addr+4,blah.l.upper); +} + +static void FPU_FBST(PhysPt addr) { + FPU_Reg val = fpu.regs[TOP]; + bool sign = false; + if(val.d<0.0){ //sign + sign=true; + val.d=-val.d; + } + //numbers from back to front + Real64 temp=val.d; + Bitu p; + for(Bitu i=0;i<9;i++){ + val.d=temp; + temp = static_cast(static_cast(floor(val.d/10.0))); + p = static_cast(val.d - 10.0*temp); + val.d=temp; + temp = static_cast(static_cast(floor(val.d/10.0))); + p |= (static_cast(val.d - 10.0*temp)<<4); + + mem_writeb(addr+i,p); + } + val.d=temp; + temp = static_cast(static_cast(floor(val.d/10.0))); + p = static_cast(val.d - 10.0*temp); + if(sign) + p|=0x80; + mem_writeb(addr+9,p); +} + + static void FPU_FADD(Bitu op1, Bitu op2){ fpu.regs[op1].d+=fpu.regs[op2].d; //flags and such :) @@ -96,9 +285,8 @@ static void FPU_FSQRT(void){ return; } static void FPU_FPATAN(void){ - fpu.regs[ST(1)].d = atan2(fpu.regs[ST(1)].d,fpu.regs[TOP].d); + fpu.regs[STV(1)].d = atan2(fpu.regs[STV(1)].d,fpu.regs[TOP].d); FPU_FPOP(); - FPU_SET_C2(0); //flags and such :) return; } @@ -154,9 +342,9 @@ static void FPU_FST(Bitu st, Bitu other){ } - static void FPU_FCOM(Bitu st, Bitu other){ - if((fpu.tags[st] != TAG_Valid) || (fpu.tags[other] != TAG_Valid)){ + if(((fpu.tags[st] != TAG_Valid) && (fpu.tags[st] != TAG_Zero)) || + ((fpu.tags[other] != TAG_Valid) && (fpu.tags[other] != TAG_Zero))){ FPU_SET_C3(1);FPU_SET_C2(1);FPU_SET_C0(1);return; } if(fpu.regs[st].d == fpu.regs[other].d){ @@ -174,31 +362,14 @@ static void FPU_FUCOM(Bitu st, Bitu other){ FPU_FCOM(st,other); } -static double FROUND(double in){ - switch(fpu.round){ - case ROUND_Nearest: - if (in-floor(in)>0.5) return (floor(in)+1); - else if (in-floor(in)<0.5) return (floor(in)); - else return (((static_cast(floor(in)))&1)!=0)?(floor(in)+1):(floor(in)); - break; - case ROUND_Down: - return (floor(in)); - break; - case ROUND_Up: - return (ceil(in)); - break; - case ROUND_Chop: - return in; //the cast afterwards will do it right maybe cast here - break; - default: - return in; - break; - } +static void FPU_FRNDINT(void){ + Bit64s temp= static_cast(FROUND(fpu.regs[TOP].d)); + fpu.regs[TOP].d=static_cast(temp); } static void FPU_FPREM(void){ Real64 valtop = fpu.regs[TOP].d; - Real64 valdiv = fpu.regs[ST(1)].d; + Real64 valdiv = fpu.regs[STV(1)].d; Bit64s ressaved = static_cast( (valtop/valdiv) ); // Some backups // Real64 res=valtop - ressaved*valdiv; @@ -210,143 +381,71 @@ static void FPU_FPREM(void){ FPU_SET_C2(0); } +static void FPU_FPREM1(void){ + Real64 valtop = fpu.regs[TOP].d; + Real64 valdiv = fpu.regs[STV(1)].d; + double quot = valtop/valdiv; + double quotf = floor(quot); + Bit64s ressaved; + if (quot-quotf>0.5) ressaved = static_cast(quotf+1); + else if (quot-quotf<0.5) ressaved = static_cast(quotf); + else ressaved = static_cast((((static_cast(quotf))&1)!=0)?(quotf+1):(quotf)); + fpu.regs[TOP].d = valtop - ressaved*valdiv; + FPU_SET_C0(static_cast(ressaved&4)); + FPU_SET_C3(static_cast(ressaved&2)); + FPU_SET_C1(static_cast(ressaved&1)); + FPU_SET_C2(0); +} + static void FPU_FXAM(void){ - if(fpu.tags[TOP] == TAG_Empty) - { - FPU_SET_C3(1);FPU_SET_C0(1); - return; - } if(fpu.regs[TOP].ll & LONGTYPE(0x8000000000000000)) //sign { FPU_SET_C1(1); - } - else + } + else { FPU_SET_C1(0); } + if(fpu.tags[TOP] == TAG_Empty) + { + FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(1); + return; + } if(fpu.regs[TOP].d == 0.0) //zero or normalized number. { FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(0); } - else{ + else + { FPU_SET_C3(0);FPU_SET_C2(1);FPU_SET_C0(0); } } -static void FPU_FBST(PhysPt addr) -{ - FPU_Reg val = fpu.regs[TOP]; - bool sign = false; - if(val.d<0.0){ //sign - sign=true; - val.d=-val.d; - } - //numbers from back to front - Real64 temp=val.d; - Bitu p; - for(Bitu i=0;i<9;i++){ - val.d=temp; - temp = static_cast(static_cast(floor(val.d/10.0))); - p = static_cast(val.d - 10.0*temp); - val.d=temp; - temp = static_cast(static_cast(floor(val.d/10.0))); - p |= (static_cast(val.d - 10.0*temp)<<4); - - mem_writeb(addr+i,p); - } - val.d=temp; - temp = static_cast(static_cast(floor(val.d/10.0))); - p = static_cast(val.d - 10.0*temp); - if(sign) - p|=0x80; - mem_writeb(addr+9,p); -} - -static Real64 FPU_FBLD(PhysPt addr) -{ - Bit64u val = 0; - Bitu in = 0; - Bit64u base = 1; - for(Bitu i = 0;i < 9;i++){ - in = mem_readb(addr + i); - val += ( (in&0xf) * base); //in&0xf shouldn't be higher then 9 - base *= 10; - val += ((( in>>4)&0xf) * base); - base *= 10; - } - - //last number, only now convert to float in order to get - //the best signification - Real64 temp = static_cast(val); - in = mem_readb(addr + 9); - temp += ( (in&0xf) * base ); - if(in&0x80) temp *= -1.0; - return temp; -} - - -#define BIAS80 16383 -#define BIAS64 1023 - -static Real64 FPU_FLD80(PhysPt addr) -{ - struct{ - Bit16s begin; - FPU_Reg eind; - } test; - test.eind.l.lower=mem_readd(addr); - test.eind.l.upper =mem_readd(addr+4); - test.begin=mem_readw(addr+8); - - Bit64s exp64= (((test.begin & 0x7fff) - BIAS80)); - Bit64s blah= ((exp64 >0)?exp64:-exp64)&0x3ff; - Bit64s exp64final= ((exp64 >0)?blah:-blah) +BIAS64; - - Bit64s mant64= (test.eind.ll >> 11) & LONGTYPE(0xfffffffffffff); - Bit64s sign = (test.begin &0x8000)?1:0; - FPU_Reg result; - result.ll= (sign <<63)|(exp64final << 52)| mant64; - return result.d; - - //mant64= test.mant80/2***64 * 2 **53 -} - -static void FPU_ST80(PhysPt addr,Bitu reg) -{ - struct{ - Bit16s begin; - FPU_Reg eind; - } test; - Bit64s sign80= (fpu.regs[reg].ll&LONGTYPE(0x8000000000000000))?1:0; - Bit64s exp80 = fpu.regs[reg].ll&LONGTYPE(0x7ff0000000000000); - Bit64s exp80final= (exp80>>52) - BIAS64 + BIAS80; - Bit64s mant80 = fpu.regs[reg].ll&LONGTYPE(0x000fffffffffffff); - Bit64s mant80final= (mant80 << 11); - // Elvira wants the 8 and tcalc doesn't - if(fpu.regs[reg].d != 0) mant80final |= LONGTYPE(0x8000000000000000); - test.begin= (static_cast(sign80)<<15)| static_cast(exp80final); - test.eind.ll=mant80final; - mem_writed(addr,test.eind.l.lower); - mem_writed(addr+4,test.eind.l.upper); - mem_writew(addr+8,test.begin); -} static void FPU_F2XM1(void){ - fpu.regs[TOP].d=pow(2.0,fpu.regs[TOP].d) -1; + fpu.regs[TOP].d = pow(2.0,fpu.regs[TOP].d) - 1; return; } static void FPU_FYL2X(void){ - fpu.regs[ST(1)].d*=log(fpu.regs[TOP].d)/log(static_cast(2.0)); + fpu.regs[STV(1)].d*=log(fpu.regs[TOP].d)/log(static_cast(2.0)); FPU_FPOP(); return; } + +static void FPU_FYL2XP1(void){ + fpu.regs[STV(1)].d*=log(fpu.regs[TOP].d+1.0)/log(static_cast(2.0)); + FPU_FPOP(); + return; +} + static void FPU_FSCALE(void){ - fpu.regs[TOP].d *= pow(2.0,static_cast(static_cast(fpu.regs[ST(1)].d))); + fpu.regs[TOP].d *= pow(2.0,static_cast(static_cast(fpu.regs[STV(1)].d))); return; //2^x where x is chopped. } static void FPU_FSTENV(PhysPt addr){ + FPU_SET_TOP(TOP); if(!cpu.code.big) { mem_writew(addr+0,static_cast(fpu.cw)); mem_writew(addr+2,static_cast(fpu.sw)); @@ -368,29 +467,31 @@ static void FPU_FLDENV(PhysPt addr){ tag = mem_readw(addr+4); } else { cw = mem_readd(addr+0); - fpu.sw = mem_readd(addr+4); + fpu.sw = (Bit16u)mem_readd(addr+4); tagbig = mem_readd(addr+8); tag = static_cast(tagbig); } FPU_SetTag(tag); FPU_SetCW(cw); + TOP = FPU_GET_TOP(); } static void FPU_FSAVE(PhysPt addr){ FPU_FSTENV(addr); - Bitu start=(cpu.code.big?28:14); - for(Bitu i=0;i<8;i++){ - FPU_ST80(addr+start,i); - start+=10; + Bitu start = (cpu.code.big?28:14); + for(Bitu i = 0;i < 8;i++){ + FPU_ST80(addr+start,STV(i)); + start += 10; } + FPU_FINIT(); } -static void FPU_FSTOR(PhysPt addr){ +static void FPU_FRSTOR(PhysPt addr){ FPU_FLDENV(addr); - Bitu start=(cpu.code.big?28:14); - for(Bitu i=0;i<8;i++){ - fpu.regs[i].d=FPU_FLD80(addr+start); - start+=10; + Bitu start = (cpu.code.big?28:14); + for(Bitu i = 0;i < 8;i++){ + fpu.regs[STV(i)].d = FPU_FLD80(addr+start); + start += 10; } } @@ -403,6 +504,55 @@ static void FPU_FXTRACT(void) { Bit64s exp80 = test.ll&LONGTYPE(0x7ff0000000000000); Bit64s exp80final = (exp80>>52) - BIAS64; Real64 mant = test.d / (pow(2.0,static_cast(exp80final))); - fpu.regs[TOP].d=exp80final; + fpu.regs[TOP].d = static_cast(exp80final); FPU_PUSH(mant); } + +static void FPU_FCHS(void){ + fpu.regs[TOP].d = -1.0*(fpu.regs[TOP].d); +} + +static void FPU_FABS(void){ + fpu.regs[TOP].d = fabs(fpu.regs[TOP].d); +} + +static void FPU_FTST(void){ + fpu.regs[8].d = 0.0; + FPU_FCOM(TOP,8); +} + +static void FPU_FLD1(void){ + FPU_PREP_PUSH(); + fpu.regs[TOP].d = 1.0; +} + +static void FPU_FLDL2T(void){ + FPU_PREP_PUSH(); + fpu.regs[TOP].d = L2T; +} + +static void FPU_FLDL2E(void){ + FPU_PREP_PUSH(); + fpu.regs[TOP].d = L2E; +} + +static void FPU_FLDPI(void){ + FPU_PREP_PUSH(); + fpu.regs[TOP].d = PI; +} + +static void FPU_FLDLG2(void){ + FPU_PREP_PUSH(); + fpu.regs[TOP].d = LG2; +} + +static void FPU_FLDLN2(void){ + FPU_PREP_PUSH(); + fpu.regs[TOP].d = LN2; +} + +static void FPU_FLDZ(void){ + FPU_PREP_PUSH(); + fpu.regs[TOP].d = 0.0; + fpu.tags[TOP] = TAG_Zero; +} diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h new file mode 100644 index 00000000..a10cd162 --- /dev/null +++ b/src/fpu/fpu_instructions_x86.h @@ -0,0 +1,864 @@ +/* + * Copyright (C) 2002-2005 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: fpu_instructions_x86.h,v 1.1 2005-02-22 13:06:06 qbix79 Exp $ */ + + +#if defined (_MSC_VER) + +#define FPUD_LOAD(op,szI,szA) \ + Bit16u new_sw; \ + __asm { \ + __asm mov eax, 8 \ + __asm shl eax, 4 \ + __asm mov ebx, store_to \ + __asm shl ebx, 4 \ + __asm fclex \ + __asm op szI PTR fpu.p_regs[eax].m1 \ + __asm fnstsw new_sw \ + __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ + } \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + +#define FPUD_STORE(op,szI,szA) \ + Bit16u new_sw,save_cw; \ + __asm { \ + __asm fnstcw save_cw \ + __asm fldcw fpu.cw_mask_all \ + __asm mov eax, TOP \ + __asm shl eax, 4 \ + __asm mov ebx, 8 \ + __asm shl ebx, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fclex \ + __asm op szI PTR fpu.p_regs[ebx].m1 \ + __asm fnstsw new_sw \ + __asm fldcw save_cw \ + } \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + +// handles fsin,fcos,f2xm1,fchs,fabs +#define FPUD_TRIG(op) \ + Bit16u new_sw; \ + __asm { \ + __asm mov eax, TOP \ + __asm shl eax, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fclex \ + __asm op \ + __asm fnstsw new_sw \ + __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ + } \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + +// handles fsincos +#define FPUD_SINCOS \ + Bit16u new_sw; \ + __asm { \ + __asm mov eax, TOP \ + __asm mov ebx, eax \ + __asm dec ebx \ + __asm and ebx, 7 \ + __asm shl eax, 4 \ + __asm shl ebx, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fclex \ + __asm fsincos \ + __asm fnstsw new_sw \ + __asm mov cx, new_sw \ + __asm and ch, 0x04 \ + __asm jnz argument_too_large1 \ + __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ + __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ + __asm jmp end_sincos \ + __asm argument_too_large1: \ + __asm fstp st(0) \ + __asm end_sincos: \ + } \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ + if ((new_sw&0x0400)==0) FPU_PREP_PUSH(); + +// handles fptan +#define FPUD_PTAN \ + Bit16u new_sw; \ + __asm { \ + __asm mov eax, TOP \ + __asm mov ebx, eax \ + __asm dec ebx \ + __asm and ebx, 7 \ + __asm shl eax, 4 \ + __asm shl ebx, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fclex \ + __asm fptan \ + __asm fnstsw new_sw \ + __asm mov cx, new_sw \ + __asm and ch, 0x04 \ + __asm jnz argument_too_large2 \ + __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ + __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ + __asm jmp end_ptan \ + __asm argument_too_large2: \ + __asm fstp st(0) \ + __asm end_ptan: \ + } \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ + if ((new_sw&0x0400)==0) FPU_PREP_PUSH(); + +// handles fxtract +#define FPUD_XTRACT \ + Bit16u new_sw; \ + __asm { \ + __asm mov eax, TOP \ + __asm mov ebx, eax \ + __asm dec ebx \ + __asm and ebx, 7 \ + __asm shl eax, 4 \ + __asm shl ebx, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fclex \ + __asm fxtract \ + __asm fnstsw new_sw \ + __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ + __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ + } \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ + FPU_PREP_PUSH(); + +// handles fadd,fmul,fsub,fsubr,fdiv,fdivr +#define FPUD_ARITH1(op) \ + Bit16u new_sw,save_cw; \ + __asm { \ + __asm fnstcw save_cw \ + __asm fldcw fpu.cw_mask_all \ + __asm mov eax, op1 \ + __asm shl eax, 4 \ + __asm mov ebx, op2 \ + __asm shl ebx, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ + __asm fclex \ + __asm op st(1), st(0) \ + __asm fnstsw new_sw \ + __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fldcw save_cw \ + } \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + +// handles fsqrt,frndint +#define FPUD_ARITH2(op) \ + Bit16u new_sw,save_cw; \ + __asm { \ + __asm fnstcw save_cw \ + __asm fldcw fpu.cw_mask_all \ + __asm mov eax, TOP \ + __asm shl eax, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fclex \ + __asm op \ + __asm fnstsw new_sw \ + __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fldcw save_cw \ + } \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + +// handles fprem,fprem1,fscale +#define FPUD_REMINDER(op) \ + Bit16u new_sw; \ + __asm { \ + __asm mov eax, TOP \ + __asm mov ebx, eax \ + __asm inc ebx \ + __asm and ebx, 7 \ + __asm shl ebx, 4 \ + __asm shl eax, 4 \ + __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fclex \ + __asm op \ + __asm fnstsw new_sw \ + __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fstp st(0) \ + } \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + +// handles fcom,fucom +#define FPUD_COMPARE(op) \ + Bit16u new_sw; \ + __asm { \ + __asm mov ebx, op2 \ + __asm shl ebx, 4 \ + __asm mov eax, op1 \ + __asm shl eax, 4 \ + __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fclex \ + __asm op \ + __asm fnstsw new_sw \ + } \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + +// handles fxam,ftst +#define FPUD_EXAMINE(op) \ + Bit16u new_sw; \ + __asm { \ + __asm mov eax, TOP \ + __asm shl eax, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fclex \ + __asm op \ + __asm fnstsw new_sw \ + __asm fstp st(0) \ + } \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + +// handles fpatan,fyl2x,fyl2xp1 +#define FPUD_WITH_POP(op) \ + Bit16u new_sw; \ + __asm { \ + __asm mov eax, TOP \ + __asm mov ebx, eax \ + __asm inc ebx \ + __asm and ebx, 7 \ + __asm shl ebx, 4 \ + __asm shl eax, 4 \ + __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fclex \ + __asm op \ + __asm fnstsw new_sw \ + __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ + } \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ + FPU_FPOP(); + +// load math constants +#define FPUD_LOAD_CONST(op) \ + Bit16u new_sw; \ + FPU_PREP_PUSH(); \ + __asm { \ + __asm mov eax, TOP \ + __asm shl eax, 4 \ + __asm fclex \ + __asm op \ + __asm fnstsw new_sw \ + __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ + } \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + +#else + +#define FPUD_LOAD(op,szI,szA) \ + Bit16u new_sw; \ + __asm__ volatile ( \ + "movl $8, %%eax \n" \ + "shl $4, %%eax \n" \ + "shl $4, %1 \n" \ + "fclex \n" \ + #op #szA " (%2, %%eax) \n" \ + "fnstsw %0 \n" \ + "fstpt (%2, %1) " \ + : "=m" (new_sw) \ + : "r" (store_to), "r" (fpu.p_regs) \ + : "eax", "memory" \ + ); \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + +#define FPUD_STORE(op,szI,szA) \ + Bit16u new_sw,save_cw; \ + __asm__ volatile ( \ + "fnstcw %1 \n" \ + "fldcw %4 \n" \ + "shll $4, %2 \n" \ + "movl $8, %%eax \n" \ + "shl $4, %%eax \n" \ + "fldt (%3, %2) \n" \ + "fclex \n" \ + #op #szA " (%3, %%eax) \n" \ + "fnstsw %0 \n" \ + "fldcw %1 " \ + : "=m" (new_sw), "=m" (save_cw) \ + : "r" (TOP), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ + : "eax", "memory" \ + ); \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + +// handles fsin,fcos,f2xm1,fchs,fabs +#define FPUD_TRIG(op) \ + Bit16u new_sw; \ + __asm__ volatile ( \ + "shll $4, %1 \n" \ + "fldt (%2, %1) \n" \ + "fclex \n" \ + #op" \n" \ + "fnstsw %0 \n" \ + "fstpt (%2, %1) " \ + : "=m" (new_sw) \ + : "r" (TOP), "r" (fpu.p_regs) \ + : "memory" \ + ); \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + +// handles fsincos +#define FPUD_SINCOS \ + Bit16u new_sw; \ + __asm__ volatile ( \ + "movl %1, %%eax \n" \ + "shll $4, %1 \n" \ + "decl %%eax \n" \ + "andl $7, %%eax \n" \ + "shll $4, %%eax \n" \ + "fldt (%2, %1) \n" \ + "fclex \n" \ + "fsincos \n" \ + "fnstsw %0 \n" \ + "fstpt (%2, %%eax) \n" \ + "movw %0, %%ax \n" \ + "sahf \n" \ + "jp argument_too_large1 \n" \ + "fstpt (%2, %1) \n" \ + "argument_too_large1: " \ + : "=m" (new_sw) \ + : "r" (TOP), "r" (fpu.p_regs) \ + : "eax", "cc", "memory" \ + ); \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ + if ((new_sw&0x0400)==0) FPU_PREP_PUSH(); + +// handles fptan +#define FPUD_PTAN \ + Bit16u new_sw; \ + __asm__ volatile ( \ + "movl %1, %%eax \n" \ + "shll $4, %1 \n" \ + "decl %%eax \n" \ + "andl $7, %%eax \n" \ + "shll $4, %%eax \n" \ + "fldt (%2, %1) \n" \ + "fclex \n" \ + "fptan \n" \ + "fnstsw %0 \n" \ + "fstpt (%2, %%eax) \n" \ + "movw %0, %%ax \n" \ + "sahf \n" \ + "jp argument_too_large2 \n" \ + "fstpt (%2, %1) \n" \ + "argument_too_large2: " \ + : "=m" (new_sw) \ + : "r" (TOP), "r" (fpu.p_regs) \ + : "eax", "cc", "memory" \ + ); \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ + if ((new_sw&0x0400)==0) FPU_PREP_PUSH(); + +// handles fxtract +#define FPUD_XTRACT \ + Bit16u new_sw; \ + __asm__ volatile ( \ + "movl %1, %%eax \n" \ + "shll $4, %1 \n" \ + "decl %%eax \n" \ + "andl $7, %%eax \n" \ + "shll $4, %%eax \n" \ + "fldt (%2, %1) \n" \ + "fclex \n" \ + "fxtract \n" \ + "fnstsw %0 \n" \ + "fstpt (%2, %%eax) \n" \ + "fstpt (%2, %1) " \ + : "=m" (new_sw) \ + : "r" (TOP), "r" (fpu.p_regs) \ + : "eax", "memory" \ + ); \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ + FPU_PREP_PUSH(); + +// handles fadd,fmul,fsub,fsubr,fdiv,fdivr +#define FPUD_ARITH1(op) \ + Bit16u new_sw,save_cw; \ + __asm__ volatile ( \ + "fnstcw %1 \n" \ + "fldcw %5 \n" \ + "shll $4, %3 \n" \ + "shll $4, %2 \n" \ + "fldt (%4, %3) \n" \ + "fldt (%4, %2) \n" \ + "fclex \n" \ + #op" \n" \ + "fnstsw %0 \n" \ + "fstpt (%4, %2) \n" \ + "fldcw %1 " \ + : "=m" (new_sw), "=m" (save_cw) \ + : "r" (op1), "r" (op2), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ + : "memory" \ + ); \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + +// handles fsqrt,frndint +#define FPUD_ARITH2(op) \ + Bit16u new_sw,save_cw; \ + __asm__ volatile ( \ + "fnstcw %1 \n" \ + "fldcw %4 \n" \ + "shll $4, %2 \n" \ + "fldt (%3, %2) \n" \ + "fclex \n" \ + #op" \n" \ + "fnstsw %0 \n" \ + "fstpt (%3, %2) \n" \ + "fldcw %1 " \ + : "=m" (new_sw), "=m" (save_cw) \ + : "r" (TOP), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ + : "memory" \ + ); \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + +// handles fprem,fprem1,fscale +#define FPUD_REMINDER(op) \ + Bit16u new_sw; \ + __asm__ volatile ( \ + "movl %1, %%eax \n" \ + "incl %%eax \n" \ + "andl $7, %%eax \n" \ + "shll $4, %%eax \n" \ + "shll $4, %1 \n" \ + "fldt (%2, %%eax) \n" \ + "fldt (%2, %1) \n" \ + "fclex \n" \ + #op" \n" \ + "fnstsw %0 \n" \ + "fstpt (%2, %1) \n" \ + "fstp %%st(0) " \ + : "=m" (new_sw) \ + : "r" (TOP), "r" (fpu.p_regs) \ + : "eax", "memory" \ + ); \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + +// handles fcom,fucom +#define FPUD_COMPARE(op) \ + Bit16u new_sw; \ + __asm__ volatile ( \ + "shll $4, %2 \n" \ + "shll $4, %1 \n" \ + "fldt (%3, %2) \n" \ + "fldt (%3, %1) \n" \ + "fclex \n" \ + #op" \n" \ + "fnstsw %0 " \ + : "=m" (new_sw) \ + : "r" (op1), "r" (op2), "r" (fpu.p_regs) \ + : "memory" \ + ); \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + +// handles fxam,ftst +#define FPUD_EXAMINE(op) \ + Bit16u new_sw; \ + __asm__ volatile ( \ + "shll $4, %1 \n" \ + "fldt (%2, %1) \n" \ + "fclex \n" \ + #op" \n" \ + "fnstsw %0 \n" \ + "fstp %%st(0) " \ + : "=m" (new_sw) \ + : "r" (TOP), "r" (fpu.p_regs) \ + : "memory" \ + ); \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + +// handles fpatan,fyl2x,fyl2xp1 +#define FPUD_WITH_POP(op) \ + Bit16u new_sw; \ + __asm__ volatile ( \ + "movl %1, %%eax \n" \ + "incl %%eax \n" \ + "andl $7, %%eax \n" \ + "shll $4, %%eax \n" \ + "shll $4, %1 \n" \ + "fldt (%2, %%eax) \n" \ + "fldt (%2, %1) \n" \ + "fclex \n" \ + #op" \n" \ + "fnstsw %0 \n" \ + "fstpt (%2, %%eax) \n" \ + : "=m" (new_sw) \ + : "r" (TOP), "r" (fpu.p_regs) \ + : "eax", "memory" \ + ); \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ + FPU_FPOP(); + +// load math constants +#define FPUD_LOAD_CONST(op) \ + Bit16u new_sw; \ + FPU_PREP_PUSH(); \ + __asm__ volatile ( \ + "shll $4, %1 \n" \ + "fclex \n" \ + #op" \n" \ + "fnstsw %0 \n" \ + "fstpt (%2, %1) \n" \ + : "=m" (new_sw) \ + : "r" (TOP), "r" (fpu.p_regs) \ + : "memory" \ + ); \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ + +#endif + +static void FPU_FINIT(void) { + FPU_SetCW(0x37F); + fpu.sw=0; + TOP=FPU_GET_TOP(); + fpu.tags[0]=TAG_Empty; + fpu.tags[1]=TAG_Empty; + fpu.tags[2]=TAG_Empty; + fpu.tags[3]=TAG_Empty; + fpu.tags[4]=TAG_Empty; + fpu.tags[5]=TAG_Empty; + fpu.tags[6]=TAG_Empty; + fpu.tags[7]=TAG_Empty; + fpu.tags[8]=TAG_Valid; // is only used by us +} + +static void FPU_FCLEX(void){ + fpu.sw&=0x7f00; //should clear exceptions +} + +static void FPU_FNOP(void){ +} + +static void FPU_PREP_PUSH(void){ + TOP = (TOP - 1) &7; + fpu.tags[TOP]=TAG_Valid; +} + +static void FPU_FPOP(void){ + fpu.tags[TOP]=TAG_Empty; + TOP = ((TOP+1)&7); +} + +static void FPU_FLD_F32(PhysPt addr,Bitu store_to) { + fpu.p_regs[8].m1 = mem_readd(addr); + FPUD_LOAD(fld,DWORD,s) +} + +static void FPU_FLD_F64(PhysPt addr,Bitu store_to) { + fpu.p_regs[8].m1 = mem_readd(addr); + fpu.p_regs[8].m2 = mem_readd(addr+4); + FPUD_LOAD(fld,QWORD,l) +} + +static void FPU_FLD_F80(PhysPt addr) { + fpu.p_regs[TOP].m1 = mem_readd(addr); + fpu.p_regs[TOP].m2 = mem_readd(addr+4); + fpu.p_regs[TOP].m3 = mem_readw(addr+8); + FPU_SET_C1(0); +} + +static void FPU_FLD_I16(PhysPt addr,Bitu store_to) { + fpu.p_regs[8].m1 = (Bit32u)mem_readw(addr); + FPUD_LOAD(fild,WORD,) +} + +static void FPU_FLD_I32(PhysPt addr,Bitu store_to) { + fpu.p_regs[8].m1 = mem_readd(addr); + FPUD_LOAD(fild,DWORD,l) +} + +static void FPU_FLD_I64(PhysPt addr,Bitu store_to) { + fpu.p_regs[8].m1 = mem_readd(addr); + fpu.p_regs[8].m2 = mem_readd(addr+4); + FPUD_LOAD(fild,QWORD,q) +} + +static void FPU_FBLD(PhysPt addr,Bitu store_to) { + fpu.p_regs[8].m1 = mem_readd(addr); + fpu.p_regs[8].m2 = mem_readd(addr+4); + fpu.p_regs[8].m3 = mem_readw(addr+8); + FPUD_LOAD(fbld,TBYTE,) +} + +static void FPU_FST_F32(PhysPt addr) { + FPUD_STORE(fstp,DWORD,s) + mem_writed(addr,fpu.p_regs[8].m1); +} + +static void FPU_FST_F64(PhysPt addr) { + FPUD_STORE(fstp,QWORD,l) + mem_writed(addr,fpu.p_regs[8].m1); + mem_writed(addr+4,fpu.p_regs[8].m2); +} + +static void FPU_FST_F80(PhysPt addr) { + mem_writed(addr,fpu.p_regs[TOP].m1); + mem_writed(addr+4,fpu.p_regs[TOP].m2); + mem_writew(addr+8,fpu.p_regs[TOP].m3); + FPU_SET_C1(0); +} + +static void FPU_FST_I16(PhysPt addr) { + FPUD_STORE(fistp,WORD,) + mem_writew(addr,(Bit16u)fpu.p_regs[8].m1); +} + +static void FPU_FST_I32(PhysPt addr) { + FPUD_STORE(fistp,DWORD,l) + mem_writed(addr,fpu.p_regs[8].m1); +} + +static void FPU_FST_I64(PhysPt addr) { + FPUD_STORE(fistp,QWORD,q) + mem_writed(addr,fpu.p_regs[8].m1); + mem_writed(addr+4,fpu.p_regs[8].m2); +} + +static void FPU_FBST(PhysPt addr) { + FPUD_STORE(fbstp,TBYTE,) + mem_writed(addr,fpu.p_regs[8].m1); + mem_writed(addr+4,fpu.p_regs[8].m2); + mem_writew(addr+8,fpu.p_regs[8].m3); +} + + +static void FPU_FSIN(void){ + FPUD_TRIG(fsin) +} + +static void FPU_FSINCOS(void){ + FPUD_SINCOS +} + +static void FPU_FCOS(void){ + FPUD_TRIG(fcos) +} + +static void FPU_FSQRT(void){ + FPUD_ARITH2(fsqrt) +} + +static void FPU_FPATAN(void){ + FPUD_WITH_POP(fpatan) +} + +static void FPU_FPTAN(void){ + FPUD_PTAN +} + + +static void FPU_FADD(Bitu op1, Bitu op2){ + FPUD_ARITH1(faddp) +} + +static void FPU_FDIV(Bitu op1, Bitu op2){ + FPUD_ARITH1(fdivp) +} + +static void FPU_FDIVR(Bitu op1, Bitu op2){ + FPUD_ARITH1(fdivrp) +} + +static void FPU_FMUL(Bitu op1, Bitu op2){ + FPUD_ARITH1(fmulp) +} + +static void FPU_FSUB(Bitu op1, Bitu op2){ + FPUD_ARITH1(fsubp) +} + +static void FPU_FSUBR(Bitu op1, Bitu op2){ + FPUD_ARITH1(fsubrp) +} + +static void FPU_FXCH(Bitu stv, Bitu other){ + FPU_Tag tag = fpu.tags[other]; + fpu.tags[other] = fpu.tags[stv]; + fpu.tags[stv] = tag; + + Bit32u m1s = fpu.p_regs[other].m1; + Bit32u m2s = fpu.p_regs[other].m2; + Bit16u m3s = fpu.p_regs[other].m3; + fpu.p_regs[other].m1 = fpu.p_regs[stv].m1; + fpu.p_regs[other].m2 = fpu.p_regs[stv].m2; + fpu.p_regs[other].m3 = fpu.p_regs[stv].m3; + fpu.p_regs[stv].m1 = m1s; + fpu.p_regs[stv].m2 = m2s; + fpu.p_regs[stv].m3 = m3s; + + FPU_SET_C1(0); +} + +static void FPU_FST(Bitu stv, Bitu other){ + fpu.tags[other] = fpu.tags[stv]; + + fpu.p_regs[other].m1 = fpu.p_regs[stv].m1; + fpu.p_regs[other].m2 = fpu.p_regs[stv].m2; + fpu.p_regs[other].m3 = fpu.p_regs[stv].m3; + + FPU_SET_C1(0); +} + + +static void FPU_FCOM(Bitu op1, Bitu op2){ + FPUD_COMPARE(fcompp) +} + +static void FPU_FUCOM(Bitu op1, Bitu op2){ + FPUD_COMPARE(fucompp) +} + +static void FPU_FRNDINT(void){ + FPUD_ARITH2(frndint) +} + +static void FPU_FPREM(void){ + FPUD_REMINDER(fprem) +} + +static void FPU_FPREM1(void){ + FPUD_REMINDER(fprem1) +} + +static void FPU_FXAM(void){ + FPUD_EXAMINE(fxam) + // handle empty registers (C1 set to sign in any way!) + if(fpu.tags[TOP] == TAG_Empty) { + FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(1); + return; + } +} + +static void FPU_F2XM1(void){ + FPUD_TRIG(f2xm1) +} + +static void FPU_FYL2X(void){ + FPUD_WITH_POP(fyl2x) +} + +static void FPU_FYL2XP1(void){ + FPUD_WITH_POP(fyl2xp1) +} + +static void FPU_FSCALE(void){ + FPUD_REMINDER(fscale) +} + + +static void FPU_FSTENV(PhysPt addr){ + FPU_SET_TOP(TOP); + if(!cpu.code.big) { + mem_writew(addr+0,static_cast(fpu.cw)); + mem_writew(addr+2,static_cast(fpu.sw)); + mem_writew(addr+4,static_cast(FPU_GetTag())); + } else { + mem_writed(addr+0,static_cast(fpu.cw)); + mem_writed(addr+4,static_cast(fpu.sw)); + mem_writed(addr+8,static_cast(FPU_GetTag())); + } +} + +static void FPU_FLDENV(PhysPt addr){ + Bit16u tag; + Bit32u tagbig; + Bitu cw; + if(!cpu.code.big) { + cw = mem_readw(addr+0); + fpu.sw = mem_readw(addr+2); + tag = mem_readw(addr+4); + } else { + cw = mem_readd(addr+0); + fpu.sw = (Bit16u)mem_readd(addr+4); + tagbig = mem_readd(addr+8); + tag = static_cast(tagbig); + } + FPU_SetTag(tag); + FPU_SetCW(cw); + TOP=FPU_GET_TOP(); +} + +static void FPU_FSAVE(PhysPt addr){ + FPU_FSTENV(addr); + Bitu start=(cpu.code.big?28:14); + for(Bitu i=0;i<8;i++){ + mem_writed(addr+start,fpu.p_regs[STV(i)].m1); + mem_writed(addr+start+4,fpu.p_regs[STV(i)].m2); + mem_writew(addr+start+8,fpu.p_regs[STV(i)].m3); + start+=10; + } + FPU_FINIT(); +} + +static void FPU_FRSTOR(PhysPt addr){ + FPU_FLDENV(addr); + Bitu start=(cpu.code.big?28:14); + for(Bitu i=0;i<8;i++){ + fpu.p_regs[STV(i)].m1 = mem_readd(addr+start); + fpu.p_regs[STV(i)].m2 = mem_readd(addr+start+4); + fpu.p_regs[STV(i)].m3 = mem_readw(addr+start+8); + start+=10; + } +} + + +static void FPU_FXTRACT(void) { + FPUD_XTRACT +} + +static void FPU_FCHS(void){ + FPUD_TRIG(fchs) +} + +static void FPU_FABS(void){ + FPUD_TRIG(fabs) +} + +static void FPU_FTST(void){ + FPUD_EXAMINE(ftst) +} + +static void FPU_FLD1(void){ + FPUD_LOAD_CONST(fld1) +} + +static void FPU_FLDL2T(void){ + FPUD_LOAD_CONST(fldl2t) +} + +static void FPU_FLDL2E(void){ + FPUD_LOAD_CONST(fldl2e) +} + +static void FPU_FLDPI(void){ + FPUD_LOAD_CONST(fldpi) +} + +static void FPU_FLDLG2(void){ + FPUD_LOAD_CONST(fldlg2) +} + +static void FPU_FLDLN2(void){ + FPUD_LOAD_CONST(fldln2) +} + +static void FPU_FLDZ(void){ + FPUD_LOAD_CONST(fldz) + fpu.tags[TOP]=TAG_Zero; +} diff --git a/src/fpu/fpu_types.h b/src/fpu/fpu_types.h index eeb0ddf9..3a4ac2fe 100644 --- a/src/fpu/fpu_types.h +++ b/src/fpu/fpu_types.h @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: fpu_types.h,v 1.12 2005-02-22 13:06:06 qbix79 Exp $ */ typedef union { double d; #ifndef WORDS_BIGENDIAN @@ -32,6 +33,15 @@ typedef union { 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, @@ -39,13 +49,13 @@ enum FPU_Tag { TAG_Empty = 3 }; - enum FPU_Round { ROUND_Nearest = 0, ROUND_Down = 1, ROUND_Up = 2, ROUND_Chop = 3 }; + //get pi from a real library #define PI 3.14159265358979323846 #define L2E 1.4426950408889634 diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index d31afd04..d9e66c87 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -33,6 +33,9 @@ /* Enable the FPU module, still only for beta testing */ #define C_FPU 1 +/* Define to 1 to use a x86 assembly fpu core */ +#define C_FPU_X86 1 + /* environ is defined */ #define ENVIRON_INCLUDED 1 diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index a01dc422..306f9f76 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -639,6 +639,10 @@ SOURCE=..\src\fpu\fpu_instructions.h # End Source File # Begin Source File +SOURCE=..\src\fpu\fpu_instructions_x86.h +# End Source File +# Begin Source File + SOURCE=..\src\fpu\fpu_types.h # End Source File # End Group diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index f397a0f1..cf873eaf 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -657,6 +657,9 @@ RelativePath="..\src\fpu\fpu_instructions.h"> + RelativePath="..\src\fpu\fpu_types.h"> From fcad77e2cbb02bc72e47d99dc8419d2894f677c2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 22 Feb 2005 15:18:14 +0000 Subject: [PATCH 2030/4131] Typo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2114 --- visualc_net/dosbox.vcproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index cf873eaf..7fec8a92 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -656,10 +656,10 @@ - + From b5d98a5162f865312af3464abbb429025082667c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Feb 2005 11:29:26 +0000 Subject: [PATCH 2031/4131] Fixed redirect filehandle (force duplicate). Has this function ever worked ? Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2115 --- src/dos/dos_files.cpp | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 63017afb..aa2a0d86 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.60 2005-02-10 10:20:51 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.61 2005-02-24 11:29:26 qbix79 Exp $ */ #include #include @@ -558,14 +558,12 @@ bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry) { }; bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry) { - // Dont duplicate console handles -/* if (entry<=STDPRN) { - newentry = entry; - return true; - }; -*/ - Bit8u orig=RealHandle(entry); - if (orig>=DOS_FILES) { + if(entry == newentry) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + } + Bit8u orig = RealHandle(entry); + if (orig >= DOS_FILES) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; @@ -573,18 +571,13 @@ bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; - Bit8u newone=RealHandle(newentry); - if (newone>=DOS_FILES) { - DOS_SetError(DOSERR_INVALID_HANDLE); - return false; - }; - if (Files[newone]) { + Bit8u newone = RealHandle(newentry); + if (newone < DOS_FILES && Files[newone]) { DOS_CloseFile(newentry); - return false; - }; + } DOS_PSP psp(dos.psp()); Files[orig]->AddRef(); - psp.SetFileHandle(newentry,(Bit8u)entry); + psp.SetFileHandle(newentry,orig); return true; }; @@ -1034,8 +1027,3 @@ void DOS_SetupFiles (void) { } Drives[25]=new Virtual_Drive(); } - - - - - From 351f5bab081e15e658ee7ad226993c0350cef105 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Feb 2005 11:35:32 +0000 Subject: [PATCH 2032/4131] force duplicate uses reg_cx instead of ax Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2116 --- src/dos/dos.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 73cabafd..259b7bd5 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.81 2005-02-10 10:20:50 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.82 2005-02-24 11:35:32 qbix79 Exp $ */ #include #include @@ -563,7 +563,8 @@ static Bitu DOS_21Handler(void) { } break; case 0x46: /* DUP2,FORCEDUP Force duplicate file handle */ - if (DOS_ForceDuplicateEntry(reg_bx,reg_ax)) { + if (DOS_ForceDuplicateEntry(reg_bx,reg_cx)) { + reg_ax=reg_cx; //Not all sources agree on it. CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; From 8beb996996fa21729265e9dcb2161412ec9ced77 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Feb 2005 11:48:01 +0000 Subject: [PATCH 2033/4131] Change filetable to 01 01 01 00 02. Fixes some bugs in DN Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2117 --- src/shell/shell.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index bd94191c..7bb39b94 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.55 2005-02-10 10:21:12 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.56 2005-02-24 11:48:01 qbix79 Exp $ */ #include #include @@ -400,12 +400,21 @@ void SHELL_Init() { DOS_PSP psp(psp_seg); psp.MakeNew(0); dos.psp(psp_seg); + + /* The start of the filetable in the psp must look like this: + * 01 01 01 00 02 + * In order to achieve this: First open 2 files. Close the first and + * duplicate the second (so the entries get 01) */ Bit16u dummy=0; DOS_OpenFile("CON",2,&dummy);/* STDIN */ DOS_OpenFile("CON",2,&dummy);/* STDOUT */ - DOS_OpenFile("CON",2,&dummy);/* STDERR */ + DOS_CloseFile(0); /* Close STDIN */ + DOS_ForceDuplicateEntry(1,0);/* "new" STDIN */ + DOS_ForceDuplicateEntry(1,2);/* STDERR */ +// DOS_OpenFile("CON",2,&dummy);/* STDERR */ DOS_OpenFile("CON",2,&dummy);/* STDAUX */ DOS_OpenFile("CON",2,&dummy);/* STDPRN */ + psp.SetParent(psp_seg); /* Set the environment */ psp.SetEnvironment(env_seg); From b91563ec450b992a08b449f26f460ab84c60d052 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Feb 2005 17:51:00 +0000 Subject: [PATCH 2034/4131] Date and time patch #1117179 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2118 --- src/hardware/cmos.cpp | 11 +++++++---- src/ints/bios.cpp | 25 +++++++++++++------------ 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 7319e6ec..8d51aa41 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -71,6 +71,7 @@ static void cmos_writereg(Bitu port,Bitu val,Bitu iolen) { case 0x07: /* Date of month */ case 0x08: /* Month */ case 0x09: /* Year */ + case 0x32: /* Century */ /* Ignore writes to change alarm */ break; case 0x01: /* Seconds Alarm */ @@ -102,7 +103,7 @@ static void cmos_writereg(Bitu port,Bitu val,Bitu iolen) { } -#define MAKE_RETURN(_VAL) (cmos.bcd ? (((_VAL / 10) << 4) | (_VAL % 10)) : _VAL); +#define MAKE_RETURN(_VAL) (cmos.bcd ? ((((_VAL) / 10) << 4) | ((_VAL) % 10)) : (_VAL)); static Bitu cmos_readreg(Bitu port,Bitu iolen) { if (cmos.reg>0x3f) { @@ -128,13 +129,15 @@ static Bitu cmos_readreg(Bitu port,Bitu iolen) { case 0x04: /* Hours */ return MAKE_RETURN(loctime->tm_hour); case 0x06: /* Day of week */ - return MAKE_RETURN(loctime->tm_wday); + return MAKE_RETURN(loctime->tm_wday + 1); case 0x07: /* Date of month */ return MAKE_RETURN(loctime->tm_mday); case 0x08: /* Month */ - return MAKE_RETURN(loctime->tm_mon); + return MAKE_RETURN(loctime->tm_mon + 1); case 0x09: /* Year */ - return MAKE_RETURN(loctime->tm_year); + return MAKE_RETURN(loctime->tm_year % 100); + case 0x32: /* Century */ + return MAKE_RETURN(loctime->tm_year / 100 + 19); case 0x01: /* Seconds Alarm */ case 0x03: /* Minutes Alarm */ case 0x05: /* Hours Alarm */ diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 9f5f8fac..ca8d2987 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.39 2005-02-10 10:21:11 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.40 2005-02-24 17:50:58 qbix79 Exp $ */ #include #include "dosbox.h" @@ -79,19 +79,20 @@ static Bitu INT1A_Handler(void) { reg_cl=IO_Read(0x71); IO_Write(0x70,0x00); //Seconds reg_dh=IO_Read(0x71); - reg_dl=0; //Daylight saving disabled + reg_dl=0; //Daylight saving disabled + CALLBACK_SCF(false); + break; + case 0x04: /* GET REAL-TIME ClOCK DATE (AT,XT286,PS) */ + IO_Write(0x70,0x32); //Centuries + reg_ch=IO_Read(0x71); + IO_Write(0x70,0x09); //Years + reg_cl=IO_Read(0x71); + IO_Write(0x70,0x08); //Months + reg_dh=IO_Read(0x71); + IO_Write(0x70,0x07); //Days + reg_dl=IO_Read(0x71); CALLBACK_SCF(false); break; - case 0x04: /* GET REAL-TIME ClOCK DATA (AT,XT286,PS) */ - reg_dx=0; - reg_cx=0x2003; - CALLBACK_SCF(false); - LOG(LOG_BIOS,LOG_ERROR)("INT1A:04:Faked RTC get date call"); - break; -// reg_dx=reg_cx=0; -// CALLBACK_SCF(false); -// LOG(LOG_BIOS,LOG_ERROR)("INT1A:04:Faked RTC get date call"); -// break; case 0x80: /* Pcjr Setup Sound Multiplexer */ LOG(LOG_BIOS,LOG_ERROR)("INT1A:80:Setup tandy sound multiplexer to %d",reg_al); break; From a2d910404ea5d32a684262556088a19fcac00da2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Feb 2005 18:24:33 +0000 Subject: [PATCH 2035/4131] add support for get code from Pinterface (thanks wd) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2119 --- src/ints/int10.cpp | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 3315d909..c3af071d 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -400,11 +400,36 @@ graphics_chars: reg_ah=0x01; } break; - case 0x0a: /* Get Pmode Inteface */ - reg_edi=RealOff(int10.rom.pmode_interface); - SegSet16(es,RealSeg(int10.rom.pmode_interface)); - reg_cx=int10.rom.pmode_interface_size; - reg_ax=0x004f; + case 0x0a: /* Get Pmode Interface */ + switch (reg_bl) { + case 0x00: + reg_edi=RealOff(int10.rom.pmode_interface); + SegSet16(es,RealSeg(int10.rom.pmode_interface)); + reg_cx=int10.rom.pmode_interface_size; + reg_ax=0x004f; + break; + case 0x01: /* Get code for "set bank" */ + reg_edi=RealOff(int10.rom.pmode_interface)+0x08; + SegSet16(es,RealSeg(int10.rom.pmode_interface)); + reg_cx=0x0b; + reg_ax=0x004f; + break; + case 0x02: /* Get code for "set display start" */ + reg_edi=RealOff(int10.rom.pmode_interface)+0x19; + SegSet16(es,RealSeg(int10.rom.pmode_interface)); + reg_cx=0x3e; + reg_ax=0x004f; + break; + case 0x03: /* Get code for "set pallete" */ + reg_edi=RealOff(int10.rom.pmode_interface)+0x57; + SegSet16(es,RealSeg(int10.rom.pmode_interface)); + reg_cx=0x37; + reg_ax=0x004f; + break; + default: + reg_ax=0x014f; + break; + } break; default: From b333849e49026f297c12d2d229e4dc10c6cfaeb6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Feb 2005 20:14:57 +0000 Subject: [PATCH 2036/4131] disable the hiding of the mousecursor videomode setting. (fixes ida) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2120 --- src/ints/mouse.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index a955de88..68b50767 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.45 2005-02-10 10:21:11 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.46 2005-02-24 20:14:57 qbix79 Exp $ */ #include #include @@ -506,7 +506,7 @@ void Mouse_NewVideoMode(void) } else { real_writed(0,((0x8+MOUSE_IRQ)<<2),CALLBACK_RealPointer(call_int74)); } - mouse.shown=-1; +// mouse.shown=-1;//Disabled as ida doesn't have mousecursor anymore /* Get the correct resolution from the current video mode */ Bitu mode=mem_readb(BIOS_VIDEO_MODE); switch (mode) { From adc44912ef9f122f759bd33df641ec043fbebee1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 1 Mar 2005 07:19:38 +0000 Subject: [PATCH 2037/4131] added patch 1121865 from moe (fixes crashes when mixing regular and imgmount cdroms) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2121 --- src/dos/dos_programs.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 62f61a9b..6e8719a8 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.34 2005-02-10 10:20:51 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.35 2005-03-01 07:19:38 qbix79 Exp $ */ #include #include @@ -597,6 +597,7 @@ public: newdrive=new fatDrive(temp_line.c_str(),sizes[0],sizes[1],sizes[2],sizes[3],0); } else if (fstype=="iso") { int error; + MSCDEX_SetCDInterface(CDROM_USE_SDL, -1); newdrive = new isoDrive(drive, temp_line.c_str(), mediaid, error); switch (error) { case 0 : WriteOut(MSG_Get("MSCDEX_SUCCESS")); break; From 042a98ddebc2b91652eb63d6cc426273936df489 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 1 Mar 2005 11:13:29 +0000 Subject: [PATCH 2038/4131] The mouse doesn't use Int10_setpos anymore. Added read+write char that accept x,y coordinates. Fixes Lotus123 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2122 --- src/ints/int10_char.cpp | 16 +++++++++++++--- src/ints/mouse.cpp | 37 +++++++++++++------------------------ 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 9dc5edf9..60b9081a 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.31 2005-02-10 10:21:11 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.32 2005-03-01 11:13:29 qbix79 Exp $ */ /* Character displaying moving functions */ @@ -378,12 +378,22 @@ void INT10_ReadCharAttr(Bit16u * result,Bit8u page) { // Compute the address Bit16u address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); address+=(cur_row*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)+cur_col)*2; - // REad the char + // Read the char PhysPt where = CurMode->pstart+address; *result=mem_readw(where); } -static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useattr) { +void ReadCharAttr(Bit16u col,Bit16u row,Bit8u page,Bit16u * result) { + /* Used by the mouse */ + Bit16u address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); + address+=(row*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)+col)*2; + // Read the char + PhysPt where = CurMode->pstart+address; + *result=mem_readw(where); +} + +void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useattr) { + /* Externally used by the mouse routine */ PhysPt fontdata; Bitu x,y; Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 68b50767..7fe9a052 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.46 2005-02-24 20:14:57 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.47 2005-03-01 11:13:29 qbix79 Exp $ */ #include #include @@ -200,20 +200,16 @@ INLINE void Mouse_AddEvent(Bit16u type) { // *************************************************************************** // Mouse cursor - text mode // *************************************************************************** +/* Write and read directly to the screen. Do no use int_setcursorpos (LOTUS123) */ +extern void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useattr); +extern void ReadCharAttr(Bit16u col,Bit16u row,Bit8u page,Bit16u * result); void RestoreCursorBackgroundText() { if (mouse.shown<0) return; if (mouse.background) { - // Save old Cursorposition - Bit8u oldx = CURSOR_POS_ROW(0); - Bit8u oldy = CURSOR_POS_COL(0); - // Restore background - INT10_SetCursorPos ((Bit8u)mouse.backposy,(Bit8u)mouse.backposx,0); - INT10_WriteChar (mouse.backData[0],mouse.backData[1],0,1,true); - // Restore old cursor position - INT10_SetCursorPos (oldx,oldy,0); + WriteChar(mouse.backposx,mouse.backposy,0,mouse.backData[0],mouse.backData[1],true); mouse.background = false; } }; @@ -223,26 +219,19 @@ void DrawCursorText() // Restore Background RestoreCursorBackgroundText(); - // Save old Cursorposition - Bit8u oldx = CURSOR_POS_ROW(0); - Bit8u oldy = CURSOR_POS_COL(0); // Save Background - Bit16u result; - INT10_SetCursorPos (POS_Y>>3,POS_X>>3,0); - INT10_ReadCharAttr (&result,0); - mouse.backData[0] = result & 0xFF; - mouse.backData[1] = result>>8; mouse.backposx = POS_X>>3; mouse.backposy = POS_Y>>3; - mouse.background = true; + Bit16u result; + ReadCharAttr(mouse.backposx,mouse.backposy,0,&result); + mouse.backData[0] = result & 0xFF; + mouse.backData[1] = result>>8; + mouse.background = true; // Write Cursor result = (result & mouse.textAndMask) ^ mouse.textXorMask; - INT10_WriteChar (result&0xFF,result>>8,0,1,true); - - // Restore old cursor position - INT10_SetCursorPos (oldx,oldy,0); + WriteChar(mouse.backposx,mouse.backposy,0,result&0xFF,result>>8,true); }; // *************************************************************************** @@ -325,7 +314,7 @@ void RestoreCursorBackground() }; void DrawCursor() { - + if (mouse.shown<0) return; // Check video page if (real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE)!=mouse.page) return; @@ -901,7 +890,7 @@ void CreateMouseCallback(void) }; void MOUSE_Init(Section* sec) { - + // Callback 0x33 CreateMouseCallback(); call_int74=CALLBACK_Allocate(); From ca59d955d998f743826ceba4f5d4abef9c4db90b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 1 Mar 2005 19:39:55 +0000 Subject: [PATCH 2039/4131] A filename that starts with a space should result in file_not_found. (Fixes some foreign editor) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2123 --- src/dos/dos_files.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index aa2a0d86..70e8ccd7 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.61 2005-02-24 11:29:26 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.62 2005-03-01 19:39:55 qbix79 Exp $ */ #include #include @@ -53,7 +53,10 @@ void DOS_SetDefaultDrive(Bit8u drive) { } bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { - if(strlen(name) == 0) { + + if(!name || *name == 0 || *name == ' ') { + /* Both \0 and space are seperators and + * empty filenames report file not found */ DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } @@ -81,7 +84,7 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { case '/': upname[w++]='\\'; break; - case ' ': + case ' ': /* should be seperator */ break; case '\\': case '$': case '#': case '@': case '(': case ')': case '!': case '%': case '{': case '}': case '`': case '~': From 25e705f6838211d794155e87e96dd16f38fb34e8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 2 Mar 2005 10:59:22 +0000 Subject: [PATCH 2040/4131] Force the correct vga clock for clocks 0 and 1 used in vga Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2124 --- src/hardware/vga_draw.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 4a8187f0..200e5323 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -349,7 +349,12 @@ void VGA_SetupDrawing(Bitu val) { if (vbstart> 2) & 3; - clock=1000*S3_CLOCK(vga.s3.clk[clock].m,vga.s3.clk[clock].n,vga.s3.clk[clock].r); + if (clock == 0) + clock = 25175000; + else if (clock == 1) + clock = 28322000; + else + clock=1000*S3_CLOCK(vga.s3.clk[clock].m,vga.s3.clk[clock].n,vga.s3.clk[clock].r); /* Check for 8 for 9 character clock mode */ if (vga.seq.clocking_mode & 1 ) clock/=8; else clock/=9; /* Check for pixel doubling, master clock/2 */ From 9a497f0b4b2f7a64e3e263b3a2d6447e916741d2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 2 Mar 2005 11:53:00 +0000 Subject: [PATCH 2041/4131] if is always with == except for errorlevel, which accepts = as well Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2125 --- src/shell/shell_cmds.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index fbbb252b..7b5223c9 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.51 2005-02-10 10:21:12 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.52 2005-03-02 11:53:00 qbix79 Exp $ */ #include #include @@ -526,9 +526,15 @@ void DOS_Shell::CMD_IF(char * args) { bool has_not=false; char * comp=strchr(args,'='); if (comp) { - if (comp[1]!='=') {SyntaxError();return;} - *comp++=' '; - *comp++=' '; + if (comp[1] == '=') { + *comp++ = ' '; + *comp++ = ' '; + } else if(strncasecmp(args,"ERRORLEVEL",10) == 0) { + /* this is in general a syntax error except for errorlevel */ + *comp++ = ' '; + while(*comp++ == ' ') + ; /*nothing */ + } else {SyntaxError();return;} }; char * word=StripWord(args); if (strcasecmp(word,"NOT")==0) { From 266f2a1270e32911d95fdadf272fc4a7fdd63e0a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 3 Mar 2005 10:54:05 +0000 Subject: [PATCH 2042/4131] Changed fm output select (fixes music in mm3 with mixer=true) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2126 --- src/hardware/sblaster.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 52aef47c..c1fc2f5d 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -816,6 +816,10 @@ static void CTMIXER_Reset(void) { static void CTMIXER_Write(Bit8u val) { switch (sb.mixer.index) { + case 0x00: /* Reset */ + CTMIXER_Reset(); + LOG(LOG_SB,LOG_WARN)("Mixer reset value %x",val); + break; case 0x02: /* Master Voulme (SBPRO) Obsolete? */ case 0x22: /* Master Volume (SBPRO) */ SETPROVOL(sb.mixer.master,val); @@ -825,9 +829,11 @@ static void CTMIXER_Write(Bit8u val) { CTMIXER_UpdateVolumes(); break; case 0x06: /* FM output selection, Somewhat obsolete with dual OPL SBpro */ - SETPROVOL(sb.mixer.fm,val); - sb.mixer.fm[1]=sb.mixer.fm[0]; + //SETPROVOL(sb.mixer.fm,val); + //volume controls both channels + sb.mixer.fm[0]=sb.mixer.fm[1] = 0x1| ((val&0x0f)<<1); CTMIXER_UpdateVolumes(); + if(val&0x60) LOG(LOG_SB,LOG_WARN)("Turned FM one channel off. not implemented %X",val); //TODO Change FM Mode if only 1 fm channel is selected break; case 0x0a: /* Mic Level */ From 460908f0e7fa2f3b046660c38d9b9750539224d9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 8 Mar 2005 09:34:27 +0000 Subject: [PATCH 2043/4131] don't print to stdout when there is no stdout. Fixes some bug with -noconsole in a read-only envirionment Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2127 --- src/gui/sdlmain.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index c45a0704..cc63d47d 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.82 2005-02-10 10:21:07 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.83 2005-03-08 09:34:27 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1000,6 +1000,10 @@ void GFX_Events() { } } +/* static variable to show wether there is not a valid stdout. + * Fixes some bugs when -noconsole is used in a read only directory */ +static bool no_stdout = false; + void GFX_ShowMsg(char * format,...) { char buf[512]; va_list msg; @@ -1007,7 +1011,7 @@ void GFX_ShowMsg(char * format,...) { vsprintf(buf,format,msg); strcat(buf,"\n"); va_end(msg); - printf(buf); + if(!no_stdout) printf(buf); }; int main(int argc, char* argv[]) { @@ -1027,7 +1031,8 @@ int main(int argc, char* argv[]) { if (control->cmdline->FindExist("-noconsole")) { FreeConsole(); /* Redirect standard input and standard output */ - freopen(STDOUT_FILE, "w", stdout); + if(freopen(STDOUT_FILE, "w", stdout) == NULL) + no_stdout = true; // No stdout so don't write messages freopen(STDERR_FILE, "w", stderr); setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* Line buffered */ setbuf(stderr, NULL); /* No buffering */ From 8618ef8870451a52cb5687683b097ca35b646441 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 16 Mar 2005 20:44:56 +0000 Subject: [PATCH 2044/4131] basic hidden file detection. Used as initial check by mechwarrior 2 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2128 --- src/dos/drive_iso.cpp | 11 ++++++----- src/dos/drives.h | 4 +++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index b30c2f72..72d07fc0 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.5 2005-02-10 10:20:51 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.6 2005-03-16 20:44:56 qbix79 Exp $ */ #include #include @@ -280,10 +280,11 @@ bool isoDrive::FindNext(DOS_DTA &dta) while (dirIter != searchCache.end()) { isoDirEntry &de = *dirIter; - Bit8u findAttr; - if (IS_DIR(de.fileFlags)) findAttr = DOS_ATTR_DIRECTORY; - else findAttr = DOS_ATTR_ARCHIVE; - + Bit8u findAttr = 0; + if (IS_DIR(de.fileFlags)) findAttr |= DOS_ATTR_DIRECTORY; + else findAttr |= DOS_ATTR_ARCHIVE; + if (IS_HIDDEN(de.fileFlags)) findAttr |= DOS_ATTR_HIDDEN; + if (WildFileCmp((char*)de.ident, pattern) && !(~attr & findAttr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM))) { diff --git a/src/dos/drives.h b/src/dos/drives.h index de99e339..e1da4047 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.26 2005-02-10 10:20:52 qbix79 Exp $ */ +/* $Id: drives.h,v 1.27 2005-03-16 20:44:55 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ @@ -274,9 +274,11 @@ struct isoDirEntry { #define ISO_FRAMESIZE 2048 #define ISO_DIRECTORY 2 +#define ISO_HIDDEN 1 #define ISO_MAXPATHNAME 256 #define ISO_FIRST_VD 16 #define IS_DIR(fileFlags) (fileFlags & ISO_DIRECTORY) +#define IS_HIDDEN(fileFlags) (fileFlags & ISO_HIDDEN) class isoDrive : public DOS_Drive { public: From 641fe1b4656d9b059de94cef04693dcf8dcd96ba Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 21 Mar 2005 12:14:10 +0000 Subject: [PATCH 2045/4131] Update and testing int Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2129 --- ChangeLog | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/ChangeLog b/ChangeLog index 910f4d4c..4573f0b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +0.64 + - 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. + - Lot's of small bug fixes. + - Fixed screenshot corruption when using -noconsole in a read-only directory. + - Addes 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. + + 0.63 - Fixed crash with keymapper (ctrl-f1) and output=surface. - Added unmounting. From fb4802a0bb905aea1eb1e8f1ad62474faf0f2789 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 24 Mar 2005 08:46:38 +0000 Subject: [PATCH 2046/4131] Add a test/option to enable unaliged memory access for certain processors Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2130 --- configure.in | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/configure.in b/configure.in index ae00c5ac..13ecf042 100644 --- a/configure.in +++ b/configure.in @@ -101,16 +101,31 @@ dnl The target cpu checks for dynamic cores AH_TEMPLATE(C_HOSTCPU,[The type of cpu this host has]) AC_MSG_CHECKING(for target cpu type) case "$target_cpu" in - i386|i486|i586|i686) + i?86) AC_DEFINE(C_HOSTCPU,X86) AC_MSG_RESULT(x86 compatible) c_hostcpu="x86" + c_unalignedmemory=yes ;; - *) + powerpc*) + AC_DEFINE(C_HOSTCPU,POWERPC) + AC_MSG_RESULT(Power PC) + c_hostcpu="powerpc" + c_unalignedmemory=yes + ;; + m68k*) + AC_DEFINE(C_HOSTCPU,M68K) + AC_MSG_RESULT(Motorola 68000) + c_hostcpu="m68k" + c_unalignedmemory=yes + ;; + *) AC_DEFINE(C_HOSTCPU,UNKOWN) AC_MSG_RESULT(unknown) + c_unalignedmemory=no ;; esac + AH_TEMPLATE(C_DYNAMIC_X86,[Define to 1 to use x86 dynamic cpu core]) AC_ARG_ENABLE(dynamic-x86,AC_HELP_STRING([--disable-dynamic-x86],[Disable x86 dynamic cpu core]),,enable_dynamic_x86=yes) AC_MSG_CHECKING(whether x86 dynamic cpu core will be enabled) @@ -125,8 +140,6 @@ else 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) @@ -155,6 +168,16 @@ else 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) From be3c6487ab9e8f1b7c0c9b5c9341a56023bb2145 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 24 Mar 2005 09:18:14 +0000 Subject: [PATCH 2047/4131] Add the c_unaligned_memory define for visual c Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2131 --- src/platform/visualc/config.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index d9e66c87..d28a4629 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -36,6 +36,9 @@ /* Define to 1 to use a x86 assembly fpu core */ #define C_FPU_X86 1 +/* Define to 1 to use a unaligned memory access */ +#define C_UNALIGNED_MEMORY 1 + /* environ is defined */ #define ENVIRON_INCLUDED 1 From 6693ca22b1bc46754075d03861063dcd4ed8b48b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 24 Mar 2005 09:19:18 +0000 Subject: [PATCH 2048/4131] Replace WLE with var_write Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2132 --- src/ints/int10_vesa.cpp | 42 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 86bb3993..fc39e0bd 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.13 2005-02-10 10:21:11 qbix79 Exp $ */ +/* $Id: int10_vesa.cpp,v 1.14 2005-03-24 09:19:18 harekiet Exp $ */ #include #include @@ -116,8 +116,6 @@ Bit8u VESA_GetSVGAInformation(Bit16u seg,Bit16u off) { return 0x00; } - - Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off) { MODE_INFO minfo; memset(&minfo,0,sizeof(minfo)); @@ -133,27 +131,27 @@ foundit: VideoModeBlock * mblock=&ModeList_VGA[i]; switch (mblock->type) { case M_LIN8: //Linear 8-bit - WLE(minfo.ModeAttributes,0x9b); - WLE(minfo.WinAAttributes,0x7); //Exists/readable/writable - WLE(minfo.WinGranularity,64); - WLE(minfo.WinSize,64); - WLE(minfo.WinASegment,0xa000); -// WLE(minfo.WinBSegment,0xa000); - WLE(minfo.WinFuncPtr,CALLBACK_RealPointer(callback.setwindow)); - WLE(minfo.BytesPerScanLine,mblock->swidth); - WLE(minfo.NumberOfPlanes,0x1); - WLE(minfo.BitsPerPixel,0x08); - WLE(minfo.NumberOfBanks,0x1); - WLE(minfo.MemoryModel,0x04); //packed pixel - WLE(minfo.NumberOfImagePages,0x05); - WLE(minfo.Reserved_page,0x1); + var_write(minfo.ModeAttributes,0x9b); + var_write(minfo.WinAAttributes,0x7); //Exists/readable/writable + var_write(minfo.WinGranularity,64); + var_write(minfo.WinSize,64); + var_write(minfo.WinASegment,0xa000); +// var_write(minfo.WinBSegment,0xa000); + var_write(minfo.WinFuncPtr,CALLBACK_RealPointer(callback.setwindow)); + var_write(minfo.BytesPerScanLine,mblock->swidth); + var_write(minfo.NumberOfPlanes,0x1); + var_write(minfo.BitsPerPixel,0x08); + var_write(minfo.NumberOfBanks,0x1); + var_write(minfo.MemoryModel,0x04); //packed pixel + var_write(minfo.NumberOfImagePages,0x05); + var_write(minfo.Reserved_page,0x1); break; } - WLE(minfo.XResolution,mblock->swidth); - WLE(minfo.YResolution,mblock->sheight); - WLE(minfo.XCharSize,mblock->cwidth); - WLE(minfo.YCharSize,mblock->cheight); - WLE(minfo.PhysBasePtr,S3_LFB_BASE); + var_write(minfo.XResolution,mblock->swidth); + var_write(minfo.YResolution,mblock->sheight); + var_write(minfo.XCharSize,mblock->cwidth); + var_write(minfo.YCharSize,mblock->cheight); + var_write(minfo.PhysBasePtr,S3_LFB_BASE); MEM_BlockWrite(buf,&minfo,sizeof(MODE_INFO)); return 0x00; From 4594c5a600529185734cca62e78f5b23d2dfb751 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 24 Mar 2005 09:20:47 +0000 Subject: [PATCH 2049/4131] Add test for systems not support unaligned memory access. Rename the WLE functions to var_write Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2133 --- include/mem.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/include/mem.h b/include/mem.h index e719ce48..616b1b45 100644 --- a/include/mem.h +++ b/include/mem.h @@ -52,7 +52,7 @@ MemHandle MEM_NextHandleAt(MemHandle handle,Bitu where); Working on big or little endian machines */ -#ifdef WORDS_BIGENDIAN +#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) INLINE Bit8u host_readb(HostPt off) { return off[0]; @@ -77,10 +77,6 @@ INLINE void host_writed(HostPt off,Bit32u val) { off[3]=(Bit8u)(val >> 24); }; -#define MLEB(_MLE_VAL_) (_MLE_VAL_) -#define MLEW(_MLE_VAL_) ((_MLE_VAL_ >> 8) | (_MLE_VAL_ << 8)) -#define MLED(_MLE_VAL_) ((_MLE_VAL_ >> 24)|((_MLE_VAL_ >> 8)&0xFF00)|((_MLE_VAL_ << 8)&0xFF0000)|((_MLE_VAL_ << 24)&0xFF000000)) - #else INLINE Bit8u host_readb(HostPt off) { @@ -102,16 +98,20 @@ INLINE void host_writed(HostPt off,Bit32u val) { *(Bit32u *)(off)=val; }; -#define MLEB(_MLE_VAL_) (_MLE_VAL_) -#define MLEW(_MLE_VAL_) (_MLE_VAL_) -#define MLED(_MLE_VAL_) (_MLE_VAL_) - #endif -#define WLE(VAR_,VAL_) \ - if (sizeof(VAR_)==1) VAR_=MLEB(VAL_); \ - if (sizeof(VAR_)==2) VAR_=MLEW(VAL_); \ - if (sizeof(VAR_)==4) VAR_=MLED(VAL_); + +INLINE void var_write(Bit8u & var, Bit8u val) { + host_writeb((HostPt)&var, val); +} + +INLINE void var_write(Bit16u & var, Bit16u val) { + host_writew((HostPt)&var, val); +} + +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 */ From b42c189ac61bd151614145a722ebb5294a403e36 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Mar 2005 10:05:57 +0000 Subject: [PATCH 2050/4131] new include system and a new RealSetVec function that returns the old value of the vector Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2134 --- include/mem.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/include/mem.h b/include/mem.h index 616b1b45..63d99233 100644 --- a/include/mem.h +++ b/include/mem.h @@ -16,9 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#if !defined __MEM_H -#define __MEM_H -#include +#ifndef DOSBOX_MEM_H +#define DOSBOX_MEM_H + +#ifndef DOSBOX_DOSBOX_H +#include "dosbox.h" +#endif typedef Bit32u PhysPt; typedef Bit8u * HostPt; @@ -199,7 +202,12 @@ INLINE RealPt RealMake(Bit16u seg,Bit16u off) { INLINE void RealSetVec(Bit8u vec,RealPt pt) { mem_writed(vec<<2,pt); -} +} + +INLINE void RealSetVec(Bit8u vec,RealPt pt,RealPt &old) { + old = mem_readd(vec<<2); + mem_writed(vec<<2,pt); +} INLINE RealPt RealGetVec(Bit8u vec) { return mem_readd(vec<<2); From e80222f29bbf420e1c32e57eb9743c9b3723fe83 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Mar 2005 10:11:18 +0000 Subject: [PATCH 2051/4131] New include system + Removed stddef.h from dosbox.h , added it to core_dyn_x86.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2135 --- include/dosbox.h | 16 +++++++--------- include/logging.h | 7 +++---- src/cpu/core_dyn_x86.cpp | 1 + 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/include/dosbox.h b/include/dosbox.h index 24ea7f9c..8adc942d 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -16,16 +16,15 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#if !defined __DOSBOX_H -#define __DOSBOX_H +#ifndef DOSBOX_DOSBOX_H +#define DOSBOX_DOSBOX_H + +#include "config.h" void E_Exit(char * message,...); void MSG_Add(const char*,const char*); //add messages to the internal langaugefile -const char* MSG_Get(char const *); //get messages from the internal langaugafile - -#include -#include "config.h" +const char* MSG_Get(char const *); //get messages from the internal langaugafile class Section; @@ -50,9 +49,8 @@ enum MachineType { extern MachineType machine; extern bool SDLNetInited; -#ifndef __LOGGING_H_ +#ifndef DOSBOX_LOGGING_H #include "logging.h" #endif // the logging system. -#endif /* __DOSBOX_H */ - +#endif /* DOSBOX_DOSBOX_H */ diff --git a/include/logging.h b/include/logging.h index ecac37d9..81ee2531 100644 --- a/include/logging.h +++ b/include/logging.h @@ -1,5 +1,5 @@ -#ifndef __LOGGING_H_ -#define __LOGGING_H_ +#ifndef DOSBOX_LOGGING_H +#define DOSBOX_LOGGING_H enum LOG_TYPES { LOG_ALL, LOG_VGA, LOG_VGAGFX,LOG_VGAMISC,LOG_INT10, @@ -63,5 +63,4 @@ void GFX_ShowMsg(char * format,...); #endif //C_DEBUG -#endif //__LOGGING_H_ - +#endif //DOSBOX_LOGGING_H diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index fab89029..4a9b2094 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "callback.h" #include "regs.h" From 989727eaaecffccca68bd025aa98eb94ee530cad Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Mar 2005 10:18:45 +0000 Subject: [PATCH 2052/4131] new include system Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2136 --- include/cpu.h | 11 ++++++++--- include/cross.h | 7 +++---- include/dma.h | 8 +++----- include/dos_inc.h | 15 +++++++++------ 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 75a746ca..ac6b6489 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -16,12 +16,18 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __CPU_H -#define __CPU_H +#ifndef DOSBOX_CPU_H +#define DOSBOX_CPU_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 /* CPU Cycle Timing */ extern Bits CPU_Cycles; @@ -418,4 +424,3 @@ INLINE void CPU_SetFlagsw(Bitu word) { #endif - diff --git a/include/cross.h b/include/cross.h index f68bd5ad..e9b750ed 100644 --- a/include/cross.h +++ b/include/cross.h @@ -16,10 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.h,v 1.12 2005-02-10 10:20:47 qbix79 Exp $ */ +/* $Id: cross.h,v 1.13 2005-03-24 10:18:45 qbix79 Exp $ */ -#ifndef _CROSS_H -#define _CROSS_H +#ifndef DOSBOX_CROSS_H +#define DOSBOX_CROSS_H #include #include @@ -57,4 +57,3 @@ #endif #endif - diff --git a/include/dma.h b/include/dma.h index e4ffc803..fb72a2ea 100644 --- a/include/dma.h +++ b/include/dma.h @@ -16,10 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dma.h,v 1.13 2005-02-10 10:20:47 qbix79 Exp $ */ +/* $Id: dma.h,v 1.14 2005-03-24 10:18:45 qbix79 Exp $ */ -#ifndef __DMA_H -#define __DMA_H +#ifndef DOSBOX_DMA_H +#define DOSBOX_DMA_H enum DMAEvent { DMA_REACHED_TC, @@ -89,5 +89,3 @@ extern DmaChannel *DmaChannels[8]; extern DmaController *DmaControllers[2]; #endif - - diff --git a/include/dos_inc.h b/include/dos_inc.h index 57521e47..49aa85e9 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,13 +16,17 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.52 2005-02-10 10:20:47 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.53 2005-03-24 10:18:45 qbix79 Exp $ */ -#ifndef DOS_H_ -#define DOS_H_ +#ifndef DOSBOX_DOS_INC_H +#define DOSBOX_DOS_INC_H -#include -#include +#ifndef DOSBOX_DOS_SYSTEM_H +#include "dos_system.h" +#endif +#ifndef DOSBOX_MEM_H +#include "mem.h" +#endif #ifdef _MSC_VER #pragma pack (1) @@ -584,4 +588,3 @@ INLINE Bit8u RealHandle(Bit16u handle) { } #endif - From 9aa295d8aaef05d436835b0df3fafef5c6e146df Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Mar 2005 10:32:09 +0000 Subject: [PATCH 2053/4131] new include system Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2137 --- include/fpu.h | 6 ++++-- include/hardware.h | 6 ++---- include/ipx.h | 5 ++--- include/ipxserver.h | 5 ++--- include/keyboard.h | 4 ++-- include/mapper.h | 4 ++-- include/mouse.h | 9 ++++----- include/paging.h | 10 +++++++--- include/pic.h | 5 ++--- include/regs.h | 9 +++++---- include/render.h | 5 ++--- include/timer.h | 6 +++--- include/vga.h | 8 ++++---- include/video.h | 5 ++--- 14 files changed, 43 insertions(+), 44 deletions(-) diff --git a/include/fpu.h b/include/fpu.h index 409b1520..d1111a21 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -16,10 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __FPU_H -#define __FPU_H +#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); diff --git a/include/hardware.h b/include/hardware.h index 0a72c1ca..5b5079b8 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -16,8 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef _HARDWARE_H_ -#define _HARDWARE_H_ +#ifndef DOSBOX_HARDWARE_H +#define DOSBOX_HARDWARE_H #include @@ -33,5 +33,3 @@ FILE * OpenCaptureFile(const char * type,const char * ext); #endif - - diff --git a/include/ipx.h b/include/ipx.h index 43f6372c..c9ff29a7 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -16,8 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef _IPX_H_ -#define _IPX_H_ +#ifndef DOSBOX_IPX_H +#define DOSBOX_IPX_H // In Use Flag codes #define USEFLAG_AVAILABLE 0x00 @@ -89,4 +89,3 @@ void PackIP(IPaddress ipAddr, PackedIP *ipPack); #endif #endif - diff --git a/include/ipxserver.h b/include/ipxserver.h index c8e70126..54805d1e 100644 --- a/include/ipxserver.h +++ b/include/ipxserver.h @@ -16,8 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef _IPXSERVER_H_ -#define _IPXSERVER_H_ +#ifndef DOSBOX_IPXSERVER_H_ +#define DOSBOX_IPXSERVER_H_ #if C_IPX @@ -47,4 +47,3 @@ Bit8u packetCRC(Bit8u *buffer, Bit16u bufSize); #endif #endif - diff --git a/include/keyboard.h b/include/keyboard.h index 195c3d06..9fb7fa29 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -16,8 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef _KEYBOARD_H_ -#define _KEYBOARD_H_ +#ifndef DOSBOX_KEYBOARD_H +#define DOSBOX_KEYBOARD_H enum KBD_KEYS { KBD_NONE, diff --git a/include/mapper.h b/include/mapper.h index ca65cd92..78bddc00 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -16,8 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef MAPPER_H_ -#define MAPPER_H_ +#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, diff --git a/include/mouse.h b/include/mouse.h index e8338381..99c7ffd5 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -16,10 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.h,v 1.8 2005-02-10 10:20:47 qbix79 Exp $ */ +/* $Id: mouse.h,v 1.9 2005-03-24 10:32:09 qbix79 Exp $ */ -#ifndef _MOUSE_H_ -#define _MOUSE_H_ +#ifndef DOSBOX_MOUSE_H +#define DOSBOX_MOUSE_H void Mouse_ShowCursor(void); void Mouse_HideCursor(void); @@ -35,5 +35,4 @@ void Mouse_ButtonReleased(Bit8u button); void Mouse_AutoLock(bool enable); void Mouse_NewVideoMode(void); -#endif - +#endif diff --git a/include/paging.h b/include/paging.h index 19861ccc..c11e39c1 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,13 +16,17 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.14 2005-02-10 10:20:47 qbix79 Exp $ */ +/* $Id: paging.h,v 1.15 2005-03-24 10:32:09 qbix79 Exp $ */ -#ifndef _PAGING_H_ -#define _PAGING_H_ +#ifndef DOSBOX_PAGING_H +#define DOSBOX_PAGING_H +#ifndef DOSBOX_DOSBOX_H #include "dosbox.h" +#endif +#ifndef DOSBOX_MEM_H #include "mem.h" +#endif class PageDirectory; diff --git a/include/pic.h b/include/pic.h index a851aa19..6440ca22 100644 --- a/include/pic.h +++ b/include/pic.h @@ -16,8 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __PIC_H -#define __PIC_H +#ifndef DOSBOX_PIC_H +#define DOSBOX_PIC_H /* CPU Cycle Timing */ @@ -60,4 +60,3 @@ void PIC_RemoveEvents(PIC_EventHandler handler); void PIC_SetIRQMask(Bitu irq, bool masked); #endif - diff --git a/include/regs.h b/include/regs.h index b9ab3016..98319c28 100644 --- a/include/regs.h +++ b/include/regs.h @@ -16,10 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#if !defined __REGS_H -#define __REGS_H +#ifndef DOSBOX_REGS_H +#define DOSBOX_REGS_H -#include +#ifndef DOSBOX_MEM_H +#include "mem.h" +#endif #define FLAG_CF 0x00000001 #define FLAG_PF 0x00000004 @@ -165,4 +167,3 @@ enum { #define reg_flags cpu_regs.flags #endif - diff --git a/include/render.h b/include/render.h index 0f9169da..de42225e 100644 --- a/include/render.h +++ b/include/render.h @@ -16,8 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __RENDER_H -#define __RENDER_H +#ifndef DOSBOX_RENDER_H +#define DOSBOX_RENDER_H typedef void (* RENDER_Line_Handler)(const Bit8u * src); @@ -29,4 +29,3 @@ extern RENDER_Line_Handler RENDER_DrawLine; #endif - diff --git a/include/timer.h b/include/timer.h index 68e600f9..742348ea 100644 --- a/include/timer.h +++ b/include/timer.h @@ -16,8 +16,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef _TIMER_H_ -#define _TIMER_H_ +#ifndef DOSBOX_TIMER_H +#define DOSBOX_TIMER_H + /* underlying clock rate in HZ */ #include @@ -35,4 +36,3 @@ void TIMER_DelTickHandler(TIMER_TickHandler handler); void TIMER_AddTick(void); #endif - diff --git a/include/vga.h b/include/vga.h index 98b1edb9..07c06bac 100644 --- a/include/vga.h +++ b/include/vga.h @@ -16,11 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef VGA_H_ -#define VGA_H_ +#ifndef DOSBOX_VGA_H +#define DOSBOX_VGA_H -#include +#ifndef DOSBOX_DOSBOX_H #include "dosbox.h" +#endif enum VGAModes { M_CGA2,M_CGA4, @@ -360,4 +361,3 @@ extern Bit32u Expand16BigTable[0x10000]; #endif - diff --git a/include/video.h b/include/video.h index 8846493b..08bbc5bf 100644 --- a/include/video.h +++ b/include/video.h @@ -16,8 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __VIDEO_H -#define __VIDEO_H +#ifndef DOSBOX_VIDEO_H +#define DOSBOX_VIDEO_H typedef void (* GFX_ResetCallBack)(void); @@ -67,4 +67,3 @@ void GFX_CaptureMouse(void); extern bool mouselocked; //true if mouse is confined to window #endif - From 228f4f443576507f0a5378c60ea6b0fd386d600f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Mar 2005 19:16:33 +0000 Subject: [PATCH 2054/4131] sensivity is max 100. Fixes/closes 1156137 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2138 --- src/ints/mouse.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 7fe9a052..0cf1f92a 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.47 2005-03-01 11:13:29 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.48 2005-03-24 19:16:33 qbix79 Exp $ */ #include #include @@ -314,11 +314,9 @@ void RestoreCursorBackground() }; void DrawCursor() { - if (mouse.shown<0) return; // Check video page if (real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE)!=mouse.page) return; - // Check if cursor in update region /* if ((POS_X >= mouse.updateRegion_x[0]) && (POS_X <= mouse.updateRegion_x[1]) && (POS_Y >= mouse.updateRegion_y[0]) && (POS_Y <= mouse.updateRegion_y[1])) { @@ -473,6 +471,8 @@ static void SetMickeyPixelRate(Bit16s px, Bit16s py){ } }; static void SetSensitivity(Bit16s px, Bit16s py){ + if(px>100) px=100; + if(py>100) py=100; if ((px!=0) && (py!=0)) { px--; //Inspired by cutemouse py--; //Although their cursor update routine is far more complex then ours @@ -909,4 +909,3 @@ void MOUSE_Init(Section* sec) { mouse_reset_hardware(); mouse_reset(); } - From a9accb324394373eae2548a3853e3f9c13ba9836 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Mar 2005 20:59:04 +0000 Subject: [PATCH 2055/4131] new include system + new class for handling callbacks Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2139 --- include/callback.h | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/include/callback.h b/include/callback.h index 37519c7c..fc7c1ec8 100644 --- a/include/callback.h +++ b/include/callback.h @@ -16,12 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.h,v 1.11 2005-02-10 10:20:47 qbix79 Exp $ */ +/* $Id: callback.h,v 1.12 2005-03-24 20:59:04 qbix79 Exp $ */ -#ifndef __CALLBACK_H -#define __CALLBACK_H +#ifndef DOSBOX_CALLBACK_H +#define DOSBOX_CALLBACK_H -#include +#ifndef DOSBOX_MEM_H +#include "mem.h" +#endif typedef Bitu (*CallBack_Handler)(void); extern CallBack_Handler CallBack_Handlers[]; @@ -60,5 +62,23 @@ void CALLBACK_SZF(bool val); extern Bitu call_priv_io; -#endif +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(); + void Install(CallBack_Handler handler,Bitu type,const char* description=0); + Bit16u Get_callback(){return m_callback;} + RealPt Get_RealPointer(){ return RealMake(CB_SEG,m_callback << 4);} + void Set_RealVec(Bit8u vec); +}; +#endif From 224ef1a68b624dd96d46cb5e4e3d364faa64c8fa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Mar 2005 21:11:05 +0000 Subject: [PATCH 2056/4131] new include system + lot's of classes maintaining certain aspects of dosbox Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2140 --- include/inout.h | 31 +++++++++++++++++++++++++------ include/mixer.h | 24 +++++++++++++++++++++++- include/support.h | 8 ++++---- 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/include/inout.h b/include/inout.h index 1de2b064..01ccfdcc 100644 --- a/include/inout.h +++ b/include/inout.h @@ -16,10 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: inout.h,v 1.7 2005-02-10 10:20:47 qbix79 Exp $ */ +/* $Id: inout.h,v 1.8 2005-03-24 21:11:05 qbix79 Exp $ */ -#ifndef __INOUT_H -#define __INOUT_H +#ifndef DOSBOX_INOUT_H +#define DOSBOX_INOUT_H #define IO_MAX (64*1024+3) @@ -37,8 +37,8 @@ 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=0); -void IO_FreeWriteHandler(Bitu port,Bitu mask,Bitu range=0); +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); @@ -48,6 +48,26 @@ 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(); +}; + INLINE void IO_Write(Bitu port,Bit8u val) { IO_WriteB(port,val); } @@ -56,4 +76,3 @@ INLINE Bit8u IO_Read(Bitu port){ } #endif - diff --git a/include/mixer.h b/include/mixer.h index b23366d9..1faa5b02 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -16,6 +16,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#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_Handler)(Bitu len); @@ -65,9 +72,24 @@ public: MixerChannel * MIXER_AddChannel(MIXER_Handler handler,Bitu freq,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,char * name); + ~MixerObject(); +}; + /* PC Speakers functions, tightly related to the timer functions */ - void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode); void PCSPEAKER_SetType(Bitu mode); +#endif diff --git a/include/support.h b/include/support.h index b9f578ed..87d910df 100644 --- a/include/support.h +++ b/include/support.h @@ -16,13 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#if !defined __SUPPORT_H -#define __SUPPORT_H +#ifndef DOSBOX_SUPPORT_H +#define DOSBOX_SUPPORT_H #include #include - +#ifndef DOSBOX_DOSBOX_H #include "dosbox.h" +#endif #if defined (_MSC_VER) /* MS Visual C++ */ #define strcasecmp(a,b) stricmp(a,b) @@ -62,4 +63,3 @@ INLINE char * lowcase(char * str) { #endif - From ebd0dc79d9b4f11c326362e1ab346f4f1bd965d6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Mar 2005 21:12:30 +0000 Subject: [PATCH 2057/4131] new include system + support for the removal of devices + new function for labels (mechwarrior 2) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2141 --- include/dos_system.h | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 0f72ca75..69df06e1 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,15 +16,19 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.29 2005-02-10 10:20:47 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.30 2005-03-24 21:12:30 qbix79 Exp $ */ + +#ifndef DOSBOX_DOS_SYSTEM_H +#define DOSBOX_DOS_SYSTEM_H -#ifndef DOSSYSTEM_H_ -#define DOSSYSTEM_H_ -#include #include +#ifndef DOSBOX_DOSBOX_H #include "dosbox.h" +#endif +#ifndef DOSBOX_CROSS_H #include "cross.h" +#endif #define DOS_NAMELENGTH 12 #define DOS_NAMELENGTH_ASCII (DOS_NAMELENGTH+1) @@ -247,7 +251,8 @@ public: char * GetInfo(void); char curdir[DOS_PATHLENGTH]; char info[256]; - + /* Can be overridden for example in iso images */ + virtual char const * GetLabel(){return dirCache.GetLabel();}; DOS_Drive_Cache dirCache; }; @@ -262,8 +267,12 @@ enum { DOS_SEEK_SET=0,DOS_SEEK_CUR=1,DOS_SEEK_END=2}; typedef bool (MultiplexHandler)(void); void DOS_AddMultiplexHandler(MultiplexHandler * handler); +void DOS_DelMultiplexHandler(MultiplexHandler * handler); +/* AddDevice stores the pointer to a created device */ void DOS_AddDevice(DOS_Device * adddev); +/* DelDevice destroys the device that is pointed to. */ +void DOS_DelDevice(DOS_Device * dev); + void VFILE_Register(const char * name,Bit8u * data,Bit32u size); #endif - From b2b5bfeb7e024637dde44e1f082e3f3e1bcd12b3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Mar 2005 21:41:26 +0000 Subject: [PATCH 2058/4131] fix compilation with gcc 3.4 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2142 --- include/mem.h | 12 ++++++------ src/ints/int10_vesa.cpp | 40 ++++++++++++++++++++-------------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/include/mem.h b/include/mem.h index 63d99233..6f99054d 100644 --- a/include/mem.h +++ b/include/mem.h @@ -104,16 +104,16 @@ INLINE void host_writed(HostPt off,Bit32u val) { #endif -INLINE void var_write(Bit8u & var, Bit8u val) { - host_writeb((HostPt)&var, val); +INLINE void var_write(Bit8u * var, Bit8u val) { + host_writeb((HostPt)var, val); } -INLINE void var_write(Bit16u & var, Bit16u val) { - host_writew((HostPt)&var, val); +INLINE void var_write(Bit16u * var, Bit16u val) { + host_writew((HostPt)var, val); } -INLINE void var_write(Bit32u & var, Bit32u val) { - host_writed((HostPt)&var, val); +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 */ diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index fc39e0bd..ca2ac628 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.14 2005-03-24 09:19:18 harekiet Exp $ */ +/* $Id: int10_vesa.cpp,v 1.15 2005-03-24 21:41:26 qbix79 Exp $ */ #include #include @@ -131,27 +131,27 @@ foundit: VideoModeBlock * mblock=&ModeList_VGA[i]; switch (mblock->type) { case M_LIN8: //Linear 8-bit - var_write(minfo.ModeAttributes,0x9b); - var_write(minfo.WinAAttributes,0x7); //Exists/readable/writable - var_write(minfo.WinGranularity,64); - var_write(minfo.WinSize,64); - var_write(minfo.WinASegment,0xa000); -// var_write(minfo.WinBSegment,0xa000); - var_write(minfo.WinFuncPtr,CALLBACK_RealPointer(callback.setwindow)); - var_write(minfo.BytesPerScanLine,mblock->swidth); - var_write(minfo.NumberOfPlanes,0x1); - var_write(minfo.BitsPerPixel,0x08); - var_write(minfo.NumberOfBanks,0x1); - var_write(minfo.MemoryModel,0x04); //packed pixel - var_write(minfo.NumberOfImagePages,0x05); - var_write(minfo.Reserved_page,0x1); + var_write(&minfo.ModeAttributes,0x9b); + var_write(&minfo.WinAAttributes,0x7); //Exists/readable/writable + var_write(&minfo.WinGranularity,64); + var_write(&minfo.WinSize,64); + var_write(&minfo.WinASegment,0xa000); +// var_write(&minfo.WinBSegment,0xa000); + var_write(&minfo.WinFuncPtr,CALLBACK_RealPointer(callback.setwindow)); + var_write(&minfo.BytesPerScanLine,mblock->swidth); + var_write(&minfo.NumberOfPlanes,0x1); + var_write(&minfo.BitsPerPixel,0x08); + var_write(&minfo.NumberOfBanks,0x1); + var_write(&minfo.MemoryModel,0x04); //packed pixel + var_write(&minfo.NumberOfImagePages,0x05); + var_write(&minfo.Reserved_page,0x1); break; } - var_write(minfo.XResolution,mblock->swidth); - var_write(minfo.YResolution,mblock->sheight); - var_write(minfo.XCharSize,mblock->cwidth); - var_write(minfo.YCharSize,mblock->cheight); - var_write(minfo.PhysBasePtr,S3_LFB_BASE); + var_write(&minfo.XResolution,mblock->swidth); + var_write(&minfo.YResolution,mblock->sheight); + var_write(&minfo.XCharSize,mblock->cwidth); + var_write(&minfo.YCharSize,mblock->cheight); + var_write(&minfo.PhysBasePtr,S3_LFB_BASE); MEM_BlockWrite(buf,&minfo,sizeof(MODE_INFO)); return 0x00; From b3771fdeec502c82318f29ec5bbf16e383c4977b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 08:39:05 +0000 Subject: [PATCH 2059/4131] new drivelabel functions (mechwarrior 2) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2143 --- src/dos/dos_ioctl.cpp | 28 ++++++++++++++++++++++++++-- src/dos/drives.h | 3 ++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 9dcf275e..4b150c33 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.22 2005-02-10 10:20:51 qbix79 Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.23 2005-03-25 08:39:05 qbix79 Exp $ */ #include #include "dosbox.h" @@ -106,6 +106,31 @@ bool DOS_IOCTL(void) { mem_writeb(ptr+8,0x00); // unit number mem_writed(ptr+0x1f,0xffffffff); // next parameter block break; + case 0x46: + case 0x66: /* Volume label */ + { + char const* bufin=Drives[drive]->GetLabel(); + char buffer[11] ={' '}; + + char* find_ext=strchr(bufin,'.'); + if (find_ext) { + Bitu size=find_ext-bufin;if (size>8) size=8; + memcpy(buffer,bufin,size); + find_ext++; + memcpy(buffer+size,find_ext,(strlen(find_ext)>3) ? 3 : strlen(find_ext)); + } else { + memcpy(buffer,bufin,(strlen(bufin) > 8) ? 8 : strlen(bufin)); + } + + char buf2[8]={ 'F','A','T','1','6',' ',' ',' '}; + if(drive<2) buf2[4] = '2'; //FAT12 for floppies + + mem_writew(ptr+0,0); // 0 + mem_writed(ptr+2,0x1234); //Serial number + MEM_BlockWrite(ptr+6,buffer,11);//volumename + if(reg_cl == 0x66) MEM_BlockWrite(ptr+0x11, buf2,8);//filesystem + } + break; default : LOG(LOG_IOCTL,LOG_ERROR)("DOS:IOCTL Call 0D:%2X Drive %2X unhandled",reg_cl,drive); return false; @@ -136,4 +161,3 @@ bool DOS_GetSTDINStatus(void) { if (Files[handle] && (Files[handle]->GetInformation() & 64)) return false; return true; }; - diff --git a/src/dos/drives.h b/src/dos/drives.h index e1da4047..020f7f8c 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.27 2005-03-16 20:44:55 qbix79 Exp $ */ +/* $Id: drives.h,v 1.28 2005-03-25 08:39:05 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ @@ -302,6 +302,7 @@ public: virtual bool isRemote(void); virtual bool isRemovable(void); bool readSector(Bit8u *buffer, Bit32u sector); + virtual char const* GetLabel(void) {return discLabel;}; private: int readDirEntry(isoDirEntry *de, Bit8u *data); bool loadImage(); From 874cb31df2c8e509e98c23c668461e55eda25d97 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 08:40:42 +0000 Subject: [PATCH 2060/4131] New callback class to handle callbacks Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2144 --- src/cpu/callback.cpp | 58 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 595e0b82..a9824e3b 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,17 +16,15 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.24 2005-02-10 10:20:47 qbix79 Exp $ */ +/* $Id: callback.cpp,v 1.25 2005-03-25 08:40:42 qbix79 Exp $ */ #include -#include #include #include "dosbox.h" #include "callback.h" #include "mem.h" #include "cpu.h" -#include "pic.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 @@ -56,6 +54,10 @@ Bitu CALLBACK_Allocate(void) { return 0; } +void CALLBACK_DeAllocate(Bitu in) { + CallBack_Handlers[in]=&illegal_handler; +} + void CALLBACK_Idle(void) { /* this makes the cpu execute instructions to handle irq's and then come back */ Bitu oldIF=GETFLAG(IF); @@ -105,8 +107,6 @@ void CALLBACK_RunRealInt(Bit8u intnum) { SegSet16(cs,oldcs); } - - void CALLBACK_SZF(bool val) { Bit16u tempf=mem_readw(SegPhys(ss)+reg_sp+4) & 0xFFBF; Bit16u newZF=(val==true) << 6; @@ -119,8 +119,7 @@ void CALLBACK_SCF(bool val) { mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newCF)); }; -void CALLBACK_SetDescription(Bitu nr, const char* descr) -{ +void CALLBACK_SetDescription(Bitu nr, const char* descr) { if (descr) { CallBack_Description[nr] = new char[strlen(descr)+1]; strcpy(CallBack_Description[nr],descr); @@ -128,8 +127,7 @@ void CALLBACK_SetDescription(Bitu nr, const char* descr) CallBack_Description[nr] = 0; }; -const char* CALLBACK_GetDescription(Bitu nr) -{ +const char* CALLBACK_GetDescription(Bitu nr) { if (nr>=CB_MAX) return 0; return CallBack_Description[nr]; }; @@ -166,6 +164,14 @@ bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* return true; } +void CALLBACK_RemoveSetup(Bitu callback) { + for (Bitu i = 0;i < 16;i++) { + phys_writeb(CB_BASE+(callback<<4)+i ,(Bit8u) 0x00); + } + CallBack_Description[callback] = 0; +} + + bool CALLBACK_SetupAt(Bitu callback,CallBack_Handler handler,Bitu type,Bitu linearAddress,const char* descr) { if (callback>=CB_MAX) return false; switch (type) { @@ -196,6 +202,38 @@ bool CALLBACK_SetupAt(Bitu callback,CallBack_Handler handler,Bitu type,Bitu line return true; } +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 E_Exit("what kind of callback is this!"); + CALLBACK_DeAllocate(m_callback); +} + +void CALLBACK_HandlerObject::Install(CallBack_Handler handler,Bitu type,const char* description){ + if(installed) E_Exit("Allready installed"); + m_type=SETUP; + m_callback=CALLBACK_Allocate(); + CALLBACK_Setup(m_callback,handler,type,description); + installed=true; +} + +void CALLBACK_HandlerObject::Set_RealVec(Bit8u vec){ + if(vectorhandler.installed) E_Exit ("double usage of vector handler"); + vectorhandler.installed=true; + vectorhandler.interrupt=vec; + RealSetVec(vec,Get_RealPointer(),vectorhandler.old_vector); +} + void CALLBACK_Init(Section* sec) { Bitu i; for (i=0;i Date: Fri, 25 Mar 2005 08:48:41 +0000 Subject: [PATCH 2061/4131] Small bug fixing + code to remove devices Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2145 --- src/dos/dos_devices.cpp | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 0691e614..8476344b 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_devices.cpp,v 1.9 2005-02-10 10:20:51 qbix79 Exp $ */ +/* $Id: dos_devices.cpp,v 1.10 2005-03-25 08:48:41 qbix79 Exp $ */ #include #include "dosbox.h" @@ -33,7 +33,6 @@ DOS_Device * Devices[DOS_DEVICES]; -static Bitu device_count; class device_NUL : public DOS_Device { public: @@ -111,37 +110,48 @@ DOS_File & DOS_File::operator= (const DOS_File & orig) { Bit8u DOS_FindDevice(char * name) { /* should only check for the names before the dot and spacepadded */ - char temp[CROSS_LEN];//TODOD + char temp[CROSS_LEN];//TODO if(!name || !(*name)) return DOS_DEVICES; strcpy(temp,name); char* dot= strrchr(temp,'.'); - if(dot && *dot) dot=0; //no ext checking + if(dot && *dot) *dot=0; //no ext checking /* loop through devices */ - Bit8u index=0; - while (indexname)) return index; } - index++; } return DOS_DEVICES; } void DOS_AddDevice(DOS_Device * adddev) { +//Caller creates the device. We store a pointer to it //TODO Give the Device a real handler in low memory that responds to calls - if (device_countSetDeviceNumber(device_count); - device_count++; - } else { - E_Exit("DOS:Too many devices added"); + for(Bitu i = 0; i < DOS_DEVICES;i++) { + if(!Devices[i]){ + Devices[i] = adddev; + Devices[i]->SetDeviceNumber(i); + return; + } + } + E_Exit("DOS:Too many devices added"); +} + +void DOS_DelDevice(DOS_Device * dev) { +// We will destroy the device if we find it in our list. +// TODO:The file table is not checked to see the device is opened somewhere! + for (Bitu i = 0; i name,dev->name)){ + delete Devices[i]; + Devices[i] = 0; + return; + } } } void DOS_SetupDevices(void) { - device_count=0; DOS_Device * newdev; newdev=new device_CON(); DOS_AddDevice(newdev); @@ -149,4 +159,3 @@ void DOS_SetupDevices(void) { newdev2=new device_NUL(); DOS_AddDevice(newdev2); } - From c7a8672c2ceedc8402cdaa464962bb67ff9c2d60 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 08:51:34 +0000 Subject: [PATCH 2062/4131] New multiplex scheme so that handlers can be removed Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2146 --- src/dos/dos_misc.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index 70b82c67..af552a25 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -16,37 +16,39 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_misc.cpp,v 1.14 2005-02-14 15:58:50 qbix79 Exp $ */ +/* $Id: dos_misc.cpp,v 1.15 2005-03-25 08:51:34 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" #include "mem.h" #include "regs.h" #include "dos_inc.h" +#include static Bitu call_int2f,call_int2a; -struct MultiplexBlock { - MultiplexHandler * handler; - MultiplexBlock * next; -}; -static MultiplexBlock * first_multiplex; +static std::list Multiplex; +typedef std::list::iterator Multiplex_it; void DOS_AddMultiplexHandler(MultiplexHandler * handler) { - MultiplexBlock * new_multiplex=new(MultiplexBlock); - new_multiplex->next=first_multiplex; - new_multiplex->handler=handler; - first_multiplex=new_multiplex; + Multiplex.push_front(handler); +} + +void DOS_DelMultiplexHandler(MultiplexHandler * handler) { + for(Multiplex_it it =Multiplex.begin();it != Multiplex.end();it++) { + if(*it == handler) { + Multiplex.erase(it); + return; + } + } } static Bitu INT2F_Handler(void) { - MultiplexBlock * loop_multiplex=first_multiplex; - while (loop_multiplex) { - if ((*loop_multiplex->handler)()) return CBRET_NONE; - loop_multiplex=loop_multiplex->next; - } - LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Multiplex Unhandled call %4X",reg_ax); + for(Multiplex_it it = Multiplex.begin();it != Multiplex.end();it++) + if( (*it)() ) return CBRET_NONE; + + LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Multiplex Unhandled call %4X",reg_ax); return CBRET_NONE; }; @@ -122,7 +124,6 @@ static bool DOS_MultiplexFunctions(void) { void DOS_SetupMisc(void) { /* Setup the dos multiplex interrupt */ - first_multiplex=0; call_int2f=CALLBACK_Allocate(); CALLBACK_Setup(call_int2f,&INT2F_Handler,CB_IRET,"DOS Int 2f"); RealSetVec(0x2f,CALLBACK_RealPointer(call_int2f)); @@ -132,4 +133,3 @@ void DOS_SetupMisc(void) { CALLBACK_Setup(call_int2a,&INT2A_Handler,CB_IRET,"DOS Int 2a"); RealSetVec(0x2A,CALLBACK_RealPointer(call_int2a)); }; - From 204409c014342d4499b3d555386d144d132b769c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 09:02:46 +0000 Subject: [PATCH 2063/4131] some includes to keep it compiling + hack so we have good console all the time Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2147 --- src/shell/shell_batch.cpp | 4 ++-- src/shell/shell_cmds.cpp | 3 ++- src/shell/shell_misc.cpp | 11 ++++++++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index c16f5b5f..086afed7 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,13 +16,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.15 2005-02-10 10:21:12 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.16 2005-03-25 09:02:43 qbix79 Exp $ */ #include #include #include "shell.h" - +#include "support.h" BatchFile::BatchFile(DOS_Shell * host,char * name, char * cmd_line) { prev=host->bf; diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 7b5223c9..a4370183 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.52 2005-03-02 11:53:00 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.53 2005-03-25 09:02:44 qbix79 Exp $ */ #include #include @@ -25,6 +25,7 @@ #include "callback.h" #include "regs.h" #include "../dos/drives.h" +#include "support.h" static SHELL_Cmd cmd_list[]={ { "CHDIR", 0, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"}, diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index ccf6bb09..9c86d91f 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.35 2005-02-10 10:21:12 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.36 2005-03-25 09:02:46 qbix79 Exp $ */ #include #include @@ -24,6 +24,7 @@ #include //std::front_inserter #include "shell.h" #include "regs.h" +#include "callback.h" void DOS_Shell::ShowPrompt(void) { Bit8u drive=DOS_GetDefaultDrive()+'A'; @@ -54,7 +55,12 @@ void DOS_Shell::InputCommand(char * line) { while (size) { dos.echo=false; - DOS_ReadFile(input_handle,&c,&n); + while(!DOS_ReadFile(input_handle,&c,&n)) { + Bit16u dummy; + DOS_CloseFile(input_handle); + DOS_OpenFile("con",2,&dummy); + LOG(LOG_MISC,LOG_ERROR)("Reopening the input handle.This is a bug!"); + } if (!n) { size=0; //Kill the while loop continue; @@ -521,4 +527,3 @@ char * DOS_Shell::Which(char * name) { } return 0; } - From 9f14e8cd3c965f223888e2ddd52dbfa65b2b99a4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 09:05:04 +0000 Subject: [PATCH 2064/4131] more compatible with older gcc versions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2148 --- src/dos/cdrom_image.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 378bb56e..6377959f 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.5 2005-02-10 10:20:50 qbix79 Exp $ */ +/* $Id: cdrom_image.cpp,v 1.6 2005-03-25 09:05:04 qbix79 Exp $ */ #include #include @@ -572,7 +572,7 @@ bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) if (stat(filename.c_str(), &test) == 0) return true; // check if file with path relative to cue file exists -#ifndef WIN32 +#if !defined(WIN32) string tmpstr(pathname + "/" + filename); if (stat(tmpstr.c_str(), &test) == 0) { filename = tmpstr; From 32ffb30cb07605ec82baca1390710447253a179e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 09:06:46 +0000 Subject: [PATCH 2065/4131] keep it compiling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2149 --- src/dos/drive_iso.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 72d07fc0..7cfbb0b1 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,13 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.6 2005-03-16 20:44:56 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.7 2005-03-25 09:06:46 qbix79 Exp $ */ #include #include #include "cdrom.h" #include "dosbox.h" #include "dos_system.h" +#include "support.h" #include "drives.h" using namespace std; From e6509a06a6f1dbbe5e21b1fc633af9de09ebf118 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 09:09:22 +0000 Subject: [PATCH 2066/4131] added code to remove a virtual file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2150 --- src/dos/drive_virtual.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index a0c4440e..43a507ed 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -49,6 +49,19 @@ void VFILE_Register(const char * name,Bit8u * data,Bit32u size) { first_file=new_file; } +void VFILE_Remove(const char *name) { + VFILE_Block * chan=first_file; + VFILE_Block * * where=&first_file; + while (chan) { + if (strcmp(name,chan->name)==0) { + *where=chan->next; + delete chan; + return; + } + where=&chan->next; + chan=chan->next; + } +} class Virtual_File : public DOS_File { public: From cbb309f5d4c09336bc9eeef772db784657e8815c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 09:11:08 +0000 Subject: [PATCH 2067/4131] Fix possible bug with adding a file 2 times to the drive_cache Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2151 --- src/dos/drive_local.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 4a8d6b43..70584476 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.55 2005-02-10 10:20:51 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.56 2005-03-25 09:11:08 qbix79 Exp $ */ #include #include @@ -53,13 +53,24 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) { strcpy(newname,basedir); strcat(newname,name); CROSS_FILENAME(newname); - FILE * hand=fopen(dirCache.GetExpandName(newname),"wb+"); + dirCache.ExpandName(newname); + /* Test if file exists (so we need to truncate it). don't add to dirCache then */ + bool existing_file=false; + + FILE * test=fopen(newname,"rb+"); + if(test) { + fclose(test); + existing_file=true; + + } + + FILE * hand=fopen(newname,"wb+"); if (!hand){ LOG_MSG("Warning: file creation failed: %s",newname); return false; } - dirCache.AddEntry(newname, true); + if(!existing_file) dirCache.AddEntry(newname, true); /* Make the 16 bit device information */ *file=new localFile(name,hand,0x202); From 09067f0e1917790df55af2d61cf55593efe43b0d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 09:14:48 +0000 Subject: [PATCH 2068/4131] added basic reset drive support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2152 --- src/dos/dos_mscdex.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index bf1d9a00..c2d21871 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.27 2005-02-10 10:20:51 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.28 2005-03-25 09:14:48 qbix79 Exp $ */ #include #include @@ -862,6 +862,10 @@ static Bitu MSCDEX_Interrupt_Handler(void) case 0x01 : // (un)Lock door // do nothing -> report as success break; + case 0x02 : // Reset Drive + LOG(LOG_MISC,LOG_WARN)("cdromDrive reset"); + mscdex->StopAudio(subUnit); + break; case 0x05 : // load media mscdex->LoadUnloadMedia(subUnit,false); break; @@ -1076,4 +1080,3 @@ void MSCDEX_Init(Section* sec) /* Create MSCDEX */ mscdex = new CMscdex; }; - From 3a2004c2e25496ac6be5a8ef15932159b0ad9ab1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 09:38:42 +0000 Subject: [PATCH 2069/4131] mix optimalisations by ih8regs. Code to manage mixer objects/channels Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2153 --- src/hardware/mixer.cpp | 49 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index c0689de5..a4d8b84f 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.29 2005-02-10 10:21:08 qbix79 Exp $ */ +/* $Id: mixer.cpp,v 1.30 2005-03-25 09:38:42 qbix79 Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -56,7 +56,12 @@ #define MIXER_WAVESIZE MIXER_BUFSIZE #define MIXER_VOLSHIFT 13 -#define MIXER_CLIP(SAMP) (SAMP>MAX_AUDIO) ? (Bit16s)MAX_AUDIO : (SAMPMAX_AUDIO) ? (Bit16s)MAX_AUDIO : (SAMPMAX_AUDIO)|(SAMPnext; + delete delchan; + return; + } + where=&chan->next; + chan=chan->next; + } +} + void MixerChannel::UpdateVolume(void) { volmul[0]=(Bits)((1 << MIXER_VOLSHIFT)*volmain[0]*mixer.mastervol[0]); volmul[1]=(Bits)((1 << MIXER_VOLSHIFT)*volmain[1]*mixer.mastervol[1]); @@ -268,6 +287,7 @@ void MixerChannel::FillUp(void) { /* Mix a certain amount of new samples */ static void MIXER_MixData(Bitu needed) { + MixerChannel * chan=mixer.channels; while (chan) { chan->Mix(needed); @@ -276,10 +296,14 @@ static void MIXER_MixData(Bitu needed) { if (mixer.wave.handle) { Bitu added=needed-mixer.done; Bitu readpos=(mixer.pos+mixer.done)&MIXER_BUFMASK; + + Bits sample; while (added--) { - Bits sample=mixer.work[readpos][0] >> MIXER_VOLSHIFT; + sample=mixer.work[readpos][0] >> MIXER_VOLSHIFT; + INIT_CLIP(sample); mixer.wave.buf[mixer.wave.used][0]=MIXER_CLIP(sample); sample=mixer.work[readpos][1] >> MIXER_VOLSHIFT; + INIT_CLIP(sample); mixer.wave.buf[mixer.wave.used][1]=MIXER_CLIP(sample); readpos=(readpos+1)&MIXER_BUFMASK; if (++mixer.wave.used==MIXER_WAVESIZE) { @@ -321,7 +345,6 @@ static void MIXER_Mix_NoSound(void) { mixer.done=0; } - static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { Bitu need=(Bitu)len/MIXER_SSIZE; if (need>mixer.done) { @@ -343,11 +366,14 @@ static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { mixer.tick_add=((mixer.freq+diff*3) << MIXER_SHIFT)/1000; } Bit16s * output=(Bit16s *)stream; + Bits sample; while (need--) { - Bits sample=mixer.work[mixer.pos][0]>>MIXER_VOLSHIFT; + sample=mixer.work[mixer.pos][0]>>MIXER_VOLSHIFT; + INIT_CLIP(sample); *output++=MIXER_CLIP(sample); mixer.work[mixer.pos][0]=0; sample=mixer.work[mixer.pos][1]>>MIXER_VOLSHIFT; + INIT_CLIP(sample); *output++=MIXER_CLIP(sample); mixer.work[mixer.pos][1]=0; mixer.pos=(mixer.pos+1)&MIXER_BUFMASK; @@ -460,6 +486,18 @@ static void MIXER_ProgramStart(Program * * make) { *make=new MIXER; } +MixerChannel* MixerObject::Install(MIXER_Handler handler,Bitu freq,char * name){ + if(strlen(name)>31) E_Exit("Too long mixer channel name"); + strncpy(m_name,name,31); + installed=true; + return MIXER_AddChannel(handler,freq,name); +} +MixerObject::~MixerObject(){ + if(!installed) return; + MIXER_DelChannel(MIXER_FindChannel(m_name)); +} + + void MIXER_Init(Section* sec) { sec->AddDestroyFunction(&MIXER_Stop); Section_prop * section=static_cast(sec); @@ -512,4 +550,3 @@ void MIXER_Init(Section* sec) { MAPPER_AddHandler(MIXER_WaveEvent,MK_f6,MMOD1,"recwave","Rec Wave"); PROGRAMS_MakeFile("MIXER.COM",MIXER_ProgramStart); } - From 22cb26c2985fd46f26fcec1f2158c1b9bb5b9ea5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 09:46:53 +0000 Subject: [PATCH 2070/4131] New include system. Added an autoexecobject which manages the lines in autoexec.bat Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2154 --- include/shell.h | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/include/shell.h b/include/shell.h index 5bfe3e41..04ca98cc 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,22 +16,18 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.10 2005-02-10 10:20:47 qbix79 Exp $ */ - -#ifndef SHELL_H_ -#define SHELL_H_ +/* $Id: shell.h,v 1.11 2005-03-25 09:46:53 qbix79 Exp $ */ +#ifndef DOSBOX_SHELL_H +#define DOSBOX_SHELL_H #include -#include +#ifndef DOSBOX_DOSBOX_H #include "dosbox.h" -#include "mem.h" +#endif +#ifndef DOSBOX_PROGRAMS_H #include "programs.h" -#include "dos_inc.h" -#include "regs.h" -#include "support.h" -#include "callback.h" -#include "setup.h" +#endif #include #include @@ -144,4 +140,17 @@ static inline char* ExpandDot(char*args, char* buffer) { return buffer; } +/* 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; + char buf[256]; +public: + AutoexecObject():installed(false){}; + void Install(char * line,...); + ~AutoexecObject(); +}; + #endif From 5a3f4fb38dca4dd2081e3dd1d7da3b015c8f2d3c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 10:12:05 +0000 Subject: [PATCH 2071/4131] jumpwise optimalisations Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2155 --- src/cpu/callback.cpp | 22 ++++++++++++---------- src/hardware/mixer.cpp | 13 ++++++++----- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index a9824e3b..e73dac18 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.25 2005-03-25 08:40:42 qbix79 Exp $ */ +/* $Id: callback.cpp,v 1.26 2005-03-25 10:12:04 qbix79 Exp $ */ #include #include @@ -220,18 +220,20 @@ CALLBACK_HandlerObject::~CALLBACK_HandlerObject(){ } void CALLBACK_HandlerObject::Install(CallBack_Handler handler,Bitu type,const char* description){ - if(installed) E_Exit("Allready installed"); - m_type=SETUP; - m_callback=CALLBACK_Allocate(); - CALLBACK_Setup(m_callback,handler,type,description); - installed=true; + 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::Set_RealVec(Bit8u vec){ - if(vectorhandler.installed) E_Exit ("double usage of vector handler"); - vectorhandler.installed=true; - vectorhandler.interrupt=vec; - RealSetVec(vec,Get_RealPointer(),vectorhandler.old_vector); + 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) { diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index a4d8b84f..d0d6778a 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.30 2005-03-25 09:38:42 qbix79 Exp $ */ +/* $Id: mixer.cpp,v 1.31 2005-03-25 10:12:05 qbix79 Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -487,11 +487,14 @@ static void MIXER_ProgramStart(Program * * make) { } MixerChannel* MixerObject::Install(MIXER_Handler handler,Bitu freq,char * name){ - if(strlen(name)>31) E_Exit("Too long mixer channel name"); - strncpy(m_name,name,31); - installed=true; - return MIXER_AddChannel(handler,freq,name); + if(!installed) { + if(strlen(name)>31) E_Exit("Too long mixer channel name"); + strncpy(m_name,name,31); + installed=true; + return MIXER_AddChannel(handler,freq,name); + } else E_Exit("allready added mixer channel."); } + MixerObject::~MixerObject(){ if(!installed) return; MIXER_DelChannel(MIXER_FindChannel(m_name)); From ebda4e8879d34fe017396114b11ac378b49599c6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 11:41:26 +0000 Subject: [PATCH 2072/4131] hopefully some speed gain here Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2156 --- include/paging.h | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/include/paging.h b/include/paging.h index c11e39c1..2839ba78 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.15 2005-03-24 10:32:09 qbix79 Exp $ */ +/* $Id: paging.h,v 1.16 2005-03-25 11:41:26 qbix79 Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H @@ -146,20 +146,22 @@ INLINE Bit8u mem_readb_inline(PhysPt address) { } INLINE Bit16u mem_readw_inline(PhysPt address) { - if (address & 1) return mem_unalignedreadw(address); + if (!(address & 1)) { + Bitu index=(address>>12); - Bitu index=(address>>12); - if (paging.tlb.read[index]) return host_readw(paging.tlb.read[index]+address); - else return paging.tlb.handler[index]->readw(address); + if (paging.tlb.read[index]) return host_readw(paging.tlb.read[index]+address); + else return paging.tlb.handler[index]->readw(address); + } else return mem_unalignedreadw(address); } INLINE Bit32u mem_readd_inline(PhysPt address) { - if (address & 3) return mem_unalignedreadd(address); + if (!(address & 3)) { + Bitu index=(address>>12); - Bitu index=(address>>12); - if (paging.tlb.read[index]) return host_readd(paging.tlb.read[index]+address); - else return paging.tlb.handler[index]->readd(address); + if (paging.tlb.read[index]) return host_readd(paging.tlb.read[index]+address); + else return paging.tlb.handler[index]->readd(address); + } else return mem_unalignedreadd(address); } INLINE void mem_writeb_inline(PhysPt address,Bit8u val) { @@ -170,21 +172,21 @@ INLINE void mem_writeb_inline(PhysPt address,Bit8u val) { } INLINE void mem_writew_inline(PhysPt address,Bit16u val) { - if (address & 1) {mem_unalignedwritew(address,val);return;} + if (!(address & 1)) { + Bitu index=(address>>12); - Bitu index=(address>>12); - - if (paging.tlb.write[index]) host_writew(paging.tlb.write[index]+address,val); - else paging.tlb.handler[index]->writew(address,val); + if (paging.tlb.write[index]) host_writew(paging.tlb.write[index]+address,val); + else paging.tlb.handler[index]->writew(address,val); + } else mem_unalignedwritew(address,val); } INLINE void mem_writed_inline(PhysPt address,Bit32u val) { - if (address & 3) {mem_unalignedwrited(address,val);return;} - - Bitu index=(address>>12); - if (paging.tlb.write[index]) host_writed(paging.tlb.write[index]+address,val); - else paging.tlb.handler[index]->writed(address,val); + if (!(address & 3)) { + Bitu index=(address>>12); + if (paging.tlb.write[index]) host_writed(paging.tlb.write[index]+address,val); + else paging.tlb.handler[index]->writed(address,val); + } else mem_unalignedwrited(address,val); } #endif From 128e3620b13167c69b4eb8c6d3478b578d57f347 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 11:42:07 +0000 Subject: [PATCH 2073/4131] new include system + change bios_extended size so it can be undone Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2157 --- include/bios.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/include/bios.h b/include/bios.h index 991a964a..4002dc94 100644 --- a/include/bios.h +++ b/include/bios.h @@ -16,8 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef _BIOS_H_ -#define _BIOS_H_ +#ifndef DOSBOX_BIOS_H +#define DOSBOX_BIOS_H #define BIOS_BASE_ADDRESS_COM1 0x400 #define BIOS_BASE_ADDRESS_COM2 0x402 @@ -112,8 +112,12 @@ struct diskGeo { extern diskGeo DiskGeometryList[]; #include +#ifndef DOSBOX_MEM_H #include "mem.h" +#endif +#ifndef DOSBOX_DOS_INC_H #include "dos_inc.h" +#endif class imageDisk { public: @@ -153,7 +157,7 @@ extern DOS_DTA *imgDTA; void swapInDisks(void); void swapInNextDisk(void); -void BIOS_ZeroExtendedSize(void); +void BIOS_ZeroExtendedSize(bool in); void char_out(Bit8u chr,Bit32u att,Bit8u page); void INT10_StartUp(void); void INT16_StartUp(void); From 7f54c626ce4956f574a0f56eef65688665a4fbbd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 11:43:36 +0000 Subject: [PATCH 2074/4131] New include system. Removed SHELL_AddAutoexec. New configuration base class + support functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2158 --- include/programs.h | 19 ++++++------- include/serialport.h | 12 ++++++-- include/setup.h | 68 ++++++++++++++++++++++++++++++++------------ 3 files changed, 68 insertions(+), 31 deletions(-) diff --git a/include/programs.h b/include/programs.h index 883b0dbd..e4d10330 100644 --- a/include/programs.h +++ b/include/programs.h @@ -16,11 +16,18 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __PROGRAM_H -#define __PROGRAM_H +#ifndef DOSBOX_PROGRAMS_H +#define DOSBOX_PROGRAMS_H + +#ifndef DOSBOX_DOSBOX_H #include "dosbox.h" +#endif +#ifndef DOSBOX_DOS_INC_H #include "dos_inc.h" +#endif +#ifndef DOSBOX_SETUP_H #include "setup.h" +#endif @@ -48,12 +55,4 @@ public: }; -void SHELL_AddAutoexec(char * line,...); - - - - - - #endif - diff --git a/include/serialport.h b/include/serialport.h index 8f6df34e..1515ebaa 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -16,12 +16,17 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#if !defined __SERIALPORT_H -#define __SERIALPORT_H +#ifndef DOSBOX_SERIALPORT_H +#define DOSBOX_SERIALPORT_H #include +#ifndef DOSBOX_DOSBOX_H #include "dosbox.h" +#endif +#ifndef DOSBOX_INOUT_H +#include "inout.h" +#endif //If it's too high you overflow terminal clients buffers i think #define QUEUE_SIZE 1024 @@ -142,6 +147,8 @@ private: Bit8u linectrl; Bit8u errors; + IO_ReadHandleObject ReadHandler[9]; + IO_WriteHandleObject WriteHandler[9]; }; #include @@ -152,4 +159,3 @@ typedef std::list::iterator CSerial_it; extern CSerialList seriallist; #endif - diff --git a/include/setup.h b/include/setup.h index 7e0160ad..8f944e43 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,16 +16,18 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.17 2005-02-10 10:20:47 qbix79 Exp $ */ +/* $Id: setup.h,v 1.18 2005-03-25 11:43:36 qbix79 Exp $ */ -#ifndef _SETUP_H_ -#define _SETUP_H_ +#ifndef DOSBOX_SETUP_H +#define DOSBOX_SETUP_H #ifdef _MSC_VER #pragma warning ( disable : 4786 ) #endif +#ifndef DOSBOX_CROSS_H #include "cross.h" +#endif #include #include @@ -42,6 +44,7 @@ public: bool FindCommand(unsigned int which,std::string & value); bool FindStringBegin(char * begin,std::string & value, bool remove=false); bool FindStringRemain(char * name,std::string & value); + bool GetStringRemain(std::string & value); unsigned int GetCount(void); private: typedef std::list::iterator cmd_it; @@ -116,31 +119,58 @@ public: } void SetValue(char* input); ~Prop_hex(){ } - void GetValuestring(char* str); + void GetValuestring(char* str); }; +class Section; +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) {}; + ~Module_base(){/*LOG_MSG("executed")*/;};//Destructors are required + /* Returns true if succesful.*/ + virtual bool Change_Config(Section* newconfig) {return false;} ; +}; + + class Section { public: Section(const char* _sectionname) { sectionname=_sectionname; } - virtual ~Section(){ ExecuteDestroy();} + virtual ~Section(){ExecuteDestroy(true); } typedef void (*SectionFunction)(Section*); - void AddInitFunction(SectionFunction func) {initfunctions.push_back(func);} - void AddDestroyFunction(SectionFunction func) {destroyfunctions.push_front(func);} - void ExecuteInit() { - typedef std::list::iterator func_it; + /* 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 _fun,bool _ch){ + function=_fun; + canchange=_ch; + } + }; + void AddInitFunction(SectionFunction func,bool canchange=false) {initfunctions.push_back(Function_wrapper(func,canchange));} + void AddDestroyFunction(SectionFunction func,bool canchange=false) {destroyfunctions.push_front(Function_wrapper(func,canchange));} + void ExecuteInit(bool initall=true) { + typedef std::list::iterator func_it; for (func_it tel=initfunctions.begin(); tel!=initfunctions.end(); tel++){ - (*tel)(this); + if(initall || (*tel).canchange) (*tel).function(this); } } - void ExecuteDestroy() { - typedef std::list::iterator func_it; - for (func_it tel=destroyfunctions.begin(); tel!=destroyfunctions.end(); tel++){ - (*tel)(this); + void ExecuteDestroy(bool destroyall=true) { + typedef std::list::iterator func_it; + for (func_it tel=destroyfunctions.begin(); tel!=destroyfunctions.end(); ){ + if(destroyall || (*tel).canchange) { + (*tel).function(this); + tel=destroyfunctions.erase(tel); //Remove destroyfunction once used + } else tel++; } } - std::list initfunctions; - std::list destroyfunctions; + std::list initfunctions; + std::list destroyfunctions; virtual void HandleInputline(char * _line){} virtual void PrintData(FILE* outfile) {} std::string sectionname; @@ -150,7 +180,8 @@ public: class Section_prop:public Section { public: Section_prop(const char* _sectionname):Section(_sectionname){} - + //ExecuteDestroy should be here else the destroy functions use destroyed properties + ~Section_prop(){ExecuteDestroy(true);} void Add_int(const char* _propname, int _value=0); void Add_string(const char* _propname, char* _value=NULL); void Add_bool(const char* _propname, bool _value=false); @@ -172,6 +203,7 @@ class Section_prop:public Section { class Section_line: public Section{ public: Section_line(const char* _sectionname):Section(_sectionname){} + ~Section_line(){ExecuteDestroy(true);} void HandleInputline(char* gegevens); void PrintData(FILE* outfile); std::string data; @@ -185,7 +217,7 @@ public: Section * AddSection(const char * _name,void (*_initfunction)(Section*)); Section_line * AddSection_line(const char * _name,void (*_initfunction)(Section*)); - Section_prop * AddSection_prop(const char * _name,void (*_initfunction)(Section*)); + Section_prop * AddSection_prop(const char * _name,void (*_initfunction)(Section*),bool canchange=false); Section* GetSection(const char* _sectionname); From 3b4e69630913fb8b8fcb52b25713b593c0021c5c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 11:45:37 +0000 Subject: [PATCH 2075/4131] new configuration layer. Cpu can change cores and other settings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2159 --- src/cpu/cpu.cpp | 148 +++++++++++++++++++++++++++------------------ src/cpu/paging.cpp | 27 ++++++--- 2 files changed, 106 insertions(+), 69 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 88aed219..57746f1f 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.67 2005-02-21 15:36:14 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.68 2005-03-25 11:45:37 qbix79 Exp $ */ #include #include "dosbox.h" @@ -1804,69 +1804,97 @@ static void CPU_CycleDecrease(void) { GFX_SetTitle(CPU_CycleMax,-1,false); } -void CPU_Init(Section* sec) { - Section_prop * section=static_cast(sec); - reg_eax=0; - reg_ebx=0; - reg_ecx=0; - reg_edx=0; - reg_edi=0; - reg_esi=0; - reg_ebp=0; - reg_esp=0; - - SegSet16(cs,0); - SegSet16(ds,0); - SegSet16(es,0); - SegSet16(fs,0); - SegSet16(gs,0); - SegSet16(ss,0); - - CPU_SetFlags(FLAG_IF,FMASK_ALL); //Enable interrupts - cpu.cr0=0xffffffff; - CPU_SET_CRX(0,0); //Initialize - cpu.code.big=false; - cpu.stack.mask=0xffff; - cpu.stack.big=false; - cpu.idt.SetBase(0); - cpu.idt.SetLimit(1023); +class CPU: public Module_base { +private: + static bool inited; +public: + CPU(Section* configuration):Module_base(configuration) { + if(inited) { + Change_Config(configuration); + return; + } + inited=true; + Section_prop * section=static_cast(configuration); + reg_eax=0; + reg_ebx=0; + reg_ecx=0; + reg_edx=0; + reg_edi=0; + reg_esi=0; + reg_ebp=0; + reg_esp=0; - /* Init the cpu cores */ - CPU_Core_Normal_Init(); - CPU_Core_Simple_Init(); - CPU_Core_Full_Init(); + SegSet16(cs,0); + SegSet16(ds,0); + SegSet16(es,0); + SegSet16(fs,0); + SegSet16(gs,0); + SegSet16(ss,0); + + CPU_SetFlags(FLAG_IF,FMASK_ALL); //Enable interrupts + cpu.cr0=0xffffffff; + CPU_SET_CRX(0,0); //Initialize + cpu.code.big=false; + cpu.stack.mask=0xffff; + cpu.stack.big=false; + cpu.idt.SetBase(0); + cpu.idt.SetLimit(1023); + + /* Init the cpu cores */ + CPU_Core_Normal_Init(); + CPU_Core_Simple_Init(); + CPU_Core_Full_Init(); #if (C_DYNAMIC_X86) - CPU_Core_Dyn_X86_Init(); + CPU_Core_Dyn_X86_Init(); #endif - MAPPER_AddHandler(CPU_CycleDecrease,MK_f11,MMOD1,"cycledown","Dec Cycles"); - MAPPER_AddHandler(CPU_CycleIncrease,MK_f12,MMOD1,"cycleup" ,"Inc Cycles"); - CPU_Cycles=0; - CPU_CycleMax=section->Get_int("cycles");; - CPU_CycleUp=section->Get_int("cycleup"); - CPU_CycleDown=section->Get_int("cycledown"); - const char * core=section->Get_string("core"); - cpudecoder=&CPU_Core_Normal_Run; - if (!strcasecmp(core,"normal")) { - cpudecoder=&CPU_Core_Normal_Run; - } else if (!strcasecmp(core,"simple")) { - cpudecoder=&CPU_Core_Simple_Run; - } else if (!strcasecmp(core,"full")) { - cpudecoder=&CPU_Core_Full_Run; - } -#if (C_DYNAMIC_X86) - else if (!strcasecmp(core,"dynamic")) { - cpudecoder=&CPU_Core_Dyn_X86_Run; - } -#endif - else { - LOG_MSG("CPU:Unknown core type %s, switcing back to normal.",core); + MAPPER_AddHandler(CPU_CycleDecrease,MK_f11,MMOD1,"cycledown","Dec Cycles"); + MAPPER_AddHandler(CPU_CycleIncrease,MK_f12,MMOD1,"cycleup" ,"Inc Cycles"); + Change_Config(configuration); + CPU_JMP(false,0,0,0); //Setup the first cpu core } - CPU_JMP(false,0,0,0); //Setup the first cpu core + bool Change_Config(Section* newconfig){ + Section_prop * section=static_cast(newconfig); + CPU_CycleLeft=0;//needed ? + CPU_Cycles=0; + CPU_CycleMax=section->Get_int("cycles");; + CPU_CycleUp=section->Get_int("cycleup"); + CPU_CycleDown=section->Get_int("cycledown"); + const char * core=section->Get_string("core"); + cpudecoder=&CPU_Core_Normal_Run; + if (!strcasecmp(core,"normal")) { + cpudecoder=&CPU_Core_Normal_Run; + } else if (!strcasecmp(core,"simple")) { + cpudecoder=&CPU_Core_Simple_Run; + } else if (!strcasecmp(core,"full")) { + cpudecoder=&CPU_Core_Full_Run; + } +#if (C_DYNAMIC_X86) + else if (!strcasecmp(core,"dynamic")) { + cpudecoder=&CPU_Core_Dyn_X86_Run; + } +#endif + else { + LOG_MSG("CPU:Unknown core type %s, switcing back to normal.",core); + } + + if (!CPU_CycleMax) CPU_CycleMax = 2500; + if(!CPU_CycleUp) CPU_CycleUp = 500; + if(!CPU_CycleDown) CPU_CycleDown = 20; + GFX_SetTitle(CPU_CycleMax,-1,false); + return true; + } + ~CPU(){ /* empty */}; +}; + +static CPU * test; - if (!CPU_CycleMax) CPU_CycleMax = 2500; - if(!CPU_CycleUp) CPU_CycleUp = 500; - if(!CPU_CycleDown) CPU_CycleDown = 20; - CPU_CycleLeft=0; - GFX_SetTitle(CPU_CycleMax,-1,false); +void CPU_ShutDown(Section* sec) { + delete test; } +void CPU_Init(Section* sec) { + test = new CPU(sec); + sec->AddDestroyFunction(&CPU_ShutDown,true); +} +//initialize static members +bool CPU::inited=false; diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 54f316a1..92008efa 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -27,6 +27,7 @@ #include "lazyflags.h" #include "cpu.h" #include "debug.h" +#include "setup.h" #define LINK_TOTAL (64*1024) @@ -326,14 +327,22 @@ bool PAGING_Enabled(void) { return paging.enabled; } -void PAGING_Init(Section * sec) { - /* Setup default Page Directory, force it to update */ - paging.enabled=false; - PAGING_InitTLB(); - Bitu i; - for (i=0;i Date: Fri, 25 Mar 2005 11:52:32 +0000 Subject: [PATCH 2076/4131] New configuration layer. Runtime changing of settings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2160 --- src/hardware/cmos.cpp | 48 ++++++--- src/hardware/disney.cpp | 42 +++++--- src/hardware/dma.cpp | 68 +++++++----- src/hardware/gus.cpp | 168 +++++++++++++++++------------ src/hardware/iohandler.cpp | 58 ++++++++-- src/hardware/joystick.cpp | 27 +++-- src/hardware/memory.cpp | 105 +++++++++--------- src/hardware/mpu401.cpp | 76 ++++++++----- src/hardware/pcspeaker.cpp | 49 ++++++--- src/hardware/sblaster.cpp | 199 ++++++++++++++++++++++------------- src/hardware/serialport.cpp | 37 +++++-- src/hardware/softmodem.cpp | 116 ++++++++++++-------- src/hardware/tandy_sound.cpp | 83 +++++++++------ src/hardware/timer.cpp | 102 ++++++++++-------- 14 files changed, 753 insertions(+), 425 deletions(-) diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 8d51aa41..7bd63844 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -24,6 +24,7 @@ #include "inout.h" #include "mem.h" #include "bios.h" +#include "setup.h" static struct { Bit8u regs[0x40]; @@ -266,20 +267,37 @@ void CMOS_SetRegister(Bitu regNr, Bit8u val) cmos.regs[regNr] = val; }; -void CMOS_Init(Section* sec) { - IO_RegisterWriteHandler(0x70,cmos_selreg,IO_MB); - IO_RegisterWriteHandler(0x71,cmos_writereg,IO_MB); - IO_RegisterReadHandler(0x71,cmos_readreg,IO_MB); - cmos.timer.enabled=false; - cmos.reg=0xa; - cmos_writereg(0x71,0x26,1); - cmos.reg=0xb; - cmos_writereg(0x71,0,1); - /* Fill in extended memory size */ - Bitu exsize=(MEM_TotalPages()*4)-1024; - cmos.regs[0x17]=(Bit8u)exsize; - cmos.regs[0x18]=(Bit8u)(exsize >> 8); - cmos.regs[0x30]=(Bit8u)exsize; - cmos.regs[0x31]=(Bit8u)(exsize >> 8); + +class CMOS:public Module_base{ +private: + IO_ReadHandleObject ReadHandler[2]; + IO_WriteHandleObject WriteHandler[2]; +public: + CMOS(Section* configuration):Module_base(configuration){ + WriteHandler[0].Install(0x70,cmos_selreg,IO_MB); + WriteHandler[1].Install(0x71,cmos_writereg,IO_MB); + ReadHandler[0].Install(0x71,cmos_readreg,IO_MB); + cmos.timer.enabled=false; + cmos.reg=0xa; + cmos_writereg(0x71,0x26,1); + cmos.reg=0xb; + cmos_writereg(0x71,0,1); + /* Fill in extended memory size */ + Bitu exsize=(MEM_TotalPages()*4)-1024; + cmos.regs[0x17]=(Bit8u)exsize; + cmos.regs[0x18]=(Bit8u)(exsize >> 8); + cmos.regs[0x30]=(Bit8u)exsize; + cmos.regs[0x31]=(Bit8u)(exsize >> 8); + } +}; + +static CMOS* test; + +void CMOS_Destroy(Section* sec){ + delete test; } +void CMOS_Init(Section* sec) { + test = new CMOS(sec); + sec->AddDestroyFunction(&CMOS_Destroy,true); +} diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index d11a7f18..15bd7350 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -98,20 +98,36 @@ static void DISNEY_CallBack(Bitu len) { } } +class DISNEY: public Module_base { +private: + IO_ReadHandleObject ReadHandler; + IO_WriteHandleObject WriteHandler; + MixerObject MixerChan; +public: + DISNEY(Section* configuration):Module_base(configuration) { + Section_prop * section=static_cast(configuration); + if(!section->Get_bool("disney")) return; + + WriteHandler.Install(DISNEY_BASE,disney_write,IO_MB,3); + ReadHandler.Install(DISNEY_BASE,disney_read,IO_MB,3); + + disney.chan=MixerChan.Install(&DISNEY_CallBack,7000,"DISNEY"); + + disney.status=0x84; + disney.control=0; + disney.used=0; + disney.last_used=0; + } + ~DISNEY(){ } +}; -void DISNEY_Init(Section* sec) { - MSG_Add("DISNEY_CONFIGFILE_HELP","Nothing to setup yet!\n"); - Section_prop * section=static_cast(sec); - if(!section->Get_bool("disney")) return; +static DISNEY* test; - IO_RegisterWriteHandler(DISNEY_BASE,disney_write,IO_MB,3); - IO_RegisterReadHandler(DISNEY_BASE,disney_read,IO_MB,3); - - disney.chan=MIXER_AddChannel(&DISNEY_CallBack,7000,"DISNEY"); - - disney.status=0x84; - disney.control=0; - disney.used=0; - disney.last_used=0; +static void DISNEY_ShutDown(Section* sec){ + delete test; } +void DISNEY_Init(Section* sec) { + test = new DISNEY(sec); + sec->AddDestroyFunction(&DISNEY_ShutDown,true); +} diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index fc0f3c98..43be4cd8 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -23,6 +23,7 @@ #include "dma.h" #include "pic.h" #include "paging.h" +#include "setup.h" DmaChannel *DmaChannels[8]; DmaController *DmaControllers[2]; @@ -254,32 +255,51 @@ again: return done; } - - -void DMA_Init(Section* sec) { - Bitu i; - DmaControllers[0] = new DmaController(0); - DmaControllers[1] = new DmaController(1); - - for(i=0;i<8;i++) { - DmaChannels[i] = new DmaChannel(i,i>=4); - } +class DMA:public Module_base{ +private: + IO_ReadHandleObject ReadHandler[0x22]; + IO_WriteHandleObject WriteHandler[0x22]; +public: + DMA(Section* configuration):Module_base(configuration){ + Bitu i; + DmaControllers[0] = new DmaController(0); + DmaControllers[1] = new DmaController(1); - for (i=0;i<0x10;i++) { - Bitu mask=IO_MB; - if (i<8) mask|=IO_MW; - IO_RegisterWriteHandler(i,DMA_Write_Port,mask); - IO_RegisterReadHandler(i,DMA_Read_Port,mask); - if (machine==MCH_VGA) { - IO_RegisterWriteHandler(0xc0+i*2,DMA_Write_Port,mask); - IO_RegisterReadHandler(0xc0+i*2,DMA_Read_Port,mask); + for(i=0;i<8;i++) { + DmaChannels[i] = new DmaChannel(i,i>=4); + } + + for (i=0;i<0x10;i++) { + Bitu mask=IO_MB; + if (i<8) mask|=IO_MW; + WriteHandler[i].Install(i,DMA_Write_Port,mask); + ReadHandler[i].Install(i,DMA_Read_Port,mask); + if (machine==MCH_VGA) { + WriteHandler[0x10+i].Install(0xc0+i*2,DMA_Write_Port,mask); + ReadHandler[0x10+i].Install(0xc0+i*2,DMA_Read_Port,mask); + } + } + WriteHandler[0x20].Install(0x81,DMA_Write_Port,IO_MB,3); + WriteHandler[0x21].Install(0x89,DMA_Write_Port,IO_MB,3); + + ReadHandler[0x20].Install(0x81,DMA_Read_Port,IO_MB,3); + ReadHandler[0x21].Install(0x89,DMA_Read_Port,IO_MB,3); + } + ~DMA(){ + delete DmaControllers[0]; + delete DmaControllers[1]; + for(Bitu i=0;i<8;i++) { + delete DmaChannels[i]; } } - IO_RegisterWriteHandler(0x81,DMA_Write_Port,IO_MB,3); - IO_RegisterWriteHandler(0x89,DMA_Write_Port,IO_MB,3); +}; - IO_RegisterReadHandler(0x81,DMA_Read_Port,IO_MB,3); - IO_RegisterReadHandler(0x89,DMA_Read_Port,IO_MB,3); +static DMA* test; + +void DMA_Destroy(Section* sec){ + delete test; +} +void DMA_Init(Section* sec) { + test = new DMA(sec); + sec->AddDestroyFunction(&DMA_Destroy); } - - diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 5d0d525f..895a5f0f 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -23,7 +23,7 @@ #include "dma.h" #include "pic.h" #include "setup.h" -#include "programs.h" +#include "shell.h" #include "math.h" #include "regs.h" @@ -791,72 +791,106 @@ static void MakeTables(void) { } } -void GUS_Init(Section* sec) { - if(machine!=MCH_VGA) return; - Section_prop * section=static_cast(sec); - if(!section->Get_bool("gus")) return; - - memset(&myGUS,0,sizeof(myGUS)); - memset(GUSRam,0,1024*1024); - - myGUS.rate=section->Get_int("rate"); - - myGUS.portbase = section->Get_hex("base") - 0x200; - myGUS.dma1 = section->Get_int("dma1"); - myGUS.dma2 = section->Get_int("dma2"); - myGUS.irq1 = section->Get_int("irq1"); - myGUS.irq2 = section->Get_int("irq2"); - strcpy(&myGUS.ultradir[0], section->Get_string("ultradir")); - - // We'll leave the MIDI interface to the MPU-401 - // Ditto for the Joystick - // GF1 Synthesizer - - IO_RegisterWriteHandler(0x302 + GUS_BASE,write_gus,IO_MB); - IO_RegisterReadHandler(0x302 + GUS_BASE,read_gus,IO_MB); - - IO_RegisterWriteHandler(0x303 + GUS_BASE,write_gus,IO_MB); - IO_RegisterReadHandler(0x303 + GUS_BASE,read_gus,IO_MB); - - IO_RegisterWriteHandler(0x304 + GUS_BASE,write_gus,IO_MB|IO_MW); - IO_RegisterReadHandler(0x304 + GUS_BASE,read_gus,IO_MB|IO_MW); - - IO_RegisterWriteHandler(0x305 + GUS_BASE,write_gus,IO_MB); - IO_RegisterReadHandler(0x305 + GUS_BASE,read_gus,IO_MB); - - IO_RegisterReadHandler(0x206 + GUS_BASE,read_gus,IO_MB); - - IO_RegisterWriteHandler(0x208 + GUS_BASE,write_gus,IO_MB); - IO_RegisterReadHandler(0x208 + GUS_BASE,read_gus,IO_MB); - - IO_RegisterWriteHandler(0x209 + GUS_BASE,write_gus,IO_MB); - - IO_RegisterWriteHandler(0x307 + GUS_BASE,write_gus,IO_MB); - IO_RegisterReadHandler(0x307 + GUS_BASE,read_gus,IO_MB); - - // Board Only - - IO_RegisterWriteHandler(0x200 + GUS_BASE,write_gus,IO_MB); - IO_RegisterReadHandler(0x20A + GUS_BASE,read_gus,IO_MB); - IO_RegisterWriteHandler(0x20B + GUS_BASE,write_gus,IO_MB); - -// DmaChannels[myGUS.dma1]->Register_TC_Callback(GUS_DMA_TC_Callback); - - MakeTables(); - - int i; - for(i=0;i<32;i++) { - guschan[i] = new GUSChannels(i); +class GUS:public Module_base{ +private: + IO_ReadHandleObject ReadHandler[8]; + IO_WriteHandleObject WriteHandler[9]; + AutoexecObject autoexecline[2]; + MixerObject MixerChan; +public: + GUS(Section* configuration):Module_base(configuration){ + if(machine!=MCH_VGA) return; + Section_prop * section=static_cast(configuration); + if(!section->Get_bool("gus")) return; + + memset(&myGUS,0,sizeof(myGUS)); + memset(GUSRam,0,1024*1024); + + myGUS.rate=section->Get_int("rate"); + + myGUS.portbase = section->Get_hex("base") - 0x200; + myGUS.dma1 = section->Get_int("dma1"); + myGUS.dma2 = section->Get_int("dma2"); + myGUS.irq1 = section->Get_int("irq1"); + myGUS.irq2 = section->Get_int("irq2"); + strcpy(&myGUS.ultradir[0], section->Get_string("ultradir")); + + // We'll leave the MIDI interface to the MPU-401 + // Ditto for the Joystick + // GF1 Synthesizer + ReadHandler[0].Install(0x302 + GUS_BASE,read_gus,IO_MB); + WriteHandler[0].Install(0x302 + GUS_BASE,write_gus,IO_MB); + + WriteHandler[1].Install(0x303 + GUS_BASE,write_gus,IO_MB); + ReadHandler[1].Install(0x303 + GUS_BASE,read_gus,IO_MB); + + WriteHandler[2].Install(0x304 + GUS_BASE,write_gus,IO_MB|IO_MW); + ReadHandler[2].Install(0x304 + GUS_BASE,read_gus,IO_MB|IO_MW); + + WriteHandler[3].Install(0x305 + GUS_BASE,write_gus,IO_MB); + ReadHandler[3].Install(0x305 + GUS_BASE,read_gus,IO_MB); + + ReadHandler[4].Install(0x206 + GUS_BASE,read_gus,IO_MB); + + WriteHandler[4].Install(0x208 + GUS_BASE,write_gus,IO_MB); + ReadHandler[5].Install(0x208 + GUS_BASE,read_gus,IO_MB); + + WriteHandler[5].Install(0x209 + GUS_BASE,write_gus,IO_MB); + + WriteHandler[6].Install(0x307 + GUS_BASE,write_gus,IO_MB); + ReadHandler[6].Install(0x307 + GUS_BASE,read_gus,IO_MB); + + // Board Only + + WriteHandler[7].Install(0x200 + GUS_BASE,write_gus,IO_MB); + ReadHandler[7].Install(0x20A + GUS_BASE,read_gus,IO_MB); + WriteHandler[8].Install(0x20B + GUS_BASE,write_gus,IO_MB); + + // DmaChannels[myGUS.dma1]->Register_TC_Callback(GUS_DMA_TC_Callback); + + MakeTables(); + + int i; + for(i=0;i<32;i++) { + guschan[i] = new GUSChannels(i); + } + // Register the Mixer CallBack + gus_chan=MixerChan.Install(GUS_CallBack,GUS_RATE,"GUS"); + myGUS.gRegData=0x1; + GUSReset(); + myGUS.gRegData=0x0; + int portat = 0x200+GUS_BASE; + // ULTRASND=Port,DMA1,DMA2,IRQ1,IRQ2 + autoexecline[0].Install("SET ULTRASND=%3X,%d,%d,%d,%d",portat,myGUS.dma1,myGUS.dma2,myGUS.irq1,myGUS.irq2); + autoexecline[1].Install("SET ULTRADIR=%s", myGUS.ultradir); } - // Register the Mixer CallBack - gus_chan=MIXER_AddChannel(GUS_CallBack,GUS_RATE,"GUS"); - myGUS.gRegData=0x1; - GUSReset(); - myGUS.gRegData=0x0; - int portat = 0x200+GUS_BASE; - // ULTRASND=Port,DMA1,DMA2,IRQ1,IRQ2 - SHELL_AddAutoexec("SET ULTRASND=%3X,%d,%d,%d,%d",portat,myGUS.dma1,myGUS.dma2,myGUS.irq1,myGUS.irq2); - SHELL_AddAutoexec("SET ULTRADIR=%s", myGUS.ultradir); + + + ~GUS() { + if(machine!=MCH_VGA) return; + Section_prop * section=static_cast(m_configuration); + if(!section->Get_bool("gus")) return; + + myGUS.gRegData=0x1; + GUSReset(); + myGUS.gRegData=0x0; + + for(Bitu i=0;i<32;i++) { + delete guschan[i]; + } + + memset(&myGUS,0,sizeof(myGUS)); + memset(GUSRam,0,1024*1024); + } +}; + +static GUS* test; + +void GUS_ShutDown(Section* sec) { + delete test; } - +void GUS_Init(Section* sec) { + test = new GUS(sec); + sec->AddDestroyFunction(&GUS_ShutDown,true); +} diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 166c547b..7b10a4c5 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -16,12 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: iohandler.cpp,v 1.16 2005-02-10 10:21:08 qbix79 Exp $ */ - -#include "dosbox.h" -#include "inout.h" +/* $Id: iohandler.cpp,v 1.17 2005-03-25 11:52:32 qbix79 Exp $ */ #include +#include "dosbox.h" +#include "inout.h" +#include "setup.h" #include "cpu.h" #include "../src/cpu/lazyflags.h" #include "callback.h" @@ -105,6 +105,36 @@ void IO_FreeWriteHandler(Bitu port,Bitu mask,Bitu range) { } } +void IO_ReadHandleObject::Install(Bitu port,IO_ReadHandler * handler,Bitu mask,Bitu range) { + if(!installed) { + installed=true; + m_port=port; + m_mask=mask; + m_range=range; + IO_RegisterReadHandler(port,handler,mask,range); + } else E_Exit("IO_readHandler allready installed port %x",port); +} + +IO_ReadHandleObject::~IO_ReadHandleObject(){ + if(!installed) return; + IO_FreeReadHandler(m_port,m_mask,m_range); +} + +void IO_WriteHandleObject::Install(Bitu port,IO_WriteHandler * handler,Bitu mask,Bitu range) { + if(!installed) { + installed=true; + m_port=port; + m_mask=mask; + m_range=range; + IO_RegisterWriteHandler(port,handler,mask,range); + } else E_Exit("IO_writeHandler allready installed port %x",port); +} + +IO_WriteHandleObject::~IO_WriteHandleObject(){ + if(!installed) return; + IO_FreeWriteHandler(m_port,m_mask,m_range); + //LOG_MSG("FreeWritehandler called with port %X",m_port); +} struct IOF_Entry { Bitu cs; @@ -332,10 +362,26 @@ Bitu IO_ReadD(Bitu port) { else return io_readhandlers[2][port](port,4); }; - -void IO_Init(Section * sect) { +class IO :public Module_base { +public: + IO(Section* configuration):Module_base(configuration){ iof_queue.used=0; IO_FreeReadHandler(0,IO_MA,IO_MAX); IO_FreeWriteHandler(0,IO_MA,IO_MAX); + } + ~IO() + { + //Same as the constructor ? + } +}; + +static IO* test; + +void IO_Destroy(Section* sec) { + delete test; } +void IO_Init(Section * sect) { + test = new IO(sect); + sect->AddDestroyFunction(&IO_Destroy); +} diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index 0f571fdc..d364f048 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -18,6 +18,7 @@ #include "dosbox.h" #include "inout.h" +#include "setup.h" #define RANGE 64 @@ -114,11 +115,25 @@ float JOYSTICK_GetMove_Y(Bitu which) return 0.0f; }; -void JOYSTICK_Init(Section* sec) { - IO_RegisterReadHandler(0x201,read_p201,IO_MB); - IO_RegisterWriteHandler(0x201,write_p201,IO_MB); - stick[0].enabled=false; - stick[1].enabled=false; +class JOYSTICK:public Module_base{ +private: + IO_ReadHandleObject ReadHandler; + IO_WriteHandleObject WriteHandler; +public: + JOYSTICK(Section* configuration):Module_base(configuration){ + ReadHandler.Install(0x201,read_p201,IO_MB); + WriteHandler.Install(0x201,write_p201,IO_MB); + stick[0].enabled=false; + stick[1].enabled=false; + } +}; +static JOYSTICK* test; + +void JOYSTICK_Destroy(Section* sec) { + delete test; } - +void JOYSTICK_Init(Section* sec) { + test = new JOYSTICK(sec); + sec->AddDestroyFunction(&JOYSTICK_Destroy,true); +} diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index dfa06a2d..1795de5b 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -16,17 +16,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include -#include -#include +/* $Id: memory.cpp,v 1.37 2005-03-25 11:52:32 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" #include "inout.h" #include "setup.h" #include "paging.h" -#include "vga.h" #define PAGES_IN_BLOCK ((1024*1024)/MEM_PAGE_SIZE) #define MAX_MEMORY 64 @@ -91,13 +87,13 @@ public: flags=PFLAG_READABLE|PFLAG_HASROM; } void writeb(PhysPt addr,Bitu val){ - LOG_MSG("Write %x to rom at %x",val,addr); + LOG(LOG_CPU,LOG_ERROR)("Write %x to rom at %x",val,addr); } void writew(PhysPt addr,Bitu val){ - LOG_MSG("Write %x to rom at %x",val,addr); + LOG(LOG_CPU,LOG_ERROR)("Write %x to rom at %x",val,addr); } void writed(PhysPt addr,Bitu val){ - LOG_MSG("Write %x to rom at %x",val,addr); + LOG(LOG_CPU,LOG_ERROR)("Write %x to rom at %x",val,addr); } }; @@ -473,50 +469,65 @@ static Bitu read_p92(Bitu port,Bitu iolen) { return memory.a20.controlport | (memory.a20.enabled ? 0x02 : 0); } +class MEMORY:public Module_base{ +private: + IO_ReadHandleObject ReadHandler; + IO_WriteHandleObject WriteHandler; +public: + MEMORY(Section* configuration):Module_base(configuration){ + Bitu i; + Section_prop * section=static_cast(configuration); + + /* Setup the Physical Page Links */ + Bitu memsize=section->Get_int("memsize"); + + if (memsize < 1) memsize = 1; + /* max 63 to solve problems with certain xms handlers */ + if (memsize > MAX_MEMORY-1) { + LOG_MSG("Maximum memory size is %d MB",MAX_MEMORY - 1); + memsize = MAX_MEMORY-1; + } + MemBase = new Bit8u[memsize*1024*1024]; + if (!MemBase) E_Exit("Can't allocate main memory of %d MB",memsize); + memory.pages = (memsize*1024*1024)/4096; + /* Allocate the data for the different page information blocks */ + memory.phandlers=new PageHandler * [memory.pages]; + memory.mhandles=new MemHandle [memory.pages]; + for (i = 0;i < memory.pages;i++) { + memory.phandlers[i] = &ram_page_handler; + memory.mhandles[i] = 0; //Set to 0 for memory allocation + } + /* Setup rom at 0xc0000-0xc8000 */ + for (i=0xc0;i<0xc8;i++) { + memory.phandlers[i] = &rom_page_handler; + } + /* Setup rom at 0xf0000-0x0x100000 */ + for (i=0xf0;i<0x100;i++) { + memory.phandlers[i] = &rom_page_handler; + } + /* Reset some links */ + memory.links.used = 0; + // A20 Line - PS/2 system control port A + WriteHandler.Install(0x92,write_p92,IO_MB); + ReadHandler.Install(0x92,read_p92,IO_MB); + MEM_A20_Enable(false); + } + ~MEMORY(){ + delete [] MemBase; + delete [] memory.phandlers; + delete [] memory.mhandles; + } +}; + +static MEMORY* test; + static void MEM_ShutDown(Section * sec) { - free(MemBase); + delete test; } void MEM_Init(Section * sec) { - Bitu i; - Section_prop * section=static_cast(sec); - - /* Setup the Physical Page Links */ - Bitu memsize=section->Get_int("memsize"); - - if (memsize<1) memsize=1; - /* max 63 to solve problems with certain xms handlers */ - if (memsize>MAX_MEMORY - 1) { - LOG_MSG("Maximum memory size is %d MB",MAX_MEMORY - 1); - memsize=MAX_MEMORY - 1; - } - MemBase=(HostPt)malloc(memsize*1024*1024); - if (!MemBase) E_Exit("Can't allocate main memory of %d MB",memsize); - memory.pages=(memsize*1024*1024)/4096; - /* Allocate the data for the different page information blocks */ - memory.phandlers=new PageHandler * [memory.pages]; - memory.mhandles=new MemHandle [memory.pages]; - for (i=0;iAddDestroyFunction(&MEM_ShutDown); } - - diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 74cb7bf4..5e6c0f4b 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.14 2005-02-10 10:21:09 qbix79 Exp $ */ +/* $Id: mpu401.cpp,v 1.15 2005-03-25 11:52:32 qbix79 Exp $ */ #include #include "dosbox.h" @@ -30,7 +30,6 @@ void MIDI_RawOutByte(Bit8u data); bool MIDI_Available(void); -static Bitu call_irq9; static void MPU401_Event(Bitu); static void MPU401_Reset(void); static void MPU401_EOIHandler(void); @@ -543,7 +542,7 @@ static void MPU401_EOIHandler(void) { } while ((i++)<16); } -static Bitu INT71_Handler() { +static Bitu MPU401_INT71_Handler() { bool signr=0; if (mpu.state.reset) if (!mpu.queue_used) { // hack for "It came to desert" signr=1; @@ -557,7 +556,7 @@ static Bitu INT71_Handler() { IO_Write(0x20,0x62); if (signr) if (mpu.queue_used==1) ClrQueue(); -return CBRET_NONE; + return CBRET_NONE; } static void MPU401_Reset(void) { @@ -590,28 +589,55 @@ static void MPU401_Reset(void) { for (Bitu i=0;i<8;i++) {mpu.playbuf[i].type=OVERFLOW;mpu.playbuf[i].counter=0;} } -void MPU401_Init(Section* sec) { - call_irq9=CALLBACK_Allocate(); /* Allocate handler for IRQ 9 */ - CALLBACK_Setup(call_irq9,&INT71_Handler,CB_IRET,"irq 9 mpu"); - RealSetVec(0x71,CALLBACK_RealPointer(call_irq9)); +class MPU401:public Module_base{ +private: + IO_ReadHandleObject ReadHandler[2]; + IO_WriteHandleObject WriteHandler[2]; + CALLBACK_HandlerObject callbackhandler; + bool installed; /*as it can fail to install by 2 ways (config and no midi)*/ +public: + MPU401(Section* configuration):Module_base(configuration){ + installed = false; + Section_prop * section=static_cast(configuration); + if(!section->Get_bool("mpu401")) return; + if (!MIDI_Available()) return; + /*Enabled and there is a Midi */ + installed = true; + + /* Install a new irq 9 handler that is more suited for the mpu401 */ + callbackhandler.Install(&MPU401_INT71_Handler,CB_IRET,"irq 9 mpu"); + callbackhandler.Set_RealVec(0x71); - Section_prop * section=static_cast(sec); - if(!section->Get_bool("mpu401")) return; + WriteHandler[0].Install(0x330,&MPU401_WriteData,IO_MB); + WriteHandler[1].Install(0x331,&MPU401_WriteCommand,IO_MB); + ReadHandler[0].Install(0x330,&MPU401_ReadData,IO_MB); + ReadHandler[1].Install(0x331,&MPU401_ReadStatus,IO_MB); + + mpu.queue_used=0; + mpu.queue_pos=0; + mpu.mode=M_UART; + + if (!(mpu.intelligent=section->Get_bool("intelligent"))) return; + /*Set IRQ and unmask it(for timequest/princess maker 2) */ + mpu.irq=9; + PIC_SetIRQMask(mpu.irq,false); + MPU401_Reset(); + } + ~MPU401(){ + if(!installed) return; + Section_prop * section=static_cast(m_configuration); + if(!section->Get_bool("intelligent")) return; + PIC_SetIRQMask(mpu.irq,true); + } +}; - if (!MIDI_Available()) return; +static MPU401* test; - IO_RegisterWriteHandler(0x330,&MPU401_WriteData,IO_MB); - IO_RegisterWriteHandler(0x331,&MPU401_WriteCommand,IO_MB); - IO_RegisterReadHandler(0x330,&MPU401_ReadData,IO_MB); - IO_RegisterReadHandler(0x331,&MPU401_ReadStatus,IO_MB); - - mpu.queue_used=0; - mpu.queue_pos=0; - mpu.mode=M_UART; - - if (!(mpu.intelligent=section->Get_bool("intelligent"))) return; - /*Set IRQ and unmask it(for timequest/princess maker 2) */ - mpu.irq=9; - PIC_SetIRQMask(mpu.irq,false); - MPU401_Reset(); +void MPU401_Destroy(Section* sec){ + delete test; +} + +void MPU401_Init(Section* sec) { + test = new MPU401(sec); + sec->AddDestroyFunction(&MPU401_Destroy,true); } diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 00d2ea62..c6d02cfe 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /* $Id: pcspeaker.cpp,v 1.19 2005-02-10 10:21:09 qbix79 Exp $ */ + /* $Id: pcspeaker.cpp,v 1.20 2005-03-25 11:52:32 qbix79 Exp $ */ #include #include "dosbox.h" @@ -304,20 +304,39 @@ static void PCSPEAKER_CallBack(Bitu len) { if(spkr.chan) spkr.chan->Enable(false); } } +class PCSPEAKER:public Module_base { +private: + MixerObject MixerChan; +public: + PCSPEAKER(Section* configuration):Module_base(configuration){ + spkr.chan=0; + Section_prop * section=static_cast(configuration); + if(!section->Get_bool("pcspeaker")) return; + spkr.mode=SPKR_OFF; + spkr.last_ticks=0; + spkr.last_index=0; + spkr.rate=section->Get_int("pcrate"); + spkr.pit_max=(1000.0f/PIT_TICK_RATE)*65535; + spkr.pit_half=spkr.pit_max/2; + spkr.pit_new_max=spkr.pit_max; + spkr.pit_new_half=spkr.pit_half; + spkr.pit_index=0; + spkr.used=0; + /* Register the sound channel */ + spkr.chan=MixerChan.Install(&PCSPEAKER_CallBack,spkr.rate,"SPKR"); + } + ~PCSPEAKER(){ + Section_prop * section=static_cast(m_configuration); + if(!section->Get_bool("pcspeaker")) return; + } +}; +static PCSPEAKER* test; + +void PCSPEAKER_ShutDown(Section* sec){ + delete test; +} void PCSPEAKER_Init(Section* sec) { - Section_prop * section=static_cast(sec); - if(!section->Get_bool("pcspeaker")) return; - spkr.mode=SPKR_OFF; - spkr.last_ticks=0; - spkr.last_index=0; - spkr.rate=section->Get_int("pcrate"); - spkr.pit_max=(1000.0f/PIT_TICK_RATE)*65535; - spkr.pit_half=spkr.pit_max/2; - spkr.pit_new_max=spkr.pit_max; - spkr.pit_new_half=spkr.pit_half; - spkr.pit_index=0; - spkr.used=0; - /* Register the sound channel */ - spkr.chan=MIXER_AddChannel(&PCSPEAKER_CallBack,spkr.rate,"SPKR"); + test = new PCSPEAKER(sec); + sec->AddDestroyFunction(&PCSPEAKER_ShutDown,true); } diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index c1fc2f5d..49d02c4c 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include #include #include #include "dosbox.h" @@ -27,7 +26,7 @@ #include "hardware.h" #include "setup.h" #include "support.h" -#include "programs.h" +#include "shell.h" #define SB_PIC_EVENTS 0 @@ -98,7 +97,6 @@ struct SB_INFO { Bit8u time_constant; DSP_MODES mode; SB_TYPES type; - OPL_Mode oplmode; struct { bool pending_8bit; bool pending_16bit; @@ -1018,80 +1016,133 @@ static void SBLASTER_CallBack(Bitu len) { break; } } +class SBLASTER: public Module_base { +private: + /* Data */ + IO_ReadHandleObject ReadHandler[0x10]; + IO_WriteHandleObject WriteHandler[0x10]; + AutoexecObject autoexecline; + MixerObject MixerChan; -void SBLASTER_Init(Section* sec) { - Bitu i; - Section_prop * section=static_cast(sec); - const char * sbtype=section->Get_string("type"); - sb.hw.base=section->Get_hex("base"); - sb.hw.irq=section->Get_int("irq"); - sb.hw.dma8=section->Get_int("dma"); - sb.hw.dma16=section->Get_int("hdma"); - sb.mixer.enabled=section->Get_bool("mixer"); - sb.mixer.stereo=false; - if (!strcasecmp(sbtype,"sb1")) sb.type=SBT_1; - else if (!strcasecmp(sbtype,"sb2")) sb.type=SBT_2; - else if (!strcasecmp(sbtype,"sbpro1")) sb.type=SBT_PRO1; - else if (!strcasecmp(sbtype,"sbpro2")) sb.type=SBT_PRO2; - else if (!strcasecmp(sbtype,"sb16")) sb.type=SBT_16; - else if (!strcasecmp(sbtype,"none")) sb.type=SBT_NONE; - else sb.type=SBT_16; + /* Support Functions */ + void Find_Type_And_Opl(Section_prop* config,SB_TYPES& type, OPL_Mode& opl_mode){ + const char * sbtype=config->Get_string("type"); + if (!strcasecmp(sbtype,"sb1")) type=SBT_1; + else if (!strcasecmp(sbtype,"sb2")) type=SBT_2; + else if (!strcasecmp(sbtype,"sbpro1")) type=SBT_PRO1; + else if (!strcasecmp(sbtype,"sbpro2")) type=SBT_PRO2; + else if (!strcasecmp(sbtype,"sb16")) type=SBT_16; + else if (!strcasecmp(sbtype,"none")) type=SBT_NONE; + else type=SBT_16; + + if (machine!=MCH_VGA && type==SBT_16) type=SBT_PRO2; - if (machine!=MCH_VGA && sb.type==SBT_16) sb.type=SBT_PRO2; - - /* OPL/CMS Init */ - const char * omode=section->Get_string("oplmode"); - Bitu oplrate=section->Get_int("oplrate"); - OPL_Mode opl_mode; - if (!strcasecmp(omode,"none")) opl_mode=OPL_none; - else if (!strcasecmp(omode,"cms")) opl_mode=OPL_cms; - else if (!strcasecmp(omode,"opl2")) opl_mode=OPL_opl2; - else if (!strcasecmp(omode,"dualopl2")) opl_mode=OPL_dualopl2; - else if (!strcasecmp(omode,"opl3")) opl_mode=OPL_opl3; - /* Else assume auto */ - else { - switch (sb.type) { - case SBT_NONE:opl_mode=OPL_none;break; - case SBT_1:opl_mode=OPL_opl2;break; - case SBT_2:opl_mode=OPL_opl2;break; - case SBT_PRO1:opl_mode=OPL_dualopl2;break; - case SBT_PRO2: - case SBT_16: - opl_mode=OPL_opl3;break; + /* OPL/CMS Init */ + const char * omode=config->Get_string("oplmode"); + if (!strcasecmp(omode,"none")) opl_mode=OPL_none; + else if (!strcasecmp(omode,"cms")) opl_mode=OPL_cms; + else if (!strcasecmp(omode,"opl2")) opl_mode=OPL_opl2; + else if (!strcasecmp(omode,"dualopl2")) opl_mode=OPL_dualopl2; + else if (!strcasecmp(omode,"opl3")) opl_mode=OPL_opl3; + /* Else assume auto */ + else { + switch (type) { + case SBT_NONE:opl_mode=OPL_none;break; + case SBT_1:opl_mode=OPL_opl2;break; + case SBT_2:opl_mode=OPL_opl2;break; + case SBT_PRO1:opl_mode=OPL_dualopl2;break; + case SBT_PRO2: + case SBT_16: + opl_mode=OPL_opl3;break; + } + } + } +public: + SBLASTER(Section* configuration):Module_base(configuration) { + Bitu i; + Section_prop * section=static_cast(configuration); + sb.hw.base=section->Get_hex("base"); + sb.hw.irq=section->Get_int("irq"); + sb.hw.dma8=section->Get_int("dma"); + sb.hw.dma16=section->Get_int("hdma"); + sb.mixer.enabled=section->Get_bool("mixer"); + Bitu oplrate=section->Get_int("oplrate"); + sb.mixer.stereo=false; + OPL_Mode opl_mode; + Find_Type_And_Opl(section,sb.type,opl_mode); + + switch (opl_mode) { + case OPL_none: + WriteHandler[0].Install(0x388,adlib_gusforward,IO_MB); + break; + case OPL_cms: + WriteHandler[0].Install(0x388,adlib_gusforward,IO_MB); + CMS_Init(section,sb.hw.base,oplrate); + break; + case OPL_opl2: + CMS_Init(section,sb.hw.base,oplrate); + case OPL_dualopl2: + case OPL_opl3: + OPL_Init(section,sb.hw.base,opl_mode,oplrate); + break; } - } - switch (opl_mode) { - case OPL_none: - IO_RegisterWriteHandler(0x388,adlib_gusforward,IO_MB); - break; - case OPL_cms: - IO_RegisterWriteHandler(0x388,adlib_gusforward,IO_MB); - CMS_Init(section,sb.hw.base,oplrate); - break; - case OPL_opl2: - CMS_Init(section,sb.hw.base,oplrate); - case OPL_dualopl2: - case OPL_opl3: - OPL_Init(section,sb.hw.base,opl_mode,oplrate); - break; - } - if (sb.type==SBT_NONE) return; - sb.chan=MIXER_AddChannel(&SBLASTER_CallBack,22050,"SB"); - sb.dsp.state=DSP_S_NORMAL; + if (sb.type==SBT_NONE) return; - for (i=4;i<=0xf;i++) { - if (i==8 || i==9) continue; - //Disable mixer ports for lower soundblaster - if ((sb.type==SBT_1 || sb.type==SBT_2) && (i==4 || i==5)) continue; - IO_RegisterReadHandler(sb.hw.base+i,read_sb,IO_MB); - IO_RegisterWriteHandler(sb.hw.base+i,write_sb,IO_MB); - } - DSP_Reset(); - CTMIXER_Reset(); - char hdma[8]=""; - if (sb.type==SBT_16) { - sprintf(hdma,"H%d ",sb.hw.dma16); - } - SHELL_AddAutoexec("SET BLASTER=A%3X I%d D%d %sT%d",sb.hw.base,sb.hw.irq,sb.hw.dma8,hdma,sb.type); + sb.chan=MixerChan.Install(&SBLASTER_CallBack,22050,"SB"); + sb.dsp.state=DSP_S_NORMAL; + + for (i=4;i<=0xf;i++) { + if (i==8 || i==9) continue; + //Disable mixer ports for lower soundblaster + if ((sb.type==SBT_1 || sb.type==SBT_2) && (i==4 || i==5)) continue; + ReadHandler[i].Install(sb.hw.base+i,read_sb,IO_MB); + WriteHandler[i].Install(sb.hw.base+i,write_sb,IO_MB); + } + DSP_Reset(); + CTMIXER_Reset(); + char hdma[8]=""; + if (sb.type==SBT_16) { + sprintf(hdma,"H%d ",sb.hw.dma16); + } + autoexecline.Install("SET BLASTER=A%3X I%d D%d %sT%d",sb.hw.base,sb.hw.irq,sb.hw.dma8,hdma,sb.type); + } + + ~SBLASTER() { + Bitu i; + Section_prop * section=static_cast(m_configuration); + OPL_Mode opl_mode; + Find_Type_And_Opl(section,sb.type,opl_mode); + + switch (opl_mode) { + case OPL_none: + + break; + case OPL_cms: + +//TODO CMS_Init(section,sb.hw.base,oplrate); + break; + case OPL_opl2: +//TODO CMS_Init(section,sb.hw.base,oplrate); + case OPL_dualopl2: + case OPL_opl3: +//TODO OPL_Init(section,sb.hw.base,opl_mode,oplrate); + break; + } + + if (sb.type==SBT_NONE) return; + DSP_Reset();//Stop everything + } +}; //End of SBLASTER class + + + + +static SBLASTER* test; +void SBLASTER_ShutDown(Section* sec) { + delete test; } +void SBLASTER_Init(Section* sec) { + test = new SBLASTER(sec); + sec->AddDestroyFunction(&SBLASTER_ShutDown,true); +} diff --git a/src/hardware/serialport.cpp b/src/hardware/serialport.cpp index a6d5cb6c..5fce2f6e 100644 --- a/src/hardware/serialport.cpp +++ b/src/hardware/serialport.cpp @@ -17,7 +17,6 @@ */ #include -#include #include #include "dosbox.h" @@ -235,9 +234,9 @@ CSerial::CSerial (Bit16u initbase, Bit8u initirq, Bit32u initbps) { initdiv = SERIALBASERATE / bps; UpdateBaudrate(); - for (i=base;i<=(base+8);i++) { - IO_RegisterWriteHandler(i+8,WriteSerial,IO_MB); - IO_RegisterReadHandler(i+8,ReadSerial,IO_MB); + for (i=0;i<=8;i++) { + WriteHandler[i].Install(base+i+8,WriteSerial,IO_MB); + ReadHandler[i].Install(base+i+8,ReadSerial,IO_MB); } rqueue=new CFifo(QUEUE_SIZE); @@ -246,16 +245,32 @@ CSerial::CSerial (Bit16u initbase, Bit8u initirq, Bit32u initbps) { CSerial::~CSerial(void) { - + //Remove pointer in list if present + for (CSerial_it it=seriallist.begin();it!=seriallist.end();) + if(this==*it) it=seriallist.erase(it); else it++; + + delete rqueue; + delete tqueue; + }; +class SERIALPORTS:public Module_base{ +public: + SERIALPORTS(Section* configuration):Module_base(configuration){ + TIMER_AddTickHandler(&SERIAL_Update); + } + ~SERIALPORTS(){ + TIMER_DelTickHandler(&SERIAL_Update); + } +}; -void SERIAL_Init(Section* sec) { - unsigned long args = 1; - Section_prop * section=static_cast(sec); +static SERIALPORTS* test; -// if(!section->Get_bool("enabled")) return; - - TIMER_AddTickHandler(&SERIAL_Update); +void SERIAL_Destroy(Section* sec){ + delete test; } +void SERIAL_Init(Section* sec) { + test = new SERIALPORTS(sec); + sec->AddDestroyFunction(&SERIAL_Destroy,false); +} diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp index 6f171c91..38d0486b 100644 --- a/src/hardware/softmodem.cpp +++ b/src/hardware/softmodem.cpp @@ -99,7 +99,6 @@ struct telnetClient { }; -static Bitu call_int14; #if 1 @@ -161,8 +160,15 @@ public: //MIXER_SetMode(mhd.chan,MIXER_16MONO); } - - + + ~CSerialModem(){ + if (mhd.socket) { + SDLNet_TCP_DelSocket(mhd.socketset,mhd.socket); + SDLNet_TCP_Close(mhd.socket); + } + if(mhd.listensocket) SDLNet_TCP_Close(mhd.listensocket); + if(mhd.socketset) SDLNet_FreeSocketSet(mhd.socketset); + } void SendLine(const char *line) { rqueue->addb(0xd); @@ -739,58 +745,76 @@ static Bitu INT14_FOSSIL(void) { } -void MODEM_Init(Section* sec) { - - unsigned long args = 1; - Section_prop * section=static_cast(sec); - - if(!section->Get_bool("modem")) return; - - if(SDLNet_Init()==-1) { - LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); - return; - } - - if(!SDLNetInited) { +class VIRTUAL_MODEM:public Module_base { +private: + CALLBACK_HandlerObject callback; +public: + VIRTUAL_MODEM(Section* configuration):Module_base(configuration){ + Section_prop * section=static_cast(configuration); + csm = NULL; + + if(!section->Get_bool("modem")) return; + if(SDLNet_Init()==-1) { LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); return; } - SDLNetInited = true; + + if(!SDLNetInited) { + if(SDLNet_Init()==-1) { + LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); + return; + } + SDLNetInited = true; + } + + Bit16u comport = section->Get_int("comport"); + + + + switch (comport) { + case 1: + csm = new CSerialModem(0x3f0, 4, 57600, section->Get_string("remote"), section->Get_int("listenport")); + break; + case 2: + csm = new CSerialModem(0x2f0, 3, 57600, section->Get_string("remote"), section->Get_int("listenport")); + break; + case 3: + csm = new CSerialModem(0x3e0, 4, 57600, section->Get_string("remote"), section->Get_int("listenport")); + break; + case 4: + csm = new CSerialModem(0x2e0, 3, 57600, section->Get_string("remote"), section->Get_int("listenport")); + break; + default: + // Default to COM2 + csm = new CSerialModem(0x2f0, 3, 57600, section->Get_string("remote"), section->Get_int("listenport")); + break; + + } + + if(csm != NULL) seriallist.push_back(csm); + + //Enable FOSSIL support (GTERM, etc) + callback.Install(&INT14_FOSSIL,CB_IRET,"int14 fossil"); + callback.Set_RealVec(0x14); } - - Bit16u comport = section->Get_int("comport"); - - csm = NULL; - - switch (comport) { - case 1: - csm = new CSerialModem(0x3f0, 4, 57600, section->Get_string("remote"), section->Get_int("listenport")); - break; - case 2: - csm = new CSerialModem(0x2f0, 3, 57600, section->Get_string("remote"), section->Get_int("listenport")); - break; - case 3: - csm = new CSerialModem(0x3e0, 4, 57600, section->Get_string("remote"), section->Get_int("listenport")); - break; - case 4: - csm = new CSerialModem(0x2e0, 3, 57600, section->Get_string("remote"), section->Get_int("listenport")); - break; - default: - // Default to COM2 - csm = new CSerialModem(0x2f0, 3, 57600, section->Get_string("remote"), section->Get_int("listenport")); - break; - + ~VIRTUAL_MODEM(){ + if(!csm) return; + delete csm; } +}; - if(csm != NULL) seriallist.push_back(csm); +static VIRTUAL_MODEM* test; - //Enable FOSSIL support (GTERM, etc) - call_int14=CALLBACK_Allocate(); - CALLBACK_Setup(call_int14,&INT14_FOSSIL,CB_IRET); - RealSetVec(0x14,CALLBACK_RealPointer(call_int14)); +void MODEM_Destroy(Section* sec){ + delete test; +} + + +void MODEM_Init(Section* sec) { + test = new VIRTUAL_MODEM(sec); + sec->AddDestroyFunction(&MODEM_Destroy,true); } #endif - diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 613ee3f4..ea5165fc 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -306,40 +306,57 @@ static void SN76496_set_gain(int gain) } - - -void TANDYSOUND_Init(Section* sec) { - if (machine!=MCH_TANDY) return; - Section_prop * section=static_cast(sec); - - IO_RegisterWriteHandler(0xc0,SN76496Write,IO_MB,2); - IO_RegisterWriteHandler(0xc4,TandyDACWrite,IO_MB,4); - - - Bit32u sample_rate = section->Get_int("tandyrate"); - tandy.chan=MIXER_AddChannel(&SN76496Update,sample_rate,"TANDY"); - - tandy.enabled=false; - - Bitu i; - struct SN76496 *R = &sn; - R->SampleRate = sample_rate; - SN76496_set_clock(2386360); - for (i = 0;i < 4;i++) R->Volume[i] = 0; - R->LastRegister = 0; - for (i = 0;i < 8;i+=2) - { - R->Register[i] = 0; - R->Register[i + 1] = 0x0f; /* volume = 0 */ +class TANDYSOUND: public Module_base { +private: + IO_WriteHandleObject WriteHandler[2]; + MixerObject MixerChan; +public: + TANDYSOUND(Section* configuration):Module_base(configuration){ + if (machine!=MCH_TANDY) return; + Section_prop * section=static_cast(configuration); + + WriteHandler[0].Install(0xc0,SN76496Write,IO_MB,2); + WriteHandler[1].Install(0xc4,TandyDACWrite,IO_MB,4); + + + Bit32u sample_rate = section->Get_int("tandyrate"); + tandy.chan=MixerChan.Install(&SN76496Update,sample_rate,"TANDY"); + + tandy.enabled=false; + + Bitu i; + struct SN76496 *R = &sn; + R->SampleRate = sample_rate; + SN76496_set_clock(2386360); + for (i = 0;i < 4;i++) R->Volume[i] = 0; + R->LastRegister = 0; + for (i = 0;i < 8;i+=2) + { + R->Register[i] = 0; + R->Register[i + 1] = 0x0f; /* volume = 0 */ + } + + for (i = 0;i < 4;i++) + { + R->Output[i] = 0; + R->Period[i] = R->Count[i] = R->UpdateStep; + } + R->RNG = NG_PRESET; + R->Output[3] = R->RNG & 1; + SN76496_set_gain(0x1); } + ~TANDYSOUND(){ } +}; - for (i = 0;i < 4;i++) - { - R->Output[i] = 0; - R->Period[i] = R->Count[i] = R->UpdateStep; - } - R->RNG = NG_PRESET; - R->Output[3] = R->RNG & 1; - SN76496_set_gain(0x1); + + +static TANDYSOUND* test; + +void TANDYSOUND_ShutDown(Section* sec) { + delete test; } +void TANDYSOUND_Init(Section* sec) { + test = new TANDYSOUND(sec); + sec->AddDestroyFunction(&TANDYSOUND_ShutDown,true); +} diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index d516bffb..06a83a8b 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,17 +16,16 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.31 2005-02-10 10:21:10 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.32 2005-03-25 11:52:32 qbix79 Exp $ */ +#include #include "dosbox.h" #include "inout.h" #include "pic.h" -#include "bios.h" #include "mem.h" -#include "dosbox.h" #include "mixer.h" #include "timer.h" -#include "math.h" +#include "setup.h" static INLINE void BIN2BCD(Bit16u& val) { Bit16u temp=val%10 + (((val/10)%10)<<4)+ (((val/100)%10)<<8) + (((val/1000)%10)<<12); @@ -245,44 +244,61 @@ static void write_p43(Bitu port,Bitu val,Bitu iolen) { } -void TIMER_Init(Section* sect) { - IO_RegisterWriteHandler(0x40,write_latch,IO_MB); -// IO_RegisterWriteHandler(0x41,write_latch,IO_MB); - IO_RegisterWriteHandler(0x42,write_latch,IO_MB); - IO_RegisterWriteHandler(0x43,write_p43,IO_MB); - IO_RegisterReadHandler(0x40,read_latch,IO_MB); - IO_RegisterReadHandler(0x41,read_latch,IO_MB); - IO_RegisterReadHandler(0x42,read_latch,IO_MB); - /* Setup Timer 0 */ - pit[0].cntr=0x10000; - pit[0].write_state = 3; - pit[0].read_state = 3; - pit[0].read_latch=0; - pit[0].write_latch=0; - pit[0].mode=3; - pit[0].bcd = false; - pit[0].go_read_latch = true; +class TIMER:public Module_base{ +private: + IO_ReadHandleObject ReadHandler[4]; + IO_WriteHandleObject WriteHandler[4]; +public: + TIMER(Section* configuration):Module_base(configuration){ + WriteHandler[0].Install(0x40,write_latch,IO_MB); + // WriteHandler[1].Install(0x41,write_latch,IO_MB); + WriteHandler[2].Install(0x42,write_latch,IO_MB); + WriteHandler[3].Install(0x43,write_p43,IO_MB); + ReadHandler[0].Install(0x40,read_latch,IO_MB); + ReadHandler[1].Install(0x41,read_latch,IO_MB); + ReadHandler[2].Install(0x42,read_latch,IO_MB); + /* Setup Timer 0 */ + pit[0].cntr=0x10000; + pit[0].write_state = 3; + pit[0].read_state = 3; + pit[0].read_latch=0; + pit[0].write_latch=0; + pit[0].mode=3; + pit[0].bcd = false; + pit[0].go_read_latch = true; + + pit[1].bcd = false; + pit[1].write_state = 1; + pit[1].read_state = 1; + pit[1].go_read_latch = true; + pit[1].cntr = 18; + pit[1].mode = 2; + pit[1].write_state = 3; + + pit[2].read_latch=0; /* MadTv1 */ + pit[2].write_state = 3; /* Chuck Yeager */ + pit[2].read_state = 3; + pit[2].mode=3; + pit[2].bcd=false; + pit[2].cntr=1320; + pit[2].go_read_latch=true; + + pit[0].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[0].cntr)); + pit[1].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[1].cntr)); + pit[2].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[2].cntr)); + + PIC_AddEvent(PIT0_Event,pit[0].delay); + } + ~TIMER(){ + PIC_RemoveEvents(PIT0_Event); + } +}; +static TIMER* test; - pit[1].bcd = false; - pit[1].write_state = 1; - pit[1].read_state = 1; - pit[1].go_read_latch = true; - pit[1].cntr = 18; - pit[1].mode = 2; - pit[1].write_state = 3; - - pit[2].read_latch=0; /* MadTv1 */ - pit[2].write_state = 3; /* Chuck Yeager */ - pit[2].read_state = 3; - pit[2].mode=3; - pit[2].bcd=false; - pit[2].cntr=1320; - pit[2].go_read_latch=true; - - pit[0].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[0].cntr)); - pit[1].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[1].cntr)); - pit[2].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[2].cntr)); - - PIC_AddEvent(PIT0_Event,pit[0].delay); +void TIMER_Destroy(Section* sec){ + delete test; +} +void TIMER_Init(Section* sec) { + test = new TIMER(sec); + sec->AddDestroyFunction(&TIMER_Destroy); } - From da9013442adffa1c4cfacb152ae91ad26953abdf Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 11:54:52 +0000 Subject: [PATCH 2077/4131] New configuration layer. Runtime changing of settings. Aditional irq 2 handler for when there is no mpu401. Small rewrite of mainloop for some more speed (inspired by ih8regs) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2161 --- src/hardware/pic.cpp | 177 +++++++++++++++++++++++++------------------ 1 file changed, 105 insertions(+), 72 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index b294a5ee..725b0b5e 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,15 +16,17 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.28 2005-02-10 10:21:09 qbix79 Exp $ */ +/* $Id: pic.cpp,v 1.29 2005-03-25 11:54:52 qbix79 Exp $ */ #include #include "dosbox.h" #include "inout.h" #include "cpu.h" +#include "callback.h" #include "pic.h" #include "timer.h" +#include "setup.h" #define PIC_QUEUESIZE 128 @@ -56,7 +58,7 @@ Bitu PIC_IRQActive; static IRQ_Block irqs[16]; static PIC_Controller pics[2]; - +static bool PIC_Special_Mode = false; //Saves one compare in the pic_run_irqloop struct PICEntry { float index; Bitu value; @@ -92,6 +94,9 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { if (val&0x40) { // special mask select if (val&0x20) pic->special=true; else pic->special=false; + if(pic[0].special || pics[1].special) + PIC_Special_Mode = true; else + PIC_Special_Mode = false; LOG(LOG_PIC,LOG_NORMAL)("port %X : special mask %s",port,(pic->special)?"ON":"OFF"); } } else { // OCW2 issued @@ -229,16 +234,15 @@ static Bitu read_data(Bitu port,Bitu iolen) { void PIC_ActivateIRQ(Bitu irq) { - if (irq<16) { - irqs[irq].active=true; - if( irq < 8 ) { - if (!irqs[irq].masked) { - PIC_IRQCheck|=(1 << irq); - } - } else { - if (!irqs[irq].masked && !irqs[2].masked) { - PIC_IRQCheck|=(1 << irq); - } + if( irq < 8 ) { + irqs[irq].active = true; + if (!irqs[irq].masked) { + PIC_IRQCheck|=(1 << irq); + } + } else if (irq < 16) { + irqs[irq].active = true; + if (!irqs[irq].masked && !irqs[2].masked) { + PIC_IRQCheck|=(1 << irq); } } } @@ -255,10 +259,11 @@ static inline bool PIC_startIRQ(Bitu i) { irqs[i].active = false; PIC_IRQCheck&= ~(1 << i); CPU_HW_Interrupt(irqs[i].vector); - if (!pics[ (i<8)?0:1 ].auto_eoi) { + Bitu pic=(i&8)>>3; + if (!pics[pic].auto_eoi) { //irq 0-7 => pic 0 else pic 1 PIC_IRQActive = i; irqs[i].inservice = true; - } else if (pics[ (i<8)?0:1 ].rotate_on_auto_eoi) { + } else if (pics[pic].rotate_on_auto_eoi) { E_Exit("rotate on auto EOI not handled"); } return true; @@ -273,7 +278,7 @@ void PIC_runIRQs(void) { static Bit16u IRQ_priority_lookup[17] = { 0,1,2,11,12,13,14,15,3,4,5,6,7,8,9,10,16 }; Bit16u activeIRQ = PIC_IRQActive; - if (activeIRQ==PIC_NOIRQ) activeIRQ = 16; + if (activeIRQ == PIC_NOIRQ) activeIRQ = 16; /* Get the priority of the active irq */ Bit16u Priority_Active_IRQ = IRQ_priority_lookup[activeIRQ]; @@ -282,10 +287,17 @@ void PIC_runIRQs(void) { * i is the irq at the current priority */ /* If one of the pics is in special mode use a check that cares for that. */ - if(pics[0].special || pics[1].special) { + if(!PIC_Special_Mode) { + for (j = 0; j < Priority_Active_IRQ; j++) { + i = IRQ_priority_order[j]; + if (!irqs[i].masked && irqs[i].active) { + if(PIC_startIRQ(i)) return; + } + } + } else { /* Special mode variant */ for (j = 0; j<= 15; j++) { i = IRQ_priority_order[j]; - if ( (j < Priority_Active_IRQ) || (pics[ (i<8)?0:1 ].special) ) { + if ( (j < Priority_Active_IRQ) || (pics[ ((i&8)>>3) ].special) ) { if (!irqs[i].masked && irqs[i].active) { /* the irq line is active. it's not masked and * the irq is allowed priority wise. So let's start it */ @@ -294,13 +306,6 @@ void PIC_runIRQs(void) { } } } - } else { - for (j = 0; j < Priority_Active_IRQ; j++) { - i = IRQ_priority_order[j]; - if (!irqs[i].masked && irqs[i].active) { - if(PIC_startIRQ(i)) return; - } - } } } @@ -436,6 +441,14 @@ bool PIC_RunQueue(void) { return true; } +//Irq 9-2 calling code +static Bitu INT71_Handler() { + CALLBACK_RunRealInt(0xa); + IO_Write(0xa0,0x61); + IO_Write(0x20,0x62); + return CBRET_NONE; +} + /* The TIMER Part */ struct TickerBlock { TIMER_TickHandler handler; @@ -488,54 +501,74 @@ void TIMER_AddTick(void) { } +class PIC:public Module_base{ +private: + IO_ReadHandleObject ReadHandler[4]; + IO_WriteHandleObject WriteHandler[4]; + CALLBACK_HandlerObject callback; +public: + PIC(Section* configuration):Module_base(configuration){ + /* Setup pic0 and pic1 with initial values like DOS has normally */ + PIC_IRQCheck=0; + PIC_IRQActive=PIC_NOIRQ; + PIC_Ticks=0; + Bitu i; + for (i=0;i<2;i++) { + pics[i].masked=0xff; + pics[i].active=0; + pics[i].inservice=0; + pics[i].auto_eoi=false; + pics[i].rotate_on_auto_eoi=false; + pics[i].request_issr=false; + pics[i].special=false; + pics[i].icw_index=0; + pics[i].icw_words=0; + } + for (i=0;i<=7;i++) { + irqs[i].active=false; + irqs[i].masked=true; + irqs[i].inservice=false; + irqs[i+8].active=false; + irqs[i+8].masked=true; + irqs[i+8].inservice=false; + irqs[i].vector=0x8+i; + irqs[i+8].vector=0x70+i; + } + irqs[0].masked=false; /* Enable system timer */ + irqs[1].masked=false; /* Enable Keyboard IRQ */ + irqs[2].masked=false; /* Enable second pic */ + irqs[8].masked=false; /* Enable RTC IRQ */ + ReadHandler[0].Install(0x20,read_command,IO_MB); + ReadHandler[1].Install(0x21,read_data,IO_MB); + WriteHandler[0].Install(0x20,write_command,IO_MB); + WriteHandler[1].Install(0x21,write_data,IO_MB); + ReadHandler[2].Install(0xa0,read_command,IO_MB); + ReadHandler[3].Install(0xa1,read_data,IO_MB); + WriteHandler[2].Install(0xa0,write_command,IO_MB); + WriteHandler[3].Install(0xa1,write_data,IO_MB); + /* Initialize the pic queue */ + for (i=0;iAddDestroyFunction(&PIC_Destroy); } - - From d2b7bc58a6457fd8292b199dc3b2027a6eaf1cab Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 11:59:24 +0000 Subject: [PATCH 2078/4131] new configuration system. Runtime changing of settings possible. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2162 --- src/ints/bios.cpp | 224 ++++++++++++++++++++++++++-------------------- src/ints/ems.cpp | 110 ++++++++++++++++------- src/ints/xms.cpp | 90 ++++++++++++------- 3 files changed, 260 insertions(+), 164 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index ca8d2987..f67866ab 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,24 +16,26 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.40 2005-02-24 17:50:58 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.41 2005-03-25 11:59:24 qbix79 Exp $ */ -#include #include "dosbox.h" +#include "mem.h" #include "bios.h" #include "regs.h" #include "cpu.h" #include "callback.h" #include "inout.h" -#include "mem.h" #include "pic.h" #include "joystick.h" -#include "dos_inc.h" #include "mouse.h" +#include "setup.h" -static Bitu call_int1a,call_int11,call_int8,call_int17,call_int12,call_int15,call_int1c; -static Bitu call_int1,call_int70,call_int14; + +/* if mem_systems 0 then size_extended is reported as the real size else + * zero is reported. ems and xms can increase or decrease the other_memsystems + * counter using the BIOS_ZeroExtendedSize call */ static Bit16u size_extended; +static Bits other_memsystems=0; static Bitu INT70_Handler(void) { /* Acknowledge irq with cmos */ @@ -311,7 +313,7 @@ static Bitu INT15_Handler(void) { break; } case 0x88: /* SYSTEM - GET EXTENDED MEMORY SIZE (286+) */ - reg_ax=size_extended; + reg_ax=other_memsystems?0:size_extended; LOG(LOG_BIOS,LOG_NORMAL)("INT15:Function 0x88 Remaining %04X kb",reg_ax); CALLBACK_SCF(false); break; @@ -414,108 +416,132 @@ static Bitu INT1_Single_Step(void) { return CBRET_NONE; } -void BIOS_ZeroExtendedSize(void) { - size_extended=0; +void BIOS_ZeroExtendedSize(bool in) { + if(in) other_memsystems++; + else other_memsystems--; + if(other_memsystems < 0) other_memsystems=0; } void BIOS_SetupKeyboard(void); void BIOS_SetupDisks(void); -void BIOS_Init(Section* sec) { - MSG_Add("BIOS_CONFIGFILE_HELP","Nothing to setup yet!\n"); - /* Clear the Bios Data Area */ - for (Bit16u i=0;i<1024;i++) real_writeb(0x40,i,0); - /* Setup all the interrupt handlers the bios controls */ - /* INT 8 Clock IRQ Handler */ - //TODO Maybe give this a special callback that will also call int 8 instead of starting - //a new system - call_int8=CALLBACK_Allocate(); - CALLBACK_Setup(call_int8,&INT8_Handler,CB_IRET,"Int 8 Clock"); - phys_writeb(CB_BASE+(call_int8<<4)+0,(Bit8u)0xFE); //GRP 4 - phys_writeb(CB_BASE+(call_int8<<4)+1,(Bit8u)0x38); //Extra Callback instruction - phys_writew(CB_BASE+(call_int8<<4)+2,call_int8); //The immediate word - phys_writeb(CB_BASE+(call_int8<<4)+4,(Bit8u)0x50); // push ax - phys_writeb(CB_BASE+(call_int8<<4)+5,(Bit8u)0xb0); // mov al, 0x20 - phys_writeb(CB_BASE+(call_int8<<4)+6,(Bit8u)0x20); - phys_writeb(CB_BASE+(call_int8<<4)+7,(Bit8u)0xe6); // out 0x20, al - phys_writeb(CB_BASE+(call_int8<<4)+8,(Bit8u)0x20); - phys_writeb(CB_BASE+(call_int8<<4)+9,(Bit8u)0x58); // pop ax - phys_writeb(CB_BASE+(call_int8<<4)+10,(Bit8u)0xcf); // iret +class BIOS:public Module_base{ +private: + CALLBACK_HandlerObject callback[10]; +public: + BIOS(Section* configuration):Module_base(configuration){ + MSG_Add("BIOS_CONFIGFILE_HELP","Nothing to setup yet!\n"); + /* Clear the Bios Data Area */ + for (Bit16u i=0;i<1024;i++) real_writeb(0x40,i,0); + /* Setup all the interrupt handlers the bios controls */ + /* INT 8 Clock IRQ Handler */ + //TODO Maybe give this a special callback that will also call int 8 instead of starting + //a new system + callback[0].Install(INT8_Handler,CB_IRET,"Int 8 Clock"); + callback[0].Set_RealVec(0x8); + Bit16u call_int8=callback[0].Get_callback(); + phys_writeb(CB_BASE+(call_int8<<4)+0,(Bit8u)0xFE); //GRP 4 + phys_writeb(CB_BASE+(call_int8<<4)+1,(Bit8u)0x38); //Extra Callback instruction + phys_writew(CB_BASE+(call_int8<<4)+2,call_int8); //The immediate word + phys_writeb(CB_BASE+(call_int8<<4)+4,(Bit8u)0x50); // push ax + phys_writeb(CB_BASE+(call_int8<<4)+5,(Bit8u)0xb0); // mov al, 0x20 + phys_writeb(CB_BASE+(call_int8<<4)+6,(Bit8u)0x20); + phys_writeb(CB_BASE+(call_int8<<4)+7,(Bit8u)0xe6); // out 0x20, al + phys_writeb(CB_BASE+(call_int8<<4)+8,(Bit8u)0x20); + phys_writeb(CB_BASE+(call_int8<<4)+9,(Bit8u)0x58); // pop ax + phys_writeb(CB_BASE+(call_int8<<4)+10,(Bit8u)0xcf); // iret - mem_writed(BIOS_TIMER,0); //Calculate the correct time - RealSetVec(0x8,CALLBACK_RealPointer(call_int8)); - /* INT 11 Get equipment list */ - call_int11=CALLBACK_Allocate(); - CALLBACK_Setup(call_int11,&INT11_Handler,CB_IRET,"Int 11 Equipment"); - RealSetVec(0x11,CALLBACK_RealPointer(call_int11)); - /* INT 12 Memory Size default at 640 kb */ - call_int12=CALLBACK_Allocate(); - CALLBACK_Setup(call_int12,&INT12_Handler,CB_IRET,"Int 12 Memory"); - RealSetVec(0x12,CALLBACK_RealPointer(call_int12)); - mem_writew(BIOS_MEMORY_SIZE,640); - /* INT 13 Bios Disk Support */ - BIOS_SetupDisks(); - call_int14=CALLBACK_Allocate(); - CALLBACK_Setup(call_int14,&INT14_Handler,CB_IRET,"Int 14 COM-port"); - RealSetVec(0x14,CALLBACK_RealPointer(call_int14)); - /* INT 15 Misc Calls */ - call_int15=CALLBACK_Allocate(); - CALLBACK_Setup(call_int15,&INT15_Handler,CB_IRET,"Int 15 Bios"); - RealSetVec(0x15,CALLBACK_RealPointer(call_int15)); - /* INT 16 Keyboard handled in another file */ - BIOS_SetupKeyboard(); - /* INT 16 Printer Routines */ - call_int17=CALLBACK_Allocate(); - CALLBACK_Setup(call_int17,&INT17_Handler,CB_IRET,"Int 17 Printer"); - RealSetVec(0x17,CALLBACK_RealPointer(call_int17)); - /* INT 1A TIME and some other functions */ - call_int1a=CALLBACK_Allocate(); - CALLBACK_Setup(call_int1a,&INT1A_Handler,CB_IRET_STI,"Int 1a Time"); - RealSetVec(0x1A,CALLBACK_RealPointer(call_int1a)); - /* INT 1C System Timer tick called from INT 8 */ - call_int1c=CALLBACK_Allocate(); - CALLBACK_Setup(call_int1c,&INT1C_Handler,CB_IRET,"Int 1c Timer tick"); - RealSetVec(0x1C,CALLBACK_RealPointer(call_int1c)); - /* IRQ 8 RTC Handler */ - call_int70=CALLBACK_Allocate(); - CALLBACK_Setup(call_int70,&INT70_Handler,CB_IRET,"Int 70 RTC"); - RealSetVec(0x70,CALLBACK_RealPointer(call_int70)); + mem_writed(BIOS_TIMER,0); //Calculate the correct time - /* Some defeault CPU error interrupt handlers */ - call_int1=CALLBACK_Allocate(); - CALLBACK_Setup(call_int1,&INT1_Single_Step,CB_IRET,"Int 1 Single step"); - RealSetVec(0x1,CALLBACK_RealPointer(call_int1)); + /* INT 11 Get equipment list */ + callback[1].Install(&INT11_Handler,CB_IRET,"Int 11 Equipment"); + callback[1].Set_RealVec(0x11); - /* Setup some stuff in 0x40 bios segment */ - /* Test for parallel port */ - if (IO_Read(0x378)!=0xff) real_writew(0x40,0x08,0x378); - /* Test for serial port */ - Bitu index=0; - if (IO_Read(0x3fa)!=0xff) real_writew(0x40,(index++)*2,0x3f8); - if (IO_Read(0x2fa)!=0xff) real_writew(0x40,(index++)*2,0x2f8); - /* Setup equipment list */ - Bitu config=0x4400; //1 Floppy, 2 serial and 1 parrallel + /* INT 12 Memory Size default at 640 kb */ + callback[2].Install(&INT12_Handler,CB_IRET,"Int 12 Memory"); + callback[2].Set_RealVec(0x12); + mem_writew(BIOS_MEMORY_SIZE,640); + + /* INT 13 Bios Disk Support */ + BIOS_SetupDisks(); + + callback[3].Install(&INT14_Handler,CB_IRET,"Int 14 COM-port"); + callback[3].Set_RealVec(0x14); + + /* INT 15 Misc Calls */ + callback[4].Install(&INT15_Handler,CB_IRET,"Int 15 Bios"); + callback[4].Set_RealVec(0x15); + + /* INT 16 Keyboard handled in another file */ + BIOS_SetupKeyboard(); + + /* INT 17 Printer Routines */ + callback[5].Install(&INT17_Handler,CB_IRET,"Int 17 Printer"); + callback[5].Set_RealVec(0x17); + + /* INT 1A TIME and some other functions */ + callback[6].Install(&INT1A_Handler,CB_IRET_STI,"Int 1a Time"); + callback[6].Set_RealVec(0x1A); + + /* INT 1C System Timer tick called from INT 8 */ + callback[7].Install(&INT1C_Handler,CB_IRET,"Int 1c Timer tick"); + callback[7].Set_RealVec(0x1C); + + /* IRQ 8 RTC Handler */ + callback[8].Install(&INT70_Handler,CB_IRET,"Int 70 RTC"); + callback[8].Set_RealVec(0x70); + + /* Some defeault CPU error interrupt handlers */ + callback[9].Install(&INT1_Single_Step,CB_IRET,"Int 1 Single step"); + callback[9].Set_RealVec(0x1); + + /* Setup some stuff in 0x40 bios segment */ + /* Test for parallel port */ + if (IO_Read(0x378)!=0xff) real_writew(0x40,0x08,0x378); + /* Test for serial port */ + Bitu index=0; + if (IO_Read(0x3fa)!=0xff) real_writew(0x40,(index++)*2,0x3f8); + if (IO_Read(0x2fa)!=0xff) real_writew(0x40,(index++)*2,0x2f8); + /* Setup equipment list */ + //1 Floppy, 2 serial and 1 parrallel + Bitu config=0x4400; #if (C_FPU) - config|=0x2; //FPU + //FPU + config|=0x2; #endif - switch (machine) { - case MCH_HERC: - config|=0x30; //Startup monochrome - break; - case MCH_CGA: case MCH_TANDY: - config|=0x20; //Startup 80x25 color - break; - default: - config|=0; //EGA VGA - break; + switch (machine) { + case MCH_HERC: + //Startup monochrome + config|=0x30; + break; + case MCH_CGA: + case MCH_TANDY: + //Startup 80x25 color + config|=0x20; + break; + default: + //EGA VGA + config|=0; + break; + } + // PS2 mouse + config |= 0x04; + mem_writew(BIOS_CONFIGURATION,config); + /* Setup extended memory size */ + IO_Write(0x70,0x30); + size_extended=IO_Read(0x71); + IO_Write(0x70,0x31); + size_extended|=(IO_Read(0x71) << 8); } - config |= 0x04; // PS2 mouse - mem_writew(BIOS_CONFIGURATION,config); - /* Setup extended memory size */ - IO_Write(0x70,0x30); - size_extended=IO_Read(0x71); - IO_Write(0x70,0x31); - size_extended|=(IO_Read(0x71) << 8); +}; + +static BIOS* test; + +void BIOS_Destroy(Section* sec){ + delete test; } - +void BIOS_Init(Section* sec) { + test = new BIOS(sec); + sec->AddDestroyFunction(&BIOS_Destroy,false); +} diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 4790310e..7025eba6 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.38 2005-02-10 10:21:11 qbix79 Exp $ */ +/* $Id: ems.cpp,v 1.39 2005-03-25 11:59:24 qbix79 Exp $ */ #include #include @@ -93,7 +93,7 @@ struct EMM_Handle { static EMM_Handle emm_handles[EMM_MAX_HANDLES]; static EMM_Mapping emm_mappings[EMM_MAX_PHYS]; -static Bitu call_int67,call_vdma; + struct MoveRegion { Bit32u bytes; @@ -609,40 +609,84 @@ static Bitu INT4B_Handler() { return CBRET_NONE; } -void EMS_Init(Section* sec) { + +class EMS: public Module_base { +private: + /* location in protected unfreeable memory where the ems name and callback are + * stored 32 bytes.*/ + static Bit16u emsnameseg; + RealPt old4b_pointer,old67_pointer; + CALLBACK_HandlerObject call_vdma,int67; + +public: + EMS(Section* configuration):Module_base(configuration){ + /* Virtual DMA interrupt callback */ - call_vdma=CALLBACK_Allocate(); - CALLBACK_Setup(call_vdma,&INT4B_Handler,CB_IRET,"Int 4b vdma"); - RealSetVec(0x4b,CALLBACK_RealPointer(call_vdma)); + call_vdma.Install(&INT4B_Handler,CB_IRET,"Int 4b vdma"); + call_vdma.Set_RealVec(0x4b); + + Section_prop * section=static_cast(configuration); + if (!section->Get_bool("ems")) return; + BIOS_ZeroExtendedSize(true); + int67.Install(&INT67_Handler,CB_IRET,"Int 67 ems"); + Bit16u call_int67=int67.Get_callback(); - Section_prop * section=static_cast(sec); - if (!section->Get_bool("ems")) return; - BIOS_ZeroExtendedSize(); - call_int67=CALLBACK_Allocate(); - CALLBACK_Setup(call_int67,&INT67_Handler,CB_IRET,"Int 67 ems"); -/* Register the ems device */ - DOS_Device * newdev = new device_EMM(); - DOS_AddDevice(newdev); + /* Register the ems device */ + //TODO MAYBE put it in the class. + DOS_Device * newdev = new device_EMM(); + DOS_AddDevice(newdev); + + /* Add a little hack so it appears that there is an actual ems device installed */ + char * emsname="EMMXXXX0"; + if(!emsnameseg) emsnameseg=DOS_GetMemory(2); //We have 32 bytes + MEM_BlockWrite(PhysMake(emsnameseg,0xa),emsname,strlen(emsname)+1); + /* Copy the callback piece into the beginning, and set the interrupt vector to it*/ + char buf[16]; + MEM_BlockRead(PhysMake(CB_SEG,call_int67<<4),buf,0xa); + MEM_BlockWrite(PhysMake(emsnameseg,0),buf,0xa); + RealSetVec(0x67,RealMake(emsnameseg,0),old67_pointer); + /* Clear handle and page tables */ + Bitu i; + for (i=0;i(m_configuration); + if (!section->Get_bool("ems")) return; + /* Undo Biosclearing */ + BIOS_ZeroExtendedSize(false); + + /* Remove ems device */ + device_EMM newdev; + DOS_DelDevice(&newdev); -/* Add a little hack so it appears that there is an actual ems device installed */ - char * emsname="EMMXXXX0"; - Bit16u seg=DOS_GetMemory(2); //We have 32 bytes - MEM_BlockWrite(PhysMake(seg,0xa),emsname,strlen(emsname)+1); -/* Copy the callback piece into the beginning, and set the interrupt vector to it*/ - char buf[16]; - MEM_BlockRead(PhysMake(CB_SEG,call_int67<<4),buf,0xa); - MEM_BlockWrite(PhysMake(seg,0),buf,0xa); - RealSetVec(0x67,RealMake(seg,0)); -/* Clear handle and page tables */ - Bitu i; - for (i=0;iAddDestroyFunction(&EMS_ShutDown,true); +} + +//Initialize static members +Bit16u EMS::emsnameseg = 0; diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 589670c7..3b2f683e 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.34 2005-02-10 10:21:11 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.35 2005-03-25 11:59:24 qbix79 Exp $ */ #include #include @@ -101,7 +101,6 @@ Bitu XMS_GetEnabledA20(void) return (IO_Read(0x92)&2)>0; }; -static Bit16u call_xms; static RealPt xms_callback; static XMS_Block xms_handles[XMS_HANDLES]; @@ -341,36 +340,63 @@ Bitu XMS_Handler(void) { // LOG(LOG_MISC,LOG_ERROR)("XMS: CALL Result: %02X",reg_bl); return CBRET_NONE; } - -void XMS_Init(Section* sec) { - - Section_prop * section=static_cast(sec); - if (!section->Get_bool("xms")) return; - Bitu i; - BIOS_ZeroExtendedSize(); - DOS_AddMultiplexHandler(multiplex_xms); - call_xms=CALLBACK_Allocate(); - CALLBACK_Setup(call_xms,&XMS_Handler,CB_RETF, "XMS Handler"); - xms_callback=CALLBACK_RealPointer(call_xms); - - /* Overide the callback with one that can be hooked */ - phys_writeb(CB_BASE+(call_xms<<4)+0,(Bit8u)0xeb); //jump near - phys_writeb(CB_BASE+(call_xms<<4)+1,(Bit8u)0x03); //offset - phys_writeb(CB_BASE+(call_xms<<4)+2,(Bit8u)0x90); //NOP - phys_writeb(CB_BASE+(call_xms<<4)+3,(Bit8u)0x90); //NOP - phys_writeb(CB_BASE+(call_xms<<4)+4,(Bit8u)0x90); //NOP - phys_writeb(CB_BASE+(call_xms<<4)+5,(Bit8u)0xFE); //GRP 4 - phys_writeb(CB_BASE+(call_xms<<4)+6,(Bit8u)0x38); //Extra Callback instruction - phys_writew(CB_BASE+(call_xms<<4)+7,call_xms); //The immediate word - phys_writeb(CB_BASE+(call_xms<<4)+9,(Bit8u)0xCB); //A RETF Instruction - - for (i=0;i(configuration); + if (!section->Get_bool("xms")) return; + Bitu i; + BIOS_ZeroExtendedSize(true); + DOS_AddMultiplexHandler(multiplex_xms); + callbackhandler.Install(&XMS_Handler,CB_RETF, "XMS Handler"); + xms_callback=callbackhandler.Get_RealPointer(); + Bit16u call_xms=callbackhandler.Get_callback(); + + /* Override the callback with one that can be hooked */ + phys_writeb(CB_BASE+(call_xms<<4)+0,(Bit8u)0xeb); //jump near + phys_writeb(CB_BASE+(call_xms<<4)+1,(Bit8u)0x03); //offset + phys_writeb(CB_BASE+(call_xms<<4)+2,(Bit8u)0x90); //NOP + phys_writeb(CB_BASE+(call_xms<<4)+3,(Bit8u)0x90); //NOP + phys_writeb(CB_BASE+(call_xms<<4)+4,(Bit8u)0x90); //NOP + phys_writeb(CB_BASE+(call_xms<<4)+5,(Bit8u)0xFE); //GRP 4 + phys_writeb(CB_BASE+(call_xms<<4)+6,(Bit8u)0x38); //Extra Callback instruction + phys_writew(CB_BASE+(call_xms<<4)+7,call_xms); //The immediate word + phys_writeb(CB_BASE+(call_xms<<4)+9,(Bit8u)0xCB); //A RETF Instruction + + for (i=0;i(m_configuration); + if (!section->Get_bool("xms")) return; + /* Undo biosclearing */ + BIOS_ZeroExtendedSize(false); + + /* Remove Multiplex */ + DOS_DelMultiplexHandler(multiplex_xms); + + /* Free used memory while skipping the 0 handle */ + for (Bitu i = 1;iAddDestroyFunction(&XMS_ShutDown,true); +} From 29d8dc723177cb799094410b96e0b018eecb1cf1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 12:00:08 +0000 Subject: [PATCH 2079/4131] header cleanup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2163 --- src/hardware/keyboard.cpp | 7 ++----- src/ints/int10.cpp | 5 ----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 2a87d51c..2c876379 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -16,11 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.30 2005-02-10 10:21:08 qbix79 Exp $ */ - -#include -#include -#include +/* $Id: keyboard.cpp,v 1.31 2005-03-25 11:55:20 qbix79 Exp $ */ #include "dosbox.h" #include "keyboard.h" @@ -28,6 +24,7 @@ #include "pic.h" #include "mem.h" #include "mixer.h" +#include "timer.h" #define KEYBUFSIZE 32 #define KEYDELAY 0.300f //Considering 20-30 khz serial clock and 11 bits/char diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index c3af071d..88f3968d 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -16,18 +16,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include #include "dosbox.h" -#include "bios.h" #include "mem.h" #include "callback.h" #include "regs.h" -#include "video.h" #include "inout.h" #include "int10.h" #include "setup.h" -#include "support.h" -#include "vga.h" Int10Data int10; static Bitu call_10; From 07b0ef0e82cf23db846fc0846638b944725e4acb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 12:00:52 +0000 Subject: [PATCH 2080/4131] new configuration support functions implementations Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2164 --- src/misc/setup.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 3b8e3bea..34aeed34 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.24 2005-02-10 10:21:11 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.25 2005-03-25 12:00:52 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -214,9 +214,9 @@ Section* Config::AddSection(const char* _name,void (*_initfunction)(Section*)){ return blah; } -Section_prop* Config::AddSection_prop(const char* _name,void (*_initfunction)(Section*)){ +Section_prop* Config::AddSection_prop(const char* _name,void (*_initfunction)(Section*),bool canchange){ Section_prop* blah = new Section_prop(_name); - blah->AddInitFunction(_initfunction); + blah->AddInitFunction(_initfunction,canchange); sectionlist.push_back(blah); return blah; } @@ -404,6 +404,17 @@ bool CommandLine::FindStringRemain(char * name,std::string & value) { return true; } +bool CommandLine::GetStringRemain(std::string & value) { + if(!cmds.size()) return false; + + cmd_it it=cmds.begin();value=(*it++); + for(;it != cmds.end();it++) { + value+=" "; + value+=(*it); + } + return true; +} + unsigned int CommandLine::GetCount(void) { return cmds.size(); @@ -449,4 +460,3 @@ CommandLine::CommandLine(char * name,char * cmdline) { } if (inword || inquote) cmds.push_back(str); } - From 6f5fde926774c940b4f6078bcac8ea7dc731bd5f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 12:03:50 +0000 Subject: [PATCH 2081/4131] new configuration layer. Removed shell_addautoexec and replaced it by objects. Fixed bug 1169240 and 1156163 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2165 --- src/shell/shell.cpp | 119 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 92 insertions(+), 27 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 7bb39b94..de4cda25 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,29 +16,39 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.56 2005-02-24 11:48:01 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.57 2005-03-25 12:03:50 qbix79 Exp $ */ #include #include #include +#include "dosbox.h" +#include "regs.h" #include "setup.h" #include "shell.h" +#include "callback.h" +#include "support.h" Bitu call_shellstop; +//Larger scope so shell_del autoexec can use it to +//remove things from the environment +Program * new_program = 0; static Bitu shellstop_handler(void) { return CBRET_STOP; } static void SHELL_ProgramStart(Program * * make) { - *make=new DOS_Shell; + *make = new DOS_Shell; } #define AUTOEXEC_SIZE 4096 -static char autoexec_data[AUTOEXEC_SIZE]={0}; +static char autoexec_data[AUTOEXEC_SIZE] = { 0 }; +static std::vector autoexec_strings; +typedef std::vector::iterator auto_it; -void SHELL_AddAutoexec(char * line,...) { - char buf[2048]; +void AutoexecObject::Install(char* line,...) { + if(installed) E_Exit("autoexec: allready created %s",buf); + installed = true; va_list msg; va_start(msg,line); @@ -50,6 +60,40 @@ void SHELL_AddAutoexec(char * line,...) { E_Exit("SYSTEM:Autoexec.bat file overflow"); } sprintf((autoexec_data+auto_len),"%s\r\n",buf); + autoexec_strings.push_back(std::string(buf)); +} + +void VFILE_Remove(const char *name); + +AutoexecObject::~AutoexecObject(){ + if(!installed) return; + VFILE_Remove("AUTOEXEC.BAT"); + // Remove the line from the autoexecbuffer + for(auto_it it = autoexec_strings.begin(); it != autoexec_strings.end(); ) { + if((*it) == buf) { + it = autoexec_strings.erase(it); + // If it's a environment variable remove it from there as well + if((strncasecmp(buf,"set ",4) == 0) && (strlen(buf) > 4)){ + char* after_set = buf + 4;//move to variable that is being set + char* test = strpbrk(after_set,"="); + if(!test) continue; + *test = 0; + //If the shell is running/exists update the environment + if(new_program) new_program->SetEnv(after_set,""); + } + } else it++; + } + //Create a new autoexec.bat + autoexec_data[0] = 0; + size_t auto_len; + for(auto_it it= autoexec_strings.begin(); it != autoexec_strings.end(); it++) { + auto_len = strlen(autoexec_data); + if ((auto_len+strlen((*it).c_str())+3)>AUTOEXEC_SIZE) { + E_Exit("SYSTEM:Autoexec.bat file overflow"); + } + sprintf((autoexec_data+auto_len),"%s\r\n",(*it).c_str()); + } + VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,strlen(autoexec_data)); } DOS_Shell::DOS_Shell():Program(){ @@ -120,39 +164,57 @@ void DOS_Shell::ParseLine(char * line) { Bit16u old_in,old_out; Bit16u dummy,dummy2; - Bitu num=0; /* Number of commands in this line */ + Bit32u bigdummy = 0; + Bitu num = 0; /* Number of commands in this line */ bool append; - + bool normalstdin=false; /* wether stdin/out are open on start. */ + bool normalstdout=false; /* Bug: Assumed is they are "con" */ + num = GetRedirection(line,&in, &out,&append); if (num>1) LOG_MSG("SHELL:Multiple command on 1 line not supported"); // if (in || num>1) DOS_DuplicateEntry(0,&old_in); - + + if (in || out) { + normalstdin = (psp->GetFileHandle(0)!=0xff); + normalstdout = (psp->GetFileHandle(1)!=0xff); + } if (in) { if(DOS_OpenFile(in,0,&dummy)) { //Test if file exists DOS_CloseFile(dummy); LOG_MSG("SHELL:Redirect input from %s",in); - DOS_CloseFile(0); //Close stdin + if(normalstdin) DOS_CloseFile(0); //Close stdin DOS_OpenFile(in,0,&dummy);//Open new stdin } } if (out){ LOG_MSG("SHELL:Redirect output to %s",out); - DOS_CloseFile(1); + if(normalstdout) DOS_CloseFile(1); + if(!normalstdin && !in) DOS_OpenFile("con",2,&dummy); + bool status = true; /* Create if not exist. Open if exist. Both in read/write mode */ - if(!DOS_OpenFileExtended(out,2,2,0x11,&dummy,&dummy2)) - DOS_OpenFile("con",2,&dummy); //Read only file, open con again + if(append){ + if( (status=DOS_OpenFile(out,2,&dummy)) ) + DOS_SeekFile(1,&bigdummy,DOS_SEEK_END); + } + else + status=DOS_OpenFileExtended(out,2,2,0x12,&dummy,&dummy2); + + if(!status && normalstdout) DOS_OpenFile("con",2,&dummy); //Read only file, open con again + if(!normalstdin && !in) DOS_CloseFile(0); } /* Run the actual command */ DoCommand(line); /* Restore handles */ if(in) { DOS_CloseFile(0); - DOS_OpenFile("con",2,&dummy); + if(normalstdin) DOS_OpenFile("con",2,&dummy); free(in); } - if(out) { + if(out) { DOS_CloseFile(1); - DOS_OpenFile("con",2,&dummy); + if(!normalstdin) DOS_OpenFile("con",2,&dummy); + if(normalstdout) DOS_OpenFile("con",2,&dummy); + if(!normalstdin) DOS_CloseFile(0); free(out); } } @@ -222,17 +284,19 @@ void DOS_Shell::SyntaxError(void) { WriteOut(MSG_Get("SHELL_SYNTAXERROR")); } - +namespace{ + AutoexecObject autoexec[6]; +} void AUTOEXEC_Init(Section * sec) { /* Register a virtual AUOEXEC.BAT file */ std::string line; Section_line * section=static_cast(sec); char * extra=(char *)section->data.c_str(); - if (extra) SHELL_AddAutoexec("%s",extra); + if (extra) autoexec[0].Install("%s",extra); /* Check to see for extra command line options to be added (before the command specified on commandline) */ while (control->cmdline->FindString("-c",line,true)) - SHELL_AddAutoexec((char *)line.c_str()); + autoexec[1].Install((char *)line.c_str()); /* Check for the -exit switch which causes dosbox to when the command on the commandline has finished */ bool addexit = control->cmdline->FindExist("-exit",true); @@ -248,25 +312,25 @@ void AUTOEXEC_Init(Section * sec) { if (stat(buffer,&test)) goto nomount; } if (test.st_mode & S_IFDIR) { - SHELL_AddAutoexec("MOUNT C \"%s\"",buffer); - SHELL_AddAutoexec("C:"); + autoexec[2].Install("MOUNT C \"%s\"",buffer); + autoexec[3].Install("C:"); } else { char * name=strrchr(buffer,CROSS_FILESPLIT); if (!name) goto nomount; *name++=0; if (access(buffer,F_OK)) goto nomount; - SHELL_AddAutoexec("MOUNT C \"%s\"",buffer); - SHELL_AddAutoexec("C:"); + autoexec[2].Install("MOUNT C \"%s\"",buffer); + autoexec[3].Install("C:"); upcase(name); if(strstr(name,".BAT")==0) { - SHELL_AddAutoexec(name); + autoexec[4].Install(name); } else { char call[CROSS_LEN] = { 0 }; strcpy(call,"CALL "); strcat(call,name); - SHELL_AddAutoexec(call); + autoexec[4].Install(call); } - if(addexit) SHELL_AddAutoexec("exit"); + if(addexit) autoexec[5].Install("exit"); } } nomount: @@ -400,7 +464,7 @@ void SHELL_Init() { DOS_PSP psp(psp_seg); psp.MakeNew(0); dos.psp(psp_seg); - + /* The start of the filetable in the psp must look like this: * 01 01 01 00 02 * In order to achieve this: First open 2 files. Close the first and @@ -428,8 +492,9 @@ void SHELL_Init() { dos.dta(RealMake(psp_seg,0x80)); dos.psp(psp_seg); - Program * new_program; + SHELL_ProgramStart(&new_program); new_program->Run(); delete new_program; + new_program=0;//Make clear that it shouldn't be used anymore } From 6d91a47d24c087cf5d85a85b7d44006f0c982a41 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 12:05:21 +0000 Subject: [PATCH 2082/4131] New configuration. runtime changing of midi handler is possible. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2166 --- src/gui/midi.cpp | 92 ++++++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 39 deletions(-) diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 79be6d75..8b8b2c07 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -231,49 +231,63 @@ bool MIDI_Available(void) { return midi.available; } -static void MIDI_Stop(Section* sec) { - if (midi.raw.handle) MIDI_SaveRawEvent(); -} -void MIDI_Init(Section * sec) { - Section_prop * section=static_cast(sec); - const char * dev=section->Get_string("device"); - const char * conf=section->Get_string("config"); - /* If device = "default" go for first handler that works */ - MidiHandler * handler; - MAPPER_AddHandler(MIDI_SaveRawEvent,MK_f8,MMOD1|MMOD2,"caprawmidi","Cap MIDI"); - sec->AddDestroyFunction(&MIDI_Stop); - midi.status=0x00; - midi.cmd_pos=0; - midi.cmd_len=0; - midi.raw.capturing=false; - if (!strcasecmp(dev,"default")) goto getdefault; - handler=handler_list; - while (handler) { - if (!strcasecmp(dev,handler->GetName())) { - if (!handler->Open(conf)) { - LOG_MSG("MIDI:Can't open device:%s with config:%s.",dev,conf); - goto getdefault; +class MIDI:public Module_base{ +public: + MIDI(Section* configuration):Module_base(configuration){ + Section_prop * section=static_cast(configuration); + const char * dev=section->Get_string("device"); + const char * conf=section->Get_string("config"); + /* If device = "default" go for first handler that works */ + MidiHandler * handler; + //TODO!!!!!!!!!!!!!!! +// MAPPER_AddHandler(MIDI_SaveRawEvent,MK_f8,MMOD1|MMOD2,"caprawmidi","Cap MIDI"); + midi.status=0x00; + midi.cmd_pos=0; + midi.cmd_len=0; + midi.raw.handle=0; + midi.raw.capturing=false; + if (!strcasecmp(dev,"default")) goto getdefault; + handler=handler_list; + while (handler) { + if (!strcasecmp(dev,handler->GetName())) { + if (!handler->Open(conf)) { + LOG_MSG("MIDI:Can't open device:%s with config:%s.",dev,conf); + goto getdefault; + } + midi.handler=handler; + midi.available=true; + LOG_MSG("MIDI:Opened device:%s",handler->GetName()); + return; } - midi.handler=handler; - midi.available=true; - LOG_MSG("MIDI:Opened device:%s",handler->GetName()); - return; + handler=handler->next; } - handler=handler->next; - } - LOG_MSG("MIDI:Can't find device:%s, finding default handler.",dev); + LOG_MSG("MIDI:Can't find device:%s, finding default handler.",dev); getdefault: - handler=handler_list; - while (handler) { - if (handler->Open(conf)) { - midi.available=true; - midi.handler=handler; - LOG_MSG("MIDI:Opened device:%s",handler->GetName()); - return; + handler=handler_list; + while (handler) { + if (handler->Open(conf)) { + midi.available=true; + midi.handler=handler; + LOG_MSG("MIDI:Opened device:%s",handler->GetName()); + return; + } + handler=handler->next; } - handler=handler->next; + /* This shouldn't be possible */ } - /* This shouldn't be possible */ + ~MIDI(){ + if(midi.raw.handle) MIDI_SaveRawEvent(); + if(midi.available) midi.handler->Close(); + midi.available = false; + midi.handler = 0; + } +}; +static MIDI* test; +void MIDI_Destroy(Section* sec){ + delete test; +} +void MIDI_Init(Section * sec) { + test = new MIDI(sec); + sec->AddDestroyFunction(&MIDI_Destroy,true); } - From 2fb7849006666346e5b3cec9c3cab7738a38ea7b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 12:06:48 +0000 Subject: [PATCH 2083/4131] New configuration system. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2167 --- src/dos/dos.cpp | 119 ++++++++++++++++++++++++------------------------ 1 file changed, 59 insertions(+), 60 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 259b7bd5..3b3c7410 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,9 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.82 2005-02-24 11:35:32 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.83 2005-03-25 12:06:48 qbix79 Exp $ */ -#include #include #include #include @@ -38,8 +37,6 @@ DOS_InfoBlock dos_infoblock; #define DOS_COPYBUFSIZE 0x10000 Bit8u dos_copybuf[DOS_COPYBUFSIZE]; -static Bitu call_20,call_21,call_25,call_26,call_27,call_28,call_29; - void DOS_SetError(Bit16u code) { dos.errorcode=code; } @@ -996,64 +993,66 @@ static Bitu DOS_29Handler(void) { } -void DOS_ShutDown(Section* sec) -{ - for (Bit16u i=0;itm_mday; + dos.date.month=(Bit8u)loctime->tm_mon+1; + dos.date.year=(Bit16u)loctime->tm_year+1900; + Bit32u ticks=(Bit32u)((loctime->tm_hour*3600+loctime->tm_min*60+loctime->tm_sec)*18.2); + mem_writed(BIOS_TIMER,ticks); + } + ~DOS(){ + for (Bit16u i=0;itm_mday; - dos.date.month=(Bit8u)loctime->tm_mon+1; - dos.date.year=(Bit16u)loctime->tm_year+1900; - Bit32u ticks=(Bit32u)((loctime->tm_hour*3600+loctime->tm_min*60+loctime->tm_sec)*18.2); - mem_writed(BIOS_TIMER,ticks); - - /* shutdown function */ - sec->AddDestroyFunction(&DOS_ShutDown); - +void DOS_ShutDown(Section* sec) { + delete test; } +void DOS_Init(Section* sec) { + test = new DOS(sec); + /* shutdown function */ + sec->AddDestroyFunction(&DOS_ShutDown,false); +} From e1df80f704f7616c9e9f324eccd6888878228acf Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 29 Mar 2005 07:05:44 +0000 Subject: [PATCH 2084/4131] recheck irqs when special mode changes. Makes more sense, might fix something. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2168 --- src/hardware/pic.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 725b0b5e..4b252f37 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.29 2005-03-25 11:54:52 qbix79 Exp $ */ +/* $Id: pic.cpp,v 1.30 2005-03-29 07:05:44 qbix79 Exp $ */ #include @@ -97,6 +97,10 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { if(pic[0].special || pics[1].special) PIC_Special_Mode = true; else PIC_Special_Mode = false; + if (PIC_IRQCheck) { //Recheck irqs + CPU_CycleLeft += CPU_Cycles; + CPU_Cycles = 0; + } LOG(LOG_PIC,LOG_NORMAL)("port %X : special mask %s",port,(pic->special)?"ON":"OFF"); } } else { // OCW2 issued From e5b9049ac528ced86bdc808ea5fd453839fe409f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 1 Apr 2005 10:15:26 +0000 Subject: [PATCH 2085/4131] added include for support.h. Fixes bug 1173820 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2169 --- src/shell/shell_misc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 9c86d91f..e2cf2a47 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.36 2005-03-25 09:02:46 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.37 2005-04-01 10:15:26 qbix79 Exp $ */ #include #include @@ -25,6 +25,7 @@ #include "shell.h" #include "regs.h" #include "callback.h" +#include "support.h" void DOS_Shell::ShowPrompt(void) { Bit8u drive=DOS_GetDefaultDrive()+'A'; From 0b0dac3832cbc548a02c545835ffe9fe2ed7a829 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 3 Apr 2005 17:37:09 +0000 Subject: [PATCH 2086/4131] fix remaining part of 1156163 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2170 --- src/shell/shell.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index de4cda25..893b16e0 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.57 2005-03-25 12:03:50 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.58 2005-04-03 17:37:09 qbix79 Exp $ */ #include #include @@ -124,6 +124,8 @@ Bitu DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn,bool * append) { if (*ofn) free(*ofn); *ofn=lr; while (*lr && *lr!=' ') lr++; + //if it ends on a : => remove it. + if((*ofn != lr) && (lr[-1] == ':')) lr[-1] = 0; if(*lr && *(lr+1)) *lr++=0; else @@ -135,6 +137,7 @@ Bitu DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn,bool * append) { lr=ltrim(lr); *ifn=lr; while (*lr && *lr!=' ') lr++; + if((*ifn != lr) && (lr[-1] == ':')) lr[-1] = 0; if(*lr && *(lr+1)) *lr++=0; else From 689cceafb5bcabf4c1b1277ac075963a06c4842e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 5 Apr 2005 11:10:08 +0000 Subject: [PATCH 2087/4131] new configuration system. Apply patch 1156149 from moe Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2171 --- src/hardware/hardware.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 9bfe32e6..9b013c1e 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -42,6 +42,7 @@ FILE * OpenCaptureFile(const char * type,const char * ext) { return 0; } strcpy(file_start,RunningProgram); + lowcase(file_start); strcat(file_start,"_"); while ((dir_ent=readdir(dir))) { char tempname[CROSS_LEN]; @@ -55,7 +56,6 @@ FILE * OpenCaptureFile(const char * type,const char * ext) { } closedir(dir); sprintf(file_name,"%s%c%s%03d%s",capturedir,CROSS_FILESPLIT,file_start,last,ext); - lowcase(file_name); /* Open the actual file */ FILE * handle=fopen(file_name,"wb"); if (handle) { @@ -66,9 +66,22 @@ FILE * OpenCaptureFile(const char * type,const char * ext) { return handle; } +class HARDWARE:public Module_base{ +public: + HARDWARE(Section* configuration):Module_base(configuration){ + Section_prop * section = static_cast(configuration); + capturedir = (char *)section->Get_string("captures"); + } + ~HARDWARE(){ } +}; -void HARDWARE_Init(Section * sec) { - Section_prop * section=static_cast(sec); - capturedir=(char *)section->Get_string("captures"); +static HARDWARE* test; + +void HARDWARE_Destroy(Section * sec) { + delete test; } +void HARDWARE_Init(Section * sec) { + test = new HARDWARE(sec); + sec->AddDestroyFunction(&HARDWARE_Destroy,true); +} From 902e09a4ecbccfb779a79ba8403961904d39354d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 5 Apr 2005 16:25:09 +0000 Subject: [PATCH 2088/4131] Removed unused function. Changed ADPCM routines to the ones of kode54 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2172 --- src/hardware/sblaster.cpp | 108 ++++++++++++++++++++++++++++---------- 1 file changed, 81 insertions(+), 27 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 49d02c4c..73cc80d9 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -241,49 +241,103 @@ static void DSP_DMA_CallBack(DmaChannel * chan, DMAEvent event) { } } -#define MIN_ADAPTIVE_STEP_SIZE 511 +#define MIN_ADAPTIVE_STEP_SIZE 0 #define MAX_ADAPTIVE_STEP_SIZE 32767 #define DC_OFFSET_FADE 254 -static INLINE Bits Clip(Bits sample) { - if (sample>MAX_AUDIO) return MAX_AUDIO; - if (sample 63)) { + LOG(LOG_SB,LOG_ERROR)("Bad ADPCM-4 sample"); + if(samp < 0 ) samp = 0; + if(samp > 63) samp = 63; } - scale = max(2, min(6, scaleMap[sample & 0x07])); + + Bits ref = reference + scaleMap[samp]; + if (ref > 0xff) reference = 0xff; + else if (ref < 0x00) reference = 0x00; + else reference = ref; + scale = (scale + adjustMap[samp]) & 0xff; + return reference; } static INLINE Bit8u decode_ADPCM_2_sample(Bit8u sample,Bit8u & reference,Bits& scale) { - static Bits scaleMap[8] = { -2, -1, 0, 0, 1, 1, 1, 1 }; + static const Bit8s scaleMap[24] = { + 0, 1, 0, -1, 1, 3, -1, -3, + 2, 6, -2, -6, 4, 12, -4, -12, + 8, 24, -8, -24, 6, 48, -16, -48 + }; + static const Bit8u adjustMap[24] = { + 0, 4, 0, 4, + 252, 4, 252, 4, 252, 4, 252, 4, + 252, 4, 252, 4, 252, 4, 252, 4, + 252, 0, 252, 0 + }; - if (sample & 0x02) { - reference = max(0x00, reference - ((sample & 0x01) << (scale+2))); - } else { - reference = min(0xff, reference + ((sample & 0x01) << (scale+2))); + Bits samp = sample + scale; + if ((samp < 0) || (samp > 23)) { + LOG(LOG_SB,LOG_ERROR)("Bad ADPCM-2 sample"); + if(samp < 0 ) samp = 0; + if(samp > 23) samp = 23; } - scale = max(2, min(6, scaleMap[sample & 0x07])); + + Bits ref = reference + scaleMap[samp]; + if (ref > 0xff) reference = 0xff; + else if (ref < 0x00) reference = 0x00; + else reference = ref; + scale = (scale + adjustMap[samp]) & 0xff; + return reference; } INLINE Bit8u decode_ADPCM_3_sample(Bit8u sample,Bit8u & reference,Bits& scale) { - static Bits scaleMap[8] = { -2, -1, 0, 0, 1, 1, 1, 1 }; + static const Bit8s scaleMap[40] = { + 0, 1, 2, 3, 0, -1, -2, -3, + 1, 3, 5, 7, -1, -3, -5, -7, + 2, 6, 10, 14, -2, -6, -10, -14, + 4, 12, 20, 28, -4, -12, -20, -28, + 5, 15, 25, 35, -5, -15, -25, -35 + }; + static const Bit8u adjustMap[40] = { + 0, 0, 0, 8, 0, 0, 0, 8, + 248, 0, 0, 8, 248, 0, 0, 8, + 248, 0, 0, 8, 248, 0, 0, 8, + 248, 0, 0, 8, 248, 0, 0, 8, + 248, 0, 0, 0, 248, 0, 0, 0 + }; - if (sample & 0x04) { - reference = max(0x00, reference - ((sample & 0x03) << (scale+1))); - } else { - reference = min(0xff, reference + ((sample & 0x03) << (scale+1))); + Bits samp = sample + scale; + if ((samp < 0) || (samp > 39)) { + LOG(LOG_SB,LOG_ERROR)("Bad ADPCM-3 sample"); + if(samp < 0 ) samp = 0; + if(samp > 39) samp = 39; } - scale = max(2, min(6, scaleMap[sample & 0x07])); + + Bits ref = reference + scaleMap[samp]; + if (ref > 0xff) reference = 0xff; + else if (ref < 0x00) reference = 0x00; + else reference = ref; + scale = (scale + adjustMap[samp]) & 0xff; + return reference; } @@ -320,7 +374,7 @@ static void GenerateDMASound(Bitu size) { for (;i> 5) & 0x7,sb.adpcm.reference,sb.adpcm.stepsize); MixTemp[done++]=decode_ADPCM_3_sample((sb.dma.buf.b8[i] >> 2) & 0x7,sb.adpcm.reference,sb.adpcm.stepsize); - MixTemp[done++]=decode_ADPCM_2_sample((sb.dma.buf.b8[i] >> 0) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize); + MixTemp[done++]=decode_ADPCM_3_sample((sb.dma.buf.b8[i] & 0x3) << 1,sb.adpcm.reference,sb.adpcm.stepsize); } sb.chan->AddSamples_m8(done,MixTemp); break; @@ -888,7 +942,7 @@ static Bit8u CTMIXER_Read(void) { case 0x22: /* Master Volume (SBPRO) */ return MAKEPROVOL(sb.mixer.master); case 0x04: /* DAC Volume (SBPRO) */ - return MAKEPROVOL(sb.mixer.dac); + return MAKEPROVOL(sb.mixer.dac); // case 0x06: /* FM output selection, Somewhat obsolete with dual OPL SBpro */ case 0x0a: /* Mic Level (SBPRO) */ return (sb.mixer.mic >> 1); From 45851e3051cfe990360e0bbc469915e5b416c523 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 6 Apr 2005 20:48:14 +0000 Subject: [PATCH 2089/4131] Fix small bug in intro cdrom, making it hard to translate Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2173 --- src/dos/dos_programs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 6e8719a8..6e73336c 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.35 2005-03-01 07:19:38 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.36 2005-04-06 20:48:14 qbix79 Exp $ */ #include #include @@ -757,7 +757,7 @@ void DOS_SetupPrograms(void) { "\n" "Replace \033[0;31mD:\\\033[0m with the location of your CD-ROM.\n" "Replace the \033[33;1m0\033[0m in \033[34;1m-usecd \033[33m0\033[0m with the number reported for your CD-ROM if you type:\n" - "\033[34;1mmount -cd\033[0m" + "\033[34;1mmount -cd\033[0m\n" ); MSG_Add("PROGRAM_BOOT_NOT_EXIST","Bootdisk file does not exist. Failing.\n"); MSG_Add("PROGRAM_BOOT_NOT_OPEN","Cannot open bootdisk file. Failing.\n"); From fcd741c15e8d2bc8c7d0362a8f23ed97ec094c33 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Apr 2005 17:56:27 +0000 Subject: [PATCH 2090/4131] added range checks to accessing the drive structure. Cleaned it up as well. (Indeed I read it). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2174 --- src/dos/dos_ioctl.cpp | 55 ++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 35 deletions(-) diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 4b150c33..3aa23026 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.23 2005-03-25 08:39:05 qbix79 Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.24 2005-04-11 17:56:27 qbix79 Exp $ */ #include #include "dosbox.h" @@ -26,7 +26,7 @@ #include "dos_inc.h" bool DOS_IOCTL(void) { - Bitu handle;Bit8u drive; + Bitu handle=0;Bit8u drive=0; if (reg_al<8) { /* call 0-7 use a file handle */ handle=RealHandle(reg_bx); if (handle>=DOS_FILES) { @@ -37,6 +37,12 @@ bool DOS_IOCTL(void) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; } + } else { /* the others use a diskdrive */ + drive=reg_bl;if (!drive) drive=dos.current_drive;else drive--; + if( !(( drive < DOS_DRIVES ) && Drives[drive]) ) { + DOS_SetError(DOSERR_INVALID_DRIVE); + return false; + } } switch(reg_al) { case 0x00: /* Get Device Information */ @@ -66,34 +72,20 @@ bool DOS_IOCTL(void) { reg_al=0xff; return true; case 0x08: /* Check if block device removable */ - drive=reg_bl;if (!drive) drive=dos.current_drive;else drive--; - if (Drives[drive]) { - /* Drive a,b are removable if mounted * - * So are cdrom drives */ - if (drive < 2 || Drives[drive]->isRemovable()) - reg_ax=0; - else reg_ax=1; - return true; - } else { - DOS_SetError(DOSERR_INVALID_DRIVE); - return false; - } + /* cdrom drives and drive a&b are removable */ + if (drive < 2 || Drives[drive]->isRemovable()) + reg_ax=0; + else reg_ax=1; + return true; case 0x09: /* Check if block device remote */ - drive=reg_bl;if (!drive) drive=dos.current_drive;else drive--; - if (Drives[drive]) { - reg_dx=0; - if (Drives[drive]->isRemote()) reg_dx|=(1 << 12); - //TODO Set bit 9 on drives that don't support direct I/O - reg_al=0; - return true; - } else { - DOS_SetError(DOSERR_INVALID_DRIVE); - return false; - } + reg_dx=0; + if (Drives[drive]->isRemote()) reg_dx|=(1 << 12); + //TODO Set bit 9 on drives that don't support direct I/O + reg_al=0; + return true; case 0x0D: /* Generic block device request */ { PhysPt ptr = SegPhys(ds)+reg_dx; - drive=reg_bl;if (!drive) drive=dos.current_drive;else drive--; switch (reg_cl) { case 0x60: /* Get Device parameters */ mem_writeb(ptr ,0x03); // special function @@ -138,15 +130,8 @@ bool DOS_IOCTL(void) { return true; } case 0xE: /* Get Logical Drive Map */ - drive=reg_bl;if (!drive) drive=dos.current_drive;else drive--; - if (Drives[drive]) { - reg_al=0; /* Only 1 logical drive assigned */ - return true; - } else { - DOS_SetError(DOSERR_INVALID_DRIVE); - return false; - } - break; + reg_al = 0; /* Only 1 logical drive assigned */ + return true; default: LOG(LOG_DOSMISC,LOG_ERROR)("DOS:IOCTL Call %2X unhandled",reg_al); return false; From a17faf3c491171684a1e6595a21d275e22b1eb33 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 15 Apr 2005 14:20:42 +0000 Subject: [PATCH 2091/4131] idiv and friends shouldn't touch registers if an overflow occurs. (Thanks wd!) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2175 --- src/cpu/core_dyn_x86/helpers.h | 46 +++++++++++++++++++++------------- src/cpu/instructions.h | 46 +++++++++++++++++++++------------- 2 files changed, 58 insertions(+), 34 deletions(-) diff --git a/src/cpu/core_dyn_x86/helpers.h b/src/cpu/core_dyn_x86/helpers.h index 6fa75b3a..b1e67759 100644 --- a/src/cpu/core_dyn_x86/helpers.h +++ b/src/cpu/core_dyn_x86/helpers.h @@ -1,18 +1,22 @@ static bool dyn_helper_divb(Bit8u val) { if (!val) return CPU_PrepareException(0,0); Bitu quo=reg_ax / val; - reg_ah=(Bit8u)(reg_ax % val); - reg_al=(Bit8u)quo; + 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; - reg_ah=(Bit8s)((Bit16s)reg_ax % val); - reg_al=(Bit8s)quo; - if (quo!=(Bit8s)reg_al) return CPU_PrepareException(0,0); + 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; } @@ -20,9 +24,11 @@ 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; - reg_dx=(Bit16u)(num % val); - reg_ax=(Bit16u)quo; - if (quo!=reg_ax) return CPU_PrepareException(0,0); + 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; } @@ -30,9 +36,11 @@ 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; - reg_dx=(Bit16s)(num % val); - reg_ax=(Bit16s)quo; - if (quo!=(Bit16s)reg_ax) return CPU_PrepareException(0,0); + 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; } @@ -40,9 +48,11 @@ 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; - reg_edx=(Bit32u)(num % val); - reg_eax=(Bit32u)quo; - if (quo!=(Bit64u)reg_eax) return CPU_PrepareException(0,0); + 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; } @@ -50,8 +60,10 @@ 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; - reg_edx=(Bit32s)(num % val); - reg_eax=(Bit32s)(quo); - if (quo!=(Bit64s)((Bit32s)reg_eax)) return CPU_PrepareException(0,0); + 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; } diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index a6994f5f..563c401b 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -599,9 +599,11 @@ Bitu val=load(op1); \ if (val==0) EXCEPTION(0); \ Bitu quo=reg_ax / val; \ - reg_ah=(Bit8u)(reg_ax % val); \ - reg_al=(Bit8u)quo; \ + Bit8u rem=(Bit8u)(reg_ax % val); \ + Bit8u quo8=(Bit8u)(quo&0xff); \ if (quo>0xff) EXCEPTION(0); \ + reg_ah=rem; \ + reg_al=quo8; \ } @@ -611,9 +613,11 @@ if (val==0) EXCEPTION(0); \ Bitu num=(reg_dx<<16)|reg_ax; \ Bitu quo=num/val; \ - reg_dx=(Bit16u)(num % val); \ - reg_ax=(Bit16u)quo; \ - if (quo>0xffff) EXCEPTION(0); \ + Bit16u rem=(Bit16u)(num % val); \ + Bit16u quo16=(Bit16u)(quo&0xffff); \ + if (quo!=(Bit32u)quo16) EXCEPTION(0); \ + reg_dx=rem; \ + reg_ax=quo16; \ } #define DIVD(op1,load,save) \ @@ -622,9 +626,11 @@ if (!val) EXCEPTION(0); \ Bit64u num=(((Bit64u)reg_edx)<<32)|reg_eax; \ Bit64u quo=num/val; \ - reg_edx=(Bit32u)(num % val); \ - reg_eax=(Bit32u)quo; \ - if (quo!=(Bit64u)reg_eax) EXCEPTION(0); \ + Bit32u rem=(Bit32u)(num % val); \ + Bit32u quo32=(Bit32u)(quo&0xffffffff); \ + if (quo!=(Bit64u)quo32) EXCEPTION(0); \ + reg_edx=rem; \ + reg_eax=quo32; \ } @@ -633,9 +639,11 @@ Bits val=(Bit8s)(load(op1)); \ if (val==0) EXCEPTION(0); \ Bits quo=((Bit16s)reg_ax) / val; \ - reg_ah=(Bit8s)(((Bit16s)reg_ax) % val); \ - reg_al=(Bit8s)quo; \ - if (quo!=(Bit8s)reg_al) EXCEPTION(0); \ + Bit8s rem=(Bit8s)((Bit16s)reg_ax % val); \ + Bit8s quo8s=(Bit8s)(quo&0xff); \ + if (quo!=(Bit16s)quo8s) EXCEPTION(0); \ + reg_ah=rem; \ + reg_al=quo8s; \ } @@ -645,9 +653,11 @@ if (!val) EXCEPTION(0); \ Bits num=(Bit32s)((reg_dx<<16)|reg_ax); \ Bits quo=num/val; \ - reg_dx=(Bit16u)(num % val); \ - reg_ax=(Bit16s)quo; \ - if (quo!=(Bit16s)reg_ax) EXCEPTION(0); \ + Bit16s rem=(Bit16s)(num % val); \ + Bit16s quo16s=(Bit16s)quo; \ + if (quo!=(Bit32s)quo16s) EXCEPTION(0); \ + reg_dx=rem; \ + reg_ax=quo16s; \ } #define IDIVD(op1,load,save) \ @@ -656,9 +666,11 @@ if (!val) EXCEPTION(0); \ Bit64s num=(((Bit64u)reg_edx)<<32)|reg_eax; \ Bit64s quo=num/val; \ - reg_edx=(Bit32s)(num % val); \ - reg_eax=(Bit32s)(quo); \ - if (quo!=(Bit64s)((Bit32s)reg_eax)) EXCEPTION(0); \ + Bit32s rem=(Bit32s)(num % val); \ + Bit32s quo32s=(Bit32s)(quo&0xffffffff); \ + if (quo!=(Bit64s)quo32s) EXCEPTION(0); \ + reg_edx=rem; \ + reg_eax=quo32s; \ } #define IMULB(op1,load,save) \ From 4f23142ddf5352d43472ec94691193b77cb24411 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 15 Apr 2005 15:58:07 +0000 Subject: [PATCH 2092/4131] gob1 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2176 --- src/dos/cdrom_image.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 6377959f..4684102b 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.6 2005-03-25 09:05:04 qbix79 Exp $ */ +/* $Id: cdrom_image.cpp,v 1.7 2005-04-15 15:58:07 qbix79 Exp $ */ #include #include @@ -256,7 +256,7 @@ bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long s Bitu buflen = num * sectorSize; Bit8u* buf = new Bit8u[buflen]; - bool success; + bool success = true; //Gobliiins reads 0 sectors for(int i = 0; i < num; i++) { success = ReadSector(&buf[i * sectorSize], raw, sector); if (!success) break; From 226a00ce8657207be8bde6f51e74080988eadf1a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 18 Apr 2005 18:46:27 +0000 Subject: [PATCH 2093/4131] added Patch 1185274 from moe. Adds another key for backspace for some linux terminals Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2177 --- src/debug/debug.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index f9b0262e..65e8503c 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.62 2005-02-10 10:20:50 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.63 2005-04-18 18:46:27 qbix79 Exp $ */ #include #include @@ -1375,6 +1375,7 @@ Bit32u DEBUG_CheckKeys(void) { ParseCommand(codeViewData.inputStr); break; case 0x107: //backspace (linux) + case 0x7f: //backspace in some terminal emulators (linux) case 0x08: // delete if (strlen(codeViewData.inputStr)>0) codeViewData.inputStr[strlen(codeViewData.inputStr)-1] = 0; break; From 77f14da8f061e7d520abd763ae60d88e7877a57c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 19 Apr 2005 08:28:41 +0000 Subject: [PATCH 2094/4131] added patch 1174832 by moe. lock and xadd in corefull/normal/simple Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2178 --- src/cpu/core_full/load.h | 3 +++ src/cpu/core_full/optable.h | 8 ++++---- src/cpu/core_full/support.h | 1 + src/cpu/core_normal/prefix_0f.h | 14 ++++++++++++++ src/cpu/core_normal/prefix_66_0f.h | 7 +++++++ src/cpu/core_normal/prefix_none.h | 2 +- 6 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 3a63a3de..cfe87413 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -427,6 +427,9 @@ l_M_Ed: goto nextopcode; case D_WAIT: case D_NOP: + case D_LOCK: /* FIXME: according to intel, LOCK should raise an exception if it's not followed by one of a small set of instructions; + probably doesn't matter for our purposes as it is a pentium prefix anyhow */ + LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK"); goto nextopcode; case D_ENTERw: { diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 4e60876a..683ec41e 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -171,7 +171,7 @@ static OpCode OpCodeTable[1024]={ {L_REGw ,O_OUTb ,0 ,REGI_DX},{L_REGw ,O_OUTw ,0 ,REGI_DX}, /* 0xf0 - 0xf7 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{D_LOCK ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {L_PREREPNE ,0 ,0 ,0 },{L_PREREP ,0 ,0 ,0 }, {D_HLT ,0 ,0 ,0 },{D_CMC ,0 ,0 ,0 }, {L_MODRM ,8 ,0 ,M_GRP },{L_MODRM ,9 ,0 ,M_GRP }, @@ -316,7 +316,7 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,0 ,S_Gw ,M_Ebx },{L_MODRM ,0 ,S_Gw ,M_Ewx }, /* 0x1c0 - 0x1cc */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,t_ADDb ,S_EbGb ,M_GbEb },{L_MODRM ,t_ADDw ,S_EwGw ,M_GwEw }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, @@ -526,7 +526,7 @@ static OpCode OpCodeTable[1024]={ {L_REGw ,O_OUTb ,0 ,REGI_DX},{L_REGw ,O_OUTd ,0 ,REGI_DX}, /* 0x2f0 - 0x2f7 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{D_LOCK ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {L_PREREPNE ,0 ,0 ,0 },{L_PREREP ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{D_CMC ,0 ,0 ,0 }, {L_MODRM ,8 ,0 ,M_GRP },{L_MODRM ,0xa ,0 ,M_GRP }, @@ -672,7 +672,7 @@ static OpCode OpCodeTable[1024]={ {L_MODRM ,0 ,S_Gd ,M_Ebx },{L_MODRM ,0 ,S_Gd ,M_Ewx }, /* 0x3c0 - 0x3cc */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,t_ADDb ,S_EbGb ,M_GbEb },{L_MODRM ,t_ADDd ,S_EdGd ,M_GdEd }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 120a854d..5521daae 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -45,6 +45,7 @@ enum { D_SAHF,D_LAHF, D_CPUID, D_HLT,D_CLTS, + D_LOCK, L_ERROR, }; diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index b6218b90..ca5c7d58 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -444,6 +444,20 @@ else {GetEAa;*rmrw=LoadMbs(eaa);} break; } + CASE_0F_B(0xc0) /* XADD Gb,Eb */ + { + GetRMrb;Bit8u oldrmrb=*rmrb; + if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;*earb+=oldrmrb;} + else {GetEAa;*rmrb=LoadMb(eaa);SaveMb(eaa,LoadMb(eaa)+oldrmrb);} + break; + } + CASE_0F_W(0xc1) /* XADD Gw,Ew */ + { + GetRMrw;Bit16u oldrmrw=*rmrw; + if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;*earw+=oldrmrw;} + else {GetEAa;*rmrw=LoadMw(eaa);SaveMw(eaa,LoadMw(eaa)+oldrmrw);} + break; + } CASE_0F_B(0xc8) /* BSWAP EAX */ BSWAP(reg_eax);break; CASE_0F_B(0xc9) /* BSWAP ECX */ diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 3e4e360e..d7ad2386 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -376,3 +376,10 @@ else {GetEAa;*rmrd=LoadMws(eaa);} break; } + CASE_0F_D(0xc1) /* XADD Gd,Ed */ + { + GetRMrd;Bit32u oldrmrd=*rmrd; + if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;*eard+=oldrmrd;} + else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,LoadMd(eaa)+oldrmrd);} + break; + } diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index f6f3a7b2..3cde3a1d 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -926,7 +926,7 @@ IO_WriteW(reg_dx,reg_ax); break; CASE_B(0xf0) /* LOCK */ - LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK"); + LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK"); /* FIXME: see case D_LOCK in core_full/load.h */ break; CASE_B(0xf2) /* REPNZ */ DO_PREFIX_REP(false); From 4295bf213ba548e7b8f9451212fee97c27bfce11 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 19 Apr 2005 15:30:03 +0000 Subject: [PATCH 2095/4131] Added new functions so you can find Sections from property names. Moved a few implementations from the header to the cpp file Reordered some stuff so every thing is present when it's encountered (inside a class) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2179 --- include/setup.h | 94 +++++++++++++++++++++------------------------- src/misc/setup.cpp | 50 +++++++++++++++++++----- 2 files changed, 82 insertions(+), 62 deletions(-) diff --git a/include/setup.h b/include/setup.h index 8f944e43..e55b1973 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.18 2005-03-25 11:43:36 qbix79 Exp $ */ +/* $Id: setup.h,v 1.19 2005-04-19 15:29:59 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -36,7 +36,7 @@ public: CommandLine(int argc,char * argv[]); CommandLine(char * name,char * cmdline); const char * GetFileName(){ return file_name.c_str();} - + bool FindExist(char * name,bool remove=false); bool FindHex(char * name,int & value,bool remove=false); bool FindInt(char * name,int & value,bool remove=false); @@ -122,25 +122,8 @@ public: void GetValuestring(char* str); }; -class Section; -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) {}; - ~Module_base(){/*LOG_MSG("executed")*/;};//Destructors are required - /* Returns true if succesful.*/ - virtual bool Change_Config(Section* newconfig) {return false;} ; -}; - - class Section { -public: - Section(const char* _sectionname) { sectionname=_sectionname; } - virtual ~Section(){ExecuteDestroy(true); } - +private: typedef void (*SectionFunction)(Section*); /* Wrapper class around startup and shutdown functions. the variable * canchange indicates it can be called on configuration changes */ @@ -152,36 +135,31 @@ public: canchange=_ch; } }; - void AddInitFunction(SectionFunction func,bool canchange=false) {initfunctions.push_back(Function_wrapper(func,canchange));} - void AddDestroyFunction(SectionFunction func,bool canchange=false) {destroyfunctions.push_front(Function_wrapper(func,canchange));} - void ExecuteInit(bool initall=true) { - typedef std::list::iterator func_it; - for (func_it tel=initfunctions.begin(); tel!=initfunctions.end(); tel++){ - if(initall || (*tel).canchange) (*tel).function(this); - } - } - void ExecuteDestroy(bool destroyall=true) { - typedef std::list::iterator func_it; - for (func_it tel=destroyfunctions.begin(); tel!=destroyfunctions.end(); ){ - if(destroyall || (*tel).canchange) { - (*tel).function(this); - tel=destroyfunctions.erase(tel); //Remove destroyfunction once used - } else tel++; - } - } std::list initfunctions; std::list destroyfunctions; + std::string sectionname; +public: + Section(const char* _sectionname) { sectionname=_sectionname; } + + void AddInitFunction(SectionFunction func,bool canchange=false) {initfunctions.push_back(Function_wrapper(func,canchange));} + void AddDestroyFunction(SectionFunction func,bool canchange=false) {destroyfunctions.push_front(Function_wrapper(func,canchange));} + void ExecuteInit(bool initall=true); + void ExecuteDestroy(bool destroyall=true); + const char* GetName() {return sectionname.c_str();} + + virtual bool HasProperty(const char* _property)=0; virtual void HandleInputline(char * _line){} virtual void PrintData(FILE* outfile) {} - std::string sectionname; + virtual ~Section(){ExecuteDestroy(true); } }; class Section_prop:public Section { - public: +private: + std::list properties; + typedef std::list::iterator it; +public: Section_prop(const char* _sectionname):Section(_sectionname){} - //ExecuteDestroy should be here else the destroy functions use destroyed properties - ~Section_prop(){ExecuteDestroy(true);} void Add_int(const char* _propname, int _value=0); void Add_string(const char* _propname, char* _value=NULL); void Add_bool(const char* _propname, bool _value=false); @@ -195,9 +173,9 @@ class Section_prop:public Section { float Get_float(const char* _propname); void HandleInputline(char *gegevens); void PrintData(FILE* outfile); - - std::list properties; - typedef std::list::iterator it; + virtual bool HasProperty(const char* _property); + //ExecuteDestroy should be here else the destroy functions use destroyed properties + virtual ~Section_prop(){ExecuteDestroy(true);} }; class Section_line: public Section{ @@ -206,20 +184,27 @@ public: ~Section_line(){ExecuteDestroy(true);} void HandleInputline(char* gegevens); void PrintData(FILE* outfile); + virtual bool HasProperty(const char* _property); std::string data; }; class Config{ +public: + CommandLine * cmdline; +private: + std::list sectionlist; + typedef std::list::iterator it; + typedef std::list::reverse_iterator reverse_it; + void (* _start_function)(void); public: Config(CommandLine * cmd){ cmdline=cmd;} ~Config(); - CommandLine * cmdline; - Section * AddSection(const char * _name,void (*_initfunction)(Section*)); Section_line * AddSection_line(const char * _name,void (*_initfunction)(Section*)); Section_prop * AddSection_prop(const char * _name,void (*_initfunction)(Section*),bool canchange=false); Section* GetSection(const char* _sectionname); + Section* GetSectionFromProperty(const char* prop); void SetStartUp(void (*_function)(void)); void Init(); @@ -228,12 +213,17 @@ public: void PrintConfig(const char* configfilename); bool ParseConfigFile(const char* configfilename); void ParseEnv(char ** envp); - - std::list sectionlist; - typedef std::list::iterator it; - typedef std::list::reverse_iterator reverse_it; -private: - void (* _start_function)(void); }; +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) {}; + ~Module_base(){/*LOG_MSG("executed")*/;};//Destructors are required + /* Returns true if succesful.*/ + virtual bool Change_Config(Section* newconfig) {return false;} ; +}; #endif diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 34aeed34..9c4394a5 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.25 2005-03-25 12:00:52 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.26 2005-04-19 15:30:03 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -168,7 +168,15 @@ void Section_prop::PrintData(FILE* outfile){ } } - +bool Section_prop::HasProperty(const char* _property) { + for(it tel=properties.begin();tel!=properties.end();tel++){ + if(!strcasecmp((*tel)->propname.c_str(),_property)){ + return true; + } + } + return false; +} + void Section_line::HandleInputline(char* line){ data+=line; data+="\n"; @@ -178,13 +186,17 @@ void Section_line::PrintData(FILE* outfile) { fprintf(outfile,"%s",data.c_str()); } +bool Section_line::HasProperty(const char* _property) { + return false; +} + void Config::PrintConfig(const char* configfilename){ char temp[50];char helpline[256]; FILE* outfile=fopen(configfilename,"w+t"); if(outfile==NULL) return; for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ /* Print out the Section header */ - strcpy(temp,(*tel)->sectionname.c_str()); + strcpy(temp,(*tel)->GetName()); lowcase(temp); fprintf(outfile,"[%s]\n",temp); upcase(temp); @@ -207,12 +219,6 @@ void Config::PrintConfig(const char* configfilename){ fclose(outfile); } -Section* Config::AddSection(const char* _name,void (*_initfunction)(Section*)){ - Section* blah = new Section(_name); - blah->AddInitFunction(_initfunction); - sectionlist.push_back(blah); - return blah; -} Section_prop* Config::AddSection_prop(const char* _name,void (*_initfunction)(Section*),bool canchange){ Section_prop* blah = new Section_prop(_name); @@ -235,6 +241,23 @@ void Config::Init(){ } } +void Section::ExecuteInit(bool initall) { + typedef std::list::iterator func_it; + for (func_it tel=initfunctions.begin(); tel!=initfunctions.end(); tel++) { + if(initall || (*tel).canchange) (*tel).function(this); + } +} + +void Section::ExecuteDestroy(bool destroyall) { + typedef std::list::iterator func_it; + for (func_it tel=destroyfunctions.begin(); tel!=destroyfunctions.end(); ) { + if(destroyall || (*tel).canchange) { + (*tel).function(this); + tel=destroyfunctions.erase(tel); //Remove destroyfunction once used + } else tel++; + } +} + Config::~Config() { reverse_it cnt=sectionlist.rbegin(); while (cnt!=sectionlist.rend()) { @@ -245,11 +268,18 @@ Config::~Config() { Section* Config::GetSection(const char* _sectionname){ for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ - if (!strcasecmp((*tel)->sectionname.c_str(),_sectionname)) return (*tel); + if (!strcasecmp((*tel)->GetName(),_sectionname)) return (*tel); } return NULL; } +Section* Config::GetSectionFromProperty(const char* prop) +{ + for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ + if ((*tel)->HasProperty(prop)) return (*tel); + } + return NULL; +} bool Config::ParseConfigFile(const char* configfilename){ ifstream in(configfilename); if (!in) return false; From 0b47601a00d4ff0b5e556a9fb1521d518b2530e8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 21 Apr 2005 18:24:40 +0000 Subject: [PATCH 2096/4131] open cdrom as when we are in forced mode as well Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2180 --- src/dos/cdrom.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index bfd3b8ab..3597e3a9 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -53,7 +53,9 @@ bool CDROM_Interface_SDL::SetDevice (char* path, int forceCD) int num = SDL_CDNumDrives(); if ((forceCD>=0) && (forceCD Date: Thu, 21 Apr 2005 18:34:47 +0000 Subject: [PATCH 2097/4131] fix for 1173099. Might need a different fix oneday. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2181 --- src/ints/mouse.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 0cf1f92a..0c40ff53 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.48 2005-03-24 19:16:33 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.49 2005-04-21 18:34:47 qbix79 Exp $ */ #include #include @@ -339,8 +339,8 @@ void DrawCursor() { mouse.clipx = CurMode->swidth-1; /* Get from bios ? */ mouse.clipy = CurMode->sheight-1; - Bit16s xratio = 640 / CurMode->swidth; /* might be mouse.max_x-.mouse.min_x+1/swidth */ - /* might even be vidmode == 0x13?2:1 */ + Bit16s xratio = 640 / CurMode->swidth;/* might be vidmode == 0x13?2:1 */ + if(xratio==0) xratio = 1; RestoreCursorBackground(); From 7e03ec15998b02502a2740f59872aba98cc845d1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 21 Apr 2005 18:43:28 +0000 Subject: [PATCH 2098/4131] vc2005.net beta proof Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2182 --- src/dos/dos_ioctl.cpp | 4 ++-- src/dos/drive_cache.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 3aa23026..e4d82eaa 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.24 2005-04-11 17:56:27 qbix79 Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.25 2005-04-21 18:42:10 qbix79 Exp $ */ #include #include "dosbox.h" @@ -104,7 +104,7 @@ bool DOS_IOCTL(void) { char const* bufin=Drives[drive]->GetLabel(); char buffer[11] ={' '}; - char* find_ext=strchr(bufin,'.'); + char const* find_ext=strchr(bufin,'.'); if (find_ext) { Bitu size=find_ext-bufin;if (size>8) size=8; memcpy(buffer,bufin,size); diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 869756d3..f8623d33 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.42 2005-02-10 10:20:51 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.43 2005-04-21 18:43:28 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -315,7 +315,7 @@ bool DOS_Drive_Cache::GetShortName(const char* fullname, char* shortname) int DOS_Drive_Cache::CompareShortname(const char* compareName, const char* shortName) { - char* cpos = strchr(shortName,'~'); + char const* cpos = strchr(shortName,'~'); if (cpos) { /* the following code is replaced as it's not safe when char* is 64 bits */ /* Bits compareCount1 = (int)cpos - (int)shortName; From e60e9f2aca71301b120be8e668aa3ae07f026dff Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 21 Apr 2005 18:46:23 +0000 Subject: [PATCH 2099/4131] maybe fix some 64 bits issue with fseek Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2183 --- src/dos/drive_local.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 70584476..8bb7a43b 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.56 2005-03-25 09:11:08 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.57 2005-04-21 18:46:23 qbix79 Exp $ */ #include #include @@ -420,7 +420,7 @@ bool localFile::Seek(Bit32u * pos,Bit32u type) { //TODO Give some doserrorcode; return false;//ERROR } - int ret=fseek(fhandle,*pos,seektype); + int ret=fseek(fhandle,*reinterpret_cast(pos),seektype); if (ret!=0) { // Out of file range, pretend everythings ok // and move file pointer top end of file... ?! (Black Thorne) From 9b7ffd101010c7020637bfc64003ef1ff45e78c7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 21 Apr 2005 18:51:54 +0000 Subject: [PATCH 2100/4131] vs.net2005 beta2 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2184 --- src/gui/sdlmain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index cc63d47d..29268e91 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.83 2005-03-08 09:34:27 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.84 2005-04-21 18:51:54 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -795,7 +795,7 @@ static void GUI_StartUp(Section * sec) { strcpy(res,fullresolution); fullresolution = lowcase (res);//so x and X are allowed - char* height = strchr(fullresolution,'x'); + char* height = const_cast(strchr(fullresolution,'x')); if(height && * height) { *height = 0; sdl.desktop.height = atoi(height+1); From 4e9a7a6120c3596175812e0fcb0ddc970680ebb6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 21 Apr 2005 18:54:59 +0000 Subject: [PATCH 2101/4131] include cleanup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2185 --- src/hardware/vga.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index cee879e2..cbdd8911 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -16,15 +16,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include #include "dosbox.h" #include "video.h" #include "pic.h" -#include "timer.h" #include "vga.h" -#include "inout.h" VGA_Type vga; @@ -199,4 +195,3 @@ void VGA_Init(Section* sec) { } } } - From baac15a8da640e2e2fe8ee4199f7254bf5437cba Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 21 Apr 2005 19:12:47 +0000 Subject: [PATCH 2102/4131] negative cycles not allowed Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2186 --- src/cpu/cpu.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 57746f1f..d7b033cf 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.68 2005-03-25 11:45:37 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.69 2005-04-21 19:12:47 qbix79 Exp $ */ #include #include "dosbox.h" @@ -1877,9 +1877,9 @@ public: LOG_MSG("CPU:Unknown core type %s, switcing back to normal.",core); } - if (!CPU_CycleMax) CPU_CycleMax = 2500; - if(!CPU_CycleUp) CPU_CycleUp = 500; - if(!CPU_CycleDown) CPU_CycleDown = 20; + if(CPU_CycleMax <= 0) CPU_CycleMax = 2500; + if(CPU_CycleUp <= 0) CPU_CycleUp = 500; + if(CPU_CycleDown <= 0) CPU_CycleDown = 20; GFX_SetTitle(CPU_CycleMax,-1,false); return true; } From 6157cbaebfb382e6883a3e8190859a6802a55601 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 21 Apr 2005 19:53:41 +0000 Subject: [PATCH 2103/4131] renamed __value to value for vs.net 2005. Added some function to get the value of a property from the section. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2187 --- include/setup.h | 26 +++++++++++++------------- src/misc/setup.cpp | 40 +++++++++++++++++++++------------------- 2 files changed, 34 insertions(+), 32 deletions(-) diff --git a/include/setup.h b/include/setup.h index e55b1973..4313bf4b 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.19 2005-04-19 15:29:59 qbix79 Exp $ */ +/* $Id: setup.h,v 1.20 2005-04-21 19:53:40 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -66,16 +66,16 @@ public: Property(const char* _propname):propname(_propname) { } virtual void SetValue(char* input)=0; virtual void GetValuestring(char* str)=0; - Value GetValue() { return __value;} - std::string propname; - Value __value; + Value GetValue() { return value;} virtual ~Property(){ } + std::string propname; + Value value; }; class Prop_int:public Property { public: Prop_int(const char* _propname, int _value):Property(_propname) { - __value._int=_value; + value._int=_value; } void SetValue(char* input); void GetValuestring(char* str); @@ -84,7 +84,7 @@ public: class Prop_float:public Property { public: Prop_float(const char* _propname, float _value):Property(_propname){ - __value._float=_value; + value._float=_value; } void SetValue(char* input); void GetValuestring(char* str); @@ -94,7 +94,7 @@ public: class Prop_bool:public Property { public: Prop_bool(const char* _propname, bool _value):Property(_propname) { - __value._bool=_value; + value._bool=_value; } void SetValue(char* input); void GetValuestring(char* str); @@ -104,10 +104,10 @@ public: class Prop_string:public Property{ public: Prop_string(const char* _propname, char* _value):Property(_propname) { - __value._string=new std::string(_value); + value._string=new std::string(_value); } ~Prop_string(){ - delete __value._string; + delete value._string; } void SetValue(char* input); void GetValuestring(char* str); @@ -115,7 +115,7 @@ public: class Prop_hex:public Property { public: Prop_hex(const char* _propname, int _value):Property(_propname) { - __value._hex=_value; + value._hex=_value; } void SetValue(char* input); ~Prop_hex(){ } @@ -147,7 +147,7 @@ public: void ExecuteDestroy(bool destroyall=true); const char* GetName() {return sectionname.c_str();} - virtual bool HasProperty(const char* _property)=0; + virtual char* GetPropValue(const char* _property)=0; virtual void HandleInputline(char * _line){} virtual void PrintData(FILE* outfile) {} virtual ~Section(){ExecuteDestroy(true); } @@ -173,7 +173,7 @@ public: float Get_float(const char* _propname); void HandleInputline(char *gegevens); void PrintData(FILE* outfile); - virtual bool HasProperty(const char* _property); + virtual char* GetPropValue(const char* _property); //ExecuteDestroy should be here else the destroy functions use destroyed properties virtual ~Section_prop(){ExecuteDestroy(true);} }; @@ -184,7 +184,7 @@ public: ~Section_line(){ExecuteDestroy(true);} void HandleInputline(char* gegevens); void PrintData(FILE* outfile); - virtual bool HasProperty(const char* _property); + virtual char* GetPropValue(const char* _property); std::string data; }; diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 9c4394a5..71735a16 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.26 2005-04-19 15:30:03 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.27 2005-04-21 19:53:41 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -32,51 +32,51 @@ using namespace std; void Prop_float::SetValue(char* input){ input=trim(input); - __value._float= atof(input); + value._float= atof(input); } void Prop_int::SetValue(char* input){ input=trim(input); - __value._int= atoi(input); + value._int= atoi(input); } void Prop_string::SetValue(char* input){ input=trim(input); - __value._string->assign(input); + value._string->assign(input); } void Prop_bool::SetValue(char* input){ input=lowcase(trim(input)); /* valid false entries: 0 ,d*, of* ,f* everything else gets true */ if((input[0]=='0') || (input[0]=='d') || ( (input[0]=='o') && (input[1]=='f')) || (input[0]=='f')){ - __value._bool=false; + value._bool=false; }else{ - __value._bool=true; + value._bool=true; } } void Prop_hex::SetValue(char* input){ input=trim(input); - if(!sscanf(input,"%X",&(__value._hex))) __value._hex=0; + if(!sscanf(input,"%X",&(value._hex))) value._hex=0; } void Prop_int::GetValuestring(char* str){ - sprintf(str,"%d",__value._int); + sprintf(str,"%d",value._int); } void Prop_string::GetValuestring(char* str){ - sprintf(str,"%s",__value._string->c_str()); + sprintf(str,"%s",value._string->c_str()); } void Prop_bool::GetValuestring(char* str){ - sprintf(str,"%s",__value._bool?"true":"false"); + sprintf(str,"%s",value._bool?"true":"false"); } void Prop_float::GetValuestring(char* str){ - sprintf(str,"%1.2f",__value._float); + sprintf(str,"%1.2f",value._float); } void Prop_hex::GetValuestring(char* str){ - sprintf(str,"%X",__value._hex); + sprintf(str,"%X",value._hex); } void Section_prop::Add_float(const char* _propname, float _value) { @@ -168,15 +168,17 @@ void Section_prop::PrintData(FILE* outfile){ } } -bool Section_prop::HasProperty(const char* _property) { +static char buffer[1024]; +char* Section_prop::GetPropValue(const char* _property) { for(it tel=properties.begin();tel!=properties.end();tel++){ if(!strcasecmp((*tel)->propname.c_str(),_property)){ - return true; + (*tel)->GetValuestring(buffer); + return buffer; } } - return false; + return NULL; } - + void Section_line::HandleInputline(char* line){ data+=line; data+="\n"; @@ -186,8 +188,8 @@ void Section_line::PrintData(FILE* outfile) { fprintf(outfile,"%s",data.c_str()); } -bool Section_line::HasProperty(const char* _property) { - return false; +char* Section_line::GetPropValue(const char* _property) { + return NULL; } void Config::PrintConfig(const char* configfilename){ @@ -276,7 +278,7 @@ Section* Config::GetSection(const char* _sectionname){ Section* Config::GetSectionFromProperty(const char* prop) { for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ - if ((*tel)->HasProperty(prop)) return (*tel); + if ((*tel)->GetPropValue(prop)) return (*tel); } return NULL; } From 4a2808a9a6f3bf69563900d462db09bb41176475 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 21 Apr 2005 21:03:19 +0000 Subject: [PATCH 2104/4131] check for builtin_expect and define GCC_UNLIKELY Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2188 --- acinclude.m4 | 6 ++++++ configure.in | 11 +++++++++++ src/platform/visualc/config.h | 1 + 3 files changed, 18 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index 0392bbea..697e36fa 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -331,6 +331,12 @@ AH_BOTTOM([#if C_HAS_ATTRIBUTE #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; diff --git a/configure.in b/configure.in index 13ecf042..0a4878bf 100644 --- a/configure.in +++ b/configure.in @@ -58,6 +58,17 @@ AC_MSG_CHECKING(if compiler allows __attribute__) AC_TRY_COMPILE([], [typedef struct { } __attribute__ ((packed)) junk;], [ AC_MSG_RESULT(yes);AC_DEFINE(C_HAS_ATTRIBUTE)],AC_MSG_RESULT(no)) +#Check if the compiler supports __builtin_expect +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_TRY_COMPILE([],[ +int main(int argc,char* argv[]){ +int x=10;if( __builtin_expect ((x==1),0) ) ; +return 0; +} +], [ AC_MSG_RESULT(yes);AC_DEFINE(C_HAS_BUILTIN_EXPECT)],AC_MSG_RESULT(no)) + + AM_PATH_ALSA(0.9.0, AC_DEFINE(HAVE_ALSA,1,[Define to 1 to use ALSA for MIDI]) , : ) #Check for big endian machine, should #define WORD_BIGENDIAN if so diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index d28a4629..f80fb7ce 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -52,6 +52,7 @@ #define C_DIRECTSERIAL 1 #define GCC_ATTRIBUTE(x) /* attribute not supported */ +#define GCC_UNLIKELY(x) (x) typedef double Real64; /* The internal types */ From 50f9e112824ff43e3efbe1bc56adfd1c0bed28f3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 21 Apr 2005 21:06:27 +0000 Subject: [PATCH 2105/4131] Trying out the new GCC_UNLIKELY macro and turning the exit to a warning on prioritysetting. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2189 --- src/hardware/pic.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 4b252f37..2932d6d5 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.30 2005-03-29 07:05:44 qbix79 Exp $ */ +/* $Id: pic.cpp,v 1.31 2005-04-21 21:06:27 qbix79 Exp $ */ #include @@ -78,14 +78,14 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { Bitu i; static Bit16u IRQ_priority_table[16] = { 0,1,2,8,9,10,11,12,13,14,15,3,4,5,6,7 }; - if (val&0x10) { // ICW1 issued + if (GCC_UNLIKELY(val&0x10)) { // ICW1 issued if (val&0x02) E_Exit("PIC: single mode not handled"); // (would have to skip ICW3) if (val&0x04) E_Exit("PIC: 4 byte interval not handled"); if (val&0x08) E_Exit("PIC: level triggered mode not handled"); if (val&0xe0) E_Exit("PIC: 8080/8085 mode not handled"); pic->icw_index=1; // next is ICW3 pic->icw_words=2 + (val&0x01); // =3 if ICW4 needed - } else if (val&0x08) { // OCW3 issued + } else if (GCC_UNLIKELY(val&0x08)) { // OCW3 issued if (val&0x04) E_Exit("PIC: poll command not handled"); if (val&0x02) { // function select if (val&0x01) pic->request_issr=true; /* select read interrupt in-service register */ @@ -105,7 +105,7 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { } } else { // OCW2 issued if (val&0x20) { // EOI commands - if (val&0x80) E_Exit("rotate mode not supported"); + if (GCC_UNLIKELY(val&0x80)) E_Exit("rotate mode not supported"); if (val&0x40) { // specific EOI if (PIC_IRQActive==(irq_base+val-0x60U)) { irqs[PIC_IRQActive].inservice=false; @@ -136,7 +136,7 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { if (val&0x80) pic->rotate_on_auto_eoi=true; else pic->rotate_on_auto_eoi=false; } else if (val&0x80) { - E_Exit("set priority command not handled"); + LOG(LOG_PIC,LOG_NORMAL)("set priority command not handled"); } // else NOP command } } // end OCW2 From 2a0f3a1f3d5d7536e0c52d7c29bc237ec192aee7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 21 Apr 2005 21:17:46 +0000 Subject: [PATCH 2106/4131] Support configuration changes from the shell. syntax: property => lists the current value of the property property=value => Sets property to value examples: ems=true cycles=5000 core=full Added "wc" as alias for writeconf and "wl" for writelang(Requested by DosFreak) Added support for home/end on the shell(parapente) Config supports the setting of configuration as well: config -set "section property=value" This one should be used for properties that exist in more than one section. Samplerate for example. Changed the main shellinput loop. So it checks for a property if the entered command isn't an internal command or an executable. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2190 --- include/shell.h | 6 ++-- src/dosbox.cpp | 49 +++++++++++++-------------- src/misc/programs.cpp | 73 +++++++++++++++++++++++++++++++++++++--- src/shell/shell_cmds.cpp | 20 +++++++++-- src/shell/shell_misc.cpp | 39 ++++++++++++--------- 5 files changed, 138 insertions(+), 49 deletions(-) diff --git a/include/shell.h b/include/shell.h index 04ca98cc..4d3eaaef 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.11 2005-03-25 09:46:53 qbix79 Exp $ */ +/* $Id: shell.h,v 1.12 2005-04-21 21:17:45 qbix79 Exp $ */ #ifndef DOSBOX_SHELL_H #define DOSBOX_SHELL_H @@ -71,7 +71,9 @@ public: void InputCommand(char * line); void ShowPrompt(); void DoCommand(char * cmd); - void Execute(char * name,char * args); + bool Execute(char * name,char * args); + /* Checks if it matches a hardware-property */ + bool CheckConfig(char* cmd,char*line); /* Some internal used functions */ char * Which(char * name); /* Some supported commands */ diff --git a/src/dosbox.cpp b/src/dosbox.cpp index d2f95883..6722a5c5 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.83 2005-02-10 10:20:47 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.84 2005-04-21 21:17:45 qbix79 Exp $ */ #include #include @@ -208,17 +208,17 @@ void DOSBOX_Init(void) { LOG_StartUp(); #endif - secprop->AddInitFunction(&IO_Init); - secprop->AddInitFunction(&PAGING_Init); - secprop->AddInitFunction(&MEM_Init); - secprop->AddInitFunction(&HARDWARE_Init); + secprop->AddInitFunction(&IO_Init);//done + secprop->AddInitFunction(&PAGING_Init);//done + secprop->AddInitFunction(&MEM_Init);//done + secprop->AddInitFunction(&HARDWARE_Init);//done secprop->Add_int("memsize",16); secprop->AddInitFunction(&CALLBACK_Init); - secprop->AddInitFunction(&PIC_Init); + secprop->AddInitFunction(&PIC_Init);//done secprop->AddInitFunction(&PROGRAMS_Init); - secprop->AddInitFunction(&TIMER_Init); - secprop->AddInitFunction(&CMOS_Init); - secprop->AddInitFunction(&SERIAL_Init); + secprop->AddInitFunction(&TIMER_Init);//done + secprop->AddInitFunction(&CMOS_Init);//done + secprop->AddInitFunction(&SERIAL_Init); //done MSG_Add("DOSBOX_CONFIGFILE_HELP", "language -- Select another language file.\n" @@ -238,7 +238,7 @@ void DOSBOX_Init(void) { " Supported are none,normal2x,advmame2x,advmame3x,advinterp2x,interp2x,tv2x.\n" ); - secprop=control->AddSection_prop("cpu",&CPU_Init); + secprop=control->AddSection_prop("cpu",&CPU_Init,true);//done secprop->Add_string("core","normal"); secprop->Add_int("cycles",3000); secprop->Add_int("cycleup",500); @@ -257,10 +257,10 @@ void DOSBOX_Init(void) { #if C_FPU secprop->AddInitFunction(&FPU_Init); #endif - secprop->AddInitFunction(&DMA_Init); + secprop->AddInitFunction(&DMA_Init);//done secprop->AddInitFunction(&VGA_Init); secprop->AddInitFunction(&KEYBOARD_Init); - secprop->AddInitFunction(&JOYSTICK_Init); + secprop->AddInitFunction(&JOYSTICK_Init);//done secprop=control->AddSection_prop("mixer",&MIXER_Init); secprop->Add_bool("nosound",false); @@ -277,8 +277,8 @@ void DOSBOX_Init(void) { "prebuffer -- How many milliseconds of data to keep on top of the blocksize.\n" ); - secprop=control->AddSection_prop("midi",&MIDI_Init); - secprop->AddInitFunction(&MPU401_Init); + secprop=control->AddSection_prop("midi",&MIDI_Init,true);//done + secprop->AddInitFunction(&MPU401_Init,true);//done secprop->Add_bool("mpu401",true); secprop->Add_bool("intelligent",true); secprop->Add_string("device","default"); @@ -296,7 +296,7 @@ void DOSBOX_Init(void) { #if C_DEBUG secprop=control->AddSection_prop("debug",&DEBUG_Init); #endif - secprop=control->AddSection_prop("sblaster",&SBLASTER_Init); + secprop=control->AddSection_prop("sblaster",&SBLASTER_Init,true);//done secprop->Add_string("type","sb16"); secprop->Add_hex("base",0x220); secprop->Add_int("irq",7); @@ -315,7 +315,7 @@ void DOSBOX_Init(void) { "oplrate -- Sample rate of OPL music emulation.\n" ); - secprop=control->AddSection_prop("gus",&GUS_Init); + secprop=control->AddSection_prop("gus",&GUS_Init,true); //done secprop->Add_bool("gus",true); secprop->Add_int("rate",22050); secprop->Add_hex("base",0x240); @@ -336,12 +336,12 @@ void DOSBOX_Init(void) { " with Timidity should work fine.\n" ); - secprop=control->AddSection_prop("speaker",&PCSPEAKER_Init); + secprop=control->AddSection_prop("speaker",&PCSPEAKER_Init,true);//done secprop->Add_bool("pcspeaker",true); secprop->Add_int("pcrate",22050); - secprop->AddInitFunction(&TANDYSOUND_Init); + secprop->AddInitFunction(&TANDYSOUND_Init,true);//done secprop->Add_int("tandyrate",22050); - secprop->AddInitFunction(&DISNEY_Init); + secprop->AddInitFunction(&DISNEY_Init,true);//done secprop->Add_bool("disney",true); MSG_Add("SPEAKER_CONFIGFILE_HELP", @@ -351,16 +351,16 @@ void DOSBOX_Init(void) { " Tandysound emulation is present if machine is set to tandy.\n" "disney -- Enable Disney Sound Source emulation.\n" ); - secprop=control->AddSection_prop("bios",&BIOS_Init); + secprop=control->AddSection_prop("bios",&BIOS_Init,false);//done secprop->AddInitFunction(&INT10_Init); secprop->AddInitFunction(&MOUSE_Init); //Must be after int10 as it uses CurMode /* All the DOS Related stuff, which will eventually start up in the shell */ //TODO Maybe combine most of the dos stuff in one section like ems,xms - secprop=control->AddSection_prop("dos",&DOS_Init); - secprop->AddInitFunction(&XMS_Init); + secprop=control->AddSection_prop("dos",&DOS_Init,false);//done + secprop->AddInitFunction(&XMS_Init,true);//done secprop->Add_bool("xms",true); - secprop->AddInitFunction(&EMS_Init); + secprop->AddInitFunction(&EMS_Init,true);//done secprop->Add_bool("ems",true); MSG_Add("DOS_CONFIGFILE_HELP", "xms -- Enable XMS support.\n" @@ -369,7 +369,7 @@ void DOSBOX_Init(void) { // Mscdex secprop->AddInitFunction(&MSCDEX_Init); #if C_MODEM - secprop=control->AddSection_prop("modem",&MODEM_Init); + secprop=control->AddSection_prop("modem",&MODEM_Init,true);//done secprop->Add_bool("modem",false); secprop->Add_hex("comport",2); secprop->Add_int("listenport",23); @@ -412,4 +412,3 @@ void DOSBOX_Init(void) { ); control->SetStartUp(&SHELL_Init); } - diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index c9cdb151..eb975c73 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.18 2005-02-10 10:21:11 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.19 2005-04-21 21:17:45 qbix79 Exp $ */ #include #include @@ -197,7 +197,8 @@ void MSG_Write(const char *); void CONFIG::Run(void) { FILE * f; - if (cmd->FindString("-writeconf",temp_line,true)) { + if (cmd->FindString("-writeconf",temp_line,true) + || cmd->FindString("-wc",temp_line,true)) { f=fopen(temp_line.c_str(),"wb+"); if (!f) { WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str()); @@ -207,7 +208,8 @@ void CONFIG::Run(void) { control->PrintConfig(temp_line.c_str()); return; } - if (cmd->FindString("-writelang",temp_line,true)) { + if (cmd->FindString("-writelang",temp_line,true) + ||cmd->FindString("-wl",temp_line,true)) { f=fopen(temp_line.c_str(),"wb+"); if (!f) { WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str()); @@ -217,7 +219,68 @@ void CONFIG::Run(void) { MSG_Write(temp_line.c_str()); return; } - WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE")); + + /* Code for the configuration changes * + * Official format: config -set "section property=value" * + * Accepted: without quotes and/or without -set and/or without section * + * and/or the "=" replaced by a " " */ + + if (cmd->FindString("-set",temp_line,true)) { //get all arguments + std::string temp2 = ""; + cmd->GetStringRemain(temp2);//So -set n1 n2=n3 can be used without quotes + if(temp2!="") temp_line = temp_line + " " + temp2; + } else if(!cmd->GetStringRemain(temp_line)) {//no set + WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE")); //and no arguments specified + return; + }; + //Wanted input: n1 n2=n3 + char copy[1024]; + strcpy(copy,temp_line.c_str()); + //seperate section from property + const char* temp = strchr(copy,' '); + if((temp && *temp) || (temp=strchr(copy,'=')) ) copy[temp++ - copy]= 0; + else { + WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE")); + return; + } + //if n1 n2 n3 then replace last space with = + const char* sign = strchr(temp,'='); + if(!sign) { + sign = strchr(temp,' '); + if(sign) { + copy[sign - copy] = '='; + } else { + //2 items specified (no space nor = between n2 and n3 + //assume that they posted: property value + //Try to determine the section. + Section* sec=control->GetSectionFromProperty(copy); + if(!sec){ + if(control->GetSectionFromProperty(temp)) return; //Weird situation:ignore + WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR"),copy); + return; + } //Hack to allow config ems true + char buffer[1024];strcpy(buffer,copy);strcat(buffer,"=");strcat(buffer,temp); + sign = strchr(buffer,' '); + if(sign) buffer[sign - buffer] = '='; + strcpy(copy,sec->GetName()); + temp = buffer; + } + } + + /* Input processed. Now the real job starts + * copy contains the likely "sectionname" + * temp contains "property=value" + * the section is destroyed and a new input line is given to + * the configuration parser. Then the section is restarted. + */ + char* inputline = const_cast(temp); + Section* sec = 0; + sec = control->GetSection(copy); + if(!sec) { WriteOut(MSG_Get("PROGRAM_CONFIG_SECTION_ERROR"),copy);return;} + sec->ExecuteDestroy(false); + sec->HandleInputline(inputline); + sec->ExecuteInit(false); + return; } @@ -234,4 +297,6 @@ void PROGRAMS_Init(Section* sec) { MSG_Add("PROGRAM_CONFIG_FILE_ERROR","Can't open file %s\n"); MSG_Add("PROGRAM_CONFIG_USAGE","Config tool:\nUse -writeconf filename to write the current config.\nUse -writelang filename to write the current language strings.\n"); + MSG_Add("PROGRAM_CONFIG_SECTION_ERROR","Section %s doesn't exist.\n"); + MSG_Add("PROGRAM_CONFIG_PROPERTY_ERROR","Property %s doesn't have a section.\n"); } diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index a4370183..897eacd5 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.53 2005-03-25 09:02:44 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.54 2005-04-21 21:17:46 qbix79 Exp $ */ #include #include @@ -60,6 +60,20 @@ static SHELL_Cmd cmd_list[]={ { "PATH", 1, &DOS_Shell::CMD_PATH, "SHELL_CMD_PATH_HELP"}, {0,0,0,0} }; +bool DOS_Shell::CheckConfig(char* cmd,char*line) { + Section* test = control->GetSectionFromProperty(cmd); + if(!test) return false; + if(line && !line[0]) { + char* val = test->GetPropValue(cmd); + if(val) WriteOut("%s\n",val); + return true; + } + char newcom[1024]; newcom[0] = 0; strcpy(newcom,"z:\\config "); + strcat(newcom,test->GetName()); strcat(newcom," "); + strcat(newcom,cmd);strcat(newcom,line); + DoCommand(newcom); + return true; +} void DOS_Shell::DoCommand(char * line) { /* First split the line into command and arguments */ @@ -96,7 +110,9 @@ void DOS_Shell::DoCommand(char * line) { cmd_index++; } /* This isn't an internal command execute it */ - Execute(cmd,line); + if(Execute(cmd,line)) return; + if(CheckConfig(cmd,line)) return; + WriteOut(MSG_Get("SHELL_EXECUTE_ILLEGAL_COMMAND"),cmd); } diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index e2cf2a47..e87385e5 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.37 2005-04-01 10:15:26 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.38 2005-04-21 21:17:46 qbix79 Exp $ */ #include #include @@ -99,6 +99,19 @@ void DOS_Shell::InputCommand(char * line) { } break; + case 0x47: /* HOME */ + while (str_index) { + outc(8); + str_index--; + } + break; + + case 0x4F: /* END */ + while (str_index < str_len) { + outc(line[str_index++]); + } + break; + case 0x48: /* UP */ if (l_history.empty() || it_history == l_history.end()) break; @@ -112,7 +125,6 @@ void DOS_Shell::InputCommand(char * line) { size = CMD_MAXLINE - str_index - 2; DOS_WriteFile(STDOUT, (Bit8u *)line, &len); it_history ++; - break; case 0x50: /* DOWN */ @@ -315,7 +327,9 @@ void DOS_Shell::InputCommand(char * line) { if (l_completion.size()) l_completion.clear(); } -void DOS_Shell::Execute(char * name,char * args) { +bool DOS_Shell::Execute(char * name,char * args) { +/* return true => don't check for hardware changes in do_command + * return false => check for hardware changes in do_command */ char * fullname; char line[CMD_MAXLINE]; if(strlen(args)!= 0){ @@ -337,15 +351,12 @@ void DOS_Shell::Execute(char * name,char * args) { if (!DOS_SetDrive(toupper(name[0])-'A')) { WriteOut(MSG_Get("SHELL_EXECUTE_DRIVE_NOT_FOUND"),toupper(name[0])); } - return; + return true; } /* Check for a full name */ fullname=Which(name); - if (!fullname) { - WriteOut(MSG_Get("SHELL_EXECUTE_ILLEGAL_COMMAND"),name); - return; - } - + if (!fullname) return false; + char* extension =strrchr(fullname,'.'); /*always disallow files without extension from being executed. */ @@ -376,8 +387,7 @@ void DOS_Shell::Execute(char * name,char * args) { else { - WriteOut(MSG_Get("SHELL_EXECUTE_ILLEGAL_COMMAND"),fullname); - return; + return false; } } @@ -396,11 +406,7 @@ void DOS_Shell::Execute(char * name,char * args) { { /* only .bat .exe .com extensions maybe be executed by the shell */ if(strcasecmp(extension, ".com") !=0) { - if(strcasecmp(extension, ".exe") !=0) - { - WriteOut(MSG_Get("SHELL_EXECUTE_ILLEGAL_COMMAND"),fullname); - return; - } + if(strcasecmp(extension, ".exe") !=0) return false; } /* Run the .exe or .com file from the shell */ /* Allocate some stack space for tables in physical memory */ @@ -453,6 +459,7 @@ void DOS_Shell::Execute(char * name,char * args) { SegSet16(cs,oldcs); #endif } + return true; //Executable started } From eeeb306b7d96735f78e357bcb2d790954ac17cd8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 22 Apr 2005 09:09:09 +0000 Subject: [PATCH 2107/4131] fix a warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2191 --- src/misc/setup.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 71735a16..c7953dcc 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.27 2005-04-21 19:53:41 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.28 2005-04-22 09:09:09 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -32,7 +32,7 @@ using namespace std; void Prop_float::SetValue(char* input){ input=trim(input); - value._float= atof(input); + value._float= static_cast(atof(input)); } void Prop_int::SetValue(char* input){ From dfe7247a7b036201659efe1568f04352f1f2601b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 Apr 2005 09:23:54 +0000 Subject: [PATCH 2108/4131] other mixer changes. ("reversing" the old ones) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2192 --- src/hardware/mixer.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index d0d6778a..71041df1 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.31 2005-03-25 10:12:05 qbix79 Exp $ */ +/* $Id: mixer.cpp,v 1.32 2005-04-25 09:23:54 qbix79 Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -56,12 +56,13 @@ #define MIXER_WAVESIZE MIXER_BUFSIZE #define MIXER_VOLSHIFT 13 -// #define MIXER_CLIP(SAMP) (SAMP>MAX_AUDIO) ? (Bit16s)MAX_AUDIO : (SAMPMAX_AUDIO)|(SAMPMIN_AUDIO) { + if (SAMP> MIXER_VOLSHIFT; - INIT_CLIP(sample); mixer.wave.buf[mixer.wave.used][0]=MIXER_CLIP(sample); sample=mixer.work[readpos][1] >> MIXER_VOLSHIFT; - INIT_CLIP(sample); mixer.wave.buf[mixer.wave.used][1]=MIXER_CLIP(sample); readpos=(readpos+1)&MIXER_BUFMASK; if (++mixer.wave.used==MIXER_WAVESIZE) { @@ -369,11 +368,9 @@ static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { Bits sample; while (need--) { sample=mixer.work[mixer.pos][0]>>MIXER_VOLSHIFT; - INIT_CLIP(sample); *output++=MIXER_CLIP(sample); mixer.work[mixer.pos][0]=0; sample=mixer.work[mixer.pos][1]>>MIXER_VOLSHIFT; - INIT_CLIP(sample); *output++=MIXER_CLIP(sample); mixer.work[mixer.pos][1]=0; mixer.pos=(mixer.pos+1)&MIXER_BUFMASK; From b34f94ecc6fffffec42425cbd9c0b6ba6cbcae69 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 Apr 2005 19:01:11 +0000 Subject: [PATCH 2109/4131] changed exit for invalid privilegdes when setting a segment to an exception. Fixes Extreme pinball. (Thanks wd) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2193 --- src/cpu/cpu.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index d7b033cf..61e53db5 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.69 2005-04-21 19:12:47 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.70 2005-04-25 19:01:11 qbix79 Exp $ */ #include #include "dosbox.h" @@ -1667,8 +1667,8 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) { case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: if (((value & 3)>desc.DPL()) || (cpu.cpl>desc.DPL())) { - E_Exit("CPU_SetSegGeneral: Invalid privileges"); -// return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); + // extreme pinball + return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); } break; case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: From 29926269fd6b7da49274f0f47865ca2d9d32092d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 26 Apr 2005 14:31:41 +0000 Subject: [PATCH 2110/4131] fix broken multiple -c commands. Changed current directory detection a bit. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2194 --- src/shell/shell.cpp | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 893b16e0..5e98a5e2 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.58 2005-04-03 17:37:09 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.59 2005-04-26 14:31:41 qbix79 Exp $ */ #include #include @@ -288,7 +288,7 @@ void DOS_Shell::SyntaxError(void) { } namespace{ - AutoexecObject autoexec[6]; + AutoexecObject autoexec[16]; } void AUTOEXEC_Init(Section * sec) { @@ -298,42 +298,54 @@ void AUTOEXEC_Init(Section * sec) { char * extra=(char *)section->data.c_str(); if (extra) autoexec[0].Install("%s",extra); /* Check to see for extra command line options to be added (before the command specified on commandline) */ - while (control->cmdline->FindString("-c",line,true)) - autoexec[1].Install((char *)line.c_str()); + /* Maximum of extra commands: 10 */ + Bitu i = 1; + while (control->cmdline->FindString("-c",line,true) && (i <= 11)) + autoexec[i++].Install((char *)line.c_str()); /* Check for the -exit switch which causes dosbox to when the command on the commandline has finished */ bool addexit = control->cmdline->FindExist("-exit",true); /* Check for first command being a directory or file */ char buffer[CROSS_LEN]; + char cross_filesplit[2] = {CROSS_FILESPLIT , 0}; if (control->cmdline->FindCommand(1,line)) { struct stat test; strcpy(buffer,line.c_str()); if (stat(buffer,&test)){ getcwd(buffer,CROSS_LEN); + strcat(buffer,cross_filesplit); strcat(buffer,line.c_str()); if (stat(buffer,&test)) goto nomount; } if (test.st_mode & S_IFDIR) { - autoexec[2].Install("MOUNT C \"%s\"",buffer); - autoexec[3].Install("C:"); + autoexec[12].Install("MOUNT C \"%s\"",buffer); + autoexec[13].Install("C:"); } else { - char * name=strrchr(buffer,CROSS_FILESPLIT); - if (!name) goto nomount; - *name++=0; + char* name = strrchr(buffer,CROSS_FILESPLIT); + if (!name) {//Only a filename + line = buffer; + getcwd(buffer,CROSS_LEN); + strcat(buffer,cross_filesplit); + strcat(buffer,line.c_str()); + if(stat(buffer,&test)) goto nomount; + name = strrchr(buffer,CROSS_FILESPLIT); + if(!name) goto nomount; + } + *name++ = 0; if (access(buffer,F_OK)) goto nomount; - autoexec[2].Install("MOUNT C \"%s\"",buffer); - autoexec[3].Install("C:"); + autoexec[12].Install("MOUNT C \"%s\"",buffer); + autoexec[13].Install("C:"); upcase(name); if(strstr(name,".BAT")==0) { - autoexec[4].Install(name); + autoexec[14].Install(name); } else { char call[CROSS_LEN] = { 0 }; strcpy(call,"CALL "); strcat(call,name); - autoexec[4].Install(call); + autoexec[14].Install(call); } - if(addexit) autoexec[5].Install("exit"); + if(addexit) autoexec[15].Install("exit"); } } nomount: From 2fdd9393f6c22a6feb5f756c70837e9c7c9b3358 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 27 Apr 2005 18:58:08 +0000 Subject: [PATCH 2111/4131] always report vesa version 2.0, changed colororder when setting pallet. (fixes quake). (Thanks kekko) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2195 --- src/ints/int10_vesa.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index ca2ac628..2d9378db 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.15 2005-03-24 21:41:26 qbix79 Exp $ */ +/* $Id: int10_vesa.cpp,v 1.16 2005-04-27 18:58:08 qbix79 Exp $ */ #include #include @@ -95,8 +95,8 @@ Bit8u VESA_GetSVGAInformation(Bit16u seg,Bit16u off) { } /* Fill common data */ MEM_BlockWrite(buffer,(void *)"VESA",4); //Identification + mem_writew(buffer+0x04,0x200); //Vesa version 0x200 if (vbe2) { - mem_writew(buffer+0x04,0x200); //Vesa version 0x200 mem_writed(buffer+0x06,RealMake(seg,vbe2_pos)); for (i=0;i255) return 0x1; if (index+count>256) return 0x1; IO_Write(0x3c8,index); while (count) { - IO_Write(0x3c9,mem_readb(data++)); - IO_Write(0x3c9,mem_readb(data++)); - IO_Write(0x3c9,mem_readb(data++)); + b = mem_readb(data++); + g = mem_readb(data++); + r = mem_readb(data++); data++; + IO_Write(0x3c9,r); + IO_Write(0x3c9,g); + IO_Write(0x3c9,b); count--; } return 0x00; @@ -201,13 +205,17 @@ Bit8u VESA_SetPalette(PhysPt data,Bitu index,Bitu count) { Bit8u VESA_GetPalette(PhysPt data,Bitu index,Bitu count) { + Bit8u r,g,b; if (index>255) return 0x1; if (index+count>256) return 0x1; IO_Write(0x3c7,index); while (count) { - mem_writeb(data++,IO_Read(0x3c9)); - mem_writeb(data++,IO_Read(0x3c9)); - mem_writeb(data++,IO_Read(0x3c9)); + r = IO_Read(0x3c9); + g = IO_Read(0x3c9); + b = IO_Read(0x3c9); + mem_writeb(data++,b); + mem_writeb(data++,g); + mem_writeb(data++,r); data++; count--; } From 93a94c5b045f2f3206aeb71bedff1d5475b07265 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 27 Apr 2005 19:57:37 +0000 Subject: [PATCH 2112/4131] Fix a bug with eip being set with wrong size on block ending Add linking to fpu opcodes in fpu emulator Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2196 --- src/cpu/core_dyn_x86/decoder.h | 59 ++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 03781b4e..3b3750c9 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -16,6 +16,18 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "fpu.h" +#define DYN_FPU_ESC(code) { \ + dyn_get_modrm(); \ + if (decode.modrm.val >= 0xc0) { \ + gen_call_function((void*)&FPU_ESC ## code ## _Normal,"%Id",decode.modrm.val); \ + } else { \ + dyn_fill_ea(); \ + gen_call_function((void*)&FPU_ESC ## code ## _EA,"%Id%Dd",decode.modrm.val,DREG(EA)); \ + gen_releasereg(DREG(EA)); \ + } \ +} + enum REP_Type { REP_NONE=0,REP_NZ,REP_Z }; @@ -133,14 +145,14 @@ static void dyn_set_eip_last_end(DynReg * endreg) { gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),decode.op_start-decode.code_start); } -static INLINE void dyn_set_eip_end(void) { - gen_protectflags(); - gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),decode.code-decode.code_start); -} - -static INLINE void dyn_set_eip_last(void) { - gen_protectflags(); - gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),decode.op_start-decode.code_start); + static INLINE void dyn_set_eip_end(void) { + gen_protectflags(); + gen_dop_word_imm(DOP_ADD,cpu.code.big,DREG(EIP),decode.code-decode.code_start); + } + + static INLINE void dyn_set_eip_last(void) { + gen_protectflags(); + gen_dop_word_imm(DOP_ADD,cpu.code.big,DREG(EIP),decode.op_start-decode.code_start); } static void dyn_push(DynReg * dynreg) { @@ -706,11 +718,6 @@ static void dyn_mov_ev_seg(void) { gen_releasereg(DREG(TMPW)); } -static void dyn_synch_eip(void) { - gen_protectflags(); - gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),decode.code-decode.code_start); -} - static void dyn_load_seg(SegNames seg,DynReg * src) { if (cpu.pmode) { gen_call_function((void *)&CPU_SetSegGeneral,"%Rd%Id%Drw",DREG(TMPB),seg,src); @@ -1331,7 +1338,31 @@ restart_prefix: //GRP2 Eb/Ev,CL case 0xd2:dyn_grp2_eb(grp2_cl);break; case 0xd3:dyn_grp2_ev(grp2_cl);break; - + //FPU + case 0xd8: + DYN_FPU_ESC(0); + break; + case 0xd9: + DYN_FPU_ESC(1); + break; + case 0xda: + DYN_FPU_ESC(2); + break; + case 0xdb: + DYN_FPU_ESC(3); + break; + case 0xdc: + DYN_FPU_ESC(4); + break; + case 0xdd: + DYN_FPU_ESC(5); + break; + case 0xde: + DYN_FPU_ESC(6); + break; + case 0xdf: + DYN_FPU_ESC(7); + break; //Loop's case 0xe2:dyn_loop(LOOP_NONE);goto finish_block; case 0xe3:dyn_loop(LOOP_JCXZ);goto finish_block; From 881ae1b28fa36c1e60f4efd27b89b4048dbc27a2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 27 Apr 2005 20:44:50 +0000 Subject: [PATCH 2113/4131] Added EGA Register Interface Library - Write One Register (0xf1). Fixes colours in A-Train Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2197 --- src/ints/int10.cpp | 3 +++ src/ints/int10.h | 3 +++ src/ints/int10_misc.cpp | 51 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 88f3968d..5357ad0e 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -432,6 +432,9 @@ graphics_chars: reg_al=0x0; } break; + case 0xf1: + INT10_EGA_RIL_F1(reg_bl, reg_bh, reg_dx); + break; case 0xff: if (!warned_ff) LOG(LOG_INT10,LOG_NORMAL)("INT10:FF:Weird NC call"); warned_ff=true; diff --git a/src/ints/int10.h b/src/ints/int10.h index d64fcfce..4c861b17 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -195,3 +195,6 @@ Bit8u VESA_GetPalette(PhysPt data,Bitu index,Bitu count); /* Sup Groups */ void INT10_SetupRomMemory(void); void INT10_SetupVESA(void); + +/* EGA RIL */ +void INT10_EGA_RIL_F1(Bit8u & bl, Bit8u bh, Bit16u dx); diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 7ec7bb9b..299d150f 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -124,3 +124,54 @@ void INT10_GetFuncStateInformation(PhysPt save) { mem_writeb(save+0x31,3); } +static void EGA_RIL(Bit16u dx, Bitu& port, Bitu& regs) { + port = 0; + regs = 0; //if nul is returned it's a single register port + switch(dx) { + case 0x00: /* CRT Controller (25 reg) 3B4h mono modes, 3D4h color modes */ + port = real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + regs = 25; + break; + case 0x08: /* Sequencer (5 registers) 3C4h */ + port = 0x3C4; + regs = 5; + break; + case 0x10: /* Graphics Controller (9 registers) 3CEh */ + port = 0x3CE; + regs = 9; + break; + case 0x18: /* Attribute Controller (20 registers) 3C0h */ + port = 0x3c0; + regs = 20; + break; + case 0x20: /* Miscellaneous Output register 3C2h */ + port = 0x3C2; + break; + case 0x28: /* Feature Control register (3BAh mono modes, 3DAh color modes) */ + port = real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS) + 6; + break; + case 0x30: /* Graphics 1 Position register 3CCh */ + port = 0x3CC; + break; + case 0x38: /* Graphics 2 Position register 3CAh */ + port = 0x3CA; + break; + default: + LOG(LOG_INT10,LOG_ERROR)("unknown RIL port selection %X",dx); + break; + } +} + +void INT10_EGA_RIL_F1(Bit8u & bl, Bit8u bh, Bit16u dx) { + Bitu port = 0; + Bitu regs = 0; + EGA_RIL(dx,port,regs); + if(regs == 0) { + IO_Write(port,bl); + } else { + IO_Write(port,bl); + IO_Write(port+1,bh); + bl = bh;//Not sure + LOG(LOG_INT10,LOG_NORMAL)("EGA RIL used with multi-reg"); + } +} From 2d4f6f39b7040d1a74b9d1e1314dfae731c0e4ca Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 27 Apr 2005 21:24:14 +0000 Subject: [PATCH 2114/4131] disable fpu if not defined (coredynamic) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2198 --- src/cpu/core_dyn_x86.cpp | 4 ++++ src/cpu/core_dyn_x86/decoder.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 4a9b2094..71605085 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -49,6 +49,10 @@ #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, diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 3b3750c9..108e0392 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1339,6 +1339,7 @@ restart_prefix: case 0xd2:dyn_grp2_eb(grp2_cl);break; case 0xd3:dyn_grp2_ev(grp2_cl);break; //FPU +#ifdef CPU_FPU case 0xd8: DYN_FPU_ESC(0); break; @@ -1363,6 +1364,7 @@ restart_prefix: case 0xdf: DYN_FPU_ESC(7); break; +#endif //Loop's case 0xe2:dyn_loop(LOOP_NONE);goto finish_block; case 0xe3:dyn_loop(LOOP_JCXZ);goto finish_block; From 2146cae4ef92837e32ea98275cf276aa7ac6b06a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 28 Apr 2005 18:54:25 +0000 Subject: [PATCH 2115/4131] release eax when fstsw is called Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2199 --- src/cpu/core_dyn_x86/decoder.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 108e0392..2cb67015 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -25,7 +25,7 @@ dyn_fill_ea(); \ gen_call_function((void*)&FPU_ESC ## code ## _EA,"%Id%Dd",decode.modrm.val,DREG(EA)); \ gen_releasereg(DREG(EA)); \ - } \ + } \ } enum REP_Type { @@ -1362,7 +1362,15 @@ restart_prefix: DYN_FPU_ESC(6); break; case 0xdf: - DYN_FPU_ESC(7); + dyn_get_modrm(); + if (decode.modrm.val >= 0xc0) { + if (decode.modrm.val == 0xe0) gen_releasereg(DREG(EAX)); /* FSTSW */ + gen_call_function((void*)&FPU_ESC7_Normal,"%Id",decode.modrm.val); + } else { + dyn_fill_ea(); + gen_call_function((void*)&FPU_ESC7_EA,"%Id%Dd",decode.modrm.val,DREG(EA)); + gen_releasereg(DREG(EA)); + } break; #endif //Loop's From 600f8d45787172e09c672e25704ae5f40c759bf0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 29 Apr 2005 13:32:31 +0000 Subject: [PATCH 2116/4131] change exit to warning for call 64 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2200 --- src/dos/dos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 3b3c7410..2b365d88 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.83 2005-03-25 12:06:48 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.84 2005-04-29 13:32:31 qbix79 Exp $ */ #include #include @@ -802,7 +802,7 @@ static Bitu DOS_21Handler(void) { } else reg_al = 0xff; //Doesn't officially touch carry flag break; case 0x64: /* Set device driver lookahead flag */ - E_Exit("Unhandled Dos 21 call %02X",reg_ah); + LOG(LOG_DOSMISC,LOG_NORMAL)("set driver look ahead flag"); break; case 0x65: /* Get extented country information and a lot of other useless shit*/ { /* Todo maybe fully support this for now we set it standard for USA */ From d15ec7c3fcf9829847c28b32f6d3aa4d82dafd32 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 29 Apr 2005 13:45:26 +0000 Subject: [PATCH 2117/4131] slighty faster and make the compiler happy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2201 --- src/hardware/mixer.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 71041df1..06424fa6 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.32 2005-04-25 09:23:54 qbix79 Exp $ */ +/* $Id: mixer.cpp,v 1.33 2005-04-29 13:45:26 qbix79 Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -57,11 +57,11 @@ #define MIXER_VOLSHIFT 13 static inline Bit16s MIXER_CLIP(Bits SAMP) { - if (SAMP>MIN_AUDIO) { - if (SAMP MIN_AUDIO) return SAMP; - else return MAX_AUDIO; - } else return MIN_AUDIO; + else return MIN_AUDIO; + } else return MAX_AUDIO; } struct MIXER_Channel { @@ -485,11 +485,14 @@ static void MIXER_ProgramStart(Program * * make) { MixerChannel* MixerObject::Install(MIXER_Handler handler,Bitu freq,char * name){ if(!installed) { - if(strlen(name)>31) E_Exit("Too long mixer channel name"); + if(strlen(name) > 31) E_Exit("Too long mixer channel name"); strncpy(m_name,name,31); - installed=true; + installed = true; return MIXER_AddChannel(handler,freq,name); - } else E_Exit("allready added mixer channel."); + } else { + E_Exit("allready added mixer channel."); + return 0; //Compiler happy + } } MixerObject::~MixerObject(){ From a7b9d51eadc1209a989e5db9bc9ae080723575a9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 29 Apr 2005 14:10:45 +0000 Subject: [PATCH 2118/4131] more comments.remove unused variables. Cleanup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2202 --- src/shell/shell.cpp | 56 ++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 5e98a5e2..9085f6b8 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.59 2005-04-26 14:31:41 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.60 2005-04-29 14:10:45 qbix79 Exp $ */ #include #include @@ -29,8 +29,8 @@ #include "support.h" Bitu call_shellstop; -//Larger scope so shell_del autoexec can use it to -//remove things from the environment +/* Larger scope so shell_del autoexec can use it to + * remove things from the environment */ Program * new_program = 0; static Bitu shellstop_handler(void) { @@ -47,7 +47,7 @@ static std::vector autoexec_strings; typedef std::vector::iterator auto_it; void AutoexecObject::Install(char* line,...) { - if(installed) E_Exit("autoexec: allready created %s",buf); + if(GCC_UNLIKELY(installed)) E_Exit("autoexec: allready created %s",buf); installed = true; va_list msg; @@ -67,7 +67,12 @@ void VFILE_Remove(const char *name); AutoexecObject::~AutoexecObject(){ if(!installed) return; + + // On destruction of the object the autoexec.bat is updated + // so that the line isn't present anymore + // First remove the current autoexec.bat VFILE_Remove("AUTOEXEC.BAT"); + // Remove the line from the autoexecbuffer for(auto_it it = autoexec_strings.begin(); it != autoexec_strings.end(); ) { if((*it) == buf) { @@ -105,9 +110,6 @@ DOS_Shell::DOS_Shell():Program(){ completion_start = NULL; } - - - Bitu DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn,bool * append) { char * lr=s; @@ -157,36 +159,33 @@ Bitu DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn,bool * append) { void DOS_Shell::ParseLine(char * line) { LOG(LOG_EXEC,LOG_ERROR)("Parsing command line: %s",line); /* Check for a leading @ */ - if (line[0]=='@') line[0]=' '; - line=trim(line); + if (line[0] == '@') line[0] = ' '; + line = trim(line); /* Do redirection and pipe checks */ - char * in=0; - char * out=0; + char * in = 0; + char * out = 0; - Bit16u old_in,old_out; Bit16u dummy,dummy2; Bit32u bigdummy = 0; Bitu num = 0; /* Number of commands in this line */ bool append; - bool normalstdin=false; /* wether stdin/out are open on start. */ - bool normalstdout=false; /* Bug: Assumed is they are "con" */ + bool normalstdin = false; /* wether stdin/out are open on start. */ + bool normalstdout = false; /* Bug: Assumed is they are "con" */ num = GetRedirection(line,&in, &out,&append); if (num>1) LOG_MSG("SHELL:Multiple command on 1 line not supported"); -// if (in || num>1) DOS_DuplicateEntry(0,&old_in); - if (in || out) { - normalstdin = (psp->GetFileHandle(0)!=0xff); - normalstdout = (psp->GetFileHandle(1)!=0xff); + normalstdin = (psp->GetFileHandle(0) != 0xff); + normalstdout = (psp->GetFileHandle(1) != 0xff); } if (in) { if(DOS_OpenFile(in,0,&dummy)) { //Test if file exists DOS_CloseFile(dummy); LOG_MSG("SHELL:Redirect input from %s",in); if(normalstdin) DOS_CloseFile(0); //Close stdin - DOS_OpenFile(in,0,&dummy);//Open new stdin + DOS_OpenFile(in,0,&dummy); //Open new stdin } } if (out){ @@ -195,14 +194,14 @@ void DOS_Shell::ParseLine(char * line) { if(!normalstdin && !in) DOS_OpenFile("con",2,&dummy); bool status = true; /* Create if not exist. Open if exist. Both in read/write mode */ - if(append){ - if( (status=DOS_OpenFile(out,2,&dummy)) ) + if(append) { + if( (status = DOS_OpenFile(out,2,&dummy)) ) DOS_SeekFile(1,&bigdummy,DOS_SEEK_END); } else - status=DOS_OpenFileExtended(out,2,2,0x12,&dummy,&dummy2); + status = DOS_OpenFileExtended(out,2,2,0x12,&dummy,&dummy2); - if(!status && normalstdout) DOS_OpenFile("con",2,&dummy); //Read only file, open con again + if(!status && normalstdout) DOS_OpenFile("con",2,&dummy); //Read only file, open con again if(!normalstdin && !in) DOS_CloseFile(0); } /* Run the actual command */ @@ -231,7 +230,7 @@ void DOS_Shell::RunInternal(void) while(bf && bf->ReadLine(input_line)) { if (echo) { - if (input_line[0]!='@') { + if (input_line[0] != '@') { ShowPrompt(); WriteOut(input_line); WriteOut("\n"); @@ -297,6 +296,7 @@ void AUTOEXEC_Init(Section * sec) { Section_line * section=static_cast(sec); char * extra=(char *)section->data.c_str(); if (extra) autoexec[0].Install("%s",extra); + /* Check to see for extra command line options to be added (before the command specified on commandline) */ /* Maximum of extra commands: 10 */ Bitu i = 1; @@ -323,7 +323,7 @@ void AUTOEXEC_Init(Section * sec) { autoexec[13].Install("C:"); } else { char* name = strrchr(buffer,CROSS_FILESPLIT); - if (!name) {//Only a filename + if (!name) { //Only a filename line = buffer; getcwd(buffer,CROSS_LEN); strcat(buffer,cross_filesplit); @@ -337,9 +337,10 @@ void AUTOEXEC_Init(Section * sec) { autoexec[12].Install("MOUNT C \"%s\"",buffer); autoexec[13].Install("C:"); upcase(name); - if(strstr(name,".BAT")==0) { + if(strstr(name,".BAT") == 0) { autoexec[14].Install(name); } else { + /* BATch files are called else exit will not work */ char call[CROSS_LEN] = { 0 }; strcpy(call,"CALL "); strcat(call,name); @@ -490,7 +491,6 @@ void SHELL_Init() { DOS_CloseFile(0); /* Close STDIN */ DOS_ForceDuplicateEntry(1,0);/* "new" STDIN */ DOS_ForceDuplicateEntry(1,2);/* STDERR */ -// DOS_OpenFile("CON",2,&dummy);/* STDERR */ DOS_OpenFile("CON",2,&dummy);/* STDAUX */ DOS_OpenFile("CON",2,&dummy);/* STDPRN */ @@ -511,5 +511,5 @@ void SHELL_Init() { SHELL_ProgramStart(&new_program); new_program->Run(); delete new_program; - new_program=0;//Make clear that it shouldn't be used anymore + new_program = 0;//Make clear that it shouldn't be used anymore } From 347c222b939937a6356d2347e6b61c7100b898bf Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 29 Apr 2005 15:04:07 +0000 Subject: [PATCH 2119/4131] some small changes that fix mode 6 at my place Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2203 --- src/hardware/vga_draw.cpp | 2 +- src/ints/int10_modes.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 200e5323..1fb07585 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -438,7 +438,7 @@ void VGA_SetupDrawing(Bitu val) { break; case M_CGA2: doubleheight=true; - vga.draw.blocks=width; + vga.draw.blocks=2*width; width<<=4; VGA_DrawLine=VGA_Draw_1BPP_Line; break; diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index ddb1669c..e06ad413 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -484,6 +484,7 @@ bool INT10_SetVideoMode(Bitu mode) { case M_LIN8: underline=0x60; //Seems to enable the every 4th clock on my s3 break; + case M_CGA2: case M_CGA4: max_scanline|=1; break; @@ -566,10 +567,10 @@ bool INT10_SetVideoMode(Bitu mode) { case M_EGA16: gfx_data[0x6]|=0x05; //graphics mode at 0xa000-affff break; - case M_CGA2: case M_CGA4: case M_TANDY16: gfx_data[0x5]|=0x20; //CGA mode + case M_CGA2: gfx_data[0x6]|=0x0f; //graphics mode at at 0xb800=0xbfff break; } From 640e9475b1ec5d116e4ed1f956889a90f735c454 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 2 May 2005 21:18:01 +0000 Subject: [PATCH 2120/4131] Some bizarre vga dac behaviour fixes star control 2 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2204 --- src/hardware/vga_dac.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index c5181059..a8d0461c 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -66,7 +66,7 @@ static void write_p3c7(Bitu port,Bitu val,Bitu iolen) { vga.dac.read_index=val; vga.dac.pel_index=0; vga.dac.state=DAC_READ; - + vga.dac.write_index= val + 1; } static Bitu read_p3c7(Bitu port,Bitu iolen) { @@ -118,6 +118,7 @@ static void write_p3c9(Bitu port,Bitu val,Bitu iolen) { } } vga.dac.write_index++; + vga.dac.read_index = vga.dac.write_index - 1; vga.dac.pel_index=0; break; default: @@ -140,6 +141,7 @@ static Bitu read_p3c9(Bitu port,Bitu iolen) { ret=vga.dac.rgb[vga.dac.read_index].blue; vga.dac.read_index++; vga.dac.pel_index=0; + vga.dac.write_index=vga.dac.read_index+1; break; default: LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:DAC:Illegal Pel Index"); //If this can actually happen that will be the day From 8008c426fb5d111c3ac6d895973f54af0107df02 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 3 May 2005 15:27:29 +0000 Subject: [PATCH 2121/4131] some safety code for games writing to con in non-textmode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2205 --- src/ints/int10_char.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 60b9081a..76640736 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.32 2005-03-01 11:13:29 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.33 2005-05-03 15:27:29 qbix79 Exp $ */ /* Character displaying moving functions */ @@ -424,6 +424,26 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt fontdata=Real2Phys(RealGetVec(0x43))+chr*cheight; break; } + + if(GCC_UNLIKELY(!useattr)) { //Set attribute(color) to a sensible value + static bool warned_use = false; + if(GCC_UNLIKELY(!warned_use)){ + LOG(LOG_INT10,LOG_ERROR)("writechar used without attribute in non-textmode"); + warned_use = true; + } + switch(CurMode->type) { + case M_CGA4: + case M_CGA2: + attr = 0x1; + break; + case M_TANDY16: + case M_EGA16: + default: + attr = 0xf; + break; + } + } + x=8*col; y=cheight*row;Bit8u xor_mask=(CurMode->type == M_VGA) ? 0x0 : 0x80; //TODO Check for out of bounds From 4751e234c04f9d92feae5d034a14e52f9e5e505a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 3 May 2005 20:33:55 +0000 Subject: [PATCH 2122/4131] Fix CGA color select register writing in machine=vga mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2206 --- src/ints/int10_pal.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 456af7ed..39a62333 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -174,12 +174,32 @@ void INT10_SetBackgroundBorder(Bit8u val) { Bitu temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL); temp=(temp & 0xe0) | (val & 0x1f); real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp); - IO_Write(0x3d9,temp); + if (machine == MCH_CGA || machine == MCH_TANDY) + IO_Write(0x3d9,temp); + else if (machine == MCH_VGA) { + val = ((val << 1) & 0x10) | (val & 0x7); + INT10_SetSinglePaletteRegister( 0, val ); + val = (temp & 0x10) | 2 | ((temp & 0x20) >> 5); + INT10_SetSinglePaletteRegister( 1, val ); + val+=2; + INT10_SetSinglePaletteRegister( 2, val ); + val+=2; + INT10_SetSinglePaletteRegister( 3, val ); + } } void INT10_SetColorSelect(Bit8u val) { Bitu temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL); temp=(temp & 0xdf) | ((val & 1) ? 0x20 : 0x0); real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp); - IO_Write(0x3d9,temp); + if (machine == MCH_CGA || machine == MCH_TANDY) + IO_Write(0x3d9,temp); + else if (machine == MCH_VGA) { + val = (temp & 0x10) | 2 | val; + INT10_SetSinglePaletteRegister( 1, val ); + val+=2; + INT10_SetSinglePaletteRegister( 2, val ); + val+=2; + INT10_SetSinglePaletteRegister( 3, val ); + } } From 2823bb909de7b49d5d10e26392a757bee7e73034 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 4 May 2005 19:33:46 +0000 Subject: [PATCH 2123/4131] fix scrolling in some weird cga mode when in the console Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2207 --- src/ints/int10_char.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 76640736..aed0030c 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.33 2005-05-03 15:27:29 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.34 2005-05-04 19:33:46 qbix79 Exp $ */ /* Character displaying moving functions */ @@ -517,10 +517,12 @@ void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr) { } // Do we need to scroll ? if(cur_row==nrows) { - INT10_ScrollWindow(0,0,nrows-1,ncols-1,-1,0x07,page); + //Fill with black on non-text modes and with 0x7 on textmode + Bit8u fill = (CurMode->type == M_TEXT)?0x7:0; + INT10_ScrollWindow(0,0,nrows-1,ncols-1,-1,fill,page); cur_row--; } - // Set the cursor for the page + // Set the cursor for the page INT10_SetCursorPos(cur_row,cur_col,page); } From 8014ff9044aab6faf264e6679636059a631631f7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 4 May 2005 19:50:32 +0000 Subject: [PATCH 2124/4131] fix type bug in movxz (thanks wd) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2208 --- src/cpu/core_dyn_x86/decoder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 2cb67015..e1a6b0fd 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -498,7 +498,7 @@ static void dyn_mov_ev_gb(bool sign) { static void dyn_mov_ev_gw(bool sign) { if (!decode.big_op) { - dyn_mov_evgv(); + dyn_mov_gvev(); return; } dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg]; From c2eef4eac899cfa8fecc3ebc30cb4b8e8be02891 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 15 May 2005 20:16:47 +0000 Subject: [PATCH 2125/4131] fix annoying log message Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2209 --- src/cpu/core_full/load.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index cfe87413..37d1e67d 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -427,6 +427,7 @@ l_M_Ed: goto nextopcode; case D_WAIT: case D_NOP: + goto nextopcode; case D_LOCK: /* FIXME: according to intel, LOCK should raise an exception if it's not followed by one of a small set of instructions; probably doesn't matter for our purposes as it is a pentium prefix anyhow */ LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK"); From 5d3d56e060abbd2aea0958bf661185dc85198520 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 18 May 2005 17:29:09 +0000 Subject: [PATCH 2126/4131] add patch/bug 1203382 from Chris Thielen. Fixes problems with batchfiles using %0 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2210 --- src/shell/shell_batch.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 086afed7..d708d66b 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.16 2005-03-25 09:02:43 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.17 2005-05-18 17:29:09 qbix79 Exp $ */ #include #include @@ -28,7 +28,7 @@ BatchFile::BatchFile(DOS_Shell * host,char * name, char * cmd_line) { prev=host->bf; echo=host->echo; shell=host; - cmd=new CommandLine(0,cmd_line); + cmd=new CommandLine(name,cmd_line); if (!DOS_OpenFile(name,128,&file_handle)) { //TODO Come up with something better E_Exit("SHELL:Can't open BatchFile"); @@ -70,12 +70,19 @@ emptyline: env_write=env_name; if (*cmd_read=='%') { cmd_read++; - if (cmd_read[0]=='%') { + if (cmd_read[0] == '%') { cmd_read++; *cmd_write++='%'; } - size_t len=strspn(cmd_read,"0123456789"); - if (len) { + if (cmd_read[0] == '0') { /* Handle %0 */ + const char *file_name = cmd->GetFileName(); + cmd_read++; + strcpy(cmd_write,file_name); + cmd_write+=strlen(file_name); + continue; + } + size_t len=strspn(cmd_read,"123456789"); + if (len) { /* Handle %1 %2 .. %9 */ memcpy(env_name,cmd_read,len); env_name[len]=0;cmd_read+=len; len=atoi(env_name); From d23d71add82891cc519a781a42a0c806ccbb4f9e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 18 May 2005 21:59:58 +0000 Subject: [PATCH 2127/4131] fix crashes with E_Exit in debug mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2211 --- src/gui/sdlmain.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 29268e91..39842348 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.84 2005-04-21 18:51:54 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.85 2005-05-18 21:59:58 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1132,11 +1132,13 @@ int main(int argc, char* argv[]) { control->StartUp(); /* Shutdown everything */ } catch (char * error) { - LOG_MSG("Exit to error: %s",error); + GFX_ShowMsg("Exit to error: %s",error); + fflush(NULL); if(sdl.wait_on_error) { //TODO Maybe look for some way to show message in linux? #if (C_DEBUG) - LOG_MSG("Press enter to continue"); + GFX_ShowMsg("Press enter to continue"); + fflush(NULL); fgetc(stdin); #elif defined(WIN32) Sleep(5000); From 719d57bea98b37d637f0ef0299a426786cc18e2b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 26 May 2005 15:25:29 +0000 Subject: [PATCH 2128/4131] sum of videoROM modules 256 = 0 in VGA mode. Fixes a few koei games. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2212 --- src/ints/int10_memory.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 0ffb3b54..6d391bdf 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -108,6 +108,15 @@ void INT10_SetupRomMemory(void) { phys_writeb(PhysMake(0xf000,0xfa6e)+i,int10_font_08[i]); } RealSetVec(0x1F,int10.rom.font_8_second); + + if (machine == MCH_VGA) { //EGA/VGA. Just to be safe + /* Sum of all bytes in rom module 256 should be 0 */ + Bit8u sum = 0; + for (i = 0;i < 32 * 1024;i++) //32 KB romsize + sum += phys_readb(rom_base + i); //OVERFLOW IS OKAY + sum = 256 - sum; + phys_writeb(rom_base+int10.rom.used++,sum); + } }; From df1b64ffadc8a845d242ec5bc4a472ca8d25f7de Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 31 May 2005 18:38:54 +0000 Subject: [PATCH 2129/4131] Don't crash if dta is rubbish with findnext. change WildFilecmp to use strrchr instead of strchr. This way .. get's matched with *. Fixes Wonderland Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2213 --- src/dos/dos_files.cpp | 11 +++++++++-- src/dos/drives.cpp | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 70e8ccd7..1430adda 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.62 2005-03-01 19:39:55 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.63 2005-05-31 18:38:54 qbix79 Exp $ */ #include #include @@ -270,7 +270,14 @@ bool DOS_FindFirst(char * search,Bit16u attr,bool fcb_findfirst) { bool DOS_FindNext(void) { DOS_DTA dta(dos.dta()); - if (Drives[dta.GetSearchDrive()]->FindNext(dta)) return true; + Bit8u i = dta.GetSearchDrive(); + if(i >= DOS_DRIVES || !Drives[i]) { + /* Corrupt search. */ + LOG(LOG_FILES,LOG_ERROR)("Corrupt search!!!!"); + DOS_SetError(DOSERR_NO_MORE_FILES); + return false; + } + if (Drives[i]->FindNext(dta)) return true; return false; } diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index 11b617c5..cf1e19cd 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -35,7 +35,7 @@ bool WildFileCmp(const char * file, const char * wild) strcpy(wild_name," "); strcpy(wild_ext," "); - find_ext=strchr(file,'.'); + find_ext=strrchr(file,'.'); if (find_ext) { Bitu size=find_ext-file;if (size>8) size=8; memcpy(file_name,file,size); @@ -45,7 +45,7 @@ bool WildFileCmp(const char * file, const char * wild) memcpy(file_name,file,(strlen(file) > 8) ? 8 : strlen(file)); } upcase(file_name);upcase(file_ext); - find_ext=strchr(wild,'.'); + find_ext=strrchr(wild,'.'); if (find_ext) { Bitu size=find_ext-wild;if (size>8) size=8; memcpy(wild_name,wild,size); From 3c88eaf92d0dc8e4d555aa07e726d501808b2136 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 31 May 2005 20:19:13 +0000 Subject: [PATCH 2130/4131] fix tiny bug when >> is used on a non-existing file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2214 --- src/shell/shell.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 9085f6b8..236dcabb 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.60 2005-04-29 14:10:45 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.61 2005-05-31 20:19:13 qbix79 Exp $ */ #include #include @@ -195,8 +195,11 @@ void DOS_Shell::ParseLine(char * line) { bool status = true; /* Create if not exist. Open if exist. Both in read/write mode */ if(append) { - if( (status = DOS_OpenFile(out,2,&dummy)) ) + if( (status = DOS_OpenFile(out,2,&dummy)) ) { DOS_SeekFile(1,&bigdummy,DOS_SEEK_END); + } else { + status = DOS_CreateFile(out,2,&dummy); //Create if not exists. + } } else status = DOS_OpenFileExtended(out,2,2,0x12,&dummy,&dummy2); From 370038048415d3b5f10a806a9691af13005196b1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 2 Jun 2005 17:27:27 +0000 Subject: [PATCH 2131/4131] change bx if a bogus mouse button is selected for button data. Fixed The Patrician (Der Patrizer) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2215 --- src/ints/mouse.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 0c40ff53..a9a9479a 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.49 2005-04-21 18:34:47 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.50 2005-06-02 17:27:27 qbix79 Exp $ */ #include #include @@ -631,6 +631,7 @@ static Bitu INT33_Handler(void) { { Bit16u but=reg_bx; reg_ax=mouse.buttons; + reg_bx++; if (but>=MOUSE_BUTTONS) break; reg_cx=mouse.last_pressed_x[but]; reg_dx=mouse.last_pressed_y[but]; @@ -642,6 +643,7 @@ static Bitu INT33_Handler(void) { { Bit16u but=reg_bx; reg_ax=mouse.buttons; + reg_bx++; if (but>=MOUSE_BUTTONS) break; reg_cx=mouse.last_released_x[but]; reg_dx=mouse.last_released_y[but]; From 82c4309af723600305062c66554fe0355a8065a0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 6 Jun 2005 16:07:31 +0000 Subject: [PATCH 2132/4131] fix 200 mb image bug(thank you wd). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2216 --- src/ints/bios_disk.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 64b01d07..0387ede1 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.17 2005-02-11 21:17:04 qbix79 Exp $ */ +/* $Id: bios_disk.cpp,v 1.18 2005-06-06 16:07:31 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" @@ -388,8 +388,8 @@ static Bitu INT13_DiskHandler(void) { reg_bl = imageDiskList[drivenum]->GetBiosType(); Bit32u tmpheads, tmpcyl, tmpsect, tmpsize; imageDiskList[drivenum]->Get_Geometry(&tmpheads, &tmpcyl, &tmpsect, &tmpsize); - reg_ch = tmpcyl; - reg_cl = tmpsect; + reg_ch = tmpcyl & 0xff; + reg_cl = (((tmpcyl >> 2) & 0xc0) | (tmpsect & 0x3f)); reg_dh = tmpheads-1; last_status = 0x00; reg_dl = 0; From 5045f19259acfb87995d45d97eb21e334ecf82a8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 13 Jun 2005 14:48:02 +0000 Subject: [PATCH 2133/4131] Add patch 1094730 from Jon Niehof. Added a time out event for the joystick.(fixes detection in certain games). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2217 --- include/joystick.h | 14 +++ src/dosbox.cpp | 11 +- src/gui/sdl_mapper.cpp | 241 ++++++++++++++++++++++++++++++++++++-- src/hardware/joystick.cpp | 31 ++++- 4 files changed, 281 insertions(+), 16 deletions(-) diff --git a/include/joystick.h b/include/joystick.h index 88407ad7..b79666e3 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -16,6 +16,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: joystick.h,v 1.7 2005-06-13 14:48:01 qbix79 Exp $ */ +#ifndef DOSBOX_JOYSTICK_H +#define DOSBOX_JOYSTICK_H void JOYSTICK_Enable(Bitu which,bool enabled); void JOYSTICK_Button(Bitu which,Bitu num,bool pressed); @@ -31,3 +34,14 @@ bool JOYSTICK_GetButton(Bitu which, Bitu num); float JOYSTICK_GetMove_X(Bitu which); float JOYSTICK_GetMove_Y(Bitu which); + +enum JoystickType { + JOY_NONE, + JOY_2AXIS, + JOY_4AXIS, + JOY_FCS, + JOY_CH +}; + +extern JoystickType joytype; +#endif diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 6722a5c5..8d865c43 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.84 2005-04-21 21:17:45 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.85 2005-06-13 14:48:00 qbix79 Exp $ */ #include #include @@ -260,7 +260,6 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&DMA_Init);//done secprop->AddInitFunction(&VGA_Init); secprop->AddInitFunction(&KEYBOARD_Init); - secprop->AddInitFunction(&JOYSTICK_Init);//done secprop=control->AddSection_prop("mixer",&MIXER_Init); secprop->Add_bool("nosound",false); @@ -354,6 +353,14 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("bios",&BIOS_Init,false);//done secprop->AddInitFunction(&INT10_Init); secprop->AddInitFunction(&MOUSE_Init); //Must be after int10 as it uses CurMode + secprop->AddInitFunction(&JOYSTICK_Init); + secprop->Add_string("joysticktype","2axis"); + MSG_Add("BIOS_CONFIGFILE_HELP", + "joysticktype -- Type of joystick to emulate: none, 2axis, 4axis,\n" + " fcs (Thrustmaster) ,ch (CH Flightstick).\n" + " none disables joystick emulation.\n" + " 2axis is the default and supports two joysticks.\n" + ); /* All the DOS Related stuff, which will eventually start up in the shell */ //TODO Maybe combine most of the dos stuff in one section like ems,xms diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 3d100faa..ba3d94d7 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.11 2005-02-10 10:21:07 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.12 2005-06-13 14:48:02 qbix79 Exp $ */ #define OLD_JOYSTICK 1 @@ -346,7 +346,9 @@ public: hat_lists=new CBindList[hats]; #if OLD_JOYSTICK LOG_MSG("Using joystick %s with %d axes and %d buttons",SDL_JoystickName(stick),axes,buttons); - JOYSTICK_Enable(stick,true); + //if the first stick is set, we must be the second + emustick=JOYSTICK_IsEnabled(0); + JOYSTICK_Enable(emustick,true); #endif } ~CStickBindGroup() { @@ -380,7 +382,7 @@ public: return CreateButtonBind(event->jbutton.button); } else return 0; } - bool CheckEvent(SDL_Event * event) { + virtual bool CheckEvent(SDL_Event * event) { #if OLD_JOYSTICK SDL_JoyAxisEvent * jaxis = NULL; SDL_JoyButtonEvent * jbutton = NULL; @@ -388,18 +390,19 @@ public: switch(event->type) { case SDL_JOYAXISMOTION: jaxis = &event->jaxis; - if(jaxis->axis == 0) - JOYSTICK_Move_X(stick,(float)(jaxis->value/32768.0)); - else if(jaxis->axis == 1) - JOYSTICK_Move_Y(stick,(float)(jaxis->value/32768.0)); + if(jaxis->which == stick) + if(jaxis->axis == 0) + JOYSTICK_Move_X(emustick,(float)(jaxis->value/32768.0)); + else if(jaxis->axis == 1) + JOYSTICK_Move_Y(emustick,(float)(jaxis->value/32768.0)); break; case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: jbutton = &event->jbutton; bool state; state=jbutton->type==SDL_JOYBUTTONDOWN; - if (jbutton->button<2) { - JOYSTICK_Button(stick,jbutton->button,state); + if ((jbutton->which == stick) && (jbutton->button<2)) { + JOYSTICK_Button(emustick,jbutton->button,state); } break; } @@ -427,11 +430,201 @@ protected: CBindList * neg_axis_lists; CBindList * button_lists; CBindList * hat_lists; - Bitu stick,axes,buttons,hats; + Bitu stick,emustick,axes,buttons,hats; SDL_Joystick * sdl_joystick; char configname[10]; }; +class C4AxisBindGroup : public CStickBindGroup { +public: + C4AxisBindGroup(Bitu _stick) : CStickBindGroup (_stick){ +#if OLD_JOYSTICK + JOYSTICK_Enable(1,true); +#endif + } + bool CheckEvent(SDL_Event * event) { +#if OLD_JOYSTICK + SDL_JoyAxisEvent * jaxis = NULL; + SDL_JoyButtonEvent * jbutton = NULL; + + switch(event->type) { + case SDL_JOYAXISMOTION: + jaxis = &event->jaxis; + if(jaxis->which == stick && jaxis->axis < 4) + if(jaxis->axis & 1) + JOYSTICK_Move_Y(jaxis->axis>>1 & 1,(float)(jaxis->value/32768.0)); + else + JOYSTICK_Move_X(jaxis->axis>>1 & 1,(float)(jaxis->value/32768.0)); + break; + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + jbutton = &event->jbutton; + bool state; + state=jbutton->type==SDL_JOYBUTTONDOWN; + if ((jbutton->which == stick) && (jbutton->button<4)) { + JOYSTICK_Button((jbutton->button >> 1), + (jbutton->button & 1),state); + } + break; + } +#endif + return false; + } +}; + +class CFCSBindGroup : public CStickBindGroup { +public: + CFCSBindGroup(Bitu _stick) : CStickBindGroup (_stick){ +#if OLD_JOYSTICK + JOYSTICK_Enable(1,true); + JOYSTICK_Move_Y(1,1.0); +#endif + } + bool CheckEvent(SDL_Event * event) { +#if OLD_JOYSTICK + SDL_JoyAxisEvent * jaxis = NULL; + SDL_JoyButtonEvent * jbutton = NULL; + SDL_JoyHatEvent * jhat = NULL; + + switch(event->type) { + case SDL_JOYAXISMOTION: + jaxis = &event->jaxis; + if(jaxis->which == stick) + if(jaxis->axis == 0) + JOYSTICK_Move_X(0,(float)(jaxis->value/32768.0)); + else if(jaxis->axis == 1) + JOYSTICK_Move_Y(0,(float)(jaxis->value/32768.0)); + else if(jaxis->axis == 2) + JOYSTICK_Move_X(1,(float)(jaxis->value/32768.0)); + break; + case SDL_JOYHATMOTION: + jhat = &event->jhat; + if(jhat->which == stick) { + switch(jhat->value) { + case SDL_HAT_CENTERED: + JOYSTICK_Move_Y(1,1.0); + break; + case SDL_HAT_UP: + JOYSTICK_Move_Y(1,-1.0); + break; + case SDL_HAT_RIGHT: + JOYSTICK_Move_Y(1,-0.5); + break; + case SDL_HAT_DOWN: + JOYSTICK_Move_Y(1,0.0); + break; + case SDL_HAT_LEFT: + JOYSTICK_Move_Y(1,0.5); + break; + case SDL_HAT_LEFTUP: + if(JOYSTICK_GetMove_Y(1) < 0) + JOYSTICK_Move_Y(1,0.5); + else + JOYSTICK_Move_Y(1,-1.0); + break; + case SDL_HAT_RIGHTUP: + if(JOYSTICK_GetMove_Y(1) < -0.7) + JOYSTICK_Move_Y(1,-0.5); + else + JOYSTICK_Move_Y(1,-1.0); + break; + case SDL_HAT_RIGHTDOWN: + if(JOYSTICK_GetMove_Y(1) < -0.2) + JOYSTICK_Move_Y(1,0.0); + else + JOYSTICK_Move_Y(1,-0.5); + break; + case SDL_HAT_LEFTDOWN: + if(JOYSTICK_GetMove_Y(1) > 0.2) + JOYSTICK_Move_Y(1,0.0); + else + JOYSTICK_Move_Y(1,0.5); + break; + } + } + + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + jbutton = &event->jbutton; + bool state; + state=jbutton->type==SDL_JOYBUTTONDOWN; + if ((jbutton->which == stick) && (jbutton->button<4)) { + JOYSTICK_Button((jbutton->button >> 1), + (jbutton->button & 1),state); + } + break; + } +#endif + return false; + } +}; + +class CCHBindGroup : public CStickBindGroup { +public: + CCHBindGroup(Bitu _stick) : CStickBindGroup (_stick){ +#if OLD_JOYSTICK + JOYSTICK_Enable(1,true); + button_state=0; +#endif + } + bool CheckEvent(SDL_Event * event) { +#if OLD_JOYSTICK + SDL_JoyAxisEvent * jaxis = NULL; + SDL_JoyButtonEvent * jbutton = NULL; + SDL_JoyHatEvent * jhat = NULL; + static unsigned const button_magic[6]={0x02,0x04,0x10,0x100,0x20,0x200}; + static unsigned const hat_magic[2][5]={{0x8888,0x8000,0x800,0x80,0x08}, + {0x5440,0x4000,0x400,0x40,0x1000}}; + switch(event->type) { + case SDL_JOYAXISMOTION: + jaxis = &event->jaxis; + if(jaxis->which == stick && jaxis->axis < 4) + if(jaxis->axis & 1) + JOYSTICK_Move_Y(jaxis->axis>>1 & 1,(float)(jaxis->value/32768.0)); + else + JOYSTICK_Move_X(jaxis->axis>>1 & 1,(float)(jaxis->value/32768.0)); + break; + case SDL_JOYHATMOTION: + jhat = &event->jhat; + if(jhat->which == stick && jhat->hat < 2) { + if(jhat->value == SDL_HAT_CENTERED) + button_state&=~hat_magic[jhat->hat][0]; + if(jhat->value & SDL_HAT_UP) + button_state|=hat_magic[jhat->hat][1]; + if(jhat->value & SDL_HAT_RIGHT) + button_state|=hat_magic[jhat->hat][2]; + if(jhat->value & SDL_HAT_DOWN) + button_state|=hat_magic[jhat->hat][3]; + if(jhat->value & SDL_HAT_LEFT) + button_state|=hat_magic[jhat->hat][4]; + } + break; + case SDL_JOYBUTTONDOWN: + jbutton = &event->jbutton; + if ((jbutton->which == stick) && (jbutton->button<6)) + button_state|=button_magic[jbutton->button]; + break; + case SDL_JOYBUTTONUP: + jbutton = &event->jbutton; + if ((jbutton->which == stick) && (jbutton->button<6)) + button_state&=~button_magic[jbutton->button]; + break; + } + unsigned i; + Bit16u j; + j=button_state; + for(i=0;i<16;i++) if (j & 1) break; else j>>=1; + JOYSTICK_Button(0,0,i&0x01); + JOYSTICK_Button(0,1,i>>1&0x01); + JOYSTICK_Button(1,0,i>>2&0x01); + JOYSTICK_Button(1,1,i>>3&0x01); +#endif + + return false; + } +protected: + Bit16u button_state; +}; static struct { SDL_Surface * surface; @@ -1209,9 +1402,31 @@ void BIND_MappingEvents(void) { static void CreateBindGroups(void) { bindgroups.clear(); new CKeyBindGroup(SDLK_LAST); - Bitu numsticks=SDL_NumJoysticks(); - if (numsticks) SDL_JoystickEventState(SDL_ENABLE); - for (Bitu i=0;i #include "dosbox.h" #include "inout.h" #include "setup.h" +#include "joystick.h" +#include "pic.h" #define RANGE 64 +#define TIMEOUT 10 struct JoyStick { bool enabled; @@ -29,11 +35,23 @@ struct JoyStick { bool button[2]; }; - +JoystickType joytype; static JoyStick stick[2]; +static Bit32u last_write = 0; +static bool write_active = false; static Bitu read_p201(Bitu port,Bitu iolen) { + /* Reset Joystick to 0 after TIMEOUT ms */ + if(write_active && ((PIC_Ticks - last_write) > TIMEOUT)) { + write_active = false; + stick[0].xcount = 0; + stick[1].xcount = 0; + stick[0].ycount = 0; + stick[1].ycount = 0; +// LOG_MSG("reset by time %d %d",PIC_Ticks,last_write); + } + /** Format of the byte to be returned: ** | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ** +-------------------------------+ @@ -60,6 +78,9 @@ static Bitu read_p201(Bitu port,Bitu iolen) { } static void write_p201(Bitu port,Bitu val,Bitu iolen) { + /* Store writetime index */ + write_active = true; + last_write = PIC_Ticks; if (stick[0].enabled) { stick[0].xcount=(Bitu)((stick[0].xpos*RANGE)+RANGE); stick[0].ycount=(Bitu)((stick[0].ypos*RANGE)+RANGE); @@ -121,6 +142,14 @@ private: IO_WriteHandleObject WriteHandler; public: JOYSTICK(Section* configuration):Module_base(configuration){ + Section_prop * section=static_cast(configuration); + const char * type=section->Get_string("joysticktype"); + if (!strcasecmp(type,"none")) joytype=JOY_NONE; + else if (!strcasecmp(type,"2axis")) joytype=JOY_2AXIS; + else if (!strcasecmp(type,"4axis")) joytype=JOY_4AXIS; + else if (!strcasecmp(type,"fcs")) joytype=JOY_FCS; + else if (!strcasecmp(type,"ch")) joytype=JOY_CH; + else joytype=JOY_2AXIS; ReadHandler.Install(0x201,read_p201,IO_MB); WriteHandler.Install(0x201,write_p201,IO_MB); stick[0].enabled=false; From f6cdebf40d3e70f9156f9d69832dc3620baee32c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 15 Jun 2005 17:47:26 +0000 Subject: [PATCH 2134/4131] Change findfirst when it comes to labels. Fixes Der Clou (The Clue) installer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2218 --- src/dos/drive_local.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 8bb7a43b..ff11d041 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.57 2005-04-21 18:46:23 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.58 2005-06-15 17:47:26 qbix79 Exp $ */ #include #include @@ -172,17 +172,27 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) { Bit8u sAttr; dta.GetSearchParams(sAttr,tempDir); - if ( (sAttr & DOS_ATTR_VOLUME) && ( (*_dir==0) || fcb_findfirst ) ) { - // Get Volume Label (DOS_ATTR_VOLUME) and only in basedir - // or it's a fcb findfirst as that always returns label + + if (sAttr == DOS_ATTR_VOLUME) { if ( strcmp(dirCache.GetLabel(), "") == 0 ) { LOG(LOG_DOSMISC,LOG_ERROR)("DRIVELABEL REQUESTED: none present, returned NOLABEL"); dta.SetResult("NO_LABEL",0,0,0,DOS_ATTR_VOLUME); return true; } - // Get Volume Label && ignore search string (pandora) dta.SetResult(dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME); return true; + } else if ((sAttr & DOS_ATTR_VOLUME) && (*_dir == 0) && !fcb_findfirst) { + //should check for a valid leading directory instead of 0 + //exists==true if the volume label matches the searchmask and the path is valid + if ( strcmp(dirCache.GetLabel(), "") == 0 ) { + LOG(LOG_DOSMISC,LOG_ERROR)("DRIVELABEL REQUESTED: none present, returned NOLABEL"); + dta.SetResult("NO_LABEL",0,0,0,DOS_ATTR_VOLUME); + return true; + } + if (WildFileCmp(dirCache.GetLabel(),tempDir)) { + dta.SetResult(dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME); + return true; + } } return FindNext(dta); } @@ -206,7 +216,6 @@ again: DOS_SetError(DOSERR_NO_MORE_FILES); return false; } - if(!WildFileCmp(dir_ent,srch_pattern)) goto again; strcpy(full_name,srchInfo[id].srch_dir); From 6e2a8288d075c67bed8c70802dc629af1367c929 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 16 Jun 2005 18:28:36 +0000 Subject: [PATCH 2135/4131] Change "get current position" to HSG. Fixes a few broken cdrom games Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2219 --- src/dos/dos_mscdex.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index c2d21871..224db0e4 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.28 2005-03-25 09:14:48 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.29 2005-06-16 18:28:36 qbix79 Exp $ */ #include #include @@ -630,8 +630,8 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph return true; } // directory wechseln - dirEntrySector = mem_readd(defBuffer+index+2); - dirSize = mem_readd(defBuffer+index+10); + dirEntrySector = mem_readd(defBuffer+index+2); + dirSize = mem_readd(defBuffer+index+10); } else { // continue search in next sector dirSize -= 2048; @@ -765,11 +765,15 @@ static Bitu MSCDEX_Interrupt_Handler(void) case 0x01 :{/* Get current position */ TMSF pos; mscdex->GetCurrentPos(subUnit,pos); - mem_writeb(buffer+1,0x01); // Red book + /*mem_writeb(buffer+1,0x01); // Red book mem_writeb(buffer+2,pos.fr); mem_writeb(buffer+3,pos.sec); mem_writeb(buffer+4,pos.min); - mem_writeb(buffer+5,0x00); + mem_writeb(buffer+5,0x00);*/ + //Changed to HSG as default + //(Seems to fix a few broken games which don't test for it) + mem_writeb(buffer+1,0x00); //HSG + mem_writed(buffer+2,MSF_TO_FRAMES (pos.min, pos.sec, pos.fr)); }break; case 0x06 : /* Get Device status */ mem_writed(buffer+1,mscdex->GetDeviceStatus(subUnit)); From d8ae7b8f88b072ae4f9d84cddb730016421f1c0a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 16 Jun 2005 18:38:08 +0000 Subject: [PATCH 2136/4131] check if stat succeeded before using it(Kippesoep) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2220 --- src/dos/cdrom.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 3597e3a9..4cd208e7 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -185,10 +185,8 @@ int CDROM_GetMountType(char* path, int forceCD) // Detect ISO struct stat file_stat; - stat(path, &file_stat); - if (S_ISREG(file_stat.st_mode)) return 1; - - return 2; + if ((stat(path, &file_stat) == 0) && S_ISREG(file_stat.st_mode)) return 1; + return 2; }; // ****************************************************** From 990701f42036538f5b74e1f44116f019426ec540 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 21 Jun 2005 18:47:25 +0000 Subject: [PATCH 2137/4131] simpler and hopefully more correct joystick routine (int 15 84 0) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2221 --- src/ints/bios.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index f67866ab..9fdaf4da 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.41 2005-03-25 11:59:24 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.42 2005-06-21 18:47:25 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -244,8 +244,7 @@ static Bitu INT15_Handler(void) { if (reg_dx == 0x0000) { // Get Joystick button status if (JOYSTICK_IsEnabled(0) || JOYSTICK_IsEnabled(1)) { - reg_al = (JOYSTICK_GetButton(0,0)<<7)|(JOYSTICK_GetButton(0,1)<<6); - reg_al |= (JOYSTICK_GetButton(1,0)<<5)|(JOYSTICK_GetButton(1,1)<<4); + reg_al = IO_ReadB(0x201)&0xf0; CALLBACK_SCF(false); } else { // dos values From f3ef0ec55c2203d8be50f8409752589afb6af942 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 22 Jun 2005 19:41:36 +0000 Subject: [PATCH 2138/4131] Fix some weird crashes. not real fix. more a workaround to prevent the crash(1201519) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2222 --- src/cpu/core_dyn_x86/cache.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 348021d1..9bdccb18 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -235,10 +235,13 @@ void CacheBlock::Clear(void) { } if (link[ind].to!=&link_blocks[ind]) { CacheBlock * * wherelink=&link[ind].to->link[ind].from; - while (*wherelink!=this) { - wherelink=&(*wherelink)->link[ind].next; + while (*wherelink != this && *wherelink) { + wherelink = &(*wherelink)->link[ind].next; } - *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); From fc628ada187e2fd3e70c3b5a5baf943cb522920e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 22 Jun 2005 19:47:40 +0000 Subject: [PATCH 2139/4131] disable flipflop to index reset on reading port 0x3c1. Patch 1214516 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2223 --- src/hardware/vga_attr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 513e5a53..ef91511a 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -157,7 +157,7 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) { } Bitu read_p3c1(Bitu port,Bitu iolen) { - vga.internal.attrindex=false; +// vga.internal.attrindex=false; switch (attr(index)) { /* Palette */ case 0x00: case 0x01: case 0x02: case 0x03: From a7f3cf151ac97bc84d7652b457a414234affaf0c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 23 Jun 2005 18:34:30 +0000 Subject: [PATCH 2140/4131] Add patch from Espen Wiborg. Adding dirname for win32. fix compilation problem. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2224 --- src/dos/cdrom_image.cpp | 27 ++++++++++++++++++++------- src/hardware/joystick.cpp | 3 ++- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 4684102b..648c43f6 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.7 2005-04-15 15:58:07 qbix79 Exp $ */ +/* $Id: cdrom_image.cpp,v 1.8 2005-06-23 18:34:29 qbix79 Exp $ */ #include #include @@ -32,6 +32,8 @@ #if !defined(WIN32) #include +#else +#include #endif using namespace std; @@ -387,6 +389,23 @@ bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mod return (pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1); } +#if defined(WIN32) +static string dirname(const char * file) { + char * sep = strrchr(file, '\\'); + if (sep == NULL) + sep = strrchr(file, '/'); + if (sep == NULL) + return ""; + else { + int len = (int)(sep - file); + char tmp[MAX_FILENAME_LENGTH]; + strncpy(tmp, file, len); + tmp[len] = '\0'; + return tmp; + } +} +#endif + bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) { Track track = {0, 0, 0, 0, 0, 0, false, NULL}; @@ -399,11 +418,7 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) bool canAddTrack = false; char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument strncpy(tmp, cuefile, MAX_FILENAME_LENGTH); -#if defined(WIN32) - string pathname(""); -#else string pathname(dirname(tmp)); -#endif ifstream in; in.open(cuefile, ios::in); if (in.fail()) return false; @@ -572,13 +587,11 @@ bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) if (stat(filename.c_str(), &test) == 0) return true; // check if file with path relative to cue file exists -#if !defined(WIN32) string tmpstr(pathname + "/" + filename); if (stat(tmpstr.c_str(), &test) == 0) { filename = tmpstr; return true; } -#endif // finally check if file is in a dosbox local drive char fullname[CROSS_LEN]; char tmp[CROSS_LEN]; diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index 591e344b..1f6d9c12 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: joystick.cpp,v 1.12 2005-06-13 14:48:02 qbix79 Exp $ */ +/* $Id: joystick.cpp,v 1.13 2005-06-23 18:34:30 qbix79 Exp $ */ #include #include "dosbox.h" @@ -24,6 +24,7 @@ #include "setup.h" #include "joystick.h" #include "pic.h" +#include "support.h" #define RANGE 64 #define TIMEOUT 10 From 5f5b27e15701f591883942de9a2965ab6f07e810 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 23 Jun 2005 20:13:58 +0000 Subject: [PATCH 2141/4131] added basic network redirector check used to detect mscdex (patch 1197725 and modified it) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2225 --- src/dos/dos_mscdex.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 224db0e4..da648e22 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.29 2005-06-16 18:28:36 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.30 2005-06-23 20:13:58 qbix79 Exp $ */ #include #include @@ -921,8 +921,19 @@ static Bitu MSCDEX_Interrupt_Handler(void) return CBRET_NONE; } -static bool MSCDEX_Handler(void) -{ +static bool MSCDEX_Handler(void) { + if(reg_ah == 0x11) { + if(reg_al == 0x00) { + reg_al = 0xff; + return true; + } else { + LOG(LOG_MISC,LOG_ERROR)("NETWORK REDIRECTOR USED!!!"); + reg_ax = 0x49;//NETWERK SOFTWARE NOT INSTALLED + CALLBACK_SCF(true); + return true; + } + } + if (reg_ah!=0x15) return false; PhysPt data = PhysMake(SegValue(es),reg_bx); From 0390f617025deda2761bdc7a162db81f8f48a227 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 29 Jun 2005 20:10:47 +0000 Subject: [PATCH 2142/4131] repeat last value in the DSP indefenitely. Fixes Jangle demo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2226 --- src/hardware/sblaster.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 73cc80d9..6e124d55 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -833,7 +833,8 @@ static void DSP_DoWrite(Bit8u val) { } static Bit8u DSP_ReadData(void) { - Bit8u data=0; +/* Static so it repeats the last value on succesive reads (JANGLE DEMO) */ + static Bit8u data = 0; if (sb.dsp.out.used) { data=sb.dsp.out.data[sb.dsp.out.pos]; sb.dsp.out.pos++; From 352640d5a9839cd30f19000497ffc84448f29074 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 1 Jul 2005 08:59:57 +0000 Subject: [PATCH 2143/4131] wcharts vga detection Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2227 --- src/hardware/vga_attr.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index ef91511a..b2010589 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -27,7 +27,11 @@ void VGA_ATTR_SetPalette(Bit8u index,Bit8u val) { else val=(val & 63) | (vga.attr.color_select & 0xc) << 4; VGA_DAC_CombineColor(index,val); } - +Bitu read_p3c0(Bitu port,Bitu iolen) { +//Wcharts + return 0x0; +} + void write_p3c0(Bitu port,Bitu val,Bitu iolen) { if (!vga.internal.attrindex) { attr(index)=val & 0x1F; @@ -188,6 +192,7 @@ Bitu read_p3c1(Bitu port,Bitu iolen) { void VGA_SetupAttr(void) { if (machine==MCH_VGA) { + IO_RegisterReadHandler(0x3c0,read_p3c0,IO_MB); IO_RegisterWriteHandler(0x3c0,write_p3c0,IO_MB); IO_RegisterReadHandler(0x3c1,read_p3c1,IO_MB); } From 0e0f29420279642b21b4f848ba214ef5feeee4d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 4 Jul 2005 20:20:19 +0000 Subject: [PATCH 2144/4131] better compatibility while in v86-mode (Strike Commander etc.) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2228 --- include/cpu.h | 4 ++- src/cpu/core_normal/prefix_0f.h | 6 ++-- src/cpu/cpu.cpp | 56 +++++++++++++++++++++++++-------- src/dos/dos_execute.cpp | 11 ++++--- 4 files changed, 57 insertions(+), 20 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index ac6b6489..01783145 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -63,8 +63,10 @@ void CPU_ARPL(Bitu & dest_sel,Bitu src_sel); void CPU_LAR(Bitu selector,Bitu & ar); void CPU_LSL(Bitu selector,Bitu & limit); -bool CPU_SET_CRX(Bitu cr,Bitu value); +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); void CPU_SMSW(Bitu & word); Bitu CPU_LMSW(Bitu word); diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index ca5c7d58..4b5103cf 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -128,7 +128,9 @@ Bitu which=(rm >> 3) & 7; if (rm >= 0xc0 ) { GetEArd; - *eard=CPU_GET_CRX(which); + Bit32u crx_value; + if (CPU_READ_CRX(which,crx_value)) RUNEXCEPTION(); + *eard=crx_value; } else { GetEAa; LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%d with non-register",which); @@ -153,7 +155,7 @@ Bitu which=(rm >> 3) & 7; if (rm >= 0xc0 ) { GetEArd; - if (CPU_SET_CRX(which,*eard)) RUNEXCEPTION(); + if (CPU_WRITE_CRX(which,*eard)) RUNEXCEPTION(); } else goto illegal_opcode; } break; diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 61e53db5..ea886505 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.70 2005-04-25 19:01:11 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.71 2005-07-04 20:20:18 c2woody Exp $ */ #include #include "dosbox.h" @@ -82,7 +82,7 @@ void CPU_Core_Dyn_X86_Init(void); } #elif defined(CPU_CHECK_EXCEPT) #define CPU_CHECK_COND(cond,msg,exc,sel) { \ - if (cond) { + if (cond) { \ CPU_Exception(exc,sel); \ return; \ } \ @@ -158,10 +158,14 @@ bool CPU_STI(void) { } bool CPU_POPF(Bitu use32) { - if ((reg_flags & FLAG_VM) && (GETFLAG(IOPL)!=FLAG_IOPL)) + if (cpu.pmode && GETFLAG(VM) && (GETFLAG(IOPL)!=FLAG_IOPL)) { + /* Not enough privileges to execute POPF */ return CPU_PrepareException(EXCEPTION_GP,0); - Bitu mask=cpu.cpl ? FMASK_NORMAL : FMASK_ALL; - if ((GETFLAG_IOPL0)) mask &= (~FLAG_IOPL); + if (cpu.pmode && !GETFLAG(VM) && (GETFLAG_IOPL #include @@ -131,7 +131,7 @@ bool DOS_Terminate(bool tsr) { /* Set the CS:IP stored in int 0x22 back on the stack */ mem_writew(SegPhys(ss)+reg_sp+0,RealOff(old22)); mem_writew(SegPhys(ss)+reg_sp+2,RealSeg(old22)); - mem_writew(SegPhys(ss)+reg_sp+4,0x200); //stack isn't preserved + mem_writew(SegPhys(ss)+reg_sp+4,reg_flags&(~FLAG_CF)); // Free memory owned by process if (!tsr) DOS_FreeProcessMemory(mempsp); DOS_UpdatePSPName(); @@ -376,10 +376,13 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { reg_sp-=6; mem_writew(SegPhys(ss)+reg_sp+0,RealOff(csip)); mem_writew(SegPhys(ss)+reg_sp+2,RealSeg(csip)); - mem_writew(SegPhys(ss)+reg_sp+4,0x200); + /* DOS starts programs with a RETF, so our IRET + should not modify the flags (e.g. IOPL in v86 mode) */ + mem_writew(SegPhys(ss)+reg_sp+4,reg_flags&(~FLAG_CF)); /* Setup the rest of the registers */ reg_ax=0;reg_si=0x100; - reg_cx=reg_dx=reg_bx=reg_di=reg_bp=0; + reg_cx=reg_dx=reg_bx=reg_di=0; + reg_bp=0x91c; /* DOS internal stack begin relict */ SegSet16(ds,pspseg);SegSet16(es,pspseg); #if C_DEBUG /* Started from debug.com, then set breakpoint at start */ From 7e56e5769429c6b33811c501adc24801d7af3eba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 5 Jul 2005 20:22:02 +0000 Subject: [PATCH 2145/4131] VCPI implementation; fix for Lemmings Chronicles+soundblaster Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2229 --- src/ints/ems.cpp | 492 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 486 insertions(+), 6 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 7025eba6..43b41eb7 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.39 2005-03-25 11:59:24 qbix79 Exp $ */ +/* $Id: ems.cpp,v 1.40 2005-07-05 20:22:02 c2woody Exp $ */ #include #include @@ -30,6 +30,8 @@ #include "inout.h" #include "dos_inc.h" #include "setup.h" +#include "support.h" +#include "cpu.h" #define EMM_PAGEFRAME 0xE000 #define EMM_PAGEFRAME4K ((EMM_PAGEFRAME*16)/4096) @@ -43,6 +45,10 @@ #define NULL_HANDLE 0xffff #define NULL_PAGE 0xffff +#define ENABLE_VCPI 1 +#define ENABLE_V86_STARTUP 0 + + /* EMM errors */ #define EMM_NO_ERROR 0x00 #define EMM_SOFT_MAL 0x80 @@ -94,6 +100,13 @@ struct EMM_Handle { static EMM_Handle emm_handles[EMM_MAX_HANDLES]; static EMM_Mapping emm_mappings[EMM_MAX_PHYS]; +static struct { + bool enabled; + Bit16u ems_handle; + Bitu pm_interface; + MemHandle private_area; + Bit8u pic1_remapping,pic2_remapping; +} vcpi ; struct MoveRegion { Bit32u bytes; @@ -198,7 +211,9 @@ static Bit8u EMM_ReleaseMemory(Bit16u handle) { static Bit8u EMM_SavePageMap(Bit16u handle) { /* Check for valid handle */ - if (handle>=EMM_MAX_HANDLES || emm_handles[handle].pages==NULL_HANDLE) return EMM_INVALID_HANDLE; + if (handle>=EMM_MAX_HANDLES || emm_handles[handle].pages==NULL_HANDLE) { + if (handle!=0) return EMM_INVALID_HANDLE; + } /* Check for previous save */ if (emm_handles[handle].saved_page_map) return EMM_PAGE_MAP_SAVED; /* Copy the mappings over */ @@ -220,7 +235,9 @@ static Bit8u EMM_RestoreMappingTable(void) { } static Bit8u EMM_RestorePageMap(Bit16u handle) { /* Check for valid handle */ - if (handle>=EMM_MAX_HANDLES || emm_handles[handle].pages==NULL_HANDLE) return EMM_INVALID_HANDLE; + if (handle>=EMM_MAX_HANDLES || emm_handles[handle].pages==NULL_HANDLE) { + if (handle!=0) return EMM_INVALID_HANDLE; + } /* Check for previous save */ if (!emm_handles[handle].saved_page_map) return EMM_INVALID_HANDLE; /* Restore the mappings */ @@ -585,8 +602,153 @@ static Bitu INT67_Handler(void) { }; break; case 0xDE: /* VCPI Functions */ - LOG(LOG_MISC,LOG_ERROR)("EMS:VCPI Call %2X not supported",reg_al); - reg_ah=EMM_FUNC_NOSUP; + if (!vcpi.enabled) { + LOG(LOG_MISC,LOG_ERROR)("EMS:VCPI Call %2X not supported",reg_al); + reg_ah=EMM_FUNC_NOSUP; + } else { + switch (reg_al) { + case 0x00: /* VCPI Installation Check */ + reg_ah=EMM_NO_ERROR; + reg_bx=0x100; + break; + case 0x01: /* VCPI Get Protected Mode Interface */ + /* Set up page table buffer */ + for (Bitu ct=0; ct<0xff; ct++) { + real_writeb(SegValue(es),reg_di+ct*4+0x00,0x67); // access bits + real_writew(SegValue(es),reg_di+ct*4+0x01,ct*0x10); // mapping + real_writeb(SegValue(es),reg_di+ct*4+0x03,0x00); + } + for (Bitu ct=0xff; ct<0x100; ct++) { + real_writeb(SegValue(es),reg_di+ct*4+0x00,0x67); // access bits + real_writew(SegValue(es),reg_di+ct*4+0x01,(ct-0xff)*0x10+0x1100); // mapping + real_writeb(SegValue(es),reg_di+ct*4+0x03,0x00); + } + reg_di+=0x800; // advance pointer by 0x200*4 + + /* Set up three descriptor table entries */ + real_writed(SegValue(ds),reg_si+0x00,0x8000ffff); // descriptor 1 (code segment) + real_writed(SegValue(ds),reg_si+0x04,0x00009a0c); // descriptor 1 + real_writed(SegValue(ds),reg_si+0x08,0x0000ffff); // descriptor 2 (data segment) + real_writed(SegValue(ds),reg_si+0x0c,0x00009200); // descriptor 2 + real_writed(SegValue(ds),reg_si+0x10,0x0000ffff); // descriptor 3 + real_writed(SegValue(ds),reg_si+0x14,0x00009200); // descriptor 3 + + reg_ebx=(vcpi.pm_interface&0xffff); + reg_ah=EMM_NO_ERROR; + break; + case 0x02: /* VCPI Maximum Physical Address */ + reg_edx=((MEM_TotalPages()*MEM_PAGESIZE)-1)&0xfffff000; + reg_ah=EMM_NO_ERROR; + break; + case 0x03: /* VCPI Get Number of Free Pages */ + reg_edx=MEM_FreeTotal(); + reg_ah=EMM_NO_ERROR; + break; + case 0x04: { /* VCPI Allocate one Page */ + MemHandle mem = MEM_AllocatePages(1,false); + if (mem) { + reg_edx=mem<<12; + reg_ah=EMM_NO_ERROR; + } else { + reg_ah=EMM_OUT_OF_LOG; + } + break; + } + case 0x05: /* VCPI Free Page */ + MEM_ReleasePages(reg_edx>>12); + reg_ah=EMM_NO_ERROR; + break; + case 0x06: { /* VCPI Get Physical Address of Page in 1st MB */ + if (((reg_cx<<8)>=EMM_PAGEFRAME) && ((reg_cx<<8)>12); + reg_ah=EMM_NO_ERROR; + break; + case 0xDE0C: { /* VCPI Switch from Protected Mode to V86 */ + reg_flags&=(~FLAG_IF); + + /* Flags need to be filled in, VM=true, IOPL=3 */ + mem_writed(SegPhys(ss) + (reg_esp & cpu.stack.mask)+0x10, 0x23002); + + /* Disable Paging */ + CPU_SET_CRX(0, CPU_GET_CRX(0)&0x7ffffff7); + CPU_SET_CRX(3, 0); + + PhysPt tbaddr=vcpi.private_area+0x0000+(0x10&0xfff8)+5; + Bit8u tb=mem_readb(tbaddr); + mem_writeb(tbaddr, tb&0xfd); + + /* Load descriptor table registers */ + CPU_LGDT(0xff, vcpi.private_area+0x0000); + CPU_LIDT(0x7ff, vcpi.private_area+0x2000); + CPU_LLDT(0x08); + CPU_LTR(0x10); + + reg_flags&=(~FLAG_NT); + reg_esp+=8; // skip interrupt return information + + /* Switch to v86-task */ + CPU_IRET(true,0); + } + break; + default: + LOG(LOG_MISC,LOG_WARN)("Unhandled VCPI-function %x in protected mode",reg_al); + break; + } + return CBRET_NONE; +} + +static Bitu V86_Monitor() { + /* Calculate which interrupt did occur */ + Bitu int_num=(mem_readw(SegPhys(ss)+(reg_esp & cpu.stack.mask))-0x2803); + + /* See if Exception 0x0d and not Interrupt 0x0d */ + if ((int_num==(0x0d*4)) && ((reg_sp&0xffff)!=0x1fda)) { + /* Protection violation during V86-execution, + needs intervention by monitor (depends on faulting opcode) */ + + reg_esp+=6; // skip ip of CALL and error code of EXCEPTION 0x0d + + /* Get adress of faulting instruction */ + Bit16u v86_cs=mem_readw(SegPhys(ss)+((reg_esp+4) & cpu.stack.mask)); + Bit16u v86_ip=mem_readw(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask)); + Bit8u v86_opcode=mem_readb((v86_cs<<4)+v86_ip); +// LOG_MSG("v86 monitor caught protection violation at %x:%x, opcode=%x",v86_cs,v86_ip,v86_opcode); + switch (v86_opcode) { + case 0x0f: // double byte opcode + v86_opcode=mem_readb((v86_cs<<4)+v86_ip+1); + switch (v86_opcode) { + case 0x20: { // mov reg,CRx + Bitu rm_val=mem_readb((v86_cs<<4)+v86_ip+2); + Bitu which=(rm_val >> 3) & 7; + if ((rm_val<0xc0) || (rm_val>=0xe8)) + E_Exit("Invalid opcode 0x0f 0x20 %x caused a protection fault!",rm_val); + Bit32u crx=CPU_GET_CRX(which); + switch (rm_val&3) { + case 0: reg_eax=crx; break; + case 1: reg_ecx=crx; break; + case 2: reg_edx=crx; break; + case 3: reg_ebx=crx; break; + case 4: reg_esp=crx; break; + case 5: reg_ebp=crx; break; + case 6: reg_esi=crx; break; + case 7: reg_edi=crx; break; + } + mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+3); + } + break; + case 0x22: { // mov CRx,reg + Bitu rm_val=mem_readb((v86_cs<<4)+v86_ip+2); + Bitu which=(rm_val >> 3) & 7; + if ((rm_val<0xc0) || (rm_val>=0xe8)) + E_Exit("Invalid opcode 0x0f 0x22 %x caused a protection fault!",rm_val); + Bit32u crx; + switch (rm_val&3) { + case 0: crx=reg_eax; break; + case 1: crx=reg_ecx; break; + case 2: crx=reg_edx; break; + case 3: crx=reg_ebx; break; + case 4: crx=reg_esp; break; + case 5: crx=reg_ebp; break; + case 6: crx=reg_esi; break; + case 7: crx=reg_edi; break; + } + if (which==0) crx|=1; // protection bit always on + CPU_SET_CRX(which,crx); + mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+3); + } + break; + default: + E_Exit("Unhandled opcode 0x0f %x caused a protection fault!",v86_opcode); + } + break; + case 0xe4: // IN AL,Ib + reg_al=IO_ReadB(mem_readb((v86_cs<<4)+v86_ip+1)); + mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+2); + break; + case 0xe5: // IN AX,Ib + reg_ax=IO_ReadW(mem_readb((v86_cs<<4)+v86_ip+1)); + mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+2); + break; + case 0xe6: // OUT Ib,AL + IO_WriteB(mem_readb((v86_cs<<4)+v86_ip+1),reg_al); + mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+2); + break; + case 0xe7: // OUT Ib,AX + IO_WriteW(mem_readb((v86_cs<<4)+v86_ip+1),reg_ax); + mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+2); + break; + case 0xec: // IN AL,DX + reg_al=IO_ReadB(reg_dx); + mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+1); + break; + case 0xed: // IN AX,DX + reg_ax=IO_ReadW(reg_dx); + mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+1); + break; + case 0xee: // OUT DX,AL + IO_WriteB(reg_dx,reg_al); + mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+1); + break; + case 0xef: // OUT DX,AX + IO_WriteW(reg_dx,reg_ax); + mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+1); + break; + case 0xf0: // LOCK prefix + mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+1); + break; + case 0xf4: // HLT + reg_flags|=FLAG_IF; + CPU_HLT(reg_eip); + mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+1); + break; + default: + E_Exit("Unhandled opcode %x caused a protection fault!",v86_opcode); + } + return CBRET_NONE; + } + + /* Get address to interrupt handler */ + Bit16u vint_vector_seg=mem_readw(SegValue(ds)+int_num+2); + Bit16u vint_vector_ofs=mem_readw(int_num); + if (reg_sp!=0x1fda) reg_esp+=(2+3*4); // Interrupt from within protected mode + else reg_esp+=2; + + /* Read entries that were pushed onto the stack by the interrupt */ + Bit16u return_ip=mem_readw(SegPhys(ss)+(reg_esp & cpu.stack.mask)); + Bit16u return_cs=mem_readw(SegPhys(ss)+((reg_esp+4) & cpu.stack.mask)); + Bit32u return_eflags=mem_readd(SegPhys(ss)+((reg_esp+8) & cpu.stack.mask)); + + /* Modify stack to call v86-interrupt handler */ + mem_writed(SegPhys(ss)+(reg_esp & cpu.stack.mask),vint_vector_ofs); + mem_writed(SegPhys(ss)+((reg_esp+4) & cpu.stack.mask),vint_vector_seg); + mem_writed(SegPhys(ss)+((reg_esp+8) & cpu.stack.mask),return_eflags&(~(FLAG_IF|FLAG_TF))); + + /* Adjust SP of v86-stack */ + Bit16u v86_ss=mem_readw(SegPhys(ss)+((reg_esp+0x10) & cpu.stack.mask)); + Bit16u v86_sp=mem_readw(SegPhys(ss)+((reg_esp+0x0c) & cpu.stack.mask))-6; + mem_writew(SegPhys(ss)+((reg_esp+0x0c) & cpu.stack.mask),v86_sp); + + /* Return to original code after v86-interrupt handler */ + mem_writew((v86_ss<<4)+v86_sp+0,return_ip); + mem_writew((v86_ss<<4)+v86_sp+2,return_cs); + mem_writew((v86_ss<<4)+v86_sp+4,(Bit16u)(return_eflags&0xffff)); + return CBRET_NONE; +} + +static void SetupVCPI() { + vcpi.enabled=true; + + vcpi.pic1_remapping=0x08; // master PIC base + vcpi.pic2_remapping=0x70; // slave PIC base + + /* Allocate one EMS-page for private VCPI-data in memory beyond 1MB */ + EMM_AllocateMemory(1,vcpi.ems_handle); + vcpi.private_area=emm_handles[vcpi.ems_handle].mem<<12; + + /* GDT */ + mem_writed(vcpi.private_area+0x0000,0x00000000); // descriptor 0 + mem_writed(vcpi.private_area+0x0004,0x00000000); // descriptor 0 + + Bit32u ldt_address=(vcpi.private_area+0x1000); + Bit16u ldt_limit=0xff; + Bit32u ldt_desc_part=((ldt_address&0xffff)<<16)|ldt_limit; + mem_writed(vcpi.private_area+0x0008,ldt_desc_part); // descriptor 1 (LDT) + ldt_desc_part=((ldt_address&0xff0000)>>16)|(ldt_address&0xff000000)|0x8200; + mem_writed(vcpi.private_area+0x000c,ldt_desc_part); // descriptor 1 + + Bit32u tss_address=(vcpi.private_area+0x3000); + Bit32u tss_desc_part=((tss_address&0xffff)<<16)|(0x0068+0x200); + mem_writed(vcpi.private_area+0x0010,tss_desc_part); // descriptor 2 (TSS) + tss_desc_part=((tss_address&0xff0000)>>16)|(tss_address&0xff000000)|0x8900; + mem_writed(vcpi.private_area+0x0014,tss_desc_part); // descriptor 2 + + /* LDT */ + mem_writed(vcpi.private_area+0x1000,0x00000000); // descriptor 0 + mem_writed(vcpi.private_area+0x1004,0x00000000); // descriptor 0 + Bit32u cs_desc_part=((vcpi.private_area&0xffff)<<16)|0xffff; + mem_writed(vcpi.private_area+0x1008,cs_desc_part); // descriptor 1 (code) + cs_desc_part=((vcpi.private_area&0xff0000)>>16)|(vcpi.private_area&0xff000000)|0x9a00; + mem_writed(vcpi.private_area+0x100c,cs_desc_part); // descriptor 1 + Bit32u ds_desc_part=((vcpi.private_area&0xffff)<<16)|0xffff; + mem_writed(vcpi.private_area+0x1010,ds_desc_part); // descriptor 2 (data) + ds_desc_part=((vcpi.private_area&0xff0000)>>16)|(vcpi.private_area&0xff000000)|0x9200; + mem_writed(vcpi.private_area+0x1014,ds_desc_part); // descriptor 2 + + /* IDT setup */ + for (Bitu int_ct=0; int_ct<0x100; int_ct++) { + /* build a CALL NEAR V86MON, the value of IP pushed by the + CALL is used to identify the interrupt number */ + mem_writeb(vcpi.private_area+0x2800+int_ct*4+0,0xe8); // call + mem_writew(vcpi.private_area+0x2800+int_ct*4+1,0x05fd-(int_ct*4)); + mem_writeb(vcpi.private_area+0x2800+int_ct*4+3,0xcf); // iret (dummy) + + /* put a Gate-Descriptor into the IDT */ + mem_writed(vcpi.private_area+0x2000+int_ct*8+0,0x000c0000|(0x2800+int_ct*4)); + mem_writed(vcpi.private_area+0x2000+int_ct*8+4,0x0000ee00); + } + + /* TSS */ + for (Bitu tse_ct=0; tse_ct<0x68+0x200; tse_ct++) { + /* clear the TSS as most entries are not used here */ + mem_writeb(vcpi.private_area+0x3000,0); + } + /* Set up the ring0-stack */ + mem_writed(vcpi.private_area+0x3004,0x00002000); // esp + mem_writed(vcpi.private_area+0x3008,0x00000014); // ss + + mem_writed(vcpi.private_area+0x3066,0x0068); // io-map base (map follows, all zero) +} + static Bitu INT4B_Handler() { switch (reg_ah) { case 0x81: @@ -616,7 +1035,7 @@ private: * stored 32 bytes.*/ static Bit16u emsnameseg; RealPt old4b_pointer,old67_pointer; - CALLBACK_HandlerObject call_vdma,int67; + CALLBACK_HandlerObject call_vdma,int67,call_vcpi,call_v86mon; public: EMS(Section* configuration):Module_base(configuration){ @@ -624,6 +1043,8 @@ public: /* Virtual DMA interrupt callback */ call_vdma.Install(&INT4B_Handler,CB_IRET,"Int 4b vdma"); call_vdma.Set_RealVec(0x4b); + + vcpi.enabled=false; Section_prop * section=static_cast(configuration); if (!section->Get_bool("ems")) return; @@ -656,6 +1077,51 @@ public: emm_mappings[i].page=NULL_PAGE; emm_mappings[i].handle=NULL_HANDLE; } + + if (!ENABLE_VCPI) return; + + /* Install a callback that handles VCPI-requests in protected mode requests */ + call_vcpi.Install(&VCPI_PM_Handler,CB_RETF,"VCPI PM"); + vcpi.pm_interface=(call_vcpi.Get_callback())<<4; + + /* Use IRETD instead of IRET for this protected mode callback */ + mem_writeb(CB_BASE+vcpi.pm_interface+4,(Bit8u)0x66); + mem_writeb(CB_BASE+vcpi.pm_interface+5,(Bit8u)0xCB); //A IRETD Instruction + + /* Initialize private data area and set up descriptor tables */ + SetupVCPI(); + + /* Install v86-callback that handles interrupts occuring + in v86 mode, including protection fault exceptions */ + call_v86mon.Install(&V86_Monitor,CB_IRET,"V86 Monitor"); + + mem_writeb(vcpi.private_area+0x2e00,(Bit8u)0xFE); //GRP 4 + mem_writeb(vcpi.private_area+0x2e01,(Bit8u)0x38); //Extra Callback instruction + mem_writew(vcpi.private_area+0x2e02,call_v86mon.Get_callback()); //The immediate word + mem_writeb(vcpi.private_area+0x2e04,(Bit8u)0x66); + mem_writeb(vcpi.private_area+0x2e05,(Bit8u)0xCF); //A IRETD Instruction + + /* Testcode only, starts up dosbox in v86-mode */ + if (ENABLE_V86_STARTUP) { + /* Prepare V86-task */ + CPU_SET_CRX(0, 1); + CPU_LGDT(0xff, vcpi.private_area+0x0000); + CPU_LIDT(0x7ff, vcpi.private_area+0x2000); + CPU_LLDT(0x08); + CPU_LTR(0x10); + + CPU_Push32(SegValue(gs)); + CPU_Push32(SegValue(fs)); + CPU_Push32(SegValue(ds)); + CPU_Push32(SegValue(es)); + CPU_Push32(SegValue(ss)); + CPU_Push32(0x23002); + CPU_Push32(SegValue(cs)); + CPU_Push32(reg_eip&0xffff); + /* Switch to V86-mode */ + cpu.cpl=0; + CPU_IRET(true,0); + } } ~EMS() { @@ -674,6 +1140,20 @@ public: RealSetVec(0x67,old67_pointer); /* Clear handle and page tables */ //TODO + + if (!ENABLE_VCPI) return; + + /* Free private data area in expanded memory */ + EMM_ReleaseMemory(vcpi.ems_handle); + + if (cpu.pmode && GETFLAG(VM)) { + /* Switch back to real mode if in v86-mode */ + CPU_SET_CRX(0, 0); + CPU_SET_CRX(3, 0); + reg_flags&=(~(FLAG_IOPL|FLAG_VM)); + CPU_LIDT(0x3ff, 0); + cpu.cpl=0; + } } }; From 46b9b106a4fc65ed81d4cdb200f17dcd717561e8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 7 Jul 2005 19:53:02 +0000 Subject: [PATCH 2146/4131] Increased MAX_HANDLES to 200 (for the Patriot) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2230 --- src/ints/ems.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 43b41eb7..f328f2db 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.40 2005-07-05 20:22:02 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.41 2005-07-07 19:53:02 qbix79 Exp $ */ #include #include @@ -35,7 +35,7 @@ #define EMM_PAGEFRAME 0xE000 #define EMM_PAGEFRAME4K ((EMM_PAGEFRAME*16)/4096) -#define EMM_MAX_HANDLES 100 /* 255 Max */ +#define EMM_MAX_HANDLES 200 /* 255 Max */ #define EMM_PAGE_SIZE (16*1024U) #define EMM_MAX_PAGES (32 * 1024 / 16 ) #define EMM_MAX_PHYS 4 /* 4 16kb pages in pageframe */ From 449475435cb0bdb69e74cf630c3746c33af73681 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 8 Jul 2005 13:39:25 +0000 Subject: [PATCH 2147/4131] added patch 1234528 from kippesoep Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2231 --- src/ints/int10_pal.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 39a62333..0dda63f3 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -75,6 +75,7 @@ void INT10_GetSinglePaletteRegister(Bit8u reg,Bit8u * val) { IO_Read(VGAREG_ACTL_RESET); IO_Write(VGAREG_ACTL_ADDRESS,reg+32); *val=IO_Read(VGAREG_ACTL_READ_DATA); + IO_Write(VGAREG_ACTL_WRITE_DATA,*val); } } @@ -82,6 +83,7 @@ void INT10_GetOverscanBorderColor(Bit8u * val) { IO_Read(VGAREG_ACTL_RESET); IO_Write(VGAREG_ACTL_ADDRESS,0x11+32); *val=IO_Read(VGAREG_ACTL_READ_DATA); + IO_Write(VGAREG_ACTL_WRITE_DATA,*val); } void INT10_GetAllPaletteRegisters(PhysPt data) { @@ -136,9 +138,10 @@ void INT10_SelectDACPage(Bit8u function,Bit8u mode) { if (!function) { //Select paging mode if (mode) old10|=0x80; else old10&=0x7f; - IO_Write(VGAREG_ACTL_ADDRESS,0x10); + //IO_Write(VGAREG_ACTL_ADDRESS,0x10); IO_Write(VGAREG_ACTL_WRITE_DATA,old10); } else { //Select page + IO_Write(VGAREG_ACTL_WRITE_DATA,old10); if (!(old10 & 0x80)) mode<<=2; mode&=0xf; IO_Write(VGAREG_ACTL_ADDRESS,0x14); @@ -151,9 +154,11 @@ void INT10_GetDACPage(Bit8u* mode,Bit8u* page) { IO_Read(VGAREG_ACTL_RESET); IO_Write(VGAREG_ACTL_ADDRESS,0x10); Bit8u reg10=IO_Read(VGAREG_ACTL_READ_DATA); + IO_Write(VGAREG_ACTL_WRITE_DATA,reg10); *mode=(reg10&0x80)?0x01:0x00; IO_Write(VGAREG_ACTL_ADDRESS,0x14); *page=IO_Read(VGAREG_ACTL_READ_DATA); + IO_Write(VGAREG_ACTL_WRITE_DATA,*page); if(*mode) { *page&=0xf; } else { From d9552a7bae52f76f022cfd70353dab1a09c886d5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 8 Jul 2005 13:48:58 +0000 Subject: [PATCH 2148/4131] int 10 call 8 now supported in non-text mode as well Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2232 --- src/ints/int10_char.cpp | 81 +++++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 19 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index aed0030c..92b1fa44 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.34 2005-05-04 19:33:46 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.35 2005-07-08 13:48:58 qbix79 Exp $ */ /* Character displaying moving functions */ @@ -369,29 +369,73 @@ void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page) { } } +void ReadCharAttr(Bit16u col,Bit16u row,Bit8u page,Bit16u * result) { + /* Externally used by the mouse routine */ + PhysPt fontdata; + Bitu x,y; + Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); + bool split_chr = false; + switch (CurMode->type) { + case M_TEXT: + { + // Compute the address + Bit16u address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); + address+=(row*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)+col)*2; + // read the char + PhysPt where = CurMode->pstart+address; + *result=mem_readw(where); + } + return; + case M_CGA4: + case M_CGA2: + case M_TANDY16: + split_chr = true; + /* Fallthrough */ + default: /* EGA/VGA don't have a split font-table */ + for(Bit16u chr=0;chr <= 255 ;chr++) { + if (!split_chr || (chr<128)) fontdata = Real2Phys(RealGetVec(0x43))+chr*cheight; + else fontdata = Real2Phys(RealGetVec(0x1F))+(chr-128)*cheight; + x=8*col; + y=cheight*row; + bool error=false; + for (Bit8u h=0;h>=1; + } + y++; + if(bitline != vidline){ + /* It's not character 'chr', move on to the next */ + error = true; + break; + } + } + if(!error){ + /* We found it */ + *result = chr; + return; + } + } + LOG(LOG_INT10,LOG_ERROR)("ReadChar didn't find character"); + *result = 0; + break; + } +} void INT10_ReadCharAttr(Bit16u * result,Bit8u page) { if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); - - // Compute the address - Bit16u address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); - address+=(cur_row*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)+cur_col)*2; - // Read the char - PhysPt where = CurMode->pstart+address; - *result=mem_readw(where); + ReadCharAttr(cur_col,cur_row,page,result); } - -void ReadCharAttr(Bit16u col,Bit16u row,Bit8u page,Bit16u * result) { - /* Used by the mouse */ - Bit16u address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); - address+=(row*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)+col)*2; - // Read the char - PhysPt where = CurMode->pstart+address; - *result=mem_readw(where); -} - void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useattr) { /* Externally used by the mouse routine */ PhysPt fontdata; @@ -559,4 +603,3 @@ void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,B INT10_SetCursorPos(cur_row,cur_col,page); } } - From 7ab3a9f466570bb6b37377f9b910ec09a559bb6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 9 Jul 2005 13:07:48 +0000 Subject: [PATCH 2149/4131] crX-exceptions for full core Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2233 --- src/cpu/core_full/op.h | 6 +++--- src/cpu/cpu.cpp | 14 ++++++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index bed42c16..410db642 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -442,17 +442,17 @@ switch (inst.code.op) { } case 6: /* LMSW */ FillFlags(); - CPU_LMSW(inst.op1.w); + if (CPU_LMSW(inst.op1.w)) RunException(); goto nextopcode; default: LOG(LOG_CPU,LOG_ERROR)("Group 7 Illegal subfunction %X",inst.rm_index); } break; case O_M_CRx_Rd: - CPU_SET_CRX(inst.rm_index,inst.op1.d); + if (CPU_WRITE_CRX(inst.rm_index,inst.op1.d)) RunException(); break; case O_M_Rd_CRx: - inst.op1.d=CPU_GET_CRX(inst.rm_index); + if (CPU_READ_CRX(inst.rm_index,inst.op1.d)) RunException(); break; case O_M_DRx_Rd: // LOG(LOG_CPU,LOG_NORMAL)("MOV DR%d,%X",inst.rm_index,inst.op1.d); diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index ea886505..b3fb3b44 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.71 2005-07-04 20:20:18 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.72 2005-07-09 13:07:48 c2woody Exp $ */ #include #include "dosbox.h" @@ -52,6 +52,7 @@ void CPU_Core_Simple_Init(void); void CPU_Core_Dyn_X86_Init(void); +#define EXCEPTION_UD 6 #define EXCEPTION_TS 10 #define EXCEPTION_NP 11 #define EXCEPTION_SS 12 @@ -1430,8 +1431,10 @@ void CPU_SET_CRX(Bitu cr,Bitu value) { } bool CPU_WRITE_CRX(Bitu cr,Bitu value) { - if (cpu.pmode && GETFLAG(VM)) return CPU_PrepareException(EXCEPTION_GP,0); - else CPU_SET_CRX(cr,value); + /* Check if privileged to access control registers */ + if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); + if ((cr==1) || (cr>4)) return CPU_PrepareException(EXCEPTION_UD,0); + CPU_SET_CRX(cr,value); return false; } @@ -1451,7 +1454,9 @@ Bitu CPU_GET_CRX(Bitu cr) { } bool CPU_READ_CRX(Bitu cr,Bit32u & retvalue) { - if (cpu.pmode && GETFLAG(VM)) return CPU_PrepareException(EXCEPTION_GP,0); + /* Check if privileged to access control registers */ + if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); + if ((cr==1) || (cr>4)) return CPU_PrepareException(EXCEPTION_UD,0); retvalue=CPU_GET_CRX(cr); return false; } @@ -1462,6 +1467,7 @@ void CPU_SMSW(Bitu & word) { } Bitu CPU_LMSW(Bitu word) { + if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); word&=0xf; if (cpu.cr0 & 1) word|=1; word|=(cpu.cr0&0xfffffff0); From 30c5c551f41623cc2b893d37b8d1366044dd9c3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 10 Jul 2005 20:29:14 +0000 Subject: [PATCH 2150/4131] CMscdex::GetDefaultBuffer returns a PhysPt (fixes LBA cd-version) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2234 --- src/dos/dos_mscdex.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index da648e22..73b0b74a 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.30 2005-06-23 20:13:58 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.31 2005-07-10 20:29:14 c2woody Exp $ */ #include #include @@ -309,7 +309,7 @@ PhysPt CMscdex::GetDefaultBuffer(void) Bit16u size = 128; //Size in block is size in pages ? defaultBuffer = DOS_GetMemory(size); }; - return defaultBuffer; + return PhysMake(defaultBuffer,0); }; void CMscdex::GetDriverInfo (PhysPt data) From 07467e8e7cd19a7ea156b8a0a0ee2b3be7cd2e17 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Jul 2005 19:10:16 +0000 Subject: [PATCH 2151/4131] Add patch 1235272 by kippesoep. "Fixes for Tandy graphics artefacts" Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2235 --- src/ints/int10.h | 3 +++ src/ints/int10_modes.cpp | 1 + src/ints/int10_pal.cpp | 53 +++++++++++++++++++++++++++++----------- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/ints/int10.h b/src/ints/int10.h index 4c861b17..2db43333 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -78,6 +78,9 @@ #define VGAREG_MDA_WRITE_FEATURE_CTL 0x3ba #define VGAREG_VGA_WRITE_FEATURE_CTL 0x3da #define VGAREG_ACTL_RESET 0x3da +#define VGAREG_TDY_RESET 0x3da +#define VGAREG_TDY_ADDRESS 0x3da +#define VGAREG_TDY_DATA 0x3de #define VGAREG_MDA_MODECTL 0x3b8 #define VGAREG_CGA_MODECTL 0x3d8 diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index e06ad413..7b8d79ec 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -172,6 +172,7 @@ static void FinishSetMode(bool clearmem) { switch (CurMode->type) { case M_CGA4: case M_CGA2: + case M_TANDY16: for (i=0;i<16*1024;i++) { real_writew(0xb800,i*2,0x0000); } diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 0dda63f3..10635e80 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -24,12 +24,21 @@ #define ACTL_MAX_REG 0x14 void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val) { - if(reg<=ACTL_MAX_REG) { - IO_Read(VGAREG_ACTL_RESET); - IO_Write(VGAREG_ACTL_ADDRESS,reg); - IO_Write(VGAREG_ACTL_WRITE_DATA,val); + switch (machine) { + case MCH_TANDY: + IO_Read(VGAREG_TDY_RESET); + IO_Write(VGAREG_TDY_ADDRESS,reg+0x10); + IO_Write(VGAREG_TDY_DATA,val); + break; + case MCH_VGA: + if(reg<=ACTL_MAX_REG) { + IO_Read(VGAREG_ACTL_RESET); + IO_Write(VGAREG_ACTL_ADDRESS,reg); + IO_Write(VGAREG_ACTL_WRITE_DATA,val); + } + IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette + break; } - IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette } @@ -41,17 +50,33 @@ void INT10_SetOverscanBorderColor(Bit8u val) { } void INT10_SetAllPaletteRegisters(PhysPt data) { - IO_Read(VGAREG_ACTL_RESET); - // First the colors - for(Bit8u i=0;i<0x10;i++) { - IO_Write(VGAREG_ACTL_ADDRESS,i); + switch (machine) { + case MCH_TANDY: + IO_Read(VGAREG_TDY_RESET); + // First the colors + for(Bit8u i=0;i<0x10;i++) { + IO_Write(VGAREG_TDY_ADDRESS,i+0x10); + IO_Write(VGAREG_TDY_DATA,mem_readb(data)); + data++; + } + // Then the border + IO_Write(VGAREG_TDY_ADDRESS,0x02); + IO_Write(VGAREG_TDY_DATA,mem_readb(data)); + break; + case MCH_VGA: + IO_Read(VGAREG_ACTL_RESET); + // First the colors + for(Bit8u i=0;i<0x10;i++) { + IO_Write(VGAREG_ACTL_ADDRESS,i); + IO_Write(VGAREG_ACTL_WRITE_DATA,mem_readb(data)); + data++; + } + // Then the border + IO_Write(VGAREG_ACTL_ADDRESS,0x11); IO_Write(VGAREG_ACTL_WRITE_DATA,mem_readb(data)); - data++; + IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette + break; } - // Then the border - IO_Write(VGAREG_ACTL_ADDRESS,0x11); - IO_Write(VGAREG_ACTL_WRITE_DATA,mem_readb(data)); - IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette } void INT10_ToggleBlinkingBit(Bit8u state) { From 876fc2cb3ad77a7a393d6be9e480d92889b1b9a3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 12 Jul 2005 18:59:31 +0000 Subject: [PATCH 2152/4131] Disable a few warnings. Added a check for images over 1 mb.(Kippesoep) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2236 --- src/dos/dos_execute.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index ba686254..abf3699d 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.46 2005-07-04 20:20:19 c2woody Exp $ */ +/* $Id: dos_execute.cpp,v 1.47 2005-07-12 18:59:31 qbix79 Exp $ */ #include #include @@ -252,6 +252,9 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { if (len 1 MB"); + head.pages&=0x07ff; headersize = head.headersize*16; imagesize = head.pages*512-headersize; if (imagesize+headersize<512) imagesize = 512-headersize; @@ -299,13 +302,13 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { while (imagesize>0x7FFF) { readsize=0x8000;DOS_ReadFile(fhandle,loadbuf,&readsize); MEM_BlockWrite(loadaddress,loadbuf,readsize); - if (readsize!=0x8000) LOG(LOG_EXEC,LOG_NORMAL)("Illegal header"); +// if (readsize!=0x8000) LOG(LOG_EXEC,LOG_NORMAL)("Illegal header"); loadaddress+=0x8000;imagesize-=0x8000; } if (imagesize>0) { readsize=(Bit16u)imagesize;DOS_ReadFile(fhandle,loadbuf,&readsize); MEM_BlockWrite(loadaddress,loadbuf,readsize); - if (readsize!=imagesize) LOG(LOG_EXEC,LOG_NORMAL)("Illegal header"); +// if (readsize!=imagesize) LOG(LOG_EXEC,LOG_NORMAL)("Illegal header"); } /* Relocate the exe image */ Bit16u relocate; @@ -410,9 +413,3 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { } return false; } - - - - - - From 56a46702a80b55ed077d9e6db45c345aa9f33b90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 13 Jul 2005 21:07:00 +0000 Subject: [PATCH 2153/4131] correcting page fault condition for unprivileged access Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2237 --- src/cpu/paging.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 92008efa..73fc2cc5 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -172,32 +172,36 @@ public: table.load=phys_readd(table_addr); if (!table.block.p) { LOG(LOG_PAGING,LOG_NORMAL)("NP Table"); - PAGING_PageFault(lin_addr,table_addr,false,0); // read fault + PAGING_PageFault(lin_addr,table_addr,false,writing?0x02:0x00); table.load=phys_readd(table_addr); if (!table.block.p) E_Exit("Pagefault didn't correct table"); } - table.block.a=1; //Set access - phys_writed(table_addr,table.load); + if (!table.block.a) { + table.block.a=1; //Set access + phys_writed(table_addr,table.load); + } X86PageEntry entry; Bitu entry_addr=(table.block.base<<12)+t_index*4; entry.load=phys_readd(entry_addr); if (!entry.block.p) { // LOG(LOG_PAGING,LOG_NORMAL)("NP Page"); - PAGING_PageFault(lin_addr,entry_addr,false,0); + PAGING_PageFault(lin_addr,entry_addr,false,writing?0x02:0x00); entry.load=phys_readd(entry_addr); if (!entry.block.p) E_Exit("Pagefault didn't correct page"); } - entry.block.a=1; //Set access if (cpu.cpl==3) { - if ((entry.block.us==0) || (table.block.us==0) || (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { + if ((entry.block.us==0) || (table.block.us==0) && (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); - PAGING_PageFault(lin_addr,entry_addr,writing,0x05); + PAGING_PageFault(lin_addr,entry_addr,writing,0x05 | (writing?0x02:0x00)); } } - entry.block.d=1; //Set dirty - phys_writed(entry_addr,entry.load); + if ((!entry.block.a) || (!entry.block.d)) { + entry.block.a=1; //Set access + entry.block.d=1; //Set dirty + phys_writed(entry_addr,entry.load); + } phys_page=entry.block.base; } else { if (lin_page Date: Fri, 15 Jul 2005 15:23:22 +0000 Subject: [PATCH 2154/4131] Fixed issues with files not showing up in the cache. This was caused by the fact that ExpandName was used instead of GetExpandName. The former modifies the name it's called with.(HunterZ Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2238 --- src/dos/drive_local.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index ff11d041..abe736c0 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.58 2005-06-15 17:47:26 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.59 2005-07-15 15:23:22 qbix79 Exp $ */ #include #include @@ -53,18 +53,18 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) { strcpy(newname,basedir); strcat(newname,name); CROSS_FILENAME(newname); - dirCache.ExpandName(newname); + char* temp_name = dirCache.GetExpandName(newname); //Can only be used in till a new drive_cache action is preformed */ /* Test if file exists (so we need to truncate it). don't add to dirCache then */ bool existing_file=false; - FILE * test=fopen(newname,"rb+"); + FILE * test=fopen(temp_name,"rb+"); if(test) { fclose(test); existing_file=true; } - FILE * hand=fopen(newname,"wb+"); + FILE * hand=fopen(temp_name,"wb+"); if (!hand){ LOG_MSG("Warning: file creation failed: %s",newname); return false; From 3429a18dc45194b01854aed3fbac970c824ea925 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 17 Jul 2005 20:29:46 +0000 Subject: [PATCH 2155/4131] Added Patch 1239770 from cyberwalker "Patch for RTCC to report correct time format" Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2239 --- src/hardware/cmos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 7bd63844..c7ade821 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -281,7 +281,7 @@ public: cmos.reg=0xa; cmos_writereg(0x71,0x26,1); cmos.reg=0xb; - cmos_writereg(0x71,0,1); + cmos_writereg(0x71,0x2,1); //Struct tm *loctime is of 24 hour format, /* Fill in extended memory size */ Bitu exsize=(MEM_TotalPages()*4)-1024; cmos.regs[0x17]=(Bit8u)exsize; From c7c2ee5d5ad215e47bd6e06a73e32a6bb0dd81fa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 19 Jul 2005 19:45:33 +0000 Subject: [PATCH 2156/4131] Add patch 1239754 from Moe. This patches fixes a few crashes by checking the SDL_SetMode return value and it changes strncopy to a safe_strncopy which adds a 0 to each string copied Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2240 --- include/support.h | 2 ++ src/debug/debug.cpp | 6 +++--- src/dos/cdrom_aspi_win32.cpp | 5 ++--- src/dos/cdrom_image.cpp | 10 +++++----- src/dos/cdrom_ioctl_linux.cpp | 5 +++-- src/dos/dos_programs.cpp | 8 ++++---- src/dos/drive_cache.cpp | 12 +++++------- src/dos/drive_iso.cpp | 7 +++---- src/gui/midi_alsa.h | 4 ++-- src/gui/midi_oss.h | 2 +- src/gui/sdl_mapper.cpp | 5 +++-- src/gui/sdlmain.cpp | 23 +++++++++++++++++++---- src/hardware/mixer.cpp | 4 ++-- src/misc/setup.cpp | 4 ++-- 14 files changed, 56 insertions(+), 41 deletions(-) diff --git a/include/support.h b/include/support.h index 87d910df..704cc105 100644 --- a/include/support.h +++ b/include/support.h @@ -34,6 +34,8 @@ //#define nocasestrcmp(a,b) stricmp(a,b) #endif +#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) + #ifdef HAVE_STRINGS_H #include #endif diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 65e8503c..57119421 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.63 2005-04-18 18:46:27 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.64 2005-07-19 19:45:15 qbix79 Exp $ */ #include #include @@ -175,7 +175,7 @@ bool GetDescriptorInfo(char* selname, char* out1, char* out2) class CDebugVar { public: - CDebugVar(char* _name, PhysPt _adr) { adr=_adr; (strlen(name)<15)?strcpy(name,_name):strncpy(name,_name,15); name[15]=0; }; + CDebugVar(char* _name, PhysPt _adr) { adr=_adr; safe_strncpy(name,_name,16); }; char* GetName(void) { return name; }; PhysPt GetAdr (void) { return adr; }; @@ -1673,7 +1673,7 @@ public: char filename[128]; char args[256]; cmd->FindCommand(1,temp_line); - strncpy(filename,temp_line.c_str(),128); + safe_strncpy(filename,temp_line.c_str(),128); // Read commandline Bit16u i =2; bool ok = false; diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index 87861f31..ca8360f1 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_aspi_win32.cpp,v 1.13 2005-02-10 10:20:50 qbix79 Exp $ */ +/* $Id: cdrom_aspi_win32.cpp,v 1.14 2005-07-19 19:45:16 qbix79 Exp $ */ #if defined (WIN32) @@ -219,8 +219,7 @@ bool CDROM_Interface_Aspi::GetVendor(BYTE HA_num, BYTE SCSI_Id, BYTE SCSI_Lun, c strcpy (szBuffer, "error" ); return false; } else { - strncpy(szBuffer,szBuffer+8,25); - szBuffer[25] = 0; + safe_strncpy(szBuffer,szBuffer+8,26); int len = strlen(szBuffer); for (int i=0; i #include @@ -29,6 +29,7 @@ #include #include "cdrom.h" #include "drives.h" +#include "support.h" #if !defined(WIN32) #include @@ -399,8 +400,7 @@ static string dirname(const char * file) { else { int len = (int)(sep - file); char tmp[MAX_FILENAME_LENGTH]; - strncpy(tmp, file, len); - tmp[len] = '\0'; + safe_strncpy(tmp, file, len+1); return tmp; } } @@ -417,7 +417,7 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) bool success; bool canAddTrack = false; char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument - strncpy(tmp, cuefile, MAX_FILENAME_LENGTH); + safe_strncpy(tmp, cuefile, MAX_FILENAME_LENGTH); string pathname(dirname(tmp)); ifstream in; in.open(cuefile, ios::in); @@ -595,7 +595,7 @@ bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) // finally check if file is in a dosbox local drive char fullname[CROSS_LEN]; char tmp[CROSS_LEN]; - strncpy(tmp, filename.c_str(), CROSS_LEN); + safe_strncpy(tmp, filename.c_str(), CROSS_LEN); Bit8u drive; if (!DOS_MakeName(tmp, fullname, &drive)) return false; diff --git a/src/dos/cdrom_ioctl_linux.cpp b/src/dos/cdrom_ioctl_linux.cpp index 4aacb3ed..6a492aa0 100644 --- a/src/dos/cdrom_ioctl_linux.cpp +++ b/src/dos/cdrom_ioctl_linux.cpp @@ -19,6 +19,7 @@ #include #include "cdrom.h" +#include "support.h" #if defined (LINUX) #include @@ -45,7 +46,7 @@ bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc) if (ret > 0) { attr = 0; - strncpy(upc, (char*)cdrom_mcn.medium_catalog_number, 14); + safe_strncpy(upc, (char*)cdrom_mcn.medium_catalog_number, 14); } return (ret > 0); @@ -86,7 +87,7 @@ bool CDROM_Interface_Ioctl::SetDevice(char* path, int forceCD) if (success) { const char* tmp = SDL_CDName(forceCD); - if (tmp) strncpy(device_name, tmp, 512); + if (tmp) safe_strncpy(device_name, tmp, 512); else success = false; } diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 6e73336c..6f9339a6 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.36 2005-04-06 20:48:14 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.37 2005-07-19 19:45:16 qbix79 Exp $ */ #include #include @@ -422,7 +422,7 @@ void LOADFIX::Run(void) if (cmd->FindCommand(commandNr++,temp_line)) { // get Filename char filename[128]; - strncpy(filename,temp_line.c_str(),128); + safe_strncpy(filename,temp_line.c_str(),128); // Setup commandline bool ok; char args[256]; @@ -570,10 +570,10 @@ public: // convert dosbox filename to system filename char fullname[CROSS_LEN]; char tmp[CROSS_LEN]; - strncpy(tmp, temp_line.c_str(), CROSS_LEN); + safe_strncpy(tmp, temp_line.c_str(), CROSS_LEN); Bit8u drive; - if (!DOS_MakeName(tmp, fullname, &drive)) { + if (!DOS_MakeName(tmp, fullname, &drive) || strncmp(Drives[drive]->GetInfo(),"local directory",15)) { WriteOut(MSG_Get("PROGRAM_IMGMOUNG_FILE_NOT_FOUND")); return; } diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index f8623d33..24fbdb00 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.43 2005-04-21 18:43:28 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.44 2005-07-19 19:45:31 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -262,8 +262,7 @@ void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) char tmp[CROSS_LEN] = { 0 }; Bit32s len = strrchr(path,CROSS_FILESPLIT) - path; if (len>0) { - strncpy(tmp,path,len); - tmp[len] = 0; + safe_strncpy(tmp,path,len+1); } else { strcpy(tmp,path); } @@ -463,11 +462,10 @@ void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) info->shortNr = CreateShortNameID(curDir,tmpName); sprintf(buffer,"%d",info->shortNr); // Copy first letters - Bit16u tocopy; + Bit16u tocopy = 0; if (len+strlen(buffer)+1>8) tocopy = 8 - strlen(buffer) - 1; else tocopy = len; - strncpy(info->shortname,tmpName,tocopy); - info->shortname[tocopy] = 0; + safe_strncpy(info->shortname,tmpName,tocopy+1); // Copy number strcat(info->shortname,"~"); strcat(info->shortname,buffer); @@ -527,7 +525,7 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* do { // bool errorcheck = false; pos = strchr(start,CROSS_FILESPLIT); - if (pos) { strncpy(dir,start,pos-start); dir[pos-start] = 0; /*errorcheck = true;*/ } + if (pos) { safe_strncpy(dir,start,pos-start+1); /*errorcheck = true;*/ } else { strcpy(dir,start); }; // Path found diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 7cfbb0b1..abeda36a 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.7 2005-03-25 09:06:46 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.8 2005-07-19 19:45:31 qbix79 Exp $ */ #include #include @@ -446,7 +446,7 @@ bool isoDrive :: lookup(isoDirEntry *de, const char *path) if (!strcmp(path, "")) return true; char isoPath[ISO_MAXPATHNAME]; - strncpy(isoPath, path, ISO_MAXPATHNAME); + safe_strncpy(isoPath, path, ISO_MAXPATHNAME); strreplace(isoPath, '\\', '/'); int beginPos = 0; @@ -456,8 +456,7 @@ bool isoDrive :: lookup(isoDirEntry *de, const char *path) char name[38]; if (pos - beginPos >= 38) return false; if (beginPos >= ISO_MAXPATHNAME) return false; - strncpy(name, &isoPath[beginPos], pos - beginPos); - name[pos - beginPos] = 0; + safe_strncpy(name, &isoPath[beginPos], pos - beginPos + 1); beginPos = pos + 1; if (!IS_DIR(de->fileFlags)) return false; if (!lookupSingle(de, name, EXTENT_LOCATION(*de), DATA_LENGTH(*de))) return false; diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index ac8caa53..fa295e22 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_alsa.h,v 1.11 2005-02-10 10:20:52 qbix79 Exp $ */ +/* $Id: midi_alsa.h,v 1.12 2005-07-19 19:45:31 qbix79 Exp $ */ #define ALSA_PCM_OLD_HW_PARAMS_API #define ALSA_PCM_OLD_SW_PARAMS_API @@ -129,7 +129,7 @@ public: // try to use port specified in config file if (conf && conf[0]) { - strncpy(var, conf, 10); + safe_strncpy(var, conf, 10); if (parse_addr(var, &seq_client, &seq_port) < 0) { LOG_MSG("ALSA:Invalid alsa port %s", var); return false; diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index 8a604a04..7aef2565 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -29,7 +29,7 @@ public: char * GetName(void) { return "oss";}; bool Open(const char * conf) { char devname[512]; - if (conf && conf[0]) strncpy(devname,conf,512); + if (conf && conf[0]) safe_strncpy(devname,conf,512); else strcpy(devname,"/dev/sequencer"); char * devfind=(strrchr(devname,',')); if (devfind) { diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index ba3d94d7..c82b2055 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.12 2005-06-13 14:48:02 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.13 2005-07-19 19:45:31 qbix79 Exp $ */ #define OLD_JOYSTICK 1 @@ -95,7 +95,7 @@ static CBindList holdlist; class CEvent { public: CEvent(char * _entry) { - strncpy(entry,_entry,16); + safe_strncpy(entry,_entry,16); events.push_back(this); bindlist.clear(); activity=0; @@ -1444,6 +1444,7 @@ void MAPPER_Run(void) { /* Be sure that there is no update in progress */ GFX_EndUpdate(); mapper.surface=SDL_SetVideoMode(640,480,8,0); + if (mapper.surface == NULL) E_Exit("Could not initialize video mode for mapper: %s",SDL_GetError()); /* Set some palette entries */ SDL_SetPalette(mapper.surface, SDL_LOGPAL|SDL_PHYSPAL, map_pal, 0, 4); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 39842348..88fdb3d3 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.85 2005-05-18 21:59:58 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.86 2005-07-19 19:45:32 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -316,18 +316,24 @@ static SDL_Surface * GFX_SetupSurfaceScaled(Bit32u sdl_flags,Bit32u bpp) { } sdl.clip.x=(Sint16)((sdl.desktop.width-sdl.clip.w)/2); sdl.clip.y=(Sint16)((sdl.desktop.height-sdl.clip.h)/2); - return sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,bpp,sdl_flags|SDL_FULLSCREEN|SDL_HWSURFACE); + sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,bpp,sdl_flags|SDL_FULLSCREEN|SDL_HWSURFACE); + if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",sdl.desktop.width,sdl.desktop.height,bpp,SDL_GetError()); + return sdl.surface; } else { sdl.clip.x=0;sdl.clip.y=0; sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex); sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley); - return sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags|SDL_FULLSCREEN|SDL_HWSURFACE); + sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags|SDL_FULLSCREEN|SDL_HWSURFACE); + if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",sdl.clip.w,sdl.clip.h,bpp,SDL_GetError()); + return sdl.surface; } } else { sdl.clip.x=0;sdl.clip.y=0; sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex*sdl.desktop.hwscale); sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley*sdl.desktop.hwscale); - return sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags|SDL_HWSURFACE); + sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags|SDL_HWSURFACE); + if (sdl.surface == NULL) E_Exit("Could not set windowed video mode %ix%i-%i: %s",sdl.clip.w,sdl.clip.h,bpp,SDL_GetError()); + return sdl.surface; } } @@ -357,14 +363,17 @@ dosurface: sdl.clip.y=(Sint16)((sdl.desktop.height-height)/2); sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,bpp, SDL_FULLSCREEN|SDL_HWSURFACE|(sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0)|SDL_HWPALETTE); + if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",sdl.desktop.width,sdl.desktop.height,bpp,SDL_GetError()); } else { sdl.clip.x=0;sdl.clip.y=0; sdl.surface=SDL_SetVideoMode(width,height,bpp, SDL_FULLSCREEN|SDL_HWSURFACE|(sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0)|SDL_HWPALETTE); + if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",width,height,bpp,SDL_GetError()); } } else { sdl.clip.x=0;sdl.clip.y=0; sdl.surface=SDL_SetVideoMode(width,height,bpp,SDL_HWSURFACE); + if (sdl.surface == NULL) E_Exit("Could not set windowed video mode %ix%i-%i: %s",width,height,bpp,SDL_GetError()); } if (sdl.surface) switch (sdl.surface->format->BitsPerPixel) { case 8:sdl.draw.mode=GFX_8;break; @@ -857,6 +866,10 @@ static void GUI_StartUp(Section * sec) { #if C_OPENGL if(sdl.desktop.want_type==SCREEN_OPENGL){ /* OPENGL is requested */ sdl.surface=SDL_SetVideoMode(640,400,0,SDL_OPENGL); + if (sdl.surface == NULL) { + LOG_MSG("Could not initialize OpenGL, switching back to surface"); + sdl.desktop.want_type=SCREEN_SURFACE; + } else { sdl.opengl.framebuf=0; sdl.opengl.texture=0; sdl.opengl.displaylist=0; @@ -877,11 +890,13 @@ static void GUI_StartUp(Section * sec) { } else { sdl.opengl.packed_pixel=sdl.opengl.paletted_texture=false; } + } } /* OPENGL is requested end */ #endif //OPENGL /* Initialize screen for first time */ sdl.surface=SDL_SetVideoMode(640,400,0,0); + if (sdl.surface == NULL) E_Exit("Could not initialize video: %s",SDL_GetError()); sdl.desktop.bpp=sdl.surface->format->BitsPerPixel; if (sdl.desktop.bpp==24) { LOG_MSG("SDL:You are running in 24 bpp mode, this will slow down things!"); diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 06424fa6..be75c972 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.33 2005-04-29 13:45:26 qbix79 Exp $ */ +/* $Id: mixer.cpp,v 1.34 2005-07-19 19:45:32 qbix79 Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -486,7 +486,7 @@ static void MIXER_ProgramStart(Program * * make) { MixerChannel* MixerObject::Install(MIXER_Handler handler,Bitu freq,char * name){ if(!installed) { if(strlen(name) > 31) E_Exit("Too long mixer channel name"); - strncpy(m_name,name,31); + safe_strncpy(m_name,name,32); installed = true; return MIXER_AddChannel(handler,freq,name); } else { diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index c7953dcc..460f00b1 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.28 2005-04-22 09:09:09 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.29 2005-07-19 19:45:33 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -337,7 +337,7 @@ bool Config::ParseConfigFile(const char* configfilename){ void Config::ParseEnv(char ** envp) { for(char** env=envp; *env;env++) { char copy[1024]; - strncpy(copy,*env,1024); + safe_strncpy(copy,*env,1024); if(strncasecmp(copy,"DOSBOX_",7)) continue; char* sec_name = ©[7]; From 664ce27aae11a6c4d9e01fcbd877e7e472cdcf68 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 20 Jul 2005 11:35:53 +0000 Subject: [PATCH 2157/4131] applied patch 1241404 from kekko81: "Boot letter bugfix" Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2241 --- src/dos/dos_programs.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 6f9339a6..f97e98f0 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.37 2005-07-19 19:45:16 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.38 2005-07-20 11:35:53 qbix79 Exp $ */ #include #include @@ -299,7 +299,7 @@ public: drive = 'A'; while(iGetCount()) { if(cmd->FindCommand(i+1, temp_line)) { - if(temp_line == "-l") { + if((temp_line == "-l") || (temp_line == "-L")) { /* Specifying drive... next argument then is the drive */ i++; if(cmd->FindCommand(i+1, temp_line)) { @@ -341,7 +341,7 @@ public: return; } - WriteOut(MSG_Get("PROGRAM_BOOT_BOOT"),"Booting from drive %c...\n", drive); + WriteOut(MSG_Get("PROGRAM_BOOT_BOOT"), drive); bootSector bootarea; imageDiskList[drive-65]->Read_Sector(0,0,1,(Bit8u *)&bootarea); From 8cf6549e85ed37a10680452106f700ef1d1d229d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 20 Jul 2005 12:00:45 +0000 Subject: [PATCH 2158/4131] Fix bug 1241199. Env variables were matched against the length of the wanted string. So if you wanted b, b* matched to this. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2242 --- src/misc/programs.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index eb975c73..e80580a2 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.19 2005-04-21 21:17:45 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.20 2005-07-20 12:00:45 qbix79 Exp $ */ #include #include @@ -127,9 +127,15 @@ bool Program::GetEnvStr(const char * entry,std::string & result) { MEM_StrCopy(env_read,env_string,1024); if (!env_string[0]) return false; env_read+=strlen(env_string)+1; - if (!strchr(env_string,'=')) continue; - if (strncasecmp(entry,env_string,strlen(entry))!=0) continue; - result=env_string; + char* equal = strchr(env_string,'='); + if (!equal) continue; + /* replace the = with \0 to get the length */ + *equal = 0; + if (strlen(env_string) != strlen(entry)) continue; + if (strcasecmp(entry,env_string)!=0) continue; + /* restore the = to get the original result */ + *equal = '='; + result = env_string; return true; } while (1); return false; From d0ea228182c3791f8ba9a84c94298fce7c3af361 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 20 Jul 2005 15:27:20 +0000 Subject: [PATCH 2159/4131] Fix bug 1241198 (if cond set a=b didn't work because a single = wasn't allowed without errorlevel) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2243 --- src/shell/shell_cmds.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 897eacd5..3fa83a94 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.54 2005-04-21 21:17:46 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.55 2005-07-20 15:27:20 qbix79 Exp $ */ #include #include @@ -551,7 +551,11 @@ void DOS_Shell::CMD_IF(char * args) { *comp++ = ' '; while(*comp++ == ' ') ; /*nothing */ - } else {SyntaxError();return;} + } else if(strncasecmp(args," set ",5) !=0) { + /* if cond set a=b is allowed as well */ + SyntaxError(); + return; + } }; char * word=StripWord(args); if (strcasecmp(word,"NOT")==0) { From 9c62fe8db26ee9fe834d44691de8a72298739550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 20 Jul 2005 19:20:23 +0000 Subject: [PATCH 2160/4131] bug when dos mem resize is used to shrink memory blocks (QuickBasic, fixes Shard of Spring) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2244 --- src/dos/dos_memory.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 55972ac3..8ffc6926 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -138,6 +138,24 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { DOS_MCB mcb(segment-1); Bit16u total=mcb.GetSize(); DOS_MCB mcb_next(segment+total); + if (*blocks<=total) { + if (GCC_UNLIKELY(*blocks==total)) { + /* Nothing to do */ + return true; + } + /* Shrinking MCB */ + DOS_MCB mcb_new_next(segment+(*blocks)); + mcb.SetSize(*blocks); + mcb_new_next.SetType(mcb.GetType()); + if (mcb.GetType()==0x5a) { + /* Further blocks follow */ + mcb.SetType(0x4d); + } + + mcb_new_next.SetSize(total-*blocks-1); + mcb_new_next.SetPSPSeg(MCB_FREE); + return true; + } if (mcb.GetType()!=0x5a) { if (mcb_next.GetPSPSeg()==MCB_FREE) { total+=mcb_next.GetSize()+1; From 74ddc58f16a09b84c56e02862bfbfdf07582855b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 21 Jul 2005 07:48:37 +0000 Subject: [PATCH 2161/4131] Missing include for safe_strncpy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2245 --- src/dos/cdrom_aspi_win32.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index ca8360f1..573fde0a 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_aspi_win32.cpp,v 1.14 2005-07-19 19:45:16 qbix79 Exp $ */ +/* $Id: cdrom_aspi_win32.cpp,v 1.15 2005-07-21 07:48:37 qbix79 Exp $ */ #if defined (WIN32) @@ -24,6 +24,7 @@ #include "dosbox.h" #include "cdrom.h" +#include "support.h" //Are actually system includes but leave for now #include "wnaspi32.h" From f8728fc4c3a14a37fb3ab757d2b260e446d49122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 21 Jul 2005 12:41:53 +0000 Subject: [PATCH 2162/4131] modified behaviour of port 0x3c1 affects INT10_GetAllPaletteRegisters (fixes colour in Borland IDEs) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2246 --- src/ints/int10_pal.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 10635e80..631095e7 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -117,11 +117,13 @@ void INT10_GetAllPaletteRegisters(PhysPt data) { for(Bit8u i=0;i<0x10;i++) { IO_Write(VGAREG_ACTL_ADDRESS,i); mem_writeb(data,IO_Read(VGAREG_ACTL_READ_DATA)); + IO_Read(VGAREG_ACTL_RESET); data++; } // Then the border IO_Write(VGAREG_ACTL_ADDRESS,0x11+32); mem_writeb(data,IO_Read(VGAREG_ACTL_READ_DATA)); + IO_Read(VGAREG_ACTL_RESET); } void INT10_SetSingleDacRegister(Bit8u index,Bit8u red,Bit8u green,Bit8u blue) { From d4cf66ccae25debc7af07eb1f59c93969a81b6d2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 21 Jul 2005 12:49:52 +0000 Subject: [PATCH 2163/4131] line end conversions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2247 --- src/dos/scsidefs.h | 576 ++++++++++++++++++++++----------------------- 1 file changed, 288 insertions(+), 288 deletions(-) diff --git a/src/dos/scsidefs.h b/src/dos/scsidefs.h index 3b02c274..85ff62a6 100644 --- a/src/dos/scsidefs.h +++ b/src/dos/scsidefs.h @@ -1,288 +1,288 @@ -/* Got it from Bochs */ - -///////////////////////////////////////////////////////////////////////// -// $Id: scsidefs.h,v 1.2 2004-01-02 14:34:48 qbix79 Exp $ -///////////////////////////////////////////////////////////////////////// -// -// -// iodev/scsidefs.h -// $Id: scsidefs.h,v 1.2 2004-01-02 14:34:48 qbix79 Exp $ -// -// This file was copied from ... ? -// - -//*************************************************************************** -// -// Name: SCSIDEFS.H -// -// Description: SCSI definitions ('C' Language) -// -//*************************************************************************** - -//*************************************************************************** -// %%% TARGET STATUS VALUES %%% -//*************************************************************************** -#define STATUS_GOOD 0x00 // Status Good -#define STATUS_CHKCOND 0x02 // Check Condition -#define STATUS_CONDMET 0x04 // Condition Met -#define STATUS_BUSY 0x08 // Busy -#define STATUS_INTERM 0x10 // Intermediate -#define STATUS_INTCDMET 0x14 // Intermediate-condition met -#define STATUS_RESCONF 0x18 // Reservation conflict -#define STATUS_COMTERM 0x22 // Command Terminated -#define STATUS_QFULL 0x28 // Queue full - -//*************************************************************************** -// %%% SCSI MISCELLANEOUS EQUATES %%% -//*************************************************************************** -#define MAXLUN 7 // Maximum Logical Unit Id -#define MAXTARG 7 // Maximum Target Id -#define MAX_SCSI_LUNS 64 // Maximum Number of SCSI LUNs -#define MAX_NUM_HA 8 // Maximum Number of SCSI HA's - -//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ -// -// %%% SCSI COMMAND OPCODES %%% -// -///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ - -//*************************************************************************** -// %%% Commands for all Device Types %%% -//*************************************************************************** -#define SCSI_CHANGE_DEF 0x40 // Change Definition (Optional) -#define SCSI_COMPARE 0x39 // Compare (O) -#define SCSI_COPY 0x18 // Copy (O) -#define SCSI_COP_VERIFY 0x3A // Copy and Verify (O) -#define SCSI_INQUIRY 0x12 // Inquiry (MANDATORY) -#define SCSI_LOG_SELECT 0x4C // Log Select (O) -#define SCSI_LOG_SENSE 0x4D // Log Sense (O) -#define SCSI_MODE_SEL6 0x15 // Mode Select 6-byte (Device Specific) -#define SCSI_MODE_SEL10 0x55 // Mode Select 10-byte (Device Specific) -#define SCSI_MODE_SEN6 0x1A // Mode Sense 6-byte (Device Specific) -#define SCSI_MODE_SEN10 0x5A // Mode Sense 10-byte (Device Specific) -#define SCSI_READ_BUFF 0x3C // Read Buffer (O) -#define SCSI_REQ_SENSE 0x03 // Request Sense (MANDATORY) -#define SCSI_SEND_DIAG 0x1D // Send Diagnostic (O) -#define SCSI_TST_U_RDY 0x00 // Test Unit Ready (MANDATORY) -#define SCSI_WRITE_BUFF 0x3B // Write Buffer (O) - -//*************************************************************************** -// %%% Commands Unique to Direct Access Devices %%% -//*************************************************************************** -#define SCSI_COMPARE 0x39 // Compare (O) -#define SCSI_FORMAT 0x04 // Format Unit (MANDATORY) -#define SCSI_LCK_UN_CAC 0x36 // Lock Unlock Cache (O) -#define SCSI_PREFETCH 0x34 // Prefetch (O) -#define SCSI_MED_REMOVL 0x1E // Prevent/Allow medium Removal (O) -#define SCSI_READ6 0x08 // Read 6-byte (MANDATORY) -#define SCSI_READ10 0x28 // Read 10-byte (MANDATORY) -#define SCSI_RD_CAPAC 0x25 // Read Capacity (MANDATORY) -#define SCSI_RD_DEFECT 0x37 // Read Defect Data (O) -#define SCSI_READ_LONG 0x3E // Read Long (O) -#define SCSI_REASS_BLK 0x07 // Reassign Blocks (O) -#define SCSI_RCV_DIAG 0x1C // Receive Diagnostic Results (O) -#define SCSI_RELEASE 0x17 // Release Unit (MANDATORY) -#define SCSI_REZERO 0x01 // Rezero Unit (O) -#define SCSI_SRCH_DAT_E 0x31 // Search Data Equal (O) -#define SCSI_SRCH_DAT_H 0x30 // Search Data High (O) -#define SCSI_SRCH_DAT_L 0x32 // Search Data Low (O) -#define SCSI_SEEK6 0x0B // Seek 6-Byte (O) -#define SCSI_SEEK10 0x2B // Seek 10-Byte (O) -#define SCSI_SEND_DIAG 0x1D // Send Diagnostics (MANDATORY) -#define SCSI_SET_LIMIT 0x33 // Set Limits (O) -#define SCSI_START_STP 0x1B // Start/Stop Unit (O) -#define SCSI_SYNC_CACHE 0x35 // Synchronize Cache (O) -#define SCSI_VERIFY 0x2F // Verify (O) -#define SCSI_WRITE6 0x0A // Write 6-Byte (MANDATORY) -#define SCSI_WRITE10 0x2A // Write 10-Byte (MANDATORY) -#define SCSI_WRT_VERIFY 0x2E // Write and Verify (O) -#define SCSI_WRITE_LONG 0x3F // Write Long (O) -#define SCSI_WRITE_SAME 0x41 // Write Same (O) - -//*************************************************************************** -// %%% Commands Unique to Sequential Access Devices %%% -//*************************************************************************** -#define SCSI_ERASE 0x19 // Erase (MANDATORY) -#define SCSI_LOAD_UN 0x1B // Load/Unload (O) -#define SCSI_LOCATE 0x2B // Locate (O) -#define SCSI_RD_BLK_LIM 0x05 // Read Block Limits (MANDATORY) -#define SCSI_READ_POS 0x34 // Read Position (O) -#define SCSI_READ_REV 0x0F // Read Reverse (O) -#define SCSI_REC_BF_DAT 0x14 // Recover Buffer Data (O) -#define SCSI_RESERVE 0x16 // Reserve Unit (MANDATORY) -#define SCSI_REWIND 0x01 // Rewind (MANDATORY) -#define SCSI_SPACE 0x11 // Space (MANDATORY) -#define SCSI_VERIFY_T 0x13 // Verify (Tape) (O) -#define SCSI_WRT_FILE 0x10 // Write Filemarks (MANDATORY) - -//*************************************************************************** -// %%% Commands Unique to Printer Devices %%% -//*************************************************************************** -#define SCSI_PRINT 0x0A // Print (MANDATORY) -#define SCSI_SLEW_PNT 0x0B // Slew and Print (O) -#define SCSI_STOP_PNT 0x1B // Stop Print (O) -#define SCSI_SYNC_BUFF 0x10 // Synchronize Buffer (O) - -//*************************************************************************** -// %%% Commands Unique to Processor Devices %%% -//*************************************************************************** -#define SCSI_RECEIVE 0x08 // Receive (O) -#define SCSI_SEND 0x0A // Send (O) - -//*************************************************************************** -// %%% Commands Unique to Write-Once Devices %%% -//*************************************************************************** -#define SCSI_MEDIUM_SCN 0x38 // Medium Scan (O) -#define SCSI_SRCHDATE10 0x31 // Search Data Equal 10-Byte (O) -#define SCSI_SRCHDATE12 0xB1 // Search Data Equal 12-Byte (O) -#define SCSI_SRCHDATH10 0x30 // Search Data High 10-Byte (O) -#define SCSI_SRCHDATH12 0xB0 // Search Data High 12-Byte (O) -#define SCSI_SRCHDATL10 0x32 // Search Data Low 10-Byte (O) -#define SCSI_SRCHDATL12 0xB2 // Search Data Low 12-Byte (O) -#define SCSI_SET_LIM_10 0x33 // Set Limits 10-Byte (O) -#define SCSI_SET_LIM_12 0xB3 // Set Limits 10-Byte (O) -#define SCSI_VERIFY10 0x2F // Verify 10-Byte (O) -#define SCSI_VERIFY12 0xAF // Verify 12-Byte (O) -#define SCSI_WRITE12 0xAA // Write 12-Byte (O) -#define SCSI_WRT_VER10 0x2E // Write and Verify 10-Byte (O) -#define SCSI_WRT_VER12 0xAE // Write and Verify 12-Byte (O) - -//*************************************************************************** -// %%% Commands Unique to CD-ROM Devices %%% -//*************************************************************************** -#define SCSI_PLAYAUD_10 0x45 // Play Audio 10-Byte (O) -#define SCSI_PLAYAUD_12 0xA5 // Play Audio 12-Byte 12-Byte (O) -#define SCSI_PLAYAUDMSF 0x47 // Play Audio MSF (O) -#define SCSI_PLAYA_TKIN 0x48 // Play Audio Track/Index (O) -#define SCSI_PLYTKREL10 0x49 // Play Track Relative 10-Byte (O) -#define SCSI_PLYTKREL12 0xA9 // Play Track Relative 12-Byte (O) -#define SCSI_READCDCAP 0x25 // Read CD-ROM Capacity (MANDATORY) -#define SCSI_READHEADER 0x44 // Read Header (O) -#define SCSI_SUBCHANNEL 0x42 // Read Subchannel (O) -#define SCSI_READ_TOC 0x43 // Read TOC (O) - -//*************************************************************************** -// %%% Commands Unique to Scanner Devices %%% -//*************************************************************************** -#define SCSI_GETDBSTAT 0x34 // Get Data Buffer Status (O) -#define SCSI_GETWINDOW 0x25 // Get Window (O) -#define SCSI_OBJECTPOS 0x31 // Object Postion (O) -#define SCSI_SCAN 0x1B // Scan (O) -#define SCSI_SETWINDOW 0x24 // Set Window (MANDATORY) - -//*************************************************************************** -// %%% Commands Unique to Optical Memory Devices %%% -//*************************************************************************** -#define SCSI_UpdateBlk 0x3D // Update Block (O) - -//*************************************************************************** -// %%% Commands Unique to Medium Changer Devices %%% -//*************************************************************************** -#define SCSI_EXCHMEDIUM 0xA6 // Exchange Medium (O) -#define SCSI_INITELSTAT 0x07 // Initialize Element Status (O) -#define SCSI_POSTOELEM 0x2B // Position to Element (O) -#define SCSI_REQ_VE_ADD 0xB5 // Request Volume Element Address (O) -#define SCSI_SENDVOLTAG 0xB6 // Send Volume Tag (O) - -//*************************************************************************** -// %%% Commands Unique to Communication Devices %%% -//*************************************************************************** -#define SCSI_GET_MSG_6 0x08 // Get Message 6-Byte (MANDATORY) -#define SCSI_GET_MSG_10 0x28 // Get Message 10-Byte (O) -#define SCSI_GET_MSG_12 0xA8 // Get Message 12-Byte (O) -#define SCSI_SND_MSG_6 0x0A // Send Message 6-Byte (MANDATORY) -#define SCSI_SND_MSG_10 0x2A // Send Message 10-Byte (O) -#define SCSI_SND_MSG_12 0xAA // Send Message 12-Byte (O) - -//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ -// -// %%% END OF SCSI COMMAND OPCODES %%% -// -///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ - -//*************************************************************************** -// %%% Request Sense Data Format %%% -//*************************************************************************** -typedef struct { - - BYTE ErrorCode; // Error Code (70H or 71H) - BYTE SegmentNum; // Number of current segment descriptor - BYTE SenseKey; // Sense Key(See bit definitions too) - BYTE InfoByte0; // Information MSB - BYTE InfoByte1; // Information MID - BYTE InfoByte2; // Information MID - BYTE InfoByte3; // Information LSB - BYTE AddSenLen; // Additional Sense Length - BYTE ComSpecInf0; // Command Specific Information MSB - BYTE ComSpecInf1; // Command Specific Information MID - BYTE ComSpecInf2; // Command Specific Information MID - BYTE ComSpecInf3; // Command Specific Information LSB - BYTE AddSenseCode; // Additional Sense Code - BYTE AddSenQual; // Additional Sense Code Qualifier - BYTE FieldRepUCode; // Field Replaceable Unit Code - BYTE SenKeySpec15; // Sense Key Specific 15th byte - BYTE SenKeySpec16; // Sense Key Specific 16th byte - BYTE SenKeySpec17; // Sense Key Specific 17th byte - BYTE AddSenseBytes; // Additional Sense Bytes - -} SENSE_DATA_FMT; - -//*************************************************************************** -// %%% REQUEST SENSE ERROR CODE %%% -//*************************************************************************** -#define SERROR_CURRENT 0x70 // Current Errors -#define SERROR_DEFERED 0x71 // Deferred Errors - -//*************************************************************************** -// %%% REQUEST SENSE BIT DEFINITIONS %%% -//*************************************************************************** -#define SENSE_VALID 0x80 // Byte 0 Bit 7 -#define SENSE_FILEMRK 0x80 // Byte 2 Bit 7 -#define SENSE_EOM 0x40 // Byte 2 Bit 6 -#define SENSE_ILI 0x20 // Byte 2 Bit 5 - -//*************************************************************************** -// %%% REQUEST SENSE SENSE KEY DEFINITIONS %%% -//*************************************************************************** -#define KEY_NOSENSE 0x00 // No Sense -#define KEY_RECERROR 0x01 // Recovered Error -#define KEY_NOTREADY 0x02 // Not Ready -#define KEY_MEDIUMERR 0x03 // Medium Error -#define KEY_HARDERROR 0x04 // Hardware Error -#define KEY_ILLGLREQ 0x05 // Illegal Request -#define KEY_UNITATT 0x06 // Unit Attention -#define KEY_DATAPROT 0x07 // Data Protect -#define KEY_BLANKCHK 0x08 // Blank Check -#define KEY_VENDSPEC 0x09 // Vendor Specific -#define KEY_COPYABORT 0x0A // Copy Abort -#define KEY_EQUAL 0x0C // Equal (Search) -#define KEY_VOLOVRFLW 0x0D // Volume Overflow -#define KEY_MISCOMP 0x0E // Miscompare (Search) -#define KEY_RESERVED 0x0F // Reserved - -//*************************************************************************** -// %%% PERIPHERAL DEVICE TYPE DEFINITIONS %%% -//*************************************************************************** -#define DTYPE_DASD 0x00 // Disk Device -#define DTYPE_SEQD 0x01 // Tape Device -#define DTYPE_PRNT 0x02 // Printer -#define DTYPE_PROC 0x03 // Processor -#define DTYPE_WORM 0x04 // Write-once read-multiple -#define DTYPE_CROM 0x05 // CD-ROM device -#define DTYPE_CDROM 0x05 // CD-ROM device -#define DTYPE_SCAN 0x06 // Scanner device -#define DTYPE_OPTI 0x07 // Optical memory device -#define DTYPE_JUKE 0x08 // Medium Changer device -#define DTYPE_COMM 0x09 // Communications device -#define DTYPE_RESL 0x0A // Reserved (low) -#define DTYPE_RESH 0x1E // Reserved (high) -#define DTYPE_UNKNOWN 0x1F // Unknown or no device type - -//*************************************************************************** -// %%% ANSI APPROVED VERSION DEFINITIONS %%% -//*************************************************************************** -#define ANSI_MAYBE 0x0 // Device may or may not be ANSI approved stand -#define ANSI_SCSI1 0x1 // Device complies to ANSI X3.131-1986 (SCSI-1) -#define ANSI_SCSI2 0x2 // Device complies to SCSI-2 -#define ANSI_RESLO 0x3 // Reserved (low) -#define ANSI_RESHI 0x7 // Reserved (high) +/* Got it from Bochs */ + +///////////////////////////////////////////////////////////////////////// +// $Id: scsidefs.h,v 1.3 2005-07-21 12:49:52 qbix79 Exp $ +///////////////////////////////////////////////////////////////////////// +// +// +// iodev/scsidefs.h +// $Id: scsidefs.h,v 1.3 2005-07-21 12:49:52 qbix79 Exp $ +// +// This file was copied from ... ? +// + +//*************************************************************************** +// +// Name: SCSIDEFS.H +// +// Description: SCSI definitions ('C' Language) +// +//*************************************************************************** + +//*************************************************************************** +// %%% TARGET STATUS VALUES %%% +//*************************************************************************** +#define STATUS_GOOD 0x00 // Status Good +#define STATUS_CHKCOND 0x02 // Check Condition +#define STATUS_CONDMET 0x04 // Condition Met +#define STATUS_BUSY 0x08 // Busy +#define STATUS_INTERM 0x10 // Intermediate +#define STATUS_INTCDMET 0x14 // Intermediate-condition met +#define STATUS_RESCONF 0x18 // Reservation conflict +#define STATUS_COMTERM 0x22 // Command Terminated +#define STATUS_QFULL 0x28 // Queue full + +//*************************************************************************** +// %%% SCSI MISCELLANEOUS EQUATES %%% +//*************************************************************************** +#define MAXLUN 7 // Maximum Logical Unit Id +#define MAXTARG 7 // Maximum Target Id +#define MAX_SCSI_LUNS 64 // Maximum Number of SCSI LUNs +#define MAX_NUM_HA 8 // Maximum Number of SCSI HA's + +//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ +// +// %%% SCSI COMMAND OPCODES %%% +// +///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ + +//*************************************************************************** +// %%% Commands for all Device Types %%% +//*************************************************************************** +#define SCSI_CHANGE_DEF 0x40 // Change Definition (Optional) +#define SCSI_COMPARE 0x39 // Compare (O) +#define SCSI_COPY 0x18 // Copy (O) +#define SCSI_COP_VERIFY 0x3A // Copy and Verify (O) +#define SCSI_INQUIRY 0x12 // Inquiry (MANDATORY) +#define SCSI_LOG_SELECT 0x4C // Log Select (O) +#define SCSI_LOG_SENSE 0x4D // Log Sense (O) +#define SCSI_MODE_SEL6 0x15 // Mode Select 6-byte (Device Specific) +#define SCSI_MODE_SEL10 0x55 // Mode Select 10-byte (Device Specific) +#define SCSI_MODE_SEN6 0x1A // Mode Sense 6-byte (Device Specific) +#define SCSI_MODE_SEN10 0x5A // Mode Sense 10-byte (Device Specific) +#define SCSI_READ_BUFF 0x3C // Read Buffer (O) +#define SCSI_REQ_SENSE 0x03 // Request Sense (MANDATORY) +#define SCSI_SEND_DIAG 0x1D // Send Diagnostic (O) +#define SCSI_TST_U_RDY 0x00 // Test Unit Ready (MANDATORY) +#define SCSI_WRITE_BUFF 0x3B // Write Buffer (O) + +//*************************************************************************** +// %%% Commands Unique to Direct Access Devices %%% +//*************************************************************************** +#define SCSI_COMPARE 0x39 // Compare (O) +#define SCSI_FORMAT 0x04 // Format Unit (MANDATORY) +#define SCSI_LCK_UN_CAC 0x36 // Lock Unlock Cache (O) +#define SCSI_PREFETCH 0x34 // Prefetch (O) +#define SCSI_MED_REMOVL 0x1E // Prevent/Allow medium Removal (O) +#define SCSI_READ6 0x08 // Read 6-byte (MANDATORY) +#define SCSI_READ10 0x28 // Read 10-byte (MANDATORY) +#define SCSI_RD_CAPAC 0x25 // Read Capacity (MANDATORY) +#define SCSI_RD_DEFECT 0x37 // Read Defect Data (O) +#define SCSI_READ_LONG 0x3E // Read Long (O) +#define SCSI_REASS_BLK 0x07 // Reassign Blocks (O) +#define SCSI_RCV_DIAG 0x1C // Receive Diagnostic Results (O) +#define SCSI_RELEASE 0x17 // Release Unit (MANDATORY) +#define SCSI_REZERO 0x01 // Rezero Unit (O) +#define SCSI_SRCH_DAT_E 0x31 // Search Data Equal (O) +#define SCSI_SRCH_DAT_H 0x30 // Search Data High (O) +#define SCSI_SRCH_DAT_L 0x32 // Search Data Low (O) +#define SCSI_SEEK6 0x0B // Seek 6-Byte (O) +#define SCSI_SEEK10 0x2B // Seek 10-Byte (O) +#define SCSI_SEND_DIAG 0x1D // Send Diagnostics (MANDATORY) +#define SCSI_SET_LIMIT 0x33 // Set Limits (O) +#define SCSI_START_STP 0x1B // Start/Stop Unit (O) +#define SCSI_SYNC_CACHE 0x35 // Synchronize Cache (O) +#define SCSI_VERIFY 0x2F // Verify (O) +#define SCSI_WRITE6 0x0A // Write 6-Byte (MANDATORY) +#define SCSI_WRITE10 0x2A // Write 10-Byte (MANDATORY) +#define SCSI_WRT_VERIFY 0x2E // Write and Verify (O) +#define SCSI_WRITE_LONG 0x3F // Write Long (O) +#define SCSI_WRITE_SAME 0x41 // Write Same (O) + +//*************************************************************************** +// %%% Commands Unique to Sequential Access Devices %%% +//*************************************************************************** +#define SCSI_ERASE 0x19 // Erase (MANDATORY) +#define SCSI_LOAD_UN 0x1B // Load/Unload (O) +#define SCSI_LOCATE 0x2B // Locate (O) +#define SCSI_RD_BLK_LIM 0x05 // Read Block Limits (MANDATORY) +#define SCSI_READ_POS 0x34 // Read Position (O) +#define SCSI_READ_REV 0x0F // Read Reverse (O) +#define SCSI_REC_BF_DAT 0x14 // Recover Buffer Data (O) +#define SCSI_RESERVE 0x16 // Reserve Unit (MANDATORY) +#define SCSI_REWIND 0x01 // Rewind (MANDATORY) +#define SCSI_SPACE 0x11 // Space (MANDATORY) +#define SCSI_VERIFY_T 0x13 // Verify (Tape) (O) +#define SCSI_WRT_FILE 0x10 // Write Filemarks (MANDATORY) + +//*************************************************************************** +// %%% Commands Unique to Printer Devices %%% +//*************************************************************************** +#define SCSI_PRINT 0x0A // Print (MANDATORY) +#define SCSI_SLEW_PNT 0x0B // Slew and Print (O) +#define SCSI_STOP_PNT 0x1B // Stop Print (O) +#define SCSI_SYNC_BUFF 0x10 // Synchronize Buffer (O) + +//*************************************************************************** +// %%% Commands Unique to Processor Devices %%% +//*************************************************************************** +#define SCSI_RECEIVE 0x08 // Receive (O) +#define SCSI_SEND 0x0A // Send (O) + +//*************************************************************************** +// %%% Commands Unique to Write-Once Devices %%% +//*************************************************************************** +#define SCSI_MEDIUM_SCN 0x38 // Medium Scan (O) +#define SCSI_SRCHDATE10 0x31 // Search Data Equal 10-Byte (O) +#define SCSI_SRCHDATE12 0xB1 // Search Data Equal 12-Byte (O) +#define SCSI_SRCHDATH10 0x30 // Search Data High 10-Byte (O) +#define SCSI_SRCHDATH12 0xB0 // Search Data High 12-Byte (O) +#define SCSI_SRCHDATL10 0x32 // Search Data Low 10-Byte (O) +#define SCSI_SRCHDATL12 0xB2 // Search Data Low 12-Byte (O) +#define SCSI_SET_LIM_10 0x33 // Set Limits 10-Byte (O) +#define SCSI_SET_LIM_12 0xB3 // Set Limits 10-Byte (O) +#define SCSI_VERIFY10 0x2F // Verify 10-Byte (O) +#define SCSI_VERIFY12 0xAF // Verify 12-Byte (O) +#define SCSI_WRITE12 0xAA // Write 12-Byte (O) +#define SCSI_WRT_VER10 0x2E // Write and Verify 10-Byte (O) +#define SCSI_WRT_VER12 0xAE // Write and Verify 12-Byte (O) + +//*************************************************************************** +// %%% Commands Unique to CD-ROM Devices %%% +//*************************************************************************** +#define SCSI_PLAYAUD_10 0x45 // Play Audio 10-Byte (O) +#define SCSI_PLAYAUD_12 0xA5 // Play Audio 12-Byte 12-Byte (O) +#define SCSI_PLAYAUDMSF 0x47 // Play Audio MSF (O) +#define SCSI_PLAYA_TKIN 0x48 // Play Audio Track/Index (O) +#define SCSI_PLYTKREL10 0x49 // Play Track Relative 10-Byte (O) +#define SCSI_PLYTKREL12 0xA9 // Play Track Relative 12-Byte (O) +#define SCSI_READCDCAP 0x25 // Read CD-ROM Capacity (MANDATORY) +#define SCSI_READHEADER 0x44 // Read Header (O) +#define SCSI_SUBCHANNEL 0x42 // Read Subchannel (O) +#define SCSI_READ_TOC 0x43 // Read TOC (O) + +//*************************************************************************** +// %%% Commands Unique to Scanner Devices %%% +//*************************************************************************** +#define SCSI_GETDBSTAT 0x34 // Get Data Buffer Status (O) +#define SCSI_GETWINDOW 0x25 // Get Window (O) +#define SCSI_OBJECTPOS 0x31 // Object Postion (O) +#define SCSI_SCAN 0x1B // Scan (O) +#define SCSI_SETWINDOW 0x24 // Set Window (MANDATORY) + +//*************************************************************************** +// %%% Commands Unique to Optical Memory Devices %%% +//*************************************************************************** +#define SCSI_UpdateBlk 0x3D // Update Block (O) + +//*************************************************************************** +// %%% Commands Unique to Medium Changer Devices %%% +//*************************************************************************** +#define SCSI_EXCHMEDIUM 0xA6 // Exchange Medium (O) +#define SCSI_INITELSTAT 0x07 // Initialize Element Status (O) +#define SCSI_POSTOELEM 0x2B // Position to Element (O) +#define SCSI_REQ_VE_ADD 0xB5 // Request Volume Element Address (O) +#define SCSI_SENDVOLTAG 0xB6 // Send Volume Tag (O) + +//*************************************************************************** +// %%% Commands Unique to Communication Devices %%% +//*************************************************************************** +#define SCSI_GET_MSG_6 0x08 // Get Message 6-Byte (MANDATORY) +#define SCSI_GET_MSG_10 0x28 // Get Message 10-Byte (O) +#define SCSI_GET_MSG_12 0xA8 // Get Message 12-Byte (O) +#define SCSI_SND_MSG_6 0x0A // Send Message 6-Byte (MANDATORY) +#define SCSI_SND_MSG_10 0x2A // Send Message 10-Byte (O) +#define SCSI_SND_MSG_12 0xAA // Send Message 12-Byte (O) + +//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ +// +// %%% END OF SCSI COMMAND OPCODES %%% +// +///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ + +//*************************************************************************** +// %%% Request Sense Data Format %%% +//*************************************************************************** +typedef struct { + + BYTE ErrorCode; // Error Code (70H or 71H) + BYTE SegmentNum; // Number of current segment descriptor + BYTE SenseKey; // Sense Key(See bit definitions too) + BYTE InfoByte0; // Information MSB + BYTE InfoByte1; // Information MID + BYTE InfoByte2; // Information MID + BYTE InfoByte3; // Information LSB + BYTE AddSenLen; // Additional Sense Length + BYTE ComSpecInf0; // Command Specific Information MSB + BYTE ComSpecInf1; // Command Specific Information MID + BYTE ComSpecInf2; // Command Specific Information MID + BYTE ComSpecInf3; // Command Specific Information LSB + BYTE AddSenseCode; // Additional Sense Code + BYTE AddSenQual; // Additional Sense Code Qualifier + BYTE FieldRepUCode; // Field Replaceable Unit Code + BYTE SenKeySpec15; // Sense Key Specific 15th byte + BYTE SenKeySpec16; // Sense Key Specific 16th byte + BYTE SenKeySpec17; // Sense Key Specific 17th byte + BYTE AddSenseBytes; // Additional Sense Bytes + +} SENSE_DATA_FMT; + +//*************************************************************************** +// %%% REQUEST SENSE ERROR CODE %%% +//*************************************************************************** +#define SERROR_CURRENT 0x70 // Current Errors +#define SERROR_DEFERED 0x71 // Deferred Errors + +//*************************************************************************** +// %%% REQUEST SENSE BIT DEFINITIONS %%% +//*************************************************************************** +#define SENSE_VALID 0x80 // Byte 0 Bit 7 +#define SENSE_FILEMRK 0x80 // Byte 2 Bit 7 +#define SENSE_EOM 0x40 // Byte 2 Bit 6 +#define SENSE_ILI 0x20 // Byte 2 Bit 5 + +//*************************************************************************** +// %%% REQUEST SENSE SENSE KEY DEFINITIONS %%% +//*************************************************************************** +#define KEY_NOSENSE 0x00 // No Sense +#define KEY_RECERROR 0x01 // Recovered Error +#define KEY_NOTREADY 0x02 // Not Ready +#define KEY_MEDIUMERR 0x03 // Medium Error +#define KEY_HARDERROR 0x04 // Hardware Error +#define KEY_ILLGLREQ 0x05 // Illegal Request +#define KEY_UNITATT 0x06 // Unit Attention +#define KEY_DATAPROT 0x07 // Data Protect +#define KEY_BLANKCHK 0x08 // Blank Check +#define KEY_VENDSPEC 0x09 // Vendor Specific +#define KEY_COPYABORT 0x0A // Copy Abort +#define KEY_EQUAL 0x0C // Equal (Search) +#define KEY_VOLOVRFLW 0x0D // Volume Overflow +#define KEY_MISCOMP 0x0E // Miscompare (Search) +#define KEY_RESERVED 0x0F // Reserved + +//*************************************************************************** +// %%% PERIPHERAL DEVICE TYPE DEFINITIONS %%% +//*************************************************************************** +#define DTYPE_DASD 0x00 // Disk Device +#define DTYPE_SEQD 0x01 // Tape Device +#define DTYPE_PRNT 0x02 // Printer +#define DTYPE_PROC 0x03 // Processor +#define DTYPE_WORM 0x04 // Write-once read-multiple +#define DTYPE_CROM 0x05 // CD-ROM device +#define DTYPE_CDROM 0x05 // CD-ROM device +#define DTYPE_SCAN 0x06 // Scanner device +#define DTYPE_OPTI 0x07 // Optical memory device +#define DTYPE_JUKE 0x08 // Medium Changer device +#define DTYPE_COMM 0x09 // Communications device +#define DTYPE_RESL 0x0A // Reserved (low) +#define DTYPE_RESH 0x1E // Reserved (high) +#define DTYPE_UNKNOWN 0x1F // Unknown or no device type + +//*************************************************************************** +// %%% ANSI APPROVED VERSION DEFINITIONS %%% +//*************************************************************************** +#define ANSI_MAYBE 0x0 // Device may or may not be ANSI approved stand +#define ANSI_SCSI1 0x1 // Device complies to ANSI X3.131-1986 (SCSI-1) +#define ANSI_SCSI2 0x2 // Device complies to SCSI-2 +#define ANSI_RESLO 0x3 // Reserved (low) +#define ANSI_RESHI 0x7 // Reserved (high) From cb8b2b2c584e65e2dbe881a7056fa466e817777f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 22 Jul 2005 10:03:20 +0000 Subject: [PATCH 2164/4131] prevent execution of zero-byte files Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2248 --- src/dos/dos_execute.cpp | 50 +++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index abf3699d..5379f9e9 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.47 2005-07-12 18:59:31 qbix79 Exp $ */ +/* $Id: dos_execute.cpp,v 1.48 2005-07-22 10:03:20 c2woody Exp $ */ #include #include @@ -243,21 +243,31 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { DOS_CloseFile(fhandle); return false; } - /* Convert the header to correct endian, i hope this works */ - HostPt endian=(HostPt)&head; - for (i=0;i 1 MB"); - head.pages&=0x07ff; - headersize = head.headersize*16; - imagesize = head.pages*512-headersize; - if (imagesize+headersize<512) imagesize = 512-headersize; + if (len 1 MB"); + head.pages&=0x07ff; + headersize = head.headersize*16; + imagesize = head.pages*512-headersize; + if (imagesize+headersize<512) imagesize = 512-headersize; + } } if (flags!=OVERLAY) { /* Create an environment block */ @@ -284,9 +294,11 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { else memsize=maxsize; if (!DOS_AllocateMemory(&pspseg,&memsize)) E_Exit("DOS:Exec error in memory"); loadseg=pspseg+16; - if ((!iscom) & (head.minmemory == 0) & (head.maxmemory == 0)) - loadseg = (0x9e000 - imagesize)/16; //c2woody - + if (!iscom) { + /* Check if requested to load program into upper part of allocated memory */ + if ((head.minmemory == 0) && (head.maxmemory == 0)) + loadseg = ((pspseg+memsize)*0x10-imagesize)/0x10; + } } else loadseg=block.overlay.loadseg; /* Load the executable */ Bit8u * loadbuf=(Bit8u *)new Bit8u[0x10000]; From a9bb758e4fb38524af8b0d5f5803a91213da38d0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 24 Jul 2005 09:17:34 +0000 Subject: [PATCH 2165/4131] Return a copy instead of the real string. Fixes some issues with stuff getting changed in the configuration file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2249 --- src/misc/setup.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 460f00b1..bf04a7bc 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.29 2005-07-19 19:45:33 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.30 2005-07-24 09:17:34 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -132,7 +132,7 @@ float Section_prop::Get_float(const char* _propname){ const char* Section_prop::Get_string(const char* _propname){ for(it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ - return ((*tel)->GetValue())._string->c_str(); + return string(((*tel)->GetValue())._string->c_str()).c_str(); } } return ""; From df11f825b86779ec5bb4a390c2ac02931f8f8699 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 24 Jul 2005 19:04:11 +0000 Subject: [PATCH 2166/4131] undo fix. Messed up in visual C Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2250 --- src/misc/setup.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index bf04a7bc..911e040f 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.30 2005-07-24 09:17:34 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.31 2005-07-24 19:04:11 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -132,7 +132,7 @@ float Section_prop::Get_float(const char* _propname){ const char* Section_prop::Get_string(const char* _propname){ for(it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ - return string(((*tel)->GetValue())._string->c_str()).c_str(); + return ((*tel)->GetValue())._string->c_str(); } } return ""; From 206a21502ef23fb40550c5f84a358dcadc92a702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 28 Jul 2005 19:53:43 +0000 Subject: [PATCH 2167/4131] prevent crashes when unexpectedly forced to exit fullscreen mode (e.g. using windows keys in fullscreen) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2251 --- include/vga.h | 1 + src/gui/sdlmain.cpp | 15 ++++++++++++--- src/hardware/vga_draw.cpp | 4 ++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/include/vga.h b/include/vga.h index 07c06bac..f61f6e71 100644 --- a/include/vga.h +++ b/include/vga.h @@ -345,6 +345,7 @@ 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; diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 88fdb3d3..ab5990ba 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.86 2005-07-19 19:45:32 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.87 2005-07-28 19:53:42 c2woody Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -40,6 +40,7 @@ #include "support.h" #include "debug.h" #include "mapper.h" +#include "vga.h" //#define DISABLE_JOYSTICK @@ -979,8 +980,16 @@ void GFX_Events() { CaptureMouse(); SetPriority(sdl.priority.focus); } else { - if (sdl.mouse.locked) - CaptureMouse(); + if (sdl.mouse.locked) { +#ifdef WIN32 + if (sdl.desktop.fullscreen) { + VGA_KillDrawing(); + sdl.desktop.fullscreen=false; + GFX_ResetScreen(); + } +#endif + CaptureMouse(); + } SetPriority(sdl.priority.nofocus); } } diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 1fb07585..9622bd65 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -523,3 +523,7 @@ void VGA_SetupDrawing(Bitu val) { PIC_AddEvent(VGA_VerticalTimer,vga.draw.delay.vtotal); } }; + +void VGA_KillDrawing(void) { + PIC_RemoveEvents(VGA_DrawPart); +} From c6f68033c5d5b81c720aeffff72d9296352e08dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 29 Jul 2005 19:57:58 +0000 Subject: [PATCH 2168/4131] check validity of MCBs on resize and free memory functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2252 --- src/dos/dos_memory.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 8ffc6926..17c30af7 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -134,8 +134,17 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { - DOS_CompressMemory(); + if (segment < MEM_START+1) { + LOG(LOG_DOSMISC,LOG_ERROR)("Program resizes %X, take care",segment); + } + DOS_MCB mcb(segment-1); + if ((mcb.GetType()!=0x4d) && (mcb.GetType()!=0x5a)) { + DOS_SetError(DOSERR_MCB_DESTROYED); + return false; + } + + DOS_CompressMemory(); Bit16u total=mcb.GetSize(); DOS_MCB mcb_next(segment+total); if (*blocks<=total) { @@ -188,12 +197,17 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { bool DOS_FreeMemory(Bit16u segment) { //TODO Check if allowed to free this segment - if ((segment-1) < MEM_START){ + if (segment < MEM_START+1) { LOG(LOG_DOSMISC,LOG_ERROR)("Program tried to free %X ---ERROR",segment); + DOS_SetError(DOSERR_MB_ADDRESS_INVALID); return false; } DOS_MCB mcb(segment-1); + if ((mcb.GetType()!=0x4d) && (mcb.GetType()!=0x5a)) { + DOS_SetError(DOSERR_MB_ADDRESS_INVALID); + return false; + } mcb.SetPSPSeg(MCB_FREE); DOS_CompressMemory(); return true; From b4fb1af8a26a3c2e73f402a7c2a0215d35f5629c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 30 Jul 2005 09:49:29 +0000 Subject: [PATCH 2169/4131] added function to only allocate a callback. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2253 --- include/callback.h | 5 ++++- src/cpu/callback.cpp | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/include/callback.h b/include/callback.h index fc7c1ec8..5a6a5c0e 100644 --- a/include/callback.h +++ b/include/callback.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.h,v 1.12 2005-03-24 20:59:04 qbix79 Exp $ */ +/* $Id: callback.h,v 1.13 2005-07-30 09:49:28 qbix79 Exp $ */ #ifndef DOSBOX_CALLBACK_H #define DOSBOX_CALLBACK_H @@ -76,7 +76,10 @@ private: 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=0); + //Only allocate a callback number + void Allocate(CallBack_Handler handler,const char* description=0); Bit16u Get_callback(){return m_callback;} RealPt Get_RealPointer(){ return RealMake(CB_SEG,m_callback << 4);} void Set_RealVec(Bit8u vec); diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index e73dac18..41a4fefb 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.26 2005-03-25 10:12:04 qbix79 Exp $ */ +/* $Id: callback.cpp,v 1.27 2005-07-30 09:49:29 qbix79 Exp $ */ #include #include @@ -168,7 +168,6 @@ void CALLBACK_RemoveSetup(Bitu callback) { for (Bitu i = 0;i < 16;i++) { phys_writeb(CB_BASE+(callback<<4)+i ,(Bit8u) 0x00); } - CallBack_Description[callback] = 0; } @@ -215,7 +214,10 @@ CALLBACK_HandlerObject::~CALLBACK_HandlerObject(){ 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!"); + CallBack_Description[m_callback] = 0; CALLBACK_DeAllocate(m_callback); } @@ -227,6 +229,15 @@ void CALLBACK_HandlerObject::Install(CallBack_Handler handler,Bitu type,const ch CALLBACK_Setup(m_callback,handler,type,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) { From 5a46ec024142456c2d4c2797731ff197da22c485 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 30 Jul 2005 10:02:39 +0000 Subject: [PATCH 2170/4131] Rewrite of the ipx client code by h-a-l-9000 (Should support more games). Modified it a bit so ipx support can be runtime enabled/disabled. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2254 --- include/ipx.h | 53 ++- src/hardware/ipx.cpp | 810 ++++++++++++++++++++----------------- src/hardware/ipxserver.cpp | 8 +- 3 files changed, 502 insertions(+), 369 deletions(-) diff --git a/include/ipx.h b/include/ipx.h index c9ff29a7..314c80a7 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -16,9 +16,21 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: ipx.h,v 1.6 2005-07-30 10:02:39 qbix79 Exp $ */ + #ifndef DOSBOX_IPX_H #define DOSBOX_IPX_H +// Uncomment this for a lot of debug messages: +//#define IPX_DEBUGMSG + +#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 @@ -31,7 +43,6 @@ #define USEFLAG_LISTENING 0xfe #define USEFLAG_SENDING 0xff - // Completion codes #define COMP_SUCCESS 0x00 #define COMP_REMOTETERM 0xec @@ -52,7 +63,6 @@ // For Uint8 type #include "SDL_net.h" - struct PackedIP { Uint32 host; Uint16 port; @@ -78,6 +88,45 @@ struct IPXHeader { } dest, src; } GCC_ATTRIBUTE(packed); +struct fragmentDescriptor { + Bit16u offset; + Bit16u segment; + Bit16u size; +}; + +class ECBClass { +public: + RealPt ECBAddr; + bool isInESRList; + ECBClass *prevECB; + ECBClass *nextECB; + Bit8u iuflag; + + #ifdef IPX_DEBUGMSG + Bitu SerialNumber; + #endif + + ECBClass::ECBClass(Bit16u segment, Bit16u offset); + Bit16u getSocket(void); + + Bit8u getInUseFlag(void); + + void setInUseFlag(Bit8u flagval); + + void setCompletionFlag(Bit8u flagval); + + Bit16u getFragCount(void); + + void getFragDesc(Bit16u descNum, fragmentDescriptor *fragDesc); + RealPt getESRAddr(void); + + void NotifyESR(void); + + void setImmAddress(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. diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index d78f9da9..ed6bb2e6 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: ipx.cpp,v 1.7 2005-07-30 10:02:39 qbix79 Exp $ */ + #include "dosbox.h" #if C_IPX @@ -39,43 +41,33 @@ #include "timer.h" #include "SDL_net.h" #include "programs.h" +#include "pic.h" #define SOCKTABLESIZE 150 // DOS IPX driver was limited to 150 open sockets -#define DOS_MEMSEG 0xd000; -Bit32u tcpPort; -bool isIpxServer; -bool isIpxConnected; -IPaddress ipxClientIp; // IPAddress for client connection to server -IPaddress ipxServConnIp; // IPAddress for client connection to server -TCPsocket ipxTCPClientSocket; -UDPsocket ipxClientSocket; -int UDPChannel; // Channel used by UDP connection -Bit8u recvBuffer[IPXBUFFERSIZE]; // Incoming packet buffer -Bitu call_ipx; // Callback of RETF entrypoint -Bitu call_ipxint; // Callback of INT 7A entrypoint -Bitu call_ipxesr1; // Callback of ESR init routine -Bitu call_ipxesr2; // Callback of ESR return routine -Bit16u dospage; -static RealPt ipx_callback; -static RealPt ipx_intcallback; -static RealPt ipx_esrcallback; -static RealPt ipx_esrptraddr; -static RealPt processedECB; - -SDLNet_SocketSet clientSocketSet; -static bool inESR; struct ipxnetaddr { Uint8 netnum[4]; // Both are big endian Uint8 netnode[6]; } localIpxAddr; -struct fragmentDescriptor { - Bit16u offset; - Bit16u segment; - Bit16u size; -}; + + +Bit32u tcpPort; +bool isIpxServer; +bool isIpxConnected; +IPaddress ipxClientIp; // IPAddress for client connection to server +IPaddress ipxServConnIp; // IPAddress for client connection to server +//TCPsocket ipxTCPClientSocket; +UDPsocket ipxClientSocket; +int UDPChannel; // Channel used by UDP connection +Bit8u recvBuffer[IPXBUFFERSIZE]; // Incoming packet buffer + +static RealPt ipx_callback; + +SDLNet_SocketSet clientSocketSet; + +static bool ESRnotificationRequired = false; packetBuffer incomingPacket; @@ -93,113 +85,153 @@ void PackIP(IPaddress ipAddr, PackedIP *ipPack) { ipPack->port = ipAddr.port; } -class ECBClass { -public: - RealPt ECBAddr; - - ECBClass *prevECB; - ECBClass *nextECB; - - Bit16u getSocket(void) { - return swapByte(real_readw(RealSeg(ECBAddr), RealOff(ECBAddr) + 0xa)); - } - - Bit8u getInUseFlag(void) { - return real_readb(RealSeg(ECBAddr), RealOff(ECBAddr) + 0x8); - } - - void setInUseFlag(Bit8u flagval) { - real_writeb(RealSeg(ECBAddr), RealOff(ECBAddr) + 0x8, flagval); - } - - void setCompletionFlag(Bit8u flagval) { - real_writeb(RealSeg(ECBAddr), RealOff(ECBAddr) + 0x9, flagval); - } - - Bit16u getFragCount(void) { - return real_readw(RealSeg(ECBAddr), RealOff(ECBAddr) + 34); - } - - void getFragDesc(Bit16u descNum, fragmentDescriptor *fragDesc) { - Bit16u memoff = RealOff(ECBAddr) + 30 + ((descNum+1) * 6); - fragDesc->offset = real_readw(RealSeg(ECBAddr), memoff); - memoff+=2; - fragDesc->segment = real_readw(RealSeg(ECBAddr), memoff); - memoff+=2; - fragDesc->size = real_readw(RealSeg(ECBAddr), memoff); - } - - RealPt getESRAddr(void) { - return RealMake(real_readw(RealSeg(ECBAddr), RealOff(ECBAddr)+6), real_readw(RealSeg(ECBAddr), RealOff(ECBAddr)+4)); - } - - void NotifyESR(void) { - RealPt tmpAddr = getESRAddr(); - if(tmpAddr == 0) return; - if(!inESR) { - //LOG_MSG("Calling ESR"); - processedECB = ECBAddr; - inESR = true; - //LOG_MSG("Write %x to %x", real_readd(RealSeg(ECBAddr), RealOff(ECBAddr)+4), RealMake(RealSeg(ipx_esrptraddr), RealOff(ipx_esrptraddr))); - real_writed(RealSeg(ipx_esrptraddr), RealOff(ipx_esrptraddr),real_readd(RealSeg(ECBAddr), RealOff(ECBAddr)+4)); - CPU_CALL(false, RealSeg(ipx_esrcallback), RealOff(ipx_esrcallback),0); - } - } - - void setImmAddress(Bit8u *immAddr) { - Bits i; - for(i=0;i<6;i++) { - real_writeb(RealSeg(ECBAddr), RealOff(ECBAddr)+28, immAddr[i]); - } - } - -}; - ECBClass *ECBList; // Linked list of ECB's +ECBClass* ESRList; // ECBs waiting to be ESR notified -ECBClass * CreateECB(RealPt useAddr) { - ECBClass *tmpECB; - tmpECB = new ECBClass(); +#ifdef IPX_DEBUGMSG +Bitu ECBSerialNumber = 0; +Bitu ECBAmount = 0; +#endif + + +ECBClass::ECBClass(Bit16u segment, Bit16u offset) { + ECBAddr = RealMake(segment, offset); - tmpECB->ECBAddr = useAddr; - tmpECB->prevECB = NULL; - tmpECB->nextECB = NULL; +#ifdef IPX_DEBUGMSG + SerialNumber = ECBSerialNumber; + ECBSerialNumber++; + ECBAmount++; + + LOG_MSG("ECB: SN%7d created. Number of ECBs: %3d, ESR %4x:%4x, ECB %4x:%4x", + SerialNumber,ECBAmount, + real_readw(RealSeg(ECBAddr), + RealOff(ECBAddr)+6), + real_readw(RealSeg(ECBAddr), + RealOff(ECBAddr)+4),segment,offset); +#endif + isInESRList = false; + prevECB = NULL; + nextECB = NULL; - if (ECBList == NULL) { - ECBList = tmpECB; - } else { + if (ECBList == NULL) + ECBList = this; + else { // Transverse the list until we hit the end - ECBClass *useECB; - useECB = ECBList; - while(useECB->nextECB != NULL) { + ECBClass *useECB = ECBList; + + while(useECB->nextECB != NULL) useECB = useECB->nextECB; + + useECB->nextECB = this; + this->prevECB = useECB; + } +} + +Bit16u ECBClass::getSocket(void) { + return swapByte(real_readw(RealSeg(ECBAddr), RealOff(ECBAddr) + 0xa)); +} + +Bit8u ECBClass::getInUseFlag(void) { + return real_readb(RealSeg(ECBAddr), RealOff(ECBAddr) + 0x8); +} + +void ECBClass::setInUseFlag(Bit8u flagval) { + iuflag = flagval; + real_writeb(RealSeg(ECBAddr), RealOff(ECBAddr) + 0x8, flagval); +} + +void ECBClass::setCompletionFlag(Bit8u flagval) { + real_writeb(RealSeg(ECBAddr), RealOff(ECBAddr) + 0x9, flagval); +} + +Bit16u ECBClass::getFragCount(void) { + return real_readw(RealSeg(ECBAddr), RealOff(ECBAddr) + 34); +} + +void ECBClass::getFragDesc(Bit16u descNum, fragmentDescriptor *fragDesc) { + Bit16u memoff = RealOff(ECBAddr) + 30 + ((descNum+1) * 6); + fragDesc->offset = real_readw(RealSeg(ECBAddr), memoff); + memoff += 2; + fragDesc->segment = real_readw(RealSeg(ECBAddr), memoff); + memoff += 2; + fragDesc->size = real_readw(RealSeg(ECBAddr), memoff); +} + +RealPt ECBClass::getESRAddr(void) { + return RealMake(real_readw(RealSeg(ECBAddr), + RealOff(ECBAddr)+6), + real_readw(RealSeg(ECBAddr), + RealOff(ECBAddr)+4)); +} + +void ECBClass::NotifyESR(void) { + Bit32u ESRval = real_readd(RealSeg(ECBAddr), RealOff(ECBAddr)+4); + + if(ESRval) { +#ifdef IPX_DEBUGMSG + LOG_MSG("ECB: SN%7d to be notified.", SerialNumber); +#endif + // take the ECB out of the current list + if(prevECB == NULL) { // was the first in the list + ECBList = nextECB; + if(ECBList != NULL) ECBList->prevECB = NULL; + } else { // not the first + prevECB->nextECB = nextECB; + if(nextECB != NULL) nextECB->prevECB = prevECB; } - useECB->nextECB = tmpECB; - tmpECB->prevECB = useECB; - } - return tmpECB; + nextECB = NULL; + // put it to the notification queue + if(ESRList==NULL) { + ESRList = this; + prevECB = NULL; + } else {// put to end of ESR list + ECBClass* useECB = ESRList; + + while(useECB->nextECB != NULL) + useECB = useECB->nextECB; + + useECB->nextECB = this; + prevECB = useECB; + } + isInESRList = true; + //LOG_MSG("ECB put to notification list"); + PIC_ActivateIRQ(11); + } + // this one does not want to be notified, delete it right away + else delete this; } -void DeleteECB(ECBClass * useECB) { - if(useECB == NULL) return; +void ECBClass::setImmAddress(Bit8u *immAddr) { + for(Bitu i=0;i<6;i++) + real_writeb(RealSeg(ECBAddr), RealOff(ECBAddr)+28, immAddr[i]); +} - if(useECB->prevECB == NULL) { - ECBList = useECB->nextECB; - if(ECBList != NULL) ECBList->prevECB = NULL; +ECBClass::~ECBClass() { +#ifdef IPX_DEBUGMSG + ECBAmount--; + LOG_MSG("ECB: SN%7d destroyed. Remaining ECBs: %3d", SerialNumber,ECBAmount); +#endif + + if(isInESRList) { + // in ESR list, always the first element is deleted. + ESRList=nextECB; } else { - useECB->prevECB->nextECB = useECB->nextECB; - if(useECB->nextECB != NULL) useECB->nextECB->prevECB = useECB->prevECB; + if(prevECB == NULL) { // was the first in the list + ECBList = nextECB; + if(ECBList != NULL) ECBList->prevECB = NULL; + } else { // not the first + prevECB->nextECB = nextECB; + if(nextECB != NULL) nextECB->prevECB = prevECB; + } } - delete useECB; } -Bit16u socketCount; -Bit16u opensockets[SOCKTABLESIZE]; +static Bit16u socketCount; +static Bit16u opensockets[SOCKTABLESIZE]; static bool sockInUse(Bit16u sockNum) { - Bit16u i; - for(i=0;i= SOCKTABLESIZE) { @@ -236,11 +268,12 @@ static void OpenSocket(void) { reg_al = 0x00; // Success reg_dx = swapByte(sockNum); // Convert back to big-endian - } static void CloseSocket(void) { Bit16u sockNum, i; + ECBClass* tmpECB = ECBList; + ECBClass* tmp2ECB = ECBList; sockNum = swapByte(reg_dx); if(!sockInUse(sockNum)) return; @@ -253,17 +286,34 @@ static void CloseSocket(void) { } } --socketCount; + + // delete all ECBs of that socket + while(tmpECB!=0) { + tmp2ECB = tmpECB->nextECB; + if(tmpECB->getSocket()==sockNum) { + tmpECB->setCompletionFlag(COMP_CANCELLED); + delete tmpECB; + } + tmpECB = tmp2ECB; + } } -static bool IPX_Multiplex(void) -{ +//static RealPt IPXVERpointer; + +static bool IPX_Multiplex(void) { if(reg_ax != 0x7a00) return false; reg_al = 0xff; SegSet16(es,RealSeg(ipx_callback)); reg_di = RealOff(ipx_callback); + + //reg_bx = RealOff(IPXVERpointer); + //reg_cx = RealSeg(ipx_callback); return true; } +//static void sendPackets(); +static void sendPacket(ECBClass* sendecb); + static void handleIpxRequest(void) { ECBClass *tmpECB; @@ -276,35 +326,64 @@ static void handleIpxRequest(void) { LOG_MSG("IPX: Close socket %4x", swapByte(reg_dx)); CloseSocket(); break; + case 0x0002: // get local target + reg_al=0xfa; // fail + break; + case 0x0003: // Send packet if(!incomingPacket.connected) { - tmpECB = CreateECB(RealMake(SegValue(es), reg_si)); + tmpECB = new ECBClass(SegValue(es),reg_si);//CreateECB(RealMake(SegValue(es), reg_si),true); tmpECB->setInUseFlag(USEFLAG_AVAILABLE); tmpECB->setCompletionFlag(COMP_UNDELIVERABLE); - DeleteECB(tmpECB); + delete tmpECB; // not notify? + //DeleteECB(tmpECB); reg_al = 0xff; // Failure } else { - tmpECB = CreateECB(RealMake(SegValue(es), reg_si)); + tmpECB = new ECBClass(SegValue(es),reg_si);//CreateECB(RealMake(SegValue(es), reg_si),true); tmpECB->setInUseFlag(USEFLAG_SENDING); + //LOG_MSG("IPX: Sending packet on %4x", tmpECB->getSocket()); reg_al = 0x00; // Success + sendPacket(tmpECB); } - //LOG_MSG("IPX: Sending packet on %4x", tmpECB->getSocket()); + + //sendPackets(); break; case 0x0004: // Listen for packet - tmpECB = CreateECB(RealMake(SegValue(es), reg_si)); + tmpECB = new ECBClass(SegValue(es),reg_si);//CreateECB(RealMake(SegValue(es), reg_si),false); if(!sockInUse(tmpECB->getSocket())) { reg_al = 0xff; // Socket is not open tmpECB->setInUseFlag(USEFLAG_AVAILABLE); tmpECB->setCompletionFlag(COMP_HARDWAREERROR); - DeleteECB(tmpECB); + delete tmpECB; } else { reg_al = 0x00; // Success tmpECB->setInUseFlag(USEFLAG_LISTENING); - //LOG_MSG("IPX: Listen for packet on 0x%4x - ESR address %4x:%4x", tmpECB->getSocket(), RealSeg(tmpECB->getESRAddr()), RealOff(tmpECB->getESRAddr())); + /*LOG_MSG("IPX: Listen for packet on 0x%4x - ESR address %4x:%4x", + tmpECB->getSocket(), + RealSeg(tmpECB->getESRAddr()), + RealOff(tmpECB->getESRAddr()));*/ } break; + case 0x0006: // cancel operation + { + RealPt ecbaddress = RealMake(SegValue(es),reg_si); + ECBClass* tmpECB= ECBList; + ECBClass* tmp2ECB; + while(tmpECB) { + tmp2ECB=tmpECB->nextECB; + if(tmpECB->ECBAddr == ecbaddress) { + delete tmpECB; // TODO: invoke flags... check if it can be canceled +#ifdef IPX_DEBUGMSG + LOG_MSG("IPX: ECB canceled."); +#endif + } + tmpECB=tmp2ECB; + } + reg_al=0; // Success + break; + } case 0x0008: // Get interval marker // ???? break; @@ -316,13 +395,18 @@ static void handleIpxRequest(void) { addrptr = (Bit8u *)&localIpxAddr; for(i=0;i<10;i++) { - real_writeb(SegValue(es),reg_si+i,addrptr[i]); + real_writeb(SegValue(es),reg_si+i,addrptr[i]); } break; } case 0x000a: // Relinquish control // Idle thingy break; + case 0x0010: // SPX install check + { + reg_al=0; // SPX not installed + break; + } default: LOG_MSG("Unhandled IPX function: %4x", reg_bx); break; @@ -343,12 +427,9 @@ Bitu IPX_IntHandler(void) { } static void disconnectServer(bool unexpected) { - // There is no Timer remove code, hence this has to be done manually incomingPacket.connected = false; - if(unexpected) LOG_MSG("IPX: Server disconnected unexpectedly"); - } static void pingAck(IPaddress retAddr) { @@ -375,7 +456,6 @@ static void pingAck(IPaddress retAddr) { regPacket.channel = UDPChannel; result = SDLNet_UDP_Send(ipxClientSocket, regPacket.channel, ®Packet); - } static void pingSend(void) { @@ -406,7 +486,6 @@ static void pingSend(void) { if(!result) { LOG_MSG("IPX: SDLNet_UDP_Send: %s\n", SDLNet_GetError()); } - } static void receivePacket(Bit8u *buffer, Bit16s bufSize) { @@ -433,9 +512,9 @@ static void receivePacket(Bit8u *buffer, Bit16s bufSize) { } } - useECB = ECBList; - while(useECB != NULL) { + while(useECB != NULL) + { nextECB = useECB->nextECB; if(useECB->getInUseFlag() == USEFLAG_LISTENING) { if(useECB->getSocket() == useSocket) { @@ -451,10 +530,13 @@ static void receivePacket(Bit8u *buffer, Bit16s bufSize) { useECB->setCompletionFlag(COMP_SUCCESS); useECB->setImmAddress(&buffer[22]); // Write in source node hostaddr = *((Bit32u *)&buffer[24]); - - //LOG_MSG("IPX: Received packet of %d bytes from %d.%d.%d.%d (%x CRC)", bufSize, CONVIP(hostaddr), packetCRC(&buffer[30], bufSize-30)); + +#ifdef IPX_DEBUGMSG + LOG_MSG("IPX: Received packet of %d bytes from %d.%d.%d.%d (%x CRC)", bufSize, CONVIP(hostaddr), packetCRC(&buffer[30], bufSize-30)); +#endif + useECB->NotifyESR(); - DeleteECB(useECB); + //DeleteECB(useECB); return; } } @@ -462,35 +544,51 @@ static void receivePacket(Bit8u *buffer, Bit16s bufSize) { if(bufoffset < bufSize) { useECB->setCompletionFlag(COMP_MALFORMED); useECB->NotifyESR(); - DeleteECB(useECB); + //DeleteECB(useECB); return; } } } useECB = nextECB; } - +#ifdef IPX_DEBUGMSG + LOG_MSG("IPX: RX Packet loss!"); +#endif } -static void sendPacketsTCP(void) { - ECBClass *useECB; - ECBClass *nextECB; +static void IPX_UDPClientLoop(void) { + int numrecv; + UDPpacket inPacket; + inPacket.data = (Uint8 *)recvBuffer; + inPacket.maxlen = IPXBUFFERSIZE; + inPacket.channel = UDPChannel; + + //do + //{ + // Its amazing how much simpler UDP is than TCP + numrecv = SDLNet_UDP_Recv(ipxClientSocket, &inPacket); + if(numrecv) receivePacket(inPacket.data, inPacket.len); + + //}while(numrecv>0); + +} +// don't waste time scanning the list +static void sendPacket(ECBClass* sendecb) { char outbuffer[IPXBUFFERSIZE]; fragmentDescriptor tmpFrag; Bit16u i, fragCount,t; Bit16s packetsize; Bit16u *wordptr; Bits result; - - useECB = ECBList; - while(useECB != NULL) { - nextECB = useECB->nextECB; - if(useECB->getInUseFlag() == USEFLAG_SENDING) { - useECB->setInUseFlag(USEFLAG_AVAILABLE); + UDPpacket outPacket; + + //if(useECB->getInUseFlag() == USEFLAG_SENDING) + // { + sendecb->setInUseFlag(USEFLAG_AVAILABLE); packetsize = 0; - fragCount = useECB->getFragCount(); + fragCount = sendecb->getFragCount(); for(i=0;igetFragDesc(i,&tmpFrag); + sendecb->getFragDesc(i,&tmpFrag); if(i==0) { // Fragment containing IPX header // Must put source address into header @@ -507,127 +605,46 @@ static void sendPacketsTCP(void) { packetsize++; if(packetsize>=IPXBUFFERSIZE) { LOG_MSG("IPX: Packet size to be sent greater than %d bytes.", IPXBUFFERSIZE); - useECB->setCompletionFlag(COMP_MALFORMED); - useECB->NotifyESR(); - DeleteECB(useECB); - goto nextECB; + sendecb->setCompletionFlag(COMP_UNDELIVERABLE); + sendecb->NotifyESR(); + //DeleteECB(useECB); + return; } } } - result = SDLNet_TCP_Send(ipxTCPClientSocket, &packetsize, 2); - if(result != 2) { - useECB->setCompletionFlag(COMP_UNDELIVERABLE); - useECB->NotifyESR(); - DeleteECB(useECB); - disconnectServer(true); - return; - } // Add length and source socket to IPX header wordptr = (Bit16u *)&outbuffer[0]; // Blank CRC - wordptr[0] = 0xffff; + wordptr[0] = 0xffff; // Length wordptr[1] = swapByte(packetsize); // Source socket - wordptr[14] = swapByte(useECB->getSocket()); + wordptr[14] = swapByte(sendecb->getSocket()); - result = SDLNet_TCP_Send(ipxTCPClientSocket, &outbuffer[0], packetsize); - if(result != packetsize) { - useECB->setCompletionFlag(COMP_UNDELIVERABLE); - useECB->NotifyESR(); - DeleteECB(useECB); + outPacket.channel = UDPChannel; + outPacket.data = (Uint8 *)&outbuffer[0]; + outPacket.len = packetsize; + outPacket.maxlen = packetsize; + // Since we're using a channel, we won't send the IP address again + result = SDLNet_UDP_Send(ipxClientSocket, UDPChannel, &outPacket); + if(result == 0) { + LOG_MSG("IPX: Could not send packet: %s", SDLNet_GetError()); + sendecb->setCompletionFlag(COMP_UNDELIVERABLE); + sendecb->NotifyESR(); + //DeleteECB(useECB); disconnectServer(true); - return; - } - useECB->setInUseFlag(USEFLAG_AVAILABLE); - useECB->setCompletionFlag(COMP_SUCCESS); - useECB->NotifyESR(); - DeleteECB(useECB); - - } -nextECB: - - useECB = nextECB; - } - -} - - -static void IPX_TCPClientLoop(void) { - Bits result; - - // Check for incoming packets - SDLNet_CheckSockets(clientSocketSet,0); - - if(SDLNet_SocketReady(ipxClientSocket)) { - if(!incomingPacket.inPacket) { - if(!incomingPacket.waitsize) { - result = SDLNet_TCP_Recv(ipxTCPClientSocket, &incomingPacket.packetSize, 2); - if(result!=2) { - if(result>0) { - incomingPacket.waitsize = true; - goto finishReceive; - } else { - disconnectServer(true); - goto finishReceive; - } - } - incomingPacket.packetRead = 0; + //return; } else { - Bit8u * nextchar; - nextchar = (Bit8u *)&incomingPacket.packetSize; - nextchar++; - result = SDLNet_TCP_Recv(ipxTCPClientSocket, nextchar, 1); - if(result!=1) { - if(result>0) { - LOG_MSG("IPX: Packet overrun"); - } else { - disconnectServer(true); - goto finishReceive; - } - } - incomingPacket.waitsize = false; - incomingPacket.packetRead = 0; + sendecb->setInUseFlag(USEFLAG_AVAILABLE); + sendecb->setCompletionFlag(COMP_SUCCESS); +#ifdef IPX_DEBUGMSG + LOG_MSG("Packet sent: size: %d",packetsize); +#endif + sendecb->NotifyESR(); } - incomingPacket.inPacket = true; - } - result = SDLNet_TCP_Recv(ipxTCPClientSocket, &incomingPacket.buffer[incomingPacket.packetRead], incomingPacket.packetSize); - if (result>0) { - incomingPacket.packetRead+=result; - incomingPacket.packetSize-=result; - if(incomingPacket.packetSize<=0) { - // IPX packet is complete. Now interpret IPX header and try to match to listening ECB - receivePacket(&incomingPacket.buffer[0], incomingPacket.packetRead); - incomingPacket.inPacket = false; - } - } else { - // Clost active socket - disconnectServer(true); - } - - } - -finishReceive:; - - + //} } - -static void IPX_UDPClientLoop(void) { - int numrecv; - UDPpacket inPacket; - inPacket.data = (Uint8 *)recvBuffer; - inPacket.maxlen = IPXBUFFERSIZE; - inPacket.channel = UDPChannel; - - // Its amazing how much simpler UDP is than TCP - numrecv = SDLNet_UDP_Recv(ipxClientSocket, &inPacket); - if(numrecv) { - receivePacket(inPacket.data, inPacket.len); - } - -} - static void sendPackets() { ECBClass *useECB; ECBClass *nextECB; @@ -666,7 +683,7 @@ static void sendPackets() { LOG_MSG("IPX: Packet size to be sent greater than %d bytes.", IPXBUFFERSIZE); useECB->setCompletionFlag(COMP_UNDELIVERABLE); useECB->NotifyESR(); - DeleteECB(useECB); + //DeleteECB(useECB); goto nextECB; } } @@ -675,7 +692,7 @@ static void sendPackets() { // Add length and source socket to IPX header wordptr = (Bit16u *)&outbuffer[0]; // Blank CRC - wordptr[0] = 0xffff; + wordptr[0] = 0xffff; // Length wordptr[1] = swapByte(packetsize); // Source socket @@ -691,28 +708,44 @@ static void sendPackets() { LOG_MSG("IPX: Could not send packet: %s", SDLNet_GetError()); useECB->setCompletionFlag(COMP_UNDELIVERABLE); useECB->NotifyESR(); - DeleteECB(useECB); + //DeleteECB(useECB); disconnectServer(true); - return; + //return; + } else { + useECB->setInUseFlag(USEFLAG_AVAILABLE); + useECB->setCompletionFlag(COMP_SUCCESS); + //LOG_MSG("Packet sent: size: %d",packetsize); + useECB->NotifyESR(); + //DeleteECB(useECB); } - useECB->setInUseFlag(USEFLAG_AVAILABLE); - useECB->setCompletionFlag(COMP_SUCCESS); - useECB->NotifyESR(); - DeleteECB(useECB); - } nextECB: - useECB = nextECB; } - } +//RealPt ESRJmpDisplacementAddr; +//RealPt ESRTargetAddr; +//RealPt ESRDummyRetAddr; +/* +void repeatESR(bool rep) +{ + if(rep) real_writeb( + RealSeg(ESRJmpDisplacementAddr), + RealOff(ESRJmpDisplacementAddr), + (Bit8u)0xF5); + else real_writeb( + RealSeg(ESRJmpDisplacementAddr), + RealOff(ESRJmpDisplacementAddr), + (Bit8u)0); +} +*/ +ECBClass* ESRHANDLER_useECB; static void IPX_ClientLoop(void) { - IPX_UDPClientLoop(); + IPX_UDPClientLoop(); // Send outgoing packets - sendPackets(); + //sendPackets(); } @@ -802,14 +835,12 @@ bool ConnectToServer(char *strAddr) { LOG_MSG("IPX: Connected to server. IPX address is %d:%d:%d:%d:%d:%d", CONVIPX(localIpxAddr.netnode)); - incomingPacket.connected = true; TIMER_AddTickHandler(&IPX_ClientLoop); return true; } } else { LOG_MSG("IPX: Unable to open socket"); - } } else { LOG_MSG("IPX: Unable resolve connection to server"); @@ -1061,9 +1092,6 @@ public: } return; } - - - } /* @@ -1086,103 +1114,161 @@ static void IPXNET_ProgramStart(Program * * make) { } Bitu IPX_ESRHandler1(void) { - CPU_Push32(reg_flags); - CPU_Push32(reg_eax);CPU_Push32(reg_ecx);CPU_Push32(reg_edx);CPU_Push32(reg_ebx); - CPU_Push32(reg_ebp);CPU_Push32(reg_esi);CPU_Push32(reg_edi); - CPU_Push16(SegValue(ds)); CPU_Push16(SegValue(es)); - - SegSet16(es, RealSeg(processedECB)); - reg_si = RealOff(processedECB); - reg_al = 0xff; - //LOG_MSG("ESR Callback 1"); +#ifdef IPX_DEBUGMSG + LOG_MSG("ESRhandler entered" ); +#endif + while(ESRList!=NULL) { +#ifdef IPX_DEBUGMSG + LOG_MSG("ECB: SN%7d notified.", ESRList->SerialNumber); +#endif + + // setup registers + SegSet16(es, RealSeg(ESRList->ECBAddr)); + reg_si = RealOff(ESRList->ECBAddr); + reg_al = 0xff; + + CALLBACK_RunRealFar(RealSeg(ESRList->getESRAddr()), RealOff(ESRList->getESRAddr())); + + delete ESRList; + } // while +// PIC_DeActivateIRQ(11); + IO_WriteB(0xa0,0x63); //EOI11 + IO_WriteB(0x20,0x62); //EOI2 +// IO_WriteB(0xa0,0x20); //EOI + //IO_WriteB(0x20,0x20); //EOI + +#ifdef IPX_DEBUGMSG + LOG_MSG("ESR loop done."); +#endif + return CBRET_NONE; } -Bitu IPX_ESRHandler2(void) { - SegSet16(es, CPU_Pop16()); SegSet16(ds, CPU_Pop16()); - reg_edi=CPU_Pop32();reg_esi=CPU_Pop32();reg_ebp=CPU_Pop32(); - reg_ebx=CPU_Pop32();reg_edx=CPU_Pop32();reg_ecx=CPU_Pop32();reg_eax=CPU_Pop32(); - reg_flags=CPU_Pop32(); +void VFILE_Remove(const char *name); - //LOG_MSG("Leaving ESR"); - inESR = false; +class IPX: public Module_base { +private: + CALLBACK_HandlerObject callback_ipx; + CALLBACK_HandlerObject callback_esr; + CALLBACK_HandlerObject callback_ipxint; + RealPt old_73_vector; + static Bit16u dospage; +public: + IPX(Section* configuration):Module_base(configuration) { + Section_prop * section = static_cast(configuration); + if(!section->Get_bool("ipx")) return; + if(!SDLNetInited) { + if(SDLNet_Init() == -1){ + LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); + return; + } + SDLNetInited = true; + } - return CBRET_NONE; -} + ECBList = NULL; + ESRList = NULL; + isIpxServer = false; + isIpxConnected = false; + IPX_NetworkInit(); -bool IPX_ESRSetupHook(Bitu callback1, CallBack_Handler handler1, Bitu callback2, CallBack_Handler handler2, RealPt *ptrAddr) { - PhysPt phyDospage; - phyDospage = PhysMake(dospage,0); + DOS_AddMultiplexHandler(IPX_Multiplex); - // Inital callback routine (should save registers, etc.) - phys_writeb(phyDospage+0,(Bit8u)0xFA); //CLI - phys_writeb(phyDospage+1,(Bit8u)0xFE); //GRP 4 - phys_writeb(phyDospage+2,(Bit8u)0x38); //Extra Callback instruction - phys_writew(phyDospage+3,callback1); //The immediate word - phys_writeb(phyDospage+5,(Bit8u)0x9a); //CALL Ap - // 0x6, 0x7, 0x8, 0x9 = address of called routine - *ptrAddr = RealMake(dospage, 6); - phys_writed(phyDospage+6,(Bit32u)0x00000000); // Called address - phys_writeb(phyDospage+0xa,(Bit8u)0xFE); //GRP 4 - phys_writeb(phyDospage+0xb,(Bit8u)0x38); //Extra Callback instruction - phys_writew(phyDospage+0xc,callback2); //The immediate word - phys_writeb(phyDospage+0xe,(Bit8u)0xFB); //STI - phys_writeb(phyDospage+0xf,(Bit8u)0xCB); //A RETF Instruction + callback_ipx.Install(&IPX_Handler,CB_RETF,"IPX Handler"); + ipx_callback = callback_ipx.Get_RealPointer(); - CallBack_Handlers[callback1]=handler1; - CallBack_Handlers[callback2]=handler2; - return true; + callback_ipxint.Install(&IPX_IntHandler,CB_IRET,"IPX (int 7a)"); + callback_ipxint.Set_RealVec(0x7a); + + callback_esr.Allocate(&IPX_ESRHandler1,"IPX_ESR"); + Bit16u call_ipxesr1 = callback_esr.Get_callback(); + + if(!dospage) dospage = DOS_GetMemory(2); // can not be freed yet + + PhysPt phyDospage = PhysMake(dospage,0); + +#ifdef IPX_DEBUGMSG + LOG_MSG("IPX INT address: %x", ipx_intcallback); + LOG_MSG("ESR callback address: %x, HandlerID %d", phyDospage,call_ipxesr1); +#endif + //save registers + phys_writeb(phyDospage+0,(Bit8u)0xFA); // CLI + phys_writeb(phyDospage+1,(Bit8u)0x60); // PUSHA + phys_writeb(phyDospage+2,(Bit8u)0x1E); // PUSH DS + phys_writeb(phyDospage+3,(Bit8u)0x06); // PUSH ES + phys_writeb(phyDospage+4,(Bit8u)0x0F); // PUSH.. + phys_writeb(phyDospage+5,(Bit8u)0xA0); // FS + phys_writeb(phyDospage+6,(Bit8u)0x0F); // PUSH.. + phys_writeb(phyDospage+7,(Bit8u)0xA8); // GS + + // callback + phys_writeb(phyDospage+8,(Bit8u)0xFE); // GRP 4 + phys_writeb(phyDospage+9,(Bit8u)0x38); // Extra Callback instruction + phys_writew(phyDospage+10,call_ipxesr1); // Callback identifier + + // register recreation + phys_writeb(phyDospage+12,(Bit8u)0x0F);// POP.. + phys_writeb(phyDospage+13,(Bit8u)0xA9); // GS + phys_writeb(phyDospage+14,(Bit8u)0x0F);// POP.. + phys_writeb(phyDospage+15,(Bit8u)0xA1); // FS + phys_writeb(phyDospage+16,(Bit8u)0x07); // POP ES + phys_writeb(phyDospage+17,(Bit8u)0x1F); // POP DS + phys_writeb(phyDospage+18,(Bit8u)0x61); //POPA + phys_writeb(phyDospage+19,(Bit8u)0xCF); //IRET: restores flags, CS, IP + + // IPX version 2.12 + //phys_writeb(phyDospage+27,(Bit8u)0x2); + //phys_writeb(phyDospage+28,(Bit8u)0x12); + //IPXVERpointer = RealMake(dospage,27); + + RealPt ESRRoutineBase = RealMake(dospage, 0); + + // Interrupt enabling + RealSetVec(0x73,ESRRoutineBase,old_73_vector); // IRQ11 + Bit8u irqmask=IO_ReadB(0xa1); + irqmask &= ~8; // enable IRQ11 + IO_WriteB(0xa1,irqmask); + + PROGRAMS_MakeFile("IPXNET.COM",IPXNET_ProgramStart); + } + + ~IPX() { + Section_prop * section = static_cast(m_configuration); + if(!section->Get_bool("ipx")) return; + + if(isIpxServer) { + isIpxServer = false; + DisconnectFromServer(); + IPX_StopServer(); + } + disconnectServer(false); + + DOS_DelMultiplexHandler(IPX_Multiplex); + RealSetVec(0x73,old_73_vector); + Bit8u irqmask=IO_ReadB(0xa1); + irqmask |= 8; // disable IRQ11 + IO_WriteB(0xa1,irqmask); + + PhysPt phyDospage = PhysMake(dospage,0); + for(Bitu i = 0;i < 32;i++) + phys_writeb(phyDospage+i,(Bit8u)0x00); + + VFILE_Remove("IPXNET.COM"); + } +}; + +static IPX* test; + +void IPX_ShutDown(Section* sec) { + delete test; } void IPX_Init(Section* sec) { - Section_prop * section=static_cast(sec); - - if(!section->Get_bool("ipx")) return; - - if(!SDLNetInited) { - if(SDLNet_Init()==-1) { - LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); - return; - } - SDLNetInited = true; - } - - ECBList = NULL; - - isIpxServer = false; - isIpxConnected = false; - - IPX_NetworkInit(); - - inESR = false; - - DOS_AddMultiplexHandler(IPX_Multiplex); - call_ipx=CALLBACK_Allocate(); - CALLBACK_Setup(call_ipx,&IPX_Handler,CB_RETF); - ipx_callback=CALLBACK_RealPointer(call_ipx); - - call_ipxint=CALLBACK_Allocate(); - CALLBACK_Setup(call_ipxint,&IPX_IntHandler,CB_IRET); - ipx_intcallback=CALLBACK_RealPointer(call_ipxint); - - call_ipxesr1=CALLBACK_Allocate(); - call_ipxesr2=CALLBACK_Allocate(); - //CALLBACK_SetupFarCall(call_ipxesr1, &IPX_ESRHandler1, call_ipxesr2, &IPX_ESRHandler2, &ipx_esrptraddr); - dospage = DOS_GetMemory(1); - IPX_ESRSetupHook(call_ipxesr1, &IPX_ESRHandler1, call_ipxesr2, &IPX_ESRHandler2, &ipx_esrptraddr); - // Allocate 16 bytes of memory from the DOS system area at 0xd000 - ipx_esrcallback=RealMake(dospage,0); - //CALLBACK_RealPointer(call_ipxesr1); - - RealSetVec(0x7a,ipx_intcallback); - PROGRAMS_MakeFile("IPXNET.COM",IPXNET_ProgramStart); - - //if(isIpxServer) { - // Auto-connect to server - // ConnectToServer("localhost"); - //} - + test = new IPX(sec); + sec->AddDestroyFunction(&IPX_ShutDown,true); } +//Initialize static members; +Bit16u IPX::dospage = 0; + #endif diff --git a/src/hardware/ipxserver.cpp b/src/hardware/ipxserver.cpp index b0cc6831..98f64dbd 100644 --- a/src/hardware/ipxserver.cpp +++ b/src/hardware/ipxserver.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: ipxserver.cpp,v 1.5 2005-07-30 10:02:39 qbix79 Exp $ */ + #include "dosbox.h" #if C_IPX @@ -85,7 +87,7 @@ static void sendIPXPacket(Bit8u *buffer, Bit16s bufSize) { if(desthost == 0xffffffff) { // Broadcast for(i=0;idest.socket) == 0x2) { - - // Null destination node means its a server registration packet if(tmpHeader->dest.addr.byIP.host == 0x0) { UnpackIP(tmpHeader->src.addr.byIP, &tmpAddr); @@ -197,8 +197,6 @@ static void IPX_ServerLoop() { return; } } - - } } From 01adaac4c7fc19f26563521f2ef4b5928a55cab1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 30 Jul 2005 10:11:40 +0000 Subject: [PATCH 2171/4131] Show cs:ip on illegal read/write Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2255 --- src/hardware/memory.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 1795de5b..3f30f55b 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -16,13 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: memory.cpp,v 1.37 2005-03-25 11:52:32 qbix79 Exp $ */ +/* $Id: memory.cpp,v 1.38 2005-07-30 10:11:40 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" #include "inout.h" #include "setup.h" #include "paging.h" +#include "regs.h" #define PAGES_IN_BLOCK ((1024*1024)/MEM_PAGE_SIZE) #define MAX_MEMORY 64 @@ -60,11 +61,11 @@ public: flags=PFLAG_INIT|PFLAG_NOCODE; } Bitu readb(PhysPt addr) { - LOG_MSG("Illegal read from %x",addr); + LOG_MSG("Illegal read from %x, CS:IP %8x:%8x",addr,SegValue(cs),reg_eip); return 0; } void writeb(PhysPt addr,Bitu val) { - LOG_MSG("Illegal write to %x",addr); + LOG_MSG("Illegal write to %x, CS:IP %8x:%8x",addr,SegValue(cs),reg_eip); } HostPt GetHostPt(Bitu phys_page) { return 0; @@ -530,4 +531,12 @@ void MEM_Init(Section * sec) { /* shutdown function */ test = new MEMORY(sec); sec->AddDestroyFunction(&MEM_ShutDown); + + // initialize interrupt handlers to 0 + // this makes availible interrupts detectable even in compiler debug mode + // tyrian network helper app is suffering from this + // + // DISABLED IT BY DEFAULT. (qbix79). But the code is there in case + // somebody needs it + //for(Bitu icntr = 0; icntr <0xFF; icntr++) RealSetVec(icntr,0); } From 4b6fd3c481d6d4513da45259c9fc7389070acdce Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 30 Jul 2005 10:13:24 +0000 Subject: [PATCH 2172/4131] Some messages when dealing with prot mode debug points.(h-a-l-9000) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2256 --- src/debug/debug.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 57119421..0d4ea81d 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.64 2005-07-19 19:45:15 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.65 2005-07-30 10:13:24 qbix79 Exp $ */ #include #include @@ -537,6 +537,9 @@ void CBreakpoint::ShowList(void) } else if (bp->GetType()==BKPNT_MEMORY) { DEBUG_ShowMsg("%02X. BPMEM %04X:%04X (%02X)\n",nr,bp->GetSegment(),bp->GetOffset(),bp->GetValue()); nr++; + } else if (bp->GetType()==BKPNT_MEMORY_PROT) { + DEBUG_ShowMsg("%02X. BPPM %04X:%08X (%02X)\n",nr,bp->GetSegment(),bp->GetOffset(),bp->GetValue()); + nr++; }; } }; @@ -965,8 +968,11 @@ bool ParseCommand(char* str) Bit16u seg = (Bit16u)GetHexValue(found,found);found++; // skip ":" Bit32u ofs = GetHexValue(found,found); CBreakpoint* bp = CBreakpoint::AddMemBreakpoint(seg,ofs); - if (bp) bp->SetType(BKPNT_MEMORY_PROT); - DEBUG_ShowMsg("DEBUG: Set prot-mode memory breakpoint at %04X:%08X\n",seg,ofs); + if (bp) + { + bp->SetType(BKPNT_MEMORY_PROT); + DEBUG_ShowMsg("DEBUG: Set prot-mode memory breakpoint at %04X:%08X\n",seg,ofs); + } return true; } found = strstr(str,"BPLM "); From a5252330f7381b4497e7964fa5531ae95b9d5d04 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 30 Jul 2005 14:41:31 +0000 Subject: [PATCH 2173/4131] Add patch 1151453 from h-a-l-9000. Improves softmodem and directserial supports. Adds a dummy serial class as well and makes the serial ports runtime changable Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2257 --- configure.in | 1 + include/bios.h | 4 +- include/serialport.h | 369 ++++-- src/Makefile.am | 2 +- src/dosbox.cpp | 67 +- src/hardware/Makefile.am | 7 +- src/hardware/directserial_win32.cpp | 198 --- src/hardware/serialport.cpp | 276 ----- src/hardware/serialport/Makefile.am | 7 + .../serialport/directserial_win32.cpp | 377 ++++++ src/hardware/serialport/directserial_win32.h | 84 ++ src/hardware/serialport/serialdummy.cpp | 85 ++ src/hardware/serialport/serialdummy.h | 54 + src/hardware/serialport/serialport.cpp | 1089 +++++++++++++++++ src/hardware/serialport/softmodem.cpp | 826 +++++++++++++ src/hardware/serialport/softmodem.h | 243 ++++ src/hardware/softmodem.cpp | 820 ------------- src/ints/bios.cpp | 270 +++- visualc_net/dosbox.vcproj | 34 +- 19 files changed, 3329 insertions(+), 1484 deletions(-) delete mode 100644 src/hardware/directserial_win32.cpp delete mode 100644 src/hardware/serialport.cpp create mode 100644 src/hardware/serialport/Makefile.am create mode 100644 src/hardware/serialport/directserial_win32.cpp create mode 100644 src/hardware/serialport/directserial_win32.h create mode 100644 src/hardware/serialport/serialdummy.cpp create mode 100644 src/hardware/serialport/serialdummy.h create mode 100644 src/hardware/serialport/serialport.cpp create mode 100644 src/hardware/serialport/softmodem.cpp create mode 100644 src/hardware/serialport/softmodem.h delete mode 100644 src/hardware/softmodem.cpp diff --git a/configure.in b/configure.in index 0a4878bf..fa36b356 100644 --- a/configure.in +++ b/configure.in @@ -287,6 +287,7 @@ src/dos/Makefile src/fpu/Makefile src/gui/Makefile src/hardware/Makefile +src/hardware/serialport/Makefile src/ints/Makefile src/misc/Makefile src/shell/Makefile diff --git a/include/bios.h b/include/bios.h index 4002dc94..ccb4d9ee 100644 --- a/include/bios.h +++ b/include/bios.h @@ -72,7 +72,9 @@ /* 0x47b is reserved */ #define BIOS_COM1_TIMEOUT 0x47c #define BIOS_COM2_TIMEOUT 0x47d -/* 0x47e is reserved */ +#define BIOS_COM3_TIMEOUT 0x47e +#define BIOS_COM4_TIMEOUT 0x47f +/* 0x47e is reserved */ //<- why that? /* 0x47f-0x4ff is unknow for me */ #define BIOS_KEYBOARD_BUFFER_START 0x480 #define BIOS_KEYBOARD_BUFFER_END 0x482 diff --git a/include/serialport.h b/include/serialport.h index 1515ebaa..b64b4de6 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -16,146 +16,283 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: serialport.h,v 1.9 2005-07-30 14:41:30 qbix79 Exp $ */ + #ifndef DOSBOX_SERIALPORT_H #define DOSBOX_SERIALPORT_H -#include +// Uncomment this for a lot of debug messages: +//#define SERIALPORT_DEBUGMSG #ifndef DOSBOX_DOSBOX_H -#include "dosbox.h" +#include "dosbox.h" #endif #ifndef DOSBOX_INOUT_H -#include "inout.h" +#include "inout.h" +#endif +#ifndef DOSBOX_TIMER_H +#include "timer.h" #endif -//If it's too high you overflow terminal clients buffers i think -#define QUEUE_SIZE 1024 // Serial port interface // -#define MS_CTS 0x01 -#define MS_DSR 0x02 -#define MS_RI 0x04 -#define MS_DCD 0x08 - -#define MC_DTR 0x1 -#define MC_RTS 0x2 - - -class CFifo { -public: - CFifo(Bitu _size) { - size=_size; - pos=used=0; - data=new Bit8u[size]; - } - ~CFifo() { - delete[] data; - } - INLINE Bitu left(void) { - return size-used; - } - INLINE Bitu inuse(void) { - return used; - } - void clear(void) { - used=pos=0; - } - bool isFull() { - return (used >= size); - } - void addb(Bit8u _val) { - assert(used=size) where-=size; - data[where]=_val; - used++; - } - void adds(Bit8u * _str,Bitu _len) { - assert((used+_len)<=size); - Bitu where=pos+used; - used+=_len; - while (_len--) { - if (where>=size) where-=size; - data[where++]=*_str++; - } - } - Bit8u getb(void) { - if (!used) return data[pos]; - Bitu where=pos; - if (++pos>=size) pos-=size; - used--; - return data[where]; - } - void gets(Bit8u * _str,Bitu _len) { - assert(used>=_len); - used-=_len; - while (_len--) { - *_str++=data[pos]; - if (++pos>=size) pos-=size; - } - } -private: - Bit8u * data; - Bitu size,pos,used; -}; - class CSerial { public: - CSerial() { - - } - // Constructor takes base port (0x3f0, 0x2f0, 0x2e0, etc.), IRQ, and initial bps // - CSerial (Bit16u initbase, Bit8u initirq, Bit32u initbps); + // Constructor takes base port (0x3f8, 0x2f8, 0x2e8, etc.), IRQ, and initial bps // + CSerial(IO_ReadHandler* rh, IO_WriteHandler* wh, + TIMER_TickHandler TimerHandler, + Bit16u initbase, Bit8u initirq, Bit32u initbps, + Bit8u bytesize, const char* parity, Bit8u stopbits); + + TIMER_TickHandler TimerHnd; virtual ~CSerial(); + + IO_ReadHandleObject ReadHandler[8]; + IO_WriteHandleObject WriteHandler[8]; - void write_reg(Bitu reg, Bitu val); - Bitu read_reg(Bitu reg); - - void SetModemStatus(Bit8u status); - virtual bool CanRecv(void)=0; - virtual bool CanSend(void)=0; - virtual void Send(Bit8u val)=0; - virtual Bit8u Recv(Bit8u val)=0; - virtual void Timer(void); - - void checkint(void); - + void Timer(void); + virtual void Timer2(void)=0; + Bitu base; Bitu irq; - Bitu bps; - Bit8u mctrl; + + bool CSerial::getDTR(); + bool CSerial::getRTS(); - CFifo *rqueue; - CFifo *tqueue; + bool CSerial::getRI(); + bool CSerial::getCD(); + bool CSerial::getDSR(); + bool CSerial::getCTS(); + + void CSerial::setRI(bool value); + void CSerial::setDSR(bool value); + void CSerial::setCD(bool value); + void CSerial::setCTS(bool value); + + void CSerial::Write_THR(Bit8u data); + Bitu CSerial::Read_RHR(); + Bitu CSerial::Read_IER(); + void CSerial::Write_IER(Bit8u data); + Bitu CSerial::Read_ISR(); + Bitu CSerial::Read_LCR(); + void CSerial::Write_LCR(Bit8u data); + Bitu CSerial::Read_MCR(); + void CSerial::Write_MCR(Bit8u data); + Bitu CSerial::Read_LSR(); + + // Really old hardware seems to have the delta part of this register writable + void CSerial::Write_MSR(Bit8u data); + + Bitu CSerial::Read_MSR(); + Bitu CSerial::Read_SPR(); + void CSerial::Write_SPR(Bit8u data); + void CSerial::Write_reserved(Bit8u data, Bit8u address); + + // If a byte comes from wherever(loopback or real port or maybe + // that softmodem thingy), put it in here. + void CSerial::receiveByte(Bit8u data); + + // If an error was received, put it here (in LSR register format) + void CSerial::receiveError(Bit8u errorword); + + // connected device checks, if port can receive data: + bool CSerial::CanReceiveByte(); + + // When done sending, notify here + void CSerial::ByteTransmitted(); + + // Virtual app has read the received data + virtual void RXBufferEmpty()=0; + + // real transmit + virtual void transmitByte(Bit8u val)=0; + + // switch break state to the passed value + virtual void setBreak(bool value)=0; + + // set output lines + virtual void updateModemControlLines(/*Bit8u mcr*/)=0; + + // change baudrate, number of bits, parity, word length al at once + virtual void updatePortConfig(Bit8u dll, Bit8u dlm, Bit8u lcr)=0; + + // CSerial requests an update of the input lines + virtual void updateMSR()=0; + + // after update request, or some "real" changes, + // modify MSR here + void CSerial::changeMSR(Bit8u data); // make public + + void CSerial::Init_Registers(Bit32u initbps, + Bit8u bytesize, const char* parity, Bit8u stopbits); private: - void UpdateBaudrate(void); - bool FIFOenabled; - Bit8u FIFOsize; - bool dotxint; - - Bit8u scratch; - Bit8u dlab; - Bit8u divisor_lsb; - Bit8u divisor_msb; - Bit8u local_loopback; - Bit8u iir; - Bit8u ier; - Bit8u mstatus; - Bit8u linectrl; - Bit8u errors; - IO_ReadHandleObject ReadHandler[9]; - IO_WriteHandleObject WriteHandler[9]; + // I used this spec: http://www.exar.com/products/st16c450v420.pdf + + void CSerial::changeMSR_Loopback(Bit8u data); + + void CSerial::WriteRealIER(Bit8u data); + // reason for an interrupt has occured - functions triggers interrupt + // if it is enabled and no higher-priority irq pending + void CSerial::rise(Bit8u priority); + + // clears the pending interrupt + void CSerial::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 pending_interrupts; // stores triggered interupts + Bit8u current_priority; + Bit8u waiting_interrupts; // these are on, but maybe not enabled + + // 16C450 (no FIFO) + // read/write name + + + Bit8u DLL; // r Baudrate divider low byte + Bit8u DLM; // r "" high byte + + 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 (r/w) + #define IER_OFFSET 1 + // Data: + // bit0 receive holding register + // bit1 transmit holding register + // bit2 receive line status interrupt + // bit3 modem status interrupt + + #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 + + Bit8u MCR; // r/w Modem Control Register + #define MCR_OFFSET 4 + // bit0: DTR + // bit1: RTS + // bit2: OP1 + // bit3: OP2 + // bit4: loop back enable + + #define MCR_LOOPBACK_Enable_MASK 0x10 + #define MCR_LEVELS_MASK 0xf + + #define MCR_DTR_MASK 0x1 + #define MCR_RTS_MASK 0x2 + #define MCR_OP1_MASK 0x4 + #define MCR_OP2_MASK 0x8 + + Bit8u LSR; // r Line Status Register + #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 + + + Bit8u MSR; // r Modem Status Register + #define MSR_OFFSET 6 + // bit0: deltaCTS + // bit1: deltaDSR + // bit2: deltaRI + // bit3: deltaCD + // bit4: CTS + // bit5: DSR + // bit6: RI + // 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... + bool loopback_pending; + Bit8u loopback_data; + void transmitLoopbackByte(Bit8u val); + + // 16C550 (FIFO) + // TODO + //Bit8u FCR; // FIFO Control Register + }; -#include - -typedef std::list CSerialList; -typedef std::list::iterator CSerial_it; - -extern CSerialList seriallist; +#define COM1_BASE 0x3f8 +#define COM2_BASE 0x2f8 +#define COM3_BASE 0x3e8 +#define COM4_BASE 0x2e8 #endif + diff --git a/src/Makefile.am b/src/Makefile.am index 24279b30..c58e2e4f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,5 +6,5 @@ bin_PROGRAMS = dosbox dosbox_SOURCES = dosbox.cpp dosbox_LDADD = cpu/libcpu.a debug/libdebug.a dos/libdos.a fpu/libfpu.a hardware/libhardware.a gui/libgui.a \ - ints/libints.a misc/libmisc.a shell/libshell.a + ints/libints.a misc/libmisc.a shell/libshell.a hardware/serialport/libserial.a diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 8d865c43..4cc4c2d1 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.85 2005-06-13 14:48:00 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.86 2005-07-30 14:41:31 qbix79 Exp $ */ #include #include @@ -80,17 +80,11 @@ void TANDYSOUND_Init(Section*); void DISNEY_Init(Section*); void SERIAL_Init(Section*); -#if C_MODEM -void MODEM_Init(Section*); -#endif #if C_IPX void IPX_Init(Section*); #endif -#if C_DIRECTSERIAL -void DIRECTSERIAL_Init(Section* sec); -#endif void SID_Init(Section* sec); void PIC_Init(Section*); @@ -218,7 +212,6 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&PROGRAMS_Init); secprop->AddInitFunction(&TIMER_Init);//done secprop->AddInitFunction(&CMOS_Init);//done - secprop->AddInitFunction(&SERIAL_Init); //done MSG_Add("DOSBOX_CONFIGFILE_HELP", "language -- Select another language file.\n" @@ -351,10 +344,6 @@ void DOSBOX_Init(void) { "disney -- Enable Disney Sound Source emulation.\n" ); secprop=control->AddSection_prop("bios",&BIOS_Init,false);//done - secprop->AddInitFunction(&INT10_Init); - secprop->AddInitFunction(&MOUSE_Init); //Must be after int10 as it uses CurMode - secprop->AddInitFunction(&JOYSTICK_Init); - secprop->Add_string("joysticktype","2axis"); MSG_Add("BIOS_CONFIGFILE_HELP", "joysticktype -- Type of joystick to emulate: none, 2axis, 4axis,\n" " fcs (Thrustmaster) ,ch (CH Flightstick).\n" @@ -362,6 +351,27 @@ void DOSBOX_Init(void) { " 2axis is the default and supports two joysticks.\n" ); + secprop->AddInitFunction(&INT10_Init); + secprop->AddInitFunction(&MOUSE_Init); //Must be after int10 as it uses CurMode + secprop->AddInitFunction(&JOYSTICK_Init); + secprop->Add_string("joysticktype","2axis"); + + // had to rename these to serial due to conflicts in config + secprop=control->AddSection_prop("serial",&SERIAL_Init,true); + secprop->Add_string("serial1","dummy"); + secprop->Add_string("serial2","dummy"); + secprop->Add_string("serial3","disabled"); + secprop->Add_string("serial4","disabled"); + MSG_Add("SERIAL_CONFIGFILE_HELP", + "serial1-4 -- set type of device connected to com port.\n" + " Can be disabled, dummy, modem, directserial.\n" + " Additional parameters must be in the same line in the form of\n" + " parameter:value. Parameters for all types are irq, startbps, bytesize,\n" + " stopbits, parity (all optional).\n" + " for directserial: realport (required).\n" + " for modem: listenport (optional).\n" + ); + /* All the DOS Related stuff, which will eventually start up in the shell */ //TODO Maybe combine most of the dos stuff in one section like ems,xms secprop=control->AddSection_prop("dos",&DOS_Init,false);//done @@ -375,39 +385,8 @@ void DOSBOX_Init(void) { ); // Mscdex secprop->AddInitFunction(&MSCDEX_Init); -#if C_MODEM - secprop=control->AddSection_prop("modem",&MODEM_Init,true);//done - secprop->Add_bool("modem",false); - secprop->Add_hex("comport",2); - secprop->Add_int("listenport",23); - - MSG_Add("MODEM_CONFIGFILE_HELP", - "modem -- Enable virtual modem emulation.\n" - "comport -- COM Port modem is connected to.\n" - "listenport -- TCP Port the modem listens on for incoming connections.\n" - ); -#endif -#if C_DIRECTSERIAL - secprop=control->AddSection_prop("directserial",&DIRECTSERIAL_Init); - secprop->Add_bool("directserial", false); - secprop->Add_hex("comport",1); - secprop->Add_string("realport", "COM1"); - secprop->Add_int("defaultbps", 1200); - secprop->Add_string("parity", "N"); // Could be N, E, O - secprop->Add_int("bytesize", 8); // Could be 5 to 8 - secprop->Add_int("stopbit", 1); // Could be 1 or 2 - MSG_Add("DIRECTSERIAL_CONFIGFILE_HELP", - "directserial -- Enable serial passthrough support.\n" - "comport -- COM Port inside DOSBox.\n" - "realport -- COM Port on the Host.\n" - "defaultbps -- Default BPS.\n" - "parity -- Parity of the packets. This can be N, E or O.\n" - "bytesize -- Size of each packet. This can be 5 or 8.\n" - "stopbit -- The number of stopbits. This can be 1 or 2.\n" - ); -#endif #if C_IPX - secprop=control->AddSection_prop("ipx",&IPX_Init); + secprop=control->AddSection_prop("ipx",&IPX_Init,true); secprop->Add_bool("ipx", false); MSG_Add("IPX_CONFIGFILE_HELP", "ipx -- Enable ipx over UDP/IP emulation.\n" diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index f51dc2a0..60657aaa 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -1,5 +1,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include +SUBDIRS = serialport + EXTRA_DIST = fmopl.c fmopl.h ymf262.h ymf262.c noinst_LIBRARIES = libhardware.a @@ -8,9 +10,6 @@ libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp vga_other.cpp \ vga_memory.cpp vga_misc.cpp vga_seq.cpp vga_xga.cpp cmos.cpp disney.cpp \ - gus.cpp mpu401.cpp serialport.cpp softmodem.cpp ipx.cpp ipxserver.cpp \ - directserial_win32.cpp - - + gus.cpp mpu401.cpp ipx.cpp ipxserver.cpp diff --git a/src/hardware/directserial_win32.cpp b/src/hardware/directserial_win32.cpp deleted file mode 100644 index a04c0ef1..00000000 --- a/src/hardware/directserial_win32.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2002-2005 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: directserial_win32.cpp,v 1.5 2005-02-10 10:21:08 qbix79 Exp $ */ - -#include "dosbox.h" - -#if C_DIRECTSERIAL - -/* Windows version */ -#if defined (WIN32) - -#include -#include -#include - -#include "setup.h" -#include "serialport.h" - -// Win32 related headers -#include - -/* This is a serial passthrough class. Its amazingly simple to */ -/* write now that the serial ports themselves were abstracted out */ - - -class CDirectSerial : public CSerial { -public: - HANDLE hCom; - DCB dcb; - BOOL fSuccess; - - CDirectSerial(char * realPort, Bit16u baseAddr, Bit8u initIrq, Bit32u initBps, Bit16u bytesize, char *parity, Bit16u stopbits ) : CSerial(baseAddr, initIrq, initBps) { - LOG_MSG("Opening Windows serial port"); - hCom = CreateFile(realPort, GENERIC_READ | GENERIC_WRITE, - 0, // must be opened with exclusive-access - NULL, // no security attributes - OPEN_EXISTING, // must use OPEN_EXISTING - 0, // non overlapped I/O - NULL // hTemplate must be NULL for comm devices - ); - - if (hCom == INVALID_HANDLE_VALUE) - { - LOG_MSG("CreateFile failed with error %d.\n", GetLastError()); - hCom = 0; - return; - } - - fSuccess = GetCommState(hCom, &dcb); - - if (!fSuccess) - { - // Handle the error. - LOG_MSG("GetCommState failed with error %d.\n", GetLastError()); - return; - } - - - dcb.BaudRate = initBps; // set the baud rate - dcb.ByteSize = bytesize; // data size, xmit, and rcv - if(parity[0] == 'N') - dcb.Parity = NOPARITY; // no parity bit - if(parity[1] == 'E') - dcb.Parity = EVENPARITY; // even parity bit - if(parity[2] == 'O') - dcb.Parity = ODDPARITY; // odd parity bit - - - if(stopbits == 1) - dcb.StopBits = ONESTOPBIT; // one stop bit - if(stopbits == 2) - dcb.StopBits = TWOSTOPBITS; // two stop bits - - fSuccess = SetCommState(hCom, &dcb); - - // Configure timeouts to effectively use polling - COMMTIMEOUTS ct; - ct.ReadIntervalTimeout = MAXDWORD; - ct.ReadTotalTimeoutConstant = 0; - ct.ReadTotalTimeoutMultiplier = 0; - ct.WriteTotalTimeoutConstant = 0; - ct.WriteTotalTimeoutMultiplier = 0; - SetCommTimeouts(hCom, &ct); - - } - - ~CDirectSerial() { - if(hCom != INVALID_HANDLE_VALUE) CloseHandle(hCom); - } - - bool CanRecv(void) { return true; } - bool CanSend(void) { return true; } - - void Send(Bit8u val) { tqueue->addb(val); } - - Bit8u Recv(Bit8u val) { return rqueue->getb(); } - - void updatestatus(void) { - Bit8u ms=0; - DWORD stat = 0; - GetCommModemStatus(hCom, &stat); - - //Check for data carrier - if(stat & MS_RLSD_ON) ms|=MS_DCD; - if (stat & MS_RING_ON) ms|=MS_RI; - if (stat & MS_DSR_ON) ms|=MS_DSR; - if (stat & MS_CTS_ON) ms|=MS_CTS; - SetModemStatus(ms); - } - - void Timer(void) { - DWORD dwRead; - Bit8u chRead; - - if (ReadFile(hCom, &chRead, 1, &dwRead, NULL)) { - if(dwRead != 0) { - if(!rqueue->isFull()) rqueue->addb(chRead); - } - } - - updatestatus(); - - Bit8u txval; - - Bitu tx_size=tqueue->inuse(); - while (tx_size--) { - txval = tqueue->getb(); - DWORD bytesWritten; - BOOL result; - result = WriteFile(hCom, &txval, 1, &bytesWritten, NULL); - if (!result) - { - // Handle the error. - LOG_MSG("WriteFile failed with error %d.\n", GetLastError()); - return; - } - - } - } - -}; - -CDirectSerial *cds; - -void DIRECTSERIAL_Init(Section* sec) { - - unsigned long args = 1; - Section_prop * section=static_cast(sec); - - - if(!section->Get_bool("directserial")) return; - - Bit16u comport = section->Get_int("comport"); - Bit32u bps = section->Get_int("defaultbps"); - switch (comport) { - case 1: - cds = new CDirectSerial((char *)section->Get_string("realport"), 0x3f0, 4, bps, section->Get_int("bytesize"), (char *)section->Get_string("parity"), section->Get_int("stopbit")); - break; - case 2: - cds = new CDirectSerial((char *)section->Get_string("realport"), 0x2f0, 3, bps, section->Get_int("bytesize"), (char *)section->Get_string("parity"), section->Get_int("stopbit")); - break; - case 3: - cds = new CDirectSerial((char *)section->Get_string("realport"), 0x3e0, 4, bps, section->Get_int("bytesize"), (char *)section->Get_string("parity"), section->Get_int("stopbit")); - break; - case 4: - cds = new CDirectSerial((char *)section->Get_string("realport"), 0x2e0, 3, bps, section->Get_int("bytesize"), (char *)section->Get_string("parity"), section->Get_int("stopbit")); - break; - default: - cds = new CDirectSerial((char *)section->Get_string("realport"), 0x3f0, 4, bps, section->Get_int("bytesize"), (char *)section->Get_string("parity"), section->Get_int("stopbit")); - break; - - } - - - - seriallist.push_back(cds); -} -#else /*linux and others oneday maybe */ - -#endif -#endif - diff --git a/src/hardware/serialport.cpp b/src/hardware/serialport.cpp deleted file mode 100644 index 5fce2f6e..00000000 --- a/src/hardware/serialport.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (C) 2002-2005 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 -#include - -#include "dosbox.h" -#include "inout.h" -#include "mixer.h" -#include "pic.h" -#include "setup.h" -#include "timer.h" -#include "math.h" -#include "regs.h" -#include "serialport.h" - -#define SERIALBASERATE 115200 -#define LOG_UART LOG_MSG - -CSerialList seriallist; - -void CSerial::UpdateBaudrate(void) { - Bitu divsize=(divisor_msb << 8) | divisor_lsb; - if (divsize) { - bps = SERIALBASERATE / divsize; - } -} - - -void CSerial::Timer(void) { - dotxint=true; - checkint(); -} - -void CSerial::checkint(void) { - /* Check which irq to activate */ - //TODO Check for line status changes, but we can't get errors anyway - //Since we only check once every millisecond, we just ignore the fifosize parameter - if ((ier & 0x1) && rqueue->inuse()) { -// LOG_MSG("RX IRQ with %d",rqueue->inuse()); - iir=0x4; - } else if ((ier & 0x2) && !tqueue->inuse() && dotxint) { - iir=0x2; - } else if ((ier & 0x8) && (mstatus & 0x0f)) { - iir=0x0; - } else { - iir=0x1; - PIC_DeActivateIRQ(irq); - return; - } - if (mctrl & 0x8) PIC_ActivateIRQ(irq); - else PIC_DeActivateIRQ(irq); -} - -void CSerial::write_reg(Bitu reg, Bitu val) { -// if (port!=9 && port!=8) LOG_MSG("Serial write %X val %x %c",port,val,val); - switch(reg) { - case 0x8: // Transmit holding buffer + Divisor LSB - if (dlab) { - divisor_lsb = val; - UpdateBaudrate(); - return; - } - if (local_loopback) rqueue->addb(val); - else tqueue->addb(val); - break; - case 0x9: // Interrupt enable register + Divisor MSB - if (dlab) { - divisor_msb = val; - UpdateBaudrate(); - return; - } else { - ier = val; - dotxint=true; - } - break; - case 0xa: // FIFO Control register - FIFOenabled = (val & 0x1) > 0; - if (val & 0x2) rqueue->clear(); //Clear receiver FIFO - if (val & 0x4) tqueue->clear(); //Clear transmit FIFO - if (val & 0x8) LOG(LOG_MISC,LOG_WARN)("UART:Enabled DMA mode"); - switch (val >> 6) { - case 0:FIFOsize = 1;break; - case 1:FIFOsize = 4;break; - case 2:FIFOsize = 8;break; - case 3:FIFOsize = 14;break; - } - break; - case 0xb: // Line control register - linectrl = val; - dlab = (val & 0x80); - break; - case 0xc: // Modem control register - mctrl=val; - local_loopback = (val & 0x10); - break; - case 0xf: // Scratch register - scratch = val; - break; - default: - LOG_UART("Modem: Write to 0x%x, with 0x%x '%c'\n", reg,val,val); - break; - } -} - -static void WriteSerial(Bitu port,Bitu val,Bitu iolen) { - Bitu check=port&~0xf; - for (CSerial_it it=seriallist.begin();it!=seriallist.end();it++){ - CSerial * serial=(*it); - if (check==serial->base) { - serial->write_reg(port&0xf,val); - return; - } - } -} - -static Bitu ReadSerial(Bitu port,Bitu iolen) { - Bitu check=port&~0xf; - - for (CSerial_it it=seriallist.begin();it!=seriallist.end();it++){ - CSerial * serial=(*it); - if (check==serial->base) { - - return serial->read_reg(port&0xf); - } - } - return 0; -} - -void SERIAL_Update(void) { - for (CSerial_it it=seriallist.begin();it!=seriallist.end();it++){ - CSerial * serial=(*it); - serial->Timer(); - } -} - - - -Bitu CSerial::read_reg(Bitu reg) { - Bitu retval; -// if (port!=0xd && port!=0xa) LOG_MSG("REad from port %x",reg); - switch(reg) { - case 0x8: // Receive buffer + Divisor LSB - if (dlab) { - return divisor_lsb ; - } else { - retval=rqueue->getb(); - //LOG_MSG("Received char %x %c",retval,retval); - checkint(); - return retval; - } - case 0x9: // Interrupt enable register + Divisor MSB - if (dlab) { - return divisor_msb ; - } else { - return ier; - } - case 0xa: // Interrupt identification register - retval=iir; - if (iir==2) { - dotxint=false; - iir=1; - } -// LOG_MSG("Read iir %d after %d",retval,iir); - return retval | ((FIFOenabled) ? (3 << 6) : 0); - case 0xb: // Line control register - return linectrl; - case 0xC: // Modem control register - return mctrl; - case 0xD: // Line status register - retval = 0x40; - if (!tqueue->inuse()) retval|=0x20; - if (rqueue->inuse()) retval|= 1; -// LOG_MSG("Read from line status %x",retval); - return retval; - case 0xE: // modem status register - retval=mstatus; - mstatus&=0xf0; - checkint(); - return retval; - case 0xF: // Scratch register - return scratch; - default: - //LOG_DEBUG("Modem: Read from 0x%x\n", port); - break; - } - return 0x00; -} - - -void CSerial::SetModemStatus(Bit8u status) { - status&=0xf; - Bit8u oldstatus=mstatus >> 4; - if (oldstatus ^ status ) { - mstatus=(mstatus & 0xf) | status << 4; - mstatus|=(oldstatus ^ status) & ((status & 0x4) | (0xf-0x4)); - } -} - - -CSerial::CSerial (Bit16u initbase, Bit8u initirq, Bit32u initbps) { - - Bitu i; - Bit16u initdiv; - - base=initbase; - irq=initirq; - bps=initbps; - - local_loopback = 0; - ier = 0; - iir = 1; - - FIFOenabled = false; - FIFOsize = 1; - dlab = 0; - mstatus = 0; - - initdiv = SERIALBASERATE / bps; - UpdateBaudrate(); - - for (i=0;i<=8;i++) { - WriteHandler[i].Install(base+i+8,WriteSerial,IO_MB); - ReadHandler[i].Install(base+i+8,ReadSerial,IO_MB); - } - - rqueue=new CFifo(QUEUE_SIZE); - tqueue=new CFifo(QUEUE_SIZE); -}; - -CSerial::~CSerial(void) -{ - //Remove pointer in list if present - for (CSerial_it it=seriallist.begin();it!=seriallist.end();) - if(this==*it) it=seriallist.erase(it); else it++; - - delete rqueue; - delete tqueue; - -}; - -class SERIALPORTS:public Module_base{ -public: - SERIALPORTS(Section* configuration):Module_base(configuration){ - TIMER_AddTickHandler(&SERIAL_Update); - } - ~SERIALPORTS(){ - TIMER_DelTickHandler(&SERIAL_Update); - } -}; - -static SERIALPORTS* test; - -void SERIAL_Destroy(Section* sec){ - delete test; -} - -void SERIAL_Init(Section* sec) { - test = new SERIALPORTS(sec); - sec->AddDestroyFunction(&SERIAL_Destroy,false); -} diff --git a/src/hardware/serialport/Makefile.am b/src/hardware/serialport/Makefile.am new file mode 100644 index 00000000..dd3633d7 --- /dev/null +++ b/src/hardware/serialport/Makefile.am @@ -0,0 +1,7 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include + +noinst_LIBRARIES = libserial.a + +libserial_a_SOURCES = directserial_win32.cpp directserial_win32.h \ + serialdummy.cpp serialdummy.h serialport.cpp \ + softmodem.cpp softmodem.h diff --git a/src/hardware/serialport/directserial_win32.cpp b/src/hardware/serialport/directserial_win32.cpp new file mode 100644 index 00000000..8bf84e9b --- /dev/null +++ b/src/hardware/serialport/directserial_win32.cpp @@ -0,0 +1,377 @@ +/* + * Copyright (C) 2002-2005 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: directserial_win32.cpp,v 1.1 2005-07-30 14:41:31 qbix79 Exp $ */ + +#include "dosbox.h" + +#if C_DIRECTSERIAL + +/* Windows version */ +#if defined (WIN32) + +#include "serialport.h" +#include "directserial_win32.h" + +// Win32 related headers +#include + +/* This is a serial passthrough class. Its amazingly simple to */ +/* write now that the serial ports themselves were abstracted out */ + +CDirectSerial::CDirectSerial (IO_ReadHandler * rh, IO_WriteHandler * wh, + TIMER_TickHandler th, Bit16u baseAddr, Bit8u initIrq, + Bit32u initBps, Bit8u bytesize, const char *parity, + Bit8u stopbits,const char *realPort) + :CSerial (rh, wh, th,baseAddr,initIrq, initBps, + bytesize, parity,stopbits) { + InstallationSuccessful = false; + lastChance = 0; + LOG_MSG ("Serial port at %x: Opening %s", base, realPort); + hCom = CreateFile (realPort, GENERIC_READ | GENERIC_WRITE, 0, // must be opened with exclusive-access + NULL, // no security attributes + OPEN_EXISTING, // must use OPEN_EXISTING + 0, // non overlapped I/O + NULL // hTemplate must be NULL for comm devices + ); + + if (hCom == INVALID_HANDLE_VALUE) { + int error = GetLastError (); + LOG_MSG ("Serial port \"%s\" could not be opened.", realPort); + if (error == 2) { + LOG_MSG ("The specified port does not exist."); + } else if (error == 5) { + LOG_MSG ("The specified port is already in use."); + } else { + LOG_MSG ("Windows error %d occurred.", error); + } + + hCom = 0; + return; + } + + fSuccess = GetCommState (hCom, &dcb); + + if (!fSuccess) { + // Handle the error. + LOG_MSG ("GetCommState failed with error %d.\n", GetLastError ()); + hCom = 0; + return; + } + // Configure timeouts to effectively use polling + COMMTIMEOUTS ct; + ct.ReadIntervalTimeout = MAXDWORD; + ct.ReadTotalTimeoutConstant = 0; + ct.ReadTotalTimeoutMultiplier = 0; + ct.WriteTotalTimeoutConstant = 0; + ct.WriteTotalTimeoutMultiplier = 0; + SetCommTimeouts (hCom, &ct); + + CSerial::Init_Registers (initBps, bytesize, parity, stopbits); + InstallationSuccessful = true; + //LOG_MSG("InstSuccess"); +} + +CDirectSerial::~CDirectSerial () { + if (hCom != INVALID_HANDLE_VALUE) + CloseHandle (hCom); +} + +Bitu lastChance; + +void CDirectSerial::RXBufferEmpty () { + DWORD dwRead; + DWORD errors; + Bit8u chRead; + if (lastChance > 0) { + receiveByte (ChanceChar); + lastChance = 0; + } else { + // update RX + if (ReadFile (hCom, &chRead, 1, &dwRead, NULL)) { + if (dwRead != 0) { + //LOG_MSG("UART 0x%x: RX 0x%x", base,chRead); + receiveByte (chRead); + } + } + } + // check for errors + if (ClearCommError (hCom, &errors, NULL)) + if (errors & (CE_BREAK | CE_FRAME | CE_RXPARITY)) { + Bit8u errreg = 0; + if (errors & CE_BREAK) { + LOG_MSG ("Serial port at 0x%x: line error: break received.", base); + errreg |= LSR_RX_BREAK_MASK; + } + if (errors & CE_FRAME) { + LOG_MSG ("Serial port at 0x%x: line error: framing error.", base); + errreg |= LSR_FRAMING_ERROR_MASK; + } + if (errors & CE_RXPARITY) { + LOG_MSG ("Serial port at 0x%x: line error: parity error.", base); + errreg |= LSR_PARITY_ERROR_MASK; + } + receiveError (errreg); + } +} + +/*****************************************************************************/ +/* updatePortConfig is called when emulated app changes the serial port **/ +/* parameters baudrate, stopbits, number of databits, parity. **/ +/*****************************************************************************/ +void CDirectSerial::updatePortConfig (Bit8u dll, Bit8u dlm, Bit8u lcr) { + Bit8u parity = 0; + Bit8u bytelength = 0; + Bit16u baudrate = 0; + + // baud + baudrate = dlm; + baudrate = baudrate << 8; + baudrate |= dll; + if (baudrate <= 0x1) + dcb.BaudRate = CBR_115200; + else if (baudrate <= 0x2) + dcb.BaudRate = CBR_57600; + else if (baudrate <= 0x3) + dcb.BaudRate = CBR_38400; + else if (baudrate <= 0x6) + dcb.BaudRate = CBR_19200; + else if (baudrate <= 0xc) + dcb.BaudRate = CBR_9600; + else if (baudrate <= 0x18) + dcb.BaudRate = CBR_4800; + else if (baudrate <= 0x30) + dcb.BaudRate = CBR_2400; + else if (baudrate <= 0x60) + dcb.BaudRate = CBR_1200; + else if (baudrate <= 0xc0) + dcb.BaudRate = CBR_600; + else if (baudrate <= 0x180) + dcb.BaudRate = CBR_300; + else if (baudrate <= 0x417) + dcb.BaudRate = CBR_110; + + // I read that windows can handle nonstandard baudrates: + else + dcb.BaudRate = 115200 / baudrate; + +#ifdef SERIALPORT_DEBUGMSG + LOG_MSG ("Serial port at %x: new baud rate: %d", base, dcb.BaudRate); +#endif + + // byte length + bytelength = lcr & 0x3; + bytelength += 5; + dcb.ByteSize = bytelength; + + // parity + parity = lcr & 0x38; + parity = parity >> 3; + switch (parity) { + case 0x1: + dcb.Parity = ODDPARITY; + break; + case 0x3: + dcb.Parity = EVENPARITY; + break; + case 0x5: + dcb.Parity = MARKPARITY; + break; + case 0x7: + dcb.Parity = SPACEPARITY; + break; + default: + dcb.Parity = NOPARITY; + break; + } + + // stopbits + if (lcr & 0x4) { + if (bytelength == 5) + dcb.StopBits = ONE5STOPBITS; + else + dcb.StopBits = TWOSTOPBITS; + } else { + dcb.StopBits = ONESTOPBIT; + } + + if (!SetCommState (hCom, &dcb)) + LOG_MSG ("Serial port at 0x%x: API did not like the new values.", base); + //LOG_MSG("Serial port at 0x%x: Port params changed: %d Baud", base,dcb.BaudRate); +} + +void CDirectSerial::updateMSR () { + Bit8u newmsr = 0; + DWORD dptr = 0; + + if (!GetCommModemStatus (hCom, &dptr)) { +#ifdef SERIALPORT_DEBUGMSG + LOG_MSG ("Serial port at %x: GetCommModemStatus failed!", base); +#endif + //return; + } + if (dptr & MS_CTS_ON) + newmsr |= MSR_CTS_MASK; + if (dptr & MS_DSR_ON) + newmsr |= MSR_DSR_MASK; + if (dptr & MS_RING_ON) + newmsr |= MSR_RI_MASK; + if (dptr & MS_RLSD_ON) + newmsr |= MSR_CD_MASK; + changeMSR (newmsr); +} + +void CDirectSerial::transmitByte (Bit8u val) { + // mean bug: with break = 1, WriteFile will never return. + if((LCR&LCR_BREAK_MASK) == 0) { + + DWORD bytesWritten = 0; + WriteFile (hCom, &val, 1, &bytesWritten, NULL); + if (bytesWritten > 0) { + ByteTransmitted (); + //LOG_MSG("UART 0x%x: TX 0x%x", base,val); + } else { + LOG_MSG ("UART 0x%x: NO BYTE WRITTEN! PORT HANGS NOW!", base); + } + } else { + // have a delay here, it's the only sense of sending + // data with break=1 + Bitu ticks; + Bitu elapsed = 0; + ticks = GetTicks(); + + while(elapsed < 10) { + elapsed = GetTicks() - ticks; + } + ByteTransmitted(); + } +} + +/*****************************************************************************/ +/* setBreak(val) switches break on or off **/ +/*****************************************************************************/ + +void CDirectSerial::setBreak (bool value) { + //#ifdef SERIALPORT_DEBUGMSG + //LOG_MSG("UART 0x%x: Break toggeled: %d", base, value); + //#endif + if (value) + SetCommBreak (hCom); + else + ClearCommBreak (hCom); +} + +/*****************************************************************************/ +/* updateModemControlLines(mcr) sets DTR and RTS. **/ +/*****************************************************************************/ +void CDirectSerial::updateModemControlLines ( /*Bit8u mcr */ ) { + bool change = false; + + /*** DTR ***/ + if (CSerial::getDTR ()) { // DTR on + if (dcb.fDtrControl == DTR_CONTROL_DISABLE) { + dcb.fDtrControl = DTR_CONTROL_ENABLE; + change = true; + } + } else { + if (dcb.fDtrControl == DTR_CONTROL_ENABLE) { + dcb.fDtrControl = DTR_CONTROL_DISABLE; + change = true; + } + } + /*** RTS ***/ + if (CSerial::getRTS ()) { // RTS on + if (dcb.fRtsControl == RTS_CONTROL_DISABLE) { + dcb.fRtsControl = RTS_CONTROL_ENABLE; + change = true; + } + } else { + if (dcb.fRtsControl == RTS_CONTROL_ENABLE) { + dcb.fRtsControl = RTS_CONTROL_DISABLE; + change = true; + } + } + if (change) + SetCommState (hCom, &dcb); +} + +void CDirectSerial::Timer2(void) { + DWORD dwRead = 0; + DWORD errors = 0; + Bit8u chRead = 0; + + + if (lastChance == 0) { // lastChance = 0 + if (CanReceiveByte ()) { + if (ReadFile (hCom, &chRead, 1, &dwRead, NULL)) { + if (dwRead) + receiveByte (chRead); + } + } else { + if (ReadFile (hCom, &chRead, 1, &dwRead, NULL)) { + if (dwRead) { + ChanceChar = chRead; + lastChance++; + } + } + } + } else if (lastChance > 10) { + receiveByte (0); // this causes RX Overrun now + lastChance = 0; + // empty serial buffer + dwRead = 1; + while (dwRead > 0) { // throw away bytes in buffer + ReadFile (hCom, &chRead, 1, &dwRead, NULL); + } + } else { // lastChance>0 // already one waiting + if (CanReceiveByte ()) { // chance used + receiveByte (ChanceChar); + lastChance = 0; + } else + lastChance++; + } + + // check for errors + if (ClearCommError (hCom, &errors, NULL)) + if (errors & (CE_BREAK | CE_FRAME | CE_RXPARITY)) { + Bit8u errreg = 0; + + if (errors & CE_BREAK) { + LOG_MSG ("Serial port at 0x%x: line error: break received.", base); + errreg |= LSR_RX_BREAK_MASK; + } + if (errors & CE_FRAME) { + LOG_MSG ("Serial port at 0x%x: line error: framing error.", base); + errreg |= LSR_FRAMING_ERROR_MASK; + } + if (errors & CE_RXPARITY) { + LOG_MSG ("Serial port at 0x%x: line error: parity error.", base); + errreg |= LSR_PARITY_ERROR_MASK; + } + + receiveError (errreg); + } + // update Modem input line states + updateMSR (); +} + + +#else /*linux and others oneday maybe */ + +#endif +#endif diff --git a/src/hardware/serialport/directserial_win32.h b/src/hardware/serialport/directserial_win32.h new file mode 100644 index 00000000..e2622803 --- /dev/null +++ b/src/hardware/serialport/directserial_win32.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2002-2005 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: directserial_win32.h,v 1.1 2005-07-30 14:41:31 qbix79 Exp $ */ + +// include guard +#ifndef DOSBOX_DIRECTSERIAL_WIN32_H +#define DOSBOX_DIRECTSERIAL_WIN32_H + +#include "dosbox.h" + +#if C_DIRECTSERIAL +#ifdef WIN32 + + + +#define DIRECTSERIAL_AVAILIBLE +#include "serialport.h" +#include + +class CDirectSerial : public CSerial { +public: + HANDLE hCom; + DCB dcb; + BOOL fSuccess; + + CDirectSerial( + IO_ReadHandler* rh, + IO_WriteHandler* wh, + TIMER_TickHandler th, + Bit16u baseAddr, + Bit8u initIrq, + Bit32u initBps, + Bit8u bytesize, + const char *parity, + Bit8u stopbits, + const char * realPort + ); + + + ~CDirectSerial(); + + + Bitu lastChance; // If there is no space for new + // received data, it gets a little chance + Bit8u ChanceChar; + + bool CanRecv(void); + bool CanSend(void); + + bool InstallationSuccessful; // check after constructing. If + // something was wrong, delete it right away. + + void RXBufferEmpty(); + + + void updatePortConfig(Bit8u dll, Bit8u dlm, Bit8u lcr); + void updateMSR(); + void transmitByte(Bit8u val); + void setBreak(bool value); + void updateModemControlLines(/*Bit8u mcr*/); + void Timer2(void); + + +}; + +#endif // WIN32 +#endif // C_DIRECTSERIAL +#endif // include guard diff --git a/src/hardware/serialport/serialdummy.cpp b/src/hardware/serialport/serialdummy.cpp new file mode 100644 index 00000000..24af9fdc --- /dev/null +++ b/src/hardware/serialport/serialdummy.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2002-2005 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: serialdummy.cpp,v 1.1 2005-07-30 14:41:31 qbix79 Exp $ */ + +#include "dosbox.h" + +#include "setup.h" +#include "serialdummy.h" +#include "serialport.h" + + +CSerialDummy::CSerialDummy( + IO_ReadHandler* rh, + IO_WriteHandler* wh, + TIMER_TickHandler th, + Bit16u baseAddr, + Bit8u initIrq, + Bit32u initBps, + Bit8u bytesize, + const char* parity, + Bit8u stopbits + ) : CSerial( + rh, wh, th, + baseAddr,initIrq,initBps,bytesize,parity,stopbits) + { + CSerial::Init_Registers(initBps,bytesize,parity,stopbits); + } + +CSerialDummy::~CSerialDummy() { +} + +void CSerialDummy::RXBufferEmpty() { +// no external buffer, not used here +} + +/*****************************************************************************/ +/* updatePortConfig is called when emulated app changes the serial port **/ +/* parameters baudrate, stopbits, number of databits, parity. **/ +/*****************************************************************************/ +void CSerialDummy::updatePortConfig(Bit8u dll, Bit8u dlm, Bit8u lcr) { + //LOG_MSG("Serial port at 0x%x: Port params changed: %d Baud", base,dcb.BaudRate); +} + +void CSerialDummy::updateMSR() { + changeMSR(0); +} + +void CSerialDummy::transmitByte(Bit8u val) { + ByteTransmitted(); + //LOG_MSG("UART 0x%x: TX 0x%x", base,val); +} + +/*****************************************************************************/ +/* setBreak(val) switches break on or off **/ +/*****************************************************************************/ + +void CSerialDummy::setBreak(bool value) { + //LOG_MSG("UART 0x%x: Break toggeled: %d", base, value); +} + +/*****************************************************************************/ +/* updateModemControlLines(mcr) sets DTR and RTS. **/ +/*****************************************************************************/ +void CSerialDummy::updateModemControlLines(/*Bit8u mcr*/) { +} + +void CSerialDummy::Timer2(void) { +} + diff --git a/src/hardware/serialport/serialdummy.h b/src/hardware/serialport/serialdummy.h new file mode 100644 index 00000000..0306a4ff --- /dev/null +++ b/src/hardware/serialport/serialdummy.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2002-2005 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: serialdummy.h,v 1.1 2005-07-30 14:41:31 qbix79 Exp $ */ + +#ifndef INCLUDEGUARD_SERIALDUMMY_H +#define INCLUDEGUARD_SERIALDUMMY_H + +#include "serialport.h" + +class CSerialDummy : public CSerial { +public: + + CSerialDummy( + IO_ReadHandler* rh, + IO_WriteHandler* wh, + TIMER_TickHandler th, + Bit16u baseAddr, + Bit8u initIrq, + Bit32u initBps, + Bit8u bytesize, + const char* parity, + Bit8u stopbits + ); + + + ~CSerialDummy(); + bool CanRecv(void); + bool CanSend(void); + void RXBufferEmpty(); + void updatePortConfig(Bit8u dll, Bit8u dlm, Bit8u lcr); + void updateMSR(); + void transmitByte(Bit8u val); + void setBreak(bool value); + void updateModemControlLines(/*Bit8u mcr*/); + void Timer2(void); +}; + +#endif // INCLUDEGUARD diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp new file mode 100644 index 00000000..c67d87cf --- /dev/null +++ b/src/hardware/serialport/serialport.cpp @@ -0,0 +1,1089 @@ +/* + * Copyright (C) 2002-2005 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.cpp,v 1.1 2005-07-30 14:41:31 qbix79 Exp $ */ + +#include +#include + +#include "dosbox.h" + +#include "support.h" +#include "inout.h" +#include "pic.h" +#include "setup.h" +#include "timer.h" + +#include "serialport.h" +#include "directserial_win32.h" +#include "serialdummy.h" +#include "softmodem.h" + +#define LOG_UART LOG_MSG + + +// COM1 - COM4 objects +static CSerial *serial1 = 0; +static CSerial *serial2 = 0; +static CSerial *serial3 = 0; +static CSerial *serial4 = 0; +//static CSerial** serialPortObjects[] = {NULL, &serial1,&serial2,&serial3,&serial4}; + +Bit8u serialGetComnumberByBaseAddress (Bit16u base) { + if (base == COM1_BASE) + return 1; + else if (base == COM2_BASE) + return 2; + else if (base == COM3_BASE) + return 3; + else if (base == COM4_BASE) + return 4; + else + return 255; // send thispointer to nirwana ;) +} + +// Usage of FastDelegates (http://www.codeproject.com/cpp/FastDelegate.asp) +// as I/O-Array would make many of these unneccessary. (member function pointer) + +//Some defines for repeated functions + +#define SERIAL_UPDATE(number) \ +void SERIAL##number##_Update(void) { \ + serial##number->Timer (); \ +} + +#define SERIAL_WRITE_TREE(number) \ +static void SERIAL##number##_Write (Bitu port, Bitu val, Bitu iolen) { \ + switch (port & 0x7) { \ + case THR_OFFSET: \ + serial##number ->Write_THR (val); \ + return; \ + case IER_OFFSET: \ + serial##number ->Write_IER (val); \ + return; \ + case LCR_OFFSET: \ + serial##number ->Write_LCR (val); \ + return; \ + case MCR_OFFSET: \ + serial##number ->Write_MCR (val); \ + return; \ + case MSR_OFFSET: \ + serial##number ->Write_MSR (val); \ + return; \ + case SPR_OFFSET: \ + serial##number ->Write_SPR (val); \ + return; \ + default: \ + serial##number ->Write_reserved (val, port & 0x7); \ + } \ +} + +#define SERIAL_READ_TREE(number) \ +static Bitu SERIAL##number##_Read (Bitu port, Bitu iolen) { \ + switch (port & 0x7) { \ + case RHR_OFFSET: \ + return serial##number ->Read_RHR (); \ + case IER_OFFSET: \ + return serial##number ->Read_IER (); \ + case ISR_OFFSET: \ + return serial##number ->Read_ISR (); \ + case LCR_OFFSET: \ + return serial##number ->Read_LCR (); \ + case MCR_OFFSET: \ + return serial##number ->Read_MCR (); \ + case LSR_OFFSET: \ + return serial##number ->Read_LSR (); \ + case MSR_OFFSET: \ + return serial##number ->Read_MSR (); \ + case SPR_OFFSET: \ + return serial##number ->Read_SPR (); \ + } \ + return 0; \ +} + +//The Functions + +SERIAL_UPDATE(1); +SERIAL_UPDATE(2); +SERIAL_UPDATE(3); +SERIAL_UPDATE(4); + +SERIAL_WRITE_TREE(1); +SERIAL_WRITE_TREE(2); +SERIAL_WRITE_TREE(3); +SERIAL_WRITE_TREE(4); + +SERIAL_READ_TREE(1); +SERIAL_READ_TREE(2); +SERIAL_READ_TREE(3); +SERIAL_READ_TREE(4); + +#undef SERIAL_UPDATE +#undef SERIAL_WRITE_TREE +#undef SERIAL_READ_TREE + +void CSerial::Timer (void) { + //LOG_UART("Serial port at %x: Timer", base); + if (loopback_pending) { +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Loopback sent back", base); +#endif + loopback_pending = false; + receiveByte (loopback_data); + ByteTransmitted (); + } + Timer2 (); +} + +/*****************************************************************************/ +/* Interrupt control routines **/ +/*****************************************************************************/ +void CSerial::rise (Bit8u priority) { + //LOG_UART("Serial port at %x: Rise priority 0x%x", base, priority); + waiting_interrupts |= priority; + WriteRealIER (IER); +} + +// clears the pending interrupt, triggers other waiting interrupt +void CSerial::clear (Bit8u priority) { + //LOG_UART("Serial port at %x: cleared priority 0x%x", base, priority); + waiting_interrupts &= (~priority); + WriteRealIER (IER); +} + +void CSerial::WriteRealIER (Bit8u data) { +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: write IER, value 0x%x", base, data); +#endif + data = data & 0xF; // THE UPPER ONES ALWAYS READ 0! NOTHIN' ELSE! + Bit8u old_pending_interrupts = pending_interrupts; + Bit8u difference_pending_interrupts; + + // rise TX AGAIN when present and is being enabled + if ((data & TX_PRIORITY) && (!(IER & TX_PRIORITY))) + if (LSR & LSR_TX_HOLDING_EMPTY_MASK) + waiting_interrupts |= TX_PRIORITY; + + pending_interrupts = waiting_interrupts & data; + if ((difference_pending_interrupts = (pending_interrupts ^ old_pending_interrupts))) { // something in pending interrupts has changed + if (difference_pending_interrupts & pending_interrupts) { // some new bits were set + if (!current_priority) { // activate interrupt.. + if (pending_interrupts & ERROR_PRIORITY) { + current_priority = ERROR_PRIORITY; + ISR = ISR_ERROR_VAL; + } else if (pending_interrupts & RX_PRIORITY) { + current_priority = RX_PRIORITY; + ISR = ISR_RX_VAL; + } else if (pending_interrupts & TX_PRIORITY) { + current_priority = TX_PRIORITY; + ISR = ISR_TX_VAL; + } else if (pending_interrupts & MSR_PRIORITY) { + current_priority = MSR_PRIORITY; + ISR = ISR_MSR_VAL; + } +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Interrupt activated: priority %d", base, current_priority); +#endif + PIC_ActivateIRQ (irq); + }// else the new interrupts were already + // written into pending_interrupts + }// else no new bits were set + + if (difference_pending_interrupts & (~pending_interrupts)) { // some bits were reset + if (pending_interrupts) { // some more are waiting + if (!(current_priority & pending_interrupts)) { // the current interrupt has been cleared + // choose the next one + if (pending_interrupts & ERROR_PRIORITY) { + current_priority = ERROR_PRIORITY; + ISR = ISR_ERROR_VAL; + } else if (pending_interrupts & RX_PRIORITY) { + current_priority = RX_PRIORITY; + ISR = ISR_RX_VAL; + } else if (pending_interrupts & TX_PRIORITY) { + current_priority = TX_PRIORITY; + ISR = ISR_TX_VAL; + } else if (pending_interrupts & MSR_PRIORITY) { + current_priority = MSR_PRIORITY; + ISR = ISR_MSR_VAL; + } + } + } else { + current_priority = NONE_PRIORITY; + ISR = ISR_CLEAR_VAL; + PIC_DeActivateIRQ (irq); +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Interrupt deactivated.", base); +#endif + } + } + } + IER = data; +} + + + +/*****************************************************************************/ +/* Internal register modification **/ +/*****************************************************************************/ +void CSerial::changeMSR (Bit8u data) { + if (!(MCR & MCR_LOOPBACK_Enable_MASK)) { + // see if something changed + if ((MSR & MSR_LINE_MASK) != data) { + Bit8u change = (MSR & MSR_LINE_MASK) ^ data; + // set new deltas + MSR |= (change >> 4); + // set new line states + MSR &= MSR_delta_MASK; + MSR |= data; + rise (MSR_PRIORITY); + } + } +} + +void CSerial::changeMSR_Loopback (Bit8u data) { + // see if something changed + if ((MSR & MSR_LINE_MASK) != data) { + Bit8u change = (MSR & MSR_LINE_MASK) ^ data; + // set new deltas + MSR |= (change >> 4); + // set new line states + MSR &= MSR_delta_MASK; + MSR |= data; + rise (MSR_PRIORITY); + } + +/* + Bit8u temp=MSR; + // look for signal changes + if(temp|=((data&MSR_LINE_MASK)^(MSR&MSR_LINE_MASK))>>4) + { // some signals changed + temp&=MSR_delta_MASK;// clear line states + temp|=(data&MSR_LINE_MASK); // set new line states + + MSR=temp; + rise(MSR_PRIORITY); + } + // else nothing happened*/ +} + +/*****************************************************************************/ +/* Can a byte be received? **/ +/*****************************************************************************/ +bool CSerial::CanReceiveByte() { + return (LSR & LSR_RX_DATA_READY_MASK) == 0; +} + +/*****************************************************************************/ +/* A byte was received **/ +/*****************************************************************************/ +void CSerial::receiveByte (Bit8u data) { +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: byte received: %d", base, data); +#endif + + if (LSR & LSR_RX_DATA_READY_MASK) { // Overrun error ;o + LOG_UART ("Serial port at %x: RX Overrun!", base, data); + LSR |= LSR_OVERRUN_ERROR_MASK; + rise (ERROR_PRIORITY); + } else { + RHR = data; + LSR |= LSR_RX_DATA_READY_MASK; + rise (RX_PRIORITY); + } +} + +/*****************************************************************************/ +/* A line error was received **/ +/*****************************************************************************/ +void CSerial::receiveError (Bit8u errorword) { + LSR |= errorword; + + rise (ERROR_PRIORITY); +} + +/*****************************************************************************/ +/* ByteTransmitted: When a byte was sent, notify here. **/ +/*****************************************************************************/ +void CSerial::ByteTransmitted () { + if (LSR & LSR_TX_HOLDING_EMPTY_MASK) { // one space was empty + // now both are + LSR |= LSR_TX_EMPTY_MASK; + } else { // both were full, now 1 is empty + if (MCR & MCR_LOOPBACK_Enable_MASK) { // loopback mode + transmitLoopbackByte (THR); + } else { // direct "real" mode + transmitByte (THR); + } + LSR |= LSR_TX_HOLDING_EMPTY_MASK; + } + rise (TX_PRIORITY); +} + +/*****************************************************************************/ +/* Transmit Holding Register, also LSB of Divisor Latch (r/w) **/ +/*****************************************************************************/ +void CSerial::Write_THR (Bit8u data) { + if ((LCR & LCR_DIVISOR_Enable_MASK)) { +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Write to DLL value 0x%x", base, data); +#endif + // write to DLL + DLL = data; + updatePortConfig (DLL, DLM, LCR); + } else { +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Write to THR value 0x%x", base, data); +#endif + + // write to THR + clear (TX_PRIORITY); + + if (LSR & LSR_TX_HOLDING_EMPTY_MASK) { // one is empty + if (LSR & LSR_TX_EMPTY_MASK) { // both are empty + LSR &= (~LSR_TX_EMPTY_MASK); + + if (MCR & MCR_LOOPBACK_Enable_MASK) { // loopback mode + transmitLoopbackByte (data); + } else { // direct "real" mode + transmitByte (data); + } + rise (TX_PRIORITY); + } else { // only THR is empty; add byte and clear holding bit + LSR &= (~LSR_TX_HOLDING_EMPTY_MASK); + THR = data; + } + } else { +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: TX Overflow!", base); +#endif + // TX overflow; how does real hardware respond to that... I do nothing + } + } +} + + +/*****************************************************************************/ +/* Receive Holding Register, also LSB of Divisor Latch (r/w) **/ +/*****************************************************************************/ +Bitu CSerial::Read_RHR () { + Bit8u retval; + if ((LCR & LCR_DIVISOR_Enable_MASK)) { +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Read from DLL value 0x%x", base, DLL); +#endif + return DLL; + } else { + clear (RX_PRIORITY); + LSR &= (~LSR_RX_DATA_READY_MASK); + retval = RHR; + RXBufferEmpty (); // <--- this one changes RHR + +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Read from RHR value 0x%x", base, retval); +#endif + + return retval; + } +} + +/*****************************************************************************/ +/* Interrupt Enable Register, also MSB of Divisor Latch (r/w) **/ +/*****************************************************************************/ +// Modified by: +// - writing to it. +Bitu CSerial::Read_IER () { + if ((LCR & LCR_DIVISOR_Enable_MASK)) { // IER or MSB? +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Read from DLM value 0x%x", base, DLM); +#endif + return DLM; + } else { +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Read from IER value 0x%x", base, IER); +#endif + return IER; + } +} + +void CSerial::Write_IER (Bit8u data) { + if ((LCR & LCR_DIVISOR_Enable_MASK)) { // write to DLM +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Write to DLM value 0x%x", base, data); +#endif + + DLM = data; + updatePortConfig (DLL, DLM, LCR); + } else { +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Write to IER value 0x%x", base, data); +#endif + WriteRealIER (data); + } +} + +/*****************************************************************************/ +/* Interrupt Status Register (r) **/ +/*****************************************************************************/ +// modified by: +// - incoming interrupts +// - loopback mode +Bitu CSerial::Read_ISR () { + Bit8u retval = ISR; + + // clear changes ISR!! mean.. + clear (TX_PRIORITY); +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Read from ISR value 0x%x", base, retval); +#endif + return retval; +} + +/*****************************************************************************/ +/* Line Control Register (r/w) **/ +/*****************************************************************************/ +// signal decoder configuration: +// - parity, stopbits, word length +// - send break +// - switch between RHR/THR and baud rate registers +// Modified by: +// - writing to it. +Bitu CSerial::Read_LCR () { +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Read from LCR value 0x%x", base, LCR); +#endif + return LCR; +} + +void CSerial::Write_LCR (Bit8u data) { + Bit8u lcr_old = LCR; + LCR = data; +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Write to LCR value 0x%x", base, data); + + // for debug output + if (((data ^ lcr_old) & LCR_DIVISOR_Enable_MASK) != 0) { + if ((data & LCR_DIVISOR_Enable_MASK) != 0) + LOG_UART ("Serial port at %x: Divisor-mode entered", base); + + else + LOG_UART ("Serial port at %x: Divisor-mode exited", base); + } +#endif + if (((data ^ lcr_old) & LCR_PORTCONFIG_MASK) != 0) { +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: comm parameters changed", base); +#endif + updatePortConfig (DLL, DLM, LCR); + } + if (((data ^ lcr_old) & LCR_BREAK_MASK) != 0) { + setBreak ((LCR & LCR_BREAK_MASK) != 0); + +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: break toggled: %d", base, + (LCR & LCR_BREAK_MASK) != 0); +#endif + } +} + +/*****************************************************************************/ +/* Modem Control Register (r/w) **/ +/*****************************************************************************/ +// Set levels of RTS and DTR, as well as loopback-mode. +// Modified by: +// - writing to it. +Bitu CSerial::Read_MCR () { +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Read from MCR value 0x%x", base, MCR); +#endif + return MCR; +} + +void CSerial::Write_MCR (Bit8u data) { +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Write to MCR value 0x%x", base, data); +#endif + data &= 0x1F; // UPPER BITS ALWAYS 0!!! + + if (MCR & MCR_LOOPBACK_Enable_MASK) + if (data & MCR_LOOPBACK_Enable_MASK) { // was on, is now on + Bit8u param = 0; + + // RTS->CD + // DTR->RI + // OP1->DSR + // OP2->CTS + + if (data & MCR_RTS_MASK) + param |= MSR_CD_MASK; + if (data & MCR_DTR_MASK) + param |= MSR_RI_MASK; + if (data & MCR_OP1_MASK) + param |= MSR_DSR_MASK; + if (data & MCR_OP2_MASK) + param |= MSR_CTS_MASK; + + changeMSR_Loopback (param); + + } else { + MCR = data; + updateModemControlLines (); + // is switched off now + } else { + if (data & MCR_LOOPBACK_Enable_MASK) { // is switched on: + Bit8u par = 0; + if (data & MCR_RTS_MASK) + par |= MSR_CD_MASK; + if (data & MCR_DTR_MASK) + par |= MSR_RI_MASK; + if (data & MCR_OP1_MASK) + par |= MSR_DSR_MASK; + if (data & MCR_OP2_MASK) + par |= MSR_CTS_MASK; + + changeMSR_Loopback (par); + + // go back to empty state + LSR &= (LSR_TX_EMPTY_MASK | LSR_TX_HOLDING_EMPTY_MASK); + + } else { + MCR = data; + updateModemControlLines (); + // loopback is off + } + } + MCR = data; +} + +/*****************************************************************************/ +/* Line Status Register (r) **/ +/*****************************************************************************/ +// errors, tx registers status, rx register status +// modified by: +// - event from real serial port +// - loopback +Bitu CSerial::Read_LSR () { + Bitu retval = LSR; + LSR &= (~LSR_ERROR_MASK); // clear error bits on read + clear (ERROR_PRIORITY); + +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Read from LSR value 0x%x", base, retval); +#endif + return retval; +} + +void CSerial::Write_MSR (Bit8u val) { +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Write to MSR, value 0x%x", base, val); +#endif + MSR &= MSR_LINE_MASK; + MSR |= val & MSR_delta_MASK; +} + +/*****************************************************************************/ +/* Modem Status Register (r) **/ +/*****************************************************************************/ +// Contains status of the control input lines (CD, RI, DSR, CTS) and +// their "deltas": if level changed since last read delta = 1. +// modified by: +// - real values +// - write operation to MCR in loopback mode +Bitu CSerial::Read_MSR () { + Bit8u retval; + if (!(MCR & MCR_LOOPBACK_Enable_MASK)) { + updateMSR (); + } + retval = MSR; + clear (MSR_PRIORITY); + // clear deltas + MSR &= MSR_LINE_MASK; +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Read from MSR value 0x%x", base, retval); +#endif + return retval; +} + +/*****************************************************************************/ +/* Scratchpad Register (r/w) **/ +/*****************************************************************************/ +// Just a memory register. Not much to do here. +Bitu CSerial::Read_SPR () { +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Read from SPR value 0x%x", base, SPR); +#endif + return SPR; +} + +void CSerial::Write_SPR (Bit8u data) { +#ifdef SERIALPORT_DEBUGMSG + LOG_UART ("Serial port at %x: Write to SPR value 0x%x", base, data); +#endif + SPR = data; +} + +/*****************************************************************************/ +/* Write_reserved **/ +/*****************************************************************************/ +void CSerial::Write_reserved (Bit8u data, Bit8u address) { + LOG_UART("Serial port at %x: Write to reserved register, value 0x%x, register %x", base, data, address); +} + +/*****************************************************************************/ +/* Loopback: add byte to loopback buffer; it is received next time Timer **/ +/* function is invoked; (time needed is not emulated correctly, but I don't **/ +/* think this is sooooo important....) **/ +/*****************************************************************************/ +void CSerial::transmitLoopbackByte (Bit8u val) { + //LOG_MSG("Serial port at %x: Loopback requested", base); + loopback_pending = true; + loopback_data = val; +} + +/*****************************************************************************/ +/* MCR Access: returns cirquit state as boolean. **/ +/*****************************************************************************/ +bool CSerial::getDTR () { + return (MCR & MCR_DTR_MASK) != 0; +} + +bool CSerial::getRTS () { + return (MCR & MCR_RTS_MASK) != 0; +} + +/*****************************************************************************/ +/* MSR Access **/ +/*****************************************************************************/ +bool CSerial::getRI () { + return (MSR & MSR_RI_MASK) != 0; +} + +bool CSerial::getCD () { + return (MSR & MSR_CD_MASK) != 0; +} + +bool CSerial::getDSR () { + return (MSR & MSR_DSR_MASK) != 0; +} + +bool CSerial::getCTS () { + return (MSR & MSR_CTS_MASK) != 0; +} + +// these give errors if invoked while loopback mode... but who cares. +void CSerial::setRI (bool value) { + bool compare = ((MSR & MSR_RI_MASK) != 0); + if (value != compare) { + if (value) + MSR |= MSR_RI_MASK; + else + MSR &= (~MSR_RI_MASK); + MSR |= MSR_dRI_MASK; + rise (MSR_PRIORITY); + } + //else no change +} +void CSerial::setDSR (bool value) { + bool compare = ((MSR & MSR_DSR_MASK) != 0); + if (value != compare) { + if (value) + MSR |= MSR_DSR_MASK; + else + MSR &= (~MSR_DSR_MASK); + MSR |= MSR_dDSR_MASK; + rise (MSR_PRIORITY); + } + //else no change +} +void CSerial::setCD (bool value) { + bool compare = ((MSR & MSR_CD_MASK) != 0); + if (value != compare) { + if (value) + MSR |= MSR_CD_MASK; + else + MSR &= (~MSR_CD_MASK); + MSR |= MSR_dCD_MASK; + rise (MSR_PRIORITY); + } + //else no change +} +void CSerial::setCTS (bool value) { + bool compare = ((MSR & MSR_CTS_MASK) != 0); + if (value != compare) { + if (value) + MSR |= MSR_CTS_MASK; + else + MSR &= (~MSR_CTS_MASK); + MSR |= MSR_dCTS_MASK; + rise (MSR_PRIORITY); + } + //else no change +} + +/*****************************************************************************/ +/* Initialisation **/ +/*****************************************************************************/ +void CSerial::Init_Registers (Bit32u initbps, Bit8u bytesize, + const char *parity, Bit8u stopbits) { + Bit8u lcrresult = 0; + Bit16u baudresult = 0; + + RHR = 0; + THR = 0; + IER = 0; + ISR = 0x1; + LCR = 0; + MCR = 0; + LSR = 0x60; + MSR = 0; + + SPR = 0xFF; + + DLL = 0x0; + DLM = 0x0; + + pending_interrupts = 0x0; + current_priority = 0x0; + waiting_interrupts = 0x0; + loopback_pending = false; + + + // make lcr: byte size, parity, stopbits, baudrate + + if (bytesize == 5) + lcrresult |= LCR_DATABITS_5; + else if (bytesize == 6) + lcrresult |= LCR_DATABITS_6; + else if (bytesize == 7) + lcrresult |= LCR_DATABITS_7; + else + lcrresult |= LCR_DATABITS_8; + + if (parity[0] == 'O' || parity[0] == 'o') + lcrresult |= LCR_PARITY_ODD; + else if (parity[0] == 'E' || parity[0] == 'e') + lcrresult |= LCR_PARITY_EVEN; + else if (parity[0] == 'M' || parity[0] == 'm') + lcrresult |= LCR_PARITY_MARK; + else if (parity[0] == 'S' || parity[0] == 's') + lcrresult |= LCR_PARITY_SPACE; + else + lcrresult |= LCR_PARITY_NONE; + + if (stopbits == 2) + lcrresult |= LCR_STOPBITS_MORE_THAN_1; + else + lcrresult |= LCR_STOPBITS_1; + + // baudrate + + if (initbps > 0) + baudresult = (Bit16u) (115200 / initbps); + else + baudresult = 12; // = 9600 baud + + Write_LCR (LCR_DIVISOR_Enable_MASK); + Write_THR ((Bit8u) baudresult & 0xff); + Write_IER ((Bit8u) (baudresult >> 8)); + Write_LCR (lcrresult); +} + +CSerial::CSerial(IO_ReadHandler * rh, IO_WriteHandler * wh, TIMER_TickHandler th, + Bit16u initbase, Bit8u initirq, Bit32u initbps, Bit8u bytesize, + const char *parity, Bit8u stopbits) { + base = initbase; + irq = initirq; + TimerHnd = th; // for destructor + TIMER_AddTickHandler(TimerHnd); + + for (Bitu i = 0; i <= 7; i++) { + WriteHandler[i].Install (i + base, wh, IO_MB); + ReadHandler[i].Install (i + base, rh, IO_MB); + } +}; + +CSerial::~CSerial(void) { + TIMER_DelTickHandler(TimerHnd); +}; + +bool getParameter(char *input, char *buffer, const char *parametername, + Bitu buffersize) { + Bitu outputPos = 0; + Bitu currentState = 0; // 0 = before '=' 1 = after '=' 2 = in word + Bitu startInputPos; + Bitu inputPos; + char *res1 = strstr(input, parametername); + if (res1 == 0) + return false; + inputPos = res1 - input; + inputPos += strlen (parametername); + startInputPos = inputPos; + while (input[inputPos] != 0 && outputPos + 2 < buffersize) { + if (currentState == 0) { + if (input[inputPos] == ' ') + inputPos++; + else if (input[inputPos] == ':') { + currentState = 1; + inputPos++; + } else + return false; + } else if (currentState == 1) { + if (input[inputPos] == ' ') + inputPos++; + else { + currentState = 2; + buffer[outputPos] = input[inputPos]; + outputPos++; + inputPos++; + } + + } else { + if (input[inputPos] == ' ') { + buffer[outputPos] = 0; + return true; + } else { + buffer[outputPos] = input[inputPos]; + outputPos++; + inputPos++; + } + } + } + buffer[outputPos] = 0; + if (inputPos == startInputPos) + return false; + return true; +} + +// functions for parsing the config line +bool scanNumber (char *scan, Bitu * retval) { + *retval = 0; + + while (char c = *scan) { + if (c >= '0' && c <= '9') { + *retval *= 10; + *retval += c - '0'; + scan++; + } else + return false; + } + return true; +} + +bool getFirstWord (char *input, char *buffer, Bitu buffersize) { + Bitu outputPointer = 0; + Bitu currentState = 0; // 0 = scanning spaces 1 = in word + Bitu currentPos = 0; + while (input[currentPos] != 0 && outputPointer + 2 < buffersize) { + if (currentState == 0) { + if (input[currentPos] != ' ') { + currentState = 1; + buffer[outputPointer] = input[currentPos]; + outputPointer++; + } + } else { + if (input[currentPos] == ' ') { + buffer[outputPointer] = 0; + return true; + } else { + buffer[outputPointer] = input[currentPos]; + outputPointer++; + } + } + currentPos++; + } + buffer[outputPointer] = 0; // end of string + if (currentState == 0) + return false; + else + return true; +} + +void BIOS_SetComPorts (Bit16u baseaddr[]); + +class SERIALPORTS:public Module_base { +public: + CSerial ** serialPortObjects[4]; + SERIALPORTS (Section * configuration):Module_base (configuration) { + // put handlers into arrays + IO_ReadHandler *serialReadHandlers[] = { + &SERIAL1_Read, &SERIAL2_Read, &SERIAL3_Read, &SERIAL4_Read + }; + IO_WriteHandler *serialWriteHandlers[] = { + &SERIAL1_Write, &SERIAL2_Write, &SERIAL3_Write, &SERIAL4_Write + }; + TIMER_TickHandler serialTimerHandlers[] = { + &SERIAL1_Update, &SERIAL2_Update, &SERIAL3_Update, &SERIAL4_Update + }; + + // default ports & interrupts + Bit16u addresses[] = { COM1_BASE, COM2_BASE, COM3_BASE, COM4_BASE }; + Bit8u defaultirq[] = { 4, 3, 4, 3 }; + Bit16u biosParameter[4] = { 0, 0, 0, 0 }; + Section_prop *section = static_cast (configuration); + char tmpbuffer[15]; + + const char *configstringsconst[4] = { + section->Get_string ("serial1"), + section->Get_string ("serial2"), + section->Get_string ("serial3"), + section->Get_string ("serial4") + }; + /* Create copies so they can be modified */ + char *configstrings[4] = { 0 }; + for(Bitu i = 0;i < 4;i++) { + size_t len = strlen(configstringsconst[i]); + configstrings[i] = new char[len+1]; + strcpy(configstrings[i],configstringsconst[i]); + configstrings[i] = upcase(configstrings[i]); + } + + serialPortObjects[0] = &serial1; + serialPortObjects[1] = &serial2; + serialPortObjects[2] = &serial3; + serialPortObjects[3] = &serial4; + + // iterate through all 4 com ports + for (Bitu i = 0; i < 4; i++) { + Bit16u baseAddress = addresses[i]; + Bitu irq = defaultirq[i]; + Bitu bps = 9600; + Bitu bytesize = 8; + Bitu stopbits = 1; + char parity = 'N'; + biosParameter[i] = baseAddress; + + // parameter: irq + if (getParameter(configstrings[i], tmpbuffer, "IRQ", sizeof (tmpbuffer))) { + if (scanNumber (tmpbuffer, &irq)) { + if (irq < 0 || irq == 2 || irq > 15) + irq = defaultirq[i]; + } else + irq = defaultirq[i]; + } + // parameter: bps + if (getParameter(configstrings[i], tmpbuffer, "STARTBPS", sizeof (tmpbuffer))) { + if (scanNumber (tmpbuffer, &bps)) { + if (bps <= 0) + bps = 9600; + } else + bps = 9600; + } + // parameter: bytesize + if (getParameter(configstrings[i], tmpbuffer, "BYTESIZE", sizeof (tmpbuffer))) { + if (scanNumber (tmpbuffer, &bytesize)) { + if (bytesize < 5 || bytesize > 8) + bytesize = 8; + } else + bytesize = 8; + } + // parameter: stopbits + if (getParameter(configstrings[i], tmpbuffer, "STOPBITS", sizeof (tmpbuffer))) { + if (scanNumber (tmpbuffer, &stopbits)) { + if (stopbits < 1 || stopbits > 2) + stopbits = 1; + } else + stopbits = 1; + } + // parameter: parity + if (getParameter(configstrings[i], tmpbuffer, "PARITY", sizeof (tmpbuffer))) { + if (!(tmpbuffer[0] == 'N' || tmpbuffer[0] == 'O' || tmpbuffer[0] == 'E' + || tmpbuffer[0] == 'M' || tmpbuffer[0] == 'S')) + tmpbuffer[0] = 'N'; + parity = tmpbuffer[0]; + } + //LOG_MSG("COM%d: %s",i+1,configstrings[i]); + if (getFirstWord (configstrings[i], tmpbuffer, sizeof (tmpbuffer))) { + //LOG_MSG("COM%d: %s",i+1,tmpbuffer); + if (!strcmp (tmpbuffer, "DUMMY")) { + *serialPortObjects[i] = new CSerialDummy (serialReadHandlers[i], serialWriteHandlers[i],serialTimerHandlers[i], baseAddress, irq, bps,bytesize, &parity, stopbits); + } +#ifdef DIRECTSERIAL_AVAILIBLE + else if (!strcmp (tmpbuffer, "DIRECTSERIAL")) { + // parameter: realport + if (getParameter (configstrings[i], tmpbuffer, "REALPORT", sizeof (tmpbuffer))) { // realport is required + CDirectSerial *cdstemp = new CDirectSerial (serialReadHandlers[i], serialWriteHandlers[i], serialTimerHandlers[i], baseAddress, irq, bps,bytesize, &parity,stopbits,tmpbuffer); + + if (cdstemp->InstallationSuccessful) { + *serialPortObjects[i] = cdstemp; + } else { // serial port name was wrong or already in use + delete cdstemp; + *serialPortObjects[i] = NULL; + biosParameter[i] = 0; + } + + } else { + *serialPortObjects[i] = NULL; + biosParameter[i] = 0; + } + } +#endif +#if C_MODEM + else if (!strcmp (tmpbuffer, "MODEM")) { + Bitu listenport = 23; + // parameter: listenport + if (getParameter(configstrings[i], tmpbuffer, "LISTENPORT", sizeof (tmpbuffer))) { + if (scanNumber (tmpbuffer, &listenport)) { + if (listenport <= 0 || listenport > 65535) + listenport = 23; + } else + listenport = 23; + } + + *serialPortObjects[i] = new CSerialModem (serialReadHandlers[i], serialWriteHandlers[i], serialTimerHandlers[i], baseAddress, irq, bps,bytesize, &parity, stopbits, 0, listenport); + } +#endif + else if (!strcmp (tmpbuffer, "DISABLED")) { + *serialPortObjects[i] = NULL; + biosParameter[i] = 0; + } else { + LOG_MSG ("Invalid type for COM%d.", i + 1); + *serialPortObjects[i] = NULL; + biosParameter[i] = 0; + } + } else { + *serialPortObjects[i] = NULL; + biosParameter[i] = 0; + } + } + + delete [] configstrings[0];delete [] configstrings[1]; + delete [] configstrings[2];delete [] configstrings[3]; + BIOS_SetComPorts (biosParameter); + } + + ~SERIALPORTS () { + for (Bitu i = 0; i < 4; i++) + if (*serialPortObjects[i]) { + delete *(serialPortObjects[i]); + *(serialPortObjects[i]) = 0; + } + } +}; + +static SERIALPORTS *testSerialPortsBaseclass; + +void SERIAL_Destroy (Section * sec) { + delete testSerialPortsBaseclass; + testSerialPortsBaseclass = NULL; +} + +void SERIAL_Init (Section * sec) { + // should never happen + if (testSerialPortsBaseclass) delete testSerialPortsBaseclass; + testSerialPortsBaseclass = new SERIALPORTS (sec); + sec->AddDestroyFunction (&SERIAL_Destroy, true); +} diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp new file mode 100644 index 00000000..7b9ca4b5 --- /dev/null +++ b/src/hardware/serialport/softmodem.cpp @@ -0,0 +1,826 @@ +/* + * Copyright (C) 2002-2005 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: softmodem.cpp,v 1.1 2005-07-30 14:41:31 qbix79 Exp $ */ + +#include "dosbox.h" + +#if C_MODEM + +#include +#include +#include + +#include "SDL_net.h" + +#include "support.h" +#include "timer.h" +#include "serialport.h" +#include "softmodem.h" + +//#include "mixer.h" + + +CSerialModem::CSerialModem( + IO_ReadHandler* rh, + IO_WriteHandler* wh, + TIMER_TickHandler th, + Bit16u baseAddr, + Bit8u initIrq, + Bit32u initBps, + Bit8u bytesize, + const char* parity, + Bit8u stopbits, + const char *remotestr, + Bit16u lport) + : CSerial(rh, wh, th, + baseAddr, initIrq, initBps, bytesize, parity, stopbits) { + socket=0; + incomingsocket=0; + + if(!SDLNetInited) { + if(SDLNet_Init()==-1) { + LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); + return; + } + SDLNetInited = true; + } + rqueue=new CFifo(MODEM_BUFFER_QUEUE_SIZE); + tqueue=new CFifo(MODEM_BUFFER_QUEUE_SIZE); + + //cmdpos = 0; + + //plusinc = 0; + //incomingsocket = 0; +// answermode = false; + //memset(®,0,sizeof(reg)); + //cmdpause = 0; + //echo = true; + //doresponse = true; + //numericresponse = false; + + /* Default to direct null modem connection. Telnet mode interprets IAC codes */ + telnetmode = false; + + /* Initialize the sockets and setup the listening port */ + socketset = SDLNet_AllocSocketSet(1); + listensocketset = SDLNet_AllocSocketSet(1); + if (!socketset || !listensocketset) { + LOG_MSG("MODEM:Can't open socketset:%s",SDLNet_GetError()); + //TODO Should probably just exit + return; + } + socket=0; + listenport=lport; + if (listenport) { + IPaddress listen_ip; + SDLNet_ResolveHost(&listen_ip, NULL, listenport); + listensocket=SDLNet_TCP_Open(&listen_ip); + if (!listensocket) LOG_MSG("MODEM:Can't open listen port: %s",SDLNet_GetError()); + + else LOG_MSG("MODEM: Port listener installed at port %d",listenport); + + } + else listensocket=0; + + // TODO: Fix dialtones if requested + //mhd.chan=MIXER_AddChannel((MIXER_MixHandler)this->MODEM_CallBack,8000,"MODEM"); + //MIXER_Enable(mhd.chan,false); + //MIXER_SetMode(mhd.chan,MIXER_16MONO); + + Reset(); + //EnterIdleState(); + CSerial::Init_Registers(initBps,bytesize,parity,stopbits); + } + + CSerialModem::~CSerialModem() { + if(socket) { + SDLNet_TCP_DelSocket(socketset,socket); + SDLNet_TCP_Close(socket); + } + + if(listensocket) SDLNet_TCP_Close(listensocket); + if(socketset) SDLNet_FreeSocketSet(socketset); + + delete rqueue; + delete tqueue; + } + +void CSerialModem::SendLine(const char *line) { + rqueue->addb(0xd); + rqueue->addb(0xa); + rqueue->adds((Bit8u *)line,strlen(line)); + rqueue->addb(0xd); + rqueue->addb(0xa); +} + +// only for numbers < 1000... +void CSerialModem::SendNumber(Bitu val) { + rqueue->addb(0xd); + rqueue->addb(0xa); + + rqueue->addb(val/100+'0'); + val = val%100; + rqueue->addb(val/10+'0'); + val = val%10; + rqueue->addb(val+'0'); + + rqueue->addb(0xd); + rqueue->addb(0xa); +} + +void CSerialModem::SendRes(ResTypes response) { + char * string;Bitu /*char **/ code; + switch (response) + { + case ResNONE: return; + case ResOK: string="OK"; code=0; break; + case ResERROR: string="ERROR"; code=4; break; + case ResRING: string="RING"; code=2; break; + case ResNODIALTONE: string="NO DIALTONE"; code=6; break; + case ResNOCARRIER: string="NO CARRIER" ;code=3; break; + case ResCONNECT: string="CONNECT 57600"; code=1; break; + } + + if(doresponse!=1) { + if(doresponse==2 && (response==ResRING || + response == ResCONNECT || response==ResNOCARRIER)) return; + if(numericresponse) + //{ + SendNumber(code); + // rqueue->addb(*code+'0'); + // rqueue->addb(0xd);rqueue->addb(0xa); + //} + else + //{ + SendLine(string); + //rqueue->addb(0xd);rqueue->addb(0xa); + //rqueue->adds((Bit8u *)string,strlen(string)); + //rqueue->addb(0xd);rqueue->addb(0xa); + //} + //if(CSerial::CanReceiveByte()) // very fast response + // if(rqueue->inuse() && CSerial::getRTS()) + // { Bit8u rbyte =rqueue->getb(); + // CSerial::receiveByte(rbyte); + // LOG_MSG("Modem: sending byte %2x back to UART2",rbyte); + // } + + LOG_MSG("Modem response: %s", string); + } +} + +void CSerialModem::openConnection(void) { + if (socket) { + LOG_MSG("Huh? already connected"); + SDLNet_TCP_DelSocket(socketset,socket); + SDLNet_TCP_Close(socket); + } + socket = SDLNet_TCP_Open(&openip); + //if (!socket) + +} + +bool CSerialModem::Dial(char * host) { + char* helper; + // scan for and remove spaces; weird bug: with leading spaces in the string, + // SDLNet_ResolveHost will return no error but not work anyway (win) + while(host[0]==' ') host++; + helper=host; + helper+=strlen(host); + while(helper[0]==' ') { + helper[0]=0; + helper--; + } + + /* Scan host for port */ + Bit16u port; + char * hasport=strrchr(host,':'); + if (hasport) { + *hasport++=0; + port=(Bit16u)atoi(hasport); + } + else port=MODEM_DEFAULT_PORT; + /* Resolve host we're gonna dial */ + LOG_MSG("Connecting to host %s port %d",host,port); + if (!SDLNet_ResolveHost(&openip,host,port)) { + openConnection(); + EnterConnectedState(); + return true; + } else { + LOG_MSG("Failed to resolve host %s: %s",host,SDLNet_GetError()); + SendRes(ResNODIALTONE); + EnterIdleState(); + return false; + } +} + +void CSerialModem::AcceptIncomingCall(void) { +// assert(!socket); + socket=incomingsocket; + SDLNet_TCP_AddSocket(socketset,socket); + incomingsocket = 0; + EnterConnectedState(); +} + +Bitu CSerialModem::ScanNumber(char * & scan) { + Bitu ret=0; + while (char c=*scan) { + if (c>='0' && c<='9') { + ret*=10; + ret+=c-'0'; + scan++; + } else break; + } + return ret; +} + +void CSerialModem::Reset(){ + EnterIdleState(); + cmdpos = 0; + cmdbuf[0]=0; + oldDTRstate = getDTR(); + + plusinc = 0; + incomingsocket = 0; + //answermode = false; // no autoanswer + memset(®,0,sizeof(reg)); + reg[MREG_AUTOANSWER_COUNT]=0; // no autoanswer + reg[MREG_RING_COUNT] = 1; + reg[MREG_ESCAPE_CHAR]='+'; + reg[MREG_CR_CHAR]='\r'; + reg[MREG_LF_CHAR]='\n'; + reg[MREG_BACKSPACE_CHAR]='\b'; + + cmdpause = 0; + echo = true; + doresponse = 0; + numericresponse = false; + + /* Default to direct null modem connection. Telnet mode interprets IAC codes */ + telnetmode = false; +} + +void CSerialModem::EnterIdleState(void){ + connected=false; + ringing=false; + txbufferfull=false; + + if(socket) { // clear current socket + SDLNet_TCP_DelSocket(socketset,socket); + SDLNet_TCP_Close(socket); + socket=0; + } + if(incomingsocket) { // clear current incoming socket + SDLNet_TCP_DelSocket(socketset,incomingsocket); + SDLNet_TCP_Close(incomingsocket); + } + // get rid of everything + while(incomingsocket=SDLNet_TCP_Accept(listensocket)) { + SDLNet_TCP_DelSocket(socketset,incomingsocket); + SDLNet_TCP_Close(incomingsocket); + } + incomingsocket=0; + + commandmode = true; + CSerial::setCD(false); + CSerial::setRI(false); + tqueue->clear(); +} + +void CSerialModem::EnterConnectedState(void) { + if(socket) { + SDLNet_TCP_AddSocket(socketset,socket); + SendRes(ResCONNECT); + commandmode = false; + memset(&telClient, 0, sizeof(telClient)); + connected = true; + ringing = false; + CSerial::setCD(true); + CSerial::setRI(false); + } else { + SendRes(ResNOCARRIER); + EnterIdleState(); + } +} + +void CSerialModem::DoCommand() { + cmdbuf[cmdpos] = 0; + cmdpos = 0; //Reset for next command + upcase(cmdbuf); + LOG_MSG("Command sent to modem: ->%s<-\n", cmdbuf); + /* Check for empty line, stops dialing and autoanswer */ + if (!cmdbuf[0]) { + reg[0]=0; // autoanswer off + //answermode = false; + return;//goto ret_none; + // } + //else { + //MIXER_Enable(mhd.chan,false); + // dialing = false; + // SendRes(ResNOCARRIER); + // goto ret_none; + // } + } + /* AT command set interpretation */ + + if ((cmdbuf[0] != 'A') || (cmdbuf[1] != 'T')) { + SendRes(ResERROR); + return;//goto ret_error; + } + + if (strstr(cmdbuf,"NET0")) { + telnetmode = false; + SendRes(ResOK); + return; + } + else if (strstr(cmdbuf,"NET1")) { + telnetmode = true; + SendRes(ResOK); + return; + } + + /* Check for dial command */ + if(strncmp(cmdbuf,"ATD3",3)==0) { + char * foundstr=&cmdbuf[3]; + if (*foundstr=='T' || *foundstr=='P') foundstr++; + /* Small protection against empty line */ + if (!foundstr[0]) { + SendRes(ResERROR);//goto ret_error; + return; + } + if (strlen(foundstr) >= 12) { + // Check if supplied parameter only consists of digits + bool isNum = true; + for (Bitu i=0; i '9') + isNum = false; + if (isNum) { + // Parameter is a number with at least 12 digits => this cannot be a valid IP/name + // Transform by adding dots + char buffer[128]; + Bitu j = 0; + for (Bitu i=0; i12) + buffer[j++] = ':'; + } + buffer[j] = 0; + foundstr = buffer; + } + } + Dial(foundstr); + return;//goto ret_none; + } + char * scanbuf; + scanbuf=&cmdbuf[2]; + char chr; + Bitu num; + while (chr=*scanbuf++) { + switch (chr) { + case 'I': //Some strings about firmware + switch (num=ScanNumber(scanbuf)) { + case 3:SendLine("DosBox Emulated Modem Firmware V1.00");break; + case 4:SendLine("Modem compiled for DosBox version " VERSION);break; + };break; + case 'E': //Echo on/off + switch (num=ScanNumber(scanbuf)) { + case 0:echo = false;break; + case 1:echo = true;break; + };break; + case 'V': + switch (num=ScanNumber(scanbuf)) { + case 0:numericresponse = true;break; + case 1:numericresponse = false;break; + };break; + case 'H': //Hang up + switch (num=ScanNumber(scanbuf)) { + case 0: + if (connected) { + SendRes(ResNOCARRIER); + EnterIdleState(); + return;//goto ret_none; + } + //Else return ok + };break; + case 'O': //Return to data mode + switch (num=ScanNumber(scanbuf)) + { + case 0: + if (socket) { + commandmode = false; + return;//goto ret_none; + } else { + SendRes(ResERROR); + return;//goto ret_none; + } + };break; + case 'T': //Tone Dial + case 'P': //Pulse Dial + break; + case 'M': //Monitor + case 'L': //Volume + ScanNumber(scanbuf); + break; + case 'A': //Answer call + if (incomingsocket) { + AcceptIncomingCall(); + } else { + SendRes(ResERROR); + return;//goto ret_none; + } + return;//goto ret_none; + case 'Z': //Reset and load profiles + { + // scan the number away, if any + ScanNumber(scanbuf); + if (socket) SendRes(ResNOCARRIER); + Reset(); + break; + } + case ' ': //Space just skip + break; + case 'Q': // Response options + { // 0 = all on, 1 = all off, + // 2 = no ring and no connect/carrier in answermode + Bitu val = ScanNumber(scanbuf); + if(!(val>2)) { + doresponse=val; + break; + } else { + SendRes(ResERROR); + return; + } + } + case 'S': //Registers + { + Bitu index=ScanNumber(scanbuf); + if(index>=SREGS) { + SendRes(ResERROR); + return; //goto ret_none; + } + + while(scanbuf[0]==' ') scanbuf++; // skip spaces + + if(scanbuf[0]=='=') { // set register + scanbuf++; + while(scanbuf[0]==' ') scanbuf++; // skip spaces + Bitu val = ScanNumber(scanbuf); + reg[index]=val; + break; + } + else if(scanbuf[0]=='?') { // get register + SendNumber(reg[index]); + scanbuf++; + break; + } + //else LOG_MSG("print reg %d with %d",index,reg[index]); + } + break; + case '&': + { + if(scanbuf[0]!=0) { + char ch = scanbuf[0]; + //switch(scanbuf[0]) Maybe You want to implement it? + scanbuf++; + LOG_MSG("Modem: Unhandled command: &%c%d",ch,ScanNumber(scanbuf)); + } else { + SendRes(ResERROR); + return; + } + } + break; + + default: + LOG_MSG("Modem: Unhandled command: %c%d",chr,ScanNumber(scanbuf)); + } + } + +/* + } + + if (strstr(mhd.cmdbuf,"NET0")) + { + telnetmode = false; + } + if (strstr(mhd.cmdbuf,"NET1")) + { + telnetmode = true; + } + #endif*/ + //ret_ok: + SendRes(ResOK); + return; + //ret_error: + //SendRes(ResERROR); + //ret_none: + // return; + + } + +void CSerialModem::TelnetEmulation(Bit8u * data, Bitu size) { + Bitu i; + Bit8u c; + for(i=0;i250) { + /* Reject anything we don't recognize */ + tqueue->addb(0xff); + tqueue->addb(252); + tqueue->addb(c); /* We won't do crap! */ + } + } + switch(telClient.command) { + case 251: /* Will */ + if(c == 0) telClient.binary[TEL_SERVER] = true; + if(c == 1) telClient.echo[TEL_SERVER] = true; + if(c == 3) telClient.supressGA[TEL_SERVER] = true; + break; + case 252: /* Won't */ + if(c == 0) telClient.binary[TEL_SERVER] = false; + if(c == 1) telClient.echo[TEL_SERVER] = false; + if(c == 3) telClient.supressGA[TEL_SERVER] = false; + break; + case 253: /* Do */ + if(c == 0) { + telClient.binary[TEL_CLIENT] = true; + tqueue->addb(0xff); + tqueue->addb(251); + tqueue->addb(0); /* Will do binary transfer */ + } + if(c == 1) { + telClient.echo[TEL_CLIENT] = false; + tqueue->addb(0xff); + tqueue->addb(252); + tqueue->addb(1); /* Won't echo (too lazy) */ + } + if(c == 3) { + telClient.supressGA[TEL_CLIENT] = true; + tqueue->addb(0xff); + tqueue->addb(251); + tqueue->addb(3); /* Will Suppress GA */ + } + break; + case 254: /* Don't */ + if(c == 0) { + telClient.binary[TEL_CLIENT] = false; + tqueue->addb(0xff); + tqueue->addb(252); + tqueue->addb(0); /* Won't do binary transfer */ + } + if(c == 1) { + telClient.echo[TEL_CLIENT] = false; + tqueue->addb(0xff); + tqueue->addb(252); + tqueue->addb(1); /* Won't echo (fine by me) */ + } + if(c == 3) { + telClient.supressGA[TEL_CLIENT] = true; + tqueue->addb(0xff); + tqueue->addb(251); + tqueue->addb(3); /* Will Suppress GA (too lazy) */ + } + break; + default: + LOG_MSG("MODEM: Telnet client sent IAC %d", telClient.command); + break; + } + + telClient.inIAC = false; + telClient.recCommand = false; + continue; + + } else { + if(c==249) { + /* Go Ahead received */ + telClient.inIAC = false; + continue; + } + telClient.command = c; + telClient.recCommand = true; + + if((telClient.binary[TEL_SERVER]) && (c == 0xff)) { + /* Binary data with value of 255 */ + telClient.inIAC = false; + telClient.recCommand = false; + rqueue->addb(0xff); + continue; + } + + } + } else { + if(c == 0xff) { + telClient.inIAC = true; + continue; + } + rqueue->addb(c); + } + } + } + +void CSerialModem::Timer2(void) { + int result =0; + unsigned long args = 1; + bool sendbyte = true; + Bitu usesize; + Bit8u txval; + Bitu txbuffersize =0; + Bitu testres = 0; + + // check for bytes to be sent to port + if(CSerial::CanReceiveByte()) + if(rqueue->inuse() && CSerial::getRTS()) { + Bit8u rbyte = rqueue->getb(); + //LOG_MSG("Modem: sending byte %2x back to UART3",rbyte); + CSerial::receiveByte(rbyte); + } + /* Check for eventual break command */ + if (!commandmode) cmdpause++; + /* Handle incoming data from serial port, read as much as available */ + //Bitu tx_size=tqueue->inuse(); + //Bitu tx_first = tx_size; // TODO:comment out + CSerial::setCTS(true); // buffer will get 'emptier', new data can be received + while (/*tx_size--*/tqueue->inuse()) { + txval = tqueue->getb(); + if (commandmode) { + if (echo) { + rqueue->addb(txval); + //LOG_MSG("Echo back to queue: %x",txval); + } + if (txval==0xa) continue; //Real modem doesn't seem to skip this? + else if (txval==0x8 && (cmdpos > 0)) --cmdpos; // backspace + else if (txval==0xd) DoCommand(); // return + else if (txval != '+') { + if(cmdpos<99) { + cmdbuf[cmdpos] = txval; + cmdpos++; + } + } + } + else {// + character + /* 1000 ticks have passed, can check for pause command */ + if (cmdpause > 1000) { + if(txval ==/* '+')*/reg[MREG_ESCAPE_CHAR]) + { + plusinc++; + if(plusinc>=3) { + LOG_MSG("Modem: Entering command mode(escape sequence)"); + commandmode = true; + SendRes(ResOK); + plusinc = 0; + } + sendbyte=false; + } else { + plusinc=0; + } + //If not a special pause command, should go for bigger blocks to send + } + tmpbuf[txbuffersize] = txval; + txbuffersize++; + } + } // while loop + + if (socket && sendbyte && txbuffersize) { + // down here it saves a lot of network traffic + SDLNet_TCP_Send(socket, tmpbuf,txbuffersize); + //TODO error testing + } + SDLNet_CheckSockets(socketset,0); + /* Handle incoming to the serial port */ + if(!commandmode && socket) { + if(rqueue->left() && SDLNet_SocketReady(socket) /*&& CSerial::getRTS()*/) + { + usesize = rqueue->left(); + if (usesize>16) usesize=16; + result = SDLNet_TCP_Recv(socket, tmpbuf, usesize); + if (result>0) { + if(telnetmode) { + /* Filter telnet commands */ + TelnetEmulation(tmpbuf, result); + } else { + rqueue->adds(tmpbuf,result); + } + cmdpause = 0; + } else { + SendRes(ResNOCARRIER); + EnterIdleState(); + } + } + } + /* Check for incoming calls */ + if (!connected && !incomingsocket && listensocket) { + incomingsocket = SDLNet_TCP_Accept(listensocket); + if (incomingsocket) { + SDLNet_TCP_AddSocket(listensocketset, incomingsocket); + + if(!CSerial::getDTR()) { + // accept no calls with DTR off; TODO: AT &Dn + EnterIdleState(); + } else { + ringing=true; + SendRes(ResRING); + CSerial::setRI(!CSerial::getRI()); + //MIXER_Enable(mhd.chan,true); + ringtimer = 3000; + reg[1] = 0; //Reset ring counter reg + } + } + } + if (ringing) { + if (ringtimer <= 0) { + reg[1]++; + if ((reg[0]>0) && (reg[0]>=reg[1])) { + AcceptIncomingCall(); + return; + } + SendRes(ResRING); + CSerial::setRI(!CSerial::getRI()); + + //MIXER_Enable(mhd.chan,true); + ringtimer = 3000; + } + --ringtimer; + } +} + + +//TODO +void CSerialModem::RXBufferEmpty() { + // see if rqueue has some more bytes + if(rqueue->inuse() && CSerial::getRTS()){ + Bit8u rbyte = rqueue->getb(); + //LOG_MSG("Modem: sending byte %2x back to UART1",rbyte); + CSerial::receiveByte(rbyte); + + //CSerial::receiveByte(rqueue->getb()); + } +} + +void CSerialModem::transmitByte(Bit8u val) { + //LOG_MSG("MODEM: Byte %x to be transmitted",val); + if(tqueue->left()) { + tqueue->addb(val); + if(!tqueue->left()) { + CSerial::setCTS(false); + txbufferfull=true; + } + } else LOG_MSG("MODEM: TX Buffer overflow!"); + CSerial::ByteTransmitted(); +} + +void CSerialModem::updatePortConfig(Bit8u dll, Bit8u dlm, Bit8u lcr) { +// nothing to do here right? +} + +void CSerialModem::updateMSR() { + // think it is not needed +} + +void CSerialModem::setBreak(bool) { + // TODO: handle this +} + +void CSerialModem::updateModemControlLines(/*Bit8u mcr*/) { + //if(!txbufferfull) + //{ + // if(CSerial::getRTS()) CSerial::setCTS(true); + // else CSerial::setCTS(false); + //} + + // If DTR goes low, hang up. + if(connected) + if(oldDTRstate) + if(!getDTR()) { + SendRes(ResNOCARRIER); + EnterIdleState(); + LOG_MSG("Modem: Hang up due to dropped DTR."); + } + + oldDTRstate = getDTR(); +} + + +#endif + diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h new file mode 100644 index 00000000..80ce6134 --- /dev/null +++ b/src/hardware/serialport/softmodem.h @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2002-2005 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: softmodem.h,v 1.1 2005-07-30 14:41:31 qbix79 Exp $ */ + +#ifndef DOSBOX_SERIALMODEM_H +#define DOSBOX_SERIALMODEM_H + +#include "dosbox.h" +#include "SDL_net.h" +#include "serialport.h" + +#define MODEMSPD 57600 +#define SREGS 100 + +//If it's too high you overflow terminal clients buffers i think +#define MODEM_BUFFER_QUEUE_SIZE 1024 + +#define MODEM_DEFAULT_PORT 23 + +enum ResTypes { + ResNONE, + ResOK,ResERROR, + ResCONNECT,ResRING, + ResBUSY,ResNODIALTONE,ResNOCARRIER, +}; + +#define TEL_CLIENT 0 +#define TEL_SERVER 1 + +class CFifo { +public: + CFifo(Bitu _size) { + size=_size; + pos=used=0; + data=new Bit8u[size]; + } + ~CFifo() { + delete[] data; + } + INLINE Bitu left(void) { + return size-used; + } + INLINE Bitu inuse(void) { + return used; + } + void clear(void) { + used=pos=0; + } + + void addb(Bit8u _val) { + if(used>=size) { + LOG_MSG("FIFO Overflow!"); + return; + } + //assert(used=size) where-=size; + data[where]=_val; + //LOG_MSG("+%x",_val); + used++; + } + void adds(Bit8u * _str,Bitu _len) { + if((used+_len)>size) { + LOG_MSG("FIFO Overflow!"); + return; + } + + //assert((used+_len)<=size); + Bitu where=pos+used; + used+=_len; + while (_len--) { + if (where>=size) where-=size; + //LOG_MSG("+%x",*_str); + data[where++]=*_str++; + } + } + Bit8u getb(void) { + if (!used) { + LOG_MSG("MODEM: FIFO UNDERFLOW!"); + return data[pos]; + } + Bitu where=pos; + if (++pos>=size) pos-=size; + used--; + //LOG_MSG("-%x",data[where]); + return data[where]; + } + void gets(Bit8u * _str,Bitu _len) { + if (!used) { + LOG_MSG("MODEM: FIFO UNDERFLOW!"); + return; + } + //assert(used>=_len); + used-=_len; + while (_len--) { + //LOG_MSG("-%x",data[pos]); + *_str++=data[pos]; + if (++pos>=size) pos-=size; + } + } +private: + Bit8u * data; + Bitu size,pos,used; + //Bit8u tmpbuf[MODEM_BUFFER_QUEUE_SIZE]; + + +}; +#define MREG_AUTOANSWER_COUNT 0 +#define MREG_RING_COUNT 1 +#define MREG_ESCAPE_CHAR 2 +#define MREG_CR_CHAR 3 +#define MREG_LF_CHAR 4 +#define MREG_BACKSPACE_CHAR 5 + + +class CSerialModem : public CSerial { +public: + + CFifo *rqueue; + CFifo *tqueue; + + CSerialModem( + IO_ReadHandler* rh, + IO_WriteHandler* wh, + TIMER_TickHandler th, + Bit16u baseAddr, + Bit8u initIrq, + Bit32u initBps, + Bit8u bytesize, + const char* parity, + Bit8u stopbits, + + const char *remotestr = NULL, + Bit16u lport = 23); + + ~CSerialModem(); + + void Reset(); + + void SendLine(const char *line); + void SendRes(ResTypes response); + void SendNumber(Bitu val); + + void EnterIdleState(); + void EnterConnectedState(); + + void openConnection(void); + bool Dial(char * host); + void AcceptIncomingCall(void); + Bitu ScanNumber(char * & scan); + + void DoCommand(); + + void MC_Changed(Bitu new_mc); + + void TelnetEmulation(Bit8u * data, Bitu size); + + void Timer2(void); + + void RXBufferEmpty(); + + void transmitByte(Bit8u val); + void updatePortConfig(Bit8u dll, Bit8u dlm, Bit8u lcr); + void updateMSR(); + + void setBreak(bool); + + void updateModemControlLines(/*Bit8u mcr*/); + +protected: + char cmdbuf[255]; + bool commandmode; // true: interpret input as commands + //bool answermode; + bool echo; // local echo on or off + + bool oldDTRstate; + bool ringing; + //bool response; + bool numericresponse; // true: send control response as number. + // false: send text (i.e. NO DIALTONE) + bool telnetmode; // true: process IAC commands. + + bool connected; + bool txbufferfull; + Bitu doresponse; + + + + Bitu cmdpause; + Bits ringtimer; + Bits ringcount; + Bitu plusinc; + Bitu cmdpos; + + + //Bit8u mctrl; + Bit8u tmpbuf[MODEM_BUFFER_QUEUE_SIZE]; + + Bitu listenport; + Bit8u reg[SREGS]; + IPaddress openip; + TCPsocket incomingsocket; + TCPsocket socket; + + TCPsocket listensocket; + SDLNet_SocketSet socketset; + SDLNet_SocketSet listensocketset; + + struct { + bool binary[2]; + bool echo[2]; + bool supressGA[2]; + bool timingMark[2]; + + bool inIAC; + bool recCommand; + Bit8u command; + } telClient; + struct { + bool active; + double f1, f2; + Bitu len,pos; + char str[256]; + } dial; +}; + +#endif diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp deleted file mode 100644 index 38d0486b..00000000 --- a/src/hardware/softmodem.cpp +++ /dev/null @@ -1,820 +0,0 @@ -/* - * Copyright (C) 2002-2005 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_MODEM - -#include -#include -#include -#include "SDL_net.h" - -#include "inout.h" -#include "mixer.h" -#include "pic.h" -#include "setup.h" -#include "programs.h" -#include "debug.h" -#include "timer.h" -#include "callback.h" -#include "math.h" -#include "regs.h" -#include "serialport.h" - -#define MODEMSPD 57600 -#define SREGS 100 - - -static Bit8u tmpbuf[QUEUE_SIZE]; - -struct ModemHd { - char cmdbuf[QUEUE_SIZE]; - bool commandmode; - bool answermode; - bool echo,response,numericresponse; - bool telnetmode; - Bitu cmdpause; - Bits ringtimer; - Bits ringcount; - Bitu plusinc; - Bitu cmdpos; - - Bit8u reg[SREGS]; - TCPsocket incomingsocket; - TCPsocket socket; - TCPsocket listensocket; - SDLNet_SocketSet socketset; - - IPaddress openip; - - Bitu comport; - Bitu listenport; - - char remotestr[4096]; - - bool dialing; - double f1, f2; - Bitu diallen; - Bitu dialpos; - char dialstr[256]; - // TODO: Re-enable dialtons - //MIXER_Channel * chan; -}; - -enum ResTypes { - ResNONE, - ResOK,ResERROR, - ResCONNECT,ResRING, - ResBUSY,ResNODIALTONE,ResNOCARRIER, -}; - -#define TEL_CLIENT 0 -#define TEL_SERVER 1 - -struct telnetClient { - bool binary[2]; - bool echo[2]; - bool supressGA[2]; - bool timingMark[2]; - - bool inIAC; - bool recCommand; - Bit8u command; -}; - - - -#if 1 - -static void toUpcase(char *buffer) { - Bitu i=0; - while (buffer[i] != 0) { - buffer[i] = toupper(buffer[i]); - i++; - } -} - - - -class CSerialModem : public CSerial { -public: - ModemHd mhd; - - CSerialModem(Bit16u baseAddr, Bit8u initIrq, Bit32u initBps, const char *remotestr = NULL, Bit16u lport = 27) - : CSerial(baseAddr, initIrq, initBps) - { - - - mhd.cmdpos = 0; - mhd.commandmode = true; - mhd.plusinc = 0; - mhd.incomingsocket = 0; - mhd.answermode = false; - memset(&mhd.reg,0,sizeof(mhd.reg)); - mhd.cmdpause = 0; - mhd.echo = true; - mhd.response = true; - mhd.numericresponse = false; - - /* Default to direct null modem connection. Telnet mode interprets IAC codes */ - mhd.telnetmode = false; - - /* Bind the modem to the correct serial port */ - //strcpy(mhd.remotestr, remotestr); - - /* Initialize the sockets and setup the listening port */ - mhd.socketset = SDLNet_AllocSocketSet(1); - if (!mhd.socketset) { - LOG_MSG("MODEM:Can't open socketset:%s",SDLNet_GetError()); - //TODO Should probably just exit - return; - } - mhd.socket=0; - mhd.listenport=lport; - if (mhd.listenport) { - IPaddress listen_ip; - SDLNet_ResolveHost(&listen_ip, NULL, mhd.listenport); - mhd.listensocket=SDLNet_TCP_Open(&listen_ip); - if (!mhd.listensocket) LOG_MSG("MODEM:Can't open listen port:%s",SDLNet_GetError()); - } else mhd.listensocket=0; - - // TODO: Fix dialtones if requested - //mhd.chan=MIXER_AddChannel((MIXER_MixHandler)this->MODEM_CallBack,8000,"MODEM"); - //MIXER_Enable(mhd.chan,false); - //MIXER_SetMode(mhd.chan,MIXER_16MONO); - - } - - ~CSerialModem(){ - if (mhd.socket) { - SDLNet_TCP_DelSocket(mhd.socketset,mhd.socket); - SDLNet_TCP_Close(mhd.socket); - } - if(mhd.listensocket) SDLNet_TCP_Close(mhd.listensocket); - if(mhd.socketset) SDLNet_FreeSocketSet(mhd.socketset); - } - - void SendLine(const char *line) { - rqueue->addb(0xd); - rqueue->addb(0xa); - rqueue->adds((Bit8u *)line,strlen(line)); - rqueue->addb(0xd); - rqueue->addb(0xa); - - } - - void SendRes(ResTypes response) { - char * string;char * code; - switch (response) { - case ResNONE: - return; - case ResOK:string="OK";code="0";break; - case ResERROR:string="ERROR";code="4";break; - case ResRING:string="RING";code="2"; - case ResNODIALTONE:string="NO DIALTONE";code="6";break; - case ResNOCARRIER:string="NO CARRIER";code="3";break; - case ResCONNECT:string="CONNECT 57600";code="1";break; - } - - rqueue->addb(0xd);rqueue->addb(0xa); - rqueue->adds((Bit8u *)string,strlen(string)); - rqueue->addb(0xd);rqueue->addb(0xa); - } - - void Send(Bit8u val) { - tqueue->addb(val); - } - - Bit8u Recv(Bit8u val) { - return rqueue->getb(); - - } - - void openConnection(void) { - if (mhd.socket) { - LOG_MSG("Huh? already connected"); - SDLNet_TCP_DelSocket(mhd.socketset,mhd.socket); - SDLNet_TCP_Close(mhd.socket); - } - mhd.socket = SDLNet_TCP_Open(&openip); - if (mhd.socket) { - SDLNet_TCP_AddSocket(mhd.socketset,mhd.socket); - SendRes(ResCONNECT); - mhd.commandmode = false; - memset(&telClient, 0, sizeof(telClient)); - updatemstatus(); - } else { - SendRes(ResNODIALTONE); - } - } - - void updatemstatus(void) { - Bit8u ms=0; - //Check for data carrier, a connection that is - if (mhd.incomingsocket) ms|=MS_RI; - if (mhd.socket) ms|=MS_DCD; - if (!mhd.commandmode) ms|=MS_DSR; - //Check for DTR reply with DSR - // if (cport->mctrl & MC_DTR) ms|=MS_DSR; - //Check for RTS reply with CTS - if (mctrl & MC_RTS) ms|=MS_CTS; - SetModemStatus(ms); - } - - bool Dial(char * host) { - /* Scan host for port */ - Bit16u port; - char * hasport=strrchr(host,':'); - if (hasport) { - *hasport++=0; - port=(Bit16u)atoi(hasport); - } else port=23; - /* Resolve host we're gonna dial */ - LOG_MSG("host %s port %x",host,port); - if (!SDLNet_ResolveHost(&openip,host,port)) { - openConnection(); - return true; - } else { - LOG_MSG("Failed to resolve host %s:%s",host,SDLNet_GetError()); - SendRes(ResNOCARRIER); - return false; - } - } - - void AcceptIncomingCall(void) { - assert(!mhd.socket); - mhd.socket=mhd.incomingsocket; - SDLNet_TCP_AddSocket(mhd.socketset,mhd.socket); - SendRes(ResCONNECT); - LOG_MSG("Connected!\n"); - - mhd.incomingsocket = 0; - mhd.commandmode = false; - } - - Bitu ScanNumber(char * & scan) { - Bitu ret=0; - while (char c=*scan) { - if (c>='0' && c<='9') { - ret*=10; - ret+=c-'0'; - scan++; - } else break; - } - return ret; - } - - - void HangUp(void) { - SendRes(ResNOCARRIER); - SDLNet_TCP_DelSocket(mhd.socketset,mhd.socket); - SDLNet_TCP_Close(mhd.socket); - mhd.socket=0; - mhd.commandmode = true; - updatemstatus(); - } - - void DoCommand() { - mhd.cmdbuf[mhd.cmdpos] = 0; - mhd.cmdpos = 0; //Reset for next command - toUpcase(mhd.cmdbuf); - LOG_MSG("Modem Sent Command: %s\n", mhd.cmdbuf); - /* Check for empty line, stops dialing and autoanswer */ - if (!mhd.cmdbuf[0]) { - if(!mhd.dialing) { - mhd.answermode = false; - goto ret_none; - } else { - //MIXER_Enable(mhd.chan,false); - mhd.dialing = false; - SendRes(ResNOCARRIER); - goto ret_none; - } - } - /* AT command set interpretation */ - if ((mhd.cmdbuf[0] != 'A') || (mhd.cmdbuf[1] != 'T')) goto ret_error; - /* Check for dial command */ - if(strncmp(mhd.cmdbuf,"ATD3",3)==0) { - char * foundstr=&mhd.cmdbuf[3]; - if (*foundstr=='T' || *foundstr=='P') foundstr++; - /* Small protection against empty line */ - if (!foundstr[0]) goto ret_error; - if (strlen(foundstr) >= 12){ - // Check if supplied parameter only consists of digits - bool isNum = true; - for (Bitu i=0; i '9') - isNum = false; - if (isNum) { - // Parameter is a number with at least 12 digits => this cannot be a valid IP/name - // Transform by adding dots - char buffer[128]; - Bitu j = 0; - for (Bitu i=0; i12) - buffer[j++] = ':'; - } - buffer[j] = 0; - foundstr = buffer; - } - } - Dial(foundstr); - goto ret_none; - } - char * scanbuf; - scanbuf=&mhd.cmdbuf[2];char chr;Bitu num; - while (chr=*scanbuf++) { - switch (chr) { - case 'I': //Some strings about firmware - switch (num=ScanNumber(scanbuf)) { - case 3:SendLine("DosBox Emulated Modem Firmware V1.00");break; - case 4:SendLine("Modem compiled for DosBox version " VERSION);break; - };break; - case 'E': //Echo on/off - switch (num=ScanNumber(scanbuf)) { - case 0:mhd.echo = false;break; - case 1:mhd.echo = true;break; - };break; - case 'V': - switch (num=ScanNumber(scanbuf)) { - case 0:mhd.numericresponse = true;break; - case 1:mhd.numericresponse = false;break; - };break; - case 'H': //Hang up - switch (num=ScanNumber(scanbuf)) { - case 0: - if (mhd.socket) { - HangUp(); - goto ret_none; - } - //Else return ok - };break; - case 'O': //Return to data mode - switch (num=ScanNumber(scanbuf)) { - case 0: - if (mhd.socket) { - mhd.commandmode = false; - goto ret_none; - } else { - goto ret_error; - } - };break; - case 'T': //Tone Dial - case 'P': //Pulse Dial - break; - case 'M': //Monitor - case 'L': //Volume - ScanNumber(scanbuf); - break; - case 'A': //Answer call - if (mhd.incomingsocket) { - AcceptIncomingCall(); - } else { - mhd.answermode = true; - } - goto ret_none; - case 'Z': //Reset and load profiles - num=ScanNumber(scanbuf); - break; - case ' ': //Space just skip - break; - case 'S': //Registers - { - Bitu index=ScanNumber(scanbuf); - bool hasequal=(*scanbuf == '='); - if (hasequal) scanbuf++; - Bitu val=ScanNumber(scanbuf); - if (index>=SREGS) goto ret_error; - if (hasequal) mhd.reg[index]=val; - else LOG_MSG("print reg %d with %d",index,mhd.reg[index]); - };break; - default: - LOG_MSG("Unhandled cmd %c%d",chr,ScanNumber(scanbuf)); - } - } - #if 0 - if (strstr(mhd.cmdbuf,"S0=1")) { - mhd.autoanswer = true; - } - if (strstr(mhd.cmdbuf,"S0=0")) { - mhd.autoanswer = false; - } - - if (strstr(mhd.cmdbuf,"NET0")) { - mhd.telnetmode = false; - } - if (strstr(mhd.cmdbuf,"NET1")) { - mhd.telnetmode = true; - } - #endif - LOG_MSG("Sending OK"); - SendRes(ResOK); - return; - ret_error: - LOG_MSG("Sending ERROR"); - SendRes(ResERROR); - ret_none: - return; - - } - - void MC_Changed(Bitu new_mc) { - LOG_MSG("New MC %x",new_mc ); - if (!(new_mc & 1) && mhd.socket) HangUp(); - updatemstatus(); - } - - void TelnetEmulation(Bit8u * data, Bitu size) { - Bitu i; - Bit8u c; - for(i=0;i250) { - /* Reject anything we don't recognize */ - tqueue->addb(0xff); - tqueue->addb(252); - tqueue->addb(c); /* We won't do crap! */ - } - } - switch(telClient.command) { - case 251: /* Will */ - if(c == 0) telClient.binary[TEL_SERVER] = true; - if(c == 1) telClient.echo[TEL_SERVER] = true; - if(c == 3) telClient.supressGA[TEL_SERVER] = true; - break; - case 252: /* Won't */ - if(c == 0) telClient.binary[TEL_SERVER] = false; - if(c == 1) telClient.echo[TEL_SERVER] = false; - if(c == 3) telClient.supressGA[TEL_SERVER] = false; - break; - case 253: /* Do */ - if(c == 0) { - telClient.binary[TEL_CLIENT] = true; - tqueue->addb(0xff); - tqueue->addb(251); - tqueue->addb(0); /* Will do binary transfer */ - } - if(c == 1) { - telClient.echo[TEL_CLIENT] = false; - tqueue->addb(0xff); - tqueue->addb(252); - tqueue->addb(1); /* Won't echo (too lazy) */ - } - if(c == 3) { - telClient.supressGA[TEL_CLIENT] = true; - tqueue->addb(0xff); - tqueue->addb(251); - tqueue->addb(3); /* Will Suppress GA */ - } - break; - case 254: /* Don't */ - if(c == 0) { - telClient.binary[TEL_CLIENT] = false; - tqueue->addb(0xff); - tqueue->addb(252); - tqueue->addb(0); /* Won't do binary transfer */ - } - if(c == 1) { - telClient.echo[TEL_CLIENT] = false; - tqueue->addb(0xff); - tqueue->addb(252); - tqueue->addb(1); /* Won't echo (fine by me) */ - } - if(c == 3) { - telClient.supressGA[TEL_CLIENT] = true; - tqueue->addb(0xff); - tqueue->addb(251); - tqueue->addb(3); /* Will Suppress GA (too lazy) */ - } - break; - default: - LOG_MSG("MODEM: Telnet client sent IAC %d", telClient.command); - break; - } - - telClient.inIAC = false; - telClient.recCommand = false; - continue; - - } else { - if(c==249) { - /* Go Ahead received */ - telClient.inIAC = false; - continue; - } - telClient.command = c; - telClient.recCommand = true; - - if((telClient.binary[TEL_SERVER]) && (c == 0xff)) { - /* Binary data with value of 255 */ - telClient.inIAC = false; - telClient.recCommand = false; - rqueue->addb(0xff); - continue; - } - - } - } else { - if(c == 0xff) { - telClient.inIAC = true; - continue; - } - rqueue->addb(c); - } - } - } - - void Timer(void) { - int result =0; - unsigned long args = 1; - bool sendbyte = true; - Bitu usesize; - Bit8u txval; - - - /* Check for eventual break command */ - if (!mhd.commandmode) mhd.cmdpause++; - /* Handle incoming data from serial port, read as much as available */ - Bitu tx_size=tqueue->inuse(); - while (tx_size--) { - txval = tqueue->getb(); - if (mhd.commandmode) { - if (mhd.echo) rqueue->addb(txval); - if (txval==0xa) continue; //Real modem doesn't seem to skip this? - else if (txval==0x8 && (mhd.cmdpos > 0)) --mhd.cmdpos; - else if (txval==0xd) DoCommand(); - else if (txval != '+') { - if(mhd.cmdpos 1000) { - if(txval == '+') { - mhd.plusinc++; - if(mhd.plusinc>=3) { - LOG_MSG("Entering command mode"); - mhd.commandmode = true; - SendRes(ResOK); - mhd.plusinc = 0; - } - sendbyte=false; - } else { - mhd.plusinc=0; - } - //If not a special pause command, should go for bigger blocks to send - } - - tmpbuf[0] = txval; - tmpbuf[1] = 0x0; - - if (mhd.socket && sendbyte) { - SDLNet_TCP_Send(mhd.socket, tmpbuf,1); - //TODO error testing - } - } - } - - SDLNet_CheckSockets(mhd.socketset,0); - /* Handle incoming to the serial port */ - if(!mhd.commandmode && mhd.socket) { - if(rqueue->left() && SDLNet_SocketReady(mhd.socket) && (mctrl & MC_RTS)) { - usesize = rqueue->left(); - if (usesize>16) usesize=16; - result = SDLNet_TCP_Recv(mhd.socket, tmpbuf, usesize); - if (result>0) { - if(mhd.telnetmode) { - /* Filter telnet commands */ - TelnetEmulation(tmpbuf, result); - } else { - - rqueue->adds(tmpbuf,result); - } - mhd.cmdpause = 0; - } else HangUp(); - } - } - /* Check for incoming calls */ - if (!mhd.socket && !mhd.incomingsocket && mhd.listensocket) { - mhd.incomingsocket = SDLNet_TCP_Accept(mhd.listensocket); - if (mhd.incomingsocket) { - mhd.diallen = 12000; - mhd.dialpos = 0; - SendRes(ResRING); - //MIXER_Enable(mhd.chan,true); - mhd.ringtimer = 3000; - mhd.reg[1] = 0; //Reset ring counter reg - } - } - if (mhd.incomingsocket) { - if (mhd.ringtimer <= 0) { - mhd.reg[1]++; - if (mhd.answermode || (mhd.reg[0]==mhd.reg[1])) { - AcceptIncomingCall(); - return; - } - SendRes(ResRING); - mhd.diallen = 12000; - mhd.dialpos = 0; - //MIXER_Enable(mhd.chan,true); - mhd.ringtimer = 3000; - } - --mhd.ringtimer; - } - updatemstatus(); - } - - bool CanSend(void) { - return true; - } - - bool CanRecv(void) { - if(rqueue->inuse()) { - return true; - } else { - return false; - } - } - - -protected: - char cmdbuf[QUEUE_SIZE]; - bool commandmode; - bool answermode; - bool echo; - bool telnetmode; - Bitu cmdpause; - Bits ringtimer; - Bits ringcount; - Bitu plusinc; - Bitu cmdpos; - - Bit8u reg[SREGS]; - IPaddress openip; - TCPsocket incomingsocket; - TCPsocket socket; - TCPsocket listensocket; - SDLNet_SocketSet socketset; - - struct { - bool binary[2]; - bool echo[2]; - bool supressGA[2]; - bool timingMark[2]; - - bool inIAC; - bool recCommand; - Bit8u command; - } telClient; - struct { - bool active; - double f1, f2; - Bitu len,pos; - char str[256]; - } dial; -}; - -#endif - - - -CSerialModem *csm; - - -static Bitu INT14_FOSSIL(void) { - switch (reg_ah) { - case 0x01: - // Serial - Write character to port - csm->tqueue->addb(reg_al); - reg_ah = csm->read_reg(0xd) & 0x7f; - break; - - case 0x02: - // FOSSIL - Receive character with wait - //LOG_MSG("FOSSIL: Calling get to receive character", reg_ah); - csm->mctrl |= MC_RTS; - while(!csm->rqueue->inuse()) { - // Wait for byte. Yes, I realize that this locks up DosBox, but - // it would an oldskool system as well. - csm->Timer(); - } - reg_al = csm->rqueue->getb(); - reg_ah = 0; - break; - case 0x03: - //LOG_MSG("FOSSIL: Calling get port status", reg_ah); - // Serial - Get port status - csm->mctrl |= MC_RTS; - reg_ah = csm->read_reg(0xd) ; // Line status - if(csm->rqueue->inuse()) reg_ah |= 0x1; - - reg_al = csm->read_reg(0xe); // Modem status - break; - default: - LOG_MSG("FOSSIL: Func 0x%x not handled", reg_ah); - break; - } - return CBRET_NONE; -} - - -class VIRTUAL_MODEM:public Module_base { -private: - CALLBACK_HandlerObject callback; -public: - VIRTUAL_MODEM(Section* configuration):Module_base(configuration){ - Section_prop * section=static_cast(configuration); - csm = NULL; - - if(!section->Get_bool("modem")) return; - - if(SDLNet_Init()==-1) { - LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); - return; - } - - if(!SDLNetInited) { - if(SDLNet_Init()==-1) { - LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); - return; - } - SDLNetInited = true; - } - - Bit16u comport = section->Get_int("comport"); - - - - switch (comport) { - case 1: - csm = new CSerialModem(0x3f0, 4, 57600, section->Get_string("remote"), section->Get_int("listenport")); - break; - case 2: - csm = new CSerialModem(0x2f0, 3, 57600, section->Get_string("remote"), section->Get_int("listenport")); - break; - case 3: - csm = new CSerialModem(0x3e0, 4, 57600, section->Get_string("remote"), section->Get_int("listenport")); - break; - case 4: - csm = new CSerialModem(0x2e0, 3, 57600, section->Get_string("remote"), section->Get_int("listenport")); - break; - default: - // Default to COM2 - csm = new CSerialModem(0x2f0, 3, 57600, section->Get_string("remote"), section->Get_int("listenport")); - break; - - } - - if(csm != NULL) seriallist.push_back(csm); - - //Enable FOSSIL support (GTERM, etc) - callback.Install(&INT14_FOSSIL,CB_IRET,"int14 fossil"); - callback.Set_RealVec(0x14); - } - ~VIRTUAL_MODEM(){ - if(!csm) return; - delete csm; - } -}; - -static VIRTUAL_MODEM* test; - -void MODEM_Destroy(Section* sec){ - delete test; -} - - -void MODEM_Init(Section* sec) { - test = new VIRTUAL_MODEM(sec); - sec->AddDestroyFunction(&MODEM_Destroy,true); -} - - -#endif diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 9fdaf4da..69c32647 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.42 2005-06-21 18:47:25 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.43 2005-07-30 14:41:31 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -177,14 +177,179 @@ static Bitu INT17_Handler(void) { return CBRET_NONE; } -static Bitu INT14_Handler(void) { - switch (reg_ah) { +static Bitu INT14_Handler(void) +{ + Bit16u port = real_readw(0x40,reg_dx*2); // DX is always port number + if(reg_dx > 0x3 || port==0) // no more than 4 serial ports + { + LOG_MSG("BIOS INT14: port %d does not exist.",reg_dx); + return CBRET_NONE; + } + switch (reg_ah) + { case 0x00: /* Init port */ + // Parameters: + // AL: port parameters + // Return: + // AH: line status + // AL: modem status { - Bitu port=real_readw(0x40,reg_dx*2); + // set baud rate + Bitu baudrate = 9600; + Bit16u baudresult; + Bitu rawbaud=reg_al>>5; + + if(rawbaud==0){ baudrate=110;} + else if (rawbaud==1){ baudrate=150;} + else if (rawbaud==2){ baudrate=300;} + else if (rawbaud==3){ baudrate=600;} + else if (rawbaud==4){ baudrate=1200;} + else if (rawbaud==5){ baudrate=2400;} + else if (rawbaud==6){ baudrate=4800;} + else if (rawbaud==7){ baudrate=9600;} + + baudresult = (Bit16u)(115200 / baudrate); + + IO_WriteB(port+3, 0x80); // enable divider access + IO_WriteB(port,(Bit8u)baudresult&0xff); + IO_WriteB(port+1,(Bit8u)(baudresult>>8)); + + // set line parameters, disable divider access + IO_WriteB(port+3, reg_al&0x1F);//LCR + + // disable interrupts + IO_WriteB(port+1, 0); + IO_ReadB(port+2); + // put RTS and DTR on + IO_WriteB(port+4,0x3); + + // get result + reg_ah=IO_ReadB(port+5); + reg_al=IO_ReadB(port+6); + } + break; + case 0x01: /* Write character */ + // Parameters: + // AL: character + // Return: + // AH: line status + // AL: modem status + { + if((IO_ReadB(port+5)&&0x20)==0) + { + // TODO: should wait until they become empty->timeout + LOG_MSG("BIOS INT14: port %d: transmit register not empty.",reg_dx); + reg_ah = IO_ReadB(port+5)|0x80; + return CBRET_NONE; + } + // transmit it + IO_WriteB(port,reg_al); + + if((IO_ReadB(port+5)&&0x60)==0) + { + // TODO: should wait until they become empty->timeout + LOG_MSG("BIOS INT14: port %d: transmit register not empty after write.",reg_dx); + reg_ah = IO_ReadB(port+5)|0x80; + return CBRET_NONE; + } + + // get result + reg_ah=IO_ReadB(port+5); + reg_al=IO_ReadB(port+6); + } + break; + + case 0x02: /* Read character */ + { + if((IO_ReadB(port+5)&0x1)!=0) + { + reg_al=IO_ReadB(port); + } + else + { + // TODO: should wait until timeout + LOG_MSG("BIOS INT14: port %d: nothing received.",reg_dx); + reg_ah = IO_ReadB(port+5)|0x80; + return CBRET_NONE; + } + reg_ah=IO_ReadB(port+5); + } + break; + case 0x03: // get status + { + reg_ah=IO_ReadB(port+5); + //LOG_MSG("status reg_ah: %x",reg_ah); + reg_al=IO_ReadB(port+6); + } + break; + case 0x04: // extended initialisation + // Parameters: + // AL: break + // BH: parity + // BL: stopbit + // CH: word length + // CL: baudrate + { + Bit8u lcr = 0; + + // baud rate + Bitu baudrate = 9600; + Bit16u baudresult; + Bitu rawbaud=reg_cl; + + if(rawbaud==0){ baudrate=110;} + else if (rawbaud==1){ baudrate=150;} + else if (rawbaud==2){ baudrate=300;} + else if (rawbaud==3){ baudrate=600;} + else if (rawbaud==4){ baudrate=1200;} + else if (rawbaud==5){ baudrate=2400;} + else if (rawbaud==6){ baudrate=4800;} + else if (rawbaud==7){ baudrate=9600;} + else if (rawbaud==8){ baudrate=19200;} + + baudresult = (Bit16u)(115200 / baudrate); + + IO_WriteB(port+3, 0x80); // enable divider access + IO_WriteB(port,(Bit8u)baudresult&0xff); + IO_WriteB(port+1,(Bit8u)(baudresult>>8)); + + // line configuration + // break + if(reg_al!=0) lcr=0x40; + // parity + if(reg_bh!=0) + { + if(reg_bh==1)lcr|=0x8;// odd + else if(reg_bh==2)lcr|=0x18;// even + else if(reg_bh==3)lcr|=0x28;// mark + else if(reg_bh==4)lcr|=0x38;// mark + } + // stopbit + if(reg_bl!=0) + { + lcr|=0x4; + } + // data length + lcr|=(reg_ch&0x3); + IO_WriteB(port+3,lcr); + + reg_ah=IO_ReadB(port+5); + reg_al=IO_ReadB(port+6); + } + break; + case 0x05: // modem control + { + if(reg_al==0) // read MCR + { + reg_bl=IO_ReadB(port+4); + } + else if(reg_al==1) // write MCR + { + IO_WriteB(port+4,reg_bl); + } + else LOG_MSG("BIOS INT14: port %d, function 5: invalid subfunction.",reg_dx); reg_ah=IO_ReadB(port+5); reg_al=IO_ReadB(port+6); - LOG_MSG("AX %X DX %X",reg_ax,reg_dx); } break; default: @@ -429,7 +594,6 @@ private: CALLBACK_HandlerObject callback[10]; public: BIOS(Section* configuration):Module_base(configuration){ - MSG_Add("BIOS_CONFIGFILE_HELP","Nothing to setup yet!\n"); /* Clear the Bios Data Area */ for (Bit16u i=0;i<1024;i++) real_writeb(0x40,i,0); /* Setup all the interrupt handlers the bios controls */ @@ -495,15 +659,61 @@ public: callback[9].Set_RealVec(0x1); /* Setup some stuff in 0x40 bios segment */ - /* Test for parallel port */ - if (IO_Read(0x378)!=0xff) real_writew(0x40,0x08,0x378); - /* Test for serial port */ - Bitu index=0; - if (IO_Read(0x3fa)!=0xff) real_writew(0x40,(index++)*2,0x3f8); - if (IO_Read(0x2fa)!=0xff) real_writew(0x40,(index++)*2,0x2f8); - /* Setup equipment list */ - //1 Floppy, 2 serial and 1 parrallel - Bitu config=0x4400; + /* detect parallel ports */ + Bit8u DEFAULTPORTTIMEOUT = 10; // 10 whatevers + Bitu ppindex=0; // number of lpt ports + if ((IO_Read(0x378)!=0xff)|(IO_Read(0x379)!=0xff)) { + // this is our LPT1 + mem_writew(BIOS_ADDRESS_LPT1,0x378); + mem_writeb(BIOS_LPT1_TIMEOUT,DEFAULTPORTTIMEOUT); + ppindex++; + if((IO_Read(0x278)!=0xff)|(IO_Read(0x279)!=0xff)) { + // this is our LPT2 + mem_writew(BIOS_ADDRESS_LPT2,0x278); + mem_writeb(BIOS_LPT2_TIMEOUT,DEFAULTPORTTIMEOUT); + ppindex++; + if((IO_Read(0x3bc)!=0xff)|(IO_Read(0x3be)!=0xff)) { + // this is our LPT3 + mem_writew(BIOS_ADDRESS_LPT3,0x3bc); + mem_writeb(BIOS_LPT3_TIMEOUT,DEFAULTPORTTIMEOUT); + ppindex++; + } + } else if((IO_Read(0x3bc)!=0xff)|(IO_Read(0x3be)!=0xff)) { + // this is our LPT2 + mem_writew(BIOS_ADDRESS_LPT2,0x3bc); + mem_writeb(BIOS_LPT2_TIMEOUT,DEFAULTPORTTIMEOUT); + ppindex++; + } + } else if((IO_Read(0x3bc)!=0xff)|(IO_Read(0x3be)!=0xff)) { + // this is our LPT1 + mem_writew(BIOS_ADDRESS_LPT1,0x3bc); + mem_writeb(BIOS_LPT1_TIMEOUT,DEFAULTPORTTIMEOUT); + ppindex++; + if((IO_Read(0x278)!=0xff)|(IO_Read(0x279)!=0xff)) { + // this is our LPT2 + mem_writew(BIOS_ADDRESS_LPT2,0x278); + mem_writeb(BIOS_LPT2_TIMEOUT,DEFAULTPORTTIMEOUT); + ppindex++; + } + } + else if((IO_Read(0x278)!=0xff)|(IO_Read(0x279)!=0xff)) { + // this is our LPT1 + mem_writew(BIOS_ADDRESS_LPT1,0x278); + mem_writeb(BIOS_LPT1_TIMEOUT,DEFAULTPORTTIMEOUT); + ppindex++; + } + + /* Setup equipment list */ + // look http://www.bioscentral.com/misc/bda.htm + + //Bitu config=0x4400; //1 Floppy, 2 serial and 1 parrallel + Bitu config = 0; + + // set number of parallel ports + // if(ppindex == 0) config |= 0x8000; // looks like 0 ports are not specified + //else if(ppindex == 1) config |= 0x0000; + if(ppindex == 2) config |= 0x4000; + else config |= 0xc000; // 3 ports #if (C_FPU) //FPU config|=0x2; @@ -534,6 +744,36 @@ public: } }; +// set com port data in bios data area +// parameter: array of 4 com port base addresses, 0 = none +void BIOS_SetComPorts(Bit16u baseaddr[]) { + Bit8u DEFAULTPORTTIMEOUT = 10; // 10 whatevers + Bit16u portcount=0; + Bit16u equipmentword; + for(Bitu i = 0; i < 4; i++) { + if(baseaddr[i]!=0) portcount++; + if(i==0) { // com1 + mem_writew(BIOS_BASE_ADDRESS_COM1,baseaddr[i]); + mem_writeb(BIOS_COM1_TIMEOUT,DEFAULTPORTTIMEOUT); + } else if(i==1) { + mem_writew(BIOS_BASE_ADDRESS_COM2,baseaddr[i]); + mem_writeb(BIOS_COM2_TIMEOUT,DEFAULTPORTTIMEOUT); + } else if(i==2) { + mem_writew(BIOS_BASE_ADDRESS_COM3,baseaddr[i]); + mem_writeb(BIOS_COM3_TIMEOUT,DEFAULTPORTTIMEOUT); + } else { + mem_writew(BIOS_BASE_ADDRESS_COM4,baseaddr[i]); + mem_writeb(BIOS_COM4_TIMEOUT,DEFAULTPORTTIMEOUT); + } + } + // set equipment word + equipmentword = mem_readw(BIOS_CONFIGURATION); + equipmentword &= (~0x0E00); + equipmentword |= (portcount << 9); + mem_writew(BIOS_CONFIGURATION,equipmentword); +} + + static BIOS* test; void BIOS_Destroy(Section* sec){ diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 7fec8a92..701ca121 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -404,9 +404,6 @@ - - @@ -440,12 +437,6 @@ - - - - @@ -514,6 +505,31 @@ RelativePath="..\src\hardware\tandy_sound.cpp"> + + + + + + + + + + + + + + + + Date: Sun, 31 Jul 2005 12:08:58 +0000 Subject: [PATCH 2174/4131] compilation fix for people without sdl_net.(vasyl) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2258 --- src/hardware/serialport/softmodem.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index 80ce6134..ab0ad83c 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -16,12 +16,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.h,v 1.1 2005-07-30 14:41:31 qbix79 Exp $ */ +/* $Id: softmodem.h,v 1.2 2005-07-31 12:08:58 qbix79 Exp $ */ #ifndef DOSBOX_SERIALMODEM_H #define DOSBOX_SERIALMODEM_H #include "dosbox.h" +#if C_MODEM #include "SDL_net.h" #include "serialport.h" @@ -239,5 +240,5 @@ protected: char str[256]; } dial; }; - +#endif #endif From 58a0aaed55cb2e7372c34ed7240e53d9b0f4be2e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 31 Jul 2005 13:59:02 +0000 Subject: [PATCH 2175/4131] Zero memory after we allocate it. Dosbox needs zeroed memory to operate correctly Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2259 --- src/hardware/memory.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 3f30f55b..0d04ac66 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: memory.cpp,v 1.38 2005-07-30 10:11:40 qbix79 Exp $ */ +/* $Id: memory.cpp,v 1.39 2005-07-31 13:59:02 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -25,6 +25,8 @@ #include "paging.h" #include "regs.h" +#include + #define PAGES_IN_BLOCK ((1024*1024)/MEM_PAGE_SIZE) #define MAX_MEMORY 64 #define MAX_PAGE_ENTRIES (MAX_MEMORY*1024*1024/4096) @@ -490,6 +492,9 @@ public: } MemBase = new Bit8u[memsize*1024*1024]; if (!MemBase) E_Exit("Can't allocate main memory of %d MB",memsize); + /* Clear the memory, as new doesn't always give zeroed memory + * (Visual C debug mode). We want zeroed memory though. */ + memset((void*)MemBase,0,memsize*1024*1024); memory.pages = (memsize*1024*1024)/4096; /* Allocate the data for the different page information blocks */ memory.phandlers=new PageHandler * [memory.pages]; @@ -531,12 +536,4 @@ void MEM_Init(Section * sec) { /* shutdown function */ test = new MEMORY(sec); sec->AddDestroyFunction(&MEM_ShutDown); - - // initialize interrupt handlers to 0 - // this makes availible interrupts detectable even in compiler debug mode - // tyrian network helper app is suffering from this - // - // DISABLED IT BY DEFAULT. (qbix79). But the code is there in case - // somebody needs it - //for(Bitu icntr = 0; icntr <0xFF; icntr++) RealSetVec(icntr,0); } From 154ad6437058b654ff4ab326f984f6f45c358f76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 1 Aug 2005 09:30:45 +0000 Subject: [PATCH 2176/4131] raise dos memory start segment (WC armada, novalogic setup); update some dos tables Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2260 --- include/dos_inc.h | 30 +++++++++++++++++++++-------- src/dos/dos_classes.cpp | 42 ++++++++++++++++++++++------------------- src/dos/dos_memory.cpp | 24 ++++++++++------------- src/dos/dos_tables.cpp | 38 ++++++++++++++++++------------------- 4 files changed, 74 insertions(+), 60 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 49aa85e9..1e27f92e 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.53 2005-03-24 10:18:45 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.54 2005-08-01 09:30:44 c2woody Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -76,6 +76,15 @@ enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; #define DOS_DRIVES 26 #define DOS_DEVICES 10 +#define DOS_INFOBLOCK_SEG 0x50 +#define DOS_SDA_SEG 0x5a +#define DOS_SDA_OFS 0 +#define DOS_CONSTRING_SEG 0x5d +#define DOS_CONDRV_SEG 0x60 +#define DOS_SFT_SEG 0x62 +#define DOS_CDS_SEG 0x64 +#define DOS_MEM_START 0x102 //First Segment that DOS can use + /* internal Dos Tables */ extern DOS_File * Files[DOS_FILES]; @@ -350,7 +359,7 @@ public: void SetCurDirStruct(Bit32u _curdirstruct); void SetFCBTable(Bit32u _fcbtable); void SetDeviceChainStart(Bit32u _devchain); - void SetDiskInfoBuffer(Bit32u _dinfobuf); + void SetDiskBufferHeadPt(Bit32u _dbheadpt); RealPt GetPointer (void); #ifdef _MSC_VER @@ -391,7 +400,17 @@ public: Bit8u bootDrive; // 0x43 boot drive Bit8u useDwordMov; // 0x44 use dword moves Bit16u extendedSize; // 0x45 size of extended memory - // some more stuff, hopefully never used. + 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 unknown2[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 () @@ -510,11 +529,6 @@ private: #endif }; -extern Bit16u sdaseg; -#define DOS_SDA_SEG sdaseg -#define DOS_SDA_OFS 0 - - class DOS_SDA : public MemStruct { public: DOS_SDA(Bit16u _seg,Bit16u _offs) { SetPt(_seg,_offs); } diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index cb9307ec..dfdafe60 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.43 2005-02-10 10:20:51 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.44 2005-08-01 09:30:45 c2woody Exp $ */ #include #include @@ -58,11 +58,10 @@ void DOS_ParamBlock::SaveData(void) { } -void DOS_InfoBlock::SetLocation(Bit16u segment) -{ +void DOS_InfoBlock::SetLocation(Bit16u segment) { seg = segment; pt=PhysMake(seg,0); -/* Clear the initual Block */ + /* Clear the initial Block */ for(Bitu i=0;i=0xe000) { @@ -81,20 +80,19 @@ void DOS_SetupTables(void) { dos.tables.tempdta_fcbdelete=RealMake(DOS_GetMemory(4),0); for (i=0;i20 detection routine */ /* Possibly obselete when SFT is properly handled */ - real_writed(0x5d,0x0a,0x204e4f43); - real_writed(0x5d,0x1a,0x204e4f43); - real_writed(0x5d,0x2a,0x204e4f43); + real_writed(DOS_CONSTRING_SEG,0x0a,0x204e4f43); + real_writed(DOS_CONSTRING_SEG,0x1a,0x204e4f43); + real_writed(DOS_CONSTRING_SEG,0x2a,0x204e4f43); /* create a CON device driver */ - seg=0x60; + seg=DOS_CONDRV_SEG; real_writed(seg,0x00,0xffffffff); // next ptr real_writew(seg,0x04,0x8013); // attributes real_writed(seg,0x06,0xffffffff); // strategy routine @@ -103,16 +101,16 @@ void DOS_SetupTables(void) { dos_infoblock.SetDeviceChainStart(RealMake(seg,0)); /* Create a fake SFT, so programs think there are 100 file handles */ - seg=0x62; - seg2=0x63; + seg=DOS_SFT_SEG; + seg2=DOS_SFT_SEG+1; real_writed(seg,0,seg2<<16); //Next File Table real_writew(seg,4,100); //File Table supports 100 files real_writed(seg2,0,0xffffffff); //Last File Table real_writew(seg2,4,100); //File Table supports 100 files dos_infoblock.SetfirstFileTable(RealMake(seg,0)); - /* Create a fake CDS */ - seg=0x64; + /* Create a fake Current Directory Structure */ + seg=DOS_CDS_SEG; real_writed(seg,0x00,0x005c3a43); dos_infoblock.SetCurDirStruct(RealMake(seg,0)); @@ -128,13 +126,15 @@ void DOS_SetupTables(void) { real_writew(seg,4,100); //File Table supports 100 files dos_infoblock.SetFCBTable(RealMake(seg,0)); - /* Create a fake disk info buffer */ + /* Create a fake disk buffer head */ seg=DOS_GetMemory(6); - seg2=DOS_GetMemory(6); - real_writed(seg,0x00,seg2<<16); - real_writed(seg2,0x00,0xffffffff); - real_writed(seg2,0x0d,0xffffffff); - dos_infoblock.SetDiskInfoBuffer(RealMake(seg,0)); + for (Bitu ct=0; ct<0x20; ct++) real_writeb(seg,ct,0); + real_writew(seg,0x00,0xffff); // forward ptr + real_writew(seg,0x02,0xffff); // backward ptr + real_writeb(seg,0x04,0xff); // not in use + real_writeb(seg,0x0a,0x01); // number of FATs + real_writed(seg,0x0d,0xffffffff); // pointer to DPB + dos_infoblock.SetDiskBufferHeadPt(RealMake(seg,0)); /* Set buffers to a nice value */ dos_infoblock.SetBuffers(50,50); From bc49a1ce91164f70828beb6eb403cdba09a073c5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 7 Aug 2005 17:33:15 +0000 Subject: [PATCH 2177/4131] Fix timers. Timer irq will now be removed if a mode 0 is programmed (fixes DSTROY). Added some explanation on why this should happen. Changed the old check to use to old timer mode instead of the new mode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2261 --- src/hardware/timer.cpp | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 06a83a8b..17565188 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.32 2005-03-25 11:52:32 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.33 2005-08-07 17:33:15 qbix79 Exp $ */ #include #include "dosbox.h" @@ -121,6 +121,7 @@ static void counter_latch(Bitu counter) { static void write_latch(Bitu port,Bitu val,Bitu iolen) { +//LOG(LOG_PIT,LOG_ERROR)("port %X write:%X state:%X",port,val,pit[port-0x40].write_state); Bitu counter=port-0x40; PIT_Block * p=&pit[counter]; if(p->bcd == true) BIN2BCD(p->write_latch); @@ -152,7 +153,7 @@ static void write_latch(Bitu port,Bitu val,Bitu iolen) { switch (counter) { case 0x00: /* Timer hooked to IRQ 0 */ if (p->new_mode || p->mode == 0 ) { - p->new_mode=false; + p->new_mode=false; PIC_AddEvent(PIT0_Event,p->delay); } else LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer set without new control word"); LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.2f Hz mode %d",1000.0/p->delay,p->mode); @@ -168,6 +169,7 @@ static void write_latch(Bitu port,Bitu val,Bitu iolen) { } static Bitu read_latch(Bitu port,Bitu iolen) { +//LOG(LOG_PIT,LOG_ERROR)("port read %X",port); Bit32u counter=port-0x40; if (pit[counter].go_read_latch == true) counter_latch(counter); @@ -204,6 +206,7 @@ static Bitu read_latch(Bitu port,Bitu iolen) { } static void write_p43(Bitu port,Bitu val,Bitu iolen) { +//LOG(LOG_PIT,LOG_ERROR)("port 43 %X",val); Bitu latch=(val >> 6) & 0x03; switch (latch) { case 0: @@ -220,15 +223,28 @@ static void write_p43(Bitu port,Bitu val,Bitu iolen) { } else { pit[latch].read_state = (val >> 4) & 0x03; pit[latch].write_state = (val >> 4) & 0x03; - pit[latch].mode = (val >> 1) & 0x07; - if (pit[latch].mode>5) - pit[latch].mode-=4; //6,7 become 2 and 3 - if (latch==0) { + Bit8u mode = (val >> 1) & 0x07; + /* Don't set it directly so counter_output uses the old mode */ + + /* If the line goes from low to up => generate irq. + * ( BUT needs to stay up until acknowlegded by the cpu!!! therefore: ) + * If the line goes to low => disable irq. + * Mode 0 starts with a low line. (so always disable irq) + * Mode 2,3 start with a high line. + * counter_output tells if the current counter is high or low + * So actually a mode 2 timer enables and disables irq al the time. (not handled) */ + + if (mode > 5) + mode -= 4; //6,7 become 2 and 3 + if (latch == 0) { PIC_RemoveEvents(PIT0_Event); - if (!counter_output(0) && pit[latch].mode) + if (!counter_output(0) && mode) PIC_ActivateIRQ(0); + if(!mode) + PIC_DeActivateIRQ(0); } - pit[latch].new_mode = true; + pit[latch].new_mode = true; + pit[latch].mode = mode; //Set the correct mode (here) } break; case 3: From caff0f7a8b5bb0ae2a82d3fc2f8cf11a07e89274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 8 Aug 2005 13:33:46 +0000 Subject: [PATCH 2178/4131] adding support for upper memory Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2262 --- include/callback.h | 4 +- include/dos_inc.h | 28 +++++--- src/dos/dos.cpp | 13 ++-- src/dos/dos_classes.cpp | 36 ++++++++-- src/dos/dos_memory.cpp | 146 +++++++++++++++++++++++++++++++++++++-- src/dos/dos_programs.cpp | 34 ++++++++- src/dos/dos_tables.cpp | 11 +-- src/dosbox.cpp | 4 +- src/ints/xms.cpp | 76 ++++++++++++++++++-- 9 files changed, 304 insertions(+), 48 deletions(-) diff --git a/include/callback.h b/include/callback.h index 5a6a5c0e..a6603387 100644 --- a/include/callback.h +++ b/include/callback.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.h,v 1.13 2005-07-30 09:49:28 qbix79 Exp $ */ +/* $Id: callback.h,v 1.14 2005-08-08 13:33:43 c2woody Exp $ */ #ifndef DOSBOX_CALLBACK_H #define DOSBOX_CALLBACK_H @@ -30,7 +30,7 @@ extern CallBack_Handler CallBack_Handlers[]; enum { CB_RETF,CB_IRET,CB_IRET_STI }; -#define CB_MAX 1024 +#define CB_MAX 144 #define CB_SEG 0xC800 #define CB_BASE (CB_SEG << 4) diff --git a/include/dos_inc.h b/include/dos_inc.h index 1e27f92e..a68f81df 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.54 2005-08-01 09:30:44 c2woody Exp $ */ +/* $Id: dos_inc.h,v 1.55 2005-08-08 13:33:43 c2woody Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -76,13 +76,13 @@ enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; #define DOS_DRIVES 26 #define DOS_DEVICES 10 -#define DOS_INFOBLOCK_SEG 0x50 -#define DOS_SDA_SEG 0x5a + +#define DOS_INFOBLOCK_SEG 0x80 +#define DOS_CDS_SEG 0x90 +#define DOS_CONSTRING_SEG 0xa0 +#define DOS_CONDRV_SEG 0xa4 +#define DOS_SDA_SEG 0xb0 #define DOS_SDA_OFS 0 -#define DOS_CONSTRING_SEG 0x5d -#define DOS_CONDRV_SEG 0x60 -#define DOS_SFT_SEG 0x62 -#define DOS_CDS_SEG 0x64 #define DOS_MEM_START 0x102 //First Segment that DOS can use /* internal Dos Tables */ @@ -158,6 +158,8 @@ void DOS_FreeProcessMemory(Bit16u pspseg); Bit16u DOS_GetMemory(Bit16u pages); void DOS_SetMemAllocStrategy(Bit16u strat); Bit16u DOS_GetMemAllocStrategy(void); +void DOS_BuildUMBChain(const char* use_umbs,bool ems_active); +bool DOS_LinkUMBsToMemChain(Bit16u linkstate); /* FCB stuff */ bool DOS_FCBOpen(Bit16u seg,Bit16u offset); @@ -354,18 +356,24 @@ public: DOS_InfoBlock () {}; void SetLocation(Bit16u seg); void SetFirstMCB(Bit16u _first_mcb); - void SetfirstFileTable(RealPt _first_table); void SetBuffers(Bit16u x,Bit16u y); void SetCurDirStruct(Bit32u _curdirstruct); void SetFCBTable(Bit32u _fcbtable); void SetDeviceChainStart(Bit32u _devchain); void SetDiskBufferHeadPt(Bit32u _dbheadpt); - RealPt GetPointer (void); + void SetStartOfUMBChain(Bit16u _umbstartseg); + void SetUMBChainState(Bit8u _umbchaining); + Bit16u GetStartOfUMBChain(void); + Bit8u GetUMBChainState(void); + RealPt GetPointer(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 @@ -406,7 +414,7 @@ public: Bit16u lookaheadBufNumber; // 0x51 number of lookahead buffers Bit8u bufferLocation; // 0x53 workspace buffer location Bit32u workspaceBuffer; // 0x54 pointer to workspace buffer - Bit8u unknown2[11]; // 0x58 + 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 diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 2b365d88..9ab3f757 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.84 2005-04-29 13:32:31 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.85 2005-08-08 13:33:44 c2woody Exp $ */ #include #include @@ -716,12 +716,15 @@ static Bitu DOS_21Handler(void) { DOS_SetMemAllocStrategy(reg_bx); break; case 2: /* Get UMB Link Status */ - reg_ax=1; // no UMB support - CALLBACK_SCF(true); + reg_al=dos_infoblock.GetUMBChainState()&1; + CALLBACK_SCF(false); break; case 3: /* Set UMB Link Status */ - reg_ax=1; // failure, no support - CALLBACK_SCF(true); + if (DOS_LinkUMBsToMemChain(reg_bx)) CALLBACK_SCF(false); + else { + reg_ax=1; + CALLBACK_SCF(true); + } break; default: LOG(LOG_DOSMISC,LOG_ERROR)("DOS:58:Not Supported Set//Get memory allocation call %X",reg_al); diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index dfdafe60..17411c3f 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.44 2005-08-01 09:30:45 c2woody Exp $ */ +/* $Id: dos_classes.cpp,v 1.45 2005-08-08 13:33:45 c2woody Exp $ */ #include #include @@ -63,6 +63,7 @@ void DOS_InfoBlock::SetLocation(Bit16u segment) { pt=PhysMake(seg,0); /* Clear the initial Block */ for(Bitu i=0;i16mb + sSave(sDIB,magicWord,(Bit16u)0x0001); // dos5+ sSave(sDIB,sharingCount,(Bit16u)0); sSave(sDIB,sharingDelay,(Bit16u)0); + sSave(sDIB,ptrCONinput,(Bit16u)0); // no unread input available + sSave(sDIB,maxSectorLength,(Bit16u)0x200); sSave(sDIB,dirtyDiskBuffers,(Bit16u)0); sSave(sDIB,lookaheadBufPt,(Bit32u)0); @@ -109,16 +113,20 @@ void DOS_InfoBlock::SetLocation(Bit16u segment) { sSave(sDIB,nulString[5],(Bit8u)0x20); sSave(sDIB,nulString[6],(Bit8u)0x20); sSave(sDIB,nulString[7],(Bit8u)0x20); + + /* Create a fake SFT, so programs think there are 100 file handles */ + Bit16u sftOffset=offsetof(sDIB,firstFileTable)+0xa2; + sSave(sDIB,firstFileTable,RealMake(segment,sftOffset)); + real_writed(segment,sftOffset+0x00,RealMake(segment+0x11,0)); //Next File Table + real_writew(segment,sftOffset+0x04,100); //File Table supports 100 files + real_writed(segment+0x11,0x00,0xffffffff); //Last File Table + real_writew(segment+0x11,0x04,100); //File Table supports 100 files } void DOS_InfoBlock::SetFirstMCB(Bit16u _firstmcb) { sSave(sDIB,firstMCB,_firstmcb); //c2woody } -void DOS_InfoBlock::SetfirstFileTable(RealPt _first_table) { - sSave(sDIB,firstFileTable,_first_table); -} - void DOS_InfoBlock::SetBuffers(Bit16u x,Bit16u y) { sSave(sDIB,buffers_x,x); sSave(sDIB,buffers_y,y); @@ -140,6 +148,22 @@ void DOS_InfoBlock::SetDiskBufferHeadPt(Bit32u _dbheadpt) { sSave(sDIB,diskBufferHeadPt,_dbheadpt); } +Bit16u DOS_InfoBlock::GetStartOfUMBChain(void) { + return sGet(sDIB,startOfUMBChain); +} + +void DOS_InfoBlock::SetStartOfUMBChain(Bit16u _umbstartseg) { + sSave(sDIB,startOfUMBChain,_umbstartseg); +} + +Bit8u DOS_InfoBlock::GetUMBChainState(void) { + return sGet(sDIB,chainingUMB); +} + +void DOS_InfoBlock::SetUMBChainState(Bit8u _umbchaining) { + sSave(sDIB,chainingUMB,_umbchaining); +} + RealPt DOS_InfoBlock::GetPointer(void) { return RealMake(seg,offsetof(sDIB,firstDPB)); } diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index df0ec862..1558f013 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -20,6 +20,8 @@ #include "mem.h" #include "dos_inc.h" +#define UMB_START_SEG 0x9fff + static Bit16u memAllocStrategy = 0x00; static void DOS_CompressMemory(void) { @@ -50,6 +52,20 @@ void DOS_FreeProcessMemory(Bit16u pspseg) { mcb_segment+=mcb.GetSize()+1; mcb.SetPt(mcb_segment); } + + Bit16u umb_start=dos_infoblock.GetStartOfUMBChain(); + if (umb_start==UMB_START_SEG) { + DOS_MCB umb_mcb(umb_start); + while (true) { + if (umb_mcb.GetPSPSeg()==pspseg) { + umb_mcb.SetPSPSeg(MCB_FREE); + } + if (umb_mcb.GetType()!=0x4d) break; + umb_start+=umb_mcb.GetSize()+1; + umb_mcb.SetPt(umb_start); + } + } else if (umb_start!=0xffff) LOG(LOG_DOSMISC,LOG_ERROR)("Corrupt UMB chain: %x",umb_start); + DOS_CompressMemory(); }; @@ -65,7 +81,15 @@ void DOS_SetMemAllocStrategy(Bit16u strat) bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { DOS_CompressMemory(); - Bit16u bigsize=0;Bit16u mcb_segment=dos.firstMCB; + Bit16u bigsize=0; + Bit16u mem_strat=memAllocStrategy; + Bit16u mcb_segment=dos.firstMCB; + + Bit16u umb_start=dos_infoblock.GetStartOfUMBChain(); + if (umb_start==UMB_START_SEG) { + if (mem_strat&0xc0) mcb_segment=umb_start; + } else if (umb_start!=0xffff) LOG(LOG_DOSMISC,LOG_ERROR)("Corrupt UMB chain: %x",umb_start); + DOS_MCB mcb(0); DOS_MCB mcb_next(0); DOS_MCB psp_mcb(dos.psp()-1); @@ -88,7 +112,7 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { } else { // TODO: Strategy "1": Best matching block /* If so allocate it */ - if ((memAllocStrategy & 0x03)==0) { + if ((mem_strat & 0x03)==0) { mcb_next.SetPt((Bit16u)(mcb_segment+*blocks+1)); mcb_next.SetPSPSeg(MCB_FREE); mcb_next.SetType(mcb.GetType()); @@ -119,11 +143,15 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { } /* Onward to the next MCB if there is one */ if (mcb.GetType()==0x5a) { - *blocks=bigsize; - DOS_SetError(DOSERR_INSUFFICIENT_MEMORY); - return false; - } - mcb_segment+=mcb.GetSize()+1; + if ((mem_strat&0x80) && (umb_start==UMB_START_SEG)) { + mcb_segment=dos.firstMCB; + mem_strat&=(~0xc0); + } else { + *blocks=bigsize; + DOS_SetError(DOSERR_INSUFFICIENT_MEMORY); + return false; + } + } else mcb_segment+=mcb.GetSize()+1; } return false; } @@ -210,6 +238,109 @@ bool DOS_FreeMemory(Bit16u segment) { } +void DOS_BuildUMBChain(const char* use_umbs,bool ems_active) { + if (strcmp(use_umbs,"false")!=0) { + Bit16u first_umb_seg=0xca00; + Bit16u first_umb_size=0x600; + + if (strcmp(use_umbs,"max")==0) { + first_umb_seg-=0x100; + first_umb_size+=0x100; + } + + dos_infoblock.SetStartOfUMBChain(UMB_START_SEG); + dos_infoblock.SetUMBChainState(0); // UMBs not linked yet + + DOS_MCB umb_mcb(first_umb_seg); + umb_mcb.SetPSPSeg(0); // currently free + umb_mcb.SetSize(first_umb_size-1); + umb_mcb.SetType(0x5a); + + /* Scan MCB-chain for last block */ + Bit16u mcb_segment=dos.firstMCB; + DOS_MCB mcb(mcb_segment); + while (mcb.GetType()!=0x5a) { + mcb_segment+=mcb.GetSize()+1; + mcb.SetPt(mcb_segment); + } + + /* A system MCB has to cover the space between the + regular MCB-chain and the UMBs */ + Bit16u cover_mcb=(Bit16u)(mcb_segment+mcb.GetSize()+1); + mcb.SetPt(cover_mcb); + mcb.SetType(0x4d); + mcb.SetPSPSeg(0x0008); + mcb.SetSize(first_umb_seg-cover_mcb-1); + mcb.SetFileName("SC "); + + if (!ems_active && (strcmp(use_umbs,"max")==0)) { + Bit16u ems_umb_seg=0xe000; + Bit16u ems_umb_size=0x1000; + + /* Continue UMB-chain */ + umb_mcb.SetSize(first_umb_size-2); + umb_mcb.SetType(0x4d); + + DOS_MCB umb2_mcb(ems_umb_seg); + umb2_mcb.SetPSPSeg(0); // currently free + umb2_mcb.SetSize(ems_umb_size-1); + umb2_mcb.SetType(0x5a); + + /* A system MCB has to take out the space between the previous and this UMB */ + cover_mcb=(Bit16u)(first_umb_seg+umb_mcb.GetSize()+1); + mcb.SetPt(cover_mcb); + mcb.SetType(0x4d); + mcb.SetPSPSeg(0x0008); + mcb.SetSize(ems_umb_seg-cover_mcb-1); + mcb.SetFileName("SC "); + } + } else { + dos_infoblock.SetStartOfUMBChain(0xffff); + dos_infoblock.SetUMBChainState(0); + } +} + +bool DOS_LinkUMBsToMemChain(Bit16u linkstate) { + /* Get start of UMB-chain */ + Bit16u umb_start=dos_infoblock.GetStartOfUMBChain(); + if (umb_start!=UMB_START_SEG) { + if (umb_start!=0xffff) LOG(LOG_DOSMISC,LOG_ERROR)("Corrupt UMB chain: %x",umb_start); + return true; + } + + if ((linkstate&1)==(dos_infoblock.GetUMBChainState()&1)) return true; + + /* Scan MCB-chain for last block before UMB-chain */ + Bit16u mcb_segment=dos.firstMCB; + Bit16u prev_mcb_segment; + DOS_MCB mcb(mcb_segment); + while ((mcb_segment!=umb_start) && (mcb.GetType()!=0x5a)) { + prev_mcb_segment=mcb_segment; + mcb_segment+=mcb.GetSize()+1; + mcb.SetPt(mcb_segment); + } + DOS_MCB prev_mcb(prev_mcb_segment); + + switch (linkstate) { + case 0x0000: // unlink + if ((prev_mcb.GetType()==0x4d) && (mcb_segment==umb_start)) { + prev_mcb.SetType(0x5a); + } + dos_infoblock.SetUMBChainState(0); + break; + case 0x0001: // link + if (mcb.GetType()==0x5a) { + mcb.SetType(0x4d); + dos_infoblock.SetUMBChainState(1); + } + break; + default: + LOG_MSG("Invalid link state %x when reconfiguring MCB chain",linkstate); + return false; + } + + return true; +} void DOS_SetupMemory(void) { @@ -218,6 +349,7 @@ void DOS_SetupMemory(void) { mcb_devicedummy.SetPSPSeg(0x0008); // Devices mcb_devicedummy.SetSize(1); mcb_devicedummy.SetType(0x4d); // More blocks will follow +// mcb_devicedummy.SetFileName("SD "); // BioMenace (segment of int2<0x8000) mem_writeb((DOS_MEM_START+1)<<4,0xcf);// iret diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index f97e98f0..668069c7 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.38 2005-07-20 11:35:53 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.39 2005-08-08 13:33:45 c2woody Exp $ */ #include #include @@ -207,9 +207,40 @@ public: void Run(void) { /* Show conventional Memory */ WriteOut("\n"); + + Bit16u umb_start=dos_infoblock.GetStartOfUMBChain(); + Bit8u umb_flag=dos_infoblock.GetUMBChainState(); + Bit8u old_memstrat=DOS_GetMemAllocStrategy()&0xff; + if (umb_start!=0xffff) { + if ((umb_flag&1)==1) DOS_LinkUMBsToMemChain(0); + DOS_SetMemAllocStrategy(0); + } + Bit16u seg,blocks;blocks=0xffff; DOS_AllocateMemory(&seg,&blocks); WriteOut(MSG_Get("PROGRAM_MEM_CONVEN"),blocks*16/1024); + + if (umb_start!=0xffff) { + DOS_LinkUMBsToMemChain(1); + DOS_SetMemAllocStrategy(0x40); // search in UMBs only + + Bit16u largest_block=0,total_blocks=0,block_count=0; + for (;; block_count++) { + blocks=0xffff; + DOS_AllocateMemory(&seg,&blocks); + if (blocks==0) break; + total_blocks+=blocks; + if (blocks>largest_block) largest_block=blocks; + DOS_AllocateMemory(&seg,&blocks); + } + + Bit8u current_umb_flag=dos_infoblock.GetUMBChainState(); + if ((current_umb_flag&1)!=(umb_flag&1)) DOS_LinkUMBsToMemChain(umb_flag); + DOS_SetMemAllocStrategy(old_memstrat); // restore strategy + + if (block_count>0) WriteOut(MSG_Get("PROGRAM_MEM_UPPER"),total_blocks*16/1024,block_count,largest_block*16/1024); + } + /* Test for and show free XMS */ reg_ax=0x4300;CALLBACK_RunRealInt(0x2f); if (reg_al==0x80) { @@ -695,6 +726,7 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_MEM_CONVEN","%10d Kb free conventional memory\n"); MSG_Add("PROGRAM_MEM_EXTEND","%10d Kb free extended memory\n"); MSG_Add("PROGRAM_MEM_EXPAND","%10d Kb free expanded memory\n"); + MSG_Add("PROGRAM_MEM_UPPER","%10d Kb free upper memory in %d blocks (largest UMB %d Kb)\n"); MSG_Add("PROGRAM_LOADFIX_ALLOC","%d kb allocated.\n"); MSG_Add("PROGRAM_LOADFIX_DEALLOC","%d kb freed.\n"); diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 6cd6f9ad..a2bd7754 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.19 2005-08-01 09:30:45 c2woody Exp $ */ +/* $Id: dos_tables.cpp,v 1.20 2005-08-08 13:33:46 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -100,15 +100,6 @@ void DOS_SetupTables(void) { real_writed(seg,0x0e,0x20202020); // driver name dos_infoblock.SetDeviceChainStart(RealMake(seg,0)); - /* Create a fake SFT, so programs think there are 100 file handles */ - seg=DOS_SFT_SEG; - seg2=DOS_SFT_SEG+1; - real_writed(seg,0,seg2<<16); //Next File Table - real_writew(seg,4,100); //File Table supports 100 files - real_writed(seg2,0,0xffffffff); //Last File Table - real_writew(seg2,4,100); //File Table supports 100 files - dos_infoblock.SetfirstFileTable(RealMake(seg,0)); - /* Create a fake Current Directory Structure */ seg=DOS_CDS_SEG; real_writed(seg,0x00,0x005c3a43); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 4cc4c2d1..bb4a9aa8 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.86 2005-07-30 14:41:31 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.87 2005-08-08 13:33:46 c2woody Exp $ */ #include #include @@ -379,9 +379,11 @@ void DOSBOX_Init(void) { secprop->Add_bool("xms",true); secprop->AddInitFunction(&EMS_Init,true);//done secprop->Add_bool("ems",true); + secprop->Add_string("umb","true"); MSG_Add("DOS_CONFIGFILE_HELP", "xms -- Enable XMS support.\n" "ems -- Enable EMS support.\n" + "umb -- Enable UMB support (false,true,max).\n" ); // Mscdex secprop->AddInitFunction(&MSCDEX_Init); diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 3b2f683e..e33e7b64 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.35 2005-03-25 11:59:24 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.36 2005-08-08 13:33:46 c2woody Exp $ */ #include #include @@ -55,6 +55,7 @@ #define XMS_QUERY_ANY_FREE_MEMORY 0x88 #define XMS_ALLOCATE_ANY_MEMORY 0x89 +#define XMS_FUNCTION_NOT_IMPLEMENTED 0x80 #define HIGH_MEMORY_NOT_EXIST 0x90 #define HIGH_MEMORY_IN_USE 0x91 #define HIGH_MEMORY_NOT_ALLOCATED 0x93 @@ -63,6 +64,8 @@ #define XMS_INVALID_HANDLE 0xa2 #define XMS_BLOCK_NOT_LOCKED 0xaa #define XMS_BLOCK_LOCKED 0xab +#define UMB_ONLY_SMALLER_BLOCK 0xb0 +#define UMB_NO_BLOCKS_AVAILABLE 0xb1 struct XMS_Block { Bitu size; @@ -102,6 +105,7 @@ Bitu XMS_GetEnabledA20(void) }; static RealPt xms_callback; +static bool umb_available; static XMS_Block xms_handles[XMS_HANDLES]; @@ -322,13 +326,57 @@ Bitu XMS_Handler(void) { reg_bl = XMS_ResizeMemory(reg_dx, reg_bx); reg_ax = (reg_bl==0); break; - case XMS_ALLOCATE_UMB: /* 10 */ - reg_ax=0; - reg_bl=0xb1; //No UMB Available - reg_dx=0; + case XMS_ALLOCATE_UMB: { /* 10 */ + if (!umb_available) { + reg_ax=0; + reg_bl=XMS_FUNCTION_NOT_IMPLEMENTED; + break; + } + Bit16u umb_start=dos_infoblock.GetStartOfUMBChain(); + if (umb_start==0xffff) { + reg_ax=0; + reg_bl=UMB_NO_BLOCKS_AVAILABLE; + reg_dx=0; // no upper memory available + break; + } + /* Save status and linkage of upper UMB chain and link upper + memory to the regular MCB chain */ + Bit8u umb_flag=dos_infoblock.GetUMBChainState(); + if ((umb_flag&1)==0) DOS_LinkUMBsToMemChain(1); + Bit8u old_memstrat=DOS_GetMemAllocStrategy()&0xff; + DOS_SetMemAllocStrategy(0x40); // search in UMBs only + + Bit16u size=reg_dx;Bit16u seg; + if (DOS_AllocateMemory(&seg,&size)) { + reg_ax=1; + reg_bx=seg; + } else { + reg_ax=0; + if (size==0) reg_bl=UMB_NO_BLOCKS_AVAILABLE; + else reg_bl=UMB_ONLY_SMALLER_BLOCK; + reg_dx=size; // size of largest available UMB + } + + /* Restore status and linkage of upper UMB chain */ + Bit8u current_umb_flag=dos_infoblock.GetUMBChainState(); + if ((current_umb_flag&1)!=(umb_flag&1)) DOS_LinkUMBsToMemChain(umb_flag); + DOS_SetMemAllocStrategy(old_memstrat); + } break; case XMS_DEALLOCATE_UMB: /* 11 */ - LOG(LOG_MISC,LOG_ERROR)("XMS:Unhandled call %2X",reg_ah); + if (!umb_available) { + reg_ax=0; + reg_bl=XMS_FUNCTION_NOT_IMPLEMENTED; + break; + } + if (dos_infoblock.GetStartOfUMBChain()!=0xffff) { + if (DOS_FreeMemory(reg_dx)) { + reg_ax=0x0001; + break; + } + } + reg_ax=0x0000; + reg_bl=UMB_NO_BLOCKS_AVAILABLE; break; case XMS_QUERY_ANY_FREE_MEMORY: /* 88 */ reg_bl = XMS_QueryFreeMemory(reg_ax,reg_dx); @@ -336,6 +384,10 @@ Bitu XMS_Handler(void) { reg_edx &= 0xffff; reg_ecx = (MEM_TotalPages()*MEM_PAGESIZE)-1; // highest known physical memory address break; + default: + LOG(LOG_MISC,LOG_ERROR)("XMS: unknown function %02X",reg_ah); + reg_ax=0; + reg_bl=XMS_FUNCTION_NOT_IMPLEMENTED; } // LOG(LOG_MISC,LOG_ERROR)("XMS: CALL Result: %02X",reg_bl); return CBRET_NONE; @@ -346,6 +398,7 @@ private: public: XMS(Section* configuration):Module_base(configuration){ Section_prop * section=static_cast(configuration); + umb_available=false; if (!section->Get_bool("xms")) return; Bitu i; BIOS_ZeroExtendedSize(true); @@ -373,10 +426,21 @@ public: } /* Disable the 0 handle */ xms_handles[0].free = false; + + /* Set up UMB chain */ + umb_available=strcmp(section->Get_string("umb"),"false")!=0; + DOS_BuildUMBChain(section->Get_string("umb"),section->Get_bool("ems")); } ~XMS(){ Section_prop * section = static_cast(m_configuration); + /* Remove upper memory information */ + dos_infoblock.SetStartOfUMBChain(0xffff); + if (umb_available) { + dos_infoblock.SetUMBChainState(0); + umb_available=false; + } + if (!section->Get_bool("xms")) return; /* Undo biosclearing */ BIOS_ZeroExtendedSize(false); From f91d45b37881a3a65b4d26f433b8772791b1b6a5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 8 Aug 2005 20:29:55 +0000 Subject: [PATCH 2179/4131] make localhost connections work as well. (h-a-l-9000) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2263 --- src/hardware/ipxserver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/ipxserver.cpp b/src/hardware/ipxserver.cpp index 98f64dbd..bcd88ec6 100644 --- a/src/hardware/ipxserver.cpp +++ b/src/hardware/ipxserver.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipxserver.cpp,v 1.5 2005-07-30 10:02:39 qbix79 Exp $ */ +/* $Id: ipxserver.cpp,v 1.6 2005-08-08 20:29:55 qbix79 Exp $ */ #include "dosbox.h" @@ -87,7 +87,7 @@ static void sendIPXPacket(Bit8u *buffer, Bit16s bufSize) { if(desthost == 0xffffffff) { // Broadcast for(i=0;i Date: Tue, 9 Aug 2005 09:49:06 +0000 Subject: [PATCH 2180/4131] updates to the debugger Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2264 --- src/debug/debug.cpp | 286 +++++++++++++++++++++++++++++-------- src/debug/debug_disasm.cpp | 26 ++-- src/debug/debug_gui.cpp | 2 + 3 files changed, 247 insertions(+), 67 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 0d4ea81d..620d17e6 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.65 2005-07-30 10:13:24 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.66 2005-08-09 09:49:06 c2woody Exp $ */ #include #include @@ -40,6 +40,7 @@ #include "shell.h" #include "programs.h" #include "debug_inc.h" +#include "../cpu/lazyflags.h" #ifdef WIN32 void WIN32_Console(); @@ -58,6 +59,8 @@ static void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num); static void LogGDT(void); static void LogLDT(void); static void LogIDT(void); +static void LogPages(char* selname); +static void LogCPUInfo(void); static void OutputVecTable(char* filename); static void DrawVariables(void); @@ -78,6 +81,7 @@ bool logHeavy = false; static FILE* cpuLogFile = 0; static bool cpuLog = false; static int cpuLogCounter = 0; +static int cpuLogType = 1; // log detail #endif @@ -89,7 +93,7 @@ static struct { static char curSelectorName[3] = { 0,0,0 }; static Segment oldsegs[6]; -static Bitu oldflags; +static Bitu oldflags,oldcpucpl; DBGBlock dbg; static Bitu input_count; Bitu cycle_count; @@ -135,7 +139,7 @@ Bit32u PhysMakeProt(Bit16u selector, Bit32u offset) Bit32u GetAddress(Bit16u seg, Bit32u offset) { if (seg==SegValue(cs)) return SegPhys(cs)+offset; - if (cpu.pmode) { + if (cpu.pmode && !(reg_flags & FLAG_VM)) { Descriptor desc; if (cpu.gdt.GetDescriptor(seg,desc)) return PhysMakeProt(seg,offset); } @@ -148,15 +152,43 @@ bool GetDescriptorInfo(char* selname, char* out1, char* out2) Bitu sel; Descriptor desc; - if (strstr(selname,"cs") || strstr(selname,"CS")) sel = SegValue(cs); else - if (strstr(selname,"ds") || strstr(selname,"DS")) sel = SegValue(ds); else - if (strstr(selname,"es") || strstr(selname,"ES")) sel = SegValue(es); else - if (strstr(selname,"fs") || strstr(selname,"FS")) sel = SegValue(fs); else - if (strstr(selname,"gs") || strstr(selname,"GS")) sel = SegValue(gs); else - if (strstr(selname,"ss") || strstr(selname,"SS")) sel = SegValue(ss); else - sel = GetHexValue(selname,selname); - // FIXME: Call Gate Descriptors + if (strstr(selname,"cs") || strstr(selname,"CS")) sel = SegValue(cs); + else if (strstr(selname,"ds") || strstr(selname,"DS")) sel = SegValue(ds); + else if (strstr(selname,"es") || strstr(selname,"ES")) sel = SegValue(es); + else if (strstr(selname,"fs") || strstr(selname,"FS")) sel = SegValue(fs); + else if (strstr(selname,"gs") || strstr(selname,"GS")) sel = SegValue(gs); + else if (strstr(selname,"ss") || strstr(selname,"SS")) sel = SegValue(ss); + else { + sel = GetHexValue(selname,selname); + if (*selname==0) selname=" "; + } if (cpu.gdt.GetDescriptor(sel,desc)) { + switch (desc.Type()) { + case DESC_TASK_GATE: + sprintf(out1,"%s: s:%08X type:%02X p",selname,desc.GetSelector(),desc.saved.gate.type); + sprintf(out2," TaskGate dpl : %01X %1X",desc.saved.gate.dpl,desc.saved.gate.p); + return true; + case DESC_LDT: + case DESC_286_TSS_A: + case DESC_286_TSS_B: + case DESC_386_TSS_A: + case DESC_386_TSS_B: + sprintf(out1,"%s: b:%08X type:%02X pag",selname,desc.GetBase(),desc.saved.seg.type); + sprintf(out2," l:%08X dpl : %01X %1X%1X%1X",desc.GetLimit(),desc.saved.seg.dpl,desc.saved.seg.p,desc.saved.seg.avl,desc.saved.seg.g); + return true; + case DESC_286_CALL_GATE: + case DESC_386_CALL_GATE: + sprintf(out1,"%s: s:%08X type:%02X p params: %02X",selname,desc.GetSelector(),desc.saved.gate.type,desc.saved.gate.paramcount); + sprintf(out2," o:%08X dpl : %01X %1X",desc.GetOffset(),desc.saved.gate.dpl,desc.saved.gate.p); + return true; + case DESC_286_INT_GATE: + case DESC_286_TRAP_GATE: + case DESC_386_INT_GATE: + case DESC_386_TRAP_GATE: + sprintf(out1,"%s: s:%08X type:%02X p",selname,desc.GetSelector(),desc.saved.gate.type); + sprintf(out2," o:%08X dpl : %01X %1X",desc.GetOffset(),desc.saved.gate.dpl,desc.saved.gate.p); + return true; + } sprintf(out1,"%s: b:%08X type:%02X parbg",selname,desc.GetBase(),desc.saved.seg.type); sprintf(out2," l:%08X dpl : %01X %1X%1X%1X%1X%1X",desc.GetLimit(),desc.saved.seg.dpl,desc.saved.seg.p,desc.saved.seg.avl,desc.saved.seg.r,desc.saved.seg.big,desc.saved.seg.g); return true; @@ -164,7 +196,6 @@ bool GetDescriptorInfo(char* selname, char* out1, char* out2) strcpy(out1," "); strcpy(out2," "); } - //out1[0] = out2[0] = 0; return false; }; @@ -607,15 +638,16 @@ static void DrawData(void) { /* Data win */ for (int y=0; y<8; y++) { // Adress - mvwprintw (dbg.win_data,1+y,0,"%04X:%04X ",dataSeg,add); + if (add<0x10000) mvwprintw (dbg.win_data,1+y,0,"%04X:%04X ",dataSeg,add); + else mvwprintw (dbg.win_data,1+y,0,"%04X:%08X ",dataSeg,add); for (int x=0; x<16; x++) { address = GetAddress(dataSeg,add); if (!(paging.tlb.handler[address >> 12]->flags & PFLAG_INIT)) { ch = mem_readb(address); } else ch = 0; - mvwprintw (dbg.win_data,1+y,11+3*x,"%02X",ch); + mvwprintw (dbg.win_data,1+y,14+3*x,"%02X",ch); if (ch<32 || !isprint(*reinterpret_cast(&ch))) ch='.'; - mvwprintw (dbg.win_data,1+y,60+x,"%c",ch); + mvwprintw (dbg.win_data,1+y,63+x,"%c",ch); add++; }; } @@ -665,8 +697,14 @@ static void DrawRegisters(void) { SetColor((reg_flags ^ oldflags)&FLAG_TF); mvwprintw (dbg.win_reg,1,77,"%01X",GETFLAG(TF) ? 1:0); + SetColor((reg_flags ^ oldflags)&FLAG_IOPL); + mvwprintw (dbg.win_reg,2,72,"%01X",GETFLAG(IOPL)>>12); oldflags=reg_flags; + SetColor(cpu.cpl ^ oldcpucpl); + mvwprintw (dbg.win_reg,2,78,"%01X",cpu.cpl); + oldcpucpl=cpu.cpl; + if (cpu.pmode) { if (reg_flags & FLAG_VM) mvwprintw(dbg.win_reg,0,76,"VM86"); else if (cpu.code.big) mvwprintw(dbg.win_reg,0,76,"Pr32"); @@ -847,12 +885,13 @@ bool ChangeRegister(char* str) if (strstr(hex,"SS")==hex) { hex+=2; SegSet16(ss,(Bit16u)GetHexValue(hex,hex)); } else if (strstr(hex,"AF")==hex) { hex+=2; SETFLAGBIT(AF,GetHexValue(hex,hex)); } else if (strstr(hex,"CF")==hex) { hex+=2; SETFLAGBIT(CF,GetHexValue(hex,hex)); } else - if (strstr(hex,"DF")==hex) { hex+=2; SETFLAGBIT(PF,GetHexValue(hex,hex)); } else + if (strstr(hex,"DF")==hex) { hex+=2; SETFLAGBIT(DF,GetHexValue(hex,hex)); } else if (strstr(hex,"IF")==hex) { hex+=2; SETFLAGBIT(IF,GetHexValue(hex,hex)); } else if (strstr(hex,"OF")==hex) { hex+=3; SETFLAGBIT(OF,GetHexValue(hex,hex)); } else if (strstr(hex,"ZF")==hex) { hex+=3; SETFLAGBIT(ZF,GetHexValue(hex,hex)); } else if (strstr(hex,"PF")==hex) { hex+=3; SETFLAGBIT(PF,GetHexValue(hex,hex)); } else - { return false; }; + if (strstr(hex,"SF")==hex) { hex+=3; SETFLAGBIT(SF,GetHexValue(hex,hex)); } else + { return false; }; return true; }; @@ -1046,10 +1085,51 @@ bool ParseCommand(char* str) // DEBUG_Log_Loop(GetHexValue(found,found)); cpuLogFile = fopen("LOGCPU.TXT","wt"); if (!cpuLogFile) { - DEBUG_ShowMsg("DEBUG: Logfile couldnt be created.\n"); + DEBUG_ShowMsg("DEBUG: Logfile couldn't be created.\n"); return false; } cpuLog = true; + cpuLogType = 1; + cpuLogCounter = GetHexValue(found,found); + + debugging=false; + CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); + ignoreAddressOnce = SegPhys(cs)+reg_eip; + DOSBOX_SetNormalLoop(); + return true; + } + + found = strstr(str,"LOGS "); + if (found) { // Create Cpu log file + found+=4; + DEBUG_ShowMsg("DEBUG: Starting log\n"); + cpuLogFile = fopen("LOGCPU.TXT","wt"); + if (!cpuLogFile) { + DEBUG_ShowMsg("DEBUG: Logfile couldn't be created.\n"); + return false; + } + cpuLog = true; + cpuLogType = 0; + cpuLogCounter = GetHexValue(found,found); + + debugging=false; + CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); + ignoreAddressOnce = SegPhys(cs)+reg_eip; + DOSBOX_SetNormalLoop(); + return true; + } + + found = strstr(str,"LOGL "); + if (found) { // Create Cpu log file + found+=4; + DEBUG_ShowMsg("DEBUG: Starting log\n"); + cpuLogFile = fopen("LOGCPU.TXT","wt"); + if (!cpuLogFile) { + DEBUG_ShowMsg("DEBUG: Logfile couldn't be created.\n"); + return false; + } + cpuLog = true; + cpuLogType = 2; cpuLogCounter = GetHexValue(found,found); debugging=false; @@ -1107,6 +1187,18 @@ bool ParseCommand(char* str) LogIDT(); } + found = strstr(str,"PAGING"); + if (found) { + found += 6; + while (found[0]==' ') found++; + LogPages(found); + } + + found = strstr(str,"CPU"); + if (found) { + LogCPUInfo(); + } + found = strstr(str,"INTVEC "); if (found) { @@ -1131,15 +1223,6 @@ bool ParseCommand(char* str) } } - /* found = strstr(str,"EXCEPTION "); - if (found) { - found += 9; - Bit8u num = GetHexValue(found,found); - DPMI_CreateException(num,0xDD); - DEBUG_ShowMsg("Exception %04X\n",num); - }; -*/ - #if C_HEAVY_DEBUG found = strstr(str,"HEAVYLOG"); if (found) { // Create Cpu log file @@ -1176,6 +1259,7 @@ bool ParseCommand(char* str) DEBUG_ShowMsg("INT [nr] / INTT [nr] - Execute / Trace into interrupt.\n"); #if C_HEAVY_DEBUG DEBUG_ShowMsg("LOG [num] - Write cpu log file.\n"); + DEBUG_ShowMsg("LOGS/LOGL [num] - Write short/long cpu log file.\n"); DEBUG_ShowMsg("HEAVYLOG - Enable/Disable automatic cpu when dosbox exits.\n"); #endif DEBUG_ShowMsg("SR [reg] [value] - Set register value.\n"); @@ -1191,6 +1275,12 @@ bool ParseCommand(char* str) DEBUG_ShowMsg("INTVEC [filename] - Writes interrupt vector table to file.\n"); DEBUG_ShowMsg("INTHAND [intNum] - Set code view to interrupt handler.\n"); + DEBUG_ShowMsg("CPU - Display CPU status information.\n"); + DEBUG_ShowMsg("GDT - Lists descriptors of the GDT.\n"); + DEBUG_ShowMsg("LDT - Lists descriptors of the LDT.\n"); + DEBUG_ShowMsg("IDT - Lists descriptors of the IDT.\n"); + DEBUG_ShowMsg("PAGING [page] - Display content of page table.\n"); + DEBUG_ShowMsg("H - Help\n"); return TRUE; @@ -1295,65 +1385,65 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) // Must be a jump if (instu[0] == 'J') { - bool jmp = 0; + bool jmp = false; switch (instu[1]) { - case 'A' : { jmp = !GETFLAGBOOL(CF) && !GETFLAGBOOL(ZF); // JA + case 'A' : { jmp = (get_CF()?false:true) && (get_ZF()?false:true); // JA } break; case 'B' : { if (instu[2] == 'E') { - jmp = GETFLAGBOOL(CF) && GETFLAGBOOL(ZF); // JBE + jmp = (get_CF()?true:false) && (get_ZF()?true:false); // JBE } else { - jmp = GETFLAGBOOL(CF); // JB + jmp = get_CF()?true:false; // JB } } break; case 'C' : { if (instu[2] == 'X') { jmp = reg_cx == 0; // JCXZ } else { - jmp = GETFLAGBOOL(CF); // JC + jmp = get_CF()?true:false; // JC } } break; - case 'E' : { jmp = GETFLAGBOOL(ZF); // JE + case 'E' : { jmp = get_ZF()?true:false; // JE } break; case 'G' : { if (instu[2] == 'E') { - jmp = !GETFLAGBOOL(SF); // JGE + jmp = get_SF()?false:true; // JGE } else { - jmp = !GETFLAGBOOL(SF) && !GETFLAGBOOL(ZF); // JG + jmp = (get_SF()?false:true) && (get_ZF()?false:true); // JG } } break; case 'L' : { if (instu[2] == 'E') { - jmp = GETFLAGBOOL(SF) || GETFLAGBOOL(ZF); // JLE + jmp = (get_SF()?true:false) || (get_ZF()?true:false) ; // JLE } else { - jmp = GETFLAGBOOL(SF); // JL + jmp = get_SF()?true:false; // JL } } break; case 'M' : { jmp = true; // JMP } break; case 'N' : { switch (instu[2]) { case 'B' : - case 'C' : { jmp = !GETFLAGBOOL(CF); // JNB / JNC + case 'C' : { jmp = get_CF()?false:true; // JNB / JNC } break; - case 'E' : { jmp = !GETFLAGBOOL(ZF); // JNE + case 'E' : { jmp = get_ZF()?false:true; // JNE } break; - case 'O' : { jmp = !GETFLAGBOOL(OF); // JNO + case 'O' : { jmp = get_OF()?false:true; // JNO } break; - case 'P' : { jmp = !GETFLAGBOOL(PF); // JNP + case 'P' : { jmp = get_PF()?false:true; // JNP } break; - case 'S' : { jmp = !GETFLAGBOOL(SF); // JNS + case 'S' : { jmp = get_SF()?false:true; // JNS } break; - case 'Z' : { jmp = !GETFLAGBOOL(ZF); // JNZ + case 'Z' : { jmp = get_ZF()?false:true; // JNZ } break; } } break; - case 'O' : { jmp = GETFLAGBOOL(OF); // JMP + case 'O' : { jmp = get_OF()?true:false; // JMP } break; case 'P' : { if (instu[2] == 'O') { - jmp = !GETFLAGBOOL(PF); // JPO + jmp = get_PF()?false:true; // JPO } else { - jmp = GETFLAGBOOL(SF); // JP / JPE + jmp = get_SF()?true:false; // JP / JPE } } break; - case 'S' : { jmp = GETFLAGBOOL(SF); // JS + case 'S' : { jmp = get_SF()?true:false; // JS } break; - case 'Z' : { jmp = GETFLAGBOOL(ZF); // JZ + case 'Z' : { jmp = get_ZF()?true:false; // JZ } break; } if (jmp) { @@ -1426,19 +1516,24 @@ Bit32u DEBUG_CheckKeys(void) { ret=(*cpudecoder)(); break; case 'D': dataSeg = SegValue(ds); - dataOfs = reg_si; + if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_esi; + else dataOfs = reg_si; break; case 'E': dataSeg = SegValue(es); - dataOfs = reg_di; + if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_edi; + else dataOfs = reg_di; break; case 'X': dataSeg = SegValue(ds); - dataOfs = reg_dx; + if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_edx; + else dataOfs = reg_dx; break; case 'B': dataSeg = SegValue(es); - dataOfs = reg_bx; + if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_ebx; + else dataOfs = reg_bx; break; case 'S': dataSeg = SegValue(ss); - dataOfs = reg_sp; + if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_esp; + else dataOfs = reg_sp; break; case 'R' : dataOfs -= 16; break; @@ -1611,6 +1706,68 @@ static void LogIDT(void) }; }; +void LogPages(char* selname) +{ + char out1[512]; + if (paging.enabled) { + Bitu sel = GetHexValue(selname,selname); + if ((sel==0x00) && ((*selname==0) || (*selname=='*'))) { + for (int i=0; i<0xfffff; i++) { + Bitu table_addr=(paging.base.page<<12)+(i >> 10)*4; + X86PageEntry table; + table.load=phys_readd(table_addr); + if (table.block.p) { + X86PageEntry entry; + Bitu entry_addr=(table.block.base<<12)+(i & 0x3ff)*4; + entry.load=phys_readd(entry_addr); + if (entry.block.p) { + sprintf(out1,"page %05Xxxx -> %04Xxxx flags [uw] %x:%x::%x:%x",i,entry.block.base,entry.block.us,table.block.us,entry.block.wr,table.block.wr); + LOG(LOG_MISC,LOG_ERROR)(out1); + } + } + } + } else { + Bitu table_addr=(paging.base.page<<12)+(sel >> 10)*4; + X86PageEntry table; + table.load=phys_readd(table_addr); + if (table.block.p) { + X86PageEntry entry; + Bitu entry_addr=(table.block.base<<12)+(sel & 0x3ff)*4; + entry.load=phys_readd(entry_addr); + sprintf(out1,"page %05Xxxx -> %04Xxxx flags [puw] %x:%x::%x:%x::%x:%x",sel,entry.block.base,entry.block.p,table.block.p,entry.block.us,table.block.us,entry.block.wr,table.block.wr); + LOG(LOG_MISC,LOG_ERROR)(out1); + } else { + sprintf(out1,"pagetable %03X not present, flags [puw] %x::%x::%x",(sel >> 10),table.block.p,table.block.us,table.block.wr); + LOG(LOG_MISC,LOG_ERROR)(out1); + } + } + } +}; + +static void LogCPUInfo(void) +{ + char out1[512]; + sprintf(out1,"cr0:%08X cr2:%08X cr3:%08X cpl=%x",cpu.cr0,paging.cr2,paging.cr3,cpu.cpl); + LOG(LOG_MISC,LOG_ERROR)(out1); + sprintf(out1,"eflags:%08X [vm=%x iopl=%x nt=%x]",reg_flags,GETFLAG(VM)>>17,GETFLAG(IOPL)>>12,GETFLAG(NT)>>14); + LOG(LOG_MISC,LOG_ERROR)(out1); + sprintf(out1,"GDT base=%08X limit=%08X",cpu.gdt.GetBase(),cpu.gdt.GetLimit()); + LOG(LOG_MISC,LOG_ERROR)(out1); + sprintf(out1,"IDT base=%08X limit=%08X",cpu.idt.GetBase(),cpu.idt.GetLimit()); + LOG(LOG_MISC,LOG_ERROR)(out1); + + Bitu sel; + Descriptor desc; + CPU_STR(sel); + cpu.gdt.GetDescriptor(sel,desc); + sprintf(out1,"TR selector=%04X, base=%08X limit=%08X*%X",sel,desc.GetBase(),desc.GetLimit(),desc.saved.seg.g?0x4000:1); + LOG(LOG_MISC,LOG_ERROR)(out1); + sel=cpu.gdt.SLDT(); + cpu.gdt.GetDescriptor(sel,desc); + sprintf(out1,"LDT selector=%04X, base=%08X limit=%08X*%X",sel,desc.GetBase(),desc.GetLimit(),desc.saved.seg.g?0x4000:1); + LOG(LOG_MISC,LOG_ERROR)(out1); +}; + static void LogInstruction(Bit16u segValue, Bit32u eipValue, char* buffer) { static char empty[15] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,0 }; @@ -1622,13 +1779,28 @@ static void LogInstruction(Bit16u segValue, Bit32u eipValue, char* buffer) char* res = empty; if (showExtend) { res = AnalyzeInstruction(dline,false); - if (!res || (strlen(res)==0)) res = empty; + len = strlen(dline); + if (cpuLogType>=2) { + Bitu reslen=strlen(res); + if (reslen<24) for (Bitu i=0; i<24-reslen; i++) strcat(res," "); + } else if (!res || (strlen(res)==0)) res = empty; }; - if (len<30) for (Bitu i=0; i<30-len; i++) strcat(dline," "); // Get register values - sprintf(buffer,"%04X:%08X %s %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X IF:%01X\n",segValue,eipValue,dline,res,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss), - GETFLAGBOOL(CF),GETFLAGBOOL(ZF),GETFLAGBOOL(SF),GETFLAGBOOL(OF),GETFLAGBOOL(AF),GETFLAGBOOL(PF),GETFLAGBOOL(IF)); + if (cpuLogType==1) { + if (len<30) for (Bitu i=0; i<30-len; i++) strcat(dline," "); + sprintf(buffer,"%04X:%08X %s %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X IF:%01X\n",segValue,eipValue,dline,res,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss), + get_CF()?1:0,get_ZF()?1:0,get_SF()?1:0,get_OF()?1:0,get_AF()?1:0,get_PF()?1:0,GETFLAGBOOL(IF)); + } else if (cpuLogType==0) { + if (len<27) for (Bitu i=0; i<27-len; i++) strcat(dline," "); + sprintf(buffer,"%04X:%04X %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X SS:%04X C%01X Z%01X S%01X O%01X I%01X\n",segValue,eipValue,dline,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(ss), + get_CF()?1:0,get_ZF()?1:0,get_SF()?1:0,get_OF()?1:0,GETFLAGBOOL(IF)); + } else { + if (len<34) for (Bitu i=0; i<34-len; i++) strcat(dline," "); + res[0]='x'; + sprintf(buffer,"%04X:%08X %s %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X IF:%01X TF:%01X VM:%01X FLG:%08X CR0:%08X\n",segValue,eipValue,dline,res,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss), + get_CF()?1:0,get_ZF()?1:0,get_SF()?1:0,get_OF()?1:0,get_AF()?1:0,get_PF()?1:0,GETFLAGBOOL(IF),GETFLAGBOOL(TF),GETFLAGBOOL(VM),reg_flags,cpu.cr0); + } }; static bool DEBUG_Log_Loop(int count) { diff --git a/src/debug/debug_disasm.cpp b/src/debug/debug_disasm.cpp index f0c0460e..3ccbded5 100644 --- a/src/debug/debug_disasm.cpp +++ b/src/debug/debug_disasm.cpp @@ -260,7 +260,7 @@ static char *op386map1[256] = { "call %Jv", "jmp %Jv", "jmp %Ap", "jmp %Ks%Jb", "in al,dx", "in %eax,dx", "out dx,al", "out dx,%eax", /* f */ - "lock %p ", 0, "repne %p ", "repe %p ", + "lock %p ", "icebp", "repne %p ", "repe %p ", "hlt", "cmc", "%g2", "%g2", "clc", "stc", "cli", "sti", "cld", "std", "%g3", "%g4" @@ -269,8 +269,8 @@ static char *op386map1[256] = { static char *second[] = { /* 0 */ "%g5", "%g6", "lar %Gv,%Ew", "lsl %Gv,%Ew", - 0, "loadall", "clts", "loadall", - "invd", "wbinvd", 0, 0, + 0, "[loadall]", "clts", "[loadall]", + "invd", "wbinvd", 0, "UD2", 0, 0, 0, 0, /* 1 */ "mov %Eb,%Gb", "mov %Ev,%Gv", "mov %Gb,%Eb", "mov %Gv,%Ev", @@ -308,7 +308,7 @@ static char *second[] = { "sets %Eb", "setns %Eb", "setp %Eb", "setnp %Eb", "setl %Eb", "setge %Eb", "setle %Eb", "setg %Eb", /* a */ - "push fs", "pop fs", 0, "bt %Ev,%Gv", + "push fs", "pop fs", "cpuid", "bt %Ev,%Gv", "shld %Ev,%Gv,%Ib", "shld %Ev,%Gv,cl", 0, 0, "push gs", "pop gs", 0, "bts %Ev,%Gv", "shrd %Ev,%Gv,%Ib", "shrd %Ev,%Gv,cl", 0, "imul %Gv,%Ev", @@ -354,7 +354,7 @@ static char *groups[][8] = { /* group 0 is group 3 for %Ev set */ "verr %Ew", "verw %Ew", 0, 0 }, /* 6 */ { "sgdt %Ms", "sidt %Ms", "lgdt %Ms", "lidt %Ms", - "smsw %Ew", 0, "lmsw %Ew", 0 }, + "smsw %Ew", 0, "lmsw %Ew", "invlpg" }, /* 7 */ { 0, 0, 0, 0, "bt", "bts", "btr", "btc" } @@ -363,8 +363,10 @@ static char *groups[][8] = { /* group 0 is group 3 for %Ev set */ /* zero here means invalid. If first entry starts with '*', use st(i) */ /* no assumed %EFs here. Indexed by RM(modrm()) */ static char *f0[] = { 0, 0, 0, 0, 0, 0, 0, 0}; +static char *fop_8[] = { "*fld st,%GF" }; static char *fop_9[] = { "*fxch st,%GF" }; static char *fop_10[] = { "fnop", 0, 0, 0, 0, 0, 0, 0 }; +static char *fop_11[] = { "*fst st,%GF" }; static char *fop_12[] = { "fchs", "fabs", 0, 0, "ftst", "fxam", 0, 0 }; static char *fop_13[] = { "fld1", "fldl2t", "fldl2e", "fldpi", "fldlg2", "fldln2", "fldz", 0 }; @@ -373,20 +375,24 @@ static char *fop_14[] = { "f2xm1", "fyl2x", "fptan", "fpatan", static char *fop_15[] = { "fprem", "fyl2xp1", "fsqrt", "fsincos", "frndint", "fscale", "fsin", "fcos" }; static char *fop_21[] = { 0, "fucompp", 0, 0, 0, 0, 0, 0 }; -static char *fop_28[] = { 0, 0, "fclex", "finit", 0, 0, 0, 0 }; +static char *fop_28[] = { "[fneni]", "[fndis]", "fclex", "finit", "[fnsetpm]", "[frstpm]", 0, 0 }; static char *fop_32[] = { "*fadd %GF,st" }; static char *fop_33[] = { "*fmul %GF,st" }; +static char *fop_34[] = { "*fcom %GF,st" }; +static char *fop_35[] = { "*fcomp %GF,st" }; static char *fop_36[] = { "*fsubr %GF,st" }; static char *fop_37[] = { "*fsub %GF,st" }; static char *fop_38[] = { "*fdivr %GF,st" }; static char *fop_39[] = { "*fdiv %GF,st" }; static char *fop_40[] = { "*ffree %GF" }; +static char *fop_41[] = { "*fxch %GF" }; static char *fop_42[] = { "*fst %GF" }; static char *fop_43[] = { "*fstp %GF" }; static char *fop_44[] = { "*fucom %GF" }; static char *fop_45[] = { "*fucomp %GF" }; static char *fop_48[] = { "*faddp %GF,st" }; static char *fop_49[] = { "*fmulp %GF,st" }; +static char *fop_50[] = { "*fcomp %GF,st" }; static char *fop_51[] = { 0, "fcompp", 0, 0, 0, 0, 0, 0 }; static char *fop_52[] = { "*fsubrp %GF,st" }; static char *fop_53[] = { "*fsubp %GF,st" }; @@ -396,12 +402,12 @@ static char *fop_60[] = { "fstsw ax", 0, 0, 0, 0, 0, 0, 0 }; static char **fspecial[] = { /* 0=use st(i), 1=undefined 0 in fop_* means undefined */ 0, 0, 0, 0, 0, 0, 0, 0, - 0, fop_9, fop_10, 0, fop_12, fop_13, fop_14, fop_15, + fop_8, fop_9, fop_10, fop_11, fop_12, fop_13, fop_14, fop_15, f0, f0, f0, f0, f0, fop_21, f0, f0, f0, f0, f0, f0, fop_28, f0, f0, f0, - fop_32, fop_33, f0, f0, fop_36, fop_37, fop_38, fop_39, - fop_40, f0, fop_42, fop_43, fop_44, fop_45, f0, f0, - fop_48, fop_49, f0, fop_51, fop_52, fop_53, fop_54, fop_55, + fop_32, fop_33, fop_34, fop_35, fop_36, fop_37, fop_38, fop_39, + fop_40, fop_41, fop_42, fop_43, fop_44, fop_45, f0, f0, + fop_48, fop_49, fop_50, fop_51, fop_52, fop_53, fop_54, fop_55, f0, f0, f0, f0, fop_60, f0, f0, f0, }; diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index bfa64dc2..95c42d7c 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -127,6 +127,8 @@ static void Draw_RegisterLayout(void) { mvwaddstr(dbg.win_reg,1,28,"CS="); mvwaddstr(dbg.win_reg,1,38,"EIP="); + mvwaddstr(dbg.win_reg,2,75,"CPL"); + mvwaddstr(dbg.win_reg,2,68,"IOPL"); mvwaddstr(dbg.win_reg,1,52,"C Z S O A P D I T "); } From c6df4f93399ba44b134eaa9cadfc7a1f9255cff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 10 Aug 2005 12:22:25 +0000 Subject: [PATCH 2181/4131] fix compiling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2265 --- src/debug/debug.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 620d17e6..f8b95b3c 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.66 2005-08-09 09:49:06 c2woody Exp $ */ +/* $Id: debug.cpp,v 1.67 2005-08-10 12:22:25 c2woody Exp $ */ #include #include @@ -1780,27 +1780,40 @@ static void LogInstruction(Bit16u segValue, Bit32u eipValue, char* buffer) if (showExtend) { res = AnalyzeInstruction(dline,false); len = strlen(dline); +#if C_HEAVY_DEBUG if (cpuLogType>=2) { Bitu reslen=strlen(res); if (reslen<24) for (Bitu i=0; i<24-reslen; i++) strcat(res," "); - } else if (!res || (strlen(res)==0)) res = empty; + } else +#endif + if (!res || (strlen(res)==0)) res = empty; }; - + // Get register values +#if C_HEAVY_DEBUG if (cpuLogType==1) { +#endif if (len<30) for (Bitu i=0; i<30-len; i++) strcat(dline," "); sprintf(buffer,"%04X:%08X %s %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X IF:%01X\n",segValue,eipValue,dline,res,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss), get_CF()?1:0,get_ZF()?1:0,get_SF()?1:0,get_OF()?1:0,get_AF()?1:0,get_PF()?1:0,GETFLAGBOOL(IF)); +#if C_HEAVY_DEBUG } else if (cpuLogType==0) { if (len<27) for (Bitu i=0; i<27-len; i++) strcat(dline," "); sprintf(buffer,"%04X:%04X %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X SS:%04X C%01X Z%01X S%01X O%01X I%01X\n",segValue,eipValue,dline,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(ss), get_CF()?1:0,get_ZF()?1:0,get_SF()?1:0,get_OF()?1:0,GETFLAGBOOL(IF)); } else { if (len<34) for (Bitu i=0; i<34-len; i++) strcat(dline," "); - res[0]='x'; - sprintf(buffer,"%04X:%08X %s %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X IF:%01X TF:%01X VM:%01X FLG:%08X CR0:%08X\n",segValue,eipValue,dline,res,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss), + char ibytes[200]=""; char tmpc[200]; + for (Bitu i=0; i Date: Wed, 10 Aug 2005 15:35:54 +0000 Subject: [PATCH 2182/4131] hide mouse cursor on non-supported(vesa) modi Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2266 --- src/ints/mouse.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index a9a9479a..c98d8a75 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.50 2005-06-02 17:27:27 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.51 2005-08-10 15:35:54 qbix79 Exp $ */ #include #include @@ -526,6 +526,8 @@ void Mouse_NewVideoMode(void) default: mouse.max_y=199; LOG(LOG_MOUSE,LOG_ERROR)("Unhandled videomode %X on reset",mode); + // Hide mouse cursor on non supported modi. + mouse.shown=-1; break; } mouse.max_x = 639; From 5baa46abfcfb0ff398aa6a60390b1469890e7b44 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Aug 2005 16:12:37 +0000 Subject: [PATCH 2183/4131] add patch "[ 1255540 ] Fixing undocumented VGA palette behavior" from vasyl. Fixes wari, but keeps star control 2 working Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2267 --- src/hardware/vga_dac.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index a8d0461c..98865c76 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -118,7 +118,7 @@ static void write_p3c9(Bitu port,Bitu val,Bitu iolen) { } } vga.dac.write_index++; - vga.dac.read_index = vga.dac.write_index - 1; +// vga.dac.read_index = vga.dac.write_index - 1;//disabled as it breaks Wari vga.dac.pel_index=0; break; default: @@ -141,7 +141,7 @@ static Bitu read_p3c9(Bitu port,Bitu iolen) { ret=vga.dac.rgb[vga.dac.read_index].blue; vga.dac.read_index++; vga.dac.pel_index=0; - vga.dac.write_index=vga.dac.read_index+1; +// vga.dac.write_index=vga.dac.read_index+1;//disabled as it breaks wari break; default: LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:DAC:Illegal Pel Index"); //If this can actually happen that will be the day From 15d976410b787b0678e3576e2fef5262afbc664d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Aug 2005 16:46:15 +0000 Subject: [PATCH 2184/4131] added simple variant of patch " [ 1239849 ] DOS 21H appends dir and driver name while accessing devices" from cyberwalker. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2268 --- src/dos/dos_files.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 1430adda..c386751b 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.63 2005-05-31 18:38:54 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.64 2005-08-10 16:46:15 qbix79 Exp $ */ #include #include @@ -404,21 +404,20 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { if (flags>2) LOG(LOG_FILES,LOG_ERROR)("Special file open command %X file %s",flags,name); else LOG(LOG_FILES,LOG_NORMAL)("file open command %X file %s",flags,name); + DOS_PSP psp(dos.psp()); Bit16u attr = 0; - if(DOS_GetFileAttr(name,&attr)){ //DON'T ALLOW directories to be openened + Bit8u devnum = DOS_FindDevice((char *)name); + bool device = (devnum != DOS_DEVICES); + if(!device && DOS_GetFileAttr(name,&attr)) { + //DON'T ALLOW directories to be openened.(skip test if file is device). if((attr & DOS_ATTR_DIRECTORY) || (attr & DOS_ATTR_VOLUME)){ DOS_SetError(DOSERR_ACCESS_DENIED); return false; } } - - DOS_PSP psp(dos.psp()); - Bit8u devnum=DOS_DEVICES; - devnum=DOS_FindDevice((char *)name); - bool device=(devnum!=DOS_DEVICES); + char fullname[DOS_PATHLENGTH];Bit8u drive;Bit8u i; - - /* First check if the name is correct */ + /* First check if the name is correct */ if (!DOS_MakeName(name,fullname,&drive)) return false; Bit8u handle=255; /* Check for a free file handle */ From dd14afd41eed48e756ab1f770601dc5154dcb186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 10 Aug 2005 19:53:11 +0000 Subject: [PATCH 2185/4131] load programs into upper memory (LH/LOADHIGH); fix tab completion Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2269 --- src/shell/shell_cmds.cpp | 14 ++++++++++++-- src/shell/shell_misc.cpp | 10 ++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 3fa83a94..920a0b21 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.55 2005-07-20 15:27:20 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.56 2005-08-10 19:53:09 c2woody Exp $ */ #include #include @@ -712,7 +712,17 @@ void DOS_Shell::CMD_SUBST (char * args) { } void DOS_Shell::CMD_LOADHIGH(char *args){ - this->ParseLine(args); + Bit16u umb_start=dos_infoblock.GetStartOfUMBChain(); + Bit8u umb_flag=dos_infoblock.GetUMBChainState(); + Bit8u old_memstrat=DOS_GetMemAllocStrategy()&0xff; + if (umb_start==0x9fff) { + if ((umb_flag&1)==0) DOS_LinkUMBsToMemChain(1); + DOS_SetMemAllocStrategy(0x80); // search in UMBs first + this->ParseLine(args); + Bit8u current_umb_flag=dos_infoblock.GetUMBChainState(); + if ((current_umb_flag&1)!=(umb_flag&1)) DOS_LinkUMBsToMemChain(umb_flag); + DOS_SetMemAllocStrategy(old_memstrat); // restore strategy + } else this->ParseLine(args); } void DOS_Shell::CMD_CHOICE(char * args){ diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index e87385e5..fd53c3ec 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.38 2005-04-21 21:17:46 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.39 2005-08-10 19:53:11 c2woody Exp $ */ #include #include @@ -226,8 +226,14 @@ void DOS_Shell::InputCommand(char * line) { char mask[DOS_PATHLENGTH]; if (completion_start) { strcpy(mask, completion_start); + char* dot_pos=strrchr(mask,'.'); + char* bs_pos=strrchr(mask,'\\'); + char* fs_pos=strrchr(mask,'/'); + char* cl_pos=strrchr(mask,':'); // not perfect when line already contains wildcards, but works - strcat(mask, "*.*"); + if ((dot_pos-bs_pos>0) && (dot_pos-fs_pos>0) && (dot_pos-cl_pos>0)) + strcat(mask, "*"); + else strcat(mask, "*.*"); } else { strcpy(mask, "*.*"); } From f9e7488309a33df24cf7d9b60de3c75c3f7e1fe6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Aug 2005 20:33:46 +0000 Subject: [PATCH 2186/4131] Fix a warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2270 --- src/cpu/paging.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 73fc2cc5..65f3d4ee 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -79,7 +79,7 @@ struct PF_Entry { }; #define PF_QUEUESIZE 16 -struct { +static struct { Bitu used; PF_Entry entries[PF_QUEUESIZE]; } pf_queue; From d0b017e5b30854a5b9bb817e888e44069001fce9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Aug 2005 20:36:36 +0000 Subject: [PATCH 2187/4131] Fix a few warnings. Reported by Xulchris Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2271 --- src/fpu/fpu.cpp | 4 ++-- src/gui/sdl_mapper.cpp | 4 ++-- src/hardware/iohandler.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 65428abf..05d41008 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu.cpp,v 1.25 2005-02-22 13:06:05 qbix79 Exp $ */ +/* $Id: fpu.cpp,v 1.26 2005-08-10 20:36:36 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU @@ -43,7 +43,7 @@ typedef PhysPt EAPoint; #include "fpu_types.h" -struct { +static struct { FPU_Reg regs[9]; FPU_P_Reg p_regs[9]; FPU_Tag tags[9]; diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index c82b2055..e27d3eeb 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.13 2005-07-19 19:45:31 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.14 2005-08-10 20:36:36 qbix79 Exp $ */ #define OLD_JOYSTICK 1 @@ -967,7 +967,7 @@ protected: }; -struct { +static struct { CCaptionButton * event_title; CCaptionButton * bind_title; CCaptionButton * selected; diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 7b10a4c5..b18a3571 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: iohandler.cpp,v 1.17 2005-03-25 11:52:32 qbix79 Exp $ */ +/* $Id: iohandler.cpp,v 1.18 2005-08-10 20:36:36 qbix79 Exp $ */ #include #include "dosbox.h" @@ -142,7 +142,7 @@ struct IOF_Entry { }; #define IOF_QUEUESIZE 16 -struct { +static struct { Bitu used; IOF_Entry entries[IOF_QUEUESIZE]; } iof_queue; From 31c4fe4ad9ba69ab1578ccf6a5a165cd89cbcb7d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 11 Aug 2005 18:56:57 +0000 Subject: [PATCH 2188/4131] make a memleak smaller Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2272 --- src/misc/programs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index e80580a2..0011a3b9 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.20 2005-07-20 12:00:45 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.21 2005-08-11 18:56:57 qbix79 Exp $ */ #include #include @@ -51,7 +51,7 @@ static Bit8u exe_block[]={ static std::vector internal_progs; void PROGRAMS_MakeFile(char * name,PROGRAMS_Main * main) { - Bit8u * comdata=(Bit8u *)malloc(128); + Bit8u * comdata=(Bit8u *)malloc(32); //MEM LEAK memcpy(comdata,&exe_block,sizeof(exe_block)); comdata[CB_POS]=call_program&0xff; comdata[CB_POS+1]=(call_program>>8)&0xff; From 8f74367940bb721dc3f33b3266b5bf17d89d9c57 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 11 Aug 2005 18:57:48 +0000 Subject: [PATCH 2189/4131] Fix some label issues with cdrom isos. Added some default labels on most stuff. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2273 --- src/dos/dos_programs.cpp | 12 +++++++++++- src/dos/drive_iso.cpp | 22 +++++++++++++++++----- src/dos/drive_local.cpp | 15 ++++++--------- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 668069c7..fc3fdd9c 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.39 2005-08-08 13:33:45 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.40 2005-08-11 18:57:48 qbix79 Exp $ */ #include #include @@ -191,6 +191,16 @@ public: WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,newdrive->GetInfo()); /* check if volume label is given and don't allow it to updated in the future */ if (cmd->FindString("-label",label,true)) newdrive->dirCache.SetLabel(label.c_str(),false); + /* For hard drives set the label to DRIVELETTER_Drive. + * For floppy drives set the label to DRIVELETTER_Floppy. + * This way every drive except cdroms should get a label.*/ + else if(type == "dir") { + label = drive; label += "_DRIVE"; + newdrive->dirCache.SetLabel(label.c_str(),true); + } else if(type == "floppy") { + label = drive; label += "_FLOPPY"; + newdrive->dirCache.SetLabel(label.c_str(),true); + } return; showusage: WriteOut(MSG_Get("PROGRAM_MOUNT_USAGE")); diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index abeda36a..95ea51d9 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.8 2005-07-19 19:45:31 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.9 2005-08-11 18:57:48 qbix79 Exp $ */ #include #include @@ -265,11 +265,23 @@ bool isoDrive::FindFirst(char *dir, DOS_DTA &dta, bool fcb_findfirst) Bit8u attr; char pattern[ISO_MAXPATHNAME]; dta.GetSearchParams(attr, pattern); - if ((attr & DOS_ATTR_VOLUME) && ((*dir == 0) || fcb_findfirst)) { - // Get Volume Label (DOS_ATTR_VOLUME) and only in basedir - dta.SetResult(discLabel, 0, 0, 0, DOS_ATTR_VOLUME); - return true; + + if (attr == DOS_ATTR_VOLUME) { + if (strlen(discLabel) != 0) { + dta.SetResult(discLabel, 0, 0, 0, DOS_ATTR_VOLUME); + return true; + } else { + DOS_SetError(DOSERR_NO_MORE_FILES); + return false; + } + } else if ((attr & DOS_ATTR_VOLUME) && (*dir == 0) && !fcb_findfirst) { + if (WildFileCmp(discLabel,pattern)) { + // Get Volume Label (DOS_ATTR_VOLUME) and only in basedir and if it matches the searchstring + dta.SetResult(discLabel, 0, 0, 0, DOS_ATTR_VOLUME); + return true; + } } + return FindNext(dta); } diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index abe736c0..8e6d144b 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.59 2005-07-15 15:23:22 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.60 2005-08-11 18:57:48 qbix79 Exp $ */ #include #include @@ -175,20 +175,17 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) { if (sAttr == DOS_ATTR_VOLUME) { if ( strcmp(dirCache.GetLabel(), "") == 0 ) { - LOG(LOG_DOSMISC,LOG_ERROR)("DRIVELABEL REQUESTED: none present, returned NOLABEL"); - dta.SetResult("NO_LABEL",0,0,0,DOS_ATTR_VOLUME); - return true; +// LOG(LOG_DOSMISC,LOG_ERROR)("DRIVELABEL REQUESTED: none present, returned NOLABEL"); +// dta.SetResult("NO_LABEL",0,0,0,DOS_ATTR_VOLUME); +// return true; + DOS_SetError(DOSERR_NO_MORE_FILES); + return false; } dta.SetResult(dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME); return true; } else if ((sAttr & DOS_ATTR_VOLUME) && (*_dir == 0) && !fcb_findfirst) { //should check for a valid leading directory instead of 0 //exists==true if the volume label matches the searchmask and the path is valid - if ( strcmp(dirCache.GetLabel(), "") == 0 ) { - LOG(LOG_DOSMISC,LOG_ERROR)("DRIVELABEL REQUESTED: none present, returned NOLABEL"); - dta.SetResult("NO_LABEL",0,0,0,DOS_ATTR_VOLUME); - return true; - } if (WildFileCmp(dirCache.GetLabel(),tempDir)) { dta.SetResult(dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME); return true; From 85850ccc227f46141479fe82ca706bfa738b91bc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 11 Aug 2005 18:58:39 +0000 Subject: [PATCH 2190/4131] apply patch: "[ 1256405 ] EGA/VGA data should be rotated only in write mode 0" from vasyl. Fixes overkill Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2274 --- src/hardware/vga_memory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 4af354d5..a3af1e60 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -61,6 +61,7 @@ INLINE static Bit32u ModeOperation(Bit8u val) { switch (vga.config.write_mode) { case 0x00: // Write Mode 0: In this mode, the host data is first rotated as per the Rotate Count field, then the Enable Set/Reset mechanism selects data from this or the Set/Reset field. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory. + val=((val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate))); full=ExpandTable[val]; full=(full & vga.config.full_not_enable_set_reset) | vga.config.full_enable_and_set_reset; full=RasterOp(full,vga.config.full_bit_mask); @@ -84,7 +85,6 @@ INLINE static Bit32u ModeOperation(Bit8u val) { } static void VGA_GFX_16_WriteHandler(PhysPt start,Bit8u val) { - val=((val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate))); Bit32u data=ModeOperation(val); /* Update video memory and the pixel buffer */ VGA_Latch pixels; From b48eceebe77299c80274fbb326e4eea0127dfe4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 15 Aug 2005 13:43:44 +0000 Subject: [PATCH 2191/4131] cpu updates (privileged instructions, trapflag handling) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2275 --- include/cpu.h | 46 +- src/cpu/core_full/load.h | 8 +- src/cpu/core_full/op.h | 18 +- src/cpu/core_full/optable.h | 4 +- src/cpu/core_full/support.h | 2 +- src/cpu/core_normal.cpp | 3 +- src/cpu/core_normal/prefix_0f.h | 72 +- src/cpu/core_normal/prefix_66.h | 30 +- src/cpu/core_normal/prefix_66_0f.h | 36 +- src/cpu/core_normal/prefix_none.h | 46 +- src/cpu/cpu.cpp | 1182 +++++++++++++++++++++++++++- src/ints/ems.cpp | 14 +- 12 files changed, 1352 insertions(+), 109 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 01783145..d1736b45 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -49,8 +49,8 @@ Bits CPU_Core_Dyn_X86_Run(void); extern Bit16u parity_lookup[256]; -void CPU_LLDT(Bitu selector); -void CPU_LTR(Bitu selector); +bool CPU_LLDT(Bitu selector); +bool CPU_LTR(Bitu selector); void CPU_LIDT(Bitu limit,Bitu base); void CPU_LGDT(Bitu limit,Bitu base); @@ -68,6 +68,9 @@ 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); + void CPU_SMSW(Bitu & word); Bitu CPU_LMSW(Bitu word); @@ -93,6 +96,7 @@ 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); INLINE void CPU_HW_Interrupt(Bitu num) { @@ -101,6 +105,9 @@ INLINE void CPU_HW_Interrupt(Bitu num) { INLINE void CPU_SW_Interrupt(Bitu num,Bitu oldeip) { CPU_Interrupt(num,CPU_INT_SOFTWARE,oldeip); } +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); @@ -116,18 +123,25 @@ void CPU_Push32(Bitu value); void CPU_SetFlags(Bitu word,Bitu mask); + +#define EXCEPTION_UD 6 +#define EXCEPTION_TS 10 +#define EXCEPTION_NP 11 +#define EXCEPTION_SS 12 +#define EXCEPTION_GP 13 + +#define CR0_PROTECTION 0x00000001 +#define CR0_MONITORPROCESSOR 0x00000002 +#define CR0_FPUEMULATION 0x00000004 +#define CR0_TASKSWITCH 0x00000008 +#define CR0_FPUPRESENT 0x00000010 +#define CR0_PAGING 0x80000000 + + // ********************************************************************* // Descriptor // ********************************************************************* -#define CR0_PROTECTION 0x00000001 -#define CR0_FPUENABLED 0x00000002 -#define CR0_FPUMONITOR 0x00000004 -#define CR0_TASKSWITCH 0x00000008 -#define CR0_FPUPRESENT 0x00000010 -#define CR0_PAGING 0x80000000 - - #define DESC_INVALID 0x00 #define DESC_286_TSS_A 0x01 #define DESC_LDT 0x02 @@ -360,9 +374,16 @@ public: return ldt_value; } bool LLDT(Bitu value) { -//TODO checking + if ((value&0xfffc)==0) { + ldt_value=0; + ldt_base=0; + ldt_limit=0; + return true; + } Descriptor desc; - GetDescriptor(value,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; @@ -410,6 +431,7 @@ struct CPUBlock { Bitu which,error; } exception; Bits direction; + Bit32u drx[8]; }; extern CPUBlock cpu; diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 37d1e67d..ce95ddcc 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -472,12 +472,18 @@ l_M_Ed: CPU_CPUID(); goto nextopcode; case D_HLT: + if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); FillFlags(); CPU_HLT(GetIP()); return CBRET_NONE; case D_CLTS: - //TODO Really clear it sometime + if (cpu.pmode && cpu.cpl) goto illegalopcode; + cpu.cr0&=(~CR0_TASKSWITCH); goto nextopcode; + case D_ICEBP: + FillFlags(); + CPU_SW_Interrupt_NoIOPLCheck(1,GetIP()); + continue; default: LOG(LOG_CPU,LOG_ERROR)("LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry); goto illegalopcode; diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 410db642..4432c5e2 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -376,6 +376,7 @@ switch (inst.code.op) { return inst.op1.d; case O_GRP6w: case O_GRP6d: + if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode; switch (inst.rm_index) { case 0x00: /* SLDT */ { @@ -392,10 +393,12 @@ switch (inst.code.op) { } break; case 0x02: /* LLDT */ - CPU_LLDT(inst.op1.d); + if (cpu.cpl) EXCEPTION(EXCEPTION_GP); + if (CPU_LLDT(inst.op1.d)) RunException(); goto nextopcode; /* Else value will saved */ case 0x03: /* LTR */ - CPU_LTR(inst.op1.d); + if (cpu.cpl) EXCEPTION(EXCEPTION_GP); + if (CPU_LTR(inst.op1.d)) RunException(); goto nextopcode; /* Else value will saved */ case 0x04: /* VERR */ FillFlags(); @@ -407,6 +410,7 @@ switch (inst.code.op) { goto nextopcode; /* Else value will saved */ default: LOG(LOG_CPU,LOG_ERROR)("Group 6 Illegal subfunction %X",inst.rm_index); + goto illegalopcode; } break; case O_GRP7w: @@ -429,9 +433,11 @@ switch (inst.code.op) { goto nextopcode; } case 2: /* LGDT */ + if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); CPU_LGDT(LoadMw(inst.rm_eaa),LoadMd(inst.rm_eaa+2)&((inst.code.op == O_GRP7w) ? 0xFFFFFF : 0xFFFFFFFF)); goto nextopcode; case 3: /* LIDT */ + if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); CPU_LIDT(LoadMw(inst.rm_eaa),LoadMd(inst.rm_eaa+2)&((inst.code.op == O_GRP7w) ? 0xFFFFFF : 0xFFFFFFFF)); goto nextopcode; case 4: /* SMSW */ @@ -446,6 +452,7 @@ switch (inst.code.op) { goto nextopcode; default: LOG(LOG_CPU,LOG_ERROR)("Group 7 Illegal subfunction %X",inst.rm_index); + goto illegalopcode; } break; case O_M_CRx_Rd: @@ -455,14 +462,14 @@ switch (inst.code.op) { if (CPU_READ_CRX(inst.rm_index,inst.op1.d)) RunException(); break; case O_M_DRx_Rd: -// LOG(LOG_CPU,LOG_NORMAL)("MOV DR%d,%X",inst.rm_index,inst.op1.d); + if (CPU_WRITE_DRX(inst.rm_index,inst.op1.d)) RunException(); break; case O_M_Rd_DRx: - inst.op1.d=0; -// LOG(LOG_CPU,LOG_NORMAL)("MOV %X,DR%d",inst.op1.d,inst.rm_index); + if (CPU_READ_DRX(inst.rm_index,inst.op1.d)) RunException(); break; case O_LAR: { + if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode; FillFlags(); Bitu ar=inst.op2.d; CPU_LAR(inst.op1.w,ar); @@ -471,6 +478,7 @@ switch (inst.code.op) { break; case O_LSL: { + if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode; FillFlags(); Bitu limit=inst.op2.d; CPU_LSL(inst.op1.w,limit); diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 683ec41e..cf119948 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -171,7 +171,7 @@ static OpCode OpCodeTable[1024]={ {L_REGw ,O_OUTb ,0 ,REGI_DX},{L_REGw ,O_OUTw ,0 ,REGI_DX}, /* 0xf0 - 0xf7 */ -{D_LOCK ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{D_LOCK ,0 ,0 ,0 },{D_ICEBP ,0 ,0 ,0 }, {L_PREREPNE ,0 ,0 ,0 },{L_PREREP ,0 ,0 ,0 }, {D_HLT ,0 ,0 ,0 },{D_CMC ,0 ,0 ,0 }, {L_MODRM ,8 ,0 ,M_GRP },{L_MODRM ,9 ,0 ,M_GRP }, @@ -526,7 +526,7 @@ static OpCode OpCodeTable[1024]={ {L_REGw ,O_OUTb ,0 ,REGI_DX},{L_REGw ,O_OUTd ,0 ,REGI_DX}, /* 0x2f0 - 0x2f7 */ -{D_LOCK ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{D_LOCK ,0 ,0 ,0 },{D_ICEBP ,0 ,0 ,0 }, {L_PREREPNE ,0 ,0 ,0 },{L_PREREP ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{D_CMC ,0 ,0 ,0 }, {L_MODRM ,8 ,0 ,M_GRP },{L_MODRM ,0xa ,0 ,M_GRP }, diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 5521daae..21561c77 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -45,7 +45,7 @@ enum { D_SAHF,D_LAHF, D_CPUID, D_HLT,D_CLTS, - D_LOCK, + D_LOCK,D_ICEBP, L_ERROR, }; diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 0ccfd14e..0588928f 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -188,13 +188,12 @@ decode_end: } Bits CPU_Core_Normal_Trap_Run(void) { - Bits oldCycles = CPU_Cycles; CPU_Cycles = 1; core.trap.skip=false; Bits ret=CPU_Core_Normal_Run(); - if (!core.trap.skip) CPU_SW_Interrupt(1,reg_eip); + if (!core.trap.skip) CPU_HW_Interrupt(1); CPU_Cycles = oldCycles-1; cpudecoder = &CPU_Core_Normal_Run; diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 4b5103cf..749e3d27 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -18,6 +18,7 @@ CASE_0F_W(0x00) /* GRP 6 Exxx */ { + if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; GetRM;Bitu which=(rm>>3)&7; switch (which) { case 0x00: /* SLDT */ @@ -37,10 +38,20 @@ if (rm >= 0xc0 ) {GetEArw;loadval=*earw;} else {GetEAa;loadval=LoadMw(eaa);} switch (which) { - case 0x02:CPU_LLDT(loadval);break; - case 0x03:CPU_LTR(loadval);break; - case 0x04:CPU_VERR(loadval);break; - case 0x05:CPU_VERW(loadval);break; + case 0x02: + if (cpu.cpl) EXCEPTION(EXCEPTION_GP); + if (CPU_LLDT(loadval)) RUNEXCEPTION(); + break; + case 0x03: + if (cpu.cpl) EXCEPTION(EXCEPTION_GP); + if (CPU_LTR(loadval)) RUNEXCEPTION(); + break; + case 0x04: + CPU_VERR(loadval); + break; + case 0x05: + CPU_VERW(loadval); + break; } } break; @@ -66,9 +77,11 @@ SaveMd(eaa+2,base); break; case 0x02: /* LGDT */ + if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF); break; case 0x03: /* LIDT */ + if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF); break; case 0x04: /* SMSW */ @@ -83,6 +96,12 @@ } else { GetEArw;Bitu limit; switch (which) { + case 0x02: /* LGDT */ + if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); + goto illegal_opcode; + case 0x03: /* LIDT */ + if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); + goto illegal_opcode; case 0x04: /* SMSW */ CPU_SMSW(limit); *earw=limit; @@ -98,6 +117,7 @@ break; CASE_0F_W(0x02) /* LAR Gw,Ew */ { + if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; FillFlags(); GetRMrw;Bitu ar=*rmrw; if (rm >= 0xc0) { @@ -110,6 +130,7 @@ break; CASE_0F_W(0x03) /* LSL Gw,Ew */ { + if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; FillFlags(); GetRMrw;Bitu limit=*rmrw; if (rm >= 0xc0) { @@ -121,54 +142,59 @@ } break; CASE_0F_B(0x06) /* CLTS */ + if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); + cpu.cr0&=(~CR0_TASKSWITCH); break; CASE_0F_B(0x20) /* MOV Rd.CRx */ { GetRM; Bitu which=(rm >> 3) & 7; - if (rm >= 0xc0 ) { - GetEArd; - Bit32u crx_value; - if (CPU_READ_CRX(which,crx_value)) RUNEXCEPTION(); - *eard=crx_value; - } else { - GetEAa; + if (rm < 0xc0 ) { + rm |= 0xc0; LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%d with non-register",which); } + GetEArd; + Bit32u crx_value; + if (CPU_READ_CRX(which,crx_value)) RUNEXCEPTION(); + *eard=crx_value; } break; CASE_0F_B(0x21) /* MOV Rd,DRx */ { GetRM; Bitu which=(rm >> 3) & 7; - if (rm >= 0xc0 ) { - GetEArd; - } else { - GetEAa; + if (rm < 0xc0 ) { + rm |= 0xc0; LOG(LOG_CPU,LOG_ERROR)("MOV XXX,DR% with non-register",which); } + GetEArd; + Bit32u drx_value; + if (CPU_READ_DRX(which,drx_value)) RUNEXCEPTION(); + *eard=drx_value; } break; CASE_0F_B(0x22) /* MOV CRx,Rd */ { GetRM; Bitu which=(rm >> 3) & 7; - if (rm >= 0xc0 ) { - GetEArd; - if (CPU_WRITE_CRX(which,*eard)) RUNEXCEPTION(); - } else goto illegal_opcode; + if (rm < 0xc0 ) { + rm |= 0xc0; + LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR% with non-register",which); + } + GetEArd; + if (CPU_WRITE_CRX(which,*eard)) RUNEXCEPTION(); } break; CASE_0F_B(0x23) /* MOV DRx,Rd */ { GetRM; Bitu which=(rm >> 3) & 7; - if (rm >= 0xc0 ) { - GetEArd; - } else { - GetEAa; + if (rm < 0xc0 ) { + rm |= 0xc0; LOG(LOG_CPU,LOG_ERROR)("MOV DR%,XXX with non-register",which); } + GetEArd; + if (CPU_WRITE_DRX(which,*eard)) RUNEXCEPTION(); } break; CASE_0F_W(0x80) /* JO */ diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index a6bfa76e..aa560535 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -331,8 +331,8 @@ case 0x05: /* MOV Ew,GS */ val=SegValue(gs);break; default: - val=0; - E_Exit("CPU:8c:Illegal RM Byte"); + LOG(LOG_CPU,LOG_ERROR)("CPU:8c:Illegal RM Byte"); + goto illegal_opcode; } if (rm >= 0xc0 ) {GetEArd;*eard=val;} else {GetEAa;SaveMw(eaa,val);} @@ -389,6 +389,12 @@ Bit32u newip=Fetchd();Bit16u newcs=Fetchw(); FillFlags(); CPU_CALL(true,newcs,newip,GETIP); +#if CPU_TRAP_CHECK + if (GETFLAG(TF)) { + cpudecoder=CPU_Core_Normal_Trap_Run; + return CBRET_NONE; + } +#endif continue; } CASE_D(0x9c) /* PUSHFD */ @@ -581,6 +587,12 @@ Bit16u newcs=Fetchw(); FillFlags(); CPU_JMP(true,newcs,newip,GETIP); +#if CPU_TRAP_CHECK + if (GETFLAG(TF)) { + cpudecoder=CPU_Core_Normal_Trap_Run; + return CBRET_NONE; + } +#endif continue; } CASE_D(0xeb) /* JMP Jb */ @@ -657,11 +669,18 @@ continue; case 0x03: /* CALL FAR Ed */ { + if (rm >= 0xc0) goto illegal_opcode; GetEAa; Bit32u newip=LoadMd(eaa); Bit16u newcs=LoadMw(eaa+4); FillFlags(); CPU_CALL(true,newcs,newip,GETIP); +#if CPU_TRAP_CHECK + if (GETFLAG(TF)) { + cpudecoder=CPU_Core_Normal_Trap_Run; + return CBRET_NONE; + } +#endif continue; } case 0x04: /* JMP NEAR Ed */ @@ -670,11 +689,18 @@ continue; case 0x05: /* JMP FAR Ed */ { + if (rm >= 0xc0) goto illegal_opcode; GetEAa; Bit32u newip=LoadMd(eaa); Bit16u newcs=LoadMw(eaa+4); FillFlags(); CPU_JMP(true,newcs,newip,GETIP); +#if CPU_TRAP_CHECK + if (GETFLAG(TF)) { + cpudecoder=CPU_Core_Normal_Trap_Run; + return CBRET_NONE; + } +#endif continue; } break; diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index d7ad2386..224c82a1 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -15,8 +15,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + CASE_0F_D(0x00) /* GRP 6 Exxx */ { + if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; GetRM;Bitu which=(rm>>3)&7; switch (which) { case 0x00: /* SLDT */ @@ -37,15 +39,26 @@ if (rm >= 0xc0 ) {GetEArw;loadval=*earw;} else {GetEAa;loadval=LoadMw(eaa);} switch (which) { - case 0x02:CPU_LLDT(loadval);break; - case 0x03:CPU_LTR(loadval);break; - case 0x04:CPU_VERR(loadval);break; - case 0x05:CPU_VERW(loadval);break; + case 0x02: + if (cpu.cpl) EXCEPTION(EXCEPTION_GP); + if (CPU_LLDT(loadval)) RUNEXCEPTION(); + break; + case 0x03: + if (cpu.cpl) EXCEPTION(EXCEPTION_GP); + if (CPU_LTR(loadval)) RUNEXCEPTION(); + break; + case 0x04: + CPU_VERR(loadval); + break; + case 0x05: + CPU_VERW(loadval); + break; } } break; default: LOG(LOG_CPU,LOG_ERROR)("GRP6:Illegal call %2X",which); + goto illegal_opcode; } } break; @@ -66,9 +79,11 @@ SaveMd(eaa+2,(Bit32u)base); break; case 0x02: /* LGDT */ + if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2)); break; case 0x03: /* LIDT */ + if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2)); break; case 0x04: /* SMSW */ @@ -77,21 +92,28 @@ break; case 0x06: /* LMSW */ limit=LoadMw(eaa); - if (!CPU_LMSW((Bit16u)limit)) goto decode_end; + if (CPU_LMSW((Bit16u)limit)) RUNEXCEPTION(); break; } } else { GetEArd;Bitu limit; switch (which) { + case 0x02: /* LGDT */ + if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); + goto illegal_opcode; + case 0x03: /* LIDT */ + if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); + goto illegal_opcode; case 0x04: /* SMSW */ CPU_SMSW(limit); *eard=(Bit32u)limit; break; case 0x06: /* LMSW */ - if (!CPU_LMSW(*eard)) goto decode_end; + if (CPU_LMSW(*eard)) RUNEXCEPTION(); break; default: LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which); + goto illegal_opcode; break; } @@ -100,6 +122,7 @@ break; CASE_0F_D(0x02) /* LAR Gd,Ed */ { + if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; FillFlags(); GetRMrd;Bitu ar=*rmrd; if (rm >= 0xc0) { @@ -112,6 +135,7 @@ break; CASE_0F_D(0x03) /* LSL Gd,Ew */ { + if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; FillFlags(); GetRMrd;Bitu limit=*rmrd; /* Just load 16-bit values for selectors */ diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 3cde3a1d..81e2c7b3 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -472,8 +472,8 @@ case 0x05: /* MOV Ew,GS */ val=SegValue(gs);break; default: - val=0; - E_Exit("CPU:8c:Illegal RM Byte"); + LOG(LOG_CPU,LOG_ERROR)("CPU:8c:Illegal RM Byte"); + goto illegal_opcode; } if (rm >= 0xc0 ) {GetEArw;*earw=val;} else {GetEAa;SaveMw(eaa,val);} @@ -551,6 +551,12 @@ FillFlags(); Bit16u newip=Fetchw();Bit16u newcs=Fetchw(); CPU_CALL(false,newcs,newip,GETIP); +#if CPU_TRAP_CHECK + if (GETFLAG(TF)) { + cpudecoder=CPU_Core_Normal_Trap_Run; + return CBRET_NONE; + } +#endif continue; } CASE_B(0x9b) /* WAIT */ @@ -727,7 +733,7 @@ if (DEBUG_Breakpoint()) return debugCallback; #endif - CPU_SW_Interrupt(3,GETIP); + CPU_SW_Interrupt_NoIOPLCheck(3,GETIP); #if CPU_TRAP_CHECK core.trap.skip=true; #endif @@ -761,14 +767,14 @@ { FillFlags(); CPU_IRET(false,GETIP); -#if CPU_PIC_CHECK - if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; -#endif #if CPU_TRAP_CHECK if (GETFLAG(TF)) { cpudecoder=CPU_Core_Normal_Trap_Run; return CBRET_NONE; } +#endif +#if CPU_PIC_CHECK + if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; #endif continue; } @@ -900,6 +906,12 @@ Bit16u newcs=Fetchw(); FillFlags(); CPU_JMP(false,newcs,newip,GETIP); +#if CPU_TRAP_CHECK + if (GETFLAG(TF)) { + cpudecoder=CPU_Core_Normal_Trap_Run; + return CBRET_NONE; + } +#endif continue; } CASE_W(0xeb) /* JMP Jb */ @@ -928,6 +940,13 @@ CASE_B(0xf0) /* LOCK */ LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK"); /* FIXME: see case D_LOCK in core_full/load.h */ break; + CASE_B(0xf1) /* ICEBP */ + FillFlags(); + CPU_SW_Interrupt_NoIOPLCheck(1,GETIP); +#if CPU_TRAP_CHECK + core.trap.skip=true; +#endif + continue; CASE_B(0xf2) /* REPNZ */ DO_PREFIX_REP(false); break; @@ -935,6 +954,7 @@ DO_PREFIX_REP(true); break; CASE_B(0xf4) /* HLT */ + if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); FillFlags(); CPU_HLT(GETIP); return CBRET_NONE; //Needs to return for hlt cpu core @@ -1094,11 +1114,18 @@ continue; case 0x03: /* CALL Ep */ { + if (rm >= 0xc0) goto illegal_opcode; GetEAa; Bit16u newip=LoadMw(eaa); Bit16u newcs=LoadMw(eaa+2); FillFlags(); CPU_CALL(false,newcs,newip,GETIP); +#if CPU_TRAP_CHECK + if (GETFLAG(TF)) { + cpudecoder=CPU_Core_Normal_Trap_Run; + return CBRET_NONE; + } +#endif continue; } break; @@ -1108,11 +1135,18 @@ continue; case 0x05: /* JMP Ep */ { + if (rm >= 0xc0) goto illegal_opcode; GetEAa; Bit16u newip=LoadMw(eaa); Bit16u newcs=LoadMw(eaa+2); FillFlags(); CPU_JMP(false,newcs,newip,GETIP); +#if CPU_TRAP_CHECK + if (GETFLAG(TF)) { + cpudecoder=CPU_Core_Normal_Trap_Run; + return CBRET_NONE; + } +#endif continue; } break; diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index b3fb3b44..d8628853 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.72 2005-07-09 13:07:48 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.73 2005-08-15 13:43:44 c2woody Exp $ */ #include #include "dosbox.h" @@ -52,13 +52,6 @@ void CPU_Core_Simple_Init(void); void CPU_Core_Dyn_X86_Init(void); -#define EXCEPTION_UD 6 -#define EXCEPTION_TS 10 -#define EXCEPTION_NP 11 -#define EXCEPTION_SS 12 -#define EXCEPTION_GP 13 - - /* In debug mode exceptions are tested and dosbox exits when * a unhandled exception state is detected. * USE CHECK_EXCEPT to raise an exception in that case to see if that exception @@ -211,16 +204,24 @@ public: } bool SetSelector(Bitu new_sel) { valid=false; - selector=new_sel; - if (!cpu.gdt.GetDescriptor(selector,desc)) return false; + if ((new_sel & 0xfffc)==0) { + selector=0; + base=0; + limit=0; + is386=1; + return true; + } + if (new_sel&4) return false; + if (!cpu.gdt.GetDescriptor(new_sel,desc)) return false; switch (desc.Type()) { case DESC_286_TSS_A: case DESC_286_TSS_B: case DESC_386_TSS_A: case DESC_386_TSS_B: break; default: - valid=false; return false; } + if (!desc.saved.seg.p) return false; + selector=new_sel; valid=true; base=desc.GetBase(); limit=desc.GetLimit(); @@ -244,16 +245,14 @@ enum TSwitchType { bool CPU_SwitchTask(Bitu new_tss_selector,TSwitchType tstype,Bitu old_eip) { TaskStateSegment new_tss; if (!new_tss.SetSelector(new_tss_selector)) - E_Exit("Illegal TSS for switch"); + E_Exit("Illegal TSS for switch, selector=%x, switchtype=%x",new_tss_selector,tstype); if (tstype==TSwitch_IRET) { - if (!cpu_tss.desc.IsBusy()) + if (!new_tss.desc.IsBusy()) E_Exit("TSS not busy for IRET"); } else { if (new_tss.desc.IsBusy()) E_Exit("TSS busy for JMP/CALL/INT"); } - if (!new_tss.desc.saved.seg.p) - E_Exit("TSS not present for switch"); Bitu new_cr3=0; Bitu new_eax,new_ebx,new_ecx,new_edx,new_esp,new_ebp,new_esi,new_edi; Bitu new_es,new_cs,new_ss,new_ds,new_fs,new_gs; @@ -401,7 +400,8 @@ doconforming: CPU_SetSegGeneral(ds,new_ds); CPU_SetSegGeneral(fs,new_fs); CPU_SetSegGeneral(gs,new_gs); - CPU_LTR(new_tss_selector); + if (!cpu_tss.SetSelector(new_tss_selector)) LOG(LOG_CPU,LOG_NORMAL)("TaskSwitch: set tss selector %X failed",new_tss_selector); + cpu_tss.desc.SetBusy(true); // LOG_MSG("Task CPL %X CS:%X IP:%X SS:%X SP:%X eflags %x",cpu.cpl,SegValue(cs),reg_eip,SegValue(ss),reg_esp,reg_flags); return true; } @@ -429,9 +429,1037 @@ void CPU_Exception(Bitu which,Bitu error ) { CPU_Interrupt(which,CPU_INT_EXCEPTION | ((which>=8) ? CPU_INT_HAS_ERROR : 0),reg_eip); } +const char* translateVXDid(Bitu nr) { + switch (nr) { + case 0x0001: return "VMM"; // Virtual Machine Manager + case 0x0002: return "DEBUG"; + case 0x0003: return "VPICD"; // Virtual PIC Device + case 0x0004: return "VDMAD"; // Virtual DMA Device + case 0x0005: return "VTD"; // Virtual Timer Device + case 0x0006: return "V86MMGR"; // Virtual Device + case 0x0007: return "PageSwap"; + case 0x000A: return "VDD"; // Virtual Display Device + case 0x000C: return "VMD"; // Virtual Mouse Device + case 0x000D: return "VKD"; // Virtual Keyboard Device + case 0x000E: return "VCD"; // Virtual COMM Device + case 0x0010: return "IOS"; // BlockDev / IOS + case 0x0011: return "VMCPD"; + case 0x0012: return "EBIOS"; + case 0x0015: return "DOSMGR"; + case 0x0017: return "SHELL"; + case 0x0018: return "VMPoll"; + case 0x001A: return "DOSNET"; + case 0x001B: return "VFD"; + case 0x001C: return "LoadHi"; + case 0x0020: return "Int13"; + case 0x0021: return "PAGEFILE"; + case 0x0026: return "VPOWERD"; + case 0x0027: return "VXDLDR"; + case 0x002A: return "VWIN32"; + case 0x002B: return "VCOMM"; + case 0x0033: return "CONFIGMG"; + case 0x0036: return "VFBACKUP"; + case 0x0037: return "VMINI"; + case 0x0040: return "IFSMgr"; + case 0x0041: return "VCDFSD"; + case 0x0048: return "PERF"; + case 0x011F: return "VFLATD"; + case 0x0446: return "VADLIB"; + case 0x044a: return "mmdevldr"; + case 0x0484: return "IfsMgr"; + case 0x048B: return "VCACHE"; + case 0x357E: return "DSOUND"; + default: + return "unknown"; + } +} + +const char* translateVXDservice(Bitu nr, Bitu sv) { + switch (nr) { + case 0x0001: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "get current VM handle"; + case 0x0002 : return "test current VM handle"; + case 0x0003 : return "get system VM handle"; + case 0x0004 : return "test system VM handle"; + case 0x0005 : return "validate VM handle"; + case 0x0006 : return "get VMM reenter count"; + case 0x0007 : return "begin reentrant execution"; + case 0x0008 : return "end reentrant execution"; + case 0x0009 : return "install V86 breakpoint"; + case 0x000A : return "remove V86 breakpoint"; + case 0x000B : return "allocate V86 callback"; + case 0x000C : return "allocation PM callback"; + case 0x000D : return "call when VM returns"; + case 0x000E : return "schedule global event"; + case 0x000F : return "schedule VM event"; + case 0x0010 : return "call global event"; + case 0x0011 : return "call VM event"; + case 0x0012 : return "cancel global event"; + case 0x0013 : return "cancel VM event"; + case 0x0014 : return "call priority VM event"; + case 0x0015 : return "cancel priority VM event"; + case 0x0016 : return "get NMI handler address"; + case 0x0017 : return "set NMI handler address"; + case 0x0018 : return "hook NMI event"; + case 0x0019 : return "call when VM interrupts enabled"; + case 0x001A : return "enable VM interrupts"; + case 0x001B : return "disable VM interrupts"; + case 0x001C : return "map flat"; + case 0x001D : return "map linear to VM address"; + case 0x001E : return "adjust execution priority"; + case 0x001F : return "begin critical section"; + case 0x0020 : return "end critical section"; + case 0x0021 : return "end critical section and suspend"; + case 0x0022 : return "claim critical section"; + case 0x0023 : return "release critical section"; + case 0x0024 : return "call when not critical"; + case 0x0025 : return "create semaphore"; + case 0x0026 : return "destroy semaphore"; + case 0x0027 : return "wait on semaphore"; + case 0x0028 : return "signal semaphore"; + case 0x0029 : return "get critical section status"; + case 0x002A : return "call when task switched"; + case 0x002B : return "suspend VM"; + case 0x002C : return "resume VM"; + case 0x002D : return "no-fail resume VM"; + case 0x002E : return "nuke VM"; + case 0x002F : return "crash current VM"; + case 0x0030 : return "get execution focus"; + case 0x0031 : return "set execution focus"; + case 0x0032 : return "get time slice priority"; + case 0x0033 : return "set time slice priority"; + case 0x0034 : return "get time slice granularity"; + case 0x0035 : return "set time slice granularity"; + case 0x0036 : return "get time slice information"; + case 0x0037 : return "adjust execution time"; + case 0x0038 : return "release time slice"; + case 0x0039 : return "wake up VM"; + case 0x003A : return "call when idle"; + case 0x003B : return "get next VM handle"; + case 0x003C : return "set global timeout"; + case 0x003D : return "set VM timeout"; + case 0x003E : return "cancel timeout"; + case 0x003F : return "get system time"; + case 0x0040 : return "get VM execution time"; + case 0x0041 : return "hook V86 interrupt chain"; + case 0x0042 : return "get V86 interrupt vector"; + case 0x0043 : return "set V86 interrupt vector"; + case 0x0044 : return "get PM interrupt vector"; + case 0x0045 : return "set PM interrupt vector"; + case 0x0046 : return "simulate interrupt"; + case 0x0047 : return "simulate IRET"; + case 0x0048 : return "simulate far call"; + case 0x0049 : return "simulate far jump"; + case 0x004A : return "simulate far RET"; + case 0x004B : return "simulate far RET N"; + case 0x004C : return "build interrupt stack frame"; + case 0x004D : return "simulate push"; + case 0x004E : return "simulate pop"; + case 0x004F : return "_HeapAllocate"; + case 0x0050 : return "_HeapReAllocate"; + case 0x0051 : return "_HeapFree"; + case 0x0052 : return "_HeapGetSize"; + case 0x0053 : return "_PageAllocate"; + case 0x0054 : return "_PageReAllocate"; + case 0x0055 : return "_PageFree"; + case 0x0056 : return "_PageLock"; + case 0x0057 : return "_PageUnLock"; + case 0x0058 : return "_PageGetSizeAddr"; + case 0x0059 : return "_PageGetAllocInfo"; + case 0x005A : return "_GetFreePageCount"; + case 0x005B : return "_GetSysPageCount"; + case 0x005C : return "_GetVMPgCount"; + case 0x005D : return "_MapIntoV86"; + case 0x005E : return "_PhysIntoV86"; + case 0x005F : return "_TestGlobalV86Mem"; + case 0x0060 : return "_ModifyPageBits"; + case 0x0061 : return "copy page table"; + case 0x0062 : return "map linear into V86"; + case 0x0063 : return "linear page lock"; + case 0x0064 : return "linear page unlock"; + case 0x0065 : return "_SetResetV86Pageabl"; + case 0x0066 : return "_GetV86PageableArray"; + case 0x0067 : return "_PageCheckLinRange"; + case 0x0068 : return "page out dirty pages"; + case 0x0069 : return "discard pages"; + case 0x006A : return "_GetNulPageHandle"; + case 0x006B : return "get first V86 page"; + case 0x006C : return "map physical address to linear address"; + case 0x006D : return "_GetAppFlatDSAlias"; + case 0x006E : return "_SelectorMapFlat"; + case 0x006F : return "_GetDemandPageInfo"; + case 0x0070 : return "_GetSetPageOutCount"; + case 0x0071 : return "hook V86 page"; + case 0x0072 : return "assign device V86 pages"; + case 0x0073 : return "deassign device V86 pages"; + case 0x0074 : return "get array of V86 pages for device"; + case 0x0075 : return "_SetNULPageAddr"; + case 0x0076 : return "allocate GDT selector"; + case 0x0077 : return "free GDT selector"; + case 0x0078 : return "allocate LDT selector"; + case 0x0079 : return "free LDT selector"; + case 0x007A : return "_BuildDescriptorDWORDs"; + case 0x007B : return "get descriptor"; + case 0x007C : return "set descriptor"; + case 0x007D : return "toggle HMA"; + case 0x007E : return "get fault hook addresses"; + case 0x007F : return "hook V86 fault"; + case 0x0080 : return "hook PM fault"; + case 0x0081 : return "hook VMM fault"; + case 0x0082 : return "begin nested V86 execution"; + case 0x0083 : return "begin nested execution"; + case 0x0084 : return "execute V86-mode interrupt"; + case 0x0085 : return "resume execution"; + case 0x0086 : return "end nested execution"; + case 0x0087 : return "allocate PM application callback area"; + case 0x0088 : return "get current PM application callback area"; + case 0x0089 : return "set V86 execution mode"; + case 0x008A : return "set PM execution mode"; + case 0x008B : return "begin using locked PM stack"; + case 0x008C : return "end using locked PM stack"; + case 0x008D : return "save client state"; + case 0x008E : return "restore client state"; + case 0x008F : return "execute VxD interrupt"; + case 0x0090 : return "hook device service"; + case 0x0091 : return "hook device V86 API"; + case 0x0092 : return "hook device PM API"; + case 0x0093 : return "system control (see also #02657)"; + case 0x0094 : return "simulate I/O"; + case 0x0095 : return "install multiple I/O handlers"; + case 0x0096 : return "install I/O handler"; + case 0x0097 : return "enable global trapping"; + case 0x0098 : return "enable local trapping"; + case 0x0099 : return "disable global trapping"; + case 0x009A : return "disable local trapping"; + case 0x009B : return "create list"; + case 0x009C : return "destroy list"; + case 0x009D : return "allocate list"; + case 0x009E : return "attach list"; + case 0x009F : return "attach list tail"; + case 0x00A0 : return "insert into list"; + case 0x00A1 : return "remove from list"; + case 0x00A2 : return "deallocate list"; + case 0x00A3 : return "get first item in list"; + case 0x00A4 : return "get next item in list"; + case 0x00A5 : return "remove first item in list"; + case 0x00A6 : return "add instance item"; + case 0x00A7 : return "allocate device callback area"; + case 0x00A8 : return "allocate global V86 data area"; + case 0x00A9 : return "allocate temporary V86 data area"; + case 0x00AA : return "free temporary V86 data area"; + case 0x00AB : return "get decimal integer from profile"; + case 0x00AC : return "convert decimal string to integer"; + case 0x00AD : return "get fixed-point number from profile"; + case 0x00AE : return "convert fixed-point string"; + case 0x00AF : return "get hex integer from profile"; + case 0x00B0 : return "convert hex string to integer"; + case 0x00B1 : return "get boolean value from profile"; + case 0x00B2 : return "convert boolean string"; + case 0x00B3 : return "get string from profile"; + case 0x00B4 : return "get next string from profile"; + case 0x00B5 : return "get environment string"; + case 0x00B6 : return "get exec path"; + case 0x00B7 : return "get configuration directory"; + case 0x00B8 : return "open file"; + case 0x00B9 : return "get PSP segment"; + case 0x00BA : return "get DOS vectors"; + case 0x00BB : return "get machine information"; + case 0x00BC : return "get/set HMA information"; + case 0x00BD : return "set system exit code"; + case 0x00BE : return "fatal error handler"; + case 0x00BF : return "fatal memory error"; + case 0x00C0 : return "update system clock"; + case 0x00C1 : return "test if debugger installed"; + case 0x00C2 : return "output debugger string"; + case 0x00C3 : return "output debugger character"; + case 0x00C4 : return "input debugger character"; + case 0x00C5 : return "debugger convert hex to binary"; + case 0x00C6 : return "debugger convert hex to decimal"; + case 0x00C7 : return "debugger test if valid handle"; + case 0x00C8 : return "validate client pointer"; + case 0x00C9 : return "test reentry"; + case 0x00CA : return "queue debugger string"; + case 0x00CB : return "log procedure call"; + case 0x00CC : return "debugger test current VM"; + case 0x00CD : return "get PM interrupt type"; + case 0x00CE : return "set PM interrupt type"; + case 0x00CF : return "get last updated system time"; + case 0x00D0 : return "get last updated VM execution time"; + case 0x00D1 : return "test if double-byte character-set lead byte"; + case 0x00D2 : return "_AddFreePhysPage"; + case 0x00D3 : return "_PageResetHandlePAddr"; + case 0x00D4 : return "_SetLastV86Page"; + case 0x00D5 : return "_GetLastV86Page"; + case 0x00D6 : return "_MapFreePhysReg"; + case 0x00D7 : return "_UnmapFreePhysReg"; + case 0x00D8 : return "_XchgFreePhysReg"; + case 0x00D9 : return "_SetFreePhysRegCalBk"; + case 0x00DA : return "get next arena (MCB)"; + case 0x00DB : return "get name of ugly TSR"; + case 0x00DC : return "get debug options"; + case 0x00DD : return "set physical HMA alias"; + case 0x00DE : return "_GetGlblRng0V86IntBase"; + case 0x00DF : return "add global V86 data area"; + case 0x00E0 : return "get/set detailed VM error"; + case 0x00E1 : return "Is_Debug_Chr"; + case 0x00E2 : return "clear monochrome screen"; + case 0x00E3 : return "output character to mono screen"; + case 0x00E4 : return "output string to mono screen"; + case 0x00E5 : return "set current position on mono screen"; + case 0x00E6 : return "get current position on mono screen"; + case 0x00E7 : return "get character from mono screen"; + case 0x00E8 : return "locate byte in ROM"; + case 0x00E9 : return "hook invalid page fault"; + case 0x00EA : return "unhook invalid page fault"; + case 0x00EB : return "set delete on exit file"; + case 0x00EC : return "close VM"; + case 0x00ED : return "Enable_Touch_1st_Meg"; + case 0x00EE : return "Disable_Touch_1st_Meg"; + case 0x00EF : return "install exception handler"; + case 0x00F0 : return "remove exception handler"; + case 0x00F1 : return "Get_Crit_Status_No_Block"; + case 0x00F2 : return "_Schedule_VM_RTI_Event"; + case 0x00F3 : return "_Trace_Out_Service"; + case 0x00F4 : return "_Debug_Out_Service"; + case 0x00F5 : return "_Debug_Flags_Service"; + case 0x00F6 : return "VMM add import module name"; + case 0x00F7 : return "VMM Add DDB"; + case 0x00F8 : return "VMM Remove DDB"; + case 0x00F9 : return "get thread time slice priority"; + case 0x00FA : return "set thread time slice priority"; + case 0x00FB : return "schedule thread event"; + case 0x00FC : return "cancel thread event"; + case 0x00FD : return "set thread timeout"; + case 0x00FE : return "set asynchronous timeout"; + case 0x00FF : return "_AllocatreThreadDataSlot"; + case 0x0100 : return "_FreeThreadDataSlot"; + case 0x0101 : return "create Mutex"; + case 0x0102 : return "destroy Mutex"; + case 0x0103 : return "get Mutex owner"; + case 0x0104 : return "call when thread switched"; + case 0x0105 : return "create thread"; + case 0x0106 : return "start thread"; + case 0x0107 : return "terminate thread"; + case 0x0108 : return "get current thread handle"; + case 0x0109 : return "test current thread handle"; + case 0x010A : return "Get_Sys_Thread_Handle"; + case 0x010B : return "Test_Sys_Thread_Handle"; + case 0x010C : return "Validate_Thread_Handle"; + case 0x010D : return "Get_Initial_Thread_Handle"; + case 0x010E : return "Test_Initial_Thread_Handle"; + case 0x010F : return "Debug_Test_Valid_Thread_Handle"; + case 0x0110 : return "Debug_Test_Cur_Thread"; + case 0x0111 : return "VMM_GetSystemInitState"; + case 0x0112 : return "Cancel_Call_When_Thread_Switched"; + case 0x0113 : return "Get_Next_Thread_Handle"; + case 0x0114 : return "Adjust_Thread_Exec_Priority"; + case 0x0115 : return "_Deallocate_Device_CB_Area"; + case 0x0116 : return "Remove_IO_Handler"; + case 0x0117 : return "Remove_Mult_IO_Handlers"; + case 0x0118 : return "unhook V86 interrupt chain"; + case 0x0119 : return "unhook V86 fault handler"; + case 0x011A : return "unhook PM fault handler"; + case 0x011B : return "unhook VMM fault handler"; + case 0x011C : return "unhook device service"; + case 0x011D : return "_PageReserve"; + case 0x011E : return "_PageCommit"; + case 0x011F : return "_PageDecommit"; + case 0x0120 : return "_PagerRegister"; + case 0x0121 : return "_PagerQuery"; + case 0x0122 : return "_PagerDeregister"; + case 0x0123 : return "_ContextCreate"; + case 0x0124 : return "_ContextDestroy"; + case 0x0125 : return "_PageAttach"; + case 0x0126 : return "_PageFlush"; + case 0x0127 : return "_SignalID"; + case 0x0128 : return "_PageCommitPhys"; + case 0x0129 : return "_Register_Win32_Services"; + case 0x012A : return "Cancel_Call_When_Not_Critical"; + case 0x012B : return "Cancel_Call_When_Idle"; + case 0x012C : return "Cancel_Call_When_Task_Switched"; + case 0x012D : return "_Debug_Printf_Service"; + case 0x012E : return "enter Mutex"; + case 0x012F : return "leave Mutex"; + case 0x0130 : return "simulate VM I/O"; + case 0x0131 : return "Signal_Semaphore_No_Switch"; + case 0x0132 : return "_MMSwitchContext"; + case 0x0133 : return "_MMModifyPermissions"; + case 0x0134 : return "_MMQuery"; + case 0x0135 : return "_EnterMustComplete"; + case 0x0136 : return "_LeaveMustComplete"; + case 0x0137 : return "_ResumeExecMustComplete"; + case 0x0138 : return "get thread termination status"; + case 0x0139 : return "_GetInstanceInfo"; + case 0x013A : return "_ExecIntMustComplete"; + case 0x013B : return "_ExecVxDIntMustComplete"; + case 0x013C : return "begin V86 serialization"; + case 0x013D : return "unhook V86 page"; + case 0x013E : return "VMM_GetVxDLocationList"; + case 0x013F : return "VMM_GetDDBList: get start of VxD chain"; + case 0x0140 : return "unhook NMI event"; + case 0x0141 : return "Get_Instanced_V86_Int_Vector"; + case 0x0142 : return "get or set real DOS PSP"; + case 0x0143 : return "call priority thread event"; + case 0x0144 : return "Get_System_Time_Address"; + case 0x0145 : return "Get_Crit_Status_Thread"; + case 0x0146 : return "Get_DDB"; + case 0x0147 : return "Directed_Sys_Control"; + case 0x0148 : return "_RegOpenKey"; + case 0x0149 : return "_RegCloseKey"; + case 0x014A : return "_RegCreateKey"; + case 0x014B : return "_RegDeleteKey"; + case 0x014C : return "_RegEnumKey"; + case 0x014D : return "_RegQueryValue"; + case 0x014E : return "_RegSetValue"; + case 0x014F : return "_RegDeleteValue"; + case 0x0150 : return "_RegEnumValue"; + case 0x0151 : return "_RegQueryValueEx"; + case 0x0152 : return "_RegSetValueEx"; + case 0x0153 : return "_CallRing3"; + case 0x0154 : return "Exec_PM_Int"; + case 0x0155 : return "_RegFlushKey"; + case 0x0156 : return "_PageCommitContig"; + case 0x0157 : return "_GetCurrentContext"; + case 0x0158 : return "_LocalizeSprintf"; + case 0x0159 : return "_LocalizeStackSprintf"; + case 0x015A : return "Call_Restricted_Event"; + case 0x015B : return "Cancel_Restricted_Event"; + case 0x015C : return "Register_PEF_Provider"; + case 0x015D : return "_GetPhysPageInfo"; + case 0x015E : return "_RegQueryInfoKey"; + case 0x015F : return "MemArb_Reserve_Pages"; + case 0x0160 : return "Time_Slice_Sys_VM_Idle"; + case 0x0161 : return "Time_Slice_Sleep"; + case 0x0162 : return "Boost_With_Decay"; + case 0x0163 : return "Set_Inversion_Pri"; + case 0x0164 : return "Reset_Inversion_Pri"; + case 0x0165 : return "Release_Inversion_Pri"; + case 0x0166 : return "Get_Thread_Win32_Pri"; + case 0x0167 : return "Set_Thread_Win32_Pri"; + case 0x0168 : return "Set_Thread_Static_Boost"; + case 0x0169 : return "Set_VM_Static_Boost"; + case 0x016A : return "Release_Inversion_Pri_ID"; + case 0x016B : return "Attach_Thread_To_Group"; + case 0x016C : return "Detach_Thread_From_Group"; + case 0x016D : return "Set_Group_Static_Boost"; + case 0x016E : return "_GetRegistryPath"; + case 0x016F : return "_GetRegistryKey"; + case 0x0170 : return "_CleanupNestedExec"; + case 0x0171 : return "_RegRemapPreDefKey"; + case 0x0172 : return "End_V86_Serialization"; + case 0x0173 : return "_Assert_Range"; + case 0x0174 : return "_Sprintf"; + case 0x0175 : return "_PageChangePager"; + case 0x0176 : return "_RegCreateDynKey"; + case 0x0177 : return "RegQMulti"; + case 0x0178 : return "Boost_Thread_With_VM"; + case 0x0179 : return "Get_Boot_Flags"; + case 0x017A : return "Set_Boot_Flags"; + case 0x017B : return "_lstrcpyn"; + case 0x017C : return "_lstrlen"; + case 0x017D : return "_lmemcpy"; + case 0x017E : return "_GetVxDName"; + case 0x017F : return "Force_Mutexes_Free"; + case 0x0180 : return "Restore_Forced_Mutexes"; + case 0x0181 : return "_AddReclaimableItem"; + case 0x0182 : return "_SetReclaimableItem"; + case 0x0183 : return "_EnumReclaimableItem"; + case 0x0184 : return "Time_Slice_Wake_Sys_VM"; + case 0x0185 : return "VMM_Replace_Global_Environment"; + case 0x0186 : return "Begin_Non_Serial_Nest_V86_Exec"; + case 0x0187 : return "Get_Nest_Exec_Status"; + case 0x0188 : return "Open_Boot_Log"; + case 0x0189 : return "Write_Boot_Log"; + case 0x018A : return "Close_Boot_Log"; + case 0x018B : return "EnableDisable_Boot_Log"; + case 0x018C : return "_Call_On_My_Stack"; + case 0x018D : return "Get_Inst_V86_Int_Vec_Base"; + case 0x018E : return "_lstrcmpi"; + case 0x018F : return "_strupr"; + case 0x0190 : return "Log_Fault_Call_Out"; + case 0x0191 : return "_AtEventTime"; + default: return "dunnoSV"; + } + case 0x0002: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "DEBUG_Fault"; + case 0x0002 : return "DEBUG_CheckFault"; + case 0x0003 : return "DEBUG_LoadSyms"; + default: return "dunnoSV"; + } + case 0x0003: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "virtualize IRQ"; + case 0x0002 : return "set interrupt request"; + case 0x0003 : return "clear interrupt request"; + case 0x0004 : return "physical EOI"; + case 0x0005 : return "get complete status"; + case 0x0006 : return "get status"; + case 0x0007 : return "test physical request"; + case 0x0008 : return "physically mask"; + case 0x0009 : return "physically unmask"; + case 0x000A : return "set automatic masking"; + case 0x000B : return "get IRQ complete status"; + case 0x000C : return "convert handle to IRQ"; + case 0x000D : return "convert IRQ to interrupt"; + case 0x000E : return "convert interrupt to IRQ"; + case 0x000F : return "call on hardware interrupt"; + case 0x0010 : return "force default owner"; + case 0x0011 : return "force default behavior"; + case 0x0012 : return "VPICD_Auto_Mask_At_Inst_Swap"; + case 0x0013 : return "VPICD_Begin_Inst_Page_Swap"; + case 0x0014 : return "VPICD_End_Inst_Page_Swap"; + case 0x0015 : return "VPICD_Virtual_EOI"; + case 0x0016 : return "VPICD_Get_Virtualization_Count"; + case 0x0017 : return "VPICD_Post_Sys_Critical_Init"; + case 0x0018 : return "VPICD_VM_SlavePIC_Mask_Change"; + default: return "dunnoSV"; + } + case 0x0004: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "virtualize channel"; + case 0x0002 : return "get region information"; + case 0x0003 : return "set region information"; + case 0x0004 : return "get virtual state"; + case 0x0005 : return "set virtual state"; + case 0x0006 : return "set physical state"; + case 0x0007 : return "mask channel"; + case 0x0008 : return "unmask channel"; + case 0x0009 : return "lock DMA region"; + case 0x000A : return "unlock DMA region"; + case 0x000B : return "scatter lock"; + case 0x000C : return "scatter unlock"; + case 0x000D : return "reserve buffer space"; + case 0x000E : return "request buffer"; + case 0x000F : return "release buffer"; + case 0x0010 : return "copy to buffer"; + case 0x0011 : return "copy from buffer"; + case 0x0012 : return "default handler"; + case 0x0013 : return "disable translation"; + case 0x0014 : return "enable translation"; + case 0x0015 : return "get EISA address mode"; + case 0x0016 : return "set EISA address mode"; + case 0x0017 : return "unlock DMA region (ND)"; + case 0x0018 : return "VDMAD_Phys_Mask_Channel"; + case 0x0019 : return "VDMAD_Phys_Unmask_Channel"; + case 0x001A : return "VDMAD_Unvirtualize_Channel"; + case 0x001B : return "VDMAD_Set_IO_Address"; + case 0x001C : return "VDMAD_Get_Phys_Count"; + case 0x001D : return "VDMAD_Get_Phys_Status"; + case 0x001E : return "VDMAD_Get_Max_Phys_Page"; + case 0x001F : return "VDMAD_Set_Channel_Callbacks"; + case 0x0020 : return "VDMAD_Get_Virt_Count"; + case 0x0021 : return "VDMAD_Set_Virt_Count"; + default: return "dunnoSV"; + } + case 0x0005: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "update system clock"; + case 0x0002 : return "get interrupt period"; + case 0x0003 : return "begin minimum interrupt period"; + case 0x0004 : return "end minimum interrupt period"; + case 0x0005 : return "disable trapping"; + case 0x0006 : return "enable trapping"; + case 0x0007 : return "get real time"; + case 0x0008 : return "VTD_Get_Date_And_Time"; + case 0x0009 : return "VTD_Adjust_VM_Count"; + case 0x000A : return "VTD_Delay"; + default: return "dunnoSV"; + } + case 0x0006: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "allocate V86 pages"; + case 0x0002 : return "set EMS and XMS limits"; + case 0x0003 : return "get EMS and XMS limits"; + case 0x0004 : return "set mapping information"; + case 0x0005 : return "get mapping information"; + case 0x0006 : return "Xlat API"; + case 0x0007 : return "load client pointer"; + case 0x0008 : return "allocate buffer"; + case 0x0009 : return "free buffer"; + case 0x000A : return "get Xlat buffer state"; + case 0x000B : return "set Xlat buffer state"; + case 0x000C : return "get VM flat selector"; + case 0x000D : return "map pages"; + case 0x000E : return "free page map region"; + case 0x000F : return "_LocalGlobalReg"; + case 0x0010 : return "get page status"; + case 0x0011 : return "set local A20"; + case 0x0012 : return "reset base pages"; + case 0x0013 : return "set available mapped pages"; + case 0x0014 : return "V86MMGR_NoUMBInitCalls"; + case 0x0015 : return "V86MMGR_Get_EMS_XMS_Avail"; + case 0x0016 : return "V86MMGR_Toggle_HMA"; + case 0x0017 : return "V86MMGR_Dev_Init"; + case 0x0018 : return "V86MMGR_Alloc_UM_Page"; + default: return "dunnoSV"; + } + case 0x0007: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "test create"; + case 0x0002 : return "create swap file"; + case 0x0003 : return "destroy swap file"; + case 0x0004 : return "in"; + case 0x0005 : return "out"; + case 0x0006 : return "test if I/O valid"; + case 0x0007 : return "Read_Or_Write"; + case 0x0008 : return "Grow_File"; + case 0x0009 : return "Init_File"; + default: return "dunnoSV"; + } + case 0x000a: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "PIF state"; + case 0x0002 : return "get GrabRtn"; + case 0x0003 : return "hide cursor"; + case 0x0004 : return "set VM type"; + case 0x0005 : return "get ModTime"; + case 0x0006 : return "set HCurTrk"; + case 0x0007 : return "message clear screen"; + case 0x0008 : return "message foreground color"; + case 0x0009 : return "message background color"; + case 0x000A : return "message output text"; + case 0x000B : return "message set cursor position"; + case 0x000C : return "query access"; + case 0x000D : return "VDD_Check_Update_Soon"; + case 0x000E : return "VDD_Get_Mini_Dispatch_Table"; + case 0x000F : return "VDD_Register_Virtual_Port"; + case 0x0010 : return "VDD_Get_VM_Info"; + case 0x0011 : return "VDD_Get_Special_VM_IDs"; + case 0x0012 : return "VDD_Register_Extra_Screen_Selector"; + case 0x0013 : return "VDD_Takeover_VGA_Port"; + default: return "dunnoSV"; + } + case 0x000c: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "set mouse type"; + case 0x0002 : return "get mouse owner"; + case 0x0003 : return "VMOUSE_Post_Pointer_Message"; + case 0x0004 : return "VMOUSE_Set_Cursor_Proc"; + case 0x0005 : return "VMOUSE_Call_Cursor_Proc"; + case 0x0006 : return "VMOUSE_Set_Mouse_Data~Get_Mouse_Data"; + case 0x0007 : return "VMOUSE_Manipulate_Pointer_Message"; + case 0x0008 : return "VMOUSE_Set_Middle_Button"; + case 0x0009 : return "VMD_Set_Middle_Button"; + case 0x000A : return "VMD_Enable_Disable_Mouse_Events"; + case 0x000B : return "VMD_Post_Absolute_Pointer_Message"; + default: return "dunnoSV"; + } + case 0x000d: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "define hotkey"; + case 0x0002 : return "remove hotkey"; + case 0x0003 : return "locally enable hotkey"; + case 0x0004 : return "locally disable hotkey"; + case 0x0005 : return "reflect hotkey"; + case 0x0006 : return "cancel hotkey state"; + case 0x0007 : return "force keys"; + case 0x0008 : return "get keyboard owner"; + case 0x0009 : return "define paste mode"; + case 0x000A : return "start pasting"; + case 0x000B : return "cancel paste"; + case 0x000C : return "get message key"; + case 0x000D : return "peek message key"; + case 0x000E : return "flush message key queue"; + case 0x000F : return "VKD_Enable_Keyboard"; + case 0x0010 : return "VKD_Disable_Keyboard"; + case 0x0011 : return "VKD_Get_Shift_State"; + case 0x0012 : return "VKD_Filter_Keyboard_Input"; + case 0x0013 : return "VKD_Put_Byte"; + case 0x0014 : return "VKD_Set_Shift_State"; + default: return "dunnoSV"; + } + case 0x000e: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "set port global"; + case 0x0002 : return "get focus"; + case 0x0003 : return "virtualize port"; + case 0x0004 : return "VCD_Acquire_Port"; + case 0x0005 : return "VCD_Free_Port"; + case 0x0006 : return "VCD_Acquire_Port_Windows_Style"; + case 0x0007 : return "VCD_Free_Port_Windows_Style"; + case 0x0008 : return "VCD_Steal_Port_Windows_Style"; + case 0x0009 : return "VCD_Find_COM_Index"; + case 0x000A : return "VCD_Set_Port_Global_Special"; + case 0x000B : return "VCD_Virtualize_Port_Dynamic"; + case 0x000C : return "VCD_Unvirtualize_Port_Dynamic"; + default: return "dunnoSV"; + } + case 0x0010: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "register device"; + case 0x0002 : return "find INT 13 drive"; + case 0x0003 : return "get device list"; + case 0x0004 : return "send command"; + case 0x0005 : return "command complete"; + case 0x0006 : return "synchronous command"; + case 0x0007 : return "IOS_Register"; + case 0x0008 : return "IOS_Requestor_Service"; + case 0x0009 : return "IOS_Exclusive_Access"; + case 0x000A : return "IOS_Send_Next_Command"; + case 0x000B : return "IOS_Set_Async_Time_Out"; + case 0x000C : return "IOS_Signal_Semaphore_No_Switch"; + case 0x000D : return "IOSIdleStatus"; + case 0x000E : return "IOSMapIORSToI24"; + case 0x000F : return "IOSMapIORSToI21"; + case 0x0010 : return "PrintLog"; + default: return "dunnoSV"; + } + case 0x0011: + switch (sv & 0x7fff) { + case 0x0000 : return "get_version"; + case 0x0001 : return "get_virt_state"; + case 0x0002 : return "set_virt_state"; + case 0x0003 : return "get_cr0_state"; + case 0x0004 : return "set_cr0_state"; + case 0x0005 : return "get_thread_state"; + case 0x0006 : return "set_thread_state"; + case 0x0007 : return "get_FP_instruction_size"; + case 0x0008 : return "set_thread_precision"; + default: return "dunnoSV"; + } + case 0x0012: + switch (sv & 0x7fff) { + case 0x0000 : return "get EBIOS version"; + case 0x0001 : return "get unused memory"; + default: return "dunnoSV"; + } + case 0x0015: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "set exec VM data"; + case 0x0002 : return "coyp VM drive state"; + case 0x0003 : return "execute VM"; + case 0x0004 : return "get InDOS pointer"; + case 0x0005 : return "add device"; + case 0x0006 : return "remove device"; + case 0x0007 : return "instance device"; + case 0x0008 : return "get DOS critical status"; + case 0x0009 : return "enable InDOS polling"; + case 0x000A : return "backfill allowed"; + case 0x000B : return "LocalGlobalReg"; + case 0x000C : return "Init_UMB_Area"; + case 0x000D : return "Begin_V86_App"; + case 0x000E : return "End_V86_App"; + case 0x000F : return "Alloc_Local_Sys_VM_Mem"; + case 0x0010 : return "DOSMGR_Grow_CDSs"; + case 0x0011 : return "DOSMGR_Translate_Server_DOS_Call"; + case 0x0012 : return "DOSMGR_MMGR_PSP_Change_Notifier"; + default: return "dunnoSV"; + } + case 0x0017: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "resolve contention"; + case 0x0002 : return "event"; + case 0x0003 : return "SYSMODAL message"; + case 0x0004 : return "message"; + case 0x0005 : return "get VM information"; + case 0x0006 : return "_SHELL_PostMessage"; + case 0x0007 : return "_SHELL_WinExec"; + case 0x0008 : return "_SHELL_CallDll"; + case 0x0009 : return "SHELL_OpenClipboard"; + case 0x000A : return "SHELL_SetClipboardData"; + case 0x000B : return "SHELL_GetClipboardData"; + case 0x000C : return "SHELL_CloseClipboard"; + case 0x000D : return "_SHELL_Install_Taskman_Hooks"; + case 0x000E : return "SHELL_Hook_Properties"; + case 0x000F : return "SHELL_Unhook_Properties"; + case 0x0010 : return "SHELL_OEMKeyScan"; + case 0x0011 : return "SHELL_Update_User_Activity"; + case 0x0012 : return "_SHELL_UnhookSystemBroadcast"; + case 0x0013 : return "_SHELL_LocalAllocEx"; + case 0x0014 : return "_SHELL_LocalFree"; + case 0x0015 : return "_SHELL_LoadLibrary"; + case 0x0016 : return "_SHELL_FreeLibrary"; + case 0x0017 : return "_SHELL_GetProcAddress"; + case 0x0018 : return "_SHELL_CallDll"; + case 0x0019 : return "_SHELL_SuggestSingleMSDOSMode"; + case 0x001A : return "SHELL_CheckHotkeyAllowed"; + case 0x001B : return "_SHELL_GetDOSAppInfo"; + default: return "dunnoSV"; + } + case 0x0018: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "enable/disable"; + case 0x0002 : return "reset detection"; + case 0x0003 : return "check idle"; + default: return "dunnoSV"; + } + case 0x001a: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "send FILESYSCHANGE"; + case 0x0002 : return "do PSP adjust"; + default: return "dunnoSV"; + } + case 0x001b: + case 0x001c: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + default: return "dunnoSV"; + } + case 0x0021: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "init file"; + case 0x0002 : return "clean up"; + case 0x0003 : return "grow file"; + case 0x0004 : return "read or write"; + case 0x0005 : return "cancel"; + case 0x0006 : return "test I/O valid"; + case 0x0007 : return "Get_Size_Info"; + case 0x0008 : return "Set_Async_Manager"; + case 0x0009 : return "Call_Async_Manager"; + default: return "dunnoSV"; + } + case 0x0027: + switch (sv & 0x7fff) { + case 0x0000 : return "VXDLDR_Get_Version"; + case 0x0001 : return "VXDLDR_LoadDevice"; + case 0x0002 : return "VXDLDR_UnloadDevice"; + case 0x0003 : return "VXDLDR_DevInitSucceeded"; + case 0x0004 : return "VXDLDR_DevInitFailed"; + case 0x0005 : return "VXDLDR_GetDeviceList"; + case 0x0006 : return "VXDLDR_UnloadMe"; + case 0x0007 : return "PELDR_LoadModule"; + case 0x0008 : return "PELDR_GetModuleHandle"; + case 0x0009 : return "PELDR_GetModuleUsage"; + case 0x000A : return "PELDR_GetEntryPoint"; + case 0x000B : return "PELDR_GetProcAddress"; + case 0x000C : return "PELDR_AddExportTable"; + case 0x000D : return "PELDR_RemoveExportTable"; + case 0x000E : return "PELDR_FreeModule"; + case 0x000F : return "VXDLDR_Notify"; + case 0x0010 : return "_PELDR_InitCompleted"; + case 0x0011 : return "_PELDR_LoadModuleEx"; + default: return "dunnoSV"; + } + case 0x002A: + switch (sv & 0x7fff) { + case 0x0000 : return "VWin32_Get_Version"; + case 0x0001 : return "VWin32_Wake_For_Event"; + case 0x0002 : return "_VWIN32_QueueUserApc"; + case 0x0003 : return "_VWIN32_Get_Thread_Context"; + case 0x0004 : return "_VWIN32_Set_Thread_Context"; + case 0x0005 : return "_VWIN32_CopyMem"; + case 0x0006 : return "_VWIN32_BlockForTermination"; + case 0x0007 : return "_VWIN32_Emulate_Npx"; + case 0x0008 : return "_VWIN32_CheckDelayedNpxTrap"; + case 0x0009 : return "VWIN32_EnterCrstR0"; + case 0x000A : return "VWIN32_LeaveCrstR0"; + case 0x000B : return "_VWIN32_FaultPopup"; + case 0x000C : return "VWIN32_GetContextHandle"; + case 0x000D : return "VWIN32_GetCurrentProcessHandle"; + case 0x000E : return "_VWIN32_SetWin32Event"; + case 0x000F : return "_VWIN32_PulseWin32Event"; + case 0x0010 : return "_VWIN32_ResetWin32Event"; + case 0x0011 : return "_VWIN32_WaitSingleObject"; + case 0x0012 : return "_VWIN32_WaitMultipleObjects"; + case 0x0013 : return "_VWIN32_CreateRing0Thread"; + case 0x0014 : return "_VWIN32_CloseVxDHandle"; + case 0x0015 : return "VWIN32_ActiveTimeBiasSet"; + case 0x0016 : return "VWIN32_GetCurrentDirectory"; + case 0x0017 : return "VWIN32_BlueScreenPopup"; + case 0x0018 : return "VWIN32_TerminateApp"; + case 0x0019 : return "_VWIN32_QueueKernelAPC"; + case 0x001A : return "VWIN32_SysErrorBox"; + case 0x001B : return "_VWIN32_IsClientWin32"; + case 0x001C : return "VWIN32_IFSRIPWhenLev2Taken"; + default: return "dunnoSV"; + } + case 0x002b: + switch (sv & 0x7fff) { + case 0x0000 : return "VCOMM_Get_Version"; + case 0x0001 : return "_VCOMM_Register_Port_Driver"; + case 0x0002 : return "_VCOMM_Acquire_Port"; + case 0x0003 : return "_VCOMM_Release_Port"; + case 0x0004 : return "_VCOMM_OpenComm"; + case 0x0005 : return "_VCOMM_SetCommState"; + case 0x0006 : return "_VCOMM_GetCommState"; + case 0x0007 : return "_VCOMM_SetupComm"; + case 0x0008 : return "_VCOMM_TransmitCommChar"; + case 0x0009 : return "_VCOMM_CloseComm"; + case 0x000A : return "_VCOMM_GetCommQueueStatus"; + case 0x000B : return "_VCOMM_ClearCommError"; + case 0x000C : return "_VCOMM_GetModemStatus"; + case 0x000D : return "_VCOMM_GetCommProperties"; + case 0x000E : return "_VCOMM_EscapeCommFunction"; + case 0x000F : return "_VCOMM_PurgeComm"; + case 0x0010 : return "_VCOMM_SetCommEventMask"; + case 0x0011 : return "_VCOMM_GetCommEventMask"; + case 0x0012 : return "_VCOMM_WriteComm"; + case 0x0013 : return "_VCOMM_ReadComm"; + case 0x0014 : return "_VCOMM_EnableCommNotification"; + case 0x0015 : return "_VCOMM_GetLastError"; + case 0x0016 : return "_VCOMM_Steal_Port"; + case 0x0017 : return "_VCOMM_SetReadCallBack"; + case 0x0018 : return "_VCOMM_SetWriteCallBack"; + case 0x0019 : return "_VCOMM_GetSetCommTimeouts"; + case 0x001A : return "_VCOMM_SetWriteRequest"; + case 0x001B : return "_VCOMM_SetReadRequest"; + case 0x001C : return "_VCOMM_Dequeue_Request"; + case 0x001D : return "_VCOMM_Dequeue_Request"; + case 0x001E : return "_VCOMM_Enumerate_DevNodes"; + case 0x001F : return "VCOMM_Map_Win32DCB_To_Ring0"; + case 0x0020 : return "VCOMM_Map_Ring0DCB_To_Win32"; + case 0x0021 : return "_VCOMM_Get_Contention_Handler"; + case 0x0022 : return "_VCOMM_Map_Name_To_Resource"; + default: return "dunnoSV"; + } + case 0x0033: + switch (sv & 0x7fff) { + case 0x0000 : return "_CONFIGMG_Get_Version"; + case 0x0001 : return "_CONFIGMG_Initialize"; + case 0x0002 : return "_CONFIGMG_Locate_DevNode"; + case 0x0003 : return "_CONFIGMG_Get_Parent"; + case 0x0004 : return "_CONFIGMG_Get_Child"; + case 0x0005 : return "_CONFIGMG_Get_Sibling"; + case 0x0006 : return "_CONFIGMG_Get_Device_ID_Size"; + case 0x0007 : return "_CONFIGMG_Get_Device_ID"; + case 0x0008 : return "_CONFIGMG_Get_Depth"; + case 0x0009 : return "_CONFIGMG_Get_Private_DWord"; + case 0x000A : return "_CONFIGMG_Set_Private_DWord"; + case 0x000B : return "_CONFIGMG_Create_DevNode"; + case 0x000C : return "_CONFIGMG_Query_Remove_SubTree"; + case 0x000D : return "_CONFIGMG_Remove_SubTree"; + case 0x000E : return "_CONFIGMG_Register_Device_Driver"; + case 0x000F : return "_CONFIGMG_Register_Enumerator"; + case 0x0010 : return "_CONFIGMG_Register_Arbitrator"; + case 0x0011 : return "_CONFIGMG_Deregister_Arbitrator"; + case 0x0012 : return "_CONFIGMG_Query_Arbitrator_Free_Size"; + case 0x0013 : return "_CONFIGMG_Query_Arbitrator_Free_Data"; + case 0x0014 : return "_CONFIGMG_Sort_NodeList"; + case 0x0015 : return "_CONFIGMG_Yield"; + case 0x0016 : return "_CONFIGMG_Lock"; + case 0x0017 : return "_CONFIGMG_Unlock"; + case 0x0018 : return "_CONFIGMG_Add_Empty_Log_Conf"; + case 0x0019 : return "_CONFIGMG_Free_Log_Conf"; + case 0x001A : return "_CONFIGMG_Get_First_Log_Conf"; + case 0x001B : return "_CONFIGMG_Get_Next_Log_Conf"; + case 0x001C : return "_CONFIGMG_Add_Res_Des"; + case 0x001D : return "_CONFIGMG_Modify_Res_Des"; + case 0x001E : return "_CONFIGMG_Free_Res_Des"; + case 0x001F : return "_CONFIGMG_Get_Next_Res_Des"; + case 0x0020 : return "_CONFIGMG_Get_Performance_Info"; + case 0x0021 : return "_CONFIGMG_Get_Res_Des_Data_Size"; + case 0x0022 : return "_CONFIGMG_Get_Res_Des_Data"; + case 0x0023 : return "_CONFIGMG_Process_Events_Now"; + case 0x0024 : return "_CONFIGMG_Create_Range_List"; + case 0x0025 : return "_CONFIGMG_Add_Range"; + case 0x0026 : return "_CONFIGMG_Delete_Range"; + case 0x0027 : return "_CONFIGMG_Test_Range_Available"; + case 0x0028 : return "_CONFIGMG_Dup_Range_List"; + case 0x0029 : return "_CONFIGMG_Free_Range_List"; + case 0x002A : return "_CONFIGMG_Invert_Range_List"; + case 0x002B : return "_CONFIGMG_Intersect_Range_List"; + case 0x002C : return "_CONFIGMG_First_Range"; + case 0x002D : return "_CONFIGMG_Next_Range"; + case 0x002E : return "_CONFIGMG_Dump_Range_List"; + case 0x002F : return "_CONFIGMG_Load_DLVxDs"; + case 0x0030 : return "_CONFIGMG_Get_DDBs"; + case 0x0031 : return "_CONFIGMG_Get_CRC_CheckSum"; + case 0x0032 : return "_CONFIGMG_Register_DevLoader"; + case 0x0033 : return "_CONFIGMG_Reenumerate_DevNode"; + case 0x0034 : return "_CONFIGMG_Setup_DevNode"; + case 0x0035 : return "_CONFIGMG_Reset_Children_Marks"; + case 0x0036 : return "_CONFIGMG_Get_DevNode_Status"; + case 0x0037 : return "_CONFIGMG_Remove_Unmarked_Children"; + case 0x0038 : return "_CONFIGMG_ISAPNP_To_CM"; + case 0x0039 : return "_CONFIGMG_CallBack_Device_Driver"; + case 0x003A : return "_CONFIGMG_CallBack_Enumerator"; + case 0x003B : return "_CONFIGMG_Get_Alloc_Log_Conf"; + case 0x003C : return "_CONFIGMG_Get_DevNode_Key_Size"; + case 0x003D : return "_CONFIGMG_Get_DevNode_Key"; + case 0x003E : return "_CONFIGMG_Read_Registry_Value"; + case 0x003F : return "_CONFIGMG_Write_Registry_Value"; + case 0x0040 : return "_CONFIGMG_Disable_DevNode"; + case 0x0041 : return "_CONFIGMG_Enable_DevNode"; + case 0x0042 : return "_CONFIGMG_Move_DevNode"; + case 0x0043 : return "_CONFIGMG_Set_Bus_Info"; + case 0x0044 : return "_CONFIGMG_Get_Bus_Info"; + case 0x0045 : return "_CONFIGMG_Set_HW_Prof"; + case 0x0046 : return "_CONFIGMG_Recompute_HW_Prof"; + case 0x0047 : return "_CONFIGMG_Query_Change_HW_Prof"; + case 0x0048 : return "_CONFIGMG_Get_Device_Driver_Private_DWord"; + case 0x0049 : return "_CONFIGMG_Set_Device_Driver_Private_DWord"; + case 0x004A : return "_CONFIGMG_Get_HW_Prof_Flags"; + case 0x004B : return "_CONFIGMG_Set_HW_Prof_Flags"; + case 0x004C : return "_CONFIGMG_Read_Registry_Log_Confs"; + case 0x004D : return "_CONFIGMG_Run_Detection"; + case 0x004E : return "_CONFIGMG_Call_At_Appy_Time"; + case 0x004F : return "_CONFIGMG_Fail_Change_HW_Prof"; + case 0x0050 : return "_CONFIGMG_Set_Private_Problem"; + case 0x0051 : return "_CONFIGMG_Debug_DevNode"; + case 0x0052 : return "_CONFIGMG_Get_Hardware_Profile_Info"; + case 0x0053 : return "_CONFIGMG_Register_Enumerator_Function"; + case 0x0054 : return "_CONFIGMG_Call_Enumerator_Function"; + case 0x0055 : return "_CONFIGMG_Add_ID"; + case 0x0056 : return "_CONFIGMG_Find_Range"; + case 0x0057 : return "_CONFIGMG_Get_Global_State"; + case 0x0058 : return "_CONFIGMG_Broadcast_Device_Change_Message"; + case 0x0059 : return "_CONFIGMG_Call_DevNode_Handler"; + case 0x005A : return "_CONFIGMG_Remove_Reinsert_All"; + default: return "dunnoSV"; + } + case 0x048B: + switch (sv & 0x7fff) { + case 0x0000 : return "VXDLDR_Get_Version"; + case 0x0001 : return "VCACHE_Register"; + case 0x0002 : return "VCACHE_GetSize"; + case 0x0003 : return "VCACHE_CheckAvail"; + case 0x0004 : return "VCACHE_FindBlock"; + case 0x0005 : return "VCACHE_FreeBlock"; + case 0x0006 : return "VCACHE_MakeMRU"; + case 0x0007 : return "VCACHE_Hold"; + case 0x0008 : return "VCACHE_Unhold"; + case 0x0009 : return "VCACHE_Enum"; + case 0x000A : return "VCACHE_TestHandle"; + case 0x000B : return "VCACHE_VerifySums"; + case 0x000C : return "VCACHE_RecalcSums"; + case 0x000D : return "VCACHE_TestHold"; + case 0x000E : return "VCACHE_GetStats"; + case 0x000F : return "VCache_Deregister"; + case 0x0010 : return "VCache_AdjustMinimum"; + case 0x0011 : return "VCache_SwapBuffers"; + case 0x0012 : return "VCache_RelinquishPage"; + case 0x0013 : return "VCache_UseThisPage"; + case 0x0014 : return "_VCache_CreateLookupCache"; + case 0x0015 : return "_VCache_CloseLookupCache"; + case 0x0016 : return "_VCache_DeleteLookupCache"; + case 0x0017 : return "_VCache_Lookup"; + case 0x0018 : return "_VCache_UpdateLookup"; + default: return "dunnoSV"; + } + default: return "dunnoNR"; + } +} + + Bit8u lastint; void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { lastint=num; +// if ((num!=0x16) && (num!=0x1a) && (num!=0x28) && (num!=0x2a) && (num!=0x13)) LOG_MSG("INT %x EAX:%04X ECX:%04X EDX:%04X EBX:%04X CS:%04X EIP:%08X SS:%04X ESP:%08X",num,reg_eax,reg_ecx,reg_edx,reg_ebx,SegValue(cs),reg_eip,SegValue(ss),reg_esp); + if ((num==0x20) && (cpu.pmode)) { + PhysPt csip20 = SegPhys(cs)+reg_eip; + Bitu sv = mem_readw(csip20+2); + Bitu nr = mem_readw(csip20+4); + LOG_MSG("VxD service %s, %s (%X:%X)",translateVXDid(nr),translateVXDservice(nr,sv),nr,sv); + } #if C_DEBUG switch (num) { case 0xcd: @@ -463,7 +1491,7 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { return; } else { /* Protected Mode Interrupt */ - if ((reg_flags & FLAG_VM) && (type&CPU_INT_SOFTWARE)) { + if ((reg_flags & FLAG_VM) && (type&CPU_INT_SOFTWARE) && !(type&CPU_INT_NOIOPLCHECK)) { // LOG_MSG("Software int in v86, AH %X IOPL %x",reg_ah,(reg_flags & FLAG_IOPL) >>12); if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) { CPU_Exception(EXCEPTION_GP,0); @@ -677,13 +1705,7 @@ void CPU_IRET(bool use32,Bitu oldeip) { CPU_CHECK_COND(!cpu_tss.IsValid(), "TASK Iret without valid TSS", EXCEPTION_TS,cpu_tss.selector & 0xfffc) - // check if busy is set - switch (cpu_tss.desc.Type()) { - case DESC_286_TSS_B: case DESC_386_TSS_B: - break; - default: - E_Exit("TASK Iret:TSS not busy"); // or #TS(sel) - } + if (!cpu_tss.desc.IsBusy()) LOG(LOG_CPU,LOG_ERROR)("TASK Iret:TSS not busy"); Bitu back_link=cpu_tss.Get_back(); CPU_SwitchTask(back_link,TSwitch_IRET,oldeip); return; @@ -1238,7 +2260,6 @@ RET_same_level: return; } else { /* Return to outer level */ - if (bytes) E_Exit("RETF outer level with immediate value"); switch (desc.Type()) { case DESC_CODE_N_NC_A:case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A:case DESC_CODE_R_NC_NA: @@ -1265,11 +2286,13 @@ RET_same_level: if (use32) { offset=CPU_Pop32(); selector=CPU_Pop32() & 0xffff; + reg_esp+=bytes; n_esp = CPU_Pop32(); n_ss = CPU_Pop32() & 0xffff; } else { offset=CPU_Pop16(); selector=CPU_Pop16(); + reg_esp+=bytes; n_esp = CPU_Pop16(); n_ss = CPU_Pop16(); } @@ -1308,11 +2331,11 @@ RET_same_level: if (n_ss_desc.Big()) { cpu.stack.big=true; cpu.stack.mask=0xffffffff; - reg_esp=n_esp; + reg_esp=n_esp+bytes; } else { cpu.stack.big=false; cpu.stack.mask=0xffff; - reg_sp=n_esp & 0xffff; + reg_sp=(n_esp & 0xffff)+bytes; } Descriptor desc; @@ -1359,18 +2382,43 @@ void CPU_SLDT(Bitu & selector) { selector=cpu.gdt.SLDT(); } -void CPU_LLDT(Bitu selector) { - cpu.gdt.LLDT(selector); +bool CPU_LLDT(Bitu selector) { + if (!cpu.gdt.LLDT(selector)) { + LOG(LOG_CPU,LOG_ERROR)("LLDT failed, selector=%X",selector); + return true; + } LOG(LOG_CPU,LOG_NORMAL)("LDT Set to %X",selector); + return false; } void CPU_STR(Bitu & selector) { selector=cpu_tss.selector; } -void CPU_LTR(Bitu selector) { - cpu_tss.SetSelector(selector); - cpu_tss.desc.SetBusy(true); +bool CPU_LTR(Bitu selector) { + if ((selector & 0xfffc)==0) { + cpu_tss.SetSelector(selector); + return false; + } + TSS_Descriptor desc; + if ((selector & 4) || (!cpu.gdt.GetDescriptor(selector,desc))) { + LOG(LOG_CPU,LOG_ERROR)("LTR failed, selector=%X",selector); + return CPU_PrepareException(EXCEPTION_GP,selector); + } + + if ((desc.Type()==DESC_286_TSS_A) || (desc.Type()==DESC_386_TSS_A)) { + if (!desc.saved.seg.p) { + LOG(LOG_CPU,LOG_ERROR)("LTR failed, selector=%X (not present)",selector); + return CPU_PrepareException(EXCEPTION_NP,selector); + } + if (!cpu_tss.SetSelector(selector)) E_Exit("LTR failed, selector=%X",selector); + cpu_tss.desc.SetBusy(true); + } else { + /* Descriptor was no available TSS descriptor */ + LOG(LOG_CPU,LOG_NORMAL)("LTR failed, selector=%X (type=%X)",selector,desc.Type()); + return CPU_PrepareException(EXCEPTION_GP,selector); + } + return false; } Bitu gdt_count=0; @@ -1413,6 +2461,7 @@ void CPU_SET_CRX(Bitu cr,Bitu value) { PAGING_Enable((value & CR0_PAGING)>0); } else { cpu.pmode=false; + if (value & CR0_PAGING) LOG_MSG("Paging requested without PE=1"); PAGING_Enable(false); LOG(LOG_CPU,LOG_NORMAL)("Real mode"); } @@ -1445,7 +2494,7 @@ Bitu CPU_GET_CRX(Bitu cr) { case 2: return paging.cr2; case 3: - return PAGING_GetDirBase(); + return PAGING_GetDirBase() & 0xfffff000; default: LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV XXX, CR%d",cr); break; @@ -1462,6 +2511,58 @@ bool CPU_READ_CRX(Bitu cr,Bit32u & retvalue) { } +bool CPU_WRITE_DRX(Bitu dr,Bitu value) { + /* Check if privileged to access control registers */ + if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); + switch (dr) { + case 0: + case 1: + case 2: + case 3: + cpu.drx[dr]=value; + break; + case 4: + case 6: + cpu.drx[6]=(value|0xffff0ff0) & 0xffffefff; + break; + case 5: + case 7: + cpu.drx[7]=(value|0x400) & 0xffff2fff; + break; + default: + LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV DR%d,%X",dr,value); + break; + } + return false; +} + +bool CPU_READ_DRX(Bitu dr,Bit32u & retvalue) { + /* Check if privileged to access control registers */ + if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); + switch (dr) { + case 0: + case 1: + case 2: + case 3: + case 6: + case 7: + retvalue=cpu.drx[dr]; + break; + case 4: + retvalue=cpu.drx[6]; + break; + case 5: + retvalue=cpu.drx[7]; + break; + default: + LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV XXX, DR%d",dr); + retvalue=0; + break; + } + return false; +} + + void CPU_SMSW(Bitu & word) { word=cpu.cr0; } @@ -1693,8 +2794,7 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) { } Descriptor desc; if (!cpu.gdt.GetDescriptor(value,desc)) { - E_Exit("CPU_SetSegGeneral: Segment beyond limits"); -// return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); + return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); } switch (desc.Type()) { case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: @@ -1738,7 +2838,6 @@ bool CPU_PopSeg(SegNames seg,bool use32) { void CPU_CPUID(void) { switch (reg_eax) { case 0: /* Vendor ID String and maximum level? */ - reg_eax=1; reg_eax=1; /* Maximum level */ reg_ebx='G' | ('e' << 8) | ('n' << 16) | ('u'<< 24); reg_edx='i' | ('n' << 8) | ('e' << 16) | ('I'<< 24); @@ -1767,17 +2866,12 @@ static Bits HLT_Decode(void) { } void CPU_HLT(Bitu oldeip) { - if (cpu.cpl) { - CPU_Exception(EXCEPTION_GP,0); - return; - } reg_eip=oldeip; CPU_Cycles=0; cpu.hlt.cs=SegValue(cs); cpu.hlt.eip=reg_eip; cpu.hlt.old_decoder=cpudecoder; cpudecoder=&HLT_Decode; - return; } void CPU_ENTER(bool use32,Bitu bytes,Bitu level) { @@ -1875,7 +2969,11 @@ public: cpu.stack.big=false; cpu.idt.SetBase(0); cpu.idt.SetLimit(1023); - + + for (Bitu i=0; i<7; i++) cpu.drx[i]=0; + cpu.drx[6]=0xffff1ff0; + cpu.drx[7]=0x00000400; + /* Init the cpu cores */ CPU_Core_Normal_Init(); CPU_Core_Simple_Init(); diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index f328f2db..e00c2cff 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.41 2005-07-07 19:53:02 qbix79 Exp $ */ +/* $Id: ems.cpp,v 1.42 2005-08-15 13:43:44 c2woody Exp $ */ #include #include @@ -729,8 +729,8 @@ static Bitu INT67_Handler(void) { /* Load tables and initialize segment registers */ CPU_LGDT(new_gdt_limit, new_gdt_base); CPU_LIDT(new_idt_limit, new_idt_base); - CPU_LLDT(new_ldt); - CPU_LTR(new_tr); + if (CPU_LLDT(new_ldt)) LOG_MSG("VCPI:Could not load LDT with %x",new_ldt); + if (CPU_LTR(new_tr)) LOG_MSG("VCPI:Could not load TR with %x",new_tr); CPU_SetSegGeneral(ds,0); CPU_SetSegGeneral(es,0); @@ -796,8 +796,8 @@ static Bitu VCPI_PM_Handler() { /* Load descriptor table registers */ CPU_LGDT(0xff, vcpi.private_area+0x0000); CPU_LIDT(0x7ff, vcpi.private_area+0x2000); - CPU_LLDT(0x08); - CPU_LTR(0x10); + if (CPU_LLDT(0x08)) LOG_MSG("VCPI:Could not load LDT"); + if (CPU_LTR(0x10)) LOG_MSG("VCPI:Could not load TR"); reg_flags&=(~FLAG_NT); reg_esp+=8; // skip interrupt return information @@ -1107,8 +1107,8 @@ public: CPU_SET_CRX(0, 1); CPU_LGDT(0xff, vcpi.private_area+0x0000); CPU_LIDT(0x7ff, vcpi.private_area+0x2000); - CPU_LLDT(0x08); - CPU_LTR(0x10); + if (CPU_LLDT(0x08)) LOG_MSG("VCPI:Could not load LDT"); + if (CPU_LTR(0x10)) LOG_MSG("VCPI:Could not load TR"); CPU_Push32(SegValue(gs)); CPU_Push32(SegValue(fs)); From 4fd29f7d493a80d5f4ec5b2573beee421c314515 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 15 Aug 2005 14:17:20 +0000 Subject: [PATCH 2192/4131] remove logging output Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2276 --- src/cpu/cpu.cpp | 1037 +---------------------------------------------- 1 file changed, 2 insertions(+), 1035 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index d8628853..c67408cc 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.73 2005-08-15 13:43:44 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.74 2005-08-15 14:17:20 c2woody Exp $ */ #include #include "dosbox.h" @@ -364,7 +364,6 @@ bool CPU_SwitchTask(Bitu new_tss_selector,TSwitchType tstype,Bitu old_eip) { } /* Load the new selectors */ if (reg_flags & FLAG_VM) { -// LOG_MSG("Entering v86 task"); SegSet16(cs,new_cs); cpu.code.big=false; cpu.cpl=3; //We don't have segment caches so this will do @@ -429,1037 +428,9 @@ void CPU_Exception(Bitu which,Bitu error ) { CPU_Interrupt(which,CPU_INT_EXCEPTION | ((which>=8) ? CPU_INT_HAS_ERROR : 0),reg_eip); } -const char* translateVXDid(Bitu nr) { - switch (nr) { - case 0x0001: return "VMM"; // Virtual Machine Manager - case 0x0002: return "DEBUG"; - case 0x0003: return "VPICD"; // Virtual PIC Device - case 0x0004: return "VDMAD"; // Virtual DMA Device - case 0x0005: return "VTD"; // Virtual Timer Device - case 0x0006: return "V86MMGR"; // Virtual Device - case 0x0007: return "PageSwap"; - case 0x000A: return "VDD"; // Virtual Display Device - case 0x000C: return "VMD"; // Virtual Mouse Device - case 0x000D: return "VKD"; // Virtual Keyboard Device - case 0x000E: return "VCD"; // Virtual COMM Device - case 0x0010: return "IOS"; // BlockDev / IOS - case 0x0011: return "VMCPD"; - case 0x0012: return "EBIOS"; - case 0x0015: return "DOSMGR"; - case 0x0017: return "SHELL"; - case 0x0018: return "VMPoll"; - case 0x001A: return "DOSNET"; - case 0x001B: return "VFD"; - case 0x001C: return "LoadHi"; - case 0x0020: return "Int13"; - case 0x0021: return "PAGEFILE"; - case 0x0026: return "VPOWERD"; - case 0x0027: return "VXDLDR"; - case 0x002A: return "VWIN32"; - case 0x002B: return "VCOMM"; - case 0x0033: return "CONFIGMG"; - case 0x0036: return "VFBACKUP"; - case 0x0037: return "VMINI"; - case 0x0040: return "IFSMgr"; - case 0x0041: return "VCDFSD"; - case 0x0048: return "PERF"; - case 0x011F: return "VFLATD"; - case 0x0446: return "VADLIB"; - case 0x044a: return "mmdevldr"; - case 0x0484: return "IfsMgr"; - case 0x048B: return "VCACHE"; - case 0x357E: return "DSOUND"; - default: - return "unknown"; - } -} - -const char* translateVXDservice(Bitu nr, Bitu sv) { - switch (nr) { - case 0x0001: - switch (sv & 0x7fff) { - case 0x0000 : return "get version"; - case 0x0001 : return "get current VM handle"; - case 0x0002 : return "test current VM handle"; - case 0x0003 : return "get system VM handle"; - case 0x0004 : return "test system VM handle"; - case 0x0005 : return "validate VM handle"; - case 0x0006 : return "get VMM reenter count"; - case 0x0007 : return "begin reentrant execution"; - case 0x0008 : return "end reentrant execution"; - case 0x0009 : return "install V86 breakpoint"; - case 0x000A : return "remove V86 breakpoint"; - case 0x000B : return "allocate V86 callback"; - case 0x000C : return "allocation PM callback"; - case 0x000D : return "call when VM returns"; - case 0x000E : return "schedule global event"; - case 0x000F : return "schedule VM event"; - case 0x0010 : return "call global event"; - case 0x0011 : return "call VM event"; - case 0x0012 : return "cancel global event"; - case 0x0013 : return "cancel VM event"; - case 0x0014 : return "call priority VM event"; - case 0x0015 : return "cancel priority VM event"; - case 0x0016 : return "get NMI handler address"; - case 0x0017 : return "set NMI handler address"; - case 0x0018 : return "hook NMI event"; - case 0x0019 : return "call when VM interrupts enabled"; - case 0x001A : return "enable VM interrupts"; - case 0x001B : return "disable VM interrupts"; - case 0x001C : return "map flat"; - case 0x001D : return "map linear to VM address"; - case 0x001E : return "adjust execution priority"; - case 0x001F : return "begin critical section"; - case 0x0020 : return "end critical section"; - case 0x0021 : return "end critical section and suspend"; - case 0x0022 : return "claim critical section"; - case 0x0023 : return "release critical section"; - case 0x0024 : return "call when not critical"; - case 0x0025 : return "create semaphore"; - case 0x0026 : return "destroy semaphore"; - case 0x0027 : return "wait on semaphore"; - case 0x0028 : return "signal semaphore"; - case 0x0029 : return "get critical section status"; - case 0x002A : return "call when task switched"; - case 0x002B : return "suspend VM"; - case 0x002C : return "resume VM"; - case 0x002D : return "no-fail resume VM"; - case 0x002E : return "nuke VM"; - case 0x002F : return "crash current VM"; - case 0x0030 : return "get execution focus"; - case 0x0031 : return "set execution focus"; - case 0x0032 : return "get time slice priority"; - case 0x0033 : return "set time slice priority"; - case 0x0034 : return "get time slice granularity"; - case 0x0035 : return "set time slice granularity"; - case 0x0036 : return "get time slice information"; - case 0x0037 : return "adjust execution time"; - case 0x0038 : return "release time slice"; - case 0x0039 : return "wake up VM"; - case 0x003A : return "call when idle"; - case 0x003B : return "get next VM handle"; - case 0x003C : return "set global timeout"; - case 0x003D : return "set VM timeout"; - case 0x003E : return "cancel timeout"; - case 0x003F : return "get system time"; - case 0x0040 : return "get VM execution time"; - case 0x0041 : return "hook V86 interrupt chain"; - case 0x0042 : return "get V86 interrupt vector"; - case 0x0043 : return "set V86 interrupt vector"; - case 0x0044 : return "get PM interrupt vector"; - case 0x0045 : return "set PM interrupt vector"; - case 0x0046 : return "simulate interrupt"; - case 0x0047 : return "simulate IRET"; - case 0x0048 : return "simulate far call"; - case 0x0049 : return "simulate far jump"; - case 0x004A : return "simulate far RET"; - case 0x004B : return "simulate far RET N"; - case 0x004C : return "build interrupt stack frame"; - case 0x004D : return "simulate push"; - case 0x004E : return "simulate pop"; - case 0x004F : return "_HeapAllocate"; - case 0x0050 : return "_HeapReAllocate"; - case 0x0051 : return "_HeapFree"; - case 0x0052 : return "_HeapGetSize"; - case 0x0053 : return "_PageAllocate"; - case 0x0054 : return "_PageReAllocate"; - case 0x0055 : return "_PageFree"; - case 0x0056 : return "_PageLock"; - case 0x0057 : return "_PageUnLock"; - case 0x0058 : return "_PageGetSizeAddr"; - case 0x0059 : return "_PageGetAllocInfo"; - case 0x005A : return "_GetFreePageCount"; - case 0x005B : return "_GetSysPageCount"; - case 0x005C : return "_GetVMPgCount"; - case 0x005D : return "_MapIntoV86"; - case 0x005E : return "_PhysIntoV86"; - case 0x005F : return "_TestGlobalV86Mem"; - case 0x0060 : return "_ModifyPageBits"; - case 0x0061 : return "copy page table"; - case 0x0062 : return "map linear into V86"; - case 0x0063 : return "linear page lock"; - case 0x0064 : return "linear page unlock"; - case 0x0065 : return "_SetResetV86Pageabl"; - case 0x0066 : return "_GetV86PageableArray"; - case 0x0067 : return "_PageCheckLinRange"; - case 0x0068 : return "page out dirty pages"; - case 0x0069 : return "discard pages"; - case 0x006A : return "_GetNulPageHandle"; - case 0x006B : return "get first V86 page"; - case 0x006C : return "map physical address to linear address"; - case 0x006D : return "_GetAppFlatDSAlias"; - case 0x006E : return "_SelectorMapFlat"; - case 0x006F : return "_GetDemandPageInfo"; - case 0x0070 : return "_GetSetPageOutCount"; - case 0x0071 : return "hook V86 page"; - case 0x0072 : return "assign device V86 pages"; - case 0x0073 : return "deassign device V86 pages"; - case 0x0074 : return "get array of V86 pages for device"; - case 0x0075 : return "_SetNULPageAddr"; - case 0x0076 : return "allocate GDT selector"; - case 0x0077 : return "free GDT selector"; - case 0x0078 : return "allocate LDT selector"; - case 0x0079 : return "free LDT selector"; - case 0x007A : return "_BuildDescriptorDWORDs"; - case 0x007B : return "get descriptor"; - case 0x007C : return "set descriptor"; - case 0x007D : return "toggle HMA"; - case 0x007E : return "get fault hook addresses"; - case 0x007F : return "hook V86 fault"; - case 0x0080 : return "hook PM fault"; - case 0x0081 : return "hook VMM fault"; - case 0x0082 : return "begin nested V86 execution"; - case 0x0083 : return "begin nested execution"; - case 0x0084 : return "execute V86-mode interrupt"; - case 0x0085 : return "resume execution"; - case 0x0086 : return "end nested execution"; - case 0x0087 : return "allocate PM application callback area"; - case 0x0088 : return "get current PM application callback area"; - case 0x0089 : return "set V86 execution mode"; - case 0x008A : return "set PM execution mode"; - case 0x008B : return "begin using locked PM stack"; - case 0x008C : return "end using locked PM stack"; - case 0x008D : return "save client state"; - case 0x008E : return "restore client state"; - case 0x008F : return "execute VxD interrupt"; - case 0x0090 : return "hook device service"; - case 0x0091 : return "hook device V86 API"; - case 0x0092 : return "hook device PM API"; - case 0x0093 : return "system control (see also #02657)"; - case 0x0094 : return "simulate I/O"; - case 0x0095 : return "install multiple I/O handlers"; - case 0x0096 : return "install I/O handler"; - case 0x0097 : return "enable global trapping"; - case 0x0098 : return "enable local trapping"; - case 0x0099 : return "disable global trapping"; - case 0x009A : return "disable local trapping"; - case 0x009B : return "create list"; - case 0x009C : return "destroy list"; - case 0x009D : return "allocate list"; - case 0x009E : return "attach list"; - case 0x009F : return "attach list tail"; - case 0x00A0 : return "insert into list"; - case 0x00A1 : return "remove from list"; - case 0x00A2 : return "deallocate list"; - case 0x00A3 : return "get first item in list"; - case 0x00A4 : return "get next item in list"; - case 0x00A5 : return "remove first item in list"; - case 0x00A6 : return "add instance item"; - case 0x00A7 : return "allocate device callback area"; - case 0x00A8 : return "allocate global V86 data area"; - case 0x00A9 : return "allocate temporary V86 data area"; - case 0x00AA : return "free temporary V86 data area"; - case 0x00AB : return "get decimal integer from profile"; - case 0x00AC : return "convert decimal string to integer"; - case 0x00AD : return "get fixed-point number from profile"; - case 0x00AE : return "convert fixed-point string"; - case 0x00AF : return "get hex integer from profile"; - case 0x00B0 : return "convert hex string to integer"; - case 0x00B1 : return "get boolean value from profile"; - case 0x00B2 : return "convert boolean string"; - case 0x00B3 : return "get string from profile"; - case 0x00B4 : return "get next string from profile"; - case 0x00B5 : return "get environment string"; - case 0x00B6 : return "get exec path"; - case 0x00B7 : return "get configuration directory"; - case 0x00B8 : return "open file"; - case 0x00B9 : return "get PSP segment"; - case 0x00BA : return "get DOS vectors"; - case 0x00BB : return "get machine information"; - case 0x00BC : return "get/set HMA information"; - case 0x00BD : return "set system exit code"; - case 0x00BE : return "fatal error handler"; - case 0x00BF : return "fatal memory error"; - case 0x00C0 : return "update system clock"; - case 0x00C1 : return "test if debugger installed"; - case 0x00C2 : return "output debugger string"; - case 0x00C3 : return "output debugger character"; - case 0x00C4 : return "input debugger character"; - case 0x00C5 : return "debugger convert hex to binary"; - case 0x00C6 : return "debugger convert hex to decimal"; - case 0x00C7 : return "debugger test if valid handle"; - case 0x00C8 : return "validate client pointer"; - case 0x00C9 : return "test reentry"; - case 0x00CA : return "queue debugger string"; - case 0x00CB : return "log procedure call"; - case 0x00CC : return "debugger test current VM"; - case 0x00CD : return "get PM interrupt type"; - case 0x00CE : return "set PM interrupt type"; - case 0x00CF : return "get last updated system time"; - case 0x00D0 : return "get last updated VM execution time"; - case 0x00D1 : return "test if double-byte character-set lead byte"; - case 0x00D2 : return "_AddFreePhysPage"; - case 0x00D3 : return "_PageResetHandlePAddr"; - case 0x00D4 : return "_SetLastV86Page"; - case 0x00D5 : return "_GetLastV86Page"; - case 0x00D6 : return "_MapFreePhysReg"; - case 0x00D7 : return "_UnmapFreePhysReg"; - case 0x00D8 : return "_XchgFreePhysReg"; - case 0x00D9 : return "_SetFreePhysRegCalBk"; - case 0x00DA : return "get next arena (MCB)"; - case 0x00DB : return "get name of ugly TSR"; - case 0x00DC : return "get debug options"; - case 0x00DD : return "set physical HMA alias"; - case 0x00DE : return "_GetGlblRng0V86IntBase"; - case 0x00DF : return "add global V86 data area"; - case 0x00E0 : return "get/set detailed VM error"; - case 0x00E1 : return "Is_Debug_Chr"; - case 0x00E2 : return "clear monochrome screen"; - case 0x00E3 : return "output character to mono screen"; - case 0x00E4 : return "output string to mono screen"; - case 0x00E5 : return "set current position on mono screen"; - case 0x00E6 : return "get current position on mono screen"; - case 0x00E7 : return "get character from mono screen"; - case 0x00E8 : return "locate byte in ROM"; - case 0x00E9 : return "hook invalid page fault"; - case 0x00EA : return "unhook invalid page fault"; - case 0x00EB : return "set delete on exit file"; - case 0x00EC : return "close VM"; - case 0x00ED : return "Enable_Touch_1st_Meg"; - case 0x00EE : return "Disable_Touch_1st_Meg"; - case 0x00EF : return "install exception handler"; - case 0x00F0 : return "remove exception handler"; - case 0x00F1 : return "Get_Crit_Status_No_Block"; - case 0x00F2 : return "_Schedule_VM_RTI_Event"; - case 0x00F3 : return "_Trace_Out_Service"; - case 0x00F4 : return "_Debug_Out_Service"; - case 0x00F5 : return "_Debug_Flags_Service"; - case 0x00F6 : return "VMM add import module name"; - case 0x00F7 : return "VMM Add DDB"; - case 0x00F8 : return "VMM Remove DDB"; - case 0x00F9 : return "get thread time slice priority"; - case 0x00FA : return "set thread time slice priority"; - case 0x00FB : return "schedule thread event"; - case 0x00FC : return "cancel thread event"; - case 0x00FD : return "set thread timeout"; - case 0x00FE : return "set asynchronous timeout"; - case 0x00FF : return "_AllocatreThreadDataSlot"; - case 0x0100 : return "_FreeThreadDataSlot"; - case 0x0101 : return "create Mutex"; - case 0x0102 : return "destroy Mutex"; - case 0x0103 : return "get Mutex owner"; - case 0x0104 : return "call when thread switched"; - case 0x0105 : return "create thread"; - case 0x0106 : return "start thread"; - case 0x0107 : return "terminate thread"; - case 0x0108 : return "get current thread handle"; - case 0x0109 : return "test current thread handle"; - case 0x010A : return "Get_Sys_Thread_Handle"; - case 0x010B : return "Test_Sys_Thread_Handle"; - case 0x010C : return "Validate_Thread_Handle"; - case 0x010D : return "Get_Initial_Thread_Handle"; - case 0x010E : return "Test_Initial_Thread_Handle"; - case 0x010F : return "Debug_Test_Valid_Thread_Handle"; - case 0x0110 : return "Debug_Test_Cur_Thread"; - case 0x0111 : return "VMM_GetSystemInitState"; - case 0x0112 : return "Cancel_Call_When_Thread_Switched"; - case 0x0113 : return "Get_Next_Thread_Handle"; - case 0x0114 : return "Adjust_Thread_Exec_Priority"; - case 0x0115 : return "_Deallocate_Device_CB_Area"; - case 0x0116 : return "Remove_IO_Handler"; - case 0x0117 : return "Remove_Mult_IO_Handlers"; - case 0x0118 : return "unhook V86 interrupt chain"; - case 0x0119 : return "unhook V86 fault handler"; - case 0x011A : return "unhook PM fault handler"; - case 0x011B : return "unhook VMM fault handler"; - case 0x011C : return "unhook device service"; - case 0x011D : return "_PageReserve"; - case 0x011E : return "_PageCommit"; - case 0x011F : return "_PageDecommit"; - case 0x0120 : return "_PagerRegister"; - case 0x0121 : return "_PagerQuery"; - case 0x0122 : return "_PagerDeregister"; - case 0x0123 : return "_ContextCreate"; - case 0x0124 : return "_ContextDestroy"; - case 0x0125 : return "_PageAttach"; - case 0x0126 : return "_PageFlush"; - case 0x0127 : return "_SignalID"; - case 0x0128 : return "_PageCommitPhys"; - case 0x0129 : return "_Register_Win32_Services"; - case 0x012A : return "Cancel_Call_When_Not_Critical"; - case 0x012B : return "Cancel_Call_When_Idle"; - case 0x012C : return "Cancel_Call_When_Task_Switched"; - case 0x012D : return "_Debug_Printf_Service"; - case 0x012E : return "enter Mutex"; - case 0x012F : return "leave Mutex"; - case 0x0130 : return "simulate VM I/O"; - case 0x0131 : return "Signal_Semaphore_No_Switch"; - case 0x0132 : return "_MMSwitchContext"; - case 0x0133 : return "_MMModifyPermissions"; - case 0x0134 : return "_MMQuery"; - case 0x0135 : return "_EnterMustComplete"; - case 0x0136 : return "_LeaveMustComplete"; - case 0x0137 : return "_ResumeExecMustComplete"; - case 0x0138 : return "get thread termination status"; - case 0x0139 : return "_GetInstanceInfo"; - case 0x013A : return "_ExecIntMustComplete"; - case 0x013B : return "_ExecVxDIntMustComplete"; - case 0x013C : return "begin V86 serialization"; - case 0x013D : return "unhook V86 page"; - case 0x013E : return "VMM_GetVxDLocationList"; - case 0x013F : return "VMM_GetDDBList: get start of VxD chain"; - case 0x0140 : return "unhook NMI event"; - case 0x0141 : return "Get_Instanced_V86_Int_Vector"; - case 0x0142 : return "get or set real DOS PSP"; - case 0x0143 : return "call priority thread event"; - case 0x0144 : return "Get_System_Time_Address"; - case 0x0145 : return "Get_Crit_Status_Thread"; - case 0x0146 : return "Get_DDB"; - case 0x0147 : return "Directed_Sys_Control"; - case 0x0148 : return "_RegOpenKey"; - case 0x0149 : return "_RegCloseKey"; - case 0x014A : return "_RegCreateKey"; - case 0x014B : return "_RegDeleteKey"; - case 0x014C : return "_RegEnumKey"; - case 0x014D : return "_RegQueryValue"; - case 0x014E : return "_RegSetValue"; - case 0x014F : return "_RegDeleteValue"; - case 0x0150 : return "_RegEnumValue"; - case 0x0151 : return "_RegQueryValueEx"; - case 0x0152 : return "_RegSetValueEx"; - case 0x0153 : return "_CallRing3"; - case 0x0154 : return "Exec_PM_Int"; - case 0x0155 : return "_RegFlushKey"; - case 0x0156 : return "_PageCommitContig"; - case 0x0157 : return "_GetCurrentContext"; - case 0x0158 : return "_LocalizeSprintf"; - case 0x0159 : return "_LocalizeStackSprintf"; - case 0x015A : return "Call_Restricted_Event"; - case 0x015B : return "Cancel_Restricted_Event"; - case 0x015C : return "Register_PEF_Provider"; - case 0x015D : return "_GetPhysPageInfo"; - case 0x015E : return "_RegQueryInfoKey"; - case 0x015F : return "MemArb_Reserve_Pages"; - case 0x0160 : return "Time_Slice_Sys_VM_Idle"; - case 0x0161 : return "Time_Slice_Sleep"; - case 0x0162 : return "Boost_With_Decay"; - case 0x0163 : return "Set_Inversion_Pri"; - case 0x0164 : return "Reset_Inversion_Pri"; - case 0x0165 : return "Release_Inversion_Pri"; - case 0x0166 : return "Get_Thread_Win32_Pri"; - case 0x0167 : return "Set_Thread_Win32_Pri"; - case 0x0168 : return "Set_Thread_Static_Boost"; - case 0x0169 : return "Set_VM_Static_Boost"; - case 0x016A : return "Release_Inversion_Pri_ID"; - case 0x016B : return "Attach_Thread_To_Group"; - case 0x016C : return "Detach_Thread_From_Group"; - case 0x016D : return "Set_Group_Static_Boost"; - case 0x016E : return "_GetRegistryPath"; - case 0x016F : return "_GetRegistryKey"; - case 0x0170 : return "_CleanupNestedExec"; - case 0x0171 : return "_RegRemapPreDefKey"; - case 0x0172 : return "End_V86_Serialization"; - case 0x0173 : return "_Assert_Range"; - case 0x0174 : return "_Sprintf"; - case 0x0175 : return "_PageChangePager"; - case 0x0176 : return "_RegCreateDynKey"; - case 0x0177 : return "RegQMulti"; - case 0x0178 : return "Boost_Thread_With_VM"; - case 0x0179 : return "Get_Boot_Flags"; - case 0x017A : return "Set_Boot_Flags"; - case 0x017B : return "_lstrcpyn"; - case 0x017C : return "_lstrlen"; - case 0x017D : return "_lmemcpy"; - case 0x017E : return "_GetVxDName"; - case 0x017F : return "Force_Mutexes_Free"; - case 0x0180 : return "Restore_Forced_Mutexes"; - case 0x0181 : return "_AddReclaimableItem"; - case 0x0182 : return "_SetReclaimableItem"; - case 0x0183 : return "_EnumReclaimableItem"; - case 0x0184 : return "Time_Slice_Wake_Sys_VM"; - case 0x0185 : return "VMM_Replace_Global_Environment"; - case 0x0186 : return "Begin_Non_Serial_Nest_V86_Exec"; - case 0x0187 : return "Get_Nest_Exec_Status"; - case 0x0188 : return "Open_Boot_Log"; - case 0x0189 : return "Write_Boot_Log"; - case 0x018A : return "Close_Boot_Log"; - case 0x018B : return "EnableDisable_Boot_Log"; - case 0x018C : return "_Call_On_My_Stack"; - case 0x018D : return "Get_Inst_V86_Int_Vec_Base"; - case 0x018E : return "_lstrcmpi"; - case 0x018F : return "_strupr"; - case 0x0190 : return "Log_Fault_Call_Out"; - case 0x0191 : return "_AtEventTime"; - default: return "dunnoSV"; - } - case 0x0002: - switch (sv & 0x7fff) { - case 0x0000 : return "get version"; - case 0x0001 : return "DEBUG_Fault"; - case 0x0002 : return "DEBUG_CheckFault"; - case 0x0003 : return "DEBUG_LoadSyms"; - default: return "dunnoSV"; - } - case 0x0003: - switch (sv & 0x7fff) { - case 0x0000 : return "get version"; - case 0x0001 : return "virtualize IRQ"; - case 0x0002 : return "set interrupt request"; - case 0x0003 : return "clear interrupt request"; - case 0x0004 : return "physical EOI"; - case 0x0005 : return "get complete status"; - case 0x0006 : return "get status"; - case 0x0007 : return "test physical request"; - case 0x0008 : return "physically mask"; - case 0x0009 : return "physically unmask"; - case 0x000A : return "set automatic masking"; - case 0x000B : return "get IRQ complete status"; - case 0x000C : return "convert handle to IRQ"; - case 0x000D : return "convert IRQ to interrupt"; - case 0x000E : return "convert interrupt to IRQ"; - case 0x000F : return "call on hardware interrupt"; - case 0x0010 : return "force default owner"; - case 0x0011 : return "force default behavior"; - case 0x0012 : return "VPICD_Auto_Mask_At_Inst_Swap"; - case 0x0013 : return "VPICD_Begin_Inst_Page_Swap"; - case 0x0014 : return "VPICD_End_Inst_Page_Swap"; - case 0x0015 : return "VPICD_Virtual_EOI"; - case 0x0016 : return "VPICD_Get_Virtualization_Count"; - case 0x0017 : return "VPICD_Post_Sys_Critical_Init"; - case 0x0018 : return "VPICD_VM_SlavePIC_Mask_Change"; - default: return "dunnoSV"; - } - case 0x0004: - switch (sv & 0x7fff) { - case 0x0000 : return "get version"; - case 0x0001 : return "virtualize channel"; - case 0x0002 : return "get region information"; - case 0x0003 : return "set region information"; - case 0x0004 : return "get virtual state"; - case 0x0005 : return "set virtual state"; - case 0x0006 : return "set physical state"; - case 0x0007 : return "mask channel"; - case 0x0008 : return "unmask channel"; - case 0x0009 : return "lock DMA region"; - case 0x000A : return "unlock DMA region"; - case 0x000B : return "scatter lock"; - case 0x000C : return "scatter unlock"; - case 0x000D : return "reserve buffer space"; - case 0x000E : return "request buffer"; - case 0x000F : return "release buffer"; - case 0x0010 : return "copy to buffer"; - case 0x0011 : return "copy from buffer"; - case 0x0012 : return "default handler"; - case 0x0013 : return "disable translation"; - case 0x0014 : return "enable translation"; - case 0x0015 : return "get EISA address mode"; - case 0x0016 : return "set EISA address mode"; - case 0x0017 : return "unlock DMA region (ND)"; - case 0x0018 : return "VDMAD_Phys_Mask_Channel"; - case 0x0019 : return "VDMAD_Phys_Unmask_Channel"; - case 0x001A : return "VDMAD_Unvirtualize_Channel"; - case 0x001B : return "VDMAD_Set_IO_Address"; - case 0x001C : return "VDMAD_Get_Phys_Count"; - case 0x001D : return "VDMAD_Get_Phys_Status"; - case 0x001E : return "VDMAD_Get_Max_Phys_Page"; - case 0x001F : return "VDMAD_Set_Channel_Callbacks"; - case 0x0020 : return "VDMAD_Get_Virt_Count"; - case 0x0021 : return "VDMAD_Set_Virt_Count"; - default: return "dunnoSV"; - } - case 0x0005: - switch (sv & 0x7fff) { - case 0x0000 : return "get version"; - case 0x0001 : return "update system clock"; - case 0x0002 : return "get interrupt period"; - case 0x0003 : return "begin minimum interrupt period"; - case 0x0004 : return "end minimum interrupt period"; - case 0x0005 : return "disable trapping"; - case 0x0006 : return "enable trapping"; - case 0x0007 : return "get real time"; - case 0x0008 : return "VTD_Get_Date_And_Time"; - case 0x0009 : return "VTD_Adjust_VM_Count"; - case 0x000A : return "VTD_Delay"; - default: return "dunnoSV"; - } - case 0x0006: - switch (sv & 0x7fff) { - case 0x0000 : return "get version"; - case 0x0001 : return "allocate V86 pages"; - case 0x0002 : return "set EMS and XMS limits"; - case 0x0003 : return "get EMS and XMS limits"; - case 0x0004 : return "set mapping information"; - case 0x0005 : return "get mapping information"; - case 0x0006 : return "Xlat API"; - case 0x0007 : return "load client pointer"; - case 0x0008 : return "allocate buffer"; - case 0x0009 : return "free buffer"; - case 0x000A : return "get Xlat buffer state"; - case 0x000B : return "set Xlat buffer state"; - case 0x000C : return "get VM flat selector"; - case 0x000D : return "map pages"; - case 0x000E : return "free page map region"; - case 0x000F : return "_LocalGlobalReg"; - case 0x0010 : return "get page status"; - case 0x0011 : return "set local A20"; - case 0x0012 : return "reset base pages"; - case 0x0013 : return "set available mapped pages"; - case 0x0014 : return "V86MMGR_NoUMBInitCalls"; - case 0x0015 : return "V86MMGR_Get_EMS_XMS_Avail"; - case 0x0016 : return "V86MMGR_Toggle_HMA"; - case 0x0017 : return "V86MMGR_Dev_Init"; - case 0x0018 : return "V86MMGR_Alloc_UM_Page"; - default: return "dunnoSV"; - } - case 0x0007: - switch (sv & 0x7fff) { - case 0x0000 : return "get version"; - case 0x0001 : return "test create"; - case 0x0002 : return "create swap file"; - case 0x0003 : return "destroy swap file"; - case 0x0004 : return "in"; - case 0x0005 : return "out"; - case 0x0006 : return "test if I/O valid"; - case 0x0007 : return "Read_Or_Write"; - case 0x0008 : return "Grow_File"; - case 0x0009 : return "Init_File"; - default: return "dunnoSV"; - } - case 0x000a: - switch (sv & 0x7fff) { - case 0x0000 : return "get version"; - case 0x0001 : return "PIF state"; - case 0x0002 : return "get GrabRtn"; - case 0x0003 : return "hide cursor"; - case 0x0004 : return "set VM type"; - case 0x0005 : return "get ModTime"; - case 0x0006 : return "set HCurTrk"; - case 0x0007 : return "message clear screen"; - case 0x0008 : return "message foreground color"; - case 0x0009 : return "message background color"; - case 0x000A : return "message output text"; - case 0x000B : return "message set cursor position"; - case 0x000C : return "query access"; - case 0x000D : return "VDD_Check_Update_Soon"; - case 0x000E : return "VDD_Get_Mini_Dispatch_Table"; - case 0x000F : return "VDD_Register_Virtual_Port"; - case 0x0010 : return "VDD_Get_VM_Info"; - case 0x0011 : return "VDD_Get_Special_VM_IDs"; - case 0x0012 : return "VDD_Register_Extra_Screen_Selector"; - case 0x0013 : return "VDD_Takeover_VGA_Port"; - default: return "dunnoSV"; - } - case 0x000c: - switch (sv & 0x7fff) { - case 0x0000 : return "get version"; - case 0x0001 : return "set mouse type"; - case 0x0002 : return "get mouse owner"; - case 0x0003 : return "VMOUSE_Post_Pointer_Message"; - case 0x0004 : return "VMOUSE_Set_Cursor_Proc"; - case 0x0005 : return "VMOUSE_Call_Cursor_Proc"; - case 0x0006 : return "VMOUSE_Set_Mouse_Data~Get_Mouse_Data"; - case 0x0007 : return "VMOUSE_Manipulate_Pointer_Message"; - case 0x0008 : return "VMOUSE_Set_Middle_Button"; - case 0x0009 : return "VMD_Set_Middle_Button"; - case 0x000A : return "VMD_Enable_Disable_Mouse_Events"; - case 0x000B : return "VMD_Post_Absolute_Pointer_Message"; - default: return "dunnoSV"; - } - case 0x000d: - switch (sv & 0x7fff) { - case 0x0000 : return "get version"; - case 0x0001 : return "define hotkey"; - case 0x0002 : return "remove hotkey"; - case 0x0003 : return "locally enable hotkey"; - case 0x0004 : return "locally disable hotkey"; - case 0x0005 : return "reflect hotkey"; - case 0x0006 : return "cancel hotkey state"; - case 0x0007 : return "force keys"; - case 0x0008 : return "get keyboard owner"; - case 0x0009 : return "define paste mode"; - case 0x000A : return "start pasting"; - case 0x000B : return "cancel paste"; - case 0x000C : return "get message key"; - case 0x000D : return "peek message key"; - case 0x000E : return "flush message key queue"; - case 0x000F : return "VKD_Enable_Keyboard"; - case 0x0010 : return "VKD_Disable_Keyboard"; - case 0x0011 : return "VKD_Get_Shift_State"; - case 0x0012 : return "VKD_Filter_Keyboard_Input"; - case 0x0013 : return "VKD_Put_Byte"; - case 0x0014 : return "VKD_Set_Shift_State"; - default: return "dunnoSV"; - } - case 0x000e: - switch (sv & 0x7fff) { - case 0x0000 : return "get version"; - case 0x0001 : return "set port global"; - case 0x0002 : return "get focus"; - case 0x0003 : return "virtualize port"; - case 0x0004 : return "VCD_Acquire_Port"; - case 0x0005 : return "VCD_Free_Port"; - case 0x0006 : return "VCD_Acquire_Port_Windows_Style"; - case 0x0007 : return "VCD_Free_Port_Windows_Style"; - case 0x0008 : return "VCD_Steal_Port_Windows_Style"; - case 0x0009 : return "VCD_Find_COM_Index"; - case 0x000A : return "VCD_Set_Port_Global_Special"; - case 0x000B : return "VCD_Virtualize_Port_Dynamic"; - case 0x000C : return "VCD_Unvirtualize_Port_Dynamic"; - default: return "dunnoSV"; - } - case 0x0010: - switch (sv & 0x7fff) { - case 0x0000 : return "get version"; - case 0x0001 : return "register device"; - case 0x0002 : return "find INT 13 drive"; - case 0x0003 : return "get device list"; - case 0x0004 : return "send command"; - case 0x0005 : return "command complete"; - case 0x0006 : return "synchronous command"; - case 0x0007 : return "IOS_Register"; - case 0x0008 : return "IOS_Requestor_Service"; - case 0x0009 : return "IOS_Exclusive_Access"; - case 0x000A : return "IOS_Send_Next_Command"; - case 0x000B : return "IOS_Set_Async_Time_Out"; - case 0x000C : return "IOS_Signal_Semaphore_No_Switch"; - case 0x000D : return "IOSIdleStatus"; - case 0x000E : return "IOSMapIORSToI24"; - case 0x000F : return "IOSMapIORSToI21"; - case 0x0010 : return "PrintLog"; - default: return "dunnoSV"; - } - case 0x0011: - switch (sv & 0x7fff) { - case 0x0000 : return "get_version"; - case 0x0001 : return "get_virt_state"; - case 0x0002 : return "set_virt_state"; - case 0x0003 : return "get_cr0_state"; - case 0x0004 : return "set_cr0_state"; - case 0x0005 : return "get_thread_state"; - case 0x0006 : return "set_thread_state"; - case 0x0007 : return "get_FP_instruction_size"; - case 0x0008 : return "set_thread_precision"; - default: return "dunnoSV"; - } - case 0x0012: - switch (sv & 0x7fff) { - case 0x0000 : return "get EBIOS version"; - case 0x0001 : return "get unused memory"; - default: return "dunnoSV"; - } - case 0x0015: - switch (sv & 0x7fff) { - case 0x0000 : return "get version"; - case 0x0001 : return "set exec VM data"; - case 0x0002 : return "coyp VM drive state"; - case 0x0003 : return "execute VM"; - case 0x0004 : return "get InDOS pointer"; - case 0x0005 : return "add device"; - case 0x0006 : return "remove device"; - case 0x0007 : return "instance device"; - case 0x0008 : return "get DOS critical status"; - case 0x0009 : return "enable InDOS polling"; - case 0x000A : return "backfill allowed"; - case 0x000B : return "LocalGlobalReg"; - case 0x000C : return "Init_UMB_Area"; - case 0x000D : return "Begin_V86_App"; - case 0x000E : return "End_V86_App"; - case 0x000F : return "Alloc_Local_Sys_VM_Mem"; - case 0x0010 : return "DOSMGR_Grow_CDSs"; - case 0x0011 : return "DOSMGR_Translate_Server_DOS_Call"; - case 0x0012 : return "DOSMGR_MMGR_PSP_Change_Notifier"; - default: return "dunnoSV"; - } - case 0x0017: - switch (sv & 0x7fff) { - case 0x0000 : return "get version"; - case 0x0001 : return "resolve contention"; - case 0x0002 : return "event"; - case 0x0003 : return "SYSMODAL message"; - case 0x0004 : return "message"; - case 0x0005 : return "get VM information"; - case 0x0006 : return "_SHELL_PostMessage"; - case 0x0007 : return "_SHELL_WinExec"; - case 0x0008 : return "_SHELL_CallDll"; - case 0x0009 : return "SHELL_OpenClipboard"; - case 0x000A : return "SHELL_SetClipboardData"; - case 0x000B : return "SHELL_GetClipboardData"; - case 0x000C : return "SHELL_CloseClipboard"; - case 0x000D : return "_SHELL_Install_Taskman_Hooks"; - case 0x000E : return "SHELL_Hook_Properties"; - case 0x000F : return "SHELL_Unhook_Properties"; - case 0x0010 : return "SHELL_OEMKeyScan"; - case 0x0011 : return "SHELL_Update_User_Activity"; - case 0x0012 : return "_SHELL_UnhookSystemBroadcast"; - case 0x0013 : return "_SHELL_LocalAllocEx"; - case 0x0014 : return "_SHELL_LocalFree"; - case 0x0015 : return "_SHELL_LoadLibrary"; - case 0x0016 : return "_SHELL_FreeLibrary"; - case 0x0017 : return "_SHELL_GetProcAddress"; - case 0x0018 : return "_SHELL_CallDll"; - case 0x0019 : return "_SHELL_SuggestSingleMSDOSMode"; - case 0x001A : return "SHELL_CheckHotkeyAllowed"; - case 0x001B : return "_SHELL_GetDOSAppInfo"; - default: return "dunnoSV"; - } - case 0x0018: - switch (sv & 0x7fff) { - case 0x0000 : return "get version"; - case 0x0001 : return "enable/disable"; - case 0x0002 : return "reset detection"; - case 0x0003 : return "check idle"; - default: return "dunnoSV"; - } - case 0x001a: - switch (sv & 0x7fff) { - case 0x0000 : return "get version"; - case 0x0001 : return "send FILESYSCHANGE"; - case 0x0002 : return "do PSP adjust"; - default: return "dunnoSV"; - } - case 0x001b: - case 0x001c: - switch (sv & 0x7fff) { - case 0x0000 : return "get version"; - default: return "dunnoSV"; - } - case 0x0021: - switch (sv & 0x7fff) { - case 0x0000 : return "get version"; - case 0x0001 : return "init file"; - case 0x0002 : return "clean up"; - case 0x0003 : return "grow file"; - case 0x0004 : return "read or write"; - case 0x0005 : return "cancel"; - case 0x0006 : return "test I/O valid"; - case 0x0007 : return "Get_Size_Info"; - case 0x0008 : return "Set_Async_Manager"; - case 0x0009 : return "Call_Async_Manager"; - default: return "dunnoSV"; - } - case 0x0027: - switch (sv & 0x7fff) { - case 0x0000 : return "VXDLDR_Get_Version"; - case 0x0001 : return "VXDLDR_LoadDevice"; - case 0x0002 : return "VXDLDR_UnloadDevice"; - case 0x0003 : return "VXDLDR_DevInitSucceeded"; - case 0x0004 : return "VXDLDR_DevInitFailed"; - case 0x0005 : return "VXDLDR_GetDeviceList"; - case 0x0006 : return "VXDLDR_UnloadMe"; - case 0x0007 : return "PELDR_LoadModule"; - case 0x0008 : return "PELDR_GetModuleHandle"; - case 0x0009 : return "PELDR_GetModuleUsage"; - case 0x000A : return "PELDR_GetEntryPoint"; - case 0x000B : return "PELDR_GetProcAddress"; - case 0x000C : return "PELDR_AddExportTable"; - case 0x000D : return "PELDR_RemoveExportTable"; - case 0x000E : return "PELDR_FreeModule"; - case 0x000F : return "VXDLDR_Notify"; - case 0x0010 : return "_PELDR_InitCompleted"; - case 0x0011 : return "_PELDR_LoadModuleEx"; - default: return "dunnoSV"; - } - case 0x002A: - switch (sv & 0x7fff) { - case 0x0000 : return "VWin32_Get_Version"; - case 0x0001 : return "VWin32_Wake_For_Event"; - case 0x0002 : return "_VWIN32_QueueUserApc"; - case 0x0003 : return "_VWIN32_Get_Thread_Context"; - case 0x0004 : return "_VWIN32_Set_Thread_Context"; - case 0x0005 : return "_VWIN32_CopyMem"; - case 0x0006 : return "_VWIN32_BlockForTermination"; - case 0x0007 : return "_VWIN32_Emulate_Npx"; - case 0x0008 : return "_VWIN32_CheckDelayedNpxTrap"; - case 0x0009 : return "VWIN32_EnterCrstR0"; - case 0x000A : return "VWIN32_LeaveCrstR0"; - case 0x000B : return "_VWIN32_FaultPopup"; - case 0x000C : return "VWIN32_GetContextHandle"; - case 0x000D : return "VWIN32_GetCurrentProcessHandle"; - case 0x000E : return "_VWIN32_SetWin32Event"; - case 0x000F : return "_VWIN32_PulseWin32Event"; - case 0x0010 : return "_VWIN32_ResetWin32Event"; - case 0x0011 : return "_VWIN32_WaitSingleObject"; - case 0x0012 : return "_VWIN32_WaitMultipleObjects"; - case 0x0013 : return "_VWIN32_CreateRing0Thread"; - case 0x0014 : return "_VWIN32_CloseVxDHandle"; - case 0x0015 : return "VWIN32_ActiveTimeBiasSet"; - case 0x0016 : return "VWIN32_GetCurrentDirectory"; - case 0x0017 : return "VWIN32_BlueScreenPopup"; - case 0x0018 : return "VWIN32_TerminateApp"; - case 0x0019 : return "_VWIN32_QueueKernelAPC"; - case 0x001A : return "VWIN32_SysErrorBox"; - case 0x001B : return "_VWIN32_IsClientWin32"; - case 0x001C : return "VWIN32_IFSRIPWhenLev2Taken"; - default: return "dunnoSV"; - } - case 0x002b: - switch (sv & 0x7fff) { - case 0x0000 : return "VCOMM_Get_Version"; - case 0x0001 : return "_VCOMM_Register_Port_Driver"; - case 0x0002 : return "_VCOMM_Acquire_Port"; - case 0x0003 : return "_VCOMM_Release_Port"; - case 0x0004 : return "_VCOMM_OpenComm"; - case 0x0005 : return "_VCOMM_SetCommState"; - case 0x0006 : return "_VCOMM_GetCommState"; - case 0x0007 : return "_VCOMM_SetupComm"; - case 0x0008 : return "_VCOMM_TransmitCommChar"; - case 0x0009 : return "_VCOMM_CloseComm"; - case 0x000A : return "_VCOMM_GetCommQueueStatus"; - case 0x000B : return "_VCOMM_ClearCommError"; - case 0x000C : return "_VCOMM_GetModemStatus"; - case 0x000D : return "_VCOMM_GetCommProperties"; - case 0x000E : return "_VCOMM_EscapeCommFunction"; - case 0x000F : return "_VCOMM_PurgeComm"; - case 0x0010 : return "_VCOMM_SetCommEventMask"; - case 0x0011 : return "_VCOMM_GetCommEventMask"; - case 0x0012 : return "_VCOMM_WriteComm"; - case 0x0013 : return "_VCOMM_ReadComm"; - case 0x0014 : return "_VCOMM_EnableCommNotification"; - case 0x0015 : return "_VCOMM_GetLastError"; - case 0x0016 : return "_VCOMM_Steal_Port"; - case 0x0017 : return "_VCOMM_SetReadCallBack"; - case 0x0018 : return "_VCOMM_SetWriteCallBack"; - case 0x0019 : return "_VCOMM_GetSetCommTimeouts"; - case 0x001A : return "_VCOMM_SetWriteRequest"; - case 0x001B : return "_VCOMM_SetReadRequest"; - case 0x001C : return "_VCOMM_Dequeue_Request"; - case 0x001D : return "_VCOMM_Dequeue_Request"; - case 0x001E : return "_VCOMM_Enumerate_DevNodes"; - case 0x001F : return "VCOMM_Map_Win32DCB_To_Ring0"; - case 0x0020 : return "VCOMM_Map_Ring0DCB_To_Win32"; - case 0x0021 : return "_VCOMM_Get_Contention_Handler"; - case 0x0022 : return "_VCOMM_Map_Name_To_Resource"; - default: return "dunnoSV"; - } - case 0x0033: - switch (sv & 0x7fff) { - case 0x0000 : return "_CONFIGMG_Get_Version"; - case 0x0001 : return "_CONFIGMG_Initialize"; - case 0x0002 : return "_CONFIGMG_Locate_DevNode"; - case 0x0003 : return "_CONFIGMG_Get_Parent"; - case 0x0004 : return "_CONFIGMG_Get_Child"; - case 0x0005 : return "_CONFIGMG_Get_Sibling"; - case 0x0006 : return "_CONFIGMG_Get_Device_ID_Size"; - case 0x0007 : return "_CONFIGMG_Get_Device_ID"; - case 0x0008 : return "_CONFIGMG_Get_Depth"; - case 0x0009 : return "_CONFIGMG_Get_Private_DWord"; - case 0x000A : return "_CONFIGMG_Set_Private_DWord"; - case 0x000B : return "_CONFIGMG_Create_DevNode"; - case 0x000C : return "_CONFIGMG_Query_Remove_SubTree"; - case 0x000D : return "_CONFIGMG_Remove_SubTree"; - case 0x000E : return "_CONFIGMG_Register_Device_Driver"; - case 0x000F : return "_CONFIGMG_Register_Enumerator"; - case 0x0010 : return "_CONFIGMG_Register_Arbitrator"; - case 0x0011 : return "_CONFIGMG_Deregister_Arbitrator"; - case 0x0012 : return "_CONFIGMG_Query_Arbitrator_Free_Size"; - case 0x0013 : return "_CONFIGMG_Query_Arbitrator_Free_Data"; - case 0x0014 : return "_CONFIGMG_Sort_NodeList"; - case 0x0015 : return "_CONFIGMG_Yield"; - case 0x0016 : return "_CONFIGMG_Lock"; - case 0x0017 : return "_CONFIGMG_Unlock"; - case 0x0018 : return "_CONFIGMG_Add_Empty_Log_Conf"; - case 0x0019 : return "_CONFIGMG_Free_Log_Conf"; - case 0x001A : return "_CONFIGMG_Get_First_Log_Conf"; - case 0x001B : return "_CONFIGMG_Get_Next_Log_Conf"; - case 0x001C : return "_CONFIGMG_Add_Res_Des"; - case 0x001D : return "_CONFIGMG_Modify_Res_Des"; - case 0x001E : return "_CONFIGMG_Free_Res_Des"; - case 0x001F : return "_CONFIGMG_Get_Next_Res_Des"; - case 0x0020 : return "_CONFIGMG_Get_Performance_Info"; - case 0x0021 : return "_CONFIGMG_Get_Res_Des_Data_Size"; - case 0x0022 : return "_CONFIGMG_Get_Res_Des_Data"; - case 0x0023 : return "_CONFIGMG_Process_Events_Now"; - case 0x0024 : return "_CONFIGMG_Create_Range_List"; - case 0x0025 : return "_CONFIGMG_Add_Range"; - case 0x0026 : return "_CONFIGMG_Delete_Range"; - case 0x0027 : return "_CONFIGMG_Test_Range_Available"; - case 0x0028 : return "_CONFIGMG_Dup_Range_List"; - case 0x0029 : return "_CONFIGMG_Free_Range_List"; - case 0x002A : return "_CONFIGMG_Invert_Range_List"; - case 0x002B : return "_CONFIGMG_Intersect_Range_List"; - case 0x002C : return "_CONFIGMG_First_Range"; - case 0x002D : return "_CONFIGMG_Next_Range"; - case 0x002E : return "_CONFIGMG_Dump_Range_List"; - case 0x002F : return "_CONFIGMG_Load_DLVxDs"; - case 0x0030 : return "_CONFIGMG_Get_DDBs"; - case 0x0031 : return "_CONFIGMG_Get_CRC_CheckSum"; - case 0x0032 : return "_CONFIGMG_Register_DevLoader"; - case 0x0033 : return "_CONFIGMG_Reenumerate_DevNode"; - case 0x0034 : return "_CONFIGMG_Setup_DevNode"; - case 0x0035 : return "_CONFIGMG_Reset_Children_Marks"; - case 0x0036 : return "_CONFIGMG_Get_DevNode_Status"; - case 0x0037 : return "_CONFIGMG_Remove_Unmarked_Children"; - case 0x0038 : return "_CONFIGMG_ISAPNP_To_CM"; - case 0x0039 : return "_CONFIGMG_CallBack_Device_Driver"; - case 0x003A : return "_CONFIGMG_CallBack_Enumerator"; - case 0x003B : return "_CONFIGMG_Get_Alloc_Log_Conf"; - case 0x003C : return "_CONFIGMG_Get_DevNode_Key_Size"; - case 0x003D : return "_CONFIGMG_Get_DevNode_Key"; - case 0x003E : return "_CONFIGMG_Read_Registry_Value"; - case 0x003F : return "_CONFIGMG_Write_Registry_Value"; - case 0x0040 : return "_CONFIGMG_Disable_DevNode"; - case 0x0041 : return "_CONFIGMG_Enable_DevNode"; - case 0x0042 : return "_CONFIGMG_Move_DevNode"; - case 0x0043 : return "_CONFIGMG_Set_Bus_Info"; - case 0x0044 : return "_CONFIGMG_Get_Bus_Info"; - case 0x0045 : return "_CONFIGMG_Set_HW_Prof"; - case 0x0046 : return "_CONFIGMG_Recompute_HW_Prof"; - case 0x0047 : return "_CONFIGMG_Query_Change_HW_Prof"; - case 0x0048 : return "_CONFIGMG_Get_Device_Driver_Private_DWord"; - case 0x0049 : return "_CONFIGMG_Set_Device_Driver_Private_DWord"; - case 0x004A : return "_CONFIGMG_Get_HW_Prof_Flags"; - case 0x004B : return "_CONFIGMG_Set_HW_Prof_Flags"; - case 0x004C : return "_CONFIGMG_Read_Registry_Log_Confs"; - case 0x004D : return "_CONFIGMG_Run_Detection"; - case 0x004E : return "_CONFIGMG_Call_At_Appy_Time"; - case 0x004F : return "_CONFIGMG_Fail_Change_HW_Prof"; - case 0x0050 : return "_CONFIGMG_Set_Private_Problem"; - case 0x0051 : return "_CONFIGMG_Debug_DevNode"; - case 0x0052 : return "_CONFIGMG_Get_Hardware_Profile_Info"; - case 0x0053 : return "_CONFIGMG_Register_Enumerator_Function"; - case 0x0054 : return "_CONFIGMG_Call_Enumerator_Function"; - case 0x0055 : return "_CONFIGMG_Add_ID"; - case 0x0056 : return "_CONFIGMG_Find_Range"; - case 0x0057 : return "_CONFIGMG_Get_Global_State"; - case 0x0058 : return "_CONFIGMG_Broadcast_Device_Change_Message"; - case 0x0059 : return "_CONFIGMG_Call_DevNode_Handler"; - case 0x005A : return "_CONFIGMG_Remove_Reinsert_All"; - default: return "dunnoSV"; - } - case 0x048B: - switch (sv & 0x7fff) { - case 0x0000 : return "VXDLDR_Get_Version"; - case 0x0001 : return "VCACHE_Register"; - case 0x0002 : return "VCACHE_GetSize"; - case 0x0003 : return "VCACHE_CheckAvail"; - case 0x0004 : return "VCACHE_FindBlock"; - case 0x0005 : return "VCACHE_FreeBlock"; - case 0x0006 : return "VCACHE_MakeMRU"; - case 0x0007 : return "VCACHE_Hold"; - case 0x0008 : return "VCACHE_Unhold"; - case 0x0009 : return "VCACHE_Enum"; - case 0x000A : return "VCACHE_TestHandle"; - case 0x000B : return "VCACHE_VerifySums"; - case 0x000C : return "VCACHE_RecalcSums"; - case 0x000D : return "VCACHE_TestHold"; - case 0x000E : return "VCACHE_GetStats"; - case 0x000F : return "VCache_Deregister"; - case 0x0010 : return "VCache_AdjustMinimum"; - case 0x0011 : return "VCache_SwapBuffers"; - case 0x0012 : return "VCache_RelinquishPage"; - case 0x0013 : return "VCache_UseThisPage"; - case 0x0014 : return "_VCache_CreateLookupCache"; - case 0x0015 : return "_VCache_CloseLookupCache"; - case 0x0016 : return "_VCache_DeleteLookupCache"; - case 0x0017 : return "_VCache_Lookup"; - case 0x0018 : return "_VCache_UpdateLookup"; - default: return "dunnoSV"; - } - default: return "dunnoNR"; - } -} - - Bit8u lastint; void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { lastint=num; -// if ((num!=0x16) && (num!=0x1a) && (num!=0x28) && (num!=0x2a) && (num!=0x13)) LOG_MSG("INT %x EAX:%04X ECX:%04X EDX:%04X EBX:%04X CS:%04X EIP:%08X SS:%04X ESP:%08X",num,reg_eax,reg_ecx,reg_edx,reg_ebx,SegValue(cs),reg_eip,SegValue(ss),reg_esp); - if ((num==0x20) && (cpu.pmode)) { - PhysPt csip20 = SegPhys(cs)+reg_eip; - Bitu sv = mem_readw(csip20+2); - Bitu nr = mem_readw(csip20+4); - LOG_MSG("VxD service %s, %s (%X:%X)",translateVXDid(nr),translateVXDservice(nr,sv),nr,sv); - } #if C_DEBUG switch (num) { case 0xcd: @@ -2421,14 +1392,10 @@ bool CPU_LTR(Bitu selector) { return false; } -Bitu gdt_count=0; - void CPU_LGDT(Bitu limit,Bitu base) { - LOG(LOG_CPU,LOG_NORMAL)("GDT Set to base:%X limit:%X count %d",base,limit,gdt_count++); + LOG(LOG_CPU,LOG_NORMAL)("GDT Set to base:%X limit:%X",base,limit); cpu.gdt.SetLimit(limit); cpu.gdt.SetBase(base); -// if (gdt_count>20) DEBUG_EnableDebugger(); -// DEBUG_EnableDebugger(); } void CPU_LIDT(Bitu limit,Bitu base) { From 47cde6a97e62362af7e259a2d16ecbde7d9d1c58 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 18 Aug 2005 10:51:57 +0000 Subject: [PATCH 2193/4131] Added patch 1154355 from Thomas Weidner. Marks memory executable in the dynamic core under 64 bits linux Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2277 --- configure.in | 7 +++++++ src/cpu/core_dyn_x86.cpp | 9 +++++++++ src/cpu/core_dyn_x86/cache.h | 11 +++++++++++ 3 files changed, 27 insertions(+) diff --git a/configure.in b/configure.in index fa36b356..7cc83ea8 100644 --- a/configure.in +++ b/configure.in @@ -244,6 +244,13 @@ 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([ diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 71605085..e66df13f 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -26,6 +26,15 @@ #include #include +#if (C_HAVE_MPROTECT) +#include + +#include +#ifndef PAGESIZE +#define PAGESIZE 4096 +#endif +#endif /* C_HAVE_MPROTECT */ + #include "callback.h" #include "regs.h" #include "mem.h" diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 9bdccb18..9bd30b5e 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -42,10 +42,17 @@ static struct { CodePageHandler * last_page; } cache; +#if (C_HAVE_MPROTECT) +static Bit8u cache_code_link_blocks[2][16] GCC_ATTRIBUTE(aligned(PAGESIZE)); +static Bit8u cache_code[CACHE_TOTAL+CACHE_MAXSIZE] GCC_ATTRIBUTE(aligned(PAGESIZE)); +#else static Bit8u cache_code_link_blocks[2][16]; static Bit8u cache_code[CACHE_TOTAL+CACHE_MAXSIZE]; +#endif + static CacheBlock cache_blocks[CACHE_BLOCKS]; static CacheBlock link_blocks[2]; + class CodePageHandler :public PageHandler { public: CodePageHandler() {} @@ -338,6 +345,10 @@ static void gen_return(BlockReturn retcode); static void cache_init(void) { Bits i; memset(&cache_blocks,0,sizeof(cache_blocks)); +#if (C_HAVE_MPROTECT) + mprotect(cache_code,sizeof(cache_code),PROT_WRITE|PROT_READ|PROT_EXEC); + mprotect(cache_code_link_blocks,sizeof(cache_code_link_blocks),PROT_WRITE|PROT_READ|PROT_EXEC); +#endif cache.block.free=&cache_blocks[0]; for (i=0;i Date: Thu, 18 Aug 2005 10:58:41 +0000 Subject: [PATCH 2194/4131] Added patch 1260609 from Vasyl Tsvirkunov. Fixes Font Request information to return the correct value in cx Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2278 --- src/ints/int10.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 5357ad0e..40abef9b 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -232,7 +232,6 @@ graphics_chars: RealPt int_1f=RealGetVec(0x1f); SegSet16(es,RealSeg(int_1f)); reg_bp=RealOff(int_1f); - reg_cx=8; } break; case 0x01: /* interupt 0x43 vector */ @@ -240,33 +239,28 @@ graphics_chars: RealPt int_43=RealGetVec(0x43); SegSet16(es,RealSeg(int_43)); reg_bp=RealOff(int_43); - reg_cx=8; } break; case 0x02: /* font 8x14 */ SegSet16(es,RealSeg(int10.rom.font_14)); reg_bp=RealOff(int10.rom.font_14); - reg_cx=14; break; case 0x03: /* font 8x8 first 128 */ SegSet16(es,RealSeg(int10.rom.font_8_first)); reg_bp=RealOff(int10.rom.font_8_first); - reg_cx=8; break; case 0x04: /* font 8x8 second 128 */ SegSet16(es,RealSeg(int10.rom.font_8_second)); reg_bp=RealOff(int10.rom.font_8_second); - reg_cx=8; break; case 0x06: /* font 8x16 */ SegSet16(es,RealSeg(int10.rom.font_16)); reg_bp=RealOff(int10.rom.font_16); - reg_cx=16; break; default: - reg_cx=16; - LOG(LOG_INT10,LOG_ERROR)("Fucntion 11:30 Request for font %2X",reg_bh); + LOG(LOG_INT10,LOG_ERROR)("Function 11:30 Request for font %2X",reg_bh); } + reg_cx=real_readw(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); reg_dl=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS); break; default: From 91bff5af1ef066d66084f97557ef219cbeb0fce3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 18 Aug 2005 11:01:10 +0000 Subject: [PATCH 2195/4131] Added patch 1261703 from Vasyl Tsvirkunov. Fixes some shaking effects by implementing more correct pixel panning logic Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2279 --- src/hardware/vga_draw.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 9622bd65..5a8e2563 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -215,7 +215,9 @@ static void VGA_DrawPart(Bitu lines) { vga.draw.address+=vga.draw.address_add; } if (vga.draw.split_line==vga.draw.lines_done) { - vga.draw.address=0;vga.draw.panning=0; + vga.draw.address=0; + if(vga.attr.mode_control&0x20) + vga.draw.panning=0; vga.draw.address_line=0; } } From 6348c925f3c7ea33beb89fa3e671304ed2cea289 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 19 Aug 2005 07:13:34 +0000 Subject: [PATCH 2196/4131] Add patch 1263194 from prompt. Fixes set attribute on isos. Changed makedir and findfirst to return an error if directory ends on backslash. Changed makedir to give an error when the directory allready exists instead of silently saying it succeeded. This all fixes bug 946881 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2280 --- src/dos/dos_files.cpp | 24 +++++++++++++++++++++--- src/dos/drive_local.cpp | 11 +++++------ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index c386751b..0b69a627 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.64 2005-08-10 16:46:15 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.65 2005-08-19 07:13:34 qbix79 Exp $ */ #include #include @@ -198,8 +198,20 @@ bool DOS_ChangeDir(char * dir) { bool DOS_MakeDir(char * dir) { Bit8u drive;char fulldir[DOS_PATHLENGTH]; + size_t len = strlen(dir); + if(!len || dir[len-1] == '\\') { + DOS_SetError(DOSERR_PATH_NOT_FOUND); + return false; + } if (!DOS_MakeName(dir,fulldir,&drive)) return false; - return Drives[drive]->MakeDir(fulldir); + if(Drives[drive]->MakeDir(fulldir)) return true; + + /* Determine reason for failing */ + if(Drives[drive]->TestDir(fulldir)) + DOS_SetError(DOSERR_ACCESS_DENIED); + else + DOS_SetError(DOSERR_PATH_NOT_FOUND); + return false; } bool DOS_RemoveDir(char * dir) { @@ -245,6 +257,12 @@ bool DOS_FindFirst(char * search,Bit16u attr,bool fcb_findfirst) { DOS_DTA dta(dos.dta()); Bit8u drive;char fullsearch[DOS_PATHLENGTH]; char dir[DOS_PATHLENGTH];char pattern[DOS_PATHLENGTH]; + size_t len = strlen(search); + if(len && search[len - 1] == '\\') { + //Dark Forces installer + DOS_SetError(DOSERR_NO_MORE_FILES); + return false; + } if (!DOS_MakeName(search,fullsearch,&drive)) return false; /* Split the search in dir and pattern */ char * find_last; @@ -510,7 +528,7 @@ bool DOS_SetFileAttr(char * name,Bit16u attr) Bit16u attrTemp; char fullname[DOS_PATHLENGTH];Bit8u drive; if (!DOS_MakeName(name,fullname,&drive)) return false; - if (strcmp(Drives[drive]->GetInfo(),"CDRom.")==0) { + if (strcmp(Drives[drive]->GetInfo(),"CDRom.")==0 || strcmp(Drives[drive]->GetInfo(),"isoDrive")==0) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 8e6d144b..a38e66af 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.60 2005-08-11 18:57:48 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.61 2005-08-19 07:13:34 qbix79 Exp $ */ #include #include @@ -205,7 +205,6 @@ bool localDrive::FindNext(DOS_DTA & dta) { Bit8u find_attr; dta.GetSearchParams(srch_attr,srch_pattern); - Bitu id = dta.GetDirID(); again: @@ -279,8 +278,8 @@ bool localDrive::MakeDir(char * dir) { int temp=mkdir(dirCache.GetExpandName(newdir),0700); #endif if (temp==0) dirCache.CacheOut(newdir,true); - // if dir already exists, return success too. - return (temp==0) || ((temp!=0) && (errno==EEXIST)); + + return (temp==0);// || ((temp!=0) && (errno==EEXIST)); } bool localDrive::RemoveDir(char * dir) { @@ -300,8 +299,8 @@ bool localDrive::TestDir(char * dir) { CROSS_FILENAME(newdir); dirCache.ExpandName(newdir); // Skip directory test, if "\" - Bit16u len = strlen(newdir); - if ((len>0) && (newdir[len-1]!='\\')) { + size_t len = strlen(newdir); + if (len && (newdir[len-1]!='\\')) { // It has to be a directory ! struct stat test; if (stat(newdir,&test)==-1) return false; From 9ac02ea71804afa7af8a9edfa4e6be802fd1455f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 21 Aug 2005 17:29:36 +0000 Subject: [PATCH 2197/4131] add int10/ax=1123 call (vasyl; checked against real bios) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2281 --- src/ints/int10.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 40abef9b..40f1d5c1 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -209,8 +209,10 @@ static Bitu INT10_Handler(void) { RealSetVec(0x43,int10.rom.font_14); real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,14); goto graphics_chars; -// case 0x23: /* Rom 8x8 double dot set */ - //TODO + case 0x23: /* Rom 8x8 double dot set */ + RealSetVec(0x43,int10.rom.font_8_first); + real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,8); + goto graphics_chars; case 0x24: /* Rom 8x16 set */ RealSetVec(0x43,int10.rom.font_16); real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,16); From a87cb5aac0dc279375cde173643d5d4a7bcd2393 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 22 Aug 2005 17:52:57 +0000 Subject: [PATCH 2198/4131] Apply patch 1240534: "Fix for INT10 screen output with multiple video pages" from kippesoep Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2282 --- src/ints/int10_char.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 92b1fa44..7f2ad71a 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.35 2005-07-08 13:48:58 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.36 2005-08-22 17:52:57 qbix79 Exp $ */ /* Character displaying moving functions */ @@ -506,9 +506,6 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt } void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) { - //TODO Check if this page thing is correct - if (CurMode->type!=M_TEXT) page=0xff; - if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); BIOS_NCOLS;BIOS_NROWS; @@ -575,10 +572,6 @@ void INT10_TeletypeOutput(Bit8u chr,Bit8u attr) { } void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,Bit16u count,Bit8u page) { - //TODO Check if this page thing is correct - if (CurMode->type!=M_TEXT) page=0xff; - - if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); BIOS_NCOLS;BIOS_NROWS; Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); From 44d90e5cf4469bfb22bda420c05422dddf20df9c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 22 Aug 2005 19:31:27 +0000 Subject: [PATCH 2199/4131] implemented feature request 1242202: "getting config values via z:\config" Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2283 --- include/shell.h | 5 ++++- src/misc/programs.cpp | 33 ++++++++++++++++++++++++++++++++- src/shell/shell.cpp | 14 +++++++------- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/include/shell.h b/include/shell.h index 4d3eaaef..ca690e6f 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.12 2005-04-21 21:17:45 qbix79 Exp $ */ +/* $Id: shell.h,v 1.13 2005-08-22 19:31:26 qbix79 Exp $ */ #ifndef DOSBOX_SHELL_H #define DOSBOX_SHELL_H @@ -36,6 +36,9 @@ #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; diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 0011a3b9..d996feb3 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.21 2005-08-11 18:56:57 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.22 2005-08-22 19:31:27 qbix79 Exp $ */ #include #include @@ -30,6 +30,7 @@ #include "support.h" #include "cross.h" #include "setup.h" +#include "shell.h" Bitu call_program; @@ -226,6 +227,35 @@ void CONFIG::Run(void) { return; } + /* Code for getting the current configuration. * + * Official format: config -get "section property" * + * As a bonus it will set %CONFIG% to this value as well */ + if(cmd->FindString("-get",temp_line,true)) { + std::string temp2 = ""; + cmd->GetStringRemain(temp2);//So -get n1 n2= can be used without quotes + if(temp2 != "") temp_line = temp_line + " " + temp2; + + std::string::size_type space = temp_line.find(" "); + if(space == std::string::npos) { + WriteOut(MSG_Get("PROGRAM_CONFIG_GET_SYNTAX")); + return; + } + //Copy the found property to a new string and erase from templine (mind the space) + std::string prop = temp_line.substr(space+1); temp_line.erase(space); + + Section* sec = control->GetSection(temp_line.c_str()); + if(!sec) { + WriteOut(MSG_Get("PROGRAM_CONFIG_SECTION_ERROR"),temp_line.c_str()); + return; + } + char* val = sec->GetPropValue(prop.c_str()); + WriteOut("%s",val); + first_shell->SetEnv("CONFIG",val); + return; + } + + + /* Code for the configuration changes * * Official format: config -set "section property=value" * * Accepted: without quotes and/or without -set and/or without section * @@ -305,4 +335,5 @@ void PROGRAMS_Init(Section* sec) { MSG_Add("PROGRAM_CONFIG_USAGE","Config tool:\nUse -writeconf filename to write the current config.\nUse -writelang filename to write the current language strings.\n"); MSG_Add("PROGRAM_CONFIG_SECTION_ERROR","Section %s doesn't exist.\n"); MSG_Add("PROGRAM_CONFIG_PROPERTY_ERROR","Property %s doesn't have a section.\n"); + MSG_Add("PROGRAM_CONFIG_GET_SYNTAX","Correct syntax: config -get \"section property\""); } diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 236dcabb..857b65bd 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.61 2005-05-31 20:19:13 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.62 2005-08-22 19:31:27 qbix79 Exp $ */ #include #include @@ -31,7 +31,7 @@ Bitu call_shellstop; /* Larger scope so shell_del autoexec can use it to * remove things from the environment */ -Program * new_program = 0; +Program * first_shell = 0; static Bitu shellstop_handler(void) { return CBRET_STOP; @@ -84,7 +84,7 @@ AutoexecObject::~AutoexecObject(){ if(!test) continue; *test = 0; //If the shell is running/exists update the environment - if(new_program) new_program->SetEnv(after_set,""); + if(first_shell) first_shell->SetEnv(after_set,""); } } else it++; } @@ -511,8 +511,8 @@ void SHELL_Init() { dos.psp(psp_seg); - SHELL_ProgramStart(&new_program); - new_program->Run(); - delete new_program; - new_program = 0;//Make clear that it shouldn't be used anymore + SHELL_ProgramStart(&first_shell); + first_shell->Run(); + delete first_shell; + first_shell = 0;//Make clear that it shouldn't be used anymore } From 5dd1fb5932ab688a59a750a71bd26b5227a6ebc5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 22 Aug 2005 19:49:07 +0000 Subject: [PATCH 2200/4131] Added some volume label exception to the "don't end findfirst with \" Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2284 --- src/dos/dos_files.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 0b69a627..7f607d6e 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.65 2005-08-19 07:13:34 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.66 2005-08-22 19:49:07 qbix79 Exp $ */ #include #include @@ -258,8 +258,8 @@ bool DOS_FindFirst(char * search,Bit16u attr,bool fcb_findfirst) { Bit8u drive;char fullsearch[DOS_PATHLENGTH]; char dir[DOS_PATHLENGTH];char pattern[DOS_PATHLENGTH]; size_t len = strlen(search); - if(len && search[len - 1] == '\\') { - //Dark Forces installer + if(len && search[len - 1] == '\\' && !( (len > 2) && (search[len - 2] == ':') && (attr == DOS_ATTR_VOLUME) )) { + //Dark Forces installer, but c:\ is allright for volume labels(exclusively set) DOS_SetError(DOSERR_NO_MORE_FILES); return false; } From d1440760bcd3d582361b16c86fae67acef44eccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 23 Aug 2005 08:49:57 +0000 Subject: [PATCH 2201/4131] fix output of dos mem.exe (extended memory) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2285 --- src/dos/dos_classes.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 17411c3f..6bd5819b 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.45 2005-08-08 13:33:45 c2woody Exp $ */ +/* $Id: dos_classes.cpp,v 1.46 2005-08-23 08:49:57 c2woody Exp $ */ #include #include @@ -83,7 +83,7 @@ void DOS_InfoBlock::SetLocation(Bit16u segment) { sSave(sDIB,bootDrive,(Bit8u)0); sSave(sDIB,useDwordMov,(Bit8u)1); - sSave(sDIB,extendedSize,(Bit16u)0x4000); // >16mb + sSave(sDIB,extendedSize,(Bit16u)(MEM_TotalPages()*4-1024)); sSave(sDIB,magicWord,(Bit16u)0x0001); // dos5+ sSave(sDIB,sharingCount,(Bit16u)0); From 28dd4ff354ce6ac4583e4758d086d5de570bfdd6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 23 Aug 2005 13:19:38 +0000 Subject: [PATCH 2202/4131] Added a few more disktypes to the list. Makes EA Booter games startup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2286 --- src/ints/bios_disk.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 0387ede1..c9843046 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.18 2005-06-06 16:07:31 qbix79 Exp $ */ +/* $Id: bios_disk.cpp,v 1.19 2005-08-23 13:19:38 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" @@ -30,11 +30,13 @@ #define MAX_DISK_IMAGES 4 diskGeo DiskGeometryList[] = { - {160, 8, 1, 40, 0}, - {180, 9, 1, 40, 0}, - {320, 8, 2, 40, 1}, - {360, 9, 2, 40, 1}, - {720, 9, 2, 80, 3}, + { 160, 8, 1, 40, 0}, + { 180, 9, 1, 40, 0}, + { 200, 10, 1, 40, 0}, + { 320, 8, 2, 40, 1}, + { 360, 9, 2, 40, 1}, + { 400, 10, 2, 40, 1}, + { 720, 9, 2, 80, 3}, {1200, 15, 2, 80, 2}, {1440, 18, 2, 80, 4}, {2880, 36, 2, 80, 6}, From 2a34df070451507800c2708e82f1218f9e5ef3ec Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 23 Aug 2005 13:58:03 +0000 Subject: [PATCH 2203/4131] fix omf with ipx Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2287 --- src/dos/dos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 9ab3f757..fccf1413 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.85 2005-08-08 13:33:44 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.86 2005-08-23 13:58:03 qbix79 Exp $ */ #include #include @@ -252,7 +252,7 @@ static Bitu DOS_21Handler(void) { { Bit8u difference; char string[1024]; - MEM_StrCopy(SegPhys(ds)+reg_si,string,1024); + MEM_StrCopy(SegPhys(ds)+reg_si,string,1023); // 1024 toasts the stack reg_al=FCB_Parsename(SegValue(es),reg_di,reg_al ,string, &difference); reg_si+=difference; } From 1cfbdc666fd669f07c8bc24ef86cade21454e2f1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 23 Aug 2005 14:21:15 +0000 Subject: [PATCH 2204/4131] Return access_denied when an existing file fails to open in write mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2288 --- src/dos/dos_files.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 7f607d6e..af120ca3 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.66 2005-08-22 19:49:07 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.67 2005-08-23 14:21:15 qbix79 Exp $ */ #include #include @@ -467,7 +467,11 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { psp.SetFileHandle(*entry,handle); return true; } else { - DOS_SetError(DOSERR_FILE_NOT_FOUND); + //Test if file exists, but opened in read-write mode (and writeprotected) + if(((flags&3) != OPEN_READ) && Drives[drive]->FileExists(fullname)) + DOS_SetError(DOSERR_ACCESS_DENIED); + else + DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } } From f4c9569dbfbc92b9ae46a1fb7aba046756c969cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 24 Aug 2005 16:06:18 +0000 Subject: [PATCH 2205/4131] add pause key Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2289 --- src/hardware/keyboard.cpp | 6 ++++- src/ints/bios_keyboard.cpp | 47 ++++++++++++++++++++++++++++++-------- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 2c876379..6a34f567 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.31 2005-03-25 11:55:20 qbix79 Exp $ */ +/* $Id: keyboard.cpp,v 1.32 2005-08-24 16:06:18 c2woody Exp $ */ #include "dosbox.h" #include "keyboard.h" @@ -329,6 +329,10 @@ void KEYBOARD_AddKey(KBD_KEYS keytype,bool pressed) { case KBD_insert:extend=true;ret=82;break; case KBD_delete:extend=true;ret=83;break; case KBD_pause: + KEYBOARD_AddBuffer(0xe1); + KEYBOARD_AddBuffer(29|(pressed?0:0x80)); + KEYBOARD_AddBuffer(69|(pressed?0:0x80)); + return; case KBD_printscreen: /* Not handled yet. But usuable in mapper for special events */ return; diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index bf4f9328..5b2ecb55 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -123,6 +123,7 @@ static struct { }; static void add_key(Bit16u code) { + if (mem_readb(BIOS_KEYBOARD_FLAGS2)&8) return; Bit16u start,end,head,tail,ttail; start=mem_readw(BIOS_KEYBOARD_BUFFER_START); end =mem_readw(BIOS_KEYBOARD_BUFFER_END); @@ -230,20 +231,24 @@ static Bitu IRQ1_Handler(void) { case 0xfa: /* ack. Do nothing for now */ break; case 0xe1: /* Extended key special. Only pause uses this */ - LOG(LOG_KEYBOARD,LOG_ERROR)("someone is putting the pause key in the keyboard buffer"); + flags3 |=0x01; break; case 0xe0: /* Extended key */ flags3 |=0x02; break; case 0x1d: /* Ctrl Pressed */ - flags1 |=0x04; - if (flags3 &0x02) flags3 |=0x04; - else flags2 |=0x01; + if (!(flags3 &0x01)) { + flags1 |=0x04; + if (flags3 &0x02) flags3 |=0x04; + else flags2 |=0x01; + } break; case 0x9d: /* Ctrl Released */ - if (flags3 &0x02) flags3 &=~0x04; - else flags2 &=~0x01; - if( !( (flags3 &0x04) || (flags2 &0x01) ) ) flags1 &=~0x04; + if (!(flags3 &0x01)) { + if (flags3 &0x02) flags3 &=~0x04; + else flags2 &=~0x01; + if( !( (flags3 &0x04) || (flags2 &0x01) ) ) flags1 &=~0x04; + } break; case 0x2a: /* Left Shift Pressed */ flags1 |=0x02; @@ -278,8 +283,31 @@ static Bitu IRQ1_Handler(void) { case 0x3a:flags2 |=0x40;flags1 |=0x40;leds |=0x04;break; //SDL gives only the state instead of the toggle /* Caps Lock */ case 0xba:flags1 &=~0x40;leds &=~0x04;break; - case 0x45:flags2 |=0x20;flags1 |=0x20;leds |=0x02;break; /* Num Lock */ - case 0xc5:flags1 &=~0x20;leds &=~0x02;break; + case 0x45: + if (flags3 &0x01) { + flags3 &=0x01; + if ((flags2&8)==0) { + mem_writeb(BIOS_KEYBOARD_FLAGS2,flags2|8); + mem_writeb(BIOS_KEYBOARD_FLAGS3,flags3); + IO_Write(0x20,0x20); + while (mem_readb(BIOS_KEYBOARD_FLAGS2)&8) CALLBACK_Idle(); // pause loop + reg_ip+=4; // skip out 20,20 + return CBRET_NONE; + } + } else { + flags2 |=0x20; + flags1 |=0x20; + leds |=0x02; + } + break; /* Num Lock */ + case 0xc5: + if (flags3 &0x01) { + flags3 &=0x01; + } else { + flags1 &=~0x20; + leds &=~0x02; + } + break; case 0x46:flags2 |=0x10;break; /* Scroll Lock SDL Seems to do this one fine (so break and make codes) */ case 0xc6:flags1 ^=0x10;flags2 &=~0x10;leds ^=0x01;break; // case 0x52:flags2|=128;break;//See numpad /* Insert */ @@ -361,6 +389,7 @@ static Bitu IRQ1_Handler(void) { irq1_end: if(scancode !=0xe0) flags3 &=~0x02; //Reset 0xE0 Flag mem_writeb(BIOS_KEYBOARD_FLAGS1,flags1); + if ((scancode&0x80)==0) flags2&=0xf7; mem_writeb(BIOS_KEYBOARD_FLAGS2,flags2); mem_writeb(BIOS_KEYBOARD_FLAGS3,flags3); mem_writeb(BIOS_KEYBOARD_LEDS,leds); From 147e30b9489269f6b11cd67cd95e64d77ee970f0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 24 Aug 2005 21:12:24 +0000 Subject: [PATCH 2206/4131] Setup some more register to startup default when booting. Fixes BuckRogers booter Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2290 --- src/dos/dos_programs.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index fc3fdd9c..5723d428 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.40 2005-08-11 18:57:48 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.41 2005-08-24 21:12:24 qbix79 Exp $ */ #include #include @@ -32,6 +32,9 @@ #include "dos_inc.h" #include "bios.h" +#if C_DEBUG +Bitu DEBUG_EnableDebugger(void); +#endif void MSCDEX_SetCDInterface(int intNr, int forceCD); @@ -281,7 +284,6 @@ static void MEM_ProgramStart(Program * * make) { extern Bit32u floppytype; - class BOOT : public Program { private: FILE *getFSFile(Bit8u * filename, Bit32u *ksize, Bit32u *bsize) { @@ -392,7 +394,16 @@ public: SegSet16(cs, 0); reg_ip = 0x7c00; - + SegSet16(ds, 0); + SegSet16(ss, 0);//Buckrogers Booter + reg_esp = 0x400; + SegSet16(es, 0); + reg_esi = 0; + reg_ecx = 1; + reg_ebp = 0; + reg_eax = 0; + reg_ebx= 0x7c00; //Real code is probably uses bx to load the image + //DEBUG_EnableDebugger(); /* Most likely a PCJr ROM */ From 2428a803213a6d7f430d9f440ba80bedd52bb522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 26 Aug 2005 19:16:20 +0000 Subject: [PATCH 2207/4131] ipx-update (h-a-l-9000) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2291 --- src/hardware/ipx.cpp | 456 ++++++++++++++++--------------------------- 1 file changed, 167 insertions(+), 289 deletions(-) diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index ed6bb2e6..33c3bafb 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.cpp,v 1.7 2005-07-30 10:02:39 qbix79 Exp $ */ +/* $Id: ipx.cpp,v 1.8 2005-08-26 19:16:20 c2woody Exp $ */ #include "dosbox.h" @@ -28,7 +28,6 @@ #include "cross.h" #include "support.h" #include "cpu.h" -#include "SDL_net.h" #include "regs.h" #include "inout.h" #include "setup.h" @@ -45,20 +44,16 @@ #define SOCKTABLESIZE 150 // DOS IPX driver was limited to 150 open sockets - struct ipxnetaddr { Uint8 netnum[4]; // Both are big endian Uint8 netnode[6]; } localIpxAddr; - - Bit32u tcpPort; bool isIpxServer; bool isIpxConnected; IPaddress ipxClientIp; // IPAddress for client connection to server IPaddress ipxServConnIp; // IPAddress for client connection to server -//TCPsocket ipxTCPClientSocket; UDPsocket ipxClientSocket; int UDPChannel; // Channel used by UDP connection Bit8u recvBuffer[IPXBUFFERSIZE]; // Incoming packet buffer @@ -67,10 +62,11 @@ static RealPt ipx_callback; SDLNet_SocketSet clientSocketSet; -static bool ESRnotificationRequired = false; - packetBuffer incomingPacket; +static Bit16u socketCount; +static Bit16u opensockets[SOCKTABLESIZE]; + static Bit16u swapByte(Bit16u sockNum) { return (((sockNum>> 8)) | (sockNum << 8)); } @@ -166,7 +162,6 @@ RealPt ECBClass::getESRAddr(void) { void ECBClass::NotifyESR(void) { Bit32u ESRval = real_readd(RealSeg(ECBAddr), RealOff(ECBAddr)+4); - if(ESRval) { #ifdef IPX_DEBUGMSG LOG_MSG("ECB: SN%7d to be notified.", SerialNumber); @@ -227,8 +222,7 @@ ECBClass::~ECBClass() { } } -static Bit16u socketCount; -static Bit16u opensockets[SOCKTABLESIZE]; + static bool sockInUse(Bit16u sockNum) { for(Bitu i=0;inextECB; if(tmpECB->getSocket()==sockNum) { tmpECB->setCompletionFlag(COMP_CANCELLED); + tmpECB->setInUseFlag(USEFLAG_AVAILABLE); delete tmpECB; } tmpECB = tmp2ECB; @@ -311,7 +306,6 @@ static bool IPX_Multiplex(void) { return true; } -//static void sendPackets(); static void sendPacket(ECBClass* sendecb); static void handleIpxRequest(void) { @@ -320,10 +314,14 @@ static void handleIpxRequest(void) { switch (reg_bx) { case 0x0000: // Open socket OpenSocket(); +#ifdef IPX_DEBUGMSG LOG_MSG("IPX: Open socket %4x", swapByte(reg_dx)); +#endif break; case 0x0001: // Close socket +#ifdef IPX_DEBUGMSG LOG_MSG("IPX: Close socket %4x", swapByte(reg_dx)); +#endif CloseSocket(); break; case 0x0002: // get local target @@ -332,26 +330,24 @@ static void handleIpxRequest(void) { case 0x0003: // Send packet if(!incomingPacket.connected) { - tmpECB = new ECBClass(SegValue(es),reg_si);//CreateECB(RealMake(SegValue(es), reg_si),true); + tmpECB = new ECBClass(SegValue(es),reg_si); tmpECB->setInUseFlag(USEFLAG_AVAILABLE); tmpECB->setCompletionFlag(COMP_UNDELIVERABLE); delete tmpECB; // not notify? - //DeleteECB(tmpECB); reg_al = 0xff; // Failure } else { - tmpECB = new ECBClass(SegValue(es),reg_si);//CreateECB(RealMake(SegValue(es), reg_si),true); + tmpECB = new ECBClass(SegValue(es),reg_si); tmpECB->setInUseFlag(USEFLAG_SENDING); //LOG_MSG("IPX: Sending packet on %4x", tmpECB->getSocket()); reg_al = 0x00; // Success sendPacket(tmpECB); } - - //sendPackets(); + break; case 0x0004: // Listen for packet - tmpECB = new ECBClass(SegValue(es),reg_si);//CreateECB(RealMake(SegValue(es), reg_si),false); - if(!sockInUse(tmpECB->getSocket())) { - reg_al = 0xff; // Socket is not open + tmpECB = new ECBClass(SegValue(es),reg_si); + if(!sockInUse(tmpECB->getSocket())) { // Socket is not open + reg_al = 0xff; tmpECB->setInUseFlag(USEFLAG_AVAILABLE); tmpECB->setCompletionFlag(COMP_HARDWAREERROR); delete tmpECB; @@ -374,14 +370,18 @@ static void handleIpxRequest(void) { while(tmpECB) { tmp2ECB=tmpECB->nextECB; if(tmpECB->ECBAddr == ecbaddress) { - delete tmpECB; // TODO: invoke flags... check if it can be canceled + tmpECB->setInUseFlag(USEFLAG_AVAILABLE); + tmpECB->setCompletionFlag(COMP_CANCELLED); + delete tmpECB; + reg_al=0; // Success #ifdef IPX_DEBUGMSG LOG_MSG("IPX: ECB canceled."); #endif + return; } tmpECB=tmp2ECB; } - reg_al=0; // Success + reg_al=0xff; // Fail break; } case 0x0008: // Get interval marker @@ -389,12 +389,11 @@ static void handleIpxRequest(void) { break; case 0x0009: // Get internetwork address { +#ifdef IPX_DEBUGMSG LOG_MSG("IPX: Get internetwork address %2x:%2x:%2x:%2x:%2x:%2x", localIpxAddr.netnode[5], localIpxAddr.netnode[4], localIpxAddr.netnode[3], localIpxAddr.netnode[2], localIpxAddr.netnode[1], localIpxAddr.netnode[0]); - Bit8u * addrptr; - Bits i; - - addrptr = (Bit8u *)&localIpxAddr; - for(i=0;i<10;i++) { +#endif + Bit8u * addrptr = (Bit8u *)&localIpxAddr; + for(Bit16u i=0;i<10;i++) { real_writeb(SegValue(es),reg_si+i,addrptr[i]); } break; @@ -426,12 +425,6 @@ Bitu IPX_IntHandler(void) { return CBRET_NONE; } -static void disconnectServer(bool unexpected) { - // There is no Timer remove code, hence this has to be done manually - incomingPacket.connected = false; - if(unexpected) LOG_MSG("IPX: Server disconnected unexpectedly"); -} - static void pingAck(IPaddress retAddr) { IPXHeader regHeader; UDPpacket regPacket; @@ -503,7 +496,7 @@ static void receivePacket(Bit8u *buffer, Bit16s bufSize) { // Check to see if ping packet if(useSocket == 0x2) { // Is this a broadcast? - if((tmpHeader->dest.addr.byIP.host == 0xffffffff) && (tmpHeader->dest.addr.byIP.port = 0xffff)) { + if((tmpHeader->dest.addr.byIP.host == 0xffffffff) && (tmpHeader->dest.addr.byIP.port == 0xffff)) { // Yes. We should return the ping back to the sender IPaddress tmpAddr; UnpackIP(tmpHeader->src.addr.byIP, &tmpAddr); @@ -530,13 +523,10 @@ static void receivePacket(Bit8u *buffer, Bit16s bufSize) { useECB->setCompletionFlag(COMP_SUCCESS); useECB->setImmAddress(&buffer[22]); // Write in source node hostaddr = *((Bit32u *)&buffer[24]); - #ifdef IPX_DEBUGMSG LOG_MSG("IPX: Received packet of %d bytes from %d.%d.%d.%d (%x CRC)", bufSize, CONVIP(hostaddr), packetCRC(&buffer[30], bufSize-30)); -#endif - +#endif useECB->NotifyESR(); - //DeleteECB(useECB); return; } } @@ -544,7 +534,6 @@ static void receivePacket(Bit8u *buffer, Bit16s bufSize) { if(bufoffset < bufSize) { useECB->setCompletionFlag(COMP_MALFORMED); useECB->NotifyESR(); - //DeleteECB(useECB); return; } } @@ -556,7 +545,7 @@ static void receivePacket(Bit8u *buffer, Bit16s bufSize) { #endif } -static void IPX_UDPClientLoop(void) { +static void IPX_ClientLoop(void) { int numrecv; UDPpacket inPacket; inPacket.data = (Uint8 *)recvBuffer; @@ -570,190 +559,127 @@ static void IPX_UDPClientLoop(void) { if(numrecv) receivePacket(inPacket.data, inPacket.len); //}while(numrecv>0); - } -// don't waste time scanning the list -static void sendPacket(ECBClass* sendecb) { - char outbuffer[IPXBUFFERSIZE]; - fragmentDescriptor tmpFrag; - Bit16u i, fragCount,t; - Bit16s packetsize; - Bit16u *wordptr; - Bits result; - UDPpacket outPacket; - - //if(useECB->getInUseFlag() == USEFLAG_SENDING) - // { - sendecb->setInUseFlag(USEFLAG_AVAILABLE); - packetsize = 0; - fragCount = sendecb->getFragCount(); - for(i=0;igetFragDesc(i,&tmpFrag); - if(i==0) { - // Fragment containing IPX header - // Must put source address into header - Bit8u * addrptr; - Bits m; - addrptr = (Bit8u *)&localIpxAddr.netnode; - for(m=0;m<6;m++) { - real_writeb(tmpFrag.segment,tmpFrag.offset+m+22,addrptr[m]); - } - } - for(t=0;t=IPXBUFFERSIZE) { - LOG_MSG("IPX: Packet size to be sent greater than %d bytes.", IPXBUFFERSIZE); - sendecb->setCompletionFlag(COMP_UNDELIVERABLE); - sendecb->NotifyESR(); - //DeleteECB(useECB); - return; - } - } - } - - // Add length and source socket to IPX header - wordptr = (Bit16u *)&outbuffer[0]; - // Blank CRC - wordptr[0] = 0xffff; - // Length - wordptr[1] = swapByte(packetsize); - // Source socket - wordptr[14] = swapByte(sendecb->getSocket()); - outPacket.channel = UDPChannel; - outPacket.data = (Uint8 *)&outbuffer[0]; - outPacket.len = packetsize; - outPacket.maxlen = packetsize; - // Since we're using a channel, we won't send the IP address again - result = SDLNet_UDP_Send(ipxClientSocket, UDPChannel, &outPacket); - if(result == 0) { - LOG_MSG("IPX: Could not send packet: %s", SDLNet_GetError()); - sendecb->setCompletionFlag(COMP_UNDELIVERABLE); - sendecb->NotifyESR(); - //DeleteECB(useECB); - disconnectServer(true); - //return; - } else { - sendecb->setInUseFlag(USEFLAG_AVAILABLE); - sendecb->setCompletionFlag(COMP_SUCCESS); -#ifdef IPX_DEBUGMSG - LOG_MSG("Packet sent: size: %d",packetsize); -#endif - sendecb->NotifyESR(); - } - //} -} -static void sendPackets() { - ECBClass *useECB; - ECBClass *nextECB; - char outbuffer[IPXBUFFERSIZE]; - fragmentDescriptor tmpFrag; - Bit16u i, fragCount,t; - Bit16s packetsize; - Bit16u *wordptr; - Bits result; - UDPpacket outPacket; - - useECB = ECBList; - while(useECB != NULL) { - nextECB = useECB->nextECB; - if(useECB->getInUseFlag() == USEFLAG_SENDING) { - useECB->setInUseFlag(USEFLAG_AVAILABLE); - packetsize = 0; - fragCount = useECB->getFragCount(); - for(i=0;igetFragDesc(i,&tmpFrag); - if(i==0) { - // Fragment containing IPX header - // Must put source address into header - Bit8u * addrptr; - Bits m; - - addrptr = (Bit8u *)&localIpxAddr.netnode; - for(m=0;m<6;m++) { - real_writeb(tmpFrag.segment,tmpFrag.offset+m+22,addrptr[m]); - } - } - for(t=0;t=IPXBUFFERSIZE) { - LOG_MSG("IPX: Packet size to be sent greater than %d bytes.", IPXBUFFERSIZE); - useECB->setCompletionFlag(COMP_UNDELIVERABLE); - useECB->NotifyESR(); - //DeleteECB(useECB); - goto nextECB; - } - } - } - - // Add length and source socket to IPX header - wordptr = (Bit16u *)&outbuffer[0]; - // Blank CRC - wordptr[0] = 0xffff; - // Length - wordptr[1] = swapByte(packetsize); - // Source socket - wordptr[14] = swapByte(useECB->getSocket()); - - outPacket.channel = UDPChannel; - outPacket.data = (Uint8 *)&outbuffer[0]; - outPacket.len = packetsize; - outPacket.maxlen = packetsize; - // Since we're using a channel, we won't send the IP address again - result = SDLNet_UDP_Send(ipxClientSocket, UDPChannel, &outPacket); - if(result == 0) { - LOG_MSG("IPX: Could not send packet: %s", SDLNet_GetError()); - useECB->setCompletionFlag(COMP_UNDELIVERABLE); - useECB->NotifyESR(); - //DeleteECB(useECB); - disconnectServer(true); - //return; - } else { - useECB->setInUseFlag(USEFLAG_AVAILABLE); - useECB->setCompletionFlag(COMP_SUCCESS); - //LOG_MSG("Packet sent: size: %d",packetsize); - useECB->NotifyESR(); - //DeleteECB(useECB); - } - } -nextECB: - useECB = nextECB; +void DisconnectFromServer(bool unexpected) { + if(unexpected) LOG_MSG("IPX: Server disconnected unexpectedly"); + if(incomingPacket.connected) { + incomingPacket.connected = false; + TIMER_DelTickHandler(&IPX_ClientLoop); + SDLNet_UDP_Close(ipxClientSocket); } } -//RealPt ESRJmpDisplacementAddr; -//RealPt ESRTargetAddr; -//RealPt ESRDummyRetAddr; -/* -void repeatESR(bool rep) -{ - if(rep) real_writeb( - RealSeg(ESRJmpDisplacementAddr), - RealOff(ESRJmpDisplacementAddr), - (Bit8u)0xF5); - else real_writeb( - RealSeg(ESRJmpDisplacementAddr), - RealOff(ESRJmpDisplacementAddr), - (Bit8u)0); -} -*/ -ECBClass* ESRHANDLER_useECB; -static void IPX_ClientLoop(void) { +static void sendPacket(ECBClass* sendecb) { + Bit8u outbuffer[IPXBUFFERSIZE]; + fragmentDescriptor tmpFrag; + Bit16u i, fragCount,t; + Bit16s packetsize; + Bit16u *wordptr; + Bits result; + UDPpacket outPacket; + + sendecb->setInUseFlag(USEFLAG_AVAILABLE); + packetsize = 0; + fragCount = sendecb->getFragCount(); + for(i=0;igetFragDesc(i,&tmpFrag); + if(i==0) { + // Fragment containing IPX header + // Must put source address into header + Bit8u * addrptr; + + addrptr = (Bit8u *)&localIpxAddr.netnum; + for(Bit16u m=0;m<4;m++) { + real_writeb(tmpFrag.segment,tmpFrag.offset+m+18,addrptr[m]); + } + addrptr = (Bit8u *)&localIpxAddr.netnode; + for(Bit16u m=0;m<6;m++) { + real_writeb(tmpFrag.segment,tmpFrag.offset+m+22,addrptr[m]); + } + } + for(t=0;t=IPXBUFFERSIZE) { + LOG_MSG("IPX: Packet size to be sent greater than %d bytes.", IPXBUFFERSIZE); + sendecb->setCompletionFlag(COMP_UNDELIVERABLE); + sendecb->NotifyESR(); + return; + } + } + } + + // Add length and source socket to IPX header + wordptr = (Bit16u *)&outbuffer[0]; + // Blank CRC + wordptr[0] = 0xffff; + // Length + wordptr[1] = swapByte(packetsize); + // Source socket + wordptr[14] = swapByte(sendecb->getSocket()); - IPX_UDPClientLoop(); - // Send outgoing packets - //sendPackets(); -} + // filter out broadcasts and local loopbacks + // ok, the situation is: + // Warcraft1 is allergic to having broadcast packets looped back. + // C&C1 is allergic to not having broadcast packets looped back. + // Warcraft1 broadcasts to 00 00 00 00 : FF FF FF FF FF FF + // C&C1 broadcasts to FF FF FF FF : FF FF FF FF FF FF + // Some other games don't care. + // I assume FF... does local loopback, 00... doesn't. + // Let's hope the bug isn't somewhere else.. + bool islocalbroadcast=true; + bool isloopback=true; + + Bit8u * addrptr; + + addrptr = (Bit8u *)&localIpxAddr.netnum; + for(Bitu m=0;m<4;m++) { + if(addrptr[m]!=outbuffer[m+0x6])isloopback=false; + if(outbuffer[m+0x6]!=0xff) islocalbroadcast=false; + } + addrptr = (Bit8u *)&localIpxAddr.netnode; + for(Bitu m=0;m<6;m++) { + if(addrptr[m]!=outbuffer[m+0xa])isloopback=false; + if(outbuffer[m+0xa]!=0xff) islocalbroadcast=false; + } + + if(!isloopback) { + outPacket.channel = UDPChannel; + outPacket.data = (Uint8 *)&outbuffer[0]; + outPacket.len = packetsize; + outPacket.maxlen = packetsize; + // Since we're using a channel, we won't send the IP address again + result = SDLNet_UDP_Send(ipxClientSocket, UDPChannel, &outPacket); + + if(result == 0) { + LOG_MSG("IPX: Could not send packet: %s", SDLNet_GetError()); + sendecb->setCompletionFlag(COMP_HARDWAREERROR); + sendecb->NotifyESR(); + DisconnectFromServer(true); + return; + } else { + sendecb->setCompletionFlag(COMP_SUCCESS); +#ifdef IPX_DEBUGMSG + LOG_MSG("Packet sent: size: %d",packetsize); +#endif + } + } + if(isloopback||islocalbroadcast) { + receivePacket(&outbuffer[0],packetsize); +#ifdef IPX_DEBUGMSG + LOG_MSG("Packet back: loopback:%d, broadcast:%d",isloopback,isbroadcast); +#endif + } + sendecb->NotifyESR(); +} static bool pingCheck(IPXHeader * outHeader) { char buffer[1024]; Bits result; UDPpacket regPacket; - IPXHeader *regHeader; regPacket.data = (Uint8 *)buffer; regPacket.maxlen = sizeof(buffer); @@ -766,8 +692,6 @@ static bool pingCheck(IPXHeader * outHeader) { return true; } return false; - - } bool ConnectToServer(char *strAddr) { @@ -776,7 +700,12 @@ bool ConnectToServer(char *strAddr) { IPXHeader regHeader; if(!SDLNet_ResolveHost(&ipxServConnIp, strAddr, (Bit16u)tcpPort)) { - + // Generate the MAC address. This is made by zeroing out the first two + // octets and then using the actual IP address for the last 4 octets. + // This idea is from the IPX over IP implementation as specified in RFC 1234: + // http://www.faqs.org/rfcs/rfc1234.html + + // Select an anonymous UDP port ipxClientSocket = SDLNet_UDP_Open(0); if(ipxClientSocket) { @@ -848,45 +777,21 @@ bool ConnectToServer(char *strAddr) { return false; } -void DisconnectFromServer(void) { +void IPX_NetworkInit() { - if(incomingPacket.connected) { - incomingPacket.connected = false; - TIMER_DelTickHandler(&IPX_ClientLoop); - SDLNet_UDP_Close(ipxClientSocket); - } -} - -bool IPX_NetworkInit() { - - localIpxAddr.netnum[0] = 0x0; localIpxAddr.netnum[1] = 0x0; localIpxAddr.netnum[2] = 0x0; localIpxAddr.netnum[3] = 0x1; - - /* - if(SDLNet_ResolveHost(&ipxClientIp, localhostname, tcpPort)) { - LOG_MSG("IPX: Unable to resolve localname: \"%s\". IPX disabled.", localhostname); - return false; - } else { - LOG_MSG("IPX: Using localname: %s IP is: %d.%d.%d.%d", localhostname, CONVIP(ipxClientIp.host)); - } - */ - - // Generate the MAC address. This is made by zeroing out the first two octets and then using the actual IP address for - // the last 4 octets. This idea is from the IPX over IP implementation as specified in RFC 1234: - // http://www.faqs.org/rfcs/rfc1234.html + localIpxAddr.netnum[0] = 0x0; + localIpxAddr.netnum[1] = 0x0; + localIpxAddr.netnum[2] = 0x0; + localIpxAddr.netnum[3] = 0x1; localIpxAddr.netnode[0] = 0x00; localIpxAddr.netnode[1] = 0x00; - //localIpxAddr.netnode[5] = (ipxClientIp.host >> 24) & 0xff; - //localIpxAddr.netnode[4] = (ipxClientIp.host >> 16) & 0xff; - //localIpxAddr.netnode[3] = (ipxClientIp.host >> 8) & 0xff; - //localIpxAddr.netnode[2] = (ipxClientIp.host & 0xff); - //To be filled in on response from server localIpxAddr.netnode[2] = 0x00; localIpxAddr.netnode[3] = 0x00; localIpxAddr.netnode[4] = 0x00; localIpxAddr.netnode[5] = 0x00; socketCount = 0; - return true; + return; } class IPXNET : public Program { @@ -1003,7 +908,7 @@ public: WriteOut("IPX Tunneling Server not running in this DosBox session.\n"); } else { isIpxServer = false; - DisconnectFromServer(); + DisconnectFromServer(false); IPX_StopServer(); WriteOut("IPX Tunneling Server stopped."); // Don't know how to stop the timer just yet. @@ -1044,7 +949,7 @@ public: // TODO: Send a packet to the server notifying of disconnect WriteOut("IPX Tunneling Client disconnected from server.\n"); - DisconnectFromServer(); + DisconnectFromServer(false); return; } @@ -1093,19 +998,6 @@ public: return; } } - - /* - WriteOut("IPX Status\n\n"); - if(!incomingPacket.connected) { - WriteOut("IPX tunneling client not presently connected"); - return; - } - if(isIpxServer) { - WriteOut("This DosBox session is an IPX tunneling server running on port %d", tcpPort); - } else { - WriteOut("This DosBox session is an IPX tunneling client connected to: %s",SDLNet_ResolveIP(&ipxServConnIp)); - } - */ } }; @@ -1126,17 +1018,12 @@ Bitu IPX_ESRHandler1(void) { SegSet16(es, RealSeg(ESRList->ECBAddr)); reg_si = RealOff(ESRList->ECBAddr); reg_al = 0xff; - CALLBACK_RunRealFar(RealSeg(ESRList->getESRAddr()), RealOff(ESRList->getESRAddr())); - delete ESRList; } // while -// PIC_DeActivateIRQ(11); IO_WriteB(0xa0,0x63); //EOI11 IO_WriteB(0x20,0x62); //EOI2 -// IO_WriteB(0xa0,0x20); //EOI - //IO_WriteB(0x20,0x20); //EOI #ifdef IPX_DEBUGMSG LOG_MSG("ESR loop done."); @@ -1192,14 +1079,12 @@ public: LOG_MSG("ESR callback address: %x, HandlerID %d", phyDospage,call_ipxesr1); #endif //save registers - phys_writeb(phyDospage+0,(Bit8u)0xFA); // CLI - phys_writeb(phyDospage+1,(Bit8u)0x60); // PUSHA - phys_writeb(phyDospage+2,(Bit8u)0x1E); // PUSH DS - phys_writeb(phyDospage+3,(Bit8u)0x06); // PUSH ES - phys_writeb(phyDospage+4,(Bit8u)0x0F); // PUSH.. - phys_writeb(phyDospage+5,(Bit8u)0xA0); // FS - phys_writeb(phyDospage+6,(Bit8u)0x0F); // PUSH.. - phys_writeb(phyDospage+7,(Bit8u)0xA8); // GS + phys_writeb(phyDospage+0,(Bit8u)0xFA); // CLI + phys_writeb(phyDospage+1,(Bit8u)0x60); // PUSHA + phys_writeb(phyDospage+2,(Bit8u)0x1E); // PUSH DS + phys_writeb(phyDospage+3,(Bit8u)0x06); // PUSH ES + phys_writew(phyDospage+4,(Bit16u)0xA00F); // PUSH FS + phys_writew(phyDospage+6,(Bit16u)0xA80F); // PUSH GS // callback phys_writeb(phyDospage+8,(Bit8u)0xFE); // GRP 4 @@ -1207,14 +1092,12 @@ public: phys_writew(phyDospage+10,call_ipxesr1); // Callback identifier // register recreation - phys_writeb(phyDospage+12,(Bit8u)0x0F);// POP.. - phys_writeb(phyDospage+13,(Bit8u)0xA9); // GS - phys_writeb(phyDospage+14,(Bit8u)0x0F);// POP.. - phys_writeb(phyDospage+15,(Bit8u)0xA1); // FS - phys_writeb(phyDospage+16,(Bit8u)0x07); // POP ES - phys_writeb(phyDospage+17,(Bit8u)0x1F); // POP DS - phys_writeb(phyDospage+18,(Bit8u)0x61); //POPA - phys_writeb(phyDospage+19,(Bit8u)0xCF); //IRET: restores flags, CS, IP + phys_writew(phyDospage+12,(Bit16u)0xA90F); // POP GS + phys_writew(phyDospage+14,(Bit16u)0xA10F); // POP FS + phys_writeb(phyDospage+16,(Bit8u)0x07); // POP ES + phys_writeb(phyDospage+17,(Bit8u)0x1F); // POP DS + phys_writeb(phyDospage+18,(Bit8u)0x61); // POPA + phys_writeb(phyDospage+19,(Bit8u)0xCF); // IRET: restores flags, CS, IP // IPX version 2.12 //phys_writeb(phyDospage+27,(Bit8u)0x2); @@ -1224,10 +1107,8 @@ public: RealPt ESRRoutineBase = RealMake(dospage, 0); // Interrupt enabling - RealSetVec(0x73,ESRRoutineBase,old_73_vector); // IRQ11 - Bit8u irqmask=IO_ReadB(0xa1); - irqmask &= ~8; // enable IRQ11 - IO_WriteB(0xa1,irqmask); + RealSetVec(0x73,ESRRoutineBase,old_73_vector); // IRQ11 + IO_WriteB(0xa1,IO_ReadB(0xa1)&(~8)); // enable IRQ11 PROGRAMS_MakeFile("IPXNET.COM",IPXNET_ProgramStart); } @@ -1238,16 +1119,13 @@ public: if(isIpxServer) { isIpxServer = false; - DisconnectFromServer(); IPX_StopServer(); } - disconnectServer(false); + DisconnectFromServer(false); DOS_DelMultiplexHandler(IPX_Multiplex); RealSetVec(0x73,old_73_vector); - Bit8u irqmask=IO_ReadB(0xa1); - irqmask |= 8; // disable IRQ11 - IO_WriteB(0xa1,irqmask); + IO_WriteB(0xa1,IO_ReadB(0xa1)|8); // disable IRQ11 PhysPt phyDospage = PhysMake(dospage,0); for(Bitu i = 0;i < 32;i++) From 2bb446cd27b8a4089c94e2cd90c903f0e9206ef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 28 Aug 2005 09:48:42 +0000 Subject: [PATCH 2208/4131] fix dos7+ boot disks Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2292 --- src/ints/bios_disk.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index c9843046..d975f07e 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.19 2005-08-23 13:19:38 qbix79 Exp $ */ +/* $Id: bios_disk.cpp,v 1.20 2005-08-28 09:48:42 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" @@ -197,7 +197,7 @@ imageDisk::imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHard } if(!founddisk) { active = false; - } + } else mem_writeb(BIOS_CONFIGURATION,mem_readb(BIOS_CONFIGURATION)|1); } } @@ -394,9 +394,15 @@ static Bitu INT13_DiskHandler(void) { reg_cl = (((tmpcyl >> 2) & 0xc0) | (tmpsect & 0x3f)); reg_dh = tmpheads-1; last_status = 0x00; - reg_dl = 0; - if(imageDiskList[2] != NULL) reg_dl++; - if(imageDiskList[3] != NULL) reg_dl++; + if (reg_dl&0x80) { // harddisks + reg_dl = 0; + if(imageDiskList[2] != NULL) reg_dl++; + if(imageDiskList[3] != NULL) reg_dl++; + } else { // floppy disks + reg_dl = 0; + if(imageDiskList[0] != NULL) reg_dl++; + if(imageDiskList[1] != NULL) reg_dl++; + } CALLBACK_SCF(false); break; case 0x11: /* Recalibrate drive */ From 97dec5a4fe0d6f9b6d49c260be38b2195f1e3191 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 31 Aug 2005 13:00:14 +0000 Subject: [PATCH 2209/4131] add binary memory dumps Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2293 --- src/debug/debug.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index f8b95b3c..1c6cb424 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.67 2005-08-10 12:22:25 c2woody Exp $ */ +/* $Id: debug.cpp,v 1.68 2005-08-31 13:00:14 qbix79 Exp $ */ #include #include @@ -56,6 +56,7 @@ static void DrawCode(void); static bool DEBUG_Log_Loop(int count); static void DEBUG_RaiseTimerIrq(void); static void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num); +static void SaveMemoryBin(Bitu seg, Bitu ofs1, Bit32s num); static void LogGDT(void); static void LogLDT(void); static void LogIDT(void); @@ -912,6 +913,15 @@ bool ParseCommand(char* str) SaveMemory(seg,ofs,num); return true; }; + found = strstr(str,"MEMDUMPBIN "); + if (found) { // Insert variable + found+=11; + Bit16u seg = (Bit16u)GetHexValue(found,found); found++; + Bit32u ofs = GetHexValue(found,found); found++; + Bit32u num = GetHexValue(found,found); found++; + SaveMemoryBin(seg,ofs,num); + return true; + }; found = strstr(str,"IV "); if (found) { // Insert variable @@ -1270,6 +1280,7 @@ bool ParseCommand(char* str) DEBUG_ShowMsg("LV [seg]:[off] [name] - Load var list from file.\n"); DEBUG_ShowMsg("MEMDUMP [seg]:[off] [len] - Write memory to file memdump.txt.\n"); + DEBUG_ShowMsg("MEMDUMPBIN [s]:[o] [len] - Write memory to file memdump.bin.\n"); DEBUG_ShowMsg("SELINFO [segName] - Show selector info.\n"); DEBUG_ShowMsg("INTVEC [filename] - Writes interrupt vector table to file.\n"); @@ -2078,6 +2089,21 @@ static void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num) DEBUG_ShowMsg("DEBUG: Memory dump success.\n"); }; +static void SaveMemoryBin(Bitu seg, Bitu ofs1, Bit32s num) { + FILE* f = fopen("MEMDUMP.BIN","wt"); + if (!f) { + DEBUG_ShowMsg("DEBUG: Memory binary dump failed.\n"); + return; + } + + for(Bitu x=0; x Date: Wed, 31 Aug 2005 18:06:09 +0000 Subject: [PATCH 2210/4131] Change clock to NTSC burst frequency. (NewRisingSun) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2294 --- src/hardware/tandy_sound.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index ea5165fc..28fa801e 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -323,11 +323,11 @@ public: tandy.chan=MixerChan.Install(&SN76496Update,sample_rate,"TANDY"); tandy.enabled=false; - + Bitu i; struct SN76496 *R = &sn; R->SampleRate = sample_rate; - SN76496_set_clock(2386360); + SN76496_set_clock(3579545); for (i = 0;i < 4;i++) R->Volume[i] = 0; R->LastRegister = 0; for (i = 0;i < 8;i+=2) From 97510138d4cbfa7ee7c02342e307e5faf0164831 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 1 Sep 2005 14:31:40 +0000 Subject: [PATCH 2211/4131] Fix inventory in KQ1 cga mode. Caused by setting wrong startaddress in cga mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2295 --- src/ints/int10_char.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 7f2ad71a..3835034f 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.36 2005-08-22 17:52:57 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.37 2005-09-01 14:31:40 qbix79 Exp $ */ /* Character displaying moving functions */ @@ -280,7 +280,7 @@ void INT10_SetActivePage(Bit8u page) { mem_address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); /* Write the new page start */ real_writew(BIOSMEM_SEG,BIOSMEM_CURRENT_START,mem_address); - if (CurMode->mode<0x8) mem_address>>=1; + if (machine==MCH_VGA && CurMode->mode<0x8) mem_address>>=1; /* Write the new start address in vgahardware */ Bit16u base=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); IO_Write(base,0x0c); From 121b29e6f1f1fda5b2550da181c0973c5fd2f671 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 1 Sep 2005 17:34:39 +0000 Subject: [PATCH 2212/4131] improve support for 2 images booters. (only pressing enter instead of having to swap disks). Fix verify disk. Makes Triva games boot Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2296 --- src/ints/bios_disk.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index d975f07e..0fd03402 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.20 2005-08-28 09:48:42 c2woody Exp $ */ +/* $Id: bios_disk.cpp,v 1.21 2005-09-01 17:34:39 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" @@ -197,7 +197,17 @@ imageDisk::imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHard } if(!founddisk) { active = false; - } else mem_writeb(BIOS_CONFIGURATION,mem_readb(BIOS_CONFIGURATION)|1); + } else { + Bit16u equipment=mem_readw(BIOS_CONFIGURATION); + if(equipment&1) { + Bitu numofdisks = (equipment>>5)&3; + numofdisks++; + if(numofdisks > 1) numofdisks=1;//max 2 floppies at the moment + equipment&=~0x00C0; + equipment|=(numofdisks<<5); + } else equipment|=1; + mem_writew(BIOS_CONFIGURATION,equipment); + } } } @@ -374,8 +384,9 @@ static Bitu INT13_DiskHandler(void) { } }*/ reg_ah = 0x00; + //Qbix: The following codes don't match my specs. al should be number of sector verified //reg_al = 0x10; /* CRC verify failed */ - reg_al = 0x00; /* CRC verify succeeded */ + //reg_al = 0x00; /* CRC verify succeeded */ CALLBACK_SCF(false); break; From 75ee82edb43558fd8a67a872197abccca4105e2c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 1 Sep 2005 19:48:37 +0000 Subject: [PATCH 2213/4131] fix screenshots that have only doubleheight set and not double width Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2297 --- src/gui/render.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 508dc560..e768837c 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.31 2005-02-10 10:21:07 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.32 2005-09-01 19:48:37 qbix79 Exp $ */ #include #include @@ -97,8 +97,12 @@ static void TakeScreenShot(Bit8u * bitmap) { png_bytep * row_pointers; png_color palette[256]; Bitu i; + Bitu fix_double_scale = 1;//variable to compensate for only doubleheight + + /* Remove this if we save rendered screens. instead of pre-rendered */ + if(render.src.dblh && !render.src.dblw) fix_double_scale = 2; + -/* Find a filename to open */ /* Open the actual file */ FILE * fp=OpenCaptureFile("Screenshot",".png"); if (!fp) return; @@ -106,10 +110,10 @@ static void TakeScreenShot(Bit8u * bitmap) { png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL, NULL); if (!png_ptr) return; info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { + if (!info_ptr) { png_destroy_write_struct(&png_ptr,(png_infopp)NULL); return; - } + } /* Finalize the initing of png library */ png_init_io(png_ptr, fp); @@ -123,7 +127,7 @@ static void TakeScreenShot(Bit8u * bitmap) { png_set_compression_buffer_size(png_ptr, 8192); if (render.shot.bpp==8) { - png_set_IHDR(png_ptr, info_ptr, render.shot.width, render.shot.height, + png_set_IHDR(png_ptr, info_ptr, render.shot.width, (render.shot.height*fix_double_scale), 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); for (i=0;i<256;i++) { @@ -133,15 +137,18 @@ static void TakeScreenShot(Bit8u * bitmap) { } png_set_PLTE(png_ptr, info_ptr, palette,256); } else { - png_set_IHDR(png_ptr, info_ptr, render.shot.width, render.shot.height, + png_set_IHDR(png_ptr, info_ptr, render.shot.width, (render.shot.height*fix_double_scale), render.shot.bpp, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); } + /*Allocate an array of scanline pointers*/ - row_pointers=(png_bytep*)malloc(render.shot.height*sizeof(png_bytep)); - for (i=0;i Date: Fri, 2 Sep 2005 19:56:18 +0000 Subject: [PATCH 2214/4131] fix drive field in FCB_Parsename() Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2298 --- src/dos/dos_files.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index af120ca3..0e15b656 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.67 2005-08-23 14:21:15 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.68 2005-09-02 19:56:18 c2woody Exp $ */ #include #include @@ -650,8 +650,7 @@ static bool isvalid(const char in){ #define PARSE_RET_WILD 1 #define PARSE_RET_BADDRIVE 0xff -Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u *change){ - +Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u *change) { char * string_begin=string;Bit8u ret=0; DOS_FCB fcb(seg,offset); bool hasdrive,hasname,hasext; @@ -673,7 +672,9 @@ Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u * #pragma pack() #endif /* Get the old information from the previous fcb */ - fcb.GetName(fcb_name.full);fcb_name.part.drive[1]=0;fcb_name.part.name[8]=0;fcb_name.part.ext[3]=0; + fcb.GetName(fcb_name.full); + fcb_name.part.drive[0]-='A'-1;fcb_name.part.drive[1]=0; + fcb_name.part.name[8]=0;fcb_name.part.ext[3]=0; /* Strip of the leading sepetaror */ if((parser & PARSE_SEP_STOP) && *string) { //ignore leading seperator char sep[] = FCB_SEP;char a[2]; From 406935348a1e8aff5334de23a22e9c6af6039c9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 3 Sep 2005 11:38:18 +0000 Subject: [PATCH 2215/4131] fix Inner Worlds (vasyl) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2299 --- include/paging.h | 10 +++++++++- src/hardware/vga_memory.cpp | 30 +++++++++++++++--------------- src/ints/ems.cpp | 12 ++++++------ 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/include/paging.h b/include/paging.h index 2839ba78..f7597265 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.16 2005-03-25 11:41:26 qbix79 Exp $ */ +/* $Id: paging.h,v 1.17 2005-09-03 11:38:18 c2woody Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H @@ -131,6 +131,14 @@ extern PagingBlock paging; PageHandler * MEM_GetPageHandler(Bitu phys_page); +/* Use this helper function to access linear addresses in readX/writeX functions */ +INLINE PhysPt PAGING_GetLinearAddress(PhysPt addr) { + if (paging.enabled) + return (paging.tlb.phys_page[addr>>12]<<12)|(addr&0xfff); + else + return addr; +} + /* Unaligned address handlers */ Bit16u mem_unalignedreadw(PhysPt address); Bit32u mem_unalignedreadd(PhysPt address); diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index a3af1e60..73a0e181 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -138,17 +138,17 @@ static struct { class VGARead_PageHandler : public PageHandler { public: Bitu readb(PhysPt addr) { - addr&=0xffff; + addr = PAGING_GetLinearAddress(addr) & 0xffff; return VGA_NormalReadHandler(addr); } Bitu readw(PhysPt addr) { - addr&=0xffff; + addr = PAGING_GetLinearAddress(addr) & 0xffff; return (VGA_NormalReadHandler(addr+0) << 0) | (VGA_NormalReadHandler(addr+1) << 8); } Bitu readd(PhysPt addr) { - addr&=0xffff; + addr = PAGING_GetLinearAddress(addr) & 0xffff; return (VGA_NormalReadHandler(addr+0) << 0) | (VGA_NormalReadHandler(addr+1) << 8) | @@ -163,16 +163,16 @@ public: flags=PFLAG_NOCODE; } void writeb(PhysPt addr,Bitu val) { - addr&=0xffff; + addr = PAGING_GetLinearAddress(addr) & 0xffff; VGA_GFX_16_WriteHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { - addr&=0xffff; + addr = PAGING_GetLinearAddress(addr) & 0xffff; VGA_GFX_16_WriteHandler(addr+0,(Bit8u)(val >> 0)); VGA_GFX_16_WriteHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { - addr&=0xffff; + addr = PAGING_GetLinearAddress(addr) & 0xffff; VGA_GFX_16_WriteHandler(addr+0,(Bit8u)(val >> 0)); VGA_GFX_16_WriteHandler(addr+1,(Bit8u)(val >> 8)); VGA_GFX_16_WriteHandler(addr+2,(Bit8u)(val >> 16)); @@ -186,16 +186,16 @@ public: flags=PFLAG_NOCODE; } void writeb(PhysPt addr,Bitu val) { - addr&=0xffff; + addr = PAGING_GetLinearAddress(addr) & 0xffff; VGA_GFX_256U_WriteHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { - addr&=0xffff; + addr = PAGING_GetLinearAddress(addr) & 0xffff; VGA_GFX_256U_WriteHandler(addr+0,(Bit8u)(val >> 0)); VGA_GFX_256U_WriteHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { - addr&=0xffff; + addr = PAGING_GetLinearAddress(addr) & 0xffff; VGA_GFX_256U_WriteHandler(addr+0,(Bit8u)(val >> 0)); VGA_GFX_256U_WriteHandler(addr+1,(Bit8u)(val >> 8)); VGA_GFX_256U_WriteHandler(addr+2,(Bit8u)(val >> 16)); @@ -209,11 +209,11 @@ public: flags=PFLAG_NOCODE; } Bitu readb(PhysPt addr) { - addr&=vgapages.mask; + addr = PAGING_GetLinearAddress(addr) & vgapages.mask; return vga.draw.font[addr]; } void writeb(PhysPt addr,Bitu val){ - addr&=vgapages.mask; + addr = PAGING_GetLinearAddress(addr) & vgapages.mask; if (vga.seq.map_mask & 0x4) { vga.draw.font[addr]=(Bit8u)val; } @@ -240,7 +240,7 @@ public: //memset(®mem[0], 0, sizeof(regmem)); } void writeb(PhysPt addr,Bitu val) { - Bitu port = addr & 0xffff; + Bitu port = PAGING_GetLinearAddress(addr) & 0xffff; if(port >= 0x82E8) IO_WriteB(port, val); if(port <= 0x4000) { if(port == 0x0000) { @@ -252,7 +252,7 @@ public: //LOG_MSG("MMIO: Write byte to %x with %x", addr, val); } void writew(PhysPt addr,Bitu val) { - Bitu port = addr & 0xffff; + Bitu port = PAGING_GetLinearAddress(addr) & 0xffff; if(port >= 0x82E8) IO_WriteW(port, val); if(port == 0x8118) IO_WriteW(0x9ae8, val); if(port <= 0x4000) { @@ -265,7 +265,7 @@ public: //LOG_MSG("MMIO: Write word to %x with %x", addr, val); } void writed(PhysPt addr,Bitu val) { - Bitu port = addr & 0xffff; + Bitu port = PAGING_GetLinearAddress(addr) & 0xffff; if(port >= 0x82E8) IO_WriteD(port, val); if(port == 0x8100) { IO_WriteW(0x86e8, (val >> 16)); @@ -294,7 +294,7 @@ public: return 0x00; } Bitu readw(PhysPt addr) { - Bitu port = addr & 0xffff; + Bitu port = PAGING_GetLinearAddress(addr) & 0xffff; if(port >= 0x82E8) return IO_ReadW(port); //LOG_MSG("MMIO: Read word from %x", addr); return 0x00; diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index e00c2cff..94effec0 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.42 2005-08-15 13:43:44 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.43 2005-09-03 11:38:18 c2woody Exp $ */ #include #include @@ -613,17 +613,17 @@ static Bitu INT67_Handler(void) { break; case 0x01: /* VCPI Get Protected Mode Interface */ /* Set up page table buffer */ - for (Bitu ct=0; ct<0xff; ct++) { + for (Bit16u ct=0; ct<0xff; ct++) { real_writeb(SegValue(es),reg_di+ct*4+0x00,0x67); // access bits - real_writew(SegValue(es),reg_di+ct*4+0x01,ct*0x10); // mapping + real_writew(SegValue(es),reg_di+ct*4+0x01,ct*0x10); // mapping real_writeb(SegValue(es),reg_di+ct*4+0x03,0x00); } - for (Bitu ct=0xff; ct<0x100; ct++) { + for (Bit16u ct=0xff; ct<0x100; ct++) { real_writeb(SegValue(es),reg_di+ct*4+0x00,0x67); // access bits real_writew(SegValue(es),reg_di+ct*4+0x01,(ct-0xff)*0x10+0x1100); // mapping real_writeb(SegValue(es),reg_di+ct*4+0x03,0x00); } - reg_di+=0x800; // advance pointer by 0x200*4 + reg_di+=0x400; // advance pointer by 0x100*4 /* Set up three descriptor table entries */ real_writed(SegValue(ds),reg_si+0x00,0x8000ffff); // descriptor 1 (code segment) @@ -991,7 +991,7 @@ static void SetupVCPI() { mem_writed(vcpi.private_area+0x1014,ds_desc_part); // descriptor 2 /* IDT setup */ - for (Bitu int_ct=0; int_ct<0x100; int_ct++) { + for (Bit16u int_ct=0; int_ct<0x100; int_ct++) { /* build a CALL NEAR V86MON, the value of IP pushed by the CALL is used to identify the interrupt number */ mem_writeb(vcpi.private_area+0x2800+int_ct*4+0,0xe8); // call From 06135e8beb5e17565a07699302c71c62171304f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 3 Sep 2005 19:20:08 +0000 Subject: [PATCH 2216/4131] dynamic core optimizations; incorporate patch from esaelon, parts of ih8regs optimizations; thanks to kekko for several ideas Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2300 --- include/paging.h | 40 ++- src/cpu/core_dyn_x86.cpp | 13 +- src/cpu/core_dyn_x86/decoder.h | 428 ++++++++++++++++++++------------ src/cpu/core_dyn_x86/risc_x86.h | 307 +++++++++++++---------- 4 files changed, 502 insertions(+), 286 deletions(-) diff --git a/include/paging.h b/include/paging.h index f7597265..9ab16588 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.17 2005-09-03 11:38:18 c2woody Exp $ */ +/* $Id: paging.h,v 1.18 2005-09-03 19:20:08 c2woody Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H @@ -162,7 +162,6 @@ INLINE Bit16u mem_readw_inline(PhysPt address) { } else return mem_unalignedreadw(address); } - INLINE Bit32u mem_readd_inline(PhysPt address) { if (!(address & 3)) { Bitu index=(address>>12); @@ -197,4 +196,41 @@ INLINE void mem_writed_inline(PhysPt address,Bit32u val) { } else mem_unalignedwrited(address,val); } + +INLINE Bit16u mem_readw_dyncorex86(PhysPt address) { + if ((address & 0xfff)<0xfff) { + Bitu index=(address>>12); + + if (paging.tlb.read[index]) return host_readw(paging.tlb.read[index]+address); + else return paging.tlb.handler[index]->readw(address); + } else return mem_unalignedreadw(address); +} + +INLINE Bit32u mem_readd_dyncorex86(PhysPt address) { + if ((address & 0xfff)<0xffd) { + Bitu index=(address>>12); + + if (paging.tlb.read[index]) return host_readd(paging.tlb.read[index]+address); + else return paging.tlb.handler[index]->readd(address); + } else return mem_unalignedreadd(address); +} + +INLINE void mem_writew_dyncorex86(PhysPt address,Bit16u val) { + if ((address & 0xfff)<0xfff) { + Bitu index=(address>>12); + + if (paging.tlb.write[index]) host_writew(paging.tlb.write[index]+address,val); + else paging.tlb.handler[index]->writew(address,val); + } else mem_unalignedwritew(address,val); +} + +INLINE void mem_writed_dyncorex86(PhysPt address,Bit32u val) { + if ((address & 0xfff)<0xffd) { + Bitu index=(address>>12); + + if (paging.tlb.write[index]) host_writed(paging.tlb.write[index]+address,val); + else paging.tlb.handler[index]->writed(address,val); + } else mem_unalignedwrited(address,val); +} + #endif diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index e66df13f..3ed19175 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -194,12 +194,23 @@ static void dyn_loadstate(DynState * state) { } } - static void dyn_synchstate(DynState * state) { for (Bitu i=0;iregs[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" Bits CPU_Core_Dyn_X86_Run(void) { diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index e1a6b0fd..423d4022 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -106,18 +106,35 @@ static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { } static void dyn_write_byte(DynReg * addr,DynReg * val,Bitu high) { if (high) gen_call_function((void *)&mem_writeb,"%Dd%Dh",addr,val); - else gen_call_function((void *)&mem_writeb,"%Dd%Dl",addr,val); + else gen_call_function((void *)&mem_writeb,"%Dd%Dd",addr,val); } - static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) { - if (dword) gen_call_function((void *)&mem_readd,"%Dd%Rd",addr,dst); - else gen_call_function((void *)&mem_readw,"%Dd%Rw",addr,dst); + if (dword) gen_call_function((void *)&mem_readd_dyncorex86,"%Dd%Rd",addr,dst); + else gen_call_function((void *)&mem_readw_dyncorex86,"%Dd%Rw",addr,dst); +} +static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { + if (dword) gen_call_function((void *)&mem_writed_dyncorex86,"%Dd%Dd",addr,val); + else gen_call_function((void *)&mem_writew_dyncorex86,"%Dd%Dd",addr,val); } -static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { - if (dword) gen_call_function((void *)&mem_writed,"%Dd%Dd",addr,val); - else gen_call_function((void *)&mem_writew,"%Dd%Dw",addr,val); + +static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) { + if (high) gen_call_function((void *)&mem_readb,"%Drd%Rh",addr,dst); + else gen_call_function((void *)&mem_readb,"%Drd%Rl",addr,dst); } +static void dyn_write_byte_release(DynReg * addr,DynReg * val,Bitu high) { + if (high) gen_call_function((void *)&mem_writeb,"%Drd%Dh",addr,val); + else gen_call_function((void *)&mem_writeb,"%Drd%Dd",addr,val); +} +static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) { + if (dword) gen_call_function((void *)&mem_readd_dyncorex86,"%Drd%Rd",addr,dst); + else gen_call_function((void *)&mem_readw_dyncorex86,"%Drd%Rw",addr,dst); +} +static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) { + if (dword) gen_call_function((void *)&mem_writed_dyncorex86,"%Drd%Dd",addr,val); + else gen_call_function((void *)&mem_writew_dyncorex86,"%Drd%Dd",addr,val); +} + static void dyn_reduce_cycles(void) { gen_protectflags(); @@ -125,7 +142,7 @@ static void dyn_reduce_cycles(void) { gen_dop_word_imm(DOP_SUB,true,DREG(CYCLES),decode.cycles); } -static void dyn_save_critical_regs(void) { +static void dyn_save_noncritical_regs(void) { gen_releasereg(DREG(EAX)); gen_releasereg(DREG(ECX)); gen_releasereg(DREG(EDX)); @@ -134,6 +151,10 @@ static void dyn_save_critical_regs(void) { gen_releasereg(DREG(EBP)); gen_releasereg(DREG(ESI)); gen_releasereg(DREG(EDI)); +} + +static void dyn_save_critical_regs(void) { + dyn_save_noncritical_regs(); gen_releasereg(DREG(FLAGS)); gen_releasereg(DREG(EIP)); gen_releasereg(DREG(CYCLES)); @@ -171,7 +192,6 @@ static void dyn_push(DynReg * dynreg) { //Can just push the whole 32-bit word as operand gen_call_function((void *)&mem_writew,"%Drd%Dd",DREG(STACK),dynreg); } - gen_releasereg(DREG(STACK)); } static void dyn_pop(DynReg * dynreg) { @@ -191,7 +211,6 @@ static void dyn_pop(DynReg * dynreg) { gen_dop_word_imm(DOP_ADD,true,DREG(ESP),2); } } - gen_releasereg(DREG(STACK)); } static void INLINE dyn_get_modrm(void) { @@ -201,7 +220,7 @@ static void INLINE dyn_get_modrm(void) { decode.modrm.rm=(decode.modrm.val & 7); } -static void dyn_fill_ea(bool addseg=true) { +static void dyn_fill_ea(bool addseg=true, DynReg * reg_ea=DREG(EA)) { DynReg * segbase; if (!decode.big_addr) { Bits imm; @@ -210,47 +229,56 @@ static void dyn_fill_ea(bool addseg=true) { case 1:imm=(Bit8s)decode_fetchb();break; case 2:imm=(Bit16s)decode_fetchw();break; } + DynReg * extend_src=reg_ea; switch (decode.modrm.rm) { case 0:/* BX+SI */ - gen_lea(DREG(EA),DREG(EBX),DREG(ESI),0,imm); + gen_lea(reg_ea,DREG(EBX),DREG(ESI),0,imm); segbase=DREG(DS); break; case 1:/* BX+DI */ - gen_lea(DREG(EA),DREG(EBX),DREG(EDI),0,imm); + gen_lea(reg_ea,DREG(EBX),DREG(EDI),0,imm); segbase=DREG(DS); break; case 2:/* BP+SI */ - gen_lea(DREG(EA),DREG(EBP),DREG(ESI),0,imm); + gen_lea(reg_ea,DREG(EBP),DREG(ESI),0,imm); segbase=DREG(SS); break; case 3:/* BP+DI */ - gen_lea(DREG(EA),DREG(EBP),DREG(EDI),0,imm); + gen_lea(reg_ea,DREG(EBP),DREG(EDI),0,imm); segbase=DREG(SS); break; case 4:/* SI */ - gen_lea(DREG(EA),DREG(ESI),0,0,imm); + if (imm) gen_lea(reg_ea,DREG(ESI),0,0,imm); + else extend_src=DREG(ESI); segbase=DREG(DS); break; case 5:/* DI */ - gen_lea(DREG(EA),DREG(EDI),0,0,imm); + if (imm) gen_lea(reg_ea,DREG(EDI),0,0,imm); + else extend_src=DREG(EDI); segbase=DREG(DS); break; case 6:/* imm/BP */ if (!decode.modrm.mod) { - imm=(Bit16s)decode_fetchw(); - gen_dop_word_imm(DOP_MOV,true,DREG(EA),imm); + imm=decode_fetchw(); + gen_dop_word_imm(DOP_MOV,true,reg_ea,imm); segbase=DREG(DS); + goto skip_extend_word; } else { - gen_lea(DREG(EA),DREG(EBP),0,0,imm); + gen_lea(reg_ea,DREG(EBP),0,0,imm); segbase=DREG(SS); } break; case 7: /* BX */ - gen_lea(DREG(EA),DREG(EBX),0,0,imm); + if (imm) gen_lea(reg_ea,DREG(EBX),0,0,imm); + else extend_src=DREG(EBX); segbase=DREG(DS); break; } - gen_extend_word(false,DREG(EA),DREG(EA)); + gen_extend_word(false,reg_ea,extend_src); +skip_extend_word: + if (addseg) { + gen_lea(reg_ea,reg_ea,decode.segprefix ? decode.segprefix : segbase,0,0); + } } else { Bits imm=0; DynReg * base=0;DynReg * scaled=0;Bitu scale=0; @@ -300,10 +328,17 @@ static void dyn_fill_ea(bool addseg=true) { case 1:imm=(Bit8s)decode_fetchb();break; case 2:imm=(Bit32s)decode_fetchd();break; } - gen_lea(DREG(EA),base,scaled,scale,imm); - } - if (addseg) { - gen_lea(DREG(EA),DREG(EA),decode.segprefix ? decode.segprefix : segbase,0,0); + if (!addseg) { + gen_lea(reg_ea,base,scaled,scale,imm); + } else { + DynReg** seg = decode.segprefix ? &decode.segprefix : &segbase; + if (!base) gen_lea(reg_ea,*seg,scaled,scale,imm); + else if (!scaled) gen_lea(reg_ea,base,*seg,0,imm); + else { + gen_lea(reg_ea,base,scaled,scale,imm); + gen_lea(reg_ea,reg_ea,decode.segprefix ? decode.segprefix : segbase,0,0); + } + } } } @@ -335,13 +370,21 @@ static void dyn_dop_ebgb(DualOps op) { dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg&3]; if (decode.modrm.mod<3) { dyn_fill_ea(); + if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); dyn_read_byte(DREG(EA),DREG(TMPB),false); - if (op<=DOP_TEST) gen_needflags(); + if (op<=DOP_TEST) { + if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); + else set_skipflags(false); + } gen_dop_byte(op,DREG(TMPB),0,rm_reg,decode.modrm.reg&4); - dyn_write_byte(DREG(EA),DREG(TMPB),false); - gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB)); + if (op!=DOP_CMP) dyn_write_byte_release(DREG(EA),DREG(TMPB),false); + else gen_releasereg(DREG(EA)); + gen_releasereg(DREG(TMPB)); } else { - if (op<=DOP_TEST) gen_needflags(); + if (op<=DOP_TEST) { + if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); + else gen_discardflags(); + } gen_dop_byte(op,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,rm_reg,decode.modrm.reg&4); } } @@ -351,12 +394,19 @@ static void dyn_dop_gbeb(DualOps op) { dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg&3]; if (decode.modrm.mod<3) { dyn_fill_ea(); - dyn_read_byte(DREG(EA),DREG(TMPB),false); - if (op<=DOP_TEST) gen_needflags(); + if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); + dyn_read_byte_release(DREG(EA),DREG(TMPB),false); + if (op<=DOP_TEST) { + if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); + else set_skipflags(false); + } gen_dop_byte(op,rm_reg,decode.modrm.reg&4,DREG(TMPB),0); - gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB)); + gen_releasereg(DREG(TMPB)); } else { - if (op<=DOP_TEST) gen_needflags(); + if (op<=DOP_TEST) { + if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); + else gen_discardflags(); + } gen_dop_byte(op,rm_reg,decode.modrm.reg&4,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); } } @@ -364,11 +414,8 @@ static void dyn_dop_gbeb(DualOps op) { static void dyn_mov_ebib(void) { dyn_get_modrm(); if (decode.modrm.mod<3) { - //TODO Maybe not use a temp register here and call mem_writeb directly? dyn_fill_ea(); - gen_dop_byte_imm(DOP_MOV,DREG(TMPB),0,decode_fetchb()); - dyn_write_byte(DREG(EA),DREG(TMPB),false); - gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB)); + gen_call_write(DREG(EA),decode_fetchb(),1); } else { gen_dop_byte_imm(DOP_MOV,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,decode_fetchb()); } @@ -379,8 +426,7 @@ static void dyn_mov_ebgb(void) { DynReg * rm_reg=&DynRegs[decode.modrm.reg&3];Bitu rm_regi=decode.modrm.reg&4; if (decode.modrm.mod<3) { dyn_fill_ea(); - dyn_write_byte(DREG(EA),rm_reg,rm_regi); - gen_releasereg(DREG(EA)); + dyn_write_byte_release(DREG(EA),rm_reg,rm_regi); } else { gen_dop_byte(DOP_MOV,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,rm_reg,rm_regi); } @@ -391,8 +437,7 @@ static void dyn_mov_gbeb(void) { DynReg * rm_reg=&DynRegs[decode.modrm.reg&3];Bitu rm_regi=decode.modrm.reg&4; if (decode.modrm.mod<3) { dyn_fill_ea(); - dyn_read_byte(DREG(EA),rm_reg,rm_regi); - gen_releasereg(DREG(EA)); + dyn_read_byte_release(DREG(EA),rm_reg,rm_regi); } else { gen_dop_byte(DOP_MOV,rm_reg,rm_regi,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); } @@ -403,13 +448,21 @@ static void dyn_dop_evgv(DualOps op) { DynReg * rm_reg=&DynRegs[decode.modrm.reg]; if (decode.modrm.mod<3) { dyn_fill_ea(); + if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); - if (op<=DOP_TEST) gen_needflags(); + if (op<=DOP_TEST) { + if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); + else set_skipflags(false); + } gen_dop_word(op,decode.big_op,DREG(TMPW),rm_reg); - dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); - gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPW)); + if (op!=DOP_CMP) dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); + else gen_releasereg(DREG(EA)); + gen_releasereg(DREG(TMPW)); } else { - if (op<=DOP_TEST) gen_needflags(); + if (op<=DOP_TEST) { + if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); + else gen_discardflags(); + } gen_dop_word(op,decode.big_op,&DynRegs[decode.modrm.rm],rm_reg); } } @@ -418,8 +471,8 @@ static void dyn_imul_gvev(Bitu immsize) { dyn_get_modrm();DynReg * src; DynReg * rm_reg=&DynRegs[decode.modrm.reg]; if (decode.modrm.mod<3) { - dyn_fill_ea();dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); - src=DREG(TMPW);gen_releasereg(DREG(EA)); + dyn_fill_ea();dyn_read_word_release(DREG(EA),DREG(TMPW),decode.big_op); + src=DREG(TMPW); } else { src=&DynRegs[decode.modrm.rm]; } @@ -438,12 +491,19 @@ static void dyn_dop_gvev(DualOps op) { DynReg * rm_reg=&DynRegs[decode.modrm.reg]; if (decode.modrm.mod<3) { dyn_fill_ea(); - dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); - if (op<=DOP_TEST) gen_needflags(); + if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); + dyn_read_word_release(DREG(EA),DREG(TMPW),decode.big_op); + if (op<=DOP_TEST) { + if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); + else set_skipflags(false); + } gen_dop_word(op,decode.big_op,rm_reg,DREG(TMPW)); - gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPW)); + gen_releasereg(DREG(TMPW)); } else { - if (op<=DOP_TEST) gen_needflags(); + if (op<=DOP_TEST) { + if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); + else gen_discardflags(); + } gen_dop_word(op,decode.big_op,rm_reg,&DynRegs[decode.modrm.rm]); } } @@ -453,8 +513,7 @@ static void dyn_mov_evgv(void) { DynReg * rm_reg=&DynRegs[decode.modrm.reg]; if (decode.modrm.mod<3) { dyn_fill_ea(); - dyn_write_word(DREG(EA),rm_reg,decode.big_op); - gen_releasereg(DREG(EA)); + dyn_write_word_release(DREG(EA),rm_reg,decode.big_op); } else { gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],rm_reg); } @@ -465,8 +524,7 @@ static void dyn_mov_gvev(void) { DynReg * rm_reg=&DynRegs[decode.modrm.reg]; if (decode.modrm.mod<3) { dyn_fill_ea(); - dyn_read_word(DREG(EA),rm_reg,decode.big_op); - gen_releasereg(DREG(EA)); + dyn_read_word_release(DREG(EA),rm_reg,decode.big_op); } else { gen_dop_word(DOP_MOV,decode.big_op,rm_reg,&DynRegs[decode.modrm.rm]); } @@ -475,9 +533,7 @@ static void dyn_mov_eviv(void) { dyn_get_modrm(); if (decode.modrm.mod<3) { dyn_fill_ea(); - gen_dop_word_imm(DOP_MOV,decode.big_op,DREG(TMPW),decode.big_op ? decode_fetchd() : decode_fetchw()); - dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); - gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPW)); + gen_call_write(DREG(EA),decode.big_op ? decode_fetchd() : decode_fetchw(),decode.big_op?4:2); } else { gen_dop_word_imm(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],decode.big_op ? decode_fetchd() : decode_fetchw()); } @@ -487,8 +543,7 @@ static void dyn_mov_ev_gb(bool sign) { dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg]; if (decode.modrm.mod<3) { dyn_fill_ea(); - dyn_read_byte(DREG(EA),DREG(TMPB),false); - gen_releasereg(DREG(EA)); + dyn_read_byte_release(DREG(EA),DREG(TMPB),false); gen_extend_byte(sign,decode.big_op,rm_reg,DREG(TMPB),0); gen_releasereg(DREG(TMPB)); } else { @@ -504,9 +559,9 @@ static void dyn_mov_ev_gw(bool sign) { dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg]; if (decode.modrm.mod<3) { dyn_fill_ea(); - dyn_read_word(DREG(EA),DREG(TMPW),false); - gen_releasereg(DREG(EA)); + dyn_read_word_release(DREG(EA),DREG(TMPW),false); gen_extend_word(sign,rm_reg,DREG(TMPW)); + gen_releasereg(DREG(TMPW)); } else { gen_extend_word(sign,rm_reg,&DynRegs[decode.modrm.rm]); } @@ -524,8 +579,8 @@ static void dyn_dshift_ev_gv(bool left,bool immediate) { if (immediate) gen_dshift_imm(decode.big_op,left,ea_reg,rm_reg,decode_fetchb()); else gen_dshift_cl(decode.big_op,left,ea_reg,rm_reg,DREG(ECX)); if (decode.modrm.mod<3) { - dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); - gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPW)); + dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); + gen_releasereg(DREG(TMPW)); } } @@ -533,32 +588,50 @@ static void dyn_dshift_ev_gv(bool left,bool immediate) { static DualOps grp1_table[8]={DOP_ADD,DOP_OR,DOP_ADC,DOP_SBB,DOP_AND,DOP_SUB,DOP_XOR,DOP_CMP}; static void dyn_grp1_eb_ib(void) { dyn_get_modrm(); + DualOps op=grp1_table[decode.modrm.reg]; if (decode.modrm.mod<3) { dyn_fill_ea(); + if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); dyn_read_byte(DREG(EA),DREG(TMPB),false); - gen_needflags(); + if (op<=DOP_TEST) { + if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); + else set_skipflags(false); + } gen_dop_byte_imm(grp1_table[decode.modrm.reg],DREG(TMPB),0,decode_fetchb()); - if (grp1_table[decode.modrm.reg]!=DOP_CMP) dyn_write_byte(DREG(EA),DREG(TMPB),false); - gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB)); + if (op!=DOP_CMP) dyn_write_byte_release(DREG(EA),DREG(TMPB),false); + else gen_releasereg(DREG(EA)); + gen_releasereg(DREG(TMPB)); } else { - gen_needflags(); + if (op<=DOP_TEST) { + if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); + else gen_discardflags(); + } gen_dop_byte_imm(grp1_table[decode.modrm.reg],&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,decode_fetchb()); } } static void dyn_grp1_ev_ivx(bool withbyte) { dyn_get_modrm(); + DualOps op=grp1_table[decode.modrm.reg]; if (decode.modrm.mod<3) { dyn_fill_ea(); + if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); Bits imm=withbyte ? (Bit8s)decode_fetchb() : (decode.big_op ? decode_fetchd(): decode_fetchw()); - gen_needflags(); + if (op<=DOP_TEST) { + if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); + else set_skipflags(false); + } gen_dop_word_imm(grp1_table[decode.modrm.reg],decode.big_op,DREG(TMPW),imm); - dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); - gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPW)); + if (op!=DOP_CMP) dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); + else gen_releasereg(DREG(EA)); + gen_releasereg(DREG(TMPW)); } else { Bits imm=withbyte ? (Bit8s)decode_fetchb() : (decode.big_op ? decode_fetchd(): decode_fetchw()); - gen_needflags(); + if (op<=DOP_TEST) { + if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); + else gen_discardflags(); + } gen_dop_word_imm(grp1_table[decode.modrm.reg],decode.big_op,&DynRegs[decode.modrm.rm],imm); } } @@ -577,21 +650,31 @@ static void dyn_grp2_eb(grp2_types type) { src=&DynRegs[decode.modrm.rm&3]; src_i=decode.modrm.rm&4; } - gen_needflags(); switch (type) { case grp2_1: + /* rotates (first 4 ops) alter cf/of only; shifts (last 4 ops) alter all flags */ + if (decode.modrm.reg < 4) gen_needflags(); + else gen_discardflags(); gen_shift_byte_imm(decode.modrm.reg,src,src_i,1); break; - case grp2_imm: - gen_shift_byte_imm(decode.modrm.reg,src,src_i,decode_fetchb()); + case grp2_imm: { + Bit8u imm=decode_fetchb(); + if (imm) { + /* rotates (first 4 ops) alter cf/of only; shifts (last 4 ops) alter all flags */ + if (decode.modrm.reg < 4) gen_needflags(); + else gen_discardflags(); + gen_shift_byte_imm(decode.modrm.reg,src,src_i,imm); + } else return; + } break; case grp2_cl: + gen_needflags(); /* flags must not be changed on ecx==0 */ gen_shift_byte_cl (decode.modrm.reg,src,src_i,DREG(ECX)); break; } if (decode.modrm.mod<3) { - dyn_write_byte(DREG(EA),src,false); - gen_releasereg(DREG(EA));gen_releasereg(src); + dyn_write_byte_release(DREG(EA),src,false); + gen_releasereg(src); } } @@ -603,21 +686,31 @@ static void dyn_grp2_ev(grp2_types type) { } else { src=&DynRegs[decode.modrm.rm]; } - gen_needflags(); switch (type) { case grp2_1: + /* rotates (first 4 ops) alter cf/of only; shifts (last 4 ops) alter all flags */ + if (decode.modrm.reg < 4) gen_needflags(); + else gen_discardflags(); gen_shift_word_imm(decode.modrm.reg,decode.big_op,src,1); break; - case grp2_imm: - gen_shift_word_imm(decode.modrm.reg,decode.big_op,src,decode_fetchb()); + case grp2_imm: { + Bit8u imm=decode_fetchb(); + if (imm) { + /* rotates (first 4 ops) alter cf/of only; shifts (last 4 ops) alter all flags */ + if (decode.modrm.reg < 4) gen_needflags(); + else gen_discardflags(); + gen_shift_word_imm(decode.modrm.reg,decode.big_op,src,imm); + } else return; + } break; case grp2_cl: + gen_needflags(); /* flags must not be changed on ecx==0 */ gen_shift_word_cl (decode.modrm.reg,decode.big_op,src,DREG(ECX)); break; } if (decode.modrm.mod<3) { - dyn_write_word(DREG(EA),src,decode.big_op); - gen_releasereg(DREG(EA));gen_releasereg(src); + dyn_write_word_release(DREG(EA),src,decode.big_op); + gen_releasereg(src); } } @@ -625,6 +718,7 @@ static void dyn_grp3_eb(void) { dyn_get_modrm();DynReg * src;Bit8u src_i; if (decode.modrm.mod<3) { dyn_fill_ea(); + if ((decode.modrm.reg==0) || (decode.modrm.reg==3)) set_skipflags(true); dyn_read_byte(DREG(EA),DREG(TMPB),false); src=DREG(TMPB);src_i=0; } else { @@ -633,13 +727,13 @@ static void dyn_grp3_eb(void) { } switch (decode.modrm.reg) { case 0x0: /* test eb,ib */ - gen_needflags();gen_dop_byte_imm(DOP_TEST,src,src_i,decode_fetchb()); + set_skipflags(false);gen_dop_byte_imm(DOP_TEST,src,src_i,decode_fetchb()); goto skipsave; case 0x2: /* NOT Eb */ - gen_needflags();gen_sop_byte(SOP_NOT,src,src_i); + gen_sop_byte(SOP_NOT,src,src_i); break; case 0x3: /* NEG Eb */ - gen_needflags();gen_sop_byte(SOP_NEG,src,src_i); + set_skipflags(false);gen_sop_byte(SOP_NEG,src,src_i); break; case 0x4: /* mul Eb */ gen_needflags();gen_mul_byte(false,DREG(EAX),src,src_i); @@ -651,15 +745,15 @@ static void dyn_grp3_eb(void) { case 0x7: /* idiv Eb */ /* EAX could be used, so precache it */ if (decode.modrm.mod==3) - gen_dop_byte(DOP_MOV,DREG(TMPB),0,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); + gen_dop_byte(DOP_MOV,src,0,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); gen_releasereg(DREG(EAX)); gen_call_function((decode.modrm.reg==6) ? (void *)&dyn_helper_divb : (void *)&dyn_helper_idivb, - "%Rd%Drl",DREG(TMPB),DREG(TMPB)); + "%Rd%Dd",DREG(TMPB),src); dyn_check_bool_exception(DREG(TMPB)); goto skipsave; } /* Save the result if memory op */ - if (decode.modrm.mod<3) dyn_write_byte(DREG(EA),DREG(TMPB),false); + if (decode.modrm.mod<3) dyn_write_byte_release(DREG(EA),src,false); skipsave: gen_releasereg(DREG(TMPB));gen_releasereg(DREG(EA)); } @@ -668,17 +762,18 @@ static void dyn_grp3_ev(void) { dyn_get_modrm();DynReg * src; if (decode.modrm.mod<3) { dyn_fill_ea();src=DREG(TMPW); + if ((decode.modrm.reg==0) || (decode.modrm.reg==3)) set_skipflags(true); dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); } else src=&DynRegs[decode.modrm.rm]; switch (decode.modrm.reg) { case 0x0: /* test ev,iv */ - gen_needflags();gen_dop_word_imm(DOP_TEST,decode.big_op,src,decode.big_op ? decode_fetchd() : decode_fetchw()); + set_skipflags(false);gen_dop_word_imm(DOP_TEST,decode.big_op,src,decode.big_op ? decode_fetchd() : decode_fetchw()); goto skipsave; case 0x2: /* NOT Ev */ - gen_needflags();gen_sop_word(SOP_NOT,decode.big_op,src); + gen_sop_word(SOP_NOT,decode.big_op,src); break; case 0x3: /* NEG Eb */ - gen_needflags();gen_sop_word(SOP_NEG,decode.big_op,src); + set_skipflags(false);gen_sop_word(SOP_NEG,decode.big_op,src); break; case 0x4: /* mul Eb */ gen_needflags();gen_mul_word(false,DREG(EAX),DREG(EDX),decode.big_op,src); @@ -690,17 +785,18 @@ static void dyn_grp3_ev(void) { case 0x7: /* idiv Eb */ /* EAX could be used, so precache it */ if (decode.modrm.mod==3) - gen_dop_word(DOP_MOV,decode.big_op,DREG(TMPW),&DynRegs[decode.modrm.rm]); + gen_dop_word(DOP_MOV,decode.big_op,src,&DynRegs[decode.modrm.rm]); gen_releasereg(DREG(EAX));gen_releasereg(DREG(EDX)); void * func=(decode.modrm.reg==6) ? (decode.big_op ? (void *)&dyn_helper_divd : (void *)&dyn_helper_divw) : (decode.big_op ? (void *)&dyn_helper_idivd : (void *)&dyn_helper_idivw); - gen_call_function(func,"%Rd%Drd",DREG(TMPB),DREG(TMPW)); + gen_call_function(func,"%Rd%Dd",DREG(TMPB),src); dyn_check_bool_exception(DREG(TMPB)); + gen_releasereg(DREG(TMPB)); goto skipsave; } /* Save the result if memory op */ - if (decode.modrm.mod<3) dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); + if (decode.modrm.mod<3) dyn_write_word_release(DREG(EA),src,decode.big_op); skipsave: gen_releasereg(DREG(TMPW));gen_releasereg(DREG(EA)); } @@ -710,8 +806,7 @@ static void dyn_mov_ev_seg(void) { gen_load_host(&Segs.val[decode.modrm.reg],DREG(TMPW),2); if (decode.modrm.mod<3) { dyn_fill_ea(); - dyn_write_word(DREG(EA),DREG(TMPW),false); - gen_releasereg(DREG(EA)); + dyn_write_word_release(DREG(EA),DREG(TMPW),false); } else { gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],DREG(TMPW)); } @@ -722,6 +817,7 @@ static void dyn_load_seg(SegNames seg,DynReg * src) { if (cpu.pmode) { gen_call_function((void *)&CPU_SetSegGeneral,"%Rd%Id%Drw",DREG(TMPB),seg,src); dyn_check_bool_exception(DREG(TMPB)); + gen_releasereg(DREG(TMPB)); } else gen_call_function((void *)CPU_SetSegGeneral,"%Id%Drw",seg,src); gen_releasereg(&DynRegs[G_ES+seg]); if (seg==ss) gen_releasereg(DREG(SMASK)); @@ -729,13 +825,12 @@ static void dyn_load_seg(SegNames seg,DynReg * src) { static void dyn_load_seg_off_ea(SegNames seg) { dyn_get_modrm(); - if (decode.modrm.mod<3) { + if (GCC_UNLIKELY(decode.modrm.mod<3)) { dyn_fill_ea(); gen_lea(DREG(TMPW),DREG(EA),0,0,decode.big_op ? 4:2); dyn_read_word(DREG(TMPW),DREG(TMPW),false); dyn_load_seg(seg,DREG(TMPW));gen_releasereg(DREG(TMPW)); - dyn_read_word(DREG(EA),&DynRegs[decode.modrm.reg],decode.big_op); - gen_releasereg(DREG(EA)); + dyn_read_word_release(DREG(EA),&DynRegs[decode.modrm.reg],decode.big_op); } else { IllegalOption(); } @@ -744,7 +839,7 @@ static void dyn_load_seg_off_ea(SegNames seg) { static void dyn_mov_seg_ev(void) { dyn_get_modrm(); SegNames seg=(SegNames)decode.modrm.reg; - if (seg==cs) IllegalOption(); + if (GCC_UNLIKELY(seg==cs)) IllegalOption(); if (decode.modrm.mod<3) { dyn_fill_ea(); dyn_read_word(DREG(EA),DREG(EA),false); @@ -770,6 +865,7 @@ static void dyn_pop_seg(SegNames seg) { gen_releasereg(DREG(ESP)); gen_call_function((void *)&CPU_PopSeg,"%Rd%Id%Id",DREG(TMPB),seg,decode.big_op); dyn_check_bool_exception(DREG(TMPB)); + gen_releasereg(DREG(TMPB)); gen_releasereg(&DynRegs[G_ES+seg]); gen_releasereg(DREG(ESP)); if (seg==ss) gen_releasereg(DREG(SMASK)); @@ -781,8 +877,7 @@ static void dyn_pop_ev(void) { dyn_get_modrm(); if (decode.modrm.mod<3) { dyn_fill_ea(); - dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); - gen_releasereg(DREG(EA)); + dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); } else { gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],DREG(TMPW)); } @@ -810,7 +905,7 @@ static void dyn_leave(void) { } static void dyn_segprefix(SegNames seg) { - if (decode.segprefix) IllegalOption(); + if (GCC_UNLIKELY(decode.segprefix)) IllegalOption(); decode.segprefix=&DynRegs[G_ES+seg]; } @@ -840,21 +935,36 @@ static void dyn_exit_link(Bits eip_change) { static void dyn_branched_exit(BranchTypes btype,Bit32s eip_add) { Bitu eip_base=decode.code-decode.code_start; - dyn_reduce_cycles(); - dyn_save_critical_regs(); - gen_needflags(); - gen_protectflags(); + gen_needflags(); + gen_protectflags(); + dyn_save_noncritical_regs(); + gen_releasereg(DREG(FLAGS)); + gen_releasereg(DREG(EIP)); + + gen_preloadreg(DREG(CYCLES)); + gen_preloadreg(DREG(EIP)); + DynReg save_cycles,save_eip; + dyn_saveregister(DREG(CYCLES),&save_cycles); + dyn_saveregister(DREG(EIP),&save_eip); Bit8u * data=gen_create_branch(btype); - /* Branch not taken */ - gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),eip_base); - gen_releasereg(DREG(EIP)); - gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); - gen_fill_branch(data); - /* Branch taken */ - gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),eip_base+eip_add); - gen_releasereg(DREG(EIP)); - gen_jmp_ptr(&decode.block->link[1].to,offsetof(CacheBlock,cache.start)); - dyn_closeblock(); + + /* Branch not taken */ + dyn_reduce_cycles(); + gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),eip_base); + gen_releasereg(DREG(CYCLES)); + gen_releasereg(DREG(EIP)); + gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); + gen_fill_branch(data); + + /* Branch taken */ + dyn_restoreregister(&save_cycles,DREG(CYCLES)); + dyn_restoreregister(&save_eip,DREG(EIP)); + dyn_reduce_cycles(); + gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),eip_base+eip_add); + gen_releasereg(DREG(CYCLES)); + gen_releasereg(DREG(EIP)); + gen_jmp_ptr(&decode.block->link[1].to,offsetof(CacheBlock,cache.start)); + dyn_closeblock(); } enum LoopTypes { @@ -1040,8 +1150,8 @@ restart_prefix: case 0x01:dyn_dop_evgv(DOP_ADD);break; case 0x02:dyn_dop_gbeb(DOP_ADD);break; case 0x03:dyn_dop_gvev(DOP_ADD);break; - case 0x04:gen_needflags();gen_dop_byte_imm(DOP_ADD,DREG(EAX),0,decode_fetchb());break; - case 0x05:gen_needflags();gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; + case 0x04:gen_discardflags();gen_dop_byte_imm(DOP_ADD,DREG(EAX),0,decode_fetchb());break; + case 0x05:gen_discardflags();gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; case 0x06:dyn_push_seg(es);break; case 0x07:dyn_pop_seg(es);break; @@ -1049,8 +1159,8 @@ restart_prefix: case 0x09:dyn_dop_evgv(DOP_OR);break; case 0x0a:dyn_dop_gbeb(DOP_OR);break; case 0x0b:dyn_dop_gvev(DOP_OR);break; - case 0x0c:gen_needflags();gen_dop_byte_imm(DOP_OR,DREG(EAX),0,decode_fetchb());break; - case 0x0d:gen_needflags();gen_dop_word_imm(DOP_OR,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; + case 0x0c:gen_discardflags();gen_dop_byte_imm(DOP_OR,DREG(EAX),0,decode_fetchb());break; + case 0x0d:gen_discardflags();gen_dop_word_imm(DOP_OR,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; case 0x0e:dyn_push_seg(cs);break; case 0x0f: { @@ -1096,8 +1206,8 @@ restart_prefix: case 0x11:dyn_dop_evgv(DOP_ADC);break; case 0x12:dyn_dop_gbeb(DOP_ADC);break; case 0x13:dyn_dop_gvev(DOP_ADC);break; - case 0x14:gen_needflags();gen_dop_byte_imm(DOP_ADC,DREG(EAX),0,decode_fetchb());break; - case 0x15:gen_needflags();gen_dop_word_imm(DOP_ADC,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; + case 0x14:gen_needcarry();gen_dop_byte_imm(DOP_ADC,DREG(EAX),0,decode_fetchb());break; + case 0x15:gen_needcarry();gen_dop_word_imm(DOP_ADC,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; case 0x16:dyn_push_seg(ss);break; case 0x17:dyn_pop_seg(ss);break; @@ -1105,48 +1215,48 @@ restart_prefix: case 0x19:dyn_dop_evgv(DOP_SBB);break; case 0x1a:dyn_dop_gbeb(DOP_SBB);break; case 0x1b:dyn_dop_gvev(DOP_SBB);break; - case 0x1c:gen_needflags();gen_dop_byte_imm(DOP_SBB,DREG(EAX),0,decode_fetchb());break; - case 0x1d:gen_needflags();gen_dop_word_imm(DOP_SBB,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; + case 0x1c:gen_needcarry();gen_dop_byte_imm(DOP_SBB,DREG(EAX),0,decode_fetchb());break; + case 0x1d:gen_needcarry();gen_dop_word_imm(DOP_SBB,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; case 0x1e:dyn_push_seg(ds);break; case 0x1f:dyn_pop_seg(ds);break; case 0x20:dyn_dop_ebgb(DOP_AND);break; case 0x21:dyn_dop_evgv(DOP_AND);break; case 0x22:dyn_dop_gbeb(DOP_AND);break; case 0x23:dyn_dop_gvev(DOP_AND);break; - case 0x24:gen_needflags();gen_dop_byte_imm(DOP_AND,DREG(EAX),0,decode_fetchb());break; - case 0x25:gen_needflags();gen_dop_word_imm(DOP_AND,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; + case 0x24:gen_discardflags();gen_dop_byte_imm(DOP_AND,DREG(EAX),0,decode_fetchb());break; + case 0x25:gen_discardflags();gen_dop_word_imm(DOP_AND,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; case 0x26:dyn_segprefix(es);goto restart_prefix; case 0x28:dyn_dop_ebgb(DOP_SUB);break; case 0x29:dyn_dop_evgv(DOP_SUB);break; case 0x2a:dyn_dop_gbeb(DOP_SUB);break; case 0x2b:dyn_dop_gvev(DOP_SUB);break; - case 0x2c:gen_needflags();gen_dop_byte_imm(DOP_SUB,DREG(EAX),0,decode_fetchb());break; - case 0x2d:gen_needflags();gen_dop_word_imm(DOP_SUB,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; + case 0x2c:gen_discardflags();gen_dop_byte_imm(DOP_SUB,DREG(EAX),0,decode_fetchb());break; + case 0x2d:gen_discardflags();gen_dop_word_imm(DOP_SUB,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; case 0x2e:dyn_segprefix(cs);goto restart_prefix; case 0x30:dyn_dop_ebgb(DOP_XOR);break; case 0x31:dyn_dop_evgv(DOP_XOR);break; case 0x32:dyn_dop_gbeb(DOP_XOR);break; case 0x33:dyn_dop_gvev(DOP_XOR);break; - case 0x34:gen_needflags();gen_dop_byte_imm(DOP_XOR,DREG(EAX),0,decode_fetchb());break; - case 0x35:gen_needflags();gen_dop_word_imm(DOP_XOR,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; + case 0x34:gen_discardflags();gen_dop_byte_imm(DOP_XOR,DREG(EAX),0,decode_fetchb());break; + case 0x35:gen_discardflags();gen_dop_word_imm(DOP_XOR,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; case 0x36:dyn_segprefix(ss);goto restart_prefix; case 0x38:dyn_dop_ebgb(DOP_CMP);break; case 0x39:dyn_dop_evgv(DOP_CMP);break; case 0x3a:dyn_dop_gbeb(DOP_CMP);break; case 0x3b:dyn_dop_gvev(DOP_CMP);break; - case 0x3c:gen_needflags();gen_dop_byte_imm(DOP_CMP,DREG(EAX),0,decode_fetchb());break; - case 0x3d:gen_needflags();gen_dop_word_imm(DOP_CMP,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; + case 0x3c:gen_discardflags();gen_dop_byte_imm(DOP_CMP,DREG(EAX),0,decode_fetchb());break; + case 0x3d:gen_discardflags();gen_dop_word_imm(DOP_CMP,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; case 0x3e:dyn_segprefix(ds);goto restart_prefix; /* INC/DEC general register */ case 0x40:case 0x41:case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:case 0x47: - gen_needflags();gen_sop_word(SOP_INC,decode.big_op,&DynRegs[opcode&7]); + gen_needcarry();gen_sop_word(SOP_INC,decode.big_op,&DynRegs[opcode&7]); break; case 0x48:case 0x49:case 0x4a:case 0x4b:case 0x4c:case 0x4d:case 0x4e:case 0x4f: - gen_needflags();gen_sop_word(SOP_DEC,decode.big_op,&DynRegs[opcode&7]); + gen_needcarry();gen_sop_word(SOP_DEC,decode.big_op,&DynRegs[opcode&7]); break; /* PUSH/POP General register */ case 0x50:case 0x51:case 0x52:case 0x53:case 0x55:case 0x56:case 0x57: @@ -1220,9 +1330,14 @@ restart_prefix: case 0x8c:dyn_mov_ev_seg();break; /* LEA Gv */ case 0x8d: - dyn_get_modrm();dyn_fill_ea(false); - gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.reg],DREG(EA)); - gen_releasereg(DREG(EA)); + dyn_get_modrm(); + if (decode.big_op) { + dyn_fill_ea(false,&DynRegs[decode.modrm.reg]); + } else { + dyn_fill_ea(false); + gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.reg],DREG(EA)); + gen_releasereg(DREG(EA)); + } break; /* Mov seg,ev */ case 0x8e:dyn_mov_seg_ev();break; @@ -1265,36 +1380,32 @@ restart_prefix: case 0xa0: gen_lea(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),0,0, decode.big_addr ? decode_fetchd() : decode_fetchw()); - dyn_read_byte(DREG(EA),DREG(EAX),false); - gen_releasereg(DREG(EA)); + dyn_read_byte_release(DREG(EA),DREG(EAX),false); break; /* MOV AX,direct addresses */ case 0xa1: gen_lea(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),0,0, decode.big_addr ? decode_fetchd() : decode_fetchw()); - dyn_read_word(DREG(EA),DREG(EAX),decode.big_op); - gen_releasereg(DREG(EA)); + dyn_read_word_release(DREG(EA),DREG(EAX),decode.big_op); break; /* MOV direct address,AL */ case 0xa2: gen_lea(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),0,0, decode.big_addr ? decode_fetchd() : decode_fetchw()); - dyn_write_byte(DREG(EA),DREG(EAX),false); - gen_releasereg(DREG(EA)); + dyn_write_byte_release(DREG(EA),DREG(EAX),false); break; /* MOV direct addresses,AX */ case 0xa3: gen_lea(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),0,0, decode.big_addr ? decode_fetchd() : decode_fetchw()); - dyn_write_word(DREG(EA),DREG(EAX),decode.big_op); - gen_releasereg(DREG(EA)); + dyn_write_word_release(DREG(EA),DREG(EAX),decode.big_op); break; /* MOVSB/W/D*/ case 0xa4:dyn_string(STR_MOVSB);break; case 0xa5:dyn_string(decode.big_op ? STR_MOVSD : STR_MOVSW);break; /* TEST AL,AX Imm */ - case 0xa8:gen_needflags();gen_dop_byte_imm(DOP_TEST,DREG(EAX),0,decode_fetchb());break; - case 0xa9:gen_needflags();gen_dop_word_imm(DOP_TEST,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; + case 0xa8:gen_discardflags();gen_dop_byte_imm(DOP_TEST,DREG(EAX),0,decode_fetchb());break; + case 0xa9:gen_discardflags();gen_dop_word_imm(DOP_TEST,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; /* STOSB/W/D*/ case 0xaa:dyn_string(STR_STOSB);break; case 0xab:dyn_string(decode.big_op ? STR_STOSD : STR_STOSW);break; @@ -1377,7 +1488,6 @@ restart_prefix: case 0xe2:dyn_loop(LOOP_NONE);goto finish_block; case 0xe3:dyn_loop(LOOP_JCXZ);goto finish_block; //IN AL/AX,imm - case 0xe4:gen_call_function((void*)&IO_ReadB,"%Id%Rl",decode_fetchb(),DREG(EAX));break; case 0xe5: if (decode.big_op) { @@ -1424,7 +1534,6 @@ restart_prefix: gen_call_function((void*)&IO_WriteW,"%Dw%Dw",DREG(EDX),DREG(EAX)); } break; - case 0xf2: //REPNE/NZ decode.rep=REP_NZ; goto restart_prefix; @@ -1444,10 +1553,12 @@ restart_prefix: case 0xfa: //CLI gen_call_function((void *)&CPU_CLI,"%Rd",DREG(TMPB)); if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); + gen_releasereg(DREG(TMPB)); break; case 0xfb: //STI gen_call_function((void *)&CPU_STI,"%Rd",DREG(TMPB)); if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); + gen_releasereg(DREG(TMPB)); if (max_opcodes<=0) max_opcodes=1; //Allow 1 extra opcode break; case 0xfc: //CLD @@ -1468,12 +1579,12 @@ restart_prefix: case 0x1://DEC Eb if (decode.modrm.mod<3) { dyn_fill_ea();dyn_read_byte(DREG(EA),DREG(TMPB),false); - gen_needflags(); + gen_needcarry(); gen_sop_byte(decode.modrm.reg==0 ? SOP_INC : SOP_DEC,DREG(TMPB),0); - dyn_write_byte(DREG(EA),DREG(TMPB),false); - gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB)); + dyn_write_byte_release(DREG(EA),DREG(TMPB),false); + gen_releasereg(DREG(TMPB)); } else { - gen_needflags(); + gen_needcarry(); gen_sop_byte(decode.modrm.reg==0 ? SOP_INC : SOP_DEC, &DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); } @@ -1500,11 +1611,11 @@ restart_prefix: switch (decode.modrm.reg) { case 0x0://INC Ev case 0x1://DEC Ev - gen_needflags(); + gen_needcarry(); gen_sop_word(decode.modrm.reg==0 ? SOP_INC : SOP_DEC,decode.big_op,src); if (decode.modrm.mod<3){ - dyn_write_word(DREG(EA),DREG(TMPW),decode.big_op); - gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPW)); + dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); + gen_releasereg(DREG(TMPW)); } break; case 0x2: /* CALL Ev */ @@ -1530,6 +1641,7 @@ restart_prefix: dyn_flags_host_to_gen(); goto core_close_block; case 0x6: /* PUSH Ev */ + gen_releasereg(DREG(EA)); dyn_push(src); break; default: diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 3f50ae83..53e8df24 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -39,36 +39,35 @@ static struct { class GenReg { public: - GenReg(Bit8u _index,bool _protect) { - index=_index;protect=_protect; + GenReg(Bit8u _index) { + index=_index; notusable=false;dynreg=0; } DynReg * dynreg; Bitu last_used; //Keeps track of last assigned regs Bit8u index; bool notusable; - bool protect; - void Load(DynReg * _dynreg) { + void Load(DynReg * _dynreg,bool stale=false) { if (!_dynreg) return; - if (dynreg) Clear(); + if (GCC_UNLIKELY(dynreg)) Clear(); dynreg=_dynreg; last_used=x86gen.last_used; dynreg->flags&=~DYNFLG_CHANGED; dynreg->genreg=this; - if (dynreg->flags & (DYNFLG_LOAD|DYNFLG_ACTIVE)) { + if ((!stale) && (dynreg->flags & (DYNFLG_LOAD|DYNFLG_ACTIVE))) { cache_addw(0x058b+(index << (8+3))); //Mov reg,[data] cache_addd((Bit32u)dynreg->data); } dynreg->flags|=DYNFLG_ACTIVE; } void Save(void) { - if (!dynreg) IllegalOption(); + if (GCC_UNLIKELY(!dynreg)) IllegalOption(); dynreg->flags&=~DYNFLG_CHANGED; cache_addw(0x0589+(index << (8+3))); //Mov [data],reg cache_addd((Bit32u)dynreg->data); } void Release(void) { - if (!dynreg) return; + if (GCC_UNLIKELY(!dynreg)) return; if (dynreg->flags&DYNFLG_CHANGED && dynreg->flags&DYNFLG_SAVE) { Save(); } @@ -82,8 +81,6 @@ public: } dynreg->genreg=0;dynreg=0; } - - }; static BlockReturn gen_runcode(Bit8u * code) { @@ -131,7 +128,7 @@ return_address: return retval; } -static GenReg * FindDynReg(DynReg * dynreg) { +static GenReg * FindDynReg(DynReg * dynreg,bool stale=false) { x86gen.last_used++; if (dynreg->genreg) { dynreg->genreg->last_used=x86gen.last_used; @@ -143,11 +140,11 @@ static GenReg * FindDynReg(DynReg * dynreg) { first_used=-1; if (dynreg->flags & DYNFLG_HAS8) { /* Has to be eax,ebx,ecx,edx */ - for (i=first_index=0;i<=X86_REG_EDX;i++) { + for (i=first_index=0;i<=X86_REG_EBX;i++) { GenReg * genreg=x86gen.regs[i]; if (genreg->notusable) continue; if (!(genreg->dynreg)) { - genreg->Load(dynreg); + genreg->Load(dynreg,stale); return genreg; } if (genreg->last_usedLoad(dynreg); - return newreg; } else { for (i=first_index=X86_REGS-1;i>=0;i--) { GenReg * genreg=x86gen.regs[i]; if (genreg->notusable) continue; if (!(genreg->dynreg)) { - genreg->Load(dynreg); + genreg->Load(dynreg,stale); return genreg; } if (genreg->last_usedLoad(dynreg); - return newreg; } + /* No free register found use earliest assigned one */ + GenReg * newreg=x86gen.regs[first_index]; + newreg->Load(dynreg,stale); + return newreg; } static GenReg * ForceDynReg(GenReg * genreg,DynReg * dynreg) { @@ -242,6 +235,30 @@ static void gen_protectflags(void) { } } +static void gen_discardflags(void) { + if (!x86gen.flagsactive) { + x86gen.flagsactive=true; + cache_addw(0xc483); //ADD ESP,4 + cache_addb(0x4); + } +} + +static void gen_needcarry(void) { + if (!x86gen.flagsactive) { + x86gen.flagsactive=true; + cache_addw(0x2cd1); //SHR DWORD [ESP],1 + cache_addb(0x24); + cache_addd(0x0424648d); //LEA ESP,[ESP+4] + } +} + +static bool skip_flags=false; + +static void set_skipflags(bool state) { + if (!state) gen_discardflags(); + skip_flags=state; +} + static void gen_reinit(void) { x86gen.last_used=0; x86gen.flagsactive=false; @@ -252,87 +269,72 @@ static void gen_reinit(void) { static void gen_dop_byte(DualOps op,DynReg * dr1,Bit8u di1,DynReg * dr2,Bit8u di2) { GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2); + Bit8u tmp; switch (op) { - case DOP_ADD:cache_addb(0x02);dr1->flags|=DYNFLG_CHANGED;break; - case DOP_OR: cache_addb(0x0a);dr1->flags|=DYNFLG_CHANGED;break; - case DOP_ADC:cache_addb(0x12);dr1->flags|=DYNFLG_CHANGED;break; - case DOP_SBB:cache_addb(0x1a);dr1->flags|=DYNFLG_CHANGED;break; - case DOP_AND:cache_addb(0x22);dr1->flags|=DYNFLG_CHANGED;break; - case DOP_SUB:cache_addb(0x2a);dr1->flags|=DYNFLG_CHANGED;break; - case DOP_XOR:cache_addb(0x32);dr1->flags|=DYNFLG_CHANGED;break; - case DOP_CMP:cache_addb(0x3a);break; - case DOP_MOV:cache_addb(0x8a);dr1->flags|=DYNFLG_CHANGED;break; - case DOP_XCHG:cache_addb(0x86);dr1->flags|=DYNFLG_CHANGED;dr2->flags|=DYNFLG_CHANGED;break; - case DOP_TEST:cache_addb(0x84);break; + case DOP_ADD: tmp=0x02; break; + case DOP_ADC: tmp=0x12; break; + case DOP_SUB: tmp=0x2a; break; + case DOP_SBB: tmp=0x1a; break; + case DOP_CMP: tmp=0x3a; goto nochange; + case DOP_XOR: tmp=0x32; break; + case DOP_AND: tmp=0x22; if ((dr1==dr2) && (di1==di2)) goto nochange; break; + case DOP_OR: tmp=0x0a; if ((dr1==dr2) && (di1==di2)) goto nochange; break; + case DOP_TEST: tmp=0x84; goto nochange; + case DOP_MOV: if ((dr1==dr2) && (di1==di2)) return; tmp=0x8a; break; + case DOP_XCHG: tmp=0x86; dr2->flags|=DYNFLG_CHANGED; break; default: IllegalOption(); } - cache_addb(0xc0+((gr1->index+di1)<<3)+gr2->index+di2); + dr1->flags|=DYNFLG_CHANGED; +nochange: + cache_addw(tmp|(0xc0+((gr1->index+di1)<<3)+gr2->index+di2)<<8); } static void gen_dop_byte_imm(DualOps op,DynReg * dr1,Bit8u di1,Bitu imm) { GenReg * gr1=FindDynReg(dr1); + Bit16u tmp; switch (op) { - case DOP_ADD: - cache_addw(0xc080+((gr1->index+di1)<<8)); - dr1->flags|=DYNFLG_CHANGED; - break; - case DOP_OR: - cache_addw(0xc880+((gr1->index+di1)<<8)); - dr1->flags|=DYNFLG_CHANGED; - break; - case DOP_ADC: - cache_addw(0xd080+((gr1->index+di1)<<8)); - dr1->flags|=DYNFLG_CHANGED; - break; - case DOP_SBB: - cache_addw(0xd880+((gr1->index+di1)<<8)); - dr1->flags|=DYNFLG_CHANGED; - break; - case DOP_AND: - cache_addw(0xe080+((gr1->index+di1)<<8)); - dr1->flags|=DYNFLG_CHANGED; - break; - case DOP_SUB: - cache_addw(0xe880+((gr1->index+di1)<<8)); - dr1->flags|=DYNFLG_CHANGED; - break; - case DOP_XOR: - cache_addw(0xf080+((gr1->index+di1)<<8)); - dr1->flags|=DYNFLG_CHANGED; - break; - case DOP_CMP: - cache_addw(0xf880+((gr1->index+di1)<<8)); - break;//Doesn't change - case DOP_MOV: - cache_addb(0xb0+gr1->index+di1); - dr1->flags|=DYNFLG_CHANGED; - break; - case DOP_TEST: - cache_addw(0xc0f6+((gr1->index+di1)<<8)); - break;//Doesn't change + case DOP_ADD: tmp=0xc080; break; + case DOP_ADC: tmp=0xd080; break; + case DOP_SUB: tmp=0xe880; break; + case DOP_SBB: tmp=0xd880; break; + case DOP_CMP: tmp=0xf880; goto nochange; //Doesn't change + case DOP_XOR: tmp=0xf080; break; + case DOP_AND: tmp=0xe080; break; + case DOP_OR: tmp=0xc880; break; + case DOP_TEST: tmp=0xc0f6; goto nochange; //Doesn't change + case DOP_MOV: cache_addb(0xb0+gr1->index+di1); + dr1->flags|=DYNFLG_CHANGED; + goto finish; default: IllegalOption(); } + dr1->flags|=DYNFLG_CHANGED; +nochange: + cache_addw(tmp+((gr1->index+di1)<<8)); +finish: cache_addb(imm); } static void gen_sop_byte(SingleOps op,DynReg * dr1,Bit8u di1) { GenReg * gr1=FindDynReg(dr1); + Bit16u tmp; switch (op) { - case SOP_INC:cache_addw(0xc0FE + ((gr1->index+di1)<<8));break; - case SOP_DEC:cache_addw(0xc8FE + ((gr1->index+di1)<<8));break; - case SOP_NOT:cache_addw(0xd0f6 + ((gr1->index+di1)<<8));break; - case SOP_NEG:cache_addw(0xd8f6 + ((gr1->index+di1)<<8));break; + case SOP_INC: tmp=0xc0FE; break; + case SOP_DEC: tmp=0xc8FE; break; + case SOP_NOT: tmp=0xd0f6; break; + case SOP_NEG: tmp=0xd8f6; break; default: IllegalOption(); } + cache_addw(tmp + ((gr1->index+di1)<<8)); dr1->flags|=DYNFLG_CHANGED; } static void gen_extend_word(bool sign,DynReg * ddr,DynReg * dsr) { - GenReg * gdr=FindDynReg(ddr);GenReg * gsr=FindDynReg(dsr); + GenReg * gsr=FindDynReg(dsr); + GenReg * gdr=FindDynReg(ddr,true); if (sign) cache_addw(0xbf0f); else cache_addw(0xb70f); cache_addb(0xc0+(gdr->index<<3)+(gsr->index)); @@ -340,7 +342,8 @@ static void gen_extend_word(bool sign,DynReg * ddr,DynReg * dsr) { } static void gen_extend_byte(bool sign,bool dword,DynReg * ddr,DynReg * dsr,Bit8u dsi) { - GenReg * gdr=FindDynReg(ddr);GenReg * gsr=FindDynReg(dsr); + GenReg * gsr=FindDynReg(dsr); + GenReg * gdr=FindDynReg(ddr,dword); if (!dword) cache_addb(0x66); if (sign) cache_addw(0xbe0f); else cache_addw(0xb60f); @@ -368,6 +371,7 @@ static void gen_lea(DynReg * ddr,DynReg * dsr1,DynReg * dsr2,Bitu scale,Bits imm Bit8u sib=(gsr1->index)+(gsr2->index<<3)+(scale<<6); cache_addb(sib); } else { + if ((ddr==dsr1) && !imm_size) return; cache_addb(0x8d); //LEA cache_addb(rm_base+gsr1->index); } @@ -394,59 +398,80 @@ static void gen_lea(DynReg * ddr,DynReg * dsr1,DynReg * dsr2,Bitu scale,Bits imm } static void gen_dop_word(DualOps op,bool dword,DynReg * dr1,DynReg * dr2) { - GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2); - if (!dword) cache_addb(0x66); + GenReg * gr2=FindDynReg(dr2); + GenReg * gr1=FindDynReg(dr1,dword && op==DOP_MOV); + Bit8u tmp; switch (op) { - case DOP_ADD:cache_addb(0x03);dr1->flags|=DYNFLG_CHANGED;break; - case DOP_OR: cache_addb(0x0b);dr1->flags|=DYNFLG_CHANGED;break; - case DOP_ADC:cache_addb(0x13);dr1->flags|=DYNFLG_CHANGED;break; - case DOP_SBB:cache_addb(0x1b);dr1->flags|=DYNFLG_CHANGED;break; - case DOP_AND:cache_addb(0x23);dr1->flags|=DYNFLG_CHANGED;break; - case DOP_SUB:cache_addb(0x2b);dr1->flags|=DYNFLG_CHANGED;break; - case DOP_XOR:cache_addb(0x33);dr1->flags|=DYNFLG_CHANGED;break; - case DOP_CMP:cache_addb(0x3b);break; - case DOP_MOV:cache_addb(0x8b);dr1->flags|=DYNFLG_CHANGED;break; - case DOP_XCHG:cache_addb(0x87);dr1->flags|=DYNFLG_CHANGED;dr2->flags|=DYNFLG_CHANGED;break; - case DOP_TEST:cache_addb(0x85);break; + case DOP_ADD: tmp=0x03; break; + case DOP_ADC: tmp=0x13; break; + case DOP_SUB: tmp=0x2b; break; + case DOP_SBB: tmp=0x1b; break; + case DOP_CMP: tmp=0x3b; goto nochange; + case DOP_XOR: tmp=0x33; break; + case DOP_AND: tmp=0x23; if (dr1==dr2) goto nochange; break; + case DOP_OR: tmp=0x0b; if (dr1==dr2) goto nochange; break; + case DOP_TEST: tmp=0x85; goto nochange; + case DOP_MOV: if (dr1==dr2) return; tmp=0x8b; break; + case DOP_XCHG: + dr2->flags|=DYNFLG_CHANGED; + if (dword && !((dr1->flags&DYNFLG_HAS8) ^ (dr2->flags&DYNFLG_HAS8))) { + dr1->genreg=gr2;dr1->genreg->dynreg=dr1; + dr2->genreg=gr1;dr2->genreg->dynreg=dr2; + dr1->flags|=DYNFLG_CHANGED; + return; + } + tmp=0x87; + break; default: IllegalOption(); } - cache_addb(0xc0+(gr1->index<<3)+gr2->index); + dr1->flags|=DYNFLG_CHANGED; +nochange: + if (!dword) cache_addb(0x66); + cache_addw(tmp|(0xc0+(gr1->index<<3)+gr2->index)<<8); } static void gen_dop_word_imm(DualOps op,bool dword,DynReg * dr1,Bits imm) { - GenReg * gr1=FindDynReg(dr1); + GenReg * gr1=FindDynReg(dr1,dword && op==DOP_MOV); + Bit16u tmp; if (!dword) cache_addb(0x66); switch (op) { - case DOP_ADD:cache_addw(0xc081+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break; - case DOP_OR: cache_addw(0xc881+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break; - case DOP_ADC:cache_addw(0xd081+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break; - case DOP_SBB:cache_addw(0xd881+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break; - case DOP_AND:cache_addw(0xe081+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break; - case DOP_SUB:cache_addw(0xe881+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break; - case DOP_XOR:cache_addw(0xf081+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break; - case DOP_CMP:cache_addw(0xf881+(gr1->index<<8));break;//Doesn't change - case DOP_MOV:cache_addb(0xb8+(gr1->index));dr1->flags|=DYNFLG_CHANGED;break; - case DOP_TEST:cache_addw(0xc0f7+(gr1->index<<8));break;//Doesn't change + case DOP_ADD: tmp=0xc081; break; + case DOP_ADC: tmp=0xd081; break; + case DOP_SUB: tmp=0xe881; break; + case DOP_SBB: tmp=0xd881; break; + case DOP_CMP: tmp=0xf881; goto nochange; //Doesn't change + case DOP_XOR: tmp=0xf081; break; + case DOP_AND: tmp=0xe081; break; + case DOP_OR: tmp=0xc881; break; + case DOP_TEST: tmp=0xc0f7; goto nochange; //Doesn't change + case DOP_MOV: cache_addb(0xb8+(gr1->index)); dr1->flags|=DYNFLG_CHANGED; goto finish; default: IllegalOption(); } + dr1->flags|=DYNFLG_CHANGED; +nochange: + cache_addw(tmp+(gr1->index<<8)); +finish: if (dword) cache_addd(imm); else cache_addw(imm); } static void gen_imul_word(bool dword,DynReg * dr1,DynReg * dr2) { GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2); - if (!dword) cache_addb(0x66); - cache_addw(0xaf0f); - cache_addb(0xc0+(gr1->index<<3)+gr2->index); dr1->flags|=DYNFLG_CHANGED; + if (!dword) { + cache_addd(0xaf0f66|(0xc0+(gr1->index<<3)+gr2->index)<<24); + } else { + cache_addw(0xaf0f); + cache_addb(0xc0+(gr1->index<<3)+gr2->index); + } } static void gen_imul_word_imm(bool dword,DynReg * dr1,DynReg * dr2,Bits imm) { GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2); if (!dword) cache_addb(0x66); - if ((imm>=-128 && imm<=127)) { + if ((imm>=-128 && imm<=127)) { cache_addb(0x6b); cache_addb(0xc0+(gr1->index<<3)+gr2->index); cache_addb(imm); @@ -498,10 +523,13 @@ static void gen_shift_word_cl(Bitu op,bool dword,DynReg * dr1,DynReg * drecx) { static void gen_shift_word_imm(Bitu op,bool dword,DynReg * dr1,Bit8u imm) { GenReg * gr1=FindDynReg(dr1); - if (!dword) cache_addb(0x66); - cache_addw(0xc0c1+(((Bit16u)op) << 11) + ((gr1->index)<<8)); - cache_addb(imm); dr1->flags|=DYNFLG_CHANGED; + if (!dword) { + cache_addd(0x66|((0xc0c1+((Bit16u)op << 11) + (gr1->index<<8))|imm<<16)<<8); + } else { + cache_addw(0xc0c1+((Bit16u)op << 11) + (gr1->index<<8)); + cache_addb(imm); + } } static void gen_cbw(bool dword,DynReg * dyn_ax) { @@ -514,10 +542,10 @@ static void gen_cbw(bool dword,DynReg * dyn_ax) { static void gen_cwd(bool dword,DynReg * dyn_ax,DynReg * dyn_dx) { ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax); ForceDynReg(x86gen.regs[X86_REG_EDX],dyn_dx); - if (!dword) cache_addb(0x66); - cache_addb(0x99); dyn_ax->flags|=DYNFLG_CHANGED; dyn_dx->flags|=DYNFLG_CHANGED; + if (!dword) cache_addw(0x9966); + else cache_addb(0x99); } static void gen_mul_byte(bool imul,DynReg * dyn_ax,DynReg * dr1,Bit8u di1) { @@ -570,9 +598,9 @@ static void gen_call_function(void * func,char * ops,...) { ParamInfo * retparam=0; /* Clear the EAX Genreg for usage */ x86gen.regs[X86_REG_EAX]->Clear(); - x86gen.regs[X86_REG_EAX]->notusable=true;; + x86gen.regs[X86_REG_EAX]->notusable=true; /* Save the flags */ - gen_protectflags(); + if (GCC_UNLIKELY(!skip_flags)) gen_protectflags(); /* Scan for the amount of params */ if (ops) { va_list params; @@ -655,6 +683,7 @@ static void gen_call_function(void * func,char * ops,...) { if (retparam) { DynReg * dynreg=(DynReg *)retparam->value; GenReg * genreg=FindDynReg(dynreg); + if (genreg->index) // test for (e)ax/al switch (*retparam->line) { case 'd': cache_addw(0xc08b+(genreg->index <<(8+3))); //mov reg,eax @@ -676,10 +705,38 @@ static void gen_call_function(void * func,char * ops,...) { x86gen.regs[X86_REG_EAX]->notusable=false; } +static void gen_call_write(DynReg * dr,Bit32u val,Bitu write_size) { + /* Clear the EAX Genreg for usage */ + x86gen.regs[X86_REG_EAX]->Clear(); + x86gen.regs[X86_REG_EAX]->notusable=true; + gen_protectflags(); + + cache_addb(0x68); //PUSH val + cache_addd(val); + GenReg * genreg=FindDynReg(dr); + cache_addb(0x50+genreg->index); //PUSH reg + + /* Clear some unprotected registers */ + x86gen.regs[X86_REG_ECX]->Clear(); + x86gen.regs[X86_REG_EDX]->Clear(); + /* Do the actual call to the procedure */ + cache_addb(0xe8); + switch (write_size) { + case 1: cache_addd((Bit32u)mem_writeb - (Bit32u)cache.pos-4); break; + case 2: cache_addd((Bit32u)mem_writew_dyncorex86 - (Bit32u)cache.pos-4); break; + case 4: cache_addd((Bit32u)mem_writed_dyncorex86 - (Bit32u)cache.pos-4); break; + default: IllegalOption(); + } + + cache_addw(0xc483); //ADD ESP,8 + cache_addb(2*4); + x86gen.regs[X86_REG_EAX]->notusable=false; + gen_releasereg(dr); +} + static Bit8u * gen_create_branch(BranchTypes type) { /* First free all registers */ - cache_addb(0x70+type); - cache_addb(0); + cache_addw(0x70+type); return (cache.pos-1); } @@ -720,7 +777,7 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { } static void gen_save_flags(DynReg * dynreg) { - if (x86gen.flagsactive) IllegalOption(); + if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption(); GenReg * genreg=FindDynReg(dynreg); cache_addb(0x8b); //MOV REG,[esp] cache_addw(0x2404+(genreg->index << 3)); @@ -728,7 +785,7 @@ static void gen_save_flags(DynReg * dynreg) { } static void gen_load_flags(DynReg * dynreg) { - if (x86gen.flagsactive) IllegalOption(); + if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption(); cache_addw(0xc483); //ADD ESP,4 cache_addb(0x4); GenReg * genreg=FindDynReg(dynreg); @@ -764,13 +821,13 @@ static void gen_return(BlockReturn retcode) { } static void gen_init(void) { - x86gen.regs[X86_REG_EAX]=new GenReg(0,false); - x86gen.regs[X86_REG_ECX]=new GenReg(1,false); - x86gen.regs[X86_REG_EDX]=new GenReg(2,false); - x86gen.regs[X86_REG_EBX]=new GenReg(3,true); - x86gen.regs[X86_REG_EBP]=new GenReg(5,true); - x86gen.regs[X86_REG_ESI]=new GenReg(6,true); - x86gen.regs[X86_REG_EDI]=new GenReg(7,true); + x86gen.regs[X86_REG_EAX]=new GenReg(0); + x86gen.regs[X86_REG_ECX]=new GenReg(1); + x86gen.regs[X86_REG_EDX]=new GenReg(2); + x86gen.regs[X86_REG_EBX]=new GenReg(3); + x86gen.regs[X86_REG_EBP]=new GenReg(5); + x86gen.regs[X86_REG_ESI]=new GenReg(6); + x86gen.regs[X86_REG_EDI]=new GenReg(7); } From 702a19d47ff698e20834ae7f1077cc247b339f36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 4 Sep 2005 13:42:01 +0000 Subject: [PATCH 2217/4131] fix GCC-compiling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2301 --- src/cpu/core_dyn_x86/decoder.h | 2 +- src/cpu/core_dyn_x86/risc_x86.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 423d4022..dd71cfff 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -905,7 +905,7 @@ static void dyn_leave(void) { } static void dyn_segprefix(SegNames seg) { - if (GCC_UNLIKELY(decode.segprefix)) IllegalOption(); + if (GCC_UNLIKELY((Bitu)(decode.segprefix))) IllegalOption(); decode.segprefix=&DynRegs[G_ES+seg]; } diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 53e8df24..f656e547 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -49,7 +49,7 @@ public: bool notusable; void Load(DynReg * _dynreg,bool stale=false) { if (!_dynreg) return; - if (GCC_UNLIKELY(dynreg)) Clear(); + if (GCC_UNLIKELY((Bitu)dynreg)) Clear(); dynreg=_dynreg; last_used=x86gen.last_used; dynreg->flags&=~DYNFLG_CHANGED; @@ -61,13 +61,13 @@ public: dynreg->flags|=DYNFLG_ACTIVE; } void Save(void) { - if (GCC_UNLIKELY(!dynreg)) IllegalOption(); + if (GCC_UNLIKELY(!((Bitu)dynreg))) IllegalOption(); dynreg->flags&=~DYNFLG_CHANGED; cache_addw(0x0589+(index << (8+3))); //Mov [data],reg cache_addd((Bit32u)dynreg->data); } void Release(void) { - if (GCC_UNLIKELY(!dynreg)) return; + if (GCC_UNLIKELY(!((Bitu)dynreg))) return; if (dynreg->flags&DYNFLG_CHANGED && dynreg->flags&DYNFLG_SAVE) { Save(); } From ad7700fa3b089305608644586b94c77b9ad7a36c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 7 Sep 2005 19:15:09 +0000 Subject: [PATCH 2218/4131] Add patch:126539:"cd image, fix for files without extension" from prompt. Fix a typo that probably broke endian support for isos Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2302 --- configure.in | 2 +- src/dos/drive_iso.cpp | 12 +++++++++--- src/dos/drives.h | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/configure.in b/configure.in index 7cc83ea8..d4d95ced 100644 --- a/configure.in +++ b/configure.in @@ -71,7 +71,7 @@ return 0; AM_PATH_ALSA(0.9.0, AC_DEFINE(HAVE_ALSA,1,[Define to 1 to use ALSA for MIDI]) , : ) -#Check for big endian machine, should #define WORD_BIGENDIAN if so +#Check for big endian machine, should #define WORDS_BIGENDIAN if so AC_C_BIGENDIAN #Features to enable/disable diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 95ea51d9..f95421e4 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.9 2005-08-11 18:57:48 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.10 2005-09-07 19:15:09 qbix79 Exp $ */ #include #include @@ -58,7 +58,7 @@ isoFile::isoFile(isoDrive *drive, const char *name, FileStat_Block *stat, Bit32u fileEnd = fileBegin + size; cachedSector = -1; open = true; - info = info; + this->info = info; this->name = NULL; SetName(name); } @@ -435,6 +435,12 @@ bool isoDrive :: lookupSingle(isoDirEntry *de, const char *name, Bit32u start, B { Bit32u end = start + length / ISO_FRAMESIZE; if (length % ISO_FRAMESIZE != 0) end++; + + // copy filename and if it has no extension remove the trailing dot + char newname[38]; + safe_strncpy(newname, name, 38); + int name_len = strlen(newname); + if (name_len > 0 && newname[name_len - 1] == '.') newname[name_len - 1] = 0; for(Bit32u i = start; i < end; i++) { Bit8u sector[ISO_FRAMESIZE]; @@ -445,7 +451,7 @@ bool isoDrive :: lookupSingle(isoDirEntry *de, const char *name, Bit32u start, B int deLength = readDirEntry(de, §or[pos]); if (deLength < 1) return false; pos += deLength; - int tmp = strncasecmp((char*)de->ident, name, 38); + int tmp = strncasecmp((char*)de->ident, newname, 38); if (tmp == 0) return true; } } diff --git a/src/dos/drives.h b/src/dos/drives.h index 020f7f8c..644673da 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.28 2005-03-25 08:39:05 qbix79 Exp $ */ +/* $Id: drives.h,v 1.29 2005-09-07 19:15:09 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ @@ -264,7 +264,7 @@ struct isoDirEntry { #pragma pack () #endif -#if defined (WORD_BIGENDIAN) +#if defined (WORDS_BIGENDIAN) #define EXTENT_LOCATION(de) ((de).extentLocationM) #define DATA_LENGTH(de) ((de).dataLengthM) #else From dd97f1a4bdfd1abf0dca973edfd5805f2cbee620 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 8 Sep 2005 13:08:52 +0000 Subject: [PATCH 2219/4131] Clear less bios area as potentially overwrites dos stuff if the bios would become restartable Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2303 --- src/ints/bios.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 69c32647..443a153b 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.43 2005-07-30 14:41:31 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.44 2005-09-08 13:08:52 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -595,7 +595,8 @@ private: public: BIOS(Section* configuration):Module_base(configuration){ /* Clear the Bios Data Area */ - for (Bit16u i=0;i<1024;i++) real_writeb(0x40,i,0); + /* till where does this bios Area run ? Some dos stuff is at 0x70 */ + for (Bit16u i=0;i<0x200;i++) real_writeb(0x40,i,0); /* Setup all the interrupt handlers the bios controls */ /* INT 8 Clock IRQ Handler */ //TODO Maybe give this a special callback that will also call int 8 instead of starting @@ -707,7 +708,7 @@ public: // look http://www.bioscentral.com/misc/bda.htm //Bitu config=0x4400; //1 Floppy, 2 serial and 1 parrallel - Bitu config = 0; + Bitu config = 0x0; // set number of parallel ports // if(ppindex == 0) config |= 0x8000; // looks like 0 ports are not specified From d8d805b2ce0e1ad96a3e021af4fc39a64021c111 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 8 Sep 2005 13:09:47 +0000 Subject: [PATCH 2220/4131] fix tiny memleak with restarting sections when dealing with callbacks Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2304 --- src/cpu/callback.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 41a4fefb..8b0a0aa2 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.27 2005-07-30 09:49:29 qbix79 Exp $ */ +/* $Id: callback.cpp,v 1.28 2005-09-08 13:09:47 qbix79 Exp $ */ #include #include @@ -217,6 +217,7 @@ CALLBACK_HandlerObject::~CALLBACK_HandlerObject(){ } 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); } @@ -271,6 +272,7 @@ void CALLBACK_Init(Section* sec) { /* Setup all Interrupt to point to the default handler */ call_default=CALLBACK_Allocate(); CALLBACK_Setup(call_default,&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)); From b6fbe42e85d89984b93331afb8e1f4d99d3e2385 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 8 Sep 2005 13:11:35 +0000 Subject: [PATCH 2221/4131] Let dos allocate/hook a few bios interrupts. Makes some buggy game (Shadow President) happy. (thanks to wd to debug this) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2305 --- src/dos/dos_memory.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 1558f013..c0eff78c 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -19,6 +19,7 @@ #include "dosbox.h" #include "mem.h" #include "dos_inc.h" +#include "callback.h" #define UMB_START_SEG 0x9fff @@ -343,6 +344,12 @@ bool DOS_LinkUMBsToMemChain(Bit16u linkstate) { } +static Bitu DOS_default_handler(void) { + LOG(LOG_CPU,LOG_ERROR)("DOS rerouted Interrupt Called %X",lastint); + return CBRET_NONE; +}; + +static CALLBACK_HandlerObject callbackhandler; void DOS_SetupMemory(void) { // Create a dummy device MCB with PSPSeg=0x0008 DOS_MCB mcb_devicedummy((Bit16u)DOS_MEM_START); @@ -351,9 +358,23 @@ void DOS_SetupMemory(void) { mcb_devicedummy.SetType(0x4d); // More blocks will follow // mcb_devicedummy.SetFileName("SD "); + /* Let dos claim a few bios interrupts. Makes DOSBox more compatible with + * buggy games, which compare against the interrupt table. (probably a + * broken linked list implementation) */ // BioMenace (segment of int2<0x8000) mem_writeb((DOS_MEM_START+1)<<4,0xcf);// iret RealSetVec(0x02,(DOS_MEM_START+1)<<16); + callbackhandler.Allocate(&DOS_default_handler,"DOS default int"); + //Shadow president wants int 4 to point to this. + real_writeb(0x70,0,(Bit8u)0xFE); //GRP 4 + real_writeb(0x70,1,(Bit8u)0x38); //Extra Callback instruction + real_writew(0x70,2,callbackhandler.Get_callback()); //The immediate word + real_writeb(0x70,4,(Bit8u)0xCF); //An IRET Instruction + real_writed(0,0x04*4,0x700000); + //claim some more ints to this location + real_writed(0,0x01*4,0x700000); + real_writed(0,0x03*4,0x700000); +// real_writed(0,0x0f*4,0x700000); //Always a tricky one (soundblaster irq) DOS_MCB mcb((Bit16u)DOS_MEM_START+2); mcb.SetPSPSeg(MCB_FREE); //Free From 8799eb0ffe079f2714c086fe68646b44fd981035 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 10 Sep 2005 14:15:37 +0000 Subject: [PATCH 2222/4131] Added a somewhat modified version of patch 1240751 from cyberwalker to make SET aware of envirionment variables on the command line Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2306 --- src/shell/shell_cmds.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 920a0b21..4a8fcce8 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.56 2005-08-10 19:53:09 c2woody Exp $ */ +/* $Id: shell_cmds.cpp,v 1.57 2005-09-10 14:15:37 qbix79 Exp $ */ #include #include @@ -531,13 +531,34 @@ void DOS_Shell::CMD_SET(char * args) { WriteOut("%s\n",line.c_str()); } else { *p++=0; - if (!SetEnv(args,p)) { + /* parse p for envirionment variables */ + char parsed[CMD_MAXLINE]; + char* p_parsed = parsed; + while(*p) { + if(*p != '%') *p_parsed++ = *p++; //Just add it (most likely path) + else if( *(p+1) == '%') { + *p_parsed++ = '%'; p += 2; //%% => % + } else { + char * second = strchr(++p,'%'); + if(!second) continue; *second++ = 0; + std::string temp; + if (GetEnvStr(p,temp)) { + std::string::size_type equals = temp.find('='); + if (equals == std::string::npos) continue; + strcpy(p_parsed,temp.substr(equals+1).c_str()); + p_parsed += strlen(p_parsed); + } + p = second; + } + } + *p_parsed = 0; + /* Try setting the variable */ + if (!SetEnv(args,parsed)) { WriteOut(MSG_Get("SHELL_CMD_SET_OUT_OF_SPACE")); } } } - void DOS_Shell::CMD_IF(char * args) { StripSpaces(args); bool has_not=false; From 4eebc6c7f6e391f3325cc978050053ec3e5795b3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 11 Sep 2005 13:04:21 +0000 Subject: [PATCH 2223/4131] add patch 1240134 from cyberwalker. (initialize some registers). Report a periodic interrupt occured when the timer is active and one occurs(status reg 0xC). Fixes contraption Zack and friends Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2307 --- src/hardware/cmos.cpp | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index c7ade821..3ee978ef 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -46,7 +46,10 @@ static struct { static void cmos_timerevent(Bitu val) { PIC_ActivateIRQ(8); - if (cmos.timer.enabled) PIC_AddEvent(cmos_timerevent,cmos.timer.delay); + if (cmos.timer.enabled) { + PIC_AddEvent(cmos_timerevent,cmos.timer.delay); + cmos.regs[0xc] = 0xC0;//Contraption Zack (music) + } } static void cmos_checktimer(void) { @@ -94,6 +97,9 @@ static void cmos_writereg(Bitu port,Bitu val,Bitu iolen) { if (val&0x10) LOG(LOG_BIOS,LOG_ERROR)("CMOS:Updated ended interrupt not supported yet"); cmos_checktimer(); break; + case 0x0d:/* Status reg D */ + cmos.regs[cmos.reg]=val & 0x80; /*Bit 7=1:RTC Pown on*/ + break; case 0x0f: /* Shutdown status byte */ cmos.regs[cmos.reg]=val & 0x7f; break; @@ -115,7 +121,6 @@ static Bitu cmos_readreg(Bitu port,Bitu iolen) { Bit8u hdparm; time_t curtime; struct tm *loctime; - /* Get the current time. */ curtime = time (NULL); @@ -143,7 +148,7 @@ static Bitu cmos_readreg(Bitu port,Bitu iolen) { case 0x03: /* Minutes Alarm */ case 0x05: /* Hours Alarm */ return cmos.regs[cmos.reg]; - case 0x0a: /* Status register C */ + case 0x0a: /* Status register A */ if (PIC_TickIndex()<0.002) { return (cmos.regs[0x0a]&0x7f) | 0x80; } else { @@ -249,21 +254,24 @@ static Bitu cmos_readreg(Bitu port,Bitu iolen) { case 0x0b: /* Status register B */ + case 0x0d: /* Status register D */ case 0x0f: /* Shutdown status byte */ + case 0x14: /* Equipment */ + case 0x15: /* Base Memory KB Low Byte */ + case 0x16: /* Base Memory KB High Byte */ case 0x17: /* Extended memory in KB Low Byte */ case 0x18: /* Extended memory in KB High Byte */ case 0x30: /* Extended memory in KB Low Byte */ case 0x31: /* Extended memory in KB High Byte */ -// LOG(LOG_BIOS,LOG_NORMAL)("CMOS:Read from reg %F : %04X",cmos.reg,cmos.regs[cmos.reg]); +// LOG(LOG_BIOS,LOG_NORMAL)("CMOS:Read from reg %X : %04X",cmos.reg,cmos.regs[cmos.reg]); return cmos.regs[cmos.reg]; default: - LOG(LOG_BIOS,LOG_NORMAL)("CMOS:Read from reg %F",cmos.reg); + LOG(LOG_BIOS,LOG_NORMAL)("CMOS:Read from reg %X",cmos.reg); return cmos.regs[cmos.reg]; } } -void CMOS_SetRegister(Bitu regNr, Bit8u val) -{ +void CMOS_SetRegister(Bitu regNr, Bit8u val) { cmos.regs[regNr] = val; }; @@ -282,6 +290,12 @@ public: cmos_writereg(0x71,0x26,1); cmos.reg=0xb; cmos_writereg(0x71,0x2,1); //Struct tm *loctime is of 24 hour format, + cmos.reg=0xd; + cmos_writereg(0x71,0x80,1); /* RTC power on */ + // Equipment is updated from bios.cpp and bios_disk.cpp + /* Fill in base memory size, it is 640K always */ + cmos.regs[0x15]=(Bit8u)0x80; + cmos.regs[0x16]=(Bit8u)0x02; /* Fill in extended memory size */ Bitu exsize=(MEM_TotalPages()*4)-1024; cmos.regs[0x17]=(Bit8u)exsize; From c317e3adc68e73c10daf98f093e08b74fe3aa8c1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 11 Sep 2005 13:06:00 +0000 Subject: [PATCH 2224/4131] update equipment word in RTC on changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2308 --- src/ints/bios.cpp | 5 ++++- src/ints/bios_disk.cpp | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 443a153b..c8de907c 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.44 2005-09-08 13:08:52 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.45 2005-09-11 13:06:00 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -36,6 +36,7 @@ * counter using the BIOS_ZeroExtendedSize call */ static Bit16u size_extended; static Bits other_memsystems=0; +void CMOS_SetRegister(Bitu regNr, Bit8u val); //For setting equipment word static Bitu INT70_Handler(void) { /* Acknowledge irq with cmos */ @@ -737,6 +738,7 @@ public: // PS2 mouse config |= 0x04; mem_writew(BIOS_CONFIGURATION,config); + CMOS_SetRegister(0x14,config); //Should be updated on changes /* Setup extended memory size */ IO_Write(0x70,0x30); size_extended=IO_Read(0x71); @@ -772,6 +774,7 @@ void BIOS_SetComPorts(Bit16u baseaddr[]) { equipmentword &= (~0x0E00); equipmentword |= (portcount << 9); mem_writew(BIOS_CONFIGURATION,equipmentword); + CMOS_SetRegister(0x14,equipmentword); //Should be updated on changes } diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 0fd03402..1a244c65 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.21 2005-09-01 17:34:39 qbix79 Exp $ */ +/* $Id: bios_disk.cpp,v 1.22 2005-09-11 13:06:00 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" @@ -52,6 +52,8 @@ RealPt imgDTAPtr; DOS_DTA *imgDTA; bool killRead; +void CMOS_SetRegister(Bitu regNr, Bit8u val); //For setting equipment word + /* 2 floppys and 2 harddrives, max */ imageDisk *imageDiskList[MAX_DISK_IMAGES]; imageDisk *diskSwap[MAX_SWAPPABLE_DISKS]; @@ -207,6 +209,7 @@ imageDisk::imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHard equipment|=(numofdisks<<5); } else equipment|=1; mem_writew(BIOS_CONFIGURATION,equipment); + CMOS_SetRegister(0x14, equipment); } } } From 3f0ac17ceb3411a78e67aaed18ae99beaf37fc67 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 11 Sep 2005 13:09:45 +0000 Subject: [PATCH 2225/4131] Add some weird char to the allowed table. Fixes installer Contraction Zack Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2309 --- src/dos/dos_files.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 0e15b656..ad3e7515 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.68 2005-09-02 19:56:18 c2woody Exp $ */ +/* $Id: dos_files.cpp,v 1.69 2005-09-11 13:09:45 qbix79 Exp $ */ #include #include @@ -89,7 +89,7 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { case '\\': case '$': case '#': case '@': case '(': case ')': case '!': case '%': case '{': case '}': case '`': case '~': case '_': case '-': case '.': case '*': case '?': case '&': - case '\'': case '+': case '^': + case '\'': case '+': case '^': case 246: upname[w++]=c; break; default: From 933642091dda56130e8e77a70b422e3a55976c11 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 11 Sep 2005 13:32:33 +0000 Subject: [PATCH 2226/4131] merged Shadow President and Bio Menace into one hack Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2310 --- src/dos/dos_memory.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index c0eff78c..ae0a8cf1 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -362,18 +362,16 @@ void DOS_SetupMemory(void) { * buggy games, which compare against the interrupt table. (probably a * broken linked list implementation) */ // BioMenace (segment of int2<0x8000) - mem_writeb((DOS_MEM_START+1)<<4,0xcf);// iret - RealSetVec(0x02,(DOS_MEM_START+1)<<16); callbackhandler.Allocate(&DOS_default_handler,"DOS default int"); //Shadow president wants int 4 to point to this. real_writeb(0x70,0,(Bit8u)0xFE); //GRP 4 real_writeb(0x70,1,(Bit8u)0x38); //Extra Callback instruction real_writew(0x70,2,callbackhandler.Get_callback()); //The immediate word real_writeb(0x70,4,(Bit8u)0xCF); //An IRET Instruction - real_writed(0,0x04*4,0x700000); - //claim some more ints to this location real_writed(0,0x01*4,0x700000); + real_writed(0,0x02*4,0x700000); //BioMenace real_writed(0,0x03*4,0x700000); + real_writed(0,0x04*4,0x700000); //Shadow President // real_writed(0,0x0f*4,0x700000); //Always a tricky one (soundblaster irq) DOS_MCB mcb((Bit16u)DOS_MEM_START+2); From a39d2912669d59da2c74fbd58bbe2559b2c31e8f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 11 Sep 2005 20:56:48 +0000 Subject: [PATCH 2227/4131] don't position mouse if the location remains the same. Fixes some sticky mouse behaviour Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2311 --- src/ints/mouse.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index c98d8a75..ef4c1739 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.51 2005-08-10 15:35:54 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.52 2005-09-11 20:56:48 qbix79 Exp $ */ #include #include @@ -619,14 +619,16 @@ static Bitu INT33_Handler(void) { reg_dx=POS_Y; break; case 0x04: /* Position Mouse */ - if(reg_cx > mouse.max_x) mouse.x = static_cast(mouse.max_x); - else if (mouse.min_x > reg_cx) mouse.x = static_cast(mouse.min_x); - else mouse.x = static_cast(reg_cx); - - if(reg_dx > mouse.max_y) mouse.y = static_cast(mouse.max_y); - else if (mouse.min_y > reg_dx) mouse.y = static_cast(mouse.min_y); - else mouse.y = static_cast(reg_dx); + /* If position isn't different from current position + * don't change it then. (as position is rounded so numbers get + * lost when the rounded number is set) (arena/simulation Wolf) */ + if(reg_cx >= mouse.max_x) mouse.x = static_cast(mouse.max_x); + else if (mouse.min_x >= reg_cx) mouse.x = static_cast(mouse.min_x); + else if (reg_cx != POS_X) mouse.x = static_cast(reg_cx); + if(reg_dx >= mouse.max_y) mouse.y = static_cast(mouse.max_y); + else if (mouse.min_y >= reg_dx) mouse.y = static_cast(mouse.min_y); + else if (reg_dx != POS_Y) mouse.y = static_cast(reg_dx); DrawCursor(); break; case 0x05: /* Return Button Press Data */ From 7b1990cdcf52fcf3710803085e35665a89723560 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 13 Sep 2005 18:44:45 +0000 Subject: [PATCH 2228/4131] Check current mouselocation when the ranges change. Update if needed. Fixes Battle Chess (EGA). (thanks kippesoep) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2312 --- src/ints/mouse.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index ef4c1739..ec1f1195 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.52 2005-09-11 20:56:48 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.53 2005-09-13 18:44:45 qbix79 Exp $ */ #include #include @@ -590,7 +590,7 @@ static void mouse_reset(void) { static Bitu INT33_Handler(void) { -// LOG(LOG_MOUSE,LOG_NORMAL)("MOUSE: %04X",reg_ax); +// LOG(LOG_MOUSE,LOG_NORMAL)("MOUSE: %04X %d %d",reg_ax,POS_X,POS_Y); switch (reg_ax) { case 0x00: /* Reset Driver and Read Status */ mouse_reset_hardware(); /* fallthrough */ @@ -664,6 +664,11 @@ static Bitu INT33_Handler(void) { else { min=(Bit16s)reg_dx;max=(Bit16s)reg_cx;} mouse.min_x=min; mouse.max_x=max; + /* Battlechess wants this */ + if(mouse.x > mouse.max_x) mouse.x = mouse.max_x; + if(mouse.x < mouse.min_x) mouse.x = mouse.min_x; + /* Or alternatively this: + mouse.x = (mouse.max_x - mouse.min_x + 1)/2;*/ LOG(LOG_MOUSE,LOG_NORMAL)("Define Hortizontal range min:%d max:%d",min,max); } break; @@ -676,6 +681,11 @@ static Bitu INT33_Handler(void) { else { min=(Bit16s)reg_dx;max=(Bit16s)reg_cx;} mouse.min_y=min; mouse.max_y=max; + /* Battlechess wants this */ + if(mouse.y > mouse.max_y) mouse.y = mouse.max_y; + if(mouse.y < mouse.min_y) mouse.y = mouse.min_y; + /* Or alternatively this: + mouse.y = (mouse.max_y - mouse.min_y + 1)/2;*/ LOG(LOG_MOUSE,LOG_NORMAL)("Define Vertical range min:%d max:%d",min,max); } break; From 9be07ec88b9f9ceaa16f38c79e45df00e9aff650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 17 Sep 2005 13:15:36 +0000 Subject: [PATCH 2229/4131] add setmode corrections from ih8regs (patch 1198821); change vga mode detection (Prehistorik 2) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2313 --- src/hardware/vga.cpp | 7 +- src/hardware/vga_draw.cpp | 2 +- src/ints/int10_modes.cpp | 133 +++++++++++++++++++++++++++----------- 3 files changed, 101 insertions(+), 41 deletions(-) diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index cbdd8911..67fa0ba1 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -52,12 +52,17 @@ void VGA_DetermineMode(void) { } /* Test for graphics or alphanumeric mode */ } else if (vga.attr.mode_control & 1) { + if (vga.gfx.mode & 0x40) VGA_SetMode(M_VGA); + else if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4); + else if ((vga.gfx.miscellaneous & 0x0c)==0x0c) VGA_SetMode(M_CGA2); + else VGA_SetMode(M_EGA16); + /* old mode detection: if (!(vga.crtc.mode_control & 0x1)) { if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4); else VGA_SetMode(M_CGA2); } else if (vga.attr.mode_control & 0x40) { VGA_SetMode(M_VGA); - } else VGA_SetMode(M_EGA16); + } else VGA_SetMode(M_EGA16); */ } else { VGA_SetMode(M_TEXT); } diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 5a8e2563..253446b5 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -441,7 +441,7 @@ void VGA_SetupDrawing(Bitu val) { case M_CGA2: doubleheight=true; vga.draw.blocks=2*width; - width<<=4; + width<<=3; VGA_DrawLine=VGA_Draw_1BPP_Line; break; case M_TEXT: diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 7b8d79ec..e01809e7 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -34,24 +34,25 @@ VideoModeBlock ModeList_VGA[]={ /* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */ -{ 0x000 ,M_TEXT ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, -{ 0x001 ,M_TEXT ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, -{ 0x002 ,M_TEXT ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, -{ 0x003 ,M_TEXT ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, -{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, -{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, -{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, -{ 0x007 ,M_TEXT ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x000 ,M_TEXT ,360 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, +{ 0x001 ,M_TEXT ,360 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, +{ 0x002 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x003 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,2 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,2 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,2 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x007 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, { 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, { 0x00E ,M_EGA16 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE }, -{ 0x00F ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,400 ,0 },/*was EGA_2*/ -{ 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,1 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, +{ 0x00F ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 },/*was EGA_2*/ +{ 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, { 0x011 ,M_EGA16 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 },/*was EGA_2 */ { 0x012 ,M_EGA16 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, { 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,0 }, -{ 0x054 ,M_TEXT ,1056 ,688, 132,43, 8, 8, 1 ,0xB8000 ,0x4000, 192, 800, 132, 688, 0 }, -{ 0x055 ,M_TEXT ,1056 ,400, 132,25, 8, 16, 1 ,0xB8000 ,0x2000, 192, 449, 132, 400, 0 }, + +{ 0x054 ,M_TEXT ,1056,688, 132,43, 8, 8, 1 ,0xB8000 ,0x4000, 192, 800, 132,688, 0 }, +{ 0x055 ,M_TEXT ,1056,400, 132,25, 8, 16, 1 ,0xB8000 ,0x2000, 192, 449, 132,400, 0 }, { 0x100 ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, { 0x101 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, { 0x103 ,M_LIN8 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, @@ -351,6 +352,7 @@ bool INT10_SetVideoMode(Bitu mode) { LOG(LOG_INT10,LOG_NORMAL)("Set Video Mode %X",mode); if (machine!=MCH_VGA) return INT10_SetVideoMode_OTHER(mode,clearmem); Bit8u modeset_ctl,video_ctl,vga_switches; + if (!SetCurMode(ModeList_VGA,mode)){ LOG(LOG_INT10,LOG_ERROR)("Trying to set illegal mode %X",mode); return false; @@ -364,18 +366,31 @@ bool INT10_SetVideoMode(Bitu mode) { /* Setup the VGA to the correct mode */ Bit16u crtc_base; - bool mono_mode=(mode == 7); + bool mono_mode=(mode == 7) || (mode==0xf); if (mono_mode) crtc_base=0x3b4; else crtc_base=0x3d4; + /* Setup MISC Output Register */ Bit8u misc_output=0x2 | (mono_mode ? 0x0 : 0x1); + + switch (CurMode->vdispend) { + case 400: misc_output|=0x60; + if (CurMode->type==M_TEXT) // && (CurMode->pstart==0xB8000)) + misc_output|=0x4; + break; + case 480: misc_output|=0xe0; + break; + case 350: misc_output|=0xa0; + break; + default: misc_output|=0x60; + } IO_Write(0x3c2,misc_output); //Setup for 3b4 or 3d4 + /* Program Sequencer */ Bit8u seq_data[SEQ_REGS]; memset(seq_data,0,SEQ_REGS); - seq_data[1]|=1; //8 dot fonts by default - seq_data[1]|= //Check for half clock - (CurMode->special & _EGA_HALF_CLOCK) ? 0x08 : 0x00; + if (CurMode->twidth==8) seq_data[1]|=1; //8 dot fonts by default + if (CurMode->special & _EGA_HALF_CLOCK) seq_data[1]|=0x08; //Check for half clock seq_data[4]|=0x02; //More than 64kb switch (CurMode->type) { case M_TEXT: @@ -415,41 +430,59 @@ bool INT10_SetVideoMode(Bitu mode) { IO_Write(crtc_base,0x02);IO_Write(crtc_base+1,CurMode->hdispend); hor_overflow|=((CurMode->hdispend) & 0x100) >> 6; /* End horizontal Blanking */ - Bitu blank_end; - if (CurMode->special & _EGA_HALF_CLOCK) { - blank_end = (CurMode->htotal-1) & 0x7f; - } else { - blank_end = (CurMode->htotal-2) & 0x7f; - } + Bitu blank_end=(CurMode->htotal-2) & 0x7f; IO_Write(crtc_base,0x03);IO_Write(crtc_base+1,0x80|(blank_end & 0x1f)); + /* Start Horizontal Retrace */ Bitu ret_start; - if (CurMode->special & _EGA_HALF_CLOCK) ret_start = (CurMode->hdispend+2); + if ((CurMode->special & _EGA_HALF_CLOCK) && (CurMode->type!=M_CGA2)) ret_start = (CurMode->hdispend+3); + else if (CurMode->type==M_TEXT) ret_start = (CurMode->hdispend+5); else ret_start = (CurMode->hdispend+4); IO_Write(crtc_base,0x04);IO_Write(crtc_base+1,ret_start); hor_overflow|=(ret_start & 0x100) >> 4; + /* End Horizontal Retrace */ Bitu ret_end; - if (CurMode->special & _EGA_HALF_CLOCK) ret_end = (CurMode->htotal-2) & 0x3f; - else ret_end = (CurMode->htotal-4) & 0x3f; - IO_Write(crtc_base,0x05);IO_Write(crtc_base+1,(ret_end & 0x1f) | (blank_end & 0x20) << 2); + if (CurMode->special & _EGA_HALF_CLOCK) { + if (CurMode->type==M_CGA2) ret_end=0; // mode 6 + else if (CurMode->special & _EGA_LINE_DOUBLE) ret_end = (CurMode->htotal-18) & 0x1f; + else ret_end = ((CurMode->htotal-18) & 0x1f) | 0x20; // mode 0&1 have 1 char sync delay + } else if (CurMode->type==M_TEXT) ret_end = (CurMode->htotal-3) & 0x1f; + else ret_end = (CurMode->htotal-4) & 0x1f; + + IO_Write(crtc_base,0x05);IO_Write(crtc_base+1,ret_end | (blank_end & 0x20) << 2); + /* Vertical Total */ IO_Write(crtc_base,0x06);IO_Write(crtc_base+1,(CurMode->vtotal-2)); overflow|=((CurMode->vtotal-2) & 0x100) >> 8; overflow|=((CurMode->vtotal-2) & 0x200) >> 4; ver_overflow|=((CurMode->vtotal-2) & 0x400) >> 10; + /* These aren't exactly accurate i think, Should be more like a certain percentage based on vertical total So you get same sized borders, but okay :) */ + + Bitu vretrace; + switch (CurMode->vdispend) { + case 400: vretrace=CurMode->vdispend+12; + break; + case 480: vretrace=CurMode->vdispend+10; + break; + case 350: vretrace=CurMode->vdispend+37; + break; + default: vretrace=CurMode->vdispend+12; + } + /* Vertical Retrace Start */ - IO_Write(crtc_base,0x10);IO_Write(crtc_base+1,(CurMode->vdispend+12)); - overflow|=((CurMode->vdispend+12) & 0x100) >> 6; - overflow|=((CurMode->vdispend+12) & 0x200) >> 2; - ver_overflow|=((CurMode->vdispend+12) & 0x400) >> 6; + IO_Write(crtc_base,0x10);IO_Write(crtc_base+1,vretrace); + overflow|=(vretrace & 0x100) >> 6; + overflow|=(vretrace & 0x200) >> 2; + ver_overflow|=(vretrace & 0x400) >> 6; + /* Vertical Retrace End */ - IO_Write(crtc_base,0x11);IO_Write(crtc_base+1,(CurMode->vdispend+14) & 0xF); + IO_Write(crtc_base,0x11);IO_Write(crtc_base+1,(vretrace+2) & 0xF); /* Vertical Display End */ IO_Write(crtc_base,0x12);IO_Write(crtc_base+1,(CurMode->vdispend-1)); @@ -457,13 +490,26 @@ bool INT10_SetVideoMode(Bitu mode) { overflow|=((CurMode->vdispend-1) & 0x200) >> 3; ver_overflow|=((CurMode->vdispend-1) & 0x400) >> 9; + Bitu vblank_trim; + switch (CurMode->vdispend) { + case 400: vblank_trim=6; + break; + case 480: vblank_trim=7; + break; + case 350: vblank_trim=5; + break; + default: vblank_trim=8; + } + /* Vertical Blank Start */ - IO_Write(crtc_base,0x15);IO_Write(crtc_base+1,(CurMode->vdispend+8)); - overflow|=((CurMode->vdispend+8) & 0x100) >> 5; - max_scanline|=((CurMode->vdispend+8) & 0x200) >> 4; - ver_overflow|=((CurMode->vdispend+8) & 0x400) >> 8; - /* Vertical Retrace End */ - IO_Write(crtc_base,0x16);IO_Write(crtc_base+1,(CurMode->vtotal-8)); + IO_Write(crtc_base,0x15);IO_Write(crtc_base+1,(CurMode->vdispend+vblank_trim)); + overflow|=((CurMode->vdispend+vblank_trim) & 0x100) >> 5; + max_scanline|=((CurMode->vdispend+vblank_trim) & 0x200) >> 4; + ver_overflow|=((CurMode->vdispend+vblank_trim) & 0x400) >> 8; + + /* Vertical Blank End */ + IO_Write(crtc_base,0x16);IO_Write(crtc_base+1,(CurMode->vtotal-vblank_trim-2)); + /* Line Compare */ Bitu line_compare=(CurMode->vtotal < 1024) ? 1023 : 2047; IO_Write(crtc_base,0x18);IO_Write(crtc_base+1,line_compare&0xff); @@ -476,7 +522,7 @@ bool INT10_SetVideoMode(Bitu mode) { switch (CurMode->type) { case M_TEXT: max_scanline|=CurMode->cheight-1; - underline=0x1f; + underline=mono_mode ? 0x0f : 0x1f; // mode 7 uses a diff underline position break; case M_VGA: underline=0x40; @@ -490,6 +536,8 @@ bool INT10_SetVideoMode(Bitu mode) { max_scanline|=1; break; } + if (CurMode->vdispend==350) underline=0x0f; + IO_Write(crtc_base,0x09);IO_Write(crtc_base+1,max_scanline); IO_Write(crtc_base,0x14);IO_Write(crtc_base+1,underline); @@ -510,12 +558,18 @@ bool INT10_SetVideoMode(Bitu mode) { } /* Mode Control */ Bit8u mode_control=0; + switch (CurMode->type) { - case M_CGA4: case M_CGA2: + mode_control=0xc2; // 0x06 sets address wrap. + break; + case M_CGA4: mode_control=0xa2; break; case M_EGA16: + if (CurMode->mode==0x11) // 0x11 also sets address wrap. thought maybe all 2 color modes did but 0x0f doesn't. + mode_control=0xc3; // so.. 0x11 or 0x0f a one off? + else mode_control=0xe3; break; case M_TEXT: @@ -526,6 +580,7 @@ bool INT10_SetVideoMode(Bitu mode) { mode_control=0xab; break; } + IO_Write(crtc_base,0x17);IO_Write(crtc_base+1,mode_control); /* Renable write protection */ IO_Write(crtc_base,0x11); From b5336f32d1ecf8c37140cb355b1403e7696d3774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 18 Sep 2005 19:50:03 +0000 Subject: [PATCH 2230/4131] add F11/F12, fix pause functionality Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2314 --- include/keyboard.h | 3 ++- src/debug/debug.cpp | 4 +++- src/gui/sdlmain.cpp | 4 +++- src/hardware/keyboard.cpp | 5 +++-- src/ints/bios_keyboard.cpp | 17 +++++++++++------ 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/include/keyboard.h b/include/keyboard.h index 9fb7fa29..9c6ea4f8 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -34,7 +34,7 @@ enum KBD_KEYS { KBD_capslock,KBD_scrolllock,KBD_numlock, KBD_grave,KBD_minus,KBD_equals,KBD_backslash,KBD_leftbracket,KBD_rightbracket, - KBD_semicolon,KBD_quote,KBD_period,KBD_comma,KBD_slash, + KBD_semicolon,KBD_quote,KBD_period,KBD_comma,KBD_slash,KBD_extra_lt_gt, KBD_printscreen,KBD_pause, KBD_insert,KBD_home,KBD_pageup,KBD_delete,KBD_end,KBD_pagedown, @@ -47,6 +47,7 @@ enum KBD_KEYS { KBD_LAST }; +void KEYBOARD_ClrBuffer(void); void KEYBOARD_AddKey(KBD_KEYS keytype,bool pressed); #endif diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 1c6cb424..eb52a3cc 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.68 2005-08-31 13:00:14 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.69 2005-09-18 19:50:03 c2woody Exp $ */ #include #include @@ -41,6 +41,7 @@ #include "programs.h" #include "debug_inc.h" #include "../cpu/lazyflags.h" +#include "keyboard.h" #ifdef WIN32 void WIN32_Console(); @@ -1651,6 +1652,7 @@ void DEBUG_Enable(void) { showhelp=true; DEBUG_ShowMsg("***| PRESS \"H\" TO SHOW ALL COMMANDS. PRESS \"RETURN\" TO ENTER COMMANDMODE. |***\n"); } + KEYBOARD_ClrBuffer(); } void DEBUG_DrawScreen(void) { diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index ab5990ba..71bf8811 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.87 2005-07-28 19:53:42 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.88 2005-09-18 19:50:03 c2woody Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -41,6 +41,7 @@ #include "debug.h" #include "mapper.h" #include "vga.h" +#include "keyboard.h" //#define DISABLE_JOYSTICK @@ -214,6 +215,7 @@ void GFX_SetTitle(Bits cycles,Bits frameskip,bool paused){ static void PauseDOSBox(void) { GFX_SetTitle(-1,-1,true); bool paused = true; + KEYBOARD_ClrBuffer(); SDL_Delay(500); SDL_Event event; while (SDL_PollEvent(&event)) { diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 6a34f567..b48b8472 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.32 2005-08-24 16:06:18 c2woody Exp $ */ +/* $Id: keyboard.cpp,v 1.33 2005-09-18 19:50:03 c2woody Exp $ */ #include "dosbox.h" #include "keyboard.h" @@ -72,7 +72,7 @@ static void KEYBOARD_TransferBuffer(Bitu val) { } -static void KEYBOARD_ClrBuffer(void) { +void KEYBOARD_ClrBuffer(void) { keyb.used=0; keyb.pos=0; PIC_RemoveEvents(KEYBOARD_TransferBuffer); @@ -309,6 +309,7 @@ void KEYBOARD_AddKey(KBD_KEYS keytype,bool pressed) { case KBD_kp0:ret=82;break; case KBD_kpperiod:ret=83;break; + case KBD_extra_lt_gt:ret=86;break; case KBD_f11:ret=87;break; case KBD_f12:ret=88;break; diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 5b2ecb55..5bba52ee 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -29,7 +29,7 @@ static Bitu call_int16,call_irq1; /* Nice table from BOCHS i should feel bad for ripping this */ #define none 0 -#define MAX_SCAN_CODE 0x53 +#define MAX_SCAN_CODE 0x58 static struct { Bit16u normal; Bit16u shift; @@ -112,14 +112,19 @@ static struct { { 0x4900, 0x4939, 0x8400, 0x0009 }, /* 9 PgUp */ { 0x4a2d, 0x4a2d, none, none }, /* - */ { 0x4b00, 0x4b34, 0x7300, 0x0004 }, /* 4 Left */ - { 0x4c00, 0x4c35, none, 0x0005 }, /* 5 */ + { 0x4cf0, 0x4c35, none, 0x0005 }, /* 5 */ { 0x4d00, 0x4d36, 0x7400, 0x0006 }, /* 6 Right */ { 0x4e2b, 0x4e2b, none, none }, /* + */ { 0x4f00, 0x4f31, 0x7500, 0x0001 }, /* 1 End */ { 0x5000, 0x5032, none, 0x0002 }, /* 2 Down */ { 0x5100, 0x5133, 0x7600, 0x0003 }, /* 3 PgDn */ { 0x5200, 0x5230, none, 0x0000 }, /* 0 Ins */ - { 0x5300, 0x532e, none, none } /* Del */ + { 0x5300, 0x532e, none, none }, /* Del */ + { none, none, none, none }, + { none, none, none, none }, + { 0x565c, 0x567c, none, none }, /* (102-key) */ + { 0x8500, 0x8700, 0x8900, 0x8b00 }, /* F11 */ + { 0x8600, 0x8800, 0x8a00, 0x8c00 } /* F12 */ }; static void add_key(Bit16u code) { @@ -285,10 +290,10 @@ static Bitu IRQ1_Handler(void) { case 0xba:flags1 &=~0x40;leds &=~0x04;break; case 0x45: if (flags3 &0x01) { - flags3 &=0x01; + flags3 &=~0x01; + mem_writeb(BIOS_KEYBOARD_FLAGS3,flags3); if ((flags2&8)==0) { mem_writeb(BIOS_KEYBOARD_FLAGS2,flags2|8); - mem_writeb(BIOS_KEYBOARD_FLAGS3,flags3); IO_Write(0x20,0x20); while (mem_readb(BIOS_KEYBOARD_FLAGS2)&8) CALLBACK_Idle(); // pause loop reg_ip+=4; // skip out 20,20 @@ -302,7 +307,7 @@ static Bitu IRQ1_Handler(void) { break; /* Num Lock */ case 0xc5: if (flags3 &0x01) { - flags3 &=0x01; + flags3 &=~0x01; } else { flags1 &=~0x20; leds &=~0x02; From 3932cb886be716fb9a0928f58799ce7de9dfbeb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 19 Sep 2005 08:25:38 +0000 Subject: [PATCH 2231/4131] set registers on executable startup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2315 --- src/dos/dos_execute.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 5379f9e9..1dc618f0 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.48 2005-07-22 10:03:20 c2woody Exp $ */ +/* $Id: dos_execute.cpp,v 1.49 2005-09-19 08:25:38 c2woody Exp $ */ #include #include @@ -395,8 +395,10 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { should not modify the flags (e.g. IOPL in v86 mode) */ mem_writew(SegPhys(ss)+reg_sp+4,reg_flags&(~FLAG_CF)); /* Setup the rest of the registers */ - reg_ax=0;reg_si=0x100; - reg_cx=reg_dx=reg_bx=reg_di=0; + reg_ax=reg_bx=0;reg_cx=0xff; + reg_dx=pspseg; + reg_si=RealOff(csip); + reg_di=RealOff(sssp); reg_bp=0x91c; /* DOS internal stack begin relict */ SegSet16(ds,pspseg);SegSet16(es,pspseg); #if C_DEBUG From 20c46346d6f70af294f0db20daf1d9b39697626e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 20 Sep 2005 11:22:33 +0000 Subject: [PATCH 2232/4131] fix cga colors when machine=vga Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2316 --- src/ints/int10_modes.cpp | 52 +++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index e01809e7..673025b8 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -38,9 +38,9 @@ VideoModeBlock ModeList_VGA[]={ { 0x001 ,M_TEXT ,360 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, { 0x002 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, { 0x003 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, -{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,2 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, -{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,2 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, -{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,2 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, { 0x007 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, { 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, @@ -49,7 +49,7 @@ VideoModeBlock ModeList_VGA[]={ { 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, { 0x011 ,M_EGA16 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 },/*was EGA_2 */ { 0x012 ,M_EGA16 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, -{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x2000 ,100 ,449 ,80 ,400 ,0 }, { 0x054 ,M_TEXT ,1056,688, 132,43, 8, 8, 1 ,0xB8000 ,0x4000, 192, 800, 132,688, 0 }, { 0x055 ,M_TEXT ,1056,400, 132,25, 8, 16, 1 ,0xB8000 ,0x2000, 192, 449, 132,400, 0 }, @@ -107,11 +107,24 @@ static Bit8u ega_palette[64][3]= {0x15,0x15,0x15}, {0x15,0x15,0x3f}, {0x15,0x3f,0x15}, {0x15,0x3f,0x3f}, {0x3f,0x15,0x15}, {0x3f,0x15,0x3f}, {0x3f,0x3f,0x15}, {0x3f,0x3f,0x3f} }; -static Bit8u cga_palette[16][3]= { +static Bit8u cga_palette[16][3]= +{ {0x00,0x00,0x00}, {0x00,0x00,0x2a}, {0x00,0x2a,0x00}, {0x00,0x2a,0x2a}, {0x2a,0x00,0x00}, {0x2a,0x00,0x2a}, {0x2a,0x15,0x00}, {0x2a,0x2a,0x2a}, {0x15,0x15,0x15}, {0x15,0x15,0x3f}, {0x15,0x3f,0x15}, {0x15,0x3f,0x3f}, {0x3f,0x15,0x15}, {0x3f,0x15,0x3f}, {0x3f,0x3f,0x15}, {0x3f,0x3f,0x3f}, }; +static Bit8u cga_palette_2[64][3]= +{ + {0x00,0x00,0x00}, {0x00,0x00,0x2a}, {0x00,0x2a,0x00}, {0x00,0x2a,0x2a}, {0x2a,0x00,0x00}, {0x2a,0x00,0x2a}, {0x2a,0x15,0x00}, {0x2a,0x2a,0x2a}, + {0x00,0x00,0x00}, {0x00,0x00,0x2a}, {0x00,0x2a,0x00}, {0x00,0x2a,0x2a}, {0x2a,0x00,0x00}, {0x2a,0x00,0x2a}, {0x2a,0x15,0x00}, {0x2a,0x2a,0x2a}, + {0x15,0x15,0x15}, {0x15,0x15,0x3f}, {0x15,0x3f,0x15}, {0x15,0x3f,0x3f}, {0x3f,0x15,0x15}, {0x3f,0x15,0x3f}, {0x3f,0x3f,0x15}, {0x3f,0x3f,0x3f}, + {0x15,0x15,0x15}, {0x15,0x15,0x3f}, {0x15,0x3f,0x15}, {0x15,0x3f,0x3f}, {0x3f,0x15,0x15}, {0x3f,0x15,0x3f}, {0x3f,0x3f,0x15}, {0x3f,0x3f,0x3f}, + {0x00,0x00,0x00}, {0x00,0x00,0x2a}, {0x00,0x2a,0x00}, {0x00,0x2a,0x2a}, {0x2a,0x00,0x00}, {0x2a,0x00,0x2a}, {0x2a,0x15,0x00}, {0x2a,0x2a,0x2a}, + {0x00,0x00,0x00}, {0x00,0x00,0x2a}, {0x00,0x2a,0x00}, {0x00,0x2a,0x2a}, {0x2a,0x00,0x00}, {0x2a,0x00,0x2a}, {0x2a,0x15,0x00}, {0x2a,0x2a,0x2a}, + {0x15,0x15,0x15}, {0x15,0x15,0x3f}, {0x15,0x3f,0x15}, {0x15,0x3f,0x3f}, {0x3f,0x15,0x15}, {0x3f,0x15,0x3f}, {0x3f,0x3f,0x15}, {0x3f,0x3f,0x3f}, + {0x15,0x15,0x15}, {0x15,0x15,0x3f}, {0x15,0x3f,0x15}, {0x15,0x3f,0x3f}, {0x3f,0x15,0x15}, {0x3f,0x15,0x3f}, {0x3f,0x3f,0x15}, {0x3f,0x3f,0x3f}, +}; + static Bit8u vga_palette[256][3]= { {0x00,0x00,0x00},{0x00,0x00,0x2a},{0x00,0x2a,0x00},{0x00,0x2a,0x2a},{0x2a,0x00,0x00},{0x2a,0x00,0x2a},{0x2a,0x15,0x00},{0x2a,0x2a,0x2a}, @@ -389,7 +402,7 @@ bool INT10_SetVideoMode(Bitu mode) { /* Program Sequencer */ Bit8u seq_data[SEQ_REGS]; memset(seq_data,0,SEQ_REGS); - if (CurMode->twidth==8) seq_data[1]|=1; //8 dot fonts by default + if (CurMode->cwidth==8) seq_data[1]|=1; //8 dot fonts by default if (CurMode->special & _EGA_HALF_CLOCK) seq_data[1]|=0x08; //Check for half clock seq_data[4]|=0x02; //More than 64kb switch (CurMode->type) { @@ -664,16 +677,21 @@ att_text16: case M_CGA2: att_data[0x10]=0x01; //Color Graphics att_data[0]=0x0; - att_data[1]=0xf; + for (i=1;i<0x10;i++) att_data[i]=0x17; att_data[0x12]=0x1; //Only enable 1 plane real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x3f); break; case M_CGA4: att_data[0x10]=0x01; //Color Graphics att_data[0]=0x0; - att_data[1]=0x3; - att_data[2]=0x5; - att_data[3]=0x7; + att_data[1]=0x13; + att_data[2]=0x15; + att_data[3]=0x17; + att_data[4]=0x2; + att_data[5]=0x4; + att_data[6]=0x6; + att_data[7]=0x7; + for (i=8;i<16;i++) att_data[i]=i+8; real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x30); break; case M_VGA: @@ -701,10 +719,10 @@ att_text16: case M_CGA2: case M_CGA4: case M_TANDY16: - for (i=0;i<16;i++) { - IO_Write(0x3c9,cga_palette[i][0]); - IO_Write(0x3c9,cga_palette[i][1]); - IO_Write(0x3c9,cga_palette[i][2]); + for (i=0;i<64;i++) { + IO_Write(0x3c9,cga_palette_2[i][0]); + IO_Write(0x3c9,cga_palette_2[i][1]); + IO_Write(0x3c9,cga_palette_2[i][2]); } break; case M_TEXT: @@ -729,11 +747,13 @@ dac_text16: switch (CurMode->type) { case M_CGA2: feature=(feature&~0x30)|0x20; - real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x12); + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x1e); break; case M_CGA4: feature=(feature&~0x30)|0x20; - real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x2); + if (CurMode->mode==4) real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x2a); + else if (CurMode->mode==5) real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x2e); + else real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x2); break; case M_TANDY16: feature=(feature&~0x30)|0x20; From 37d91eea182ded2fa70b7ecd8fb35a6e3664c50e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 21 Sep 2005 11:37:35 +0000 Subject: [PATCH 2233/4131] update ps2 mouse; fix mousecursor in mode13 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2317 --- include/mouse.h | 4 ++-- src/ints/bios.cpp | 36 +++++++++++++++++++++++------------- src/ints/mouse.cpp | 36 +++++++++++++++++++++++------------- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/include/mouse.h b/include/mouse.h index 99c7ffd5..891e3a55 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.h,v 1.9 2005-03-24 10:32:09 qbix79 Exp $ */ +/* $Id: mouse.h,v 1.10 2005-09-21 11:37:35 c2woody Exp $ */ #ifndef DOSBOX_MOUSE_H #define DOSBOX_MOUSE_H @@ -24,7 +24,7 @@ void Mouse_ShowCursor(void); void Mouse_HideCursor(void); -void Mouse_SetPS2State(bool use); +bool Mouse_SetPS2State(bool use); void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs); void Mouse_CursorMoved(float x,float y); diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index c8de907c..1abdfef9 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.45 2005-09-11 13:06:00 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.46 2005-09-21 11:37:35 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -520,20 +520,27 @@ static Bitu INT15_Handler(void) { reg_ah=0; CALLBACK_SCF(false); } else if (reg_bh==0x01) { //enable - Mouse_SetPS2State(true); + if (!Mouse_SetPS2State(true)) { + reg_ah=5; + CALLBACK_SCF(true); + break; + } reg_ah=0; CALLBACK_SCF(false); - } else CALLBACK_SCF(true); + } else { + CALLBACK_SCF(true); + reg_ah=1; + } break; case 0x01: // reset - Mouse_SetPS2State(false); reg_bx=0x00aa; // mouse - CALLBACK_SCF(false); - break; - case 0x02: // set sampling rate + // fall through + case 0x05: // initialize + Mouse_SetPS2State(false); CALLBACK_SCF(false); reg_ah=0; break; + case 0x02: // set sampling rate case 0x03: // set resolution CALLBACK_SCF(false); reg_ah=0; @@ -543,20 +550,23 @@ static Bitu INT15_Handler(void) { CALLBACK_SCF(false); reg_ah=0; break; - case 0x05: // initialize - CALLBACK_SCF(false); - reg_ah=0; - break; case 0x06: // extended commands - if ((reg_bh==0x01) || (reg_bh==0x02)) { CALLBACK_SCF(false); reg_ah=0;} - else CALLBACK_SCF(true); + if ((reg_bh==0x01) || (reg_bh==0x02)) { + CALLBACK_SCF(false); + reg_ah=0; + } else { + CALLBACK_SCF(true); + reg_ah=1; + } break; case 0x07: // set callback Mouse_ChangePS2Callback(SegValue(es),reg_bx); CALLBACK_SCF(false); + reg_ah=0; break; default: CALLBACK_SCF(true); + reg_ah=1; break; } break; diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index ec1f1195..8fa4c3d3 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.53 2005-09-13 18:44:45 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.54 2005-09-21 11:37:35 c2woody Exp $ */ #include #include @@ -36,7 +36,7 @@ static Bitu call_int33,call_int74; static Bit16u ps2cbseg,ps2cbofs; -static bool useps2callback; +static bool useps2callback,ps2callbackinit; static Bit16u call_ps2; static RealPt ps2_callback; static Bit16s oldmouseX, oldmouseY; @@ -121,19 +121,28 @@ static struct { Bit16s oldshown; } mouse; -void Mouse_SetPS2State(bool use) { - if ((SegValue(es)!=0) && (reg_bx!=0)) useps2callback = use; - else useps2callback = false; +bool Mouse_SetPS2State(bool use) { + if (use && (!ps2callbackinit)) { + useps2callback = false; + PIC_SetIRQMask(MOUSE_IRQ,true); + return false; + } + useps2callback = use; Mouse_AutoLock(useps2callback); PIC_SetIRQMask(MOUSE_IRQ,!useps2callback); + return true; } void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs) { - if ((pseg==0) && (pofs==0)) useps2callback = false; - else useps2callback = true; - ps2cbseg = pseg; - ps2cbofs = pofs; - Mouse_AutoLock(useps2callback); + if ((pseg==0) && (pofs==0)) { + ps2callbackinit = false; + Mouse_AutoLock(false); + } else { + ps2callbackinit = true; + ps2cbseg = pseg; + ps2cbofs = pofs; + } + Mouse_AutoLock(ps2callbackinit); } void DoPS2Callback(Bit16u data, Bit16s mouseX, Bit16s mouseY) { @@ -247,8 +256,8 @@ void SaveVgaRegisters() gfxReg[i] = IO_Read(0x3CF); } /* Setup some default values in GFX regs that should work */ - IO_Write (0x3CE,3);IO_Write(0x3Cf,0); //disable rotate and operation - IO_Write (0x3CE,5);IO_Write(0x3Cf,0); //Force read/write mode 0 + IO_Write(0x3CE,3); IO_Write(0x3Cf,0); //disable rotate and operation + IO_Write(0x3CE,5); IO_Write(0x3Cf,gfxReg[5]&0xf0); //Force read/write mode 0 } void RestoreVgaRegisters() @@ -398,6 +407,7 @@ void Mouse_CursorMoved(float x,float y) { if((fabs(x) > 1.0) || (mouse.senv_x < 1.0)) dx *= mouse.senv_x; if((fabs(y) > 1.0) || (mouse.senv_y < 1.0)) dy *= mouse.senv_y; + if (useps2callback) dy *= 2; mouse.mickey_x += dx; mouse.mickey_y += dy; @@ -916,7 +926,7 @@ void MOUSE_Init(Section* sec) { } else { real_writed(0,((0x8+MOUSE_IRQ)<<2),CALLBACK_RealPointer(call_int74)); } - useps2callback = false; + useps2callback = false; ps2callbackinit = false; call_ps2=CALLBACK_Allocate(); CALLBACK_Setup(call_ps2,&PS2_Handler,CB_IRET,"ps2 bios callback"); ps2_callback=CALLBACK_RealPointer(call_ps2); From 3feb3975e1a91de26bbc6048e616158e6e9ac6e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 23 Sep 2005 11:42:29 +0000 Subject: [PATCH 2234/4131] add fatDrive::GetFileAttr, update FileCreate to handle existing files on a diskimage Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2318 --- src/dos/drive_fat.cpp | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 8a4e734a..fcd99427 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.8 2005-02-10 10:20:51 qbix79 Exp $ */ +/* $Id: drive_fat.cpp,v 1.9 2005-09-23 11:42:29 c2woody Exp $ */ #include #include @@ -723,21 +723,25 @@ bool fatDrive::FileCreate(DOS_File **file, char *name, Bit16u attributes) { char pathName[11]; /* Check if file already exists */ - if(getFileDirEntry(name, &fileEntry, &dirClust, &subEntry)) return false; + if(getFileDirEntry(name, &fileEntry, &dirClust, &subEntry)) { + /* Truncate file */ + fileEntry.entrysize=0; + directoryChange(dirClust, &fileEntry, subEntry); + } else { + /* Can we even get the name of the file itself? */ + if(!getEntryName(name, &dirName[0])) return false; + convToDirFile(&dirName[0], &pathName[0]); - /* Can we even get the name of the file itself? */ - if(!getEntryName(name, &dirName[0])) return false; - convToDirFile(&dirName[0], &pathName[0]); + /* Can we find the base directory? */ + if(!getDirClustNum(name, &dirClust, true)) return false; + memset(&fileEntry, 0, sizeof(direntry)); + memcpy(&fileEntry.entryname, &pathName[0], 11); + fileEntry.attrib = attributes; + addDirectoryEntry(dirClust, fileEntry); - /* Can we find the base directory? */ - if(!getDirClustNum(name, &dirClust, true)) return false; - memset(&fileEntry, 0, sizeof(direntry)); - memcpy(&fileEntry.entryname, &pathName[0], 11); - fileEntry.attrib = attributes; - addDirectoryEntry(dirClust, fileEntry); - - /* Check if file exists now */ - if(!getFileDirEntry(name, &fileEntry, &dirClust, &subEntry)) return false; + /* Check if file exists now */ + if(!getFileDirEntry(name, &fileEntry, &dirClust, &subEntry)) return false; + } /* Empty file created, now lets open it */ /* TODO: check for read-only flag and requested write access */ @@ -881,8 +885,11 @@ bool fatDrive::FindNext(DOS_DTA &dta) { } bool fatDrive::GetFileAttr(char *name, Bit16u *attr) { - /* TODO: Stub */ - return false; + direntry fileEntry; + Bit32u dirClust, subEntry; + if(!getFileDirEntry(name, &fileEntry, &dirClust, &subEntry)) return false; + *attr=fileEntry.attrib; + return true; } bool fatDrive::directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum) { From 9d8f00c6c3e8a10dfef3f7734a86bb60c243f34d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 24 Sep 2005 19:18:42 +0000 Subject: [PATCH 2235/4131] add missing errorcodes to fatDrive; extend GetFileAttr to retrieve attributes from directories Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2319 --- src/dos/drive_fat.cpp | 74 +++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index fcd99427..227e0110 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.9 2005-09-23 11:42:29 c2woody Exp $ */ +/* $Id: drive_fat.cpp,v 1.10 2005-09-24 19:18:42 c2woody Exp $ */ #include #include @@ -85,9 +85,6 @@ static void convToDirFile(char *filename, char *filearray) { charidx = 8; } } - - - } fatFile::fatFile(const char* name, Bit32u startCluster, Bit32u fileLen, fatDrive *useDrive) { @@ -198,7 +195,6 @@ finalizeWrite: *size =sizecount; return true; - } bool fatFile::Seek(Bit32u *pos, Bit32u type) { @@ -251,12 +247,8 @@ Bit32u fatDrive::getClusterValue(Bit32u clustNum) { Bit32u fatoffset; Bit32u fatsectnum; Bit32u fatentoff; - Bit32u clustValue; - - - switch(fattype) { case FAT12: fatoffset = clustNum + (clustNum / 2); @@ -304,7 +296,6 @@ void fatDrive::setClusterValue(Bit32u clustNum, Bit32u clustValue) { Bit32u fatentoff; Bit32u tmpValue; - switch(fattype) { case FAT12: fatoffset = clustNum + (clustNum / 2); @@ -413,9 +404,6 @@ bool fatDrive::getFileDirEntry(char * filename, direntry * useEntry, Bit32u * di memcpy(useEntry, &foundEntry, sizeof(direntry)); *dirClust = (Bit32u)currentClust; *subEntry = ((Bit32u)imgDTA->GetDirID()-1); - - - return true; } @@ -452,7 +440,6 @@ bool fatDrive::getDirClustNum(char *dir, Bit32u *clustNum, bool parDir) { return true; } return false; - } Bit32u fatDrive::getSectorSize(void) { @@ -554,10 +541,6 @@ Bit32u fatDrive::appendCluster(Bit32u startCluster) { zeroOutCluster(newClust); return newClust; - - - - } bool fatDrive::allocateCluster(Bit32u useCluster, Bit32u prevCluster) { @@ -586,7 +569,6 @@ bool fatDrive::allocateCluster(Bit32u useCluster, Bit32u prevCluster) { break; } return true; - } fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, Bit32u headscyl, Bit32u cylinders, Bit32u startSector) { @@ -682,7 +664,6 @@ fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, memset(fatSectBuffer,0,1024); curFatSect = 0xffffffff; - } bool fatDrive::AllocationInfo(Bit16u *_bytes_sector, Bit8u *_sectors_cluster, Bit16u *_total_clusters, Bit16u *_free_clusters) { @@ -708,7 +689,6 @@ Bit32u fatDrive::getFirstFreeClust(void) { /* No free cluster found */ return 0; - } bool fatDrive::isRemote(void) { return false; } @@ -794,9 +774,20 @@ bool fatDrive::FindFirst(char *_dir, DOS_DTA &dta,bool fcb_findfirst) { direntry dummyClust; Bit8u attr;char pattern[DOS_NAMELENGTH_ASCII]; dta.GetSearchParams(attr,pattern); + if(attr==DOS_ATTR_VOLUME) { + if (strcmp(GetLabel(), "") == 0 ) { + DOS_SetError(DOSERR_NO_MORE_FILES); + return false; + } + dta.SetResult(GetLabel(),0,0,0,DOS_ATTR_VOLUME); + return true; + } if(attr & DOS_ATTR_VOLUME) //check for root dir or fcb_findfirst LOG(LOG_DOSMISC,LOG_WARN)("findfirst for volumelabel used on fatDrive. Unhandled!!!!!"); - if(!getDirClustNum(_dir, &cwdDirCluster, false)) return false; + if(!getDirClustNum(_dir, &cwdDirCluster, false)) { + DOS_SetError(DOSERR_PATH_NOT_FOUND); + return false; + } dta.SetDirID(0); return FindNextInternal(cwdDirCluster, dta, &dummyClust); } @@ -845,7 +836,10 @@ nextfile: } else { tmpsector = getAbsoluteSectFromChain(dirClustNumber, logentsector); /* A zero sector number can't happen */ - if(tmpsector == 0) return false; + if(tmpsector == 0) { + DOS_SetError(DOSERR_NO_MORE_FILES); + return false; + } loadedDisk->Read_AbsoluteSector(tmpsector,sectbuf); } dirPos++; @@ -855,7 +849,10 @@ nextfile: if (sectbuf[entryoffset].entryname[0] == 0xe5) goto nextfile; /* End of directory list */ - if (sectbuf[entryoffset].entryname[0] == 0x00) return false; + if (sectbuf[entryoffset].entryname[0] == 0x00) { + DOS_SetError(DOSERR_NO_MORE_FILES); + return false; + } memset(find_name,0,DOS_NAMELENGTH_ASCII); memset(extension,0,4); @@ -875,7 +872,6 @@ nextfile: memcpy(foundEntry, §buf[entryoffset], sizeof(direntry)); return true; - } bool fatDrive::FindNext(DOS_DTA &dta) { @@ -887,8 +883,28 @@ bool fatDrive::FindNext(DOS_DTA &dta) { bool fatDrive::GetFileAttr(char *name, Bit16u *attr) { direntry fileEntry; Bit32u dirClust, subEntry; - if(!getFileDirEntry(name, &fileEntry, &dirClust, &subEntry)) return false; - *attr=fileEntry.attrib; + if(!getFileDirEntry(name, &fileEntry, &dirClust, &subEntry)) { + char dirName[DOS_NAMELENGTH_ASCII]; + char pathName[11]; + + /* Can we even get the name of the directory itself? */ + if(!getEntryName(name, &dirName[0])) return false; + convToDirFile(&dirName[0], &pathName[0]); + + /* Get parent directory starting cluster */ + if(!getDirClustNum(name, &dirClust, true)) return false; + + /* Find directory entry in parent directory */ + Bit32s fileidx = 2; + while(directoryBrowse(dirClust, &fileEntry, fileidx)) { + if(memcmp(&fileEntry.entryname, &pathName[0], 11) == 0) { + *attr=fileEntry.attrib; + return true; + } + fileidx++; + } + return false; + } else *attr=fileEntry.attrib; return true; } @@ -1015,7 +1031,6 @@ bool fatDrive::addDirectoryEntry(Bit32u dirClustNumber, direntry useEntry) { } } - return false; } @@ -1028,7 +1043,6 @@ void fatDrive::zeroOutCluster(Bit32u clustNumber) { for(i=0;iWrite_AbsoluteSector(getAbsoluteSectFromChain(clustNumber,i), &secBuffer[0]); } - } bool fatDrive::MakeDir(char *dir) { @@ -1081,7 +1095,6 @@ bool fatDrive::MakeDir(char *dir) { addDirectoryEntry(dummyClust, tmpentry); return true; - } bool fatDrive::RemoveDir(char *dir) { @@ -1137,7 +1150,6 @@ bool fatDrive::RemoveDir(char *dir) { } bool fatDrive::Rename(char *oldname, char*newname) { - return false; } From 417fb048ba059318030693a77ae35027f368556d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 27 Sep 2005 11:05:44 +0000 Subject: [PATCH 2236/4131] better vga compatibility (rom strings, initial mode field) for 221b Baker Street/Coloring Book 2; fixes for monochrome modes, clearmem flag; corrections from ih8regs Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2320 --- src/ints/int10.cpp | 2 +- src/ints/int10_memory.cpp | 13 ++++--- src/ints/int10_misc.cpp | 8 ++-- src/ints/int10_modes.cpp | 79 +++++++++++++++++++++++++++++++-------- src/ints/int10_pal.cpp | 28 ++++++++------ src/ints/int10_vesa.cpp | 4 +- 6 files changed, 95 insertions(+), 39 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 40f1d5c1..1cd0d074 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -125,7 +125,7 @@ static Bitu INT10_Handler(void) { break; case 0x0F: /* Get videomode */ reg_bh=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); - reg_al=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); + reg_al=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)|(real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL)&0x80); reg_ah=(Bit8u)real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); break; case 0x10: /* EGA/VGA Palette functions */ diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 6d391bdf..52f51a3d 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -72,17 +72,20 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu } } - - - void INT10_SetupRomMemory(void) { /* This should fill up certain structures inside the Video Bios Rom Area */ PhysPt rom_base=PhysMake(0xc000,0); Bitu i; - int10.rom.used=3; // int10.rom.used=2; Size of ROM added + int10.rom.used=3; if (machine==MCH_VGA) { + // set up the start of the ROM phys_writew(rom_base+0,0xaa55); - phys_writeb(rom_base+2,0x40); // Size of ROM: 64 512-blocks = 32KB + phys_writeb(rom_base+2,0x40); // Size of ROM: 64 512-blocks = 32KB + phys_writeb(rom_base+0x1e,0x49); // IBM string + phys_writeb(rom_base+0x1f,0x42); + phys_writeb(rom_base+0x20,0x4d); + phys_writeb(rom_base+0x21,0x00); + int10.rom.used=0x100; } int10.rom.font_8_first=RealMake(0xC000,int10.rom.used); for (i=0;i<128*8;i++) { diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 299d150f..92d7fea5 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -92,13 +92,13 @@ void INT10_GetFuncStateInformation(PhysPt save) { Bit16u col_count=0; switch (CurMode->type) { case M_TEXT: - col_count=16;break; + if (CurMode->mode==0x7) col_count=1; else col_count=16;break; case M_CGA2: col_count=2;break; case M_CGA4: col_count=4;break; case M_EGA16: - col_count=16;break; + if (CurMode->mode==0x11 || CurMode->mode==0x0f) col_count=2; else col_count=16;break; case M_VGA: col_count=256;break; default: @@ -119,7 +119,9 @@ void INT10_GetFuncStateInformation(PhysPt save) { case 480: mem_writeb(save+0x2a,3);break; }; - //TODO Maybe misc flags + /* misc flags */ + if (CurMode->type==M_TEXT) mem_writeb(save+0x2d,0x21); + else mem_writeb(save+0x2d,0x01); /* Video Memory available */ mem_writeb(save+0x31,3); } diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 673025b8..24d433be 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -38,9 +38,9 @@ VideoModeBlock ModeList_VGA[]={ { 0x001 ,M_TEXT ,360 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, { 0x002 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, { 0x003 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, -{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, -{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, -{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, { 0x007 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, { 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, @@ -95,6 +95,18 @@ static Bit8u text_palette[64][3]= {0x15,0x15,0x15},{0x15,0x15,0x3f},{0x15,0x3f,0x15},{0x15,0x3f,0x3f},{0x3f,0x15,0x15},{0x3f,0x15,0x3f},{0x3f,0x3f,0x15},{0x3f,0x3f,0x3f} }; +static Bit8u mtext_palette[64][3]= +{ + 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, + 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, + 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, + 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, + 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, + 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, + 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, + 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f +}; + static Bit8u ega_palette[64][3]= { {0x00,0x00,0x00}, {0x00,0x00,0x2a}, {0x00,0x2a,0x00}, {0x00,0x2a,0x2a}, {0x2a,0x00,0x00}, {0x2a,0x00,0x2a}, {0x2a,0x15,0x00}, {0x2a,0x2a,0x2a}, @@ -210,10 +222,10 @@ static void FinishSetMode(bool clearmem) { else real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,CurMode->mode-0x98); //Looks like the s3 bios real_writew(BIOSMEM_SEG,BIOSMEM_NB_COLS,CurMode->twidth); real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,CurMode->plength); - real_writew(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,CurMode->mode==7 ? 0x3b4 : 0x3d4); + real_writew(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,((CurMode->mode==7 )|| (CurMode->mode==0x0f)) ? 0x3b4 : 0x3d4); real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,CurMode->theight-1); real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,CurMode->cheight); - real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem << 7))); + real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem?0:0x80))); real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0x09); real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); @@ -358,9 +370,13 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { bool INT10_SetVideoMode(Bitu mode) { bool clearmem=true;Bitu i; - if ((mode<256) && (mode & 128)) { + if (mode>=0x100) { + if (mode & 0x8000) clearmem=false; + mode&=0xfff; + } + if ((mode<0x100) && (mode & 0x80)) { clearmem=false; - mode-=128; + mode-=0x80; } LOG(LOG_INT10,LOG_NORMAL)("Set Video Mode %X",mode); if (machine!=MCH_VGA) return INT10_SetVideoMode_OTHER(mode,clearmem); @@ -615,7 +631,7 @@ bool INT10_SetVideoMode(Bitu mode) { misc_control_2=0x0; break; } - IO_WriteB(0x3d4,0x67);IO_WriteB(0x3d5,misc_control_2); + IO_WriteB(crtc_base,0x67);IO_WriteB(crtc_base+1,misc_control_2); /* Write Misc Output */ IO_Write(0x3c2,misc_output); /* Program Graphics controller */ @@ -654,10 +670,26 @@ bool INT10_SetVideoMode(Bitu mode) { switch (CurMode->type) { case M_EGA16: att_data[0x10]=0x01; //Color Graphics - if (CurMode->mode>0xe) goto att_text16; + switch (CurMode->mode) { + case 0x0f: + att_data[0x10]|=0x0a; //Monochrome + att_data[0x01]=0x08; + att_data[0x04]=0x18; + att_data[0x05]=0x18; + att_data[0x09]=0x08; + att_data[0x0d]=0x18; + break; + case 0x11: + for (i=1;i<16;i++) att_data[i]=0x3f; + break; + case 0x10: + case 0x12: goto att_text16; + default: for (i=0;i<8;i++) { - att_data[i]=i; - att_data[i+8]=i+0x10; + att_data[i]=i; + att_data[i+8]=i+0x10; + } + break; } break; case M_TANDY16: @@ -667,6 +699,7 @@ bool INT10_SetVideoMode(Bitu mode) { case M_TEXT: att_data[0x13]=0x08; //Pel panning on 8, although we don't have 9 dot text mode att_data[0x10]=0x0C; //Color Text with blinking + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x30); att_text16: for (i=0;i<8;i++) { att_data[i]=i; @@ -709,7 +742,8 @@ att_text16: IO_Write(0x3c8,0); switch (CurMode->type) { case M_EGA16: - if (CurMode->mode>0xe) goto dac_text16; + if (CurMode->mode>0xf) goto dac_text16; + else if (CurMode->mode==0xf) goto dac_mtext16; for (i=0;i<64;i++) { IO_Write(0x3c9,ega_palette[i][0]); IO_Write(0x3c9,ega_palette[i][1]); @@ -726,6 +760,15 @@ att_text16: } break; case M_TEXT: + if (CurMode->mode==7) { +dac_mtext16: + for (i=0;i<64;i++) { + IO_Write(0x3c9,mtext_palette[i][0]); + IO_Write(0x3c9,mtext_palette[i][1]); + IO_Write(0x3c9,mtext_palette[i][2]); + } + break; + } dac_text16: for (i=0;i<64;i++) { IO_Write(0x3c9,text_palette[i][0]); @@ -760,6 +803,12 @@ dac_text16: break; case M_TEXT: feature=(feature&~0x30)|0x20; + switch (CurMode->mode) { + case 0:real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x2c);break; + case 1:real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x28);break; + case 2:real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x2d);break; + case 3:real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x29);break; + } break; case M_EGA16: case M_VGA: @@ -767,7 +816,8 @@ dac_text16: break; } - real_writeb(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE,feature); + // disabled, has to be set in bios.cpp exclusively +// real_writeb(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE,feature); /* Setup the CPU Window */ IO_Write(crtc_base,0x6a); IO_Write(crtc_base+1,0); @@ -790,6 +840,3 @@ dac_text16: } return true; } - - - diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 631095e7..480d3d76 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -23,6 +23,10 @@ #define ACTL_MAX_REG 0x14 +static INLINE void ResetACTL(void) { + IO_Read(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS) + 6); +} + void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val) { switch (machine) { case MCH_TANDY: @@ -32,7 +36,7 @@ void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val) { break; case MCH_VGA: if(reg<=ACTL_MAX_REG) { - IO_Read(VGAREG_ACTL_RESET); + ResetACTL(); IO_Write(VGAREG_ACTL_ADDRESS,reg); IO_Write(VGAREG_ACTL_WRITE_DATA,val); } @@ -43,7 +47,7 @@ void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val) { void INT10_SetOverscanBorderColor(Bit8u val) { - IO_Read(VGAREG_ACTL_RESET); + ResetACTL(); IO_Write(VGAREG_ACTL_ADDRESS,0x11); IO_Write(VGAREG_ACTL_WRITE_DATA,val); IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette @@ -64,7 +68,7 @@ void INT10_SetAllPaletteRegisters(PhysPt data) { IO_Write(VGAREG_TDY_DATA,mem_readb(data)); break; case MCH_VGA: - IO_Read(VGAREG_ACTL_RESET); + ResetACTL(); // First the colors for(Bit8u i=0;i<0x10;i++) { IO_Write(VGAREG_ACTL_ADDRESS,i); @@ -82,14 +86,14 @@ void INT10_SetAllPaletteRegisters(PhysPt data) { void INT10_ToggleBlinkingBit(Bit8u state) { Bit8u value; state&=0x01; - IO_Read(VGAREG_ACTL_RESET); + ResetACTL(); IO_Write(VGAREG_ACTL_ADDRESS,0x10); value=IO_Read(VGAREG_ACTL_READ_DATA); value&=0xf7; value|=state<<3; - IO_Read(VGAREG_ACTL_RESET); + ResetACTL(); IO_Write(VGAREG_ACTL_ADDRESS,0x10); IO_Write(VGAREG_ACTL_WRITE_DATA,value); IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette @@ -97,7 +101,7 @@ void INT10_ToggleBlinkingBit(Bit8u state) { void INT10_GetSinglePaletteRegister(Bit8u reg,Bit8u * val) { if(reg<=ACTL_MAX_REG) { - IO_Read(VGAREG_ACTL_RESET); + ResetACTL(); IO_Write(VGAREG_ACTL_ADDRESS,reg+32); *val=IO_Read(VGAREG_ACTL_READ_DATA); IO_Write(VGAREG_ACTL_WRITE_DATA,*val); @@ -105,25 +109,25 @@ void INT10_GetSinglePaletteRegister(Bit8u reg,Bit8u * val) { } void INT10_GetOverscanBorderColor(Bit8u * val) { - IO_Read(VGAREG_ACTL_RESET); + ResetACTL(); IO_Write(VGAREG_ACTL_ADDRESS,0x11+32); *val=IO_Read(VGAREG_ACTL_READ_DATA); IO_Write(VGAREG_ACTL_WRITE_DATA,*val); } void INT10_GetAllPaletteRegisters(PhysPt data) { - IO_Read(VGAREG_ACTL_RESET); + ResetACTL(); // First the colors for(Bit8u i=0;i<0x10;i++) { IO_Write(VGAREG_ACTL_ADDRESS,i); mem_writeb(data,IO_Read(VGAREG_ACTL_READ_DATA)); - IO_Read(VGAREG_ACTL_RESET); + ResetACTL(); data++; } // Then the border IO_Write(VGAREG_ACTL_ADDRESS,0x11+32); mem_writeb(data,IO_Read(VGAREG_ACTL_READ_DATA)); - IO_Read(VGAREG_ACTL_RESET); + ResetACTL(); } void INT10_SetSingleDacRegister(Bit8u index,Bit8u red,Bit8u green,Bit8u blue) { @@ -159,7 +163,7 @@ void INT10_GetDACBlock(Bit16u index,Bit16u count,PhysPt data) { } void INT10_SelectDACPage(Bit8u function,Bit8u mode) { - IO_Read(VGAREG_ACTL_RESET); + ResetACTL(); IO_Write(VGAREG_ACTL_ADDRESS,0x10); Bit8u old10=IO_Read(VGAREG_ACTL_READ_DATA); if (!function) { //Select paging mode @@ -178,7 +182,7 @@ void INT10_SelectDACPage(Bit8u function,Bit8u mode) { } void INT10_GetDACPage(Bit8u* mode,Bit8u* page) { - IO_Read(VGAREG_ACTL_RESET); + ResetACTL(); IO_Write(VGAREG_ACTL_ADDRESS,0x10); Bit8u reg10=IO_Read(VGAREG_ACTL_READ_DATA); IO_Write(VGAREG_ACTL_WRITE_DATA,reg10); diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 2d9378db..579bd2e6 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.16 2005-04-27 18:58:08 qbix79 Exp $ */ +/* $Id: int10_vesa.cpp,v 1.17 2005-09-27 11:05:44 c2woody Exp $ */ #include #include @@ -158,7 +158,7 @@ foundit: Bit8u VESA_SetSVGAMode(Bit16u mode) { - if (INT10_SetVideoMode(mode & 0xfff)) return 0x00; + if (INT10_SetVideoMode(mode)) return 0x00; return 0x01; }; From 96445503b6df04b2b8cb10b6dae50a6a91870701 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 27 Sep 2005 12:50:54 +0000 Subject: [PATCH 2237/4131] make mount accept ~ for home Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2321 --- src/dos/dos_programs.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 5723d428..ad655c93 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.41 2005-08-24 21:12:24 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.42 2005-09-27 12:50:54 qbix79 Exp $ */ #include #include @@ -141,12 +141,25 @@ public: if (!cmd->FindCommand(2,temp_line)) goto showusage; if (!temp_line.size()) goto showusage; + struct stat test; + //Win32 : strip tailing backslashes + //rest: substiture ~ for home #if defined (WIN32) /* Removing trailing backslash if not root dir so stat will succeed */ if(temp_line.size() > 3 && temp_line[temp_line.size()-1]=='\\') temp_line.erase(temp_line.size()-1,1); -#endif - struct stat test; if (stat(temp_line.c_str(),&test)) { +#else + bool failed = false; + if (stat(temp_line.c_str(),&test)) { + failed = true; + if(temp_line.size() && temp_line[0] == '~') { + char * home = getenv("HOME"); + if(home) temp_line.replace(0,1,std::string(home)); + if(!stat(temp_line.c_str(),&test)) failed = false; + } + } + if(failed) { +#endif WriteOut(MSG_Get("PROGRAM_MOUNT_ERROR_1"),temp_line.c_str()); return; } From 489ffd7d1c41a67e1457cb7ebfef2b0c2cd4ef0c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 27 Sep 2005 13:50:56 +0000 Subject: [PATCH 2238/4131] Add "Support for VGA chain4 in 16-color modes" from patch 1302853 created by Vasyl Tsvirkunov. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2322 --- src/hardware/vga_memory.cpp | 80 ++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 73a0e181..edae45b3 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -40,6 +40,10 @@ static Bitu VGA_NormalReadHandler(PhysPt start) { return 0; } +static Bitu VGA_Chain4ReadHandler(PhysPt start) { + return vga.mem.linear[start]; +} + //Nice one from DosEmu INLINE static Bit32u RasterOp(Bit32u input,Bit32u mask) { @@ -114,6 +118,33 @@ static void VGA_GFX_16_WriteHandler(PhysPt start,Bit8u val) { } +static void VGA_GFX_16Chain4_WriteHandler(PhysPt start,Bit8u val) { + Bit32u data=ModeOperation(val); + /* Update video memory and the pixel buffer */ + VGA_Latch pixels; + vga.mem.linear[start] = val; + start >>= 2; + pixels.d=vga.mem.latched[start].d; + + Bit8u * write_pixels=&vga.mem.linear[512*1024+(start<<3)]; + + Bit32u colors0_3, colors4_7; + VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f; + colors0_3 = + Expand16Table[0][temp.b[0]] | + Expand16Table[1][temp.b[1]] | + Expand16Table[2][temp.b[2]] | + Expand16Table[3][temp.b[3]]; + *(Bit32u *)write_pixels=colors0_3; + temp.d=pixels.d & 0x0f0f0f0f; + colors4_7 = + Expand16Table[0][temp.b[0]] | + Expand16Table[1][temp.b[1]] | + Expand16Table[2][temp.b[2]] | + Expand16Table[3][temp.b[3]]; + *(Bit32u *)(write_pixels+4)=colors4_7; +} + static void VGA_GFX_256U_WriteHandler(PhysPt start,Bit8u val) { Bit32u data=ModeOperation(val); VGA_Latch pixels; @@ -157,6 +188,28 @@ public: } }; +class VGAReadChain4_PageHandler : public PageHandler { +public: + Bitu readb(PhysPt addr) { + addr = PAGING_GetLinearAddress(addr) & 0xffff; + return VGA_Chain4ReadHandler(addr); + } + Bitu readw(PhysPt addr) { + addr = PAGING_GetLinearAddress(addr) & 0xffff; + return + (VGA_Chain4ReadHandler(addr+0) << 0) | + (VGA_Chain4ReadHandler(addr+1) << 8); + } + Bitu readd(PhysPt addr) { + addr = PAGING_GetLinearAddress(addr) & 0xffff; + return + (VGA_Chain4ReadHandler(addr+0) << 0) | + (VGA_Chain4ReadHandler(addr+1) << 8) | + (VGA_Chain4ReadHandler(addr+2) << 16) | + (VGA_Chain4ReadHandler(addr+3) << 24); + } +}; + class VGA_16_PageHandler : public VGARead_PageHandler { public: VGA_16_PageHandler() { @@ -180,6 +233,29 @@ public: } }; +class VGA_16Chain4_PageHandler : public VGAReadChain4_PageHandler { +public: + VGA_16Chain4_PageHandler() { + flags=PFLAG_NOCODE; + } + void writeb(PhysPt addr,Bitu val) { + addr = PAGING_GetLinearAddress(addr) & 0xffff; + VGA_GFX_16Chain4_WriteHandler(addr+0,(Bit8u)(val >> 0)); + } + void writew(PhysPt addr,Bitu val) { + addr = PAGING_GetLinearAddress(addr) & 0xffff; + VGA_GFX_16Chain4_WriteHandler(addr+0,(Bit8u)(val >> 0)); + VGA_GFX_16Chain4_WriteHandler(addr+1,(Bit8u)(val >> 8)); + } + void writed(PhysPt addr,Bitu val) { + addr = PAGING_GetLinearAddress(addr) & 0xffff; + VGA_GFX_16Chain4_WriteHandler(addr+0,(Bit8u)(val >> 0)); + VGA_GFX_16Chain4_WriteHandler(addr+1,(Bit8u)(val >> 8)); + VGA_GFX_16Chain4_WriteHandler(addr+2,(Bit8u)(val >> 16)); + VGA_GFX_16Chain4_WriteHandler(addr+3,(Bit8u)(val >> 24)); + } +}; + class VGA_256_PageHandler : public VGARead_PageHandler { public: VGA_256_PageHandler() { @@ -330,6 +406,7 @@ static struct vg { VGA_TANDY_PageHandler htandy; VGA_256_PageHandler h256; VGA_16_PageHandler h16; + VGA_16Chain4_PageHandler h16c4; VGA_MMIO_PageHandler mmio; } vgaph; @@ -363,7 +440,8 @@ void VGA_SetupHandlers(void) { } break; case M_EGA16: - range_handler=&vgaph.h16; + if (vga.config.chained) range_handler=&vgaph.h16c4; + else range_handler=&vgaph.h16; break; case M_TEXT: /* Check if we're not in odd/even mode */ From 981aed10d4361e14d3f8c432f4e09e1b332469c0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 27 Sep 2005 20:31:05 +0000 Subject: [PATCH 2239/4131] Add a new way of drawing composite cga. Implement register 3d9 in cga mode.(NewRisingSun) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2323 --- src/hardware/vga_draw.cpp | 47 ++++++++++++++++++++-------- src/hardware/vga_other.cpp | 63 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 13 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 253446b5..92172764 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -52,22 +52,43 @@ static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { return TempLine; } -static Bit8u convert16[16]={ - 0x0,0x2,0x1,0x3,0x5,0x7,0x4,0x9, - 0x6,0xa,0x8,0xb,0xd,0xe,0xc,0xf -}; +static Bitu temp[643]={0}; static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart,Bitu panning,Bitu line) { Bit8u * reader=&vga.mem.linear[vidstart + (line * 8 * 1024)]; Bit32u * draw=(Bit32u *)TempLine; + //Generate a temporary bitline to calculate the avarage + //over bit-2 bit-1 bit bit+1. + //Combine this number with the current colour to get + //an unigue index in the pallete. Or it with bit 7 as they are stored + //in the upperpart to keep them from interfering the regular cga stuff + + for(Bitu x = 0; x < 640; x++) + temp[x+2] = (( reader[(x>>3)] >> (7-(x&7)) )&1) << 4; + //shift 4 as that is for the index. + Bitu i = 0,temp1,temp2,temp3,temp4; for (Bitu x=0;x> 4]; - *draw++=(val1 << 0) | - (val1 << 8) | - (val2 << 16) | - (val2 << 24); + Bitu val1 = *reader++; + Bitu val2 = val1&0xf; + val1 >>= 4; + + temp1 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; + temp2 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; + temp3 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; + temp4 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; + + *draw++ = 0x80808080|(temp1|val1) | + ((temp2|val1) << 8) | + ((temp3|val1) <<16) | + ((temp4|val1) <<24); + temp1 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; + temp2 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; + temp3 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; + temp4 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; + *draw++ = 0x80808080|(temp1|val2) | + ((temp2|val2) << 8) | + ((temp3|val2) <<16) | + ((temp4|val2) <<24); } return TempLine; } @@ -426,10 +447,9 @@ void VGA_SetupDrawing(Bitu val) { VGA_DrawLine=VGA_Draw_EGA_Line; break; case M_CGA16: - doublewidth=true; doubleheight=true; vga.draw.blocks=width*2; - width<<=3; + width<<=4; VGA_DrawLine=VGA_Draw_CGA16_Line; break; case M_CGA4: @@ -482,6 +502,7 @@ void VGA_SetupDrawing(Bitu val) { VGA_DrawLine=VGA_Draw_4BPP_Line; break; case M_TANDY_TEXT: + LOG_MSG("tandy text"); doublewidth=(vga.tandy.mode_control & 0x1)==0; case M_HERC_TEXT: aspect_ratio=1; diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 5c92636a..0d7900da 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -20,6 +20,7 @@ #include "dosbox.h" #include "inout.h" #include "vga.h" +#include "render.h" static void write_crtc_index_other(Bitu port,Bitu val,Bitu iolen) { vga.other.index=val; @@ -123,6 +124,65 @@ static Bitu read_crtc_data_other(Bitu port,Bitu iolen) { return (Bitu)-1; } +static void cga16_color_select(Bit8u val) { +// Algorithm provided by NewRisingSun +// His/Her algorithm is more complex and gives better results than the one below +// However that algorithm doesn't fit in our vga pallette. +// Therefore a simple variant is used, but the colours are bit lighter. + +// It uses an avarage over the bits to give smooth transitions from colour to colour +// This is represented by the j variable. The i variable gives the 16 colours +// The draw handler calculates the needed avarage and combines this with the colour +// to match an entry that is generated here. + + int baseR=0, baseG=0, baseB=0; + double sinhue,coshue; + double I,Q,Y,pixelI,pixelQ,R,G,B; + Bitu colorBit1,colorBit2,colorBit3,colorBit4,index; + + if (val & 0x01) baseB += 0xa8; + if (val & 0x02) baseG += 0xa8; + if (val & 0x04) baseR += 0xa8; + if (val & 0x08) { baseR += 0x57; baseG += 0x57; baseB += 0x57; } + if (val & 0x20) { + //Hue = 33.0 + hueoffset (0) + sinhue=0.54463904; //sin(hue*PI/180); + coshue=0.83867057; //sin(hue*PI/180); + } else { + //Hue = 55.0 + hueoffset (0) + sinhue=0.81915204; //sin(hue*PI/180); + coshue=0.57357644; //cos(hue*PI/180); + } + for(Bitu i = 0; i < 16;i++) { + for(Bitu j = 0;j < 5;j++) { + index = 0x80|(j << 4)|i; //use upperpart of vga pallette + colorBit4 = (i&1)>>0; + colorBit3 = (i&2)>>1; + colorBit2 = (i&4)>>2; + colorBit1 = (i&8)>>3; + + //calculate lookup table + I = 0; Q = 0; + I += (double) colorBit1; + Q += (double) colorBit2; + I -= (double) colorBit3; + Q -= (double) colorBit4; + Y = (double) j / 4.0; //calculated avarage is over 4 bits + + pixelI = I * 1.0 / 3.0; //I* tvSaturnation / 3.0 + pixelQ = Q * 1.0 / 3.0; //Q* tvSaturnation / 3.0 + I = pixelI*coshue + pixelQ*sinhue; + Q = pixelQ*coshue - pixelI*sinhue; + + R = Y + 0.956*I + 0.621*Q; if (R < 0.0) R = 0.0; if (R > 1.0) R = 1.0; + G = Y - 0.272*I - 0.647*Q; if (G < 0.0) G = 0.0; if (G > 1.0) G = 1.0; + B = Y - 1.105*I + 1.702*Q; if (B < 0.0) B = 0.0; if (B > 1.0) B = 1.0; + + RENDER_SetPal(index,static_cast(R*baseR),static_cast(G*baseG),static_cast(B*baseB)); + } + } +} + static void write_color_select(Bit8u val) { vga.tandy.color_select=val; switch (vga.mode) { @@ -146,6 +206,9 @@ static void write_color_select(Bit8u val) { } } break; + case M_CGA16: + cga16_color_select(val); + break; case M_TEXT: case M_TANDY16: break; From 583cfcae5d533b9c2d5643d0d4ae991c6a46fe24 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 28 Sep 2005 08:14:27 +0000 Subject: [PATCH 2240/4131] Fix bug 1306390. Batch labels can start with a space Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2324 --- src/shell/shell_batch.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index d708d66b..cf957c5b 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.17 2005-05-18 17:29:09 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.18 2005-09-28 08:14:27 qbix79 Exp $ */ #include #include @@ -133,9 +133,10 @@ again: } } while (c!='\n' && n); *cmd_write++=0; - if (cmd[0]==':') { - char *nospace = trim(cmd+1); - if (strcasecmp(nospace,where)==0) return true; + char *nospace = trim(cmd); + if (nospace[0] == ':') { + char* nonospace = trim(nospace+1); + if (strcasecmp(nonospace,where)==0) return true; } if (!n) { delete this; From 190e5aa920e9e4d8526fcf0cb67c247d01058c34 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 28 Sep 2005 09:23:07 +0000 Subject: [PATCH 2241/4131] Add patch 1302908 from vasyl. Fixes vectorballs in unreal demo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2325 --- src/hardware/vga_draw.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 92172764..3544d0f1 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -35,7 +35,9 @@ static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; for (Bitu x=vga.draw.blocks;x>0;x--) { Bitu val=vga.mem.linear[vidstart+line]; - vidstart=(vidstart+1)&0x1dfff; + vidstart++; + if((vga.crtc.mode_control & 0x01) == 0) // CGA compatible addressing + vidstart &= 0x1dfff; *draw++=CGA_2_Table[val >> 4]; *draw++=CGA_2_Table[val & 0xf]; } @@ -46,7 +48,9 @@ static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; for (Bitu x=0;x Date: Wed, 28 Sep 2005 11:21:50 +0000 Subject: [PATCH 2242/4131] Fix cdrom detection of Xcom Apocalipse Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2326 --- src/dos/dos_mscdex.cpp | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 73b0b74a..c0871f96 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.31 2005-07-10 20:29:14 c2woody Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.32 2005-09-28 11:21:50 qbix79 Exp $ */ #include #include @@ -582,7 +582,13 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph MEM_StrCopy(pathname+1,searchName,mem_readb(pathname)); upcase(searchName); char* searchPos = searchName; -// LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Get DirEntry : Find : %s",searchName); + + //strip of tailing . (XCOM APOCALIPSE) + int searchlen = strlen(searchName); + if(searchlen > 1 && strcmp(searchName,"..")) + if(searchName[searchlen-1] =='.') searchName[searchlen-1] = 0; + + //LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Get DirEntry : Find : %s",searchName); // read vtoc PhysPt defBuffer = GetDefaultBuffer(); if (!ReadSectors(GetSubUnit(drive),false,16,1,defBuffer)) return false; @@ -613,10 +619,22 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph nameLength = mem_readb(defBuffer+index+32); MEM_StrCopy(defBuffer+index+33,entryName,nameLength); if (strcmp(entryName,useName)==0) { -// LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Get DirEntry : Found : %s",useName); + //LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Get DirEntry : Found : %s",useName); foundName = true; break; } + /* Xcom Apocalipse searches for MUSIC. and expects to find MUSIC;1 + * All Files on the CDROM are of the kind blah;1 + */ + char* longername = strchr(entryName,';'); + if(longername) { + *longername = 0; + if (strcmp(entryName,useName)==0) { + //LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Get DirEntry : Found : %s",useName); + foundName = true; + break; + } + } index += entryLength; } while (index+33<=2048); @@ -725,8 +743,7 @@ Bit16u CMscdex::GetStatusWord(Bit8u subUnit) return status; }; -void CMscdex::InitNewMedia(Bit8u subUnit) -{ +void CMscdex::InitNewMedia(Bit8u subUnit) { if (subUnitInitNewMedia(); @@ -735,16 +752,12 @@ void CMscdex::InitNewMedia(Bit8u subUnit) static CMscdex* mscdex = 0; -static Bitu MSCDEX_Strategy_Handler(void) -{ -// LOG("MSCDEX: Device Strategy Routine called."); +static Bitu MSCDEX_Strategy_Handler(void) { +// MSCDEX_LOG("MSCDEX: Device Strategy Routine called."); return CBRET_NONE; } -static Bitu MSCDEX_Interrupt_Handler(void) -{ -// LOG("MSCDEX: Device Interrupt Routine called."); - +static Bitu MSCDEX_Interrupt_Handler(void) { Bit8u subFuncNr = 0xFF; PhysPt data = PhysMake(SegValue(es),reg_bx); Bit8u subUnit = mem_readb(data+1); From 6b94af7c5851f746caee25f8ef5b423eda0d5325 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 28 Sep 2005 12:52:36 +0000 Subject: [PATCH 2243/4131] Fix booting now that register layout in dos_execute has changed. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2327 --- src/dos/dos_programs.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index ad655c93..0b4be7bb 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.42 2005-09-27 12:50:54 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.43 2005-09-28 12:52:36 qbix79 Exp $ */ #include #include @@ -415,6 +415,7 @@ public: reg_ecx = 1; reg_ebp = 0; reg_eax = 0; + reg_edx = 0; //Head 0 drive 0 reg_ebx= 0x7c00; //Real code is probably uses bx to load the image //DEBUG_EnableDebugger(); From 74d63d330b3130f14112676e4b733aae7aa2ca51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 28 Sep 2005 19:13:21 +0000 Subject: [PATCH 2244/4131] fix returncode of int21,ah=5b (create new file) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2328 --- include/dos_inc.h | 3 ++- src/dos/dos.cpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index a68f81df..8531692d 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.55 2005-08-08 13:33:43 c2woody Exp $ */ +/* $Id: dos_inc.h,v 1.56 2005-09-28 19:13:21 c2woody Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -223,6 +223,7 @@ INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) { #define DOSERR_REMOVE_CURRENT_DIRECTORY 16 #define DOSERR_NOT_SAME_DEVICE 17 #define DOSERR_NO_MORE_FILES 18 +#define DOSERR_FILE_ALREADY_EXISTS 80 /* Remains some classes used to access certain things */ diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index fccf1413..b47c95dc 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.86 2005-08-23 13:58:03 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.87 2005-09-28 19:13:21 c2woody Exp $ */ #include #include @@ -756,7 +756,7 @@ static Bitu DOS_21Handler(void) { Bit16u handle; if (DOS_OpenFile(name1,0,&handle)) { DOS_CloseFile(handle); - DOS_SetError(DOSERR_ACCESS_DENIED); + DOS_SetError(DOSERR_FILE_ALREADY_EXISTS); reg_ax=dos.errorcode; CALLBACK_SCF(true); break; From 5464fb8bcaaaf5c4c523ee4628d9d8e50cc275de Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 29 Sep 2005 08:48:39 +0000 Subject: [PATCH 2245/4131] Internal documentation update. Merging with patch 1277001 from TaeWoong Yoo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2329 --- src/dos/dos_programs.cpp | 104 +++++++++++++++++++++++++++++++++------ src/shell/shell.cpp | 5 +- src/shell/shell_cmds.cpp | 4 +- 3 files changed, 95 insertions(+), 18 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 0b4be7bb..dc00a07f 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.43 2005-09-28 12:52:36 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.44 2005-09-29 08:48:39 qbix79 Exp $ */ #include #include @@ -536,12 +536,41 @@ static void RESCAN_ProgramStart(Program * * make) { class INTRO : public Program { public: + void DisplayMount(void) { + /* Basic mounting has a version for each operating system. + * This is done this way so both messages appear in the language file*/ + WriteOut(MSG_Get("PROGRAM_INTRO_MOUNT_START")); +#if (WIN32) + WriteOut(MSG_Get("PROGRAM_INTRO_MOUNT_WINDOWS")); +#else + WriteOut(MSG_Get("PROGRAM_INTRO_MOUNT_OTHER")); +#endif + WriteOut(MSG_Get("PROGRAM_INTRO_MOUNT_END")); + } + void Run(void) { if(cmd->FindExist("cdrom",false)) { - WriteOut(MSG_Get("PROGRAM_INTRO_CDROM")); + WriteOut(MSG_Get("PROGRAM_INTRO_CDROM")); return; } + if(cmd->FindExist("mount",false)) { + WriteOut("\033[2J");//Clear screen before printing + DisplayMount(); + return; + } + if(cmd->FindExist("special",false)) { + WriteOut(MSG_Get("PROGRAM_INTRO_SPECIAL")); + return; + } + /* Default action is to show all pages */ WriteOut(MSG_Get("PROGRAM_INTRO")); + Bit8u c;Bit16u n=1; + DOS_ReadFile (STDIN,&c,&n); + DisplayMount(); + DOS_ReadFile (STDIN,&c,&n); + WriteOut(MSG_Get("PROGRAM_INTRO_CDROM")); + DOS_ReadFile (STDIN,&c,&n); + WriteOut(MSG_Get("PROGRAM_INTRO_SPECIAL")); } }; @@ -779,27 +808,52 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_RESCAN_SUCCESS","Drive cache cleared.\n"); MSG_Add("PROGRAM_INTRO", - "\033[2J\033[33;1mWelcome to DOSBox\033[0m, an x86 emulator with sound and graphics.\n" + "\033[2J\033[32;1mWelcome to DOSBox\033[0m, an x86 emulator with sound and graphics.\n" "DOSBox creates a shell for you which looks like old plain DOS.\n" - "\n" - "Here are some commands to get you started:\n" + "\n" + "For information about basic mount type \033[34;1mintro mount\033[0m\n" + "For information about CD-ROM support type \033[34;1mintro cdrom\033[0m\n" + "For information about special keys type \033[34;1mintro special\033[0m\n" + "For more information about DOSBox, go to \033[34;1mhttp://dosbox.sourceforge.net/wiki\033[0m\n" + "\n" + "\033[31;1mDOSBox will stop/exit without a warning if an error occured!\033[0m\n" + "\n" + "\n" + ); + MSG_Add("PROGRAM_INTRO_MOUNT_START", + "\033[32;1mHere are some commands to get you started:\033[0m\n" "Before you can use the files located on your own filesystem,\n" "You have to mount the directory containing the files.\n" - "For \033[1mWindows\033[0m:\n" - "\033[34;1mmount c c:\\dosprog\033[0m will create a C drive in DOSBox with c:\\dosprog as contents.\n" - "\n" - "For \033[1mother platforms\033[0m:\n" - "\033[34;1mmount c /home/user/dosprog\033[0m will do the same.\n" "\n" + ); + MSG_Add("PROGRAM_INTRO_MOUNT_WINDOWS", + "\033[44;1m\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n" + "\xBA \033[32mmount c c:\\dosprog\\\033[37m will create a C drive with c:\\dosprog as contents. \xBA\n" + "\xBA \xBA\n" + "\xBA \033[32mc:\\dosprog\\\033[37m is an example. Replace it with your own games directory. \033[37m \xBA\n" + "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC\033[0m\n" + ); + MSG_Add("PROGRAM_INTRO_MOUNT_OTHER", + "\033[44;1m\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n" + "\xBA \033[32mmount c ~/dosprog\033[37m will create a C drive with ~/dosprog as contents. \xBA\n" + "\xBA \xBA\n" + "\xBA \033[32m~/dosprog\033[37m is an example. Replace it with your own games directory. \033[37m \xBA\n" + "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC\033[0m\n" + ); + MSG_Add("PROGRAM_INTRO_MOUNT_END", "When the mount has succesfully completed you can type \033[34;1mc:\033[0m to go to your freshly\n" "mounted C-drive. Typing \033[34;1mdir\033[0m there will show its contents." " \033[34;1mcd\033[0m will allow you to\n" - "enter a directory (recognised by the \033[1m[]\033[0m in a directory listing).\n" + "enter a directory (recognised by the \033[33;1m[]\033[0m in a directory listing).\n" "You can run programs/files which end with \033[31m.exe .bat\033[0m and \033[31m.com\033[0m.\n" - "\n" - "For information about CD-ROM support type \033[34;1mintro cdrom\033[0m\n" - "\n" - "\033[32;1mDOSBox will stop/exit without a warning if an error occured!\033[0m\n" ); MSG_Add("PROGRAM_INTRO_CDROM", "\033[2J\033[32;1mHow to mount a Real/Virtual CD-ROM Drive in DOSBox:\033[0m\n" @@ -826,6 +880,26 @@ void DOS_SetupPrograms(void) { "Replace the \033[33;1m0\033[0m in \033[34;1m-usecd \033[33m0\033[0m with the number reported for your CD-ROM if you type:\n" "\033[34;1mmount -cd\033[0m\n" ); + MSG_Add("PROGRAM_INTRO_SPECIAL", + "\033[2J\033[32;1mSpecial keys:\033[0m\n" + "These are the default keybindings.\n" + "They can be changed in the \033[33mkeymapper\033[0m.\n" + "\n" + "\033[33;1mALT-ENTER\033[0m : Go full screen and back.\n" + "\033[33;1mPAUSE\033[0m : Pause DOSBox.\n" + "\033[33;1mCTRL-F1\033[0m : Start the \033[33mkeymapper\033[0m.\n" + "\033[33;1mCTRL-F4\033[0m : Update directory cache for all drives! Swap mounted disk-image.\n" + "\033[33;1mCTRL-F5\033[0m : Save a screenshot.\n" + "\033[33;1mCTRL-F6\033[0m : Start/Stop recording sound output to a wave file.\n" + "\033[33;1mCTRL-ALT-F7\033[0m : Start/Stop recording of OPL commands.\n" + "\033[33;1mCTRL-ALT-F8\033[0m : Start/Stop the recording of raw MIDI commands.\n" + "\033[33;1mCTRL-F7\033[0m : Decrease frameskip.\n" + "\033[33;1mCTRL-F8\033[0m : Increase frameskip.\n" + "\033[33;1mCTRL-F9\033[0m : Kill DOSBox.\n" + "\033[33;1mCTRL-F10\033[0m : Capture/Release the mouse.\n" + "\033[33;1mCTRL-F11\033[0m : Slow down emulation (Decrease DOSBox Cycles).\n" + "\033[33;1mCTRL-F12\033[0m : Speed up emulation (Increase DOSBox Cycles).\n" + ); MSG_Add("PROGRAM_BOOT_NOT_EXIST","Bootdisk file does not exist. Failing.\n"); MSG_Add("PROGRAM_BOOT_NOT_OPEN","Cannot open bootdisk file. Failing.\n"); MSG_Add("PROGRAM_BOOT_PRINT_ERROR","This command boots DosBox from either a floppy or hard disk image.\n\n" diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 857b65bd..95d8c472 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.62 2005-08-22 19:31:27 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.63 2005-09-29 08:48:39 qbix79 Exp $ */ #include #include @@ -369,6 +369,7 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_ECHO_OFF","ECHO is off.\n"); MSG_Add("SHELL_ILLEGAL_SWITCH","Illegal switch: %s.\n"); MSG_Add("SHELL_CMD_CHDIR_ERROR","Unable to change to: %s.\n"); + MSG_Add("SHELL_CMD_CHDIR_HINT","To change to different drive type \033[31m%c:\033[0m\n"); MSG_Add("SHELL_CMD_MKDIR_ERROR","Unable to make: %s.\n"); MSG_Add("SHELL_CMD_RMDIR_ERROR","Unable to remove: %s.\n"); MSG_Add("SHELL_CMD_DEL_ERROR","Unable to delete: %s.\n"); @@ -385,7 +386,7 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_DIR_INTRO","Directory of %s.\n"); MSG_Add("SHELL_CMD_DIR_BYTES_USED","%5d File(s) %17s Bytes.\n"); MSG_Add("SHELL_CMD_DIR_BYTES_FREE","%5d Dir(s) %17s Bytes free.\n"); - MSG_Add("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\nYou must \033[31mmount\033[0m it first. Type \033[1;33mintro\033[0m for more information.\n"); + MSG_Add("SHELL_EXECUTE_DRIVE_NOT_FOUND","Drive %c does not exist!\nYou must \033[31mmount\033[0m it first. Type \033[1;33mintro\033[0m or \033[1;33mintro mount\033[0m for more information.\n"); MSG_Add("SHELL_EXECUTE_ILLEGAL_COMMAND","Illegal command: %s.\n"); MSG_Add("SHELL_CMD_PAUSE","Press any key to continue.\n"); MSG_Add("SHELL_CMD_PAUSE_HELP","Waits for 1 keystroke to continue.\n"); diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 4a8fcce8..c314d71a 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.57 2005-09-10 14:15:37 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.58 2005-09-29 08:48:39 qbix79 Exp $ */ #include #include @@ -213,6 +213,8 @@ void DOS_Shell::CMD_CHDIR(char * args) { char dir[DOS_PATHLENGTH]; DOS_GetCurrentDir(0,dir); WriteOut("%c:\\%s\n",drive,dir); + } else if(strlen(args) == 2 && args[1]==':') { + WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT"),toupper(*reinterpret_cast(&args[0]))); } else if (!DOS_ChangeDir(args)) { WriteOut(MSG_Get("SHELL_CMD_CHDIR_ERROR"),args); } From c36e1f72ee7f57b9b0e9fea0b227bad9b6e2794b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 29 Sep 2005 14:59:57 +0000 Subject: [PATCH 2246/4131] removed log message Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2330 --- src/hardware/vga_draw.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 3544d0f1..9c97e5b3 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -506,7 +506,6 @@ void VGA_SetupDrawing(Bitu val) { VGA_DrawLine=VGA_Draw_4BPP_Line; break; case M_TANDY_TEXT: - LOG_MSG("tandy text"); doublewidth=(vga.tandy.mode_control & 0x1)==0; case M_HERC_TEXT: aspect_ratio=1; From 1f3c7cb1602c8517b5739ca299eb3e63d66faf26 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 30 Sep 2005 10:14:27 +0000 Subject: [PATCH 2247/4131] Fix Celtic Tales. By enabling writes to planes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2331 --- src/ints/mouse.cpp | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 8fa4c3d3..4ccbce0e 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.54 2005-09-21 11:37:35 c2woody Exp $ */ +/* $Id: mouse.cpp,v 1.55 2005-09-30 10:14:27 qbix79 Exp $ */ #include #include @@ -247,25 +247,33 @@ void DrawCursorText() // Mouse cursor - graphic mode // *************************************************************************** -static Bit8u gfxReg[9]; - +static Bit8u gfxReg3CE[9]; +static Bit8u index3C4,gfxReg3C5; void SaveVgaRegisters() { for (int i=0; i<9; i++) { IO_Write (0x3CE,i); - gfxReg[i] = IO_Read(0x3CF); + gfxReg3CE[i] = IO_Read(0x3CF); } /* Setup some default values in GFX regs that should work */ IO_Write(0x3CE,3); IO_Write(0x3Cf,0); //disable rotate and operation - IO_Write(0x3CE,5); IO_Write(0x3Cf,gfxReg[5]&0xf0); //Force read/write mode 0 + IO_Write(0x3CE,5); IO_Write(0x3Cf,gfxReg3CE[5]&0xf0); //Force read/write mode 0 + + //Set Map to all planes. Celtic Tales + index3C4 = IO_Read(0x3c4); IO_Write(0x3C4,2); + gfxReg3C5 = IO_Read(0x3C5); IO_Write(0x3C5,0xF); } void RestoreVgaRegisters() { for (int i=0; i<9; i++) { IO_Write(0x3CE,i); - IO_Write(0x3CF,gfxReg[i]); + IO_Write(0x3CF,gfxReg3CE[i]); } + + IO_Write(0x3C4,2); + IO_Write(0x3C5,gfxReg3C5); + IO_Write(0x3C4,index3C4); } void ClipCursorArea(Bit16s& x1, Bit16s& x2, Bit16s& y1, Bit16s& y2, Bit16u& addx1, Bit16u& addx2, Bit16u& addy) @@ -472,7 +480,6 @@ void Mouse_ButtonReleased(Bit8u button) { } static void SetMickeyPixelRate(Bit16s px, Bit16s py){ - if ((px!=0) && (py!=0)) { mouse.mickeysPerPixel_x = (float)px/X_MICKEY; mouse.mickeysPerPixel_y = (float)py/Y_MICKEY; @@ -536,8 +543,8 @@ void Mouse_NewVideoMode(void) default: mouse.max_y=199; LOG(LOG_MOUSE,LOG_ERROR)("Unhandled videomode %X on reset",mode); - // Hide mouse cursor on non supported modi. - mouse.shown=-1; + // Hide mouse cursor on non supported modi. Pirates Gold + mouse.shown = -1; break; } mouse.max_x = 639; @@ -600,7 +607,7 @@ static void mouse_reset(void) { static Bitu INT33_Handler(void) { -// LOG(LOG_MOUSE,LOG_NORMAL)("MOUSE: %04X %d %d",reg_ax,POS_X,POS_Y); +// LOG(LOG_MOUSE,LOG_NORMAL)("MOUSE: %04X %X %X %d %d",reg_ax,reg_bx,reg_cx,POS_X,POS_Y); switch (reg_ax) { case 0x00: /* Reset Driver and Read Status */ mouse_reset_hardware(); /* fallthrough */ From 06d4ae4b3bea5f309b953bfe6680c3b83bbf617a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 1 Oct 2005 15:26:32 +0000 Subject: [PATCH 2248/4131] fix dynamic core div/idiv (Aces over Europe intro) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2332 --- src/cpu/core_dyn_x86/decoder.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index dd71cfff..9733b1e8 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -745,10 +745,10 @@ static void dyn_grp3_eb(void) { case 0x7: /* idiv Eb */ /* EAX could be used, so precache it */ if (decode.modrm.mod==3) - gen_dop_byte(DOP_MOV,src,0,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); + gen_dop_byte(DOP_MOV,DREG(TMPB),0,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); gen_releasereg(DREG(EAX)); gen_call_function((decode.modrm.reg==6) ? (void *)&dyn_helper_divb : (void *)&dyn_helper_idivb, - "%Rd%Dd",DREG(TMPB),src); + "%Rd%Dd",DREG(TMPB),DREG(TMPB)); dyn_check_bool_exception(DREG(TMPB)); goto skipsave; } @@ -785,12 +785,12 @@ static void dyn_grp3_ev(void) { case 0x7: /* idiv Eb */ /* EAX could be used, so precache it */ if (decode.modrm.mod==3) - gen_dop_word(DOP_MOV,decode.big_op,src,&DynRegs[decode.modrm.rm]); + gen_dop_word(DOP_MOV,decode.big_op,DREG(TMPW),&DynRegs[decode.modrm.rm]); gen_releasereg(DREG(EAX));gen_releasereg(DREG(EDX)); void * func=(decode.modrm.reg==6) ? (decode.big_op ? (void *)&dyn_helper_divd : (void *)&dyn_helper_divw) : (decode.big_op ? (void *)&dyn_helper_idivd : (void *)&dyn_helper_idivw); - gen_call_function(func,"%Rd%Dd",DREG(TMPB),src); + gen_call_function(func,"%Rd%Dd",DREG(TMPB),DREG(TMPW)); dyn_check_bool_exception(DREG(TMPB)); gen_releasereg(DREG(TMPB)); goto skipsave; From 0b4350c79df8a2970fbb6f308af322b30e94ac38 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 2 Oct 2005 10:12:31 +0000 Subject: [PATCH 2249/4131] Add final (slightly modified and extended) part of patch 1295927 (vga accuracy) from keith. Add (modified) bug/patch 1241142(ansi emulation updates) from moe. Add fix suggested by vasyl to fix MyChess. Corrected some missing parts in these patches. (Missing update nbrows in dev_con.h). Implemented a writebuffer to workaround the CR/LF issue. Let's hope everything still works Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2333 --- src/dos/dev_con.h | 49 ++++++++++++++++++++++----------------- src/hardware/vga_misc.cpp | 20 +++++++++++++++- src/ints/int10.cpp | 9 +++++++ src/ints/int10.h | 2 +- src/ints/int10_char.cpp | 12 ++++++---- src/ints/int10_memory.cpp | 2 +- src/ints/int10_modes.cpp | 8 +------ 7 files changed, 66 insertions(+), 36 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index d94124ab..18daa012 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.20 2005-02-10 10:20:50 qbix79 Exp $ */ +/* $Id: dev_con.h,v 1.21 2005-10-02 10:12:29 qbix79 Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" @@ -34,7 +34,8 @@ public: void ClearAnsi(void); Bit16u GetInformation(void); private: - Bit8u cache; + Bit8u readcache; + Bit8u lastwrite; struct ansi { /* should create a constructor which fills them with the appriorate values */ bool esc; bool sci; @@ -53,10 +54,10 @@ private: bool device_CON::Read(Bit8u * data,Bit16u * size) { Bit16u oldax=reg_ax; Bit16u count=0; - if ((cache) && (*size)) { - data[count++]=cache; - if(dos.echo) INT10_TeletypeOutput(cache,7); - cache=0; + if ((readcache) && (*size)) { + data[count++]=readcache; + if(dos.echo) INT10_TeletypeOutput(readcache,7); + readcache=0; } while (*size>count) { reg_ah=0; @@ -89,7 +90,7 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { case 0: data[count++]=reg_al; if (*size>count) data[count++]=reg_ah; - else cache=reg_ah; + else readcache=reg_ah; break; } if(dos.echo) { //what to do if *size==1 and character is BS ????? @@ -117,9 +118,11 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { count++; continue; } else { + /* Some sort of "hack" now that \n doesn't set col to 0 (int10_char.cpp old chessgame) */ + if((data[count] == '\n') && (lastwrite != '\r')) INT10_TeletypeOutputAttr('\r',ansi.attr,ansi.enabled); /* pass attribute only if ansi is enabled */ INT10_TeletypeOutputAttr(data[count],ansi.attr,ansi.enabled); - count++; + lastwrite = data[count++]; continue; } } @@ -130,7 +133,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { case '[': ansi.sci=true; break; - case '7': /* save cursor pos +attr */ + case '7': /* save cursor pos + attr */ case '8': /* restore this (Wonder if this is actually used) */ case 'D':/* scrolling DOWN*/ case 'M':/* scrolling UP*/ @@ -298,16 +301,15 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { break; case 'J': /*erase screen and move cursor home*/ if(ansi.data[0]==0) ansi.data[0]=2; - if(ansi.data[0]!=2) {/* only number 2 (the standard one supported) */ - LOG(LOG_IOCTL,LOG_NORMAL)("ANSI: esc[%dJ called : not supported",ansi.data[0]); - break; + if(ansi.data[0]!=2) {/* every version behaves like type 2 */ + LOG(LOG_IOCTL,LOG_NORMAL)("ANSI: esc[%dJ called : not supported handling as 2",ansi.data[0]); } - for(i=0;i<(Bitu)ansi.ncols*ansi.nrows;i++) INT10_TeletypeOutputAttr(' ',ansi.attr,true); + INT10_ScrollWindow(0,0,999,999,0,ansi.attr,0xFF); ClearAnsi(); INT10_SetCursorPos(0,0,0); break; - case 'h': /* set MODE (if code =7 enable linewrap) */ - case 'I': /*RESET MODE */ + case 'h': /* SET MODE (if code =7 enable linewrap) */ + case 'I': /* RESET MODE */ LOG(LOG_IOCTL,LOG_NORMAL)("ANSI: set/reset mode called(not supported)"); ClearAnsi(); break; @@ -320,9 +322,13 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { ansi.saverow=CURSOR_POS_ROW(0); ClearAnsi(); break; - case 'K':/* erase till end of line */ - for(i = CURSOR_POS_COL(0);i<(Bitu) ansi.ncols; i++) INT10_TeletypeOutputAttr(' ',ansi.attr,true); - ClearAnsi(); /* maybe set cursor back to starting place ???? */ + case 'K':/* erase till end of line (don't touch cursor) */ + col = CURSOR_POS_COL(0); + row = CURSOR_POS_ROW(0); + INT10_WriteChar(' ',ansi.attr,0,ansi.ncols-col,true); //Use this one to prevent scrolling when end of screen is reached + //for(i = col;i<(Bitu) ansi.ncols; i++) INT10_TeletypeOutputAttr(' ',ansi.attr,true); + INT10_SetCursorPos(row,col,0); + ClearAnsi(); break; case 'l':/* (if code =7) disable linewrap */ case 'p':/* reassign keys (needs strings) */ @@ -352,17 +358,18 @@ Bit16u device_CON::GetInformation(void) { Bit16u head=mem_readw(BIOS_KEYBOARD_BUFFER_HEAD); Bit16u tail=mem_readw(BIOS_KEYBOARD_BUFFER_TAIL); - if ((head==tail) && !cache) return 0x80D3; /* No Key Available */ + if ((head==tail) && !readcache) return 0x80D3; /* No Key Available */ return 0x8093; /* Key Available */ }; device_CON::device_CON() { SetName("CON"); - cache=0; + readcache=0; + lastwrite=0; ansi.enabled=false; ansi.attr=0x7; ansi.ncols=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); //should be updated once set/reset mode is implemented - ansi.nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS) + 1; + ansi.nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS); ansi.saverow=0; ansi.savecol=0; ClearAnsi(); diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 4af47ffc..92495588 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -94,10 +94,29 @@ static Bitu read_p3cc(Bitu port,Bitu iolen) { return vga.misc_output; } +/* +Test 13: Hardware: General Registers + Mode 00h, General -- Feat Ctrl: IBM=00h Current=FFh + Mode 00h, General -- Input Status 0: IBM=70h Current=FFh + .. & modes 1,2,3,4,5,6,d,e,10,11,12,13 + +following read handlers silence the above vgatest errors. + +*/ + +static Bitu read_p3ca(Bitu port,Bitu iolen) { + return 0; +} + +static Bitu read_p3c2(Bitu port,Bitu iolen) { + return 0x70; +} void VGA_SetupMisc(void) { if (machine==MCH_VGA) { + IO_RegisterReadHandler(0x3ca,read_p3ca,IO_MB); + IO_RegisterReadHandler(0x3c2,read_p3c2,IO_MB); IO_RegisterWriteHandler(0x3c2,write_p3c2,IO_MB); IO_RegisterReadHandler(0x3cc,read_p3cc,IO_MB); } else if (machine==MCH_CGA || machine==MCH_TANDY) { @@ -105,7 +124,6 @@ void VGA_SetupMisc(void) { } else if (machine==MCH_HERC) { IO_RegisterReadHandler(0x3ba,read_p3da,IO_MB); } - } diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 1cd0d074..46bd874b 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -46,6 +46,7 @@ static Bitu INT10_Handler(void) { break; } #endif + switch (reg_ah) { case 0x00: /* Set VideoMode */ INT10_SetVideoMode(reg_al); @@ -279,6 +280,14 @@ graphics_chars: reg_cx=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES) & 0x0F; break; } + case 0x34: /* ALTERNATE FUNCTION SELECT (VGA) - CURSOR EMULATION */ + { + // bit 0: 0=enable, 1=disable + Bit8u temp = real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL) & 0xfe; + real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,temp|reg_al); + reg_al=0x12; + break; + } case 0x36: /* VGA Refresh control */ /* Call disables/enables the vga from outputting video, diff --git a/src/ints/int10.h b/src/ints/int10.h index 2db43333..e7ae5c81 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -92,7 +92,7 @@ #define VGAMEM_MTEXT 0xB000 #define BIOS_NCOLS Bit16u ncols=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); -#define BIOS_NROWS Bit16u nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; +#define BIOS_NROWS Bit16u nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS); extern Bit8u int10_font_08[256 * 8]; extern Bit8u int10_font_14[256 * 14]; diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 3835034f..a0c765ba 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.37 2005-09-01 14:31:40 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.38 2005-10-02 10:12:31 qbix79 Exp $ */ /* Character displaying moving functions */ @@ -309,11 +309,12 @@ void INT10_SetCursorShape(Bit8u first,Bit8u last) { goto dowrite; } /* Check if we need to convert CGA Bios cursor values */ - if (!(real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL) & 0x1)) { + if (!(real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL) & 0x1)) { // set by int10 fun12 sub34 // if (CurMode->mode>0x3) goto dowrite; //Only mode 0-3 are text modes on cga if ((first & 0xe0) || (last & 0xe0)) goto dowrite; Bit8u cheight=real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT)-1; /* Creative routine i based of the original ibmvga bios */ + if (last0xc) { - first--; + + if (cheight>0xc) { // vgatest sets 15 15 2x where only one should be decremented to 14 14 + first--; // implementing int10 fun12 sub34 fixed this. last--; } } @@ -537,7 +539,7 @@ void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr) { cur_col=0; break; case '\n': - cur_col=0; +// cur_col=0; //Seems to break an old chess game cur_row++; break; case '\t': diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 52f51a3d..9252e054 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -66,7 +66,7 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu IO_Write(base+1,(IO_Read(base+1) & 0xe0)|(height-1)); //Vertical display end bios says, but should stay the same? //Rows setting in bios segment - real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,(CurMode->sheight/height)-1); + real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,(CurMode->sheight/height)); real_writeb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,height); //TODO Reprogram cursor size? } diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 24d433be..5d96a40e 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -223,7 +223,7 @@ static void FinishSetMode(bool clearmem) { real_writew(BIOSMEM_SEG,BIOSMEM_NB_COLS,CurMode->twidth); real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,CurMode->plength); real_writew(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,((CurMode->mode==7 )|| (CurMode->mode==0x0f)) ? 0x3b4 : 0x3d4); - real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,CurMode->theight-1); + real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,CurMode->theight); real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,CurMode->cheight); real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem?0:0x80))); real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0x09); @@ -487,12 +487,6 @@ bool INT10_SetVideoMode(Bitu mode) { overflow|=((CurMode->vtotal-2) & 0x200) >> 4; ver_overflow|=((CurMode->vtotal-2) & 0x400) >> 10; -/* - These aren't exactly accurate i think, - Should be more like a certain percentage based on vertical total - So you get same sized borders, but okay :) - */ - Bitu vretrace; switch (CurMode->vdispend) { case 400: vretrace=CurMode->vdispend+12; From a270f4d0bc3950deabb6fe398a67aa2929847c59 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 3 Oct 2005 14:03:49 +0000 Subject: [PATCH 2250/4131] Some small corrections to patch 1295927 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2334 --- src/dos/dev_con.h | 4 ++-- src/ints/int10.h | 2 +- src/ints/int10_memory.cpp | 2 +- src/ints/int10_misc.cpp | 3 ++- src/ints/int10_modes.cpp | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 18daa012..0a27c73f 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.21 2005-10-02 10:12:29 qbix79 Exp $ */ +/* $Id: dev_con.h,v 1.22 2005-10-03 14:03:49 qbix79 Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" @@ -369,7 +369,7 @@ device_CON::device_CON() { ansi.enabled=false; ansi.attr=0x7; ansi.ncols=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); //should be updated once set/reset mode is implemented - ansi.nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS); + ansi.nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS) + 1; ansi.saverow=0; ansi.savecol=0; ClearAnsi(); diff --git a/src/ints/int10.h b/src/ints/int10.h index e7ae5c81..2db43333 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -92,7 +92,7 @@ #define VGAMEM_MTEXT 0xB000 #define BIOS_NCOLS Bit16u ncols=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); -#define BIOS_NROWS Bit16u nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS); +#define BIOS_NROWS Bit16u nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; extern Bit8u int10_font_08[256 * 8]; extern Bit8u int10_font_14[256 * 14]; diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 9252e054..52f51a3d 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -66,7 +66,7 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu IO_Write(base+1,(IO_Read(base+1) & 0xe0)|(height-1)); //Vertical display end bios says, but should stay the same? //Rows setting in bios segment - real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,(CurMode->sheight/height)); + real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,(CurMode->sheight/height)-1); real_writeb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,height); //TODO Reprogram cursor size? } diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 92d7fea5..cbcf578e 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -82,7 +82,8 @@ void INT10_GetFuncStateInformation(PhysPt save) { mem_writeb(save+0x4+i,real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE+i)); } /* Second area */ - for (i=0;i<3;i++) { + mem_writeb(save+0x22,real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1); + for (i=1;i<3;i++) { mem_writeb(save+0x22+i,real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS+i)); } /* Zero out rest of block */ diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 5d96a40e..d527a8bf 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -223,7 +223,7 @@ static void FinishSetMode(bool clearmem) { real_writew(BIOSMEM_SEG,BIOSMEM_NB_COLS,CurMode->twidth); real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,CurMode->plength); real_writew(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,((CurMode->mode==7 )|| (CurMode->mode==0x0f)) ? 0x3b4 : 0x3d4); - real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,CurMode->theight); + real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,CurMode->theight-1); real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,CurMode->cheight); real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem?0:0x80))); real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0x09); From 59910aafbc56d8cc30d2c547ff1c141529a6b662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 3 Oct 2005 19:22:13 +0000 Subject: [PATCH 2251/4131] add some EGA RIL functions, show mouse on requestet page (1994Pool); don't use current page for bios string output (Gobble Man) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2335 --- src/ints/int10.cpp | 23 +++++++- src/ints/int10.h | 8 ++- src/ints/int10_char.cpp | 14 +++-- src/ints/int10_misc.cpp | 120 ++++++++++++++++++++++++++++++++++++++-- src/ints/mouse.cpp | 8 +-- 5 files changed, 156 insertions(+), 17 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 46bd874b..90ff9fc8 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -437,8 +437,29 @@ graphics_chars: reg_al=0x0; } break; + case 0xf0: + INT10_EGA_RIL_ReadRegister(reg_bl, reg_dx); + break; case 0xf1: - INT10_EGA_RIL_F1(reg_bl, reg_bh, reg_dx); + INT10_EGA_RIL_WriteRegister(reg_bl, reg_bh, reg_dx); + break; + case 0xf2: + INT10_EGA_RIL_ReadRegisterRange(reg_bl, reg_ch, reg_cl, reg_dx, SegPhys(es)+reg_bx); + break; + case 0xf3: + INT10_EGA_RIL_WriteRegisterRange(reg_bl, reg_ch, reg_cl, reg_dx, SegPhys(es)+reg_bx); + break; + case 0xf4: + INT10_EGA_RIL_ReadRegisterSet(reg_cx, SegPhys(es)+reg_bx); + break; + case 0xf5: + INT10_EGA_RIL_WriteRegisterSet(reg_cx, SegPhys(es)+reg_bx); + break; + case 0xfa: { + RealPt pt=INT10_EGA_RIL_GetVersionPt(); + SegSet16(es,RealSeg(pt)); + reg_bx=RealOff(pt); + } break; case 0xff: if (!warned_ff) LOG(LOG_INT10,LOG_NORMAL)("INT10:FF:Weird NC call"); diff --git a/src/ints/int10.h b/src/ints/int10.h index 2db43333..abdb7110 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -200,4 +200,10 @@ void INT10_SetupRomMemory(void); void INT10_SetupVESA(void); /* EGA RIL */ -void INT10_EGA_RIL_F1(Bit8u & bl, Bit8u bh, Bit16u dx); +RealPt INT10_EGA_RIL_GetVersionPt(void); +void INT10_EGA_RIL_ReadRegister(Bit8u & bl, Bit16u dx); +void INT10_EGA_RIL_WriteRegister(Bit8u & bl, Bit8u bh, Bit16u dx); +void INT10_EGA_RIL_ReadRegisterRange(Bit8u & bl, Bit8u ch, Bit8u cl, Bit16u dx, PhysPt dst); +void INT10_EGA_RIL_WriteRegisterRange(Bit8u & bl, Bit8u ch, Bit8u cl, Bit16u dx, PhysPt dst); +void INT10_EGA_RIL_ReadRegisterSet(Bit16u cx, PhysPt tbl); +void INT10_EGA_RIL_WriteRegisterSet(Bit16u cx, PhysPt tbl); diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index a0c765ba..642885e1 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.38 2005-10-02 10:12:31 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.39 2005-10-03 19:22:13 c2woody Exp $ */ /* Character displaying moving functions */ @@ -522,9 +522,7 @@ void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) } } -void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr) { - //TODO Check if this page thing is correct - Bit8u page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); +static INLINE void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr,Bit8u page) { BIOS_NCOLS;BIOS_NROWS; Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); @@ -544,7 +542,7 @@ void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr) { break; case '\t': do { - INT10_TeletypeOutputAttr(' ',attr,useattr); + INT10_TeletypeOutputAttr(' ',attr,useattr,page); cur_row=CURSOR_POS_ROW(page); cur_col=CURSOR_POS_COL(page); } while(cur_col%8); @@ -569,6 +567,10 @@ void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr) { INT10_SetCursorPos(cur_row,cur_col,page); } +void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr) { + INT10_TeletypeOutputAttr(chr,attr,useattr,real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE)); +} + void INT10_TeletypeOutput(Bit8u chr,Bit8u attr) { INT10_TeletypeOutputAttr(chr,attr,CurMode->type!=M_TEXT); } @@ -591,7 +593,7 @@ void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,B attr=mem_readb(string); string++; }; - INT10_TeletypeOutputAttr(chr,attr,true); + INT10_TeletypeOutputAttr(chr,attr,true,page); count--; } if (!(flag&1)) { diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index cbcf578e..5c680ffc 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -127,6 +127,12 @@ void INT10_GetFuncStateInformation(PhysPt save) { mem_writeb(save+0x31,3); } +RealPt INT10_EGA_RIL_GetVersionPt(void) { + /* points to a graphics ROM location at the moment + as checks test for bx!=0 only */ + return RealMake(0xc000,0x30); +} + static void EGA_RIL(Bit16u dx, Bitu& port, Bitu& regs) { port = 0; regs = 0; //if nul is returned it's a single register port @@ -165,16 +171,120 @@ static void EGA_RIL(Bit16u dx, Bitu& port, Bitu& regs) { } } -void INT10_EGA_RIL_F1(Bit8u & bl, Bit8u bh, Bit16u dx) { +void INT10_EGA_RIL_ReadRegister(Bit8u & bl, Bit16u dx) { Bitu port = 0; Bitu regs = 0; EGA_RIL(dx,port,regs); if(regs == 0) { - IO_Write(port,bl); + if(port) bl = IO_Read(port); } else { + if(port == 0x3c0) IO_Read(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS) + 6); IO_Write(port,bl); - IO_Write(port+1,bh); - bl = bh;//Not sure - LOG(LOG_INT10,LOG_NORMAL)("EGA RIL used with multi-reg"); + bl = IO_Read(port+1); + if(port == 0x3c0) IO_Read(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS) + 6); + LOG(LOG_INT10,LOG_NORMAL)("EGA RIL read used with multi-reg"); + } +} + +void INT10_EGA_RIL_WriteRegister(Bit8u & bl, Bit8u bh, Bit16u dx) { + Bitu port = 0; + Bitu regs = 0; + EGA_RIL(dx,port,regs); + if(regs == 0) { + if(port) IO_Write(port,bl); + } else { + if(port == 0x3c0) { + IO_Read(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS) + 6); + IO_Write(port,bl); + IO_Write(port,bh); + } else { + IO_Write(port,bl); + IO_Write(port+1,bh); + } + bl = bh;//Not sure + LOG(LOG_INT10,LOG_NORMAL)("EGA RIL write used with multi-reg"); + } +} + +void INT10_EGA_RIL_ReadRegisterRange(Bit8u & bl, Bit8u ch, Bit8u cl, Bit16u dx, PhysPt dst) { + Bitu port = 0; + Bitu regs = 0; + EGA_RIL(dx,port,regs); + if(regs == 0) { + LOG(LOG_INT10,LOG_ERROR)("EGA RIL range read with port %x called",port); + } else { + if(chregs) cl=regs-ch; + for (Bitu i=0; iregs) cl=regs-ch; + if(port == 0x3c0) { + IO_Read(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS) + 6); + for (Bitu i=0; i #include @@ -321,7 +321,7 @@ void RestoreCursorBackground() for (y=y1; y<=y2; y++) { dataPos += addx1; for (x=x1; x<=x2; x++) { - INT10_PutPixel(x,y,0,mouse.backData[dataPos++]); + INT10_PutPixel(x,y,mouse.page,mouse.backData[dataPos++]); }; dataPos += addx2; }; @@ -378,7 +378,7 @@ void DrawCursor() { for (y=y1; y<=y2; y++) { dataPos += addx1; for (x=x1; x<=x2; x++) { - INT10_GetPixel(x,y,0,&mouse.backData[dataPos++]); + INT10_GetPixel(x,y,mouse.page,&mouse.backData[dataPos++]); }; dataPos += addx2; }; @@ -401,7 +401,7 @@ void DrawCursor() { if (cuMask & HIGHESTBIT) pixel = pixel ^ 0x0F; cuMask<<=1; // Set Pixel - INT10_PutPixel(x,y,0,pixel); + INT10_PutPixel(x,y,mouse.page,pixel); dataPos++; }; dataPos += addx2; From d87e59032f2b4cf7c641ef750c41bbf73ceb078c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 4 Oct 2005 12:59:12 +0000 Subject: [PATCH 2252/4131] Add patch 1311184 and 1250588 from cyberwalker and shdon Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2336 --- src/ints/xms.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index e33e7b64..7847f1fe 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.36 2005-08-08 13:33:46 c2woody Exp $ */ +/* $Id: xms.cpp,v 1.37 2005-10-04 12:59:12 qbix79 Exp $ */ #include #include @@ -54,6 +54,7 @@ #define XMS_DEALLOCATE_UMB 0x11 #define XMS_QUERY_ANY_FREE_MEMORY 0x88 #define XMS_ALLOCATE_ANY_MEMORY 0x89 +#define XMS_GET_EMB_HANDLE_INFORMATION_EXT 0x8e #define XMS_FUNCTION_NOT_IMPLEMENTED 0x80 #define HIGH_MEMORY_NOT_EXIST 0x90 @@ -318,10 +319,11 @@ Bitu XMS_Handler(void) { reg_bl = XMS_UnlockMemory(reg_dx); reg_ax = (reg_bl==0); break; - case XMS_GET_EMB_HANDLE_INFORMATION: /* 0e */ - reg_bl = XMS_GetHandleInformation(reg_dx,reg_bh,reg_bl,reg_dx); - reg_ax = (reg_bl==0); - break; + case XMS_GET_EMB_HANDLE_INFORMATION: { /* 0e */ + Bitu result = XMS_GetHandleInformation(reg_dx,reg_bh,reg_bl,reg_dx); + if (result != 0) reg_bl = result; + reg_ax = (result==0); + }; break; case XMS_RESIZE_EXTENDED_MEMORY_BLOCK: /* 0f */ reg_bl = XMS_ResizeMemory(reg_dx, reg_bx); reg_ax = (reg_bl==0); @@ -380,10 +382,15 @@ Bitu XMS_Handler(void) { break; case XMS_QUERY_ANY_FREE_MEMORY: /* 88 */ reg_bl = XMS_QueryFreeMemory(reg_ax,reg_dx); - reg_eax &= 0xffff; - reg_edx &= 0xffff; - reg_ecx = (MEM_TotalPages()*MEM_PAGESIZE)-1; // highest known physical memory address + reg_eax &= 0xffff; + reg_edx &= 0xffff; + reg_ecx = (MEM_TotalPages()*MEM_PAGESIZE)-1; // highest known physical memory address break; + case XMS_GET_EMB_HANDLE_INFORMATION_EXT: { + Bitu result = XMS_GetHandleInformation(reg_dx,reg_bh,reg_bl,reg_dx); + if (result != 0) reg_bl = result; else reg_edx &= 0xFFFF; + reg_ax = (result==0); + } break; default: LOG(LOG_MISC,LOG_ERROR)("XMS: unknown function %02X",reg_ah); reg_ax=0; From 015278394453c56fde79b4400d49435be6a7e557 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 5 Oct 2005 07:57:55 +0000 Subject: [PATCH 2253/4131] Implement GetFileAttr. Fixes Installer crystal caves. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2337 --- src/dos/drive_virtual.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 43a507ed..802e6d6f 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -225,6 +225,14 @@ bool Virtual_Drive::FindNext(DOS_DTA & dta) { } bool Virtual_Drive::GetFileAttr(char * name,Bit16u * attr) { + VFILE_Block * cur_file=first_file; + while (cur_file) { + if (strcasecmp(name,cur_file->name)==0) { + *attr = DOS_ATTR_ARCHIVE; //Maybe readonly ? + return true; + } + cur_file=cur_file->next; + } return false; } From 511687f8f1551fd496d661750135a83e806c9823 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 5 Oct 2005 08:58:24 +0000 Subject: [PATCH 2254/4131] Change behavior of rename when in the source a directory is specified Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2338 --- src/shell/shell_cmds.cpp | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index c314d71a..8f816242 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.58 2005-09-29 08:48:39 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.59 2005-10-05 08:58:24 qbix79 Exp $ */ #include #include @@ -176,7 +176,32 @@ void DOS_Shell::CMD_RENAME(char * args){ if(!*args) {SyntaxError();return;} if((strchr(args,'*')!=NULL) || (strchr(args,'?')!=NULL) ) { WriteOut(MSG_Get("SHELL_CMD_NO_WILD"));return;} char * arg1=StripWord(args); - DOS_Rename(arg1,args); + char* slash = strrchr(arg1,'\\'); + if(slash) { + slash++; + //If directory specified (crystal caves installer) + // rename from c:\X : rename c:\abc.exe abc.shr. File must appear in C:\ + + char dir_source[DOS_PATHLENGTH]={0}; + //Copy first and then modify, makes GCC happy + strcpy(dir_source,arg1); + char* dummy = strrchr(dir_source,'\\'); + *dummy=0; + + if((strlen(dir_source) == 2) && (dir_source[1] == ':')) + strcat(dir_source,"\\"); //X: add slash + + char dir_current[DOS_PATHLENGTH]; + DOS_GetCurrentDir(0,dir_current); + if(!DOS_ChangeDir(dir_source)) { + WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); + return; + } + DOS_Rename(slash,args); + DOS_ChangeDir(dir_current); + } else { + DOS_Rename(arg1,args); + } } void DOS_Shell::CMD_ECHO(char * args){ From a77e5b6d36d2f69ad002920e839d9f98af61ac9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 7 Oct 2005 15:16:58 +0000 Subject: [PATCH 2255/4131] use 16bit for mediaid-field (Pinball 3D/VCR installer workaround); create new PSP function should copy command line (Kings Quest AGI -cga switch) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2339 --- src/dos/dos_execute.cpp | 7 +++++-- src/dos/dos_files.cpp | 4 ++-- src/dos/dos_programs.cpp | 8 ++++---- src/dos/dos_tables.cpp | 6 +++--- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 1dc618f0..846f604b 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.49 2005-09-19 08:25:38 c2woody Exp $ */ +/* $Id: dos_execute.cpp,v 1.50 2005-10-07 15:16:58 c2woody Exp $ */ #include #include @@ -185,8 +185,11 @@ static bool MakeEnv(char * name,Bit16u * segment) { bool DOS_NewPSP(Bit16u segment, Bit16u size) { DOS_PSP psp(segment); psp.MakeNew(size); - DOS_PSP psp_parent(psp.GetParent()); + Bit16u parent_psp_seg=psp.GetParent(); + DOS_PSP psp_parent(parent_psp_seg); psp.CopyFileTable(&psp_parent,false); + // copy command line as well (Kings Quest AGI -cga switch) + psp.SetCommandTail(RealMake(parent_psp_seg,0x80)); return true; }; diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index ad3e7515..4af385ee 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.69 2005-09-11 13:09:45 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.70 2005-10-07 15:16:58 c2woody Exp $ */ #include #include @@ -1014,7 +1014,7 @@ bool DOS_GetAllocationInfo(Bit8u drive,Bit16u * _bytes_sector,Bit8u * _sectors_c Bit16u _free_clusters; Drives[drive]->AllocationInfo(_bytes_sector,_sectors_cluster,_total_clusters,&_free_clusters); SegSet16(ds,RealSeg(dos.tables.mediaid)); - reg_bx=RealOff(dos.tables.mediaid+drive); + reg_bx=RealOff(dos.tables.mediaid+drive*2); return true; } diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index dc00a07f..baf3a899 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.44 2005-09-29 08:48:39 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.45 2005-10-07 15:16:58 c2woody Exp $ */ #include #include @@ -203,7 +203,7 @@ public: if (!newdrive) E_Exit("DOS:Can't create drive"); Drives[drive-'A']=newdrive; /* Set the correct media byte in the table */ - mem_writeb(Real2Phys(dos.tables.mediaid)+drive-'A',newdrive->GetMediaByte()); + mem_writeb(Real2Phys(dos.tables.mediaid)+(drive-'A')*2,newdrive->GetMediaByte()); WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,newdrive->GetInfo()); /* check if volume label is given and don't allow it to updated in the future */ if (cmd->FindString("-label",label,true)) newdrive->dirCache.SetLabel(label.c_str(),false); @@ -725,7 +725,7 @@ public: if (!newdrive) WriteOut(MSG_Get("PROGRAM_IMGMOUNT_CANT_CREATE")); Drives[drive-'A']=newdrive; // Set the correct media byte in the table - mem_writeb(Real2Phys(dos.tables.mediaid)+drive-'A',mediaid); + mem_writeb(Real2Phys(dos.tables.mediaid)+(drive-'A')*2,mediaid); WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,temp_line.c_str()); if(((fatDrive *)newdrive)->loadedDisk->hardDrive) { if(imageDiskList[2] == NULL) { @@ -751,7 +751,7 @@ public: if (!newdrive) WriteOut(MSG_Get("PROGRAM_IMGMOUNT_CANT_CREATE")); Drives[drive-'A']=newdrive; // Set the correct media byte in the table - mem_writeb(Real2Phys(dos.tables.mediaid)+drive-'A',mediaid); + mem_writeb(Real2Phys(dos.tables.mediaid)+(drive-'A')*2,mediaid); WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,temp_line.c_str()); } else if (fstype=="none") { if(imageDiskList[drive] != NULL) delete imageDiskList[drive]; diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index a2bd7754..95bdca02 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.20 2005-08-08 13:33:46 c2woody Exp $ */ +/* $Id: dos_tables.cpp,v 1.21 2005-10-07 15:16:58 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -75,10 +75,10 @@ static Bit8u country_info[0x22] = { void DOS_SetupTables(void) { dos_memseg=0xd000; Bit16u seg,seg2;Bitu i; - dos.tables.mediaid=RealMake(DOS_GetMemory(2),0); + dos.tables.mediaid=RealMake(DOS_GetMemory(4),0); dos.tables.tempdta=RealMake(DOS_GetMemory(4),0); dos.tables.tempdta_fcbdelete=RealMake(DOS_GetMemory(4),0); - for (i=0;i Date: Sun, 9 Oct 2005 15:17:01 +0000 Subject: [PATCH 2256/4131] don't add a handler twice. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2340 --- src/gui/sdl_mapper.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index e27d3eeb..96b6a5db 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.14 2005-08-10 20:36:36 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.15 2005-10-09 15:17:01 qbix79 Exp $ */ #define OLD_JOYSTICK 1 @@ -962,8 +962,9 @@ public: protected: MapKeys defkey; Bitu defmod; - char * buttonname; MAPPER_Handler * handler; +public: + char * buttonname; }; @@ -1326,6 +1327,10 @@ static void CreateDefaultBinds(void) { } void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char * eventname,char * buttonname) { + //Check if it allready exists=> if so return. + for(CHandlerEventVector_it it=handlergroup.begin();it!=handlergroup.end();it++) + if(strcmp((*it)->buttonname,buttonname) == 0) return; + char tempname[17]; strcpy(tempname,"hand_"); strcat(tempname,eventname); From 5f47d64ea74425016956e0488af5320133438fde Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 9 Oct 2005 15:20:05 +0000 Subject: [PATCH 2257/4131] mapper accepts handlers again Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2341 --- src/gui/midi.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 8b8b2c07..524ab956 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -240,8 +240,7 @@ public: const char * conf=section->Get_string("config"); /* If device = "default" go for first handler that works */ MidiHandler * handler; - //TODO!!!!!!!!!!!!!!! -// MAPPER_AddHandler(MIDI_SaveRawEvent,MK_f8,MMOD1|MMOD2,"caprawmidi","Cap MIDI"); + MAPPER_AddHandler(MIDI_SaveRawEvent,MK_f8,MMOD1|MMOD2,"caprawmidi","Cap MIDI"); midi.status=0x00; midi.cmd_pos=0; midi.cmd_len=0; From 420a5a7fd03408de4ac0b910e0ec7336d8be22f1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 9 Oct 2005 15:33:07 +0000 Subject: [PATCH 2258/4131] Make the soundblaster really reinitializable. Fixes bug 1241149 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2342 --- include/hardware.h | 6 ++- src/hardware/adlib.cpp | 84 +++++++++++++++++++++++------------- src/hardware/gameblaster.cpp | 43 ++++++++++++------ src/hardware/sblaster.cpp | 14 +++--- 4 files changed, 95 insertions(+), 52 deletions(-) diff --git a/include/hardware.h b/include/hardware.h index 5b5079b8..0c89fa5e 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -26,8 +26,10 @@ enum OPL_Mode { OPL_none,OPL_cms,OPL_opl2,OPL_dualopl2,OPL_opl3 }; -void OPL_Init(Section* sec,Bitu base,OPL_Mode mode,Bitu rate); -void CMS_Init(Section* sec,Bitu base,Bitu rate); +void OPL_Init(Section* sec,OPL_Mode mode); +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); diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index c1246f86..7ab235ca 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -312,37 +312,61 @@ static void OPL_SaveRawEvent(void) { } } -static void OPL_Stop(Section* sec) { - if (opl.raw.handle) OPL_SaveRawEvent(); -} +class OPL: public Module_base { +private: + IO_ReadHandleObject ReadHandler[3]; + IO_WriteHandleObject WriteHandler[3]; + MixerObject MixerChan; +public: + static OPL_Mode oplmode; -void OPL_Init(Section* sec,Bitu base,OPL_Mode oplmode,Bitu rate) { - Section_prop * section=static_cast(sec); - if (OPL2::YM3812Init(2,OPL2_INTERNAL_FREQ,rate)) { - E_Exit("Can't create OPL2 Emulator"); - }; - OPL2::YM3812SetTimerHandler(0,OPL2::TimerHandler,0); - OPL2::YM3812SetTimerHandler(1,OPL2::TimerHandler,256); - if (THEOPL3::YMF262Init(1,OPL3_INTERNAL_FREQ,rate)) { - E_Exit("Can't create OPL3 Emulator"); - }; - THEOPL3::YMF262SetTimerHandler(0,THEOPL3::TimerHandler,0); - IO_RegisterWriteHandler(0x388,OPL_Write,IO_MB,4); - IO_RegisterReadHandler(0x388,OPL_Read,IO_MB,4); - if (oplmode>=OPL_dualopl2) { - IO_RegisterWriteHandler(base,OPL_Write,IO_MB,4); - IO_RegisterReadHandler(base,OPL_Read,IO_MB,4); + OPL(Section* configuration):Module_base(configuration) { + Section_prop * section=static_cast(configuration); + Bitu base = section->Get_hex("base"); + Bitu rate = section->Get_int("oplrate"); + if (OPL2::YM3812Init(2,OPL2_INTERNAL_FREQ,rate)) { + E_Exit("Can't create OPL2 Emulator"); + }; + OPL2::YM3812SetTimerHandler(0,OPL2::TimerHandler,0); + OPL2::YM3812SetTimerHandler(1,OPL2::TimerHandler,256); + if (THEOPL3::YMF262Init(1,OPL3_INTERNAL_FREQ,rate)) { + E_Exit("Can't create OPL3 Emulator"); + }; + THEOPL3::YMF262SetTimerHandler(0,THEOPL3::TimerHandler,0); + WriteHandler[0].Install(0x388,OPL_Write,IO_MB,4); + ReadHandler[0].Install(0x388,OPL_Read,IO_MB,4); + if (oplmode>=OPL_dualopl2) { + WriteHandler[1].Install(base,OPL_Write,IO_MB,4); + ReadHandler[1].Install(base,OPL_Read,IO_MB,4); + } + + WriteHandler[2].Install(base+8,OPL_Write,IO_MB,2); + ReadHandler[2].Install(base+8,OPL_Read,IO_MB,2); + + opl.active=false; + opl.last_used=0; + opl.mode=oplmode; + memset(&opl.raw,0,sizeof(opl.raw)); + opl.chan=MixerChan.Install(OPL_CallBack,rate,"FM"); + MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL"); + } + ~OPL() { + if (opl.raw.handle) OPL_SaveRawEvent(); + OPL2::YM3812Shutdown(); + THEOPL3::YMF262Shutdown(); } - - IO_RegisterWriteHandler(base+8,OPL_Write,IO_MB,2); - IO_RegisterReadHandler(base+8,OPL_Read,IO_MB,2); - - opl.active=false; - opl.last_used=0; - opl.mode=oplmode; - memset(&opl.raw,0,sizeof(opl.raw)); - opl.chan=MIXER_AddChannel(OPL_CallBack,rate,"FM"); - MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL"); - sec->AddDestroyFunction(&OPL_Stop); }; +static OPL* test; + +//Initialize static members +OPL_Mode OPL::oplmode=OPL_none; + +void OPL_Init(Section* sec,OPL_Mode oplmode) { + OPL::oplmode = oplmode; + test = new OPL(sec); +} + +void OPL_ShutDown(Section* sec){ + delete test; +} diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index f061a351..2df5fa77 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -420,20 +420,39 @@ static void write_cms(Bitu port,Bitu val,Bitu iolen) { } - void CMS_Init(Section* sec,Bitu base,Bitu rate) { - Section_prop * section=static_cast(sec); - sample_rate=rate; +class CMS:public Module_base { +private: + IO_WriteHandleObject WriteHandler; + MixerObject MixerChan; - IO_RegisterWriteHandler(base,write_cms,IO_MB,4); +public: + CMS(Section* configuration):Module_base(configuration) { + Section_prop * section=static_cast(configuration); + Bitu sample_rate = section->Get_int("oplrate"); + Bitu base = section->Get_hex("base"); + WriteHandler.Install(base,write_cms,IO_MB,4); -/* Register the Mixer CallBack */ - - cms_chan=MIXER_AddChannel(CMS_CallBack,rate,"CMS"); - last_command=PIC_Ticks; + /* Register the Mixer CallBack */ + cms_chan = MixerChan.Install(CMS_CallBack,sample_rate,"CMS"); - for (int s=0;s<2;s++) { - struct SAA1099 *saa = &saa1099[s]; - memset(saa, 0, sizeof(struct SAA1099)); + last_command=PIC_Ticks; + + for (int s=0;s<2;s++) { + struct SAA1099 *saa = &saa1099[s]; + memset(saa, 0, sizeof(struct SAA1099)); + } } -} + ~CMS() { + cms_chan->Enable(false); + } +}; + +static CMS* test; + +void CMS_Init(Section* sec) { + test = new CMS(sec); +} +void CMS_ShutDown(Section* sec) { + delete test; +} diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 6e124d55..bc8a1816 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1132,13 +1132,13 @@ public: break; case OPL_cms: WriteHandler[0].Install(0x388,adlib_gusforward,IO_MB); - CMS_Init(section,sb.hw.base,oplrate); + CMS_Init(section); break; case OPL_opl2: - CMS_Init(section,sb.hw.base,oplrate); + CMS_Init(section); case OPL_dualopl2: case OPL_opl3: - OPL_Init(section,sb.hw.base,opl_mode,oplrate); + OPL_Init(section,opl_mode); break; } if (sb.type==SBT_NONE) return; @@ -1174,13 +1174,13 @@ public: break; case OPL_cms: -//TODO CMS_Init(section,sb.hw.base,oplrate); + CMS_ShutDown(m_configuration); break; case OPL_opl2: -//TODO CMS_Init(section,sb.hw.base,oplrate); + CMS_ShutDown(m_configuration); case OPL_dualopl2: case OPL_opl3: -//TODO OPL_Init(section,sb.hw.base,opl_mode,oplrate); + OPL_ShutDown(m_configuration); break; } @@ -1190,8 +1190,6 @@ public: }; //End of SBLASTER class - - static SBLASTER* test; void SBLASTER_ShutDown(Section* sec) { delete test; From 7865e50411d9de4a32c679e2816130aa03df143b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 9 Oct 2005 15:50:09 +0000 Subject: [PATCH 2259/4131] Add modified patch for restartable renderer from moe. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2343 --- src/dosbox.cpp | 4 ++-- src/gui/render.cpp | 23 ++++++++++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index bb4a9aa8..ae642ba4 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.87 2005-08-08 13:33:46 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.88 2005-10-09 15:50:09 qbix79 Exp $ */ #include #include @@ -220,7 +220,7 @@ void DOSBOX_Init(void) { "captures -- Directory where things like wave,midi,screenshot get captured.\n" ); - secprop=control->AddSection_prop("render",&RENDER_Init); + secprop=control->AddSection_prop("render",&RENDER_Init,true); secprop->Add_int("frameskip",0); secprop->Add_bool("aspect",false); secprop->Add_string("scaler","normal2x"); diff --git a/src/gui/render.cpp b/src/gui/render.cpp index e768837c..fe7da14e 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.32 2005-09-01 19:48:37 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.33 2005-10-09 15:50:09 qbix79 Exp $ */ #include #include @@ -383,15 +383,16 @@ static void DecreaseFrameSkip(void) { void RENDER_Init(Section * sec) { Section_prop * section=static_cast(sec); + //For restarting the renderer. + static bool running = false; + bool aspect = render.aspect; + RENDER_Operation type = render.op.want_type; + render.pal.first=256; render.pal.last=0; render.aspect=section->Get_bool("aspect"); render.frameskip.max=section->Get_int("frameskip"); render.frameskip.count=0; - render.updating=true; -#if (C_SSHOT) - MAPPER_AddHandler(EnableScreenShot,MK_f5,MMOD1,"scrshot","Screenshot"); -#endif const char * scaler;std::string cline; if (control->cmdline->FindString("-scaler",cline,false)) { scaler=cline.c_str(); @@ -409,6 +410,18 @@ void RENDER_Init(Section * sec) { render.op.want_type=OP_Normal; LOG_MSG("Illegal scaler type %s,falling back to normal.",scaler); } + + //If something changed that needs a ReInit + if(running && (render.aspect != aspect || render.op.want_type != type)) + RENDER_ReInit(); + if(!running) render.updating=true; + running = true; + + + +#if (C_SSHOT) + MAPPER_AddHandler(EnableScreenShot,MK_f5,MMOD1,"scrshot","Screenshot"); +#endif MAPPER_AddHandler(DecreaseFrameSkip,MK_f7,MMOD1,"decfskip","Dec Fskip"); MAPPER_AddHandler(IncreaseFrameSkip,MK_f8,MMOD1,"incfskip","Inc Fskip"); GFX_SetTitle(-1,render.frameskip.max,false); From aa8b2f11f4d9531c84ed7633968817e56aaf0553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 10 Oct 2005 10:16:42 +0000 Subject: [PATCH 2260/4131] correct register usage of xms function 0x8e Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2344 --- src/ints/xms.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 7847f1fe..5f7fce4e 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.37 2005-10-04 12:59:12 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.38 2005-10-10 10:16:42 c2woody Exp $ */ #include #include @@ -386,9 +386,14 @@ Bitu XMS_Handler(void) { reg_edx &= 0xffff; reg_ecx = (MEM_TotalPages()*MEM_PAGESIZE)-1; // highest known physical memory address break; - case XMS_GET_EMB_HANDLE_INFORMATION_EXT: { - Bitu result = XMS_GetHandleInformation(reg_dx,reg_bh,reg_bl,reg_dx); - if (result != 0) reg_bl = result; else reg_edx &= 0xFFFF; + case XMS_GET_EMB_HANDLE_INFORMATION_EXT: { /* 8e */ + Bit8u free_handles; + Bitu result = XMS_GetHandleInformation(reg_dx,reg_bh,free_handles,reg_dx); + if (result != 0) reg_bl = result; + else { + reg_edx &= 0xffff; + reg_cx = free_handles; + } reg_ax = (result==0); } break; default: From b475db8f13237261643ba3016626bd0fe664c9f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 10 Oct 2005 17:08:35 +0000 Subject: [PATCH 2261/4131] fill psp-field of mcb with current psp when resizing Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2345 --- src/dos/dos_memory.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index ae0a8cf1..0f97762d 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -188,6 +188,7 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { mcb_new_next.SetSize(total-*blocks-1); mcb_new_next.SetPSPSeg(MCB_FREE); + mcb.SetPSPSeg(dos.psp()); return true; } if (mcb.GetType()!=0x5a) { @@ -205,6 +206,7 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { mcb_next.SetType(mcb.GetType()); mcb_next.SetPSPSeg(MCB_FREE); mcb.SetType(0x4d); + mcb.SetPSPSeg(dos.psp()); return true; } if (*blocks==total) { @@ -212,6 +214,7 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { mcb.SetType(mcb_next.GetType()); } mcb.SetSize(*blocks); + mcb.SetPSPSeg(dos.psp()); return true; } *blocks=total; From bb792e21a124c75f441f9d84cc25e3bdf77ef569 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 11 Oct 2005 09:39:16 +0000 Subject: [PATCH 2262/4131] Change composite mode detection a bit so that spellcasting 101 displays in black and white Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2346 --- src/hardware/vga_other.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 0d7900da..5ae48a0d 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -267,7 +267,7 @@ static void write_cga(Bitu port,Bitu val,Bitu iolen) { vga.tandy.mode_control=val; if (vga.tandy.mode_control & 0x2) { if (vga.tandy.mode_control & 0x10) { - if (val & 0x8 && machine==MCH_CGA) { + if (!(val & 0x4) && machine==MCH_CGA) { VGA_SetMode(M_CGA16); //Video burst 16 160x200 color mode } else { VGA_SetMode(M_TANDY2); From 267d3c2539f997afa8dd1f80a9db118bc6e167b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 13 Oct 2005 16:24:42 +0000 Subject: [PATCH 2263/4131] resize MCB to maximum if requested size is too big (DSPlay) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2347 --- src/dos/dos_memory.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 0f97762d..6a3c47a8 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -191,6 +191,7 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { mcb.SetPSPSeg(dos.psp()); return true; } + /* MCB will grow, try to join with following MCB */ if (mcb.GetType()!=0x5a) { if (mcb_next.GetPSPSeg()==MCB_FREE) { total+=mcb_next.GetSize()+1; @@ -198,6 +199,7 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { } if (*blockstotal, + in the second case resize block to maximum */ + + if (mcb.GetType()!=0x5a) { + /* adjust type of joined MCB */ + mcb.SetType(mcb_next.GetType()); } - *blocks=total; + mcb.SetSize(total); + mcb.SetPSPSeg(dos.psp()); + if (*blocks==total) return true; /* block fit exactly */ + + *blocks=total; /* return maximum */ DOS_SetError(DOSERR_INSUFFICIENT_MEMORY); return false; } From 9d1cf58132638d8ee41213fd42ae6fa4377cbd6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 17 Oct 2005 20:17:08 +0000 Subject: [PATCH 2264/4131] better compatibility of the flags after dos exec/terminate (updated Ultima3) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2348 --- src/dos/dos_execute.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 846f604b..c089a06b 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.50 2005-10-07 15:16:58 c2woody Exp $ */ +/* $Id: dos_execute.cpp,v 1.51 2005-10-17 20:17:08 c2woody Exp $ */ #include #include @@ -131,7 +131,9 @@ bool DOS_Terminate(bool tsr) { /* Set the CS:IP stored in int 0x22 back on the stack */ mem_writew(SegPhys(ss)+reg_sp+0,RealOff(old22)); mem_writew(SegPhys(ss)+reg_sp+2,RealSeg(old22)); - mem_writew(SegPhys(ss)+reg_sp+4,reg_flags&(~FLAG_CF)); + /* set IOPL=3 (Strike Commander), nested task set, + interrupts enabled, test flags cleared */ + mem_writew(SegPhys(ss)+reg_sp+4,0x7202); // Free memory owned by process if (!tsr) DOS_FreeProcessMemory(mempsp); DOS_UpdatePSPName(); @@ -395,8 +397,9 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { mem_writew(SegPhys(ss)+reg_sp+0,RealOff(csip)); mem_writew(SegPhys(ss)+reg_sp+2,RealSeg(csip)); /* DOS starts programs with a RETF, so our IRET - should not modify the flags (e.g. IOPL in v86 mode) */ - mem_writew(SegPhys(ss)+reg_sp+4,reg_flags&(~FLAG_CF)); + should not modify critical flags (IOPL in v86 mode); + interrupt flag is set explicitly, test flags cleared */ + mem_writew(SegPhys(ss)+reg_sp+4,(reg_flags&(~FMASK_TEST))|FLAG_IF); /* Setup the rest of the registers */ reg_ax=reg_bx=0;reg_cx=0xff; reg_dx=pspseg; From 593e664e8b658d1d5551232b8754bba51f481753 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 19 Oct 2005 06:40:33 +0000 Subject: [PATCH 2265/4131] Apply patch 1329540: Fixes compilation on GCC4.1 Changed order of definitions as well. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2349 --- include/programs.h | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/include/programs.h b/include/programs.h index e4d10330..90163958 100644 --- a/include/programs.h +++ b/include/programs.h @@ -30,12 +30,6 @@ #endif - -class Program; - -typedef void (PROGRAMS_Main)(Program * * make); -void PROGRAMS_MakeFile(char * name,PROGRAMS_Main * main); - class Program { public: Program(); @@ -47,12 +41,15 @@ public: CommandLine * cmd; DOS_PSP * psp; virtual void Run(void)=0; - bool Program::GetEnvStr(const char * entry,std::string & result); + bool GetEnvStr(const char * entry,std::string & result); bool GetEnvNum(Bitu num,std::string & result); Bitu GetEnvCount(void); bool SetEnv(const char * entry,const char * new_string); - void WriteOut(const char * format,...); /* Write to standard output */ + void WriteOut(const char * format,...); /* Write to standard output */ }; +typedef void (PROGRAMS_Main)(Program * * make); +void PROGRAMS_MakeFile(char * name,PROGRAMS_Main * main); + #endif From 7f07885811479abf0e48e889c71b0866a0a76b1a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 21 Oct 2005 11:20:08 +0000 Subject: [PATCH 2266/4131] Commit patch 1311364 from vasyl. Improves chain4 memory model when in vga mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2350 --- include/vga.h | 1 + src/hardware/vga_crtc.cpp | 2 ++ src/hardware/vga_draw.cpp | 18 +++++++++++++++++- src/hardware/vga_memory.cpp | 36 +++++++++++++++++++++++++++++++++++- src/ints/int10_modes.cpp | 5 ++++- 5 files changed, 59 insertions(+), 3 deletions(-) diff --git a/include/vga.h b/include/vga.h index f61f6e71..5fde426f 100644 --- a/include/vga.h +++ b/include/vga.h @@ -62,6 +62,7 @@ typedef struct { /* 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 */ diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 9c7445fb..82daa008 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -293,6 +293,8 @@ void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen) { case 0x31: /* CR31 Memory Configuration */ //TODO Base address vga.s3.reg_31=val; + vga.config.compatible_chain4 = !(val&0x08); + VGA_SetupHandlers(); break; /* 0 Enable Base Address Offset (CPUA BASE). Enables bank operation if diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 9c97e5b3..b0ff8370 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -131,6 +131,22 @@ static Bit8u * VGA_Draw_VGA_Line(Bitu vidstart,Bitu panning,Bitu line) { return &vga.mem.linear[vidstart*4+panning]; } +static Bit8u * VGA_Draw_VGAChained_Line(Bitu vidstart,Bitu panning,Bitu line) { + if(vga.config.compatible_chain4) { + if(vga.crtc.underline_location & 0x40) { + Bitu readindex = vidstart*4+panning; + Bit32u* draw = (Bit32u*)TempLine; + for(Bitu x=0;x> 0)); + } + void writew(PhysPt addr,Bitu val) { + addr = PAGING_GetLinearAddress(addr) & 0xffff; + VGA_Chain4WriteHandler(addr+0,(Bit8u)(val >> 0)); + VGA_Chain4WriteHandler(addr+1,(Bit8u)(val >> 8)); + } + void writed(PhysPt addr,Bitu val) { + addr = PAGING_GetLinearAddress(addr) & 0xffff; + VGA_Chain4WriteHandler(addr+0,(Bit8u)(val >> 0)); + VGA_Chain4WriteHandler(addr+1,(Bit8u)(val >> 8)); + VGA_Chain4WriteHandler(addr+2,(Bit8u)(val >> 16)); + VGA_Chain4WriteHandler(addr+3,(Bit8u)(val >> 24)); + } +}; + class VGA_TEXT_PageHandler : public PageHandler { public: VGA_TEXT_PageHandler() { @@ -405,6 +435,7 @@ static struct vg { VGA_TEXT_PageHandler htext; VGA_TANDY_PageHandler htandy; VGA_256_PageHandler h256; + VGA_256Chain4_PageHandler h256c4; VGA_16_PageHandler h16; VGA_16Chain4_PageHandler h16c4; VGA_MMIO_PageHandler mmio; @@ -434,7 +465,10 @@ void VGA_SetupHandlers(void) { break; case M_VGA: if (vga.config.chained) { - range_handler=&vgaph.hmap; + if(vga.config.compatible_chain4) + range_handler = &vgaph.h256c4; + else + range_handler=&vgaph.hmap; } else { range_handler=&vgaph.h256; } diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index d527a8bf..06db9fdd 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -439,6 +439,8 @@ bool INT10_SetVideoMode(Bitu mode) { IO_Write(0x3c4,i); IO_Write(0x3c5,seq_data[i]); } + vga.config.compatible_chain4 = true; // this may be changed by SVGA chipset emulation + /* Program CRTC */ /* First disable write protection */ IO_Write(crtc_base,0x11); @@ -822,7 +824,8 @@ dac_text16: IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 16)); /* Setup some remaining S3 registers */ - IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,0x9); //Enable banked memory and 256k+ access +// IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,0x9); //Enable banked memory and 256k+ access + IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,CurMode->mode<=0x13?0x1:0x9); //Enable banked memory and 256k+ access for SVGA modes only IO_Write(crtc_base,0x58);IO_Write(crtc_base+1,0x3); //Enable 8 mb of linear addressing IO_Write(crtc_base,0x38);IO_Write(crtc_base+1,0x48); //Register lock 1 IO_Write(crtc_base,0x39);IO_Write(crtc_base+1,0xa5); //Register lock 2 From aec4e8489f223201d02d5b80c56cc5bab641169d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 21 Oct 2005 16:49:48 +0000 Subject: [PATCH 2267/4131] fix tandy put pixel with high attribute bit set (Kings Quest tandy booter) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2351 --- src/ints/int10_put_pixel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index a1ead666..241d8d35 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -65,7 +65,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { Bitu ind = 1-(x & 0x1); if (color & 0x80) { - p[ind]^=color; + p[ind]^=(color & 0x7f); } else { p[ind]=color; } From 9175b74b13f22cac5c9d530b91093f0345635e9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 22 Oct 2005 10:28:57 +0000 Subject: [PATCH 2268/4131] correct video startup mode field Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2352 --- src/ints/bios.cpp | 5 +++-- src/ints/bios_disk.cpp | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 1abdfef9..28dddbd5 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.46 2005-09-21 11:37:35 c2woody Exp $ */ +/* $Id: bios.cpp,v 1.47 2005-10-22 10:28:57 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -735,7 +735,8 @@ public: //Startup monochrome config|=0x30; break; - case MCH_CGA: + case MCH_VGA: + case MCH_CGA: case MCH_TANDY: //Startup 80x25 color config|=0x20; diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 1a244c65..6608ad6b 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.22 2005-09-11 13:06:00 qbix79 Exp $ */ +/* $Id: bios_disk.cpp,v 1.23 2005-10-22 10:28:57 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" @@ -202,11 +202,11 @@ imageDisk::imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHard } else { Bit16u equipment=mem_readw(BIOS_CONFIGURATION); if(equipment&1) { - Bitu numofdisks = (equipment>>5)&3; + Bitu numofdisks = (equipment>>6)&3; numofdisks++; if(numofdisks > 1) numofdisks=1;//max 2 floppies at the moment equipment&=~0x00C0; - equipment|=(numofdisks<<5); + equipment|=(numofdisks<<6); } else equipment|=1; mem_writew(BIOS_CONFIGURATION,equipment); CMOS_SetRegister(0x14, equipment); From c614c13e0edcd9675b990505c03a19dc33743417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 23 Oct 2005 19:47:18 +0000 Subject: [PATCH 2269/4131] fix INT10_GetDACBlock; add gray scale summing (from VGABIOS) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2353 --- src/ints/int10.cpp | 21 +++++++++++++++------ src/ints/int10.h | 2 +- src/ints/int10_modes.cpp | 6 ++++++ src/ints/int10_pal.cpp | 17 ++++++++++++++++- 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 90ff9fc8..6edfe462 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -176,6 +176,9 @@ static Bitu INT10_Handler(void) { case 0x1A: /* GET VIDEO DAC COLOR PAGE */ INT10_GetDACPage(®_bl,®_bh); break; + case 0x1B: /* PERFORM GRAY-SCALE SUMMING */ + INT10_PerformGrayScaleSumming(reg_bx,reg_cx); + break; default: LOG(LOG_INT10,LOG_ERROR)("Function 10:Unhandled EGA/VGA Palette Function %2X",reg_al); } @@ -274,12 +277,18 @@ graphics_chars: if (machinetype) { diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 480d3d76..ed13342f 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -154,7 +154,7 @@ void INT10_SetDACBlock(Bit16u index,Bit16u count,PhysPt data) { } void INT10_GetDACBlock(Bit16u index,Bit16u count,PhysPt data) { - IO_Write(VGAREG_DAC_WRITE_ADDRESS,(Bit8u)index); + IO_Write(VGAREG_DAC_READ_ADDRESS,(Bit8u)index); for (;count>0;count--) { mem_writeb(data++,IO_Read(VGAREG_DAC_DATA)); mem_writeb(data++,IO_Read(VGAREG_DAC_DATA)); @@ -239,3 +239,18 @@ void INT10_SetColorSelect(Bit8u val) { INT10_SetSinglePaletteRegister( 3, val ); } } + +void INT10_PerformGrayScaleSumming(Bit16u start_reg,Bit16u count) { + if (count>0x100) count=0x100; + for (Bitu ct=0; ct> 8; + Bit8u ic=(i>0x3f) ? 0x3f : ((Bit8u)(i & 0xff)); + INT10_SetSingleDacRegister(start_reg+ct,ic,ic,ic); + } +} From 3bc50d7f6f797b932e56c99f32dda7f172631ff9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 24 Oct 2005 14:43:53 +0000 Subject: [PATCH 2270/4131] Add some reordering optimalisation from ih8regs Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2354 --- src/gui/render.cpp | 73 +++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index fe7da14e..8d9453fa 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.33 2005-10-09 15:50:09 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.34 2005-10-24 14:43:53 qbix79 Exp $ */ #include #include @@ -220,46 +220,45 @@ static void RENDER_EmptyLineHandler(const Bit8u * src) { } bool RENDER_StartUpdate(void) { - if (render.updating) return false; - if (render.frameskip.countrender.frameskip.max) { + if (render.src.bpp==8) Check_Palette(); + render.frameskip.count=0; + Scaler_Line=0; + Scaler_Index=Scaler_Data; + if (GFX_StartUpdate(Scaler_DstWrite,Scaler_DstPitch)) { + RENDER_DrawLine=render.op.line_handler; #if (C_SSHOT) - if (render.shot.take) { - render.shot.take=false; - if (render.shot.buffer) { - free(render.shot.buffer); - } - render.shot.width=render.src.width; - render.shot.height=render.src.height; - render.shot.bpp=render.src.bpp; - switch (render.shot.bpp) { - case 8:render.shot.rowlen=render.shot.width;break; - case 15: - case 16:render.shot.rowlen=render.shot.width*2;break; - case 32:render.shot.rowlen=render.shot.width*4;break; - } - render.shot.buffer=(Bit8u*)malloc(render.shot.rowlen*render.shot.height); - render.shot.draw=render.shot.buffer; - RENDER_DrawLine=RENDER_ShotDraw; - render.shot.taking=true; - } + if (GCC_UNLIKELY(render.shot.take)) { + render.shot.take=false; + if (render.shot.buffer) free(render.shot.buffer); + render.shot.width=render.src.width; + render.shot.height=render.src.height; + render.shot.bpp=render.src.bpp; + switch (render.shot.bpp) { + case 8:render.shot.rowlen=render.shot.width;break; + case 15: + case 16:render.shot.rowlen=render.shot.width*2;break; + case 32:render.shot.rowlen=render.shot.width*4;break; + } + render.shot.buffer=(Bit8u*)malloc(render.shot.rowlen*render.shot.height); + render.shot.draw=render.shot.buffer; + RENDER_DrawLine=RENDER_ShotDraw; + render.shot.taking=true; + } #endif - render.updating=true; - return true; + render.updating=true; + return true; + } + } else render.frameskip.count++; + } + return false; } void RENDER_EndUpdate(void) { - if (!render.updating) return; + if (render.updating) { #if (C_SSHOT) - if (render.shot.taking) { + if (GCC_UNLIKELY(render.shot.taking)) { render.shot.taking=false; TakeScreenShot(render.shot.buffer); free(render.shot.buffer); @@ -268,10 +267,10 @@ void RENDER_EndUpdate(void) { #endif /* If Things are added to please check the define */ GFX_EndUpdate(); RENDER_DrawLine=RENDER_EmptyLineHandler; - render.updating=false; + render.updating=false; + } } - static Bitu MakeAspectTable(Bitu height,double scaley,Bitu miny) { double lines=0; Bitu linesadded=0; From 5e08378445488859bef6dae5f36d2833023782c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 24 Oct 2005 17:27:37 +0000 Subject: [PATCH 2271/4131] add possibility to use scancodes rather than symkeys Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2355 --- src/gui/sdl_mapper.cpp | 149 +++++++++++++++++++++++++++++++++++++---- src/gui/sdlmain.cpp | 4 +- 2 files changed, 140 insertions(+), 13 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 96b6a5db..6c66fb6b 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.15 2005-10-09 15:17:01 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.16 2005-10-24 17:27:37 c2woody Exp $ */ #define OLD_JOYSTICK 1 @@ -209,6 +209,74 @@ protected: }; + +#define MAX_SDLKEYS 323 +#define MAX_SCANCODES 212 + +static bool usescancodes; +Bit8u scancode_map[MAX_SDLKEYS]; + +#define Z SDLK_UNKNOWN + +SDLKey sdlkey_map[MAX_SCANCODES]={SDLK_UNKNOWN,SDLK_ESCAPE, + SDLK_1,SDLK_2,SDLK_3,SDLK_4,SDLK_5,SDLK_6,SDLK_7,SDLK_8,SDLK_9,SDLK_0, + /* 0x0c: */ + SDLK_MINUS,SDLK_EQUALS,SDLK_BACKSPACE,SDLK_TAB, + SDLK_q,SDLK_w,SDLK_e,SDLK_r,SDLK_t,SDLK_y,SDLK_u,SDLK_i,SDLK_o,SDLK_p, + SDLK_LEFTBRACKET,SDLK_RIGHTBRACKET,SDLK_RETURN,SDLK_LCTRL, + SDLK_a,SDLK_s,SDLK_d,SDLK_f,SDLK_g,SDLK_h,SDLK_j,SDLK_k,SDLK_l, + SDLK_SEMICOLON,SDLK_QUOTE,SDLK_BACKQUOTE,SDLK_LSHIFT,SDLK_BACKSLASH, + SDLK_z,SDLK_x,SDLK_c,SDLK_v,SDLK_b,SDLK_n,SDLK_m, + /* 0x33: */ + SDLK_COMMA,SDLK_PERIOD,SDLK_SLASH,SDLK_RSHIFT,SDLK_KP_MULTIPLY, + SDLK_LALT,SDLK_SPACE,SDLK_CAPSLOCK, + SDLK_F1,SDLK_F2,SDLK_F3,SDLK_F4,SDLK_F5,SDLK_F6,SDLK_F7,SDLK_F8,SDLK_F9,SDLK_F10, + /* 0x45: */ + SDLK_NUMLOCK,SDLK_SCROLLOCK, + SDLK_KP7,SDLK_KP8,SDLK_KP9,SDLK_KP_MINUS,SDLK_KP4,SDLK_KP5,SDLK_KP6,SDLK_KP_PLUS, + SDLK_KP1,SDLK_KP2,SDLK_KP3,SDLK_KP0,SDLK_KP_PERIOD, + SDLK_UNKNOWN,SDLK_UNKNOWN, + SDLK_LESS,SDLK_F11,SDLK_F12, + Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z, + Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z, + Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z, + /* 0xb7: */ + Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z + /* 0xd4: ... */ +}; + +#undef Z + + +SDLKey MapSDLCode(Bitu skey) { + if (usescancodes) { + if (skeytype!=SDL_KEYDOWN) return 0; - return CreateKeyBind(event->key.keysym.sym); + return CreateKeyBind((SDLKey)GetKeyCode(event->key.keysym)); }; bool CheckEvent(SDL_Event * event) { if (event->type!=SDL_KEYDOWN && event->type!=SDL_KEYUP) return false; - Bitu key=(Bitu)event->key.keysym.sym; - assert(keykey.keysym); + LOG_MSG("key type %i is %x [%x %x]",event->type,key,event->key.keysym.sym,event->key.keysym.scancode); + assert(Bitu(event->key.keysym.sym)type==SDL_KEYDOWN) ActivateBindList(&lists[key],0x7fff); else DeactivateBindList(&lists[key]); return 0; } CBind * CreateKeyBind(SDLKey _key) { - assert((Bitu)_key(sec); + usescancodes=false; + + if (section->Get_bool("usescancodes")) { + usescancodes=true; + + /* Note: table has to be tested/updated for various OSs */ +#if !defined (WIN32) + sdlkey_map[0x5a]=SDLK_UP; + sdlkey_map[0x60]=SDLK_DOWN; + sdlkey_map[0x5c]=SDLK_LEFT; + sdlkey_map[0x5e]=SDLK_RIGHT; + sdlkey_map[0x59]=SDLK_HOME; + sdlkey_map[0x5f]=SDLK_END; + sdlkey_map[0x5b]=SDLK_PAGEUP; + sdlkey_map[0x61]=SDLK_PAGEDOWN; + sdlkey_map[0x62]=SDLK_INSERT; + sdlkey_map[0x63]=SDLK_DELETE; + sdlkey_map[0x68]=SDLK_KP_DIVIDE; + sdlkey_map[0x64]=SDLK_KP_ENTER; + sdlkey_map[0x65]=SDLK_RCTRL; + sdlkey_map[0x66]=SDLK_PAUSE; + sdlkey_map[0x67]=SDLK_PRINT; + sdlkey_map[0x69]=SDLK_RALT; +#else + sdlkey_map[0xc8]=SDLK_UP; + sdlkey_map[0xd0]=SDLK_DOWN; + sdlkey_map[0xcb]=SDLK_LEFT; + sdlkey_map[0xcd]=SDLK_RIGHT; + sdlkey_map[0xc7]=SDLK_HOME; + sdlkey_map[0xcf]=SDLK_END; + sdlkey_map[0xc9]=SDLK_PAGEUP; + sdlkey_map[0xd1]=SDLK_PAGEDOWN; + sdlkey_map[0xd2]=SDLK_INSERT; + sdlkey_map[0xd3]=SDLK_DELETE; + sdlkey_map[0xb5]=SDLK_KP_DIVIDE; + sdlkey_map[0x9c]=SDLK_KP_ENTER; + sdlkey_map[0x9d]=SDLK_RCTRL; + sdlkey_map[0xc5]=SDLK_PAUSE; + sdlkey_map[0xb7]=SDLK_PRINT; + sdlkey_map[0xb8]=SDLK_RALT; +#endif + + Bitu i; + for (i=0; iGet_string("mapperfile"); MAPPER_AddHandler(&MAPPER_Run,MK_f1,MMOD1,"mapper","Mapper"); } diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 71bf8811..f38d5597 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.88 2005-09-18 19:50:03 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.89 2005-10-24 17:27:37 c2woody Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1095,6 +1095,7 @@ int main(int argc, char* argv[]) { sdl_sec->Add_bool("waitonerror",true); sdl_sec->Add_string("priority","higher,normal"); sdl_sec->Add_string("mapperfile","mapper.txt"); + sdl_sec->Add_bool("usescancodes",false); MSG_Add("SDL_CONFIGFILE_HELP", "fullscreen -- Start dosbox directly in fullscreen.\n" @@ -1116,6 +1117,7 @@ int main(int argc, char* argv[]) { "priority -- Priority levels for dosbox: lower,normal,higher,highest.\n" " Second entry behind the comma is for when dosbox is not focused/minimized.\n" "mapperfile -- File used to load/save the key/event mappings from.\n" + "usescancodes -- Avoid usage of symkeys, might not work on all operating systems.\n" ); /* Init all the dosbox subsystems */ DOSBOX_Init(); From 3878f069f52ac7a6c25ec7db914d7bf49f84a248 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 24 Oct 2005 17:39:00 +0000 Subject: [PATCH 2272/4131] disabled some log message Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2356 --- src/gui/sdl_mapper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 6c66fb6b..aaf2f413 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.16 2005-10-24 17:27:37 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.17 2005-10-24 17:39:00 qbix79 Exp $ */ #define OLD_JOYSTICK 1 @@ -322,7 +322,7 @@ public: bool CheckEvent(SDL_Event * event) { if (event->type!=SDL_KEYDOWN && event->type!=SDL_KEYUP) return false; Bitu key=GetKeyCode(event->key.keysym); - LOG_MSG("key type %i is %x [%x %x]",event->type,key,event->key.keysym.sym,event->key.keysym.scancode); +// LOG_MSG("key type %i is %x [%x %x]",event->type,key,event->key.keysym.sym,event->key.keysym.scancode); assert(Bitu(event->key.keysym.sym)type==SDL_KEYDOWN) ActivateBindList(&lists[key],0x7fff); else DeactivateBindList(&lists[key]); From 45b73c8174501ecfa6ce7bc3bba4f1c47bc5e768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 24 Oct 2005 19:20:05 +0000 Subject: [PATCH 2273/4131] improve enhanced keys handling of int16 handler; contains modified patch #1317559 from virtualdub Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2357 --- src/ints/bios_keyboard.cpp | 203 ++++++++++++++++++++++++++----------- 1 file changed, 143 insertions(+), 60 deletions(-) diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 5bba52ee..2928ded1 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -37,7 +37,7 @@ static struct { Bit16u alt; } scan_to_scanascii[MAX_SCAN_CODE + 1] = { { none, none, none, none }, - { 0x011b, 0x011b, 0x011b, 0x0100 }, /* escape */ + { 0x011b, 0x011b, 0x011b, 0x01f0 }, /* escape */ { 0x0231, 0x0221, none, 0x7800 }, /* 1! */ { 0x0332, 0x0340, 0x0300, 0x7900 }, /* 2@ */ { 0x0433, 0x0423, none, 0x7a00 }, /* 3# */ @@ -50,8 +50,8 @@ static struct { { 0x0b30, 0x0b29, none, 0x8100 }, /* 0) */ { 0x0c2d, 0x0c5f, 0x0c1f, 0x8200 }, /* -_ */ { 0x0d3d, 0x0d2b, none, 0x8300 }, /* =+ */ - { 0x0e08, 0x0e08, 0x0e7f, none }, /* backspace */ - { 0x0f09, 0x0f00, none, none }, /* tab */ + { 0x0e08, 0x0e08, 0x0e7f, 0x0ef0 }, /* backspace */ + { 0x0f09, 0x0f00, 0x9400, none }, /* tab */ { 0x1071, 0x1051, 0x1011, 0x1000 }, /* Q */ { 0x1177, 0x1157, 0x1117, 0x1100 }, /* W */ { 0x1265, 0x1245, 0x1205, 0x1200 }, /* E */ @@ -62,8 +62,8 @@ static struct { { 0x1769, 0x1749, 0x1709, 0x1700 }, /* I */ { 0x186f, 0x184f, 0x180f, 0x1800 }, /* O */ { 0x1970, 0x1950, 0x1910, 0x1900 }, /* P */ - { 0x1a5b, 0x1a7b, 0x1a1b, none }, /* [{ */ - { 0x1b5d, 0x1b7d, 0x1b1d, none }, /* ]} */ + { 0x1a5b, 0x1a7b, 0x1a1b, 0x1af0 }, /* [{ */ + { 0x1b5d, 0x1b7d, 0x1b1d, 0x1bf0 }, /* ]} */ { 0x1c0d, 0x1c0d, 0x1c0a, none }, /* Enter */ { none, none, none, none }, /* L Ctrl */ { 0x1e61, 0x1e41, 0x1e01, 0x1e00 }, /* A */ @@ -75,11 +75,11 @@ static struct { { 0x246a, 0x244a, 0x240a, 0x2400 }, /* J */ { 0x256b, 0x254b, 0x250b, 0x2500 }, /* K */ { 0x266c, 0x264c, 0x260c, 0x2600 }, /* L */ - { 0x273b, 0x273a, none, none }, /* ;: */ - { 0x2827, 0x2822, none, none }, /* '" */ - { 0x2960, 0x297e, none, none }, /* `~ */ + { 0x273b, 0x273a, none, 0x27f0 }, /* ;: */ + { 0x2827, 0x2822, none, 0x28f0 }, /* '" */ + { 0x2960, 0x297e, none, 0x29f0 }, /* `~ */ { none, none, none, none }, /* L shift */ - { 0x2b5c, 0x2b7c, 0x2b1c, none }, /* |\ */ + { 0x2b5c, 0x2b7c, 0x2b1c, 0x2bf0 }, /* |\ */ { 0x2c7a, 0x2c5a, 0x2c1a, 0x2c00 }, /* Z */ { 0x2d78, 0x2d58, 0x2d18, 0x2d00 }, /* X */ { 0x2e63, 0x2e43, 0x2e03, 0x2e00 }, /* C */ @@ -87,11 +87,11 @@ static struct { { 0x3062, 0x3042, 0x3002, 0x3000 }, /* B */ { 0x316e, 0x314e, 0x310e, 0x3100 }, /* N */ { 0x326d, 0x324d, 0x320d, 0x3200 }, /* M */ - { 0x332c, 0x333c, none, none }, /* ,< */ - { 0x342e, 0x343e, none, none }, /* .> */ - { 0x352f, 0x353f, none, none }, /* /? */ + { 0x332c, 0x333c, none, 0x33f0 }, /* ,< */ + { 0x342e, 0x343e, none, 0x34f0 }, /* .> */ + { 0x352f, 0x353f, none, 0x35f0 }, /* /? */ { none, none, none, none }, /* R Shift */ - { 0x372a, 0x372a, none, none }, /* * */ + { 0x372a, 0x372a, 0x9600, 0x37f0 }, /* * */ { none, none, none, none }, /* L Alt */ { 0x3920, 0x3920, 0x3920, 0x3920 }, /* space */ { none, none, none, none }, /* caps lock */ @@ -108,18 +108,18 @@ static struct { { none, none, none, none }, /* Num Lock */ { none, none, none, none }, /* Scroll Lock */ { 0x4700, 0x4737, 0x7700, 0x0007 }, /* 7 Home */ - { 0x4800, 0x4838, none, 0x0008 }, /* 8 UP */ + { 0x4800, 0x4838, 0x8d00, 0x0008 }, /* 8 UP */ { 0x4900, 0x4939, 0x8400, 0x0009 }, /* 9 PgUp */ - { 0x4a2d, 0x4a2d, none, none }, /* - */ + { 0x4a2d, 0x4a2d, 0x8e00, 0x4af0 }, /* - */ { 0x4b00, 0x4b34, 0x7300, 0x0004 }, /* 4 Left */ - { 0x4cf0, 0x4c35, none, 0x0005 }, /* 5 */ + { 0x4cf0, 0x4c35, 0x8f00, 0x0005 }, /* 5 */ { 0x4d00, 0x4d36, 0x7400, 0x0006 }, /* 6 Right */ - { 0x4e2b, 0x4e2b, none, none }, /* + */ + { 0x4e2b, 0x4e2b, 0x9000, 0x4ef0 }, /* + */ { 0x4f00, 0x4f31, 0x7500, 0x0001 }, /* 1 End */ - { 0x5000, 0x5032, none, 0x0002 }, /* 2 Down */ + { 0x5000, 0x5032, 0x9100, 0x0002 }, /* 2 Down */ { 0x5100, 0x5133, 0x7600, 0x0003 }, /* 3 PgDn */ - { 0x5200, 0x5230, none, 0x0000 }, /* 0 Ins */ - { 0x5300, 0x532e, none, none }, /* Del */ + { 0x5200, 0x5230, 0x9200, 0x0000 }, /* 0 Ins */ + { 0x5300, 0x532e, 0x9300, none }, /* Del */ { none, none, none, none }, { none, none, none, none }, { 0x565c, 0x567c, none, none }, /* (102-key) */ @@ -127,8 +127,8 @@ static struct { { 0x8600, 0x8800, 0x8a00, 0x8c00 } /* F12 */ }; -static void add_key(Bit16u code) { - if (mem_readb(BIOS_KEYBOARD_FLAGS2)&8) return; +static bool add_key_forced(Bit16u code) { + if (mem_readb(BIOS_KEYBOARD_FLAGS2)&8) return true; Bit16u start,end,head,tail,ttail; start=mem_readw(BIOS_KEYBOARD_BUFFER_START); end =mem_readw(BIOS_KEYBOARD_BUFFER_END); @@ -140,31 +140,38 @@ static void add_key(Bit16u code) { } /* Check for buffer Full */ //TODO Maybe beeeeeeep or something although that should happend when internal buffer is full - if (ttail==head) return; + if (ttail==head) return false; real_writew(0x40,tail,code); mem_writew(BIOS_KEYBOARD_BUFFER_TAIL,ttail); + return true; } -static Bit16u get_key(void) { +static void add_key(Bit16u code) { + if (code!=0) add_key_forced(code); +} + +static bool get_key(Bit16u &code) { Bit16u start,end,head,tail,thead; start=mem_readw(BIOS_KEYBOARD_BUFFER_START); end =mem_readw(BIOS_KEYBOARD_BUFFER_END); head =mem_readw(BIOS_KEYBOARD_BUFFER_HEAD); tail =mem_readw(BIOS_KEYBOARD_BUFFER_TAIL); - if (head==tail) return 0; + if (head==tail) return false; thead=head+2; if (thead>=end) thead=start; mem_writew(BIOS_KEYBOARD_BUFFER_HEAD,thead); - return real_readw(0x40,head); + code = real_readw(0x40,head); + return true; } -static Bit16u check_key(void) { +static bool check_key(Bit16u &code) { Bit16u head,tail; head =mem_readw(BIOS_KEYBOARD_BUFFER_HEAD); tail =mem_readw(BIOS_KEYBOARD_BUFFER_TAIL); - if (head==tail) return 0; - return real_readw(0x40,head); + if (head==tail) return false; + code = real_readw(0x40,head); + return true; } /* Flag Byte 1 @@ -246,7 +253,7 @@ static Bitu IRQ1_Handler(void) { flags1 |=0x04; if (flags3 &0x02) flags3 |=0x04; else flags2 |=0x01; - } + } /* else it's part of the pause scancodes */ break; case 0x9d: /* Ctrl Released */ if (!(flags3 &0x01)) { @@ -290,9 +297,16 @@ static Bitu IRQ1_Handler(void) { case 0xba:flags1 &=~0x40;leds &=~0x04;break; case 0x45: if (flags3 &0x01) { + /* last scancode of pause received; first remove 0xe1-prefix */ flags3 &=~0x01; mem_writeb(BIOS_KEYBOARD_FLAGS3,flags3); - if ((flags2&8)==0) { + if (flags2&1) { + /* ctrl-pause (break), special handling needed: + add zero to the keyboard buffer, call int 0x1b which + sets ctrl-c flag which calls int 0x23 in certain dos + input/output functions; not handled */ + } else if ((flags2&8)==0) { + /* normal pause key, enter loop */ mem_writeb(BIOS_KEYBOARD_FLAGS2,flags2|8); IO_Write(0x20,0x20); while (mem_readb(BIOS_KEYBOARD_FLAGS2)&8) CALLBACK_Idle(); // pause loop @@ -300,15 +314,18 @@ static Bitu IRQ1_Handler(void) { return CBRET_NONE; } } else { + /* Num Lock */ flags2 |=0x20; flags1 |=0x20; leds |=0x02; } - break; /* Num Lock */ + break; case 0xc5: if (flags3 &0x01) { + /* pause released */ flags3 &=~0x01; } else { + /* Num Lock released */ flags1 &=~0x20; leds &=~0x02; } @@ -350,10 +367,10 @@ static Bitu IRQ1_Handler(void) { Bit8u token = mem_readb(BIOS_KEYBOARD_TOKEN); token= token*10 + scan_to_scanascii[scancode].alt; mem_writeb(BIOS_KEYBOARD_TOKEN,token); - } else if( ((flags1 &0x3) != 0) ^ ((flags1 &0x20) != 0) ) { - add_key(scan_to_scanascii[scancode].shift); } else if (flags1 &0x04) { add_key(scan_to_scanascii[scancode].control); + } else if( ((flags1 &0x3) != 0) ^ ((flags1 &0x20) != 0) ) { + add_key(scan_to_scanascii[scancode].shift); } else add_key(scan_to_scanascii[scancode].normal); break; @@ -388,6 +405,17 @@ static Bitu IRQ1_Handler(void) { asciiscan=scan_to_scanascii[scancode].shift; } } + if (flags3 &0x02) { + /* extended key (numblock), return and slash need special handling */ + if (scancode==0x1c) { /* return */ + if (flags1 &0x08) asciiscan=0xa600; + else asciiscan=(asciiscan&0xff)|0xe000; + } else if (scancode==0x35) { /* slash */ + if (flags1 &0x08) asciiscan=0xa400; + else if (flags1 &0x04) asciiscan=0x9500; + else asciiscan=0xe02f; + } + } add_key(asciiscan); break; }; @@ -410,35 +438,91 @@ irq1_return: return CBRET_NONE; } -static Bitu INT16_Handler(void) { - Bit16u temp; - bool extended = false; //accept extended keycodes (call 0x10 0x11) - switch (reg_ah) { - case 0x10: /* GET KEYSTROKE (extended) */ - extended = true; /* Fallthrough */ - case 0x00: /* GET KEYSTROKE */ - //Officially: the non extended version should skip all extended keys. - //For improved compatibility: clear the extended part (0xe0) - { - do { - //TODO find a more elegant way to do this - temp=get_key(); - if (temp==0) { CALLBACK_Idle();}; - } while (temp==0); - reg_ax=temp; - if(!extended && reg_al==0xe0) reg_al=0; //no extended - break; +/* check whether key combination is enhanced or not, + translate key if necessary */ +static bool IsEnhancedKey(Bit16u &key) { + /* test for special keys (return and slash on numblock) */ + if ((key>>8)==0xe0) { + if (((key&0xff)==0x0a) || ((key&0xff)==0x0d)) { + /* key is return on the numblock */ + key=(key&0xff)|0x1c00; + } else { + /* key is slash on the numblock */ + key=(key&0xff)|0x3500; } - case 0x11: /* CHECK FOR KEYSTROKE (extended) */ - extended = true; /* Fallthrough */ + /* both keys are not considered enhanced keys */ + return false; + } else if (((key>>8)>0x84) || (((key&0xff)==0xf0) && (key>>8))) { + /* key is enhanced key (either scancode part>0x84 or + specially-marked keyboard combination, low part==0xf0) */ + return true; + } + /* convert key if necessary (extended keys) */ + if ((key>>8) && ((key&0xff)==0xe0)) { + key&=0xff00; + } + return false; +} + +static Bitu INT16_Handler(void) { + Bit16u temp=0; + switch (reg_ah) { + case 0x00: /* GET KEYSTROKE */ + for (;;) { + if (get_key(temp)) { + if (!IsEnhancedKey(temp)) { + /* normal key, exit scanning for keys */ + break; + } + } + CALLBACK_Idle(); + } + /* normal key found, return translated key in ax */ + reg_ax=temp; + break; + case 0x10: /* GET KEYSTROKE (enhanced keyboards only) */ + for (;;) { + if (get_key(temp)) { + if (((temp&0xff)==0xf0) && (temp>>8)) { + /* special enhanced key, clear low part before returning key */ + temp&=0xff00; + } + break; + } + CALLBACK_Idle(); + } + reg_ax=temp; + break; case 0x01: /* CHECK FOR KEYSTROKE */ - temp=check_key(); - if (temp==0) { + for (;;) { + if (check_key(temp)) { + if (!IsEnhancedKey(temp)) { + /* normal key, return translated key in ax */ + CALLBACK_SZF(false); + reg_ax=temp; + break; + } else { + /* remove enhanced key from buffer and ignore it */ + get_key(temp); + } + } else { + /* no key available */ + CALLBACK_SZF(true); + break; + } + CALLBACK_Idle(); + } + break; + case 0x11: /* CHECK FOR KEYSTROKE (enhanced keyboards only) */ + if (!check_key(temp)) { CALLBACK_SZF(true); } else { CALLBACK_SZF(false); + if (((temp&0xff)==0xf0) && (temp>>8)) { + /* special enhanced key, clear low part before returning key */ + temp&=0xff00; + } reg_ax=temp; - if(!extended && reg_al==0xe0) reg_al=0; //no extended } break; case 0x02: /* GET SHIFT FlAGS */ @@ -456,9 +540,8 @@ static Bitu INT16_Handler(void) { } break; case 0x05: /* STORE KEYSTROKE IN KEYBOARD BUFFER */ -//TODO make add_key bool :) - add_key(reg_cx); - reg_al=0; + if (add_key_forced(reg_cx)) reg_al=0; + else reg_al=1; break; case 0x12: /* GET EXTENDED SHIFT STATES */ reg_al=mem_readb(BIOS_KEYBOARD_FLAGS1); From eb1cda134da6df7913d935e808ee00bdfccba1e8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 25 Oct 2005 14:02:11 +0000 Subject: [PATCH 2274/4131] Whoooooops :) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2358 --- src/gui/render.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 8d9453fa..e3cd1381 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.34 2005-10-24 14:43:53 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.35 2005-10-25 14:02:11 qbix79 Exp $ */ #include #include @@ -221,7 +221,7 @@ static void RENDER_EmptyLineHandler(const Bit8u * src) { bool RENDER_StartUpdate(void) { if (!render.updating) { - if (render.frameskip.count>render.frameskip.max) { + if (render.frameskip.count>=render.frameskip.max) { if (render.src.bpp==8) Check_Palette(); render.frameskip.count=0; Scaler_Line=0; From 91c5cd496af3341ab937a7adac7f9dcc2348dbad Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 29 Oct 2005 09:32:52 +0000 Subject: [PATCH 2275/4131] fix get display start. Fixes MSF51 in 640x400 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2359 --- src/ints/int10_vesa.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 579bd2e6..6a4388c1 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.17 2005-09-27 11:05:44 c2woody Exp $ */ +/* $Id: int10_vesa.cpp,v 1.18 2005-10-29 09:32:52 qbix79 Exp $ */ #include #include @@ -295,7 +295,7 @@ Bit8u VESA_GetDisplayStart(Bit16u & x,Bit16u & y) { switch (CurMode->type) { case M_LIN8: y=times; - x=rem*4+pan; + x=rem+pan; break; default: return 0x1; From 5783f7ff820b9fd88537715d8898d1bc41e67f42 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 31 Oct 2005 10:21:45 +0000 Subject: [PATCH 2276/4131] Add patch 1335753 from virtualdub. Fixes a lost surface problem in ddraw mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2360 --- src/gui/sdlmain.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index f38d5597..bd7f49d4 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.89 2005-10-24 17:27:37 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.90 2005-10-31 10:21:45 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -630,6 +630,7 @@ void GFX_EndUpdate(void) { break; case DDERR_SURFACELOST: IDirectDrawSurface3_Restore(sdl.blit.surface->hwdata->dd_surface); + IDirectDrawSurface3_Restore(sdl.surface->hwdata->dd_surface); break; default: LOG_MSG("DDRAW:Failed to blit, error %X",ret); From 48ca454da69542d00b6357aeb49766e1eb51123f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 31 Oct 2005 10:24:56 +0000 Subject: [PATCH 2277/4131] Add patch 1340216 from vasyl. Speeds up the new and slower chain4 mode a bit. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2361 --- src/hardware/vga_draw.cpp | 30 ++++++++++++++++-------------- src/hardware/vga_memory.cpp | 5 +++++ 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index b0ff8370..f826839e 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -27,8 +27,10 @@ #define VGA_PARTS 4 typedef Bit8u * (* VGA_Line_Handler)(Bitu vidstart,Bitu panning,Bitu line); +typedef void (* VGA_FrameStart_Handler)(); static VGA_Line_Handler VGA_DrawLine; +static VGA_FrameStart_Handler VGA_FrameStart; static Bit8u TempLine[1280]; static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { @@ -132,19 +134,14 @@ static Bit8u * VGA_Draw_VGA_Line(Bitu vidstart,Bitu panning,Bitu line) { } static Bit8u * VGA_Draw_VGAChained_Line(Bitu vidstart,Bitu panning,Bitu line) { - if(vga.config.compatible_chain4) { - if(vga.crtc.underline_location & 0x40) { - Bitu readindex = vidstart*4+panning; - Bit32u* draw = (Bit32u*)TempLine; - for(Bitu x=0;x Date: Mon, 31 Oct 2005 18:12:56 +0000 Subject: [PATCH 2278/4131] add stdin-flush to int21/ah=0c (fixes President is Missing keyboard lockup) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2362 --- src/dos/dos.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index b47c95dc..70c3a7c6 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.87 2005-09-28 19:13:21 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.88 2005-10-31 18:12:56 c2woody Exp $ */ #include #include @@ -144,6 +144,13 @@ static Bitu DOS_21Handler(void) { case 0x0c: /* Flush Buffer and read STDIN call */ { switch (reg_al) { + case 0x0: + /* flush STDIN-buffer */ + Bit8u c;Bit16u n; + while (DOS_GetSTDINStatus()) { + n=1; DOS_ReadFile(STDIN,&c,&n); + } + break; case 0x1: case 0x6: case 0x7: From 4a6719a72550b8bc32f9b705a295cc83053cef15 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 1 Nov 2005 11:09:14 +0000 Subject: [PATCH 2279/4131] some vs2005 fixes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2363 --- src/dos/cdrom_image.cpp | 4 ++-- src/gui/sdlmain.cpp | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 36f1e73c..bdd830db 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.9 2005-07-19 19:45:16 qbix79 Exp $ */ +/* $Id: cdrom_image.cpp,v 1.10 2005-11-01 11:09:14 qbix79 Exp $ */ #include #include @@ -391,7 +391,7 @@ bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mod } #if defined(WIN32) -static string dirname(const char * file) { +static string dirname(char * file) { char * sep = strrchr(file, '\\'); if (sep == NULL) sep = strrchr(file, '/'); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index bd7f49d4..ca0120c3 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.90 2005-10-31 10:21:45 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.91 2005-11-01 11:09:14 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -95,7 +95,7 @@ extern char** environ; #define WIN32_LEAN_AND_MEAN #endif #include -#if defined(HAVE_DDRAW_H) +#if (HAVE_DDRAW_H) #include struct private_hwdata { LPDIRECTDRAWSURFACE3 dd_surface; @@ -168,7 +168,7 @@ struct SDL_Block { #endif } opengl; #endif -#if defined(HAVE_DDRAW_H) && defined(WIN32) +#if (HAVE_DDRAW_H) && defined(WIN32) struct { SDL_Surface * surface; RECT rect; @@ -387,7 +387,7 @@ dosurface: break; } break; -#if defined(HAVE_DDRAW_H) && defined(WIN32) +#if (HAVE_DDRAW_H) && defined(WIN32) case SCREEN_SURFACE_DDRAW: if (flags & CAN_16) bpp=16; if (flags & CAN_32) bpp=32; @@ -579,7 +579,7 @@ bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) { pixels+=sdl.clip.x*sdl.surface->format->BytesPerPixel; pitch=sdl.surface->pitch; return true; -#if defined(HAVE_DDRAW_H) && defined(WIN32) +#if (HAVE_DDRAW_H) && defined(WIN32) case SCREEN_SURFACE_DDRAW: if (SDL_LockSurface(sdl.blit.surface)) { // LOG_MSG("SDL Lock failed"); @@ -616,7 +616,7 @@ void GFX_EndUpdate(void) { } SDL_Flip(sdl.surface); break; -#if defined(HAVE_DDRAW_H) && defined(WIN32) +#if (HAVE_DDRAW_H) && defined(WIN32) case SCREEN_SURFACE_DDRAW: if (SDL_MUSTLOCK(sdl.blit.surface)) { SDL_UnlockSurface(sdl.blit.surface); @@ -847,7 +847,7 @@ static void GUI_StartUp(Section * sec) { const char * output=section->Get_string("output"); if (!strcasecmp(output,"surface")) { sdl.desktop.want_type=SCREEN_SURFACE; -#if defined(HAVE_DDRAW_H) && defined(WIN32) +#if (HAVE_DDRAW_H) && defined(WIN32) } else if (!strcasecmp(output,"ddraw")) { sdl.desktop.want_type=SCREEN_SURFACE_DDRAW; #endif @@ -1107,7 +1107,7 @@ int main(int argc, char* argv[]) { #if C_OPENGL ",opengl,openglnb" #endif -#if defined(HAVE_DDRAW_H) && defined(WIN32) +#if (HAVE_DDRAW_H) && defined(WIN32) ",ddraw" #endif ".\n" From 300514b10e506196f06f7435ea703aebb4f942e9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 1 Nov 2005 15:53:39 +0000 Subject: [PATCH 2280/4131] and the last one Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2364 --- src/gui/sdlmain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index ca0120c3..899a930d 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.91 2005-11-01 11:09:14 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.92 2005-11-01 15:53:39 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -265,7 +265,7 @@ check_gotbpp: } /* Not a valid display depth found? Let's just hope sdl provides conversions */ break; -#if defined(HAVE_DDRAW_H) && defined(WIN32) +#if (HAVE_DDRAW_H) && defined(WIN32) case SCREEN_SURFACE_DDRAW: if (!(flags&CAN_32|CAN_16)) goto check_surface; if (flags & LOVE_16) testbpp=16; From 38c75c55a8aba22f26db35b113fb788a08cb1871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 1 Nov 2005 21:05:14 +0000 Subject: [PATCH 2281/4131] fix cga palette selection when B/W bit set Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2365 --- src/hardware/vga_other.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 5ae48a0d..904e34a0 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -198,8 +198,10 @@ static void write_color_select(Bit8u val) { Bit8u base=(val & 0x10) ? 0x08 : 0; /* Check for BW Mode */ if (vga.tandy.mode_control & 0x4) { + VGA_SetCGA4Table(val & 0xf,3+base,4+base,7+base); + /* old code: if (val & 0x20) VGA_SetCGA4Table(val & 0xf,3+base,4+base,7+base); - else VGA_SetCGA4Table(val & 0xf,2+base,4+base,6+base); + else VGA_SetCGA4Table(val & 0xf,2+base,4+base,6+base); */ } else { if (val & 0x20) VGA_SetCGA4Table(val & 0xf,3+base,5+base,7+base); else VGA_SetCGA4Table(val & 0xf,2+base,4+base,6+base); From 8d663041b01165b6204e1a4d39772697fbce930d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 4 Nov 2005 08:53:07 +0000 Subject: [PATCH 2282/4131] Some fixes to the modem and a small effiency update by hal Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2366 --- include/serialport.h | 5 +- .../serialport/directserial_win32.cpp | 5 +- src/hardware/serialport/serialport.cpp | 20 ++++++-- src/hardware/serialport/softmodem.cpp | 50 +++++++------------ src/hardware/serialport/softmodem.h | 3 +- 5 files changed, 41 insertions(+), 42 deletions(-) diff --git a/include/serialport.h b/include/serialport.h index b64b4de6..9a2ce162 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -16,13 +16,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.h,v 1.9 2005-07-30 14:41:30 qbix79 Exp $ */ +/* $Id: serialport.h,v 1.10 2005-11-04 08:53:06 qbix79 Exp $ */ #ifndef DOSBOX_SERIALPORT_H #define DOSBOX_SERIALPORT_H // Uncomment this for a lot of debug messages: -//#define SERIALPORT_DEBUGMSG +// #define SERIALPORT_DEBUGMSG #ifndef DOSBOX_DOSBOX_H #include "dosbox.h" @@ -48,6 +48,7 @@ public: TIMER_TickHandler TimerHnd; virtual ~CSerial(); + void InstallTimerHandler(TIMER_TickHandler); IO_ReadHandleObject ReadHandler[8]; IO_WriteHandleObject WriteHandler[8]; diff --git a/src/hardware/serialport/directserial_win32.cpp b/src/hardware/serialport/directserial_win32.cpp index 8bf84e9b..5def0603 100644 --- a/src/hardware/serialport/directserial_win32.cpp +++ b/src/hardware/serialport/directserial_win32.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_win32.cpp,v 1.1 2005-07-30 14:41:31 qbix79 Exp $ */ +/* $Id: directserial_win32.cpp,v 1.2 2005-11-04 08:53:07 qbix79 Exp $ */ #include "dosbox.h" @@ -41,6 +41,7 @@ CDirectSerial::CDirectSerial (IO_ReadHandler * rh, IO_WriteHandler * wh, :CSerial (rh, wh, th,baseAddr,initIrq, initBps, bytesize, parity,stopbits) { InstallationSuccessful = false; + InstallTimerHandler(th); lastChance = 0; LOG_MSG ("Serial port at %x: Opening %s", base, realPort); hCom = CreateFile (realPort, GENERIC_READ | GENERIC_WRITE, 0, // must be opened with exclusive-access @@ -221,7 +222,7 @@ void CDirectSerial::updateMSR () { if (!GetCommModemStatus (hCom, &dptr)) { #ifdef SERIALPORT_DEBUGMSG - LOG_MSG ("Serial port at %x: GetCommModemStatus failed!", base); +// LOG_MSG ("Serial port at %x: GetCommModemStatus failed!", base); #endif //return; } diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index c67d87cf..d57f6d4f 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.cpp,v 1.1 2005-07-30 14:41:31 qbix79 Exp $ */ +/* $Id: serialport.cpp,v 1.2 2005-11-04 08:53:07 qbix79 Exp $ */ #include #include @@ -802,13 +802,14 @@ void CSerial::Init_Registers (Bit32u initbps, Bit8u bytesize, Write_LCR (lcrresult); } -CSerial::CSerial(IO_ReadHandler * rh, IO_WriteHandler * wh, TIMER_TickHandler th, +CSerial::CSerial(IO_ReadHandler * rh, IO_WriteHandler * wh, TIMER_TickHandler, Bit16u initbase, Bit8u initirq, Bit32u initbps, Bit8u bytesize, const char *parity, Bit8u stopbits) { base = initbase; irq = initirq; - TimerHnd = th; // for destructor - TIMER_AddTickHandler(TimerHnd); + TimerHnd = NULL; + //TimerHnd = th; // for destructor + //TIMER_AddTickHandler(TimerHnd); for (Bitu i = 0; i <= 7; i++) { WriteHandler[i].Install (i + base, wh, IO_MB); @@ -817,9 +818,18 @@ CSerial::CSerial(IO_ReadHandler * rh, IO_WriteHandler * wh, TIMER_TickHandler th }; CSerial::~CSerial(void) { - TIMER_DelTickHandler(TimerHnd); + + if(TimerHnd) TIMER_DelTickHandler(TimerHnd); }; +void CSerial::InstallTimerHandler(TIMER_TickHandler th) +{ + if(TimerHnd==NULL) { + TimerHnd=th; + TIMER_AddTickHandler(th); + } +} + bool getParameter(char *input, char *buffer, const char *parametername, Bitu buffersize) { Bitu outputPos = 0; diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index 7b9ca4b5..f7f66ae1 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.cpp,v 1.1 2005-07-30 14:41:31 qbix79 Exp $ */ +/* $Id: softmodem.cpp,v 1.2 2005-11-04 08:53:07 qbix79 Exp $ */ #include "dosbox.h" @@ -52,6 +52,7 @@ CSerialModem::CSerialModem( baseAddr, initIrq, initBps, bytesize, parity, stopbits) { socket=0; incomingsocket=0; + InstallTimerHandler(th); if(!SDLNetInited) { if(SDLNet_Init()==-1) { @@ -145,7 +146,7 @@ void CSerialModem::SendNumber(Bitu val) { } void CSerialModem::SendRes(ResTypes response) { - char * string;Bitu /*char **/ code; + char * string;Bitu code; switch (response) { case ResNONE: return; @@ -160,19 +161,9 @@ void CSerialModem::SendRes(ResTypes response) { if(doresponse!=1) { if(doresponse==2 && (response==ResRING || response == ResCONNECT || response==ResNOCARRIER)) return; - if(numericresponse) - //{ - SendNumber(code); - // rqueue->addb(*code+'0'); - // rqueue->addb(0xd);rqueue->addb(0xa); - //} - else - //{ - SendLine(string); - //rqueue->addb(0xd);rqueue->addb(0xa); - //rqueue->adds((Bit8u *)string,strlen(string)); - //rqueue->addb(0xd);rqueue->addb(0xa); - //} + if(numericresponse) SendNumber(code); + else SendLine(string); + //if(CSerial::CanReceiveByte()) // very fast response // if(rqueue->inuse() && CSerial::getRTS()) // { Bit8u rbyte =rqueue->getb(); @@ -191,21 +182,9 @@ void CSerialModem::openConnection(void) { SDLNet_TCP_Close(socket); } socket = SDLNet_TCP_Open(&openip); - //if (!socket) - } bool CSerialModem::Dial(char * host) { - char* helper; - // scan for and remove spaces; weird bug: with leading spaces in the string, - // SDLNet_ResolveHost will return no error but not work anyway (win) - while(host[0]==' ') host++; - helper=host; - helper+=strlen(host); - while(helper[0]==' ') { - helper[0]=0; - helper--; - } /* Scan host for port */ Bit16u port; @@ -257,7 +236,6 @@ void CSerialModem::Reset(){ plusinc = 0; incomingsocket = 0; - //answermode = false; // no autoanswer memset(®,0,sizeof(reg)); reg[MREG_AUTOANSWER_COUNT]=0; // no autoanswer reg[MREG_RING_COUNT] = 1; @@ -326,8 +304,7 @@ void CSerialModem::DoCommand() { /* Check for empty line, stops dialing and autoanswer */ if (!cmdbuf[0]) { reg[0]=0; // autoanswer off - //answermode = false; - return;//goto ret_none; + return; // } //else { //MIXER_Enable(mhd.chan,false); @@ -363,6 +340,17 @@ void CSerialModem::DoCommand() { SendRes(ResERROR);//goto ret_error; return; } + char* helper; + // scan for and remove spaces; weird bug: with leading spaces in the string, + // SDLNet_ResolveHost will return no error but not work anyway (win) + while(foundstr[0]==' ') foundstr++; + helper=foundstr; + helper+=strlen(foundstr); + while(helper[0]==' ') { + helper[0]=0; + helper--; + } + if (strlen(foundstr) >= 12) { // Check if supplied parameter only consists of digits bool isNum = true; @@ -388,7 +376,7 @@ void CSerialModem::DoCommand() { } } Dial(foundstr); - return;//goto ret_none; + return; } char * scanbuf; scanbuf=&cmdbuf[2]; diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index ab0ad83c..5aa4faad 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.h,v 1.2 2005-07-31 12:08:58 qbix79 Exp $ */ +/* $Id: softmodem.h,v 1.3 2005-11-04 08:53:07 qbix79 Exp $ */ #ifndef DOSBOX_SERIALMODEM_H #define DOSBOX_SERIALMODEM_H @@ -187,7 +187,6 @@ public: protected: char cmdbuf[255]; bool commandmode; // true: interpret input as commands - //bool answermode; bool echo; // local echo on or off bool oldDTRstate; From 2233eb66625580d03ea124240a9cd943f8bb5766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 4 Nov 2005 21:22:06 +0000 Subject: [PATCH 2283/4131] correct trap-flag handling in rep_movs instructions (fixes J-Bird booter); handle reading of zero sectors through int13 correctly (fixes Metropolis booter) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2367 --- src/cpu/core_normal/string.h | 1 + src/ints/bios_disk.cpp | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_normal/string.h b/src/cpu/core_normal/string.h index 33ce3d58..a2639eb4 100644 --- a/src/cpu/core_normal/string.h +++ b/src/cpu/core_normal/string.h @@ -34,6 +34,7 @@ static void DoString(STRING_OP type) { CPU_Cycles=0; LOADIP; //RESET IP to the start } else { + if ((count<=1) && (CPU_Cycles<=1)) CPU_Cycles--; /* Won't interrupt scas and cmps instruction since they can interrupt themselves */ count_left=0; } diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 6608ad6b..8c2feb91 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.23 2005-10-22 10:28:57 c2woody Exp $ */ +/* $Id: bios_disk.cpp,v 1.24 2005-11-04 21:22:06 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" @@ -318,6 +318,11 @@ static Bitu INT13_DiskHandler(void) { } break; case 0x2: /* Read sectors */ + if (reg_al==0) { + reg_ah = 0x01; + CALLBACK_SCF(true); + return CBRET_NONE; + } if(driveInactive(drivenum)) { reg_ah = 0xff; CALLBACK_SCF(true); @@ -368,6 +373,11 @@ static Bitu INT13_DiskHandler(void) { CALLBACK_SCF(false); break; case 0x04: /* Verify sectors */ + if (reg_al==0) { + reg_ah = 0x01; + CALLBACK_SCF(true); + return CBRET_NONE; + } if(driveInactive(drivenum)) return CBRET_NONE; /* TODO: Finish coding this section */ From 3063cdda9949cb8f4bc0a85e975427899011ac2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 6 Nov 2005 15:26:06 +0000 Subject: [PATCH 2284/4131] add TandyDAC support (fixes Space Quest 3 hangup in tandy mode) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2368 --- src/ints/bios.cpp | 304 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 267 insertions(+), 37 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 28dddbd5..fb649d37 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.47 2005-10-22 10:28:57 c2woody Exp $ */ +/* $Id: bios.cpp,v 1.48 2005-11-06 15:26:06 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -62,6 +62,212 @@ static Bitu INT70_Handler(void) { return 0; } +CALLBACK_HandlerObject* tandy_DAC_callback; +static struct { + Bit16u port; + Bit8u irq; + Bit8u dma; +} tandy_sb; + +static bool Tandy_ProbeSBPort(Bit16u sbport) { + IO_Write(sbport+0x6,1); + IO_Write(sbport+0x6,0); + while (!(IO_Read(sbport+0xe)&0x80)) ; + if (IO_Read(sbport+0xa)==0xaa) return true; + else return false; +} + +static bool Tandy_InitializeSB() { + /* see if soundblaster module available and at what port */ + if (Tandy_ProbeSBPort(0x220)) tandy_sb.port=0x220; + else if (Tandy_ProbeSBPort(0x230)) tandy_sb.port=0x230; + else if (Tandy_ProbeSBPort(0x210)) tandy_sb.port=0x210; + else if (Tandy_ProbeSBPort(0x240)) tandy_sb.port=0x240; + else if (Tandy_ProbeSBPort(0x250)) tandy_sb.port=0x250; + else if (Tandy_ProbeSBPort(0x260)) tandy_sb.port=0x260; + else { + /* no soundblaster accessible, disable Tandy DAC */ + tandy_sb.port=0; + return false; + } + + /* try to detect IRQ setting */ + IO_Write(tandy_sb.port+0x4,0x80); + Bit8u rval=IO_Read(tandy_sb.port+0x5); + if (rval && (rval!=0xff)) { + if (rval&1) tandy_sb.irq=0x02; + else if (rval&2) tandy_sb.irq=0x05; + else if (rval&4) tandy_sb.irq=0x07; + else tandy_sb.irq=0x10; + } else tandy_sb.irq=0x07; /* assume irq=7 for older soundblaster settings */ + + /* try to detect DMA setting */ + IO_Write(tandy_sb.port+0x4,0x81); + rval=IO_Read(tandy_sb.port+0x5); + if (rval && (rval!=0xff)) { + if (rval&1) tandy_sb.dma=0x00; + else if (rval&2) tandy_sb.dma=0x01; + else tandy_sb.dma=0x03; + } else tandy_sb.dma=0x01; /* assume dma=1 for older soundblaster settings */ + + return true; +} + +/* check if Tandy DAC is still playing */ +static bool Tandy_TransferInProgress(void) { + if (real_readw(0x40,0xd0)) return true; /* not yet done */ + if (real_readb(0x40,0xd4)) return false; /* still in init-state */ + + IO_Write(0x0c,0x00); + if (IO_ReadW(tandy_sb.dma*2+1)==0xffff) return false; /* no DMA transfer */ + return true; +} + +static void Tandy_SetupTransfer(PhysPt bufpt,bool isplayback) { + Bitu length=real_readw(0x40,0xd0); + if (length==0) return; /* nothing to do... */ + + if (tandy_sb.port==0) return; + + /* revector IRQ-handler if necessary */ + RealPt current_irq=RealGetVec(tandy_sb.irq+8); + if (current_irq!=tandy_DAC_callback->Get_RealPointer()) { + real_writed(0x40,0xd6,current_irq); + real_writed(0x40,0xd6,current_irq); + RealSetVec(tandy_sb.irq+8,tandy_DAC_callback->Get_RealPointer()); + } + + IO_Write(0x21,IO_Read(0x21)&(~(1<>16)&0xff); + IO_Write(tandy_sb.dma*2,(Bit8u)(bufpt&0xff)); + IO_Write(tandy_sb.dma*2,(Bit8u)((bufpt>>8)&0xff)); + switch (tandy_sb.dma) { + case 0: IO_Write(0x87,bufpage); break; + case 1: IO_Write(0x83,bufpage); break; + case 2: IO_Write(0x81,bufpage); break; + case 3: IO_Write(0x82,bufpage); break; + } + real_writeb(0x40,0xd4,bufpage); + /* calculate transfer size (respects segment boundaries) */ + Bit32u tlength=length; + if (tlength+(bufpt&0xffff)>0x10000) tlength=0x10000-(bufpt&0xffff); + /* set transfer size */ + IO_Write(tandy_sb.dma*2+1,(Bit8u)(tlength&0xff)); + IO_Write(tandy_sb.dma*2+1,(Bit8u)((tlength>>8)&0xff)); + IO_Write(0x0a,tandy_sb.dma); /* enable DMA channel */ + + real_writew(0x40,0xd0,(Bit16u)(length-tlength)); /* remaining buffer length */ + + Bitu delay=real_readw(0x40,0xd2)&0xfff; + + /* set frequency */ + IO_Write(tandy_sb.port+0xc,0x40); + IO_Write(tandy_sb.port+0xc,256-delay*100/358); + /* set playback type to 8bit */ + if (isplayback) IO_Write(tandy_sb.port+0xc,0x14); + else IO_Write(tandy_sb.port+0xc,0x24); + /* set transfer size */ + IO_Write(tandy_sb.port+0xc,(Bit8u)(tlength&0xff)); + IO_Write(tandy_sb.port+0xc,(Bit8u)((tlength>>8)&0xff)); + + if (!isplayback) { + /* mark transfer as recording operation */ + real_writew(0x40,0xd2,delay|0x1000); + } +} + +static Bitu IRQ_TandyDAC(void) { + if (real_readw(0x40,0xd0)) { /* play/record next buffer */ + /* acknowledge IRQ */ + IO_Write(0x20,0x20); + IO_Read(tandy_sb.port+0xe); + + /* buffer starts at the next page */ + Bit8u npage=real_readb(0x40,0xd4)+1; + real_writeb(0x40,0xd4,npage); + + Bitu rb=real_readb(0x40,0xd3); + if (rb&0x10) { + /* start recording */ + real_writeb(0x40,0xd3,rb&0xef); + Tandy_SetupTransfer(npage<<16,false); + } else { + /* start playback */ + Tandy_SetupTransfer(npage<<16,true); + } + } else { /* playing/recording is finished */ + RealSetVec(tandy_sb.irq+8,real_readd(0x40,0xd6)); + + /* turn off speaker and acknowledge soundblaster IRQ */ + IO_Write(tandy_sb.port+0xc,0xd3); + IO_Read(tandy_sb.port+0xe); + + /* issue BIOS tandy sound device busy callout */ + Bit16u oldax=reg_ax; + reg_ax=0x91fb; + CALLBACK_RunRealInt(0x15); + reg_ax = oldax; + + IO_Write(0x20,0x20); + } + return CBRET_NONE; +} + +static void TandyDAC_Handler(Bit8u tfunction) { + if (machine!=MCH_TANDY) return; + switch (tfunction) { + case 0x81: /* Tandy sound system check */ + if (tandy_sb.port) { + reg_ax=0xc4; + CALLBACK_SCF(Tandy_TransferInProgress()); + } + break; + case 0x82: /* Tandy sound system start recording */ + case 0x83: /* Tandy sound system start playback */ + if (!tandy_sb.port) { + CALLBACK_SCF(true); + break; + } + if (Tandy_TransferInProgress()) { + /* cannot play yet as the last transfer isn't finished yet */ + reg_ah=0x00; + CALLBACK_SCF(true); + break; + } + /* store buffer length */ + real_writew(0x40,0xd0,reg_cx); + /* store delay and volume */ + real_writew(0x40,0xd2,(reg_dx&0xfff)|((reg_al&7)<<13)); + Tandy_SetupTransfer(PhysMake(SegValue(es),reg_bx),reg_ah==0x83); + reg_ah=0x00; + CALLBACK_SCF(false); + break; + case 0x84: /* Tandy sound system stop playing */ + if (!tandy_sb.port) { + CALLBACK_SCF(true); + break; + } + reg_ah=0x00; + + /* setup for a small buffer with zeros (silence) */ + real_writew(0x40,0xd0,0x0a); + real_writew(0x40,0xd2,0x1c); + Tandy_SetupTransfer(PhysMake(0xf000,0xa084),false); + CALLBACK_SCF(false); + break; + case 0x85: /* Tandy sound system reset */ + reg_ah=0x00; + CALLBACK_SCF(false); + break; + } +} + static Bitu INT1A_Handler(void) { switch (reg_ah) { case 0x00: /* Get System time */ @@ -99,21 +305,13 @@ static Bitu INT1A_Handler(void) { case 0x80: /* Pcjr Setup Sound Multiplexer */ LOG(LOG_BIOS,LOG_ERROR)("INT1A:80:Setup tandy sound multiplexer to %d",reg_al); break; - case 0x81: /* Tandy sound system checks */ - if (machine!=MCH_TANDY) break; - reg_ax=0xc4; - CALLBACK_SCF(false); + case 0x81: /* Tandy sound system check */ + case 0x82: /* Tandy sound system start recording */ + case 0x83: /* Tandy sound system start playback */ + case 0x84: /* Tandy sound system stop playing */ + case 0x85: /* Tandy sound system reset */ + TandyDAC_Handler(reg_ah); break; -/* - INT 1A - Tandy 2500, Tandy 1000L series - DIGITAL SOUND - INSTALLATION CHECK - AX = 8100h - Return: AL > 80h if supported - AX = 00C4h if supported (1000SL/TL) - CF set if sound chip is busy - CF clear if sound chip is free - Note: the value of CF is not definitive; call this function until CF is - clear on return, then call AH=84h"Tandy" - */ case 0xb1: /* PCI Bios Calls */ LOG(LOG_BIOS,LOG_ERROR)("INT1A:PCI bios call %2X",reg_al); CALLBACK_SCF(true); @@ -370,15 +568,23 @@ static Bitu INT15_Handler(void) { { if (biosConfigSeg==0) biosConfigSeg = DOS_GetMemory(1); //We have 16 bytes PhysPt data = PhysMake(biosConfigSeg,0); - mem_writew(data,8); // 3 Bytes following - mem_writeb(data+2,0xFC); // Model ID - mem_writeb(data+3,0x00); // Submodel ID - mem_writeb(data+4,0x01); // Bios Revision - mem_writeb(data+5,(1<<6)|(1<<5)|(1<<4));// Feature Byte 1 + mem_writew(data,8); // 8 Bytes following + if (machine==MCH_TANDY) { + mem_writeb(data+2,0xFF); // Model ID (Tandy) + mem_writeb(data+3,0x0A); // Submodel ID + mem_writeb(data+4,0x10); // Bios Revision + /* Tandy doesn't have a 2nd PIC, left as is for now */ + mem_writeb(data+5,(1<<6)|(1<<5)|(1<<4)); // Feature Byte 1 + } else { + mem_writeb(data+2,0xFC); // Model ID (PC) + mem_writeb(data+3,0x00); // Submodel ID + mem_writeb(data+4,0x01); // Bios Revision + mem_writeb(data+5,(1<<6)|(1<<5)|(1<<4)); // Feature Byte 1 + } mem_writeb(data+6,(1<<6)); // Feature Byte 2 mem_writeb(data+7,0); // Feature Byte 3 mem_writeb(data+8,0); // Feature Byte 4 - mem_writeb(data+9,0); // Feature Byte 4 + mem_writeb(data+9,0); // Feature Byte 5 CPU_SetSegGeneral(es,biosConfigSeg); reg_bx = 0; reg_ah = 0; @@ -582,15 +788,6 @@ static Bitu INT15_Handler(void) { return CBRET_NONE; } -static Bitu INT1_Single_Step(void) { - static bool warned=false; - if (!warned) { - warned=true; - LOG(LOG_CPU,LOG_NORMAL)("INT 1:Single Step called"); - } - return CBRET_NONE; -} - void BIOS_ZeroExtendedSize(bool in) { if(in) other_memsystems++; else other_memsystems--; @@ -602,11 +799,10 @@ void BIOS_SetupDisks(void); class BIOS:public Module_base{ private: - CALLBACK_HandlerObject callback[10]; + CALLBACK_HandlerObject callback[9]; public: BIOS(Section* configuration):Module_base(configuration){ - /* Clear the Bios Data Area */ - /* till where does this bios Area run ? Some dos stuff is at 0x70 */ + /* Clear the Bios Data Area (0x400-0x5ff, 0x600- is accounted to DOS) */ for (Bit16u i=0;i<0x200;i++) real_writeb(0x40,i,0); /* Setup all the interrupt handlers the bios controls */ /* INT 8 Clock IRQ Handler */ @@ -640,6 +836,7 @@ public: /* INT 13 Bios Disk Support */ BIOS_SetupDisks(); + /* INT 14 Serial Ports */ callback[3].Install(&INT14_Handler,CB_IRET,"Int 14 COM-port"); callback[3].Set_RealVec(0x14); @@ -666,10 +863,24 @@ public: callback[8].Install(&INT70_Handler,CB_IRET,"Int 70 RTC"); callback[8].Set_RealVec(0x70); - /* Some defeault CPU error interrupt handlers */ - callback[9].Install(&INT1_Single_Step,CB_IRET,"Int 1 Single step"); - callback[9].Set_RealVec(0x1); - + if (machine==MCH_TANDY) { + phys_writeb(0xffffe,0xfc); /* Tandy model */ + phys_writeb(0xfc000,0x21); /* Tandy bios identificator */ + if (Tandy_InitializeSB()) { + real_writew(0x40,0xd0,0x0000); + real_writew(0x40,0xd2,0x0000); + real_writeb(0x40,0xd4,0xff); /* initial value */ + real_writed(0x40,0xd6,0x00000000); + /* install the DAC callback handler */ + tandy_DAC_callback=new CALLBACK_HandlerObject(); + tandy_DAC_callback->Install(&IRQ_TandyDAC,CB_IRET,"Tandy DAC IRQ"); + RealPt current_irq=RealGetVec(tandy_sb.irq+8); + real_writed(0x40,0xd6,current_irq); + } + } else { + phys_writeb(0xffffe,0xfc); /* PC */ + } + /* Setup some stuff in 0x40 bios segment */ /* detect parallel ports */ Bit8u DEFAULTPORTTIMEOUT = 10; // 10 whatevers @@ -756,6 +967,25 @@ public: IO_Write(0x70,0x31); size_extended|=(IO_Read(0x71) << 8); } + ~BIOS(){ + if (machine==MCH_TANDY) { + /* abort DAC playing */ + if (tandy_sb.port) { + IO_Write(tandy_sb.port+0xc,0xd3); + IO_Write(tandy_sb.port+0xc,0xd0); + } + if (tandy_DAC_callback) { + Bit32u orig_vector=real_readd(0x40,0xd6); + if (orig_vector==tandy_DAC_callback->Get_RealPointer()) { + /* set IRQ vector to old value */ + RealSetVec(tandy_sb.irq+8,real_readd(0x40,0xd6)); + real_writed(0x40,0xd6,0x00000000); + } + delete tandy_DAC_callback; + tandy_DAC_callback=NULL; + } + } + } }; // set com port data in bios data area From 561579365ee363177a7918547f6fface225509e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 6 Nov 2005 19:42:58 +0000 Subject: [PATCH 2285/4131] display exit reason for IllegalOption() Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2369 --- src/cpu/core_dyn_x86.cpp | 4 ++-- src/cpu/core_dyn_x86/decoder.h | 8 ++++---- src/cpu/core_dyn_x86/risc_x86.h | 26 +++++++++++++------------- src/cpu/core_dyn_x86/string.h | 6 +++--- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 3ed19175..07bfa63e 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -147,8 +147,8 @@ static struct { Bitu ea,tmpb,tmpd,stack,shift; } extra_regs; -static void IllegalOption(void) { - E_Exit("Illegal option"); +static void IllegalOption(const char* msg) { + E_Exit("DynCore: illegal option in %s",msg); } #include "core_dyn_x86/cache.h" diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 9733b1e8..c0c53e01 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -832,14 +832,14 @@ static void dyn_load_seg_off_ea(SegNames seg) { dyn_load_seg(seg,DREG(TMPW));gen_releasereg(DREG(TMPW)); dyn_read_word_release(DREG(EA),&DynRegs[decode.modrm.reg],decode.big_op); } else { - IllegalOption(); + IllegalOption("dyn_load_seg_off_ea"); } } static void dyn_mov_seg_ev(void) { dyn_get_modrm(); SegNames seg=(SegNames)decode.modrm.reg; - if (GCC_UNLIKELY(seg==cs)) IllegalOption(); + if (GCC_UNLIKELY(seg==cs)) IllegalOption("dyn_mov_seg_ev"); if (decode.modrm.mod<3) { dyn_fill_ea(); dyn_read_word(DREG(EA),DREG(EA),false); @@ -905,7 +905,7 @@ static void dyn_leave(void) { } static void dyn_segprefix(SegNames seg) { - if (GCC_UNLIKELY((Bitu)(decode.segprefix))) IllegalOption(); + if (GCC_UNLIKELY((Bitu)(decode.segprefix))) IllegalOption("dyn_segprefix"); decode.segprefix=&DynRegs[G_ES+seg]; } @@ -1645,7 +1645,7 @@ restart_prefix: dyn_push(src); break; default: - IllegalOption(); + IllegalOption("opcode 0xff"); }} break; default: diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index f656e547..11430f1b 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -61,7 +61,7 @@ public: dynreg->flags|=DYNFLG_ACTIVE; } void Save(void) { - if (GCC_UNLIKELY(!((Bitu)dynreg))) IllegalOption(); + if (GCC_UNLIKELY(!((Bitu)dynreg))) IllegalOption("GenReg->Save"); dynreg->flags&=~DYNFLG_CHANGED; cache_addw(0x0589+(index << (8+3))); //Mov [data],reg cache_addd((Bit32u)dynreg->data); @@ -283,7 +283,7 @@ static void gen_dop_byte(DualOps op,DynReg * dr1,Bit8u di1,DynReg * dr2,Bit8u di case DOP_MOV: if ((dr1==dr2) && (di1==di2)) return; tmp=0x8a; break; case DOP_XCHG: tmp=0x86; dr2->flags|=DYNFLG_CHANGED; break; default: - IllegalOption(); + IllegalOption("gen_dop_byte"); } dr1->flags|=DYNFLG_CHANGED; nochange: @@ -307,7 +307,7 @@ static void gen_dop_byte_imm(DualOps op,DynReg * dr1,Bit8u di1,Bitu imm) { dr1->flags|=DYNFLG_CHANGED; goto finish; default: - IllegalOption(); + IllegalOption("gen_dop_byte_imm"); } dr1->flags|=DYNFLG_CHANGED; nochange: @@ -325,7 +325,7 @@ static void gen_sop_byte(SingleOps op,DynReg * dr1,Bit8u di1) { case SOP_NOT: tmp=0xd0f6; break; case SOP_NEG: tmp=0xd8f6; break; default: - IllegalOption(); + IllegalOption("gen_sop_byte"); } cache_addw(tmp + ((gr1->index+di1)<<8)); dr1->flags|=DYNFLG_CHANGED; @@ -423,7 +423,7 @@ static void gen_dop_word(DualOps op,bool dword,DynReg * dr1,DynReg * dr2) { tmp=0x87; break; default: - IllegalOption(); + IllegalOption("gen_dop_word"); } dr1->flags|=DYNFLG_CHANGED; nochange: @@ -447,7 +447,7 @@ static void gen_dop_word_imm(DualOps op,bool dword,DynReg * dr1,Bits imm) { case DOP_TEST: tmp=0xc0f7; goto nochange; //Doesn't change case DOP_MOV: cache_addb(0xb8+(gr1->index)); dr1->flags|=DYNFLG_CHANGED; goto finish; default: - IllegalOption(); + IllegalOption("gen_dop_word_imm"); } dr1->flags|=DYNFLG_CHANGED; nochange: @@ -494,7 +494,7 @@ static void gen_sop_word(SingleOps op,bool dword,DynReg * dr1) { case SOP_NOT:cache_addw(0xd0f7+(gr1->index<<8));break; case SOP_NEG:cache_addw(0xd8f7+(gr1->index<<8));break; default: - IllegalOption(); + IllegalOption("gen_sop_word"); } dr1->flags|=DYNFLG_CHANGED; } @@ -654,7 +654,7 @@ static void gen_call_function(void * func,char * ops,...) { release=true; goto scanagain; default: - IllegalOption(); + IllegalOption("gen_call_function param:DREG"); } if (release) gen_releasereg(dynreg); } @@ -664,7 +664,7 @@ static void gen_call_function(void * func,char * ops,...) { pinfo[pindex].line=scan; break; default: - IllegalOption(); + IllegalOption("gen_call_function unknown param"); } } } @@ -725,7 +725,7 @@ static void gen_call_write(DynReg * dr,Bit32u val,Bitu write_size) { case 1: cache_addd((Bit32u)mem_writeb - (Bit32u)cache.pos-4); break; case 2: cache_addd((Bit32u)mem_writew_dyncorex86 - (Bit32u)cache.pos-4); break; case 4: cache_addd((Bit32u)mem_writed_dyncorex86 - (Bit32u)cache.pos-4); break; - default: IllegalOption(); + default: IllegalOption("gen_call_write"); } cache_addw(0xc483); //ADD ESP,8 @@ -777,7 +777,7 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { } static void gen_save_flags(DynReg * dynreg) { - if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption(); + if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_save_flags"); GenReg * genreg=FindDynReg(dynreg); cache_addb(0x8b); //MOV REG,[esp] cache_addw(0x2404+(genreg->index << 3)); @@ -785,7 +785,7 @@ static void gen_save_flags(DynReg * dynreg) { } static void gen_load_flags(DynReg * dynreg) { - if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption(); + if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_load_flags"); cache_addw(0xc483); //ADD ESP,4 cache_addb(0x4); GenReg * genreg=FindDynReg(dynreg); @@ -805,7 +805,7 @@ static void gen_load_host(void * data,DynReg * dr1,Bitu size) { case 2:cache_addw(0xb70f);break; //movzx word case 4:cache_addb(0x8b);break; //mov default: - IllegalOption(); + IllegalOption("gen_load_host"); } cache_addb(0x5+(gr1->index<<3)); cache_addd((Bit32u)data); diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index e59c7077..4c8a710c 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -51,7 +51,7 @@ static void dyn_string(STRING_OP op) { case STR_INSB: case STR_INSW: case STR_INSD: tmp_reg=DREG(TMPB);usesi=false;usedi=true;break; default: - IllegalOption(); + IllegalOption("dyn_string op"); } gen_load_host(&cpu.direction,DREG(TMPW),4); switch (op & 3) { @@ -59,7 +59,7 @@ static void dyn_string(STRING_OP op) { 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(); + IllegalOption("dyn_string shift"); } if (usesi) { @@ -139,7 +139,7 @@ static void dyn_string(STRING_OP op) { dyn_write_word(DREG(EA),tmp_reg,true); break; default: - IllegalOption(); + IllegalOption("dyn_string op"); } } gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB)); From 530d276ce6691e376602b250a15221bc33c12923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 7 Nov 2005 21:08:11 +0000 Subject: [PATCH 2286/4131] better relative placement of SDA (fixes FS4 dos detection) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2370 --- include/dos_inc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 8531692d..6cf48b8c 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.56 2005-09-28 19:13:21 c2woody Exp $ */ +/* $Id: dos_inc.h,v 1.57 2005-11-07 21:08:11 c2woody Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -81,7 +81,7 @@ enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; #define DOS_CDS_SEG 0x90 #define DOS_CONSTRING_SEG 0xa0 #define DOS_CONDRV_SEG 0xa4 -#define DOS_SDA_SEG 0xb0 +#define DOS_SDA_SEG 0xb2 #define DOS_SDA_OFS 0 #define DOS_MEM_START 0x102 //First Segment that DOS can use From b318eb1324b749e8c07a690bc60b053330f45ca1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 8 Nov 2005 19:41:04 +0000 Subject: [PATCH 2287/4131] a few tiny fixes to the logic determining the video graphics. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2371 --- src/gui/sdlmain.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 899a930d..78e22792 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.92 2005-11-01 15:53:39 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.93 2005-11-08 19:41:04 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -267,7 +267,7 @@ check_gotbpp: break; #if (HAVE_DDRAW_H) && defined(WIN32) case SCREEN_SURFACE_DDRAW: - if (!(flags&CAN_32|CAN_16)) goto check_surface; + if (!(flags&(CAN_32|CAN_16))) goto check_surface; if (flags & LOVE_16) testbpp=16; else if (flags & LOVE_32) testbpp=32; else testbpp=0; @@ -277,13 +277,13 @@ check_gotbpp: case SCREEN_OVERLAY: if (flags & NEED_RGB || !(flags&CAN_32)) goto check_surface; flags|=HAVE_SCALING; - flags&=~(CAN_8,CAN_16); + flags&=~(CAN_8|CAN_16); break; #if C_OPENGL case SCREEN_OPENGL: if (flags & NEED_RGB || !(flags&CAN_32)) goto check_surface; flags|=HAVE_SCALING; - flags&=~(CAN_8,CAN_16); + flags&=~(CAN_8|CAN_16); break; #endif } From dc4aaeaed01862f7aa9d02502d50175521e80239 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 10 Nov 2005 13:08:47 +0000 Subject: [PATCH 2288/4131] add patch 1348881 from vasyl. Fixes sb16 detection in some games. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2372 --- src/hardware/sblaster.cpp | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index bc8a1816..a154dfd9 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -126,6 +126,7 @@ struct SB_INFO { bool stereo; bool enabled; bool filtered; + Bit8u unhandled[0x48]; } mixer; struct { Bit8u reference; @@ -195,6 +196,7 @@ static void GenerateDMASound(Bitu size); static void DSP_SetSpeaker(bool how) { if (sb.speaker==how) return; sb.speaker=how; + if (sb.type==SBT_16) return; sb.chan->Enable(how); if (sb.speaker) { PIC_RemoveEvents(DMA_Silent_Event); @@ -494,7 +496,7 @@ static void END_DMA_Event(Bitu val) { static void CheckDMAEnd(void) { if (!sb.dma.left) return; - if (!sb.speaker) { + if (!sb.speaker && sb.type!=SBT_16) { Bitu bigger=(sb.dma.left > sb.dma.min) ? sb.dma.min : sb.dma.left; float delay=(bigger*1000.0f)/sb.dma.rate; PIC_AddEvent(DMA_Silent_Event,delay,bigger); @@ -628,7 +630,7 @@ static void DSP_Reset(void) { sb.irq.pending_8bit=false; sb.irq.pending_16bit=false; sb.chan->SetFreq(22050); - DSP_SetSpeaker(false); +// DSP_SetSpeaker(false); PIC_RemoveEvents(END_DMA_Event); } @@ -729,7 +731,7 @@ static void DSP_DoCommand(void) { case 0xb0: case 0xb2: case 0xb4: case 0xb6: case 0xc0: case 0xc2: case 0xc4: case 0xc6: /* Generic 8/16 bit DMA */ - DSP_SetSpeaker(true); //SB16 always has speaker enabled +// DSP_SetSpeaker(true); //SB16 always has speaker enabled sb.dma.sign=(sb.dsp.in.data[0] & 0x10) > 0; DSP_PrepareDMA_New((sb.dsp.cmd & 0x10) ? DSP_DMA_16 : DSP_DMA_8, 1+sb.dsp.in.data[1]+(sb.dsp.in.data[2] << 8), @@ -750,6 +752,11 @@ static void DSP_DoCommand(void) { case 0xd3: /* Disable Speaker */ DSP_SetSpeaker(false); break; + case 0xd8: /* Speaker status */ + DSP_FlushData(); + if (sb.speaker) DSP_AddData(0xff); + else DSP_AddData(0x00); + break; case 0xd4: /* Continue DMA 8-bit*/ case 0xd6: /* Continue DMA 16-bit */ if (sb.mode==MODE_DMA_PAUSE) { @@ -926,6 +933,10 @@ static void CTMIXER_Write(Bit8u val) { LOG(LOG_SB,LOG_NORMAL)("Mixer select dma8:%x dma16:%x",sb.hw.dma8,sb.hw.dma16); break; default: + if ((sb.type == SBT_2 && sb.mixer.index==0x08) || /* CD volume on SB2 */ + ((sb.type == SBT_PRO1 || sb.type == SBT_PRO2) && sb.mixer.index==0x0c) || /* Input control on SBPro */ + (sb.type == SBT_16 && sb.mixer.index >= 0x30 && sb.mixer.index <= 0x47)) /* New SB16 registers */ + sb.mixer.unhandled[sb.mixer.index] = val; LOG(LOG_SB,LOG_WARN)("MIXER:Write %X to unhandled index %X",val,sb.mixer.index); } } @@ -979,8 +990,13 @@ static Bit8u CTMIXER_Read(void) { return (sb.irq.pending_8bit ? 0x1 : 0) | (sb.irq.pending_16bit ? 0x2 : 0); default: /* IRQ Status */ + if ((sb.type == SBT_2 && sb.mixer.index==0x08) || /* CD volume on SB2 */ + ((sb.type == SBT_PRO1 || sb.type == SBT_PRO2) && sb.mixer.index==0x0c) || /* Input control on SBPro */ + (sb.type == SBT_16 && sb.mixer.index >= 0x30 && sb.mixer.index <= 0x47)) /* New SB16 registers */ + ret = sb.mixer.unhandled[sb.mixer.index]; + else + ret=0xa; LOG(LOG_SB,LOG_WARN)("MIXER:Read from unhandled index %X",sb.mixer.index); - ret=0xa; } return ret; } @@ -1155,6 +1171,13 @@ public: } DSP_Reset(); CTMIXER_Reset(); + // The documentation does not specify if SB gets initialized with the speaker enabled + // or disabled. Real SBPro2 has it disabled. + sb.speaker=false; + // On SB16 the speaker flag does not affect actual speaker state. + if (sb.type == SBT_16) sb.chan->Enable(true); + else sb.chan->Enable(false); + char hdma[8]=""; if (sb.type==SBT_16) { sprintf(hdma,"H%d ",sb.hw.dma16); From 7529d70fbe4ec2f48602c985e4927daceaa2cc12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 10 Nov 2005 18:05:12 +0000 Subject: [PATCH 2289/4131] add support for tandy sound when machine is not set to tandy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2373 --- src/dosbox.cpp | 8 +++- src/hardware/tandy_sound.cpp | 18 +++++++-- src/ints/bios.cpp | 75 ++++++++++++++++-------------------- 3 files changed, 55 insertions(+), 46 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index ae642ba4..8192e805 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.88 2005-10-09 15:50:09 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.89 2005-11-10 18:05:10 c2woody Exp $ */ #include #include @@ -288,6 +288,7 @@ void DOSBOX_Init(void) { #if C_DEBUG secprop=control->AddSection_prop("debug",&DEBUG_Init); #endif + secprop=control->AddSection_prop("sblaster",&SBLASTER_Init,true);//done secprop->Add_string("type","sb16"); secprop->Add_hex("base",0x220); @@ -332,6 +333,7 @@ void DOSBOX_Init(void) { secprop->Add_bool("pcspeaker",true); secprop->Add_int("pcrate",22050); secprop->AddInitFunction(&TANDYSOUND_Init,true);//done + secprop->Add_string("tandy","auto"); secprop->Add_int("tandyrate",22050); secprop->AddInitFunction(&DISNEY_Init,true);//done secprop->Add_bool("disney",true); @@ -339,10 +341,12 @@ void DOSBOX_Init(void) { MSG_Add("SPEAKER_CONFIGFILE_HELP", "pcspeaker -- Enable PC-Speaker emulation.\n" "pcrate -- Sample rate of the PC-Speaker sound generation.\n" + "tandy -- Enable Tandy Sound System emulation (false,true,auto).\n" + " For auto Tandysound emulation is present only if machine is set to tandy.\n" "tandyrate -- Sample rate of the Tandy 3-Voice generation.\n" - " Tandysound emulation is present if machine is set to tandy.\n" "disney -- Enable Disney Sound Source emulation.\n" ); + secprop=control->AddSection_prop("bios",&BIOS_Init,false);//done MSG_Add("BIOS_CONFIGFILE_HELP", "joysticktype -- Type of joystick to emulate: none, 2axis, 4axis,\n" diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 28fa801e..abcdc996 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -312,17 +312,29 @@ private: MixerObject MixerChan; public: TANDYSOUND(Section* configuration):Module_base(configuration){ - if (machine!=MCH_TANDY) return; Section_prop * section=static_cast(configuration); + + real_writeb(0x40,0xd4,0x00); + if (machine==MCH_TANDY) { + /* enable tandy sound if tandy=true/auto */ + if ((strcmp(section->Get_string("tandy"),"true")!=0) && + (strcmp(section->Get_string("tandy"),"auto")!=0)) return; + } else { + /* only enable tandy sound if tandy=true */ + if (strcmp(section->Get_string("tandy"),"true")!=0) return; + } - WriteHandler[0].Install(0xc0,SN76496Write,IO_MB,2); - WriteHandler[1].Install(0xc4,TandyDACWrite,IO_MB,4); + if (machine==MCH_TANDY) { + WriteHandler[0].Install(0xc0,SN76496Write,IO_MB,2); + WriteHandler[1].Install(0xc4,TandyDACWrite,IO_MB,4); + } else WriteHandler[0].Install(0x1e0,SN76496Write,IO_MB,2); Bit32u sample_rate = section->Get_int("tandyrate"); tandy.chan=MixerChan.Install(&SN76496Update,sample_rate,"TANDY"); tandy.enabled=false; + real_writeb(0x40,0xd4,0xff); /* tandy DAC initialization value */ Bitu i; struct SN76496 *R = &sn; diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index fb649d37..22f74b6c 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.48 2005-11-06 15:26:06 c2woody Exp $ */ +/* $Id: bios.cpp,v 1.49 2005-11-10 18:05:12 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -115,11 +115,12 @@ static bool Tandy_InitializeSB() { /* check if Tandy DAC is still playing */ static bool Tandy_TransferInProgress(void) { - if (real_readw(0x40,0xd0)) return true; /* not yet done */ - if (real_readb(0x40,0xd4)) return false; /* still in init-state */ + if (real_readw(0x40,0xd0)) return true; /* not yet done */ + if (real_readb(0x40,0xd4)==0xff) return false; /* still in init-state */ IO_Write(0x0c,0x00); - if (IO_ReadW(tandy_sb.dma*2+1)==0xffff) return false; /* no DMA transfer */ + Bit16u datalen=IO_ReadB(tandy_sb.dma*2+1)|(IO_ReadB(tandy_sb.dma*2+1)<<8); + if (datalen==0xffff) return false; /* no DMA transfer */ return true; } @@ -220,20 +221,14 @@ static Bitu IRQ_TandyDAC(void) { } static void TandyDAC_Handler(Bit8u tfunction) { - if (machine!=MCH_TANDY) return; + if (!tandy_sb.port) return; switch (tfunction) { case 0x81: /* Tandy sound system check */ - if (tandy_sb.port) { - reg_ax=0xc4; - CALLBACK_SCF(Tandy_TransferInProgress()); - } + reg_ax=0xc4; + CALLBACK_SCF(Tandy_TransferInProgress()); break; case 0x82: /* Tandy sound system start recording */ case 0x83: /* Tandy sound system start playback */ - if (!tandy_sb.port) { - CALLBACK_SCF(true); - break; - } if (Tandy_TransferInProgress()) { /* cannot play yet as the last transfer isn't finished yet */ reg_ah=0x00; @@ -249,16 +244,12 @@ static void TandyDAC_Handler(Bit8u tfunction) { CALLBACK_SCF(false); break; case 0x84: /* Tandy sound system stop playing */ - if (!tandy_sb.port) { - CALLBACK_SCF(true); - break; - } reg_ah=0x00; - /* setup for a small buffer with zeros (silence) */ + /* setup for a small buffer with silence */ real_writew(0x40,0xd0,0x0a); real_writew(0x40,0xd2,0x1c); - Tandy_SetupTransfer(PhysMake(0xf000,0xa084),false); + Tandy_SetupTransfer(PhysMake(0xf000,0xa084),true); CALLBACK_SCF(false); break; case 0x85: /* Tandy sound system reset */ @@ -802,6 +793,8 @@ private: CALLBACK_HandlerObject callback[9]; public: BIOS(Section* configuration):Module_base(configuration){ + /* tandy DAC can be requested in tandy_sound.cpp by initializing this field */ + bool use_tandyDAC=(real_readb(0x40,0xd4)==0xff); /* Clear the Bios Data Area (0x400-0x5ff, 0x600- is accounted to DOS) */ for (Bit16u i=0;i<0x200;i++) real_writeb(0x40,i,0); /* Setup all the interrupt handlers the bios controls */ @@ -863,22 +856,23 @@ public: callback[8].Install(&INT70_Handler,CB_IRET,"Int 70 RTC"); callback[8].Set_RealVec(0x70); - if (machine==MCH_TANDY) { - phys_writeb(0xffffe,0xfc); /* Tandy model */ - phys_writeb(0xfc000,0x21); /* Tandy bios identificator */ + if (machine==MCH_TANDY) phys_writeb(0xffffe,0xff); /* Tandy model */ + else phys_writeb(0xffffe,0xfc); /* PC */ + + if (use_tandyDAC) { + /* tandy DAC sound requested, see if soundblaster device is available */ if (Tandy_InitializeSB()) { real_writew(0x40,0xd0,0x0000); real_writew(0x40,0xd2,0x0000); - real_writeb(0x40,0xd4,0xff); /* initial value */ + real_writeb(0x40,0xd4,0xff); /* tandy DAC init value */ real_writed(0x40,0xd6,0x00000000); /* install the DAC callback handler */ tandy_DAC_callback=new CALLBACK_HandlerObject(); tandy_DAC_callback->Install(&IRQ_TandyDAC,CB_IRET,"Tandy DAC IRQ"); RealPt current_irq=RealGetVec(tandy_sb.irq+8); real_writed(0x40,0xd6,current_irq); - } - } else { - phys_writeb(0xffffe,0xfc); /* PC */ + for (Bitu i=0; i<0x10; i++) phys_writeb(PhysMake(0xf000,0xa084+i),0x80); + } else real_writeb(0x40,0xd4,0x00); } /* Setup some stuff in 0x40 bios segment */ @@ -968,22 +962,21 @@ public: size_extended|=(IO_Read(0x71) << 8); } ~BIOS(){ - if (machine==MCH_TANDY) { - /* abort DAC playing */ - if (tandy_sb.port) { - IO_Write(tandy_sb.port+0xc,0xd3); - IO_Write(tandy_sb.port+0xc,0xd0); - } - if (tandy_DAC_callback) { - Bit32u orig_vector=real_readd(0x40,0xd6); - if (orig_vector==tandy_DAC_callback->Get_RealPointer()) { - /* set IRQ vector to old value */ - RealSetVec(tandy_sb.irq+8,real_readd(0x40,0xd6)); - real_writed(0x40,0xd6,0x00000000); - } - delete tandy_DAC_callback; - tandy_DAC_callback=NULL; + /* abort DAC playing */ + if (tandy_sb.port) { + IO_Write(tandy_sb.port+0xc,0xd3); + IO_Write(tandy_sb.port+0xc,0xd0); + } + real_writeb(0x40,0xd4,0x00); + if (tandy_DAC_callback) { + Bit32u orig_vector=real_readd(0x40,0xd6); + if (orig_vector==tandy_DAC_callback->Get_RealPointer()) { + /* set IRQ vector to old value */ + RealSetVec(tandy_sb.irq+8,real_readd(0x40,0xd6)); + real_writed(0x40,0xd6,0x00000000); } + delete tandy_DAC_callback; + tandy_DAC_callback=NULL; } } }; From 01e60082eaea51a79ed9149bb3e22edd4801d65e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 10 Nov 2005 20:24:55 +0000 Subject: [PATCH 2290/4131] enable all planes when outputing characters through int10 (fixes Ultima1 text colour) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2374 --- src/ints/int10_char.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 642885e1..9f478eb8 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.39 2005-10-03 19:22:13 c2woody Exp $ */ +/* $Id: int10_char.cpp,v 1.40 2005-11-10 20:24:55 c2woody Exp $ */ /* Character displaying moving functions */ @@ -493,6 +493,7 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt x=8*col; y=cheight*row;Bit8u xor_mask=(CurMode->type == M_VGA) ? 0x0 : 0x80; //TODO Check for out of bounds + IO_Write(0x3c4,0x2);IO_Write(0x3c5,0xf); /* enable all planes */ for (Bit8u h=0;h Date: Sat, 12 Nov 2005 14:17:36 +0000 Subject: [PATCH 2291/4131] enable all planes only for EGA Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2375 --- src/ints/int10_char.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 9f478eb8..9df3c0ca 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.40 2005-11-10 20:24:55 c2woody Exp $ */ +/* $Id: int10_char.cpp,v 1.41 2005-11-12 14:17:36 c2woody Exp $ */ /* Character displaying moving functions */ @@ -493,7 +493,12 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt x=8*col; y=cheight*row;Bit8u xor_mask=(CurMode->type == M_VGA) ? 0x0 : 0x80; //TODO Check for out of bounds - IO_Write(0x3c4,0x2);IO_Write(0x3c5,0xf); /* enable all planes */ + if (CurMode->type==M_EGA16) { + /* enable all planes for EGA modes (Ultima 1 colour bug) */ + /* might be put into INT10_PutPixel but different vga bios + implementations have different opinions about this */ + IO_Write(0x3c4,0x2);IO_Write(0x3c5,0xf); + } for (Bit8u h=0;h Date: Sun, 13 Nov 2005 15:14:49 +0000 Subject: [PATCH 2292/4131] don't change type field when resizing dos memory just before the last block that is marked allocated Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2376 --- src/dos/dos_memory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 6a3c47a8..ebd1ab01 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -215,7 +215,7 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { /* at this point: *blocks==total (fits) or *blocks>total, in the second case resize block to maximum */ - if (mcb.GetType()!=0x5a) { + if ((mcb_next.GetPSPSeg()==MCB_FREE) && (mcb.GetType()!=0x5a)) { /* adjust type of joined MCB */ mcb.SetType(mcb_next.GetType()); } From f22e8d50410b5f44c0a453ccf89a60a06d5ebe31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 16 Nov 2005 20:27:40 +0000 Subject: [PATCH 2293/4131] add possibility to close dma controllers; remove second dma controller when tandy sound is enabled and machine=vga Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2377 --- include/dma.h | 49 +++++--- src/dosbox.cpp | 4 +- src/hardware/dma.cpp | 231 ++++++++++++++++++++--------------- src/hardware/gus.cpp | 8 +- src/hardware/sblaster.cpp | 39 +++--- src/hardware/tandy_sound.cpp | 18 ++- 6 files changed, 207 insertions(+), 142 deletions(-) diff --git a/include/dma.h b/include/dma.h index fb72a2ea..84ec9a7a 100644 --- a/include/dma.h +++ b/include/dma.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dma.h,v 1.14 2005-03-24 10:18:45 qbix79 Exp $ */ +/* $Id: dma.h,v 1.15 2005-11-16 20:27:39 c2woody Exp $ */ #ifndef DOSBOX_DMA_H #define DOSBOX_DMA_H @@ -31,19 +31,6 @@ enum DMAEvent { class DmaChannel; typedef void (* DMA_CallBack)(DmaChannel * chan,DMAEvent event); -class DmaController { -public: - bool flipflop; - Bit8u ctrlnum; - Bit8u chanbase; -public: - DmaController(Bit8u num) { - flipflop = false; - ctrlnum = num; - chanbase = num * 4; - } -}; - class DmaChannel { public: Bit32u pagebase; @@ -85,7 +72,37 @@ public: Bitu Write(Bitu size, Bit8u * buffer); }; -extern DmaChannel *DmaChannels[8]; -extern DmaController *DmaControllers[2]; +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 diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 8192e805..28da68d6 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.89 2005-11-10 18:05:10 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.90 2005-11-16 20:27:39 c2woody Exp $ */ #include #include @@ -341,7 +341,7 @@ void DOSBOX_Init(void) { MSG_Add("SPEAKER_CONFIGFILE_HELP", "pcspeaker -- Enable PC-Speaker emulation.\n" "pcrate -- Sample rate of the PC-Speaker sound generation.\n" - "tandy -- Enable Tandy Sound System emulation (false,true,auto).\n" + "tandy -- Enable Tandy Sound System emulation (off,on,auto).\n" " For auto Tandysound emulation is present only if machine is set to tandy.\n" "tandyrate -- Sample rate of the Tandy 3-Voice generation.\n" "disney -- Enable Disney Sound Source emulation.\n" diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 43be4cd8..988f0a30 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -25,37 +25,100 @@ #include "paging.h" #include "setup.h" -DmaChannel *DmaChannels[8]; DmaController *DmaControllers[2]; +/* read a block from physical memory */ static void DMA_BlockRead(PhysPt pt,void * data,Bitu size) { Bit8u * write=(Bit8u *) data; for ( ; size ; size--, pt++) { Bitu page = pt >> 12; - if (page < LINK_START) + if (page < LINK_START) /* cares for EMS pageframe etc. */ page = paging.firstmb[page]; *write++=phys_readb(page*4096 + (pt & 4095)); } } +/* write a block into physical memory */ static void DMA_BlockWrite(PhysPt pt,void * data,Bitu size) { Bit8u * read=(Bit8u *) data; for ( ; size ; size--, pt++) { Bitu page = pt >> 12; - if (page < LINK_START) + if (page < LINK_START) /* cares for EMS pageframe etc. */ page = paging.firstmb[page]; phys_writeb(page*4096 + (pt & 4095), *read++); } } -static void DMA_WriteControllerReg(DmaController * cont,Bitu reg,Bitu val,Bitu len) { +DmaChannel * GetDMAChannel(Bit8u chan) { + if (chan<4) { + /* channel on first DMA controller */ + if (DmaControllers[0]) return DmaControllers[0]->GetChannel(chan); + } else if (chan<8) { + /* channel on second DMA controller */ + if (DmaControllers[1]) return DmaControllers[1]->GetChannel(chan-4); + } + return NULL; +} + +/* remove the second DMA controller (ports are removed automatically) */ +void CloseSecondDMAController(void) { + if (DmaControllers[1]) { + delete DmaControllers[1]; + DmaControllers[1]=NULL; + } +} + +/* check availability of second DMA controller, needed for SB16 */ +bool SecondDMAControllerAvailable(void) { + if (DmaControllers[1]) return true; + else return false; +} + +static void DMA_Write_Port(Bitu port,Bitu val,Bitu iolen) { + if (port<0x10) { + /* write to the first DMA controller (channels 0-3) */ + DmaControllers[0]->WriteControllerReg(port,val,1); + } else if (port>=0xc0 && port <=0xdf) { + /* write to the second DMA controller (channels 4-7) */ + DmaControllers[1]->WriteControllerReg((port-0xc0) >> 1,val,1); + } else switch (port) { + /* write DMA page register */ + case 0x81:GetDMAChannel(2)->SetPage(val);break; + case 0x82:GetDMAChannel(3)->SetPage(val);break; + case 0x83:GetDMAChannel(1)->SetPage(val);break; + case 0x89:GetDMAChannel(6)->SetPage(val);break; + case 0x8a:GetDMAChannel(7)->SetPage(val);break; + case 0x8b:GetDMAChannel(5)->SetPage(val);break; + } +} + +static Bitu DMA_Read_Port(Bitu port,Bitu iolen) { + if (port<0x10) { + /* read from the first DMA controller (channels 0-3) */ + return DmaControllers[0]->ReadControllerReg(port,iolen); + } else if (port>=0xc0 && port <=0xdf) { + /* read from the second DMA controller (channels 4-7) */ + return DmaControllers[1]->ReadControllerReg((port-0xc0) >> 1,iolen); + } else switch (port) { + /* read DMA page register */ + case 0x81:return GetDMAChannel(2)->pagenum; + case 0x82:return GetDMAChannel(3)->pagenum; + case 0x83:return GetDMAChannel(1)->pagenum; + case 0x89:return GetDMAChannel(6)->pagenum; + case 0x8a:return GetDMAChannel(7)->pagenum; + case 0x8b:return GetDMAChannel(5)->pagenum; + } + return 0; +} + +void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) { DmaChannel * chan;Bitu i; - Bitu base=cont->chanbase; switch (reg) { + /* set base address of DMA transfer (1st byte low part, 2nd byte high part) */ case 0x0:case 0x2:case 0x4:case 0x6: - chan=DmaChannels[base+(reg >> 1)]; - cont->flipflop=!cont->flipflop; - if (cont->flipflop) { + chan=GetChannel(reg >> 1); + flipflop=!flipflop; + if (flipflop) { chan->baseaddr=(chan->baseaddr&0xff00)|val; chan->curraddr=(chan->curraddr&0xff00)|val; } else { @@ -63,10 +126,11 @@ static void DMA_WriteControllerReg(DmaController * cont,Bitu reg,Bitu val,Bitu l chan->curraddr=(chan->curraddr&0x00ff)|(val << 8); } break; + /* set DMA transfer count (1st byte low part, 2nd byte high part) */ case 0x1:case 0x3:case 0x5:case 0x7: - chan=DmaChannels[base+(reg >> 1)]; - cont->flipflop=!cont->flipflop; - if (cont->flipflop) { + chan=GetChannel(reg >> 1); + flipflop=!flipflop; + if (flipflop) { chan->basecnt=(chan->basecnt&0xff00)|val; chan->currcnt=(chan->currcnt&0xff00)|val; } else { @@ -80,63 +144,67 @@ static void DMA_WriteControllerReg(DmaController * cont,Bitu reg,Bitu val,Bitu l //TODO Warning? break; case 0xa: /* Mask Register */ - chan=DmaChannels[base+(val & 3 )]; + chan=GetChannel(val & 3); chan->SetMask((val & 0x4)>0); break; case 0xb: /* Mode Register */ - chan=DmaChannels[base+(val & 3 )]; + chan=GetChannel(val & 3); chan->autoinit=(val & 0x10) > 0; chan->increment=(val & 0x20) > 0; //TODO Maybe other bits? break; case 0xc: /* Clear Flip/Flip */ - cont->flipflop=false; + flipflop=false; break; case 0xd: /* Master Clear/Reset */ for (i=0;i<4;i++) { - DmaChannels[base+i]->SetMask(true); - DmaChannels[base+i]->tcount=false; + chan=GetChannel(i); + chan->SetMask(true); + chan->tcount=false; } - cont->flipflop=false; + flipflop=false; break; case 0xe: /* Clear Mask register */ for (i=0;i<4;i++) { - DmaChannels[base+i]->SetMask(false); + chan=GetChannel(i); + chan->SetMask(false); } break; case 0xf: /* Multiple Mask register */ for (i=0;i<4;i++) { - DmaChannels[base+i]->SetMask(val & 1); + chan=GetChannel(i); + chan->SetMask(val & 1); val>>=1; } break; } } -static Bitu DMA_ReadControllerReg(DmaController * cont,Bitu reg,Bitu len) { +Bitu DmaController::ReadControllerReg(Bitu reg,Bitu len) { DmaChannel * chan;Bitu i,ret; - Bitu base=cont->chanbase; switch (reg) { + /* read base address of DMA transfer (1st byte low part, 2nd byte high part) */ case 0x0:case 0x2:case 0x4:case 0x6: - chan=DmaChannels[base+(reg >> 1)]; - cont->flipflop=!cont->flipflop; - if (cont->flipflop) { + chan=GetChannel(reg >> 1); + flipflop=!flipflop; + if (flipflop) { return chan->curraddr & 0xff; } else { return (chan->curraddr >> 8) & 0xff; } + /* read DMA transfer count (1st byte low part, 2nd byte high part) */ case 0x1:case 0x3:case 0x5:case 0x7: - chan=DmaChannels[base+(reg >> 1)]; - cont->flipflop=!cont->flipflop; - if (cont->flipflop) { + chan=GetChannel(reg >> 1); + flipflop=!flipflop; + if (flipflop) { return chan->currcnt & 0xff; } else { return (chan->currcnt >> 8) & 0xff; } - case 0x8: + case 0x8: /* Status Register */ ret=0; for (i=0;i<4;i++) { - chan=DmaChannels[base+i]; + chan=GetChannel(i); if (chan->tcount) ret|=1 << i; chan->tcount=false; if (chan->callback) ret|=1 << (i+4); @@ -149,53 +217,21 @@ static Bitu DMA_ReadControllerReg(DmaController * cont,Bitu reg,Bitu len) { return 0xffffffff; } - -static void DMA_Write_Port(Bitu port,Bitu val,Bitu iolen) { - if (port<0x10) { - DMA_WriteControllerReg(DmaControllers[0],port,val,1); - } else if (port>=0xc0 && port <=0xdf) { - DMA_WriteControllerReg(DmaControllers[1],(port-0xc0) >> 1,val,1); - } else switch (port) { - case 0x81:DmaChannels[2]->SetPage(val);break; - case 0x82:DmaChannels[3]->SetPage(val);break; - case 0x83:DmaChannels[1]->SetPage(val);break; - case 0x89:DmaChannels[6]->SetPage(val);break; - case 0x8a:DmaChannels[7]->SetPage(val);break; - case 0x8b:DmaChannels[5]->SetPage(val);break; - } -} - -static Bitu DMA_Read_Port(Bitu port,Bitu iolen) { - if (port<0x10) { - return DMA_ReadControllerReg(DmaControllers[0],port,iolen); - } else if (port>=0xc0 && port <=0xdf) { - return DMA_ReadControllerReg(DmaControllers[1],(port-0xc0) >> 1,iolen); - } else switch (port) { - case 0x81:return DmaChannels[2]->pagenum; - case 0x82:return DmaChannels[3]->pagenum; - case 0x83:return DmaChannels[1]->pagenum; - case 0x89:return DmaChannels[6]->pagenum; - case 0x8a:return DmaChannels[7]->pagenum; - case 0x8b:return DmaChannels[5]->pagenum; - } - return 0; -} - DmaChannel::DmaChannel(Bit8u num, bool dma16) { - masked = true; - callback = NULL; - if(num == 4) return; - channum = num; - DMA16 = dma16 ? 0x1 : 0x0; - pagenum = 0; - pagebase = 0; - baseaddr = 0; - curraddr = 0; - basecnt = 0; - currcnt = 0; - increment = true; - autoinit = false; - tcount = false; + masked = true; + callback = NULL; + if(num == 4) return; + channum = num; + DMA16 = dma16 ? 0x1 : 0x0; + pagenum = 0; + pagebase = 0; + baseaddr = 0; + curraddr = 0; + basecnt = 0; + currcnt = 0; + increment = true; + autoinit = false; + tcount = false; } Bitu DmaChannel::Read(Bitu want, Bit8u * buffer) { @@ -226,6 +262,7 @@ again: } return done; } + Bitu DmaChannel::Write(Bitu want, Bit8u * buffer) { Bitu done=0; again: @@ -256,40 +293,42 @@ again: } class DMA:public Module_base{ -private: - IO_ReadHandleObject ReadHandler[0x22]; - IO_WriteHandleObject WriteHandler[0x22]; public: DMA(Section* configuration):Module_base(configuration){ Bitu i; DmaControllers[0] = new DmaController(0); - DmaControllers[1] = new DmaController(1); + if (machine==MCH_VGA) DmaControllers[1] = new DmaController(1); - for(i=0;i<8;i++) { - DmaChannels[i] = new DmaChannel(i,i>=4); - } - for (i=0;i<0x10;i++) { Bitu mask=IO_MB; if (i<8) mask|=IO_MW; - WriteHandler[i].Install(i,DMA_Write_Port,mask); - ReadHandler[i].Install(i,DMA_Read_Port,mask); + /* install handler for first DMA controller ports */ + DmaControllers[0]->DMA_WriteHandler[i].Install(i,DMA_Write_Port,mask); + DmaControllers[0]->DMA_ReadHandler[i].Install(i,DMA_Read_Port,mask); if (machine==MCH_VGA) { - WriteHandler[0x10+i].Install(0xc0+i*2,DMA_Write_Port,mask); - ReadHandler[0x10+i].Install(0xc0+i*2,DMA_Read_Port,mask); + /* install handler for second DMA controller ports */ + DmaControllers[1]->DMA_WriteHandler[i].Install(0xc0+i*2,DMA_Write_Port,mask); + DmaControllers[1]->DMA_ReadHandler[i].Install(0xc0+i*2,DMA_Read_Port,mask); } } - WriteHandler[0x20].Install(0x81,DMA_Write_Port,IO_MB,3); - WriteHandler[0x21].Install(0x89,DMA_Write_Port,IO_MB,3); - - ReadHandler[0x20].Install(0x81,DMA_Read_Port,IO_MB,3); - ReadHandler[0x21].Install(0x89,DMA_Read_Port,IO_MB,3); + /* install handlers for ports 0x81-0x83 (on the first DMA controller) */ + DmaControllers[0]->DMA_WriteHandler[0x10].Install(0x81,DMA_Write_Port,IO_MB,3); + DmaControllers[0]->DMA_ReadHandler[0x10].Install(0x81,DMA_Read_Port,IO_MB,3); + + if (machine==MCH_VGA) { + /* install handlers for ports 0x81-0x83 (on the second DMA controller) */ + DmaControllers[1]->DMA_WriteHandler[0x10].Install(0x89,DMA_Write_Port,IO_MB,3); + DmaControllers[1]->DMA_ReadHandler[0x10].Install(0x89,DMA_Read_Port,IO_MB,3); + } } ~DMA(){ - delete DmaControllers[0]; - delete DmaControllers[1]; - for(Bitu i=0;i<8;i++) { - delete DmaChannels[i]; + if (DmaControllers[0]) { + delete DmaControllers[0]; + DmaControllers[0]=NULL; + } + if (DmaControllers[1]) { + delete DmaControllers[1]; + DmaControllers[1]=NULL; } } }; diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 895a5f0f..abe48b7b 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -83,8 +83,8 @@ struct GFGus { } timers[2]; Bit32u rate; Bit16u portbase; - Bit16u dma1; - Bit16u dma2; + Bit8u dma1; + Bit8u dma2; Bit16u irq1; Bit16u irq2; @@ -568,7 +568,7 @@ static void ExecuteGlobRegister(void) { break; case 0x41: // Dma control register myGUS.DMAControl = (Bit8u)(myGUS.gRegData>>8); - DmaChannels[myGUS.dma1]->Register_Callback( + GetDMAChannel(myGUS.dma1)->Register_Callback( (myGUS.DMAControl & 0x1) ? GUS_DMA_Callback : 0); break; case 0x42: // Gravis DRAM DMA address register @@ -597,7 +597,7 @@ static void ExecuteGlobRegister(void) { break; case 0x49: // DMA sampling control register myGUS.SampControl = (Bit8u)(myGUS.gRegData>>8); - DmaChannels[myGUS.dma1]->Register_Callback( + GetDMAChannel(myGUS.dma1)->Register_Callback( (myGUS.SampControl & 0x1) ? GUS_DMA_Callback : 0); break; case 0x4c: // GUS reset register diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index a154dfd9..24900da7 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -518,7 +518,7 @@ static void DSP_RaiseIRQEvent(Bitu val) { SB_RaiseIRQ(SB_IRQ_8); } -static void DSP_DoDMATranfser(DMA_MODES mode,Bitu freq,bool stereo) { +static void DSP_DoDMATransfer(DMA_MODES mode,Bitu freq,bool stereo) { char * type; sb.mode=MODE_DMA_MASKED; sb.chan->FillUp(); @@ -576,8 +576,8 @@ static void DSP_DoDMATranfser(DMA_MODES mode,Bitu freq,bool stereo) { static void DSP_PrepareDMA_Old(DMA_MODES mode,bool autoinit) { sb.dma.autoinit=autoinit; if (!autoinit) sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); - sb.dma.chan=DmaChannels[sb.hw.dma8]; - DSP_DoDMATranfser(mode,sb.freq / (sb.mixer.stereo ? 2 : 1),sb.mixer.stereo); + sb.dma.chan=GetDMAChannel(sb.hw.dma8); + DSP_DoDMATransfer(mode,sb.freq / (sb.mixer.stereo ? 2 : 1),sb.mixer.stereo); } static void DSP_PrepareDMA_New(DMA_MODES mode,Bitu length,bool autoinit,bool stereo) { @@ -585,14 +585,14 @@ static void DSP_PrepareDMA_New(DMA_MODES mode,Bitu length,bool autoinit,bool ste sb.dma.total=length; sb.dma.autoinit=autoinit; if (mode==DSP_DMA_16) { - if (sb.hw.dma16!=0xff) sb.dma.chan=DmaChannels[sb.hw.dma16]; + if (sb.hw.dma16!=0xff) sb.dma.chan=GetDMAChannel(sb.hw.dma16); else { - sb.dma.chan=DmaChannels[sb.hw.dma8]; + sb.dma.chan=GetDMAChannel(sb.hw.dma8); mode=DSP_DMA_16_ALIASED; freq/=2; } - } else sb.dma.chan=DmaChannels[sb.hw.dma8]; - DSP_DoDMATranfser(mode,freq,stereo); + } else sb.dma.chan=GetDMAChannel(sb.hw.dma8); + DSP_DoDMATransfer(mode,freq,stereo); } @@ -650,19 +650,21 @@ static void DSP_DoReset(Bit8u val) { static void DSP_E2_DMA_CallBack(DmaChannel * chan, DMAEvent event) { if (event==DMA_UNMASKED) { Bit8u val=sb.e2.value; - DmaChannels[sb.hw.dma8]->Register_Callback(0); - DmaChannels[sb.hw.dma8]->Write(1,&val); + DmaChannel * chan=GetDMAChannel(sb.hw.dma8); + chan->Register_Callback(0); + chan->Write(1,&val); } } static void DSP_ADC_CallBack(DmaChannel * chan, DMAEvent event) { if (event!=DMA_UNMASKED) return; Bit8u val=128; + DmaChannel * ch=GetDMAChannel(sb.hw.dma8); while (sb.dma.left--) { - DmaChannels[sb.hw.dma8]->Write(1,&val); + ch->Write(1,&val); } SB_RaiseIRQ(SB_IRQ_8); - DmaChannels[sb.hw.dma8]->Register_Callback(0); + ch->Register_Callback(0); } Bitu DEBUG_EnableDebugger(void); @@ -684,7 +686,7 @@ static void DSP_DoCommand(void) { case 0x24: /* Singe Cycle 8-Bit DMA ADC */ sb.dma.left=sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); LOG(LOG_SB,LOG_ERROR)("DSP:Faked ADC for %d bytes",sb.dma.total); - DmaChannels[sb.hw.dma8]->Register_Callback(DSP_ADC_CallBack); + GetDMAChannel(sb.hw.dma8)->Register_Callback(DSP_ADC_CallBack); break; case 0x14: /* Singe Cycle 8-Bit DMA DAC */ case 0x91: /* Singe Cycle 8-Bit DMA High speed DAC */ @@ -794,7 +796,7 @@ static void DSP_DoCommand(void) { if ((sb.dsp.in.data[0] >> i) & 0x01) sb.e2.value += E2_incr_table[sb.e2.count % 4][i]; sb.e2.value += E2_incr_table[sb.e2.count % 4][8]; sb.e2.count++; - DmaChannels[sb.hw.dma8]->Register_Callback(DSP_E2_DMA_CallBack); + GetDMAChannel(sb.hw.dma8)->Register_Callback(DSP_E2_DMA_CallBack); } break; case 0xe3: /* DSP Copyright */ @@ -1105,12 +1107,14 @@ private: else if (!strcasecmp(sbtype,"sb16")) type=SBT_16; else if (!strcasecmp(sbtype,"none")) type=SBT_NONE; else type=SBT_16; - - if (machine!=MCH_VGA && type==SBT_16) type=SBT_PRO2; - + + if (type==SBT_16) { + if ((machine!=MCH_VGA) || !SecondDMAControllerAvailable()) type=SBT_PRO2; + } + /* OPL/CMS Init */ const char * omode=config->Get_string("oplmode"); - if (!strcasecmp(omode,"none")) opl_mode=OPL_none; + if (!strcasecmp(omode,"none")) opl_mode=OPL_none; else if (!strcasecmp(omode,"cms")) opl_mode=OPL_cms; else if (!strcasecmp(omode,"opl2")) opl_mode=OPL_opl2; else if (!strcasecmp(omode,"dualopl2")) opl_mode=OPL_dualopl2; @@ -1186,7 +1190,6 @@ public: } ~SBLASTER() { - Bitu i; Section_prop * section=static_cast(m_configuration); OPL_Mode opl_mode; Find_Type_And_Opl(section,sb.type,opl_mode); diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index abcdc996..33ffd8e1 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -27,6 +27,7 @@ #include "mem.h" #include "setup.h" #include "pic.h" +#include "dma.h" #define DAC_CLOCK 3570000 #define MAX_OUTPUT 0x7fff @@ -308,7 +309,7 @@ static void SN76496_set_gain(int gain) class TANDYSOUND: public Module_base { private: - IO_WriteHandleObject WriteHandler[2]; + IO_WriteHandleObject WriteHandler[3]; MixerObject MixerChan; public: TANDYSOUND(Section* configuration):Module_base(configuration){ @@ -318,16 +319,21 @@ public: if (machine==MCH_TANDY) { /* enable tandy sound if tandy=true/auto */ if ((strcmp(section->Get_string("tandy"),"true")!=0) && + (strcmp(section->Get_string("tandy"),"on")!=0) && (strcmp(section->Get_string("tandy"),"auto")!=0)) return; } else { /* only enable tandy sound if tandy=true */ - if (strcmp(section->Get_string("tandy"),"true")!=0) return; + if ((strcmp(section->Get_string("tandy"),"true")!=0) && + (strcmp(section->Get_string("tandy"),"on")!=0)) return; + + /* ports from second DMA controller conflict with tandy ports */ + CloseSecondDMAController(); + + WriteHandler[2].Install(0x1e0,SN76496Write,IO_MB,2); } - if (machine==MCH_TANDY) { - WriteHandler[0].Install(0xc0,SN76496Write,IO_MB,2); - WriteHandler[1].Install(0xc4,TandyDACWrite,IO_MB,4); - } else WriteHandler[0].Install(0x1e0,SN76496Write,IO_MB,2); + WriteHandler[0].Install(0xc0,SN76496Write,IO_MB,2); + WriteHandler[1].Install(0xc4,TandyDACWrite,IO_MB,4); Bit32u sample_rate = section->Get_int("tandyrate"); From d6f0adb9a63ab78d90cd5cad922744af957724dc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 17 Nov 2005 07:59:02 +0000 Subject: [PATCH 2294/4131] Add patch 1357811:Runtime help of debug command "LV" wrong Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2378 --- src/debug/debug.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index eb52a3cc..15d95e20 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.69 2005-09-18 19:50:03 c2woody Exp $ */ +/* $Id: debug.cpp,v 1.70 2005-11-17 07:59:02 qbix79 Exp $ */ #include #include @@ -1278,7 +1278,7 @@ bool ParseCommand(char* str) DEBUG_ShowMsg("IV [seg]:[off] [name] - Create var name for memory address.\n"); DEBUG_ShowMsg("SV [filename] - Save var list in file.\n"); - DEBUG_ShowMsg("LV [seg]:[off] [name] - Load var list from file.\n"); + DEBUG_ShowMsg("LV [filename] - Load var list from file.\n"); DEBUG_ShowMsg("MEMDUMP [seg]:[off] [len] - Write memory to file memdump.txt.\n"); DEBUG_ShowMsg("MEMDUMPBIN [s]:[o] [len] - Write memory to file memdump.bin.\n"); From 0797de3e253e51ab9f9d7bd3ae026f32490cfc4f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 17 Nov 2005 13:16:34 +0000 Subject: [PATCH 2295/4131] Fix Fable. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2379 --- src/dos/dos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 70c3a7c6..e16898fe 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.88 2005-10-31 18:12:56 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.89 2005-11-17 13:16:34 qbix79 Exp $ */ #include #include @@ -410,7 +410,7 @@ static Bitu DOS_21Handler(void) { if (reg_al==0) { /* Get country specidic information */ PhysPt dest = SegPhys(ds)+reg_dx; MEM_BlockWrite(dest,dos.tables.country,0x18); - reg_bx = 0x01; + reg_ax = reg_bx = 0x01; CALLBACK_SCF(false); break; } else { /* Set country code */ From 1b9f9c016941dc3b12c4823141e3379bcd8277a1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 20 Nov 2005 20:15:16 +0000 Subject: [PATCH 2296/4131] don't parse redirection when in quotes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2380 --- src/shell/shell.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 95d8c472..9a463917 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.63 2005-09-29 08:48:39 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.64 2005-11-20 20:15:16 qbix79 Exp $ */ #include #include @@ -116,9 +116,18 @@ Bitu DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn,bool * append) { char * lw=s; char ch; Bitu num=0; + bool quote = false; while ( (ch=*lr++) ) { + if(quote) { /* don't parse redirection within quotes. Not perfect yet. Escaped quotes will mess the count up */ + *lw++ = ch; + continue; + } + switch (ch) { + case '"': + quote = !quote; + break; case '>': *append=((*lr)=='>'); if (*append) lr++; From 00fab72f8c01bff03fac84cc4ffaad1f401d9b7f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 21 Nov 2005 07:21:28 +0000 Subject: [PATCH 2297/4131] quotes can end as well Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2381 --- src/shell/shell.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 9a463917..18ef8e2e 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.64 2005-11-20 20:15:16 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.65 2005-11-21 07:21:28 qbix79 Exp $ */ #include #include @@ -119,7 +119,7 @@ Bitu DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn,bool * append) { bool quote = false; while ( (ch=*lr++) ) { - if(quote) { /* don't parse redirection within quotes. Not perfect yet. Escaped quotes will mess the count up */ + if(quote && ch != '"') { /* don't parse redirection within quotes. Not perfect yet. Escaped quotes will mess the count up */ *lw++ = ch; continue; } From c13994c8343e31e5a9e8596c34f331f4d62206df Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 21 Nov 2005 13:10:19 +0000 Subject: [PATCH 2298/4131] Fix colours YPM when in cga mode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2382 --- src/ints/int10.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 6edfe462..5ca6781e 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -113,6 +113,9 @@ static Bitu INT10_Handler(void) { case 0x01: //Set color Select INT10_SetColorSelect(reg_bl); break; + default: + if(machine == MCH_CGA) INT10_SetColorSelect(reg_bl); + break; } break; case 0x0C: /* Write Graphics Pixel */ From 3e2ba6a557221150f9c5188108019f5551a0f4dd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 21 Nov 2005 15:20:27 +0000 Subject: [PATCH 2299/4131] Some grammar improvements suggested by AJ Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2383 --- README | 257 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 129 insertions(+), 128 deletions(-) diff --git a/README b/README index 666ae326..f01fc933 100644 --- a/README +++ b/README @@ -5,15 +5,15 @@ DOSBox v0.63 NOTE: ===== -While we hope that, one day, DOSBox will run virtually all programs -ever made for the PC...we are not there yet. At present, DOSBox run on a high- +While we are hoping that one day, DOSBox will run all programs +ever made for the PC,we are not there yet. At present, DOSBox run on a high- end machine will roughly be the equivalent of a 486 PC. The 0.60 release has added support for "protected mode" allowing for more complex and -recent programs, but note that this support is early in development and -nowhere near as complete as the support for 386 real-mode games (or -earlier). Also note that "protected mode" games need substantially more -resources and may require a much faster processor for you to run it properly -in DOSBox. +recent programs, but note that this support is still in an early in stage of +development and unlike the support the 386 real-mode games (or earlier) hasn't +been completed yet. Also note that "protected mode" games need substantially +more resources and may require a much faster processor for you to run them +properly in DOSBox. @@ -66,16 +66,16 @@ Q: Great README, but I still don't get it. Q: I've got a Z instead of a C at the prompt. A: You have to make your directories available as drives in DOSBox by using - the "mount" command. For example, in Windows "mount C D:\" would give - you a C in DOSBox which points at your Windows D:\ drive. - In Linux, "mount c /home/username" would give you a C in DOSBox - which points at /home/username in Linux. + the "mount" command. For example, in Windows "mount C D:\" will give + you a C in DOSBox which points to your Windows D:\ drive. + In Linux, "mount c /home/username" will give you a C in DOSBox + which points to /home/username in Linux. Q: My CD-ROM doesn't work. -A: To mount your cdrom in DOSBox you have to specify some additional options - when mounting the cdrom. - To enable the most basic cdrom support: +A: To mount your CD-ROM in DOSBox you have to specify some additional options + when mounting the CD-ROM. + To enable the most basic CD-ROM support: - mount d f:\ -t cdrom To enable low-level SDL-support: - mount d f:\ -t cdrom -usecd 0 @@ -84,23 +84,23 @@ A: To mount your cdrom in DOSBox you have to specify some additional options To enable low-level aspi-support (win98 with aspi-layer installed): - mount d f:\ -t cdrom -usecd 0 -apsi - In the commands: - d driveletter you in DOSBox + In the commands: - d driveletter you will get in DOSBox - f:\ location of cdrom on your PC. - - 0 The number of the cdrom drive, reported by mount -cd + - 0 The number of the CD-ROM drive, reported by mount -cd See also the question: The game/application can't find its CD-ROM. Q: The mouse doesn't work. -A: Normally DOSBox detects the mouse being used by a game. If you click on - the screen then it should get locked (confined to the DOSBox window) - and work. Sometimes the DOSBox mouse detection doesn't work with certain - games. You might have to force to lock the mouse then with ctrl-F10. +A: Usually, DOSBox detects when a game uses mouse control. When you click on + the screen it should get locked (confined to the DOSBox window) and work. + With certain games, the DOSBox mouse detection doesn't work. In that case + you will have to lock the mouse manually by pressing CTRL-F10. Q: The sound stutters. A: You're using too much cpu power to keep DOSBox running at the current speed. - You can either lower the cycles or skip frames or get a faster machine. - You can also increase the prebuffer in the configfile + You can lower the cycles, skip frames or get a faster machine. + You can also increase the prebuffer in the configfile. Q: I can't type \ or : in DOSBox. @@ -109,15 +109,16 @@ A: This is a known problem. It only occurs if your keyboard layout isn't US. 1. Switch your keyboard layout. 2. Use / instead. 3. Add the commands you want to execute to the "configfile". - 4. Start the keymapper (CTRL-F1 or add -startmapper switch to dosbox) - 5. for \ try the keys around "enter". For ":" try shift and the keys between - "enter" and "l" (US keyboard layout). - 6. Use keyb.com from FreeDOS (http://projects.freedos.net/keyb/). + 4. Start the keymapper (CTRL-F1 or add -startmapper switch to DOSBox). + 5. Use ALT-58 for : and ALT-92 for \. + 6. for \ try the keys around "enter". For ":" try shift and the keys + between "enter" and "l" (US keyboard layout). + 7. Use keyb.com from FreeDOS (http://projects.freedos.net/keyb/). Q: The game/application can't find its CD-ROM. A: Be sure to mount the CD-ROM with -t cdrom switch. Also try adding the - correct label (-label LABEL). To enable more low-level CD-ROM support add + correct label (-label LABEL). To enable more low-level CD-ROM support, add the following switch to mount: -usecd #, where # is the number of your CD-ROM drive reported by mount -cd. If you run Win32 you can specify -ioctl or -aspi. Look at the description elsewhere in this document for their @@ -145,26 +146,26 @@ A: DOSBox emulates several legacy sound devices: this with the Adlib emulation may result in conflicts. - Tandy 3 voice The emulation of this sound hardware is complete with the exception of - the noise channel, which is not very well documented and as such is only - a best guess as to the sound's accuracy. + the noise channel. The noise channel is not very well documented and as + such is only a best guess as to the sound's accuracy. - Adlib Borrowed from MAME, this emulation is almost perfect and includes the Adlib's ability to almost play digitized sound. - - SoundBlaster 16/ SoundBlaster Pro I & II /Sound Blaster I & II - Coupled with the Adlib, by default DOSBox provides Soundblaster 16 - level 16-bit stereo sound. You can select a different SoundBlaster - version in the configfile of DOSBox (See Internal Commands: CONFIG). + - SoundBlaster 16/ SoundBlaster Pro I & II /SoundBlaster I & II + By default DOSBox provides Soundblaster 16 level 16-bit stereo sound. + You can select a different SoundBlaster version in the configfile of + DOSBox (See Internal Commands: CONFIG). - Disney Soundsource Using the printer port, this sound device outputs digital sound only. - Gravis Ultrasound The emulation of this hardware is nearly complete, though the MIDI - capabilities have been left out since an MPU-401 has been + capabilities have been left out, since an MPU-401 has been emulated in other code. - MPU-401 A MIDI passthrough interface is also emulated. This method of sound output will only work when used with a General Midi or MT-32 device. -Q: DOSBox crashes on startup and I'm running arts +Q: DOSBox crashes on startup and I'm running arts. A: This isn't really a DOSBox problem, but the solution is to set the environment variable SDL_AUDIODRIVER to alsa or oss. @@ -189,7 +190,7 @@ http://dosbox.sourceforge.net An overview of the commandline options you can give to DOSBox. Windows Users must open cmd.exe or command.com or edit the shortcut to -dosbox.exe for this. +DOSBox.exe for this. The options are valid for all operating systems unless noted in the option description: @@ -205,32 +206,32 @@ dosbox -version as the C: drive and execute "name". -exit - dosbox will close itself when the DOS application "name" ends. + DOSBox will close itself when the DOS application "name" ends. -c command Runs the specified command before running "name". Multiple commands - can be specified. Each command should start with -c though. + can be specified. Each command should start with "-c", though. A command can be: an Internal Program, a DOS command or an executable on a mounted drive. -fullscreen - Starts dosbox in fullscreen mode. + Starts DOSBox in fullscreen mode. -conf configfile - Start dosbox with the options specified in "configfile". + Start DOSBox with the options specified in "configfile". See Chapter 9 for more details. -lang languagefile - Start dosbox using the language specified in "languagefile". + Start DOSBox using the language specified in "languagefile". -noconsole (Windows Only) - Start dosbox without showing the console window. Output will + Start DOSBox without showing the console window. Output will be redirected to stdout.txt and stderr.txt -machine machinetype - Setup dosbox to emulate a specific type of machine. Valid choices are: - hercules, cga, tandy, vga (default). The machinetype has influence on - both the videocard and the available soundcards. + Setup DOSBox to emulate a specific type of machine. Valid choices are: + hercules, cga, tandy, vga (default). The machinetype affects both the + videocard and the available soundcards. -startmapper Enter the keymapper directly on startup. Useful for people with @@ -239,18 +240,18 @@ dosbox -version -version output version information and exit. Useful for frontends. -Note: If a name/command/configfile/languagefile contains a space in it, put +Note: If a name/command/configfile/languagefile contains a space, put the whole name/command/configfile/languagefile between quotes ("command or file name"). For example: dosbox c:\atlantis\atlantis.exe -c "MOUNT D C:\SAVES" - This would mount c:\atlantis as c:\ and run atlantis.exe. + This mounts c:\atlantis as c:\ and run atlantis.exe. Before it does that it would first mount C:\SAVES as the D drive. -In Windows you can also drag directories/files onto the dosbox executable. - +In Windows, you can also drag directories/files onto the DOSBox executable. + ===================== @@ -285,7 +286,7 @@ MOUNT -u "Emulated Drive letter" -freesize size_in_mb Sets the amount of free space available on a drive in MB's. This - is a more simple version of -size. + is a simpler version of -size. -label drivelabel Sets the name of the drive to "drivelabel". Needed on some @@ -295,7 +296,7 @@ MOUNT -u "Emulated Drive letter" For win32: label is extracted from "Real Drive". For Linux: label is set to NO_LABEL. - If you do specify a label this label will be kept as long as the drive + If you do specify a label, this label will be kept as long as the drive is mounted. It will not be updated !! -aspi @@ -325,11 +326,11 @@ MOUNT -u "Emulated Drive letter" programs that demand specific drive letters. For example: Touche: Adventures of The Fifth Musketeer must be run on your C: - drive. Using DOSBox and its mount command, you can trick into thinking it - is on C drive while placing it where you want it. For example, if the game - were in D:\TOUCHE, you can use the command MOUNT C D:\ would allow you to - run Touche from the D drive. - + drive. Using DOSBox and its mount command, you can trick the game into + believing it is on the C drive, while you can still place it where you + want it. For example, if the game is in D:\TOUCHE, the command MOUNT C D:\ + will allow you to run Touche from the D drive. + General MOUNT Examples: 1. To mount c:\DirX as a floppy : @@ -351,11 +352,11 @@ MEM CONFIG [-writeconf] [-writelang] localfile Write the current configuration or language settings to file. - "localfile" is located on the local drive. Not a mounted drive in DOSBox. + "localfile" is located on the local drive, not a mounted drive in DOSBox. - The configuration file controls various settings of DOSBox: The amount + The configuration file controls various settings of DOSBox: the amount of emulated memory, the emulated soundcards and many more things. It - allows acces to AUTOEXEC.BAT as well. + allows access to AUTOEXEC.BAT as well. See section 9 (The Config File) for more information. The language file controls all visible ouput of the internal commands @@ -364,8 +365,8 @@ CONFIG [-writeconf] [-writelang] localfile Example: To create a configfile in your current directory: config -writeconf dosbox.conf - - + + LOADFIX [-size] [program] [program-parameters] LOADFIX -f Program to reduce the amount of memory available. Useful for old programs @@ -395,9 +396,9 @@ RESCAN MIXER Makes DOSBox display its current volume settings. - You can change this way: + Here's how you can change them: - mixer channel left:right [/NOSHOW] + mixer channel left:right [/NOSHOW] [/LISTMIDI] channel Can be one of the following: MASTER, DISNEY, SPKR, GUS, SB, FM. @@ -416,7 +417,7 @@ MIXER 'config=id' to the [midi] section in the configuration file, where 'id' is the number for the device as listed by LISTMIDI. - + IMGMOUNT A utility to mount disk images and CD-ROM images in DOSBox. @@ -424,9 +425,9 @@ IMGMOUNT -size [sectorsbytesize, sectorsperhead, heads, cylinders] imagefile - location of the image files to mount in DOSBox. The location is on a + Location of the image files to mount in DOSBox. The location is on a mounted drive inside DOSBox. CD-ROM images can be mounted - directly as well. They don't need to be a mounted drive. + directly as well. They don't have to be on a mounted drive. -t The following are valid image types: @@ -440,16 +441,16 @@ IMGMOUNT -fs The following are valid file system formats: iso: Specifies the ISO 9660 CD-ROM format. - fat: Specifies the image uses the FAT file system. DOSBox will attempt + fat: Specifies that the image uses the FAT file system. DOSBox will attempt to mount this image as a drive in DOSBox and make the files available from inside DOSBox. none: DOSBox will make no attempt to read the file system on the disk. - This is useful if one needs to format it or one wants to boot - off of the disk using the BOOT command. When using the "none" - filesystem, one must specify the drive number (2 or 3, + This is useful if you need to format it or if you want to boot + the disk using the BOOT command. When using the "none" + filesystem, you must specify the drive number (2 or 3, where 2 = master, 3 = slave) rather than a drive letter. For example, to mount a 70MB image as the slave drive device, - one would type: + you would type: "imgmount 3 d:\test.img -size 512,63,16,142 -fs none" (without the quotes) Compare this with a mount to read the drive in DOSBox, which would read as: @@ -476,13 +477,13 @@ BOOT diskimgN.img This can be any number of floppy disk images one wants mounted after DOSBox boots the specified drive letter. - To swap between images, one hits CTRL+F4 to swap out the current disk - and swap in the next disk in the list. Once the last disk in the list is - swapped out, the list loops back to the beginning. + To swap between images, hit CTRL+F4 to change from the current disk + and to the next disk in the list. The list will loop back from the last + disk image to the beginning. [-l driveletter] - This parameter allows one to specify the drive to boot from. - The default is the A drive, the floppy drive. One can also boot off of + This parameter allows you to specify the drive to boot from. + The default is the A drive, the floppy drive. You can also boot a hard drive image mounted as master by specifying "-l C" without the quotes, or the drive as slave by specifying "-l D" @@ -493,14 +494,14 @@ IPX All of the IPX networking is managed through the internal DOSBox program IPXNET. For help on the IPX networking from inside DOSBox, type - "IPXNET HELP" (without quotes) and the program will list out the commands + "IPXNET HELP" (without quotes) and the program will list the commands and relevant documentation. With regard to actually setting up a network, one system needs to be - the server. To set this up, in a DOSBox session, one should type - "IPXNET STARTSERVER" (without the quotes). The server DOSBox session will - automatically add itself to the virtual IPX network. In turn, for every - other computer that should be part of the virtual IPX network, + the server. To set this up, type "IPXNET STARTSERVER" (without the quotes) + in a DOSBox session. The server DOSBox session will + automatically add itself to the virtual IPX network. For every + additional computer that should be part of the virtual IPX network, you'll need to type "IPXNET CONNECT ". For example, if your server is at bob.dosbox.com, you would type "IPXNET CONNECT bob.dosbox.com" on every non-server system. @@ -509,18 +510,18 @@ IPX IPXNET CONNECT - IPXNET CONNECT opens a connection to an IPX tunneling server + IPXNET CONNECT opens a connection to an IPX tunnelling server running on another DOSBox session. The "address" parameter specifies - the IP address or host name of the server computer. One can also - specify the UDP port to use. By default IPXNET uses port 213, the - assigned IANA port for IPX tunneling, for its connection. + the IP address or host name of the server computer. You can also + specify the UDP port to use. By default IPXNET uses port 213 - the + assigned IANA port for IPX tunnelling - for its connection. The syntax for IPXNET CONNECT is: IPXNET CONNECT address IPXNET DISCONNECT - IPXNET DISCONNECT closes the connection to the IPX tunneling server. + IPXNET DISCONNECT closes the connection to the IPX tunnelling server. The syntax for IPXNET DISCONNECT is: IPXNET DISCONNECT @@ -530,34 +531,34 @@ IPX IPXNET STARTSERVER starts and IPX tunneling server on this DOSBox session. By default, the server will accept connections on UDP port 213, though this can be changed. Once the server is started, DOSBox - will automatically start a client connection to the IPX tunneling server. + will automatically start a client connection to the IPX tunnelling server. - The syntax for IPXNET STARTSERVER is: - IPXNET STARTSERVER + The syntax for IPXNET STARTSERVER is: + IPXNET STARTSERVER - IPXNET STOPSERVER + IPXNET STOPSERVER - IPXNET STOPSERVER stops the IPX tunneling server running on this DOSBox + IPXNET STOPSERVER stops the IPX tunnelling server running on this DOSBox session. Care should be taken to ensure that all other connections have - terminated as well since stopping the server may cause lockups on other - machines still using the IPX tunneling server. + terminated as well, since stopping the server may cause lockups on other + machines that are still using the IPX tunnelling server. The syntax for IPXNET STOPSERVER is: IPXNET STOPSERVER - IPXNET PING + IPXNET PING - IPXNET PING broadcasts a ping request through the IPX tunneled network. + IPXNET PING broadcasts a ping request through the IPX tunnelled network. In response, all other connected computers will respond to the ping and report the time it took to receive and send the ping message. The syntax for IPXNET PING is: - IPXNET PING + IPXNET PING - IPXNET STATUS + IPXNET STATUS - IPXNET STATUS reports the current state of this DOSBox's sessions - IPX tunneling network. For a list of the computers connected to the + IPXNET STATUS reports the current state of this DOSBox session's + IPX tunnelling network. For a list of all computers connected to the network use the IPXNET PING command. The syntax for IPXNET STATUS is: @@ -572,9 +573,9 @@ For more information use the /? command line switch with the programs. 5. Special Keys: ================ -ALT-ENTER Go full screen and back. +ALT-ENTER Switch to full screen and back. CTRL-F1 Start the keymapper. -CTRL-F4 Swap mounted disk-image. Update directory cache for all drives! +CTRL-F4 Change between mounted disk-images. Update directory cache for all drives! CTRL-F5 Save a screenshot.(png) CTRL-F6 Start/Stop recording sound output to a wave file. CTRL-ALT-F7 Start/Stop recording of OPL commands. @@ -590,13 +591,13 @@ These are the default keybindings. They can be changed in the keymapper. Saved/recorded files can be found in current_directory/capture (can be changed in the configfile). -The directory has to exist prior to starting DOSBox else nothing +The directory has to exist prior to starting DOSBox, otherwise nothing gets saved/recorded ! 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. +This maximum will vary from computer to computer; there is no standard. @@ -608,9 +609,9 @@ When you start the keymapper (either with CTRL-F1 or -startmapper as a commandline argument to the DOSBox executable) you are presented with a virtual keyboard. -This virtual keyboard corresponds with the keys DOSBox will report to its +This virtual keyboard corresponds to the keys DOSBox will report to its applications. If you click on a key with your mouse, you can see in the -lowerleft corner which key on your keyboard corresponds with it. +lower left corner which key on your keyboard corresponds to it. Event: EVENT BIND: BIND @@ -630,35 +631,35 @@ mod1,2,3 BIND. mod1 = CTRL and mod2 = ALT. These are generally only used when you want to change the special keys of DOSBox. Add - Add a new BIND to this EVENT. Basicly add a key from your keyboard which + Add a new BIND to this EVENT. Basically add a key from your keyboard which will produce the key EVENT in DOSBox. Del - Delete the BIND to this EVENT. If an EVENT has no BINDS than it's not + Delete the BIND to this EVENT. If an EVENT has no BINDS, then it's not possible to type this key in DOSBox. Next - Cycle through the list of keys(BINDS) which map to this EVENT. + Go through the list of keys(BINDS) which map to this EVENT. Example: Q1. You want to have the X on your keyboard to type a Z in DOSBox. - A. With your mouse click on the Z on the keyboard mapper. Click "Add". + A. Click on the Z on the keyboard mapper. Click "Add". Now press the X key on your keyboard. -Q2. If you click "Next" a few times you will notice that the Z on your +Q2. If you click "Next" a couple of times, you will notice that the Z on your keyboard also produces an Z in DOSBox. - A. Therefore select the Z again and click "Next" till you have the Z on + A. Therefore select the Z again, and click "Next" until you have the Z on your keyboard. Now click "Del". -Q3. If you try it out in DOSBox you will notice that pressing X makes ZX +Q3. If you try it out in DOSBox, you will notice that pressing X makes ZX appear. A. The X on your keyboard is still mapped to the X as well! Click on - the X in the keyboard mapper and search with "Next" till you find the + the X in the keyboard mapper and search with "Next" until you find the mapped key X. Click "Del". -If you change the default mapping you can save your changes by pressing -"Save". DOSBox will save the mapping to location specified in the configfile -(mapperfile=mapper.txt). At startup DOSBox will load your mapperfile if it's +If you change the default mapping, you can save your changes by pressing +"Save". DOSBox will save the mapping to a location specified in the configfile +(mapperfile=mapper.txt). At startup, DOSBox will load your mapperfile, if it's present in the configfile. @@ -669,8 +670,8 @@ present in the configfile. 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 +For protected mode games a 1 Ghz machine is recommended - don't expect +them to run fast, though! Be sure to read the next section on how to speed it up somewhat. @@ -695,14 +696,14 @@ Overclock DOSBox until 100% of your CPU is used (use the utilities above to check) Since VGA emulation is the most demanding part of DOSBox in terms of actual -CPU usage, we'll start here. Increase the number of frames skipped (in +CPU usage, we'll start there. Increase the number of frames skipped (in increments of one) by pressing CRTL+F8. Your CPU usage should decrease. Go back one step and repeat this until the game runs fast enough for you. -Please note that this is a trade off: you lose in fluidity of video what you +Please note that this is a trade-off: you lose in fluidity of video what you gain in speed You can also try to disable the sound through the setup utility of the game -to further reduce load on your CPU. +to reduce load on your CPU further. @@ -716,7 +717,7 @@ programs section of the readme for usage of CONFIG.COM. You can edit the generated configfile to customize DOSBox. The file is divided into several sections (the names have [] around it). -Some sections have options which you can set. +Some sections have options you can set. # and % indicate comment-lines. The generated configfile contains the current settings. You can alter them and start DOSBox with the -conf switch to load the file and use these settings. @@ -732,10 +733,10 @@ current directory for dosbox.conf. Then it will look for ~/.dosboxrc (Linux), ====================== A language file can be generated by CONFIG.COM. -Read it and you will hopefully understand how to change it. -Start DOSBox with the -lang switch to use your new language file -or you can setup the filename in the config file in the [dosbox] section. -There's a language= entry that can be changed with the filename. +Read it, and you will hopefully understand how to change it. +Start DOSBox with the -lang switch to use your new language file. +Alternatively, you can setup the filename in the config file in the [dosbox] +section. There's a language= entry that can be changed with the filename. @@ -752,9 +753,9 @@ Check the INSTALL in the source distribution. 12. Special Thanks: =================== -Vlad R. of the vdmsound project for excellent sound blaster info. +Vlad R. of the VDMSound project for excellent SoundBlaster info. Tatsuyuki Satoh of the Mame Team for making an excellent FM 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. Pierre-Yves Gérardy for hosting the old Beta Board. Colin Snover for hosting our forum. From 2eb59a43e38ca59657e4fe1fc341420d21312cef Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 21 Nov 2005 18:32:38 +0000 Subject: [PATCH 2300/4131] setup int 23 to point into the rootpsp. Fixes What.exe Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2384 --- src/shell/shell.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 18ef8e2e..7f9028a1 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.65 2005-11-21 07:21:28 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.66 2005-11-21 18:32:38 qbix79 Exp $ */ #include #include @@ -475,6 +475,9 @@ void SHELL_Init() { real_writed(psp_seg+16+1,1,real_readd(0,0x24*4)); real_writed(0,0x24*4,((Bit32u)psp_seg<<16) | ((16+1)<<4)); + /* Set up int 23 to "int 20" in the psp. Fixes what.exe */ + real_writed(0,0x23*4,((Bit32u)psp_seg<<16)); + /* Setup MCB and the environment */ DOS_MCB envmcb((Bit16u)(env_seg-1)); envmcb.SetPSPSeg(psp_seg); From 96bf0e28d6131533c9b520b43ffe743c64f2d060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 24 Nov 2005 17:05:22 +0000 Subject: [PATCH 2301/4131] add error handling for DOS_SetMemAllocStrategy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2385 --- include/dos_inc.h | 4 ++-- src/dos/dos.cpp | 8 ++++++-- src/dos/dos_memory.cpp | 19 +++++++++++-------- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 6cf48b8c..997807dd 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.57 2005-11-07 21:08:11 c2woody Exp $ */ +/* $Id: dos_inc.h,v 1.58 2005-11-24 17:05:19 c2woody Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -156,7 +156,7 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks); bool DOS_FreeMemory(Bit16u segment); void DOS_FreeProcessMemory(Bit16u pspseg); Bit16u DOS_GetMemory(Bit16u pages); -void DOS_SetMemAllocStrategy(Bit16u strat); +bool DOS_SetMemAllocStrategy(Bit16u strat); Bit16u DOS_GetMemAllocStrategy(void); void DOS_BuildUMBChain(const char* use_umbs,bool ems_active); bool DOS_LinkUMBsToMemChain(Bit16u linkstate); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index e16898fe..32d8f693 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.89 2005-11-17 13:16:34 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.90 2005-11-24 17:05:22 c2woody Exp $ */ #include #include @@ -720,7 +720,11 @@ static Bitu DOS_21Handler(void) { reg_ax=DOS_GetMemAllocStrategy(); break; case 1: /* Set Strategy */ - DOS_SetMemAllocStrategy(reg_bx); + if (DOS_SetMemAllocStrategy(reg_bx)) CALLBACK_SCF(false); + else { + reg_ax=1; + CALLBACK_SCF(true); + } break; case 2: /* Get UMB Link Status */ reg_al=dos_infoblock.GetUMBChainState()&1; diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index ebd1ab01..ed30d13b 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -68,17 +68,20 @@ void DOS_FreeProcessMemory(Bit16u pspseg) { } else if (umb_start!=0xffff) LOG(LOG_DOSMISC,LOG_ERROR)("Corrupt UMB chain: %x",umb_start); DOS_CompressMemory(); -}; +} -Bit16u DOS_GetMemAllocStrategy() -{ +Bit16u DOS_GetMemAllocStrategy() { return memAllocStrategy; -}; +} -void DOS_SetMemAllocStrategy(Bit16u strat) -{ - memAllocStrategy = strat; -}; +bool DOS_SetMemAllocStrategy(Bit16u strat) { + if ((strat&0x3f)<3) { + memAllocStrategy = strat; + return true; + } + /* otherwise an invalid allocation strategy was specified */ + return false; +} bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { DOS_CompressMemory(); From 220fe7e462aada8edfc01173f8756966870417fa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Nov 2005 17:53:08 +0000 Subject: [PATCH 2302/4131] Changes for os2 support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2386 --- include/cross.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/cross.h b/include/cross.h index e9b750ed..2ef41136 100644 --- a/include/cross.h +++ b/include/cross.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.h,v 1.13 2005-03-24 10:18:45 qbix79 Exp $ */ +/* $Id: cross.h,v 1.14 2005-11-24 17:53:08 qbix79 Exp $ */ #ifndef DOSBOX_CROSS_H #define DOSBOX_CROSS_H @@ -40,7 +40,7 @@ #define CROSS_LEN 512 /* Maximum filename size */ -#if defined (WIN32) /* Win 32 */ +#if defined (WIN32) || defined (OS2) /* Win 32 */ #define CROSS_FILENAME(blah) #define CROSS_FILESPLIT '\\' #define F_OK 0 From 0539eba66b83a156ad236e6519cd1eeb9758e2ed Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Nov 2005 17:53:48 +0000 Subject: [PATCH 2303/4131] Break is now ctrl-break Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2387 --- src/debug/debug.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 15d95e20..791cc022 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.70 2005-11-17 07:59:02 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.71 2005-11-24 17:53:48 qbix79 Exp $ */ #include #include @@ -1977,7 +1977,7 @@ void DEBUG_Init(Section* sec) { MSG_Add("DEBUG_CONFIGFILE_HELP","Debugger related options.\n"); DEBUG_DrawScreen(); /* Add some keyhandlers */ - MAPPER_AddHandler(DEBUG_Enable,MK_pause,0,"debugger","Debugger"); + MAPPER_AddHandler(DEBUG_Enable,MK_pause,MMOD1,"debugger","Debugger"); /* Clear the TBreakpoint list */ memset((void*)&codeViewData,0,sizeof(codeViewData)); /* setup debug.com */ From ebc9c2c38136da908e57d699c43d93b180b9b9db Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Nov 2005 18:09:47 +0000 Subject: [PATCH 2304/4131] Some changes for os2 support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2388 --- src/dos/dos_programs.cpp | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index baf3a899..53bcd27a 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.45 2005-10-07 15:16:58 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.46 2005-11-24 18:09:47 qbix79 Exp $ */ #include #include @@ -32,6 +32,12 @@ #include "dos_inc.h" #include "bios.h" +#if defined(OS2) +#define INCL DOSFILEMGR +#define INCL_DOSERRORS +#include "os2.h" +#endif + #if C_DEBUG Bitu DEBUG_EnableDebugger(void); #endif @@ -143,13 +149,35 @@ public: if (!temp_line.size()) goto showusage; struct stat test; //Win32 : strip tailing backslashes + //os2: some special drive check //rest: substiture ~ for home -#if defined (WIN32) + bool failed = false; +#if defined (WIN32) || defined(OS2) /* Removing trailing backslash if not root dir so stat will succeed */ if(temp_line.size() > 3 && temp_line[temp_line.size()-1]=='\\') temp_line.erase(temp_line.size()-1,1); if (stat(temp_line.c_str(),&test)) { +#endif +#if defined(WIN32) +// Nothing to do here. +#elif defined (OS2) + if (temp_line.size() <= 2) // Seems to be a drive. + { + failed = true; + HFILE cdrom_fd = 0; + ULONG ulAction = 0; + + APIRET rc = DosOpen((unsigned char*)temp_line.c_str(), &cdrom_fd, &ulAction, 0L, FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS, + OPEN_FLAGS_DASD | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, 0L); + if (rc != NO_ERROR && rc != ERROR_NOT_READY) + { + failed = true; + } else { + failed = false; + } + } + } + if (failed) { #else - bool failed = false; if (stat(temp_line.c_str(),&test)) { failed = true; if(temp_line.size() && temp_line[0] == '~') { From a573488619a18583fa013fc7ff99bb8015e5284b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Nov 2005 18:14:08 +0000 Subject: [PATCH 2305/4131] os2 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2389 --- src/dos/cdrom.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 4cd208e7..76a5d83c 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -166,7 +166,7 @@ int CDROM_GetMountType(char* path, int forceCD) const char* cdName; char buffer[512]; strcpy(buffer,path); -#if defined (WIN32) +#if defined (WIN32) || defined(OS2) upcase(buffer); #endif From 6ed6d775c7365fdb81c3442095a318df5a01ee7e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Nov 2005 18:16:15 +0000 Subject: [PATCH 2306/4131] Fixing possible stack overflow. (thanks Jochen) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2390 --- src/shell/shell_cmds.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 8f816242..4e38d0ab 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.59 2005-10-05 08:58:24 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.60 2005-11-24 18:16:15 qbix79 Exp $ */ #include #include @@ -518,7 +518,7 @@ void DOS_Shell::CMD_COPY(char * args) { if (DOS_CreateFile(nameTarget,0,&targetHandle)) { // Copy - Bit8u buffer[0x8000]; + static Bit8u buffer[0x8000]; // static, otherwise stack overflow possible. bool failed = false; Bit16u toread = 0x8000; do { From 340e59ff7ad43ae283f442a37f0cf028e46a312e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Nov 2005 18:25:20 +0000 Subject: [PATCH 2307/4131] remove unused variable Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2391 --- src/ints/bios.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 22f74b6c..9e761c18 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.49 2005-11-10 18:05:12 c2woody Exp $ */ +/* $Id: bios.cpp,v 1.50 2005-11-24 18:25:20 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -323,7 +323,7 @@ static Bitu INT8_Handler(void) { mem_writed(BIOS_TIMER,mem_readd(BIOS_TIMER)+1); /* decrease floppy motor timer */ Bit8u val = mem_readb(BIOS_DISK_MOTOR_TIMEOUT); - if (val>0) mem_writeb(BIOS_DISK_MOTOR_TIMEOUT,val-1); + if (val) mem_writeb(BIOS_DISK_MOTOR_TIMEOUT,val-1); /* and running drive */ mem_writeb(BIOS_DRIVE_RUNNING,mem_readb(BIOS_DRIVE_RUNNING) & 0xF0); // Save ds,dx,ax @@ -641,8 +641,6 @@ static Bitu INT15_Handler(void) { break; case 0x86: /* BIOS - WAIT (AT,PS) */ { - //TODO Perhaps really wait :) - Bit32u micro=(reg_cx<<16)|reg_dx; if (mem_readb(BIOS_WAIT_FLAG_ACTIVE)) { reg_ah=0x83; CALLBACK_SCF(true); From 45f519d0c226d8f3578d1e8fc4864949335736d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 24 Nov 2005 21:11:45 +0000 Subject: [PATCH 2308/4131] adjust tandy DAC transfer size Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2392 --- src/ints/bios.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 9e761c18..f6fb02ef 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.50 2005-11-24 18:25:20 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.51 2005-11-24 21:11:45 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -133,7 +133,6 @@ static void Tandy_SetupTransfer(PhysPt bufpt,bool isplayback) { /* revector IRQ-handler if necessary */ RealPt current_irq=RealGetVec(tandy_sb.irq+8); if (current_irq!=tandy_DAC_callback->Get_RealPointer()) { - real_writed(0x40,0xd6,current_irq); real_writed(0x40,0xd6,current_irq); RealSetVec(tandy_sb.irq+8,tandy_DAC_callback->Get_RealPointer()); } @@ -155,18 +154,19 @@ static void Tandy_SetupTransfer(PhysPt bufpt,bool isplayback) { case 3: IO_Write(0x82,bufpage); break; } real_writeb(0x40,0xd4,bufpage); + /* calculate transfer size (respects segment boundaries) */ Bit32u tlength=length; if (tlength+(bufpt&0xffff)>0x10000) tlength=0x10000-(bufpt&0xffff); + real_writew(0x40,0xd0,(Bit16u)(length-tlength)); /* remaining buffer length */ + tlength--; + /* set transfer size */ IO_Write(tandy_sb.dma*2+1,(Bit8u)(tlength&0xff)); IO_Write(tandy_sb.dma*2+1,(Bit8u)((tlength>>8)&0xff)); IO_Write(0x0a,tandy_sb.dma); /* enable DMA channel */ - real_writew(0x40,0xd0,(Bit16u)(length-tlength)); /* remaining buffer length */ - Bitu delay=real_readw(0x40,0xd2)&0xfff; - /* set frequency */ IO_Write(tandy_sb.port+0xc,0x40); IO_Write(tandy_sb.port+0xc,256-delay*100/358); From 2c3ae52a795315aa16ae3cc8a199816a8e50ebd2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Nov 2005 19:15:12 +0000 Subject: [PATCH 2309/4131] os2 cdrom support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2393 --- src/dos/Makefile.am | 3 +- src/dos/cdrom.h | 2 +- src/dos/cdrom_ioctl_os2.cpp | 153 ++++++++++++++++++++++++++++++++++++ src/dos/dos_mscdex.cpp | 6 +- 4 files changed, 159 insertions(+), 5 deletions(-) create mode 100644 src/dos/cdrom_ioctl_os2.cpp diff --git a/src/dos/Makefile.am b/src/dos/Makefile.am index 4d206c7b..0beeb4aa 100644 --- a/src/dos/Makefile.am +++ b/src/dos/Makefile.am @@ -6,4 +6,5 @@ libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioc dos_misc.cpp dos_classes.cpp dos_programs.cpp dos_tables.cpp \ drives.cpp drives.h drive_virtual.cpp drive_local.cpp drive_cache.cpp drive_fat.cpp \ drive_iso.cpp dev_con.h dos_mscdex.cpp \ - cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp cdrom_ioctl_linux.cpp cdrom_image.cpp + cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp cdrom_ioctl_linux.cpp cdrom_image.cpp \ + cdrom_ioctl_os2.cpp diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index 173a9c24..705f8429 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -296,7 +296,7 @@ private: #endif /* WIN 32 */ -#if defined (LINUX) +#if defined (LINUX) || defined(OS2) class CDROM_Interface_Ioctl : public CDROM_Interface_SDL { diff --git a/src/dos/cdrom_ioctl_os2.cpp b/src/dos/cdrom_ioctl_os2.cpp new file mode 100644 index 00000000..7374d8f0 --- /dev/null +++ b/src/dos/cdrom_ioctl_os2.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2002-2005 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* $Id: cdrom_ioctl_os2.cpp,v 1.1 2005-11-25 19:15:12 qbix79 Exp $ */ + +#include +#include "dosbox.h" +#include "cdrom.h" + +#if defined (OS2) +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSDEVICES +#define INCL_DOSDEVIOCTL +#include "os2.h" + +// Ripped from linux/cdrom.h +#define CD_FRAMESIZE_RAW 2352 +#define CD_FRAMESIZE 2048 + +CDROM_Interface_Ioctl::CDROM_Interface_Ioctl(void) : CDROM_Interface_SDL(){ + strcpy(device_name, ""); +} + +bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc){ + HFILE cdrom_fd = 0; + ULONG ulAction = 0; + APIRET rc = DosOpen((unsigned char*)device_name, &cdrom_fd, &ulAction, 0L, FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS, + OPEN_FLAGS_DASD | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, 0L); + if (rc != NO_ERROR) { + return false; + } + char data[50]; + ULONG len = sizeof(data); + char sig[] = {'C', 'D', '0', '1'}; + ULONG sigsize = 4; + rc = DosDevIOCtl(cdrom_fd, IOCTL_CDROMDISK, CDROMDISK_GETUPC, sig, sigsize, &sigsize, + data, len, &len); + if (rc != NO_ERROR) { + return false; + } + rc = DosClose(cdrom_fd); + return rc == NO_ERROR; +} + +bool CDROM_Interface_Ioctl::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num){ + HFILE cdrom_fd = 0; + ULONG ulAction = 0; + APIRET rc = DosOpen((unsigned char*)device_name, &cdrom_fd, &ulAction, 0L, FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS, + OPEN_FLAGS_DASD | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, 0L); + if (rc != NO_ERROR) { + return false; + } + + Bitu buflen = raw ? num * CD_FRAMESIZE_RAW : num * CD_FRAMESIZE; + Bit8u* buf = new Bit8u[buflen]; + int ret = NO_ERROR; + + if (raw) { + struct paramseek { + UCHAR sig[4]; + UCHAR mode; + ULONG sec; + + paramseek(ULONG sector) + { + sig[0] = 'C'; sig[1] = 'D'; sig[2] = '0'; sig[3] = '1'; + sec = sector; + } + } param_seek(sector); + ULONG paramsize = sizeof (paramseek); + rc = DosDevIOCtl(cdrom_fd, IOCTL_CDROMDISK, CDROMDISK_SEEK, ¶m_seek, paramsize, ¶msize, + 0, 0, 0); + if (rc != NO_ERROR) { + return false; + } + + struct paramread { + UCHAR sig[4]; + UCHAR mode; + USHORT number; + BYTE sec; + BYTE reserved; + BYTE interleave; + + paramread(USHORT num) + { + sig[0] = 'C'; sig[1] = 'D'; sig[2] = '0'; sig[3] = '1'; + mode = 0; number = num; + sec = interleave = 0; + } + } param_read(num); + paramsize = sizeof (paramread); + ULONG len = buflen; + rc = DosDevIOCtl(cdrom_fd, IOCTL_CDROMDISK, CDROMDISK_READLONG, ¶m_read, paramsize, ¶msize, + buf, len, &len); + if (rc != NO_ERROR) { + return false; + } + } else { + ULONG pos = 0; + rc = DosSetFilePtr(cdrom_fd, sector * CD_FRAMESIZE, FILE_BEGIN, &pos); + if (rc != NO_ERROR) { + return false; + } + ULONG read = 0; + rc = DosRead(cdrom_fd, buf, buflen, &read); + if (rc != NO_ERROR || read != buflen) { + return false; + } + } + rc = DosClose(cdrom_fd); + MEM_BlockWrite(buffer, buf, buflen); + delete[] buf; + + return (ret == NO_ERROR); +} + +bool CDROM_Interface_Ioctl::SetDevice(char* path, int forceCD) { + bool success = CDROM_Interface_SDL::SetDevice(path, forceCD); + + if (success) { + char temp[3] = {0, 0, 0}; + if (path[1] == ':') { + temp[0] = path[0]; + temp[1] = path[1]; + temp[2] = 0; + } + strncpy(device_name, temp, 512); + } else { + strcpy(device_name, ""); + success = false; + } + + return success; +} + +#endif diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index c0871f96..088cc5a1 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.32 2005-09-28 11:21:50 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.33 2005-11-25 19:15:12 qbix79 Exp $ */ #include #include @@ -264,8 +264,8 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) break; } #endif - #if defined (LINUX) - // Always use IOCTL in Linux + #if defined (LINUX) || defined(OS2) + // Always use IOCTL in Linux or OS/2 // if (useCdromInterface==CDROM_USE_IOCTL) { cdrom[numDrives] = new CDROM_Interface_Ioctl(); LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface."); From 6c03551b3804b172b43f0b88fee9cb97caf4f6e5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 28 Nov 2005 16:12:31 +0000 Subject: [PATCH 2310/4131] Some more OS/2 changes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2394 --- src/dos/dos_programs.cpp | 19 +++++++++++++++++-- src/dos/drive_cache.cpp | 20 ++++++++++++++++++-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 53bcd27a..b7a94690 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.46 2005-11-24 18:09:47 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.47 2005-11-28 16:12:30 qbix79 Exp $ */ #include #include @@ -168,6 +168,7 @@ public: APIRET rc = DosOpen((unsigned char*)temp_line.c_str(), &cdrom_fd, &ulAction, 0L, FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_DASD | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, 0L); + DosClose(cdrom_fd); if (rc != NO_ERROR && rc != ERROR_NOT_READY) { failed = true; @@ -193,9 +194,23 @@ public: } /* Not a switch so a normal directory/file */ if (!(test.st_mode & S_IFDIR)) { +#ifdef OS2 + HFILE cdrom_fd = 0; + ULONG ulAction = 0; + + APIRET rc = DosOpen((unsigned char*)temp_line.c_str(), &cdrom_fd, &ulAction, 0L, FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS, + OPEN_FLAGS_DASD | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, 0L); + DosClose(cdrom_fd); + if (rc != NO_ERROR && rc != ERROR_NOT_READY) { WriteOut(MSG_Get("PROGRAM_MOUNT_ERROR_2"),temp_line.c_str()); return; } +#else + WriteOut(MSG_Get("PROGRAM_MOUNT_ERROR_2"),temp_line.c_str()); + return; +#endif + } + if (temp_line[temp_line.size()-1]!=CROSS_FILESPLIT) temp_line+=CROSS_FILESPLIT; Bit8u bit8size=(Bit8u) sizes[1]; if (type=="cdrom") { @@ -914,7 +929,7 @@ void DOS_SetupPrograms(void) { "They can be changed in the \033[33mkeymapper\033[0m.\n" "\n" "\033[33;1mALT-ENTER\033[0m : Go full screen and back.\n" - "\033[33;1mPAUSE\033[0m : Pause DOSBox.\n" + "\033[33;1mCTRL-PAUSE\033[0m : Pause DOSBox.\n" "\033[33;1mCTRL-F1\033[0m : Start the \033[33mkeymapper\033[0m.\n" "\033[33;1mCTRL-F4\033[0m : Update directory cache for all drives! Swap mounted disk-image.\n" "\033[33;1mCTRL-F5\033[0m : Save a screenshot.\n" diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 24fbdb00..f4c6c1c1 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.44 2005-07-19 19:45:31 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.45 2005-11-28 16:12:31 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -34,6 +34,12 @@ #include #endif +#if defined (OS2) +#define INCL_DOSERRORS +#define INCL_DOSFILEMGR +#include +#endif + int fileInfoCounter = 0; bool SortByName(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b) @@ -155,11 +161,21 @@ void DOS_Drive_Cache::SetBaseDir(const char* baseDir) ReadDir(id,result); }; // Get Volume Label -#if defined (WIN32) +#if defined (WIN32) || defined (OS2) char labellocal[256]={ 0 }; char drive[4] = "C:\\"; drive[0] = basePath[0]; +#if defined (WIN32) if (GetVolumeInformation(drive,labellocal,256,NULL,NULL,NULL,NULL,0)) { +#else // OS2 + FSINFO fsinfo; + ULONG drivenumber = drive[0]; + if (drivenumber > 26) { // drive letter was lowercase + drivenumber = drive[0] - 'a' + 1; + } + APIRET rc = DosQueryFSInfo(drivenumber, FSIL_VOLSER, &fsinfo, sizeof(FSINFO)); + if (rc == NO_ERROR) { +#endif /* Set label and allow being updated */ SetLabel(labellocal,true); } From 2e0c766400d64f502a47e6ae12326258f177631d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 28 Nov 2005 16:18:35 +0000 Subject: [PATCH 2311/4131] Add OS/2 directserial support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2395 --- src/hardware/serialport/Makefile.am | 3 +- src/hardware/serialport/directserial_os2.cpp | 418 +++++++++++++++++++ src/hardware/serialport/directserial_os2.h | 86 ++++ src/hardware/serialport/serialport.cpp | 3 +- 4 files changed, 508 insertions(+), 2 deletions(-) create mode 100644 src/hardware/serialport/directserial_os2.cpp create mode 100644 src/hardware/serialport/directserial_os2.h diff --git a/src/hardware/serialport/Makefile.am b/src/hardware/serialport/Makefile.am index dd3633d7..4ae53b23 100644 --- a/src/hardware/serialport/Makefile.am +++ b/src/hardware/serialport/Makefile.am @@ -4,4 +4,5 @@ noinst_LIBRARIES = libserial.a libserial_a_SOURCES = directserial_win32.cpp directserial_win32.h \ serialdummy.cpp serialdummy.h serialport.cpp \ - softmodem.cpp softmodem.h + softmodem.cpp softmodem.h \ + directserial_os2.h directserial_os2.cpp diff --git a/src/hardware/serialport/directserial_os2.cpp b/src/hardware/serialport/directserial_os2.cpp new file mode 100644 index 00000000..5c986154 --- /dev/null +++ b/src/hardware/serialport/directserial_os2.cpp @@ -0,0 +1,418 @@ +/* + * Copyright (C) 2002-2005 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: directserial_os2.cpp,v 1.1 2005-11-28 16:18:35 qbix79 Exp $ */ + +#include "dosbox.h" + +#if C_DIRECTSERIAL + + +#if defined(OS2) +#include "serialport.h" +#include "directserial_os2.h" + +// OS/2 related headers +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSDEVICES +#define INCL_DOSDEVIOCTL +#define INCL_DOSPROCESS +#include + +/* This is a serial passthrough class. Its amazingly simple to */ +/* write now that the serial ports themselves were abstracted out */ + +CDirectSerial::CDirectSerial (IO_ReadHandler * rh, IO_WriteHandler * wh, + TIMER_TickHandler th, Bit16u baseAddr, Bit8u initIrq, + Bit32u initBps, Bit8u bytesize, const char *parity, + Bit8u stopbits,const char *realPort) + :CSerial (rh, wh, th,baseAddr,initIrq, initBps, + bytesize, parity,stopbits) { + InstallationSuccessful = false; + InstallTimerHandler(th); + lastChance = 0; + LOG_MSG ("OS/2 Serial port at %x: Opening %s", base, realPort); + LOG_MSG("Opening OS2 serial port"); + + ULONG ulAction = 0; + APIRET rc = DosOpen((unsigned char*)realPort, &hCom, &ulAction, 0L, FILE_NORMAL, FILE_OPEN, + OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | OPEN_FLAGS_SEQUENTIAL, 0L); + if (rc != NO_ERROR) + { + LOG_MSG ("Serial port \"%s\" could not be opened.", realPort); + if (rc == 2) { + LOG_MSG ("The specified port does not exist."); + } else if (rc == 99) { + LOG_MSG ("The specified port is already in use."); + } else { + LOG_MSG ("OS/2 error %d occurred.", rc); + } + + hCom = 0; + return; + } + + DCBINFO dcb; + ULONG ulParmLen = sizeof(DCBINFO); + rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &dcb, ulParmLen, &ulParmLen); + if ( rc != NO_ERROR) + { + DosClose(hCom); + hCom = 0; + return; + } + dcb.usWriteTimeout = 0; + dcb.usReadTimeout = 0; //65535; + dcb.fbTimeout |= 6; + rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0); + if ( rc != NO_ERROR) + { + DosClose(hCom); + hCom = 0; + return; + } + + CSerial::Init_Registers (initBps, bytesize, parity, stopbits); + InstallationSuccessful = true; + //LOG_MSG("InstSuccess"); +} + +CDirectSerial::~CDirectSerial () { + if (hCom != 0) + DosClose (hCom); +} + +Bitu lastChance; + +void CDirectSerial::RXBufferEmpty () { + ULONG dwRead; + Bit8u chRead; + USHORT errors = 0; + ULONG ulParmLen = sizeof(errors); + + if (lastChance > 0) { + receiveByte (ChanceChar); + lastChance = 0; + } else { + // update RX + if (DosRead (hCom, &chRead, 1, &dwRead) != NO_ERROR) { + if (dwRead != 0) { + //LOG_MSG("UART 0x%x: RX 0x%x", base,chRead); + receiveByte (chRead); + } + } + } + // check for errors + Bit8u errreg = 0; + APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMERROR, 0, 0, 0, &errors, ulParmLen, &ulParmLen); + if (rc != NO_ERROR && errors) + { + if (errors & 8) { + LOG_MSG ("Serial port at 0x%x: line error: framing error.", base); + errreg |= LSR_FRAMING_ERROR_MASK; + } + if (errors & 4) { + LOG_MSG ("Serial port at 0x%x: line error: parity error.", base); + errreg |= LSR_PARITY_ERROR_MASK; + } + } + errors = 0; + rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMEVENT, 0, 0, 0, &errors, ulParmLen, &ulParmLen); + if (rc != NO_ERROR && errors) + { + if (errors & 6) { + LOG_MSG ("Serial port at 0x%x: line error: break received.", base); + errreg |= LSR_RX_BREAK_MASK; + } + } + if (errreg != 0) + { + receiveError (errreg); + } + +} + +/*****************************************************************************/ +/* updatePortConfig is called when emulated app changes the serial port **/ +/* parameters baudrate, stopbits, number of databits, parity. **/ +/*****************************************************************************/ +void CDirectSerial::updatePortConfig (Bit8u dll, Bit8u dlm, Bit8u lcr) { + Bit8u parity = 0; + Bit8u bytelength = 0; + Bit16u baudrate = 0, baud = 0; + + // baud + baudrate = dlm; + baudrate = baudrate << 8; + baudrate |= dll; + if (baudrate <= 0x1) + baud = 115200; + else if (baudrate <= 0x2) + baud = 57600; + else if (baudrate <= 0x3) + baud = 38400; + else if (baudrate <= 0x6) + baud = 19200; + else if (baudrate <= 0xc) + baud = 9600; + else if (baudrate <= 0x18) + baud = 4800; + else if (baudrate <= 0x30) + baud = 2400; + else if (baudrate <= 0x60) + baud = 1200; + else if (baudrate <= 0xc0) + baud = 600; + else if (baudrate <= 0x180) + baud = 300; + else if (baudrate <= 0x417) + baud = 110; + + // I read that windows can handle nonstandard baudrates: + else + baud = 115200 / baudrate; + +#ifdef SERIALPORT_DEBUGMSG + LOG_MSG ("Serial port at %x: new baud rate: %d", base, dcb.BaudRate); +#endif + + struct { + ULONG baud; + BYTE fraction; + } setbaud; + setbaud.baud = baud; + setbaud.fraction = 0; + ULONG ulParmLen = sizeof(setbaud); + APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_EXTSETBAUDRATE, &setbaud, ulParmLen, &ulParmLen, 0, 0, 0); + if (rc != NO_ERROR) + { + } + + + struct { + UCHAR data; + UCHAR parity; + UCHAR stop; + } paramline; + + // byte length + bytelength = lcr & 0x3; + bytelength += 5; + paramline.data = bytelength; + + // parity + parity = lcr & 0x38; + parity = parity >> 3; + switch (parity) { + case 0x1: + paramline.parity = 1; + break; + case 0x3: + paramline.parity = 2; + break; + case 0x5: + paramline.parity = 3; + break; + case 0x7: + paramline.parity = 4; + break; + default: + paramline.parity = 0; + break; + } + + // stopbits + if (lcr & 0x4) { + if (bytelength == 5) + paramline.stop = 1; + else + paramline.stop = 2; + } else { + paramline.stop = 0; + } + + + ulParmLen = sizeof(paramline); + rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETLINECTRL, ¶mline, ulParmLen, &ulParmLen, 0, 0, 0); + if ( rc != NO_ERROR) + { + LOG_MSG ("Serial port at 0x%x: API did not like the new values.", base); + } + +} + +void CDirectSerial::updateMSR () { + Bit8u newmsr = 0; + UCHAR dptr = 0; + ULONG ulParmLen = sizeof(dptr); + + APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETMODEMINPUT, &dptr, ulParmLen, &ulParmLen, 0, 0, 0); + if (rc != NO_ERROR) { +#ifdef SERIALPORT_DEBUGMSG +// LOG_MSG ("Serial port at %x: GetCommModemStatus failed!", base); +#endif + //return; + } + if (dptr & 16) + newmsr |= MSR_CTS_MASK; + if (dptr & 32) + newmsr |= MSR_DSR_MASK; + if (dptr & 64) + newmsr |= MSR_RI_MASK; + if (dptr & 128) + newmsr |= MSR_CD_MASK; + changeMSR (newmsr); +} + +void CDirectSerial::transmitByte (Bit8u val) { + // mean bug: with break = 1, WriteFile will never return. + ULONG bytesWritten = 0; + APIRET rc = DosWrite (hCom, &val, 1, &bytesWritten); + if (rc == NO_ERROR && bytesWritten > 0) { + ByteTransmitted (); + //LOG_MSG("UART 0x%x: TX 0x%x", base,val); + } else { + LOG_MSG ("UART 0x%x: NO BYTE WRITTEN!", base); + } +} + +/*****************************************************************************/ +/* setBreak(val) switches break on or off **/ +/*****************************************************************************/ + +void CDirectSerial::setBreak (bool value) { + //#ifdef SERIALPORT_DEBUGMSG + //LOG_MSG("UART 0x%x: Break toggeled: %d", base, value); + //#endif + USHORT error; + ULONG ulParmLen = sizeof(error); + if (value) + DosDevIOCtl (hCom, IOCTL_ASYNC, ASYNC_SETBREAKON, 0,0,0, &error, ulParmLen, &ulParmLen); + else + DosDevIOCtl (hCom, IOCTL_ASYNC, ASYNC_SETBREAKOFF, 0,0,0, &error, ulParmLen, &ulParmLen); +} + +/*****************************************************************************/ +/* updateModemControlLines(mcr) sets DTR and RTS. **/ +/*****************************************************************************/ +void CDirectSerial::updateModemControlLines ( /*Bit8u mcr */ ) { + bool change = false; + DCBINFO dcb; + ULONG ulParmLen = sizeof(dcb); + + DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &dcb, ulParmLen, &ulParmLen); + + /*** DTR ***/ + if (CSerial::getDTR ()) { // DTR on + if (dcb.fbCtlHndShake && 3 == 0) { // DTR disabled + dcb.fbCtlHndShake |= 1; + change = true; + } + } else { + if (dcb.fbCtlHndShake && 3 == 1) { // DTR enabled + dcb.fbCtlHndShake &= ~3; + change = true; + } + } + /*** RTS ***/ + if (CSerial::getRTS ()) { // RTS on + if (dcb.fbFlowReplace && 192 == 0) { //RTS disabled + dcb.fbFlowReplace |= 64; + change = true; + } + } else { + if (dcb.fbFlowReplace && 192 == 1) { // RTS enabled + dcb.fbFlowReplace &= ~192; + change = true; + } + } + if (change) + DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0); +} + +void CDirectSerial::Timer2(void) { + ULONG dwRead = 0; + USHORT errors = 0; + Bit8u chRead = 0; + ULONG ulParmLen = sizeof(errors); + + + if (lastChance == 0) { // lastChance = 0 + if (CanReceiveByte ()) { + if (DosRead (hCom, &chRead, 1, &dwRead)) { + if (dwRead) + receiveByte (chRead); + } + } else { + if (DosRead (hCom, &chRead, 1, &dwRead)) { + if (dwRead) { + ChanceChar = chRead; + lastChance++; + } + } + } + } else if (lastChance > 10) { + receiveByte (0); // this causes RX Overrun now + lastChance = 0; + // empty serial buffer + dwRead = 1; + while (dwRead > 0) { // throw away bytes in buffer + DosRead (hCom, &chRead, 1, &dwRead); + } + } else { // lastChance>0 // already one waiting + if (CanReceiveByte ()) { // chance used + receiveByte (ChanceChar); + lastChance = 0; + } else + lastChance++; + } + + // check for errors + Bit8u errreg = 0; + APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMERROR, 0, 0, 0, &errors, ulParmLen, &ulParmLen); + if (rc != NO_ERROR && errors) + { + if (errors & 8) { + LOG_MSG ("Serial port at 0x%x: line error: framing error.", base); + errreg |= LSR_FRAMING_ERROR_MASK; + } + if (errors & 4) { + LOG_MSG ("Serial port at 0x%x: line error: parity error.", base); + errreg |= LSR_PARITY_ERROR_MASK; + } + } + errors = 0; + rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMEVENT, 0, 0, 0, &errors, ulParmLen, &ulParmLen); + if (rc != NO_ERROR && errors) + { + if (errors & 6) { + LOG_MSG ("Serial port at 0x%x: line error: break received.", base); + errreg |= LSR_RX_BREAK_MASK; + } + } + if (errreg != 0) + { + receiveError (errreg); + } + // update Modem input line states + updateMSR (); +} + +#endif +#endif diff --git a/src/hardware/serialport/directserial_os2.h b/src/hardware/serialport/directserial_os2.h new file mode 100644 index 00000000..431c1519 --- /dev/null +++ b/src/hardware/serialport/directserial_os2.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2002-2005 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: directserial_os2.h,v 1.1 2005-11-28 16:18:35 qbix79 Exp $ */ + +// include guard +#ifndef DOSBOX_DIRECTSERIAL_OS2_H +#define DOSBOX_DIRECTSERIAL_OS2_H + +#include "dosbox.h" + +#if C_DIRECTSERIAL +#if defined(OS2) +#define DIRECTSERIAL_AVAILIBLE +#include "serialport.h" +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSDEVICES +#define INCL_DOSDEVIOCTL +#define INCL_DOSPROCESS +#include + +class CDirectSerial : public CSerial { +public: + HFILE hCom; + BOOL fSuccess; + + CDirectSerial( + IO_ReadHandler* rh, + IO_WriteHandler* wh, + TIMER_TickHandler th, + Bit16u baseAddr, + Bit8u initIrq, + Bit32u initBps, + Bit8u bytesize, + const char *parity, + Bit8u stopbits, + const char * realPort + ); + + + ~CDirectSerial(); + + + Bitu lastChance; // If there is no space for new + // received data, it gets a little chance + Bit8u ChanceChar; + + bool CanRecv(void); + bool CanSend(void); + + bool InstallationSuccessful; // check after constructing. If + // something was wrong, delete it right away. + + void RXBufferEmpty(); + + + void updatePortConfig(Bit8u dll, Bit8u dlm, Bit8u lcr); + void updateMSR(); + void transmitByte(Bit8u val); + void setBreak(bool value); + void updateModemControlLines(/*Bit8u mcr*/); + void Timer2(void); + + +}; +#endif // IFDEF + +#endif // C_DIRECTSERIAL +#endif // include guard + diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index d57f6d4f..ade40bd0 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.cpp,v 1.2 2005-11-04 08:53:07 qbix79 Exp $ */ +/* $Id: serialport.cpp,v 1.3 2005-11-28 16:18:35 qbix79 Exp $ */ #include #include @@ -31,6 +31,7 @@ #include "serialport.h" #include "directserial_win32.h" +#include "directserial_os2.h" #include "serialdummy.h" #include "softmodem.h" From 241e89b1757a226623370a2fad6835ff5437c70f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 29 Nov 2005 07:25:30 +0000 Subject: [PATCH 2312/4131] GCC 4.1 changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2396 --- include/cross.h | 4 +-- include/ipx.h | 4 +-- include/serialport.h | 72 ++++++++++++++++++++++---------------------- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/include/cross.h b/include/cross.h index 2ef41136..1258ee30 100644 --- a/include/cross.h +++ b/include/cross.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.h,v 1.14 2005-11-24 17:53:08 qbix79 Exp $ */ +/* $Id: cross.h,v 1.15 2005-11-29 07:25:30 qbix79 Exp $ */ #ifndef DOSBOX_CROSS_H #define DOSBOX_CROSS_H @@ -40,7 +40,7 @@ #define CROSS_LEN 512 /* Maximum filename size */ -#if defined (WIN32) || defined (OS2) /* Win 32 */ +#if defined (WIN32) || defined (OS2) /* Win 32 & OS/2*/ #define CROSS_FILENAME(blah) #define CROSS_FILESPLIT '\\' #define F_OK 0 diff --git a/include/ipx.h b/include/ipx.h index 314c80a7..8b882456 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.h,v 1.6 2005-07-30 10:02:39 qbix79 Exp $ */ +/* $Id: ipx.h,v 1.7 2005-11-29 07:25:30 qbix79 Exp $ */ #ifndef DOSBOX_IPX_H #define DOSBOX_IPX_H @@ -106,7 +106,7 @@ public: Bitu SerialNumber; #endif - ECBClass::ECBClass(Bit16u segment, Bit16u offset); + ECBClass(Bit16u segment, Bit16u offset); Bit16u getSocket(void); Bit8u getInUseFlag(void); diff --git a/include/serialport.h b/include/serialport.h index 9a2ce162..aac0b4c5 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.h,v 1.10 2005-11-04 08:53:06 qbix79 Exp $ */ +/* $Id: serialport.h,v 1.11 2005-11-29 07:25:30 qbix79 Exp $ */ #ifndef DOSBOX_SERIALPORT_H #define DOSBOX_SERIALPORT_H @@ -59,50 +59,50 @@ public: Bitu base; Bitu irq; - bool CSerial::getDTR(); - bool CSerial::getRTS(); + bool getDTR(); + bool getRTS(); - bool CSerial::getRI(); - bool CSerial::getCD(); - bool CSerial::getDSR(); - bool CSerial::getCTS(); + bool getRI(); + bool getCD(); + bool getDSR(); + bool getCTS(); - void CSerial::setRI(bool value); - void CSerial::setDSR(bool value); - void CSerial::setCD(bool value); - void CSerial::setCTS(bool value); + void setRI(bool value); + void setDSR(bool value); + void setCD(bool value); + void setCTS(bool value); - void CSerial::Write_THR(Bit8u data); - Bitu CSerial::Read_RHR(); - Bitu CSerial::Read_IER(); - void CSerial::Write_IER(Bit8u data); - Bitu CSerial::Read_ISR(); - Bitu CSerial::Read_LCR(); - void CSerial::Write_LCR(Bit8u data); - Bitu CSerial::Read_MCR(); - void CSerial::Write_MCR(Bit8u data); - Bitu CSerial::Read_LSR(); + void Write_THR(Bit8u data); + Bitu Read_RHR(); + Bitu Read_IER(); + void Write_IER(Bit8u data); + Bitu Read_ISR(); + Bitu Read_LCR(); + void Write_LCR(Bit8u data); + Bitu Read_MCR(); + void Write_MCR(Bit8u data); + Bitu Read_LSR(); // Really old hardware seems to have the delta part of this register writable - void CSerial::Write_MSR(Bit8u data); + void Write_MSR(Bit8u data); - Bitu CSerial::Read_MSR(); - Bitu CSerial::Read_SPR(); - void CSerial::Write_SPR(Bit8u data); - void CSerial::Write_reserved(Bit8u data, Bit8u address); + Bitu Read_MSR(); + Bitu Read_SPR(); + void Write_SPR(Bit8u data); + void Write_reserved(Bit8u data, Bit8u address); // If a byte comes from wherever(loopback or real port or maybe // that softmodem thingy), put it in here. - void CSerial::receiveByte(Bit8u data); + void receiveByte(Bit8u data); // If an error was received, put it here (in LSR register format) - void CSerial::receiveError(Bit8u errorword); + void receiveError(Bit8u errorword); // connected device checks, if port can receive data: - bool CSerial::CanReceiveByte(); + bool CanReceiveByte(); // When done sending, notify here - void CSerial::ByteTransmitted(); + void ByteTransmitted(); // Virtual app has read the received data virtual void RXBufferEmpty()=0; @@ -124,24 +124,24 @@ public: // after update request, or some "real" changes, // modify MSR here - void CSerial::changeMSR(Bit8u data); // make public + void changeMSR(Bit8u data); // make public - void CSerial::Init_Registers(Bit32u initbps, + void Init_Registers(Bit32u initbps, Bit8u bytesize, const char* parity, Bit8u stopbits); private: // I used this spec: http://www.exar.com/products/st16c450v420.pdf - void CSerial::changeMSR_Loopback(Bit8u data); + void changeMSR_Loopback(Bit8u data); - void CSerial::WriteRealIER(Bit8u data); + void WriteRealIER(Bit8u data); // reason for an interrupt has occured - functions triggers interrupt // if it is enabled and no higher-priority irq pending - void CSerial::rise(Bit8u priority); + void rise(Bit8u priority); // clears the pending interrupt - void CSerial::clear(Bit8u priority); + void clear(Bit8u priority); #define ERROR_PRIORITY 4 // overrun, parity error, frame error, break #define RX_PRIORITY 1 // a byte has been received From 19f535dbb8854a82656fc508bf523e5c6ea7cfbf Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 Dec 2005 10:02:03 +0000 Subject: [PATCH 2313/4131] OS/2 support. windib workaround from with in DOSBox. pause changed to ctrl-pause. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2397 --- src/gui/sdlmain.cpp | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 78e22792..3f189057 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.93 2005-11-08 19:41:04 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.94 2005-12-02 10:02:03 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -117,6 +117,12 @@ struct private_hwdata { #define PRIO_TOTAL (PRIO_MAX-PRIO_MIN) #endif +#ifdef OS2 +#define INCL_DOS +#define INCL_WIN +#include +#endif + enum SCREEN_TYPES { SCREEN_SURFACE, SCREEN_SURFACE_DDRAW, @@ -335,6 +341,15 @@ static SDL_Surface * GFX_SetupSurfaceScaled(Bit32u sdl_flags,Bit32u bpp) { sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex*sdl.desktop.hwscale); sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley*sdl.desktop.hwscale); sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags|SDL_HWSURFACE); +#ifdef WIN32 + if (sdl.surface == NULL) { + LOG_MSG("Failed to create hardware surface.\nRestarting video subsystem with windib enabled."); + SDL_QuitSubSystem(SDL_INIT_VIDEO); + putenv("SDL_VIDEODRIVER=windib"); + SDL_InitSubSystem(SDL_INIT_VIDEO); + sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags|SDL_HWSURFACE); + } +#endif if (sdl.surface == NULL) E_Exit("Could not set windowed video mode %ix%i-%i: %s",sdl.clip.w,sdl.clip.h,bpp,SDL_GetError()); return sdl.surface; } @@ -375,7 +390,16 @@ dosurface: } } else { sdl.clip.x=0;sdl.clip.y=0; - sdl.surface=SDL_SetVideoMode(width,height,bpp,SDL_HWSURFACE); + sdl.surface = SDL_SetVideoMode(width,height,bpp,SDL_HWSURFACE); +#ifdef WIN32 + if (sdl.surface == NULL) { + LOG_MSG("Failed to create hardware surface.\nRestarting video subsystem with windib enabled."); + SDL_QuitSubSystem(SDL_INIT_VIDEO); + putenv("SDL_VIDEODRIVER=windib"); + SDL_InitSubSystem(SDL_INIT_VIDEO); + sdl.surface = SDL_SetVideoMode(width,height,bpp,SDL_HWSURFACE); + } +#endif if (sdl.surface == NULL) E_Exit("Could not set windowed video mode %ix%i-%i: %s",width,height,bpp,SDL_GetError()); } if (sdl.surface) switch (sdl.surface->format->BitsPerPixel) { @@ -913,7 +937,7 @@ static void GUI_StartUp(Section * sec) { #if C_DEBUG /* Pause binds with activate-debugger */ #else - MAPPER_AddHandler(PauseDOSBox,MK_pause,0,"pause","Pause"); + MAPPER_AddHandler(PauseDOSBox,MK_pause,MMOD1,"pause","Pause"); #endif /* Get Keyboard state of numlock and capslock */ SDLMod keystate = SDL_GetModState(); @@ -1077,6 +1101,16 @@ int main(int argc, char* argv[]) { #if C_DEBUG DEBUG_SetupConsole(); #endif + +#ifdef OS2 + PPIB pib; + PTIB tib; + DosGetInfoBlocks(&tib, &pib); + if (pib->pib_ultype == 2) pib->pib_ultype = 3; + setbuf(stdout, NULL); + setbuf(stderr, NULL); +#endif + if ( SDL_Init( SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM #ifndef DISABLE_JOYSTICK |SDL_INIT_JOYSTICK From 24b045e69fd26f1ec9781afc03544b374a503059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 2 Dec 2005 13:10:18 +0000 Subject: [PATCH 2314/4131] change tandy machine definition a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2398 --- include/dosbox.h | 4 ++++ src/hardware/tandy_sound.cpp | 2 +- src/hardware/vga_draw.cpp | 4 ++-- src/hardware/vga_memory.cpp | 2 +- src/hardware/vga_misc.cpp | 2 +- src/hardware/vga_other.cpp | 8 ++++---- src/ints/bios.cpp | 17 ++++++++++++----- src/ints/int10.cpp | 13 +++++++------ src/ints/int10.h | 1 + src/ints/int10_char.cpp | 4 ++-- src/ints/int10_modes.cpp | 4 ++-- src/ints/int10_pal.cpp | 23 +++++++++++++---------- 12 files changed, 50 insertions(+), 34 deletions(-) diff --git a/include/dosbox.h b/include/dosbox.h index 8adc942d..51017f56 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -43,12 +43,16 @@ enum MachineType { MCH_HERC, MCH_CGA, MCH_TANDY, + MCH_PCJR, MCH_VGA }; extern MachineType machine; extern bool SDLNetInited; +#define IS_TANDY_ARCH ((machine==MCH_TANDY) || (machine==MCH_PCJR)) +#define TANDY_ARCH_CASE MCH_TANDY: case MCH_PCJR + #ifndef DOSBOX_LOGGING_H #include "logging.h" #endif // the logging system. diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 33ffd8e1..49e0f87f 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -316,7 +316,7 @@ public: Section_prop * section=static_cast(configuration); real_writeb(0x40,0xd4,0x00); - if (machine==MCH_TANDY) { + if (IS_TANDY_ARCH) { /* enable tandy sound if tandy=true/auto */ if ((strcmp(section->Get_string("tandy"),"true")!=0) && (strcmp(section->Get_string("tandy"),"on")!=0) && diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index f826839e..1569b2bc 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -313,7 +313,7 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.address=(vga.draw.address*2)&0x1fff; break; } - if (machine==MCH_TANDY) { + if (IS_TANDY_ARCH) { vga.draw.address+=vga.tandy.disp_bank << 14; vga.draw.cursor.address+=vga.tandy.disp_bank << 14; } @@ -418,7 +418,7 @@ void VGA_SetupDrawing(Bitu val) { vga.draw.double_scan=false; switch (machine) { case MCH_CGA: - case MCH_TANDY: + case TANDY_ARCH_CASE: clock=((vga.tandy.mode_control & 1) ? 14318180 : (14318180/2))/8; break; case MCH_HERC: diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index d2b46e43..88cbc4b2 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -457,7 +457,7 @@ void VGA_SetupHandlers(void) { range_handler=&vgaph.hmap; if (vga.herc.mode_control&0x80) goto range_b800; else goto range_b000; - case MCH_TANDY: + case TANDY_ARCH_CASE: range_handler=&vgaph.htandy; MEM_SetPageHandler(0x80,32,range_handler); goto range_b800; diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 92495588..1f96bcda 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -119,7 +119,7 @@ void VGA_SetupMisc(void) { IO_RegisterReadHandler(0x3c2,read_p3c2,IO_MB); IO_RegisterWriteHandler(0x3c2,write_p3c2,IO_MB); IO_RegisterReadHandler(0x3cc,read_p3cc,IO_MB); - } else if (machine==MCH_CGA || machine==MCH_TANDY) { + } else if (machine==MCH_CGA || IS_TANDY_ARCH) { IO_RegisterReadHandler(0x3da,read_p3da,IO_MB); } else if (machine==MCH_HERC) { IO_RegisterReadHandler(0x3ba,read_p3da,IO_MB); diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 904e34a0..13e7f854 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -191,7 +191,7 @@ static void write_color_select(Bit8u val) { break; case M_TANDY4: { - if (machine == MCH_TANDY && (vga.tandy.gfx_control & 0x8)) { + if (IS_TANDY_ARCH && (vga.tandy.gfx_control & 0x8)) { VGA_SetCGA4Table(0,1,2,3); return; } @@ -342,7 +342,7 @@ static Bitu read_hercules(Bitu port,Bitu iolen) { void VGA_SetupOther(void) { Bitu i; - if (machine==MCH_CGA || machine==MCH_TANDY) { + if (machine==MCH_CGA || IS_TANDY_ARCH) { extern Bit8u int10_font_08[256 * 8]; for (i=0;i<256;i++) memcpy(&vga.draw.font[i*32],&int10_font_08[i*8],8); vga.draw.font_tables[0]=vga.draw.font_tables[1]=vga.draw.font; @@ -362,14 +362,14 @@ void VGA_SetupOther(void) { IO_RegisterWriteHandler(0x3b8,write_hercules,IO_MB); IO_RegisterWriteHandler(0x3bf,write_hercules,IO_MB); } - if (machine==MCH_TANDY) { + if (IS_TANDY_ARCH) { IO_RegisterWriteHandler(0x3d8,write_tandy,IO_MB); IO_RegisterWriteHandler(0x3d9,write_tandy,IO_MB); IO_RegisterWriteHandler(0x3de,write_tandy,IO_MB); IO_RegisterWriteHandler(0x3df,write_tandy,IO_MB); IO_RegisterWriteHandler(0x3da,write_tandy,IO_MB); } - if (machine==MCH_CGA || machine==MCH_HERC || machine==MCH_TANDY) { + if (machine==MCH_CGA || machine==MCH_HERC || IS_TANDY_ARCH) { Bitu base=machine==MCH_HERC ? 0x3b4 : 0x3d4; IO_RegisterWriteHandler(base,write_crtc_index_other,IO_MB); IO_RegisterWriteHandler(base+1,write_crtc_data_other,IO_MB); diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index f6fb02ef..76f8191f 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.51 2005-11-24 21:11:45 c2woody Exp $ */ +/* $Id: bios.cpp,v 1.52 2005-12-02 13:10:18 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -560,8 +560,14 @@ static Bitu INT15_Handler(void) { if (biosConfigSeg==0) biosConfigSeg = DOS_GetMemory(1); //We have 16 bytes PhysPt data = PhysMake(biosConfigSeg,0); mem_writew(data,8); // 8 Bytes following - if (machine==MCH_TANDY) { - mem_writeb(data+2,0xFF); // Model ID (Tandy) + if (IS_TANDY_ARCH) { + if (machine==MCH_TANDY) { + // Model ID (Tandy) + mem_writeb(data+2,0xFF); + } else { + // Model ID (PCJR) + mem_writeb(data+2,0xFD); + } mem_writeb(data+3,0x0A); // Submodel ID mem_writeb(data+4,0x10); // Bios Revision /* Tandy doesn't have a 2nd PIC, left as is for now */ @@ -854,7 +860,8 @@ public: callback[8].Install(&INT70_Handler,CB_IRET,"Int 70 RTC"); callback[8].Set_RealVec(0x70); - if (machine==MCH_TANDY) phys_writeb(0xffffe,0xff); /* Tandy model */ + if (machine==MCH_TANDY) phys_writeb(0xffffe,0xff) ; /* Tandy model */ + else if (machine==MCH_PCJR) phys_writeb(0xffffe,0xfd); /* PCJr model */ else phys_writeb(0xffffe,0xfc); /* PC */ if (use_tandyDAC) { @@ -940,7 +947,7 @@ public: break; case MCH_VGA: case MCH_CGA: - case MCH_TANDY: + case TANDY_ARCH_CASE: //Startup 80x25 color config|=0x20; break; diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 5ca6781e..27dcc17a 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -68,7 +68,7 @@ static Bitu INT10_Handler(void) { reg_ah=0; break; case 0x05: /* Set Active Page */ - if (reg_al & 0x80 && machine==MCH_TANDY) { + if (reg_al & 0x80 && IS_TANDY_ARCH) { Bit8u crtcpu=real_readb(BIOSMEM_SEG, BIOSMEM_CRTCPU_PAGE); switch (reg_al) { case 0x80: @@ -519,16 +519,17 @@ static void SetupTandyBios(void) { 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x73, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x0d, 0x0a, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x61, 0x6e, 0x64, 0x79 }; - Bitu i; - phys_writeb(0xffffe,0xff); - for(i=0;i<130;i++) { - phys_writeb(0xf0000+i+0xc000, TandyConfig[i]); + if (machine==MCH_TANDY) { + Bitu i; + for(i=0;i<130;i++) { + phys_writeb(0xf0000+i+0xc000, TandyConfig[i]); + } } } void INT10_Init(Section* sec) { INT10_InitVGA(); - if (machine==MCH_TANDY) SetupTandyBios(); + if (IS_TANDY_ARCH) SetupTandyBios(); /* Setup the INT 10 vector */ call_10=CALLBACK_Allocate(); CALLBACK_Setup(call_10,&INT10_Handler,CB_IRET,"Int 10 video"); diff --git a/src/ints/int10.h b/src/ints/int10.h index bc769198..7f5baf4a 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -81,6 +81,7 @@ #define VGAREG_TDY_RESET 0x3da #define VGAREG_TDY_ADDRESS 0x3da #define VGAREG_TDY_DATA 0x3de +#define VGAREG_PCJR_DATA 0x3da #define VGAREG_MDA_MODECTL 0x3b8 #define VGAREG_CGA_MODECTL 0x3d8 diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 9df3c0ca..09ae940f 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.41 2005-11-12 14:17:36 c2woody Exp $ */ +/* $Id: int10_char.cpp,v 1.42 2005-12-02 13:10:18 c2woody Exp $ */ /* Character displaying moving functions */ @@ -299,7 +299,7 @@ void INT10_SetActivePage(Bit8u page) { void INT10_SetCursorShape(Bit8u first,Bit8u last) { real_writew(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE,last|(first<<8)); if (machine==MCH_CGA) goto dowrite; - if (machine==MCH_TANDY) goto dowrite; + if (IS_TANDY_ARCH) goto dowrite; /* Skip CGA cursor emulation if EGA/VGA system is active */ if (!(real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL) & 0x8)) { /* Check for CGA type 01, invisible */ diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 925e63c5..a64c2537 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -257,7 +257,7 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { switch (machine) { case MCH_CGA: if (mode>6) return false; - case MCH_TANDY: + case TANDY_ARCH_CASE: if (mode>0xa) return false; if (!SetCurMode(ModeList_OTHER,mode)) { LOG(LOG_INT10,LOG_ERROR)("Trying to set illegal mode %X",mode); @@ -336,7 +336,7 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,mode_control); real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select); break; - case MCH_TANDY: + case TANDY_ARCH_CASE: /* Init some registers */ IO_WriteB(0x3da,0x1);IO_WriteB(0x3de,0xf); //Palette mask always 0xf IO_WriteB(0x3da,0x2);IO_WriteB(0x3de,0x0); //block border diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index ed13342f..2011d98f 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -27,12 +27,17 @@ static INLINE void ResetACTL(void) { IO_Read(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS) + 6); } +static INLINE void WriteTandyACTL(Bit8u creg,Bit8u val) { + IO_Write(VGAREG_TDY_ADDRESS,creg); + if (machine==MCH_TANDY) IO_Write(VGAREG_TDY_DATA,val); + else IO_Write(VGAREG_PCJR_DATA,val); +} + void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val) { switch (machine) { - case MCH_TANDY: + case TANDY_ARCH_CASE: IO_Read(VGAREG_TDY_RESET); - IO_Write(VGAREG_TDY_ADDRESS,reg+0x10); - IO_Write(VGAREG_TDY_DATA,val); + WriteTandyACTL(reg+0x10,val); break; case MCH_VGA: if(reg<=ACTL_MAX_REG) { @@ -55,17 +60,15 @@ void INT10_SetOverscanBorderColor(Bit8u val) { void INT10_SetAllPaletteRegisters(PhysPt data) { switch (machine) { - case MCH_TANDY: + case TANDY_ARCH_CASE: IO_Read(VGAREG_TDY_RESET); // First the colors for(Bit8u i=0;i<0x10;i++) { - IO_Write(VGAREG_TDY_ADDRESS,i+0x10); - IO_Write(VGAREG_TDY_DATA,mem_readb(data)); + WriteTandyACTL(i+0x10,mem_readb(data)); data++; } // Then the border - IO_Write(VGAREG_TDY_ADDRESS,0x02); - IO_Write(VGAREG_TDY_DATA,mem_readb(data)); + WriteTandyACTL(0x02,mem_readb(data)); break; case MCH_VGA: ResetACTL(); @@ -210,7 +213,7 @@ void INT10_SetBackgroundBorder(Bit8u val) { Bitu temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL); temp=(temp & 0xe0) | (val & 0x1f); real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp); - if (machine == MCH_CGA || machine == MCH_TANDY) + if (machine == MCH_CGA || IS_TANDY_ARCH) IO_Write(0x3d9,temp); else if (machine == MCH_VGA) { val = ((val << 1) & 0x10) | (val & 0x7); @@ -228,7 +231,7 @@ void INT10_SetColorSelect(Bit8u val) { Bitu temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL); temp=(temp & 0xdf) | ((val & 1) ? 0x20 : 0x0); real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp); - if (machine == MCH_CGA || machine == MCH_TANDY) + if (machine == MCH_CGA || IS_TANDY_ARCH) IO_Write(0x3d9,temp); else if (machine == MCH_VGA) { val = (temp & 0x10) | 2 | val; From ed1cadea92048886fdb1a0b0c53dd71e22f1c016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 2 Dec 2005 20:03:51 +0000 Subject: [PATCH 2315/4131] add basic PCJr graphics functionality based on current Tandy implementation Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2399 --- include/vga.h | 2 ++ src/hardware/vga_draw.cpp | 9 ++++-- src/hardware/vga_memory.cpp | 8 +++-- src/hardware/vga_misc.cpp | 1 + src/hardware/vga_other.cpp | 58 +++++++++++++++++++++++++++++++++---- src/ints/int10.cpp | 10 ++++++- src/ints/int10_modes.cpp | 37 +++++++++++++++++++++-- 7 files changed, 112 insertions(+), 13 deletions(-) diff --git a/include/vga.h b/include/vga.h index 5fde426f..2674aeee 100644 --- a/include/vga.h +++ b/include/vga.h @@ -196,6 +196,8 @@ typedef struct { Bit8u gfx_control; Bit8u palette_mask; Bit8u border_color; + bool is_32k_mode; + bool pcjr_flipflop; } VGA_TANDY; typedef struct { diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 1569b2bc..fb54ce9c 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -502,7 +502,8 @@ void VGA_SetupDrawing(Bitu val) { case M_TANDY2: aspect_ratio=1.2; doubleheight=true; - doublewidth=(vga.tandy.mode_control & 0x10)==0; + if (machine==MCH_TANDY) doublewidth=(vga.tandy.mode_control & 0x10)==0; + else doublewidth=(vga.tandy.gfx_control & 0x8)==0x00; vga.draw.blocks=width * (doublewidth ? 4:8); width=vga.draw.blocks*2; VGA_DrawLine=VGA_Draw_1BPP_Line; @@ -510,7 +511,8 @@ void VGA_SetupDrawing(Bitu val) { case M_TANDY4: aspect_ratio=1.2; doubleheight=true; - doublewidth=(vga.tandy.mode_control & 0x10)==0; + if (machine==MCH_TANDY) doublewidth=(vga.tandy.mode_control & 0x10)==0; + else doublewidth=(vga.tandy.gfx_control & 0x8)==0x00; vga.draw.blocks=width * (doublewidth ? 4:8); width=vga.draw.blocks*2; VGA_DrawLine=VGA_Draw_2BPP_Line; @@ -518,7 +520,8 @@ void VGA_SetupDrawing(Bitu val) { case M_TANDY16: aspect_ratio=1.2; doubleheight=true; - doublewidth=(vga.tandy.mode_control & 0x10)==0; + if (machine==MCH_TANDY) doublewidth=(vga.tandy.mode_control & 0x10)==0; + else doublewidth=(vga.tandy.gfx_control & 0x8)==0x00; vga.draw.blocks=width * (doublewidth ? 2:4); width=vga.draw.blocks*2; VGA_DrawLine=VGA_Draw_4BPP_Line; diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 88cbc4b2..93d6d5d9 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -428,7 +428,7 @@ public: phys_page-=0xb8; return &vga.mem.linear[(vga.tandy.mem_bank << 14)+(phys_page * 4096)]; } else { - phys_page-=0x80; + if (machine==MCH_TANDY) phys_page-=0x80; return &vga.mem.linear[phys_page * 4096]; } } @@ -457,10 +457,14 @@ void VGA_SetupHandlers(void) { range_handler=&vgaph.hmap; if (vga.herc.mode_control&0x80) goto range_b800; else goto range_b000; - case TANDY_ARCH_CASE: + case MCH_TANDY: range_handler=&vgaph.htandy; MEM_SetPageHandler(0x80,32,range_handler); goto range_b800; + case MCH_PCJR: + range_handler=&vgaph.htandy; + MEM_SetPageHandler(vga.tandy.mem_bank<<2,vga.tandy.is_32k_mode ? 0x08 : 0x04,range_handler); + goto range_b800; } switch (vga.mode) { case M_ERROR: diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 1f96bcda..c63c53b2 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -30,6 +30,7 @@ Bitu read_p3d5_vga(Bitu port,Bitu iolen); static Bitu read_p3da(Bitu port,Bitu iolen) { vga.internal.attrindex=false; + vga.tandy.pcjr_flipflop=false; if (vga.config.retrace) { switch (machine) { case MCH_HERC: diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 13e7f854..3453c73b 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -199,9 +199,6 @@ static void write_color_select(Bit8u val) { /* Check for BW Mode */ if (vga.tandy.mode_control & 0x4) { VGA_SetCGA4Table(val & 0xf,3+base,4+base,7+base); - /* old code: - if (val & 0x20) VGA_SetCGA4Table(val & 0xf,3+base,4+base,7+base); - else VGA_SetCGA4Table(val & 0xf,2+base,4+base,6+base); */ } else { if (val & 0x20) VGA_SetCGA4Table(val & 0xf,3+base,5+base,7+base); else VGA_SetCGA4Table(val & 0xf,2+base,4+base,6+base); @@ -242,14 +239,39 @@ static void TANDY_FindMode(void) { } } +static void PCJr_FindMode(void) { + if (vga.tandy.mode_control & 0x2) { + if (vga.tandy.mode_control & 0x10) { + /* bit4 of mode control 1 signals 16 colour graphics mode */ + VGA_SetMode(M_TANDY16); + } else if (vga.tandy.gfx_control & 0x08) { + /* bit3 of mode control 2 signals 2 colour graphics mode */ + VGA_SetMode(M_TANDY2); + } else { + /* otherwise some 4-colour graphics mode */ + VGA_SetMode(M_TANDY4); + } + write_color_select(vga.tandy.color_select); + } else { + VGA_SetMode(M_TANDY_TEXT); + } +} + static void write_tandy_reg(Bit8u val) { switch (vga.tandy.reg_index) { + case 0x0: + if (machine==MCH_PCJR) { + vga.tandy.mode_control=val; + VGA_SetBlinking(val & 0x20); + PCJr_FindMode(); + } else LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index); case 0x2: /* Border color */ vga.tandy.border_color=val; break; case 0x3: /* More control */ vga.tandy.gfx_control=val; - TANDY_FindMode(); + if (machine==MCH_TANDY) TANDY_FindMode(); + else PCJr_FindMode(); break; /* palette colors */ case 0x10: case 0x11: case 0x12: case 0x13: @@ -311,6 +333,25 @@ static void write_tandy(Bitu port,Bitu val,Bitu iolen) { } } +static void write_pcjr(Bitu port,Bitu val,Bitu iolen) { + switch (port) { + case 0x3d9: + write_color_select(val); + break; + case 0x3da: + if (vga.tandy.pcjr_flipflop) write_tandy_reg(val); + else vga.tandy.reg_index=val; + vga.tandy.pcjr_flipflop=!vga.tandy.pcjr_flipflop; + break; + case 0x3df: + vga.tandy.is_32k_mode=(val & 0x80)==0x80; + vga.tandy.disp_bank=val & (vga.tandy.is_32k_mode ? 0x6 : 0x7); + vga.tandy.mem_bank=(val >> 3) & (vga.tandy.is_32k_mode ? 0x6 : 0x7); + VGA_SetupHandlers(); + break; + } +} + static void write_hercules(Bitu port,Bitu val,Bitu iolen) { switch (port) { case 0x3b8: @@ -362,13 +403,20 @@ void VGA_SetupOther(void) { IO_RegisterWriteHandler(0x3b8,write_hercules,IO_MB); IO_RegisterWriteHandler(0x3bf,write_hercules,IO_MB); } - if (IS_TANDY_ARCH) { + if (machine==MCH_TANDY) { IO_RegisterWriteHandler(0x3d8,write_tandy,IO_MB); IO_RegisterWriteHandler(0x3d9,write_tandy,IO_MB); IO_RegisterWriteHandler(0x3de,write_tandy,IO_MB); IO_RegisterWriteHandler(0x3df,write_tandy,IO_MB); IO_RegisterWriteHandler(0x3da,write_tandy,IO_MB); } + if (machine==MCH_PCJR) { + vga.tandy.mem_bank=7;vga.tandy.disp_bank=7; + vga.tandy.is_32k_mode=false;vga.tandy.pcjr_flipflop=false; + IO_RegisterWriteHandler(0x3d9,write_pcjr,IO_MB); + IO_RegisterWriteHandler(0x3da,write_pcjr,IO_MB); + IO_RegisterWriteHandler(0x3df,write_pcjr,IO_MB); + } if (machine==MCH_CGA || machine==MCH_HERC || IS_TANDY_ARCH) { Bitu base=machine==MCH_HERC ? 0x3b4 : 0x3d4; IO_RegisterWriteHandler(base,write_crtc_index_other,IO_MB); diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 27dcc17a..22ede176 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -85,6 +85,11 @@ static Bitu INT10_Handler(void) { crtcpu=(crtcpu & 0xc0) | (reg_bh & 7) | ((reg_bl & 7) << 3); break; } + if (machine==MCH_PCJR) { + /* always return graphics mapping, even for invalid values of AL */ + reg_bh=crtcpu & 7; + reg_bl=(crtcpu >> 3) & 0x7; + } IO_WriteB(0x3df,crtcpu); real_writeb(BIOSMEM_SEG, BIOSMEM_CRTCPU_PAGE,crtcpu); } @@ -114,7 +119,10 @@ static Bitu INT10_Handler(void) { INT10_SetColorSelect(reg_bl); break; default: - if(machine == MCH_CGA) INT10_SetColorSelect(reg_bl); + if ((machine==MCH_CGA) || (machine==MCH_PCJR)) { + /* those BIOSes check for !=0 */ + INT10_SetColorSelect(reg_bl); + } break; } break; diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index a64c2537..2996f014 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -300,9 +300,11 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { break; case M_CGA2: scanline=2; + break; case M_CGA4: if (CurMode->mode!=0xa) scanline=2; else scanline=4; + break; case M_TANDY16: if (CurMode->mode!=0x9) scanline=2; else scanline=4; @@ -319,6 +321,11 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { 0x2a,0x2e,0x1e,0x29, //4-7 0x2a,0x2b,0x3b //8-a }; + Bit8u mode_control_list_pcjr[0xa+1]={ + 0x0c,0x08,0x0d,0x09, //0-3 + 0x0a,0x0e,0x0e,0x09, //4-7 + 0x1a,0x1b,0x0b //8-a + }; Bit8u mode_control,color_select; switch (machine) { case MCH_HERC: @@ -336,10 +343,10 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,mode_control); real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select); break; - case TANDY_ARCH_CASE: + case MCH_TANDY: /* Init some registers */ IO_WriteB(0x3da,0x1);IO_WriteB(0x3de,0xf); //Palette mask always 0xf - IO_WriteB(0x3da,0x2);IO_WriteB(0x3de,0x0); //block border + IO_WriteB(0x3da,0x2);IO_WriteB(0x3de,0x0); //black border IO_WriteB(0x3da,0x3); //Tandy color overrides? switch (CurMode->mode) { case 0x8: @@ -362,6 +369,32 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,mode_control); real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select); break; + case MCH_PCJR: + /* Init some registers */ + IO_ReadB(0x3da); + IO_WriteB(0x3da,0x1);IO_WriteB(0x3da,0xf); //Palette mask always 0xf + IO_WriteB(0x3da,0x2);IO_WriteB(0x3da,0x0); //black border + IO_WriteB(0x3da,0x3); + if (CurMode->mode<=0x04) IO_WriteB(0x3da,0x02); + else if (CurMode->mode==0x06) IO_WriteB(0x3da,0x08); + else IO_WriteB(0x3da,0x00); + + /* set CRT/Processor page register */ + if (CurMode->mode<0x04) crtpage=0x3f; + else if (CurMode->mode>=0x09) crtpage=0xf6; + else crtpage=0x7f; + IO_WriteB(0x3df,crtpage); + real_writeb(BIOSMEM_SEG,BIOSMEM_CRTCPU_PAGE,crtpage); + + mode_control=mode_control_list_pcjr[CurMode->mode]; + IO_WriteB(0x3da,0x0);IO_WriteB(0x3da,mode_control); + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,mode_control); + + if (CurMode->mode == 0x6 || CurMode->mode==0xa) color_select=0x3f; + else color_select=0x30; + IO_WriteB(0x3d9,color_select); + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select); + break; } FinishSetMode(clearmem); return true; From de579c6a8952f135b7e6194051c5617ecd03325e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 3 Dec 2005 10:43:22 +0000 Subject: [PATCH 2316/4131] add PCJr-compatible dos memory layout Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2400 --- src/dos/dos_execute.cpp | 17 +++++++++++++++-- src/dos/dos_memory.cpp | 31 ++++++++++++++++++++++++++----- src/hardware/memory.cpp | 10 ++++++++-- src/ints/ems.cpp | 6 +++++- 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index c089a06b..29ccb928 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.51 2005-10-17 20:17:08 c2woody Exp $ */ +/* $Id: dos_execute.cpp,v 1.52 2005-12-03 10:43:22 c2woody Exp $ */ #include #include @@ -274,6 +274,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { if (imagesize+headersize<512) imagesize = 512-headersize; } } + Bit8u * loadbuf=(Bit8u *)new Bit8u[0x10000]; if (flags!=OVERLAY) { /* Create an environment block */ envseg=block.exec.envseg; @@ -285,6 +286,14 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { Bit16u minsize,maxsize;Bit16u maxfree=0xffff;DOS_AllocateMemory(&pspseg,&maxfree); if (iscom) { minsize=0x1000;maxsize=0xffff; + if (machine==MCH_PCJR) { + /* try to load file into memory below 96k */ + pos=0;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET); + Bit16u dataread=0x1800; + DOS_ReadFile(fhandle,loadbuf,&dataread); + if (dataread<0x1800) maxsize=dataread; + if (minsize>maxsize) minsize=maxsize; + } } else { /* Exe size calculated from header */ minsize=long2para(imagesize+(head.minmemory<<4)+256); if (head.maxmemory!=0) maxsize=long2para(imagesize+(head.maxmemory<<4)+256); @@ -298,6 +307,11 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { if (maxfree #include @@ -1048,6 +1048,10 @@ public: Section_prop * section=static_cast(configuration); if (!section->Get_bool("ems")) return; + if (machine==MCH_PCJR) { + LOG_MSG("EMS disabled for PCJr machine"); + return; + } BIOS_ZeroExtendedSize(true); int67.Install(&INT67_Handler,CB_IRET,"Int 67 ems"); Bit16u call_int67=int67.Get_callback(); From 6ede5e436f5a5aac26ac8db6c61ec02b9815939e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 4 Dec 2005 10:35:51 +0000 Subject: [PATCH 2317/4131] add Tandy 4-colour hires mode (0x0a); fix bios putpixel for modes 0x08, 0x0a (also used by bios write) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2401 --- include/vga.h | 1 + src/hardware/vga.cpp | 10 ++++++++++ src/hardware/vga_draw.cpp | 21 ++++++++++++++++++-- src/hardware/vga_other.cpp | 3 ++- src/ints/int10_put_pixel.cpp | 38 ++++++++++++++++++++++++++---------- 5 files changed, 60 insertions(+), 13 deletions(-) diff --git a/include/vga.h b/include/vga.h index 2674aeee..abd1d296 100644 --- a/include/vga.h +++ b/include/vga.h @@ -356,6 +356,7 @@ 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]; diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 67fa0ba1..d56735d2 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -26,6 +26,7 @@ VGA_Type vga; Bit32u CGA_2_Table[16]; Bit32u CGA_4_Table[256]; +Bit32u CGA_4_HiRes_Table[256]; Bit32u CGA_16_Table[256]; Bit32u TXT_Font_Table[16]; Bit32u TXT_FG_Table[16]; @@ -132,9 +133,18 @@ void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3) { #else (total[(i >> 6) & 3] << 0 ) | (total[(i >> 4) & 3] << 8 ) | (total[(i >> 2) & 3] << 16 ) | (total[(i >> 0) & 3] << 24 ); +#endif + CGA_4_HiRes_Table[i]= +#ifdef WORDS_BIGENDIAN + (total[((i >> 0) & 1) | ((i >> 3) & 2)] << 0 ) | (total[((i >> 1) & 1) | ((i >> 4) & 2)] << 8 ) | + (total[((i >> 2) & 1) | ((i >> 5) & 2)] << 16 ) | (total[((i >> 3) & 1) | ((i >> 6) & 2)] << 24 ); +#else + (total[((i >> 3) & 1) | ((i >> 6) & 2)] << 0 ) | (total[((i >> 2) & 1) | ((i >> 5) & 2)] << 8 ) | + (total[((i >> 1) & 1) | ((i >> 4) & 2)] << 16 ) | (total[((i >> 0) & 1) | ((i >> 3) & 2)] << 24 ); #endif } } + void VGA_Init(Section* sec) { vga.draw.resizing=false; vga.mode=M_ERROR; //For first init diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index fb54ce9c..b8f07a84 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -58,6 +58,20 @@ static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { return TempLine; } +static Bit8u * VGA_Draw_2BPPHiRes_Line(Bitu vidstart,Bitu panning,Bitu line) { + line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; + for (Bitu x=0;x<(vga.draw.blocks>>1);x++) { + Bitu val1=vga.mem.linear[vidstart+line]; + Bitu val2=vga.mem.linear[vidstart+1+line]; + vidstart+=2; + if((vga.crtc.mode_control & 0x01) == 0) // CGA compatible addressing + vidstart &= 0x1dfff; + *draw++=CGA_4_HiRes_Table[(val1>>4)|(val2&0xf0)]; + *draw++=CGA_4_HiRes_Table[(val1&0x0f)|((val2&0x0f)<<4)]; + } + return TempLine; +} + static Bitu temp[643]={0}; static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart,Bitu panning,Bitu line) { @@ -513,9 +527,12 @@ void VGA_SetupDrawing(Bitu val) { doubleheight=true; if (machine==MCH_TANDY) doublewidth=(vga.tandy.mode_control & 0x10)==0; else doublewidth=(vga.tandy.gfx_control & 0x8)==0x00; - vga.draw.blocks=width * (doublewidth ? 4:8); +// vga.draw.blocks=width * (doublewidth ? 4:8); + vga.draw.blocks=width * 4; width=vga.draw.blocks*2; - VGA_DrawLine=VGA_Draw_2BPP_Line; + if ((machine==MCH_TANDY && (vga.tandy.gfx_control & 0x8)) || + (machine==MCH_PCJR && (vga.tandy.mode_control==0x0b))) VGA_DrawLine=VGA_Draw_2BPPHiRes_Line; + else VGA_DrawLine=VGA_Draw_2BPP_Line; break; case M_TANDY16: aspect_ratio=1.2; diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 3453c73b..0d35895f 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -191,7 +191,8 @@ static void write_color_select(Bit8u val) { break; case M_TANDY4: { - if (IS_TANDY_ARCH && (vga.tandy.gfx_control & 0x8)) { + if ((machine==MCH_TANDY && (vga.tandy.gfx_control & 0x8)) || + (machine==MCH_PCJR && (vga.tandy.mode_control==0x0b))) { VGA_SetCGA4Table(0,1,2,3); return; } diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 241d8d35..5992a059 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -28,16 +28,32 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { switch (CurMode->type) { case M_CGA4: { - Bit16u off=(y>>1)*80+(x>>2); - if (y&1) off+=8*1024; - Bit8u old=real_readb(0xb800,off); - if (color & 0x80) { - color&=3; - old^=color << (2*(3-(x&3))); + IO_Write(0x3d4,0x09); + if (IO_Read(0x3d5)==1) { + Bit16u off=(y>>1)*80+(x>>2); + if (y&1) off+=8*1024; + + Bit8u old=real_readb(0xb800,off); + if (color & 0x80) { + color&=3; + old^=color << (2*(3-(x&3))); + } else { + old=old&cga_masks[x&3]|((color&3) << (2*(3-(x&3)))); + } + real_writeb(0xb800,off,old); } else { - old=old&cga_masks[x&3]|((color&3) << (2*(3-(x&3)))); + Bit16u off=(y>>2)*160+((x>>2)&(~1)); + off+=(8*1024) * (y & 3); + + Bit16u old=real_readw(0xb800,off); + if (color & 0x80) { + old^=(color&1) << (7-(x&7)); + old^=((color&2)>>1) << ((7-(x&7))+8); + } else { + old=old&(~(0x101<<(7-(x&7)))) | ((color&1) << (7-(x&7))) | (((color&2)>>1) << ((7-(x&7))+8)); + } + real_writew(0xb800,off,old); } - real_writeb(0xb800,off,old); } break; case M_CGA2: @@ -56,8 +72,10 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { break; case M_TANDY16: { - Bit16u off=(y>>2)*160+(x>>1); - off+=(8*1024) * (y & 3); + IO_Write(0x3d4,0x09); + Bit8u scanlines_m1=IO_Read(0x3d5); + Bit16u off=(y>>((scanlines_m1==1)?1:2))*(CurMode->swidth>>1)+(x>>1); + off+=(8*1024) * (y & scanlines_m1); Bit8u old=real_readb(0xb800,off); Bit8u p[2]; p[1] = (old >> 4) & 0xf; From 90d6d74f99cad3f06b2596e1a77f6d53cfc27446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 4 Dec 2005 21:17:29 +0000 Subject: [PATCH 2318/4131] add PCJr-compatible keyboard layer; add support for PCJr cartridges Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2402 --- src/dos/dos_programs.cpp | 81 ++++++++++++++++++++------------------ src/hardware/keyboard.cpp | 5 ++- src/hardware/pic.cpp | 17 ++++++-- src/ints/bios.cpp | 12 +++++- src/ints/bios_keyboard.cpp | 22 ++++++++++- 5 files changed, 91 insertions(+), 46 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index b7a94690..423ace13 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.47 2005-11-28 16:12:30 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.48 2005-12-04 21:17:28 c2woody Exp $ */ #include #include @@ -440,49 +440,53 @@ public: return; } - WriteOut(MSG_Get("PROGRAM_BOOT_BOOT"), drive); - bootSector bootarea; imageDiskList[drive-65]->Read_Sector(0,0,1,(Bit8u *)&bootarea); - for(i=0;i<512;i++) real_writeb(0, 0x7c00 + i, bootarea.rawdata[i]); + if ((bootarea.rawdata[0]==0x50) && (bootarea.rawdata[1]==0x43) && (bootarea.rawdata[2]==0x6a) && (bootarea.rawdata[3]==0x72)) { + if (machine!=MCH_PCJR) WriteOut(MSG_Get("PROGRAM_BOOT_CART_WO_PCJR")); + else { + Bit8u rombuf[65536]; + fseek(usefile,0x200L, SEEK_SET); + fread(rombuf, 1, rombytesize-0x200, usefile); + fclose(usefile); - + /* write cartridge data into ROM */ + Bit16u romseg=0xe000; + if ((rombuf[7]==0x42) && (rombuf[8]==0x41) && (rombuf[9]==0x53) && (rombuf[10]==0x49)) { + /* BASIC rom, doesn't work though */ + romseg=0xf600; + } + for(i=0;i @@ -47,6 +47,7 @@ struct PIC_Controller { bool special; bool auto_eoi; bool rotate_on_auto_eoi; + bool single; bool request_issr; Bit8u vector_base; }; @@ -79,11 +80,11 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { static Bit16u IRQ_priority_table[16] = { 0,1,2,8,9,10,11,12,13,14,15,3,4,5,6,7 }; if (GCC_UNLIKELY(val&0x10)) { // ICW1 issued - if (val&0x02) E_Exit("PIC: single mode not handled"); // (would have to skip ICW3) if (val&0x04) E_Exit("PIC: 4 byte interval not handled"); if (val&0x08) E_Exit("PIC: level triggered mode not handled"); if (val&0xe0) E_Exit("PIC: 8080/8085 mode not handled"); - pic->icw_index=1; // next is ICW3 + pic->single=val&0x02; + pic->icw_index=1; // next is ICW2 pic->icw_words=2 + (val&0x01); // =3 if ICW4 needed } else if (GCC_UNLIKELY(val&0x08)) { // OCW3 issued if (val&0x04) E_Exit("PIC: poll command not handled"); @@ -160,6 +161,10 @@ static void write_data(Bitu port,Bitu val,Bitu iolen) { else PIC_IRQCheck&=~(1 << (i+irq_base)); } } + if (machine==MCH_PCJR) { + /* irq6 cannot be disabled as it serves as pseudo-NMI */ + irqs[6].masked=false; + } if(irqs[2].masked != old_irq2_mask) { /* Irq 2 mask has changed recheck second pic */ for(i=8;i<=15;i++) { @@ -178,6 +183,7 @@ static void write_data(Bitu port,Bitu val,Bitu iolen) { irqs[i+irq_base].vector=(val&0xf8)+i; }; if(pic->icw_index++ >= pic->icw_words) pic->icw_index=0; + else if(pic->single) pic->icw_index=3; /* skip ICW3 in single mode */ break; case 2: /* icw 3 */ LOG(LOG_PIC,LOG_NORMAL)("%d:ICW 3 %X",port==0x21 ? 0 : 1,val); @@ -525,6 +531,7 @@ public: pics[i].rotate_on_auto_eoi=false; pics[i].request_issr=false; pics[i].special=false; + pics[i].single=false; pics[i].icw_index=0; pics[i].icw_words=0; } @@ -542,6 +549,10 @@ public: irqs[1].masked=false; /* Enable Keyboard IRQ */ irqs[2].masked=false; /* Enable second pic */ irqs[8].masked=false; /* Enable RTC IRQ */ + if (machine==MCH_PCJR) { + /* Enable IRQ6 (replacement for the NMI for PCJr) */ + irqs[6].masked=false; + } ReadHandler[0].Install(0x20,read_command,IO_MB); ReadHandler[1].Install(0x21,read_data,IO_MB); WriteHandler[0].Install(0x20,write_command,IO_MB); diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 76f8191f..a07aeb1d 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.52 2005-12-02 13:10:18 c2woody Exp $ */ +/* $Id: bios.cpp,v 1.53 2005-12-04 21:17:29 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -789,6 +789,13 @@ void BIOS_ZeroExtendedSize(bool in) { if(other_memsystems < 0) other_memsystems=0; } +#define RAM_REFRESH_DELAY 16.7f + +static void RAMRefresh_Event(Bitu val) { + PIC_ActivateIRQ(5); + PIC_AddEvent(RAMRefresh_Event,RAM_REFRESH_DELAY); +} + void BIOS_SetupKeyboard(void); void BIOS_SetupDisks(void); @@ -964,7 +971,8 @@ public: IO_Write(0x70,0x30); size_extended=IO_Read(0x71); IO_Write(0x70,0x31); - size_extended|=(IO_Read(0x71) << 8); + size_extended|=(IO_Read(0x71) << 8); + if (machine==MCH_PCJR) PIC_AddEvent(RAMRefresh_Event,RAM_REFRESH_DELAY); } ~BIOS(){ /* abort DAC playing */ diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 2928ded1..341c969d 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -25,7 +25,7 @@ #include "inout.h" -static Bitu call_int16,call_irq1; +static Bitu call_int16,call_irq1,call_irq6; /* Nice table from BOCHS i should feel bad for ripping this */ #define none 0 @@ -438,6 +438,21 @@ irq1_return: return CBRET_NONE; } +static bool pcjr_extended_key=false; + +static Bitu IRQ6_Handler(void) { + Bit8u scancode=IO_Read(0x60); + Bit16u old_ax=reg_ax; + if (pcjr_extended_key) reg_ax=scancode<<8; + else reg_al=scancode; + pcjr_extended_key=(scancode==0xe0); + /* call the real keyboard IRQ now, with the scancode in AL */ + CALLBACK_RunRealInt(0x09); + reg_ax=old_ax; + IO_Write(0x20,0x20); + return CBRET_NONE; +} + /* check whether key combination is enhanced or not, translate key if necessary */ static bool IsEnhancedKey(Bit16u &key) { @@ -592,6 +607,11 @@ void BIOS_SetupKeyboard(void) { RealSetVec(0x16,CALLBACK_RealPointer(call_int16)); CALLBACK_Setup(call_irq1,&IRQ1_Handler,CB_IRET,"keyboard irq"); RealSetVec(0x9,CALLBACK_RealPointer(call_irq1)); + if (machine==MCH_PCJR) { + call_irq6=CALLBACK_Allocate(); + CALLBACK_Setup(call_irq6,&IRQ6_Handler,CB_IRET,"PCJr kb irq"); + RealSetVec(0x0e,CALLBACK_RealPointer(call_irq6)); + } /* bring the all port operations outside the callback */ phys_writeb(CB_BASE+(call_irq1<<4)+0x00,(Bit8u)0x50); // push ax From 3ecebe3887097703987519dc02a2998d16932f41 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 5 Dec 2005 12:04:40 +0000 Subject: [PATCH 2319/4131] Turn off speaker faster. More aggressive premixing. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2403 --- src/hardware/mixer.cpp | 15 ++++++++------- src/hardware/pcspeaker.cpp | 13 ++++++++++--- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index be75c972..1bb2a2e3 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.34 2005-07-19 19:45:32 qbix79 Exp $ */ +/* $Id: mixer.cpp,v 1.35 2005-12-05 12:04:40 qbix79 Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -198,6 +198,7 @@ INLINE void MixerChannel::AddSamples(Bitu len,void * data) { Bitu mixpos=mixer.pos+done; freq_index&=MIXER_REMAIN; Bitu pos=0;Bitu new_pos; + goto thestart; while (1) { new_pos=freq_index >> MIXER_SHIFT; @@ -347,9 +348,9 @@ static void MIXER_Mix_NoSound(void) { static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { Bitu need=(Bitu)len/MIXER_SSIZE; if (need>mixer.done) { -// LOG_MSG("Buffer underrun"); + //LOG_MSG("%d Buffer underrun %d done and %d needed",count++,mixer.done,need); return; - } + }//else LOG_MSG("%d Buffer regular run %d done and %d needed",count++,mixer.done,need); /* Reduce done count in all channels */ for (MixerChannel * chan=mixer.channels;chan;chan=chan->next) { if (chan->done>need) chan->done-=need; @@ -357,12 +358,12 @@ static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { } mixer.done-=need; mixer.needed-=need; - if (mixer.done>mixer.min_needed) { + if (mixer.done > mixer.min_needed) { Bitu diff=mixer.done-mixer.min_needed; - mixer.tick_add=((mixer.freq-(diff>>2)) << MIXER_SHIFT)/1000; + mixer.tick_add = ((mixer.freq-(diff/5)) << MIXER_SHIFT)/1000; } else { - Bitu diff=mixer.needed-mixer.done; - mixer.tick_add=((mixer.freq+diff*3) << MIXER_SHIFT)/1000; + Bitu diff = ((mixer.min_needed>mixer.needed)?mixer.min_needed:mixer.needed) - mixer.done; + mixer.tick_add = ((mixer.freq+(diff*3)) << MIXER_SHIFT)/1000; } Bit16s * output=(Bit16s *)stream; Bits sample; diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index c6d02cfe..9e321c11 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /* $Id: pcspeaker.cpp,v 1.20 2005-03-25 11:52:32 qbix79 Exp $ */ + /* $Id: pcspeaker.cpp,v 1.21 2005-12-05 12:04:40 qbix79 Exp $ */ #include #include "dosbox.h" @@ -223,7 +223,7 @@ void PCSPEAKER_SetType(Bitu mode) { ForwardPIT(newindex); switch (mode) { case 0: - spkr.mode=SPKR_OFF; + spkr.mode=SPKR_OFF; AddDelayEntry(newindex,-SPKR_VOLUME); break; case 1: @@ -299,7 +299,14 @@ static void PCSPEAKER_CallBack(Bitu len) { *stream++=(Bit16s)(value/sample_add); } if(spkr.chan) spkr.chan->AddSamples_m16(len,(Bit16s*)MixTemp); - if ((spkr.last_ticks+10000)Enable(false); + } + if((spkr.mode == SPKR_OFF) && ((spkr.last_ticks+1000) Enable(false); } From 93697766341710aefa1ed651da56ac3037fad3a4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 5 Dec 2005 12:07:55 +0000 Subject: [PATCH 2320/4131] mode specific startup messages Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2404 --- src/shell/shell.cpp | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 7f9028a1..06a571f8 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.66 2005-11-21 18:32:38 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.67 2005-12-05 12:07:55 qbix79 Exp $ */ #include #include @@ -266,7 +266,12 @@ void DOS_Shell::Run(void) { return; } /* Start a normal shell and check for a first command init */ - WriteOut(MSG_Get("SHELL_STARTUP")); + WriteOut(MSG_Get("SHELL_STARTUP_BEGIN")); +#if C_DEBUG + WriteOut(MSG_Get("SHELL_STARTUP_DEBUG")); +#endif + if(machine == MCH_CGA) WriteOut(MSG_Get("SHELL_STARTUP_CGA")); + WriteOut(MSG_Get("SHELL_STARTUP_END")); if (cmd->FindString("/INIT",line,true)) { strcpy(input_line,line.c_str()); line.erase(); @@ -404,7 +409,7 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_SUBST_NO_REMOVE","Removing drive not supported. Doing nothing.\n"); MSG_Add("SHELL_CMD_SUBST_FAILURE","SUBST failed. You either made an error in your commandline or the target drive is already used.\nIt's only possible to use SUBST on Local drives"); - MSG_Add("SHELL_STARTUP", + MSG_Add("SHELL_STARTUP_BEGIN", "\033[44;1m\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n" @@ -417,18 +422,23 @@ void SHELL_Init() { "\xBA To activate the keymapper \033[31mctrl-F1\033[37m. \xBA\n" "\xBA For more information read the \033[36mREADME\033[37m file in the DOSBox directory. \xBA\n" "\xBA \xBA\n" -#if C_DEBUG - "\xBA Press \033[31mPause\033[37m to enter the debugger or start the exe with \033[33mDEBUG\033[37m. \xBA\n" - "\xBA \xBA\n" -#endif - "\xBA \033[32mHAVE FUN!\033[37m \xBA\n" - "\xBA \033[32mThe DOSBox Team\033[37m \xBA\n" - "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC\033[0m\n" - //"\n" //Breaks the startup message if you type a mount and a drive change. ); - + MSG_Add("SHELL_STARTUP_CGA","\xBA DOSBox supports Composite CGA mode. \xBA\n" + "\xBA Use \033[31m(ctrl-)F11\033[37m to change the colours when in this mode. \xBA\n" + "\xBA \xBA\n" + ); + MSG_Add("SHELL_STARTUP_DEBUG", + "\xBA Press \033[31mctrl-Pause\033[37m to enter the debugger or start the exe with \033[33mDEBUG\033[37m.\xBA\n" + "\xBA \xBA\n" + ); + MSG_Add("SHELL_STARTUP_END", + "\xBA \033[32mHAVE FUN!\033[37m \xBA\n" + "\xBA \033[32mThe DOSBox Team\033[37m \xBA\n" + "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC\033[0m\n" + //"\n" //Breaks the startup message if you type a mount and a drive change. + ); MSG_Add("SHELL_CMD_CHDIR_HELP","Change Directory.\n"); MSG_Add("SHELL_CMD_CLS_HELP","Clear screen.\n"); MSG_Add("SHELL_CMD_DIR_HELP","Directory View.\n"); From b37e0b8c260d400ca45113b679a2bb52ef3e6ae5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 5 Dec 2005 12:09:00 +0000 Subject: [PATCH 2321/4131] copy/paste errors. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2405 --- README | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README b/README index f01fc933..e7ece2b3 100644 --- a/README +++ b/README @@ -9,8 +9,8 @@ While we are hoping that one day, DOSBox will run all programs ever made for the PC,we are not there yet. At present, DOSBox run on a high- end machine will roughly be the equivalent of a 486 PC. The 0.60 release has added support for "protected mode" allowing for more complex and -recent programs, but note that this support is still in an early in stage of -development and unlike the support the 386 real-mode games (or earlier) hasn't +recent programs, but note that this support is still in an early stage of +development and unlike the support for 386 real-mode games (or earlier) hasn't been completed yet. Also note that "protected mode" games need substantially more resources and may require a much faster processor for you to run them properly in DOSBox. @@ -574,6 +574,7 @@ For more information use the /? command line switch with the programs. ================ ALT-ENTER Switch to full screen and back. +CTRL-PAUSE Pause emulation. CTRL-F1 Start the keymapper. CTRL-F4 Change between mounted disk-images. Update directory cache for all drives! CTRL-F5 Save a screenshot.(png) From 6833d3ada5aa084d86b2f1e729c83e0fdc5df9f4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 5 Dec 2005 12:09:33 +0000 Subject: [PATCH 2322/4131] Some progress report for the "fans". Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2406 --- ChangeLog | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4573f0b3..4f6b755e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,7 +2,7 @@ - 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. + - 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. @@ -14,13 +14,42 @@ - Fix crashes/segfaults related to the disabling of the pcspeaker. - Added some more FILES=XX detection tricks. - Fixed some vga detection schemes. - - Lot's of small bug fixes. - Fixed screenshot corruption when using -noconsole in a read-only directory. - - Addes some hidden file functions when using diskimages. (helps with cdrom + - 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 6. + - Improvements to the joystick emulation. 4 buttons are supported as well. + - Add VCPI emulation. No more ems=false with 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 palete 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. + - Lots of bugfixes. + - Even more bugfixes. - 0.63 - Fixed crash with keymapper (ctrl-f1) and output=surface. - Added unmounting. From 35dccef707db33ccf056b75ec4e18f29cfad3d4a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 5 Dec 2005 12:18:12 +0000 Subject: [PATCH 2323/4131] Added hue control for the composite mode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2407 --- src/hardware/vga_other.cpp | 52 ++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 0d35895f..ae738588 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -16,11 +16,15 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: vga_other.cpp,v 1.14 2005-12-05 12:18:12 qbix79 Exp $ */ + #include +#include #include "dosbox.h" #include "inout.h" #include "vga.h" #include "render.h" +#include "mapper.h" static void write_crtc_index_other(Bitu port,Bitu val,Bitu iolen) { vga.other.index=val; @@ -124,7 +128,16 @@ static Bitu read_crtc_data_other(Bitu port,Bitu iolen) { return (Bitu)-1; } +static double hue_offset = 0.0; +static Bit8u cga16_val = 0; +static void update_cga16_color(void); + static void cga16_color_select(Bit8u val) { + cga16_val = val; + update_cga16_color(); +} + +static void update_cga16_color(void) { // Algorithm provided by NewRisingSun // His/Her algorithm is more complex and gives better results than the one below // However that algorithm doesn't fit in our vga pallette. @@ -136,23 +149,20 @@ static void cga16_color_select(Bit8u val) { // to match an entry that is generated here. int baseR=0, baseG=0, baseB=0; - double sinhue,coshue; + double sinhue,coshue,hue,basehue = 50.0; double I,Q,Y,pixelI,pixelQ,R,G,B; Bitu colorBit1,colorBit2,colorBit3,colorBit4,index; - if (val & 0x01) baseB += 0xa8; - if (val & 0x02) baseG += 0xa8; - if (val & 0x04) baseR += 0xa8; - if (val & 0x08) { baseR += 0x57; baseG += 0x57; baseB += 0x57; } - if (val & 0x20) { - //Hue = 33.0 + hueoffset (0) - sinhue=0.54463904; //sin(hue*PI/180); - coshue=0.83867057; //sin(hue*PI/180); - } else { - //Hue = 55.0 + hueoffset (0) - sinhue=0.81915204; //sin(hue*PI/180); - coshue=0.57357644; //cos(hue*PI/180); - } + if (cga16_val & 0x01) baseB += 0xa8; + if (cga16_val & 0x02) baseG += 0xa8; + if (cga16_val & 0x04) baseR += 0xa8; + if (cga16_val & 0x08) { baseR += 0x57; baseG += 0x57; baseB += 0x57; } + if (cga16_val & 0x20) basehue = 35.0; + + hue = (basehue + hue_offset)*0.017453239; + sinhue = sin(hue); + coshue = cos(hue); + for(Bitu i = 0; i < 16;i++) { for(Bitu j = 0;j < 5;j++) { index = 0x80|(j << 4)|i; //use upperpart of vga pallette @@ -183,6 +193,18 @@ static void cga16_color_select(Bit8u val) { } } +static void IncreaseHue(void) { + hue_offset += 5.0; + update_cga16_color(); + LOG_MSG("Hue at %f",hue_offset); +} + +static void DecreaseHue(void) { + hue_offset -= 5.0; + update_cga16_color(); + LOG_MSG("Hue at %f",hue_offset); +} + static void write_color_select(Bit8u val) { vga.tandy.color_select=val; switch (vga.mode) { @@ -397,6 +419,8 @@ void VGA_SetupOther(void) { if (machine==MCH_CGA) { IO_RegisterWriteHandler(0x3d8,write_cga,IO_MB); IO_RegisterWriteHandler(0x3d9,write_cga,IO_MB); + MAPPER_AddHandler(IncreaseHue,MK_f11,MMOD1,"inchue","Inc Hue"); + MAPPER_AddHandler(DecreaseHue,MK_f11,0,"dechue","Dec Hue"); } if (machine==MCH_HERC) { vga.herc.enable_bits=0; From 380a7c73d09412ae35da44eebcdd4095c26393ee Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 5 Dec 2005 19:23:10 +0000 Subject: [PATCH 2324/4131] Add support for canonicalized directory entry readout Should fix fade to black videoplay Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2408 --- src/dos/dos_mscdex.cpp | 46 ++++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 088cc5a1..7751deb7 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.33 2005-11-25 19:15:12 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.34 2005-12-05 19:23:10 harekiet Exp $ */ #include #include @@ -149,7 +149,7 @@ private: Bit32u volumeSize; // for media change } TDriveInfo; - PhysPt defaultBuffer; + Bit16u defaultBufSeg; TDriveInfo dinfo[MSCDEX_MAX_DRIVES]; CDROM_Interface* cdrom[MSCDEX_MAX_DRIVES]; @@ -161,7 +161,7 @@ CMscdex::CMscdex(void) { numDrives = 0; rootDriverHeaderSeg = 0; - defaultBuffer = 0; + defaultBufSeg = 0; memset(dinfo,0,sizeof(dinfo)); for (Bit32u i=0; i 256) + return false; + MEM_BlockRead( defBuffer+index, readBuf, entryLength ); + writeBuf[0] = readBuf[1]; // 00h BYTE length of XAR in Logical Block Numbers + memcpy( &writeBuf[1], &readBuf[0x2], 4); // 01h DWORD Logical Block Number of file start + writeBuf[5] = 0;writeBuf[6] = 8; // 05h WORD size of disk in logical blocks + memcpy( &writeBuf[7], &readBuf[0xa], 4); // 07h DWORD file length in bytes + memcpy( &writeBuf[0xb], &readBuf[0x12], 7); // 0bh DWORD date and time + writeBuf[0x12] = readBuf[0x19]; // 12h BYTE bit flags + writeBuf[0x13] = readBuf[0x1a]; // 13h BYTE interleave size + writeBuf[0x14] = readBuf[0x1b]; // 14h BYTE interleave skip factor + memcpy( &writeBuf[0x15], &readBuf[0x1c], 2); // 15h WORD volume set sequence number + writeBuf[0x17] = readBuf[0x20]; + memcpy( &writeBuf[0x18], &readBuf[21], readBuf[0x20] <= 38 ? readBuf[0x20] : 38 ); + MEM_BlockWrite( buffer, writeBuf, 0x18 + 40 ); + } else { + // Direct copy + MEM_BlockCopy(buffer,defBuffer+index,entryLength); + } error = iso ? 1:0; return true; } @@ -765,7 +785,7 @@ static Bitu MSCDEX_Interrupt_Handler(void) { MSCDEX_LOG("MSCDEX: Driver Function %02X",funcNr); - switch (funcNr) { + switch (funcNr) { case 0x03 : { /* IOCTL INPUT */ PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); From a708a1344f86e106572286f0a8c42fbe5b38ccc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 5 Dec 2005 21:25:56 +0000 Subject: [PATCH 2325/4131] use RAM for PCJr graphics memory Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2409 --- include/mem.h | 1 + include/vga.h | 1 + src/hardware/memory.cpp | 4 +++- src/hardware/vga_draw.cpp | 16 ++++++++-------- src/hardware/vga_memory.cpp | 22 ++++++++++++++++++++-- 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/include/mem.h b/include/mem.h index 6f99054d..ce3f5d7c 100644 --- a/include/mem.h +++ b/include/mem.h @@ -32,6 +32,7 @@ typedef Bit32s MemHandle; #define MEM_PAGESIZE 4096 extern HostPt MemBase; +HostPt GetMemBase(void); bool MEM_A20_Enabled(void); void MEM_A20_Enable(bool enable); diff --git a/include/vga.h b/include/vga.h index abd1d296..ceb6f4d7 100644 --- a/include/vga.h +++ b/include/vga.h @@ -311,6 +311,7 @@ typedef struct { VGA_TANDY tandy; VGA_OTHER other; VGA_Memory mem; + Bit8u * gfxmem_start; } VGA_Type; diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 8423c353..c434ca9a 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: memory.cpp,v 1.40 2005-12-03 10:43:22 c2woody Exp $ */ +/* $Id: memory.cpp,v 1.41 2005-12-05 21:25:56 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -472,6 +472,8 @@ static Bitu read_p92(Bitu port,Bitu iolen) { return memory.a20.controlport | (memory.a20.enabled ? 0x02 : 0); } +HostPt GetMemBase(void) { return MemBase; } + class MEMORY:public Module_base{ private: IO_ReadHandleObject ReadHandler; diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index b8f07a84..ae042c2d 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -36,7 +36,7 @@ static Bit8u TempLine[1280]; static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; for (Bitu x=vga.draw.blocks;x>0;x--) { - Bitu val=vga.mem.linear[vidstart+line]; + Bitu val=vga.gfxmem_start[vidstart+line]; vidstart++; if((vga.crtc.mode_control & 0x01) == 0) // CGA compatible addressing vidstart &= 0x1dfff; @@ -49,7 +49,7 @@ static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; for (Bitu x=0;x>1);x++) { - Bitu val1=vga.mem.linear[vidstart+line]; - Bitu val2=vga.mem.linear[vidstart+1+line]; + Bitu val1=vga.gfxmem_start[vidstart+line]; + Bitu val2=vga.gfxmem_start[vidstart+1+line]; vidstart+=2; if((vga.crtc.mode_control & 0x01) == 0) // CGA compatible addressing vidstart &= 0x1dfff; @@ -114,7 +114,7 @@ static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart,Bitu panning,Bitu line) { } static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { - Bit8u * reader=&vga.mem.linear[vidstart + (line * 8 * 1024)]; + Bit8u * reader=&vga.gfxmem_start[vidstart + (line * 8 * 1024)]; Bit32u * draw=(Bit32u *)TempLine; for (Bitu x=0;xvga.draw.cursor.eline) goto skip_cursor; draw=(Bit32u *)&TempLine[font_addr*8]; - Bit32u att=TXT_FG_Table[vga.mem.linear[vga.draw.cursor.address+1]&0xf]; + Bit32u att=TXT_FG_Table[vga.gfxmem_start[vga.draw.cursor.address+1]&0xf]; *draw++=att;*draw++=att; } skip_cursor: diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 93d6d5d9..391f66ae 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -434,11 +434,24 @@ public: } }; +class VGA_PCJR_PageHandler : public PageHandler { +public: + VGA_PCJR_PageHandler() { + flags=PFLAG_READABLE|PFLAG_WRITEABLE; + } + HostPt GetHostPt(Bitu phys_page) { + phys_page-=0xb8; + if (!vga.tandy.is_32k_mode) phys_page&=0x03; + return MemBase+(vga.tandy.mem_bank << 14)+(phys_page * 4096); + } +}; + static struct vg { VGA_MAP_PageHandler hmap; VGA_TEXT_PageHandler htext; VGA_TANDY_PageHandler htandy; + VGA_PCJR_PageHandler hpcjr; VGA_256_PageHandler h256; VGA_256Chain4_PageHandler h256c4; VGA_16_PageHandler h16; @@ -462,8 +475,8 @@ void VGA_SetupHandlers(void) { MEM_SetPageHandler(0x80,32,range_handler); goto range_b800; case MCH_PCJR: - range_handler=&vgaph.htandy; - MEM_SetPageHandler(vga.tandy.mem_bank<<2,vga.tandy.is_32k_mode ? 0x08 : 0x04,range_handler); + range_handler=&vgaph.hpcjr; +// MEM_SetPageHandler(vga.tandy.mem_bank<<2,vga.tandy.is_32k_mode ? 0x08 : 0x04,range_handler); goto range_b800; } switch (vga.mode) { @@ -557,4 +570,9 @@ void VGA_UnmapMMIO(void) { void VGA_SetupMemory() { memset((void *)&vga.mem,0,512*1024*4); + if (machine==MCH_PCJR) { + /* PCJr does not have dedicated graphics memory but uses + conventional memory below 128k */ + vga.gfxmem_start=GetMemBase(); + } else vga.gfxmem_start=&vga.mem.linear[0]; } From 748a64aa0893c72f5b784a17de94f4d4a76d8a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 11 Dec 2005 15:09:50 +0000 Subject: [PATCH 2326/4131] add memory wrapping to 16 colour tandy modes (vertical scrollers, Scuba Venture); double pixels in mode8 (160x200) to fit screen better Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2410 --- src/hardware/vga_draw.cpp | 51 +++++++++++++++++++++++--------------- src/hardware/vga_other.cpp | 6 +++-- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index ae042c2d..5c40c1f5 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -60,7 +60,7 @@ static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { static Bit8u * VGA_Draw_2BPPHiRes_Line(Bitu vidstart,Bitu panning,Bitu line) { line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; - for (Bitu x=0;x<(vga.draw.blocks>>1);x++) { + for (Bitu x=0;x> 4 | (val2 & 0x0f) << 24 | @@ -127,14 +133,16 @@ static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { } static Bit8u * VGA_Draw_4BPP_Line_Double(Bitu vidstart,Bitu panning,Bitu line) { - Bit8u * reader=&vga.gfxmem_start[vidstart + (line * 8 * 1024)]; - Bit32u * draw=(Bit32u *)TempLine; + line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; for (Bitu x=0;x> 4 | - (val2 & 0x0f) << 24 | - (val2 & 0xf0) << 12; + if((vga.crtc.mode_control & 0x01) == 0) // CGA compatible addressing + vidstart &= 0x1dfff; + Bitu val=vga.gfxmem_start[vidstart+line]; + vidstart++; + *draw++=(val & 0xf0) >> 4 | + (val & 0xf0) << 4 | + (val & 0x0f) << 16 | + (val & 0x0f) << 24; } return TempLine; } @@ -352,7 +360,7 @@ void VGA_CheckScanLength(void) { vga.draw.address_add=vga.draw.blocks/4; break; case M_TANDY4: - vga.draw.address_add=vga.draw.blocks/2; + vga.draw.address_add=vga.draw.blocks; break; case M_TANDY16: vga.draw.address_add=vga.draw.blocks; @@ -527,9 +535,8 @@ void VGA_SetupDrawing(Bitu val) { doubleheight=true; if (machine==MCH_TANDY) doublewidth=(vga.tandy.mode_control & 0x10)==0; else doublewidth=(vga.tandy.gfx_control & 0x8)==0x00; -// vga.draw.blocks=width * (doublewidth ? 4:8); - vga.draw.blocks=width * 4; - width=vga.draw.blocks*2; + vga.draw.blocks=width * 2; + width=vga.draw.blocks*4; if ((machine==MCH_TANDY && (vga.tandy.gfx_control & 0x8)) || (machine==MCH_PCJR && (vga.tandy.mode_control==0x0b))) VGA_DrawLine=VGA_Draw_2BPPHiRes_Line; else VGA_DrawLine=VGA_Draw_2BPP_Line; @@ -537,11 +544,15 @@ void VGA_SetupDrawing(Bitu val) { case M_TANDY16: aspect_ratio=1.2; doubleheight=true; - if (machine==MCH_TANDY) doublewidth=(vga.tandy.mode_control & 0x10)==0; - else doublewidth=(vga.tandy.gfx_control & 0x8)==0x00; - vga.draw.blocks=width * (doublewidth ? 2:4); - width=vga.draw.blocks*2; - VGA_DrawLine=VGA_Draw_4BPP_Line; + doublewidth=true; + vga.draw.blocks=width*2; + if (vga.tandy.mode_control & 0x1) { + width=vga.draw.blocks*2; + VGA_DrawLine=VGA_Draw_4BPP_Line; + } else { + width=vga.draw.blocks*4; + VGA_DrawLine=VGA_Draw_4BPP_Line_Double; + } break; case M_TANDY_TEXT: doublewidth=(vga.tandy.mode_control & 0x1)==0; diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index ae738588..07f108d8 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_other.cpp,v 1.14 2005-12-05 12:18:12 qbix79 Exp $ */ +/* $Id: vga_other.cpp,v 1.15 2005-12-11 15:09:50 c2woody Exp $ */ #include #include @@ -349,6 +349,7 @@ static void write_tandy(Bitu port,Bitu val,Bitu iolen) { write_tandy_reg(val); break; case 0x3df: + vga.tandy.is_32k_mode=(val & 0x80)==0x80; vga.tandy.disp_bank=val & ((val & 0x80) ? 0x6 : 0x7); vga.tandy.mem_bank=(val >> 3) & ((val & 0x80) ? 0x6 : 0x7); VGA_SetupHandlers(); @@ -369,7 +370,7 @@ static void write_pcjr(Bitu port,Bitu val,Bitu iolen) { case 0x3df: vga.tandy.is_32k_mode=(val & 0x80)==0x80; vga.tandy.disp_bank=val & (vga.tandy.is_32k_mode ? 0x6 : 0x7); - vga.tandy.mem_bank=(val >> 3) & (vga.tandy.is_32k_mode ? 0x6 : 0x7); + vga.tandy.mem_bank=(val >> 3) & 0x7; VGA_SetupHandlers(); break; } @@ -429,6 +430,7 @@ void VGA_SetupOther(void) { IO_RegisterWriteHandler(0x3bf,write_hercules,IO_MB); } if (machine==MCH_TANDY) { + vga.tandy.is_32k_mode=false; IO_RegisterWriteHandler(0x3d8,write_tandy,IO_MB); IO_RegisterWriteHandler(0x3d9,write_tandy,IO_MB); IO_RegisterWriteHandler(0x3de,write_tandy,IO_MB); From 8ebe87d0ceaa68024a567871f700f79d59bcaf39 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 13 Dec 2005 11:15:50 +0000 Subject: [PATCH 2327/4131] Don't restore int 33 vector on int 10 mode change. Fixes Rac Racing and Big Red Adventure Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2411 --- src/ints/mouse.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 7657050d..130fa902 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.56 2005-10-03 19:22:13 c2woody Exp $ */ +/* $Id: mouse.cpp,v 1.57 2005-12-13 11:15:50 qbix79 Exp $ */ #include #include @@ -505,7 +505,7 @@ static void mouse_reset_hardware(void){ void Mouse_NewVideoMode(void) { //Does way to much. Many of this stuff should be moved to mouse_reset one day - WriteMouseIntVector(); +// WriteMouseIntVector();//Disabled. Big Red Adventure, Rac Racing if(MOUSE_IRQ > 7) { real_writed(0,((0x70+MOUSE_IRQ-8)<<2),CALLBACK_RealPointer(call_int74)); From a93c25213364a267f50037a745955aaa728225a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 14 Dec 2005 16:32:33 +0000 Subject: [PATCH 2328/4131] add bestfit search to DOS_AllocateMemory (Armour-Geddon) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2412 --- src/dos/dos_memory.cpp | 108 ++++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 33 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index ec4758a6..25aae77b 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -91,6 +91,7 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { Bit16u umb_start=dos_infoblock.GetStartOfUMBChain(); if (umb_start==UMB_START_SEG) { + /* start with UMBs if requested (bits 7 or 6 set) */ if (mem_strat&0xc0) mcb_segment=umb_start; } else if (umb_start!=0xffff) LOG(LOG_DOSMISC,LOG_ERROR)("Corrupt UMB chain: %x",umb_start); @@ -99,58 +100,99 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { DOS_MCB psp_mcb(dos.psp()-1); char psp_name[9]; psp_mcb.GetFileName(psp_name); - bool stop=false; - while(!stop) { + Bit16u found_seg=0,found_seg_size=0; + for (;;) { mcb.SetPt(mcb_segment); if (mcb.GetPSPSeg()==0) { /* Check for enough free memory in current block */ Bit16u block_size=mcb.GetSize(); if (block_size<(*blocks)) { if (bigsize Date: Thu, 15 Dec 2005 20:53:05 +0000 Subject: [PATCH 2329/4131] use different scanline length detection for cga4 putpixel; fix doublewidth for tandy2 modes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2413 --- src/hardware/vga_draw.cpp | 4 ++-- src/ints/int10_put_pixel.cpp | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 5c40c1f5..40b0582b 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -524,8 +524,8 @@ void VGA_SetupDrawing(Bitu val) { case M_TANDY2: aspect_ratio=1.2; doubleheight=true; - if (machine==MCH_TANDY) doublewidth=(vga.tandy.mode_control & 0x10)==0; - else doublewidth=(vga.tandy.gfx_control & 0x8)==0x00; + if (machine==MCH_PCJR) doublewidth=(vga.tandy.gfx_control & 0x8)==0x00; + else doublewidth=(vga.tandy.mode_control & 0x10)==0; vga.draw.blocks=width * (doublewidth ? 4:8); width=vga.draw.blocks*2; VGA_DrawLine=VGA_Draw_1BPP_Line; diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 5992a059..d20ac51d 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -28,8 +28,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { switch (CurMode->type) { case M_CGA4: { - IO_Write(0x3d4,0x09); - if (IO_Read(0x3d5)==1) { + if (real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)<=5) { Bit16u off=(y>>1)*80+(x>>2); if (y&1) off+=8*1024; From b9bba7251902ac551c4cd2b7bb6c36d77a6c33b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 16 Dec 2005 21:05:46 +0000 Subject: [PATCH 2330/4131] add small free MCB to start of dos memory (fixes Cannon Fodder2 sound, Xenobots) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2414 --- src/dos/dos_memory.cpp | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 25aae77b..19bf2d1a 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -405,13 +405,6 @@ static Bitu DOS_default_handler(void) { static CALLBACK_HandlerObject callbackhandler; void DOS_SetupMemory(void) { - // Create a dummy device MCB with PSPSeg=0x0008 - DOS_MCB mcb_devicedummy((Bit16u)DOS_MEM_START); - mcb_devicedummy.SetPSPSeg(MCB_DOS); // Devices - mcb_devicedummy.SetSize(1); - mcb_devicedummy.SetType(0x4d); // More blocks will follow -// mcb_devicedummy.SetFileName("SD "); - /* Let dos claim a few bios interrupts. Makes DOSBox more compatible with * buggy games, which compare against the interrupt table. (probably a * broken linked list implementation) */ @@ -428,13 +421,35 @@ void DOS_SetupMemory(void) { real_writed(0,0x04*4,0x700000); //Shadow President // real_writed(0,0x0f*4,0x700000); //Always a tricky one (soundblaster irq) - DOS_MCB mcb((Bit16u)DOS_MEM_START+2); + // Create a dummy device MCB with PSPSeg=0x0008 + DOS_MCB mcb_devicedummy((Bit16u)DOS_MEM_START); + mcb_devicedummy.SetPSPSeg(MCB_DOS); // Devices + mcb_devicedummy.SetSize(1); + mcb_devicedummy.SetType(0x4d); // More blocks will follow +// mcb_devicedummy.SetFileName("SD "); + + Bit16u mcb_sizes=2; + // Create a small empty MCB (result from a growing environment block) + DOS_MCB tempmcb((Bit16u)DOS_MEM_START+mcb_sizes); + tempmcb.SetPSPSeg(MCB_FREE); + tempmcb.SetSize(4); + mcb_sizes+=5; + tempmcb.SetType(0x4d); + + // Lock the previous empty MCB + DOS_MCB tempmcb2((Bit16u)DOS_MEM_START+mcb_sizes); + tempmcb2.SetPSPSeg(0x40); // can be removed by loadfix + tempmcb2.SetSize(16); + mcb_sizes+=17; + tempmcb2.SetType(0x4d); + + DOS_MCB mcb((Bit16u)DOS_MEM_START+mcb_sizes); mcb.SetPSPSeg(MCB_FREE); //Free mcb.SetType(0x5a); //Last Block if (machine==MCH_TANDY) { /* memory up to 608k available, the rest (to 640k) is used by the tandy graphics system's variable mapping of 0xb800 */ - mcb.SetSize(0x97FE - DOS_MEM_START - 2); + mcb.SetSize(0x97FE - DOS_MEM_START - mcb_sizes); } else if (machine==MCH_PCJR) { /* memory from 128k to 640k is available */ mcb_devicedummy.SetPt((Bit16u)0x2000); @@ -449,11 +464,11 @@ void DOS_SetupMemory(void) { mcb_devicedummy.SetType(0x4d); /* memory below 96k */ - mcb.SetSize(0x1800 - DOS_MEM_START - 4); + mcb.SetSize(0x1800 - DOS_MEM_START - (2+mcb_sizes)); mcb.SetType(0x4d); } else { /* complete memory up to 640k available */ - mcb.SetSize(0x9FFE - DOS_MEM_START - 2); + mcb.SetSize(0x9FFE - DOS_MEM_START - mcb_sizes); } dos.firstMCB=DOS_MEM_START; From 7c919537f0604daf895981c10bebd36ee67cd2c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 17 Dec 2005 16:28:18 +0000 Subject: [PATCH 2331/4131] add truemem field, correct reported memory for tandy (Transsylvania/TandyDOS) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2415 --- include/bios.h | 1 + src/ints/bios.cpp | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/bios.h b/include/bios.h index ccb4d9ee..fc015ccc 100644 --- a/include/bios.h +++ b/include/bios.h @@ -30,6 +30,7 @@ #define BIOS_CONFIGURATION 0x410 /* 0x412 is reserved */ #define BIOS_MEMORY_SIZE 0x413 +#define BIOS_TRUE_MEMORY_SIZE 0x415 /* #define bios_expansion_memory_size (*(unsigned int *) 0x415) */ #define BIOS_KEYBOARD_STATE 0x417 #define BIOS_KEYBOARD_FLAGS1 BIOS_KEYBOARD_STATE diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index a07aeb1d..11ca7096 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.53 2005-12-04 21:17:29 c2woody Exp $ */ +/* $Id: bios.cpp,v 1.54 2005-12-17 16:28:18 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -835,7 +835,13 @@ public: /* INT 12 Memory Size default at 640 kb */ callback[2].Install(&INT12_Handler,CB_IRET,"Int 12 Memory"); callback[2].Set_RealVec(0x12); - mem_writew(BIOS_MEMORY_SIZE,640); + if (IS_TANDY_ARCH) { + /* reduce reported memory size for the Tandy (32k graphics memory + at the end of the conventional 640k) */ + if (machine==MCH_TANDY) mem_writew(BIOS_MEMORY_SIZE,608); + else mem_writew(BIOS_MEMORY_SIZE,640); + mem_writew(BIOS_TRUE_MEMORY_SIZE,640); + } else mem_writew(BIOS_MEMORY_SIZE,640); /* INT 13 Bios Disk Support */ BIOS_SetupDisks(); From 2d06e157958c6973e2c36f3ad07831e8ef8c8079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 18 Dec 2005 21:22:42 +0000 Subject: [PATCH 2332/4131] remove enhanced-attribute of keys in PCJr keyboard layer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2416 --- src/ints/bios_keyboard.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 341c969d..ed0aa613 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -438,21 +438,23 @@ irq1_return: return CBRET_NONE; } -static bool pcjr_extended_key=false; - static Bitu IRQ6_Handler(void) { Bit8u scancode=IO_Read(0x60); - Bit16u old_ax=reg_ax; - if (pcjr_extended_key) reg_ax=scancode<<8; - else reg_al=scancode; - pcjr_extended_key=(scancode==0xe0); - /* call the real keyboard IRQ now, with the scancode in AL */ - CALLBACK_RunRealInt(0x09); - reg_ax=old_ax; + /* skip extended keys, all of them should map quite nicely + onto corresponding non-extended keys */ + if (scancode!=0xe0) { + Bit16u old_ax=reg_ax; + reg_al=scancode; + /* call the real keyboard IRQ now, with the scancode in AL */ + CALLBACK_RunRealInt(0x09); + reg_ax=old_ax; + } + IO_Write(0x20,0x20); return CBRET_NONE; } + /* check whether key combination is enhanced or not, translate key if necessary */ static bool IsEnhancedKey(Bit16u &key) { From ef5e7f519ef8d8f044bebe231746cbeaf0035326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 19 Dec 2005 20:39:51 +0000 Subject: [PATCH 2333/4131] fake a 128k-PCJr when com files are loaded low (dos memory only) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2417 --- src/dos/dos_execute.cpp | 10 +++++++++- src/dos/dos_memory.cpp | 9 ++++++++- src/dos/dos_programs.cpp | 12 +++++------- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 29ccb928..966aded7 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.52 2005-12-03 10:43:22 c2woody Exp $ */ +/* $Id: dos_execute.cpp,v 1.53 2005-12-19 20:39:51 c2woody Exp $ */ #include #include @@ -311,6 +311,14 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { maxsize=0xffff; /* resize to full extent of memory block */ DOS_ResizeMemory(pspseg,&maxsize); + /* now try to lock out memory above segment 0x2000 */ + if ((real_readb(0x2000,0)==0x5a) && (real_readw(0x2000,1)==0) && (real_readw(0x2000,3)==0x7ffe)) { + /* MCB after PCJr graphics memory region is still free */ + if (pspseg+maxsize==0x17ff) { + DOS_MCB cmcb((Bit16u)(pspseg-1)); + cmcb.SetType(0x5a); // last block + } + } } loadseg=pspseg+16; if (!iscom) { diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 19bf2d1a..dbdd7063 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -49,7 +49,14 @@ void DOS_FreeProcessMemory(Bit16u pspseg) { if (mcb.GetPSPSeg()==pspseg) { mcb.SetPSPSeg(MCB_FREE); } - if (mcb.GetType()==0x5a) break; + if (mcb.GetType()==0x5a) { + /* check if currently last block reaches up to the PCJr graphics memory */ + if ((machine==MCH_PCJR) && (mcb_segment+mcb.GetSize()==0x17fe) && + (real_readb(0x17ff,0)==0x4d) && (real_readw(0x17ff,1)==8)) { + /* re-enable the memory past segment 0x2000 */ + mcb.SetType(0x4d); + } else break; + } mcb_segment+=mcb.GetSize()+1; mcb.SetPt(mcb_segment); } diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 423ace13..3432341d 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.48 2005-12-04 21:17:28 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.49 2005-12-19 20:39:51 c2woody Exp $ */ #include #include @@ -287,7 +287,9 @@ public: Bit16u seg,blocks;blocks=0xffff; DOS_AllocateMemory(&seg,&blocks); - WriteOut(MSG_Get("PROGRAM_MEM_CONVEN"),blocks*16/1024); + if ((machine==MCH_PCJR) && (real_readb(0x2000,0)==0x5a) && (real_readw(0x2000,1)==0) && (real_readw(0x2000,3)==0x7ffe)) { + WriteOut(MSG_Get("PROGRAM_MEM_CONVEN"),0x7ffe*16/1024); + } else WriteOut(MSG_Get("PROGRAM_MEM_CONVEN"),blocks*16/1024); if (umb_start!=0xffff) { DOS_LinkUMBsToMemChain(1); @@ -451,11 +453,7 @@ public: fclose(usefile); /* write cartridge data into ROM */ - Bit16u romseg=0xe000; - if ((rombuf[7]==0x42) && (rombuf[8]==0x41) && (rombuf[9]==0x53) && (rombuf[10]==0x49)) { - /* BASIC rom, doesn't work though */ - romseg=0xf600; - } + Bit16u romseg=host_readw(&bootarea.rawdata[0x1ce]); for(i=0;i Date: Tue, 20 Dec 2005 08:42:40 +0000 Subject: [PATCH 2334/4131] Some endian fixes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2418 --- include/paging.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/include/paging.h b/include/paging.h index 9ab16588..4652b6a8 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.18 2005-09-03 19:20:08 c2woody Exp $ */ +/* $Id: paging.h,v 1.19 2005-12-20 08:42:40 qbix79 Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H @@ -82,6 +82,19 @@ void MEM_ResetPageHandler(Bitu phys_page, Bitu pages); #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; @@ -93,6 +106,7 @@ struct X86_PageEntryBlock{ Bit32u g:1; Bit32u avl:3; Bit32u base:20; +#endif } GCC_ATTRIBUTE(packed); #ifdef _MSC_VER #pragma pack () From 60be22c0edec224454986c871e5bab7f218eaabe Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 20 Dec 2005 08:56:16 +0000 Subject: [PATCH 2335/4131] Fix some endian issues Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2419 --- src/cpu/core_full/load.h | 170 ++++++++++---------- src/cpu/core_full/op.h | 298 ++++++++++++++++++------------------ src/cpu/core_full/save.h | 68 ++++---- src/cpu/core_full/support.h | 60 ++++++++ 4 files changed, 328 insertions(+), 268 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index ce95ddcc..73ced332 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -1,10 +1,10 @@ switch (inst.code.load) { /* General loading */ case L_POPwRM: - inst.op1.w = Pop_16(); + inst_op1_w = Pop_16(); goto case_L_MODRM; case L_POPdRM: - inst.op1.d = Pop_32(); + inst_op1_d = Pop_32(); goto case_L_MODRM; case_L_MODRM: case L_MODRM: @@ -21,160 +21,160 @@ l_MODRMswitch: switch (inst.code.extra) { /* Byte */ case M_Ib: - inst.op1.d=Fetchb(); + inst_op1_d=Fetchb(); break; case M_Ebx: - if (inst.rm<0xc0) inst.op1.ds=(Bit8s)LoadMb(inst.rm_eaa); - else inst.op1.ds=(Bit8s)reg_8(inst.rm_eai); + if (inst.rm<0xc0) inst_op1_ds=(Bit8s)LoadMb(inst.rm_eaa); + else inst_op1_ds=(Bit8s)reg_8(inst.rm_eai); break; case M_EbIb: - inst.op2.d=Fetchb(); + inst_op2_d=Fetchb(); case M_Eb: - if (inst.rm<0xc0) inst.op1.d=LoadMb(inst.rm_eaa); - else inst.op1.d=reg_8(inst.rm_eai); + if (inst.rm<0xc0) inst_op1_d=LoadMb(inst.rm_eaa); + else inst_op1_d=reg_8(inst.rm_eai); break; case M_EbGb: - if (inst.rm<0xc0) inst.op1.d=LoadMb(inst.rm_eaa); - else inst.op1.d=reg_8(inst.rm_eai); - inst.op2.d=reg_8(inst.rm_index); + if (inst.rm<0xc0) inst_op1_d=LoadMb(inst.rm_eaa); + else inst_op1_d=reg_8(inst.rm_eai); + inst_op2_d=reg_8(inst.rm_index); break; case M_GbEb: - if (inst.rm<0xc0) inst.op2.d=LoadMb(inst.rm_eaa); - else inst.op2.d=reg_8(inst.rm_eai); + if (inst.rm<0xc0) inst_op2_d=LoadMb(inst.rm_eaa); + else inst_op2_d=reg_8(inst.rm_eai); case M_Gb: - inst.op1.d=reg_8(inst.rm_index);; + inst_op1_d=reg_8(inst.rm_index);; break; /* Word */ case M_Iw: - inst.op1.d=Fetchw(); + inst_op1_d=Fetchw(); break; case M_EwxGwx: - inst.op2.ds=(Bit16s)reg_16(inst.rm_index); + inst_op2_ds=(Bit16s)reg_16(inst.rm_index); goto l_M_Ewx; case M_EwxIbx: - inst.op2.ds=Fetchbs(); + inst_op2_ds=Fetchbs(); goto l_M_Ewx; case M_EwxIwx: - inst.op2.ds=Fetchws(); + inst_op2_ds=Fetchws(); l_M_Ewx: case M_Ewx: - if (inst.rm<0xc0) inst.op1.ds=(Bit16s)LoadMw(inst.rm_eaa); - else inst.op1.ds=(Bit16s)reg_16(inst.rm_eai); + if (inst.rm<0xc0) inst_op1_ds=(Bit16s)LoadMw(inst.rm_eaa); + else inst_op1_ds=(Bit16s)reg_16(inst.rm_eai); break; case M_EwIb: - inst.op2.d=Fetchb(); + inst_op2_d=Fetchb(); goto l_M_Ew; case M_EwIbx: - inst.op2.ds=Fetchbs(); + inst_op2_ds=Fetchbs(); goto l_M_Ew; case M_EwIw: - inst.op2.d=Fetchw(); + inst_op2_d=Fetchw(); goto l_M_Ew; case M_EwGwCL: - inst.imm.d=reg_cl; + inst_imm_d=reg_cl; goto l_M_EwGw; case M_EwGwIb: - inst.imm.d=Fetchb(); + inst_imm_d=Fetchb(); goto l_M_EwGw; case M_EwGwt: - inst.op2.d=reg_16(inst.rm_index); - inst.rm_eaa+=((Bit16s)inst.op2.d >> 4) * 2; + inst_op2_d=reg_16(inst.rm_index); + inst.rm_eaa+=((Bit16s)inst_op2_d >> 4) * 2; goto l_M_Ew; l_M_EwGw: case M_EwGw: - inst.op2.d=reg_16(inst.rm_index); + inst_op2_d=reg_16(inst.rm_index); l_M_Ew: case M_Ew: - if (inst.rm<0xc0) inst.op1.d=LoadMw(inst.rm_eaa); - else inst.op1.d=reg_16(inst.rm_eai); + if (inst.rm<0xc0) inst_op1_d=LoadMw(inst.rm_eaa); + else inst_op1_d=reg_16(inst.rm_eai); break; case M_GwEw: - if (inst.rm<0xc0) inst.op2.d=LoadMw(inst.rm_eaa); - else inst.op2.d=reg_16(inst.rm_eai); + if (inst.rm<0xc0) inst_op2_d=LoadMw(inst.rm_eaa); + else inst_op2_d=reg_16(inst.rm_eai); case M_Gw: - inst.op1.d=reg_16(inst.rm_index);; + inst_op1_d=reg_16(inst.rm_index);; break; /* DWord */ case M_Id: - inst.op1.d=Fetchd(); + inst_op1_d=Fetchd(); break; case M_EdxGdx: - inst.op2.ds=(Bit32s)reg_32(inst.rm_index); + inst_op2_ds=(Bit32s)reg_32(inst.rm_index); case M_Edx: - if (inst.rm<0xc0) inst.op1.d=(Bit32s)LoadMd(inst.rm_eaa); - else inst.op1.d=(Bit32s)reg_32(inst.rm_eai); + if (inst.rm<0xc0) inst_op1_d=(Bit32s)LoadMd(inst.rm_eaa); + else inst_op1_d=(Bit32s)reg_32(inst.rm_eai); break; case M_EdIb: - inst.op2.d=Fetchb(); + inst_op2_d=Fetchb(); goto l_M_Ed; case M_EdIbx: - inst.op2.ds=Fetchbs(); + inst_op2_ds=Fetchbs(); goto l_M_Ed; case M_EdId: - inst.op2.d=Fetchd(); + inst_op2_d=Fetchd(); goto l_M_Ed; case M_EdGdCL: - inst.imm.d=reg_cl; + inst_imm_d=reg_cl; goto l_M_EdGd; case M_EdGdt: - inst.op2.d=reg_32(inst.rm_index); - inst.rm_eaa+=((Bit32s)inst.op2.d >> 5) * 4; + inst_op2_d=reg_32(inst.rm_index); + inst.rm_eaa+=((Bit32s)inst_op2_d >> 5) * 4; goto l_M_Ed; case M_EdGdIb: - inst.imm.d=Fetchb(); + inst_imm_d=Fetchb(); goto l_M_EdGd; l_M_EdGd: case M_EdGd: - inst.op2.d=reg_32(inst.rm_index); + inst_op2_d=reg_32(inst.rm_index); l_M_Ed: case M_Ed: - if (inst.rm<0xc0) inst.op1.d=LoadMd(inst.rm_eaa); - else inst.op1.d=reg_32(inst.rm_eai); + if (inst.rm<0xc0) inst_op1_d=LoadMd(inst.rm_eaa); + else inst_op1_d=reg_32(inst.rm_eai); break; case M_GdEd: - if (inst.rm<0xc0) inst.op2.d=LoadMd(inst.rm_eaa); - else inst.op2.d=reg_32(inst.rm_eai); + if (inst.rm<0xc0) inst_op2_d=LoadMd(inst.rm_eaa); + else inst_op2_d=reg_32(inst.rm_eai); case M_Gd: - inst.op1.d=reg_32(inst.rm_index); + inst_op1_d=reg_32(inst.rm_index); break; /* Others */ case M_SEG: //TODO Check for limit - inst.op1.d=SegValue((SegNames)inst.rm_index); + inst_op1_d=SegValue((SegNames)inst.rm_index); break; case M_Efw: if (inst.rm>=0xc0) goto illegalopcode; - inst.op1.d=LoadMw(inst.rm_eaa); - inst.op2.d=LoadMw(inst.rm_eaa+2); + inst_op1_d=LoadMw(inst.rm_eaa); + inst_op2_d=LoadMw(inst.rm_eaa+2); break; case M_Efd: if (inst.rm>=0xc0) goto illegalopcode; - inst.op1.d=LoadMd(inst.rm_eaa); - inst.op2.d=LoadMw(inst.rm_eaa+4); + inst_op1_d=LoadMd(inst.rm_eaa); + inst_op2_d=LoadMw(inst.rm_eaa+4); break; case M_EA: - inst.op1.d=inst.rm_off; + inst_op1_d=inst.rm_off; break; case M_POPw: - inst.op1.d = Pop_16(); + inst_op1_d = Pop_16(); break; case M_POPd: - inst.op1.d = Pop_32(); + inst_op1_d = Pop_32(); break; case M_GRP: inst.code=Groups[inst.code.op][inst.rm_index]; goto l_MODRMswitch; case M_GRP_Ib: - inst.op2.d=Fetchb(); + inst_op2_d=Fetchb(); inst.code=Groups[inst.code.op][inst.rm_index]; goto l_MODRMswitch; case M_GRP_CL: - inst.op2.d=reg_cl; + inst_op2_d=reg_cl; inst.code=Groups[inst.code.op][inst.rm_index]; goto l_MODRMswitch; case M_GRP_1: - inst.op2.d=1; + inst_op2_d=1; inst.code=Groups[inst.code.op][inst.rm_index]; goto l_MODRMswitch; case 0: @@ -185,61 +185,61 @@ l_M_Ed: } break; case L_POPw: - inst.op1.d = Pop_16(); + inst_op1_d = Pop_16(); break; case L_POPd: - inst.op1.d = Pop_32(); + inst_op1_d = Pop_32(); break; case L_POPfw: - inst.op1.d = Pop_16(); - inst.op2.d = Pop_16(); + inst_op1_d = Pop_16(); + inst_op2_d = Pop_16(); break; case L_POPfd: - inst.op1.d = Pop_32(); - inst.op2.d = Pop_16(); + inst_op1_d = Pop_32(); + inst_op2_d = Pop_16(); break; case L_Ib: - inst.op1.d=Fetchb(); + inst_op1_d=Fetchb(); break; case L_Ibx: - inst.op1.ds=Fetchbs(); + inst_op1_ds=Fetchbs(); break; case L_Iw: - inst.op1.d=Fetchw(); + inst_op1_d=Fetchw(); break; case L_Iwx: - inst.op1.ds=Fetchws(); + inst_op1_ds=Fetchws(); break; case L_Idx: case L_Id: - inst.op1.d=Fetchd(); + inst_op1_d=Fetchd(); break; case L_Ifw: - inst.op1.d=Fetchw(); - inst.op2.d=Fetchw(); + inst_op1_d=Fetchw(); + inst_op2_d=Fetchw(); break; case L_Ifd: - inst.op1.d=Fetchd(); - inst.op2.d=Fetchw(); + inst_op1_d=Fetchd(); + inst_op2_d=Fetchw(); break; /* Direct load of registers */ case L_REGbIb: - inst.op2.d=Fetchb(); + inst_op2_d=Fetchb(); case L_REGb: - inst.op1.d=reg_8(inst.code.extra); + inst_op1_d=reg_8(inst.code.extra); break; case L_REGwIw: - inst.op2.d=Fetchw(); + inst_op2_d=Fetchw(); case L_REGw: - inst.op1.d=reg_16(inst.code.extra); + inst_op1_d=reg_16(inst.code.extra); break; case L_REGdId: - inst.op2.d=Fetchd(); + inst_op2_d=Fetchd(); case L_REGd: - inst.op1.d=reg_32(inst.code.extra); + inst_op1_d=reg_32(inst.code.extra); break; case L_SEG: - inst.op1.d=SegValue((SegNames)inst.code.extra); + inst_op1_d=SegValue((SegNames)inst.code.extra); break; /* Depending on addressize */ case L_OP: @@ -277,11 +277,11 @@ l_M_Ed: inst.prefix=(inst.prefix & ~1) | (cpu.code.big ^ 1); goto restartopcode; case L_VAL: - inst.op1.d=inst.code.extra; + inst_op1_d=inst.code.extra; break; case L_INTO: if (!get_OF()) goto nextopcode; - inst.op1.d=4; + inst_op1_d=4; break; case D_IRETw: FillFlags(); diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 4432c5e2..8f25a72d 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -1,223 +1,223 @@ /* Do the actual opcode */ switch (inst.code.op) { case t_ADDb: case t_ADDw: case t_ADDd: - lf_var1d=inst.op1.d; - lf_var2d=inst.op2.d; - inst.op1.d=lf_resd=lf_var1d + lf_var2d; + lf_var1d=inst_op1_d; + lf_var2d=inst_op2_d; + inst_op1_d=lf_resd=lf_var1d + lf_var2d; lflags.type=inst.code.op; break; case t_CMPb: case t_CMPw: case t_CMPd: case t_SUBb: case t_SUBw: case t_SUBd: - lf_var1d=inst.op1.d; - lf_var2d=inst.op2.d; - inst.op1.d=lf_resd=lf_var1d - lf_var2d; + lf_var1d=inst_op1_d; + lf_var2d=inst_op2_d; + inst_op1_d=lf_resd=lf_var1d - lf_var2d; lflags.type=inst.code.op; break; case t_ORb: case t_ORw: case t_ORd: - lf_var1d=inst.op1.d; - lf_var2d=inst.op2.d; - inst.op1.d=lf_resd=lf_var1d | lf_var2d; + lf_var1d=inst_op1_d; + lf_var2d=inst_op2_d; + inst_op1_d=lf_resd=lf_var1d | lf_var2d; lflags.type=inst.code.op; break; case t_XORb: case t_XORw: case t_XORd: - lf_var1d=inst.op1.d; - lf_var2d=inst.op2.d; - inst.op1.d=lf_resd=lf_var1d ^ lf_var2d; + lf_var1d=inst_op1_d; + lf_var2d=inst_op2_d; + inst_op1_d=lf_resd=lf_var1d ^ lf_var2d; lflags.type=inst.code.op; break; case t_TESTb: case t_TESTw: case t_TESTd: case t_ANDb: case t_ANDw: case t_ANDd: - lf_var1d=inst.op1.d; - lf_var2d=inst.op2.d; - inst.op1.d=lf_resd=lf_var1d & lf_var2d; + lf_var1d=inst_op1_d; + lf_var2d=inst_op2_d; + inst_op1_d=lf_resd=lf_var1d & lf_var2d; lflags.type=inst.code.op; break; case t_ADCb: case t_ADCw: case t_ADCd: lflags.oldcf=(get_CF()!=0); - lf_var1d=inst.op1.d; - lf_var2d=inst.op2.d; - inst.op1.d=lf_resd=lf_var1d + lf_var2d + lflags.oldcf; + lf_var1d=inst_op1_d; + lf_var2d=inst_op2_d; + inst_op1_d=lf_resd=lf_var1d + lf_var2d + lflags.oldcf; lflags.type=inst.code.op; break; case t_SBBb: case t_SBBw: case t_SBBd: lflags.oldcf=(get_CF()!=0); - lf_var1d=inst.op1.d; - lf_var2d=inst.op2.d; - inst.op1.d=lf_resd=lf_var1d - lf_var2d - lflags.oldcf; + lf_var1d=inst_op1_d; + lf_var2d=inst_op2_d; + inst_op1_d=lf_resd=lf_var1d - lf_var2d - lflags.oldcf; lflags.type=inst.code.op; break; case t_INCb: case t_INCw: case t_INCd: LoadCF; - lf_var1d=inst.op1.d; - inst.op1.d=lf_resd=inst.op1.d+1; + lf_var1d=inst_op1_d; + inst_op1_d=lf_resd=inst_op1_d+1; lflags.type=inst.code.op; break; case t_DECb: case t_DECw: case t_DECd: LoadCF; - lf_var1d=inst.op1.d; - inst.op1.d=lf_resd=inst.op1.d-1; + lf_var1d=inst_op1_d; + inst_op1_d=lf_resd=inst_op1_d-1; lflags.type=inst.code.op; break; /* Using the instructions.h defines */ case t_ROLb: - ROLB(inst.op1.b,inst.op2.b,LoadD,SaveD); + ROLB(inst_op1_b,inst_op2_b,LoadD,SaveD); break; case t_ROLw: - ROLW(inst.op1.w,inst.op2.b,LoadD,SaveD); + ROLW(inst_op1_w,inst_op2_b,LoadD,SaveD); break; case t_ROLd: - ROLD(inst.op1.d,inst.op2.b,LoadD,SaveD); + ROLD(inst_op1_d,inst_op2_b,LoadD,SaveD); break; case t_RORb: - RORB(inst.op1.b,inst.op2.b,LoadD,SaveD); + RORB(inst_op1_b,inst_op2_b,LoadD,SaveD); break; case t_RORw: - RORW(inst.op1.w,inst.op2.b,LoadD,SaveD); + RORW(inst_op1_w,inst_op2_b,LoadD,SaveD); break; case t_RORd: - RORD(inst.op1.d,inst.op2.b,LoadD,SaveD); + RORD(inst_op1_d,inst_op2_b,LoadD,SaveD); break; case t_RCLb: - RCLB(inst.op1.b,inst.op2.b,LoadD,SaveD); + RCLB(inst_op1_b,inst_op2_b,LoadD,SaveD); break; case t_RCLw: - RCLW(inst.op1.w,inst.op2.b,LoadD,SaveD); + RCLW(inst_op1_w,inst_op2_b,LoadD,SaveD); break; case t_RCLd: - RCLD(inst.op1.d,inst.op2.b,LoadD,SaveD); + RCLD(inst_op1_d,inst_op2_b,LoadD,SaveD); break; case t_RCRb: - RCRB(inst.op1.b,inst.op2.b,LoadD,SaveD); + RCRB(inst_op1_b,inst_op2_b,LoadD,SaveD); break; case t_RCRw: - RCRW(inst.op1.w,inst.op2.b,LoadD,SaveD); + RCRW(inst_op1_w,inst_op2_b,LoadD,SaveD); break; case t_RCRd: - RCRD(inst.op1.d,inst.op2.b,LoadD,SaveD); + RCRD(inst_op1_d,inst_op2_b,LoadD,SaveD); break; case t_SHLb: - SHLB(inst.op1.b,inst.op2.b,LoadD,SaveD); + SHLB(inst_op1_b,inst_op2_b,LoadD,SaveD); break; case t_SHLw: - SHLW(inst.op1.w,inst.op2.b,LoadD,SaveD); + SHLW(inst_op1_w,inst_op2_b,LoadD,SaveD); break; case t_SHLd: - SHLD(inst.op1.d,inst.op2.b,LoadD,SaveD); + SHLD(inst_op1_d,inst_op2_b,LoadD,SaveD); break; case t_SHRb: - SHRB(inst.op1.b,inst.op2.b,LoadD,SaveD); + SHRB(inst_op1_b,inst_op2_b,LoadD,SaveD); break; case t_SHRw: - SHRW(inst.op1.w,inst.op2.b,LoadD,SaveD); + SHRW(inst_op1_w,inst_op2_b,LoadD,SaveD); break; case t_SHRd: - SHRD(inst.op1.d,inst.op2.b,LoadD,SaveD); + SHRD(inst_op1_d,inst_op2_b,LoadD,SaveD); break; case t_SARb: - SARB(inst.op1.b,inst.op2.b,LoadD,SaveD); + SARB(inst_op1_b,inst_op2_b,LoadD,SaveD); break; case t_SARw: - SARW(inst.op1.w,inst.op2.b,LoadD,SaveD); + SARW(inst_op1_w,inst_op2_b,LoadD,SaveD); break; case t_SARd: - SARD(inst.op1.d,inst.op2.b,LoadD,SaveD); + SARD(inst_op1_d,inst_op2_b,LoadD,SaveD); break; case O_DSHLw: { - DSHLW(inst.op1.w,inst.op2.w,inst.imm.b,LoadD,SaveD); + DSHLW(inst_op1_w,inst_op2_w,inst_imm_b,LoadD,SaveD); break; } case O_DSHRw: { - DSHRW(inst.op1.w,inst.op2.w,inst.imm.b,LoadD,SaveD); + DSHRW(inst_op1_w,inst_op2_w,inst_imm_b,LoadD,SaveD); break; } case O_DSHLd: { - DSHLD(inst.op1.d,inst.op2.d,inst.imm.b,LoadD,SaveD); + DSHLD(inst_op1_d,inst_op2_d,inst_imm_b,LoadD,SaveD); break; } case O_DSHRd: { - DSHRD(inst.op1.d,inst.op2.d,inst.imm.b,LoadD,SaveD); + DSHRD(inst_op1_d,inst_op2_d,inst_imm_b,LoadD,SaveD); break; } case t_NEGb: - lf_var1b=inst.op1.b; - inst.op1.b=lf_resb=0-inst.op1.b; + lf_var1b=inst_op1_b; + inst_op1_b=lf_resb=0-inst_op1_b; lflags.type=t_NEGb; break; case t_NEGw: - lf_var1w=inst.op1.w; - inst.op1.w=lf_resw=0-inst.op1.w; + lf_var1w=inst_op1_w; + inst_op1_w=lf_resw=0-inst_op1_w; lflags.type=t_NEGw; break; case t_NEGd: - lf_var1d=inst.op1.d; - inst.op1.d=lf_resd=0-inst.op1.d; + lf_var1d=inst_op1_d; + inst_op1_d=lf_resd=0-inst_op1_d; lflags.type=t_NEGd; break; case O_NOT: - inst.op1.d=~inst.op1.d; + inst_op1_d=~inst_op1_d; break; /* Special instructions */ case O_IMULRw: - DIMULW(inst.op1.ws,inst.op1.ws,inst.op2.ws,LoadD,SaveD); + DIMULW(inst_op1_ws,inst_op1_ws,inst_op2_ws,LoadD,SaveD); break; case O_IMULRd: - DIMULD(inst.op1.ds,inst.op1.ds,inst.op2.ds,LoadD,SaveD); + DIMULD(inst_op1_ds,inst_op1_ds,inst_op2_ds,LoadD,SaveD); break; case O_MULb: - MULB(inst.op1.b,LoadD,0); + MULB(inst_op1_b,LoadD,0); goto nextopcode; case O_MULw: - MULW(inst.op1.w,LoadD,0); + MULW(inst_op1_w,LoadD,0); goto nextopcode; case O_MULd: - MULD(inst.op1.d,LoadD,0); + MULD(inst_op1_d,LoadD,0); goto nextopcode; case O_IMULb: - IMULB(inst.op1.b,LoadD,0); + IMULB(inst_op1_b,LoadD,0); goto nextopcode; case O_IMULw: - IMULW(inst.op1.w,LoadD,0); + IMULW(inst_op1_w,LoadD,0); goto nextopcode; case O_IMULd: - IMULD(inst.op1.d,LoadD,0); + IMULD(inst_op1_d,LoadD,0); goto nextopcode; case O_DIVb: - DIVB(inst.op1.b,LoadD,0); + DIVB(inst_op1_b,LoadD,0); goto nextopcode; case O_DIVw: - DIVW(inst.op1.w,LoadD,0); + DIVW(inst_op1_w,LoadD,0); goto nextopcode; case O_DIVd: - DIVD(inst.op1.d,LoadD,0); + DIVD(inst_op1_d,LoadD,0); goto nextopcode; case O_IDIVb: - IDIVB(inst.op1.b,LoadD,0); + IDIVB(inst_op1_b,LoadD,0); goto nextopcode; case O_IDIVw: - IDIVW(inst.op1.w,LoadD,0); + IDIVW(inst_op1_w,LoadD,0); goto nextopcode; case O_IDIVd: - IDIVD(inst.op1.d,LoadD,0); + IDIVD(inst_op1_d,LoadD,0); goto nextopcode; case O_AAM: - AAM(inst.op1.b); + AAM(inst_op1_b); goto nextopcode; case O_AAD: - AAD(inst.op1.b); + AAD(inst_op1_b); goto nextopcode; case O_C_O: inst.cond=TFLG_O; break; @@ -302,15 +302,15 @@ switch (inst.code.op) { case O_XCHG_AX: { Bit16u temp=reg_ax; - reg_ax=inst.op1.w; - inst.op1.w=temp; + reg_ax=inst_op1_w; + inst_op1_w=temp; break; } case O_XCHG_EAX: { Bit32u temp=reg_eax; - reg_eax=inst.op1.d; - inst.op1.d=temp; + reg_eax=inst_op1_d; + inst_op1_d=temp; break; } case O_CALLNw: @@ -323,57 +323,57 @@ switch (inst.code.op) { break; case O_CALLFw: FillFlags(); - CPU_CALL(false,inst.op2.d,inst.op1.d,GetIP()); + CPU_CALL(false,inst_op2_d,inst_op1_d,GetIP()); continue; case O_CALLFd: FillFlags(); - CPU_CALL(true,inst.op2.d,inst.op1.d,GetIP()); + CPU_CALL(true,inst_op2_d,inst_op1_d,GetIP()); continue; case O_JMPFw: FillFlags(); - CPU_JMP(false,inst.op2.d,inst.op1.d,GetIP()); + CPU_JMP(false,inst_op2_d,inst_op1_d,GetIP()); continue; case O_JMPFd: FillFlags(); - CPU_JMP(true,inst.op2.d,inst.op1.d,GetIP()); + CPU_JMP(true,inst_op2_d,inst_op1_d,GetIP()); continue; case O_INT: FillFlags(); #if C_DEBUG if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint()) return debugCallback; - else if (DEBUG_IntBreakpoint(inst.op1.b)) + else if (DEBUG_IntBreakpoint(inst_op1_b)) return debugCallback; #endif - CPU_SW_Interrupt(inst.op1.b,GetIP()); + CPU_SW_Interrupt(inst_op1_b,GetIP()); continue; case O_INb: - if (CPU_IO_Exception(inst.op1.d,1)) RunException(); - reg_al=IO_ReadB(inst.op1.d); + if (CPU_IO_Exception(inst_op1_d,1)) RunException(); + reg_al=IO_ReadB(inst_op1_d); goto nextopcode; case O_INw: - if (CPU_IO_Exception(inst.op1.d,2)) RunException(); - reg_ax=IO_ReadW(inst.op1.d); + if (CPU_IO_Exception(inst_op1_d,2)) RunException(); + reg_ax=IO_ReadW(inst_op1_d); goto nextopcode; case O_INd: - if (CPU_IO_Exception(inst.op1.d,4)) RunException(); - reg_eax=IO_ReadD(inst.op1.d); + if (CPU_IO_Exception(inst_op1_d,4)) RunException(); + reg_eax=IO_ReadD(inst_op1_d); goto nextopcode; case O_OUTb: - if (CPU_IO_Exception(inst.op1.d,1)) RunException(); - IO_WriteB(inst.op1.d,reg_al); + if (CPU_IO_Exception(inst_op1_d,1)) RunException(); + IO_WriteB(inst_op1_d,reg_al); goto nextopcode; case O_OUTw: - if (CPU_IO_Exception(inst.op1.d,2)) RunException(); - IO_WriteW(inst.op1.d,reg_ax); + if (CPU_IO_Exception(inst_op1_d,2)) RunException(); + IO_WriteW(inst_op1_d,reg_ax); goto nextopcode; case O_OUTd: - if (CPU_IO_Exception(inst.op1.d,4)) RunException(); - IO_WriteD(inst.op1.d,reg_eax); + if (CPU_IO_Exception(inst_op1_d,4)) RunException(); + IO_WriteD(inst_op1_d,reg_eax); goto nextopcode; case O_CBACK: FillFlags();SaveIP(); - return inst.op1.d; + return inst_op1_d; case O_GRP6w: case O_GRP6d: if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode; @@ -382,31 +382,31 @@ switch (inst.code.op) { { Bitu selector; CPU_SLDT(selector); - inst.op1.d=(Bit32u)selector; + inst_op1_d=(Bit32u)selector; } break; case 0x01: /* STR */ { Bitu selector; CPU_STR(selector); - inst.op1.d=(Bit32u)selector; + inst_op1_d=(Bit32u)selector; } break; case 0x02: /* LLDT */ if (cpu.cpl) EXCEPTION(EXCEPTION_GP); - if (CPU_LLDT(inst.op1.d)) RunException(); + if (CPU_LLDT(inst_op1_d)) RunException(); goto nextopcode; /* Else value will saved */ case 0x03: /* LTR */ if (cpu.cpl) EXCEPTION(EXCEPTION_GP); - if (CPU_LTR(inst.op1.d)) RunException(); + if (CPU_LTR(inst_op1_d)) RunException(); goto nextopcode; /* Else value will saved */ case 0x04: /* VERR */ FillFlags(); - CPU_VERR(inst.op1.d); + CPU_VERR(inst_op1_d); goto nextopcode; /* Else value will saved */ case 0x05: /* VERW */ FillFlags(); - CPU_VERW(inst.op1.d); + CPU_VERW(inst_op1_d); goto nextopcode; /* Else value will saved */ default: LOG(LOG_CPU,LOG_ERROR)("Group 6 Illegal subfunction %X",inst.rm_index); @@ -443,12 +443,12 @@ switch (inst.code.op) { case 4: /* SMSW */ { Bitu word;CPU_SMSW(word); - inst.op1.d=word; + inst_op1_d=word; break; } case 6: /* LMSW */ FillFlags(); - if (CPU_LMSW(inst.op1.w)) RunException(); + if (CPU_LMSW(inst_op1_w)) RunException(); goto nextopcode; default: LOG(LOG_CPU,LOG_ERROR)("Group 7 Illegal subfunction %X",inst.rm_index); @@ -456,57 +456,57 @@ switch (inst.code.op) { } break; case O_M_CRx_Rd: - if (CPU_WRITE_CRX(inst.rm_index,inst.op1.d)) RunException(); + if (CPU_WRITE_CRX(inst.rm_index,inst_op1_d)) RunException(); break; case O_M_Rd_CRx: - if (CPU_READ_CRX(inst.rm_index,inst.op1.d)) RunException(); + if (CPU_READ_CRX(inst.rm_index,inst_op1_d)) RunException(); break; case O_M_DRx_Rd: - if (CPU_WRITE_DRX(inst.rm_index,inst.op1.d)) RunException(); + if (CPU_WRITE_DRX(inst.rm_index,inst_op1_d)) RunException(); break; case O_M_Rd_DRx: - if (CPU_READ_DRX(inst.rm_index,inst.op1.d)) RunException(); + if (CPU_READ_DRX(inst.rm_index,inst_op1_d)) RunException(); break; case O_LAR: { if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode; FillFlags(); - Bitu ar=inst.op2.d; - CPU_LAR(inst.op1.w,ar); - inst.op1.d=(Bit32u)ar; + Bitu ar=inst_op2_d; + CPU_LAR(inst_op1_w,ar); + inst_op1_d=(Bit32u)ar; } break; case O_LSL: { if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode; FillFlags(); - Bitu limit=inst.op2.d; - CPU_LSL(inst.op1.w,limit); - inst.op1.d=(Bit32u)limit; + Bitu limit=inst_op2_d; + CPU_LSL(inst_op1_w,limit); + inst_op1_d=(Bit32u)limit; } break; case O_ARPL: { if ((reg_flags & FLAG_VM) || !cpu.pmode) goto illegalopcode; FillFlags(); - Bitu new_sel=inst.op1.d; - CPU_ARPL(new_sel,inst.op2.d); - inst.op1.d=(Bit32u)new_sel; + Bitu new_sel=inst_op1_d; + CPU_ARPL(new_sel,inst_op2_d); + inst_op1_d=(Bit32u)new_sel; } break; case O_BSFw: { FillFlags(); - if (!inst.op1.w) { + if (!inst_op1_w) { SETFLAGBIT(ZF,true); goto nextopcode; } else { Bitu count=0; while (1) { - if (inst.op1.w & 0x1) break; - count++;inst.op1.w>>=1; + if (inst_op1_w & 0x1) break; + count++;inst_op1_w>>=1; } - inst.op1.d=count; + inst_op1_d=count; SETFLAGBIT(ZF,false); } } @@ -514,16 +514,16 @@ switch (inst.code.op) { case O_BSFd: { FillFlags(); - if (!inst.op1.d) { + if (!inst_op1_d) { SETFLAGBIT(ZF,true); goto nextopcode; } else { Bitu count=0; while (1) { - if (inst.op1.d & 0x1) break; - count++;inst.op1.d>>=1; + if (inst_op1_d & 0x1) break; + count++;inst_op1_d>>=1; } - inst.op1.d=count; + inst_op1_d=count; SETFLAGBIT(ZF,false); } } @@ -531,16 +531,16 @@ switch (inst.code.op) { case O_BSRw: { FillFlags(); - if (!inst.op1.w) { + if (!inst_op1_w) { SETFLAGBIT(ZF,true); goto nextopcode; } else { Bitu count=15; while (1) { - if (inst.op1.w & 0x8000) break; - count--;inst.op1.w<<=1; + if (inst_op1_w & 0x8000) break; + count--;inst_op1_w<<=1; } - inst.op1.d=count; + inst_op1_d=count; SETFLAGBIT(ZF,false); } } @@ -548,60 +548,60 @@ switch (inst.code.op) { case O_BSRd: { FillFlags(); - if (!inst.op1.d) { + if (!inst_op1_d) { SETFLAGBIT(ZF,true); goto nextopcode; } else { Bitu count=31; while (1) { - if (inst.op1.d & 0x80000000) break; - count--;inst.op1.d<<=1; + if (inst_op1_d & 0x80000000) break; + count--;inst_op1_d<<=1; } - inst.op1.d=count; + inst_op1_d=count; SETFLAGBIT(ZF,false); } } break; case O_BTw: FillFlags(); - SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15)))); + SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 15)))); break; case O_BTSw: FillFlags(); - SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15)))); - inst.op1.d|=(1 << (inst.op2.d & 15)); + SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 15)))); + inst_op1_d|=(1 << (inst_op2_d & 15)); break; case O_BTCw: FillFlags(); - SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15)))); - inst.op1.d^=(1 << (inst.op2.d & 15)); + SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 15)))); + inst_op1_d^=(1 << (inst_op2_d & 15)); break; case O_BTRw: FillFlags(); - SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15)))); - inst.op1.d&=~(1 << (inst.op2.d & 15)); + SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 15)))); + inst_op1_d&=~(1 << (inst_op2_d & 15)); break; case O_BTd: FillFlags(); - SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31)))); + SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 31)))); break; case O_BTSd: FillFlags(); - SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31)))); - inst.op1.d|=(1 << (inst.op2.d & 31)); + SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 31)))); + inst_op1_d|=(1 << (inst_op2_d & 31)); break; case O_BTCd: FillFlags(); - SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31)))); - inst.op1.d^=(1 << (inst.op2.d & 31)); + SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 31)))); + inst_op1_d^=(1 << (inst_op2_d & 31)); break; case O_BTRd: FillFlags(); - SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31)))); - inst.op1.d&=~(1 << (inst.op2.d & 31)); + SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 31)))); + inst_op1_d&=~(1 << (inst_op2_d & 31)); break; case O_BSWAP: - BSWAP(inst.op1.d); + BSWAP(inst_op1_d); break; case O_FPU: #if C_FPU @@ -634,7 +634,7 @@ switch (inst.code.op) { Bit16s bound_min, bound_max; bound_min=LoadMw(inst.rm_eaa); bound_max=LoadMw(inst.rm_eaa+2); - if ( (((Bit16s)inst.op1.w) < bound_min) || (((Bit16s)inst.op1.w) > bound_max) ) { + if ( (((Bit16s)inst_op1_w) < bound_min) || (((Bit16s)inst_op1_w) > bound_max) ) { EXCEPTION(5); } } diff --git a/src/cpu/core_full/save.h b/src/cpu/core_full/save.h index ba9968e4..4e10db12 100644 --- a/src/cpu/core_full/save.h +++ b/src/cpu/core_full/save.h @@ -2,95 +2,95 @@ switch (inst.code.save) { /* Byte */ case S_C_Eb: - inst.op1.b=inst.cond ? 1 : 0; + inst_op1_b=inst.cond ? 1 : 0; case S_Eb: - if (inst.rm<0xc0) SaveMb(inst.rm_eaa,inst.op1.b); - else reg_8(inst.rm_eai)=inst.op1.b; + if (inst.rm<0xc0) SaveMb(inst.rm_eaa,inst_op1_b); + else reg_8(inst.rm_eai)=inst_op1_b; break; case S_Gb: - reg_8(inst.rm_index)=inst.op1.b; + reg_8(inst.rm_index)=inst_op1_b; break; case S_EbGb: - if (inst.rm<0xc0) SaveMb(inst.rm_eaa,inst.op1.b); - else reg_8(inst.rm_eai)=inst.op1.b; - reg_8(inst.rm_index)=inst.op2.b; + if (inst.rm<0xc0) SaveMb(inst.rm_eaa,inst_op1_b); + else reg_8(inst.rm_eai)=inst_op1_b; + reg_8(inst.rm_index)=inst_op2_b; break; /* Word */ case S_Ew: - if (inst.rm<0xc0) SaveMw(inst.rm_eaa,inst.op1.w); - else reg_16(inst.rm_eai)=inst.op1.w; + if (inst.rm<0xc0) SaveMw(inst.rm_eaa,inst_op1_w); + else reg_16(inst.rm_eai)=inst_op1_w; break; case S_Gw: - reg_16(inst.rm_index)=inst.op1.w; + reg_16(inst.rm_index)=inst_op1_w; break; case S_EwGw: - if (inst.rm<0xc0) SaveMw(inst.rm_eaa,inst.op1.w); - else reg_16(inst.rm_eai)=inst.op1.w; - reg_16(inst.rm_index)=inst.op2.w; + if (inst.rm<0xc0) SaveMw(inst.rm_eaa,inst_op1_w); + else reg_16(inst.rm_eai)=inst_op1_w; + reg_16(inst.rm_index)=inst_op2_w; break; /* Dword */ case S_Ed: - if (inst.rm<0xc0) SaveMd(inst.rm_eaa,inst.op1.d); - else reg_32(inst.rm_eai)=inst.op1.d; + if (inst.rm<0xc0) SaveMd(inst.rm_eaa,inst_op1_d); + else reg_32(inst.rm_eai)=inst_op1_d; break; case S_EdMw: /* Special one 16 to memory, 32 zero extend to reg */ - if (inst.rm<0xc0) SaveMw(inst.rm_eaa,inst.op1.w); - else reg_32(inst.rm_eai)=inst.op1.d; + if (inst.rm<0xc0) SaveMw(inst.rm_eaa,inst_op1_w); + else reg_32(inst.rm_eai)=inst_op1_d; break; case S_Gd: - reg_32(inst.rm_index)=inst.op1.d; + reg_32(inst.rm_index)=inst_op1_d; break; case S_EdGd: - if (inst.rm<0xc0) SaveMd(inst.rm_eaa,inst.op1.d); - else reg_32(inst.rm_eai)=inst.op1.d; - reg_32(inst.rm_index)=inst.op2.d; + if (inst.rm<0xc0) SaveMd(inst.rm_eaa,inst_op1_d); + else reg_32(inst.rm_eai)=inst_op1_d; + reg_32(inst.rm_index)=inst_op2_d; break; case S_REGb: - reg_8(inst.code.extra)=inst.op1.b; + reg_8(inst.code.extra)=inst_op1_b; break; case S_REGw: - reg_16(inst.code.extra)=inst.op1.w; + reg_16(inst.code.extra)=inst_op1_w; break; case S_REGd: - reg_32(inst.code.extra)=inst.op1.d; + reg_32(inst.code.extra)=inst_op1_d; break; case S_SEGm: - if (CPU_SetSegGeneral((SegNames)inst.rm_index,inst.op1.w)) RunException(); + if (CPU_SetSegGeneral((SegNames)inst.rm_index,inst_op1_w)) RunException(); break; case S_SEGGw: - if (CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w)) RunException(); - reg_16(inst.rm_index)=inst.op1.w; + if (CPU_SetSegGeneral((SegNames)inst.code.extra,inst_op2_w)) RunException(); + reg_16(inst.rm_index)=inst_op1_w; break; case S_SEGGd: - if (CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w)) RunException(); - reg_32(inst.rm_index)=inst.op1.d; + if (CPU_SetSegGeneral((SegNames)inst.code.extra,inst_op2_w)) RunException(); + reg_32(inst.rm_index)=inst_op1_d; break; case S_PUSHw: - Push_16(inst.op1.w); + Push_16(inst_op1_w); break; case S_PUSHd: - Push_32(inst.op1.d); + Push_32(inst_op1_d); break; case S_C_AIPw: if (!inst.cond) goto nextopcode; case S_AIPw: SaveIP(); - reg_eip+=inst.op1.d; + reg_eip+=inst_op1_d; reg_eip&=0xffff; continue; case S_C_AIPd: if (!inst.cond) goto nextopcode; case S_AIPd: SaveIP(); - reg_eip+=inst.op1.d; + reg_eip+=inst_op1_d; continue; case S_IPIw: reg_esp+=Fetchw(); case S_IP: SaveIP(); - reg_eip=inst.op1.d; + reg_eip=inst_op1_d; continue; case 0: break; diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 21561c77..d7f68f70 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -165,11 +165,22 @@ struct FullData { Bitu rm_mod; OpCode code; EAPoint cseip; +#ifdef WORDS_BIGENDIAN + union { + Bit32u dword[1]; + Bit32s dwords[1]; + Bit16u word[2]; + Bit16s words[2]; + Bit8u byte[4]; + Bit8s bytes[4]; + } blah1,blah2,blah_imm; +#else union { Bit8u b;Bit8s bs; Bit16u w;Bit16s ws; Bit32u d;Bit32s ds; } op1,op2,imm; +#endif Bitu new_flags; struct { EAPoint base; @@ -179,6 +190,55 @@ struct FullData { Bitu prefix; }; +/* Some defines to get the names correct. */ +#ifdef WORDS_BIGENDIAN + +#define inst_op1_b inst.blah1.byte[3] +#define inst_op1_bs inst.blah1.bytes[3] +#define inst_op1_w inst.blah1.word[1] +#define inst_op1_ws inst.blah1.words[1] +#define inst_op1_d inst.blah1.dword[0] +#define inst_op1_ds inst.blah1.dwords[0] + +#define inst_op2_b inst.blah2.byte[3] +#define inst_op2_bs inst.blah2.bytes[3] +#define inst_op2_w inst.blah2.word[1] +#define inst_op2_ws inst.blah2.words[1] +#define inst_op2_d inst.blah2.dword[0] +#define inst_op2_ds inst.blah2.dwords[0] + +#define inst_imm_b inst.blah_imm.byte[3] +#define inst_imm_bs inst.blah_imm.bytes[3] +#define inst_imm_w inst.blah_imm.word[1] +#define inst_imm_ws inst.blah_imm.words[1] +#define inst_imm_d inst.blah_imm.dword[0] +#define inst_imm_ds inst.blah_imm.dwords[0] + +#else + +#define inst_op1_b inst.op1.b +#define inst_op1_bs inst.op1.bs +#define inst_op1_w inst.op1.w +#define inst_op1_ws inst.op1.ws +#define inst_op1_d inst.op1.d +#define inst_op1_ds inst.op1.ds + +#define inst_op2_b inst.op2.b +#define inst_op2_bs inst.op2.bs +#define inst_op2_w inst.op2.w +#define inst_op2_ws inst.op2.ws +#define inst_op2_d inst.op2.d +#define inst_op2_ds inst.op2.ds + +#define inst_imm_b inst.imm.b +#define inst_imm_bs inst.imm.bs +#define inst_imm_w inst.imm.w +#define inst_imm_ws inst.imm.ws +#define inst_imm_d inst.imm.d +#define inst_imm_ds inst.imm.ds + +#endif + #define PREFIX_NONE 0x0 #define PREFIX_ADDR 0x1 From 15455827d95c9d622ec101d518331d73a04ca399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 20 Dec 2005 21:33:02 +0000 Subject: [PATCH 2336/4131] faster resume of tandy DAC playing after stop request (Outrun) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2420 --- src/ints/bios.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 11ca7096..8eb2e430 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.54 2005-12-17 16:28:18 c2woody Exp $ */ +/* $Id: bios.cpp,v 1.55 2005-12-20 21:33:02 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -119,8 +119,13 @@ static bool Tandy_TransferInProgress(void) { if (real_readb(0x40,0xd4)==0xff) return false; /* still in init-state */ IO_Write(0x0c,0x00); - Bit16u datalen=IO_ReadB(tandy_sb.dma*2+1)|(IO_ReadB(tandy_sb.dma*2+1)<<8); + Bit16u datalen=IO_ReadB(tandy_sb.dma*2+1); + datalen|=(IO_ReadB(tandy_sb.dma*2+1)<<8); if (datalen==0xffff) return false; /* no DMA transfer */ + else if ((datalen<0x10) && (real_readb(0x40,0xd4)==0x0f) && (real_readw(0x40,0xd2)==0x1c)) { + /* stop already requested */ + return false; + } return true; } @@ -137,6 +142,7 @@ static void Tandy_SetupTransfer(PhysPt bufpt,bool isplayback) { RealSetVec(tandy_sb.irq+8,tandy_DAC_callback->Get_RealPointer()); } + IO_Write(tandy_sb.port+0xc,0xd0); /* stop DMA transfer */ IO_Write(0x21,IO_Read(0x21)&(~(1< Date: Thu, 22 Dec 2005 20:37:20 +0000 Subject: [PATCH 2337/4131] use fixed keyboard buffer start/end for old bioses (ApplePanic booter); enable PCJr selection Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2421 --- src/dosbox.cpp | 5 +++-- src/ints/bios_keyboard.cpp | 20 ++++++++++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 28da68d6..c2d5294f 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.90 2005-11-16 20:27:39 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.91 2005-12-22 20:37:20 c2woody Exp $ */ #include #include @@ -179,6 +179,7 @@ static void DOSBOX_RealInit(Section * sec) { else mtype=section->Get_string("machine"); if (strcasecmp(mtype,"cga")==0) machine=MCH_CGA; else if (strcasecmp(mtype,"tandy")==0) machine=MCH_TANDY; + else if (strcasecmp(mtype,"pcjr")==0) machine=MCH_PCJR; else if (strcasecmp(mtype,"hercules")==0) machine=MCH_HERC; else if (strcasecmp(mtype,"vga")==0) machine=MCH_VGA; else LOG_MSG("DOSBOX:Unknown machine type %s",mtype); @@ -216,7 +217,7 @@ void DOSBOX_Init(void) { MSG_Add("DOSBOX_CONFIGFILE_HELP", "language -- Select another language file.\n" "memsize -- Amount of memory dosbox has in megabytes.\n" - "machine -- The type of machine tries to emulate:hercules,cga,tandy,vga.\n" + "machine -- The type of machine tries to emulate:hercules,cga,tandy,pcjr,vga.\n" "captures -- Directory where things like wave,midi,screenshot get captured.\n" ); diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index ed0aa613..80cb1798 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -130,8 +130,14 @@ static struct { static bool add_key_forced(Bit16u code) { if (mem_readb(BIOS_KEYBOARD_FLAGS2)&8) return true; Bit16u start,end,head,tail,ttail; - start=mem_readw(BIOS_KEYBOARD_BUFFER_START); - end =mem_readw(BIOS_KEYBOARD_BUFFER_END); + if (machine==MCH_PCJR) { + /* should be done for cga and others as well, to be tested */ + start=0x1e; + end=0x3e; + } else { + start=mem_readw(BIOS_KEYBOARD_BUFFER_START); + end =mem_readw(BIOS_KEYBOARD_BUFFER_END); + } head =mem_readw(BIOS_KEYBOARD_BUFFER_HEAD); tail =mem_readw(BIOS_KEYBOARD_BUFFER_TAIL); ttail=tail+2; @@ -152,8 +158,14 @@ static void add_key(Bit16u code) { static bool get_key(Bit16u &code) { Bit16u start,end,head,tail,thead; - start=mem_readw(BIOS_KEYBOARD_BUFFER_START); - end =mem_readw(BIOS_KEYBOARD_BUFFER_END); + if (machine==MCH_PCJR) { + /* should be done for cga and others as well, to be tested */ + start=0x1e; + end=0x3e; + } else { + start=mem_readw(BIOS_KEYBOARD_BUFFER_START); + end =mem_readw(BIOS_KEYBOARD_BUFFER_END); + } head =mem_readw(BIOS_KEYBOARD_BUFFER_HEAD); tail =mem_readw(BIOS_KEYBOARD_BUFFER_TAIL); From a8f1afe1c2350f13fb9c0342d83b5af7a8999141 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 26 Dec 2005 20:28:08 +0000 Subject: [PATCH 2338/4131] change int13-reset for old bios versions (Wizardry booter) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2422 --- src/ints/bios_disk.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 8c2feb91..ec198df3 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.24 2005-11-04 21:22:06 c2woody Exp $ */ +/* $Id: bios_disk.cpp,v 1.25 2005-12-26 20:28:08 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" @@ -285,7 +285,6 @@ static Bitu INT13_DiskHandler(void) { Bit16u segat, bufptr; Bit8u sectbuf[512]; Bitu drivenum; - Bits readcnt; int i,t; last_drive = reg_dl; drivenum = GetDosDriveNumber(reg_dl); @@ -302,7 +301,17 @@ static Bitu INT13_DiskHandler(void) { * always succeed on reset disk. If there are diskimages then and only then * do real checks */ - if(any_images && driveInactive(drivenum)) return CBRET_NONE; + if (any_images && driveInactive(drivenum)) { + /* driveInactive sets carry flag if the specified drive is not available */ + if ((machine==MCH_CGA) || (machine==MCH_PCJR)) { + /* those bioses call floppy drive reset for invalid drive values */ + if (((imageDiskList[0]) && (imageDiskList[0]->active)) || ((imageDiskList[1]) && (imageDiskList[1]->active))) { + last_status = 0x00; + CALLBACK_SCF(false); + } + } + return CBRET_NONE; + } last_status = 0x00; CALLBACK_SCF(false); } @@ -346,7 +355,7 @@ static Bitu INT13_DiskHandler(void) { } } reg_ah = 0x00; - CALLBACK_SCF(false); + CALLBACK_SCF(false); break; case 0x3: /* Write sectors */ From 146d4b33808f1bcab9133f6bb33db1d0469e34dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 5 Jan 2006 14:14:53 +0000 Subject: [PATCH 2339/4131] initialize a few fixed-position bios interrupt locations (fixes Star Fleet 2, Defender booter), revector some dos-occupied ints when booting/set stack to safe values (fixes some booters) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2423 --- src/dos/dos_programs.cpp | 11 ++++++++--- src/ints/bios.cpp | 7 ++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 3432341d..aa83df83 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.49 2005-12-19 20:39:51 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.50 2006-01-05 14:14:52 c2woody Exp $ */ #include #include @@ -471,12 +471,17 @@ public: WriteOut(MSG_Get("PROGRAM_BOOT_BOOT"), drive); for(i=0;i<512;i++) real_writeb(0, 0x7c00 + i, bootarea.rawdata[i]); + /* revector some dos-allocated interrupts */ + real_writed(0,0x01*4,0xf000ff53); + real_writed(0,0x03*4,0xf000ff53); + SegSet16(cs, 0); reg_ip = 0x7c00; SegSet16(ds, 0); - SegSet16(ss, 0);//Buckrogers Booter - reg_esp = 0x400; SegSet16(es, 0); + /* set up stack at a safe place */ + SegSet16(ss, 0x7000); + reg_esp = 0xfffe; reg_esi = 0; reg_ecx = 1; reg_ebp = 0; diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 8eb2e430..49a1717d 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.55 2005-12-20 21:33:02 c2woody Exp $ */ +/* $Id: bios.cpp,v 1.56 2006-01-05 14:14:53 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -984,6 +984,11 @@ public: size_extended=IO_Read(0x71); IO_Write(0x70,0x31); size_extended|=(IO_Read(0x71) << 8); + + phys_writeb(0xfff53,0xcf); /* bios default interrupt vector location */ + phys_writeb(0xfe987,0xea); /* original IRQ1 location (Defender booter) */ + phys_writed(0xfe988,RealGetVec(0x09)); + if (machine==MCH_PCJR) PIC_AddEvent(RAMRefresh_Event,RAM_REFRESH_DELAY); } ~BIOS(){ From 17ea37fe89aa773b59693fbc5fbf6dac60993faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 7 Jan 2006 14:17:53 +0000 Subject: [PATCH 2340/4131] add pagefault checking memory functions to the dynamic core Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2424 --- include/paging.h | 90 +++++++++++++- src/cpu/core_dyn_x86.cpp | 9 +- src/cpu/core_dyn_x86/decoder.h | 208 ++++++++++++++++++++++---------- src/cpu/core_dyn_x86/risc_x86.h | 23 ++++ src/cpu/core_dyn_x86/string.h | 11 +- src/cpu/paging.cpp | 77 +++++++++++- src/hardware/memory.cpp | 34 +++++- 7 files changed, 377 insertions(+), 75 deletions(-) diff --git a/include/paging.h b/include/paging.h index 4652b6a8..d0ffa03b 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.19 2005-12-20 08:42:40 qbix79 Exp $ */ +/* $Id: paging.h,v 1.20 2006-01-07 14:17:53 c2woody Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H @@ -54,6 +54,12 @@ public: virtual void writeb(PhysPt addr,Bitu val); virtual void writew(PhysPt addr,Bitu val); virtual void writed(PhysPt addr,Bitu val); + virtual bool readb_checked(PhysPt addr, Bitu * val); + virtual bool readw_checked(PhysPt addr, Bitu * val); + virtual bool readd_checked(PhysPt addr, Bitu * 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); virtual HostPt GetHostPt(Bitu phys_page); Bitu flags; }; @@ -159,6 +165,11 @@ Bit32u mem_unalignedreadd(PhysPt address); void mem_unalignedwritew(PhysPt address,Bit16u val); void mem_unalignedwrited(PhysPt address,Bit32u val); +bool mem_unalignedreadw_checked_x86(PhysPt address,Bit16u * val); +bool mem_unalignedreadd_checked_x86(PhysPt address,Bit32u * val); +bool mem_unalignedwritew_checked_x86(PhysPt address,Bit16u val); +bool mem_unalignedwrited_checked_x86(PhysPt address,Bit32u val); + /* Special inlined memory reading/writing */ INLINE Bit8u mem_readb_inline(PhysPt address) { @@ -247,4 +258,81 @@ INLINE void mem_writed_dyncorex86(PhysPt address,Bit32u val) { } else mem_unalignedwrited(address,val); } + +INLINE bool mem_readb_checked_x86(PhysPt address, Bit8u * val) { + Bitu index=(address>>12); + if (paging.tlb.read[index]) { + *val=host_readb(paging.tlb.read[index]+address); + return false; + } else { + Bitu uval; + bool retval; + retval=paging.tlb.handler[index]->readb_checked(address, &uval); + *val=(Bit8u)uval; + return retval; + } +} + +INLINE bool mem_readw_checked_x86(PhysPt address, Bit16u * val) { + if ((address & 0xfff)<0xfff) { + Bitu index=(address>>12); + if (paging.tlb.read[index]) { + *val=host_readw(paging.tlb.read[index]+address); + return false; + } else { + Bitu uval; + bool retval; + retval=paging.tlb.handler[index]->readw_checked(address, &uval); + *val=(Bit16u)uval; + return retval; + } + } else return mem_unalignedreadw_checked_x86(address, val); +} + + +INLINE bool mem_readd_checked_x86(PhysPt address, Bit32u * val) { + if ((address & 0xfff)<0xffd) { + Bitu index=(address>>12); + if (paging.tlb.read[index]) { + *val=host_readd(paging.tlb.read[index]+address); + return false; + } else { + Bitu uval; + bool retval; + retval=paging.tlb.handler[index]->readd_checked(address, &uval); + *val=(Bit32u)uval; + return retval; + } + } else return mem_unalignedreadd_checked_x86(address, val); +} + +INLINE bool mem_writeb_checked_x86(PhysPt address,Bit8u val) { + Bitu index=(address>>12); + if (paging.tlb.write[index]) { + host_writeb(paging.tlb.write[index]+address,val); + return false; + } else return paging.tlb.handler[index]->writeb_checked(address,val); +} + +INLINE bool mem_writew_checked_x86(PhysPt address,Bit16u val) { + if ((address & 0xfff)<0xfff) { + Bitu index=(address>>12); + if (paging.tlb.write[index]) { + host_writew(paging.tlb.write[index]+address,val); + return false; + } else return paging.tlb.handler[index]->writew_checked(address,val); + } else return mem_unalignedwritew_checked_x86(address,val); +} + +INLINE bool mem_writed_checked_x86(PhysPt address,Bit32u val) { + if ((address & 0xfff)<0xffd) { + Bitu index=(address>>12); + if (paging.tlb.write[index]) { + host_writed(paging.tlb.write[index]+address,val); + return false; + } else return paging.tlb.handler[index]->writed_checked(address,val); + } else return mem_unalignedwrited_checked_x86(address,val); +} + + #endif diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 07bfa63e..09569015 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -20,6 +20,8 @@ #if (C_DYNAMIC_X86) +#define CHECKED_MEMORY_ACCESS + #include #include #include @@ -43,8 +45,13 @@ #include "paging.h" #include "inout.h" +#ifdef CHECKED_MEMORY_ACCESS +#define CACHE_TOTAL (1024*1024) +#define CACHE_MAXSIZE (4096*3) +#else #define CACHE_TOTAL (512*1024) #define CACHE_MAXSIZE (4096) +#endif #define CACHE_BLOCKS (32*1024) #define CACHE_ALIGN (16) #define CACHE_PAGES (128) @@ -154,7 +161,7 @@ static void IllegalOption(const char* msg) { #include "core_dyn_x86/cache.h" static struct { - Bitu callback; + Bitu callback,readdata; } core_dyn; diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index c0c53e01..323bc5bf 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -100,41 +100,6 @@ static Bit32u decode_fetchd(void) { return mem_readd(decode.code-4); } -static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { - if (high) gen_call_function((void *)&mem_readb,"%Dd%Rh",addr,dst); - else gen_call_function((void *)&mem_readb,"%Dd%Rl",addr,dst); -} -static void dyn_write_byte(DynReg * addr,DynReg * val,Bitu high) { - if (high) gen_call_function((void *)&mem_writeb,"%Dd%Dh",addr,val); - else gen_call_function((void *)&mem_writeb,"%Dd%Dd",addr,val); -} -static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) { - if (dword) gen_call_function((void *)&mem_readd_dyncorex86,"%Dd%Rd",addr,dst); - else gen_call_function((void *)&mem_readw_dyncorex86,"%Dd%Rw",addr,dst); -} -static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { - if (dword) gen_call_function((void *)&mem_writed_dyncorex86,"%Dd%Dd",addr,val); - else gen_call_function((void *)&mem_writew_dyncorex86,"%Dd%Dd",addr,val); -} - - -static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) { - if (high) gen_call_function((void *)&mem_readb,"%Drd%Rh",addr,dst); - else gen_call_function((void *)&mem_readb,"%Drd%Rl",addr,dst); -} -static void dyn_write_byte_release(DynReg * addr,DynReg * val,Bitu high) { - if (high) gen_call_function((void *)&mem_writeb,"%Drd%Dh",addr,val); - else gen_call_function((void *)&mem_writeb,"%Drd%Dd",addr,val); -} -static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) { - if (dword) gen_call_function((void *)&mem_readd_dyncorex86,"%Drd%Rd",addr,dst); - else gen_call_function((void *)&mem_readw_dyncorex86,"%Drd%Rw",addr,dst); -} -static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) { - if (dword) gen_call_function((void *)&mem_writed_dyncorex86,"%Drd%Dd",addr,val); - else gen_call_function((void *)&mem_writew_dyncorex86,"%Drd%Dd",addr,val); -} - static void dyn_reduce_cycles(void) { gen_protectflags(); @@ -166,16 +131,139 @@ static void dyn_set_eip_last_end(DynReg * endreg) { gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),decode.op_start-decode.code_start); } - static INLINE void dyn_set_eip_end(void) { - gen_protectflags(); +static INLINE void dyn_set_eip_end(void) { + gen_protectflags(); gen_dop_word_imm(DOP_ADD,cpu.code.big,DREG(EIP),decode.code-decode.code_start); - } +} - static INLINE void dyn_set_eip_last(void) { - gen_protectflags(); +static INLINE void dyn_set_eip_last(void) { + gen_protectflags(); gen_dop_word_imm(DOP_ADD,cpu.code.big,DREG(EIP),decode.op_start-decode.code_start); } + +static void DynRunException(void) { + CPU_Exception(cpu.exception.which,cpu.exception.error); +} + +static void dyn_check_bool_exception(DynReg * check) { + Bit8u * branch;DynState state; + gen_dop_byte(DOP_OR,check,0,check,0); + branch=gen_create_branch(BR_Z); + dyn_savestate(&state); + dyn_flags_gen_to_host(); + dyn_reduce_cycles(); + dyn_set_eip_last(); + dyn_save_critical_regs(); + gen_call_function((void *)&DynRunException,""); + dyn_flags_host_to_gen(); + gen_return(BR_Normal); + dyn_loadstate(&state); + gen_fill_branch(branch); +} + +static void dyn_check_bool_exception_al(void) { + Bit8u * branch;DynState state; + cache_addw(0xc00a); // or al, al + branch=gen_create_branch(BR_Z); + dyn_savestate(&state); + dyn_flags_gen_to_host(); + dyn_reduce_cycles(); + dyn_set_eip_last(); + dyn_save_critical_regs(); + gen_call_function((void *)&DynRunException,""); + dyn_flags_host_to_gen(); + gen_return(BR_Normal); + dyn_loadstate(&state); + gen_fill_branch(branch); +} + +#ifdef CHECKED_MEMORY_ACCESS +static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { + gen_protectflags(); + gen_call_function((void *)&mem_readb_checked_x86,"%Dd%Id",addr,&core_dyn.readdata); + dyn_check_bool_exception_al(); + gen_mov_host(&core_dyn.readdata,dst,1,high); +} +static void dyn_write_byte(DynReg * addr,DynReg * val,Bitu high) { + gen_protectflags(); + if (high) gen_call_function((void *)&mem_writeb_checked_x86,"%Dd%Dh",addr,val); + else gen_call_function((void *)&mem_writeb_checked_x86,"%Dd%Dd",addr,val); + dyn_check_bool_exception_al(); +} +static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) { + gen_protectflags(); + if (dword) gen_call_function((void *)&mem_readd_checked_x86,"%Dd%Id",addr,&core_dyn.readdata); + else gen_call_function((void *)&mem_readw_checked_x86,"%Dd%Id",addr,&core_dyn.readdata); + dyn_check_bool_exception_al(); + gen_mov_host(&core_dyn.readdata,dst,dword?4:2); +} +static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { + gen_protectflags(); + if (dword) gen_call_function((void *)&mem_writed_checked_x86,"%Dd%Dd",addr,val); + else gen_call_function((void *)&mem_writew_checked_x86,"%Dd%Dd",addr,val); + dyn_check_bool_exception_al(); +} +static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) { + gen_protectflags(); + gen_call_function((void *)&mem_readb_checked_x86,"%Ddr%Id",addr,&core_dyn.readdata); + dyn_check_bool_exception_al(); + gen_mov_host(&core_dyn.readdata,dst,1,high); +} + static void dyn_write_byte_release(DynReg * addr,DynReg * val,Bitu high) { + gen_protectflags(); + if (high) gen_call_function((void *)&mem_writeb_checked_x86,"%Ddr%Dh",addr,val); + else gen_call_function((void *)&mem_writeb_checked_x86,"%Ddr%Dd",addr,val); + dyn_check_bool_exception_al(); +} +static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) { + gen_protectflags(); + if (dword) gen_call_function((void *)&mem_readd_checked_x86,"%Ddr%Id",addr,&core_dyn.readdata); + else gen_call_function((void *)&mem_readw_checked_x86,"%Ddr%Id",addr,&core_dyn.readdata); + dyn_check_bool_exception_al(); + gen_mov_host(&core_dyn.readdata,dst,dword?4:2); +} +static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) { + gen_protectflags(); + if (dword) gen_call_function((void *)&mem_writed_checked_x86,"%Ddr%Dd",addr,val); + else gen_call_function((void *)&mem_writew_checked_x86,"%Ddr%Dd",addr,val); + dyn_check_bool_exception_al(); +} +#else +static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { + if (high) gen_call_function((void *)&mem_readb,"%Dd%Rh",addr,dst); + else gen_call_function((void *)&mem_readb,"%Dd%Rl",addr,dst); +} +static void dyn_write_byte(DynReg * addr,DynReg * val,Bitu high) { + if (high) gen_call_function((void *)&mem_writeb,"%Dd%Dh",addr,val); + else gen_call_function((void *)&mem_writeb,"%Dd%Dd",addr,val); +} +static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) { + if (dword) gen_call_function((void *)&mem_readd_dyncorex86,"%Dd%Rd",addr,dst); + else gen_call_function((void *)&mem_readw_dyncorex86,"%Dd%Rw",addr,dst); +} +static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { + if (dword) gen_call_function((void *)&mem_writed_dyncorex86,"%Dd%Dd",addr,val); + else gen_call_function((void *)&mem_writew_dyncorex86,"%Dd%Dd",addr,val); +} +static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) { + if (high) gen_call_function((void *)&mem_readb,"%Ddr%Rh",addr,dst); + else gen_call_function((void *)&mem_readb,"%Ddr%Rl",addr,dst); +} +static void dyn_write_byte_release(DynReg * addr,DynReg * val,Bitu high) { + if (high) gen_call_function((void *)&mem_writeb,"%Ddr%Dh",addr,val); + else gen_call_function((void *)&mem_writeb,"%Ddr%Dd",addr,val); +} +static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) { + if (dword) gen_call_function((void *)&mem_readd_dyncorex86,"%Ddr%Rd",addr,dst); + else gen_call_function((void *)&mem_readw_dyncorex86,"%Ddr%Rw",addr,dst); +} +static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) { + if (dword) gen_call_function((void *)&mem_writed_dyncorex86,"%Ddr%Dd",addr,val); + else gen_call_function((void *)&mem_writew_dyncorex86,"%Ddr%Dd",addr,val); +} +#endif + static void dyn_push(DynReg * dynreg) { gen_protectflags(); if (decode.big_op) { @@ -345,26 +433,6 @@ skip_extend_word: #include "helpers.h" #include "string.h" -static void DynRunException(void) { - CPU_Exception(cpu.exception.which,cpu.exception.error); -} - -static void dyn_check_bool_exception(DynReg * check) { - Bit8u * branch;DynState state; - gen_dop_byte(DOP_OR,check,0,check,0); - branch=gen_create_branch(BR_Z); - dyn_savestate(&state); - dyn_flags_gen_to_host(); - dyn_reduce_cycles(); - dyn_set_eip_last(); - dyn_save_critical_regs(); - gen_call_function((void *)&DynRunException,""); - dyn_flags_host_to_gen(); - gen_return(BR_Normal); - dyn_loadstate(&state); - gen_fill_branch(branch); -} - static void dyn_dop_ebgb(DualOps op) { dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg&3]; @@ -416,6 +484,9 @@ static void dyn_mov_ebib(void) { if (decode.modrm.mod<3) { dyn_fill_ea(); gen_call_write(DREG(EA),decode_fetchb(),1); +#ifdef CHECKED_MEMORY_ACCESS + dyn_check_bool_exception_al(); +#endif } else { gen_dop_byte_imm(DOP_MOV,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,decode_fetchb()); } @@ -534,6 +605,9 @@ static void dyn_mov_eviv(void) { if (decode.modrm.mod<3) { dyn_fill_ea(); gen_call_write(DREG(EA),decode.big_op ? decode_fetchd() : decode_fetchw(),decode.big_op?4:2); +#ifdef CHECKED_MEMORY_ACCESS + dyn_check_bool_exception_al(); +#endif } else { gen_dop_word_imm(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],decode.big_op ? decode_fetchd() : decode_fetchw()); } @@ -597,7 +671,7 @@ static void dyn_grp1_eb_ib(void) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else set_skipflags(false); } - gen_dop_byte_imm(grp1_table[decode.modrm.reg],DREG(TMPB),0,decode_fetchb()); + gen_dop_byte_imm(op,DREG(TMPB),0,decode_fetchb()); if (op!=DOP_CMP) dyn_write_byte_release(DREG(EA),DREG(TMPB),false); else gen_releasereg(DREG(EA)); gen_releasereg(DREG(TMPB)); @@ -606,7 +680,7 @@ static void dyn_grp1_eb_ib(void) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else gen_discardflags(); } - gen_dop_byte_imm(grp1_table[decode.modrm.reg],&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,decode_fetchb()); + gen_dop_byte_imm(op,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,decode_fetchb()); } } @@ -622,7 +696,7 @@ static void dyn_grp1_ev_ivx(bool withbyte) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else set_skipflags(false); } - gen_dop_word_imm(grp1_table[decode.modrm.reg],decode.big_op,DREG(TMPW),imm); + gen_dop_word_imm(op,decode.big_op,DREG(TMPW),imm); if (op!=DOP_CMP) dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); else gen_releasereg(DREG(EA)); gen_releasereg(DREG(TMPW)); @@ -632,7 +706,7 @@ static void dyn_grp1_ev_ivx(bool withbyte) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else gen_discardflags(); } - gen_dop_word_imm(grp1_table[decode.modrm.reg],decode.big_op,&DynRegs[decode.modrm.rm],imm); + gen_dop_word_imm(op,decode.big_op,&DynRegs[decode.modrm.rm],imm); } } @@ -1604,9 +1678,9 @@ restart_prefix: { dyn_get_modrm();DynReg * src; if (decode.modrm.mod<3) { - dyn_fill_ea(); - dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); - src=DREG(TMPW); + dyn_fill_ea(); + dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); + src=DREG(TMPW); } else src=&DynRegs[decode.modrm.rm]; switch (decode.modrm.reg) { case 0x0://INC Ev diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 11430f1b..e7d0f6fa 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -721,12 +721,21 @@ static void gen_call_write(DynReg * dr,Bit32u val,Bitu write_size) { x86gen.regs[X86_REG_EDX]->Clear(); /* Do the actual call to the procedure */ cache_addb(0xe8); +#ifdef CHECKED_MEMORY_ACCESS + switch (write_size) { + case 1: cache_addd((Bit32u)mem_writeb_checked_x86 - (Bit32u)cache.pos-4); break; + case 2: cache_addd((Bit32u)mem_writew_checked_x86 - (Bit32u)cache.pos-4); break; + case 4: cache_addd((Bit32u)mem_writed_checked_x86 - (Bit32u)cache.pos-4); break; + default: IllegalOption("gen_call_write"); + } +#else switch (write_size) { case 1: cache_addd((Bit32u)mem_writeb - (Bit32u)cache.pos-4); break; case 2: cache_addd((Bit32u)mem_writew_dyncorex86 - (Bit32u)cache.pos-4); break; case 4: cache_addd((Bit32u)mem_writed_dyncorex86 - (Bit32u)cache.pos-4); break; default: IllegalOption("gen_call_write"); } +#endif cache_addw(0xc483); //ADD ESP,8 cache_addb(2*4); @@ -812,6 +821,20 @@ static void gen_load_host(void * data,DynReg * dr1,Bitu size) { dr1->flags|=DYNFLG_CHANGED; } +static void gen_mov_host(void * data,DynReg * dr1,Bitu size,Bit8u di1=0) { + GenReg * gr1=FindDynReg(dr1); + switch (size) { + case 1:cache_addb(0x8a);break; //mov byte + case 2:cache_addb(0x66); //mov word + case 4:cache_addb(0x8b);break; //mov + default: + IllegalOption("gen_load_host"); + } + cache_addb(0x5+((gr1->index+(di1?4:0))<<3)); + cache_addd((Bit32u)data); + dr1->flags|=DYNFLG_CHANGED; +} + static void gen_return(BlockReturn retcode) { gen_protectflags(); cache_addb(0x59); //POP ECX, the flags diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index 4c8a710c..13748c56 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -80,13 +80,12 @@ static void dyn_string(STRING_OP op) { dyn_savestate(&rep_state); Bit8u * rep_start=cache.pos; Bit8u * rep_ecx_jmp; - /* Check if ECX!=zero and decrease it */ + /* Check if ECX!=zero */ if (decode.rep) { gen_dop_word(DOP_OR,decode.big_addr,DREG(ECX),DREG(ECX)); Bit8u * branch_ecx=gen_create_branch(BR_NZ); rep_ecx_jmp=gen_create_jump(); gen_fill_branch(branch_ecx); - gen_sop_word(SOP_DEC,decode.big_addr,DREG(ECX)); } if (usesi) { if (!decode.big_addr) { @@ -95,7 +94,6 @@ static void dyn_string(STRING_OP op) { } else { gen_lea(DREG(EA),si_base,DREG(ESI),0,0); } - gen_dop_word(DOP_ADD,decode.big_addr,DREG(ESI),DREG(TMPW)); switch (op&3) { case 0:dyn_read_byte(DREG(EA),tmp_reg,false);break; case 1:dyn_read_word(DREG(EA),tmp_reg,false);break; @@ -117,7 +115,6 @@ static void dyn_string(STRING_OP op) { } else { gen_lea(DREG(EA),di_base,DREG(EDI),0,0); } - gen_dop_word(DOP_ADD,decode.big_addr,DREG(EDI),DREG(TMPW)); /* Maybe something special to be done to fill the value */ switch (op) { case STR_INSB: @@ -143,8 +140,14 @@ static void dyn_string(STRING_OP 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) { DynState cycle_state; + gen_sop_word(SOP_DEC,decode.big_addr,DREG(ECX)); gen_sop_word(SOP_DEC,true,DREG(CYCLES)); gen_releasereg(DREG(CYCLES)); dyn_savestate(&cycle_state); diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 65f3d4ee..b80c7c0e 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -67,6 +67,25 @@ void PageHandler::writed(PhysPt addr,Bitu val) { writeb(addr+3,(Bit8u) (val >> 24)); }; +bool PageHandler::readb_checked(PhysPt addr, Bitu * val) { + *val=readb(addr); return false; +} +bool PageHandler::readw_checked(PhysPt addr, Bitu * val) { + *val=readw(addr); return false; +} +bool PageHandler::readd_checked(PhysPt addr, Bitu * val) { + *val=readd(addr); return false; +} +bool PageHandler::writeb_checked(PhysPt addr,Bitu val) { + writeb(addr,val); return false; +} +bool PageHandler::writew_checked(PhysPt addr,Bitu val) { + writew(addr,val); return false; +} +bool PageHandler::writed_checked(PhysPt addr,Bitu val) { + writed(addr,val); return false; +} + HostPt PageHandler::GetHostPt(Bitu phys_page) { return 0; } @@ -161,7 +180,43 @@ public: InitPage(addr,true); mem_writed(addr,val); } - void InitPage(Bitu lin_addr,bool writing) { + bool readb_checked(PhysPt addr, Bitu * val) { + if (InitPage(addr,false,true)) { + *val=mem_readb(addr); + return false; + } else return true; + } + bool readw_checked(PhysPt addr, Bitu * val) { + if (InitPage(addr,false,true)){ + *val=mem_readw(addr); + return false; + } else return true; + } + bool readd_checked(PhysPt addr, Bitu * val) { + if (InitPage(addr,false,true)) { + *val=mem_readd(addr); + return false; + } else return true; + } + bool writeb_checked(PhysPt addr,Bitu val) { + if (InitPage(addr,true,true)) { + mem_writeb(addr,val); + return false; + } else return true; + } + bool writew_checked(PhysPt addr,Bitu val) { + if (InitPage(addr,true,true)) { + mem_writew(addr,val); + return false; + } else return true; + } + bool writed_checked(PhysPt addr,Bitu val) { + if (InitPage(addr,true,true)) { + mem_writed(addr,val); + return false; + } else return true; + } + bool InitPage(Bitu lin_addr,bool writing,bool check_only=false) { Bitu lin_page=lin_addr >> 12; Bitu phys_page; if (paging.enabled) { @@ -171,6 +226,12 @@ public: X86PageEntry table; table.load=phys_readd(table_addr); if (!table.block.p) { + if (check_only) { + paging.cr2=lin_addr; + cpu.exception.which=14; + cpu.exception.error=writing?0x02:0x00; + return false; + } LOG(LOG_PAGING,LOG_NORMAL)("NP Table"); PAGING_PageFault(lin_addr,table_addr,false,writing?0x02:0x00); table.load=phys_readd(table_addr); @@ -185,6 +246,12 @@ public: Bitu entry_addr=(table.block.base<<12)+t_index*4; entry.load=phys_readd(entry_addr); if (!entry.block.p) { + if (check_only) { + paging.cr2=lin_addr; + cpu.exception.which=14; + cpu.exception.error=writing?0x02:0x00; + return false; + } // LOG(LOG_PAGING,LOG_NORMAL)("NP Page"); PAGING_PageFault(lin_addr,entry_addr,false,writing?0x02:0x00); entry.load=phys_readd(entry_addr); @@ -194,9 +261,16 @@ public: if (cpu.cpl==3) { if ((entry.block.us==0) || (table.block.us==0) && (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); + if (check_only) { + paging.cr2=lin_addr; + cpu.exception.which=14; + cpu.exception.error=0x05 | (writing?0x02:0x00); + return false; + } PAGING_PageFault(lin_addr,entry_addr,writing,0x05 | (writing?0x02:0x00)); } } + if (check_only) return true; if ((!entry.block.a) || (!entry.block.d)) { entry.block.a=1; //Set access entry.block.d=1; //Set dirty @@ -208,6 +282,7 @@ public: else phys_page=lin_page; } PAGING_LinkPage(lin_page,phys_page); + return true; } }; diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index c434ca9a..b433960c 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: memory.cpp,v 1.41 2005-12-05 21:25:56 c2woody Exp $ */ +/* $Id: memory.cpp,v 1.42 2006-01-07 14:17:53 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -437,6 +437,38 @@ void mem_unalignedwrited(PhysPt address,Bit32u val) { } +bool mem_unalignedreadw_checked_x86(PhysPt address, Bit16u * val) { + Bit8u rval1,rval2; + if (mem_readb_checked_x86(address+0, &rval1)) return true; + if (mem_readb_checked_x86(address+1, &rval2)) return true; + *val=(Bit16u)(((Bit8u)rval1) | (((Bit8u)rval2) << 8)); + return false; +} + +bool mem_unalignedreadd_checked_x86(PhysPt address, Bit32u * val) { + Bit8u rval1,rval2,rval3,rval4; + if (mem_readb_checked_x86(address+0, &rval1)) return true; + if (mem_readb_checked_x86(address+1, &rval2)) return true; + if (mem_readb_checked_x86(address+2, &rval3)) return true; + if (mem_readb_checked_x86(address+3, &rval4)) return true; + *val=(Bit32u)(((Bit8u)rval1) | (((Bit8u)rval2) << 8) | (((Bit8u)rval3) << 16) | (((Bit8u)rval4) << 24)); + return false; +} + +bool mem_unalignedwritew_checked_x86(PhysPt address,Bit16u val) { + if (mem_writeb_checked_x86(address,(Bit8u)(val & 0xff))) return true;val>>=8; + if (mem_writeb_checked_x86(address+1,(Bit8u)(val & 0xff))) return true; + return false; +} + +bool mem_unalignedwrited_checked_x86(PhysPt address,Bit32u val) { + if (mem_writeb_checked_x86(address,(Bit8u)(val & 0xff))) return true;val>>=8; + if (mem_writeb_checked_x86(address+1,(Bit8u)(val & 0xff))) return true;val>>=8; + if (mem_writeb_checked_x86(address+2,(Bit8u)(val & 0xff))) return true;val>>=8; + if (mem_writeb_checked_x86(address+3,(Bit8u)(val & 0xff))) return true; + return false; +} + Bit8u mem_readb(PhysPt address) { return mem_readb_inline(address); } From 8faeb470b4d49359ccef63db1643b4e55d04c76c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 8 Jan 2006 18:05:06 +0000 Subject: [PATCH 2341/4131] ignore unneeded fpu-exception flags Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2425 --- src/fpu/fpu_instructions_x86.h | 366 +++++++++++++++++++++++++-------- 1 file changed, 281 insertions(+), 85 deletions(-) diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index a10cd162..45e3c6e5 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -16,11 +16,31 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions_x86.h,v 1.1 2005-02-22 13:06:06 qbix79 Exp $ */ +/* $Id: fpu_instructions_x86.h,v 1.2 2006-01-08 18:05:06 c2woody Exp $ */ + + +#define WEAK_EXCEPTIONS #if defined (_MSC_VER) +#ifdef WEAK_EXCEPTIONS +#define clx +#else +#define clx fclex +#endif + +#ifdef WEAK_EXCEPTIONS +#define FPUD_LOAD(op,szI,szA) \ + __asm { \ + __asm mov eax, 8 \ + __asm shl eax, 4 \ + __asm mov ebx, store_to \ + __asm shl ebx, 4 \ + __asm op szI PTR fpu.p_regs[eax].m1 \ + __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ + } +#else #define FPUD_LOAD(op,szI,szA) \ Bit16u new_sw; \ __asm { \ @@ -34,6 +54,7 @@ __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ } \ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); +#endif #define FPUD_STORE(op,szI,szA) \ Bit16u new_sw,save_cw; \ @@ -45,12 +66,12 @@ __asm mov ebx, 8 \ __asm shl ebx, 4 \ __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fclex \ + __asm clx \ __asm op szI PTR fpu.p_regs[ebx].m1 \ __asm fnstsw new_sw \ __asm fldcw save_cw \ } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); // handles fsin,fcos,f2xm1,fchs,fabs #define FPUD_TRIG(op) \ @@ -59,15 +80,15 @@ __asm mov eax, TOP \ __asm shl eax, 4 \ __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fclex \ + __asm clx \ __asm op \ __asm fnstsw new_sw \ __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); // handles fsincos -#define FPUD_SINCOS \ +#define FPUD_SINCOS() \ Bit16u new_sw; \ __asm { \ __asm mov eax, TOP \ @@ -77,7 +98,7 @@ __asm shl eax, 4 \ __asm shl ebx, 4 \ __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fclex \ + __asm clx \ __asm fsincos \ __asm fnstsw new_sw \ __asm mov cx, new_sw \ @@ -90,11 +111,11 @@ __asm fstp st(0) \ __asm end_sincos: \ } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ if ((new_sw&0x0400)==0) FPU_PREP_PUSH(); // handles fptan -#define FPUD_PTAN \ +#define FPUD_PTAN() \ Bit16u new_sw; \ __asm { \ __asm mov eax, TOP \ @@ -104,7 +125,7 @@ __asm shl eax, 4 \ __asm shl ebx, 4 \ __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fclex \ + __asm clx \ __asm fptan \ __asm fnstsw new_sw \ __asm mov cx, new_sw \ @@ -117,10 +138,26 @@ __asm fstp st(0) \ __asm end_ptan: \ } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ if ((new_sw&0x0400)==0) FPU_PREP_PUSH(); // handles fxtract +#ifdef WEAK_EXCEPTIONS +#define FPUD_XTRACT \ + __asm { \ + __asm mov eax, TOP \ + __asm mov ebx, eax \ + __asm dec ebx \ + __asm and ebx, 7 \ + __asm shl eax, 4 \ + __asm shl ebx, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fxtract \ + __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ + __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ + } \ + FPU_PREP_PUSH(); +#else #define FPUD_XTRACT \ Bit16u new_sw; \ __asm { \ @@ -139,9 +176,47 @@ } \ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ FPU_PREP_PUSH(); +#endif -// handles fadd,fmul,fsub,fsubr,fdiv,fdivr +// handles fadd,fmul,fsub,fsubr #define FPUD_ARITH1(op) \ + Bit16u new_sw,save_cw; \ + __asm { \ + __asm fnstcw save_cw \ + __asm fldcw fpu.cw_mask_all \ + __asm mov eax, op1 \ + __asm shl eax, 4 \ + __asm mov ebx, op2 \ + __asm shl ebx, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ + __asm clx \ + __asm op st(1), st(0) \ + __asm fnstsw new_sw \ + __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fldcw save_cw \ + } \ + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); + +// handles fsqrt,frndint +#define FPUD_ARITH2(op) \ + Bit16u new_sw,save_cw; \ + __asm { \ + __asm fnstcw save_cw \ + __asm fldcw fpu.cw_mask_all \ + __asm mov eax, TOP \ + __asm shl eax, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm clx \ + __asm op \ + __asm fnstsw new_sw \ + __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fldcw save_cw \ + } \ + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); + +// handles fdiv,fdivr +#define FPUD_ARITH3(op) \ Bit16u new_sw,save_cw; \ __asm { \ __asm fnstcw save_cw \ @@ -160,23 +235,6 @@ } \ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); -// handles fsqrt,frndint -#define FPUD_ARITH2(op) \ - Bit16u new_sw,save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm fldcw fpu.cw_mask_all \ - __asm mov eax, TOP \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fclex \ - __asm op \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); - // handles fprem,fprem1,fscale #define FPUD_REMINDER(op) \ Bit16u new_sw; \ @@ -207,11 +265,11 @@ __asm shl eax, 4 \ __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fclex \ + __asm clx \ __asm op \ __asm fnstsw new_sw \ } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); // handles fxam,ftst #define FPUD_EXAMINE(op) \ @@ -220,15 +278,52 @@ __asm mov eax, TOP \ __asm shl eax, 4 \ __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fclex \ + __asm clx \ __asm op \ __asm fnstsw new_sw \ __asm fstp st(0) \ } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -// handles fpatan,fyl2x,fyl2xp1 +// handles fpatan,fyl2xp1 +#ifdef WEAK_EXCEPTIONS #define FPUD_WITH_POP(op) \ + __asm { \ + __asm mov eax, TOP \ + __asm mov ebx, eax \ + __asm inc ebx \ + __asm and ebx, 7 \ + __asm shl ebx, 4 \ + __asm shl eax, 4 \ + __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm op \ + __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ + } \ + FPU_FPOP(); +#else +#define FPUD_WITH_POP(op) \ + Bit16u new_sw; \ + __asm { \ + __asm mov eax, TOP \ + __asm mov ebx, eax \ + __asm inc ebx \ + __asm and ebx, 7 \ + __asm shl ebx, 4 \ + __asm shl eax, 4 \ + __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fclex \ + __asm op \ + __asm fnstsw new_sw \ + __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ + } \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ + FPU_FPOP(); +#endif + +// handles fyl2x +#define FPUD_FYL2X(op) \ Bit16u new_sw; \ __asm { \ __asm mov eax, TOP \ @@ -248,21 +343,37 @@ FPU_FPOP(); // load math constants -#define FPUD_LOAD_CONST(op) \ - Bit16u new_sw; \ +#define FPUD_LOAD_CONST(op) \ FPU_PREP_PUSH(); \ __asm { \ __asm mov eax, TOP \ __asm shl eax, 4 \ - __asm fclex \ + __asm clx \ __asm op \ - __asm fnstsw new_sw \ __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); #else +#ifdef WEAK_EXCEPTIONS +#define clx +#else +#define clx "fclex" +#endif + +#ifdef WEAK_EXCEPTIONS +#define FPUD_LOAD(op,szI,szA) \ + __asm__ volatile ( \ + "movl $8, %%eax \n" \ + "shl $4, %%eax \n" \ + "shl $4, %0 \n" \ + #op #szA " (%1, %%eax) \n" \ + "fstpt (%1, %0) " \ + : \ + : "r" (store_to), "r" (fpu.p_regs) \ + : "eax", "memory" \ + ); +#else #define FPUD_LOAD(op,szI,szA) \ Bit16u new_sw; \ __asm__ volatile ( \ @@ -278,6 +389,7 @@ : "eax", "memory" \ ); \ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); +#endif #define FPUD_STORE(op,szI,szA) \ Bit16u new_sw,save_cw; \ @@ -288,7 +400,7 @@ "movl $8, %%eax \n" \ "shl $4, %%eax \n" \ "fldt (%3, %2) \n" \ - "fclex \n" \ + clx" \n" \ #op #szA " (%3, %%eax) \n" \ "fnstsw %0 \n" \ "fldcw %1 " \ @@ -296,7 +408,7 @@ : "r" (TOP), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ : "eax", "memory" \ ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); // handles fsin,fcos,f2xm1,fchs,fabs #define FPUD_TRIG(op) \ @@ -304,7 +416,7 @@ __asm__ volatile ( \ "shll $4, %1 \n" \ "fldt (%2, %1) \n" \ - "fclex \n" \ + clx" \n" \ #op" \n" \ "fnstsw %0 \n" \ "fstpt (%2, %1) " \ @@ -312,10 +424,10 @@ : "r" (TOP), "r" (fpu.p_regs) \ : "memory" \ ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); // handles fsincos -#define FPUD_SINCOS \ +#define FPUD_SINCOS() \ Bit16u new_sw; \ __asm__ volatile ( \ "movl %1, %%eax \n" \ @@ -324,7 +436,7 @@ "andl $7, %%eax \n" \ "shll $4, %%eax \n" \ "fldt (%2, %1) \n" \ - "fclex \n" \ + clx" \n" \ "fsincos \n" \ "fnstsw %0 \n" \ "fstpt (%2, %%eax) \n" \ @@ -337,11 +449,11 @@ : "r" (TOP), "r" (fpu.p_regs) \ : "eax", "cc", "memory" \ ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ if ((new_sw&0x0400)==0) FPU_PREP_PUSH(); // handles fptan -#define FPUD_PTAN \ +#define FPUD_PTAN() \ Bit16u new_sw; \ __asm__ volatile ( \ "movl %1, %%eax \n" \ @@ -350,7 +462,7 @@ "andl $7, %%eax \n" \ "shll $4, %%eax \n" \ "fldt (%2, %1) \n" \ - "fclex \n" \ + clx" \n" \ "fptan \n" \ "fnstsw %0 \n" \ "fstpt (%2, %%eax) \n" \ @@ -363,10 +475,28 @@ : "r" (TOP), "r" (fpu.p_regs) \ : "eax", "cc", "memory" \ ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ if ((new_sw&0x0400)==0) FPU_PREP_PUSH(); // handles fxtract +#ifdef WEAK_EXCEPTIONS +#define FPUD_XTRACT \ + __asm__ volatile ( \ + "movl %0, %%eax \n" \ + "shll $4, %0 \n" \ + "decl %%eax \n" \ + "andl $7, %%eax \n" \ + "shll $4, %%eax \n" \ + "fldt (%1, %0) \n" \ + "fxtract \n" \ + "fstpt (%1, %%eax) \n" \ + "fstpt (%1, %0) " \ + : \ + : "r" (TOP), "r" (fpu.p_regs) \ + : "eax", "memory" \ + ); \ + FPU_PREP_PUSH(); +#else #define FPUD_XTRACT \ Bit16u new_sw; \ __asm__ volatile ( \ @@ -387,9 +517,50 @@ ); \ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ FPU_PREP_PUSH(); +#endif -// handles fadd,fmul,fsub,fsubr,fdiv,fdivr +// handles fadd,fmul,fsub,fsubr #define FPUD_ARITH1(op) \ + Bit16u new_sw,save_cw; \ + __asm__ volatile ( \ + "fnstcw %1 \n" \ + "fldcw %5 \n" \ + "shll $4, %3 \n" \ + "shll $4, %2 \n" \ + "fldt (%4, %3) \n" \ + "fldt (%4, %2) \n" \ + clx" \n" \ + #op" \n" \ + "fnstsw %0 \n" \ + "fstpt (%4, %2) \n" \ + "fldcw %1 " \ + : "=m" (new_sw), "=m" (save_cw) \ + : "r" (op1), "r" (op2), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ + : "memory" \ + ); \ + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); + +// handles fsqrt,frndint +#define FPUD_ARITH2(op) \ + Bit16u new_sw,save_cw; \ + __asm__ volatile ( \ + "fnstcw %1 \n" \ + "fldcw %4 \n" \ + "shll $4, %2 \n" \ + "fldt (%3, %2) \n" \ + clx" \n" \ + #op" \n" \ + "fnstsw %0 \n" \ + "fstpt (%3, %2) \n" \ + "fldcw %1 " \ + : "=m" (new_sw), "=m" (save_cw) \ + : "r" (TOP), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ + : "memory" \ + ); \ + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); + +// handles fdiv,fdivr +#define FPUD_ARITH3(op) \ Bit16u new_sw,save_cw; \ __asm__ volatile ( \ "fnstcw %1 \n" \ @@ -405,29 +576,10 @@ "fldcw %1 " \ : "=m" (new_sw), "=m" (save_cw) \ : "r" (op1), "r" (op2), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ + : "memory" \ ); \ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); -// handles fsqrt,frndint -#define FPUD_ARITH2(op) \ - Bit16u new_sw,save_cw; \ - __asm__ volatile ( \ - "fnstcw %1 \n" \ - "fldcw %4 \n" \ - "shll $4, %2 \n" \ - "fldt (%3, %2) \n" \ - "fclex \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt (%3, %2) \n" \ - "fldcw %1 " \ - : "=m" (new_sw), "=m" (save_cw) \ - : "r" (TOP), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ - ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); - // handles fprem,fprem1,fscale #define FPUD_REMINDER(op) \ Bit16u new_sw; \ @@ -458,14 +610,14 @@ "shll $4, %1 \n" \ "fldt (%3, %2) \n" \ "fldt (%3, %1) \n" \ - "fclex \n" \ + clx" \n" \ #op" \n" \ "fnstsw %0 " \ : "=m" (new_sw) \ : "r" (op1), "r" (op2), "r" (fpu.p_regs) \ : "memory" \ ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); // handles fxam,ftst #define FPUD_EXAMINE(op) \ @@ -473,7 +625,7 @@ __asm__ volatile ( \ "shll $4, %1 \n" \ "fldt (%2, %1) \n" \ - "fclex \n" \ + clx" \n" \ #op" \n" \ "fnstsw %0 \n" \ "fstp %%st(0) " \ @@ -481,9 +633,27 @@ : "r" (TOP), "r" (fpu.p_regs) \ : "memory" \ ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -// handles fpatan,fyl2x,fyl2xp1 +// handles fpatan,fyl2xp1 +#ifdef WEAK_EXCEPTIONS +#define FPUD_WITH_POP(op) \ + __asm__ volatile ( \ + "movl %0, %%eax \n" \ + "incl %%eax \n" \ + "andl $7, %%eax \n" \ + "shll $4, %%eax \n" \ + "shll $4, %0 \n" \ + "fldt (%1, %%eax) \n" \ + "fldt (%1, %0) \n" \ + #op" \n" \ + "fstpt (%1, %%eax) \n" \ + : \ + : "r" (TOP), "r" (fpu.p_regs) \ + : "eax", "memory" \ + ); \ + FPU_FPOP(); +#else #define FPUD_WITH_POP(op) \ Bit16u new_sw; \ __asm__ volatile ( \ @@ -504,23 +674,49 @@ ); \ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ FPU_FPOP(); +#endif -// load math constants -#define FPUD_LOAD_CONST(op) \ +// handles fyl2x +#define FPUD_FYL2X(op) \ Bit16u new_sw; \ - FPU_PREP_PUSH(); \ __asm__ volatile ( \ + "movl %1, %%eax \n" \ + "incl %%eax \n" \ + "andl $7, %%eax \n" \ + "shll $4, %%eax \n" \ "shll $4, %1 \n" \ + "fldt (%2, %%eax) \n" \ + "fldt (%2, %1) \n" \ "fclex \n" \ #op" \n" \ "fnstsw %0 \n" \ - "fstpt (%2, %1) \n" \ + "fstpt (%2, %%eax) \n" \ : "=m" (new_sw) \ : "r" (TOP), "r" (fpu.p_regs) \ - : "memory" \ + : "eax", "memory" \ ); \ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ + FPU_FPOP(); +// load math constants +#define FPUD_LOAD_CONST(op) \ + FPU_PREP_PUSH(); \ + __asm__ volatile ( \ + "shll $4, %0 \n" \ + clx" \n" \ + #op" \n" \ + "fstpt (%1, %0) \n" \ + : \ + : "r" (TOP), "r" (fpu.p_regs) \ + : "memory" \ + ); + +#endif + +#ifdef WEAK_EXCEPTIONS +const Bit16u exc_mask=0x7f00; +#else +const Bit16u exc_mask=0xffbf; #endif static void FPU_FINIT(void) { @@ -643,7 +839,7 @@ static void FPU_FSIN(void){ } static void FPU_FSINCOS(void){ - FPUD_SINCOS + FPUD_SINCOS() } static void FPU_FCOS(void){ @@ -659,7 +855,7 @@ static void FPU_FPATAN(void){ } static void FPU_FPTAN(void){ - FPUD_PTAN + FPUD_PTAN() } @@ -668,11 +864,11 @@ static void FPU_FADD(Bitu op1, Bitu op2){ } static void FPU_FDIV(Bitu op1, Bitu op2){ - FPUD_ARITH1(fdivp) + FPUD_ARITH3(fdivp) } static void FPU_FDIVR(Bitu op1, Bitu op2){ - FPUD_ARITH1(fdivrp) + FPUD_ARITH3(fdivrp) } static void FPU_FMUL(Bitu op1, Bitu op2){ @@ -750,7 +946,7 @@ static void FPU_F2XM1(void){ } static void FPU_FYL2X(void){ - FPUD_WITH_POP(fyl2x) + FPUD_FYL2X(fyl2x) } static void FPU_FYL2XP1(void){ From 57167a934e8595dcefc5aac8aab1f046993e164e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 11 Jan 2006 09:25:38 +0000 Subject: [PATCH 2342/4131] some issues with the restartable stuff. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2426 --- src/shell/shell.cpp | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 06a571f8..93dbe78f 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.67 2005-12-05 12:07:55 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.68 2006-01-11 09:25:38 qbix79 Exp $ */ #include #include @@ -46,6 +46,8 @@ static char autoexec_data[AUTOEXEC_SIZE] = { 0 }; static std::vector autoexec_strings; typedef std::vector::iterator auto_it; +void VFILE_Remove(const char *name); + void AutoexecObject::Install(char* line,...) { if(GCC_UNLIKELY(installed)) E_Exit("autoexec: allready created %s",buf); installed = true; @@ -54,16 +56,38 @@ void AutoexecObject::Install(char* line,...) { va_start(msg,line); vsprintf(buf,line,msg); va_end(msg); - - size_t auto_len=strlen(autoexec_data); - if ((auto_len+strlen(line)+3)>AUTOEXEC_SIZE) { - E_Exit("SYSTEM:Autoexec.bat file overflow"); - } - sprintf((autoexec_data+auto_len),"%s\r\n",buf); autoexec_strings.push_back(std::string(buf)); + + if(first_shell) VFILE_Remove("AUTOEXEC.BAT"); + //Create a new autoexec.bat + autoexec_data[0] = 0; + size_t auto_len; + for(auto_it it= autoexec_strings.begin(); it != autoexec_strings.end(); it++) { + auto_len = strlen(autoexec_data); + if ((auto_len+strlen((*it).c_str())+3)>AUTOEXEC_SIZE) { + E_Exit("SYSTEM:Autoexec.bat file overflow"); + } + sprintf((autoexec_data+auto_len),"%s\r\n",(*it).c_str()); + } + + //autoexec.bat is normally created AUTOEXEC_Init. + //But if we are allready running (first_shell) then create it here. + //And update the envirionment to display changes + + if(first_shell) { + VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,strlen(autoexec_data)); + char buf2[256]; strcpy(buf2,buf);//used in shell.h + if((strncasecmp(buf2,"set ",4) == 0) && (strlen(buf2) > 4)){ + char* after_set = buf2 + 4;//move to variable that is being set + char* test = strpbrk(after_set,"="); + if(!test) {first_shell->SetEnv(after_set,"");return;} + *test++ = 0; + //If the shell is running/exists update the environment + first_shell->SetEnv(after_set,test); + } + } } -void VFILE_Remove(const char *name); AutoexecObject::~AutoexecObject(){ if(!installed) return; @@ -424,7 +448,7 @@ void SHELL_Init() { "\xBA \xBA\n" ); MSG_Add("SHELL_STARTUP_CGA","\xBA DOSBox supports Composite CGA mode. \xBA\n" - "\xBA Use \033[31m(ctrl-)F11\033[37m to change the colours when in this mode. \xBA\n" + "\xBA Use \033[31m(alt-)F11\033[37m to change the colours when in this mode. \xBA\n" "\xBA \xBA\n" ); MSG_Add("SHELL_STARTUP_DEBUG", From 92203e9c1a78e4afc6b24cf10c2e4504178e644c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 11 Jan 2006 09:32:12 +0000 Subject: [PATCH 2343/4131] change ctrl to alt for increase Hue Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2427 --- src/hardware/vga_other.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 07f108d8..8b109093 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_other.cpp,v 1.15 2005-12-11 15:09:50 c2woody Exp $ */ +/* $Id: vga_other.cpp,v 1.16 2006-01-11 09:32:12 qbix79 Exp $ */ #include #include @@ -420,7 +420,7 @@ void VGA_SetupOther(void) { if (machine==MCH_CGA) { IO_RegisterWriteHandler(0x3d8,write_cga,IO_MB); IO_RegisterWriteHandler(0x3d9,write_cga,IO_MB); - MAPPER_AddHandler(IncreaseHue,MK_f11,MMOD1,"inchue","Inc Hue"); + MAPPER_AddHandler(IncreaseHue,MK_f11,MMOD2,"inchue","Inc Hue"); MAPPER_AddHandler(DecreaseHue,MK_f11,0,"dechue","Dec Hue"); } if (machine==MCH_HERC) { From afb9e84c53934fd1a878a987ef70f48393748e79 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 12 Jan 2006 10:20:20 +0000 Subject: [PATCH 2344/4131] Add an noautoexec switch (RFE: 1215226). And made echo off skip the internal SET lines of dosbox as well. (RFE/PATCH: 1258897) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2428 --- include/shell.h | 5 ++- src/dos/drive_virtual.cpp | 5 ++- src/shell/shell.cpp | 89 +++++++++++++++++++++++---------------- 3 files changed, 59 insertions(+), 40 deletions(-) diff --git a/include/shell.h b/include/shell.h index ca690e6f..d8110043 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.13 2005-08-22 19:31:26 qbix79 Exp $ */ +/* $Id: shell.h,v 1.14 2006-01-12 10:20:20 qbix79 Exp $ */ #ifndef DOSBOX_SHELL_H #define DOSBOX_SHELL_H @@ -155,7 +155,10 @@ private: public: AutoexecObject():installed(false){}; void Install(char * line,...); + void InstallBefore(char* line, ...); ~AutoexecObject(); +private: + void CreateAutoexec(void); }; #endif diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 802e6d6f..1611a978 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -53,8 +53,9 @@ void VFILE_Remove(const char *name) { VFILE_Block * chan=first_file; VFILE_Block * * where=&first_file; while (chan) { - if (strcmp(name,chan->name)==0) { - *where=chan->next; + if (strcmp(name,chan->name) == 0) { + *where = chan->next; + if(chan == first_file) first_file = chan->next; delete chan; return; } diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 93dbe78f..f407c7ec 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.68 2006-01-11 09:25:38 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.69 2006-01-12 10:20:20 qbix79 Exp $ */ #include #include @@ -43,8 +43,8 @@ static void SHELL_ProgramStart(Program * * make) { #define AUTOEXEC_SIZE 4096 static char autoexec_data[AUTOEXEC_SIZE] = { 0 }; -static std::vector autoexec_strings; -typedef std::vector::iterator auto_it; +static std::list autoexec_strings; +typedef std::list::iterator auto_it; void VFILE_Remove(const char *name); @@ -58,24 +58,13 @@ void AutoexecObject::Install(char* line,...) { va_end(msg); autoexec_strings.push_back(std::string(buf)); - if(first_shell) VFILE_Remove("AUTOEXEC.BAT"); - //Create a new autoexec.bat - autoexec_data[0] = 0; - size_t auto_len; - for(auto_it it= autoexec_strings.begin(); it != autoexec_strings.end(); it++) { - auto_len = strlen(autoexec_data); - if ((auto_len+strlen((*it).c_str())+3)>AUTOEXEC_SIZE) { - E_Exit("SYSTEM:Autoexec.bat file overflow"); - } - sprintf((autoexec_data+auto_len),"%s\r\n",(*it).c_str()); - } + this->CreateAutoexec(); //autoexec.bat is normally created AUTOEXEC_Init. - //But if we are allready running (first_shell) then create it here. - //And update the envirionment to display changes + //But if we are allready running (first_shell) + //we have to update the envirionment to display changes if(first_shell) { - VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,strlen(autoexec_data)); char buf2[256]; strcpy(buf2,buf);//used in shell.h if((strncasecmp(buf2,"set ",4) == 0) && (strlen(buf2) > 4)){ char* after_set = buf2 + 4;//move to variable that is being set @@ -88,16 +77,39 @@ void AutoexecObject::Install(char* line,...) { } } +void AutoexecObject::InstallBefore(char* line,...) { + if(GCC_UNLIKELY(installed)) E_Exit("autoexec: allready created %s",buf); + installed = true; + va_list msg; + + va_start(msg,line); + vsprintf(buf,line,msg); + va_end(msg); + autoexec_strings.push_front(std::string(buf)); + this->CreateAutoexec(); +} + +void AutoexecObject::CreateAutoexec(void) { + /* Remove old autoexec.bat if the shell exists */ + if(first_shell) VFILE_Remove("AUTOEXEC.BAT"); + + //Create a new autoexec.bat + autoexec_data[0] = 0; + size_t auto_len; + for(auto_it it= autoexec_strings.begin(); it != autoexec_strings.end(); it++) { + auto_len = strlen(autoexec_data); + if ((auto_len+strlen((*it).c_str())+3)>AUTOEXEC_SIZE) { + E_Exit("SYSTEM:Autoexec.bat file overflow"); + } + sprintf((autoexec_data+auto_len),"%s\r\n",(*it).c_str()); + } + if(first_shell) VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,strlen(autoexec_data)); +} AutoexecObject::~AutoexecObject(){ if(!installed) return; - // On destruction of the object the autoexec.bat is updated - // so that the line isn't present anymore - // First remove the current autoexec.bat - VFILE_Remove("AUTOEXEC.BAT"); - - // Remove the line from the autoexecbuffer + // Remove the line from the autoexecbuffer and update environment for(auto_it it = autoexec_strings.begin(); it != autoexec_strings.end(); ) { if((*it) == buf) { it = autoexec_strings.erase(it); @@ -112,17 +124,7 @@ AutoexecObject::~AutoexecObject(){ } } else it++; } - //Create a new autoexec.bat - autoexec_data[0] = 0; - size_t auto_len; - for(auto_it it= autoexec_strings.begin(); it != autoexec_strings.end(); it++) { - auto_len = strlen(autoexec_data); - if ((auto_len+strlen((*it).c_str())+3)>AUTOEXEC_SIZE) { - E_Exit("SYSTEM:Autoexec.bat file overflow"); - } - sprintf((autoexec_data+auto_len),"%s\r\n",(*it).c_str()); - } - VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,strlen(autoexec_data)); + this->CreateAutoexec(); } DOS_Shell::DOS_Shell():Program(){ @@ -327,16 +329,29 @@ void DOS_Shell::SyntaxError(void) { WriteOut(MSG_Get("SHELL_SYNTAXERROR")); } -namespace{ +namespace { AutoexecObject autoexec[16]; + AutoexecObject autoexec_echo; } void AUTOEXEC_Init(Section * sec) { /* Register a virtual AUOEXEC.BAT file */ std::string line; Section_line * section=static_cast(sec); - char * extra=(char *)section->data.c_str(); - if (extra) autoexec[0].Install("%s",extra); + + /* add stuff from the configfile unless -noautexec is specified. */ + char * extra=const_cast(section->data.c_str()); + if (extra && !control->cmdline->FindExist("-noautoexec",true)) { + /* detect if "echo off" is the first line */ + bool echo_off = !strncasecmp(extra,"echo off",8); + if (!echo_off) echo_off = !strncasecmp(extra,"@echo off",9); + + /* if "echo off" add it to the front of autoexec.bat */ + if(echo_off) autoexec_echo.InstallBefore("@echo off"); + + /* Install the stuff from the configfile */ + autoexec[0].Install("%s",extra); + } /* Check to see for extra command line options to be added (before the command specified on commandline) */ /* Maximum of extra commands: 10 */ From c325a806e21834727c6a4583879ec84235101d26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 13 Jan 2006 17:29:11 +0000 Subject: [PATCH 2345/4131] reduce size of exception-check code in the dynamic core Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2429 --- src/cpu/core_dyn_x86/decoder.h | 40 ++++++++++++++------------------- src/cpu/core_dyn_x86/risc_x86.h | 32 +++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 26 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 323bc5bf..79a1979c 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -142,7 +142,10 @@ static INLINE void dyn_set_eip_last(void) { } -static void DynRunException(void) { +static void DynRunException(Bit32u eip_add,Bit32u cycle_sub,Bit32u dflags) { + reg_flags=(dflags&FMASK_TEST) | (reg_flags&(~FMASK_TEST)); + reg_eip+=eip_add; + CPU_Cycles-=cycle_sub; CPU_Exception(cpu.exception.which,cpu.exception.error); } @@ -151,13 +154,11 @@ static void dyn_check_bool_exception(DynReg * check) { gen_dop_byte(DOP_OR,check,0,check,0); branch=gen_create_branch(BR_Z); dyn_savestate(&state); - dyn_flags_gen_to_host(); - dyn_reduce_cycles(); - dyn_set_eip_last(); + if (!decode.cycles) decode.cycles++; dyn_save_critical_regs(); - gen_call_function((void *)&DynRunException,""); - dyn_flags_host_to_gen(); - gen_return(BR_Normal); + if (cpu.code.big) gen_call_function((void *)&DynRunException,"%Id%Id%F",decode.op_start-decode.code_start,decode.cycles); + else gen_call_function((void *)&DynRunException,"%Iw%Id%F",(decode.op_start-decode.code_start)&0xffff,decode.cycles); + gen_return_fast(BR_Normal,false); dyn_loadstate(&state); gen_fill_branch(branch); } @@ -167,13 +168,11 @@ static void dyn_check_bool_exception_al(void) { cache_addw(0xc00a); // or al, al branch=gen_create_branch(BR_Z); dyn_savestate(&state); - dyn_flags_gen_to_host(); - dyn_reduce_cycles(); - dyn_set_eip_last(); + if (!decode.cycles) decode.cycles++; dyn_save_critical_regs(); - gen_call_function((void *)&DynRunException,""); - dyn_flags_host_to_gen(); - gen_return(BR_Normal); + if (cpu.code.big) gen_call_function((void *)&DynRunException,"%Id%Id%F",decode.op_start-decode.code_start,decode.cycles); + else gen_call_function((void *)&DynRunException,"%Iw%Id%F",(decode.op_start-decode.code_start)&0xffff,decode.cycles); + gen_return_fast(BR_Normal,false); dyn_loadstate(&state); gen_fill_branch(branch); } @@ -1122,8 +1121,7 @@ static void dyn_ret_far(Bitu bytes) { dyn_flags_gen_to_host(); dyn_save_critical_regs(); gen_call_function((void*)&CPU_RET,"%Id%Id%Drd",decode.big_op,bytes,DREG(TMPW)); - dyn_flags_host_to_gen(); - gen_return(BR_Normal); + gen_return_fast(BR_Normal); dyn_closeblock(); } @@ -1136,8 +1134,7 @@ static void dyn_call_far_imm(void) { dyn_flags_gen_to_host(); dyn_save_critical_regs(); gen_call_function((void*)&CPU_CALL,"%Id%Id%Id%Drd",decode.big_op,sel,off,DREG(TMPW)); - dyn_flags_host_to_gen(); - gen_return(BR_Normal); + gen_return_fast(BR_Normal); dyn_closeblock(); } @@ -1151,8 +1148,7 @@ static void dyn_jmp_far_imm(void) { dyn_flags_gen_to_host(); dyn_save_critical_regs(); gen_call_function((void*)&CPU_JMP,"%Id%Id%Id%Drd",decode.big_op,sel,off,DREG(TMPW)); - dyn_flags_host_to_gen(); - gen_return(BR_Normal); + gen_return_fast(BR_Normal); dyn_closeblock(); } @@ -1163,8 +1159,7 @@ static void dyn_iret(void) { dyn_set_eip_last_end(DREG(TMPW)); dyn_save_critical_regs(); gen_call_function((void*)&CPU_IRET,"%Id%Drd",decode.big_op,DREG(TMPW)); - dyn_flags_host_to_gen(); - gen_return(BR_Normal); + gen_return_fast(BR_Normal); dyn_closeblock(); } @@ -1175,8 +1170,7 @@ static void dyn_interrupt(Bitu num) { dyn_set_eip_last_end(DREG(TMPW)); dyn_save_critical_regs(); gen_call_function((void*)&CPU_Interrupt,"%Id%Id%Drd",num,CPU_INT_SOFTWARE,DREG(TMPW)); - dyn_flags_host_to_gen(); - gen_return(BR_Normal); + gen_return_fast(BR_Normal); dyn_closeblock(); } diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index e7d0f6fa..ba662e6f 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -591,6 +591,7 @@ static void gen_dshift_cl(bool dword,bool left,DynReg * dr1,DynReg * dr2,DynReg static void gen_call_function(void * func,char * ops,...) { Bits paramcount=0; + bool release_flags=false; struct ParamInfo { char * line; Bitu value; @@ -663,6 +664,9 @@ static void gen_call_function(void * func,char * ops,...) { retparam =&pinfo[pindex]; pinfo[pindex].line=scan; break; + case 'F': /* Release flags from stack */ + release_flags=true; + break; default: IllegalOption("gen_call_function unknown param"); } @@ -677,7 +681,10 @@ static void gen_call_function(void * func,char * ops,...) { /* Restore the params of the stack */ if (paramcount) { cache_addw(0xc483); //add ESP,imm byte - cache_addb(paramcount*4); + cache_addb(paramcount*4+(release_flags?4:0)); + } else if (release_flags) { + cache_addw(0xc483); //add ESP,imm byte + cache_addb(4); } /* Save the return value in correct register */ if (retparam) { @@ -838,8 +845,27 @@ static void gen_mov_host(void * data,DynReg * dr1,Bitu size,Bit8u di1=0) { static void gen_return(BlockReturn retcode) { gen_protectflags(); cache_addb(0x59); //POP ECX, the flags - cache_addb(0xb8); //MOV EAX, retcode - cache_addd(retcode); + if (retcode==0) cache_addw(0xc033); //MOV EAX, 0 + else { + cache_addb(0xb8); //MOV EAX, retcode + cache_addd(retcode); + } + cache_addb(0xc3); //RET +} + +static void gen_return_fast(BlockReturn retcode,bool popflags=true) { + if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_return_fast"); + cache_addw(0x0d8b); //MOV ECX, the flags + cache_addd((Bit32u)&cpu_regs.flags); + if (popflags) { + cache_addw(0xc483); //ADD ESP,4 + cache_addb(0x4); + } + if (retcode==0) cache_addw(0xc033); //MOV EAX, 0 + else { + cache_addb(0xb8); //MOV EAX, retcode + cache_addd(retcode); + } cache_addb(0xc3); //RET } From 931561bf3bc95adebaaaea352825385cb3072d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 17 Jan 2006 20:29:50 +0000 Subject: [PATCH 2346/4131] handle modification of the running dynamic core code block Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2430 --- src/cpu/core_dyn_x86.cpp | 16 ++++++++--- src/cpu/core_dyn_x86/cache.h | 51 +++++++++++++++++++++++++++++++-- src/cpu/core_dyn_x86/decoder.h | 8 ++++-- src/cpu/core_dyn_x86/risc_x86.h | 14 ++++----- 4 files changed, 72 insertions(+), 17 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 09569015..1aa13e98 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -46,15 +46,15 @@ #include "inout.h" #ifdef CHECKED_MEMORY_ACCESS -#define CACHE_TOTAL (1024*1024) -#define CACHE_MAXSIZE (4096*3) +#define CACHE_PAGES (128*2) +#define CACHE_MAXSIZE (4096*2) #else -#define CACHE_TOTAL (512*1024) +#define CACHE_PAGES (128) #define CACHE_MAXSIZE (4096) #endif +#define CACHE_TOTAL (CACHE_PAGES*4096) #define CACHE_BLOCKS (32*1024) #define CACHE_ALIGN (16) -#define CACHE_PAGES (128) #define DYN_HASH_SHIFT (4) #define DYN_PAGE_HASH (4096>>DYN_HASH_SHIFT) #define DYN_LINKS (16) @@ -119,8 +119,12 @@ enum BlockReturn { BR_OpcodeFull, #endif 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 @@ -252,6 +256,10 @@ run_block: return CBRET_NONE; case BR_CallBack: 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; diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 9bd30b5e..5f507a5b 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -66,21 +66,27 @@ public: memset(&hash_map,0,sizeof(hash_map)); memset(&write_map,0,sizeof(write_map)); } - void InvalidateRange(Bitu start,Bitu end) { + bool InvalidateRange(Bitu start,Bitu end) { Bits index=1+(start>>DYN_HASH_SHIFT); + bool is_current_block=false; + Bit32u ip_point=SegPhys(cs)+reg_eip; + ip_point=((paging.tlb.phys_page[ip_point>>12]-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; + 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 (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; @@ -109,6 +115,45 @@ public: if (!active_count) Release(); } else InvalidateRange(addr,addr+3); } + bool writeb_checked(PhysPt addr,Bitu val) { + addr&=4095; + host_writeb(hostmem+addr,val); + if (!*(Bit8u*)&write_map[addr]) { + if (active_blocks) return false; + active_count--; + if (!active_count) Release(); + } else if (InvalidateRange(addr,addr)) { + cpu.exception.which=SMC_CURRENT_BLOCK; + return true; + } + return false; + } + bool writew_checked(PhysPt addr,Bitu val) { + addr&=4095; + host_writew(hostmem+addr,val); + if (!*(Bit16u*)&write_map[addr]) { + if (active_blocks) return false; + active_count--; + if (!active_count) Release(); + } else if (InvalidateRange(addr,addr+1)) { + cpu.exception.which=SMC_CURRENT_BLOCK; + return true; + } + return false; + } + bool writed_checked(PhysPt addr,Bitu val) { + addr&=4095; + host_writed(hostmem+addr,val); + if (!*(Bit32u*)&write_map[addr]) { + if (active_blocks) return false; + active_count--; + if (!active_count) Release(); + } else if (InvalidateRange(addr,addr+3)) { + cpu.exception.which=SMC_CURRENT_BLOCK; + return true; + } + return false; + } void AddCacheBlock(CacheBlock * block) { Bitu index=1+(block->page.start>>DYN_HASH_SHIFT); block->hash.next=hash_map[index]; diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 79a1979c..30f6bdd2 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -142,11 +142,13 @@ static INLINE void dyn_set_eip_last(void) { } -static void DynRunException(Bit32u eip_add,Bit32u cycle_sub,Bit32u dflags) { +static BlockReturn DynRunException(Bit32u eip_add,Bit32u cycle_sub,Bit32u dflags) { reg_flags=(dflags&FMASK_TEST) | (reg_flags&(~FMASK_TEST)); reg_eip+=eip_add; CPU_Cycles-=cycle_sub; + if (cpu.exception.which==SMC_CURRENT_BLOCK) return BR_SMCBlock; CPU_Exception(cpu.exception.which,cpu.exception.error); + return BR_Normal; } static void dyn_check_bool_exception(DynReg * check) { @@ -158,7 +160,7 @@ static void dyn_check_bool_exception(DynReg * check) { dyn_save_critical_regs(); if (cpu.code.big) gen_call_function((void *)&DynRunException,"%Id%Id%F",decode.op_start-decode.code_start,decode.cycles); else gen_call_function((void *)&DynRunException,"%Iw%Id%F",(decode.op_start-decode.code_start)&0xffff,decode.cycles); - gen_return_fast(BR_Normal,false); + gen_return_fast(BR_Normal,true); dyn_loadstate(&state); gen_fill_branch(branch); } @@ -172,7 +174,7 @@ static void dyn_check_bool_exception_al(void) { dyn_save_critical_regs(); if (cpu.code.big) gen_call_function((void *)&DynRunException,"%Id%Id%F",decode.op_start-decode.code_start,decode.cycles); else gen_call_function((void *)&DynRunException,"%Iw%Id%F",(decode.op_start-decode.code_start)&0xffff,decode.cycles); - gen_return_fast(BR_Normal,false); + gen_return_fast(BR_Normal,true); dyn_loadstate(&state); gen_fill_branch(branch); } diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index ba662e6f..65d1ab68 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -853,18 +853,18 @@ static void gen_return(BlockReturn retcode) { cache_addb(0xc3); //RET } -static void gen_return_fast(BlockReturn retcode,bool popflags=true) { +static void gen_return_fast(BlockReturn retcode,bool ret_exception=false) { if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_return_fast"); cache_addw(0x0d8b); //MOV ECX, the flags cache_addd((Bit32u)&cpu_regs.flags); - if (popflags) { + if (!ret_exception) { cache_addw(0xc483); //ADD ESP,4 cache_addb(0x4); - } - if (retcode==0) cache_addw(0xc033); //MOV EAX, 0 - else { - cache_addb(0xb8); //MOV EAX, retcode - cache_addd(retcode); + if (retcode==0) cache_addw(0xc033); //MOV EAX, 0 + else { + cache_addb(0xb8); //MOV EAX, retcode + cache_addd(retcode); + } } cache_addb(0xc3); //RET } From 67693a939678d93f7db892c290e07e12f197e8aa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 19 Jan 2006 14:42:19 +0000 Subject: [PATCH 2347/4131] Add patch 1391092:"Soundblaster DSP fixes" from Vasyl and the SB MIDI interface from Srecko. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2431 --- src/hardware/sblaster.cpp | 69 +++++++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 10 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 24900da7..aa8bd9f6 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: sblaster.cpp,v 1.51 2006-01-19 14:42:19 qbix79 Exp $ */ + #include #include #include "dosbox.h" @@ -28,6 +30,9 @@ #include "support.h" #include "shell.h" +void MIDI_RawOutByte(Bit8u data); +bool MIDI_Available(void); + #define SB_PIC_EVENTS 0 #define DSP_MAJOR 3 @@ -94,6 +99,7 @@ struct SB_INFO { Bitu remain_size; } dma; bool speaker; + bool midi; Bit8u time_constant; DSP_MODES mode; SB_TYPES type; @@ -155,7 +161,7 @@ static Bit8u DSP_cmd_len[256] = { 0,0,0,0, 0,2,0,0, 0,0,0,0, 0,0,0,0, // 0x00 1,0,0,0, 2,0,2,2, 0,0,0,0, 0,0,0,0, // 0x10 0,0,0,0, 2,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x30 + 0,0,0,0, 0,0,0,0, 1,0,0,0, 0,0,0,0, // 0x30 1,2,2,0, 0,0,0,0, 2,0,0,0, 0,0,0,0, // 0x40 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x50 @@ -344,7 +350,7 @@ INLINE Bit8u decode_ADPCM_3_sample(Bit8u sample,Bit8u & reference,Bits& scale) { } static void GenerateDMASound(Bitu size) { - Bitu read;Bitu done=0;Bitu i=0; + Bitu read=0;Bitu done=0;Bitu i=0; if (sb.dma.left<=sb.dma.min) { size=sb.dma.left; } @@ -669,6 +675,9 @@ static void DSP_ADC_CallBack(DmaChannel * chan, DMAEvent event) { Bitu DEBUG_EnableDebugger(void); +#define DSP_SB16_ONLY if (sb.type != SBT_16) { LOG(LOG_SB,LOG_ERROR)("DSP:Command %2X requires SB16",sb.dsp.cmd); break; } +#define DSP_SB2_ABOVE if (sb.type <= SBT_1) { LOG(LOG_SB,LOG_ERROR)("DSP:Command %2X requires SB2 or above",sb.dsp.cmd); break; } + static void DSP_DoCommand(void) { // LOG_MSG("DSP Command %X",sb.dsp.cmd); switch (sb.dsp.cmd) { @@ -690,12 +699,17 @@ static void DSP_DoCommand(void) { break; case 0x14: /* Singe Cycle 8-Bit DMA DAC */ case 0x91: /* Singe Cycle 8-Bit DMA High speed DAC */ + /* Note: 0x91 is documented only for DSP ver.2.x and 3.x, not 4.x */ DSP_PrepareDMA_Old(DSP_DMA_8,false); break; case 0x90: /* Auto Init 8-bit DMA High Speed */ case 0x1c: /* Auto Init 8-bit DMA */ + DSP_SB2_ABOVE; /* Note: 0x90 is documented only for DSP ver.2.x and 3.x, not 4.x */ DSP_PrepareDMA_Old(DSP_DMA_8,true); break; + case 0x38: /* Write to SB MIDI Output */ + if (sb.midi == true) MIDI_RawOutByte(sb.dsp.in.data[0]); + break; case 0x40: /* Set Timeconstant */ sb.freq=(1000000 / (256 - sb.dsp.in.data[0])); /* Nasty kind of hack to allow runtime changing of frequency */ @@ -705,15 +719,17 @@ static void DSP_DoCommand(void) { break; case 0x41: /* Set Output Samplerate */ case 0x42: /* Set Input Samplerate */ + DSP_SB16_ONLY; sb.freq=(sb.dsp.in.data[0] << 8) | sb.dsp.in.data[1]; break; case 0x48: /* Set DMA Block Size */ + DSP_SB2_ABOVE; //TODO Maybe check limit for new irq? sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); break; - case 0x75: /* 075h : Single Cycle 4-bit ADPCM Reference */ + case 0x75: /* 075h : Single Cycle 4-bit ADPCM Reference */ sb.adpcm.haveref=true; - case 0x74: /* 074h : Single Cycle 4-bit ADPCM */ + case 0x74: /* 074h : Single Cycle 4-bit ADPCM */ DSP_PrepareDMA_Old(DSP_DMA_4,false); break; case 0x77: /* 077h : Single Cycle 3-bit(2.6bit) ADPCM Reference*/ @@ -730,8 +746,11 @@ static void DSP_DoCommand(void) { PIC_AddEvent(&DSP_RaiseIRQEvent, (1000.0f*(1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8))/sb.freq)); break; - case 0xb0: case 0xb2: case 0xb4: case 0xb6: - case 0xc0: case 0xc2: case 0xc4: case 0xc6: + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: + case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: + DSP_SB16_ONLY; /* Generic 8/16 bit DMA */ // DSP_SetSpeaker(true); //SB16 always has speaker enabled sb.dma.sign=(sb.dsp.in.data[0] & 0x10) > 0; @@ -741,8 +760,9 @@ static void DSP_DoCommand(void) { (sb.dsp.in.data[0] & 0x20) > 0 ); break; - case 0xd0: /* Halt 8-bit DMA */ case 0xd5: /* Halt 16-bit DMA */ + DSP_SB16_ONLY; + case 0xd0: /* Halt 8-bit DMA */ // DSP_ChangeMode(MODE_NONE); // Games sometimes already program a new dma before stopping, gives noise sb.mode=MODE_DMA_PAUSE; @@ -755,18 +775,23 @@ static void DSP_DoCommand(void) { DSP_SetSpeaker(false); break; case 0xd8: /* Speaker status */ + DSP_SB2_ABOVE; DSP_FlushData(); if (sb.speaker) DSP_AddData(0xff); else DSP_AddData(0x00); break; - case 0xd4: /* Continue DMA 8-bit*/ case 0xd6: /* Continue DMA 16-bit */ + DSP_SB16_ONLY; + case 0xd4: /* Continue DMA 8-bit*/ if (sb.mode==MODE_DMA_PAUSE) { sb.mode=MODE_DMA_MASKED; sb.dma.chan->Register_Callback(DSP_DMA_CallBack); } break; + case 0xd9: /* Exit Autoinitialize 16-bit */ + DSP_SB16_ONLY; case 0xda: /* Exit Autoinitialize 8-bit */ + DSP_SB2_ABOVE; /* Set mode to single transfer so it ends with current block */ sb.dma.autoinit=false; //Should stop itself break; @@ -817,8 +842,29 @@ static void DSP_DoCommand(void) { case 0xf2: /* Trigger 8bit IRQ */ SB_RaiseIRQ(SB_IRQ_8); break; + case 0xf8: /* Undocumented, pre-SB16 only */ + DSP_FlushData(); + DSP_AddData(0); + break; + case 0x30: case 0x31: + LOG(LOG_SB,LOG_ERROR)("DSP:Unimplemented MIDI I/O command %2X",sb.dsp.cmd); + break; + case 0x34: case 0x35: case 0x36: case 0x37: + DSP_SB2_ABOVE; + LOG(LOG_SB,LOG_ERROR)("DSP:Unimplemented MIDI UART command %2X",sb.dsp.cmd); + break; + case 0x7d: case 0x7f: case 0x1f: + DSP_SB2_ABOVE; + LOG(LOG_SB,LOG_ERROR)("DSP:Unimplemented auto-init DMA ADPCM command %2X",sb.dsp.cmd); + break; + case 0x20: + case 0x2c: + case 0x98: case 0x99: /* Documented only for DSP 2.x and 3.x */ + case 0xa0: case 0xa8: /* Documented only for DSP 3.x */ + LOG(LOG_SB,LOG_ERROR)("DSP:Unimplemented input command %2X",sb.dsp.cmd); + break; default: - LOG(LOG_SB,LOG_ERROR)("DSP:Unhandled command %2X",sb.dsp.cmd); + LOG(LOG_SB,LOG_ERROR)("DSP:Unhandled (undocumented) command %2X",sb.dsp.cmd); break; } sb.dsp.cmd=DSP_NO_COMMAND; @@ -1162,7 +1208,6 @@ public: break; } if (sb.type==SBT_NONE) return; - sb.chan=MixerChan.Install(&SBLASTER_CallBack,22050,"SB"); sb.dsp.state=DSP_S_NORMAL; @@ -1187,6 +1232,10 @@ public: sprintf(hdma,"H%d ",sb.hw.dma16); } autoexecline.Install("SET BLASTER=A%3X I%d D%d %sT%d",sb.hw.base,sb.hw.irq,sb.hw.dma8,hdma,sb.type); + + /* Soundblaster midi interface */ + if (!MIDI_Available()) sb.midi = false; + else sb.midi = true; } ~SBLASTER() { From f47287f59c678e2efcd8bc936b522bd6dd27406c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 20 Jan 2006 21:27:03 +0000 Subject: [PATCH 2348/4131] dynamic core: prevent double memory access on smc, handle 16bit-underflow of stack (fixes Privateer) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2432 --- src/cpu/core_dyn_x86/cache.h | 27 +++++++++++++++------------ src/cpu/core_dyn_x86/decoder.h | 7 ++++--- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 5f507a5b..4777c2ee 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -117,41 +117,44 @@ public: } bool writeb_checked(PhysPt addr,Bitu val) { addr&=4095; - host_writeb(hostmem+addr,val); if (!*(Bit8u*)&write_map[addr]) { - if (active_blocks) return false; - active_count--; - if (!active_count) Release(); + if (!active_blocks) { + active_count--; + if (!active_count) Release(); + } } else 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; - host_writew(hostmem+addr,val); if (!*(Bit16u*)&write_map[addr]) { - if (active_blocks) return false; - active_count--; - if (!active_count) Release(); + if (!active_blocks) { + active_count--; + if (!active_count) Release(); + } } else 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; - host_writed(hostmem+addr,val); if (!*(Bit32u*)&write_map[addr]) { - if (active_blocks) return false; - active_count--; - if (!active_count) Release(); + if (!active_blocks) { + active_count--; + if (!active_count) Release(); + } } else if (InvalidateRange(addr,addr+3)) { cpu.exception.which=SMC_CURRENT_BLOCK; return true; } + host_writed(hostmem+addr,val); return false; } void AddCacheBlock(CacheBlock * block) { diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 30f6bdd2..274df299 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -272,8 +272,8 @@ static void dyn_push(DynReg * dynreg) { } else { gen_dop_word_imm(DOP_SUB,true,DREG(ESP),2); } + gen_dop_word(DOP_AND,true,DREG(ESP),DREG(SMASK)); gen_dop_word(DOP_MOV,true,DREG(STACK),DREG(ESP)); - gen_dop_word(DOP_AND,true,DREG(STACK),DREG(SMASK)); gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); if (decode.big_op) { gen_call_function((void *)&mem_writed,"%Drd%Dd",DREG(STACK),dynreg); @@ -299,6 +299,7 @@ static void dyn_pop(DynReg * dynreg) { } else { gen_dop_word_imm(DOP_ADD,true,DREG(ESP),2); } + gen_dop_word(DOP_AND,true,DREG(ESP),DREG(SMASK)); } } @@ -904,8 +905,8 @@ static void dyn_load_seg_off_ea(SegNames seg) { dyn_fill_ea(); gen_lea(DREG(TMPW),DREG(EA),0,0,decode.big_op ? 4:2); dyn_read_word(DREG(TMPW),DREG(TMPW),false); - dyn_load_seg(seg,DREG(TMPW));gen_releasereg(DREG(TMPW)); dyn_read_word_release(DREG(EA),&DynRegs[decode.modrm.reg],decode.big_op); + dyn_load_seg(seg,DREG(TMPW));gen_releasereg(DREG(TMPW)); } else { IllegalOption("dyn_load_seg_off_ea"); } @@ -1701,8 +1702,8 @@ restart_prefix: gen_protectflags(); dyn_flags_gen_to_host(); gen_lea(DREG(EA),DREG(EA),0,0,decode.big_op ? 4: 2); - dyn_set_eip_last_end(DREG(TMPB)); dyn_read_word(DREG(EA),DREG(EA),false); + dyn_set_eip_last_end(DREG(TMPB)); dyn_save_critical_regs(); gen_call_function( decode.modrm.reg == 3 ? (void*)&CPU_CALL : (void*)&CPU_JMP, From 18cb433c5cb139c0c7d82e0a4518dbaeb545b409 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 22 Jan 2006 14:10:37 +0000 Subject: [PATCH 2349/4131] update Changelog Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2433 --- ChangeLog | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 4f6b755e..d427ec84 100644 --- a/ChangeLog +++ b/ChangeLog @@ -47,6 +47,16 @@ - 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 with 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. + - Made core_full endian safe. + - Made pagefaults endian safe. + - Compilation fixes for various platforms. - Lots of bugfixes. - Even more bugfixes. From 2b828867f7695142e169342bb7d84048559d594f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 22 Jan 2006 14:13:00 +0000 Subject: [PATCH 2350/4131] change ctrl-pause to alt-pause Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2434 --- README | 2 +- src/debug/debug.cpp | 4 ++-- src/dos/dos_programs.cpp | 4 ++-- src/gui/sdlmain.cpp | 4 ++-- src/shell/shell.cpp | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README b/README index e7ece2b3..6fe210ab 100644 --- a/README +++ b/README @@ -574,7 +574,7 @@ For more information use the /? command line switch with the programs. ================ ALT-ENTER Switch to full screen and back. -CTRL-PAUSE Pause emulation. +ALT-PAUSE Pause emulation. CTRL-F1 Start the keymapper. CTRL-F4 Change between mounted disk-images. Update directory cache for all drives! CTRL-F5 Save a screenshot.(png) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 791cc022..d3030752 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.71 2005-11-24 17:53:48 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.72 2006-01-22 14:13:00 qbix79 Exp $ */ #include #include @@ -1977,7 +1977,7 @@ void DEBUG_Init(Section* sec) { MSG_Add("DEBUG_CONFIGFILE_HELP","Debugger related options.\n"); DEBUG_DrawScreen(); /* Add some keyhandlers */ - MAPPER_AddHandler(DEBUG_Enable,MK_pause,MMOD1,"debugger","Debugger"); + MAPPER_AddHandler(DEBUG_Enable,MK_pause,MMOD2,"debugger","Debugger"); /* Clear the TBreakpoint list */ memset((void*)&codeViewData,0,sizeof(codeViewData)); /* setup debug.com */ diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index aa83df83..cb7ed663 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.50 2006-01-05 14:14:52 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.51 2006-01-22 14:13:00 qbix79 Exp $ */ #include #include @@ -936,7 +936,7 @@ void DOS_SetupPrograms(void) { "They can be changed in the \033[33mkeymapper\033[0m.\n" "\n" "\033[33;1mALT-ENTER\033[0m : Go full screen and back.\n" - "\033[33;1mCTRL-PAUSE\033[0m : Pause DOSBox.\n" + "\033[33;1mALT-PAUSE\033[0m : Pause DOSBox.\n" "\033[33;1mCTRL-F1\033[0m : Start the \033[33mkeymapper\033[0m.\n" "\033[33;1mCTRL-F4\033[0m : Update directory cache for all drives! Swap mounted disk-image.\n" "\033[33;1mCTRL-F5\033[0m : Save a screenshot.\n" diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 3f189057..8b7790e0 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.94 2005-12-02 10:02:03 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.95 2006-01-22 14:13:00 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -937,7 +937,7 @@ static void GUI_StartUp(Section * sec) { #if C_DEBUG /* Pause binds with activate-debugger */ #else - MAPPER_AddHandler(PauseDOSBox,MK_pause,MMOD1,"pause","Pause"); + MAPPER_AddHandler(PauseDOSBox,MK_pause,MMOD2,"pause","Pause"); #endif /* Get Keyboard state of numlock and capslock */ SDLMod keystate = SDL_GetModState(); diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index f407c7ec..db6e4127 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.69 2006-01-12 10:20:20 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.70 2006-01-22 14:13:00 qbix79 Exp $ */ #include #include @@ -467,7 +467,7 @@ void SHELL_Init() { "\xBA \xBA\n" ); MSG_Add("SHELL_STARTUP_DEBUG", - "\xBA Press \033[31mctrl-Pause\033[37m to enter the debugger or start the exe with \033[33mDEBUG\033[37m.\xBA\n" + "\xBA Press \033[31malt-Pause\033[37m to enter the debugger or start the exe with \033[33mDEBUG\033[37m. \xBA\n" "\xBA \xBA\n" ); MSG_Add("SHELL_STARTUP_END", From e24298c28ad7492a342693c904fbe5f4e6ac7a53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 26 Jan 2006 21:07:17 +0000 Subject: [PATCH 2351/4131] dynamic core: add memory checking stack functions (Descent1), move rarely executed blocks to end of cacheblock Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2435 --- src/cpu/core_dyn_x86/decoder.h | 169 +++++++++++++++++++++++++------- src/cpu/core_dyn_x86/risc_x86.h | 10 ++ src/cpu/core_dyn_x86/string.h | 24 +++-- 3 files changed, 153 insertions(+), 50 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 274df299..ecede836 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -135,13 +135,32 @@ static INLINE void dyn_set_eip_end(void) { gen_protectflags(); gen_dop_word_imm(DOP_ADD,cpu.code.big,DREG(EIP),decode.code-decode.code_start); } - + +static INLINE void dyn_set_eip_end(DynReg * endreg) { + gen_protectflags(); + gen_dop_word(DOP_MOV,cpu.code.big,DREG(TMPW),DREG(EIP)); + gen_dop_word_imm(DOP_ADD,cpu.code.big,DREG(TMPW),decode.code-decode.code_start); +} + static INLINE void dyn_set_eip_last(void) { gen_protectflags(); gen_dop_word_imm(DOP_ADD,cpu.code.big,DREG(EIP),decode.op_start-decode.code_start); } +enum save_info_type {exception, cycle_check, normal}; + +struct { + save_info_type type; + DynState state; + Bit8u * branch_pos; + Bit32u eip_change; + Bitu cycles; +} save_info[512]; + +Bitu used_save_info=0; + + static BlockReturn DynRunException(Bit32u eip_add,Bit32u cycle_sub,Bit32u dflags) { reg_flags=(dflags&FMASK_TEST) | (reg_flags&(~FMASK_TEST)); reg_eip+=eip_add; @@ -152,31 +171,53 @@ static BlockReturn DynRunException(Bit32u eip_add,Bit32u cycle_sub,Bit32u dflags } static void dyn_check_bool_exception(DynReg * check) { - Bit8u * branch;DynState state; gen_dop_byte(DOP_OR,check,0,check,0); - branch=gen_create_branch(BR_Z); - dyn_savestate(&state); + save_info[used_save_info].branch_pos=gen_create_branch_long(BR_NZ); + dyn_savestate(&save_info[used_save_info].state); if (!decode.cycles) decode.cycles++; - dyn_save_critical_regs(); - if (cpu.code.big) gen_call_function((void *)&DynRunException,"%Id%Id%F",decode.op_start-decode.code_start,decode.cycles); - else gen_call_function((void *)&DynRunException,"%Iw%Id%F",(decode.op_start-decode.code_start)&0xffff,decode.cycles); - gen_return_fast(BR_Normal,true); - dyn_loadstate(&state); - gen_fill_branch(branch); + save_info[used_save_info].cycles=decode.cycles; + save_info[used_save_info].eip_change=decode.op_start-decode.code_start; + if (!cpu.code.big) save_info[used_save_info].eip_change&=0xffff; + save_info[used_save_info].type=exception; + used_save_info++; } static void dyn_check_bool_exception_al(void) { - Bit8u * branch;DynState state; cache_addw(0xc00a); // or al, al - branch=gen_create_branch(BR_Z); - dyn_savestate(&state); + save_info[used_save_info].branch_pos=gen_create_branch_long(BR_NZ); + dyn_savestate(&save_info[used_save_info].state); if (!decode.cycles) decode.cycles++; - dyn_save_critical_regs(); - if (cpu.code.big) gen_call_function((void *)&DynRunException,"%Id%Id%F",decode.op_start-decode.code_start,decode.cycles); - else gen_call_function((void *)&DynRunException,"%Iw%Id%F",(decode.op_start-decode.code_start)&0xffff,decode.cycles); - gen_return_fast(BR_Normal,true); - dyn_loadstate(&state); - gen_fill_branch(branch); + save_info[used_save_info].cycles=decode.cycles; + save_info[used_save_info].eip_change=decode.op_start-decode.code_start; + if (!cpu.code.big) save_info[used_save_info].eip_change&=0xffff; + save_info[used_save_info].type=exception; + used_save_info++; +} + +static void dyn_fill_blocks(void) { + for (Bitu sct=0; sct> 6) & 3; @@ -903,10 +992,11 @@ static void dyn_load_seg_off_ea(SegNames seg) { dyn_get_modrm(); if (GCC_UNLIKELY(decode.modrm.mod<3)) { dyn_fill_ea(); - gen_lea(DREG(TMPW),DREG(EA),0,0,decode.big_op ? 4:2); - dyn_read_word(DREG(TMPW),DREG(TMPW),false); - dyn_read_word_release(DREG(EA),&DynRegs[decode.modrm.reg],decode.big_op); - dyn_load_seg(seg,DREG(TMPW));gen_releasereg(DREG(TMPW)); + gen_lea(DREG(TMPB),DREG(EA),0,0,decode.big_op ? 4:2); + dyn_read_word(DREG(TMPB),DREG(TMPB),false); + dyn_read_word_release(DREG(EA),DREG(TMPW),decode.big_op); + dyn_load_seg(seg,DREG(TMPB));gen_releasereg(DREG(TMPB)); + gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.reg],DREG(TMPW)); } else { IllegalOption("dyn_load_seg_off_ea"); } @@ -953,7 +1043,9 @@ static void dyn_pop_ev(void) { dyn_get_modrm(); if (decode.modrm.mod<3) { dyn_fill_ea(); - dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); +// dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); + if (decode.big_op) gen_call_function((void *)&mem_writed_dyncorex86,"%Ddr%Dd",DREG(EA),DREG(TMPW)); + else gen_call_function((void *)&mem_writew_dyncorex86,"%Ddr%Dd",DREG(EA),DREG(TMPW)); } else { gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],DREG(TMPW)); } @@ -976,7 +1068,7 @@ static void dyn_leave(void) { gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(EBP)); gen_dop_word(DOP_AND,true,DREG(TMPW),DREG(SMASK)); gen_dop_word(DOP_OR,true,DREG(ESP),DREG(TMPW)); - dyn_pop(DREG(EBP)); + dyn_pop_unchecked(DREG(EBP)); gen_releasereg(DREG(TMPW)); } @@ -988,6 +1080,7 @@ static void dyn_segprefix(SegNames seg) { static void dyn_closeblock(void) { //Shouldn't create empty block normally but let's do it like this gen_protectflags(); + dyn_fill_blocks(); cache_closeblock(); } @@ -1108,9 +1201,10 @@ static void dyn_call_near_imm(void) { Bits imm; if (decode.big_op) imm=(Bit32s)decode_fetchd(); else imm=(Bit16s)decode_fetchw(); - dyn_set_eip_end(); - dyn_push(DREG(EIP)); - gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),imm); + dyn_set_eip_end(DREG(TMPW)); + dyn_push(DREG(TMPW)); + gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(TMPW),imm); + gen_dop_word(DOP_MOV,decode.big_op,DREG(EIP),DREG(TMPW)); dyn_reduce_cycles(); dyn_save_critical_regs(); gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); @@ -1200,9 +1294,9 @@ static CacheBlock * CreateCacheBlock(CodePageHandler * codepage,PhysPt start,Bit /* Start with the cycles check */ gen_protectflags(); gen_dop_word_imm(DOP_CMP,true,DREG(CYCLES),0); - Bit8u * cyclebranch=gen_create_branch(BR_NLE); - gen_return(BR_Cycles); - gen_fill_branch(cyclebranch); + save_info[used_save_info].branch_pos=gen_create_branch_long(BR_LE); + save_info[used_save_info].type=cycle_check; + used_save_info++; gen_releasereg(DREG(CYCLES)); decode.cycles=0; while (max_opcodes--) { @@ -1344,13 +1438,13 @@ restart_prefix: case 0x60: /* PUSHA */ gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(ESP)); for (i=G_EAX;i<=G_EDI;i++) { - dyn_push((i!=G_ESP) ? &DynRegs[i] : DREG(TMPW)); + dyn_push_unchecked((i!=G_ESP) ? &DynRegs[i] : DREG(TMPW)); } gen_releasereg(DREG(TMPW)); break; case 0x61: /* POPA */ for (i=G_EDI;i>=G_EAX;i--) { - dyn_pop((i!=G_ESP) ? &DynRegs[i] : DREG(TMPW)); + dyn_pop_unchecked((i!=G_ESP) ? &DynRegs[i] : DREG(TMPW)); } gen_releasereg(DREG(TMPW)); break; @@ -1690,8 +1784,9 @@ restart_prefix: } break; case 0x2: /* CALL Ev */ - gen_lea(DREG(EIP),DREG(EIP),0,0,decode.code-decode.code_start); - dyn_push(DREG(EIP)); + gen_lea(DREG(TMPB),DREG(EIP),0,0,decode.code-decode.code_start); + dyn_push(DREG(TMPB)); + gen_releasereg(DREG(TMPB)); gen_dop_word(DOP_MOV,decode.big_op,DREG(EIP),src); goto core_close_block; case 0x4: /* JMP Ev */ diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 65d1ab68..d3a2856a 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -765,6 +765,16 @@ static void gen_fill_branch(Bit8u * data,Bit8u * from=cache.pos) { *data=(from-data-1); } +static Bit8u * gen_create_branch_long(BranchTypes type) { + cache_addw(0x800f+(type<<8)); + cache_addd(0); + return (cache.pos-4); +} + +static void gen_fill_branch_long(Bit8u * data,Bit8u * from=cache.pos) { + *(Bit32u*)data=(from-data-4); +} + static Bit8u * gen_create_jump(Bit8u * to=0) { /* First free all registers */ cache_addb(0xe9); diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index 13748c56..48d61672 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -83,9 +83,7 @@ static void dyn_string(STRING_OP op) { /* Check if ECX!=zero */ if (decode.rep) { gen_dop_word(DOP_OR,decode.big_addr,DREG(ECX),DREG(ECX)); - Bit8u * branch_ecx=gen_create_branch(BR_NZ); - rep_ecx_jmp=gen_create_jump(); - gen_fill_branch(branch_ecx); + rep_ecx_jmp=gen_create_branch_long(BR_Z); } if (usesi) { if (!decode.big_addr) { @@ -146,21 +144,21 @@ static void dyn_string(STRING_OP op) { if (usedi) gen_dop_word(DOP_ADD,decode.big_addr,DREG(EDI),DREG(TMPW)); if (decode.rep) { - DynState cycle_state; gen_sop_word(SOP_DEC,decode.big_addr,DREG(ECX)); gen_sop_word(SOP_DEC,true,DREG(CYCLES)); gen_releasereg(DREG(CYCLES)); - dyn_savestate(&cycle_state); - Bit8u * cycle_branch=gen_create_branch(BR_NLE); - gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),decode.op_start-decode.code_start); - dyn_save_critical_regs(); - gen_return(BR_Cycles); - gen_fill_branch(cycle_branch); - dyn_loadstate(&cycle_state); - dyn_synchstate(&rep_state); + 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); - gen_fill_jump(rep_ecx_jmp); + + dyn_loadstate(&rep_state); + gen_fill_branch_long(rep_ecx_jmp); } gen_releasereg(DREG(TMPW)); } From 2f358d904ef3141b7ec890ed7ce8698725846a2c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 27 Jan 2006 07:54:51 +0000 Subject: [PATCH 2352/4131] increased amount of simultanious cdrom drives. Makes a few people happy with games that have lot's of cdroms. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2436 --- src/dos/dos_mscdex.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 7751deb7..018b0ef3 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.34 2005-12-05 19:23:10 harekiet Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.35 2006-01-27 07:54:51 qbix79 Exp $ */ #include #include @@ -34,7 +34,7 @@ #define MSCDEX_VERSION_HIGH 2 #define MSCDEX_VERSION_LOW 23 -#define MSCDEX_MAX_DRIVES 5 +#define MSCDEX_MAX_DRIVES 8 // Error Codes #define MSCDEX_ERROR_BAD_FORMAT 11 From c5c513fc60044c1186efd0a8ff03883ea2bb14fe Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 27 Jan 2006 10:44:55 +0000 Subject: [PATCH 2353/4131] Work around broken POSIX implementations. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2437 --- src/dos/drive_local.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index a38e66af..8d6151aa 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.61 2005-08-19 07:13:34 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.62 2006-01-27 10:44:55 qbix79 Exp $ */ #include #include @@ -303,7 +303,7 @@ bool localDrive::TestDir(char * dir) { if (len && (newdir[len-1]!='\\')) { // It has to be a directory ! struct stat test; - if (stat(newdir,&test)==-1) return false; + if (stat(newdir,&test)) return false; if ((test.st_mode & S_IFDIR)==0) return false; }; int temp=access(newdir,F_OK); From 5a601f5b3516cfd3e64e634756dc57c36e4de9eb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 09:46:01 +0000 Subject: [PATCH 2354/4131] New pagehandler option for different read and write pointers Slight change to getphysicaladdress call to always use the tables Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2438 --- include/paging.h | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/include/paging.h b/include/paging.h index d0ffa03b..7a05d61e 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.20 2006-01-07 14:17:53 c2woody Exp $ */ +/* $Id: paging.h,v 1.21 2006-01-30 09:46:01 harekiet Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H @@ -54,13 +54,14 @@ public: 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, Bitu * val); virtual bool readw_checked(PhysPt addr, Bitu * val); virtual bool readd_checked(PhysPt addr, Bitu * 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); - virtual HostPt GetHostPt(Bitu phys_page); Bitu flags; }; @@ -79,8 +80,8 @@ void PAGING_UnlinkPages(Bitu lin_page,Bitu pages); void PAGING_MapPage(Bitu lin_page,Bitu phys_page); bool PAGING_MakePhysPage(Bitu & page); -void MEM_SetLFB(Bitu _page,Bitu _pages,HostPt _pt); -void MEM_SetPageHandler(Bitu phys_page,Bitu pages,PageHandler * handler); +void MEM_SetLFB( Bitu page, Bitu pages, PageHandler *handler); +void MEM_SetPageHandler(Bitu phys_page, Bitu pages, PageHandler * handler); void MEM_ResetPageHandler(Bitu phys_page, Bitu pages); @@ -152,13 +153,15 @@ extern PagingBlock paging; PageHandler * MEM_GetPageHandler(Bitu phys_page); /* Use this helper function to access linear addresses in readX/writeX functions */ -INLINE PhysPt PAGING_GetLinearAddress(PhysPt addr) { - if (paging.enabled) - return (paging.tlb.phys_page[addr>>12]<<12)|(addr&0xfff); - else - return addr; +INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { + return (paging.tlb.phys_page[linePage>>12]<<12); } +INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { + return (paging.tlb.phys_page[linAddr>>12]<<12)|(linAddr&0xfff); +} + + /* Unaligned address handlers */ Bit16u mem_unalignedreadw(PhysPt address); Bit32u mem_unalignedreadd(PhysPt address); From c73974515122c5b781757b031af0fd6258259fb3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 09:47:04 +0000 Subject: [PATCH 2355/4131] New pagehandler option for different read and write pointers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2439 --- src/cpu/core_dyn_x86/cache.h | 7 +++++-- src/cpu/paging.cpp | 16 ++++++++++------ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 4777c2ee..9d307779 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -216,10 +216,13 @@ public: } return 0; } - HostPt GetHostPt(Bitu phys_page) { - hostmem=old_pagehandler->GetHostPt(phys_page); + 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]; CodePageHandler * next, * prev; diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index b80c7c0e..e1d93a52 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -67,6 +67,14 @@ void PageHandler::writed(PhysPt addr,Bitu val) { writeb(addr+3,(Bit8u) (val >> 24)); }; +HostPt PageHandler::GetHostReadPt(Bitu phys_page) { + return 0; +} + +HostPt PageHandler::GetHostWritePt(Bitu phys_page) { + return 0; +} + bool PageHandler::readb_checked(PhysPt addr, Bitu * val) { *val=readb(addr); return false; } @@ -86,9 +94,6 @@ bool PageHandler::writed_checked(PhysPt addr,Bitu val) { writed(addr,val); return false; } -HostPt PageHandler::GetHostPt(Bitu phys_page) { - return 0; -} struct PF_Entry { @@ -350,11 +355,10 @@ void PAGING_LinkPage(Bitu lin_page,Bitu phys_page) { PAGING_ClearTLB(); } - HostPt host_mem=handler->GetHostPt(phys_page); paging.tlb.phys_page[lin_page]=phys_page; - if (handler->flags & PFLAG_READABLE) paging.tlb.read[lin_page]=host_mem-lin_base; + if (handler->flags & PFLAG_READABLE) paging.tlb.read[lin_page]=handler->GetHostReadPt(phys_page)-lin_base; else paging.tlb.read[lin_page]=0; - if (handler->flags & PFLAG_WRITEABLE) paging.tlb.write[lin_page]=host_mem-lin_base; + if (handler->flags & PFLAG_WRITEABLE) paging.tlb.write[lin_page]=handler->GetHostWritePt(phys_page)-lin_base; else paging.tlb.write[lin_page]=0; paging.links.entries[paging.links.used++]=lin_page; From 45f98bff5354896d20ef5e12b1d7b7ab12979e6f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 09:48:03 +0000 Subject: [PATCH 2356/4131] Fix some compilation warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2440 --- src/debug/debug.cpp | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index d3030752..0c2b4a1f 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.72 2006-01-22 14:13:00 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.73 2006-01-30 09:48:03 harekiet Exp $ */ #include #include @@ -56,8 +56,8 @@ int old_cursor_state; static void DrawCode(void); static bool DEBUG_Log_Loop(int count); static void DEBUG_RaiseTimerIrq(void); -static void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num); -static void SaveMemoryBin(Bitu seg, Bitu ofs1, Bit32s num); +static void SaveMemory(Bitu seg, Bitu ofs1, Bit32u num); +static void SaveMemoryBin(Bitu seg, Bitu ofs1, Bit32u num); static void LogGDT(void); static void LogLDT(void); static void LogIDT(void); @@ -69,6 +69,24 @@ static void DrawVariables(void); char* AnalyzeInstruction(char* inst, bool saveSelector); Bit32u GetHexValue(char* str, char*& hex); +class DebugPageHandler : public PageHandler { +public: + Bitu readb(PhysPt addr) { + } + Bitu readw(PhysPt addr) { + } + Bitu readd(PhysPt addr) { + } + void writeb(PhysPt addr,Bitu val) { + } + void writew(PhysPt addr,Bitu val) { + } + void writed(PhysPt addr,Bitu val) { + } + + + +}; class DEBUG; @@ -2064,7 +2082,7 @@ bool CDebugVar::LoadVars(char* name) return true; }; -static void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num) +static void SaveMemory(Bitu seg, Bitu ofs1, Bit32u num) { FILE* f = fopen("MEMDUMP.TXT","wt"); if (!f) { @@ -2091,7 +2109,7 @@ static void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num) DEBUG_ShowMsg("DEBUG: Memory dump success.\n"); }; -static void SaveMemoryBin(Bitu seg, Bitu ofs1, Bit32s num) { +static void SaveMemoryBin(Bitu seg, Bitu ofs1, Bit32u num) { FILE* f = fopen("MEMDUMP.BIN","wt"); if (!f) { DEBUG_ShowMsg("DEBUG: Memory binary dump failed.\n"); From 8cceb3b0e9712f037afa0751d4fce90924f3d395 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 09:49:07 +0000 Subject: [PATCH 2357/4131] new svgacard option that's not finished Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2441 --- include/dosbox.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/dosbox.h b/include/dosbox.h index 51017f56..a36a76eb 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -47,6 +47,12 @@ enum MachineType { MCH_VGA }; +enum SVGACards { + SVGA_None, + SVGA_S3Trio +}; + +extern SVGACards svgaCard; extern MachineType machine; extern bool SDLNetInited; From a9f5e6619b6fdfd9ef1cc452db2f2794ab5025e6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 09:54:34 +0000 Subject: [PATCH 2358/4131] Scaler rewrite for detecting changes New scalers for tv3x, rgb2x, rgb3x, scan2x, scan3x Only updaterect the changed parts in sdl Add support for 15/16/32bpp modes Add support for highres 4bpp modes Rewrite of vga page handlers for most other modes AVI capturing using zmbv codec Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2442 --- include/hardware.h | 13 ++++++++++ include/render.h | 59 +++++++++++++++++++++++++++++++++++++++++++--- include/vga.h | 36 +++++++++++++++++++++------- include/video.h | 34 ++++++++++++-------------- 4 files changed, 112 insertions(+), 30 deletions(-) diff --git a/include/hardware.h b/include/hardware.h index 0c89fa5e..d8e19470 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -25,13 +25,26 @@ class Section; enum OPL_Mode { OPL_none,OPL_cms,OPL_opl2,OPL_dualopl2,OPL_opl3 }; +#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 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 diff --git a/include/render.h b/include/render.h index de42225e..a8ca48d5 100644 --- a/include/render.h +++ b/include/render.h @@ -19,13 +19,66 @@ #ifndef DOSBOX_RENDER_H #define DOSBOX_RENDER_H -typedef void (* RENDER_Line_Handler)(const Bit8u * src); +#include "../src/gui/render_scalers.h" -void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,bool dblw,bool dblh); +typedef struct { + struct { + Bit8u red; + Bit8u green; + Bit8u blue; + Bit8u unused; + } rgb[256]; + union { + Bit16u b16[256]; + Bit32u b32[256]; + } lut; + bool modified[256]; + Bitu first; + Bitu last; + bool changed; +} RenderPal_t; + +typedef struct { + struct { + Bitu width; + Bitu height; + Bitu bpp; + bool dblw,dblh; + double ratio; + float fps; + } src; + struct { + Bitu count; + Bitu max; + } frameskip; + struct { + Bitu size; + scalerMode_t inMode; + scalerMode_t outMode; + scalerOperation_t op; + ScalerLineHandler_t currentHandler; + Bitu lineFlags; + bool clearCache; + + ScalerLineHandler_t lineHandler; + ScalerCacheHandler_t cacheHandler; + Bitu blocks, lastBlock; + Bitu outPitch; + Bit8u *outWrite; + Bitu inHeight, inLine, outLine; + } scale; + RenderPal_t pal; + bool updating; + bool active; + bool aspect; +} Render_t; + +extern Render_t render; +void RENDER_DrawLine( const void *src ); +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); void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue); -extern RENDER_Line_Handler RENDER_DrawLine; #endif diff --git a/include/vga.h b/include/vga.h index ceb6f4d7..fe4b1b91 100644 --- a/include/vga.h +++ b/include/vga.h @@ -23,17 +23,19 @@ #include "dosbox.h" #endif +class PageHandler; + enum VGAModes { - M_CGA2,M_CGA4, - M_EGA16, - M_VGA, - M_LIN8, + 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_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 @@ -86,7 +88,6 @@ typedef struct { Bit32u full_not_enable_set_reset; Bit32u full_enable_set_reset; Bit32u full_enable_and_set_reset; - } VGA_Config; typedef struct { @@ -291,10 +292,20 @@ union VGA_Memory { Bit8u linear[512*1024*4]; Bit8u paged[512*1024][4]; VGA_Latch latched[512*1024]; -}; +}; +typedef struct { + Bit32u page; + Bit32u addr; + Bit32u mask; + PageHandler *handler; +} VGA_LFB; + +#define VGA_CHANGE_SHIFT 9 +typedef Bit8u VGA_Changed[(2*1024*1024) >> VGA_CHANGE_SHIFT]; typedef struct { VGAModes mode; /* The mode the vga system is in */ + VGAModes lastmode; Bit8u misc_output; VGA_Draw draw; VGA_Config config; @@ -311,6 +322,8 @@ typedef struct { VGA_TANDY tandy; VGA_OTHER other; VGA_Memory mem; + VGA_LFB lfb; + VGA_Changed changed; Bit8u * gfxmem_start; } VGA_Type; @@ -351,6 +364,13 @@ void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3); void VGA_ActivateHardwareCursor(void); void VGA_KillDrawing(void); +/* S3 Functions */ +Bitu SVGA_S3_GetClock(void); +void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen); +Bitu SVGA_S3_ReadCRTC(Bitu reg,Bitu iolen); +void SVGA_S3_WriteSEQ(Bitu reg,Bitu val,Bitu iolen); +Bitu SVGA_S3_ReadSEQ(Bitu reg,Bitu iolen); + extern VGA_Type vga; extern Bit32u ExpandTable[256]; diff --git a/include/video.h b/include/video.h index 08bbc5bf..b89aa938 100644 --- a/include/video.h +++ b/include/video.h @@ -19,7 +19,7 @@ #ifndef DOSBOX_VIDEO_H #define DOSBOX_VIDEO_H -typedef void (* GFX_ResetCallBack)(void); +typedef void (* GFX_ResetCallBack)( bool stopIt ); struct GFX_PalEntry { Bit8u r; @@ -28,39 +28,35 @@ struct GFX_PalEntry { Bit8u unused; }; -#define CAN_8 0x0001 -#define CAN_16 0x0002 -#define CAN_32 0x0004 +#define GFX_CAN_8 0x0001 +#define GFX_CAN_15 0x0002 +#define GFX_CAN_16 0x0004 +#define GFX_CAN_32 0x0008 -#define CAN_ALL (CAN_8|CAN_16|CAN_32) +#define GFX_LOVE_8 0x0010 +#define GFX_LOVE_15 0x0020 +#define GFX_LOVE_16 0x0040 +#define GFX_LOVE_32 0x0080 -#define LOVE_8 0x0010 -#define LOVE_16 0x0020 -#define LOVE_32 0x0040 +#define GFX_RGBONLY 0x0100 -#define NEED_RGB 0x0100 -#define DONT_ASPECT 0x0200 +#define GFX_SCALING 0x1000 +#define GFX_HARDWARE 0x2000 -#define HAVE_SCALING 0x1000 - - -enum GFX_Modes { - GFX_8,GFX_15,GFX_16,GFX_32,GFX_NONE, -}; +#define GFX_CAN_RANDOM 0x4000 //If the interface can also do random access surface void GFX_Events(void); void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries); Bitu GFX_GetBestMode(Bitu flags); - Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue); -GFX_Modes GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_ResetCallBack cb_reset); +Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_ResetCallBack cb_reset); void GFX_ResetScreen(void); void GFX_Start(void); void GFX_Stop(void); void GFX_SwitchFullScreen(void); bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch); -void GFX_EndUpdate(void); +void GFX_EndUpdate( const Bit16u *changedLines ); /* Mouse related */ void GFX_CaptureMouse(void); From 0968989c7a0ea7a06c0c278c1940fc3c80b72670 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 09:57:18 +0000 Subject: [PATCH 2359/4131] Remove active events when losing focus Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2443 --- src/gui/sdl_mapper.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index aaf2f413..2247b941 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.17 2005-10-24 17:39:00 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.18 2006-01-30 09:57:18 harekiet Exp $ */ #define OLD_JOYSTICK 1 @@ -1509,6 +1509,12 @@ static void CreateBindGroups(void) { } } +void MAPPER_LosingFocus(void) { + for (CEventVector_it evit=events.begin();evit!=events.end();evit++) { + (*evit)->DeActivateAll(); + } +} + void MAPPER_Run(void) { /* Deactive all running binds */ for (CEventVector_it evit=events.begin();evit!=events.end();evit++) { @@ -1522,7 +1528,7 @@ void MAPPER_Run(void) { } /* Be sure that there is no update in progress */ - GFX_EndUpdate(); + GFX_EndUpdate( 0 ); mapper.surface=SDL_SetVideoMode(640,480,8,0); if (mapper.surface == NULL) E_Exit("Could not initialize video mode for mapper: %s",SDL_GetError()); From 3b74afe0c4fa1f1003e698f40402e58a2ff6cc12 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 09:58:07 +0000 Subject: [PATCH 2360/4131] Scaler rewrite for detecting changes New scalers for tv3x, rgb2x, rgb3x, scan2x, scan3x Only updaterect the changed parts in sdl Add support for 15/16/32bpp modes Add support for highres 4bpp modes Rewrite of vga page handlers for most other modes AVI capturing using zmbv codec New option for hardware scaled windows to try and reach a specified resolution Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2444 --- src/gui/midi.cpp | 98 +----- src/gui/render.cpp | 534 ++++++++++++++-------------- src/gui/render_loops.h | 182 ++++++++++ src/gui/render_scalers.cpp | 253 ++++++++++---- src/gui/render_scalers.h | 121 +++++-- src/gui/render_templates.h | 694 ++++++++++++++++++++++++------------- src/gui/sdlmain.cpp | 349 ++++++++++++------- 7 files changed, 1418 insertions(+), 813 deletions(-) create mode 100644 src/gui/render_loops.h diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 524ab956..9c303bb1 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -107,86 +107,8 @@ static struct { } sysex; bool available; MidiHandler * handler; - struct { - FILE * handle; - Bit8u buffer[RAWBUF+SYSEX_SIZE]; - bool capturing; - Bitu used,done; - Bit32u last; - } raw; } midi; -static Bit8u midi_header[]={ - 'M','T','h','d', /* Bit32u, Header Chunk */ - 0x0,0x0,0x0,0x6, /* Bit32u, Chunk Length */ - 0x0,0x0, /* Bit16u, Format, 0=single track */ - 0x0,0x1, /* Bit16u, Track Count, 1 track */ - 0x01,0xf4, /* Bit16u, Timing, 2 beats/second with 500 frames */ - 'M','T','r','k', /* Bit32u, Track Chunk */ - 0x0,0x0,0x0,0x0, /* Bit32u, Chunk Length */ - //Track data -}; - -#define ADDBUF(_VAL_) midi.raw.buffer[midi.raw.used++]=(Bit8u)(_VAL_); -static INLINE void RawAddNumber(Bit32u val) { - if (val & 0xfe00000) ADDBUF(0x80|((val >> 21) & 0x7f)); - if (val & 0xfffc000) ADDBUF(0x80|((val >> 14) & 0x7f)); - if (val & 0xfffff80) ADDBUF(0x80|((val >> 7) & 0x7f)); - ADDBUF(val & 0x7f); -} -static INLINE void RawAddDelta(void) { - if (!midi.raw.handle) { - midi.raw.handle=OpenCaptureFile("Raw Midi",".mid"); - if (!midi.raw.handle) { - midi.raw.capturing=false; - return; - } - fwrite(midi_header,1,sizeof(midi_header),midi.raw.handle); - midi.raw.last=PIC_Ticks; - } - Bit32u delta=PIC_Ticks-midi.raw.last; - midi.raw.last=PIC_Ticks; - RawAddNumber(delta); -} - -static INLINE void RawAddData(Bit8u * data,Bitu len) { - for (Bitu i=0;i=RAWBUF) { - fwrite(midi.raw.buffer,1,midi.raw.used,midi.raw.handle); - midi.raw.done+=midi.raw.used; - midi.raw.used=0; - } -} - -static void MIDI_SaveRawEvent(void) { - /* Check for previously opened wave file */ - if (midi.raw.capturing) { - LOG_MSG("Stopping raw midi saving."); - midi.raw.capturing=false; - if (!midi.raw.handle) return; - ADDBUF(0x00);//Delta time - ADDBUF(0xff);ADDBUF(0x2F);ADDBUF(0x00); //End of track event - fwrite(midi.raw.buffer,1,midi.raw.used,midi.raw.handle); - midi.raw.done+=midi.raw.used; - fseek(midi.raw.handle,18, SEEK_SET); - Bit8u size[4]; - size[0]=(Bit8u)(midi.raw.done >> 24); - size[1]=(Bit8u)(midi.raw.done >> 16); - size[2]=(Bit8u)(midi.raw.done >> 8); - size[3]=(Bit8u)(midi.raw.done >> 0); - fwrite(&size,1,4,midi.raw.handle); - fclose(midi.raw.handle); - midi.raw.handle=0; - } else { - LOG_MSG("Preparing for raw midi capture, will start with first data."); - midi.raw.used=0; - midi.raw.done=0; - midi.raw.handle=0; - midi.raw.capturing=true; - } -} - - void MIDI_RawOutByte(Bit8u data) { /* Test for a active sysex tranfer */ if (midi.status==0xf0) { @@ -197,11 +119,8 @@ void MIDI_RawOutByte(Bit8u data) { midi.sysex.buf[midi.sysex.used++]=0xf7; midi.handler->PlaySysex(midi.sysex.buf,midi.sysex.used); LOG(LOG_ALL,LOG_NORMAL)("Sysex message size %d",midi.sysex.used); - if (midi.raw.capturing) { - RawAddDelta(); - ADDBUF(0xf0); - RawAddNumber(midi.sysex.used-1); - RawAddData(&midi.sysex.buf[1],midi.sysex.used-1); + if (CaptureState & CAPTURE_MIDI) { + CAPTURE_AddMidi( true, midi.sysex.used-1, &midi.sysex.buf[1]); } } } @@ -217,9 +136,8 @@ void MIDI_RawOutByte(Bit8u data) { if (midi.cmd_len) { midi.cmd_buf[midi.cmd_pos++]=data; if (midi.cmd_pos >= midi.cmd_len) { - if (midi.raw.capturing) { - RawAddDelta(); - RawAddData(midi.cmd_buf,midi.cmd_len); + if (CaptureState & CAPTURE_MIDI) { + CAPTURE_AddMidi(false, midi.cmd_len, midi.cmd_buf); } midi.handler->PlayMsg(midi.cmd_buf); midi.cmd_pos=1; //Use Running status @@ -231,7 +149,6 @@ bool MIDI_Available(void) { return midi.available; } - class MIDI:public Module_base{ public: MIDI(Section* configuration):Module_base(configuration){ @@ -240,12 +157,10 @@ public: const char * conf=section->Get_string("config"); /* If device = "default" go for first handler that works */ MidiHandler * handler; - MAPPER_AddHandler(MIDI_SaveRawEvent,MK_f8,MMOD1|MMOD2,"caprawmidi","Cap MIDI"); +// MAPPER_AddHandler(MIDI_SaveRawEvent,MK_f8,MMOD1|MMOD2,"caprawmidi","Cap MIDI"); midi.status=0x00; midi.cmd_pos=0; midi.cmd_len=0; - midi.raw.handle=0; - midi.raw.capturing=false; if (!strcasecmp(dev,"default")) goto getdefault; handler=handler_list; while (handler) { @@ -276,12 +191,13 @@ getdefault: /* This shouldn't be possible */ } ~MIDI(){ - if(midi.raw.handle) MIDI_SaveRawEvent(); if(midi.available) midi.handler->Close(); midi.available = false; midi.handler = 0; } }; + + static MIDI* test; void MIDI_Destroy(Section* sec){ delete test; diff --git a/src/gui/render.cpp b/src/gui/render.cpp index e3cd1381..b6bd4ea8 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.35 2005-10-25 14:02:11 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.36 2006-01-30 09:58:07 harekiet Exp $ */ #include #include @@ -34,166 +34,45 @@ #include "render_scalers.h" -struct PalData { - struct { - Bit8u red; - Bit8u green; - Bit8u blue; - Bit8u unused; - } rgb[256]; - volatile Bitu first; - volatile Bitu last; -}; - -static struct { - struct { - Bitu width; - Bitu height; - Bitu bpp; - bool dblw,dblh; - double ratio; - } src; - struct { - Bitu width; - Bitu height; - Bitu pitch; - GFX_Modes mode; - RENDER_Operation type; - RENDER_Operation want_type; - RENDER_Line_Handler line_handler; - } op; - struct { - Bitu count; - Bitu max; - } frameskip; - PalData pal; -#if (C_SSHOT) - struct { - Bitu bpp,width,height,rowlen; - Bit8u * buffer,* draw; - bool take,taking; - } shot; -#endif - bool active; - bool aspect; - bool updating; -} render; - -RENDER_Line_Handler RENDER_DrawLine; - -#if (C_SSHOT) -#include - -static void RENDER_ShotDraw(const Bit8u * src) { - memcpy(render.shot.draw,src,render.shot.rowlen); - render.shot.draw+=render.shot.rowlen; - render.op.line_handler(src); -} - -/* Take a screenshot of the data that should be rendered */ -static void TakeScreenShot(Bit8u * bitmap) { - png_structp png_ptr; - png_infop info_ptr; - png_bytep * row_pointers; - png_color palette[256]; - Bitu i; - Bitu fix_double_scale = 1;//variable to compensate for only doubleheight - - /* Remove this if we save rendered screens. instead of pre-rendered */ - if(render.src.dblh && !render.src.dblw) fix_double_scale = 2; - - - /* Open the actual file */ - FILE * fp=OpenCaptureFile("Screenshot",".png"); - if (!fp) return; - /* First try to alloacte the png structures */ - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL, NULL); - if (!png_ptr) return; - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_write_struct(&png_ptr,(png_infopp)NULL); - return; - } - - /* Finalize the initing of png library */ - png_init_io(png_ptr, fp); - png_set_compression_level(png_ptr,Z_BEST_COMPRESSION); - - /* set other zlib parameters */ - png_set_compression_mem_level(png_ptr, 8); - png_set_compression_strategy(png_ptr,Z_DEFAULT_STRATEGY); - png_set_compression_window_bits(png_ptr, 15); - png_set_compression_method(png_ptr, 8); - png_set_compression_buffer_size(png_ptr, 8192); - - if (render.shot.bpp==8) { - png_set_IHDR(png_ptr, info_ptr, render.shot.width, (render.shot.height*fix_double_scale), - 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - for (i=0;i<256;i++) { - palette[i].red=render.pal.rgb[i].red; - palette[i].green=render.pal.rgb[i].green; - palette[i].blue=render.pal.rgb[i].blue; - } - png_set_PLTE(png_ptr, info_ptr, palette,256); - } else { - png_set_IHDR(png_ptr, info_ptr, render.shot.width, (render.shot.height*fix_double_scale), - render.shot.bpp, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - } - - /*Allocate an array of scanline pointers*/ - row_pointers=(png_bytep*)malloc(render.shot.height*fix_double_scale*sizeof(png_bytep)); - for (i = 0;i < render.shot.height;i++) { - row_pointers[fix_double_scale*i] = (bitmap+i*render.shot.rowlen); - if(fix_double_scale == 2) row_pointers[fix_double_scale*i+1] = (bitmap+i*render.shot.rowlen); - } - - /*tell the png library what to encode.*/ - png_set_rows(png_ptr, info_ptr, row_pointers); - - /*Write image to file*/ - png_write_png(png_ptr, info_ptr, 0, NULL); - - /*close file*/ - fclose(fp); - - /*Destroy PNG structs*/ - png_destroy_write_struct(&png_ptr, &info_ptr); - - /*clean up dynamically allocated RAM.*/ - free(row_pointers); -} - -static void EnableScreenShot(void) { - render.shot.take=true; -} - -#endif - +Render_t render; static void Check_Palette(void) { - if (render.pal.first>render.pal.last) return; + /* Clean up any previous changed palette data */ + if (render.pal.changed) { + memset(render.pal.modified, 0, sizeof(render.pal.modified)); + render.pal.changed = false; + } + if (render.pal.first>render.pal.last) + return; Bitu i; - switch (render.op.mode) { - case GFX_8: + switch (render.scale.outMode) { + case scalerMode8: GFX_SetPalette(render.pal.first,render.pal.last-render.pal.first+1,(GFX_PalEntry *)&render.pal.rgb[render.pal.first]); break; - case GFX_15: - case GFX_16: + case scalerMode15: + case scalerMode16: for (i=render.pal.first;i<=render.pal.last;i++) { Bit8u r=render.pal.rgb[i].red; Bit8u g=render.pal.rgb[i].green; Bit8u b=render.pal.rgb[i].blue; - Scaler_PaletteLut.b16[i]=GFX_GetRGB(r,g,b); + Bit16u newPal = GFX_GetRGB(r,g,b); + if (newPal != render.pal.lut.b16[i]) { + render.pal.changed = true; + render.pal.lut.b16[i] = newPal; + } } break; - case GFX_32: + case scalerMode32: + default: for (i=render.pal.first;i<=render.pal.last;i++) { Bit8u r=render.pal.rgb[i].red; Bit8u g=render.pal.rgb[i].green; Bit8u b=render.pal.rgb[i].blue; - Scaler_PaletteLut.b32[i]=GFX_GetRGB(r,g,b); + Bit32u newPal = GFX_GetRGB(r,g,b); + if (newPal != render.pal.lut.b32[i]) { + render.pal.changed = true; + render.pal.lut.b32[i] = newPal; + } } break; } @@ -215,60 +94,101 @@ void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue) { if (render.pal.last=render.frameskip.max) { - if (render.src.bpp==8) Check_Palette(); - render.frameskip.count=0; - Scaler_Line=0; - Scaler_Index=Scaler_Data; - if (GFX_StartUpdate(Scaler_DstWrite,Scaler_DstPitch)) { - RENDER_DrawLine=render.op.line_handler; -#if (C_SSHOT) - if (GCC_UNLIKELY(render.shot.take)) { - render.shot.take=false; - if (render.shot.buffer) free(render.shot.buffer); - render.shot.width=render.src.width; - render.shot.height=render.src.height; - render.shot.bpp=render.src.bpp; - switch (render.shot.bpp) { - case 8:render.shot.rowlen=render.shot.width;break; - case 15: - case 16:render.shot.rowlen=render.shot.width*2;break; - case 32:render.shot.rowlen=render.shot.width*4;break; - } - render.shot.buffer=(Bit8u*)malloc(render.shot.rowlen*render.shot.height); - render.shot.draw=render.shot.buffer; - RENDER_DrawLine=RENDER_ShotDraw; - render.shot.taking=true; - } -#endif - render.updating=true; - return true; - } - } else render.frameskip.count++; - } - return false; + if (GCC_UNLIKELY(render.updating)) + return false; + if (GCC_UNLIKELY(!render.active)) + return false; + if (GCC_UNLIKELY(render.frameskip.countsimple[render.scale.outMode]; + } else { + render.scale.cacheHandler = cacheBlock->complex[render.scale.outMode]; + } + } + render.scale.lineHandler = render.scale.currentHandler; + render.updating=true; + return true; } void RENDER_EndUpdate(void) { - if (render.updating) { -#if (C_SSHOT) - if (GCC_UNLIKELY(render.shot.taking)) { - render.shot.taking=false; - TakeScreenShot(render.shot.buffer); - free(render.shot.buffer); - render.shot.buffer=0; + if (!render.updating) + return; + render.scale.cacheHandler = RENDER_EmptyCacheHandler; + render.scale.lineHandler = RENDER_EmptyLineHandler; + if (CaptureState & (CAPTURE_IMAGE|CAPTURE_VIDEO)) { + Bitu pitch, flags; + switch (render.scale.inMode) { + case scalerMode8: + pitch = sizeof(scalerSourceCache.b8[0]); + break; + case scalerMode15: + case scalerMode16: + pitch = sizeof(scalerSourceCache.b16[0]); + break; + case scalerMode32: + pitch = sizeof(scalerSourceCache.b32[0]); + break; + } + flags = 0; + if (render.src.dblw != render.src.dblh) { + if (render.src.dblw) flags|=CAPTURE_FLAG_DBLW; + if (render.src.dblh) flags|=CAPTURE_FLAG_DBLH; + } + CAPTURE_AddImage( render.src.width, render.src.height, render.src.bpp, pitch, + flags, render.src.fps, scalerSourceCache.b8[0], (Bit8u*)&render.pal.rgb ); } -#endif /* If Things are added to please check the define */ - GFX_EndUpdate(); - RENDER_DrawLine=RENDER_EmptyLineHandler; + GFX_EndUpdate( Scaler_ChangedLines ); render.updating=false; - } +} + +void RENDER_DrawLine( const void *src ) { + render.scale.cacheHandler( src ); + render.scale.lineHandler(); } static Bitu MakeAspectTable(Bitu height,double scaley,Bitu miny) { @@ -280,90 +200,191 @@ static Bitu MakeAspectTable(Bitu height,double scaley,Bitu miny) { Bitu templines=(Bitu)lines; lines-=templines; linesadded+=templines; - Scaler_Data[i]=templines-miny; - } else Scaler_Data[i]=0; + Scaler_Aspect[1+i]=templines-miny; + } else Scaler_Aspect[1+i]=0; } return linesadded; } -void RENDER_ReInit(void) { - if (render.updating) RENDER_EndUpdate(); +void RENDER_ReInit( bool stopIt ) { + if (render.updating) + RENDER_EndUpdate(); + + if (stopIt) + return; + Bitu width=render.src.width; Bitu height=render.src.height; bool dblw=render.src.dblw; bool dblh=render.src.dblh; - double gfx_scalew=1.0; - double gfx_scaleh=1.0; + double gfx_scalew; + double gfx_scaleh; - if (render.src.ratio>1.0) gfx_scaleh*=render.src.ratio; - else gfx_scalew*=(1/render.src.ratio); - Bitu gfx_flags; - ScalerBlock * block; + ScalerLineBlock_t *lineBlock; + if (render.aspect) { + if (render.src.ratio>1.0) { + gfx_scalew = 1; + gfx_scaleh = render.src.ratio; + } else { + gfx_scalew = (1/render.src.ratio); + gfx_scaleh = 1; + } + } else { + gfx_scalew = 1; + gfx_scaleh = 1; + } + lineBlock = &ScaleNormal; if (dblh && dblw) { - render.op.type=render.op.want_type; + /* Initialize always working defaults */ + if (render.scale.size == 2) + lineBlock = &ScaleNormal2x; + else if (render.scale.size == 3) + lineBlock = &ScaleNormal3x; + else + lineBlock = &ScaleNormal; + /* Maybe override them */ + switch (render.scale.op) { + case scalerOpAdvInterp: + if (render.scale.size == 2) + lineBlock = &ScaleAdvInterp2x; + break; + case scalerOpAdvMame: + if (render.scale.size == 2) + lineBlock = &ScaleAdvMame2x; + else if (render.scale.size == 3) + lineBlock = &ScaleAdvMame3x; + break; + case scalerOpTV: + if (render.scale.size == 2) + lineBlock = &ScaleTV2x; + else if (render.scale.size == 3) + lineBlock = &ScaleTV3x; + break; + case scalerOpRGB: + if (render.scale.size == 2) + lineBlock = &ScaleRGB2x; + else if (render.scale.size == 3) + lineBlock = &ScaleRGB3x; + break; + case scalerOpScan: + if (render.scale.size == 2) + lineBlock = &ScaleScan2x; + else if (render.scale.size == 3) + lineBlock = &ScaleScan3x; + break; + } } else if (dblw) { - render.op.type=OP_Normal2x; + lineBlock = &ScaleNormalDw; } else if (dblh) { - render.op.type=OP_Normal; - gfx_scaleh*=2; + lineBlock = &ScaleNormalDh; } else { forcenormal: - render.op.type=OP_Normal; + lineBlock = &ScaleNormal; } - switch (render.op.type) { - case OP_Normal:block=&Normal_8;break; - case OP_Normal2x:block=(dblh) ? &Normal2x_8 : &NormalDbl_8;break; - case OP_AdvMame2x:block=&AdvMame2x_8;break; - case OP_AdvMame3x:block=&AdvMame3x_8;break; - case OP_Interp2x:block=&Interp2x_8;break; - case OP_AdvInterp2x:block=&AdvInterp2x_8;break; - case OP_TV2x:block=&TV2x_8;break; - } - gfx_flags=GFX_GetBestMode(block->flags); + gfx_flags = lineBlock->gfxFlags; + if (render.src.bpp != 8) + gfx_flags |= GFX_RGBONLY; + gfx_flags=GFX_GetBestMode(gfx_flags); if (!gfx_flags) { - if (render.op.type==OP_Normal) E_Exit("Failed to create a rendering output"); - else goto forcenormal; + if (lineBlock == &ScaleNormal) + E_Exit("Failed to create a rendering output"); + else + goto forcenormal; } /* Special test for normal2x to switch to normal with hardware scaling */ - if (gfx_flags & HAVE_SCALING && render.op.type==OP_Normal2x) { - if (dblw) gfx_scalew*=2; - if (dblh) gfx_scaleh*=2; - block=&Normal_8; - render.op.type=OP_Normal; - } - width*=block->xscale; - if (gfx_flags & HAVE_SCALING) { - height=MakeAspectTable(render.src.height,block->yscale,block->miny); + width *= lineBlock->xscale; + if (gfx_flags & GFX_SCALING) { + height = MakeAspectTable(render.src.height, lineBlock->yscale, lineBlock->yscale ); } else { - gfx_scaleh*=block->yscale; - height=MakeAspectTable(render.src.height,gfx_scaleh,block->miny); + if ((gfx_flags & GFX_CAN_RANDOM) && gfx_scaleh > 1) { + gfx_scaleh *= lineBlock->yscale; + height = MakeAspectTable(render.src.height, gfx_scaleh, lineBlock->yscale ); + } else { + gfx_flags &= ~GFX_CAN_RANDOM; //Hardware surface when possible + height = MakeAspectTable(render.src.height, lineBlock->yscale, lineBlock->yscale); + } } /* Setup the scaler variables */ - render.op.mode=GFX_SetSize(width,height,gfx_flags,gfx_scalew,gfx_scaleh,&RENDER_ReInit);; - if (render.op.mode==GFX_NONE) E_Exit("Failed to create a rendering output"); - render.op.line_handler=block->handlers[render.op.mode]; - render.op.width=width; - render.op.height=height; - Scaler_SrcWidth=render.src.width; - Scaler_SrcHeight=render.src.height; + gfx_flags=GFX_SetSize(width,height,gfx_flags,gfx_scalew,gfx_scaleh,&RENDER_ReInit);; + if (gfx_flags & GFX_CAN_8) + render.scale.outMode = scalerMode8; + else if (gfx_flags & GFX_CAN_15) + render.scale.outMode = scalerMode15; + else if (gfx_flags & GFX_CAN_16) + render.scale.outMode = scalerMode16; + else if (gfx_flags & GFX_CAN_32) + render.scale.outMode = scalerMode32; + else + E_Exit("Failed to create a rendering output"); + if (gfx_flags & GFX_HARDWARE) { + render.scale.currentHandler = lineBlock->Linear[ render.scale.outMode ]; + } else { + render.scale.currentHandler = lineBlock->Random[ render.scale.outMode ]; + } + switch (render.src.bpp) { + case 8: + render.scale.inMode = scalerMode8; + break; + case 15: + render.scale.inMode = scalerMode15; + break; + case 16: + render.scale.inMode = scalerMode16; + break; + case 32: + render.scale.inMode = scalerMode32; + break; + default: + E_Exit("RENDER:Wrong source bpp %d", render.src.bpp ); + } + render.scale.lineFlags = lineBlock->scaleFlags; + render.scale.blocks = render.src.width / SCALER_BLOCKSIZE; + render.scale.lastBlock = render.src.width % SCALER_BLOCKSIZE; + render.scale.inHeight = render.src.height; RENDER_ResetPal(); + /* Not exactltly the best way to clean the cache, but seems to do the trick */ + for (Bitu y=0;y0;x--) + cacheLine[x] = ~cacheLine[x]; + } + //Maybe do it again through a special passthrough cache check handler + render.scale.clearCache = true; render.active=true; } -void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,bool dblw,bool dblh) { +void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool dblw,bool dblh) { if (!width || !height) { render.active=false; return; } + RENDER_EndUpdate(); render.src.width=width; render.src.height=height; render.src.bpp=bpp; render.src.dblw=dblw; render.src.dblh=dblh; - render.src.ratio=render.aspect ? ratio : 1.0; - RENDER_ReInit(); + render.src.fps=fps; + render.src.ratio=ratio; + RENDER_ReInit( false ); } extern void GFX_SetTitle(Bits cycles, Bits frameskip,bool paused); @@ -385,42 +406,43 @@ void RENDER_Init(Section * sec) { //For restarting the renderer. static bool running = false; bool aspect = render.aspect; - RENDER_Operation type = render.op.want_type; + scalerOperation_t scaleOp = render.scale.op; render.pal.first=256; render.pal.last=0; render.aspect=section->Get_bool("aspect"); render.frameskip.max=section->Get_int("frameskip"); render.frameskip.count=0; + render.active=false; const char * scaler;std::string cline; if (control->cmdline->FindString("-scaler",cline,false)) { scaler=cline.c_str(); } else { scaler=section->Get_string("scaler"); } - if (!strcasecmp(scaler,"none")) render.op.want_type=OP_Normal; - else if (!strcasecmp(scaler,"normal2x")) render.op.want_type=OP_Normal2x; - else if (!strcasecmp(scaler,"advmame2x")) render.op.want_type=OP_AdvMame2x; - else if (!strcasecmp(scaler,"advmame3x")) render.op.want_type=OP_AdvMame3x; - else if (!strcasecmp(scaler,"advinterp2x")) render.op.want_type=OP_AdvInterp2x; - else if (!strcasecmp(scaler,"interp2x")) render.op.want_type=OP_Interp2x; - else if (!strcasecmp(scaler,"tv2x")) render.op.want_type=OP_TV2x; + if (!strcasecmp(scaler,"none")) { render.scale.op = scalerOpNormal;render.scale.size = 1; } + else if (!strcasecmp(scaler,"normal2x")) { render.scale.op = scalerOpNormal;render.scale.size = 2; } + else if (!strcasecmp(scaler,"normal3x")) { render.scale.op = scalerOpNormal;render.scale.size = 3; } + else if (!strcasecmp(scaler,"advmame2x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 2; } + else if (!strcasecmp(scaler,"advmame3x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 3; } + else if (!strcasecmp(scaler,"advinterp2x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 2; } + else if (!strcasecmp(scaler,"tv2x")) { render.scale.op = scalerOpTV;render.scale.size = 2; } + else if (!strcasecmp(scaler,"tv3x")) { render.scale.op = scalerOpTV;render.scale.size = 3; } + else if (!strcasecmp(scaler,"rgb2x")){ render.scale.op = scalerOpRGB;render.scale.size = 2; } + else if (!strcasecmp(scaler,"rgb3x")){ render.scale.op = scalerOpRGB;render.scale.size = 3; } + else if (!strcasecmp(scaler,"scan2x")){ render.scale.op = scalerOpScan;render.scale.size = 2; } + else if (!strcasecmp(scaler,"scan3x")){ render.scale.op = scalerOpScan;render.scale.size = 3; } else { - render.op.want_type=OP_Normal; + render.scale.op = scalerOpNormal;render.scale.size = 1; LOG_MSG("Illegal scaler type %s,falling back to normal.",scaler); } //If something changed that needs a ReInit - if(running && (render.aspect != aspect || render.op.want_type != type)) - RENDER_ReInit(); + if(running && (render.aspect != aspect || render.scale.op != scaleOp)) + RENDER_ReInit( false ); if(!running) render.updating=true; running = true; - - -#if (C_SSHOT) - MAPPER_AddHandler(EnableScreenShot,MK_f5,MMOD1,"scrshot","Screenshot"); -#endif MAPPER_AddHandler(DecreaseFrameSkip,MK_f7,MMOD1,"decfskip","Dec Fskip"); MAPPER_AddHandler(IncreaseFrameSkip,MK_f8,MMOD1,"incfskip","Inc Fskip"); GFX_SetTitle(-1,render.frameskip.max,false); diff --git a/src/gui/render_loops.h b/src/gui/render_loops.h new file mode 100644 index 00000000..291b7cb2 --- /dev/null +++ b/src/gui/render_loops.h @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2002-2005 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. + */ + +#if defined (SCALERLINEAR) +void conc3d(SCALERNAME,SBPP,L)(void) { +#else +void conc3d(SCALERNAME,SBPP,R)(void) { +#endif + if (!render.scale.outLine) { + render.scale.outLine++; + return; + } +lastagain: + if (!CC[render.scale.outLine][0]) { +#if defined(SCALERLINEAR) + Bitu scaleLines = SCALERHEIGHT; +#else + Bitu scaleLines = SCALERHEIGHT + Scaler_Aspect[ render.scale.outLine ]; +#endif + render.scale.outWrite += render.scale.outPitch * scaleLines; + if (!(Scaler_ChangedLineIndex & 1)) { + Scaler_ChangedLines[Scaler_ChangedLineIndex] += scaleLines; + } else { + Scaler_ChangedLines[++Scaler_ChangedLineIndex] = scaleLines; + } + if (++render.scale.outLine == render.scale.inHeight) + goto lastagain; + return; + } + /* Clear the complete line marker */ + CC[render.scale.outLine][0] = 0; + const PTYPE * fc = &FC[render.scale.outLine][1]; + PTYPE * line0=(PTYPE *)(render.scale.outWrite); + Bit8u * changed = &CC[render.scale.outLine][1]; + Bitu b; + for (b=0;b 1) + PTYPE * line1; +#endif +#if (SCALERHEIGHT > 2) + PTYPE * line2; +#endif + +#if defined ( SCALERSIMPLE ) + if (!changed[b]) { + line0 += SCALERWIDTH * SCALER_BLOCKSIZE; + fc += SCALER_BLOCKSIZE; + continue; + } +#else + switch (changed[b]) { + case 0: + line0 += SCALERWIDTH * SCALER_BLOCKSIZE; + fc += SCALER_BLOCKSIZE; + continue; + case SCALE_LEFT: +#if (SCALERHEIGHT > 1) + line1 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch); +#endif +#if (SCALERHEIGHT > 2) + line2 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch * 2); +#endif + SCALERFUNC; + line0 += SCALERWIDTH * SCALER_BLOCKSIZE; + fc += SCALER_BLOCKSIZE; + break; + case SCALE_LEFT | SCALE_RIGHT: +#if (SCALERHEIGHT > 1) + line1 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch); +#endif +#if (SCALERHEIGHT > 2) + line2 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch * 2); +#endif + SCALERFUNC; + case SCALE_RIGHT: +#if (SCALERHEIGHT > 1) + line1 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch); +#endif +#if (SCALERHEIGHT > 2) + line2 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch * 2); +#endif + line0 += SCALERWIDTH * (SCALER_BLOCKSIZE -1); +#if (SCALERHEIGHT > 1) + line1 += SCALERWIDTH * (SCALER_BLOCKSIZE -1); +#endif +#if (SCALERHEIGHT > 2) + line2 += SCALERWIDTH * (SCALER_BLOCKSIZE -1); +#endif + fc += SCALER_BLOCKSIZE -1; + SCALERFUNC; + line0 += SCALERWIDTH; + fc++; + break; + default: +#endif //SCALERSIMPLE + +#if defined(SCALERLINEAR) +#if (SCALERHEIGHT > 1) + line1 = WC[0]; +#endif +#if (SCALERHEIGHT > 2) + line2 = WC[1]; +#endif +#else +#if (SCALERHEIGHT > 1) + line1 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch); +#endif +#if (SCALERHEIGHT > 2) + line2 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch * 2); +#endif +#endif //defined(SCALERLINEAR) + for (Bitu i = 0; i 1) + line1 += SCALERWIDTH; +#endif +#if (SCALERHEIGHT > 2) + line2 += SCALERWIDTH; +#endif + fc++; + } +#if defined(SCALERLINEAR) +#if (SCALERHEIGHT > 1) + BituMove((Bit8u*)(&line0[-SCALER_BLOCKSIZE*SCALERWIDTH])+render.scale.outPitch ,WC[0], SCALER_BLOCKSIZE *SCALERWIDTH*PSIZE); +#endif +#if (SCALERHEIGHT > 2) + BituMove((Bit8u*)(&line0[-SCALER_BLOCKSIZE*SCALERWIDTH])+render.scale.outPitch*2,WC[1], SCALER_BLOCKSIZE *SCALERWIDTH*PSIZE); +#endif +#endif //defined(SCALERLINEAR) +#if !defined (SCALERSIMPLE) + break; + } +#endif + /* Clear this block being dirty marker */ + changed[b] = 0; + } +#if defined(SCALERLINEAR) + Bitu scaleLines = SCALERHEIGHT; + render.scale.outWrite += render.scale.outPitch * scaleLines; +#else + Bitu scaleLines = SCALERHEIGHT; + if ( Scaler_Aspect[ render.scale.outLine ] ) { + scaleLines++; + BituMove( render.scale.outWrite + render.scale.outPitch * SCALERHEIGHT, + render.scale.outWrite + render.scale.outPitch * (SCALERHEIGHT-1), + render.src.width * SCALERWIDTH * PSIZE); + render.scale.outWrite += render.scale.outPitch * (SCALERHEIGHT + 1); + } else { + render.scale.outWrite += render.scale.outPitch * SCALERHEIGHT; + } +#endif + /* Keep track of changed lines */ + if (Scaler_ChangedLineIndex & 1) { + Scaler_ChangedLines[Scaler_ChangedLineIndex] += scaleLines; + } else { + Scaler_ChangedLines[++Scaler_ChangedLineIndex] = scaleLines; + } + if (++render.scale.outLine == render.scale.inHeight) + goto lastagain; +} + +#if !defined(SCALERLINEAR) +#define SCALERLINEAR 1 +#include "render_loops.h" +#undef SCALERLINEAR +#endif diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index 6a723b54..c67c7a39 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -16,30 +16,28 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +//TODO: +//Maybe just do the cache checking back into the simple scalers so they can +//just handle it all in one go, but this seems to work well enough for now + #include "dosbox.h" -#include "render_scalers.h" +#include "render.h" +#include -Bitu Scaler_Line; -Bitu Scaler_SrcWidth; -Bitu Scaler_SrcHeight; -Bitu Scaler_DstPitch; -Bit8u * Scaler_DstWrite; -Bit8u * Scaler_Index; -Bit8u Scaler_Data[SCALER_MAXHEIGHT*5]; //5cmds/line -PaletteLut Scaler_PaletteLut; +Bit8u Scaler_Aspect[SCALER_MAXHEIGHT]; +Bit16u Scaler_ChangedLines[SCALER_MAXHEIGHT]; +Bitu Scaler_ChangedLineIndex; -static union { - Bit32u b32 [4][SCALER_MAXWIDTH]; - Bit16u b16 [4][SCALER_MAXWIDTH]; - Bit8u b8 [4][SCALER_MAXWIDTH]; -} line_cache; -static union { +union { Bit32u b32 [4][SCALER_MAXWIDTH*3]; Bit16u b16 [4][SCALER_MAXWIDTH*3]; Bit8u b8 [4][SCALER_MAXWIDTH*3]; -} write_cache; +} scalerWriteCache; +scalerFrameCache_t scalerFrameCache; +scalerSourceCache_t scalerSourceCache; -static Bit8u * ln[3]; +Bit8u scalerChangeCache [SCALER_MAXHEIGHT][SCALER_MAXWIDTH / SCALER_BLOCKSIZE]; #define _conc2(A,B) A ## B #define _conc3(A,B,C) A ## B ## C @@ -52,7 +50,15 @@ static Bit8u * ln[3]; #define conc2d(A,B) _conc3(A,_,B) #define conc3d(A,B,C) _conc5(A,_,B,_,C) -#define BituMove(_DST,_SRC,_SIZE) \ +static INLINE void BituMove( void *_dst, const void * _src, Bitu size) { + Bitu * dst=(Bitu *)(_dst); + const Bitu * src=(Bitu *)(_src); + size/=sizeof(Bitu); + for (Bitu x=0; x -#define SCALER_MAXWIDTH 1280 -#define SCALER_MAXHEIGHT 1024 +#define SCALER_MAXWIDTH 1024 +#define SCALER_MAXHEIGHT 768 +#define SCALER_BLOCKSIZE 16 -extern Bitu Scaler_Line; -extern Bitu Scaler_SrcWidth; -extern Bitu Scaler_SrcHeight; -extern Bitu Scaler_DstPitch; -extern Bit8u * Scaler_DstWrite; -extern Bit8u Scaler_Data[]; -extern Bit8u * Scaler_Index; +typedef enum { + scalerMode8, scalerMode15, scalerMode16, scalerMode32 +} scalerMode_t; -union PaletteLut { - Bit16u b16[256]; - Bit32u b32[256]; -}; +typedef enum { + scalerOpNormal, + scalerOpAdvMame, + scalerOpAdvInterp, + scalerOpTV, + scalerOpRGB, + scalerOpScan, +} scalerOperation_t; -extern PaletteLut Scaler_PaletteLut; +typedef void (*ScalerCacheHandler_t)(const void *src); +typedef void (*ScalerLineHandler_t)(void); -enum RENDER_Operation { - OP_Normal, - OP_Normal2x, - OP_AdvMame2x, - OP_AdvMame3x, - OP_AdvInterp2x, - OP_Interp2x, - OP_TV2x, -}; +extern Bit8u Scaler_Aspect[]; +extern Bit8u diff_table[]; +extern Bitu Scaler_ChangedLineIndex; +extern Bit16u Scaler_ChangedLines[]; +extern Bit8u scalerChangeCache [SCALER_MAXHEIGHT][SCALER_MAXWIDTH / SCALER_BLOCKSIZE]; +typedef union { + Bit32u b32 [(SCALER_MAXHEIGHT+2)] [(SCALER_MAXWIDTH+2)]; + Bit16u b16 [(SCALER_MAXHEIGHT+2)] [(SCALER_MAXWIDTH+2)]; + Bit8u b8 [(SCALER_MAXHEIGHT+2)] [(SCALER_MAXWIDTH+2)]; +} scalerFrameCache_t; +typedef union { + Bit32u b32 [SCALER_MAXHEIGHT] [SCALER_MAXWIDTH]; + Bit16u b16 [SCALER_MAXHEIGHT] [SCALER_MAXWIDTH]; + Bit8u b8 [SCALER_MAXHEIGHT] [SCALER_MAXWIDTH]; +} scalerSourceCache_t; -struct ScalerBlock { - Bitu flags; - Bitu xscale,yscale,miny; - RENDER_Line_Handler handlers[4]; -}; +extern scalerFrameCache_t scalerFrameCache; +extern scalerSourceCache_t scalerSourceCache; -extern ScalerBlock Normal_8; -extern ScalerBlock NormalDbl_8; -extern ScalerBlock Normal2x_8; -extern ScalerBlock AdvMame2x_8; -extern ScalerBlock AdvMame3x_8; -extern ScalerBlock AdvInterp2x_8; -extern ScalerBlock Interp2x_8; -extern ScalerBlock TV2x_8; +#define ScaleFlagSimple 0x001 +typedef struct { + Bitu gfxFlags; + Bitu scaleFlags; + Bitu xscale,yscale; + ScalerLineHandler_t Linear[4]; + ScalerLineHandler_t Random[4]; +} ScalerLineBlock_t; + +typedef struct { + Bitu gfxFlags; + Bitu scaleFlags; + Bitu xscale,yscale; + ScalerLineHandler_t Linear[4][4]; + ScalerLineHandler_t Random[4][4]; +} ScalerFullLineBlock_t; + + +typedef struct { + ScalerCacheHandler_t simple[4]; + ScalerCacheHandler_t complex[4]; +} ScalerCacheBlock_t; + +extern ScalerLineBlock_t ScaleNormal; +extern ScalerLineBlock_t ScaleNormalDw; +extern ScalerLineBlock_t ScaleNormalDh; + +#define SCALE_LEFT 0x1 +#define SCALE_RIGHT 0x2 +#define SCALE_FULL 0x4 + +extern ScalerLineBlock_t ScaleNormal2x; +extern ScalerLineBlock_t ScaleNormal3x; +extern ScalerLineBlock_t ScaleAdvMame2x; +extern ScalerLineBlock_t ScaleAdvMame3x; +extern ScalerLineBlock_t ScaleAdvInterp2x; + +extern ScalerLineBlock_t ScaleTV2x; +extern ScalerLineBlock_t ScaleTV3x; +extern ScalerLineBlock_t ScaleRGB2x; +extern ScalerLineBlock_t ScaleRGB3x; +extern ScalerLineBlock_t ScaleScan2x; +extern ScalerLineBlock_t ScaleScan3x; + +extern ScalerCacheBlock_t ScalerCache_8; +extern ScalerCacheBlock_t ScalerCache_8Pal; +extern ScalerCacheBlock_t ScalerCache_15; +extern ScalerCacheBlock_t ScalerCache_16; +extern ScalerCacheBlock_t ScalerCache_32; #endif diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index 9a129328..18c11083 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -19,294 +19,502 @@ #if DBPP == 8 #define PSIZE 1 #define PTYPE Bit8u -#define WC write_cache.b8 -#define LC line_cache.b8 -#define redblueMask 0 -#define greenMask 0 +#define WC scalerWriteCache.b8 +#define FC scalerFrameCache.b8 +#define redMask 0 +#define greenMask 0 +#define blueMask 0 #elif DBPP == 15 || DBPP == 16 #define PSIZE 2 #define PTYPE Bit16u -#define WC write_cache.b16 -#define LC line_cache.b16 +#define WC scalerWriteCache.b16 +#define FC scalerFrameCache.b16 #if DBPP == 15 -#define redblueMask 0x7C1F -#define greenMask 0x03E0 +#define redMask 0x7C00 +#define greenMask 0x03E0 +#define blueMask 0x001F #elif DBPP == 16 -#define redblueMask 0xF81F -#define greenMask 0x07E0 +#define redMask 0xF800 +#define greenMask 0x07E0 +#define blueMask 0x001F #endif #elif DBPP == 32 #define PSIZE 4 #define PTYPE Bit32u -#define WC write_cache.b32 -#define LC line_cache.b32 -#define redblueMask 0xff00ff -#define greenMask 0xff00 +#define WC scalerWriteCache.b32 +#define FC scalerFrameCache.b32 +#define redMask 0xff0000 +#define greenMask 0x00ff00 +#define blueMask 0x0000ff #endif +#define redblueMask (redMask | blueMask) + + #if SBPP == 8 +#define SC scalerSourceCache.b8 #if DBPP == 8 -#define PMAKE(_VAL) _VAL +#define PMAKE(_VAL) (_VAL) #elif DBPP == 15 -#define PMAKE(_VAL) Scaler_PaletteLut.b16[_VAL] +#define PMAKE(_VAL) render.pal.lut.b16[_VAL] #elif DBPP == 16 -#define PMAKE(_VAL) Scaler_PaletteLut.b16[_VAL] +#define PMAKE(_VAL) render.pal.lut.b16[_VAL] #elif DBPP == 32 -#define PMAKE(_VAL) Scaler_PaletteLut.b32[_VAL] +#define PMAKE(_VAL) render.pal.lut.b32[_VAL] #endif +#define SRCTYPE Bit8u #endif -#define C0 LC[0][x-1] -#define C1 LC[0][x+0] -#define C2 LC[0][x+1] -#define C3 LC[1][x-1] -#define C4 LC[1][x+0] -#define C5 LC[1][x+1] -#define C6 LC[2][x-1] -#define C7 LC[2][x+0] -#define C8 LC[2][x+1] +#if SBPP == 15 +#define SC scalerSourceCache.b16 +#if DBPP == 15 +#define PMAKE(_VAL) (_VAL) +#elif DBPP == 16 +#define PMAKE(_VAL) (((_VAL) & 31) | ((_VAL) & ~31) << 1) +#elif DBPP == 32 +#define PMAKE(_VAL) (((_VAL&(31<<10))<<9)|((_VAL&(31<<5))<<6)|((_VAL&31)<<3)) +#endif +#define SRCTYPE Bit16u +#endif -static void conc3d(Normal,SBPP,DBPP) (const Bit8u * src) { - const Bit8u * line; -#if SBPP == DBPP - line=src; - BituMove(Scaler_DstWrite,line,Scaler_SrcWidth*PSIZE); +#if SBPP == 16 +#define SC scalerSourceCache.b16 +#if DBPP == 15 +#define PMAKE(_VAL) (((_VAL&~31)>>1)|(_VAL&31)) +#elif DBPP == 16 +#define PMAKE(_VAL) (_VAL) +#elif DBPP == 32 +#define PMAKE(_VAL) (((_VAL&(31<<11))<<8)|((_VAL&(63<<5))<<5)|((_VAL&31)<<3)) +#endif +#define SRCTYPE Bit16u +#endif + +#if SBPP == 32 +#define SC scalerSourceCache.b32 +#if DBPP == 15 +#define PMAKE(_VAL) (PTYPE)(((_VAL&(31<<19))>>9)|((_VAL&(31<<11))>>6)|((_VAL&(31<<3))>>3)) +#elif DBPP == 16 +#define PMAKE(_VAL) (PTYPE)(((_VAL&(31<<19))>>8)|((_VAL&(63<<10))>>4)|((_VAL&(31<<3))>>3)) +#elif DBPP == 32 +#define PMAKE(_VAL) (_VAL) +#endif +#define SRCTYPE Bit32u +#endif + +#define C0 fc[-1 - SCALER_MAXWIDTH -2] +#define C1 fc[+0 - SCALER_MAXWIDTH -2] +#define C2 fc[+1 - SCALER_MAXWIDTH -2] +#define C3 fc[-1 ] +#define C4 fc[+0 ] +#define C5 fc[+1 ] +#define C6 fc[-1 + SCALER_MAXWIDTH +2] +#define C7 fc[+0 + SCALER_MAXWIDTH +2] +#define C8 fc[+1 + SCALER_MAXWIDTH +2] + +#if defined (CACHEWITHPAL) +static void conc3d(CacheComplexPal,SBPP,DBPP) (const void * s) { #else - PTYPE * dst=(PTYPE *)Scaler_DstWrite; - line=line_cache.b8[0]; - for (Bitu x=0;x 8) -static void conc3d(TV2x,SBPP,DBPP) (const Bit8u * src) { - PTYPE * dst=(PTYPE *)Scaler_DstWrite; - for (Bitu x=0;x> 3) & redblueMask; - halfpixel|=(((pixel & greenMask) * 7) >> 3) & greenMask; - dst[x*2+0]=dst[x*2+1]=halfpixel; - LC[0][x*2+0]=LC[0][x*2+1]=pixel; - } - Scaler_DstWrite+=Scaler_DstPitch; - for (Bitu lines=*Scaler_Index++;lines;lines--) { - BituMove(Scaler_DstWrite,LC[0],Scaler_SrcWidth*2*PSIZE); - Scaler_DstWrite+=Scaler_DstPitch; - } -} -static void conc3d(Interp2x,SBPP,DBPP) (const Bit8u * src) { - if (!Scaler_Line) { - Scaler_Line++; - for (Bitu tempx=Scaler_SrcWidth;tempx>0;tempx--) { - LC[1][tempx] = LC[2][tempx] = PMAKE(src[tempx]); - } - return; - } -lastagain: - Bitu x=0; - PTYPE * dst=(PTYPE *)Scaler_DstWrite; - C1=C4;C4=C7;C7=PMAKE(src[x]); - C2=C5;C5=C8;C8=PMAKE(src[x+1]); - dst[0] = interp_w2(C4,C1,3,1); - dst[1] = interp_w4(C4,C1,C2,C5,5,1,1,1); - WC[1][0] = interp_w2(C4,C7,3,1); - WC[1][1] = interp_w4(C4,C5,C8,C7,5,1,1,1); - for (x=1;x> 3) & redblueMask; \ + halfpixel|=(((C4 & greenMask) * 5) >> 3) & greenMask; \ + line0[0]=C4; \ + line0[1]=C4; \ + line1[0]=halfpixel; \ + line1[1]=halfpixel; \ } +#include "render_loops.h" +#undef SCALERNAME +#undef SCALERWIDTH +#undef SCALERHEIGHT +#undef SCALERFUNC +#undef SCALERSIMPLE -static void conc3d(AdvInterp2x,SBPP,DBPP) (const Bit8u * src) { - if (!Scaler_Line) { - Scaler_Line++; - for (Bitu tempx=Scaler_SrcWidth;tempx>0;tempx--) { - LC[1][tempx]=LC[2][tempx]=PMAKE(src[tempx]); - } - return; - } -lastagain: - Bitu x=0; - PTYPE * dst=(PTYPE *)Scaler_DstWrite; - C1=C4;C4=C7;C7=PMAKE(src[x]); - C2=C5;C5=C8;C8=PMAKE(src[x+1]); - dst[0]=C4; - WC[1][0]=C4; - dst[1] = C5 == C1 && C7 != C1 ? C2 : C4; - WC[1][1]= C5 == C7 && C1 != C7 ? C7 : C4; - for (x=1;x0;lines--) { - BituMove(Scaler_DstWrite,&WC[1],2*Scaler_SrcWidth*PSIZE); - Scaler_DstWrite+=Scaler_DstPitch; - } - if (++Scaler_Line==Scaler_SrcHeight) goto lastagain; + +#define SCALERSIMPLE 1 +#define SCALERNAME TV3x +#define SCALERWIDTH 3 +#define SCALERHEIGHT 3 +#define SCALERFUNC \ +{ \ + Bitu halfpixel=(((C4 & redblueMask) * 5) >> 3) & redblueMask; \ + halfpixel|=(((C4 & greenMask) * 5) >> 3) & greenMask; \ + line0[0]=C4; \ + line0[1]=C4; \ + line0[2]=C4; \ + line1[0]=halfpixel; \ + line1[1]=halfpixel; \ + line1[2]=halfpixel; \ + halfpixel=(((C4 & redblueMask) * 5) >> 4) & redblueMask; \ + halfpixel|=(((C4 & greenMask) * 5) >> 4) & greenMask; \ + line2[0]=halfpixel; \ + line2[1]=halfpixel; \ + line2[2]=halfpixel; \ } +#include "render_loops.h" +#undef SCALERNAME +#undef SCALERWIDTH +#undef SCALERHEIGHT +#undef SCALERFUNC +#undef SCALERSIMPLE + +#define SCALERSIMPLE 1 +#define SCALERNAME RGB2x +#define SCALERWIDTH 2 +#define SCALERHEIGHT 2 +#define SCALERFUNC \ + line0[0]=C4 & redMask; \ + line0[1]=C4 & greenMask; \ + line1[0]=C4 & blueMask; \ + line1[1]=C4; +#include "render_loops.h" +#undef SCALERNAME +#undef SCALERWIDTH +#undef SCALERHEIGHT +#undef SCALERFUNC +#undef SCALERSIMPLE + + +#define SCALERSIMPLE 1 +#define SCALERNAME RGB3x +#define SCALERWIDTH 3 +#define SCALERHEIGHT 3 +#define SCALERFUNC \ + line0[0]=C4; \ + line0[1]=C4 & greenMask; \ + line0[2]=C4 & blueMask; \ + line1[0]=C4 & blueMask; \ + line1[1]=C4; \ + line1[2]=C4 & redMask; \ + line2[0]=C4 & redMask; \ + line2[1]=C4 & greenMask; \ + line2[2]=C4; +#include "render_loops.h" +#undef SCALERNAME +#undef SCALERWIDTH +#undef SCALERHEIGHT +#undef SCALERFUNC +#undef SCALERSIMPLE + + +#define SCALERSIMPLE 1 +#define SCALERNAME Scan2x +#define SCALERWIDTH 2 +#define SCALERHEIGHT 2 +#define SCALERFUNC \ + line0[0]=C4; \ + line0[1]=C4; \ + line1[0]=0; \ + line1[1]=0; +#include "render_loops.h" +#undef SCALERNAME +#undef SCALERWIDTH +#undef SCALERHEIGHT +#undef SCALERFUNC +#undef SCALERSIMPLE + + +#define SCALERSIMPLE 1 +#define SCALERNAME Scan3x +#define SCALERWIDTH 3 +#define SCALERHEIGHT 3 +#define SCALERFUNC \ + line0[0]=C4; \ + line0[1]=C4; \ + line0[2]=C4; \ + line1[0]=0; \ + line1[1]=0; \ + line1[2]=0; \ + line2[0]=0; \ + line2[1]=0; \ + line2[2]=0; +#include "render_loops.h" +#undef SCALERNAME +#undef SCALERWIDTH +#undef SCALERHEIGHT +#undef SCALERFUNC +#undef SCALERSIMPLE + + + +#define SCALERNAME AdvInterp2x +#define SCALERWIDTH 2 +#define SCALERHEIGHT 2 +#define SCALERFUNC \ + if (C1 != C7 && C3 != C5) { \ + line0[0] = C3 == C1 ? interp_w2(C3,C4,5,3) : C4; \ + line0[1] = C1 == C5 ? interp_w2(C5,C4,5,3) : C4; \ + line1[0] = C3 == C7 ? interp_w2(C3,C4,5,3) : C4; \ + line1[1] = C7 == C5 ? interp_w2(C5,C4,5,3) : C4; \ + } else { \ + line0[0] = line0[1] = C4; \ + line1[0] = line1[1] = C4; \ + } +#include "render_loops.h" +#undef SCALERNAME +#undef SCALERWIDTH +#undef SCALERHEIGHT +#undef SCALERFUNC + +#define SCALERNAME AdvInterp3x +#define SCALERWIDTH 3 +#define SCALERHEIGHT 3 +#define SCALERFUNC \ + if (C1 != C7 && C3 != C5) { \ + line0[0] = C3 == C1 ? interp_w2(C3,C4,5,3) : C4; \ + line0[1] = C1 == C5 ? interp_w2(C5,C4,5,3) : C4; \ + line1[0] = C3 == C7 ? interp_w2(C3,C4,5,3) : C4; \ + line1[1] = C7 == C5 ? interp_w2(C5,C4,5,3) : C4; \ + } else { \ + line0[0] = line0[1] = C4; \ + line1[0] = line1[1] = C4; \ + } +#include "render_loops.h" +#undef SCALERNAME +#undef SCALERWIDTH +#undef SCALERHEIGHT +#undef SCALERFUNC #endif //DBPP > 8 -static void conc3d(AdvMame2x,SBPP,DBPP) (const Bit8u * src) { - if (!Scaler_Line) { - Scaler_Line++; - for (Bitu tempx=Scaler_SrcWidth;tempx>0;tempx--) { - LC[1][tempx]=LC[2][tempx]=PMAKE(src[tempx]); - } - return; +#define SCALERNAME AdvMame2x +#define SCALERWIDTH 2 +#define SCALERHEIGHT 2 +#define SCALERFUNC \ + if (C1 != C7 && C3 != C5) { \ + line0[0] = C3 == C1 ? C3 : C4; \ + line0[1] = C1 == C5 ? C5 : C4; \ + line1[0] = C3 == C7 ? C3 : C4; \ + line1[1] = C7 == C5 ? C5 : C4; \ + } else { \ + line0[0] = line0[1] = C4; \ + line1[0] = line1[1] = C4; \ } -lastagain: - Bitu x=0; - PTYPE * dst=(PTYPE *)Scaler_DstWrite; - C1=C4;C4=C7;C7=PMAKE(src[x]); - C2=C5;C5=C8;C8=PMAKE(src[x+1]); - dst[0]=C4; - WC[1][0]=C4; - dst[1] = C5 == C1 && C7 != C1 ? C2 : C4; - WC[1][1]= C5 == C7 && C1 != C7 ? C7 : C4; - for (x=1;x0;lines--) { - BituMove(Scaler_DstWrite,&WC[1],2*Scaler_SrcWidth*PSIZE); - Scaler_DstWrite+=Scaler_DstPitch; - } - if (++Scaler_Line==Scaler_SrcHeight) goto lastagain; -} +#include "render_loops.h" +#undef SCALERNAME +#undef SCALERWIDTH +#undef SCALERHEIGHT +#undef SCALERFUNC -static void conc3d(AdvMame3x,SBPP,DBPP) (const Bit8u * src) { - if (!Scaler_Line) { - Scaler_Line++; - for (Bitu tempx=Scaler_SrcWidth;tempx>0;tempx--) { - LC[1][tempx]=LC[2][tempx]=PMAKE(src[tempx]); - } - return; +#define SCALERNAME AdvMame3x +#define SCALERWIDTH 3 +#define SCALERHEIGHT 3 +#define SCALERFUNC \ + if ((C1 != C7) && (C3 != C5)) { \ + line0[0] = C3 == C1 ? C3 : C4; \ + line0[1] = (C3 == C1 && C4 != C2) || (C5 == C1 && C4 != C0) ? C1 : C4; \ + line0[2] = C5 == C1 ? C5 : C4; \ + line1[0] = (C3 == C1 && C4 != C6) || (C3 == C7 && C4 != C0) ? C3 : C4; \ + line1[1] = C4; \ + line1[2] = (C5 == C1 && C4 != C8) || (C5 == C7 && C4 != C2) ? C5 : C4; \ + line2[0] = C3 == C7 ? C3 : C4; \ + line2[1] = (C3 == C7 && C4 != C8) || (C5 == C7 && C4 != C6) ? C7 : C4; \ + line2[2] = C5 == C7 ? C5 : C4; \ + } else { \ + line0[0] = line0[1] = line0[2] = C4; \ + line1[0] = line1[1] = line1[2] = C4; \ + line2[0] = line2[1] = line2[2] = C4; \ } -lastagain: - PTYPE * dst=(PTYPE *)Scaler_DstWrite; - LC[0][0]=LC[1][0];LC[1][0]=LC[2][0];LC[2][0]=PMAKE(src[0]); - LC[0][1]=LC[1][1];LC[1][1]=LC[2][1];LC[2][1]=PMAKE(src[1]); - /* first pixel */ - dst[0] = LC[1][0]; - dst[1] = LC[1][0]; - dst[2] = (LC[1][1] == LC[0][0] && LC[2][0] != LC[0][0]) ? LC[0][0] : LC[1][0]; - WC[1][0] = LC[1][0]; - WC[1][1] = LC[1][0]; - WC[1][2] = (LC[0][0] != LC[2][0]) ? (((LC[1][1] == LC[0][0] && LC[1][0] != LC[2][1]) || (LC[1][1] == LC[2][0] && LC[1][0] != LC[0][1])) ? LC[1][1] : LC[1][0]) : LC[1][0]; - WC[2][0] = LC[1][0]; - WC[2][1] = LC[1][0]; - WC[2][2] = (LC[1][1] == LC[2][0] && LC[0][0] != LC[2][0]) ? LC[2][0] : LC[1][0]; - Bitu x; - for (x=1;x0;lines--) { - BituMove(Scaler_DstWrite,&WC[2],3*Scaler_SrcWidth*PSIZE); - Scaler_DstWrite+=Scaler_DstPitch; - } - if (++Scaler_Line==Scaler_SrcHeight) goto lastagain; -} + +#include "render_loops.h" +#undef SCALERNAME +#undef SCALERWIDTH +#undef SCALERHEIGHT +#undef SCALERFUNC + + +#endif // (SBPP == DBPP) && !defined (CACHEWITHPAL) #undef PSIZE #undef PTYPE #undef PMAKE #undef WC #undef LC +#undef FC +#undef SC +#undef redMask #undef greenMask +#undef blueMask #undef redblueMask +#undef SRCTYPE - +#if (SBPP == 8) && (DBPP > 8) && !defined (CACHEWITHPAL) +#define CACHEWITHPAL 1 +#include "render_templates.h" +#undef CACHEWITHPAL +#endif diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 8b7790e0..e37efa6d 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.95 2006-01-22 14:13:00 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.96 2006-01-30 09:58:07 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -144,20 +144,25 @@ struct SDL_Block { struct { Bit32u width; Bit32u height; + Bit32u bpp; Bitu flags; - GFX_Modes mode; double scalex,scaley; GFX_ResetCallBack reset; } draw; bool wait_on_error; struct { - Bit32u width,height,bpp; - bool fixed; + struct { + Bit16u width, height; + bool fixed; + } full; + struct { + Bit16u width, height; + } window; + Bit8u bpp; bool fullscreen; bool doublebuf; SCREEN_TYPES type; SCREEN_TYPES want_type; - double hwscale; } desktop; #if C_OPENGL struct { @@ -196,6 +201,7 @@ struct SDL_Block { bool locked; Bitu sensitivity; } mouse; + SDL_Rect updateRects[1024]; }; static SDL_Block sdl; @@ -249,47 +255,51 @@ Bitu GFX_GetBestMode(Bitu flags) { case SCREEN_SURFACE: check_surface: /* Check if we can satisfy the depth it loves */ - if (flags & LOVE_8) testbpp=8; - else if (flags & LOVE_16) testbpp=16; - else if (flags & LOVE_32) testbpp=32; + if (flags & GFX_LOVE_8) testbpp=8; + else if (flags & GFX_LOVE_15) testbpp=15; + else if (flags & GFX_LOVE_16) testbpp=16; + else if (flags & GFX_LOVE_32) testbpp=32; check_gotbpp: if (sdl.desktop.fullscreen) gotbpp=SDL_VideoModeOK(640,480,testbpp,SDL_FULLSCREEN|SDL_HWSURFACE|SDL_HWPALETTE); else gotbpp=sdl.desktop.bpp; /* If we can't get our favorite mode check for another working one */ switch (gotbpp) { case 8: - if (flags & CAN_8) flags&=~(CAN_16|CAN_32); + if (flags & GFX_CAN_8) flags&=~(GFX_CAN_15|GFX_CAN_16|GFX_CAN_32); break; case 15: + if (flags & GFX_CAN_15) flags&=~(GFX_CAN_8|GFX_CAN_16|GFX_CAN_32); + break; case 16: - if (flags & CAN_16) flags&=~(CAN_8|CAN_32); + if (flags & GFX_CAN_16) flags&=~(GFX_CAN_8|GFX_CAN_15|GFX_CAN_32); break; case 24: case 32: - if (flags & CAN_32) flags&=~(CAN_8|CAN_16); + if (flags & GFX_CAN_32) flags&=~(GFX_CAN_8|GFX_CAN_15|GFX_CAN_16); break; } - /* Not a valid display depth found? Let's just hope sdl provides conversions */ + flags |= GFX_CAN_RANDOM; break; #if (HAVE_DDRAW_H) && defined(WIN32) case SCREEN_SURFACE_DDRAW: - if (!(flags&(CAN_32|CAN_16))) goto check_surface; - if (flags & LOVE_16) testbpp=16; - else if (flags & LOVE_32) testbpp=32; + if (!(flags&(GFX_CAN_15|GFX_CAN_16|GFX_CAN_32))) goto check_surface; + if (flags & GFX_LOVE_15) testbpp=15; + else if (flags & GFX_LOVE_16) testbpp=16; + else if (flags & GFX_LOVE_32) testbpp=32; else testbpp=0; - flags|=HAVE_SCALING; + flags|=GFX_SCALING; goto check_gotbpp; #endif case SCREEN_OVERLAY: - if (flags & NEED_RGB || !(flags&CAN_32)) goto check_surface; - flags|=HAVE_SCALING; - flags&=~(CAN_8|CAN_16); + if (flags & GFX_RGBONLY || !(flags&GFX_CAN_32)) goto check_surface; + flags|=GFX_SCALING; + flags&=~(GFX_CAN_8|GFX_CAN_15|GFX_CAN_16); break; #if C_OPENGL case SCREEN_OPENGL: - if (flags & NEED_RGB || !(flags&CAN_32)) goto check_surface; - flags|=HAVE_SCALING; - flags&=~(CAN_8|CAN_16); + if (flags & GFX_RGBONLY || !(flags&GFX_CAN_32)) goto check_surface; + flags|=GFX_SCALING; + flags&=~(GFX_CAN_8|GFX_CAN_15|GFX_CAN_16); break; #endif } @@ -299,7 +309,7 @@ check_gotbpp: void GFX_ResetScreen(void) { GFX_Stop(); - if (sdl.draw.reset) (sdl.draw.reset)(); + if (sdl.draw.reset) (sdl.draw.reset)( false ); GFX_Start(); } @@ -311,86 +321,91 @@ static int int_log2 (int val) { } -static SDL_Surface * GFX_SetupSurfaceScaled(Bit32u sdl_flags,Bit32u bpp) { +static SDL_Surface * GFX_SetupSurfaceScaled(Bit32u sdl_flags, Bit32u bpp) { + Bit16u fixedWidth; + Bit16u fixedHeight; + if (sdl.desktop.fullscreen) { - if (sdl.desktop.fixed) { - double ratio_w=(double)sdl.desktop.width/(sdl.draw.width*sdl.draw.scalex); - double ratio_h=(double)sdl.desktop.height/(sdl.draw.height*sdl.draw.scaley); - if ( ratio_w < ratio_h) { - sdl.clip.w=(Bit16u)sdl.desktop.width; - sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley*ratio_w); - } else { - sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex*ratio_h); - sdl.clip.h=(Bit16u)sdl.desktop.height; - } - sdl.clip.x=(Sint16)((sdl.desktop.width-sdl.clip.w)/2); - sdl.clip.y=(Sint16)((sdl.desktop.height-sdl.clip.h)/2); - sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,bpp,sdl_flags|SDL_FULLSCREEN|SDL_HWSURFACE); - if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",sdl.desktop.width,sdl.desktop.height,bpp,SDL_GetError()); - return sdl.surface; + fixedWidth = sdl.desktop.full.fixed ? sdl.desktop.full.width : 0; + fixedHeight = sdl.desktop.full.fixed ? sdl.desktop.full.height : 0; + sdl_flags |= SDL_FULLSCREEN|SDL_HWSURFACE; + } else { + fixedWidth = sdl.desktop.window.width; + fixedHeight = sdl.desktop.window.height; + sdl_flags |= SDL_HWSURFACE; + } + if (fixedWidth && fixedHeight) { + double ratio_w=(double)fixedWidth/(sdl.draw.width*sdl.draw.scalex); + double ratio_h=(double)fixedHeight/(sdl.draw.height*sdl.draw.scaley); + if ( ratio_w < ratio_h) { + sdl.clip.w=fixedWidth; + sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley*ratio_w); } else { - sdl.clip.x=0;sdl.clip.y=0; - sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex); - sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley); - sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags|SDL_FULLSCREEN|SDL_HWSURFACE); - if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",sdl.clip.w,sdl.clip.h,bpp,SDL_GetError()); - return sdl.surface; + sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex*ratio_h); + sdl.clip.h=(Bit16u)fixedHeight; } + if (sdl.desktop.fullscreen) + sdl.surface = SDL_SetVideoMode(fixedWidth,fixedHeight,bpp,sdl_flags); + else + sdl.surface = SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags); + if (sdl.surface && sdl.surface->flags & SDL_FULLSCREEN) { + sdl.clip.x=(Sint16)((sdl.surface->w-sdl.clip.w)/2); + sdl.clip.y=(Sint16)((sdl.surface->h-sdl.clip.h)/2); + } else { + sdl.clip.x = 0; + sdl.clip.y = 0; + } + return sdl.surface; } else { sdl.clip.x=0;sdl.clip.y=0; - sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex*sdl.desktop.hwscale); - sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley*sdl.desktop.hwscale); - sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags|SDL_HWSURFACE); -#ifdef WIN32 - if (sdl.surface == NULL) { - LOG_MSG("Failed to create hardware surface.\nRestarting video subsystem with windib enabled."); - SDL_QuitSubSystem(SDL_INIT_VIDEO); - putenv("SDL_VIDEODRIVER=windib"); - SDL_InitSubSystem(SDL_INIT_VIDEO); - sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags|SDL_HWSURFACE); - } -#endif - if (sdl.surface == NULL) E_Exit("Could not set windowed video mode %ix%i-%i: %s",sdl.clip.w,sdl.clip.h,bpp,SDL_GetError()); + sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex); + sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley); + sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags); return sdl.surface; } } -GFX_Modes GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_ResetCallBack reset) { - if (sdl.updating) GFX_EndUpdate(); +Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_ResetCallBack reset) { + if (sdl.updating) + GFX_EndUpdate( 0 ); + sdl.draw.width=width; sdl.draw.height=height; - sdl.draw.flags=flags; - sdl.draw.mode=GFX_NONE; sdl.draw.reset=reset; sdl.draw.scalex=scalex; sdl.draw.scaley=scaley; Bitu bpp; + Bitu retFlags; switch (sdl.desktop.want_type) { case SCREEN_SURFACE: dosurface: - if (flags & CAN_8) bpp=8; - if (flags & CAN_16) bpp=16; - if (flags & CAN_32) bpp=32; + if (flags & GFX_CAN_8) bpp=8; + if (flags & GFX_CAN_15) bpp=15; + if (flags & GFX_CAN_16) bpp=16; + if (flags & GFX_CAN_32) bpp=32; sdl.desktop.type=SCREEN_SURFACE; sdl.clip.w=width; sdl.clip.h=height; if (sdl.desktop.fullscreen) { - if (sdl.desktop.fixed) { - sdl.clip.x=(Sint16)((sdl.desktop.width-width)/2); - sdl.clip.y=(Sint16)((sdl.desktop.height-height)/2); - sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,bpp, - SDL_FULLSCREEN|SDL_HWSURFACE|(sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0)|SDL_HWPALETTE); - if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",sdl.desktop.width,sdl.desktop.height,bpp,SDL_GetError()); + if (sdl.desktop.full.fixed) { + sdl.clip.x=(Sint16)((sdl.desktop.full.width-width)/2); + sdl.clip.y=(Sint16)((sdl.desktop.full.height-height)/2); + sdl.surface=SDL_SetVideoMode(sdl.desktop.full.width,sdl.desktop.full.height,bpp, + SDL_FULLSCREEN | ((flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE) | + (sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0) | SDL_HWPALETTE); + if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",sdl.desktop.full.width,sdl.desktop.full.height,bpp,SDL_GetError()); } else { sdl.clip.x=0;sdl.clip.y=0; sdl.surface=SDL_SetVideoMode(width,height,bpp, - SDL_FULLSCREEN|SDL_HWSURFACE|(sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0)|SDL_HWPALETTE); - if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",width,height,bpp,SDL_GetError()); + SDL_FULLSCREEN | ((flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE) | + (sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0)|SDL_HWPALETTE); + if (sdl.surface == NULL) + E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",width,height,bpp,SDL_GetError()); } } else { sdl.clip.x=0;sdl.clip.y=0; - sdl.surface = SDL_SetVideoMode(width,height,bpp,SDL_HWSURFACE); + sdl.surface=SDL_SetVideoMode(width,height,bpp,(flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE); #ifdef WIN32 if (sdl.surface == NULL) { LOG_MSG("Failed to create hardware surface.\nRestarting video subsystem with windib enabled."); @@ -400,21 +415,33 @@ dosurface: sdl.surface = SDL_SetVideoMode(width,height,bpp,SDL_HWSURFACE); } #endif - if (sdl.surface == NULL) E_Exit("Could not set windowed video mode %ix%i-%i: %s",width,height,bpp,SDL_GetError()); + if (sdl.surface == NULL) + E_Exit("Could not set windowed video mode %ix%i-%i: %s",width,height,bpp,SDL_GetError()); } - if (sdl.surface) switch (sdl.surface->format->BitsPerPixel) { - case 8:sdl.draw.mode=GFX_8;break; - case 15:sdl.draw.mode=GFX_15;break; - case 16:sdl.draw.mode=GFX_16;break; - case 32:sdl.draw.mode=GFX_32;break; - default: + if (sdl.surface) { + switch (sdl.surface->format->BitsPerPixel) { + case 8: + retFlags = GFX_CAN_8; + break; + case 15: + retFlags = GFX_CAN_15; break; + case 16: + retFlags = GFX_CAN_16; + break; + case 32: + retFlags = GFX_CAN_32; + break; + } + if (retFlags && sdl.surface->flags & SDL_HWSURFACE) + retFlags |= GFX_HARDWARE; } break; #if (HAVE_DDRAW_H) && defined(WIN32) case SCREEN_SURFACE_DDRAW: - if (flags & CAN_16) bpp=16; - if (flags & CAN_32) bpp=32; + if (flags & GFX_CAN_15) bpp=15; + if (flags & GFX_CAN_16) bpp=16; + if (flags & GFX_CAN_32) bpp=32; if (sdl.blit.surface) { SDL_FreeSurface(sdl.blit.surface); sdl.blit.surface=0; @@ -437,11 +464,15 @@ dosurface: goto dosurface; } switch (sdl.surface->format->BitsPerPixel) { - case 15:sdl.draw.mode=GFX_15;break; - case 16:sdl.draw.mode=GFX_16;break; - case 32:sdl.draw.mode=GFX_32;break; - default: - break; + case 15: + retFlags = GFX_CAN_15 | GFX_SCALING | GFX_HARDWARE; + break; + case 16: + retFlags = GFX_CAN_16 | GFX_SCALING | GFX_HARDWARE; + break; + case 32: + retFlags = GFX_CAN_32 | GFX_SCALING | GFX_HARDWARE; + break; } sdl.desktop.type=SCREEN_SURFACE_DDRAW; break; @@ -451,7 +482,7 @@ dosurface: SDL_FreeYUVOverlay(sdl.overlay); sdl.overlay=0; } - if (!(flags&CAN_32) || (flags & NEED_RGB)) goto dosurface; + if (!(flags&GFX_CAN_32) || (flags & GFX_RGBONLY)) goto dosurface; if (!GFX_SetupSurfaceScaled(0,0)) goto dosurface; sdl.overlay=SDL_CreateYUVOverlay(width*2,height,SDL_UYVY_OVERLAY,sdl.surface); if (!sdl.overlay) { @@ -459,7 +490,7 @@ dosurface: goto dosurface; } sdl.desktop.type=SCREEN_OVERLAY; - sdl.draw.mode=GFX_32; + retFlags = GFX_CAN_32 | GFX_SCALING | GFX_HARDWARE; break; #if C_OPENGL case SCREEN_OPENGL: @@ -472,7 +503,7 @@ dosurface: free(sdl.opengl.framebuf); } sdl.opengl.framebuf=0; - if (!(flags&CAN_32) || (flags & NEED_RGB)) goto dosurface; + if (!(flags&GFX_CAN_32) || (flags & GFX_RGBONLY)) goto dosurface; int texsize=2 << int_log2(width > height ? width : height); if (texsize>sdl.opengl.max_texsize) { LOG_MSG("SDL:OPENGL:No support for texturesize of %d, falling back to surface",texsize); @@ -546,13 +577,18 @@ dosurface: glEnd(); glEndList(); sdl.desktop.type=SCREEN_OPENGL; - sdl.draw.mode=GFX_32; - break; + retFlags = GFX_CAN_32 | GFX_SCALING; +#if defined(NVIDIA_PixelDataRange) + if (sdl.opengl.pixel_data_range) + retFlags |= GFX_HARDWARE; +#endif + break; }//OPENGL #endif //C_OPENGL }//CASE - if (sdl.draw.mode!=GFX_NONE) GFX_Start(); - return sdl.draw.mode; + if (retFlags) + GFX_Start(); + return retFlags; } bool mouselocked; //Global variable for mapper @@ -629,7 +665,8 @@ bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) { return false; } -void GFX_EndUpdate(void) { + +void GFX_EndUpdate( const Bit16u *changedLines ) { int ret; if (!sdl.updating) return; sdl.updating=false; @@ -637,8 +674,27 @@ void GFX_EndUpdate(void) { case SCREEN_SURFACE: if (SDL_MUSTLOCK(sdl.surface)) { SDL_UnlockSurface(sdl.surface); + SDL_Flip(sdl.surface); + } else if (changedLines) { + Bitu y = 0, index = 0, rectCount = 0; + while (y < sdl.draw.height) { + if (!(index & 1)) { + y += changedLines[index]; + } else { + SDL_Rect *rect = &sdl.updateRects[rectCount++]; + rect->x = sdl.clip.x; + rect->y = sdl.clip.y + y; + rect->w = (Bit16u)sdl.draw.width; + rect->h = changedLines[index]; + y += changedLines[index]; + } + index++; + } + if (rectCount) + SDL_UpdateRects( sdl.surface, rectCount, sdl.updateRects ); + } else { + SDL_Flip(sdl.surface); } - SDL_Flip(sdl.surface); break; #if (HAVE_DDRAW_H) && defined(WIN32) case SCREEN_SURFACE_DDRAW: @@ -668,12 +724,35 @@ void GFX_EndUpdate(void) { break; #if C_OPENGL case SCREEN_OPENGL: - glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, - sdl.draw.width, sdl.draw.height, GL_BGRA_EXT, - GL_UNSIGNED_INT_8_8_8_8_REV, sdl.opengl.framebuf); - glCallList(sdl.opengl.displaylist); - SDL_GL_SwapBuffers(); +#if defined(NVIDIA_PixelDataRange) + if (sdl.opengl.pixel_data_range) { + glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, + sdl.draw.width, sdl.draw.height, GL_BGRA_EXT, + GL_UNSIGNED_INT_8_8_8_8_REV, sdl.opengl.framebuf); + glCallList(sdl.opengl.displaylist); + SDL_GL_SwapBuffers(); + } else +#endif + if (changedLines) { + Bitu y = 0, index = 0; + glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture); + while (y < sdl.draw.height) { + if (!(index & 1)) { + y += changedLines[index]; + } else { + Bit8u *pixels = (Bit8u *)sdl.opengl.framebuf + y * sdl.opengl.pitch; + Bitu height = changedLines[index]; + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, y, + sdl.draw.width, height, GL_BGRA_EXT, + GL_UNSIGNED_INT_8_8_8_8_REV, pixels ); + y += height; + } + index++; + } + glCallList(sdl.opengl.displaylist); + SDL_GL_SwapBuffers(); + } break; #endif @@ -719,7 +798,8 @@ Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue) { } void GFX_Stop() { - if (sdl.updating) GFX_EndUpdate(); + if (sdl.updating) + GFX_EndUpdate( 0 ); sdl.active=false; } @@ -729,6 +809,7 @@ void GFX_Start() { static void GUI_ShutDown(Section * sec) { GFX_Stop(); + if (sdl.draw.reset) (sdl.draw.reset)( true ); if (sdl.mouse.locked) CaptureMouse(); if (sdl.desktop.fullscreen) SwitchFullScreen(); } @@ -825,44 +906,58 @@ static void GUI_StartUp(Section * sec) { sdl.mouse.locked=false; mouselocked=false; //Global for mapper sdl.mouse.requestlock=false; - sdl.desktop.fixed=section->Get_bool("fullfixed"); + sdl.desktop.full.fixed=section->Get_bool("fullfixed"); const char* fullresolution=section->Get_string("fullresolution"); if(fullresolution && *fullresolution) { - char res[100]= { 0 }; - strcpy(res,fullresolution); + char res[100]; + strncpy( res, fullresolution, sizeof( res )); fullresolution = lowcase (res);//so x and X are allowed char* height = const_cast(strchr(fullresolution,'x')); if(height && * height) { *height = 0; - sdl.desktop.height = atoi(height+1); - sdl.desktop.width = atoi(res); + sdl.desktop.full.height = atoi(height+1); + sdl.desktop.full.width = atoi(res); } else { - sdl.desktop.width = 0; - sdl.desktop.height = 0; + sdl.desktop.full.width = 0; + sdl.desktop.full.height = 0; } } else { - sdl.desktop.width = 0; - sdl.desktop.height = 0; + sdl.desktop.full.width = 0; + sdl.desktop.full.height = 0; + } + const char* windowresolution=section->Get_string("windowresolution"); + if(windowresolution && *windowresolution) { + char res[100]; + strncpy( res,windowresolution, sizeof( res )); + windowresolution = lowcase (res);//so x and X are allowed + + char* height = const_cast(strchr(windowresolution,'x')); + if(height && *height) { + *height = 0; + sdl.desktop.window.height = atoi(height+1); + sdl.desktop.window.width = atoi(res); + } else { + sdl.desktop.window.width = 0; + sdl.desktop.window.height = 0; + } + } else { + sdl.desktop.window.width = 0; + sdl.desktop.window.height = 0; } sdl.desktop.doublebuf=section->Get_bool("fulldouble"); - sdl.desktop.hwscale=section->Get_float("hwscale"); - if (sdl.desktop.hwscale<0.1f) { - LOG_MSG("SDL:Can't hwscale lower than 0.1"); - sdl.desktop.hwscale=0.1f; - } - if (!sdl.desktop.width) { + if (!sdl.desktop.full.width) { #ifdef WIN32 - sdl.desktop.width=GetSystemMetrics(SM_CXSCREEN); + sdl.desktop.full.width=GetSystemMetrics(SM_CXSCREEN); #else - sdl.desktop.width=1024; + sdl.desktop.full.width=1024; #endif } - if (!sdl.desktop.height) { + if (!sdl.desktop.full.height) { #ifdef WIN32 - sdl.desktop.height=GetSystemMetrics(SM_CYSCREEN); + sdl.desktop.full.height=GetSystemMetrics(SM_CYSCREEN); #else - sdl.desktop.height=768; + sdl.desktop.full.height=768; #endif } sdl.mouse.autoenable=section->Get_bool("autolock"); @@ -914,6 +1009,7 @@ static void GUI_StartUp(Section * sec) { #if defined(NVIDIA_PixelDataRange) sdl.opengl.pixel_data_range=(strstr(gl_ext,"GL_NV_pixel_data_range") >0 ) && glPixelDataRangeNV && db_glAllocateMemoryNV && db_glFreeMemoryNV; + sdl.opengl.pixel_data_range = 0; #endif } else { sdl.opengl.packed_pixel=sdl.opengl.paletted_texture=false; @@ -1018,6 +1114,7 @@ void GFX_Events() { CaptureMouse(); } SetPriority(sdl.priority.nofocus); + MAPPER_LosingFocus(); } } break; @@ -1112,9 +1209,9 @@ int main(int argc, char* argv[]) { #endif if ( SDL_Init( SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM + |SDL_INIT_NOPARACHUTE #ifndef DISABLE_JOYSTICK |SDL_INIT_JOYSTICK - #endif ) < 0 ) E_Exit("Can't init SDL %s",SDL_GetError()); Section_prop * sdl_sec=control->AddSection_prop("sdl",&GUI_StartUp); @@ -1123,8 +1220,8 @@ int main(int argc, char* argv[]) { sdl_sec->Add_bool("fulldouble",false); sdl_sec->Add_bool("fullfixed",false); sdl_sec->Add_string("fullresolution","1024x768"); + sdl_sec->Add_string("windowresolution","0x0"); sdl_sec->Add_string("output","surface"); - sdl_sec->Add_float("hwscale",1.0); sdl_sec->Add_bool("autolock",true); sdl_sec->Add_int("sensitivity",100); sdl_sec->Add_bool("waitonerror",true); From 8bc8960ab795143f7a550723543f5e90d4cf1d99 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 10:00:44 +0000 Subject: [PATCH 2361/4131] Fix compilation warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2445 --- src/hardware/iohandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index b18a3571..f001ba8a 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: iohandler.cpp,v 1.18 2005-08-10 20:36:36 qbix79 Exp $ */ +/* $Id: iohandler.cpp,v 1.19 2006-01-30 10:00:44 harekiet Exp $ */ #include #include "dosbox.h" @@ -30,7 +30,7 @@ IO_WriteHandler * io_writehandlers[3][IO_MAX]; IO_ReadHandler * io_readhandlers[3][IO_MAX]; static Bitu IO_ReadBlocked(Bitu port,Bitu iolen) { - return (Bitu)-1; + return ~0; } static void IO_WriteBlocked(Bitu port,Bitu val,Bitu iolen) { } From c196fba725f8512d42bd2dfe0cd58c2d1f128359 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 10:04:03 +0000 Subject: [PATCH 2362/4131] Rewrtites of most memory and drawing handlers Some splitting of the s3 hardware into a seperate module Support for 15/16/32bpp modes Support for a highres 4bpp mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2446 --- src/hardware/vga.cpp | 18 +- src/hardware/vga_attr.cpp | 1 + src/hardware/vga_crtc.cpp | 369 ++-------------------- src/hardware/vga_dac.cpp | 3 + src/hardware/vga_draw.cpp | 106 +++++-- src/hardware/vga_memory.cpp | 595 +++++++++++++++++++++++------------- src/hardware/vga_misc.cpp | 39 +-- src/hardware/vga_s3.cpp | 432 ++++++++++++++++++++++++++ src/hardware/vga_seq.cpp | 58 +--- src/hardware/vga_xga.cpp | 10 +- 10 files changed, 968 insertions(+), 663 deletions(-) create mode 100644 src/hardware/vga_s3.cpp diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index d56735d2..c924393c 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -50,20 +50,22 @@ void VGA_DetermineMode(void) { if (vga.s3.misc_control_2 & 0xf0) { switch (vga.s3.misc_control_2 >> 4) { case 1:VGA_SetMode(M_LIN8);break; + case 3:VGA_SetMode(M_LIN15);break; + case 5:VGA_SetMode(M_LIN16);break; + case 13:VGA_SetMode(M_LIN32);break; } /* Test for graphics or alphanumeric mode */ } else if (vga.attr.mode_control & 1) { if (vga.gfx.mode & 0x40) VGA_SetMode(M_VGA); else if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4); else if ((vga.gfx.miscellaneous & 0x0c)==0x0c) VGA_SetMode(M_CGA2); - else VGA_SetMode(M_EGA16); - /* old mode detection: - if (!(vga.crtc.mode_control & 0x1)) { - if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4); - else VGA_SetMode(M_CGA2); - } else if (vga.attr.mode_control & 0x40) { - VGA_SetMode(M_VGA); - } else VGA_SetMode(M_EGA16); */ + else { + if (vga.s3.reg_31 & 0x8) + VGA_SetMode(M_LIN4); + else + VGA_SetMode(M_EGA); + + } } else { VGA_SetMode(M_TEXT); } diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index b2010589..1e7bc272 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -121,6 +121,7 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) { case M_LIN8: vga.config.pel_panning=(val & 0x7)/2; break; + case M_LIN16: default: vga.config.pel_panning=(val & 0x7); } diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 82daa008..d193f372 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -29,18 +29,18 @@ void VGA_MapMMIO(void); void VGA_UnmapMMIO(void); -void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen); +void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen); Bitu DEBUG_EnableDebugger(void); -void write_p3d4_vga(Bitu port,Bitu val,Bitu iolen) { +void vga_write_p3d4(Bitu port,Bitu val,Bitu iolen) { crtc(index)=val; } -Bitu read_p3d4_vga(Bitu port,Bitu iolen) { +Bitu vga_read_p3d4(Bitu port,Bitu iolen) { return crtc(index); } -void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen) { +void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { // if (crtc(index)>0x18) LOG_MSG("VGA CRCT write %X to reg %X",val,crtc(index)); switch(crtc(index)) { case 0x00: /* Horizontal Total Register */ @@ -289,291 +289,19 @@ void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen) { Bit 9 is found in 3d4h index 9 bit 6. */ break; -/* S3 specific group */ - case 0x31: /* CR31 Memory Configuration */ -//TODO Base address - vga.s3.reg_31=val; - vga.config.compatible_chain4 = !(val&0x08); - VGA_SetupHandlers(); - break; - /* - 0 Enable Base Address Offset (CPUA BASE). Enables bank operation if - set, disables if clear. - 1 Two Page Screen Image. If set enables 2048 pixel wide screen setup - 2 VGA 16bit Memory Bus Width. Set for 16bit, clear for 8bit - 3 Use Enhanced Mode Memory Mapping (ENH MAP). Set to enable access to - video memory above 256k. - 4-5 Bit 16-17 of the Display Start Address. For the 801/5,928 see index - 51h, for the 864/964 see index 69h. - 6 High Speed Text Display Font Fetch Mode. If set enables Page Mode - for Alpha Mode Font Access. - 7 (not 864/964) Extended BIOS ROM Space Mapped out. If clear the area - C6800h-C7FFFh is mapped out, if set it is accessible. - */ - case 0x35: /* CR35 CRT Register Lock */ - if (vga.s3.reg_lock1 != 0x48) return; //Needed for uvconfig detection - vga.s3.reg_35=val & 0xf0; - if ((vga.s3.bank & 0xf) ^ (val & 0xf)) { - vga.s3.bank&=0xf0; - vga.s3.bank|=val & 0xf; - VGA_SetupHandlers(); - } - break; - /* - 0-3 CPU Base Address. 64k bank number. For the 801/5 and 928 see 3d4h - index 51h bits 2-3. For the 864/964 see index 6Ah. - 4 Lock Vertical Timing Registers (LOCK VTMG). Locks 3d4h index 6, 7 - (bits 0,2,3,5,7), 9 bit 5, 10h, 11h bits 0-3, 15h, 16h if set - 5 Lock Horizontal Timing Registers (LOCK HTMG). Locks 3d4h index - 0,1,2,3,4,5,17h bit 2 if set - 6 (911/924) Lock VSync Polarity. - 7 (911/924) Lock HSync Polarity. - */ - case 0x38: /* CR38 Register Lock 1 */ - vga.s3.reg_lock1=val; - break; - case 0x39: /* CR39 Register Lock 2 */ - vga.s3.reg_lock2=val; - break; - case 0x40: /* CR40 System Config */ - vga.s3.reg_40 = val; - break; - case 0x43: /* CR43 Extended Mode */ - vga.s3.reg_43=val & ~0x4; - if (((val & 0x4) ^ (vga.config.scan_len >> 6)) & 0x4) { - vga.config.scan_len&=0x2ff; - vga.config.scan_len|=(val & 0x4) << 6; - VGA_CheckScanLength(); - } - break; - /* - 2 Logical Screen Width bit 8. Bit 8 of the Display Offset Register/ - (3d4h index 13h). (801/5,928) Only active if 3d4h index 51h bits 4-5 - are 0 - */ - case 0x45: /* Hardware cursor mode */ - vga.s3.hgc.curmode = val; - // Activate hardware cursor code if needed - VGA_ActivateHardwareCursor(); - break; - case 0x46: - vga.s3.hgc.originx = (vga.s3.hgc.originx & 0x00ff) | (val << 8); - break; - case 0x47: /* HGC orgX */ - vga.s3.hgc.originx = (vga.s3.hgc.originx & 0xff00) | val; - break; - case 0x48: - vga.s3.hgc.originy = (vga.s3.hgc.originy & 0x00ff) | (val << 8); - break; - case 0x49: /* HGC orgY */ - vga.s3.hgc.originy = (vga.s3.hgc.originy & 0xff00) | val; - break; - case 0x4A: /* HGC foreground stack */ - if (vga.s3.hgc.fstackpos > 2) vga.s3.hgc.fstackpos = 0; - vga.s3.hgc.forestack[vga.s3.hgc.fstackpos] = val; - vga.s3.hgc.fstackpos++; - break; - case 0x4B: /* HGC background stack */ - if (vga.s3.hgc.bstackpos > 2) vga.s3.hgc.bstackpos = 0; - vga.s3.hgc.backstack[vga.s3.hgc.bstackpos] = val; - vga.s3.hgc.bstackpos++; - break; - case 0x4c: /* HGC start address high byte*/ - vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | ((val & 0xff) << 8); - break; - case 0x4d: /* HGC start address low byte*/ - vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | (val & 0xff); - break; - case 0x4e: /* HGC pattern start X */ - vga.s3.hgc.posx = val; - break; - case 0x4f: /* HGC pattern start X */ - vga.s3.hgc.posy = val; - break; - case 0x51: /* Extended System Control 2 */ - vga.s3.reg_51=val & 0xc0; //Only store bits 6,7 - //TODO Display start - vga.config.display_start&=0xFCFFFF; - vga.config.display_start|=(val & 3) << 16; - if ((vga.s3.bank&0xcf) ^ ((val&0xc)<<2)) { - vga.s3.bank&=0xcf; - vga.s3.bank|=(val&0xc)<<2; - VGA_SetupHandlers(); - } - if (((val & 0x30) ^ (vga.config.scan_len >> 4)) & 0x30) { - vga.config.scan_len&=0xff; - vga.config.scan_len|=(val & 0x30) << 4; - VGA_CheckScanLength(); - } - break; - /* - 0 (80x) Display Start Address bit 18 - 0-1 (928 +) Display Start Address bit 18-19 - Bits 16-17 are in index 31h bits 4-5, Bits 0-15 are in 3d4h index - 0Ch,0Dh. For the 864/964 see 3d4h index 69h - 2 (80x) CPU BASE. CPU Base Address Bit 18. - 2-3 (928 +) Old CPU Base Address Bits 19-18. - 64K Bank register bits 4-5. Bits 0-3 are in 3d4h index 35h. - For the 864/964 see 3d4h index 6Ah - 4-5 Logical Screen Width Bit [8-9]. Bits 8-9 of the CRTC Offset register - (3d4h index 13h). If this field is 0, 3d4h index 43h bit 2 is active - 6 (928,964) DIS SPXF. Disable Split Transfers if set. Spilt Transfers - allows transferring one half of the VRAM shift register data while - the other half is being output. For the 964 Split Transfers - must be enabled in enhanced modes (4AE8h bit 0 set). Guess: They - probably can't time the VRAM load cycle closely enough while the - graphics engine is running. - 7 (not 864/964) Enable EPROM Write. If set enables flash memory write - control to the BIOS ROM address - */ - case 0x53: - if((val & 0x10) != (vga.s3.ext_mem_ctrl & 0x10)) { - /* Map or unmap MMIO */ - if ((val & 0x10) != 0) { - //LOG_MSG("VGA: Mapping Memory Mapped I/O to 0xA0000"); - VGA_MapMMIO(); - } else { - VGA_UnmapMMIO(); - } - } - vga.s3.ext_mem_ctrl = val; - break; - case 0x55: /* Extended Video DAC Control */ - vga.s3.reg_55=val; - break; - /* - 0-1 DAC Register Select Bits. Passed to the RS2 and RS3 pins on the - RAMDAC, allowing access to all 8 or 16 registers on advanced RAMDACs. - If this field is 0, 3d4h index 43h bit 1 is active. - 2 Enable General Input Port Read. If set DAC reads are disabled and the - STRD strobe for reading the General Input Port is enabled for reading - while DACRD is active, if clear DAC reads are enabled. - 3 (928) Enable External SID Operation if set. If set video data is - passed directly from the VRAMs to the DAC rather than through the - VGA chip - 4 Hardware Cursor MS/X11 Mode. If set the Hardware Cursor is in X11 - mode, if clear in MS-Windows mode - 5 (80x,928) Hardware Cursor External Operation Mode. If set the two - bits of cursor data ,is output on the HC[0-1] pins for the video DAC - The SENS pin becomes HC1 and the MID2 pin becomes HC0. - 6 ?? - 7 (80x,928) Disable PA Output. If set PA[0-7] and VCLK are tristated. - (864/964) TOFF VCLK. Tri-State Off VCLK Output. VCLK output tri - -stated if set - */ - case 0x58: /* Linear Address Window Control */ - vga.s3.reg_58=val; - break; - /* - 0-1 Linear Address Window Size. Must be less than or equal to video - memory size. 0: 64K, 1: 1MB, 2: 2MB, 3: 4MB (928)/8Mb (864/964) - 2 (not 864/964) Enable Read Ahead Cache if set - 3 (80x,928) ISA Latch Address. If set latches address during every ISA - cycle, unlatches during every ISA cycle if clear. - (864/964) LAT DEL. Address Latch Delay Control (VL-Bus only). If set - address latching occours in the T1 cycle, if clear in the T2 cycle - (I.e. one clock cycle delayed). - 4 ENB LA. Enable Linear Addressing if set. - 5 (not 864/964) Limit Entry Depth for Write-Post. If set limits Write - -Post Entry Depth to avoid ISA bus timeout due to wait cycle limit. - 6 (928,964) Serial Access Mode (SAM) 256 Words Control. If set SAM - control is 256 words, if clear 512 words. - 7 (928) RAS 6-MCLK. If set the random read/write cycle time is 6MCLKs, - if clear 7MCLKs - */ - case 0x59: /* Linear Address Window Position High */ - if ((vga.s3.la_window&0xff00) ^ (val << 8)) { - vga.s3.la_window=(vga.s3.la_window&0x00ff) | (val << 8); - VGA_StartUpdateLFB(); - } - break; - case 0x5a: /* Linear Address Window Position Low */ - if ((vga.s3.la_window&0x00ff) ^ val) { - vga.s3.la_window=(vga.s3.la_window&0xff00) | val; - VGA_StartUpdateLFB(); - } - break; - case 0x5D: /* Extended Horizontal Overflow */ - if ((val & vga.s3.ex_hor_overflow) ^ 3) { - vga.s3.ex_hor_overflow=val; - VGA_StartResize(); - } else vga.s3.ex_hor_overflow=val; - break; - /* - 0 Horizontal Total bit 8. Bit 8 of the Horizontal Total register (3d4h - index 0) - 1 Horizontal Display End bit 8. Bit 8 of the Horizontal Display End - register (3d4h index 1) - 2 Start Horizontal Blank bit 8. Bit 8 of the Horizontal Start Blanking - register (3d4h index 2). - 3 (864,964) EHB+64. End Horizontal Blank +64. If set the /BLANK pulse - is extended by 64 DCLKs. Note: Is this bit 6 of 3d4h index 3 or - does it really extend by 64 ? - 4 Start Horizontal Sync Position bit 8. Bit 8 of the Horizontal Start - Retrace register (3d4h index 4). - 5 (864,964) EHS+32. End Horizontal Sync +32. If set the HSYNC pulse - is extended by 32 DCLKs. Note: Is this bit 5 of 3d4h index 5 or - does it really extend by 32 ? - 6 (928,964) Data Transfer Position bit 8. Bit 8 of the Data Transfer - Position register (3d4h index 3Bh) - 7 (928,964) Bus-Grant Terminate Position bit 8. Bit 8 of the Bus Grant - Termination register (3d4h index 5Fh). - */ - case 0x5e: /* Extended Vertical Overflow */ - vga.config.line_compare=(vga.config.line_compare & 0x3ff) | (val & 0x40) << 4; - if ((val ^ vga.s3.ex_ver_overflow) & 0x3) { - vga.s3.ex_ver_overflow=val; - VGA_StartResize(); - } else vga.s3.ex_ver_overflow=val; - break; - /* - 0 Vertical Total bit 10. Bit 10 of the Vertical Total register (3d4h - index 6). Bits 8 and 9 are in 3d4h index 7 bit 0 and 5. - 1 Vertical Display End bit 10. Bit 10 of the Vertical Display End - register (3d4h index 12h). Bits 8 and 9 are in 3d4h index 7 bit 1 - and 6 - 2 Start Vertical Blank bit 10. Bit 10 of the Vertical Start Blanking - register (3d4h index 15h). Bit 8 is in 3d4h index 7 bit 3 and bit 9 - in 3d4h index 9 bit 5 - 4 Vertical Retrace Start bit 10. Bit 10 of the Vertical Start Retrace - register (3d4h index 10h). Bits 8 and 9 are in 3d4h index 7 bit 2 - and 7. - 6 Line Compare Position bit 10. Bit 10 of the Line Compare register - (3d4h index 18h). Bit 8 is in 3d4h index 7 bit 4 and bit 9 in 3d4h - index 9 bit 6. - */ - case 0x67: /* Extended Miscellaneous Control 2 */ - /* - 0 VCLK PHS. VCLK Phase With Respect to DCLK. If clear VLKC is inverted - DCLK, if set VCLK = DCLK. - 4-7 Pixel format. - 0 Mode 0: 8bit (1 pixel/VCLK) - 1 Mode 8: 8bit (2 pixels/VCLK) - 3 Mode 9: 15bit (1 pixel/VCLK) - 5 Mode 10: 16bit (1 pixel/VCLK) - 7 Mode 11: 24/32bit (2 VCLKs/pixel) - 13 (732/764) 32bit (1 pixel/VCLK) - */ - vga.s3.misc_control_2=val; - VGA_DetermineMode(); - break; - case 0x69: /* Extended System Control 3 */ - if (((vga.config.display_start & 0x1f0000)>>16) ^ (val & 0x1f)) { - vga.config.display_start&=0xffff; - vga.config.display_start|=(val & 0x1f) << 16; - } - break; - case 0x6a: /* Extended System Control 4 */ - vga.s3.bank=val & 0x3f; - VGA_SetupHandlers(); - break; - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:Write %X to unknown index %2X",val,crtc(index)); + switch (svgaCard) { + case SVGA_S3Trio: + SVGA_S3_WriteCRTC( crtc(index), val, iolen); + break; + default: + break; + } + break; } } -Bitu read_p3d5_vga(Bitu port,Bitu iolen) { +Bitu vga_read_p3d5(Bitu port,Bitu iolen) { // LOG_MSG("VGA CRCT read from reg %X",crtc(index)); switch(crtc(index)) { case 0x00: /* Horizontal Total Register */ @@ -626,72 +354,15 @@ Bitu read_p3d5_vga(Bitu port,Bitu iolen) { return crtc(mode_control); case 0x18: /* Line Compare Register */ return crtc(line_compare); - - -/* Additions for S3 SVGA Support */ - case 0x2d: /* Extended Chip ID. */ - return 0x88; - // Always 88h ? - case 0x2e: /* New Chip ID */ - return 0x11; - //Trio 64 id - case 0x2f: /* Revision */ - return 0x00; - case 0x30: /* CR30 Chip ID/REV register */ - return 0xe0; //Trio+ dual byte - // Trio32/64 has 0xe0. extended - case 0x31: /* CR31 Memory Configuration */ -//TODO mix in bits from baseaddress; - return vga.s3.reg_31; - case 0x35: /* CR35 CRT Register Lock */ - return vga.s3.reg_35|(vga.s3.bank & 0xf); - case 0x36: /* CR36 Reset State Read 1 */ - //return 0x8f; - return 0x8e; /* PCI version */ - //2 Mb PCI and some bios settings - case 0x37: /* Reset state read 2 */ - return 0x2b; - case 0x38: /* CR38 Register Lock 1 */ - return vga.s3.reg_lock1; - case 0x39: /* CR39 Register Lock 2 */ - return vga.s3.reg_lock2; - case 0x40: /* CR40 system config */ - return vga.s3.reg_40; - case 0x43: /* CR43 Extended Mode */ - return vga.s3.reg_43|((vga.config.scan_len>>6)&0x4); - case 0x45: /* Hardware cursor mode */ - vga.s3.hgc.bstackpos = 0; - vga.s3.hgc.fstackpos = 0; - return vga.s3.hgc.curmode; - case 0x51: /* Extended System Control 2 */ - return ((vga.config.display_start >> 16) & 3 ) | - ((vga.s3.bank & 0x30) >> 2) | - ((vga.config.scan_len & 0x300) >> 4) | - vga.s3.reg_51; - case 0x53: - return vga.s3.ext_mem_ctrl; - case 0x55: /* Extended Video DAC Control */ - return vga.s3.reg_55; - case 0x58: /* Linear Address Window Control */ - return vga.s3.reg_58; - case 0x59: /* Linear Address Window Position High */ - return (vga.s3.la_window >> 8); - case 0x5a: /* Linear Address Window Position Low */ - return (vga.s3.la_window & 0xff); - case 0x5D: /* Extended Horizontal Overflow */ - return vga.s3.ex_hor_overflow; - case 0x5e: /* Extended Vertical Overflow */ - return vga.s3.ex_ver_overflow; - case 0x67: /* Extended Miscellaneous Control 2 */ - return vga.s3.misc_control_2; - case 0x69: /* Extended System Control 3 */ - return (Bit8u)((vga.config.display_start & 0x1f0000)>>16); - case 0x6a: /* Extended System Control 4 */ - return (Bit8u)(vga.s3.bank & 0x3f); default: - LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:Read from unknown index %X",crtc(index)); + switch (svgaCard) { + case SVGA_S3Trio: + return SVGA_S3_ReadCRTC( crtc(index), iolen ); + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:Read from unknown index %X",crtc(index)); + return 0x0; + } } - return 0x0; } diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index 98865c76..c714c8c6 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -100,6 +100,7 @@ static void write_p3c9(Bitu port,Bitu val,Bitu iolen) { switch (vga.mode) { case M_VGA: case M_LIN8: + case M_LIN16: RENDER_SetPal(vga.dac.write_index, vga.dac.rgb[vga.dac.write_index].red << 2, vga.dac.rgb[vga.dac.write_index].green << 2, @@ -155,6 +156,7 @@ void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal) { switch (vga.mode) { case M_VGA: case M_LIN8: + case M_LIN16: break; default: RENDER_SetPal(attr, @@ -172,6 +174,7 @@ void VGA_DAC_SetEntry(Bitu entry,Bit8u red,Bit8u green,Bit8u blue) { switch (vga.mode) { case M_VGA: case M_LIN8: + case M_LIN16: return; } for (Bitu i=0;i<16;i++) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 40b0582b..1d9b6e29 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -21,6 +21,7 @@ #include "dosbox.h" #include "video.h" #include "render.h" +#include "../gui/render_scalers.h" #include "vga.h" #include "pic.h" @@ -31,7 +32,7 @@ typedef void (* VGA_FrameStart_Handler)(); static VGA_Line_Handler VGA_DrawLine; static VGA_FrameStart_Handler VGA_FrameStart; -static Bit8u TempLine[1280]; +static Bit8u TempLine[SCALER_MAXWIDTH * 4]; static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; @@ -75,7 +76,7 @@ static Bit8u * VGA_Draw_2BPPHiRes_Line(Bitu vidstart,Bitu panning,Bitu line) { static Bitu temp[643]={0}; static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart,Bitu panning,Bitu line) { - Bit8u * reader=&vga.mem.linear[vidstart + (line * 8 * 1024)]; + const Bit8u * reader=&vga.mem.linear[vidstart + (line * 8 * 1024)]; Bit32u * draw=(Bit32u *)TempLine; //Generate a temporary bitline to calculate the avarage //over bit-2 bit-1 bit bit+1. @@ -147,13 +148,21 @@ static Bit8u * VGA_Draw_4BPP_Line_Double(Bitu vidstart,Bitu panning,Bitu line) { return TempLine; } - +static Bit8u * VGA_Draw_LIN4_Line(Bitu vidstart,Bitu panning,Bitu line) { + return &vga.mem.linear[512*1024+vidstart*8+panning]; +} static Bit8u * VGA_Draw_EGA_Line(Bitu vidstart,Bitu panning,Bitu line) { return &vga.mem.linear[512*1024+vidstart*8+panning]; } static Bit8u * VGA_Draw_VGA_Line(Bitu vidstart,Bitu panning,Bitu line) { return &vga.mem.linear[vidstart*4+panning]; } +static Bit8u * VGA_Draw_LIN16_Line(Bitu vidstart,Bitu panning,Bitu line) { + return &vga.mem.linear[vidstart*4+panning]; +} +static Bit8u * VGA_Draw_LIN32_Line(Bitu vidstart,Bitu panning,Bitu line) { + return &vga.mem.linear[vidstart*4+panning]; +} static Bit8u * VGA_Draw_VGAChained_Line(Bitu vidstart,Bitu panning,Bitu line) { return &vga.mem.linear[512*1024+((vidstart*4+panning)&0xffff)]; @@ -169,17 +178,16 @@ static void VGA_StartFrame_VGA() { static Bit8u * VGA_Draw_VGA_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) { if(vga.s3.hgc.curmode & 0x1) { Bitu lineat = vidstart / ((160 * vga.draw.height) / 480); - if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63))) { + if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) { return VGA_Draw_VGA_Line(vidstart, panning, line); } else { - memcpy(TempLine, VGA_Draw_VGA_Line(vidstart, panning, line), vga.draw.width); /* Draw mouse cursor */ Bits moff = ((Bits)lineat - (Bits)vga.s3.hgc.originy) + (Bits)vga.s3.hgc.posy; if(moff>63) return VGA_Draw_VGA_Line(vidstart, panning, line); if(moff<0) moff+=64; Bitu xat = vga.s3.hgc.originx; - Bitu m, mat, mapat; + Bitu m, mapat; Bits r, z; mapat = 0; @@ -242,8 +250,8 @@ static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { *draw++=fg&mask1 | bg&~mask1; *draw++=fg&mask2 | bg&~mask2; } - Bits font_addr=(vga.draw.cursor.address-vidstart)/2; if (!vga.draw.cursor.enabled || !(vga.draw.cursor.count&0x8)) goto skip_cursor; + Bitu font_addr=(vga.draw.cursor.address-vidstart) >> 1; if (font_addr>=0 && font_addrvga.draw.cursor.eline) goto skip_cursor; @@ -257,7 +265,7 @@ skip_cursor: static void VGA_VerticalDisplayEnd(Bitu val) { vga.config.retrace=true; - vga.config.real_start=vga.config.display_start; + vga.config.real_start=vga.config.display_start & ((2*1024*1024)-1); } static void VGA_HorizontalTimer(void) { @@ -310,14 +318,16 @@ static void VGA_VerticalTimer(Bitu val) { vga.config.retrace=false; PIC_AddEvent(VGA_VerticalTimer,vga.draw.delay.vtotal); PIC_AddEvent(VGA_VerticalDisplayEnd,vga.draw.delay.vend); - if (RENDER_StartUpdate()) { + bool bDoDraw = RENDER_StartUpdate(); + if (bDoDraw) { +// if (RENDER_StartUpdate()) { vga.draw.parts_left=vga.draw.parts_total; vga.draw.lines_done=0; vga.draw.address=vga.config.real_start; vga.draw.address_line=vga.config.hlines_skip; vga.draw.split_line=(vga.config.line_compare/vga.draw.lines_scaled); vga.draw.panning=vga.config.pel_panning; - PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts,vga.draw.parts_lines); +// PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts,vga.draw.parts_lines); } switch (vga.mode) { case M_TEXT: @@ -339,13 +349,19 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.address+=vga.tandy.disp_bank << 14; vga.draw.cursor.address+=vga.tandy.disp_bank << 14; } + if (bDoDraw) + VGA_DrawPart(vga.draw.parts_lines); } void VGA_CheckScanLength(void) { switch (vga.mode) { - case M_EGA16: + case M_EGA: case M_VGA: + case M_LIN4: case M_LIN8: + case M_LIN15: + case M_LIN16: + case M_LIN32: vga.draw.address_add=vga.config.scan_len*2; break; case M_TEXT: @@ -412,13 +428,21 @@ void VGA_SetupDrawing(Bitu val) { if (hbstart> 2) & 3; - if (clock == 0) - clock = 25175000; - else if (clock == 1) - clock = 28322000; - else - clock=1000*S3_CLOCK(vga.s3.clk[clock].m,vga.s3.clk[clock].n,vga.s3.clk[clock].r); + switch (svgaCard) { + case SVGA_S3Trio: + clock = SVGA_S3_GetClock(); + break; + default: + switch ((vga.misc_output >> 2) & 3) { + case 0: + clock = 25175000; + break; + case 1: + clock = 28322000; + break; + } + break; + } /* Check for 8 for 9 character clock mode */ if (vga.seq.clocking_mode & 1 ) clock/=8; else clock/=9; /* Check for pixel doubling, master clock/2 */ @@ -469,6 +493,7 @@ void VGA_SetupDrawing(Bitu val) { vga.draw.resizing=false; Bitu width=hdispend; Bitu height=vdispend; + Bitu bpp=8; bool doubleheight=false; bool doublewidth=false; VGA_FrameStart = NULL; @@ -482,11 +507,49 @@ void VGA_SetupDrawing(Bitu val) { break; case M_LIN8: width<<=3; + if (vga.crtc.mode_control & 0x8) { + doublewidth = true; + width >>= 1; + } /* Use HW mouse cursor drawer if enabled */ VGA_ActivateHardwareCursor(); break; - case M_EGA16: + case M_LIN15: + bpp = 15; + width<<=3; + if (vga.crtc.mode_control & 0x8) { + doublewidth = true; + width >>= 1; + } + VGA_DrawLine=VGA_Draw_LIN16_Line; + break; + case M_LIN16: + bpp = 16; + width<<=3; + if (vga.crtc.mode_control & 0x8) { + doublewidth = true; + width >>= 1; + } + VGA_DrawLine=VGA_Draw_LIN16_Line; + break; + case M_LIN32: + bpp = 32; + width<<=3; + if (vga.crtc.mode_control & 0x8) { + doublewidth = true; + width >>= 1; + } + VGA_DrawLine=VGA_Draw_LIN32_Line; + break; + case M_LIN4: doublewidth=(vga.seq.clocking_mode & 0x8) > 0; + vga.draw.blocks = width; + width<<=3; + VGA_DrawLine=VGA_Draw_LIN4_Line; + break; + case M_EGA: + doublewidth=(vga.seq.clocking_mode & 0x8) > 0; + vga.draw.blocks = width; width<<=3; VGA_DrawLine=VGA_Draw_EGA_Line; break; @@ -579,7 +642,8 @@ void VGA_SetupDrawing(Bitu val) { } vga.draw.lines_total=height; vga.draw.parts_lines=vga.draw.lines_total/vga.draw.parts_total; - if (( width != vga.draw.width) || (height != vga.draw.height)) { + if (( width != vga.draw.width) || (height != vga.draw.height) || (vga.mode != vga.lastmode)) { + vga.lastmode = vga.mode; PIC_RemoveEvents(VGA_VerticalTimer); PIC_RemoveEvents(VGA_VerticalDisplayEnd); PIC_RemoveEvents(VGA_DrawPart); @@ -594,7 +658,7 @@ void VGA_SetupDrawing(Bitu val) { LOG(LOG_VGA,LOG_NORMAL)("%s width, %s height aspect %f", doublewidth ? "double":"normal",doubleheight ? "double":"normal",aspect_ratio); #endif - RENDER_SetSize(width,height,8,aspect_ratio,doublewidth,doubleheight); + RENDER_SetSize(width,height,bpp,fps,aspect_ratio,doublewidth,doubleheight); PIC_AddEvent(VGA_VerticalTimer,vga.draw.delay.vtotal); } }; diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 391f66ae..6581b3eb 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -26,38 +26,7 @@ #include "inout.h" void VGA_MapMMIO(void); - -static Bitu VGA_NormalReadHandler(PhysPt start) { - vga.latch.d=vga.mem.latched[start].d; - switch (vga.config.read_mode) { - case 0: - return (vga.latch.b[vga.config.read_map_select]); - case 1: - VGA_Latch templatch; - templatch.d=(vga.latch.d & FillTable[vga.config.color_dont_care]) ^ FillTable[vga.config.color_compare & vga.config.color_dont_care]; - return (Bit8u)~(templatch.b[0] | templatch.b[1] | templatch.b[2] | templatch.b[3]); - } - return 0; -} - -static Bitu VGA_Chain4ReadHandler(PhysPt start) { - if(vga.mode == M_VGA) - return vga.mem.linear[((start&~3)<<2)|(start&3)]; - return vga.mem.linear[start]; -} - -static void VGA_Chain4WriteHandler(PhysPt start, Bit8u val) { - // No need to check for compatible chains here, this one is only enabled if that bit is set - vga.mem.linear[((start&~3)<<2)|(start&3)] = val; - // Linearized version for faster rendering - vga.mem.linear[512*1024+start] = val; - // And replicate the first line - if (start < 320) - vga.mem.linear[512*1024+start+64*1024] = val; -} - //Nice one from DosEmu - INLINE static Bit32u RasterOp(Bit32u input,Bit32u mask) { switch (vga.config.raster_op) { case 0x00: /* None */ @@ -100,73 +69,6 @@ INLINE static Bit32u ModeOperation(Bit8u val) { return full; } -static void VGA_GFX_16_WriteHandler(PhysPt start,Bit8u val) { - Bit32u data=ModeOperation(val); - /* Update video memory and the pixel buffer */ - VGA_Latch pixels; - pixels.d=vga.mem.latched[start].d; - pixels.d&=vga.config.full_not_map_mask; - pixels.d|=(data & vga.config.full_map_mask); - vga.mem.latched[start].d=pixels.d; - Bit8u * write_pixels=&vga.mem.linear[512*1024+(start<<3)]; - - Bit32u colors0_3, colors4_7; - VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f; - colors0_3 = - Expand16Table[0][temp.b[0]] | - Expand16Table[1][temp.b[1]] | - Expand16Table[2][temp.b[2]] | - Expand16Table[3][temp.b[3]]; - *(Bit32u *)write_pixels=colors0_3; - *(Bit32u *)(write_pixels+512*1024)=colors0_3; - temp.d=pixels.d & 0x0f0f0f0f; - colors4_7 = - Expand16Table[0][temp.b[0]] | - Expand16Table[1][temp.b[1]] | - Expand16Table[2][temp.b[2]] | - Expand16Table[3][temp.b[3]]; - *(Bit32u *)(write_pixels+4)=colors4_7; - *(Bit32u *)(write_pixels+512*1024+4)=colors4_7; - -} - -static void VGA_GFX_16Chain4_WriteHandler(PhysPt start,Bit8u val) { - Bit32u data=ModeOperation(val); - /* Update video memory and the pixel buffer */ - VGA_Latch pixels; - vga.mem.linear[start] = val; - start >>= 2; - pixels.d=vga.mem.latched[start].d; - - Bit8u * write_pixels=&vga.mem.linear[512*1024+(start<<3)]; - - Bit32u colors0_3, colors4_7; - VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f; - colors0_3 = - Expand16Table[0][temp.b[0]] | - Expand16Table[1][temp.b[1]] | - Expand16Table[2][temp.b[2]] | - Expand16Table[3][temp.b[3]]; - *(Bit32u *)write_pixels=colors0_3; - temp.d=pixels.d & 0x0f0f0f0f; - colors4_7 = - Expand16Table[0][temp.b[0]] | - Expand16Table[1][temp.b[1]] | - Expand16Table[2][temp.b[2]] | - Expand16Table[3][temp.b[3]]; - *(Bit32u *)(write_pixels+4)=colors4_7; -} - -static void VGA_GFX_256U_WriteHandler(PhysPt start,Bit8u val) { - Bit32u data=ModeOperation(val); - VGA_Latch pixels; - pixels.d=vga.mem.latched[start].d; - pixels.d&=vga.config.full_not_map_mask; - pixels.d|=(data & vga.config.full_map_mask); - vga.mem.latched[start].d=pixels.d; - vga.mem.latched[start+64*1024].d=pixels.d; -} - /* Gonna assume that whoever maps vga memory, maps it on 32/64kb boundary */ #define VGA_PAGES (128/4) @@ -175,142 +77,238 @@ static void VGA_GFX_256U_WriteHandler(PhysPt start,Bit8u val) { #define VGA_PAGE_B8 (0xB8000/4096) static struct { - Bitu base,mask; + Bitu base, mask; } vgapages; -class VGARead_PageHandler : public PageHandler { +class VGA_UnchainedRead_Handler : public PageHandler { +public: + Bitu readHandler(PhysPt start) { + vga.latch.d=vga.mem.latched[start].d; + switch (vga.config.read_mode) { + case 0: + return (vga.latch.b[vga.config.read_map_select]); + case 1: + VGA_Latch templatch; + templatch.d=(vga.latch.d & FillTable[vga.config.color_dont_care]) ^ FillTable[vga.config.color_compare & vga.config.color_dont_care]; + return (Bit8u)~(templatch.b[0] | templatch.b[1] | templatch.b[2] | templatch.b[3]); + } + return 0; + } public: Bitu readb(PhysPt addr) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - return VGA_NormalReadHandler(addr); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + return readHandler(addr); } Bitu readw(PhysPt addr) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; return - (VGA_NormalReadHandler(addr+0) << 0) | - (VGA_NormalReadHandler(addr+1) << 8); + (readHandler(addr+0) << 0) | + (readHandler(addr+1) << 8); } Bitu readd(PhysPt addr) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; return - (VGA_NormalReadHandler(addr+0) << 0) | - (VGA_NormalReadHandler(addr+1) << 8) | - (VGA_NormalReadHandler(addr+2) << 16) | - (VGA_NormalReadHandler(addr+3) << 24); + (readHandler(addr+0) << 0) | + (readHandler(addr+1) << 8) | + (readHandler(addr+2) << 16) | + (readHandler(addr+3) << 24); } }; -class VGAReadChain4_PageHandler : public PageHandler { +class VGA_Chained_ReadHandler : public PageHandler { +public: + Bitu readHandler(PhysPt addr) { + if(vga.mode == M_VGA) + return vga.mem.linear[((addr&~3)<<2)|(addr&3)]; + return vga.mem.linear[addr]; + } public: Bitu readb(PhysPt addr) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - return VGA_Chain4ReadHandler(addr); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + return readHandler(addr); } Bitu readw(PhysPt addr) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; return - (VGA_Chain4ReadHandler(addr+0) << 0) | - (VGA_Chain4ReadHandler(addr+1) << 8); + (readHandler(addr+0) << 0) | + (readHandler(addr+1) << 8); } Bitu readd(PhysPt addr) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; return - (VGA_Chain4ReadHandler(addr+0) << 0) | - (VGA_Chain4ReadHandler(addr+1) << 8) | - (VGA_Chain4ReadHandler(addr+2) << 16) | - (VGA_Chain4ReadHandler(addr+3) << 24); + (readHandler(addr+0) << 0) | + (readHandler(addr+1) << 8) | + (readHandler(addr+2) << 16) | + (readHandler(addr+3) << 24); } }; -class VGA_16_PageHandler : public VGARead_PageHandler { +class VGA_ChainedEGA_Handler : public VGA_Chained_ReadHandler { +public: + void writeHandler(PhysPt start, Bit8u val) { + Bit32u data=ModeOperation(val); + /* Update video memory and the pixel buffer */ + VGA_Latch pixels; + vga.mem.linear[start] = val; + start >>= 2; + pixels.d=vga.mem.latched[start].d; + + Bit8u * write_pixels=&vga.mem.linear[512*1024+(start<<3)]; + + Bit32u colors0_3, colors4_7; + VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f; + colors0_3 = + Expand16Table[0][temp.b[0]] | + Expand16Table[1][temp.b[1]] | + Expand16Table[2][temp.b[2]] | + Expand16Table[3][temp.b[3]]; + *(Bit32u *)write_pixels=colors0_3; + temp.d=pixels.d & 0x0f0f0f0f; + colors4_7 = + Expand16Table[0][temp.b[0]] | + Expand16Table[1][temp.b[1]] | + Expand16Table[2][temp.b[2]] | + Expand16Table[3][temp.b[3]]; + *(Bit32u *)(write_pixels+4)=colors4_7; + } public: - VGA_16_PageHandler() { + VGA_ChainedEGA_Handler() { flags=PFLAG_NOCODE; } void writeb(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_GFX_16_WriteHandler(addr+0,(Bit8u)(val >> 0)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_GFX_16_WriteHandler(addr+0,(Bit8u)(val >> 0)); - VGA_GFX_16_WriteHandler(addr+1,(Bit8u)(val >> 8)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_GFX_16_WriteHandler(addr+0,(Bit8u)(val >> 0)); - VGA_GFX_16_WriteHandler(addr+1,(Bit8u)(val >> 8)); - VGA_GFX_16_WriteHandler(addr+2,(Bit8u)(val >> 16)); - VGA_GFX_16_WriteHandler(addr+3,(Bit8u)(val >> 24)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); + writeHandler(addr+2,(Bit8u)(val >> 16)); + writeHandler(addr+3,(Bit8u)(val >> 24)); } }; -class VGA_16Chain4_PageHandler : public VGAReadChain4_PageHandler { +class VGA_UnchainedEGA_Handler : public VGA_UnchainedRead_Handler { +public: + void writeHandler(PhysPt start, Bit8u val) { + Bit32u data=ModeOperation(val); + /* Update video memory and the pixel buffer */ + VGA_Latch pixels; + pixels.d=vga.mem.latched[start].d; + pixels.d&=vga.config.full_not_map_mask; + pixels.d|=(data & vga.config.full_map_mask); + vga.mem.latched[start].d=pixels.d; + Bit8u * write_pixels=&vga.mem.linear[512*1024+(start<<3)]; + + Bit32u colors0_3, colors4_7; + VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f; + colors0_3 = + Expand16Table[0][temp.b[0]] | + Expand16Table[1][temp.b[1]] | + Expand16Table[2][temp.b[2]] | + Expand16Table[3][temp.b[3]]; + *(Bit32u *)write_pixels=colors0_3; + *(Bit32u *)(write_pixels+512*1024)=colors0_3; + temp.d=pixels.d & 0x0f0f0f0f; + colors4_7 = + Expand16Table[0][temp.b[0]] | + Expand16Table[1][temp.b[1]] | + Expand16Table[2][temp.b[2]] | + Expand16Table[3][temp.b[3]]; + *(Bit32u *)(write_pixels+4)=colors4_7; + *(Bit32u *)(write_pixels+512*1024+4)=colors4_7; + } public: - VGA_16Chain4_PageHandler() { + VGA_UnchainedEGA_Handler() { flags=PFLAG_NOCODE; } void writeb(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_GFX_16Chain4_WriteHandler(addr+0,(Bit8u)(val >> 0)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_GFX_16Chain4_WriteHandler(addr+0,(Bit8u)(val >> 0)); - VGA_GFX_16Chain4_WriteHandler(addr+1,(Bit8u)(val >> 8)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_GFX_16Chain4_WriteHandler(addr+0,(Bit8u)(val >> 0)); - VGA_GFX_16Chain4_WriteHandler(addr+1,(Bit8u)(val >> 8)); - VGA_GFX_16Chain4_WriteHandler(addr+2,(Bit8u)(val >> 16)); - VGA_GFX_16Chain4_WriteHandler(addr+3,(Bit8u)(val >> 24)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); + writeHandler(addr+2,(Bit8u)(val >> 16)); + writeHandler(addr+3,(Bit8u)(val >> 24)); } }; -class VGA_256_PageHandler : public VGARead_PageHandler { + +class VGA_ChainedVGA_Handler : public VGA_Chained_ReadHandler { +public: + void writeHandler(PhysPt addr, Bitu val) { + // No need to check for compatible chains here, this one is only enabled if that bit is set + vga.mem.linear[((addr&~3)<<2)|(addr&3)] = val; + // Linearized version for faster rendering + vga.mem.linear[512*1024+addr] = val; + // And replicate the first line + if (addr < 320) + vga.mem.linear[512*1024+addr+64*1024] = val; + } public: - VGA_256_PageHandler() { + VGA_ChainedVGA_Handler() { flags=PFLAG_NOCODE; } void writeb(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_GFX_256U_WriteHandler(addr+0,(Bit8u)(val >> 0)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_GFX_256U_WriteHandler(addr+0,(Bit8u)(val >> 0)); - VGA_GFX_256U_WriteHandler(addr+1,(Bit8u)(val >> 8)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_GFX_256U_WriteHandler(addr+0,(Bit8u)(val >> 0)); - VGA_GFX_256U_WriteHandler(addr+1,(Bit8u)(val >> 8)); - VGA_GFX_256U_WriteHandler(addr+2,(Bit8u)(val >> 16)); - VGA_GFX_256U_WriteHandler(addr+3,(Bit8u)(val >> 24)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); + writeHandler(addr+2,(Bit8u)(val >> 16)); + writeHandler(addr+3,(Bit8u)(val >> 24)); } }; -class VGA_256Chain4_PageHandler : public VGAReadChain4_PageHandler { -public: - VGA_256Chain4_PageHandler() { +class VGA_UnchainedVGA_Handler : public VGA_UnchainedRead_Handler { +public: + void writeHandler( PhysPt addr, Bit8u val ) { + Bit32u data=ModeOperation(val); + VGA_Latch pixels; + pixels.d=vga.mem.latched[addr].d; + pixels.d&=vga.config.full_not_map_mask; + pixels.d|=(data & vga.config.full_map_mask); + vga.mem.latched[addr].d=pixels.d; + vga.mem.latched[addr+64*1024].d=pixels.d; + } +public: + VGA_UnchainedVGA_Handler() { flags=PFLAG_NOCODE; } void writeb(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_Chain4WriteHandler(addr+0,(Bit8u)(val >> 0)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_Chain4WriteHandler(addr+0,(Bit8u)(val >> 0)); - VGA_Chain4WriteHandler(addr+1,(Bit8u)(val >> 8)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { - addr = PAGING_GetLinearAddress(addr) & 0xffff; - VGA_Chain4WriteHandler(addr+0,(Bit8u)(val >> 0)); - VGA_Chain4WriteHandler(addr+1,(Bit8u)(val >> 8)); - VGA_Chain4WriteHandler(addr+2,(Bit8u)(val >> 16)); - VGA_Chain4WriteHandler(addr+3,(Bit8u)(val >> 24)); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); + writeHandler(addr+2,(Bit8u)(val >> 16)); + writeHandler(addr+3,(Bit8u)(val >> 24)); } }; @@ -320,11 +318,11 @@ public: flags=PFLAG_NOCODE; } Bitu readb(PhysPt addr) { - addr = PAGING_GetLinearAddress(addr) & vgapages.mask; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; return vga.draw.font[addr]; } void writeb(PhysPt addr,Bitu val){ - addr = PAGING_GetLinearAddress(addr) & vgapages.mask; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; if (vga.seq.map_mask & 0x4) { vga.draw.font[addr]=(Bit8u)val; } @@ -336,22 +334,163 @@ public: VGA_MAP_PageHandler() { flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; } - HostPt GetHostPt(Bitu phys_page) { + HostPt GetHostReadPt(Bitu phys_page) { + phys_page-=vgapages.base; + return &vga.mem.linear[vga.s3.bank*64*1024+phys_page*4096]; + } + HostPt GetHostWritePt(Bitu phys_page) { phys_page-=vgapages.base; return &vga.mem.linear[vga.s3.bank*64*1024+phys_page*4096]; } }; -class VGA_MMIO_PageHandler : public PageHandler { + +class VGA_LIN4Linear_Handler : public VGA_UnchainedEGA_Handler { +public: + VGA_LIN4Linear_Handler() { + flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; + } + void writeb(PhysPt addr,Bitu val) { + addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1); + writeHandler(addr+0,(Bit8u)(val >> 0)); + } + void writew(PhysPt addr,Bitu val) { + addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1); + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); + } + void writed(PhysPt addr,Bitu val) { + addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1); + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); + writeHandler(addr+2,(Bit8u)(val >> 16)); + writeHandler(addr+3,(Bit8u)(val >> 24)); + } + Bitu readb(PhysPt addr) { + addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1); + return readHandler(addr); + } + Bitu readw(PhysPt addr) { + addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1); + return + (readHandler(addr+0) << 0) | + (readHandler(addr+1) << 8); + } + Bitu readd(PhysPt addr) { + addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1); + return + (readHandler(addr+0) << 0) | + (readHandler(addr+1) << 8) | + (readHandler(addr+2) << 16) | + (readHandler(addr+3) << 24); + } +}; + +class VGA_LIN4Banked_Handler : public VGA_UnchainedEGA_Handler { +public: + VGA_LIN4Banked_Handler() { + flags=PFLAG_NOCODE; + } + void writeb(PhysPt addr,Bitu val) { + addr = vga.s3.bank*64*1024 + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr &= (512*1024-1); + writeHandler(addr+0,(Bit8u)(val >> 0)); + } + void writew(PhysPt addr,Bitu val) { + addr = vga.s3.bank*64*1024 + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr &= (512*1024-1); + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); + } + void writed(PhysPt addr,Bitu val) { + addr = vga.s3.bank*64*1024 + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr &= (512*1024-1); + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); + writeHandler(addr+2,(Bit8u)(val >> 16)); + writeHandler(addr+3,(Bit8u)(val >> 24)); + } + Bitu readb(PhysPt addr) { + addr = vga.s3.bank*64*1024 + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr &= (512*1024-1); + return readHandler(addr); + } + Bitu readw(PhysPt addr) { + addr = vga.s3.bank*64*1024 + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr &= (512*1024-1); + return + (readHandler(addr+0) << 0) | + (readHandler(addr+1) << 8); + } + Bitu readd(PhysPt addr) { + addr = vga.s3.bank*64*1024 + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr &= (512*1024-1); + return + (readHandler(addr+0) << 0) | + (readHandler(addr+1) << 8) | + (readHandler(addr+2) << 16) | + (readHandler(addr+3) << 24); + } +}; + + +class VGA_LFBChanges_Handler : public PageHandler { +public: + VGA_LFBChanges_Handler() { + flags=PFLAG_NOCODE; + } + Bitu readb(PhysPt addr) { + addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + return *(Bit8u*)(&vga.mem.linear[addr]); + } + Bitu readw(PhysPt addr) { + addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + return *(Bit16u*)(&vga.mem.linear[addr]); + } + Bitu readd(PhysPt addr) { + addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + return *(Bit32u*)(&vga.mem.linear[addr]); + } + void writeb(PhysPt addr,Bitu val) { + addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + *(Bit8u*)(&vga.mem.linear[addr]) = val; + vga.changed[addr >> VGA_CHANGE_SHIFT] = 1; + } + void writew(PhysPt addr,Bitu val) { + addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + *(Bit16u*)(&vga.mem.linear[addr]) = val; + vga.changed[addr >> VGA_CHANGE_SHIFT] = 1; + } + void writed(PhysPt addr,Bitu val) { + addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + *(Bit32u*)(&vga.mem.linear[addr]) = val; + vga.changed[addr >> VGA_CHANGE_SHIFT] = 1; + } +}; + +class VGA_LFB_Handler : public PageHandler { +public: + VGA_LFB_Handler() { + flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; + } + HostPt GetHostReadPt( Bitu phys_page ) { + phys_page -= vga.lfb.page; + return &vga.mem.linear[phys_page * 4096]; + } + HostPt GetHostWritePt( Bitu phys_page ) { + return GetHostReadPt( phys_page ); + } +}; + +class VGA_MMIO_Handler : public PageHandler { public: Bit16u regmem[16384]; - - VGA_MMIO_PageHandler() { + VGA_MMIO_Handler() { flags=PFLAG_NOCODE; //memset(®mem[0], 0, sizeof(regmem)); } void writeb(PhysPt addr,Bitu val) { - Bitu port = PAGING_GetLinearAddress(addr) & 0xffff; + Bitu port = PAGING_GetPhysicalAddress(addr) & 0xffff; if(port >= 0x82E8) IO_WriteB(port, val); if(port <= 0x4000) { if(port == 0x0000) { @@ -363,7 +502,7 @@ public: //LOG_MSG("MMIO: Write byte to %x with %x", addr, val); } void writew(PhysPt addr,Bitu val) { - Bitu port = PAGING_GetLinearAddress(addr) & 0xffff; + Bitu port = PAGING_GetPhysicalAddress(addr) & 0xffff; if(port >= 0x82E8) IO_WriteW(port, val); if(port == 0x8118) IO_WriteW(0x9ae8, val); if(port <= 0x4000) { @@ -376,7 +515,7 @@ public: //LOG_MSG("MMIO: Write word to %x with %x", addr, val); } void writed(PhysPt addr,Bitu val) { - Bitu port = PAGING_GetLinearAddress(addr) & 0xffff; + Bitu port = PAGING_GetPhysicalAddress(addr) & 0xffff; if(port >= 0x82E8) IO_WriteD(port, val); if(port == 0x8100) { IO_WriteW(0x86e8, (val >> 16)); @@ -391,9 +530,9 @@ public: IO_WriteW(0xe2e0, (val & 0xffff)); IO_WriteW(0xe2e8, (val >> 16)); } else { - IO_WriteW(0xe2e8, (val & 0xffff)); - IO_WriteW(0xe2e8, (val >> 16)); - } + IO_WriteW(0xe2e8, (val & 0xffff)); + IO_WriteW(0xe2e8, (val >> 16)); + } } //LOG_MSG("MMIO: Write dword to %x with %x", addr, val); @@ -405,7 +544,7 @@ public: return 0x00; } Bitu readw(PhysPt addr) { - Bitu port = PAGING_GetLinearAddress(addr) & 0xffff; + Bitu port = PAGING_GetPhysicalAddress(addr) & 0xffff; if(port >= 0x82E8) return IO_ReadW(port); //LOG_MSG("MMIO: Read word from %x", addr); return 0x00; @@ -423,7 +562,7 @@ public: flags=PFLAG_READABLE|PFLAG_WRITEABLE; // |PFLAG_NOCODE; } - HostPt GetHostPt(Bitu phys_page) { + HostPt GetHostReadPt(Bitu phys_page) { if (phys_page>=0xb8) { phys_page-=0xb8; return &vga.mem.linear[(vga.tandy.mem_bank << 14)+(phys_page * 4096)]; @@ -432,6 +571,9 @@ public: return &vga.mem.linear[phys_page * 4096]; } } + HostPt GetHostWritePt(Bitu phys_page) { + return GetHostReadPt( phys_page ); + } }; class VGA_PCJR_PageHandler : public PageHandler { @@ -439,24 +581,31 @@ public: VGA_PCJR_PageHandler() { flags=PFLAG_READABLE|PFLAG_WRITEABLE; } - HostPt GetHostPt(Bitu phys_page) { + HostPt GetHostReadPt(Bitu phys_page) { phys_page-=0xb8; if (!vga.tandy.is_32k_mode) phys_page&=0x03; return MemBase+(vga.tandy.mem_bank << 14)+(phys_page * 4096); } + HostPt GetHostWritePt(Bitu phys_page) { + return GetHostReadPt( phys_page ); + } }; static struct vg { - VGA_MAP_PageHandler hmap; - VGA_TEXT_PageHandler htext; - VGA_TANDY_PageHandler htandy; - VGA_PCJR_PageHandler hpcjr; - VGA_256_PageHandler h256; - VGA_256Chain4_PageHandler h256c4; - VGA_16_PageHandler h16; - VGA_16Chain4_PageHandler h16c4; - VGA_MMIO_PageHandler mmio; + VGA_MAP_PageHandler map; + VGA_TEXT_PageHandler text; + VGA_TANDY_PageHandler tandy; + VGA_ChainedEGA_Handler cega; + VGA_ChainedVGA_Handler cvga; + VGA_UnchainedEGA_Handler uega; + VGA_UnchainedVGA_Handler uvga; + VGA_PCJR_PageHandler hpcjr; + VGA_LIN4Banked_Handler l4banked; + VGA_LIN4Linear_Handler l4linear; + VGA_LFB_Handler lfb; + VGA_LFBChanges_Handler lfbchanges; + VGA_MMIO_Handler mmio; } vgaph; @@ -464,14 +613,14 @@ void VGA_SetupHandlers(void) { PageHandler * range_handler; switch (machine) { case MCH_CGA: - range_handler=&vgaph.hmap; + range_handler=&vgaph.map; goto range_b800; case MCH_HERC: - range_handler=&vgaph.hmap; + range_handler=&vgaph.map; if (vga.herc.mode_control&0x80) goto range_b800; else goto range_b000; case MCH_TANDY: - range_handler=&vgaph.htandy; + range_handler=&vgaph.tandy; MEM_SetPageHandler(0x80,32,range_handler); goto range_b800; case MCH_PCJR: @@ -482,31 +631,39 @@ void VGA_SetupHandlers(void) { switch (vga.mode) { case M_ERROR: return; + case M_LIN4: + range_handler=&vgaph.l4banked; + break; case M_LIN8: - range_handler=&vgaph.hmap; + case M_LIN15: + case M_LIN16: + case M_LIN32: + range_handler=&vgaph.map; break; case M_VGA: if (vga.config.chained) { if(vga.config.compatible_chain4) - range_handler = &vgaph.h256c4; + range_handler = &vgaph.cvga; else - range_handler=&vgaph.hmap; + range_handler=&vgaph.map; } else { - range_handler=&vgaph.h256; + range_handler=&vgaph.uvga; } break; - case M_EGA16: - if (vga.config.chained) range_handler=&vgaph.h16c4; - else range_handler=&vgaph.h16; + case M_EGA: + if (vga.config.chained) + range_handler=&vgaph.cega; + else + range_handler=&vgaph.uega; break; case M_TEXT: /* Check if we're not in odd/even mode */ - if (vga.gfx.miscellaneous & 0x2) range_handler=&vgaph.hmap; - else range_handler=&vgaph.htext; + if (vga.gfx.miscellaneous & 0x2) range_handler=&vgaph.map; + else range_handler=&vgaph.text; break; case M_CGA4: case M_CGA2: - range_handler=&vgaph.hmap; + range_handler=&vgaph.map; break; } switch ((vga.gfx.miscellaneous >> 2) & 3) { @@ -539,28 +696,28 @@ range_b800: break; } - if(((vga.s3.ext_mem_ctrl & 0x10) != 0x00) && (vga.mode == M_LIN8)) MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio); + if(((vga.s3.ext_mem_ctrl & 0x10) != 0x00) && (vga.mode == M_LIN8)) + MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio); PAGING_ClearTLB(); } -static bool lfb_update; - -static void VGA_DoUpdateLFB(Bitu val) { - lfb_update=false; - MEM_SetLFB(vga.s3.la_window << 4 ,sizeof(vga.mem.linear)/4096,&vga.mem.linear[0]); -} - void VGA_StartUpdateLFB(void) { - if (!lfb_update) { - lfb_update=true; - PIC_AddEvent(VGA_DoUpdateLFB,0.100f); //100 microseconds later + vga.lfb.page = vga.s3.la_window << 4; + vga.lfb.addr = vga.s3.la_window << 16; + switch (vga.mode) { + case M_LIN4: + vga.lfb.handler = &vgaph.l4linear; + break; + default: + vga.lfb.handler = &vgaph.lfbchanges; + break; } + MEM_SetLFB(vga.s3.la_window << 4 ,sizeof(vga.mem.linear)/4096, vga.lfb.handler ); } void VGA_MapMMIO(void) { MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio); - } void VGA_UnmapMMIO(void) { diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index c63c53b2..3cefa5aa 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -23,12 +23,12 @@ static Bit8u flip=0; -void write_p3d4_vga(Bitu port,Bitu val,Bitu iolen); -Bitu read_p3d4_vga(Bitu port,Bitu iolen); -void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen); -Bitu read_p3d5_vga(Bitu port,Bitu iolen); +void vga_write_p3d4(Bitu port,Bitu val,Bitu iolen); +Bitu vga_read_p3d4(Bitu port,Bitu iolen); +void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen); +Bitu vga_read_p3d5(Bitu port,Bitu iolen); -static Bitu read_p3da(Bitu port,Bitu iolen) { +static Bitu vga_read_p3da(Bitu port,Bitu iolen) { vga.internal.attrindex=false; vga.tandy.pcjr_flipflop=false; if (vga.config.retrace) { @@ -53,23 +53,26 @@ static Bitu read_p3da(Bitu port,Bitu iolen) { static void write_p3c2(Bitu port,Bitu val,Bitu iolen) { vga.misc_output=val; if (val & 0x1) { - IO_RegisterWriteHandler(0x3d4,write_p3d4_vga,IO_MB); - IO_RegisterReadHandler(0x3d4,read_p3d4_vga,IO_MB); - IO_RegisterWriteHandler(0x3d5,write_p3d5_vga,IO_MB); - IO_RegisterReadHandler(0x3d5,read_p3d5_vga,IO_MB); - IO_RegisterReadHandler(0x3da,read_p3da,IO_MB); - + IO_RegisterWriteHandler(0x3d4,vga_write_p3d4,IO_MB); + IO_RegisterReadHandler(0x3d4,vga_read_p3d4,IO_MB); + IO_RegisterReadHandler(0x3da,vga_read_p3da,IO_MB); + + IO_RegisterWriteHandler(0x3d5,vga_write_p3d5,IO_MB); + IO_RegisterReadHandler(0x3d5,vga_read_p3d5,IO_MB); + IO_FreeWriteHandler(0x3b4,IO_MB); IO_FreeReadHandler(0x3b4,IO_MB); IO_FreeWriteHandler(0x3b5,IO_MB); IO_FreeReadHandler(0x3b5,IO_MB); IO_FreeReadHandler(0x3ba,IO_MB); } else { - IO_RegisterWriteHandler(0x3b4,write_p3d4_vga,IO_MB); - IO_RegisterReadHandler(0x3b4,read_p3d4_vga,IO_MB); - IO_RegisterWriteHandler(0x3b5,write_p3d5_vga,IO_MB); - IO_RegisterReadHandler(0x3b5,read_p3d5_vga,IO_MB); - IO_RegisterReadHandler(0x3ba,read_p3da,IO_MB); + IO_RegisterWriteHandler(0x3b4,vga_write_p3d4,IO_MB); + IO_RegisterReadHandler(0x3b4,vga_read_p3d4,IO_MB); + IO_RegisterReadHandler(0x3ba,vga_read_p3da,IO_MB); + + IO_RegisterWriteHandler(0x3b5,vga_write_p3d5,IO_MB); + IO_RegisterReadHandler(0x3b5,vga_read_p3d5,IO_MB); + IO_FreeWriteHandler(0x3d4,IO_MB); IO_FreeReadHandler(0x3d4,IO_MB); @@ -121,9 +124,9 @@ void VGA_SetupMisc(void) { IO_RegisterWriteHandler(0x3c2,write_p3c2,IO_MB); IO_RegisterReadHandler(0x3cc,read_p3cc,IO_MB); } else if (machine==MCH_CGA || IS_TANDY_ARCH) { - IO_RegisterReadHandler(0x3da,read_p3da,IO_MB); + IO_RegisterReadHandler(0x3da,vga_read_p3da,IO_MB); } else if (machine==MCH_HERC) { - IO_RegisterReadHandler(0x3ba,read_p3da,IO_MB); + IO_RegisterReadHandler(0x3ba,vga_read_p3da,IO_MB); } } diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp new file mode 100644 index 00000000..b54400a0 --- /dev/null +++ b/src/hardware/vga_s3.cpp @@ -0,0 +1,432 @@ +/* + * Copyright (C) 2002-2005 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" +#include "inout.h" +#include "vga.h" + +void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { + switch (reg) { + case 0x31: /* CR31 Memory Configuration */ +//TODO Base address + vga.s3.reg_31 = val; + VGA_DetermineMode(); + break; + /* + 0 Enable Base Address Offset (CPUA BASE). Enables bank operation if + set, disables if clear. + 1 Two Page Screen Image. If set enables 2048 pixel wide screen setup + 2 VGA 16bit Memory Bus Width. Set for 16bit, clear for 8bit + 3 Use Enhanced Mode Memory Mapping (ENH MAP). Set to enable access to + video memory above 256k. + 4-5 Bit 16-17 of the Display Start Address. For the 801/5,928 see index + 51h, for the 864/964 see index 69h. + 6 High Speed Text Display Font Fetch Mode. If set enables Page Mode + for Alpha Mode Font Access. + 7 (not 864/964) Extended BIOS ROM Space Mapped out. If clear the area + C6800h-C7FFFh is mapped out, if set it is accessible. + */ + case 0x35: /* CR35 CRT Register Lock */ + if (vga.s3.reg_lock1 != 0x48) return; //Needed for uvconfig detection + vga.s3.reg_35=val & 0xf0; + if ((vga.s3.bank & 0xf) ^ (val & 0xf)) { + vga.s3.bank&=0xf0; + vga.s3.bank|=val & 0xf; + VGA_SetupHandlers(); + } + break; + /* + 0-3 CPU Base Address. 64k bank number. For the 801/5 and 928 see 3d4h + index 51h bits 2-3. For the 864/964 see index 6Ah. + 4 Lock Vertical Timing Registers (LOCK VTMG). Locks 3d4h index 6, 7 + (bits 0,2,3,5,7), 9 bit 5, 10h, 11h bits 0-3, 15h, 16h if set + 5 Lock Horizontal Timing Registers (LOCK HTMG). Locks 3d4h index + 0,1,2,3,4,5,17h bit 2 if set + 6 (911/924) Lock VSync Polarity. + 7 (911/924) Lock HSync Polarity. + */ + case 0x38: /* CR38 Register Lock 1 */ + vga.s3.reg_lock1=val; + break; + case 0x39: /* CR39 Register Lock 2 */ + vga.s3.reg_lock2=val; + break; + case 0x40: /* CR40 System Config */ + vga.s3.reg_40 = val; + break; + case 0x43: /* CR43 Extended Mode */ + vga.s3.reg_43=val & ~0x4; + if (((val & 0x4) ^ (vga.config.scan_len >> 6)) & 0x4) { + vga.config.scan_len&=0x2ff; + vga.config.scan_len|=(val & 0x4) << 6; + VGA_CheckScanLength(); + } + break; + /* + 2 Logical Screen Width bit 8. Bit 8 of the Display Offset Register/ + (3d4h index 13h). (801/5,928) Only active if 3d4h index 51h bits 4-5 + are 0 + */ + case 0x45: /* Hardware cursor mode */ + vga.s3.hgc.curmode = val; + // Activate hardware cursor code if needed + VGA_ActivateHardwareCursor(); + break; + case 0x46: + vga.s3.hgc.originx = (vga.s3.hgc.originx & 0x00ff) | (val << 8); + break; + case 0x47: /* HGC orgX */ + vga.s3.hgc.originx = (vga.s3.hgc.originx & 0xff00) | val; + break; + case 0x48: + vga.s3.hgc.originy = (vga.s3.hgc.originy & 0x00ff) | (val << 8); + break; + case 0x49: /* HGC orgY */ + vga.s3.hgc.originy = (vga.s3.hgc.originy & 0xff00) | val; + break; + case 0x4A: /* HGC foreground stack */ + if (vga.s3.hgc.fstackpos > 2) vga.s3.hgc.fstackpos = 0; + vga.s3.hgc.forestack[vga.s3.hgc.fstackpos] = val; + vga.s3.hgc.fstackpos++; + break; + case 0x4B: /* HGC background stack */ + if (vga.s3.hgc.bstackpos > 2) vga.s3.hgc.bstackpos = 0; + vga.s3.hgc.backstack[vga.s3.hgc.bstackpos] = val; + vga.s3.hgc.bstackpos++; + break; + case 0x4c: /* HGC start address high byte*/ + vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | ((val & 0xff) << 8); + break; + case 0x4d: /* HGC start address low byte*/ + vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | (val & 0xff); + break; + case 0x4e: /* HGC pattern start X */ + vga.s3.hgc.posx = val; + break; + case 0x4f: /* HGC pattern start X */ + vga.s3.hgc.posy = val; + break; + case 0x51: /* Extended System Control 2 */ + vga.s3.reg_51=val & 0xc0; //Only store bits 6,7 + //TODO Display start + vga.config.display_start&=0xFCFFFF; + vga.config.display_start|=(val & 3) << 16; + if ((vga.s3.bank&0xcf) ^ ((val&0xc)<<2)) { + vga.s3.bank&=0xcf; + vga.s3.bank|=(val&0xc)<<2; + VGA_SetupHandlers(); + } + if (((val & 0x30) ^ (vga.config.scan_len >> 4)) & 0x30) { + vga.config.scan_len&=0xff; + vga.config.scan_len|=(val & 0x30) << 4; + VGA_CheckScanLength(); + } + break; + /* + 0 (80x) Display Start Address bit 18 + 0-1 (928 +) Display Start Address bit 18-19 + Bits 16-17 are in index 31h bits 4-5, Bits 0-15 are in 3d4h index + 0Ch,0Dh. For the 864/964 see 3d4h index 69h + 2 (80x) CPU BASE. CPU Base Address Bit 18. + 2-3 (928 +) Old CPU Base Address Bits 19-18. + 64K Bank register bits 4-5. Bits 0-3 are in 3d4h index 35h. + For the 864/964 see 3d4h index 6Ah + 4-5 Logical Screen Width Bit [8-9]. Bits 8-9 of the CRTC Offset register + (3d4h index 13h). If this field is 0, 3d4h index 43h bit 2 is active + 6 (928,964) DIS SPXF. Disable Split Transfers if set. Spilt Transfers + allows transferring one half of the VRAM shift register data while + the other half is being output. For the 964 Split Transfers + must be enabled in enhanced modes (4AE8h bit 0 set). Guess: They + probably can't time the VRAM load cycle closely enough while the + graphics engine is running. + 7 (not 864/964) Enable EPROM Write. If set enables flash memory write + control to the BIOS ROM address + */ + case 0x53: + if((val & 0x10) != (vga.s3.ext_mem_ctrl & 0x10)) { + /* Map or unmap MMIO */ + if ((val & 0x10) != 0) { + //LOG_MSG("VGA: Mapping Memory Mapped I/O to 0xA0000"); +// VGA_MapMMIO(); + } else { +// VGA_UnmapMMIO(); + } + } + vga.s3.ext_mem_ctrl = val; + break; + case 0x55: /* Extended Video DAC Control */ + vga.s3.reg_55=val; + break; + /* + 0-1 DAC Register Select Bits. Passed to the RS2 and RS3 pins on the + RAMDAC, allowing access to all 8 or 16 registers on advanced RAMDACs. + If this field is 0, 3d4h index 43h bit 1 is active. + 2 Enable General Input Port Read. If set DAC reads are disabled and the + STRD strobe for reading the General Input Port is enabled for reading + while DACRD is active, if clear DAC reads are enabled. + 3 (928) Enable External SID Operation if set. If set video data is + passed directly from the VRAMs to the DAC rather than through the + VGA chip + 4 Hardware Cursor MS/X11 Mode. If set the Hardware Cursor is in X11 + mode, if clear in MS-Windows mode + 5 (80x,928) Hardware Cursor External Operation Mode. If set the two + bits of cursor data ,is output on the HC[0-1] pins for the video DAC + The SENS pin becomes HC1 and the MID2 pin becomes HC0. + 6 ?? + 7 (80x,928) Disable PA Output. If set PA[0-7] and VCLK are tristated. + (864/964) TOFF VCLK. Tri-State Off VCLK Output. VCLK output tri + -stated if set + */ + case 0x58: /* Linear Address Window Control */ + vga.s3.reg_58=val; + break; + /* + 0-1 Linear Address Window Size. Must be less than or equal to video + memory size. 0: 64K, 1: 1MB, 2: 2MB, 3: 4MB (928)/8Mb (864/964) + 2 (not 864/964) Enable Read Ahead Cache if set + 3 (80x,928) ISA Latch Address. If set latches address during every ISA + cycle, unlatches during every ISA cycle if clear. + (864/964) LAT DEL. Address Latch Delay Control (VL-Bus only). If set + address latching occours in the T1 cycle, if clear in the T2 cycle + (I.e. one clock cycle delayed). + 4 ENB LA. Enable Linear Addressing if set. + 5 (not 864/964) Limit Entry Depth for Write-Post. If set limits Write + -Post Entry Depth to avoid ISA bus timeout due to wait cycle limit. + 6 (928,964) Serial Access Mode (SAM) 256 Words Control. If set SAM + control is 256 words, if clear 512 words. + 7 (928) RAS 6-MCLK. If set the random read/write cycle time is 6MCLKs, + if clear 7MCLKs + */ + case 0x59: /* Linear Address Window Position High */ + if ((vga.s3.la_window&0xff00) ^ (val << 8)) { + vga.s3.la_window=(vga.s3.la_window&0x00ff) | (val << 8); + VGA_StartUpdateLFB(); + } + break; + case 0x5a: /* Linear Address Window Position Low */ + if ((vga.s3.la_window&0x00ff) ^ val) { + vga.s3.la_window=(vga.s3.la_window&0xff00) | val; + VGA_StartUpdateLFB(); + } + break; + case 0x5D: /* Extended Horizontal Overflow */ + if ((val & vga.s3.ex_hor_overflow) ^ 3) { + vga.s3.ex_hor_overflow=val; + VGA_StartResize(); + } else vga.s3.ex_hor_overflow=val; + break; + /* + 0 Horizontal Total bit 8. Bit 8 of the Horizontal Total register (3d4h + index 0) + 1 Horizontal Display End bit 8. Bit 8 of the Horizontal Display End + register (3d4h index 1) + 2 Start Horizontal Blank bit 8. Bit 8 of the Horizontal Start Blanking + register (3d4h index 2). + 3 (864,964) EHB+64. End Horizontal Blank +64. If set the /BLANK pulse + is extended by 64 DCLKs. Note: Is this bit 6 of 3d4h index 3 or + does it really extend by 64 ? + 4 Start Horizontal Sync Position bit 8. Bit 8 of the Horizontal Start + Retrace register (3d4h index 4). + 5 (864,964) EHS+32. End Horizontal Sync +32. If set the HSYNC pulse + is extended by 32 DCLKs. Note: Is this bit 5 of 3d4h index 5 or + does it really extend by 32 ? + 6 (928,964) Data Transfer Position bit 8. Bit 8 of the Data Transfer + Position register (3d4h index 3Bh) + 7 (928,964) Bus-Grant Terminate Position bit 8. Bit 8 of the Bus Grant + Termination register (3d4h index 5Fh). + */ + case 0x5e: /* Extended Vertical Overflow */ + vga.config.line_compare=(vga.config.line_compare & 0x3ff) | (val & 0x40) << 4; + if ((val ^ vga.s3.ex_ver_overflow) & 0x3) { + vga.s3.ex_ver_overflow=val; + VGA_StartResize(); + } else vga.s3.ex_ver_overflow=val; + break; + /* + 0 Vertical Total bit 10. Bit 10 of the Vertical Total register (3d4h + index 6). Bits 8 and 9 are in 3d4h index 7 bit 0 and 5. + 1 Vertical Display End bit 10. Bit 10 of the Vertical Display End + register (3d4h index 12h). Bits 8 and 9 are in 3d4h index 7 bit 1 + and 6 + 2 Start Vertical Blank bit 10. Bit 10 of the Vertical Start Blanking + register (3d4h index 15h). Bit 8 is in 3d4h index 7 bit 3 and bit 9 + in 3d4h index 9 bit 5 + 4 Vertical Retrace Start bit 10. Bit 10 of the Vertical Start Retrace + register (3d4h index 10h). Bits 8 and 9 are in 3d4h index 7 bit 2 + and 7. + 6 Line Compare Position bit 10. Bit 10 of the Line Compare register + (3d4h index 18h). Bit 8 is in 3d4h index 7 bit 4 and bit 9 in 3d4h + index 9 bit 6. + */ + case 0x67: /* Extended Miscellaneous Control 2 */ + /* + 0 VCLK PHS. VCLK Phase With Respect to DCLK. If clear VLKC is inverted + DCLK, if set VCLK = DCLK. + 4-7 Pixel format. + 0 Mode 0: 8bit (1 pixel/VCLK) + 1 Mode 8: 8bit (2 pixels/VCLK) + 3 Mode 9: 15bit (1 pixel/VCLK) + 5 Mode 10: 16bit (1 pixel/VCLK) + 7 Mode 11: 24/32bit (2 VCLKs/pixel) + 13 (732/764) 32bit (1 pixel/VCLK) + */ + vga.s3.misc_control_2=val; + VGA_DetermineMode(); + break; + case 0x69: /* Extended System Control 3 */ + if (((vga.config.display_start & 0x1f0000)>>16) ^ (val & 0x1f)) { + vga.config.display_start&=0xffff; + vga.config.display_start|=(val & 0x1f) << 16; + } + break; + case 0x6a: /* Extended System Control 4 */ + vga.s3.bank=val & 0x3f; + VGA_SetupHandlers(); + break; + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:Write to illegal index %2X", reg ); + break; + } +} + +Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { + switch (reg) { + case 0x2d: /* Extended Chip ID. */ + return 0x88; + // Always 88h ? + case 0x2e: /* New Chip ID */ + return 0x11; + //Trio 64 id + case 0x2f: /* Revision */ + return 0x00; + case 0x30: /* CR30 Chip ID/REV register */ + return 0xe0; //Trio+ dual byte + // Trio32/64 has 0xe0. extended + case 0x31: /* CR31 Memory Configuration */ +//TODO mix in bits from baseaddress; + return vga.s3.reg_31; + case 0x35: /* CR35 CRT Register Lock */ + return vga.s3.reg_35|(vga.s3.bank & 0xf); + case 0x36: /* CR36 Reset State Read 1 */ + //return 0x8f; + return 0x8e; /* PCI version */ + //2 Mb PCI and some bios settings + case 0x37: /* Reset state read 2 */ + return 0x2b; + case 0x38: /* CR38 Register Lock 1 */ + return vga.s3.reg_lock1; + case 0x39: /* CR39 Register Lock 2 */ + return vga.s3.reg_lock2; + case 0x40: /* CR40 system config */ + return vga.s3.reg_40; + case 0x43: /* CR43 Extended Mode */ + return vga.s3.reg_43|((vga.config.scan_len>>6)&0x4); + case 0x45: /* Hardware cursor mode */ + vga.s3.hgc.bstackpos = 0; + vga.s3.hgc.fstackpos = 0; + return vga.s3.hgc.curmode; + case 0x51: /* Extended System Control 2 */ + return ((vga.config.display_start >> 16) & 3 ) | + ((vga.s3.bank & 0x30) >> 2) | + ((vga.config.scan_len & 0x300) >> 4) | + vga.s3.reg_51; + case 0x53: + return vga.s3.ext_mem_ctrl; + case 0x55: /* Extended Video DAC Control */ + return vga.s3.reg_55; + case 0x58: /* Linear Address Window Control */ + return vga.s3.reg_58; + case 0x59: /* Linear Address Window Position High */ + return (vga.s3.la_window >> 8); + case 0x5a: /* Linear Address Window Position Low */ + return (vga.s3.la_window & 0xff); + case 0x5D: /* Extended Horizontal Overflow */ + return vga.s3.ex_hor_overflow; + case 0x5e: /* Extended Vertical Overflow */ + return vga.s3.ex_ver_overflow; + case 0x67: /* Extended Miscellaneous Control 2 */ + return vga.s3.misc_control_2; + case 0x69: /* Extended System Control 3 */ + return (Bit8u)((vga.config.display_start & 0x1f0000)>>16); + case 0x6a: /* Extended System Control 4 */ + return (Bit8u)(vga.s3.bank & 0x3f); + default: + return 0x00; + } +} + +void SVGA_S3_WriteSEQ(Bitu reg,Bitu val,Bitu iolen) { + switch (reg) { + case 0x08: + vga.s3.pll.lock=val; + break; + case 0x10: /* Memory PLL Data Low */ + vga.s3.mclk.n=val & 0x1f; + vga.s3.mclk.r=val >> 5; + break; + case 0x11: /* Memory PLL Data High */ + vga.s3.mclk.m=val & 0x7f; + break; + case 0x12: /* Video PLL Data Low */ + vga.s3.clk[3].n=val & 0x1f; + vga.s3.clk[3].r=val >> 5; + break; + case 0x13: /* Video PLL Data High */ + vga.s3.clk[3].m=val & 0x7f; + break; + case 0x15: + vga.s3.pll.cmd=val; + VGA_StartResize(); + break; + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:S3:SEQ:Write to illegal index %2X", reg ); + break; + } +} + +Bitu SVGA_S3_ReadSEQ(Bitu reg,Bitu iolen) { + /* S3 specific group */ + switch (reg) { + case 0x08: /* PLL Unlock */ + return vga.s3.pll.lock; + case 0x10: /* Memory PLL Data Low */ + return vga.s3.mclk.n || (vga.s3.mclk.r << 5); + case 0x11: /* Memory PLL Data High */ + return vga.s3.mclk.m; + case 0x12: /* Video PLL Data Low */ + return vga.s3.clk[3].n || (vga.s3.clk[3].r << 5); + case 0x13: /* Video Data High */ + return vga.s3.clk[3].m; + case 0x15: + return vga.s3.pll.cmd; + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:S3:SEQ:Read from illegal index %2X", reg); + return 0; + } +} + +Bitu SVGA_S3_GetClock(void) { + Bitu clock = (vga.misc_output >> 2) & 3; + if (clock == 0) + clock = 25175000; + else if (clock == 1) + clock = 28322000; + else + clock=1000*S3_CLOCK(vga.s3.clk[clock].m,vga.s3.clk[clock].n,vga.s3.clk[clock].r); + return clock; +} \ No newline at end of file diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index e001ea9a..6015d0ef 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -98,33 +98,16 @@ void write_p3c5(Bitu port,Bitu val,Bitu iolen) { else vga.config.chained=false; VGA_SetupHandlers(); break; -/* S3 specific group */ - case 0x08: - vga.s3.pll.lock=val; - break; - case 0x10: /* Memory PLL Data Low */ - vga.s3.mclk.n=val & 0x1f; - vga.s3.mclk.r=val >> 5; - break; - case 0x11: /* Memory PLL Data High */ - vga.s3.mclk.m=val & 0x7f; - break; - case 0x12: /* Video PLL Data Low */ - vga.s3.clk[3].n=val & 0x1f; - vga.s3.clk[3].r=val >> 5; - break; - case 0x13: /* Video PLL Data High */ - vga.s3.clk[3].m=val & 0x7f; - break; - case 0x15: - vga.s3.pll.cmd=val; - VGA_StartResize(); - break; - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:Write to illegal index %2X",seq(index)); - }; -}; + switch (svgaCard) { + case SVGA_S3Trio: + SVGA_S3_WriteSEQ( seq(index), val, iolen ); + break; + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:Write to illegal index %2X",seq(index)); + } + } +} Bitu read_p3c5(Bitu port,Bitu iolen) { @@ -145,25 +128,14 @@ Bitu read_p3c5(Bitu port,Bitu iolen) { break; case 4: /* Memory Mode */ return seq(memory_mode); - /* S3 specific group */ - case 0x08: /* PLL Unlock */ - return vga.s3.pll.lock; - case 0x10: /* Memory PLL Data Low */ - return vga.s3.mclk.n || (vga.s3.mclk.r << 5); - case 0x11: /* Memory PLL Data High */ - return vga.s3.mclk.m; - case 0x12: /* Video PLL Data Low */ - return vga.s3.clk[3].n || (vga.s3.clk[3].r << 5); - case 0x13: /* Video Data High */ - return vga.s3.clk[3].m; - case 0x15: - return vga.s3.pll.cmd; - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:Read from illegal index %2X",seq(index)); - }; + switch (svgaCard) { + case SVGA_S3Trio: + return SVGA_S3_ReadSEQ( seq(index), iolen ); + } + } return 0; -}; +} void VGA_SetupSEQ(void) { diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index f600dda7..1fe0c121 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -35,8 +35,8 @@ struct XGAStatus { Bit32u readmask; Bit32u writemask; - Bit32u forecolor; - Bit32u backcolor; + Bit8u forecolor; + Bit8u backcolor; Bitu curcommand; @@ -189,7 +189,7 @@ void XGA_DrawLineVector(Bitu val) { Bit8u dstdata; Bits i; - Bits dx, sx, dy, sy, e; + Bits dx, sx, sy; dx = xga.MAPcount; xat = xga.curx; @@ -487,7 +487,7 @@ void XGA_DrawWait(Bitu val, Bitu len) { switch(mixmode) { case 0x00: /* FOREMIX always used */ mixmode = xga.foremix; - int t; + Bitu t; for(t=0;t> (8 * t)) & 0xff; switch((mixmode >> 5) & 0x03) { @@ -616,7 +616,7 @@ void XGA_DrawWait(Bitu val, Bitu len) { void XGA_BlitRect(Bitu val) { Bit32u xat, yat; - Bit32u xmass, xmod, xdist, memrec; +// Bit32u xmass, xmod, xdist, memrec; //Bit8u *srcptr; //Bit8u *destptr; //Bit8u *destline; From b45c282867680a6704492907307752fc7c5e04de Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 10:04:20 +0000 Subject: [PATCH 2363/4131] Avi capturing with zmbv codec Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2447 --- src/hardware/hardware.cpp | 620 +++++++++++++++++++++++++++++++++++++- src/hardware/mixer.cpp | 80 ++--- 2 files changed, 631 insertions(+), 69 deletions(-) diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 9b013c1e..9fb07c5d 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -15,20 +15,66 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* - This could do with a serious revision :) -*/ - #include #include +#include +#include #include "dosbox.h" #include "hardware.h" #include "setup.h" #include "support.h" +#include "mem.h" +#include "mapper.h" +#include "pic.h" +#include "render.h" + +#if (C_SSHOT) +#include +#include "../libs/zmbv/zmbv.h" +#endif static char * capturedir; extern char * RunningProgram; +Bitu CaptureState; + +#define WAVE_BUF 16*1024 +#define MIDI_BUF 4*1024 +#define AVI_HEADER_SIZE 500 + +static struct { + struct { + FILE * handle; + Bit16s buf[WAVE_BUF][2]; + Bitu used; + Bit32u length; + Bit32u freq; + } wave; + struct { + FILE * handle; + Bit8u buffer[MIDI_BUF]; + Bitu used,done; + Bit32u last; + } midi; + struct { + Bitu rowlen; + } image; + struct { + FILE *handle; + Bitu frames; + Bit16s audiobuf[WAVE_BUF][2]; + Bitu audioused; + Bitu audiorate; + Bitu audiowritten; + VideoCodec *codec; + Bitu width, height, bpp; + Bitu written; + float fps; + int bufSize; + void *buf; + Bit8u *index; + Bitu indexsize, indexused; + } video; +} capture; FILE * OpenCaptureFile(const char * type,const char * ext) { Bitu last=0; @@ -66,13 +112,575 @@ FILE * OpenCaptureFile(const char * type,const char * ext) { return handle; } +#if (C_SSHOT) +static void CAPTURE_AddAviChunk(const char * tag, Bit32u size, void * data, Bit32u flags) { + Bit8u chunk[8];Bit8u *index;Bit32u pos, writesize; + + chunk[0] = tag[0];chunk[1] = tag[1];chunk[2] = tag[2];chunk[3] = tag[3]; + host_writed(&chunk[4], size); + /* Write the actual data */ + fwrite(chunk,1,8,capture.video.handle); + writesize = (size+1)&~1; + fwrite(data,1,writesize,capture.video.handle); + pos = capture.video.written + 4; + capture.video.written += writesize + 8; + if (capture.video.indexused + 16 >= capture.video.indexsize ) { + capture.video.index = (Bit8u*)realloc( capture.video.index, capture.video.indexsize + 16 * 4096); + if (!capture.video.index) + E_Exit("Ran out of memory during AVI capturing"); + capture.video.indexsize += 16*4096; + } + index = capture.video.index+capture.video.indexused; + capture.video.indexused += 16; + index[0] = tag[0]; + index[1] = tag[1]; + index[2] = tag[2]; + index[3] = tag[3]; + host_writed(index+4, flags); + host_writed(index+8, pos); + host_writed(index+12, size); +} +#endif + +static void CAPTURE_VideoEvent(void) { + if (CaptureState & CAPTURE_VIDEO) { + /* Close the video */ + CaptureState &= ~CAPTURE_VIDEO; + Bit8u avi_header[AVI_HEADER_SIZE]; + Bitu main_list; + Bitu header_pos=0; +#define AVIOUT4(_S_) memcpy(&avi_header[header_pos],_S_,4);header_pos+=4; +#define AVIOUTw(_S_) host_writew(&avi_header[header_pos], _S_);header_pos+=2; +#define AVIOUTd(_S_) host_writed(&avi_header[header_pos], _S_);header_pos+=4; + /* Try and write an avi header */ + AVIOUT4("RIFF"); // Riff header + AVIOUTd(AVI_HEADER_SIZE + capture.video.written - 8 + capture.video.indexused); + AVIOUT4("AVI "); + AVIOUT4("LIST"); // List header + main_list = header_pos; + AVIOUTd(0); // TODO size of list + AVIOUT4("hdrl"); + + AVIOUT4("avih"); + AVIOUTd(56); /* # of bytes to follow */ + AVIOUTd((Bit32u)(1000000 / capture.video.fps)); /* Microseconds per frame */ + AVIOUTd(0); + AVIOUTd(0); /* PaddingGranularity (whatever that might be) */ + AVIOUTd(0x110); /* Flags,0x10 has index, 0x100 interleaved */ + AVIOUTd(capture.video.frames); /* TotalFrames */ + AVIOUTd(0); /* InitialFrames */ + AVIOUTd(2); /* Stream count */ + AVIOUTd(0); /* SuggestedBufferSize */ + AVIOUTd(capture.video.width); /* Width */ + AVIOUTd(capture.video.height); /* Height */ + AVIOUTd(0); /* TimeScale: Unit used to measure time */ + AVIOUTd(0); /* DataRate: Data rate of playback */ + AVIOUTd(0); /* StartTime: Starting time of AVI data */ + AVIOUTd(0); /* DataLength: Size of AVI data chunk */ + + /* Video stream list */ + AVIOUT4("LIST"); + AVIOUTd(4 + 8 + 56 + 8 + 40); /* Size of the list */ + AVIOUT4("strl"); + /* video stream header */ + AVIOUT4("strh"); + AVIOUTd(56); /* # of bytes to follow */ + AVIOUT4("vids"); /* Type */ + AVIOUT4(CODEC_4CC); /* Handler */ + AVIOUTd(0); /* Flags */ + AVIOUTd(0); /* Reserved, MS says: wPriority, wLanguage */ + AVIOUTd(0); /* InitialFrames */ + AVIOUTd(1000000); /* Scale */ + AVIOUTd((Bit32u)(1000000 * capture.video.fps)); /* Rate: Rate/Scale == samples/second */ + AVIOUTd(0); /* Start */ + AVIOUTd(capture.video.frames); /* Length */ + AVIOUTd(0); /* SuggestedBufferSize */ + AVIOUTd(-1); /* Quality */ + AVIOUTd(0); /* SampleSize */ + AVIOUTd(0); /* Frame */ + AVIOUTd(0); /* Frame */ + /* The video stream format */ + AVIOUT4("strf"); + AVIOUTd(40); /* # of bytes to follow */ + AVIOUTd(40); /* Size */ + AVIOUTd(capture.video.width); /* Width */ + AVIOUTd(capture.video.height); /* Height */ +// OUTSHRT(1); OUTSHRT(24); /* Planes, Count */ + AVIOUTd(0); + AVIOUT4(CODEC_4CC); /* Compression */ + AVIOUTd(capture.video.width * capture.video.height*4); /* SizeImage (in bytes?) */ + AVIOUTd(0); /* XPelsPerMeter */ + AVIOUTd(0); /* YPelsPerMeter */ + AVIOUTd(0); /* ClrUsed: Number of colors used */ + AVIOUTd(0); /* ClrImportant: Number of colors important */ + + /* Audio stream list */ + AVIOUT4("LIST"); + AVIOUTd(4 + 8 + 56 + 8 + 16); /* Length of list in bytes */ + AVIOUT4("strl"); + /* The audio stream header */ + AVIOUT4("strh"); + AVIOUTd(56); /* # of bytes to follow */ + AVIOUT4("auds"); + AVIOUTd(0); /* Format (Optionally) */ + AVIOUTd(0); /* Flags */ + AVIOUTd(0); /* Reserved, MS says: wPriority, wLanguage */ + AVIOUTd(0); /* InitialFrames */ + AVIOUTd(4); /* Scale */ + AVIOUTd(capture.video.audiorate*4); /* Rate, actual rate is scale/rate */ + AVIOUTd(0); /* Start */ + if (!capture.video.audiorate) + capture.video.audiorate = 1; + AVIOUTd(capture.video.audiowritten/4); /* Length */ + AVIOUTd(0); /* SuggestedBufferSize */ + AVIOUTd(-1); /* Quality */ + AVIOUTd(4); /* SampleSize */ + AVIOUTd(0); /* Frame */ + AVIOUTd(0); /* Frame */ + /* The audio stream format */ + AVIOUT4("strf"); + AVIOUTd(16); /* # of bytes to follow */ + AVIOUTw(1); /* Format, WAVE_ZMBV_FORMAT_PCM */ + AVIOUTw(2); /* Number of channels */ + AVIOUTd(capture.video.audiorate); /* SamplesPerSec */ + AVIOUTd(capture.video.audiorate*4); /* AvgBytesPerSec*/ + AVIOUTw(4); /* BlockAlign */ + AVIOUTw(16); /* BitsPerSample */ + int nmain = header_pos - main_list - 4; + /* Finish stream list, i.e. put number of bytes in the list to proper pos */ + LOG_MSG("Wrote a total of %d", header_pos ); + int njunk = AVI_HEADER_SIZE - 8 - 12 - header_pos; + AVIOUT4("JUNK"); + AVIOUTd(njunk); + /* Fix the size of the main list */ + header_pos = main_list; + AVIOUTd(nmain); + header_pos = AVI_HEADER_SIZE - 12; + AVIOUT4("LIST"); + AVIOUTd(capture.video.written+4); /* Length of list in bytes */ + AVIOUT4("movi"); + /* First add the index table to the end */ + memcpy(capture.video.index, "idx1", 4); + host_writed( capture.video.index+4, capture.video.indexused - 8 ); + fwrite( capture.video.index, 1, capture.video.indexused, capture.video.handle); + fseek(capture.video.handle, 0, SEEK_SET); + fwrite(&avi_header, 1, AVI_HEADER_SIZE, capture.video.handle); + fclose( capture.video.handle ); + free( capture.video.index ); + free( capture.video.buf ); + delete capture.video.codec; + capture.video.handle = 0; + } else { + CaptureState |= CAPTURE_VIDEO; + } +} + +void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags, float fps, Bit8u * data, Bit8u * pal) { + Bitu i; +#if (C_SSHOT) + Bit32u doubleRow[SCALER_MAXWIDTH]; + + if (flags & CAPTURE_FLAG_DBLH) + height *= 2; + if (flags & CAPTURE_FLAG_DBLW) + width *= 2; + + if (height > SCALER_MAXHEIGHT) + return; + if (width > SCALER_MAXWIDTH) + return; + + if (CaptureState & CAPTURE_IMAGE) { + png_structp png_ptr; + png_infop info_ptr; + png_color palette[256]; + + CaptureState &= ~CAPTURE_IMAGE; + /* Open the actual file */ + FILE * fp=OpenCaptureFile("Screenshot",".png"); + if (!fp) goto skip_shot; + /* First try to alloacte the png structures */ + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL, NULL); + if (!png_ptr) goto skip_shot; + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_write_struct(&png_ptr,(png_infopp)NULL); + goto skip_shot; + } + + /* Finalize the initing of png library */ + png_init_io(png_ptr, fp); + png_set_compression_level(png_ptr,Z_BEST_COMPRESSION); + + /* set other zlib parameters */ + png_set_compression_mem_level(png_ptr, 8); + png_set_compression_strategy(png_ptr,Z_DEFAULT_STRATEGY); + png_set_compression_window_bits(png_ptr, 15); + png_set_compression_method(png_ptr, 8); + png_set_compression_buffer_size(png_ptr, 8192); + + if (bpp==8) { + png_set_IHDR(png_ptr, info_ptr, width, height, + 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + for (i=0;i<256;i++) { + palette[i].red=pal[i*4+0]; + palette[i].green=pal[i*4+1]; + palette[i].blue=pal[i*4+2]; + } + png_set_PLTE(png_ptr, info_ptr, palette,256); + } else { + png_set_swap(png_ptr); + if (bpp == 32) { + png_set_IHDR(png_ptr, info_ptr, width, height, + 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + } else { + png_set_IHDR(png_ptr, info_ptr, width, height, + 16, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + } + } + png_write_info(png_ptr, info_ptr); + for (i=0;i> 1; + if (flags & CAPTURE_FLAG_DBLH) + srcLine=(data+(i >> 1)*pitch); + else + srcLine=(data+(i >> 0)*pitch); + switch ( bpp) { + case 8: + for (x=0;x> 1)*pitch); + else + rowPointer=(data+(i >> 0)*pitch); + } + png_write_row(png_ptr, (png_bytep)rowPointer); + png_write_flush( png_ptr ); + } + /*close file*/ + fclose(fp); + + /*Destroy PNG structs*/ + png_destroy_write_struct(&png_ptr, &info_ptr); + } +skip_shot: + if (CaptureState & CAPTURE_VIDEO) { + zmbv_format_t format; + /* Disable capturing if any of the test fails */ + if (capture.video.handle && ( + capture.video.width != width || + capture.video.height != height || + capture.video.bpp != bpp || + capture.video.fps != fps)) + { + CAPTURE_VideoEvent(); + } + CaptureState &= ~CAPTURE_VIDEO; + switch (bpp) { + case 8:format = ZMBV_FORMAT_8BPP;break; + case 15:format = ZMBV_FORMAT_15BPP;break; + case 16:format = ZMBV_FORMAT_16BPP;break; + case 32:format = ZMBV_FORMAT_32BPP;break; + default: + goto skip_video; + } + if (!capture.video.handle) { + capture.video.handle = OpenCaptureFile("Video",".avi"); + if (!capture.video.handle) + goto skip_video; + capture.video.codec = new VideoCodec(); + if (!capture.video.codec) + goto skip_video; + if (!capture.video.codec->SetupCompress( width, height)) + goto skip_video; + capture.video.bufSize = capture.video.codec->NeededSize(width, height, format); + capture.video.buf = malloc( capture.video.bufSize ); + if (!capture.video.buf) + goto skip_video; + capture.video.index = (Bit8u*)malloc( 16*4096 ); + if (!capture.video.buf) + goto skip_video; + capture.video.indexsize = 16*4096; + capture.video.indexused = 8; + + capture.video.width = width; + capture.video.height = height; + capture.video.bpp = bpp; + capture.video.fps = fps; + for (i=0;iPrepareCompressFrame( codecFlags, format, (char *)pal, capture.video.buf, capture.video.bufSize)) + goto skip_video; + + for (i=0;i> 1; + if (flags & CAPTURE_FLAG_DBLH) + srcLine=(data+(i >> 1)*pitch); + else + srcLine=(data+(i >> 0)*pitch); + switch ( bpp) { + case 8: + for (x=0;x> 1)*pitch); + else + rowPointer=(data+(i >> 0)*pitch); + } + capture.video.codec->CompressLines( 1, &rowPointer ); + } + int written = capture.video.codec->FinishCompressFrame(); + if (written < 0) + goto skip_video; + CAPTURE_AddAviChunk( "00dc", written, capture.video.buf, codecFlags & 1 ? 0x10 : 0x0); + capture.video.frames++; + LOG_MSG("Frame %d video %d audio %d",capture.video.frames, written, capture.video.audioused *4 ); + if ( capture.video.audioused ) { + CAPTURE_AddAviChunk( "01wb", capture.video.audioused * 4, capture.video.audiobuf, 0); + capture.video.audiowritten = capture.video.audioused*4; + capture.video.audioused = 0; + } + + /* Everything went okay, set flag again for next frame */ + CaptureState |= CAPTURE_VIDEO; + } +skip_video: +#endif + return; +} + + +static void CAPTURE_ScreenShotEvent(void) { + CaptureState |= CAPTURE_IMAGE; +} + + +/* WAV capturing */ +static Bit8u wavheader[]={ + 'R','I','F','F', 0x0,0x0,0x0,0x0, /* Bit32u Riff Chunk ID / Bit32u riff size */ + 'W','A','V','E', 'f','m','t',' ', /* Bit32u Riff Format / Bit32u fmt chunk id */ + 0x10,0x0,0x0,0x0, 0x1,0x0,0x2,0x0, /* Bit32u fmt size / Bit16u encoding/ Bit16u channels */ + 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, /* Bit32u freq / Bit32u byterate */ + 0x4,0x0,0x10,0x0, 'd','a','t','a', /* Bit16u byte-block / Bit16u bits / Bit16u data chunk id */ + 0x0,0x0,0x0,0x0, /* Bit32u data size */ +}; + +void CAPTURE_AddWave(Bit32u freq, Bit32u len, Bit16s * data) { + if (CaptureState & CAPTURE_VIDEO) { + Bitu left = WAVE_BUF - capture.video.audioused; + if (left > len) + left = len; + memcpy( &capture.video.audiobuf[capture.video.audioused], data, left*4); + capture.video.audioused += left; + capture.video.audiorate = freq; + } + if (CaptureState & CAPTURE_WAVE) { + if (!capture.wave.handle) { + capture.wave.handle=OpenCaptureFile("Wave Output",".wav"); + if (!capture.wave.handle) { + CaptureState &= ~CAPTURE_WAVE; + return; + } + capture.wave.length = 0; + capture.wave.used = 0; + capture.wave.freq = freq; + fwrite(wavheader,1,sizeof(wavheader),capture.wave.handle); + } + Bit16s * read = data; + while (len > 0 ) { + Bitu left = WAVE_BUF - capture.wave.used; + if (!left) { + fwrite(capture.wave.buf,1,4*WAVE_BUF,capture.wave.handle); + capture.wave.length += 4*WAVE_BUF; + capture.wave.used = 0; + left = WAVE_BUF; + } + if (left > len) + left = len; + memcpy( &capture.wave.buf[capture.wave.used], read, left*4); + capture.wave.used += left; + read += left*2; + len -= left; + } + } +} +static void CAPTURE_WaveEvent(void) { + /* Check for previously opened wave file */ + if (capture.wave.handle) { + LOG_MSG("Stopped capturing wave output."); + /* Write last piece of audio in buffer */ + fwrite(capture.wave.buf,1,capture.wave.used*4,capture.wave.handle); + capture.wave.length+=capture.wave.used*4; + /* Fill in the header with useful information */ + host_writed(&wavheader[0x04],capture.wave.length+sizeof(wavheader)-8); + host_writed(&wavheader[0x18],capture.wave.freq); + host_writed(&wavheader[0x1C],capture.wave.freq*4); + host_writed(&wavheader[0x28],capture.wave.length); + + fseek(capture.wave.handle,0,0); + fwrite(wavheader,1,sizeof(wavheader),capture.wave.handle); + fclose(capture.wave.handle); + capture.wave.handle=0; + CaptureState |= CAPTURE_WAVE; + } + CaptureState ^= CAPTURE_WAVE; +} + +/* MIDI capturing */ + +static Bit8u midi_header[]={ + 'M','T','h','d', /* Bit32u, Header Chunk */ + 0x0,0x0,0x0,0x6, /* Bit32u, Chunk Length */ + 0x0,0x0, /* Bit16u, Format, 0=single track */ + 0x0,0x1, /* Bit16u, Track Count, 1 track */ + 0x01,0xf4, /* Bit16u, Timing, 2 beats/second with 500 frames */ + 'M','T','r','k', /* Bit32u, Track Chunk */ + 0x0,0x0,0x0,0x0, /* Bit32u, Chunk Length */ + //Track data +}; + + +static void RawMidiAdd(Bit8u data) { + capture.midi.buffer[capture.midi.used++]=data; + if (capture.midi.used >= MIDI_BUF ) { + capture.midi.done += capture.midi.used; + fwrite(capture.midi.buffer,1,MIDI_BUF,capture.midi.handle); + capture.midi.used = 0; + } +} + +static void RawMidiAddNumber(Bit32u val) { + if (val & 0xfe00000) RawMidiAdd((Bit8u)(0x80|((val >> 21) & 0x7f))); + if (val & 0xfffc000) RawMidiAdd((Bit8u)(0x80|((val >> 14) & 0x7f))); + if (val & 0xfffff80) RawMidiAdd((Bit8u)(0x80|((val >> 7) & 0x7f))); + RawMidiAdd((Bit8u)(val & 0x7f)); +} + +void CAPTURE_AddMidi(bool sysex, Bitu len, Bit8u * data) { + if (!capture.midi.handle) { + capture.midi.handle=OpenCaptureFile("Raw Midi",".mid"); + if (!capture.midi.handle) { + return; + } + fwrite(midi_header,1,sizeof(midi_header),capture.midi.handle); + capture.midi.last=PIC_Ticks; + } + Bit32u delta=PIC_Ticks-capture.midi.last; + capture.midi.last=PIC_Ticks; + RawMidiAddNumber(delta); + if (sysex) { + RawMidiAdd( 0xf0 ); + RawMidiAddNumber( len ); + } + for (Bitu i=0;i> 24); + size[1]=(Bit8u)(capture.midi.done >> 16); + size[2]=(Bit8u)(capture.midi.done >> 8); + size[3]=(Bit8u)(capture.midi.done >> 0); + fwrite(&size,1,4,capture.midi.handle); + fclose(capture.midi.handle); + capture.midi.handle=0; + CaptureState &= ~CAPTURE_MIDI; + return; + } + CaptureState ^= CAPTURE_MIDI; + if (CaptureState & CAPTURE_MIDI) { + LOG_MSG("Preparing for raw midi capture, will start with first data."); + capture.midi.used=0; + capture.midi.done=0; + capture.midi.handle=0; + } else { + LOG_MSG("Stopped capturing raw midi before any data arrived."); + } +} + class HARDWARE:public Module_base{ public: HARDWARE(Section* configuration):Module_base(configuration){ Section_prop * section = static_cast(configuration); capturedir = (char *)section->Get_string("captures"); + CaptureState = 0; + MAPPER_AddHandler(CAPTURE_WaveEvent,MK_f6,MMOD1,"recwave","Rec Wave"); + MAPPER_AddHandler(CAPTURE_MidiEvent,MK_f8,MMOD1|MMOD2,"caprawmidi","Cap MIDI"); +#if (C_SSHOT) + MAPPER_AddHandler(CAPTURE_ScreenShotEvent,MK_f5,MMOD1,"scrshot","Screenshot"); + MAPPER_AddHandler(CAPTURE_VideoEvent,MK_f5,MMOD1|MMOD2,"video","Video"); +#endif + } + ~HARDWARE(){ + if (capture.wave.handle) CAPTURE_WaveEvent(); + if (capture.midi.handle) CAPTURE_MidiEvent(); } - ~HARDWARE(){ } }; static HARDWARE* test; diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 1bb2a2e3..c525d2bf 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.35 2005-12-05 12:04:40 qbix79 Exp $ */ +/* $Id: mixer.cpp,v 1.36 2006-01-30 10:04:20 harekiet Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -53,7 +53,6 @@ #define MIXER_SSIZE 4 #define MIXER_SHIFT 14 #define MIXER_REMAIN ((1<Mix(needed); chan=chan->next; } - if (mixer.wave.handle) { + if (CaptureState & (CAPTURE_WAVE|CAPTURE_VIDEO)) { + Bit16s convert[1024][2]; Bitu added=needed-mixer.done; + if (added>1024) + added=1024; Bitu readpos=(mixer.pos+mixer.done)&MIXER_BUFMASK; - - Bits sample; - while (added--) { - sample=mixer.work[readpos][0] >> MIXER_VOLSHIFT; - mixer.wave.buf[mixer.wave.used][0]=MIXER_CLIP(sample); + for (Bitu i=0;i> MIXER_VOLSHIFT; + convert[i][0]=MIXER_CLIP(sample); sample=mixer.work[readpos][1] >> MIXER_VOLSHIFT; - mixer.wave.buf[mixer.wave.used][1]=MIXER_CLIP(sample); + convert[i][1]=MIXER_CLIP(sample); readpos=(readpos+1)&MIXER_BUFMASK; - if (++mixer.wave.used==MIXER_WAVESIZE) { - mixer.wave.length+=MIXER_WAVESIZE*MIXER_SSIZE; - mixer.wave.used=0; - fwrite(mixer.wave.buf,MIXER_WAVESIZE*MIXER_SSIZE,1,mixer.wave.handle); - } } + CAPTURE_AddWave( mixer.freq, added, (Bit16s*)convert ); + //Reset the the tick_add for constant speed + mixer.tick_add=((mixer.freq) << MIXER_SHIFT)/1000; } mixer.done=needed; } @@ -378,34 +360,7 @@ static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { } } -static void MIXER_WaveEvent(void) { - /* Check for previously opened wave file */ - if (mixer.wave.handle) { - LOG_MSG("Stopped capturing wave output."); - /* Write last piece of audio in buffer */ - fwrite(mixer.wave.buf,1,mixer.wave.used*MIXER_SSIZE,mixer.wave.handle); - mixer.wave.length+=mixer.wave.used*MIXER_SSIZE; - /* Fill in the header with useful information */ - host_writed(&wavheader[0x04],mixer.wave.length+sizeof(wavheader)-8); - host_writed(&wavheader[0x18],mixer.freq); - host_writed(&wavheader[0x1C],mixer.freq*4); - host_writed(&wavheader[0x28],mixer.wave.length); - - fseek(mixer.wave.handle,0,0); - fwrite(wavheader,1,sizeof(wavheader),mixer.wave.handle); - fclose(mixer.wave.handle); - mixer.wave.handle=0; - } else { - mixer.wave.handle=OpenCaptureFile("Wave Output",".wav"); - if (!mixer.wave.handle) return; - mixer.wave.length=0; - mixer.wave.used=0; - fwrite(wavheader,1,sizeof(wavheader),mixer.wave.handle); - } -} - static void MIXER_Stop(Section* sec) { - if (mixer.wave.handle) MIXER_WaveEvent(); } class MIXER : public Program { @@ -504,6 +459,7 @@ MixerObject::~MixerObject(){ void MIXER_Init(Section* sec) { sec->AddDestroyFunction(&MIXER_Stop); + Section_prop * section=static_cast(sec); /* Read out config section */ mixer.freq=section->Get_int("rate"); @@ -515,8 +471,6 @@ void MIXER_Init(Section* sec) { mixer.pos=0; mixer.done=0; memset(mixer.work,0,sizeof(mixer.work)); - mixer.wave.handle=0; - mixer.wave.used=0; mixer.mastervol[0]=1.0f; mixer.mastervol[1]=1.0f; @@ -537,6 +491,7 @@ void MIXER_Init(Section* sec) { mixer.tick_add=((mixer.freq) << MIXER_SHIFT)/1000; TIMER_AddTickHandler(MIXER_Mix_NoSound); } else if (SDL_OpenAudio(&spec, &obtained) <0 ) { + mixer.nosound = true; LOG_MSG("MIXER:Can't open audio: %s , running in nosound mode.",SDL_GetError()); mixer.tick_add=((mixer.freq) << MIXER_SHIFT)/1000; TIMER_AddTickHandler(MIXER_Mix_NoSound); @@ -551,6 +506,5 @@ void MIXER_Init(Section* sec) { if (mixer.min_needed>100) mixer.min_needed=100; mixer.min_needed=(mixer.freq*mixer.min_needed)/1000; mixer.needed=mixer.min_needed+1; - MAPPER_AddHandler(MIXER_WaveEvent,MK_f6,MMOD1,"recwave","Rec Wave"); PROGRAMS_MakeFile("MIXER.COM",MIXER_ProgramStart); } From 28588c997ba187ded3e1899ea489be18d00f7926 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 10:04:46 +0000 Subject: [PATCH 2364/4131] New seperate read/write handlers for getHostPt Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2448 --- src/hardware/memory.cpp | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index b433960c..3754202b 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: memory.cpp,v 1.42 2006-01-07 14:17:53 c2woody Exp $ */ +/* $Id: memory.cpp,v 1.43 2006-01-30 10:04:46 harekiet Exp $ */ #include "dosbox.h" #include "mem.h" @@ -47,7 +47,7 @@ static struct MemoryBlock { Bitu start_page; Bitu end_page; Bitu pages; - HostPt address; + PageHandler *handler; } lfb; struct { bool enabled; @@ -69,9 +69,6 @@ public: void writeb(PhysPt addr,Bitu val) { LOG_MSG("Illegal write to %x, CS:IP %8x:%8x",addr,SegValue(cs),reg_eip); } - HostPt GetHostPt(Bitu phys_page) { - return 0; - } }; class RAMPageHandler : public PageHandler { @@ -79,7 +76,10 @@ public: RAMPageHandler() { flags=PFLAG_READABLE|PFLAG_WRITEABLE; } - HostPt GetHostPt(Bitu phys_page) { + HostPt GetHostReadPt(Bitu phys_page) { + return MemBase+phys_page*MEM_PAGESIZE; + } + HostPt GetHostWritePt(Bitu phys_page) { return MemBase+phys_page*MEM_PAGESIZE; } }; @@ -100,24 +100,14 @@ public: } }; -class LFBPageHandler : public RAMPageHandler { -public: - LFBPageHandler() { - flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; - } - HostPt GetHostPt(Bitu phys_page) { - return memory.lfb.address+(phys_page-memory.lfb.start_page)*4096; - } -}; static IllegalPageHandler illegal_page_handler; static RAMPageHandler ram_page_handler; static ROMPageHandler rom_page_handler; -static LFBPageHandler lfb_page_handler; -void MEM_SetLFB(Bitu page,Bitu pages,HostPt pt) { - memory.lfb.address=pt; +void MEM_SetLFB(Bitu page, Bitu pages, PageHandler *handler) { + memory.lfb.handler=handler; memory.lfb.start_page=page; memory.lfb.end_page=page+pages; memory.lfb.pages=pages; @@ -128,7 +118,7 @@ PageHandler * MEM_GetPageHandler(Bitu phys_page) { if (phys_page=memory.lfb.start_page) && (phys_page Date: Mon, 30 Jan 2006 10:06:36 +0000 Subject: [PATCH 2365/4131] Fix some compilation warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2449 --- src/ints/mouse.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 130fa902..fb5ca08d 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.57 2005-12-13 11:15:50 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.58 2006-01-30 10:06:36 harekiet Exp $ */ #include #include @@ -113,12 +113,13 @@ static struct { float senv_y; Bit16u updateRegion_x[2]; Bit16u updateRegion_y[2]; - Bit16u page; Bit16u doubleSpeedThreshold; Bit16u language; Bit16u cursorType; + Bit16s oldshown; + Bit8u page; bool enabled; - Bit16s oldshown; + } mouse; bool Mouse_SetPS2State(bool use) { @@ -505,8 +506,6 @@ static void mouse_reset_hardware(void){ void Mouse_NewVideoMode(void) { //Does way to much. Many of this stuff should be moved to mouse_reset one day -// WriteMouseIntVector();//Disabled. Big Red Adventure, Rac Racing - if(MOUSE_IRQ > 7) { real_writed(0,((0x70+MOUSE_IRQ-8)<<2),CALLBACK_RealPointer(call_int74)); } else { @@ -577,15 +576,9 @@ void Mouse_NewVideoMode(void) SetMickeyPixelRate(8,16); oldmouseX = static_cast(mouse.x); - oldmouseY = static_cast(mouse.y); - - - } - - static void mouse_reset(void) { //Much to empty Mouse_NewVideoMode contains stuff that should be in here @@ -804,7 +797,7 @@ static Bitu INT33_Handler(void) { /* Can't really set a rate this is host determined */ break; case 0x1d: /* Set display page number */ - mouse.page=reg_bx; + mouse.page=reg_bl; break; case 0x1e: /* Get display page number */ reg_bx=mouse.page; From b032209b752bf1651c21ea3d08457c4198afe1fd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 10:07:19 +0000 Subject: [PATCH 2366/4131] Support for 15/16/32 bpp and highres 4bpp Added some lowres resolutions to the vesa modes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2450 --- src/ints/int10_char.cpp | 10 +- src/ints/int10_misc.cpp | 8 +- src/ints/int10_modes.cpp | 197 +++++++++++++++++++++++++++-------- src/ints/int10_put_pixel.cpp | 14 ++- src/ints/int10_vesa.cpp | 111 ++++++++++++++++---- 5 files changed, 267 insertions(+), 73 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 09ae940f..90ebe5de 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.42 2005-12-02 13:10:18 c2woody Exp $ */ +/* $Id: int10_char.cpp,v 1.43 2006-01-30 10:07:19 harekiet Exp $ */ /* Character displaying moving functions */ @@ -235,7 +235,7 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit CGA4_CopyRow(cul,clr,start,start+nlines,base);break; case M_TANDY16: TANDY16_CopyRow(cul,clr,start,start+nlines,base);break; - case M_EGA16: + case M_EGA: EGA16_CopyRow(cul,clr,start,start+nlines,base);break; case M_VGA: VGA_CopyRow(cul,clr,start,start+nlines,base);break; @@ -261,7 +261,7 @@ filling: CGA4_FillRow(cul,clr,start,base,attr);break; case M_TANDY16: TANDY16_FillRow(cul,clr,start,base,attr);break; - case M_EGA16: + case M_EGA: EGA16_FillRow(cul,clr,start,base,attr);break; case M_VGA: VGA_FillRow(cul,clr,start,base,attr);break; @@ -483,7 +483,7 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt attr = 0x1; break; case M_TANDY16: - case M_EGA16: + case M_EGA: default: attr = 0xf; break; @@ -493,7 +493,7 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt x=8*col; y=cheight*row;Bit8u xor_mask=(CurMode->type == M_VGA) ? 0x0 : 0x80; //TODO Check for out of bounds - if (CurMode->type==M_EGA16) { + if (CurMode->type==M_EGA) { /* enable all planes for EGA modes (Ultima 1 colour bug) */ /* might be put into INT10_PutPixel but different vga bios implementations have different opinions about this */ diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 5c680ffc..de1db8fb 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -98,8 +98,12 @@ void INT10_GetFuncStateInformation(PhysPt save) { col_count=2;break; case M_CGA4: col_count=4;break; - case M_EGA16: - if (CurMode->mode==0x11 || CurMode->mode==0x0f) col_count=2; else col_count=16;break; + case M_EGA: + if (CurMode->mode==0x11 || CurMode->mode==0x0f) + col_count=2; + else + col_count=16; + break; case M_VGA: col_count=256;break; default: diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 2996f014..0120c6d3 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -27,6 +27,7 @@ #define _EGA_HALF_CLOCK 0x0001 #define _EGA_LINE_DOUBLE 0x0002 +#define _VGA_PIXEL_DOUBLE 0x0004 #define SEQ_REGS 0x05 #define GFX_REGS 0x09 @@ -43,24 +44,60 @@ VideoModeBlock ModeList_VGA[]={ { 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, { 0x007 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, -{ 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, -{ 0x00E ,M_EGA16 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE }, -{ 0x00F ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 },/*was EGA_2*/ -{ 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, -{ 0x011 ,M_EGA16 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 },/*was EGA_2 */ -{ 0x012 ,M_EGA16 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, +{ 0x00D ,M_EGA ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, +{ 0x00E ,M_EGA ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE }, +{ 0x00F ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 },/*was EGA_2*/ +{ 0x010 ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, +{ 0x011 ,M_EGA ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 },/*was EGA_2 */ +{ 0x012 ,M_EGA ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, { 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x2000 ,100 ,449 ,80 ,400 ,0 }, { 0x054 ,M_TEXT ,1056,688, 132,43, 8, 8, 1 ,0xB8000 ,0x4000, 192, 800, 132,688, 0 }, { 0x055 ,M_TEXT ,1056,400, 132,25, 8, 16, 1 ,0xB8000 ,0x2000, 192, 449, 132,400, 0 }, + +/* Follow vesa 1.2 for first 0x20 */ { 0x100 ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, { 0x101 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, +{ 0x102 ,M_LIN4 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, { 0x103 ,M_LIN8 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, +{ 0x104 ,M_LIN4 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,150 ,800 ,128,768 ,0 }, +{ 0x105 ,M_LIN8 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,150 ,800 ,128,768 ,0 }, + +{ 0x10D ,M_LIN15 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x10E ,M_LIN16 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x10F ,M_LIN32 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x110 ,M_LIN15 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, +{ 0x111 ,M_LIN16 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, +{ 0x112 ,M_LIN32 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, +{ 0x113 ,M_LIN15 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, +{ 0x114 ,M_LIN16 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, +{ 0x115 ,M_LIN32 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, + +{ 0x116 ,M_LIN15 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,150 ,800 ,128,768 ,0 }, +{ 0x117 ,M_LIN16 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,150 ,800 ,128,768 ,0 }, +{ 0x118 ,M_LIN32 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,150 ,800 ,128,768 ,0 }, + + +{ 0x150 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x151 ,M_LIN8 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x152 ,M_LIN8 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE }, +{ 0x153 ,M_LIN8 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE }, + +{ 0x160 ,M_LIN15 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x161 ,M_LIN15 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE }, +{ 0x162 ,M_LIN15 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE }, +{ 0x165 ,M_LIN15 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, + +{ 0x170 ,M_LIN16 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x171 ,M_LIN16 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE }, +{ 0x172 ,M_LIN16 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE }, +{ 0x175 ,M_LIN16 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, + +{ 0x190 ,M_LIN32 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x191 ,M_LIN32 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE }, +{ 0x192 ,M_LIN32 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE }, +{ 0x195 ,M_LIN32 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, -{ 0x150 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _EGA_LINE_DOUBLE }, -{ 0x151 ,M_LIN8 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _EGA_LINE_DOUBLE }, -{ 0x152 ,M_LIN8 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , 0 }, -{ 0x153 ,M_LIN8 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , 0 }, {0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, }; @@ -175,7 +212,6 @@ static Bit8u vga_palette[256][3]= {0x0b,0x10,0x0b},{0x0b,0x10,0x0c},{0x0b,0x10,0x0d},{0x0b,0x10,0x0f},{0x0b,0x10,0x10},{0x0b,0x0f,0x10},{0x0b,0x0d,0x10},{0x0b,0x0c,0x10}, {0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00} }; - VideoModeBlock * CurMode; static bool SetCurMode(VideoModeBlock modeblock[],Bitu mode) { @@ -210,9 +246,13 @@ static void FinishSetMode(bool clearmem) { real_writew(0xb800,i*2,0x0720); } break; - case M_EGA16: + case M_EGA: case M_VGA: case M_LIN8: + case M_LIN4: + case M_LIN15: + case M_LIN16: + case M_LIN32: /* Hack we just acess the memory directly */ memset(&vga.mem,0,sizeof(vga.mem)); } @@ -318,7 +358,7 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { //Setup the special registers for each machine type Bit8u mode_control_list[0xa+1]={ 0x2c,0x28,0x2d,0x29, //0-3 - 0x2a,0x2e,0x1e,0x29, //4-7 + 0x2a,0x2e,0x16,0x29, //4-7 0x2a,0x2b,0x3b //8-a }; Bit8u mode_control_list_pcjr[0xa+1]={ @@ -436,15 +476,19 @@ bool INT10_SetVideoMode(Bitu mode) { Bit8u misc_output=0x2 | (mono_mode ? 0x0 : 0x1); switch (CurMode->vdispend) { - case 400: misc_output|=0x60; - if (CurMode->type==M_TEXT) // && (CurMode->pstart==0xB8000)) - misc_output|=0x4; - break; - case 480: misc_output|=0xe0; - break; - case 350: misc_output|=0xa0; - break; - default: misc_output|=0x60; + case 400: + misc_output|=0x60; + if (CurMode->type==M_TEXT) // && (CurMode->pstart==0xB8000)) + misc_output|=0x4; + break; + case 480: + misc_output|=0xe0; + break; + case 350: + misc_output|=0xa0; + break; + default: + misc_output|=0x60; } IO_Write(0x3c2,misc_output); //Setup for 3b4 or 3d4 @@ -459,10 +503,17 @@ bool INT10_SetVideoMode(Bitu mode) { seq_data[2]|=0x3; //Enable plane 0 and 1 seq_data[4]|=0x05; //Alpanumeric and odd/even enabled break; - case M_EGA16: + case M_CGA2: + seq_data[2]|=0xf; //Enable plane 0 + break; + case M_LIN4: + case M_EGA: seq_data[2]|=0xf; //Enable all planes for writing break; case M_LIN8: //Seems to have the same reg layout from testing + case M_LIN15: + case M_LIN16: + case M_LIN32: case M_VGA: seq_data[2]|=0xf; //Enable all planes for writing seq_data[4]|=0xc; //Graphics - odd/even - Chained @@ -587,6 +638,9 @@ bool INT10_SetVideoMode(Bitu mode) { max_scanline|=1; //Vga doesn't use double line but this break; case M_LIN8: + case M_LIN15: + case M_LIN16: + case M_LIN32: underline=0x60; //Seems to enable the every 4th clock on my s3 break; case M_CGA2: @@ -606,14 +660,30 @@ bool INT10_SetVideoMode(Bitu mode) { /* Extended Vertical Overflow */ IO_Write(crtc_base,0x5e);IO_Write(crtc_base+1,ver_overflow); /* Offset Register */ - IO_Write(crtc_base,0x13); + Bitu offset; switch (CurMode->type) { case M_LIN8: - IO_Write(crtc_base+1,CurMode->swidth/8); + offset = CurMode->swidth/8; + break; + case M_LIN15: + case M_LIN16: + offset = 2 * CurMode->swidth/8; + break; + case M_LIN32: + offset = 4 * CurMode->swidth/8; break; default: - IO_Write(crtc_base+1,CurMode->hdispend/2); + offset = CurMode->hdispend/2; } + IO_Write(crtc_base,0x13); + IO_Write(crtc_base + 1,offset & 0xff); + /* Extended System Control 2 Register */ + /* This register actually has more bits but only use the extended offset ones */ + IO_Write(crtc_base,0x61); + IO_Write(crtc_base + 1,(offset & 0x300) >> 4); + /* Extended Vertical Overflow */ + IO_Write(crtc_base,0x5e);IO_Write(crtc_base+1,ver_overflow); + /* Mode Control */ Bit8u mode_control=0; @@ -624,7 +694,8 @@ bool INT10_SetVideoMode(Bitu mode) { case M_CGA4: mode_control=0xa2; break; - case M_EGA16: + case M_LIN4: + case M_EGA: if (CurMode->mode==0x11) // 0x11 also sets address wrap. thought maybe all 2 color modes did but 0x0f doesn't. mode_control=0xc3; // so.. 0x11 or 0x0f a one off? else @@ -632,10 +703,13 @@ bool INT10_SetVideoMode(Bitu mode) { break; case M_TEXT: case M_VGA: - mode_control=0xa3; - break; case M_LIN8: - mode_control=0xab; + case M_LIN15: + case M_LIN16: + case M_LIN32: + mode_control=0xa3; + if (CurMode->special & _VGA_PIXEL_DOUBLE) + mode_control |= 0x08; break; } @@ -653,8 +727,18 @@ bool INT10_SetVideoMode(Bitu mode) { /* Setup Pixel format */ switch (CurMode->type) { case M_LIN8: - if (CurMode->swidth < 640) misc_control_2=0x0; //Use single pixel mode,M_VGA then - else misc_control_2=0x10; + /* This should be 0x0 according to the specs but makes it easier to detect + compared to normal vga modes now */ + misc_control_2=0x10; + break; + case M_LIN15: + misc_control_2=0x30; + break; + case M_LIN16: + misc_control_2=0x50; + break; + case M_LIN32: + misc_control_2=0xd0; break; default: misc_control_2=0x0; @@ -674,15 +758,18 @@ bool INT10_SetVideoMode(Bitu mode) { gfx_data[0x6]|=mono_mode ? 0x0a : 0x0e; //Either b800 or b000 break; case M_LIN8: + case M_LIN15: + case M_LIN16: + case M_LIN32: case M_VGA: gfx_data[0x5]|=0x40; //256 color mode gfx_data[0x6]|=0x05; //graphics mode at 0xa000-affff break; - case M_EGA16: + case M_LIN4: + case M_EGA: gfx_data[0x6]|=0x05; //graphics mode at 0xa000-affff break; case M_CGA4: - case M_TANDY16: gfx_data[0x5]|=0x20; //CGA mode case M_CGA2: gfx_data[0x6]|=0x0f; //graphics mode at at 0xb800=0xbfff @@ -697,7 +784,8 @@ bool INT10_SetVideoMode(Bitu mode) { att_data[0x12]=0xf; //Always have all color planes enabled /* Program Attribute Controller */ switch (CurMode->type) { - case M_EGA16: + case M_LIN4: + case M_EGA: att_data[0x10]=0x01; //Color Graphics switch (CurMode->mode) { case 0x0f: @@ -749,15 +837,17 @@ att_text16: att_data[1]=0x13; att_data[2]=0x15; att_data[3]=0x17; - att_data[4]=0x2; - att_data[5]=0x4; - att_data[6]=0x6; - att_data[7]=0x7; - for (i=8;i<16;i++) att_data[i]=i+8; + att_data[4]=0x02; + att_data[5]=0x04; + att_data[6]=0x06; + att_data[7]=0x07; + for (i=0x8;i<0x10;i++) + att_data[i] = i + 0x8; real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x30); break; case M_VGA: case M_LIN8: + case M_LIN16: for (i=0;i<16;i++) att_data[i]=i; att_data[0x10]=0x41; //Color Graphics 8-bit break; @@ -767,10 +857,11 @@ att_text16: IO_Write(0x3c0,i); IO_Write(0x3c0,att_data[i]); } + IO_Write(0x3c0,0x20); //Disable palette access /* Setup the DAC */ IO_Write(0x3c8,0); switch (CurMode->type) { - case M_EGA16: + case M_EGA: if (CurMode->mode>0xf) goto dac_text16; else if (CurMode->mode==0xf) goto dac_mtext16; for (i=0;i<64;i++) { @@ -807,6 +898,7 @@ dac_text16: break; case M_VGA: case M_LIN8: + case M_LIN16: for (i=0;i<256;i++) { IO_Write(0x3c9,vga_palette[i][0]); IO_Write(0x3c9,vga_palette[i][1]); @@ -845,11 +937,11 @@ dac_text16: case 3:real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x29);break; } break; - case M_EGA16: + case M_LIN4: + case M_EGA: case M_VGA: feature=(feature&~0x30); break; - } // disabled, has to be set in bios.cpp exclusively // real_writeb(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE,feature); @@ -861,11 +953,24 @@ dac_text16: IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 24)); IO_Write(crtc_base,0x5a); IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 16)); - /* Setup some remaining S3 registers */ -// IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,0x9); //Enable banked memory and 256k+ access - IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,CurMode->mode<=0x13?0x1:0x9); //Enable banked memory and 256k+ access for SVGA modes only + Bitu reg_31; + switch (CurMode->type) { + case M_LIN4: + case M_LIN8: + case M_LIN15: + case M_LIN16: + case M_LIN32: + reg_31 = 9; + break; + default: + reg_31 = 0; + break; + } + IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,reg_31); //Enable banked memory and 256k+ access + IO_Write(crtc_base,0x58);IO_Write(crtc_base+1,0x3); //Enable 8 mb of linear addressing IO_Write(crtc_base,0x58);IO_Write(crtc_base+1,0x3); //Enable 8 mb of linear addressing + IO_Write(crtc_base,0x38);IO_Write(crtc_base+1,0x48); //Register lock 1 IO_Write(crtc_base,0x39);IO_Write(crtc_base+1,0xa5); //Register lock 2 diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index d20ac51d..17d10eae 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -90,7 +90,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { real_writeb(0xb800,off,old); } break; - case M_EGA16: + case M_EGA: { /* Set the correct bitmask for the pixel position */ IO_Write(0x3ce,0x8);Bit8u mask=128>>(x&7);IO_Write(0x3cf,mask); @@ -117,6 +117,11 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { case M_VGA: mem_writeb(PhysMake(0xa000,y*320+x),color); break; + case M_LIN8: { + PhysPt off=S3_LFB_BASE+y*CurMode->swidth+x; + mem_writeb(off,color); + break; + } default: LOG(LOG_INT10,LOG_ERROR)("PutPixel unhandled mode type %d",CurMode->type); break; @@ -141,7 +146,7 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { *color=(val>>(((7-x&7)))) & 1 ; } break; - case M_EGA16: + case M_EGA: { /* Calculate where the pixel is in video memory */ PhysPt off=0xa0000+CurMode->plength*page+((y*CurMode->swidth+x)>>3); @@ -161,6 +166,11 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { case M_VGA: *color=mem_readb(PhysMake(0xa000,320*y+x)); break; + case M_LIN8: { + PhysPt off=S3_LFB_BASE+y*CurMode->swidth+x; + *color = mem_readb(off); + break; + } default: LOG(LOG_INT10,LOG_ERROR)("GetPixel unhandled mode type %d",CurMode->type); break; diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 6a4388c1..b9453b60 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.18 2005-10-29 09:32:52 qbix79 Exp $ */ +/* $Id: int10_vesa.cpp,v 1.19 2006-01-30 10:07:19 harekiet Exp $ */ #include #include @@ -87,7 +87,8 @@ Bit8u VESA_GetSVGAInformation(Bit16u seg,Bit16u off) { PhysPt buffer=PhysMake(seg,off); Bitu i; bool vbe2=false;Bit16u vbe2_pos=256+off; - if (mem_readd(buffer)==0x32454256) vbe2=true; + Bitu id=mem_readd(buffer); + if ((id==0x56424532)||(id==0x32454256)) vbe2=true; if (vbe2) { for (i=0;i<0x200;i++) mem_writeb(buffer+i,0); } else { @@ -119,8 +120,9 @@ Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off) { MODE_INFO minfo; memset(&minfo,0,sizeof(minfo)); PhysPt buf=PhysMake(seg,off); - + Bitu pageSize; Bitu i=0; + if (mode<0x100) return 0x01; while (ModeList_VGA[i].mode!=0xffff) { if (mode==ModeList_VGA[i].mode) goto foundit; else i++; @@ -129,23 +131,77 @@ Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off) { foundit: VideoModeBlock * mblock=&ModeList_VGA[i]; switch (mblock->type) { - case M_LIN8: //Linear 8-bit - var_write(&minfo.ModeAttributes,0x9b); - var_write(&minfo.WinAAttributes,0x7); //Exists/readable/writable - var_write(&minfo.WinGranularity,64); - var_write(&minfo.WinSize,64); - var_write(&minfo.WinASegment,0xa000); -// var_write(&minfo.WinBSegment,0xa000); - var_write(&minfo.WinFuncPtr,CALLBACK_RealPointer(callback.setwindow)); - var_write(&minfo.BytesPerScanLine,mblock->swidth); - var_write(&minfo.NumberOfPlanes,0x1); - var_write(&minfo.BitsPerPixel,0x08); - var_write(&minfo.NumberOfBanks,0x1); - var_write(&minfo.MemoryModel,0x04); //packed pixel - var_write(&minfo.NumberOfImagePages,0x05); - var_write(&minfo.Reserved_page,0x1); + case M_LIN4: + pageSize = mblock->sheight * mblock->swidth/2; + pageSize = (pageSize | 15) & ~ 15; + var_write(&minfo.NumberOfImagePages,(512*1024 / pageSize)-1); + var_write(&minfo.BytesPerScanLine,mblock->swidth/8); + var_write(&minfo.BitsPerPixel,4); + var_write(&minfo.MemoryModel,3); //ega planar mode break; + case M_LIN8: + pageSize = mblock->sheight * mblock->swidth; + pageSize = (pageSize | 15) & ~ 15; + var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); + var_write(&minfo.BytesPerScanLine,mblock->swidth); + var_write(&minfo.BitsPerPixel,8); + var_write(&minfo.MemoryModel,4); //packed pixel + break; + case M_LIN15: + pageSize = mblock->sheight * mblock->swidth*2; + pageSize = (pageSize | 15) & ~ 15; + var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); + var_write(&minfo.BytesPerScanLine,mblock->swidth*2); + var_write(&minfo.BitsPerPixel,15); + var_write(&minfo.MemoryModel,6); //HiColour + var_write(&minfo.RedMaskSize,5); + var_write(&minfo.RedMaskPos,10); + var_write(&minfo.GreenMaskSize,5); + var_write(&minfo.GreenMaskPos,5); + var_write(&minfo.BlueMaskSize,5); + var_write(&minfo.BlueMaskPos,0); + break; + case M_LIN16: + pageSize = mblock->sheight * mblock->swidth*2; + pageSize = (pageSize | 15) & ~ 15; + var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); + var_write(&minfo.BytesPerScanLine,mblock->swidth*2); + var_write(&minfo.BitsPerPixel,16); + var_write(&minfo.MemoryModel,6); //HiColour + var_write(&minfo.RedMaskSize,5); + var_write(&minfo.RedMaskPos,11); + var_write(&minfo.GreenMaskSize,6); + var_write(&minfo.GreenMaskPos,5); + var_write(&minfo.BlueMaskSize,5); + var_write(&minfo.BlueMaskPos,0); + break; + case M_LIN32: + pageSize = mblock->sheight * mblock->swidth*4; + pageSize = (pageSize | 15) & ~ 15; + var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); + var_write(&minfo.BytesPerScanLine,mblock->swidth*2); + var_write(&minfo.BitsPerPixel,32); + var_write(&minfo.MemoryModel,6); //HiColour + var_write(&minfo.RedMaskSize,5); + var_write(&minfo.RedMaskPos,11); + var_write(&minfo.GreenMaskSize,6); + var_write(&minfo.GreenMaskPos,5); + var_write(&minfo.BlueMaskSize,5); + var_write(&minfo.BlueMaskPos,0); + break; + default: + return 0x1; } + + var_write(&minfo.ModeAttributes,0x9b); + var_write(&minfo.WinAAttributes,0x7); //Exists/readable/writable + var_write(&minfo.WinGranularity,64); + var_write(&minfo.WinSize,64); + var_write(&minfo.WinASegment,0xa000); + var_write(&minfo.WinFuncPtr,CALLBACK_RealPointer(callback.setwindow)); + var_write(&minfo.NumberOfPlanes,0x1); + var_write(&minfo.NumberOfBanks,0x1); + var_write(&minfo.Reserved_page,0x1); var_write(&minfo.XResolution,mblock->swidth); var_write(&minfo.YResolution,mblock->sheight); var_write(&minfo.XCharSize,mblock->cwidth); @@ -275,6 +331,13 @@ Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y) { //TODO Maybe do things differently with lowres double line modes? Bitu start; switch (CurMode->type) { + case M_LIN4: + start=vga.config.scan_len*8*y+x; + vga.config.display_start=start/8; + IO_Read(0x3da); + IO_Write(0x3c0,0x13+32); + IO_Write(0x3c0,start % 8); + break; case M_LIN8: start=vga.config.scan_len*8*y+x; vga.config.display_start=start/4; @@ -282,6 +345,15 @@ Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y) { IO_Write(0x3c0,0x13+32); IO_Write(0x3c0,(start % 4)*2); break; + case M_LIN16: + case M_LIN15: + start=vga.config.scan_len*4*y+x; + vga.config.display_start=start/4; + break; + case M_LIN32: + start=vga.config.scan_len*4*y+x; + vga.config.display_start=start/4; + break; default: return 0x1; } @@ -333,6 +405,9 @@ void INT10_SetupVESA(void) { /* Copy the pmode interface block */ int10.rom.pmode_interface=RealMake(0xc000,int10.rom.used); int10.rom.pmode_interface_size=sizeof(PmodeInterface); + switch (svgaCard) { + + } for (i=0;i Date: Mon, 30 Jan 2006 10:10:04 +0000 Subject: [PATCH 2367/4131] ZMBV codec for avi capturing Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2451 --- src/libs/zmbv/drvproc.cpp | 212 ++++++++++++++++ src/libs/zmbv/resource.h | 21 ++ src/libs/zmbv/zmbv.cpp | 516 ++++++++++++++++++++++++++++++++++++++ src/libs/zmbv/zmbv.def | 4 + src/libs/zmbv/zmbv.h | 112 +++++++++ src/libs/zmbv/zmbv.inf | 54 ++++ src/libs/zmbv/zmbv.sln | 21 ++ src/libs/zmbv/zmbv.vcproj | 141 +++++++++++ src/libs/zmbv/zmbv_vfw.h | 61 +++++ src/libs/zmbv/zmbv_vfw.rc | 123 +++++++++ 10 files changed, 1265 insertions(+) create mode 100644 src/libs/zmbv/drvproc.cpp create mode 100644 src/libs/zmbv/resource.h create mode 100644 src/libs/zmbv/zmbv.cpp create mode 100644 src/libs/zmbv/zmbv.def create mode 100644 src/libs/zmbv/zmbv.h create mode 100644 src/libs/zmbv/zmbv.inf create mode 100644 src/libs/zmbv/zmbv.sln create mode 100644 src/libs/zmbv/zmbv.vcproj create mode 100644 src/libs/zmbv/zmbv_vfw.h create mode 100644 src/libs/zmbv/zmbv_vfw.rc diff --git a/src/libs/zmbv/drvproc.cpp b/src/libs/zmbv/drvproc.cpp new file mode 100644 index 00000000..b6c37540 --- /dev/null +++ b/src/libs/zmbv/drvproc.cpp @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2002-2005 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. + */ +// +// Zipped Motion Block Video +// +// Based on Huffyuv by Ben Rudiak-Gould. +// which was based on MSYUV sample code, which is: +// Copyright (c) 1993 Microsoft Corporation. +// All Rights Reserved. +// + +#include "zmbv_vfw.h" + +/*************************************************************************** + * DriverProc - The entry point for an installable driver. + * + * PARAMETERS + * dwDriverId: For most messages, is the DWORD + * value that the driver returns in response to a message. + * Each time that the driver is opened, through the API, + * the driver receives a message and can return an + * arbitrary, non-zero value. The installable driver interface + * saves this value and returns a unique driver handle to the + * application. Whenever the application sends a message to the + * driver using the driver handle, the interface routes the message + * to this entry point and passes the corresponding . + * This mechanism allows the driver to use the same or different + * identifiers for multiple opens but ensures that driver handles + * are unique at the application interface layer. + * + * The following messages are not related to a particular open + * instance of the driver. For these messages, the dwDriverId + * will always be zero. + * + * DRV_LOAD, DRV_FREE, DRV_ENABLE, DRV_DISABLE, DRV_OPEN + * + * hDriver: This is the handle returned to the application by the + * driver interface. + * + * uiMessage: The requested action to be performed. Message + * values below are used for globally defined messages. + * Message values from to are used for + * defined driver protocols. Messages above are used + * for driver specific messages. + * + * lParam1: Data for this message. Defined separately for + * each message + * + * lParam2: Data for this message. Defined separately for + * each message + * + * RETURNS + * Defined separately for each message. + * + ***************************************************************************/ +LRESULT PASCAL DriverProc(DWORD dwDriverID, HDRVR hDriver, UINT uiMessage, LPARAM lParam1, LPARAM lParam2) { + CodecInst* pi = (CodecInst*)dwDriverID; + + switch (uiMessage) { + case DRV_LOAD: + return (LRESULT)1L; + + case DRV_FREE: + return (LRESULT)1L; + + case DRV_OPEN: + // GAAH! This used to return a pointer to 0xFFFF0000 when lParam==0! + return (LRESULT)(DWORD)(UINT) Open((ICOPEN*) lParam2); + + case DRV_CLOSE: + if (pi) Close(pi); + return (LRESULT)1L; + + /********************************************************************* + + state messages + + *********************************************************************/ + + // cwk + case DRV_QUERYCONFIGURE: // configuration from drivers applet + return (LRESULT)1L; + + case DRV_CONFIGURE: + pi->Configure((HWND)lParam1); + return DRV_OK; + + case ICM_CONFIGURE: + // + // return ICERR_OK if you will do a configure box, error otherwise + // + if (lParam1 == -1) + return pi->QueryConfigure() ? ICERR_OK : ICERR_UNSUPPORTED; + else + return pi->Configure((HWND)lParam1); + + case ICM_ABOUT: + // + // return ICERR_OK if you will do a about box, error otherwise + // + if (lParam1 == -1) + return pi->QueryAbout() ? ICERR_OK : ICERR_UNSUPPORTED; + else + return pi->About((HWND)lParam1); + + case ICM_GETSTATE: + return pi->GetState((LPVOID)lParam1, (DWORD)lParam2); + + case ICM_SETSTATE: + return pi->SetState((LPVOID)lParam1, (DWORD)lParam2); + + case ICM_GETINFO: + return pi->GetInfo((ICINFO*)lParam1, (DWORD)lParam2); + + case ICM_GETDEFAULTQUALITY: + if (lParam1) { + *((LPDWORD)lParam1) = 10000; + return ICERR_OK; + } + break; + + /********************************************************************* + + compression messages + + *********************************************************************/ + + case ICM_COMPRESS_QUERY: + return pi->CompressQuery((LPBITMAPINFOHEADER)lParam1, (LPBITMAPINFOHEADER)lParam2); + + case ICM_COMPRESS_BEGIN: + return pi->CompressBegin((LPBITMAPINFOHEADER)lParam1, (LPBITMAPINFOHEADER)lParam2); + + case ICM_COMPRESS_GET_FORMAT: + return pi->CompressGetFormat((LPBITMAPINFOHEADER)lParam1, (LPBITMAPINFOHEADER)lParam2); + + case ICM_COMPRESS_GET_SIZE: + return pi->CompressGetSize((LPBITMAPINFOHEADER)lParam1, (LPBITMAPINFOHEADER)lParam2); + + case ICM_COMPRESS: + return pi->Compress((ICCOMPRESS*)lParam1, (DWORD)lParam2); + + case ICM_COMPRESS_END: + return pi->CompressEnd(); + + /********************************************************************* + + decompress messages + + *********************************************************************/ + + case ICM_DECOMPRESS_QUERY: + return pi->DecompressQuery((LPBITMAPINFOHEADER)lParam1, (LPBITMAPINFOHEADER)lParam2); + + case ICM_DECOMPRESS_BEGIN: + return pi->DecompressBegin((LPBITMAPINFOHEADER)lParam1, (LPBITMAPINFOHEADER)lParam2); + + case ICM_DECOMPRESS_GET_FORMAT: + return pi->DecompressGetFormat((LPBITMAPINFOHEADER)lParam1, (LPBITMAPINFOHEADER)lParam2); + + case ICM_DECOMPRESS_GET_PALETTE: + return pi->DecompressGetPalette((LPBITMAPINFOHEADER)lParam1, (LPBITMAPINFOHEADER)lParam2); + + case ICM_DECOMPRESS: + return pi->Decompress((ICDECOMPRESS*)lParam1, (DWORD)lParam2); + + case ICM_DECOMPRESS_END: + return pi->DecompressEnd(); + + /********************************************************************* + + standard driver messages + + *********************************************************************/ + + case DRV_DISABLE: + case DRV_ENABLE: + return (LRESULT)1L; + + case DRV_INSTALL: + case DRV_REMOVE: + return (LRESULT)DRV_OK; + } + + if (uiMessage < DRV_USER) + return DefDriverProc(dwDriverID, hDriver, uiMessage, lParam1, lParam2); + else + return ICERR_UNSUPPORTED; +} + + +HMODULE hmoduleCodec=0; + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD, LPVOID) { + hmoduleCodec = (HMODULE) hinstDLL; + return TRUE; +} diff --git a/src/libs/zmbv/resource.h b/src/libs/zmbv/resource.h new file mode 100644 index 00000000..f4830af1 --- /dev/null +++ b/src/libs/zmbv/resource.h @@ -0,0 +1,21 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by zmbv_vfw.rc +// +#define IDD_ABOUT 101 +#define IDD_CONFIGURE 102 +#define IDC_HOMEPAGE 1000 +#define IDC_EMAIL 1001 +#define IDC_SLIDER1 1008 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1009 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/libs/zmbv/zmbv.cpp b/src/libs/zmbv/zmbv.cpp new file mode 100644 index 00000000..b697934c --- /dev/null +++ b/src/libs/zmbv/zmbv.cpp @@ -0,0 +1,516 @@ +/* + * Copyright (C) 2002-2005 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 +#include +#include +#include + +#include "zmbv.h" + +#define DBZV_VERSION_HIGH 0 +#define DBZV_VERSION_LOW 1 + +#define COMPRESSION_NONE 0 +#define COMPRESSION_ZLIB 1 + +#define MAX_VECTOR 16 + +#define Mask_KeyFrame 0x01 +#define Mask_DeltaPalette 0x02 + +zmbv_format_t BPPFormat( int bpp ) { + switch (bpp) { + case 8: + return ZMBV_FORMAT_8BPP; + case 15: + return ZMBV_FORMAT_15BPP; + case 16: + return ZMBV_FORMAT_16BPP; + case 32: + return ZMBV_FORMAT_32BPP; + } + return ZMBV_FORMAT_NONE; +} +int VideoCodec::NeededSize( int _width, int _height, zmbv_format_t _format) { + int f; + switch (_format) { + case ZMBV_FORMAT_8BPP:f = 1;break; + case ZMBV_FORMAT_15BPP:f = 2;break; + case ZMBV_FORMAT_16BPP:f = 2;break; + case ZMBV_FORMAT_32BPP:f = 4;break; + default: + return -1; + } + f = f*_width*_height + 2*(1+(_width/8)) * (1+(_height/8))+1024; + return f + f/1000; +} + +bool VideoCodec::SetupBuffers(zmbv_format_t _format, int blockwidth, int blockheight) { + FreeBuffers(); + palsize = 0; + switch (_format) { + case ZMBV_FORMAT_8BPP: + pixelsize = 1; + palsize = 256; + break; + case ZMBV_FORMAT_15BPP: + pixelsize = 2; + break; + case ZMBV_FORMAT_16BPP: + pixelsize = 2; + break; + case ZMBV_FORMAT_32BPP: + pixelsize = 4; + break; + default: + return false; + }; + bufsize = (height+2*MAX_VECTOR)*pitch*pixelsize+2048; + + buf1 = new unsigned char[bufsize]; + buf2 = new unsigned char[bufsize]; + work = new unsigned char[bufsize]; + + int xblocks = (width/blockwidth); + int xleft = width % blockwidth; + if (xleft) xblocks++; + int yblocks = (height/blockheight); + int yleft = height % blockheight; + if (yleft) yblocks++; + blockcount=yblocks*xblocks; + blocks=new FrameBlock[blockcount]; + + if (!buf1 || !buf2 || !work || !blocks) { + FreeBuffers(); + return false; + } + int y,x,i; + i=0; + for (y=0;y +INLINE int VideoCodec::PossibleBlock(int vx,int vy,FrameBlock * block) { + int ret=0; + P * pold=((P*)oldframe)+block->start+(vy*pitch)+vx; + P * pnew=((P*)newframe)+block->start;; + for (int y=0;ydy;y+=4) { + for (int x=0;xdx;x+=4) { + int test=0-((pold[x]-pnew[x])&0x00ffffff); + ret-=(test>>31); + } + pold+=pitch*4; + pnew+=pitch*4; + } + return ret; +} + +template +INLINE int VideoCodec::CompareBlock(int vx,int vy,FrameBlock * block) { + int ret=0; + P * pold=((P*)oldframe)+block->start+(vy*pitch)+vx; + P * pnew=((P*)newframe)+block->start;; + for (int y=0;ydy;y++) { + for (int x=0;xdx;x++) { + int test=0-((pold[x]-pnew[x])&0x00ffffff); + ret-=(test>>31); + } + pold+=pitch; + pnew+=pitch; + } + return ret; +} + +template +INLINE void VideoCodec::AddXorBlock(int vx,int vy,FrameBlock * block) { + P * pold=((P*)oldframe)+block->start+(vy*pitch)+vx; + P * pnew=((P*)newframe)+block->start; + for (int y=0;ydy;y++) { + for (int x=0;xdx;x++) { + *((P*)&work[workUsed])=pnew[x] ^ pold[x]; + workUsed+=sizeof(P); + } + pold+=pitch; + pnew+=pitch; + } +} + +template +void VideoCodec::AddXorFrame(void) { + int written=0; + int lastvector=0; + signed char * vectors=(signed char*)&work[workUsed]; + /* Align the following xor data on 4 byte boundary*/ + workUsed=(workUsed + blockcount*2 +3) & ~3; + int totalx=0; + int totaly=0; + for (int b=0;b(0,0, block); + int possibles=64; + for (int v=0;v(vx, vy, block) < 4) { + possibles--; +// if (!possibles) Msg("Ran out of possibles, at %d of %d best %d\n",v,VectorCount,bestchange); + int testchange=CompareBlock

(vx,vy, block); + if (testchange(bestvx, bestvy, block); + } + } +} + +bool VideoCodec::SetupCompress( int _width, int _height ) { + width = _width; + height = _height; + pitch = _width + 2*MAX_VECTOR; + format = ZMBV_FORMAT_NONE; + if (deflateInit (&zstream, 4) != Z_OK) + return false; + return true; +} + +bool VideoCodec::SetupDecompress( int _width, int _height) { + width = _width; + height = _height; + pitch = _width + 2*MAX_VECTOR; + format = ZMBV_FORMAT_NONE; + if (inflateInit (&zstream) != Z_OK) + return false; + return true; +} + +bool VideoCodec::PrepareCompressFrame(int flags, zmbv_format_t _format, char * pal, void *writeBuf, int writeSize) { + int i; + unsigned char *firstByte; + + if (_format != format) { + if (!SetupBuffers( _format, 16, 16)) + return false; + flags|=1; //Force a keyframe + } + /* replace oldframe with new frame */ + unsigned char *copyFrame = newframe; + newframe = oldframe; + oldframe = copyFrame; + + compress.linesDone = 0; + compress.writeSize = writeSize; + compress.writeDone = 1; + compress.writeBuf = (unsigned char *)writeBuf; + /* Set a pointer to the first byte which will contain info about this frame */ + firstByte = compress.writeBuf; + *firstByte = 0; + //Reset the work buffer + workUsed = 0;workPos = 0; + if (flags & 1) { + /* Make a keyframe */ + *firstByte |= Mask_KeyFrame; + KeyframeHeader * header = (KeyframeHeader *)(compress.writeBuf + compress.writeDone); + header->high_version = DBZV_VERSION_HIGH; + header->low_version = DBZV_VERSION_LOW; + header->compression = COMPRESSION_ZLIB; + header->format = format; + header->blockwidth = 16; + header->blockheight = 16; + compress.writeDone += sizeof(KeyframeHeader); + /* Copy the new frame directly over */ + if (palsize) { + if (pal) + memcpy(&palette, pal, sizeof(palette)); + else + memset(&palette,0, sizeof(palette)); + /* keyframes get the full palette */ + for (i=0;i(); + break; + case ZMBV_FORMAT_15BPP: + case ZMBV_FORMAT_16BPP: + AddXorFrame(); + break; + case ZMBV_FORMAT_32BPP: + AddXorFrame(); + break; + } + } + /* Create the actual frame with compression */ + zstream.next_in = (Bytef *)work; + zstream.avail_in = workUsed; + zstream.total_in = 0; + + zstream.next_out = (Bytef *)(compress.writeBuf + compress.writeDone); + zstream.avail_out = compress.writeSize - compress.writeDone; + zstream.total_out = 0; + int res = deflate(&zstream, Z_SYNC_FLUSH); + return compress.writeDone + zstream.total_out; +} + +template +INLINE void VideoCodec::UnXorBlock(int vx,int vy,FrameBlock * block) { + P * pold=((P*)oldframe)+block->start+(vy*pitch)+vx; + P * pnew=((P*)newframe)+block->start; + for (int y=0;ydy;y++) { + for (int x=0;xdx;x++) { + pnew[x]=pold[x]^*((P*)&work[workPos]); + workPos+=sizeof(P); + } + pold+=pitch; + pnew+=pitch; + } +} + +template +INLINE void VideoCodec::CopyBlock(int vx,int vy,FrameBlock * block) { + P * pold=((P*)oldframe)+block->start+(vy*pitch)+vx; + P * pnew=((P*)newframe)+block->start; + for (int y=0;ydy;y++) { + for (int x=0;xdx;x++) { + pnew[x]=pold[x]; + } + pold+=pitch; + pnew+=pitch; + } +} + +template +void VideoCodec::UnXorFrame(void) { + signed char * vectors=(signed char *)&work[workPos]; + workPos=(workPos + blockcount*2 + 3) & ~3; + for (int b=0;b> 1; + int vy = vectors[b*2+1] >> 1; + if (xor) UnXorBlock

(vx,vy,block); + else CopyBlock

(vx,vy,block); + } +} + +bool VideoCodec::DecompressFrame(void * framedata, int size) { + unsigned char *data=(unsigned char *)framedata; + unsigned char tag;int i; + + tag = *data++; + if (--size<=0) + return false; + if (tag & Mask_KeyFrame) { + KeyframeHeader * header = (KeyframeHeader *)data; + size -= sizeof(KeyframeHeader);data += sizeof(KeyframeHeader); + if (size<=0) + return false; + if (header->low_version != DBZV_VERSION_LOW || header->high_version != DBZV_VERSION_HIGH) + return false; + if (format != (zmbv_format_t)header->format && !SetupBuffers((zmbv_format_t)header->format, header->blockwidth, header->blockheight)) + return false; + inflateReset(&zstream); + } + zstream.next_in = (Bytef *)data; + zstream.avail_in = size; + zstream.total_in = 0; + + zstream.next_out = (Bytef *)work; + zstream.avail_out = bufsize; + zstream.total_out = 0; + int res = inflate(&zstream, Z_FINISH); + workUsed= zstream.total_out; + workPos = 0; + if (tag & Mask_KeyFrame) { + if (palsize) { + for (i=0;i(); + break; + case ZMBV_FORMAT_15BPP: + case ZMBV_FORMAT_16BPP: + UnXorFrame(); + break; + case ZMBV_FORMAT_32BPP: + UnXorFrame(); + break; + } + } + return true; +} + +void VideoCodec::Output_UpsideDown_24(void *output) { + int i; + unsigned char *r; + unsigned char *w = (unsigned char *)output; + for (i=height-1;i>=0;i--) { + r = newframe + pixelsize*(MAX_VECTOR+(i+MAX_VECTOR)*pitch); + for (int j=0;j + void AddXorFrame(void); + template + void UnXorFrame(void); + template + INLINE int PossibleBlock(int vx,int vy,FrameBlock * block); + template + INLINE int CompareBlock(int vx,int vy,FrameBlock * block); + template + INLINE void AddXorBlock(int vx,int vy,FrameBlock * block); + template + INLINE void UnXorBlock(int vx,int vy,FrameBlock * block); + template + INLINE void CopyBlock(int vx, int vy,FrameBlock * block); +public: + VideoCodec(); + bool SetupCompress( int _width, int _height); + bool SetupDecompress( int _width, int _height); + zmbv_format_t BPPFormat( int bpp ); + int NeededSize( int _width, int _height, zmbv_format_t _format); + + void CompressLines(int lineCount, void *lineData[]); + bool PrepareCompressFrame(int flags, zmbv_format_t _format, char * pal, void *writeBuf, int writeSize); + int FinishCompressFrame( void ); + bool DecompressFrame(void * framedata, int size); + void Output_UpsideDown_24(void * output); +}; diff --git a/src/libs/zmbv/zmbv.inf b/src/libs/zmbv/zmbv.inf new file mode 100644 index 00000000..d1b81c98 --- /dev/null +++ b/src/libs/zmbv/zmbv.inf @@ -0,0 +1,54 @@ +; +; Zip Motion Block Video AVI codec +; +; Copyright (c) 2000 Ben Rudiak-Gould +; +; This Windows 9x Installation INF File by Rainbow Software +; +[version] +signature="$CHICAGO$" + +[DefaultInstall] +CopyFiles=ZMBV.Files.Inf,ZMBV.Files.Dll +AddReg=ZMBV.Reg +UpdateInis=ZMBV.INIs + +[DefaultUnInstall] +DelFiles=ZMBV.Files.Dll,ZMBV.Files.Inf,ZMBV.Files.Ini +DelReg=ZMBV.Reg +UpdateInis=ZMBV.INIs.Del + +[SourceDisksNames] +1="Zip Motion Block Video codec","",1 + +[SourceDisksFiles] +ZMBV.INF=1 + +[DestinationDirs] +ZMBV.Files.Inf=17 +ZMBV.Files.Dll=11 +ZMBV.Files.Ini=25 + +[ZMBV.Files.Inf] +zmbv.inf + +[ZMBV.Files.Dll] +zmbv.dll + +[ZMBV.Files.Ini] +zmbv.ini + +[ZMBV.Reg] +HKLM,SYSTEM\CurrentControlSet\Control\MediaResources\icm\VIDC.ZMBV,Description,,"Zip Motion Block Video [ZMBV]" +HKLM,SYSTEM\CurrentControlSet\Control\MediaResources\icm\VIDC.ZMBV,Driver,,"zmbv.dll" +HKLM,SYSTEM\CurrentControlSet\Control\MediaResources\icm\VIDC.ZMBV,FriendlyName,,"Zip Motion Block Video [ZMBV]" + +HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV +HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,DisplayName,,"Zip Motion Block Video codec (Remove Only)" +HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,UninstallString,,"rundll.exe setupx.dll,InstallHinfSection DefaultUninstall 132 %17%\ZMBV.INF" + +[ZMBV.INIs] +system.ini, drivers32,, "VIDC.ZMBV=zmbv.dll" + +[ZMBV.INIs.Del] +system.ini, drivers32, "VIDC.ZMBV=zmbv.dll" \ No newline at end of file diff --git a/src/libs/zmbv/zmbv.sln b/src/libs/zmbv/zmbv.sln new file mode 100644 index 00000000..aea19d7c --- /dev/null +++ b/src/libs/zmbv/zmbv.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zmbv", "zmbv.vcproj", "{619CF3F9-C373-4BD5-93DA-025F5E16F8FA}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {619CF3F9-C373-4BD5-93DA-025F5E16F8FA}.Debug.ActiveCfg = Debug|Win32 + {619CF3F9-C373-4BD5-93DA-025F5E16F8FA}.Debug.Build.0 = Debug|Win32 + {619CF3F9-C373-4BD5-93DA-025F5E16F8FA}.Release.ActiveCfg = Release|Win32 + {619CF3F9-C373-4BD5-93DA-025F5E16F8FA}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/src/libs/zmbv/zmbv.vcproj b/src/libs/zmbv/zmbv.vcproj new file mode 100644 index 00000000..ce973b86 --- /dev/null +++ b/src/libs/zmbv/zmbv.vcproj @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/zmbv/zmbv_vfw.h b/src/libs/zmbv/zmbv_vfw.h new file mode 100644 index 00000000..9f50656b --- /dev/null +++ b/src/libs/zmbv/zmbv_vfw.h @@ -0,0 +1,61 @@ +// +// Huffyuv v2.1.1, by Ben Rudiak-Gould. +// http://www.math.berkeley.edu/~benrg/huffyuv.html +// +// This file is copyright 2000 Ben Rudiak-Gould, and distributed under +// the terms of the GNU General Public License, v2 or later. See +// http://www.gnu.org/copyleft/gpl.html. +// +// I edit these files in 10-point Verdana, a proportionally-spaced font. +// You may notice formatting oddities if you use a monospaced font. +// + + +#include +#include +#include +#include "zmbv.h" +#pragma hdrstop + +extern HMODULE hmoduleCodec; + + +// huffyuv.cpp + +class CodecInst { +private: + VideoCodec * codec; +public: + CodecInst(); + ~CodecInst(); + + BOOL QueryAbout(); + DWORD About(HWND hwnd); + + BOOL QueryConfigure(); + DWORD Configure(HWND hwnd); + + DWORD GetState(LPVOID pv, DWORD dwSize); + DWORD SetState(LPVOID pv, DWORD dwSize); + + DWORD GetInfo(ICINFO* icinfo, DWORD dwSize); + + DWORD CompressQuery(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut); + DWORD CompressGetFormat(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut); + DWORD CompressBegin(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut); + DWORD CompressGetSize(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut); + DWORD Compress(ICCOMPRESS* icinfo, DWORD dwSize); + DWORD CompressEnd(); + + DWORD DecompressQuery(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut); + DWORD DecompressGetFormat(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut); + DWORD DecompressBegin(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut); + + DWORD Decompress(ICDECOMPRESS* icinfo, DWORD dwSize); + DWORD DecompressGetPalette(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut); + DWORD DecompressEnd(); +}; + +CodecInst* Open(ICOPEN* icinfo); +DWORD Close(CodecInst* pinst); + diff --git a/src/libs/zmbv/zmbv_vfw.rc b/src/libs/zmbv/zmbv_vfw.rc new file mode 100644 index 00000000..6678d1a5 --- /dev/null +++ b/src/libs/zmbv/zmbv_vfw.rc @@ -0,0 +1,123 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUT DIALOGEX 0, 0, 167, 55 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "DOSBox Video Codec v0.1" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + DEFPUSHBUTTON "OK",IDOK,131,34,29,14 + CTEXT "Zipped Motion Block Video v 0.1\nCopyright 2005, DOSBox Team", + IDC_STATIC,7,7,153,25,SS_NOPREFIX + PUSHBUTTON "Email author",IDC_EMAIL,7,34,50,14 + PUSHBUTTON "Visit home page",IDC_HOMEPAGE,59,34,58,14 +END + +IDD_CONFIGURE DIALOGEX 0, 0, 213, 146 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "ZMBV configuration dialog" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + PUSHBUTTON "Email author",IDC_EMAIL,44,86,50,14 + PUSHBUTTON "Visit home page",IDC_HOMEPAGE,109,87,58,14 + DEFPUSHBUTTON "OK",IDOK,44,125,50,14 + PUSHBUTTON "Cancel",IDCANCEL,117,125,50,14 + CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH | + TBS_NOTICKS | WS_TABSTOP,57,30,92,18 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_ABOUT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 160 + TOPMARGIN, 7 + BOTTOMMARGIN, 48 + END + + IDD_CONFIGURE, DIALOG + BEGIN + LEFTMARGIN, 44 + RIGHTMARGIN, 167 + TOPMARGIN, 6 + BOTTOMMARGIN, 139 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + From 960f3b55ec31a94fc6550da585f0343fb0f212a6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 10:11:18 +0000 Subject: [PATCH 2368/4131] new svgacard option Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2452 --- src/dosbox.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index c2d5294f..1ed7a110 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.91 2005-12-22 20:37:20 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.92 2006-01-30 10:11:18 harekiet Exp $ */ #include #include @@ -41,6 +41,7 @@ Config * control; MachineType machine; +SVGACards svgaCard; /* The whole load of startups for all the subfunctions */ void MSG_Init(Section_prop *); @@ -50,7 +51,7 @@ void PAGING_Init(Section *); void IO_Init(Section * ); void CALLBACK_Init(Section*); void PROGRAMS_Init(Section*); -void CREDITS_Init(Section*); +//void CREDITS_Init(Section*); void RENDER_Init(Section*); void VGA_Init(Section*); @@ -128,11 +129,11 @@ static Bitu Normal_Loop(void) { if (RemainTicks>0) { TIMER_AddTick(); RemainTicks--; - GFX_Events(); } else goto increaseticks; } } increaseticks: + GFX_Events(); NewTicks=GetTicks(); if (NewTicks>LastTicks) { RemainTicks=NewTicks-LastTicks; @@ -173,6 +174,7 @@ static void DOSBOX_RealInit(Section * sec) { DOSBOX_SetLoop(&Normal_Loop); MSG_Init(section); + svgaCard = SVGA_S3Trio; machine=MCH_VGA;std::string cmd_machine; const char * mtype; if (control->cmdline->FindString("-machine",cmd_machine,true)) mtype=cmd_machine.c_str(); @@ -227,9 +229,9 @@ void DOSBOX_Init(void) { secprop->Add_string("scaler","normal2x"); MSG_Add("RENDER_CONFIGFILE_HELP", "frameskip -- How many frames dosbox skips before drawing one.\n" - "aspect -- Do aspect correction.\n" + "aspect -- Do aspect correction, if your output method doesn't support scaling this can slow things down!.\n" "scaler -- Scaler used to enlarge/enhance low resolution modes.\n" - " Supported are none,normal2x,advmame2x,advmame3x,advinterp2x,interp2x,tv2x.\n" + " Supported are none,normal2x,normal3x,advmame2x,advmame3x,advinterp2x,interp2x,tv2x,tv3x,rgb2x,rgb3x,scan2x,scan3x.\n" ); secprop=control->AddSection_prop("cpu",&CPU_Init,true);//done @@ -399,6 +401,8 @@ void DOSBOX_Init(void) { "ipx -- Enable ipx over UDP/IP emulation.\n" ); #endif +// secprop->AddInitFunction(&CREDITS_Init); + secline=control->AddSection_line("autoexec",&AUTOEXEC_Init); MSG_Add("AUTOEXEC_CONFIGFILE_HELP", "Lines in this section will be run at startup.\n" From 16e30fb710217591da46f74bb0abc0846a2b73f8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 10:20:25 +0000 Subject: [PATCH 2369/4131] Add the missing losing focus call Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2453 --- include/mapper.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/mapper.h b/include/mapper.h index 78bddc00..469265f8 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -30,8 +30,7 @@ void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char * eve void MAPPER_Init(void); void MAPPER_StartUp(Section * sec); void MAPPER_Run(void); - - +void MAPPER_LosingFocus(void); #define MMOD1 0x1 From b202a02f2e90bcdffaab647475f31d71c90c0cf4 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 10:23:30 +0000 Subject: [PATCH 2370/4131] Remove SSE instrinsics include Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2454 --- src/gui/render_scalers.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index aaba8420..8ea118fa 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -21,7 +21,6 @@ //#include "render.h" #include "video.h" -#include #define SCALER_MAXWIDTH 1024 #define SCALER_MAXHEIGHT 768 From 6804f85609eef3f906a9bf24bb88046574ef8c6e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 30 Jan 2006 10:33:58 +0000 Subject: [PATCH 2371/4131] add vga_23.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2455 --- src/hardware/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index 60657aaa..c733621c 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -9,7 +9,7 @@ noinst_LIBRARIES = libhardware.a libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler.cpp joystick.cpp keyboard.cpp \ memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp vga_other.cpp \ - vga_memory.cpp vga_misc.cpp vga_seq.cpp vga_xga.cpp cmos.cpp disney.cpp \ - gus.cpp mpu401.cpp ipx.cpp ipxserver.cpp + vga_memory.cpp vga_misc.cpp vga_seq.cpp vga_xga.cpp vga_s3.cpp \ + cmos.cpp disney.cpp gus.cpp mpu401.cpp ipx.cpp ipxserver.cpp From 78f4e566bc735f101539f4b4dde0c881d2ece6c9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 30 Jan 2006 10:45:49 +0000 Subject: [PATCH 2372/4131] fix a memleak Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2456 --- src/debug/debug_gui.cpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 95c42d7c..1ae6da60 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -16,9 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - +/* $Id: debug_gui.cpp,v 1.26 2006-01-30 10:45:49 qbix79 Exp $ */ #include "dosbox.h" + #if C_DEBUG #include "setup.h" #include @@ -36,11 +37,16 @@ struct _LogGroup { char * front; bool enabled; }; +#include +#include +using namespace std; + +#define MAX_LOG_BUFFER 500 +static list logBuff; +static list::iterator logBuffPos = logBuff.end(); static _LogGroup loggrp[LOG_MAX]={{"",true},{0,false}}; static FILE* debuglog; -static std::list logBuff; -static std::list::iterator logBuffPos = logBuff.end(); extern int old_cursor_state; @@ -60,19 +66,15 @@ void DEBUG_ShowMsg(char * format,...) { if(debuglog) fprintf(debuglog,"%s",buf); - char* newLine = new char[strlen(buf) + 1]; - strcpy(newLine, buf); if (logBuffPos!=logBuff.end()) { logBuffPos=logBuff.end(); DEBUG_RefreshPage(0); mvwprintw(dbg.win_out,dbg.win_out->_maxy-1, 0, ""); } - logBuff.push_back(newLine); - if (logBuff.size()>500) { - char * firstline = logBuff.front(); - delete firstline; + logBuff.push_back(buf); + if (logBuff.size() > MAX_LOG_BUFFER) logBuff.pop_front(); - } + logBuffPos = logBuff.end(); wprintw(dbg.win_out,"%s",buf); wrefresh(dbg.win_out); @@ -82,14 +84,14 @@ void DEBUG_RefreshPage(char scroll) { if (scroll==-1 && logBuffPos!=logBuff.begin()) logBuffPos--; else if (scroll==1 && logBuffPos!=logBuff.end()) logBuffPos++; - std::list::iterator i = logBuffPos; + list::iterator i = logBuffPos; int rem_lines = dbg.win_out->_maxy; wclear(dbg.win_out); while (rem_lines > 0 && i!=logBuff.begin()) { - rem_lines -= (int) (strlen(*--i) / dbg.win_out->_maxx) + 1; - mvwprintw(dbg.win_out,rem_lines-1, 0, *i); + rem_lines -= (int) ((*--i).size() / dbg.win_out->_maxx) + 1; + mvwprintw(dbg.win_out,rem_lines-1, 0, (*i).c_str()); } wrefresh(dbg.win_out); } From 952f8f0d1dbd6d71a3b96f93888d24445c63308c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 10:55:49 +0000 Subject: [PATCH 2373/4131] Fix some gcc compilation issues Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2457 --- configure.in | 2 ++ src/Makefile.am | 5 +++-- src/hardware/vga_draw.cpp | 3 ++- src/libs/Makefile.am | 3 +++ src/libs/zmbv/Makefile.am | 4 ++++ src/libs/zmbv/zmbv.cpp | 5 +++-- src/libs/zmbv/zmbv.h | 8 +++++++- 7 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 src/libs/Makefile.am create mode 100644 src/libs/zmbv/Makefile.am diff --git a/configure.in b/configure.in index d4d95ced..3afe2214 100644 --- a/configure.in +++ b/configure.in @@ -296,6 +296,8 @@ src/gui/Makefile src/hardware/Makefile src/hardware/serialport/Makefile src/ints/Makefile +src/libs/Makefile +src/libs/zmbv/Makefile src/misc/Makefile src/shell/Makefile src/platform/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index c58e2e4f..c18bf996 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,10 +1,11 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -SUBDIRS = cpu debug dos fpu gui hardware ints misc shell platform +SUBDIRS = cpu debug dos fpu gui hardware libs 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 hardware/serialport/libserial.a + ints/libints.a misc/libmisc.a shell/libshell.a hardware/serialport/libserial.a \ + libs/zmbv/libzmbv.a diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 1d9b6e29..96b6c742 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -237,6 +237,7 @@ static Bit8u * VGA_Draw_VGA_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) static Bit32u FontMask[2]={0xffffffff,0x0}; static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { + Bitu font_addr; Bit32u * draw=(Bit32u *)TempLine; Bit8u * vidmem=&vga.gfxmem_start[vidstart]; for (Bitu cx=0;cx> 1; + font_addr = (vga.draw.cursor.address-vidstart) >> 1; if (font_addr>=0 && font_addrvga.draw.cursor.eline) goto skip_cursor; diff --git a/src/libs/Makefile.am b/src/libs/Makefile.am new file mode 100644 index 00000000..b74bb58a --- /dev/null +++ b/src/libs/Makefile.am @@ -0,0 +1,3 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include + +SUBDIRS = zmbv \ No newline at end of file diff --git a/src/libs/zmbv/Makefile.am b/src/libs/zmbv/Makefile.am new file mode 100644 index 00000000..6f6f5e31 --- /dev/null +++ b/src/libs/zmbv/Makefile.am @@ -0,0 +1,4 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include + +noinst_LIBRARIES = libzmbv.a +libzmbv_a_SOURCES = zmbv.cpp zmbv.h diff --git a/src/libs/zmbv/zmbv.cpp b/src/libs/zmbv/zmbv.cpp index b697934c..01436953 100644 --- a/src/libs/zmbv/zmbv.cpp +++ b/src/libs/zmbv/zmbv.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -396,10 +397,10 @@ void VideoCodec::UnXorFrame(void) { workPos=(workPos + blockcount*2 + 3) & ~3; for (int b=0;b> 1; int vy = vectors[b*2+1] >> 1; - if (xor) UnXorBlock

(vx,vy,block); + if (delta) UnXorBlock

(vx,vy,block); else CopyBlock

(vx,vy,block); } } diff --git a/src/libs/zmbv/zmbv.h b/src/libs/zmbv/zmbv.h index f0b8b4f4..b1c97aa2 100644 --- a/src/libs/zmbv/zmbv.h +++ b/src/libs/zmbv/zmbv.h @@ -16,8 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - +#ifndef DOSBOX_DOSBOX_H +#ifdef _MSC_VER #define INLINE __forceinline +#else +#define INLINE inline +#endif +#endif + #define CODEC_4CC "ZMBV" typedef enum { From 519033406932ee3430a8b537873e4dbfe939a1c5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 11:29:06 +0000 Subject: [PATCH 2374/4131] Add video for windows control for zmbv codec Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2458 --- src/libs/zmbv/zmbv_vfw.cpp | 334 +++++++++++++++++++++++++++++++++++++ 1 file changed, 334 insertions(+) create mode 100644 src/libs/zmbv/zmbv_vfw.cpp diff --git a/src/libs/zmbv/zmbv_vfw.cpp b/src/libs/zmbv/zmbv_vfw.cpp new file mode 100644 index 00000000..c0ac550c --- /dev/null +++ b/src/libs/zmbv/zmbv_vfw.cpp @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2002-2005 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. + */ +// +// Zipped Motion Block Video +// +// Based on Huffyuv by Ben Rudiak-Gould. +// which was based on MSYUV sample code, which is: +// Copyright (c) 1993 Microsoft Corporation. +// All Rights Reserved. +// + +#include "zmbv_vfw.h" +#include "resource.h" + +#include +#include + +TCHAR szDescription[] = TEXT("Zipped Motion Block Video v0.1"); +TCHAR szName[] = TEXT(CODEC_4CC); + +#define VERSION 0x00000001 // 0.1 + +/******************************************************************** +********************************************************************/ + +CodecInst *encode_table_owner, *decode_table_owner; + +/******************************************************************** +********************************************************************/ + +void Msg(const char fmt[], ...) { + DWORD written; + char buf[2000]; + va_list val; + + va_start(val, fmt); + wvsprintf(buf, fmt, val); + + const COORD _80x50 = {80,50}; + static BOOL startup = (AllocConsole(), SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), _80x50)); + WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), buf, lstrlen(buf), &written, 0); +} + + +/******************************************************************** +********************************************************************/ + +CodecInst::CodecInst() { + codec = 0; +} + +CodecInst* Open(ICOPEN* icinfo) { + if (icinfo && icinfo->fccType != ICTYPE_VIDEO) + return NULL; + + CodecInst* pinst = new CodecInst(); + + if (icinfo) icinfo->dwError = pinst ? ICERR_OK : ICERR_MEMORY; + + return pinst; +} + +DWORD Close(CodecInst* pinst) { +// delete pinst; // this caused problems when deleting at app close time + return 1; +} + +/******************************************************************** +********************************************************************/ + + +/******************************************************************** +********************************************************************/ + +BOOL CodecInst::QueryAbout() { return TRUE; } + +static BOOL CALLBACK AboutDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { + if (uMsg == WM_COMMAND) { + switch (LOWORD(wParam)) { + case IDOK: + EndDialog(hwndDlg, 0); + break; + case IDC_HOMEPAGE: + ShellExecute(NULL, NULL, "http://dosbox.sf.net", NULL, NULL, SW_SHOW); + break; + case IDC_EMAIL: + ShellExecute(NULL, NULL, "mailto:db.crew@gmail.com", NULL, NULL, SW_SHOW); + break; + } + } + return FALSE; +} +DWORD CodecInst::About(HWND hwnd) { + DialogBox(hmoduleCodec, MAKEINTRESOURCE(IDD_ABOUT), hwnd, AboutDialogProc); + return ICERR_OK; +} + +static BOOL CALLBACK ConfigureDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { + + if (uMsg == WM_INITDIALOG) { + + } else if (uMsg == WM_COMMAND) { + + switch (LOWORD(wParam)) { + + case IDOK: + + case IDCANCEL: + EndDialog(hwndDlg, 0); + break; + + default: + return AboutDialogProc(hwndDlg, uMsg, wParam, lParam); // handle email and home-page buttons + } + } + return FALSE; +} + +BOOL CodecInst::QueryConfigure() { return TRUE; } + +DWORD CodecInst::Configure(HWND hwnd) { + DialogBox(hmoduleCodec, MAKEINTRESOURCE(IDD_CONFIGURE), hwnd, ConfigureDialogProc); + return ICERR_OK; +} + + +/******************************************************************** +********************************************************************/ + + +// we have no state information which needs to be stored + +DWORD CodecInst::GetState(LPVOID pv, DWORD dwSize) { return 0; } + +DWORD CodecInst::SetState(LPVOID pv, DWORD dwSize) { return 0; } + + +DWORD CodecInst::GetInfo(ICINFO* icinfo, DWORD dwSize) { + if (icinfo == NULL) + return sizeof(ICINFO); + + if (dwSize < sizeof(ICINFO)) + return 0; + + icinfo->dwSize = sizeof(ICINFO); + icinfo->fccType = ICTYPE_VIDEO; + memcpy(&icinfo->fccHandler,CODEC_4CC, 4); + icinfo->dwFlags = VIDCF_FASTTEMPORALC | VIDCF_FASTTEMPORALD | VIDCF_TEMPORAL | VIDCF_QUALITY; + + icinfo->dwVersion = VERSION; + icinfo->dwVersionICM = ICVERSION; + MultiByteToWideChar(CP_ACP, 0, szDescription, -1, icinfo->szDescription, sizeof(icinfo->szDescription)/sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, szName, -1, icinfo->szName, sizeof(icinfo->szName)/sizeof(WCHAR)); + + return sizeof(ICINFO); +} + +/******************************************************************** +****************************************************************/ + +static bool CanCompress(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) { + if (lpbiIn) { + if (lpbiIn->biCompression) return false; + if (lpbiIn->biBitCount==24) return false; + } else return false; + if (lpbiOut) { + if (memcmp(&lpbiOut->biCompression,CODEC_4CC, 4)) + return false; + } else return false; + return true; +} +/******************************************************************** +****************************************************************/ + +DWORD CodecInst::CompressQuery(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) { + if (CanCompress(lpbiIn,lpbiOut)) return ICERR_OK; + return ICERR_BADFORMAT; +} + +DWORD CodecInst::CompressGetFormat(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) { + if (!lpbiOut) + return sizeof(BITMAPINFOHEADER); + if (!CanCompress(lpbiIn,lpbiOut)) + return ICERR_BADFORMAT; + return ICERR_OK; +} + +DWORD CodecInst::CompressBegin(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) { + CompressEnd(); // free resources if necessary + if (!CanCompress(lpbiIn, lpbiOut)) + return ICERR_BADFORMAT; + codec = new VideoCodec(); + if (!codec) + return ICERR_MEMORY; + if (!codec->SetupCompress( lpbiIn->biWidth, lpbiIn->biHeight)) + return ICERR_MEMORY; + return ICERR_OK; +} + +DWORD CodecInst::CompressGetSize(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) { + if (!CanCompress(lpbiIn, lpbiOut)) + return ICERR_BADFORMAT; + return lpbiIn->biWidth * lpbiIn->biHeight * lpbiIn->biBitCount/8 + 1024; +} + +DWORD CodecInst::Compress(ICCOMPRESS* icinfo, DWORD dwSize) { + int i, pitch; + zmbv_format_t format; + LPBITMAPINFOHEADER lpbiIn=icinfo->lpbiInput; + LPBITMAPINFOHEADER lpbiOut=icinfo->lpbiOutput; + if (!CanCompress(lpbiIn, lpbiOut)) + return ICERR_BADFORMAT; + if (!icinfo->lpInput || !icinfo->lpOutput) + return ICERR_ABORT; + switch (lpbiIn->biBitCount) { + case 8: + format = ZMBV_FORMAT_8BPP; + pitch = lpbiIn->biWidth; + break; + case 15: + format = ZMBV_FORMAT_15BPP; + pitch = lpbiIn->biWidth * 2; + break; + case 16: + format = ZMBV_FORMAT_16BPP; + pitch = lpbiIn->biWidth * 2; + break; + case 32: + format = ZMBV_FORMAT_32BPP; + pitch = lpbiIn->biWidth * 4; + break; + } + codec->PrepareCompressFrame( 0, format, 0, icinfo->lpOutput, 99999999); + char *readPt = (char *)icinfo->lpbiInput; + for(i = 0;ibiHeight;i++) { + codec->CompressLines(1, (void **)&readPt ); + readPt += pitch; + } + lpbiOut->biSizeImage = codec->FinishCompressFrame(); + return ICERR_OK; +} + + +DWORD CodecInst::CompressEnd() { + if (codec) + delete codec; + codec = 0; + return ICERR_OK; +} + +/******************************************************************** +********************************************************************/ + +static bool CanDecompress(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) { + if (memcmp(&lpbiIn->biCompression,CODEC_4CC,4)) + return false; + if (lpbiOut) { + if (lpbiOut->biCompression!=0) return false; + if (lpbiOut->biBitCount != 24) return false; + if (lpbiIn->biWidth!=lpbiOut->biWidth || lpbiIn->biHeight!=lpbiOut->biHeight) + return false; + } + return true; +} + +/******************************************************************** +********************************************************************/ + + +DWORD CodecInst::DecompressQuery(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) { + return CanDecompress(lpbiIn, lpbiOut) ? ICERR_OK : ICERR_BADFORMAT; +} + +DWORD CodecInst::DecompressGetFormat(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) { + if (memcmp(&lpbiIn->biCompression,CODEC_4CC,4)) + return ICERR_BADFORMAT; + if (!lpbiOut) return sizeof(BITMAPINFOHEADER); + *lpbiOut = *lpbiIn; + lpbiOut->biPlanes = 1; + lpbiOut->biSize=sizeof(BITMAPINFOHEADER); + lpbiOut->biBitCount=24; + lpbiOut->biCompression=0; + return ICERR_OK; +} + +DWORD CodecInst::DecompressBegin(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) { + DecompressEnd(); // free resources if necessary + if (!CanDecompress(lpbiIn, lpbiOut)) + return ICERR_BADFORMAT; + codec=new VideoCodec(); + if (!codec) + return ICERR_MEMORY; + if (!codec->SetupDecompress( lpbiIn->biWidth, lpbiIn->biHeight)) + return ICERR_MEMORY; + return ICERR_OK; +} + +DWORD CodecInst::Decompress(ICDECOMPRESS* icinfo, DWORD dwSize) { + if (!codec || !icinfo) + return ICERR_ABORT; + if (codec->DecompressFrame( icinfo->lpInput, icinfo->lpbiInput->biSizeImage)) { + codec->Output_UpsideDown_24(icinfo->lpOutput); + icinfo->lpbiOutput->biSizeImage=icinfo->lpbiOutput->biWidth*icinfo->lpbiOutput->biHeight*icinfo->lpbiOutput->biBitCount/8; + } else return ICERR_DONTDRAW; + return ICERR_OK; +} + + +// palette-mapped output only +DWORD CodecInst::DecompressGetPalette(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) { + return ICERR_BADFORMAT; +} + +DWORD CodecInst::DecompressEnd() { + if (codec) + delete codec; + codec = 0; + return ICERR_OK; +} From 5efb59c0aa5936445a187bd9b8969194008c7307 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 11:56:55 +0000 Subject: [PATCH 2375/4131] Fix double height scaler Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2459 --- src/gui/render_scalers.cpp | 2 +- src/gui/render_templates.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index c67c7a39..04fdb071 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -173,7 +173,7 @@ ScalerLineBlock_t ScaleNormalDw = { ScalerLineBlock_t ScaleNormalDh = { GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8, ScaleFlagSimple, - 2,1, + 1,2, NormalDh_8_L,NormalDh_16_L,NormalDh_16_L,NormalDh_32_L, NormalDh_8_R,NormalDh_16_R,NormalDh_16_R,NormalDh_32_R }; diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index 18c11083..9c7b8de8 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -237,7 +237,7 @@ static void conc3d(CacheSimple,SBPP,DBPP) (const void * s) { #define SCALERHEIGHT 2 #define SCALERFUNC \ line0[0] = C4; \ - line1[1] = C4; + line1[0] = C4; #include "render_loops.h" #undef SCALERNAME #undef SCALERWIDTH From e82452e6a99ea95a33bc91b91472317795c4948f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 30 Jan 2006 11:58:14 +0000 Subject: [PATCH 2376/4131] added render_loops.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2460 --- src/gui/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 8d76e38d..3d96a05b 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -2,6 +2,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libgui.a libgui_a_SOURCES = sdlmain.cpp sdl_mapper.cpp \ - render.cpp render_scalers.cpp render_scalers.h render_templates.h \ + render.cpp render_scalers.cpp render_scalers.h \ + render_templates.h render_loops.h \ midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h midi_alsa.h From b33bfb80d9fbfdfbd9e87627e7c6a2451bca9d44 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 30 Jan 2006 14:01:52 +0000 Subject: [PATCH 2377/4131] Add a larger cache. Allocated when the dynamic core is selected. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2461 --- src/cpu/core_dyn_x86.cpp | 13 +++-- src/cpu/core_dyn_x86/cache.h | 95 +++++++++++++++++++++++------------- src/cpu/cpu.cpp | 7 ++- 3 files changed, 75 insertions(+), 40 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 1aa13e98..1383116b 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #if (C_HAVE_MPROTECT) #include @@ -46,14 +47,13 @@ #include "inout.h" #ifdef CHECKED_MEMORY_ACCESS -#define CACHE_PAGES (128*2) #define CACHE_MAXSIZE (4096*2) #else -#define CACHE_PAGES (128) #define CACHE_MAXSIZE (4096) #endif +#define CACHE_PAGES (128*8) #define CACHE_TOTAL (CACHE_PAGES*4096) -#define CACHE_BLOCKS (32*1024) +#define CACHE_BLOCKS (64*1024) #define CACHE_ALIGN (16) #define DYN_HASH_SHIFT (4) #define DYN_PAGE_HASH (4096>>DYN_HASH_SHIFT) @@ -346,11 +346,14 @@ void CPU_Core_Dyn_X86_Init(void) { DynRegs[G_SHIFT].flags=DYNFLG_HAS8|DYNFLG_HAS16; DynRegs[G_EXIT].data=0; DynRegs[G_EXIT].flags=DYNFLG_HAS16; - /* Initialize code cache and dynamic blocks */ - cache_init(); /* Init the generator */ gen_init(); return; } +void CPU_Core_Dyn_X86_Cache_Init(bool enable_cache) { + /* Initialize code cache and dynamic blocks */ + cache_init(enable_cache); +} + #endif diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 9d307779..07ff1b94 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -44,13 +44,10 @@ static struct { #if (C_HAVE_MPROTECT) static Bit8u cache_code_link_blocks[2][16] GCC_ATTRIBUTE(aligned(PAGESIZE)); -static Bit8u cache_code[CACHE_TOTAL+CACHE_MAXSIZE] GCC_ATTRIBUTE(aligned(PAGESIZE)); #else static Bit8u cache_code_link_blocks[2][16]; -static Bit8u cache_code[CACHE_TOTAL+CACHE_MAXSIZE]; #endif -static CacheBlock cache_blocks[CACHE_BLOCKS]; static CacheBlock link_blocks[2]; class CodePageHandler :public PageHandler { @@ -393,38 +390,68 @@ static INLINE void cache_addd(Bit32u val) { static void gen_return(BlockReturn retcode); -static void cache_init(void) { - Bits i; - memset(&cache_blocks,0,sizeof(cache_blocks)); +static Bit8u * cache_code=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) - mprotect(cache_code,sizeof(cache_code),PROT_WRITE|PROT_READ|PROT_EXEC); - mprotect(cache_code_link_blocks,sizeof(cache_code_link_blocks),PROT_WRITE|PROT_READ|PROT_EXEC); +#define PAGESIZE_TEMP PAGESIZE +#else +#define PAGESIZE_TEMP 1 #endif - cache.block.free=&cache_blocks[0]; - for (i=0;icache.start=&cache_code[0]; - block->cache.size=CACHE_TOTAL; - block->cache.next=0; //Last block in the list - cache.pos=&cache_code_link_blocks[0][0]; - link_blocks[0].cache.start=cache.pos; - gen_return(BR_Link1); - cache.pos=&cache_code_link_blocks[1][0]; - 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;inext=cache.free_pages; - cache.free_pages=newpage; + + +static void cache_init(bool enable) { + static bool cache_initialized = false; + 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;icache.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][0]; + link_blocks[0].cache.start=cache.pos; + gen_return(BR_Link1); + cache.pos=&cache_code_link_blocks[1][0]; + 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;inext=cache.free_pages; + cache.free_pages=newpage; + } } } diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index c67408cc..05093caf 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.74 2005-08-15 14:17:20 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.75 2006-01-30 14:01:52 qbix79 Exp $ */ #include #include "dosbox.h" @@ -50,6 +50,7 @@ void CPU_Core_Full_Init(void); void CPU_Core_Normal_Init(void); void CPU_Core_Simple_Init(void); void CPU_Core_Dyn_X86_Init(void); +void CPU_Core_Dyn_X86_Cache_Init(bool enable_cache); /* In debug mode exceptions are tested and dosbox exits when @@ -1977,6 +1978,10 @@ public: else { LOG_MSG("CPU:Unknown core type %s, switcing back to normal.",core); } + +#if (C_DYNAMIC_X86) + CPU_Core_Dyn_X86_Cache_Init(!strcasecmp(core,"dynamic")); +#endif if(CPU_CycleMax <= 0) CPU_CycleMax = 2500; if(CPU_CycleUp <= 0) CPU_CycleUp = 500; From 5866acbba250ff4bf967f1842fee9aa609e06dce Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 15:02:34 +0000 Subject: [PATCH 2378/4131] Fix not giving bad updaterects during an unfinished screenupdate Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2462 --- include/render.h | 2 +- src/gui/render.cpp | 14 ++++++++------ src/gui/sdlmain.cpp | 7 ++++++- src/hardware/vga_draw.cpp | 2 +- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/include/render.h b/include/render.h index a8ca48d5..612dd589 100644 --- a/include/render.h +++ b/include/render.h @@ -77,7 +77,7 @@ extern Render_t render; void RENDER_DrawLine( const void *src ); 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); +void RENDER_EndUpdate( bool fullUpdate ); void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue); diff --git a/src/gui/render.cpp b/src/gui/render.cpp index b6bd4ea8..0b493ebb 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.36 2006-01-30 09:58:07 harekiet Exp $ */ +/* $Id: render.cpp,v 1.37 2006-01-30 15:02:33 harekiet Exp $ */ #include #include @@ -155,7 +155,7 @@ bool RENDER_StartUpdate(void) { return true; } -void RENDER_EndUpdate(void) { +void RENDER_EndUpdate( bool fullUpdate ) { if (!render.updating) return; render.scale.cacheHandler = RENDER_EmptyCacheHandler; @@ -182,7 +182,7 @@ void RENDER_EndUpdate(void) { CAPTURE_AddImage( render.src.width, render.src.height, render.src.bpp, pitch, flags, render.src.fps, scalerSourceCache.b8[0], (Bit8u*)&render.pal.rgb ); } - GFX_EndUpdate( Scaler_ChangedLines ); + GFX_EndUpdate( fullUpdate ? Scaler_ChangedLines : 0); render.updating=false; } @@ -207,8 +207,10 @@ static Bitu MakeAspectTable(Bitu height,double scaley,Bitu miny) { } void RENDER_ReInit( bool stopIt ) { - if (render.updating) - RENDER_EndUpdate(); + if (render.updating) { + /* Still updating the current screen, shut it down correctly */ + RENDER_EndUpdate( false ); + } if (stopIt) return; @@ -376,7 +378,7 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool render.active=false; return; } - RENDER_EndUpdate(); + RENDER_EndUpdate( false ); render.src.width=width; render.src.height=height; render.src.bpp=bpp; diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index e37efa6d..20509559 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.96 2006-01-30 09:58:07 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.97 2006-01-30 15:02:33 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -686,6 +686,11 @@ void GFX_EndUpdate( const Bit16u *changedLines ) { rect->y = sdl.clip.y + y; rect->w = (Bit16u)sdl.draw.width; rect->h = changedLines[index]; +#if 0 + if (rect->h + rect->y > sdl.surface->h) { + LOG_MSG("WTF"); + } +#endif y += changedLines[index]; } index++; diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 96b6c742..0feadf10 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -294,7 +294,7 @@ static void VGA_DrawPart(Bitu lines) { PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts, (vga.draw.parts_left!=1) ? vga.draw.parts_lines : (vga.draw.lines_total - vga.draw.lines_done)); } else { - RENDER_EndUpdate(); + RENDER_EndUpdate( true ); } } From 3fc521c909add9790ae41ddce4bf7fe0b856e1ca Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 30 Jan 2006 16:10:13 +0000 Subject: [PATCH 2379/4131] Fix compilation without png Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2463 --- src/hardware/hardware.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 9fb07c5d..1627e3d2 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -15,6 +15,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* $Id: hardware.cpp,v 1.10 2006-01-30 16:10:13 qbix79 Exp $ */ + #include #include #include @@ -58,6 +61,7 @@ static struct { struct { Bitu rowlen; } image; +#if (C_SSHOT) struct { FILE *handle; Bitu frames; @@ -74,6 +78,7 @@ static struct { Bit8u *index; Bitu indexsize, indexused; } video; +#endif } capture; FILE * OpenCaptureFile(const char * type,const char * ext) { @@ -143,6 +148,7 @@ static void CAPTURE_AddAviChunk(const char * tag, Bit32u size, void * data, Bit3 #endif static void CAPTURE_VideoEvent(void) { +#if (C_SSHOT) if (CaptureState & CAPTURE_VIDEO) { /* Close the video */ CaptureState &= ~CAPTURE_VIDEO; @@ -273,6 +279,7 @@ static void CAPTURE_VideoEvent(void) { } else { CaptureState |= CAPTURE_VIDEO; } +#endif } void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags, float fps, Bit8u * data, Bit8u * pal) { @@ -518,6 +525,7 @@ static Bit8u wavheader[]={ }; void CAPTURE_AddWave(Bit32u freq, Bit32u len, Bit16s * data) { +#if (C_SSHOT) if (CaptureState & CAPTURE_VIDEO) { Bitu left = WAVE_BUF - capture.video.audioused; if (left > len) @@ -526,6 +534,7 @@ void CAPTURE_AddWave(Bit32u freq, Bit32u len, Bit16s * data) { capture.video.audioused += left; capture.video.audiorate = freq; } +#endif if (CaptureState & CAPTURE_WAVE) { if (!capture.wave.handle) { capture.wave.handle=OpenCaptureFile("Wave Output",".wav"); From 6b7b66c0ec422aebcc304f5df5f9a49dadf9febc Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 30 Jan 2006 19:05:05 +0000 Subject: [PATCH 2380/4131] Improved clearing the cache a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2464 --- include/render.h | 2 +- src/gui/render.cpp | 105 +++++++++++++++++++++++---------------------- 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/include/render.h b/include/render.h index 612dd589..a0218a6d 100644 --- a/include/render.h +++ b/include/render.h @@ -59,7 +59,7 @@ typedef struct { ScalerLineHandler_t currentHandler; Bitu lineFlags; bool clearCache; - + ScalerCacheHandler_t clearCacheHandler; ScalerLineHandler_t lineHandler; ScalerCacheHandler_t cacheHandler; Bitu blocks, lastBlock; diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 0b493ebb..3e1bc29b 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.37 2006-01-30 15:02:33 harekiet Exp $ */ +/* $Id: render.cpp,v 1.38 2006-01-30 19:05:05 harekiet Exp $ */ #include #include @@ -100,6 +100,30 @@ static void RENDER_EmptyLineHandler(void) { } +static void RENDER_ClearCacheHandler(const void * src) { + Bitu x, width; + Bit32u *srcLine, *cacheLine; + srcLine = (Bit32u *)src; + switch (render.scale.inMode) { + case scalerMode8: + width = render.src.width / 4; + cacheLine = (Bit32u*)scalerSourceCache.b8[render.scale.inLine]; + break; + case scalerMode15: + case scalerMode16: + width = render.src.width / 2; + cacheLine = (Bit32u*)scalerSourceCache.b16[render.scale.inLine]; + break; + case scalerMode32: + width = render.src.width; + cacheLine = (Bit32u*)scalerSourceCache.b32[render.scale.inLine]; + break; + } + for (x=0;xsimple[render.scale.outMode]; + } else { + render.scale.cacheHandler = cacheBlock->complex[render.scale.outMode]; + } + /* Clearing the cache will first process the line to make sure it's never the same */ if (GCC_UNLIKELY( render.scale.clearCache) ) { - LOG_MSG("Clearing cache"); +// LOG_MSG("Clearing cache"); render.scale.clearCache = false; - render.scale.cacheHandler = RENDER_EmptyCacheHandler; - memset( scalerChangeCache, SCALE_FULL, sizeof( scalerChangeCache ) ); - } else */ - { - ScalerCacheBlock_t *cacheBlock; - switch (render.scale.inMode) { - case scalerMode8: - cacheBlock = !render.pal.changed ? &ScalerCache_8 : &ScalerCache_8Pal; - break; - case scalerMode15: - cacheBlock = &ScalerCache_15; - break; - case scalerMode16: - cacheBlock = &ScalerCache_16; - break; - case scalerMode32: - cacheBlock = &ScalerCache_32; - break; - default: - return false; - } - if (render.scale.lineFlags & ScaleFlagSimple) { - render.scale.cacheHandler = cacheBlock->simple[render.scale.outMode]; - } else { - render.scale.cacheHandler = cacheBlock->complex[render.scale.outMode]; - } + render.scale.clearCacheHandler = render.scale.cacheHandler; + render.scale.cacheHandler = RENDER_ClearCacheHandler; } render.scale.lineHandler = render.scale.currentHandler; render.updating=true; @@ -346,29 +369,7 @@ forcenormal: render.scale.lastBlock = render.src.width % SCALER_BLOCKSIZE; render.scale.inHeight = render.src.height; RENDER_ResetPal(); - /* Not exactltly the best way to clean the cache, but seems to do the trick */ - for (Bitu y=0;y0;x--) - cacheLine[x] = ~cacheLine[x]; - } - //Maybe do it again through a special passthrough cache check handler + /* Signal the next frame to first reinit the cache */ render.scale.clearCache = true; render.active=true; } From 0e9168b5560b47d92a80b8f5fda9a109947b5ce7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 30 Jan 2006 19:37:49 +0000 Subject: [PATCH 2381/4131] Fix some memory leaks. Fix double destruction of classes. Add some input checks on the environment reader Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2465 --- include/setup.h | 12 ++++++------ src/misc/setup.cpp | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/include/setup.h b/include/setup.h index 4313bf4b..e65ef854 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.20 2005-04-21 19:53:40 qbix79 Exp $ */ +/* $Id: setup.h,v 1.21 2006-01-30 19:37:48 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -139,7 +139,7 @@ private: std::list destroyfunctions; std::string sectionname; public: - Section(const char* _sectionname) { sectionname=_sectionname; } + Section(const char* _sectionname):sectionname(_sectionname) { } void AddInitFunction(SectionFunction func,bool canchange=false) {initfunctions.push_back(Function_wrapper(func,canchange));} void AddDestroyFunction(SectionFunction func,bool canchange=false) {destroyfunctions.push_front(Function_wrapper(func,canchange));} @@ -148,9 +148,9 @@ public: const char* GetName() {return sectionname.c_str();} virtual char* GetPropValue(const char* _property)=0; - virtual void HandleInputline(char * _line){} - virtual void PrintData(FILE* outfile) {} - virtual ~Section(){ExecuteDestroy(true); } + virtual void HandleInputline(char * _line)=0; + virtual void PrintData(FILE* outfile)=0; + virtual ~Section() { /*Children must call executedestroy ! */} }; @@ -175,7 +175,7 @@ public: void PrintData(FILE* outfile); virtual char* GetPropValue(const char* _property); //ExecuteDestroy should be here else the destroy functions use destroyed properties - virtual ~Section_prop(){ExecuteDestroy(true);} + virtual ~Section_prop(); }; class Section_line: public Section{ diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 911e040f..2c0fb772 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.31 2005-07-24 19:04:11 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.32 2006-01-30 19:37:49 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -229,6 +229,15 @@ Section_prop* Config::AddSection_prop(const char* _name,void (*_initfunction)(Se return blah; } +Section_prop::~Section_prop() { +//ExecuteDestroy should be here else the destroy functions use destroyed properties + ExecuteDestroy(true); + /* Delete properties themself (properties stores the pointer of a prop */ + for(it prop = properties.begin(); prop != properties.end(); prop++) + delete (*prop); +} + + Section_line* Config::AddSection_line(const char* _name,void (*_initfunction)(Section*)){ Section_line* blah = new Section_line(_name); blah->AddInitFunction(_initfunction); @@ -341,10 +350,14 @@ void Config::ParseEnv(char ** envp) { if(strncasecmp(copy,"DOSBOX_",7)) continue; char* sec_name = ©[7]; + if(!(*sec_name)) + continue; char* prop_name = strrchr(sec_name,'_'); + if(!prop_name || !(*prop_name)) + continue; *prop_name++=0; Section* sect = GetSection(sec_name); - if(!sect) + if(!sect) continue; sect->HandleInputline(prop_name); } From dec67f012924d7beea5e189626d101377a129841 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 30 Jan 2006 19:55:21 +0000 Subject: [PATCH 2382/4131] mention noautoexec Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2466 --- README | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README b/README index 6fe210ab..f5745e49 100644 --- a/README +++ b/README @@ -196,7 +196,7 @@ description: dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] [-lang languagefile] [-machine machinetype] [-noconsole] - [-startmapper] + [-startmapper] [-noautoexec] dosbox -version @@ -237,6 +237,9 @@ dosbox -version Enter the keymapper directly on startup. Useful for people with keyboard problems. + -noautoexec + Skips the [autoexec] section of the loaded configuration file. + -version output version information and exit. Useful for frontends. From 73530a5ed1ce6939082c597a125aa629309e423c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 31 Jan 2006 07:31:45 +0000 Subject: [PATCH 2383/4131] Added vga_s3 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2467 --- visualc_net/dosbox.vcproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 701ca121..cafb8984 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -476,6 +476,9 @@ + + Date: Tue, 31 Jan 2006 09:26:45 +0000 Subject: [PATCH 2384/4131] Add patch 1210768 which reintroduces the lockfree mouse from Moe Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2468 --- include/mouse.h | 4 ++-- src/gui/sdlmain.cpp | 21 +++++++++++++++------ src/ints/mouse.cpp | 26 ++++++++++++++++++++------ 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/include/mouse.h b/include/mouse.h index 891e3a55..21c44551 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.h,v 1.10 2005-09-21 11:37:35 c2woody Exp $ */ +/* $Id: mouse.h,v 1.11 2006-01-31 09:26:43 qbix79 Exp $ */ #ifndef DOSBOX_MOUSE_H #define DOSBOX_MOUSE_H @@ -27,7 +27,7 @@ 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_ButtonPressed(Bit8u button); void Mouse_ButtonReleased(Bit8u button); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 20509559..e05fa274 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.97 2006-01-30 15:02:33 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.98 2006-01-31 09:26:44 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -588,6 +588,7 @@ dosurface: }//CASE if (retFlags) GFX_Start(); + if (!sdl.mouse.autoenable) SDL_ShowCursor(sdl.mouse.autolock?SDL_DISABLE:SDL_ENABLE); return retFlags; } @@ -599,7 +600,7 @@ static void CaptureMouse(void) { SDL_ShowCursor(SDL_DISABLE); } else { SDL_WM_GrabInput(SDL_GRAB_OFF); - SDL_ShowCursor(SDL_ENABLE); + if (sdl.mouse.autoenable || !sdl.mouse.autolock) SDL_ShowCursor(SDL_ENABLE); } mouselocked=sdl.mouse.locked; } @@ -966,6 +967,7 @@ static void GUI_StartUp(Section * sec) { #endif } sdl.mouse.autoenable=section->Get_bool("autolock"); + if (!sdl.mouse.autoenable) SDL_ShowCursor(SDL_DISABLE); sdl.mouse.autolock=false; sdl.mouse.sensitivity=section->Get_int("sensitivity"); const char * output=section->Get_string("output"); @@ -1048,13 +1050,16 @@ static void GUI_StartUp(Section * sec) { void Mouse_AutoLock(bool enable) { sdl.mouse.autolock=enable; - if (enable && sdl.mouse.autoenable) sdl.mouse.requestlock=true; - else sdl.mouse.requestlock=false; + if (sdl.mouse.autoenable) sdl.mouse.requestlock=enable; + else { + SDL_ShowCursor(enable?SDL_DISABLE:SDL_ENABLE); + sdl.mouse.requestlock=false; + } } static void HandleMouseMotion(SDL_MouseMotionEvent * motion) { - if (sdl.mouse.locked) - Mouse_CursorMoved((float)motion->xrel*sdl.mouse.sensitivity/100,(float)motion->yrel*sdl.mouse.sensitivity/100); + if (sdl.mouse.locked || !sdl.mouse.autoenable) + Mouse_CursorMoved((float)motion->xrel*sdl.mouse.sensitivity/100,(float)motion->yrel*sdl.mouse.sensitivity/100,(float)(motion->x-sdl.clip.x)/(sdl.clip.w-1)*sdl.mouse.sensitivity/100,(float)(motion->y-sdl.clip.y)/(sdl.clip.h-1)*sdl.mouse.sensitivity/100.0,sdl.mouse.locked); } static void HandleMouseButton(SDL_MouseButtonEvent * button) { @@ -1065,6 +1070,10 @@ static void HandleMouseButton(SDL_MouseButtonEvent * button) { // Dont pass klick to mouse handler break; } + if (!sdl.mouse.autoenable && sdl.mouse.autolock && button->button == SDL_BUTTON_MIDDLE) { + CaptureMouse(); + break; + } switch (button->button) { case SDL_BUTTON_LEFT: Mouse_ButtonPressed(0); diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index fb5ca08d..6c47bf9e 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.58 2006-01-30 10:06:36 harekiet Exp $ */ +/* $Id: mouse.cpp,v 1.59 2006-01-31 09:26:45 qbix79 Exp $ */ #include #include @@ -410,9 +410,9 @@ void DrawCursor() { RestoreVgaRegisters(); } -void Mouse_CursorMoved(float x,float y) { - float dx = x * mouse.pixelPerMickey_x; - float dy = y * mouse.pixelPerMickey_y; +void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate) { + float dx = xrel * mouse.pixelPerMickey_x; + float dy = yrel * mouse.pixelPerMickey_y; if((fabs(x) > 1.0) || (mouse.senv_x < 1.0)) dx *= mouse.senv_x; if((fabs(y) > 1.0) || (mouse.senv_y < 1.0)) dy *= mouse.senv_y; @@ -420,8 +420,22 @@ void Mouse_CursorMoved(float x,float y) { mouse.mickey_x += dx; mouse.mickey_y += dy; - mouse.x += dx; - mouse.y += dy; + if (emulate) { + mouse.x += dx; + mouse.y += dy; + } else { + if (CurMode->type == M_TEXT) { + mouse.x = x*CurMode->swidth; + mouse.y = y*CurMode->sheight * 8 / CurMode->cheight; + } else if (mouse.max_x < 2048 || mouse.max_y < 2048 || mouse.max_x != mouse.max_y) { + mouse.x = x*mouse.max_x; + mouse.y = y*mouse.max_y; + } else { // Games faking relative movement through absolute coordinates. Quite surprising that this actually works.. + mouse.x += xrel; + mouse.y += yrel; + } + } + /* ignore constraints if using PS2 mouse callback in the bios */ if (!useps2callback) { From 69550d3db5794843aab8691b19e0413ddf0370bd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 1 Feb 2006 07:22:45 +0000 Subject: [PATCH 2385/4131] Fix some issues with 1024x768 resolutions Add the adveinterp3x scaler, although not really doing much interpolating Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2469 --- src/gui/render.cpp | 7 +++++-- src/gui/render_scalers.cpp | 11 +++++++++-- src/gui/render_scalers.h | 5 ++++- src/gui/render_templates.h | 31 +++++++++++++++++++------------ 4 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 3e1bc29b..5f89554d 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.38 2006-01-30 19:05:05 harekiet Exp $ */ +/* $Id: render.cpp,v 1.39 2006-02-01 07:22:45 harekiet Exp $ */ #include #include @@ -274,6 +274,8 @@ void RENDER_ReInit( bool stopIt ) { case scalerOpAdvInterp: if (render.scale.size == 2) lineBlock = &ScaleAdvInterp2x; + else if (render.scale.size == 3) + lineBlock = &ScaleAdvInterp3x; break; case scalerOpAdvMame: if (render.scale.size == 2) @@ -375,7 +377,7 @@ forcenormal: } void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool dblw,bool dblh) { - if (!width || !height) { + if (!width || !height || width > SCALER_MAXWIDTH || height > SCALER_MAXHEIGHT) { render.active=false; return; } @@ -429,6 +431,7 @@ void RENDER_Init(Section * sec) { else if (!strcasecmp(scaler,"advmame2x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 2; } else if (!strcasecmp(scaler,"advmame3x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 3; } else if (!strcasecmp(scaler,"advinterp2x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 2; } + else if (!strcasecmp(scaler,"advinterp3x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 3; } else if (!strcasecmp(scaler,"tv2x")) { render.scale.op = scalerOpTV;render.scale.size = 2; } else if (!strcasecmp(scaler,"tv3x")) { render.scale.op = scalerOpTV;render.scale.size = 3; } else if (!strcasecmp(scaler,"rgb2x")){ render.scale.op = scalerOpRGB;render.scale.size = 2; } diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index 04fdb071..874f856e 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -36,8 +36,7 @@ union { } scalerWriteCache; scalerFrameCache_t scalerFrameCache; scalerSourceCache_t scalerSourceCache; - -Bit8u scalerChangeCache [SCALER_MAXHEIGHT][SCALER_MAXWIDTH / SCALER_BLOCKSIZE]; +scalerChangeCache_t scalerChangeCache; #define _conc2(A,B) A ## B #define _conc3(A,B,C) A ## B ## C @@ -220,6 +219,14 @@ ScalerLineBlock_t ScaleAdvInterp2x = { 0,AdvInterp2x_15_R,AdvInterp2x_16_R,AdvInterp2x_32_R }; +ScalerLineBlock_t ScaleAdvInterp3x = { + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, + 0, + 3,3, + 0,AdvInterp3x_15_L,AdvInterp3x_16_L,AdvInterp3x_32_L, + 0,AdvInterp3x_15_R,AdvInterp3x_16_R,AdvInterp3x_32_R +}; + ScalerLineBlock_t ScaleTV2x = { GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, ScaleFlagSimple, diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index 8ea118fa..33d72b00 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -46,7 +46,8 @@ extern Bit8u Scaler_Aspect[]; extern Bit8u diff_table[]; extern Bitu Scaler_ChangedLineIndex; extern Bit16u Scaler_ChangedLines[]; -extern Bit8u scalerChangeCache [SCALER_MAXHEIGHT][SCALER_MAXWIDTH / SCALER_BLOCKSIZE]; +/* Not entirely happy about those +2's since they make a non power of 2, with muls instead of shift */ +typedef Bit8u scalerChangeCache_t [SCALER_MAXHEIGHT+2][2+(SCALER_MAXWIDTH / SCALER_BLOCKSIZE)] ; typedef union { Bit32u b32 [(SCALER_MAXHEIGHT+2)] [(SCALER_MAXWIDTH+2)]; Bit16u b16 [(SCALER_MAXHEIGHT+2)] [(SCALER_MAXWIDTH+2)]; @@ -60,6 +61,7 @@ typedef union { extern scalerFrameCache_t scalerFrameCache; extern scalerSourceCache_t scalerSourceCache; +extern scalerChangeCache_t scalerChangeCache; #define ScaleFlagSimple 0x001 @@ -98,6 +100,7 @@ extern ScalerLineBlock_t ScaleNormal3x; extern ScalerLineBlock_t ScaleAdvMame2x; extern ScalerLineBlock_t ScaleAdvMame3x; extern ScalerLineBlock_t ScaleAdvInterp2x; +extern ScalerLineBlock_t ScaleAdvInterp3x; extern ScalerLineBlock_t ScaleTV2x; extern ScalerLineBlock_t ScaleTV3x; diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index 9c7b8de8..ad00d285 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -417,10 +417,10 @@ static void conc3d(CacheSimple,SBPP,DBPP) (const void * s) { #define SCALERHEIGHT 2 #define SCALERFUNC \ if (C1 != C7 && C3 != C5) { \ - line0[0] = C3 == C1 ? interp_w2(C3,C4,5,3) : C4; \ - line0[1] = C1 == C5 ? interp_w2(C5,C4,5,3) : C4; \ - line1[0] = C3 == C7 ? interp_w2(C3,C4,5,3) : C4; \ - line1[1] = C7 == C5 ? interp_w2(C5,C4,5,3) : C4; \ + line0[0] = C3 == C1 ? interp_w2(C3,C4,5U,3U) : C4; \ + line0[1] = C1 == C5 ? interp_w2(C5,C4,5U,3U) : C4; \ + line1[0] = C3 == C7 ? interp_w2(C3,C4,5U,3U) : C4; \ + line1[1] = C7 == C5 ? interp_w2(C5,C4,5U,3U) : C4; \ } else { \ line0[0] = line0[1] = C4; \ line1[0] = line1[1] = C4; \ @@ -431,18 +431,25 @@ static void conc3d(CacheSimple,SBPP,DBPP) (const void * s) { #undef SCALERHEIGHT #undef SCALERFUNC +//TODO, come up with something better for this one #define SCALERNAME AdvInterp3x #define SCALERWIDTH 3 #define SCALERHEIGHT 3 #define SCALERFUNC \ - if (C1 != C7 && C3 != C5) { \ - line0[0] = C3 == C1 ? interp_w2(C3,C4,5,3) : C4; \ - line0[1] = C1 == C5 ? interp_w2(C5,C4,5,3) : C4; \ - line1[0] = C3 == C7 ? interp_w2(C3,C4,5,3) : C4; \ - line1[1] = C7 == C5 ? interp_w2(C5,C4,5,3) : C4; \ - } else { \ - line0[0] = line0[1] = C4; \ - line1[0] = line1[1] = C4; \ + if ((C1 != C7) && (C3 != C5)) { \ + line0[0] = C3 == C1 ? interp_w2(C3,C4,5U,3U) : C4; \ + line0[1] = (C3 == C1 && C4 != C2) || (C5 == C1 && C4 != C0) ? C1 : C4; \ + line0[2] = C5 == C1 ? interp_w2(C5,C4,5U,3U) : C4; \ + line1[0] = (C3 == C1 && C4 != C6) || (C3 == C7 && C4 != C0) ? C3 : C4; \ + line1[1] = C4; \ + line1[2] = (C5 == C1 && C4 != C8) || (C5 == C7 && C4 != C2) ? C5 : C4; \ + line2[0] = C3 == C7 ? interp_w2(C3,C4,5U,3U) : C4; \ + line2[1] = (C3 == C7 && C4 != C8) || (C5 == C7 && C4 != C6) ? C7 : C4; \ + line2[2] = C5 == C7 ? interp_w2(C5,C4,5U,3U) : C4; \ + } else { \ + line0[0] = line0[1] = line0[2] = C4; \ + line1[0] = line1[1] = line1[2] = C4; \ + line2[0] = line2[1] = line2[2] = C4; \ } #include "render_loops.h" #undef SCALERNAME From 5f4018f19d0a78b99d4b2849077c6ed928fa7ce7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 1 Feb 2006 07:59:54 +0000 Subject: [PATCH 2386/4131] workaround bug in pdcurses Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2470 --- src/debug/debug_gui.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 1ae6da60..1b738dcb 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug_gui.cpp,v 1.26 2006-01-30 10:45:49 qbix79 Exp $ */ +/* $Id: debug_gui.cpp,v 1.27 2006-02-01 07:59:54 qbix79 Exp $ */ #include "dosbox.h" @@ -90,8 +90,9 @@ void DEBUG_RefreshPage(char scroll) { wclear(dbg.win_out); while (rem_lines > 0 && i!=logBuff.begin()) { - rem_lines -= (int) ((*--i).size() / dbg.win_out->_maxx) + 1; - mvwprintw(dbg.win_out,rem_lines-1, 0, (*i).c_str()); + rem_lines -= (int) ((*--i).size() / dbg.win_out->_maxx) + 1; + /* Const cast is needed for pdcurses which has no const char in mvwprintw (bug maybe) */ + mvwprintw(dbg.win_out,rem_lines-1, 0, const_cast((*i).c_str())); } wrefresh(dbg.win_out); } From ab78ad03e6444929872faf626191f987bfcb87cb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 2 Feb 2006 17:57:08 +0000 Subject: [PATCH 2387/4131] Fix some 32bpp colormask issues Rewrite protected mode vbe2 interface Fix set scanlength call somewhat Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2471 --- src/ints/int10.cpp | 18 +++--- src/ints/int10.h | 5 +- src/ints/int10_modes.cpp | 2 +- src/ints/int10_vesa.cpp | 126 ++++++++++++++++++++++++++------------- 4 files changed, 97 insertions(+), 54 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 22ede176..8c66058d 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -384,7 +384,7 @@ graphics_chars: break; case 0x06: reg_al=0x4f; - reg_ah=VESA_ScanLineLength(reg_bl,reg_bx,reg_cx,reg_dx); + reg_ah=VESA_ScanLineLength(reg_bl,reg_cx,reg_bx,reg_cx,reg_dx); break; case 0x07: switch (reg_bl) { @@ -428,22 +428,22 @@ graphics_chars: reg_cx=int10.rom.pmode_interface_size; reg_ax=0x004f; break; - case 0x01: /* Get code for "set bank" */ - reg_edi=RealOff(int10.rom.pmode_interface)+0x08; + case 0x01: /* Get code for "set window" */ + reg_edi=RealOff(int10.rom.pmode_interface)+int10.rom.pmode_interface_window; SegSet16(es,RealSeg(int10.rom.pmode_interface)); - reg_cx=0x0b; + reg_cx=0x10; //0x10 should be enough for the callbacks reg_ax=0x004f; break; case 0x02: /* Get code for "set display start" */ - reg_edi=RealOff(int10.rom.pmode_interface)+0x19; + reg_edi=RealOff(int10.rom.pmode_interface)+int10.rom.pmode_interface_start; SegSet16(es,RealSeg(int10.rom.pmode_interface)); - reg_cx=0x3e; + reg_cx=0x10; //0x10 should be enough for the callbacks reg_ax=0x004f; break; - case 0x03: /* Get code for "set pallete" */ - reg_edi=RealOff(int10.rom.pmode_interface)+0x57; + case 0x03: /* Get code for "set palette" */ + reg_edi=RealOff(int10.rom.pmode_interface)+int10.rom.pmode_interface_palette; SegSet16(es,RealSeg(int10.rom.pmode_interface)); - reg_cx=0x37; + reg_cx=0x10; //0x10 should be enough for the callbacks reg_ax=0x004f; break; default: diff --git a/src/ints/int10.h b/src/ints/int10.h index 7f5baf4a..aa195c1b 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -126,6 +126,9 @@ typedef struct { RealPt vesa_modes; RealPt pmode_interface; Bit16u pmode_interface_size; + Bit16u pmode_interface_start; + Bit16u pmode_interface_window; + Bit16u pmode_interface_palette; Bitu used; } rom; } Int10Data; @@ -190,7 +193,7 @@ Bit8u VESA_SetSVGAMode(Bit16u mode); Bit8u VESA_GetSVGAMode(Bit16u & mode); Bit8u VESA_SetCPUWindow(Bit8u window,Bit8u address); Bit8u VESA_GetCPUWindow(Bit8u window,Bit16u & address); -Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u & bytes,Bit16u & pixels,Bit16u & lines); +Bit8u VESA_ScanLineLength(Bit8u subcall, Bit16u val, Bit16u & bytes,Bit16u & pixels,Bit16u & lines); Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y); Bit8u VESA_GetDisplayStart(Bit16u & x,Bit16u & y); Bit8u VESA_SetPalette(PhysPt data,Bitu index,Bitu count); diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 0120c6d3..23a6a17f 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -679,7 +679,7 @@ bool INT10_SetVideoMode(Bitu mode) { IO_Write(crtc_base + 1,offset & 0xff); /* Extended System Control 2 Register */ /* This register actually has more bits but only use the extended offset ones */ - IO_Write(crtc_base,0x61); + IO_Write(crtc_base,0x51); IO_Write(crtc_base + 1,(offset & 0x300) >> 4); /* Extended Vertical Overflow */ IO_Write(crtc_base,0x5e);IO_Write(crtc_base+1,ver_overflow); diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index b9453b60..259f24de 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.19 2006-01-30 10:07:19 harekiet Exp $ */ +/* $Id: int10_vesa.cpp,v 1.20 2006-02-02 17:57:08 harekiet Exp $ */ #include #include @@ -31,6 +31,9 @@ static struct { Bitu setwindow; + Bitu pmStart; + Bitu pmWindow; + Bitu pmPalette; } callback; static char string_oem[]="S3 Incorporated. Trio64"; @@ -179,15 +182,17 @@ foundit: pageSize = mblock->sheight * mblock->swidth*4; pageSize = (pageSize | 15) & ~ 15; var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); - var_write(&minfo.BytesPerScanLine,mblock->swidth*2); + var_write(&minfo.BytesPerScanLine,mblock->swidth*4); var_write(&minfo.BitsPerPixel,32); var_write(&minfo.MemoryModel,6); //HiColour - var_write(&minfo.RedMaskSize,5); - var_write(&minfo.RedMaskPos,11); - var_write(&minfo.GreenMaskSize,6); - var_write(&minfo.GreenMaskPos,5); - var_write(&minfo.BlueMaskSize,5); - var_write(&minfo.BlueMaskPos,0); + var_write(&minfo.RedMaskSize,8); + var_write(&minfo.RedMaskPos,0x10); + var_write(&minfo.GreenMaskSize,0x8); + var_write(&minfo.GreenMaskPos,0x8); + var_write(&minfo.BlueMaskSize,0x8); + var_write(&minfo.BlueMaskPos,0x0); + var_write(&minfo.ReservedMaskSize,0x8); + var_write(&minfo.ReservedMaskPos,0x18); break; default: return 0x1; @@ -279,28 +284,35 @@ Bit8u VESA_GetPalette(PhysPt data,Bitu index,Bitu count) { } -Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u & bytes,Bit16u & pixels,Bit16u & lines) { +Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u val, Bit16u & bytes,Bit16u & pixels,Bit16u & lines) { Bit8u bpp; switch (CurMode->type) { + case M_LIN4: + break; case M_LIN8: - bpp=1;break; + bpp=1; + break; + case M_LIN15: + case M_LIN16: + bpp=2; + break; + case M_LIN32: + bpp=4; + break; default: return 0x1; } - Bitu scan_len; - lines=0xfff; //Does anyone care? switch (subcall) { case 0x00: /* Set in pixels */ - bytes=(pixels*bpp); + vga.config.scan_len = (val * bpp); + break; case 0x02: /* Set in bytes */ - scan_len=bytes/8; - if (bytes % 8) scan_len++; - vga.config.scan_len=scan_len; - VGA_StartResize(); + vga.config.scan_len = val; break; case 0x03: /* Get maximum */ bytes=0x400*4; pixels=bytes/bpp; + lines = 2*1024*1024 / bytes; return 0x00; case 0x01: /* Get lengths */ break; @@ -308,25 +320,16 @@ Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u & bytes,Bit16u & pixels,Bit16u & return 0x1; //Illegal call } /* Write the scan line to video card the simple way */ + if (vga.config.scan_len & 7) + vga.config.scan_len += 8; + vga.config.scan_len /= 8; pixels=(vga.config.scan_len*8)/bpp; bytes=vga.config.scan_len*8; + lines = 2*1024*1024 / bytes; + VGA_StartResize(); return 0x0; } - -/* Based of the s3 univbe driver */ -static Bit8u PmodeInterface[]={ - 0x08,0x00,0x19,0x00,0x57,0x00,0x00,0x00,0x50,0x52,0x8b,0xc2,0x8a,0xe0,0xb0,0x6a, - 0x66,0xba,0xd4,0x03,0x66,0xef,0x5a,0x58,0xc3,0x52,0x66,0xba,0xda,0x03,0xec,0xa8, - 0x01,0x75,0xfb,0x5a,0x53,0x8a,0xf9,0xb3,0x0d,0xb1,0x0c,0x66,0x8b,0xf2,0x66,0xba, - 0xd4,0x03,0x66,0x8b,0xc3,0x66,0xef,0x66,0x8b,0xc1,0x66,0xef,0x66,0x8b,0xde,0x8a, - 0xe3,0xb0,0x69,0x66,0xef,0x5b,0x52,0xf6,0xc3,0x80,0x74,0x09,0x66,0xba,0xda,0x03, - 0xec,0xa8,0x08,0x74,0xfb,0x5a,0xc3,0xf6,0xc3,0x80,0x74,0x10,0x52,0x66,0xba,0xda, - 0x03,0xec,0xa8,0x08,0x75,0xfb,0xec,0xa8,0x08,0x74,0xfb,0x5a,0x1e,0x06,0x1f,0x0f, - 0xb7,0xc9,0x8b,0xc2,0x66,0xba,0xc8,0x03,0xee,0x42,0xfc,0x8a,0x47,0x02,0xee,0x8a, - 0x47,0x01,0xee,0x8a,0x07,0xee,0x83,0xc7,0x04,0x49,0x75,0xef,0x1f,0xc3 -}; - Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y) { //TODO Maybe do things differently with lowres double line modes? Bitu start; @@ -347,11 +350,11 @@ Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y) { break; case M_LIN16: case M_LIN15: - start=vga.config.scan_len*4*y+x; + start=vga.config.scan_len*8*y+x; vga.config.display_start=start/4; break; case M_LIN32: - start=vga.config.scan_len*4*y+x; + start=vga.config.scan_len*8*y+x; vga.config.display_start=start/4; break; default: @@ -375,13 +378,30 @@ Bit8u VESA_GetDisplayStart(Bit16u & x,Bit16u & y) { return 0x00; } -static Bitu SetWindowPositionHandler(void) { +static Bitu VESA_SetWindow(void) { if (reg_bh) reg_ah=VESA_GetCPUWindow(reg_bl,reg_dx); else reg_ah=VESA_SetCPUWindow(reg_bl,(Bit8u)reg_dx); reg_al=0x4f; return 0; } +static Bitu VESA_PMSetWindow(void) { + VESA_SetCPUWindow(reg_bl,(Bit8u)reg_dx); + return 0; +} +static Bitu VESA_PMSetPalette(void) { + VESA_SetPalette(SegPhys(es) + reg_edi, reg_dx, reg_cx ); + return 0; +} +static Bitu VESA_PMSetStart(void) { + Bit32u start = (reg_dx << 16) | reg_cx; + vga.config.display_start = start; + return 0; +} + + + + void INT10_SetupVESA(void) { /* Put the mode list somewhere in memory */ Bitu i; @@ -402,17 +422,37 @@ void INT10_SetupVESA(void) { for (i=0;i Date: Fri, 3 Feb 2006 17:07:41 +0000 Subject: [PATCH 2388/4131] New callback_setupat call Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2472 --- include/callback.h | 7 +++--- src/cpu/callback.cpp | 52 +++++++++++++++++++++++--------------------- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/include/callback.h b/include/callback.h index a6603387..266c4faa 100644 --- a/include/callback.h +++ b/include/callback.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.h,v 1.14 2005-08-08 13:33:43 c2woody Exp $ */ +/* $Id: callback.h,v 1.15 2006-02-03 17:07:41 harekiet Exp $ */ #ifndef DOSBOX_CALLBACK_H #define DOSBOX_CALLBACK_H @@ -28,7 +28,7 @@ typedef Bitu (*CallBack_Handler)(void); extern CallBack_Handler CallBack_Handlers[]; -enum { CB_RETF,CB_IRET,CB_IRET_STI }; +enum { CB_RETN, CB_RETF,CB_IRET,CB_IRET_STI }; #define CB_MAX 144 #define CB_SEG 0xC800 @@ -52,7 +52,8 @@ void CALLBACK_RunRealInt(Bit8u intnum); void CALLBACK_RunRealFar(Bit16u seg,Bit16u off); bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* description=0); -bool CALLBACK_SetupAt(Bitu callback,CallBack_Handler handler,Bitu type,Bitu linearAddress, const char* description=0); +/* Returns with the size of the extra callback */ +Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress); const char* CALLBACK_GetDescription(Bitu callback); bool CALLBACK_Free(Bitu callback); diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 8b0a0aa2..dbcb057f 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.28 2005-09-08 13:09:47 qbix79 Exp $ */ +/* $Id: callback.cpp,v 1.29 2006-02-03 17:07:41 harekiet Exp $ */ #include #include @@ -154,10 +154,8 @@ bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* phys_writew(CB_BASE+(callback<<4)+3,callback); //The immediate word phys_writeb(CB_BASE+(callback<<4)+5,(Bit8u)0xCF); //An IRET Instruction break; - default: E_Exit("CALLBACK:Setup:Illegal type %d",type); - } CallBack_Handlers[callback]=handler; CALLBACK_SetDescription(callback,descr); @@ -170,35 +168,39 @@ void CALLBACK_RemoveSetup(Bitu callback) { } } - -bool CALLBACK_SetupAt(Bitu callback,CallBack_Handler handler,Bitu type,Bitu linearAddress,const char* descr) { - if (callback>=CB_MAX) return false; +Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress) { + if (callback>=CB_MAX) + return 0; switch (type) { + case CB_RETN: + phys_writeb(physAddress+0,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+1,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+2, callback); //The immediate word + phys_writeb(physAddress+4,(Bit8u)0xC3); //A RETN Instruction + return 5; case CB_RETF: - mem_writeb(linearAddress+0,(Bit8u)0xFE); //GRP 4 - mem_writeb(linearAddress+1,(Bit8u)0x38); //Extra Callback instruction - mem_writew(linearAddress+2, callback); //The immediate word - mem_writeb(linearAddress+4,(Bit8u)0xCB); //A RETF Instruction - break; + phys_writeb(physAddress+0,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+1,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+2, callback); //The immediate word + phys_writeb(physAddress+4,(Bit8u)0xCB); //A RETF Instruction + return 5; case CB_IRET: - mem_writeb(linearAddress+0,(Bit8u)0xFE); //GRP 4 - mem_writeb(linearAddress+1,(Bit8u)0x38); //Extra Callback instruction - mem_writew(linearAddress+2,callback); //The immediate word - mem_writeb(linearAddress+4,(Bit8u)0xCF); //An IRET Instruction - break; + phys_writeb(physAddress+0,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+1,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+2,callback); //The immediate word + phys_writeb(physAddress+4,(Bit8u)0xCF); //An IRET Instruction + return 5; case CB_IRET_STI: - mem_writeb(linearAddress+0,(Bit8u)0xFB); //STI - mem_writeb(linearAddress+1,(Bit8u)0xFE); //GRP 4 - mem_writeb(linearAddress+2,(Bit8u)0x38); //Extra Callback instruction - mem_writew(linearAddress+3, callback); //The immediate word - mem_writeb(linearAddress+5,(Bit8u)0xCF); //An IRET Instruction - break; + phys_writeb(physAddress+0,(Bit8u)0xFB); //STI + phys_writeb(physAddress+1,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+2,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+3, callback); //The immediate word + phys_writeb(physAddress+5,(Bit8u)0xCF); //An IRET Instruction + return 6; default: E_Exit("CALLBACK:Setup:Illegal type %d",type); } - CallBack_Handlers[callback]=handler; - CALLBACK_SetDescription(callback,descr); - return true; + return 0; } CALLBACK_HandlerObject::~CALLBACK_HandlerObject(){ From 17e0c0b8c592a415ba5107f2981314a2d0a04fc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 7 Feb 2006 20:12:27 +0000 Subject: [PATCH 2389/4131] fix VESA_ScanLineLength subcall 1; improve some vesa mode detection a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2473 --- src/ints/int10_vesa.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 259f24de..cf9c1897 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.20 2006-02-02 17:57:08 harekiet Exp $ */ +/* $Id: int10_vesa.cpp,v 1.21 2006-02-07 20:12:27 c2woody Exp $ */ #include #include @@ -127,6 +127,7 @@ Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off) { Bitu i=0; if (mode<0x100) return 0x01; + mode&=0xfff; while (ModeList_VGA[i].mode!=0xffff) { if (mode==ModeList_VGA[i].mode) goto foundit; else i++; } @@ -319,10 +320,12 @@ Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u val, Bit16u & bytes,Bit16u & pixe default: return 0x1; //Illegal call } - /* Write the scan line to video card the simple way */ - if (vga.config.scan_len & 7) - vga.config.scan_len += 8; - vga.config.scan_len /= 8; + if (subcall!=0x01) { + /* Write the scan line to video card the simple way */ + if (vga.config.scan_len & 7) + vga.config.scan_len += 8; + vga.config.scan_len /= 8; + } pixels=(vga.config.scan_len*8)/bpp; bytes=vga.config.scan_len*8; lines = 2*1024*1024 / bytes; From 163e4a81a23b0374d42492f7c49d991f7c094de5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 7 Feb 2006 20:25:47 +0000 Subject: [PATCH 2390/4131] Some special case for mode 6 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2474 --- src/ints/int10_char.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 90ebe5de..5906de56 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.43 2006-01-30 10:07:19 harekiet Exp $ */ +/* $Id: int10_char.cpp,v 1.44 2006-02-07 20:25:47 qbix79 Exp $ */ /* Character displaying moving functions */ @@ -490,6 +490,10 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt } } + //Some weird behavior of mode 6 (and 11) + if ((CurMode->mode == 0x6)/* || (CurMode->mode==0x11)*/) attr = (attr&0x80)|1; + //(same fix for 11 fixes vgatest2, but it's not entirely correct according to wd) + x=8*col; y=cheight*row;Bit8u xor_mask=(CurMode->type == M_VGA) ? 0x0 : 0x80; //TODO Check for out of bounds From 3be8dfc37af6e506b57aebe4db15bc98f0531b0d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 8 Feb 2006 07:16:15 +0000 Subject: [PATCH 2391/4131] Fix png output from generating too big files and being unreadable for certain viewers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2475 --- src/hardware/hardware.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 1627e3d2..5ce67e96 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: hardware.cpp,v 1.10 2006-01-30 16:10:13 qbix79 Exp $ */ +/* $Id: hardware.cpp,v 1.11 2006-02-08 07:16:15 harekiet Exp $ */ #include #include @@ -385,13 +385,13 @@ void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags, rowPointer=(data+(i >> 0)*pitch); } png_write_row(png_ptr, (png_bytep)rowPointer); - png_write_flush( png_ptr ); } - /*close file*/ - fclose(fp); - + /* Finish writing */ + png_write_end(png_ptr, 0); /*Destroy PNG structs*/ png_destroy_write_struct(&png_ptr, &info_ptr); + /*close file*/ + fclose(fp); } skip_shot: if (CaptureState & CAPTURE_VIDEO) { From b2ca61030edf8c659e179a76a610b2b66063fa7f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 8 Feb 2006 15:13:06 +0000 Subject: [PATCH 2392/4131] Fix ROM checksum. (was broken as setupvesa modifies the rom as well) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2476 --- src/ints/int10.cpp | 1 + src/ints/int10.h | 1 + src/ints/int10_memory.cpp | 21 ++++++++++++++------- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 8c66058d..53a4a013 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -546,5 +546,6 @@ void INT10_Init(Section* sec) { INT10_SetupRomMemory(); INT10_Seg40Init(); INT10_SetupVESA(); + INT10_SetupRomMemoryChecksum();//SetupVesa modifies the rom as well. INT10_SetVideoMode(machine==MCH_HERC ? 0x7 : 0x3); }; diff --git a/src/ints/int10.h b/src/ints/int10.h index aa195c1b..8ae53e17 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -201,6 +201,7 @@ Bit8u VESA_GetPalette(PhysPt data,Bitu index,Bitu count); /* Sup Groups */ void INT10_SetupRomMemory(void); +void INT10_SetupRomMemoryChecksum(void); void INT10_SetupVESA(void); /* EGA RIL */ diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 52f51a3d..abdedc69 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -72,6 +72,7 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu } } +static Bitu checksumlocation = 0; //Same type as int10.rom.used void INT10_SetupRomMemory(void) { /* This should fill up certain structures inside the Video Bios Rom Area */ PhysPt rom_base=PhysMake(0xc000,0); @@ -113,16 +114,22 @@ void INT10_SetupRomMemory(void) { RealSetVec(0x1F,int10.rom.font_8_second); if (machine == MCH_VGA) { //EGA/VGA. Just to be safe - /* Sum of all bytes in rom module 256 should be 0 */ - Bit8u sum = 0; - for (i = 0;i < 32 * 1024;i++) //32 KB romsize - sum += phys_readb(rom_base + i); //OVERFLOW IS OKAY - sum = 256 - sum; - phys_writeb(rom_base+int10.rom.used++,sum); + //Reserve checksum location + checksumlocation = int10.rom.used++; } }; - +void INT10_SetupRomMemoryChecksum(void) { + if (machine == MCH_VGA) { //EGA/VGA. Just to be safe + /* Sum of all bytes in rom module 256 should be 0 */ + Bit8u sum = 0; + PhysPt rom_base = PhysMake(0xc000,0); + for (Bitu i = 0;i < 32 * 1024;i++) //32 KB romsize + sum += phys_readb(rom_base + i); //OVERFLOW IS OKAY + sum = 256 - sum; + phys_writeb(rom_base + checksumlocation,sum); + } +} Bit8u int10_font_08[256 * 8] = { From eb3209cc3a56f6c6e8f54317c6cafb305fbcf522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 8 Feb 2006 19:03:52 +0000 Subject: [PATCH 2393/4131] fix pcjr doublewidth of mode 0x0a Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2477 --- src/hardware/vga_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 0feadf10..30a7c63e 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -598,7 +598,7 @@ void VGA_SetupDrawing(Bitu val) { aspect_ratio=1.2; doubleheight=true; if (machine==MCH_TANDY) doublewidth=(vga.tandy.mode_control & 0x10)==0; - else doublewidth=(vga.tandy.gfx_control & 0x8)==0x00; + else doublewidth=(vga.tandy.mode_control & 0x01)==0x00; vga.draw.blocks=width * 2; width=vga.draw.blocks*4; if ((machine==MCH_TANDY && (vga.tandy.gfx_control & 0x8)) || From bb17ee6101b2a75731b4589a6d7760f148353cca Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 9 Feb 2006 08:42:42 +0000 Subject: [PATCH 2394/4131] add icon to titlebar Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2478 --- src/gui/Makefile.am | 2 +- src/gui/dosbox_logo.h | 539 ++++++++++++++++++++++++++++++++++++++++++ src/gui/sdlmain.cpp | 15 +- 3 files changed, 554 insertions(+), 2 deletions(-) create mode 100644 src/gui/dosbox_logo.h diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 3d96a05b..9e017c5d 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -1,7 +1,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libgui.a -libgui_a_SOURCES = sdlmain.cpp sdl_mapper.cpp \ +libgui_a_SOURCES = sdlmain.cpp sdl_mapper.cpp dosbox_logo.h \ render.cpp render_scalers.cpp render_scalers.h \ render_templates.h render_loops.h \ midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h midi_alsa.h diff --git a/src/gui/dosbox_logo.h b/src/gui/dosbox_logo.h new file mode 100644 index 00000000..50aba157 --- /dev/null +++ b/src/gui/dosbox_logo.h @@ -0,0 +1,539 @@ +/* + * Copyright (C) 2002-2006 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: dosbox_logo.h,v 1.1 2006-02-09 08:42:42 qbix79 Exp $ */ + +/* Select only one logo at the time */ +#define LOGO_1 1 +//#define LOGO_2 1 +#ifdef LOGO_1 +64 , 46, 30,0, 64, 46, 30,0, 91, 61, 37,0, 91, 61, 37,0 +, 91, 61, 37,0, 89, 60, 37,0, 94, 62, 37,0, 95, 62, 36,0 +, 94, 62, 37,0, 94, 62, 37,0, 95, 64, 39,0, 95, 64, 39,0 +, 95, 64, 39,0, 95, 64, 39,0, 94, 62, 37,0, 94, 62, 37,0 +, 88, 58, 34,0, 88, 58, 34,0, 94, 62, 37,0, 94, 62, 37,0 +, 91, 61, 37,0, 91, 61, 36,0, 91, 61, 36,0, 88, 58, 34,0 +, 91, 60, 35,0, 91, 60, 35,0, 82, 53, 31,0, 82, 53, 31,0 +, 86, 56, 32,0, 86, 56, 32,0, 61, 42, 27,0, 61, 42, 27,0 +, 64, 46, 30,0, 64, 46, 30,0, 91, 61, 37,0, 91, 61, 37,0 +, 89, 60, 37,0, 89, 60, 37,0, 95, 62, 36,0, 95, 62, 36,0 +, 94, 62, 37,0, 94, 62, 37,0, 95, 64, 39,0, 95, 64, 39,0 +, 95, 64, 39,0, 95, 64, 39,0, 94, 62, 37,0, 94, 62, 37,0 +, 88, 58, 34,0, 88, 58, 34,0, 94, 62, 37,0, 94, 62, 37,0 +, 91, 61, 37,0, 91, 61, 37,0, 91, 61, 36,0, 91, 61, 36,0 +, 91, 60, 35,0, 91, 60, 35,0, 82, 53, 31,0, 82, 53, 31,0 +, 86, 56, 32,0, 86, 56, 32,0, 61, 42, 27,0, 61, 42, 27,0 +, 79, 53, 33,0, 79, 53, 33,0,142, 95, 58,0,142, 95, 58,0 +,139, 82, 43,0,139, 82, 43,0,129, 77, 39,0,129, 77, 39,0 +,132, 82, 44,0,132, 82, 44,0,143, 91, 49,0,143, 91, 49,0 +,132, 82, 44,0,132, 82, 44,0,129, 77, 40,0,129, 77, 40,0 +,112, 69, 36,0,112, 69, 36,0,136, 85, 45,0,136, 85, 45,0 +,136, 86, 47,0,136, 86, 47,0,119, 75, 39,0,119, 75, 39,0 +,119, 73, 38,0,119, 73, 38,0,125, 76, 39,0,125, 76, 39,0 +,131, 85, 49,0,131, 85, 49,0, 82, 53, 31,0, 82, 53, 31,0 +, 79, 53, 33,0, 79, 53, 33,0,142, 95, 58,0,142, 95, 58,0 +,139, 82, 43,0,139, 82, 43,0,129, 77, 39,0,129, 77, 39,0 +,132, 82, 44,0,129, 77, 40,0,143, 91, 49,0,143, 91, 49,0 +,132, 82, 44,0,132, 82, 44,0,129, 77, 40,0,129, 77, 40,0 +,112, 69, 36,0,112, 69, 36,0,136, 85, 45,0,136, 85, 45,0 +,136, 86, 47,0,136, 85, 45,0,119, 75, 39,0,119, 75, 39,0 +,119, 73, 38,0,119, 73, 38,0,125, 76, 39,0,125, 76, 39,0 +,131, 85, 49,0,131, 85, 49,0, 82, 53, 31,0, 82, 53, 31,0 +, 77, 50, 31,0, 77, 50, 31,0,141, 82, 43,0,141, 82, 43,0 +,255,229, 42,0,255,229, 42,0,255,238, 87,0,255,238, 88,0 +,125, 98, 52,0,125, 98, 52,0,145,120, 69,0,145,120, 69,0 +,133,105, 55,0,133,105, 55,0,255,233, 60,0,255,233, 60,0 +,255,238, 88,0,255,238, 88,0,127,100, 53,0,127,100, 53,0 +,143,117, 67,0,143,117, 67,0,132,105, 55,0,132,105, 55,0 +,255,234, 67,0,255,234, 67,0,255,238, 89,0,255,238, 89,0 +, 83, 49, 23,0, 81, 47, 23,0, 76, 49, 27,0, 82, 51, 26,0 +, 77, 50, 31,0, 79, 53, 33,0,141, 82, 43,0,141, 82, 43,0 +,255,229, 42,0,255,229, 42,0,255,238, 88,0,255,238, 88,0 +,125, 98, 52,0,125, 98, 52,0,145,120, 69,0,145,120, 69,0 +,133,105, 55,0,133,105, 55,0,255,233, 60,0,255,233, 60,0 +,255,238, 88,0,255,238, 88,0,127,100, 53,0,127,100, 53,0 +,143,117, 67,0,143,117, 67,0,132,105, 55,0,132,105, 55,0 +,255,234, 67,0,255,235, 73,0,255,238, 89,0,255,238, 89,0 +, 83, 49, 23,0, 81, 47, 23,0, 80, 50, 27,0, 80, 50, 27,0 +, 77, 50, 31,0, 77, 50, 31,0,143, 78, 37,0,143, 78, 37,0 +,255,229, 43,0,255,229, 42,0, 82, 56, 21,0, 82, 56, 21,0 +,255,238, 88,0,255,238, 88,0, 97, 72, 30,0, 97, 72, 30,0 +,255,233, 60,0,255,233, 60,0, 16, 12, 5,0, 16, 12, 5,0 +,102, 75, 32,0,102, 75, 32,0,255,238, 88,0,255,238, 88,0 +,107, 80, 36,0,107, 80, 36,0,255,224, 13,0,255,224, 13,0 +, 65, 45, 19,0, 65, 45, 19,0, 47, 37, 16,0, 48, 38, 19,0 +, 63, 35, 14,0, 63, 35, 14,0, 77, 46, 22,0, 77, 46, 22,0 +, 77, 51, 30,0, 77, 51, 30,0,143, 78, 37,0,143, 78, 37,0 +,255,229, 43,0,255,229, 42,0, 82, 56, 21,0, 82, 56, 21,0 +,255,238, 88,0,255,238, 88,0, 97, 72, 30,0, 98, 75, 35,0 +,255,233, 60,0,255,233, 60,0, 16, 12, 5,0, 16, 12, 5,0 +,102, 75, 32,0,102, 75, 32,0,255,238, 88,0,255,238, 88,0 +,107, 80, 36,0,107, 80, 36,0,255,224, 13,0,255,224, 13,0 +, 65, 45, 19,0, 65, 45, 19,0, 47, 37, 16,0, 47, 37, 16,0 +, 63, 35, 14,0, 63, 35, 14,0, 77, 46, 22,0, 77, 46, 22,0 +, 82, 53, 31,0, 82, 53, 31,0,144, 81, 38,0,143, 77, 35,0 +,255,231, 49,0,255,231, 49,0, 14, 11, 3,0, 16, 12, 3,0 +,255,238, 88,0,255,238, 88,0, 62, 48, 12,0, 62, 48, 12,0 +,255,238, 89,0,255,238, 89,0, 27, 21, 8,0, 27, 21, 8,0 +,109, 84, 35,0,106, 84, 35,0,255,238, 88,0,255,238, 88,0 +, 11, 8, 3,0, 11, 8, 3,0,106, 84, 35,0,106, 84, 35,0 +,255,238, 88,0,255,238, 87,0, 98, 75, 35,0, 98, 75, 35,0 +,100, 54, 18,0,100, 54, 18,0, 82, 51, 26,0, 77, 46, 22,0 +, 82, 53, 31,0, 82, 53, 31,0,143, 77, 35,0,143, 77, 35,0 +,255,231, 49,0,255,231, 49,0, 14, 11, 3,0, 16, 12, 3,0 +,255,238, 88,0,255,238, 88,0, 62, 48, 12,0, 62, 48, 12,0 +,255,238, 89,0,255,238, 89,0, 27, 21, 8,0, 27, 21, 8,0 +,106, 84, 35,0,106, 84, 35,0,255,238, 88,0,255,238, 88,0 +, 11, 8, 3,0, 11, 8, 3,0,106, 84, 35,0,106, 84, 35,0 +,255,238, 87,0,255,238, 87,0, 98, 75, 35,0, 98, 75, 35,0 +,100, 54, 18,0,100, 54, 18,0, 79, 47, 22,0, 82, 51, 26,0 +, 77, 51, 30,0, 82, 53, 31,0,135, 73, 33,0,135, 73, 33,0 +,255,232, 57,0,255,232, 57,0, 2, 2, 1,0, 2, 2, 1,0 +,255,238, 88,0,255,238, 88,0, 75, 58, 13,0, 75, 58, 13,0 +,255,238, 89,0,255,238, 89,0, 80, 62, 19,0, 80, 62, 19,0 +, 82, 64, 22,0, 82, 64, 22,0,255,238, 88,0,255,238, 89,0 +, 2, 2, 1,0, 2, 2, 1,0,111, 86, 36,0,111, 86, 36,0 +, 88, 63, 23,0, 88, 63, 23,0,255,238, 88,0,255,238, 88,0 +, 62, 33, 10,0, 62, 33, 10,0, 83, 49, 23,0, 83, 49, 23,0 +, 77, 51, 30,0, 77, 51, 30,0,135, 73, 33,0,135, 73, 33,0 +,255,232, 57,0,255,232, 57,0, 2, 2, 1,0, 2, 2, 1,0 +,255,238, 89,0,255,238, 88,0, 75, 58, 13,0, 75, 58, 13,0 +,255,238, 88,0,255,238, 88,0, 80, 62, 19,0, 80, 62, 19,0 +, 82, 64, 22,0, 82, 64, 22,0,255,238, 88,0,255,238, 88,0 +, 2, 2, 1,0, 2, 2, 1,0,111, 86, 36,0,111, 86, 36,0 +, 88, 63, 23,0, 88, 63, 23,0,255,238, 88,0,255,238, 88,0 +, 62, 33, 10,0, 62, 33, 10,0, 83, 49, 23,0, 83, 49, 23,0 +, 79, 52, 30,0, 76, 49, 27,0,144, 81, 40,0,144, 81, 40,0 +,255,238, 87,0,255,238, 87,0,255,238, 88,0,255,238, 88,0 +, 57, 46, 20,0, 57, 44, 14,0,111, 87, 27,0,111, 87, 27,0 +,104, 80, 30,0,104, 80, 30,0,255,238, 88,0,255,238, 88,0 +,255,238, 87,0,255,238, 88,0, 47, 37, 16,0, 47, 37, 16,0 +,116, 91, 38,0,116, 91, 38,0,255,238, 88,0,255,238, 88,0 +,255,238, 88,0,255,238, 88,0, 38, 30, 13,0, 38, 30, 13,0 +, 53, 28, 9,0, 53, 28, 9,0, 77, 46, 22,0, 81, 47, 23,0 +, 76, 49, 27,0, 76, 49, 27,0,144, 81, 40,0,144, 81, 40,0 +,255,238, 87,0,255,238, 87,0,255,238, 87,0,255,238, 87,0 +, 57, 44, 14,0, 57, 44, 14,0,111, 87, 27,0,111, 87, 27,0 +,104, 80, 30,0,104, 80, 30,0,255,238, 88,0,255,238, 88,0 +,255,238, 88,0,255,238, 88,0, 47, 37, 16,0, 47, 37, 16,0 +,116, 91, 38,0,116, 91, 38,0,255,238, 88,0,255,238, 88,0 +,255,238, 88,0,255,238, 88,0, 38, 30, 13,0, 38, 30, 13,0 +, 53, 28, 9,0, 53, 28, 9,0, 83, 49, 23,0, 77, 46, 22,0 +, 82, 53, 31,0, 82, 53, 31,0,153, 91, 46,0,153, 91, 46,0 +,125,101, 52,0,125,101, 52,0, 63, 50, 23,0, 57, 46, 20,0 +, 66, 51, 23,0, 66, 51, 23,0,140,115, 53,0,140,115, 53,0 +,134,109, 51,0,134,109, 51,0,118, 94, 41,0,118, 94, 41,0 +, 47, 37, 16,0, 47, 37, 16,0, 63, 50, 23,0, 63, 50, 23,0 +,129,105, 46,0,129,105, 46,0,114, 92, 41,0,114, 92, 41,0 +, 71, 57, 25,0, 71, 57, 25,0, 68, 52, 26,0, 68, 52, 26,0 +,105, 55, 18,0,105, 55, 18,0, 82, 51, 26,0, 79, 47, 22,0 +, 79, 53, 33,0, 77, 51, 30,0,153, 91, 46,0,153, 91, 46,0 +,125,101, 52,0,125,101, 52,0, 57, 46, 20,0, 57, 46, 20,0 +, 66, 51, 23,0, 66, 51, 23,0,140,115, 53,0,140,115, 53,0 +,134,109, 51,0,134,109, 51,0,118, 94, 41,0,118, 94, 41,0 +, 47, 38, 16,0, 47, 37, 16,0, 63, 50, 23,0, 63, 50, 23,0 +,129,105, 46,0,129,105, 46,0,114, 92, 41,0,114, 92, 41,0 +, 71, 57, 25,0, 71, 57, 25,0, 68, 52, 26,0, 68, 52, 26,0 +,105, 55, 18,0,100, 54, 18,0, 82, 51, 26,0, 82, 51, 26,0 +, 77, 51, 30,0, 82, 53, 31,0,158, 96, 50,0,158, 96, 50,0 +,130,104, 57,0,130,104, 57,0,123, 98, 47,0,123, 98, 47,0 +,131,109, 52,0,131,109, 52,0,139,116, 57,0,139,116, 57,0 +,137,114, 58,0,137,114, 58,0,123, 98, 47,0,123, 98, 47,0 +,125,101, 49,0,125,101, 49,0,139,115, 59,0,139,115, 59,0 +,141,118, 62,0,141,118, 62,0,137,110, 58,0,137,110, 58,0 +,130,106, 52,0,130,106, 52,0,131,108, 55,0,131,108, 55,0 +,107, 58, 20,0,107, 58, 20,0, 80, 50, 27,0, 80, 50, 27,0 +, 77, 51, 30,0, 82, 53, 31,0,158, 96, 50,0,158, 96, 50,0 +,130,104, 57,0,127,100, 53,0,121, 97, 46,0,118, 92, 43,0 +,131,109, 52,0,131,109, 52,0,139,116, 57,0,139,116, 57,0 +,137,114, 58,0,137,114, 58,0,123, 98, 47,0,123, 98, 47,0 +,125,101, 49,0,125,101, 49,0,139,115, 59,0,139,115, 59,0 +,141,118, 62,0,141,118, 62,0,137,110, 58,0,137,110, 58,0 +,130,106, 52,0,130,106, 52,0,131,108, 55,0,131,108, 55,0 +,107, 58, 20,0,107, 58, 20,0, 82, 51, 26,0, 82, 51, 26,0 +, 76, 50, 29,0, 76, 50, 29,0,141, 82, 43,0,144, 81, 38,0 +,255,231, 49,0,255,230, 46,0,255,238, 88,0,255,238, 88,0 +,118, 90, 42,0,118, 90, 42,0,137,114, 58,0,138,111, 58,0 +,120, 93, 46,0,120, 93, 46,0,255,233, 60,0,255,233, 60,0 +,255,238, 88,0,255,238, 88,0,118, 92, 43,0,118, 92, 43,0 +,118, 91, 42,0,118, 91, 42,0,255,235, 73,0,255,235, 73,0 +,100, 73, 31,0,100, 73, 31,0,255,238, 88,0,255,238, 88,0 +, 97, 54, 19,0, 97, 54, 19,0, 83, 49, 23,0, 77, 46, 22,0 +, 72, 46, 26,0, 76, 50, 29,0,144, 81, 38,0,141, 82, 43,0 +,255,230, 46,0,255,230, 46,0,255,238, 88,0,255,238, 87,0 +,118, 90, 42,0,118, 90, 42,0,137,110, 58,0,137,110, 58,0 +,120, 93, 46,0,120, 93, 46,0,255,233, 60,0,255,232, 57,0 +,255,238, 88,0,255,238, 88,0,118, 92, 43,0,118, 92, 43,0 +,118, 91, 42,0,118, 94, 41,0,255,235, 73,0,255,235, 73,0 +,100, 73, 31,0,100, 73, 31,0,255,238, 88,0,255,238, 88,0 +, 97, 54, 19,0, 97, 54, 19,0, 77, 46, 22,0, 81, 47, 23,0 +, 76, 50, 29,0, 76, 50, 29,0,135, 73, 33,0,135, 73, 33,0 +,255,228, 35,0,255,228, 35,0, 82, 56, 21,0, 82, 56, 20,0 +,255,238, 88,0,255,238, 88,0,107, 80, 36,0,107, 80, 36,0 +,255,223, 10,0,255,223, 10,0, 14, 11, 3,0, 14, 11, 3,0 +, 97, 72, 30,0, 97, 72, 30,0,255,238, 87,0,255,238, 87,0 +, 93, 70, 27,0, 93, 70, 27,0,255,221, 2,0,255,221, 2,0 +, 66, 50, 15,0, 67, 52, 16,0,255,238, 88,0,255,238, 88,0 +, 62, 33, 10,0, 62, 32, 8,0, 74, 43, 19,0, 74, 43, 19,0 +, 76, 50, 29,0, 76, 50, 29,0,135, 73, 33,0,135, 73, 33,0 +,255,228, 35,0,255,228, 37,0, 82, 56, 21,0, 82, 56, 20,0 +,255,238, 88,0,255,238, 88,0,104, 80, 30,0,107, 80, 36,0 +,255,224, 13,0,255,224, 13,0, 14, 11, 3,0, 16, 12, 3,0 +,100, 73, 31,0, 97, 72, 30,0,255,238, 87,0,255,238, 88,0 +, 93, 70, 27,0, 93, 70, 27,0,255,221, 2,0,255,221, 2,0 +, 66, 50, 15,0, 67, 52, 16,0,255,238, 88,0,255,238, 88,0 +, 62, 32, 8,0, 62, 32, 8,0, 74, 43, 19,0, 74, 43, 19,0 +, 83, 55, 32,0, 83, 55, 32,0,130, 70, 31,0,130, 70, 31,0 +,255,232, 57,0,255,232, 57,0,255,238, 88,0,255,238, 88,0 +, 43, 34, 8,0, 43, 34, 8,0, 80, 62, 19,0, 82, 64, 20,0 +,255,238, 87,0,255,238, 87,0, 27, 21, 8,0, 27, 21, 8,0 +,109, 84, 35,0,109, 84, 35,0,255,228, 37,0,255,228, 37,0 +, 35, 26, 9,0, 35, 26, 9,0, 82, 64, 22,0, 82, 64, 22,0 +,255,238, 88,0,255,238, 87,0, 49, 39, 13,0, 49, 39, 13,0 +, 68, 31, 2,0, 68, 31, 2,0, 76, 43, 16,0, 76, 43, 16,0 +, 83, 55, 32,0, 83, 55, 32,0,130, 70, 31,0,130, 70, 31,0 +,255,232, 57,0,255,232, 57,0,255,238, 88,0,255,238, 88,0 +, 43, 34, 8,0, 43, 34, 8,0, 82, 64, 20,0, 82, 64, 20,0 +,255,238, 87,0,255,238, 87,0, 27, 21, 8,0, 27, 21, 8,0 +,109, 84, 35,0,109, 84, 35,0,255,228, 37,0,255,228, 37,0 +, 35, 26, 9,0, 35, 26, 9,0, 82, 64, 22,0, 82, 64, 22,0 +,255,238, 87,0,255,238, 87,0, 49, 39, 13,0, 49, 39, 13,0 +, 68, 31, 2,0, 68, 31, 2,0, 76, 43, 16,0, 76, 43, 16,0 +, 72, 46, 26,0, 72, 46, 26,0,133, 69, 30,0,133, 69, 30,0 +,255,238, 88,0,255,238, 87,0, 14, 11, 3,0, 14, 11, 3,0 +,255,238, 89,0,255,238, 89,0, 82, 63, 15,0, 82, 63, 15,0 +,255,238, 89,0,255,238, 88,0, 80, 62, 19,0, 80, 62, 19,0 +, 86, 67, 22,0, 86, 67, 22,0,255,238, 88,0,255,238, 88,0 +, 67, 52, 16,0, 67, 52, 16,0,255,238, 87,0,255,238, 88,0 +, 42, 33, 8,0, 42, 33, 8,0,255,238, 89,0,255,238, 89,0 +, 68, 31, 2,0, 68, 31, 2,0, 68, 36, 11,0, 68, 36, 11,0 +, 72, 46, 26,0, 72, 46, 26,0,133, 69, 30,0,133, 69, 30,0 +,255,238, 87,0,255,238, 87,0, 14, 11, 3,0, 14, 11, 3,0 +,255,238, 89,0,255,238, 89,0, 82, 63, 15,0, 82, 63, 15,0 +,255,238, 88,0,255,238, 88,0, 80, 62, 19,0, 80, 62, 19,0 +, 86, 67, 22,0, 86, 67, 22,0,255,238, 88,0,255,238, 88,0 +, 67, 52, 16,0, 67, 52, 16,0,255,238, 87,0,255,238, 88,0 +, 42, 33, 8,0, 42, 33, 8,0,255,238, 89,0,255,238, 88,0 +, 68, 31, 2,0, 68, 31, 2,0, 68, 36, 11,0, 68, 36, 11,0 +, 75, 48, 27,0, 75, 48, 27,0,138, 77, 35,0,138, 77, 35,0 +,255,238, 88,0,255,238, 88,0,255,238, 88,0,255,238, 88,0 +, 47, 37, 11,0, 47, 37, 11,0,108, 84, 26,0,108, 84, 26,0 +, 95, 76, 27,0, 95, 76, 27,0,255,238, 89,0,255,238, 89,0 +,255,238, 88,0,255,238, 88,0, 71, 55, 20,0, 71, 55, 20,0 +, 98, 77, 26,0, 98, 77, 26,0,255,238, 88,0,255,238, 88,0 +, 78, 62, 19,0, 78, 62, 19,0,255,238, 88,0,255,238, 88,0 +, 31, 15, 2,0, 31, 15, 2,0, 71, 40, 13,0, 71, 40, 13,0 +, 75, 48, 27,0, 75, 48, 27,0,138, 77, 35,0,138, 77, 35,0 +,255,238, 88,0,255,238, 88,0,255,238, 88,0,255,238, 88,0 +, 47, 37, 11,0, 49, 39, 13,0,108, 84, 26,0,108, 84, 26,0 +, 95, 76, 27,0, 95, 76, 27,0,255,238, 89,0,255,238, 89,0 +,255,238, 88,0,255,238, 88,0, 71, 55, 20,0, 71, 55, 20,0 +, 98, 77, 26,0, 98, 77, 26,0,255,238, 88,0,255,238, 88,0 +, 78, 62, 19,0, 78, 62, 19,0,255,238, 88,0,255,238, 88,0 +, 31, 15, 2,0, 31, 15, 2,0, 71, 40, 13,0, 71, 40, 13,0 +, 77, 50, 31,0, 77, 50, 31,0,127, 80, 43,0,127, 80, 43,0 +,118, 64, 25,0,118, 64, 25,0, 93, 47, 10,0, 93, 46, 7,0 +, 53, 24, 1,0, 53, 24, 1,0,122, 58, 6,0,122, 58, 6,0 +,128, 64, 15,0,128, 64, 15,0,117, 58, 15,0,117, 58, 15,0 +, 91, 46, 9,0, 91, 46, 9,0, 91, 46, 9,0, 91, 46, 9,0 +,119, 60, 10,0,119, 60, 10,0,115, 58, 11,0,115, 58, 11,0 +, 96, 43, 1,0, 96, 43, 1,0, 93, 47, 10,0, 93, 47, 10,0 +, 53, 28, 9,0, 54, 30, 10,0, 77, 46, 22,0, 77, 46, 22,0 +, 77, 50, 31,0, 77, 50, 31,0,127, 80, 43,0,127, 80, 43,0 +,118, 64, 25,0,118, 64, 25,0, 93, 46, 7,0, 93, 46, 7,0 +, 53, 24, 1,0, 53, 24, 1,0,122, 58, 6,0,122, 58, 6,0 +,128, 64, 15,0,119, 60, 10,0,117, 58, 15,0,117, 58, 15,0 +, 91, 46, 9,0, 91, 46, 9,0, 91, 46, 9,0, 91, 46, 9,0 +,119, 60, 10,0,119, 60, 10,0,115, 58, 11,0,115, 58, 11,0 +, 96, 43, 1,0, 96, 43, 1,0, 93, 47, 10,0, 93, 47, 10,0 +, 53, 28, 9,0, 53, 28, 9,0, 76, 46, 20,0, 77, 46, 22,0 +, 64, 46, 30,0, 64, 46, 30,0, 76, 49, 27,0, 76, 49, 27,0 +, 67, 41, 20,0, 67, 41, 20,0, 65, 37, 14,0, 68, 39, 16,0 +, 66, 37, 14,0, 66, 37, 14,0, 65, 37, 14,0, 65, 37, 14,0 +, 74, 43, 19,0, 71, 41, 19,0, 68, 39, 16,0, 68, 39, 16,0 +, 68, 39, 16,0, 68, 39, 16,0, 69, 39, 16,0, 69, 39, 16,0 +, 65, 37, 14,0, 65, 37, 14,0, 63, 35, 14,0, 63, 35, 14,0 +, 61, 35, 14,0, 65, 37, 14,0, 61, 35, 14,0, 61, 35, 14,0 +, 71, 41, 19,0, 71, 41, 19,0, 59, 37, 20,0, 59, 37, 20,0 +, 65, 45, 29,0, 64, 46, 30,0, 76, 49, 27,0, 76, 49, 27,0 +, 67, 41, 20,0, 67, 41, 20,0, 69, 39, 16,0, 65, 37, 14,0 +, 66, 37, 14,0, 71, 40, 13,0, 65, 37, 14,0, 65, 37, 14,0 +, 68, 41, 17,0, 68, 41, 17,0, 68, 39, 16,0, 68, 39, 16,0 +, 68, 39, 16,0, 69, 39, 16,0, 69, 39, 16,0, 69, 39, 16,0 +, 65, 37, 14,0, 65, 37, 14,0, 63, 35, 14,0, 65, 37, 14,0 +, 61, 35, 14,0, 62, 33, 10,0, 61, 35, 14,0, 61, 35, 14,0 +, 71, 41, 19,0, 71, 41, 19,0, 59, 37, 20,0, 59, 37, 20,0 +#endif +#ifdef LOGO_2 + 59, 42, 28,0, 87, 60, 38,0, 84, 57, 35,0, 81, 54, 33,0 +, 82, 56, 34,0, 88, 59, 36,0, 88, 59, 36,0, 88, 59, 36,0 +, 86, 58, 36,0, 88, 59, 36,0, 89, 60, 37,0, 89, 60, 37,0 +, 87, 60, 38,0, 89, 60, 37,0, 88, 59, 36,0, 84, 57, 35,0 +, 78, 52, 32,0, 84, 57, 35,0, 89, 60, 37,0, 87, 60, 38,0 +, 84, 57, 35,0, 86, 58, 36,0, 84, 57, 35,0, 82, 56, 34,0 +, 82, 56, 34,0, 82, 56, 34,0, 81, 54, 33,0, 76, 51, 31,0 +, 76, 51, 31,0, 81, 54, 33,0, 86, 58, 36,0, 57, 40, 26,0 +, 89, 60, 37,0,136, 95, 61,0,162,108, 65,0,156,103, 62,0 +,153,101, 61,0,160,106, 64,0,158,105, 64,0,156,103, 62,0 +,164,109, 66,0,164,109, 66,0,164,109, 66,0,154,104, 62,0 +,156,103, 62,0,157,104, 62,0,156,103, 62,0,145, 96, 58,0 +,153,101, 61,0,148, 98, 60,0,153,101, 61,0,153,101, 61,0 +,162,108, 65,0,162,108, 65,0,156,103, 62,0,154,104, 62,0 +,156,103, 62,0,162,108, 65,0,148, 98, 60,0,143, 96, 58,0 +,145, 96, 58,0,156,103, 62,0,152,104, 66,0, 87, 60, 38,0 +, 73, 49, 32,0,146, 97, 60,0,148,103, 66,0,167,111, 68,0 +,158,105, 64,0,157,104, 62,0,154,103, 64,0,143, 96, 58,0 +,143, 96, 58,0,143, 96, 58,0,146, 97, 60,0,143, 96, 58,0 +,137, 90, 53,0,148, 97, 57,0,148, 97, 57,0,139, 92, 53,0 +,139, 92, 53,0,138, 92, 56,0,148, 97, 57,0,153,101, 61,0 +,148, 98, 60,0,141, 94, 57,0,141, 94, 57,0,131, 88, 53,0 +,144, 94, 57,0,143, 96, 58,0,150,100, 61,0,148, 98, 60,0 +,154,104, 62,0,142, 97, 62,0,164,109, 66,0, 78, 52, 32,0 +, 70, 48, 29,0,135, 90, 56,0,169,112, 68,0,135, 92, 60,0 +,132, 96, 62,0,130, 97, 62,0,137,101, 66,0,144,106, 69,0 +,140,104, 68,0,138,104, 70,0,137,102, 68,0,140,104, 68,0 +,130, 93, 56,0,223,192, 81,0,237,207, 88,0,237,207, 88,0 +,236,206, 86,0,237,207, 88,0,237,207, 88,0,137,101, 66,0 +,144,106, 69,0,137,102, 68,0,133,101, 66,0,133,101, 66,0 +,137,102, 68,0,130, 97, 62,0,121, 90, 57,0,124, 90, 58,0 +,123, 86, 55,0,162,108, 65,0,156,103, 62,0, 76, 51, 31,0 +, 73, 49, 30,0,146, 97, 60,0,160,106, 64,0,117, 88, 56,0 +,130,112, 74,0,130,112, 74,0,130,112, 74,0,154,135, 91,0 +,166,148,101,0,166,148,101,0,168,149,102,0,166,148, 99,0 +,147,124, 77,0,132,107, 61,0,215,184, 75,0,234,205, 88,0 +,156,136, 86,0,150,129, 80,0,234,205, 85,0,236,206, 86,0 +,164,145, 98,0,164,145, 98,0,165,146,100,0,166,148,101,0 +,154,135, 91,0,130,112, 74,0,133,114, 76,0,133,114, 76,0 +,110, 85, 54,0,153,101, 61,0,164,109, 66,0, 78, 52, 32,0 +, 70, 48, 29,0,158,105, 64,0,162,108, 65,0,124, 90, 58,0 +,129,110, 73,0,130,113, 76,0,130,113, 76,0,129,110, 73,0 +,148,129, 86,0,164,145, 98,0,166,148, 99,0,166,148, 99,0 +,161,142, 93,0,132,107, 61,0,212,178, 73,0,239,210, 92,0 +,156,135, 82,0,153,130, 79,0,236,206, 86,0,238,209, 89,0 +,162,144, 95,0,168,149,102,0,168,149,102,0,150,132, 89,0 +,127,109, 72,0,129,110, 73,0,130,112, 74,0,130,112, 74,0 +,112, 86, 55,0,153,101, 61,0,175,116, 70,0, 73, 49, 30,0 +, 73, 49, 30,0,146, 97, 60,0,167,112, 66,0,137,101, 66,0 +,129,110, 73,0,130,112, 74,0,133,114, 76,0,133,114, 76,0 +,130,112, 74,0,149,131, 88,0,166,148, 99,0,162,144, 95,0 +,157,138, 89,0,132,107, 61,0,208,175, 70,0,234,205, 88,0 +,234,205, 88,0,224,193, 81,0,232,203, 84,0,159,140, 90,0 +,162,144, 97,0,166,148, 99,0,150,132, 89,0,130,112, 74,0 +,133,114, 76,0,132,112, 74,0,130,112, 74,0,130,112, 74,0 +,123, 96, 63,0,150,100, 61,0,160,106, 64,0, 76, 51, 31,0 +, 75, 52, 33,0,141, 94, 57,0,169,113, 67,0,144,106, 69,0 +,161,142, 96,0,129,110, 73,0,129,110, 73,0,132,112, 74,0 +,132,112, 74,0,127,109, 72,0,150,132, 89,0,164,145, 98,0 +,161,142, 93,0,135,112, 63,0,215,184, 75,0,239,210, 92,0 +,156,135, 82,0,144,122, 72,0,232,203, 84,0,237,207, 88,0 +,162,144, 95,0,148,129, 86,0,127,109, 72,0,132,112, 74,0 +,132,112, 74,0,130,112, 74,0,130,112, 74,0,164,145, 98,0 +,127,100, 66,0,150,100, 61,0,156,103, 62,0, 81, 54, 33,0 +, 78, 52, 32,0,144, 94, 57,0,169,113, 67,0,149,109, 69,0 +,166,148,101,0,161,142, 96,0,129,110, 73,0,127,109, 72,0 +,130,112, 74,0,130,112, 74,0,129,110, 73,0,146,128, 84,0 +,153,134, 84,0,137,113, 65,0,217,185, 74,0,236,206, 86,0 +,156,135, 82,0,148,128, 75,0,227,197, 82,0,236,206, 86,0 +,148,129, 86,0,130,112, 74,0,130,112, 74,0,129,110, 73,0 +,127,109, 72,0,127,109, 72,0,161,142, 96,0,168,149,102,0 +,129,100, 68,0,148, 98, 60,0,157,104, 62,0, 82, 56, 34,0 +, 81, 54, 33,0,143, 96, 58,0,173,115, 69,0,149,109, 69,0 +,165,146,100,0,166,148,101,0,161,142, 96,0,130,112, 74,0 +,130,112, 74,0,136,115, 77,0,136,115, 77,0,130,109, 70,0 +,129,106, 61,0,202,166, 65,0,204,170, 69,0,222,190, 80,0 +,227,197, 82,0,217,185, 76,0,217,185, 74,0,140,120, 76,0 +,130,112, 74,0,134,116, 77,0,133,114, 76,0,129,110, 73,0 +,133,114, 76,0,162,144, 97,0,168,149,102,0,166,148,101,0 +,130,100, 65,0,148, 98, 60,0,160,106, 64,0, 82, 56, 34,0 +, 73, 49, 30,0,146, 97, 60,0,167,111, 68,0,149,110, 72,0 +,169,150,104,0,169,150,104,0,165,146,100,0,164,145, 98,0 +,134,116, 77,0,133,114, 76,0,133,114, 76,0,130,109, 70,0 +,115, 94, 55,0,117, 93, 53,0,137,113, 65,0,144,122, 72,0 +,146,124, 75,0,148,126, 78,0,136,117, 73,0,129,110, 73,0 +,134,116, 77,0,134,116, 77,0,132,112, 74,0,134,116, 77,0 +,164,145, 98,0,168,149,102,0,169,150,104,0,166,148,101,0 +,127,100, 66,0,148, 98, 60,0,167,111, 68,0, 82, 56, 34,0 +, 73, 49, 30,0,144, 94, 57,0,161,106, 62,0,153,110, 70,0 +,164,145, 98,0,164,145, 98,0,165,146,100,0,165,146,100,0 +,161,142, 96,0,134,116, 77,0,129,110, 73,0,132,112, 74,0 +,130,109, 70,0,117, 97, 59,0,136,117, 73,0,157,138, 89,0 +,156,136, 86,0,136,117, 73,0,125,106, 68,0,133,114, 76,0 +,136,115, 77,0,130,112, 74,0,134,116, 77,0,164,145, 98,0 +,166,148, 99,0,166,148,101,0,166,148,101,0,165,146,100,0 +,133,101, 66,0,146, 97, 60,0,157,104, 62,0, 81, 54, 33,0 +, 73, 49, 30,0,141, 93, 54,0,158,100, 55,0,227,197, 82,0 +,240,212, 94,0,240,212, 94,0,240,210, 92,0,238,209, 89,0 +,158,140, 93,0,162,144, 95,0,130,113, 76,0,126,108, 70,0 +,125,105, 65,0,125,105, 65,0,239,210, 92,0,240,210, 90,0 +,238,209, 89,0,240,210, 90,0,237,208, 86,0,132,112, 74,0 +,130,112, 74,0,135,117, 80,0,161,142, 93,0,161,142, 93,0 +,240,210, 92,0,240,210, 90,0,240,210, 90,0,240,210, 90,0 +,126, 98, 64,0,143, 96, 58,0,153,101, 61,0, 81, 54, 33,0 +, 69, 46, 28,0,141, 93, 54,0,152, 93, 47,0,110, 72, 38,0 +,215,184, 75,0,236,206, 86,0,157,138, 89,0,231,202, 85,0 +,237,207, 88,0,166,148,101,0,165,146,100,0,133,116, 75,0 +,114, 93, 56,0,222,190, 80,0,236,206, 86,0,122,100, 59,0 +,113, 88, 53,0,109, 87, 48,0,234,205, 88,0,237,207, 88,0 +,135,117, 80,0,162,144, 95,0,148,126, 78,0,217,185, 74,0 +,236,206, 86,0,152,130, 81,0,156,136, 86,0,232,203, 84,0 +,236,206, 86,0,148, 98, 60,0,154,104, 62,0, 78, 52, 32,0 +, 73, 49, 30,0,136, 88, 50,0,151, 94, 49,0,113, 70, 33,0 +,205,173, 66,0,232,204, 82,0,153,133, 79,0,140,117, 70,0 +,231,202, 85,0,236,206, 86,0,166,148, 99,0,162,144, 95,0 +,109, 88, 49,0,212,178, 73,0,232,203, 84,0,125,103, 62,0 +,121, 99, 57,0, 97, 75, 37,0,214,182, 73,0,234,205, 85,0 +,158,140, 93,0,157,138, 89,0,135,112, 63,0,195,160, 60,0 +,221,189, 77,0,232,204, 82,0,154,133, 81,0,159,140, 90,0 +,126, 96, 61,0,125, 84, 50,0,169,112, 68,0, 78, 52, 32,0 +, 76, 51, 31,0,136, 88, 50,0,158, 98, 51,0,113, 70, 33,0 +,214,182, 73,0,237,207, 88,0,148,128, 75,0,140,117, 70,0 +,223,192, 81,0,238,209, 89,0,164,145, 95,0,160,140, 90,0 +,129,106, 61,0,215,184, 75,0,239,210, 92,0,125,105, 65,0 +,125,103, 62,0, 99, 77, 40,0,214,182, 73,0,238,209, 89,0 +,161,142, 93,0,155,136, 86,0,133,109, 62,0,123, 98, 52,0 +,209,176, 70,0,232,203, 84,0,237,208, 86,0,157,138, 89,0 +,123, 95, 59,0,131, 88, 53,0,153,101, 61,0, 82, 56, 34,0 +, 75, 52, 33,0,130, 85, 49,0,161,101, 54,0,115, 72, 34,0 +,217,185, 74,0,234,205, 85,0,150,129, 76,0,144,121, 71,0 +,224,194, 77,0,232,204, 82,0,155,136, 86,0,156,136, 86,0 +,102, 80, 41,0,205,173, 66,0,234,205, 85,0,130,109, 70,0 +,125,105, 65,0,106, 84, 45,0,217,185, 74,0,234,205, 85,0 +,162,144, 95,0,164,145, 95,0,150,129, 80,0,144,121, 71,0 +,144,121, 71,0,141,120, 69,0,230,200, 81,0,234,205, 85,0 +,234,205, 85,0,133, 89, 53,0,153,101, 61,0, 82, 56, 34,0 +, 73, 49, 30,0,132, 84, 49,0,154, 93, 48,0,115, 73, 36,0 +,222,190, 80,0,237,208, 86,0,153,133, 79,0,238,209, 89,0 +,236,206, 86,0,157,138, 89,0,157,138, 89,0,125,105, 65,0 +, 97, 75, 40,0,202,166, 65,0,237,208, 86,0,121,101, 60,0 +,121,101, 60,0,112, 91, 49,0,228,197, 84,0,240,210, 90,0 +,134,116, 77,0,164,145, 98,0,152,130, 81,0,223,192, 81,0 +,238,209, 89,0,150,129, 76,0,144,121, 71,0,234,205, 85,0 +,238,209, 89,0,137, 90, 53,0,160,106, 64,0, 82, 56, 34,0 +, 69, 46, 28,0,139, 92, 53,0,147, 87, 44,0,202,169, 70,0 +,205,172, 72,0,219,189, 82,0,222,190, 80,0,221,189, 77,0 +,153,134, 84,0,161,142, 93,0,130,113, 76,0,125,105, 65,0 +,109, 87, 48,0,101, 77, 41,0,212,178, 73,0,230,200, 81,0 +,230,200, 81,0,217,185, 74,0,220,187, 77,0,125,105, 65,0 +,127,109, 72,0,130,112, 74,0,147,124, 77,0,137,113, 65,0 +,214,182, 73,0,221,189, 77,0,214,182, 73,0,217,185, 76,0 +,113, 88, 53,0,156,103, 62,0,150,100, 61,0, 78, 52, 32,0 +, 69, 46, 28,0,139, 92, 53,0,140, 86, 45,0,117, 76, 39,0 +,135,112, 63,0,137,113, 65,0,142,118, 72,0,152,130, 81,0 +,159,140, 90,0,134,116, 77,0,132,112, 74,0,132,112, 74,0 +,125,105, 65,0,107, 86, 49,0,122,100, 59,0,144,122, 72,0 +,142,120, 73,0,122,100, 59,0,117, 97, 59,0,130,109, 70,0 +,132,112, 74,0,126,108, 70,0,125,105, 65,0,134,112, 65,0 +,134,112, 65,0,137,113, 65,0,142,118, 72,0,150,129, 80,0 +,121, 90, 57,0,138, 92, 56,0,158,105, 64,0, 78, 52, 32,0 +, 69, 46, 28,0,137, 90, 53,0,155,101, 57,0,145,102, 62,0 +,160,140, 90,0,162,144, 95,0,164,145, 98,0,162,144, 95,0 +,133,114, 76,0,132,112, 74,0,133,114, 76,0,132,112, 74,0 +,125,106, 68,0,140,120, 76,0,159,140, 90,0,157,138, 89,0 +,160,140, 90,0,156,136, 86,0,143,124, 80,0,130,109, 70,0 +,133,114, 76,0,132,112, 74,0,126,108, 70,0,125,106, 68,0 +,153,134, 84,0,155,136, 86,0,159,140, 90,0,158,140, 93,0 +,130,100, 65,0,145, 96, 58,0,158,105, 64,0, 76, 51, 31,0 +, 73, 49, 30,0,130, 87, 52,0,167,109, 63,0,143,105, 67,0 +,164,145, 98,0,166,148,101,0,164,145, 98,0,130,113, 76,0 +,130,112, 74,0,136,115, 77,0,136,115, 77,0,130,112, 74,0 +,137,116, 77,0,236,206, 86,0,236,206, 86,0,161,142, 93,0 +,161,142, 93,0,155,136, 86,0,236,206, 86,0,236,206, 86,0 +,130,112, 74,0,133,114, 76,0,133,114, 76,0,125,106, 68,0 +,126,108, 70,0,157,138, 89,0,161,142, 93,0,166,148,101,0 +,129,100, 68,0,143, 96, 58,0,154,104, 62,0, 77, 52, 31,0 +, 81, 54, 33,0,131, 88, 53,0,154,104, 62,0,146,108, 70,0 +,166,148,101,0,164,145, 98,0,130,113, 76,0,130,112, 74,0 +,132,112, 74,0,132,112, 74,0,129,110, 73,0,145,125, 81,0 +,139,116, 69,0,212,178, 73,0,240,212, 94,0,164,145, 95,0 +,162,144, 95,0,157,138, 89,0,239,210, 92,0,240,210, 90,0 +,147,127, 86,0,130,112, 74,0,132,112, 74,0,130,112, 74,0 +,129,110, 73,0,129,110, 73,0,158,140, 93,0,162,144, 97,0 +,127,100, 66,0,133, 89, 53,0,156,103, 62,0, 78, 52, 32,0 +, 78, 52, 32,0,141, 94, 57,0,162,108, 65,0,152,111, 72,0 +,162,144, 97,0,129,110, 73,0,129,110, 73,0,129,110, 73,0 +,129,110, 73,0,126,108, 70,0,148,129, 86,0,162,144, 95,0 +,140,117, 70,0,129,105, 58,0,217,185, 74,0,236,206, 86,0 +,156,136, 86,0,234,205, 85,0,237,207, 88,0,162,144, 95,0 +,165,146,100,0,149,131, 88,0,127,109, 72,0,130,112, 74,0 +,129,110, 73,0,129,110, 73,0,127,109, 72,0,158,140, 93,0 +,126, 98, 64,0,146, 97, 60,0,153,101, 61,0, 81, 54, 33,0 +, 73, 49, 32,0,138, 92, 56,0,164,109, 66,0,140,104, 68,0 +,130,112, 74,0,129,110, 73,0,129,110, 73,0,129,110, 73,0 +,127,109, 72,0,146,128, 84,0,161,142, 96,0,159,140, 90,0 +,155,136, 86,0,137,113, 65,0,133,109, 62,0,224,194, 77,0 +,236,206, 86,0,236,206, 86,0,160,139, 90,0,164,145, 95,0 +,165,146,100,0,166,148,101,0,150,132, 89,0,130,113, 76,0 +,134,116, 77,0,133,114, 76,0,130,113, 76,0,130,113, 76,0 +,122, 95, 61,0,143, 96, 58,0,148, 98, 60,0, 78, 52, 32,0 +, 69, 46, 28,0,135, 90, 56,0,164,109, 66,0,117, 88, 56,0 +,129,110, 73,0,129,110, 73,0,129,110, 73,0,129,110, 73,0 +,149,131, 88,0,164,145, 98,0,164,145, 98,0,161,142, 93,0 +,157,138, 89,0,146,124, 75,0,137,113, 65,0,220,187, 77,0 +,227,197, 82,0,238,209, 89,0,160,140, 90,0,165,146,100,0 +,166,148,101,0,166,148,101,0,164,145, 98,0,150,132, 89,0 +,129,110, 73,0,130,112, 74,0,130,112, 74,0,129,110, 73,0 +,102, 81, 53,0,143, 96, 58,0,150,100, 61,0, 73, 49, 30,0 +, 69, 46, 28,0,146, 97, 60,0,162,108, 65,0,124, 90, 58,0 +,133,114, 76,0,130,112, 74,0,127,109, 72,0,148,129, 86,0 +,162,144, 97,0,165,146,100,0,166,148, 99,0,161,142, 93,0 +,153,134, 84,0,146,124, 75,0,230,200, 81,0,224,194, 77,0 +,133,109, 62,0,217,185, 74,0,234,205, 85,0,162,144, 95,0 +,162,144, 95,0,165,146,100,0,165,146,100,0,165,146,100,0 +,154,137, 93,0,130,112, 74,0,130,112, 74,0,129,110, 73,0 +,110, 85, 54,0,148, 98, 60,0,169,112, 68,0, 70, 48, 29,0 +, 70, 48, 29,0,138, 92, 56,0,162,108, 65,0,121, 90, 57,0 +,130,112, 74,0,129,110, 73,0,150,132, 89,0,162,144, 95,0 +,162,144, 97,0,161,142, 96,0,158,140, 93,0,157,138, 89,0 +,141,120, 69,0,220,187, 77,0,237,208, 86,0,148,128, 75,0 +,135,112, 63,0,129,105, 58,0,230,200, 81,0,238,209, 89,0 +,162,144, 97,0,165,146,100,0,168,149,102,0,169,150,104,0 +,166,148,101,0,150,132, 89,0,129,110, 73,0,130,112, 74,0 +,112, 86, 55,0,150,100, 61,0,164,109, 66,0, 76, 51, 31,0 +, 70, 48, 29,0,135, 90, 56,0,164,109, 66,0,131, 90, 57,0 +,132, 96, 62,0,149,109, 69,0,157,116, 73,0,154,114, 74,0 +,149,110, 72,0,152,111, 72,0,149,109, 69,0,150,109, 66,0 +,125, 82, 44,0,202,168, 67,0,224,193, 81,0,150,107, 61,0 +,150,106, 59,0,117, 76, 39,0,204,170, 67,0,232,203, 84,0 +,152,111, 72,0,152,111, 72,0,149,110, 72,0,149,110, 72,0 +,154,114, 74,0,153,110, 70,0,146,108, 70,0,126, 92, 60,0 +,124, 90, 58,0,167,111, 68,0,157,104, 62,0, 76, 51, 31,0 +, 73, 49, 32,0,141, 94, 57,0,142, 97, 62,0,154,103, 64,0 +,148, 98, 60,0,158,105, 64,0,148, 98, 60,0,141, 94, 57,0 +,141, 94, 57,0,141, 94, 57,0,144, 94, 57,0,147, 94, 54,0 +,128, 76, 37,0,128, 76, 37,0,140, 86, 45,0,147, 94, 54,0 +,129, 81, 45,0,128, 76, 37,0,123, 76, 37,0,129, 81, 45,0 +,153,101, 61,0,145, 96, 58,0,150,100, 61,0,150,100, 61,0 +,141, 94, 57,0,138, 92, 56,0,145, 96, 58,0,143, 96, 58,0 +,150,100, 61,0,142, 97, 62,0,167,111, 68,0, 81, 54, 33,0 +, 87, 60, 38,0,115, 78, 49,0,135, 90, 56,0,127, 84, 52,0 +,119, 80, 49,0,121, 81, 49,0,115, 78, 49,0,115, 78, 49,0 +,124, 82, 50,0,121, 81, 49,0,125, 84, 50,0,136, 88, 50,0 +,121, 78, 45,0,115, 75, 44,0,121, 78, 45,0,115, 75, 44,0 +,115, 75, 44,0,115, 75, 44,0,115, 75, 44,0,121, 78, 45,0 +,124, 82, 50,0,125, 84, 50,0,121, 81, 49,0,124, 82, 50,0 +,119, 80, 49,0,119, 80, 49,0,115, 78, 49,0,115, 78, 49,0 +,121, 81, 49,0,133, 89, 53,0,135, 92, 60,0, 88, 59, 36,0 +, 61, 43, 29,0, 87, 60, 38,0, 73, 49, 30,0, 69, 46, 28,0 +, 69, 46, 28,0, 70, 48, 29,0, 70, 48, 29,0, 70, 48, 29,0 +, 70, 48, 29,0, 70, 48, 29,0, 73, 49, 30,0, 69, 46, 28,0 +, 70, 48, 29,0, 73, 49, 30,0, 69, 46, 28,0, 69, 46, 28,0 +, 69, 45, 26,0, 69, 45, 26,0, 73, 49, 30,0, 70, 48, 29,0 +, 69, 46, 28,0, 73, 49, 30,0, 69, 46, 28,0, 69, 46, 28,0 +, 69, 46, 28,0, 69, 46, 28,0, 69, 46, 28,0, 65, 44, 28,0 +, 65, 44, 28,0, 73, 49, 30,0, 86, 58, 36,0, 60, 42, 27,0 +#endif diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index e05fa274..328f916e 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.98 2006-01-31 09:26:44 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.99 2006-02-09 08:42:42 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -868,11 +868,24 @@ static void SetPriority(PRIORITY_LEVELS level) { } } +static unsigned char logo[32*32*4]= { +#include "dosbox_logo.h" +}; + static void GUI_StartUp(Section * sec) { sec->AddDestroyFunction(&GUI_ShutDown); Section_prop * section=static_cast(sec); sdl.active=false; sdl.updating=false; + + /* Set Icon (must be done before any sdl_setvideomode call) */ +#if WORDS_BIGENDIAN + SDL_Surface* logos= SDL_CreateRGBSurfaceFrom((void*)logo,32,32,32,128,0xff000000,0x00ff0000,0x0000ff00,0); +#else + SDL_Surface* logos= SDL_CreateRGBSurfaceFrom((void*)logo,32,32,32,128,0x000000ff,0x0000ff00,0x00ff0000,0); +#endif + SDL_WM_SetIcon(logos,NULL); + sdl.desktop.fullscreen=section->Get_bool("fullscreen"); sdl.wait_on_error=section->Get_bool("waitonerror"); const char * priority=section->Get_string("priority"); From f29645ce696f43c518dcff920caef0b590f3359f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 9 Feb 2006 08:49:52 +0000 Subject: [PATCH 2395/4131] Add icon + mention movie capturing Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2479 --- README | 1 + configure.in | 13 +++++++++++++ src/Makefile.am | 8 ++++++++ src/dos/dos_programs.cpp | 3 ++- src/dosbox.ico | Bin 0 -> 110434 bytes src/dosbox.rc | 1 + 6 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 src/dosbox.ico create mode 100644 src/dosbox.rc diff --git a/README b/README index f5745e49..cb92aa1b 100644 --- a/README +++ b/README @@ -580,6 +580,7 @@ ALT-ENTER Switch to full screen and back. ALT-PAUSE Pause emulation. CTRL-F1 Start the keymapper. CTRL-F4 Change between mounted disk-images. Update directory cache for all drives! +CTRL-ALT-F5 Start/Stop creating a movie of the screen. CTRL-F5 Save a screenshot.(png) CTRL-F6 Start/Stop recording sound output to a wave file. CTRL-ALT-F7 Start/Stop recording of OPL commands. diff --git a/configure.in b/configure.in index 3afe2214..4a981905 100644 --- a/configure.in +++ b/configure.in @@ -281,6 +281,19 @@ case "$target" in ;; 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_OUTPUT([ Makefile diff --git a/src/Makefile.am b/src/Makefile.am index c18bf996..2ef2a360 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,4 +8,12 @@ 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 hardware/serialport/libserial.a \ libs/zmbv/libzmbv.a + +if HAVE_WINDRES +dosbox_LDADD += dosbox_ico.o +endif + +EXTRA_DIST = dosbox.rc dosbox.ico +dosbox_ico.o: dosbox.rc dosbox.ico + $(WINDRES) dosbox.rc dosbox_ico.o diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index cb7ed663..d678a2c5 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.51 2006-01-22 14:13:00 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.52 2006-02-09 08:49:52 qbix79 Exp $ */ #include #include @@ -939,6 +939,7 @@ void DOS_SetupPrograms(void) { "\033[33;1mALT-PAUSE\033[0m : Pause DOSBox.\n" "\033[33;1mCTRL-F1\033[0m : Start the \033[33mkeymapper\033[0m.\n" "\033[33;1mCTRL-F4\033[0m : Update directory cache for all drives! Swap mounted disk-image.\n" + "\033[33;1mCTRL-ALT-F5\033[0m : Start/Stop creating a movie of the screen.\n" "\033[33;1mCTRL-F5\033[0m : Save a screenshot.\n" "\033[33;1mCTRL-F6\033[0m : Start/Stop recording sound output to a wave file.\n" "\033[33;1mCTRL-ALT-F7\033[0m : Start/Stop recording of OPL commands.\n" diff --git a/src/dosbox.ico b/src/dosbox.ico new file mode 100644 index 0000000000000000000000000000000000000000..b6fcd91612cc498f442829901a57802069cf59bb GIT binary patch literal 110434 zcmXtfWmp?sv~F;BihF@##TwkLxI4uu65QRL;;v1xQrxY$dx0ViQV0QxyE`}EJ?G?C z_Q*3cd(Eu1UfBQu0ssy0-wy$R4k#c*0C>ayhlc*om_-EuAS6Nnn4AC4xSRt35H>>q zaC86f7#9H8j7I>_(f#ij9RT=}hX5cW`=9X`DgeM+f&jqB|DUlP3IOm>fdGipP?N{O zq`-t<3P({vR_njL|NjX1@c?7@avK1E4xlJ2rQ=&L)$NzUxNP|D&f|91)>roP$IlGypnJHOh$)x=+zjivbwBKm?dm2&1n+(l}zACgC+Y2iRE| z-|E62!x8n~D&OMi%MKqKzc9gH{Z;ptfU_Gkw7av_+w&2D-ZwU_k`$*fN!U3#8Cngl%jBVjgYG_LI6GXP?#rcYqa+?!P z--|{dPZ_9>%{{FoSQhP;GQjUSRg9fv-N*0g_=wo>0B&iN++0H$h_nhB9TeTpiP~49 zz4Z~LqKdhozD&VNs{HFhQN%mlQFqmSY6u7gk5a_S2N9mSFeFm_IJN3fAfSn97o-SX z78Z?%ot==0xuDKi?g?==i^^sEs~<%41Hb(uEhrZ~?#sEF_1s8?tG@YB#8PEzglw@P z){SE9qATwbWkl+W;G4_EI-o?}Ymp1zPAd4v&%)bVu_U^30$-O&sho>Uzrx^aQB-#8 zSS{Sq>%v`Da3|j=!wwmjrD!k+3+5KfG2`Yz2;1yK!L79tuirkTX{NDRvX83$WphSrq$N`6F2`O3>b0;*{n5Lf zVxqiG<^-(^a?FoV0i!@J*8s?(}i+|^#sKyO>+Vf6jKK#?xS zv|BJIoMh1l8_|$!fMV9$Nsl8>6W>;h8GfFF)eS$x_x1>*K=Zx4=44P2)x2a@Hu^kb z7r?kmItM6|zt*tfCF<#f z(=%8<-vVo=-m~Uob&Kw?#SEx#-l#`>1}E3n^f%#Li4lRF`uML~LM~GV`Mq4h7Bucc zAK{l?p+N=X)@_C5GIzA1rpMiaDQ{9eICt5{F%us6IURrQ`EV?^7E$gAGIywnnLUco zIBLs7KlEP`wz8(g=Q10Y$QluE_+dbAhkZr0Z`x+5?Y{4Mq`g7k#E#~C$ov<@h%E!L zx5>0gyHg!ZaWKtb!ZwMq{oun#3l3Z77qxbjK^$n($02hJI>z=U=A0Q zhc=z{t@F?6;3pS3vCLR*nkgl+!P4GQj=F@6pxpq>LO-kK4zeK8hO zMCqzh!ov*CW|<(ADj4^RZzAldjpy0-kKk++l~4QE-l>psjyN^TjrU;)ggd#=AHVXg zKL-I~$?ZukXBbXSkyF$^>vhj51F_f>M(sgTo!>CR=AY-m``~x#)BVrQIOv`&c&kbO z{O>Q;_2(s~r>)ZfqL-_22lG}?pAE(OYpnq6;QG_ulz{Vw!0QfXFlrxO$XVz4wToyJ zyAMfP(^`S7mg+Y-^7Ypd0@3&)ZjP%iBk8nlO(p?1Tiq`-TnyYc3Tl|>&IilFS6vkk zh>{iyr|~8AX?6|U^_3GcPBSv=Dbq43$20!|AQiPkpBHAtlE-ZUN$;~^j7kJ$zih8X zhwYXkz>wY+DA!TDxm<+SsrG7e3I0338nqJqvQYaxfNFl0N~!m1<%ksp>dK388jYm3 zQRNEib@IBH;&t>#S;^<`y8)(4DWNlKc~%sR?V_7Y`yG}hL`kDu-v)pCa<&NMAr%h9 zh-Q{8Yw-M9XlUir)?L*;)#c0L`1V#suuO{K{GyOoRY5sF3enajDf?nAfqYLGTO@Pj zqsQVU*+_hI-ej4cBL!+8%u)v0^t*27(_%{Kit$N6>jL^N{V2o?JQhF*-Wu>mOJXJ4 zP=gFV_8wB-JqUmYPDB0yLVUauz6ESv-}U+QP|Hh&Q_GWz0}_Au!X|XPo^kMs2i*f7 zmPPKK>!{3^8qWU+bfYAT`iAGXxhSrt>*$SOD^39$N>9q!m~bLf!trAl=2|;gdmybQ zS)`I}Hi-V5CqBk_@>_n&i>2e$L1<1bWaR{LBhAxq*FQ4*t6LbP)tk(Re$q^yK;8r2 zbn3i@nGWG>YmBNZG){{%A(zgS5%A+j<8w`78UJibnW%G@!U{^ZuDy{pNj=blls6CwP~jhFz?= z=?yesdpZ(r$t7q)q#zbc&~w-GzbM#`G|t9BxU>Nm=>N@Q$klqxd6-Wi+RM|W+2ALd z0J5g)FNhga1DEnajTq8~5yP2xcfKi>HG}U4dYMkwONkRhrWC7HTkn0y`@u@<9TN2%c!i zW%IntC8aYJbWLH(r=VyhnRzG!fIiduuyZdz(y-6Ug z7|P7kz=WSH^jewjF=^e-7f*S)bUXBzM4Gy(&7xN@cPvDM6Y!;M!5Ax(XD&cT%FCB< zu*m_(m82{@h288;KLbgg%&N<8o5}(3%y%29ts*Fuc6!noCmIu6@^vHRe))ED;3wAIb~bou7u*}sCVIn7Wiznneg+!W7&(A>?8U$kLP_%2g1FuQe8bgJ)? z(2Zk3ywPtQjAxltVwiBw(CSM>pJztH>ciKK8TWQ9bB@7PI+QSA`_vvJVm9b zM>mPJ-GvLPaAGzL`&}P1Zj8U{OJLQZ^4rTEQLRz>#o8}yoHy#1y|j-CQp`O5)GRDV z+LEFJ6`XzXGk8XR6cK0#Pr{_~pA0@?d<>!#F`?{nU>L`Qm6RXp|86}qC1SV{qhx-& zuSK^b6gV0=?nxZAhqpW;XUL%P0rX1bmaCH88xO4%#}O@{ywTi2`O-MF-WuVTQ*>%b zcI_m}eMaEXz`q+EH01VW5QMHeUn2)gM)ke~I>RfN%V!-lms;8g*Alh}~YHl_(Z2vV6V*P;fm9OBDmNndMm z=4T1Ys6@G7%h-x~8@>eN_l>!@5KDMj_l|OrV|}ugD&Rlq>{KWX`Ek1JsuEocaAZDu zfQP|^*?^gfXNG{0N^0P|Z#Kp@KZoN3=#*AXhJz@n?Z{;d76T0pd2X12&3x;L+I9YQ zHu<{u)pxr;h{`wwL)}!QpBLsE7!o=o79hhN8pC;nC^`}`h#TF5)V;lQ;&cA?G=Nh4 zVfjaciU(sq@oC`dYSDL(1kyOqC2BR9(yk%VsqGD?vXW{l9*Y90`N$8kv9b7_r@687 z#+(_=QS;bx2yxAkDo({r(fC7Mo3WO^#a1K7v2#>ntay#7oG>CS^B8OC#v9fewmqB> z-;KybO3nN}HOY_F6`WLwAo~=go)v!^2||Tfrk!D^WwAz^$hYzw8711Dsvu4cst|gP zB8D5#naSlhnz5BI?BPre0o78AwZciY=V_+G*d@tZi}wpGnZit#ru)7BZ=veF6Rq7b?Q(TwuwxR4KK%10~u9( z(JrrVRv7m`bnPUOCNfe~ngL*h^?~o5F=?{s75>YHw%Le&ZGu}@?0G=%Rl2JQ-la9- zHmhSg{j|Gi{p#TB7_T^Q$L9xs_EjlgBjiT9=>QEx8KR|5J#@@Hbj*D?}_Rb=n zkX8sKtjMjVQG4mfVSVB~iqr1*(?{NQRW^=pbv}uO8^yI!ad>aB99)pOCtR&X+lWvVBmJ7X+f}Q_jGLGsCp`V?=VeRU_xm6d84Vdv`-yaw?FdX6J#>M{Vw)Oa z+>ZGimM;m>U!XS#1V^50_K9;8A``ao|G`frlq` z^kir7qCDlJ3?80|XtLSk((d{4?kSy$`_oCteK&W&+rTGviDfc@f8>%@(n!9(b{3+^ zuny{W6ZWIysA`rOT>Z+G3HUu9sfXF3(w4 z1|e$b0`5aMC&?uGC3kvRRFT6#PnC4|Dm9iAhvW1xZyI4*Ga+WlZ!fRETXNw^Oh<+$ zq-m2)s;uuFnaQwoS+8)@w30xD&_hd?St%+kWW`3~q=@E-!E}7)D&0N!DGa-@TRKYm z2V7xR6fEp~89Ev=5VtM`jjZnlc)CP|+{6{N;9uJ!E@})z6?-AjrtOY&MS1%k`w`Xb z2IFkH+Fu-bXu6jje5U5Scu^0=lGA?pKNNWTRh-HMR7enilUmHBpf)QA@^a2uC}+%J z(=kg0b?bk#qmt8%X^C%)v_60%1mk#%4UzUhi&!Uhc}@EqPAdZNd{mIS5q%UMLQ!sH z#jJv7O$NkH)C3}Jx;-abpPS@kygqR6v3ut7x?Od5`NO6EvvBZfb}->AcHndV%*Oqy z2eBV(bFb(qOfeFYX#BJ|ACrl}eZUaQE9$*Ynj~T}`qCF&bSNm4+kfbJMnoHk)^jnX z8~FT>C+XdXu3HnA(THwBKUQ?UNvt@*D|xn3vdCyBvmtjJ6B&H0O{~pk7%hIJu2NGU z4>^@K;~=sdr|u@58oRDSc_bS>K_h{tW`Q0rBJ+biFLk;#rU_A`8;}T#abZc=R4r1m z(jtp=Y1O-w+HQ~Hrj^>a6=8;-;#4qin9vP-^ORS! zpNK-ayH^q-9771q{(P@ITt@AvWr7$UvlAS`fJ0vm6LNNE`Nn!GS|7??;DCsC-DQuW zmim1kHV%BIH6`e1{G2we&v87Z{9{3edfM?P<<@S!x)jEyV(9c#Fs_dK!lL%Df*iS+~6(J5NyA!4XhdCD5rxxVUkv1e$G?xjZQdV z4h~mdrG8qT7s$gl-xHZFvLLapCzBzwU0S_38+I`reIXf4?s@%sci;hWbD-G#m)~~2 z?$b>zLXCx@j{n{7?UnS9JfX0PAP`-#rR^9Rec>Cr!LB`!T^;y9iT!e)oU@}5BLsZ(O zLlwuWVxwT`s*)<}aqJwL&ON;5mtdWyysgYmsneog;gqI!sj(EPn1z+k%f*93SOC45 z_2S5h#)XoMzXLF)=0_t8&brl}npau%x8!uG^#J%-V+nP?{GlPsb1?;Rn?Mjhc#h*I zkzz2%llj<$hh@%|w)SCDM;DdIvu=Rkfp1uB;K7==UsnY=%=6jARu4IuMgGJ#;ohfH zbMv9!`CCi&hKEI|yyykD6W7sZEI55<7%S8RRy}>8CA{R_FVpY}WbkBqNb z2GbWrc)#MN$H3)Il_2vsS03Fmso5XzL-Pbx3!9TdHM^qsfS2xD7A5*|I6>BR-A^z4 z>Fv`@@1>uym}q~Y!t?&VK;Pj zg=)wIm#mJ`Q0pZJ`ia)Rjv(PE0OR)pb~REjOi2|IZgtGb2A zL@mjl$yWB<)RaAwpM@Q=9MFjzk5ki3hV8-1Q}urZYgOtoO&#j?YA8{6jAMez^eggg6G90h>^sDd9gHxBUZPNHQ zGOhn^#%& zJQG&C=uMD|w0+Es$C``Qp|`oiD4pSMppyPKm&B=+*nY_utT5hOUMfZA!7YE#``(f)FXe6uf9UfbLkVxJtneNOVcsl5oC z>8X%z-DvnpN9lJcfQMYUKqjRQ|??`_o4Q zSt?=sV-<+fULL3FcTMO>4Tv#_Wq>|+BX^aanO+`h!J_%)NPI>bqk&1dW=G;*R6$iS zF@$`c=juJYeEmu%v~--B#V|$iJc(EK*LGo#-2T z`xH6__rKuiJ;CU08#zs)?DXQi@A+8v*1JK@4-N*HK0P82j!bRIDet((_)A;WEVa;7(vI{X<+X7|kcM-Y^`8Vd9MzOeXFKa> zludD^0?TrHQKJBJRmp5EYv2euX_%3o`n_eOA}&0GKMVF{Dt_sy;d{tFM{N3@vLXWo zU9rXrimsMFn3)rNXSvYg-2t_raw4t!u8(?;N|Sl)btJ9M<7-Z&>Uhfau<*86i*%q) z65olNl(kb6Z{+&c?qZH^ZsCc=ilnm!AI?LEY`^tJpvjBDd(&HsuDdy`yN7F{BRo-J z7Pn{LI4mU6&Yq~lEqt)km&h_uWO{pFNjB=;5X7|h5|Gu82(F1o*+EHTGi03fI7=wu zP|gwFSY`(M-ILjfk0uA6b@oTFia)eL+^j~Sn+V13^KqBWXX5jP)#%7-(-C3+sZUEs(HXXpCHL#p8(|wc4B5} zuWfvy8ue(XEjfD-);yw*4bMbl^-To2R8i8~X(dn{DL!(iN;?%=)t5wW8AobE@ffW0Mb5wTCz>_ErP=&K>hXwKYY23QVih360g{?B)rDfAzWSO~w8N@id*{o#%D z;Nf!T!HY6bw>)4{;vkY*fa^|`BPNm?rNcRaBMV9m*6o&n(*VdSH+X&6CHO|}X;?ev zE=<6zFXWLn5TGvh$kFpKN9NK#E0Ym-G|l;4SMK!mh zz+4NT1e6^v9T?=qkbC>{YjLL8a^jd6)5gH@Y+p%0P}lBp@*peX(>SDd>p*ZAEHt_b zy&x%t#VxVwO8WDH4el$YiA>kDf zos>+4VE6Ih99=mU9Oel^_=;o(^+q!kynRyXimBr>6(#4?A)Y_2JyzS8tmq;YE~M>o zww;(;a`q_*O=Gul=R;48$h^s-sp&1^@D;TUm5DPWl1udsg?bf~8&s6Oa?W}o6E#$F zvx%u6h|TlC6AiSb@X$Z#8=>ykAwX`1;_#3{r@Kl6ZfOug3N|p-x5Nyk*+`X3`N+v{ zBTD0!E;FGlLuHYSOvXQ)blG`6Zkh54u(eKQlk3I%N`F)p$TkJH4c&zM_V-!S6HdbM zzX}KPnI1m5t_6o!@`4y8h!g{Y@N?lIC1y4>RWP3Oq80|2Ks1S&aBZbOC|*eODpQo$ zlFw>7=+_Rz*?wZVxUXPyg$%$DHnj?=&6&vh6Pc;+x!ltqTeCiW(}Im3&_}wLCfZ=U zIrD_%;Co@J`97Hv&f32iDgT6olUS*9C)p6CrsrdklEJ4iBD2nw&wy1EG!dG?;V`Uj zqiPF?R2s%iW$dRs7EJW~iS2d|Pc%5>6q&W6>b<;YH~37^ngIAuIX&)V*@7wQ?<)e%hG86yL3s5TiH&PP*#T4r-rI)WT z59G_`HaAr0q@NnOi|kc5c1~(3l(D=~$T>q4Movo~q5G~Rmm)PpX@rYO-_L5s025*+ zC@lH1tACrp@_hk0QYM9w0K|0=05sw5-RI2=#^TMl69<~em}bFm3gE29FjY*Q+2t zLN(atvkG1_#Y>jB@qaqjp4m)?wkL9R0f%QK&bfoP#asrm!F~ua?+7+CtX4_)VVZ2k zYT#e4er?+K%d$Dbu^vOB`hfthlGME6oV9Y?txoJF?$P-+2GM4x&5N;N(d~9UYfRHU z5jbajzS-h%cOG*3*Z|iGNrShl0HFfVd(q%Cq*J*Z@x+KNe0c8%;~1E2E4{R%0Dkyo zx2xS*oO1dFYH&^E)JgS_b#*43Wnesgjf&Xos=t&=t*3A4R$c6dN5?ptSpwkyfIMII zkhYB?+{)U$Ni593sj6$TFauBDGxLFS1zHmOxq`nabuAah&`k8J#sQ()%&`^>VR11r zBsLYbN3BSX@8zekm(WxDBK0}U2c-~+_<4V;3pN&z0}_mR%G!0&N`=%@wn~eM1l|!? zZYRDVNG5dgco!P}4d1C8bQjFhtueu!Z?K>M?3Q(vePme>7y5JXHmVuE%y^4n9an zr@my~@8Qx(`MOB?NXEvd9oC~rapI>-z$}j7RCO!TyAP3zrG)OZC>Wf$#>fPtQQ-RQ z1)XU|u9Pz^=ikqVGl8h50jpMbdlGJEsb0@1^}h1xBF8!ctVielAf)yC7gaB@QW^sW@AQBaZvBo#|lLH_o) z&x6Vg;T@-pRwnS$1XY%b$9= zL^=FEuh2-WE^5JF_#V)vP&UUMgRCK;hi;R(_y@J#$w#(m1oNo73NZ%naaXEyzYRb@ z5GkHXFrfE(yl&G@cre=xycP0X(YE>b1pnLpW_mjiKS5-|eVODpLsTJaw-I-Q2yf|> zU%0ur%v4huYM)nt|L%WrxTgu+ z)|WuL(WB%Ny#=CnbFN>Hp#(lpP?OK|;~>pTMy@;Rlk(U!8M4(yzncyJ@p_96$PAqeZ znq;(8OUu_31v$}{V?}J=VMO`8fsZV4^Slm`>P;#yy`O^qq*$bpxHgeB)&F5Mp6^rf zOFA(_tGM`7FuWLjNT#WWs1oxduE!;>%AclbI!i~S-ZWZ9H($fq ziviiv6wXQmUwn^!zC}+Q!+&mHIkm}4zNgSH-z2eW8ILEurR3sL_WQa!&>7@P2xBDi z=AMyrL$QgiX{p?b-(_Op#ILgA6KLj^A*BbJ#8{CFLVR3n*_D1Q!>t~*anE5mV7Gg< zGOT%XL#DT?mXh+gWry{tFf9lGNG+E|$A$S9M@u#rJ?emkfRVh|I#Og3I|w43@sHt? z7P~ol2gf~?HIs^rqxAU|A~wq0gq7;;ZsuzQDSVrJHi8jr?PamfdQp)r`I*XZu9~sJ zH{@kfk%BWC8J0BgW>s{t=xuh=P!GFS_jn8doq4R13iVR_5#1IK-&JKI&+C z-I)?pYI{+PJTF%oIa048IKY^F6FA_(%^XPdIe3qyKDN@;;a^0~D0z}}n0ja*+8gNf zHMM~=nz~tMeDd@0r0>3Sg4umV+rVv5m#Zr}b>0-|f4V|6XBuo1IEvIsjoh#_>*GUH zvPA|*RjzO<%4Kp;P+_(~71?++pX>CGIN*J5KQBsKkhvrqILzm$LpORJ5ihwTCko@n zN0fYmNFl3ax1n+&eTl&5Y%2cl_;tK47(3*CiXL9R1EIHFL?SRAhjvN)W?~Kchl$|%EXHp0^!@~5t zKiP=^mZLw%kZTd9P6%8aM@J&qi}1iKf7hw2eWrcDjY#8QUQ{)dYyB5br~CTg8y0e2 zw~k{Y2pD5&%a}O~+s!a`fAB-E+gbkhIvRolIHRUC7e>uA6jWr$0AY+CBHAfg8?hJa zh3t18kh*cmOux$wQg+sH&~ZTAo>BBoGHkJZ`{hG>Qe3LbTiDM6NPc>GQEJ>{Xm;|j zG1f0cLD9JFUBwzvgmRz~^GL%ss<6tH!#KSJ5^9!5k*RhFfHs~k#g8n0!tF@7h1r!D zkS>=X1(AYY^DK!a_dXpowYv+VaRHw$LhfiX6k}(^JWT9~o8nR~4%B9ypdvnwVCF6Y+*lFn?ABJA0L-F#l^g9s4mzP?Y#aXU*HdNIVA268UCTt>Fj&`X}8pm^+vW- z_0#-!?re}mt{)q@dw3seP?KgmW;?VVokWZIIR8`^E$-J1cX|q?Z)u-@$GH-@e%vRm z-7;^K&Dp+Fm$*U&q?Apxx=aGCFJ=%@Ad3ger4QPw3cPQ|_V50iU98@h@BUn&@wwYN z>0}DN975}lroB;cMJ~zEX=lGP(a6Srt@ZerAoQ)MkArDu^UfXZE6iu}+w)EK*>(#? z)|26X-Q58&{qKdTB$d`8cI=iqTiwqpR|v~A#Up^j8mZHP0tff6^Qi7gVk1?ppUHif z(YNH<`M=*M^t2{{DKJKK42ZXnI3cI1}N_g2LXi+!JHoEY|!$Z*nPiEo>R@OMn!eR<@ozzj{z#}(fsxC5krhz9-mss2;& zsR%UI*PBC^rSPWMhnhK_=;V4W^T7sg1`~~sTl3aU6mHq;=a_KygN#zrh$g@8L0&LH z7*{#5`TjTEy1HfA8^iXwyQ;lB-Hp&c#`<+pif&~$i;s)qF8<(?x3QOmNHcb#b?Zdz z)}xJGfJq{_?XCBzw+9bkE`my>9<%#x8a>oSqMry|V%-1zw#fQz005x+`%6a$nN?XG zc%XDz{_&D=3fA06x$3bFKD`N0|77*h9YhQJ;{Oa34dlaTj_N~5q*o-eD@%NRdW6RA zkE`S{6}%(6Z%x=1)axdRr13jx%fZLafKlGFX?f1g-g^lNE+F7T za*-~L1GzBo)dUt-`_y0wC!FaWi1>V4wdlWqL{feLN+T64kZUJnx*HSW+IXU*1pr)o z3=^$YT%N!-R9WLGHo79+xSX0AL@8|RD?TkcO-+=Y zEc)86n@J*z{P!gEM-zwNhJ-e`Ll4PZ15Q3NgtQE)Qw(+Zv<4v^_$-E;{Uv>&2W;F* z6pddV*x~5t`h8t_`ttbv8gbnlAka77EbgD+N`ilfT|MeIl6Uz~(Hlr%fxmIa7=D;D zFba^;x3^2(OXHEz>%HLU2hfN^hWp)O^X1C7e)PD#9(@Ndf_POVp z`l?Jqz~2Q$3#|CfTG4wHpAOCEUA6;lranSHm{%oj>P=%i{VucozMb&n_#fJq>o7Jv ze*+5M%}q0_S6dloZq@l+5g-r)M$Ue4WlEGFnc9);schV!n=?m} z?0b%ym7@z%8EByOJ@>qk5JnbB`}-jDFU7KXj1J#QpsTYz*=nD~s+xu3uapUsN{s}Z zwKb=(L5>U+fn=>#h1&!GEN7R@v&pGwn_9C#_#^KKDT$>Hfpy+|(PC2T5=7t_MNXmr zlD{(sB0#d)yBotJxhv^)=U?CI7&xSn3wz@DHiJdSHQQp}6h`@gDUI6j#4+!?DlPu}*vKf=A{{Eg49@ zdUy^+k#tIbOGK$>Y>Ic@0ls3H4JxtK=b0)Cm{Bdr;jcsiU1+}2skB!^Ulv+GB^q`G zaiZ=`)kGF6g=#uQ4)qHqZR{1b;guMGKD*Dg92ZKInC|%H@m0aj%J|m-k7PF2uifbR z!TP75w=`i+9~gDPfM+x^-ztf zHDZ%;;T9gQRNNF|9)DQG*fYxK#`ry_#PO;1JyVS6D}K z-P1hPrKC(&?75xc7cIY+x37iTiZ+D{M6w1y^^$7i@7sIR?{9fxuR9IE`A@Bp8?uuHxmUBKhiuI<|xLoMXTQePFOd`%W zC=i?6KjdhjwM##7>=bT(^han{w`aa}GJSk&08D+qCff0+cd#G21ko!V@xjeKyd~ zL(@GAx7N4&`^3ThUf@yd`_F}bYz_mL+SK$w3#YicfsWll1=lTjKA3FP4|Y+`@$&v> zC>8YD(RxCvGrsMs7J+dU=q8!xw2eN{`qc=i;{`z|_QP!>9TsmZ+VG0930H7R0qa0c8Gksb?OMC3)jCpdnzBVk3z&&zwdLl`7jFL@Gvo zX(>SgcZ$j6xC+HG38?*xMlJ(QjBCG3y+j0!SOX=a;7KuG;GLFq6~0_p2KT{cRcukP z-m%)X&x3=R2v+%R?NVnM%BnMii)|HJuY_bT+{Q|M2S#Y}QZJ^{u7GS!$7>LFJ{Uez z<73D4o#Jhq^==hI-F{!HE;EB@zrAQB0LP<}875PPgo+IW3DuFn+jm8`@7xbLm)C7G zmoCI^{Upv-Y9watTfQwb=QNU6%<}Dh0YVvvbpD#6Sva^1PL3iZg_o|xGZX|juX--E z9DFTr9I<&%Hx9z9{^QD+vY^0^=5(bYAQY?Zav=P)jsF*VUa!Jy7$<2JT%{qs6OxjdKfW|n`nVGakpu!_US zJ(21!v({v2tjrB#mVd9(5(d{mVp;IqZvXCoe}hD^-Vj_B-t5Q*R{GYk4F1i40JGp@>zLqUvpR$_9fFmx7)Z4SC}w)i z!4_9ioirXx5A%Q+EK&*zR+0;dO9h{5g%QVJT$Do!_e<@SEf@DO3t`ECP!2_lnsEU^ zhok2~_0qct^*^%djQKLo3uyB|%A}u zoG8}Tpih5RXD*5>{kTNG09=bsH-3Jylzvws2vw`Ou3MpMj;O5}ap`E~q}1s8q1J40 zD?*pkw-~|0d3-&4{`|=N(CcCVq3tLWMwMGMLTYsi&Fx4)76jvtX*sAe+J(%-*TYk}*;kNBk7bfrkMM38ZlEb$7iZ46MeB(uTQgM9E zsA&C>DT;qpw(KKw8cXysd7^kTtYtl0GQr$r%xlf4w$oeUuooMV3ho|CcZ{0V?f1;n zegxvZ3U73!SV*qa|MAIDnWlUoc>ur1N}2^zhVIR$3~|MFhi>_E;}juGOKZj>0WjCX z23254beZ|y)tb85aHDz_0mI_}5Sxmt*#5CDYM@-b5QWYvxfubrvL?x|RMB^<{KVFr z&ap6a7>EoSaociDVpRNB+(z_q;qc(q1?_M0draW>w?fDegzpDn)V$m=iR-m1Xyfsl zmb^eD`^VP9K5uGIQOYc<2^?kQDgHl%5+)K@R`g?Vqvc;Z1rl+chGfl*k zbbX0~KXo24+NKHnJ4l;bsQD1oqQ)6UN>>teWexKwh5cYr%*%-l%k@UA$_@D@pVJBUcN!pYN=1KSgmY>I zZGu}$zBJ02piMGH!0WwQwmSWbzHonrEMs9!El(lKf6u8L(EX9wH2>120~a{2w;v#a z=&D!vxF}2dpoYuh-&^azD*-4ELZF^;Bs62n$f=cS;$Plu`D&YII0$iFS<=<;KwY?5 z#ok+&Q~ZL;(=33y#x=%gcV7eliffQuCmzzb-@&6-AnL#pFyBLbod?3a9GT=8jO9$Y}7Y(f^4fs>6r{CK+sfnPuSVZ1{|&O z>1!+`ucS7;cXz8^@AQK|4niR$}?5{?Oc*y2rmc)_T|?^J4&wjD^AMB{5tuz_-R7$go->IL(d1;C}NG(PN9i zg!XnkNRZ%fe?!6uECX%SVk<>u1t#z6)*JWfx)&EX9WzCqb6^4Pms8$@^w=v+o#Qc1Y&xNU}xQ?4E3sQrrn(X6kF zRk##LVLOMh6wO-`XaDu%>`iUmDgj#c?bPElLhzN$;(hXPrPB1}rVjJjYRDLbaIorn z*fDRkN!D?Wu|IK8=&Cq!*Jz{5&hY>wLpifz7yZ%aey7#J^}>@-Bhih` zzD$~DZrIYvt?Q*7!$goS-#=FAdJgP;q!gyu5oJcdFaeH}iHp%=YK?qzBB?5ibZ?4t zX1bAd8!Ct?jTI2_pHY0Z+%xaKV?Os?F8)XQm@x!m(aq{*LwB6An=WB z`%FaEJDrKzhoTp|ZBBP9J`3A)XvB?hP8mie!IKp{;q_B2$6SbQ?@L%E&6NGpxW&57 zlYg^f^%YzyC``ewua>M(gG8M&Y@plUj1k#K=)2kj;UuKuv~0JD&VB3s`=;tZay#?ZnIlq<!F61cuQ~9C#`>ist#|{DsL->rO_iX3Jc!ilemgD(2qe0MGyrL zuSh!*M=V~iL2HxuADv?lbRC8HX?#_KROb|50vQqC{efl+}^=~$&j>UHG8S^ z5n&{rc(69gFei2}Fo`5bj=aa~6II$p)}-ZD%3thlL)4yI5l-_e=S;H8j=H4Ufe5Pr{t|8YL+Bmg~<0;1AO!dNK33`@>G5S9(`P zAN)?Ee&it@7c(5L=wg&PL7dop-Sp5X>nmA_WJ zfB6T^q?LK+xRZltE~o};nNZIEX_C5hG)HaGjl4eptl||jxaol}^?)y(4G4&q_YMM? z!B;Iyq(7e;Vs|ISr`v^%ayo9EsMsOmVF&t>48jz#XDqb>?9?4aJWhip|J7EcN&D&9 z%%ZlGNm5Fk=o;GdZR&p)jRL$rZgfQYIDdvSwN{!1O}em?uDOcGD68aOv65+aD}1 z0caM$icDxpTSYF~OS{)>?p+Wuso{#lQsuPYp&$0>{{#O(0KY+udB~;4;MrA0VV=V* z?_CD`tQ&>e6S}Sfi=}HaFT1^ykeCBwIttwcPclrZgA#UkMd;|;Srd?K|4rqp)X!O# zN!xpQG6ytN8-ms+)4Wm>;I!&Nb>dEa4`~9_mS!d^CCHd zBwov8jcQbkDJC4-)P9|suKJ_s8qgF(XW7?6J^%vBp0yoY984Rg@Lh&Mlr=JQiTJ5% z_jbRBOI^rtzG(oDUmD@yIK<&B!o!6SDlE%un|l^>jH=UbFAju+n1{Sk7W|R@9q4(A zt;z?G@DiqB;DLdU>yrRkUdV!kW|gp@ZY)X`6WHB>9QZmdU}c(Hn!%=f8_tvsTvu(A z^8yyrp_>e8g9(UxHx;FPtzZ*ktBgT4OFCOUnS`T)nhS70aF&u`r#;&yc=dCe@YSrt zvwHqtE8-_@Zk^<(kLG?;>hD?bQAeHSw{CM=TkWs44dDZz6Oia6WX23!8hGM( zy}ZCq6>g`qIS$65DEk#A@Y%L>3LY;ad9pW9rwZ2^K$eSaz}-52N=JIn!W0jWe0VmK zp8qfv<-sqGwnUYnAeME==-4m-IGjbol+fyfGEZXyo4Dlt~*0)aSR#2^H_c+;JIRg+@t2;Z~ktr zEvj3K3GOHC_ezL=UBsm*N*o<6)=K`inP@e%#^y#IlJfU*_Nm*2+cZea0t{mNon7cZGT1y&J40eibBPwxspF{86Vx zod~aal7Uxk)6;F@PZkqwkM>rs*Jl>y^3-BFbcassR;vV4Ik1ZZw;_lDVY)xE>!9lh zlYNmSLIW@i19^3B_^r8(fg{X-$1iPR7ADdOsFnpQ3=2TLw-^vip)f2QFT`2oahl`u zt}mSuQ7npg-n==%^ym-(HfjR$v%;a*nF41GU(xfYfu(E09LTuL6WCMs53~`pjj;Di z^zHogbxdX5_-rEw&kWf28H7-aO%SmYkyBDnyRZk93J2<4how&GzpHKh^pDzLwt?UL z-4JmY!||L(%%2jQ)Kc8{TNvc5*_P{U{?l-Px3q!NBsp+z4RcepOC|DTAxyf_#eIw_ zM>-&E`L6HdXgb4QbpYuF+r-ef5ND-y?9mqBx&~+7C=2%Jg&w|fFhvk?sf~9XA8w}) z)6nZgAo2rno*>~2OKwPM@4KvWF67wTa!?pnmGo2K4SQWgS&l82VUp^&c_eZOE)H#6 z-d)YPw`?01FAiXu=Gp{|brX2n$tw2)n>hNahS4rNE{ctwW%JOc&uzF@p1?Y0()Ix) zjU=5KvDNV0X%4|?o+FBdDWH}HSAp7~!$~a1L=xxd53sQkF;8-tFYpJST+RDeBLSNj z>#Kz{Nj9qeK#dEhX_qRTWm8bwL|uokZ5+3|1N3{HwFPZCPcYid>rW_CKba87oMVN>LqFI5sLf;^kx zR3 zHG)zeBI-aM4F(7;e5b0+6(*2pa8UgJa27R6e}yR*S-qZ(Ws>1LUpK@&pTR#oF{8XdOkCW!T>z-V+h;cWdyyo@>{@*Gh)fEzbf< zJz2XsXPp-CXJ3v0bSuU}&blsw*`zKwViX8MfruY`hmJJK8>PU`$^<_AM2b)RjV+y; z>(YP$G!EZbcT!I~hhW`Ww26P6&3``*<$E!Qb?;UoElTKE@9-nySJ$5UOQ$10dZFL& zqm36LxBqwn8EpfE_n#8=OhcEMxSqx2S%E{}!rwf5gkjggW4-gDzncagL>xgRQh+J6 z=U9eJH6-vX-e3r%ihSc>isx?6(09%1h%u4XL>!&eo&EixGzZk^z&aosZk^O_bKTdP z34~FKgM+a=k5E2yk4-?pdZ*P{!;5W++1ct<$v{P;8jrdycaz$$Y6Ee&>cL;0%%Op5 z4+4ORBp1Z`sjrE3`~P@**BDvS^E~Y7x>t2|_ssO1IcLw=vo~tJaw0{y!~$VKq$7$9 zvl2ym$%L>eScvS%LL`L{W67a`$bTe=HY76&6gd~c2BatqNP^;01S67>#6++n0-_=W zGP0($yWHJ#cy`X2OLte-y{hx$tM{w7zW%DZ=PcnD7|cvhUuvrAd%yScywCI2@9e%N zjm<4OIbgd$_=9gN@tH4nslDWLA2PC1qlbMLKYib|S?s!ph9ZP~0Hg+VcYf_X(`=S6 z++D!;Y<$OK2U4+X8J7(ju1x$j}>0HyNw(z%SuXv$)mO`7nbEp)*g#} zr+k7Vk&3F4#lI)7jd6b=Lz%=@0%zyB0&5df?$g*7O1N1R5(LJL30?=Xo*|qp} zj6U@HF47L5y}wkz55MR5dn?YtcLx%Yo9b}8KnYeQI4#taT;Y<#JLRpNr4*> z#rV({sd*GdvI{^3LfaIPedt?VWgzMTkfnJg#|=GuBo{EX4*&ryAl(1=efv}R^Ox@m zEr5oNmKBI>UlgDhjM|&Lc?s1Si27@Nxx{8vBCAZP5~Nz57D!_g zqgtpE0g!+}og;YvyDWV2bNUFNkGW@;m4y(B<;=ZTC7ao|yQGT}b-6x)fch5y(DkpX zN-q3weq<(yKN@fzZK}6U4)B$)-ov9u0q!l5&LXc(2a9+qQv@0gBC|~sV_)36765E4 z2dKKh5H28?RW)qW><|z}4Gqx?Uti$KYp+Wj007A!xJpFej z002!&pi(mHOsx$JLoc_%NBsFzZ_pKzNPB?N0p8lvfrmH=i2B%&(N4#KKr{=$fk0%G zhpPY`g6-1d^t(!3t&aP)9E9RpWM+jZuJ8w6sqywVw~JdK5i@X|z@fn)b=s2d1M0N! zLg0{ih_2wr>qJ8se&vX^?up*d+|dr?7y#8~(=iSY#J#f5^*@?;IE^x#HV4Z;x;{94r-jMQH7mLM18x2f2(XW3dh*MxeAwOywl|WG z*yPp1?_=>YFOeEyHx4T6w}WR~f{3&yZaW9thLQ2@}&y7T{?pG!WNrTe?9?;zrx|Cs8WTAex?DL<@C8k6*^*%986TWT2vRsJ-99tFE4L!LS1vc=l zH^t^UpLjT#PZ4LOoXa5|z$Z>7xHTU)9D=S)?d?s`5`t_j2S;`y#0Q#VaZLlTExDM( zFvMY;BXBMFwkb(M1INN;QX z+Fj@_-Oj(XK84u>30=8q!YJL!(rRDv1-(NISwEz^mJgAnZSaFO+FeR z2i-O`=j9QBDppFV0M{iT+Y~OFQ*r7|Izw2)paEy&e0ip;`-ac%ianTiUEfZ<6kqq4=A7E6iASfRL zUdE-Q_=~f)Lq`#S1psxH;IyPRU`yXEs*5xVd>>I#VwIK>gM4c~#*6U^v%u{D4_-Tu z;jKpa;_24`KvIDnX{yD5KG(Z;O+0pbde++=*k=@TAKNu()G6*L=q{oiCjpW^8yb1- z8+xI(nHrkYPE5cY!T&A!S$OGwgp+V4ML{e}gzvU#;`VXS zkshX9o`w)O8_C48P*fG3d1Qu{??;$5A`)MF5aGK9PkYzs#GL|LPC(7?`iglv_Ez2E z?%N6Y=k?8l=UE{chj~q4-y+sk+F*nOD2uuS1>R>CfSX}dJ3m(iB2i6Xv{?@F643C_ z5HV;U#$RVVU)D)=$-fOagnj$=`@C)_&jNpsHh7O%6~t?J3JNAH5=qA92lwx33x1YmY&{0(p}A_ONT=Pm5AI)G{B<6|aKydJ!~T6tHw5K3U( zQ!$-3WKoDGoKC9}w1^!9x7%(VSMvr0&~FjvxK8J#{RcBCLqv1OQIa9_Exh_b^!P2y zL|F>1u~vbk!vA;oLjFwY08J{9m&&3`sXVmH)SHsm1gNN@a|Aqp<0PWH2t{F-ysH9_TeE=7r)MQ z6lt{cukyIV*$?Pt;>mP7c3%XbrUW{tVU`I>xV;gE>{w-DgL>le`5U_aqcVr@*+|j? z=avgjq;sB%Xkb3^q&@&g?cO<0kQSRZ*JtfNir%R+AZq|*E)()B%Sw$drjc@>l>jPybnMZ&Y z2?(@YfFks_5a%KdAlNSe$w)%Bh?UoGt{%#&=DH3}PUgKe0i6?|i#V}`L&{(c7LL@O zt{NHaiYDl>mtH-?(QK;C0sEAOhKw)D@xc_1Cl(|J0ddoX{QPk*@Or7abZSdH1^C-P zbbyV~b{K?wS<~ft2tm-H4S^Ov5BK*O4(r2$^ufn9H-Y}3FKCleX|0|Ey?qx}FHdjAFoV2*?X;5dMJ z=-|$I0?!^HD#i5CIx9LbV5<1fCysCiG>O#Y{Q$Nk#YWy#))*ef=q6DkfgvXVv=^|l zn%!xSK_Z!e2xPE zhS7lS-x3MPQCo3CwCKVdjG9x_(E}V<{8R_{#Aj>RwmH}Z03iGP=Zhr_bZ7a8hI#sm zy4en;5}gz0pR=pr_vno&j<4O&syhMLy8b$?N#74)85F(!F1Yu)R!KjJAYVRfU>Ibn;(zi1>R0tFhclU zUMyf>82;V&SfBAoV&^gMSo{DmIXc13n=_2Vu!H#2rMmq3lM~Rv!$}$FHpWtkyL><%Ru04YgC`NoX{4@*;s ze|UZXqsk>4@H01s3=!uCTqH$r3b2cKle{M1A*ss#_~SP2+&KrJ?+kQlmRkUij^%aN zRG7LW4Bd!)z=%tcUAq?c)<9GaJHAMCd3g|S@A90XcbBaeD=lXqH^K_k^#;$q(}pM- zf0t>x-TaFT5(X} z7}8>cWW5l_$`3%2c2+geV1@y7B*LOZO#3ZjK?)*1R44*}^CLCRa|6pbZB&7)t(M`w zMvj5JrYfZkwCqCE7v5#EWvA@oyVQWLYHB`76k`Cits#{JqbLfz`)wN~q~`y7pj~7# z?=ONadT{z1z2^tsx6jZ}#d`S-M42sq^%&^)G!`=>R2Sfj-?r_YIsf@$*&*xP#q+3h z(A;!XbNeiQolyaLe0&{`Hj5wVE_xk$kruxCzw1O|C?cozc;vO4@KYxuN+4MtL30AK#g`*`Xkgl(Ewr6tO;!eQvbvqz{6uf+kFrim;Q2NC){(Bv8yQ6>uy zGzc^g9mzo^Gyv%aiE%d(q#&!b#Kf~?S77Gb70HGL^x^xt8j#NR z9Wx&KTmTL2_*9}C0e$5?jZ-Ac8vgX*3Tw33``Cc4V(M;BxxBjAb(Y2ne*259jv4*Ku8(oJ{cA zy(QKUULS-FUqz1Wsz4!N`$ko7veVNu7@HK6*+hodIswqj%N$9=_iw~)m7Rk$I`fvpFcFJ3;@sno+;A|o=&J_phL9XfL=qA+dc@thjrdt@9Wxl^7i~n zE#9k|kOvn%|C>`Wgg5isX+F;$A%)oi1px#Is_@kH3GQ8{IG*@e#%+;4t70DglN#HLp4;=kw|$Ii zq`<*HoVL63oSyJ}U(nW&16H56&wB^H^M)5cpug93_cN^(aso8bb-GGBGdh4^3wo-- z_LgM@qiR!g+cXvn7P8t6usb*8>o z-}|@x68hs0d}l90*oQS86}r>#0gSB*R7Vee3yY+?_@BByfo*ov@i;FV6kslO18mdi z-~^^>7hn}dIP#i4q-jXN0RRajq;O&xiw{`WCQdJf_YT7l7poX^pph#QK!rz-0$fBH ze5*_ItUC#+4e{s=(P%rai`%#7y}Jt_aye@tr5Ktl9I{>0hsvi&Cq+(xX8yCRgzH+3 z69CF0+shGf9)JEjJ(d*(Rx5O#L$4J>2PK{zx`%o;D0RW*`woA6=hB$}r62ehDxp%ZS|B4h)$wFfNMmZXhj zTnO@Exdpm1W&7;d1@Z!j7UwWapN-pEa9vHWy{J(ZnU)TWKSzAm)dmXrcl9|#@5vp- z7yh^aP++vN5FTt7TlvD*L5=Hr(^>q1uOEQY{mhkxb=HR$pzEnpppiMoNK0FyE`Hw+ zK`uh&d8Eg7*;Smxx->EKfORRN^s*FUp|)uvEd)cbwMg;kk!S&)MLFi7)5-mXq#tAP zZg2wt+7zHLJ)}{D%wwT^({5V8oM@Lz8`gD!4ASP;#^+? z=(E1o-@azq4j#RI4EMe#`|xC31r}&;j;k(yepBwcLHXwZVrOz}3pqkOI6ud#FcJ6; zOaTAt{}snU48UZrS!snq)W35kU;2IMbwDLw!=EQ26LAcqjRnGvwS0lC^(}t7-dwFm zZSxH=^s2Vcc_!02bk#xR^=7NZIGc{~=)3gW1?eI6K1na*5g4Ql{_h9jJEt zI}>=_>vh0r<6|=_-!wy?I%G{9{%eVKR4Q# zba;NpSE(WRw%PCjRzMia$efJ2YgFtzJzL_zD#3%5NYRB;5Dp+sVt9Ulr*8|i zpl!z6%0OfUJ0whh%1(@Di;K!V3oY`;j>UYq5DgW&fkYs3wn}jstx?vs7W>SNXp$dR zVW-b#Q@g`B>`snaN6?%Gf}ZxZjrh*9Pq^PcxBDKzHqM+h5sECw0xd`X`f`cUMmPb= zxB1Uxy2tvA(|)U_zK3qXll4J~byQ^@U>_dbN6O4+UQ_w8eS zn-4hxUX!|tC5d3w_C1>o1UV9vN4Y(v=Zp9OfObN#sA?EhJ0^U#$`LnnJ5(5~4X>>M zlx2qVRVwEJvdV1OMRFMl@DCuw(by2;Af6v!xlVBJGDT6vk`Uyji$Zo5_({_VVDOXI zce3AzQ!tE?R9{^vf8$&M9Q8L81(01O`?=`&)B%Wh}Jn=pQd+d@!vU5a6F0H8h~ZF@NLS0UEFOX zqX~sXg#=z$xOH*>*Q!OuF)ncm;N{bm#0`YLg_~8BOXuwX03ZNKL_t)IXC9g1!79N) zIL6eozv0?>WICOBZd82ag+U#~*gn<&zQWYLa|F6k)rs9YfjW<*69{KVn1*(zOR%r0 zG+wlDRn*}=@54=3+*6CYWszeYMY7QeFHy3?=u8^ z3tR)f?@M{`RTM!ec8QJjv}xP6SO7!L>5$snEN~7}PvR*Z)_m$9>_y`gdKVP!xq0rYh#uOIZ|j9ls?cT zs;PC3zP>*Hnc%%~lFOEBS=OlOwe0=&ZTIO+Jr}z=IkhqB%!FKpyi;d=Y|gu0)7J@$ zv({l9dBBkuV&>ao!8=6*3To4F4!Wb^JwQzCF5wQ<2^Y#Q!S^L5P9m>1&}x z1eRrmMN-Im0Feyv%72`fn2%iqjwO4JoFN#1tN{d$xwWWu;Zk2H)%UuGK^CfoLDl-I z)4Oiap=d$(d)Fa|9g13GrG0?BDDhyKh#+T}oX4)todi*2pGeHXv3;M^zr$~Px!Wp8a{8U-mpL;zF+ zXjA6`4e<}gR)xbblu-Ry!^}Mk+JYb;Ao)bfF9`<-ws+*$0Z5%|6j$2Mg|4wzdo{W$A>C!;9+ZeTTS zdjNLqJdvovuoa~1AsdLZoFu8Rlb0}p(5SmL+wH;VsSmfUA%MZP1pyh0=9eC zyBsqi;pqKJ_8PwUx%Kt!`Twqa&Q<8x)Yp;q5qk6qcF@ngh}D5}se6vqq{*de?A^Am z*Oy!Lc_aX`E?bcgVg$BLQ!emZa~B%rcc~q4GM~aWAGF5`Kvw^cJi;3n9Z^qS03`8& z+VFrnmGj0xyYPAVPeVm{CLBedfTs3DYIdHh?s~o-O0wEM`0$Vu;C9tr2+*eh{B^s? zF1V2%;R%Lm$FEw2R#U68$gwKUwdcAIoTa1fE*Yj`7bZgAUe(u3$cE_L<=-1F%eLi< zy=c4pD*U@1`$kw^j~WVnuOS7g(9m(<$-}lqe;B%0r6LUg#9EtAoQ_HtZQKOUC+om8uOD1o z=90FXj#d4ChB*1vpZ6^U4n+icy^+TwpZ{-RmY+;Lzv{UiI-gF%xSXT~9zS-$#1=bt z`#2Ci{;X_j0;1~AS-5yAei3Czi&(Df4j%v@s{b@>Ky$+?_W0IZ_7BbWm!W#yWhygKU6R1d%nuNOvjODZM;s;$qW}q6S4bK=uZW~^R&PsDddFh?c+cS z^{i5&>&q~oII>0%xUEy5C_sw@B=*snFBnHBo+UqM;#pW{V)uXbL5#+7tL@o0_SqqFn7Zl?_hh<^XfhwK8-;->;V75W0#lJ&c^*x+o{9v?*r zWVUH;rvR-GfjDtlSqZ3NLq=$uCepmZs}Ew_TO@epJi;WxP4D7W|E}`qWm(?Qm?!MD`g(4C7mvU1(QLY!n|$X|!+zTN`=q#cnQqrt&yOyu>iZj+Zt>GS z@C$OuBrxjp2Sn=}IllrMOWiHT?7 zY}LMa=G#*BmkNKp=U-G6USAONZiU)&;nq2#I7gl($kOdTG+&&%JSd$o-RsC`@vEX2 z+;(x<0YKnmFBPI8<(aN^hluDHxeevM>T`*Eu*?dao}MA_^@Tw$Fe>x}yw1-m8L0{q zqT|i7Tpqs~_H(<+R3CqT^|8J*NjK-;$KS7$>gq%0>GJf4v7yvpp9P;*8;Q&Dy++J4 zEpeW<48iLrGNoMpc;aIkSa^Mr;@T{b&f$2{vOQ4;?|9;45$D|$K#C7q0&hH@c<}5I zW`QHy4Aa1p)yHXINdS;*jSx5`9+}x#7aPG5kQ=Zp69?`HNm8S-JlLB8t2FJX+vrSp z7y-rzfcX5ocNaJ~6xaqewUYloV**zl!4N!{x9Tn~Qd~5gi&702nN;3UMN)QQ zA^K32oV&k|$KSFHF~N!L#ZN3glj+f3t!6-9th=i5=yT|^dTqmY=LP~ygdj&AI?~{_ z=Soh%2P?7Z-d~86pr|Umd@6SDCr&2v_ruVYh(Lg~0SR-wE&(7#R#sAq2oMY;q(buI z>nj{jd^~m(N^i6-Hdw6^)P{rGvk{Uc!7{1wpZvs|P+E-BuF7<*Ke)_1;Fc=@vizjlWi%CL|;60b?`9 z?692|pd0#!-d>^1bm!iMxF(bz>#xtpp3kt13S6At6UXIl-^kn%>@xNL>O=aGsSbmF z*HMLYB9C2NAYM4;grz_Dwth9Bhqcdq(Yo?zFsT8PJeWLgi`0Ki+3LGBcQJNtsmTGL zqb0aV5*&uEm?{hz6c_+}&u;j~On8o<1%LD?kfFV8ZqpE-CN&J!TTGG!Uq4F_H-*DA zj*%=A_)}jlW&l@P&{t%z9g?Dc@3Uf2?&AnJ+*UdPr7)NmrR0(0_;Nl~DF2U#n15Fn z`%t(m2Z-_rNe2AA4|Ih;bV4FmF(C=&0{A8Xz%T#WE2#5Ez8fKc5;+8G?ZmE-mE;Ka zWARac28I!Vxh$k@@BEx-Rjt_5&aQSj$|9GGUYskYl-+ag)O&N+X2qS#XTI3HhvEo| zs+P#yu~lJRnjLwt`H=(LG!Z2kifV+k*r2E?$p-WwO67piVJJ|$B;hx2z(vOsf4d7n z;YL=9kwecONdSQ;I?xp05dzmhn#3@w90$H7)qnsXoJcU7tMIYsv);iNUU(!$mnU!Ay#gdUneu(ciFLns{trz7j4ys#gn-zU zf98WvYTt*S3pzJ%#3}srk3R+g_{c~90(JxJDzY55>qv*td@@uXzJ2QheGWlI8j|sy ze@#A+09CiI?n)W8;Mpld@>rOrq_2>`rc z*x9}39W_4nyY1)K^#)~`At@@^`=`afE={pXS2bKqs0Gb@vA#$q9DoGtQ73@&0*a|# z1LLL;C5M4TAR@4{@G2HyWJ@tlu6-!3k?;rdjFh8Tx+DmGLk+!xcn3(L-T z{UXcpb07YzgYQSCJ0E>F_pWoN+J`^%Cj7!L{blE|yeQ$K+Nulm@dD^ft$pMTg_nFU z*T&d&)+wux<8@UqMV4j^nLiEcp@5V9zj;GP#> zUtvCRB&(=x8u)A9bPZqri~Cru5-gjN_O)q%`^y+(&y=*(d0N2nY-DMLB(30kCPr2y z(*kjlA9CuiN;}Fm0Hk`2VF+2RU7q;;@3J~h0O$fXfbML9WEbk89UnYiO)p#L6!_ww z*bN&f6!{2trPtUis{rb8jq(Iysv2~3*fr(vVRhU>6CMLEh4sxU(b)NcA zl{)qwoiilC4nRLi%JCgMx}bVcd(Y)Pzc=sIoHKsD`ZN^cC=v=ukvNC@oWJMZxxvSt zXZ0mH5762op=sT!ng6GSUCEh$0P^Q2P9~jUJO#7lgr}Bj8RzSCQrgCC7Dfv{I zv5F!9p>&!v-$qu|c=>)Ll)F6_wrMcp9s_}ENswMq)$(tgGz0*wqN2i*_=jeJgLNsM z^u);oi#W%fvo)SLnRF)qi1mkTY>#l`z=e$|E*ezefkQ$NjDjfx*2v+ymUIS=S72k< z7}XX0sVOw?uv_PTQ@E&VadDC~L6%m?Q=z28`R^^;Xf8;Bg98WtR73>2R6!RBa8MC% z;|ysJh;ypvpd-6#EnqV$QRl*=|Lh09iG}ZJ@51CEYaEFlaT?d18<=ihe$D_$tpGZA zu4f_$O@xPGC(i}C=kOo?h4cC2hq)7h0tpF-0{W# zTc7H(Npi~eg5g`<{${&#kGr;w$wA$51j6}jf9@-P@_zi(PyMO&?)Hzk)*2gQ zBhx})I8UeZ1_1xdC&anu6z${yNOM7T0%WdhVH~({JR7qkd#`i%jvx3OY{$a4KQ@II zh;)-cKs1@lnYy_6$1^vl_+S6{F241qF9|~EHGoL%k0(C<>;LUf+7y6TfyY*blf#(| z{|Wm~GGRsKBF;+OIyr(-r||p$)1d5-ggDI&ewtJmdnVR!gjRrW!*-p{i7Jb_Qz#^b zqN(Um?c9S7*|;$_7}X=x*dUD) ztuU&3zJB|Q?QwPW8Q5_tf-9pU$EW@eaj!o6J?&?RNGrgo7Hx6$-sASWzw=J~z~B4= zUS8BVs++=K(@rID-bIv2pbr`4_TPHb$5YpZ<9PK!+~|7>v>dleqB7jZdVq|CXyUxPd5rA_n(GAN!|3?Mh{${(AjsPCKpv4QQJLr4fQR6eer~MeM zsT5;Ci`ma1IPizSEwt#(GC^FJ$cr}L2Y~ zq;V@>E}`&;DV8XTQfso>g$zc@j#` z(H1s_gXL}=Itaay-02Ao=r-q;L-UCo6c7>l@x<@c?q-40S%b7;8$de=NW1>g#KU~z zAxcU)ZfKhZ;;fW!I5sND3Al)JT%S(_;o!taZ8(TFHu9o?W7{Y#QKYD<4W^+zC{eXB zG9=3iRjp^95qW=%GOIclj{|y$N_##Z!*(4BTcv0q%Sx={3|U&?{4^2^=?ZPHA%W9t z*FwyuX-*;eH;zsd(PdWo~1X)%hD~hI@lW5yuK$AZ=UqANu zZpg=7wAFw5lE*rb8l0TWJ7GW7U^vQeX!oa@$3E)EyNpCz$SH8zcDmO#EIs+`ABuC7 zXBE~_j@2qgmR5)(QJ2wyh03hLI;{|;nJmr&0s1&}t0x}{(8Y3ihU{X}@Z80SD^zCCg6*wQ0qR<9sRe+rB zc&0hRXk+bk0)RdO;D4hpFYw?69&B4sXHRA#VhLwQ^0TI)-EjhWRw2tuT%1SEg@}>H zMdzlauXnyB#yS#wcl5QZF7W8>W1O7KJCCWwK;Q50jjsy*x#791YU)l#zyJJ4UXYL3 zt|QL{{Y;L5zQ`ev6W~TpfTwMBz3Dhm{++(~|CGVihX1@ps2cJ2^__R_23z>1p0H$cYiXv*ZBL752grbM+j#}xOwY3Zr-|%zW^v<(f#!8V{lZ@p_H(Q~-hi;4BjGe9P*Rg=SUV(E$KN2S9um zD8faYb(Fp>K+FLELXC863H~v9Nant|5w@6T%4qm!1B*5lqi-KcUj0}7B z2v1-0V3xpiYQsCcE>GC{a*1gO5LwtR$!l&D`coRfb84CZoXjSjP@9T_WPk9L8gGBI zi7YFzTEzeY7)FB7Wn-f(B6#n!z$ZT29Y)zD{-9$V<}AZ%zArWEVIo_J<4p>2qyFrV z-2?^zYaH6ELVVSs9h%@H>NKq8Ei~_i2MFA(Z;RObgW!1rQSf;|N zYZ|gMK$w6bdl=eoK(uDnX}ry-M4q+_UWDGQ=^*2D{%AQMGrp2sLyzIfz8LJU1eFat$NiPslthfvTp#Vml(|I1`Pv05c4EAjKSz`~

7& z(Rr+JQJLLbv#e5iqI9M@fzih5q#e8-AamMfB13=Go_ptJixp>=QB6Qi2jnp}3y+K! z`~aXX#Q&EtkPhYCx{$xGpfwx&a(EAK^(=1E+V9{xIdSLfkm9dbHp@mSyo8%3T0WzRDd?<(6?Yzd4~{0 zK==h`z{{sA#94_u=ZUBrkS+iqkbsM{loa7b)j9yq4h#rq5I7bv0bXCE2pkLdE>pba zTOP%qzIYE$TnptG;*;}+c;fOtd~1YdRKTcKSVl#2v-?{pD&G@rK*$Zh{n<2vPJwW> zh~*+5A{!y6vk7ha+0+@JC?H8qj4mRChoRO9{NURJK0uuml*iqp9&_!QU>H)ziTjLp z{~!Orqw=whvB9S9-dwr`uM7YCY6{}B`kq8FT zC@Ces|Emv#$_OEi%Cf?%XEFZlYv*|3wFgX%MD!`|$EBDNFig0vCwKiJbz5B&K&EyF z_R+cP3&+TK6tF3WTSI)Jj2r>aJ87rlyOr;U7>6OAygl!*3#%b-=W~iw?pQz@YH!N@ zfJwB-`i!CvH3}i4T7hqGWF$iN8_##4zEsR2q~X3+WV!qzyK!xd*|eo{<3u33nFZZ$ zO8^~?)C1bz=(1?%=Z+xTm@vvU>Z-spDquEx_kG6e0B^)P#hXBc zhN3e7WM(CC2mrcKfYmJs%I9Pio_$M&&wi;(H`W*OsZPN6Lp%xKrB~0kA^|?(N2X#U z0AOT^sA*rLyuY$`y{1JhmSqhW8EV%N5u5FyE>c*Q)xilotQ9?x+U++zjmdO-3bRjH z2+%J?A*0?dY>HSM*Tg!?f#$Nfp1D^l@b0&5@Y`P;ZOw=D4N=kYx^6?q7PM)}KI+cd zdWrMe!S$fVy~P@iE!2Qyk*^W%xpSU0VjyC{FXIv~Uu5{|t3vsQQ-M>_@QG_7R%yA- z2n0ZShIMJ;-XcMoS8)A?*KK@LY%f!Z3w_QTG_ z(a}m>)rixs?*<`$KijsEqOHujzK5(T@cBQ=JFrclf0yM2Bb`F-J|ZNJ>vq_M)Vx0_ zM#$nAWm(Dz%7-zEutpmi@ER5~(LH83A*P`?z62r-04yzp80fawhD=3+x|1W!rejct zlRH%k`&CEF7hj(Po`yD-0RG@BIo|r6h6Lk~6L3;Gx6O$9fRPg*8*)l&x?tOOhmR5H zaxwBK*6{k7miUPuzO8+29}Yk@3V#j9mBl|Q^tE(dt6IM^w!v4N8JdHGT-Q-@@N?+|xTEJ-25M#cQ*#hp z_1 z&Q`fpC|SfgJbNS=h3CNtVHm=6#DR=7DFE$sG!Ud3<^Htj$qA76+$H+KcZ|yNVV23( zF%TppGHl{PO&wv-s&)I6gvmUM$xfghf;MFaN)$;?KkU zRbh5&0DUKK_ zw3PWi34xL`;lo0~=cX!t!#fxj8xH}XpRF6(bHg>A1{uSlso1Q(b$o?bq zsWk!!aa^6Kw$o0dRk7(G;3EM6A0ga6dUAn~HCpUhEoYKRuT?rpgpkf>t*P1Q%$3>= zhC-jGXA?g7M7$fXA(K)z{#M5427X zv_N5KA(e!ipik65 z9w)xeLX~{HWs?Rx_&DdlLsK~}^C_b}D@#CRMCL^s4ssB|Cdk&`+P3%jf=8Ea-=Wu+ zX>dFud+y*>;bdG7l-ylmeaELjRH{=~^P#hIRKUUL#2@Uk(GB*}c z@$A*mT{4xCjx;96zYr;F6lzXfL|&>pdsn(xnH z?h&AU#n~ii&i|I1exF6ehSYn5;}{N70NSS@+gDo*8{w9Urup>CZZUX?D*# zdun*ShaVIDJQ>y|G3Re zHJScU6B1nD1_Bh)Kn|RK(j4G7QAyEfFyYQ#cViyw6uZ4oaeS|n5`1Vxo~!>i)dQVL6$b1P}Fpe*GI$&#x!{Pxibd+QRgKO?iL zXd+#L9kxH5^fgiim{;o9j+A&QRptv=ADK*ikdK#d5r?Fsj0a=@mb2HO+(XS71B9O` z)-evl@I5}cC4GUU>$UFX<<++T2?eSK@b|5FkWb<{&D&pSxCXC&8~8P*d8y_7+Yu?a z7@_q+eoFKhCF40`EDS*Gir_}x6D|!`Ywq9tkLpwoXg|K06SLMMl;O)`l^;_sVB?p` z(DvLsQ!{fO|EC+4fekQvcmiEdeojuVAs^&*Mh6HIlw@EJmyt&O?Ufa$B%`Ba`TE^W z%jBQaVc!oFUh9M0zW3;x@irU@P=pLJ19mnQ?T}VLbBJ^vFTA*T|K9)tf~zB*gDsrj z%j=RwlaCIxcSMA#kf^UDTiE3K-OiK#;MP*#d3+N05AbtO4W4C{<5uuBI1 z`}5&9&ajxt7&TzdbMx;gbGj4<@h_+Bb}ID(ezu#>ph~~+keU7^kpf_dQ>CDHdw3K7m;4d;T5B%x|_0rYs;l^A^ ze`I8yYAVqC{E2K94t!MC2}#d$;XDz-HNsv8u8du9BBt|?#X6-mIutGoMnqIqgRt^k zfiY*a);e|(3SmB^^J=r^#xu8iHagM_7=N&>!8nuu34~nknNwNEOgGL$E18X3LSaD zkoRHf93T67GGVGo#~ca%1N5&yI#41Lx6~sbEEa7%>z%T_%2UV(HvB$#$ zbB1a8xbycG#+iEhnb~T4hGT#yj2xtkLBPRYgI^D=KtV<@U&6vmGfH zCUWyo#_`F?a&FN1dK|R@hWK$h=hI^|#X(iZ^ZhSeLDKE{pV6VNfI%hTq!bv%UY5No z3Z=xn+K^^p>_MJh!qyPJMBnx)xCz{A1U~4cqK3z0C9kU{EBor4I&;qua*jJ55s@HiCMK;ECk9FJVDVs)l$QeX& z47R|NKsncqA18u|=Z$v)5tr~m3SA0o&#())I z1+e)Jpj71{_1xk7GS4heWHp-*MIuiIH8Q`m2-lxP6F1SU!`jR+BmMMt)c!v>(bb>b zb$?Pp1sUP|6mPP$TiPc*T96ga@qt&T-%N#3PHu>_3Gc}EF(uo z3^=Sw^$~x6jXWzNl{L6 zX=7~?8B{L?$0(%ebK9Em=@l+pN&k`qDctatvFLhu3ANBe8fDZHxj|rOId95Q^25hp zo{g2kzUOY$h^!6J&mwQ`!RswvPKSn@c}Wk!j?Oa)HD&Wz z^Cqt6k`t=Z?p|^L*Qj7?sUHJ80u|!9`Yg0j1;hovqK3GoeJC#n;7}aW+r~Zur6^J- zdDQi{9MBqd0uvnY8)UxhXgs;?T_Crj`=?8_4241;lB`SYGl)sH+Ln1tu6wzvHh3Z< zG`fmIMk`8~SxCh&sox-v9HOIm;hhK;1hazkmSniA@!Ppsw0iY7r$;5&$n{c!*hjQZ| za{|8XjcFZs>UO7vWNHD+sFKK!4-GP8oucZ{Z=gg~eI;&9t{~5C1RNQXHhZiB_TcT= zsaESEJe`w#Y~<;E$=oj(2nxRTnE;{(+(4wDo90+Qje z==q-RmnNXi0q!DH){DLX zI~#qRzr>QU?61y|4ZaQYRLXRP$0ciH!U%wlr}Y4A{~eL%#7V>rliV+M0SN?r%7GCc zf%$kCT}Nk1_2J)2aRK4CjLT4fi8hnmWTm571<;!%QLO%v(0R?20?}-RA0K^%2Q%3+ zB%f5aUu}ZIlq3xgRVFI#+f^IxQ@OA@5fOhR9Q(B<3`i|hVZh_?NeI`U+$&zoJG|%JMIQ5s5m%6Y6J0Yfa4fg&VNG zW@4D@p%q9CHI(VhXWVEWCv??oaB@S>648z!a7{{U>94=9GvcBGkN|taKAn^8PbDOMu3a>AnD$aN7rN6=y=%b~h%fYI5LV5tgRR zM}VInVATPYAJ~mKdHa5@z{qWj_3Lyk4fX{YGK1oi&?UiGS5t#cq zkMF~6k7zLw6U*07T@y2dJw9bcLDP)EvMd=5OB7tX?j9Ac3pn#gtQos>5=#XFxm#!E zi^}}&luGizhl66m*wt~RqPdq5)B$tVwPn1XeBiaK(=D;-Zd($|Cw8peSKCWxva>2P z@x4a2f2y?QZ>g5D|5n#MVQw!MEzQHCr|@XJc}3a+Kue+$bX;8F+iQL9n3^ITLc+kP z0DY%FtGeFH+rv*79ab#XW$*TN*EKghE90tB`)i<`b$?L1$a5`pBo=c0ffM&dz<~+yE!>>6OoAl$D83TEJ z%7tz4QP46{G+Gp(Cx!z8H5CEp@pf_n9N371R>GIGBNNn27ZN?_7o%fLD!Xt=vKcNr z-66y@LEJc)G3yi?i^>uw0Qs^HM!^ho6L?a|8 z7ium7ueuz6quqR1f&PZzyGefV+~R=hdzb6uvKfTJf!XI0Y;`eiP>KftXZCuljYX&a z&sa`xTnH84p;aQ1d?cn(b8hLFyAm>vy@#mAD_C1%qajZJ(UBT$vroi@9{)S)ca>k4 zt|?oB@3H|)ePC@U7K-)>e-SN6=mHV7iwh?yu(q?$^k55q@;}_?@FjN#mpsGkTdqd@ zx&xHZmaL8@W0nweClH_z41uVQ9>jU4#i{2DoQ_J~!CHkVb4pIV7h0sH$8}PsN@ZWu zsi~BG^X?YD)BlMuhkqUmCN}%B)o4ZkWi(BV(AeW1vB*UGt&5Q-)GhLG$zWL~F<+)! zr-SJ7x*hP829RK-($C($xxpYxV}%7!G7NtO91(T=>z!g~*Q*psSx)%+`A8>s$bHV0 z519(My3!x`21~mh7iyP0E4xsdp2(XQc1-4;TrGll65E^Zzc4nXU17}t6v zYK%-Yd9$D)ho-X_;LBA?=*e3Hr8V`~ht?+up-_KOwdi99c?0DGJX?lkcrybjC(Ebg zN&${a_*@e}nTNCSdmMa8eN{h>1J~8HZA(2NVNZIpi{QJ+L z+945SMd<(*1tzWTYrXaV{(R&a&R@s$dVP#*1sFF8E*_B;13&?MoYT6o{>@w|mF^SNZwYThb;JSvAnjwDaCzg_yVJTg-OA zUcwKB9-E7>_oolMSWAkDYDfT9CPp`4BW{}UL6oF&c!BQ5AQk1&N02oV4%;U)1So(o zhJmL)Y#=&~cS~9epXJTl!m5Y0LlYgdML&&6`Vo z>jC)tc(>9;-(goJxpA{WPs7Fc^MhLZP7KlbZ5}{^g_s2py(7El9s>X|d~rHNlA4=qmXY)0=8G|4K!D(P!vTA=PKG#*$4&TE z$?xW>rX7yM+UO5ts2hS0PtgJUQ>7BPL~h7R3HuEk&%VJ;S|>%O!c z^b6Q^%O%Lr`OYlcJ%SB8YLFdv7vyz!0 zxPh~a z;0XETxK_Z50$SC824xA>1%j>fiZm2z6vY35{b4lh;rCL7eEH*G=g{z#*YSK@+Ct@MXtaQb710tL{opK^MWE?SZX; z;+P-F{(Q)gy647lY)oWaBFIO#b%86(irnqJlFs;)cP#QRwGFYs?Ueh^#ZBgsfboB; z_yIrc3o$Nde^>uj_??7toPVUDX!)nG_)RJ5=N@qOd}Y?(ffB58zI6_)Iv{+DcU}{q zpn^NFTrR=On~moBI^1E*gbHlxKwC_D*+{rP&=7veR?5e;xL@>sN8?WU55q12R`Amg z363j0Md$Dm=pN|VuKbVuJ`9GHcL#qzWeYw+plG9Vu_ljT7AhJUd;TKk|Mr3ACFXp^ zI@C>Y_7-jCQR4k;ie_8iqjG)JvvDh%^>pp#S-5v>_7t&u0m_a~{ValDkO@-GABq4~ zO+19&4{uR?$0fkFi(AAmpV?ZxE%c{N_DdsZloddFsf)fcth!S6>Yj;7j|5UF@`juR z!?^o&T9_)~!Uvt?K&ua)$n)`gw}d2N$M0O=A|sg1pYrwR=yMp^##P`wV%q|&{pBau z@tytkqklMRbM>qn!BEi8Pq+{M1NAEJX^2_GP<*8iu0PKroCu1UKFdVn+R;zFMzFK& zWC5&d5Cx-;&|n%njp9*hgb$jELIHmJNq^sFwb;k#ZaMAVeiOL|a#d-^Z@ zpIKO?A~?!3Mp`-6>3C4uos{avue8lHGr!F$Q_3m{zP3sMqaqQd@s-^HjI$7#^QdAm zCQso!jvl!6VR}1W7y>DRvDFg8sm(@4lhM8si);o_%^_w1R)zIi0X@K}Oese#-dZhZ z()ff$c2+sE;g9~(n;k<5y{`g0OANyL^1FF{ijsd;JJ#9!Idj0}O3*hUD+6CtK^=w6 z^9KKYgJT5Fs_y=3AR+33*u7tcW1zZDdF|U>Kr2`@?s_BYr@Mdl6n~4YsY(n;2EO|d z7(2cyfn&eAPw3j3yZ@b%QeN>tIBgN>Q2uNkPn7#Os_gH8kfeG&R}@!@tsv%{T~OFN z)Z23@@f$q7x1(mFQTw5cwBBaWdZRQ62cCjAiatmRfJ8#~2{FMyCkezi4%d&^UmvPh-xvw2f>I(y?H#V#nsbm93Z(Z89t+$^V*2BgZHBp4! z+*3j(eqJxK^JiZ-v0>y^Zun3r32vB?Qv$$kuYuyW&vT{+ikf^7Y@ohX_1UF$vj2*=-Z96khX^ zRCC%#=OUvV5zP;*^GIBXva37U0u9Q1KxYLcyXAx{0|EF2`Hw$HE*5%!>an`=@>1wb zeauwgJ%@#DV^~6HkeH@DTUmU1u%a2TUzoB(}1cm zWdCRyXqs7*z2HMEotqhSs3&sy^z_tPgAyuxfHESmadUG9{)Wam3b!Q7mi97p$4jiCk9*i})^~nR zUPt$By<61CoI5?b*X|OI6zrKPMjs_oOp3eXTM&2D?brGh)O)}BB!pghYW{;)BD>n~ zcL9M0{Y!{3?p#Pcm391A;NNKAB<6laB%1tq$Nl=Na=yrC!&~5=tF+XaZt4wj>6O?0 zDpjLi7kdJ?$EJ^gO6e!k$s!et&1+O#7z>1_U-ocjeP*D0`-E>p0O zZF7#z?GI4Ge~e3!uOF%1-b}+o2CD)u?_547HlHyeHKh~fx4Dm;_LLwNN%;C>?S4M* z26I0ru9N9(@B9wH<>Oa7UHVWhrZ6v=a34VoaltlS;6-on&qEV3E^SDxx!p7YG-Cf+ zC;vsFyyWcCk&R%ImA;0F% zlS>+aHB$%a^O1^|yDVDQl{hWAS4LO0bPq3yH|%xSqZk(f!DvWP5I}?J*^lL zCjy{aLL_Y0erF!$R+~*LXYngyL{W{ZoU`|lj4vyf5p7ZHd=cDPzmv>%3&zo#@8gs@ z&`(FGwA&4M9G9U-iI~6_RY!zq)363p@o{7RSSYaDs`U!O{f<98g66*J?zxd#tt${< zoyzy)VK9+w;-|{7Z7g3NQ_YvY^O|(u-8{{(^xDjGc72*wUpL1U4x$|ryJ$=kE@GdK zmk@ip733zDHowq}3qWakTi~ zqcYs%Z9g@C@;`(2iT;HzWd}7dzx>RP#pg*iI;lXSWe9m0FW_&2kN>82rHL*f7QJwH z=PalO)H!yGcl@*@Ku;$glX~SLi>7_n7IFSwi@x$AD_LVeZjRx)kJJ+(D?6sHvr2HY zzv`D9Q9In28piYRLdJ`%Cq6WFNm9;A0$T zV`}=t$cS3wd)J^Z*CZcFSt!uTq+|VXK>*R_kJU1Lfhx#^O?iO&1;_h$Frk{t77P@R zRf7q;CX=fbBfziJs+TgI%8RgQ+kzOkT^>Ez>a*(&Y!@`5Q1fm#73|}1WZqEZd8t!O zfU8ff%XfGN{0Utu{XA69W=tHE~B+0I{kbNNF*pW2iY{PGTZ4D-C$VTl!K1-b5| zK!byfB;1WqQG0~#XDx<1zDWiuSYl&)OmZ7N0V&|*skZ3KTi;bqIX}~6PRK*q(X7`i zg74!WHigD7Q);%;vPugD^(f2SISdK6&D=5R3sx1q?W|@28GQLJy_bVkK5rioDnmFh zK4SHP-J3>_vRQ*SOYja68^5FR4*PvgGq|a|v@e8vKYUaS>H=;V3jVzb@ND`e_(loB z^S0CQG{d6I^(zvMQ;D4H%I9%PA~E*01=jT2LCl&V8HA!#U>!xsE+aaDxDULjen81T5n%UEu)erp1c4 zz52u`7EdY{>Gv2!v-lZ9c}z_BXfrPF3sHa(ZD0E#3>9`9aEJWR60qNMyEe=^B8yE12^XK4PDaQF=)D~qEI4D% zDFlpsZC7%jO1~HHH>h2f{Wb-k_N{H>M7(`6}KS;}37kacnzBJ(vI{k-la_(M(&; zXnEuI+$y)!V68ppMlrr0XTBV6V)Of5K7ymZ$n&+u753j`H@goPB((=;_D>Ij--B1V zbGJVUk=I>7_!6wsN@hxZ2c@~On9DiZ{xKMyO!-MMkAHZmM;&o-_C7E>iV*A+Wa5zh z)>sr+kPw#7xEnn#IP7G#CHo>$hNME*X{G~8wH!WN2_>7Y-Q_Y#OySEA;QL)114UX) z69Zm)G$G2UkYJsW19_N7&EKD+VQ$b%S@Knnbs0IRjbP6BwvV{2O7l@>H=F&|E@!pK zpeFkE3J(`|ah@Z&E}!ljn7_{$*STpLq!mEq7i|ANGn0^t>qSYm?RmaNP;cKb?lpg8 zfQ#o?w|Et&%ds7fj!CGqM=Nk_UdIK9B`y9c#uC*KL_cixC(u_mNyzJJ%q zsAj;5uOKa|7q035jtIqXkp8=@iR{VSc0yb&Sot4*X(0e0m13Gh0>GHU*b!KOn{@-f z2i8);d)#*0E3S^W*jDALK%cKB!Xw&$@$4ZlRR*l1tuqMJD7oykwQ09K{w5rp`B(@&M@h1mQSu z*1K>FDkhOU$!o+w@xXUY94|LbhP2e{*0@|IW^N297fc9{L1s3%$kc_ynoP%Ydl64n zZ{vjzx{q9kyzzH9;JUH@@9$s_8gb~M%nQ9>=ilErpqg7=xj-LjaS5A14h&#;R%hTR zsQpqp0u~RTzx_eC7oOq*&!qf5V8uW88K_0+PVSR%_ArFw)Nr@FBd%O zi@=7TZ1KOE2o-gN?hL2rkvk>Rkf*$aLh-3b&<)0jP+tCU9b`oX8mX_-OyRcp(#S{} zNyr=;%J1wY{!Sk9!gF~9PMwHHIpaxlhDmeAaW1avlZZ8tO61ZGFuLv{Yve76u*(bP z7;e7siRx()$M|~sLvW=WremVzrE(B8NYoafs!5tkQu@nli2|QzZgCPMk=*b9Uh}DV z(6sE0Fl~CYH6D%LeM3A@bAshyDLYV#cS?@sT+hAT+@KWvsnB%E6`|jAwKT+j;lOZy z!$==X{bYXMetl(_dnfu4%U%PF-7m$#b$RZd{U22692xMBXySqg5-9m35kjl|jLJ7W zSxLLyE^glJ=VqVQ4WOkfqTq0~*Ui}f@X2dSRd1G}Wr6V3|Cu?+9%P08nZCKq=L-v9 zp%EX_B&u5IS>yEaHu#sUcK&$!&U@J#uO_?_>Zp?V&>*}Zu25^;qAV#nUV11fcE5)b z>t4?uMr}~B-021erTMq%ZJrjRFUBc#Yf~D^vrpNo{_N00?})iN?hiTS<&`TgmQIgu zFxRNOF~qkaK)14CHXUs~n}PpGv`thA=YNN&H(s`dFI#@^5h(ksVr)&C1p#i}I5?Y~ zPg^7uMP47sriH+QEcy3dGKB^3*eWf3ufj?t;p`Hl5~VHLuydexgnlhgOQRh0uZ}q$ zpW1y%J+>(5%KJ`~2kfj%j|jgzBb>_>o!>P$+*JPOHy{g9s(AQCCZv&s3Fmw#upua4 ziQLSCJkPx~hr#H6=&{F9VY_eA9%U14=lF6jZLh9@w|)PSSm{-+M*6sYP}h#>V83io zmYHeT%E_Uyj~TfN(`B%YX+_^MV1U1iT&bags=NaBaS!#MU>b`lWT$BCvqos$IFnvr zgilyxn-`)1Y-Mm&0J~wMR8^CMxz3#?%y8=mxG?mCmjF~iB5kVrViH@tp|4$XhjPB0 zpd@B%YA~tVFGr}8nXOtu0u>i$Ex|GqiDg7GivhAPIMgerR2e!}2D}m3OknsEE;6`< zqXprn^SzBQK_^{cV<~92A)S}D%65zX*zjYFL8nqUNOskei76mqj}?V|ZDmHfN-_T$ z%eCiYb7EfQ-9!injA?JbvTVEglNajjz2mmqJFn0lFmk63J<@-Y6SW2+2$K2cbXxCz z%WD*rdxHT0o+PT+OBpR>sC&0#T9^bCgZ33067#L@oV|7mo8#9lUC+naG_a6pQt$R+ z0NMn2K9R%UU5HBpXH%n3zqqNF7-16UJK#FCe3PGFa5+JS=DPXZ>tLw{gYgd_m1Ivf zQq$n?RsaYG2vuCI8~CqA^!|JCRpWKX9QrDQ;jEhB`SFTB%w(#kxYE0U$*~l>!+~34 z(Th{cOm0|&1bY)PM@!fBk~!{j?%3-+l_d_ETkzsZjikV|0s_zcm}KN%r-o=iwK42F zLHqRYzXDKPHhX2!fc9s`(z`~1?#TAjv&>#2qAxL{tjVc2Nv$8mV88m(0b)y*qPQ9O z{Z%XM@-l-4O;3m^hL-$qn^1Sk-+Z^8~;l}*axI!ppLXxSE#9f&L+5+)t}Ck9q5ENUx__8UpF^)l;4{eqZ)u6QnqXiQ>&yok8nEsdK-3=*(zR$Ms&oW zQ^63x;tP!+BJLY<<=hoxA#(h0Ezt#|m{N3=ljU^O(ZPfg1#5#ijNKO}ky^mB~Za1aiow7HY_BG#K z{o03^aV$nRzIHx0zs&q$Xcqmiwqhm3B0dN7DW;Q?*Yf$I9Z6$+W^jM|mL<=}F^p=!VlJ4)`m0j7 zJ@Rscw)b}q)8Gi6qoJhdn{CJnN`_RfY&<+)WJ_1329KRQGD`71xLOl+Bfghb5F=bI z(86W^WUcZTC0BN|6x(_oEH8NFmoHE2zIhLPMg479^Wk$zbAxE@7J3N#1?B5aM6W8# zFcPx73Aq;Ia0$`bvoWlnM~B%<${_C^*NC}b8#X(@L+aa_3p?yQHM^>P+g2}>tl*2p zJs3tkQD>ve+dhGx&r=~XUWW!Aw`uXj{ea`x}w-^J*U=SssPc(PhsU+Sci-Fp0;=d+`s%}3=VzE3&cz~=?? zhvTxVWABv~f{x?Bg8Qc>gGV2NbM?fkVJ&Wer@`aeX5*6HDnUA z;Z9k@BI~$a*MEB>!p|FK`}OsCIO`G3X81_o`z zg#k{igUta!HQeXefGBG!H)k>(xME6GYmlFOnd_sgz3e&fr9Flpk*sPM;QdITX4+#U zbp@`Tfi9LopW>GeM!77?I8_n~wte(P9}IYc`R1Ww(1>M^ir9<{@+OWz9(pgXVGCRG z*{z{2jP20nxuvjtv-sq@5z(_800$?T+66$&z}-ZuQ>m3B45U0f~7UFOGM z){ld7Boz5NcV`^A{}@a;DH>qNR!e9M?{E6&N5C^cbJ$gTi}{tuX%|5)F@io<6F7v& z759xLA5<)jq{Tgr0^x*7i#tzWGxqH=FE3F|W_z7}U!IVC+|uwn0>fLxGpEFw8}4A@(p-KGcKJK;N?XyoJ-NlSI%oST4!BuaDFwI#`B1=jHyF8IFBuNoDWtGG%f?QiF>Ms+6c;67}r?;=;hV z{WFd3sz%IGAYB^0Fhs{RR$90}Fhs=DGsY{cmZzVH$U)ML_`)xr{^d!_zw+hT^{OpA zo@%HJGjhe^>$WP0!eFEG_YrH@!=L4L}b()G7(%W=C~0Q_$q zT|mROrHL;lvE$MNsg3)6U~M&qjyFsYyP6W?WT-W_cH4O&ZWtV+I)&^*X#~VOF@v6d zA7KPmn!m$I0YpvR(&-2;}xjk*s zOLOxftTz+`?`WSmaw{6k5|c`D(%CEy@VN;}YTm6(X%Ghv#7$Zv$TS;imm?>mZ;UzE zRz?+O_Y(30GRAa?ipXXdb{T|d`$Q-n6H$^a@c2*+@OA7vHkLEb<;S>8923es;wYE{ z9DlN8t*F6EUQud@8l`Fl{QKm9u@k3s7g$a`W%=+N?3kGtfQ;V}vXWVZ7};7D16?>P zvi|SAZe{5!)uyw^+hL-i+l9SnUF=$PP8MQ7+=mWJk_$g=7>);k=*n(Z%NADaIFyh1jM%Xob1(2H%}yN0xeaJ>V6c@EZeW{HQodBsIIqWfa5Ck`t+ ztwS%SDUBnH09#0n248BhHx>oE1jgWlIkfRo0&PnV6k}0O@U~8_4L`w5lZW5s97R@% zGEM)i4_lBBJ`SEjhT1;(FjkC!`$xHSM3ljJGCbg0@RB$*&b6HOZ4 zf$w}!9<5poG`ufji<1bI{PZ#&y3;s)Z$4pKa5{gHWfyg8YLOrgl&j2WWhtq@bEj+J z!tAdWNhE7$w$2Y=%U(9qYPtT;+V;adv%sO2lbvXky_LH&xR*YVu@|jn%@|Y`zmc^ zCSvZJ^tR1$2K+9k30cS5t3-U2ip0M8(7{~gr)BUwGlN@Mg+EGktR!=}?1|)OxyTj^ z^fp9h788@&xS3tcFqo^@VV}-ledaH3n}9=eMEhP@4Sa%{&`GakS;l~;lSQ~gpUb2@ z)t(f-6I&d6389;q8HU%G=xKpIb5$e+ePuMu?bQCsLfbdlvsiF&QDNE}wQwcwFaOh*yOB&U+LhBEzcH>^% zHqv00_Q3*`P2;(Vd3ytQhsr$IGzqn!!iT@BXT)jAlsNs@7bR2@k*;v{#oC<0Jo5e+Y=_~Vq)qgy% zuBe)((*pcIB!;kd84laeMDCaB6Pyi^_xItT!L4DwOZo8didCoV=A1;Hcbsd$fHU)3 zaXT<^aa$T*=w@irW*a){aNX)Iv~9Rd{RJ}OqHolxNzDhU#52W+6+_N*oO>ao7rt4; zSFJ!NQ^-cMLZ*P%km|n)@}bhPLpon7nWLOj!k1_!D_NIvmO+SZ2HaT|8n%s}E^+um z{;~je1fl!scsM)kXnOqe>aC9lHHe#%V&#$Jzs~cEmx@Uw-?evpG-Zj_UM0!gYxZa* zeQi9MR~>%9I#%j}h^G+&0B`@WH6BFX*j=8VFawvKCsK^x9la9e--C>v?f!&ZjEX1L z)_ydo3MALAsyc(YDOyiEt4o`#`_0-{$)i}scS?EmUHeU2A^v0=9_Xv;@x4i`QRr2i6dHb7y$nn`FbGFrCS+uXwf?7p+sU~*gfe^ zZi4^~HNJeZ4KdvSU2v52D&B#RW3DbcGSBfIirL@|crW7+(<;__~|q?qpL;&G>UgL9(cr-|<0Q;_@I+1wd(_Ory> zw+ki1uytX4{{~cKC@d^Cj40Jo2BmzM*gA#Mn&ai+`+tJO=GA{Vu@`G@PcHM-$Sdk`PX*&N@fc8;J z3oMm0_yq2JUgz$5bcXsA!=K}E6!vwJ%^PbL>{yEf$CiX618?IH=zQtnH)fY};qO9z zqueiha0rEPMws^fQqJ!-?e`k}fcuI1lmP7sFbNRwDF!fsdNULkAV&6I08XiFNbt%n zC9EXm^KSjHA8qq1{6T)A+C4v#qLr|4z`(+8Tgw7e?c6Yxv%O8HB;`Ff#s%g*SGRkH zh8efm8S)Cd{(`BHXbGJUE%aO1iO)}ePHN)HveJ#Q8vo>iTKC)~yMWfkZ%@ffkRt?D zrBnRCq0Ct*8R4UD%msTO#6cJA^vas|v@oL~i!(T3OsrA{b&)F6$zDNxmsc{PK^ZKr zXFRUTQ}w^MI^`Ck&xf5y}?)-<2A2>40A0yRiSXMU$(ZzLbv z!1d|~-U65Y58HIG#eLRC(JS);j-4=(C8A+F$4tF|A&!^pb!)kZm-bT6C()LWe{SSi zIZGFYz>h_#7w$~f##lvetwM~-et*CExQBi7P%*%2o|kV6|=s!jbS?LeYTdLs0p|%my*j1 z0Y!Uz^IEf98-PQ|K*>cU6SBJ(BSgcnAoWnnEB&*>6Q-fFu8(nh6EWP@@YUz&zPSux z=dN54;@5px4lRPUx9ggagtpTD3j44_=3MBUHMtiu*oB3}bxgvOOGhQz_r z1>!?B3S#$JBj2CHh!ra@A1>##bd|XmPLCaJ&Zq1{&OA0g>4m$)R&d|_kYg!Flg>XH z?gBu~?JPKrXn~pif)k~r!IewD7>L=cQ{+|jvvAVIDdwIvl0j^l0~c%S^=1%T`3{nc)~zo2!rPZM9>L|fJBhQ)!B zCWbbg{ND86`2YU679y208fK3)ze#mSfYdec>IdcW=`Wbeb(6u6V)^zf;HKB1&Qn- z*3WcMQqADyU9dbODy^Wn41s)>JcE#e#?}tPIVCJ|sv-5-o|y(kwau*E=Q2zE$MW9q zXM4-2AVJS};DdkimH*Q4#O}#!F0Gat+e-qMk(QG&;r}>rP zif2oOwnkXlkCNgSYR$kS9J?S(i3@F&K{eMbC0j5LJK~e?8V9xySf<9Y7t(P|X&xpr zV4S>6kT;iWXU88qbdPs>ViQxZMWVUshn%#k$t(B4nZIBCI<}|vaKQ9DQ~TN#D!jS( z6Tai+tq}%p!$KZKd)&B*8OnAbSKCKmek%N+WAc{Y)i{s~VxuN%IhAM8LCrh6Mde}fAG7U2jOYx{b%&FSueH!d$XE@!te|92k?yTw!pZgGHK@pb9rpN~4U1bXkN9Y}tM@sre0 z2^H=j@%{@Z^TM%1;`d&`d)}!qd3>~~M~Kpc)gK2aum1ZCw7|6*tHv|T54S>VZ8ia9 z5nfZi4wIjhhg{evYQm}{hPX`b_lH+TmJ?rXJbb})E@iFevZCik;;(MTJ9!JWCZ{Zo z=#YolC}%+!DgI{T?3myrUxSL(Z2%PVj&G=4q=OMZq*Db<>NNRBNH{hTLrrvJoo|Sp zyL5{X6K{-x{oHqgBO1*r_fsr*@)D8Enx!9|)~ufStwvruZK)})Bxy`yj>efZd^x@4 z$R2Bk9NAPa>w~Z6E{t?qrVR^qCAxo}vnfW&Z&Nv)4=nq^qB9PJbRI$^Yd^qu1*FX1 zRY|8UJZo%LU${ju2rru6CiqK5P1{>e195)&;P2#(YH#2CG~^(Dd0)eC6o>j0(umDH zyI`syHKjesGR_aCjV4@@MED38Yn6KIQ>V2jh z==VPyO2+AUL6w05-<-x?LmMd&RJkHK%&3%X3jdgV&olmUc)o+mgsbC#hSaL+P6q1XhCL7#i6)mAIfFEM)MK z)F@tv$3QSCo80&;(WUHqEUcpI@wL$@Lf3>B)8S9umjbon<{u>c`NaBmB|FdW2WX$g z&!+Ul_mFnplruNC4A~yH#Rb_O+MO;q>ILYguqLAf0dePG_W)V>WA$cTu1YuAYP^Mq zUSDlP1|*8v>9~5Q*5JcGPJgl`I5G!GQwwU}QT^+#sxzg7E;#?wSE zKYuxaqPb(cLpP2glD}q-|4tPxEy;^tJ!yv$Yc0ZE#+2NhPs!xYgVYE1RYUha!s`~- zBm3GT7vBt4&w@uFERe3AfK`Y=Ej#C>(@?Qc5TF3}ns6q|`u!URa$YtZgkNirv6E%C z`Ko)45`BBI=AQC zo3X*drmTtS`Y9&e;R5JrVgq|q-GeAacZ0{{W9r`FkrFGI(| z&anSG>iIE3OmW)#G}5|{BG(6VvY&VN7O!N93uI)sHkD^6F)ski!lWr{~!Oa<#X zeESbpIaihkqPAz-t1p-KmSQvL={^GXqdm}6Iq0R-aGg413da~8hKHS)3&%i1RD?5UT&3av>p?5_H*$78}5}*+Nnb&8AC;ypdLAv#@Av?1dV(>YKc|1n-Gks6rv^*5|dBSauOZHd-&133C3YS_!S!0o|bv-Qihh9OvPf)d~DZCMF*U zE7(MyMSo!_FNH8NAl}DyQGDW4>}R2}-9rrG#J6G`z;wo^X(5l$-INQ82(0w3RCZsI zdDZ?CcVFz(P9@$WO@ zo`9~x=2GU12p2!kcsY3#Q-gk>i>8uLfI=}&KauyM;({(Y;=u>_0lVD=4da6nWCaPd*6DA=?ojRU>Elc_cryVEjy(QnpKUw`23@xhJu%h#s|%>g1D_}DhS6qOGcLD^uG3w;G%$I z<)wkmcV!cpdnjz$v(oDM?*oWb646s{&2oVY}U?({eP_xL+G_= zsWr|LC;Z5aVk1%vESO>}fmU}e42cLHOdJ{fTo7;M0vRH-QmXlPdsKSnPyHEQkHpZ+ zk0qT4251@IqBPpe@LzRuF?XuS*sp)iM7y4fcA{iGRFh!;MjJ0uJ4Z#RKJ?-=nIV{a zt8jsRG+SryWNz}(SN9mk<|R^1$_E5B$pUm~SAz_5l)sN#`5%=?=)`UjL3{GSE&O&( z{l~8K70EzrwahDNBwR-YazZ^dx&!$A)v6T?M?P1bvZpj8%Vr(#htth;g_SlCw)%gg ziqq`NC->H!f00~g1pRhKc)UMjx}BjVFbD~)c6s3%)JXF;4mfQUCZ}wiIk?Yjco*Fb z(G4ibN7dCq+OEHew1{$BO17Og6=Gaz%M}B&us2qYBX-vCu@-c85gF>_)_p+0a0Cvt zR59dj1h>u(nDWgp4uIigJ z5GB#yac4)=&Kqt)wN*qgD~gO?QJdJY?PG$77V$}et{CE|^wGI<@_g7~*`An1&{ATE zPvR2q>dh4e#V+hs{))bP8Kiy~r~VPt*1V9{A2o8yt`sK>zAwgT(9>e=gIas>4BP+u zQ|{l;dY`GwBpRf;D3)M~5?oqScP*Rd2ZIEg7R>A+)#`~AvT8L6FO9%{$kZy45+<_) z)p!MEdYNOI4yWBP%FkG2E)|-5Do#goIG2o#--emvTy$&uZu@76irRr#uOgG}*)DHC zu$NRKv2f{C=u8E>Fr)k`zGRNztCi29 z;bo63K3CgwAZ?%&@qK)phhbPX^x*__*Z5T&A?{z{{2mo(?3UINP#jO(e7<|Lx|g3t zWgY#I0H4KO)C}ugGL7I>z81lKDmm!d_X_OnnFnqolKSb1(LC&e*jf(%JY0p zba6UVwlbI4XFg-Ry;!Q}fjj!0_ZJE3xj^eD5vGY|r|m2I=bEL^G?hz#iLdZEf8E$T zh7QicjoNe?x{U@$REW3kNLC?IJ6C2A6NYYyBvT$e^(q-D9>~o`QNF|v56Pz zkNX!Ec|(E(kg70hKNruSpV1c*P!*i*5vY~l-g@qFkcoPmTO!!IwKI?3D*AYB(5X^!{n~(d;dir0J*52Xx#T^&%fu}5RD_~vBB6l z$@Cj4(oFW2jWzMv&u7}lPDplf>^D=1!SYE+Ob?taJ>8A50x6|OoqtHP6|CvOVW`l9 ze#IfB57I+RVRUV;PVuiFE?J6zM{xLi*%b+nH0hEDu|=y9{c8?`FODqh^_1xAqS#DZ z`y#)RC7^iJ;dazcQ6xXgk4ZQGqoU%|HM~JWs{}w^3q(!?Fv`YMTNL6@<+ zx!ytp_JLGKV&r5D0E?9R`bZuJ-%3LFsKn`)P=9mozVXV)~p8$<2+U+A{5;Dtzd2l zp$B|mqKfHJ4ey2V?T8ge7AV&&U9YH0`TJ4#Mo_gN~vzAtU$C-Kb*NFe(5o%6~OyBf9?0)+=6?9@Zj`*+T3sBQ`R3#0mRaUV8RfA7tQpiRKfjk zISR@Pk;;?oUy-zdOYe5aVfuSZ?_QiW8&F@#lsy%Ei+Azqisvqksqc?`SwrS_T?uZ1 z?1@h(0~LPkw`!XSJe6NTS>bBez=Rs#jb%^kz3Vjew!U% z5FKz>?Kb+XG4w1RTc`2a26uZd+o=?{BT^1 zhZ=S<=O;18Og4BkbaT7k81uSvAl+paGXP?*ZhH z@_2rS0SFub%2CJa!vb&r(;Qn2199F*MqGfA2OrJM_8;e`iKklq<^>|SZDW&^K+yc^ zzbaH;Xn{Oqp%-@OFbP@KQ$d<&GJ;O#=<^*Qn|Bsbs^6snk{SEQjO-IdYWI_oA z_}yhgy;tdD!95w}zkSVs(~HzC8^r|9vCn^+$S4OT@QMi;RFFw@CqmtEdekkKT6M+S z)o+p9ZJ%y0nV#ct4T&dgK8%{TuGM>2@wRwc;=Zn1bpOx% z)fs}!Qctt?{rb3&o`&EcT4C~4wTMJEMtO628$h!DN2zM$)ZThBt=9&wZ>ddv0&?o( zkY^vI`d{>b2lavpdU`jaj+fqgAMjxy3gUG9MQ3NZ6SH4>n>d zR5B+Mn9A**8qtgzF%YrNuY^O+3=EjbsaBxCz*Qq-_4Z{4POP^6E_`{A(aA8P*0F|z z`X$$_1IQfh{EK4PYW95?>hA39^;_%tFPXuIAzb-@TvnoD1>0-@=S>&)@ zV1)(?zWV;`m%qoOstr-=6UfET)wSdyGY5XY7x8~A^D{IRoejwKDb zI4XD?2U}~>O$gkk3b=}RErAw3g);qWWCKDpEU+E2GHxM~-f2Hk3>g|x#Lj=RKrV#) z)E5@-s+yOBzHua3Z>?5WOBrVHU`Yp*pZ)n4eHPj1h$=ht#%o*f{2M}ZtqcPGY)+`; z(cShGJzH;oHR4XPOL)Z;f5{5VaSr(kANF0(;ZD4OjUW}aOK)5fF|phrJyu#H7NR~n zo**L8E()cCMmnWIc`yQs!X*Ljsai4fcn=Wo20f%4UYjH#d&qHjiUj&Q2wmd@`@P(hIEg zR~wX!a?lXXiP6u3zGEX)riP+~ICnFE03v&Z*y1Nd2F>0oZgr)1|GFcp|0VlZV~)JC z0okh;uJ;)|EES<5oY-hn>*|+1sl2~vt#hOZQ*j(x^-Ux_$h;F8^F54gLbr)tOL-YFAFS*@bH&b7~cK~YuD>ur=ZqsQ42~Sfq z)XiR}$%Ytle)u1oA5YYg{IdqDu&JlNUE%c8QK*Ca>g)kq54?6r3inFoOpo^m1Qmy# zo~GUP8K1wwqqm78EC9vS027C{j-4%)d+*LkXFgY+MBYg~u+`3bGD!1HCC0|@6YNL`^30B zSIEjDy^2Wjw?DYR@rms82ri#wGaHSym zi|HjQAI|a0*7845%1eVdaOx{Ml24?tuYqy79Z>6^$dY5;6bLN)0TOsm1{twT9J^9q zcCC?N-(O0znXh*4Dh;c1gd}5ZT8MD-MyTA zqH{?-Er@S7FbZOU%ZxX~sxHi?V<;oHynhkQamx8b5S~$b6zBnsc-Ges)Ou!$X;OC2 z3o;!S|2_ZHv_3Tc#MT>?jYy%`e(#xUX(%yp;J2`T_B+_j{o{4aI7j2r_aIj7dVLO= zCY}gT%l@>zl=l)}5l)KAiIHx>$-(HL`;LWeddGYIO{4PTt;@V}VnHsBJXOEdY&7A< zlH}0K?ZQ)nN#{;A>le^;3)tx$c&0W0(D5!^%Pk2wlXazlk9mj$;(CJSO5SLEa>WU{ zPl(RV8(|GYE3GN1cI@urU-viS*8K%B74etNZ`JcR{buydeOr~Q1^dIu88`({w_FE4 z`(y&kDs=HyWp!&r6pClD!;S3~TAHMruM1mb8~LFA*jPuhx~H$`xTv;4QNFUP-G9>W zV4h!sIG(u~p^8fAzAj{73AESe=R0FPt%c5--5MSPX0Tm^6tY|@{r_n8uZr%M!qMlK zUzj*H7kUu94abKIbWIfa=(L8u@XZ3<`*A!p z1zw`KCALs|4EPJ^yj)z~%+`&uKYN<}GkfAJeDzlc{-CpamQ#s%h0gR&Oqb9o?fB4b z&FNA+*>Qg>p#I7P&iVI;VQE(Xzg8W#9>FEL6Llu!&x{&1UO`~H~!Ct+<-=8t-Dyb@M9^G~Dx8NY9OIX0mj~M>#e0TMV3()slP6$@lYJjY~3RB5el*ZEwo>2?m zA-!g(KiYU+?$|}YYRyA*{BgELbsS3i3NA`XIF+*5VS{Uh0|E_D%opsTlA&feNS1yR`8Lwr5Y*;I zskv<#bHWB$dUI3BAs(1isWPvdy4YLsS!V{{d>Up?sGNDse#xxa+#`(DNV13h=@iHdoH08=wRhF-*&<)9QI+ycxf&r4@#s zSm;QBW`cQBA*l?n;!`iqI8SA8q6`uwz4o(2BA^t2U)Zq{{`bgJPGxi$4ABdA(={Ksr8MjR{{7e=#5exQBspNR6*D@=R1RZJ>G-D*E9I*pbx5Vn5YL^X^ z5K3WP_>uso-v#RUeJ{(waH@~2pW3(lc zCZsh`SL{jg={zonaGLz%n&?XU>y2oM>lgp<{7?(Btt)q?<$!zJ?Rf$L0Y6#I{%|q; z&xR4lNR#$Xew{{&L-oMiS2Eo{Psn4o4Yl809uC%R-)&ch<}uQZtxT0uq3SV@DXI7w zcRhiXqOgm0a&vHR#UfI%&$6zPW;f^uvZYMfGRCGAyUpE#RsJD5 z=&6YXU&EDgdLh4t0>PAQCLC>b54+Zhlj27b8`?Th zzr0<{C;75xgILk&DP1#kCFl^pg@`>&>v^!J8B_9KwsGl%Q*JrdoNO_k!4J0CVuxx_ zo83Hz8-sLEwA1#_qaH~lODW=D01V4qC*ERzn>2)fswT2JZ>SKX81$8scfliTu~}V3 zCYo^JBIN>6^^=)^Sk2bW+yj%p(y}blz>T!W=NLuYNK{t7H^PBrW9GZw>q^hb7j6L2 z1{2}dH_d)_x#8pa{sG zNj67{nFRwVMl<=@>ow6KV^Zbl#UHsBtnL5{^zwHawseFbNU#2_szC;uSqVREnv@Bt zrJt3{nUK`$X$F})ll;pTSW|CfQzZ?=`r5fE4n7`@S~6+HE1k~G|AFRVF7Z&zWir6W zYvC{DbzuFYy;NMsgFB%`*Y6KE6l}M=u~ym9FV34EP|W=8>S#R zd?P{1cEIg0Zb}vka^|O2(leJ}`dh#`{)bWE{Fc35Qd~=~{O(BA`xME2N!5_3X_@gDdif>nnoIcuWG#V0DO^n~M4= z!`%hp@%H>ReKq&x-+qSOiaR&+?p(Dx(VDT>ro1ZOru5f5>zP{o7x0cTom5x0#`|*2 z=z%4DXMVIG+a_`Z7J@?XS7yYq6TpuhXW(LcL~5^;Lhg`Y^>=~;@n3%g5Kp5F8C3Q} zYL&VBaOc69qlfh;MPpzC0y#p^HWoh;lWCb4&9ATC7~6wvkgsqOx$7$$-Cf8@eQ4%c z91zuYaZ!leJ3@I69ZP*|eBuN3BbP>wepio3)*seKM*XW} zf4TpJfF+ZH4U*ocw@V2wbuf(x0?c1}NCq4KfXWz-bQa2WDVVC?taw<3;-Oz7mrg3c zKOTue?3I`M@EM_pcdL3|QaSc{fkf}1ByJ63UX)a5u&E4LIDI*dv(w>6Vp0#q^e>3(oU4YT>Ra``HFPKij(k1}H+3}l=$V%P6DCu0DU|HIZwh7s<>iA#$IDDRU) zz5ao=i(tZ<0SG!oB(2-(jxB!#Xkf;IdS%0F#x$aNR$1oJL@3mgx_)H|7f zf4RpW6%jI7$*8G4%8t^r{&^;l6e=VFx5A)}iNJ$fSWCHzX zB|=`sRBaV$-V$R@hL}y3wr48-dNAJ*T)0AAfyDJP>DYz1Fmi!rqVZbyA`s6O2`=_ zylfg81{TY;gpC2CrLh};_C{f%_Q#z($=^po=*+a^6D|nXMi~%uRdD#TCxmrH44@gd0T)9s~( z&VnAMAWRSHL%#nZLDV?F^BBFd8|u+=HutoEPCddfW*i1sB6U$;8_oG%VTqV#I-@{w z1CF}SXNweuUI7W6USk3q%ZMiB=~Ocn$QdMN7XxF;f}#}L2fI=%JA0ZD0AIWYO|jGB zJ19TC#+o4)s~m8og}u~At1wksOE-(m2R>52F4(+~GnjQT-|YVI6@L0Y^0r(2QmDs| zV#9Ym5Eb?WA$;5{`P_+(!QoXw|B|as@BL4LqHJ*b2Ow}DXVjd-rzh72hi_FfaR8f` z&yvI!&1qy2`JxgjPK|1Ac31NnQHNEsnv05a&F`Mj3R|ZlK2Z}`3ymq|-9wEtl|}r% zfX?4s{TY#yD>SpjI+XryLMUsvDKCDNB8VcMMEK49gFBVGSQ^>Zp8Q^i5qENvAJnpG zI9}`dgFIVA@QNK$u`aNy*x;vu!frRH^MLT*0y>(}XeZ_2-060v3v5y!uY;V_^N$t2 zvNsyL?O0DIha_}edUsFC%m1RSLhEU{(s0!VNG`Y?3zAygiPo<2X5k3n@rRnTNqD!D z$p-Cn>iZTYA#bZ(aHwB4(JWV!Y6-D6D9LaHV5ryGEOnSv2);i*2UIZ;`LTg7Hjp6T z_n~`{w^fOOq{E)S;NuTS9Otgg&B^5L9M-*BOTCCQKi@)0KPCq&hjLO~4* zHFZrc5oAM43bRP*2SCA;iRJLh@AJR{;l<%3m!c1Q($E=yh`y}8QD2FP!8r5366SWw zi4;|yBjMD~0oQ*n8r3fCJV)CXpkqh*Pv~YZi+C;o*?Yf{LlP3oC{q?JIm~-=eSIzM zqPm^#Y%1_v^q6<{z{*7%YlGXApzTmirATGL-)#vkf4A21*@C*P@wlznS}}pI>9gJz znjBvcDVozpL%=ygLZZ56c0x}D2(JtsycGI2#}a;A)B)J1FuilB+q)x6Bj+ybtt4(Uhs@AZtw>Thxp81|V&)b@q1Zz=kJ5f4Ki`8O zaSdYG+u}fq@u2wadl;|>V03vI>)pHGTSgS}@;ti&rAi#X%*cj0bq4-NWX>|>X5xp6 z{QBXCql<7WsVbi@@iL~Q2=@r2*Z?k<3-FI6`Sz7<9AGizjC?UVU*)WA4Ec_ToB3H% z=RDI)G?Xw7KK62vc@F7D_1a|`f;}WBZjCKHQx)9R!3MW$$mHK0zcF*Mb4J7C*w_5+ zOf-8qStsC)!H18`X)n^!lFq4kfqkmp0RN}UWS6q1$?{OGtE|Wo<0$6PtENkE-vhEW z82wnJtGvN37VMbgW!*b)>^d``iAALx!Y@-pJOB-j$1u#QcxIibDJz>p~7%L^zl|NA$WXSZN-<)R1-nA4Q()Wjo zmfAQ69B$m-j7{Xdz>8*8T4}LggKOg@(k*E%*xVjAIQxwjwK>hhaHJp9Cem>v?vGOl zul~g{aC>2pb&Bb2>X-L#T_?#F@AGNs9R4~a#)#{9M{^oO{XsdFprT~2b?HLyNc0cC z_l(4Lbc%dRv#u|J;BCE=@Ic_LfOuTNUHWUVdeF-bX#nZVzW6f|*d`*-wBXebI1x;H z02frQ7CvGf4jfvCf!N^P3>iMa(5JbZeP4ctweG?9$M12)Y+&U($ErB-xyEa1jQ!0T zBwiAFwdU<)XWjqMmq5?B?dd^deGUMhw^BSerd^fQw7SiGS!mdD*xH2M<=<>I_&-c| zeRW|LR~Cq}{1igPxQk4|Z>jYuhkpmQN1D`?Td5x$HpPDKDE@84Syj5rerGXN^5QtS z=T3(}6ysY)|K`Z6%4w>qRniHv5k^`-5Au9I^Nw3T`%#Qp8-dQ~U366u8%>6Xon?~= z{Tdl-$*1dbCRkShi8_lI)f{wYG<~->*tp%%Cc-L=9F;^wJgEkucbKyM_Fd_btq!?^ zPGLQ~EgAgf@DrKq$z7AG31Y&Yr3i-co~-4={KR^gzk9D4Lr-5@8PLBfu5Yb zXTUIt+w;h6GDUhjz9MkZ12B83!f^ogC&21$JK%_h#u!eSiSP5;G32PtPvkqXrI2Cn2C; zFnJ3@8Wy#1?@#8YOkR*Epd#VqA;^&=Vf&X-BAyn8Nbl+EDF~nhVHg@(nC2MBBmZ>? zSIqAJ=kLXD1&c`f^lo&b+QV^_u1YB1o$*gceDyO;Tm}KEv>6Q{$jTboP5UO^0NRWv zgahN>{LRl2aB12FF@Yak|0kAhsXaU*+dg$z9v=azTF3bMFuDJPK`u0in1P*q+j3YN zfSI=EBW(2~Dd@Mlw5v+9Q=1uNDAHS8D2&DyfBdd09pdIJL?hXCV&$dyA<#W|?&jN8 z3G9)ZD$&pHG;zJZ?zgd|K>hyqzlqN6iA|PMY z&u)Ko+n`=AWmG;t*n0j6KWyKgdfrJqe|bDmS?4smj&>xIm_TOwXYu@pm+kkUaps#xkS3L4?1a7} zK{M37>EPk8ZGZDSP!?50ytfbh6Gj$wL(5_Vh=iSg79+1r>YFId{`UzRyq&_z3U_Xx zUKt(}{B86uwbC0zJqH@c*w*Ye;fFhh1&6x$iwPXa`AD2-IX+Df>3nN6YBgwmE{iNy&V> zQs%jaHB3Ll8~)Z9FkO4`CJwX%?7tShPn%Dz!44fRniWQ4#%0JhG}Zvb(qSNVh$;VT zd_u`5hRNy?_yQCrlp?y#Znr(pFTUZ6UDUnaoG|Mi!1X&~3%Ic9iz;}*6^rY8dZHa_ zcs|wNW$@v1ht~w2BY~LkSi>_OZ-+EsXqT+vXUmQaP<3mnfzA& zPRj<-h)i}R*zZjK8T;|q*$Yj;y-ffnZQwN(%$sHl_Ox@eJz@6j-ve;noG`GNoi}3? zNh@8{m4Vy9nJU$_mI`(3{0=+|Hn;`>60D-u9_Z@v+`=cZ4d?EDnG;quIlz4M7B50e zjMIHv(MxdfMw$kxj#r{2F3sfW#r|QIY$D;P=WNjww%BlUVE1d*L~g6Rh%J#dJEP7Z z#gRcuYQ>NW(FHu#M}VLfK!%V41&1Ih;_Vb{kfCjjMmY{OIxuSDNhYaswQ;^rQ;6Ln zaE+L7_9^e)^XOZ8YU|cp%cb4R@A7c!D<7p}E1YRCgOwf5SAF;MILs4F-Om`15kjE* zc>L4#R<@kfz{uWzj=;d~y)D(@&|-5U4+74F=PI>69rs*JxOMSGbw(aO^KdJD7C!_z zUfT+9zpYn`uA>XqGo30$$F)WZM3>oMBAxJ)ou+E_V~<{2N{+1zlslIj5J|yCu!r9u z^G%hpB`x_bc=V8YN#?j6{8?!7NW~Gk5wUr6s1KiU7gq@@FdgKn`ZbkxC1BjX3nkhf zG{jiKK{(#}t}Y%8d-`(;3Q~U=c?l1^Y^NQp$nS|cGYh0n)!3S~CxvkFB=GiG`Vh2$~6{Bkaeb z5~d?euJ5E6_SNM}U80~OemVI?ab+{UH3kXVn#oCuPOcpJA4n*)waQgh1#_GPJW%ZG zD7jZ$!nuU+v#0;Z;0(E=XQoVvPu8REqkd2^7m@?L1`)DICb_z|TkCfuekY`^5j=5T1iTdO8FJGXTBsBQ$bkw3Y_^a~D;iIn;O^>X(9npfjHvu>^b#oP$LZK?RFY%;66v zPM>{pV`G7D$^6IY#SqB&a#b)s_Ahi5nOy#j17m*d!we>s`wHLd!Nx+r9WR zm!2(0A{=!%D960sE<0sHYoW@vi!+b^y$X}%c4LA!^~2p$8*V#Q`vFPTLA&7aN6xCz zzX|x!_D1zTO|n)Gv$PY$f?D$<3m1k@XObZiT8HVzarNPp-SSZ-c;Zh(gThDu8vL(O zwrZiTMLn=nXFyYHqjbz=S8vz$fveq`&w2Nv;DiXC9=ZGsE?hdX^o?#YwM2^LarLRE zH5X*YJD0|->jyr|sh8)a^Rm6KE+^ys&&w6-k##qs2{sV8NBn$lA>{*$3f6tMlw&x1`4?wKJ{Au-}Gn(!R-4(4#jFe|{+9;r8;_-ciQGkpQ0 zBqDmK*~!kYwDWS>!J%0X+0>##XObo1^zCaRkS!&`Yi=@qXZJw;E)a!v?XAyO)k)-n zsveR>CASZ2HkKkb)cQ`(ju?IAJiVSJp=Z7Rwe7if+?xM-m5NjmBw9p&hNOEZ6kD^2 z-Y6{zw3TUIKB?*lKhqw1cZy=nU>C$(V$=2jkzm(_|bcuCJ6@~dW9cn&S7?%Is>8PT`*UC zue2}T_~Q=TOgME`@xxQrDCTabUMlq2JzS$zIbOvE7Y#Q?Ugv)8R(UP|Adsf-{qawp zpm#aeN}Eg;umy2z1fK5#>X9?InjA@8l_zO;q-06kycd1}R``o$t{}{i`T0aW~2=@3?T|a-xLtnJQLD5q{_tt1zhc8k~28 z>T?u-Ww{iXYj0@alUZLx=nNIDKTOE)-@z*vSNEVZlfJU;B*Z0l z@1CzAd01pWZ^#t9tnQEPskjRt}OAyYcnQ zu%&;M^pearmM@Rs4X1yNR?di6OcgaSX^SF}4aX^`vxwkRb)HMv?lW`)TahbP+21&0 zh1q@jeo#*yo%Y92)pmCX;fn%KQB6mx9dbpe35W<}tWy?ZHzb9@tJNupigGAF(RX9W>Ju zaZKdZH<%`!dDUG6Rj1J%Iuh!F@mB;{@ymq<1P7fnEM5eM_=*X3mAObiuYum@ni@3X zb+n^RLgdo<2Go<=}OfIC0kZ19{vM8-^yR=Q)94J2cGc~RE z2aSB0>`V}i=v%dPlwv**83*g0HD4+gK6QBI~o$UG7qOq|1qn@1w!?qJdc zF238v3o2~qzts}Ou2w0v6*_+vlnXTsq!RsGjrFj{i7tu@X$^=+(^H6-N{K-&BBNk|LL~^N@`=JFtg}CZ-tmfJ3W*mWcD0TJRSay`RfI4dHEP10D`& znENR4k9Y|ZX}fsL3X@X;q>ka3$s3lN?7G2UHj1~Cd4=;Uvg8O{l>Uh56GO2;yr_PW z>T{n2$>fu~gGUATKZPtH(J3DnFh!LBEkE41Ng!|QwG$4!F4JjqPW;lvJr6tu>55e| z-!|!sKSI^s5fX)kgc}y~U@+74cEr6F_pHG{0*~(P4j_CsReu<9sXqTm+Y<%FJy#ES z!gb+Qho6_Z-A-yR;SD#hCMc^RyJgMN&^i9th_hqJ-pnt_`o-w*FC^!y<;iRuQuo`u zrJ(ox6TctNVCYlgAP@nfqKu?Ydv&E;y@S>LKMvDAlC_awkxw6xf>fT0T*|X>i#*Db5?1s95;VZ%w{=S{#31>>zDDmr00qKM~r9oj#ZN1s>_MyhaF;g^E;@u6N> zV%b{nC>qB;+|*6naY;%vZ?LQM$4Ohtp}9@=iRwUupL8F6A|5O3>Cs?6Jk~kbAnm_$W*cny1MjnlLC*u zA1iDV8OZhVZ8jFYC+20=+mA|=vQUFLK}jO?K+J2S_RTHn?w(X7tQdKd+LHuj1#W_>8{NfU2h^*c)MU>hF)FG%V;7-tIt*Ru#ElhQcI475N$gNn3_rDG*$*GfQ(Vn6{&o z7V;_*xxq?lfYuh_Ct?mi#&D z!iyWze_OX;$0+|NdDqT(JFhwapRVe47X~bgc3XMBkKokrkFQ_(X2bZD)BbbYT93FW zmfT;lrCC|h`F8QC&8J>(Dv_&?uk}j0QyF6CklK`#`7tggLiBs%$QRFY5_`=a5_(Fv ztEbU{|J;eFJhL`Fc>PyT?_}%Wg^%yid1c!D*1E|*_gsAIT6M(dyZ?SZWRCwwr^jXl zly%IRcVSTFL6z&ofG>vI_m*w=xkuyvKZl)LIK?5ta`&z`H!XVo@^kaLxv`g5=T7*> z{D5v)@72X)&(0|sa^~u6Z5UgBAmr48f}DDjRhpaU#}s8v4E*G+ozVBVbN}#>k%xZi z$_u>L`*!T8lOu3}t=p|5cNUC!d&MNIf6CLyG;PC(pKM<5K6*D|=+gOPYN8f>vc1R7 zDLoF%x_ZPoEdN6(k}-!=4?VJT)5)~g^JS-go-*;|?>GDJUo+v9?WYZozKy@}?emYq zmS*ld{(5v`?&Mzei|##~RDJW#spE3ZioP}0eaotMoD6Rs-QxcF^wC+zRiOJidDyNTT%$YH4*?;1$ zo}9pxf5be$`o)v$W?F8uC@b5()Ah>sE_Ji)i_7W5WcD62=j^x_9U5nv zmbyOw%QJhOD_*z_`DTT5|G|FtC#F}ApFN=bX!NIHuHHkhv~*4H8F}zVcv{8>NgE&k z_2|gL!p1={+e_V6w-ziJ{Br2Wel|V&E;zb&?5Dyv|75EBynB4z zCQbGBKbm)S?>-9Yy8m@&V|XHCQ5(%yEZ6L>`{OKoQXg2XyYqS4{m`Z7N*;AhXnFdy z0sqfj)St&|{$5`(`%Q&@#UR`I{7uK=BZlmn)cd#d-!EGiya zOLm_fHB*PInbD(1O+Oob|77X&7YnDmtZ`qO>>eWUUsCq5OOK3!Emy8B^L0*lpUjee z?Xm5nRq7@ebIXl>`DU@}m-rtZ=-YBF_fwAxF+HM6M%$mb))bnZ>VC@J{MhM+;Z7U= zc+#h>>b_Cja*gk3>!)X3XNQjZX_Wf|7YE0to}L%?!o~V^+lg5YYqF2K&EDER&sTYVyzDT(Lgq7JU2W*Ry>_8aI5l zRJ^arVfO>?FBVR4*lySAw8o-hiM3$sy`I}|R5jdx^|bTTYu{EZJ^X8MsP`9L3qJ2Z zc>eK=ZyGoCcw00g+ksMwlLUUZy)e(9?5D$Jx;z zt+x0v`o~=p_HSCp?)dhY@XR;m`*Yt^)Xfo0P6+&T-t@!kg!wT?d@SbuV*c&%ev5DD zesJ}Ev+<9D)q`&ZoL!$aqCgd;y?^VgyR{alFPArW)>^%u_d%ai&MV6Y4gUS>`|{Vd z?r&=KC$|Wi=h`oC|F+<1+scC0w&gR!1B|zXoz{(exBvU&u8)+)zqlW)JhZ%5M(&5R zGNbP*p<>@`95PyZR#sjdqx|gGnHT#FTC~`6!`C*#hR+?uDLqc#K3cx@(Zq*uW+imp zO!#nT#F1D33dP6WgmLb^)$1Bm9l^IB{PSb#jdiBdy+8NO+%@dU_;sOUB$aC>-WWe> zUHv~*DQ|N#%|5^5sCjDl>rMYL&pJzvtZV4Zi#juIp^w<9{D88=6UU#8YDxK`dRR_-MBU^sRO2_F`#ZFG z!^*fFx5v(@{^h~39yc}jt`=n)pM`zllm)j!zwBw7w?tWFT4~p;?v;4o0eT% z?DsN7T)tWo^@+u_@_%-B+6^xJrFrqw2CMp0YeU}N4Y?cg?}*!Lbl(&lRmRqJoZYJU zI&Axno=fKc9^aH3SMqJ%>IES;&m`(ktv8m=eRE^u$cDeq7;E?Ssb0Bm)P*I|@gzRjlPhS`9BJb7HIN4`>Qq%ZNOY^>5vo5-yMmAyDiwUh3u0Kizmlhq*{d}GgbDJH% zsh|D!w!X1*{f+*-wtQS@pFKUKA79hWn0Gj9Px09Og-^U2w*2tjj)D8-8yZ%A?6*@J z^{Q{LNdr6QRn+{*|&=vuS94(;YPbJ# z=-BW-PBz$h44MAfR;x`bEr)%uKkSQG(ZW$9wtcMZUp92z-Xi-SYu=_I^IRGTwY)TvF|)rxyR` z%cOOm$v&MnsKWT@B;%7-7mcD*Lqg78I2bP<{w(C*#!vjM&t|F{y?%W*XpYs~H^m`0 zzBAsl#6IZw{XxOeOZ$bW!c6<=pWf~tzbO5f`rFD=%ccqJYQI~3+P}wYr&E`+eiV!y z_aB|rs4ug&^)Nc{;ZXOG^EG|0Ef_IwN5Hv-+0EgNom;J|R3EPPY6<`1iv#o07LO8) zOzv~!YD$sW%i&O>cK@S+e_DYS!ifZu-ZpMR@INdB%k0^~wL{FW#^`JbLhoTfa5`esX2T z+1zniA6C|eH4ShcaDKaRwf^aqq;kpkqtzD|A0IcOa%t0eMb^_zJ_BZ!5BfMmqo2{c zVSI7u^w21m*U!fbk3Kr0i1U>;IUcz){7mt!0e|(4NVyPkWtwTjk`1OWf4Fht?p-)T#SPVc z_K9QbJG+{ZW~_hH+K~74hrfR_xb~6vi4~8`;_p8B_uE^8)=gacG(%we?5=e2$d3dw zH!L*CGCDbG;onXTXTR{+{cfMDF!1)M;yn4odDZjB_gptnB~5uSbZKG#50k?0M$PW= zpRaZvS|f^Ekn(q&!0yPy$o%Px%66~uj2KhlIr-3wSrtK_zp>B$W9W#KO52jcK0}n| zUyZAJ88POyXiN3yCd&R9D_7s#mA#^JQ18l^bKwDpU8JpHmg=JkcA|F-^ri^~F zr~lr%uU~UHviF(kf5iDmTnTu3cd@K6d0lQ-(IUJ9>B0`kk(E>U)JT z4`h=yRlm$}x}N=SozLW$6_0c&S6|*zTKHZIvZ{FbcF$;=*W!;0U;nho;m6NTzPK@> z;IAnq7XnwCM#YEqTobbF!`?54_wMX8d%5T4i3s!KZ)y{exLX*YAlW9cxQ!Qv2<=bt5k%=E21p z&wDQm#zk~gw3upSBX7xve|Bb>HbR=S@3r*Op{wexwPW8!qy?ScSTWl6dcd+Ve@q!r zG45?j<>;pZ(}Mb6U)zn_QS!m?mgW<$-tDs9Sgb#(F#V&YQf_bT$_g~U$Gom=|LjHG z2h7)cLtVgzABCrv+&MV0Y zQDNf!pH@x3^YYHY73shAW+&^XZ(rB?*2ZUGzdhOaEoSeN3p>a5e5!ohYp7;mM1J>^=XNY-)%>UX$30#AZ{?xcb#EertD|f8KCP%d z)EsfEuHf*ixt2>;#C?2Nyy;3xz5a4tRM+9Fi9YxG*w4{)4DwRG+uOD5O|0|Vu}>#7 z>lVblyLmC^>apy@i?=xU*}UHW#npnRg)d$nTDj8v+VH)zpTAuY_x9$cT_q*YuceOp z_uoVRCOw_O9No@YK*>Ebx9ceenVP z^`Uo+Iq+x06TYY4s2F|n8SDF>FW6__jAZ{AJeGYqWE>mtqYeAY!j^qLWFi|dbUZV) zn8Locv}fOsoW%MKnZ`c*aVj&ln#R7ebYNc(cVyp;aAX5VIJ0j?I2m8U+lMR{R!z}H6*pK#s%wqB!_Klqg*Vand50k^#_l~pKNC!V=<{ZR^ zIm~54T|=0K>s&U<5m5@qdCYQJI2-B~#w^{#*^p@xW;J~w8{xW$jhZo^Sqm1i5uOoj zgiyjp`7B_gXD?!710vakxsiak6tI@D5i@^gKe()7Ke|OTt68hqs98(da6dU48Spb3 z=^4$eJr!)Ca2XpDv=r@rX4XO_o9MfeSqHCR_Wse#CUiNo6D?=sL`r5iU&(A2YS^TO zDmE=h#iq_*&ZaMnVpAhlFlR|Lo3TjE1WPn*=*%^2nEM)L<-L}Tn7x^e^p9g>eb+FX zfOTv_;089zZxb6AxS5Tg8^cEUZ)aoY?qCyww*qGpvyE8ICg5Q&`Grjk-NL3U*0RY< zHn1sjEoj*VT6QoSQ3{(hKbcKln2Nf4*d)nbHaYS)Hd%g}C#P9h(ukn@wM}l?kG^GmoWu=B?h&92f0nQ)LI(v?cqQU}*+(`uTSzSpGYk zx#BSMT>dNbj5@%)Rvu#0mmgs>6n_ENQRcexD05kr&)lN(nNXF@Jk@z@rlyFE*>aSP z+nUS9Z$F0ra^^Ujuq&TUOg_on*X&}m)+RA8y!x-*#f0lqSm1^vHd~v@0ypbeXsnL; z#_VBpQij?>KqpMOAhl{a{_JhS?HE@CffchTevfmMeI7j7AE}079<^H z;-uf1O!p_V*A=tLdrq^-`%8iEZzf##H}l_E%zU*aENJs-78qO39Mb+~esPyr;I>*e zZ^s2TZ|5cExc4lZnsJUzJ9wVC{!z)C4_{<6@RZEdZstSl@nt*tCAtgZ0D*2==#+Sc0A%G%1>)(-FR-U2_^+1c9J z+1cCL+S=iRwYfQJQfpg#J3QOjSzB9~104R@0hW~&ezdj*Tnj5aTL6QFg*mcU3(XS5Z`-v z2t0(S;ekKY!50F7y{!vcdkBO=fCNQoAV33KI~O8*vc0VpQ7^Ff5ZVI#4s(IoV5>=% zdlW(d6atP=446W+5?gbqsE9(}iG^aBP(pYlAVpyB;^N`~s2&0r7dy~}0^$Xz3WQ=* z2Z1gil<0Ip9eaENU3j1cpn_c49$SUX%*0}+c0h(0;05+ViA;=+5_zBo2#6{8NhlVJ z@kSz*N#$|{K#Pe8p}>}?Ko0>NUr{v~wUrPo5A@hxAO>o}YA<#{ufbY@P%0MKxd;Jv zkJ;X&`KC=g3Qomhf@U@<5qV(1~1N@Oy*LP8xTswDKCSj=T1 zM)wUO0^#%nQ3PIyi8#|yCX56@=!^tZfHLa(ESYeYP%uj(mZBX%2_;ggQYuqQ z!7l0+@S;7QrBVr+iFNzT&Kyk7l$e^BgX_Be7XPFx6bh*%L7|i>q~gRxr4p#bN(JZ< zN&rTgAWc`QbZTX!I5IL)DN|9A$s?r_$U+>c!I!fl@mZx*ChBAfN~Jmx_*F`U5{(ry zr4lR$?NX%}T$JhdnV&tR)9D3fgDk{Ar_8cAn5B^E5_M>=#FIWzsZa>Ta)pu*NWgX( zuminZvu4$*C7M-{OHflKj|2-MmC9ACWJ@Aft%{V(mAchw#3hAVuhXGMqC^6YNmMeK zB0&MnDy2#+*_Ua4MwhA7r+b(gn|VkTGL`y_`M&DJ^z;KdwJuSwOiWaPbhQ$#&>TfFdRjhy-qwl7(T?_6EyyG2Aq${-s#sw-t`l~gHHDj-FLDltI~I65LKQhZQr zQIn}tL7eFx1B}fuIK(ogUUkh@cU7OR)ak$gU3xm0tp)=XV4q9~cuKWcDUMVDz3Yq_ zuFmroE?5}-i+Z(2wK^L3=iw{Yc?%XTlFKAYp&Ff52%sZU@B!ThPXShyNK`5RP+DA) z>7YE2slBO@xd7}}C1mO{ui5Xoe)^xRUw_TW$jVCJw{P$M{TZi!-Lq%k>3{a@*}GT0 z=j=acYF7We_~_A`%A0o{v>n7}lz;w7Trwj&`)K9OyARsZ{>jSvXODVs`kp=ioZY8O z+I>1>-`;e+E@4l`o;|yh@c75q`jA?gmI&^rD?Ln%EwEuCRjCf9{h>Mtqe!-jOs}<_ zy`?1?NmzQa=C-!5-IkUX1N(ehdF5t(!-KY$1HT^0%hz9g@yXGgoAr&4J30qie2q#L zh9+o)>B8F5($3ZjW|v!JOfo954l1r!B`RcOe=zonCohrisoA2W#u##Uz9-#VRqA1Z`}iA18%xWb}BUQU+q zf|s)M09RU&8;j1jwzt20nSU%7B%I1mSsvh?U3DMdwYPzu!os4W!V`EQLdwc3&J#(c z+ru_)jNwHJeM?7=F~oJ?znMe`tsIl*zlt370?$H7E}Mx^@@s$ay;-{R$3AR zaA6x`;=tIA8*MEGVwhSbhIyjc)Yx1M{%58g%!Iw($(avMK?My25Cv55N|HTMPymLf zY-t7usH7yvt_W~Hl2iYPJ{1&z`^6-5u6Z1NMd``Hn2<1_f6rSxD~vd3V7gA7AT%{H z^KenYDrTmuBpy3}Iu2}#*-C_phyz>#r3NJ~K1n1%0?7|rp0q&++H;d3eD@=j4g3>n z9(Z32>30_*rF1KX6zLQ_<6&!VD^Msf0M#mmy@`>jSggdvlc-BqDRy%Fz-}m_I2v>R zcO(`=wIPC(l$MsKgt9Fby8ma+9eikOBiuk<47DW+INKopt%Q|hCn7`}C)v7S#?>-p#WY^D%ejF2n)kFGIR!jNd37M6hP}*sr&7159S2qRNiUj z+$RBnzCu1!x}{KYZYy<%OP*i@s;xQvG)bZ^5!0KksgadXqEI9r%uH94{&7yBBCG(g zhlPe6Cxu3#K?L&y1{W1U2l9_`j<-E(sIPD2=<^|b;4VS;xe22BAUFnHhf;U*03b!S z7C^6rO$G&G*k2bRW@~UmsT3$+dw`s)ACU@r!wU_72o?tj5@7Q{0cSw#!zNf_41L%_ z{9>rf2Tc)a?a6Qh6tb$+H3DjFW-pM5F+u5Ie@%?c1QMYlA$>KbL!lx#OhlAYP5d+P z>%@PxiA#WZKpZ%h+uGXN*4Enkf&`IY06rBLSDZT!#&g44Qc_e}h;a;n92ojS><c) z(1MPR4w&MCQ(XDWE6U5yk;204m6o2Q?g9*Th4%&4JvhY5!b%_(CnUm$lSxdBZEZbZ z4lw0QR8nanBu*`;0dGSjhzuNn4Js)qE%L?NPZj+(eeRMU)foa_$? zlz5Mh6&Ib#PmWr;?C!&kt~V(8r%rL33wz&fDIl{#poZ#i+ZKlhjR3GTM0B#$+QN>z zd@_|z0sCtU{Yz9`O3PGZeNkR^k`q8=13hmx;j+qVue)wtWFo6=O7D`@- zTBIpJOV1D>22DsRdJofHglQl@KQBKo7U+-U+`*JjrL7I>4+X&3qrqAZ%YRa|k@&cg zxg2+mWVAp4R{}0E;sZ$_j5xrDAUIH% zN0ZKR2;uAk0ulaWRzeWFfhF zL@$3P+JQY-bfO6IA^o+ou)`u-0S8F0kP-idShVV}Qjkg3!et^HARq=J09r%e`3n>{ zwY03b08{R4Lf_TZ*@-)DPvz%6ZhekVU0p@RP=dm3As`vZsVOyt_J#(BpTx{m0;l%) z2`ei*ti&ZUOh7W}0Amk3u`Ce|=x;ieL`#zwF%eAI8XWQ-2!WzuxG`)SxW8q2K+es3 z9k6?EVeyNLPvswb_Pn#}^_$nP3-XJL(0c>NfSXe<0{R$Yyn+3tqbywzKEVu#=}$Sp z*b`w7Oa%!EGP!u2VXB1?&y|&K3pVhPIzfem5W1bDpH2SOt5>gJbI|}6A@5;pdndkl zRamqwl&FRiMQ#-7AF2K}bcz!|JsV|-AQ1$BHHZ-NuO|c`m0$=a$fWDQ|8BPtj^p+) zm|{M9xfP>PBnsUS8!dPMV`LN3WSsst7Upv~=M5fLS$XO9U{MUWon%C}#l^vrZ}j%x zaJ2GH3;A280Fn%HL2mq(1}q6kA<=t7=V9_m4w!F)x6#Z2{CJRT$3gx=sUoo(zrCFp z@eO7A0j$&K^5p{7EEVObiB$vF0q`)6Iz%(c#^7n*w;K6Ur;RH#+&vhCEsa0#yFkt86r`~TTuG7?AQhNS8Q83OH9)~m`QJ;_~ zMEuRl7BMD;J`wR6$vUuy*Wr{BF{z}4fC%0jW|FYb&<--Yz{RznG!`0YSPpb{0z0Zg z{@@l3z2MYRNQqCGkW?`kTRsl@Fua^7L+JX0r2t5y9 zvb?<1Kmd(?uGxSMixNiIyJ2I+Ra_{-oXwHbFy%u}6zre+eihG&K)>L8eP1q=33jeWw?L9)b-gAOeFQ0TysUa01|k^Y}v{>X&TnRueu( z$?#*?`)@bUhI8{k z>(;HX08qoYH~183n2leVS&64R~eYI@)vSrKPm#9s#DR~%aB!`m_ z0l13JZ@>r)3v`+~Wx|*V0aP_;$`psG-u^)l3JIQ!UMQhQU@Cs|vVed@I*makhjBxF=LMA zTr||LuWy*<9k>C#C;me|Az>$=KLsh91K}oCqEZ!st-l+al3!S4_OXo}JYJnHL7`Te z7};72rLxuOt2IA6->Sde*mxVI@!ms}rh5(d@3)XkQB+z~Onx~ZSg=2Y{>ahF`i7>K zmIwFmH8eCdJ@5~NW!gYfKUNSWFdjvDvCC%vdGz9)dkS%98yC=X;0}>(-5d&gkHiS+C@8JO6Yoi$t zlg^`-2QAI5{{BHA0Nw{Jaya_sKws6wmx!2~+gqEPn_CNtOurmyr&7q32>L1%##sMI z6hc+{nl-Cj;YM{lfA;J-3_QS6llB)h&yv<+Vkij@5yATTdpnFD{Z~%?<4zuN;}l>S z+}i2~9i)-D5xvLqD|PcS5cz-rk*5j|m0-6QnSS-P0RDEODnThxV*Q8dk0yX$Gz%go zp2~mzyyFe|a>p=a@Pc`!qZ5M%GC=4j#3|U{f7+BWqu~K@=ikrI&)+}LP_3gQkaQ4> z95|81Mfnscz5NU@x)3KsNojxaqOHBNv)@P?7X-9H0Pvd{TYF#~tk$KiiH?Yvn4bb) zvg4J5B8b z3ZVjmmb|jLwSzv79BAVrN2DKKkHU=B|JXuMrT?-jdhx{A<@NAnXfDsqEr4s=*7kxv zVBrTlhh=YJnA6k=qqC1*yiZ^I`2}(c{QMq0dCDVl{@!5}DyBKHFhBLda}d=DIHyig zoNzf}=I{}_z8W~vPNGx70;-e)23cbL6DihZu2~haWaNr~i+AonC6T58f5EY1&CUE1 z`56F1@Q{`- zT?)669EYz)y4YizM2{7K*v!P%1si)ReH#92oCU*IEX}EEeDd_^lPAgX$;t6sVplZY z$H%7#Fz_j?s36|)CoH|1$o~WC4MAZWfPb0;1>}irj1`)<&tn#&)jBQLPZi{DS+Oj@ z-TlbL26Eim!G0GHY)HTZQ<@pu+G90@_%kf2}kedeDz^;j{Yd_B_5 zMTmVS3HWc;*A~GTY>%a>7cE&h9GRvN5-|zfKSgX?NjnV)@X!oG{mG48hEV@ga`u9t z?i;{?ATNjU)T|v&7?uQvr3RFRR_cI}yb>`=_dm0tvjn))WaLN$pb_&B!v>-Mh<`|R zYW?cpmMj_`6;N5<#F>P39Ts=sTzvycmiW(|2`oP<>+b`9$4hj7Bk#Z8RF0po!fB=_ zdqqwW3bqTdT=V)fJEzK^SM7x+BQ3FKCsgTa^9=D9dk=*|o%y?Z^`a%iH_dsEpT>WF zesb*cn|Fz89pvm20f;6!^Vvpyr+(#{!O3F!ZVsWylQ z9WmgSyvN_yPT(O^V*RaN9ldaP>~aGm+uQSKYaxFN|AH1a7y#%I!%is=`7Gtx=Q02`V&if6(@8>Z7R%0^{MHO&5DOQg`ml_*1+dVty z);$DhJ70Caf=nSqGfNw+xe`hLlvw}UVFy)(_*0rj6ES>w07%8&2HDKKV+E%mZNd+u zRZLR=Mpa(y6jbRXJGR_Fzy|2wnD@<~CnR?A%<@xcX9R=g5v@#Ly-G0xsPw4w)FmIrdR?c&}jl&UCq+E3W~gBkDa zg5}{QaN3m75F0h?B6o%8g!&a?sLaMZ)l4xW+AGS-&4Wuz0Isr|klfV_=F>;TK8n19S|C1M#igVUl{{X7z(jjATTwF2V@`320* zt|xNjy1;g_r0t(_c2SWHXcrlP@ zscVFEJzUi3f9Miq0#jpKJK6x#sWLUu^Q~#PbNP1>_oHUd&c65nqUIK* ztc)U)Hp%WE2Z!O?$FI1B~Bb2uR6{gv{a(ncOA{^5SEcFFShWHjMDsSbxYR z*l>_3OpNTTBx<$#x7BMj5hK1{7Enos9G=&)W3ez?m3K+g2^ymL*cgC&kJYDl>oeN^ zY;T)3)nN)cKN^u>YV?u@Bw{pSC&~K5_%$~187CLJbb$eWUf8MP^01jDiBv}-{F#tI z@qcW;>we4BM7VzORRHGyhfueU_FPO_i1YBZJ`KLI67(MKHLdId1Ib0~?0nGz{6K%S z@@^~j9@r^#4Ntug<_gv~x4D%91K1^-6M$I&UK<}cBQfQxROx*G!N`*0Z)s_nYvzx* zSP9eK+6im-`gP~ydv_bTlhwtiUdW!WKrrKk1uhTlhbv{x6fM)70s!=MRSy@q)u8 z3f^>bgJQsrB`D&N)HzHyVQ@PF$tI#!7o5s=?)(8gt-pvx;pBqD2c>y{`ttg9R|g#F z7ci_K#&qDm`9NH5qAdFSJ(*vHhe}A^std zN+Ok+zpq)ckP8QTg+l6u2e9X3oqe3J8(>ohIR*Y<*mpuL(Ae>^gS-CkSKvJK5`raI zDQ1n*($1HFL;%}Sv9#1|q#am}J!d53sK9@rLW1pw%+-;rmUzHnq4~ow*OLE2^H^aj z?FaC_(E@y19Ap3`FGS=uzknOIyikAQJ;es7P?SOx62imPG!x)Kw4l(7nI*FAu=dGR zCd%ReBN~O|oP)oqu>wN;g$m&X5#&G>BYc(0W8vsNVW9qF+6Q`!G5Bai1L9w_Z-!qC z=nbpzuwVr2$q-@q0rRmk0GxE0Vv`VnOT}rAtew%JNy)TGsI|U7+}xDU^}?$g4*;q%o6b@7+ho`DQW(p z+$0^+eRL{0;%}&5LXI6wc=XI0Hw)B`OpFqWBX9X$e1P0YrdG z_y?$1lTiV{VU`qsRLbD~D|G_~Ss<}cr9OxqAhm40p^AYEgdFHY5CVjDK9sfk^C)C>?v-tllaMef}F+>0f0A+hO0f>K6pQzuw zz&WS*D{`Z-=Frpn&(>ZdRjbl59ZEdr8t~IIZ&Jbo&<6a}e~N7Y{bodSVmEaMiYNrM zB?S~<=K}<6?Z(fwfC53=ffv9KQ#DB7+$b|^IDC|6rc)vQi1oiRQU8ZNJwc)1{I95> z5HM}ELG`+MO7UES@I#%vH!WZO{|1Q=0E*f~ksb2<;tb(;9{nW(5QG(lYzOl(BlDdd zV#PR$|4Y-6af6(j0mj&VMw%KvBJpn>@rX-`X7JMO-RNTs(RZ%d{$a5fFH+p+CJF_0 z>g(~iyM@Qf3gbczV}O`oP=s(%==O8(*-G2v<)f_aT*P9m{#6O8MC?By{s{*Bo{sz% zihmQccq!Q$io6w=9a4bz-4ELkzv<$w`UZrF?%r-}LcpfA`N4yGjSY{1Y?>C^xsPG3U z3EhT}UVY;OULHQ?0icfd=dCS>E+MuAzn}Jhcpw-=&?v+c?f(Ed$B&^s$_lBVa+OXE z|5s{eVvPhpY=xvBOiWN{NmMALeOq}h0zttxDn>m5dmFI<2a5x&9WRjkKz=dGOWJ#U z*4o_iC^sL(r@~Sr(TuR8&@;AkyZ66nXQ$kX@_!^`e)JLr@FV*`rPpPu^h#Mbe(V7j z)BYcYR1H!j>TB#!^V9;P^@R zfSy}ZE=WR;5`*nmu9?NygQOfhj*vWigqC6(A7BFtg`3Xf+)p9Q1}RWTHW*$hmu)$6 z+bKIaQHThf*sQNL905!Q2M?s{B)bSXMf1tmLR-k5p1A0-|4ry=9}jC#%C+R~2`n(S zM5Exh!6oeKLg)qK_XO!mHvmpLoKkGT8tAvCj30#(34jSYG5C-8p9;*tCV)qh0lkQ} z-w81a=ObWr?|##CLotx|Yf$Qc3Zgsk+R4v)O;ZsH-+(9Wr+*v_cEUu4$Oz>hAmx$b z|5*PFqRlvDgCQSDCEr0Cg(tbENh}0*Y7Oqa&wrrdSyYG^0M^^wJv>H%wPgXbFE+Nl z0zY2Cao`jjC*?JWkDyQoKmgAGfc{Y`G-f~KTALYT`wx2ox@vto@~=R8p@=&>-DGpx z!$lO&h7sd7ytEVxnVSuU)D!fc(C6HG$UQuGPlotU*@^dts2dP^5{}R)fFS<_<_{@n z81RY#*#ALNuugaIpk5`}QBqontpgBF`o)U@u2vxE&N}F?tngB7b(@k&4<{iI(c%u8Ql5zDQL(bzz!OhKbA=}{!yMket56x zF??afC=J06TK>^=cQU-2g$DFc0Sv>C6V?{inExo#Jy8*f{7d-1ip&F<2QeCU0R6@o z&V4dm)B?to#tnK;!K=;FAFdHKO zOhEaM2jP9GTxkDGtWv1b(+;Us!X4b~{2$p!rgCXgch_nRK+pu+C_$L=`?5(uNTm6Io7^9)=-0u$MvE!{D=u1*T8fCkKlNCWIZ zJ_@wYU}p(`Y0(K_hWYKD2>>w$`KOd}q=UgxE9{VekJ(43|2;7c0hy$3Ri%2^!A9n2 z3GIV(-N{in%>Dgy}jMzDd2Tn@PLlStzw z`t3UleBXh*R64eI}98k%`|IPn3Gy!@8uyW)@Adwpu03;L_^Zp~=h@c+qZ$1Kj zQFoAiPV)g@IPpg0L6Rnx5CJ@;mbP!Pi;MhQ4~0^%M*c75KU!fefXNT(=qg1Lv5M55 z+e}dmP3PU+G4vdt!2kHDfSb2rf1vcVvyux7c(H+JKp-WBm-jkL%}ciN0mTO)>Ea|S zd+hkp{G&_6{=b!2fjlT2Kj8V-gq=nn2oY^9#Wn&l6EfgVDPAzBxXF7T1IC!gY%n_@ z=guRVe%rejj)WJzH?%J$0%!#V=0gK*vHn2BU6qDK7xdpsfG`}=uT(gFvx8>MIG(v8 z5^XCfy8wQZ*nu4soG(WPele2omInmn+(MWR_>LV*S-E_+*I$*5WB?5*$RL^UgM#<% zw~NAI2e5|P8WSFa`5z&7_@AmYCGvkPu?>Lj51f2Sl#=1iWv*m3HvEmxfl@@y3ip!%qkMZ-MO( z%zyf7wMvr2g+wcSq~CMYl(s{oj}jNCU{iNf4mN&yxE~HjdrRZ3o3{`EqQd8>3skU% z<<+~-4ipu|g^(7KbT>}67I+}}Co_$oKQOU^F$R9P18PYEuYxC_$Dr@-13~EI6 zQe$z_gTiX0?udY3_q7%Kf3QWQt=#-_{)6uS)BfCcN+JRFm>3sZ90!u(`~@;@#5n)M z&!4C>6AvhK!z?V#%`MES3^p@2F*P$YH#b8WjDKb(ynOuON7x~N*UgcW%Aw$MdmogK zd-6KQ#%6;}%}fTHnxdJRsfh_16Bzz}u!-13Ay&cqsuhTT_co_s45DG`w9B?@_wUlK z_3`obS-aN9mzQ<;C?iDijN}JHr zbM87H!DLS~_3`xa5a8L=fRs_g#bDOmY57bg1u@DbB9w-pn<1{ID zm+X=3i9IG9J(Pd|oZw9IHOtUr{}uZm9;Sx#XKM9Xi+yLXCygUo$je1^1O@vNI4mc{ z`9Gvc%5ba?S-W)f5r~9hH@8Kc4$uG=xL`#~-y)-3D)RuTIOKQ?)kV8A+pMwDEI#T7p5;}y3D2W6zM!ZrY zk;@iIA|u5vC~jZ~=#$8C&@K`g#i)lPXQ)o%0~PoK1UivuILIiGd5HI9T4W`rE9m?m z_>ajj!?N~JBE_RXfs#&~AvqucB;Z9ZRjA;qsdWk@h$C!><8~6cQmI;v^9nd_C!944 zWXj|yh@-=zP%@h|0r53TuR)5BN`?3WLj6d#18sEv5UtbCSp0JU2wesnTS;UIyUl73 zqar_~rozcZk^%^!C<#)NFi+s94vvU`IoPQ}=!i}^0yjD=!8=p}ek2osK3d9SX_qMH zbxDL_$3DF3|Q!0D{?akAHpv1%k zv`(kpDbRL+4hE{RRKngdWTyuxByNE;C3*zv60xU;AXcJ|enI~sOys#B(I4L<+!2ZG zZY;Ir$h$|;9X8#&S1ukv=WoqxDH#U`_kc<7C!>;&@+zDgmd-64MAf91FZ+MWF{Ia0Xz|9Np)=r+Ei@1(Tz!G2e4pXg1hZ zV0R-EeFxK3YMgycz_gfo5R(JghHdFIzylq6_-jZ}2WD_G0gM99M3M%^41J_7(a=#P zB&6#OrK2P0G7dOFr;yv6m=4A&6bWiN)2Wa{QoygTv)`dG8$8M4EY6Y2)Ae8^;2L(qpRpbM*3;xjm<&qPJoG)N{9)E-Qyly2f2 z=mixBZqNZx1$qvx#)?}amCMfB`kM8y*bCOf1qS^R9J57E2r)7-4Iu$=0^)-_Gx3hJ zKu-m@XtIVF&?%`5yNAjIC=a*;cIj#S;BXmbS3_Rl3o5BFgka-kI8chAET*HxIF$=7 zoU!il!C*tdTrt?xgr4xglbI<#qL|{d3I7SR$6)%6irHZL!BF1>^-NKvyWrcwgLz9n z7x5=l?EZ$o@=t>Y5wPwXK=^e4|9ko$2mZ%_|8d}d9QYpx{>Op;pKyTg2@A!e2#^2X z6E*}N-k1M#PuM5@2eMB-|B8KXX2S;lIED=zI*xrgbOP=No4~%buww&<*|V>#9N1UG z4flb4HInWFb7q5Z7uevjQ`tA8rn9d{&0yc)PO!n&GugLe-Pw0zr?KyFPuP$#F3ikk zI{VQE?>KM+3 zO$}qir-d>rr*JkL4~wbunWfWwHhlVgX6}mbXNEI#XEC#!E@s1BBhhvqvv!}yM)CW@ z=ChIBVm8(*f{pQ!u<^c9euvn^02$gU`2At#u1Yq%`|hw&9xK>So>6S1S2P=qyTc~< zEoC-AayF6f4)a#B3BF2Z6S9KY%~3LY(K6iGwF-B2t-@Vh(aa%uIdhzcN5m>NO`_uW zg;~y81N^_>4l^wq<-Hnrn62S=g^l)IkJoin=8N zUIMen!zL`5O%NsFb27hEY~p+!n-q}>dUxZYV-ptaVG|do16Delf;+z^F8meujs40d zFUsI|jyVLcXAU7+Hf`Qo+&8v{&A@$Qj$xbFv`8&;!hK_IOV%;xpEomCMJyBGzA?II z%u5-IyVG_sXYmf^urL{~Nw{Y$jX6nD+0;d8Z2BS{bH$xwGnLzz7w#H!kfihb#+)PZ zD*cr?MrJVQ#dyX2V@|k#%$7bCUnYrpmK$7ug}^yzDUUBRj-qt;oXtW_y|E zsy~>+(j#ozvOk$K?j&Ge&oeO-et* zrtCk5JIwxO4*GwX!`?H7`@?>(Fx(yXM-}c4yTsg%*07m*wM=l#aBrAr;Y~IZcZPYL zyv=6e&M;w7J?;&=gL}j78SV``)4+suZ&>+#erK3JzccI!3&6c$ewSL=9NZZeTKk;e z6V}7Rv@aDSDs%%FZu;uoyEh(mYZ%?@)vFhN>_e{~b{D!dtXCiU=|fbZ+rw~|7#@ZT zzgt<6uJt&kl|bHV(Wv^7r%s4|fOrFvZbk9KLn1nc|LG zsB4KThKBf(H@CF0v9z(oGkqUr)6;aSC`>F(~2<{3`1 z@B2EXSni9I07XI>F$r1O_W@Mj|j?m6L|Xb7J7LLC4eIF_j2@f zba40f1W-qJkVgpoB|c7`{*rw*r!u}ba+hV;WNV_LA|sqE`GywFx6iORMq$&UT3uVbVt*XgWA z6(!L`A+8do1u8Fp1X;WhW{Hw(qO@9kk0{SdgnAYuriFj_gnr>mjYcky!V{WDNutnG zAN&xhLVeX~rz<(xn$P+=L`t-|PKBDNjBKq|ldZ{)#U)aaK!QM)CQ`l%U&>b!>5-AZ0-&1g`0Q+LtX8GT$aBie)?|R;eT{6ua!vM`JN|`Nt{_dk z@N8aQPHtf-l9o>uX6MCcl%6fsu9R0)+-hn;65rXg*oH=j&Y!>A)Plnb85w!m1*JLJ zxupff0HiykoXl`PjSqPlv69dF0=`C@mlK;a!*#YR;)cj!4D}QE`3VHBuC4-nGh@cI z(Iao&y4~FIY6gny4426xe=M(Pdi?4Y)i4yQPVc5s8EXTk5$4#a?~NRNqEy*=c}H`8 zO`aD%52dEI_Hs>4O>JE*p08fNe(l<&NZQs<&5!9|IKc<9=-{~xEp$#Czt+{(aqvXP<>YVxdt$=8sHO->Z;1DJx}ON&l`HbCu#27ihGn&T8nbEj)%j~ zCy(~`iHge5YO__)e}6&+_`%5>IXFZJ(2|;0S5c|NzZcJ+Kks~Ad1z0na&B4u6MRAy z1L-$z+_-u3>ZN%AZ-6n{$48}ts>gyqmR=fdY)*ERW)8)z3?;dyt`6)3L+iK{E?ugs zy3~fmfsVFAY0-1b>szpoKFV6!a+;5ot**r zD9IopdEUHBppC=71_;EX>gp;=OnBa$7L6Pc@Cx7KhgxFfRfyoSL3;CafIsgiPf1iH zz-RdP?PcR1rO7)Quhq;3V^DB`1@-{LvM!PEy6FcbC{7i4@&XxGI8D{bRR?$t-Mj|g zgD7gQn>SAsKElyUvMMJhLmP$hf_kS1(^gr-?YQ9$3P|M%Xxd$zgW^zc1`hlr~SJ%@Cyn0aYR) zCCv*LWpVLU6KG(lu7U38A3l9WdQSzq!@*;sMl)A{`f>`j>c!pV-v4k0|F{ZDB(%r;bD70W=$=0r@E@9>QI_eS%EZkln#8) zc~6Kgiso^x0S=HiFKq9%t79D8VU)?xe{bpt{n5fyXm($&y__Bt79O4q=;3%E1z=CN zWNQF^H>{2!v;Fn!F6tKHxOTk~94ESoJrHf!-s{({jM=p+E_?FMHNh0v2~j4S2&#;32Kn%JJ}?1UwP0$-~Gb3k=ck}es4;bCFv7!cRS zI6Xbe0befHLV+^EZ;%z)i_0It8{P$y!QRURy>btzHw@dFn$FHwuV21|`T+G_ z)Imu`kAX-Owil!M>a{VB?wCC_v7rAmM@;qF?0CS3iM@WUZf{VSC((p)_EwlMpV3g@qG?XsDsRC`2D!cK&u7S!60T zRaF;SUXY*xo79G=fU;q@Tqd(|t!{)9xDKB}Bk$K2rbxaj5Bv|saHP2i&zH~xki;A7 zlEVFh(i$HC;41_C>Z%KeS~^IR2tNLiK@1A2H1Pg1rc`SuM=z))20*{QHr{Zsjvkd~ zgkB|ugE@gdUZimVrK6IZB=QU5S#z(r(%04kek)Gcc6E`2xRd}si-rn@#C6Oy)=myk z8W;#kzrMrVBjwuISkQmXFdLxw-xfg+IfwssWY6 zBAN`6l0t%mgMzav4;?y`Rhbp!7evBA0r9~^Jv^AK%F3!sgaY=#%*Wk33T~{1;Cn@? zwQ99cJ{pbp7|NlnDsI2#VaCBw1{gr`b#qHiOH0$Ixw*Od1_dFh5DAOH!G5Bu>dHgd zFVySN_z<{QTla(GIQK{ls>rCmAKLh1CeyC>m^pGcN-8}8$RTjF7A%4>3P*lqcu26X zoAYF6IcFLsd0q!yNehxJuLa!*T8sEJN1MfB5LpqlfqJKYIM^#k0rF%`K0s(1Y5V z@E}kh9_%|~`s8xB=s3fMtnlVX%`HK}M1DB@2RNj2%PQc$cXqsZ{HVG4am^3oY_RUY z`bN{Y*A!u-JYE|Y(f$%iEzjCt!brmUzU=7efD;E@PX>!belwgWS2R50z5{;k!0D%# zL10c2)U`S*6)soH+kdINGk(o=*Ffg?l214 zSkOPkL!#Ek$E&r|_9PkLU${_Nsc&w9y?>7JigL(pIOGSnkTeMcE7;ffehXa$MZ+BU zxhDy;2SF%r89W%Q@wM?-_4V)T;1#h_4fyfX^r=W5L$?WJ)}dzTLuY3dhD+^*G`EWS z=2x$}VCX_Zl0t%fr#Im==BqAZ5B>oKN|jzYH?SP_(Cif)Annn}RoebWc(+m$zf-N9 z49}axr^*o819GLP12ynXZryGHy%@>R`j9|3=Z5=q+8um=9EA>h6Fe+{vGP)2; zkYIHz*Yq`VaFnRycE+!abJp)}xYq{Rpw*=;eOl9FSa@>$;rl4>Hc=ip2cHxk6 z`tTXThrz2N^RPQwSz$=te*L=Z2S?0`fFHT4FXl(NCQcitj(6F!yYV5d;xMqP_oPO{ zU--QuD2cE;= ze$q)R99kLtK!GBIe6fC)YhZ!a6a9A~{0>s&L($5zh8N&CiLNHZ+4=T8k~~xsRv~Em zHNmIjyPbUaUC>9Dm)`>T&JHea@a${HVUFHM<1v2w_Zf!y zH+JRDmD-=8=c11!Uouz~_rZ^@8catz9C!BhZ6^M7!Q}YD6pbpsP3YW2RWKpYt_o0( zhUg3=f=R&CeTvX4{%`nKG`~nNkasSY|Fk`*%=@2Asm^syYUf0 zt-a9H_>i)6(E#?DCKybP|4)109u?J*^}8oV1#Cn_W8xD;2r3|;E#V;#dD#dGEnq7k z50OL=Vn<9P2ng6pYsZcX9Ryoq28_8zG9RdmwOaWM2oqo$w3BGm#F#LN#!*HuLwIQ7 z{q573ICtIu?z-Q%?pi6RKIhb_v+KQUzp4uK;Lz~T4>|jWUVtAS#{884vV!r?ePJ{h zdyZA+Z!r7-bm5Oy1y!pMnTgkwl{IO0Y{JZdI^h2G>+sLRjB8OhR~bB}M;^G0fPeXA z2%E<|806R7S1~)Xz@ul7xw2n|(5r8Kdw1x`FHZuwQvyMA{_`}N@*NSt2Lg1C$cUJ+ z?dPD}u!Ua|rb1BCNSR*>uYdW4M*`+wE&+O^fc<|N`sY9X@h|>%fj{$)XVgU)Ul~~_ zKwdvXMLKHPffusQ|@3 zFi@5SvLr7L_$MPH?@SAl0R3}Apb&3B=pt}*selfABM>4;A_*yej=_BeeRM;r5R9tB z7Ei`&OcbI;hOm|cDcl5og8B!8tpI%RM}S{=b}h>hQ0Mr+25RYwK<2<;w(_Wn(5d|5 z+7~@6OZof?7s`|@iU2aqBqm_?3ZxnS7e)qxerQArR-yn1D_fe%n$9zQ%dmkF_!k5y z$ZpgEBTaN5kZ(f&W}MKC{wx-IYQU>%gEfH;57l*~1U`mq1xwV*&7*jY!IJjX+9}GxLRtJqke$DmYcw{c+9R`wt&Idhp=U&%?|o4gKp8_AmZim%!Y$(0lPg zYRYAy0H|J%U}+ZW2R(@84~nA3rWVK_1oq;_jnmvQM>%-zp~o?*KL7dgyCOyzu}@o!o=7MBlq*u$L`!80-8kk{ruya_a8BeMs82D zi9XjRnxPVnj1rjSGeZ5ddyP2lBQcfj*=oM-D!cGw6{`N)C)Qx2dEAv1M-?kPga^g*bMiczh)6jbujh_qo z=Te}3|Nhg!ufL-IAhlmG5SURjLC4@Yjn2%xxKKxFE)co_X`ZcP`8K3`O;9j2Zs2#L zE)B>Kd_GT@jMs0VeVMxE{>i2Jy!(FN&ma@<4vt6tH6wZkH?iOrLp-TC+jO>(<=cuf zXkyM5)y0p# zAyez10$D0}^Ex^PbSzNtI7LNeL4E?L+`a{MtlueP{Rm!eMDB0!Bqq#sT>KjlFklha zw_wN~V@HzvcmDqOA0Iu2W1wgwG?Y+7H?AMq$Pjco_n2r#`mCQ41u`aWYO1SaD|zmq zEWx?{C0Y?31tJ0<=PRdcun{7Q^cej^%D}Wbz(bPv%}qo^lRz~2C4`eG0Qb=_8N_>a zU;q@5&&wd`YefAlU*hg$Z*RZY#lwZ&Lj1$cMbM0C*7r;x1-PR>a|LJ5-z?%^w*eE&8KRswA!j{1?-@!;48A%WyHuTvbEC4=*Od^ zEjsA0eEX|RwpxZbG0AU}ad3Ul1uPP&BqjU1)@2 zm6ZYztYono8OnY9MrK6gpcObQ%~-=)<%|rhE)ha_=>#gcickfpT!AzbPpjh z1jW$Y3i9H!EWi;oW30z7gC-xDW>rBU5-TgrgMI}V9vOj_9y!N%h=ep0oJqJ#!58Yv ztVL0^%iBQ+VLYIZ0(4^&S{_w*wyqIcJp>lzsWs{{O%vveJT@mN1Y-huGG^DZGfijI zd1bIW09+_Zn*axNgJ98sRL%!~R%d4y8}*f%!SEPpY&zT4#ClH*I9!{W+V~2L?=->+UKop`tQE)zLEbMda1ZQn+ zXE%ClBRD%7J6z#S?{RNsC4#epLoh z_{a5+8u+6I{-}Zf>Kb4>WjFX__}}c5&GGQeJ!hvp-N~C~F7Tn53w>#(^KzQWcF3?j z=Cg?Bz?OIp+Z}s^!}d6m?3PB++}EUJ|5^;q^TxTszH4coj||s!L6s>?4n8*bl>=*dxYdN9-Y0lE>OTB#wob zm5_Lyl3t64O>x2=^4qWnHqZO`-Q<&{q-9%_~`hCRvGx@-F*=Gyvgh$Upj(8JiBEPwt z0&pI3;MTpcPcESdc(zlHcnjwv=j^3bI1f4KEfqy>E2CB0%W!`2I~0-rBe+WBfc=;*vdha}WRW(!iE_?%<<4Bx;EG;peeJtBk1-s*F zS_9kTIF*j#_a7q}&OctS#u>;s=Xk@rAHdfNXC9~EKJ{QNrNI_?WBCc3S$yKR^N%;< z{A2H<7ik&JHC_fgWVTCYd*r~{zfxe`XTq7rp?sF{UyQVZ&oagt#*uuE@%ft+343Je z1zh?3;!k0h3@?QZax8o_&M=OFUxPD@rJXp#7+(6fpD5Pw6UBAkCz;_M$#9Lk+(+w2 z?UUETMma&SQ^xg+hk~8*n5kwKIC&UG#&Bl%8)t!q`ND&lh1s~V`2X!>Vl#`$V`hkb zeB6D+?(RjmrB_HQ>jc>!pEg2^G&h7 zUNqK6sh7&PZ$GqMzC9s1d27N}=a-#V81bnqf6sOcApvLe4GKnm88me+{4-XrLhX)Ov?LxV( zB7U_tv;uw4)N-@Z0U!M#XIkx%s^hh_=TNHZFl|N1s}2q!A&!oIVOniiwV}4K>UiPt z#t!3TWxW#pU%l^6@9ppI-ub?_4Ii8g3w4--bKV}_`TmYySXiyGvGD7A19(7u4cf~r zF8Q$YCwB&)v_2UaY{SWS6?3NF8W;%*3hH|}98`<$@ZFOqtu6QZ20C7m*DEb8e3Xa7 zxidDl+H*63-MPLemgMG)^;3WC|u#q zzCkTYF^_w+vD?tm(GqmyJ5=t>WKFsy#`|F*eoJfNcLRff&mUJH{v2G<`7RwV^uGm2 z0|rxk)MsSj?I$CxZTNkH?(c|8MMX%^Y+TXI$Ng`74`Yg!w$4|idL`qNeUU*o9}cu0 z_y3+VT+R6i2?<&@`zF%q>^O1}d1-6w;P}mG-#B%-OX0VJ107Z04h$QOABHVO;z2m;U`c0mO7vwxxG5u z@UF4&Ha4F z4;W_|?Uic1rG-p?UiuZ>X!PoeSAz-#SJil_y87ft$Wk?rCLX`~^OmA?O>;5>zl_l< z438?Pm~Maf-R;}G9XuXQDe!QbrPS10TBO%E%klkXNf`HijQ2K1RuB?Ce28Jmv9;9_ z$z_Z{JEdMPvPf4q3;2XV;T7(_MH$Yg>%&df1VwKesoy5X6TNVQ zd7mQ#Q(C%EvIGRCw(%sh_9u^smI7O4Ls_mYGFOB-|M^< z7O=4vcIhUpgT-1@|Ev$Oj<NCMAWA@|HoHR22HgJ__2bq2M>v;4k->_)Gco z{H2m2!CwZ-Ram3CpF+2*1wK;(J~J{$1zz(2c+Gc6l6!z6a@7>I9sK4_4K07YoI*0* zMSUIu->9XKtO~5P1@HNK6)k_Gl0vhO2t4SDH!B4mbVVNc(4B`Ua_3=MRalNSvQ;F> z(NT24L5eH-oewqfpdVuW?1vPD^|QfPM;o&3G==7TLMwNbQ$(?rR+k*1)yg9jv+EE= z;W@6joMfdHv<~ZGqf06&T3JOgSQ9JVdz9k$ns`)RADgJEqILUp;7@BPQGJZoKgX*k zfj>2u;Jgffe-}u$2=35kvwX=~ezw@jyZGWd|teuVRyhAZv%&UTD1&{h0 zuiEnfyy^p5ccl+J>ObijuexEBPkqtGeEfKDre+RfVq$9Y%9WAH5i4Jf$c6qSF;Si=&up+V zi*1PAR0B)yx|*5=H~VsO9B%g4)xjpOw#L`DA>Z6AvB6hWda=iNrK?MOcerUw`lAuh zQC}G^ma3fP4d&zJc&`d?#$4Lndh*eO^t=5%J$UF+sY-3-XU)dPHh5q=y3&hy-*r-R zw-2-l9KKeS&dQXVixM05s_;I%`AS#2CjCKwe>XnAsAA`vDHq{=osj`ZntL<=-rhgd zW4suSPr|!G()=2ukz<#h*7W|`)6+Hb>uG)}?J|Z)b4BK>3-=;DmFmzT)gb`y zZtw5MYl)<*+qf$;-+cVqTsczgVF;4SuCDI(suF(P+TPW*OJ0ljkq%olhgwk{mBcpi zWM$y861;{A=1{Y5Vy$TW+6^~v-@A9WwHvQr>3#I*?p;Z^>ZGRkZtq>!TshL;=x}dX zKhodTC3)q>aA2To->)iT>-~|Y6a6D=8*D_YcRJkdZ#wayzrB6N&HfU}Os>G@6DPEf z`unB1Hs))$&+Q#*(%c{E=}!M)L=yN)??`uhy5INx!(G0@`{cPd`}LYf{l*@<-u}SA zmwJ)Zmg{%>Te|{1&mw=xRGObfo7bUZW!9`69sYgJsJ|R}V@h z8TobO*I||FNOw1zyM$!sTA8O7f;qy1Kvk)#WZ9vv_CpfYA(e`QjJxFdR_5}C_nC-B z^^~}}YEGU!c?eC52$`im60b`U0pFwisd#^-G#o+A ztr}#jsjt5o58>fgt^vM{DDiB~l~RBVzi8~<^212$Npyf_L`M?b{^s(=-9myFjXhoI z-wh4*^>;n%KY{3&zd9u9)Q(`K5aai{=-mv zbALaVtqp;;xeX$-*t4;lHtnw2yLb2ASS*8t9nJ2V-Me<}-sJ1+*^p~4l2

<{!t# zdGgG)a{1b|iSk?wE@^6}T%MoVAexfckel03o7>RPke{2MindnMpQ|)N{EC(X%MKperGtsOC@GfLAa{-OFT|h6|yVAIME@Wo6 zh-j_{5#;i;(2pi8^ri`me8?Jf&%ep*-Mk^6_b1Cm0W{MEdxn4(!loN!DGnvkYZ98^ z8%a~dVZX`qr(=(hXEJ?SyoMmaCJ-Y;UQtBYAB242z1QIyPc!gtws(xMw}>s%QqTq1 zil5O_Ysg-pr`8hFQx2m#fQbQ7G%+}iEF+T08uyb{ZlHw{8TRo=1d*3a6uJ?96OkmH zCSk9TNfDc9cGO0CDJBzs3(bkyOcU0X({CPUhA-*NBkc0g6!UtW%2PU+^fiU1Fjp?ixc5uhPd=kEb!W)67v=0DSH(Nz2Ja5Jws#8e4RVw;OF0YO0Mure|k#G?>!~SKc3R6`%g*s;3;kT=Tpjf z_>{8X|9^8&pQ5Z{TU%R4Td}PeH}H;l#LWzGs^U#~qFi3gG>1GdNRMK%ttwGf zSDd3LRw!y!3OK$^JRx>e$tx>sE}Yk!86zheOK}ixO?l<|lVaNgIoajqH5V>87^jMQ z5MEPRnYI3;qpd3EOm<~uwSKXU(J1+ZgDcOhQHjMW#fAUKF0ZV4*%&VA*rThg%>Iw_ zu^gUr;nOBW3Nr59``Ky)pSf@$Muq$+Cd_{QFO`)c)8+-Q&a9j{#yaX8r(2hZ*}eWf96zBa;`|!{cJ3W(4tR-Ga^uG3hO`UTMz^Vk=nHGj zja~V%bzb5Fa-*|b$3gu(=NK_b~AkDmRWu@?eb^sfG<9o zb8zRL50TN(($Y*^{<1fJ55upk#n#g0m6bEcSqGFJ#*3zwPuC;-M9!xiTr-YmubmbA z;zG;;AMpvr8B{~{g~>)|clW=2g8Iom6N~t$Pp;?-(;zr9NKSLbmB$9u%a=dNi-Jz1*aKbq+5MK+FZG{wP(rnq|1j0MX`65EEXlwv_;Wme zBbw%jr8EUPZ5!;1HO*g!y|Y%6Eo26^uf@?^%!T%t3+MT+r+I!G=uZoi$!2K^O%+X Date: Thu, 9 Feb 2006 11:47:57 +0000 Subject: [PATCH 2396/4131] time passes on and on.... Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2480 --- acinclude.m4 | 2 +- include/bios.h | 2 +- include/callback.h | 4 ++-- include/cpu.h | 2 +- include/cross.h | 4 ++-- include/debug.h | 2 +- include/dma.h | 4 ++-- include/dos_inc.h | 4 ++-- include/dos_system.h | 4 ++-- include/dosbox.h | 2 +- include/fpu.h | 2 +- include/hardware.h | 2 +- include/inout.h | 4 ++-- include/ipx.h | 4 ++-- include/ipxserver.h | 2 +- include/joystick.h | 4 ++-- include/keyboard.h | 2 +- include/mapper.h | 2 +- include/mem.h | 2 +- include/mixer.h | 2 +- include/mouse.h | 4 ++-- include/paging.h | 4 ++-- include/pic.h | 2 +- include/programs.h | 2 +- include/regs.h | 2 +- include/render.h | 2 +- include/serialport.h | 4 ++-- include/setup.h | 4 ++-- include/shell.h | 4 ++-- include/support.h | 2 +- include/timer.h | 2 +- include/vga.h | 2 +- include/video.h | 2 +- src/cpu/callback.cpp | 4 ++-- src/cpu/core_dyn_x86.cpp | 2 +- src/cpu/core_dyn_x86/decoder.h | 2 +- src/cpu/core_dyn_x86/risc_x86.h | 2 +- src/cpu/core_dyn_x86/string.h | 2 +- src/cpu/core_full.cpp | 2 +- src/cpu/core_normal.cpp | 2 +- src/cpu/core_normal/helpers.h | 2 +- src/cpu/core_normal/prefix_0f.h | 2 +- src/cpu/core_normal/prefix_66.h | 2 +- src/cpu/core_normal/prefix_66_0f.h | 2 +- src/cpu/core_normal/prefix_none.h | 2 +- src/cpu/core_normal/support.h | 2 +- src/cpu/core_normal/table_ea.h | 2 +- src/cpu/core_simple.cpp | 2 +- src/cpu/cpu.cpp | 4 ++-- src/cpu/flags.cpp | 2 +- src/cpu/instructions.h | 2 +- src/cpu/lazyflags.h | 2 +- src/cpu/modrm.cpp | 2 +- src/cpu/modrm.h | 2 +- src/cpu/paging.cpp | 2 +- src/debug/debug.cpp | 4 ++-- src/debug/debug_gui.cpp | 4 ++-- src/debug/debug_inc.h | 4 ++-- src/debug/debug_win32.cpp | 2 +- src/debug/disasm_tables.h | 2 +- src/dos/cdrom.cpp | 2 +- src/dos/cdrom_aspi_win32.cpp | 4 ++-- src/dos/cdrom_image.cpp | 4 ++-- src/dos/cdrom_ioctl_linux.cpp | 2 +- src/dos/cdrom_ioctl_os2.cpp | 4 ++-- src/dos/cdrom_ioctl_win32.cpp | 4 ++-- src/dos/dev_con.h | 4 ++-- src/dos/dos.cpp | 4 ++-- src/dos/dos_classes.cpp | 4 ++-- src/dos/dos_devices.cpp | 4 ++-- src/dos/dos_execute.cpp | 4 ++-- src/dos/dos_files.cpp | 4 ++-- src/dos/dos_ioctl.cpp | 4 ++-- src/dos/dos_memory.cpp | 2 +- src/dos/dos_misc.cpp | 4 ++-- src/dos/dos_mscdex.cpp | 4 ++-- src/dos/dos_programs.cpp | 4 ++-- src/dos/dos_tables.cpp | 4 ++-- src/dos/drive_cache.cpp | 4 ++-- src/dos/drive_fat.cpp | 4 ++-- src/dos/drive_iso.cpp | 4 ++-- src/dos/drive_local.cpp | 4 ++-- src/dos/drive_virtual.cpp | 2 +- src/dos/drives.cpp | 2 +- src/dos/drives.h | 4 ++-- src/dosbox.cpp | 4 ++-- src/fpu/fpu.cpp | 4 ++-- src/fpu/fpu_instructions.h | 4 ++-- src/fpu/fpu_instructions_x86.h | 4 ++-- src/fpu/fpu_types.h | 4 ++-- src/gui/midi.cpp | 2 +- src/gui/midi_alsa.h | 4 ++-- src/gui/midi_coreaudio.h | 2 +- src/gui/midi_oss.h | 2 +- src/gui/midi_win32.h | 4 ++-- src/gui/render.cpp | 4 ++-- src/gui/render_loops.h | 2 +- src/gui/render_scalers.cpp | 2 +- src/gui/render_scalers.h | 2 +- src/gui/render_templates.h | 2 +- src/gui/sdl_mapper.cpp | 4 ++-- src/gui/sdlmain.cpp | 4 ++-- src/hardware/adlib.cpp | 2 +- src/hardware/cmos.cpp | 2 +- src/hardware/disney.cpp | 2 +- src/hardware/dma.cpp | 2 +- src/hardware/gameblaster.cpp | 2 +- src/hardware/gus.cpp | 2 +- src/hardware/hardware.cpp | 4 ++-- src/hardware/iohandler.cpp | 4 ++-- src/hardware/ipx.cpp | 4 ++-- src/hardware/ipxserver.cpp | 4 ++-- src/hardware/joystick.cpp | 4 ++-- src/hardware/keyboard.cpp | 4 ++-- src/hardware/memory.cpp | 4 ++-- src/hardware/mixer.cpp | 4 ++-- src/hardware/mpu401.cpp | 4 ++-- src/hardware/pcspeaker.cpp | 4 ++-- src/hardware/pic.cpp | 4 ++-- src/hardware/sblaster.cpp | 4 ++-- src/hardware/serialport/directserial_os2.cpp | 4 ++-- src/hardware/serialport/directserial_os2.h | 4 ++-- src/hardware/serialport/directserial_win32.cpp | 4 ++-- src/hardware/serialport/directserial_win32.h | 4 ++-- src/hardware/serialport/serialdummy.cpp | 4 ++-- src/hardware/serialport/serialdummy.h | 4 ++-- src/hardware/serialport/serialport.cpp | 4 ++-- src/hardware/serialport/softmodem.cpp | 4 ++-- src/hardware/serialport/softmodem.h | 4 ++-- src/hardware/tandy_sound.cpp | 2 +- src/hardware/timer.cpp | 4 ++-- src/hardware/vga.cpp | 2 +- src/hardware/vga_attr.cpp | 2 +- src/hardware/vga_crtc.cpp | 2 +- src/hardware/vga_dac.cpp | 2 +- src/hardware/vga_draw.cpp | 2 +- src/hardware/vga_gfx.cpp | 2 +- src/hardware/vga_memory.cpp | 2 +- src/hardware/vga_misc.cpp | 2 +- src/hardware/vga_other.cpp | 4 ++-- src/hardware/vga_s3.cpp | 2 +- src/hardware/vga_seq.cpp | 2 +- src/hardware/vga_xga.cpp | 2 +- src/ints/bios.cpp | 4 ++-- src/ints/bios_disk.cpp | 4 ++-- src/ints/bios_keyboard.cpp | 2 +- src/ints/ems.cpp | 4 ++-- src/ints/int10.cpp | 2 +- src/ints/int10.h | 2 +- src/ints/int10_char.cpp | 4 ++-- src/ints/int10_memory.cpp | 2 +- src/ints/int10_misc.cpp | 2 +- src/ints/int10_modes.cpp | 2 +- src/ints/int10_pal.cpp | 2 +- src/ints/int10_put_pixel.cpp | 2 +- src/ints/int10_vesa.cpp | 4 ++-- src/ints/mouse.cpp | 4 ++-- src/ints/xms.cpp | 4 ++-- src/ints/xms.h | 2 +- src/libs/zmbv/drvproc.cpp | 2 +- src/libs/zmbv/zmbv.cpp | 2 +- src/libs/zmbv/zmbv.h | 2 +- src/libs/zmbv/zmbv_vfw.cpp | 2 +- src/misc/messages.cpp | 4 ++-- src/misc/programs.cpp | 4 ++-- src/misc/setup.cpp | 4 ++-- src/misc/support.cpp | 4 ++-- src/shell/shell.cpp | 4 ++-- src/shell/shell_batch.cpp | 4 ++-- src/shell/shell_cmds.cpp | 4 ++-- src/shell/shell_misc.cpp | 4 ++-- 171 files changed, 257 insertions(+), 257 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 697e36fa..7ee06924 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -305,7 +305,7 @@ AC_SUBST(ALSA_LIBS) AH_TOP([ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/bios.h b/include/bios.h index fc015ccc..d222ef2c 100644 --- a/include/bios.h +++ b/include/bios.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/callback.h b/include/callback.h index 266c4faa..85b9d246 100644 --- a/include/callback.h +++ b/include/callback.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.h,v 1.15 2006-02-03 17:07:41 harekiet Exp $ */ +/* $Id: callback.h,v 1.16 2006-02-09 11:47:47 qbix79 Exp $ */ #ifndef DOSBOX_CALLBACK_H #define DOSBOX_CALLBACK_H diff --git a/include/cpu.h b/include/cpu.h index d1736b45..5c07092a 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/cross.h b/include/cross.h index 1258ee30..e7a7b04c 100644 --- a/include/cross.h +++ b/include/cross.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.h,v 1.15 2005-11-29 07:25:30 qbix79 Exp $ */ +/* $Id: cross.h,v 1.16 2006-02-09 11:47:47 qbix79 Exp $ */ #ifndef DOSBOX_CROSS_H #define DOSBOX_CROSS_H diff --git a/include/debug.h b/include/debug.h index 804a31d5..112f668e 100644 --- a/include/debug.h +++ b/include/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/dma.h b/include/dma.h index 84ec9a7a..655a7984 100644 --- a/include/dma.h +++ b/include/dma.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dma.h,v 1.15 2005-11-16 20:27:39 c2woody Exp $ */ +/* $Id: dma.h,v 1.16 2006-02-09 11:47:47 qbix79 Exp $ */ #ifndef DOSBOX_DMA_H #define DOSBOX_DMA_H diff --git a/include/dos_inc.h b/include/dos_inc.h index 997807dd..0d093c5f 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.58 2005-11-24 17:05:19 c2woody Exp $ */ +/* $Id: dos_inc.h,v 1.59 2006-02-09 11:47:47 qbix79 Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H diff --git a/include/dos_system.h b/include/dos_system.h index 69df06e1..1f0af3f1 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.30 2005-03-24 21:12:30 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.31 2006-02-09 11:47:47 qbix79 Exp $ */ #ifndef DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H diff --git a/include/dosbox.h b/include/dosbox.h index a36a76eb..cb843854 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/fpu.h b/include/fpu.h index d1111a21..6bea5cef 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/hardware.h b/include/hardware.h index d8e19470..fcfa4ace 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/inout.h b/include/inout.h index 01ccfdcc..741bf8c7 100644 --- a/include/inout.h +++ b/include/inout.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: inout.h,v 1.8 2005-03-24 21:11:05 qbix79 Exp $ */ +/* $Id: inout.h,v 1.9 2006-02-09 11:47:47 qbix79 Exp $ */ #ifndef DOSBOX_INOUT_H #define DOSBOX_INOUT_H diff --git a/include/ipx.h b/include/ipx.h index 8b882456..7022aa33 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.h,v 1.7 2005-11-29 07:25:30 qbix79 Exp $ */ +/* $Id: ipx.h,v 1.8 2006-02-09 11:47:47 qbix79 Exp $ */ #ifndef DOSBOX_IPX_H #define DOSBOX_IPX_H diff --git a/include/ipxserver.h b/include/ipxserver.h index 54805d1e..31240f7c 100644 --- a/include/ipxserver.h +++ b/include/ipxserver.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/joystick.h b/include/joystick.h index b79666e3..8eda8b03 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: joystick.h,v 1.7 2005-06-13 14:48:01 qbix79 Exp $ */ +/* $Id: joystick.h,v 1.8 2006-02-09 11:47:48 qbix79 Exp $ */ #ifndef DOSBOX_JOYSTICK_H #define DOSBOX_JOYSTICK_H void JOYSTICK_Enable(Bitu which,bool enabled); diff --git a/include/keyboard.h b/include/keyboard.h index 9c6ea4f8..76878d78 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/mapper.h b/include/mapper.h index 469265f8..90813f06 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/mem.h b/include/mem.h index ce3f5d7c..b91ff93f 100644 --- a/include/mem.h +++ b/include/mem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/mixer.h b/include/mixer.h index 1faa5b02..c778bf5d 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/mouse.h b/include/mouse.h index 21c44551..37bbb3dc 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.h,v 1.11 2006-01-31 09:26:43 qbix79 Exp $ */ +/* $Id: mouse.h,v 1.12 2006-02-09 11:47:48 qbix79 Exp $ */ #ifndef DOSBOX_MOUSE_H #define DOSBOX_MOUSE_H diff --git a/include/paging.h b/include/paging.h index 7a05d61e..e7a18422 100644 --- a/include/paging.h +++ b/include/paging.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.21 2006-01-30 09:46:01 harekiet Exp $ */ +/* $Id: paging.h,v 1.22 2006-02-09 11:47:48 qbix79 Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H diff --git a/include/pic.h b/include/pic.h index 6440ca22..90a49b47 100644 --- a/include/pic.h +++ b/include/pic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/programs.h b/include/programs.h index 90163958..7d6be6a4 100644 --- a/include/programs.h +++ b/include/programs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/regs.h b/include/regs.h index 98319c28..02eb2557 100644 --- a/include/regs.h +++ b/include/regs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/render.h b/include/render.h index a0218a6d..8bf71afd 100644 --- a/include/render.h +++ b/include/render.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/serialport.h b/include/serialport.h index aac0b4c5..75785ccf 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.h,v 1.11 2005-11-29 07:25:30 qbix79 Exp $ */ +/* $Id: serialport.h,v 1.12 2006-02-09 11:47:48 qbix79 Exp $ */ #ifndef DOSBOX_SERIALPORT_H #define DOSBOX_SERIALPORT_H diff --git a/include/setup.h b/include/setup.h index e65ef854..f53ddecd 100644 --- a/include/setup.h +++ b/include/setup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.21 2006-01-30 19:37:48 qbix79 Exp $ */ +/* $Id: setup.h,v 1.22 2006-02-09 11:47:48 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H diff --git a/include/shell.h b/include/shell.h index d8110043..ec609c25 100644 --- a/include/shell.h +++ b/include/shell.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.14 2006-01-12 10:20:20 qbix79 Exp $ */ +/* $Id: shell.h,v 1.15 2006-02-09 11:47:48 qbix79 Exp $ */ #ifndef DOSBOX_SHELL_H #define DOSBOX_SHELL_H diff --git a/include/support.h b/include/support.h index 704cc105..83ee6ff7 100644 --- a/include/support.h +++ b/include/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/timer.h b/include/timer.h index 742348ea..b6ebab9c 100644 --- a/include/timer.h +++ b/include/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/vga.h b/include/vga.h index fe4b1b91..8c365c9c 100644 --- a/include/vga.h +++ b/include/vga.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/include/video.h b/include/video.h index b89aa938..f6a3c208 100644 --- a/include/video.h +++ b/include/video.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index dbcb057f..29a14244 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.29 2006-02-03 17:07:41 harekiet Exp $ */ +/* $Id: callback.cpp,v 1.30 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 1383116b..5dd4e64c 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index ecede836..19dc1a4d 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index d3a2856a..7c9b5e3c 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index 48d61672..61384269 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index b21d504a..6e372c34 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 0588928f..5ff39eeb 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/core_normal/helpers.h b/src/cpu/core_normal/helpers.h index 38c069c7..237144b3 100644 --- a/src/cpu/core_normal/helpers.h +++ b/src/cpu/core_normal/helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 749e3d27..cb24f83f 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index aa560535..a839c42b 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 224c82a1..d9cc9901 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 81e2c7b3..44a9a941 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index 774d0640..2d1aeb1d 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/core_normal/table_ea.h b/src/cpu/core_normal/table_ea.h index 60526f1f..bfe5ed0a 100644 --- a/src/cpu/core_normal/table_ea.h +++ b/src/cpu/core_normal/table_ea.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp index 60ee1e6f..72d722e5 100644 --- a/src/cpu/core_simple.cpp +++ b/src/cpu/core_simple.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 05093caf..a4f87ad0 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.75 2006-01-30 14:01:52 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.76 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index c613dd6e..5d878375 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 563c401b..bd5981cd 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index 6568acce..227d5f2c 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/modrm.cpp b/src/cpu/modrm.cpp index 779b5452..15e4cd0d 100644 --- a/src/cpu/modrm.cpp +++ b/src/cpu/modrm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/modrm.h b/src/cpu/modrm.h index 697d0ba1..e98f139d 100644 --- a/src/cpu/modrm.h +++ b/src/cpu/modrm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index e1d93a52..7c804cf7 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 0c2b4a1f..a4792c94 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.73 2006-01-30 09:48:03 harekiet Exp $ */ +/* $Id: debug.cpp,v 1.74 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 1b738dcb..41b5d46a 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug_gui.cpp,v 1.27 2006-02-01 07:59:54 qbix79 Exp $ */ +/* $Id: debug_gui.cpp,v 1.28 2006-02-09 11:47:48 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h index a66d63c6..43b629a1 100644 --- a/src/debug/debug_inc.h +++ b/src/debug/debug_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 @@ -18,7 +18,7 @@ /* Local Debug Function */ -/* $Id: debug_inc.h,v 1.9 2005-02-10 10:20:50 qbix79 Exp $ */ +/* $Id: debug_inc.h,v 1.10 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include "mem.h" diff --git a/src/debug/debug_win32.cpp b/src/debug/debug_win32.cpp index f83ae42d..70d4bb4d 100644 --- a/src/debug/debug_win32.cpp +++ b/src/debug/debug_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/debug/disasm_tables.h b/src/debug/disasm_tables.h index 60f0d888..b0d3c4cc 100644 --- a/src/debug/disasm_tables.h +++ b/src/debug/disasm_tables.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 76a5d83c..96a17ae6 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index 573fde0a..830788d6 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_aspi_win32.cpp,v 1.15 2005-07-21 07:48:37 qbix79 Exp $ */ +/* $Id: cdrom_aspi_win32.cpp,v 1.16 2006-02-09 11:47:48 qbix79 Exp $ */ #if defined (WIN32) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index bdd830db..cbf10d41 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.10 2005-11-01 11:09:14 qbix79 Exp $ */ +/* $Id: cdrom_image.cpp,v 1.11 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include diff --git a/src/dos/cdrom_ioctl_linux.cpp b/src/dos/cdrom_ioctl_linux.cpp index 6a492aa0..a05e0ab1 100644 --- a/src/dos/cdrom_ioctl_linux.cpp +++ b/src/dos/cdrom_ioctl_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/dos/cdrom_ioctl_os2.cpp b/src/dos/cdrom_ioctl_os2.cpp index 7374d8f0..bbda0f16 100644 --- a/src/dos/cdrom_ioctl_os2.cpp +++ b/src/dos/cdrom_ioctl_os2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_ioctl_os2.cpp,v 1.1 2005-11-25 19:15:12 qbix79 Exp $ */ +/* $Id: cdrom_ioctl_os2.cpp,v 1.2 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index ed0b4c72..8c8f7f2b 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_ioctl_win32.cpp,v 1.12 2005-02-10 10:20:50 qbix79 Exp $ */ +/* $Id: cdrom_ioctl_win32.cpp,v 1.13 2006-02-09 11:47:48 qbix79 Exp $ */ #if defined (WIN32) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 0a27c73f..df97577b 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.22 2005-10-03 14:03:49 qbix79 Exp $ */ +/* $Id: dev_con.h,v 1.23 2006-02-09 11:47:48 qbix79 Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 32d8f693..4e3d03fb 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.90 2005-11-24 17:05:22 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.91 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 6bd5819b..40a9687c 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.46 2005-08-23 08:49:57 c2woody Exp $ */ +/* $Id: dos_classes.cpp,v 1.47 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 8476344b..341e1cee 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_devices.cpp,v 1.10 2005-03-25 08:48:41 qbix79 Exp $ */ +/* $Id: dos_devices.cpp,v 1.11 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 966aded7..de504c72 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.53 2005-12-19 20:39:51 c2woody Exp $ */ +/* $Id: dos_execute.cpp,v 1.54 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 4af385ee..5dddad38 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.70 2005-10-07 15:16:58 c2woody Exp $ */ +/* $Id: dos_files.cpp,v 1.71 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index e4d82eaa..cee95b74 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.25 2005-04-21 18:42:10 qbix79 Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.26 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index dbdd7063..23eccf76 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index af552a25..df08976b 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_misc.cpp,v 1.15 2005-03-25 08:51:34 qbix79 Exp $ */ +/* $Id: dos_misc.cpp,v 1.16 2006-02-09 11:47:48 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 018b0ef3..f47442b8 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.35 2006-01-27 07:54:51 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.36 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index d678a2c5..92d3015a 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.52 2006-02-09 08:49:52 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.53 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 95bdca02..b276ecde 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.21 2005-10-07 15:16:58 c2woody Exp $ */ +/* $Id: dos_tables.cpp,v 1.22 2006-02-09 11:47:48 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index f4c6c1c1..c650db8b 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -1,6 +1,6 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.45 2005-11-28 16:12:31 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.46 2006-02-09 11:47:48 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 227e0110..e32c7b07 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.10 2005-09-24 19:18:42 c2woody Exp $ */ +/* $Id: drive_fat.cpp,v 1.11 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index f95421e4..5dea73ed 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.10 2005-09-07 19:15:09 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.11 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 8d6151aa..6a526a09 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.62 2006-01-27 10:44:55 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.63 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 1611a978..ae1e7867 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index cf1e19cd..8b821627 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/dos/drives.h b/src/dos/drives.h index 644673da..d9141f05 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.29 2005-09-07 19:15:09 qbix79 Exp $ */ +/* $Id: drives.h,v 1.30 2006-02-09 11:47:48 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 1ed7a110..cc51cef0 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.92 2006-01-30 10:11:18 harekiet Exp $ */ +/* $Id: dosbox.cpp,v 1.93 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 05d41008..69872c0b 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu.cpp,v 1.26 2005-08-10 20:36:36 qbix79 Exp $ */ +/* $Id: fpu.cpp,v 1.27 2006-02-09 11:47:48 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index f7dd9fb0..8609aae0 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.27 2005-02-22 13:06:06 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.28 2006-02-09 11:47:48 qbix79 Exp $ */ static void FPU_FINIT(void) { diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index 45e3c6e5..f3babb49 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions_x86.h,v 1.2 2006-01-08 18:05:06 c2woody Exp $ */ +/* $Id: fpu_instructions_x86.h,v 1.3 2006-02-09 11:47:48 qbix79 Exp $ */ #define WEAK_EXCEPTIONS diff --git a/src/fpu/fpu_types.h b/src/fpu/fpu_types.h index 3a4ac2fe..0e5220e2 100644 --- a/src/fpu/fpu_types.h +++ b/src/fpu/fpu_types.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_types.h,v 1.12 2005-02-22 13:06:06 qbix79 Exp $ */ +/* $Id: fpu_types.h,v 1.13 2006-02-09 11:47:48 qbix79 Exp $ */ typedef union { double d; #ifndef WORDS_BIGENDIAN diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 9c303bb1..a6ca7961 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index fa295e22..5d02dc58 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_alsa.h,v 1.12 2005-07-19 19:45:31 qbix79 Exp $ */ +/* $Id: midi_alsa.h,v 1.13 2006-02-09 11:47:48 qbix79 Exp $ */ #define ALSA_PCM_OLD_HW_PARAMS_API #define ALSA_PCM_OLD_SW_PARAMS_API diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index 1d5b534c..1af883b4 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index 7aef2565..20db3944 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index f4e4a547..39953f2a 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_win32.h,v 1.11 2005-02-10 10:21:07 qbix79 Exp $ */ +/* $Id: midi_win32.h,v 1.12 2006-02-09 11:47:48 qbix79 Exp $ */ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 5f89554d..a78398c2 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.39 2006-02-01 07:22:45 harekiet Exp $ */ +/* $Id: render.cpp,v 1.40 2006-02-09 11:47:48 qbix79 Exp $ */ #include #include diff --git a/src/gui/render_loops.h b/src/gui/render_loops.h index 291b7cb2..a9af5216 100644 --- a/src/gui/render_loops.h +++ b/src/gui/render_loops.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index 874f856e..4ae8c751 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index 33d72b00..3d982369 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index ad00d285..803099bd 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 2247b941..9e4b0c8b 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.18 2006-01-30 09:57:18 harekiet Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.19 2006-02-09 11:47:48 qbix79 Exp $ */ #define OLD_JOYSTICK 1 diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 328f916e..585520e7 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.99 2006-02-09 08:42:42 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.100 2006-02-09 11:47:48 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 7ab235ca..7daf7797 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 3ee978ef..0596ec2a 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 15bd7350..e33e46e9 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 988f0a30..e039d46f 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index 2df5fa77..af3be1b0 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index abe48b7b..9cd3cbba 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 5ce67e96..0d073f49 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: hardware.cpp,v 1.11 2006-02-08 07:16:15 harekiet Exp $ */ +/* $Id: hardware.cpp,v 1.12 2006-02-09 11:47:49 qbix79 Exp $ */ #include #include diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index f001ba8a..bae6effd 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: iohandler.cpp,v 1.19 2006-01-30 10:00:44 harekiet Exp $ */ +/* $Id: iohandler.cpp,v 1.20 2006-02-09 11:47:49 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index 33c3bafb..580d784c 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.cpp,v 1.8 2005-08-26 19:16:20 c2woody Exp $ */ +/* $Id: ipx.cpp,v 1.9 2006-02-09 11:47:49 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/ipxserver.cpp b/src/hardware/ipxserver.cpp index bcd88ec6..f5d84ae3 100644 --- a/src/hardware/ipxserver.cpp +++ b/src/hardware/ipxserver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipxserver.cpp,v 1.6 2005-08-08 20:29:55 qbix79 Exp $ */ +/* $Id: ipxserver.cpp,v 1.7 2006-02-09 11:47:49 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index 1f6d9c12..fdaff0b1 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: joystick.cpp,v 1.13 2005-06-23 18:34:30 qbix79 Exp $ */ +/* $Id: joystick.cpp,v 1.14 2006-02-09 11:47:49 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 8971229c..acbc3fd6 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.34 2005-12-04 21:17:29 c2woody Exp $ */ +/* $Id: keyboard.cpp,v 1.35 2006-02-09 11:47:49 qbix79 Exp $ */ #include "dosbox.h" #include "keyboard.h" diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 3754202b..c14cf5cd 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: memory.cpp,v 1.43 2006-01-30 10:04:46 harekiet Exp $ */ +/* $Id: memory.cpp,v 1.44 2006-02-09 11:47:49 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index c525d2bf..2e643ecc 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.36 2006-01-30 10:04:20 harekiet Exp $ */ +/* $Id: mixer.cpp,v 1.37 2006-02-09 11:47:49 qbix79 Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 5e6c0f4b..3c4c7e13 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.15 2005-03-25 11:52:32 qbix79 Exp $ */ +/* $Id: mpu401.cpp,v 1.16 2006-02-09 11:47:49 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 9e321c11..b90b0764 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /* $Id: pcspeaker.cpp,v 1.21 2005-12-05 12:04:40 qbix79 Exp $ */ + /* $Id: pcspeaker.cpp,v 1.22 2006-02-09 11:47:49 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index f4fe0c58..ac8fee80 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.32 2005-12-04 21:17:29 c2woody Exp $ */ +/* $Id: pic.cpp,v 1.33 2006-02-09 11:47:49 qbix79 Exp $ */ #include diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index aa8bd9f6..f05bfdeb 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.51 2006-01-19 14:42:19 qbix79 Exp $ */ +/* $Id: sblaster.cpp,v 1.52 2006-02-09 11:47:49 qbix79 Exp $ */ #include #include diff --git a/src/hardware/serialport/directserial_os2.cpp b/src/hardware/serialport/directserial_os2.cpp index 5c986154..d2c1ef73 100644 --- a/src/hardware/serialport/directserial_os2.cpp +++ b/src/hardware/serialport/directserial_os2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_os2.cpp,v 1.1 2005-11-28 16:18:35 qbix79 Exp $ */ +/* $Id: directserial_os2.cpp,v 1.2 2006-02-09 11:47:54 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/directserial_os2.h b/src/hardware/serialport/directserial_os2.h index 431c1519..a1488670 100644 --- a/src/hardware/serialport/directserial_os2.h +++ b/src/hardware/serialport/directserial_os2.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_os2.h,v 1.1 2005-11-28 16:18:35 qbix79 Exp $ */ +/* $Id: directserial_os2.h,v 1.2 2006-02-09 11:47:54 qbix79 Exp $ */ // include guard #ifndef DOSBOX_DIRECTSERIAL_OS2_H diff --git a/src/hardware/serialport/directserial_win32.cpp b/src/hardware/serialport/directserial_win32.cpp index 5def0603..4b13fa4f 100644 --- a/src/hardware/serialport/directserial_win32.cpp +++ b/src/hardware/serialport/directserial_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_win32.cpp,v 1.2 2005-11-04 08:53:07 qbix79 Exp $ */ +/* $Id: directserial_win32.cpp,v 1.3 2006-02-09 11:47:54 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/directserial_win32.h b/src/hardware/serialport/directserial_win32.h index e2622803..63adb893 100644 --- a/src/hardware/serialport/directserial_win32.h +++ b/src/hardware/serialport/directserial_win32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_win32.h,v 1.1 2005-07-30 14:41:31 qbix79 Exp $ */ +/* $Id: directserial_win32.h,v 1.2 2006-02-09 11:47:54 qbix79 Exp $ */ // include guard #ifndef DOSBOX_DIRECTSERIAL_WIN32_H diff --git a/src/hardware/serialport/serialdummy.cpp b/src/hardware/serialport/serialdummy.cpp index 24af9fdc..749e9e67 100644 --- a/src/hardware/serialport/serialdummy.cpp +++ b/src/hardware/serialport/serialdummy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialdummy.cpp,v 1.1 2005-07-30 14:41:31 qbix79 Exp $ */ +/* $Id: serialdummy.cpp,v 1.2 2006-02-09 11:47:54 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/serialdummy.h b/src/hardware/serialport/serialdummy.h index 0306a4ff..dbff5e70 100644 --- a/src/hardware/serialport/serialdummy.h +++ b/src/hardware/serialport/serialdummy.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialdummy.h,v 1.1 2005-07-30 14:41:31 qbix79 Exp $ */ +/* $Id: serialdummy.h,v 1.2 2006-02-09 11:47:55 qbix79 Exp $ */ #ifndef INCLUDEGUARD_SERIALDUMMY_H #define INCLUDEGUARD_SERIALDUMMY_H diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index ade40bd0..2f2ce439 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.cpp,v 1.3 2005-11-28 16:18:35 qbix79 Exp $ */ +/* $Id: serialport.cpp,v 1.4 2006-02-09 11:47:55 qbix79 Exp $ */ #include #include diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index f7f66ae1..8352b6aa 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.cpp,v 1.2 2005-11-04 08:53:07 qbix79 Exp $ */ +/* $Id: softmodem.cpp,v 1.3 2006-02-09 11:47:55 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index 5aa4faad..4ec1e764 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.h,v 1.3 2005-11-04 08:53:07 qbix79 Exp $ */ +/* $Id: softmodem.h,v 1.4 2006-02-09 11:47:55 qbix79 Exp $ */ #ifndef DOSBOX_SERIALMODEM_H #define DOSBOX_SERIALMODEM_H diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 49e0f87f..84f34df3 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 17565188..0fa2f36d 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.33 2005-08-07 17:33:15 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.34 2006-02-09 11:47:49 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index c924393c..696a5be9 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 1e7bc272..1f2f1f9c 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index d193f372..cf47441c 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index c714c8c6..b6648e39 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 30a7c63e..92ea0bbf 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index e49856c5..7a8190b0 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 6581b3eb..6138229a 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 3cefa5aa..141bfba4 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 8b109093..ba424fd4 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_other.cpp,v 1.16 2006-01-11 09:32:12 qbix79 Exp $ */ +/* $Id: vga_other.cpp,v 1.17 2006-02-09 11:47:49 qbix79 Exp $ */ #include #include diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index b54400a0..67c9f1f3 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 6015d0ef..406baba7 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index 1fe0c121..c998eae7 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 49a1717d..506494e0 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.56 2006-01-05 14:14:53 c2woody Exp $ */ +/* $Id: bios.cpp,v 1.57 2006-02-09 11:47:55 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index ec198df3..d1721388 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.25 2005-12-26 20:28:08 c2woody Exp $ */ +/* $Id: bios_disk.cpp,v 1.26 2006-02-09 11:47:56 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 80cb1798..ffce76d3 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index dade5702..b325e4f8 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.44 2005-12-03 10:43:22 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.45 2006-02-09 11:47:56 qbix79 Exp $ */ #include #include diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 53a4a013..21749b28 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/ints/int10.h b/src/ints/int10.h index 8ae53e17..2438ea2f 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 5906de56..d5b329ab 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.44 2006-02-07 20:25:47 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.45 2006-02-09 11:47:57 qbix79 Exp $ */ /* Character displaying moving functions */ diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index abdedc69..7079e45c 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index de1db8fb..9bce3d6d 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 23a6a17f..c4ef9710 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 2011d98f..8026ef9e 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 17d10eae..93db017b 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index cf9c1897..b776f28b 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.21 2006-02-07 20:12:27 c2woody Exp $ */ +/* $Id: int10_vesa.cpp,v 1.22 2006-02-09 11:47:57 qbix79 Exp $ */ #include #include diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 6c47bf9e..296591a8 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.59 2006-01-31 09:26:45 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.60 2006-02-09 11:47:57 qbix79 Exp $ */ #include #include diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 5f7fce4e..f8064662 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.38 2005-10-10 10:16:42 c2woody Exp $ */ +/* $Id: xms.cpp,v 1.39 2006-02-09 11:47:57 qbix79 Exp $ */ #include #include diff --git a/src/ints/xms.h b/src/ints/xms.h index 855c8c06..59449115 100644 --- a/src/ints/xms.h +++ b/src/ints/xms.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/libs/zmbv/drvproc.cpp b/src/libs/zmbv/drvproc.cpp index b6c37540..53e7c8c2 100644 --- a/src/libs/zmbv/drvproc.cpp +++ b/src/libs/zmbv/drvproc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/libs/zmbv/zmbv.cpp b/src/libs/zmbv/zmbv.cpp index 01436953..78872b08 100644 --- a/src/libs/zmbv/zmbv.cpp +++ b/src/libs/zmbv/zmbv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/libs/zmbv/zmbv.h b/src/libs/zmbv/zmbv.h index b1c97aa2..eae58d93 100644 --- a/src/libs/zmbv/zmbv.h +++ b/src/libs/zmbv/zmbv.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/libs/zmbv/zmbv_vfw.cpp b/src/libs/zmbv/zmbv_vfw.cpp index c0ac550c..cb2e057e 100644 --- a/src/libs/zmbv/zmbv_vfw.cpp +++ b/src/libs/zmbv/zmbv_vfw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 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 diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index f06a9eab..0cae1e0d 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: messages.cpp,v 1.17 2005-02-10 10:21:11 qbix79 Exp $ */ +/* $Id: messages.cpp,v 1.18 2006-02-09 11:47:57 qbix79 Exp $ */ #include #include diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index d996feb3..3998a9d3 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.22 2005-08-22 19:31:27 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.23 2006-02-09 11:47:57 qbix79 Exp $ */ #include #include diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 2c0fb772..f8351253 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.32 2006-01-30 19:37:49 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.33 2006-02-09 11:47:57 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" diff --git a/src/misc/support.cpp b/src/misc/support.cpp index e5a3a045..6fac9042 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.28 2005-02-10 10:21:12 qbix79 Exp $ */ +/* $Id: support.cpp,v 1.29 2006-02-09 11:47:57 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index db6e4127..3bf8229a 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.70 2006-01-22 14:13:00 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.71 2006-02-09 11:47:57 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index cf957c5b..2fbf1eaf 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.18 2005-09-28 08:14:27 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.19 2006-02-09 11:47:57 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 4e38d0ab..c8ba70df 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.60 2005-11-24 18:16:15 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.61 2006-02-09 11:47:57 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index fd53c3ec..7105790a 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * Copyright (C) 2002-2006 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.39 2005-08-10 19:53:11 c2woody Exp $ */ +/* $Id: shell_misc.cpp,v 1.40 2006-02-09 11:47:57 qbix79 Exp $ */ #include #include From f6efa75ba5611997d00e8bfbac1f29c6745a8688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 9 Feb 2006 21:29:19 +0000 Subject: [PATCH 2397/4131] fix a few key combinations of the numblock when numlock enabled Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2481 --- src/ints/bios_keyboard.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index ffce76d3..b80817e4 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -368,10 +368,10 @@ static Bitu IRQ1_Handler(void) { if(scancode == 0x52) flags2 |=0x80; /* press insert */ if(flags1 &0x08) { add_key(scan_to_scanascii[scancode].normal+0x5000); - } else if( ((flags1 &0x3) != 0) ^ ((flags1 &0x20) != 0) ) { - add_key((scan_to_scanascii[scancode].shift&0xff00)|0xe0); } else if (flags1 &0x04) { add_key((scan_to_scanascii[scancode].control&0xff00)|0xe0); + } else if( ((flags1 &0x3) != 0) || ((flags1 &0x20) != 0) ) { + add_key((scan_to_scanascii[scancode].shift&0xff00)|0xe0); } else add_key((scan_to_scanascii[scancode].normal&0xff00)|0xe0); break; } @@ -381,7 +381,7 @@ static Bitu IRQ1_Handler(void) { mem_writeb(BIOS_KEYBOARD_TOKEN,token); } else if (flags1 &0x04) { add_key(scan_to_scanascii[scancode].control); - } else if( ((flags1 &0x3) != 0) ^ ((flags1 &0x20) != 0) ) { + } else if( ((flags1 &0x3) != 0) || ((flags1 &0x20) != 0) ) { add_key(scan_to_scanascii[scancode].shift); } else add_key(scan_to_scanascii[scancode].normal); break; From 0e3603396ec27b83c52b3fc1a49e875ae098f24a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 11 Feb 2006 09:37:16 +0000 Subject: [PATCH 2398/4131] New mixer routine to handle speeding up emulator causing faster output Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2482 --- src/hardware/mixer.cpp | 79 ++++++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 26 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 2e643ecc..6c286a81 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.37 2006-02-09 11:47:49 qbix79 Exp $ */ +/* $Id: mixer.cpp,v 1.38 2006-02-11 09:37:16 harekiet Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -80,13 +80,13 @@ struct MIXER_Channel { static struct { Bit32s work[MIXER_BUFSIZE][2]; Bitu pos,done; - Bitu needed,min_needed; + Bitu needed, min_needed, max_needed; + Bit32u tick_add,tick_remain; float mastervol[2]; MixerChannel * channels; bool nosound; Bit32u freq; Bit32u blocksize; - Bit32u tick_add,tick_remain; } mixer; Bit8u MixTemp[MIXER_BUFSIZE]; @@ -292,8 +292,6 @@ static void MIXER_MixData(Bitu needed) { readpos=(readpos+1)&MIXER_BUFMASK; } CAPTURE_AddWave( mixer.freq, added, (Bit16s*)convert ); - //Reset the the tick_add for constant speed - mixer.tick_add=((mixer.freq) << MIXER_SHIFT)/1000; } mixer.done=needed; } @@ -329,34 +327,62 @@ static void MIXER_Mix_NoSound(void) { static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { Bitu need=(Bitu)len/MIXER_SSIZE; - if (need>mixer.done) { - //LOG_MSG("%d Buffer underrun %d done and %d needed",count++,mixer.done,need); - return; - }//else LOG_MSG("%d Buffer regular run %d done and %d needed",count++,mixer.done,need); + Bit16s * output=(Bit16s *)stream; + Bitu reduce; + Bitu pos, index, index_add; + Bits sample; + /* Enough room in the buffer ? */ + if (mixer.done < need) { +// LOG_MSG("Full underrun need %d, have %d, min %d", need, mixer.done, mixer.min_needed); + reduce = mixer.done; + index_add = (reduce << MIXER_SHIFT) / need; + } else if (mixer.done < mixer.max_needed) { + Bitu left = mixer.done - need; + if (left < mixer.min_needed) { + left = (mixer.min_needed - left); + left = 1 + (2*left) / mixer.min_needed; +// left = 1; +// left = 1 + (left / 128); +// LOG_MSG("needed underrun need %d, have %d, min %d, left %d", need, mixer.done, mixer.min_needed, left); + reduce = need - left; + index_add = (reduce << MIXER_SHIFT) / need; + } else { + reduce = need; + index_add = (1 << MIXER_SHIFT); + } + } else { + /* There is way too much data in the buffer */ + if (mixer.done > MIXER_BUFSIZE) + index_add = MIXER_BUFSIZE - mixer.min_needed; + else + index_add = mixer.done - mixer.min_needed; + index_add = (index_add << MIXER_SHIFT) / need; + reduce = mixer.done - mixer.min_needed; + } /* Reduce done count in all channels */ for (MixerChannel * chan=mixer.channels;chan;chan=chan->next) { - if (chan->done>need) chan->done-=need; + if (chan->done>need) chan->done-=reduce; else chan->done=0; } - mixer.done-=need; - mixer.needed-=need; - if (mixer.done > mixer.min_needed) { - Bitu diff=mixer.done-mixer.min_needed; - mixer.tick_add = ((mixer.freq-(diff/5)) << MIXER_SHIFT)/1000; - } else { - Bitu diff = ((mixer.min_needed>mixer.needed)?mixer.min_needed:mixer.needed) - mixer.done; - mixer.tick_add = ((mixer.freq+(diff*3)) << MIXER_SHIFT)/1000; - } - Bit16s * output=(Bit16s *)stream; - Bits sample; + mixer.done -= reduce; + mixer.needed -= reduce; + pos = mixer.pos; + mixer.pos = (mixer.pos + reduce) & MIXER_BUFMASK; + index = 0; while (need--) { - sample=mixer.work[mixer.pos][0]>>MIXER_VOLSHIFT; + Bitu i = (pos + (index >> MIXER_SHIFT )) & MIXER_BUFMASK; + index += index_add; + sample=mixer.work[i][0]>>MIXER_VOLSHIFT; *output++=MIXER_CLIP(sample); - mixer.work[mixer.pos][0]=0; - sample=mixer.work[mixer.pos][1]>>MIXER_VOLSHIFT; + sample=mixer.work[i][1]>>MIXER_VOLSHIFT; *output++=MIXER_CLIP(sample); - mixer.work[mixer.pos][1]=0; - mixer.pos=(mixer.pos+1)&MIXER_BUFMASK; + } + /* Clean the used buffer */ + while (reduce--) { + pos &= MIXER_BUFMASK; + mixer.work[pos][0]=0; + mixer.work[pos][1]=0; + pos++; } } @@ -505,6 +531,7 @@ void MIXER_Init(Section* sec) { mixer.min_needed=section->Get_int("prebuffer"); if (mixer.min_needed>100) mixer.min_needed=100; mixer.min_needed=(mixer.freq*mixer.min_needed)/1000; + mixer.max_needed=mixer.blocksize * 2 + mixer.min_needed; mixer.needed=mixer.min_needed+1; PROGRAMS_MakeFile("MIXER.COM",MIXER_ProgramStart); } From ecc77541f140c3885b13115387329629e91f35c2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 12 Feb 2006 12:30:54 +0000 Subject: [PATCH 2399/4131] Add patch " 1428943 ] Fix for wrong ATTR flipflop state after INT10_SetVideoMode" from vasyl Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2483 --- src/ints/int10_modes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index c4ef9710..5e865beb 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -857,7 +857,7 @@ att_text16: IO_Write(0x3c0,i); IO_Write(0x3c0,att_data[i]); } - IO_Write(0x3c0,0x20); //Disable palette access + IO_Write(0x3c0,0x20); IO_Write(0x3c0,0x00); //Disable palette access /* Setup the DAC */ IO_Write(0x3c8,0); switch (CurMode->type) { From 234d45fabc1fdae6c711f5445c45def2b77e6fa9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 12 Feb 2006 12:35:13 +0000 Subject: [PATCH 2400/4131] Add patch: " [ 1425902 ] Zipped Motion Block Vector VFW codec fixes" from virtualdub Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2484 --- src/libs/zmbv/zmbv.cpp | 44 +++++++++++++--- src/libs/zmbv/zmbv_vfw.cpp | 103 ++++++++++++++++++++++++++++++------- 2 files changed, 121 insertions(+), 26 deletions(-) diff --git a/src/libs/zmbv/zmbv.cpp b/src/libs/zmbv/zmbv.cpp index 78872b08..06812514 100644 --- a/src/libs/zmbv/zmbv.cpp +++ b/src/libs/zmbv/zmbv.cpp @@ -480,14 +480,46 @@ void VideoCodec::Output_UpsideDown_24(void *output) { int i; unsigned char *r; unsigned char *w = (unsigned char *)output; + int pad = width & 3; + for (i=height-1;i>=0;i--) { - r = newframe + pixelsize*(MAX_VECTOR+(i+MAX_VECTOR)*pitch); - for (int j=0;j> 2); + *w++ = (unsigned char)(((c & 0x03e0) * 0x21) >> 7); + *w++ = (unsigned char)(((c & 0x7c00) * 0x21) >> 12); + } + break; + case ZMBV_FORMAT_16BPP: + for (int j=0;j> 2); + *w++ = (unsigned char)(((c & 0x07e0) * 0x41) >> 9); + *w++ = (unsigned char)(((c & 0xf800) * 0x21) >> 13); + } + break; + case ZMBV_FORMAT_32BPP: + for (int j=0;jdwSize = sizeof(ICINFO); icinfo->fccType = ICTYPE_VIDEO; memcpy(&icinfo->fccHandler,CODEC_4CC, 4); - icinfo->dwFlags = VIDCF_FASTTEMPORALC | VIDCF_FASTTEMPORALD | VIDCF_TEMPORAL | VIDCF_QUALITY; + icinfo->dwFlags = VIDCF_FASTTEMPORALC | VIDCF_FASTTEMPORALD | VIDCF_TEMPORAL; icinfo->dwVersion = VERSION; icinfo->dwVersionICM = ICVERSION; @@ -173,36 +173,82 @@ DWORD CodecInst::GetInfo(ICINFO* icinfo, DWORD dwSize) { /******************************************************************** ****************************************************************/ -static bool CanCompress(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) { +static int GetInputBitDepth(const BITMAPINFOHEADER *lpbiIn) { + if (lpbiIn->biCompression == BI_RGB) { + if (lpbiIn->biPlanes != 1) + return -1; + + switch(lpbiIn->biBitCount) { + case 8: + return 8; + case 16: + return 15; // Standard Windows 16-bit RGB is 1555. + case 32: + return 32; + } + + } else if (lpbiIn->biCompression == BI_BITFIELDS) { + // BI_BITFIELDS RGB masks lie right after the BITMAPINFOHEADER structure, + // at (ptr+40). This is true even for a BITMAPV4HEADER or BITMAPV5HEADER. + const DWORD *masks = (const DWORD *)(lpbiIn + 1); + + if (lpbiIn->biBitCount == 16) { + // Test for 16 (555) + if (masks[0] == 0x7C00 && masks[1] == 0x03E0 && masks[2] == 0x001F) + return 15; + + // Test for 16 (565) + if (masks[0] == 0xF800 && masks[1] == 0x07E0 && masks[2] == 0x001F) + return 16; + } else if (lpbiIn->biBitCount == 32) { + if (masks[0] == 0xFF0000 && masks[1] == 0x00FF00 && masks[2] == 0x0000FF) + return 32; + } + } + + return -1; +} + +static bool CanCompress(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, bool requireOutput) { if (lpbiIn) { - if (lpbiIn->biCompression) return false; - if (lpbiIn->biBitCount==24) return false; + if (GetInputBitDepth(lpbiIn) < 0) + return false; } else return false; if (lpbiOut) { if (memcmp(&lpbiOut->biCompression,CODEC_4CC, 4)) return false; - } else return false; + } else return !requireOutput; return true; } + /******************************************************************** ****************************************************************/ DWORD CodecInst::CompressQuery(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) { - if (CanCompress(lpbiIn,lpbiOut)) return ICERR_OK; + if (CanCompress(lpbiIn,lpbiOut,false)) return ICERR_OK; return ICERR_BADFORMAT; } DWORD CodecInst::CompressGetFormat(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) { if (!lpbiOut) return sizeof(BITMAPINFOHEADER); - if (!CanCompress(lpbiIn,lpbiOut)) - return ICERR_BADFORMAT; + lpbiOut->biSize = sizeof(BITMAPINFOHEADER); + lpbiOut->biWidth = lpbiIn->biWidth; + lpbiOut->biHeight = lpbiIn->biHeight; + lpbiOut->biPlanes = 1; + lpbiOut->biCompression = *(const DWORD *)CODEC_4CC; + lpbiOut->biBitCount = lpbiIn->biBitCount; + lpbiOut->biSizeImage = lpbiIn->biWidth * lpbiIn->biHeight * lpbiIn->biBitCount/8 + 1024; + lpbiOut->biXPelsPerMeter = lpbiIn->biXPelsPerMeter; + lpbiOut->biYPelsPerMeter = lpbiIn->biYPelsPerMeter; + lpbiOut->biClrUsed = 0; + lpbiOut->biClrImportant = 0; return ICERR_OK; } DWORD CodecInst::CompressBegin(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) { CompressEnd(); // free resources if necessary - if (!CanCompress(lpbiIn, lpbiOut)) + if (!CanCompress(lpbiIn, lpbiOut, true)) return ICERR_BADFORMAT; codec = new VideoCodec(); if (!codec) @@ -213,7 +259,7 @@ DWORD CodecInst::CompressBegin(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpb } DWORD CodecInst::CompressGetSize(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) { - if (!CanCompress(lpbiIn, lpbiOut)) + if (!CanCompress(lpbiIn, lpbiOut, true)) return ICERR_BADFORMAT; return lpbiIn->biWidth * lpbiIn->biHeight * lpbiIn->biBitCount/8 + 1024; } @@ -223,11 +269,11 @@ DWORD CodecInst::Compress(ICCOMPRESS* icinfo, DWORD dwSize) { zmbv_format_t format; LPBITMAPINFOHEADER lpbiIn=icinfo->lpbiInput; LPBITMAPINFOHEADER lpbiOut=icinfo->lpbiOutput; - if (!CanCompress(lpbiIn, lpbiOut)) + if (!CanCompress(lpbiIn, lpbiOut, true)) return ICERR_BADFORMAT; if (!icinfo->lpInput || !icinfo->lpOutput) return ICERR_ABORT; - switch (lpbiIn->biBitCount) { + switch (GetInputBitDepth(lpbiIn)) { case 8: format = ZMBV_FORMAT_8BPP; pitch = lpbiIn->biWidth; @@ -245,13 +291,28 @@ DWORD CodecInst::Compress(ICCOMPRESS* icinfo, DWORD dwSize) { pitch = lpbiIn->biWidth * 4; break; } - codec->PrepareCompressFrame( 0, format, 0, icinfo->lpOutput, 99999999); - char *readPt = (char *)icinfo->lpbiInput; + + // DIB scanlines for RGB formats are always aligned to DWORD. + pitch = (pitch + 3) & ~3; + + // force a key frame if requested by the client + int flags = 0; + if (icinfo->dwFlags & ICCOMPRESS_KEYFRAME) + flags |= 1; + + codec->PrepareCompressFrame( flags, format, 0, icinfo->lpOutput, 99999999); + char *readPt = (char *)icinfo->lpInput + pitch*(lpbiIn->biHeight - 1); for(i = 0;ibiHeight;i++) { codec->CompressLines(1, (void **)&readPt ); - readPt += pitch; + readPt -= pitch; } lpbiOut->biSizeImage = codec->FinishCompressFrame(); + + if (flags & 1) + *icinfo->lpdwFlags = AVIIF_KEYFRAME; + else + *icinfo->lpdwFlags = 0; + return ICERR_OK; } @@ -291,10 +352,13 @@ DWORD CodecInst::DecompressGetFormat(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEAD return ICERR_BADFORMAT; if (!lpbiOut) return sizeof(BITMAPINFOHEADER); *lpbiOut = *lpbiIn; - lpbiOut->biPlanes = 1; - lpbiOut->biSize=sizeof(BITMAPINFOHEADER); - lpbiOut->biBitCount=24; - lpbiOut->biCompression=0; + lpbiOut->biPlanes = 1; + lpbiOut->biSize = sizeof(BITMAPINFOHEADER); + lpbiOut->biBitCount = 24; + lpbiOut->biSizeImage = ((lpbiOut->biWidth*3 + 3) & ~3) * lpbiOut->biHeight; + lpbiOut->biCompression = BI_RGB; + lpbiOut->biClrUsed = 0; + lpbiOut->biClrImportant = 0; return ICERR_OK; } @@ -315,7 +379,6 @@ DWORD CodecInst::Decompress(ICDECOMPRESS* icinfo, DWORD dwSize) { return ICERR_ABORT; if (codec->DecompressFrame( icinfo->lpInput, icinfo->lpbiInput->biSizeImage)) { codec->Output_UpsideDown_24(icinfo->lpOutput); - icinfo->lpbiOutput->biSizeImage=icinfo->lpbiOutput->biWidth*icinfo->lpbiOutput->biHeight*icinfo->lpbiOutput->biBitCount/8; } else return ICERR_DONTDRAW; return ICERR_OK; } From d1db7843eb63195a76f74ab829b0c7da12fdffba Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 12 Feb 2006 13:19:58 +0000 Subject: [PATCH 2401/4131] add lowest priority class. RFE 1306384 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2485 --- src/gui/sdlmain.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 585520e7..6762c324 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.100 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.101 2006-02-12 13:19:58 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -131,6 +131,7 @@ enum SCREEN_TYPES { }; enum PRIORITY_LEVELS { + PRIORITY_LEVEL_LOWEST, PRIORITY_LEVEL_LOWER, PRIORITY_LEVEL_NORMAL, PRIORITY_LEVEL_HIGHER, @@ -836,6 +837,9 @@ static void SetPriority(PRIORITY_LEVELS level) { #endif switch (level) { #ifdef WIN32 + case PRIORITY_LEVEL_LOWEST: + SetPriorityClass(GetCurrentProcess(),IDLE_PRIORITY_CLASS); + break; case PRIORITY_LEVEL_LOWER: SetPriorityClass(GetCurrentProcess(),BELOW_NORMAL_PRIORITY_CLASS); break; @@ -850,6 +854,9 @@ static void SetPriority(PRIORITY_LEVELS level) { break; #elif C_SET_PRIORITY /* Linux use group as dosbox has mulitple threads under linux */ + case PRIORITY_LEVEL_LOWEST: + setpriority (PRIO_PGRP, 0,PRIO_MAX); + break; case PRIORITY_LEVEL_LOWER: setpriority (PRIO_PGRP, 0,PRIO_MAX-(PRIO_TOTAL/3)); break; @@ -891,7 +898,9 @@ static void GUI_StartUp(Section * sec) { const char * priority=section->Get_string("priority"); if (priority && priority[0]) { Bitu next; - if (!strncasecmp(priority,"lower",5)) { + if (!strncasecmp(priority,"lowest",6)) { + sdl.priority.focus=PRIORITY_LEVEL_LOWEST;next=6; + } else if (!strncasecmp(priority,"lower",5)) { sdl.priority.focus=PRIORITY_LEVEL_LOWER;next=5; } else if (!strncasecmp(priority,"normal",6)) { sdl.priority.focus=PRIORITY_LEVEL_NORMAL;next=6; @@ -905,7 +914,9 @@ static void GUI_StartUp(Section * sec) { priority=&priority[next]; if (next && priority[0]==',' && priority[1]) { priority++; - if (!strncasecmp(priority,"lower",5)) { + if (!strncasecmp(priority,"lowest",6)) { + sdl.priority.nofocus=PRIORITY_LEVEL_LOWEST; + } else if (!strncasecmp(priority,"lower",5)) { sdl.priority.nofocus=PRIORITY_LEVEL_LOWER; } else if (!strncasecmp(priority,"normal",6)) { sdl.priority.nofocus=PRIORITY_LEVEL_NORMAL; @@ -1273,7 +1284,7 @@ int main(int argc, char* argv[]) { "autolock -- Mouse will automatically lock, if you click on the screen.\n" "sensitiviy -- Mouse sensitivity.\n" "waitonerror -- Wait before closing the console if dosbox has an error.\n" - "priority -- Priority levels for dosbox: lower,normal,higher,highest.\n" + "priority -- Priority levels for dosbox: lowest,lower,normal,higher,highest.\n" " Second entry behind the comma is for when dosbox is not focused/minimized.\n" "mapperfile -- File used to load/save the key/event mappings from.\n" "usescancodes -- Avoid usage of symkeys, might not work on all operating systems.\n" From 2315b01df00a4deb75402576c6c73ef315b0e2bd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 12 Feb 2006 13:32:30 +0000 Subject: [PATCH 2402/4131] Add patch:" [ 1391443 ] directory iterators for the iso drive" from prompt Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2486 --- src/dos/drive_iso.cpp | 185 +++++++++++++++++++++++++++--------------- src/dos/drives.h | 26 +++++- 2 files changed, 141 insertions(+), 70 deletions(-) diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 5dea73ed..aefa0ba0 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.11 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.12 2006-02-12 13:32:30 qbix79 Exp $ */ #include #include @@ -145,13 +145,16 @@ bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name); isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &error) { + nextFreeDirIterator = 0; + memset(dirIterators, 0, sizeof(dirIterators)); + memset(sectorHashEntries, 0, sizeof(sectorHashEntries)); + memset(&rootEntry, 0, sizeof(isoDirEntry)); + error = MSCDEX_AddDrive(driveLetter, fileName, subUnit); if (!error) { if (loadImage()) { strcpy(info, "isoDrive"); - searchCache.clear(); - dirIter = searchCache.end(); this->mediaid = mediaid; char buffer[32] = { 0 }; if (!MSCDEX_GetVolumeName(subUnit, buffer)) strcpy(buffer, ""); @@ -242,25 +245,8 @@ bool isoDrive::FindFirst(char *dir, DOS_DTA &dta, bool fcb_findfirst) return false; } - Bit32u sectorStart = EXTENT_LOCATION(de); - Bit32u sectorEnd = sectorStart + DATA_LENGTH(de) / ISO_FRAMESIZE; - if (DATA_LENGTH(de) % ISO_FRAMESIZE != 0) sectorEnd++; - searchCache.clear(); - - for(Bit32u sector = sectorStart; sector < sectorEnd; sector++) { - Bit8u block[ISO_FRAMESIZE]; - readSector(block, sector); - - Bit32u pos = 0; - while (pos < ISO_FRAMESIZE && block[pos] != 0 && (pos + block[pos]) <= ISO_FRAMESIZE) { - isoDirEntry tmp; - int length = readDirEntry(&tmp, &block[pos]); - if (length < 0) return false; - searchCache.push_back(tmp); - pos += length; - } - } - dirIter = searchCache.begin(); + // get a directory iterator and save its id in the dta + dta.SetDirID(GetDirIterator(&de)); Bit8u attr; char pattern[ISO_MAXPATHNAME]; @@ -291,8 +277,10 @@ bool isoDrive::FindNext(DOS_DTA &dta) char pattern[DOS_NAMELENGTH_ASCII]; dta.GetSearchParams(attr, pattern); - while (dirIter != searchCache.end()) { - isoDirEntry &de = *dirIter; + int dirIterator = dta.GetDirID(); + + isoDirEntry de; + while (GetNextDirEntry(dirIterator, &de)) { Bit8u findAttr = 0; if (IS_DIR(de.fileFlags)) findAttr |= DOS_ATTR_DIRECTORY; else findAttr |= DOS_ATTR_ARCHIVE; @@ -303,6 +291,7 @@ bool isoDrive::FindNext(DOS_DTA &dta) /* file is okay, setup everything to be copied in DTA Block */ char findName[DOS_NAMELENGTH_ASCII]; + findName[0] = 0; if(strlen((char*)de.ident) < DOS_NAMELENGTH_ASCII) { strcpy(findName, (char*)de.ident); upcase(findName); @@ -311,12 +300,11 @@ bool isoDrive::FindNext(DOS_DTA &dta) Bit16u findDate = DOS_PackDate(1900 + de.dateYear, de.dateMonth, de.dateDay); Bit16u findTime = DOS_PackTime(de.timeHour, de.timeMin, de.timeSec); dta.SetResult(findName, findSize, findDate, findTime, findAttr); - - dirIter++; return true; } - dirIter++; } + // after searching the directory, free the iterator + FreeDirIterator(dirIterator); DOS_SetError(DOSERR_NO_MORE_FILES); return false; @@ -386,6 +374,88 @@ bool isoDrive::isRemovable(void) return true; } +int isoDrive::GetDirIterator(const isoDirEntry* de) +{ + int dirIterator = nextFreeDirIterator; + + // get start and end sector of the directory entry (pad end sector if necessary) + dirIterators[dirIterator].currentSector = EXTENT_LOCATION(*de); + dirIterators[dirIterator].endSector = + EXTENT_LOCATION(*de) + DATA_LENGTH(*de) / ISO_FRAMESIZE - 1; + if (DATA_LENGTH(*de) % ISO_FRAMESIZE != 0) + dirIterators[dirIterator].endSector++; + + // reset position and mark as valid + dirIterators[dirIterator].pos = 0; + dirIterators[dirIterator].valid = true; + + // advance to next directory iterator (wrap around if necessary) + nextFreeDirIterator = (nextFreeDirIterator + 1) % MAX_OPENDIRS; + + return dirIterator; +} + +bool isoDrive::GetNextDirEntry(const int dirIteratorHandle, isoDirEntry* de) +{ + bool result = false; + Bit8u* buffer = NULL; + DirIterator& dirIterator = dirIterators[dirIteratorHandle]; + + // check if the directory entry is valid + if (dirIterator.valid && ReadCachedSector(&buffer, dirIterator.currentSector)) { + // check if the next sector has to be read + if ((dirIterator.pos >= ISO_FRAMESIZE) + || (buffer[dirIterator.pos] == 0) + || (dirIterator.pos + buffer[dirIterator.pos] > ISO_FRAMESIZE)) { + + // check if there is another sector available + if (dirIterator.currentSector < dirIterator.endSector) { + dirIterator.pos = 0; + dirIterator.currentSector++; + if (!ReadCachedSector(&buffer, dirIterator.currentSector)) { + return false; + } + } else { + return false; + } + } + // read sector and advance sector pointer + int length = readDirEntry(de, &buffer[dirIterator.pos]); + result = length >= 0; + dirIterator.pos += length; + } + return result; +} + +void isoDrive::FreeDirIterator(const int dirIterator) +{ + dirIterators[dirIterator].valid = false; + + // if this was the last aquired iterator decrement nextFreeIterator + if ((dirIterator + 1) % MAX_OPENDIRS == nextFreeDirIterator) { + nextFreeDirIterator--; + } +} + +bool isoDrive::ReadCachedSector(Bit8u** buffer, const Bit32u sector) +{ + // get hash table entry + int pos = sector % ISO_MAX_HASH_TABLE_SIZE; + SectorHashEntry& he = sectorHashEntries[pos]; + + // check if the entry is valid and contains the correct sector + if (!he.valid || he.sector != sector) { + if (!CDROM_Interface_Image::images[subUnit]->ReadSector(he.data, false, sector)) { + return false; + } + he.valid = true; + he.sector = sector; + } + + *buffer = he.data; + return true; +} + inline bool isoDrive :: readSector(Bit8u *buffer, Bit32u sector) { return CDROM_Interface_Image::images[subUnit]->ReadSector(buffer, false, sector); @@ -431,33 +501,6 @@ bool isoDrive :: loadImage() return (readDirEntry(&this->rootEntry, pvd.rootEntry)); } -bool isoDrive :: lookupSingle(isoDirEntry *de, const char *name, Bit32u start, Bit32u length) -{ - Bit32u end = start + length / ISO_FRAMESIZE; - if (length % ISO_FRAMESIZE != 0) end++; - - // copy filename and if it has no extension remove the trailing dot - char newname[38]; - safe_strncpy(newname, name, 38); - int name_len = strlen(newname); - if (name_len > 0 && newname[name_len - 1] == '.') newname[name_len - 1] = 0; - - for(Bit32u i = start; i < end; i++) { - Bit8u sector[ISO_FRAMESIZE]; - if (!readSector(sector, i)) return false; - - int pos = 0; - while (pos < ISO_FRAMESIZE && sector[pos] != 0 && (pos + sector[pos]) <= ISO_FRAMESIZE) { - int deLength = readDirEntry(de, §or[pos]); - if (deLength < 1) return false; - pos += deLength; - int tmp = strncasecmp((char*)de->ident, newname, 38); - if (tmp == 0) return true; - } - } - return false; -} - bool isoDrive :: lookup(isoDirEntry *de, const char *path) { *de = this->rootEntry; @@ -467,19 +510,27 @@ bool isoDrive :: lookup(isoDirEntry *de, const char *path) safe_strncpy(isoPath, path, ISO_MAXPATHNAME); strreplace(isoPath, '\\', '/'); - int beginPos = 0; - int pos = 0; - while (isoPath[pos] != 0) { - if (isoPath[pos] == '/') { - char name[38]; - if (pos - beginPos >= 38) return false; - if (beginPos >= ISO_MAXPATHNAME) return false; - safe_strncpy(name, &isoPath[beginPos], pos - beginPos + 1); - beginPos = pos + 1; - if (!IS_DIR(de->fileFlags)) return false; - if (!lookupSingle(de, name, EXTENT_LOCATION(*de), DATA_LENGTH(*de))) return false; + // iterate over all path elements (name), and search each of them in the current de + for(char* name = strtok(isoPath, "/"); NULL != name; name = strtok(NULL, "/")) { + + bool found = false; + // current entry must be a directory, abort otherwise + if (IS_DIR(de->fileFlags)) { + + // remove the trailing dot if present + int nameLength = strlen(name); + if (nameLength > 0 && name[nameLength - 1] == '.') name[nameLength - 1] = 0; + + // look for the current path element + int dirIterator = GetDirIterator(de); + while (!found && GetNextDirEntry(dirIterator, de)) { + if (0 == strncasecmp((char*) de->ident, name, ISO_MAX_FILENAME_LENGTH)) { + found = true; + } + } + FreeDirIterator(dirIterator); } - pos++; + if (!found) return false; } - return lookupSingle(de, &isoPath[beginPos], EXTENT_LOCATION(*de), DATA_LENGTH(*de)); + return true; } diff --git a/src/dos/drives.h b/src/dos/drives.h index d9141f05..2c65ff1d 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.30 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: drives.h,v 1.31 2006-02-12 13:32:30 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ @@ -275,10 +275,12 @@ struct isoDirEntry { #define ISO_FRAMESIZE 2048 #define ISO_DIRECTORY 2 #define ISO_HIDDEN 1 +#define ISO_MAX_FILENAME_LENGTH 37 #define ISO_MAXPATHNAME 256 #define ISO_FIRST_VD 16 #define IS_DIR(fileFlags) (fileFlags & ISO_DIRECTORY) #define IS_HIDDEN(fileFlags) (fileFlags & ISO_HIDDEN) +#define ISO_MAX_HASH_TABLE_SIZE 100 class isoDrive : public DOS_Drive { public: @@ -308,9 +310,27 @@ private: bool loadImage(); bool lookupSingle(isoDirEntry *de, const char *name, Bit32u sectorStart, Bit32u length); bool lookup(isoDirEntry *de, const char *path); + + int GetDirIterator(const isoDirEntry* de); + bool GetNextDirEntry(const int dirIterator, isoDirEntry* de); + void FreeDirIterator(const int dirIterator); + bool ReadCachedSector(Bit8u** buffer, const Bit32u sector); + + struct DirIterator { + bool valid; + Bit32u currentSector; + Bit32u endSector; + Bit32u pos; + } dirIterators[MAX_OPENDIRS]; + + int nextFreeDirIterator; + + struct SectorHashEntry { + bool valid; + Bit32u sector; + Bit8u data[ISO_FRAMESIZE]; + } sectorHashEntries[ISO_MAX_HASH_TABLE_SIZE]; - std::vector searchCache; - std::vector::iterator dirIter; isoDirEntry rootEntry; Bit8u mediaid; Bit8u subUnit; From 19985730a329614f7ba5b1822958a3c9221da39a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 12 Feb 2006 23:06:15 +0000 Subject: [PATCH 2403/4131] Disable LFB in 4bpp vesa modes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2487 --- src/ints/int10_vesa.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index b776f28b..0330efa2 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.22 2006-02-09 11:47:57 qbix79 Exp $ */ +/* $Id: int10_vesa.cpp,v 1.23 2006-02-12 23:06:15 harekiet Exp $ */ #include #include @@ -142,6 +142,7 @@ foundit: var_write(&minfo.BytesPerScanLine,mblock->swidth/8); var_write(&minfo.BitsPerPixel,4); var_write(&minfo.MemoryModel,3); //ega planar mode + var_write(&minfo.ModeAttributes,0x1b); //Color, graphics, no linear buffer break; case M_LIN8: pageSize = mblock->sheight * mblock->swidth; @@ -149,7 +150,8 @@ foundit: var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); var_write(&minfo.BytesPerScanLine,mblock->swidth); var_write(&minfo.BitsPerPixel,8); - var_write(&minfo.MemoryModel,4); //packed pixel + var_write(&minfo.MemoryModel,4); //packed pixel + var_write(&minfo.ModeAttributes,0x9b); //Color, graphics, linear buffer break; case M_LIN15: pageSize = mblock->sheight * mblock->swidth*2; @@ -164,6 +166,7 @@ foundit: var_write(&minfo.GreenMaskPos,5); var_write(&minfo.BlueMaskSize,5); var_write(&minfo.BlueMaskPos,0); + var_write(&minfo.ModeAttributes,0x9b); //Color, graphics, linear buffer break; case M_LIN16: pageSize = mblock->sheight * mblock->swidth*2; @@ -178,6 +181,7 @@ foundit: var_write(&minfo.GreenMaskPos,5); var_write(&minfo.BlueMaskSize,5); var_write(&minfo.BlueMaskPos,0); + var_write(&minfo.ModeAttributes,0x9b); //Color, graphics, linear buffer break; case M_LIN32: pageSize = mblock->sheight * mblock->swidth*4; @@ -194,12 +198,11 @@ foundit: var_write(&minfo.BlueMaskPos,0x0); var_write(&minfo.ReservedMaskSize,0x8); var_write(&minfo.ReservedMaskPos,0x18); + var_write(&minfo.ModeAttributes,0x9b); //Color, graphics, linear buffer break; default: return 0x1; } - - var_write(&minfo.ModeAttributes,0x9b); var_write(&minfo.WinAAttributes,0x7); //Exists/readable/writable var_write(&minfo.WinGranularity,64); var_write(&minfo.WinSize,64); From b81c210530d60c0d1ea984f6e5bb3a9926909a01 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 12 Feb 2006 23:23:52 +0000 Subject: [PATCH 2404/4131] New format for mapper handlers to support keeping keys pressed. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2488 --- include/debug.h | 2 +- include/mapper.h | 4 ++-- src/debug/debug.cpp | 8 +++++--- src/gui/sdl_mapper.cpp | 12 +++++++----- src/ints/bios_disk.cpp | 6 ++++-- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/include/debug.h b/include/debug.h index 112f668e..ce8a0028 100644 --- a/include/debug.h +++ b/include/debug.h @@ -20,7 +20,7 @@ void DEBUG_SetupConsole(void); void DEBUG_DrawScreen(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); diff --git a/include/mapper.h b/include/mapper.h index 90813f06..d789deda 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -25,11 +25,11 @@ enum MapKeys { }; -typedef void (MAPPER_Handler)(void); +typedef void (MAPPER_Handler)(bool pressed); void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char * eventname,char * buttonname); void MAPPER_Init(void); void MAPPER_StartUp(Section * sec); -void MAPPER_Run(void); +void MAPPER_Run(bool pressed); void MAPPER_LosingFocus(void); diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index a4792c94..9c781bf4 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.74 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.75 2006-02-12 23:23:52 harekiet Exp $ */ #include #include @@ -1660,7 +1660,9 @@ Bitu DEBUG_Loop(void) { return DEBUG_CheckKeys(); } -void DEBUG_Enable(void) { +void DEBUG_Enable(bool pressed) { + if (!pressed) + return; static bool showhelp=false; debugging=true; SetCodeWinStart(); @@ -1947,7 +1949,7 @@ void DEBUG_CheckExecuteBreakpoint(Bit16u seg, Bit32u off) Bitu DEBUG_EnableDebugger(void) { exitLoop = true; - DEBUG_Enable(); + DEBUG_Enable(true); CPU_Cycles=CPU_CycleLeft=0; return 0; }; diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 9e4b0c8b..f8438d8f 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.19 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.20 2006-02-12 23:23:52 harekiet Exp $ */ #define OLD_JOYSTICK 1 @@ -996,7 +996,7 @@ public: handlergroup.push_back(this); } void Active(bool yesno) { - if (yesno) (*handler)(); + (*handler)(yesno); }; char * ButtonName(void) { return buttonname; @@ -1502,8 +1502,8 @@ static void CreateBindGroups(void) { case JOY_2AXIS: default: new CStickBindGroup(joyno); - if((joyno+1) < numsticks) - new CStickBindGroup(joyno+1); + if((joyno+1U) < numsticks) + new CStickBindGroup(joyno+1U); break; } } @@ -1515,7 +1515,9 @@ void MAPPER_LosingFocus(void) { } } -void MAPPER_Run(void) { +void MAPPER_Run(bool pressed) { + if (!pressed) + return; /* Deactive all running binds */ for (CEventVector_it evit=events.begin();evit!=events.end();evit++) { (*evit)->DeActivateAll(); diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index d1721388..72f66a72 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.26 2006-02-09 11:47:56 qbix79 Exp $ */ +/* $Id: bios_disk.cpp,v 1.27 2006-02-12 23:23:52 harekiet Exp $ */ #include "dosbox.h" #include "callback.h" @@ -112,7 +112,9 @@ void swapInDisks(void) { } } -void swapInNextDisk(void) { +void swapInNextDisk(bool pressed) { + if (!pressed) + return; /* Hack/feature: rescan all disks as well */ for(Bitu i=0;iEmptyCache(); From 03633e3a5c9505cf71ba2cf425518d6494870850 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 12 Feb 2006 23:25:46 +0000 Subject: [PATCH 2405/4131] New format for mapper handlers to support keeping keys pressed. Add png capturing of 15,16,32bpp input Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2489 --- src/hardware/adlib.cpp | 6 +- src/hardware/hardware.cpp | 140 ++++++++++++++++++++++++-------------- 2 files changed, 93 insertions(+), 53 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 7daf7797..403b128e 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -283,7 +283,9 @@ static void OPL_RawAdd(Bitu index,Bitu val) { if (opl.raw.used>=RAW_SIZE) OPL_RawEmptyBuffer(); } -static void OPL_SaveRawEvent(void) { +static void OPL_SaveRawEvent(bool pressed) { + if (!pressed) + return; /* Check for previously opened wave file */ if (opl.raw.handle) { OPL_RawEmptyBuffer(); @@ -351,7 +353,7 @@ public: MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL"); } ~OPL() { - if (opl.raw.handle) OPL_SaveRawEvent(); + if (opl.raw.handle) OPL_SaveRawEvent(true); OPL2::YM3812Shutdown(); THEOPL3::YMF262Shutdown(); } diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 0d073f49..0cc8e657 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: hardware.cpp,v 1.12 2006-02-09 11:47:49 qbix79 Exp $ */ +/* $Id: hardware.cpp,v 1.13 2006-02-12 23:25:46 harekiet Exp $ */ #include #include @@ -147,7 +147,9 @@ static void CAPTURE_AddAviChunk(const char * tag, Bit32u size, void * data, Bit3 } #endif -static void CAPTURE_VideoEvent(void) { +static void CAPTURE_VideoEvent(bool pressed) { + if (!pressed) + return; #if (C_SSHOT) if (CaptureState & CAPTURE_VIDEO) { /* Close the video */ @@ -285,7 +287,8 @@ static void CAPTURE_VideoEvent(void) { void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags, float fps, Bit8u * data, Bit8u * pal) { Bitu i; #if (C_SSHOT) - Bit32u doubleRow[SCALER_MAXWIDTH]; + Bit8u doubleRow[SCALER_MAXWIDTH*4]; + Bitu countWidth = width; if (flags & CAPTURE_FLAG_DBLH) height *= 2; @@ -337,52 +340,81 @@ void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags, } png_set_PLTE(png_ptr, info_ptr, palette,256); } else { - png_set_swap(png_ptr); - if (bpp == 32) { - png_set_IHDR(png_ptr, info_ptr, width, height, - 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - } else { - png_set_IHDR(png_ptr, info_ptr, width, height, - 16, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - } + png_set_bgr( png_ptr ); + png_set_IHDR(png_ptr, info_ptr, width, height, + 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); } png_write_info(png_ptr, info_ptr); for (i=0;i> 1; - if (flags & CAPTURE_FLAG_DBLH) - srcLine=(data+(i >> 1)*pitch); - else - srcLine=(data+(i >> 0)*pitch); - switch ( bpp) { - case 8: - for (x=0;x> 1)*pitch); + else + srcLine=(data+(i >> 0)*pitch); + rowPointer=srcLine; + switch (bpp) { + case 8: + if (flags & CAPTURE_FLAG_DBLW) { + for (Bitu x=0;x> 1)*pitch); - else - rowPointer=(data+(i >> 0)*pitch); + break; + case 15: + if (flags & CAPTURE_FLAG_DBLW) { + for (Bitu x=0;x> 2; + doubleRow[x*6+1] = doubleRow[x*6+4] = ((pixel& 0x03e0) * 0x21) >> 7; + doubleRow[x*6+2] = doubleRow[x*6+5] = ((pixel& 0x7c00) * 0x21) >> 12; + } + } else { + for (Bitu x=0;x> 2; + doubleRow[x*3+1] = ((pixel& 0x03e0) * 0x21) >> 7; + doubleRow[x*3+2] = ((pixel& 0x7c00) * 0x21) >> 12; + } + } + rowPointer = doubleRow; + break; + case 16: + if (flags & CAPTURE_FLAG_DBLW) { + for (Bitu x=0;x> 2; + doubleRow[x*6+1] = doubleRow[x*6+4] = ((pixel& 0x07e0) * 0x41) >> 9; + doubleRow[x*6+2] = doubleRow[x*6+5] = ((pixel& 0xf800) * 0x21) >> 13; + } + } else { + for (Bitu x=0;x> 2; + doubleRow[x*3+1] = ((pixel& 0x07e0) * 0x41) >> 9; + doubleRow[x*3+2] = ((pixel& 0xf800) * 0x21) >> 13; + } + } + rowPointer = doubleRow; + break; + case 32: + if (flags & CAPTURE_FLAG_DBLW) { + for (Bitu x=0;x Date: Sun, 12 Feb 2006 23:28:21 +0000 Subject: [PATCH 2406/4131] New format for mapper handlers to support keeping keys pressed. Add unlocked speed hotkey Add some sort of auto cycle guessing Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2490 --- include/cpu.h | 1 + src/cpu/callback.cpp | 7 ++-- src/cpu/cpu.cpp | 21 ++++++++--- src/dosbox.cpp | 84 ++++++++++++++++++++++++++++++++------------ 4 files changed, 83 insertions(+), 30 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 5c07092a..9e755a12 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -33,6 +33,7 @@ extern Bits CPU_Cycles; extern Bits CPU_CycleLeft; extern Bits CPU_CycleMax; +extern bool CPU_CycleAuto; /* Some common Defines */ /* A CPU Handler */ diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 29a14244..91f13f49 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.30 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: callback.cpp,v 1.31 2006-02-12 23:28:21 harekiet Exp $ */ #include #include @@ -31,7 +31,6 @@ far return or and IRET */ - CallBack_Handler CallBack_Handlers[CB_MAX]; char* CallBack_Description[CB_MAX]; @@ -58,6 +57,7 @@ void CALLBACK_DeAllocate(Bitu in) { CallBack_Handlers[in]=&illegal_handler; } + void CALLBACK_Idle(void) { /* this makes the cpu execute instructions to handle irq's and then come back */ Bitu oldIF=GETFLAG(IF); @@ -70,7 +70,8 @@ void CALLBACK_Idle(void) { reg_eip=oldeip; SegSet16(cs,oldcs); SETFLAGBIT(IF,oldIF); - if (CPU_Cycles>0) CPU_Cycles=0; + if (!CPU_CycleAuto && CPU_Cycles>0) + CPU_Cycles=0; } static Bitu default_handler(void) { diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index a4f87ad0..ff74d7af 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.76 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.77 2006-02-12 23:28:21 harekiet Exp $ */ #include #include "dosbox.h" @@ -45,6 +45,7 @@ Bits CPU_CycleMax = 2500; Bits CPU_CycleUp = 0; Bits CPU_CycleDown = 0; CPU_Decoder * cpudecoder; +bool CPU_CycleAuto; void CPU_Core_Full_Init(void); void CPU_Core_Normal_Init(void); @@ -52,7 +53,6 @@ void CPU_Core_Simple_Init(void); void CPU_Core_Dyn_X86_Init(void); void CPU_Core_Dyn_X86_Cache_Init(bool enable_cache); - /* In debug mode exceptions are tested and dosbox exits when * a unhandled exception state is detected. * USE CHECK_EXCEPT to raise an exception in that case to see if that exception @@ -1876,7 +1876,9 @@ void CPU_ENTER(bool use32,Bitu bytes,Bitu level) { } extern void GFX_SetTitle(Bits cycles ,Bits frameskip,bool paused); -static void CPU_CycleIncrease(void) { +static void CPU_CycleIncrease(bool pressed) { + if (!pressed) + return; Bits old_cycles=CPU_CycleMax; if(CPU_CycleUp < 100){ CPU_CycleMax = (Bits)(CPU_CycleMax * (1 + (float)CPU_CycleUp / 100.0)); @@ -1890,7 +1892,9 @@ static void CPU_CycleIncrease(void) { GFX_SetTitle(CPU_CycleMax,-1,false); } -static void CPU_CycleDecrease(void) { +static void CPU_CycleDecrease(bool pressed) { + if (!pressed) + return; if(CPU_CycleDown < 100){ CPU_CycleMax = (Bits)(CPU_CycleMax / (1 + (float)CPU_CycleDown / 100.0)); } else { @@ -1958,7 +1962,14 @@ public: Section_prop * section=static_cast(newconfig); CPU_CycleLeft=0;//needed ? CPU_Cycles=0; - CPU_CycleMax=section->Get_int("cycles");; + const char *cyclesLine = section->Get_string("cycles"); + if (!strcasecmp(cyclesLine,"auto")) { + CPU_CycleMax=0; + CPU_CycleAuto=true; + } else { + CPU_CycleMax=atoi(cyclesLine); + CPU_CycleAuto=false; + } CPU_CycleUp=section->Get_int("cycleup"); CPU_CycleDown=section->Get_int("cycledown"); const char * core=section->Get_string("core"); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index cc51cef0..c6ffdf33 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.93 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.94 2006-02-12 23:28:21 harekiet Exp $ */ #include #include @@ -38,6 +38,7 @@ #include "cross.h" #include "programs.h" #include "support.h" +#include "mapper.h" Config * control; MachineType machine; @@ -109,11 +110,15 @@ static LoopHandler * loop; bool SDLNetInited; -Bits RemainTicks; -Bits LastTicks; +static Bit32u ticksRemain; +static Bit32u ticksLast; +static Bit32u ticksAdded; +static Bit32u ticksDone; +static Bit32u ticksScheduled; +static bool ticksLocked; static Bitu Normal_Loop(void) { - Bits ret,NewTicks; + Bits ret; while (1) { if (PIC_RunQueue()) { ret=(*cpudecoder)(); @@ -126,27 +131,51 @@ static Bitu Normal_Loop(void) { if (DEBUG_ExitLoop()) return 0; #endif } else { - if (RemainTicks>0) { + GFX_Events(); + if (ticksRemain>0) { TIMER_AddTick(); - RemainTicks--; + ticksRemain--; } else goto increaseticks; } } increaseticks: - GFX_Events(); - NewTicks=GetTicks(); - if (NewTicks>LastTicks) { - RemainTicks=NewTicks-LastTicks; - if (RemainTicks>20) { -// LOG_MSG("Ticks to handle overflow %d",RemainTicks); - RemainTicks=20; + if (GCC_UNLIKELY(ticksLocked)) { + ticksRemain=5; + /* Reset any auto cycle guessing for this frame */ + ticksLast = GetTicks(); + ticksAdded = 0; + ticksDone = 0; + ticksScheduled = 0; + } else { + Bit32u ticksNew; + ticksNew=GetTicks(); + ticksScheduled += ticksAdded; + if (ticksNew > ticksLast) { + ticksRemain = ticksNew-ticksLast; + ticksLast = ticksNew; + ticksDone += ticksRemain; + if ( ticksRemain > 20 ) { + ticksRemain = 20; + } + ticksAdded = ticksRemain; + if (CPU_CycleAuto && (ticksScheduled >= 1000 || ticksDone >= 1000) ) { + /* ratio we are aiming for is around 90% usage*/ + Bits ratio = (ticksScheduled * (90*1024/100)) / ticksDone ; +// LOG_MSG("Done %d schedulded %d ratio %d cycles %d", ticksDone, ticksScheduled, ratio, CPU_CycleMax); + if (ratio <= 1024) + CPU_CycleMax = (CPU_CycleMax * ratio) / 1024; + else + CPU_CycleMax = 1 + (CPU_CycleMax >> 1) + (CPU_CycleMax * ratio) / 2048; + ticksDone = 0; + ticksScheduled = 0; + } + } else { + ticksAdded = 0; + SDL_Delay(1); + ticksDone -= GetTicks() - ticksNew; + if (ticksDone < 0) + ticksDone = 0; } - LastTicks=NewTicks; - } - //TODO Make this selectable in the config file, since it gives some lag */ - if (RemainTicks<=0) { - SDL_Delay(1); - return 0; } return 0; } @@ -166,16 +195,27 @@ void DOSBOX_RunMachine(void){ } while (!ret); } +static void DOSBOX_UnlockSpeed( bool pressed ) { + if (pressed) + ticksLocked = true; + else + ticksLocked = false; +} + static void DOSBOX_RealInit(Section * sec) { Section_prop * section=static_cast(sec); /* Initialize some dosbox internals */ - RemainTicks=0;LastTicks=GetTicks(); + ticksRemain=0; + ticksLast=GetTicks(); + ticksLocked = false; DOSBOX_SetLoop(&Normal_Loop); MSG_Init(section); + MAPPER_AddHandler(DOSBOX_UnlockSpeed, MK_f12, MMOD2,"speedlock","Speedlock"); svgaCard = SVGA_S3Trio; - machine=MCH_VGA;std::string cmd_machine; + machine=MCH_VGA; + std::string cmd_machine; const char * mtype; if (control->cmdline->FindString("-machine",cmd_machine,true)) mtype=cmd_machine.c_str(); else mtype=section->Get_string("machine"); @@ -236,7 +276,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("cpu",&CPU_Init,true);//done secprop->Add_string("core","normal"); - secprop->Add_int("cycles",3000); + secprop->Add_string("cycles","3000"); secprop->Add_int("cycleup",500); secprop->Add_int("cycledown",20); MSG_Add("CPU_CONFIGFILE_HELP", From 2fb65fe0ee672829ce68c1b541537df9aeee01c7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 12 Feb 2006 23:39:37 +0000 Subject: [PATCH 2407/4131] New format for mapper handlers to support keeping keys pressed. Better support for double buffering with surface output with the new cached scalers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2491 --- src/gui/sdlmain.cpp | 109 +++++++++++++++++++++++++++----------------- 1 file changed, 66 insertions(+), 43 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 6762c324..5c23a25a 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.101 2006-02-12 13:19:58 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.102 2006-02-12 23:39:37 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -180,13 +180,12 @@ struct SDL_Block { #endif } opengl; #endif -#if (HAVE_DDRAW_H) && defined(WIN32) struct { SDL_Surface * surface; +#if (HAVE_DDRAW_H) && defined(WIN32) RECT rect; - DDBLTFX fx; - } blit; #endif + } blit; struct { PRIORITY_LEVELS focus; PRIORITY_LEVELS nofocus; @@ -206,7 +205,6 @@ struct SDL_Block { }; static SDL_Block sdl; -static void CaptureMouse(void); extern char * RunningProgram; //Globals for keyboard initialisation @@ -378,6 +376,11 @@ Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,G Bitu bpp; Bitu retFlags; + + if (sdl.blit.surface) { + SDL_FreeSurface(sdl.blit.surface); + sdl.blit.surface=0; + } switch (sdl.desktop.want_type) { case SCREEN_SURFACE: dosurface: @@ -394,7 +397,7 @@ dosurface: sdl.clip.y=(Sint16)((sdl.desktop.full.height-height)/2); sdl.surface=SDL_SetVideoMode(sdl.desktop.full.width,sdl.desktop.full.height,bpp, SDL_FULLSCREEN | ((flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE) | - (sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0) | SDL_HWPALETTE); + (sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0) | SDL_HWPALETTE); if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",sdl.desktop.full.width,sdl.desktop.full.height,bpp,SDL_GetError()); } else { sdl.clip.x=0;sdl.clip.y=0; @@ -434,8 +437,18 @@ dosurface: retFlags = GFX_CAN_32; break; } - if (retFlags && sdl.surface->flags & SDL_HWSURFACE) + if (retFlags && (sdl.surface->flags & SDL_HWSURFACE)) retFlags |= GFX_HARDWARE; + if (retFlags && (sdl.surface->flags & SDL_DOUBLEBUF)) { + sdl.blit.surface=SDL_CreateRGBSurface(SDL_HWSURFACE, + sdl.draw.width, sdl.draw.height, + sdl.surface->format->BitsPerPixel, + sdl.surface->format->Rmask, + sdl.surface->format->Gmask, + sdl.surface->format->Bmask, + 0); + /* If this one fails be ready for some flickering... */ + } } break; #if (HAVE_DDRAW_H) && defined(WIN32) @@ -443,12 +456,6 @@ dosurface: if (flags & GFX_CAN_15) bpp=15; if (flags & GFX_CAN_16) bpp=16; if (flags & GFX_CAN_32) bpp=32; - if (sdl.blit.surface) { - SDL_FreeSurface(sdl.blit.surface); - sdl.blit.surface=0; - } - memset(&sdl.blit.fx,0,sizeof(DDBLTFX)); - sdl.blit.fx.dwSize=sizeof(DDBLTFX); if (!GFX_SetupSurfaceScaled((sdl.desktop.doublebuf && sdl.desktop.fullscreen) ? SDL_DOUBLEBUF : 0,bpp)) goto dosurface; sdl.blit.rect.top=sdl.clip.y; sdl.blit.rect.left=sdl.clip.x; @@ -593,8 +600,7 @@ dosurface: return retFlags; } -bool mouselocked; //Global variable for mapper -static void CaptureMouse(void) { +void GFX_CaptureMouse(void) { sdl.mouse.locked=!sdl.mouse.locked; if (sdl.mouse.locked) { SDL_WM_GrabInput(SDL_GRAB_ON); @@ -606,61 +612,71 @@ static void CaptureMouse(void) { mouselocked=sdl.mouse.locked; } -void GFX_CaptureMouse(void) { - CaptureMouse(); +bool mouselocked; //Global variable for mapper +static void CaptureMouse(bool pressed) { + if (!pressed) + return; + GFX_CaptureMouse(); } -static void SwitchFullScreen(void) { +void GFX_SwitchFullScreen(void) { sdl.desktop.fullscreen=!sdl.desktop.fullscreen; if (sdl.desktop.fullscreen) { - if (!sdl.mouse.locked) CaptureMouse(); + if (!sdl.mouse.locked) GFX_CaptureMouse(); } else { - if (sdl.mouse.locked) CaptureMouse(); + if (sdl.mouse.locked) GFX_CaptureMouse(); } GFX_ResetScreen(); } -void GFX_SwitchFullScreen(void) { - SwitchFullScreen(); +static void SwitchFullScreen(bool pressed) { + if (!pressed) + return; + GFX_SwitchFullScreen(); } + bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) { if (!sdl.active || sdl.updating) return false; - sdl.updating=true; switch (sdl.desktop.type) { case SCREEN_SURFACE: - if (SDL_MUSTLOCK(sdl.surface)) { - if (SDL_LockSurface(sdl.surface)) { -// LOG_MSG("SDL Lock failed"); - sdl.updating=false; + if (sdl.blit.surface) { + if (SDL_MUSTLOCK(sdl.blit.surface) && SDL_LockSurface(sdl.blit.surface)) return false; - } + pixels=(Bit8u *)sdl.blit.surface->pixels; + pitch=sdl.blit.surface->pitch; + } else { + if (SDL_MUSTLOCK(sdl.surface) && SDL_LockSurface(sdl.surface)) + return false; + pixels=(Bit8u *)sdl.surface->pixels; + pixels+=sdl.clip.y*sdl.surface->pitch; + pixels+=sdl.clip.x*sdl.surface->format->BytesPerPixel; + pitch=sdl.surface->pitch; } - pixels=(Bit8u *)sdl.surface->pixels; - pixels+=sdl.clip.y*sdl.surface->pitch; - pixels+=sdl.clip.x*sdl.surface->format->BytesPerPixel; - pitch=sdl.surface->pitch; + sdl.updating=true; return true; #if (HAVE_DDRAW_H) && defined(WIN32) case SCREEN_SURFACE_DDRAW: if (SDL_LockSurface(sdl.blit.surface)) { // LOG_MSG("SDL Lock failed"); - sdl.updating=false; return false; } pixels=(Bit8u *)sdl.blit.surface->pixels; pitch=sdl.blit.surface->pitch; + sdl.updating=true; return true; #endif case SCREEN_OVERLAY: SDL_LockYUVOverlay(sdl.overlay); pixels=(Bit8u *)*(sdl.overlay->pixels); pitch=*(sdl.overlay->pitches); + sdl.updating=true; return true; #if C_OPENGL case SCREEN_OPENGL: pixels=(Bit8u *)sdl.opengl.framebuf; pitch=sdl.opengl.pitch; + sdl.updating=true; return true; #endif } @@ -675,7 +691,12 @@ void GFX_EndUpdate( const Bit16u *changedLines ) { switch (sdl.desktop.type) { case SCREEN_SURFACE: if (SDL_MUSTLOCK(sdl.surface)) { - SDL_UnlockSurface(sdl.surface); + if (sdl.blit.surface) { + SDL_UnlockSurface(sdl.blit.surface); + LOG_MSG("Bit %d",SDL_BlitSurface( sdl.blit.surface, 0, sdl.surface, &sdl.clip )); + } else { + SDL_UnlockSurface(sdl.surface); + } SDL_Flip(sdl.surface); } else if (changedLines) { Bitu y = 0, index = 0, rectCount = 0; @@ -817,11 +838,13 @@ void GFX_Start() { static void GUI_ShutDown(Section * sec) { GFX_Stop(); if (sdl.draw.reset) (sdl.draw.reset)( true ); - if (sdl.mouse.locked) CaptureMouse(); - if (sdl.desktop.fullscreen) SwitchFullScreen(); + if (sdl.mouse.locked) GFX_CaptureMouse(); + if (sdl.desktop.fullscreen) GFX_SwitchFullScreen(); } -static void KillSwitch(void){ +static void KillSwitch(bool pressed) { + if (!pressed) + return; throw 1; } @@ -1090,12 +1113,12 @@ static void HandleMouseButton(SDL_MouseButtonEvent * button) { switch (button->state) { case SDL_PRESSED: if (sdl.mouse.requestlock && !sdl.mouse.locked) { - CaptureMouse(); + GFX_CaptureMouse(); // Dont pass klick to mouse handler break; } if (!sdl.mouse.autoenable && sdl.mouse.autolock && button->button == SDL_BUTTON_MIDDLE) { - CaptureMouse(); + GFX_CaptureMouse(); break; } switch (button->button) { @@ -1138,7 +1161,7 @@ void GFX_Events() { if (event.active.state & SDL_APPINPUTFOCUS) { if (event.active.gain) { if (sdl.desktop.fullscreen && !sdl.mouse.locked) - CaptureMouse(); + GFX_CaptureMouse(); SetPriority(sdl.priority.focus); } else { if (sdl.mouse.locked) { @@ -1149,7 +1172,7 @@ void GFX_Events() { GFX_ResetScreen(); } #endif - CaptureMouse(); + GFX_CaptureMouse(); } SetPriority(sdl.priority.nofocus); MAPPER_LosingFocus(); @@ -1318,13 +1341,13 @@ int main(int argc, char* argv[]) { /* Some extra SDL Functions */ if (control->cmdline->FindExist("-fullscreen") || sdl_sec->Get_bool("fullscreen")) { if(!sdl.desktop.fullscreen) { //only switch if not allready in fullscreen - SwitchFullScreen(); + GFX_SwitchFullScreen(); } } /* Init the keyMapper */ MAPPER_Init(); - if (control->cmdline->FindExist("-startmapper")) MAPPER_Run(); + if (control->cmdline->FindExist("-startmapper")) MAPPER_Run(true); /* Start up main machine */ control->StartUp(); From 397220ea1df0b789f6820140b186334a9bf90ef9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 12 Feb 2006 23:43:54 +0000 Subject: [PATCH 2408/4131] Rewrite the simple scalers to handle everything in one pass for less memory strain Limit the complex scalers to a lower resolution and share some memory for framecache fix image output to reduce FPS when capturing with frameskip Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2492 --- include/render.h | 14 +- src/gui/render.cpp | 191 ++++++++++++------------- src/gui/render_loops.h | 23 +-- src/gui/render_scalers.cpp | 278 +++++++++++++++++++++++------------- src/gui/render_scalers.h | 81 +++++------ src/gui/render_simple.h | 119 ++++++++++++++++ src/gui/render_templates.h | 281 ++++++++++++++----------------------- 7 files changed, 545 insertions(+), 442 deletions(-) create mode 100644 src/gui/render_simple.h diff --git a/include/render.h b/include/render.h index 8bf71afd..539e40ea 100644 --- a/include/render.h +++ b/include/render.h @@ -32,10 +32,10 @@ typedef struct { Bit16u b16[256]; Bit32u b32[256]; } lut; - bool modified[256]; + bool changed; + Bit8u modified[256]; Bitu first; Bitu last; - bool changed; } RenderPal_t; typedef struct { @@ -56,15 +56,15 @@ typedef struct { scalerMode_t inMode; scalerMode_t outMode; scalerOperation_t op; - ScalerLineHandler_t currentHandler; - Bitu lineFlags; bool clearCache; - ScalerCacheHandler_t clearCacheHandler; ScalerLineHandler_t lineHandler; - ScalerCacheHandler_t cacheHandler; + 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; @@ -74,7 +74,7 @@ typedef struct { } Render_t; extern Render_t render; -void RENDER_DrawLine( const void *src ); +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( bool fullUpdate ); diff --git a/src/gui/render.cpp b/src/gui/render.cpp index a78398c2..52d36120 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.40 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.41 2006-02-12 23:43:54 harekiet Exp $ */ #include #include @@ -35,6 +35,7 @@ #include "render_scalers.h" Render_t render; +ScalerLineHandler_t RENDER_DrawLine; static void Check_Palette(void) { /* Clean up any previous changed palette data */ @@ -58,6 +59,7 @@ static void Check_Palette(void) { Bit16u newPal = GFX_GetRGB(r,g,b); if (newPal != render.pal.lut.b16[i]) { render.pal.changed = true; + render.pal.modified[i] = 1; render.pal.lut.b16[i] = newPal; } } @@ -71,6 +73,7 @@ static void Check_Palette(void) { Bit32u newPal = GFX_GetRGB(r,g,b); if (newPal != render.pal.lut.b32[i]) { render.pal.changed = true; + render.pal.modified[i] = 1; render.pal.lut.b32[i] = newPal; } } @@ -94,34 +97,18 @@ void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue) { if (render.pal.lastsimple[render.scale.outMode]; - } else { - render.scale.cacheHandler = cacheBlock->complex[render.scale.outMode]; - } /* Clearing the cache will first process the line to make sure it's never the same */ if (GCC_UNLIKELY( render.scale.clearCache) ) { // LOG_MSG("Clearing cache"); render.scale.clearCache = false; - render.scale.clearCacheHandler = render.scale.cacheHandler; - render.scale.cacheHandler = RENDER_ClearCacheHandler; + RENDER_DrawLine = RENDER_ClearCacheHandler; + } else { + if (render.pal.changed) + RENDER_DrawLine = render.scale.linePalHandler; + else + RENDER_DrawLine = render.scale.lineHandler; } - render.scale.lineHandler = render.scale.currentHandler; render.updating=true; return true; } @@ -181,39 +149,25 @@ bool RENDER_StartUpdate(void) { void RENDER_EndUpdate( bool fullUpdate ) { if (!render.updating) return; - render.scale.cacheHandler = RENDER_EmptyCacheHandler; - render.scale.lineHandler = RENDER_EmptyLineHandler; + RENDER_DrawLine = RENDER_EmptyLineHandler; if (CaptureState & (CAPTURE_IMAGE|CAPTURE_VIDEO)) { Bitu pitch, flags; - switch (render.scale.inMode) { - case scalerMode8: - pitch = sizeof(scalerSourceCache.b8[0]); - break; - case scalerMode15: - case scalerMode16: - pitch = sizeof(scalerSourceCache.b16[0]); - break; - case scalerMode32: - pitch = sizeof(scalerSourceCache.b32[0]); - break; - } flags = 0; if (render.src.dblw != render.src.dblh) { if (render.src.dblw) flags|=CAPTURE_FLAG_DBLW; if (render.src.dblh) flags|=CAPTURE_FLAG_DBLH; } + float fps = render.src.fps; + pitch = render.scale.cachePitch; + if (render.frameskip.max) + fps /= 1+render.frameskip.max; CAPTURE_AddImage( render.src.width, render.src.height, render.src.bpp, pitch, - flags, render.src.fps, scalerSourceCache.b8[0], (Bit8u*)&render.pal.rgb ); + flags, fps, (Bit8u *)&scalerSourceCache, (Bit8u*)&render.pal.rgb ); } GFX_EndUpdate( fullUpdate ? Scaler_ChangedLines : 0); render.updating=false; } -void RENDER_DrawLine( const void *src ) { - render.scale.cacheHandler( src ); - render.scale.lineHandler(); -} - static Bitu MakeAspectTable(Bitu height,double scaley,Bitu miny) { double lines=0; Bitu linesadded=0; @@ -246,8 +200,9 @@ void RENDER_ReInit( bool stopIt ) { double gfx_scalew; double gfx_scaleh; - Bitu gfx_flags; - ScalerLineBlock_t *lineBlock; + Bitu gfx_flags, xscale, yscale; + ScalerSimpleBlock_t *simpleBlock = &ScaleNormal1x; + ScalerComplexBlock_t *complexBlock = 0; if (render.aspect) { if (render.src.ratio>1.0) { gfx_scalew = 1; @@ -260,77 +215,89 @@ void RENDER_ReInit( bool stopIt ) { gfx_scalew = 1; gfx_scaleh = 1; } - lineBlock = &ScaleNormal; if (dblh && dblw) { /* Initialize always working defaults */ if (render.scale.size == 2) - lineBlock = &ScaleNormal2x; + simpleBlock = &ScaleNormal2x; else if (render.scale.size == 3) - lineBlock = &ScaleNormal3x; + simpleBlock = &ScaleNormal3x; else - lineBlock = &ScaleNormal; + simpleBlock = &ScaleNormal1x; /* Maybe override them */ switch (render.scale.op) { case scalerOpAdvInterp: if (render.scale.size == 2) - lineBlock = &ScaleAdvInterp2x; + complexBlock = &ScaleAdvInterp2x; else if (render.scale.size == 3) - lineBlock = &ScaleAdvInterp3x; + complexBlock = &ScaleAdvInterp3x; break; case scalerOpAdvMame: if (render.scale.size == 2) - lineBlock = &ScaleAdvMame2x; + complexBlock = &ScaleAdvMame2x; else if (render.scale.size == 3) - lineBlock = &ScaleAdvMame3x; + complexBlock = &ScaleAdvMame3x; break; case scalerOpTV: if (render.scale.size == 2) - lineBlock = &ScaleTV2x; + simpleBlock = &ScaleTV2x; else if (render.scale.size == 3) - lineBlock = &ScaleTV3x; + simpleBlock = &ScaleTV3x; break; case scalerOpRGB: if (render.scale.size == 2) - lineBlock = &ScaleRGB2x; + simpleBlock = &ScaleRGB2x; else if (render.scale.size == 3) - lineBlock = &ScaleRGB3x; + simpleBlock = &ScaleRGB3x; break; case scalerOpScan: if (render.scale.size == 2) - lineBlock = &ScaleScan2x; + simpleBlock = &ScaleScan2x; else if (render.scale.size == 3) - lineBlock = &ScaleScan3x; + simpleBlock = &ScaleScan3x; break; } } else if (dblw) { - lineBlock = &ScaleNormalDw; + simpleBlock = &ScaleNormalDw; } else if (dblh) { - lineBlock = &ScaleNormalDh; + simpleBlock = &ScaleNormalDh; } else { forcenormal: - lineBlock = &ScaleNormal; + complexBlock = 0; + simpleBlock = &ScaleNormal1x; + } + if (complexBlock) { + if ((width >= SCALER_COMPLEXWIDTH - 16) || height >= SCALER_COMPLEXHEIGHT - 16) { + LOG_MSG("Scaler can't handle this resolution, going back to normal"); + goto forcenormal; + } + gfx_flags = complexBlock->gfxFlags; + xscale = complexBlock->xscale; + yscale = complexBlock->yscale; + } else { + gfx_flags = simpleBlock->gfxFlags; + xscale = simpleBlock->xscale; + yscale = simpleBlock->yscale; } - gfx_flags = lineBlock->gfxFlags; if (render.src.bpp != 8) gfx_flags |= GFX_RGBONLY; gfx_flags=GFX_GetBestMode(gfx_flags); if (!gfx_flags) { - if (lineBlock == &ScaleNormal) + if (!complexBlock && simpleBlock == &ScaleNormal1x) E_Exit("Failed to create a rendering output"); else goto forcenormal; } /* Special test for normal2x to switch to normal with hardware scaling */ - width *= lineBlock->xscale; + width *= xscale; if (gfx_flags & GFX_SCALING) { - height = MakeAspectTable(render.src.height, lineBlock->yscale, lineBlock->yscale ); + height = MakeAspectTable(render.src.height, yscale, yscale ); } else { if ((gfx_flags & GFX_CAN_RANDOM) && gfx_scaleh > 1) { - gfx_scaleh *= lineBlock->yscale; - height = MakeAspectTable(render.src.height, gfx_scaleh, lineBlock->yscale ); + gfx_scaleh *= yscale; + height = MakeAspectTable(render.src.height, gfx_scaleh, yscale ); } else { gfx_flags &= ~GFX_CAN_RANDOM; //Hardware surface when possible - height = MakeAspectTable(render.src.height, lineBlock->yscale, lineBlock->yscale); + height = MakeAspectTable(render.src.height, yscale, yscale); } } /* Setup the scaler variables */ @@ -345,28 +312,52 @@ forcenormal: render.scale.outMode = scalerMode32; else E_Exit("Failed to create a rendering output"); + ScalerLineBlock_t *lineBlock; if (gfx_flags & GFX_HARDWARE) { - render.scale.currentHandler = lineBlock->Linear[ render.scale.outMode ]; + if (complexBlock) { + lineBlock = &ScalerCache; + render.scale.complexHandler = complexBlock->Linear[ render.scale.outMode ]; + } else { + render.scale.complexHandler = 0; + lineBlock = &simpleBlock->Linear; + } } else { - render.scale.currentHandler = lineBlock->Random[ render.scale.outMode ]; + if (complexBlock) { + lineBlock = &ScalerCache; + render.scale.complexHandler = complexBlock->Random[ render.scale.outMode ]; + } else { + render.scale.complexHandler = 0; + lineBlock = &simpleBlock->Random; + } } switch (render.src.bpp) { case 8: + render.scale.lineHandler = (*lineBlock)[0][render.scale.outMode]; + render.scale.linePalHandler = (*lineBlock)[4][render.scale.outMode]; render.scale.inMode = scalerMode8; + render.scale.cachePitch = render.src.width * 1; break; case 15: + render.scale.lineHandler = (*lineBlock)[1][render.scale.outMode]; + render.scale.linePalHandler = 0; render.scale.inMode = scalerMode15; + render.scale.cachePitch = render.src.width * 2; break; case 16: + render.scale.lineHandler = (*lineBlock)[2][render.scale.outMode]; + render.scale.linePalHandler = 0; render.scale.inMode = scalerMode16; + render.scale.cachePitch = render.src.width * 2; break; case 32: + render.scale.lineHandler = (*lineBlock)[3][render.scale.outMode]; + render.scale.linePalHandler = 0; render.scale.inMode = scalerMode32; + render.scale.cachePitch = render.src.width * 4; break; default: E_Exit("RENDER:Wrong source bpp %d", render.src.bpp ); } - render.scale.lineFlags = lineBlock->scaleFlags; render.scale.blocks = render.src.width / SCALER_BLOCKSIZE; render.scale.lastBlock = render.src.width % SCALER_BLOCKSIZE; render.scale.inHeight = render.src.height; @@ -393,13 +384,17 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool } extern void GFX_SetTitle(Bits cycles, Bits frameskip,bool paused); -static void IncreaseFrameSkip(void) { +static void IncreaseFrameSkip(bool pressed) { + if (!pressed) + return; if (render.frameskip.max<10) render.frameskip.max++; LOG_MSG("Frame Skip at %d",render.frameskip.max); GFX_SetTitle(-1,render.frameskip.max,false); } -static void DecreaseFrameSkip(void) { +static void DecreaseFrameSkip(bool pressed) { + if (!pressed) + return; if (render.frameskip.max>0) render.frameskip.max--; LOG_MSG("Frame Skip at %d",render.frameskip.max); GFX_SetTitle(-1,render.frameskip.max,false); diff --git a/src/gui/render_loops.h b/src/gui/render_loops.h index a9af5216..40fb97bf 100644 --- a/src/gui/render_loops.h +++ b/src/gui/render_loops.h @@ -17,9 +17,9 @@ */ #if defined (SCALERLINEAR) -void conc3d(SCALERNAME,SBPP,L)(void) { +static void conc3d(SCALERNAME,SBPP,L)(void) { #else -void conc3d(SCALERNAME,SBPP,R)(void) { +static void conc3d(SCALERNAME,SBPP,R)(void) { #endif if (!render.scale.outLine) { render.scale.outLine++; @@ -55,15 +55,10 @@ lastagain: #if (SCALERHEIGHT > 2) PTYPE * line2; #endif - -#if defined ( SCALERSIMPLE ) - if (!changed[b]) { - line0 += SCALERWIDTH * SCALER_BLOCKSIZE; - fc += SCALER_BLOCKSIZE; - continue; - } -#else - switch (changed[b]) { + /* Clear this block being dirty marker */ + const Bitu changeType = changed[b]; + changed[b] = 0; + switch (changeType) { case 0: line0 += SCALERWIDTH * SCALER_BLOCKSIZE; fc += SCALER_BLOCKSIZE; @@ -107,8 +102,6 @@ lastagain: fc++; break; default: -#endif //SCALERSIMPLE - #if defined(SCALERLINEAR) #if (SCALERHEIGHT > 1) line1 = WC[0]; @@ -143,12 +136,8 @@ lastagain: BituMove((Bit8u*)(&line0[-SCALER_BLOCKSIZE*SCALERWIDTH])+render.scale.outPitch*2,WC[1], SCALER_BLOCKSIZE *SCALERWIDTH*PSIZE); #endif #endif //defined(SCALERLINEAR) -#if !defined (SCALERSIMPLE) break; } -#endif - /* Clear this block being dirty marker */ - changed[b] = 0; } #if defined(SCALERLINEAR) Bitu scaleLines = SCALERHEIGHT; diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index 4ae8c751..826b16c0 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -34,7 +34,7 @@ union { Bit16u b16 [4][SCALER_MAXWIDTH*3]; Bit8u b8 [4][SCALER_MAXWIDTH*3]; } scalerWriteCache; -scalerFrameCache_t scalerFrameCache; +//scalerFrameCache_t scalerFrameCache; scalerSourceCache_t scalerSourceCache; scalerChangeCache_t scalerChangeCache; @@ -42,12 +42,14 @@ scalerChangeCache_t scalerChangeCache; #define _conc3(A,B,C) A ## B ## C #define _conc4(A,B,C,D) A ## B ## C ## D #define _conc5(A,B,C,D,E) A ## B ## C ## D ## E +#define _conc7(A,B,C,D,E,F,G) A ## B ## C ## D ## E ## F ## G #define conc2(A,B) _conc2(A,B) #define conc3(A,B,C) _conc3(A,B,C) #define conc4(A,B,C,D) _conc4(A,B,C,D) #define conc2d(A,B) _conc3(A,_,B) #define conc3d(A,B,C) _conc5(A,_,B,_,C) +#define conc4d(A,B,C,D) _conc7(A,_,B,_,C,_,D) static INLINE void BituMove( void *_dst, const void * _src, Bitu size) { Bitu * dst=(Bitu *)(_dst); @@ -94,6 +96,22 @@ static INLINE void BituMove( void *_dst, const void * _src, Bitu size) { #undef SBPP #undef DBPP +/* SBPP 9 is a special case with palette check support */ +#define SBPP 9 +#define DBPP 8 +#include "render_templates.h" +#undef DBPP +#define DBPP 15 +#include "render_templates.h" +#undef DBPP +#define DBPP 16 +#include "render_templates.h" +#undef DBPP +#define DBPP 32 +#include "render_templates.h" +#undef SBPP +#undef DBPP + #define SBPP 15 #define DBPP 15 #include "render_templates.h" @@ -130,150 +148,210 @@ static INLINE void BituMove( void *_dst, const void * _src, Bitu size) { #undef SBPP #undef DBPP -ScalerCacheBlock_t ScalerCache_8 = { - CacheSimple_8_8, CacheSimple_8_15, CacheSimple_8_16, CacheSimple_8_32, - CacheComplex_8_8, CacheComplex_8_15, CacheComplex_8_16, CacheComplex_8_32, -}; -ScalerCacheBlock_t ScalerCache_8Pal = { - 0, CacheSimplePal_8_15, CacheSimplePal_8_16, CacheSimplePal_8_32, - 0, CacheComplexPal_8_15, CacheComplexPal_8_16, CacheComplexPal_8_32, -}; -ScalerCacheBlock_t ScalerCache_15 = { - 0, CacheSimple_15_15, CacheSimple_15_16, CacheSimple_15_32, - 0, CacheComplex_15_15, CacheComplex_15_16, CacheComplex_15_32, -}; -ScalerCacheBlock_t ScalerCache_16 = { - 0, CacheSimple_16_15, CacheSimple_16_16, CacheSimple_16_32, - 0, CacheComplex_16_15, CacheComplex_16_16, CacheComplex_16_32, -}; -ScalerCacheBlock_t ScalerCache_32 = { - 0, CacheSimple_32_15, CacheSimple_32_16, CacheSimple_32_32, - 0, CacheComplex_32_15, CacheComplex_32_16, CacheComplex_32_32, + +ScalerLineBlock_t ScalerCache = { + Cache_8_8, Cache_8_15, Cache_8_16, Cache_8_32, + 0, Cache_15_15, Cache_15_16, Cache_15_32, + 0, Cache_16_15, Cache_16_16, Cache_16_32, + 0, Cache_32_15, Cache_32_16, Cache_32_32, + Cache_8_8, Cache_9_15, Cache_9_16, Cache_9_32, }; - -/* 8 bpp input versions */ -ScalerLineBlock_t ScaleNormal = { +ScalerSimpleBlock_t ScaleNormal1x = { GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8, - ScaleFlagSimple, 1,1, - Normal_8_L,Normal_16_L,Normal_16_L,Normal_32_L, - Normal_8_R,Normal_16_R,Normal_16_R,Normal_32_R + Normal1x_8_8_L, Normal1x_8_15_L, Normal1x_8_16_L, Normal1x_8_32_L, + 0, Normal1x_15_15_L, Normal1x_15_16_L, Normal1x_15_32_L, + 0, Normal1x_16_15_L, Normal1x_16_16_L, Normal1x_16_32_L, + 0, Normal1x_32_15_L, Normal1x_32_16_L, Normal1x_32_32_L, + Normal1x_8_8_L, Normal1x_9_15_L, Normal1x_9_16_L, Normal1x_9_32_L, + Normal1x_8_8_R, Normal1x_8_15_R, Normal1x_8_16_R, Normal1x_8_32_R, + 0, Normal1x_15_15_R, Normal1x_15_16_R, Normal1x_15_32_R, + 0, Normal1x_16_15_R, Normal1x_16_16_R, Normal1x_16_32_R, + 0, Normal1x_32_15_R, Normal1x_32_16_R, Normal1x_32_32_R, + Normal1x_8_8_R, Normal1x_9_15_R, Normal1x_9_16_R, Normal1x_9_32_R, }; -ScalerLineBlock_t ScaleNormalDw = { +ScalerSimpleBlock_t ScaleNormalDw = { GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8, - ScaleFlagSimple, 2,1, - NormalDw_8_L,NormalDw_16_L,NormalDw_16_L,NormalDw_32_L, - NormalDw_8_R,NormalDw_16_R,NormalDw_16_R,NormalDw_32_R + NormalDw_8_8_L, NormalDw_8_15_L, NormalDw_8_16_L, NormalDw_8_32_L, + 0, NormalDw_15_15_L, NormalDw_15_16_L, NormalDw_15_32_L, + 0, NormalDw_16_15_L, NormalDw_16_16_L, NormalDw_16_32_L, + 0, NormalDw_32_15_L, NormalDw_32_16_L, NormalDw_32_32_L, + NormalDw_8_8_L, NormalDw_9_15_L, NormalDw_9_16_L, NormalDw_9_32_L, + NormalDw_8_8_R, NormalDw_8_15_R, NormalDw_8_16_R, NormalDw_8_32_R, + 0, NormalDw_15_15_R, NormalDw_15_16_R, NormalDw_15_32_R, + 0, NormalDw_16_15_R, NormalDw_16_16_R, NormalDw_16_32_R, + 0, NormalDw_32_15_R, NormalDw_32_16_R, NormalDw_32_32_R, + NormalDw_8_8_R, NormalDw_9_15_R, NormalDw_9_16_R, NormalDw_9_32_R, }; -ScalerLineBlock_t ScaleNormalDh = { +ScalerSimpleBlock_t ScaleNormalDh = { GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8, - ScaleFlagSimple, 1,2, - NormalDh_8_L,NormalDh_16_L,NormalDh_16_L,NormalDh_32_L, - NormalDh_8_R,NormalDh_16_R,NormalDh_16_R,NormalDh_32_R + NormalDh_8_8_L, NormalDh_8_15_L, NormalDh_8_16_L, NormalDh_8_32_L, + 0, NormalDh_15_15_L, NormalDh_15_16_L, NormalDh_15_32_L, + 0, NormalDh_16_15_L, NormalDh_16_16_L, NormalDh_16_32_L, + 0, NormalDh_32_15_L, NormalDh_32_16_L, NormalDh_32_32_L, + NormalDh_8_8_L, NormalDh_9_15_L, NormalDh_9_16_L, NormalDh_9_32_L, + NormalDh_8_8_R, NormalDh_8_15_R, NormalDh_8_16_R, NormalDh_8_32_R, + 0, NormalDh_15_15_R, NormalDh_15_16_R, NormalDh_15_32_R, + 0, NormalDh_16_15_R, NormalDh_16_16_R, NormalDh_16_32_R, + 0, NormalDh_32_15_R, NormalDh_32_16_R, NormalDh_32_32_R, + NormalDh_8_8_R, NormalDh_9_15_R, NormalDh_9_16_R, NormalDh_9_32_R, }; - -ScalerLineBlock_t ScaleNormal2x = { +ScalerSimpleBlock_t ScaleNormal2x = { GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8, - ScaleFlagSimple, 2,2, - Normal2x_8_L,Normal2x_16_L,Normal2x_16_L,Normal2x_32_L, - Normal2x_8_R,Normal2x_16_R,Normal2x_16_R,Normal2x_32_R + Normal2x_8_8_L, Normal2x_8_15_L, Normal2x_8_16_L, Normal2x_8_32_L, + 0, Normal2x_15_15_L, Normal2x_15_16_L, Normal2x_15_32_L, + 0, Normal2x_16_15_L, Normal2x_16_16_L, Normal2x_16_32_L, + 0, Normal2x_32_15_L, Normal2x_32_16_L, Normal2x_32_32_L, + Normal2x_8_8_L, Normal2x_9_15_L, Normal2x_9_16_L, Normal2x_9_32_L, + Normal2x_8_8_R, Normal2x_8_15_R, Normal2x_8_16_R, Normal2x_8_32_R, + 0, Normal2x_15_15_R, Normal2x_15_16_R, Normal2x_15_32_R, + 0, Normal2x_16_15_R, Normal2x_16_16_R, Normal2x_16_32_R, + 0, Normal2x_32_15_R, Normal2x_32_16_R, Normal2x_32_32_R, + Normal2x_8_8_R, Normal2x_9_15_R, Normal2x_9_16_R, Normal2x_9_32_R, }; -ScalerLineBlock_t ScaleNormal3x = { +ScalerSimpleBlock_t ScaleNormal3x = { GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8, - ScaleFlagSimple, 3,3, - Normal3x_8_L,Normal3x_16_L,Normal3x_16_L,Normal3x_32_L, - Normal3x_8_R,Normal3x_16_R,Normal3x_16_R,Normal3x_32_R + Normal3x_8_8_L, Normal3x_8_15_L, Normal3x_8_16_L, Normal3x_8_32_L, + 0, Normal3x_15_15_L, Normal3x_15_16_L, Normal3x_15_32_L, + 0, Normal3x_16_15_L, Normal3x_16_16_L, Normal3x_16_32_L, + 0, Normal3x_32_15_L, Normal3x_32_16_L, Normal3x_32_32_L, + Normal3x_8_8_L, Normal3x_9_15_L, Normal3x_9_16_L, Normal3x_9_32_L, + Normal3x_8_8_R, Normal3x_8_15_R, Normal3x_8_16_R, Normal3x_8_32_R, + 0, Normal3x_15_15_R, Normal3x_15_16_R, Normal3x_15_32_R, + 0, Normal3x_16_15_R, Normal3x_16_16_R, Normal3x_16_32_R, + 0, Normal3x_32_15_R, Normal3x_32_16_R, Normal3x_32_32_R, + Normal3x_8_8_R, Normal3x_9_15_R, Normal3x_9_16_R, Normal3x_9_32_R, }; -ScalerLineBlock_t ScaleAdvMame2x ={ +ScalerSimpleBlock_t ScaleTV2x = { + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, + 2,2, + 0, TV2x_8_15_L, TV2x_8_16_L, TV2x_8_32_L, + 0, TV2x_15_15_L, TV2x_15_16_L, TV2x_15_32_L, + 0, TV2x_16_15_L, TV2x_16_16_L, TV2x_16_32_L, + 0, TV2x_32_15_L, TV2x_32_16_L, TV2x_32_32_L, + 0, TV2x_9_15_L, TV2x_9_16_L, TV2x_9_32_L, + 0, TV2x_8_15_R, TV2x_8_16_R, TV2x_8_32_R, + 0, TV2x_15_15_R, TV2x_15_16_R, TV2x_15_32_R, + 0, TV2x_16_15_R, TV2x_16_16_R, TV2x_16_32_R, + 0, TV2x_32_15_R, TV2x_32_16_R, TV2x_32_32_R, + 0, TV2x_9_15_R, TV2x_9_16_R, TV2x_9_32_R, +}; + +ScalerSimpleBlock_t ScaleTV3x = { + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, + 3,3, + 0, TV3x_8_15_L, TV3x_8_16_L, TV3x_8_32_L, + 0, TV3x_15_15_L, TV3x_15_16_L, TV3x_15_32_L, + 0, TV3x_16_15_L, TV3x_16_16_L, TV3x_16_32_L, + 0, TV3x_32_15_L, TV3x_32_16_L, TV3x_32_32_L, + 0, TV3x_9_15_L, TV3x_9_16_L, TV3x_9_32_L, + 0, TV3x_8_15_R, TV3x_8_16_R, TV3x_8_32_R, + 0, TV3x_15_15_R, TV3x_15_16_R, TV3x_15_32_R, + 0, TV3x_16_15_R, TV3x_16_16_R, TV3x_16_32_R, + 0, TV3x_32_15_R, TV3x_32_16_R, TV3x_32_32_R, + 0, TV3x_9_15_R, TV3x_9_16_R, TV3x_9_32_R, +}; + +ScalerSimpleBlock_t ScaleScan2x = { + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, + 2,2, + 0, Scan2x_8_15_L, Scan2x_8_16_L, Scan2x_8_32_L, + 0, Scan2x_15_15_L, Scan2x_15_16_L, Scan2x_15_32_L, + 0, Scan2x_16_15_L, Scan2x_16_16_L, Scan2x_16_32_L, + 0, Scan2x_32_15_L, Scan2x_32_16_L, Scan2x_32_32_L, + 0, Scan2x_9_15_L, Scan2x_9_16_L, Scan2x_9_32_L, + 0, Scan2x_8_15_R, Scan2x_8_16_R, Scan2x_8_32_R, + 0, Scan2x_15_15_R, Scan2x_15_16_R, Scan2x_15_32_R, + 0, Scan2x_16_15_R, Scan2x_16_16_R, Scan2x_16_32_R, + 0, Scan2x_32_15_R, Scan2x_32_16_R, Scan2x_32_32_R, + 0, Scan2x_9_15_R, Scan2x_9_16_R, Scan2x_9_32_R, +}; + +ScalerSimpleBlock_t ScaleScan3x = { + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, + 3,3, + 0, Scan3x_8_15_L, Scan3x_8_16_L, Scan3x_8_32_L, + 0, Scan3x_15_15_L, Scan3x_15_16_L, Scan3x_15_32_L, + 0, Scan3x_16_15_L, Scan3x_16_16_L, Scan3x_16_32_L, + 0, Scan3x_32_15_L, Scan3x_32_16_L, Scan3x_32_32_L, + 0, Scan3x_9_15_L, Scan3x_9_16_L, Scan3x_9_32_L, + 0, Scan3x_8_15_R, Scan3x_8_16_R, Scan3x_8_32_R, + 0, Scan3x_15_15_R, Scan3x_15_16_R, Scan3x_15_32_R, + 0, Scan3x_16_15_R, Scan3x_16_16_R, Scan3x_16_32_R, + 0, Scan3x_32_15_R, Scan3x_32_16_R, Scan3x_32_32_R, + 0, Scan3x_9_15_R, Scan3x_9_16_R, Scan3x_9_32_R, +}; + +ScalerSimpleBlock_t ScaleRGB2x = { + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, + 2,2, + 0, RGB2x_8_15_L, RGB2x_8_16_L, RGB2x_8_32_L, + 0, RGB2x_15_15_L, RGB2x_15_16_L, RGB2x_15_32_L, + 0, RGB2x_16_15_L, RGB2x_16_16_L, RGB2x_16_32_L, + 0, RGB2x_32_15_L, RGB2x_32_16_L, RGB2x_32_32_L, + 0, RGB2x_9_15_L, RGB2x_9_16_L, RGB2x_9_32_L, + 0, RGB2x_8_15_R, RGB2x_8_16_R, RGB2x_8_32_R, + 0, RGB2x_15_15_R, RGB2x_15_16_R, RGB2x_15_32_R, + 0, RGB2x_16_15_R, RGB2x_16_16_R, RGB2x_16_32_R, + 0, RGB2x_32_15_R, RGB2x_32_16_R, RGB2x_32_32_R, + 0, RGB2x_9_15_R, RGB2x_9_16_R, RGB2x_9_32_R, +}; + +ScalerSimpleBlock_t ScaleRGB3x = { + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, + 3,3, + 0, RGB3x_8_15_L, RGB3x_8_16_L, RGB3x_8_32_L, + 0, RGB3x_15_15_L, RGB3x_15_16_L, RGB3x_15_32_L, + 0, RGB3x_16_15_L, RGB3x_16_16_L, RGB3x_16_32_L, + 0, RGB3x_32_15_L, RGB3x_32_16_L, RGB3x_32_32_L, + 0, RGB3x_9_15_L, RGB3x_9_16_L, RGB3x_9_32_L, + 0, RGB3x_8_15_R, RGB3x_8_16_R, RGB3x_8_32_R, + 0, RGB3x_15_15_R, RGB3x_15_16_R, RGB3x_15_32_R, + 0, RGB3x_16_15_R, RGB3x_16_16_R, RGB3x_16_32_R, + 0, RGB3x_32_15_R, RGB3x_32_16_R, RGB3x_32_32_R, + 0, RGB3x_9_15_R, RGB3x_9_16_R, RGB3x_9_32_R, +}; + + +/* Complex scalers */ + +ScalerComplexBlock_t ScaleAdvMame2x ={ GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8, - 0, 2,2, AdvMame2x_8_L,AdvMame2x_16_L,AdvMame2x_16_L,AdvMame2x_32_L, AdvMame2x_8_R,AdvMame2x_16_R,AdvMame2x_16_R,AdvMame2x_32_R }; -ScalerLineBlock_t ScaleAdvMame3x = { +ScalerComplexBlock_t ScaleAdvMame3x = { GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8, - 0, 3,3, AdvMame3x_8_L,AdvMame3x_16_L,AdvMame3x_16_L,AdvMame3x_32_L, AdvMame3x_8_R,AdvMame3x_16_R,AdvMame3x_16_R,AdvMame3x_32_R }; /* These need specific 15bpp versions */ -ScalerLineBlock_t ScaleAdvInterp2x = { +ScalerComplexBlock_t ScaleAdvInterp2x = { GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, - 0, 2,2, 0,AdvInterp2x_15_L,AdvInterp2x_16_L,AdvInterp2x_32_L, 0,AdvInterp2x_15_R,AdvInterp2x_16_R,AdvInterp2x_32_R }; -ScalerLineBlock_t ScaleAdvInterp3x = { +ScalerComplexBlock_t ScaleAdvInterp3x = { GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, - 0, 3,3, 0,AdvInterp3x_15_L,AdvInterp3x_16_L,AdvInterp3x_32_L, 0,AdvInterp3x_15_R,AdvInterp3x_16_R,AdvInterp3x_32_R }; -ScalerLineBlock_t ScaleTV2x = { - GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, - ScaleFlagSimple, - 2,2, - 0,TV2x_15_L,TV2x_16_L,TV2x_32_L, - 0,TV2x_15_R,TV2x_16_R,TV2x_32_R -}; - -ScalerLineBlock_t ScaleTV3x = { - GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, - ScaleFlagSimple, - 3,3, - 0,TV3x_15_L,TV3x_16_L,TV3x_32_L, - 0,TV3x_15_R,TV3x_16_R,TV3x_32_R -}; - -ScalerLineBlock_t ScaleRGB2x = { - GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, - ScaleFlagSimple, - 2,2, - 0,RGB2x_15_L,RGB2x_16_L,RGB2x_32_L, - 0,RGB2x_15_R,RGB2x_16_R,RGB2x_32_R -}; - -ScalerLineBlock_t ScaleRGB3x = { - GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, - ScaleFlagSimple, - 3,3, - 0,RGB3x_15_L,RGB3x_16_L,RGB3x_32_L, - 0,RGB3x_15_R,RGB3x_16_R,RGB3x_32_R -}; - - -ScalerLineBlock_t ScaleScan2x = { - GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, - ScaleFlagSimple, - 2,2, - 0,Scan2x_15_L,Scan2x_16_L,Scan2x_32_L, - 0,Scan2x_15_R,Scan2x_16_R,Scan2x_32_R -}; - -ScalerLineBlock_t ScaleScan3x = { - GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, - ScaleFlagSimple, - 3,3, - 0,Scan3x_15_L,Scan3x_16_L,Scan3x_32_L, - 0,Scan3x_15_R,Scan3x_16_R,Scan3x_32_R -}; - diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index 3d982369..7cc419b2 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -24,6 +24,9 @@ #define SCALER_MAXWIDTH 1024 #define SCALER_MAXHEIGHT 768 + +#define SCALER_COMPLEXWIDTH 512 +#define SCALER_COMPLEXHEIGHT 400 #define SCALER_BLOCKSIZE 16 typedef enum { @@ -39,80 +42,64 @@ typedef enum { scalerOpScan, } scalerOperation_t; -typedef void (*ScalerCacheHandler_t)(const void *src); -typedef void (*ScalerLineHandler_t)(void); +typedef void (*ScalerLineHandler_t)(const void *src); +typedef void (*ScalerComplexHandler_t)(void); extern Bit8u Scaler_Aspect[]; extern Bit8u diff_table[]; extern Bitu Scaler_ChangedLineIndex; extern Bit16u Scaler_ChangedLines[]; /* Not entirely happy about those +2's since they make a non power of 2, with muls instead of shift */ -typedef Bit8u scalerChangeCache_t [SCALER_MAXHEIGHT+2][2+(SCALER_MAXWIDTH / SCALER_BLOCKSIZE)] ; +typedef Bit8u scalerChangeCache_t [SCALER_COMPLEXHEIGHT][SCALER_COMPLEXWIDTH / SCALER_BLOCKSIZE] ; typedef union { - Bit32u b32 [(SCALER_MAXHEIGHT+2)] [(SCALER_MAXWIDTH+2)]; - Bit16u b16 [(SCALER_MAXHEIGHT+2)] [(SCALER_MAXWIDTH+2)]; - Bit8u b8 [(SCALER_MAXHEIGHT+2)] [(SCALER_MAXWIDTH+2)]; + Bit32u b32 [SCALER_COMPLEXHEIGHT] [SCALER_COMPLEXWIDTH]; + Bit16u b16 [SCALER_COMPLEXHEIGHT] [SCALER_COMPLEXWIDTH]; + Bit8u b8 [SCALER_COMPLEXHEIGHT] [SCALER_COMPLEXWIDTH]; } scalerFrameCache_t; typedef union { Bit32u b32 [SCALER_MAXHEIGHT] [SCALER_MAXWIDTH]; Bit16u b16 [SCALER_MAXHEIGHT] [SCALER_MAXWIDTH]; Bit8u b8 [SCALER_MAXHEIGHT] [SCALER_MAXWIDTH]; } scalerSourceCache_t; - -extern scalerFrameCache_t scalerFrameCache; extern scalerSourceCache_t scalerSourceCache; extern scalerChangeCache_t scalerChangeCache; - -#define ScaleFlagSimple 0x001 +typedef ScalerLineHandler_t ScalerLineBlock_t[5][4]; typedef struct { Bitu gfxFlags; - Bitu scaleFlags; Bitu xscale,yscale; - ScalerLineHandler_t Linear[4]; - ScalerLineHandler_t Random[4]; -} ScalerLineBlock_t; + ScalerComplexHandler_t Linear[4]; + ScalerComplexHandler_t Random[4]; +} ScalerComplexBlock_t; typedef struct { Bitu gfxFlags; - Bitu scaleFlags; Bitu xscale,yscale; - ScalerLineHandler_t Linear[4][4]; - ScalerLineHandler_t Random[4][4]; -} ScalerFullLineBlock_t; + ScalerLineBlock_t Linear; + ScalerLineBlock_t Random; +} ScalerSimpleBlock_t; -typedef struct { - ScalerCacheHandler_t simple[4]; - ScalerCacheHandler_t complex[4]; -} ScalerCacheBlock_t; - -extern ScalerLineBlock_t ScaleNormal; -extern ScalerLineBlock_t ScaleNormalDw; -extern ScalerLineBlock_t ScaleNormalDh; - #define SCALE_LEFT 0x1 #define SCALE_RIGHT 0x2 #define SCALE_FULL 0x4 -extern ScalerLineBlock_t ScaleNormal2x; -extern ScalerLineBlock_t ScaleNormal3x; -extern ScalerLineBlock_t ScaleAdvMame2x; -extern ScalerLineBlock_t ScaleAdvMame3x; -extern ScalerLineBlock_t ScaleAdvInterp2x; -extern ScalerLineBlock_t ScaleAdvInterp3x; - -extern ScalerLineBlock_t ScaleTV2x; -extern ScalerLineBlock_t ScaleTV3x; -extern ScalerLineBlock_t ScaleRGB2x; -extern ScalerLineBlock_t ScaleRGB3x; -extern ScalerLineBlock_t ScaleScan2x; -extern ScalerLineBlock_t ScaleScan3x; - -extern ScalerCacheBlock_t ScalerCache_8; -extern ScalerCacheBlock_t ScalerCache_8Pal; -extern ScalerCacheBlock_t ScalerCache_15; -extern ScalerCacheBlock_t ScalerCache_16; -extern ScalerCacheBlock_t ScalerCache_32; - +/* Simple scalers */ +extern ScalerSimpleBlock_t ScaleNormal1x; +extern ScalerSimpleBlock_t ScaleNormalDw; +extern ScalerSimpleBlock_t ScaleNormalDh; +extern ScalerSimpleBlock_t ScaleNormal2x; +extern ScalerSimpleBlock_t ScaleNormal3x; +extern ScalerSimpleBlock_t ScaleTV2x; +extern ScalerSimpleBlock_t ScaleTV3x; +extern ScalerSimpleBlock_t ScaleRGB2x; +extern ScalerSimpleBlock_t ScaleRGB3x; +extern ScalerSimpleBlock_t ScaleScan2x; +extern ScalerSimpleBlock_t ScaleScan3x; +/* Complex scalers */ +extern ScalerComplexBlock_t ScaleAdvMame2x; +extern ScalerComplexBlock_t ScaleAdvMame3x; +extern ScalerComplexBlock_t ScaleAdvInterp2x; +extern ScalerComplexBlock_t ScaleAdvInterp3x; +extern ScalerLineBlock_t ScalerCache; #endif diff --git a/src/gui/render_simple.h b/src/gui/render_simple.h new file mode 100644 index 00000000..35e337cb --- /dev/null +++ b/src/gui/render_simple.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2002-2006 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. + */ + +#if defined (SCALERLINEAR) +static void conc4d(SCALERNAME,SBPP,DBPP,L)(const void *s) { +#else +static void conc4d(SCALERNAME,SBPP,DBPP,R)(const void *s) { +#endif + /* Clear the complete line marker */ + const SRCTYPE *src = (SRCTYPE*)s; + SRCTYPE *cache = (SRCTYPE*)(render.scale.cacheRead); + render.scale.cacheRead += render.scale.cachePitch; + PTYPE * line0=(PTYPE *)(render.scale.outWrite); + Bitu hadChange = 0; +#if (SBPP == 9) + for (Bits x=render.src.width;x>0;) { + if (*(Bit32u*)src == *(Bit32u*)cache && !( + render.pal.modified[src[0]] | + render.pal.modified[src[1]] | + render.pal.modified[src[2]] | + render.pal.modified[src[3]] )) { + x-=4; + src+=4; + cache+=4; + line0+=4*SCALERWIDTH; +#else + for (Bits x=render.src.width;x>0;) { + if (*(Bitu*)src == *(Bitu*)cache) { + x-=(sizeof(Bitu)/sizeof(SRCTYPE)); + src+=(sizeof(Bitu)/sizeof(SRCTYPE)); + cache+=(sizeof(Bitu)/sizeof(SRCTYPE)); + line0+=(sizeof(Bitu)/sizeof(SRCTYPE))*SCALERWIDTH; +#endif + } else { +#if defined(SCALERLINEAR) +#if (SCALERHEIGHT > 1) + PTYPE *line1 = WC[0]; +#endif +#if (SCALERHEIGHT > 2) + PTYPE *line2 = WC[1]; +#endif +#else +#if (SCALERHEIGHT > 1) + PTYPE *line1 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch); +#endif +#if (SCALERHEIGHT > 2) + PTYPE *line2 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch * 2); +#endif +#endif //defined(SCALERLINEAR) + hadChange = 1; + for (Bitu i = x > 32 ? 32 : x;i>0;i--,x--) { + const SRCTYPE S = *src; + *cache = S; + src++;cache++; + const PTYPE P = PMAKE(S); + SCALERFUNC; + line0 += SCALERWIDTH; +#if (SCALERHEIGHT > 1) + line1 += SCALERWIDTH; +#endif +#if (SCALERHEIGHT > 2) + line2 += SCALERWIDTH; +#endif + } +#if defined(SCALERLINEAR) +#if (SCALERHEIGHT > 1) + Bitu copyLen = (Bit8u*)line1 - (Bit8u*)WC[0]; + BituMove(((Bit8u*)line0)-copyLen+render.scale.outPitch ,WC[0], copyLen ); +#endif +#if (SCALERHEIGHT > 2) + BituMove(((Bit8u*)line0)-copyLen+render.scale.outPitch*2,WC[1], copyLen ); +#endif +#endif //defined(SCALERLINEAR) + } + } +#if defined(SCALERLINEAR) + Bitu scaleLines = SCALERHEIGHT; + render.scale.outWrite += render.scale.outPitch * scaleLines; +#else + Bitu scaleLines = SCALERHEIGHT; + if ( Scaler_Aspect[ render.scale.outLine++ ] ) { + scaleLines++; + if (hadChange) + BituMove( render.scale.outWrite + render.scale.outPitch * SCALERHEIGHT, + render.scale.outWrite + render.scale.outPitch * (SCALERHEIGHT-1), + render.src.width * SCALERWIDTH * PSIZE); + render.scale.outWrite += render.scale.outPitch * (SCALERHEIGHT + 1); + } else { + render.scale.outWrite += render.scale.outPitch * SCALERHEIGHT; + } + /* Keep track of changed lines */ + if ((Scaler_ChangedLineIndex & 1) == hadChange) { + Scaler_ChangedLines[Scaler_ChangedLineIndex] += scaleLines; + } else { + Scaler_ChangedLines[++Scaler_ChangedLineIndex] = scaleLines; + } +#endif +} + +#if !defined(SCALERLINEAR) +#define SCALERLINEAR 1 +#include "render_simple.h" +#undef SCALERLINEAR +#endif diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index 803099bd..21631bc2 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -20,7 +20,8 @@ #define PSIZE 1 #define PTYPE Bit8u #define WC scalerWriteCache.b8 -#define FC scalerFrameCache.b8 +//#define FC scalerFrameCache.b8 +#define FC (*(scalerFrameCache_t*)(&scalerSourceCache.b32[400][0])).b8 #define redMask 0 #define greenMask 0 #define blueMask 0 @@ -28,7 +29,8 @@ #define PSIZE 2 #define PTYPE Bit16u #define WC scalerWriteCache.b16 -#define FC scalerFrameCache.b16 +//#define FC scalerFrameCache.b16 +#define FC (*(scalerFrameCache_t*)(&scalerSourceCache.b32[400][0])).b16 #if DBPP == 15 #define redMask 0x7C00 #define greenMask 0x03E0 @@ -42,7 +44,8 @@ #define PSIZE 4 #define PTYPE Bit32u #define WC scalerWriteCache.b32 -#define FC scalerFrameCache.b32 +//#define FC scalerFrameCache.b32 +#define FC (*(scalerFrameCache_t*)(&scalerSourceCache.b32[400][0])).b32 #define redMask 0xff0000 #define greenMask 0x00ff00 #define blueMask 0x0000ff @@ -51,7 +54,7 @@ #define redblueMask (redMask | blueMask) -#if SBPP == 8 +#if SBPP == 8 || SBPP == 9 #define SC scalerSourceCache.b8 #if DBPP == 8 #define PMAKE(_VAL) (_VAL) @@ -101,29 +104,26 @@ #define SRCTYPE Bit32u #endif -#define C0 fc[-1 - SCALER_MAXWIDTH -2] -#define C1 fc[+0 - SCALER_MAXWIDTH -2] -#define C2 fc[+1 - SCALER_MAXWIDTH -2] +#define C0 fc[-1 - SCALER_COMPLEXWIDTH] +#define C1 fc[+0 - SCALER_COMPLEXWIDTH] +#define C2 fc[+1 - SCALER_COMPLEXWIDTH] #define C3 fc[-1 ] #define C4 fc[+0 ] #define C5 fc[+1 ] -#define C6 fc[-1 + SCALER_MAXWIDTH +2] -#define C7 fc[+0 + SCALER_MAXWIDTH +2] -#define C8 fc[+1 + SCALER_MAXWIDTH +2] +#define C6 fc[-1 + SCALER_COMPLEXWIDTH] +#define C7 fc[+0 + SCALER_COMPLEXWIDTH] +#define C8 fc[+1 + SCALER_COMPLEXWIDTH] -#if defined (CACHEWITHPAL) -static void conc3d(CacheComplexPal,SBPP,DBPP) (const void * s) { -#else -static void conc3d(CacheComplex,SBPP,DBPP) (const void * s) { -#endif +static void conc3d(Cache,SBPP,DBPP) (const void * s) { const SRCTYPE * src = (SRCTYPE*)s; PTYPE *fc= &FC[render.scale.inLine+1][1]; - SRCTYPE *sc= &SC[render.scale.inLine][0]; + SRCTYPE *sc = (SRCTYPE*)(render.scale.cacheRead); + render.scale.cacheRead += render.scale.cachePitch; Bitu b; bool hadChange = false; /* This should also copy the surrounding pixels but it looks nice enough without */ for (b=0;b 8) -#define SCALERSIMPLE 1 #define SCALERNAME TV2x #define SCALERWIDTH 2 #define SCALERHEIGHT 2 #define SCALERFUNC \ { \ - Bitu halfpixel=(((C4 & redblueMask) * 5) >> 3) & redblueMask; \ - halfpixel|=(((C4 & greenMask) * 5) >> 3) & greenMask; \ - line0[0]=C4; \ - line0[1]=C4; \ + Bitu halfpixel=(((P & redblueMask) * 5) >> 3) & redblueMask; \ + halfpixel|=(((P & greenMask) * 5) >> 3) & greenMask; \ + line0[0]=P; \ + line0[1]=P; \ line1[0]=halfpixel; \ line1[1]=halfpixel; \ } -#include "render_loops.h" +#include "render_simple.h" #undef SCALERNAME #undef SCALERWIDTH #undef SCALERHEIGHT #undef SCALERFUNC -#undef SCALERSIMPLE - -#define SCALERSIMPLE 1 #define SCALERNAME TV3x #define SCALERWIDTH 3 #define SCALERHEIGHT 3 -#define SCALERFUNC \ -{ \ - Bitu halfpixel=(((C4 & redblueMask) * 5) >> 3) & redblueMask; \ - halfpixel|=(((C4 & greenMask) * 5) >> 3) & greenMask; \ - line0[0]=C4; \ - line0[1]=C4; \ - line0[2]=C4; \ +#define SCALERFUNC \ +{ \ + Bitu halfpixel=(((P & redblueMask) * 5) >> 3) & redblueMask; \ + halfpixel|=(((P & greenMask) * 5) >> 3) & greenMask; \ + line0[0]=P; \ + line0[1]=P; \ + line0[2]=P; \ line1[0]=halfpixel; \ line1[1]=halfpixel; \ line1[2]=halfpixel; \ - halfpixel=(((C4 & redblueMask) * 5) >> 4) & redblueMask; \ - halfpixel|=(((C4 & greenMask) * 5) >> 4) & greenMask; \ + halfpixel=(((P & redblueMask) * 5) >> 4) & redblueMask; \ + halfpixel|=(((P & greenMask) * 5) >> 4) & greenMask; \ line2[0]=halfpixel; \ line2[1]=halfpixel; \ line2[2]=halfpixel; \ } -#include "render_loops.h" +#include "render_simple.h" #undef SCALERNAME #undef SCALERWIDTH #undef SCALERHEIGHT #undef SCALERFUNC -#undef SCALERSIMPLE -#define SCALERSIMPLE 1 #define SCALERNAME RGB2x #define SCALERWIDTH 2 #define SCALERHEIGHT 2 #define SCALERFUNC \ - line0[0]=C4 & redMask; \ - line0[1]=C4 & greenMask; \ - line1[0]=C4 & blueMask; \ - line1[1]=C4; -#include "render_loops.h" + line0[0]=P & redMask; \ + line0[1]=P & greenMask; \ + line1[0]=P & blueMask; \ + line1[1]=P; +#include "render_simple.h" #undef SCALERNAME #undef SCALERWIDTH #undef SCALERHEIGHT #undef SCALERFUNC -#undef SCALERSIMPLE - -#define SCALERSIMPLE 1 #define SCALERNAME RGB3x #define SCALERWIDTH 3 #define SCALERHEIGHT 3 #define SCALERFUNC \ - line0[0]=C4; \ - line0[1]=C4 & greenMask; \ - line0[2]=C4 & blueMask; \ - line1[0]=C4 & blueMask; \ - line1[1]=C4; \ - line1[2]=C4 & redMask; \ - line2[0]=C4 & redMask; \ - line2[1]=C4 & greenMask; \ - line2[2]=C4; -#include "render_loops.h" + line0[0]=P; \ + line0[1]=P & greenMask; \ + line0[2]=P & blueMask; \ + line1[0]=P & blueMask; \ + line1[1]=P; \ + line1[2]=P & redMask; \ + line2[0]=P & redMask; \ + line2[1]=P & greenMask; \ + line2[2]=P; +#include "render_simple.h" #undef SCALERNAME #undef SCALERWIDTH #undef SCALERHEIGHT #undef SCALERFUNC -#undef SCALERSIMPLE - -#define SCALERSIMPLE 1 #define SCALERNAME Scan2x #define SCALERWIDTH 2 #define SCALERHEIGHT 2 #define SCALERFUNC \ - line0[0]=C4; \ - line0[1]=C4; \ + line0[0]=P; \ + line0[1]=P; \ line1[0]=0; \ line1[1]=0; -#include "render_loops.h" +#include "render_simple.h" #undef SCALERNAME #undef SCALERWIDTH #undef SCALERHEIGHT #undef SCALERFUNC -#undef SCALERSIMPLE - -#define SCALERSIMPLE 1 #define SCALERNAME Scan3x #define SCALERWIDTH 3 #define SCALERHEIGHT 3 #define SCALERFUNC \ - line0[0]=C4; \ - line0[1]=C4; \ - line0[2]=C4; \ + line0[0]=P; \ + line0[1]=P; \ + line0[2]=P; \ line1[0]=0; \ line1[1]=0; \ line1[2]=0; \ line2[0]=0; \ line2[1]=0; \ line2[2]=0; -#include "render_loops.h" +#include "render_simple.h" #undef SCALERNAME #undef SCALERWIDTH #undef SCALERHEIGHT #undef SCALERFUNC -#undef SCALERSIMPLE + +#endif //#if (DBPP > 8) + +/* Complex scalers */ +#if (SBPP == DBPP) +#if (DBPP > 8) #define SCALERNAME AdvInterp2x #define SCALERWIDTH 2 @@ -457,7 +397,7 @@ static void conc3d(CacheSimple,SBPP,DBPP) (const void * s) { #undef SCALERHEIGHT #undef SCALERFUNC -#endif //DBPP > 8 +#endif // #if (DBPP > 8) #define SCALERNAME AdvMame2x #define SCALERWIDTH 2 @@ -520,8 +460,3 @@ static void conc3d(CacheSimple,SBPP,DBPP) (const void * s) { #undef redblueMask #undef SRCTYPE -#if (SBPP == 8) && (DBPP > 8) && !defined (CACHEWITHPAL) -#define CACHEWITHPAL 1 -#include "render_templates.h" -#undef CACHEWITHPAL -#endif From 1ee4a87477c26de744ee29251e5c07ffd46bebe8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 12 Feb 2006 23:53:50 +0000 Subject: [PATCH 2409/4131] Fix some non-debug mapper handler to new format Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2493 --- src/gui/sdlmain.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 5c23a25a..fa424328 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.102 2006-02-12 23:39:37 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.103 2006-02-12 23:53:50 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -223,7 +223,9 @@ void GFX_SetTitle(Bits cycles,Bits frameskip,bool paused){ SDL_WM_SetCaption(title,VERSION); } -static void PauseDOSBox(void) { +static void PauseDOSBox(bool pressed) { + if (!pressed) + return; GFX_SetTitle(-1,-1,true); bool paused = true; KEYBOARD_ClrBuffer(); From 572b1ea551fde6d098b64c76f1b38eff629779c0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 12 Feb 2006 23:55:53 +0000 Subject: [PATCH 2410/4131] New format for mapper handlers to support keeping keys pressed. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2494 --- src/hardware/vga_other.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index ba424fd4..b200d557 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_other.cpp,v 1.17 2006-02-09 11:47:49 qbix79 Exp $ */ +/* $Id: vga_other.cpp,v 1.18 2006-02-12 23:55:53 harekiet Exp $ */ #include #include @@ -193,13 +193,17 @@ static void update_cga16_color(void) { } } -static void IncreaseHue(void) { +static void IncreaseHue(bool pressed) { + if (!pressed) + return; hue_offset += 5.0; update_cga16_color(); LOG_MSG("Hue at %f",hue_offset); } -static void DecreaseHue(void) { +static void DecreaseHue(bool pressed) { + if (!pressed) + return; hue_offset -= 5.0; update_cga16_color(); LOG_MSG("Hue at %f",hue_offset); From df62fa5c202814a05d6573baa5310981be4a10ff Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 13 Feb 2006 07:48:25 +0000 Subject: [PATCH 2411/4131] lock mouse on 0xc (define USR) (requested by wd) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2495 --- src/ints/mouse.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 296591a8..f0639d5d 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.60 2006-02-09 11:47:57 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.61 2006-02-13 07:48:25 qbix79 Exp $ */ #include #include @@ -735,6 +735,7 @@ static Bitu INT33_Handler(void) { mouse.sub_mask=reg_cx; mouse.sub_seg=SegValue(es); mouse.sub_ofs=reg_dx; + Mouse_AutoLock(true); //Some games don't seem to reset the mouse before using break; case 0x0f: /* Define mickey/pixel rate */ SetMickeyPixelRate(reg_cx,reg_dx); From c7f66d9a4085cf57ccc6d09897f27e919b1ad692 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 13 Feb 2006 08:22:18 +0000 Subject: [PATCH 2412/4131] Handle the gfx loving based on the source bpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2496 --- src/gui/render.cpp | 25 +++++++++++++++++++++---- src/gui/render_scalers.cpp | 30 +++++++++++++++--------------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 52d36120..69fe644a 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.41 2006-02-12 23:43:54 harekiet Exp $ */ +/* $Id: render.cpp,v 1.42 2006-02-13 08:22:17 harekiet Exp $ */ #include #include @@ -278,8 +278,26 @@ forcenormal: xscale = simpleBlock->xscale; yscale = simpleBlock->yscale; } - if (render.src.bpp != 8) - gfx_flags |= GFX_RGBONLY; + switch (render.src.bpp) { + case 8: + if (gfx_flags & GFX_CAN_8) + gfx_flags |= GFX_LOVE_8; + else + gfx_flags |= GFX_LOVE_32; + break; + case 15: + gfx_flags |= GFX_LOVE_15; + gfx_flags = (gfx_flags & ~GFX_CAN_8) | GFX_RGBONLY; + break; + case 16: + gfx_flags |= GFX_LOVE_16; + gfx_flags = (gfx_flags & ~GFX_CAN_8) | GFX_RGBONLY; + break; + case 32: + gfx_flags |= GFX_LOVE_32; + gfx_flags = (gfx_flags & ~GFX_CAN_8) | GFX_RGBONLY; + break; + } gfx_flags=GFX_GetBestMode(gfx_flags); if (!gfx_flags) { if (!complexBlock && simpleBlock == &ScaleNormal1x) @@ -287,7 +305,6 @@ forcenormal: else goto forcenormal; } - /* Special test for normal2x to switch to normal with hardware scaling */ width *= xscale; if (gfx_flags & GFX_SCALING) { height = MakeAspectTable(render.src.height, yscale, yscale ); diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index 826b16c0..28f44864 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -158,7 +158,7 @@ ScalerLineBlock_t ScalerCache = { }; ScalerSimpleBlock_t ScaleNormal1x = { - GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8, + GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, 1,1, Normal1x_8_8_L, Normal1x_8_15_L, Normal1x_8_16_L, Normal1x_8_32_L, 0, Normal1x_15_15_L, Normal1x_15_16_L, Normal1x_15_32_L, @@ -173,7 +173,7 @@ ScalerSimpleBlock_t ScaleNormal1x = { }; ScalerSimpleBlock_t ScaleNormalDw = { - GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8, + GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, 2,1, NormalDw_8_8_L, NormalDw_8_15_L, NormalDw_8_16_L, NormalDw_8_32_L, 0, NormalDw_15_15_L, NormalDw_15_16_L, NormalDw_15_32_L, @@ -188,7 +188,7 @@ ScalerSimpleBlock_t ScaleNormalDw = { }; ScalerSimpleBlock_t ScaleNormalDh = { - GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8, + GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, 1,2, NormalDh_8_8_L, NormalDh_8_15_L, NormalDh_8_16_L, NormalDh_8_32_L, 0, NormalDh_15_15_L, NormalDh_15_16_L, NormalDh_15_32_L, @@ -203,7 +203,7 @@ ScalerSimpleBlock_t ScaleNormalDh = { }; ScalerSimpleBlock_t ScaleNormal2x = { - GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8, + GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, 2,2, Normal2x_8_8_L, Normal2x_8_15_L, Normal2x_8_16_L, Normal2x_8_32_L, 0, Normal2x_15_15_L, Normal2x_15_16_L, Normal2x_15_32_L, @@ -218,7 +218,7 @@ ScalerSimpleBlock_t ScaleNormal2x = { }; ScalerSimpleBlock_t ScaleNormal3x = { - GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8, + GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, 3,3, Normal3x_8_8_L, Normal3x_8_15_L, Normal3x_8_16_L, Normal3x_8_32_L, 0, Normal3x_15_15_L, Normal3x_15_16_L, Normal3x_15_32_L, @@ -233,7 +233,7 @@ ScalerSimpleBlock_t ScaleNormal3x = { }; ScalerSimpleBlock_t ScaleTV2x = { - GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 2,2, 0, TV2x_8_15_L, TV2x_8_16_L, TV2x_8_32_L, 0, TV2x_15_15_L, TV2x_15_16_L, TV2x_15_32_L, @@ -248,7 +248,7 @@ ScalerSimpleBlock_t ScaleTV2x = { }; ScalerSimpleBlock_t ScaleTV3x = { - GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 3,3, 0, TV3x_8_15_L, TV3x_8_16_L, TV3x_8_32_L, 0, TV3x_15_15_L, TV3x_15_16_L, TV3x_15_32_L, @@ -263,7 +263,7 @@ ScalerSimpleBlock_t ScaleTV3x = { }; ScalerSimpleBlock_t ScaleScan2x = { - GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 2,2, 0, Scan2x_8_15_L, Scan2x_8_16_L, Scan2x_8_32_L, 0, Scan2x_15_15_L, Scan2x_15_16_L, Scan2x_15_32_L, @@ -278,7 +278,7 @@ ScalerSimpleBlock_t ScaleScan2x = { }; ScalerSimpleBlock_t ScaleScan3x = { - GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 3,3, 0, Scan3x_8_15_L, Scan3x_8_16_L, Scan3x_8_32_L, 0, Scan3x_15_15_L, Scan3x_15_16_L, Scan3x_15_32_L, @@ -293,7 +293,7 @@ ScalerSimpleBlock_t ScaleScan3x = { }; ScalerSimpleBlock_t ScaleRGB2x = { - GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 2,2, 0, RGB2x_8_15_L, RGB2x_8_16_L, RGB2x_8_32_L, 0, RGB2x_15_15_L, RGB2x_15_16_L, RGB2x_15_32_L, @@ -308,7 +308,7 @@ ScalerSimpleBlock_t ScaleRGB2x = { }; ScalerSimpleBlock_t ScaleRGB3x = { - GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 3,3, 0, RGB3x_8_15_L, RGB3x_8_16_L, RGB3x_8_32_L, 0, RGB3x_15_15_L, RGB3x_15_16_L, RGB3x_15_32_L, @@ -326,14 +326,14 @@ ScalerSimpleBlock_t ScaleRGB3x = { /* Complex scalers */ ScalerComplexBlock_t ScaleAdvMame2x ={ - GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8, + GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, 2,2, AdvMame2x_8_L,AdvMame2x_16_L,AdvMame2x_16_L,AdvMame2x_32_L, AdvMame2x_8_R,AdvMame2x_16_R,AdvMame2x_16_R,AdvMame2x_32_R }; ScalerComplexBlock_t ScaleAdvMame3x = { - GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8, + GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, 3,3, AdvMame3x_8_L,AdvMame3x_16_L,AdvMame3x_16_L,AdvMame3x_32_L, AdvMame3x_8_R,AdvMame3x_16_R,AdvMame3x_16_R,AdvMame3x_32_R @@ -341,14 +341,14 @@ ScalerComplexBlock_t ScaleAdvMame3x = { /* These need specific 15bpp versions */ ScalerComplexBlock_t ScaleAdvInterp2x = { - GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 2,2, 0,AdvInterp2x_15_L,AdvInterp2x_16_L,AdvInterp2x_32_L, 0,AdvInterp2x_15_R,AdvInterp2x_16_R,AdvInterp2x_32_R }; ScalerComplexBlock_t ScaleAdvInterp3x = { - GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY, + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 3,3, 0,AdvInterp3x_15_L,AdvInterp3x_16_L,AdvInterp3x_32_L, 0,AdvInterp3x_15_R,AdvInterp3x_16_R,AdvInterp3x_32_R From 36f1182601fbc0eb39c0f76eea8de80942230827 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 13 Feb 2006 09:26:01 +0000 Subject: [PATCH 2413/4131] Handle window exposure to trigger a full redraw Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2497 --- src/gui/sdlmain.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index fa424328..04a4b8f7 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.103 2006-02-12 23:53:50 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.104 2006-02-13 09:26:01 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -142,6 +142,7 @@ enum PRIORITY_LEVELS { struct SDL_Block { bool active; //If this isn't set don't draw bool updating; + bool exposeEvent; struct { Bit32u width; Bit32u height; @@ -700,7 +701,7 @@ void GFX_EndUpdate( const Bit16u *changedLines ) { SDL_UnlockSurface(sdl.surface); } SDL_Flip(sdl.surface); - } else if (changedLines) { + } else if (changedLines && !sdl.exposeEvent) { Bitu y = 0, index = 0, rectCount = 0; while (y < sdl.draw.height) { if (!(index & 1)) { @@ -723,6 +724,7 @@ void GFX_EndUpdate( const Bit16u *changedLines ) { if (rectCount) SDL_UpdateRects( sdl.surface, rectCount, sdl.updateRects ); } else { + sdl.exposeEvent = false; SDL_Flip(sdl.surface); } break; @@ -1194,6 +1196,9 @@ void GFX_Events() { case SDL_QUIT: throw(0); break; + case SDL_VIDEOEXPOSE: + sdl.exposeEvent = true; + break; #ifdef WIN32 case SDL_KEYDOWN: case SDL_KEYUP: @@ -1203,7 +1208,6 @@ void GFX_Events() { if (((event.key.keysym.sym==SDLK_TAB)) && ((laltstate==SDL_KEYDOWN) || (raltstate==SDL_KEYDOWN))) break; #endif - default: void MAPPER_CheckEvent(SDL_Event * event); MAPPER_CheckEvent(&event); From fba156039781f5f79882fe7b01976775b0149a64 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 13 Feb 2006 11:12:29 +0000 Subject: [PATCH 2414/4131] Add render_simple.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2498 --- src/gui/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 9e017c5d..12695b17 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -3,6 +3,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libgui.a libgui_a_SOURCES = sdlmain.cpp sdl_mapper.cpp dosbox_logo.h \ render.cpp render_scalers.cpp render_scalers.h \ - render_templates.h render_loops.h \ + render_templates.h render_loops.h render_simple.h \ midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h midi_alsa.h From fd40723fd27de4e3b2822bfb5125c44a28fb360f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 14 Feb 2006 08:49:30 +0000 Subject: [PATCH 2415/4131] Give console a name Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2499 --- src/gui/sdlmain.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 04a4b8f7..5ace2eab 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.104 2006-02-13 09:26:01 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.105 2006-02-14 08:49:30 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1253,6 +1253,7 @@ int main(int argc, char* argv[]) { setbuf(stderr, NULL); /* No buffering */ } else { if (AllocConsole()) { + SetConsoleTitle("DOSBox Status Window"); fclose(stdin); fclose(stdout); fclose(stderr); From 28e87018ac06359ed9c95601a1f11791898cf27c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 14 Feb 2006 08:51:07 +0000 Subject: [PATCH 2416/4131] Give debugger console a name as well Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2500 --- src/debug/debug_win32.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/debug/debug_win32.cpp b/src/debug/debug_win32.cpp index 70d4bb4d..c3c48e51 100644 --- a/src/debug/debug_win32.cpp +++ b/src/debug/debug_win32.cpp @@ -69,6 +69,7 @@ static void ResizeConsole( HANDLE hConsole, SHORT xSize, SHORT ySize ) { void WIN32_Console() { AllocConsole(); + SetConsoleTitle("DOSBox Debugger"); ResizeConsole(GetStdHandle(STD_OUTPUT_HANDLE),80,50); } #endif From c807253656995d8e2f34f448926526eb1ee6c9ff Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 14 Feb 2006 09:53:24 +0000 Subject: [PATCH 2417/4131] hopefully fix random crashes with cycles=auto Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2501 --- src/dosbox.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index c6ffdf33..947c1822 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.94 2006-02-12 23:28:21 harekiet Exp $ */ +/* $Id: dosbox.cpp,v 1.95 2006-02-14 09:53:24 qbix79 Exp $ */ #include #include @@ -113,7 +113,7 @@ bool SDLNetInited; static Bit32u ticksRemain; static Bit32u ticksLast; static Bit32u ticksAdded; -static Bit32u ticksDone; +static Bit32s ticksDone; static Bit32u ticksScheduled; static bool ticksLocked; @@ -148,7 +148,7 @@ increaseticks: ticksScheduled = 0; } else { Bit32u ticksNew; - ticksNew=GetTicks(); + ticksNew=GetTicks(); ticksScheduled += ticksAdded; if (ticksNew > ticksLast) { ticksRemain = ticksNew-ticksLast; From 8b9ba65e3685468675af1556e6a71fb3ea3dbe0a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 14 Feb 2006 12:44:38 +0000 Subject: [PATCH 2418/4131] Fix a warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2502 --- src/gui/render_scalers.cpp | 2 +- src/hardware/vga_s3.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index 28f44864..dc7d084e 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -29,7 +29,7 @@ Bit8u Scaler_Aspect[SCALER_MAXHEIGHT]; Bit16u Scaler_ChangedLines[SCALER_MAXHEIGHT]; Bitu Scaler_ChangedLineIndex; -union { +static union { Bit32u b32 [4][SCALER_MAXWIDTH*3]; Bit16u b16 [4][SCALER_MAXWIDTH*3]; Bit8u b8 [4][SCALER_MAXWIDTH*3]; diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index 67c9f1f3..8668cac8 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: vga_s3.cpp,v 1.3 2006-02-14 12:44:38 qbix79 Exp $ */ + #include "dosbox.h" #include "inout.h" #include "vga.h" @@ -429,4 +431,5 @@ Bitu SVGA_S3_GetClock(void) { else clock=1000*S3_CLOCK(vga.s3.clk[clock].m,vga.s3.clk[clock].n,vga.s3.clk[clock].r); return clock; -} \ No newline at end of file +} + From 3656d0e59919dc7ff856d5aa1068a08f65cfdabb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 14 Feb 2006 12:46:43 +0000 Subject: [PATCH 2419/4131] Change -1 to ~0. Let's hope I didn't break a thing. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2503 --- src/hardware/hardware.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 0cc8e657..b59dd1fc 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: hardware.cpp,v 1.13 2006-02-12 23:25:46 harekiet Exp $ */ +/* $Id: hardware.cpp,v 1.14 2006-02-14 12:46:43 qbix79 Exp $ */ #include #include @@ -203,7 +203,7 @@ static void CAPTURE_VideoEvent(bool pressed) { AVIOUTd(0); /* Start */ AVIOUTd(capture.video.frames); /* Length */ AVIOUTd(0); /* SuggestedBufferSize */ - AVIOUTd(-1); /* Quality */ + AVIOUTd(~0); /* Quality */ AVIOUTd(0); /* SampleSize */ AVIOUTd(0); /* Frame */ AVIOUTd(0); /* Frame */ @@ -241,7 +241,7 @@ static void CAPTURE_VideoEvent(bool pressed) { capture.video.audiorate = 1; AVIOUTd(capture.video.audiowritten/4); /* Length */ AVIOUTd(0); /* SuggestedBufferSize */ - AVIOUTd(-1); /* Quality */ + AVIOUTd(~0); /* Quality */ AVIOUTd(4); /* SampleSize */ AVIOUTd(0); /* Frame */ AVIOUTd(0); /* Frame */ From 4ab434490657719e0223c7caaea0a7a926e31918 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 14 Feb 2006 13:04:02 +0000 Subject: [PATCH 2420/4131] Make cycles=auto look more beautiful ;) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2504 --- src/cpu/cpu.cpp | 10 +++++----- src/gui/sdlmain.cpp | 11 +++++++---- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index ff74d7af..7a37d5bd 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.77 2006-02-12 23:28:21 harekiet Exp $ */ +/* $Id: cpu.cpp,v 1.78 2006-02-14 13:04:01 qbix79 Exp $ */ #include #include "dosbox.h" @@ -1877,7 +1877,7 @@ void CPU_ENTER(bool use32,Bitu bytes,Bitu level) { extern void GFX_SetTitle(Bits cycles ,Bits frameskip,bool paused); static void CPU_CycleIncrease(bool pressed) { - if (!pressed) + if (!pressed || CPU_CycleAuto) return; Bits old_cycles=CPU_CycleMax; if(CPU_CycleUp < 100){ @@ -1893,7 +1893,7 @@ static void CPU_CycleIncrease(bool pressed) { } static void CPU_CycleDecrease(bool pressed) { - if (!pressed) + if (!pressed || CPU_CycleAuto) return; if(CPU_CycleDown < 100){ CPU_CycleMax = (Bits)(CPU_CycleMax / (1 + (float)CPU_CycleDown / 100.0)); @@ -1964,10 +1964,10 @@ public: CPU_Cycles=0; const char *cyclesLine = section->Get_string("cycles"); if (!strcasecmp(cyclesLine,"auto")) { - CPU_CycleMax=0; + CPU_CycleMax=0; CPU_CycleAuto=true; } else { - CPU_CycleMax=atoi(cyclesLine); + CPU_CycleMax=atoi(cyclesLine); CPU_CycleAuto=false; } CPU_CycleUp=section->Get_int("cycleup"); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 5ace2eab..7dbc66a6 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.105 2006-02-14 08:49:30 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.106 2006-02-14 13:04:02 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -208,6 +208,7 @@ struct SDL_Block { static SDL_Block sdl; extern char * RunningProgram; +extern bool CPU_CycleAuto; //Globals for keyboard initialisation bool startup_state_numlock=false; bool startup_state_capslock=false; @@ -217,10 +218,12 @@ void GFX_SetTitle(Bits cycles,Bits frameskip,bool paused){ static Bits internal_frameskip=0; if(cycles != -1) internal_cycles = cycles; if(frameskip != -1) internal_frameskip = frameskip; - if(paused) - sprintf(title,"DOSBox %s,Cpu Cycles: %8d, Frameskip %2d, Program: %8s PAUSED",VERSION,internal_cycles,internal_frameskip,RunningProgram); + if(CPU_CycleAuto) + sprintf(title,"DOSBox %s,Cpu Cycles: auto, Frameskip %2d, Program: %8s",VERSION,internal_frameskip,RunningProgram); else - sprintf(title,"DOSBox %s,Cpu Cycles: %8d, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram); + sprintf(title,"DOSBox %s,Cpu Cycles: %8d, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram); + + if(paused) strcat(title," PAUSED"); SDL_WM_SetCaption(title,VERSION); } From 1446999784aeb551bb0cce9b8906b06a3f646d56 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 15 Feb 2006 14:48:41 +0000 Subject: [PATCH 2421/4131] SDL under vsc doesn't close console ?(kekko) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2505 --- src/gui/sdlmain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 7dbc66a6..e4e17e00 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.106 2006-02-14 13:04:02 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.107 2006-02-15 14:48:41 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1256,7 +1256,6 @@ int main(int argc, char* argv[]) { setbuf(stderr, NULL); /* No buffering */ } else { if (AllocConsole()) { - SetConsoleTitle("DOSBox Status Window"); fclose(stdin); fclose(stdout); fclose(stderr); @@ -1264,6 +1263,7 @@ int main(int argc, char* argv[]) { freopen("CONOUT$","w",stdout); freopen("CONOUT$","w",stderr); } + SetConsoleTitle("DOSBox Status Window"); } #endif //defined(WIN32) && !(C_DEBUG) #if C_DEBUG From db884adba430eadf14a125de16cf5cdd28e487fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 16 Feb 2006 20:18:59 +0000 Subject: [PATCH 2422/4131] add scancode mapping of MacOSX for usescancodes=true (thanks to cc_benny for this!) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2506 --- src/gui/sdl_mapper.cpp | 90 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 82 insertions(+), 8 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index f8438d8f..d3e54a3c 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.20 2006-02-12 23:23:52 harekiet Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.21 2006-02-16 20:18:59 c2woody Exp $ */ #define OLD_JOYSTICK 1 @@ -211,14 +211,70 @@ protected: #define MAX_SDLKEYS 323 -#define MAX_SCANCODES 212 static bool usescancodes; -Bit8u scancode_map[MAX_SDLKEYS]; +static Bit8u scancode_map[MAX_SDLKEYS]; #define Z SDLK_UNKNOWN -SDLKey sdlkey_map[MAX_SCANCODES]={SDLK_UNKNOWN,SDLK_ESCAPE, +#if defined (MACOSX) +static SDLKey sdlkey_map[]={ + /* Main block printables */ + /*00-05*/ SDLK_a, SDLK_s, SDLK_d, SDLK_f, SDLK_h, SDLK_g, + /*06-0B*/ SDLK_z, SDLK_x, SDLK_c, SDLK_v, SDLK_WORLD_0, SDLK_b, + /*0C-11*/ SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_y, SDLK_t, + /*12-17*/ SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_6, SDLK_5, + /*18-1D*/ SDLK_EQUALS, SDLK_9, SDLK_7, SDLK_MINUS, SDLK_8, SDLK_0, + /*1E-21*/ SDLK_RIGHTBRACKET, SDLK_o, SDLK_u, SDLK_LEFTBRACKET, + /*22-23*/ SDLK_i, SDLK_p, + /*24-29*/ SDLK_RETURN, SDLK_l, SDLK_j, SDLK_QUOTE, SDLK_k, SDLK_SEMICOLON, + /*2A-29*/ SDLK_BACKSLASH, SDLK_COMMA, SDLK_SLASH, SDLK_n, SDLK_m, + /*2F-2F*/ SDLK_PERIOD, + + /* Spaces, controls, modifiers (dosbox uses LMETA only for + * hotkeys, it's not really mapped to an emulated key) */ + /*30-33*/ SDLK_TAB, SDLK_SPACE, SDLK_BACKQUOTE, SDLK_BACKSPACE, + /*34-37*/ Z, SDLK_ESCAPE, Z, SDLK_LMETA, + /*38-3B*/ SDLK_LSHIFT, SDLK_CAPSLOCK, SDLK_LALT, SDLK_LCTRL, + + /*3C-40*/ Z, Z, Z, Z, Z, + + /* Keypad (KP_EQUALS not supported, NUMLOCK used on what is CLEAR + * in Mac OS X) */ + /*41-46*/ SDLK_KP_PERIOD, Z, SDLK_KP_MULTIPLY, Z, SDLK_PLUS, Z, + /*47-4A*/ SDLK_NUMLOCK /*==SDLK_CLEAR*/, Z, Z, Z, + /*4B-4D*/ SDLK_KP_DIVIDE, SDLK_KP_ENTER, Z, + /*4E-51*/ SDLK_KP_MINUS, Z, Z, SDLK_KP_EQUALS, + /*52-57*/ SDLK_KP0, SDLK_KP1, SDLK_KP2, SDLK_KP3, SDLK_KP4, SDLK_KP5, + /*58-5C*/ SDLK_KP6, SDLK_KP7, Z, SDLK_KP8, SDLK_KP9, + + /*5D-5F*/ Z, Z, Z, + + /* Function keys and cursor blocks (F13-F16 not supported, INSERT + * used on what is HELP in Mac OS X) */ + /*60-64*/ SDLK_F5, SDLK_F6, SDLK_F7, SDLK_F3, SDLK_F8, + /*65-6A*/ SDLK_F9, Z, SDLK_F11, Z, SDLK_F13, (SDLKey)(SDLK_F15+1), + /*6B-71*/ SDLK_F14, Z, SDLK_F10, Z, SDLK_F12, Z, SDLK_F15, + /*72-74*/ SDLK_INSERT /*==SDLK_HELP*/, SDLK_HOME, SDLK_PAGEUP, + /*75-79*/ SDLK_DELETE, SDLK_F4, SDLK_END, SDLK_F2, SDLK_PAGEDOWN, + /*7A-7E*/ SDLK_F1, SDLK_LEFT, SDLK_RIGHT, SDLK_DOWN, SDLK_UP, + + /*7F-7F*/ Z, + + /* 4 extra keys that don't really exist, but are needed for + * round-trip mapping (dosbox uses RMETA only for hotkeys, it's + * not really mapped to an emulated key) */ + SDLK_RMETA, SDLK_RSHIFT, SDLK_RALT, SDLK_RCTRL, +}; +#define MAX_SCANCODES (0x80+4) +/* Make sure that the table above has the expected size. This + expression will raise a compiler error if the condition is false. */ +typedef char assert_right_size [MAX_SCANCODES == (sizeof(sdlkey_map)/sizeof(sdlkey_map[0])) ? 1 : -1]; + +#else // !MACOSX + +#define MAX_SCANCODES 212 +static SDLKey sdlkey_map[MAX_SCANCODES]={SDLK_UNKNOWN,SDLK_ESCAPE, SDLK_1,SDLK_2,SDLK_3,SDLK_4,SDLK_5,SDLK_6,SDLK_7,SDLK_8,SDLK_9,SDLK_0, /* 0x0c: */ SDLK_MINUS,SDLK_EQUALS,SDLK_BACKSPACE,SDLK_TAB, @@ -244,6 +300,7 @@ SDLKey sdlkey_map[MAX_SCANCODES]={SDLK_UNKNOWN,SDLK_ESCAPE, Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z /* 0xd4: ... */ }; +#endif #undef Z @@ -258,11 +315,18 @@ SDLKey MapSDLCode(Bitu skey) { Bitu GetKeyCode(SDL_keysym keysym) { if (usescancodes) { Bitu key=(Bitu)keysym.scancode; - if (key==0) { + if (key==0 +#if defined (MACOSX) + /* On Mac on US keyboards, scancode 0 is actually the 'a' + * key. For good measure exclude all printables from this + * condition. */ + && (keysym.sym < SDLK_SPACE || keysym.sym > SDLK_WORLD_95) +#endif + ) { /* try to retrieve key from symbolic key as scancode is zero */ if (keysym.sym Linux */ sdlkey_map[0x5a]=SDLK_UP; sdlkey_map[0x60]=SDLK_DOWN; sdlkey_map[0x5c]=SDLK_LEFT; From a2cb88f4913488636e45b9c1867b2c23d84bf4e0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 18 Feb 2006 14:45:12 +0000 Subject: [PATCH 2423/4131] Fix for aces of the deep with vcpi.(wd) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2507 --- src/ints/ems.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index b325e4f8..f37e4987 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.45 2006-02-09 11:47:56 qbix79 Exp $ */ +/* $Id: ems.cpp,v 1.46 2006-02-18 14:45:12 qbix79 Exp $ */ #include #include @@ -611,18 +611,31 @@ static Bitu INT67_Handler(void) { reg_ah=EMM_NO_ERROR; reg_bx=0x100; break; - case 0x01: /* VCPI Get Protected Mode Interface */ + case 0x01: { /* VCPI Get Protected Mode Interface */ + Bit16u ct; /* Set up page table buffer */ - for (Bit16u ct=0; ct<0xff; ct++) { + for (ct=0; ct<0xff; ct++) { real_writeb(SegValue(es),reg_di+ct*4+0x00,0x67); // access bits real_writew(SegValue(es),reg_di+ct*4+0x01,ct*0x10); // mapping real_writeb(SegValue(es),reg_di+ct*4+0x03,0x00); } - for (Bit16u ct=0xff; ct<0x100; ct++) { + for (ct=0xff; ct<0x100; ct++) { real_writeb(SegValue(es),reg_di+ct*4+0x00,0x67); // access bits real_writew(SegValue(es),reg_di+ct*4+0x01,(ct-0xff)*0x10+0x1100); // mapping real_writeb(SegValue(es),reg_di+ct*4+0x03,0x00); } + /* adjust paging entries for page frame (if mapped) */ + for (ct=0; ct<4; ct++) { + Bit16u handle=emm_mappings[ct].handle; + if (handle!=0xffff) { + Bit16u memh=(Bit16u)MEM_NextHandleAt(emm_handles[handle].mem,emm_mappings[ct].page*4); + Bit16u entry_addr=reg_di+(EMM_PAGEFRAME>>6)+(ct*0x10); + real_writew(SegValue(es),entry_addr+0x00+0x01,(memh+0)*0x10); // mapping of 1/4 of page + real_writew(SegValue(es),entry_addr+0x04+0x01,(memh+1)*0x10); // mapping of 2/4 of page + real_writew(SegValue(es),entry_addr+0x08+0x01,(memh+2)*0x10); // mapping of 3/4 of page + real_writew(SegValue(es),entry_addr+0x0c+0x01,(memh+3)*0x10); // mapping of 4/4 of page + } + } reg_di+=0x400; // advance pointer by 0x100*4 /* Set up three descriptor table entries */ @@ -636,6 +649,7 @@ static Bitu INT67_Handler(void) { reg_ebx=(vcpi.pm_interface&0xffff); reg_ah=EMM_NO_ERROR; break; + } case 0x02: /* VCPI Maximum Physical Address */ reg_edx=((MEM_TotalPages()*MEM_PAGESIZE)-1)&0xfffff000; reg_ah=EMM_NO_ERROR; @@ -737,6 +751,8 @@ static Bitu INT67_Handler(void) { CPU_SetSegGeneral(fs,0); CPU_SetSegGeneral(gs,0); +// MEM_A20_Enable(true); + /* Switch to protected mode */ reg_flags&=(~(FLAG_VM|FLAG_NT)); reg_flags|=0x3000; @@ -801,6 +817,7 @@ static Bitu VCPI_PM_Handler() { reg_flags&=(~FLAG_NT); reg_esp+=8; // skip interrupt return information +// MEM_A20_Enable(false); /* Switch to v86-task */ CPU_IRET(true,0); From 50a6f4e0be72b91b9bf7015ef69376d5a7792dc6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 20 Feb 2006 08:59:52 +0000 Subject: [PATCH 2424/4131] Improve fat drive (findnext). Fat drive still not perfect. Deleting of files sometimes messes FAT up. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2508 --- src/dos/drive_fat.cpp | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index e32c7b07..19a50b0a 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.11 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: drive_fat.cpp,v 1.12 2006-02-20 08:59:52 qbix79 Exp $ */ #include #include @@ -389,6 +389,13 @@ bool fatDrive::getFileDirEntry(char * filename, direntry * useEntry, Bit32u * di findFile = findDir; if(!FindNextInternal(currentClust, *imgDTA, &foundEntry)) break; + else { + //Found something. See if it's a directory (findfirst always finds regular files) + char find_name[DOS_NAMELENGTH_ASCII];Bit16u find_date,find_time;Bit32u find_size;Bit8u find_attr; + imgDTA->GetResult(find_name,find_size,find_date,find_time,find_attr); + if(!(find_attr & DOS_ATTR_DIRECTORY)) break; + } + currentClust = foundEntry.loFirstClust; findDir = strtok(NULL,"\\"); } @@ -400,7 +407,7 @@ bool fatDrive::getFileDirEntry(char * filename, direntry * useEntry, Bit32u * di imgDTA->SetupSearch(0,0x5,findFile); imgDTA->SetDirID(0); if(!FindNextInternal(currentClust, *imgDTA, &foundEntry)) return false; - + memcpy(useEntry, &foundEntry, sizeof(direntry)); *dirClust = (Bit32u)currentClust; *subEntry = ((Bit32u)imgDTA->GetDirID()-1); @@ -423,14 +430,17 @@ bool fatDrive::getDirClustNum(char *dir, Bit32u *clustNum, bool parDir) { imgDTA->SetupSearch(0,DOS_ATTR_DIRECTORY,findDir); imgDTA->SetDirID(0); findDir = strtok(NULL,"\\"); - if(!parDir) { - if(!FindNextInternal(currentClust, *imgDTA, &foundEntry)) return false; + if(parDir && (findDir == NULL)) break; + + char find_name[DOS_NAMELENGTH_ASCII];Bit16u find_date,find_time;Bit32u find_size;Bit8u find_attr; + if(!FindNextInternal(currentClust, *imgDTA, &foundEntry)) { + return false; } else { - if(findDir == NULL) break; - if(!FindNextInternal(currentClust, *imgDTA, &foundEntry)) return false; + imgDTA->GetResult(find_name,find_size,find_date,find_time,find_attr); + if(!(find_attr &DOS_ATTR_DIRECTORY)) return false; } currentClust = foundEntry.loFirstClust; - + } *clustNum = currentClust; return true; @@ -865,7 +875,11 @@ nextfile: strcat(find_name, extension); } - if((attrs & (sectbuf[entryoffset].attrib | 0x21)) == 0) goto nextfile; + /* Ignore files with volume label. FindFirst should search for those. (return the first one found) */ + if(sectbuf[entryoffset].attrib & 0x8) goto nextfile; + + /* Always find ARCHIVES even if bit is not set Perhaps test is not the best test */ + if(~attrs & sectbuf[entryoffset].attrib & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM) ) goto nextfile; if(!WildFileCmp(find_name,srch_pattern)) goto nextfile; dta.SetResult(find_name, sectbuf[entryoffset].entrysize, sectbuf[entryoffset].crtDate, sectbuf[entryoffset].crtTime, sectbuf[entryoffset].attrib); From 2fa26d71d168219d185332da0758f875ebcf9914 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 20 Feb 2006 14:40:37 +0000 Subject: [PATCH 2425/4131] Whoops. Mention Ido Beeri. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2509 --- src/gui/dosbox_logo.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/dosbox_logo.h b/src/gui/dosbox_logo.h index 50aba157..be40334c 100644 --- a/src/gui/dosbox_logo.h +++ b/src/gui/dosbox_logo.h @@ -16,7 +16,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox_logo.h,v 1.1 2006-02-09 08:42:42 qbix79 Exp $ */ +/* $Id: dosbox_logo.h,v 1.2 2006-02-20 14:40:37 qbix79 Exp $ */ + +/* DOSBox icon designed by Ido Beeri */ /* Select only one logo at the time */ #define LOGO_1 1 From 579bf59181130a87e4dbf3856aae43785fbf4764 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 23 Feb 2006 08:13:14 +0000 Subject: [PATCH 2426/4131] Fix alien odyssey. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2510 --- src/shell/shell_batch.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 2fbf1eaf..952dd348 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.19 2006-02-09 11:47:57 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.20 2006-02-23 08:13:14 qbix79 Exp $ */ #include #include @@ -51,7 +51,11 @@ emptyline: n=1; DOS_ReadFile(file_handle,&c,&n); if (n>0) { - if (c>31 || c==0x1b || c=='\t') + /* Why are we filtering this ? + * Exclusion list: tab for batch files + * escape for ansi + * backspace for alien odyssey */ + if (c>31 || c==0x1b || c=='\t' || c==8) *cmd_write++=c; } } while (c!='\n' && n); From 6472a2bbf32af619ee82c0da0aa07014df4b9e18 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 24 Feb 2006 11:50:11 +0000 Subject: [PATCH 2427/4131] display gig correctly Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2511 --- src/shell/shell_cmds.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index c8ba70df..6db7cebc 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.61 2006-02-09 11:47:57 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.62 2006-02-24 11:50:11 qbix79 Exp $ */ #include #include @@ -270,12 +270,18 @@ void DOS_Shell::CMD_RMDIR(char * args) { }; static void FormatNumber(Bitu num,char * buf) { - Bitu numm,numk,numb; + Bitu numm,numk,numb,numg; numb=num % 1000; num/=1000; numk=num % 1000; num/=1000; - numm=num; + numm=num % 1000; + num/=1000; + numg=num; + if (numg) { + sprintf(buf,"%d,%03d,%03d,%03d",numg,numm,numk,numb); + return; + }; if (numm) { sprintf(buf,"%d,%03d,%03d",numm,numk,numb); return; From da4e0390210ce4d4e52f8c0d000d309373d48873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 24 Feb 2006 14:31:24 +0000 Subject: [PATCH 2428/4131] enable ems remapping during dma transfers from the pageframe (fixes sound in several MicroProse games) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2512 --- src/hardware/dma.cpp | 56 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index e039d46f..36dcdd1e 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -27,13 +27,26 @@ DmaController *DmaControllers[2]; +#define EMM_PAGEFRAME4K ((0xE000*16)/4096) +Bit32u ems_board_mapping[LINK_START]; + +static void UpdateEMSMapping(void) { + /* if EMS is not present, this will result in a 1:1 mapping */ + Bitu i; + for (i=0;i<0x10;i++) { + ems_board_mapping[EMM_PAGEFRAME4K+i]=paging.firstmb[EMM_PAGEFRAME4K+i]; + } +} + /* read a block from physical memory */ static void DMA_BlockRead(PhysPt pt,void * data,Bitu size) { Bit8u * write=(Bit8u *) data; for ( ; size ; size--, pt++) { Bitu page = pt >> 12; - if (page < LINK_START) /* cares for EMS pageframe etc. */ - page = paging.firstmb[page]; + /* care for EMS pageframe etc. */ + if (page < EMM_PAGEFRAME4K) page = paging.firstmb[page]; + else if (page < EMM_PAGEFRAME4K+0x10) page = ems_board_mapping[page]; + else if (page < LINK_START) page = paging.firstmb[page]; *write++=phys_readb(page*4096 + (pt & 4095)); } } @@ -43,8 +56,10 @@ static void DMA_BlockWrite(PhysPt pt,void * data,Bitu size) { Bit8u * read=(Bit8u *) data; for ( ; size ; size--, pt++) { Bitu page = pt >> 12; - if (page < LINK_START) /* cares for EMS pageframe etc. */ - page = paging.firstmb[page]; + /* care for EMS pageframe etc. */ + if (page < EMM_PAGEFRAME4K) page = paging.firstmb[page]; + else if (page < EMM_PAGEFRAME4K+0x10) page = ems_board_mapping[page]; + else if (page < LINK_START) page = paging.firstmb[page]; phys_writeb(page*4096 + (pt & 4095), *read++); } } @@ -81,14 +96,17 @@ static void DMA_Write_Port(Bitu port,Bitu val,Bitu iolen) { } else if (port>=0xc0 && port <=0xdf) { /* write to the second DMA controller (channels 4-7) */ DmaControllers[1]->WriteControllerReg((port-0xc0) >> 1,val,1); - } else switch (port) { - /* write DMA page register */ - case 0x81:GetDMAChannel(2)->SetPage(val);break; - case 0x82:GetDMAChannel(3)->SetPage(val);break; - case 0x83:GetDMAChannel(1)->SetPage(val);break; - case 0x89:GetDMAChannel(6)->SetPage(val);break; - case 0x8a:GetDMAChannel(7)->SetPage(val);break; - case 0x8b:GetDMAChannel(5)->SetPage(val);break; + } else { + UpdateEMSMapping(); + switch (port) { + /* write DMA page register */ + case 0x81:GetDMAChannel(2)->SetPage(val);break; + case 0x82:GetDMAChannel(3)->SetPage(val);break; + case 0x83:GetDMAChannel(1)->SetPage(val);break; + case 0x89:GetDMAChannel(6)->SetPage(val);break; + case 0x8a:GetDMAChannel(7)->SetPage(val);break; + case 0x8b:GetDMAChannel(5)->SetPage(val);break; + } } } @@ -116,6 +134,7 @@ void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) { switch (reg) { /* set base address of DMA transfer (1st byte low part, 2nd byte high part) */ case 0x0:case 0x2:case 0x4:case 0x6: + UpdateEMSMapping(); chan=GetChannel(reg >> 1); flipflop=!flipflop; if (flipflop) { @@ -128,6 +147,7 @@ void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) { break; /* set DMA transfer count (1st byte low part, 2nd byte high part) */ case 0x1:case 0x3:case 0x5:case 0x7: + UpdateEMSMapping(); chan=GetChannel(reg >> 1); flipflop=!flipflop; if (flipflop) { @@ -144,10 +164,12 @@ void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) { //TODO Warning? break; case 0xa: /* Mask Register */ + if ((val & 0x4)==0) UpdateEMSMapping(); chan=GetChannel(val & 3); chan->SetMask((val & 0x4)>0); break; case 0xb: /* Mode Register */ + UpdateEMSMapping(); chan=GetChannel(val & 3); chan->autoinit=(val & 0x10) > 0; chan->increment=(val & 0x20) > 0; @@ -165,12 +187,14 @@ void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) { flipflop=false; break; case 0xe: /* Clear Mask register */ + UpdateEMSMapping(); for (i=0;i<4;i++) { chan=GetChannel(i); chan->SetMask(false); } break; case 0xf: /* Multiple Mask register */ + UpdateEMSMapping(); for (i=0;i<4;i++) { chan=GetChannel(i); chan->SetMask(val & 1); @@ -253,10 +277,12 @@ again: currcnt=basecnt; curraddr=baseaddr; if (want) goto again; + UpdateEMSMapping(); } else { curraddr+=left; currcnt=0xffff; masked=true; + UpdateEMSMapping(); DoCallBack(DMA_TRANSFEREND); } } @@ -282,10 +308,12 @@ again: currcnt=basecnt; curraddr=baseaddr; if (want) goto again; + UpdateEMSMapping(); } else { curraddr+=left; currcnt=0xffff; masked=true; + UpdateEMSMapping(); DoCallBack(DMA_TRANSFEREND); } } @@ -341,4 +369,8 @@ void DMA_Destroy(Section* sec){ void DMA_Init(Section* sec) { test = new DMA(sec); sec->AddDestroyFunction(&DMA_Destroy); + Bitu i; + for (i=0;i Date: Fri, 24 Feb 2006 20:42:15 +0000 Subject: [PATCH 2429/4131] don't mess up vga registers in VGA_FillRow (Mortal Kombat Ping Pong) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2513 --- src/ints/int10_char.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index d5b329ab..011c02e5 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.45 2006-02-09 11:47:57 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.46 2006-02-24 20:42:15 c2woody Exp $ */ /* Character displaying moving functions */ @@ -179,8 +179,6 @@ static INLINE void VGA_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bi for (Bitu x=0;x Date: Sun, 26 Feb 2006 13:46:31 +0000 Subject: [PATCH 2430/4131] ipx changes by hal Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2514 --- include/ipx.h | 5 ++++- include/ipxserver.h | 1 - src/hardware/ipx.cpp | 52 +++++++++++++++++++++++++++----------------- 3 files changed, 36 insertions(+), 22 deletions(-) diff --git a/include/ipx.h b/include/ipx.h index 7022aa33..5d2bc6e6 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.h,v 1.8 2006-02-09 11:47:47 qbix79 Exp $ */ +/* $Id: ipx.h,v 1.9 2006-02-26 13:46:31 qbix79 Exp $ */ #ifndef DOSBOX_IPX_H #define DOSBOX_IPX_H @@ -94,6 +94,8 @@ struct fragmentDescriptor { Bit16u size; }; +#define IPXBUFFERSIZE 1424 + class ECBClass { public: RealPt ECBAddr; @@ -123,6 +125,7 @@ public: void NotifyESR(void); void setImmAddress(Bit8u *immAddr); + void getImmAddress(Bit8u* immAddr); ~ECBClass(); }; diff --git a/include/ipxserver.h b/include/ipxserver.h index 31240f7c..041e541f 100644 --- a/include/ipxserver.h +++ b/include/ipxserver.h @@ -33,7 +33,6 @@ struct packetBuffer { }; #define SOCKETTABLESIZE 16 -#define IPXBUFFERSIZE 1024 #define CONVIP(hostvar) hostvar & 0xff, (hostvar >> 8) & 0xff, (hostvar >> 16) & 0xff, (hostvar >> 24) & 0xff #define CONVIPX(hostvar) hostvar[0], hostvar[1], hostvar[2], hostvar[3], hostvar[4], hostvar[5] diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index 580d784c..907c6ca2 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.cpp,v 1.9 2006-02-09 11:47:49 qbix79 Exp $ */ +/* $Id: ipx.cpp,v 1.10 2006-02-26 13:46:31 qbix79 Exp $ */ #include "dosbox.h" @@ -199,7 +199,12 @@ void ECBClass::NotifyESR(void) { void ECBClass::setImmAddress(Bit8u *immAddr) { for(Bitu i=0;i<6;i++) - real_writeb(RealSeg(ECBAddr), RealOff(ECBAddr)+28, immAddr[i]); + real_writeb(RealSeg(ECBAddr), RealOff(ECBAddr)+28+i, immAddr[i]); +} + +void ECBClass::getImmAddress(Bit8u* immAddr) { + for(Bitu i=0;i<6;i++) + immAddr[i] = real_readb(RealSeg(ECBAddr), RealOff(ECBAddr)+28+i); } ECBClass::~ECBClass() { @@ -325,7 +330,14 @@ static void handleIpxRequest(void) { CloseSocket(); break; case 0x0002: // get local target - reg_al=0xfa; // fail + // es:si + // Currently no support for multiple networks + + for(Bitu i = 0; i < 6; i++) + real_writeb(SegValue(es),reg_di+i,real_readb(SegValue(es),reg_si+i+4)); + + reg_cx=1; // time ticks expected + reg_al=0x00;//success break; case 0x0003: // Send packet @@ -401,11 +413,21 @@ static void handleIpxRequest(void) { case 0x000a: // Relinquish control // Idle thingy break; + case 0x000b: // Disconnect from Target + // We don't even connect + break; + case 0x0010: // SPX install check { reg_al=0; // SPX not installed break; } + case 0x001a: // get driver maximum packet size + { + reg_cx=0; // retry count + reg_ax=IPXBUFFERSIZE; // max packet size + break; + } default: LOG_MSG("Unhandled IPX function: %4x", reg_bx); break; @@ -552,13 +574,9 @@ static void IPX_ClientLoop(void) { inPacket.maxlen = IPXBUFFERSIZE; inPacket.channel = UDPChannel; - //do - //{ - // Its amazing how much simpler UDP is than TCP - numrecv = SDLNet_UDP_Recv(ipxClientSocket, &inPacket); - if(numrecv) receivePacket(inPacket.data, inPacket.len); - - //}while(numrecv>0); + // Its amazing how much simpler UDP is than TCP + numrecv = SDLNet_UDP_Recv(ipxClientSocket, &inPacket); + if(numrecv) receivePacket(inPacket.data, inPacket.len); } @@ -620,15 +638,10 @@ static void sendPacket(ECBClass* sendecb) { // Source socket wordptr[14] = swapByte(sendecb->getSocket()); + Bit8u immedAddr[6]; + sendecb->getImmAddress(immedAddr); // filter out broadcasts and local loopbacks - // ok, the situation is: - // Warcraft1 is allergic to having broadcast packets looped back. - // C&C1 is allergic to not having broadcast packets looped back. - // Warcraft1 broadcasts to 00 00 00 00 : FF FF FF FF FF FF - // C&C1 broadcasts to FF FF FF FF : FF FF FF FF FF FF - // Some other games don't care. - // I assume FF... does local loopback, 00... doesn't. - // Let's hope the bug isn't somewhere else.. + // Real implementation uses the ImmedAddr to check wether this is a broadcast bool islocalbroadcast=true; bool isloopback=true; @@ -638,12 +651,11 @@ static void sendPacket(ECBClass* sendecb) { addrptr = (Bit8u *)&localIpxAddr.netnum; for(Bitu m=0;m<4;m++) { if(addrptr[m]!=outbuffer[m+0x6])isloopback=false; - if(outbuffer[m+0x6]!=0xff) islocalbroadcast=false; } addrptr = (Bit8u *)&localIpxAddr.netnode; for(Bitu m=0;m<6;m++) { if(addrptr[m]!=outbuffer[m+0xa])isloopback=false; - if(outbuffer[m+0xa]!=0xff) islocalbroadcast=false; + if(immedAddr[m]!=0xff) islocalbroadcast=false; } if(!isloopback) { From 2d8426975a721d2fb128180427a9aa6b0ee6afbe Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 Feb 2006 13:48:06 +0000 Subject: [PATCH 2431/4131] modem changes by hal. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2515 --- src/hardware/serialport/softmodem.cpp | 79 +++++++++++---------------- src/hardware/serialport/softmodem.h | 5 +- 2 files changed, 33 insertions(+), 51 deletions(-) diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index 8352b6aa..c83c02cb 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.cpp,v 1.3 2006-02-09 11:47:55 qbix79 Exp $ */ +/* $Id: softmodem.cpp,v 1.4 2006-02-26 13:48:06 qbix79 Exp $ */ #include "dosbox.h" @@ -64,17 +64,6 @@ CSerialModem::CSerialModem( rqueue=new CFifo(MODEM_BUFFER_QUEUE_SIZE); tqueue=new CFifo(MODEM_BUFFER_QUEUE_SIZE); - //cmdpos = 0; - - //plusinc = 0; - //incomingsocket = 0; -// answermode = false; - //memset(®,0,sizeof(reg)); - //cmdpause = 0; - //echo = true; - //doresponse = true; - //numericresponse = false; - /* Default to direct null modem connection. Telnet mode interprets IAC codes */ telnetmode = false; @@ -233,7 +222,7 @@ void CSerialModem::Reset(){ cmdpos = 0; cmdbuf[0]=0; oldDTRstate = getDTR(); - + flowcontrol = 0; plusinc = 0; incomingsocket = 0; memset(®,0,sizeof(reg)); @@ -256,8 +245,7 @@ void CSerialModem::Reset(){ void CSerialModem::EnterIdleState(void){ connected=false; ringing=false; - txbufferfull=false; - + if(socket) { // clear current socket SDLNet_TCP_DelSocket(socketset,socket); SDLNet_TCP_Close(socket); @@ -277,6 +265,8 @@ void CSerialModem::EnterIdleState(void){ commandmode = true; CSerial::setCD(false); CSerial::setRI(false); + CSerial::setDSR(true); + CSerial::setCTS(true); tqueue->clear(); } @@ -487,41 +477,39 @@ void CSerialModem::DoCommand() { { if(scanbuf[0]!=0) { char ch = scanbuf[0]; - //switch(scanbuf[0]) Maybe You want to implement it? scanbuf++; - LOG_MSG("Modem: Unhandled command: &%c%d",ch,ScanNumber(scanbuf)); + switch(ch) { + case 'K': + { + Bitu val = ScanNumber(scanbuf); + if(val<5) flowcontrol=val; + else { + SendRes(ResERROR); + return; + } + break; + } + default: + { + scanbuf++; + LOG_MSG("Modem: Unhandled command: &%c%d",ch,ScanNumber(scanbuf)); + break; + } + } } else { SendRes(ResERROR); return; } } - break; + break; default: LOG_MSG("Modem: Unhandled command: %c%d",chr,ScanNumber(scanbuf)); } } -/* - } - - if (strstr(mhd.cmdbuf,"NET0")) - { - telnetmode = false; - } - if (strstr(mhd.cmdbuf,"NET1")) - { - telnetmode = true; - } - #endif*/ - //ret_ok: SendRes(ResOK); return; - //ret_error: - //SendRes(ResERROR); - //ret_none: - // return; - } void CSerialModem::TelnetEmulation(Bit8u * data, Bitu size) { @@ -639,7 +627,7 @@ void CSerialModem::Timer2(void) { // check for bytes to be sent to port if(CSerial::CanReceiveByte()) - if(rqueue->inuse() && CSerial::getRTS()) { + if(rqueue->inuse() && (CSerial::getRTS()||(flowcontrol!=3))) { Bit8u rbyte = rqueue->getb(); //LOG_MSG("Modem: sending byte %2x back to UART3",rbyte); CSerial::receiveByte(rbyte); @@ -757,12 +745,10 @@ void CSerialModem::Timer2(void) { //TODO void CSerialModem::RXBufferEmpty() { // see if rqueue has some more bytes - if(rqueue->inuse() && CSerial::getRTS()){ + if(rqueue->inuse() && (CSerial::getRTS()||(flowcontrol!=3))){ Bit8u rbyte = rqueue->getb(); //LOG_MSG("Modem: sending byte %2x back to UART1",rbyte); CSerial::receiveByte(rbyte); - - //CSerial::receiveByte(rqueue->getb()); } } @@ -770,9 +756,8 @@ void CSerialModem::transmitByte(Bit8u val) { //LOG_MSG("MODEM: Byte %x to be transmitted",val); if(tqueue->left()) { tqueue->addb(val); - if(!tqueue->left()) { + if(tqueue->left() < 2) { CSerial::setCTS(false); - txbufferfull=true; } } else LOG_MSG("MODEM: TX Buffer overflow!"); CSerial::ByteTransmitted(); @@ -790,12 +775,10 @@ void CSerialModem::setBreak(bool) { // TODO: handle this } -void CSerialModem::updateModemControlLines(/*Bit8u mcr*/) { - //if(!txbufferfull) - //{ - // if(CSerial::getRTS()) CSerial::setCTS(true); - // else CSerial::setCTS(false); - //} +void CSerialModem::updateModemControlLines() { + //bool txrdy=tqueue->left(); + //if(CSerial::getRTS() && txrdy) CSerial::setCTS(true); + //else CSerial::setCTS(tqueue->left()); // If DTR goes low, hang up. if(connected) diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index 4ec1e764..259f27ce 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.h,v 1.4 2006-02-09 11:47:55 qbix79 Exp $ */ +/* $Id: softmodem.h,v 1.5 2006-02-26 13:48:06 qbix79 Exp $ */ #ifndef DOSBOX_SERIALMODEM_H #define DOSBOX_SERIALMODEM_H @@ -197,7 +197,6 @@ protected: bool telnetmode; // true: process IAC commands. bool connected; - bool txbufferfull; Bitu doresponse; @@ -207,7 +206,7 @@ protected: Bits ringcount; Bitu plusinc; Bitu cmdpos; - + Bitu flowcontrol; //Bit8u mctrl; Bit8u tmpbuf[MODEM_BUFFER_QUEUE_SIZE]; From ab1f16e077dd524d907d8b0538fb06761ca7b6f4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 Feb 2006 15:57:28 +0000 Subject: [PATCH 2432/4131] Fix F3 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2516 --- src/shell/shell_misc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 7105790a..568625a9 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.40 2006-02-09 11:47:57 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.41 2006-02-26 15:57:28 qbix79 Exp $ */ #include #include @@ -83,6 +83,7 @@ void DOS_Shell::InputCommand(char * line) { } str_len = str_index = it_history->length(); size = CMD_MAXLINE - str_index - 2; + line[str_len] = 0; } break; From a7d928260af0eb5963ee20ba6379bbd821999018 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 Feb 2006 15:58:49 +0000 Subject: [PATCH 2433/4131] Fix crashes with -c set a=b and exiting dosbox externally. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2517 --- src/shell/shell.cpp | 137 +++++++++++++++++++++++--------------------- 1 file changed, 72 insertions(+), 65 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 3bf8229a..29c272e7 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.71 2006-02-09 11:47:57 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.72 2006-02-26 15:58:49 qbix79 Exp $ */ #include #include @@ -329,84 +329,91 @@ void DOS_Shell::SyntaxError(void) { WriteOut(MSG_Get("SHELL_SYNTAXERROR")); } -namespace { +class AUTOEXEC:public Module_base { +private: AutoexecObject autoexec[16]; AutoexecObject autoexec_echo; -} +public: + AUTOEXEC(Section* configuration):Module_base(configuration) { + /* Register a virtual AUOEXEC.BAT file */ + std::string line; + Section_line * section=static_cast(configuration); -void AUTOEXEC_Init(Section * sec) { - /* Register a virtual AUOEXEC.BAT file */ - std::string line; - Section_line * section=static_cast(sec); + /* add stuff from the configfile unless -noautexec is specified. */ + char * extra=const_cast(section->data.c_str()); + if (extra && !control->cmdline->FindExist("-noautoexec",true)) { + /* detect if "echo off" is the first line */ + bool echo_off = !strncasecmp(extra,"echo off",8); + if (!echo_off) echo_off = !strncasecmp(extra,"@echo off",9); - /* add stuff from the configfile unless -noautexec is specified. */ - char * extra=const_cast(section->data.c_str()); - if (extra && !control->cmdline->FindExist("-noautoexec",true)) { - /* detect if "echo off" is the first line */ - bool echo_off = !strncasecmp(extra,"echo off",8); - if (!echo_off) echo_off = !strncasecmp(extra,"@echo off",9); + /* if "echo off" add it to the front of autoexec.bat */ + if(echo_off) autoexec_echo.InstallBefore("@echo off"); - /* if "echo off" add it to the front of autoexec.bat */ - if(echo_off) autoexec_echo.InstallBefore("@echo off"); - - /* Install the stuff from the configfile */ - autoexec[0].Install("%s",extra); - } - - /* Check to see for extra command line options to be added (before the command specified on commandline) */ - /* Maximum of extra commands: 10 */ - Bitu i = 1; - while (control->cmdline->FindString("-c",line,true) && (i <= 11)) - autoexec[i++].Install((char *)line.c_str()); - - /* Check for the -exit switch which causes dosbox to when the command on the commandline has finished */ - bool addexit = control->cmdline->FindExist("-exit",true); - - /* Check for first command being a directory or file */ - char buffer[CROSS_LEN]; - char cross_filesplit[2] = {CROSS_FILESPLIT , 0}; - if (control->cmdline->FindCommand(1,line)) { - struct stat test; - strcpy(buffer,line.c_str()); - if (stat(buffer,&test)){ - getcwd(buffer,CROSS_LEN); - strcat(buffer,cross_filesplit); - strcat(buffer,line.c_str()); - if (stat(buffer,&test)) goto nomount; + /* Install the stuff from the configfile */ + autoexec[0].Install("%s",extra); } - if (test.st_mode & S_IFDIR) { - autoexec[12].Install("MOUNT C \"%s\"",buffer); - autoexec[13].Install("C:"); - } else { - char* name = strrchr(buffer,CROSS_FILESPLIT); - if (!name) { //Only a filename - line = buffer; + + /* Check to see for extra command line options to be added (before the command specified on commandline) */ + /* Maximum of extra commands: 10 */ + Bitu i = 1; + while (control->cmdline->FindString("-c",line,true) && (i <= 11)) + autoexec[i++].Install((char *)line.c_str()); + + /* Check for the -exit switch which causes dosbox to when the command on the commandline has finished */ + bool addexit = control->cmdline->FindExist("-exit",true); + + /* Check for first command being a directory or file */ + char buffer[CROSS_LEN]; + char cross_filesplit[2] = {CROSS_FILESPLIT , 0}; + if (control->cmdline->FindCommand(1,line)) { + struct stat test; + strcpy(buffer,line.c_str()); + if (stat(buffer,&test)){ getcwd(buffer,CROSS_LEN); strcat(buffer,cross_filesplit); strcat(buffer,line.c_str()); - if(stat(buffer,&test)) goto nomount; - name = strrchr(buffer,CROSS_FILESPLIT); - if(!name) goto nomount; + if (stat(buffer,&test)) goto nomount; } - *name++ = 0; - if (access(buffer,F_OK)) goto nomount; - autoexec[12].Install("MOUNT C \"%s\"",buffer); - autoexec[13].Install("C:"); - upcase(name); - if(strstr(name,".BAT") == 0) { - autoexec[14].Install(name); + if (test.st_mode & S_IFDIR) { + autoexec[12].Install("MOUNT C \"%s\"",buffer); + autoexec[13].Install("C:"); } else { - /* BATch files are called else exit will not work */ - char call[CROSS_LEN] = { 0 }; - strcpy(call,"CALL "); - strcat(call,name); - autoexec[14].Install(call); + char* name = strrchr(buffer,CROSS_FILESPLIT); + if (!name) { //Only a filename + line = buffer; + getcwd(buffer,CROSS_LEN); + strcat(buffer,cross_filesplit); + strcat(buffer,line.c_str()); + if(stat(buffer,&test)) goto nomount; + name = strrchr(buffer,CROSS_FILESPLIT); + if(!name) goto nomount; + } + *name++ = 0; + if (access(buffer,F_OK)) goto nomount; + autoexec[12].Install("MOUNT C \"%s\"",buffer); + autoexec[13].Install("C:"); + upcase(name); + if(strstr(name,".BAT") == 0) { + autoexec[14].Install(name); + } else { + /* BATch files are called else exit will not work */ + char call[CROSS_LEN] = { 0 }; + strcpy(call,"CALL "); + strcat(call,name); + autoexec[14].Install(call); + } + if(addexit) autoexec[15].Install("exit"); } - if(addexit) autoexec[15].Install("exit"); } - } nomount: - VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,strlen(autoexec_data)); + VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,strlen(autoexec_data)); + } +}; + +static AUTOEXEC* test; + +void AUTOEXEC_Init(Section * sec) { + test = new AUTOEXEC(sec); } static char * path_string="PATH=Z:\\"; From 6c7c289c62ba27696c1fbf6515c13ec0ffdf0e62 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 Feb 2006 16:01:31 +0000 Subject: [PATCH 2434/4131] Hopefully fix gameblaster support. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2518 --- src/hardware/gameblaster.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index af3be1b0..db647db6 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -364,7 +364,7 @@ static void saa1099_write_port_w( int chip, int offset, int data ) static void write_cms(Bitu port,Bitu val,Bitu iolen) { - if (last_command + 1000 < PIC_Ticks) cms_chan->Enable(true); + if (last_command + 1000 < PIC_Ticks) if(cms_chan) cms_chan->Enable(true); last_command = PIC_Ticks; switch (port) { case 0x0220: @@ -415,8 +415,8 @@ static void write_cms(Bitu port,Bitu val,Bitu iolen) { else *stream=(Bit16s)right; stream++; } - cms_chan->AddSamples_s16(len,(Bit16s *)MixTemp); - if (last_command + 10000 < PIC_Ticks) cms_chan->Enable(false); + if(cms_chan) cms_chan->AddSamples_s16(len,(Bit16s *)MixTemp); + if (last_command + 10000 < PIC_Ticks) if(cms_chan) cms_chan->Enable(false); } @@ -427,15 +427,16 @@ private: public: CMS(Section* configuration):Module_base(configuration) { - Section_prop * section=static_cast(configuration); - Bitu sample_rate = section->Get_int("oplrate"); + Section_prop * section = static_cast(configuration); + Bitu sample_rate_temp = section->Get_int("oplrate"); + sample_rate = static_cast(sample_rate_temp); Bitu base = section->Get_hex("base"); WriteHandler.Install(base,write_cms,IO_MB,4); - + /* Register the Mixer CallBack */ - cms_chan = MixerChan.Install(CMS_CallBack,sample_rate,"CMS"); + cms_chan = MixerChan.Install(CMS_CallBack,sample_rate_temp,"CMS"); - last_command=PIC_Ticks; + last_command = PIC_Ticks; for (int s=0;s<2;s++) { struct SAA1099 *saa = &saa1099[s]; @@ -443,7 +444,7 @@ public: } } ~CMS() { - cms_chan->Enable(false); + cms_chan = 0; } }; From af25c4382d2f67d38bfdcfa3cdf55b8afbc521fd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 Feb 2006 16:04:35 +0000 Subject: [PATCH 2435/4131] Add workaround for corrupted surface on exposure event. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2519 --- include/video.h | 10 ++++++++-- src/gui/render.cpp | 18 ++++++++++++------ src/gui/sdlmain.cpp | 19 ++++++++----------- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/include/video.h b/include/video.h index f6a3c208..e439369e 100644 --- a/include/video.h +++ b/include/video.h @@ -19,7 +19,13 @@ #ifndef DOSBOX_VIDEO_H #define DOSBOX_VIDEO_H -typedef void (* GFX_ResetCallBack)( bool stopIt ); +typedef enum { + GFX_CallBackReset, + GFX_CallBackStop, + GFX_CallBackRedraw, +} GFX_CallBackFunctions_t; + +typedef void (*GFX_CallBack_t)( GFX_CallBackFunctions_t function ); struct GFX_PalEntry { Bit8u r; @@ -49,7 +55,7 @@ void GFX_Events(void); void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries); Bitu GFX_GetBestMode(Bitu flags); Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue); -Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_ResetCallBack cb_reset); +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); diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 69fe644a..10e9a10d 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.42 2006-02-13 08:22:17 harekiet Exp $ */ +/* $Id: render.cpp,v 1.43 2006-02-26 16:04:35 qbix79 Exp $ */ #include #include @@ -183,14 +183,20 @@ static Bitu MakeAspectTable(Bitu height,double scaley,Bitu miny) { return linesadded; } -void RENDER_ReInit( bool stopIt ) { +void RENDER_CallBack( GFX_CallBackFunctions_t function ) { if (render.updating) { /* Still updating the current screen, shut it down correctly */ RENDER_EndUpdate( false ); } - if (stopIt) + if (function == GFX_CallBackStop) return; + + if (function == GFX_CallBackRedraw) { + //LOG_MSG("redraw"); + render.scale.clearCache = true; + return; + } Bitu width=render.src.width; Bitu height=render.src.height; @@ -318,7 +324,7 @@ forcenormal: } } /* Setup the scaler variables */ - gfx_flags=GFX_SetSize(width,height,gfx_flags,gfx_scalew,gfx_scaleh,&RENDER_ReInit);; + gfx_flags=GFX_SetSize(width,height,gfx_flags,gfx_scalew,gfx_scaleh,&RENDER_CallBack); if (gfx_flags & GFX_CAN_8) render.scale.outMode = scalerMode8; else if (gfx_flags & GFX_CAN_15) @@ -397,7 +403,7 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool render.src.dblh=dblh; render.src.fps=fps; render.src.ratio=ratio; - RENDER_ReInit( false ); + RENDER_CallBack( GFX_CallBackReset ); } extern void GFX_SetTitle(Bits cycles, Bits frameskip,bool paused); @@ -457,7 +463,7 @@ void RENDER_Init(Section * sec) { //If something changed that needs a ReInit if(running && (render.aspect != aspect || render.scale.op != scaleOp)) - RENDER_ReInit( false ); + RENDER_CallBack( GFX_CallBackReset ); if(!running) render.updating=true; running = true; diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index e4e17e00..0666b265 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.107 2006-02-15 14:48:41 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.108 2006-02-26 16:04:35 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -142,14 +142,13 @@ enum PRIORITY_LEVELS { struct SDL_Block { bool active; //If this isn't set don't draw bool updating; - bool exposeEvent; struct { Bit32u width; Bit32u height; Bit32u bpp; Bitu flags; double scalex,scaley; - GFX_ResetCallBack reset; + GFX_CallBack_t callback; } draw; bool wait_on_error; struct { @@ -314,7 +313,7 @@ check_gotbpp: void GFX_ResetScreen(void) { GFX_Stop(); - if (sdl.draw.reset) (sdl.draw.reset)( false ); + if (sdl.draw.callback) (sdl.draw.callback)( GFX_CallBackReset ); GFX_Start(); } @@ -370,13 +369,13 @@ static SDL_Surface * GFX_SetupSurfaceScaled(Bit32u sdl_flags, Bit32u bpp) { } } -Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_ResetCallBack reset) { +Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_CallBack_t callback) { if (sdl.updating) GFX_EndUpdate( 0 ); sdl.draw.width=width; sdl.draw.height=height; - sdl.draw.reset=reset; + sdl.draw.callback=callback; sdl.draw.scalex=scalex; sdl.draw.scaley=scaley; @@ -704,7 +703,7 @@ void GFX_EndUpdate( const Bit16u *changedLines ) { SDL_UnlockSurface(sdl.surface); } SDL_Flip(sdl.surface); - } else if (changedLines && !sdl.exposeEvent) { + } else if (changedLines) { Bitu y = 0, index = 0, rectCount = 0; while (y < sdl.draw.height) { if (!(index & 1)) { @@ -727,7 +726,6 @@ void GFX_EndUpdate( const Bit16u *changedLines ) { if (rectCount) SDL_UpdateRects( sdl.surface, rectCount, sdl.updateRects ); } else { - sdl.exposeEvent = false; SDL_Flip(sdl.surface); } break; @@ -844,7 +842,7 @@ void GFX_Start() { static void GUI_ShutDown(Section * sec) { GFX_Stop(); - if (sdl.draw.reset) (sdl.draw.reset)( true ); + if (sdl.draw.callback) (sdl.draw.callback)( GFX_CallBackStop ); if (sdl.mouse.locked) GFX_CaptureMouse(); if (sdl.desktop.fullscreen) GFX_SwitchFullScreen(); } @@ -1159,7 +1157,6 @@ static void HandleMouseButton(SDL_MouseButtonEvent * button) { static Bit8u laltstate = SDL_KEYUP; static Bit8u raltstate = SDL_KEYUP; - void GFX_Events() { SDL_Event event; while (SDL_PollEvent(&event)) { @@ -1200,7 +1197,7 @@ void GFX_Events() { throw(0); break; case SDL_VIDEOEXPOSE: - sdl.exposeEvent = true; + if (sdl.draw.callback) sdl.draw.callback( GFX_CallBackRedraw ); break; #ifdef WIN32 case SDL_KEYDOWN: From 7736351416416580aba2edcc4948abe57900cea2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 Feb 2006 16:05:13 +0000 Subject: [PATCH 2436/4131] Make con use extended keys when machine is vga Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2520 --- src/dos/dev_con.h | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index df97577b..5479014d 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.23 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: dev_con.h,v 1.24 2006-02-26 16:05:13 qbix79 Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" @@ -60,7 +60,7 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { readcache=0; } while (*size>count) { - reg_ah=0; + reg_ah=(machine==MCH_VGA)?0x10:0x0; CALLBACK_RunRealInt(0x16); switch(reg_al) { case 13: @@ -84,14 +84,23 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { continue; //no data read yet so restart whileloop. } break; - default: - data[count++]=reg_al; + case 0xe0: /* Extended keys in the int 16 0x10 case */ + if(!reg_ah) { /*extended key if reg_ah isn't 0 */ + data[count++] = reg_al; + } else { + data[count++] = 0; + if (*size>count) data[count++] = reg_ah; + else readcache = reg_ah; + } break; - case 0: + case 0: /* Extended keys in the int 16 0x0 case */ data[count++]=reg_al; if (*size>count) data[count++]=reg_ah; else readcache=reg_ah; break; + default: + data[count++]=reg_al; + break; } if(dos.echo) { //what to do if *size==1 and character is BS ????? INT10_TeletypeOutput(reg_al,7); @@ -357,7 +366,7 @@ bool device_CON::Close() { Bit16u device_CON::GetInformation(void) { Bit16u head=mem_readw(BIOS_KEYBOARD_BUFFER_HEAD); Bit16u tail=mem_readw(BIOS_KEYBOARD_BUFFER_TAIL); - + if ((head==tail) && !readcache) return 0x80D3; /* No Key Available */ return 0x8093; /* Key Available */ }; From edc31febd20b60542214234e56b85893079d3b81 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 Feb 2006 16:07:27 +0000 Subject: [PATCH 2437/4131] Fix crashes when specifying an illegal type with imgmount Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2521 --- src/dos/dos_programs.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 92d3015a..28d91b01 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.53 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.54 2006-02-26 16:07:27 qbix79 Exp $ */ #include #include @@ -642,16 +642,17 @@ public: std::string fstype="fat"; cmd->FindString("-t",type,true); cmd->FindString("-fs",fstype,true); + if(type == "cdrom") type = "iso"; //Tiny hack for people who like to type -t cdrom Bit8u mediaid; if (type=="floppy" || type=="hdd" || type=="iso") { Bit16u sizes[4]; std::string str_size; - mediaid=0xF8; + mediaid=0xF8; if (type=="floppy") { mediaid=0xF0; - } else if (type=="cdrom" || type=="iso") { + } else if (type=="iso") { str_size="650,127,16513,1700"; mediaid=0xF8; fstype = "iso"; @@ -676,8 +677,7 @@ public: if(fstype=="fat" || fstype=="iso") { // get the drive letter - cmd->FindCommand(1,temp_line); - if ((temp_line.size() > 2) || ((temp_line.size()>1) && (temp_line[1]!=':'))) { + if (!cmd->FindCommand(1,temp_line) || (temp_line.size() > 2) || ((temp_line.size()>1) && (temp_line[1]!=':'))) { WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_DRIVE")); return; } @@ -765,7 +765,11 @@ public: newImage = new imageDisk(newDisk, (Bit8u *)temp_line.c_str(), imagesize, (imagesize > 2880)); if(imagesize>2880) newImage->Set_Geometry(sizes[2],sizes[3],sizes[1],sizes[0]); } + } else { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_TYPE_UNSUPPORTED"),type.c_str()); + return; } + if(fstype=="fat") { if (Drives[drive-'A']) { WriteOut(MSG_Get("PROGRAM_IMGMOUNT_ALLREADY_MOUNTED")); @@ -976,6 +980,7 @@ void DOS_SetupPrograms(void) { "\n" "For \033[33mhardrive\033[0m images: Must specify drive geometry for hard drives:\n" "bytes_per_sector, sectors_per_cylinder, heads_per_cylinder, cylinder_count.\n"); + MSG_Add("PROGRAM_IMGMOUNT_TYPE_UNSUPPORTED","Type \"%s\" is unsupported. Specify \"hdd\" or \"floppy\" or\"iso\".\n"); MSG_Add("PROGRAM_IMGMOUNT_FORMAT_UNSUPPORTED","Format \"%s\" is unsupported. Specify \"fat\" or \"iso\" or \"none\".\n"); MSG_Add("PROGRAM_IMGMOUNT_SPECIFY_FILE","Must specify file-image to mount.\n"); MSG_Add("PROGRAM_IMGMOUNG_FILE_NOT_FOUND","Image file not found.\n"); From 1859bf4f5d7172258898f6badf683c8be97ee5c7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 Feb 2006 16:11:00 +0000 Subject: [PATCH 2438/4131] fix typo. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2522 --- src/cpu/cpu.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 7a37d5bd..51e2b575 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.78 2006-02-14 13:04:01 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.79 2006-02-26 16:11:00 qbix79 Exp $ */ #include #include "dosbox.h" @@ -1987,7 +1987,7 @@ public: } #endif else { - LOG_MSG("CPU:Unknown core type %s, switcing back to normal.",core); + LOG_MSG("CPU:Unknown core type %s, switching back to normal.",core); } #if (C_DYNAMIC_X86) From c1e01a4cb0ca0ae3324a67574c9c57e8081e48de Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Feb 2006 19:48:56 +0000 Subject: [PATCH 2439/4131] --disable-debug didn't work Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2523 --- configure.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 4a981905..e8daf184 100644 --- a/configure.in +++ b/configure.in @@ -82,7 +82,9 @@ AC_ARG_ENABLE(debug,AC_HELP_STRING([--enable-debug],[Enable debug mode]),[ AC_CHECK_LIB(curses, initscr, have_curses_lib=yes, , ) AC_CHECK_LIB(pdcurses, initscr, have_pdcurses_lib=yes, , ) - if test x$have_curses_lib = xyes -a x$have_curses_h = xyes ; then + 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 From fcae186854efb801ee30f4b836a5a3ce953cbab5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Feb 2006 20:16:08 +0000 Subject: [PATCH 2440/4131] Fix tearline tyrian. Hopefully I don't break too much other things. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2524 --- src/hardware/vga_draw.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 92ea0bbf..1aac3051 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -351,7 +351,8 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.cursor.address+=vga.tandy.disp_bank << 14; } if (bDoDraw) - VGA_DrawPart(vga.draw.parts_lines); +// VGA_DrawPart(vga.draw.parts_lines); + PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts/2,vga.draw.parts_lines); //Else tearline in Tyrian and second reality } void VGA_CheckScanLength(void) { From da5641fc2ff31675f291668a3424b48e06c75b7c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Feb 2006 20:16:49 +0000 Subject: [PATCH 2441/4131] Revert former fix so that panic works again. (DSTROY still works as well). Makes no sense though. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2525 --- src/hardware/timer.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 0fa2f36d..ecfbd8a5 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.34 2006-02-09 11:47:49 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.35 2006-02-27 20:16:49 qbix79 Exp $ */ #include #include "dosbox.h" @@ -224,7 +224,12 @@ static void write_p43(Bitu port,Bitu val,Bitu iolen) { pit[latch].read_state = (val >> 4) & 0x03; pit[latch].write_state = (val >> 4) & 0x03; Bit8u mode = (val >> 1) & 0x07; + if (mode > 5) + mode -= 4; //6,7 become 2 and 3 + /* Don't set it directly so counter_output uses the old mode */ + /* That's theory. It breaks panic. So set it here again */ + if(!pit[latch].mode) pit[latch].mode = mode; /* If the line goes from low to up => generate irq. * ( BUT needs to stay up until acknowlegded by the cpu!!! therefore: ) @@ -234,8 +239,6 @@ static void write_p43(Bitu port,Bitu val,Bitu iolen) { * counter_output tells if the current counter is high or low * So actually a mode 2 timer enables and disables irq al the time. (not handled) */ - if (mode > 5) - mode -= 4; //6,7 become 2 and 3 if (latch == 0) { PIC_RemoveEvents(PIT0_Event); if (!counter_output(0) && mode) From 4ec565af2d15f2bddf63b853f304707789f81eb2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Feb 2006 20:33:28 +0000 Subject: [PATCH 2442/4131] Some documentation improvements Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2526 --- ChangeLog | 10 +++++++--- README | 50 +++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index d427ec84..39bb479d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,7 +27,7 @@ - Improved ADPCM emulation. - Fixed a few cpu instructions. - Always report vesa 2.0 and fix some colour issues with vesa games. - - Fix video mode 6. + - Fix video mode 0x06 and 0x0a. - Improvements to the joystick emulation. 4 buttons are supported as well. - Add VCPI emulation. No more ems=false with Origin games. - Fixed a lot of things in the boot code. Most booters work now. @@ -39,7 +39,7 @@ - Improve Composite CGA mode emulation. - Lots of vga compatibility changes. - Improved support for chained video modes. - - Improved mode and palete handling in cga modes. + - Improved mode and palette handling in cga modes. - Mount accepts ~ now. - Added a few of the EGA RIL functions. - Added TandyDAC emulation. @@ -48,12 +48,16 @@ - 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 with come with their + - 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. - Compilation fixes for various platforms. diff --git a/README b/README index cb92aa1b..1d32eb04 100644 --- a/README +++ b/README @@ -354,21 +354,49 @@ MEM Program to display the amount of free memory. CONFIG [-writeconf] [-writelang] localfile - Write the current configuration or language settings to file. - "localfile" is located on the local drive, not a mounted drive in DOSBox. +CONFIG -set "section property=value" +CONFIG -get "section property" - The configuration file controls various settings of DOSBox: the amount - of emulated memory, the emulated soundcards and many more things. It - allows access to AUTOEXEC.BAT as well. - See section 9 (The Config File) for more information. + CONFIG can be used to change or query various settings of DOSBox + during runtime. It can save the current settings and language strings to + disk. Information about all possible sections and properties can + be found in section 9 (The Config File). - The language file controls all visible ouput of the internal commands - and the internal dos. + -writeconf localfile + Write the current configuration settings to file. "localfile" is + located on the local drive, not a mounted drive in DOSBox. + The configuration file controls various settings of DOSBox: + the amount of emulated memory, the emulated soundcards and many more + things. It allows access to AUTOEXEC.BAT as well. + See section 9 (The Config File) for more information. - Example: - To create a configfile in your current directory: - config -writeconf dosbox.conf + -writelang localfile + Write the current language settings to file. "localfile" is + located on the local drive, not a mounted drive in DOSBox. + The language file controls all visible ouput of the internal commands + and the internal dos. + -set "section property=value" + CONFIG will attempt to set the property to new value. At this moment + CONFIG can not report whether the command succeeded or not. + + -get "section property" + The current value of the property is reported and stored in the + environment variable %CONFIG%. This can be used to store the value + when using batch files. + + Both "-set" and "-get" work from batch files and can be used to set up your + own preferences for each game. + + Examples: + 1. To create a configfile in your current directory: + config -writeconf dosbox.conf + 2. To set the cpu cycles to 10000: + config -set "cpu cycles=1000" + 3. To turn ems memory emulation off: + config -set "dos ems=false" + 4. To check which cpu core is being used. + config -get "cpu core" LOADFIX [-size] [program] [program-parameters] LOADFIX -f From 545d46516725ed033a6ed4e985e2477ff996539f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Feb 2006 21:00:27 +0000 Subject: [PATCH 2443/4131] spaces + windowresolution documentation Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2527 --- src/gui/sdlmain.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 0666b265..404c33bd 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.108 2006-02-26 16:04:35 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.109 2006-02-27 21:00:27 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -218,9 +218,9 @@ void GFX_SetTitle(Bits cycles,Bits frameskip,bool paused){ if(cycles != -1) internal_cycles = cycles; if(frameskip != -1) internal_frameskip = frameskip; if(CPU_CycleAuto) - sprintf(title,"DOSBox %s,Cpu Cycles: auto, Frameskip %2d, Program: %8s",VERSION,internal_frameskip,RunningProgram); + sprintf(title,"DOSBox %s, Cpu Cycles: auto, Frameskip %2d, Program: %8s",VERSION,internal_frameskip,RunningProgram); else - sprintf(title,"DOSBox %s,Cpu Cycles: %8d, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram); + sprintf(title,"DOSBox %s, Cpu Cycles: %8d, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram); if(paused) strcat(title," PAUSED"); SDL_WM_SetCaption(title,VERSION); @@ -1310,7 +1310,7 @@ int main(int argc, char* argv[]) { ",ddraw" #endif ".\n" - "hwscale -- Extra scaling of window if the output device supports hardware scaling.\n" + "windowresolution -- Scale the window to this size IF the output device supports hardware scaling.\n" "autolock -- Mouse will automatically lock, if you click on the screen.\n" "sensitiviy -- Mouse sensitivity.\n" "waitonerror -- Wait before closing the console if dosbox has an error.\n" From d8a9fd5065824ebf69466d5a5a88c7b4b6d5c5aa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Feb 2006 15:13:00 +0000 Subject: [PATCH 2444/4131] Documentation improvements Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2528 --- README | 64 ++++++++++++++++++++++------------------ src/dos/dos_programs.cpp | 13 ++++++-- 2 files changed, 46 insertions(+), 31 deletions(-) diff --git a/README b/README index 1d32eb04..82256e06 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -DOSBox v0.63 +DOSBox v0.65 ===== @@ -6,8 +6,8 @@ NOTE: ===== While we are hoping that one day, DOSBox will run all programs -ever made for the PC,we are not there yet. At present, DOSBox run on a high- -end machine will roughly be the equivalent of a 486 PC. The 0.60 +ever made for the PC, we are not there yet. At present, DOSBox running on a +high-end machine will roughly be the equivalent of a 486 PC. The 0.60 release has added support for "protected mode" allowing for more complex and recent programs, but note that this support is still in an early stage of development and unlike the support for 386 real-mode games (or earlier) hasn't @@ -51,7 +51,7 @@ Some Frequently Asked Questions: Q: I've got a Z instead of a C at the prompt. Q: My CD-ROM doesn't work. Q: The mouse doesn't work. -Q: The sound stutters. +Q: The sound stutters or sounds stretched/weird. Q: I can't type \ or : in DOSBox. Q: The game/application can't find its CD-ROM. Q: The game/application runs much too slow! @@ -66,9 +66,9 @@ Q: Great README, but I still don't get it. Q: I've got a Z instead of a C at the prompt. A: You have to make your directories available as drives in DOSBox by using - the "mount" command. For example, in Windows "mount C D:\" will give - you a C in DOSBox which points to your Windows D:\ drive. - In Linux, "mount c /home/username" will give you a C in DOSBox + the "mount" command. For example, in Windows "mount C D:\GAMES" will give + you a C drive in DOSBox which points to your Windows D:\GAMES directory. + In Linux, "mount c /home/username" will give you a C drive in DOSBox which points to /home/username in Linux. @@ -97,7 +97,7 @@ A: Usually, DOSBox detects when a game uses mouse control. When you click on you will have to lock the mouse manually by pressing CTRL-F10. -Q: The sound stutters. +Q: The sound stutters or sounds stretched/weird. A: You're using too much cpu power to keep DOSBox running at the current speed. You can lower the cycles, skip frames or get a faster machine. You can also increase the prebuffer in the configfile. @@ -108,12 +108,13 @@ A: This is a known problem. It only occurs if your keyboard layout isn't US. Some possible fixes: 1. Switch your keyboard layout. 2. Use / instead. - 3. Add the commands you want to execute to the "configfile". - 4. Start the keymapper (CTRL-F1 or add -startmapper switch to DOSBox). - 5. Use ALT-58 for : and ALT-92 for \. - 6. for \ try the keys around "enter". For ":" try shift and the keys + 3. Open dosbox.conf and change usescancodes=false to usescancodes=true. + 4. Add the commands you want to execute to the "configfile". + 5. Start the keymapper (CTRL-F1 or add -startmapper switch to DOSBox). + 6. Use ALT-58 for : and ALT-92 for \. + 7. for \ try the keys around "enter". For ":" try shift and the keys between "enter" and "l" (US keyboard layout). - 7. Use keyb.com from FreeDOS (http://projects.freedos.net/keyb/). + 8. Use keyb.com from FreeDOS (http://projects.freedos.net/keyb/). Q: The game/application can't find its CD-ROM. @@ -188,7 +189,7 @@ http://dosbox.sourceforge.net 3. Usage: ========= -An overview of the commandline options you can give to DOSBox. +An overview of the command line options you can give to DOSBox. Windows Users must open cmd.exe or command.com or edit the shortcut to DOSBox.exe for this. The options are valid for all operating systems unless noted in the option @@ -201,8 +202,8 @@ dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] dosbox -version name - If "name" is a directory it'll mount that as the C: drive. - If "name" is an executable it'll mount the directory of "name" + If "name" is a directory it will mount that as the C: drive. + If "name" is an executable it will mount the directory of "name" as the C: drive and execute "name". -exit @@ -250,7 +251,7 @@ Note: If a name/command/configfile/languagefile contains a space, put For example: dosbox c:\atlantis\atlantis.exe -c "MOUNT D C:\SAVES" - This mounts c:\atlantis as c:\ and run atlantis.exe. + This mounts c:\atlantis as c:\ and runs atlantis.exe. Before it does that it would first mount C:\SAVES as the D drive. In Windows, you can also drag directories/files onto the DOSBox executable. @@ -303,15 +304,15 @@ MOUNT -u "Emulated Drive letter" is mounted. It will not be updated !! -aspi - Forces to use the aspi layer. Only valid if mounting a cdrom under + Forces use of the aspi layer. Only valid if mounting a cdrom under Windows systems with an ASPI-Layer. -ioctl - Forces to use ioctl commands. Only valid if mounting a cdrom under + Forces use of ioctl commands. Only valid if mounting a cdrom under a Windows OS which support them (Win2000/XP/NT). -usecd number - Forces to use SDL cdrom support for drive number. + Forces use of SDL cdrom support for drive number. Number can be found by -cd. Valid on all systems. -cd @@ -324,9 +325,9 @@ MOUNT -u "Emulated Drive letter" Hardware support is then missing. Basically, MOUNT allows you to connect real hardware to DOSBox's "emulated" - PC. So MOUNT C C:\ tells DOSBox to use your real C: drive as drive C: in - DOSBox. It also allows you to change the drive's letter identification for - programs that demand specific drive letters. + PC. So MOUNT C C:\GAMES tells DOSBox to use your C:\GAMES directory as drive + C: in DOSBox. It also allows you to change the drive's letter identification + for programs that demand specific drive letters. For example: Touche: Adventures of The Fifth Musketeer must be run on your C: drive. Using DOSBox and its mount command, you can trick the game into @@ -334,6 +335,10 @@ MOUNT -u "Emulated Drive letter" want it. For example, if the game is in D:\TOUCHE, the command MOUNT C D:\ will allow you to run Touche from the D drive. + Mounting your entire C drive with MOUNT C C:\ is NOT recommended! + If you or DOSBox makes a mistake you may loose all your files. + It's recommended to put all your applications/games in a subdirectory and + mount that. General MOUNT Examples: 1. To mount c:\DirX as a floppy : @@ -392,9 +397,9 @@ CONFIG -get "section property" 1. To create a configfile in your current directory: config -writeconf dosbox.conf 2. To set the cpu cycles to 10000: - config -set "cpu cycles=1000" + config -set "cpu cycles=10000" 3. To turn ems memory emulation off: - config -set "dos ems=false" + config -set "dos ems=off" 4. To check which cpu core is being used. config -get "cpu core" @@ -508,8 +513,8 @@ BOOT diskimgN.img This can be any number of floppy disk images one wants mounted after DOSBox boots the specified drive letter. - To swap between images, hit CTRL+F4 to change from the current disk - and to the next disk in the list. The list will loop back from the last + To swap between images, hit CTRL-F4 to change from the current disk + to the next disk in the list. The list will loop back from the last disk image to the beginning. [-l driveletter] @@ -619,6 +624,7 @@ CTRL-F9 Kill dosbox. CTRL-F10 Capture/Release the mouse. CTRL-F11 Slow down emulation (Decrease DOSBox Cycles). CTRL-F12 Speed up emulation (Increase DOSBox Cycles). +ALT-F12 Unlock speed (turbo button). These are the default keybindings. They can be changed in the keymapper. @@ -639,7 +645,7 @@ This maximum will vary from computer to computer; there is no standard. ============= When you start the keymapper (either with CTRL-F1 or -startmapper as a -commandline argument to the DOSBox executable) you are presented with +command line argument to the DOSBox executable) you are presented with a virtual keyboard. This virtual keyboard corresponds to the keys DOSBox will report to its @@ -802,4 +808,4 @@ The Beta Testers. See the site: http://dosbox.sourceforge.net -for an emailaddress (The Crew-page). +for an email address (The Crew-page). diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 28d91b01..cab4d4e9 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.54 2006-02-26 16:07:27 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.55 2006-02-28 15:13:00 qbix79 Exp $ */ #include #include @@ -232,6 +232,12 @@ public: default : WriteOut(MSG_Get("MSCDEX_UNKNOWN_ERROR")); break; }; } else { + /* Give a warning when mount c:\ or the / */ +#if defined (WIN32) || defined(OS2) + if( (temp_line == "c:\\") || (temp_line == "C:\\")) WriteOut(MSG_Get("PROGRAM_MOUNT_WARNING_WIN")); +#else + if(temp_line == "/") WriteOut(MSG_Get("PROGRAM_MOUNT_WARNING_OTHER")); +#endif newdrive=new localDrive(temp_line.c_str(),sizes[0],bit8size,sizes[2],sizes[3],mediaid); } } else { @@ -840,7 +846,9 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED","Drive %c isn't mounted.\n"); MSG_Add("PROGRAM_MOUNT_UMOUNT_SUCCES","Drive %c has succesfully been removed.\n"); MSG_Add("PROGRAM_MOUNT_UMOUNT_NO_VIRTUAL","Virtual Drives can not be unMOUNTed.\n"); - + MSG_Add("PROGRAM_MOUNT_WARNING_WIN","\033[31;1mMounting c:\\ is NOT recommended. Please mount a (sub)directory next time.\033[0m\n"); + MSG_Add("PROGRAM_MOUNT_WARNING_OTHER","\033[31;1mMounting / is NOT recommended. Please mount a (sub)directory next time.\033[0m\n"); + MSG_Add("PROGRAM_MEM_CONVEN","%10d Kb free conventional memory\n"); MSG_Add("PROGRAM_MEM_EXTEND","%10d Kb free extended memory\n"); MSG_Add("PROGRAM_MEM_EXPAND","%10d Kb free expanded memory\n"); @@ -954,6 +962,7 @@ void DOS_SetupPrograms(void) { "\033[33;1mCTRL-F10\033[0m : Capture/Release the mouse.\n" "\033[33;1mCTRL-F11\033[0m : Slow down emulation (Decrease DOSBox Cycles).\n" "\033[33;1mCTRL-F12\033[0m : Speed up emulation (Increase DOSBox Cycles).\n" + "\033[33;1mALT-F12\033[0m : Unlock speed (turbo button).\n" ); MSG_Add("PROGRAM_BOOT_NOT_EXIST","Bootdisk file does not exist. Failing.\n"); MSG_Add("PROGRAM_BOOT_NOT_OPEN","Cannot open bootdisk file. Failing.\n"); From 86d386e5c78b2c0818b6baa37c518a551eea7889 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Feb 2006 17:07:27 +0000 Subject: [PATCH 2445/4131] some fixes for possible overflows Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2529 --- src/shell/shell_misc.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 568625a9..3f12edc3 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.41 2006-02-26 15:57:28 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.42 2006-02-28 17:07:27 qbix79 Exp $ */ #include #include @@ -342,11 +342,12 @@ bool DOS_Shell::Execute(char * name,char * args) { if(strlen(args)!= 0){ if(*args != ' '){ //put a space in front line[0]=' ';line[1]=0; - strcat(line,args); + strncat(line,args,CMD_MAXLINE-2); + line[CMD_MAXLINE-1]=0; } else { - strcpy(line,args); + safe_strncpy(line,args,CMD_MAXLINE); } }else{ line[0]=0; @@ -370,7 +371,7 @@ bool DOS_Shell::Execute(char * name,char * args) { /*only internal commands can be run this way and they never get in this handler */ if(extension == 0) { - char temp_name[256],* temp_fullname; + char temp_name[DOS_PATHLENGTH+4],* temp_fullname; //try to add .com, .exe and .bat extensions to filename strcpy(temp_name,fullname); @@ -478,7 +479,8 @@ static char * exe_ext=".EXE"; static char which_ret[DOS_PATHLENGTH+4]; char * DOS_Shell::Which(char * name) { - if(strlen(name) >= DOS_PATHLENGTH) return 0; + size_t name_len = strlen(name); + if(name_len >= DOS_PATHLENGTH) return 0; /* Parse through the Path to find the correct entry */ /* Check if name is already ok but just misses an extension */ @@ -517,13 +519,15 @@ char * DOS_Shell::Which(char * name) { /* get next entry */ while(*pathenv && (*pathenv !=';')) *path_write++=*pathenv++; - + + path[DOS_PATHLENGTH-1] = 0; /* check entry */ - if(Bitu len=strlen(path)){ - if(path[strlen(path)-1]!='\\') strcat(path,"\\"); - strcat(path,name); + if(size_t len=strlen(path)){ + if(path[len-1]!='\\') {strcat(path,"\\"); len++;} + //If name too long =>next - if(strlen(path) >= DOS_PATHLENGTH) continue; + if((name_len + len +1) >= DOS_PATHLENGTH) continue; + strcat(path,name); strcpy(which_ret,path); if (DOS_FileExists(which_ret)) return which_ret; From 665abeaca46e5ccd56cf3a44df7b4d90ac126da3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Feb 2006 19:41:27 +0000 Subject: [PATCH 2446/4131] Fix even more possible overflows Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2530 --- src/shell/shell_misc.cpp | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 3f12edc3..09a5c600 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.42 2006-02-28 17:07:27 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.43 2006-02-28 19:41:27 qbix79 Exp $ */ #include #include @@ -506,27 +506,36 @@ char * DOS_Shell::Which(char * name) { pathenv=strchr(pathenv,'='); if (!pathenv) return 0; pathenv++; - char * path_write=path; + Bitu i_path = 0; while (*pathenv) { /* remove ; and ;; at the beginning. (and from the second entry etc) */ while(*pathenv && (*pathenv ==';')) pathenv++; - /* Clear old path */ - for(Bitu dummy = 0;dummy < DOS_PATHLENGTH; dummy++) - path[dummy] = 0; //OVERKILL could be strlen(path). but run no risks - /* get next entry */ - while(*pathenv && (*pathenv !=';')) - *path_write++=*pathenv++; + i_path = 0; /* reset writer */ + while(*pathenv && (*pathenv !=';') && (i_path < DOS_PATHLENGTH) ) + path[i_path++] = *pathenv++; + + if(i_path == DOS_PATHLENGTH) { + /* If max size. move till next ; and terminate path */ + while(*pathenv != ';') + pathenv++; + path[DOS_PATHLENGTH - 1] = 0; + } else path[i_path] = 0; + - path[DOS_PATHLENGTH-1] = 0; /* check entry */ - if(size_t len=strlen(path)){ - if(path[len-1]!='\\') {strcat(path,"\\"); len++;} + if(size_t len = strlen(path)){ + if(len >= (DOS_PATHLENGTH - 2)) continue; + + if(path[len - 1] != '\\') { + strcat(path,"\\"); + len++; + } //If name too long =>next - if((name_len + len +1) >= DOS_PATHLENGTH) continue; + if((name_len + len + 1) >= DOS_PATHLENGTH) continue; strcat(path,name); strcpy(which_ret,path); @@ -541,8 +550,6 @@ char * DOS_Shell::Which(char * name) { strcat(which_ret,bat_ext); if (DOS_FileExists(which_ret)) return which_ret; } - path_write=path; /* reset it */ - } return 0; } From a86f6151290a949a03dac0b62eb1e5f080712782 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Feb 2006 20:11:49 +0000 Subject: [PATCH 2447/4131] mention cvs=auto Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2531 --- src/dosbox.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 947c1822..2178c35d 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.95 2006-02-14 09:53:24 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.96 2006-02-28 20:11:49 qbix79 Exp $ */ #include #include @@ -287,6 +287,8 @@ void DOSBOX_Init(void) { ".\n" "cycles -- Amount of instructions dosbox tries to emulate each millisecond.\n" " Setting this higher than your machine can handle is bad!\n" + " You can also let DOSBox guess the correct value by setting it to auto.\n" + " Please note that this guessing feature is still experimental.\n" "cycleup -- Amount of cycles to increase/decrease with keycombo.\n" "cycledown Setting it lower than 100 will be a percentage.\n" ); From 0a7ec74a344b284fe55edfa5296fd8957338bb78 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Feb 2006 21:14:48 +0000 Subject: [PATCH 2448/4131] ignore files Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2532 From 83237eff9142b9126a7cd8d2cdb4224f587eda1a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 1 Mar 2006 10:59:29 +0000 Subject: [PATCH 2449/4131] Don't change lower palette entries when changing the background/border color in text mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2533 --- src/ints/int10_pal.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 8026ef9e..62f43985 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -217,6 +217,11 @@ void INT10_SetBackgroundBorder(Bit8u val) { IO_Write(0x3d9,temp); else if (machine == MCH_VGA) { val = ((val << 1) & 0x10) | (val & 0x7); + /* Aways set the overscan color */ + INT10_SetSinglePaletteRegister( 0x11, val ); + /* Don't set any extra colors when in text mode */ + if (CurMode->mode <= 3) + return; INT10_SetSinglePaletteRegister( 0, val ); val = (temp & 0x10) | 2 | ((temp & 0x20) >> 5); INT10_SetSinglePaletteRegister( 1, val ); From 3a071e89b9d643024d828f2ac07bdc8e60430608 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 2 Mar 2006 14:12:49 +0000 Subject: [PATCH 2450/4131] A few fixes for broken input Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2534 --- src/misc/programs.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 3998a9d3..f58b042d 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.23 2006-02-09 11:47:57 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.24 2006-03-02 14:12:49 qbix79 Exp $ */ #include #include @@ -249,6 +249,10 @@ void CONFIG::Run(void) { return; } char* val = sec->GetPropValue(prop.c_str()); + if(!val) { + WriteOut(MSG_Get("PROGRAM_CONFIG_NO_PROPERTY"),prop.c_str(),temp_line.c_str()); + return; + } WriteOut("%s",val); first_shell->SetEnv("CONFIG",val); return; @@ -334,6 +338,7 @@ void PROGRAMS_Init(Section* sec) { MSG_Add("PROGRAM_CONFIG_FILE_ERROR","Can't open file %s\n"); MSG_Add("PROGRAM_CONFIG_USAGE","Config tool:\nUse -writeconf filename to write the current config.\nUse -writelang filename to write the current language strings.\n"); MSG_Add("PROGRAM_CONFIG_SECTION_ERROR","Section %s doesn't exist.\n"); - MSG_Add("PROGRAM_CONFIG_PROPERTY_ERROR","Property %s doesn't have a section.\n"); - MSG_Add("PROGRAM_CONFIG_GET_SYNTAX","Correct syntax: config -get \"section property\""); + MSG_Add("PROGRAM_CONFIG_PROPERTY_ERROR","No such section or property.\n"); + MSG_Add("PROGRAM_CONFIG_NO_PROPERTY","There is no property %s in section %s.\n"); + MSG_Add("PROGRAM_CONFIG_GET_SYNTAX","Correct syntax: config -get \"section property\".\n"); } From 78dbd4109e6c7029114c7e2003383260dd15d25e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 7 Mar 2006 12:06:11 +0000 Subject: [PATCH 2451/4131] Add Patch 1321309 (Backspace and overflow fixes to line input) from Avery Lee. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2535 --- src/dos/dos.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 4e3d03fb..26abd3f2 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.91 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.92 2006-03-07 12:06:11 qbix79 Exp $ */ #include #include @@ -126,8 +126,22 @@ static Bitu DOS_21Handler(void) { Bit8u free=mem_readb(data); Bit8u read=0;Bit8u c;Bit16u n=1; if (!free) break; - while (read= free) { // Keyboard buffer full + Bit8u bell = 7; + DOS_WriteFile(STDOUT, &bell, &n); + continue; + } DOS_WriteFile(STDOUT,&c,&n); mem_writeb(data+read+2,c); if (c==13) From ddc3811ead868870d692f7724465726826be0c3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 7 Mar 2006 21:08:32 +0000 Subject: [PATCH 2452/4131] move int3 default handler a bit (work around bug in Alien Incident) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2536 --- src/dos/dos_memory.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 23eccf76..723fd049 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -415,18 +415,16 @@ void DOS_SetupMemory(void) { /* Let dos claim a few bios interrupts. Makes DOSBox more compatible with * buggy games, which compare against the interrupt table. (probably a * broken linked list implementation) */ - // BioMenace (segment of int2<0x8000) callbackhandler.Allocate(&DOS_default_handler,"DOS default int"); - //Shadow president wants int 4 to point to this. - real_writeb(0x70,0,(Bit8u)0xFE); //GRP 4 - real_writeb(0x70,1,(Bit8u)0x38); //Extra Callback instruction - real_writew(0x70,2,callbackhandler.Get_callback()); //The immediate word - real_writeb(0x70,4,(Bit8u)0xCF); //An IRET Instruction - real_writed(0,0x01*4,0x700000); - real_writed(0,0x02*4,0x700000); //BioMenace - real_writed(0,0x03*4,0x700000); - real_writed(0,0x04*4,0x700000); //Shadow President -// real_writed(0,0x0f*4,0x700000); //Always a tricky one (soundblaster irq) + real_writeb(0x70,4,(Bit8u)0xFE); //GRP 4 + real_writeb(0x70,5,(Bit8u)0x38); //Extra Callback instruction + real_writew(0x70,6,callbackhandler.Get_callback()); //The immediate word + real_writeb(0x70,8,(Bit8u)0xCF); //An IRET Instruction + real_writed(0,0x01*4,0x700004); + real_writed(0,0x02*4,0x700004); //BioMenace (segment<0x8000) + real_writed(0,0x03*4,0x700004); //Alien Incident (offset!=0) + real_writed(0,0x04*4,0x700004); //Shadow President (lower byte of segment!=0) +// real_writed(0,0x0f*4,0x700004); //Always a tricky one (soundblaster irq) // Create a dummy device MCB with PSPSeg=0x0008 DOS_MCB mcb_devicedummy((Bit16u)DOS_MEM_START); From a606344cb9625cfa5edd37dd47c858f778daa4e7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 8 Mar 2006 15:57:23 +0000 Subject: [PATCH 2453/4131] typo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2537 --- src/dos/dos.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 26abd3f2..fa32a395 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.92 2006-03-07 12:06:11 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.93 2006-03-08 15:57:23 qbix79 Exp $ */ #include #include @@ -129,13 +129,14 @@ static Bitu DOS_21Handler(void) { for(;;) { DOS_ReadFile(STDIN,&c,&n); if (c == 8) { // Backspace - if (!read) //Nothing to backspace. - continue; - // STDOUT treats backspace as non-destructive. - DOS_WriteFile(STDOUT,&c,&n); - c = ' '; DOS_WriteFile(STDOUT,&c,&n); - c = 8; DOS_WriteFile(STDOUT,&c,&n); - --read; + if (read) { //Something to backspace. + // STDOUT treats backspace as non-destructive. + DOS_WriteFile(STDOUT,&c,&n); + c = ' '; DOS_WriteFile(STDOUT,&c,&n); + c = 8; DOS_WriteFile(STDOUT,&c,&n); + --read; + } + continue; } if (read >= free) { // Keyboard buffer full Bit8u bell = 7; From 763aef7778cf71a0dfced1ea6927c71d470ffe44 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 10 Mar 2006 09:38:24 +0000 Subject: [PATCH 2454/4131] add 0xff and 0xa0 to the allow table. Fixes DUPLITOP (French scrabble game). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2538 --- src/dos/dos_files.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 5dddad38..c007955d 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.71 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.72 2006-03-10 09:38:24 qbix79 Exp $ */ #include #include @@ -89,10 +89,11 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { case '\\': case '$': case '#': case '@': case '(': case ')': case '!': case '%': case '{': case '}': case '`': case '~': case '_': case '-': case '.': case '*': case '?': case '&': - case '\'': case '+': case '^': case 246: + case '\'': case '+': case '^': case 246: case 255: case 0xa0: upname[w++]=c; break; default: + LOG(LOG_FILES,LOG_NORMAL)("Makename encountered an illegal char %c hex:%X !",c,c); DOS_SetError(DOSERR_PATH_NOT_FOUND);return false; break; } From 2a9ea0299ff6bfbcff541466bb0e57fd35b7babc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 12 Mar 2006 20:31:49 +0000 Subject: [PATCH 2455/4131] limit VCPI support to JEMM games Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2539 --- src/ints/ems.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index f37e4987..45357393 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.46 2006-02-18 14:45:12 qbix79 Exp $ */ +/* $Id: ems.cpp,v 1.47 2006-03-12 20:31:49 c2woody Exp $ */ #include #include @@ -608,8 +608,13 @@ static Bitu INT67_Handler(void) { } else { switch (reg_al) { case 0x00: /* VCPI Installation Check */ - reg_ah=EMM_NO_ERROR; - reg_bx=0x100; + if (((reg_cx==0) && (reg_di=0x0012)) || (cpu.pmode && (reg_flags & FLAG_VM))) { + /* JEMM detected or already in v86 mode */ + reg_ah=EMM_NO_ERROR; + reg_bx=0x100; + } else { + reg_ah=EMM_FUNC_NOSUP; + } break; case 0x01: { /* VCPI Get Protected Mode Interface */ Bit16u ct; From 46e1cb9a37dfabe3706f77f6b293c7bd72b554dd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 12 Mar 2006 21:12:20 +0000 Subject: [PATCH 2456/4131] disable ems/xms/umb on booting Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2540 --- src/dos/dos_programs.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index cab4d4e9..c2f4f238 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.55 2006-02-28 15:13:00 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.56 2006-03-12 21:12:20 qbix79 Exp $ */ #include #include @@ -389,9 +389,21 @@ private: WriteOut(MSG_Get("PROGRAM_BOOT_PRINT_ERROR")); } + void disable_umb_ems_xms(void) { + Section* dos_sec = control->GetSection("dos"); + dos_sec->ExecuteDestroy(false); + char test[20]; + strcpy(test,"umb=false"); + dos_sec->HandleInputline(test); + strcpy(test,"xms=false"); + dos_sec->HandleInputline(test); + strcpy(test,"ems=false"); + dos_sec->HandleInputline(test); + dos_sec->ExecuteInit(false); + } public: - + void Run(void) { FILE *usefile; Bitu i; @@ -453,6 +465,7 @@ public: if ((bootarea.rawdata[0]==0x50) && (bootarea.rawdata[1]==0x43) && (bootarea.rawdata[2]==0x6a) && (bootarea.rawdata[3]==0x72)) { if (machine!=MCH_PCJR) WriteOut(MSG_Get("PROGRAM_BOOT_CART_WO_PCJR")); else { + disable_umb_ems_xms(); Bit8u rombuf[65536]; fseek(usefile,0x200L, SEEK_SET); fread(rombuf, 1, rombytesize-0x200, usefile); @@ -474,6 +487,7 @@ public: reg_ip = mem_readw(0x60); } } else { + disable_umb_ems_xms(); WriteOut(MSG_Get("PROGRAM_BOOT_BOOT"), drive); for(i=0;i<512;i++) real_writeb(0, 0x7c00 + i, bootarea.rawdata[i]); From 3ceb01754ec2776cd047b5c962c8cab854605675 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 12 Mar 2006 21:14:45 +0000 Subject: [PATCH 2457/4131] Some small changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2541 --- src/hardware/pic.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index ac8fee80..bc1a67a7 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.33 2006-02-09 11:47:49 qbix79 Exp $ */ +/* $Id: pic.cpp,v 1.34 2006-03-12 21:14:45 qbix79 Exp $ */ #include @@ -320,6 +320,7 @@ void PIC_runIRQs(void) { } void PIC_SetIRQMask(Bitu irq, bool masked) { + if(irqs[irq].masked == masked) return; /* Do nothing if mask doesn't change */ bool old_irq2_mask = irqs[2].masked; irqs[irq].masked=masked; if(irq < 8) { @@ -453,12 +454,18 @@ bool PIC_RunQueue(void) { //Irq 9-2 calling code static Bitu INT71_Handler() { - CALLBACK_RunRealInt(0xa); IO_Write(0xa0,0x61); + CALLBACK_RunRealInt(0xa); + return CBRET_NONE; +} + +static Bitu INT0A_Handler() { IO_Write(0x20,0x62); return CBRET_NONE; } + + /* The TIMER Part */ struct TickerBlock { TIMER_TickHandler handler; @@ -515,7 +522,7 @@ class PIC:public Module_base{ private: IO_ReadHandleObject ReadHandler[4]; IO_WriteHandleObject WriteHandler[4]; - CALLBACK_HandlerObject callback; + CALLBACK_HandlerObject callback[2]; public: PIC(Section* configuration):Module_base(configuration){ /* Setup pic0 and pic1 with initial values like DOS has normally */ @@ -570,8 +577,10 @@ public: pic.next_entry=0; /* Irq 9 and 2 thingie * Should be done by bios but then it overwrites the mpu handler */ - callback.Install(&INT71_Handler,CB_IRET,"irq 9 bios"); - callback.Set_RealVec(0x71); + callback[0].Install(&INT71_Handler,CB_IRET,"irq 9 bios"); + callback[0].Set_RealVec(0x71); + callback[1].Install(&INT0A_Handler,CB_IRET,"irq 2 bios"); + callback[1].Set_RealVec(0xA); } ~PIC(){ } From c4313730b637c8bb75d004657da5d441c9f80131 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 12 Mar 2006 21:16:23 +0000 Subject: [PATCH 2458/4131] acknowlegde second pic before running int a Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2542 --- src/hardware/mpu401.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 3c4c7e13..295e2531 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.16 2006-02-09 11:47:49 qbix79 Exp $ */ +/* $Id: mpu401.cpp,v 1.17 2006-03-12 21:16:23 qbix79 Exp $ */ #include #include "dosbox.h" @@ -551,9 +551,9 @@ static Bitu MPU401_INT71_Handler() { mpu.queue_used=1; mpu.state.reset=0; } - CALLBACK_RunRealInt(0xa); IO_Write(0xa0,0x61); - IO_Write(0x20,0x62); + CALLBACK_RunRealInt(0xa); +// IO_Write(0x20,0x62); //0xA default handler does this. if (signr) if (mpu.queue_used==1) ClrQueue(); return CBRET_NONE; From 59721b003c456f012205a69d2be5727dca492647 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 12 Mar 2006 21:26:22 +0000 Subject: [PATCH 2459/4131] small bugfix Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2543 --- src/misc/setup.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index f8351253..eda8d57b 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.33 2006-02-09 11:47:57 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.34 2006-03-12 21:26:22 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -148,7 +148,8 @@ int Section_prop::Get_hex(const char* _propname){ void Section_prop::HandleInputline(char *gegevens){ char * rest=strrchr(gegevens,'='); - *rest=0; + if(!rest) return; + *rest = 0; gegevens=trim(gegevens); for(it tel=properties.begin();tel!=properties.end();tel++){ if(!strcasecmp((*tel)->propname.c_str(),gegevens)){ From 2ff5e7f0fba89b58446273caeb8bbd7ea0e36e26 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 13 Mar 2006 19:58:09 +0000 Subject: [PATCH 2460/4131] unmask irq2 on file reads Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2544 --- src/dos/drive_local.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 6a526a09..6f9e38e9 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.63 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.64 2006-03-13 19:58:09 qbix79 Exp $ */ #include #include @@ -29,7 +29,7 @@ #include "drives.h" #include "support.h" #include "cross.h" - +#include "inout.h" class localFile : public DOS_File { public: @@ -400,6 +400,11 @@ bool localFile::Read(Bit8u * data,Bit16u * size) { if (last_action==WRITE) fseek(fhandle,ftell(fhandle),SEEK_SET); last_action=READ; *size=fread(data,1,*size,fhandle); + /* Fake harddrive motion. Inspector Gadget with soundblaster compatible */ + /* Same for Igor */ + /* hardrive motion => unmask irq 2. Only do it when it's masked as unmasking is realitively heavy to emulate */ + Bit8u mask = IO_Read(0x21); + if(mask & 0x4 ) IO_Write(0x21,mask&0xfb); return true; }; From dc3f72049f469cab9e682d5e32764a560b6f7e42 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 13 Mar 2006 20:00:41 +0000 Subject: [PATCH 2461/4131] rename a few configuration items. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2545 --- src/dosbox.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 2178c35d..4fbf961c 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.96 2006-02-28 20:11:49 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.97 2006-03-13 20:00:41 qbix79 Exp $ */ #include #include @@ -316,14 +316,12 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("midi",&MIDI_Init,true);//done secprop->AddInitFunction(&MPU401_Init,true);//done - secprop->Add_bool("mpu401",true); - secprop->Add_bool("intelligent",true); + secprop->Add_string("mpu401","intelligent"); secprop->Add_string("device","default"); secprop->Add_string("config",""); MSG_Add("MIDI_CONFIGFILE_HELP", - "mpu401 -- Enable MPU-401 Emulation.\n" - "intelligent -- Operate in Intelligent mode.\n" + "mpu401 -- Type of MPU-401 to emulate: none, uart or intelligent.\n" "device -- Device that will receive the MIDI data from MPU-401.\n" " This can be default,alsa,oss,win32,coreaudio,none.\n" "config -- Special configuration options for the device. In Windows put\n" @@ -335,8 +333,8 @@ void DOSBOX_Init(void) { #endif secprop=control->AddSection_prop("sblaster",&SBLASTER_Init,true);//done - secprop->Add_string("type","sb16"); - secprop->Add_hex("base",0x220); + secprop->Add_string("sbtype","sb16"); + secprop->Add_hex("sbbase",0x220); secprop->Add_int("irq",7); secprop->Add_int("dma",1); secprop->Add_int("hdma",5); @@ -345,8 +343,8 @@ void DOSBOX_Init(void) { secprop->Add_int("oplrate",22050); MSG_Add("SBLASTER_CONFIGFILE_HELP", - "type -- Type of sblaster to emulate:none,sb1,sb2,sbpro1,sbpro2,sb16.\n" - "base,irq,dma,hdma -- The IO/IRQ/DMA/High DMA address of the soundblaster.\n" + "sbtype -- Type of sblaster to emulate:none,sb1,sb2,sbpro1,sbpro2,sb16.\n" + "sbbase,irq,dma,hdma -- The IO/IRQ/DMA/High DMA address of the soundblaster.\n" "mixer -- Allow the soundblaster mixer to modify the dosbox mixer.\n" "oplmode -- Type of OPL emulation: auto,cms,opl2,dualopl2,opl3.\n" " On auto the mode is determined by sblaster type.\n" @@ -355,8 +353,8 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("gus",&GUS_Init,true); //done secprop->Add_bool("gus",true); - secprop->Add_int("rate",22050); - secprop->Add_hex("base",0x240); + secprop->Add_int("gusrate",22050); + secprop->Add_hex("gusbase",0x240); secprop->Add_int("irq1",5); secprop->Add_int("irq2",5); secprop->Add_int("dma1",3); @@ -365,9 +363,9 @@ void DOSBOX_Init(void) { MSG_Add("GUS_CONFIGFILE_HELP", "gus -- Enable the Gravis Ultrasound emulation.\n" - "base,irq1,irq2,dma1,dma2 -- The IO/IRQ/DMA addresses of the \n" + "gusbase,irq1,irq2,dma1,dma2 -- The IO/IRQ/DMA addresses of the \n" " Gravis Ultrasound. (Same IRQ's and DMA's are OK.)\n" - "rate -- Sample rate of Ultrasound emulation.\n" + "gusrate -- Sample rate of Ultrasound emulation.\n" "ultradir -- Path to Ultrasound directory. In this directory\n" " there should be a MIDI directory that contains\n" " the patch files for GUS playback. Patch sets used\n" From 0ce4453cdf018971de3943c8f12ef8763c4ea5ad Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 13 Mar 2006 20:01:55 +0000 Subject: [PATCH 2462/4131] some configuration items renames. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2546 --- src/hardware/adlib.cpp | 2 +- src/hardware/gameblaster.cpp | 2 +- src/hardware/gus.cpp | 4 ++-- src/hardware/sblaster.cpp | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 403b128e..9cdba658 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -324,7 +324,7 @@ public: OPL(Section* configuration):Module_base(configuration) { Section_prop * section=static_cast(configuration); - Bitu base = section->Get_hex("base"); + Bitu base = section->Get_hex("sbbase"); Bitu rate = section->Get_int("oplrate"); if (OPL2::YM3812Init(2,OPL2_INTERNAL_FREQ,rate)) { E_Exit("Can't create OPL2 Emulator"); diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index db647db6..e4169f4d 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -430,7 +430,7 @@ public: Section_prop * section = static_cast(configuration); Bitu sample_rate_temp = section->Get_int("oplrate"); sample_rate = static_cast(sample_rate_temp); - Bitu base = section->Get_hex("base"); + Bitu base = section->Get_hex("sbbase"); WriteHandler.Install(base,write_cms,IO_MB,4); /* Register the Mixer CallBack */ diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 9cd3cbba..6395325b 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -806,9 +806,9 @@ public: memset(&myGUS,0,sizeof(myGUS)); memset(GUSRam,0,1024*1024); - myGUS.rate=section->Get_int("rate"); + myGUS.rate=section->Get_int("gusrate"); - myGUS.portbase = section->Get_hex("base") - 0x200; + myGUS.portbase = section->Get_hex("gusbase") - 0x200; myGUS.dma1 = section->Get_int("dma1"); myGUS.dma2 = section->Get_int("dma2"); myGUS.irq1 = section->Get_int("irq1"); diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index f05bfdeb..d75278dd 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.52 2006-02-09 11:47:49 qbix79 Exp $ */ +/* $Id: sblaster.cpp,v 1.53 2006-03-13 20:01:55 qbix79 Exp $ */ #include #include @@ -1145,7 +1145,7 @@ private: /* Support Functions */ void Find_Type_And_Opl(Section_prop* config,SB_TYPES& type, OPL_Mode& opl_mode){ - const char * sbtype=config->Get_string("type"); + const char * sbtype=config->Get_string("sbtype"); if (!strcasecmp(sbtype,"sb1")) type=SBT_1; else if (!strcasecmp(sbtype,"sb2")) type=SBT_2; else if (!strcasecmp(sbtype,"sbpro1")) type=SBT_PRO1; @@ -1182,7 +1182,7 @@ public: SBLASTER(Section* configuration):Module_base(configuration) { Bitu i; Section_prop * section=static_cast(configuration); - sb.hw.base=section->Get_hex("base"); + sb.hw.base=section->Get_hex("sbbase"); sb.hw.irq=section->Get_int("irq"); sb.hw.dma8=section->Get_int("dma"); sb.hw.dma16=section->Get_int("hdma"); From a98616a982108be48eaab66dd594c151fe3baf2b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 18 Mar 2006 12:28:30 +0000 Subject: [PATCH 2463/4131] merged mpu and intelligent into one option Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2547 --- src/hardware/mpu401.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 295e2531..271b3562 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.17 2006-03-12 21:16:23 qbix79 Exp $ */ +/* $Id: mpu401.cpp,v 1.18 2006-03-18 12:28:30 qbix79 Exp $ */ #include #include "dosbox.h" @@ -25,7 +25,7 @@ #include "setup.h" #include "cpu.h" #include "callback.h" - +#include "support.h" void MIDI_RawOutByte(Bit8u data); bool MIDI_Available(void); @@ -599,7 +599,10 @@ public: MPU401(Section* configuration):Module_base(configuration){ installed = false; Section_prop * section=static_cast(configuration); - if(!section->Get_bool("mpu401")) return; + const char* s_mpu = section->Get_string("mpu401"); + if(strcasecmp(s_mpu,"none") == 0) return; + if(strcasecmp(s_mpu,"off") == 0) return; + if(strcasecmp(s_mpu,"false") == 0) return; if (!MIDI_Available()) return; /*Enabled and there is a Midi */ installed = true; @@ -616,17 +619,19 @@ public: mpu.queue_used=0; mpu.queue_pos=0; mpu.mode=M_UART; - - if (!(mpu.intelligent=section->Get_bool("intelligent"))) return; + mpu.irq=9; /* Princess Maker 2 wants it on irq 9 */ + + mpu.intelligent = true; //Default is on + if(strcasecmp(s_mpu,"uart") == 0) mpu.intelligent = false; + if (!mpu.intelligent) return; /*Set IRQ and unmask it(for timequest/princess maker 2) */ - mpu.irq=9; PIC_SetIRQMask(mpu.irq,false); MPU401_Reset(); } ~MPU401(){ if(!installed) return; Section_prop * section=static_cast(m_configuration); - if(!section->Get_bool("intelligent")) return; + if(strcasecmp(section->Get_string("mpu401"),"intelligent") return; PIC_SetIRQMask(mpu.irq,true); } }; From 977a33d64bd69622601f8c2a523e6995d8b5ca4b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 18 Mar 2006 12:29:14 +0000 Subject: [PATCH 2464/4131] typo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2548 --- src/hardware/mpu401.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 271b3562..9f4c428d 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.18 2006-03-18 12:28:30 qbix79 Exp $ */ +/* $Id: mpu401.cpp,v 1.19 2006-03-18 12:29:14 qbix79 Exp $ */ #include #include "dosbox.h" @@ -631,7 +631,7 @@ public: ~MPU401(){ if(!installed) return; Section_prop * section=static_cast(m_configuration); - if(strcasecmp(section->Get_string("mpu401"),"intelligent") return; + if(strcasecmp(section->Get_string("mpu401"),"intelligent")) return; PIC_SetIRQMask(mpu.irq,true); } }; From 1387fa3d55a3a2c299ee2347a96706635d2e0c66 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 19 Mar 2006 10:24:59 +0000 Subject: [PATCH 2465/4131] Fix hanging installers of darklands and master of orion. It even fixes It came from the desert. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2549 --- src/hardware/mpu401.cpp | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 9f4c428d..f9d1c0d2 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.19 2006-03-18 12:29:14 qbix79 Exp $ */ +/* $Id: mpu401.cpp,v 1.20 2006-03-19 10:24:59 qbix79 Exp $ */ #include #include "dosbox.h" @@ -24,7 +24,6 @@ #include "pic.h" #include "setup.h" #include "cpu.h" -#include "callback.h" #include "support.h" void MIDI_RawOutByte(Bit8u data); @@ -260,6 +259,8 @@ static Bitu MPU401_ReadData(Bitu port,Bitu iolen) { } if (!mpu.intelligent) return ret; + if (mpu.queue_used == 0) PIC_DeActivateIRQ(mpu.irq); + if (ret>=0xf0 && ret<=0xf7) { /* MIDI data request */ mpu.state.channel=ret&7; mpu.state.data_onoff=0; @@ -542,23 +543,6 @@ static void MPU401_EOIHandler(void) { } while ((i++)<16); } -static Bitu MPU401_INT71_Handler() { - bool signr=0; - if (mpu.state.reset) if (!mpu.queue_used) { // hack for "It came to desert" - signr=1; - mpu.queue_pos=0; - mpu.queue[0]=0xfe; - mpu.queue_used=1; - mpu.state.reset=0; - } - IO_Write(0xa0,0x61); - CALLBACK_RunRealInt(0xa); -// IO_Write(0x20,0x62); //0xA default handler does this. - - if (signr) if (mpu.queue_used==1) ClrQueue(); - return CBRET_NONE; -} - static void MPU401_Reset(void) { PIC_DeActivateIRQ(mpu.irq); mpu.mode=(mpu.intelligent ? M_INTELLIGENT : M_UART); @@ -593,7 +577,6 @@ class MPU401:public Module_base{ private: IO_ReadHandleObject ReadHandler[2]; IO_WriteHandleObject WriteHandler[2]; - CALLBACK_HandlerObject callbackhandler; bool installed; /*as it can fail to install by 2 ways (config and no midi)*/ public: MPU401(Section* configuration):Module_base(configuration){ @@ -607,10 +590,6 @@ public: /*Enabled and there is a Midi */ installed = true; - /* Install a new irq 9 handler that is more suited for the mpu401 */ - callbackhandler.Install(&MPU401_INT71_Handler,CB_IRET,"irq 9 mpu"); - callbackhandler.Set_RealVec(0x71); - WriteHandler[0].Install(0x330,&MPU401_WriteData,IO_MB); WriteHandler[1].Install(0x331,&MPU401_WriteCommand,IO_MB); ReadHandler[0].Install(0x330,&MPU401_ReadData,IO_MB); From 9800b84d45e168d638a3e5aa1c02077cbcc45d6b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 19 Mar 2006 10:48:50 +0000 Subject: [PATCH 2466/4131] Some configure changes for OS2 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2550 --- configure.in | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index e8daf184..98f4be75 100644 --- a/configure.in +++ b/configure.in @@ -19,6 +19,14 @@ AC_PROG_CXX AC_PROG_INSTALL AC_PROG_RANLIB +dnl Some needed libaries for OS2 +dnl perharps join this with the other host 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 SDL_VERSION=1.2.0 AM_PATH_SDL($SDL_VERSION, @@ -204,7 +212,21 @@ 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([ + #include + int main(int argc,char * argv[]) { + return 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) @@ -268,7 +290,7 @@ 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 only).]) + AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32 and OS/2 only).]) ;; *-*-darwin*) dnl We have a problem here: both MacOS X and Darwin report @@ -281,6 +303,10 @@ case "$target" in *-*-linux-gnu*) AC_DEFINE(LINUX, 1, [Compiling on GNU/Linux]) ;; + *-*-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 and OS/2 only).]) + ;; esac dnl Some stuff for the icon. From dba2dbcbd3966240479a1b9d50b43de2fe1ca51f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 19 Mar 2006 11:20:20 +0000 Subject: [PATCH 2467/4131] change log_msg to log. Improves behaviour in release version when games use the undefined port. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2551 --- src/hardware/dma.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 36dcdd1e..02a23378 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -235,7 +235,7 @@ Bitu DmaController::ReadControllerReg(Bitu reg,Bitu len) { } return ret; default: - LOG_MSG("Trying to read undefined DMA port %x",reg); + LOG(LOG_DMA,LOG_NORMAL)("Trying to read undefined DMA port %x",reg); break; } return 0xffffffff; From 6a48704051a686512916df321829db7791382291 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 24 Mar 2006 17:11:35 +0000 Subject: [PATCH 2468/4131] Don't use listensocket if portbind failed. Fixes crash when port can't be bound to. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2552 --- src/hardware/serialport/softmodem.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index c83c02cb..423ce994 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.cpp,v 1.4 2006-02-26 13:48:06 qbix79 Exp $ */ +/* $Id: softmodem.cpp,v 1.5 2006-03-24 17:11:35 qbix79 Exp $ */ #include "dosbox.h" @@ -256,9 +256,11 @@ void CSerialModem::EnterIdleState(void){ SDLNet_TCP_Close(incomingsocket); } // get rid of everything - while(incomingsocket=SDLNet_TCP_Accept(listensocket)) { - SDLNet_TCP_DelSocket(socketset,incomingsocket); - SDLNet_TCP_Close(incomingsocket); + if(listensocket) { + while(incomingsocket=SDLNet_TCP_Accept(listensocket)) { + SDLNet_TCP_DelSocket(socketset,incomingsocket); + SDLNet_TCP_Close(incomingsocket); + } } incomingsocket=0; From 0904221dfa2c8ba47a712d1fc96a3ee3ae3f72cd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 Mar 2006 11:11:56 +0000 Subject: [PATCH 2469/4131] Fix bineary memory dumps. (Ognjen Milic) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2553 --- src/debug/debug.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 9c781bf4..3c4aa719 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.75 2006-02-12 23:23:52 harekiet Exp $ */ +/* $Id: debug.cpp,v 1.76 2006-03-26 11:11:56 qbix79 Exp $ */ #include #include @@ -2112,14 +2112,15 @@ static void SaveMemory(Bitu seg, Bitu ofs1, Bit32u num) }; static void SaveMemoryBin(Bitu seg, Bitu ofs1, Bit32u num) { - FILE* f = fopen("MEMDUMP.BIN","wt"); + FILE* f = fopen("MEMDUMP.BIN","wb"); if (!f) { DEBUG_ShowMsg("DEBUG: Memory binary dump failed.\n"); return; } - for(Bitu x=0; x Date: Sun, 26 Mar 2006 11:54:44 +0000 Subject: [PATCH 2470/4131] Fix some log message Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2554 --- src/dos/dos_mscdex.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index f47442b8..506872bc 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.36 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.37 2006-03-26 11:54:44 qbix79 Exp $ */ #include #include @@ -970,7 +970,7 @@ static bool MSCDEX_Handler(void) { if (reg_ah!=0x15) return false; PhysPt data = PhysMake(SegValue(es),reg_bx); - MSCDEX_LOG("MSCDEX: INT 2F %04X BX= %04X CX=%04X",reg_ax,reg_bx,reg_bx); + MSCDEX_LOG("MSCDEX: INT 2F %04X BX= %04X CX=%04X",reg_ax,reg_bx,reg_cx); switch (reg_ax) { case 0x1500: /* Install check */ From 49529ce99475349c19b0c48fd617ee6c306567aa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Mar 2006 12:34:04 +0000 Subject: [PATCH 2471/4131] Fix memory problem of Might and Magic III. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2555 --- src/dos/dos_memory.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 723fd049..5a8b737b 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -52,7 +52,7 @@ void DOS_FreeProcessMemory(Bit16u pspseg) { if (mcb.GetType()==0x5a) { /* check if currently last block reaches up to the PCJr graphics memory */ if ((machine==MCH_PCJR) && (mcb_segment+mcb.GetSize()==0x17fe) && - (real_readb(0x17ff,0)==0x4d) && (real_readw(0x17ff,1)==8)) { + (real_readb(0x17ff,0)==0x4d) && (real_readw(0x17ff,1)==8)) { /* re-enable the memory past segment 0x2000 */ mcb.SetType(0x4d); } else break; @@ -184,7 +184,10 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { if (found_seg_size==*blocks) { /* use the whole block */ mcb.SetPSPSeg(dos.psp()); - *segment=found_seg+1; + //Not consistent with line 124. But how many application will use this information ? + mcb.SetFileName(psp_name); + *segment = found_seg+1; + return true; } *segment = found_seg+1+found_seg_size - *blocks; mcb_next.SetPt((Bit16u)(*segment-1)); From f5e4334ff8903150d3f1d7937bc0ea23382d91d6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Mar 2006 19:18:00 +0000 Subject: [PATCH 2472/4131] Fix compilation when there is no zlib Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2556 --- src/Makefile.am | 3 +-- src/hardware/hardware.cpp | 4 ++-- src/libs/zmbv/Makefile.am | 5 +---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 2ef2a360..bccc59a1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,8 +6,7 @@ bin_PROGRAMS = dosbox dosbox_SOURCES = dosbox.cpp dosbox_LDADD = cpu/libcpu.a debug/libdebug.a dos/libdos.a fpu/libfpu.a hardware/libhardware.a gui/libgui.a \ - ints/libints.a misc/libmisc.a shell/libshell.a hardware/serialport/libserial.a \ - libs/zmbv/libzmbv.a + ints/libints.a misc/libmisc.a shell/libshell.a hardware/serialport/libserial.a if HAVE_WINDRES dosbox_LDADD += dosbox_ico.o diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index b59dd1fc..104c0fde 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: hardware.cpp,v 1.14 2006-02-14 12:46:43 qbix79 Exp $ */ +/* $Id: hardware.cpp,v 1.15 2006-03-27 19:18:00 qbix79 Exp $ */ #include #include @@ -33,7 +33,7 @@ #if (C_SSHOT) #include -#include "../libs/zmbv/zmbv.h" +#include "../libs/zmbv/zmbv.cpp" #endif static char * capturedir; diff --git a/src/libs/zmbv/Makefile.am b/src/libs/zmbv/Makefile.am index 6f6f5e31..311db44b 100644 --- a/src/libs/zmbv/Makefile.am +++ b/src/libs/zmbv/Makefile.am @@ -1,4 +1 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include - -noinst_LIBRARIES = libzmbv.a -libzmbv_a_SOURCES = zmbv.cpp zmbv.h +EXTRA_DIST = zmbv.cpp zmbv.h From 2b448f8d3d038e8bdec92cdd7e5739d9d0ca096e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 27 Mar 2006 19:31:54 +0000 Subject: [PATCH 2473/4131] respect maximal page in INT10_WriteChar when in graphics mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2557 --- src/ints/int10_char.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 011c02e5..8dda0539 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.46 2006-02-24 20:42:15 c2woody Exp $ */ +/* $Id: int10_char.cpp,v 1.47 2006-03-27 19:31:54 c2woody Exp $ */ /* Character displaying moving functions */ @@ -516,6 +516,18 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt } void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) { + if (CurMode->type!=M_TEXT) { + switch (machine) { + case MCH_VGA: + page%=CurMode->ptotal; + break; + case MCH_CGA: + case MCH_PCJR: + page=0; + break; + } + } + Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); BIOS_NCOLS;BIOS_NROWS; From 3d06ae7bd93701e27485b65e9259ba4d1a9b7ece Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Mar 2006 19:40:25 +0000 Subject: [PATCH 2474/4131] Remove fullfixed. enable usescancodes by default Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2558 --- src/gui/sdlmain.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 404c33bd..29b9124b 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.109 2006-02-27 21:00:27 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.110 2006-03-27 19:40:25 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -964,21 +964,23 @@ static void GUI_StartUp(Section * sec) { sdl.mouse.locked=false; mouselocked=false; //Global for mapper sdl.mouse.requestlock=false; - sdl.desktop.full.fixed=section->Get_bool("fullfixed"); + sdl.desktop.full.fixed=false; const char* fullresolution=section->Get_string("fullresolution"); if(fullresolution && *fullresolution) { char res[100]; strncpy( res, fullresolution, sizeof( res )); fullresolution = lowcase (res);//so x and X are allowed - - char* height = const_cast(strchr(fullresolution,'x')); - if(height && * height) { - *height = 0; - sdl.desktop.full.height = atoi(height+1); - sdl.desktop.full.width = atoi(res); - } else { - sdl.desktop.full.width = 0; - sdl.desktop.full.height = 0; + if(strcasecmp(fullresolution,"original")) { + sdl.desktop.full.fixed = true; + char* height = const_cast(strchr(fullresolution,'x')); + if(height && * height) { + *height = 0; + sdl.desktop.full.height = atoi(height+1); + sdl.desktop.full.width = atoi(res); + } else { + sdl.desktop.full.width = 0; + sdl.desktop.full.height = 0; + } } } else { sdl.desktop.full.width = 0; @@ -1286,8 +1288,7 @@ int main(int argc, char* argv[]) { sdl_sec->AddInitFunction(&MAPPER_StartUp); sdl_sec->Add_bool("fullscreen",false); sdl_sec->Add_bool("fulldouble",false); - sdl_sec->Add_bool("fullfixed",false); - sdl_sec->Add_string("fullresolution","1024x768"); + sdl_sec->Add_string("fullresolution","original"); sdl_sec->Add_string("windowresolution","0x0"); sdl_sec->Add_string("output","surface"); sdl_sec->Add_bool("autolock",true); @@ -1295,13 +1296,13 @@ int main(int argc, char* argv[]) { sdl_sec->Add_bool("waitonerror",true); sdl_sec->Add_string("priority","higher,normal"); sdl_sec->Add_string("mapperfile","mapper.txt"); - sdl_sec->Add_bool("usescancodes",false); + sdl_sec->Add_bool("usescancodes",true); MSG_Add("SDL_CONFIGFILE_HELP", "fullscreen -- Start dosbox directly in fullscreen.\n" "fulldouble -- Use double buffering in fullscreen.\n" - "fullfixed -- Don't resize the screen when in fullscreen.\n" - "fullresolution -- What resolution to use for fullscreen, use together with fullfixed.\n" + "fullresolution -- What resolution to use for fullscreen: original or fixed size (e.g. 1024x768).\n" + "windowresolution -- Scale the window to this size IF the output device supports hardware scaling.\n" "output -- What to use for output: surface,overlay" #if C_OPENGL ",opengl,openglnb" @@ -1310,7 +1311,6 @@ int main(int argc, char* argv[]) { ",ddraw" #endif ".\n" - "windowresolution -- Scale the window to this size IF the output device supports hardware scaling.\n" "autolock -- Mouse will automatically lock, if you click on the screen.\n" "sensitiviy -- Mouse sensitivity.\n" "waitonerror -- Wait before closing the console if dosbox has an error.\n" From cc60e080e0b1f4833583891cf760f92b6ffdcd5b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Mar 2006 19:41:55 +0000 Subject: [PATCH 2475/4131] update some comments. Update mixer to be more oldstyle Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2559 --- src/dosbox.cpp | 6 ++- src/hardware/mixer.cpp | 102 +++++++++++++++++++++++++++++++---------- 2 files changed, 82 insertions(+), 26 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 4fbf961c..bb60b66e 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.97 2006-03-13 20:00:41 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.98 2006-03-27 19:41:55 qbix79 Exp $ */ #include #include @@ -115,7 +115,7 @@ static Bit32u ticksLast; static Bit32u ticksAdded; static Bit32s ticksDone; static Bit32u ticksScheduled; -static bool ticksLocked; +bool ticksLocked; static Bitu Normal_Loop(void) { Bits ret; @@ -348,6 +348,7 @@ void DOSBOX_Init(void) { "mixer -- Allow the soundblaster mixer to modify the dosbox mixer.\n" "oplmode -- Type of OPL emulation: auto,cms,opl2,dualopl2,opl3.\n" " On auto the mode is determined by sblaster type.\n" + " All OPL modes are 'Adlib', except for CMS.\n" "oplrate -- Sample rate of OPL music emulation.\n" ); @@ -417,6 +418,7 @@ void DOSBOX_Init(void) { " stopbits, parity (all optional).\n" " for directserial: realport (required).\n" " for modem: listenport (optional).\n" + " Example: serial1=modem listenport:5000\n" ); /* All the DOS Related stuff, which will eventually start up in the shell */ diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 6c286a81..353af4c3 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.38 2006-02-11 09:37:16 harekiet Exp $ */ +/* $Id: mixer.cpp,v 1.39 2006-03-27 19:41:55 qbix79 Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -271,6 +271,13 @@ void MixerChannel::FillUp(void) { SDL_UnlockAudio(); } +extern bool ticksLocked; +static inline bool Mixer_irq_important(void) { + /* In some states correct timing of the irqs is more important then + * non stuttering audo */ + return (ticksLocked || (CaptureState & (CAPTURE_WAVE|CAPTURE_VIDEO))); +} + /* Mix a certain amount of new samples */ static void MIXER_MixData(Bitu needed) { MixerChannel * chan=mixer.channels; @@ -293,7 +300,10 @@ static void MIXER_MixData(Bitu needed) { } CAPTURE_AddWave( mixer.freq, added, (Bit16s*)convert ); } - mixer.done=needed; + //Reset the the tick_add for constant speed + if( Mixer_irq_important() ) + mixer.tick_add = ((mixer.freq) << MIXER_SHIFT)/1000; + mixer.done = needed; } static void MIXER_Mix(void) { @@ -334,55 +344,99 @@ static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { /* Enough room in the buffer ? */ if (mixer.done < need) { // LOG_MSG("Full underrun need %d, have %d, min %d", need, mixer.done, mixer.min_needed); + if((need - mixer.done) > (need >>7) ) //Max 1 procent stretch. + return; reduce = mixer.done; index_add = (reduce << MIXER_SHIFT) / need; + mixer.tick_add = ((mixer.freq+mixer.min_needed) << MIXER_SHIFT)/1000; } else if (mixer.done < mixer.max_needed) { Bitu left = mixer.done - need; if (left < mixer.min_needed) { - left = (mixer.min_needed - left); - left = 1 + (2*left) / mixer.min_needed; -// left = 1; -// left = 1 + (left / 128); + if( !Mixer_irq_important() ) { + Bitu needed = mixer.needed - need; + Bitu diff = (mixer.min_needed>needed?mixer.min_needed:needed) - left; + mixer.tick_add = ((mixer.freq+(diff*3)) << MIXER_SHIFT)/1000; + left = 0; //No stretching as we compensate with the tick_add value + } else { + left = (mixer.min_needed - left); + left = 1 + (2*left) / mixer.min_needed; //left=1,2,3 + } // LOG_MSG("needed underrun need %d, have %d, min %d, left %d", need, mixer.done, mixer.min_needed, left); reduce = need - left; index_add = (reduce << MIXER_SHIFT) / need; } else { reduce = need; index_add = (1 << MIXER_SHIFT); +// LOG_MSG("regular run need %d, have %d, min %d, left %d", need, mixer.done, mixer.min_needed, left); + + /* Mixer tick value being updated: + * 3 cases: + * 1) A lot too high. >division by 5. but maxed by 2* min to prevent too fast drops. + * 2) A little too high > division by 8 + * 3) A little to nothing above the min_needed buffer > go to default value + */ + Bitu diff = left - mixer.min_needed; + if(diff > (mixer.min_needed<<1)) diff = mixer.min_needed<<1; + if(diff > (mixer.min_needed>>1)) + mixer.tick_add = ((mixer.freq-(diff/5)) << MIXER_SHIFT)/1000; + else if (diff > (mixer.min_needed>>4)) + mixer.tick_add = ((mixer.freq-(diff>>3)) << MIXER_SHIFT)/1000; + else + mixer.tick_add = (mixer.freq<< MIXER_SHIFT)/1000; } } else { /* There is way too much data in the buffer */ +// LOG_MSG("overflow run need %d, have %d, min %d", need, mixer.done, mixer.min_needed); if (mixer.done > MIXER_BUFSIZE) - index_add = MIXER_BUFSIZE - mixer.min_needed; + index_add = MIXER_BUFSIZE - 2*mixer.min_needed; else - index_add = mixer.done - mixer.min_needed; + index_add = mixer.done - 2*mixer.min_needed; index_add = (index_add << MIXER_SHIFT) / need; - reduce = mixer.done - mixer.min_needed; + reduce = mixer.done - 2* mixer.min_needed; + mixer.tick_add = ((mixer.freq-(mixer.min_needed/5)) << MIXER_SHIFT)/1000; } /* Reduce done count in all channels */ for (MixerChannel * chan=mixer.channels;chan;chan=chan->next) { if (chan->done>need) chan->done-=reduce; else chan->done=0; } + + // Reset mixer.tick_add when irqs are important + if( Mixer_irq_important() ) + mixer.tick_add=(mixer.freq<< MIXER_SHIFT)/1000; + mixer.done -= reduce; mixer.needed -= reduce; pos = mixer.pos; mixer.pos = (mixer.pos + reduce) & MIXER_BUFMASK; index = 0; - while (need--) { - Bitu i = (pos + (index >> MIXER_SHIFT )) & MIXER_BUFMASK; - index += index_add; - sample=mixer.work[i][0]>>MIXER_VOLSHIFT; - *output++=MIXER_CLIP(sample); - sample=mixer.work[i][1]>>MIXER_VOLSHIFT; - *output++=MIXER_CLIP(sample); - } - /* Clean the used buffer */ - while (reduce--) { - pos &= MIXER_BUFMASK; - mixer.work[pos][0]=0; - mixer.work[pos][1]=0; - pos++; + if(need != reduce) { + while (need--) { + Bitu i = (pos + (index >> MIXER_SHIFT )) & MIXER_BUFMASK; + index += index_add; + sample=mixer.work[i][0]>>MIXER_VOLSHIFT; + *output++=MIXER_CLIP(sample); + sample=mixer.work[i][1]>>MIXER_VOLSHIFT; + *output++=MIXER_CLIP(sample); + } + /* Clean the used buffer */ + while (reduce--) { + pos &= MIXER_BUFMASK; + mixer.work[pos][0]=0; + mixer.work[pos][1]=0; + pos++; + } + } else { + while (reduce--) { + pos &= MIXER_BUFMASK; + sample=mixer.work[pos][0]>>MIXER_VOLSHIFT; + *output++=MIXER_CLIP(sample); + sample=mixer.work[pos][1]>>MIXER_VOLSHIFT; + *output++=MIXER_CLIP(sample); + mixer.work[pos][0]=0; + mixer.work[pos][1]=0; + pos++; + } } } @@ -531,7 +585,7 @@ void MIXER_Init(Section* sec) { mixer.min_needed=section->Get_int("prebuffer"); if (mixer.min_needed>100) mixer.min_needed=100; mixer.min_needed=(mixer.freq*mixer.min_needed)/1000; - mixer.max_needed=mixer.blocksize * 2 + mixer.min_needed; + mixer.max_needed=mixer.blocksize * 2 + 2*mixer.min_needed; mixer.needed=mixer.min_needed+1; PROGRAMS_MakeFile("MIXER.COM",MIXER_ProgramStart); } From 0bd9accb675997b7f99a074a5773682b85e599ca Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Mar 2006 19:56:22 +0000 Subject: [PATCH 2476/4131] Video documentation. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2560 --- docs/Makefile.am | 4 ++-- docs/README.video | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 docs/README.video diff --git a/docs/Makefile.am b/docs/Makefile.am index 17738546..7e313172 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -1,7 +1,7 @@ # Main Makefile for DOSBox -man_MANS = dosbox.1 -EXTRA_DIST = $(man_MANS) +man_MANS = dosbox.1 +EXTRA_DIST = $(man_MANS) README.video diff --git a/docs/README.video b/docs/README.video new file mode 100644 index 00000000..a79f8028 --- /dev/null +++ b/docs/README.video @@ -0,0 +1,32 @@ +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. From b626d77546dc77975542891b0ce72a83c09975f3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Mar 2006 20:04:39 +0000 Subject: [PATCH 2477/4131] Some updates Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2561 --- ChangeLog | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 39bb479d..80328353 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -0.64 +0.65 - Fixed FAT writing. - Added some more missing DOS functions. - Improved PIC so that it actually honours irq 2/9. @@ -21,7 +21,7 @@ - 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 + - Check for unaligned memory acces fixes hangups on ARM processors. - Some 64 bit fixes. - Added code to change configuration at runtime. - Improved ADPCM emulation. @@ -29,7 +29,7 @@ - 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. No more ems=false with Origin games. + - 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. @@ -60,7 +60,24 @@ - 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. + - 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. + - Implemented the Tandy-DAC. - Lots of bugfixes. - Even more bugfixes. From 84edd8ef0e1ebaddf4eb77bbd182f35c1e2e94c3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Mar 2006 06:44:09 +0000 Subject: [PATCH 2478/4131] original is a setting for windowresolution as well. Made the choice logic more simple. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2562 --- src/gui/sdlmain.cpp | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 29b9124b..d99fbadb 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.110 2006-03-27 19:40:25 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.111 2006-03-28 06:44:09 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -966,44 +966,38 @@ static void GUI_StartUp(Section * sec) { sdl.mouse.requestlock=false; sdl.desktop.full.fixed=false; const char* fullresolution=section->Get_string("fullresolution"); + sdl.desktop.full.width = 0; + sdl.desktop.full.height = 0; if(fullresolution && *fullresolution) { char res[100]; strncpy( res, fullresolution, sizeof( res )); fullresolution = lowcase (res);//so x and X are allowed - if(strcasecmp(fullresolution,"original")) { + if(strcmp(fullresolution,"original")) { sdl.desktop.full.fixed = true; char* height = const_cast(strchr(fullresolution,'x')); if(height && * height) { *height = 0; sdl.desktop.full.height = atoi(height+1); sdl.desktop.full.width = atoi(res); - } else { - sdl.desktop.full.width = 0; - sdl.desktop.full.height = 0; } } - } else { - sdl.desktop.full.width = 0; - sdl.desktop.full.height = 0; } + + sdl.desktop.window.width = 0; + sdl.desktop.window.height = 0; const char* windowresolution=section->Get_string("windowresolution"); if(windowresolution && *windowresolution) { char res[100]; strncpy( res,windowresolution, sizeof( res )); windowresolution = lowcase (res);//so x and X are allowed - - char* height = const_cast(strchr(windowresolution,'x')); - if(height && *height) { - *height = 0; - sdl.desktop.window.height = atoi(height+1); - sdl.desktop.window.width = atoi(res); - } else { - sdl.desktop.window.width = 0; - sdl.desktop.window.height = 0; + if(strcmp(windowresolution,"original")) { + char* height = const_cast(strchr(windowresolution,'x')); + if(height && *height) { + *height = 0; + sdl.desktop.window.height = atoi(height+1); + sdl.desktop.window.width = atoi(res); + } } - } else { - sdl.desktop.window.width = 0; - sdl.desktop.window.height = 0; } sdl.desktop.doublebuf=section->Get_bool("fulldouble"); if (!sdl.desktop.full.width) { @@ -1289,7 +1283,7 @@ int main(int argc, char* argv[]) { sdl_sec->Add_bool("fullscreen",false); sdl_sec->Add_bool("fulldouble",false); sdl_sec->Add_string("fullresolution","original"); - sdl_sec->Add_string("windowresolution","0x0"); + sdl_sec->Add_string("windowresolution","original"); sdl_sec->Add_string("output","surface"); sdl_sec->Add_bool("autolock",true); sdl_sec->Add_int("sensitivity",100); From 5b4531c0e460e653aa865fbd461f5d7eb63a9486 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Mar 2006 10:10:21 +0000 Subject: [PATCH 2479/4131] small bugs Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2563 --- ChangeLog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 80328353..4608e009 100644 --- a/ChangeLog +++ b/ChangeLog @@ -65,6 +65,8 @@ - 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. @@ -77,7 +79,6 @@ - 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. - - Implemented the Tandy-DAC. - Lots of bugfixes. - Even more bugfixes. From d8c6b96e92952d77867223ef49be7cfec2da91f8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Mar 2006 10:17:34 +0000 Subject: [PATCH 2480/4131] typo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2564 --- src/dosbox.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index bb60b66e..34e35952 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.98 2006-03-27 19:41:55 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.99 2006-03-28 10:17:34 qbix79 Exp $ */ #include #include @@ -271,7 +271,7 @@ void DOSBOX_Init(void) { "frameskip -- How many frames dosbox skips before drawing one.\n" "aspect -- Do aspect correction, if your output method doesn't support scaling this can slow things down!.\n" "scaler -- Scaler used to enlarge/enhance low resolution modes.\n" - " Supported are none,normal2x,normal3x,advmame2x,advmame3x,advinterp2x,interp2x,tv2x,tv3x,rgb2x,rgb3x,scan2x,scan3x.\n" + " Supported are none,normal2x,normal3x,advmame2x,advmame3x,advinterp2x,advinterp3x,tv2x,tv3x,rgb2x,rgb3x,scan2x,scan3x.\n" ); secprop=control->AddSection_prop("cpu",&CPU_Init,true);//done From 38fb9ee6fc9373aa6f161bc5fb53c4c4c392e8d7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Mar 2006 10:18:13 +0000 Subject: [PATCH 2481/4131] scale a log message down. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2565 --- src/gui/sdlmain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index d99fbadb..ca861847 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.111 2006-03-28 06:44:09 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.112 2006-03-28 10:18:13 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -698,7 +698,7 @@ void GFX_EndUpdate( const Bit16u *changedLines ) { if (SDL_MUSTLOCK(sdl.surface)) { if (sdl.blit.surface) { SDL_UnlockSurface(sdl.blit.surface); - LOG_MSG("Bit %d",SDL_BlitSurface( sdl.blit.surface, 0, sdl.surface, &sdl.clip )); + LOG(LOG_MISC,LOG_WARN)("Bit %d",SDL_BlitSurface( sdl.blit.surface, 0, sdl.surface, &sdl.clip )); } else { SDL_UnlockSurface(sdl.surface); } From a367bf7d651fef6352f1a342e719dd8a4a956e4a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Mar 2006 11:51:29 +0000 Subject: [PATCH 2482/4131] updated icon Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2566 --- src/dosbox.ico | Bin 110434 -> 114926 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/dosbox.ico b/src/dosbox.ico index b6fcd91612cc498f442829901a57802069cf59bb..f8817084bd6875bd7ad4e62af4c4916f7880c822 100644 GIT binary patch literal 114926 zcmagHjh|c9b@zK5$5STujF7F&*ix+6s-))-%_+D^pu!wR(Vzs$OhSW5hD6q7?4${y zj~#3eFA1RuqzMTD?9h@Iu!Es(Vz3Ri$7YPj#^4fOgl9_S$Q&<9YMEKk(G%d1rZkex7$d=U@JE^!_r>+rej7U+v!i zXvFh={P}s_dFMs%2R(1Y_Icil718^%Ja1_CJa6ez_x`y)&pS3f&pZ2U_x`gBJnw5q z=6OE%;D(;}Hut&SdMorn)S}ZrIO{BL;n_ppI|dhf14}aAS?^fny)(DU%a@zppIqAV zR@K_xIUiW-l`mWGz4y{jdFRz8J^$iQdd2W6?>%Gdz4C{z@kT!QSugEh;4Lk@&pU5? zvv<)|U-DMIZ;h8b|8g&TUd>yv>VsZT|8wt;F1yZKac<399#p;aC%)<>hce#cWq;^p z&ROkUc=cW0hd#5_d+!xr^j2Mdz4!i)eZ{L?bFX*Nx_i9j(sz3w-SU9$LZ|drx_vyX%OTT7HgK|Lk2} z<(lo@hi}~L)vw>c%QrfHLrd95pUg{PkUnx@~=Jb)o+^iuK4QH-p9B8v-g!pf8$mD?EBs)zk1mF#J67XK6U@U zdmp_1F>m}UC%j8GJ>sq1`cr=Ux_9aI`@9eT<#XPrw!PqeZ0o;xo45a?*ZTH9d0%?$ zzrD}zc-8yp?Js%Pe*b@YSKRTkx8=c~dtX2Ff4uXr{%bG1<{@wDhyUrluk~%OH2wwe zypMgu8~Ny8dLO)TzxV#h`@G_1U-9zwFM7pGw|MVuf8Pr~zsJjeaFe&;fq(UatNzOS z^!I+|B~$P8)_vz+yfwER_x^C~S}#|-$(y+QAHB@Q*Lll7Fy&<~{4?)Q{`v{;qWhon zF5dZ!H}-cgc$e-y<*hk%+8aOqZ{EjW_}^aU{EvB+?N56je)@Iq>j!@2-SoGwd7t~M z7rc$%ebJlv`qSR}tv~i|-g(NK`u_9YpC12L@1sXv^FHzNZ@r~|w8s1Jv0r$tfBHXO zGP}wfNWaHBYuNV|B>&J$6;^vg{>9$g2h!e}O@HatH+;oweEu(xi7&#hZQiH;>hHYI zZ-3O=@cjc`d+S5q)pzam*53Jmclj;%cpv=2R_Vj-a6o4|BWZSa`OhS{IM^1 zwX1LSs;yhR_kH|Y?>*z6@~T(Q4-23RJ`@Bmx z?C`$)@ax`|2maYx^Z6fmtuOtZ_nEIhDq}Ej-rL?bZ@v!m-afC}^q%&%=pQe-#Ex&X z@AOV*I=tNuI@%TSL2uvAe|_)za#yMs>&<@Peq%jEzgLHEf7?9wKfcDjzU}SqUb@_x z?k~{XOVlfv=ms3)FLZx_z^?_2u72Cw!G1yCADq?yj)i9}qAgt1Z|$u9{sA@K=(N9o z5eNSCfxRCX?CTrs8`N=dU|>*}5Ar2H=^ND9S&RAx7WEJIFYI5qD6w#1f{qi31PA-I z>tdj9fVVU{;Y3l! z&xA?;qJ@e6Mf`t9|H8AAi{bu~)H}IzLSO)&Ui(0AXn1&NxUX-xZ)j-gvLX5hfx*7v zq5grs;bGqO^(VOB;4mNve(sk@f?`5_aPLIlGSD098%U+onPeiJNFnaU+qE&h$Cm^y@Nu>rbYW$@D-Wa?FN?t zHTVPnyOu6rwhScroCcsmLa-UJ_)#|du6KKHUon4W?ho^6AQX!XT7XT66A2*DKfp+H zbB<}fNkYeDB9lsU89?h3U6D!m4;aWvN5kYmp0|nqWYYRcXHr@Hnl~BxNu=}nOgb?* zm`G;w1>UL)0O0!~G~XrjP1QbXj${I8YE>}nP54REnJD3&0dq%f5h6X~4BC25pq5DiJd1GvCvB4IK)kVqw9 ztgucYXQd!7-3FlI`*Oo8a_>L?g82&v{v>(9aQS@~`b9~hLl)}7YETJ)NWd9M3Wbpo zGz~&#_!ub=&fFfzdBZ2gY@rln^Z8;B6!|&i1NC&eSj-0CnkgVj+yZFw1(RAn0XjGW zLiA%_App`4us{+-c>3V(0w$jgN=D`);t2zchN6J_fZx&v_=X?=e@beW%!q9Hj7$*l zaU&>{%;#2L6b_tQx;VIK)v9+aPQGV!!BFJ`)smm9K>K{L2z!cjIijCH%wn;`Te>V1 zgJgfYGzL^@12-eMvY=cP3%NX#gf97Pu~IDLb0!MeQZ5Mi9zlTuX*%Y|Bj_|ZCh2HI z=*gU^FVB(X~ z46`ZVgw&Vw8ZZ!l^o0u=pdtSOCu$E5M8rH z@CPsHkFz0}q|70i^ZjX`y;>MLpkKHGfeblrNs&ykJTCq7Yz%e2@(! z(U4J^kVzK<*-RqFe24M_L2XL#2gl9VR{yI@+8A!gSF_2073dJ{bqyk%H)!BKlbtRXnCU8T(PQu8E7OcS6#Z`+~k^CQ1nX` z;m_R>=#pP5>3-EJ!vYu-^1dV;irPRZL6yNqr34#5^G@7=*QFwu>z^*kBbM+Rvk8)E z0O8sKT>=gigv`ZkHiZVIky?2M2*?Pw5&1@VxNSCvQb_7D>5`w%ikx&S!N#XZb32)0 zu0zMLypXU6jUkTS(i>Mw^>W2vq}cpK^4!IjeX^M^m2>IViunV}^SNx``xjlh{M^LF zYs)zXvyc^*@DD3$mRV2JBMImq6%0j7&ZV4#a#6g9kT!^K`#WOK3#zf);&Xy2vM$7Lb0)?>Ohdu8_FjE$pt8h z(>`@%7KEM{eS#5DmtO)Uwge<#5SFDf{(mLTeb;4Iw=WiILa%qRWaT7DUp63rF!7cCtCy>dNSY1iIAxUBHmYg$}f_9sTeoFDQh zP}}@GlgUj~{gG@ihFD^dGu$sQ^Pa;Fmi*B&pXPGaR=JWLZ%+o$so4mFN+n+$4aTzN zQJ@P)D+0O_PE7hGjbCcmd>@3sZ*(H`N2}S<(Gq`jpA9Nds}lN+N_i4FS`ESAZMhX9 z1c8RwQXZO=v#=a6b%5RY2gPDel+5MEs?ZQ2rmtM7am5ESO9wBzX6@?2y0y7>yOT)o2ALm^Hkd67FJN z!+b8=@B;=(IK~g_!XlT0|(k#@kb}>?N+;93ERBE7za7%S`R@QtdI_wUIrz`OXe5lDtZclkP-g@`{b7< z5R3^wi<0>hA01CEPF%Luzhbh`yf)Wf8ze6>{E^@aoZ2fuug2bo(=cLaK!iJBq zPxyf^j={G|nKOvuhx!i2Atz{EaRh4zIWV&t?4$%aC=jj=0TAg4VfWbR=;(&g>S%ei z5^hBPs~i1MeGyFLs%50TGzz}eieDT>%SVH(KMJ<|4=UA4yXu!AB!tI)gI%@Su7{0w zqZ&-`8m_G{S_FQzQO{=bZ8QT#g8slTfhPIYuv!9#Y^4-_{))jB`O9jhR@2WmYNbk} zls-@L--kVhsl`$|U%2-3xeJn4d}ds{ueHkII3f)FLl7z=i*OLILVuzHM@v~o1{)o8 zqcWx-hisN}QcVVrb_>yC6q2R8=CYfrieq*^y#) zWb+oTsBE~dxCy+*{89ksVXFcTNIb;H9KiW9Uoa{o1{mdRu2NyZ#)Xu!`mmeVGPEg| zTg|H9XfbkBT9-BZSClUMR6e^FIV(@nOCcfuXZaw*rXQj#4ZqZGUshg`ochcam3m`x zs?}3 z59BvU{XyTD3@-Aoe7Q~-R=?$JWKiAa(*(~2s6biTD6Zi-<_;{W-Y#8xe9Vv9KSvljy6hV8MF#?XJ{xfCCdh*qw@3u ze1sx2tc>bA*`X3-@~db8(&CSS)Rs**Y`Njan{K?}#xHC@4!*b%i->XtV_1MJ&L7B+ zZrE`Bbr9*gEt|OT=9@R&02zvCKo*(9e$goiOWy-Vp#~Nab~I$%xOt|)m>AaE$UPV4 zvSm!R*~n2*DWCV-A1n>LJN#0+eoeM8S@TovwqI*jlE{DmO2oe(Zvivn7>5sSJcZ!iOBzQTQtA#!I{Ix2t2L zW1BZ`+H%V+o44FRyK#%SyJ6!-Gh)KV1~VUXuz_!G*mR>^hNNt|@rF%X#zyg&sisaP%Mk?O#Q0O_??U)>JdljU5w-LBW$wR$;hwkqw`t$1~2 z$|uUL2}~H;r?DRfrg6|vXvVX^!Wx7E7@V?W*Nttt={7k3)f++ot2f@b1s%W~RvYbV zwHyL*6@w`Jue%Q1xrnR2dc#+5yBP)8QVd43qnKK}8M$>uphMp9q~X^@Fwv|tLRT1S z;6SM|QDwxyG_@uwVXG0+aGDVQ$~D(C2Hsu!OGtr<&DL{%qv{tJ#rhia=P!C!BEj^q zm`n#@-mhKLo@m!T`OyoOg`d2pZ7vq(O56e@9YE|t1 z)t4!rIFAdk$aD)g`!X3x55=aNAMw6X);!} zZmm}~Uw8d2H+;j|H)(f#>(0CG-g^D@^^Mi`R0H8E!>UTTI<|S!ZQHg**WK}LF1z!t zd$w-Aj#)(2pI|7_D%f)($7GC^v)JZSrb7Jx;b8(z6&yG|z$u)pG}cazUwifPzU-I&>d*iB z{qMi`-h0=t|IT;5`@Qeo`<*rSUU}tr$FE#-<(l>1`|kRCzw`ZjzrTLXn(uvg&6@k} zyZ65JYreOp#s#%2zq@|T_wQYQFCSg{#V>r}3%3X_;cjT%zjf=H%RhbJcfRwT_3JGkV5`}FtMTy$RBuG3|-JMY?l&(to{{P@G@w`mBTEg2$x^Hbwee{~Jwf3XS-<7S6Vr*o5@FOq~ zIFS`%n;0#o*CY86d|So`ri;w3U;r*F-Vg)11q`t#S+3b~+Yf%QZJQV`++peiptWPu zrs5br0f7RIYP7LUH{Epe?b{&Ix51suw%@;X$IhKMZ`m|L#59XY5ny19N7%TUIS_2l zGSiYffXA=s1RrKcGFU_|VOoZ_0HjPaE9u2cTIF1}Jzl9anCO+;)ygEZN9?)V{@o9M zNC#@V#exSPdg!6Q{n0lJeJ&I8ckbNz(1QyWEVyLBlEoJ+SpYD)kM6Qy@e+P_$zpE3 ze96kiib{k%u3CSg*VJzh|$tM`@2e=Fa2ezWw|4 zKYrVJJup3e@X+HC`r97>{T(}Y?wC0+b3kq1f&KgU@7=%ez=6ZlPaK&&`VF%W+wZ?$ zLIMHeZgj^-ALX4L+^6o;j@()u9RPy;GkX9Sum!WVT@Mdb2ucz{RY)pmhqcDkL|7|N z)Js{-e+CCJBZ_$iReXYStJPvqsg;9u*{Flg%kJIBo{S;dyBEMY2xFZXIx`3M^J?$i zb^G?sOiw>?=!oO~J@?!r^l39Ru-^yZ{FEQfaMkgro(BIr@7&(G3_8)&y=$PikJkOb zJ{Da%ZU3>|aEcbA5A*s;3EVTn30Q50uvT>{oCq09i>2nOdHqAf79%JAfYGkCYirlG zFv>xGeZl(KZ7n|CC5ViB!qhcKcw+!q8Ckk)Ixuti#KFfU`|vcv9{dl_9G;#zU{uqA ziw+%m>L~bgrHI5oH6v4ep9A|vHnjsCbam3b8LSZcpl;YB0*LUgUCaNzFCn|tt|^{D zC9T>G0Z>B+ z_U?tCGq8Ua@fZGg8|QUEPORH~`}QL99C!=GXXX&N_l*<&i0cNjiNNyA@(gPwM5ORu zYVB)lwMk|+VJlZ?&PV=-a42!0i<-TMjj2hd*I_u3I4{|Qx;o=6_|NW|k;FPJ?ASZ# zAT@AA03;~!q{tzb$pYSW_ubNJhn47X_yj6|wn&7qeTR^{5^UQX$L3D+fhM%q_ z4F7Il!d`9Hldw!8*b&1=O(IMtpn@X;f}nH5|HQ#V4*du(;V%IYJ9UX{zoZ}QhxYR= zLm$nqIDl4(o^ue_VBiLX=wksi^N545Lx6{$aTu&jFHN#wRLo_H?IJ#Bc{B_f_&=po z9sGy;e7xHrT_C6uHmBs0GH)48o!38y|Bm~RS1JH!xv^|sYpH-{PmW$*qOxNi~)q`P(< zI|kz%0uL`v4-u>$Oy?7YMx{|^S`-FMiwM>!{yjWQq%B`5R+zn(+x2R@)vDAhrPO%? z9sG}3Z*g}{0yN%(q#N@i{+kZ)ky!$n0*AjWz`^Gn0Xo<@0to-<$o5P6@9#lh#9>Gm z3HTRFfLXg9lNU2!2F3_r9YDPY|6PldLjx=$24w>D1o4ic!VjPgp04<9~wkF$U~G`PzU$OIgQGEabhWc;?rmd{MTnbUoa2B6qwdI$Fy`@Q16 zYYs*ocS!{V{>t?5;6NH5h^1dbbJ+$H<#wrDFKPbMKRiSXE;AAo6U}P5KHg|I+eA2n z;40aFPh zN1y)jk2Us1Lj+V1;eNmE@8B(}JUO#xTDVL31+uY;qf=Vp|03v1{_`m<%LHvkfL1U; zw6L{m-oWs37LZb%YAn#7$;nbZs5|A_qPxEUql8|;2$4;Y(`*Q=!893K(D zz5w+nr5(K5pnZ6H`b3N#me3qL3?t6r5piE*-(Ad%qo&^=NhaF={|8JTaM5@HT6gZw z^k(IYLm0qxp^OVabbNwPdVMWxF8w3KfBJ@&DorJe;+GqKINl0tL^232GzWzEF)T@B z{$e`lm0RHl#4Q?}dblEb$Y@2Q0O*LFe~k7sIdW|WP9`Q_1B`Tv zBb1OmHA*{b>kiTV4gCmf)7gjsk@`P;Ns!?9U0Hj5vGZ)|?DDeJ)e$bR1l^k(2w4Ggb1bBGHEMH6nUVG<+z)my6Eg7I4ro|XW zuZItI*pKvgzQo0Jn5%DwHermJvF?lkGIEfE%oQi^XCsPUtS1UgRkaFselEnVbx$3EAL&Yf zBZBbnp@~5b@Yt~!|1)jC!RL;=^i(AM9qpK-_u{|$5D}b2nHX>y`Cl`dp<9Dp@#&n` zm1hr_hf$~&kaIm~;{#ku}Brv2=hZ2iE^;Wss9u2eAeCqi`jJLCW zbZPb_?ph{iTKX-c_tp&pm=rkoz=;4xu!HEAw$2?@LLlTghz?a7mAbE|HUf@lNMwrD$If( zt4+8EfM>VE{-+f6 zx${|b4>{;68BJ>-@7|w5;*P1A*%e#p2uwrS5g;BDFG(&RCQC#y5aQu}69=$P_%}V& z$N1N`vPj-j9v_exZnIUdPqbOPU^VT9{yFS+D#k~>_|MK70VJOhw>k=dxH7u|3FBlG zACVEj4~VQBFVEif(o=VUJ$|oTf{xegu*cpZ_po2W|CSA(--W2eA19{}Kr|4fQCs}t z&_F-gFk~k({ne6T796WrO!igh&l?y@4zN_gVr^J%t(#igBm!D(2HDgH5)OYSMozb^ z!%n~U4gy3do&g|$$3&5Im>7$h9Y;v$KfC?TJ1y87`9$KrXol$XFG5>C?{?lpiv4@K zEYg`1cPFZL)Q7uwga2THrE`4zMuq6kRJk%9K^_R3NhT&u+i#E`lS^ZvBZ3 zi-ta=0$-ROcgCxeFcU5bg@R`E?9ewT!BZI9!B7Wo_xdpSziXIO?P4{bsN~BNtf?s_ zD4XfeD*iK^WV8<&#Q(CDcDYucVsvC-CwbwZ5VQ{Co;n@Nvhe>AY>fp4d-)?EyPgXX zP5~T|!NhuICe{EG0AeH0qWrGm5=-^P`p)#)$SY}ZbfypK6}Gj*{Yc#n%nq#X1RQoR zLH|h;V=*TglG#E^M}3?OiAHXuzUplQ!-J%+sG<7<1yz;Xlo!KO&|x`dz0#mInGDtU|Pd zP+y1L4jMpm{{@-BCk()Ui0Kdcg4GmxG_9$Le9&x%rD`e_&RaFGY#Etmg+h{*Hr9FD zrLdf3QNNIRVW5M*b!Ywc;O(%N0PH>nKd@8|@aPy3K)5^nBO72Q;KZ}{JG7Ai;r)}J z{6yw2^7#3ML-u!(H#*9gxJYM5;3NFITyfAD`nxYlE*)ZlB$+0SuUM&0mVi_n`8fcj7Q6aF#|W;3B(j{rq--|1Q>`}W3hZU>ga{o;)ppTvS;kRMx; zWLJn%!?AIGouyn>HwgAuSn{7Ye-Rn&to^e5!;)^jR^$I@xlH2c3w<*X01D_1afj}1 z?pB=ZX8eZ$nyN%xGeD)Krut~A(Lx7V_I)yd5a6!uqJS`0J4JJr-_*opW?y%jYhCsp z=7#wl+7a^3GC4qZ?>@Qv*!~4C_9ZZYtkRPkLDodpFZr!3SrfSn@qgGClT47&Vj=Kw zg2ahDSx&-VDrOQ8V{doRA;R2Y?+BovU_=9FpAG8>ciA(E16slupm5mZM`ZU9{GYmZ z>Xb|$=|GHscj}KqIGxz@i18rOe}kxp|3IYXxc}td1&aQq2QnqruZy{QGe?S9 zD^*OUifz_E(gl12rP#6pP@Y^{4a<4f4U5?qhJgbUt7d%*>8R1Uo!MR7eFzGIB(Uqh z8|-;&MCdS1m=O>M|HmIca>VdA>|dt2^#DV@bG@C|kLG?9hxucO%=higQU#m=CdiLL z(giPS#})xlSvJ4bDzFODU@4bS@BDd-*bkB_5dvoUmzDNgS^6aqJeJPCFsPLkM*v4{ zq3kesNB35@5(!ut5tPU{d~{6`|Ku6YyB0(a9(wM`k(ch=j`;snxT`t*B>?c)wYf-( ztWG#U-(h|XwYLeX2*97418DItVm`u;@315}yiD6>G9fw7CBKmh+d-{P0%mbi{?8!! ztK^^gbryhd58GEXwOkxrHDLF51TZ8Gdl(;+y$65Y4+%i&_rvrEaG;gU&y8XbAv|%2 zSzT0)ICp$DK7upT-td)oi|Jf?V9t$#{{jgM7yLQ|UrzS{A%myzEn6AmoplOz2L~w`b zM!KOBHWAi#dZ;Enc>QJo%>Ky&M)t3Jbwmh@DyUNtH;!|| z28XWU-N8J9YnS1_dynJ9B}q014vZ8Akp5hONC)Y00jUtB9RA-T_TDIKq=NHTUc0VY zX-z>163r(EBS?$@psk5zL;}NF2Vu`a5+Mn2%fr$G_+);u?3hMtNFiY$+^eN7B0dWC zi~pTwF+Xs83lq>K3DPX#7a%<>h)xYSgJur;dzU1JhS*t9%H*2aa-q`pTZFnTDY(i0 zCpKJak4=g6jbgo3DV3XLEMQQ4e$e5uk2}usgd!U7;)cdZ*L2TEv@~f5Fz+>Q51jyM z8q2+WAmL}R<0;~O$UnYMgue6tWjK&<1^&#IAo5+*UEJGDAGb!tW4d=~5r4wB0HbUL zet+P=B}sOFGR771)&5eZ${e7WBUOp?v=6M9w~$>kX>y2jWPlPGXX%?{<03iUSM?)o zAb}k3*=?Rs7jZj_g(1RUS~9zPPb8;OR%BMV*qQ(_0=}6!0ry{e>ZpY~CH`l$*ad)w zvK^-MbL2rwd@&fNdmVu{>&I7oVAw~xFTq>P_|GPWkwQ>rL&0jB{VJt7>pwq#{yW$v zl_XOtsFJw7x;)-&wFrW-r{SsuP~gKzp&@|K>)bj9!QIaYVc&DuBa1J($qw);dC*&} zax?Nd;kR(-@1nnTt5(HKQA}@a{FDSZY1qpOr#NrC2hXm-i>csPVxYte6i|KTi_7}h zCBkMvGMRE@evCI7@^*9KRjhw&b0o7tQUe=)J1CR=QJK(2m8+6szvLMoHj)5Qz}>4$ zf#}|RAo8FBU6GB?LY=|{^y8*p%3r%%NS`+H6C)@FJof?AEB;4 zy*Dy&(5oQ8@W+nbKp(sRTmnQenBT|9=WHLr z?q_%GFaq?(#I-IEEsRTPIzM$MPaZR?Hz&Rsh2??7hGJ*;Q9@}>$8an-yKk_-PQakj z$l~M{H2c*)oOG_q_{WA$pENn`Gt0Hf{9<2DjvXtx_YE;}xyJn!Y_Zu;ECq(LBtiVQ zSCDt~j~54f;Fs{D`x1Vly$<~yr*`1=;|$w+h~~dLcXD8rKw3bXbAMan)1B;YPV}7= z8YD<0uO|BlzZ4e(6ajGVi|mIVWIuGFlunHi_+%Xf{Bt9=|B>CYWD^qcVINCNTRz$~ z$PoDN8}0;IT|ZHNf!&Tnlw5!~f_GO61jWNqqMZ93b`XRZ_tAY@=wqeJmU@J;Rz=)$ zkltC-7-+wAId+i-Jt-n{8=>i%-nw_sxUcwF1lTP{Ts_E!>SY1`A3G`8%gGknY5I|~BV#{C*O^v!b6lmqnqkjzf62JdkR7P@)xLUpSy>{*p5BaaPUYrPvV8TA8Wp#vwi0# z;Xlj2mLkuVDt1J$_FE=F`YQ7O*d|XhIQc(HjjQA)!V2%041T0f=nI0!+=OKBqcd}j zpy=OaM?@6&8LOia5ZvF~zK-t8@3mm}jvYc@)1?^#!O*}FfRiYqYBK>deUCBlX@HL? z-*ej-0E0vLcgG*p$Kk((^)GhCkpYO=CzV$z@%0K>4$S{o$^Kyy*iOoxmg;Co3OUoD zFf4tbZ%&Slbrq-B$j}Q>HEF$C^un1wWPLm)0IE;=gDF3{--G^+Q@BU812a)9$Oxd7 zVd=g+H_VUzo@9O7?%@u-Zyf${tX~5k?uU$rEP(xZ|A8e7wfxJrVDiD)5DABKl^Pa4 z7fiDMmwohT1@@24RxE(FNPuXP44rvi^M5r%1X9xBzL`fl!(c>#V_JLWf6N=#Xk#5Q0b@xDWk&mQeX-|*Lrz}Sxsy#M~L28akE zfN2L2gifHhgT0}x+lc)li?x&JzB!#XYR%Z}bI+bVGYb++ndBCiBVbtD{k!-(VT|890x$uXG2K7v zxc}_dmv`>uKN&tw%2_PXAmD&6zPY$}czZ1R78BLo zNs=EUuWuatQ90Q>aF_Da?0nze1!oVdt_d3vMS>i=R+R2Yk&Y7Uzh}KOHOyDUe;VvP zE!QVnn1|79kU4({O7^-@u?%PmN^{a5!4-jJ>~K6WsE*-f(N!>Rt-+|b>}8a5 zq9TN<5wX>w9{8lWQle%Aw{pLM3c>`e^Y`SX|eLO7>qBY+8AmjVtv zn}j(^@Bv`4JbXggt?M*$B@?v-_8tw(l>u@z-?@_+Eq_U#%3 zcAx`M6Zaimd+^tMuZQdods~8|LmK_M6Tp`buy4QcA55@6oIO9<$eqj8*#*RuucZ9P ze@-We4U-%Z6#Ot>P1P!Xo7fQikMY;+J8scb+!4UgH%!Iy4))QBK6`lg$yp*kLSN~9 z9sGs9@k%l#4`|xfgh-PY1!y(~?3^|9&+ORzKxk`J5dJLkDAZ#A2E zmN!6tym@4V}-yM=#5rmeH+k8#;amyWtsNBjX{mT9@T@0c$NNEFyw)3shJ{-uxN zN2<^T1y}$i(u4ft373@rNsCpAKpwW=o9`>)an))|XPGfs(HD4J`g=`9|g;!`h ze=d0@{t@!A%<^h6F_Xf`NWBFCob4j$q%hrUs1tN1T1 zk9aP|ce&3ud`nE~*puQpy(wOzqq>dl6|Z|&oV|Q#sGqu2Y=|Vafm|nlvd;KdC}{sH zo^b->hiIf4tp2w{w*C_e%HFp!a-a-C=&RQld;3fwAqSwrCDA;C0;T{bPrfR@PaKV# z*iVc2iGpR%li=0%q zs7<2cxgztQcTg&;Kf``08Gj_tW{_cPBtW8L=l9gnRVU2T;^rc|A{37-h-;EeSZ z{I&mw8f@%53>~!LHTQuP^B4A0;*kxu3;kb4@SC0E>{eFglu34hhgko7@p5L{@<#r8%KU^ieX~X)C9cRjsgh0U0m69DhWc=y0 zSF7v|-P(P%!U-g1{viPb&|;I$^qCYuM*D()8CI>zd;#80Hk*^SzmNETzJUGfr~W~| z3fajzP-;VkW~fY44nESsU%P$zQ+GP$L@Of^4vqk^m2wmSXr~Rl1<+?6eg-v|-8~)u z#{D$jC8$o#tB@Sy3QXfOY2ZV2TtBYUNCcugMCgOPlYI#QgP#P;oyOsFdcWYsLGUkT zsEC(Q&6QD@U8oQR?yocd?PG7CrarK}LExWFFn9=~+5A-<{Lkc8SN!$Oj1vH{TIf3X zB9`e539~{)s|S`Y4Tdt-9Rl|B&Q}Lw^o4(9`l2p-UmW}4zVX}yKtrDy0eL_A7zrSF z!X+2HI80?)Ccv!ulL0+ZZ?eRz@jt)%HTFN_7pT@7TObJy)|yk)7^&2Y;Ex+YC(^Et zw)OzqIVJy|*2%keU`l0O!%4G@X(IsA>BfG9)<%@>fC5dV0@Jg`edE8R-!wpqq~46e ze8T+{>k_XWqQ-Lxk4_A6eU3H23*2`B`LC*jNfDif%3-M<4pn>na#sG|F!d~{@K+9~ z7|xe>rb-w^>RkV#Opo9)}T;_N}P-&Hb|7&mJh zsJTL16!}v8OPO(~epN;O+SMs)=+s;7TdSkke`CGrm5uzpz{(V8Krmg12@ngvsX}D5 zY_tMolUQtk;4+-0uD!@}zArMTU4t4CQTU6r>PJlir>2J${ASW_>uEn;+Rj37|H5zB=J%U{0cKLdRfKgtFTs(%H3J5K^E0pPLf zhT?}`gP^X#B5ROYu+!we^^oH+mgXgs4tj}vjCo7|;~yN12|#~F0{ZG$m6?coy4JL3 z`q;7QJsjd6$MapqxzV232@yOr87Q?b+cY6SCEooa-Y*kCvR-qo$`l2B>M0g@s(!J7 z{!=3wcfX;Xv8!vvjktdsH&U@|%Z0B^oBiNmE3z`(oz}TstO$=;L_`wmz_nvc1ZlBr zrUL93FxfRacA@QXKc<;zz>ZzN;8XCK}}Mj7HWv(M@;AdCRw zwqL#_0pLG%uM-K%>yhH#q6}see&_0$g7V)q0c81?Y&i0tM=7nikz!PvZn?4Yqk{*Z zIQRtZ;Gsi@4$_`Dq&NEH33jtitAK@M&Jtes&$ytV1w^`d>&(yrd;?yNqAd*c2ot2- zcfjIFhNPwVI4brW^%XswB+hM?U)m$<5viujFOw)pDCUyk-7gMMURiad$@w9}0q>s_ z=vNw8Fec@_{}k!tAbTrh9COrLhGXwIbEr=o3-E(TrpC-d^m2lU9Ny zGM~~-z)&?6LDSPTw#0OppJe$vGcZ7uS0#-p|3Nu1R>J(!^UVMI$o@(dDD9M`Dpb8Z zmc8!!EjMku{r1iOdi?nDBQ#!KI{wm2`s0+(_zwvVK0yf!X+fN<_iqqD0kKX*EEZt_ zAIZN7!R+km)4NZckQhC25J^I_cAq|t+b7q@js5nMi2H_nBt6Qp1TFEI8zVzfOPXZz z;4Xx7*DfcVQc%GrQJ9baJ48Ww%7+%Jq<>QVG0bJMV-@nh!Jqsuw!h}f<<)I=Kh~?) zZ`g8UT#4+PZ{5Cq2Nit|9*hV8p(BZNqkv5ZqZyHDbC&>`4AV}(`s(bVC(tUVR|g@8 zK32HH#*i5O*yHI4PPEDa{z!nB&-QuxffUy zw`){*DCThV@^#h!p*9TVhzo3fCN-kotZ#(>x3gXW>UW&kRGQ4SJ1Noy0WbnF@>05J zVSo(1$c)9WPM~cXbQb1%(Qcg6^H4T)w<-s4qd5U&Sv>vAf@|QpOJ-r!jxt;4ZsTddl|8#i3H<;JfQu~pHgJK3GrX}kmJIZY#@6SCOk$c{;dBjM#GG67hFXA}!M z4f3!2;uo*K{>oEMpJreE+0P)rtB}BCKtI)=8BU?DX1%&}cCp^9rz%SwIX*kf+UiRj zW>HX1pE7zJK|#$zA)E7)%a*070Kl4O7-Sl%sH#eWR1&X%e;>~ap!N+xA^ZYjLtni9 z`de|ov)FQ-Hnd_dd_uO+2%k>XDz?ToiRxn0CmH= zTy~~%Q(V*fp+GU;a2NK5 zc1N2eT&GVTojtDUADCMc36KMq&)=I^dtT^d$in7Pi4F5(4lS`bS@luov=H=g*0klQ8MlQP}_yz{$U(;v)~o`P{LX zkyEov6~mNNL0`nz?|Oix1KI<~Wz;F_iKd?O7ydg1z?cFunDK{ZN_lYJ?&+S&O;vMbf}g9Z+uA5j0IkMM84KyiIWKXN~cYy|n@mQ6Rk`Mw`9l~QV= zNMM}*=_#e>y2(%kI$x_nfEYUWDgv17n(>$Y#`3*_-2;7LKX*CANNIwg!#$=0&JU6d znC**`sU9WpK(fU2L2=)$s=Ja|F)il;25blR{pX^8A09~klF~0Fc0N|iBt9VtR4-4J z+5a=ZqZX*(N=aSDL)tV zBOnC*h52>mB5(5iqd941-7#NP&yZoRO`ED3$WH3y$#5D;{>=(OY4+umfA zBR`_W&uXPwh0&7#i5&PZV*4kafp$Og*n?KRcI#BLJ(?|UXuqa?s)4s#V6e@0HMGYF!Ca^POJ z)DH>&BZj^t!0=bHkknse{`Re0Y7U9v9Up}MbFy2VWyc>3{*Y-tCDZj_1d70F8-(m1 z``?Iv@c;_y%oiCF{Q6{wcRa@9cg8;aAZfcj_{;NSmu5@=+2BLitIka%dKQh?r=<RA3Gxj(MW)qTt?8D)6Bpx><(=rDJT zfi=MW9Bhkyn4LSfz4?Q|U-HzxJWq09m}3EuX)xp8^RKNsOONAW`JYGW_>>3304M@J zn$K>0XctDthH5L$!XU8Y)DHPN7OsK~>}Gr5SqNbGyv(Amyz)-mL7^CiLFe*2_5<@h zPF;2y_ibH>!!w|N^61kK^p=R-A9h4~}YqP2JC*x*0?M2Gv_TbAElXL@` z2E)L_SU~)+Hrp^7}U^MjFasx}@@jIteeH2kpPZ@zU80VL%e{zCx4949vj`5tf$ zZU}(!`^D=WSH;lVD)cqHxrjLwIIg*YW}GGi?joW@ij;N<;1=R7U2vv5>~D4W>vkHK z861SZY>n-+5Nmd9+x8}T9z1fZ%)^f=BE+I;o~@EA4Lenxo8Mzvj~0%9{9 z<#{aa*LFR3{HZhXXSU~pDiQz$O|xWYYJpj9@b3_S1h6+=|E=oV_2fX=ERQ)3gPhHf zo*^`F^i_3+(8ld_NBG%+BJ?x_2uq0>QfGsu^hst%cQ*7@P*5`i?Jt&STKmDa+sNq! z|2B2++eASLe^3CP_}`+zG&>;31<$YpFs!lv$qYa+7Cxl3b;I8hQyo;qmB4!se}tac z$9^2F?v9g|+z?s(Ol& z|8CCN58iw;$qGOz?KhPBuO|x;2G7C&vq+6gVE-wQkKJeQOSv^kDZpT?{UGK|Y9veB zX~uu)fQdf=80=%0&JqB=ieV#AtFij%>;Gk*kMchykz2RIeogQd+pze?F@?sk6NbNy zHbw!bX`n8|br22YTsw8>N`!18qY(^4^bLJ&FOQ8aH~qnz37#^W7)ki7a_gZ3 zTg3}IgW%o+O8$T9b<=*4(Q(#7988QlG7#fWXI%9Y23ob4kiC5GAkCMobUPA3XYTXN z5lsr8epU4Z8MnI@atHn&^$&Pz5f6SVuN!YzwyM8k^eq1HQY}m8d zh7QodVq>rT!kjuIlgokSZgEFvzM8!=lV_|@EEFda-V1x}FzrEqaNC=|{AGqDpkjed z@02-ZBN(Qznq&X_!hW`Y>5+rN-!He;k{ZnOs3wdT)mn@RNDMCg7yfj!9U?J@c=;4wq*=d+`Dg%VZh{=$O(e1oO__RVfKNro zc7M*?IRdAGLMHlHJ|-Dr{`QWay>sW!w{067PUHtv=Oa6&5Jx^+^)vXwFRYq(7Kxz= zHU}43{^Th-m0H-Q01V}THp>1#6>-EM(m{eB@dN?T5D*!F=!#f5v?MArNiN+ef?*T> zBEe3qUz8mX6G8g_${QVT6Dg6ds5dd1pkho=(ATNq?xaw=>sSSl*?(2o+mK~qrjZ|z ze?Iuj!J$mGz=L#%0h0UNBGb`NG7Uuk2U!0~G66vTiHP!uGYY^=wt3ni_*0rT(tjzp zgUA4iU=VW8NdY7Pu8H~b1DOD@L=FB{+}l7hfjq@!r*UoH{5#4PODq;pNs{*X zkI0L9Hj1Lal;aBTncN#0AcV!o-uR}3sapkDaW&D~W>c2w!x>E)DBf$-vkJA~(XZt&)3-^v*k{O4CQfF1m|$0X;=*j|YMm7YkjtrrjE z;3`0JeAdRc7&icR(&@l<Ej-AnP$BrWkdoc1@Y}Cl$?7!h}6G}%a89&z%+;&gf za14MLP~W^=7Y28{@7f{#UcXjb#Ur~Di4;5Fh;wKCsX7mT;h~ugH~#T-WyC+=$zHi! zoytJvdNm*L;5qYu-1vv)sz2fAJlu#aR?LSfvUqmNjeughgV;GO+Wh;t8%2mB#&J}) zz~lIDPLKtNUya9qOr+h=Mq7FV2YLLmg=D;lsZhaTFJJ$6B;RJ^+F#3s{C35Q{o4A- zBVqkwEiA8XcKn|gl>fxm@I22j#OWnBjwwK^Rb^^0w)#OE|IGcu?|DFyg<;h#xtZPX5Frnyj=j zO4jn61o#u>=}+X7B}0+`m(qZk{}BJPrx)wdg86)SYqdz~JLPbS72%KnV;t%3N{!sR z19HD$zam5mYHp3tcLW#WQDgJ|>DPY;|07a<;cZmVQT#{#d+7ukhQ3)FH^r6F5nd*E z?wKJ@@$ZSliiUl>C=dTJ!QfAl3%mT;{*`9?7mqTf4me8zm4NyW3zsDd86M=VCuwH_ zo_ERy_`n|>3EHn|=+f{P`M-E>+P5l+jP!9D0x?4dXz;f?$Fka)r0t(R`LmzB9!;W< zB6TAF&ji4ne~>2xX6V16yKR3qstG9kDhf z8z*BcxpU|4=^n&8r$kxx*Z}A8IO7XdoyF7wr4V;f3b@6Xxk7t<`ZJ0CbTN&M!vW?2 zygdFfn|gi)@=x{y%Yo#?uq~#k?8vZ6{AAr6fGL&-U&akw48Hk9O}3o&?bsQOiycly;ompp*7o|fivPfLc>v(g z1_|(oP_MH-G$(990C*Y$X7>bpSwQ-h;dwkpzt^prgF6vAORYOGJ#X;e`<4z-0WKY+ zDvf5H=Uh?&mK>n$YWPoLSR$Xv@-S8&47RR8^{aYrEEjGh{!7&kIO04q^ITM*O)`ZM z!22=rSDcYrR@Qn3DS6A2B^iUF>i>NJz*RD*micy=Z6lm zet3SGQqHP|o~HTTAdi@Cun9a(4I~UAiRO4ieLO;Tu$U-Ktqoh$|0flMMR4k0VE^-J zp5sdNvpp7$`xEu?c16!%C;p3hI}?BPO5+x)YVi^l2>hM%Yuh?m98tW=n%fw|zL(P$ z+3iIC*w^SLfDU=70SSPX8zNt_JO9xF$jOs?gt=}B5zPKe`nC42)x@_%-y9{mhb|HD z=i7$gTs~CHWJYqSTx&dRV*INC)o_V_uHyN3$$lOmT_pOQ4coACKcr`K z82(+?6$Oi%20vL~J+~xczX*T8@K?0Xq3_ndjsM+gq+9xPE4;SK#U4@C$A4{MvM&CR zPEC78L~&_=Lfp!HlJZM5J2E8#X{u}u=1*H*q$TS9eDKX*4i1dwN2qFDEssxL+YEWM zbuJi5*TH{yFfqWBa&dp#R0SHVg&&N0F<+&^=tTl8ujm8*^mJAHeK@S8?S4TKtcPsX^{*Pu-QQru&IwuH12@EWMvNe z5%$;zrbZ~QQY(*;v;Ciatbg}q3#r0DzQHp<*R?2gPL1z8&;MG5YtWyh;2}Fh+d+$s zAvJA)uM~^_&yVo#jzr@h>;E=(pK>V5t%V0lzk>ZPR;Bg7j^W!I6%KazqX5JRZLL&B z8fiJH1pux5Y4rkw*aNkI2Owafr&###aNdOTI z$p0T;{gcgcIi7nG=1GrfkGHQG<)P)p_x?&T#a{nMLLe-$t@h9^;eW@Sl72Z~fFR$j zi@rQuY&%#m1e`YfLEc8uty=$#Rlp1+$w36ksfzim{6lL9M`R%BqIVTs=sh0cZ{(C# z0+?%$+4x9E4D?N&yvO{w_V=>-$95p{ANz~_{UwI~aDs<}uqs}gnyQT6wCT<8M@J~zeqo{|%t&)Bo+T@t!*d7re%7KRY5&-jVPoCC8eVy<_fE^Iv=xP3|$@6<1^fjEv zwv@fkwnoIyoeXKmmztyxELAI@yY9xa9F65KRTj4;pjTgIfTX{>joe#*u#FASV?4l` zr@v<>d1!Q_T1Di2@_z?2{lkS^TMu-fp!QpRW4Mw1FE`&_{+05ng+KalP0p+C!=%?` z9ZUHm;}>DB7t?)GR*iWgfHuLyXtULZJBO`X4f9u(3{FDuuZ6xmDMuk_D$}6(k@FA{ z040Ar2iPsVFrswU9l>AqW3*d^oM1%-BJ?d92HCg0N$m^D->||*s#nM^e;x!`F0=oO z=bxk#S#lpp3a+lE`dz)UVbhk|w*9yND_E@fH$WKy40K$|gDi_%$gSh~?3m;DEBDb# z!&qR`qP)2H$hw(+i8lYYZoTILkpG3{f*bad{!SQK+>h`#5mJ{YsitLP4EV$AgWDef ze*q;G0C|mf9(WnKi0pkK%{hz@?ayY}ZkHF7ltu|ht zs%*Gv^9}#~f5!e*Og8n8_|M$!ls&q@EWacp;?|Ddk*{Y1fZ{t&3W#rzTmeV0(47UVF3_BOP4XGsJD9#si;0%b)s-6j5FD{3;y39 z-j>Pe0qGPu=Fzv~Nm7B?3zXyeKZ8qoE@&$Bv*F}8uJ3sGn=f9!<+dBYsnJtFY5eFW zKmUX$Hr@HHJHBlr%L6>h+y-iM39)~Sf6)dIm%As~wT1~K$q5Mn8li6lxPLp_3chs* zow;mqbYD|=ee2c--EW0Iv~UE7)J)#J70&H+$D_m^H~b~E1~}9-L(07dfA}8>Vn39= zVvV;^ZjLu<;}rUCv@7$F|8#ng`iEsaqlrd&oc#BjZrgVIw;hUxJ;Q#do#IB?4IwvO zkg7%K%Rap|`kLS%&lmyat3~Y;DgX(rGi({6?|S2?T~J-=H!I+3dPm!TxQ|V5SWt_5 z+ab6_PY8O49Ao9iMeRSqp9-i0R5>aXNq`{xuSNo_3Laqp`tX0)``vEmRQUMXI@$kQ zZr)~_Uu=NsLTvW}>}Q{qEsuM*AeFoV(6>^J;uQQc(*@_mKXFff-t24)uU^dxknl}I zGdlf|`8EfCIu0PZ#cohP#WB%94^!juEs87DIu}3E#4}$Sm1+ zh~?YJaVE)`Du;z+vBBau^E)>AQwdo4PgH*^^1xrHvAWr=UD2#xKeple8+v?egV4=> zPDRi7emHMql`M@QzQ6B2ENmJ1A>O`HY5FXgRaig9gxUGXbCr`~dBLW<3NN z?CW$k_k?ck1F7Y_1dl(=7t$lybfy$i>~>TeA$a0lS@HjVJR{NqwE)@(n?(Pw-?U}R z4ak1f!`y!7yfee6gVwrjz6*GWdc=Mk{2ctU0g(|0zhmm<48-j%3PKO&`F8QvSwu!> z1$oel@&Q;95*46;P<7o|$2z#?#%1tl|8qJM@Bq{jkNU>RWdls3G||xhXO>1X)c<7z z5T4OBYim;*D;uxB?hNSc7ICkVE6zLEOaCMEBbO}#S73MW&}U8yrUmtZGYN2bmu3AE z7nJzKKXZ!&jsQBECFw17X*7r-oAZirpp>-v3#tFcCjTN+95#8DuPKx6N11Cs2mkvA zcraWJd&u*z+wHaMYQJf*|9#{2V;B7@M$qO}lC|DuA4UfSWun5!W~!ayQ@miB;stvQ z6=5%O@V(3FnImR?*nyrDhj6AN}_?0YgR{_Zc*WfoA81o$V9k?moa0YM@ zA;m>nBmof(W6`0Ln5rUzi9lBZI=G7+G|B<)*YF5yT>TH~-z4$&34c-Izf#Wf>~mZJ zwtrMq|A(|N2vhJ&1)hGkw#~y)v!m7DR7U?{We+M@VPy#b4qBtVUbYr&tB(gr6DyCIZI)NC?!wB)~mvsRs@N&*q3C0}=%SlGF=a z{Ug6XTe4jL&Jj?&*%79r8&Dx{aHdyuAehV$eiodUUcy{jZ_E zsQ%R?kM^vL>mj(z_)3A+zsQQu1f_H}7nG+~x7y5%Lgfc%KeW7;Q*qDnD+?U%G>UX~ zV2$8(tc!`^SoV7!i~yyCG*JOLE^!km#HhPHPTUC$WxO z(J_)-2EH!(S{;hY>B*V3tY%(SSr4*4iK7pi#&R9>C#B*gYLLg>H8!S*55V%g2z6k6 zTa~_u9zFH%QiQ;YW%|d%>9QCP*PyLHly;!eJwc90E z|5&7yfV$o|XZ#b%U2~znNHlG*HVBP(5d&cqteV}ejWZhPe_!Lv1D&CjsT9v}lp3g) zIfNDeWdLaA3w8+*1J(2DXifc7ivN}J2^RTF%5$&R5OKd4madZgQ~#a?AfaDrUO^d% zVvZ*vgu#8wofyqMx-rmhv2S0e&_To+05yOGqna_vg1;*GqdGTipP(s-J}vi;Y(o1y zs@|g^%goGv3cpL=U5CB+n-s)d!+-4%>p|H0M68qAXL1Ahe*yJx`|yDKwa8V)2jCHR zHM~FSKT`j5nDU=_QX`lY`DNBWuBbzrWFdL};yKzB*_Q6TT*;&yh1VAhj`iGu*jwLAt=y{Esi`d&cE45|ygiH^(&9S(;_!+%Ay>ecbbsw*c z#GpBCjoYf%9UZS4J5-} zAQ&Z>W`NS@8g)I0u=#N1hof>(0A)@BKO^jJY@64Fq_-0ADEpt|Kb8K3^-o`fgKyaa z7{eLbqVo?1hpK06Yb7(Fn8p$PBHYYQ&4&!#L*7~U;Q)vuCOZ#n26n->uCms=XD*Tl z=Z!a%4r@>ZjDk_cX@(B+b+G--2V)D%BO)ms(o@xM?P8yQkn1a=R|irtV!b*38w()P zPWxwPIrHt~Kj|OJ{um`SZZME4`vduJ_0QCi?g5z^Gj9I0iZVzJqQ?jO0@xY*? zH*NczGfp$o30@Liq#yDLBY=3;B>t*AWJ<3>4gD3b$(&|17E+#$0P=6)sN@*4-ZIf}g39jh^=ZG~mo7(Mb`e@TXxHdM}Xqr`P3as;wNOG89 zm?z6|t3QD4OR8UYATglv57}V!^ZVOxYHn?BZENmKwk11aWfQWHKU0NlC^Uh>@SuOt z)0rmUU|@?Sn5dYfFT#pMr#SWC0IP*&^}nyr&Lk${(_37IumCY&DNJdbOx`MH2lC;h z89)o0$_+R}w7!aX6$!xGf6pOMi2Sqo??$Z!{jv67kQ68}g1{@a|NpX_95<(*1c`nR zk{P8j)z%uXZ)s`sy$}7i@*8BRJ`ApMC^l)ZHHL_z!ACE~)o0v;FA$|@=se%6K7@4h zaWJJAy+JyF`H>)U?4+qKQ*nl7eb0P0^qV=Bp7>NLJUN=PKS*=SCP%IPL>imi9Z5gy zVT%7GF%Z^2>A>B-_CyD#-_9mHur^XO0R5RMl!g-fT=sM1n+B2eo3@t`m_g9IKb9e@g)c=P$3M*A(m5&A7uc5COxx)IKhD2X z`e#y}1OkafbF3xOR6@Q7D3<>xFPp>f{QgQZqb3;u@&7ip5(!;&VhH_E|BOk|Ka_lw z`?+!+{gQoVrnWUsAJ#NilRrCS(79*=WfQRrqOSE|6?kR1fE|#rKc2_TMDu4F+|Z0n zJe?i_bzK6WF2FOILK)DR*}x^2mCDQGF2Mm5Y2)zQeQ(ar~v9eZj1L zn#>=*cuPx5+;@YaUotRQ4n8k)P6dDfHRRiG!huib#WcyM@|GAec;Q>=bXpk}7?+>i zbmGE!`IKP9Ir@P+DCq`{{gPQFHSi2tAZFkW_FH2TA^%$ba%Qu}Kd=D;-v=82833CI z4)O(0j6R=!a{{v6_E4#)HsK%y((n3aE~HgoMtRuWGn+PK1lYmU5RV2hQyt@_Rr|m8 zgz{?+(F=E$x#xp)1?%?PT`clR6lDGl10YrtJ+f>2Dw-1|S1N z+`>FpIC9h|3;^;!8|P=FZC0wKg*jkO4FB)tB*tb3BwP6IceLBO>BkakUzXorkT{_SXbJD$ckdIZAciFoe&Z`$;~M==~Y#~*`7 zngM`Hlbr@Sc;Rm_fGS)kU1LVE0hImUPC0>s5#j(i|JUng|Jw+bKiU1|Pek#4HWC5a zN{mG7tbq6Zd;=5xGvrv3v;s&26nJ5xcZvyp;baELL3L_<8q3F2!UyJoqzXvyCVuBV zdygY}j{#7_zcy15x@bomXUNxXORZw6HqAt2f0!a@_CTvod^Ww|Tpy4G=rJ4qSl0hI z(2w9Boov;Vip^r5FUvjt)KtcQoZrL+;QKH0C)oozyE)PrZ%MTTZ^#2OYyE)D2)`lF zhM0aGB;Ce~H7=XrG}&rd{U=rl?f)FjtAI+;evW?WekBqyLDeP%nsBqU{A+MXuL_tc zm{}b?#{y9f2KImR(V(Rp3HaS^gsLHDKY`E ze`NY7i#s9piYnHI1sT9*1Y`%h73@KffB@KJdsgGfQ%=v?w& z1}c4#Jknf6%4lk4LT;bNf7-vOocyoB6z-p3Q|gP!7M!4|a^FCXwcYpa&YS*El_iZ)N1Ky0TpisU>yL~db$ z%#>F$UyK~+C;c}ZAY-zzJsR>xjiTdozH2k#Z?TRz4z75@O$JC4|EIKg_`ezhcs)9r zX3Zisc92ksnR%wmG5)%rHAfK{=fn@=>M(f{%T+4i3q17-i1 zy$m>rX?+sfYCp+a8P5RCZ!92cMG6n5S9Q#xxWd9NW(3xYFtZC^Y_Fi!#(# zhU-U>Z#S3C1Y>!p`N5mo|HbFh*%WO7fCVgo$vs5mzV?%Rs`=3wLn}0ONeg5cAP!`> za1I-Dg*e%?1n8*(?4PXcU|CU&@r`r7eeF^7y`M&w|1XF0UpV_UmMF*b*FL-T<^+2{ zo1OJDvxzV~N>HB27ybG(a10}Ch`Pj|A%9Rz)#RTpLpH710$_L`qyI(rQL@n{b40Qc ze@TZDy{i3f9Ypi%oJ+%ma|{r88>I|p_ScL6U))M6s zEDubP|I?dCS}Z(6-ew$M$+meo$b$8Oz)b8P<9^}8kTmMG> z?L1fy4ap{`%>+GK1~8iq?A=;+&(IO6B3^|^mZNDuys6wsfRRW6x9J}$3FZ>N2yu0R zOD-GDA&+^)zLMD?l1zFz0jVt*A=jyCe>y;ZjPcJ+?zhOSCI&#Ii48*kU^qL#M0AF^ z_Pc#a7lC9Szx^rN&wZ7Blg=hIr1`a*LL8v1H39eMbOSBV=!5!$e*Ok!%dS$08I*>S zoxx5#5n~MfLadM&2R8YXlllhBr?rVt&v>#t;H=d7cbBm_-dRpWs6UWOvHPdBHQ9{$ z+v1*?l@@+emklig;{11!4}uzQgsc5uZW!4?Y3oHJJlT|teJAgiU9^|LK4N0sxv4SQ z-^7F(0WcoejNqT+rvx+89O-w{JZW6hZ?wNo2ZsJUvV4>8l;!`%SR=V!6G=k;EBynZ zi!R6hVed2fKbR6FTk(uWH~`UGSw1tz9O-4`j7beV71eTdr>W2Ig#{?hH#Ah45f=vV zMZRZUGJTd#tPQ#L_@D8Ayz@?m31Wls4B6v8TG7~rHY=%(nhfbir?SeUKE?W@jewS5 z!HqA%D?>SL!bkOhx1TD!te8#SCEiMox!{PuM(uv^;{^=F+b&}N_h?^bkl>JDq#XxX zbF7KkPdw%=pP6S=U%EmnPeaInpmzH=oBVTa^EW@4J(HixCc=pVl=SujnMC?ZG4vbN zm!|tuHHy81esP>FBHwVpG>na=uHuIm1D-Cpte8zc9CMD7k8v)U@)HKdNvC-wDfa&= z{)f=_GH<*&IiqP-VooataLVtk$&uz4iH5Cq^JiFWxS=2E`*OIXwcMu=)mKS|3~{q# z82PvNQ>EqKrda8Y(j`6g%OtkdU%E!S{fAa>CM9OA!Gy^SwvLUb%@yzy{e}6Xa+v#+ zWBe$@DH-u;2JDVimN#B>F|qN)h9VZs4akf;BiNB_Y#|$d$%*VV`C@?BK;hkRz;Hys ziA03_{}c5_F)(Or&+=dOf3YD$y59BOP7z`(V^m;E9^MX46F3XwC!Kg(4 zx3?#6PR^UvI42qFBvRsrd?Wle7gd?~U}8P&OLpI4e8EhSux82-l#T1g##VX2GX9Tq zCZ%c;SrhL)X^GgPbAvhwceR|nfiEFm4ij!?cW&qWTb1J zrowDyh{z72DvrqenW6vO_@`&gljbFD`J~^ppykL)k8T!oz8~r@U$n!rK ze%lPNWikC~<7m*d8%q73Mc(|fa!vChO=Ng)t8FZEj?NU@z&(4igcr!F<;$2{atT>`;LjVw^xSEFfD0K7lZbo1~BtqWz)dK%c#6}-h~8F zuR=Z@=-289CG7y0H2q!j0fX8xvval5xdtDCq;0Fn|5L;Xz(Eo{k@X7_IqZuLQ0XK8 zOOC79i%U$Qp=|$Y<7DVrZF6Ex5&wjebd`f7+lH#$d`qzkO-*HxId*<{)+x|je`J>+NypKOAQAZ6OH!6UK=|y zH=o1b%Mu)O>u+u(|8FY?oh4gxa$;9rltXG*cEh)|;}eU`;&4>L!^sU6ao-^MAFMU= z;hg#RDL=POvUxQWgCFmliD-|G_Wa)r|K>CeTws)R`^um}K`F;=Qx#E4hMa{ejdKh8i&QCYl$BhHhvI$LMW3g&sqe~~+SbUxNE zM_;tYQggmIyQ6V7p@6Iu4)*^H>FIYH2AVbF?MP!MjP(D!@>9P3RM!ptwtL(7{|x!> z4T`rEgwoB}{{KM+{4D{n>oy=b)6i=A&*XPjQ-C`C(<5ioxz5uJg?dRm_ukdInRg*OR@IvkIe3fV*$EvD6vfn zQJXHRP9IVHd*$hb{6VDBbpE|JdN&Sk^xt{*kH!u(A9QGWh*KMMgEXKxz#Bhj%nH4$ za&g?i732(jJR+ba+&(3&eBBHExrDef{q>e7ykvfEZI_ad_`QmMzC1Udlfkil2Va)C{$MM6?Y+?`DllZSwc1{p;(-{Wm0=o*4s0pW0QuU&(e}PNy5O_uhVr zezVJV2*mT?E7uk{su&Iov5EISHTGmyu1>&p7kRboFWA_@G(Skf1D}b1gnn;~w3jiW z-#GpwHoKiYa%H|6+5gmP>NU-7H#{IRj^3d{`PU?;ub3!GGyQ+*P5HM?`x;A+glS3? zudz?F1ISm>4l*GO7RiS#0lY!5ee}#As3Gu&tc@8Cp!oD|O!b2N(YZ{30ttCJqqIL` z-z-wS`^(#u|BLkxUyS^3wa{$GMo*pC6c08%(5_VS!PPLz;XjJfNQk|KKa8>De?v+Z)X% zMQsG4;3Q{Ud7Z&XQ4uS@9QBfbe&%@Y$`tYcS@{2n4P!feBG%D1i)|6^N|FPX*W}p* z!$no6FA@ilpI+V{gg&oEhCpPe%FjiV$xzuUjO#7!>*tD;my`HQs_`hlYbB8H# zbR8=0@0au8GaWPwgbC)S@3e?Mp5qW_7FAuvRHqhpA~ zoQS`<4c}1Qc_QEDo}phBg~(S)ldqv&O~8M9iP{W+gE%1&b_0>G(8RzhF^j}IF*2I-eJ7@I#P9}l1}$oWrRGTf8u ztG2N%?hX_w|Ieswt^fO24T-s%HglDKiH3E?Fbf#PP@3&6+7g`_H zF5#z`Y(g3UH3eeEOT0fxHtG5BM(OKW{uxYYNK&2ulY;#l@a^C<`2%e7MZ1bC--V2O zef9KzABTL#IOS8PJo%i=|JeT%ATd&aO(9JzezrBT2Y~rcEN{SRKdrfsDYgV~{Y_qF;Z?Vp+dy!)=nCe*W*;P_sXx&K^Fo$b^jO)}J;6y;pb)c-f&4>G{k zd`5s7|MIg)@?D-?7Aazu-^L6WYmd`z%ZhaV?dV+2f5sl|ogM#_uK`UhFT zO9+69xEoWgoc~Dxd?G@Sd=&Z5)MK+#10V6ca&j0`OgNgx7^mv_~rdoP0Kf`tuTMsYY9^8dd`xE@Z%b8oovWVNHt-YA;twR-U(rQ%(Z` zGF>#bG6#xBaQOSmrV#&e5J<84i};6R!k;ShO}R33X;v<*3B(D2(5~n9q&Wz$%o!iJdij-C zR#%T3r~lQLRP!=UZ{x;Ya)~Y$R##VFY5%C-s&%vOuO4?LFR&jChs8OS`a&oeBa&o!C>GD~6)9dKb`n8yO_2^N*_{FGS z?%44k|8b6bh*t;r`#jkCAA7z{8RHt`YA6^pdeo@m(ZC!-onutvXd9Y7j0PwNTjY)g znu`c0K^_Ap+%hUx=>kr0kT2) zWAG=Da&taNv@pQ}DN zR(0ms2Y)snKls4wa5(s@I`d~eR`tOdXBQ=XQsrPn|J@Hor%n}>pYnQ7IZksXfzt~d zDyjPOnGd+&IPLJB0rsDPcE;g2<~VaqP^&%wqcf+u;q>X##~dFVJ9Fmr2O#>vu@62t zQ^nm`4dYsv`1)DrDPskw0|PM8!3l59O7ws3s2ub^dtoENR(GP6*mvdtw|u2=bkTps z$c&rMv4J_Xyz-|IKvrI&)3SI)V!Zj;-Vze4lRgLma^@Ft$V8sAs3bo(hmbnb?dnh! zXI{yoMO|A7Xv)Mi4NXoZN6%o--_9Y0zrJ_rue+$+$%ch;7*I~!GOEkx%+KKn6TpIu z5_Xh3^AJNsGQS+p1{;`3Zvz(jI?FOYn{ZDxepYsNZtm#ZvcKext^RC`Ah$|?inQmm zA{~KbYrHn*bK?KKbPO8+m>iM>KjC$E%wmSv`lT7wF82*>ZZsx{;2zZ2+4(dQCrhx2DlZ$xfOEN*Y;sPY+sU%BuZXe5xrpPm@BR4Wu6w&4+;DH# z(k1tHb$#5mbn)V)UH2|o+QlcXeB9M_FLy2d_}380U|q=(UF_J$V_R09kLOZn7ZSn- z;G&Y;9Iw}{_k3qAr@H2IQ7q#D{Z2X`+QP|>cMiPcYy;N4|GTL0>exiKxdhu9{l2z% zxsxnVF>fFb`zL2Ct(9$-fI0S<+&4l0b+fO?Ykll7CB?^O91LpPOaRGY#|T>o1H{Ug zF+*U^L`vZRP!WmBau`T!6?rkVif9{}0WpCcMU|CB`CZOMi13(eSp;d>`I^rAO1wxlEM_I!>nkUW z8`hWkipppoRl(fkXJ5qqMeGI0!vB{&Hm}G@a13!l ztwr8h$zrHk~1|Ms0Bz>EBVv2_0-96MP+4x z=F}o~sB=g+(8L_r%z;iE>XcKGgJ71!b74ZSbaFdvLj=S(j&-M-<~j47{%i9`FHhA3 zVyUFp%MJ(TIz{e8Z7%!2FCCN5X1}02-`5y(`ewH#|EKkeyxRY5B|SDxjUNQE{BfO+ zs~|BHDRm>~`N(KFycKk?Vh6D=pzB~N4)GYn4dl>$Dv^N_C!b1|E^^+<*}`QD>K8e? z7F8~~%eTnq`v#=b?Bu4d^wkHsn{*7QXDAo5p^R;7JVWbN!W@K(PC+)S(OKEK`9;}z zMaVv>odlSVIu zawf|nnl?g25fji*yTcC-RX}2(okSBp_<_YGVIaMHu(q~LDaiR!8w@14E@9`OX^}>7 zKCLD62~lCA26y3-ck7g9LUXBz4i1t05C|}n)yTr581-T+!U+!aN+E%I@{!JtR1aWC zVng=*Va#&A!Hu!3E4{bPEB7V+9Dm*lB}In*V$Ovtfz_-Gm$m<|uR5>$e^Q(V<&L+o zD++SURFUKva&=I)8&cRuX@H^L^FfDwHOeh1PH-E$XQ4p+p>sMJ5;5NJZl zBW+bHY+-99$dL6LOv=h@A8pRPvhu!;GUh(MSO;qXzWgayYy2ZJFcr^FGzXh+%`5QE zxxNwiFZ1CD$68n!BXkgSFwqg?h>BWFMu!?j zt%Ao{XAF6LwXjEu44uZAEJf%Us0vDncq?Hr-5$y`jEajy>f)Tz6WXF#;tRB}i;o(8 zgmaV5QU_Nek>ZHPDdfyo}wD@h;DMJk8a!hx&c z>rUWU3E*INV_s@k75q{ERCtA7X$Enw@EGa@M%dg@*M&*AAV|+x)`H;H`U2XJOs>MD zn_3LxTM5cYsrS*v;_jjrJXVQF0;?5=y_?3+cHVd^lI9O!$}pjUa{h7FyBVe3zS=G4{9{De5|MK$6GS)_JyftgA@4nfskys;}L6{GC-I0j4Ou<-& zcqu*YoMYz%$AqC0STXgt1R8M`v0TXES>)4aTSW`1gVSX>PE0Ok=p>nzED8Rz$UyWd zh2%43PRV$JcGLhZHG!nUp+JILrEBDjK-j!R>IGhZqOlyMLj%N-4@qGezFZngts=wL z+|-itlH7xhJi#Kibd@1Bv|AaYp*Rj2vE==gW3&F}es?g*w*>YN?e8ittE?|em0$D7 zD3^2oiX>7>Y!tL95gy3^>0u^sP&?#Mdje3PDc#JDGDzh_oft<7$+F~dDI^7JgS#Sr zMjqS>J~AzUBspc!#Z13aYGA~a<3~7zs|*@pO`I*4i9`VFixn!mxjrH9KA1;SXhRO( zD)uDsLkl_(S|a}X1kwCtuHe)z9NMW=O9IQ)-xz7(U~hHOB33*7Zu0rKNo}A%z_;Ff zeZFh-ee-;siIl%JmW}^2$Hl2YNb<}-xGr(dzZuOB16U2>lu)uDm^=Yc2m!59T`~n* zXat%&5lgj4h@p%5TVjo=2!JEVKJL|y_BhGJSY;!pNW4WutF{}o)W%!eQZx;DsB1AK z7@Zhcy>UEoEreyqrD20KWBKHDlmufRL| zrc?^&mY?27VjI?WB2*knpmf!o5*ykq;7`rDzGU2(`&Og~bnI-)jG7M5&FHI~tD>AY=pf4Vx1 zp-o!JC#Y;`qzzH8wzrV6!VatG-XPmZzHt-bF-L3cVycQ!V_!jXp#D) zdHnHKa*v6AV7IkPuHXmoQVL7~4lEJn0!CK{6l{Vejg0|tBV|G=fl^F0wx*B+OzXxrl%f`tV=>$Z8I%q*Q zT2S>q^?rl|Nl*t7qPQOrawaJLmRf|aMY+nU9+xG82p&O>?Vv}S`uMrU-_lZ+;7P$S z$G2mvakP=pgIE@o9Q@jPUvN~xeb;?yRt*1l=+d#d!T&o_J<7Xj zhPpkAgPP#67z95F5+q*??GKu8F4hK1nh2q%Q=x++h9!_o6Vs~rR8!4TPpMWwHnO`2 zO-Q%}I=Bfu5UE5w0LJu$cncFgevHTKnZKhbV`$wn z_pJHlqsAp~`$9aM`1us9MWVL0@4Gz)Mn z)=FnU6J=P^)}CxnMQK(fFx8@kl~fxKpf~74X0U9dm$dKztO&;VnfEw7HxVi4g0QC# z>u1S#u%%Wa0h!z>V*!0bvii0eaF-LykuLPC`c4F%B8hZsqpoAD+O##bFk0a1QRPJV zAjh)Pu}&E<&;{6J?gT9mX}-TBx1c%f9(}F$zkjZzI(ydq>zZO1pHfChr|B=y(3k{Q zLZ%>`b%W-nWHZMn06x}^EWnc14)p~Hmw2`jSkpFZ78zvJV4NfZ7vP4lRd5M1P1i*$ z@F9gLn@%Ybt)(IHznypQXbmGPQ@J7D*FRc zks}n0#Il87THNe!p`O}!TLO;B2%=`>1}ZREEVaNK;;Wj-EyDRasT4_eVHoM=>7kMmng)`|JBe^N#+pr^Wx&@yg#?F^ z(fylKO>Ok6WK##v3nEmv&;dIdC1{LuI?yY@umacAcUzDiSx+c=jCLa<^|g_<_7t9) z5~gOU`K`It?nnM>=der1RF7`GHQ`60^9)pj6EFVydedydGGz;h!gO>oYX`|@G6X~$ z8x!rxDDB`uW%lK}xPglTJ+hQ=VV zPdy0LKx#h?hf*V?IAr9C}1@D%8aZl#}2nHE{;w@`T$2K z#f(Q17>6{!WXggWDgOd95Y!)ni+z=9fl)1OT+qN^V4^cnO(Yh9GE}!DI~wsvo0F;b zrkiFp-PDXy*YLp70#%^Dg_kTCIZ`!)19vfuwu3Hqpo^vLvDT*c=B7AlnK2fFP?$)- z76}LypcTwRXnV8((+$jY&GtFj8hK*$EyMkTN5)LrvD7P>pfM2?o0+5r03P%|)|q>? zWsME|Ki5v2aP5?9ubndRZ`V$lGI8R>fx3Z#=){T9i6>4BOg(X8;=sVnn&uNVCz_kD zx#mR8KywX$ZKO(SZEkNxCp0(L%+zl+H78D7)7CuDd}8Lz_uHCh4z$<3e`4y)nh8^D z-k*7*rtZYlftnKo?E{qPz=`(uw)Pr*u8Foqqq;!4;qXQG$rVK=*Z4)P63mqDb zQc)-qpy-rqr%aqOC0h4iZFLjkF3YlpUmUvVqKiWp^K$X9i_aB(r(9(I@q@nVi*B@k z%KUoKMHdazrD4PPq-V^{=0RTgX&C?X1K;#D{k*wiAlpxHUALJU%p-iYZ|0J@D%ckd zGq?zp?oD6U4}8}J`(_~|V1k;yq|d^I|Mta;hC}{^a)AREIBOYu zxvQsH6TkeBHTIf><&R9Y8ou0R1t%}Eu9YHmmHKq&4Hd z?^<>9cUa+D)>xmNcCR&g$um~-ikGa0Mf$=;YvL<|alXdN^J}WkNhm~0Hq&4G#SFIbrdC3;c^e!tf z^8|N>xrr+IT&FLDwXNT2eSXCzE46f;Rk!d#>!vq7ZHd+N zjn&rIAKMGPo2==_eql}Ndd#|c?Gx6ddwZ?$?0c-w&Rk?&x91J(h8I4xZdv)5HR;X= ztR`@-z4Jk<`fJOr@vV1R)4sXdx_-$ztM&B1TQ|S|@7A=VXRT@9SZQ5<+hVI0{H}ZA zn050%{KmTe?)BDncdWF+>yKDXM}KBHE9eMzP4lg5n!j!(?&!9Bjo+|J!!1_y z)_ZvFb}KmTYgR?mSGfKqD>!4WRUAxOqy4p3#H2jj`mt4YM)@QOVxg;x#|DVzS&s?hVna_OY(k#7Z4d)W~>6R?} z%B7i4+(NlTkAEiX(&0R+e}jde`Of32_fnv6@9?bQ7iW*KE*n9j_B=M@=ZqZ5p6r~F zdHFdb`I0*_pDp+~c_VX1=HwReiO>1`P*9LtP*70F&iw+uF4Z<~kSxgM zff63bEhrY+WrevTg?&k3sWX@AuP7?Ha@5GNd2WZ33Z2yBbWtZ8N=scirdDpG=$gyv z@;KQL%ho_pDJdjxKq#6=+WMUQYJry1gP+cA`Z=$f+>GXs=dZfbX@pxR-(U5*~)_@Si zc)NhL0<)aCpKE zwMExWsgB2|MjN8lRiWzYFsL_#c#4M*j!;;ri{NRoX`i1y{qr-XE9lk}@_GVZ*R*NV zrt8`acmwAE#?yip3Ws3;?c?>r7wQaGRaZNj-Q%W2tLm$&stYF!&qws@9o2O=jlB5_ z4sHlnS3y}_*i++hc^v^&f@E+V+8V;iNrK)o^Oi5R&PoPEKWv}W%C(s@TV_n3UgM!{ z0^A<*G=wWco{)o9bcCzx8>lBLq-tE_ugY($i-u{=c&UH*I68;R6RHY-DL4Ars(6S{ z*6ONgJPxxPV4wr`d7RW2YH)>IHDSQd{PLG)w%^kF`PSKAX_%Z0Po53@Tevjymd{U{ z7VvmO&IX8flprG&@By;nDb_1_bLPyQH~;np3&-=Fl1Nlf z`tluj%$Ya;&IJpb5)&sT+zrHryA#)67rps&U%&dgV7w|?@4njY{@l&{B^Kq}&=6{> zhWqhQY4-5^!qSS0aCm&vSHt5`iqch5y*UMid3jQjO41^IPUZ#DKIGr^jgEQWoWFR< zf`v=(y89ke?!Ncl`{vA@zj)dG%U9f$e>XSf+mG-N!v)DZ3UWuHc8x}6kO{k@h$su6pPUg}xAm>&uvCh2Xi<1u`2^KS0L$)~usej)hu^{rmrx0g2|vU1gfPY9*%2l_iZNf}0|K;Gg|Oc#&B z|8ZU?QW34Yp(iYF0IqB`~-A3-6E;={5FdBAU0qf0eUHx7Chef(ULTp%T+GFpA-gVmz z0?Ji&aOcjQ+Ydaq=h-`+U-E)-#vu+pq94*9eDJ|l{PDW7d(A$o>+jsR4aRnM=H`{S zP_-etd9^DtyvPOr>zc;bp|5?0`EUvmv=I;nD!i*@_ioq#!*?Gz1P4@hzqs+GJ>PzL z?&9z1+lCErzekO3B+r0b35-V@>Yb6S38lqhv|?R6>@B?l z(A!|szQaPaOB^sQ&}|EG&sw2C3%t1C>Bkl#1M9cHNaKI|<#|iYH%T76@1gb6MW}Qi zrb|ht^vYjuQErLDK?iIII|^UPinv@M2A=9@JnZlp_&~Qy*EaRJp*^t&37`pf?|%B} zqXM~bBeMVfxwrFW;X=U%cn@ML3=G?7{=*5WPKf@_*L<{IR?XCTf$jmg5kH{{zFYe2id2`WP@RxA=-KJdPdz;kKK=xZH;Q-7n$_KX^kXVCl|hTx-+v^hsJOVIqCW0m zEG&Fwcut`cWa{GMLjjlP_;D146tGYg9$je;P-k~HBuNw6^lv|~als*^VEOXpsNxN~ zjPS2|aMh~EC9tTy?(VfBmuf_cp#|-J{K&}sktHryeKj_m$D2JoH@6gZz>x0^S5)-T z;(9_4m}i7Sm(77S8U%XQK&C-p_r{ktE!eUAb#m*!u@m@4Ol%``zuhqM(>JjyQ_5X zRl`%o{{8z8+X`h%|MC8{D_7{E(izu)@jiB{+z{!Y~TwQ z9(`bVNt!5v-4VS!LKt-u>1*|m4&$|p3e(E1y8KR2-Fj=8t*SV58M)6lOTNdGtBSFIJz zhqswV1Pcb<{;kJpdzGAgXI7CjbQYT@L##|RXw0StbaxUbZtG}X@l=Z{+S&*!_EdY zj{nBOQg6s>PgXo9%z%x>w9hCanhi4evt_|FAhz7-97uhQTpCc=cn$B$$xQB~@Oo&Eda{(((<=FWd~xy}?ZC#>!2 z-TC&LD-OQ#`WtU-=W`FlPdBwO-7y%jnLjK{G4l)aOOlZXaj4&roW1HTl{23@e;Q!xhqr_DwT#|QdR#isWfEv8=7we{VN z@7*zH{<0l3{!)6JYz{2qWycP^APHEyUyX*&d*FfnX{m+#hhe@{w;7ka-x-;U=ORRl zM=Ly$;U#!V7>wiJVq*Tj;k<2etz6ap!11nqMt4ey?%%czP2PFx^t*HB-Tt)ftzA?p zg}h<=LkE^HC6GWuy-hqSU+utndwjn}4&d{rw*7$icUCy6)9?!mT=+La@u|$y-#60* z<}44c;!b7_Mh4*FHW8$er1SWhQzw_1sm?+p(3pEDgagZ%6UZLiDmyz}B!)=74PNZG z4dNe;%f+RlDH!~Z48tAA{Hv;JYJ@oKkOohy52_ZGYdwV45-@0|V)Gn}$^h;uqKzll{Vg=B-mG*~Q>UzgFchgE{ z$fTuuVC5`^2{zk$D8o~vndH9j_6fG| zlfb|*zV&hW-88rMAKt%>DMZ(it($F&$>4zU(Gx$+ky8 z)1<1J%1zZPAAj}85t*-2g{Dt+z1#oZ>3&VUO{GFZ7SV?O(=u-D8`J&%`0>r^AU1HD z348l`emJs}`Cl}ItF59UGCZ%iA{6j8)P*Nc4lL5#!O$f{pTL$}wW`}jK)v5cHg%&> z`UO2*H#4rDzAnaW16b!2Trl}+n;{G#*zEP1Jx?V zmg6ONRaB$=qaIK8@Vt_WhERjtLz7Y^y2a+c?ln!orM+r`!-o%}0T9D&+o&84^ojwh zxu?4i&cB=P_`*@})65r-jHrklQ_680yQKX!{z88#eqCH$4XH`fK4etQ*>_k(xdU`7nC09PUYU3y^u*`Iy% z^I!b(7khN;dq4mA#~+grhE0W;_a53XR zuDB*ErvUk@jst(@H@`XmWV$T2%aQ}zZI?>-US=+;UKsShck1I`{PLG`=00!Vzj*PI zGpEkJ3-uJ(-+!ckFY>ct_m9tFCeGugCspm@J2&p`?OR>>>kkXCc%#vJM??4(onTVo znH-;-oYj7E@o$zb`weB;qpwkpJ-Xznr=FHcvATP8kL+^OvCuyP|MHx9ix>UA3j9{K*9=Wl;>0on5xEFin_u?4`N;4dhxk^V;q zgs=I`$YN)}(-2S1p4I;7Yxm!OzaZcLCjPDE>v!R$Lny0?z^3sjLTRV-B1y?%A%r+1fNZ&!!wL*5YcKZZXI z0AERde)^Ag^}hM$^4Dd{?WD`_#yGQl1)YaB!1Z(FXU9*UKJ)Wm{tgSs82_Jq^2zDb zXYJdTFFz|8WRims*|WM=j?&+}t-A0NQg*L@;f00kSFHHgdp<12p$!7Sj||T#WggrR zZEBo7efp1jcVkN)e1o!+(tB{lcMraC@L&dh-`=f1Gt^^&>`=wPrhM`VIO^-`@4dJ6 zv}ya5J!^n}`?2+^3Ri(@d+|Gmb}ZNTd+z$MIDn@gtH&`x^M95Q!tt-9W`FTV8#gV+ zlF?YceftJX+l32X&=)3t=sBjnef>ZC=oi1cW6twW>GCI^oHZDH^2zreJ8C>~r%(0E zRje_wuXpo;H$iFz_3YXuKj9{P=Gce_e|pzF1>R@~4HypjZ_H!(_sB_UwE7fA76dzWwo|3(QpX zOh4`#pg-~86CnG75l^|Pv5+=B^9*LA42PfIQ(VY0Nfk2ySLLwWVixwoRZZd9lRp3Z zm!6sX0t-zTo?FOl2>&x0 zc-oIPJ~Q{E;2%A@d$&Yp<9BXfvOr(g+3LGz_3ll-#Miz+4!^VNZz`uh`o;6N)6Xcl zKaB^7i7IVix7!A049|Z1KfXVAF*8QW-S^BWcCyaoh5r*S&czwS@>o;Dv`MYMe|X?| z8c9ro`@6)p?`Wj~2M=X~=-Iw;09XG}8GG*`?(f2Z_n!Uuw|Y#|QKkg;R0CnrOr1Jj z{0=_KZ-4&|WL6cg_|-l4;DE;G;X(&NKmL!3XhYTHw7}n^6j4|%V7m6~_wShdq%BwL`+jv# z9&2{aaFrI%@V^w6Ivfpke`uIIZPM=_{y_%5`hRcliyJr1zf)XWE@NK^;CXm{@v()H zETit;?d*K_)JMM*{c;1O#YCn7g%Rjs!2b)X+HM{QvEh3&@GmYXDfNVye>Y5?-TM2D zn`}m|U%yUE3%v)-1x;+|08m8xi~lx@fRDbR2~MTyU%DJLA>M|)p|2PAJ@d%Rcg)j_ z!Kl++u;-u8rp&7tld7JKYl zUVq*2{$1dI^6_s^E<0pgQ5y`N^3~JnHgA0Ik#FBI_vE8EXjgo9#dm2_8gX3Shs?RE zC4ZsNgkc4&poZ~3H6@eNf4^xDsIs;pow;u3hF!F_;G?v9%#=j%f6gr{q{lYd2)v8@ z{W9|ya-wFJW!Ae}DW(II!ug5!-{t8bzp9Z$Ii9a^-iZJ1htDEvefp3~rj8nspDZjVF(pr4^JP?YHNVI~GeF(4v4})xAZAC##Q$ z^ZMnVoM!krefpC#zxeI%<~(WBf9hw)vHXON%fTlJYW#vkFCS~{@J7k7P zjs5!n5%9mc>}}~btdHYcx>w@FTDcPb&tGgL1wq=dfu+*}n^>m(&Hc;oV#%E~p9Wk` z+2ne666)|)<5wDIwBPgGGw60a87r3K)_VAvJulB)BCTpqA>1}9ecx!TFa{7PXJ+Nn<6gigH&Yc@kT=VXfq^mZ(`78`z-ZT3=wc~9qf39D6=A(~) z4)MRk6Rd}pszc(V>0c}DkMdh~%#1kOS*1I>=aXkysWR>HVa!|8P=oukzWx>b|17^p z->OSapLy?3_b~pyhPW+Xznwt~KaZK~tMjdtXCCufGrO~AWg@Ov@xs%<2mG9QckU4N zK$q(pOT7xh2^q&M6^y1H=nHH?2APeW5fd~(b0F(O_t^$LU6 zR~Ut2LuU$#KT^ao-1K91oRv=Gu7enr>y7aTc+J1WqAfDPu|YKsh?Y0rIJg```UMm# z$VBeCTPyI@(FR9_Cwo|7X^kt?6#qkV`sW|rVb>%@#uy+Ik2O^^DzhJ%)|y;&GR5G_ z*0bgobI%HF0c=rC{|tOqJrI?(D`kE3^q9IdqM!y0u2VI`&oD5E^u7Fbh$D8Gc$1GdO5-rtea7z zyL-h_YEp&kxv{%@!aW7BoHb_xa>9)NPKTG}hq}o%sY#_6EE+%Tu~zm=pPUDqwH{z- z(*%6~HZfsqe_zio^omhz>$aX2@8ug%k(Z+D$PweN)=0pgaG~g}GLL9G=00_y>HzjX z-Y9}|#=q6T3<&>=ir|6-|4=-uS8q1HaL5+~(a*3Cc={MNnsC7XrFAoYvBBH3@c!dC z?4^k4zCgCC=ED!sIH(*4v%hKw`me;nYVi2F$$_StMP`^0w%nb5cIB(a17^Sr_&!-3 zIH1HQsaXxFv=Ru=LdN%I`)Je+STnJ8hcR8aTmOHUhyMwMOC(ZAZ-N_`)ld&BwQjGUI&_`JM7^$N^__6fUXA10?^GoV0>(SU?kS6aT1{IhhI-{xDDe z$B+l}KNR)fm``9~xM4giKn$e5_4R_93&;H871_AA$Mi> zHrqpDQ*UrU7jLGHo^Hkie7ZOlg~11T@;Eny8|rX@Ro<9WP|9jhT@&u`@IM;Ar}2Q> z^skiv(==<^|B3Hs>#5U>;zJ9jnp$I@5Rmhe@<18^{GXypben>4F8?dBQOr529F9ut zUvEW2IL>hBEq&jHuUGTP8smVr;TzYNd{3uN%bTm3fm{|6tG3s_5Sh+dkf^5@!( zzx8LQ9^SO+oRbI#&~p#Vvm?uIo9%u#-d`br6SnKf12CTv*{tk{6(7j|UlAwbhL{`w zaF(A5Q{yXve`CZW(^4A2yB|n{-)DQ@L1Ev%)BPJc+!L41e2Sbpix=~E=K)W=~ z?gL_i7_e{OmaeT2Jf2~zmd97UlT*O4R?Pmx_2FvPpYVUefIq~Ef06%N%ra%o;jP52 zpmrnx8S?wzedyumPcB}9o9NEpEIWq7X2+og3m#pzWSP8cJ*&0;!Tm;2Xt0p0^2mPb zWMSH_xaS?oKNe5Dq8%f{@CD=kioSKj__&AlU!y9tQnDtq041ej{=j7Geq4Hsmn|^m zwfl_&X!-g#cRY=E3EvWSzt(?@BUr>6+|BwAzzux5_B$g91q~3&iTztKVOWlrs7$

Y&L3S}^sn#Cf-f`&Z?``iz5o|_N z6KE#r6uq*Xn_mCY%Fe2hivRIS{Zx4!z$f}3TotVgSA{%j_^bi;X#GzvRl5}h9k(i- zNt%(>|F_?MVY${jjA6NJ`FdHo3m2}FlX){TYcD>6v3$YuN7@KL*@LTC|EB-3{1(5V z!7<@R^dIj3s_|3nqK>OFoz-6dOyh6pK(6-fRdj(c=-qt`e+MJ#a!R<#{4&i z>Z>x-qyUA5_+SvgpKmX%am+S%FXj9XW0#Dh;@~e@| z9@ZcggJ%HBvd6WwaoGYEpeROlzA8JxK(<>!E?L%p?Y3P-Y`db9tDSh@T$LB+U)09YS&!GHXJVVJ=pKyLC;kcq`?`#=lSbRHU`v<$*(foi!@Ikg$jo12hn_$^ zu@H~UJ^7lk@UWh2|If<38AX(?2uil#8l@8APf&k^oYCPOe%5~o3XVp{kFN@QuUOOF z$I=0abG!YZ5o3W@L?LcHyj$J9FTTVy?M<1K^6xyeXU;d5F(X>Op7np0SrHQG*qb)l zL_vm;1_8xiIAs11XYGs(FDS$pK0bcKx8TNA0zdeiK>$1mK%&01R#x{z{)`U><@5Hj zJLk`v%cM=+f0r>H?Ug1Fu*pDqW_YQEfi)}Pe<8~M5B$mhn~VMHh)%7FM{6ps!px`H zgs`zA^#OA}6M{wr0V`;x{h21I|5M()|FuVt-H$DdkJ5I2X!@t&Zta#d3+-wU0lMLl zy*c?gjDL!BuXfZBe~JC;sGC|hp5AZ;;5+vj?n`m$36!b&4b-dqDmr3y&t}_AWwft( zK^LxHZ^OsfGB=A|eLQZWse}iN+@jHt__GqlKaR)x3Kwhr%N2Hn<4rd-gq>FywKJsc z^}HHWMOaWP^1m53B^(!Mn+Loy3@}%*qrl9~@PH{R_}j4cuD0wyk~^-jG*rRhOPo9L zr|5sizgusZN(7qE^cll76T-sX1R&ZaU8(fH(Lb-fphX46;cee(CKtF#u*8W#w3WEv zuX&XUR1~}+`1`hW_Kzk0&{NO)Gd8dHmEq$`Dscb3RYf?cGadh!9&>1ceub^9U5n1M zxj+Du^v{8`5ANU!xmCb{(eMSPH^ieLeYTzz{O;9zfsFc1j|9}XkN8uC97Rz$4UPi; z@JdFXXw@I8n{de7oEBBxw;!XobKe@RgB#mfkr~vfYIg#kxuW!)ag(C|U)!QYcT%TegyD#Wvhsb zAdnjk017=lhJO5wIQ7uKy*T=wyPfEBjR$7pWFC?QDM?%-1WZV+mTy_bCH}V55vpn+ z{#WsjBbf^@_z{jCcHAshN$hDWy=pj5lVelPH~9b1b9?6h2K|H3Yh`6S8u0lgCIW(x z6jL%XtH;;uHyz4!LdoLTk%g@IY5a*+v;IHQ<#2>UY(FsZ*Me?fgUR7;mJ!5E+Q6PZ zuo{nBLn<%h1E$Y28a%RR?(N^x@Vh=eaTHvrx1aA80-8a=d?YZJ`3D~Na1)a*mWwSUdZKf!M`JJ7-4iB&}4_Yi!yY0sXyCvnpOZ|Bb4-`VuY zv;Q)0nG~QMf^52}!65Ve16^Ct1I(cg@7uDE@gJ8v_Gh>$MEp-4%K$8Yu=Azb>qGun zW#6XR^M1Acbn&A_EZv&?1srM;xL4`%#hv%~JYux=99P6K6 zc5?nn96%~&jN)L~KmCb0thqhCcVPAEZAT=9YTeGVoRU(4f9jgd{)1s7QO3Z>9BA;? zn_GARJe@vGg^5M6J2hUt%^TV2A-9^u9S;bruRB=(Ll;R}jrvv3Cs=pr^N&A(Q7HKP z_7&%{9jJo+7ew5+*#BeppET4}Pjy6pn9q4?oEk_OF|H^(GGUyK`J7NWqH@H9%3-ez z%YNmWU;p{PSRugbHozrv6uz(j2Ibe6zVgbjVZ(+GpD-daA$vq5GJ>Zg!-kEUkgaMe zD z`7zVh#z<6@~1-;I}XV@c%v1*USz)?X?1O7|DyEGA%ZJ`cG!WV$(rq#*ElB{M9ZK6`oR1Ws{%wX&TCfIvW}ZvxhKtrMaqn6PmI4 z@%R)@xVT9B@50ySHz$Y!4}}4abYh=_fJi4)P8$>1gol^JOB>^_WIvu~nzyFL#rDhM z888I=yc|5}ts$bA``B{E?P@--;6F8JN20xv(d#L7x$E*LR>vLM{|EmW46n}n?;AK^ zJ0uK3Oh`Qh2h@WCZ-EL&7*nkw>L5TIw;|i@ya7Cyli9Dpb~|S*2AUq7bB7-tjiO+- z3icm56kgN7)|xQ>1zi0E+ku<*AM$j(Ha{^HfW;%U|FZsbmH*w$jb@Wtn4ODi1rU*! zgwQ0$3AXC6MFi%sQibbCyBvWH!CpRb6YvQp06$ITnc7tc%)JsNPqd20u8u+w8{R}q zDB$qa)lQgLR~1M9v;Xvuktrwx0-|xmD-^z7YxCL=R9#)q({Zg%f!kDV3~XSk#M&`! zS0%R8;7FiCO((gV>$+3FKtGL1oC|^eT*uu}!*VxMtpIWNlxQ<2Rs~#s?Y}MhZw2G9 zaSu>z(yMOJe4O!tJt_>$tdq%8!+0%=74Te$z6FM%K)?g3Z11ZN*Rz|fx=GM6EO=)| zQAJH~hH7{m@(uMGcaSSoPN=QO{RL;`sN9l*|EYs^m>zCm?_)i~V%>NK2iV54bQAS~ zM-}!OA?iSell3qPnAK_x`i#DcBz2u|eSJK7LmWaNnGH_J6tT_KaTrU;bA$GDIs&v5 z@T+bryuwj_(b)X!*+&|PSHVc?!7VuzNO88OMbXjYF_MHq9qyT_@v0keQ$iv5aSM1c zYZag2R8<`}qSI)ZYOoz2S4g)w2fko|b3+?I9Z-%`GvoGF1U%R0E-Jq)Kd7ycVQske zvdxy55HYg436}tzp!sOeIzCAXbZ9w1sx(;B3=mb}Vf8RnkMO`9*j1(e!{#zYSJPhb zg`2{3A#}Wl4W)Etm$nkKD;F-*=3Hi7G~$0pjJjwPW5tL_wqE$-WkQ6n6pq0ekv(D* zKTWujOCv72Xv9S$MobtnOvmJy`?I+(@(K^}1HW?hq7ghe%sig`$}ol`ZZvh7i`Tr8 z&5$%~#Ep@QMvTg20l4sffddyfaDf9CIBnNFac+B_WuQAhIt4vWkF$$|8yokbOss0-^=0*t+6U z>sGK@yIAdN@9yip_P+b;zXq&XU?2C=ggTiYY^*; zuSg(*z!V}-Wsuc~`6W`N5K(A0;VDv>xL__p8Dv#J65;uoh%hjTNKN|@k1Uw14o)VD zlxE_tDPv-Xt&ZGI*6FK>II5WVr*{$`V2Xts}SF7ACbn@6Hik; zS*_Vc+|)Y|cWE~f0d`dB7-E9;F|omdGCGJzxtRoQMSQKzO~gB~g@_QpD=7OA2}9g3 zd3rBdzFLKQ4P<@(5fWZ{ipUaMaUEphi+Q4+-pOsmH?@bj>rsc;17uB1HCeamAX$T$ zV4>Si67BADBoJ}QXxy=g?I(x~&--T{0_<)gMJzM#lwPvNaDcdJ_8_KHGm&Q;LTt0+ zBrtD;1Y{o}0b2$U3#yg~B6btcgihiTx{Y`xc95XLR}e!A&maz&cQXAQF{IK45Swfe z@yw1BN5r;LZJ$6)uB$}7<1|rZ_5C}3m~wQAi5;dz>@cs^^TfaZ8WY1Ss_-!Jh|VO^ zm@UL>V*y#KP9^@EiikI2T6r6Ch@P%>)e9QfL6#w|mm=>3 zS?Oycj;O0V>j)ETj^`T&`pqM&yh9NeECuwDK|JHP6Yumv688FgBxLL!(O-W;TtedU z+acm#a1u1InK%b-BuiI^khSIs#N-PmD?C*saNB93EF32Sf5hU;>>=#6O5(IuL7Y8< zNGM{|`N!9ypR0*iOc`0_xq-ao>_NDQvBz2)PF%b-e{caX2YTk96%7=IAYaUdU|uv( znDuM~{j#=3gfQHkL*J>cK@&b&&z?hXJ&#B58835jAp;XAjD`WT21rYb7hatE0>Xe{ zYpU(MdGqmM9->q*;kyv4%YHsSFPw)@i09>i@3xEV7cR!Hw(}P`;LgJNwo4Y`DJCO! zm(H7K`_jB6_@B3A$%2>Y?~V)RE?u@{Im?N~a>C_c!*X&!#4ra3dm9$p247ih4wvoV zz-DnB@T*c_9@N#f)u8hz#(xwB@)c{p_ODj_w+zQms*Fw328JM=0coIUET` z6s^)pMeElGhs10QS+8Fo48S5$$c9jq6dbKHD5C`ul}afIQt}0XEQQcfEtgA_0X#*l zU6fH7sqnD2WjT-Mk*(AwL9&Wi_O8*gfE!fQ)wYg=1;M`u@lcMrVx`uZCC`a1dt4i!}v96nr3ZRqXo z?QL{B+skcjZOwxX@M{0~QwicSZ zsTqD)?H$8a`wB-!Mkss~c5L*}@dA7u!Cm;GGT>=F4%V9)7=xuQE()b4$z3BqVQufi zQ_D<7wfjIr{opHuXhVG?b@7^kPs`{V>li=z>Z!wr51*!=Pfi>Sgz6)MD0?Q= zV?7M$1VZ7Xh!(WBkBzmTKUG{@cz(G5*rD391;xe1w0Lw9R_)x`|ypxl{ewgLC36wN-^&@g1aV$bGBM?|PQIFoCIBaV_Qgih1(Ne0z4FQpJ<XCG<6db~?M? ztfq8N6KID4kMYOUe5U(Qz~n2p?B=@!D76v^>$cTA7C%6id`GIBXnkdp!4Ojs+6^dx z0&nbNP|+uIP*7%^RDBd40k2F?n$7iqZpJkR{T}aT2wk8Mcj$#l_XVH*bP`Q1ld@ zL8_a>@5o4RHO6#fCv7B6v_3T2p7($_dRilNRxpP0aypPmA2 z(A%{ub`D~3phOlVxNTu;gLzq%Dq21Yl3+;s8b#4eF8VgwIX2!u@OtiLfSe)trpAls zdkTvW4}us#Y83r=2T!3x9%yU6Wd|`#=zdAfzina1brl53RFZdg(gD*-JK@^oq?sa! z4mIQ-deC|7^`gr2lq1vBI5u{@poexeU{kW8wE(eUxEw?S0RM`ey$g^cRRq3!!k+CS zihl2sZtYGCM>-ebwH+-$m6*(f6Xx>i{;taaSUm&3Z|wSTK_R6i3Lk%zAx=+YmjK26 zK}@Ol?CjYfOR2>1-7WLE9KI?gC2;M|7D{knC!oh`bR2-_7^0pSDxa<@1WT?4ZfOyK zf3dh4KQJUldkNsj8R$*Tt(a@>+1a`Zl`5H3{I2Eu4jhq6CQAf3z=S}_J$Z|_VCL7YRA?X+Y2+EECg+;d`ym6<6jiTJklLN-58nW9V8 zmSdWrMc@V9)Q&!265yL3JQy`IHK%N$xec7!JoaCGp0HzCAC zVc-XI=82;@s)zcAp5-$TC;(bW4$+& z*-2yL6(?7&@RC%aaQR@)La|;T`cN<0T7k;XG=O$-b93X+vjQlJ%;pC};BjMPePc~+ zO%y6{^BQ{g0mzvmugM`B(fST&-S6h(A0 zn3#AlIyyZ%-Z4BpJl-)rT|P}ahbeYwl-3>+%y>t~SUW8O{Na&}16LRaq89)@o1@q1 z^=`qtk@@6I8Xg~G_*VmF91LaD9#9@%z4{t_R66^wUcLHwdV1&qnuMM&9~$fH81C%v z?CeD5VPLVT`6K(q4jidg#Swn+{6dxhGVx}wggtOyIrp|6I@M=7$+qvZf!Q*^d6|I8UYaOTtL2M<8~L(^vT zDA>nnZ7%N7bY^(0@zMLXt`d-cwB&>57dwQe8WK0hcYpr*=iN`9e7^5S&y9UmRR#OT z(1NB$^E7I29(`Q$Nlh(8^q#`PQx^-WKCdd69;MYcLwH&@!6d{b3{q*J=!4k{T|+`7AAT63 zs%UQP=_v;A#-@=G%uvO}9hi7K#)htzKQ5{HQ*B;1;uM?)M>da)fEQJd3{4MWL_)0S z?|RaMe5XMZr%&~qDn2~IUC2#Trb+?>-?d)o7Ay*R_@zj7wQsz;;1mE;v=p8~1Bx3# zMtx)Et0f=*>Gh)g!o$Vz1;Wn7V-L=s??L$!AOQ@vj$!Bq)l?pBZ0s1XdX=)O_w5BT zWooMQw)G&EToi#fi?R0@som^fI^2kD#J*UV0-9@fxHw@0gNX;zk3Y%pE<9X)n4$-N zRFnqS?i@JuX)T^ZwrX1kS6vDxI`y`-t%G>IG~+{kY7HcB20nclopzauQnUe$kWKO` z3s7ImO3f1wKE3+!@h9hJY66CU1lhE60un}UWfgudE`}{3l%FaRNItN(wdd>8Kg?L4 z{&DBg<7dvJZ&3aA@y`DIec3YMClSjL{sTPNU)pzo>V~`i_-)BVJj?Sy} z&i(rn6hCJ3KM-Gb|+)^Jh__23$4bkZy>U6-* z@iRTB|JYd5SpTtOXA4k6I>eegrgwwFnflWXe(?B{kMo!((KgKWCnrWf{SJfs)ncmQ zP|e^YYAB-p8-)2w94yhNez^G(>c0)0Uq}gg_}IYf$9sTr+I5W&KK{7!4DET4Cb+`% zCpBN^KA{slRll03Wcpq0*~^8+48egS8b7jMWbZ1wq*8LAKRO7cszhDzrJDYM+{ywd ziO6zv0Q3%k3~AI~y;_ognZn0BNf|YTe;Hqknc;W6^H^5nDf)-Hyv9a&%-?!(c zT#^bzx97ai4i(APf4E+E;n*Rxk@hcTSh-JtkHd|ajs~Xz@^KZ#&tb5f$6!T&s;#8O zT^$+&3juZIqV~v$#sE4dfgckd1o#HO4}G(l8^S& z4f{>za@6_paIN;OOPr#_RA!1^0@91{8%M<(LLqvjxccTzl+X(KL@bb`N|Zvt=Lke8Kc(s;%BdXz zIHwX4q@^)N%ozf|d~HV1nP_Zo?4Y)kzA@UUnPSldh+#8k0;*m?G{gVT4)*NmAdN&R zdDqI8&k_9eUTShIm2W9*a0L1a0Tg04ut1q62ngaEL*JAqTn9ak;zs=hqlrvTVw_Oe z)ELzagTl{FVzxx1gjMmjm4gdklAJ6vMDC=8Q}9eH+9#)}3c&mW`s3+gNGvoluN^3W zX~MHUm~5xnX6g?ZSM1oX(g3w8An3NGE%e{ypHvV1sQv}vpH_m_9@(k>LZ!nYj4#M- zkkC5m_KMEV;qmbY=wOOBw1Mda6u`iT{?pb5`J5G`R3@t=Z(A*P3XC?rrwV*$^4vMx zeEDV6q={-sX#Q(JJ!pUW>eT_rXaAj!LQEUN$Y2y4=9$UKYiKrAPhhxfxo0<@B~b=l zie&H~5cK1FDN?^l+C0F=GpKz7g-?|qlu$l>G%qjjEEVpaB}i!<7Kh~cUN7XV7hn^3L4c0(E_G=c!B<6&x$t5l}hE?C%7;_sIu;;-Z4Y<25JsAk55y% z9M}Q&f#9LR>%*Ow3ohQcv2Wjv!fL7~75Ch@c(JE%aGGk@4D~W}dW~rSVBE9ga)MOS zNR_0{(w-xfM85Zv!E=aFFWTD1DPca-;3G61h`|Y&k&aPjlouC5Olx`t>NlE7 zYXf@)^lPwFTE;CWHYZS{a@WBA;J^`RBa<|S$hTnIF*8$N&|1ib8++<^5Q`kZavdccgDyI*5f*S!Slndk7s1^8;`X;{eEx zsh61=P@3t$XapAq_huxDvEk46Q9jdj@FX2zXaH)1SE%r)B8Bh35lYn>iRA7HTaHp< zNJ=sM0{c>1%M=I`L__I@HXRlw%Dpgh`^Nj96cmF^f_(diJ5S!AEE=^P2Z~S|+Fq2w zv|z?QBT-6CDr#SHktp1gmD=S;8Stn*eV9>-hK8uYVkV72dbv!cjrZ5S&wQR5o=pmjg&V@icg6)n7LHJ>My$b2rTemUAQ zh+#EjN*knhZu9tzZ5&^Bj2KK7ZEI-;icouMBBSHEVQA{y ze%O~ZQe~Vw=eFg17oj%UCt2e87R)Wc4P$bkbuo7^23$s?M*TaFo;^e1_g4256kMcq zgz11v=q)WBs1|a}zFk>APO=Y9Yh~+(V+HzPTNgLA#hq zw_u-lj4(!+sD0Z}>7HqdP^>ue>?VEU;7mRyFU{Qq@W-~Dp&AD|10rER>{(PGL;(~$ z5);@5Szm#n_=26iqdX$n7{~g+68KS@OquFmj!+Cz`fsQ|$jlTp7ZQ++HJzi!j$uiP zO4pQ>j&6HW2x%E}@r;f~4POW8&|#`Sc*V&{DA#BrA~FBk^BfhCGLsbbf406ec#yI3 zQBK1AwKh`o>cGHRsG+c(chK>bf06d_Oz!}J)GFB80>Ys6AFO}F$%(_m4um)f?O(Zj zq|vBW()AJCG^6%ybP{7`I@l+ZtFNaPoEEzO8lw{?0x;*X@y_GWSSg~yX?l&GidUWf` zy(={RjDMt$@YDBy{>$exAQ`yNUOr;dBbw)D`tX%2_wL>M=%c^>_0gj@Tv$A%EZJQd z=z;YSN43P1hFJFwbBtg7FOZ<$I4$_Y*_zT`FE}ZyZ4!B3j(E5^vHb{ z%Zr6)Y_Mwm>pyBFj&c4@QJzYu z9smJH;KIjJH`_(bcW`BkyD1^%A9AsNnHj0G-d_V+o!k=8O4Q5O)>3 zx&{Xeyy)sUUc_#0uCAg`HxX)qrFWLCJp?K?hlTZfjw5j6D1XN;R&B!i;0Y^R7mn7? zDST@{q(-ZDbW|wR3OR=(5OV@~0s%izC;>1x0Tz&hL!yJRye~%eu~Z%$jJ0b~pnxw9 z0tG^q3Ja!6iCQa^tEK2gb(me$R;90{(}89F8l^(0Hbtu8 zg|CV<%9I+7(iGtynGzWgX9|!;%M3D=;XOk}VzekaRi~FmC#I-URfZr{N^*)UTBT8; z$r7b3!e~-TIF131N|n%sCl83V!&yfEEOQFi252;D098jCBeIerHIW+kR}GC3(L zGbvef$)G|?1+Jo{`b1TtUK*rN4FXbv3~^beOp`{51EAd1m=3i{Nq|fZM9GEf07pf* z%W~(r3%n%?btIaFj@6nXO%cXOO>%N_gvn&Q6p>_%b5AxYRhLq-9zINYD0?V{LxNN# zGu(N2Nrgs9m6sw6+Dml%0ott8sHH-9Dme1^5}{J=D35je*Ne|B{mtXII*;FceShXN(~ z*JfP*_EVmVFMp(Ge#*;)GQx*1u@ihy+3xEZAKqo~t)%A&FB2)?{}_&Qiw!vA*c;~< zo8ae)^N6E&k~QiQvN{}Rw}$5vxAnR3JKo9o6|dD)5O>@chvgBs&>SK)Rudmn4bD9_ zz)yAukta9fw_4%}|KoM~J!GAsn(-xe-&jM$fZ-m!8$O^dL>9jvez^UF;~B;H5BnzI z{M=Od6T>Ii8~(=<6a1FpQ|txbWiR*!OX6E_zO9+Kn;IFPVjn!WCKhK0!`E1raF7IU zJ<9kpE3yZPyLvbAHUUmtC-U|YpX8T`G`5wj!@0zs`UYH0#6t(4XhSPuD|V9QemjUD zY(H6R>V&WK0P%=9h_hsOk##ZkM2hFvzz^CFKFa=?xEEdb@3VoUw(lp2O@kyEKD+ch z;DpA*Bo6N(+vDjs7J(o!c&Kr)I{+>Bkczy03#wXfc zQ%%D1t4TyrEiu;hk@cl!5^?2I#>baA6L?Q63CEehzFE~|Z9)lAjo)Ydc9UCzIkf7~mBFm~|e3hxMupEBcNyw+U{WWujuy@98 zqMQ1LglyRXzt|l_jdJOk*6Vk+62IJiBpklXCin;&AN)-8IFmR6X9{cKiyV-_mY6Y8#tdBaHhURUz>4O z^$_Ei99{sQb@*0qY8)it6)ntJ!WlRZ**B$xMAP$yL$;8Bv@-ZEH#2_TUho%R=AB9W z>AA+~<-`sC+G})~#5-XdS?QxE>k_(1IL=B|;XG)~#YcpP^MnJA+$8Jq+lEs3t;083 zhxV_M$B}iW2I2$X;oy=+5{q_n0*#E%w0Cj|S-%VCF~h%jm3%YdN;PCfa5V|p(L}u3 zFA$$>^x1_+jL-hckZK~^Qbl~>Yb}gQCeqY$vNE(5XBa0iXB2yNU4rlS3F4DAOq@e1 z&}QJym`9dMld%sVldO?iU~H5ktu$ufZtS?L|a_$k8=*@{WCaLBNgk@gE6aNs1qETaCza3-F=m>wu;XSZnH zA~+R0&RK%p9_Fc|i?qrWU^PJeuI9k^d7Ji|~ zmCxt6iC42%Q&--#9_u{UtmJw?nsyegb{09WW-oX1TJ5|{;O)b+wsDpD%KiKU{1tx6 zz`!6CMDdXI8^Sh(<2@oWGAJ@oDUXa)1Vu)vy*19WX4#9h(YlzJjX0B3Z;UnSO>vvz zHzy<}BqgV$rWp--V|seJ-ndbx%kb68G`v|(qRcJ2jI5aK*jRn6$z;men#%Z;7Huou zzTIThmz0*K8?$4wGRk)FGktbiFX7|)tgH-OHh>$-a}o=1%x2o2%57C?X(l5aMbpy_ z*)h6|YMmWln>ovxU89ZEWn}1dF&R0AlD&IPIf;d}yZ7ynPpdPPGZ_pUncD|;ILmyj ztZhV@zV$IWnzCYXh^pR{la#-Cb3 zn~(r+nC6z&a#X!UZ_LihYHQ2T#pIX~aKU1Z6JNGPpL1ZQ1YM31^??~7zP2u*t6aY~ z-O$!eBiZR7s-N3N@8h-9-Xc_R&Pq^?W@|AR+rXl(x)5SGODY4ssUZE zH*=i%Jf4%QCbBfWBsL}{qeqvatIlcdNRIFCZ|(0NFy$Pg&FazBAIOO{<(S1H4UgyG zdiZ6EWJ5RFFqqX--;sQz|7f|XYpB2ZP)~JRHc+QC8IAhAX10hwXO7MA$jc0t_1(Ja z>|>+4<41DqOr{eFuWU}M8_UWX)YZqBVq*=Z&L3Ab*IM?6BBX( z4)tHH70t0`zqaA^xU(I-ad8t}MtxhoZtUFg^XJcM{iMYMS}j4 zvyX^p?QmxDa%%jQtCx#YlT7-OWA&%cUwdO;-LC7!*Du!BXB*$VQI&i1a`EK^{jI|y zXWlIK?K>fFT^^b$oVq!Xl#r7%c5V7@-S(3w-+pyh|H*8FKJH4((ZYMV_tO&JS>q#m zVClfQ^KNDQ?%nU@=kBUa=rXmQe?PVM+*tkF=dah*>G$qUygAff_`&{%b#))IwfqNj zY&drw?SG@LE-9(^VcqV;goMW*Z64C~jGg;9zOK$>EN@L{&;KOl%I>tf4_TVk59Zj{ z(C5?A@(U}kqz#x%t(EvPhUc&09mH4A`?&A!L-a-0%=1p1*FN1JKefFuX@7i6^IpB_ zLj2U!*x0$ZKf}AJJfU}6O7Zr*y!@n`ckDAo;3sD$KmFvRUA2Y1eZ_Tk2E*XT@wGS4 zojdvYXCLjZ9m`2P`{YV(ZBkMKef|s494q#jKYdyB#!y;9#~W$=dc#-sUth0FJ9+Zl z`D>{I{V~Uk6R9`Tl9DQVuMFMd@cDDBS$8JCDY`s0m2kO#%BcUUURQszzoq5k*XOTH zP3d&?Svg59EeRDx@p*aAyZZR>EZH@$-5-Ksx*r49gzoJbt3Tb3FKKycSbxhZ%Qlry zVJr;vmwY=cLj76%JHh23Mv7@PM~k^F`oZ14cXsdsg;nbxgbK9v7EMR zS8bOm3s3iC#Kgpwq?dl{td;TRi1|MS>A_EQ)nJieae7m0^I#5}FN-wh#4sFAmk|qsXl+VuX-;~psc!rBa(yhg9?GC4n9*MkW{EXl zD0Av#da|mkGqO-@$zIdhBd-p%H{HEi*JUyqVzV-;vuF`UvyYEv&Mdae$d-D{2H@yl z=?#VwgDIi%jhh1l4VUv0x+oVgww0lTGTi|)Ka+1^H9R5<#M9mQ%fXak(4XikitleO zEc|((Kc^g%OL}Y;I2MYq<9{KWWi{-RxrJ7~?3fW#Lwfq&^43ql4-4Nrdk_>7i_SIZ zH)en_Wt^&!$t-3q*J!t7WR1pT>(M9arRjUWzp?Ge{knVmH#MXUpg9J5Z7j=f>$c-( zYUj*y(qu-0MQ+4wWGvZ>>cqWqB{wZ?_rr#vA>=oJa~ezZbiPyj$ZB}j3%q{%<qN1zy1A}`8)nG-%kAx^)J4^y!>ls4QG}m+ei3MnNN++ zkFLYRUc+9VZtUBL=fRb7Z@aqIIJ>SMX0ca$4LkF__`-k5G;?^%e)HD&@cH~2K40VW zqt?fjBjWSdV4`>Bc-G)oXRl!qUnBBb?d7Wd*AG0$|AHuxsgeDVsnz}<`)Nd`(fVX& zikvkf5uj+l&}M2hm`9ymUHM|KAOH3H|8nGg$KyTt{nDkU_`CG{rCYy0f9ulI@8&%C z?)l$;fBN0i@4kER-~k?)V`0JLJ^h~=(I1-8f8PHuVu0$YY+U}h{;j84;maTCnVz~_ z=u1{XZe{dR=%;kAsiSKUbkqPwj$JB{K@Tf{9=8|zX$AJu7Bf1kyJiQYkGkt?i7RAb z(S`y>=aiZDGCBYodal=|dLmC~ApU7xjP6PIyi%Rgb5k>M4%S0i@mU2*w@)gLbi6`ej5=%$5jsB zX7nfDEp5anvyHff6%pmJw@CDzuZb$B6Z;(x5}B!-c*jCt#=csro6|k9Ua`sZw`pQ;D&ke}i$LK*+*IS4Euz~3ZNc66Q(Ea)u{g&#pvCs|Up%aJY?IGdN z5q;xJVPl9uo6Cu+=m4{SRe$#f;-6R!`v7p6-i0<-5%ta{?Bj)Q{ptg<3A&-_{!fe^ z7E{qo6v-7tp4LOwZrnrsvWJK=!%V2I7+$y!y6R36n7o_OdFftfuas`+woN2#`vDTQ z!%S4!(5;hUhcMMaFK-~~Jsl(<1NIH<>-9-4B_XAaBy>A;zl0*_vNa@XH~Mg6Gf|D) zCLzbC7`-v-(#MScyLw|b;fJS?@Ey%0^vruC40_}`eI8j8T}4*MbwSrFAd%Qx%iEAZ z0*>A$GU%;qjJYKG`WHlvJ+WbcP4!D^N1%EnXYB^)tJv$Da)@w43ZSQdP54o%L~&w@ zxI&lpNbDmVRUY;+?^|a6U(6c-y=TpWn|5!cIdEQku~~k;+0fFoKd!H z;2Kd^cM;#s<-`;A6LDMzSrw84-Mbq0jeJJ$jw;$q;5tMk$$gAoFULOYP}m(5Db+-> z31cX(hy)d!AVHv8CG=3uUhF&0Y{Wk6Aw08>_(IQBjlE6$HkXmeJ)r5rF=E^cJwIU& zQKj!EfvI%g`5w?;8BwIQ5U+$5#?Iu6{k4kp4n{v+;S~+Llh+Ix3LmYl zEvzi*7F$cpS+gu=&v}kfO`m^$o(1649msfbz0_p{vS@2giBVpSR=G|DKdQsRIbjV4K@XMVN<_YFD0TXQouLtM-+(C7jSi}Zzs+g3Ri z7ccf-jrAC%a(ir0Nn}D^X<}KBCe45>hL9Z_xjf#^avxoKp`xNfiEW9M1wo-z)isI= z+z(OhwXZF<*tfq9?xKZ?0|ylKd3h#NZeE^3uW#5MYSNikl{Z>KCEOB}9;C0(S2VP2 z4c$`O+NQ7A-Vm3&HKcvTQa{TMCrLy`XV=!EiVCdv_VxD;v{h{HK6EIf^KgLk(qhYw zmj{m=9U6`^6?Tst+Y=R)u%X+a7|l37eEh^KwJVD)#>P($g}tiI3k~f)bvkTf;>>H+ zMd@9ytIwWGR5zW!aPiXQ<%Gnu=i;yAmR`M<*w+095Lj^d+`08piHY{y3x2lO-#lIx zUh=xSV9Sl0Ro%C4A6J`lH{W^7D=c(sC-;Jd?ev@1uDn`uH_sUK_8zZW_wFB03<-^R zXZXs4t?$lHDYks?{SR*Dh2AaGX&!z!l-K*p$fL5yK_4aLb(MPMIhGe&y!UZtW#uR8 zkf6ft-Q88y>guox#bcA{6D()%SjFX8Ec?_uJzb*-E>c#s4SW__`dNeifTAefsMBda z-zeuBx(YA9L)~(Bz@QeTXFaKKZ`K7gx{K{+PwJW%eT&}-=ZF#M~ zQ@#mFiwytCGXFtIdPYt|#a0qpCp3TAG1 z)A3h%--kS~(e`+sJtcN_bgZO3kGPd&#c~y)Ip)NV_Z`mQfVSvnW z;E?Q}pAuG75}CV9Kt!<7GPdjHBP0#-f@ViOBX_KhEM(>iuWU?Mh4o{40$V(aMwjZ{z5Dg#5RfB*A1KV zUSj7TMb^NUz4FVaWKnb$Y{F^G+)vjOX4{I0jo6>?Hg6~D$~Hy@5r*o?3t}Jgf-Ica zZrFr8TVVIyNtUhlCf4)p$gGvF#3?$1XkedT6Ol*!A&1d;9sU`;z-u{KlD?ZnV_qXK z*byR&A&!UzAqYx_K)ad5?e8I$Hu!y>8zFXLVjGr1Bnf3?9_onT7X+P7+|V}P)K0?2 zItLr`{XERwHevB3^t-3THmQtQtw3JbYF{wq6G2oCnZ4YZcz*MgI6$UzTc1U^5)I@T zluvQ%6-7MC4w4t8p@i71M0rVs%afyNjdZh`4Y+VtqjFO6?&2 zNe6*rKVmhPLuRuDWL{tl@z2>qHXZ0?w?;j>M>r@270ST_^ByM53Oq>=GaJ>}uv3>HC=&=5w+i8Y8LDyg^ zh-b_WvM#y=@mR{xFJ(k(*oEJ*o}}3hJ)ju(%ZLZ!>$peeGiz9$8_S7bVjbjpjGdHr z#-8pSZzkUHjf_4(?d8-)?u>PUmEIf4N|_$|2QFVDS>df?bP=vpi_eJhvo`GikW*ka zpKUScxmmNGpKDfDiXSp~9 zK_OPT!u}l!0YwlV&WDWhqGJ>{Ozk7#2{dAA_uk0k`=~{*eM3qKTepcHAHO*?At5m- zJlrQpxHj1(WmYOXEj=T1OE^xg+nSpfj_p^}(p@sEv<%KbJ9dWWmy5*}dHh}U+iow% zSuSPbJ<VlSpX5wA(*@`PJ9oeEaQ!;n|Mgd0+Vc2k#$yqk4b(d1-xb)WYvC{9^iZ z!(XOid;a>jzy1BM|M>Nvj(`2vZ~t}kx1Qf$jQxLoo}=@aEiN{$Kjtz2XLA>RqCYZ; z#;jVpCX6iPE6My-N;1!xUJ7Ez4{4IBeT3q$$bA^WWIM1dEU)P=C~TkTv;)B!MlJwC)`ZtisQ&!mM2;0 z7KWHS8_0_A{Y3xcQ)0mNg0q-7f|oA^UtA~&CXV5W#9kgjEap2A8y>#9g%DOyHQ9(~ zEnk>N=KE=gyLf9h~G1ZDc&BkR7v2a2=g<)hlVi9pd_mUO3zmV!>QJG}!Cr^ph3-bvpB#A6l z#Sx2-o|5_Q3NnW+C-%bim_ODNp1P5^f!7LRw-N8H`-xlJb|M4s7MivZfpHtd%KBBwo;Yy)hSyF)yqE|Mn@UBXX=Cd*?t_$b|lc zHQR;WTZp5F1~NeuaWi(3wRmo!n-^K^p&;uD4iJy*8p7YSjo7Xdlf~|S#0_%?-;_^Y zLd+w_wSi=TB!j%XpPc_J^ebmLaY0_nsSxL;)~BsQ#7f^qKJdP8ec8Q%9yQWv7esI<;cn6HCo^q>!9IgvIg^;<%_oD#np1i7)uEk^Q+~Y z7l3c9XKqL&3p|tYd=z1Mz|SDUOoZU?4!|)hB!O5XAA3V8SsAs3*nIkw*n=kRSFI*C zTsc|fh8R&E5k#n|Cj#VIo46CU5BLRSAT|~30m>pXK4YyJ^UGqfnk;pXLR_gx@b?Df zsUt4oyNOU;3H{p)n@kn-=G|mvP%d%R)e><`EpgdUjCI*!*k)i0&{d*uP$xHk;tc*z z{UKJ$7(#HYd>fw^skkCCvYF=VL#vdsVA67+34kInvL z%@G6(Vw|q-mXxd<$kWuRA(-YhU5z6 znM<{24Tnxh9J&z8r8+ZJnVCgcI{nPdK7UL;rDZ#ImUFmRNab?(RC2gg)ux(2>0WLv zci(<)-GO>;19o#AZ05FbTiZD89j=&ZsEW!Rh&gnaGozPcZs9-^jp0BKeU*FaG-j38 k&z_snJFi^5_69kUMr``3x0mnuiqyPW_ literal 110434 zcmXtfWmp?sv~F;BihF@##TwkLxI4uu65QRL;;v1xQrxY$dx0ViQV0QxyE`}EJ?G?C z_Q*3cd(Eu1UfBQu0ssy0-wy$R4k#c*0C>ayhlc*om_-EuAS6Nnn4AC4xSRt35H>>q zaC86f7#9H8j7I>_(f#ij9RT=}hX5cW`=9X`DgeM+f&jqB|DUlP3IOm>fdGipP?N{O zq`-t<3P({vR_njL|NjX1@c?7@avK1E4xlJ2rQ=&L)$NzUxNP|D&f|91)>roP$IlGypnJHOh$)x=+zjivbwBKm?dm2&1n+(l}zACgC+Y2iRE| z-|E62!x8n~D&OMi%MKqKzc9gH{Z;ptfU_Gkw7av_+w&2D-ZwU_k`$*fN!U3#8Cngl%jBVjgYG_LI6GXP?#rcYqa+?!P z--|{dPZ_9>%{{FoSQhP;GQjUSRg9fv-N*0g_=wo>0B&iN++0H$h_nhB9TeTpiP~49 zz4Z~LqKdhozD&VNs{HFhQN%mlQFqmSY6u7gk5a_S2N9mSFeFm_IJN3fAfSn97o-SX z78Z?%ot==0xuDKi?g?==i^^sEs~<%41Hb(uEhrZ~?#sEF_1s8?tG@YB#8PEzglw@P z){SE9qATwbWkl+W;G4_EI-o?}Ymp1zPAd4v&%)bVu_U^30$-O&sho>Uzrx^aQB-#8 zSS{Sq>%v`Da3|j=!wwmjrD!k+3+5KfG2`Yz2;1yK!L79tuirkTX{NDRvX83$WphSrq$N`6F2`O3>b0;*{n5Lf zVxqiG<^-(^a?FoV0i!@J*8s?(}i+|^#sKyO>+Vf6jKK#?xS zv|BJIoMh1l8_|$!fMV9$Nsl8>6W>;h8GfFF)eS$x_x1>*K=Zx4=44P2)x2a@Hu^kb z7r?kmItM6|zt*tfCF<#f z(=%8<-vVo=-m~Uob&Kw?#SEx#-l#`>1}E3n^f%#Li4lRF`uML~LM~GV`Mq4h7Bucc zAK{l?p+N=X)@_C5GIzA1rpMiaDQ{9eICt5{F%us6IURrQ`EV?^7E$gAGIywnnLUco zIBLs7KlEP`wz8(g=Q10Y$QluE_+dbAhkZr0Z`x+5?Y{4Mq`g7k#E#~C$ov<@h%E!L zx5>0gyHg!ZaWKtb!ZwMq{oun#3l3Z77qxbjK^$n($02hJI>z=U=A0Q zhc=z{t@F?6;3pS3vCLR*nkgl+!P4GQj=F@6pxpq>LO-kK4zeK8hO zMCqzh!ov*CW|<(ADj4^RZzAldjpy0-kKk++l~4QE-l>psjyN^TjrU;)ggd#=AHVXg zKL-I~$?ZukXBbXSkyF$^>vhj51F_f>M(sgTo!>CR=AY-m``~x#)BVrQIOv`&c&kbO z{O>Q;_2(s~r>)ZfqL-_22lG}?pAE(OYpnq6;QG_ulz{Vw!0QfXFlrxO$XVz4wToyJ zyAMfP(^`S7mg+Y-^7Ypd0@3&)ZjP%iBk8nlO(p?1Tiq`-TnyYc3Tl|>&IilFS6vkk zh>{iyr|~8AX?6|U^_3GcPBSv=Dbq43$20!|AQiPkpBHAtlE-ZUN$;~^j7kJ$zih8X zhwYXkz>wY+DA!TDxm<+SsrG7e3I0338nqJqvQYaxfNFl0N~!m1<%ksp>dK388jYm3 zQRNEib@IBH;&t>#S;^<`y8)(4DWNlKc~%sR?V_7Y`yG}hL`kDu-v)pCa<&NMAr%h9 zh-Q{8Yw-M9XlUir)?L*;)#c0L`1V#suuO{K{GyOoRY5sF3enajDf?nAfqYLGTO@Pj zqsQVU*+_hI-ej4cBL!+8%u)v0^t*27(_%{Kit$N6>jL^N{V2o?JQhF*-Wu>mOJXJ4 zP=gFV_8wB-JqUmYPDB0yLVUauz6ESv-}U+QP|Hh&Q_GWz0}_Au!X|XPo^kMs2i*f7 zmPPKK>!{3^8qWU+bfYAT`iAGXxhSrt>*$SOD^39$N>9q!m~bLf!trAl=2|;gdmybQ zS)`I}Hi-V5CqBk_@>_n&i>2e$L1<1bWaR{LBhAxq*FQ4*t6LbP)tk(Re$q^yK;8r2 zbn3i@nGWG>YmBNZG){{%A(zgS5%A+j<8w`78UJibnW%G@!U{^ZuDy{pNj=blls6CwP~jhFz?= z=?yesdpZ(r$t7q)q#zbc&~w-GzbM#`G|t9BxU>Nm=>N@Q$klqxd6-Wi+RM|W+2ALd z0J5g)FNhga1DEnajTq8~5yP2xcfKi>HG}U4dYMkwONkRhrWC7HTkn0y`@u@<9TN2%c!i zW%IntC8aYJbWLH(r=VyhnRzG!fIiduuyZdz(y-6Ug z7|P7kz=WSH^jewjF=^e-7f*S)bUXBzM4Gy(&7xN@cPvDM6Y!;M!5Ax(XD&cT%FCB< zu*m_(m82{@h288;KLbgg%&N<8o5}(3%y%29ts*Fuc6!noCmIu6@^vHRe))ED;3wAIb~bou7u*}sCVIn7Wiznneg+!W7&(A>?8U$kLP_%2g1FuQe8bgJ)? z(2Zk3ywPtQjAxltVwiBw(CSM>pJztH>ciKK8TWQ9bB@7PI+QSA`_vvJVm9b zM>mPJ-GvLPaAGzL`&}P1Zj8U{OJLQZ^4rTEQLRz>#o8}yoHy#1y|j-CQp`O5)GRDV z+LEFJ6`XzXGk8XR6cK0#Pr{_~pA0@?d<>!#F`?{nU>L`Qm6RXp|86}qC1SV{qhx-& zuSK^b6gV0=?nxZAhqpW;XUL%P0rX1bmaCH88xO4%#}O@{ywTi2`O-MF-WuVTQ*>%b zcI_m}eMaEXz`q+EH01VW5QMHeUn2)gM)ke~I>RfN%V!-lms;8g*Alh}~YHl_(Z2vV6V*P;fm9OBDmNndMm z=4T1Ys6@G7%h-x~8@>eN_l>!@5KDMj_l|OrV|}ugD&Rlq>{KWX`Ek1JsuEocaAZDu zfQP|^*?^gfXNG{0N^0P|Z#Kp@KZoN3=#*AXhJz@n?Z{;d76T0pd2X12&3x;L+I9YQ zHu<{u)pxr;h{`wwL)}!QpBLsE7!o=o79hhN8pC;nC^`}`h#TF5)V;lQ;&cA?G=Nh4 zVfjaciU(sq@oC`dYSDL(1kyOqC2BR9(yk%VsqGD?vXW{l9*Y90`N$8kv9b7_r@687 z#+(_=QS;bx2yxAkDo({r(fC7Mo3WO^#a1K7v2#>ntay#7oG>CS^B8OC#v9fewmqB> z-;KybO3nN}HOY_F6`WLwAo~=go)v!^2||Tfrk!D^WwAz^$hYzw8711Dsvu4cst|gP zB8D5#naSlhnz5BI?BPre0o78AwZciY=V_+G*d@tZi}wpGnZit#ru)7BZ=veF6Rq7b?Q(TwuwxR4KK%10~u9( z(JrrVRv7m`bnPUOCNfe~ngL*h^?~o5F=?{s75>YHw%Le&ZGu}@?0G=%Rl2JQ-la9- zHmhSg{j|Gi{p#TB7_T^Q$L9xs_EjlgBjiT9=>QEx8KR|5J#@@Hbj*D?}_Rb=n zkX8sKtjMjVQG4mfVSVB~iqr1*(?{NQRW^=pbv}uO8^yI!ad>aB99)pOCtR&X+lWvVBmJ7X+f}Q_jGLGsCp`V?=VeRU_xm6d84Vdv`-yaw?FdX6J#>M{Vw)Oa z+>ZGimM;m>U!XS#1V^50_K9;8A``ao|G`frlq` z^kir7qCDlJ3?80|XtLSk((d{4?kSy$`_oCteK&W&+rTGviDfc@f8>%@(n!9(b{3+^ zuny{W6ZWIysA`rOT>Z+G3HUu9sfXF3(w4 z1|e$b0`5aMC&?uGC3kvRRFT6#PnC4|Dm9iAhvW1xZyI4*Ga+WlZ!fRETXNw^Oh<+$ zq-m2)s;uuFnaQwoS+8)@w30xD&_hd?St%+kWW`3~q=@E-!E}7)D&0N!DGa-@TRKYm z2V7xR6fEp~89Ev=5VtM`jjZnlc)CP|+{6{N;9uJ!E@})z6?-AjrtOY&MS1%k`w`Xb z2IFkH+Fu-bXu6jje5U5Scu^0=lGA?pKNNWTRh-HMR7enilUmHBpf)QA@^a2uC}+%J z(=kg0b?bk#qmt8%X^C%)v_60%1mk#%4UzUhi&!Uhc}@EqPAdZNd{mIS5q%UMLQ!sH z#jJv7O$NkH)C3}Jx;-abpPS@kygqR6v3ut7x?Od5`NO6EvvBZfb}->AcHndV%*Oqy z2eBV(bFb(qOfeFYX#BJ|ACrl}eZUaQE9$*Ynj~T}`qCF&bSNm4+kfbJMnoHk)^jnX z8~FT>C+XdXu3HnA(THwBKUQ?UNvt@*D|xn3vdCyBvmtjJ6B&H0O{~pk7%hIJu2NGU z4>^@K;~=sdr|u@58oRDSc_bS>K_h{tW`Q0rBJ+biFLk;#rU_A`8;}T#abZc=R4r1m z(jtp=Y1O-w+HQ~Hrj^>a6=8;-;#4qin9vP-^ORS! zpNK-ayH^q-9771q{(P@ITt@AvWr7$UvlAS`fJ0vm6LNNE`Nn!GS|7??;DCsC-DQuW zmim1kHV%BIH6`e1{G2we&v87Z{9{3edfM?P<<@S!x)jEyV(9c#Fs_dK!lL%Df*iS+~6(J5NyA!4XhdCD5rxxVUkv1e$G?xjZQdV z4h~mdrG8qT7s$gl-xHZFvLLapCzBzwU0S_38+I`reIXf4?s@%sci;hWbD-G#m)~~2 z?$b>zLXCx@j{n{7?UnS9JfX0PAP`-#rR^9Rec>Cr!LB`!T^;y9iT!e)oU@}5BLsZ(O zLlwuWVxwT`s*)<}aqJwL&ON;5mtdWyysgYmsneog;gqI!sj(EPn1z+k%f*93SOC45 z_2S5h#)XoMzXLF)=0_t8&brl}npau%x8!uG^#J%-V+nP?{GlPsb1?;Rn?Mjhc#h*I zkzz2%llj<$hh@%|w)SCDM;DdIvu=Rkfp1uB;K7==UsnY=%=6jARu4IuMgGJ#;ohfH zbMv9!`CCi&hKEI|yyykD6W7sZEI55<7%S8RRy}>8CA{R_FVpY}WbkBqNb z2GbWrc)#MN$H3)Il_2vsS03Fmso5XzL-Pbx3!9TdHM^qsfS2xD7A5*|I6>BR-A^z4 z>Fv`@@1>uym}q~Y!t?&VK;Pj zg=)wIm#mJ`Q0pZJ`ia)Rjv(PE0OR)pb~REjOi2|IZgtGb2A zL@mjl$yWB<)RaAwpM@Q=9MFjzk5ki3hV8-1Q}urZYgOtoO&#j?YA8{6jAMez^eggg6G90h>^sDd9gHxBUZPNHQ zGOhn^#%& zJQG&C=uMD|w0+Es$C``Qp|`oiD4pSMppyPKm&B=+*nY_utT5hOUMfZA!7YE#``(f)FXe6uf9UfbLkVxJtneNOVcsl5oC z>8X%z-DvnpN9lJcfQMYUKqjRQ|??`_o4Q zSt?=sV-<+fULL3FcTMO>4Tv#_Wq>|+BX^aanO+`h!J_%)NPI>bqk&1dW=G;*R6$iS zF@$`c=juJYeEmu%v~--B#V|$iJc(EK*LGo#-2T z`xH6__rKuiJ;CU08#zs)?DXQi@A+8v*1JK@4-N*HK0P82j!bRIDet((_)A;WEVa;7(vI{X<+X7|kcM-Y^`8Vd9MzOeXFKa> zludD^0?TrHQKJBJRmp5EYv2euX_%3o`n_eOA}&0GKMVF{Dt_sy;d{tFM{N3@vLXWo zU9rXrimsMFn3)rNXSvYg-2t_raw4t!u8(?;N|Sl)btJ9M<7-Z&>Uhfau<*86i*%q) z65olNl(kb6Z{+&c?qZH^ZsCc=ilnm!AI?LEY`^tJpvjBDd(&HsuDdy`yN7F{BRo-J z7Pn{LI4mU6&Yq~lEqt)km&h_uWO{pFNjB=;5X7|h5|Gu82(F1o*+EHTGi03fI7=wu zP|gwFSY`(M-ILjfk0uA6b@oTFia)eL+^j~Sn+V13^KqBWXX5jP)#%7-(-C3+sZUEs(HXXpCHL#p8(|wc4B5} zuWfvy8ue(XEjfD-);yw*4bMbl^-To2R8i8~X(dn{DL!(iN;?%=)t5wW8AobE@ffW0Mb5wTCz>_ErP=&K>hXwKYY23QVih360g{?B)rDfAzWSO~w8N@id*{o#%D z;Nf!T!HY6bw>)4{;vkY*fa^|`BPNm?rNcRaBMV9m*6o&n(*VdSH+X&6CHO|}X;?ev zE=<6zFXWLn5TGvh$kFpKN9NK#E0Ym-G|l;4SMK!mh zz+4NT1e6^v9T?=qkbC>{YjLL8a^jd6)5gH@Y+p%0P}lBp@*peX(>SDd>p*ZAEHt_b zy&x%t#VxVwO8WDH4el$YiA>kDf zos>+4VE6Ih99=mU9Oel^_=;o(^+q!kynRyXimBr>6(#4?A)Y_2JyzS8tmq;YE~M>o zww;(;a`q_*O=Gul=R;48$h^s-sp&1^@D;TUm5DPWl1udsg?bf~8&s6Oa?W}o6E#$F zvx%u6h|TlC6AiSb@X$Z#8=>ykAwX`1;_#3{r@Kl6ZfOug3N|p-x5Nyk*+`X3`N+v{ zBTD0!E;FGlLuHYSOvXQ)blG`6Zkh54u(eKQlk3I%N`F)p$TkJH4c&zM_V-!S6HdbM zzX}KPnI1m5t_6o!@`4y8h!g{Y@N?lIC1y4>RWP3Oq80|2Ks1S&aBZbOC|*eODpQo$ zlFw>7=+_Rz*?wZVxUXPyg$%$DHnj?=&6&vh6Pc;+x!ltqTeCiW(}Im3&_}wLCfZ=U zIrD_%;Co@J`97Hv&f32iDgT6olUS*9C)p6CrsrdklEJ4iBD2nw&wy1EG!dG?;V`Uj zqiPF?R2s%iW$dRs7EJW~iS2d|Pc%5>6q&W6>b<;YH~37^ngIAuIX&)V*@7wQ?<)e%hG86yL3s5TiH&PP*#T4r-rI)WT z59G_`HaAr0q@NnOi|kc5c1~(3l(D=~$T>q4Movo~q5G~Rmm)PpX@rYO-_L5s025*+ zC@lH1tACrp@_hk0QYM9w0K|0=05sw5-RI2=#^TMl69<~em}bFm3gE29FjY*Q+2t zLN(atvkG1_#Y>jB@qaqjp4m)?wkL9R0f%QK&bfoP#asrm!F~ua?+7+CtX4_)VVZ2k zYT#e4er?+K%d$Dbu^vOB`hfthlGME6oV9Y?txoJF?$P-+2GM4x&5N;N(d~9UYfRHU z5jbajzS-h%cOG*3*Z|iGNrShl0HFfVd(q%Cq*J*Z@x+KNe0c8%;~1E2E4{R%0Dkyo zx2xS*oO1dFYH&^E)JgS_b#*43Wnesgjf&Xos=t&=t*3A4R$c6dN5?ptSpwkyfIMII zkhYB?+{)U$Ni593sj6$TFauBDGxLFS1zHmOxq`nabuAah&`k8J#sQ()%&`^>VR11r zBsLYbN3BSX@8zekm(WxDBK0}U2c-~+_<4V;3pN&z0}_mR%G!0&N`=%@wn~eM1l|!? zZYRDVNG5dgco!P}4d1C8bQjFhtueu!Z?K>M?3Q(vePme>7y5JXHmVuE%y^4n9an zr@my~@8Qx(`MOB?NXEvd9oC~rapI>-z$}j7RCO!TyAP3zrG)OZC>Wf$#>fPtQQ-RQ z1)XU|u9Pz^=ikqVGl8h50jpMbdlGJEsb0@1^}h1xBF8!ctVielAf)yC7gaB@QW^sW@AQBaZvBo#|lLH_o) z&x6Vg;T@-pRwnS$1XY%b$9= zL^=FEuh2-WE^5JF_#V)vP&UUMgRCK;hi;R(_y@J#$w#(m1oNo73NZ%naaXEyzYRb@ z5GkHXFrfE(yl&G@cre=xycP0X(YE>b1pnLpW_mjiKS5-|eVODpLsTJaw-I-Q2yf|> zU%0ur%v4huYM)nt|L%WrxTgu+ z)|WuL(WB%Ny#=CnbFN>Hp#(lpP?OK|;~>pTMy@;Rlk(U!8M4(yzncyJ@p_96$PAqeZ znq;(8OUu_31v$}{V?}J=VMO`8fsZV4^Slm`>P;#yy`O^qq*$bpxHgeB)&F5Mp6^rf zOFA(_tGM`7FuWLjNT#WWs1oxduE!;>%AclbI!i~S-ZWZ9H($fq ziviiv6wXQmUwn^!zC}+Q!+&mHIkm}4zNgSH-z2eW8ILEurR3sL_WQa!&>7@P2xBDi z=AMyrL$QgiX{p?b-(_Op#ILgA6KLj^A*BbJ#8{CFLVR3n*_D1Q!>t~*anE5mV7Gg< zGOT%XL#DT?mXh+gWry{tFf9lGNG+E|$A$S9M@u#rJ?emkfRVh|I#Og3I|w43@sHt? z7P~ol2gf~?HIs^rqxAU|A~wq0gq7;;ZsuzQDSVrJHi8jr?PamfdQp)r`I*XZu9~sJ zH{@kfk%BWC8J0BgW>s{t=xuh=P!GFS_jn8doq4R13iVR_5#1IK-&JKI&+C z-I)?pYI{+PJTF%oIa048IKY^F6FA_(%^XPdIe3qyKDN@;;a^0~D0z}}n0ja*+8gNf zHMM~=nz~tMeDd@0r0>3Sg4umV+rVv5m#Zr}b>0-|f4V|6XBuo1IEvIsjoh#_>*GUH zvPA|*RjzO<%4Kp;P+_(~71?++pX>CGIN*J5KQBsKkhvrqILzm$LpORJ5ihwTCko@n zN0fYmNFl3ax1n+&eTl&5Y%2cl_;tK47(3*CiXL9R1EIHFL?SRAhjvN)W?~Kchl$|%EXHp0^!@~5t zKiP=^mZLw%kZTd9P6%8aM@J&qi}1iKf7hw2eWrcDjY#8QUQ{)dYyB5br~CTg8y0e2 zw~k{Y2pD5&%a}O~+s!a`fAB-E+gbkhIvRolIHRUC7e>uA6jWr$0AY+CBHAfg8?hJa zh3t18kh*cmOux$wQg+sH&~ZTAo>BBoGHkJZ`{hG>Qe3LbTiDM6NPc>GQEJ>{Xm;|j zG1f0cLD9JFUBwzvgmRz~^GL%ss<6tH!#KSJ5^9!5k*RhFfHs~k#g8n0!tF@7h1r!D zkS>=X1(AYY^DK!a_dXpowYv+VaRHw$LhfiX6k}(^JWT9~o8nR~4%B9ypdvnwVCF6Y+*lFn?ABJA0L-F#l^g9s4mzP?Y#aXU*HdNIVA268UCTt>Fj&`X}8pm^+vW- z_0#-!?re}mt{)q@dw3seP?KgmW;?VVokWZIIR8`^E$-J1cX|q?Z)u-@$GH-@e%vRm z-7;^K&Dp+Fm$*U&q?Apxx=aGCFJ=%@Ad3ger4QPw3cPQ|_V50iU98@h@BUn&@wwYN z>0}DN975}lroB;cMJ~zEX=lGP(a6Srt@ZerAoQ)MkArDu^UfXZE6iu}+w)EK*>(#? z)|26X-Q58&{qKdTB$d`8cI=iqTiwqpR|v~A#Up^j8mZHP0tff6^Qi7gVk1?ppUHif z(YNH<`M=*M^t2{{DKJKK42ZXnI3cI1}N_g2LXi+!JHoEY|!$Z*nPiEo>R@OMn!eR<@ozzj{z#}(fsxC5krhz9-mss2;& zsR%UI*PBC^rSPWMhnhK_=;V4W^T7sg1`~~sTl3aU6mHq;=a_KygN#zrh$g@8L0&LH z7*{#5`TjTEy1HfA8^iXwyQ;lB-Hp&c#`<+pif&~$i;s)qF8<(?x3QOmNHcb#b?Zdz z)}xJGfJq{_?XCBzw+9bkE`my>9<%#x8a>oSqMry|V%-1zw#fQz005x+`%6a$nN?XG zc%XDz{_&D=3fA06x$3bFKD`N0|77*h9YhQJ;{Oa34dlaTj_N~5q*o-eD@%NRdW6RA zkE`S{6}%(6Z%x=1)axdRr13jx%fZLafKlGFX?f1g-g^lNE+F7T za*-~L1GzBo)dUt-`_y0wC!FaWi1>V4wdlWqL{feLN+T64kZUJnx*HSW+IXU*1pr)o z3=^$YT%N!-R9WLGHo79+xSX0AL@8|RD?TkcO-+=Y zEc)86n@J*z{P!gEM-zwNhJ-e`Ll4PZ15Q3NgtQE)Qw(+Zv<4v^_$-E;{Uv>&2W;F* z6pddV*x~5t`h8t_`ttbv8gbnlAka77EbgD+N`ilfT|MeIl6Uz~(Hlr%fxmIa7=D;D zFba^;x3^2(OXHEz>%HLU2hfN^hWp)O^X1C7e)PD#9(@Ndf_POVp z`l?Jqz~2Q$3#|CfTG4wHpAOCEUA6;lranSHm{%oj>P=%i{VucozMb&n_#fJq>o7Jv ze*+5M%}q0_S6dloZq@l+5g-r)M$Ue4WlEGFnc9);schV!n=?m} z?0b%ym7@z%8EByOJ@>qk5JnbB`}-jDFU7KXj1J#QpsTYz*=nD~s+xu3uapUsN{s}Z zwKb=(L5>U+fn=>#h1&!GEN7R@v&pGwn_9C#_#^KKDT$>Hfpy+|(PC2T5=7t_MNXmr zlD{(sB0#d)yBotJxhv^)=U?CI7&xSn3wz@DHiJdSHQQp}6h`@gDUI6j#4+!?DlPu}*vKf=A{{Eg49@ zdUy^+k#tIbOGK$>Y>Ic@0ls3H4JxtK=b0)Cm{Bdr;jcsiU1+}2skB!^Ulv+GB^q`G zaiZ=`)kGF6g=#uQ4)qHqZR{1b;guMGKD*Dg92ZKInC|%H@m0aj%J|m-k7PF2uifbR z!TP75w=`i+9~gDPfM+x^-ztf zHDZ%;;T9gQRNNF|9)DQG*fYxK#`ry_#PO;1JyVS6D}K z-P1hPrKC(&?75xc7cIY+x37iTiZ+D{M6w1y^^$7i@7sIR?{9fxuR9IE`A@Bp8?uuHxmUBKhiuI<|xLoMXTQePFOd`%W zC=i?6KjdhjwM##7>=bT(^han{w`aa}GJSk&08D+qCff0+cd#G21ko!V@xjeKyd~ zL(@GAx7N4&`^3ThUf@yd`_F}bYz_mL+SK$w3#YicfsWll1=lTjKA3FP4|Y+`@$&v> zC>8YD(RxCvGrsMs7J+dU=q8!xw2eN{`qc=i;{`z|_QP!>9TsmZ+VG0930H7R0qa0c8Gksb?OMC3)jCpdnzBVk3z&&zwdLl`7jFL@Gvo zX(>SgcZ$j6xC+HG38?*xMlJ(QjBCG3y+j0!SOX=a;7KuG;GLFq6~0_p2KT{cRcukP z-m%)X&x3=R2v+%R?NVnM%BnMii)|HJuY_bT+{Q|M2S#Y}QZJ^{u7GS!$7>LFJ{Uez z<73D4o#Jhq^==hI-F{!HE;EB@zrAQB0LP<}875PPgo+IW3DuFn+jm8`@7xbLm)C7G zmoCI^{Upv-Y9watTfQwb=QNU6%<}Dh0YVvvbpD#6Sva^1PL3iZg_o|xGZX|juX--E z9DFTr9I<&%Hx9z9{^QD+vY^0^=5(bYAQY?Zav=P)jsF*VUa!Jy7$<2JT%{qs6OxjdKfW|n`nVGakpu!_US zJ(21!v({v2tjrB#mVd9(5(d{mVp;IqZvXCoe}hD^-Vj_B-t5Q*R{GYk4F1i40JGp@>zLqUvpR$_9fFmx7)Z4SC}w)i z!4_9ioirXx5A%Q+EK&*zR+0;dO9h{5g%QVJT$Do!_e<@SEf@DO3t`ECP!2_lnsEU^ zhok2~_0qct^*^%djQKLo3uyB|%A}u zoG8}Tpih5RXD*5>{kTNG09=bsH-3Jylzvws2vw`Ou3MpMj;O5}ap`E~q}1s8q1J40 zD?*pkw-~|0d3-&4{`|=N(CcCVq3tLWMwMGMLTYsi&Fx4)76jvtX*sAe+J(%-*TYk}*;kNBk7bfrkMM38ZlEb$7iZ46MeB(uTQgM9E zsA&C>DT;qpw(KKw8cXysd7^kTtYtl0GQr$r%xlf4w$oeUuooMV3ho|CcZ{0V?f1;n zegxvZ3U73!SV*qa|MAIDnWlUoc>ur1N}2^zhVIR$3~|MFhi>_E;}juGOKZj>0WjCX z23254beZ|y)tb85aHDz_0mI_}5Sxmt*#5CDYM@-b5QWYvxfubrvL?x|RMB^<{KVFr z&ap6a7>EoSaociDVpRNB+(z_q;qc(q1?_M0draW>w?fDegzpDn)V$m=iR-m1Xyfsl zmb^eD`^VP9K5uGIQOYc<2^?kQDgHl%5+)K@R`g?Vqvc;Z1rl+chGfl*k zbbX0~KXo24+NKHnJ4l;bsQD1oqQ)6UN>>teWexKwh5cYr%*%-l%k@UA$_@D@pVJBUcN!pYN=1KSgmY>I zZGu}$zBJ02piMGH!0WwQwmSWbzHonrEMs9!El(lKf6u8L(EX9wH2>120~a{2w;v#a z=&D!vxF}2dpoYuh-&^azD*-4ELZF^;Bs62n$f=cS;$Plu`D&YII0$iFS<=<;KwY?5 z#ok+&Q~ZL;(=33y#x=%gcV7eliffQuCmzzb-@&6-AnL#pFyBLbod?3a9GT=8jO9$Y}7Y(f^4fs>6r{CK+sfnPuSVZ1{|&O z>1!+`ucS7;cXz8^@AQK|4niR$}?5{?Oc*y2rmc)_T|?^J4&wjD^AMB{5tuz_-R7$go->IL(d1;C}NG(PN9i zg!XnkNRZ%fe?!6uECX%SVk<>u1t#z6)*JWfx)&EX9WzCqb6^4Pms8$@^w=v+o#Qc1Y&xNU}xQ?4E3sQrrn(X6kF zRk##LVLOMh6wO-`XaDu%>`iUmDgj#c?bPElLhzN$;(hXPrPB1}rVjJjYRDLbaIorn z*fDRkN!D?Wu|IK8=&Cq!*Jz{5&hY>wLpifz7yZ%aey7#J^}>@-Bhih` zzD$~DZrIYvt?Q*7!$goS-#=FAdJgP;q!gyu5oJcdFaeH}iHp%=YK?qzBB?5ibZ?4t zX1bAd8!Ct?jTI2_pHY0Z+%xaKV?Os?F8)XQm@x!m(aq{*LwB6An=WB z`%FaEJDrKzhoTp|ZBBP9J`3A)XvB?hP8mie!IKp{;q_B2$6SbQ?@L%E&6NGpxW&57 zlYg^f^%YzyC``ewua>M(gG8M&Y@plUj1k#K=)2kj;UuKuv~0JD&VB3s`=;tZay#?ZnIlq<!F61cuQ~9C#`>ist#|{DsL->rO_iX3Jc!ilemgD(2qe0MGyrL zuSh!*M=V~iL2HxuADv?lbRC8HX?#_KROb|50vQqC{efl+}^=~$&j>UHG8S^ z5n&{rc(69gFei2}Fo`5bj=aa~6II$p)}-ZD%3thlL)4yI5l-_e=S;H8j=H4Ufe5Pr{t|8YL+Bmg~<0;1AO!dNK33`@>G5S9(`P zAN)?Ee&it@7c(5L=wg&PL7dop-Sp5X>nmA_WJ zfB6T^q?LK+xRZltE~o};nNZIEX_C5hG)HaGjl4eptl||jxaol}^?)y(4G4&q_YMM? z!B;Iyq(7e;Vs|ISr`v^%ayo9EsMsOmVF&t>48jz#XDqb>?9?4aJWhip|J7EcN&D&9 z%%ZlGNm5Fk=o;GdZR&p)jRL$rZgfQYIDdvSwN{!1O}em?uDOcGD68aOv65+aD}1 z0caM$icDxpTSYF~OS{)>?p+Wuso{#lQsuPYp&$0>{{#O(0KY+udB~;4;MrA0VV=V* z?_CD`tQ&>e6S}Sfi=}HaFT1^ykeCBwIttwcPclrZgA#UkMd;|;Srd?K|4rqp)X!O# zN!xpQG6ytN8-ms+)4Wm>;I!&Nb>dEa4`~9_mS!d^CCHd zBwov8jcQbkDJC4-)P9|suKJ_s8qgF(XW7?6J^%vBp0yoY984Rg@Lh&Mlr=JQiTJ5% z_jbRBOI^rtzG(oDUmD@yIK<&B!o!6SDlE%un|l^>jH=UbFAju+n1{Sk7W|R@9q4(A zt;z?G@DiqB;DLdU>yrRkUdV!kW|gp@ZY)X`6WHB>9QZmdU}c(Hn!%=f8_tvsTvu(A z^8yyrp_>e8g9(UxHx;FPtzZ*ktBgT4OFCOUnS`T)nhS70aF&u`r#;&yc=dCe@YSrt zvwHqtE8-_@Zk^<(kLG?;>hD?bQAeHSw{CM=TkWs44dDZz6Oia6WX23!8hGM( zy}ZCq6>g`qIS$65DEk#A@Y%L>3LY;ad9pW9rwZ2^K$eSaz}-52N=JIn!W0jWe0VmK zp8qfv<-sqGwnUYnAeME==-4m-IGjbol+fyfGEZXyo4Dlt~*0)aSR#2^H_c+;JIRg+@t2;Z~ktr zEvj3K3GOHC_ezL=UBsm*N*o<6)=K`inP@e%#^y#IlJfU*_Nm*2+cZea0t{mNon7cZGT1y&J40eibBPwxspF{86Vx zod~aal7Uxk)6;F@PZkqwkM>rs*Jl>y^3-BFbcassR;vV4Ik1ZZw;_lDVY)xE>!9lh zlYNmSLIW@i19^3B_^r8(fg{X-$1iPR7ADdOsFnpQ3=2TLw-^vip)f2QFT`2oahl`u zt}mSuQ7npg-n==%^ym-(HfjR$v%;a*nF41GU(xfYfu(E09LTuL6WCMs53~`pjj;Di z^zHogbxdX5_-rEw&kWf28H7-aO%SmYkyBDnyRZk93J2<4how&GzpHKh^pDzLwt?UL z-4JmY!||L(%%2jQ)Kc8{TNvc5*_P{U{?l-Px3q!NBsp+z4RcepOC|DTAxyf_#eIw_ zM>-&E`L6HdXgb4QbpYuF+r-ef5ND-y?9mqBx&~+7C=2%Jg&w|fFhvk?sf~9XA8w}) z)6nZgAo2rno*>~2OKwPM@4KvWF67wTa!?pnmGo2K4SQWgS&l82VUp^&c_eZOE)H#6 z-d)YPw`?01FAiXu=Gp{|brX2n$tw2)n>hNahS4rNE{ctwW%JOc&uzF@p1?Y0()Ix) zjU=5KvDNV0X%4|?o+FBdDWH}HSAp7~!$~a1L=xxd53sQkF;8-tFYpJST+RDeBLSNj z>#Kz{Nj9qeK#dEhX_qRTWm8bwL|uokZ5+3|1N3{HwFPZCPcYid>rW_CKba87oMVN>LqFI5sLf;^kx zR3 zHG)zeBI-aM4F(7;e5b0+6(*2pa8UgJa27R6e}yR*S-qZ(Ws>1LUpK@&pTR#oF{8XdOkCW!T>z-V+h;cWdyyo@>{@*Gh)fEzbf< zJz2XsXPp-CXJ3v0bSuU}&blsw*`zKwViX8MfruY`hmJJK8>PU`$^<_AM2b)RjV+y; z>(YP$G!EZbcT!I~hhW`Ww26P6&3``*<$E!Qb?;UoElTKE@9-nySJ$5UOQ$10dZFL& zqm36LxBqwn8EpfE_n#8=OhcEMxSqx2S%E{}!rwf5gkjggW4-gDzncagL>xgRQh+J6 z=U9eJH6-vX-e3r%ihSc>isx?6(09%1h%u4XL>!&eo&EixGzZk^z&aosZk^O_bKTdP z34~FKgM+a=k5E2yk4-?pdZ*P{!;5W++1ct<$v{P;8jrdycaz$$Y6Ee&>cL;0%%Op5 z4+4ORBp1Z`sjrE3`~P@**BDvS^E~Y7x>t2|_ssO1IcLw=vo~tJaw0{y!~$VKq$7$9 zvl2ym$%L>eScvS%LL`L{W67a`$bTe=HY76&6gd~c2BatqNP^;01S67>#6++n0-_=W zGP0($yWHJ#cy`X2OLte-y{hx$tM{w7zW%DZ=PcnD7|cvhUuvrAd%yScywCI2@9e%N zjm<4OIbgd$_=9gN@tH4nslDWLA2PC1qlbMLKYib|S?s!ph9ZP~0Hg+VcYf_X(`=S6 z++D!;Y<$OK2U4+X8J7(ju1x$j}>0HyNw(z%SuXv$)mO`7nbEp)*g#} zr+k7Vk&3F4#lI)7jd6b=Lz%=@0%zyB0&5df?$g*7O1N1R5(LJL30?=Xo*|qp} zj6U@HF47L5y}wkz55MR5dn?YtcLx%Yo9b}8KnYeQI4#taT;Y<#JLRpNr4*> z#rV({sd*GdvI{^3LfaIPedt?VWgzMTkfnJg#|=GuBo{EX4*&ryAl(1=efv}R^Ox@m zEr5oNmKBI>UlgDhjM|&Lc?s1Si27@Nxx{8vBCAZP5~Nz57D!_g zqgtpE0g!+}og;YvyDWV2bNUFNkGW@;m4y(B<;=ZTC7ao|yQGT}b-6x)fch5y(DkpX zN-q3weq<(yKN@fzZK}6U4)B$)-ov9u0q!l5&LXc(2a9+qQv@0gBC|~sV_)36765E4 z2dKKh5H28?RW)qW><|z}4Gqx?Uti$KYp+Wj007A!xJpFej z002!&pi(mHOsx$JLoc_%NBsFzZ_pKzNPB?N0p8lvfrmH=i2B%&(N4#KKr{=$fk0%G zhpPY`g6-1d^t(!3t&aP)9E9RpWM+jZuJ8w6sqywVw~JdK5i@X|z@fn)b=s2d1M0N! zLg0{ih_2wr>qJ8se&vX^?up*d+|dr?7y#8~(=iSY#J#f5^*@?;IE^x#HV4Z;x;{94r-jMQH7mLM18x2f2(XW3dh*MxeAwOywl|WG z*yPp1?_=>YFOeEyHx4T6w}WR~f{3&yZaW9thLQ2@}&y7T{?pG!WNrTe?9?;zrx|Cs8WTAex?DL<@C8k6*^*%986TWT2vRsJ-99tFE4L!LS1vc=l zH^t^UpLjT#PZ4LOoXa5|z$Z>7xHTU)9D=S)?d?s`5`t_j2S;`y#0Q#VaZLlTExDM( zFvMY;BXBMFwkb(M1INN;QX z+Fj@_-Oj(XK84u>30=8q!YJL!(rRDv1-(NISwEz^mJgAnZSaFO+FeR z2i-O`=j9QBDppFV0M{iT+Y~OFQ*r7|Izw2)paEy&e0ip;`-ac%ianTiUEfZ<6kqq4=A7E6iASfRL zUdE-Q_=~f)Lq`#S1psxH;IyPRU`yXEs*5xVd>>I#VwIK>gM4c~#*6U^v%u{D4_-Tu z;jKpa;_24`KvIDnX{yD5KG(Z;O+0pbde++=*k=@TAKNu()G6*L=q{oiCjpW^8yb1- z8+xI(nHrkYPE5cY!T&A!S$OGwgp+V4ML{e}gzvU#;`VXS zkshX9o`w)O8_C48P*fG3d1Qu{??;$5A`)MF5aGK9PkYzs#GL|LPC(7?`iglv_Ez2E z?%N6Y=k?8l=UE{chj~q4-y+sk+F*nOD2uuS1>R>CfSX}dJ3m(iB2i6Xv{?@F643C_ z5HV;U#$RVVU)D)=$-fOagnj$=`@C)_&jNpsHh7O%6~t?J3JNAH5=qA92lwx33x1YmY&{0(p}A_ONT=Pm5AI)G{B<6|aKydJ!~T6tHw5K3U( zQ!$-3WKoDGoKC9}w1^!9x7%(VSMvr0&~FjvxK8J#{RcBCLqv1OQIa9_Exh_b^!P2y zL|F>1u~vbk!vA;oLjFwY08J{9m&&3`sXVmH)SHsm1gNN@a|Aqp<0PWH2t{F-ysH9_TeE=7r)MQ z6lt{cukyIV*$?Pt;>mP7c3%XbrUW{tVU`I>xV;gE>{w-DgL>le`5U_aqcVr@*+|j? z=avgjq;sB%Xkb3^q&@&g?cO<0kQSRZ*JtfNir%R+AZq|*E)()B%Sw$drjc@>l>jPybnMZ&Y z2?(@YfFks_5a%KdAlNSe$w)%Bh?UoGt{%#&=DH3}PUgKe0i6?|i#V}`L&{(c7LL@O zt{NHaiYDl>mtH-?(QK;C0sEAOhKw)D@xc_1Cl(|J0ddoX{QPk*@Or7abZSdH1^C-P zbbyV~b{K?wS<~ft2tm-H4S^Ov5BK*O4(r2$^ufn9H-Y}3FKCleX|0|Ey?qx}FHdjAFoV2*?X;5dMJ z=-|$I0?!^HD#i5CIx9LbV5<1fCysCiG>O#Y{Q$Nk#YWy#))*ef=q6DkfgvXVv=^|l zn%!xSK_Z!e2xPE zhS7lS-x3MPQCo3CwCKVdjG9x_(E}V<{8R_{#Aj>RwmH}Z03iGP=Zhr_bZ7a8hI#sm zy4en;5}gz0pR=pr_vno&j<4O&syhMLy8b$?N#74)85F(!F1Yu)R!KjJAYVRfU>Ibn;(zi1>R0tFhclU zUMyf>82;V&SfBAoV&^gMSo{DmIXc13n=_2Vu!H#2rMmq3lM~Rv!$}$FHpWtkyL><%Ru04YgC`NoX{4@*;s ze|UZXqsk>4@H01s3=!uCTqH$r3b2cKle{M1A*ss#_~SP2+&KrJ?+kQlmRkUij^%aN zRG7LW4Bd!)z=%tcUAq?c)<9GaJHAMCd3g|S@A90XcbBaeD=lXqH^K_k^#;$q(}pM- zf0t>x-TaFT5(X} z7}8>cWW5l_$`3%2c2+geV1@y7B*LOZO#3ZjK?)*1R44*}^CLCRa|6pbZB&7)t(M`w zMvj5JrYfZkwCqCE7v5#EWvA@oyVQWLYHB`76k`Cits#{JqbLfz`)wN~q~`y7pj~7# z?=ONadT{z1z2^tsx6jZ}#d`S-M42sq^%&^)G!`=>R2Sfj-?r_YIsf@$*&*xP#q+3h z(A;!XbNeiQolyaLe0&{`Hj5wVE_xk$kruxCzw1O|C?cozc;vO4@KYxuN+4MtL30AK#g`*`Xkgl(Ewr6tO;!eQvbvqz{6uf+kFrim;Q2NC){(Bv8yQ6>uy zGzc^g9mzo^Gyv%aiE%d(q#&!b#Kf~?S77Gb70HGL^x^xt8j#NR z9Wx&KTmTL2_*9}C0e$5?jZ-Ac8vgX*3Tw33``Cc4V(M;BxxBjAb(Y2ne*259jv4*Ku8(oJ{cA zy(QKUULS-FUqz1Wsz4!N`$ko7veVNu7@HK6*+hodIswqj%N$9=_iw~)m7Rk$I`fvpFcFJ3;@sno+;A|o=&J_phL9XfL=qA+dc@thjrdt@9Wxl^7i~n zE#9k|kOvn%|C>`Wgg5isX+F;$A%)oi1px#Is_@kH3GQ8{IG*@e#%+;4t70DglN#HLp4;=kw|$Ii zq`<*HoVL63oSyJ}U(nW&16H56&wB^H^M)5cpug93_cN^(aso8bb-GGBGdh4^3wo-- z_LgM@qiR!g+cXvn7P8t6usb*8>o z-}|@x68hs0d}l90*oQS86}r>#0gSB*R7Vee3yY+?_@BByfo*ov@i;FV6kslO18mdi z-~^^>7hn}dIP#i4q-jXN0RRajq;O&xiw{`WCQdJf_YT7l7poX^pph#QK!rz-0$fBH ze5*_ItUC#+4e{s=(P%rai`%#7y}Jt_aye@tr5Ktl9I{>0hsvi&Cq+(xX8yCRgzH+3 z69CF0+shGf9)JEjJ(d*(Rx5O#L$4J>2PK{zx`%o;D0RW*`woA6=hB$}r62ehDxp%ZS|B4h)$wFfNMmZXhj zTnO@Exdpm1W&7;d1@Z!j7UwWapN-pEa9vHWy{J(ZnU)TWKSzAm)dmXrcl9|#@5vp- z7yh^aP++vN5FTt7TlvD*L5=Hr(^>q1uOEQY{mhkxb=HR$pzEnpppiMoNK0FyE`Hw+ zK`uh&d8Eg7*;Smxx->EKfORRN^s*FUp|)uvEd)cbwMg;kk!S&)MLFi7)5-mXq#tAP zZg2wt+7zHLJ)}{D%wwT^({5V8oM@Lz8`gD!4ASP;#^+? z=(E1o-@azq4j#RI4EMe#`|xC31r}&;j;k(yepBwcLHXwZVrOz}3pqkOI6ud#FcJ6; zOaTAt{}snU48UZrS!snq)W35kU;2IMbwDLw!=EQ26LAcqjRnGvwS0lC^(}t7-dwFm zZSxH=^s2Vcc_!02bk#xR^=7NZIGc{~=)3gW1?eI6K1na*5g4Ql{_h9jJEt zI}>=_>vh0r<6|=_-!wy?I%G{9{%eVKR4Q# zba;NpSE(WRw%PCjRzMia$efJ2YgFtzJzL_zD#3%5NYRB;5Dp+sVt9Ulr*8|i zpl!z6%0OfUJ0whh%1(@Di;K!V3oY`;j>UYq5DgW&fkYs3wn}jstx?vs7W>SNXp$dR zVW-b#Q@g`B>`snaN6?%Gf}ZxZjrh*9Pq^PcxBDKzHqM+h5sECw0xd`X`f`cUMmPb= zxB1Uxy2tvA(|)U_zK3qXll4J~byQ^@U>_dbN6O4+UQ_w8eS zn-4hxUX!|tC5d3w_C1>o1UV9vN4Y(v=Zp9OfObN#sA?EhJ0^U#$`LnnJ5(5~4X>>M zlx2qVRVwEJvdV1OMRFMl@DCuw(by2;Af6v!xlVBJGDT6vk`Uyji$Zo5_({_VVDOXI zce3AzQ!tE?R9{^vf8$&M9Q8L81(01O`?=`&)B%Wh}Jn=pQd+d@!vU5a6F0H8h~ZF@NLS0UEFOX zqX~sXg#=z$xOH*>*Q!OuF)ncm;N{bm#0`YLg_~8BOXuwX03ZNKL_t)IXC9g1!79N) zIL6eozv0?>WICOBZd82ag+U#~*gn<&zQWYLa|F6k)rs9YfjW<*69{KVn1*(zOR%r0 zG+wlDRn*}=@54=3+*6CYWszeYMY7QeFHy3?=u8^ z3tR)f?@M{`RTM!ec8QJjv}xP6SO7!L>5$snEN~7}PvR*Z)_m$9>_y`gdKVP!xq0rYh#uOIZ|j9ls?cT zs;PC3zP>*Hnc%%~lFOEBS=OlOwe0=&ZTIO+Jr}z=IkhqB%!FKpyi;d=Y|gu0)7J@$ zv({l9dBBkuV&>ao!8=6*3To4F4!Wb^JwQzCF5wQ<2^Y#Q!S^L5P9m>1&}x z1eRrmMN-Im0Feyv%72`fn2%iqjwO4JoFN#1tN{d$xwWWu;Zk2H)%UuGK^CfoLDl-I z)4Oiap=d$(d)Fa|9g13GrG0?BDDhyKh#+T}oX4)todi*2pGeHXv3;M^zr$~Px!Wp8a{8U-mpL;zF+ zXjA6`4e<}gR)xbblu-Ry!^}Mk+JYb;Ao)bfF9`<-ws+*$0Z5%|6j$2Mg|4wzdo{W$A>C!;9+ZeTTS zdjNLqJdvovuoa~1AsdLZoFu8Rlb0}p(5SmL+wH;VsSmfUA%MZP1pyh0=9eC zyBsqi;pqKJ_8PwUx%Kt!`Twqa&Q<8x)Yp;q5qk6qcF@ngh}D5}se6vqq{*de?A^Am z*Oy!Lc_aX`E?bcgVg$BLQ!emZa~B%rcc~q4GM~aWAGF5`Kvw^cJi;3n9Z^qS03`8& z+VFrnmGj0xyYPAVPeVm{CLBedfTs3DYIdHh?s~o-O0wEM`0$Vu;C9tr2+*eh{B^s? zF1V2%;R%Lm$FEw2R#U68$gwKUwdcAIoTa1fE*Yj`7bZgAUe(u3$cE_L<=-1F%eLi< zy=c4pD*U@1`$kw^j~WVnuOS7g(9m(<$-}lqe;B%0r6LUg#9EtAoQ_HtZQKOUC+om8uOD1o z=90FXj#d4ChB*1vpZ6^U4n+icy^+TwpZ{-RmY+;Lzv{UiI-gF%xSXT~9zS-$#1=bt z`#2Ci{;X_j0;1~AS-5yAei3Czi&(Df4j%v@s{b@>Ky$+?_W0IZ_7BbWm!W#yWhygKU6R1d%nuNOvjODZM;s;$qW}q6S4bK=uZW~^R&PsDddFh?c+cS z^{i5&>&q~oII>0%xUEy5C_sw@B=*snFBnHBo+UqM;#pW{V)uXbL5#+7tL@o0_SqqFn7Zl?_hh<^XfhwK8-;->;V75W0#lJ&c^*x+o{9v?*r zWVUH;rvR-GfjDtlSqZ3NLq=$uCepmZs}Ew_TO@epJi;WxP4D7W|E}`qWm(?Qm?!MD`g(4C7mvU1(QLY!n|$X|!+zTN`=q#cnQqrt&yOyu>iZj+Zt>GS z@C$OuBrxjp2Sn=}IllrMOWiHT?7 zY}LMa=G#*BmkNKp=U-G6USAONZiU)&;nq2#I7gl($kOdTG+&&%JSd$o-RsC`@vEX2 z+;(x<0YKnmFBPI8<(aN^hluDHxeevM>T`*Eu*?dao}MA_^@Tw$Fe>x}yw1-m8L0{q zqT|i7Tpqs~_H(<+R3CqT^|8J*NjK-;$KS7$>gq%0>GJf4v7yvpp9P;*8;Q&Dy++J4 zEpeW<48iLrGNoMpc;aIkSa^Mr;@T{b&f$2{vOQ4;?|9;45$D|$K#C7q0&hH@c<}5I zW`QHy4Aa1p)yHXINdS;*jSx5`9+}x#7aPG5kQ=Zp69?`HNm8S-JlLB8t2FJX+vrSp z7y-rzfcX5ocNaJ~6xaqewUYloV**zl!4N!{x9Tn~Qd~5gi&702nN;3UMN)QQ zA^K32oV&k|$KSFHF~N!L#ZN3glj+f3t!6-9th=i5=yT|^dTqmY=LP~ygdj&AI?~{_ z=Soh%2P?7Z-d~86pr|Umd@6SDCr&2v_ruVYh(Lg~0SR-wE&(7#R#sAq2oMY;q(buI z>nj{jd^~m(N^i6-Hdw6^)P{rGvk{Uc!7{1wpZvs|P+E-BuF7<*Ke)_1;Fc=@vizjlWi%CL|;60b?`9 z?692|pd0#!-d>^1bm!iMxF(bz>#xtpp3kt13S6At6UXIl-^kn%>@xNL>O=aGsSbmF z*HMLYB9C2NAYM4;grz_Dwth9Bhqcdq(Yo?zFsT8PJeWLgi`0Ki+3LGBcQJNtsmTGL zqb0aV5*&uEm?{hz6c_+}&u;j~On8o<1%LD?kfFV8ZqpE-CN&J!TTGG!Uq4F_H-*DA zj*%=A_)}jlW&l@P&{t%z9g?Dc@3Uf2?&AnJ+*UdPr7)NmrR0(0_;Nl~DF2U#n15Fn z`%t(m2Z-_rNe2AA4|Ih;bV4FmF(C=&0{A8Xz%T#WE2#5Ez8fKc5;+8G?ZmE-mE;Ka zWARac28I!Vxh$k@@BEx-Rjt_5&aQSj$|9GGUYskYl-+ag)O&N+X2qS#XTI3HhvEo| zs+P#yu~lJRnjLwt`H=(LG!Z2kifV+k*r2E?$p-WwO67piVJJ|$B;hx2z(vOsf4d7n z;YL=9kwecONdSQ;I?xp05dzmhn#3@w90$H7)qnsXoJcU7tMIYsv);iNUU(!$mnU!Ay#gdUneu(ciFLns{trz7j4ys#gn-zU zf98WvYTt*S3pzJ%#3}srk3R+g_{c~90(JxJDzY55>qv*td@@uXzJ2QheGWlI8j|sy ze@#A+09CiI?n)W8;Mpld@>rOrq_2>`rc z*x9}39W_4nyY1)K^#)~`At@@^`=`afE={pXS2bKqs0Gb@vA#$q9DoGtQ73@&0*a|# z1LLL;C5M4TAR@4{@G2HyWJ@tlu6-!3k?;rdjFh8Tx+DmGLk+!xcn3(L-T z{UXcpb07YzgYQSCJ0E>F_pWoN+J`^%Cj7!L{blE|yeQ$K+Nulm@dD^ft$pMTg_nFU z*T&d&)+wux<8@UqMV4j^nLiEcp@5V9zj;GP#> zUtvCRB&(=x8u)A9bPZqri~Cru5-gjN_O)q%`^y+(&y=*(d0N2nY-DMLB(30kCPr2y z(*kjlA9CuiN;}Fm0Hk`2VF+2RU7q;;@3J~h0O$fXfbML9WEbk89UnYiO)p#L6!_ww z*bN&f6!{2trPtUis{rb8jq(Iysv2~3*fr(vVRhU>6CMLEh4sxU(b)NcA zl{)qwoiilC4nRLi%JCgMx}bVcd(Y)Pzc=sIoHKsD`ZN^cC=v=ukvNC@oWJMZxxvSt zXZ0mH5762op=sT!ng6GSUCEh$0P^Q2P9~jUJO#7lgr}Bj8RzSCQrgCC7Dfv{I zv5F!9p>&!v-$qu|c=>)Ll)F6_wrMcp9s_}ENswMq)$(tgGz0*wqN2i*_=jeJgLNsM z^u);oi#W%fvo)SLnRF)qi1mkTY>#l`z=e$|E*ezefkQ$NjDjfx*2v+ymUIS=S72k< z7}XX0sVOw?uv_PTQ@E&VadDC~L6%m?Q=z28`R^^;Xf8;Bg98WtR73>2R6!RBa8MC% z;|ysJh;ypvpd-6#EnqV$QRl*=|Lh09iG}ZJ@51CEYaEFlaT?d18<=ihe$D_$tpGZA zu4f_$O@xPGC(i}C=kOo?h4cC2hq)7h0tpF-0{W# zTc7H(Npi~eg5g`<{${&#kGr;w$wA$51j6}jf9@-P@_zi(PyMO&?)Hzk)*2gQ zBhx})I8UeZ1_1xdC&anu6z${yNOM7T0%WdhVH~({JR7qkd#`i%jvx3OY{$a4KQ@II zh;)-cKs1@lnYy_6$1^vl_+S6{F241qF9|~EHGoL%k0(C<>;LUf+7y6TfyY*blf#(| z{|Wm~GGRsKBF;+OIyr(-r||p$)1d5-ggDI&ewtJmdnVR!gjRrW!*-p{i7Jb_Qz#^b zqN(Um?c9S7*|;$_7}X=x*dUD) ztuU&3zJB|Q?QwPW8Q5_tf-9pU$EW@eaj!o6J?&?RNGrgo7Hx6$-sASWzw=J~z~B4= zUS8BVs++=K(@rID-bIv2pbr`4_TPHb$5YpZ<9PK!+~|7>v>dleqB7jZdVq|CXyUxPd5rA_n(GAN!|3?Mh{${(AjsPCKpv4QQJLr4fQR6eer~MeM zsT5;Ci`ma1IPizSEwt#(GC^FJ$cr}L2Y~ zq;V@>E}`&;DV8XTQfso>g$zc@j#` z(H1s_gXL}=Itaay-02Ao=r-q;L-UCo6c7>l@x<@c?q-40S%b7;8$de=NW1>g#KU~z zAxcU)ZfKhZ;;fW!I5sND3Al)JT%S(_;o!taZ8(TFHu9o?W7{Y#QKYD<4W^+zC{eXB zG9=3iRjp^95qW=%GOIclj{|y$N_##Z!*(4BTcv0q%Sx={3|U&?{4^2^=?ZPHA%W9t z*FwyuX-*;eH;zsd(PdWo~1X)%hD~hI@lW5yuK$AZ=UqANu zZpg=7wAFw5lE*rb8l0TWJ7GW7U^vQeX!oa@$3E)EyNpCz$SH8zcDmO#EIs+`ABuC7 zXBE~_j@2qgmR5)(QJ2wyh03hLI;{|;nJmr&0s1&}t0x}{(8Y3ihU{X}@Z80SD^zCCg6*wQ0qR<9sRe+rB zc&0hRXk+bk0)RdO;D4hpFYw?69&B4sXHRA#VhLwQ^0TI)-EjhWRw2tuT%1SEg@}>H zMdzlauXnyB#yS#wcl5QZF7W8>W1O7KJCCWwK;Q50jjsy*x#791YU)l#zyJJ4UXYL3 zt|QL{{Y;L5zQ`ev6W~TpfTwMBz3Dhm{++(~|CGVihX1@ps2cJ2^__R_23z>1p0H$cYiXv*ZBL752grbM+j#}xOwY3Zr-|%zW^v<(f#!8V{lZ@p_H(Q~-hi;4BjGe9P*Rg=SUV(E$KN2S9um zD8faYb(Fp>K+FLELXC863H~v9Nant|5w@6T%4qm!1B*5lqi-KcUj0}7B z2v1-0V3xpiYQsCcE>GC{a*1gO5LwtR$!l&D`coRfb84CZoXjSjP@9T_WPk9L8gGBI zi7YFzTEzeY7)FB7Wn-f(B6#n!z$ZT29Y)zD{-9$V<}AZ%zArWEVIo_J<4p>2qyFrV z-2?^zYaH6ELVVSs9h%@H>NKq8Ei~_i2MFA(Z;RObgW!1rQSf;|N zYZ|gMK$w6bdl=eoK(uDnX}ry-M4q+_UWDGQ=^*2D{%AQMGrp2sLyzIfz8LJU1eFat$NiPslthfvTp#Vml(|I1`Pv05c4EAjKSz`~

7& z(Rr+JQJLLbv#e5iqI9M@fzih5q#e8-AamMfB13=Go_ptJixp>=QB6Qi2jnp}3y+K! z`~aXX#Q&EtkPhYCx{$xGpfwx&a(EAK^(=1E+V9{xIdSLfkm9dbHp@mSyo8%3T0WzRDd?<(6?Yzd4~{0 zK==h`z{{sA#94_u=ZUBrkS+iqkbsM{loa7b)j9yq4h#rq5I7bv0bXCE2pkLdE>pba zTOP%qzIYE$TnptG;*;}+c;fOtd~1YdRKTcKSVl#2v-?{pD&G@rK*$Zh{n<2vPJwW> zh~*+5A{!y6vk7ha+0+@JC?H8qj4mRChoRO9{NURJK0uuml*iqp9&_!QU>H)ziTjLp z{~!Orqw=whvB9S9-dwr`uM7YCY6{}B`kq8FT zC@Ces|Emv#$_OEi%Cf?%XEFZlYv*|3wFgX%MD!`|$EBDNFig0vCwKiJbz5B&K&EyF z_R+cP3&+TK6tF3WTSI)Jj2r>aJ87rlyOr;U7>6OAygl!*3#%b-=W~iw?pQz@YH!N@ zfJwB-`i!CvH3}i4T7hqGWF$iN8_##4zEsR2q~X3+WV!qzyK!xd*|eo{<3u33nFZZ$ zO8^~?)C1bz=(1?%=Z+xTm@vvU>Z-spDquEx_kG6e0B^)P#hXBc zhN3e7WM(CC2mrcKfYmJs%I9Pio_$M&&wi;(H`W*OsZPN6Lp%xKrB~0kA^|?(N2X#U z0AOT^sA*rLyuY$`y{1JhmSqhW8EV%N5u5FyE>c*Q)xilotQ9?x+U++zjmdO-3bRjH z2+%J?A*0?dY>HSM*Tg!?f#$Nfp1D^l@b0&5@Y`P;ZOw=D4N=kYx^6?q7PM)}KI+cd zdWrMe!S$fVy~P@iE!2Qyk*^W%xpSU0VjyC{FXIv~Uu5{|t3vsQQ-M>_@QG_7R%yA- z2n0ZShIMJ;-XcMoS8)A?*KK@LY%f!Z3w_QTG_ z(a}m>)rixs?*<`$KijsEqOHujzK5(T@cBQ=JFrclf0yM2Bb`F-J|ZNJ>vq_M)Vx0_ zM#$nAWm(Dz%7-zEutpmi@ER5~(LH83A*P`?z62r-04yzp80fawhD=3+x|1W!rejct zlRH%k`&CEF7hj(Po`yD-0RG@BIo|r6h6Lk~6L3;Gx6O$9fRPg*8*)l&x?tOOhmR5H zaxwBK*6{k7miUPuzO8+29}Yk@3V#j9mBl|Q^tE(dt6IM^w!v4N8JdHGT-Q-@@N?+|xTEJ-25M#cQ*#hp z_1 z&Q`fpC|SfgJbNS=h3CNtVHm=6#DR=7DFE$sG!Ud3<^Htj$qA76+$H+KcZ|yNVV23( zF%TppGHl{PO&wv-s&)I6gvmUM$xfghf;MFaN)$;?KkU zRbh5&0DUKK_ zw3PWi34xL`;lo0~=cX!t!#fxj8xH}XpRF6(bHg>A1{uSlso1Q(b$o?bq zsWk!!aa^6Kw$o0dRk7(G;3EM6A0ga6dUAn~HCpUhEoYKRuT?rpgpkf>t*P1Q%$3>= zhC-jGXA?g7M7$fXA(K)z{#M5427X zv_N5KA(e!ipik65 z9w)xeLX~{HWs?Rx_&DdlLsK~}^C_b}D@#CRMCL^s4ssB|Cdk&`+P3%jf=8Ea-=Wu+ zX>dFud+y*>;bdG7l-ylmeaELjRH{=~^P#hIRKUUL#2@Uk(GB*}c z@$A*mT{4xCjx;96zYr;F6lzXfL|&>pdsn(xnH z?h&AU#n~ii&i|I1exF6ehSYn5;}{N70NSS@+gDo*8{w9Urup>CZZUX?D*# zdun*ShaVIDJQ>y|G3Re zHJScU6B1nD1_Bh)Kn|RK(j4G7QAyEfFyYQ#cViyw6uZ4oaeS|n5`1Vxo~!>i)dQVL6$b1P}Fpe*GI$&#x!{Pxibd+QRgKO?iL zXd+#L9kxH5^fgiim{;o9j+A&QRptv=ADK*ikdK#d5r?Fsj0a=@mb2HO+(XS71B9O` z)-evl@I5}cC4GUU>$UFX<<++T2?eSK@b|5FkWb<{&D&pSxCXC&8~8P*d8y_7+Yu?a z7@_q+eoFKhCF40`EDS*Gir_}x6D|!`Ywq9tkLpwoXg|K06SLMMl;O)`l^;_sVB?p` z(DvLsQ!{fO|EC+4fekQvcmiEdeojuVAs^&*Mh6HIlw@EJmyt&O?Ufa$B%`Ba`TE^W z%jBQaVc!oFUh9M0zW3;x@irU@P=pLJ19mnQ?T}VLbBJ^vFTA*T|K9)tf~zB*gDsrj z%j=RwlaCIxcSMA#kf^UDTiE3K-OiK#;MP*#d3+N05AbtO4W4C{<5uuBI1 z`}5&9&ajxt7&TzdbMx;gbGj4<@h_+Bb}ID(ezu#>ph~~+keU7^kpf_dQ>CDHdw3K7m;4d;T5B%x|_0rYs;l^A^ ze`I8yYAVqC{E2K94t!MC2}#d$;XDz-HNsv8u8du9BBt|?#X6-mIutGoMnqIqgRt^k zfiY*a);e|(3SmB^^J=r^#xu8iHagM_7=N&>!8nuu34~nknNwNEOgGL$E18X3LSaD zkoRHf93T67GGVGo#~ca%1N5&yI#41Lx6~sbEEa7%>z%T_%2UV(HvB$#$ zbB1a8xbycG#+iEhnb~T4hGT#yj2xtkLBPRYgI^D=KtV<@U&6vmGfH zCUWyo#_`F?a&FN1dK|R@hWK$h=hI^|#X(iZ^ZhSeLDKE{pV6VNfI%hTq!bv%UY5No z3Z=xn+K^^p>_MJh!qyPJMBnx)xCz{A1U~4cqK3z0C9kU{EBor4I&;qua*jJ55s@HiCMK;ECk9FJVDVs)l$QeX& z47R|NKsncqA18u|=Z$v)5tr~m3SA0o&#())I z1+e)Jpj71{_1xk7GS4heWHp-*MIuiIH8Q`m2-lxP6F1SU!`jR+BmMMt)c!v>(bb>b zb$?Pp1sUP|6mPP$TiPc*T96ga@qt&T-%N#3PHu>_3Gc}EF(uo z3^=Sw^$~x6jXWzNl{L6 zX=7~?8B{L?$0(%ebK9Em=@l+pN&k`qDctatvFLhu3ANBe8fDZHxj|rOId95Q^25hp zo{g2kzUOY$h^!6J&mwQ`!RswvPKSn@c}Wk!j?Oa)HD&Wz z^Cqt6k`t=Z?p|^L*Qj7?sUHJ80u|!9`Yg0j1;hovqK3GoeJC#n;7}aW+r~Zur6^J- zdDQi{9MBqd0uvnY8)UxhXgs;?T_Crj`=?8_4241;lB`SYGl)sH+Ln1tu6wzvHh3Z< zG`fmIMk`8~SxCh&sox-v9HOIm;hhK;1hazkmSniA@!Ppsw0iY7r$;5&$n{c!*hjQZ| za{|8XjcFZs>UO7vWNHD+sFKK!4-GP8oucZ{Z=gg~eI;&9t{~5C1RNQXHhZiB_TcT= zsaESEJe`w#Y~<;E$=oj(2nxRTnE;{(+(4wDo90+Qje z==q-RmnNXi0q!DH){DLX zI~#qRzr>QU?61y|4ZaQYRLXRP$0ciH!U%wlr}Y4A{~eL%#7V>rliV+M0SN?r%7GCc zf%$kCT}Nk1_2J)2aRK4CjLT4fi8hnmWTm571<;!%QLO%v(0R?20?}-RA0K^%2Q%3+ zB%f5aUu}ZIlq3xgRVFI#+f^IxQ@OA@5fOhR9Q(B<3`i|hVZh_?NeI`U+$&zoJG|%JMIQ5s5m%6Y6J0Yfa4fg&VNG zW@4D@p%q9CHI(VhXWVEWCv??oaB@S>648z!a7{{U>94=9GvcBGkN|taKAn^8PbDOMu3a>AnD$aN7rN6=y=%b~h%fYI5LV5tgRR zM}VInVATPYAJ~mKdHa5@z{qWj_3Lyk4fX{YGK1oi&?UiGS5t#cq zkMF~6k7zLw6U*07T@y2dJw9bcLDP)EvMd=5OB7tX?j9Ac3pn#gtQos>5=#XFxm#!E zi^}}&luGizhl66m*wt~RqPdq5)B$tVwPn1XeBiaK(=D;-Zd($|Cw8peSKCWxva>2P z@x4a2f2y?QZ>g5D|5n#MVQw!MEzQHCr|@XJc}3a+Kue+$bX;8F+iQL9n3^ITLc+kP z0DY%FtGeFH+rv*79ab#XW$*TN*EKghE90tB`)i<`b$?L1$a5`pBo=c0ffM&dz<~+yE!>>6OoAl$D83TEJ z%7tz4QP46{G+Gp(Cx!z8H5CEp@pf_n9N371R>GIGBNNn27ZN?_7o%fLD!Xt=vKcNr z-66y@LEJc)G3yi?i^>uw0Qs^HM!^ho6L?a|8 z7ium7ueuz6quqR1f&PZzyGefV+~R=hdzb6uvKfTJf!XI0Y;`eiP>KftXZCuljYX&a z&sa`xTnH84p;aQ1d?cn(b8hLFyAm>vy@#mAD_C1%qajZJ(UBT$vroi@9{)S)ca>k4 zt|?oB@3H|)ePC@U7K-)>e-SN6=mHV7iwh?yu(q?$^k55q@;}_?@FjN#mpsGkTdqd@ zx&xHZmaL8@W0nweClH_z41uVQ9>jU4#i{2DoQ_J~!CHkVb4pIV7h0sH$8}PsN@ZWu zsi~BG^X?YD)BlMuhkqUmCN}%B)o4ZkWi(BV(AeW1vB*UGt&5Q-)GhLG$zWL~F<+)! zr-SJ7x*hP829RK-($C($xxpYxV}%7!G7NtO91(T=>z!g~*Q*psSx)%+`A8>s$bHV0 z519(My3!x`21~mh7iyP0E4xsdp2(XQc1-4;TrGll65E^Zzc4nXU17}t6v zYK%-Yd9$D)ho-X_;LBA?=*e3Hr8V`~ht?+up-_KOwdi99c?0DGJX?lkcrybjC(Ebg zN&${a_*@e}nTNCSdmMa8eN{h>1J~8HZA(2NVNZIpi{QJ+L z+945SMd<(*1tzWTYrXaV{(R&a&R@s$dVP#*1sFF8E*_B;13&?MoYT6o{>@w|mF^SNZwYThb;JSvAnjwDaCzg_yVJTg-OA zUcwKB9-E7>_oolMSWAkDYDfT9CPp`4BW{}UL6oF&c!BQ5AQk1&N02oV4%;U)1So(o zhJmL)Y#=&~cS~9epXJTl!m5Y0LlYgdML&&6`Vo z>jC)tc(>9;-(goJxpA{WPs7Fc^MhLZP7KlbZ5}{^g_s2py(7El9s>X|d~rHNlA4=qmXY)0=8G|4K!D(P!vTA=PKG#*$4&TE z$?xW>rX7yM+UO5ts2hS0PtgJUQ>7BPL~h7R3HuEk&%VJ;S|>%O!c z^b6Q^%O%Lr`OYlcJ%SB8YLFdv7vyz!0 zxPh~a z;0XETxK_Z50$SC824xA>1%j>fiZm2z6vY35{b4lh;rCL7eEH*G=g{z#*YSK@+Ct@MXtaQb710tL{opK^MWE?SZX; z;+P-F{(Q)gy647lY)oWaBFIO#b%86(irnqJlFs;)cP#QRwGFYs?Ueh^#ZBgsfboB; z_yIrc3o$Nde^>uj_??7toPVUDX!)nG_)RJ5=N@qOd}Y?(ffB58zI6_)Iv{+DcU}{q zpn^NFTrR=On~moBI^1E*gbHlxKwC_D*+{rP&=7veR?5e;xL@>sN8?WU55q12R`Amg z363j0Md$Dm=pN|VuKbVuJ`9GHcL#qzWeYw+plG9Vu_ljT7AhJUd;TKk|Mr3ACFXp^ zI@C>Y_7-jCQR4k;ie_8iqjG)JvvDh%^>pp#S-5v>_7t&u0m_a~{ValDkO@-GABq4~ zO+19&4{uR?$0fkFi(AAmpV?ZxE%c{N_DdsZloddFsf)fcth!S6>Yj;7j|5UF@`juR z!?^o&T9_)~!Uvt?K&ua)$n)`gw}d2N$M0O=A|sg1pYrwR=yMp^##P`wV%q|&{pBau z@tytkqklMRbM>qn!BEi8Pq+{M1NAEJX^2_GP<*8iu0PKroCu1UKFdVn+R;zFMzFK& zWC5&d5Cx-;&|n%njp9*hgb$jELIHmJNq^sFwb;k#ZaMAVeiOL|a#d-^Z@ zpIKO?A~?!3Mp`-6>3C4uos{avue8lHGr!F$Q_3m{zP3sMqaqQd@s-^HjI$7#^QdAm zCQso!jvl!6VR}1W7y>DRvDFg8sm(@4lhM8si);o_%^_w1R)zIi0X@K}Oese#-dZhZ z()ff$c2+sE;g9~(n;k<5y{`g0OANyL^1FF{ijsd;JJ#9!Idj0}O3*hUD+6CtK^=w6 z^9KKYgJT5Fs_y=3AR+33*u7tcW1zZDdF|U>Kr2`@?s_BYr@Mdl6n~4YsY(n;2EO|d z7(2cyfn&eAPw3j3yZ@b%QeN>tIBgN>Q2uNkPn7#Os_gH8kfeG&R}@!@tsv%{T~OFN z)Z23@@f$q7x1(mFQTw5cwBBaWdZRQ62cCjAiatmRfJ8#~2{FMyCkezi4%d&^UmvPh-xvw2f>I(y?H#V#nsbm93Z(Z89t+$^V*2BgZHBp4! z+*3j(eqJxK^JiZ-v0>y^Zun3r32vB?Qv$$kuYuyW&vT{+ikf^7Y@ohX_1UF$vj2*=-Z96khX^ zRCC%#=OUvV5zP;*^GIBXva37U0u9Q1KxYLcyXAx{0|EF2`Hw$HE*5%!>an`=@>1wb zeauwgJ%@#DV^~6HkeH@DTUmU1u%a2TUzoB(}1cm zWdCRyXqs7*z2HMEotqhSs3&sy^z_tPgAyuxfHESmadUG9{)Wam3b!Q7mi97p$4jiCk9*i})^~nR zUPt$By<61CoI5?b*X|OI6zrKPMjs_oOp3eXTM&2D?brGh)O)}BB!pghYW{;)BD>n~ zcL9M0{Y!{3?p#Pcm391A;NNKAB<6laB%1tq$Nl=Na=yrC!&~5=tF+XaZt4wj>6O?0 zDpjLi7kdJ?$EJ^gO6e!k$s!et&1+O#7z>1_U-ocjeP*D0`-E>p0O zZF7#z?GI4Ge~e3!uOF%1-b}+o2CD)u?_547HlHyeHKh~fx4Dm;_LLwNN%;C>?S4M* z26I0ru9N9(@B9wH<>Oa7UHVWhrZ6v=a34VoaltlS;6-on&qEV3E^SDxx!p7YG-Cf+ zC;vsFyyWcCk&R%ImA;0F% zlS>+aHB$%a^O1^|yDVDQl{hWAS4LO0bPq3yH|%xSqZk(f!DvWP5I}?J*^lL zCjy{aLL_Y0erF!$R+~*LXYngyL{W{ZoU`|lj4vyf5p7ZHd=cDPzmv>%3&zo#@8gs@ z&`(FGwA&4M9G9U-iI~6_RY!zq)363p@o{7RSSYaDs`U!O{f<98g66*J?zxd#tt${< zoyzy)VK9+w;-|{7Z7g3NQ_YvY^O|(u-8{{(^xDjGc72*wUpL1U4x$|ryJ$=kE@GdK zmk@ip733zDHowq}3qWakTi~ zqcYs%Z9g@C@;`(2iT;HzWd}7dzx>RP#pg*iI;lXSWe9m0FW_&2kN>82rHL*f7QJwH z=PalO)H!yGcl@*@Ku;$glX~SLi>7_n7IFSwi@x$AD_LVeZjRx)kJJ+(D?6sHvr2HY zzv`D9Q9In28piYRLdJ`%Cq6WFNm9;A0$T zV`}=t$cS3wd)J^Z*CZcFSt!uTq+|VXK>*R_kJU1Lfhx#^O?iO&1;_h$Frk{t77P@R zRf7q;CX=fbBfziJs+TgI%8RgQ+kzOkT^>Ez>a*(&Y!@`5Q1fm#73|}1WZqEZd8t!O zfU8ff%XfGN{0Utu{XA69W=tHE~B+0I{kbNNF*pW2iY{PGTZ4D-C$VTl!K1-b5| zK!byfB;1WqQG0~#XDx<1zDWiuSYl&)OmZ7N0V&|*skZ3KTi;bqIX}~6PRK*q(X7`i zg74!WHigD7Q);%;vPugD^(f2SISdK6&D=5R3sx1q?W|@28GQLJy_bVkK5rioDnmFh zK4SHP-J3>_vRQ*SOYja68^5FR4*PvgGq|a|v@e8vKYUaS>H=;V3jVzb@ND`e_(loB z^S0CQG{d6I^(zvMQ;D4H%I9%PA~E*01=jT2LCl&V8HA!#U>!xsE+aaDxDULjen81T5n%UEu)erp1c4 zz52u`7EdY{>Gv2!v-lZ9c}z_BXfrPF3sHa(ZD0E#3>9`9aEJWR60qNMyEe=^B8yE12^XK4PDaQF=)D~qEI4D% zDFlpsZC7%jO1~HHH>h2f{Wb-k_N{H>M7(`6}KS;}37kacnzBJ(vI{k-la_(M(&; zXnEuI+$y)!V68ppMlrr0XTBV6V)Of5K7ymZ$n&+u753j`H@goPB((=;_D>Ij--B1V zbGJVUk=I>7_!6wsN@hxZ2c@~On9DiZ{xKMyO!-MMkAHZmM;&o-_C7E>iV*A+Wa5zh z)>sr+kPw#7xEnn#IP7G#CHo>$hNME*X{G~8wH!WN2_>7Y-Q_Y#OySEA;QL)114UX) z69Zm)G$G2UkYJsW19_N7&EKD+VQ$b%S@Knnbs0IRjbP6BwvV{2O7l@>H=F&|E@!pK zpeFkE3J(`|ah@Z&E}!ljn7_{$*STpLq!mEq7i|ANGn0^t>qSYm?RmaNP;cKb?lpg8 zfQ#o?w|Et&%ds7fj!CGqM=Nk_UdIK9B`y9c#uC*KL_cixC(u_mNyzJJ%q zsAj;5uOKa|7q035jtIqXkp8=@iR{VSc0yb&Sot4*X(0e0m13Gh0>GHU*b!KOn{@-f z2i8);d)#*0E3S^W*jDALK%cKB!Xw&$@$4ZlRR*l1tuqMJD7oykwQ09K{w5rp`B(@&M@h1mQSu z*1K>FDkhOU$!o+w@xXUY94|LbhP2e{*0@|IW^N297fc9{L1s3%$kc_ynoP%Ydl64n zZ{vjzx{q9kyzzH9;JUH@@9$s_8gb~M%nQ9>=ilErpqg7=xj-LjaS5A14h&#;R%hTR zsQpqp0u~RTzx_eC7oOq*&!qf5V8uW88K_0+PVSR%_ArFw)Nr@FBd%O zi@=7TZ1KOE2o-gN?hL2rkvk>Rkf*$aLh-3b&<)0jP+tCU9b`oX8mX_-OyRcp(#S{} zNyr=;%J1wY{!Sk9!gF~9PMwHHIpaxlhDmeAaW1avlZZ8tO61ZGFuLv{Yve76u*(bP z7;e7siRx()$M|~sLvW=WremVzrE(B8NYoafs!5tkQu@nli2|QzZgCPMk=*b9Uh}DV z(6sE0Fl~CYH6D%LeM3A@bAshyDLYV#cS?@sT+hAT+@KWvsnB%E6`|jAwKT+j;lOZy z!$==X{bYXMetl(_dnfu4%U%PF-7m$#b$RZd{U22692xMBXySqg5-9m35kjl|jLJ7W zSxLLyE^glJ=VqVQ4WOkfqTq0~*Ui}f@X2dSRd1G}Wr6V3|Cu?+9%P08nZCKq=L-v9 zp%EX_B&u5IS>yEaHu#sUcK&$!&U@J#uO_?_>Zp?V&>*}Zu25^;qAV#nUV11fcE5)b z>t4?uMr}~B-021erTMq%ZJrjRFUBc#Yf~D^vrpNo{_N00?})iN?hiTS<&`TgmQIgu zFxRNOF~qkaK)14CHXUs~n}PpGv`thA=YNN&H(s`dFI#@^5h(ksVr)&C1p#i}I5?Y~ zPg^7uMP47sriH+QEcy3dGKB^3*eWf3ufj?t;p`Hl5~VHLuydexgnlhgOQRh0uZ}q$ zpW1y%J+>(5%KJ`~2kfj%j|jgzBb>_>o!>P$+*JPOHy{g9s(AQCCZv&s3Fmw#upua4 ziQLSCJkPx~hr#H6=&{F9VY_eA9%U14=lF6jZLh9@w|)PSSm{-+M*6sYP}h#>V83io zmYHeT%E_Uyj~TfN(`B%YX+_^MV1U1iT&bags=NaBaS!#MU>b`lWT$BCvqos$IFnvr zgilyxn-`)1Y-Mm&0J~wMR8^CMxz3#?%y8=mxG?mCmjF~iB5kVrViH@tp|4$XhjPB0 zpd@B%YA~tVFGr}8nXOtu0u>i$Ex|GqiDg7GivhAPIMgerR2e!}2D}m3OknsEE;6`< zqXprn^SzBQK_^{cV<~92A)S}D%65zX*zjYFL8nqUNOskei76mqj}?V|ZDmHfN-_T$ z%eCiYb7EfQ-9!injA?JbvTVEglNajjz2mmqJFn0lFmk63J<@-Y6SW2+2$K2cbXxCz z%WD*rdxHT0o+PT+OBpR>sC&0#T9^bCgZ33067#L@oV|7mo8#9lUC+naG_a6pQt$R+ z0NMn2K9R%UU5HBpXH%n3zqqNF7-16UJK#FCe3PGFa5+JS=DPXZ>tLw{gYgd_m1Ivf zQq$n?RsaYG2vuCI8~CqA^!|JCRpWKX9QrDQ;jEhB`SFTB%w(#kxYE0U$*~l>!+~34 z(Th{cOm0|&1bY)PM@!fBk~!{j?%3-+l_d_ETkzsZjikV|0s_zcm}KN%r-o=iwK42F zLHqRYzXDKPHhX2!fc9s`(z`~1?#TAjv&>#2qAxL{tjVc2Nv$8mV88m(0b)y*qPQ9O z{Z%XM@-l-4O;3m^hL-$qn^1Sk-+Z^8~;l}*axI!ppLXxSE#9f&L+5+)t}Ck9q5ENUx__8UpF^)l;4{eqZ)u6QnqXiQ>&yok8nEsdK-3=*(zR$Ms&oW zQ^63x;tP!+BJLY<<=hoxA#(h0Ezt#|m{N3=ljU^O(ZPfg1#5#ijNKO}ky^mB~Za1aiow7HY_BG#K z{o03^aV$nRzIHx0zs&q$Xcqmiwqhm3B0dN7DW;Q?*Yf$I9Z6$+W^jM|mL<=}F^p=!VlJ4)`m0j7 zJ@Rscw)b}q)8Gi6qoJhdn{CJnN`_RfY&<+)WJ_1329KRQGD`71xLOl+Bfghb5F=bI z(86W^WUcZTC0BN|6x(_oEH8NFmoHE2zIhLPMg479^Wk$zbAxE@7J3N#1?B5aM6W8# zFcPx73Aq;Ia0$`bvoWlnM~B%<${_C^*NC}b8#X(@L+aa_3p?yQHM^>P+g2}>tl*2p zJs3tkQD>ve+dhGx&r=~XUWW!Aw`uXj{ea`x}w-^J*U=SssPc(PhsU+Sci-Fp0;=d+`s%}3=VzE3&cz~=?? zhvTxVWABv~f{x?Bg8Qc>gGV2NbM?fkVJ&Wer@`aeX5*6HDnUA z;Z9k@BI~$a*MEB>!p|FK`}OsCIO`G3X81_o`z zg#k{igUta!HQeXefGBG!H)k>(xME6GYmlFOnd_sgz3e&fr9Flpk*sPM;QdITX4+#U zbp@`Tfi9LopW>GeM!77?I8_n~wte(P9}IYc`R1Ww(1>M^ir9<{@+OWz9(pgXVGCRG z*{z{2jP20nxuvjtv-sq@5z(_800$?T+66$&z}-ZuQ>m3B45U0f~7UFOGM z){ld7Boz5NcV`^A{}@a;DH>qNR!e9M?{E6&N5C^cbJ$gTi}{tuX%|5)F@io<6F7v& z759xLA5<)jq{Tgr0^x*7i#tzWGxqH=FE3F|W_z7}U!IVC+|uwn0>fLxGpEFw8}4A@(p-KGcKJK;N?XyoJ-NlSI%oST4!BuaDFwI#`B1=jHyF8IFBuNoDWtGG%f?QiF>Ms+6c;67}r?;=;hV z{WFd3sz%IGAYB^0Fhs{RR$90}Fhs=DGsY{cmZzVH$U)ML_`)xr{^d!_zw+hT^{OpA zo@%HJGjhe^>$WP0!eFEG_YrH@!=L4L}b()G7(%W=C~0Q_$q zT|mROrHL;lvE$MNsg3)6U~M&qjyFsYyP6W?WT-W_cH4O&ZWtV+I)&^*X#~VOF@v6d zA7KPmn!m$I0YpvR(&-2;}xjk*s zOLOxftTz+`?`WSmaw{6k5|c`D(%CEy@VN;}YTm6(X%Ghv#7$Zv$TS;imm?>mZ;UzE zRz?+O_Y(30GRAa?ipXXdb{T|d`$Q-n6H$^a@c2*+@OA7vHkLEb<;S>8923es;wYE{ z9DlN8t*F6EUQud@8l`Fl{QKm9u@k3s7g$a`W%=+N?3kGtfQ;V}vXWVZ7};7D16?>P zvi|SAZe{5!)uyw^+hL-i+l9SnUF=$PP8MQ7+=mWJk_$g=7>);k=*n(Z%NADaIFyh1jM%Xob1(2H%}yN0xeaJ>V6c@EZeW{HQodBsIIqWfa5Ck`t+ ztwS%SDUBnH09#0n248BhHx>oE1jgWlIkfRo0&PnV6k}0O@U~8_4L`w5lZW5s97R@% zGEM)i4_lBBJ`SEjhT1;(FjkC!`$xHSM3ljJGCbg0@RB$*&b6HOZ4 zf$w}!9<5poG`ufji<1bI{PZ#&y3;s)Z$4pKa5{gHWfyg8YLOrgl&j2WWhtq@bEj+J z!tAdWNhE7$w$2Y=%U(9qYPtT;+V;adv%sO2lbvXky_LH&xR*YVu@|jn%@|Y`zmc^ zCSvZJ^tR1$2K+9k30cS5t3-U2ip0M8(7{~gr)BUwGlN@Mg+EGktR!=}?1|)OxyTj^ z^fp9h788@&xS3tcFqo^@VV}-ledaH3n}9=eMEhP@4Sa%{&`GakS;l~;lSQ~gpUb2@ z)t(f-6I&d6389;q8HU%G=xKpIb5$e+ePuMu?bQCsLfbdlvsiF&QDNE}wQwcwFaOh*yOB&U+LhBEzcH>^% zHqv00_Q3*`P2;(Vd3ytQhsr$IGzqn!!iT@BXT)jAlsNs@7bR2@k*;v{#oC<0Jo5e+Y=_~Vq)qgy% zuBe)((*pcIB!;kd84laeMDCaB6Pyi^_xItT!L4DwOZo8didCoV=A1;Hcbsd$fHU)3 zaXT<^aa$T*=w@irW*a){aNX)Iv~9Rd{RJ}OqHolxNzDhU#52W+6+_N*oO>ao7rt4; zSFJ!NQ^-cMLZ*P%km|n)@}bhPLpon7nWLOj!k1_!D_NIvmO+SZ2HaT|8n%s}E^+um z{;~je1fl!scsM)kXnOqe>aC9lHHe#%V&#$Jzs~cEmx@Uw-?evpG-Zj_UM0!gYxZa* zeQi9MR~>%9I#%j}h^G+&0B`@WH6BFX*j=8VFawvKCsK^x9la9e--C>v?f!&ZjEX1L z)_ydo3MALAsyc(YDOyiEt4o`#`_0-{$)i}scS?EmUHeU2A^v0=9_Xv;@x4i`QRr2i6dHb7y$nn`FbGFrCS+uXwf?7p+sU~*gfe^ zZi4^~HNJeZ4KdvSU2v52D&B#RW3DbcGSBfIirL@|crW7+(<;__~|q?qpL;&G>UgL9(cr-|<0Q;_@I+1wd(_Ory> zw+ki1uytX4{{~cKC@d^Cj40Jo2BmzM*gA#Mn&ai+`+tJO=GA{Vu@`G@PcHM-$Sdk`PX*&N@fc8;J z3oMm0_yq2JUgz$5bcXsA!=K}E6!vwJ%^PbL>{yEf$CiX618?IH=zQtnH)fY};qO9z zqueiha0rEPMws^fQqJ!-?e`k}fcuI1lmP7sFbNRwDF!fsdNULkAV&6I08XiFNbt%n zC9EXm^KSjHA8qq1{6T)A+C4v#qLr|4z`(+8Tgw7e?c6Yxv%O8HB;`Ff#s%g*SGRkH zh8efm8S)Cd{(`BHXbGJUE%aO1iO)}ePHN)HveJ#Q8vo>iTKC)~yMWfkZ%@ffkRt?D zrBnRCq0Ct*8R4UD%msTO#6cJA^vas|v@oL~i!(T3OsrA{b&)F6$zDNxmsc{PK^ZKr zXFRUTQ}w^MI^`Ck&xf5y}?)-<2A2>40A0yRiSXMU$(ZzLbv z!1d|~-U65Y58HIG#eLRC(JS);j-4=(C8A+F$4tF|A&!^pb!)kZm-bT6C()LWe{SSi zIZGFYz>h_#7w$~f##lvetwM~-et*CExQBi7P%*%2o|kV6|=s!jbS?LeYTdLs0p|%my*j1 z0Y!Uz^IEf98-PQ|K*>cU6SBJ(BSgcnAoWnnEB&*>6Q-fFu8(nh6EWP@@YUz&zPSux z=dN54;@5px4lRPUx9ggagtpTD3j44_=3MBUHMtiu*oB3}bxgvOOGhQz_r z1>!?B3S#$JBj2CHh!ra@A1>##bd|XmPLCaJ&Zq1{&OA0g>4m$)R&d|_kYg!Flg>XH z?gBu~?JPKrXn~pif)k~r!IewD7>L=cQ{+|jvvAVIDdwIvl0j^l0~c%S^=1%T`3{nc)~zo2!rPZM9>L|fJBhQ)!B zCWbbg{ND86`2YU679y208fK3)ze#mSfYdec>IdcW=`Wbeb(6u6V)^zf;HKB1&Qn- z*3WcMQqADyU9dbODy^Wn41s)>JcE#e#?}tPIVCJ|sv-5-o|y(kwau*E=Q2zE$MW9q zXM4-2AVJS};DdkimH*Q4#O}#!F0Gat+e-qMk(QG&;r}>rP zif2oOwnkXlkCNgSYR$kS9J?S(i3@F&K{eMbC0j5LJK~e?8V9xySf<9Y7t(P|X&xpr zV4S>6kT;iWXU88qbdPs>ViQxZMWVUshn%#k$t(B4nZIBCI<}|vaKQ9DQ~TN#D!jS( z6Tai+tq}%p!$KZKd)&B*8OnAbSKCKmek%N+WAc{Y)i{s~VxuN%IhAM8LCrh6Mde}fAG7U2jOYx{b%&FSueH!d$XE@!te|92k?yTw!pZgGHK@pb9rpN~4U1bXkN9Y}tM@sre0 z2^H=j@%{@Z^TM%1;`d&`d)}!qd3>~~M~Kpc)gK2aum1ZCw7|6*tHv|T54S>VZ8ia9 z5nfZi4wIjhhg{evYQm}{hPX`b_lH+TmJ?rXJbb})E@iFevZCik;;(MTJ9!JWCZ{Zo z=#YolC}%+!DgI{T?3myrUxSL(Z2%PVj&G=4q=OMZq*Db<>NNRBNH{hTLrrvJoo|Sp zyL5{X6K{-x{oHqgBO1*r_fsr*@)D8Enx!9|)~ufStwvruZK)})Bxy`yj>efZd^x@4 z$R2Bk9NAPa>w~Z6E{t?qrVR^qCAxo}vnfW&Z&Nv)4=nq^qB9PJbRI$^Yd^qu1*FX1 zRY|8UJZo%LU${ju2rru6CiqK5P1{>e195)&;P2#(YH#2CG~^(Dd0)eC6o>j0(umDH zyI`syHKjesGR_aCjV4@@MED38Yn6KIQ>V2jh z==VPyO2+AUL6w05-<-x?LmMd&RJkHK%&3%X3jdgV&olmUc)o+mgsbC#hSaL+P6q1XhCL7#i6)mAIfFEM)MK z)F@tv$3QSCo80&;(WUHqEUcpI@wL$@Lf3>B)8S9umjbon<{u>c`NaBmB|FdW2WX$g z&!+Ul_mFnplruNC4A~yH#Rb_O+MO;q>ILYguqLAf0dePG_W)V>WA$cTu1YuAYP^Mq zUSDlP1|*8v>9~5Q*5JcGPJgl`I5G!GQwwU}QT^+#sxzg7E;#?wSE zKYuxaqPb(cLpP2glD}q-|4tPxEy;^tJ!yv$Yc0ZE#+2NhPs!xYgVYE1RYUha!s`~- zBm3GT7vBt4&w@uFERe3AfK`Y=Ej#C>(@?Qc5TF3}ns6q|`u!URa$YtZgkNirv6E%C z`Ko)45`BBI=AQC zo3X*drmTtS`Y9&e;R5JrVgq|q-GeAacZ0{{W9r`FkrFGI(| z&anSG>iIE3OmW)#G}5|{BG(6VvY&VN7O!N93uI)sHkD^6F)ski!lWr{~!Oa<#X zeESbpIaihkqPAz-t1p-KmSQvL={^GXqdm}6Iq0R-aGg413da~8hKHS)3&%i1RD?5UT&3av>p?5_H*$78}5}*+Nnb&8AC;ypdLAv#@Av?1dV(>YKc|1n-Gks6rv^*5|dBSauOZHd-&133C3YS_!S!0o|bv-Qihh9OvPf)d~DZCMF*U zE7(MyMSo!_FNH8NAl}DyQGDW4>}R2}-9rrG#J6G`z;wo^X(5l$-INQ82(0w3RCZsI zdDZ?CcVFz(P9@$WO@ zo`9~x=2GU12p2!kcsY3#Q-gk>i>8uLfI=}&KauyM;({(Y;=u>_0lVD=4da6nWCaPd*6DA=?ojRU>Elc_cryVEjy(QnpKUw`23@xhJu%h#s|%>g1D_}DhS6qOGcLD^uG3w;G%$I z<)wkmcV!cpdnjz$v(oDM?*oWb646s{&2oVY}U?({eP_xL+G_= zsWr|LC;Z5aVk1%vESO>}fmU}e42cLHOdJ{fTo7;M0vRH-QmXlPdsKSnPyHEQkHpZ+ zk0qT4251@IqBPpe@LzRuF?XuS*sp)iM7y4fcA{iGRFh!;MjJ0uJ4Z#RKJ?-=nIV{a zt8jsRG+SryWNz}(SN9mk<|R^1$_E5B$pUm~SAz_5l)sN#`5%=?=)`UjL3{GSE&O&( z{l~8K70EzrwahDNBwR-YazZ^dx&!$A)v6T?M?P1bvZpj8%Vr(#htth;g_SlCw)%gg ziqq`NC->H!f00~g1pRhKc)UMjx}BjVFbD~)c6s3%)JXF;4mfQUCZ}wiIk?Yjco*Fb z(G4ibN7dCq+OEHew1{$BO17Og6=Gaz%M}B&us2qYBX-vCu@-c85gF>_)_p+0a0Cvt zR59dj1h>u(nDWgp4uIigJ z5GB#yac4)=&Kqt)wN*qgD~gO?QJdJY?PG$77V$}et{CE|^wGI<@_g7~*`An1&{ATE zPvR2q>dh4e#V+hs{))bP8Kiy~r~VPt*1V9{A2o8yt`sK>zAwgT(9>e=gIas>4BP+u zQ|{l;dY`GwBpRf;D3)M~5?oqScP*Rd2ZIEg7R>A+)#`~AvT8L6FO9%{$kZy45+<_) z)p!MEdYNOI4yWBP%FkG2E)|-5Do#goIG2o#--emvTy$&uZu@76irRr#uOgG}*)DHC zu$NRKv2f{C=u8E>Fr)k`zGRNztCi29 z;bo63K3CgwAZ?%&@qK)phhbPX^x*__*Z5T&A?{z{{2mo(?3UINP#jO(e7<|Lx|g3t zWgY#I0H4KO)C}ugGL7I>z81lKDmm!d_X_OnnFnqolKSb1(LC&e*jf(%JY0p zba6UVwlbI4XFg-Ry;!Q}fjj!0_ZJE3xj^eD5vGY|r|m2I=bEL^G?hz#iLdZEf8E$T zh7QicjoNe?x{U@$REW3kNLC?IJ6C2A6NYYyBvT$e^(q-D9>~o`QNF|v56Pz zkNX!Ec|(E(kg70hKNruSpV1c*P!*i*5vY~l-g@qFkcoPmTO!!IwKI?3D*AYB(5X^!{n~(d;dir0J*52Xx#T^&%fu}5RD_~vBB6l z$@Cj4(oFW2jWzMv&u7}lPDplf>^D=1!SYE+Ob?taJ>8A50x6|OoqtHP6|CvOVW`l9 ze#IfB57I+RVRUV;PVuiFE?J6zM{xLi*%b+nH0hEDu|=y9{c8?`FODqh^_1xAqS#DZ z`y#)RC7^iJ;dazcQ6xXgk4ZQGqoU%|HM~JWs{}w^3q(!?Fv`YMTNL6@<+ zx!ytp_JLGKV&r5D0E?9R`bZuJ-%3LFsKn`)P=9mozVXV)~p8$<2+U+A{5;Dtzd2l zp$B|mqKfHJ4ey2V?T8ge7AV&&U9YH0`TJ4#Mo_gN~vzAtU$C-Kb*NFe(5o%6~OyBf9?0)+=6?9@Zj`*+T3sBQ`R3#0mRaUV8RfA7tQpiRKfjk zISR@Pk;;?oUy-zdOYe5aVfuSZ?_QiW8&F@#lsy%Ei+Azqisvqksqc?`SwrS_T?uZ1 z?1@h(0~LPkw`!XSJe6NTS>bBez=Rs#jb%^kz3Vjew!U% z5FKz>?Kb+XG4w1RTc`2a26uZd+o=?{BT^1 zhZ=S<=O;18Og4BkbaT7k81uSvAl+paGXP?*ZhH z@_2rS0SFub%2CJa!vb&r(;Qn2199F*MqGfA2OrJM_8;e`iKklq<^>|SZDW&^K+yc^ zzbaH;Xn{Oqp%-@OFbP@KQ$d<&GJ;O#=<^*Qn|Bsbs^6snk{SEQjO-IdYWI_oA z_}yhgy;tdD!95w}zkSVs(~HzC8^r|9vCn^+$S4OT@QMi;RFFw@CqmtEdekkKT6M+S z)o+p9ZJ%y0nV#ct4T&dgK8%{TuGM>2@wRwc;=Zn1bpOx% z)fs}!Qctt?{rb3&o`&EcT4C~4wTMJEMtO628$h!DN2zM$)ZThBt=9&wZ>ddv0&?o( zkY^vI`d{>b2lavpdU`jaj+fqgAMjxy3gUG9MQ3NZ6SH4>n>d zR5B+Mn9A**8qtgzF%YrNuY^O+3=EjbsaBxCz*Qq-_4Z{4POP^6E_`{A(aA8P*0F|z z`X$$_1IQfh{EK4PYW95?>hA39^;_%tFPXuIAzb-@TvnoD1>0-@=S>&)@ zV1)(?zWV;`m%qoOstr-=6UfET)wSdyGY5XY7x8~A^D{IRoejwKDb zI4XD?2U}~>O$gkk3b=}RErAw3g);qWWCKDpEU+E2GHxM~-f2Hk3>g|x#Lj=RKrV#) z)E5@-s+yOBzHua3Z>?5WOBrVHU`Yp*pZ)n4eHPj1h$=ht#%o*f{2M}ZtqcPGY)+`; z(cShGJzH;oHR4XPOL)Z;f5{5VaSr(kANF0(;ZD4OjUW}aOK)5fF|phrJyu#H7NR~n zo**L8E()cCMmnWIc`yQs!X*Ljsai4fcn=Wo20f%4UYjH#d&qHjiUj&Q2wmd@`@P(hIEg zR~wX!a?lXXiP6u3zGEX)riP+~ICnFE03v&Z*y1Nd2F>0oZgr)1|GFcp|0VlZV~)JC z0okh;uJ;)|EES<5oY-hn>*|+1sl2~vt#hOZQ*j(x^-Ux_$h;F8^F54gLbr)tOL-YFAFS*@bH&b7~cK~YuD>ur=ZqsQ42~Sfq z)XiR}$%Ytle)u1oA5YYg{IdqDu&JlNUE%c8QK*Ca>g)kq54?6r3inFoOpo^m1Qmy# zo~GUP8K1wwqqm78EC9vS027C{j-4%)d+*LkXFgY+MBYg~u+`3bGD!1HCC0|@6YNL`^30B zSIEjDy^2Wjw?DYR@rms82ri#wGaHSym zi|HjQAI|a0*7845%1eVdaOx{Ml24?tuYqy79Z>6^$dY5;6bLN)0TOsm1{twT9J^9q zcCC?N-(O0znXh*4Dh;c1gd}5ZT8MD-MyTA zqH{?-Er@S7FbZOU%ZxX~sxHi?V<;oHynhkQamx8b5S~$b6zBnsc-Ges)Ou!$X;OC2 z3o;!S|2_ZHv_3Tc#MT>?jYy%`e(#xUX(%yp;J2`T_B+_j{o{4aI7j2r_aIj7dVLO= zCY}gT%l@>zl=l)}5l)KAiIHx>$-(HL`;LWeddGYIO{4PTt;@V}VnHsBJXOEdY&7A< zlH}0K?ZQ)nN#{;A>le^;3)tx$c&0W0(D5!^%Pk2wlXazlk9mj$;(CJSO5SLEa>WU{ zPl(RV8(|GYE3GN1cI@urU-viS*8K%B74etNZ`JcR{buydeOr~Q1^dIu88`({w_FE4 z`(y&kDs=HyWp!&r6pClD!;S3~TAHMruM1mb8~LFA*jPuhx~H$`xTv;4QNFUP-G9>W zV4h!sIG(u~p^8fAzAj{73AESe=R0FPt%c5--5MSPX0Tm^6tY|@{r_n8uZr%M!qMlK zUzj*H7kUu94abKIbWIfa=(L8u@XZ3<`*A!p z1zw`KCALs|4EPJ^yj)z~%+`&uKYN<}GkfAJeDzlc{-CpamQ#s%h0gR&Oqb9o?fB4b z&FNA+*>Qg>p#I7P&iVI;VQE(Xzg8W#9>FEL6Llu!&x{&1UO`~H~!Ct+<-=8t-Dyb@M9^G~Dx8NY9OIX0mj~M>#e0TMV3()slP6$@lYJjY~3RB5el*ZEwo>2?m zA-!g(KiYU+?$|}YYRyA*{BgELbsS3i3NA`XIF+*5VS{Uh0|E_D%opsTlA&feNS1yR`8Lwr5Y*;I zskv<#bHWB$dUI3BAs(1isWPvdy4YLsS!V{{d>Up?sGNDse#xxa+#`(DNV13h=@iHdoH08=wRhF-*&<)9QI+ycxf&r4@#s zSm;QBW`cQBA*l?n;!`iqI8SA8q6`uwz4o(2BA^t2U)Zq{{`bgJPGxi$4ABdA(={Ksr8MjR{{7e=#5exQBspNR6*D@=R1RZJ>G-D*E9I*pbx5Vn5YL^X^ z5K3WP_>uso-v#RUeJ{(waH@~2pW3(lc zCZsh`SL{jg={zonaGLz%n&?XU>y2oM>lgp<{7?(Btt)q?<$!zJ?Rf$L0Y6#I{%|q; z&xR4lNR#$Xew{{&L-oMiS2Eo{Psn4o4Yl809uC%R-)&ch<}uQZtxT0uq3SV@DXI7w zcRhiXqOgm0a&vHR#UfI%&$6zPW;f^uvZYMfGRCGAyUpE#RsJD5 z=&6YXU&EDgdLh4t0>PAQCLC>b54+Zhlj27b8`?Th zzr0<{C;75xgILk&DP1#kCFl^pg@`>&>v^!J8B_9KwsGl%Q*JrdoNO_k!4J0CVuxx_ zo83Hz8-sLEwA1#_qaH~lODW=D01V4qC*ERzn>2)fswT2JZ>SKX81$8scfliTu~}V3 zCYo^JBIN>6^^=)^Sk2bW+yj%p(y}blz>T!W=NLuYNK{t7H^PBrW9GZw>q^hb7j6L2 z1{2}dH_d)_x#8pa{sG zNj67{nFRwVMl<=@>ow6KV^Zbl#UHsBtnL5{^zwHawseFbNU#2_szC;uSqVREnv@Bt zrJt3{nUK`$X$F})ll;pTSW|CfQzZ?=`r5fE4n7`@S~6+HE1k~G|AFRVF7Z&zWir6W zYvC{DbzuFYy;NMsgFB%`*Y6KE6l}M=u~ym9FV34EP|W=8>S#R zd?P{1cEIg0Zb}vka^|O2(leJ}`dh#`{)bWE{Fc35Qd~=~{O(BA`xME2N!5_3X_@gDdif>nnoIcuWG#V0DO^n~M4= z!`%hp@%H>ReKq&x-+qSOiaR&+?p(Dx(VDT>ro1ZOru5f5>zP{o7x0cTom5x0#`|*2 z=z%4DXMVIG+a_`Z7J@?XS7yYq6TpuhXW(LcL~5^;Lhg`Y^>=~;@n3%g5Kp5F8C3Q} zYL&VBaOc69qlfh;MPpzC0y#p^HWoh;lWCb4&9ATC7~6wvkgsqOx$7$$-Cf8@eQ4%c z91zuYaZ!leJ3@I69ZP*|eBuN3BbP>wepio3)*seKM*XW} zf4TpJfF+ZH4U*ocw@V2wbuf(x0?c1}NCq4KfXWz-bQa2WDVVC?taw<3;-Oz7mrg3c zKOTue?3I`M@EM_pcdL3|QaSc{fkf}1ByJ63UX)a5u&E4LIDI*dv(w>6Vp0#q^e>3(oU4YT>Ra``HFPKij(k1}H+3}l=$V%P6DCu0DU|HIZwh7s<>iA#$IDDRU) zz5ao=i(tZ<0SG!oB(2-(jxB!#Xkf;IdS%0F#x$aNR$1oJL@3mgx_)H|7f zf4RpW6%jI7$*8G4%8t^r{&^;l6e=VFx5A)}iNJ$fSWCHzX zB|=`sRBaV$-V$R@hL}y3wr48-dNAJ*T)0AAfyDJP>DYz1Fmi!rqVZbyA`s6O2`=_ zylfg81{TY;gpC2CrLh};_C{f%_Q#z($=^po=*+a^6D|nXMi~%uRdD#TCxmrH44@gd0T)9s~( z&VnAMAWRSHL%#nZLDV?F^BBFd8|u+=HutoEPCddfW*i1sB6U$;8_oG%VTqV#I-@{w z1CF}SXNweuUI7W6USk3q%ZMiB=~Ocn$QdMN7XxF;f}#}L2fI=%JA0ZD0AIWYO|jGB zJ19TC#+o4)s~m8og}u~At1wksOE-(m2R>52F4(+~GnjQT-|YVI6@L0Y^0r(2QmDs| zV#9Ym5Eb?WA$;5{`P_+(!QoXw|B|as@BL4LqHJ*b2Ow}DXVjd-rzh72hi_FfaR8f` z&yvI!&1qy2`JxgjPK|1Ac31NnQHNEsnv05a&F`Mj3R|ZlK2Z}`3ymq|-9wEtl|}r% zfX?4s{TY#yD>SpjI+XryLMUsvDKCDNB8VcMMEK49gFBVGSQ^>Zp8Q^i5qENvAJnpG zI9}`dgFIVA@QNK$u`aNy*x;vu!frRH^MLT*0y>(}XeZ_2-060v3v5y!uY;V_^N$t2 zvNsyL?O0DIha_}edUsFC%m1RSLhEU{(s0!VNG`Y?3zAygiPo<2X5k3n@rRnTNqD!D z$p-Cn>iZTYA#bZ(aHwB4(JWV!Y6-D6D9LaHV5ryGEOnSv2);i*2UIZ;`LTg7Hjp6T z_n~`{w^fOOq{E)S;NuTS9Otgg&B^5L9M-*BOTCCQKi@)0KPCq&hjLO~4* zHFZrc5oAM43bRP*2SCA;iRJLh@AJR{;l<%3m!c1Q($E=yh`y}8QD2FP!8r5366SWw zi4;|yBjMD~0oQ*n8r3fCJV)CXpkqh*Pv~YZi+C;o*?Yf{LlP3oC{q?JIm~-=eSIzM zqPm^#Y%1_v^q6<{z{*7%YlGXApzTmirATGL-)#vkf4A21*@C*P@wlznS}}pI>9gJz znjBvcDVozpL%=ygLZZ56c0x}D2(JtsycGI2#}a;A)B)J1FuilB+q)x6Bj+ybtt4(Uhs@AZtw>Thxp81|V&)b@q1Zz=kJ5f4Ki`8O zaSdYG+u}fq@u2wadl;|>V03vI>)pHGTSgS}@;ti&rAi#X%*cj0bq4-NWX>|>X5xp6 z{QBXCql<7WsVbi@@iL~Q2=@r2*Z?k<3-FI6`Sz7<9AGizjC?UVU*)WA4Ec_ToB3H% z=RDI)G?Xw7KK62vc@F7D_1a|`f;}WBZjCKHQx)9R!3MW$$mHK0zcF*Mb4J7C*w_5+ zOf-8qStsC)!H18`X)n^!lFq4kfqkmp0RN}UWS6q1$?{OGtE|Wo<0$6PtENkE-vhEW z82wnJtGvN37VMbgW!*b)>^d``iAALx!Y@-pJOB-j$1u#QcxIibDJz>p~7%L^zl|NA$WXSZN-<)R1-nA4Q()Wjo zmfAQ69B$m-j7{Xdz>8*8T4}LggKOg@(k*E%*xVjAIQxwjwK>hhaHJp9Cem>v?vGOl zul~g{aC>2pb&Bb2>X-L#T_?#F@AGNs9R4~a#)#{9M{^oO{XsdFprT~2b?HLyNc0cC z_l(4Lbc%dRv#u|J;BCE=@Ic_LfOuTNUHWUVdeF-bX#nZVzW6f|*d`*-wBXebI1x;H z02frQ7CvGf4jfvCf!N^P3>iMa(5JbZeP4ctweG?9$M12)Y+&U($ErB-xyEa1jQ!0T zBwiAFwdU<)XWjqMmq5?B?dd^deGUMhw^BSerd^fQw7SiGS!mdD*xH2M<=<>I_&-c| zeRW|LR~Cq}{1igPxQk4|Z>jYuhkpmQN1D`?Td5x$HpPDKDE@84Syj5rerGXN^5QtS z=T3(}6ysY)|K`Z6%4w>qRniHv5k^`-5Au9I^Nw3T`%#Qp8-dQ~U366u8%>6Xon?~= z{Tdl-$*1dbCRkShi8_lI)f{wYG<~->*tp%%Cc-L=9F;^wJgEkucbKyM_Fd_btq!?^ zPGLQ~EgAgf@DrKq$z7AG31Y&Yr3i-co~-4={KR^gzk9D4Lr-5@8PLBfu5Yb zXTUIt+w;h6GDUhjz9MkZ12B83!f^ogC&21$JK%_h#u!eSiSP5;G32PtPvkqXrI2Cn2C; zFnJ3@8Wy#1?@#8YOkR*Epd#VqA;^&=Vf&X-BAyn8Nbl+EDF~nhVHg@(nC2MBBmZ>? zSIqAJ=kLXD1&c`f^lo&b+QV^_u1YB1o$*gceDyO;Tm}KEv>6Q{$jTboP5UO^0NRWv zgahN>{LRl2aB12FF@Yak|0kAhsXaU*+dg$z9v=azTF3bMFuDJPK`u0in1P*q+j3YN zfSI=EBW(2~Dd@Mlw5v+9Q=1uNDAHS8D2&DyfBdd09pdIJL?hXCV&$dyA<#W|?&jN8 z3G9)ZD$&pHG;zJZ?zgd|K>hyqzlqN6iA|PMY z&u)Ko+n`=AWmG;t*n0j6KWyKgdfrJqe|bDmS?4smj&>xIm_TOwXYu@pm+kkUaps#xkS3L4?1a7} zK{M37>EPk8ZGZDSP!?50ytfbh6Gj$wL(5_Vh=iSg79+1r>YFId{`UzRyq&_z3U_Xx zUKt(}{B86uwbC0zJqH@c*w*Ye;fFhh1&6x$iwPXa`AD2-IX+Df>3nN6YBgwmE{iNy&V> zQs%jaHB3Ll8~)Z9FkO4`CJwX%?7tShPn%Dz!44fRniWQ4#%0JhG}Zvb(qSNVh$;VT zd_u`5hRNy?_yQCrlp?y#Znr(pFTUZ6UDUnaoG|Mi!1X&~3%Ic9iz;}*6^rY8dZHa_ zcs|wNW$@v1ht~w2BY~LkSi>_OZ-+EsXqT+vXUmQaP<3mnfzA& zPRj<-h)i}R*zZjK8T;|q*$Yj;y-ffnZQwN(%$sHl_Ox@eJz@6j-ve;noG`GNoi}3? zNh@8{m4Vy9nJU$_mI`(3{0=+|Hn;`>60D-u9_Z@v+`=cZ4d?EDnG;quIlz4M7B50e zjMIHv(MxdfMw$kxj#r{2F3sfW#r|QIY$D;P=WNjww%BlUVE1d*L~g6Rh%J#dJEP7Z z#gRcuYQ>NW(FHu#M}VLfK!%V41&1Ih;_Vb{kfCjjMmY{OIxuSDNhYaswQ;^rQ;6Ln zaE+L7_9^e)^XOZ8YU|cp%cb4R@A7c!D<7p}E1YRCgOwf5SAF;MILs4F-Om`15kjE* zc>L4#R<@kfz{uWzj=;d~y)D(@&|-5U4+74F=PI>69rs*JxOMSGbw(aO^KdJD7C!_z zUfT+9zpYn`uA>XqGo30$$F)WZM3>oMBAxJ)ou+E_V~<{2N{+1zlslIj5J|yCu!r9u z^G%hpB`x_bc=V8YN#?j6{8?!7NW~Gk5wUr6s1KiU7gq@@FdgKn`ZbkxC1BjX3nkhf zG{jiKK{(#}t}Y%8d-`(;3Q~U=c?l1^Y^NQp$nS|cGYh0n)!3S~CxvkFB=GiG`Vh2$~6{Bkaeb z5~d?euJ5E6_SNM}U80~OemVI?ab+{UH3kXVn#oCuPOcpJA4n*)waQgh1#_GPJW%ZG zD7jZ$!nuU+v#0;Z;0(E=XQoVvPu8REqkd2^7m@?L1`)DICb_z|TkCfuekY`^5j=5T1iTdO8FJGXTBsBQ$bkw3Y_^a~D;iIn;O^>X(9npfjHvu>^b#oP$LZK?RFY%;66v zPM>{pV`G7D$^6IY#SqB&a#b)s_Ahi5nOy#j17m*d!we>s`wHLd!Nx+r9WR zm!2(0A{=!%D960sE<0sHYoW@vi!+b^y$X}%c4LA!^~2p$8*V#Q`vFPTLA&7aN6xCz zzX|x!_D1zTO|n)Gv$PY$f?D$<3m1k@XObZiT8HVzarNPp-SSZ-c;Zh(gThDu8vL(O zwrZiTMLn=nXFyYHqjbz=S8vz$fveq`&w2Nv;DiXC9=ZGsE?hdX^o?#YwM2^LarLRE zH5X*YJD0|->jyr|sh8)a^Rm6KE+^ys&&w6-k##qs2{sV8NBn$lA>{*$3f6tMlw&x1`4?wKJ{Au-}Gn(!R-4(4#jFe|{+9;r8;_-ciQGkpQ0 zBqDmK*~!kYwDWS>!J%0X+0>##XObo1^zCaRkS!&`Yi=@qXZJw;E)a!v?XAyO)k)-n zsveR>CASZ2HkKkb)cQ`(ju?IAJiVSJp=Z7Rwe7if+?xM-m5NjmBw9p&hNOEZ6kD^2 z-Y6{zw3TUIKB?*lKhqw1cZy=nU>C$(V$=2jkzm(_|bcuCJ6@~dW9cn&S7?%Is>8PT`*UC zue2}T_~Q=TOgME`@xxQrDCTabUMlq2JzS$zIbOvE7Y#Q?Ugv)8R(UP|Adsf-{qawp zpm#aeN}Eg;umy2z1fK5#>X9?InjA@8l_zO;q-06kycd1}R``o$t{}{i`T0aW~2=@3?T|a-xLtnJQLD5q{_tt1zhc8k~28 z>T?u-Ww{iXYj0@alUZLx=nNIDKTOE)-@z*vSNEVZlfJU;B*Z0l z@1CzAd01pWZ^#t9tnQEPskjRt}OAyYcnQ zu%&;M^pearmM@Rs4X1yNR?di6OcgaSX^SF}4aX^`vxwkRb)HMv?lW`)TahbP+21&0 zh1q@jeo#*yo%Y92)pmCX;fn%KQB6mx9dbpe35W<}tWy?ZHzb9@tJNupigGAF(RX9W>Ju zaZKdZH<%`!dDUG6Rj1J%Iuh!F@mB;{@ymq<1P7fnEM5eM_=*X3mAObiuYum@ni@3X zb+n^RLgdo<2Go<=}OfIC0kZ19{vM8-^yR=Q)94J2cGc~RE z2aSB0>`V}i=v%dPlwv**83*g0HD4+gK6QBI~o$UG7qOq|1qn@1w!?qJdc zF238v3o2~qzts}Ou2w0v6*_+vlnXTsq!RsGjrFj{i7tu@X$^=+(^H6-N{K-&BBNk|LL~^N@`=JFtg}CZ-tmfJ3W*mWcD0TJRSay`RfI4dHEP10D`& znENR4k9Y|ZX}fsL3X@X;q>ka3$s3lN?7G2UHj1~Cd4=;Uvg8O{l>Uh56GO2;yr_PW z>T{n2$>fu~gGUATKZPtH(J3DnFh!LBEkE41Ng!|QwG$4!F4JjqPW;lvJr6tu>55e| z-!|!sKSI^s5fX)kgc}y~U@+74cEr6F_pHG{0*~(P4j_CsReu<9sXqTm+Y<%FJy#ES z!gb+Qho6_Z-A-yR;SD#hCMc^RyJgMN&^i9th_hqJ-pnt_`o-w*FC^!y<;iRuQuo`u zrJ(ox6TctNVCYlgAP@nfqKu?Ydv&E;y@S>LKMvDAlC_awkxw6xf>fT0T*|X>i#*Db5?1s95;VZ%w{=S{#31>>zDDmr00qKM~r9oj#ZN1s>_MyhaF;g^E;@u6N> zV%b{nC>qB;+|*6naY;%vZ?LQM$4Ohtp}9@=iRwUupL8F6A|5O3>Cs?6Jk~kbAnm_$W*cny1MjnlLC*u zA1iDV8OZhVZ8jFYC+20=+mA|=vQUFLK}jO?K+J2S_RTHn?w(X7tQdKd+LHuj1#W_>8{NfU2h^*c)MU>hF)FG%V;7-tIt*Ru#ElhQcI475N$gNn3_rDG*$*GfQ(Vn6{&o z7V;_*xxq?lfYuh_Ct?mi#&D z!iyWze_OX;$0+|NdDqT(JFhwapRVe47X~bgc3XMBkKokrkFQ_(X2bZD)BbbYT93FW zmfT;lrCC|h`F8QC&8J>(Dv_&?uk}j0QyF6CklK`#`7tggLiBs%$QRFY5_`=a5_(Fv ztEbU{|J;eFJhL`Fc>PyT?_}%Wg^%yid1c!D*1E|*_gsAIT6M(dyZ?SZWRCwwr^jXl zly%IRcVSTFL6z&ofG>vI_m*w=xkuyvKZl)LIK?5ta`&z`H!XVo@^kaLxv`g5=T7*> z{D5v)@72X)&(0|sa^~u6Z5UgBAmr48f}DDjRhpaU#}s8v4E*G+ozVBVbN}#>k%xZi z$_u>L`*!T8lOu3}t=p|5cNUC!d&MNIf6CLyG;PC(pKM<5K6*D|=+gOPYN8f>vc1R7 zDLoF%x_ZPoEdN6(k}-!=4?VJT)5)~g^JS-go-*;|?>GDJUo+v9?WYZozKy@}?emYq zmS*ld{(5v`?&Mzei|##~RDJW#spE3ZioP}0eaotMoD6Rs-QxcF^wC+zRiOJidDyNTT%$YH4*?;1$ zo}9pxf5be$`o)v$W?F8uC@b5()Ah>sE_Ji)i_7W5WcD62=j^x_9U5nv zmbyOw%QJhOD_*z_`DTT5|G|FtC#F}ApFN=bX!NIHuHHkhv~*4H8F}zVcv{8>NgE&k z_2|gL!p1={+e_V6w-ziJ{Br2Wel|V&E;zb&?5Dyv|75EBynB4z zCQbGBKbm)S?>-9Yy8m@&V|XHCQ5(%yEZ6L>`{OKoQXg2XyYqS4{m`Z7N*;AhXnFdy z0sqfj)St&|{$5`(`%Q&@#UR`I{7uK=BZlmn)cd#d-!EGiya zOLm_fHB*PInbD(1O+Oob|77X&7YnDmtZ`qO>>eWUUsCq5OOK3!Emy8B^L0*lpUjee z?Xm5nRq7@ebIXl>`DU@}m-rtZ=-YBF_fwAxF+HM6M%$mb))bnZ>VC@J{MhM+;Z7U= zc+#h>>b_Cja*gk3>!)X3XNQjZX_Wf|7YE0to}L%?!o~V^+lg5YYqF2K&EDER&sTYVyzDT(Lgq7JU2W*Ry>_8aI5l zRJ^arVfO>?FBVR4*lySAw8o-hiM3$sy`I}|R5jdx^|bTTYu{EZJ^X8MsP`9L3qJ2Z zc>eK=ZyGoCcw00g+ksMwlLUUZy)e(9?5D$Jx;z zt+x0v`o~=p_HSCp?)dhY@XR;m`*Yt^)Xfo0P6+&T-t@!kg!wT?d@SbuV*c&%ev5DD zesJ}Ev+<9D)q`&ZoL!$aqCgd;y?^VgyR{alFPArW)>^%u_d%ai&MV6Y4gUS>`|{Vd z?r&=KC$|Wi=h`oC|F+<1+scC0w&gR!1B|zXoz{(exBvU&u8)+)zqlW)JhZ%5M(&5R zGNbP*p<>@`95PyZR#sjdqx|gGnHT#FTC~`6!`C*#hR+?uDLqc#K3cx@(Zq*uW+imp zO!#nT#F1D33dP6WgmLb^)$1Bm9l^IB{PSb#jdiBdy+8NO+%@dU_;sOUB$aC>-WWe> zUHv~*DQ|N#%|5^5sCjDl>rMYL&pJzvtZV4Zi#juIp^w<9{D88=6UU#8YDxK`dRR_-MBU^sRO2_F`#ZFG z!^*fFx5v(@{^h~39yc}jt`=n)pM`zllm)j!zwBw7w?tWFT4~p;?v;4o0eT% z?DsN7T)tWo^@+u_@_%-B+6^xJrFrqw2CMp0YeU}N4Y?cg?}*!Lbl(&lRmRqJoZYJU zI&Axno=fKc9^aH3SMqJ%>IES;&m`(ktv8m=eRE^u$cDeq7;E?Ssb0Bm)P*I|@gzRjlPhS`9BJb7HIN4`>Qq%ZNOY^>5vo5-yMmAyDiwUh3u0Kizmlhq*{d}GgbDJH% zsh|D!w!X1*{f+*-wtQS@pFKUKA79hWn0Gj9Px09Og-^U2w*2tjj)D8-8yZ%A?6*@J z^{Q{LNdr6QRn+{*|&=vuS94(;YPbJ# z=-BW-PBz$h44MAfR;x`bEr)%uKkSQG(ZW$9wtcMZUp92z-Xi-SYu=_I^IRGTwY)TvF|)rxyR` z%cOOm$v&MnsKWT@B;%7-7mcD*Lqg78I2bP<{w(C*#!vjM&t|F{y?%W*XpYs~H^m`0 zzBAsl#6IZw{XxOeOZ$bW!c6<=pWf~tzbO5f`rFD=%ccqJYQI~3+P}wYr&E`+eiV!y z_aB|rs4ug&^)Nc{;ZXOG^EG|0Ef_IwN5Hv-+0EgNom;J|R3EPPY6<`1iv#o07LO8) zOzv~!YD$sW%i&O>cK@S+e_DYS!ifZu-ZpMR@INdB%k0^~wL{FW#^`JbLhoTfa5`esX2T z+1zniA6C|eH4ShcaDKaRwf^aqq;kpkqtzD|A0IcOa%t0eMb^_zJ_BZ!5BfMmqo2{c zVSI7u^w21m*U!fbk3Kr0i1U>;IUcz){7mt!0e|(4NVyPkWtwTjk`1OWf4Fht?p-)T#SPVc z_K9QbJG+{ZW~_hH+K~74hrfR_xb~6vi4~8`;_p8B_uE^8)=gacG(%we?5=e2$d3dw zH!L*CGCDbG;onXTXTR{+{cfMDF!1)M;yn4odDZjB_gptnB~5uSbZKG#50k?0M$PW= zpRaZvS|f^Ekn(q&!0yPy$o%Px%66~uj2KhlIr-3wSrtK_zp>B$W9W#KO52jcK0}n| zUyZAJ88POyXiN3yCd&R9D_7s#mA#^JQ18l^bKwDpU8JpHmg=JkcA|F-^ri^~F zr~lr%uU~UHviF(kf5iDmTnTu3cd@K6d0lQ-(IUJ9>B0`kk(E>U)JT z4`h=yRlm$}x}N=SozLW$6_0c&S6|*zTKHZIvZ{FbcF$;=*W!;0U;nho;m6NTzPK@> z;IAnq7XnwCM#YEqTobbF!`?54_wMX8d%5T4i3s!KZ)y{exLX*YAlW9cxQ!Qv2<=bt5k%=E21p z&wDQm#zk~gw3upSBX7xve|Bb>HbR=S@3r*Op{wexwPW8!qy?ScSTWl6dcd+Ve@q!r zG45?j<>;pZ(}Mb6U)zn_QS!m?mgW<$-tDs9Sgb#(F#V&YQf_bT$_g~U$Gom=|LjHG z2h7)cLtVgzABCrv+&MV0Y zQDNf!pH@x3^YYHY73shAW+&^XZ(rB?*2ZUGzdhOaEoSeN3p>a5e5!ohYp7;mM1J>^=XNY-)%>UX$30#AZ{?xcb#EertD|f8KCP%d z)EsfEuHf*ixt2>;#C?2Nyy;3xz5a4tRM+9Fi9YxG*w4{)4DwRG+uOD5O|0|Vu}>#7 z>lVblyLmC^>apy@i?=xU*}UHW#npnRg)d$nTDj8v+VH)zpTAuY_x9$cT_q*YuceOp z_uoVRCOw_O9No@YK*>Ebx9ceenVP z^`Uo+Iq+x06TYY4s2F|n8SDF>FW6__jAZ{AJeGYqWE>mtqYeAY!j^qLWFi|dbUZV) zn8Locv}fOsoW%MKnZ`c*aVj&ln#R7ebYNc(cVyp;aAX5VIJ0j?I2m8U+lMR{R!z}H6*pK#s%wqB!_Klqg*Vand50k^#_l~pKNC!V=<{ZR^ zIm~54T|=0K>s&U<5m5@qdCYQJI2-B~#w^{#*^p@xW;J~w8{xW$jhZo^Sqm1i5uOoj zgiyjp`7B_gXD?!710vakxsiak6tI@D5i@^gKe()7Ke|OTt68hqs98(da6dU48Spb3 z=^4$eJr!)Ca2XpDv=r@rX4XO_o9MfeSqHCR_Wse#CUiNo6D?=sL`r5iU&(A2YS^TO zDmE=h#iq_*&ZaMnVpAhlFlR|Lo3TjE1WPn*=*%^2nEM)L<-L}Tn7x^e^p9g>eb+FX zfOTv_;089zZxb6AxS5Tg8^cEUZ)aoY?qCyww*qGpvyE8ICg5Q&`Grjk-NL3U*0RY< zHn1sjEoj*VT6QoSQ3{(hKbcKln2Nf4*d)nbHaYS)Hd%g}C#P9h(ukn@wM}l?kG^GmoWu=B?h&92f0nQ)LI(v?cqQU}*+(`uTSzSpGYk zx#BSMT>dNbj5@%)Rvu#0mmgs>6n_ENQRcexD05kr&)lN(nNXF@Jk@z@rlyFE*>aSP z+nUS9Z$F0ra^^Ujuq&TUOg_on*X&}m)+RA8y!x-*#f0lqSm1^vHd~v@0ypbeXsnL; z#_VBpQij?>KqpMOAhl{a{_JhS?HE@CffchTevfmMeI7j7AE}079<^H z;-uf1O!p_V*A=tLdrq^-`%8iEZzf##H}l_E%zU*aENJs-78qO39Mb+~esPyr;I>*e zZ^s2TZ|5cExc4lZnsJUzJ9wVC{!z)C4_{<6@RZEdZstSl@nt*tCAtgZ0D*2==#+Sc0A%G%1>)(-FR-U2_^+1c9J z+1cCL+S=iRwYfQJQfpg#J3QOjSzB9~104R@0hW~&ezdj*Tnj5aTL6QFg*mcU3(XS5Z`-v z2t0(S;ekKY!50F7y{!vcdkBO=fCNQoAV33KI~O8*vc0VpQ7^Ff5ZVI#4s(IoV5>=% zdlW(d6atP=446W+5?gbqsE9(}iG^aBP(pYlAVpyB;^N`~s2&0r7dy~}0^$Xz3WQ=* z2Z1gil<0Ip9eaENU3j1cpn_c49$SUX%*0}+c0h(0;05+ViA;=+5_zBo2#6{8NhlVJ z@kSz*N#$|{K#Pe8p}>}?Ko0>NUr{v~wUrPo5A@hxAO>o}YA<#{ufbY@P%0MKxd;Jv zkJ;X&`KC=g3Qomhf@U@<5qV(1~1N@Oy*LP8xTswDKCSj=T1 zM)wUO0^#%nQ3PIyi8#|yCX56@=!^tZfHLa(ESYeYP%uj(mZBX%2_;ggQYuqQ z!7l0+@S;7QrBVr+iFNzT&Kyk7l$e^BgX_Be7XPFx6bh*%L7|i>q~gRxr4p#bN(JZ< zN&rTgAWc`QbZTX!I5IL)DN|9A$s?r_$U+>c!I!fl@mZx*ChBAfN~Jmx_*F`U5{(ry zr4lR$?NX%}T$JhdnV&tR)9D3fgDk{Ar_8cAn5B^E5_M>=#FIWzsZa>Ta)pu*NWgX( zuminZvu4$*C7M-{OHflKj|2-MmC9ACWJ@Aft%{V(mAchw#3hAVuhXGMqC^6YNmMeK zB0&MnDy2#+*_Ua4MwhA7r+b(gn|VkTGL`y_`M&DJ^z;KdwJuSwOiWaPbhQ$#&>TfFdRjhy-qwl7(T?_6EyyG2Aq${-s#sw-t`l~gHHDj-FLDltI~I65LKQhZQr zQIn}tL7eFx1B}fuIK(ogUUkh@cU7OR)ak$gU3xm0tp)=XV4q9~cuKWcDUMVDz3Yq_ zuFmroE?5}-i+Z(2wK^L3=iw{Yc?%XTlFKAYp&Ff52%sZU@B!ThPXShyNK`5RP+DA) z>7YE2slBO@xd7}}C1mO{ui5Xoe)^xRUw_TW$jVCJw{P$M{TZi!-Lq%k>3{a@*}GT0 z=j=acYF7We_~_A`%A0o{v>n7}lz;w7Trwj&`)K9OyARsZ{>jSvXODVs`kp=ioZY8O z+I>1>-`;e+E@4l`o;|yh@c75q`jA?gmI&^rD?Ln%EwEuCRjCf9{h>Mtqe!-jOs}<_ zy`?1?NmzQa=C-!5-IkUX1N(ehdF5t(!-KY$1HT^0%hz9g@yXGgoAr&4J30qie2q#L zh9+o)>B8F5($3ZjW|v!JOfo954l1r!B`RcOe=zonCohrisoA2W#u##Uz9-#VRqA1Z`}iA18%xWb}BUQU+q zf|s)M09RU&8;j1jwzt20nSU%7B%I1mSsvh?U3DMdwYPzu!os4W!V`EQLdwc3&J#(c z+ru_)jNwHJeM?7=F~oJ?znMe`tsIl*zlt370?$H7E}Mx^@@s$ay;-{R$3AR zaA6x`;=tIA8*MEGVwhSbhIyjc)Yx1M{%58g%!Iw($(avMK?My25Cv55N|HTMPymLf zY-t7usH7yvt_W~Hl2iYPJ{1&z`^6-5u6Z1NMd``Hn2<1_f6rSxD~vd3V7gA7AT%{H z^KenYDrTmuBpy3}Iu2}#*-C_phyz>#r3NJ~K1n1%0?7|rp0q&++H;d3eD@=j4g3>n z9(Z32>30_*rF1KX6zLQ_<6&!VD^Msf0M#mmy@`>jSggdvlc-BqDRy%Fz-}m_I2v>R zcO(`=wIPC(l$MsKgt9Fby8ma+9eikOBiuk<47DW+INKopt%Q|hCn7`}C)v7S#?>-p#WY^D%ejF2n)kFGIR!jNd37M6hP}*sr&7159S2qRNiUj z+$RBnzCu1!x}{KYZYy<%OP*i@s;xQvG)bZ^5!0KksgadXqEI9r%uH94{&7yBBCG(g zhlPe6Cxu3#K?L&y1{W1U2l9_`j<-E(sIPD2=<^|b;4VS;xe22BAUFnHhf;U*03b!S z7C^6rO$G&G*k2bRW@~UmsT3$+dw`s)ACU@r!wU_72o?tj5@7Q{0cSw#!zNf_41L%_ z{9>rf2Tc)a?a6Qh6tb$+H3DjFW-pM5F+u5Ie@%?c1QMYlA$>KbL!lx#OhlAYP5d+P z>%@PxiA#WZKpZ%h+uGXN*4Enkf&`IY06rBLSDZT!#&g44Qc_e}h;a;n92ojS><c) z(1MPR4w&MCQ(XDWE6U5yk;204m6o2Q?g9*Th4%&4JvhY5!b%_(CnUm$lSxdBZEZbZ z4lw0QR8nanBu*`;0dGSjhzuNn4Js)qE%L?NPZj+(eeRMU)foa_$? zlz5Mh6&Ib#PmWr;?C!&kt~V(8r%rL33wz&fDIl{#poZ#i+ZKlhjR3GTM0B#$+QN>z zd@_|z0sCtU{Yz9`O3PGZeNkR^k`q8=13hmx;j+qVue)wtWFo6=O7D`@- zTBIpJOV1D>22DsRdJofHglQl@KQBKo7U+-U+`*JjrL7I>4+X&3qrqAZ%YRa|k@&cg zxg2+mWVAp4R{}0E;sZ$_j5xrDAUIH% zN0ZKR2;uAk0ulaWRzeWFfhF zL@$3P+JQY-bfO6IA^o+ou)`u-0S8F0kP-idShVV}Qjkg3!et^HARq=J09r%e`3n>{ zwY03b08{R4Lf_TZ*@-)DPvz%6ZhekVU0p@RP=dm3As`vZsVOyt_J#(BpTx{m0;l%) z2`ei*ti&ZUOh7W}0Amk3u`Ce|=x;ieL`#zwF%eAI8XWQ-2!WzuxG`)SxW8q2K+es3 z9k6?EVeyNLPvswb_Pn#}^_$nP3-XJL(0c>NfSXe<0{R$Yyn+3tqbywzKEVu#=}$Sp z*b`w7Oa%!EGP!u2VXB1?&y|&K3pVhPIzfem5W1bDpH2SOt5>gJbI|}6A@5;pdndkl zRamqwl&FRiMQ#-7AF2K}bcz!|JsV|-AQ1$BHHZ-NuO|c`m0$=a$fWDQ|8BPtj^p+) zm|{M9xfP>PBnsUS8!dPMV`LN3WSsst7Upv~=M5fLS$XO9U{MUWon%C}#l^vrZ}j%x zaJ2GH3;A280Fn%HL2mq(1}q6kA<=t7=V9_m4w!F)x6#Z2{CJRT$3gx=sUoo(zrCFp z@eO7A0j$&K^5p{7EEVObiB$vF0q`)6Iz%(c#^7n*w;K6Ur;RH#+&vhCEsa0#yFkt86r`~TTuG7?AQhNS8Q83OH9)~m`QJ;_~ zMEuRl7BMD;J`wR6$vUuy*Wr{BF{z}4fC%0jW|FYb&<--Yz{RznG!`0YSPpb{0z0Zg z{@@l3z2MYRNQqCGkW?`kTRsl@Fua^7L+JX0r2t5y9 zvb?<1Kmd(?uGxSMixNiIyJ2I+Ra_{-oXwHbFy%u}6zre+eihG&K)>L8eP1q=33jeWw?L9)b-gAOeFQ0TysUa01|k^Y}v{>X&TnRueu( z$?#*?`)@bUhI8{k z>(;HX08qoYH~183n2leVS&64R~eYI@)vSrKPm#9s#DR~%aB!`m_ z0l13JZ@>r)3v`+~Wx|*V0aP_;$`psG-u^)l3JIQ!UMQhQU@Cs|vVed@I*makhjBxF=LMA zTr||LuWy*<9k>C#C;me|Az>$=KLsh91K}oCqEZ!st-l+al3!S4_OXo}JYJnHL7`Te z7};72rLxuOt2IA6->Sde*mxVI@!ms}rh5(d@3)XkQB+z~Onx~ZSg=2Y{>ahF`i7>K zmIwFmH8eCdJ@5~NW!gYfKUNSWFdjvDvCC%vdGz9)dkS%98yC=X;0}>(-5d&gkHiS+C@8JO6Yoi$t zlg^`-2QAI5{{BHA0Nw{Jaya_sKws6wmx!2~+gqEPn_CNtOurmyr&7q32>L1%##sMI z6hc+{nl-Cj;YM{lfA;J-3_QS6llB)h&yv<+Vkij@5yATTdpnFD{Z~%?<4zuN;}l>S z+}i2~9i)-D5xvLqD|PcS5cz-rk*5j|m0-6QnSS-P0RDEODnThxV*Q8dk0yX$Gz%go zp2~mzyyFe|a>p=a@Pc`!qZ5M%GC=4j#3|U{f7+BWqu~K@=ikrI&)+}LP_3gQkaQ4> z95|81Mfnscz5NU@x)3KsNojxaqOHBNv)@P?7X-9H0Pvd{TYF#~tk$KiiH?Yvn4bb) zvg4J5B8b z3ZVjmmb|jLwSzv79BAVrN2DKKkHU=B|JXuMrT?-jdhx{A<@NAnXfDsqEr4s=*7kxv zVBrTlhh=YJnA6k=qqC1*yiZ^I`2}(c{QMq0dCDVl{@!5}DyBKHFhBLda}d=DIHyig zoNzf}=I{}_z8W~vPNGx70;-e)23cbL6DihZu2~haWaNr~i+AonC6T58f5EY1&CUE1 z`56F1@Q{`- zT?)669EYz)y4YizM2{7K*v!P%1si)ReH#92oCU*IEX}EEeDd_^lPAgX$;t6sVplZY z$H%7#Fz_j?s36|)CoH|1$o~WC4MAZWfPb0;1>}irj1`)<&tn#&)jBQLPZi{DS+Oj@ z-TlbL26Eim!G0GHY)HTZQ<@pu+G90@_%kf2}kedeDz^;j{Yd_B_5 zMTmVS3HWc;*A~GTY>%a>7cE&h9GRvN5-|zfKSgX?NjnV)@X!oG{mG48hEV@ga`u9t z?i;{?ATNjU)T|v&7?uQvr3RFRR_cI}yb>`=_dm0tvjn))WaLN$pb_&B!v>-Mh<`|R zYW?cpmMj_`6;N5<#F>P39Ts=sTzvycmiW(|2`oP<>+b`9$4hj7Bk#Z8RF0po!fB=_ zdqqwW3bqTdT=V)fJEzK^SM7x+BQ3FKCsgTa^9=D9dk=*|o%y?Z^`a%iH_dsEpT>WF zesb*cn|Fz89pvm20f;6!^Vvpyr+(#{!O3F!ZVsWylQ z9WmgSyvN_yPT(O^V*RaN9ldaP>~aGm+uQSKYaxFN|AH1a7y#%I!%is=`7Gtx=Q02`V&if6(@8>Z7R%0^{MHO&5DOQg`ml_*1+dVty z);$DhJ70Caf=nSqGfNw+xe`hLlvw}UVFy)(_*0rj6ES>w07%8&2HDKKV+E%mZNd+u zRZLR=Mpa(y6jbRXJGR_Fzy|2wnD@<~CnR?A%<@xcX9R=g5v@#Ly-G0xsPw4w)FmIrdR?c&}jl&UCq+E3W~gBkDa zg5}{QaN3m75F0h?B6o%8g!&a?sLaMZ)l4xW+AGS-&4Wuz0Isr|klfV_=F>;TK8n19S|C1M#igVUl{{X7z(jjATTwF2V@`320* zt|xNjy1;g_r0t(_c2SWHXcrlP@ zscVFEJzUi3f9Miq0#jpKJK6x#sWLUu^Q~#PbNP1>_oHUd&c65nqUIK* ztc)U)Hp%WE2Z!O?$FI1B~Bb2uR6{gv{a(ncOA{^5SEcFFShWHjMDsSbxYR z*l>_3OpNTTBx<$#x7BMj5hK1{7Enos9G=&)W3ez?m3K+g2^ymL*cgC&kJYDl>oeN^ zY;T)3)nN)cKN^u>YV?u@Bw{pSC&~K5_%$~187CLJbb$eWUf8MP^01jDiBv}-{F#tI z@qcW;>we4BM7VzORRHGyhfueU_FPO_i1YBZJ`KLI67(MKHLdId1Ib0~?0nGz{6K%S z@@^~j9@r^#4Ntug<_gv~x4D%91K1^-6M$I&UK<}cBQfQxROx*G!N`*0Z)s_nYvzx* zSP9eK+6im-`gP~ydv_bTlhwtiUdW!WKrrKk1uhTlhbv{x6fM)70s!=MRSy@q)u8 z3f^>bgJQsrB`D&N)HzHyVQ@PF$tI#!7o5s=?)(8gt-pvx;pBqD2c>y{`ttg9R|g#F z7ci_K#&qDm`9NH5qAdFSJ(*vHhe}A^std zN+Ok+zpq)ckP8QTg+l6u2e9X3oqe3J8(>ohIR*Y<*mpuL(Ae>^gS-CkSKvJK5`raI zDQ1n*($1HFL;%}Sv9#1|q#am}J!d53sK9@rLW1pw%+-;rmUzHnq4~ow*OLE2^H^aj z?FaC_(E@y19Ap3`FGS=uzknOIyikAQJ;es7P?SOx62imPG!x)Kw4l(7nI*FAu=dGR zCd%ReBN~O|oP)oqu>wN;g$m&X5#&G>BYc(0W8vsNVW9qF+6Q`!G5Bai1L9w_Z-!qC z=nbpzuwVr2$q-@q0rRmk0GxE0Vv`VnOT}rAtew%JNy)TGsI|U7+}xDU^}?$g4*;q%o6b@7+ho`DQW(p z+$0^+eRL{0;%}&5LXI6wc=XI0Hw)B`OpFqWBX9X$e1P0YrdG z_y?$1lTiV{VU`qsRLbD~D|G_~Ss<}cr9OxqAhm40p^AYEgdFHY5CVjDK9sfk^C)C>?v-tllaMef}F+>0f0A+hO0f>K6pQzuw zz&WS*D{`Z-=Frpn&(>ZdRjbl59ZEdr8t~IIZ&Jbo&<6a}e~N7Y{bodSVmEaMiYNrM zB?S~<=K}<6?Z(fwfC53=ffv9KQ#DB7+$b|^IDC|6rc)vQi1oiRQU8ZNJwc)1{I95> z5HM}ELG`+MO7UES@I#%vH!WZO{|1Q=0E*f~ksb2<;tb(;9{nW(5QG(lYzOl(BlDdd zV#PR$|4Y-6af6(j0mj&VMw%KvBJpn>@rX-`X7JMO-RNTs(RZ%d{$a5fFH+p+CJF_0 z>g(~iyM@Qf3gbczV}O`oP=s(%==O8(*-G2v<)f_aT*P9m{#6O8MC?By{s{*Bo{sz% zihmQccq!Q$io6w=9a4bz-4ELkzv<$w`UZrF?%r-}LcpfA`N4yGjSY{1Y?>C^xsPG3U z3EhT}UVY;OULHQ?0icfd=dCS>E+MuAzn}Jhcpw-=&?v+c?f(Ed$B&^s$_lBVa+OXE z|5s{eVvPhpY=xvBOiWN{NmMALeOq}h0zttxDn>m5dmFI<2a5x&9WRjkKz=dGOWJ#U z*4o_iC^sL(r@~Sr(TuR8&@;AkyZ66nXQ$kX@_!^`e)JLr@FV*`rPpPu^h#Mbe(V7j z)BYcYR1H!j>TB#!^V9;P^@R zfSy}ZE=WR;5`*nmu9?NygQOfhj*vWigqC6(A7BFtg`3Xf+)p9Q1}RWTHW*$hmu)$6 z+bKIaQHThf*sQNL905!Q2M?s{B)bSXMf1tmLR-k5p1A0-|4ry=9}jC#%C+R~2`n(S zM5Exh!6oeKLg)qK_XO!mHvmpLoKkGT8tAvCj30#(34jSYG5C-8p9;*tCV)qh0lkQ} z-w81a=ObWr?|##CLotx|Yf$Qc3Zgsk+R4v)O;ZsH-+(9Wr+*v_cEUu4$Oz>hAmx$b z|5*PFqRlvDgCQSDCEr0Cg(tbENh}0*Y7Oqa&wrrdSyYG^0M^^wJv>H%wPgXbFE+Nl z0zY2Cao`jjC*?JWkDyQoKmgAGfc{Y`G-f~KTALYT`wx2ox@vto@~=R8p@=&>-DGpx z!$lO&h7sd7ytEVxnVSuU)D!fc(C6HG$UQuGPlotU*@^dts2dP^5{}R)fFS<_<_{@n z81RY#*#ALNuugaIpk5`}QBqontpgBF`o)U@u2vxE&N}F?tngB7b(@k&4<{iI(c%u8Ql5zDQL(bzz!OhKbA=}{!yMket56x zF??afC=J06TK>^=cQU-2g$DFc0Sv>C6V?{inExo#Jy8*f{7d-1ip&F<2QeCU0R6@o z&V4dm)B?to#tnK;!K=;FAFdHKO zOhEaM2jP9GTxkDGtWv1b(+;Us!X4b~{2$p!rgCXgch_nRK+pu+C_$L=`?5(uNTm6Io7^9)=-0u$MvE!{D=u1*T8fCkKlNCWIZ zJ_@wYU}p(`Y0(K_hWYKD2>>w$`KOd}q=UgxE9{VekJ(43|2;7c0hy$3Ri%2^!A9n2 z3GIV(-N{in%>Dgy}jMzDd2Tn@PLlStzw z`t3UleBXh*R64eI}98k%`|IPn3Gy!@8uyW)@Adwpu03;L_^Zp~=h@c+qZ$1Kj zQFoAiPV)g@IPpg0L6Rnx5CJ@;mbP!Pi;MhQ4~0^%M*c75KU!fefXNT(=qg1Lv5M55 z+e}dmP3PU+G4vdt!2kHDfSb2rf1vcVvyux7c(H+JKp-WBm-jkL%}ciN0mTO)>Ea|S zd+hkp{G&_6{=b!2fjlT2Kj8V-gq=nn2oY^9#Wn&l6EfgVDPAzBxXF7T1IC!gY%n_@ z=guRVe%rejj)WJzH?%J$0%!#V=0gK*vHn2BU6qDK7xdpsfG`}=uT(gFvx8>MIG(v8 z5^XCfy8wQZ*nu4soG(WPele2omInmn+(MWR_>LV*S-E_+*I$*5WB?5*$RL^UgM#<% zw~NAI2e5|P8WSFa`5z&7_@AmYCGvkPu?>Lj51f2Sl#=1iWv*m3HvEmxfl@@y3ip!%qkMZ-MO( z%zyf7wMvr2g+wcSq~CMYl(s{oj}jNCU{iNf4mN&yxE~HjdrRZ3o3{`EqQd8>3skU% z<<+~-4ipu|g^(7KbT>}67I+}}Co_$oKQOU^F$R9P18PYEuYxC_$Dr@-13~EI6 zQe$z_gTiX0?udY3_q7%Kf3QWQt=#-_{)6uS)BfCcN+JRFm>3sZ90!u(`~@;@#5n)M z&!4C>6AvhK!z?V#%`MES3^p@2F*P$YH#b8WjDKb(ynOuON7x~N*UgcW%Aw$MdmogK zd-6KQ#%6;}%}fTHnxdJRsfh_16Bzz}u!-13Ay&cqsuhTT_co_s45DG`w9B?@_wUlK z_3`obS-aN9mzQ<;C?iDijN}JHr zbM87H!DLS~_3`xa5a8L=fRs_g#bDOmY57bg1u@DbB9w-pn<1{ID zm+X=3i9IG9J(Pd|oZw9IHOtUr{}uZm9;Sx#XKM9Xi+yLXCygUo$je1^1O@vNI4mc{ z`9Gvc%5ba?S-W)f5r~9hH@8Kc4$uG=xL`#~-y)-3D)RuTIOKQ?)kV8A+pMwDEI#T7p5;}y3D2W6zM!ZrY zk;@iIA|u5vC~jZ~=#$8C&@K`g#i)lPXQ)o%0~PoK1UivuILIiGd5HI9T4W`rE9m?m z_>ajj!?N~JBE_RXfs#&~AvqucB;Z9ZRjA;qsdWk@h$C!><8~6cQmI;v^9nd_C!944 zWXj|yh@-=zP%@h|0r53TuR)5BN`?3WLj6d#18sEv5UtbCSp0JU2wesnTS;UIyUl73 zqar_~rozcZk^%^!C<#)NFi+s94vvU`IoPQ}=!i}^0yjD=!8=p}ek2osK3d9SX_qMH zbxDL_$3DF3|Q!0D{?akAHpv1%k zv`(kpDbRL+4hE{RRKngdWTyuxByNE;C3*zv60xU;AXcJ|enI~sOys#B(I4L<+!2ZG zZY;Ir$h$|;9X8#&S1ukv=WoqxDH#U`_kc<7C!>;&@+zDgmd-64MAf91FZ+MWF{Ia0Xz|9Np)=r+Ei@1(Tz!G2e4pXg1hZ zV0R-EeFxK3YMgycz_gfo5R(JghHdFIzylq6_-jZ}2WD_G0gM99M3M%^41J_7(a=#P zB&6#OrK2P0G7dOFr;yv6m=4A&6bWiN)2Wa{QoygTv)`dG8$8M4EY6Y2)Ae8^;2L(qpRpbM*3;xjm<&qPJoG)N{9)E-Qyly2f2 z=mixBZqNZx1$qvx#)?}amCMfB`kM8y*bCOf1qS^R9J57E2r)7-4Iu$=0^)-_Gx3hJ zKu-m@XtIVF&?%`5yNAjIC=a*;cIj#S;BXmbS3_Rl3o5BFgka-kI8chAET*HxIF$=7 zoU!il!C*tdTrt?xgr4xglbI<#qL|{d3I7SR$6)%6irHZL!BF1>^-NKvyWrcwgLz9n z7x5=l?EZ$o@=t>Y5wPwXK=^e4|9ko$2mZ%_|8d}d9QYpx{>Op;pKyTg2@A!e2#^2X z6E*}N-k1M#PuM5@2eMB-|B8KXX2S;lIED=zI*xrgbOP=No4~%buww&<*|V>#9N1UG z4flb4HInWFb7q5Z7uevjQ`tA8rn9d{&0yc)PO!n&GugLe-Pw0zr?KyFPuP$#F3ikk zI{VQE?>KM+3 zO$}qir-d>rr*JkL4~wbunWfWwHhlVgX6}mbXNEI#XEC#!E@s1BBhhvqvv!}yM)CW@ z=ChIBVm8(*f{pQ!u<^c9euvn^02$gU`2At#u1Yq%`|hw&9xK>So>6S1S2P=qyTc~< zEoC-AayF6f4)a#B3BF2Z6S9KY%~3LY(K6iGwF-B2t-@Vh(aa%uIdhzcN5m>NO`_uW zg;~y81N^_>4l^wq<-Hnrn62S=g^l)IkJoin=8N zUIMen!zL`5O%NsFb27hEY~p+!n-q}>dUxZYV-ptaVG|do16Delf;+z^F8meujs40d zFUsI|jyVLcXAU7+Hf`Qo+&8v{&A@$Qj$xbFv`8&;!hK_IOV%;xpEomCMJyBGzA?II z%u5-IyVG_sXYmf^urL{~Nw{Y$jX6nD+0;d8Z2BS{bH$xwGnLzz7w#H!kfihb#+)PZ zD*cr?MrJVQ#dyX2V@|k#%$7bCUnYrpmK$7ug}^yzDUUBRj-qt;oXtW_y|E zsy~>+(j#ozvOk$K?j&Ge&oeO-et* zrtCk5JIwxO4*GwX!`?H7`@?>(Fx(yXM-}c4yTsg%*07m*wM=l#aBrAr;Y~IZcZPYL zyv=6e&M;w7J?;&=gL}j78SV``)4+suZ&>+#erK3JzccI!3&6c$ewSL=9NZZeTKk;e z6V}7Rv@aDSDs%%FZu;uoyEh(mYZ%?@)vFhN>_e{~b{D!dtXCiU=|fbZ+rw~|7#@ZT zzgt<6uJt&kl|bHV(Wv^7r%s4|fOrFvZbk9KLn1nc|LG zsB4KThKBf(H@CF0v9z(oGkqUr)6;aSC`>F(~2<{3`1 z@B2EXSni9I07XI>F$r1O_W@Mj|j?m6L|Xb7J7LLC4eIF_j2@f zba40f1W-qJkVgpoB|c7`{*rw*r!u}ba+hV;WNV_LA|sqE`GywFx6iORMq$&UT3uVbVt*XgWA z6(!L`A+8do1u8Fp1X;WhW{Hw(qO@9kk0{SdgnAYuriFj_gnr>mjYcky!V{WDNutnG zAN&xhLVeX~rz<(xn$P+=L`t-|PKBDNjBKq|ldZ{)#U)aaK!QM)CQ`l%U&>b!>5-AZ0-&1g`0Q+LtX8GT$aBie)?|R;eT{6ua!vM`JN|`Nt{_dk z@N8aQPHtf-l9o>uX6MCcl%6fsu9R0)+-hn;65rXg*oH=j&Y!>A)Plnb85w!m1*JLJ zxupff0HiykoXl`PjSqPlv69dF0=`C@mlK;a!*#YR;)cj!4D}QE`3VHBuC4-nGh@cI z(Iao&y4~FIY6gny4426xe=M(Pdi?4Y)i4yQPVc5s8EXTk5$4#a?~NRNqEy*=c}H`8 zO`aD%52dEI_Hs>4O>JE*p08fNe(l<&NZQs<&5!9|IKc<9=-{~xEp$#Czt+{(aqvXP<>YVxdt$=8sHO->Z;1DJx}ON&l`HbCu#27ihGn&T8nbEj)%j~ zCy(~`iHge5YO__)e}6&+_`%5>IXFZJ(2|;0S5c|NzZcJ+Kks~Ad1z0na&B4u6MRAy z1L-$z+_-u3>ZN%AZ-6n{$48}ts>gyqmR=fdY)*ERW)8)z3?;dyt`6)3L+iK{E?ugs zy3~fmfsVFAY0-1b>szpoKFV6!a+;5ot**r zD9IopdEUHBppC=71_;EX>gp;=OnBa$7L6Pc@Cx7KhgxFfRfyoSL3;CafIsgiPf1iH zz-RdP?PcR1rO7)Quhq;3V^DB`1@-{LvM!PEy6FcbC{7i4@&XxGI8D{bRR?$t-Mj|g zgD7gQn>SAsKElyUvMMJhLmP$hf_kS1(^gr-?YQ9$3P|M%Xxd$zgW^zc1`hlr~SJ%@Cyn0aYR) zCCv*LWpVLU6KG(lu7U38A3l9WdQSzq!@*;sMl)A{`f>`j>c!pV-v4k0|F{ZDB(%r;bD70W=$=0r@E@9>QI_eS%EZkln#8) zc~6Kgiso^x0S=HiFKq9%t79D8VU)?xe{bpt{n5fyXm($&y__Bt79O4q=;3%E1z=CN zWNQF^H>{2!v;Fn!F6tKHxOTk~94ESoJrHf!-s{({jM=p+E_?FMHNh0v2~j4S2&#;32Kn%JJ}?1UwP0$-~Gb3k=ck}es4;bCFv7!cRS zI6Xbe0befHLV+^EZ;%z)i_0It8{P$y!QRURy>btzHw@dFn$FHwuV21|`T+G_ z)Imu`kAX-Owil!M>a{VB?wCC_v7rAmM@;qF?0CS3iM@WUZf{VSC((p)_EwlMpV3g@qG?XsDsRC`2D!cK&u7S!60T zRaF;SUXY*xo79G=fU;q@Tqd(|t!{)9xDKB}Bk$K2rbxaj5Bv|saHP2i&zH~xki;A7 zlEVFh(i$HC;41_C>Z%KeS~^IR2tNLiK@1A2H1Pg1rc`SuM=z))20*{QHr{Zsjvkd~ zgkB|ugE@gdUZimVrK6IZB=QU5S#z(r(%04kek)Gcc6E`2xRd}si-rn@#C6Oy)=myk z8W;#kzrMrVBjwuISkQmXFdLxw-xfg+IfwssWY6 zBAN`6l0t%mgMzav4;?y`Rhbp!7evBA0r9~^Jv^AK%F3!sgaY=#%*Wk33T~{1;Cn@? zwQ99cJ{pbp7|NlnDsI2#VaCBw1{gr`b#qHiOH0$Ixw*Od1_dFh5DAOH!G5Bu>dHgd zFVySN_z<{QTla(GIQK{ls>rCmAKLh1CeyC>m^pGcN-8}8$RTjF7A%4>3P*lqcu26X zoAYF6IcFLsd0q!yNehxJuLa!*T8sEJN1MfB5LpqlfqJKYIM^#k0rF%`K0s(1Y5V z@E}kh9_%|~`s8xB=s3fMtnlVX%`HK}M1DB@2RNj2%PQc$cXqsZ{HVG4am^3oY_RUY z`bN{Y*A!u-JYE|Y(f$%iEzjCt!brmUzU=7efD;E@PX>!belwgWS2R50z5{;k!0D%# zL10c2)U`S*6)soH+kdINGk(o=*Ffg?l214 zSkOPkL!#Ek$E&r|_9PkLU${_Nsc&w9y?>7JigL(pIOGSnkTeMcE7;ffehXa$MZ+BU zxhDy;2SF%r89W%Q@wM?-_4V)T;1#h_4fyfX^r=W5L$?WJ)}dzTLuY3dhD+^*G`EWS z=2x$}VCX_Zl0t%fr#Im==BqAZ5B>oKN|jzYH?SP_(Cif)Annn}RoebWc(+m$zf-N9 z49}axr^*o819GLP12ynXZryGHy%@>R`j9|3=Z5=q+8um=9EA>h6Fe+{vGP)2; zkYIHz*Yq`VaFnRycE+!abJp)}xYq{Rpw*=;eOl9FSa@>$;rl4>Hc=ip2cHxk6 z`tTXThrz2N^RPQwSz$=te*L=Z2S?0`fFHT4FXl(NCQcitj(6F!yYV5d;xMqP_oPO{ zU--QuD2cE;= ze$q)R99kLtK!GBIe6fC)YhZ!a6a9A~{0>s&L($5zh8N&CiLNHZ+4=T8k~~xsRv~Em zHNmIjyPbUaUC>9Dm)`>T&JHea@a${HVUFHM<1v2w_Zf!y zH+JRDmD-=8=c11!Uouz~_rZ^@8catz9C!BhZ6^M7!Q}YD6pbpsP3YW2RWKpYt_o0( zhUg3=f=R&CeTvX4{%`nKG`~nNkasSY|Fk`*%=@2Asm^syYUf0 zt-a9H_>i)6(E#?DCKybP|4)109u?J*^}8oV1#Cn_W8xD;2r3|;E#V;#dD#dGEnq7k z50OL=Vn<9P2ng6pYsZcX9Ryoq28_8zG9RdmwOaWM2oqo$w3BGm#F#LN#!*HuLwIQ7 z{q573ICtIu?z-Q%?pi6RKIhb_v+KQUzp4uK;Lz~T4>|jWUVtAS#{884vV!r?ePJ{h zdyZA+Z!r7-bm5Oy1y!pMnTgkwl{IO0Y{JZdI^h2G>+sLRjB8OhR~bB}M;^G0fPeXA z2%E<|806R7S1~)Xz@ul7xw2n|(5r8Kdw1x`FHZuwQvyMA{_`}N@*NSt2Lg1C$cUJ+ z?dPD}u!Ua|rb1BCNSR*>uYdW4M*`+wE&+O^fc<|N`sY9X@h|>%fj{$)XVgU)Ul~~_ zKwdvXMLKHPffusQ|@3 zFi@5SvLr7L_$MPH?@SAl0R3}Apb&3B=pt}*selfABM>4;A_*yej=_BeeRM;r5R9tB z7Ei`&OcbI;hOm|cDcl5og8B!8tpI%RM}S{=b}h>hQ0Mr+25RYwK<2<;w(_Wn(5d|5 z+7~@6OZof?7s`|@iU2aqBqm_?3ZxnS7e)qxerQArR-yn1D_fe%n$9zQ%dmkF_!k5y z$ZpgEBTaN5kZ(f&W}MKC{wx-IYQU>%gEfH;57l*~1U`mq1xwV*&7*jY!IJjX+9}GxLRtJqke$DmYcw{c+9R`wt&Idhp=U&%?|o4gKp8_AmZim%!Y$(0lPg zYRYAy0H|J%U}+ZW2R(@84~nA3rWVK_1oq;_jnmvQM>%-zp~o?*KL7dgyCOyzu}@o!o=7MBlq*u$L`!80-8kk{ruya_a8BeMs82D zi9XjRnxPVnj1rjSGeZ5ddyP2lBQcfj*=oM-D!cGw6{`N)C)Qx2dEAv1M-?kPga^g*bMiczh)6jbujh_qo z=Te}3|Nhg!ufL-IAhlmG5SURjLC4@Yjn2%xxKKxFE)co_X`ZcP`8K3`O;9j2Zs2#L zE)B>Kd_GT@jMs0VeVMxE{>i2Jy!(FN&ma@<4vt6tH6wZkH?iOrLp-TC+jO>(<=cuf zXkyM5)y0p# zAyez10$D0}^Ex^PbSzNtI7LNeL4E?L+`a{MtlueP{Rm!eMDB0!Bqq#sT>KjlFklha zw_wN~V@HzvcmDqOA0Iu2W1wgwG?Y+7H?AMq$Pjco_n2r#`mCQ41u`aWYO1SaD|zmq zEWx?{C0Y?31tJ0<=PRdcun{7Q^cej^%D}Wbz(bPv%}qo^lRz~2C4`eG0Qb=_8N_>a zU;q@5&&wd`YefAlU*hg$Z*RZY#lwZ&Lj1$cMbM0C*7r;x1-PR>a|LJ5-z?%^w*eE&8KRswA!j{1?-@!;48A%WyHuTvbEC4=*Od^ zEjsA0eEX|RwpxZbG0AU}ad3Ul1uPP&BqjU1)@2 zm6ZYztYono8OnY9MrK6gpcObQ%~-=)<%|rhE)ha_=>#gcickfpT!AzbPpjh z1jW$Y3i9H!EWi;oW30z7gC-xDW>rBU5-TgrgMI}V9vOj_9y!N%h=ep0oJqJ#!58Yv ztVL0^%iBQ+VLYIZ0(4^&S{_w*wyqIcJp>lzsWs{{O%vveJT@mN1Y-huGG^DZGfijI zd1bIW09+_Zn*axNgJ98sRL%!~R%d4y8}*f%!SEPpY&zT4#ClH*I9!{W+V~2L?=->+UKop`tQE)zLEbMda1ZQn+ zXE%ClBRD%7J6z#S?{RNsC4#epLoh z_{a5+8u+6I{-}Zf>Kb4>WjFX__}}c5&GGQeJ!hvp-N~C~F7Tn53w>#(^KzQWcF3?j z=Cg?Bz?OIp+Z}s^!}d6m?3PB++}EUJ|5^;q^TxTszH4coj||s!L6s>?4n8*bl>=*dxYdN9-Y0lE>OTB#wob zm5_Lyl3t64O>x2=^4qWnHqZO`-Q<&{q-9%_~`hCRvGx@-F*=Gyvgh$Upj(8JiBEPwt z0&pI3;MTpcPcESdc(zlHcnjwv=j^3bI1f4KEfqy>E2CB0%W!`2I~0-rBe+WBfc=;*vdha}WRW(!iE_?%<<4Bx;EG;peeJtBk1-s*F zS_9kTIF*j#_a7q}&OctS#u>;s=Xk@rAHdfNXC9~EKJ{QNrNI_?WBCc3S$yKR^N%;< z{A2H<7ik&JHC_fgWVTCYd*r~{zfxe`XTq7rp?sF{UyQVZ&oagt#*uuE@%ft+343Je z1zh?3;!k0h3@?QZax8o_&M=OFUxPD@rJXp#7+(6fpD5Pw6UBAkCz;_M$#9Lk+(+w2 z?UUETMma&SQ^xg+hk~8*n5kwKIC&UG#&Bl%8)t!q`ND&lh1s~V`2X!>Vl#`$V`hkb zeB6D+?(RjmrB_HQ>jc>!pEg2^G&h7 zUNqK6sh7&PZ$GqMzC9s1d27N}=a-#V81bnqf6sOcApvLe4GKnm88me+{4-XrLhX)Ov?LxV( zB7U_tv;uw4)N-@Z0U!M#XIkx%s^hh_=TNHZFl|N1s}2q!A&!oIVOniiwV}4K>UiPt z#t!3TWxW#pU%l^6@9ppI-ub?_4Ii8g3w4--bKV}_`TmYySXiyGvGD7A19(7u4cf~r zF8Q$YCwB&)v_2UaY{SWS6?3NF8W;%*3hH|}98`<$@ZFOqtu6QZ20C7m*DEb8e3Xa7 zxidDl+H*63-MPLemgMG)^;3WC|u#q zzCkTYF^_w+vD?tm(GqmyJ5=t>WKFsy#`|F*eoJfNcLRff&mUJH{v2G<`7RwV^uGm2 z0|rxk)MsSj?I$CxZTNkH?(c|8MMX%^Y+TXI$Ng`74`Yg!w$4|idL`qNeUU*o9}cu0 z_y3+VT+R6i2?<&@`zF%q>^O1}d1-6w;P}mG-#B%-OX0VJ107Z04h$QOABHVO;z2m;U`c0mO7vwxxG5u z@UF4&Ha4F z4;W_|?Uic1rG-p?UiuZ>X!PoeSAz-#SJil_y87ft$Wk?rCLX`~^OmA?O>;5>zl_l< z438?Pm~Maf-R;}G9XuXQDe!QbrPS10TBO%E%klkXNf`HijQ2K1RuB?Ce28Jmv9;9_ z$z_Z{JEdMPvPf4q3;2XV;T7(_MH$Yg>%&df1VwKesoy5X6TNVQ zd7mQ#Q(C%EvIGRCw(%sh_9u^smI7O4Ls_mYGFOB-|M^< z7O=4vcIhUpgT-1@|Ev$Oj<NCMAWA@|HoHR22HgJ__2bq2M>v;4k->_)Gco z{H2m2!CwZ-Ram3CpF+2*1wK;(J~J{$1zz(2c+Gc6l6!z6a@7>I9sK4_4K07YoI*0* zMSUIu->9XKtO~5P1@HNK6)k_Gl0vhO2t4SDH!B4mbVVNc(4B`Ua_3=MRalNSvQ;F> z(NT24L5eH-oewqfpdVuW?1vPD^|QfPM;o&3G==7TLMwNbQ$(?rR+k*1)yg9jv+EE= z;W@6joMfdHv<~ZGqf06&T3JOgSQ9JVdz9k$ns`)RADgJEqILUp;7@BPQGJZoKgX*k zfj>2u;Jgffe-}u$2=35kvwX=~ezw@jyZGWd|teuVRyhAZv%&UTD1&{h0 zuiEnfyy^p5ccl+J>ObijuexEBPkqtGeEfKDre+RfVq$9Y%9WAH5i4Jf$c6qSF;Si=&up+V zi*1PAR0B)yx|*5=H~VsO9B%g4)xjpOw#L`DA>Z6AvB6hWda=iNrK?MOcerUw`lAuh zQC}G^ma3fP4d&zJc&`d?#$4Lndh*eO^t=5%J$UF+sY-3-XU)dPHh5q=y3&hy-*r-R zw-2-l9KKeS&dQXVixM05s_;I%`AS#2CjCKwe>XnAsAA`vDHq{=osj`ZntL<=-rhgd zW4suSPr|!G()=2ukz<#h*7W|`)6+Hb>uG)}?J|Z)b4BK>3-=;DmFmzT)gb`y zZtw5MYl)<*+qf$;-+cVqTsczgVF;4SuCDI(suF(P+TPW*OJ0ljkq%olhgwk{mBcpi zWM$y861;{A=1{Y5Vy$TW+6^~v-@A9WwHvQr>3#I*?p;Z^>ZGRkZtq>!TshL;=x}dX zKhodTC3)q>aA2To->)iT>-~|Y6a6D=8*D_YcRJkdZ#wayzrB6N&HfU}Os>G@6DPEf z`unB1Hs))$&+Q#*(%c{E=}!M)L=yN)??`uhy5INx!(G0@`{cPd`}LYf{l*@<-u}SA zmwJ)Zmg{%>Te|{1&mw=xRGObfo7bUZW!9`69sYgJsJ|R}V@h z8TobO*I||FNOw1zyM$!sTA8O7f;qy1Kvk)#WZ9vv_CpfYA(e`QjJxFdR_5}C_nC-B z^^~}}YEGU!c?eC52$`im60b`U0pFwisd#^-G#o+A ztr}#jsjt5o58>fgt^vM{DDiB~l~RBVzi8~<^212$Npyf_L`M?b{^s(=-9myFjXhoI z-wh4*^>;n%KY{3&zd9u9)Q(`K5aai{=-mv zbALaVtqp;;xeX$-*t4;lHtnw2yLb2ASS*8t9nJ2V-Me<}-sJ1+*^p~4l2

<{!t# zdGgG)a{1b|iSk?wE@^6}T%MoVAexfckel03o7>RPke{2MindnMpQ|)N{EC(X%MKperGtsOC@GfLAa{-OFT|h6|yVAIME@Wo6 zh-j_{5#;i;(2pi8^ri`me8?Jf&%ep*-Mk^6_b1Cm0W{MEdxn4(!loN!DGnvkYZ98^ z8%a~dVZX`qr(=(hXEJ?SyoMmaCJ-Y;UQtBYAB242z1QIyPc!gtws(xMw}>s%QqTq1 zil5O_Ysg-pr`8hFQx2m#fQbQ7G%+}iEF+T08uyb{ZlHw{8TRo=1d*3a6uJ?96OkmH zCSk9TNfDc9cGO0CDJBzs3(bkyOcU0X({CPUhA-*NBkc0g6!UtW%2PU+^fiU1Fjp?ixc5uhPd=kEb!W)67v=0DSH(Nz2Ja5Jws#8e4RVw;OF0YO0Mure|k#G?>!~SKc3R6`%g*s;3;kT=Tpjf z_>{8X|9^8&pQ5Z{TU%R4Td}PeH}H;l#LWzGs^U#~qFi3gG>1GdNRMK%ttwGf zSDd3LRw!y!3OK$^JRx>e$tx>sE}Yk!86zheOK}ixO?l<|lVaNgIoajqH5V>87^jMQ z5MEPRnYI3;qpd3EOm<~uwSKXU(J1+ZgDcOhQHjMW#fAUKF0ZV4*%&VA*rThg%>Iw_ zu^gUr;nOBW3Nr59``Ky)pSf@$Muq$+Cd_{QFO`)c)8+-Q&a9j{#yaX8r(2hZ*}eWf96zBa;`|!{cJ3W(4tR-Ga^uG3hO`UTMz^Vk=nHGj zja~V%bzb5Fa-*|b$3gu(=NK_b~AkDmRWu@?eb^sfG<9o zb8zRL50TN(($Y*^{<1fJ55upk#n#g0m6bEcSqGFJ#*3zwPuC;-M9!xiTr-YmubmbA z;zG;;AMpvr8B{~{g~>)|clW=2g8Iom6N~t$Pp;?-(;zr9NKSLbmB$9u%a=dNi-Jz1*aKbq+5MK+FZG{wP(rnq|1j0MX`65EEXlwv_;Wme zBbw%jr8EUPZ5!;1HO*g!y|Y%6Eo26^uf@?^%!T%t3+MT+r+I!G=uZoi$!2K^O%+X Date: Tue, 28 Mar 2006 12:00:18 +0000 Subject: [PATCH 2483/4131] mention all keys Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2567 --- docs/dosbox.1 | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/dosbox.1 b/docs/dosbox.1 index 7ffa8029..28b23088 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -1,5 +1,5 @@ .\" Hey, EMACS: -*- nroff -*- -.TH DOSBOX 1 "Nov 18, 2004" +.TH DOSBOX 1 "Mar 28, 2005" .\" Please adjust this date whenever revising the manpage. .SH NAME dosbox \- an x86/DOS emulator with sound/graphics @@ -7,6 +7,7 @@ dosbox \- an x86/DOS emulator with sound/graphics .B dosbox .B [\-fullscreen] .B [\-startmapper] +.B [\-noautoexec] .BI "[\-conf " configfile ] .BI "[\-lang " langfile ] .B [file] @@ -35,6 +36,9 @@ A summary of options is included below. .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 .BI \-c " command" .RI "Runs the specified " command " before running " .BR file . @@ -214,8 +218,12 @@ automatically loaded, else ~/.dosboxrc (if present) will be loaded. .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! @@ -239,6 +247,8 @@ Capture/Release the mouse. 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 From 35107bd3a46bd43ced25d5a48a7bcf3e943dca2d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Mar 2006 14:39:26 +0000 Subject: [PATCH 2484/4131] A few typos pointed out ykhwong Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2568 --- README | 8 ++++---- docs/dosbox.1 | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README b/README index 82256e06..0b51a9e5 100644 --- a/README +++ b/README @@ -231,8 +231,8 @@ dosbox -version -machine machinetype Setup DOSBox to emulate a specific type of machine. Valid choices are: - hercules, cga, tandy, vga (default). The machinetype affects both the - videocard and the available soundcards. + hercules, cga, pcjr, tandy, vga (default). The machinetype affects + both the videocard and the available soundcards. -startmapper Enter the keymapper directly on startup. Useful for people with @@ -720,7 +720,7 @@ it up somewhat. =================================== DOSBox emulates the CPU, the sound and graphic cards, and some other -stuff, all at the same time. You can overclock DOSBox by using CTRL+F12, but +stuff, all at the same time. You can overclock DOSBox by using CTRL-F12, but you'll be limited by the power of your actual CPU. You can see how much free time your true CPU has by looking at the Task Manager in Windows 2000/XP and the System Monitor in Windows 95/98/ME. Once 100% of your real CPU time is @@ -736,7 +736,7 @@ check) Since VGA emulation is the most demanding part of DOSBox in terms of actual CPU usage, we'll start there. Increase the number of frames skipped (in -increments of one) by pressing CRTL+F8. Your CPU usage should decrease. +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 diff --git a/docs/dosbox.1 b/docs/dosbox.1 index 28b23088..e8d78eaf 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -60,7 +60,7 @@ wish to execute on startup. .TP .BI \-machine " machinetype .RB "Setup " dosbox " to emulate a specific type of machine." -.RI "Valid choices are: " "hercules, cga, tandy, vga(default)". +.RI "Valid choices are: " "hercules, cga, pcjr, tandy, vga(default)". The machinetype has influence on both the videocard and the available soundcards. .TP @@ -278,11 +278,11 @@ So: .PP .RB "Close every program but " dosbox . .PP -.RB "Overclock " dosbox " until 100% of your CPU is used.(CTR\-+F12)" +.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 CRTL\-F8. Your CPU usage should decrease. +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. From 74ae27f017386c04f6b17f4cf43158f37167d602 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 29 Mar 2006 07:52:47 +0000 Subject: [PATCH 2485/4131] Add video stuff. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2569 --- scripts/dosbox-installer.nsi | 39 +++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index 957453c6..c11a94a4 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -1,11 +1,11 @@ !define VER_MAYOR 0 -!define VER_MINOR 63 +!define VER_MINOR 65 ; The name of the installer Name "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer" ; The file to write -OutFile "Dosbox${VER_MAYOR}.${VER_MINOR}-win32-installer.exe" +OutFile "DOSBox${VER_MAYOR}.${VER_MINOR}-win32-installer.exe" ; The default installation directory InstallDir "$PROGRAMFILES\DOSBox-${VER_MAYOR}.${VER_MINOR}" @@ -23,6 +23,8 @@ Section "ThisNameIsIgnoredSoWhyBother?" SetOutPath $INSTDIR ; Put file there + CreateDirectory "$INSTDIR\capture" + CreateDirectory "$INSTDIR\zmbv" File /oname=README.txt README File /oname=COPYING.txt COPYING File /oname=THANKS.txt THANKS @@ -33,18 +35,22 @@ Section "ThisNameIsIgnoredSoWhyBother?" 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 ; File libpng12.dll - File libogg-0.dll - File libvorbis-0.dll - File libvorbisfile-3.dll - - CreateDirectory "$INSTDIR\capture" +; File libogg-0.dll +; File libvorbis-0.dll +; File libvorbisfile-3.dll + 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$\"" 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}\Video\Video instructions.lnk" "$INSTDIR\zmbv\README.txt" + CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Install movie codec.lnk" "rundll32" "syssetup,SetupInfObjectInstallAction DefaultInstall 128 $INSTDIR\zmbv\zmbv.inf" WriteUninstaller "uninstall.exe" SectionEnd ; end the section @@ -64,11 +70,13 @@ Section "Uninstall" Delete $INSTDIR\dosbox.conf Delete $INSTDIR\SDL.dll Delete $INSTDIR\SDL_net.dll -; Delete $INSTDIR\libpng12.dll - Delete $INSTDIR\libogg-0.dll - Delete $INSTDIR\libvorbis-0.dll - Delete $INSTDIR\libvorbisfile-3.dll - + Delete $INSTDIR\zmbv\zmbv.dll + Delete $INSTDIR\zmbv\zmbv.inf + Delete $INSTDIR\zmbv\README.txt +; Delete $INSTDIR\libpng12.dll +; Delete $INSTDIR\libogg-0.dll +; Delete $INSTDIR\libvorbis-0.dll +; Delete $INSTDIR\libvorbisfile-3.dll ;Files left by sdl taking over the console Delete $INSTDIR\stdout.txt Delete $INSTDIR\stderr.txt @@ -81,10 +89,13 @@ Section "Uninstall" 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.conf.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 From 06da2ec1db9f34d5cfb405d51bfc57c7bfb9fc0c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 29 Mar 2006 10:18:57 +0000 Subject: [PATCH 2486/4131] Time moves fast.... Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2570 --- docs/dosbox.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dosbox.1 b/docs/dosbox.1 index e8d78eaf..f5c30658 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -1,5 +1,5 @@ .\" Hey, EMACS: -*- nroff -*- -.TH DOSBOX 1 "Mar 28, 2005" +.TH DOSBOX 1 "Mar 28, 2006" .\" Please adjust this date whenever revising the manpage. .SH NAME dosbox \- an x86/DOS emulator with sound/graphics From f34300a4f453d9f01d03b77dd1b0624a7ef16f28 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 29 Mar 2006 12:26:07 +0000 Subject: [PATCH 2487/4131] Better safe then sorry. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2571 --- src/gui/sdlmain.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index ca861847..4749b9d2 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.112 2006-03-28 10:18:13 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.113 2006-03-29 12:26:07 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -698,7 +698,8 @@ void GFX_EndUpdate( const Bit16u *changedLines ) { if (SDL_MUSTLOCK(sdl.surface)) { if (sdl.blit.surface) { SDL_UnlockSurface(sdl.blit.surface); - LOG(LOG_MISC,LOG_WARN)("Bit %d",SDL_BlitSurface( sdl.blit.surface, 0, sdl.surface, &sdl.clip )); + int Blit = SDL_BlitSurface( sdl.blit.surface, 0, sdl.surface, &sdl.clip ); + LOG(LOG_MISC,LOG_WARN)("BlitSurface returned %d",Blit); } else { SDL_UnlockSurface(sdl.surface); } From b0a2637385ffeb8b5c9602f7429e79a29b073035 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 29 Mar 2006 12:26:41 +0000 Subject: [PATCH 2488/4131] update logo again. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2572 --- src/dosbox.ico | Bin 114926 -> 114926 bytes src/gui/dosbox_logo.h | 972 +++++++++++++++++++++--------------------- 2 files changed, 486 insertions(+), 486 deletions(-) diff --git a/src/dosbox.ico b/src/dosbox.ico index f8817084bd6875bd7ad4e62af4c4916f7880c822..1602b2a621562076d0d572cc12f73a211a79ac32 100644 GIT binary patch literal 114926 zcmd?SkAIWpz4(1&D%BPUDc<33X$)bs2$q`~QZh6&X{14_(h`eeMaoR831I_TK-;bZ z4OX-!$N7t)SaR5=wy(g!?^flt>HO~NCOyaFG#=*+E2}=o=Q%$Fc7UCy&+~%iJnzpH z*mvL8>-!%(7c{?m=en=Y@1NIIO`D<>Yci&2*JwA)pQ7#J^`1SK-`}BWLwvSrQ{nyV zHJbMRwkcX|?dA6~H0?XDOws1fz5MjO+RT}S_tC30ZQ$oq zv>UhwH`KJN3ZKhcZLWN9d0c*Z%X|N>E&J9ZntS9kZE18w>wMvLZP`ywX}52GT-%UL zYv26Y|Dmn^#|zrc55K2X)~(Z;cRi&A-}_p-b=PsNF8+pgXZJp>w*8;DIjfn_X{fRjVJ?Zsof6XAWykz2Das z-}8*Ndh1?oaZ9h}zOP$b|Kuy$lC~GLK=wbin;&{qyS3{nZSAAHk3Xh$KKo z8`mW@-*3)qD<679o4x!YZT_lmEiiUg`^L(x+D#Fz`N4=*edliN#=reXE%4!a?ZM|i z($+rzui6dGd$enH4T zlJ8Zl8qiwz9n>0QecG)9C$-hNi(2z1|BqI4-vQSAnD))BqgwsjUuo{n*R(~i{Jl1N zVNkp2?k(EANGXf85jUWA|cKm>Qk&b_ck*{^kwZ-2(@-dlJuUjo{n=!8xsF?L*payHeUc`(Dy+XRXcOeOBA@ zcG<-{|fAG6n`03wr|EIOUM}N}hH9w_Q)ZU@F!p~~;|NURI z(67&EH?4k1TekJMws1pQtGOq|wFBCUPyQ3U{Yb0%)~njWJ05^u7qo`0PiXBg{h!*( z&o65Cg4cVV{e!lW&sY8ZAGHN5quK`65W~*t@=HD}<-EjB!!R?S1fk!tz`?}`vuhZ7?zJBwM zwGQ5|_|Aald-Drz@x~#|Z2P|E-*!xkvF@AxE~mBc`-QghgA3Y{*fDLvx*urYdiF=m zzeijB?Z>olJ@X@;_wfEP?SW@sMK<;z2S3u4WCYGtNE-G{{7Z7uL9R&+D4x5 z1jaleq0geV zPic2VpVn5zdboGLc7N(O@b_cdO?U0qR{Z~cw3Y7J)AiJz_C0FU*LQVw)wj!|yr{3= z!zcA!dw3{(Sh%38tF*MMR6VNe+SQ{x@S#kwr?iXD+V|A&+0*{A{I73s=UuzZ#^6CN zWAJvk&_Wb2Dxucq$ zncCay_dHeq@>BLUsNd%PFMh@JrLr`6X0p5U&^`}T%gv# zSKICU2+(qudM4H@A)U*?-~8~MDnURKKM!dhkhtuo~8fDBnCKQc|>xvPFO)e88H zD_ULuX?Q%Wp5=Sg3%gwb*Uk#$AItFYRUY{*gGuc5ZilDcZf8C6iCp3K)OV>R+Y30f zcNx3|*$NWA>Q2eGnba-wcnm|nA=4U$r(Iy>YMJUhI0IkIrm$vr)Z1mvOe7a^OPQ7{ z6@ug&p0tNcz`V>ZgUk6f*T`GJmfQxAWCG!XdTwXf^npg`zo)gaHTB=z9=pTg@TJ`z z2QNM8G}p%zlX8CC&t%lp3=2sp_=k_`bZ#r$*+ugqQym8*` z_IR03pidiS+U-ai4t{O8f!b>TxXfXsJ$ARD=8}m_`J8J&RK5J(unT;Kn@b$r6ga_z z(1m-u`SExRw-7GvNIQJ2Ug*OWK;I75kW+S+HVXngAL?2QA- z84)f3FqzNJcfF(M7vQVyYdu8#) zaLO=~qdwoTnarophd>__c|7^y(Ii*89lYTdf;WfaTF}etkfZ`Tsf*JdxlDM;lQz?Q zjXB&NBM+jDNHSsgyoN9DfV;UN>w({7a3>MOdb;h6F>JyQW&(Bq zKYRj@;I{M9H#%$^cKD(`ug~EdHC?9Z%ct`p!v{@aC7BbMhG_Nzc(6av zz!g3tj|_t6v`6GDZ-`Jbxsmn-c<1){Afx~*+-bmq5P)C8Wg;fLlqcRmAcL>L0pJDR zgFOuom%?+YsOgI6@7PM)DsPFF0{@=YuH+}S##Z}77M~+O>TtP)zdXihXgCmnPJGLd zH{6`LLZfM=l$7xKQuXP)+X#hxMqt<%$d4MMD0{mR$@@%K)aCLG2h3PEP0{C+cg9JFEyh7 z_{lqMt-gnBhLQB-N4?yF+nO$5NJ8L50-%sEBb9&%h8ILQjI`+rd42UP%@-JkK3?xI z3p7y~Y2UCfA27_}K*DB=#h4}#@VMasJgKszy7|x@CSRPX`LLnfq!`F^<(w7gh ze)-hr3Jm#>g1j#s2)MYE7akZB0>F7(;6XvPLt+OjLJLCedZZ&=kIakiwx1tHI!x1* zOa{C~2CeH<@y|M!k7J%gZf2 zc~jI9Tww$PBHgSI#RV_g4No8?3$de$K}p)^S+d;+8i~jv(+};re{sarlfD! zNMvEERJ3|DF^oC^m%|_w6@V&1PE$TdfHm^@a0n?3a2M$3O}86)Gc8mc_Id3{xX%=x zG#nuxav+k9u=;%G%_NYb;@oh9Fx4m*3!c!MOb+Xfg6TkVXt%ws@%Hb=V|Bq0@YfFj zhTZngLv4-rEtO_IYU+WcE0r>#Ys#!P1L?Ha6$~Z=J~3F{>I8F`e2SLzCJcDq;f|QG zQK;h+NoDn3uLA)H_^Pv}E8sHo5fBesy4_yXWIlx?1{_@LNCxs~2XoXhjK+zKrbB@g zq!8KjMN*)_ZU^RMz+}Er7tF&zL`>Z`D&l@VxcCl8UD5+7AOu#krfoLiPgf88c@EWL#M8r%5Ldj|y0NShd%uw9s z(o>Gm=xBb}kz3%f~T!dIP6N5*zyE~K!z(lS< z!UL&Y`E1tAGkrESeBN{+ccFyK^tuw~;ZB(bSrQEr@fqk_mjMAnW&o`h3RDj#d6)M_ zjDTM9SbJmZEw@+)t(Ma*?Uu$B^{ocNI%;uL-a61~e{4&}6)|0@>WC{;?TUwO+zAY) ze34`%8;{1~kz_Iv$wT2ZG6ptumn~?*8EAM60Mg^mC-w7j9VYL$SZvicmuZXZu52Xf z3V0o0O!N1SU zC(Wd8i`#U4lO=0bgZp8x!)KbXe$0l&$$L}Dq#n!ruvCT_s*dXc7trFDZ*JzvbrAHpgRw@oL@X8qxK9%3;QBNnO_ip@_rbO4>3* zVT;8QwguyY7M~ss>Mj?s!)HEU#Iz+-v8W!?lcr&b+q`<*X0b7{u4E`1O+{mTpy!h# z;gNXI7S&zBa5x^-^=hzfgn$!@CF?eUsz3}nr?nAV}Yn1LOo<%HnZC0vRNN$YfJOt0JI(xXvVFasXk?rbnvZKSw0|6LA` zX-1RSb~BJwuVcYP!j*Let#MnVB-3Kn+2WO!F!(b<(WDuP$MiFLIHp_bSY+7NuP5BT zNC?Rf;VkMpNZM+~f_2<1g6u_HuB~P?V(Q^|T(7IP=p!vjeZ(4%Mw2Yg8crsX$yhd< z4L}9k$Y>;K>L^-Mua4UiUd(7d8?H99uB-`(0=k(^>XB^3^2ROh)~;LL*ljgV@6KAS zA^RZoA85~}(iWRNIA{+3puWvGeM=^uFpX%PB_6lcWo%yVB!C3gTB^b3t&sgi~V);lYqT6ECdc4k- zG`$g&mB$eYxWrW0)`Tt4H?}5rMvv-IZvftN*(@1r#-eY^Ff9&AG8?vyST^al5gQU^ z>Zk+5j7TVvb|glEsZp0+J!%W^xzxW zOi9u{L&1+Xr(#aRgVj6)5OqKEliG?WUt zVD&&Cg#N(1`cN;nXbhQ-=`J1ctYI($9ATR+oY)$Ry&F3ddnRTJ*PV&SgLT!hHJfxj zX^REp$@7RV@CR*c^6y8YTVwA>*2F$WL~Piipv@YL#w$04MgD@C&EA8oe)62Koo}QA=e& zx0oLBe_Bhi-qF!yK4A43x4#f=w4eTNiO{~JB_1xR92&~>XTmmpByX#O@xqXyuG(g^ z1oc1)K}aUdBqqXD9Y+;pZP9ofdl3M7nn=X*I?Nn1hmn~` z#8sVzxnkAkd2C0FVT;${V8SFxToYqBDwaQq60wF+Hlmtz>ri-T2nHCuCEV4Ry~Scp z1WUqUOUYokGVZHK|Ltk@;9X{Q`>18eoqEGs^4-BkyY0KX>s-lT5cRD`lTk}c*fkUg z>cL72&QUU&j|2$QFlnwxGMY>p$s|VChp9siMWb0Plnq^s>O>CLB-TK68TZ}y^=)7O z`tv8ASo6DZY%98o%U!-ygt#f?ioP3N^YrJRKmO+Dx83&jeP7G9kH7iqtI@4`Bpk*M zM+*tWx|vLwVudWWkvd2m3)oCEN z-1LIg@Wbv7Z|o!4e#lalFSRYlR*9MY2*t_8x0Nx5qE?* zfOPj)_G6P`5q(5YMR0BPC`dLF@gY4MbpSbXfxrjN6bfS~V~JYNBw||=kKcA1T5H(VDyV*xoyriw?C@58oW>G3y#y>QjzPw?vNHxscnk+iur>cWhf@vxq?z;fAW z)|GO2e8{_wWesHYkfG!%)VT^qMU{FiKaH{J_@IQsVROF0n*M zEJidQ?Xm)YTUWiO-Z$zBgn~Yw;_6#&Z}jZON2<%T#9i@B#$vHnTH;|~&-9mM(1H30 z8X?{fVqkb&)l>qH-xG=@t7E}X2!7zKF%8LsJ+w zUyA>S|5Kk&+kJMAYsjltzLBwIN0)A| zB<4tL4J3WutSuM>>v3!4rf9e%=8f4b`p0iV@m~PaO*aAjO*g>`zkcHLci;aw(_d+^ zh5ON?;eKl-xMt1gpa1#^g(0~N;C~^C;N5qFdNh)4smsPI!FM)j3)-@7N8P59pe^PY zjiR}eBBzi(*wT^-V=99!8Cy1}kD7WmG-}56NO16tWLsm&8)4lHmRR-k)}SLD^_pRy z_&+PU2D)%7ZDH?Fwh}{gx-wYVAHU^=wywx`-!P2;DHoh^w-NJ(&}P-aWOcmS7LQfO zT;@>17>XK>d?XcdWl@7RJa_b>?!qn3+6Lj1{u0Z_i6@@^#cdDV&3NGTd+)vLoA-Qr z_1dLRKW(WylNq$ct=2d=u$>7eUj6!}pZ)Ch2OfCf_1Euu@2+ot@2ab>(Uw2{e)M;B z=$(EYhd+&?t0p4#;+oY3lWDwYk0UnZ7!8XZint=akb`JhVkaX>PRXItWgesdG0#BT zmXc9@BoMB&j@VAeE6tLA>_Xl>g#TY!>T#H8k!aN7!&LX{mfig&x8KrQntI{8FTC*B zpa1;Wt+(F#=Ra>LJnWXSWjF7(@ZrsWzWLTITW;OGWy{Ss-^$Bdw^Z_5es0}z^PlDS zw{H2}uYd9DU)&8?!2Z4O-2+(rc0DK8%WrSxYyABA=9{<7n8B5D*}dvAu%zu;Fvv}~ z`>i)~kKIhWyK)P+<5o9sVGRska=~s^!!Jwtf9sY%v!dO6jm7ZspZTt*wXMV&)Gg6e zP%O?MUKW}>n)G;)|2>i`CJ7S^m?JtIS<>Hf`x`^n-M6>4Mk-@wOeZVGf3jn^mjRo@ zm%y!&WB@83<7d-d#KXiF$w(}QDC9BaZ-OYgDd1^V58Qhf;D7YdHP>jXHZr)ZFx2zqsSBUTcVroDJP*h+)KE*h{GdK$-W4k>qxETf z-sLqdBW7I~$JB-)*KI~#{QuJWl#$1o#<&3Sk2hPL~f#L zQQuq7{{+@Y?hD{An6+`i>f);XRmH^({%wAL@r2*GZ5x-}IA#9b_lkbFX5T(-`K+%N zY~1+MpB63ShRe7eH$A&}@!4g|WCeV<`0QqRIJ>!MaYeDy-@rr-tiZpmue|)|rK7#Q z%}2{moji4_xw*MZx7*2(;6ad*$%IQXgRnW_NgyKrUssopOfx~V8LTd;L?iWE>Tr&d zrz0nuPd1-AS$^^)bI4P9?X)Agn#swU+!&8eXD&DHcaD$e{JDwohHVYow)GVI8yXtM zoi*TTvSzGe!td`{)HiqGjRorO)3l|_7c5vXYgXCnvY!2*3#?5{fQN>%zDIuY=zM`+ z^xjgDky#67EvPynNXpgZa${p-H8n?$9PvAyPXAa%1*@2>DVm%tnk+iIxMG5T6%{%D z9hp|!bgH@hXfrEk)$+f$G|=vF5n*R_vJQAj!NIUCJe{+4E zvi~bLaiV+C+=ahUMAdffT@LIrRxc`Bw5X?HqL>MC4GkxH7R`PBhAH#cJ#g1OpI*at z3!YoBckhzDOS-FixPt$TZ4F1dyAK{b*wejZTW&D~0QSkr#gj#wmlc7Y9Nbm`_)Seh zu6fO;jyCu9o@$;qZ|c0(WGOkuKr&Mz(OftaFUe$D^l03X&a4pl^*~oLDK322RuYVt zv_wX@E>L2?@r)(~K6pHNvZ=On>JC6X(XfBpHrC!Ft7|Cs=lo7Z7bkcqZWxC)K)<+% zk@KG@0|D^#T5aib3U&qm>eXey4`?}OMR9Rex8nZ!>s}Y~?^>{T!IJ0pKDXpK;IG=h ze_M}$&&(&f4|ex-Z`*dzzZfBqJE#Y64dILUH{rhm{=D8^gcl}g?rrXEbx{9uc-zge zk;;x(OX3;KT_9W%acAKFfzoW=jwd@B%w*!H2U|{;Y>L}#b?qhYlMG=X9t4f^ns?R; z2lP0LAv>JDt)T}l;1vuE+=w7D=r68VwsP^x%`1^vm>>smi~0b6pSE<>fdf}CP`0QH z*kC3lL?_DTE`Hy z-k(4M{2k>@<+9qTQ>S)J?VUFdG&BRhyOo-sK}O1~hW59Yl(djs3irE=7UBPaq{AJG zMkNUosI#>6XENcTu+3g+SKuqynQ!VmbU93LM?`o||ALPY@sPN9?E zkF0`$Jr zaDQQR1OG9<6Ag=wRU!`573da74+40B5GXWEOrVaob#yk>Hk~{Lt2C)y9EZ`Q1@uD>4RcYRq;73@{)bWTkA z{o^Rv+=Sc=?Z0_5D(0-%1CfA=+&Bx$9c=ErSlfxTBKRH9AAW^*Po3%oetT&>2GH%Z z=7-{$cx+P=M?M)yTN)dwl}CM;MvoD;WQGP?p2=9x_(&S1XVi=QpK4~NnKPLTOCYKM zC2-*&ikr2dik-P}wC?!0qQ5*SeV{b^F@Yal(E|s}ee12IOLw9Dfb6>KuD|~J7hl|7 zRt5s9s;YVbALX}h-2)H2chA-PR`L56U%cbR>+a}Y-Cd>htFS(I~5~DMO*Q&{M5XTnKL`)%~JrJYHsrkkgV?VcqB>>-nX-(Cf2+|HT(CBVct^5Ab6kMEB2s0Of!6zNOdQamR~l ztlkg#1%+Z@0A`i(Bfm5f-PaQql+h!l= z^7uUF2nl+^ZPOOC=q03a1b)%~QG8iKTA~ZxlCklVwNa^<(FO3pd#d@QXg?GQlOtci zj}nCKbHzsl!fnop33!1e$RbhJ*o7TCy3y1D!S37+}LJ5TM3&*S+{b)!||= zfamiQ;J>@T{Tt-B0{`mO-TQlrov_)svjQL|@pS-w<>IqNxL=cq04i1-F@D4SyPN0K z!k-9eIsTexzp)r>G_+pqQ+a<+9$HQ>XUwAO5F(hH9nD;kA&%k68LML)Jhr95ASV z(W!La5buy|STJrWv1A6Vq})vN9ecU*9&tsfmdH7!8 zA%~SJKz~pW04Az10-^-_Lv4{ZfIm;H76Zb`)6r9{FAogRY2b)EywQj+Ks}BaKd(nohbvalgXVE~?4wq+AIY7P zmT)DR42RcI+0}8O_d*AnbebrWj;R;Gf_PO^doN6d2hahKMXYj-e*&&7Dq6XDa#B8! zcxVD`Ah>aY2eEN*I=~_TNWg&&8-RZmcqrRWaBzcw|DAhreU|Q8r37R_)v;r_`-?#) znjbI2Io?n)p)9J{L2M5{eC)>tzyvkj7l0lECGv{7pNH3W*>#cUlcz-fOS=rWE#(?I zT|y#nFsvt|HgCN8=@vF@;4}LKYzxq`^3{dVatHJWwS@02C}042TQ>{i;>VxBrFw z4=C_=;UeK9bywa0r9UUU&p@ryR-tC1Wv@3kN{rc%|EhOrlkMQ4x@ULIa=Wzew`@j5>dEulY@Td%nf_I#`@PY=~%I11M~qhP_-H}fD#ln0Pq6;+TV!j1AOs(U<*{k@&_M0c8rJ;gYP7{AcRN9 zPFCRT67q`vtEqwUxlawQ|Jj4Rnxeyp{;O|mE47cNlV-F!6QsHw)Hj9nY|OB?VE+ZL<@nPDO(NzW6SMR3 zBhg^(v~H|h4^YDI{CAEE8pefokgcEukz282M0r&`tINvZfC2)RuV4SlzH0>j2kupl z->MA<_CB|FZ&`Ow)qXLY0=LM{L5VV*6*X`a*$0t%wEi+lf?x;^UO3v@0sN?WSX5Y5 z0)JWWRFrhVB(~Y9@p;H`yL|ylGJ_QHEas+=XP^}OSK8{+X~WQsfJ?UxwpefgqtR!m zrp>6w$|)C+FhGQhIm>r8mG3OT4<>3m=gbiVND`-@sdA$D#!v|p6KJUhe-A)_9QcFC zt$2Uc;i^StkB9`I=~k`!?6c`>Ke}Pcd+(9#-M4DPhFP=m`d4>%WB4SblTwz^hG7ot?F;6Z&`6lf)i%1Y+@i zO4fQL6V-#KTS|lC|Jl394TMcs-AMoGmXb;`puxdp1o)epE;W<=V$$YQ%!iF?jb3> z_Q?&aW)U5Kg-?89KT)yzht$iYB1Spldx5*6hR_Q~7@IheJF?>$VLp{6K4UJ!4=ZOkrO z$Jy7!5+R3LN%J7>yc(AXlON1tA9Of%NkTL{Gh7n2Ml!ajtY%p-zk)y) zFN*w2%V5H^4<#wJ5#p58;RCr075{Y6#+S9x>l>v!lBpYPK|tcjf9V{=2M)lv5=Wr` zl!@gDahuvvz%Mtd?VLtd67W&?0G*o{gHlev*a1)?)(c9>Gfdzw-v1!*Z{Iha@yaVt zJ~@5*zP0>~(#Pk(aylfV4swXa>v|5XPz z5b{)sArYh$Q2Y;@!}Sv^P>i=SUy=~yzZ%2>$NU7tePjeh?BV=hUaQ7y zue~;V_38&71bjgo9Khqs&Hq85TZnR1q6_L{{RII>rlI+TCB@knHx0@Q`Gq{<48x*I zTZ@JEx4m3Sm#aMzNYS^pDY%K|9KD4;Nw@1075}3g6T?0lCCu!Ijm8NhZaGt(m{B^u zZ5r^apc-t-%^2K6-9_+#h>6rG4j_}Qq#Qh;sB&a(1Z1GW^${jeZ;&+t@D04Qpiu0L zx9kpv<8+}$@~Ii6MMYzM$j?QwtO}MFnbLB3Dep>#gU1^OGB{{%GHmzZBrr*uH)BVIe;pByz6A358cv<0Pz>XGDR4 z*E5!b`b|>d68-~XqBEW)NhjdTqF@8D(n5Wl5a4GcOuaocBE5P2Ee^VKECHKg84>=+ z0Hy;;x0jyJV3gpee|OjxOL%-Ux+t+t_SGK0c=6(;Q@s~@d*_i+S6YT!NFXHdcqJ$x z7`V_)z*Zr-@j~Q}ky4>w17RwWjHvF4iJ}k3Pjr*+{>cqD+;A1}UwZ}oJIl709X_$Y z7&SSzc%|gEHlM}ef#{Qy6QT_9s6{3~A>d1n_re8Y(q2h)PMbEZ;{rMF4w4;2XGe+H zjw;QM?E7;Q!vC$(((ewNBiV#*anxm!6hIU1Pz(MKsUiI0L?mjV02J@HWlj(F$7yVO zr;9ja@z}KEh`>cDs41_y@TlZK@!Ic2E@TJ-B=IQ}SB?Nm3So9S8yZxi=8sr0Dl`-R zD(XRGyr#T&)zu$ONBLdBzy}Zh+m}E6Df~`FQ!Q_*l zAnutq6Zj=cpEj+K_6G~SlB@5WbG%Oi(_GujB)Pi+UeAb6r@cRJWGpm|#S#u5^k;(_ zUDLFON5cu*?vj#dc+eJ4h9XI!|Kg$=|BmCp-vmy3e-D_@8i3(`l@*#PzOf8`QCr)* z!^sMz3Ltpkwb(n;-7*@!3lkfW8)oY>u zU&aOyaF~=I+ymnY2N3R#QA{V)Rcs)OnVh7=S8&D%_W*P%c^NbSKa!O=dg>I3YJxUG z)H$7fV>RMPjkmQA46uVN;C59;f)1Niw?>0eI_Z)+{og-lkA>{939wZq6mHQI@xgf9 zNNx?y=yKw}3mK<%iWLBIp}v4G;|qS8li$R2f}diVFd96lqQOpK zxH&r)3Bwn(fLH-1>F{DA?l?=Wa2$iX z4gQyHckDPBF+(Y<9=NzuilxSTLd6`kyJO?C+-s>Wt}qryT_*4H^iv zAYcxWw4%R2t#BZ0a1!PdGeEqpG6GFI5P5|*(F1U^*m6k^_{o7$=D!R+>CUUJQ4s*J z%UBNvNPd;AUR~8d$rGTF8*t`y){Iw-IbnTrjAyr9C_mME3E)ZgkeL;+FMu!XPjZe- zz|l+PO~+ALJ8GzuR^(8>+ur`U^f<6>ED)`BWh+O5M87m0S7(Q0{~MmMgKai0I?we? zGTtw}p6tkSzhf6FAdSG_>^olYg$V}=PLP0JU|Z=k99AR0gd7PK8{VO~j> zh`2P=@Bd2puUh-$`fJy(f9a(H_>iA`=<>3%5B49sU)%_mF3OAlWO|mZT)C2x&yfqK zM9W?1RVHsHiP_%^`8%cwE_gfh0-_He&Y5#@(O8Y#dO|#})}ONx8vD;CP9!}^hklBl zX|}nU|ou{@+SCx|tL0~8A=&4==X*#KQ^ zfno<(qlxlEdHIEdxB;xXFfbv@D*ng^6He)bAlW}<3c3&KKe=j^=)PY9In;jz@b_+b zP8i_uiDP&Q+_Ml+V8B+c6zVTNG7Yg;lqLh;t9TH%2M6HtU^Qa)fdAr-F|u$IP=bK8 zg8at-yJ0-u(QL?-9U}Ur^`2cUT_Ym@Y~}ShXbyC_`roLewZ1Mh*k6|!aXnND`@sQt zB;&cU;zhL*42TRAKrW~NTrL4$-f(NthqbjAc8IIGSa84#^!OivKbKQ}kE(Qihc=IE zrf=8)^sl{Ew*9luK3o6FQlx*wf#>!v*)Ad=W`Ncp?u+k7wv(wQC%1Ko*dyJiKmtMs z1#tbu3%Nw-hwWF9h)}6%7N7kGDNl+C}$Vz_eLLadM61U?!Z5hetfFmKBYA z*f6LEyfoH%y)LSs@!+PgD^FMXI|I&f6~(~?H3;zz;Q;J_$|)*t|AO1X03!a%6%>Kk z$?wZ|NCptrQR&(mNnAReCl>W7%}=2d@IRV9Yr}@w8(w>jl=xd4HmrXI?LS-UezOj2 zSG^%8a2<#Q$t-{f?ms@ZqnwZj(^_RSRCqbQ=vv*Pm3sof#iLvKNQ3CG0# z*LSh6*pZ;qE9~<`Tyfyf8j}Cr!|ug^H0x zv*VIv6UF_J8=l-L0xxnfkCz25xcs}OOFPDDzm8?I#a56Y=y4uNBM> zI9JX-`R($Z;9rTN^7^DMBRng<$2jog|KsD=r-#{9?Da%4HeW=~=z2Jip#Immhuxx) z6m9$twqlgjS*(Nct%G42EoTfYQ!RJ2*^zccA}O+7&Ic&41rI`Yma|hnz$D1Z0~1GuqZU!?ys&^#+=SQvt}?ij;=lS0Kr1=b9=ui*7k=e!HU5BLWJQW74A4_6&7 zlQhtJ+N1dF0EzL#|NhTE`eRXU<>tkb1450gJlH|XO;xv4l3Q-d4+HL#(L5EOpd8iL zd8r$51NdA81{5w3`v1JEU3P}BIiDyu8r;O@L2O;tmi+|!qyJC|p%mLk(Es7Oe#+nR zp&{}gcwDO6f+AB*1ykk54qoaM8=!jZMDd`8q|2t@7(oEhgc2MOf9x15n#6BmIMIAi zU)(;Lz+wKiugsQQ_w3oTj}?FU<^A_RST>z>*pq?)*nbrmIK2PLc2!%Z+UawGX);5!&_XQ3Q{?9(zs$(2k3?lu$95la4_@-O@CeQeVe1!r^FDl>8R zlfwV?>=7pc>ZOO=MxS}OztY-2NHes1MyX&P1x_AX1Q)s6S08*{?$6O3(?jv6p+}|q0GpDAcpZ=(T!0FomvCSFPw_xeedRlVU7{|D!l}HI znB3Mw{+9z~d?tI_QvtesTB!eIqU=_T(f{3U)H~R;O8JL9MU~Y)n&fB%PQ}un4A5DM z;jJJcNkf~Hz=Q~#K9f1Z1N25nVpupp79*r+?jZLhiBeq9URqFhpuA9^75=imh0p&4 zuNUwsbgfn3i?Uz6-$_jCY@jv{0tym<04Omy{NVlfQwUSZZb|e)bAewtO>sSPC;TUR zw*b7D{W+KD&Qzuo_1`0|-?l}Ic67J3x5{}f>`Zr%0XySh_ny@nW#gr3h5x_7Q6-!& zV7k0{AB~X#OEgj)%g4O$lwxxw4pYvYWVX>|IsZWrpn`#u(jEf)vmRNJtco8ZFen3V zC_MDlR1{4VI~$Pw8>P&tn1A2;+1Jg!?z-zXZWJpo2HIIH-4W1#{iP6MevVR;3;k~AT|x*-f8Mu=b4D(au=mTpYRMFT&4P`qu&qV7cp@qaLK z6u-Un(x-yHaQ_*$is;Ev6aT0E8**#_s?id3vH!smKV3o;6b$+vD#icE@t;5p6pWM9 zoe;eO0>Jg3NW9@nxyb42lpGkA!8=as* zX8Myaty+a#fEqPcul}IB=gZs#RSuFpR3L=27)Tu1E}ponVmlth>!F(a(|*fo>N>&pNAuk-+Cez3vXVvDiMDcE0UbHyU2`=J4l zFL?~g5t5OSydz^-k-q~!fP8o%`OA`60g3=kAfE^uDEOOcNSlTiBHeG|_7>Xvmd?Hc z{@?%01TG>vqJrcGNP2~M;57liaKVdZ-DT9miiP@2isu8!3dtSQrjqIr0g$^fq%Rfl zn-BWOF?i5R$TZ<(;n=_*IVXU>3-WVxP`e}P$^>t>gilw7Q~4nA|B5}(-|ms!^K6KU zdS#n=EaBtajfYzOPNu_{j7^9bNGKvD$g!Fu7mgpN&vf3@OP53)3pXMM1$mTkOkQ{N zvStv_KyP!OBz#nR-`eR1u7LmGu`h`WB(d=!H66){zw!#%;Msp+k2}iBsDpQi$1Sd& zm=)F3hx4oaUQxaZ2QxdsPVI5ZaL6YPAFhgWe1&%_CI|x>fu9a2IfRF8E4pb(>VuX# z4$Tn%uj^YJq+tvvvXcKRsSEe_4ciF;+D~>ih}X;Rk6DzsXU*Dp{e#8#|1$|e+`F^OCX2|7paO6L zURu9lmgolQ0^HdBK^5KnvWr2GOQ0i(E;4-`)Fb82_&s8K3;M6)hzfT>f$+e%YRs9$ zheB+DpYu^1oECH5!zS)*HBA5^-SAbX$p3Zym&fk&rV_)Upix~Jr2~paNZD`s+g8VcMhnmRltMZ1xfB6P7@nsDtS_a+M zIj7?wc^8#Gywk^pDKm*Ib0&;OHum_XJZ!2h&4r#Q}X}c@{j=Y*u80& zLl1j{=@MHslV>;IL#-n40KQmqvYY>7^WXlMytG8(7)8>;WJQk>i4%b-dncJ_6@*K# zltP8VKWZqHzozo<1M79LgN7YHpKTc3FNi-?O3jO7TB@WRl2k5X(oJ|A+vsh)trnNA;f5 zmP5%{q7ae)`g%?Yk-cLHn}VO{*B0<8|A+9OQ@KK}Azxe%Sq3XB4Lwdf#BbXOU-97y zpq<4NPGq0Z+U{?z}8^pVi6bESkYd&O^Qb=J;=KRDp^q-E?jt&Cw zgHARR{<1h+;mhLr*9h2oXv(^WpZ(sabhfjf2ihy>_U}I-`#PLt2vvJS4*gGpVBx2b ze~I)!E@7VtmmWHV0u;+9D)tZa=KTSq3-$R(H8`PzaYm=ne?)r>;VzCuh0{5P*cVYa z6|E&5;){WQU;zFfmLsifI=xQO7E4?XS{j1>oE2vGrIQ?Xl(r0pt=3Ju+5F{;rEY#3 z@7xJf<;0zUyJXiJi)L?=I0LYTWJO5`DOJo0$;17x2tWop{%~&2{P_>V*1IliKBWNm z7qk0Kd@I6pe1Hk=ga&*B_%#K+!hpbkj&{33qC=TeJfT9O<0M^Z1+S;T{9^NRv|o_# zN1q~E;;sqsKmPHLH#e?B|D*qWX2Qh=ah=mGINKs`WQXzppW=YTdbc}}XLqZ$Kd!g* zSBB#*TRimJHdIs2>6E>8!u2&o^r!=oD3L2sj1`oIC`U*{23cm#oA(#_SBMaVd~pc) z*R7qtLDabnmE<`F`vd(rT~c5d9Q#R-&>}9Ie-><?nGhv}2|*~@Of4FG81G$%k#}nYyrzd}oOLzj8(-r`-jR4LS2APV>_m8%H4F|5dP?6<@MQj2;LOd1BKk zIQVf9D#j0Uj5!xwlE8UeXsQ{~)7Z&{NBa-WFOHG$Q2$_M3+LI`!cm$&9ppc{h>h!gb^-vbw2WT+9AxSplb_rbsdt{mYlmfBW*-{SPiWH098tN5R^;rawrQ zS1KI%7)Ss(5NCrD2wjaZfBBAa;e8Px(I%q!k$s+(EgV<-gjspx&&B!ox$U80Pf`x; zNO9tcP8PVH{ZD&Ju?yy~kJKP1M{LRrR$A1VGTwJup^}tysYhc(l_$sx1}Q-tfW`P0 z3=mN81Exwz4&{u3>LpZBG(&LbokW9uaqiF|Y?%}XmEQADfIvYX9)_5cilPr`Y0VYi zUtGL@(K)UJ{+&C|?G%ju37A!h53ZsKLp-i|^CaS>$b-gbN}yN&fgATvXwQRWPI$4+ zU*l|~|C8+xhA-;kyeMM)K}x)tP;^B0f3$b8HIj3b0(tiN2RZPE%>lYClQ-TW{^9%5 zzT;Oqm3nNhW`eGSLVX?t6x7SXOUG$4lrCH$x-fo6p+E(pgc)}JkCRQ%9|Uyv^;Df8 z=XpYCg{=mA(#u*j`5`U^DohgPeONTyo^ywGej&*&$*C#@C`AvpqfqxH=2UjSb_caN zdMNdA|Du@)zM>blR%sDZEy{ed)oK$&|mcAl#}grmx?SF$?j>j`*(tQssPI)E`ru82x&Q)lhYo#Ycwp8OwE|MVx6J zj-F2>75#|~9caH`lJ39^hlj-38EY*G#vW=@hDj{H@G4!$)M40x2MSaaNJ1QKxN;em zvAY*HKyp4*U?mIQL4znc3N^%EyON}=om1Ne-V4kiD!4> z+==8Dg1&;whlQ26Pr1G@f2}Gsi=G2i5vqb5s6-{qBzz&s&xYa&;-4;$$pL$Y4;7De z2W&%}gh0!iUHpGK139gco$=Maq$LXbSAVR(%0XTawc(u$b%Z#}79*o-l|prb;6g{5 z97I4u#JS@Vj?g8#^A8kCsSPX3wi^+Bsc}IUQTf8`G7Hc)^!Ud`T1k3fS}<8dS6^0k6b+R5%r+@V#`ILHupqoJpV*O9Q*( zm2OgbTUmDF&*}eT2P_5PR4{9`1)_1o5>6zl1CswKZ8uV>q{U^SE7Iz-4u&&pUQL{N z_tj4tt4^FaA-u&d-4iF+#HHBmnBUKTvbx3W`{5XZ0z0fECq|!~l<3gVz$(6n(9kOiG8tfgt%G z{J*Yt!oRGABaW*3D?@d4;c(se*F5q0o1Zi;DpP~)tA!UQ*wflwRwjE|PgI>iDHKgi zQlk>uEnYd+0r=(QgCH2)8A9(XeF*{yTgb6x;GnQ$00uyN!TnB{Ok6DFXb1ba#AIOY z1ZToC%I{DXwL35QPry7UPPrxL&s{{z3BQ((QL zqq-FhNDsKdafLx|>T>@d@Q>I=LM}^*Zha;gUbFRyH=p=A+}L+{%w_LpA3yS_#@xO| z>|H%Un?Alljeq>Z8vmrfTR1=^1ZYE3FkB%akn}3GrE>VFw?5SV`1moD);3Yx(kwqo zeY>{&((k3hExjyPP#}JJP;MYK13d(t zqE{6{CMO$T?vew->p88K7I$k>&s0M1ti^30{}TNe$tb5()Anqk{~q)>{jCqds|L?p$zCR)v#YF+slv{cZ=x{2j^+N_1fzH_Ha*3v6Grt zKk*J<<QXzCot5&W@To9bB?kwf7E~)?#R_|Ad%e4>%SZ)=IVzIlKQ_gJ zkpzbu6aUq7HcH;@&`0$Y2bPAPNxb^`({JAQvzvbQ#0q+JFOMlVsDD$gyuSeyy!FUj zZYldUh=XvHYyS4flhar~DKT1eFK?ZNjipBtno2u5ZcS6I1cd9>Jvw(T%)~|j#YugK z)~%Z(9}pFYlc}V{A9CU7`PBX&{$7B= zhDS?v9jy_T!QXxVX-=z?bJ*m>vTyz`g9FUIcaIuZahTWDkBAPy5Rk?z_^^@}7dv=~ zCTwwrMQjUzi1x>Mf%XFY!_PkZ!*wtb<3`5(XPo;tpX1Ift(epPdp1e``Q@X0B+#o{w8?f+*tZp@8kXvDIZRHPw)cZK( zG3sEGGy4EA1J$lkseiQcrzH%I4IXl_{fF=$-JbfB5ZhKP#(cOnLZ+KLh~}gM#@} z=FB;F@=t%l+N~Ym&aa(}RK(hahKR=M?xJua^K>f4scTfNNi6`!pQ`k7QhwW*9 zfmrQWku$88Y8w3tYdOyAnrr&{%2s!CNDWS{B(rlB&S|pgQp&^gFk&b|kRV1teAh=M z7xpl~3;1_))SVI~ktWW(0|N-b{3(zAD_1rv$63BFjzsTK3HOg5pGF3)lA=HHs-qr>4F3BRGcebZf*6XyBwpjtR-rxM9T%kKCyMx@f9m% zXAGx=r$#J8R!e0|W&iKqefo*pZjwETQjva%)|7p0R#LU8m#&riwA5%fZdg^o!oGcT z%c{z-J*b*LPAF%juxSQgM&J-a62dDNR?hel&Ik4ffL@@!B22^LU?M{Ot;gFVcuXQw7AQtKtEfiizadJpM6+QyEu_7C7;xv+?D(a9Xt|>5>td}=v!7EA-x0gfQP$SK~($6g&z2evqi_z9xCE%-`lDl7LCjq>A%|3Wj zI8zuCUX@ey_H8fYn7I|`zj}v5CadF(V=RkAo5F+lSNMgm1(`ZM-hp z|8Ds6uW#D7zEFeQu&br3z&;&Jb8CNDz(%BjTp6Xm2eob<{_aoE__k;^+l+ ztL=6RhX6)7|AN*yj^SpQX_VlIrp25{L_AE~hZfu^;9q8bIqG3O zWe^3mRCx0aM`c@d_JxNt zo2>m-tL}X>;r(RAgS4*5=6uk$TzD*RL&{2;w#|qLyl;dpaHIl1i(!PCpZUbw;CXRJ`g_fgkywJzEt2b!v}R zF^H~OUDhWOwj3?Can@H~p%^5NB_$#0C`nFACL2T81og$~`Sw511tG29%V%w*!o`vS z{mPgxB$L*^*-9(SnlV221Mb~q- zPFZ&kmRJs0*gp3+OSS1x2i~~;`dMFfmEKg!pJp@gd-)R?K{`N&F7rS6AGUvbIYyjQ zvHNutU`ff~U?vuMb&a)AP9~GHDfazRZPC5+PP9J!Uq!&Ze?R_L-y=(>FI|3MW8u8E z?KqqCoB%#)S587LE+C+`_8f*!z?T)X=j*_Wg#++_uu$c>@!XA%f(PN)S+FtZ!|`y( zp>rqyP~LR$;_*udrI2}cB{`-E32B`Q{u|_k=(S6)bd#yHRF51dC;f)o-}=o$dWl%u zbuTjAi!c7F^li3zdO`vIu8Av}<*@xECm|=L{k8FHD-|HT*`|J7Z{pURn?)jDZb>G){UFUV4=XL)0o{K1f zA^YnTN$3Cq1{W=%mVhu3k`GrCo@1a?sHAvs7BIovmY(`skq=(jf{9>=oQS*(wvrt*9e<%i+ z{Dw*uxGuaEf6b0APW%6B*-AFRC8*fBi!S)ww>6Mu%YJhR7LZep(|{aw6A2DpB+>V+ zFT(w91{jJ{(OohAqq7YCM0+5glYwqFcfAyuqQHm-_RkV(NuC_Vi>*2sC8W%r(6tXh z#d{#1sRSsIi;4;U3h6s07Qi_8^y`;ju8q5NrtZY`(-(h=o{tCWWy|jCYxG$KZ^H6f zX8p;H@>i)0PT0wE>9DWSpifJ~DIZvPkLbs?{Q0&=sL|nC^alD5{8Rb6OeyD&1neoW zUKH6o@64FE%#G_aUUN+#K5oco{SCky9J>XDNq!IHA3gf^U1+&W-~RPo+5wl{jQyi2 zkXDgQ(>*K{rr{otR325HBGODy2zyk7cRq>@h+9hZJ%T~es1 zYwp~ob4kjafxB}0*lun1VGtK z>({gSkN(5kFTYF{Dc6l}9~J#~qind_Tvv9_yXxkfZ(qm368MMdWa20ZkqXdjufh5y zUwGTxnOiV=NGIDebKr`D-RB zghRrD_L)w}ZEf?&?BZIygLS|VhIDzNg;_Ow?L|iR8%xbVJEJpD@WglDBrv#S+S?z< z(K$;(@@^etZrV0icFV2v9@uj8(Y0_I7C%;>N#y_qn{XTc58$*&rGrb9DF*%Su0!hV zP@#$OgBUvt`YEYkY2g0nvT^8dQ0Ca6iBKOkpz8mE{8Ph4a=~L(v*-k=e<}wPH(0Cx z*;#nc>$5KZV^)o$Fl(>%U%!6SotxI3zm7|;Cv7v0xoxh=YNB=x?htep;Sr)6Xe-ix zKYjNXfA+IK{Zpwv{!qYY>*uY%cNXMx#KkLg9`2q?-<vz$T=c-s2Oc2C z1q-41weuAvgm{AH9c25Vfw^!ZgB8W0b06`q4W!ZI091YL&6gQSF*5GfUnNMj^*_D3 zlNNm0LZ{sq_BCj|MU0!ySjvAUG0IOWP&7bjv;hFj$Z(=oOcY=7EEFuO_@8~G0zH;( z{rXGfXWalU^;(Kr5W{D2)YcAgCtwrekpri3>T?og4%S?8$G<-mzhsl_4551(1vu++bC5knzia@OqJs@U zz>tu>O!WsZ`(pce{-+l9RzB`MItwqK92^Rh66d`1%}1ps%)=%xHJXOKy;APW2}-*W z&?V-t;?00dPv;B78v&zF%rt5C@FV^($Y=FcUXHMJvkh6BpLTYF0MQxn+uijKL_~_PcD6feTkEOt&*(Rfk>Jk z@j!P2%rl97Tktn*SVv?}&iCmj-Uki?aWw0)FLLNp3ZSX*p~MH>|MJ^J^q2zN14Q^Q zy$kwp{+7W1Z<@UHTB2x z4f#4{aR3mO^p=@wR!s$HHbUb!3OqddJosOYgk{#B!0=!*6&|6PLJ_xM#+L}79d2kW zlq3=TjOf;LRj>E-g$zj|j$z@0btk~=*}3Q|O!{w#0oWWf*0B6scq;+>`N8Gp%zIAT zQtkoH&rb5%ehvAGh?~TIW#g^ z7gH>2b0T2uDljvs5=^4NG=-ZsykzkE4OYl(7U0D|*7RG=$cHc!QOBSZe%!Y^a~ z$3w?LDY}JG7N7H4&Tya-&j0f_q5tx;wEb_o57(D_QM1JM?ij@m9i2$<1zqE=zm6dn zFJF!bBAx|*D6q|fQU5jK+- zUC8nqFuV=>_Dz&(V~xe-q%|nC1#2Pl7z8uZu?)CfC6BwTf7#9d0d;q{am3;;Jk$b5Pa-t?AOBC%Pm8_+y|Qe_$@nba z;asD*`WJ@&%TDco;gd0_ogh>wd#3{(|60ce&@5iZ&_c1{%#zJE6ZyZ7u&B;~3cll} z{aB04g{`?L@p|;=+pNC<)mF8jq5mxS-<@r&P0qmc*Z_+OvFdrC!Qox(BIOR!b?Nz- zyJ#50`l>I&UdA8vT@;qwOH7^y#K+FaCeRZ zT?;rvp4OtqjRpryU4HLfFJFpNoWPigbi@CI1`PeA$;;YaDva2xt^y1KW@7!NQwemN z{jR(L^L+NdIfcsLfqFRu-Tp#tS`6b@`^FX^HU1U-ruHGm@pqhl>Hq$~NRv){b=rai zb5PE0HYyrwL$4 zHK89kg6QwAHNb4^3_iZ`#rdwW&R%pEp8>%@GuF)S@9p0@mnwNwv#)ib*zcW%@yn_!)nQ!zp#bg{|FixSLP`O!fhmK9*^zwo zS5Yz_MLwDY*nwnOLf=yPhV|uC$5dtZ+U7A5GZc}pGx5avRDZ$cK%fKjMMtcxO&w4% zep>z=qd7*?4%dM`_4>fa^;CU!_^%tM>6iX9_=G#R%v7L#thm)?v1clST*uf>-EXbyIgdDBNB zAG2DsfaNLvgZxcM{g0_PY=|S=)K;6pJihzT?n8&Vx)y@*)axIV{u`t*ZI0SEnr4oW z>L~f|A3PQS79vA~)S|~nLq$&}MJv)9Wd9iE#v*w`8tK9<3~3W_N6|05zk_Qpd5{4> zKg#w(xo(zEWxYB~4ho6Ks+{dQpFy5Q^$S+Sco+c*fNzH&C*E<%0L&{Q^Q>NPt~5nL#LkqiST&xX?cp1aTt@?<{}ko#hu_tkx;yuXYgs zBFDWm5E@AphJuL_7=QoD{t^CDH9$8;;-8M?tC!0(xJ|G2asEO7>-hih)1O!93+25W z14msc%ptGC749nSnT%RD&X_|Oz8qKpCZ_g)q(PijKf3n`wlx7Y-Gz%koCV2ei}5i4 zmFMK@|GW9SQ`Uyg^~;y9T@0gju$edp2~tmThm9vZ1@V=PCaFBCi;T?Is^jp}_3g!L znLG-t`R9e;9{_(CqR`hLuF^4<^G~1b-?a9B=U|QA)uDhjJX`|)(-#cV0>w&l{z11H z`v>|ZwRK&L{M$g5?nD)?sIdD7m-BGdbdS5D4t2;tH76FThNh1#IRBDacmK>7k<8*$ zL;dGIr?Q3*pnsCizRbY~uKo8#cedR}sSgHTtqlvO$JJ#$&RxRwr{Gn-jXK&J<&XgKHr$Fz{Qlk$4bN-FBS|o?2 ztY|9bcrz_)IBega$y(44b0fGB{~D22cV=v zDQJ>@Ov?~+&Q*?z%$>G*EIDs(?+B8Lkka69aXKJTk^SEu?1^b#rh1Ha|wi%c<>8@K}#nm`E z#;CwEqOP0u7yqkki@9(@5(5RJ5vetXjoPv4A|-oBHcPG%L?MQB0ruZ4&OgfYxJ$zS z&41AG?^{p&Y}`&zxY2C5+pqW)B#)hTr^)ig^)>^cDli#EfP|vAl!+yJAd7*n8dvCu z$}xocapd2=4f|aAN1a=|6({!-1DGJ#Fzx0;uKy=>tWc#YA`@&l1N2bM)icF#~P4{KsU<2Ed%^>O!Re7$KwD z1i(1yY+J;mnE_4=TUdG}z@a1cp`t|P;I~|{>{rA&+1aDJG5*p1I@tqiAl`2@Bwal z;2W1+cKfD%5G@o2QI9B~XdXb3dwwADO;It(=^`Ety@i!08AUE|*EUpc9Tz<=+Pk;L z@PCIxH0AbqvNQxPfQ2?9{0kDpI#aP)W_UPQY8>|Xa%HDjDLT%99?t(C`@i0J1dP7* z^AIcwf1sB3F$nyu@-uE5x3^X<>*yj862VVSKe2kj#mN8vttU=7_GCrl|6=|B;cbc; zPhD@{CGq#ICzQ&;;e|ipy6P&jp)R|9(gwsHhal`<>Ax;qN@7fN*pcYPU5sIlaZUhc z!#)f?d@~EW4yx&j5+jKR>Ws6sJqZMOtGANd?3BU(k7j9;U3KMuD&9t1XC zdZcFZ#RC3c^q=ehbN$~s0VvM0L0##_GceS-;gfCbyO}c|ct8&Dt}&doTzIXXp)f|d z`jBSmZ!?Do9Dwu4fy4w*TDQ4gzUv~_OYXXfCd<*NNbp$~UB=rcS(|KSCIB_K0Fzqn z!gSVC08rj?Ghdv{IC_$@j&00@(O1aLiq!hI_jhkiar_St7R%ngAaTG9y`c^NcWwn6 ziuTd1XeyI;8m&@@E_uEh_Mg#zhJO6NngRJ`4gHz}&OU69%fK@GyL0Bb^gq6mlKzRa zRVjESAG=N}6OMe(ar$op;Y4mUOyIK~CDoHl8SQ)_M0S~yLw*K0l0XvN^@T*42#WjcU?Un#Tt86o*@w0Y(I z6$8lpG#ZGuHFJ@C5`VuX4~~pm^`#^MK;%y&Z_%W?BK{TGF!sOVJH)ria4?rC;Kz=G ze%EO|nZ3W>lu0Z8$94OrXP5z{{F@!%TAhC)S%Kd{eN=E32sx5Xf^SZS37oHlQ1SpT zfAG_nkmJMwC?6OM^(Q@55MF#Vw6+Vafa(85{+FMASCt4ofqbQkj{r!(ww@yY!RUWu zx}pDF8;v@Veam+*TZUCA*~kaL!3HgD8uV)eKtJq{UmN1- ze{&fEkTR#E2EyVlqCX}`B=*N~g*a2GPc^tZnu2y_V73`Pg4iDNOngw;<~ns?p{?cK@M6!izH>0%U&TlxowM{MEWclL)! z4j*ZyqjgWpS0V(GIQ+`}ji;X4J74l0{V)HYG&1q;3oqnM_2lR%JV?7zP(9fF=d6cz zE}=K0pC$ONJkfOp_z$lV#9KDPDCsM$LWjvk%1NkSWgCGrgCRT*o%`88liI49< z^6|drj`xkz?FW~$I9k2Qn$Vvr%AckMM!2sSp!Zw4=;T^OJE8nH@K2fndK}XO*t;3< zM`!adD*jupuFscxmqn%o05Iy61$Zv|Y=-9FxSS;X&zUEy^MVUdJo`ou&ZZS9)*ofj zq_K0n<&C0!L!tqA+IhjPTek2{=8GcWTsW=_@Bi#)KSP}xY&5q__~>1~CKY@m(b2a~ zG68`3l354#!fYfUyIX-r;z>JiU4){zgzOV(I@ORX2FBC2#TTjbucV?Q zA<>@z=CKfsQSwawV`qxE&`1W{JDP(89V<8x{Q6&0|IkPNKi0jW|KW4rc;j5&kpCpV zsbL+zI*VMcPn@GDG?y@vCUoov?rzk8qo@|>?6aSxl8Fq)qgvu^+sH>TUJd!?c8YF! zY`GL5B}VvPOb0ZqKE{hg#X>|sDu3$I@$6TV{(~z3ztbf@QcqRlZd-tqU;;J)qew3` za^c;iSZ+$lQRcw|3X*R5=?mn)Q1MX9dy0Addz1lYnkAe5S6IdDjb@`TJUna-_+R-W)rzKXq zR2oMA^^zCSS*zRNVw5sIU(o0I#SQOXcl8TDyFe@(XUA+jfqjU8&%rUbAU( zqm%%(`~p`0*Mx=M{CgRRE}A)=3^0K3yx{ZZ==o`)4rCteoGGY`c@!r-I17d6W|9yD zGPdztW0>%X^q*e9&yuxpA15GhwcN0Qe-ZuN&dq(EsHZH{9~I>wfy; z*XF~bI{z#G&0T*q6Uh}qG6c>F&NyeTk}Du*H=cQ+L$C*CPXaL?;YTSSv>Wne<{d@c zohAMk`8an-A1C8i8KH*tP1FMN`7M_m#BX2936ZHYB_x^vsy`-mu)Baup^XkRU?i%$ zS(JuRm(jvpwH*puanw>Kshi zBlWV^<862y@BjF(U%mReKUM(@p%i2N;J8Q4C;{&2N4EX^6MyujKQxZ^o92mn!d{%V zgjI)EaP*lKfCHlWRI6w9uCo6TfhNi6ETv;WKJQGxwsSs7^P?~QT^$RahNe-(eKaRdSi$0PNkMs6U4^llx9FG~ZeD;j7o(@&cs^oLO#adt|5Ui{f6NoBDY^PhB)uB@uJynJ%S@FD@n> z0MirWhqffoyVW1lbh)@doO8&4z3Zp}K{)Hw-9)LFfP39UqWa`T&VAh@t98${waMaA~#U4E&GhZn@j;35kH;nB0y*%txe4(;0)zaxX__iy*@ zZ=2j#Rlv(LDj5RIzurN9=EjpweCILsLs+0Q*jm6tMq?A5NNm#{@P25hzZ4E6Hu+(qQ=4-}~|o zugzeWJvj>fy}hwG{a$bZdI)|~{s0tA)v7E0(K{Hg6|8JJVwDGcG=Olv{E zUA2Wkk}lcU+N}vf~ z3JkH5%cO9jy!B4AdtLM9>Ad$SP3AD3@C}>L;CLx5s2a~w2le6eE4mJ@?HcRo*nR%) zLlbwKL?PzSOrbuZ?R6{VrE^i4H3r5(tT##hYdRiFyYSZlemK?eu<$=Rfrg3F``f}b zS`P+;<*z57`|5QhD(ad!J_E|lzF;RY8BMbZFY1fyWy9G7>=eML=DRszwevu85^5MTf1*S|K`#VRw$aF%6@x#@V3g)v|*n5mU_--uCk z?RrZ)pNtmy^o0K)`iXFjli`{{{Bp_dk8aw1XxZ-H;xA&=$EN`D&;Nj>m*6*ZC)zay z!hJGfGL_PhEW|$g@WU1RF}4IP{r>+PUG_sDlv$lEJK;yD*9>TSXU_cX#6xJLv9bNs zzd|GKk8nC-*X`1tBVa%DS%Cuh@3Mcv{;fv~GzDoiHXjZKeK%BIVFsp9{{VXnja~`= zyO)u3w~RyfvfaP=&2J7ZTd4yVXC6f)Chl9X_N2-7H-B(vkzgwK)P{KLOv}&ao%m>7Rrf2 z=!v1(y3lFVTkd93??QTglQE30}Ab!Y-; zNyoK&A0A)jJ>rELCHZYP9;tnDx2dnk8pt;#e@i&As^k%+r^G%pc;RE}QqPVXr=46! za7^ie#(<&Kr(ggGbD6ZN4&Yz3d&akq=1=!fhTz#Zf+!1P2zB`+PSum^I>x$yW943B zijKYyUO4NmB_AE_7@hvZC!YkbNU;Oqp9=p2@V}^S5%;QXrVx%YNKZJe{y%E}l(L7c zLb8$Blf(Oc#5YhroVa0CPZv^sbQv5(09sYSb=W|uMJOD7Xd;+vxqYp-RLryXie9lu|pkt0sIfvgIXLggQwYmeemX6 zWJ;;aiv$d&(DNJD5*Q=R+IWSod|%UmrTX{*6DH%C`d9DtfO} z^HnGTiqHttlK)?6VQCvci~z}Ro2h-tKNZdde-U2w;zY1B$YBlhou!{4Da zRA?Z~L0oS7blm(Dd#O;9_wgw(N>A%}=?Wsfe8;$_(HMaf99hvMPrWu<3)Mkd3$Fc9 zZ7_xEHsChAi@p*}80yn(0ZC9HjEaq1`sq7}4A{sPP=_WBkas1;vRqmo+`xz``HSg8 zN6rBBE62OjA8H}uJQZKDp=N(}w5a@F(js8~INguzMxU1sSb$$2!9W84O2l!2tHJb| zdC;0SH>)>EnT;-9k@^9c;{OlvVs}mC7NqktvrH;k zQU{+gc};xMicJIt#5JHUJ^M{pi9(NKdU?q+7e z^zM*w2LG1&SK(h}Z7Y|-0q9i|+`dA(QdRzcXP_FZM&n@qmIlh@2K4t4B8%qtb_+m{ zTn+<+DnUz3YjjM{famDU$1hcoVgTTloD>YIk9Dj*T!Wp!2WRm# zhZqB=CS}XmQDIk~ZWE)WnY-9@%Yj{>}R7Eg72DIUoib8HE zVJGhBVxC<28pkAd7kNnB6Z%PV4g>)IrM;C^^+iCyuz`C~{Rf$$t-;Vxyj}+z#ghXX zHENgXkR4goZ9L9|v4N3csr0VlkKx}Ft}Y)`CAj1>Vz=1cs4eK`(r4L#l84xGZ!I}{ z*BC8{kQAKa^qzGvagJ2F_t8AsWw-t3shMo z5Ng8s?dq5S*dMns_ceEBfv^!2IXC!su`Kv^BZJ{cEn6bK0Rn3LB(B!-LhjS2F7<RN z1}(eg>;)6vf1foWqnpK|j9Z)5ED%3ZbRQvp<@;oJ)8qH3VIQe(*;<(TFX3O&8)_&} zu7*Gs4d`CXt1@rDj0- zWR6HC_1Us{KjDZ5sPJG&%Pi&gBL`e^>q2pA-L$52jPa zLL?dn|03tfdc5UEqw>pc@_4Ab)0?`Gm>a)`{O>r}LHPlP@GB<>|CCl3VppL(N#!#E z0=|UvOy*E$lDQ5 z5De5vtDaW>FT$UGe_*5#sfMkA!zE9>)y#yGiRx#%$>4&URC9E#=9RB^Tzg^^;&~VE zcZ}oT>Zl`Ktpyj^2JuLR|3(84-6D#89sp7xND+@$1|g6=AcrVCO)pseOy4PftMVbX zTF0(Q)1GDLb4vt?A^g-Qod%3lg#p+B^my!mXM{rt^(Yi@Y6Y#w_{a|KLcx;%2L3Ho zp8ie>zv~%n09xDyokXMr{x$W_y`9Mvq2an^M@pL;!NZMGq2&+w!G9L<FeVN(7YmM8UPfAoE zx0duS?Frf&3tU_+4##)ZDf-1*h!q6NT{46~Al?MQ2jza9u)k~66iTxZFo#|Ptq@r) z{O|6q-5hgTPBC0+7J#|(S!D|xM8!YRf1RX5kr5lV6MaD^cRl%mCA%{C%N}sBs9;=M(dR!LrnM08oAh z)+vzcSXQ!Mv0jY)=kyZ*_`@^c0scHlo!3CHoH6x}aZdl~%y1)P1vh)0V9@eZ0(Lkc z{BKiuV#;n@TaV?3&6M6ll!GA0NxX8$5mdl_n&lrqs*X!5`EKbB{wTx~m@p7pIOvUw zo^MWF1QYa9v!U$)4ZycxIonSG5e8TiQ#XvC49&evBNkFo!Jk|pU z&5TlNU#RVT2>%iLr@glpx9yP<{*A^S`dpCcUN!yC=zdV60WR^+REfs7j@NMlk&+eo zWw#^|tgbzU4v-pnk1{;fHcqDj1VJ8-rHH5Fl7FoK_!1fJH?P?OXV1Clu6yqJ0YE>3 zeEEsFn8*Neqx|-UI(@bR54O)i6wLD1QSk{5Vo}Bpx%rr$X%Ik>`jcT6&sH~ zOM-y>;s&J|%KyNSz&-runWv4aFGPo(Cie`f}24pvuXHBa>eLI^y`Wh z7{Y>vdVW%u>__c+b?wqP0ZS46Ff95n-rq~{9|53}Cs%EjoW82ZV?|2fpK>blCtIzk zMM-4C*-Z6oBWMAHp9TN=1bM9Qb6ge9CFp|MO%nX0YmVdUGM5}3oK=DBW0d2nirs0f z9;xU#XKzv#3B(KWhRaZCKDmHDLg_J={Putsee#n(x(7wDR(L{V)1TQS`rR{?ObWyN zI!@?>jBv#UGMIu)!HO=%sgc6*oKE*MY-~1F390`FISzx(!GfL1WpagVu3=RjPaQ8H z_Fp_Ucntgt8iUxLW*rX@=(zaD0>9j`gIK!sFx*c`QwL}NQOH+WKO^IqB4?eB zdnhEGbqx=&_V6mFzB$t-5v!&&3wS2Q>w)+=1*au=BE>yaQ_Y3fULZhjJy~;q@+4*kh5$Y>gHR90%NPJn7+W1Pr9<@7|Hkhh z0st=(PBrWnJ{}tdQ1vMPEmX_W_{}O5JQf_m`g;%iNDUVK9h@flf2h_@&@~YwRvoa6 zugfeAo?5d*#hc@XAAGOLcyrF2NrY+%OFyXeSEBXfxJ01*n3&H}IhBpy9>4NV6AN;A zVH>UBcaOcMbgnM9(LGbGGqffF#|pCm(dO~Y3%g8P;Pw?==sYftmuS5SV+Z+f&eZh( zmHZ2&GDC$(hBLn%4RZE(Z~|sTKZUWOw3R3na+?QoWnW_e1Q3K|dR04ZDMU86(L3Qy zO@R7eiF^~}ksYqJr+`)d9_eM+l7N-O*0d#?CYs)NRLPrEg$IbzDt5*-`98PE<5szp z-4gBPiV2^>Z6cv%-){0*fVrdv5R^i{o(Md!gn@eoGSgw6sNTzJ041wW962;;d;W;DjTx56w2{0I)bT6Jl}Cv`S4wfYq6FTy8{j~>Vv zNC!+zNo&fdR(wIR3&n4y?p$gRfY=Oeo9?`V>Su~uXOC_=$v!6p%5C2Q4otkSi$};y zhHGIOQov-&(E$r{Uyf08@MG+}ow$ zvWr=SL)jNRJkVDv9vPg{j`Ty9ileS&N2xFSgwb8cg}>`gfOe))OE3VOV5E|kNHPmA z?WQh{Ca>Wj-7#YxYpih0A{yP&=@wA2r_VJLKy1nU!X(gvfU{`55eG;;+WW zw3*jED@_af`Lm|giZB)3y$@8dAkqX7rheZSUG&ykIh0^o(7M^Yc!ki}6UO`BMVsMD zI+GblSS4?qcF(OynDqz$^;oTH7Xq}#2zqk(e{FBM5RE`Txy)2tGllFZdSG75IbD)p zd2PBdz%lyS?8Y+({gOyfFXrd-y8T^@9r;UF5`5DuY4v$0)YIf^yqe(Y3vb;-`_CDV z11Pm}w?K=?;gvmqLH|R4su0gxk>Lhe?!nET;AUS${a;xB-exFTuxfVQQ^qLv zC2*6`4mrEGom>kJ*CaHP(9W?6KNX-(EWXL>a|5(S(J8_y%E!4<0{YFj)*0&=`wNc; zEXf3{Tzsb>*(N_iD$#g0<;s;ncTD{4%Eupnb@Adm*&ZZws_;!IJ2TIpq43o~RuOFA zH;Jeid2eQzjRv0)Bt-ZcVTcOQ3|w^kv|XG84uVUJ9)xyG_bcBs{lD>Yb|%xQK-zJN zwkP2&d!pm{&v9D6)<}i{7|1F&f)oHZ=zv*R)!%^>!Pb@5C!d`@&}->_DL+3;%yJvq zXPhzGi~0^x>;|oGT(JwE0WP^~I^Y`&=;=TF)$YZ2f~NIzaCyjYS3V6Xbp}ldEG5vi z;0`rFQ%(mHKp>cmLaP79@CphXS?yoV#@9p4L>u|fTpL-)+#nz&1g7o63wG^)=hVjY z-+OQLn(y2}|5HCPo}oaonWp`NV{!WTR2xmzzu_CED>h}p%}5FJ7xxbeut7XHI%R7I z3r8`}Y&@T1PofA-^G`!Q5w16JQ;TeOR7MaXj>H3U_pZYr$Ipl8kN|lfS-ea|E2LDA zn;HT(IQ-I1GMS74~^avqci8Ebo>LcI;J1*mgd6@hvnaR_Ou&! z$@au-z6Mtxu1&eM=x}t&r%g@?)wF8*t&$RUKdA#sW!ON*_KzMM$A3}Mn&^LghrA)Q z9Kz)QIyjW_6tmBeFaU_?VmO)#e!~mn6+O95{zdosSDwHn>h?bljSR-JsdzM3LJ8!^ z^RHHulK=f24AUdc!caP2PTWw;WvWM@Ui7ar<8r8v6M8CuWcLzaI1lqVZ7E zlZ~efPSbHBDe!N|f9MainuQF&|J26iJl7Ke4tmPb@Tz`!kvCom^ajuU3=}W<4cUu&0`G7jDr)0tZ&&HW*(4%vQ9o+ z*Y*3)$Np&#grd=^Mc<32oh$~+o&qWG@d)ex7xAqjP!XbPoCjCxRt6u7zo#AHmP1SiwPDMiWh~r0BnC^26u8 zbnZ(^sebymzan@6{a_lB(@Dm@skWos(xk3TojUqM$#9&H*ItV*#Vcwa0hSl)PCxlC=szJtx3a0`NHmf! z73mI8s1#|4xGJ_E+T}x08gn;&U?xnL!bjO1es%!3BEFn!I9OW1xQ zUn9WJs^=R{WJ4M~C_6w}V9ph@KYo7qUv+nr0TieEXDk~kL}`CP{ZlHH68^`Z$AG`C zHSG+Y0lc(^3i|9wU(TBjtnxE~s8X&jR^LtR67T7m62XRM8GvROEI-pT=gqa+&;&`x zuzQ5pA=xqJVix|uttO@p_|!$}7=iDJ_`U^Zj3>xsTQ4HlZajBO$Cs{yxM3ItudqLK z-c^85yU?W7Xc@Ezc$X3oQZzF_e~{D9@23AvHh>9C^JkJjJ&Db9dCSo7%cK71em||B zn$>E(W(Vzr?{M&b4uT$Q_1<1qkyt-xp3_i{)7;K1X38}YZ)w-T1<=mk;K9dtb?C@( z5VGCtU~XMp6AeH(yJ7Iu%xDn3<9Ozp4MpPCkvTF5OqfN`25 z(yp_Id-~Eki0>GL`J#1@9F`EkFW#jQ==sP$s(%Rp7VF`3I+%&(tP&MKrHYAv0F6&? z@O-k6vYeVHu-PdEqgK9}p3*tGfHp0}(nUT`B%f3FHx%YmnIzg- zaXiGh3=p5hCfN`(427ne#I1vu6^#8e<8fMF5(997n}lY2(|uI(VE_RUdHxPnJM-Ti z3()9e+^mE12hlcj=}^dMunRP(zaL)+GXmLi%NQ|K=wiESw{=iFYAm|BXr*zWfN{`$G>pwq@{zf=?72e;-S%izygc}V5 z8ac#FESa+c;}e-jmsA2razn`zWiH7-N>U{MsHQ^xx!0>QeEE&3SOCAo;JH4s=nX)E zFoBluARIDAcn?3mdX6G0Crp24#fJokak$FNhVReQQJc4ojEp2v_5i;%d2$rZxX*|F zt?^@lXvhv$>Z!f~D@gb^6Ap(B{!uTLA<=AU5Gr@|6_FFE`@r$@bW}*j#SO2^q=ynC%<&xOI&;+ zy9(B)5dfuhB-;zM>gSU=8FDb@#7L>hKKx*GS5Smkr#dEs6R2?siGJu-dYJJGu>kBt zlX464yvdM23z+9i|F?H01D#fB*iPDwY7mqU93IuC`XA95IZ$g24c7y8@`AkeJq4dP ziixzhv#V=#tjk0><}7*Z*=NT&U)sh9TO)AY-Jq$5e1w$Db+h8EygU0khDiTianFxl zcj-6O8(?KYl|sEL)ewFx|CcDGSDB$eqL$$WMwo(tbpk!4CX5oST^$=%Ue)ml&~W;4 zhjZ7HAnysrD|`D7Qb@W2wXe-D(}stdCmCsDUPN8gf(i0W~PH=VRA8qocsKTn-sNU{kNtJ`X^0}3P*eaPp;_oS>ZtX z0P7!1b+!UlI%)?7h<*osdvbQAT1lt(;{S4ET*mBSiIv)7_P(BLxPZrMW-vQGq%*@9 z5(;^TwQo{<_>BLAq=aiuy#M}gQ?)o=O==+Jq5nQpOz;ze1Ey9FSa53D4c5@2dCIht z|BrWyKA-98Fc_GoV_b*Z6?UE-Hl10RUvPLVKOj+W6y7zeT_N)^mq2g(`0>@ zz<5rT3brp=N@DKK7ytLi{RtwYVX)syo5=t^QY%^ZYR>;_#zTDUee}J;+%OwC3EBYS zwT*lb`a}lf>6EZ#0$_qspg47C(51uyzMRIvat*wPA7=lb`_jWEXa96eKu{xE`bE?; zQ_qHFuuQ6x5Bj=tZ;s-mBJc!-h7kLN0eCi_O_dnKl2N3S0S3S*trvN@4C{@#uw5LJ!PYwW(q7|^hd)pTrNA!vJxzv=0fUKDU z9e?EVfP5LAh`tXebwMMhE*3+_D4Ujb;{^k!2Nhe`#Q_^flT$g33}75V58pR=+f6tH zT-U#FCgm3dWnF2f``CUgzSdv8vPn0?6{HIlqu}5)X5QWNMjk=6Iac{zm_+s0^PV zZVx$zCQp7?F40@5F*|?pN|p2C${Up-*+DASmFSfTru{fOYWmnFqXqE&F%pw?XB;GE z0u&e41dLlk$9w)_EA0XXJJg8jEnwZ56g}jv8#$J4>LO`FryXN_Ih80ZDkY%k`}4P7B>HiG#Q{IEv!y=T9t`3KFC==Y|EB(>|5$*oxFZ2O z7(DFtX7-eaJ(j1C+}m%MpVmdtEJF)U*Y+|`(Dv8Eb>dM*?|U3mh!tV>@j=R*i4t>c zCtU>Fy~}`wVBn9Rf5)vKzL-fca7WNjZw0gdLfMyR4B3y=qq6Xt6Z$IZUvtyin1v3^ z(m8UrLn)C^mgQNq0T`ILQ!T) z=RO+*kUdozpi&;1jZf)RkV`DC*%kdr9F%~zoF)Nd3pO}OPN$lp6BMR10h2&&3PMVF z)m&s>&@{4xHl3XBC>S^VzYYB_31BWJ0I&};4f=HMxh5)bt8n%oNBeb*!2o!VrVHlM zEWcQQd4LzX=r(ooMlHYcLM57r1sI*kjyTC!pH<}$?&=|RG}Gf6gl1Zm3)Ue z7Zqd`#;d|AFsb&xuumzJ-rmh0QTP&fF|$_3ht4$ zJ_xC1;jd&)C@0h*XoS{G=bS^R=;D&956X!5a-vAY(X+ z5_t!ejl^Bj!39plTL&DA+v)`J3d2|V2Z(|R;D90jIR6Mv{xtotxk>=2sa-=;d`LLUel_~uS6EG)Qez_VZtz9E9++7>=PX03Bw+9hdEZ1xBs|Jm{!YJ1H z7aYugNB^rUXUuqY?W?MQSiDq$F_l7fv6YHD_`eEf<#RSL-j z==@`f+2kBT1-wRGvG$NY2*$a-FvKA<+~vvu+2h)#SU*z9YyedY$V(}O#rn4oc4lMM zOqk0z(JX|GPV7SEB`NLtkUFZ{W!Nn|*uwyrsyhxNgar*OjfL+PErK z=~rq*%>iRAx@iJ=HrE(&$7}dh&?n@gie~m}*L#l)wy zaNmQKch9Hse_`Uk^s)aBy!>T{{uct`&~BQo(6+#Y#|-@{;QTgdyB%DJ6CJ6f08Vgk z7yYLp{FQQCN&krt)~uXEhQnrWZu919 zXVOvso2~w1SirW&SNH7sgTpz`VXLn~q>%k@3>+zZvz<6#LpW(?yh{e`qBF4JNY)(2 zR3}&t{p6sLCi>nT-_do)V;p@Sn?Qzp2mJrwtbgnO1K*hl*Vq_Qa{2#Xzg+I2N8V8X z2dKaJ;MpFO^!2lS_Q z@E>ve)(?9fj~A2+Qh{3jK^y(wzI8AeBO$12S>a}4pp-eR_IQEh-nh}KY%R$VZ3Q>n zzL7m4*WWt!ItLuAecq&;0H>FvlBhB|4|5&;&o?OR3Hv}SnC0rf$&!4MfKNZY_;Fku zqkt)P8Jx@?xLCU2q`DP+Gs%`Vs#UfHY=F`ew{?+^G@H}LspogBJHEtpUN*L>Nek3w zU?Q{|Hs08c{R{j@AQ8ygm0A_-hfMi!*0wv7*#GoD1sH*}_KdC)WWQq+IYdgol+y{)B54E(@y0@#ErXcD8Xu#h3U7?t zf5`t+7J$0R?B2Hq195}GV`oW0;vW=5D%G)90qG^BYK#laiv`A$%8^LZKHBl|^GA1W zWUVksStV^#=r&(4fu*v#|EixNzfiQ43S~e)E|km8@Iawt2TcBByT4Wo*@aTQG~$#S zhb?=cMEJ9k-s>05to1nkDoW+0PCZNJytP*9tpiOjOU$^ZNRv@-KItm-6qCVPLHz`Z zK3;ombg`ii%m@U)eOSND!P0Y=k^+zR8|&!Ww^m>~<8Ui;-w;9!?d7go46Fibeu025 zcdeN?hH*KzU&jnN#DD+!ngBGtX+n=EI88sVp553@|5JP%fo3R4lg~tyGd@{>B~P?v z@*n-_R-is)57&zx;GYwT!?{8!pEvuTZmiQVE0BYl1QBlb#D~Xsu@fguH%v*6td@Ji zY?E=v;^T9J>A|h%7)17j41sa=f7W*u0K)%?>q{Sxtemm(SN~0wZ);^80a?QY0jwbK zyLswcKxy@c4KgYh$PmC4#xcM(ga7UGcOB=f!T@z1)Y{_=;n;$y%DePme<+^Lq_U-Y z*<+LBWp6H&%77jy|C83ht-cYfC`ZM;>{2 z>8pz$U-?@kAEI9lP(weUR=~fRy5PsDJUz&gi)Ql~yBB8DHu!hXCtqA=ULA*wXIiO} zFoIIZp}#Ypj8#jaP=%(C4*bM>^Wi& zG@`Yn6`SJM&NuQzIlahH_oOlB_!=y`6BGXOJMg)@+|UoyG1WHYTHSH2=0oq4B4GlU z$Sy8^2{-6BXhK3$XYIK_Q&KA*LD#5{DgJ-re{BZ&T%bPt6#Ns>9HW(g)IpCyEx)`B z|H1S3Pon$uk|og3ifIBEHnz$}_CMVZJ3&8QN8oODGJq3f0-wPa9dH>Di7_7Q;?vv?juJ_+ZqWn(RU+VhZU;geI zIT+Xyda`@{o9C}xp$rX4KVu5>Ld(Cg+uu!%SBMP1G?l%a@5%kQt%NTe!2SmtqgflI zHrguE`Oi~|>;VJP!cLeHkmJL+7pd%&`OArC&WZ(N9a2A|2a)~;j!-8wJhkFg=7VgW z4!lA9!B__$V_>mS`|`)%6<8@5@RI&Zjk`zgt_vU82K>#J{x4Mn{6uHN(>S^y3ICAv zAqs9VBER#y#~xEgKUNatBNG18=Q9Cw?qbw-}wImgDINAdcsZ}=J#H|$LGnEq5;l-#FY4VO`*)G<0m11t%}q-x;k)l zA5@*yIN{6$-VesdR}dFeB1Qa{ks7ql%fI_wDgcxLe-2pkCcFn+EA%hL`weIh`Ty$v zOIu7AvxM~@ebRJ(!jgUr>K}XTFaPo}=;wLv^D%<{!{_f}0SzI9byuZWfdu$$zo`ZsD!u~-hjKKh=RqHGYJcR5I1myY$)JTS; zUjh7HC=4XGku(S2rOJAObY=bkTf#XSnFpLO+ll-iX;KmZ=zT3q@IQV2GpZTE`z80M zoR*3acgNB3gW#VL)gtf7XAL-3;#kXS<>7zmNB@I{Q?h)+B>9q=Gru1W}Fh{5UyPbk#KZk5c#Id3YajmjD|SZxnJsIVWHL^A6E zEaY&Hg-^FfzU2o3u$xCByurm1`q|XwGdenmahT*8c!{9bbbaO!NI0G&;s5FRCpK|v z!wTAnZ&tWbz@1DO-_`a;94cR+srh_oe%JK9`|hJ`E){(nbIbOx}2{G{$X=bicU-ADiaUH*@+8Q<>>$b579@AdeP;-Fu}Qn93k|KBM)Q8>UZ+My)z&o5H| z2{N+3RHRG!k)4U0 zUv1sWADI^~YRa%_0e*u>^=x|pTp@sJz-tlpOa{=GX_dJpB z+^3n>3`I}phx)BvsL#EAWd`N`s(0(ch2dHtW_y5t%Vs@5-`M3)E8EJ(S%2&w48Xjd zP8SM^l%TQ0M}l>q_X|DU@dM|7|9}7EkAM6{rI2s z;-lNX_cwp@y}!{9KlRZ^AMx?M+xP|laoa~R|J8oKFgW3B5$rDZDQaDknHp_+z6^fq zQ=!180)bC`^r=q;24kP%7P`;h@YIh2+&G|T|BZ(8(MKA{kM&eDA|9)Mx{XKQb{qf4 zXI-amb>y{9Kr$Y%?!P`H+l92;;P>VTYLG>-j0zke$LU`cy8Sz28#9w~dv5nny> zh0peE9bDxIG{xUb_W+uQb`nA*fh?|WSpn23=P7@GDo$gGzu-0D1%C{faln+QG~>7# zqo_QYtps9M$3ySN1;r-RFCeq%`#MgnAgY#MeDNvTmoI;z{pzc4x#epAyWEYOqyQ5@ z+H#5qwscc`m@%HGMy7*21vb>$1=>3Y%`gGDiUa1fIn8HK)ITx zgIgfPCmVSb5Hr+af8+b*O9sii^$xj-{ZF`gI=PvV`ufSdV4)xVAPEOZVO(#fdL z6KOT9Pz)3(CspYc|M#$3ovEQ{wq>P~Ivy1uzt{JLy>_%&$PTumRjR}6Xsu=!Qe;q9 zE43(dFp{b@v&2o)Bak18F)s3`Sg|CAR;X9`*1dyfI3XsB(?{}MT~N=(O!%SPe5X&m z^81;Rxc(%ROeI5sq-ctTP+GMV6vx%UfCcu$3xhFOu|MVyw8&e@w`z2+O$L%J;JpSz z$!hJ`U_J`eQ*|hLtkoKn)E`XNJ=OO4&XiC*87?M=Ja{+lLa35VwmZ;|Z5$&xCRJ$o zLIHv!&i2FeJ5!$-h$bN|l^UuHrJ~hzYbZ1n2+$Zdl>#k4l}^QDL#Y7o>GZKyEtyJX z`P_a_=bn4+T}=ga z^EL3CNKa<7`Fy3842)E(H9#weKGPzv{oc{QyB!oBnL09?Kr~1^>*q zu($Y`a-@}tR?_*ARw_w&EKKVNl}I$1guoDd&XR_B2}cT7jq#;PBH$-OyyWTpWQc(! z;nG2tQftXhdiUMfE3Z8D+*5!3%DeCS-%SRddhXrl_yC)QZ=OqXLJ5n%W1&E6Xe1rA zfaqoiWD7Rj#_IAs%oq_1n$=cRnm^PDmmw5jJ;uq)01FUE#?ymC#dHWU0S9S%lJ=@V z`~2`{OGh>j4f+O}gC0+Dpd1nZf4RGVFxtZ3T`c$_`9|X*YoXuwnPAwq1d=`+ZMACI zYOxx&vsD_#rqZoww3!Tq(&0iSl^&v@7{IaN7QIE7{ZOmb8iD+5xEhP4hnNI$P#~Jm z#sb-75(1MUI6GT>Di*q$z0Br}#n>C65a?vtBy@+8HKu{GR3Nb`+`cgTg_0+4 z2Q&94g5^@#N_HChfkp@w^3__UoC@sO-dyPSZXYPwcGFi6N9Yn;pc_y)-AZRcj|w*d z$v_y8I#{f>0wc9*mCmWifI&KFX$(V!=18lR96@Y_DYk(vn4okkTLW*Bwv(%~_*zr> zVltPWqsC#ca@rTB9=blz3KohW{1+q9 z5cJdk7SDLxu7>iCQ!8(8E$qDh&pg#kwP;fjY(>J=8lmFWP$~<#BY_d<2RqQtR9Vgx z4Da_d`OR=NO!vf*YC3-`n~a7>!d0>>v*N@U>9wI`xR9>a;Fv-h2~vceV4mb)GMUfk zDNIDaK)ghLG&)p_GP7i(6~pjVB#L~A(y%kkbfs%7b8Q3$CtNX9Ll31|R-{s4rH8U< zo=_c0XDMWgW-CP^8bj$M43my>3#3pjRQ#7<`@+EXfqcVPXe9<}kwn%n`nx-;wGi#l zG6T_p&-C`B_B`atq|>3Om5CI?b~;kbXKSh+C`RlmeN!UgN>%$hHq<&ck_JS0s5M0K zWGY)bmTIO^eEC8lObSi7NwxXr(oRh)rda zDJB@!YDHTZ>nvcnS&g)^;cU1WEi&;)!B!e(jIz8fup9%u?5-3tFG2xl3nmDUz&e95 z(l^qu6rv*#ZRPXPJRKfGQTuxDU{B|EZ((yI<~xkDH!b@6yZcl5P^s>>8o__*-jD~&zdISFq+9P|u&y_|NF$Uo@sYRmHonJ+PhQR50^{o0@+upL<7ZA zhACj@rs)xi=uIOK$eXHr`fRJpfe}AZlvXlUp)i~&mHLJWAr13GyXIKYbfjj{R4$SQ zOsl~5h=%E}S{jLfzT>Hv?0gI~@@9r6JSb?kGg6>hVGpG<02EcSRXb64>ZL*3E;TUN5`Zx2~tf= z!Gfwo>6Vk}^W=tyX&V)>9MNC0hBJ*}r_{&|*iOBWNl;_cppLZg|IlkJL4iHZl|6+@ zH04hf*~AzH`D`=*d%-j?l2t6i*?Gb;^xv}KVod0?<@8aF*>LLFYKgD~yl3BEv@1<& zl>@B;Vf%ExiK0&MN6Y}uEz0@a8P4OFrTPx{D|P7fXe(i+0n`OA@Lw6EO`#g5JCpmzY?4$9KH@&+kH}f0uo=l) zM7v}X1G!Q$pXYb{z^>eY3@e07;)KHw4fgbGf2f?yXI96B|In_gpkGc|*pqzduxA)X zbu2he*>KDsRRY9IGXv1$$$M~+!0LT)#Bh}Qx$1Dl=kwK_VMlH=PoK68bK?+UXR4xh zvx0blH8OAvyV6N`D6XZ!IvI9-M_8T&Dyxv;`&BK`!Al$}hez!Z>#l;e*{Mt3}Y zee|Vv?!VvZD>XCVbY$#mUj`Y#X7^CG3jIuOU)?j1a}vXe0!Mq9JqbIRtrZH?az|9%}yWfmJ+pyZ`TY)`pNCqTL(BgUZr8yo9YNuSrUz!>2W0mPGRVXsv1^`M?yN_Jj7KJuIE{a;af$PPW zs3-V4$I3U;*+QBdnGL{w5u2jSLsx2#l5vW7>a0F6naYGCXv)h@I8ux@6J>Sj)_*CH zjct=>x@;O3depw1S+Po)YHLtX|1gc!WMLc#z$&kx!mA`YSIgV0TYDb*$``!#kkSAB z(F4N^wyht;8zB*8So8opw5HoJ`EXt6ph)hrDUn<>%e2RPotHYj@r z5YJ6{P!mq6!lKl1s@X@h@OajPPQyFkX)t|-NFEt(Wdck#|5-wMv)%|9Ixv!hp36AC zJw7X#$QJ4erXvR=1-#Hm(6cGxOEf(6sGv}fT@$rzd^W6x<>YceH?uj5(E{7dI&vh! zD6K%aSV~aOUP;AM$z;OGTXw$a-5%K5<9#R?XczrG{_huh+6Nv26dz!Gi`-wwDL^y- z4ezlLN;ZY!MXjk|&XARyhAO8mt?xBKiVrk;sepvVIv0W_IWj zYo>&KP8SX41omw37Y(J>_*jY{y3^BOcHl@jI|_vm%Zf2x>Pt!#+}T(JtT_E{(12EOu;x3?$#*^25Pzvo}rUf%9Qa_THa0c0a{Lx~1S zY(J;Pur2rR`@2RIWp(B>e6IyV4EATR;b9Ps6k zsN6*|&e!mI-~?)KJ!O)R*c5%9I*a1IW5+dNdx!Q6cwp(mQU{}zI($^vu+y*xXieea zpS?N$U+^W;m?iL=XI*&XjKsZ;2UPJ27o=XYth0(zW$!xDY)7fZr%KqT&Z4QqZEXVhdqf{ z;?xXAE)U@cR1C9!`&cpd0UyW(gp^j8Od>eYj0Es}Ae0bOIU38@g{IX<77>H4j=oVvHmVrTS)mkIJ{h8LNsNk_m=~G4y!pz)YSJ zHaM$MuVeYb`ppdSnzF}AVCcc4t#jvbKBCA{Jd}=5hPFFdTak#MSfI@4p(I6YE*J{}H z26&-X6H}1sKt1vYaHx+Q3W-9@FaYLYfz6w}n}aMHEAR6%cT52+j;RC|X{GA=M>r6M znJ}k5%oe5yg_UHIaKa<_fn^@H!y&M0v2r~bjt})Z`nKMrUtzP*Y+^5ww_!zxBTybY!BPj+Q=Y<&4aB}9)}8^ml_dIRviPNnb)7JUS0Ttw}0XM`7h>I?LF|zy;G*_ zJuqeO-UGU(aODo-DJ3>Dg&>u{h;>+nz_pWN> z^gpY3Ic1f3ckjiG^;dk#P z2D60-(oeVzqh>QsIpAX?2O5y#J8*z~(cmR7_|iBqMK2FbS=E^GOH1poXp{S4zWGl+ z>2J(+`o*aq{F|?*et+ugzxnmQ`quo-zx%^~_k(}+KmXr+bNU&=S~_!`nSnDiaApS1 z%)pr$I5PuhX5h>WoSA_$GjL`G&dk7>88|ZoXJ+8c44j#PGc#~z2F}dDnHe}U17~L7 z%nY2Ffip93W(Lm8z?m61GXwwso`K65{+C6`RakT z#23HccHtGDZJV*=p0@OBzia!0mw(fC)v}#!b9(yQKKq3)x6OO;|8D#2FaNo1>3zG} zuK%-dw*5ij-nQhL=i9Dr{$tzR@Be+gc?r6K< zvUzP+-tth}qEfl7`)hyEcI6*^qb)G+_O_Xy+tfB^_?K-ruD`D>_1})P6?Y7`eQxuE zZIRD^scpr#zSH)Z{D!vcM*nx)wRb9)mxdT-mp;>NaB+rQg(`Hf$0n{nN`w&>IUz3orF`D9!7|I6OH_%(HH`=d)9Mlpy+ zlNg8*F(`p3h7f@S2m}Nq5fTLDErIY#N+@@T$7iSyd1 zrCVC4(7X!DE8ai_U+$;4Vht6Nt)~<{gJ{2%3Mjci`2o)h-ff^XmG4uYrmv_OTh3D{ z=!0u)Jr%KH9VJ`#2^9s{>F<9?sa9{KJQvkd+1n0M!M(pxTHrM7=C9O(6>F&!v^OI> zg_>W{MJWrbsTqqJDbbPdDCNp^)Z%s9sFb=r!1;&hE9Nn?mCD-oG36e+fm#Y2c_~*@ zJ~^LI-XHZ+Np&V_c3d8nxT%>6|L!&A`{{jZ*7hzcbK6Ih=fW(?H8`6}s%fG;(_5&B zWoxO>l{M6y4|^!zWgS$=ijS#TakZ5E#;=sRrkN6F9iYNiwNrERj!Z%3s$^1!LY*49!$f&KfFp%ZF6V`VXi@ z8=I+_3o@u|%yC5NX7u|bYANQ=bIEqfH+?JRhilR{@1xw}n<(9mgOns4G>~qh5^DES z0orZU!c`lnSs!#$!OJ&LzPXs|h<7Q^#f`vqE9D(iLTQ21sCU*=aqF9?fGho!aPbyO zar-yQVf-XYqH6)(H&Wp}zf!EZaTxO^N`ZOzKl6Z^lY5kkey56xTK*oD`Tl-Nmb{)y ztlJA3+DIki|I~SlDJPzoq6;)saN#jZa`Y~hy1A7aH$8+}h&44MY&jL4qo=aAeoW#4cG6fHE{PpkchyVS?`t|?5{Pi>W;s@&={#y_7 z!~Zn#KX0Z0^6lG+*Q26hqMF$AqN1KWiHVAN@+2yz3E#v#iHc%J#l%EK;YYl~cR6^^ z?r&nV`z1|H_!8gd??C($ALjBz6*PSB;W{;6Iy<7fFAJgvYbPPCvVTo}6cgGw@poTOtYJ+wo8z zDul-ik=WVc5n>mD6GB2HO=tzD@#G=sCA$fihJ>KY{pcN=jdo-3j~&u)$7{l;^EsOn zZRhe4*<(bhM&-@6GBq0F9maxe? zHt8YGCH=ywA$Dp$Uye&c`XwPeK01eU`g!;nCrhlo#BV%1;p!$8H^=tL(bP z;puwY?Jy3B9iPvWpi#cOpQo1dg?g@vtG45-<@@Aven=B~ferx&AvlGP zuZ4CJ9^VY;5?%-!LqMZ=Cz15aB^Wij6C&5Qqu)H9TD>~aG>ZS7ZA{4dOSY?NXj|Vd zm+Sa;YCS)MFW1R+YK(y=x3lA85_o*MTpzK7t5WSF0|vHudUQc9e}t3xJT-=9r^cK} z_`Hw^Ihi%N8q)*ZVZ=OjyH1Y*$@zHl&`;#*CLos@W5f`;wv z_OPIx0ntg3eEsN>!-xEP9_^&qHT^`$G!Stjz?Uw zN~PB^RH9y$UTrWWi;{cIY7tkb=E);OI<82pGl{y42GNo_RF&ae>+0&F(YPwTK7y}* zRHxsCFYENzR7+5<=deu3pozo=k-nE9N~VeQDsC^0#^=d}I3cnO5grSz9gCR^5wP9mb`qq z4q6xRSx38eZOK0Wb*pgr*8%9uYsveTe73J{ANj(6mH$_DOZ10192zd6sW9qZ8iT=2 zrjhy6(L@FYgT{zsvA6}RbJohVj5w`9k~k$t&TnU^3{IoweLPBq6Bvi%7|9$PbU0bA zBaH}?^?I&|LE~Oa7Sk54TL(z~U-^IW>d?Z^cA-0lXt(c*ZCQxf|nay3^J#~9UQ9Hlh@$wpS3 z%w#gk3}P8-{6?6CT%HKiB35(imUOLpwaS0~eE<2t!n$1tcFA^i$##7K_~a}9SF2Wi zcI^>IE>0G4l0&!*njQqOpTQ6t4KkyVVPMdN3{HXQ$y%X|M(a&B3njKwaza!DO*TfG zQIhlIj@5hjez@1;CzH)jI6m~)yL$Cc9v-V#+nB_w*Ltj7yYSE#UvB^MojvQ*k2vA8 z2YDP`H-GWsFMq>#bK^+WtJPwYY4vK4wLe|`c(2FapMHvqyDDD&;p)|UKgQGJkEjBM zD9)gbGni<0wzf|sJiVU5aMBhqoWK;pU?mbZ_%OR492#%H=?OP)Y69<$>FD_HpFhfY z$18NA!(7i#I>-+EsZ%?C{PCm38D7)29a}Tula7uUh>*9J5Xr$NoSxkj1GWpUj!#c= zXzfOkjG<*1l6(1ywlO>%sM1DjGHN+afyEV;d&SPqE8NS1gM*)ApV+WM;ohl<76=sH zweG_k^L>|Jd1ueGZ4O6TJYB+Y7Xtc2ms69*UtIiK=(f=<)S8Wo;b%(a1$Xya_u4bT z&x3>Ap6?hI4C5Z?D=e1ZD=I9Oz+T+!KqWGmOa=qtKRG%(ols;GS0H0?f3jGdQ-YeE zn-7-OXliPrqw&;O@1cQz7oI;?eqA5tI4N{u`e=L9*FJs9*CpJgJKXU~+L-NIw%vp_ zf5e4OZ;USNJl@#YNWXv~1V49sUhZDI!`*eLxVXBS$s8OsOXRpyCc`GqKr`B5{>?lQ zS1hwB(8~121WU1{IB<|zJWyJb87;u=d^3j?nVL>bXQx0}>#o?Cf7*BX#B`q{q`vop z8K-81hle@dnK@?hI}@{8T3V=zk@o^F3@+}3g9PMr!rb!x`h@fXKrO!L`Fj??spPQWf1Rwz-YkQ~9ms8k@hpP8unN@+-4rGFG zG=QBcz@G*)+SnKt7ItF>Fff<$B!}bjNdUj{%TOQk$%P(Ucrw3Msl>FCnYSM9(Z{O- zf&zj9djhMfFa^y17zt0|c9am+fX$=f+zb)=rqZaiV4J?_7p}JI6b-ArA z6&(PvFb6HA!?oq^?!nKMZVE+txqJPvps%yR1s!nweDqBMayr5O%8d2XQLOJstW;Vu zEVbeaFPOW`Oz$_r_e(8I)Q84!@X8EquK0ITh)yk+8RKl?j8V2z5+!n>N@kSp=Oo*m z$KE#USt&!7=H`@?fT5i=HJaga?{YMT>o`mpp z9FvyCGB7}Y;J>|QuGVBD5{0M&oSmzf6->;RbD*=Oxwyi)x<)We3gv+lW-5lghc$hg z&c~R8*6_LZ_AU0=4(Sd@JUv@lzzYitI~CrTsNqb3clmH9R?YCad(IY1MTK**GuR60 zfwRRqDzQI=s}_lpSt>3M^lzu*bHyfB9EZVE`2|?+VXDZP_^S%6us9Fx)PS7I72e<~ zJ3s-M`I^31`svp28KbkOA3>#lLWlOJLHj4A`On`xuO)*IR$j==>>NJsJY;b$W)51L z0~&fP&OrfDITDFZ$1th51`+5l3Q8W0W@FKJ1N~~^jv$?qxAG_J>C7Vp|4L$_|2POyuK+bb61=r-6v!h zSd|L80`Ip3`31~-0tR4a7(~!(%(hdSn(XAZK$BbK1#l#XIw1{J9XeU@9 z)?p@ufK;Q&mlno8Jl*Oz>B^P#>^0UhW2ahOx?@k4lnjI60sNacwQrPV7tU4Ry9``b z4HA}G6-Z>;(7-_BJlG(~B9Tq9N+ieq;GRfyat2KtR}h!1J|CRv958gRsv0O890cO3 z0)c>_p$&xpU_vtq53W`GLs}Wzy8O<_$atZ?2*h7Xy7ZuDt1j~gD|APYYu)FE%&qNGLRZjtHF^j7SsEh{_Y zzJmzu@(7JIjtBV#IVV`~up|^W_keyu5d#}AdO>GqXLMmh*o_-ur>tx@V?9JZp}r$WTA>NV z#^$4kCFSLq1-EmSihI>ngMn>iCaXZxsrM`azeA#RM#Zr0_)zghTxj}=W&pA_BF6jJsVt>C~yN+R?!K_G} zg5}TP+Q^Jhy|0}||A)Ohhy1V(nLRzs9`H@F5}Q-*Iq$4JbLPTxrLw&Kq|5RvBWa5> z)@LUr-AW?7r=`W-KHTMDWvoE)OnC-t;9PYTVdc1#-1vqF-khrt23*cvnOWgC5M*giXl`yMEHe<&&@wc%p?rro7;!%R#`3o^ z@AHrl>+ zi#aqo@Xs@g+Qr)avSg8P_Ad~cSiXu)egV!F2x78$0JZoEylX9&IAu7 zjB#F!M6Fk;82b$>hKP(G_90EIwTWX0Npa;jWjISy?H3T#T!q<7EpBd3umn~GGTQ<- zxGSFhqtbErNZQKnd%j<@CT~G^cQ+Kk(b+HZ*5Hszp&~@nT>}ylEO_7vT@Ev!666=@ z+}K$IH419XyeDjaNIO(MMx2UE#?Ncln`L?$r`J3i8e1)<<~3y*Bd933H6CnHnY{ehq(rs6RS%%8#Clxex~*e z$gC7oP+ZI;G}r^h5u7_EA;>kh(edo~v@iF3|1IG=Cr?UGN*{*#&V3PY9Nr-CfvF;?iRhz zHP?a@+py@`fIBRos=%QES8oO6H&mh>%Gz4+U$|@3DjJK%hy1+`Zwu`HWE*j>{sCz3 zd9a(?FGO<-b`2P+s4l(SRt-kz>NH z$QmMvT!X;y!E>y!(X=qfTf$WwV42VXTTP5HZvb z-UNe%m%kyMPzK*$;pdD+4Blx4Uy3@1%!G@PSHARG|2bIBk=V-0d}&F3EKGv46Md#H z072U4Hur#L+e%AaCl6XI&6eh%06$mAO#)w&3C-xu8_YjO%ryuZGMzASNl@2CEF1-j-$DZ)q*oMOV{CcSr4B_my z(MPBw_V&|r52h3izMU{;LbJ0oDBracVgvJkANTY81(=-&{gZFzCW{ON|F&@T!T!Qd ze}ho?gDS`6@Eh%&>jH4w3HBGYF2J;9*TmJxh^Rw5p0w~-t^JK>GSri;)EtcU==6~u_s6gJSKA-tu8yUm08AvD-P;4tLS|6|yEb1%mzlZiP?{!rBJ zPzJ+pbtCpe?R|H20Gt?NoPY)wNM$D6#SJcs9&aouIr$H8if5QE<+F`ghYdvs?~c9O z(?hfkP)gh7)ESS!UC9O}6ikLhvXk zIZ_xM5M;{Q3m4vO7znUb6Vs(_5Q03l$8tC8MC4s!ddF&@ab`*t3TX)x!n=_uI@VkS zo?8k7>Rw^34mVCBkb4f{kZG8#E+_T!RVQvd*p~WkALMIGtyL`Et*_K)gkuu0^zI!k$ z44wyJBKzDfpxrZwRD|5N8?{eQ8VK>4W9~Pe6 z=>1HQh){vNm&=gRR3aVdkH_cISO>aZzMMaQ>ZD0$|E^$rcGB79j=qhLJEfV5vU5X2 z&Q(=dh?ki~DJfY8b0fzregFL{Lh zbGvciMBf|qSZRG?&J%XKoW_dNnmNG#laL5CLwwk{@QeAMd@?eAWQ6Raw;oq^Pg?Fv zhlEkomem9dz=2a-U6oK&ba!ml%%w{|_~6q|)5v)zKKS5$bl}9@th+r$2@sSi;5q|4 z`x+X3&q7s5n@QTlD{1aVV{ATH4qLB!#4=z7>S6z|&6s}EfrVfAdwF?n*|G=6mMyqL z-`I;@fXu%$@t8)N1mbSDk&!crCJ2f2dgh5NfdAba4jZW^Z26T8ucvd-#-dX* zX24bGm^b&ukp)Rfwo|7{dEiteT{A-uL|NK@*Xi`>H?i8GR;p4{L z8aHd!*6=X6HHiq@nR_wvB1TVKF0jW02C6h=bY37aPccy)B zPqf6=Q!~)ospY$U-kQr(ziSFniQ%FL{u6B>jjvscpqc)4=+GBaCyk#r@$)0(<}@>A zxO8{7PM;1xujj4Gld<$dO-V_9O%N8|dy6rvBPW5uwpuH*c98i{QY?=zudBoINUJZ zceAp_LL4uB9}fBHutn`3my|<&zVN*4zCfA@<-8A0DVG_94~-eK*lVJ7XrD|)u$H&g0NPm$sLtgZ~HG7*{2>Dd>`|`vT(!{A_aCDJ=T1aJZNEJVj~hmIW}b3m?bE(&2dk zi5>xOT5tmJ?~d*1c?&=Ni06V9s{7&NPEBDn{G@aU|I??);K77}vg`$*V~Pr+1HM`w zLEv)$-lKN$#$5{!t;71mM9#IsKXv1Dc=*{n_=2!7&)AdsQmF>>KMCVU7eQ+$ zpl{+Bd)GStbj-<`HL;bDm-OSu=}`6PVL;!^ix~SBK(`(bL5{X0ti(R^*6tRO8@>_v z?|-^yqE8+;&{h{LRDo1e6Aeu>Yy||+7%OyQE#A82;?n)_Vg7d=@IUYmi&?s>R{Cp~ z^J!dD7ZxDaUmBL5Cy8Vbmeu_b#^#=7a|wLG*E`^YESLID`T(a)AYXy{K>%aN68ii5 zvM`s&g$P#_V)%#@jmM(PnD#kgI^)JUI)>3*!W!td9Zg6DV92y8kqqO1A`zNJLYi1c z@PBqZrW>~WxLe?UE~mqRKd@SmZTZ(VgCHzsyOg|PXw1KPu~Uc`T+V1D{?{)|UkyG;`+CPv843 zG(8(mC@R+_KYzGhs)^43hYR9jL;!+#sUwIJ5%`YF9UW~y`Hn4VXK85+8ck^Bf6)J& z#5TKD9RmLU=061gWbIgE8}{~Eki;JoAj{0~0O2>sr=ye|4} zK#-(R6W!1N?FTx_MB<(!vMfB@g$`}hafNM1;#X`t79zmCdidXRqIBvdG!y5*u0wyp zw?;M~GBJN?7Z-C-N!2|K-V=j_i@JL>EtSn)D(FYJ#dw(t?BOV(wx zYnOi%*5A`(#Fw)OlnVS^TGaPK4jN32bv44?~E`0z+T2S|bv z>{oF=*bScGS||YE6nVJZr5o_2|MZ=7WqZb+r^nWOQYU{Tx@I)MuTX31{8FP))g1QxfKT7WyfHKLc!Z1YDQ|>c|&U?e^)#LL+0p82V>a z6qhD8I@v5-<^SU+X=z^T-v(DnToG!3Tn*c%=g z>q9hAjQ*YVR#g-XAq6p;A-{m*C4zc-n6K~XY{;aRBLqC)6RnK`;--ew?Gw{%5P#4? z|7EMMu@0DQ{^dW_>m9Ex-)B$QN|;Ohv29P6WfM*`4(4ND$?*WrrrfQx)J4w7_Z%&Q!3_|JC=SlL+bmbs((c>G|$y7ng?o;l_a6T!hZxQ0p0sxFE#?pdd_uc725X)P&fQPPB@3GmM(jZ@f8m9Tjd zj$A0FaTrAY>m&3cn}P$^){VwWCkN5ma6p{8oQB$=(QL>a2mtXBFASVpJR_IaSt3H9DEKSFwi9IlN@ ztfB$`a+SWz;N&D*^76CIeGebTYV!NQXd!O%D`OwV!gufDk>P;joiqry9rDf|KtIeC5hk%>@0ic4TpKYbhsYggc39=Er-u45xE%r zUXIE}gd``Tf3)i&I8IK74;VRr0IpP;Uzq=x-j{zeKfkX}P}14C0={r(cv6`dUmJ1i z7Nx)eL$5EXgpSr77VZ-JFf0r17vlQC@ZtBW3M7#}zYW8~$_ur%%G!G9LsD|U6Ik*D z?msz)mdp~-3?%*&qEf46PEM@P4lMaYT3?UgbqVRFw7ypP40c!T26(_oAOR1|E})OS zn-zKR1{6y;e;(37WI8Z=uncy>g;iU=W5@7DsYY5^*%w<_ zSX1~U#*QuTGBUI*gNVoHuoa-$WAdFbM0#5i%a6A$4 z@Gdan`+*I(oXBy4HH<7DrDY{XdGUT_yU3uXRpd#?17$?Jt3<=)d3nsoN;@>6i_&?mzKbs0S+?pIeh3acz|z`81SC?G({@RgW?+Bfh&L*Zk< z0c3>#1@@PYX3!RBO=6Ym!5efH7(fq#gD+eN-T;?D3th$p2Aml zBkW;A>A{2^I0>!iwqZ6dS5>0}Wu!$C)Ubv(=0zd?(+=TJ6Ej$dKicWw4A456Sj7Kb zi_{4?J{1V}XO`v$1PmpR(AQuaIsm3p4Da*VJ6@sdCr*6&bp6w1-@{dN%m*GIxPTme zZ#>+X@0yZO3?DQ+(5XxWfr=6P3J7q$?_T!iISFm-*x`-%M?WI|3>JfB*v~*+Rz&|< zCZkhFcA2B zonFK;I)MYJ&Vy6ABX7kT|4c#r67EKl4Fb*EA z7WB_+7YPkC7RQ*(olVkwkY}U$9Rcu)s=?+2@EkZj6G-Y(#Rg^Bj`HF1la;3(C&5iL zofx!`e#Esj32qXEpX~EW>JdBGfGHp|Pz6F9MCY4R5PYxB1YW@bF#aZ_L8}dNgdpI5 ziQ)+vEE>vAn^@*cB+IG1oW#F@Z^#;?jKSTX;EV*Cpbg$g!YV-m1{7(SX;!y{=U-j| zxVlEKiH~2jsJ84mqBlE{>XKrq0u`o~5}$2g!ceZ?@100tDZhVz-V} zJH!n8hZQI080?M$x_5b}GYP+wI1Z*hflPqKQjF-gpqymiz^4Kq$d+YqZBV!gk$*Un z7W%!_N}VMI+r|iXI$J;jRXtS+OiUpfsvz-yWG~zwcDLpq=z3W)B*?0){71)Sp*JiB z_Y&fSnXobfhHy0kzes@q77#%W3fe$aa0LV@v=aCLwoLR{Gj0({0feFq-P&v0kz4S; z-J+A2AOr_)z8C~`4M{XTh~oG3Sc>73cRq(E%1QnOQoM}}5pu1G{cq+njI6a<6Qlh+ zlH33u;g)*{+zwVDeF1Y&0ey0(yF1~EZs5x0^{0rL>|jrn#a6g?0RGD@J|rYKp}V2) zBv>fYwRR$IcMlP>HiWJ~gGeT-t_b-3K3F^QzvOC`%4o!bPe%MH1UdCAC?Hx!#HCCD z^lT(y5&G>RaYw9T=rTh)hsz-s03SJ^%5o$?z>InUpX=*Z*r+3E+mU~`0E|fLLNf43 zx~X^hPG~K_;M+DZiB*IZ|9&6vpY+RBG!=`pUn@fXBfDQGR5_Un3RE2K`C$TnD6qI1 znoepUp3LHENkb4j4!*cwkyBtelJ98JDPY0Z2+ z6a9Nd6%k)ZCBy?$N)jOkcFube#WU;n!}(|6BL0%Y=bE`TPBud~kEutN{XElb09Y!WEB9kZ!pDhM##OX|a~1 zK_UID!h#`K^S|y@2mW4tZ)gDdXCZc&aVMI{$Uy#ej9oiT#V~0L3=H0RzaUF-6=)B$ zMNo$1Gt2Lp_pvGw5G|{9f1`94Z0xi80O2M9`+xl!es?PxU;}ub?(UA2ZXDh*OyEP+ za*wt+qyLZr$o>kfW>#!M0@?ub-|RSghM1wHk^I*vHJ4#9tu1iU8uuLyvJ7FlLuyyw z1Ib#3Ab>a2&}+ysOp@Tr%AUb8!2EkXb$Ahv4ur$GKI7CHd;0|l$lJRhB;F?|f1`X8 zO!&AWbLS9AJq-$K4oa!OYTktW*PwqtLBbou#wIS#$kN%`CfeyaVy%-_D`v>ggKHE+ z-MYL9*`N2oxPzPd25nD zfce9<$bk#4Evqea7j!lvZG@!r5pIOFY{4pQ!uZ>TGLsetARGCwdL;kGIUUy8uoy?N z=)m_br``*!n%vfQxp-411ZEio$6xyEg)?WAU;hKiXaB?h$US_){~fXsHo<{lCzdKw zaBE2_5%~RmFaU&3k$rXu7|&pmH>zDs{ts1fXd84>J; zIZ*6C47sfs860h!kXQ=^4jpL9X|hWeX$>ZsL4?ZhF>*caD#wU)bO!h65R#3MIn)f2 zO{j2giw4=bmlLfOlOIenGKPmwp6nw&VDO&_a5&F^0Gt8uzSmQ01_V-&>GYatk~4}m zOA_A|?wOOp27rCoFyI5#f&Yg7O*T}3;~V7Qe{vO|NW$55%_ zxsp&a79P-#!Q0zVbWz$3E;X8HH^J6tXIpiUqyqqMrZ z8r$0>ykwe8%rFxE8>0qzqYc^lVm?pQ91_BZ^*k9WTksoiSbz|`P#cj85e&B${RT!4 zH_^7ykbelRkyO02ceXeXH^ZW@pDC@n_Aj*%LW2LjUQmh%KCBpIWmH#1#n|z=T$ag% zd!Qo!{t0$%(XbV0t(al{m}#{%C$|L#OwL5A6w=Q-kvD?OA%asR$86jfwtV-OUm~#g zIb48nYvg@Cam$`9Z~&3x>#u>OU&w)+d1P$<@AaLN1CUKhREfZQ5_tR!dK&g0aAes3 zf&2$O1AB&y;=?*I$ulbkjSRUW)47vm;viuUW&@Ps;4@`qwZkQt?mbYx;OZqg*YJQ$ zAMG=D0?B=vpn>v*1TGkSwLln>HUD4NySrMd0;{2x4KhQTutiOe{TGJ~oJYj}ZKucn zBO8N_N{gK%IXQUXNX*FrZz6C0K1h*&Y?b`s2P{2k-JT@+3KtDUwU9Rpez0zPe0!2@ zBK9@m5C8Fw{IkBZzPGhiOOhYaXj+; zd#|pySC4IKILCw@Sl(O{`1-FujaGyH4obl&2kA3 z`Gv@E!!qZ=(hfljWcwm^@{#>{Jl;3*oS)(Y*pm-BIbh4g&2(Fn?DmjjAL=)l0`B*vj0J+LjDQae@2tBWE>Tu z!usT1VXqK|ks7vHFCSa`)Izmf&)3WO>bgh#eRXwpU)k-e^Cy`2if`>fUEQNPzFH;Z z>xDcskEg@_MLED>hobxu&?r}%<-&F|@}7FR>ec5HJq$949dSSQ|EYCq1LMOd9v;cU z!y+12h`ob)M5KCqg}AES4qMlBLY)~2lh_}KQG#6e?fdN7zJ1v62gtzDSJ;hMr&mQp zLI}4j)da*7N)KZNIo}tJn?X19cG1q z|LU$W_9m_^U|{DRvVd_u_JYuG4uJMDXvqea_Nsw#73><@=Y%3*7hFerY;aRA5dsJM z#G;q9F3z>&&uC~@EubkSK=GRI(G95oVj0%L5PwWBGO+P_F)qEx9=xFvA1%)|Dl zy~(h@u>Uq^)ZxRlF0NUmMNnuzHVZPeMjHeNSaEUi48|F*#$k69 zj_O+PVZf!~AvOVdar*&X3(d+%>y;U`2J%BM#uR5`!fq#(?piWU)rF`J?-93`BU+oY zdK8JjZDx;h!d?{Cei57^TErsaSWr#&?*|-gQHn!iGD~ZUv%z6vVQTiXfF=OMbO}XV z21ABC4jO|a!nRA5NCmahMpj^oGszI%!5)|W1a(@LiC`&N%)m}FS~6G95pg-9IP5p% z<|O|6$yyrHVN6<_fOdbU>_v*gF4x0<4iW#o(2uc6jxw#m1V$ZY@Nj)JZJ_E zHn_rp6NhW!v@GN_kjtQ3nHbp8vmbJmbro}G(29C7M~r0owO(w7y=GvUu}^bt(;qpv zpX{X}^_PMBG;?%%73fw42u2n*!0x{al*3DOHO__w{}`wM_Z^3wqSe|s;eW431gEkTHzdX$r*PH?*NwF}N6-s@<#?f-MNKpH-x9Po}Mn!v6QS z!U95q$POYRtTMwYKK_y>|MSydV&v@^fB*Q`eR9NpTN*uq8(o}7y!chmyLtRbDGEgfDHLFM+uu%N&yZi(dQv50E zi@l@-p$U|C>Mlx#`d!n*S5Z3D)(Xq7u+|xiM-47v#(rykFhRoml(PJNDhSt*I$d)! z_EBD~*C}Drb}BHpiV~u>n1A6JYHrp?R61&Wg=7_5>vHimb=3T#T5AohAe|nywl-3c zC7Z2v!blx3Ug!!c95u;8PyrqV1sgs1Y_bP={JxSE-QPcPUX`JL++5pahBAsSwnjnx!g7 zJ0@$LGg2eWebM`rK$%I2^V?AqY@fB38GnHuHPO(={7PyGV3Rs)(*m{B5{xJE+hM@m zhq`Xz)GW;=YDvvbDmbT{3Ii;rS0oj5?FE&E{(GaY7OCwe&s{@>;u($_W}@6SYDPmR zYK9F`?AZ$_1!{LqjapC5`RFF)f9f7JYr$$tn7)q+T~>t}WiP1!U8S`Sm0(FD@Q=D+ znQhecs4{AfI)|F6d>8%MMJ+Y9SnG++S-O`}@|#1{BAid^qXl1hO3Aa=Q_{Qx zROC1RZLJd)dh0hT6m{+-oj*{a*M6b=GS^Vv3-hRXY41{kl)Y2}YKytbbFFpSe08mq z1ogo}ZoHx<%?zfZP&d#2>;o!lbq#8x?WF=U-lK9*gG{mPJt|OJO1UTOqLNW7Ev#TI zB}c8dl+7)a-?2NCd-w{E^wZdqg3XXxIZ-<-m!7@ zZBfIrZl~dHr)7(~@n)Hm6Wgg9H(+7SL-(>}c;ImA9!7JIyJ?Z%FN;qL`rw0{oV2u{w3wWroMr4FHajQgbxu%2%=|QE z!*O=d@fhP%eEYQ9_bHq0i@3#8oD#&&VF$%De9({+hPt*%g*qn zO64U$Q5Jp>L#Kbx(12HDJIBNn#?WW-3hj=w9~g~n3_; zH+=9xObmT~3`QH1Mo;^I-jGHwL{53`m)$Qjwid^JcS*MJI|frGEsU4aFBLvsAj>Um zn6FgQU(*Yfxjbgwwr#RPrBEwO;qmH(g?10@9?a)y3+ER~m36%Mcznr^m&VIvvO=CT zSDA)>U6Ro+<;n)W+nph17RNeWDjc=&yMa-Uw|Zb>arku{Nu~B z(q2v!yH#X(WF#edxNUQrDO1)-r88%4leX{{pzrHQ`&#a1?nQ1*&Bb2wd7Yh9nxfp+ z(t>g3VrLJN>7n(Jt?=iclz~OxY0;p%5e&WTX1jPZu7`MxlK%Q&xP{DNQzN)U1hHkG`?b&Q4CY zUtQ4D@2AuGE%j?^N>A5y2*Mk?9HzB8vp)LhqpmLhkuC?(FP)t;0`T#p{tmxzT}P;5 zO3xIs{Msh_fc8cV0gk2*T>=uz3qtKZRcM{TXh8nyN7g6!l|*#)Z$vYQ(H z8vV-9J|JAbzHh|kq$T(d*12;h&PDsXI0UD5-v4;#m2>CL_4k`qeggEpr)SC(#jE}H zoYe&(r;_dMe@$!1&3&z>s}YxL?1{PovSPmSaDw z%b}Bp4xO}N^_95x9hw$gWw@WP{tu-1d1?G`k6@Hg?CI&*v7>QS!Rpl#dwbv@`PYU9 zKHqJtcq{O;tYOrstr=n&^8&h`oct4pmz^E`O7QAH#L@_XpPwo^dZerCkV_Y<&(*cW zX4-7`&V(7~T_?Gk%^IMwzh4l3phGaF=Qk2pvp)COPabApdMvJ}@JJ){$&1&&5PNLB z@Du6{CfgU_v;xU0o!=`(#H-NISK(%_>t50RU0p7Hu0Ol70%rfRWcnY7%5-Qns_5%F zzs6VL2Lz#0ezPYNYhRGPC)-vsIf$;jbW|)p8WT(Fp3h?*N%GjnqzceqKs~Fkk9B_h)bTcQSJ&&&`O()$qQfIz;VeZ9KdtE5Y$T&JmivFibmExp|c-dIYEa`gz9t9H4F+T*?I&}RSKeHDA;CX#Hi)G{E z>{Igd&#w5S!|wu}F4UZ!Za%i1(6)8#Xn`}jJ4h*Yn>i}JaOKs-G4tca6>c-*DbLkt zxWIl7IZ+~6eJtGXmB3GMUFGF<9TrDpvE@j%Z}$xB_cBLgZb!OY@()e>!QBwI(}!eNmT1hFeVt!N2f!R# zEhz{A1duhlS1>2=z=6q5V9GouGdDMKB|C=4cRM0(8TF}7*MG`!&UOiqgTq#mILABi zy4l=xy+3+{G;iqqWV+7;u$?huCgkT|zpl{<$|9yXNF?^zAt8H0K;HHRt33l15skk( z1?5O(OgFwXa^kJGOZo+q@rtObi56zY#DUaD^GplQy~LUzbmqFlN)|Xgf6GRp9p9 z9L{YHFuMKr9tnCc5cq{hOdbv@l*;0_@*hVQv+0Gr1!51k7oSe)DOJ1@1Uk-HZHpAn zA938?ZhJcrb9+cse(c z{A9gP*he2>FdZFUPo9i9cW#XT$UnUk=gj%>Ho>Q4^&B*>N;juB?LUV8(+S&QN+XM% zatiBG+!pXg-PibqBabU0!ohR(ZO)H*w{M_~Y+iYu_dgG*e=tD}ucrXjst{l#pFI}+JjsGPDF;r@u zgJW~%Y$uoO*@IcLz47ihqF)j|UT@Ra=ViviHAlM~vIN+Sk#E|BQ@|2Kek}iylj!NG z_EPCokb9wm$s2(6mX?-yUh&HBUekGX6Fq81QRwdt&(c^78N~Li6e-U4OdSEFiLG^04oG-Zr-vGwH>#%Yu|VL`H`WQxMRK9`t`onP11M zIdlF-t*x!e`{wU!fc-IM;78M;fxMYSb{?-m=SdH4m(THB)gOI5`u(oxesjbW#pDe! z^W7#Ux$);mUhO_!$lI1wa}nj4!@5 zoAbLQ-tWHqW8Mv0(52*dxufT?=bL>ylb{N5_^$DE@(`Vz1)B(pRrKqUU%f{>aG#05o*_ z$D%}+e8~DP7q2qaZO}a6hV1#~-J+tKj*ch6W22*8Mxy&QWf6joj?qEBMxJ;k&kg7*E;R5!PBOZ zj2j%&)Q7tKuX}|`Jj*2@)Z6dAYjSji3RpFJ_H5B?q7FLVG`)+?&++zloO8(k;55-} zk%&|gn&#lL{CdY|_F`jU%T_lfkKji-RKx9E_jDOaNlZ;eVQ4fm?POQJs-r2<(c4s> z_wJ2vzVW8UZpqAaPyJyd6wt9_?>l+}HE7*&PFKEzsOlGY_g^-q{*pR-cCcmD-O8R5_*IEOd4|QGl(p=x}SoF>9UDn=1XAZD&b!GVkwBqNRrXrKc zQPMBa9E3tz88_8=-lTap&H>i~oJU44?pC%C%Vq)ep9f0b<{GZupI?3TXVmGaufkT~ zSo8V3dGn&N49Yb2j$o1mIiGx3y@~AS95-&v=O~E%`AzSejuK>jE?58HzGS`gS?m}J z3tRE~yr@4njUHZH=%H_!$piiu+iA5aj~;2=#&$$Q`}k-@b>@#muQQk-6o=n;_X51XdkXL1UuOFN?d;Lxufc?yWB>x_OEu^NqM}@n|W?ym#bR?SSNn|IT~D`gvA1Y{4Qi_xNJx7f35s@s_TiL zO(s*(H{a}f7ezo_Crz@2hTEa(vP`SC88hJuScg}%gF4`k5^$zPY$T9%XsnKt)udmO+ z;@}_(I1hf`=i&l6?mvy1jPCbMn$)(dZP%`i8@(y&Tj$R=ZF;XPv@A4~3?dY&qNYm? zDf-`2eV_qcVH=GL^mQ%hzwhz+DJ`2f*Lr**N?kJb5Bx|92CJvFo`<6F^C6e(8ZXQ2 zv2im3z@T@11MF;k_a?Pvdh0xr*(C7O2sDBYjk({e-$mr!c_Cp&>lmb#$bFyAuSrt! zx1s%~r2R*=7c-%GPyOR(*PkIpyfA6w2`m?vk^Jk>P2$!&Z<5PxH-1yJYvVUq3m@(T zrMl+(Lk)uN3&!UlO2s1hczu8?OoK^m_G@fe;z{|%SAE%qDcmH2A5rRzoi^yDKa_p7 zX!cYeaQJ*QF%k>{oN5CJuyI$>Hydql+#j3y;rJ->>j)TLmx~4LA=Tae<0b1`KSxQ5 zF%w3!*~jM>F5oHo#j)(;(iAS23;YD9uCJc=(YXIQgd_|B!VnTHlRy)}1t?zr%d++D>|NFf6KJW9n2M&iMC;RNP_da{A z?{}@WmnS>yP<;Hln`oe&M=@MG+5bFrC|)z}e9W1FOlXMSJ6ug zaX&UTSJ3y)&bI;hF05YtGt;)%QhZaUXNH74+?XtK(}mHn2T zhX;oL;PpGG{*$>V4!w_&cJVf}mz-QSo;QzY*nFYB%yh_h_$^;Hq;N}|wd8bdU*r0_ zKX%W4bbhYu@2}dt3Iy$a9_kc2YJ6`~Y>d@)tV{rf2Wqp_>JBp%Jpn+)Kr^dz#uUPg zE-&^94A;rY>6&L}AOsR0hM1g|`G|xn%>TdnCI95oU#ggW?@=z(%BJcw{=J7?nJ5*f9}Ek z(J1}~q?+Tn2J8WwnYaHYzi95i&injfSLk-oe^9>OE%WNUFMrZM@BeWPgvNfO7G`|K zx4r!}GuNu0iYFbd0&YOeV%)DrweVWx)w%dSLq z9L+t*w!>WNP>VIWl7)(fS=PS^8fACaKLmqu4j(MVZt*Q9;x{kKQ!YaFkPbr9)(!3) zylG*9^8d5d;ZcD6wW>cbIbP|@Ts+?5pTXB6jK2NW!eU9tX}4~E{=iVfRR>k7i_6{h zenuW`Oq(*Bokz4s<+Ep#&+<^b6mlFD9UPR_bJ>beV2gT5=;*lb^wV?a z7!42D%;SowDaNNss!*vHC=;(**Vgux`M7j*%m4@(x*|@EUX@>Te&!s2(($}v#=LP8 z!hF>M%{WxU%45>&*QJ9yp`SoQacq`s*)%!{mCUpa8Z|Rf_ryUzQMn290=*LRTdiAP zJ}3F}G71kD7e7@4dyaydsdP4|IfJWK8T2dYuoL6ram)tCj>(VVvK8yFF$n5@o-`n3 zw79q!Y9CX%y->qv&T-hNOcn`}(LUC-sS3{X z0tpDp@*5l9C#bf=45uIl4iGPwUf&XWgVAqqRIHL-Co3p!&aa#~a||)YuQ;Envw|E3 z!h!Bm;kYFrV7XYFfY!yPR*S{69Zs7J3Aub>aw7O8H^FlbUzUCyAA7J<@B*7!-LyQQp3ys@ATw9E zZ*~1%?%Z6gi~#NKj}7|W?TYJpH~xh$LPIf5mk%?;FRmEP0Q^;}eLlb`8DQF9>DKyO zCP=>{j>R2*43K&X@Cy}34hvN7#*OVqkvKLyb`+Fa7DxyHU`D^kcZ~yL zAph7A!DC}iPGez)2e2n>EO^XF{^9kThEB#1aC8KCKV|4)v@iI9)MUO^#R3j^PQet}SUv%5~Gx{3HFMc^M8CQHT9S$Qlg zBG@jv#Z)sLnb!=Y?^uC8Fm!U3fen4~>zvCy=-8XIqs;0}tP z4x{~R0UulW;D2se3bc=(>jzl>C>~A#JA__~vG7*;reiiibq6cRefdve$a$G)&^25P!hfm@^ zrhHc?!_#H>17!p(XbpHuJn+kL-%P85Uj>Kj2!7SUQXrBk`HFUwFW`=par7*5MCrK0 zMW_R4%D)#E$A;^M!E`>IMoC$Q`a`K;#2}-Bn?_G!p4DJh1Lt%KEss0EB~Zbt`k9v& zD+RIv5i7Of>MaGU)rT`8;$Ofi4;X$PByTs8#oKTFz5;r}CFE1|{DUn$&ySk*D^?0PUL_2T+Z3D84F)=*&1rO~?NDAz*PN>D>&QZ|rT!W#5 zYDPydy8HXH?V(BdPR2fEuFhO#JHGY+Wg~31VD_)SmMcrjMr0YwG94~+Suz=i``!g` z)H6bj847*-aJZpnPcb>fibs7fo&h?6_Ui;_GAVu~=w6W*8|ciw`r@XPNf0)%Vx0dA zhR%!vT;jol*$;8u6?k8x0R6;hN%PshnI2&^lGoS z7dr_W*rd7tqu#lmzqddQ+AJ2M^>GWJy?AlMFn%mL8+o>1(af&JsR|LF5BYT!_S46* zkr6Hn_7~jTgZf2j!z({tiH;LLO-L{hTGd(phmRcgV*lO)mDXN3iU`{BAy6w0D4ABSgY=hD9alT9o z`_!dv_;;n>m|#^~aW&crD448T-uW$DecfJ@@Yq4M*mD!?&;= zBHpmfP_STsWGND_F4}t85t)s0%1~z`5Ncpv~AmPHuIPH^1Sz8M{VV^YGMC!$WTtnY`eZIVJWrRDTK$k zA^Z+&)@5WYwp7*5QJq$OX`)iW{BH6ktja2t$;K~DPMDa~BI}k)^-u*P{T$F?8TiMt z7B=?Fmh;g#m);)`@RbV7OxTxU>9O5rTQV>J%d>JyixsY5K(9@O5#2JC`Hv|YKYppD zDAwdl{K2JECT^)FeYKV_y{j^;Ly&vy<=TvGskN8OEi+&pKmO}?tX4hx7v-nI+KdoH zaP-_M)Ss(`eOzIgT8`B~Y7vN|`tr*!6>dX?3b!9qO-`IpG3A#Q!uk$_yc_K0<;?9` zrYg$a$`x*x1(z=?wA@tK$J1MdBG?CS)e6$PcFP{KxF=a$v=9qc_;La4RYJa=#pgF_ zYx|UarEY~ojr!01O5JKzDnCVGpPQn)+eIN1Gzx`70-;tb6!Kwjc|4$njbF)vZGrW} zuePEA!LqA!E+4;TE93JAPQot!7`A#?Zc#4laS5NL*UM!5Az@*1V{&(Lp`x(V4P3?N zg>Hp~pRX_M6LvQyC-XtF37A6p{KqVoUd!T7DY-(eK){8C|0Js+v+H|nTMw z2Tnfb%SIkUH0WDPPRd$kLYYj6N;Woj!$KoV?sMx)?j9N{{3#!Z8ACe%d48jkFXAV& zxB@-Dq)f&Vq)u_C^n9fy%sb!RvOU?JIKON6fKUYaf?ZZt;^QL|$wZB1BW10!GLFv( zCm%2Qd_4-(yYvkW{p9k~kT4mcUuYJtNaoYZX%(?hp~qZ32vs;L3~;BoT%{XVIHlcf z$<3Z+{klNQm2vq~S}vDgB5N%fk%_Q&U`cE1h^&M&B70ociisrOM+PIMi%i%Dr-kmu zMwH4Q;5Q2OvJw$r*7*43NfB;C#1gu31?5wUTEP@c2_K6t_|IT9E@o?Jz@CU#hBw;( zc=L}}*?+v%-rn8-XP$jJh%ICTmv85VTy#0F_Vi}TC@YXX7>@3@7FF2e!}o) zPF&JT;wGd3CWD9cJ$Q95$c#>1DD$z#mq1ZHyh@}%j8 z{Kwv@og~l>82p&+;S(%KSx@QkRTXQx{>TqJ@gw;oudj5$ZupJvL7wCmgU_<;)SoGG zNf$}yEg|o@{p6F;Zpi%`v%JTUk2wl;mz}*sD)=7D|8$okb*m^ie**;`okafGgA`u@ zpJUvA^wKV}Q+5(RZYj-!uQKC{%j9GBQZ-Rf*?tN-`4>aZV(E#`DC~`|;0xVJ3*ej0 zAUfDi0JgWoQbr@07y;Xi+nLYJH(|Ew1D**=O!c}z}X-+7zh2i=UEx@##5 z?HP@B2`bq|5oJvVKk2l(9&!%Ng`e(L^2tKZ>da0`sNX=^b$iGyvdrMu8~@1@iuw2{ z`f(kF6fC2Nk`>6Ez1xsC*iBJHT%nR;ku$gezS6NDKgPK~Q1nMXQuO#E%7u?}?1ztO z4t6J5HpL=;aKzj9aJ?Pmodv&c_^}J};6si3^2r&1U-wS3_f=B_^86~_xQnrkoYlxX zoR91Ir1z1!zK`M>`X~)~lpTCkBtgDt$6(|phM%*d3S)oMA&R~E3oS&BXusT-;6wZ~ zIm_mf3OTn`7)v3@T^tP`=g{H?O8n$!3OkARjW2-j@}DVcSud%YkdqpI(JAn$mcfrZ zss_2IH3R6c8>FsTOYSihB$+=%@yG$Ktb)HalUKQTn<1yS?A0$wcIpd?fnPe7t)(R7 zw~ibCf&7d2!6$zg<-(7e@%hf}9VD0FERr4hgaU>qNVfPOMZG6UIh_mx~*x9e*kII=zAn2^Z@v1ZPVagwyv+C%vqZ{+xR^!*)arJ69xBUF{ z!F;IGc;RU7W^T@W!u-!{ZjNrfy+>8O8^5is9ZVk{cFRxCAKX;yx+#BfFgQKmZ7?x^ zFu1lCKk&TF&vzRR<}Cc}nsfTLh1)m^4JnGQUk~2A*?0F_NpJ0T6{P1SCFSLDGy*JM zF9@zJQs5tjQB7D%zCxbp?ha3BcX$7(sXcSffqwHkH|w0?=t$r}WyI`Bz(6baWK!=kg{d zG9peq*>c9(FH#(^wXdPU5(yr7QC1e!)g9T69HSoRtN9#x;-ZdFNwp+2!DoV})Abeb zr8X=4gu;RbhKtjACUjU;SBG}k4=HRF&gXHyzo&hN6(|fzy{BbE-+pb?%)-~W+^6b^ zwl-s)Wr+UDl`Hk3_H&0g9F0nqPV!V9vc5{No_R;;+~kH6eE!Ag<<_GtnOZkt$4jeM zUQz0+Lwy>C1RTY+up*8eOtnvTaeVcWYKcCAtz{K9Wu4j@u(eA2k)354E_}oy)ZSCa z?o@E-T3EWTt$&-{gr|LR{Sk?UL|^c<@SVo)?y4Kz2lf}dU5%DGBFVP@J;HPD{p%dt zYro|C+FoWGx3%)>LoFSp~^$l8CX7~EHk65IISfHAomX_>^&Rz|LsRn(G zK0q_H*;&?C>qDY;#vgj-w^iGxW=U-VPI@b^>_q9F4Gp}u)=pp2sLtoR_V}|W?AqEU zbO{o@Qg2bZ;)ZZXvX1@s^tABN&Yj8*tBCz4JR2tLDmikF>U@#l$31;&H9N!DZXzwz zLa&T}II!+Sfh_s$Y;WaGi_q+jS1z3{*q_|MuJrA}`N6IaQq}7HT6J;;+cN5fQh9Hz zv~*p8EPNo_Td(gJD1P$fbU}kIgFSIy(8CE!3I6fT+3(%GyLay!>txC7v~0=4pxnT~ zm1BXqhsTZ_$xe{HS6+Cryl~ymABi~3`GXtYyztjw|NM^&ISbZ` z;nZCk#Y=u8hs%wT`mH$lWC-;+tIGE^@%pCB+IpsRhRqq4tgkB9<2&o1hhwF=b^N72W%axwH0)QrT=K+HJ&A$FOB)8Ot@IvS2g}jC^VdpBgXcY!f%>PUz-*R zWz6|!Rl`jA;+BtN;#QV%*JrS`x#AY?!-qlJ-xasC^r;IjMtdwf{_@LGe!)<>Tys{H zzTtsalj)f=G4D6!WRCJCzFaFlbt)*R^wzss*4FWto|L05XYSl#ZNd5doUrr3Kgzx4 zJ!?L|x|=oqC!H>2(V@vvVQFc5;M(sNcNa(L)-5sN|4Ym#Wvy=z~^l#+LP=`j8Oi!$VE)jDIuln|T*!hFd8^ zqC)i5^_F&Rc%(WxW=36M*QtMMf@f^(6WXCyhU~N`E;oIa_4QX@iNy=}e2K-Co%I%> z^}NU?wa{f)88!bf#ZGW?YQZsm#U3mP*W=c;fAS?Cd%@nwn3;dNoG= zI?Pvi+alD;$5^MWD*T??5_h|>`NI}9+tW&d5AX#~W6Xz|E@zbQ|9iIm5g4JYu0$BO z8E0tkK6Cov&KIVqMr3`KJf8&2-un7#d&|z69?bu}zZs=whgMtYt2;t;Jf1OcKkJ*U zR~H}fTQ$8;ro${?nTF+6G2v!+YUG$t6h`trq1DQIeSLywgpY1QrZeVO-8W-q-hFL)$%zJZE>9O_ zrB^B~DsAOPD%9UBwOYRul|i2{=RaN<{cOdEG}6OQI6YxE!JELO9u*pLrQXq2ZU*^9 za({@AC?88Ugb7cV{Km5!zW||i$&BVqG&&D6r{x4YDpX=+UITdtd1~YUS?ccZ;E)K3 zzBF-mCf4*bY)h9qm@kENcUx-ikm&G%xg7FE)m!tek-W#Y##Z6$tMFC07HxX#_1Aaj ziW-dn8jxNOd+j88w+|0}frZgjbMQ*0y*m4k{M`rzy(KQ+~IR_q1 zMGD(*MaPa_>$-OBQzor8vmM0`^V=16b{7u2x}25R%#HPNv@z|epH{=aGg z2B&&pkHP*QoN9s>|K9$EQ)f^A)g`WEg@wcle4{?tEd3pn`imBX2 zIfw%lA%=D#@NF6N`^XReZoqu&S`pt{(oIZEr>kZwg;t*i?mIvMz||>@ z{gi|_Rt5`-vwKKg-Dbe23dDwn&aX#2>ZiaO<-oaJ2CNrZ*@1g+r*Opb#sGt50tYh~ zc#du(;*KAachMoL*ml$qhZ+mKAzpx(+`R1utS>{%t0=9En3&oHz=sU}4q3R3f)*d6 zu-Cq%kXLV0#HGK{yfu1KmLVQAdjqidS}Fua6=t*qM?R$l z;I~xtci3BZ$t5h;fDhB^dkrzV_QFWSgSG;fuBR--rKY#(fx&=*fT@`nQU?DeAg+_a zhk?LE5r}zaxQsc)t0^#V0|g*fIT$!BsiBv&?E|C+7SkbSwivj30pd%25ignp9L3;b zpSisxE!a$nz*r%b$AMY<&~GI$Z_yF%R4C?STq%UN@pk)Mq?On#y8IdnJQdezk{WBM)FWJ%IAuCVzK>S z{xbgN%l@ICo~?AzZFjL3^LXMH!vyxpMzwd>W_;DY{dI?fq6^Cxe$k$^ z!|w>)z1xzqUf#aOD^5!pYlXYlhb1_a1V%fnPy70R*uCDpm5c&v_oZYVi=!5!(o+8q z72I7VA}eQg^OFyL4Bg$HW^`-ut8TOMLX9$>zT#hft~zhVh@Hs1?pKR*=L<|(Z_3yH zJ{O4=JwNsSc}KUgAadJVrppiX1=cOFm~9fd?=zF#PTBwHk1@)g-S4-fd)u~^SOss; zIw$b(0*fS)^?YlKR0I8dfs}(a+j{l%kOrYKbCw@ zWd7wsEI%qR4f9KDF*5QNmB)B`zcC0G9z;d#>dbN506y{CSMiui7`^7nZ7ZHiTIx5!9Bz^ z8woU*R1KAs92|BSkPI)sa|cY4#9FfJhja&rOv%BSi$v_roDu5-2fl%qi1kRxh(l&_ z=4}q=p!G(M#KB?X_v}t~&he9QA8W(T97H*6c1~LxR#!b97l-sq9f{Qj2=j#_V)6>tuS%*M& zNayb&|LhLPoHp{y=?7PuL;jl8IQM08x&OkzeN$Kt_}Nwp1kX;2d;`bL$Z5-n6v(12 zI!28Ms=JW-a;6T?6iaH5prRAXBpqGS@jU0$lSTcv?02 zgNv0iGCsH8z}q?oWf8gfLMNC@-0US({P!0IPIvyJ7Y3QX07vEDUXX)dlEJpY@YgBR zFDR>NgF*iA@cmNA!vM&wBAm;}IEL#N#8-gl-bzVbI}Pie*rOdBai9M4pdaL-{qi@H zPi8x0e<$jOd+FT;9daFXK+Mmog}C-1e71(9EBg()f(*KatYinxauJXkx?$3)jpQba zGH~yVp2O%6A>X_p4fGOrd=AD-Z=ezKqDgYzzdeMFqOlqhKt`J+yzvps0u_b(`< z4DuiPlQ^}Jq}mSh#8?zRM4w}gjez>~G~@0IBF`Y`$_I(0YO)GZkxg_aIm(i;PDwLa zr7nP-U=JlgrwxQ|8V$WxgSM4nTx**9X>RjIvPqdwjzMV@kG5w+p9!fxMHF2Oow$Xx zeS;K*wLlyLQpkMjg~4Xy58XxE`V!fTVzCBC9oFL5N1B#?gH9Gy@RC6nWb}E7c7ws* zleQc>YgQ)}pzleZNipBzsK_zcx&r6*U_4<=W#Aq)=#Qdp6p&eDuy0x9Ehn3W&19o% zCA+fKl;6FboT1|{#25|E>of4@lB{lGbb7{ilnwpPOI1T2o(m;8OPBgBob+6ruOfg>;Qqd>?EMwr&a&n%TkcVLGG=z*t!2j6v!dc2 z_5b4PU6uCR)^+PHJWvNJ7duy2|E$PdWtFf%R4P3DMsr`q(Ri2f#s2q-^34agM<&ab zrhZqxq|)to=c4@b$`Jp)cgxF{xCQU8UuyMz*QFJ+}F$SCzZnjoLhoye(e|Jk;l0@%T-zn_t&CH>;yJxSIsXQZsz2 zx{uY>4a_v(;dP~=jxMM9MDhyS8dYiC$D9k7&n#zZ_;E#&@rkNcU7TMUSNv>kTyslq zUe0oK+}7f2Tw^VWGYRmVf56(<*jHQ?Uk(zd_q{A%md9%IzH; z%{KXnTaAW{sarydikI4%}8#OM0lIpv28EfI^?n0d-vLo zMULg>I`I6;KA3OP)YNq+_WjtqcOy(eeC3)E5Z2#cFh?q#GlxG%S~iEzk#abT z+GPD<|3jkuANiM&V>Z}5u>V_*#r#Wl;jRDJg;T$KK`EF6lCewi%)2T}h%M1zPA(?9 zxQ%4yr6!(COMVYtkg125Of0O)DZGeG9K&gbr46~J_7E?1E6w&xB~zbFa!K8cxj2?w zB1*{0JAr1p#}bKP*NfKRvrWWOfX)#wAQxpZ@v|$*+J7F7)nwxxKw%YK6j8IDB9``& znIoUPw0hzMWRsUFVXim&zbZcycwFh1QZ|S}8frt08V&4s7CTvJ03? zcHtWGgsiahiy=9%q`6Q{35}b`EO-%F`)Y~U?!<}OKx|(*^oLfgakPR2m~&;7Yly;{ zX*RwuDqK#E(G4WXTnC$I6gefXAuB}-j@`s^jRlvniA+5uWNg7EyQoZZz`QxbS&lYb zi|eM5xL^g%Lj66nt59YW*-JAp-#gJPz6$S0la;GCImI`VE81}uKLPz+O8mTo69-Xj9KMJQyFX#NV~2BecCD= zW(ZQq8U5*^C??m$g=8O?g<}bsa-At`Nhetd0wA;6(3e`+Z(kxCymko5Bcsq3l9#U` zHb0VhzAqyEU$Qshh~(WPPWlKWQVc+|LZn5?vU2HCg0T5 z_oK$d)#5Sf!6h?a*14RS=^DGrv9n&bLd~L){_{lHSu{cO4_#bfR7(S_<#SnAjg}GD z@4|I+viQX4xTjv|WVCa?-G*6pIV69{@`zDN&lXxLv5lL@QVK$hS*0t}cT?ev$hBwR zUzgV#UJ|q2yX-{frVl>6w&V3ZyZZPF|HTRi4+{Lay{h8mYr&Vc*_)WW(&cvefR)*+mH)f__P+p#8JB?o literal 114926 zcmagHjh|c9b@zK5$5STujF7F&*ix+6s-))-%_+D^pu!wR(Vzs$OhSW5hD6q7?4${y zj~#3eFA1RuqzMTD?9h@Iu!Es(Vz3Ri$7YPj#^4fOgl9_S$Q&<9YMEKk(G%d1rZkex7$d=U@JE^!_r>+rej7U+v!i zXvFh={P}s_dFMs%2R(1Y_Icil718^%Ja1_CJa6ez_x`y)&pS3f&pZ2U_x`gBJnw5q z=6OE%;D(;}Hut&SdMorn)S}ZrIO{BL;n_ppI|dhf14}aAS?^fny)(DU%a@zppIqAV zR@K_xIUiW-l`mWGz4y{jdFRz8J^$iQdd2W6?>%Gdz4C{z@kT!QSugEh;4Lk@&pU5? zvv<)|U-DMIZ;h8b|8g&TUd>yv>VsZT|8wt;F1yZKac<399#p;aC%)<>hce#cWq;^p z&ROkUc=cW0hd#5_d+!xr^j2Mdz4!i)eZ{L?bFX*Nx_i9j(sz3w-SU9$LZ|drx_vyX%OTT7HgK|Lk2} z<(lo@hi}~L)vw>c%QrfHLrd95pUg{PkUnx@~=Jb)o+^iuK4QH-p9B8v-g!pf8$mD?EBs)zk1mF#J67XK6U@U zdmp_1F>m}UC%j8GJ>sq1`cr=Ux_9aI`@9eT<#XPrw!PqeZ0o;xo45a?*ZTH9d0%?$ zzrD}zc-8yp?Js%Pe*b@YSKRTkx8=c~dtX2Ff4uXr{%bG1<{@wDhyUrluk~%OH2wwe zypMgu8~Ny8dLO)TzxV#h`@G_1U-9zwFM7pGw|MVuf8Pr~zsJjeaFe&;fq(UatNzOS z^!I+|B~$P8)_vz+yfwER_x^C~S}#|-$(y+QAHB@Q*Lll7Fy&<~{4?)Q{`v{;qWhon zF5dZ!H}-cgc$e-y<*hk%+8aOqZ{EjW_}^aU{EvB+?N56je)@Iq>j!@2-SoGwd7t~M z7rc$%ebJlv`qSR}tv~i|-g(NK`u_9YpC12L@1sXv^FHzNZ@r~|w8s1Jv0r$tfBHXO zGP}wfNWaHBYuNV|B>&J$6;^vg{>9$g2h!e}O@HatH+;oweEu(xi7&#hZQiH;>hHYI zZ-3O=@cjc`d+S5q)pzam*53Jmclj;%cpv=2R_Vj-a6o4|BWZSa`OhS{IM^1 zwX1LSs;yhR_kH|Y?>*z6@~T(Q4-23RJ`@Bmx z?C`$)@ax`|2maYx^Z6fmtuOtZ_nEIhDq}Ej-rL?bZ@v!m-afC}^q%&%=pQe-#Ex&X z@AOV*I=tNuI@%TSL2uvAe|_)za#yMs>&<@Peq%jEzgLHEf7?9wKfcDjzU}SqUb@_x z?k~{XOVlfv=ms3)FLZx_z^?_2u72Cw!G1yCADq?yj)i9}qAgt1Z|$u9{sA@K=(N9o z5eNSCfxRCX?CTrs8`N=dU|>*}5Ar2H=^ND9S&RAx7WEJIFYI5qD6w#1f{qi31PA-I z>tdj9fVVU{;Y3l! z&xA?;qJ@e6Mf`t9|H8AAi{bu~)H}IzLSO)&Ui(0AXn1&NxUX-xZ)j-gvLX5hfx*7v zq5grs;bGqO^(VOB;4mNve(sk@f?`5_aPLIlGSD098%U+onPeiJNFnaU+qE&h$Cm^y@Nu>rbYW$@D-Wa?FN?t zHTVPnyOu6rwhScroCcsmLa-UJ_)#|du6KKHUon4W?ho^6AQX!XT7XT66A2*DKfp+H zbB<}fNkYeDB9lsU89?h3U6D!m4;aWvN5kYmp0|nqWYYRcXHr@Hnl~BxNu=}nOgb?* zm`G;w1>UL)0O0!~G~XrjP1QbXj${I8YE>}nP54REnJD3&0dq%f5h6X~4BC25pq5DiJd1GvCvB4IK)kVqw9 ztgucYXQd!7-3FlI`*Oo8a_>L?g82&v{v>(9aQS@~`b9~hLl)}7YETJ)NWd9M3Wbpo zGz~&#_!ub=&fFfzdBZ2gY@rln^Z8;B6!|&i1NC&eSj-0CnkgVj+yZFw1(RAn0XjGW zLiA%_App`4us{+-c>3V(0w$jgN=D`);t2zchN6J_fZx&v_=X?=e@beW%!q9Hj7$*l zaU&>{%;#2L6b_tQx;VIK)v9+aPQGV!!BFJ`)smm9K>K{L2z!cjIijCH%wn;`Te>V1 zgJgfYGzL^@12-eMvY=cP3%NX#gf97Pu~IDLb0!MeQZ5Mi9zlTuX*%Y|Bj_|ZCh2HI z=*gU^FVB(X~ z46`ZVgw&Vw8ZZ!l^o0u=pdtSOCu$E5M8rH z@CPsHkFz0}q|70i^ZjX`y;>MLpkKHGfeblrNs&ykJTCq7Yz%e2@(! z(U4J^kVzK<*-RqFe24M_L2XL#2gl9VR{yI@+8A!gSF_2073dJ{bqyk%H)!BKlbtRXnCU8T(PQu8E7OcS6#Z`+~k^CQ1nX` z;m_R>=#pP5>3-EJ!vYu-^1dV;irPRZL6yNqr34#5^G@7=*QFwu>z^*kBbM+Rvk8)E z0O8sKT>=gigv`ZkHiZVIky?2M2*?Pw5&1@VxNSCvQb_7D>5`w%ikx&S!N#XZb32)0 zu0zMLypXU6jUkTS(i>Mw^>W2vq}cpK^4!IjeX^M^m2>IViunV}^SNx``xjlh{M^LF zYs)zXvyc^*@DD3$mRV2JBMImq6%0j7&ZV4#a#6g9kT!^K`#WOK3#zf);&Xy2vM$7Lb0)?>Ohdu8_FjE$pt8h z(>`@%7KEM{eS#5DmtO)Uwge<#5SFDf{(mLTeb;4Iw=WiILa%qRWaT7DUp63rF!7cCtCy>dNSY1iIAxUBHmYg$}f_9sTeoFDQh zP}}@GlgUj~{gG@ihFD^dGu$sQ^Pa;Fmi*B&pXPGaR=JWLZ%+o$so4mFN+n+$4aTzN zQJ@P)D+0O_PE7hGjbCcmd>@3sZ*(H`N2}S<(Gq`jpA9Nds}lN+N_i4FS`ESAZMhX9 z1c8RwQXZO=v#=a6b%5RY2gPDel+5MEs?ZQ2rmtM7am5ESO9wBzX6@?2y0y7>yOT)o2ALm^Hkd67FJN z!+b8=@B;=(IK~g_!XlT0|(k#@kb}>?N+;93ERBE7za7%S`R@QtdI_wUIrz`OXe5lDtZclkP-g@`{b7< z5R3^wi<0>hA01CEPF%Luzhbh`yf)Wf8ze6>{E^@aoZ2fuug2bo(=cLaK!iJBq zPxyf^j={G|nKOvuhx!i2Atz{EaRh4zIWV&t?4$%aC=jj=0TAg4VfWbR=;(&g>S%ei z5^hBPs~i1MeGyFLs%50TGzz}eieDT>%SVH(KMJ<|4=UA4yXu!AB!tI)gI%@Su7{0w zqZ&-`8m_G{S_FQzQO{=bZ8QT#g8slTfhPIYuv!9#Y^4-_{))jB`O9jhR@2WmYNbk} zls-@L--kVhsl`$|U%2-3xeJn4d}ds{ueHkII3f)FLl7z=i*OLILVuzHM@v~o1{)o8 zqcWx-hisN}QcVVrb_>yC6q2R8=CYfrieq*^y#) zWb+oTsBE~dxCy+*{89ksVXFcTNIb;H9KiW9Uoa{o1{mdRu2NyZ#)Xu!`mmeVGPEg| zTg|H9XfbkBT9-BZSClUMR6e^FIV(@nOCcfuXZaw*rXQj#4ZqZGUshg`ochcam3m`x zs?}3 z59BvU{XyTD3@-Aoe7Q~-R=?$JWKiAa(*(~2s6biTD6Zi-<_;{W-Y#8xe9Vv9KSvljy6hV8MF#?XJ{xfCCdh*qw@3u ze1sx2tc>bA*`X3-@~db8(&CSS)Rs**Y`Njan{K?}#xHC@4!*b%i->XtV_1MJ&L7B+ zZrE`Bbr9*gEt|OT=9@R&02zvCKo*(9e$goiOWy-Vp#~Nab~I$%xOt|)m>AaE$UPV4 zvSm!R*~n2*DWCV-A1n>LJN#0+eoeM8S@TovwqI*jlE{DmO2oe(Zvivn7>5sSJcZ!iOBzQTQtA#!I{Ix2t2L zW1BZ`+H%V+o44FRyK#%SyJ6!-Gh)KV1~VUXuz_!G*mR>^hNNt|@rF%X#zyg&sisaP%Mk?O#Q0O_??U)>JdljU5w-LBW$wR$;hwkqw`t$1~2 z$|uUL2}~H;r?DRfrg6|vXvVX^!Wx7E7@V?W*Nttt={7k3)f++ot2f@b1s%W~RvYbV zwHyL*6@w`Jue%Q1xrnR2dc#+5yBP)8QVd43qnKK}8M$>uphMp9q~X^@Fwv|tLRT1S z;6SM|QDwxyG_@uwVXG0+aGDVQ$~D(C2Hsu!OGtr<&DL{%qv{tJ#rhia=P!C!BEj^q zm`n#@-mhKLo@m!T`OyoOg`d2pZ7vq(O56e@9YE|t1 z)t4!rIFAdk$aD)g`!X3x55=aNAMw6X);!} zZmm}~Uw8d2H+;j|H)(f#>(0CG-g^D@^^Mi`R0H8E!>UTTI<|S!ZQHg**WK}LF1z!t zd$w-Aj#)(2pI|7_D%f)($7GC^v)JZSrb7Jx;b8(z6&yG|z$u)pG}cazUwifPzU-I&>d*iB z{qMi`-h0=t|IT;5`@Qeo`<*rSUU}tr$FE#-<(l>1`|kRCzw`ZjzrTLXn(uvg&6@k} zyZ65JYreOp#s#%2zq@|T_wQYQFCSg{#V>r}3%3X_;cjT%zjf=H%RhbJcfRwT_3JGkV5`}FtMTy$RBuG3|-JMY?l&(to{{P@G@w`mBTEg2$x^Hbwee{~Jwf3XS-<7S6Vr*o5@FOq~ zIFS`%n;0#o*CY86d|So`ri;w3U;r*F-Vg)11q`t#S+3b~+Yf%QZJQV`++peiptWPu zrs5br0f7RIYP7LUH{Epe?b{&Ix51suw%@;X$IhKMZ`m|L#59XY5ny19N7%TUIS_2l zGSiYffXA=s1RrKcGFU_|VOoZ_0HjPaE9u2cTIF1}Jzl9anCO+;)ygEZN9?)V{@o9M zNC#@V#exSPdg!6Q{n0lJeJ&I8ckbNz(1QyWEVyLBlEoJ+SpYD)kM6Qy@e+P_$zpE3 ze96kiib{k%u3CSg*VJzh|$tM`@2e=Fa2ezWw|4 zKYrVJJup3e@X+HC`r97>{T(}Y?wC0+b3kq1f&KgU@7=%ez=6ZlPaK&&`VF%W+wZ?$ zLIMHeZgj^-ALX4L+^6o;j@()u9RPy;GkX9Sum!WVT@Mdb2ucz{RY)pmhqcDkL|7|N z)Js{-e+CCJBZ_$iReXYStJPvqsg;9u*{Flg%kJIBo{S;dyBEMY2xFZXIx`3M^J?$i zb^G?sOiw>?=!oO~J@?!r^l39Ru-^yZ{FEQfaMkgro(BIr@7&(G3_8)&y=$PikJkOb zJ{Da%ZU3>|aEcbA5A*s;3EVTn30Q50uvT>{oCq09i>2nOdHqAf79%JAfYGkCYirlG zFv>xGeZl(KZ7n|CC5ViB!qhcKcw+!q8Ckk)Ixuti#KFfU`|vcv9{dl_9G;#zU{uqA ziw+%m>L~bgrHI5oH6v4ep9A|vHnjsCbam3b8LSZcpl;YB0*LUgUCaNzFCn|tt|^{D zC9T>G0Z>B+ z_U?tCGq8Ua@fZGg8|QUEPORH~`}QL99C!=GXXX&N_l*<&i0cNjiNNyA@(gPwM5ORu zYVB)lwMk|+VJlZ?&PV=-a42!0i<-TMjj2hd*I_u3I4{|Qx;o=6_|NW|k;FPJ?ASZ# zAT@AA03;~!q{tzb$pYSW_ubNJhn47X_yj6|wn&7qeTR^{5^UQX$L3D+fhM%q_ z4F7Il!d`9Hldw!8*b&1=O(IMtpn@X;f}nH5|HQ#V4*du(;V%IYJ9UX{zoZ}QhxYR= zLm$nqIDl4(o^ue_VBiLX=wksi^N545Lx6{$aTu&jFHN#wRLo_H?IJ#Bc{B_f_&=po z9sGy;e7xHrT_C6uHmBs0GH)48o!38y|Bm~RS1JH!xv^|sYpH-{PmW$*qOxNi~)q`P(< zI|kz%0uL`v4-u>$Oy?7YMx{|^S`-FMiwM>!{yjWQq%B`5R+zn(+x2R@)vDAhrPO%? z9sG}3Z*g}{0yN%(q#N@i{+kZ)ky!$n0*AjWz`^Gn0Xo<@0to-<$o5P6@9#lh#9>Gm z3HTRFfLXg9lNU2!2F3_r9YDPY|6PldLjx=$24w>D1o4ic!VjPgp04<9~wkF$U~G`PzU$OIgQGEabhWc;?rmd{MTnbUoa2B6qwdI$Fy`@Q16 zYYs*ocS!{V{>t?5;6NH5h^1dbbJ+$H<#wrDFKPbMKRiSXE;AAo6U}P5KHg|I+eA2n z;40aFPh zN1y)jk2Us1Lj+V1;eNmE@8B(}JUO#xTDVL31+uY;qf=Vp|03v1{_`m<%LHvkfL1U; zw6L{m-oWs37LZb%YAn#7$;nbZs5|A_qPxEUql8|;2$4;Y(`*Q=!893K(D zz5w+nr5(K5pnZ6H`b3N#me3qL3?t6r5piE*-(Ad%qo&^=NhaF={|8JTaM5@HT6gZw z^k(IYLm0qxp^OVabbNwPdVMWxF8w3KfBJ@&DorJe;+GqKINl0tL^232GzWzEF)T@B z{$e`lm0RHl#4Q?}dblEb$Y@2Q0O*LFe~k7sIdW|WP9`Q_1B`Tv zBb1OmHA*{b>kiTV4gCmf)7gjsk@`P;Ns!?9U0Hj5vGZ)|?DDeJ)e$bR1l^k(2w4Ggb1bBGHEMH6nUVG<+z)my6Eg7I4ro|XW zuZItI*pKvgzQo0Jn5%DwHermJvF?lkGIEfE%oQi^XCsPUtS1UgRkaFselEnVbx$3EAL&Yf zBZBbnp@~5b@Yt~!|1)jC!RL;=^i(AM9qpK-_u{|$5D}b2nHX>y`Cl`dp<9Dp@#&n` zm1hr_hf$~&kaIm~;{#ku}Brv2=hZ2iE^;Wss9u2eAeCqi`jJLCW zbZPb_?ph{iTKX-c_tp&pm=rkoz=;4xu!HEAw$2?@LLlTghz?a7mAbE|HUf@lNMwrD$If( zt4+8EfM>VE{-+f6 zx${|b4>{;68BJ>-@7|w5;*P1A*%e#p2uwrS5g;BDFG(&RCQC#y5aQu}69=$P_%}V& z$N1N`vPj-j9v_exZnIUdPqbOPU^VT9{yFS+D#k~>_|MK70VJOhw>k=dxH7u|3FBlG zACVEj4~VQBFVEif(o=VUJ$|oTf{xegu*cpZ_po2W|CSA(--W2eA19{}Kr|4fQCs}t z&_F-gFk~k({ne6T796WrO!igh&l?y@4zN_gVr^J%t(#igBm!D(2HDgH5)OYSMozb^ z!%n~U4gy3do&g|$$3&5Im>7$h9Y;v$KfC?TJ1y87`9$KrXol$XFG5>C?{?lpiv4@K zEYg`1cPFZL)Q7uwga2THrE`4zMuq6kRJk%9K^_R3NhT&u+i#E`lS^ZvBZ3 zi-ta=0$-ROcgCxeFcU5bg@R`E?9ewT!BZI9!B7Wo_xdpSziXIO?P4{bsN~BNtf?s_ zD4XfeD*iK^WV8<&#Q(CDcDYucVsvC-CwbwZ5VQ{Co;n@Nvhe>AY>fp4d-)?EyPgXX zP5~T|!NhuICe{EG0AeH0qWrGm5=-^P`p)#)$SY}ZbfypK6}Gj*{Yc#n%nq#X1RQoR zLH|h;V=*TglG#E^M}3?OiAHXuzUplQ!-J%+sG<7<1yz;Xlo!KO&|x`dz0#mInGDtU|Pd zP+y1L4jMpm{{@-BCk()Ui0Kdcg4GmxG_9$Le9&x%rD`e_&RaFGY#Etmg+h{*Hr9FD zrLdf3QNNIRVW5M*b!Ywc;O(%N0PH>nKd@8|@aPy3K)5^nBO72Q;KZ}{JG7Ai;r)}J z{6yw2^7#3ML-u!(H#*9gxJYM5;3NFITyfAD`nxYlE*)ZlB$+0SuUM&0mVi_n`8fcj7Q6aF#|W;3B(j{rq--|1Q>`}W3hZU>ga{o;)ppTvS;kRMx; zWLJn%!?AIGouyn>HwgAuSn{7Ye-Rn&to^e5!;)^jR^$I@xlH2c3w<*X01D_1afj}1 z?pB=ZX8eZ$nyN%xGeD)Krut~A(Lx7V_I)yd5a6!uqJS`0J4JJr-_*opW?y%jYhCsp z=7#wl+7a^3GC4qZ?>@Qv*!~4C_9ZZYtkRPkLDodpFZr!3SrfSn@qgGClT47&Vj=Kw zg2ahDSx&-VDrOQ8V{doRA;R2Y?+BovU_=9FpAG8>ciA(E16slupm5mZM`ZU9{GYmZ z>Xb|$=|GHscj}KqIGxz@i18rOe}kxp|3IYXxc}td1&aQq2QnqruZy{QGe?S9 zD^*OUifz_E(gl12rP#6pP@Y^{4a<4f4U5?qhJgbUt7d%*>8R1Uo!MR7eFzGIB(Uqh z8|-;&MCdS1m=O>M|HmIca>VdA>|dt2^#DV@bG@C|kLG?9hxucO%=higQU#m=CdiLL z(giPS#})xlSvJ4bDzFODU@4bS@BDd-*bkB_5dvoUmzDNgS^6aqJeJPCFsPLkM*v4{ zq3kesNB35@5(!ut5tPU{d~{6`|Ku6YyB0(a9(wM`k(ch=j`;snxT`t*B>?c)wYf-( ztWG#U-(h|XwYLeX2*97418DItVm`u;@315}yiD6>G9fw7CBKmh+d-{P0%mbi{?8!! ztK^^gbryhd58GEXwOkxrHDLF51TZ8Gdl(;+y$65Y4+%i&_rvrEaG;gU&y8XbAv|%2 zSzT0)ICp$DK7upT-td)oi|Jf?V9t$#{{jgM7yLQ|UrzS{A%myzEn6AmoplOz2L~w`b zM!KOBHWAi#dZ;Enc>QJo%>Ky&M)t3Jbwmh@DyUNtH;!|| z28XWU-N8J9YnS1_dynJ9B}q014vZ8Akp5hONC)Y00jUtB9RA-T_TDIKq=NHTUc0VY zX-z>163r(EBS?$@psk5zL;}NF2Vu`a5+Mn2%fr$G_+);u?3hMtNFiY$+^eN7B0dWC zi~pTwF+Xs83lq>K3DPX#7a%<>h)xYSgJur;dzU1JhS*t9%H*2aa-q`pTZFnTDY(i0 zCpKJak4=g6jbgo3DV3XLEMQQ4e$e5uk2}usgd!U7;)cdZ*L2TEv@~f5Fz+>Q51jyM z8q2+WAmL}R<0;~O$UnYMgue6tWjK&<1^&#IAo5+*UEJGDAGb!tW4d=~5r4wB0HbUL zet+P=B}sOFGR771)&5eZ${e7WBUOp?v=6M9w~$>kX>y2jWPlPGXX%?{<03iUSM?)o zAb}k3*=?Rs7jZj_g(1RUS~9zPPb8;OR%BMV*qQ(_0=}6!0ry{e>ZpY~CH`l$*ad)w zvK^-MbL2rwd@&fNdmVu{>&I7oVAw~xFTq>P_|GPWkwQ>rL&0jB{VJt7>pwq#{yW$v zl_XOtsFJw7x;)-&wFrW-r{SsuP~gKzp&@|K>)bj9!QIaYVc&DuBa1J($qw);dC*&} zax?Nd;kR(-@1nnTt5(HKQA}@a{FDSZY1qpOr#NrC2hXm-i>csPVxYte6i|KTi_7}h zCBkMvGMRE@evCI7@^*9KRjhw&b0o7tQUe=)J1CR=QJK(2m8+6szvLMoHj)5Qz}>4$ zf#}|RAo8FBU6GB?LY=|{^y8*p%3r%%NS`+H6C)@FJof?AEB;4 zy*Dy&(5oQ8@W+nbKp(sRTmnQenBT|9=WHLr z?q_%GFaq?(#I-IEEsRTPIzM$MPaZR?Hz&Rsh2??7hGJ*;Q9@}>$8an-yKk_-PQakj z$l~M{H2c*)oOG_q_{WA$pENn`Gt0Hf{9<2DjvXtx_YE;}xyJn!Y_Zu;ECq(LBtiVQ zSCDt~j~54f;Fs{D`x1Vly$<~yr*`1=;|$w+h~~dLcXD8rKw3bXbAMan)1B;YPV}7= z8YD<0uO|BlzZ4e(6ajGVi|mIVWIuGFlunHi_+%Xf{Bt9=|B>CYWD^qcVINCNTRz$~ z$PoDN8}0;IT|ZHNf!&Tnlw5!~f_GO61jWNqqMZ93b`XRZ_tAY@=wqeJmU@J;Rz=)$ zkltC-7-+wAId+i-Jt-n{8=>i%-nw_sxUcwF1lTP{Ts_E!>SY1`A3G`8%gGknY5I|~BV#{C*O^v!b6lmqnqkjzf62JdkR7P@)xLUpSy>{*p5BaaPUYrPvV8TA8Wp#vwi0# z;Xlj2mLkuVDt1J$_FE=F`YQ7O*d|XhIQc(HjjQA)!V2%041T0f=nI0!+=OKBqcd}j zpy=OaM?@6&8LOia5ZvF~zK-t8@3mm}jvYc@)1?^#!O*}FfRiYqYBK>deUCBlX@HL? z-*ej-0E0vLcgG*p$Kk((^)GhCkpYO=CzV$z@%0K>4$S{o$^Kyy*iOoxmg;Co3OUoD zFf4tbZ%&Slbrq-B$j}Q>HEF$C^un1wWPLm)0IE;=gDF3{--G^+Q@BU812a)9$Oxd7 zVd=g+H_VUzo@9O7?%@u-Zyf${tX~5k?uU$rEP(xZ|A8e7wfxJrVDiD)5DABKl^Pa4 z7fiDMmwohT1@@24RxE(FNPuXP44rvi^M5r%1X9xBzL`fl!(c>#V_JLWf6N=#Xk#5Q0b@xDWk&mQeX-|*Lrz}Sxsy#M~L28akE zfN2L2gifHhgT0}x+lc)li?x&JzB!#XYR%Z}bI+bVGYb++ndBCiBVbtD{k!-(VT|890x$uXG2K7v zxc}_dmv`>uKN&tw%2_PXAmD&6zPY$}czZ1R78BLo zNs=EUuWuatQ90Q>aF_Da?0nze1!oVdt_d3vMS>i=R+R2Yk&Y7Uzh}KOHOyDUe;VvP zE!QVnn1|79kU4({O7^-@u?%PmN^{a5!4-jJ>~K6WsE*-f(N!>Rt-+|b>}8a5 zq9TN<5wX>w9{8lWQle%Aw{pLM3c>`e^Y`SX|eLO7>qBY+8AmjVtv zn}j(^@Bv`4JbXggt?M*$B@?v-_8tw(l>u@z-?@_+Eq_U#%3 zcAx`M6Zaimd+^tMuZQdods~8|LmK_M6Tp`buy4QcA55@6oIO9<$eqj8*#*RuucZ9P ze@-We4U-%Z6#Ot>P1P!Xo7fQikMY;+J8scb+!4UgH%!Iy4))QBK6`lg$yp*kLSN~9 z9sGs9@k%l#4`|xfgh-PY1!y(~?3^|9&+ORzKxk`J5dJLkDAZ#A2E zmN!6tym@4V}-yM=#5rmeH+k8#;amyWtsNBjX{mT9@T@0c$NNEFyw)3shJ{-uxN zN2<^T1y}$i(u4ft373@rNsCpAKpwW=o9`>)an))|XPGfs(HD4J`g=`9|g;!`h ze=d0@{t@!A%<^h6F_Xf`NWBFCob4j$q%hrUs1tN1T1 zk9aP|ce&3ud`nE~*puQpy(wOzqq>dl6|Z|&oV|Q#sGqu2Y=|Vafm|nlvd;KdC}{sH zo^b->hiIf4tp2w{w*C_e%HFp!a-a-C=&RQld;3fwAqSwrCDA;C0;T{bPrfR@PaKV# z*iVc2iGpR%li=0%q zs7<2cxgztQcTg&;Kf``08Gj_tW{_cPBtW8L=l9gnRVU2T;^rc|A{37-h-;EeSZ z{I&mw8f@%53>~!LHTQuP^B4A0;*kxu3;kb4@SC0E>{eFglu34hhgko7@p5L{@<#r8%KU^ieX~X)C9cRjsgh0U0m69DhWc=y0 zSF7v|-P(P%!U-g1{viPb&|;I$^qCYuM*D()8CI>zd;#80Hk*^SzmNETzJUGfr~W~| z3fajzP-;VkW~fY44nESsU%P$zQ+GP$L@Of^4vqk^m2wmSXr~Rl1<+?6eg-v|-8~)u z#{D$jC8$o#tB@Sy3QXfOY2ZV2TtBYUNCcugMCgOPlYI#QgP#P;oyOsFdcWYsLGUkT zsEC(Q&6QD@U8oQR?yocd?PG7CrarK}LExWFFn9=~+5A-<{Lkc8SN!$Oj1vH{TIf3X zB9`e539~{)s|S`Y4Tdt-9Rl|B&Q}Lw^o4(9`l2p-UmW}4zVX}yKtrDy0eL_A7zrSF z!X+2HI80?)Ccv!ulL0+ZZ?eRz@jt)%HTFN_7pT@7TObJy)|yk)7^&2Y;Ex+YC(^Et zw)OzqIVJy|*2%keU`l0O!%4G@X(IsA>BfG9)<%@>fC5dV0@Jg`edE8R-!wpqq~46e ze8T+{>k_XWqQ-Lxk4_A6eU3H23*2`B`LC*jNfDif%3-M<4pn>na#sG|F!d~{@K+9~ z7|xe>rb-w^>RkV#Opo9)}T;_N}P-&Hb|7&mJh zsJTL16!}v8OPO(~epN;O+SMs)=+s;7TdSkke`CGrm5uzpz{(V8Krmg12@ngvsX}D5 zY_tMolUQtk;4+-0uD!@}zArMTU4t4CQTU6r>PJlir>2J${ASW_>uEn;+Rj37|H5zB=J%U{0cKLdRfKgtFTs(%H3J5K^E0pPLf zhT?}`gP^X#B5ROYu+!we^^oH+mgXgs4tj}vjCo7|;~yN12|#~F0{ZG$m6?coy4JL3 z`q;7QJsjd6$MapqxzV232@yOr87Q?b+cY6SCEooa-Y*kCvR-qo$`l2B>M0g@s(!J7 z{!=3wcfX;Xv8!vvjktdsH&U@|%Z0B^oBiNmE3z`(oz}TstO$=;L_`wmz_nvc1ZlBr zrUL93FxfRacA@QXKc<;zz>ZzN;8XCK}}Mj7HWv(M@;AdCRw zwqL#_0pLG%uM-K%>yhH#q6}see&_0$g7V)q0c81?Y&i0tM=7nikz!PvZn?4Yqk{*Z zIQRtZ;Gsi@4$_`Dq&NEH33jtitAK@M&Jtes&$ytV1w^`d>&(yrd;?yNqAd*c2ot2- zcfjIFhNPwVI4brW^%XswB+hM?U)m$<5viujFOw)pDCUyk-7gMMURiad$@w9}0q>s_ z=vNw8Fec@_{}k!tAbTrh9COrLhGXwIbEr=o3-E(TrpC-d^m2lU9Ny zGM~~-z)&?6LDSPTw#0OppJe$vGcZ7uS0#-p|3Nu1R>J(!^UVMI$o@(dDD9M`Dpb8Z zmc8!!EjMku{r1iOdi?nDBQ#!KI{wm2`s0+(_zwvVK0yf!X+fN<_iqqD0kKX*EEZt_ zAIZN7!R+km)4NZckQhC25J^I_cAq|t+b7q@js5nMi2H_nBt6Qp1TFEI8zVzfOPXZz z;4Xx7*DfcVQc%GrQJ9baJ48Ww%7+%Jq<>QVG0bJMV-@nh!Jqsuw!h}f<<)I=Kh~?) zZ`g8UT#4+PZ{5Cq2Nit|9*hV8p(BZNqkv5ZqZyHDbC&>`4AV}(`s(bVC(tUVR|g@8 zK32HH#*i5O*yHI4PPEDa{z!nB&-QuxffUy zw`){*DCThV@^#h!p*9TVhzo3fCN-kotZ#(>x3gXW>UW&kRGQ4SJ1Noy0WbnF@>05J zVSo(1$c)9WPM~cXbQb1%(Qcg6^H4T)w<-s4qd5U&Sv>vAf@|QpOJ-r!jxt;4ZsTddl|8#i3H<;JfQu~pHgJK3GrX}kmJIZY#@6SCOk$c{;dBjM#GG67hFXA}!M z4f3!2;uo*K{>oEMpJreE+0P)rtB}BCKtI)=8BU?DX1%&}cCp^9rz%SwIX*kf+UiRj zW>HX1pE7zJK|#$zA)E7)%a*070Kl4O7-Sl%sH#eWR1&X%e;>~ap!N+xA^ZYjLtni9 z`de|ov)FQ-Hnd_dd_uO+2%k>XDz?ToiRxn0CmH= zTy~~%Q(V*fp+GU;a2NK5 zc1N2eT&GVTojtDUADCMc36KMq&)=I^dtT^d$in7Pi4F5(4lS`bS@luov=H=g*0klQ8MlQP}_yz{$U(;v)~o`P{LX zkyEov6~mNNL0`nz?|Oix1KI<~Wz;F_iKd?O7ydg1z?cFunDK{ZN_lYJ?&+S&O;vMbf}g9Z+uA5j0IkMM84KyiIWKXN~cYy|n@mQ6Rk`Mw`9l~QV= zNMM}*=_#e>y2(%kI$x_nfEYUWDgv17n(>$Y#`3*_-2;7LKX*CANNIwg!#$=0&JU6d znC**`sU9WpK(fU2L2=)$s=Ja|F)il;25blR{pX^8A09~klF~0Fc0N|iBt9VtR4-4J z+5a=ZqZX*(N=aSDL)tV zBOnC*h52>mB5(5iqd941-7#NP&yZoRO`ED3$WH3y$#5D;{>=(OY4+umfA zBR`_W&uXPwh0&7#i5&PZV*4kafp$Og*n?KRcI#BLJ(?|UXuqa?s)4s#V6e@0HMGYF!Ca^POJ z)DH>&BZj^t!0=bHkknse{`Re0Y7U9v9Up}MbFy2VWyc>3{*Y-tCDZj_1d70F8-(m1 z``?Iv@c;_y%oiCF{Q6{wcRa@9cg8;aAZfcj_{;NSmu5@=+2BLitIka%dKQh?r=<RA3Gxj(MW)qTt?8D)6Bpx><(=rDJT zfi=MW9Bhkyn4LSfz4?Q|U-HzxJWq09m}3EuX)xp8^RKNsOONAW`JYGW_>>3304M@J zn$K>0XctDthH5L$!XU8Y)DHPN7OsK~>}Gr5SqNbGyv(Amyz)-mL7^CiLFe*2_5<@h zPF;2y_ibH>!!w|N^61kK^p=R-A9h4~}YqP2JC*x*0?M2Gv_TbAElXL@` z2E)L_SU~)+Hrp^7}U^MjFasx}@@jIteeH2kpPZ@zU80VL%e{zCx4949vj`5tf$ zZU}(!`^D=WSH;lVD)cqHxrjLwIIg*YW}GGi?joW@ij;N<;1=R7U2vv5>~D4W>vkHK z861SZY>n-+5Nmd9+x8}T9z1fZ%)^f=BE+I;o~@EA4Lenxo8Mzvj~0%9{9 z<#{aa*LFR3{HZhXXSU~pDiQz$O|xWYYJpj9@b3_S1h6+=|E=oV_2fX=ERQ)3gPhHf zo*^`F^i_3+(8ld_NBG%+BJ?x_2uq0>QfGsu^hst%cQ*7@P*5`i?Jt&STKmDa+sNq! z|2B2++eASLe^3CP_}`+zG&>;31<$YpFs!lv$qYa+7Cxl3b;I8hQyo;qmB4!se}tac z$9^2F?v9g|+z?s(Ol& z|8CCN58iw;$qGOz?KhPBuO|x;2G7C&vq+6gVE-wQkKJeQOSv^kDZpT?{UGK|Y9veB zX~uu)fQdf=80=%0&JqB=ieV#AtFij%>;Gk*kMchykz2RIeogQd+pze?F@?sk6NbNy zHbw!bX`n8|br22YTsw8>N`!18qY(^4^bLJ&FOQ8aH~qnz37#^W7)ki7a_gZ3 zTg3}IgW%o+O8$T9b<=*4(Q(#7988QlG7#fWXI%9Y23ob4kiC5GAkCMobUPA3XYTXN z5lsr8epU4Z8MnI@atHn&^$&Pz5f6SVuN!YzwyM8k^eq1HQY}m8d zh7QodVq>rT!kjuIlgokSZgEFvzM8!=lV_|@EEFda-V1x}FzrEqaNC=|{AGqDpkjed z@02-ZBN(Qznq&X_!hW`Y>5+rN-!He;k{ZnOs3wdT)mn@RNDMCg7yfj!9U?J@c=;4wq*=d+`Dg%VZh{=$O(e1oO__RVfKNro zc7M*?IRdAGLMHlHJ|-Dr{`QWay>sW!w{067PUHtv=Oa6&5Jx^+^)vXwFRYq(7Kxz= zHU}43{^Th-m0H-Q01V}THp>1#6>-EM(m{eB@dN?T5D*!F=!#f5v?MArNiN+ef?*T> zBEe3qUz8mX6G8g_${QVT6Dg6ds5dd1pkho=(ATNq?xaw=>sSSl*?(2o+mK~qrjZ|z ze?Iuj!J$mGz=L#%0h0UNBGb`NG7Uuk2U!0~G66vTiHP!uGYY^=wt3ni_*0rT(tjzp zgUA4iU=VW8NdY7Pu8H~b1DOD@L=FB{+}l7hfjq@!r*UoH{5#4PODq;pNs{*X zkI0L9Hj1Lal;aBTncN#0AcV!o-uR}3sapkDaW&D~W>c2w!x>E)DBf$-vkJA~(XZt&)3-^v*k{O4CQfF1m|$0X;=*j|YMm7YkjtrrjE z;3`0JeAdRc7&icR(&@l<Ej-AnP$BrWkdoc1@Y}Cl$?7!h}6G}%a89&z%+;&gf za14MLP~W^=7Y28{@7f{#UcXjb#Ur~Di4;5Fh;wKCsX7mT;h~ugH~#T-WyC+=$zHi! zoytJvdNm*L;5qYu-1vv)sz2fAJlu#aR?LSfvUqmNjeughgV;GO+Wh;t8%2mB#&J}) zz~lIDPLKtNUya9qOr+h=Mq7FV2YLLmg=D;lsZhaTFJJ$6B;RJ^+F#3s{C35Q{o4A- zBVqkwEiA8XcKn|gl>fxm@I22j#OWnBjwwK^Rb^^0w)#OE|IGcu?|DFyg<;h#xtZPX5Frnyj=j zO4jn61o#u>=}+X7B}0+`m(qZk{}BJPrx)wdg86)SYqdz~JLPbS72%KnV;t%3N{!sR z19HD$zam5mYHp3tcLW#WQDgJ|>DPY;|07a<;cZmVQT#{#d+7ukhQ3)FH^r6F5nd*E z?wKJ@@$ZSliiUl>C=dTJ!QfAl3%mT;{*`9?7mqTf4me8zm4NyW3zsDd86M=VCuwH_ zo_ERy_`n|>3EHn|=+f{P`M-E>+P5l+jP!9D0x?4dXz;f?$Fka)r0t(R`LmzB9!;W< zB6TAF&ji4ne~>2xX6V16yKR3qstG9kDhf z8z*BcxpU|4=^n&8r$kxx*Z}A8IO7XdoyF7wr4V;f3b@6Xxk7t<`ZJ0CbTN&M!vW?2 zygdFfn|gi)@=x{y%Yo#?uq~#k?8vZ6{AAr6fGL&-U&akw48Hk9O}3o&?bsQOiycly;ompp*7o|fivPfLc>v(g z1_|(oP_MH-G$(990C*Y$X7>bpSwQ-h;dwkpzt^prgF6vAORYOGJ#X;e`<4z-0WKY+ zDvf5H=Uh?&mK>n$YWPoLSR$Xv@-S8&47RR8^{aYrEEjGh{!7&kIO04q^ITM*O)`ZM z!22=rSDcYrR@Qn3DS6A2B^iUF>i>NJz*RD*micy=Z6lm zet3SGQqHP|o~HTTAdi@Cun9a(4I~UAiRO4ieLO;Tu$U-Ktqoh$|0flMMR4k0VE^-J zp5sdNvpp7$`xEu?c16!%C;p3hI}?BPO5+x)YVi^l2>hM%Yuh?m98tW=n%fw|zL(P$ z+3iIC*w^SLfDU=70SSPX8zNt_JO9xF$jOs?gt=}B5zPKe`nC42)x@_%-y9{mhb|HD z=i7$gTs~CHWJYqSTx&dRV*INC)o_V_uHyN3$$lOmT_pOQ4coACKcr`K z82(+?6$Oi%20vL~J+~xczX*T8@K?0Xq3_ndjsM+gq+9xPE4;SK#U4@C$A4{MvM&CR zPEC78L~&_=Lfp!HlJZM5J2E8#X{u}u=1*H*q$TS9eDKX*4i1dwN2qFDEssxL+YEWM zbuJi5*TH{yFfqWBa&dp#R0SHVg&&N0F<+&^=tTl8ujm8*^mJAHeK@S8?S4TKtcPsX^{*Pu-QQru&IwuH12@EWMvNe z5%$;zrbZ~QQY(*;v;Ciatbg}q3#r0DzQHp<*R?2gPL1z8&;MG5YtWyh;2}Fh+d+$s zAvJA)uM~^_&yVo#jzr@h>;E=(pK>V5t%V0lzk>ZPR;Bg7j^W!I6%KazqX5JRZLL&B z8fiJH1pux5Y4rkw*aNkI2Owafr&###aNdOTI z$p0T;{gcgcIi7nG=1GrfkGHQG<)P)p_x?&T#a{nMLLe-$t@h9^;eW@Sl72Z~fFR$j zi@rQuY&%#m1e`YfLEc8uty=$#Rlp1+$w36ksfzim{6lL9M`R%BqIVTs=sh0cZ{(C# z0+?%$+4x9E4D?N&yvO{w_V=>-$95p{ANz~_{UwI~aDs<}uqs}gnyQT6wCT<8M@J~zeqo{|%t&)Bo+T@t!*d7re%7KRY5&-jVPoCC8eVy<_fE^Iv=xP3|$@6<1^fjEv zwv@fkwnoIyoeXKmmztyxELAI@yY9xa9F65KRTj4;pjTgIfTX{>joe#*u#FASV?4l` zr@v<>d1!Q_T1Di2@_z?2{lkS^TMu-fp!QpRW4Mw1FE`&_{+05ng+KalP0p+C!=%?` z9ZUHm;}>DB7t?)GR*iWgfHuLyXtULZJBO`X4f9u(3{FDuuZ6xmDMuk_D$}6(k@FA{ z040Ar2iPsVFrswU9l>AqW3*d^oM1%-BJ?d92HCg0N$m^D->||*s#nM^e;x!`F0=oO z=bxk#S#lpp3a+lE`dz)UVbhk|w*9yND_E@fH$WKy40K$|gDi_%$gSh~?3m;DEBDb# z!&qR`qP)2H$hw(+i8lYYZoTILkpG3{f*bad{!SQK+>h`#5mJ{YsitLP4EV$AgWDef ze*q;G0C|mf9(WnKi0pkK%{hz@?ayY}ZkHF7ltu|ht zs%*Gv^9}#~f5!e*Og8n8_|M$!ls&q@EWacp;?|Ddk*{Y1fZ{t&3W#rzTmeV0(47UVF3_BOP4XGsJD9#si;0%b)s-6j5FD{3;y39 z-j>Pe0qGPu=Fzv~Nm7B?3zXyeKZ8qoE@&$Bv*F}8uJ3sGn=f9!<+dBYsnJtFY5eFW zKmUX$Hr@HHJHBlr%L6>h+y-iM39)~Sf6)dIm%As~wT1~K$q5Mn8li6lxPLp_3chs* zow;mqbYD|=ee2c--EW0Iv~UE7)J)#J70&H+$D_m^H~b~E1~}9-L(07dfA}8>Vn39= zVvV;^ZjLu<;}rUCv@7$F|8#ng`iEsaqlrd&oc#BjZrgVIw;hUxJ;Q#do#IB?4IwvO zkg7%K%Rap|`kLS%&lmyat3~Y;DgX(rGi({6?|S2?T~J-=H!I+3dPm!TxQ|V5SWt_5 z+ab6_PY8O49Ao9iMeRSqp9-i0R5>aXNq`{xuSNo_3Laqp`tX0)``vEmRQUMXI@$kQ zZr)~_Uu=NsLTvW}>}Q{qEsuM*AeFoV(6>^J;uQQc(*@_mKXFff-t24)uU^dxknl}I zGdlf|`8EfCIu0PZ#cohP#WB%94^!juEs87DIu}3E#4}$Sm1+ zh~?YJaVE)`Du;z+vBBau^E)>AQwdo4PgH*^^1xrHvAWr=UD2#xKeple8+v?egV4=> zPDRi7emHMql`M@QzQ6B2ENmJ1A>O`HY5FXgRaig9gxUGXbCr`~dBLW<3NN z?CW$k_k?ck1F7Y_1dl(=7t$lybfy$i>~>TeA$a0lS@HjVJR{NqwE)@(n?(Pw-?U}R z4ak1f!`y!7yfee6gVwrjz6*GWdc=Mk{2ctU0g(|0zhmm<48-j%3PKO&`F8QvSwu!> z1$oel@&Q;95*46;P<7o|$2z#?#%1tl|8qJM@Bq{jkNU>RWdls3G||xhXO>1X)c<7z z5T4OBYim;*D;uxB?hNSc7ICkVE6zLEOaCMEBbO}#S73MW&}U8yrUmtZGYN2bmu3AE z7nJzKKXZ!&jsQBECFw17X*7r-oAZirpp>-v3#tFcCjTN+95#8DuPKx6N11Cs2mkvA zcraWJd&u*z+wHaMYQJf*|9#{2V;B7@M$qO}lC|DuA4UfSWun5!W~!ayQ@miB;stvQ z6=5%O@V(3FnImR?*nyrDhj6AN}_?0YgR{_Zc*WfoA81o$V9k?moa0YM@ zA;m>nBmof(W6`0Ln5rUzi9lBZI=G7+G|B<)*YF5yT>TH~-z4$&34c-Izf#Wf>~mZJ zwtrMq|A(|N2vhJ&1)hGkw#~y)v!m7DR7U?{We+M@VPy#b4qBtVUbYr&tB(gr6DyCIZI)NC?!wB)~mvsRs@N&*q3C0}=%SlGF=a z{Ug6XTe4jL&Jj?&*%79r8&Dx{aHdyuAehV$eiodUUcy{jZ_E zsQ%R?kM^vL>mj(z_)3A+zsQQu1f_H}7nG+~x7y5%Lgfc%KeW7;Q*qDnD+?U%G>UX~ zV2$8(tc!`^SoV7!i~yyCG*JOLE^!km#HhPHPTUC$WxO z(J_)-2EH!(S{;hY>B*V3tY%(SSr4*4iK7pi#&R9>C#B*gYLLg>H8!S*55V%g2z6k6 zTa~_u9zFH%QiQ;YW%|d%>9QCP*PyLHly;!eJwc90E z|5&7yfV$o|XZ#b%U2~znNHlG*HVBP(5d&cqteV}ejWZhPe_!Lv1D&CjsT9v}lp3g) zIfNDeWdLaA3w8+*1J(2DXifc7ivN}J2^RTF%5$&R5OKd4madZgQ~#a?AfaDrUO^d% zVvZ*vgu#8wofyqMx-rmhv2S0e&_To+05yOGqna_vg1;*GqdGTipP(s-J}vi;Y(o1y zs@|g^%goGv3cpL=U5CB+n-s)d!+-4%>p|H0M68qAXL1Ahe*yJx`|yDKwa8V)2jCHR zHM~FSKT`j5nDU=_QX`lY`DNBWuBbzrWFdL};yKzB*_Q6TT*;&yh1VAhj`iGu*jwLAt=y{Esi`d&cE45|ygiH^(&9S(;_!+%Ay>ecbbsw*c z#GpBCjoYf%9UZS4J5-} zAQ&Z>W`NS@8g)I0u=#N1hof>(0A)@BKO^jJY@64Fq_-0ADEpt|Kb8K3^-o`fgKyaa z7{eLbqVo?1hpK06Yb7(Fn8p$PBHYYQ&4&!#L*7~U;Q)vuCOZ#n26n->uCms=XD*Tl z=Z!a%4r@>ZjDk_cX@(B+b+G--2V)D%BO)ms(o@xM?P8yQkn1a=R|irtV!b*38w()P zPWxwPIrHt~Kj|OJ{um`SZZME4`vduJ_0QCi?g5z^Gj9I0iZVzJqQ?jO0@xY*? zH*NczGfp$o30@Liq#yDLBY=3;B>t*AWJ<3>4gD3b$(&|17E+#$0P=6)sN@*4-ZIf}g39jh^=ZG~mo7(Mb`e@TXxHdM}Xqr`P3as;wNOG89 zm?z6|t3QD4OR8UYATglv57}V!^ZVOxYHn?BZENmKwk11aWfQWHKU0NlC^Uh>@SuOt z)0rmUU|@?Sn5dYfFT#pMr#SWC0IP*&^}nyr&Lk${(_37IumCY&DNJdbOx`MH2lC;h z89)o0$_+R}w7!aX6$!xGf6pOMi2Sqo??$Z!{jv67kQ68}g1{@a|NpX_95<(*1c`nR zk{P8j)z%uXZ)s`sy$}7i@*8BRJ`ApMC^l)ZHHL_z!ACE~)o0v;FA$|@=se%6K7@4h zaWJJAy+JyF`H>)U?4+qKQ*nl7eb0P0^qV=Bp7>NLJUN=PKS*=SCP%IPL>imi9Z5gy zVT%7GF%Z^2>A>B-_CyD#-_9mHur^XO0R5RMl!g-fT=sM1n+B2eo3@t`m_g9IKb9e@g)c=P$3M*A(m5&A7uc5COxx)IKhD2X z`e#y}1OkafbF3xOR6@Q7D3<>xFPp>f{QgQZqb3;u@&7ip5(!;&VhH_E|BOk|Ka_lw z`?+!+{gQoVrnWUsAJ#NilRrCS(79*=WfQRrqOSE|6?kR1fE|#rKc2_TMDu4F+|Z0n zJe?i_bzK6WF2FOILK)DR*}x^2mCDQGF2Mm5Y2)zQeQ(ar~v9eZj1L zn#>=*cuPx5+;@YaUotRQ4n8k)P6dDfHRRiG!huib#WcyM@|GAec;Q>=bXpk}7?+>i zbmGE!`IKP9Ir@P+DCq`{{gPQFHSi2tAZFkW_FH2TA^%$ba%Qu}Kd=D;-v=82833CI z4)O(0j6R=!a{{v6_E4#)HsK%y((n3aE~HgoMtRuWGn+PK1lYmU5RV2hQyt@_Rr|m8 zgz{?+(F=E$x#xp)1?%?PT`clR6lDGl10YrtJ+f>2Dw-1|S1N z+`>FpIC9h|3;^;!8|P=FZC0wKg*jkO4FB)tB*tb3BwP6IceLBO>BkakUzXorkT{_SXbJD$ckdIZAciFoe&Z`$;~M==~Y#~*`7 zngM`Hlbr@Sc;Rm_fGS)kU1LVE0hImUPC0>s5#j(i|JUng|Jw+bKiU1|Pek#4HWC5a zN{mG7tbq6Zd;=5xGvrv3v;s&26nJ5xcZvyp;baELL3L_<8q3F2!UyJoqzXvyCVuBV zdygY}j{#7_zcy15x@bomXUNxXORZw6HqAt2f0!a@_CTvod^Ww|Tpy4G=rJ4qSl0hI z(2w9Boov;Vip^r5FUvjt)KtcQoZrL+;QKH0C)oozyE)PrZ%MTTZ^#2OYyE)D2)`lF zhM0aGB;Ce~H7=XrG}&rd{U=rl?f)FjtAI+;evW?WekBqyLDeP%nsBqU{A+MXuL_tc zm{}b?#{y9f2KImR(V(Rp3HaS^gsLHDKY`E ze`NY7i#s9piYnHI1sT9*1Y`%h73@KffB@KJdsgGfQ%=v?w& z1}c4#Jknf6%4lk4LT;bNf7-vOocyoB6z-p3Q|gP!7M!4|a^FCXwcYpa&YS*El_iZ)N1Ky0TpisU>yL~db$ z%#>F$UyK~+C;c}ZAY-zzJsR>xjiTdozH2k#Z?TRz4z75@O$JC4|EIKg_`ezhcs)9r zX3Zisc92ksnR%wmG5)%rHAfK{=fn@=>M(f{%T+4i3q17-i1 zy$m>rX?+sfYCp+a8P5RCZ!92cMG6n5S9Q#xxWd9NW(3xYFtZC^Y_Fi!#(# zhU-U>Z#S3C1Y>!p`N5mo|HbFh*%WO7fCVgo$vs5mzV?%Rs`=3wLn}0ONeg5cAP!`> za1I-Dg*e%?1n8*(?4PXcU|CU&@r`r7eeF^7y`M&w|1XF0UpV_UmMF*b*FL-T<^+2{ zo1OJDvxzV~N>HB27ybG(a10}Ch`Pj|A%9Rz)#RTpLpH710$_L`qyI(rQL@n{b40Qc ze@TZDy{i3f9Ypi%oJ+%ma|{r88>I|p_ScL6U))M6s zEDubP|I?dCS}Z(6-ew$M$+meo$b$8Oz)b8P<9^}8kTmMG> z?L1fy4ap{`%>+GK1~8iq?A=;+&(IO6B3^|^mZNDuys6wsfRRW6x9J}$3FZ>N2yu0R zOD-GDA&+^)zLMD?l1zFz0jVt*A=jyCe>y;ZjPcJ+?zhOSCI&#Ii48*kU^qL#M0AF^ z_Pc#a7lC9Szx^rN&wZ7Blg=hIr1`a*LL8v1H39eMbOSBV=!5!$e*Ok!%dS$08I*>S zoxx5#5n~MfLadM&2R8YXlllhBr?rVt&v>#t;H=d7cbBm_-dRpWs6UWOvHPdBHQ9{$ z+v1*?l@@+emklig;{11!4}uzQgsc5uZW!4?Y3oHJJlT|teJAgiU9^|LK4N0sxv4SQ z-^7F(0WcoejNqT+rvx+89O-w{JZW6hZ?wNo2ZsJUvV4>8l;!`%SR=V!6G=k;EBynZ zi!R6hVed2fKbR6FTk(uWH~`UGSw1tz9O-4`j7beV71eTdr>W2Ig#{?hH#Ah45f=vV zMZRZUGJTd#tPQ#L_@D8Ayz@?m31Wls4B6v8TG7~rHY=%(nhfbir?SeUKE?W@jewS5 z!HqA%D?>SL!bkOhx1TD!te8#SCEiMox!{PuM(uv^;{^=F+b&}N_h?^bkl>JDq#XxX zbF7KkPdw%=pP6S=U%EmnPeaInpmzH=oBVTa^EW@4J(HixCc=pVl=SujnMC?ZG4vbN zm!|tuHHy81esP>FBHwVpG>na=uHuIm1D-Cpte8zc9CMD7k8v)U@)HKdNvC-wDfa&= z{)f=_GH<*&IiqP-VooataLVtk$&uz4iH5Cq^JiFWxS=2E`*OIXwcMu=)mKS|3~{q# z82PvNQ>EqKrda8Y(j`6g%OtkdU%E!S{fAa>CM9OA!Gy^SwvLUb%@yzy{e}6Xa+v#+ zWBe$@DH-u;2JDVimN#B>F|qN)h9VZs4akf;BiNB_Y#|$d$%*VV`C@?BK;hkRz;Hys ziA03_{}c5_F)(Or&+=dOf3YD$y59BOP7z`(V^m;E9^MX46F3XwC!Kg(4 zx3?#6PR^UvI42qFBvRsrd?Wle7gd?~U}8P&OLpI4e8EhSux82-l#T1g##VX2GX9Tq zCZ%c;SrhL)X^GgPbAvhwceR|nfiEFm4ij!?cW&qWTb1J zrowDyh{z72DvrqenW6vO_@`&gljbFD`J~^ppykL)k8T!oz8~r@U$n!rK ze%lPNWikC~<7m*d8%q73Mc(|fa!vChO=Ng)t8FZEj?NU@z&(4igcr!F<;$2{atT>`;LjVw^xSEFfD0K7lZbo1~BtqWz)dK%c#6}-h~8F zuR=Z@=-289CG7y0H2q!j0fX8xvval5xdtDCq;0Fn|5L;Xz(Eo{k@X7_IqZuLQ0XK8 zOOC79i%U$Qp=|$Y<7DVrZF6Ex5&wjebd`f7+lH#$d`qzkO-*HxId*<{)+x|je`J>+NypKOAQAZ6OH!6UK=|y zH=o1b%Mu)O>u+u(|8FY?oh4gxa$;9rltXG*cEh)|;}eU`;&4>L!^sU6ao-^MAFMU= z;hg#RDL=POvUxQWgCFmliD-|G_Wa)r|K>CeTws)R`^um}K`F;=Qx#E4hMa{ejdKh8i&QCYl$BhHhvI$LMW3g&sqe~~+SbUxNE zM_;tYQggmIyQ6V7p@6Iu4)*^H>FIYH2AVbF?MP!MjP(D!@>9P3RM!ptwtL(7{|x!> z4T`rEgwoB}{{KM+{4D{n>oy=b)6i=A&*XPjQ-C`C(<5ioxz5uJg?dRm_ukdInRg*OR@IvkIe3fV*$EvD6vfn zQJXHRP9IVHd*$hb{6VDBbpE|JdN&Sk^xt{*kH!u(A9QGWh*KMMgEXKxz#Bhj%nH4$ za&g?i732(jJR+ba+&(3&eBBHExrDef{q>e7ykvfEZI_ad_`QmMzC1Udlfkil2Va)C{$MM6?Y+?`DllZSwc1{p;(-{Wm0=o*4s0pW0QuU&(e}PNy5O_uhVr zezVJV2*mT?E7uk{su&Iov5EISHTGmyu1>&p7kRboFWA_@G(Skf1D}b1gnn;~w3jiW z-#GpwHoKiYa%H|6+5gmP>NU-7H#{IRj^3d{`PU?;ub3!GGyQ+*P5HM?`x;A+glS3? zudz?F1ISm>4l*GO7RiS#0lY!5ee}#As3Gu&tc@8Cp!oD|O!b2N(YZ{30ttCJqqIL` z-z-wS`^(#u|BLkxUyS^3wa{$GMo*pC6c08%(5_VS!PPLz;XjJfNQk|KKa8>De?v+Z)X% zMQsG4;3Q{Ud7Z&XQ4uS@9QBfbe&%@Y$`tYcS@{2n4P!feBG%D1i)|6^N|FPX*W}p* z!$no6FA@ilpI+V{gg&oEhCpPe%FjiV$xzuUjO#7!>*tD;my`HQs_`hlYbB8H# zbR8=0@0au8GaWPwgbC)S@3e?Mp5qW_7FAuvRHqhpA~ zoQS`<4c}1Qc_QEDo}phBg~(S)ldqv&O~8M9iP{W+gE%1&b_0>G(8RzhF^j}IF*2I-eJ7@I#P9}l1}$oWrRGTf8u ztG2N%?hX_w|Ieswt^fO24T-s%HglDKiH3E?Fbf#PP@3&6+7g`_H zF5#z`Y(g3UH3eeEOT0fxHtG5BM(OKW{uxYYNK&2ulY;#l@a^C<`2%e7MZ1bC--V2O zef9KzABTL#IOS8PJo%i=|JeT%ATd&aO(9JzezrBT2Y~rcEN{SRKdrfsDYgV~{Y_qF;Z?Vp+dy!)=nCe*W*;P_sXx&K^Fo$b^jO)}J;6y;pb)c-f&4>G{k zd`5s7|MIg)@?D-?7Aazu-^L6WYmd`z%ZhaV?dV+2f5sl|ogM#_uK`UhFT zO9+69xEoWgoc~Dxd?G@Sd=&Z5)MK+#10V6ca&j0`OgNgx7^mv_~rdoP0Kf`tuTMsYY9^8dd`xE@Z%b8oovWVNHt-YA;twR-U(rQ%(Z` zGF>#bG6#xBaQOSmrV#&e5J<84i};6R!k;ShO}R33X;v<*3B(D2(5~n9q&Wz$%o!iJdij-C zR#%T3r~lQLRP!=UZ{x;Ya)~Y$R##VFY5%C-s&%vOuO4?LFR&jChs8OS`a&oeBa&o!C>GD~6)9dKb`n8yO_2^N*_{FGS z?%44k|8b6bh*t;r`#jkCAA7z{8RHt`YA6^pdeo@m(ZC!-onutvXd9Y7j0PwNTjY)g znu`c0K^_Ap+%hUx=>kr0kT2) zWAG=Da&taNv@pQ}DN zR(0ms2Y)snKls4wa5(s@I`d~eR`tOdXBQ=XQsrPn|J@Hor%n}>pYnQ7IZksXfzt~d zDyjPOnGd+&IPLJB0rsDPcE;g2<~VaqP^&%wqcf+u;q>X##~dFVJ9Fmr2O#>vu@62t zQ^nm`4dYsv`1)DrDPskw0|PM8!3l59O7ws3s2ub^dtoENR(GP6*mvdtw|u2=bkTps z$c&rMv4J_Xyz-|IKvrI&)3SI)V!Zj;-Vze4lRgLma^@Ft$V8sAs3bo(hmbnb?dnh! zXI{yoMO|A7Xv)Mi4NXoZN6%o--_9Y0zrJ_rue+$+$%ch;7*I~!GOEkx%+KKn6TpIu z5_Xh3^AJNsGQS+p1{;`3Zvz(jI?FOYn{ZDxepYsNZtm#ZvcKext^RC`Ah$|?inQmm zA{~KbYrHn*bK?KKbPO8+m>iM>KjC$E%wmSv`lT7wF82*>ZZsx{;2zZ2+4(dQCrhx2DlZ$xfOEN*Y;sPY+sU%BuZXe5xrpPm@BR4Wu6w&4+;DH# z(k1tHb$#5mbn)V)UH2|o+QlcXeB9M_FLy2d_}380U|q=(UF_J$V_R09kLOZn7ZSn- z;G&Y;9Iw}{_k3qAr@H2IQ7q#D{Z2X`+QP|>cMiPcYy;N4|GTL0>exiKxdhu9{l2z% zxsxnVF>fFb`zL2Ct(9$-fI0S<+&4l0b+fO?Ykll7CB?^O91LpPOaRGY#|T>o1H{Ug zF+*U^L`vZRP!WmBau`T!6?rkVif9{}0WpCcMU|CB`CZOMi13(eSp;d>`I^rAO1wxlEM_I!>nkUW z8`hWkipppoRl(fkXJ5qqMeGI0!vB{&Hm}G@a13!l ztwr8h$zrHk~1|Ms0Bz>EBVv2_0-96MP+4x z=F}o~sB=g+(8L_r%z;iE>XcKGgJ71!b74ZSbaFdvLj=S(j&-M-<~j47{%i9`FHhA3 zVyUFp%MJ(TIz{e8Z7%!2FCCN5X1}02-`5y(`ewH#|EKkeyxRY5B|SDxjUNQE{BfO+ zs~|BHDRm>~`N(KFycKk?Vh6D=pzB~N4)GYn4dl>$Dv^N_C!b1|E^^+<*}`QD>K8e? z7F8~~%eTnq`v#=b?Bu4d^wkHsn{*7QXDAo5p^R;7JVWbN!W@K(PC+)S(OKEK`9;}z zMaVv>odlSVIu zawf|nnl?g25fji*yTcC-RX}2(okSBp_<_YGVIaMHu(q~LDaiR!8w@14E@9`OX^}>7 zKCLD62~lCA26y3-ck7g9LUXBz4i1t05C|}n)yTr581-T+!U+!aN+E%I@{!JtR1aWC zVng=*Va#&A!Hu!3E4{bPEB7V+9Dm*lB}In*V$Ovtfz_-Gm$m<|uR5>$e^Q(V<&L+o zD++SURFUKva&=I)8&cRuX@H^L^FfDwHOeh1PH-E$XQ4p+p>sMJ5;5NJZl zBW+bHY+-99$dL6LOv=h@A8pRPvhu!;GUh(MSO;qXzWgayYy2ZJFcr^FGzXh+%`5QE zxxNwiFZ1CD$68n!BXkgSFwqg?h>BWFMu!?j zt%Ao{XAF6LwXjEu44uZAEJf%Us0vDncq?Hr-5$y`jEajy>f)Tz6WXF#;tRB}i;o(8 zgmaV5QU_Nek>ZHPDdfyo}wD@h;DMJk8a!hx&c z>rUWU3E*INV_s@k75q{ERCtA7X$Enw@EGa@M%dg@*M&*AAV|+x)`H;H`U2XJOs>MD zn_3LxTM5cYsrS*v;_jjrJXVQF0;?5=y_?3+cHVd^lI9O!$}pjUa{h7FyBVe3zS=G4{9{De5|MK$6GS)_JyftgA@4nfskys;}L6{GC-I0j4Ou<-& zcqu*YoMYz%$AqC0STXgt1R8M`v0TXES>)4aTSW`1gVSX>PE0Ok=p>nzED8Rz$UyWd zh2%43PRV$JcGLhZHG!nUp+JILrEBDjK-j!R>IGhZqOlyMLj%N-4@qGezFZngts=wL z+|-itlH7xhJi#Kibd@1Bv|AaYp*Rj2vE==gW3&F}es?g*w*>YN?e8ittE?|em0$D7 zD3^2oiX>7>Y!tL95gy3^>0u^sP&?#Mdje3PDc#JDGDzh_oft<7$+F~dDI^7JgS#Sr zMjqS>J~AzUBspc!#Z13aYGA~a<3~7zs|*@pO`I*4i9`VFixn!mxjrH9KA1;SXhRO( zD)uDsLkl_(S|a}X1kwCtuHe)z9NMW=O9IQ)-xz7(U~hHOB33*7Zu0rKNo}A%z_;Ff zeZFh-ee-;siIl%JmW}^2$Hl2YNb<}-xGr(dzZuOB16U2>lu)uDm^=Yc2m!59T`~n* zXat%&5lgj4h@p%5TVjo=2!JEVKJL|y_BhGJSY;!pNW4WutF{}o)W%!eQZx;DsB1AK z7@Zhcy>UEoEreyqrD20KWBKHDlmufRL| zrc?^&mY?27VjI?WB2*knpmf!o5*ykq;7`rDzGU2(`&Og~bnI-)jG7M5&FHI~tD>AY=pf4Vx1 zp-o!JC#Y;`qzzH8wzrV6!VatG-XPmZzHt-bF-L3cVycQ!V_!jXp#D) zdHnHKa*v6AV7IkPuHXmoQVL7~4lEJn0!CK{6l{Vejg0|tBV|G=fl^F0wx*B+OzXxrl%f`tV=>$Z8I%q*Q zT2S>q^?rl|Nl*t7qPQOrawaJLmRf|aMY+nU9+xG82p&O>?Vv}S`uMrU-_lZ+;7P$S z$G2mvakP=pgIE@o9Q@jPUvN~xeb;?yRt*1l=+d#d!T&o_J<7Xj zhPpkAgPP#67z95F5+q*??GKu8F4hK1nh2q%Q=x++h9!_o6Vs~rR8!4TPpMWwHnO`2 zO-Q%}I=Bfu5UE5w0LJu$cncFgevHTKnZKhbV`$wn z_pJHlqsAp~`$9aM`1us9MWVL0@4Gz)Mn z)=FnU6J=P^)}CxnMQK(fFx8@kl~fxKpf~74X0U9dm$dKztO&;VnfEw7HxVi4g0QC# z>u1S#u%%Wa0h!z>V*!0bvii0eaF-LykuLPC`c4F%B8hZsqpoAD+O##bFk0a1QRPJV zAjh)Pu}&E<&;{6J?gT9mX}-TBx1c%f9(}F$zkjZzI(ydq>zZO1pHfChr|B=y(3k{Q zLZ%>`b%W-nWHZMn06x}^EWnc14)p~Hmw2`jSkpFZ78zvJV4NfZ7vP4lRd5M1P1i*$ z@F9gLn@%Ybt)(IHznypQXbmGPQ@J7D*FRc zks}n0#Il87THNe!p`O}!TLO;B2%=`>1}ZREEVaNK;;Wj-EyDRasT4_eVHoM=>7kMmng)`|JBe^N#+pr^Wx&@yg#?F^ z(fylKO>Ok6WK##v3nEmv&;dIdC1{LuI?yY@umacAcUzDiSx+c=jCLa<^|g_<_7t9) z5~gOU`K`It?nnM>=der1RF7`GHQ`60^9)pj6EFVydedydGGz;h!gO>oYX`|@G6X~$ z8x!rxDDB`uW%lK}xPglTJ+hQ=VV zPdy0LKx#h?hf*V?IAr9C}1@D%8aZl#}2nHE{;w@`T$2K z#f(Q17>6{!WXggWDgOd95Y!)ni+z=9fl)1OT+qN^V4^cnO(Yh9GE}!DI~wsvo0F;b zrkiFp-PDXy*YLp70#%^Dg_kTCIZ`!)19vfuwu3Hqpo^vLvDT*c=B7AlnK2fFP?$)- z76}LypcTwRXnV8((+$jY&GtFj8hK*$EyMkTN5)LrvD7P>pfM2?o0+5r03P%|)|q>? zWsME|Ki5v2aP5?9ubndRZ`V$lGI8R>fx3Z#=){T9i6>4BOg(X8;=sVnn&uNVCz_kD zx#mR8KywX$ZKO(SZEkNxCp0(L%+zl+H78D7)7CuDd}8Lz_uHCh4z$<3e`4y)nh8^D z-k*7*rtZYlftnKo?E{qPz=`(uw)Pr*u8Foqqq;!4;qXQG$rVK=*Z4)P63mqDb zQc)-qpy-rqr%aqOC0h4iZFLjkF3YlpUmUvVqKiWp^K$X9i_aB(r(9(I@q@nVi*B@k z%KUoKMHdazrD4PPq-V^{=0RTgX&C?X1K;#D{k*wiAlpxHUALJU%p-iYZ|0J@D%ckd zGq?zp?oD6U4}8}J`(_~|V1k;yq|d^I|Mta;hC}{^a)AREIBOYu zxvQsH6TkeBHTIf><&R9Y8ou0R1t%}Eu9YHmmHKq&4Hd z?^<>9cUa+D)>xmNcCR&g$um~-ikGa0Mf$=;YvL<|alXdN^J}WkNhm~0Hq&4G#SFIbrdC3;c^e!tf z^8|N>xrr+IT&FLDwXNT2eSXCzE46f;Rk!d#>!vq7ZHd+N zjn&rIAKMGPo2==_eql}Ndd#|c?Gx6ddwZ?$?0c-w&Rk?&x91J(h8I4xZdv)5HR;X= ztR`@-z4Jk<`fJOr@vV1R)4sXdx_-$ztM&B1TQ|S|@7A=VXRT@9SZQ5<+hVI0{H}ZA zn050%{KmTe?)BDncdWF+>yKDXM}KBHE9eMzP4lg5n!j!(?&!9Bjo+|J!!1_y z)_ZvFb}KmTYgR?mSGfKqD>!4WRUAxOqy4p3#H2jj`mt4YM)@QOVxg;x#|DVzS&s?hVna_OY(k#7Z4d)W~>6R?} z%B7i4+(NlTkAEiX(&0R+e}jde`Of32_fnv6@9?bQ7iW*KE*n9j_B=M@=ZqZ5p6r~F zdHFdb`I0*_pDp+~c_VX1=HwReiO>1`P*9LtP*70F&iw+uF4Z<~kSxgM zff63bEhrY+WrevTg?&k3sWX@AuP7?Ha@5GNd2WZ33Z2yBbWtZ8N=scirdDpG=$gyv z@;KQL%ho_pDJdjxKq#6=+WMUQYJry1gP+cA`Z=$f+>GXs=dZfbX@pxR-(U5*~)_@Si zc)NhL0<)aCpKE zwMExWsgB2|MjN8lRiWzYFsL_#c#4M*j!;;ri{NRoX`i1y{qr-XE9lk}@_GVZ*R*NV zrt8`acmwAE#?yip3Ws3;?c?>r7wQaGRaZNj-Q%W2tLm$&stYF!&qws@9o2O=jlB5_ z4sHlnS3y}_*i++hc^v^&f@E+V+8V;iNrK)o^Oi5R&PoPEKWv}W%C(s@TV_n3UgM!{ z0^A<*G=wWco{)o9bcCzx8>lBLq-tE_ugY($i-u{=c&UH*I68;R6RHY-DL4Ars(6S{ z*6ONgJPxxPV4wr`d7RW2YH)>IHDSQd{PLG)w%^kF`PSKAX_%Z0Po53@Tevjymd{U{ z7VvmO&IX8flprG&@By;nDb_1_bLPyQH~;np3&-=Fl1Nlf z`tluj%$Ya;&IJpb5)&sT+zrHryA#)67rps&U%&dgV7w|?@4njY{@l&{B^Kq}&=6{> zhWqhQY4-5^!qSS0aCm&vSHt5`iqch5y*UMid3jQjO41^IPUZ#DKIGr^jgEQWoWFR< zf`v=(y89ke?!Ncl`{vA@zj)dG%U9f$e>XSf+mG-N!v)DZ3UWuHc8x}6kO{k@h$su6pPUg}xAm>&uvCh2Xi<1u`2^KS0L$)~usej)hu^{rmrx0g2|vU1gfPY9*%2l_iZNf}0|K;Gg|Oc#&B z|8ZU?QW34Yp(iYF0IqB`~-A3-6E;={5FdBAU0qf0eUHx7Chef(ULTp%T+GFpA-gVmz z0?Ji&aOcjQ+Ydaq=h-`+U-E)-#vu+pq94*9eDJ|l{PDW7d(A$o>+jsR4aRnM=H`{S zP_-etd9^DtyvPOr>zc;bp|5?0`EUvmv=I;nD!i*@_ioq#!*?Gz1P4@hzqs+GJ>PzL z?&9z1+lCErzekO3B+r0b35-V@>Yb6S38lqhv|?R6>@B?l z(A!|szQaPaOB^sQ&}|EG&sw2C3%t1C>Bkl#1M9cHNaKI|<#|iYH%T76@1gb6MW}Qi zrb|ht^vYjuQErLDK?iIII|^UPinv@M2A=9@JnZlp_&~Qy*EaRJp*^t&37`pf?|%B} zqXM~bBeMVfxwrFW;X=U%cn@ML3=G?7{=*5WPKf@_*L<{IR?XCTf$jmg5kH{{zFYe2id2`WP@RxA=-KJdPdz;kKK=xZH;Q-7n$_KX^kXVCl|hTx-+v^hsJOVIqCW0m zEG&Fwcut`cWa{GMLjjlP_;D146tGYg9$je;P-k~HBuNw6^lv|~als*^VEOXpsNxN~ zjPS2|aMh~EC9tTy?(VfBmuf_cp#|-J{K&}sktHryeKj_m$D2JoH@6gZz>x0^S5)-T z;(9_4m}i7Sm(77S8U%XQK&C-p_r{ktE!eUAb#m*!u@m@4Ol%``zuhqM(>JjyQ_5X zRl`%o{{8z8+X`h%|MC8{D_7{E(izu)@jiB{+z{!Y~TwQ z9(`bVNt!5v-4VS!LKt-u>1*|m4&$|p3e(E1y8KR2-Fj=8t*SV58M)6lOTNdGtBSFIJz zhqswV1Pcb<{;kJpdzGAgXI7CjbQYT@L##|RXw0StbaxUbZtG}X@l=Z{+S&*!_EdY zj{nBOQg6s>PgXo9%z%x>w9hCanhi4evt_|FAhz7-97uhQTpCc=cn$B$$xQB~@Oo&Eda{(((<=FWd~xy}?ZC#>!2 z-TC&LD-OQ#`WtU-=W`FlPdBwO-7y%jnLjK{G4l)aOOlZXaj4&roW1HTl{23@e;Q!xhqr_DwT#|QdR#isWfEv8=7we{VN z@7*zH{<0l3{!)6JYz{2qWycP^APHEyUyX*&d*FfnX{m+#hhe@{w;7ka-x-;U=ORRl zM=Ly$;U#!V7>wiJVq*Tj;k<2etz6ap!11nqMt4ey?%%czP2PFx^t*HB-Tt)ftzA?p zg}h<=LkE^HC6GWuy-hqSU+utndwjn}4&d{rw*7$icUCy6)9?!mT=+La@u|$y-#60* z<}44c;!b7_Mh4*FHW8$er1SWhQzw_1sm?+p(3pEDgagZ%6UZLiDmyz}B!)=74PNZG z4dNe;%f+RlDH!~Z48tAA{Hv;JYJ@oKkOohy52_ZGYdwV45-@0|V)Gn}$^h;uqKzll{Vg=B-mG*~Q>UzgFchgE{ z$fTuuVC5`^2{zk$D8o~vndH9j_6fG| zlfb|*zV&hW-88rMAKt%>DMZ(it($F&$>4zU(Gx$+ky8 z)1<1J%1zZPAAj}85t*-2g{Dt+z1#oZ>3&VUO{GFZ7SV?O(=u-D8`J&%`0>r^AU1HD z348l`emJs}`Cl}ItF59UGCZ%iA{6j8)P*Nc4lL5#!O$f{pTL$}wW`}jK)v5cHg%&> z`UO2*H#4rDzAnaW16b!2Trl}+n;{G#*zEP1Jx?V zmg6ONRaB$=qaIK8@Vt_WhERjtLz7Y^y2a+c?ln!orM+r`!-o%}0T9D&+o&84^ojwh zxu?4i&cB=P_`*@})65r-jHrklQ_680yQKX!{z88#eqCH$4XH`fK4etQ*>_k(xdU`7nC09PUYU3y^u*`Iy% z^I!b(7khN;dq4mA#~+grhE0W;_a53XR zuDB*ErvUk@jst(@H@`XmWV$T2%aQ}zZI?>-US=+;UKsShck1I`{PLG`=00!Vzj*PI zGpEkJ3-uJ(-+!ckFY>ct_m9tFCeGugCspm@J2&p`?OR>>>kkXCc%#vJM??4(onTVo znH-;-oYj7E@o$zb`weB;qpwkpJ-Xznr=FHcvATP8kL+^OvCuyP|MHx9ix>UA3j9{K*9=Wl;>0on5xEFin_u?4`N;4dhxk^V;q zgs=I`$YN)}(-2S1p4I;7Yxm!OzaZcLCjPDE>v!R$Lny0?z^3sjLTRV-B1y?%A%r+1fNZ&!!wL*5YcKZZXI z0AERde)^Ag^}hM$^4Dd{?WD`_#yGQl1)YaB!1Z(FXU9*UKJ)Wm{tgSs82_Jq^2zDb zXYJdTFFz|8WRims*|WM=j?&+}t-A0NQg*L@;f00kSFHHgdp<12p$!7Sj||T#WggrR zZEBo7efp1jcVkN)e1o!+(tB{lcMraC@L&dh-`=f1Gt^^&>`=wPrhM`VIO^-`@4dJ6 zv}ya5J!^n}`?2+^3Ri(@d+|Gmb}ZNTd+z$MIDn@gtH&`x^M95Q!tt-9W`FTV8#gV+ zlF?YceftJX+l32X&=)3t=sBjnef>ZC=oi1cW6twW>GCI^oHZDH^2zreJ8C>~r%(0E zRje_wuXpo;H$iFz_3YXuKj9{P=Gce_e|pzF1>R@~4HypjZ_H!(_sB_UwE7fA76dzWwo|3(QpX zOh4`#pg-~86CnG75l^|Pv5+=B^9*LA42PfIQ(VY0Nfk2ySLLwWVixwoRZZd9lRp3Z zm!6sX0t-zTo?FOl2>&x0 zc-oIPJ~Q{E;2%A@d$&Yp<9BXfvOr(g+3LGz_3ll-#Miz+4!^VNZz`uh`o;6N)6Xcl zKaB^7i7IVix7!A049|Z1KfXVAF*8QW-S^BWcCyaoh5r*S&czwS@>o;Dv`MYMe|X?| z8c9ro`@6)p?`Wj~2M=X~=-Iw;09XG}8GG*`?(f2Z_n!Uuw|Y#|QKkg;R0CnrOr1Jj z{0=_KZ-4&|WL6cg_|-l4;DE;G;X(&NKmL!3XhYTHw7}n^6j4|%V7m6~_wShdq%BwL`+jv# z9&2{aaFrI%@V^w6Ivfpke`uIIZPM=_{y_%5`hRcliyJr1zf)XWE@NK^;CXm{@v()H zETit;?d*K_)JMM*{c;1O#YCn7g%Rjs!2b)X+HM{QvEh3&@GmYXDfNVye>Y5?-TM2D zn`}m|U%yUE3%v)-1x;+|08m8xi~lx@fRDbR2~MTyU%DJLA>M|)p|2PAJ@d%Rcg)j_ z!Kl++u;-u8rp&7tld7JKYl zUVq*2{$1dI^6_s^E<0pgQ5y`N^3~JnHgA0Ik#FBI_vE8EXjgo9#dm2_8gX3Shs?RE zC4ZsNgkc4&poZ~3H6@eNf4^xDsIs;pow;u3hF!F_;G?v9%#=j%f6gr{q{lYd2)v8@ z{W9|ya-wFJW!Ae}DW(II!ug5!-{t8bzp9Z$Ii9a^-iZJ1htDEvefp3~rj8nspDZjVF(pr4^JP?YHNVI~GeF(4v4})xAZAC##Q$ z^ZMnVoM!krefpC#zxeI%<~(WBf9hw)vHXON%fTlJYW#vkFCS~{@J7k7P zjs5!n5%9mc>}}~btdHYcx>w@FTDcPb&tGgL1wq=dfu+*}n^>m(&Hc;oV#%E~p9Wk` z+2ne666)|)<5wDIwBPgGGw60a87r3K)_VAvJulB)BCTpqA>1}9ecx!TFa{7PXJ+Nn<6gigH&Yc@kT=VXfq^mZ(`78`z-ZT3=wc~9qf39D6=A(~) z4)MRk6Rd}pszc(V>0c}DkMdh~%#1kOS*1I>=aXkysWR>HVa!|8P=oukzWx>b|17^p z->OSapLy?3_b~pyhPW+Xznwt~KaZK~tMjdtXCCufGrO~AWg@Ov@xs%<2mG9QckU4N zK$q(pOT7xh2^q&M6^y1H=nHH?2APeW5fd~(b0F(O_t^$LU6 zR~Ut2LuU$#KT^ao-1K91oRv=Gu7enr>y7aTc+J1WqAfDPu|YKsh?Y0rIJg```UMm# z$VBeCTPyI@(FR9_Cwo|7X^kt?6#qkV`sW|rVb>%@#uy+Ik2O^^DzhJ%)|y;&GR5G_ z*0bgobI%HF0c=rC{|tOqJrI?(D`kE3^q9IdqM!y0u2VI`&oD5E^u7Fbh$D8Gc$1GdO5-rtea7z zyL-h_YEp&kxv{%@!aW7BoHb_xa>9)NPKTG}hq}o%sY#_6EE+%Tu~zm=pPUDqwH{z- z(*%6~HZfsqe_zio^omhz>$aX2@8ug%k(Z+D$PweN)=0pgaG~g}GLL9G=00_y>HzjX z-Y9}|#=q6T3<&>=ir|6-|4=-uS8q1HaL5+~(a*3Cc={MNnsC7XrFAoYvBBH3@c!dC z?4^k4zCgCC=ED!sIH(*4v%hKw`me;nYVi2F$$_StMP`^0w%nb5cIB(a17^Sr_&!-3 zIH1HQsaXxFv=Ru=LdN%I`)Je+STnJ8hcR8aTmOHUhyMwMOC(ZAZ-N_`)ld&BwQjGUI&_`JM7^$N^__6fUXA10?^GoV0>(SU?kS6aT1{IhhI-{xDDe z$B+l}KNR)fm``9~xM4giKn$e5_4R_93&;H871_AA$Mi> zHrqpDQ*UrU7jLGHo^Hkie7ZOlg~11T@;Eny8|rX@Ro<9WP|9jhT@&u`@IM;Ar}2Q> z^skiv(==<^|B3Hs>#5U>;zJ9jnp$I@5Rmhe@<18^{GXypben>4F8?dBQOr529F9ut zUvEW2IL>hBEq&jHuUGTP8smVr;TzYNd{3uN%bTm3fm{|6tG3s_5Sh+dkf^5@!( zzx8LQ9^SO+oRbI#&~p#Vvm?uIo9%u#-d`br6SnKf12CTv*{tk{6(7j|UlAwbhL{`w zaF(A5Q{yXve`CZW(^4A2yB|n{-)DQ@L1Ev%)BPJc+!L41e2Sbpix=~E=K)W=~ z?gL_i7_e{OmaeT2Jf2~zmd97UlT*O4R?Pmx_2FvPpYVUefIq~Ef06%N%ra%o;jP52 zpmrnx8S?wzedyumPcB}9o9NEpEIWq7X2+og3m#pzWSP8cJ*&0;!Tm;2Xt0p0^2mPb zWMSH_xaS?oKNe5Dq8%f{@CD=kioSKj__&AlU!y9tQnDtq041ej{=j7Geq4Hsmn|^m zwfl_&X!-g#cRY=E3EvWSzt(?@BUr>6+|BwAzzux5_B$g91q~3&iTztKVOWlrs7$

Y&L3S}^sn#Cf-f`&Z?``iz5o|_N z6KE#r6uq*Xn_mCY%Fe2hivRIS{Zx4!z$f}3TotVgSA{%j_^bi;X#GzvRl5}h9k(i- zNt%(>|F_?MVY${jjA6NJ`FdHo3m2}FlX){TYcD>6v3$YuN7@KL*@LTC|EB-3{1(5V z!7<@R^dIj3s_|3nqK>OFoz-6dOyh6pK(6-fRdj(c=-qt`e+MJ#a!R<#{4&i z>Z>x-qyUA5_+SvgpKmX%am+S%FXj9XW0#Dh;@~e@| z9@ZcggJ%HBvd6WwaoGYEpeROlzA8JxK(<>!E?L%p?Y3P-Y`db9tDSh@T$LB+U)09YS&!GHXJVVJ=pKyLC;kcq`?`#=lSbRHU`v<$*(foi!@Ikg$jo12hn_$^ zu@H~UJ^7lk@UWh2|If<38AX(?2uil#8l@8APf&k^oYCPOe%5~o3XVp{kFN@QuUOOF z$I=0abG!YZ5o3W@L?LcHyj$J9FTTVy?M<1K^6xyeXU;d5F(X>Op7np0SrHQG*qb)l zL_vm;1_8xiIAs11XYGs(FDS$pK0bcKx8TNA0zdeiK>$1mK%&01R#x{z{)`U><@5Hj zJLk`v%cM=+f0r>H?Ug1Fu*pDqW_YQEfi)}Pe<8~M5B$mhn~VMHh)%7FM{6ps!px`H zgs`zA^#OA}6M{wr0V`;x{h21I|5M()|FuVt-H$DdkJ5I2X!@t&Zta#d3+-wU0lMLl zy*c?gjDL!BuXfZBe~JC;sGC|hp5AZ;;5+vj?n`m$36!b&4b-dqDmr3y&t}_AWwft( zK^LxHZ^OsfGB=A|eLQZWse}iN+@jHt__GqlKaR)x3Kwhr%N2Hn<4rd-gq>FywKJsc z^}HHWMOaWP^1m53B^(!Mn+Loy3@}%*qrl9~@PH{R_}j4cuD0wyk~^-jG*rRhOPo9L zr|5sizgusZN(7qE^cll76T-sX1R&ZaU8(fH(Lb-fphX46;cee(CKtF#u*8W#w3WEv zuX&XUR1~}+`1`hW_Kzk0&{NO)Gd8dHmEq$`Dscb3RYf?cGadh!9&>1ceub^9U5n1M zxj+Du^v{8`5ANU!xmCb{(eMSPH^ieLeYTzz{O;9zfsFc1j|9}XkN8uC97Rz$4UPi; z@JdFXXw@I8n{de7oEBBxw;!XobKe@RgB#mfkr~vfYIg#kxuW!)ag(C|U)!QYcT%TegyD#Wvhsb zAdnjk017=lhJO5wIQ7uKy*T=wyPfEBjR$7pWFC?QDM?%-1WZV+mTy_bCH}V55vpn+ z{#WsjBbf^@_z{jCcHAshN$hDWy=pj5lVelPH~9b1b9?6h2K|H3Yh`6S8u0lgCIW(x z6jL%XtH;;uHyz4!LdoLTk%g@IY5a*+v;IHQ<#2>UY(FsZ*Me?fgUR7;mJ!5E+Q6PZ zuo{nBLn<%h1E$Y28a%RR?(N^x@Vh=eaTHvrx1aA80-8a=d?YZJ`3D~Na1)a*mWwSUdZKf!M`JJ7-4iB&}4_Yi!yY0sXyCvnpOZ|Bb4-`VuY zv;Q)0nG~QMf^52}!65Ve16^Ct1I(cg@7uDE@gJ8v_Gh>$MEp-4%K$8Yu=Azb>qGun zW#6XR^M1Acbn&A_EZv&?1srM;xL4`%#hv%~JYux=99P6K6 zc5?nn96%~&jN)L~KmCb0thqhCcVPAEZAT=9YTeGVoRU(4f9jgd{)1s7QO3Z>9BA;? zn_GARJe@vGg^5M6J2hUt%^TV2A-9^u9S;bruRB=(Ll;R}jrvv3Cs=pr^N&A(Q7HKP z_7&%{9jJo+7ew5+*#BeppET4}Pjy6pn9q4?oEk_OF|H^(GGUyK`J7NWqH@H9%3-ez z%YNmWU;p{PSRugbHozrv6uz(j2Ibe6zVgbjVZ(+GpD-daA$vq5GJ>Zg!-kEUkgaMe zD z`7zVh#z<6@~1-;I}XV@c%v1*USz)?X?1O7|DyEGA%ZJ`cG!WV$(rq#*ElB{M9ZK6`oR1Ws{%wX&TCfIvW}ZvxhKtrMaqn6PmI4 z@%R)@xVT9B@50ySHz$Y!4}}4abYh=_fJi4)P8$>1gol^JOB>^_WIvu~nzyFL#rDhM z888I=yc|5}ts$bA``B{E?P@--;6F8JN20xv(d#L7x$E*LR>vLM{|EmW46n}n?;AK^ zJ0uK3Oh`Qh2h@WCZ-EL&7*nkw>L5TIw;|i@ya7Cyli9Dpb~|S*2AUq7bB7-tjiO+- z3icm56kgN7)|xQ>1zi0E+ku<*AM$j(Ha{^HfW;%U|FZsbmH*w$jb@Wtn4ODi1rU*! zgwQ0$3AXC6MFi%sQibbCyBvWH!CpRb6YvQp06$ITnc7tc%)JsNPqd20u8u+w8{R}q zDB$qa)lQgLR~1M9v;Xvuktrwx0-|xmD-^z7YxCL=R9#)q({Zg%f!kDV3~XSk#M&`! zS0%R8;7FiCO((gV>$+3FKtGL1oC|^eT*uu}!*VxMtpIWNlxQ<2Rs~#s?Y}MhZw2G9 zaSu>z(yMOJe4O!tJt_>$tdq%8!+0%=74Te$z6FM%K)?g3Z11ZN*Rz|fx=GM6EO=)| zQAJH~hH7{m@(uMGcaSSoPN=QO{RL;`sN9l*|EYs^m>zCm?_)i~V%>NK2iV54bQAS~ zM-}!OA?iSell3qPnAK_x`i#DcBz2u|eSJK7LmWaNnGH_J6tT_KaTrU;bA$GDIs&v5 z@T+bryuwj_(b)X!*+&|PSHVc?!7VuzNO88OMbXjYF_MHq9qyT_@v0keQ$iv5aSM1c zYZag2R8<`}qSI)ZYOoz2S4g)w2fko|b3+?I9Z-%`GvoGF1U%R0E-Jq)Kd7ycVQske zvdxy55HYg436}tzp!sOeIzCAXbZ9w1sx(;B3=mb}Vf8RnkMO`9*j1(e!{#zYSJPhb zg`2{3A#}Wl4W)Etm$nkKD;F-*=3Hi7G~$0pjJjwPW5tL_wqE$-WkQ6n6pq0ekv(D* zKTWujOCv72Xv9S$MobtnOvmJy`?I+(@(K^}1HW?hq7ghe%sig`$}ol`ZZvh7i`Tr8 z&5$%~#Ep@QMvTg20l4sffddyfaDf9CIBnNFac+B_WuQAhIt4vWkF$$|8yokbOss0-^=0*t+6U z>sGK@yIAdN@9yip_P+b;zXq&XU?2C=ggTiYY^*; zuSg(*z!V}-Wsuc~`6W`N5K(A0;VDv>xL__p8Dv#J65;uoh%hjTNKN|@k1Uw14o)VD zlxE_tDPv-Xt&ZGI*6FK>II5WVr*{$`V2Xts}SF7ACbn@6Hik; zS*_Vc+|)Y|cWE~f0d`dB7-E9;F|omdGCGJzxtRoQMSQKzO~gB~g@_QpD=7OA2}9g3 zd3rBdzFLKQ4P<@(5fWZ{ipUaMaUEphi+Q4+-pOsmH?@bj>rsc;17uB1HCeamAX$T$ zV4>Si67BADBoJ}QXxy=g?I(x~&--T{0_<)gMJzM#lwPvNaDcdJ_8_KHGm&Q;LTt0+ zBrtD;1Y{o}0b2$U3#yg~B6btcgihiTx{Y`xc95XLR}e!A&maz&cQXAQF{IK45Swfe z@yw1BN5r;LZJ$6)uB$}7<1|rZ_5C}3m~wQAi5;dz>@cs^^TfaZ8WY1Ss_-!Jh|VO^ zm@UL>V*y#KP9^@EiikI2T6r6Ch@P%>)e9QfL6#w|mm=>3 zS?Oycj;O0V>j)ETj^`T&`pqM&yh9NeECuwDK|JHP6Yumv688FgBxLL!(O-W;TtedU z+acm#a1u1InK%b-BuiI^khSIs#N-PmD?C*saNB93EF32Sf5hU;>>=#6O5(IuL7Y8< zNGM{|`N!9ypR0*iOc`0_xq-ao>_NDQvBz2)PF%b-e{caX2YTk96%7=IAYaUdU|uv( znDuM~{j#=3gfQHkL*J>cK@&b&&z?hXJ&#B58835jAp;XAjD`WT21rYb7hatE0>Xe{ zYpU(MdGqmM9->q*;kyv4%YHsSFPw)@i09>i@3xEV7cR!Hw(}P`;LgJNwo4Y`DJCO! zm(H7K`_jB6_@B3A$%2>Y?~V)RE?u@{Im?N~a>C_c!*X&!#4ra3dm9$p247ih4wvoV zz-DnB@T*c_9@N#f)u8hz#(xwB@)c{p_ODj_w+zQms*Fw328JM=0coIUET` z6s^)pMeElGhs10QS+8Fo48S5$$c9jq6dbKHD5C`ul}afIQt}0XEQQcfEtgA_0X#*l zU6fH7sqnD2WjT-Mk*(AwL9&Wi_O8*gfE!fQ)wYg=1;M`u@lcMrVx`uZCC`a1dt4i!}v96nr3ZRqXo z?QL{B+skcjZOwxX@M{0~QwicSZ zsTqD)?H$8a`wB-!Mkss~c5L*}@dA7u!Cm;GGT>=F4%V9)7=xuQE()b4$z3BqVQufi zQ_D<7wfjIr{opHuXhVG?b@7^kPs`{V>li=z>Z!wr51*!=Pfi>Sgz6)MD0?Q= zV?7M$1VZ7Xh!(WBkBzmTKUG{@cz(G5*rD391;xe1w0Lw9R_)x`|ypxl{ewgLC36wN-^&@g1aV$bGBM?|PQIFoCIBaV_Qgih1(Ne0z4FQpJ<XCG<6db~?M? ztfq8N6KID4kMYOUe5U(Qz~n2p?B=@!D76v^>$cTA7C%6id`GIBXnkdp!4Ojs+6^dx z0&nbNP|+uIP*7%^RDBd40k2F?n$7iqZpJkR{T}aT2wk8Mcj$#l_XVH*bP`Q1ld@ zL8_a>@5o4RHO6#fCv7B6v_3T2p7($_dRilNRxpP0aypPmA2 z(A%{ub`D~3phOlVxNTu;gLzq%Dq21Yl3+;s8b#4eF8VgwIX2!u@OtiLfSe)trpAls zdkTvW4}us#Y83r=2T!3x9%yU6Wd|`#=zdAfzina1brl53RFZdg(gD*-JK@^oq?sa! z4mIQ-deC|7^`gr2lq1vBI5u{@poexeU{kW8wE(eUxEw?S0RM`ey$g^cRRq3!!k+CS zihl2sZtYGCM>-ebwH+-$m6*(f6Xx>i{;taaSUm&3Z|wSTK_R6i3Lk%zAx=+YmjK26 zK}@Ol?CjYfOR2>1-7WLE9KI?gC2;M|7D{knC!oh`bR2-_7^0pSDxa<@1WT?4ZfOyK zf3dh4KQJUldkNsj8R$*Tt(a@>+1a`Zl`5H3{I2Eu4jhq6CQAf3z=S}_J$Z|_VCL7YRA?X+Y2+EECg+;d`ym6<6jiTJklLN-58nW9V8 zmSdWrMc@V9)Q&!265yL3JQy`IHK%N$xec7!JoaCGp0HzCAC zVc-XI=82;@s)zcAp5-$TC;(bW4$+& z*-2yL6(?7&@RC%aaQR@)La|;T`cN<0T7k;XG=O$-b93X+vjQlJ%;pC};BjMPePc~+ zO%y6{^BQ{g0mzvmugM`B(fST&-S6h(A0 zn3#AlIyyZ%-Z4BpJl-)rT|P}ahbeYwl-3>+%y>t~SUW8O{Na&}16LRaq89)@o1@q1 z^=`qtk@@6I8Xg~G_*VmF91LaD9#9@%z4{t_R66^wUcLHwdV1&qnuMM&9~$fH81C%v z?CeD5VPLVT`6K(q4jidg#Swn+{6dxhGVx}wggtOyIrp|6I@M=7$+qvZf!Q*^d6|I8UYaOTtL2M<8~L(^vT zDA>nnZ7%N7bY^(0@zMLXt`d-cwB&>57dwQe8WK0hcYpr*=iN`9e7^5S&y9UmRR#OT z(1NB$^E7I29(`Q$Nlh(8^q#`PQx^-WKCdd69;MYcLwH&@!6d{b3{q*J=!4k{T|+`7AAT63 zs%UQP=_v;A#-@=G%uvO}9hi7K#)htzKQ5{HQ*B;1;uM?)M>da)fEQJd3{4MWL_)0S z?|RaMe5XMZr%&~qDn2~IUC2#Trb+?>-?d)o7Ay*R_@zj7wQsz;;1mE;v=p8~1Bx3# zMtx)Et0f=*>Gh)g!o$Vz1;Wn7V-L=s??L$!AOQ@vj$!Bq)l?pBZ0s1XdX=)O_w5BT zWooMQw)G&EToi#fi?R0@som^fI^2kD#J*UV0-9@fxHw@0gNX;zk3Y%pE<9X)n4$-N zRFnqS?i@JuX)T^ZwrX1kS6vDxI`y`-t%G>IG~+{kY7HcB20nclopzauQnUe$kWKO` z3s7ImO3f1wKE3+!@h9hJY66CU1lhE60un}UWfgudE`}{3l%FaRNItN(wdd>8Kg?L4 z{&DBg<7dvJZ&3aA@y`DIec3YMClSjL{sTPNU)pzo>V~`i_-)BVJj?Sy} z&i(rn6hCJ3KM-Gb|+)^Jh__23$4bkZy>U6-* z@iRTB|JYd5SpTtOXA4k6I>eegrgwwFnflWXe(?B{kMo!((KgKWCnrWf{SJfs)ncmQ zP|e^YYAB-p8-)2w94yhNez^G(>c0)0Uq}gg_}IYf$9sTr+I5W&KK{7!4DET4Cb+`% zCpBN^KA{slRll03Wcpq0*~^8+48egS8b7jMWbZ1wq*8LAKRO7cszhDzrJDYM+{ywd ziO6zv0Q3%k3~AI~y;_ognZn0BNf|YTe;Hqknc;W6^H^5nDf)-Hyv9a&%-?!(c zT#^bzx97ai4i(APf4E+E;n*Rxk@hcTSh-JtkHd|ajs~Xz@^KZ#&tb5f$6!T&s;#8O zT^$+&3juZIqV~v$#sE4dfgckd1o#HO4}G(l8^S& z4f{>za@6_paIN;OOPr#_RA!1^0@91{8%M<(LLqvjxccTzl+X(KL@bb`N|Zvt=Lke8Kc(s;%BdXz zIHwX4q@^)N%ozf|d~HV1nP_Zo?4Y)kzA@UUnPSldh+#8k0;*m?G{gVT4)*NmAdN&R zdDqI8&k_9eUTShIm2W9*a0L1a0Tg04ut1q62ngaEL*JAqTn9ak;zs=hqlrvTVw_Oe z)ELzagTl{FVzxx1gjMmjm4gdklAJ6vMDC=8Q}9eH+9#)}3c&mW`s3+gNGvoluN^3W zX~MHUm~5xnX6g?ZSM1oX(g3w8An3NGE%e{ypHvV1sQv}vpH_m_9@(k>LZ!nYj4#M- zkkC5m_KMEV;qmbY=wOOBw1Mda6u`iT{?pb5`J5G`R3@t=Z(A*P3XC?rrwV*$^4vMx zeEDV6q={-sX#Q(JJ!pUW>eT_rXaAj!LQEUN$Y2y4=9$UKYiKrAPhhxfxo0<@B~b=l zie&H~5cK1FDN?^l+C0F=GpKz7g-?|qlu$l>G%qjjEEVpaB}i!<7Kh~cUN7XV7hn^3L4c0(E_G=c!B<6&x$t5l}hE?C%7;_sIu;;-Z4Y<25JsAk55y% z9M}Q&f#9LR>%*Ow3ohQcv2Wjv!fL7~75Ch@c(JE%aGGk@4D~W}dW~rSVBE9ga)MOS zNR_0{(w-xfM85Zv!E=aFFWTD1DPca-;3G61h`|Y&k&aPjlouC5Olx`t>NlE7 zYXf@)^lPwFTE;CWHYZS{a@WBA;J^`RBa<|S$hTnIF*8$N&|1ib8++<^5Q`kZavdccgDyI*5f*S!Slndk7s1^8;`X;{eEx zsh61=P@3t$XapAq_huxDvEk46Q9jdj@FX2zXaH)1SE%r)B8Bh35lYn>iRA7HTaHp< zNJ=sM0{c>1%M=I`L__I@HXRlw%Dpgh`^Nj96cmF^f_(diJ5S!AEE=^P2Z~S|+Fq2w zv|z?QBT-6CDr#SHktp1gmD=S;8Stn*eV9>-hK8uYVkV72dbv!cjrZ5S&wQR5o=pmjg&V@icg6)n7LHJ>My$b2rTemUAQ zh+#EjN*knhZu9tzZ5&^Bj2KK7ZEI-;icouMBBSHEVQA{y ze%O~ZQe~Vw=eFg17oj%UCt2e87R)Wc4P$bkbuo7^23$s?M*TaFo;^e1_g4256kMcq zgz11v=q)WBs1|a}zFk>APO=Y9Yh~+(V+HzPTNgLA#hq zw_u-lj4(!+sD0Z}>7HqdP^>ue>?VEU;7mRyFU{Qq@W-~Dp&AD|10rER>{(PGL;(~$ z5);@5Szm#n_=26iqdX$n7{~g+68KS@OquFmj!+Cz`fsQ|$jlTp7ZQ++HJzi!j$uiP zO4pQ>j&6HW2x%E}@r;f~4POW8&|#`Sc*V&{DA#BrA~FBk^BfhCGLsbbf406ec#yI3 zQBK1AwKh`o>cGHRsG+c(chK>bf06d_Oz!}J)GFB80>Ys6AFO}F$%(_m4um)f?O(Zj zq|vBW()AJCG^6%ybP{7`I@l+ZtFNaPoEEzO8lw{?0x;*X@y_GWSSg~yX?l&GidUWf` zy(={RjDMt$@YDBy{>$exAQ`yNUOr;dBbw)D`tX%2_wL>M=%c^>_0gj@Tv$A%EZJQd z=z;YSN43P1hFJFwbBtg7FOZ<$I4$_Y*_zT`FE}ZyZ4!B3j(E5^vHb{ z%Zr6)Y_Mwm>pyBFj&c4@QJzYu z9smJH;KIjJH`_(bcW`BkyD1^%A9AsNnHj0G-d_V+o!k=8O4Q5O)>3 zx&{Xeyy)sUUc_#0uCAg`HxX)qrFWLCJp?K?hlTZfjw5j6D1XN;R&B!i;0Y^R7mn7? zDST@{q(-ZDbW|wR3OR=(5OV@~0s%izC;>1x0Tz&hL!yJRye~%eu~Z%$jJ0b~pnxw9 z0tG^q3Ja!6iCQa^tEK2gb(me$R;90{(}89F8l^(0Hbtu8 zg|CV<%9I+7(iGtynGzWgX9|!;%M3D=;XOk}VzekaRi~FmC#I-URfZr{N^*)UTBT8; z$r7b3!e~-TIF131N|n%sCl83V!&yfEEOQFi252;D098jCBeIerHIW+kR}GC3(L zGbvef$)G|?1+Jo{`b1TtUK*rN4FXbv3~^beOp`{51EAd1m=3i{Nq|fZM9GEf07pf* z%W~(r3%n%?btIaFj@6nXO%cXOO>%N_gvn&Q6p>_%b5AxYRhLq-9zINYD0?V{LxNN# zGu(N2Nrgs9m6sw6+Dml%0ott8sHH-9Dme1^5}{J=D35je*Ne|B{mtXII*;FceShXN(~ z*JfP*_EVmVFMp(Ge#*;)GQx*1u@ihy+3xEZAKqo~t)%A&FB2)?{}_&Qiw!vA*c;~< zo8ae)^N6E&k~QiQvN{}Rw}$5vxAnR3JKo9o6|dD)5O>@chvgBs&>SK)Rudmn4bD9_ zz)yAukta9fw_4%}|KoM~J!GAsn(-xe-&jM$fZ-m!8$O^dL>9jvez^UF;~B;H5BnzI z{M=Od6T>Ii8~(=<6a1FpQ|txbWiR*!OX6E_zO9+Kn;IFPVjn!WCKhK0!`E1raF7IU zJ<9kpE3yZPyLvbAHUUmtC-U|YpX8T`G`5wj!@0zs`UYH0#6t(4XhSPuD|V9QemjUD zY(H6R>V&WK0P%=9h_hsOk##ZkM2hFvzz^CFKFa=?xEEdb@3VoUw(lp2O@kyEKD+ch z;DpA*Bo6N(+vDjs7J(o!c&Kr)I{+>Bkczy03#wXfc zQ%%D1t4TyrEiu;hk@cl!5^?2I#>baA6L?Q63CEehzFE~|Z9)lAjo)Ydc9UCzIkf7~mBFm~|e3hxMupEBcNyw+U{WWujuy@98 zqMQ1LglyRXzt|l_jdJOk*6Vk+62IJiBpklXCin;&AN)-8IFmR6X9{cKiyV-_mY6Y8#tdBaHhURUz>4O z^$_Ei99{sQb@*0qY8)it6)ntJ!WlRZ**B$xMAP$yL$;8Bv@-ZEH#2_TUho%R=AB9W z>AA+~<-`sC+G})~#5-XdS?QxE>k_(1IL=B|;XG)~#YcpP^MnJA+$8Jq+lEs3t;083 zhxV_M$B}iW2I2$X;oy=+5{q_n0*#E%w0Cj|S-%VCF~h%jm3%YdN;PCfa5V|p(L}u3 zFA$$>^x1_+jL-hckZK~^Qbl~>Yb}gQCeqY$vNE(5XBa0iXB2yNU4rlS3F4DAOq@e1 z&}QJym`9dMld%sVldO?iU~H5ktu$ufZtS?L|a_$k8=*@{WCaLBNgk@gE6aNs1qETaCza3-F=m>wu;XSZnH zA~+R0&RK%p9_Fc|i?qrWU^PJeuI9k^d7Ji|~ zmCxt6iC42%Q&--#9_u{UtmJw?nsyegb{09WW-oX1TJ5|{;O)b+wsDpD%KiKU{1tx6 zz`!6CMDdXI8^Sh(<2@oWGAJ@oDUXa)1Vu)vy*19WX4#9h(YlzJjX0B3Z;UnSO>vvz zHzy<}BqgV$rWp--V|seJ-ndbx%kb68G`v|(qRcJ2jI5aK*jRn6$z;men#%Z;7Huou zzTIThmz0*K8?$4wGRk)FGktbiFX7|)tgH-OHh>$-a}o=1%x2o2%57C?X(l5aMbpy_ z*)h6|YMmWln>ovxU89ZEWn}1dF&R0AlD&IPIf;d}yZ7ynPpdPPGZ_pUncD|;ILmyj ztZhV@zV$IWnzCYXh^pR{la#-Cb3 zn~(r+nC6z&a#X!UZ_LihYHQ2T#pIX~aKU1Z6JNGPpL1ZQ1YM31^??~7zP2u*t6aY~ z-O$!eBiZR7s-N3N@8h-9-Xc_R&Pq^?W@|AR+rXl(x)5SGODY4ssUZE zH*=i%Jf4%QCbBfWBsL}{qeqvatIlcdNRIFCZ|(0NFy$Pg&FazBAIOO{<(S1H4UgyG zdiZ6EWJ5RFFqqX--;sQz|7f|XYpB2ZP)~JRHc+QC8IAhAX10hwXO7MA$jc0t_1(Ja z>|>+4<41DqOr{eFuWU}M8_UWX)YZqBVq*=Z&L3Ab*IM?6BBX( z4)tHH70t0`zqaA^xU(I-ad8t}MtxhoZtUFg^XJcM{iMYMS}j4 zvyX^p?QmxDa%%jQtCx#YlT7-OWA&%cUwdO;-LC7!*Du!BXB*$VQI&i1a`EK^{jI|y zXWlIK?K>fFT^^b$oVq!Xl#r7%c5V7@-S(3w-+pyh|H*8FKJH4((ZYMV_tO&JS>q#m zVClfQ^KNDQ?%nU@=kBUa=rXmQe?PVM+*tkF=dah*>G$qUygAff_`&{%b#))IwfqNj zY&drw?SG@LE-9(^VcqV;goMW*Z64C~jGg;9zOK$>EN@L{&;KOl%I>tf4_TVk59Zj{ z(C5?A@(U}kqz#x%t(EvPhUc&09mH4A`?&A!L-a-0%=1p1*FN1JKefFuX@7i6^IpB_ zLj2U!*x0$ZKf}AJJfU}6O7Zr*y!@n`ckDAo;3sD$KmFvRUA2Y1eZ_Tk2E*XT@wGS4 zojdvYXCLjZ9m`2P`{YV(ZBkMKef|s494q#jKYdyB#!y;9#~W$=dc#-sUth0FJ9+Zl z`D>{I{V~Uk6R9`Tl9DQVuMFMd@cDDBS$8JCDY`s0m2kO#%BcUUURQszzoq5k*XOTH zP3d&?Svg59EeRDx@p*aAyZZR>EZH@$-5-Ksx*r49gzoJbt3Tb3FKKycSbxhZ%Qlry zVJr;vmwY=cLj76%JHh23Mv7@PM~k^F`oZ14cXsdsg;nbxgbK9v7EMR zS8bOm3s3iC#Kgpwq?dl{td;TRi1|MS>A_EQ)nJieae7m0^I#5}FN-wh#4sFAmk|qsXl+VuX-;~psc!rBa(yhg9?GC4n9*MkW{EXl zD0Av#da|mkGqO-@$zIdhBd-p%H{HEi*JUyqVzV-;vuF`UvyYEv&Mdae$d-D{2H@yl z=?#VwgDIi%jhh1l4VUv0x+oVgww0lTGTi|)Ka+1^H9R5<#M9mQ%fXak(4XikitleO zEc|((Kc^g%OL}Y;I2MYq<9{KWWi{-RxrJ7~?3fW#Lwfq&^43ql4-4Nrdk_>7i_SIZ zH)en_Wt^&!$t-3q*J!t7WR1pT>(M9arRjUWzp?Ge{knVmH#MXUpg9J5Z7j=f>$c-( zYUj*y(qu-0MQ+4wWGvZ>>cqWqB{wZ?_rr#vA>=oJa~ezZbiPyj$ZB}j3%q{%<qN1zy1A}`8)nG-%kAx^)J4^y!>ls4QG}m+ei3MnNN++ zkFLYRUc+9VZtUBL=fRb7Z@aqIIJ>SMX0ca$4LkF__`-k5G;?^%e)HD&@cH~2K40VW zqt?fjBjWSdV4`>Bc-G)oXRl!qUnBBb?d7Wd*AG0$|AHuxsgeDVsnz}<`)Nd`(fVX& zikvkf5uj+l&}M2hm`9ymUHM|KAOH3H|8nGg$KyTt{nDkU_`CG{rCYy0f9ulI@8&%C z?)l$;fBN0i@4kER-~k?)V`0JLJ^h~=(I1-8f8PHuVu0$YY+U}h{;j84;maTCnVz~_ z=u1{XZe{dR=%;kAsiSKUbkqPwj$JB{K@Tf{9=8|zX$AJu7Bf1kyJiQYkGkt?i7RAb z(S`y>=aiZDGCBYodal=|dLmC~ApU7xjP6PIyi%Rgb5k>M4%S0i@mU2*w@)gLbi6`ej5=%$5jsB zX7nfDEp5anvyHff6%pmJw@CDzuZb$B6Z;(x5}B!-c*jCt#=csro6|k9Ua`sZw`pQ;D&ke}i$LK*+*IS4Euz~3ZNc66Q(Ea)u{g&#pvCs|Up%aJY?IGdN z5q;xJVPl9uo6Cu+=m4{SRe$#f;-6R!`v7p6-i0<-5%ta{?Bj)Q{ptg<3A&-_{!fe^ z7E{qo6v-7tp4LOwZrnrsvWJK=!%V2I7+$y!y6R36n7o_OdFftfuas`+woN2#`vDTQ z!%S4!(5;hUhcMMaFK-~~Jsl(<1NIH<>-9-4B_XAaBy>A;zl0*_vNa@XH~Mg6Gf|D) zCLzbC7`-v-(#MScyLw|b;fJS?@Ey%0^vruC40_}`eI8j8T}4*MbwSrFAd%Qx%iEAZ z0*>A$GU%;qjJYKG`WHlvJ+WbcP4!D^N1%EnXYB^)tJv$Da)@w43ZSQdP54o%L~&w@ zxI&lpNbDmVRUY;+?^|a6U(6c-y=TpWn|5!cIdEQku~~k;+0fFoKd!H z;2Kd^cM;#s<-`;A6LDMzSrw84-Mbq0jeJJ$jw;$q;5tMk$$gAoFULOYP}m(5Db+-> z31cX(hy)d!AVHv8CG=3uUhF&0Y{Wk6Aw08>_(IQBjlE6$HkXmeJ)r5rF=E^cJwIU& zQKj!EfvI%g`5w?;8BwIQ5U+$5#?Iu6{k4kp4n{v+;S~+Llh+Ix3LmYl zEvzi*7F$cpS+gu=&v}kfO`m^$o(1649msfbz0_p{vS@2giBVpSR=G|DKdQsRIbjV4K@XMVN<_YFD0TXQouLtM-+(C7jSi}Zzs+g3Ri z7ccf-jrAC%a(ir0Nn}D^X<}KBCe45>hL9Z_xjf#^avxoKp`xNfiEW9M1wo-z)isI= z+z(OhwXZF<*tfq9?xKZ?0|ylKd3h#NZeE^3uW#5MYSNikl{Z>KCEOB}9;C0(S2VP2 z4c$`O+NQ7A-Vm3&HKcvTQa{TMCrLy`XV=!EiVCdv_VxD;v{h{HK6EIf^KgLk(qhYw zmj{m=9U6`^6?Tst+Y=R)u%X+a7|l37eEh^KwJVD)#>P($g}tiI3k~f)bvkTf;>>H+ zMd@9ytIwWGR5zW!aPiXQ<%Gnu=i;yAmR`M<*w+095Lj^d+`08piHY{y3x2lO-#lIx zUh=xSV9Sl0Ro%C4A6J`lH{W^7D=c(sC-;Jd?ev@1uDn`uH_sUK_8zZW_wFB03<-^R zXZXs4t?$lHDYks?{SR*Dh2AaGX&!z!l-K*p$fL5yK_4aLb(MPMIhGe&y!UZtW#uR8 zkf6ft-Q88y>guox#bcA{6D()%SjFX8Ec?_uJzb*-E>c#s4SW__`dNeifTAefsMBda z-zeuBx(YA9L)~(Bz@QeTXFaKKZ`K7gx{K{+PwJW%eT&}-=ZF#M~ zQ@#mFiwytCGXFtIdPYt|#a0qpCp3TAG1 z)A3h%--kS~(e`+sJtcN_bgZO3kGPd&#c~y)Ip)NV_Z`mQfVSvnW z;E?Q}pAuG75}CV9Kt!<7GPdjHBP0#-f@ViOBX_KhEM(>iuWU?Mh4o{40$V(aMwjZ{z5Dg#5RfB*A1KV zUSj7TMb^NUz4FVaWKnb$Y{F^G+)vjOX4{I0jo6>?Hg6~D$~Hy@5r*o?3t}Jgf-Ica zZrFr8TVVIyNtUhlCf4)p$gGvF#3?$1XkedT6Ol*!A&1d;9sU`;z-u{KlD?ZnV_qXK z*byR&A&!UzAqYx_K)ad5?e8I$Hu!y>8zFXLVjGr1Bnf3?9_onT7X+P7+|V}P)K0?2 zItLr`{XERwHevB3^t-3THmQtQtw3JbYF{wq6G2oCnZ4YZcz*MgI6$UzTc1U^5)I@T zluvQ%6-7MC4w4t8p@i71M0rVs%afyNjdZh`4Y+VtqjFO6?&2 zNe6*rKVmhPLuRuDWL{tl@z2>qHXZ0?w?;j>M>r@270ST_^ByM53Oq>=GaJ>}uv3>HC=&=5w+i8Y8LDyg^ zh-b_WvM#y=@mR{xFJ(k(*oEJ*o}}3hJ)ju(%ZLZ!>$peeGiz9$8_S7bVjbjpjGdHr z#-8pSZzkUHjf_4(?d8-)?u>PUmEIf4N|_$|2QFVDS>df?bP=vpi_eJhvo`GikW*ka zpKUScxmmNGpKDfDiXSp~9 zK_OPT!u}l!0YwlV&WDWhqGJ>{Ozk7#2{dAA_uk0k`=~{*eM3qKTepcHAHO*?At5m- zJlrQpxHj1(WmYOXEj=T1OE^xg+nSpfj_p^}(p@sEv<%KbJ9dWWmy5*}dHh}U+iow% zSuSPbJ<VlSpX5wA(*@`PJ9oeEaQ!;n|Mgd0+Vc2k#$yqk4b(d1-xb)WYvC{9^iZ z!(XOid;a>jzy1BM|M>Nvj(`2vZ~t}kx1Qf$jQxLoo}=@aEiN{$Kjtz2XLA>RqCYZ; z#;jVpCX6iPE6My-N;1!xUJ7Ez4{4IBeT3q$$bA^WWIM1dEU)P=C~TkTv;)B!MlJwC)`ZtisQ&!mM2;0 z7KWHS8_0_A{Y3xcQ)0mNg0q-7f|oA^UtA~&CXV5W#9kgjEap2A8y>#9g%DOyHQ9(~ zEnk>N=KE=gyLf9h~G1ZDc&BkR7v2a2=g<)hlVi9pd_mUO3zmV!>QJG}!Cr^ph3-bvpB#A6l z#Sx2-o|5_Q3NnW+C-%bim_ODNp1P5^f!7LRw-N8H`-xlJb|M4s7MivZfpHtd%KBBwo;Yy)hSyF)yqE|Mn@UBXX=Cd*?t_$b|lc zHQR;WTZp5F1~NeuaWi(3wRmo!n-^K^p&;uD4iJy*8p7YSjo7Xdlf~|S#0_%?-;_^Y zLd+w_wSi=TB!j%XpPc_J^ebmLaY0_nsSxL;)~BsQ#7f^qKJdP8ec8Q%9yQWv7esI<;cn6HCo^q>!9IgvIg^;<%_oD#np1i7)uEk^Q+~Y z7l3c9XKqL&3p|tYd=z1Mz|SDUOoZU?4!|)hB!O5XAA3V8SsAs3*nIkw*n=kRSFI*C zTsc|fh8R&E5k#n|Cj#VIo46CU5BLRSAT|~30m>pXK4YyJ^UGqfnk;pXLR_gx@b?Df zsUt4oyNOU;3H{p)n@kn-=G|mvP%d%R)e><`EpgdUjCI*!*k)i0&{d*uP$xHk;tc*z z{UKJ$7(#HYd>fw^skkCCvYF=VL#vdsVA67+34kInvL z%@G6(Vw|q-mXxd<$kWuRA(-YhU5z6 znM<{24Tnxh9J&z8r8+ZJnVCgcI{nPdK7UL;rDZ#ImUFmRNab?(RC2gg)ux(2>0WLv zci(<)-GO>;19o#AZ05FbTiZD89j=&ZsEW!Rh&gnaGozPcZs9-^jp0BKeU*FaG-j38 k&z_snJFi^5_69kUMr``3x0mnuiqyPW_ diff --git a/src/gui/dosbox_logo.h b/src/gui/dosbox_logo.h index be40334c..c0502ba5 100644 --- a/src/gui/dosbox_logo.h +++ b/src/gui/dosbox_logo.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox_logo.h,v 1.2 2006-02-20 14:40:37 qbix79 Exp $ */ +/* $Id: dosbox_logo.h,v 1.3 2006-03-29 12:26:41 qbix79 Exp $ */ /* DOSBox icon designed by Ido Beeri */ @@ -24,518 +24,518 @@ #define LOGO_1 1 //#define LOGO_2 1 #ifdef LOGO_1 -64 , 46, 30,0, 64, 46, 30,0, 91, 61, 37,0, 91, 61, 37,0 -, 91, 61, 37,0, 89, 60, 37,0, 94, 62, 37,0, 95, 62, 36,0 -, 94, 62, 37,0, 94, 62, 37,0, 95, 64, 39,0, 95, 64, 39,0 -, 95, 64, 39,0, 95, 64, 39,0, 94, 62, 37,0, 94, 62, 37,0 -, 88, 58, 34,0, 88, 58, 34,0, 94, 62, 37,0, 94, 62, 37,0 -, 91, 61, 37,0, 91, 61, 36,0, 91, 61, 36,0, 88, 58, 34,0 -, 91, 60, 35,0, 91, 60, 35,0, 82, 53, 31,0, 82, 53, 31,0 -, 86, 56, 32,0, 86, 56, 32,0, 61, 42, 27,0, 61, 42, 27,0 -, 64, 46, 30,0, 64, 46, 30,0, 91, 61, 37,0, 91, 61, 37,0 -, 89, 60, 37,0, 89, 60, 37,0, 95, 62, 36,0, 95, 62, 36,0 -, 94, 62, 37,0, 94, 62, 37,0, 95, 64, 39,0, 95, 64, 39,0 -, 95, 64, 39,0, 95, 64, 39,0, 94, 62, 37,0, 94, 62, 37,0 -, 88, 58, 34,0, 88, 58, 34,0, 94, 62, 37,0, 94, 62, 37,0 -, 91, 61, 37,0, 91, 61, 37,0, 91, 61, 36,0, 91, 61, 36,0 -, 91, 60, 35,0, 91, 60, 35,0, 82, 53, 31,0, 82, 53, 31,0 -, 86, 56, 32,0, 86, 56, 32,0, 61, 42, 27,0, 61, 42, 27,0 -, 79, 53, 33,0, 79, 53, 33,0,142, 95, 58,0,142, 95, 58,0 -,139, 82, 43,0,139, 82, 43,0,129, 77, 39,0,129, 77, 39,0 -,132, 82, 44,0,132, 82, 44,0,143, 91, 49,0,143, 91, 49,0 -,132, 82, 44,0,132, 82, 44,0,129, 77, 40,0,129, 77, 40,0 -,112, 69, 36,0,112, 69, 36,0,136, 85, 45,0,136, 85, 45,0 -,136, 86, 47,0,136, 86, 47,0,119, 75, 39,0,119, 75, 39,0 -,119, 73, 38,0,119, 73, 38,0,125, 76, 39,0,125, 76, 39,0 -,131, 85, 49,0,131, 85, 49,0, 82, 53, 31,0, 82, 53, 31,0 -, 79, 53, 33,0, 79, 53, 33,0,142, 95, 58,0,142, 95, 58,0 -,139, 82, 43,0,139, 82, 43,0,129, 77, 39,0,129, 77, 39,0 -,132, 82, 44,0,129, 77, 40,0,143, 91, 49,0,143, 91, 49,0 -,132, 82, 44,0,132, 82, 44,0,129, 77, 40,0,129, 77, 40,0 -,112, 69, 36,0,112, 69, 36,0,136, 85, 45,0,136, 85, 45,0 -,136, 86, 47,0,136, 85, 45,0,119, 75, 39,0,119, 75, 39,0 -,119, 73, 38,0,119, 73, 38,0,125, 76, 39,0,125, 76, 39,0 -,131, 85, 49,0,131, 85, 49,0, 82, 53, 31,0, 82, 53, 31,0 -, 77, 50, 31,0, 77, 50, 31,0,141, 82, 43,0,141, 82, 43,0 -,255,229, 42,0,255,229, 42,0,255,238, 87,0,255,238, 88,0 + 65, 44, 25,0, 65, 44, 25,0, 93, 58, 30,0, 93, 58, 30,0 +, 92, 57, 30,0, 92, 57, 30,0, 98, 59, 28,0, 98, 59, 28,0 +, 97, 58, 29,0, 97, 58, 29,0, 97, 60, 30,0, 97, 60, 30,0 +, 97, 60, 30,0, 97, 60, 30,0, 96, 59, 29,0, 96, 59, 29,0 +, 91, 55, 26,0, 91, 55, 26,0, 96, 60, 29,0, 96, 60, 29,0 +, 93, 58, 28,0, 93, 58, 28,0, 93, 57, 27,0, 93, 57, 27,0 +, 93, 56, 27,0, 93, 56, 27,0, 85, 52, 25,0, 85, 52, 25,0 +, 89, 53, 24,0, 89, 53, 24,0, 63, 39, 22,0, 63, 39, 22,0 +, 65, 44, 25,0, 65, 44, 25,0, 93, 58, 30,0, 93, 58, 30,0 +, 92, 57, 30,0, 92, 57, 30,0, 98, 59, 28,0, 98, 59, 28,0 +, 97, 58, 29,0, 97, 58, 29,0, 97, 60, 30,0, 97, 60, 30,0 +, 97, 60, 30,0, 97, 60, 30,0, 96, 59, 29,0, 96, 59, 29,0 +, 91, 55, 26,0, 91, 55, 26,0, 96, 60, 29,0, 96, 60, 29,0 +, 93, 58, 28,0, 93, 58, 28,0, 93, 57, 27,0, 93, 57, 27,0 +, 93, 56, 27,0, 93, 56, 27,0, 85, 52, 25,0, 85, 52, 25,0 +, 89, 53, 24,0, 89, 53, 24,0, 63, 39, 22,0, 63, 39, 22,0 +, 81, 50, 26,0, 81, 50, 26,0,145, 89, 46,0,145, 89, 46,0 +,145, 76, 29,0,145, 76, 29,0,134, 72, 26,0,134, 72, 26,0 +,136, 76, 30,0,136, 76, 30,0,148, 85, 36,0,148, 85, 36,0 +,137, 77, 31,0,137, 77, 31,0,134, 72, 27,0,134, 72, 27,0 +,117, 64, 26,0,117, 64, 26,0,141, 80, 32,0,141, 80, 32,0 +,141, 81, 34,0,141, 81, 34,0,123, 70, 27,0,123, 70, 27,0 +,123, 68, 27,0,123, 68, 27,0,130, 72, 27,0,130, 72, 27,0 +,135, 80, 37,0,135, 80, 37,0, 85, 50, 24,0, 85, 50, 24,0 +, 81, 50, 26,0, 81, 50, 26,0,145, 89, 46,0,145, 89, 46,0 +,145, 76, 29,0,145, 76, 29,0,134, 72, 26,0,134, 72, 26,0 +,136, 76, 30,0,136, 76, 30,0,148, 85, 36,0,148, 85, 36,0 +,137, 77, 31,0,137, 77, 31,0,134, 72, 27,0,134, 72, 27,0 +,117, 64, 26,0,117, 64, 26,0,141, 80, 32,0,141, 80, 32,0 +,141, 81, 34,0,141, 81, 34,0,123, 70, 27,0,123, 70, 27,0 +,123, 68, 27,0,123, 68, 27,0,130, 72, 27,0,130, 72, 27,0 +,135, 80, 37,0,135, 80, 37,0, 85, 50, 24,0, 85, 50, 24,0 +, 80, 48, 24,0, 80, 48, 24,0,146, 76, 29,0,146, 76, 29,0 +,255,227, 30,0,255,227, 30,0,255,237, 75,0,255,237, 75,0 ,125, 98, 52,0,125, 98, 52,0,145,120, 69,0,145,120, 69,0 -,133,105, 55,0,133,105, 55,0,255,233, 60,0,255,233, 60,0 -,255,238, 88,0,255,238, 88,0,127,100, 53,0,127,100, 53,0 +,133,105, 55,0,133,105, 55,0,255,231, 48,0,255,231, 48,0 +,255,237, 75,0,255,237, 75,0,127,100, 53,0,127,100, 53,0 ,143,117, 67,0,143,117, 67,0,132,105, 55,0,132,105, 55,0 -,255,234, 67,0,255,234, 67,0,255,238, 89,0,255,238, 89,0 -, 83, 49, 23,0, 81, 47, 23,0, 76, 49, 27,0, 82, 51, 26,0 -, 77, 50, 31,0, 79, 53, 33,0,141, 82, 43,0,141, 82, 43,0 -,255,229, 42,0,255,229, 42,0,255,238, 88,0,255,238, 88,0 +,255,232, 54,0,255,232, 54,0,255,236, 76,0,255,236, 76,0 +, 85, 44, 15,0, 85, 44, 15,0, 83, 47, 20,0, 83, 47, 20,0 +, 80, 48, 24,0, 80, 48, 24,0,146, 76, 29,0,146, 76, 29,0 +,255,227, 30,0,255,227, 30,0,255,237, 75,0,255,237, 75,0 ,125, 98, 52,0,125, 98, 52,0,145,120, 69,0,145,120, 69,0 -,133,105, 55,0,133,105, 55,0,255,233, 60,0,255,233, 60,0 -,255,238, 88,0,255,238, 88,0,127,100, 53,0,127,100, 53,0 +,133,105, 55,0,133,105, 55,0,255,231, 48,0,255,231, 48,0 +,255,237, 75,0,255,237, 75,0,127,100, 53,0,127,100, 53,0 ,143,117, 67,0,143,117, 67,0,132,105, 55,0,132,105, 55,0 -,255,234, 67,0,255,235, 73,0,255,238, 89,0,255,238, 89,0 -, 83, 49, 23,0, 81, 47, 23,0, 80, 50, 27,0, 80, 50, 27,0 -, 77, 50, 31,0, 77, 50, 31,0,143, 78, 37,0,143, 78, 37,0 -,255,229, 43,0,255,229, 42,0, 82, 56, 21,0, 82, 56, 21,0 -,255,238, 88,0,255,238, 88,0, 97, 72, 30,0, 97, 72, 30,0 -,255,233, 60,0,255,233, 60,0, 16, 12, 5,0, 16, 12, 5,0 -,102, 75, 32,0,102, 75, 32,0,255,238, 88,0,255,238, 88,0 -,107, 80, 36,0,107, 80, 36,0,255,224, 13,0,255,224, 13,0 -, 65, 45, 19,0, 65, 45, 19,0, 47, 37, 16,0, 48, 38, 19,0 -, 63, 35, 14,0, 63, 35, 14,0, 77, 46, 22,0, 77, 46, 22,0 -, 77, 51, 30,0, 77, 51, 30,0,143, 78, 37,0,143, 78, 37,0 -,255,229, 43,0,255,229, 42,0, 82, 56, 21,0, 82, 56, 21,0 -,255,238, 88,0,255,238, 88,0, 97, 72, 30,0, 98, 75, 35,0 -,255,233, 60,0,255,233, 60,0, 16, 12, 5,0, 16, 12, 5,0 -,102, 75, 32,0,102, 75, 32,0,255,238, 88,0,255,238, 88,0 -,107, 80, 36,0,107, 80, 36,0,255,224, 13,0,255,224, 13,0 -, 65, 45, 19,0, 65, 45, 19,0, 47, 37, 16,0, 47, 37, 16,0 -, 63, 35, 14,0, 63, 35, 14,0, 77, 46, 22,0, 77, 46, 22,0 -, 82, 53, 31,0, 82, 53, 31,0,144, 81, 38,0,143, 77, 35,0 -,255,231, 49,0,255,231, 49,0, 14, 11, 3,0, 16, 12, 3,0 -,255,238, 88,0,255,238, 88,0, 62, 48, 12,0, 62, 48, 12,0 -,255,238, 89,0,255,238, 89,0, 27, 21, 8,0, 27, 21, 8,0 -,109, 84, 35,0,106, 84, 35,0,255,238, 88,0,255,238, 88,0 +,255,232, 54,0,255,232, 54,0,255,236, 76,0,255,236, 76,0 +, 85, 44, 15,0, 85, 44, 15,0, 83, 47, 20,0, 83, 47, 20,0 +, 79, 48, 23,0, 79, 48, 23,0,149, 72, 24,0,149, 72, 24,0 +,255,227, 31,0,255,227, 31,0, 82, 56, 21,0, 82, 56, 21,0 +,255,236, 76,0,255,236, 76,0, 97, 72, 30,0, 97, 72, 30,0 +,255,231, 48,0,255,231, 48,0, 16, 12, 5,0, 16, 12, 5,0 +,102, 75, 32,0,102, 75, 32,0,255,237, 75,0,255,237, 75,0 +,107, 80, 36,0,107, 80, 36,0,255,221, 2,0,255,221, 2,0 +, 65, 45, 19,0, 65, 45, 19,0, 48, 38, 19,0, 48, 38, 19,0 +, 66, 32, 6,0, 66, 32, 6,0, 80, 43, 14,0, 80, 43, 14,0 +, 79, 48, 23,0, 79, 48, 23,0,149, 72, 24,0,149, 72, 24,0 +,255,227, 31,0,255,227, 31,0, 82, 56, 21,0, 82, 56, 21,0 +,255,236, 76,0,255,236, 76,0, 97, 72, 30,0, 97, 72, 30,0 +,255,231, 48,0,255,231, 48,0, 16, 12, 5,0, 16, 12, 5,0 +,102, 75, 32,0,102, 75, 32,0,255,237, 75,0,255,237, 75,0 +,107, 80, 36,0,107, 80, 36,0,255,221, 2,0,255,221, 2,0 +, 65, 45, 19,0, 65, 45, 19,0, 48, 38, 19,0, 48, 38, 19,0 +, 66, 32, 6,0, 66, 32, 6,0, 80, 43, 14,0, 80, 43, 14,0 +, 85, 52, 25,0, 85, 52, 25,0,149, 70, 21,0,149, 70, 21,0 +,255,229, 37,0,255,229, 37,0, 16, 12, 3,0, 16, 12, 3,0 +,255,236, 76,0,255,236, 76,0, 62, 48, 12,0, 62, 48, 12,0 +,255,236, 76,0,255,236, 76,0, 27, 21, 8,0, 27, 21, 8,0 +,107, 84, 34,0,107, 84, 34,0,255,237, 75,0,255,237, 75,0 , 11, 8, 3,0, 11, 8, 3,0,106, 84, 35,0,106, 84, 35,0 -,255,238, 88,0,255,238, 87,0, 98, 75, 35,0, 98, 75, 35,0 -,100, 54, 18,0,100, 54, 18,0, 82, 51, 26,0, 77, 46, 22,0 -, 82, 53, 31,0, 82, 53, 31,0,143, 77, 35,0,143, 77, 35,0 -,255,231, 49,0,255,231, 49,0, 14, 11, 3,0, 16, 12, 3,0 -,255,238, 88,0,255,238, 88,0, 62, 48, 12,0, 62, 48, 12,0 -,255,238, 89,0,255,238, 89,0, 27, 21, 8,0, 27, 21, 8,0 -,106, 84, 35,0,106, 84, 35,0,255,238, 88,0,255,238, 88,0 +,255,237, 74,0,255,237, 74,0, 98, 75, 35,0, 98, 75, 35,0 +,105, 50, 7,0,105, 50, 7,0, 83, 46, 15,0, 83, 46, 15,0 +, 85, 52, 25,0, 85, 52, 25,0,149, 70, 21,0,149, 70, 21,0 +,255,229, 37,0,255,229, 37,0, 16, 12, 3,0, 16, 12, 3,0 +,255,236, 76,0,255,236, 76,0, 62, 48, 12,0, 62, 48, 12,0 +,255,236, 76,0,255,236, 76,0, 27, 21, 8,0, 27, 21, 8,0 +,107, 84, 34,0,107, 84, 34,0,255,237, 75,0,255,237, 75,0 , 11, 8, 3,0, 11, 8, 3,0,106, 84, 35,0,106, 84, 35,0 -,255,238, 87,0,255,238, 87,0, 98, 75, 35,0, 98, 75, 35,0 -,100, 54, 18,0,100, 54, 18,0, 79, 47, 22,0, 82, 51, 26,0 -, 77, 51, 30,0, 82, 53, 31,0,135, 73, 33,0,135, 73, 33,0 -,255,232, 57,0,255,232, 57,0, 2, 2, 1,0, 2, 2, 1,0 -,255,238, 88,0,255,238, 88,0, 75, 58, 13,0, 75, 58, 13,0 -,255,238, 89,0,255,238, 89,0, 80, 62, 19,0, 80, 62, 19,0 -, 82, 64, 22,0, 82, 64, 22,0,255,238, 88,0,255,238, 89,0 +,255,237, 74,0,255,237, 74,0, 98, 75, 35,0, 98, 75, 35,0 +,105, 50, 7,0,105, 50, 7,0, 83, 46, 15,0, 83, 46, 15,0 +, 81, 49, 23,0, 81, 49, 23,0,142, 67, 20,0,142, 67, 20,0 +,255,230, 45,0,255,230, 45,0, 2, 1, 0,0, 2, 1, 0,0 +,255,236, 76,0,255,236, 76,0, 75, 58, 13,0, 75, 58, 13,0 +,255,236, 76,0,255,236, 76,0, 80, 62, 19,0, 80, 62, 19,0 +, 81, 64, 21,0, 81, 64, 21,0,255,236, 76,0,255,236, 76,0 , 2, 2, 1,0, 2, 2, 1,0,111, 86, 36,0,111, 86, 36,0 -, 88, 63, 23,0, 88, 63, 23,0,255,238, 88,0,255,238, 88,0 -, 62, 33, 10,0, 62, 33, 10,0, 83, 49, 23,0, 83, 49, 23,0 -, 77, 51, 30,0, 77, 51, 30,0,135, 73, 33,0,135, 73, 33,0 -,255,232, 57,0,255,232, 57,0, 2, 2, 1,0, 2, 2, 1,0 -,255,238, 89,0,255,238, 88,0, 75, 58, 13,0, 75, 58, 13,0 -,255,238, 88,0,255,238, 88,0, 80, 62, 19,0, 80, 62, 19,0 -, 82, 64, 22,0, 82, 64, 22,0,255,238, 88,0,255,238, 88,0 +, 88, 63, 23,0, 88, 63, 23,0,255,236, 76,0,255,236, 76,0 +, 66, 31, 4,0, 66, 31, 4,0, 87, 46, 15,0, 87, 46, 15,0 +, 81, 49, 23,0, 81, 49, 23,0,142, 67, 20,0,142, 67, 20,0 +,255,230, 45,0,255,230, 45,0, 2, 1, 0,0, 2, 1, 0,0 +,255,236, 76,0,255,236, 76,0, 75, 58, 13,0, 75, 58, 13,0 +,255,236, 76,0,255,236, 76,0, 80, 62, 19,0, 80, 62, 19,0 +, 81, 64, 21,0, 81, 64, 21,0,255,236, 76,0,255,236, 76,0 , 2, 2, 1,0, 2, 2, 1,0,111, 86, 36,0,111, 86, 36,0 -, 88, 63, 23,0, 88, 63, 23,0,255,238, 88,0,255,238, 88,0 -, 62, 33, 10,0, 62, 33, 10,0, 83, 49, 23,0, 83, 49, 23,0 -, 79, 52, 30,0, 76, 49, 27,0,144, 81, 40,0,144, 81, 40,0 -,255,238, 87,0,255,238, 87,0,255,238, 88,0,255,238, 88,0 -, 57, 46, 20,0, 57, 44, 14,0,111, 87, 27,0,111, 87, 27,0 -,104, 80, 30,0,104, 80, 30,0,255,238, 88,0,255,238, 88,0 -,255,238, 87,0,255,238, 88,0, 47, 37, 16,0, 47, 37, 16,0 -,116, 91, 38,0,116, 91, 38,0,255,238, 88,0,255,238, 88,0 -,255,238, 88,0,255,238, 88,0, 38, 30, 13,0, 38, 30, 13,0 -, 53, 28, 9,0, 53, 28, 9,0, 77, 46, 22,0, 81, 47, 23,0 -, 76, 49, 27,0, 76, 49, 27,0,144, 81, 40,0,144, 81, 40,0 -,255,238, 87,0,255,238, 87,0,255,238, 87,0,255,238, 87,0 +, 88, 63, 23,0, 88, 63, 23,0,255,236, 76,0,255,236, 76,0 +, 66, 31, 4,0, 66, 31, 4,0, 87, 46, 15,0, 87, 46, 15,0 +, 78, 46, 21,0, 78, 46, 21,0,150, 76, 25,0,150, 76, 25,0 +,255,237, 75,0,255,237, 75,0,255,236, 76,0,255,236, 76,0 , 57, 44, 14,0, 57, 44, 14,0,111, 87, 27,0,111, 87, 27,0 -,104, 80, 30,0,104, 80, 30,0,255,238, 88,0,255,238, 88,0 -,255,238, 88,0,255,238, 88,0, 47, 37, 16,0, 47, 37, 16,0 -,116, 91, 38,0,116, 91, 38,0,255,238, 88,0,255,238, 88,0 -,255,238, 88,0,255,238, 88,0, 38, 30, 13,0, 38, 30, 13,0 -, 53, 28, 9,0, 53, 28, 9,0, 83, 49, 23,0, 77, 46, 22,0 -, 82, 53, 31,0, 82, 53, 31,0,153, 91, 46,0,153, 91, 46,0 -,125,101, 52,0,125,101, 52,0, 63, 50, 23,0, 57, 46, 20,0 -, 66, 51, 23,0, 66, 51, 23,0,140,115, 53,0,140,115, 53,0 -,134,109, 51,0,134,109, 51,0,118, 94, 41,0,118, 94, 41,0 -, 47, 37, 16,0, 47, 37, 16,0, 63, 50, 23,0, 63, 50, 23,0 -,129,105, 46,0,129,105, 46,0,114, 92, 41,0,114, 92, 41,0 -, 71, 57, 25,0, 71, 57, 25,0, 68, 52, 26,0, 68, 52, 26,0 -,105, 55, 18,0,105, 55, 18,0, 82, 51, 26,0, 79, 47, 22,0 -, 79, 53, 33,0, 77, 51, 30,0,153, 91, 46,0,153, 91, 46,0 +,104, 80, 30,0,104, 80, 30,0,255,236, 76,0,255,236, 76,0 +,255,236, 76,0,255,236, 76,0, 47, 37, 16,0, 47, 37, 16,0 +,116, 91, 38,0,116, 91, 38,0,255,237, 75,0,255,237, 75,0 +,255,236, 76,0,255,236, 76,0, 38, 30, 13,0, 38, 30, 13,0 +, 56, 26, 4,0, 56, 26, 4,0, 82, 43, 14,0, 82, 43, 14,0 +, 78, 46, 21,0, 78, 46, 21,0,150, 76, 25,0,150, 76, 25,0 +,255,237, 75,0,255,237, 75,0,255,236, 76,0,255,236, 76,0 +, 57, 44, 14,0, 57, 44, 14,0,111, 87, 27,0,111, 87, 27,0 +,104, 80, 30,0,104, 80, 30,0,255,236, 76,0,255,236, 76,0 +,255,236, 76,0,255,236, 76,0, 47, 37, 16,0, 47, 37, 16,0 +,116, 91, 38,0,116, 91, 38,0,255,237, 75,0,255,237, 75,0 +,255,236, 76,0,255,236, 76,0, 38, 30, 13,0, 38, 30, 13,0 +, 56, 26, 4,0, 56, 26, 4,0, 82, 43, 14,0, 82, 43, 14,0 +, 82, 50, 25,0, 82, 50, 25,0,159, 84, 31,0,159, 84, 31,0 ,125,101, 52,0,125,101, 52,0, 57, 46, 20,0, 57, 46, 20,0 , 66, 51, 23,0, 66, 51, 23,0,140,115, 53,0,140,115, 53,0 ,134,109, 51,0,134,109, 51,0,118, 94, 41,0,118, 94, 41,0 -, 47, 38, 16,0, 47, 37, 16,0, 63, 50, 23,0, 63, 50, 23,0 +, 47, 38, 16,0, 47, 38, 16,0, 63, 50, 23,0, 63, 50, 23,0 ,129,105, 46,0,129,105, 46,0,114, 92, 41,0,114, 92, 41,0 , 71, 57, 25,0, 71, 57, 25,0, 68, 52, 26,0, 68, 52, 26,0 -,105, 55, 18,0,100, 54, 18,0, 82, 51, 26,0, 82, 51, 26,0 -, 77, 51, 30,0, 82, 53, 31,0,158, 96, 50,0,158, 96, 50,0 -,130,104, 57,0,130,104, 57,0,123, 98, 47,0,123, 98, 47,0 +,111, 51, 7,0,111, 51, 7,0, 84, 47, 17,0, 84, 47, 17,0 +, 82, 50, 25,0, 82, 50, 25,0,159, 84, 31,0,159, 84, 31,0 +,125,101, 52,0,125,101, 52,0, 57, 46, 20,0, 57, 46, 20,0 +, 66, 51, 23,0, 66, 51, 23,0,140,115, 53,0,140,115, 53,0 +,134,109, 51,0,134,109, 51,0,118, 94, 41,0,118, 94, 41,0 +, 47, 38, 16,0, 47, 38, 16,0, 63, 50, 23,0, 63, 50, 23,0 +,129,105, 46,0,129,105, 46,0,114, 92, 41,0,114, 92, 41,0 +, 71, 57, 25,0, 71, 57, 25,0, 68, 52, 26,0, 68, 52, 26,0 +,111, 51, 7,0,111, 51, 7,0, 84, 47, 17,0, 84, 47, 17,0 +, 81, 50, 24,0, 81, 50, 24,0,164, 89, 35,0,164, 89, 35,0 +,130,104, 57,0,130,104, 57,0,121, 97, 46,0,121, 97, 46,0 ,131,109, 52,0,131,109, 52,0,139,116, 57,0,139,116, 57,0 ,137,114, 58,0,137,114, 58,0,123, 98, 47,0,123, 98, 47,0 ,125,101, 49,0,125,101, 49,0,139,115, 59,0,139,115, 59,0 ,141,118, 62,0,141,118, 62,0,137,110, 58,0,137,110, 58,0 ,130,106, 52,0,130,106, 52,0,131,108, 55,0,131,108, 55,0 -,107, 58, 20,0,107, 58, 20,0, 80, 50, 27,0, 80, 50, 27,0 -, 77, 51, 30,0, 82, 53, 31,0,158, 96, 50,0,158, 96, 50,0 -,130,104, 57,0,127,100, 53,0,121, 97, 46,0,118, 92, 43,0 +,113, 54, 9,0,113, 54, 9,0, 85, 48, 18,0, 85, 48, 18,0 +, 81, 50, 24,0, 81, 50, 24,0,164, 89, 35,0,164, 89, 35,0 +,130,104, 57,0,130,104, 57,0,121, 97, 46,0,121, 97, 46,0 ,131,109, 52,0,131,109, 52,0,139,116, 57,0,139,116, 57,0 ,137,114, 58,0,137,114, 58,0,123, 98, 47,0,123, 98, 47,0 ,125,101, 49,0,125,101, 49,0,139,115, 59,0,139,115, 59,0 ,141,118, 62,0,141,118, 62,0,137,110, 58,0,137,110, 58,0 ,130,106, 52,0,130,106, 52,0,131,108, 55,0,131,108, 55,0 -,107, 58, 20,0,107, 58, 20,0, 82, 51, 26,0, 82, 51, 26,0 -, 76, 50, 29,0, 76, 50, 29,0,141, 82, 43,0,144, 81, 38,0 -,255,231, 49,0,255,230, 46,0,255,238, 88,0,255,238, 88,0 -,118, 90, 42,0,118, 90, 42,0,137,114, 58,0,138,111, 58,0 -,120, 93, 46,0,120, 93, 46,0,255,233, 60,0,255,233, 60,0 -,255,238, 88,0,255,238, 88,0,118, 92, 43,0,118, 92, 43,0 -,118, 91, 42,0,118, 91, 42,0,255,235, 73,0,255,235, 73,0 -,100, 73, 31,0,100, 73, 31,0,255,238, 88,0,255,238, 88,0 -, 97, 54, 19,0, 97, 54, 19,0, 83, 49, 23,0, 77, 46, 22,0 -, 72, 46, 26,0, 76, 50, 29,0,144, 81, 38,0,141, 82, 43,0 -,255,230, 46,0,255,230, 46,0,255,238, 88,0,255,238, 87,0 -,118, 90, 42,0,118, 90, 42,0,137,110, 58,0,137,110, 58,0 -,120, 93, 46,0,120, 93, 46,0,255,233, 60,0,255,232, 57,0 -,255,238, 88,0,255,238, 88,0,118, 92, 43,0,118, 92, 43,0 -,118, 91, 42,0,118, 94, 41,0,255,235, 73,0,255,235, 73,0 -,100, 73, 31,0,100, 73, 31,0,255,238, 88,0,255,238, 88,0 -, 97, 54, 19,0, 97, 54, 19,0, 77, 46, 22,0, 81, 47, 23,0 -, 76, 50, 29,0, 76, 50, 29,0,135, 73, 33,0,135, 73, 33,0 -,255,228, 35,0,255,228, 35,0, 82, 56, 21,0, 82, 56, 20,0 -,255,238, 88,0,255,238, 88,0,107, 80, 36,0,107, 80, 36,0 -,255,223, 10,0,255,223, 10,0, 14, 11, 3,0, 14, 11, 3,0 -, 97, 72, 30,0, 97, 72, 30,0,255,238, 87,0,255,238, 87,0 -, 93, 70, 27,0, 93, 70, 27,0,255,221, 2,0,255,221, 2,0 -, 66, 50, 15,0, 67, 52, 16,0,255,238, 88,0,255,238, 88,0 -, 62, 33, 10,0, 62, 32, 8,0, 74, 43, 19,0, 74, 43, 19,0 -, 76, 50, 29,0, 76, 50, 29,0,135, 73, 33,0,135, 73, 33,0 -,255,228, 35,0,255,228, 37,0, 82, 56, 21,0, 82, 56, 20,0 -,255,238, 88,0,255,238, 88,0,104, 80, 30,0,107, 80, 36,0 -,255,224, 13,0,255,224, 13,0, 14, 11, 3,0, 16, 12, 3,0 -,100, 73, 31,0, 97, 72, 30,0,255,238, 87,0,255,238, 88,0 -, 93, 70, 27,0, 93, 70, 27,0,255,221, 2,0,255,221, 2,0 -, 66, 50, 15,0, 67, 52, 16,0,255,238, 88,0,255,238, 88,0 -, 62, 32, 8,0, 62, 32, 8,0, 74, 43, 19,0, 74, 43, 19,0 -, 83, 55, 32,0, 83, 55, 32,0,130, 70, 31,0,130, 70, 31,0 -,255,232, 57,0,255,232, 57,0,255,238, 88,0,255,238, 88,0 -, 43, 34, 8,0, 43, 34, 8,0, 80, 62, 19,0, 82, 64, 20,0 -,255,238, 87,0,255,238, 87,0, 27, 21, 8,0, 27, 21, 8,0 -,109, 84, 35,0,109, 84, 35,0,255,228, 37,0,255,228, 37,0 +,113, 54, 9,0,113, 54, 9,0, 85, 48, 18,0, 85, 48, 18,0 +, 76, 45, 21,0, 76, 45, 21,0,150, 75, 26,0,150, 75, 26,0 +,255,228, 34,0,255,228, 34,0,255,237, 75,0,255,237, 75,0 +,118, 90, 42,0,118, 90, 42,0,138,111, 58,0,138,111, 58,0 +,120, 93, 46,0,120, 93, 46,0,255,231, 48,0,255,231, 48,0 +,255,237, 75,0,255,237, 75,0,118, 92, 43,0,118, 92, 43,0 +,118, 91, 42,0,118, 91, 42,0,255,233, 60,0,255,233, 60,0 +,100, 73, 31,0,100, 73, 31,0,255,236, 76,0,255,236, 76,0 +,102, 51, 9,0,102, 51, 9,0, 82, 43, 14,0, 82, 43, 14,0 +, 76, 45, 21,0, 76, 45, 21,0,150, 75, 26,0,150, 75, 26,0 +,255,228, 34,0,255,228, 34,0,255,237, 75,0,255,237, 75,0 +,118, 90, 42,0,118, 90, 42,0,138,111, 58,0,138,111, 58,0 +,120, 93, 46,0,120, 93, 46,0,255,231, 48,0,255,231, 48,0 +,255,237, 75,0,255,237, 75,0,118, 92, 43,0,118, 92, 43,0 +,118, 91, 42,0,118, 91, 42,0,255,233, 60,0,255,233, 60,0 +,100, 73, 31,0,100, 73, 31,0,255,236, 76,0,255,236, 76,0 +,102, 51, 9,0,102, 51, 9,0, 82, 43, 14,0, 82, 43, 14,0 +, 78, 47, 22,0, 78, 47, 22,0,142, 67, 20,0,142, 67, 20,0 +,255,226, 24,0,255,226, 24,0, 82, 56, 20,0, 82, 56, 20,0 +,255,236, 76,0,255,236, 76,0,106, 80, 33,0,106, 80, 33,0 +,255,220, 0,0,255,220, 0,0, 15, 11, 4,0, 15, 11, 4,0 +, 99, 72, 30,0, 99, 72, 30,0,255,237, 74,0,255,237, 74,0 +, 93, 70, 27,0, 93, 70, 27,0,247,212, 0,0,247,212, 0,0 +, 66, 50, 15,0, 66, 50, 15,0,255,236, 76,0,255,236, 76,0 +, 66, 30, 1,0, 66, 30, 1,0, 77, 40, 11,0, 77, 40, 11,0 +, 78, 47, 22,0, 78, 47, 22,0,142, 67, 20,0,142, 67, 20,0 +,255,226, 24,0,255,226, 24,0, 82, 56, 20,0, 82, 56, 20,0 +,255,236, 76,0,255,236, 76,0,106, 80, 33,0,106, 80, 33,0 +,255,220, 0,0,255,220, 0,0, 15, 11, 4,0, 15, 11, 4,0 +, 99, 72, 30,0, 99, 72, 30,0,255,237, 74,0,255,237, 74,0 +, 93, 70, 27,0, 93, 70, 27,0,247,212, 0,0,247,212, 0,0 +, 66, 50, 15,0, 66, 50, 15,0,255,236, 76,0,255,236, 76,0 +, 66, 30, 1,0, 66, 30, 1,0, 77, 40, 11,0, 77, 40, 11,0 +, 86, 52, 25,0, 86, 52, 25,0,136, 64, 18,0,136, 64, 18,0 +,255,230, 45,0,255,230, 45,0,255,236, 76,0,255,236, 76,0 +, 42, 33, 8,0, 42, 33, 8,0, 82, 64, 20,0, 82, 64, 20,0 +,255,237, 74,0,255,237, 74,0, 28, 22, 8,0, 28, 22, 8,0 +,109, 84, 35,0,109, 84, 35,0,255,225, 26,0,255,225, 26,0 , 35, 26, 9,0, 35, 26, 9,0, 82, 64, 22,0, 82, 64, 22,0 -,255,238, 88,0,255,238, 87,0, 49, 39, 13,0, 49, 39, 13,0 -, 68, 31, 2,0, 68, 31, 2,0, 76, 43, 16,0, 76, 43, 16,0 -, 83, 55, 32,0, 83, 55, 32,0,130, 70, 31,0,130, 70, 31,0 -,255,232, 57,0,255,232, 57,0,255,238, 88,0,255,238, 88,0 -, 43, 34, 8,0, 43, 34, 8,0, 82, 64, 20,0, 82, 64, 20,0 -,255,238, 87,0,255,238, 87,0, 27, 21, 8,0, 27, 21, 8,0 -,109, 84, 35,0,109, 84, 35,0,255,228, 37,0,255,228, 37,0 +,255,237, 74,0,255,237, 74,0, 49, 39, 13,0, 49, 39, 13,0 +, 67, 30, 0,0, 67, 30, 0,0, 80, 40, 8,0, 80, 40, 8,0 +, 86, 52, 25,0, 86, 52, 25,0,136, 64, 18,0,136, 64, 18,0 +,255,230, 45,0,255,230, 45,0,255,236, 76,0,255,236, 76,0 +, 42, 33, 8,0, 42, 33, 8,0, 82, 64, 20,0, 82, 64, 20,0 +,255,237, 74,0,255,237, 74,0, 28, 22, 8,0, 28, 22, 8,0 +,109, 84, 35,0,109, 84, 35,0,255,225, 26,0,255,225, 26,0 , 35, 26, 9,0, 35, 26, 9,0, 82, 64, 22,0, 82, 64, 22,0 -,255,238, 87,0,255,238, 87,0, 49, 39, 13,0, 49, 39, 13,0 -, 68, 31, 2,0, 68, 31, 2,0, 76, 43, 16,0, 76, 43, 16,0 -, 72, 46, 26,0, 72, 46, 26,0,133, 69, 30,0,133, 69, 30,0 -,255,238, 88,0,255,238, 87,0, 14, 11, 3,0, 14, 11, 3,0 -,255,238, 89,0,255,238, 89,0, 82, 63, 15,0, 82, 63, 15,0 -,255,238, 89,0,255,238, 88,0, 80, 62, 19,0, 80, 62, 19,0 -, 86, 67, 22,0, 86, 67, 22,0,255,238, 88,0,255,238, 88,0 -, 67, 52, 16,0, 67, 52, 16,0,255,238, 87,0,255,238, 88,0 -, 42, 33, 8,0, 42, 33, 8,0,255,238, 89,0,255,238, 89,0 -, 68, 31, 2,0, 68, 31, 2,0, 68, 36, 11,0, 68, 36, 11,0 -, 72, 46, 26,0, 72, 46, 26,0,133, 69, 30,0,133, 69, 30,0 -,255,238, 87,0,255,238, 87,0, 14, 11, 3,0, 14, 11, 3,0 -,255,238, 89,0,255,238, 89,0, 82, 63, 15,0, 82, 63, 15,0 -,255,238, 88,0,255,238, 88,0, 80, 62, 19,0, 80, 62, 19,0 -, 86, 67, 22,0, 86, 67, 22,0,255,238, 88,0,255,238, 88,0 -, 67, 52, 16,0, 67, 52, 16,0,255,238, 87,0,255,238, 88,0 -, 42, 33, 8,0, 42, 33, 8,0,255,238, 89,0,255,238, 88,0 -, 68, 31, 2,0, 68, 31, 2,0, 68, 36, 11,0, 68, 36, 11,0 -, 75, 48, 27,0, 75, 48, 27,0,138, 77, 35,0,138, 77, 35,0 -,255,238, 88,0,255,238, 88,0,255,238, 88,0,255,238, 88,0 +,255,237, 74,0,255,237, 74,0, 49, 39, 13,0, 49, 39, 13,0 +, 67, 30, 0,0, 67, 30, 0,0, 80, 40, 8,0, 80, 40, 8,0 +, 74, 43, 19,0, 74, 43, 19,0,140, 63, 17,0,140, 63, 17,0 +,255,237, 74,0,255,237, 74,0, 14, 11, 3,0, 14, 11, 3,0 +,255,236, 76,0,255,236, 76,0, 82, 63, 15,0, 82, 63, 15,0 +,255,237, 75,0,255,237, 75,0, 80, 63, 19,0, 80, 63, 19,0 +, 86, 67, 22,0, 86, 67, 22,0,255,237, 75,0,255,237, 75,0 +, 67, 52, 16,0, 67, 52, 16,0,255,237, 74,0,255,237, 74,0 +, 43, 34, 8,0, 43, 34, 8,0,255,236, 76,0,255,236, 76,0 +, 66, 29, 0,0, 66, 29, 0,0, 71, 34, 4,0, 71, 34, 4,0 +, 74, 43, 19,0, 74, 43, 19,0,140, 63, 17,0,140, 63, 17,0 +,255,237, 74,0,255,237, 74,0, 14, 11, 3,0, 14, 11, 3,0 +,255,236, 76,0,255,236, 76,0, 82, 63, 15,0, 82, 63, 15,0 +,255,237, 75,0,255,237, 75,0, 80, 63, 19,0, 80, 63, 19,0 +, 86, 67, 22,0, 86, 67, 22,0,255,237, 75,0,255,237, 75,0 +, 67, 52, 16,0, 67, 52, 16,0,255,237, 74,0,255,237, 74,0 +, 43, 34, 8,0, 43, 34, 8,0,255,236, 76,0,255,236, 76,0 +, 66, 29, 0,0, 66, 29, 0,0, 71, 34, 4,0, 71, 34, 4,0 +, 77, 45, 20,0, 77, 45, 20,0,145, 71, 22,0,145, 71, 22,0 +,255,237, 75,0,255,237, 75,0,255,236, 76,0,255,236, 76,0 , 47, 37, 11,0, 47, 37, 11,0,108, 84, 26,0,108, 84, 26,0 -, 95, 76, 27,0, 95, 76, 27,0,255,238, 89,0,255,238, 89,0 -,255,238, 88,0,255,238, 88,0, 71, 55, 20,0, 71, 55, 20,0 -, 98, 77, 26,0, 98, 77, 26,0,255,238, 88,0,255,238, 88,0 -, 78, 62, 19,0, 78, 62, 19,0,255,238, 88,0,255,238, 88,0 -, 31, 15, 2,0, 31, 15, 2,0, 71, 40, 13,0, 71, 40, 13,0 -, 75, 48, 27,0, 75, 48, 27,0,138, 77, 35,0,138, 77, 35,0 -,255,238, 88,0,255,238, 88,0,255,238, 88,0,255,238, 88,0 -, 47, 37, 11,0, 49, 39, 13,0,108, 84, 26,0,108, 84, 26,0 -, 95, 76, 27,0, 95, 76, 27,0,255,238, 89,0,255,238, 89,0 -,255,238, 88,0,255,238, 88,0, 71, 55, 20,0, 71, 55, 20,0 -, 98, 77, 26,0, 98, 77, 26,0,255,238, 88,0,255,238, 88,0 -, 78, 62, 19,0, 78, 62, 19,0,255,238, 88,0,255,238, 88,0 -, 31, 15, 2,0, 31, 15, 2,0, 71, 40, 13,0, 71, 40, 13,0 -, 77, 50, 31,0, 77, 50, 31,0,127, 80, 43,0,127, 80, 43,0 -,118, 64, 25,0,118, 64, 25,0, 93, 47, 10,0, 93, 46, 7,0 -, 53, 24, 1,0, 53, 24, 1,0,122, 58, 6,0,122, 58, 6,0 -,128, 64, 15,0,128, 64, 15,0,117, 58, 15,0,117, 58, 15,0 -, 91, 46, 9,0, 91, 46, 9,0, 91, 46, 9,0, 91, 46, 9,0 -,119, 60, 10,0,119, 60, 10,0,115, 58, 11,0,115, 58, 11,0 -, 96, 43, 1,0, 96, 43, 1,0, 93, 47, 10,0, 93, 47, 10,0 -, 53, 28, 9,0, 54, 30, 10,0, 77, 46, 22,0, 77, 46, 22,0 -, 77, 50, 31,0, 77, 50, 31,0,127, 80, 43,0,127, 80, 43,0 -,118, 64, 25,0,118, 64, 25,0, 93, 46, 7,0, 93, 46, 7,0 -, 53, 24, 1,0, 53, 24, 1,0,122, 58, 6,0,122, 58, 6,0 -,128, 64, 15,0,119, 60, 10,0,117, 58, 15,0,117, 58, 15,0 -, 91, 46, 9,0, 91, 46, 9,0, 91, 46, 9,0, 91, 46, 9,0 -,119, 60, 10,0,119, 60, 10,0,115, 58, 11,0,115, 58, 11,0 -, 96, 43, 1,0, 96, 43, 1,0, 93, 47, 10,0, 93, 47, 10,0 -, 53, 28, 9,0, 53, 28, 9,0, 76, 46, 20,0, 77, 46, 22,0 -, 64, 46, 30,0, 64, 46, 30,0, 76, 49, 27,0, 76, 49, 27,0 -, 67, 41, 20,0, 67, 41, 20,0, 65, 37, 14,0, 68, 39, 16,0 -, 66, 37, 14,0, 66, 37, 14,0, 65, 37, 14,0, 65, 37, 14,0 -, 74, 43, 19,0, 71, 41, 19,0, 68, 39, 16,0, 68, 39, 16,0 -, 68, 39, 16,0, 68, 39, 16,0, 69, 39, 16,0, 69, 39, 16,0 -, 65, 37, 14,0, 65, 37, 14,0, 63, 35, 14,0, 63, 35, 14,0 -, 61, 35, 14,0, 65, 37, 14,0, 61, 35, 14,0, 61, 35, 14,0 -, 71, 41, 19,0, 71, 41, 19,0, 59, 37, 20,0, 59, 37, 20,0 -, 65, 45, 29,0, 64, 46, 30,0, 76, 49, 27,0, 76, 49, 27,0 -, 67, 41, 20,0, 67, 41, 20,0, 69, 39, 16,0, 65, 37, 14,0 -, 66, 37, 14,0, 71, 40, 13,0, 65, 37, 14,0, 65, 37, 14,0 -, 68, 41, 17,0, 68, 41, 17,0, 68, 39, 16,0, 68, 39, 16,0 -, 68, 39, 16,0, 69, 39, 16,0, 69, 39, 16,0, 69, 39, 16,0 -, 65, 37, 14,0, 65, 37, 14,0, 63, 35, 14,0, 65, 37, 14,0 -, 61, 35, 14,0, 62, 33, 10,0, 61, 35, 14,0, 61, 35, 14,0 -, 71, 41, 19,0, 71, 41, 19,0, 59, 37, 20,0, 59, 37, 20,0 +, 95, 76, 27,0, 95, 76, 27,0,255,236, 76,0,255,236, 76,0 +,255,236, 76,0,255,236, 76,0, 71, 55, 20,0, 71, 55, 20,0 +, 98, 77, 26,0, 98, 77, 26,0,255,236, 76,0,255,236, 76,0 +, 78, 62, 19,0, 78, 62, 19,0,255,236, 76,0,255,236, 76,0 +, 32, 14, 0,0, 32, 14, 0,0, 75, 37, 5,0, 75, 37, 5,0 +, 77, 45, 20,0, 77, 45, 20,0,145, 71, 22,0,145, 71, 22,0 +,255,237, 75,0,255,237, 75,0,255,236, 76,0,255,236, 76,0 +, 47, 37, 11,0, 47, 37, 11,0,108, 84, 26,0,108, 84, 26,0 +, 95, 76, 27,0, 95, 76, 27,0,255,236, 76,0,255,236, 76,0 +,255,236, 76,0,255,236, 76,0, 71, 55, 20,0, 71, 55, 20,0 +, 98, 77, 26,0, 98, 77, 26,0,255,236, 76,0,255,236, 76,0 +, 78, 62, 19,0, 78, 62, 19,0,255,236, 76,0,255,236, 76,0 +, 32, 14, 0,0, 32, 14, 0,0, 75, 37, 5,0, 75, 37, 5,0 +, 79, 46, 24,0, 79, 46, 24,0,132, 76, 31,0,132, 76, 31,0 +,124, 59, 13,0,124, 59, 13,0, 96, 43, 0,0, 96, 43, 0,0 +, 52, 23, 0,0, 52, 23, 0,0,123, 55, 0,0,123, 55, 0,0 +,136, 59, 1,0,136, 59, 1,0,124, 54, 2,0,124, 54, 2,0 +, 96, 43, 0,0, 96, 43, 0,0, 95, 42, 0,0, 95, 42, 0,0 +,124, 57, 0,0,124, 57, 0,0,121, 55, 0,0,121, 55, 0,0 +, 93, 41, 0,0, 93, 41, 0,0, 98, 43, 0,0, 98, 43, 0,0 +, 57, 28, 5,0, 57, 28, 5,0, 79, 43, 12,0, 79, 43, 12,0 +, 79, 46, 24,0, 79, 46, 24,0,132, 76, 31,0,132, 76, 31,0 +,124, 59, 13,0,124, 59, 13,0, 96, 43, 0,0, 96, 43, 0,0 +, 52, 23, 0,0, 52, 23, 0,0,123, 55, 0,0,123, 55, 0,0 +,136, 59, 1,0,136, 59, 1,0,124, 54, 2,0,124, 54, 2,0 +, 96, 43, 0,0, 96, 43, 0,0, 95, 42, 0,0, 95, 42, 0,0 +,124, 57, 0,0,124, 57, 0,0,121, 55, 0,0,121, 55, 0,0 +, 93, 41, 0,0, 93, 41, 0,0, 98, 43, 0,0, 98, 43, 0,0 +, 57, 28, 5,0, 57, 28, 5,0, 79, 43, 12,0, 79, 43, 12,0 +, 66, 43, 24,0, 66, 43, 24,0, 78, 46, 20,0, 78, 46, 20,0 +, 69, 38, 13,0, 69, 38, 13,0, 70, 36, 8,0, 70, 36, 8,0 +, 70, 35, 7,0, 70, 35, 7,0, 69, 35, 7,0, 69, 35, 7,0 +, 71, 39, 10,0, 71, 39, 10,0, 71, 36, 9,0, 71, 36, 9,0 +, 71, 36, 9,0, 71, 36, 9,0, 72, 36, 9,0, 72, 36, 9,0 +, 68, 36, 7,0, 68, 36, 7,0, 67, 33, 7,0, 67, 33, 7,0 +, 67, 33, 6,0, 67, 33, 6,0, 64, 33, 7,0, 64, 33, 7,0 +, 74, 38, 12,0, 74, 38, 12,0, 61, 35, 14,0, 61, 35, 14,0 +, 66, 43, 24,0, 66, 43, 24,0, 78, 46, 20,0, 78, 46, 20,0 +, 69, 38, 13,0, 69, 38, 13,0, 70, 36, 8,0, 70, 36, 8,0 +, 70, 35, 7,0, 70, 35, 7,0, 69, 35, 7,0, 69, 35, 7,0 +, 71, 39, 10,0, 71, 39, 10,0, 71, 36, 9,0, 71, 36, 9,0 +, 71, 36, 9,0, 71, 36, 9,0, 72, 36, 9,0, 72, 36, 9,0 +, 68, 36, 7,0, 68, 36, 7,0, 67, 33, 7,0, 67, 33, 7,0 +, 67, 33, 6,0, 67, 33, 6,0, 64, 33, 7,0, 64, 33, 7,0 +, 74, 38, 12,0, 74, 38, 12,0, 61, 35, 14,0, 61, 35, 14,0 #endif #ifdef LOGO_2 - 59, 42, 28,0, 87, 60, 38,0, 84, 57, 35,0, 81, 54, 33,0 -, 82, 56, 34,0, 88, 59, 36,0, 88, 59, 36,0, 88, 59, 36,0 -, 86, 58, 36,0, 88, 59, 36,0, 89, 60, 37,0, 89, 60, 37,0 -, 87, 60, 38,0, 89, 60, 37,0, 88, 59, 36,0, 84, 57, 35,0 -, 78, 52, 32,0, 84, 57, 35,0, 89, 60, 37,0, 87, 60, 38,0 -, 84, 57, 35,0, 86, 58, 36,0, 84, 57, 35,0, 82, 56, 34,0 -, 82, 56, 34,0, 82, 56, 34,0, 81, 54, 33,0, 76, 51, 31,0 -, 76, 51, 31,0, 81, 54, 33,0, 86, 58, 36,0, 57, 40, 26,0 -, 89, 60, 37,0,136, 95, 61,0,162,108, 65,0,156,103, 62,0 -,153,101, 61,0,160,106, 64,0,158,105, 64,0,156,103, 62,0 -,164,109, 66,0,164,109, 66,0,164,109, 66,0,154,104, 62,0 -,156,103, 62,0,157,104, 62,0,156,103, 62,0,145, 96, 58,0 -,153,101, 61,0,148, 98, 60,0,153,101, 61,0,153,101, 61,0 -,162,108, 65,0,162,108, 65,0,156,103, 62,0,154,104, 62,0 -,156,103, 62,0,162,108, 65,0,148, 98, 60,0,143, 96, 58,0 -,145, 96, 58,0,156,103, 62,0,152,104, 66,0, 87, 60, 38,0 -, 73, 49, 32,0,146, 97, 60,0,148,103, 66,0,167,111, 68,0 -,158,105, 64,0,157,104, 62,0,154,103, 64,0,143, 96, 58,0 -,143, 96, 58,0,143, 96, 58,0,146, 97, 60,0,143, 96, 58,0 -,137, 90, 53,0,148, 97, 57,0,148, 97, 57,0,139, 92, 53,0 -,139, 92, 53,0,138, 92, 56,0,148, 97, 57,0,153,101, 61,0 -,148, 98, 60,0,141, 94, 57,0,141, 94, 57,0,131, 88, 53,0 -,144, 94, 57,0,143, 96, 58,0,150,100, 61,0,148, 98, 60,0 -,154,104, 62,0,142, 97, 62,0,164,109, 66,0, 78, 52, 32,0 -, 70, 48, 29,0,135, 90, 56,0,169,112, 68,0,135, 92, 60,0 -,132, 96, 62,0,130, 97, 62,0,137,101, 66,0,144,106, 69,0 -,140,104, 68,0,138,104, 70,0,137,102, 68,0,140,104, 68,0 -,130, 93, 56,0,223,192, 81,0,237,207, 88,0,237,207, 88,0 -,236,206, 86,0,237,207, 88,0,237,207, 88,0,137,101, 66,0 -,144,106, 69,0,137,102, 68,0,133,101, 66,0,133,101, 66,0 -,137,102, 68,0,130, 97, 62,0,121, 90, 57,0,124, 90, 58,0 -,123, 86, 55,0,162,108, 65,0,156,103, 62,0, 76, 51, 31,0 -, 73, 49, 30,0,146, 97, 60,0,160,106, 64,0,117, 88, 56,0 -,130,112, 74,0,130,112, 74,0,130,112, 74,0,154,135, 91,0 -,166,148,101,0,166,148,101,0,168,149,102,0,166,148, 99,0 -,147,124, 77,0,132,107, 61,0,215,184, 75,0,234,205, 88,0 -,156,136, 86,0,150,129, 80,0,234,205, 85,0,236,206, 86,0 -,164,145, 98,0,164,145, 98,0,165,146,100,0,166,148,101,0 -,154,135, 91,0,130,112, 74,0,133,114, 76,0,133,114, 76,0 -,110, 85, 54,0,153,101, 61,0,164,109, 66,0, 78, 52, 32,0 -, 70, 48, 29,0,158,105, 64,0,162,108, 65,0,124, 90, 58,0 -,129,110, 73,0,130,113, 76,0,130,113, 76,0,129,110, 73,0 -,148,129, 86,0,164,145, 98,0,166,148, 99,0,166,148, 99,0 -,161,142, 93,0,132,107, 61,0,212,178, 73,0,239,210, 92,0 -,156,135, 82,0,153,130, 79,0,236,206, 86,0,238,209, 89,0 -,162,144, 95,0,168,149,102,0,168,149,102,0,150,132, 89,0 -,127,109, 72,0,129,110, 73,0,130,112, 74,0,130,112, 74,0 -,112, 86, 55,0,153,101, 61,0,175,116, 70,0, 73, 49, 30,0 -, 73, 49, 30,0,146, 97, 60,0,167,112, 66,0,137,101, 66,0 -,129,110, 73,0,130,112, 74,0,133,114, 76,0,133,114, 76,0 -,130,112, 74,0,149,131, 88,0,166,148, 99,0,162,144, 95,0 -,157,138, 89,0,132,107, 61,0,208,175, 70,0,234,205, 88,0 -,234,205, 88,0,224,193, 81,0,232,203, 84,0,159,140, 90,0 -,162,144, 97,0,166,148, 99,0,150,132, 89,0,130,112, 74,0 -,133,114, 76,0,132,112, 74,0,130,112, 74,0,130,112, 74,0 -,123, 96, 63,0,150,100, 61,0,160,106, 64,0, 76, 51, 31,0 -, 75, 52, 33,0,141, 94, 57,0,169,113, 67,0,144,106, 69,0 -,161,142, 96,0,129,110, 73,0,129,110, 73,0,132,112, 74,0 -,132,112, 74,0,127,109, 72,0,150,132, 89,0,164,145, 98,0 -,161,142, 93,0,135,112, 63,0,215,184, 75,0,239,210, 92,0 -,156,135, 82,0,144,122, 72,0,232,203, 84,0,237,207, 88,0 -,162,144, 95,0,148,129, 86,0,127,109, 72,0,132,112, 74,0 -,132,112, 74,0,130,112, 74,0,130,112, 74,0,164,145, 98,0 -,127,100, 66,0,150,100, 61,0,156,103, 62,0, 81, 54, 33,0 -, 78, 52, 32,0,144, 94, 57,0,169,113, 67,0,149,109, 69,0 -,166,148,101,0,161,142, 96,0,129,110, 73,0,127,109, 72,0 -,130,112, 74,0,130,112, 74,0,129,110, 73,0,146,128, 84,0 -,153,134, 84,0,137,113, 65,0,217,185, 74,0,236,206, 86,0 -,156,135, 82,0,148,128, 75,0,227,197, 82,0,236,206, 86,0 -,148,129, 86,0,130,112, 74,0,130,112, 74,0,129,110, 73,0 -,127,109, 72,0,127,109, 72,0,161,142, 96,0,168,149,102,0 -,129,100, 68,0,148, 98, 60,0,157,104, 62,0, 82, 56, 34,0 -, 81, 54, 33,0,143, 96, 58,0,173,115, 69,0,149,109, 69,0 -,165,146,100,0,166,148,101,0,161,142, 96,0,130,112, 74,0 -,130,112, 74,0,136,115, 77,0,136,115, 77,0,130,109, 70,0 -,129,106, 61,0,202,166, 65,0,204,170, 69,0,222,190, 80,0 -,227,197, 82,0,217,185, 76,0,217,185, 74,0,140,120, 76,0 -,130,112, 74,0,134,116, 77,0,133,114, 76,0,129,110, 73,0 -,133,114, 76,0,162,144, 97,0,168,149,102,0,166,148,101,0 -,130,100, 65,0,148, 98, 60,0,160,106, 64,0, 82, 56, 34,0 -, 73, 49, 30,0,146, 97, 60,0,167,111, 68,0,149,110, 72,0 -,169,150,104,0,169,150,104,0,165,146,100,0,164,145, 98,0 -,134,116, 77,0,133,114, 76,0,133,114, 76,0,130,109, 70,0 -,115, 94, 55,0,117, 93, 53,0,137,113, 65,0,144,122, 72,0 -,146,124, 75,0,148,126, 78,0,136,117, 73,0,129,110, 73,0 -,134,116, 77,0,134,116, 77,0,132,112, 74,0,134,116, 77,0 -,164,145, 98,0,168,149,102,0,169,150,104,0,166,148,101,0 -,127,100, 66,0,148, 98, 60,0,167,111, 68,0, 82, 56, 34,0 -, 73, 49, 30,0,144, 94, 57,0,161,106, 62,0,153,110, 70,0 -,164,145, 98,0,164,145, 98,0,165,146,100,0,165,146,100,0 -,161,142, 96,0,134,116, 77,0,129,110, 73,0,132,112, 74,0 -,130,109, 70,0,117, 97, 59,0,136,117, 73,0,157,138, 89,0 -,156,136, 86,0,136,117, 73,0,125,106, 68,0,133,114, 76,0 -,136,115, 77,0,130,112, 74,0,134,116, 77,0,164,145, 98,0 -,166,148, 99,0,166,148,101,0,166,148,101,0,165,146,100,0 -,133,101, 66,0,146, 97, 60,0,157,104, 62,0, 81, 54, 33,0 -, 73, 49, 30,0,141, 93, 54,0,158,100, 55,0,227,197, 82,0 -,240,212, 94,0,240,212, 94,0,240,210, 92,0,238,209, 89,0 -,158,140, 93,0,162,144, 95,0,130,113, 76,0,126,108, 70,0 -,125,105, 65,0,125,105, 65,0,239,210, 92,0,240,210, 90,0 -,238,209, 89,0,240,210, 90,0,237,208, 86,0,132,112, 74,0 -,130,112, 74,0,135,117, 80,0,161,142, 93,0,161,142, 93,0 -,240,210, 92,0,240,210, 90,0,240,210, 90,0,240,210, 90,0 -,126, 98, 64,0,143, 96, 58,0,153,101, 61,0, 81, 54, 33,0 -, 69, 46, 28,0,141, 93, 54,0,152, 93, 47,0,110, 72, 38,0 -,215,184, 75,0,236,206, 86,0,157,138, 89,0,231,202, 85,0 -,237,207, 88,0,166,148,101,0,165,146,100,0,133,116, 75,0 -,114, 93, 56,0,222,190, 80,0,236,206, 86,0,122,100, 59,0 -,113, 88, 53,0,109, 87, 48,0,234,205, 88,0,237,207, 88,0 -,135,117, 80,0,162,144, 95,0,148,126, 78,0,217,185, 74,0 -,236,206, 86,0,152,130, 81,0,156,136, 86,0,232,203, 84,0 -,236,206, 86,0,148, 98, 60,0,154,104, 62,0, 78, 52, 32,0 -, 73, 49, 30,0,136, 88, 50,0,151, 94, 49,0,113, 70, 33,0 -,205,173, 66,0,232,204, 82,0,153,133, 79,0,140,117, 70,0 -,231,202, 85,0,236,206, 86,0,166,148, 99,0,162,144, 95,0 -,109, 88, 49,0,212,178, 73,0,232,203, 84,0,125,103, 62,0 -,121, 99, 57,0, 97, 75, 37,0,214,182, 73,0,234,205, 85,0 -,158,140, 93,0,157,138, 89,0,135,112, 63,0,195,160, 60,0 -,221,189, 77,0,232,204, 82,0,154,133, 81,0,159,140, 90,0 -,126, 96, 61,0,125, 84, 50,0,169,112, 68,0, 78, 52, 32,0 -, 76, 51, 31,0,136, 88, 50,0,158, 98, 51,0,113, 70, 33,0 -,214,182, 73,0,237,207, 88,0,148,128, 75,0,140,117, 70,0 -,223,192, 81,0,238,209, 89,0,164,145, 95,0,160,140, 90,0 -,129,106, 61,0,215,184, 75,0,239,210, 92,0,125,105, 65,0 -,125,103, 62,0, 99, 77, 40,0,214,182, 73,0,238,209, 89,0 -,161,142, 93,0,155,136, 86,0,133,109, 62,0,123, 98, 52,0 -,209,176, 70,0,232,203, 84,0,237,208, 86,0,157,138, 89,0 -,123, 95, 59,0,131, 88, 53,0,153,101, 61,0, 82, 56, 34,0 -, 75, 52, 33,0,130, 85, 49,0,161,101, 54,0,115, 72, 34,0 -,217,185, 74,0,234,205, 85,0,150,129, 76,0,144,121, 71,0 -,224,194, 77,0,232,204, 82,0,155,136, 86,0,156,136, 86,0 -,102, 80, 41,0,205,173, 66,0,234,205, 85,0,130,109, 70,0 -,125,105, 65,0,106, 84, 45,0,217,185, 74,0,234,205, 85,0 -,162,144, 95,0,164,145, 95,0,150,129, 80,0,144,121, 71,0 -,144,121, 71,0,141,120, 69,0,230,200, 81,0,234,205, 85,0 -,234,205, 85,0,133, 89, 53,0,153,101, 61,0, 82, 56, 34,0 -, 73, 49, 30,0,132, 84, 49,0,154, 93, 48,0,115, 73, 36,0 -,222,190, 80,0,237,208, 86,0,153,133, 79,0,238,209, 89,0 -,236,206, 86,0,157,138, 89,0,157,138, 89,0,125,105, 65,0 -, 97, 75, 40,0,202,166, 65,0,237,208, 86,0,121,101, 60,0 -,121,101, 60,0,112, 91, 49,0,228,197, 84,0,240,210, 90,0 -,134,116, 77,0,164,145, 98,0,152,130, 81,0,223,192, 81,0 -,238,209, 89,0,150,129, 76,0,144,121, 71,0,234,205, 85,0 -,238,209, 89,0,137, 90, 53,0,160,106, 64,0, 82, 56, 34,0 -, 69, 46, 28,0,139, 92, 53,0,147, 87, 44,0,202,169, 70,0 -,205,172, 72,0,219,189, 82,0,222,190, 80,0,221,189, 77,0 -,153,134, 84,0,161,142, 93,0,130,113, 76,0,125,105, 65,0 -,109, 87, 48,0,101, 77, 41,0,212,178, 73,0,230,200, 81,0 -,230,200, 81,0,217,185, 74,0,220,187, 77,0,125,105, 65,0 -,127,109, 72,0,130,112, 74,0,147,124, 77,0,137,113, 65,0 -,214,182, 73,0,221,189, 77,0,214,182, 73,0,217,185, 76,0 -,113, 88, 53,0,156,103, 62,0,150,100, 61,0, 78, 52, 32,0 -, 69, 46, 28,0,139, 92, 53,0,140, 86, 45,0,117, 76, 39,0 -,135,112, 63,0,137,113, 65,0,142,118, 72,0,152,130, 81,0 -,159,140, 90,0,134,116, 77,0,132,112, 74,0,132,112, 74,0 -,125,105, 65,0,107, 86, 49,0,122,100, 59,0,144,122, 72,0 -,142,120, 73,0,122,100, 59,0,117, 97, 59,0,130,109, 70,0 -,132,112, 74,0,126,108, 70,0,125,105, 65,0,134,112, 65,0 -,134,112, 65,0,137,113, 65,0,142,118, 72,0,150,129, 80,0 -,121, 90, 57,0,138, 92, 56,0,158,105, 64,0, 78, 52, 32,0 -, 69, 46, 28,0,137, 90, 53,0,155,101, 57,0,145,102, 62,0 -,160,140, 90,0,162,144, 95,0,164,145, 98,0,162,144, 95,0 -,133,114, 76,0,132,112, 74,0,133,114, 76,0,132,112, 74,0 -,125,106, 68,0,140,120, 76,0,159,140, 90,0,157,138, 89,0 -,160,140, 90,0,156,136, 86,0,143,124, 80,0,130,109, 70,0 -,133,114, 76,0,132,112, 74,0,126,108, 70,0,125,106, 68,0 -,153,134, 84,0,155,136, 86,0,159,140, 90,0,158,140, 93,0 -,130,100, 65,0,145, 96, 58,0,158,105, 64,0, 76, 51, 31,0 -, 73, 49, 30,0,130, 87, 52,0,167,109, 63,0,143,105, 67,0 -,164,145, 98,0,166,148,101,0,164,145, 98,0,130,113, 76,0 -,130,112, 74,0,136,115, 77,0,136,115, 77,0,130,112, 74,0 -,137,116, 77,0,236,206, 86,0,236,206, 86,0,161,142, 93,0 -,161,142, 93,0,155,136, 86,0,236,206, 86,0,236,206, 86,0 -,130,112, 74,0,133,114, 76,0,133,114, 76,0,125,106, 68,0 -,126,108, 70,0,157,138, 89,0,161,142, 93,0,166,148,101,0 -,129,100, 68,0,143, 96, 58,0,154,104, 62,0, 77, 52, 31,0 -, 81, 54, 33,0,131, 88, 53,0,154,104, 62,0,146,108, 70,0 -,166,148,101,0,164,145, 98,0,130,113, 76,0,130,112, 74,0 -,132,112, 74,0,132,112, 74,0,129,110, 73,0,145,125, 81,0 -,139,116, 69,0,212,178, 73,0,240,212, 94,0,164,145, 95,0 -,162,144, 95,0,157,138, 89,0,239,210, 92,0,240,210, 90,0 -,147,127, 86,0,130,112, 74,0,132,112, 74,0,130,112, 74,0 -,129,110, 73,0,129,110, 73,0,158,140, 93,0,162,144, 97,0 -,127,100, 66,0,133, 89, 53,0,156,103, 62,0, 78, 52, 32,0 -, 78, 52, 32,0,141, 94, 57,0,162,108, 65,0,152,111, 72,0 -,162,144, 97,0,129,110, 73,0,129,110, 73,0,129,110, 73,0 -,129,110, 73,0,126,108, 70,0,148,129, 86,0,162,144, 95,0 -,140,117, 70,0,129,105, 58,0,217,185, 74,0,236,206, 86,0 -,156,136, 86,0,234,205, 85,0,237,207, 88,0,162,144, 95,0 -,165,146,100,0,149,131, 88,0,127,109, 72,0,130,112, 74,0 -,129,110, 73,0,129,110, 73,0,127,109, 72,0,158,140, 93,0 -,126, 98, 64,0,146, 97, 60,0,153,101, 61,0, 81, 54, 33,0 -, 73, 49, 32,0,138, 92, 56,0,164,109, 66,0,140,104, 68,0 -,130,112, 74,0,129,110, 73,0,129,110, 73,0,129,110, 73,0 -,127,109, 72,0,146,128, 84,0,161,142, 96,0,159,140, 90,0 -,155,136, 86,0,137,113, 65,0,133,109, 62,0,224,194, 77,0 -,236,206, 86,0,236,206, 86,0,160,139, 90,0,164,145, 95,0 -,165,146,100,0,166,148,101,0,150,132, 89,0,130,113, 76,0 -,134,116, 77,0,133,114, 76,0,130,113, 76,0,130,113, 76,0 -,122, 95, 61,0,143, 96, 58,0,148, 98, 60,0, 78, 52, 32,0 -, 69, 46, 28,0,135, 90, 56,0,164,109, 66,0,117, 88, 56,0 -,129,110, 73,0,129,110, 73,0,129,110, 73,0,129,110, 73,0 -,149,131, 88,0,164,145, 98,0,164,145, 98,0,161,142, 93,0 -,157,138, 89,0,146,124, 75,0,137,113, 65,0,220,187, 77,0 -,227,197, 82,0,238,209, 89,0,160,140, 90,0,165,146,100,0 -,166,148,101,0,166,148,101,0,164,145, 98,0,150,132, 89,0 -,129,110, 73,0,130,112, 74,0,130,112, 74,0,129,110, 73,0 -,102, 81, 53,0,143, 96, 58,0,150,100, 61,0, 73, 49, 30,0 -, 69, 46, 28,0,146, 97, 60,0,162,108, 65,0,124, 90, 58,0 -,133,114, 76,0,130,112, 74,0,127,109, 72,0,148,129, 86,0 -,162,144, 97,0,165,146,100,0,166,148, 99,0,161,142, 93,0 -,153,134, 84,0,146,124, 75,0,230,200, 81,0,224,194, 77,0 -,133,109, 62,0,217,185, 74,0,234,205, 85,0,162,144, 95,0 -,162,144, 95,0,165,146,100,0,165,146,100,0,165,146,100,0 -,154,137, 93,0,130,112, 74,0,130,112, 74,0,129,110, 73,0 -,110, 85, 54,0,148, 98, 60,0,169,112, 68,0, 70, 48, 29,0 -, 70, 48, 29,0,138, 92, 56,0,162,108, 65,0,121, 90, 57,0 -,130,112, 74,0,129,110, 73,0,150,132, 89,0,162,144, 95,0 -,162,144, 97,0,161,142, 96,0,158,140, 93,0,157,138, 89,0 -,141,120, 69,0,220,187, 77,0,237,208, 86,0,148,128, 75,0 -,135,112, 63,0,129,105, 58,0,230,200, 81,0,238,209, 89,0 -,162,144, 97,0,165,146,100,0,168,149,102,0,169,150,104,0 -,166,148,101,0,150,132, 89,0,129,110, 73,0,130,112, 74,0 -,112, 86, 55,0,150,100, 61,0,164,109, 66,0, 76, 51, 31,0 -, 70, 48, 29,0,135, 90, 56,0,164,109, 66,0,131, 90, 57,0 -,132, 96, 62,0,149,109, 69,0,157,116, 73,0,154,114, 74,0 -,149,110, 72,0,152,111, 72,0,149,109, 69,0,150,109, 66,0 -,125, 82, 44,0,202,168, 67,0,224,193, 81,0,150,107, 61,0 -,150,106, 59,0,117, 76, 39,0,204,170, 67,0,232,203, 84,0 -,152,111, 72,0,152,111, 72,0,149,110, 72,0,149,110, 72,0 -,154,114, 74,0,153,110, 70,0,146,108, 70,0,126, 92, 60,0 -,124, 90, 58,0,167,111, 68,0,157,104, 62,0, 76, 51, 31,0 -, 73, 49, 32,0,141, 94, 57,0,142, 97, 62,0,154,103, 64,0 -,148, 98, 60,0,158,105, 64,0,148, 98, 60,0,141, 94, 57,0 -,141, 94, 57,0,141, 94, 57,0,144, 94, 57,0,147, 94, 54,0 -,128, 76, 37,0,128, 76, 37,0,140, 86, 45,0,147, 94, 54,0 -,129, 81, 45,0,128, 76, 37,0,123, 76, 37,0,129, 81, 45,0 -,153,101, 61,0,145, 96, 58,0,150,100, 61,0,150,100, 61,0 -,141, 94, 57,0,138, 92, 56,0,145, 96, 58,0,143, 96, 58,0 -,150,100, 61,0,142, 97, 62,0,167,111, 68,0, 81, 54, 33,0 -, 87, 60, 38,0,115, 78, 49,0,135, 90, 56,0,127, 84, 52,0 -,119, 80, 49,0,121, 81, 49,0,115, 78, 49,0,115, 78, 49,0 -,124, 82, 50,0,121, 81, 49,0,125, 84, 50,0,136, 88, 50,0 -,121, 78, 45,0,115, 75, 44,0,121, 78, 45,0,115, 75, 44,0 -,115, 75, 44,0,115, 75, 44,0,115, 75, 44,0,121, 78, 45,0 -,124, 82, 50,0,125, 84, 50,0,121, 81, 49,0,124, 82, 50,0 -,119, 80, 49,0,119, 80, 49,0,115, 78, 49,0,115, 78, 49,0 -,121, 81, 49,0,133, 89, 53,0,135, 92, 60,0, 88, 59, 36,0 -, 61, 43, 29,0, 87, 60, 38,0, 73, 49, 30,0, 69, 46, 28,0 -, 69, 46, 28,0, 70, 48, 29,0, 70, 48, 29,0, 70, 48, 29,0 -, 70, 48, 29,0, 70, 48, 29,0, 73, 49, 30,0, 69, 46, 28,0 -, 70, 48, 29,0, 73, 49, 30,0, 69, 46, 28,0, 69, 46, 28,0 -, 69, 45, 26,0, 69, 45, 26,0, 73, 49, 30,0, 70, 48, 29,0 -, 69, 46, 28,0, 73, 49, 30,0, 69, 46, 28,0, 69, 46, 28,0 -, 69, 46, 28,0, 69, 46, 28,0, 69, 46, 28,0, 65, 44, 28,0 -, 65, 44, 28,0, 73, 49, 30,0, 86, 58, 36,0, 60, 42, 27,0 + 61, 39, 23,0, 91, 57, 30,0, 85, 53, 28,0, 82, 51, 26,0 +, 83, 52, 28,0, 91, 57, 30,0, 91, 57, 30,0, 91, 57, 30,0 +, 88, 55, 29,0, 91, 57, 30,0, 91, 57, 30,0, 91, 57, 30,0 +, 91, 57, 30,0, 91, 57, 30,0, 91, 57, 30,0, 88, 55, 29,0 +, 80, 50, 25,0, 85, 53, 28,0, 91, 57, 30,0, 91, 57, 30,0 +, 85, 53, 28,0, 88, 55, 29,0, 88, 55, 29,0, 85, 53, 28,0 +, 85, 53, 28,0, 85, 53, 28,0, 82, 51, 26,0, 78, 48, 25,0 +, 78, 48, 25,0, 82, 51, 26,0, 88, 55, 29,0, 61, 39, 23,0 +, 91, 57, 30,0,140, 89, 49,0,166,101, 49,0,161, 97, 49,0 +,157, 96, 49,0,165, 99, 50,0,165, 99, 50,0,161, 99, 50,0 +,170,104, 52,0,170,104, 52,0,170,104, 52,0,157, 96, 49,0 +,161, 97, 49,0,162, 99, 50,0,161, 97, 49,0,148, 89, 46,0 +,156, 95, 48,0,153, 93, 47,0,156, 95, 48,0,156, 95, 47,0 +,166,101, 49,0,166,101, 49,0,159, 98, 50,0,157, 96, 49,0 +,160, 96, 49,0,166,101, 49,0,150, 92, 47,0,148, 89, 46,0 +,148, 89, 46,0,160, 96, 49,0,156, 99, 53,0, 91, 57, 30,0 +, 75, 46, 24,0,150, 92, 47,0,151, 99, 53,0,172,106, 53,0 +,162, 99, 50,0,162, 99, 50,0,159, 98, 50,0,147, 91, 46,0 +,148, 89, 46,0,146, 89, 47,0,150, 92, 47,0,147, 91, 46,0 +,140, 84, 42,0,153, 91, 44,0,153, 91, 44,0,145, 86, 41,0 +,145, 86, 41,0,145, 86, 41,0,150, 92, 47,0,157, 96, 49,0 +,150, 92, 47,0,143, 87, 44,0,144, 89, 45,0,136, 84, 42,0 +,148, 89, 46,0,148, 89, 46,0,156, 95, 48,0,150, 92, 47,0 +,159, 98, 50,0,145, 93, 52,0,170,104, 52,0, 80, 50, 25,0 +, 71, 45, 23,0,140, 84, 42,0,172,106, 53,0,137, 87, 53,0 +,132, 92, 57,0,132, 92, 57,0,140, 97, 61,0,141,101, 64,0 +,141,101, 64,0,141,101, 64,0,140, 97, 61,0,141,101, 64,0 +,132, 88, 51,0,231,192, 61,0,245,209, 66,0,245,209, 66,0 +,245,209, 66,0,246,210, 68,0,243,209, 68,0,136, 97, 62,0 +,141,101, 64,0,136, 97, 62,0,136, 97, 62,0,136, 97, 62,0 +,136, 97, 62,0,132, 92, 57,0,122, 85, 52,0,125, 88, 54,0 +,122, 85, 52,0,168,102, 50,0,161, 97, 49,0, 78, 48, 25,0 +, 75, 46, 24,0,150, 92, 47,0,165, 99, 50,0,122, 85, 52,0 +,132,112, 74,0,130,111, 74,0,130,111, 74,0,154,135, 91,0 +,167,148,101,0,167,148,101,0,168,149,102,0,166,147, 99,0 +,147,124, 78,0,132,107, 61,0,224,185, 54,0,242,206, 67,0 +,156,136, 86,0,151,129, 80,0,242,208, 64,0,244,207, 66,0 +,164,145, 99,0,165,146, 99,0,165,146, 99,0,167,148,101,0 +,154,135, 91,0,132,112, 74,0,131,113, 76,0,134,115, 78,0 +,113, 84, 53,0,156, 95, 48,0,171,103, 50,0, 80, 50, 25,0 +, 72, 44, 22,0,163,102, 51,0,168,102, 50,0,125, 88, 54,0 +,128,110, 73,0,131,113, 76,0,131,113, 76,0,128,110, 73,0 +,148,130, 87,0,164,145, 99,0,167,148,101,0,166,147, 98,0 +,162,143, 92,0,132,107, 61,0,220,180, 55,0,247,212, 70,0 +,155,135, 82,0,152,130, 81,0,243,209, 65,0,246,212, 67,0 +,163,144, 96,0,168,149,102,0,168,149,102,0,150,132, 89,0 +,127,109, 71,0,130,111, 74,0,132,112, 74,0,129,112, 75,0 +,113, 84, 53,0,156, 95, 48,0,178,109, 54,0, 75, 46, 24,0 +, 75, 46, 24,0,150, 92, 47,0,172,106, 53,0,140, 97, 61,0 +,128,111, 74,0,129,112, 75,0,133,113, 75,0,133,113, 75,0 +,132,112, 74,0,150,132, 89,0,166,147, 98,0,163,144, 96,0 +,158,138, 88,0,132,107, 61,0,217,177, 51,0,243,207, 69,0 +,243,207, 69,0,231,192, 61,0,240,205, 65,0,159,140, 90,0 +,163,144, 96,0,167,148,101,0,150,132, 89,0,130,111, 74,0 +,133,114, 76,0,133,113, 75,0,130,111, 74,0,129,112, 75,0 +,123, 93, 58,0,154, 94, 48,0,165, 99, 50,0, 78, 48, 25,0 +, 78, 48, 25,0,144, 88, 45,0,174,108, 52,0,142,101, 62,0 +,161,141, 95,0,128,111, 74,0,130,111, 74,0,133,113, 75,0 +,133,113, 75,0,128,110, 73,0,150,132, 89,0,165,146, 98,0 +,161,142, 93,0,135,112, 64,0,223,183, 55,0,247,212, 70,0 +,155,135, 82,0,144,122, 72,0,240,205, 65,0,245,209, 66,0 +,163,143, 95,0,148,130, 87,0,127,109, 71,0,133,113, 75,0 +,133,113, 75,0,130,111, 74,0,129,112, 75,0,164,145, 99,0 +,126, 96, 62,0,154, 94, 48,0,161, 97, 49,0, 83, 52, 28,0 +, 80, 50, 25,0,147, 91, 46,0,178,109, 54,0,148,103, 65,0 +,166,147,100,0,161,142, 95,0,128,111, 74,0,128,109, 72,0 +,132,112, 74,0,132,112, 74,0,130,110, 73,0,147,128, 85,0 +,153,132, 84,0,137,114, 66,0,224,185, 54,0,245,209, 66,0 +,155,135, 82,0,149,129, 75,0,235,199, 63,0,245,209, 66,0 +,148,130, 87,0,130,111, 74,0,132,112, 74,0,130,111, 74,0 +,128,110, 73,0,128,111, 74,0,161,142, 95,0,168,149,102,0 +,127, 97, 63,0,153, 93, 47,0,162, 99, 50,0, 83, 52, 28,0 +, 82, 51, 26,0,148, 89, 46,0,178,109, 54,0,151,106, 65,0 +,166,147,100,0,167,148,101,0,160,143, 95,0,129,112, 75,0 +,129,112, 75,0,135,115, 77,0,135,115, 77,0,130,109, 69,0 +,129,106, 61,0,210,166, 47,0,210,169, 51,0,231,192, 61,0 +,234,197, 61,0,224,185, 56,0,225,189, 55,0,141,120, 75,0 +,130,111, 74,0,134,116, 78,0,133,114, 76,0,128,110, 73,0 +,132,114, 76,0,163,144, 98,0,168,149,102,0,167,148,101,0 +,127, 97, 63,0,153, 93, 47,0,163,102, 51,0, 84, 52, 27,0 +, 75, 46, 24,0,150, 92, 47,0,170,104, 52,0,147,105, 69,0 +,170,151,105,0,170,151,105,0,166,147,100,0,164,145, 99,0 +,134,116, 78,0,133,114, 76,0,133,114, 76,0,131,110, 71,0 +,116, 94, 54,0,116, 94, 54,0,137,114, 66,0,144,122, 72,0 +,146,125, 75,0,148,127, 78,0,137,117, 73,0,130,110, 73,0 +,134,116, 78,0,134,116, 78,0,133,113, 75,0,134,116, 78,0 +,164,145, 99,0,168,149,102,0,170,151,105,0,167,148,101,0 +,126, 96, 62,0,150, 92, 47,0,172,106, 53,0, 85, 53, 28,0 +, 75, 46, 24,0,147, 91, 46,0,166,101, 49,0,151,106, 65,0 +,165,146, 98,0,165,146, 98,0,165,146, 99,0,165,146, 99,0 +,160,143, 95,0,134,116, 78,0,130,110, 73,0,132,112, 74,0 +,130,109, 69,0,117, 98, 59,0,137,117, 73,0,158,138, 88,0 +,156,136, 86,0,137,117, 73,0,125,105, 65,0,133,114, 76,0 +,135,115, 77,0,130,111, 74,0,134,116, 78,0,164,145, 99,0 +,166,147, 99,0,167,148,101,0,166,147,100,0,166,147,100,0 +,134, 97, 62,0,150, 92, 47,0,162, 99, 50,0, 84, 52, 27,0 +, 75, 46, 24,0,146, 89, 43,0,162, 95, 42,0,234,197, 61,0 +,248,214, 73,0,248,214, 73,0,248,211, 69,0,246,210, 68,0 +,159,140, 93,0,163,144, 96,0,131,113, 76,0,126,107, 69,0 +,125,105, 65,0,125,105, 65,0,247,212, 70,0,248,211, 69,0 +,246,210, 68,0,248,211, 69,0,245,211, 67,0,132,112, 74,0 +,132,112, 74,0,134,116, 78,0,161,141, 95,0,162,142, 94,0 +,247,212, 70,0,247,212, 70,0,248,211, 69,0,247,212, 70,0 +,123, 93, 58,0,148, 89, 46,0,157, 96, 49,0, 84, 52, 27,0 +, 72, 44, 22,0,145, 86, 41,0,158, 87, 33,0,110, 68, 32,0 +,224,185, 56,0,243,209, 68,0,158,138, 88,0,240,205, 65,0 +,244,208, 66,0,167,148,101,0,165,146, 99,0,134,116, 76,0 +,114, 93, 56,0,231,192, 61,0,244,208, 66,0,122,100, 60,0 +,112, 90, 51,0,109, 87, 49,0,241,207, 67,0,244,208, 66,0 +,134,116, 78,0,162,142, 94,0,148,127, 78,0,225,187, 56,0 +,243,209, 65,0,152,130, 81,0,156,136, 86,0,240,205, 65,0 +,245,209, 66,0,153, 93, 47,0,159, 98, 50,0, 80, 50, 25,0 +, 75, 46, 24,0,142, 84, 38,0,157, 88, 35,0,117, 67, 29,0 +,214,174, 48,0,241,206, 62,0,153,133, 80,0,141,118, 71,0 +,239,202, 64,0,243,208, 67,0,166,147, 99,0,163,143, 95,0 +,109, 87, 49,0,221,179, 53,0,241,206, 62,0,124,103, 62,0 +,121, 99, 57,0, 97, 75, 39,0,223,183, 53,0,241,206, 62,0 +,159,140, 93,0,157,139, 89,0,135,112, 64,0,202,161, 42,0 +,232,194, 57,0,241,206, 62,0,153,133, 80,0,159,139, 90,0 +,123, 93, 58,0,127, 79, 39,0,172,106, 53,0, 80, 50, 25,0 +, 78, 48, 25,0,142, 84, 38,0,166, 93, 38,0,117, 67, 29,0 +,221,183, 53,0,245,209, 66,0,149,129, 75,0,140,117, 70,0 +,231,192, 61,0,246,212, 67,0,164,145, 96,0,161,141, 92,0 +,129,106, 61,0,222,184, 56,0,247,212, 70,0,125,105, 65,0 +,124,103, 62,0,100, 77, 41,0,221,183, 53,0,245,211, 67,0 +,161,141, 92,0,155,136, 86,0,134,109, 62,0,123, 98, 52,0 +,217,177, 51,0,240,205, 65,0,245,209, 66,0,157,139, 89,0 +,123, 93, 58,0,137, 83, 40,0,157, 96, 49,0, 84, 52, 27,0 +, 78, 48, 25,0,132, 79, 38,0,166, 93, 38,0,117, 67, 29,0 +,224,185, 54,0,241,206, 62,0,149,129, 75,0,144,122, 72,0 +,232,194, 57,0,241,206, 62,0,155,136, 86,0,156,136, 86,0 +,104, 82, 43,0,214,174, 48,0,241,206, 65,0,130,109, 69,0 +,125,105, 65,0,104, 82, 43,0,224,185, 54,0,241,206, 65,0 +,163,144, 96,0,164,145, 96,0,152,130, 81,0,144,121, 71,0 +,144,121, 71,0,141,121, 70,0,238,201, 61,0,241,206, 62,0 +,241,206, 62,0,137, 83, 40,0,157, 96, 49,0, 85, 53, 28,0 +, 75, 46, 24,0,132, 79, 38,0,160, 87, 33,0,117, 67, 29,0 +,228,191, 59,0,246,209, 65,0,153,133, 80,0,246,210, 68,0 +,244,208, 66,0,157,139, 89,0,158,138, 88,0,125,107, 68,0 +, 97, 75, 39,0,210,166, 47,0,246,209, 65,0,122,100, 60,0 +,122,100, 60,0,112, 90, 51,0,235,199, 63,0,247,212, 70,0 +,134,116, 76,0,164,145, 96,0,152,130, 81,0,231,192, 61,0 +,248,211, 69,0,149,129, 75,0,144,121, 71,0,243,205, 64,0 +,246,210, 68,0,140, 84, 42,0,165, 99, 50,0, 84, 52, 27,0 +, 69, 43, 22,0,145, 86, 41,0,150, 82, 30,0,210,169, 51,0 +,212,172, 53,0,226,190, 63,0,229,191, 61,0,227,189, 57,0 +,155,136, 86,0,161,141, 92,0,131,113, 76,0,125,105, 65,0 +,109, 87, 49,0,100, 77, 41,0,220,180, 55,0,238,201, 61,0 +,239,202, 64,0,225,187, 56,0,227,189, 57,0,125,105, 65,0 +,127,109, 71,0,131,114, 73,0,147,124, 78,0,137,114, 66,0 +,223,183, 55,0,228,191, 59,0,223,183, 55,0,225,187, 56,0 +,113, 84, 53,0,161, 97, 49,0,154, 94, 48,0, 80, 50, 25,0 +, 72, 44, 22,0,145, 86, 41,0,150, 82, 30,0,120, 73, 33,0 +,134,109, 62,0,137,114, 66,0,141,118, 71,0,152,130, 81,0 +,159,139, 90,0,134,116, 78,0,132,112, 76,0,132,112, 74,0 +,125,105, 65,0,107, 86, 49,0,122,100, 60,0,144,122, 72,0 +,141,120, 75,0,123,102, 59,0,117, 98, 59,0,131,110, 71,0 +,132,112, 74,0,126,107, 69,0,125,105, 65,0,134,113, 66,0 +,134,113, 66,0,137,114, 66,0,141,118, 71,0,151,129, 80,0 +,122, 85, 52,0,143, 87, 44,0,162, 99, 50,0, 80, 50, 25,0 +, 71, 45, 23,0,140, 84, 42,0,162, 95, 42,0,144, 98, 56,0 +,161,141, 92,0,163,143, 95,0,164,145, 96,0,163,144, 96,0 +,134,115, 78,0,132,112, 74,0,133,113, 75,0,133,113, 75,0 +,126,107, 69,0,141,120, 75,0,159,139, 90,0,158,138, 88,0 +,161,141, 92,0,156,136, 88,0,143,124, 80,0,131,110, 71,0 +,133,114, 76,0,132,112, 74,0,127,109, 71,0,125,107, 68,0 +,152,133, 84,0,155,136, 86,0,159,139, 90,0,159,140, 93,0 +,134, 97, 62,0,148, 89, 46,0,162, 99, 50,0, 78, 48, 25,0 +, 75, 46, 24,0,134, 83, 41,0,171,103, 50,0,142,101, 62,0 +,164,145, 96,0,167,148,101,0,163,144, 98,0,132,114, 76,0 +,130,111, 74,0,135,115, 77,0,137,116, 77,0,132,112, 74,0 +,137,116, 77,0,243,208, 67,0,243,209, 65,0,162,142, 94,0 +,162,143, 92,0,155,136, 86,0,244,208, 66,0,245,209, 66,0 +,129,112, 75,0,133,114, 76,0,133,113, 75,0,125,107, 68,0 +,127,109, 71,0,157,137, 89,0,161,141, 92,0,167,148,101,0 +,128, 97, 65,0,148, 89, 46,0,159, 98, 50,0, 80, 50, 25,0 +, 81, 51, 29,0,136, 84, 42,0,157, 96, 49,0,148,103, 65,0 +,167,148,101,0,164,145, 99,0,131,113, 76,0,132,112, 74,0 +,132,112, 74,0,133,113, 75,0,128,110, 73,0,145,125, 81,0 +,139,116, 69,0,221,179, 53,0,248,214, 73,0,164,145, 96,0 +,163,143, 95,0,157,137, 89,0,247,212, 70,0,247,212, 70,0 +,147,128, 85,0,130,111, 74,0,133,113, 75,0,132,112, 74,0 +,130,111, 74,0,128,111, 74,0,159,140, 93,0,163,144, 96,0 +,126, 96, 62,0,136, 84, 42,0,161, 97, 49,0, 80, 50, 25,0 +, 80, 50, 25,0,144, 88, 45,0,168,102, 50,0,151,106, 65,0 +,163,144, 98,0,128,111, 74,0,128,110, 73,0,130,111, 74,0 +,130,110, 73,0,127,109, 71,0,148,130, 87,0,163,144, 96,0 +,140,117, 70,0,129,106, 61,0,224,185, 54,0,245,209, 66,0 +,156,136, 86,0,242,208, 64,0,244,208, 66,0,163,143, 95,0 +,165,146, 99,0,150,132, 89,0,128,109, 72,0,132,112, 74,0 +,130,111, 74,0,130,111, 74,0,128,110, 73,0,159,140, 93,0 +,123, 93, 58,0,150, 92, 47,0,156, 95, 48,0, 82, 51, 26,0 +, 75, 46, 24,0,140, 84, 42,0,171,103, 50,0,142,101, 62,0 +,129,112, 75,0,130,111, 74,0,130,111, 74,0,130,111, 74,0 +,128,109, 72,0,147,128, 85,0,161,142, 95,0,159,139, 90,0 +,155,136, 86,0,135,112, 64,0,134,109, 62,0,233,196, 58,0 +,244,208, 66,0,244,208, 66,0,160,139, 90,0,164,145, 96,0 +,166,147,100,0,167,148,101,0,150,132, 89,0,131,113, 76,0 +,134,115, 78,0,134,115, 78,0,132,112, 76,0,131,113, 76,0 +,123, 93, 58,0,146, 89, 47,0,153, 93, 47,0, 80, 50, 25,0 +, 71, 45, 23,0,138, 85, 44,0,168,102, 50,0,122, 85, 52,0 +,128,110, 73,0,130,111, 74,0,128,110, 73,0,128,110, 73,0 +,150,132, 89,0,164,146, 97,0,164,146, 97,0,161,142, 93,0 +,157,139, 89,0,146,125, 75,0,137,114, 66,0,227,189, 57,0 +,235,199, 63,0,245,211, 67,0,160,140, 90,0,165,146, 99,0 +,168,149,102,0,167,148,101,0,165,146, 99,0,150,132, 89,0 +,128,110, 73,0,130,111, 74,0,130,111, 74,0,128,110, 73,0 +,103, 81, 51,0,147, 91, 46,0,156, 95, 48,0, 75, 46, 24,0 +, 69, 43, 22,0,150, 92, 47,0,166,101, 49,0,125, 88, 54,0 +,131,113, 76,0,130,111, 74,0,128,109, 72,0,148,130, 87,0 +,163,144, 96,0,166,147,100,0,166,147, 98,0,161,141, 92,0 +,153,132, 84,0,146,125, 75,0,238,201, 61,0,233,196, 58,0 +,134,109, 62,0,225,187, 56,0,241,206, 62,0,163,143, 95,0 +,163,143, 95,0,165,146, 99,0,166,147,100,0,166,147,100,0 +,154,137, 93,0,130,111, 74,0,130,111, 74,0,130,111, 74,0 +,113, 84, 53,0,153, 93, 47,0,172,106, 53,0, 72, 44, 22,0 +, 71, 45, 23,0,143, 87, 44,0,168,102, 50,0,122, 85, 52,0 +,129,112, 75,0,130,111, 74,0,150,132, 89,0,163,144, 96,0 +,163,144, 96,0,161,142, 95,0,159,140, 93,0,157,137, 89,0 +,141,121, 70,0,225,189, 55,0,246,209, 65,0,149,129, 75,0 +,135,112, 64,0,129,104, 58,0,238,201, 61,0,248,211, 69,0 +,163,144, 96,0,166,147,100,0,168,149,102,0,170,151,105,0 +,167,148,101,0,150,132, 89,0,128,111, 74,0,132,112, 74,0 +,113, 84, 53,0,156, 95, 48,0,168,102, 50,0, 78, 48, 25,0 +, 71, 45, 23,0,138, 85, 44,0,168,102, 50,0,134, 86, 50,0 +,132, 92, 57,0,151,106, 65,0,156,110, 68,0,156,110, 68,0 +,149,107, 67,0,151,106, 65,0,150,104, 59,0,150,104, 59,0 +,127, 79, 39,0,209,167, 48,0,234,197, 61,0,150,104, 59,0 +,151, 99, 53,0,120, 73, 33,0,212,170, 48,0,241,206, 65,0 +,149,107, 67,0,151,106, 65,0,149,107, 67,0,149,107, 67,0 +,156,110, 68,0,151,106, 65,0,147,105, 64,0,132, 92, 57,0 +,122, 85, 52,0,170,104, 52,0,162, 99, 50,0, 78, 48, 25,0 +, 75, 46, 24,0,144, 89, 45,0,145, 93, 52,0,159, 98, 50,0 +,154, 94, 48,0,162, 99, 50,0,153, 93, 47,0,144, 88, 45,0 +,144, 89, 45,0,144, 88, 45,0,148, 89, 46,0,152, 89, 41,0 +,131, 71, 25,0,131, 71, 25,0,146, 83, 34,0,152, 89, 41,0 +,134, 76, 33,0,131, 71, 25,0,131, 71, 25,0,134, 76, 33,0 +,156, 95, 48,0,150, 92, 47,0,156, 95, 48,0,156, 95, 48,0 +,144, 88, 45,0,143, 87, 44,0,150, 92, 47,0,147, 91, 46,0 +,155, 96, 51,0,146, 91, 48,0,170,104, 52,0, 82, 51, 26,0 +, 91, 57, 30,0,117, 75, 42,0,138, 85, 44,0,132, 79, 38,0 +,122, 76, 39,0,124, 77, 40,0,120, 74, 37,0,117, 73, 38,0 +,127, 79, 39,0,124, 77, 40,0,132, 79, 38,0,141, 83, 40,0 +,125, 74, 34,0,119, 70, 32,0,120, 73, 33,0,120, 74, 37,0 +,118, 71, 34,0,119, 70, 32,0,119, 70, 32,0,120, 73, 33,0 +,127, 79, 39,0,127, 79, 39,0,124, 77, 40,0,127, 79, 39,0 +,122, 76, 39,0,122, 76, 39,0,117, 73, 38,0,117, 73, 38,0 +,124, 77, 40,0,138, 85, 44,0,140, 89, 49,0, 91, 57, 30,0 +, 61, 39, 23,0, 88, 55, 29,0, 75, 46, 24,0, 69, 43, 22,0 +, 69, 43, 22,0, 72, 44, 22,0, 71, 45, 23,0, 71, 45, 23,0 +, 71, 45, 23,0, 71, 45, 23,0, 75, 46, 24,0, 72, 44, 22,0 +, 72, 44, 22,0, 75, 46, 24,0, 72, 44, 22,0, 69, 43, 22,0 +, 69, 43, 22,0, 72, 44, 22,0, 75, 46, 24,0, 72, 44, 22,0 +, 69, 43, 22,0, 75, 46, 24,0, 69, 43, 22,0, 69, 43, 22,0 +, 71, 45, 23,0, 69, 43, 22,0, 69, 43, 22,0, 69, 43, 22,0 +, 69, 43, 22,0, 75, 46, 24,0, 88, 55, 29,0, 61, 39, 23,0 #endif From e098ad6d81a2dc622e0e4528e0c88ecc1677d7de Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 29 Mar 2006 12:28:42 +0000 Subject: [PATCH 2489/4131] Make sure palette detection only occurs in 8bpp source input mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2573 --- src/gui/render.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 10e9a10d..05f47cd5 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.43 2006-02-26 16:04:35 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.44 2006-03-29 12:28:42 harekiet Exp $ */ #include #include @@ -84,11 +84,6 @@ static void Check_Palette(void) { render.pal.last=0; } -static void RENDER_ResetPal(void) { - render.pal.first=0; - render.pal.last=255; -} - void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue) { render.pal.rgb[entry].red=red; render.pal.rgb[entry].green=green; @@ -384,7 +379,11 @@ forcenormal: render.scale.blocks = render.src.width / SCALER_BLOCKSIZE; render.scale.lastBlock = render.src.width % SCALER_BLOCKSIZE; render.scale.inHeight = render.src.height; - RENDER_ResetPal(); + /* Reset the palette change detection to it's initial value */ + render.pal.first= 0; + render.pal.last = 255; + render.pal.changed = false; + memset(render.pal.modified, 0, sizeof(render.pal.modified)); /* Signal the next frame to first reinit the cache */ render.scale.clearCache = true; render.active=true; From 5e86dc8954aef1b5679b1c4b4ba7882e0bcccd67 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 29 Mar 2006 12:48:37 +0000 Subject: [PATCH 2490/4131] version increase. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2574 --- NEWS | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ VERSION | 2 +- configure.in | 2 +- 3 files changed, 86 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index efee9e0d..705cb4f4 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,87 @@ +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. diff --git a/VERSION b/VERSION index 21b86bac..f429be05 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.63 +0.65 diff --git a/configure.in b/configure.in index 98f4be75..00cc1f8b 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Init. -AC_INIT(dosbox,0.63) +AC_INIT(dosbox,0.65) AC_PREREQ(2.50) AC_CONFIG_SRCDIR(README) From ec9b634b2c6671e2c617a0d6a49f81c7584f8ba5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 29 Mar 2006 12:59:04 +0000 Subject: [PATCH 2491/4131] Tiny undate. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2575 --- README | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README b/README index 0b51a9e5..1a6eac88 100644 --- a/README +++ b/README @@ -49,6 +49,7 @@ Type INTRO in DOSBox. That's it. Some Frequently Asked Questions: Q: I've got a Z instead of a C at the prompt. +Q: My game crashes when using opengl/nb or is much slower. Q: My CD-ROM doesn't work. Q: The mouse doesn't work. Q: The sound stutters or sounds stretched/weird. @@ -72,6 +73,11 @@ A: You have to make your directories available as drives in DOSBox by using which points to /home/username in Linux. +Q: My game crashes when using opengl/nb or is much slower. +A: Somehow our opengl code isn't entirely stable on some platforms. + Use surface instead. + + Q: My CD-ROM doesn't work. A: To mount your CD-ROM in DOSBox you have to specify some additional options when mounting the CD-ROM. From dc13ef5f67211cc9e7e1c37ceb3dae9d032e56ec Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 29 Mar 2006 13:50:29 +0000 Subject: [PATCH 2492/4131] add capture folder Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2576 --- scripts/dosbox-installer.nsi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index c11a94a4..df265ad9 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -49,6 +49,7 @@ Section "ThisNameIsIgnoredSoWhyBother?" CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.lnk" "$INSTDIR\DOSBox.exe" "-conf $\"$INSTDIR\dosbox.conf$\"" 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" CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Install movie codec.lnk" "rundll32" "syssetup,SetupInfObjectInstallAction DefaultInstall 128 $INSTDIR\zmbv\zmbv.inf" WriteUninstaller "uninstall.exe" @@ -88,7 +89,8 @@ Section "Uninstall" 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.conf.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. From 2c76e6130f64499c3e6056bcad60067de43ed349 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 29 Mar 2006 13:51:58 +0000 Subject: [PATCH 2493/4131] Remove video frame logging message and add a new stopped capturing message Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2577 --- src/hardware/hardware.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 104c0fde..f1460381 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: hardware.cpp,v 1.15 2006-03-27 19:18:00 qbix79 Exp $ */ +/* $Id: hardware.cpp,v 1.16 2006-03-29 13:51:58 harekiet Exp $ */ #include #include @@ -152,8 +152,10 @@ static void CAPTURE_VideoEvent(bool pressed) { return; #if (C_SSHOT) if (CaptureState & CAPTURE_VIDEO) { - /* Close the video */ + /* Close the video */ CaptureState &= ~CAPTURE_VIDEO; + LOG_MSG("Stopped capturing video."); + Bit8u avi_header[AVI_HEADER_SIZE]; Bitu main_list; Bitu header_pos=0; @@ -256,7 +258,7 @@ static void CAPTURE_VideoEvent(bool pressed) { AVIOUTw(16); /* BitsPerSample */ int nmain = header_pos - main_list - 4; /* Finish stream list, i.e. put number of bytes in the list to proper pos */ - LOG_MSG("Wrote a total of %d", header_pos ); + int njunk = AVI_HEADER_SIZE - 8 - 12 - header_pos; AVIOUT4("JUNK"); AVIOUTd(njunk); @@ -525,7 +527,7 @@ skip_shot: goto skip_video; CAPTURE_AddAviChunk( "00dc", written, capture.video.buf, codecFlags & 1 ? 0x10 : 0x0); capture.video.frames++; - LOG_MSG("Frame %d video %d audio %d",capture.video.frames, written, capture.video.audioused *4 ); +// LOG_MSG("Frame %d video %d audio %d",capture.video.frames, written, capture.video.audioused *4 ); if ( capture.video.audioused ) { CAPTURE_AddAviChunk( "01wb", capture.video.audioused * 4, capture.video.audiobuf, 0); capture.video.audiowritten = capture.video.audioused*4; From 7b71d46b4f2dafd139a3ce6ee2f2fdbea8173e85 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 29 Mar 2006 14:17:27 +0000 Subject: [PATCH 2494/4131] fix hangups when changing frameskip runtime Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2578 --- src/gui/render.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 05f47cd5..5dc43920 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.44 2006-03-29 12:28:42 harekiet Exp $ */ +/* $Id: render.cpp,v 1.45 2006-03-29 14:17:27 qbix79 Exp $ */ #include #include @@ -435,7 +435,6 @@ void RENDER_Init(Section * sec) { render.aspect=section->Get_bool("aspect"); render.frameskip.max=section->Get_int("frameskip"); render.frameskip.count=0; - render.active=false; const char * scaler;std::string cline; if (control->cmdline->FindString("-scaler",cline,false)) { scaler=cline.c_str(); From 38d38abd46deb9614efce6cc1341ae3d128348c8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 29 Mar 2006 19:56:07 +0000 Subject: [PATCH 2495/4131] mention some debian SDL behaviour Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2579 --- INSTALL | 2 ++ src/ints/bios_keyboard.cpp | 24 +++++++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/INSTALL b/INSTALL index 70289563..e500002d 100644 --- a/INSTALL +++ b/INSTALL @@ -60,6 +60,8 @@ In step 1 you could add the following switches: 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 diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index b80817e4..0a524e95 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -24,6 +24,10 @@ #include "regs.h" #include "inout.h" +/* SDL by default treats numlock and scrolllock different from all other keys. + * Some linux distros disable this bad behaviour. (for example debian) + * Define the following if this is the case */ +//#define CAN_USE_LOCK 1 static Bitu call_int16,call_irq1,call_irq6; @@ -249,7 +253,11 @@ static Bitu IRQ1_Handler(void) { flags2=mem_readb(BIOS_KEYBOARD_FLAGS2); flags3=mem_readb(BIOS_KEYBOARD_FLAGS3); leds =mem_readb(BIOS_KEYBOARD_LEDS); +#ifdef CAN_USE_LOCK + /* No hack anymore! */ +#else flags2&=~(0x40+0x20);//remove numlock/capslock pressed (hack for sdl only reporting states) +#endif switch (scancode) { /* First the hard ones */ case 0xfa: /* ack. Do nothing for now */ @@ -304,9 +312,13 @@ static Bitu IRQ1_Handler(void) { } break; - +#ifdef CAN_USE_LOCK + case 0x3a:flags2 |=0x40;break;//CAPSLOCK + case 0xba:flags1 ^=0x40;flags2 &=~0x40;leds ^=0x04;break; +#else case 0x3a:flags2 |=0x40;flags1 |=0x40;leds |=0x04;break; //SDL gives only the state instead of the toggle /* Caps Lock */ case 0xba:flags1 &=~0x40;leds &=~0x04;break; +#endif case 0x45: if (flags3 &0x01) { /* last scancode of pause received; first remove 0xe1-prefix */ @@ -327,9 +339,13 @@ static Bitu IRQ1_Handler(void) { } } else { /* Num Lock */ +#ifdef CAN_USE_LOCK + flags2 |=0x20; +#else flags2 |=0x20; flags1 |=0x20; leds |=0x02; +#endif } break; case 0xc5: @@ -337,9 +353,15 @@ static Bitu IRQ1_Handler(void) { /* pause released */ flags3 &=~0x01; } else { +#ifdef CAN_USE_LOCK + flags1^=0x20; + leds^=0x02; + flags2&=~0x20; +#else /* Num Lock released */ flags1 &=~0x20; leds &=~0x02; +#endif } break; case 0x46:flags2 |=0x10;break; /* Scroll Lock SDL Seems to do this one fine (so break and make codes) */ From 35b8249ab16bcc6a45f99deacf78441bdbc6d44a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 7 Apr 2006 15:15:45 +0000 Subject: [PATCH 2496/4131] Only run demo if called from the first shell. (Xcom TFTD) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2581 --- src/dos/dos_programs.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index c2f4f238..c3b21ee6 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.56 2006-03-12 21:12:20 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.57 2006-04-07 15:15:45 qbix79 Exp $ */ #include #include @@ -619,6 +619,8 @@ public: } void Run(void) { + /* Only run if called from the first shell (Xcom TFTD runs any intro file in the path) */ + if(DOS_PSP(dos.psp()).GetParent() != DOS_PSP(DOS_PSP(dos.psp()).GetParent()).GetParent()) return; if(cmd->FindExist("cdrom",false)) { WriteOut(MSG_Get("PROGRAM_INTRO_CDROM")); return; From 3359eee9563e3a9928aa25452edcf67addfd0424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 7 Apr 2006 16:34:07 +0000 Subject: [PATCH 2497/4131] add device control channel handling; fix typo in ems.cpp (#1462677) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2582 --- include/dos_system.h | 6 +++++- src/dos/dev_con.h | 6 ++++-- src/dos/dos_devices.cpp | 12 +++++++++++- src/dos/dos_ioctl.cpp | 38 +++++++++++++++++++++++++++++++++----- src/dos/dos_mscdex.cpp | 6 ++++-- src/ints/ems.cpp | 8 +++++--- 6 files changed, 62 insertions(+), 14 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 1f0af3f1..5cdb3bd4 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.31 2006-02-09 11:47:47 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.32 2006-04-07 16:34:07 c2woody Exp $ */ #ifndef DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H @@ -30,6 +30,8 @@ #include "cross.h" #endif +#include "mem.h" + #define DOS_NAMELENGTH 12 #define DOS_NAMELENGTH_ASCII (DOS_NAMELENGTH+1) #define DOS_FCBNAME 15 @@ -99,6 +101,8 @@ public: 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; diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 5479014d..1e7c62d2 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.24 2006-02-26 16:05:13 qbix79 Exp $ */ +/* $Id: dev_con.h,v 1.25 2006-04-07 16:34:07 c2woody Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" @@ -33,6 +33,8 @@ public: bool Close(); void ClearAnsi(void); Bit16u GetInformation(void); + bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return false;} + bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return false;} private: Bit8u readcache; Bit8u lastwrite; @@ -313,7 +315,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { if(ansi.data[0]!=2) {/* every version behaves like type 2 */ LOG(LOG_IOCTL,LOG_NORMAL)("ANSI: esc[%dJ called : not supported handling as 2",ansi.data[0]); } - INT10_ScrollWindow(0,0,999,999,0,ansi.attr,0xFF); + INT10_ScrollWindow(0,0,255,255,0,ansi.attr,0xFF); ClearAnsi(); INT10_SetCursorPos(0,0,0); break; diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 341e1cee..83fecee5 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_devices.cpp,v 1.11 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: dos_devices.cpp,v 1.12 2006-04-07 16:34:07 c2woody Exp $ */ #include #include "dosbox.h" @@ -53,6 +53,8 @@ public: } bool Close() { return true; } Bit16u GetInformation(void) { return 0x8084; } + bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return false;} + bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return false;} }; bool DOS_Device::Read(Bit8u * data,Bit16u * size) { @@ -75,6 +77,14 @@ Bit16u DOS_Device::GetInformation(void) { return Devices[devnum]->GetInformation(); } +bool DOS_Device::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode) { + return Devices[devnum]->ReadFromControlChannel(bufptr,size,retcode); +} + +bool DOS_Device::WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode) { + return Devices[devnum]->WriteToControlChannel(bufptr,size,retcode); +} + DOS_File::DOS_File(const DOS_File& orig) { type=orig.type; flags=orig.flags; diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index cee95b74..a9c36586 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.26 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.27 2006-04-07 16:34:07 c2woody Exp $ */ #include #include "dosbox.h" @@ -46,9 +46,38 @@ bool DOS_IOCTL(void) { } switch(reg_al) { case 0x00: /* Get Device Information */ - reg_dx=Files[handle]->GetInformation(); + if (Files[handle]->GetInformation() & 0x8000) { //Check for device + reg_dx=Files[handle]->GetInformation(); + } else { + /* return drive number in lower 5 bits for block devices */ + reg_dx=(Files[handle]->GetInformation()&0xffe0)|drive; + } reg_ax=reg_dx; //Destroyed officially return true; + case 0x02: /* Read from Device Control Channel */ + if (Files[handle]->GetInformation() & 0xc000) { + /* is character device with IOCTL support */ + PhysPt bufptr=PhysMake(SegValue(ds),reg_dx); + Bit16u retcode=0; + if (((DOS_Device*)(Files[handle]))->ReadFromControlChannel(bufptr,reg_cx,&retcode)) { + reg_ax=retcode; + return true; + } + } + DOS_SetError(0x0001); // invalid function + return false; + case 0x03: /* Write to Device Control Channel */ + if (Files[handle]->GetInformation() & 0xc000) { + /* is character device with IOCTL support */ + PhysPt bufptr=PhysMake(SegValue(ds),reg_dx); + Bit16u retcode=0; + if (((DOS_Device*)(Files[handle]))->WriteToControlChannel(bufptr,reg_cx,&retcode)) { + reg_ax=retcode; + return true; + } + } + DOS_SetError(0x0001); // invalid function + return false; case 0x06: /* Get Input Status */ if (Files[handle]->GetInformation() & 0x8000) { //Check for device reg_al=(Files[handle]->GetInformation() & 0x40) ? 0x0 : 0xff; @@ -59,12 +88,11 @@ bool DOS_IOCTL(void) { Files[handle]->Seek(&endlocation, DOS_SEEK_END); if(oldlocation < endlocation){//Still data available reg_al=0xff; - } else - { + } else { reg_al=0x0; //EOF or beyond } Files[handle]->Seek(&oldlocation, DOS_SEEK_SET); //restore filelocation - LOG(LOG_IOCTL,LOG_NORMAL)("06:Used Get Input Status on regualar file with handle %d",handle); + LOG(LOG_IOCTL,LOG_NORMAL)("06:Used Get Input Status on regular file with handle %d",handle); } return true; case 0x07: /* Get Output Status */ diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 506872bc..fa9ceda1 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.37 2006-03-26 11:54:44 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.38 2006-04-07 16:34:07 c2woody Exp $ */ #include #include @@ -1065,7 +1065,9 @@ public: } bool Seek(Bit32u * pos,Bit32u type){return false;} bool Close(){return false;} - Bit16u GetInformation(void){return 0x8093;} + Bit16u GetInformation(void){return 0xc880;} + bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return true;} + bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return true;} private: Bit8u cache; }; diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 45357393..f19e79cb 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.47 2006-03-12 20:31:49 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.48 2006-04-07 16:34:07 c2woody Exp $ */ #include #include @@ -79,7 +79,9 @@ public: } bool Seek(Bit32u * pos,Bit32u type){return false;} bool Close(){return false;} - Bit16u GetInformation(void){return 0x8093;} + Bit16u GetInformation(void){return 0xc080;} + bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return true;} + bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return true;} private: Bit8u cache; }; @@ -608,7 +610,7 @@ static Bitu INT67_Handler(void) { } else { switch (reg_al) { case 0x00: /* VCPI Installation Check */ - if (((reg_cx==0) && (reg_di=0x0012)) || (cpu.pmode && (reg_flags & FLAG_VM))) { + if (((reg_cx==0) && (reg_di==0x0012)) || (cpu.pmode && (reg_flags & FLAG_VM))) { /* JEMM detected or already in v86 mode */ reg_ah=EMM_NO_ERROR; reg_bx=0x100; From d000d714e9d1aff3678f56c41af484154f8f6e6f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 7 Apr 2006 19:56:45 +0000 Subject: [PATCH 2498/4131] Add patch 1463945 from XulChris and add a tiny part of patch 1235377 of msharov Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2583 --- src/shell/shell_misc.cpp | 68 ++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 09a5c600..d383e77f 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.43 2006-02-28 19:41:27 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.44 2006-04-07 19:56:45 qbix79 Exp $ */ #include #include @@ -39,16 +39,12 @@ static void outc(Bit8u c) { DOS_WriteFile(STDOUT,&c,&n); } -static void outs(char * str) { - Bit16u n=strlen(str); - DOS_WriteFile(STDOUT,(Bit8u *)str,&n); -} - void DOS_Shell::InputCommand(char * line) { Bitu size=CMD_MAXLINE-2; //lastcharacter+0 Bit8u c;Bit16u n=1; Bitu str_len=0;Bitu str_index=0; - Bit16u len; + Bit16u len=0; + bool current_hist=false; // current command stored in history? line[0] = '\0'; @@ -116,6 +112,12 @@ void DOS_Shell::InputCommand(char * line) { case 0x48: /* UP */ if (l_history.empty() || it_history == l_history.end()) break; + // store current command in history if we are at beginning + if (it_history == l_history.begin() && !current_hist) { + current_hist=true; + l_history.push_front(line); + } + for (;str_index>0; str_index--) { // removes all characters outc(8); outc(' '); outc(8); @@ -136,6 +138,12 @@ void DOS_Shell::InputCommand(char * line) { if (it_history == l_history.begin()) { // no previous commands in history it_history ++; + + // remove current command from history + if (current_hist) { + current_hist=false; + l_history.pop_front(); + } break; } else it_history --; @@ -209,13 +217,13 @@ void DOS_Shell::InputCommand(char * line) { // build new completion list // get completion mask - char *completion_start = strrchr(line, ' '); + char *p_completion_start = strrchr(line, ' '); - if (completion_start) { - completion_start ++; - completion_index = str_index - strlen(completion_start); + if (p_completion_start) { + p_completion_start ++; + completion_index = str_index - strlen(p_completion_start); } else { - completion_start = line; + p_completion_start = line; completion_index = 0; } @@ -225,8 +233,8 @@ void DOS_Shell::InputCommand(char * line) { // build the completion list char mask[DOS_PATHLENGTH]; - if (completion_start) { - strcpy(mask, completion_start); + if (p_completion_start) { + strcpy(mask, p_completion_start); char* dot_pos=strrchr(mask,'.'); char* bs_pos=strrchr(mask,'\\'); char* fs_pos=strrchr(mask,'/'); @@ -249,11 +257,11 @@ void DOS_Shell::InputCommand(char * line) { } DOS_DTA dta(dos.dta()); - char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr; + char name[DOS_NAMELENGTH_ASCII];Bit32u sz;Bit16u date;Bit16u time;Bit8u att; std::list executable; while (res) { - dta.GetResult(name,size,date,time,attr); + dta.GetResult(name,sz,date,time,att); // add result to completion list char *ext; // file extension @@ -329,6 +337,12 @@ void DOS_Shell::InputCommand(char * line) { if (!str_len) return; str_len++; + // remove current command from history if it's there + if (current_hist) { + current_hist=false; + l_history.pop_front(); + } + // add command line to history l_history.push_front(line); it_history = l_history.begin(); if (l_completion.size()) l_completion.clear(); @@ -365,7 +379,7 @@ bool DOS_Shell::Execute(char * name,char * args) { fullname=Which(name); if (!fullname) return false; - char* extension =strrchr(fullname,'.'); + const char* extension =strrchr(fullname,'.'); /*always disallow files without extension from being executed. */ /*only internal commands can be run this way and they never get in this handler */ @@ -426,17 +440,17 @@ bool DOS_Shell::Execute(char * name,char * args) { RealPt file_name=RealMakeSeg(ss,reg_sp+0x20); MEM_BlockWrite(Real2Phys(file_name),fullname,strlen(fullname)+1); /* Fill the command line */ - CommandTail cmd; + CommandTail cmdtail; if (strlen(line)>126) line[126]=0; - cmd.count=strlen(line); - memcpy(cmd.buffer,line,strlen(line)); - cmd.buffer[strlen(line)]=0xd; + cmdtail.count=strlen(line); + memcpy(cmdtail.buffer,line,strlen(line)); + cmdtail.buffer[strlen(line)]=0xd; /* Copy command line in stack block too */ - MEM_BlockWrite(SegPhys(ss)+reg_sp+0x100,&cmd,128); + MEM_BlockWrite(SegPhys(ss)+reg_sp+0x100,&cmdtail,128); /* Parse FCB (first two parameters) and put them into the current DOS_PSP */ Bit8u add; - FCB_Parsename(dos.psp(),0x5C,0x00,cmd.buffer,&add); - FCB_Parsename(dos.psp(),0x6C,0x00,&cmd.buffer[add],&add); + FCB_Parsename(dos.psp(),0x5C,0x00,cmdtail.buffer,&add); + FCB_Parsename(dos.psp(),0x6C,0x00,&cmdtail.buffer[add],&add); block.exec.fcb1=RealMake(dos.psp(),0x5C); block.exec.fcb2=RealMake(dos.psp(),0x6C); /* Set the command line in the block and save it */ @@ -473,9 +487,9 @@ bool DOS_Shell::Execute(char * name,char * args) { -static char * bat_ext=".BAT"; -static char * com_ext=".COM"; -static char * exe_ext=".EXE"; +static const char * bat_ext=".BAT"; +static const char * com_ext=".COM"; +static const char * exe_ext=".EXE"; static char which_ret[DOS_PATHLENGTH+4]; char * DOS_Shell::Which(char * name) { From 5b0b099febb7029b628e8c3ecc0e5970bd6e63a3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 8 Apr 2006 11:25:41 +0000 Subject: [PATCH 2499/4131] Fix a few warnings and fix the filename not being cleared. (capture problems with filenames having stackdata in them) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2584 --- src/dos/dos_execute.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index de504c72..c7acbae6 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.54 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: dos_execute.cpp,v 1.55 2006-04-08 11:25:41 qbix79 Exp $ */ #include #include @@ -27,7 +27,7 @@ #include "callback.h" #include "debug.h" -char * RunningProgram="DOSBOX"; +const char * RunningProgram="DOSBOX"; #ifdef _MSC_VER #pragma pack(1) @@ -233,12 +233,12 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { Bit16u fhandle;Bit16u len;Bit32u pos; Bit16u pspseg,envseg,loadseg,memsize,readsize; PhysPt loadaddress;RealPt relocpt; - Bitu headersize,imagesize; + Bitu headersize=0,imagesize=0; DOS_ParamBlock block(block_pt); block.LoadData(); if (flags!=LOADNGO && flags!=OVERLAY && flags!=LOAD) { - E_Exit("DOS:Not supported execute mode %d for file %s",flags,name); + E_Exit("DOS:Not supported execute mode %d for file %s",flags,name); } /* Check for EXE or COM File */ bool iscom=false; @@ -433,7 +433,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { DEBUG_CheckExecuteBreakpoint(RealSeg(csip),RealOff(csip)); #endif /* Add the filename to PSP and environment MCB's */ - char stripname[8];Bitu index=0; + char stripname[8]= { 0 };Bitu index=0; while (char chr=*name++) { switch (chr) { case ':':case '\\':case '/':index=0;break; From 970b0a4842054068137209d85daaf24c9d9c4cb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 8 Apr 2006 19:31:48 +0000 Subject: [PATCH 2500/4131] add a few more scancodes for Mac OSX (cc_benny) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2585 --- src/gui/sdl_mapper.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index d3e54a3c..25360556 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.21 2006-02-16 20:18:59 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.22 2006-04-08 19:31:48 c2woody Exp $ */ #define OLD_JOYSTICK 1 @@ -241,7 +241,7 @@ static SDLKey sdlkey_map[]={ /* Keypad (KP_EQUALS not supported, NUMLOCK used on what is CLEAR * in Mac OS X) */ - /*41-46*/ SDLK_KP_PERIOD, Z, SDLK_KP_MULTIPLY, Z, SDLK_PLUS, Z, + /*41-46*/ SDLK_KP_PERIOD, Z, SDLK_KP_MULTIPLY, Z, SDLK_KP_PLUS, Z, /*47-4A*/ SDLK_NUMLOCK /*==SDLK_CLEAR*/, Z, Z, Z, /*4B-4D*/ SDLK_KP_DIVIDE, SDLK_KP_ENTER, Z, /*4E-51*/ SDLK_KP_MINUS, Z, Z, SDLK_KP_EQUALS, @@ -250,14 +250,15 @@ static SDLKey sdlkey_map[]={ /*5D-5F*/ Z, Z, Z, - /* Function keys and cursor blocks (F13-F16 not supported, INSERT - * used on what is HELP in Mac OS X) */ + /* Function keys and cursor blocks (F13 not supported, F14 => + * PRINT[SCREEN], F15 => SCROLLOCK, F16 => PAUSE, HELP => INSERT) */ /*60-64*/ SDLK_F5, SDLK_F6, SDLK_F7, SDLK_F3, SDLK_F8, - /*65-6A*/ SDLK_F9, Z, SDLK_F11, Z, SDLK_F13, (SDLKey)(SDLK_F15+1), - /*6B-71*/ SDLK_F14, Z, SDLK_F10, Z, SDLK_F12, Z, SDLK_F15, - /*72-74*/ SDLK_INSERT /*==SDLK_HELP*/, SDLK_HOME, SDLK_PAGEUP, - /*75-79*/ SDLK_DELETE, SDLK_F4, SDLK_END, SDLK_F2, SDLK_PAGEDOWN, - /*7A-7E*/ SDLK_F1, SDLK_LEFT, SDLK_RIGHT, SDLK_DOWN, SDLK_UP, + /*65-6A*/ SDLK_F9, Z, SDLK_F11, Z, SDLK_F13, SDLK_PAUSE /*==SDLK_F16*/, + /*6B-70*/ SDLK_PRINT /*==SDLK_F14*/, Z, SDLK_F10, Z, SDLK_F12, Z, + /*71-72*/ SDLK_SCROLLOCK /*==SDLK_F15*/, SDLK_INSERT /*==SDLK_HELP*/, + /*73-77*/ SDLK_HOME, SDLK_PAGEUP, SDLK_DELETE, SDLK_F4, SDLK_END, + /*78-7C*/ SDLK_F2, SDLK_PAGEDOWN, SDLK_F1, SDLK_LEFT, SDLK_RIGHT, + /*7D-7E*/ SDLK_DOWN, SDLK_UP, /*7F-7F*/ Z, From 3b7451fe35b5ed107d8af78fc58ea6fdcbc83476 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 8 Apr 2006 19:41:49 +0000 Subject: [PATCH 2501/4131] Some better const usage. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2586 --- include/mapper.h | 2 +- include/setup.h | 6 +-- src/gui/sdl_mapper.cpp | 96 +++++++++++++++++++++--------------------- 3 files changed, 53 insertions(+), 51 deletions(-) diff --git a/include/mapper.h b/include/mapper.h index d789deda..9fdab5c8 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -26,7 +26,7 @@ enum MapKeys { }; typedef void (MAPPER_Handler)(bool pressed); -void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char * eventname,char * buttonname); +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); diff --git a/include/setup.h b/include/setup.h index f53ddecd..13e42c32 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.22 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: setup.h,v 1.23 2006-04-08 19:41:49 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -222,8 +222,8 @@ protected: public: Module_base(Section* configuration){m_configuration=configuration;}; // Module_base(Section* configuration, SaveState* state) {}; - ~Module_base(){/*LOG_MSG("executed")*/;};//Destructors are required + virtual ~Module_base(){/*LOG_MSG("executed")*/;};//Destructors are required /* Returns true if succesful.*/ - virtual bool Change_Config(Section* newconfig) {return false;} ; + virtual bool Change_Config(Section* /*newconfig*/) {return false;} ; }; #endif diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 25360556..3ebf1f30 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.22 2006-04-08 19:31:48 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.23 2006-04-08 19:41:49 qbix79 Exp $ */ #define OLD_JOYSTICK 1 @@ -47,8 +47,8 @@ enum { }; enum BB_Types { - BB_Next,BB_Prev,BB_Add,BB_Del, - BB_Save,BB_Reset,BB_Exit + BB_Next,BB_Add,BB_Del, + BB_Save,BB_Exit }; enum BC_Types { @@ -94,7 +94,7 @@ static CBindList holdlist; class CEvent { public: - CEvent(char * _entry) { + CEvent(char const * const _entry) { safe_strncpy(entry,_entry,16); events.push_back(this); bindlist.clear(); @@ -112,7 +112,7 @@ public: if (!activity) Active(false); } void DeActivateAll(void); - void SetValue(Bits value){ + void SetValue(Bits /*value*/){ }; char * GetName(void) { return entry;} CBindList bindlist; @@ -149,8 +149,8 @@ public: if (!strcasecmp(word,"hold")) flags|=BFLG_Hold; } } - void Activate(Bits value) { - event->SetValue(value); + void Activate(Bits _value) { + event->SetValue(_value); if (active) return; event->Activate(); active=true; @@ -172,6 +172,7 @@ public: } virtual void ConfigName(char * buf)=0; virtual void BindName(char * buf)=0; + Bitu mods,flags; Bit16s value; CEvent * event; @@ -203,8 +204,10 @@ public: virtual CBind * CreateEventBind(SDL_Event * event)=0; virtual bool CheckEvent(SDL_Event * event)=0; - virtual char * ConfigStart(void)=0; - virtual char * BindStart(void)=0; + virtual const char * ConfigStart(void)=0; + virtual const char * BindStart(void)=0; + virtual ~CBindGroup (void) { } + protected: }; @@ -398,14 +401,14 @@ public: return new CKeyBind(&lists[(Bitu)_key],_key); } private: - char * ConfigStart(void) { + const char * ConfigStart(void) { return configname; } - char * BindStart(void) { + const char * BindStart(void) { return "Key"; } protected: - char * configname; + const char * configname; CBindList * lists; Bitu keys; }; @@ -558,11 +561,11 @@ private: assert(buttonbegin();it!=list->end();it++) { (*it)->DeActivate(); @@ -892,13 +894,8 @@ public: CCaptionButton(Bitu _x,Bitu _y,Bitu _dx,Bitu _dy) : CButton(_x,_y,_dx,_dy){ caption[0]=0; } - void Change(char * format,...) { - va_list msg; - va_start(msg,format); - vsprintf(caption,format,msg); - va_end(msg); - mapper.redraw=true; - } + void Change(const char * format,...) GCC_ATTRIBUTE(__format__(__printf__,2,3)); + void Draw(void) { if (!enabled) return; DrawText(x+2,y+2,caption,color); @@ -907,6 +904,14 @@ protected: char caption[128]; }; +void CCaptionButton::Change(const char * format,...) { + va_list msg; + va_start(msg,format); + vsprintf(caption,format,msg); + va_end(msg); + mapper.redraw=true; +} + static void MAPPER_SaveBinds(void); class CBindButton : public CTextButton { public: @@ -1004,7 +1009,7 @@ protected: class CKeyEvent : public CEvent { public: - CKeyEvent(char * _entry,KBD_KEYS _key) : CEvent(_entry) { + CKeyEvent(char const * const _entry,KBD_KEYS _key) : CEvent(_entry) { key=_key; } void Active(bool yesno) { @@ -1015,12 +1020,12 @@ public: class CJAxisEvent : public CEvent { public: - CJAxisEvent(char * _entry,Bitu _stick,bool _yaxis,bool _positive) : CEvent(_entry) { + CJAxisEvent(char const * const _entry,Bitu _stick,bool _yaxis,bool _positive) : CEvent(_entry) { stick=_stick; yaxis=_yaxis; positive=_positive; } - void Active(bool yesno) { + void Active(bool /*yesno*/) { }; Bitu stick; bool yaxis,positive; @@ -1028,11 +1033,11 @@ public: class CJButtonEvent : public CEvent { public: - CJButtonEvent(char * _entry,Bitu _stick,Bitu _button) : CEvent(_entry) { + CJButtonEvent(char const * const _entry,Bitu _stick,Bitu _button) : CEvent(_entry) { stick=_stick; button=_button; } - void Active(bool yesno) { + void Active(bool /*yesno*/) { }; Bitu stick,button; }; @@ -1040,7 +1045,7 @@ public: class CModEvent : public CEvent { public: - CModEvent(char * _entry,Bitu _wmod) : CEvent(_entry) { + CModEvent(char const * const _entry,Bitu _wmod) : CEvent(_entry) { wmod=_wmod; } void Active(bool yesno) { @@ -1053,7 +1058,7 @@ protected: class CHandlerEvent : public CEvent { public: - CHandlerEvent(char * _entry,MAPPER_Handler * _handler,MapKeys _key,Bitu _mod,char * _buttonname) : CEvent(_entry) { + CHandlerEvent(char const * const _entry,MAPPER_Handler * _handler,MapKeys _key,Bitu _mod,char const * const _buttonname) : CEvent(_entry) { handler=_handler; defmod=_mod; defkey=_key; @@ -1063,7 +1068,7 @@ public: void Active(bool yesno) { (*handler)(yesno); }; - char * ButtonName(void) { + const char * ButtonName(void) { return buttonname; } void MakeDefaultBind(char * buf) { @@ -1103,7 +1108,7 @@ protected: Bitu defmod; MAPPER_Handler * handler; public: - char * buttonname; + const char * buttonname; }; @@ -1117,7 +1122,6 @@ static struct { CBindButton * add; CBindButton * del; CBindButton * next; - CBindButton * prev; CCheckButton * mod1,* mod2,* mod3,* hold; } bind_but; @@ -1136,7 +1140,6 @@ static void SetActiveBind(CBind * _bind) { } else { bind_but.bind_title->Enable(false); bind_but.del->Enable(false); - bind_but.prev->Enable(false); bind_but.next->Enable(false); bind_but.mod1->Enable(false); bind_but.mod2->Enable(false); @@ -1173,34 +1176,34 @@ static void DrawButtons(void) { SDL_Flip(mapper.surface); } -static void AddKeyButtonEvent(Bitu x,Bitu y,Bitu dx,Bitu dy,const char * title,const char * entry,KBD_KEYS key) { +static void AddKeyButtonEvent(Bitu x,Bitu y,Bitu dx,Bitu dy,char const * const title,char const * const entry,KBD_KEYS key) { char buf[64]; strcpy(buf,"key_"); strcat(buf,entry); CKeyEvent * event=new CKeyEvent(buf,key); - CButton * button=new CEventButton(x,y,dx,dy,title,event); + new CEventButton(x,y,dx,dy,title,event); } - -static void AddJAxisButton(Bitu x,Bitu y,Bitu dx,Bitu dy,const char * title,Bitu stick,bool yaxis,bool positive) { +#if 0 //unused code +static void AddJAxisButton(Bitu x,Bitu y,Bitu dx,Bitu dy,char const * const title,Bitu stick,bool yaxis,bool positive) { char buf[64]; sprintf(buf,"jaxis_%d%s%s",stick,yaxis ? "Y":"X",positive ? "+" : "-"); CJAxisEvent * event=new CJAxisEvent(buf,stick,yaxis,positive); - CButton * button=new CEventButton(x,y,dx,dy,title,event); + new CEventButton(x,y,dx,dy,title,event); } -static void AddJButtonButton(Bitu x,Bitu y,Bitu dx,Bitu dy,const char * title,Bitu _stick,Bitu _button) { +static void AddJButtonButton(Bitu x,Bitu y,Bitu dx,Bitu dy,char const * const title,Bitu _stick,Bitu _button) { char buf[64]; sprintf(buf,"jbutton_%d_%d",_stick,_button); CJButtonEvent * event=new CJButtonEvent(buf,_stick,_button); - CButton * button=new CEventButton(x,y,dx,dy,title,event); + new CEventButton(x,y,dx,dy,title,event); } +#endif - -static void AddModButton(Bitu x,Bitu y,Bitu dx,Bitu dy,const char * title,Bitu _mod) { +static void AddModButton(Bitu x,Bitu y,Bitu dx,Bitu dy,char const * const title,Bitu _mod) { char buf[64]; sprintf(buf,"mod_%d",_mod); CModEvent * event=new CModEvent(buf,_mod); - CButton * button=new CEventButton(x,y,dx,dy,title,event); + new CEventButton(x,y,dx,dy,title,event); } struct KeyBlock { @@ -1359,7 +1362,6 @@ static void CreateLayout(void) { bind_but.mod3=new CCheckButton(20,454,60,20, "mod3",BC_Mod3); bind_but.hold=new CCheckButton(100,410,60,20,"hold",BC_Hold); - bind_but.prev=new CBindButton(200,400,50,20,"Prev",BB_Prev); bind_but.next=new CBindButton(250,400,50,20,"Next",BB_Next); bind_but.add=new CBindButton(250,380,50,20,"Add",BB_Add); @@ -1404,7 +1406,7 @@ foundevent: } static struct { - char * eventend; + const char * eventend; Bitu key; } DefaultKeys[]={ {"f1",SDLK_F1}, {"f2",SDLK_F2}, {"f3",SDLK_F3}, {"f4",SDLK_F4}, @@ -1474,7 +1476,7 @@ static void CreateDefaultBinds(void) { } -void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char * eventname,char * buttonname) { +void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char const * const eventname,char const * const buttonname) { //Check if it allready exists=> if so return. for(CHandlerEventVector_it it=handlergroup.begin();it!=handlergroup.end();it++) if(strcmp((*it)->buttonname,buttonname) == 0) return; From 480df88fa4aa79ea0224539e62b4723848915dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 9 Apr 2006 12:46:03 +0000 Subject: [PATCH 2502/4131] implement ioctl control channel for mscdex device (NBA95), swapInNextDisk flags cdroms with medium changed, switch between HSG/Red book position information as requested by the application Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2587 --- src/dos/dos_mscdex.cpp | 287 ++++++++++++++++++++++------------------- 1 file changed, 157 insertions(+), 130 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index fa9ceda1..11f21fd8 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.38 2006-04-07 16:34:07 c2woody Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.39 2006-04-09 12:46:03 c2woody Exp $ */ #include #include @@ -26,6 +26,7 @@ #include "dos_inc.h" #include "setup.h" #include "support.h" +#include "bios.h" #include "cdrom.h" @@ -221,7 +222,8 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) real_writeb(seg,off+4,(Bit8u)0xCB); //A RETF Instruction devHeader.SetStrategy(off); - // Create Callback Interruptoff += 5; + // Create Callback Interrupt + off += 5; Bitu call_interrupt=CALLBACK_Allocate(); CallBack_Handlers[call_interrupt]=MSCDEX_Interrupt_Handler; real_writeb(seg,off+0,(Bit8u)0xFE); //GRP 4 @@ -315,7 +317,7 @@ PhysPt CMscdex::GetDefaultBuffer(void) void CMscdex::GetDriverInfo (PhysPt data) { for (Bit16u i=0; i=numDrives) return false; - bool media,changed,open,result; +/* bool media,changed,open,result; result = GetMediaStatus(subUnit,media,changed,open); status = changed ? 0xFF : 0x01; - return result; + return result; */ + status = getSwapRequest() ? 0xFF : 0x01; + return true; }; bool CMscdex::LoadUnloadMedia(Bit8u subUnit, bool unload) @@ -772,13 +775,137 @@ void CMscdex::InitNewMedia(Bit8u subUnit) { static CMscdex* mscdex = 0; +static bool MSCDEX_IOCTL_Input(PhysPt buffer,Bit8u drive_unit) { + Bitu ioctl_fct = mem_readb(buffer); + MSCDEX_LOG("MSCDEX: IOCTL INPUT Subfunction %02X",ioctl_fct); + switch (ioctl_fct) { + case 0x00 : /* Get Device Header address */ + mem_writed(buffer+1,RealMake(mscdex->rootDriverHeaderSeg,0)); + break; + case 0x01 :{/* Get current position */ + TMSF pos; + mscdex->GetCurrentPos(drive_unit,pos); + Bit8u addr_mode = mem_readb(buffer+1); + if (addr_mode==0) { // HSG + mem_writed(buffer+2,MSF_TO_FRAMES (pos.min, pos.sec, pos.fr)); + } else if (addr_mode==1) { // Red book + mem_writeb(buffer+2,pos.fr); + mem_writeb(buffer+3,pos.sec); + mem_writeb(buffer+4,pos.min); + mem_writeb(buffer+5,0x00); + } else LOG_MSG("MSCDEX: Get position: invalid address mode %x",addr_mode); + }break; + case 0x06 : /* Get Device status */ + mem_writed(buffer+1,mscdex->GetDeviceStatus(drive_unit)); + break; + case 0x07 : /* Get sector size */ + if (mem_readb(buffer+1)==0x01) mem_writed(buffer+2,2352); + else mem_writed(buffer+2,2048); + break; + case 0x08 : /* Get size of current volume */ + mem_writed(buffer+1,mscdex->GetVolumeSize(drive_unit)); + break; + case 0x09 : /* Media change ? */ + Bit8u status; + if (!mscdex->GetMediaStatus(drive_unit,status)) { + status = 0; // state unknown + } + mem_writeb(buffer+1,status); + break; + case 0x0A : /* Get Audio Disk info */ + Bit8u tr1,tr2; TMSF leadOut; + mscdex->GetCDInfo(drive_unit,tr1,tr2,leadOut); + mem_writeb(buffer+1,tr1); + mem_writeb(buffer+2,tr2); + mem_writeb(buffer+3,leadOut.fr); + mem_writeb(buffer+4,leadOut.sec); + mem_writeb(buffer+5,leadOut.min); + mem_writeb(buffer+6,0x00); + break; + case 0x0B :{/* Audio Track Info */ + Bit8u attr; TMSF start; + Bit8u track = mem_readb(buffer+1); + mscdex->GetTrackInfo(drive_unit,track,attr,start); + mem_writeb(buffer+2,start.fr); + mem_writeb(buffer+3,start.sec); + mem_writeb(buffer+4,start.min); + mem_writeb(buffer+5,0x00); + mem_writeb(buffer+6,attr); + break; }; + case 0x0C :{/* Get Audio Sub Channel data */ + Bit8u attr,track,index; + TMSF abs,rel; + mscdex->GetSubChannelData(drive_unit,attr,track,index,rel,abs); + mem_writeb(buffer+1,attr); + mem_writeb(buffer+2,track); + mem_writeb(buffer+3,index); + mem_writeb(buffer+4,rel.min); + mem_writeb(buffer+5,rel.sec); + mem_writeb(buffer+6,rel.fr); + mem_writeb(buffer+7,0x00); + mem_writeb(buffer+8,abs.min); + mem_writeb(buffer+9,abs.sec); + mem_writeb(buffer+10,abs.fr); + break; + }; + case 0x0E :{ /* Get UPC */ + Bit8u attr; char upc[8]; + mscdex->GetUPC(drive_unit,attr,&upc[0]); + mem_writeb(buffer+1,attr); + for (int i=0; i<7; i++) mem_writeb(buffer+2+i,upc[i]); + mem_writeb(buffer+9,0x00); + break; + }; + case 0x0F :{ /* Get Audio Status */ + bool playing,pause; + TMSF resStart,resEnd; + mscdex->GetAudioStatus(drive_unit,playing,pause,resStart,resEnd); + mem_writeb(buffer+1,pause); + mem_writeb(buffer+3,resStart.min); + mem_writeb(buffer+4,resStart.sec); + mem_writeb(buffer+5,resStart.fr); + mem_writeb(buffer+6,0x00); + mem_writeb(buffer+7,resEnd.min); + mem_writeb(buffer+8,resEnd.sec); + mem_writeb(buffer+9,resEnd.fr); + mem_writeb(buffer+10,0x00); + break; + }; + default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unsupported IOCTL INPUT Subfunction %02X",ioctl_fct); + return false; + } + return true; // success +} + +static bool MSCDEX_IOCTL_Optput(PhysPt buffer,Bit8u drive_unit) { + Bitu ioctl_fct = mem_readb(buffer); +// MSCDEX_LOG("MSCDEX: IOCTL OUTPUT Subfunction %02X",ioctl_fct); + switch (ioctl_fct) { + case 0x00 : // Unload /eject media + mscdex->LoadUnloadMedia(drive_unit,true); + break; + case 0x01 : // (un)Lock door + // do nothing -> report as success + break; + case 0x02 : // Reset Drive + LOG(LOG_MISC,LOG_WARN)("cdromDrive reset"); + mscdex->StopAudio(drive_unit); + break; + case 0x05 : // load media + mscdex->LoadUnloadMedia(drive_unit,false); + break; + default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unsupported IOCTL OUTPUT Subfunction %02X",ioctl_fct); + return false; + } + return true; // success +} + static Bitu MSCDEX_Strategy_Handler(void) { // MSCDEX_LOG("MSCDEX: Device Strategy Routine called."); return CBRET_NONE; } static Bitu MSCDEX_Interrupt_Handler(void) { - Bit8u subFuncNr = 0xFF; PhysPt data = PhysMake(SegValue(es),reg_bx); Bit8u subUnit = mem_readb(data+1); Bit8u funcNr = mem_readb(data+2); @@ -786,129 +913,14 @@ static Bitu MSCDEX_Interrupt_Handler(void) { MSCDEX_LOG("MSCDEX: Driver Function %02X",funcNr); switch (funcNr) { - case 0x03 : { /* IOCTL INPUT */ - PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); - subFuncNr = mem_readb(buffer); - MSCDEX_LOG("MSCDEX: IOCTL INPUT Subfunction %02X",subFuncNr); - switch (subFuncNr) { - case 0x00 : /* Get Device Header address */ - mem_writed(buffer+1,RealMake(mscdex->rootDriverHeaderSeg,0)); - break; - case 0x01 :{/* Get current position */ - TMSF pos; - mscdex->GetCurrentPos(subUnit,pos); - /*mem_writeb(buffer+1,0x01); // Red book - mem_writeb(buffer+2,pos.fr); - mem_writeb(buffer+3,pos.sec); - mem_writeb(buffer+4,pos.min); - mem_writeb(buffer+5,0x00);*/ - //Changed to HSG as default - //(Seems to fix a few broken games which don't test for it) - mem_writeb(buffer+1,0x00); //HSG - mem_writed(buffer+2,MSF_TO_FRAMES (pos.min, pos.sec, pos.fr)); - }break; - case 0x06 : /* Get Device status */ - mem_writed(buffer+1,mscdex->GetDeviceStatus(subUnit)); - break; - case 0x07 : /* Get sector size */ - if (mem_readb(buffer+1)==0x01) mem_writed(buffer+2,2352); - else mem_writed(buffer+2,2048); - break; - case 0x08 : /* Get size of current volume */ - mem_writed(buffer+1,mscdex->GetVolumeSize(subUnit)); - break; - case 0x09 : /* Media change ? */ - Bit8u status; - //TEMP mscdex->GetMediaStatus(subUnit,status); - status = 1; - mem_writeb(buffer+1,status); - break; - case 0x0A : /* Get Audio Disk info */ - Bit8u tr1,tr2; TMSF leadOut; - mscdex->GetCDInfo(subUnit,tr1,tr2,leadOut); - mem_writeb(buffer+1,tr1); - mem_writeb(buffer+2,tr2); - mem_writeb(buffer+3,leadOut.fr); - mem_writeb(buffer+4,leadOut.sec); - mem_writeb(buffer+5,leadOut.min); - mem_writeb(buffer+6,0x00); - break; - case 0x0B :{/* Audio Track Info */ - Bit8u attr; TMSF start; - Bit8u track = mem_readb(buffer+1); - mscdex->GetTrackInfo(subUnit,track,attr,start); - mem_writeb(buffer+2,start.fr); - mem_writeb(buffer+3,start.sec); - mem_writeb(buffer+4,start.min); - mem_writeb(buffer+5,0x00); - mem_writeb(buffer+6,attr); - break; }; - case 0x0C :{/* Get Audio Sub Channel data */ - Bit8u attr,track,index; - TMSF abs,rel; - mscdex->GetSubChannelData(subUnit,attr,track,index,rel,abs); - mem_writeb(buffer+1,attr); - mem_writeb(buffer+2,track); - mem_writeb(buffer+3,index); - mem_writeb(buffer+4,rel.min); - mem_writeb(buffer+5,rel.sec); - mem_writeb(buffer+6,rel.fr); - mem_writeb(buffer+7,0x00); - mem_writeb(buffer+8,abs.min); - mem_writeb(buffer+9,abs.sec); - mem_writeb(buffer+10,abs.fr); - break; - }; - case 0x0E :{ /* Get UPC */ - Bit8u attr; char upc[8]; - mscdex->GetUPC(subUnit,attr,&upc[0]); - mem_writeb(buffer+1,attr); - for (int i=0; i<7; i++) mem_writeb(buffer+2+i,upc[i]); - mem_writeb(buffer+9,0x00); - break; - }; - case 0x0F :{ /* Get Audio Status */ - bool playing,pause; - TMSF resStart,resEnd; - mscdex->GetAudioStatus(subUnit,playing,pause,resStart,resEnd); - mem_writeb(buffer+1,pause); - mem_writeb(buffer+3,resStart.min); - mem_writeb(buffer+4,resStart.sec); - mem_writeb(buffer+5,resStart.fr); - mem_writeb(buffer+6,0x00); - mem_writeb(buffer+7,resEnd.min); - mem_writeb(buffer+8,resEnd.sec); - mem_writeb(buffer+9,resEnd.fr); - mem_writeb(buffer+10,0x00); - break; - }; - default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unsupported IOCTL INPUT Subfunction %02X",subFuncNr); - break; - } + PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); + MSCDEX_IOCTL_Input(buffer,subUnit); break; }; case 0x0C : { /* IOCTL OUTPUT */ - PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); - subFuncNr = mem_readb(buffer); -// LOG(LOG_MISC,LOG_ERROR)("MSCDEX: IOCTL OUTPUT Subfunction %02X",subFuncNr); - switch (subFuncNr) { - case 0x00 : // Unload /eject) media - mscdex->LoadUnloadMedia(subUnit,true); - break; - case 0x01 : // (un)Lock door - // do nothing -> report as success - break; - case 0x02 : // Reset Drive - LOG(LOG_MISC,LOG_WARN)("cdromDrive reset"); - mscdex->StopAudio(subUnit); - break; - case 0x05 : // load media - mscdex->LoadUnloadMedia(subUnit,false); - break; - default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unsupported IOCTL OUTPUT Subfunction %02X",subFuncNr); - break; - }; + PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); + MSCDEX_IOCTL_Optput(buffer,subUnit); break; }; case 0x0D : // device open @@ -1047,7 +1059,6 @@ static bool MSCDEX_Handler(void) { case 0x1510: /* Device driver request */ mscdex->SendDriverRequest(reg_cx,data); return true; - default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unknwon call : %04X",reg_ax); return true; @@ -1066,12 +1077,28 @@ public: bool Seek(Bit32u * pos,Bit32u type){return false;} bool Close(){return false;} Bit16u GetInformation(void){return 0xc880;} - bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return true;} - bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return true;} + bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode); + bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode); private: Bit8u cache; }; +bool device_MSCDEX::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode) { + if (MSCDEX_IOCTL_Input(bufptr,0)) { + *retcode=size; + return true; + } + return false; +} + +bool device_MSCDEX::WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode) { + if (MSCDEX_IOCTL_Optput(bufptr,0)) { + *retcode=size; + return true; + } + return false; +} + int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit) { int result = mscdex->AddDrive(driveLetter-'A',(char*)physicalPath,subUnit); From 1521cdcbda45c9ec59db630e08bd63f7d0596820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 9 Apr 2006 13:03:24 +0000 Subject: [PATCH 2503/4131] change swapInNextDisk Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2588 --- include/bios.h | 1 + src/ints/bios_disk.cpp | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/bios.h b/include/bios.h index d222ef2c..902e5525 100644 --- a/include/bios.h +++ b/include/bios.h @@ -159,6 +159,7 @@ extern DOS_DTA *imgDTA; void swapInDisks(void); void swapInNextDisk(void); +bool getSwapRequest(void); void BIOS_ZeroExtendedSize(bool in); void char_out(Bit8u chr,Bit32u att,Bit8u page); diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 72f66a72..90c76b8d 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.27 2006-02-12 23:23:52 harekiet Exp $ */ +/* $Id: bios_disk.cpp,v 1.28 2006-04-09 13:03:24 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" @@ -51,6 +51,7 @@ Bit16u imgDTASeg; RealPt imgDTAPtr; DOS_DTA *imgDTA; bool killRead; +static bool swapping_requested; void CMOS_SetRegister(Bitu regNr, Bit8u val); //For setting equipment word @@ -112,6 +113,12 @@ void swapInDisks(void) { } } +bool getSwapRequest(void) { + bool sreq=swapping_requested; + swapping_requested = false; + return sreq; +} + void swapInNextDisk(bool pressed) { if (!pressed) return; @@ -122,6 +129,7 @@ void swapInNextDisk(bool pressed) { swapPosition++; if(diskSwap[swapPosition] == NULL) swapPosition = 0; swapInDisks(); + swapping_requested = true; } @@ -492,4 +500,5 @@ void BIOS_SetupDisks(void) { MAPPER_AddHandler(swapInNextDisk,MK_f4,MMOD1,"swapimg","Swap Image"); killRead = false; + swapping_requested = false; } From b8499cab5a6ada18dc9d95627d35bb8169c57bde Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 10 Apr 2006 12:06:07 +0000 Subject: [PATCH 2504/4131] Some more const correctness Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2589 --- src/misc/programs.cpp | 4 +-- src/misc/setup.cpp | 66 ++++++++++++++++++++-------------------- src/shell/shell_cmds.cpp | 4 +-- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index f58b042d..c9b6dd12 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.24 2006-03-02 14:12:49 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.25 2006-04-10 12:06:07 qbix79 Exp $ */ #include #include @@ -248,7 +248,7 @@ void CONFIG::Run(void) { WriteOut(MSG_Get("PROGRAM_CONFIG_SECTION_ERROR"),temp_line.c_str()); return; } - char* val = sec->GetPropValue(prop.c_str()); + char const* val = sec->GetPropValue(prop.c_str()); if(!val) { WriteOut(MSG_Get("PROGRAM_CONFIG_NO_PROPERTY"),prop.c_str(),temp_line.c_str()); return; diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index eda8d57b..f3bcdd7a 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.34 2006-03-12 21:26:22 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.35 2006-04-10 12:06:07 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -79,7 +79,7 @@ void Prop_hex::GetValuestring(char* str){ sprintf(str,"%X",value._hex); } -void Section_prop::Add_float(const char* _propname, float _value) { +void Section_prop::Add_float(char const * const _propname, float _value) { Property* test=new Prop_float(_propname,_value); properties.push_back(test); } @@ -90,12 +90,12 @@ void Section_prop::Add_int(const char* _propname, int _value) { properties.push_back(test); } -void Section_prop::Add_string(const char* _propname, char* _value) { +void Section_prop::Add_string(char const * const _propname, char const * const _value) { Property* test=new Prop_string(_propname,_value); properties.push_back(test); } -void Section_prop::Add_bool(const char* _propname, bool _value) { +void Section_prop::Add_bool(char const * const _propname, bool _value) { Property* test=new Prop_bool(_propname,_value); properties.push_back(test); } @@ -103,7 +103,7 @@ void Section_prop::Add_hex(const char* _propname, int _value) { Property* test=new Prop_hex(_propname,_value); properties.push_back(test); } -int Section_prop::Get_int(const char* _propname){ +int Section_prop::Get_int(char const * const _propname){ for(it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ return ((*tel)->GetValue())._int; @@ -112,7 +112,7 @@ int Section_prop::Get_int(const char* _propname){ return 0; } -bool Section_prop::Get_bool(const char* _propname){ +bool Section_prop::Get_bool(char const * const _propname){ for(it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ return ((*tel)->GetValue())._bool; @@ -120,7 +120,7 @@ bool Section_prop::Get_bool(const char* _propname){ } return false; } -float Section_prop::Get_float(const char* _propname){ +float Section_prop::Get_float(char const * const _propname){ for(it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ return ((*tel)->GetValue())._float; @@ -129,7 +129,7 @@ float Section_prop::Get_float(const char* _propname){ return false; } -const char* Section_prop::Get_string(const char* _propname){ +const char* Section_prop::Get_string(char const * const _propname){ for(it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ return ((*tel)->GetValue())._string->c_str(); @@ -137,7 +137,7 @@ const char* Section_prop::Get_string(const char* _propname){ } return ""; } -int Section_prop::Get_hex(const char* _propname){ +int Section_prop::Get_hex(char const * const _propname){ for(it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ return ((*tel)->GetValue())._hex; @@ -170,7 +170,7 @@ void Section_prop::PrintData(FILE* outfile){ } static char buffer[1024]; -char* Section_prop::GetPropValue(const char* _property) { +char const * Section_prop::GetPropValue(char const * const _property) { for(it tel=properties.begin();tel!=properties.end();tel++){ if(!strcasecmp((*tel)->propname.c_str(),_property)){ (*tel)->GetValuestring(buffer); @@ -189,11 +189,11 @@ void Section_line::PrintData(FILE* outfile) { fprintf(outfile,"%s",data.c_str()); } -char* Section_line::GetPropValue(const char* _property) { +char const* Section_line::GetPropValue(char const * const /* _property*/) { return NULL; } -void Config::PrintConfig(const char* configfilename){ +void Config::PrintConfig(char const * const configfilename){ char temp[50];char helpline[256]; FILE* outfile=fopen(configfilename,"w+t"); if(outfile==NULL) return; @@ -223,7 +223,7 @@ void Config::PrintConfig(const char* configfilename){ } -Section_prop* Config::AddSection_prop(const char* _name,void (*_initfunction)(Section*),bool canchange){ +Section_prop* Config::AddSection_prop(char const * const _name,void (*_initfunction)(Section*),bool canchange){ Section_prop* blah = new Section_prop(_name); blah->AddInitFunction(_initfunction,canchange); sectionlist.push_back(blah); @@ -239,7 +239,7 @@ Section_prop::~Section_prop() { } -Section_line* Config::AddSection_line(const char* _name,void (*_initfunction)(Section*)){ +Section_line* Config::AddSection_line(char const * const _name,void (*_initfunction)(Section*)){ Section_line* blah = new Section_line(_name); blah->AddInitFunction(_initfunction); sectionlist.push_back(blah); @@ -278,21 +278,20 @@ Config::~Config() { } } -Section* Config::GetSection(const char* _sectionname){ +Section* Config::GetSection(char const * const _sectionname){ for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ if (!strcasecmp((*tel)->GetName(),_sectionname)) return (*tel); } return NULL; } -Section* Config::GetSectionFromProperty(const char* prop) -{ +Section* Config::GetSectionFromProperty(char const * const prop){ for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ if ((*tel)->GetPropValue(prop)) return (*tel); } return NULL; } -bool Config::ParseConfigFile(const char* configfilename){ +bool Config::ParseConfigFile(char const * const configfilename){ ifstream in(configfilename); if (!in) return false; LOG_MSG("CONFIG:Loading settings from config file %s", configfilename); @@ -373,14 +372,14 @@ void Config::StartUp(void) { (*_start_function)(); } -bool CommandLine::FindExist(char * name,bool remove) { +bool CommandLine::FindExist(char const * const name,bool remove) { cmd_it it; if (!(FindEntry(name,it,false))) return false; if (remove) cmds.erase(it); return true; } -bool CommandLine::FindHex(char * name,int & value,bool remove) { +bool CommandLine::FindHex(char const * const name,int & value,bool remove) { cmd_it it,it_next; if (!(FindEntry(name,it,true))) return false; it_next=it;it_next++; @@ -389,7 +388,7 @@ bool CommandLine::FindHex(char * name,int & value,bool remove) { return true; } -bool CommandLine::FindInt(char * name,int & value,bool remove) { +bool CommandLine::FindInt(char const * const name,int & value,bool remove) { cmd_it it,it_next; if (!(FindEntry(name,it,true))) return false; it_next=it;it_next++; @@ -398,7 +397,7 @@ bool CommandLine::FindInt(char * name,int & value,bool remove) { return true; } -bool CommandLine::FindString(char * name,std::string & value,bool remove) { +bool CommandLine::FindString(char const * const name,std::string & value,bool remove) { cmd_it it,it_next; if (!(FindEntry(name,it,true))) return false; it_next=it;it_next++; @@ -416,7 +415,7 @@ bool CommandLine::FindCommand(unsigned int which,std::string & value) { return true; } -bool CommandLine::FindEntry(char * name,cmd_it & it,bool neednext) { +bool CommandLine::FindEntry(char const * const name,cmd_it & it,bool neednext) { for (it=cmds.begin();it!=cmds.end();it++) { if (!strcasecmp((*it).c_str(),name)) { cmd_it itnext=it;itnext++; @@ -427,11 +426,11 @@ bool CommandLine::FindEntry(char * name,cmd_it & it,bool neednext) { return false; } -bool CommandLine::FindStringBegin(char * begin,std::string & value, bool remove) { - cmd_it it; - for (it=cmds.begin();it!=cmds.end();it++) { - if (strncmp(begin,(*it).c_str(),strlen(begin))==0) { - value=((*it).c_str()+strlen(begin)); +bool CommandLine::FindStringBegin(char const* const begin,std::string & value, bool remove) { + size_t len = strlen(begin); + for (cmd_it it=cmds.begin();it!=cmds.end();it++) { + if (strncmp(begin,(*it).c_str(),len)==0) { + value=((*it).c_str() + len); if (remove) cmds.erase(it); return true; } @@ -439,7 +438,7 @@ bool CommandLine::FindStringBegin(char * begin,std::string & value, bool remove) return false; } -bool CommandLine::FindStringRemain(char * name,std::string & value) { +bool CommandLine::FindStringRemain(char const * const name,std::string & value) { cmd_it it;value=""; if (!FindEntry(name,it)) return false; it++; @@ -466,7 +465,7 @@ unsigned int CommandLine::GetCount(void) { return cmds.size(); } -CommandLine::CommandLine(int argc,char * argv[]) { +CommandLine::CommandLine(int argc,char const * const argv[]) { if (argc>0) { file_name=argv[0]; } @@ -478,13 +477,14 @@ CommandLine::CommandLine(int argc,char * argv[]) { } -CommandLine::CommandLine(char * name,char * cmdline) { +CommandLine::CommandLine(char const * const name,char const * const cmdline) { if (name) file_name=name; /* Parse the cmds and put them in the list */ bool inword,inquote;char c; inword=false;inquote=false; std::string str; - while ((c=*cmdline)!=0) { + const char * c_cmdline=cmdline; + while ((c=*c_cmdline)!=0) { if (inquote) { if (c!='"') str+=c; else { @@ -502,7 +502,7 @@ CommandLine::CommandLine(char * name,char * cmdline) { } else if (c=='"') { inquote=true;} else if (c!=' ') { str+=c;inword=true;} - cmdline++; + c_cmdline++; } if (inword || inquote) cmds.push_back(str); } diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 6db7cebc..308b4439 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.62 2006-02-24 11:50:11 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.63 2006-04-10 12:06:07 qbix79 Exp $ */ #include #include @@ -64,7 +64,7 @@ bool DOS_Shell::CheckConfig(char* cmd,char*line) { Section* test = control->GetSectionFromProperty(cmd); if(!test) return false; if(line && !line[0]) { - char* val = test->GetPropValue(cmd); + char const* val = test->GetPropValue(cmd); if(val) WriteOut("%s\n",val); return true; } From 25b46f0a57a710e86aa60694b56192c34ff4428b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 10 Apr 2006 12:06:25 +0000 Subject: [PATCH 2505/4131] Some more const correctness. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2590 --- include/setup.h | 80 ++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/include/setup.h b/include/setup.h index 13e42c32..b3475e09 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.23 2006-04-08 19:41:49 qbix79 Exp $ */ +/* $Id: setup.h,v 1.24 2006-04-10 12:06:25 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -33,24 +33,24 @@ class CommandLine { public: - CommandLine(int argc,char * argv[]); - CommandLine(char * name,char * cmdline); + 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 * name,bool remove=false); - bool FindHex(char * name,int & value,bool remove=false); - bool FindInt(char * name,int & value,bool remove=false); - bool FindString(char * name,std::string & value,bool remove=false); + 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 * begin,std::string & value, bool remove=false); - bool FindStringRemain(char * name,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); private: typedef std::list::iterator cmd_it; std::list cmds; std::string file_name; - bool FindEntry(char * name,cmd_it & it,bool neednext=false); + bool FindEntry(char const * const name,cmd_it & it,bool neednext=false); }; union Value{ @@ -63,7 +63,7 @@ union Value{ class Property { public: - Property(const char* _propname):propname(_propname) { } + Property(char const * const _propname):propname(_propname) { } virtual void SetValue(char* input)=0; virtual void GetValuestring(char* str)=0; Value GetValue() { return value;} @@ -74,7 +74,7 @@ public: class Prop_int:public Property { public: - Prop_int(const char* _propname, int _value):Property(_propname) { + Prop_int(char const * const _propname, int _value):Property(_propname) { value._int=_value; } void SetValue(char* input); @@ -83,7 +83,7 @@ public: }; class Prop_float:public Property { public: - Prop_float(const char* _propname, float _value):Property(_propname){ + Prop_float(char const * const _propname, float _value):Property(_propname){ value._float=_value; } void SetValue(char* input); @@ -93,7 +93,7 @@ public: class Prop_bool:public Property { public: - Prop_bool(const char* _propname, bool _value):Property(_propname) { + Prop_bool(char const * const _propname, bool _value):Property(_propname) { value._bool=_value; } void SetValue(char* input); @@ -103,7 +103,7 @@ public: class Prop_string:public Property{ public: - Prop_string(const char* _propname, char* _value):Property(_propname) { + Prop_string(char const * const _propname, char const * const _value):Property(_propname) { value._string=new std::string(_value); } ~Prop_string(){ @@ -114,7 +114,7 @@ public: }; class Prop_hex:public Property { public: - Prop_hex(const char* _propname, int _value):Property(_propname) { + Prop_hex(char const * const _propname, int _value):Property(_propname) { value._hex=_value; } void SetValue(char* input); @@ -130,7 +130,7 @@ private: struct Function_wrapper { SectionFunction function; bool canchange; - Function_wrapper(SectionFunction _fun,bool _ch){ + Function_wrapper(SectionFunction const _fun,bool _ch){ function=_fun; canchange=_ch; } @@ -139,7 +139,7 @@ private: std::list destroyfunctions; std::string sectionname; public: - Section(const char* _sectionname):sectionname(_sectionname) { } + Section(char const * const _sectionname):sectionname(_sectionname) { } void AddInitFunction(SectionFunction func,bool canchange=false) {initfunctions.push_back(Function_wrapper(func,canchange));} void AddDestroyFunction(SectionFunction func,bool canchange=false) {destroyfunctions.push_front(Function_wrapper(func,canchange));} @@ -147,7 +147,7 @@ public: void ExecuteDestroy(bool destroyall=true); const char* GetName() {return sectionname.c_str();} - virtual char* GetPropValue(const char* _property)=0; + virtual char const * GetPropValue(char const * const _property)=0; virtual void HandleInputline(char * _line)=0; virtual void PrintData(FILE* outfile)=0; virtual ~Section() { /*Children must call executedestroy ! */} @@ -159,32 +159,32 @@ private: std::list properties; typedef std::list::iterator it; public: - Section_prop(const char* _sectionname):Section(_sectionname){} - void Add_int(const char* _propname, int _value=0); - void Add_string(const char* _propname, char* _value=NULL); - void Add_bool(const char* _propname, bool _value=false); - void Add_hex(const char* _propname, int _value=0); - void Add_float(const char* _propname, float _value=0.0); + Section_prop(char const * const _sectionname):Section(_sectionname){} + void Add_int(char const * const _propname, int _value=0); + void Add_string(char const * const _propname, char const * const _value=NULL); + void Add_bool(char const * const _propname, bool _value=false); + void Add_hex(char const * const _propname, int _value=0); + void Add_float(char const * const _propname, float _value=0.0); - int Get_int(const char* _propname); - const char* Get_string(const char* _propname); - bool Get_bool(const char* _propname); - int Get_hex(const char* _propname); - float Get_float(const char* _propname); + int Get_int(char const * const _propname); + const char* Get_string(char const * const _propname); + bool Get_bool(char const * const _propname); + int Get_hex(char const * const _propname); + float Get_float(char const * const _propname); void HandleInputline(char *gegevens); void PrintData(FILE* outfile); - virtual char* GetPropValue(const char* _property); + virtual char const * GetPropValue(char const * const _property); //ExecuteDestroy should be here else the destroy functions use destroyed properties virtual ~Section_prop(); }; class Section_line: public Section{ public: - Section_line(const char* _sectionname):Section(_sectionname){} + Section_line(char const * const _sectionname):Section(_sectionname){} ~Section_line(){ExecuteDestroy(true);} void HandleInputline(char* gegevens); void PrintData(FILE* outfile); - virtual char* GetPropValue(const char* _property); + virtual const char* GetPropValue(char const * const _property); std::string data; }; @@ -197,21 +197,21 @@ private: typedef std::list::reverse_iterator reverse_it; void (* _start_function)(void); public: - Config(CommandLine * cmd){ cmdline=cmd;} + Config(CommandLine * cmd):cmdline(cmd){} ~Config(); - Section_line * AddSection_line(const char * _name,void (*_initfunction)(Section*)); - Section_prop * AddSection_prop(const char * _name,void (*_initfunction)(Section*),bool canchange=false); + 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(const char* _sectionname); - Section* GetSectionFromProperty(const char* prop); + Section* GetSection(char const* const _sectionname); + Section* GetSectionFromProperty(char const * const prop); void SetStartUp(void (*_function)(void)); void Init(); void ShutDown(); void StartUp(); - void PrintConfig(const char* configfilename); - bool ParseConfigFile(const char* configfilename); + void PrintConfig(char const * const configfilename); + bool ParseConfigFile(char const * const configfilename); void ParseEnv(char ** envp); }; From 57d8180da80968218c828525bbaa77323487fa87 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 10 Apr 2006 12:52:47 +0000 Subject: [PATCH 2506/4131] Remove DOS_No_Drive_Cache. Didn't compile anymore since 0.60. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2591 --- include/dos_system.h | 41 ++++++---------------------------------- src/dos/drive_cache.cpp | 42 +---------------------------------------- 2 files changed, 7 insertions(+), 76 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 5cdb3bd4..411148ca 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.32 2006-04-07 16:34:07 c2woody Exp $ */ +/* $Id: dos_system.h,v 1.33 2006-04-10 12:52:46 qbix79 Exp $ */ #ifndef DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H @@ -108,8 +108,12 @@ 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); @@ -196,40 +200,6 @@ private: bool updatelabel; }; -class DOS_No_Drive_Cache { -public: - DOS_No_Drive_Cache (void) {}; - DOS_No_Drive_Cache (const char* path); - ~DOS_No_Drive_Cache (void) {}; - - typedef enum TDirSort { NOSORT, ALPHABETICAL, DIRALPHABETICAL, ALPHABETICALREV, DIRALPHABETICALREV }; - - void SetBaseDir (const char* path); - void SetDirSort (TDirSort sort) {}; - bool OpenDir (const char* path, Bit16u& id); - bool ReadDir (Bit16u id, char * &result); - - void ExpandName (char* path) {}; - char* GetExpandName (const char* path) { return (char*)path; }; - bool GetShortName (const char* fullname, char* shortname) { return false; }; - - void CacheOut (const char* path, bool ignoreLastDir = false) {}; - void AddEntry (const char* path, bool checkExists = false) {}; - void DeleteEntry (const char* path, bool ignoreLastDir = false) {}; - - void SetCurrentEntry (Bit16u entry) {}; - Bit16u GetCurrentEntry (void) { return 0; }; - - void EmptyCache (void) {}; - - void SetLabel (const char* name) {}; - char* GetLabel (void) {return "";}; - -public: - char basePath [CROSS_LEN]; - char dirPath [CROSS_LEN]; -}; - class DOS_Drive { public: DOS_Drive(); @@ -257,6 +227,7 @@ public: char info[256]; /* Can be overridden for example in iso images */ virtual char const * GetLabel(){return dirCache.GetLabel();}; + DOS_Drive_Cache dirCache; }; diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index c650db8b..adff3b51 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.46 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.47 2006-04-10 12:52:47 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -745,43 +745,3 @@ bool DOS_Drive_Cache::FindNext(Bitu id, char* &result) } return true; }; - -// **************************************************************************** -// No Dir Cache, -// **************************************************************************** - -static DIR* srch_opendir = 0; - -DOS_No_Drive_Cache::DOS_No_Drive_Cache(const char* path) -{ - SetBaseDir(path); -}; - -void DOS_No_Drive_Cache::SetBaseDir(const char* path) -{ - strcpy(basePath,path); -} - -bool DOS_No_Drive_Cache::OpenDir(const char* path, Bit16u& id) -{ - id = 0; - strcpy(dirPath,path); - if((srch_opendir=opendir(dirPath))==NULL) return false; - return true; -}; - -bool DOS_No_Drive_Cache::ReadDir(Bit16u id, char* &result) -{ - static char res[CROSS_LEN] = { 0 }; - dirent * ent; - - if (!srch_opendir) return false; - if ((ent=readdir(srch_opendir))==NULL) { - strcpy(res,ent->d_name); - result=res; - closedir(srch_opendir); - srch_opendir=NULL; - return false; - } - return true; -}; From 49870fee9c6673f0ca797ab8fc2135f81369477c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 11 Apr 2006 12:02:09 +0000 Subject: [PATCH 2507/4131] Implement counter status.(h-a-l-9000) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2592 --- src/hardware/timer.cpp | 140 ++++++++++++++++++++++++++++------------- 1 file changed, 98 insertions(+), 42 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index ecfbd8a5..43e59082 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.35 2006-02-27 20:16:49 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.36 2006-04-11 12:02:09 qbix79 Exp $ */ #include #include "dosbox.h" @@ -53,11 +53,17 @@ struct PIT_Block { bool bcd; bool go_read_latch; bool new_mode; + bool counterstatus_set; }; static PIT_Block pit[3]; -static void PIT0_Event(Bitu val) { +static Bit8u latched_timerstatus; +// the timer status can not be overwritten until it is read or the timer was +// reprogrammed. +static bool latched_timerstatus_locked; + +static void PIT0_Event(Bitu /*val*/) { PIC_ActivateIRQ(0); if (pit[0].mode!=0) PIC_AddEvent(PIT0_Event,pit[0].delay); } @@ -84,7 +90,31 @@ static bool counter_output(Bitu counter) { return true; } } - +static void status_latch(Bitu counter) { + // the timer status can not be overwritten until it is read or the timer was + // reprogrammed. + if(!latched_timerstatus_locked) { + PIT_Block * p=&pit[counter]; + latched_timerstatus=0; + // Timer Status Word + // 0: BCD + // 1-3: Timer mode + // 4-5: read/load mode + // 6: "NULL" - this is 0 if "the counter value is in the counter" ;) + // should rarely be 1 (i.e. on exotic modes) + // 7: OUT - the logic level on the Timer output pin + if(p->bcd)latched_timerstatus|=0x1; + latched_timerstatus|=((p->mode&7)<<1); + if((p->read_state==0)||(p->read_state==3)) latched_timerstatus|=0x30; + else if(p->read_state==1) latched_timerstatus|=0x10; + else if(p->read_state==2) latched_timerstatus|=0x20; + if(counter_output(counter)) latched_timerstatus|=0x80; + // The first thing that is being read from this counter now is the + // counter status. + p->counterstatus_set=true; + latched_timerstatus_locked=true; + } +} static void counter_latch(Bitu counter) { /* Fill the read_latch of the selected counter with current count */ PIT_Block * p=&pit[counter]; @@ -120,7 +150,7 @@ static void counter_latch(Bitu counter) { } -static void write_latch(Bitu port,Bitu val,Bitu iolen) { +static void write_latch(Bitu port,Bitu val,Bitu /*iolen*/) { //LOG(LOG_PIT,LOG_ERROR)("port %X write:%X state:%X",port,val,pit[port-0x40].write_state); Bitu counter=port-0x40; PIT_Block * p=&pit[counter]; @@ -168,44 +198,55 @@ static void write_latch(Bitu port,Bitu val,Bitu iolen) { } } -static Bitu read_latch(Bitu port,Bitu iolen) { +static Bitu read_latch(Bitu port,Bitu /*iolen*/) { //LOG(LOG_PIT,LOG_ERROR)("port read %X",port); Bit32u counter=port-0x40; - if (pit[counter].go_read_latch == true) - counter_latch(counter); - Bit8u ret; - if( pit[counter].bcd == true) BIN2BCD(pit[counter].read_latch); - - switch (pit[counter].read_state) { - case 0: /* read MSB & return to state 3 */ - ret=(pit[counter].read_latch >> 8) & 0xff; - pit[counter].read_state = 3; - pit[counter].go_read_latch = true; - break; - case 3: /* read LSB followed by MSB */ - ret = (pit[counter].read_latch & 0xff); - if (pit[counter].mode & 0x80) pit[counter].mode &= 7; /* moved here */ - else - pit[counter].read_state = 0; - break; - case 1: /* read LSB */ - ret = (pit[counter].read_latch & 0xff); - pit[counter].go_read_latch = true; - break; - case 2: /* read MSB */ - ret = (pit[counter].read_latch >> 8) & 0xff; - pit[counter].go_read_latch = true; - break; - default: - ret=0; - E_Exit("Timer.cpp: error in readlatch"); - break; + Bit8u ret=0; + if(GCC_UNLIKELY(pit[counter].counterstatus_set)){ + pit[counter].counterstatus_set = false; + latched_timerstatus_locked = false; + ret = latched_timerstatus; + } else { + if (pit[counter].go_read_latch == true) + counter_latch(counter); + + if( pit[counter].bcd == true) BIN2BCD(pit[counter].read_latch); + + switch (pit[counter].read_state) { + case 0: /* read MSB & return to state 3 */ + ret=(pit[counter].read_latch >> 8) & 0xff; + pit[counter].read_state = 3; + pit[counter].go_read_latch = true; + break; + case 3: /* read LSB followed by MSB */ + // In mode 3 it never returns odd numbers LSB (if odd number is written 1 will be + // subtracted on first clock and then always 2) + // fixes "Corncob 3D" + if((pit[counter].mode&0x7) == 3) ret = (pit[counter].read_latch & 0xfe); + else ret = (pit[counter].read_latch & 0xff); + + if (pit[counter].mode & 0x80) pit[counter].mode &= 7; + else pit[counter].read_state = 0; + break; + case 1: /* read LSB */ + if((pit[counter].mode&0x7) == 3) ret = (pit[counter].read_latch & 0xfe); + else ret = (pit[counter].read_latch & 0xff); + pit[counter].go_read_latch = true; + break; + case 2: /* read MSB */ + ret = (pit[counter].read_latch >> 8) & 0xff; + pit[counter].go_read_latch = true; + break; + default: + E_Exit("Timer.cpp: error in readlatch"); + break; + } + if( pit[counter].bcd == true) BCD2BIN(pit[counter].read_latch); } - if( pit[counter].bcd == true) BCD2BIN(pit[counter].read_latch); return ret; } -static void write_p43(Bitu port,Bitu val,Bitu iolen) { +static void write_p43(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { //LOG(LOG_PIT,LOG_ERROR)("port 43 %X",val); Bitu latch=(val >> 6) & 0x03; switch (latch) { @@ -221,6 +262,12 @@ static void write_p43(Bitu port,Bitu val,Bitu iolen) { /* Counter latch command */ counter_latch(latch); } else { + // Timer is being reprogrammed, unlock the status + if(pit[latch].counterstatus_set) { + pit[latch].counterstatus_set=false; + latched_timerstatus_locked=false; + } + pit[latch].read_state = (val >> 4) & 0x03; pit[latch].write_state = (val >> 4) & 0x03; Bit8u mode = (val >> 1) & 0x07; @@ -255,9 +302,14 @@ static void write_p43(Bitu port,Bitu val,Bitu iolen) { if (val & 0x02) counter_latch(0); if (val & 0x04) counter_latch(1); if (val & 0x08) counter_latch(2); - } else if ((val & 0x10)==0) { /* Latch status words */ - LOG(LOG_PIT,LOG_ERROR)("Unsupported Latch status word call"); - } else LOG(LOG_PIT,LOG_ERROR)("Unhandled command:%X",val); + } + // status and values can be latched simultaneously + if ((val & 0x10)==0) { /* Latch status words */ + // but only 1 status can be latched simultaneously + if (val & 0x02) status_latch(0); + else if (val & 0x04) status_latch(1); + else if (val & 0x08) status_latch(2); + } break; } } @@ -285,6 +337,7 @@ public: pit[0].mode=3; pit[0].bcd = false; pit[0].go_read_latch = true; + pit[0].counterstatus_set = false; pit[1].bcd = false; pit[1].write_state = 1; @@ -292,7 +345,8 @@ public: pit[1].go_read_latch = true; pit[1].cntr = 18; pit[1].mode = 2; - pit[1].write_state = 3; + pit[1].write_state = 3; + pit[1].counterstatus_set = false; pit[2].read_latch=0; /* MadTv1 */ pit[2].write_state = 3; /* Chuck Yeager */ @@ -301,11 +355,13 @@ public: pit[2].bcd=false; pit[2].cntr=1320; pit[2].go_read_latch=true; + pit[2].counterstatus_set = false; pit[0].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[0].cntr)); pit[1].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[1].cntr)); pit[2].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[2].cntr)); - + + latched_timerstatus_locked=false; PIC_AddEvent(PIT0_Event,pit[0].delay); } ~TIMER(){ @@ -314,7 +370,7 @@ public: }; static TIMER* test; -void TIMER_Destroy(Section* sec){ +void TIMER_Destroy(Section*){ delete test; } void TIMER_Init(Section* sec) { From 132bbffb68de36b27cd4ab8e3f971fef8b74da2e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 11 Apr 2006 19:02:33 +0000 Subject: [PATCH 2508/4131] Add part of patch 1235377 of msharov and fix a few small bugs in the return values of the cpu cores Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2593 --- include/dosbox.h | 2 +- include/logging.h | 34 +++++++++++++++++----------------- include/paging.h | 3 ++- include/programs.h | 2 +- include/support.h | 2 +- src/cpu/paging.cpp | 8 ++++---- src/debug/debug_gui.cpp | 11 +++++------ src/gui/render_simple.h | 4 ++-- src/gui/render_templates.h | 2 +- src/gui/sdlmain.cpp | 4 ++-- src/hardware/iohandler.cpp | 10 +++++----- src/misc/programs.cpp | 4 ++-- src/misc/support.cpp | 6 +++--- 13 files changed, 46 insertions(+), 46 deletions(-) diff --git a/include/dosbox.h b/include/dosbox.h index cb843854..47c6953d 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -21,7 +21,7 @@ #include "config.h" -void E_Exit(char * message,...); +void E_Exit(const char * message,...) GCC_ATTRIBUTE( __format__(__printf__, 1, 2)); void MSG_Add(const char*,const char*); //add messages to the internal langaugefile const char* MSG_Get(char const *); //get messages from the internal langaugafile diff --git a/include/logging.h b/include/logging.h index 81ee2531..bf161734 100644 --- a/include/logging.h +++ b/include/logging.h @@ -14,50 +14,50 @@ enum LOG_TYPES { enum LOG_SEVERITIES { LOG_NORMAL, - LOG_WARN, + LOG_WARN, LOG_ERROR, }; #if C_DEBUG class LOG { - LOG_TYPES d_type; - LOG_SEVERITIES d_severity; + 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* buf, ...); //../src/debug/debug_gui.cpp + void operator() (char const* buf, ...) GCC_ATTRIBUTE(__format__(__printf__, 2, 3)); //../src/debug/debug_gui.cpp }; -void DEBUG_ShowMsg(char * format,...); +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 type, LOG_SEVERITIES severity) { return;} - void operator()(char const* buf) { return;} - void operator()(char const* buf, double f1) { return;} - void operator()(char const* buf, double f1, double f2) { return;} - void operator()(char const* buf, double f1, double f2, double f3) { return;} - void operator()(char const* buf, double f1, double f2, double f3, double f4) { return;} - void operator()(char const* buf, double f1, double f2, double f3, double f4, double f5) { return;} + 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* buf, char const* s1) { return;} - void operator()(char const* buf, char const* s1, double f1) { return;} - void operator()(char const* buf, char const* s1, double f1,double f2) { return;} - void operator()(char const* buf, double f1, char const* s1) { return;} + 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* ) { } }; //add missing operators to here //try to avoid anything smaller than bit32... -void GFX_ShowMsg(char * format,...); +void GFX_ShowMsg(char const* format,...) GCC_ATTRIBUTE(__format__(__printf__, 1, 2)); #define LOG_MSG GFX_ShowMsg #endif //C_DEBUG diff --git a/include/paging.h b/include/paging.h index e7a18422..64751c96 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.22 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: paging.h,v 1.23 2006-04-11 19:02:33 qbix79 Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H @@ -48,6 +48,7 @@ class PageDirectory; class PageHandler { public: + virtual ~PageHandler(void) { } virtual Bitu readb(PhysPt addr); virtual Bitu readw(PhysPt addr); virtual Bitu readd(PhysPt addr); diff --git a/include/programs.h b/include/programs.h index 7d6be6a4..17c7a5c5 100644 --- a/include/programs.h +++ b/include/programs.h @@ -50,6 +50,6 @@ public: }; typedef void (PROGRAMS_Main)(Program * * make); -void PROGRAMS_MakeFile(char * name,PROGRAMS_Main * main); +void PROGRAMS_MakeFile(char const * const name,PROGRAMS_Main * main); #endif diff --git a/include/support.h b/include/support.h index 83ee6ff7..73d20813 100644 --- a/include/support.h +++ b/include/support.h @@ -45,7 +45,7 @@ char *ltrim(char *str); char *rtrim(char *str); char *trim(char * str); -bool ScanCMDBool(char * cmd,char * check); +bool ScanCMDBool(char * cmd,char const * const check); char * ScanCMDRemain(char * cmd); char * StripWord(char *&cmd); bool IsDecWord(char * word); diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 7c804cf7..0fdb6dca 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -52,7 +52,7 @@ Bitu PageHandler::readd(PhysPt addr) { (readb(addr+3) << 24); } -void PageHandler::writeb(PhysPt addr,Bitu val) { +void PageHandler::writeb(PhysPt addr,Bitu /*val*/) { E_Exit("No byte handler for write to %d",addr); }; @@ -67,11 +67,11 @@ void PageHandler::writed(PhysPt addr,Bitu val) { writeb(addr+3,(Bit8u) (val >> 24)); }; -HostPt PageHandler::GetHostReadPt(Bitu phys_page) { +HostPt PageHandler::GetHostReadPt(Bitu /*phys_page*/) { return 0; } -HostPt PageHandler::GetHostWritePt(Bitu phys_page) { +HostPt PageHandler::GetHostWritePt(Bitu /*phys_page*/) { return 0; } @@ -111,7 +111,7 @@ static struct { static Bits PageFaultCore(void) { CPU_CycleLeft+=CPU_Cycles; CPU_Cycles=1; - Bitu ret=CPU_Core_Full_Run(); + Bits ret=CPU_Core_Full_Run(); CPU_CycleLeft+=CPU_Cycles; if (ret<0) E_Exit("Got a dosbox close machine in pagefault core?"); if (ret) diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 41b5d46a..0b6e8f11 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug_gui.cpp,v 1.28 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: debug_gui.cpp,v 1.29 2006-04-11 19:02:33 qbix79 Exp $ */ #include "dosbox.h" @@ -34,7 +34,7 @@ #include "debug_inc.h" struct _LogGroup { - char * front; + char const* front; bool enabled; }; #include @@ -52,7 +52,7 @@ extern int old_cursor_state; -void DEBUG_ShowMsg(char * format,...) { +void DEBUG_ShowMsg(char const* format,...) { char buf[512]; va_list msg; @@ -97,7 +97,7 @@ void DEBUG_RefreshPage(char scroll) { wrefresh(dbg.win_out); } -void LOG::operator() (char* format, ...){ +void LOG::operator() (char const* format, ...){ char buf[512]; va_list msg; va_start(msg,format); @@ -188,8 +188,7 @@ static void MakePairs(void) { init_pair(PAIR_BLACK_GREY, COLOR_BLACK /*| FOREGROUND_INTENSITY */, COLOR_WHITE); init_pair(PAIR_GREY_RED, COLOR_WHITE/*| FOREGROUND_INTENSITY */, COLOR_RED); } -static void LOG_Destroy(Section* sec) { - +static void LOG_Destroy(Section*) { if(debuglog) fclose(debuglog); } diff --git a/src/gui/render_simple.h b/src/gui/render_simple.h index 35e337cb..bbdce56b 100644 --- a/src/gui/render_simple.h +++ b/src/gui/render_simple.h @@ -29,7 +29,7 @@ static void conc4d(SCALERNAME,SBPP,DBPP,R)(const void *s) { Bitu hadChange = 0; #if (SBPP == 9) for (Bits x=render.src.width;x>0;) { - if (*(Bit32u*)src == *(Bit32u*)cache && !( + if (*(Bit32u const*)src == *(Bit32u*)cache && !( render.pal.modified[src[0]] | render.pal.modified[src[1]] | render.pal.modified[src[2]] | @@ -40,7 +40,7 @@ static void conc4d(SCALERNAME,SBPP,DBPP,R)(const void *s) { line0+=4*SCALERWIDTH; #else for (Bits x=render.src.width;x>0;) { - if (*(Bitu*)src == *(Bitu*)cache) { + if (*(Bitu const*)src == *(Bitu*)cache) { x-=(sizeof(Bitu)/sizeof(SRCTYPE)); src+=(sizeof(Bitu)/sizeof(SRCTYPE)); cache+=(sizeof(Bitu)/sizeof(SRCTYPE)); diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index 21631bc2..ea234529 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -129,7 +129,7 @@ static void conc3d(Cache,SBPP,DBPP) (const void * s) { if (pixel != fc[x]) { #else for (Bitu x=0;x #include "dosbox.h" @@ -29,10 +29,10 @@ IO_WriteHandler * io_writehandlers[3][IO_MAX]; IO_ReadHandler * io_readhandlers[3][IO_MAX]; -static Bitu IO_ReadBlocked(Bitu port,Bitu iolen) { +static Bitu IO_ReadBlocked(Bitu /*port*/,Bitu /*iolen*/) { return ~0; } -static void IO_WriteBlocked(Bitu port,Bitu val,Bitu iolen) { +static void IO_WriteBlocked(Bitu /*port*/,Bitu /*val*/,Bitu /*iolen*/) { } static Bitu IO_ReadDefault(Bitu port,Bitu iolen) { @@ -150,7 +150,7 @@ static struct { static Bits IOFaultCore(void) { CPU_CycleLeft+=CPU_Cycles; CPU_Cycles=1; - Bitu ret=CPU_Core_Full_Run(); + Bits ret=CPU_Core_Full_Run(); CPU_CycleLeft+=CPU_Cycles; if (ret<0) E_Exit("Got a dosbox close machine in IO-fault core?"); if (ret) @@ -377,7 +377,7 @@ public: static IO* test; -void IO_Destroy(Section* sec) { +void IO_Destroy(Section*) { delete test; } diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index c9b6dd12..76f05c96 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.25 2006-04-10 12:06:07 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.26 2006-04-11 19:02:33 qbix79 Exp $ */ #include #include @@ -51,7 +51,7 @@ static Bit8u exe_block[]={ static std::vector internal_progs; -void PROGRAMS_MakeFile(char * name,PROGRAMS_Main * main) { +void PROGRAMS_MakeFile(char const * const name,PROGRAMS_Main * main) { Bit8u * comdata=(Bit8u *)malloc(32); //MEM LEAK memcpy(comdata,&exe_block,sizeof(exe_block)); comdata[CB_POS]=call_program&0xff; diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 6fac9042..0b8bd8dc 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.29 2006-02-09 11:47:57 qbix79 Exp $ */ +/* $Id: support.cpp,v 1.30 2006-04-11 19:02:33 qbix79 Exp $ */ #include #include @@ -65,7 +65,7 @@ char *trim(char *str) { } -bool ScanCMDBool(char * cmd,char * check) { +bool ScanCMDBool(char * cmd,char const * const check) { char * scan=cmd;size_t c_len=strlen(check); while ((scan=strchr(scan,'/'))) { /* found a / now see behind it */ @@ -145,7 +145,7 @@ double ConvDblWord(char * word) { static char buf[1024]; //greater scope as else it doesn't always gets thrown right (linux/gcc2.95) -void E_Exit(char * format,...) { +void E_Exit(const char * format,...) { #if C_DEBUG && C_HEAVY_DEBUG DEBUG_HeavyWriteLogInstruction(); #endif From 550e61640f4686b639d6289b142ad01b00dd62b6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 12 Apr 2006 18:52:50 +0000 Subject: [PATCH 2509/4131] keep it compiling with msvc. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2594 --- src/gui/sdlmain.cpp | 4 ++-- src/hardware/hardware.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index cb7b4999..3e5ad1d1 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.114 2006-04-11 19:02:33 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.115 2006-04-12 18:52:50 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -206,7 +206,7 @@ struct SDL_Block { static SDL_Block sdl; -extern char * RunningProgram; +extern const char* RunningProgram; extern bool CPU_CycleAuto; //Globals for keyboard initialisation bool startup_state_numlock=false; diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index f1460381..13f4e06e 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: hardware.cpp,v 1.16 2006-03-29 13:51:58 harekiet Exp $ */ +/* $Id: hardware.cpp,v 1.17 2006-04-12 18:52:50 qbix79 Exp $ */ #include #include @@ -37,7 +37,7 @@ #endif static char * capturedir; -extern char * RunningProgram; +extern const char* RunningProgram; Bitu CaptureState; #define WAVE_BUF 16*1024 From 20530fa7259a90f67bcf21f9ea95d35785e16601 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 14 Apr 2006 07:03:47 +0000 Subject: [PATCH 2510/4131] A few flag fixes by c2woody. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2595 --- src/cpu/instructions.h | 107 ++++++++++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 27 deletions(-) diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index bd5981cd..d2830733 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -228,7 +228,14 @@ #define ROLB(op1,op2,load,save) \ - if (!(op2&0x7)) break; \ + if (!(op2&0x7)) { \ + if (op2&0x18) { \ + FillFlags(); \ + SETFLAGBIT(CF,op1 & 1); \ + SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 7)); \ + } \ + break; \ + } \ FillFlags(); \ lf_var1b=load(op1); \ lf_var2b=op2&0x07; \ @@ -239,7 +246,13 @@ SETFLAGBIT(OF,(lf_resb & 1) ^ (lf_resb >> 7)); #define ROLW(op1,op2,load,save) \ - if (!(op2&0xf)) break; \ + if (!(op2&0xf)) { \ + if (op2&0x10) { \ + FillFlags(); \ + SETFLAGBIT(CF,op1 & 1); \ + } \ + break; \ + } \ FillFlags(); \ lf_var1w=load(op1); \ lf_var2b=op2&0xf; \ @@ -262,7 +275,14 @@ #define RORB(op1,op2,load,save) \ - if (!(op2&0x7)) break; \ + if (!(op2&0x7)) { \ + if (op2&0x10) { \ + FillFlags(); \ + SETFLAGBIT(CF,op1>>7); \ + SETFLAGBIT(OF,(op1>>7) ^ ((op1>>6) & 1)); \ + } \ + break; \ + } \ FillFlags(); \ lf_var1b=load(op1); \ lf_var2b=op2&0x07; \ @@ -273,7 +293,13 @@ if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resb ^ lf_var1b) & 0x80); #define RORW(op1,op2,load,save) \ - if (!(op2&0xf)) break; \ + if (!(op2&0xf)) { \ + if (op2&0x10) { \ + FillFlags(); \ + SETFLAGBIT(CF,op1>>15); \ + } \ + break; \ + } \ FillFlags(); \ lf_var1w=load(op1); \ lf_var2b=op2&0xf; \ @@ -470,43 +496,58 @@ #define DAA() \ if (((reg_al & 0x0F)>0x09) || get_AF()) { \ + if ((reg_al > 0x99) || get_CF()) { \ + reg_al+=0x60; \ + SETFLAGBIT(CF,true); \ + } else { \ + SETFLAGBIT(CF,false); \ + } \ reg_al+=0x06; \ SETFLAGBIT(AF,true); \ } else { \ + if ((reg_al > 0x99) || get_CF()) { \ + reg_al+=0x60; \ + SETFLAGBIT(CF,true); \ + } else { \ + SETFLAGBIT(CF,false); \ + } \ SETFLAGBIT(AF,false); \ } \ - if ((reg_al > 0x9F) || get_CF()) { \ - reg_al+=0x60; \ - SETFLAGBIT(CF,true); \ - } else { \ - SETFLAGBIT(CF,false); \ - } \ SETFLAGBIT(SF,(reg_al&0x80)); \ SETFLAGBIT(ZF,(reg_al==0)); \ + SETFLAGBIT(PF,parity_lookup[reg_al]); \ lflags.type=t_UNKNOWN; #define DAS() \ if (((reg_al & 0x0f) > 9) || get_AF()) { \ + if ((reg_al>0x99) || get_CF()) { \ + reg_al-=0x60; \ + SETFLAGBIT(CF,true); \ + } else { \ + SETFLAGBIT(CF,false); \ + } \ reg_al-=6; \ SETFLAGBIT(AF,true); \ } else { \ + if ((reg_al>0x99) || get_CF()) { \ + reg_al-=0x60; \ + SETFLAGBIT(CF,true); \ + } else { \ + SETFLAGBIT(CF,false); \ + } \ SETFLAGBIT(AF,false); \ } \ - if ((reg_al>0x9f) || get_CF()) { \ - reg_al-=0x60; \ - SETFLAGBIT(CF,true); \ - } else { \ - SETFLAGBIT(CF,false); \ - } \ + SETFLAGBIT(SF,(reg_al&0x80)); \ + SETFLAGBIT(ZF,(reg_al==0)); \ + SETFLAGBIT(PF,parity_lookup[reg_al]); \ lflags.type=t_UNKNOWN; #define AAA() \ if (get_AF() || ((reg_al & 0xf) > 9)) \ { \ - reg_al += 6; \ - reg_ah += 1; \ + reg_ax += 0x106; \ SETFLAGBIT(AF,true); \ SETFLAGBIT(CF,true); \ } else { \ @@ -514,13 +555,15 @@ SETFLAGBIT(CF,false); \ } \ reg_al &= 0x0F; \ - lflags.type=t_UNKNOWN; + lflags.type=t_UNKNOWN; \ + SETFLAGBIT(SF,0); \ + SETFLAGBIT(OF,0); \ + SETFLAGBIT(ZF,(reg_al == 0)); \ + SETFLAGBIT(PF,parity_lookup[reg_al]); #define AAS() \ if (((reg_al & 0x0f)>9) || get_AF()) { \ - reg_ah--; \ - if (reg_al < 6) reg_ah--; \ - reg_al=(reg_al-6) & 0xF; \ + reg_ax -= 0x106; \ SETFLAGBIT(AF,true); \ SETFLAGBIT(CF,true); \ } else { \ @@ -528,17 +571,24 @@ SETFLAGBIT(CF,false); \ } \ reg_al &= 0x0F; \ - lflags.type=t_UNKNOWN; + lflags.type=t_UNKNOWN; \ + SETFLAGBIT(SF,0); \ + SETFLAGBIT(OF,0); \ + SETFLAGBIT(ZF,(reg_al == 0)); \ + SETFLAGBIT(PF,parity_lookup[reg_al]); #define AAM(op1) \ { \ Bit8u BLAH=op1; \ reg_ah=reg_al / BLAH; \ reg_al=reg_al % BLAH; \ - lflags.type=t_UNKNOWN; \ SETFLAGBIT(SF,(reg_al & 0x80)); \ SETFLAGBIT(ZF,(reg_al == 0)); \ SETFLAGBIT(PF,parity_lookup[reg_al]); \ + SETFLAGBIT(CF,0); \ + SETFLAGBIT(OF,0); \ + SETFLAGBIT(AF,0); \ + lflags.type=t_UNKNOWN; \ } @@ -550,9 +600,9 @@ Bit8u old_al = reg_al; \ reg_al = (Bit8u) ax2; \ reg_ah = 0; \ - SETFLAGBIT(AF,(ax1 & 0x08) != (ax2 & 0x08)); \ - SETFLAGBIT(CF,ax2 > 0xff); \ - SETFLAGBIT(OF,(reg_al & 0x80) != (old_al & 0x80)); \ + SETFLAGBIT(CF,0); \ + SETFLAGBIT(OF,0); \ + SETFLAGBIT(AF,0); \ SETFLAGBIT(SF,reg_al >= 0x80); \ SETFLAGBIT(ZF,reg_al == 0); \ SETFLAGBIT(PF,parity_lookup[reg_al]); \ @@ -562,6 +612,7 @@ #define MULB(op1,load,save) \ FillFlags(); \ reg_ax=reg_al*load(op1); \ + SETFLAGBIT(ZF,reg_al == 0); \ if (reg_ax & 0xff00) { \ SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ } else { \ @@ -574,6 +625,7 @@ Bitu tempu=(Bitu)reg_ax*(Bitu)(load(op1)); \ reg_ax=(Bit16u)(tempu); \ reg_dx=(Bit16u)(tempu >> 16); \ + SETFLAGBIT(ZF,reg_ax == 0); \ if (reg_dx) { \ SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ } else { \ @@ -587,6 +639,7 @@ Bit64u tempu=(Bit64u)reg_eax*(Bit64u)(load(op1)); \ reg_eax=(Bit32u)(tempu); \ reg_edx=(Bit32u)(tempu >> 32); \ + SETFLAGBIT(ZF,reg_eax == 0); \ if (reg_edx) { \ SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ } else { \ From b53832e7a81734592f28486189c5ebac70a8600e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 14 Apr 2006 07:19:37 +0000 Subject: [PATCH 2511/4131] Improve error code support(c2woody). Silence a few warnings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2596 --- src/dos/dos_mscdex.cpp | 65 ++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 11f21fd8..c8058fb2 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.39 2006-04-09 12:46:03 c2woody Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.40 2006-04-14 07:19:37 qbix79 Exp $ */ #include #include @@ -124,7 +124,7 @@ public: bool GetCDInfo (Bit8u subUnit, Bit8u& tr1, Bit8u& tr2, TMSF& leadOut); Bit32u GetVolumeSize (Bit8u subUnit); bool GetTrackInfo (Bit8u subUnit, Bit8u track, Bit8u& attr, TMSF& start); - Bit16u GetStatusWord (Bit8u subUnit); + Bit16u GetStatusWord (Bit8u subUnit,Bit16u status); bool GetCurrentPos (Bit8u subUnit, TMSF& pos); Bit32u GetDeviceStatus (Bit8u subUnit); bool GetMediaStatus (Bit8u subUnit, Bit8u& status); @@ -317,7 +317,7 @@ PhysPt CMscdex::GetDefaultBuffer(void) void CMscdex::GetDriverInfo (PhysPt data) { for (Bit16u i=0; i=numDrives) return false; + if (subUnit>=numDrives) return false; // Get SubUnit mem_writeb(data+1,subUnit); // Call Strategy / Interrupt @@ -743,13 +743,12 @@ bool CMscdex::SendDriverRequest(Bit16u drive, PhysPt data) return true; }; -Bit16u CMscdex::GetStatusWord(Bit8u subUnit) +Bit16u CMscdex::GetStatusWord(Bit8u subUnit,Bit16u status) { - if (subUnit>=numDrives) return 0x02; // error : Drive not ready + if (subUnit>=numDrives) return REQUEST_STATUS_ERROR | 0x02; // error : Drive not ready - Bit16u status ; - if (dinfo[subUnit].lastResult) status = REQUEST_STATUS_DONE; // ok - else status = REQUEST_STATUS_ERROR; + if (dinfo[subUnit].lastResult) status |= REQUEST_STATUS_DONE; // ok + else status |= REQUEST_STATUS_ERROR; if (dinfo[subUnit].audioPlay) { // Check if audio is still playing.... @@ -793,14 +792,18 @@ static bool MSCDEX_IOCTL_Input(PhysPt buffer,Bit8u drive_unit) { mem_writeb(buffer+3,pos.sec); mem_writeb(buffer+4,pos.min); mem_writeb(buffer+5,0x00); - } else LOG_MSG("MSCDEX: Get position: invalid address mode %x",addr_mode); + } else { + LOG_MSG("MSCDEX: Get position: invalid address mode %x",addr_mode); + return false; + } }break; case 0x06 : /* Get Device status */ mem_writed(buffer+1,mscdex->GetDeviceStatus(drive_unit)); break; case 0x07 : /* Get sector size */ - if (mem_readb(buffer+1)==0x01) mem_writed(buffer+2,2352); - else mem_writed(buffer+2,2048); + if (mem_readb(buffer+1)==0) mem_writed(buffer+2,2048); + else if (mem_readb(buffer+1)==1) mem_writed(buffer+2,2352); + else return false; break; case 0x08 : /* Get size of current volume */ mem_writed(buffer+1,mscdex->GetVolumeSize(drive_unit)); @@ -877,27 +880,26 @@ static bool MSCDEX_IOCTL_Input(PhysPt buffer,Bit8u drive_unit) { return true; // success } -static bool MSCDEX_IOCTL_Optput(PhysPt buffer,Bit8u drive_unit) { +static Bit16u MSCDEX_IOCTL_Optput(PhysPt buffer,Bit8u drive_unit) { Bitu ioctl_fct = mem_readb(buffer); // MSCDEX_LOG("MSCDEX: IOCTL OUTPUT Subfunction %02X",ioctl_fct); switch (ioctl_fct) { case 0x00 : // Unload /eject media - mscdex->LoadUnloadMedia(drive_unit,true); + if (!mscdex->LoadUnloadMedia(drive_unit,true)) return 0x02; break; case 0x01 : // (un)Lock door // do nothing -> report as success break; case 0x02 : // Reset Drive LOG(LOG_MISC,LOG_WARN)("cdromDrive reset"); - mscdex->StopAudio(drive_unit); + if (!mscdex->StopAudio(drive_unit)) return 0x02; break; case 0x05 : // load media - mscdex->LoadUnloadMedia(drive_unit,false); - break; + if (!mscdex->LoadUnloadMedia(drive_unit,false)) return 0x02; default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unsupported IOCTL OUTPUT Subfunction %02X",ioctl_fct); - return false; + return 0x03; // invalid function } - return true; // success + return 0x00; // success } static Bitu MSCDEX_Strategy_Handler(void) { @@ -909,18 +911,22 @@ static Bitu MSCDEX_Interrupt_Handler(void) { PhysPt data = PhysMake(SegValue(es),reg_bx); Bit8u subUnit = mem_readb(data+1); Bit8u funcNr = mem_readb(data+2); + Bit16u errcode = 0; MSCDEX_LOG("MSCDEX: Driver Function %02X",funcNr); switch (funcNr) { case 0x03 : { /* IOCTL INPUT */ PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); - MSCDEX_IOCTL_Input(buffer,subUnit); + if (!MSCDEX_IOCTL_Input(buffer,subUnit)) { + errcode = 0x03; //unknown command + } break; }; case 0x0C : { /* IOCTL OUTPUT */ PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); - MSCDEX_IOCTL_Optput(buffer,subUnit); + Bit16u error=MSCDEX_IOCTL_Optput(buffer,subUnit); + if (error) errcode = error; break; }; case 0x0D : // device open @@ -961,7 +967,7 @@ static Bitu MSCDEX_Interrupt_Handler(void) { }; // Set Statusword - mem_writew(data+3,mscdex->GetStatusWord(subUnit)); + mem_writew(data+3,mscdex->GetStatusWord(subUnit,errcode)); MSCDEX_LOG("MSCDEX: Status : %04X",mem_readw(data+3)); return CBRET_NONE; } @@ -1057,7 +1063,12 @@ static bool MSCDEX_Handler(void) { CALLBACK_SCF(!success); }; return true; case 0x1510: /* Device driver request */ - mscdex->SendDriverRequest(reg_cx,data); + if (mscdex->SendDriverRequest(reg_cx,data)) { + CALLBACK_SCF(false); + } else { + reg_ax = 0x0f; // invalid drive + CALLBACK_SCF(true); + } return true; default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unknwon call : %04X",reg_ax); return true; @@ -1069,18 +1080,18 @@ static bool MSCDEX_Handler(void) { class device_MSCDEX : public DOS_Device { public: device_MSCDEX() { SetName("MSCD001"); } - bool Read (Bit8u * data,Bit16u * size) { return false;} - bool Write(Bit8u * data,Bit16u * size) { + bool Read (Bit8u * /*data*/,Bit16u * /*size*/) { return false;} + bool Write(Bit8u * /*data*/,Bit16u * /*size*/) { LOG(LOG_ALL,LOG_NORMAL)("Write to mscdex device"); return false; } - bool Seek(Bit32u * pos,Bit32u type){return false;} + bool Seek(Bit32u * /*pos*/,Bit32u /*type*/){return false;} bool Close(){return false;} Bit16u GetInformation(void){return 0xc880;} bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode); bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode); private: - Bit8u cache; +// Bit8u cache; }; bool device_MSCDEX::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode) { From 1627e9540a43f268c3401babad6e0a747251f533 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 14 Apr 2006 13:53:58 +0000 Subject: [PATCH 2512/4131] Don't change reg_bl on succes. (Fixes B.A.T 2 CD version) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2597 --- src/ints/xms.cpp | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index f8064662..3e367bbf 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.39 2006-02-09 11:47:57 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.40 2006-04-14 13:53:58 qbix79 Exp $ */ #include #include @@ -252,9 +252,15 @@ static bool multiplex_xms(void) { return false; }; +#define SET_RESULT(caller) { \ +res = caller; \ +if(res) reg_bl = res; \ +reg_ax = (res==0); \ +} Bitu XMS_Handler(void) { // LOG(LOG_MISC,LOG_ERROR)("XMS: CALL %02X",reg_ah); + Bitu res = 0; switch (reg_ah) { case XMS_GET_VERSION: /* 00 */ @@ -273,13 +279,11 @@ Bitu XMS_Handler(void) { case XMS_GLOBAL_ENABLE_A20: /* 03 */ case XMS_LOCAL_ENABLE_A20: /* 05 */ - reg_bl = XMS_EnableA20(true); - reg_ax = (reg_bl==0); + SET_RESULT(XMS_EnableA20(true)); break; case XMS_GLOBAL_DISABLE_A20: /* 04 */ case XMS_LOCAL_DISABLE_A20: /* 06 */ - reg_bl = XMS_EnableA20(false); - reg_ax = (reg_bl==0); + SET_RESULT(XMS_EnableA20(false)); break; case XMS_QUERY_A20: /* 07 */ reg_ax = XMS_GetEnabledA20(); @@ -294,39 +298,33 @@ Bitu XMS_Handler(void) { case XMS_ALLOCATE_EXTENDED_MEMORY: /* 09 */ { Bit16u handle = 0; - reg_bl = XMS_AllocateMemory(reg_dx,handle); + SET_RESULT(XMS_AllocateMemory(reg_dx,handle)); reg_dx = handle; - reg_ax = (reg_bl==0); // set ax to success/failure }; break; case XMS_FREE_EXTENDED_MEMORY: /* 0a */ - reg_bl = XMS_FreeMemory(reg_dx); - reg_ax = (reg_bl==0); + SET_RESULT(XMS_FreeMemory(reg_dx)); break; case XMS_MOVE_EXTENDED_MEMORY_BLOCK: /* 0b */ - reg_bl = XMS_MoveMemory(SegPhys(ds)+reg_si); - reg_ax = (reg_bl==0); + SET_RESULT(XMS_MoveMemory(SegPhys(ds)+reg_si)); break; case XMS_LOCK_EXTENDED_MEMORY_BLOCK: { /* 0c */ Bit32u address; - reg_bl = XMS_LockMemory(reg_dx, address); - reg_ax = (reg_bl==0); - if (reg_bl==0) { // success + res = XMS_LockMemory(reg_dx, address); + if(res) reg_bl = res; + reg_ax = (res==0); + if (res==0) { // success reg_bx=(Bit16u)(address & 0xFFFF); reg_dx=(Bit16u)(address >> 16); }; }; break; case XMS_UNLOCK_EXTENDED_MEMORY_BLOCK: /* 0d */ - reg_bl = XMS_UnlockMemory(reg_dx); - reg_ax = (reg_bl==0); + SET_RESULT(XMS_UnlockMemory(reg_dx)); + break; + case XMS_GET_EMB_HANDLE_INFORMATION: /* 0e */ + SET_RESULT(XMS_GetHandleInformation(reg_dx,reg_bh,reg_bl,reg_dx)); break; - case XMS_GET_EMB_HANDLE_INFORMATION: { /* 0e */ - Bitu result = XMS_GetHandleInformation(reg_dx,reg_bh,reg_bl,reg_dx); - if (result != 0) reg_bl = result; - reg_ax = (result==0); - }; break; case XMS_RESIZE_EXTENDED_MEMORY_BLOCK: /* 0f */ - reg_bl = XMS_ResizeMemory(reg_dx, reg_bx); - reg_ax = (reg_bl==0); + SET_RESULT(XMS_ResizeMemory(reg_dx, reg_bx)); break; case XMS_ALLOCATE_UMB: { /* 10 */ if (!umb_available) { @@ -387,7 +385,7 @@ Bitu XMS_Handler(void) { reg_ecx = (MEM_TotalPages()*MEM_PAGESIZE)-1; // highest known physical memory address break; case XMS_GET_EMB_HANDLE_INFORMATION_EXT: { /* 8e */ - Bit8u free_handles; + Bit8u free_handles; Bitu result = XMS_GetHandleInformation(reg_dx,reg_bh,free_handles,reg_dx); if (result != 0) reg_bl = result; else { @@ -468,7 +466,7 @@ public: }; static XMS* test; -void XMS_ShutDown(Section* sec) { +void XMS_ShutDown(Section* /*sec*/) { delete test; } From 8b7b77b21e74cf6197adbde57e121800725199aa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 15 Apr 2006 15:53:37 +0000 Subject: [PATCH 2513/4131] Isname should use strcasecmp as it deals with emulated DOS file names. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2598 --- include/dos_system.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 411148ca..25a9d54b 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,12 +16,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.33 2006-04-10 12:52:46 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.34 2006-04-15 15:53:37 qbix79 Exp $ */ #ifndef DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H - #include #ifndef DOSBOX_DOSBOX_H #include "dosbox.h" @@ -29,8 +28,12 @@ #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_ASCII (DOS_NAMELENGTH+1) @@ -71,7 +74,7 @@ public: virtual void SetName(const char* _name) { if (name) delete[] name; name = new char[strlen(_name)+1]; strcpy(name,_name); } virtual char* GetName(void) { return name; }; virtual bool IsOpen() { return open; }; - virtual bool IsName(const char* _name) { if (!name) return false; return strcmp(name,_name)==0; }; + 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; } From fd7f1e45b428201ed9384b278bc46d3993e66f46 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 16 Apr 2006 14:02:39 +0000 Subject: [PATCH 2514/4131] Add a very simple dummy LPT1 class. Fixes games opening LPT1 under MS Windows. (for example Cisco Heat) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2599 --- src/dos/dos_devices.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 83fecee5..ed436f10 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_devices.cpp,v 1.12 2006-04-07 16:34:07 c2woody Exp $ */ +/* $Id: dos_devices.cpp,v 1.13 2006-04-16 14:02:39 qbix79 Exp $ */ #include #include "dosbox.h" @@ -37,24 +37,30 @@ DOS_Device * Devices[DOS_DEVICES]; class device_NUL : public DOS_Device { public: device_NUL() { SetName("NUL"); }; - bool Read(Bit8u * data,Bit16u * size) { + virtual bool Read(Bit8u * data,Bit16u * size) { for(Bitu i = 0; i < *size;i++) data[i]=0; - LOG(LOG_IOCTL,LOG_NORMAL)("NUL:READ"); + LOG(LOG_IOCTL,LOG_NORMAL)("%s:READ",GetName()); return true; } - bool Write(Bit8u * data,Bit16u * size) { - LOG(LOG_IOCTL,LOG_NORMAL)("NUL:WRITE"); + virtual bool Write(Bit8u * data,Bit16u * size) { + LOG(LOG_IOCTL,LOG_NORMAL)("%s:WRITE",GetName()); return true; } - bool Seek(Bit32u * pos,Bit32u type) { - LOG(LOG_IOCTL,LOG_NORMAL)("NUL:SEEK"); + virtual bool Seek(Bit32u * pos,Bit32u type) { + LOG(LOG_IOCTL,LOG_NORMAL)("%s:SEEK",GetName()); return true; } - bool Close() { return true; } - Bit16u GetInformation(void) { return 0x8084; } - bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return false;} - bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return false;} + virtual bool Close() { return true; } + virtual Bit16u GetInformation(void) { return 0x8084; } + virtual bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return false;} + virtual bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return false;} +}; + +class device_LPT1 : public device_NUL { +public: + device_LPT1() { SetName("LPT1");} + Bit16u GetInformation(void) { return 0x80A0; } }; bool DOS_Device::Read(Bit8u * data,Bit16u * size) { @@ -168,4 +174,7 @@ void DOS_SetupDevices(void) { DOS_Device * newdev2; newdev2=new device_NUL(); DOS_AddDevice(newdev2); + DOS_Device * newdev3; + newdev3=new device_LPT1(); + DOS_AddDevice(newdev3); } From 31103c160e301bd3fa33c12a8dfc23af4fb6b79c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 16 Apr 2006 14:04:03 +0000 Subject: [PATCH 2515/4131] In unlink fails and it happends because of the file is open. Try closing it and deleting again. Fixes problems of Ultima 7 addon installer under MS Windows. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2600 --- src/dos/drive_local.cpp | 44 +++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 6f9e38e9..6ea92f08 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.64 2006-03-13 19:58:09 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.65 2006-04-16 14:04:03 qbix79 Exp $ */ #include #include @@ -78,7 +78,7 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) { }; bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { - char * type; + const char* type; switch (flags &3) { case OPEN_READ:type="rb"; break; case OPEN_WRITE:type="rb+"; break; @@ -107,7 +107,7 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { } return false; } - + *file=new localFile(name,hand,0x202); (*file)->flags=flags; //for the inheritance flag and maybe check for others. // (*file)->SetFileName(newname); @@ -135,17 +135,45 @@ bool localDrive::GetSystemFilename(char *sysName, char *dosName) { } bool localDrive::FileUnlink(char * name) { + char newname[CROSS_LEN]; strcpy(newname,basedir); strcat(newname,name); CROSS_FILENAME(newname); - if (!unlink(dirCache.GetExpandName(newname))) { + char *fullname = dirCache.GetExpandName(newname); + if (unlink(fullname)) { + //Unlink failed for some reason try finding it. + struct stat buffer; + if(stat(fullname,&buffer)) return false; // File not found. + + FILE* file_writable = fopen(fullname,"rb+"); + if(!file_writable) return false; //No acces ? ERROR MESSAGE NOT SET. FIXME ? + fclose(file_writable); + + //File exists and can technically be deleted, nevertheless it failed. + //This means that the file is probably open by some process. + //See if We have it open. + DOS_File* found_file = 0; + for(Bitu i = 0;i < DOS_FILES;i++){ + if(Files[i] && Files[i]->IsName(name)) + if(!found_file) found_file=Files[i]; + else return false; + } + if(!found_file) return false; + Bitu max = DOS_FILES; + while(found_file->IsOpen() && max--) + found_file->Close(); + if (!unlink(fullname)) { + dirCache.DeleteEntry(newname); + return true; + } + return false; + } else { dirCache.DeleteEntry(newname); return true; - }; + } return false; -}; - +} bool localDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) { @@ -450,7 +478,7 @@ bool localFile::Seek(Bit32u * pos,Bit32u type) { bool localFile::Close() { // only close if one reference left if (refCtr==1) { - fclose(fhandle); + if(fhandle) fclose(fhandle); fhandle = 0; open = false; }; From 0b6195208d82d3501c35e3236fc214f3f01896bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 16 Apr 2006 20:11:04 +0000 Subject: [PATCH 2516/4131] implement ioctl control channels for ems device (GEMMIS support) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2601 --- src/ints/ems.cpp | 87 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 5 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index f19e79cb..6fe6f932 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.48 2006-04-07 16:34:07 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.49 2006-04-16 20:11:04 c2woody Exp $ */ #include #include @@ -41,6 +41,7 @@ #define EMM_MAX_PHYS 4 /* 4 16kb pages in pageframe */ #define EMM_VERSION 0x40 +#define GEMMIS_VERSION 0x0001 // Version 1.0 #define NULL_HANDLE 0xffff #define NULL_PAGE 0xffff @@ -68,10 +69,14 @@ #define EMM_MOVE_OVLAPI 0x97 #define EMM_NOT_FOUND 0xa0 +static Bit16u GEMMIS_seg; class device_EMM : public DOS_Device { public: - device_EMM(){SetName("EMMXXXX0");} + device_EMM() { + SetName("EMMXXXX0"); + GEMMIS_seg=0; + } bool Read(Bit8u * data,Bit16u * size) { return false;} bool Write(Bit8u * data,Bit16u * size){ LOG(LOG_IOCTL,LOG_NORMAL)("EMS:Write to device"); @@ -80,12 +85,82 @@ public: bool Seek(Bit32u * pos,Bit32u type){return false;} bool Close(){return false;} Bit16u GetInformation(void){return 0xc080;} - bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return true;} + bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode); bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return true;} private: Bit8u cache; }; +bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode) { + Bitu subfct=mem_readb(bufptr); + switch (subfct) { + case 0x00: + if (size!=6) return false; + mem_writew(bufptr+0x00,0x0023); // ID + mem_writed(bufptr+0x02,0); // private API entry point + *retcode=6; + return true; + case 0x01: { + if (size!=6) return false; + if (GEMMIS_seg==0) GEMMIS_seg=DOS_GetMemory(0x20); + PhysPt GEMMIS_addr=PhysMake(GEMMIS_seg,0); + + mem_writew(GEMMIS_addr+0x00,0x0004); // flags + mem_writew(GEMMIS_addr+0x02,0x019d); // size of this structure + mem_writew(GEMMIS_addr+0x04,GEMMIS_VERSION); // version 1.0 (provide ems information only) + mem_writed(GEMMIS_addr+0x06,0); // reserved + + /* build non-EMS frames (0-0xe000) */ + for (Bitu frct=0; frct>4); // version 4.0 + mem_writew(bufptr+0x01,EMM_VERSION&0x0f); + *retcode=2; + return true; + } + return false; +} + struct EMM_Mapping { Bit16u handle; Bit16u page; @@ -863,7 +938,7 @@ static Bitu V86_Monitor() { if ((rm_val<0xc0) || (rm_val>=0xe8)) E_Exit("Invalid opcode 0x0f 0x20 %x caused a protection fault!",rm_val); Bit32u crx=CPU_GET_CRX(which); - switch (rm_val&3) { + switch (rm_val&7) { case 0: reg_eax=crx; break; case 1: reg_ecx=crx; break; case 2: reg_edx=crx; break; @@ -882,7 +957,7 @@ static Bitu V86_Monitor() { if ((rm_val<0xc0) || (rm_val>=0xe8)) E_Exit("Invalid opcode 0x0f 0x22 %x caused a protection fault!",rm_val); Bit32u crx; - switch (rm_val&3) { + switch (rm_val&7) { case 0: crx=reg_eax; break; case 1: crx=reg_ecx; break; case 2: crx=reg_edx; break; @@ -1069,6 +1144,7 @@ public: call_vdma.Set_RealVec(0x4b); vcpi.enabled=false; + GEMMIS_seg=0; Section_prop * section=static_cast(configuration); if (!section->Get_bool("ems")) return; @@ -1161,6 +1237,7 @@ public: /* Remove ems device */ device_EMM newdev; DOS_DelDevice(&newdev); + GEMMIS_seg=0; /* Remove the emsname and callback hack */ char buf[32]= { 0 }; From 329d32a8ddf5711c8be4701e60ec2934fd4a6879 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 17 Apr 2006 10:45:32 +0000 Subject: [PATCH 2517/4131] Fix some issues with mounting floppy images with invalid bootsector. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2602 --- src/dos/dos_programs.cpp | 39 ++++++++++++++++++++++----------------- src/dos/drive_fat.cpp | 16 ++++++++-------- src/dos/drive_local.cpp | 6 +++--- src/dos/drives.h | 7 ++++--- 4 files changed, 37 insertions(+), 31 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index c3b21ee6..b9ca13be 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.57 2006-04-07 15:15:45 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.58 2006-04-17 10:45:32 qbix79 Exp $ */ #include #include @@ -54,22 +54,22 @@ public: /* Check for unmounting */ if (cmd->FindString("-u",umount,false)) { umount[0] = toupper(umount[0]); - int drive = umount[0]-'A'; - if(drive < DOS_DRIVES && Drives[drive]) { - if(drive == DOS_GetDefaultDrive()) { + int i_drive = umount[0]-'A'; + if(i_drive < DOS_DRIVES && Drives[i_drive]) { + if(i_drive == DOS_GetDefaultDrive()) { WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_CURRENT")); return; } try { /* Check if virtualdrive */ - if( dynamic_cast(Drives[drive]) == 0 ) throw 0; + if( dynamic_cast(Drives[i_drive]) == 0 ) throw 0; } catch(...) { WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NO_VIRTUAL")); return; } WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCES"),umount[0]); - delete Drives[drive]; - Drives[drive] = 0; + delete Drives[i_drive]; + Drives[i_drive] = 0; } else { WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED"),umount[0]); } @@ -331,7 +331,8 @@ public: } /* Test for and show free EMS */ Bit16u handle; - if (DOS_OpenFile("EMMXXXX0",0,&handle)) { + char emm[9] = { 'E','M','M','X','X','X','X','0',0 }; + if (DOS_OpenFile(emm,0,&handle)) { DOS_CloseFile(handle); reg_ah=0x42; CALLBACK_RunRealInt(0x67); @@ -714,8 +715,8 @@ public: WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY2")); return; } - drive=temp_line[0]-'0'; - if(drive>3) { + drive=temp_line[0]; + if((drive-'0')>3) { WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY2")); return; } @@ -739,13 +740,13 @@ public: char tmp[CROSS_LEN]; safe_strncpy(tmp, temp_line.c_str(), CROSS_LEN); - Bit8u drive; - if (!DOS_MakeName(tmp, fullname, &drive) || strncmp(Drives[drive]->GetInfo(),"local directory",15)) { + Bit8u dummy; + if (!DOS_MakeName(tmp, fullname, &dummy) || strncmp(Drives[dummy]->GetInfo(),"local directory",15)) { WriteOut(MSG_Get("PROGRAM_IMGMOUNG_FILE_NOT_FOUND")); return; } - localDrive *ldp = (localDrive*)Drives[drive]; + localDrive *ldp = (localDrive*)Drives[dummy]; ldp->GetSystemFilename(tmp, fullname); temp_line = tmp; @@ -762,6 +763,10 @@ public: if(fstype=="fat") { newdrive=new fatDrive(temp_line.c_str(),sizes[0],sizes[1],sizes[2],sizes[3],0); + if(!(dynamic_cast(newdrive))->created_succesfully) { + delete newdrive; + newdrive = 0; + } } else if (fstype=="iso") { int error; MSCDEX_SetCDInterface(CDROM_USE_SDL, -1); @@ -798,7 +803,7 @@ public: if (newdrive) delete newdrive; return; } - if (!newdrive) WriteOut(MSG_Get("PROGRAM_IMGMOUNT_CANT_CREATE")); + if (!newdrive) {WriteOut(MSG_Get("PROGRAM_IMGMOUNT_CANT_CREATE"));return;} Drives[drive-'A']=newdrive; // Set the correct media byte in the table mem_writeb(Real2Phys(dos.tables.mediaid)+(drive-'A')*2,mediaid); @@ -830,10 +835,10 @@ public: mem_writeb(Real2Phys(dos.tables.mediaid)+(drive-'A')*2,mediaid); WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,temp_line.c_str()); } else if (fstype=="none") { - if(imageDiskList[drive] != NULL) delete imageDiskList[drive]; - imageDiskList[drive] = newImage; + if(imageDiskList[drive-'0'] != NULL) delete imageDiskList[drive-'0']; + imageDiskList[drive-'0'] = newImage; updateDPT(); - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MOUNT_NUMBER"),drive,temp_line.c_str()); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MOUNT_NUMBER"),drive-'0',temp_line.c_str()); } // check if volume label is given diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 19a50b0a..54a6b4d2 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.12 2006-02-20 08:59:52 qbix79 Exp $ */ +/* $Id: drive_fat.cpp,v 1.13 2006-04-17 10:45:32 qbix79 Exp $ */ #include #include @@ -582,6 +582,7 @@ bool fatDrive::allocateCluster(Bit32u useCluster, Bit32u prevCluster) { } fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, Bit32u headscyl, Bit32u cylinders, Bit32u startSector) { + created_succesfully = true; FILE *diskfile; Bit32u filesize; struct partTable mbrData; @@ -593,14 +594,14 @@ fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, } diskfile = fopen(sysFilename, "rb+"); - if(!diskfile) return; + if(!diskfile) {created_succesfully = false;return;} fseek(diskfile, 0L, SEEK_END); filesize = (Bit32u)ftell(diskfile) / 1024L; - /* Load disk image */ + /* Load disk image */ loadedDisk = new imageDisk(diskfile, (Bit8u *)sysFilename, filesize, (filesize > 2880)); if(!loadedDisk) { - delete this; + created_succesfully = false; return; } @@ -629,13 +630,12 @@ fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, loadedDisk->Read_AbsoluteSector(0+partSectOff,&bootbuffer); if ((bootbuffer.magic1 != 0x55) || (bootbuffer.magic2 != 0xaa)) { /* Not a FAT filesystem */ - delete this; - return; + LOG_MSG("Loaded image has no valid magicnumbers at the end!"); } if(!bootbuffer.sectorsperfat) { /* FAT32 not implemented yet */ - delete this; + created_succesfully = false; return; } @@ -673,7 +673,7 @@ fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, cwdDirCluster = 0; memset(fatSectBuffer,0,1024); - curFatSect = 0xffffffff; + curFatSect = 0xffffffff; } bool fatDrive::AllocationInfo(Bit16u *_bytes_sector, Bit8u *_sectors_cluster, Bit16u *_total_clusters, Bit16u *_free_clusters) { diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 6ea92f08..cca4e2bf 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.65 2006-04-16 14:04:03 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.66 2006-04-17 10:45:30 qbix79 Exp $ */ #include #include @@ -114,7 +114,7 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { return true; }; -FILE * localDrive::GetSystemFilePtr(char * name, char * type) { +FILE * localDrive::GetSystemFilePtr(char const * const name, char const * const type) { char newname[CROSS_LEN]; strcpy(newname,basedir); @@ -125,7 +125,7 @@ FILE * localDrive::GetSystemFilePtr(char * name, char * type) { return fopen(newname,type); } -bool localDrive::GetSystemFilename(char *sysName, char *dosName) { +bool localDrive::GetSystemFilename(char *sysName, char const * const dosName) { strcpy(sysName, basedir); strcat(sysName, dosName); diff --git a/src/dos/drives.h b/src/dos/drives.h index 2c65ff1d..30503d1e 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.31 2006-02-12 13:32:30 qbix79 Exp $ */ +/* $Id: drives.h,v 1.32 2006-04-17 10:45:32 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ @@ -33,8 +33,8 @@ class localDrive : public DOS_Drive { public: localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid); virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags); - virtual FILE *GetSystemFilePtr(char * name, char * type); - virtual bool GetSystemFilename(char *sysName, char *dosName); + virtual FILE *GetSystemFilePtr(char const * const name, char const * const type); + virtual bool GetSystemFilename(char* sysName, char const * const dosName); virtual bool FileCreate(DOS_File * * file,char * name,Bit16u attributes); virtual bool FileUnlink(char * name); virtual bool RemoveDir(char * dir); @@ -153,6 +153,7 @@ public: bool directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum); bool directoryChange(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum); imageDisk *loadedDisk; + bool created_succesfully; private: Bit32u getClusterValue(Bit32u clustNum); void setClusterValue(Bit32u clustNum, Bit32u clustValue); From 6250acff2dc86771929888ec18820f06769b3658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 17 Apr 2006 20:06:39 +0000 Subject: [PATCH 2518/4131] add mscdex device strategy implementation Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2603 --- src/dos/dos_mscdex.cpp | 85 +++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 39 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index c8058fb2..70c5d93f 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.40 2006-04-14 07:19:37 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.41 2006-04-17 20:06:39 c2woody Exp $ */ #include #include @@ -114,7 +114,7 @@ public: bool GetCopyrightName (Bit16u drive, PhysPt data); bool GetAbstractName (Bit16u drive, PhysPt data); bool GetDocumentationName(Bit16u drive, PhysPt data); - bool GetDirectoryEntry (Bit16u drive, bool copyFlag, PhysPt pathname, PhysPt buffer, Bitu& error); + bool GetDirectoryEntry (Bit16u drive, bool copyFlag, PhysPt pathname, PhysPt buffer, Bit16u& error); bool ReadVTOC (Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error); bool ReadSectors (Bit16u drive, Bit32u sector, Bit16u num, PhysPt data); bool ReadSectors (Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data); @@ -570,14 +570,14 @@ bool CMscdex::ReadSectors(Bit16u drive, Bit32u sector, Bit16u num, PhysPt data) return ReadSectors(GetSubUnit(drive),false,sector,num,data); }; -bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, PhysPt buffer, Bitu& error) +bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, PhysPt buffer, Bit16u& error) { char volumeID[6] = {0}; char searchName[256]; char entryName[256]; bool foundComplete = false; bool foundName; - char* useName; + char* useName = 0; Bitu entryLength,nameLength; // clear error error = 0; @@ -773,8 +773,9 @@ void CMscdex::InitNewMedia(Bit8u subUnit) { }; static CMscdex* mscdex = 0; +static PhysPt curReqheaderPtr = 0; -static bool MSCDEX_IOCTL_Input(PhysPt buffer,Bit8u drive_unit) { +static Bit16u MSCDEX_IOCTL_Input(PhysPt buffer,Bit8u drive_unit) { Bitu ioctl_fct = mem_readb(buffer); MSCDEX_LOG("MSCDEX: IOCTL INPUT Subfunction %02X",ioctl_fct); switch (ioctl_fct) { @@ -794,7 +795,7 @@ static bool MSCDEX_IOCTL_Input(PhysPt buffer,Bit8u drive_unit) { mem_writeb(buffer+5,0x00); } else { LOG_MSG("MSCDEX: Get position: invalid address mode %x",addr_mode); - return false; + return 0x03; // invalid function } }break; case 0x06 : /* Get Device status */ @@ -803,7 +804,7 @@ static bool MSCDEX_IOCTL_Input(PhysPt buffer,Bit8u drive_unit) { case 0x07 : /* Get sector size */ if (mem_readb(buffer+1)==0) mem_writed(buffer+2,2048); else if (mem_readb(buffer+1)==1) mem_writed(buffer+2,2352); - else return false; + else return 0x03; // invalid function break; case 0x08 : /* Get size of current volume */ mem_writed(buffer+1,mscdex->GetVolumeSize(drive_unit)); @@ -875,9 +876,9 @@ static bool MSCDEX_IOCTL_Input(PhysPt buffer,Bit8u drive_unit) { break; }; default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unsupported IOCTL INPUT Subfunction %02X",ioctl_fct); - return false; + return 0x03; // invalid function } - return true; // success + return 0x00; // success } static Bit16u MSCDEX_IOCTL_Optput(PhysPt buffer,Bit8u drive_unit) { @@ -903,28 +904,34 @@ static Bit16u MSCDEX_IOCTL_Optput(PhysPt buffer,Bit8u drive_unit) { } static Bitu MSCDEX_Strategy_Handler(void) { -// MSCDEX_LOG("MSCDEX: Device Strategy Routine called."); + curReqheaderPtr = PhysMake(SegValue(es),reg_bx); +// MSCDEX_LOG("MSCDEX: Device Strategy Routine called, request header at %x",curReqheaderPtr); return CBRET_NONE; } static Bitu MSCDEX_Interrupt_Handler(void) { - PhysPt data = PhysMake(SegValue(es),reg_bx); - Bit8u subUnit = mem_readb(data+1); - Bit8u funcNr = mem_readb(data+2); + if (curReqheaderPtr==0) { + MSCDEX_LOG("MSCDEX: invalid call to interrupt handler"); + return CBRET_NONE; + } + Bit8u subUnit = mem_readb(curReqheaderPtr+1); + Bit8u funcNr = mem_readb(curReqheaderPtr+2); Bit16u errcode = 0; + PhysPt buffer = 0; MSCDEX_LOG("MSCDEX: Driver Function %02X",funcNr); + if ((funcNr==0x03) || (funcNr==0x0c) || (funcNr==0x80) || (funcNr==0x82)) { + buffer = PhysMake(mem_readw(curReqheaderPtr+0x10),mem_readw(curReqheaderPtr+0x0E)); + } + switch (funcNr) { case 0x03 : { /* IOCTL INPUT */ - PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); - if (!MSCDEX_IOCTL_Input(buffer,subUnit)) { - errcode = 0x03; //unknown command - } + Bit16u error=MSCDEX_IOCTL_Input(buffer,subUnit); + if (error) errcode = error; break; }; case 0x0C : { /* IOCTL OUTPUT */ - PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); Bit16u error=MSCDEX_IOCTL_Optput(buffer,subUnit); if (error) errcode = error; break; @@ -934,22 +941,21 @@ static Bitu MSCDEX_Interrupt_Handler(void) { break; case 0x80 : // Read long case 0x82 : { // Read long prefetch -> both the same here :) - PhysPt buff = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E)); - Bit32u start = mem_readd(data+0x14); - Bit16u len = mem_readw(data+0x12); - bool raw = (mem_readb(data+0x18)==1); - if (mem_readb(data+0x0D)==0x00) // HSG - mscdex->ReadSectors(subUnit,raw,start,len,buff); + Bit32u start = mem_readd(curReqheaderPtr+0x14); + Bit16u len = mem_readw(curReqheaderPtr+0x12); + bool raw = (mem_readb(curReqheaderPtr+0x18)==1); + if (mem_readb(curReqheaderPtr+0x0D)==0x00) // HSG + mscdex->ReadSectors(subUnit,raw,start,len,buffer); else - mscdex->ReadSectorsMSF(subUnit,raw,start,len,buff); + mscdex->ReadSectorsMSF(subUnit,raw,start,len,buffer); break; }; case 0x83 : // Seek - dont care :) break; case 0x84 : { /* Play Audio Sectors */ - Bit32u start = mem_readd(data+0x0E); - Bit32u len = mem_readd(data+0x12); - if (mem_readb(data+0x0D)==0x00) // HSG + Bit32u start = mem_readd(curReqheaderPtr+0x0E); + Bit32u len = mem_readd(curReqheaderPtr+0x12); + if (mem_readb(curReqheaderPtr+0x0D)==0x00) // HSG mscdex->PlayAudioSector(subUnit,start,len); else // RED BOOK mscdex->PlayAudioMSF(subUnit,start,len); @@ -967,8 +973,8 @@ static Bitu MSCDEX_Interrupt_Handler(void) { }; // Set Statusword - mem_writew(data+3,mscdex->GetStatusWord(subUnit,errcode)); - MSCDEX_LOG("MSCDEX: Status : %04X",mem_readw(data+3)); + mem_writew(curReqheaderPtr+3,mscdex->GetStatusWord(subUnit,errcode)); + MSCDEX_LOG("MSCDEX: Status : %04X",mem_readw(curReqheaderPtr+3)); return CBRET_NONE; } @@ -985,7 +991,7 @@ static bool MSCDEX_Handler(void) { } } - if (reg_ah!=0x15) return false; + if (reg_ah!=0x15) return false; // not handled here, continue chain PhysPt data = PhysMake(SegValue(es),reg_bx); MSCDEX_LOG("MSCDEX: INT 2F %04X BX= %04X CX=%04X",reg_ax,reg_bx,reg_cx); @@ -1057,7 +1063,7 @@ static bool MSCDEX_Handler(void) { mscdex->GetDrives(data); return true; case 0x150F: { // Get directory entry - Bitu error; + Bit16u error; bool success = mscdex->GetDirectoryEntry(reg_cl,reg_ch&1,data,PhysMake(reg_si,reg_di),error); reg_ax = error; CALLBACK_SCF(!success); @@ -1070,11 +1076,9 @@ static bool MSCDEX_Handler(void) { CALLBACK_SCF(true); } return true; - default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unknwon call : %04X",reg_ax); - return true; - }; - return false; + LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unknwon call : %04X",reg_ax); + return true; }; class device_MSCDEX : public DOS_Device { @@ -1095,7 +1099,7 @@ private: }; bool device_MSCDEX::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode) { - if (MSCDEX_IOCTL_Input(bufptr,0)) { + if (MSCDEX_IOCTL_Input(bufptr,0)==0) { *retcode=size; return true; } @@ -1103,7 +1107,7 @@ bool device_MSCDEX::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * re } bool device_MSCDEX::WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode) { - if (MSCDEX_IOCTL_Optput(bufptr,0)) { + if (MSCDEX_IOCTL_Optput(bufptr,0)==0) { *retcode=size; return true; } @@ -1153,7 +1157,9 @@ void MSCDEX_SetCDInterface(int intNr, int numCD) void MSCDEX_ShutDown(Section* sec) { - delete mscdex; mscdex = 0; + delete mscdex; + mscdex = 0; + curReqheaderPtr = 0; }; void MSCDEX_Init(Section* sec) @@ -1163,6 +1169,7 @@ void MSCDEX_Init(Section* sec) /* Register the mscdex device */ DOS_Device * newdev = new device_MSCDEX(); DOS_AddDevice(newdev); + curReqheaderPtr = 0; /* Add Multiplexer */ DOS_AddMultiplexHandler(MSCDEX_Handler); /* Create MSCDEX */ From aa07ccb5288c86580c8444133af0ea9703d89b6e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 18 Apr 2006 13:52:24 +0000 Subject: [PATCH 2519/4131] Keep it compiling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2604 --- src/ints/ems.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 6fe6f932..0ae57537 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.49 2006-04-16 20:11:04 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.50 2006-04-18 13:52:24 qbix79 Exp $ */ #include #include @@ -115,7 +115,7 @@ bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retco mem_writeb(GEMMIS_addr+0x0a+frct*6,0x00); // frame type: NONE mem_writeb(GEMMIS_addr+0x0b+frct*6,0xff); // owner: NONE mem_writew(GEMMIS_addr+0x0c+frct*6,0xffff); // non-EMS frame - mem_writeb(GEMMIS_addr+0x0e+frct*6,0xff); // EMS page number (NONE) + mem_writeb(GEMMIS_addr+0x0e + frct*6,0xff); // EMS page number (NONE) mem_writeb(GEMMIS_addr+0x0f+frct*6,0xaa); // flags: direct mapping } /* build EMS page frame (0xe000-0xf000) */ @@ -124,7 +124,7 @@ bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retco mem_writeb(GEMMIS_addr+0x0a+frnr,0x03); // frame type: EMS frame in 64k page mem_writeb(GEMMIS_addr+0x0b+frnr,0xff); // owner: NONE mem_writew(GEMMIS_addr+0x0c+frnr,0x7fff); // no logical page number - mem_writeb(GEMMIS_addr+0x0e+frnr,frct); // physical EMS page number + mem_writeb(GEMMIS_addr+0x0e + frnr,frct); // physical EMS page number mem_writeb(GEMMIS_addr+0x0f+frnr,0x00); // EMS frame } /* build non-EMS ROM frames (0xf000-0x10000) */ @@ -132,7 +132,7 @@ bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retco mem_writeb(GEMMIS_addr+0x0a+frct*6,0x00); // frame type: NONE mem_writeb(GEMMIS_addr+0x0b+frct*6,0xff); // owner: NONE mem_writew(GEMMIS_addr+0x0c+frct*6,0xffff); // non-EMS frame - mem_writeb(GEMMIS_addr+0x0e+frct*6,0xff); // EMS page number (NONE) + mem_writeb(GEMMIS_addr+0x0e + frct*6,0xff); // EMS page number (NONE) mem_writeb(GEMMIS_addr+0x0f+frct*6,0xaa); // flags: direct mapping } From ec58b58543580d162f4175ae784b4918a573d150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 18 Apr 2006 15:24:09 +0000 Subject: [PATCH 2520/4131] update msvc configuration files Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2605 --- src/platform/visualc/config.h | 2 +- visualc_net/dosbox.vcproj | 68 +++++++++++++++++------------------ 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index f80fb7ce..06e87ca5 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -1,6 +1,6 @@ #define INLINE __forceinline -#define VERSION "0.63" +#define VERSION "0.65" /* Define to 1 to enable internal debugger, requires libcurses */ diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index cafb8984..c7706767 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -298,21 +298,6 @@ - - - - - - - - - - @@ -349,24 +334,6 @@ - - - - - - - - - - - - @@ -392,10 +359,43 @@ - + + + + + + + + + + + + + + + + + + + + + + + Date: Tue, 18 Apr 2006 17:44:25 +0000 Subject: [PATCH 2521/4131] precalculate inverted stack mask; improve dynamic core stack functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2606 --- include/cpu.h | 2 +- src/cpu/core_dyn_x86.cpp | 14 +--- src/cpu/core_dyn_x86/decoder.h | 136 +++++++++----------------------- src/cpu/core_dyn_x86/risc_x86.h | 32 +++++--- src/cpu/cpu.cpp | 34 +++++--- 5 files changed, 87 insertions(+), 131 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 9e755a12..8562ee0f 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -418,7 +418,7 @@ struct CPUBlock { GDTDescriptorTable gdt; DescriptorTable idt; struct { - Bitu mask; + Bitu mask,notmask; bool big; } stack; struct { diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 5dd4e64c..570a0b00 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -20,8 +20,6 @@ #if (C_DYNAMIC_X86) -#define CHECKED_MEMORY_ACCESS - #include #include #include @@ -46,11 +44,7 @@ #include "paging.h" #include "inout.h" -#ifdef CHECKED_MEMORY_ACCESS #define CACHE_MAXSIZE (4096*2) -#else -#define CACHE_MAXSIZE (4096) -#endif #define CACHE_PAGES (128*8) #define CACHE_TOTAL (CACHE_PAGES*4096) #define CACHE_BLOCKS (64*1024) @@ -73,7 +67,7 @@ enum { G_EAX,G_ECX,G_EDX,G_EBX, G_ESP,G_EBP,G_ESI,G_EDI, G_ES,G_CS,G_SS,G_DS,G_FS,G_GS, - G_FLAGS,G_SMASK,G_EIP, + G_FLAGS,G_NEWESP,G_EIP, G_EA,G_STACK,G_CYCLES, G_TMPB,G_TMPW,G_SHIFT, G_EXIT, @@ -155,7 +149,7 @@ static DynReg DynRegs[G_MAX]; #define DREG(_WHICH_) &DynRegs[G_ ## _WHICH_ ] static struct { - Bitu ea,tmpb,tmpd,stack,shift; + Bitu ea,tmpb,tmpd,stack,shift,newesp; } extra_regs; static void IllegalOption(const char* msg) { @@ -326,8 +320,8 @@ void CPU_Core_Dyn_X86_Init(void) { DynRegs[G_FLAGS].data=®_flags; DynRegs[G_FLAGS].flags=DYNFLG_LOAD|DYNFLG_SAVE; - DynRegs[G_SMASK].data=&cpu.stack.mask; - DynRegs[G_SMASK].flags=DYNFLG_LOAD|DYNFLG_SAVE; + DynRegs[G_NEWESP].data=&extra_regs.newesp; + DynRegs[G_NEWESP].flags=0; DynRegs[G_EIP].data=®_eip; DynRegs[G_EIP].flags=DYNFLG_LOAD|DYNFLG_SAVE; diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 19dc1a4d..e851d6c1 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -220,7 +220,6 @@ static void dyn_fill_blocks(void) { used_save_info=0; } -#ifdef CHECKED_MEMORY_ACCESS static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { gen_protectflags(); gen_call_function((void *)&mem_readb_checked_x86,"%Dd%Id",addr,&core_dyn.readdata); @@ -271,50 +270,13 @@ static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) { else gen_call_function((void *)&mem_writew_checked_x86,"%Ddr%Dd",addr,val); dyn_check_bool_exception_al(); } -#else -static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { - if (high) gen_call_function((void *)&mem_readb,"%Dd%Rh",addr,dst); - else gen_call_function((void *)&mem_readb,"%Dd%Rl",addr,dst); -} -static void dyn_write_byte(DynReg * addr,DynReg * val,Bitu high) { - if (high) gen_call_function((void *)&mem_writeb,"%Dd%Dh",addr,val); - else gen_call_function((void *)&mem_writeb,"%Dd%Dd",addr,val); -} -static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) { - if (dword) gen_call_function((void *)&mem_readd_dyncorex86,"%Dd%Rd",addr,dst); - else gen_call_function((void *)&mem_readw_dyncorex86,"%Dd%Rw",addr,dst); -} -static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { - if (dword) gen_call_function((void *)&mem_writed_dyncorex86,"%Dd%Dd",addr,val); - else gen_call_function((void *)&mem_writew_dyncorex86,"%Dd%Dd",addr,val); -} -static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) { - if (high) gen_call_function((void *)&mem_readb,"%Ddr%Rh",addr,dst); - else gen_call_function((void *)&mem_readb,"%Ddr%Rl",addr,dst); -} -static void dyn_write_byte_release(DynReg * addr,DynReg * val,Bitu high) { - if (high) gen_call_function((void *)&mem_writeb,"%Ddr%Dh",addr,val); - else gen_call_function((void *)&mem_writeb,"%Ddr%Dd",addr,val); -} -static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) { - if (dword) gen_call_function((void *)&mem_readd_dyncorex86,"%Ddr%Rd",addr,dst); - else gen_call_function((void *)&mem_readw_dyncorex86,"%Ddr%Rw",addr,dst); -} -static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) { - if (dword) gen_call_function((void *)&mem_writed_dyncorex86,"%Ddr%Dd",addr,val); - else gen_call_function((void *)&mem_writew_dyncorex86,"%Ddr%Dd",addr,val); -} -#endif static void dyn_push_unchecked(DynReg * dynreg) { gen_protectflags(); - if (decode.big_op) { - gen_dop_word_imm(DOP_SUB,true,DREG(ESP),4); - } else { - gen_dop_word_imm(DOP_SUB,true,DREG(ESP),2); - } - gen_dop_word(DOP_AND,true,DREG(ESP),DREG(SMASK)); - gen_dop_word(DOP_MOV,true,DREG(STACK),DREG(ESP)); + gen_lea(DREG(STACK),DREG(ESP),0,0,decode.big_op?(-4):(-2)); + gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask); + gen_dop_word_var(DOP_AND,true,DREG(ESP),&cpu.stack.notmask); + gen_dop_word(DOP_OR,true,DREG(ESP),DREG(STACK)); gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); if (decode.big_op) { gen_call_function((void *)&mem_writed,"%Drd%Dd",DREG(STACK),dynreg); @@ -326,13 +288,11 @@ static void dyn_push_unchecked(DynReg * dynreg) { static void dyn_push(DynReg * dynreg) { gen_protectflags(); - gen_dop_word(DOP_MOV,true,DREG(STACK),DREG(ESP)); - if (decode.big_op) { - gen_dop_word_imm(DOP_SUB,true,DREG(STACK),4); - } else { - gen_dop_word_imm(DOP_SUB,true,DREG(STACK),2); - } - gen_dop_word(DOP_AND,true,DREG(STACK),DREG(SMASK)); + gen_lea(DREG(STACK),DREG(ESP),0,0,decode.big_op?(-4):(-2)); + gen_dop_word(DOP_MOV,true,DREG(NEWESP),DREG(ESP)); + gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask); + gen_dop_word_var(DOP_AND,true,DREG(NEWESP),&cpu.stack.notmask); + gen_dop_word(DOP_OR,true,DREG(NEWESP),DREG(STACK)); gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); if (decode.big_op) { gen_call_function((void *)&mem_writed_checked_x86,"%Drd%Dd",DREG(STACK),dynreg); @@ -341,54 +301,36 @@ static void dyn_push(DynReg * dynreg) { gen_call_function((void *)&mem_writew_checked_x86,"%Drd%Dd",DREG(STACK),dynreg); } dyn_check_bool_exception_al(); - /* everything was ok, change registers now */ - if (decode.big_op) { - gen_dop_word_imm(DOP_SUB,true,DREG(ESP),4); - } else { - gen_dop_word_imm(DOP_SUB,true,DREG(ESP),2); - } - gen_dop_word(DOP_AND,true,DREG(ESP),DREG(SMASK)); + /* everything was ok, change register now */ + gen_dop_word(DOP_MOV,true,DREG(ESP),DREG(NEWESP)); + gen_releasereg(DREG(NEWESP)); } -static void dyn_pop_unchecked(DynReg * dynreg) { +static void dyn_pop(DynReg * dynreg,bool checked=true) { gen_protectflags(); gen_dop_word(DOP_MOV,true,DREG(STACK),DREG(ESP)); - gen_dop_word(DOP_AND,true,DREG(STACK),DREG(SMASK)); + gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask); gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); - if (decode.big_op) { - gen_call_function((void *)&mem_readd,"%Rd%Drd",dynreg,DREG(STACK)); + if (checked) { + if (decode.big_op) { + gen_call_function((void *)&mem_readd_checked_x86,"%Drd%Id",DREG(STACK),&core_dyn.readdata); + } else { + gen_call_function((void *)&mem_readw_checked_x86,"%Drd%Id",DREG(STACK),&core_dyn.readdata); + } + dyn_check_bool_exception_al(); + gen_mov_host(&core_dyn.readdata,dynreg,decode.big_op?4:2); } else { - gen_call_function((void *)&mem_readw,"%Rw%Drd",dynreg,DREG(STACK)); + if (decode.big_op) { + gen_call_function((void *)&mem_readd,"%Rd%Drd",dynreg,DREG(STACK)); + } else { + gen_call_function((void *)&mem_readw,"%Rw%Drd",dynreg,DREG(STACK)); + } } if (dynreg!=DREG(ESP)) { - if (decode.big_op) { - gen_dop_word_imm(DOP_ADD,true,DREG(ESP),4); - } else { - gen_dop_word_imm(DOP_ADD,true,DREG(ESP),2); - } - gen_dop_word(DOP_AND,true,DREG(ESP),DREG(SMASK)); - } -} - -static void dyn_pop(DynReg * dynreg) { - gen_protectflags(); - gen_dop_word(DOP_MOV,true,DREG(STACK),DREG(ESP)); - gen_dop_word(DOP_AND,true,DREG(STACK),DREG(SMASK)); - gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); - if (decode.big_op) { - gen_call_function((void *)&mem_readd_checked_x86,"%Drd%Id",DREG(STACK),&core_dyn.readdata); - } else { - gen_call_function((void *)&mem_readw_checked_x86,"%Drd%Id",DREG(STACK),&core_dyn.readdata); - } - dyn_check_bool_exception_al(); - gen_mov_host(&core_dyn.readdata,dynreg,decode.big_op?4:2); - if (dynreg!=DREG(ESP)) { - if (decode.big_op) { - gen_dop_word_imm(DOP_ADD,true,DREG(ESP),4); - } else { - gen_dop_word_imm(DOP_ADD,true,DREG(ESP),2); - } - gen_dop_word(DOP_AND,true,DREG(ESP),DREG(SMASK)); + gen_lea(DREG(STACK),DREG(ESP),0,0,decode.big_op?4:2); + gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask); + gen_dop_word_var(DOP_AND,true,DREG(ESP),&cpu.stack.notmask); + gen_dop_word(DOP_OR,true,DREG(ESP),DREG(STACK)); } } @@ -575,9 +517,7 @@ static void dyn_mov_ebib(void) { if (decode.modrm.mod<3) { dyn_fill_ea(); gen_call_write(DREG(EA),decode_fetchb(),1); -#ifdef CHECKED_MEMORY_ACCESS dyn_check_bool_exception_al(); -#endif } else { gen_dop_byte_imm(DOP_MOV,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,decode_fetchb()); } @@ -696,9 +636,7 @@ static void dyn_mov_eviv(void) { if (decode.modrm.mod<3) { dyn_fill_ea(); gen_call_write(DREG(EA),decode.big_op ? decode_fetchd() : decode_fetchw(),decode.big_op?4:2); -#ifdef CHECKED_MEMORY_ACCESS dyn_check_bool_exception_al(); -#endif } else { gen_dop_word_imm(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],decode.big_op ? decode_fetchd() : decode_fetchw()); } @@ -985,7 +923,6 @@ static void dyn_load_seg(SegNames seg,DynReg * src) { gen_releasereg(DREG(TMPB)); } else gen_call_function((void *)CPU_SetSegGeneral,"%Id%Drw",seg,src); gen_releasereg(&DynRegs[G_ES+seg]); - if (seg==ss) gen_releasereg(DREG(SMASK)); } static void dyn_load_seg_off_ea(SegNames seg) { @@ -1034,7 +971,6 @@ static void dyn_pop_seg(SegNames seg) { gen_releasereg(DREG(TMPB)); gen_releasereg(&DynRegs[G_ES+seg]); gen_releasereg(DREG(ESP)); - if (seg==ss) gen_releasereg(DREG(SMASK)); } } @@ -1062,13 +998,13 @@ static void dyn_enter(void) { static void dyn_leave(void) { gen_protectflags(); - gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(SMASK)); + gen_dop_word_var(DOP_MOV,true,DREG(TMPW),&cpu.stack.mask); gen_sop_word(SOP_NOT,true,DREG(TMPW)); gen_dop_word(DOP_AND,true,DREG(ESP),DREG(TMPW)); gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(EBP)); - gen_dop_word(DOP_AND,true,DREG(TMPW),DREG(SMASK)); + gen_dop_word_var(DOP_AND,true,DREG(TMPW),&cpu.stack.mask); gen_dop_word(DOP_OR,true,DREG(ESP),DREG(TMPW)); - dyn_pop_unchecked(DREG(EBP)); + dyn_pop(DREG(EBP),false); gen_releasereg(DREG(TMPW)); } @@ -1444,7 +1380,7 @@ restart_prefix: break; case 0x61: /* POPA */ for (i=G_EDI;i>=G_EAX;i--) { - dyn_pop_unchecked((i!=G_ESP) ? &DynRegs[i] : DREG(TMPW)); + dyn_pop((i!=G_ESP) ? &DynRegs[i] : DREG(TMPW),false); } gen_releasereg(DREG(TMPW)); break; @@ -1453,7 +1389,7 @@ restart_prefix: case 0x65:dyn_segprefix(gs);goto restart_prefix; //Push immediates //Operand size - case 0x66:decode.big_op=!cpu.code.big;;goto restart_prefix; + case 0x66:decode.big_op=!cpu.code.big;goto restart_prefix; //Address size case 0x67:decode.big_addr=!cpu.code.big;goto restart_prefix; case 0x68: /* PUSH Iv */ diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 7c9b5e3c..f3a809a3 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -457,6 +457,29 @@ finish: else cache_addw(imm); } +static void gen_dop_word_var(DualOps op,bool dword,DynReg * dr1,void* drd) { + GenReg * gr1=FindDynReg(dr1,dword && op==DOP_MOV); + Bit8u tmp; + switch (op) { + case DOP_ADD: tmp=0x03; break; + case DOP_ADC: tmp=0x13; break; + case DOP_SUB: tmp=0x2b; break; + case DOP_SBB: tmp=0x1b; break; + case DOP_CMP: tmp=0x3b; break; + case DOP_XOR: tmp=0x33; break; + case DOP_AND: tmp=0x23; break; + case DOP_OR: tmp=0x0b; break; + case DOP_TEST: tmp=0x85; break; + case DOP_MOV: tmp=0x8b; break; + case DOP_XCHG: tmp=0x87; break; + default: + IllegalOption("gen_dop_word_var"); + } + if (!dword) cache_addb(0x66); + cache_addw(tmp|(0x05+((gr1->index)<<3))<<8); + cache_addd((Bit32u)drd); +} + static void gen_imul_word(bool dword,DynReg * dr1,DynReg * dr2) { GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2); dr1->flags|=DYNFLG_CHANGED; @@ -728,21 +751,12 @@ static void gen_call_write(DynReg * dr,Bit32u val,Bitu write_size) { x86gen.regs[X86_REG_EDX]->Clear(); /* Do the actual call to the procedure */ cache_addb(0xe8); -#ifdef CHECKED_MEMORY_ACCESS switch (write_size) { case 1: cache_addd((Bit32u)mem_writeb_checked_x86 - (Bit32u)cache.pos-4); break; case 2: cache_addd((Bit32u)mem_writew_checked_x86 - (Bit32u)cache.pos-4); break; case 4: cache_addd((Bit32u)mem_writed_checked_x86 - (Bit32u)cache.pos-4); break; default: IllegalOption("gen_call_write"); } -#else - switch (write_size) { - case 1: cache_addd((Bit32u)mem_writeb - (Bit32u)cache.pos-4); break; - case 2: cache_addd((Bit32u)mem_writew_dyncorex86 - (Bit32u)cache.pos-4); break; - case 4: cache_addd((Bit32u)mem_writed_dyncorex86 - (Bit32u)cache.pos-4); break; - default: IllegalOption("gen_call_write"); - } -#endif cache_addw(0xc483); //ADD ESP,8 cache_addb(2*4); diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 51e2b575..abe57759 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.79 2006-02-26 16:11:00 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.80 2006-04-18 17:44:25 c2woody Exp $ */ #include #include "dosbox.h" @@ -90,26 +90,26 @@ void CPU_Core_Dyn_X86_Cache_Init(bool enable_cache); void CPU_Push16(Bitu value) { - Bit32u new_esp=(reg_esp&~cpu.stack.mask)|((reg_esp-2)&cpu.stack.mask); + Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-2)&cpu.stack.mask); mem_writew(SegPhys(ss) + (new_esp & cpu.stack.mask) ,value); reg_esp=new_esp; } void CPU_Push32(Bitu value) { - Bit32u new_esp=(reg_esp&~cpu.stack.mask)|((reg_esp-4)&cpu.stack.mask); + Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-4)&cpu.stack.mask); mem_writed(SegPhys(ss) + (new_esp & cpu.stack.mask) ,value); reg_esp=new_esp; } Bitu CPU_Pop16(void) { Bitu val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - reg_esp=(reg_esp&~cpu.stack.mask)|((reg_esp+2)&cpu.stack.mask); + reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+2)&cpu.stack.mask); return val; } Bitu CPU_Pop32(void) { Bitu val=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - reg_esp=(reg_esp&~cpu.stack.mask)|((reg_esp+4)&cpu.stack.mask); + reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+4)&cpu.stack.mask); return val; } @@ -409,11 +409,11 @@ doconforming: bool CPU_IO_Exception(Bitu port,Bitu size) { if (cpu.pmode && ((GETFLAG_IOPLcpu_tss.limit) goto doexception; - where=cpu_tss.base+ofs+(port/8); - Bitu map=mem_readw(where); + bwhere=cpu_tss.base+ofs+(port/8); + Bitu map=mem_readw(bwhere); Bitu mask=(0xffff>>(16-size)) << (port&7); if (map & mask) goto doexception; } @@ -552,10 +552,12 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { if (n_ss_desc.Big()) { cpu.stack.big=true; cpu.stack.mask=0xffffffff; + cpu.stack.notmask=0; reg_esp=n_esp; } else { cpu.stack.big=false; cpu.stack.mask=0xffff; + cpu.stack.notmask=0xffff0000; reg_sp=n_esp & 0xffff; } @@ -814,10 +816,12 @@ void CPU_IRET(bool use32,Bitu oldeip) { if (n_ss_desc.Big()) { cpu.stack.big=true; cpu.stack.mask=0xffffffff; + cpu.stack.notmask=0; reg_esp=n_esp; } else { cpu.stack.big=false; cpu.stack.mask=0xffff; + cpu.stack.notmask=0xffff0000; reg_sp=n_esp & 0xffff; } @@ -1070,10 +1074,12 @@ call_code: if (n_ss_desc.Big()) { cpu.stack.big=true; cpu.stack.mask=0xffffffff; + cpu.stack.notmask=0; reg_esp=n_esp; } else { cpu.stack.big=false; cpu.stack.mask=0xffff; + cpu.stack.notmask=0xffff0000; reg_sp=n_esp & 0xffff; } @@ -1303,10 +1309,12 @@ RET_same_level: if (n_ss_desc.Big()) { cpu.stack.big=true; cpu.stack.mask=0xffffffff; + cpu.stack.notmask=0; reg_esp=n_esp+bytes; } else { cpu.stack.big=false; cpu.stack.mask=0xffff; + cpu.stack.notmask=0xffff0000; reg_sp=(n_esp & 0xffff)+bytes; } @@ -1712,6 +1720,7 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) { if (seg==ss) { cpu.stack.big=false; cpu.stack.mask=0xffff; + cpu.stack.notmask=0xffff0000; } return false; } else { @@ -1750,9 +1759,11 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) { if (desc.Big()) { cpu.stack.big=true; cpu.stack.mask=0xffffffff; + cpu.stack.notmask=0; } else { cpu.stack.big=false; cpu.stack.mask=0xffff; + cpu.stack.notmask=0xffff0000; } } else { if ((value & 0xfffc)==0) { @@ -1799,7 +1810,7 @@ bool CPU_PopSeg(SegNames seg,bool use32) { Bitu val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); if (CPU_SetSegGeneral(seg,val)) return true; Bitu addsp=use32?0x04:0x02; - reg_esp=(reg_esp&~cpu.stack.mask)|((reg_esp+addsp)&cpu.stack.mask); + reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+addsp)&cpu.stack.mask); return false; } @@ -1872,7 +1883,7 @@ void CPU_ENTER(bool use32,Bitu bytes,Bitu level) { } } sp_index-=bytes; - reg_esp=(reg_esp&~cpu.stack.mask)|((sp_index)&cpu.stack.mask); + reg_esp=(reg_esp&cpu.stack.notmask)|((sp_index)&cpu.stack.mask); } extern void GFX_SetTitle(Bits cycles ,Bits frameskip,bool paused); @@ -1938,6 +1949,7 @@ public: CPU_SET_CRX(0,0); //Initialize cpu.code.big=false; cpu.stack.mask=0xffff; + cpu.stack.notmask=0xffff0000; cpu.stack.big=false; cpu.idt.SetBase(0); cpu.idt.SetLimit(1023); From b43c3d6643156d897b12a3757fbbacdc74782264 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 21 Apr 2006 08:18:51 +0000 Subject: [PATCH 2522/4131] Rewrite Choice a bit. So that it honours /S and that the : is optional. Fixes Ishar Triology Installer/Startup menu Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2607 --- src/shell/shell_cmds.cpp | 50 ++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 308b4439..2df385fe 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.63 2006-04-10 12:06:07 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.64 2006-04-21 08:18:51 qbix79 Exp $ */ #include #include @@ -212,7 +212,7 @@ void DOS_Shell::CMD_ECHO(char * args){ } char buffer[512]; char* pbuffer = buffer; - strcpy(buffer,args); + safe_strncpy(buffer,args,512); StripSpaces(pbuffer); if (strcasecmp(pbuffer,"OFF")==0) { echo=false; @@ -780,38 +780,54 @@ void DOS_Shell::CMD_LOADHIGH(char *args){ } void DOS_Shell::CMD_CHOICE(char * args){ - static char defargs[] = "[YN]"; - static char defchoice[] = "yn"; + static char defchoice[3] = {'Y','N',0}; char *rem = NULL, *ptr; - bool optN = false; + bool optN = ScanCMDBool(args,"N"); + bool optS = ScanCMDBool(args,"S"); //Case-sensitive matching + ScanCMDBool(args,"T"); //Default Choice after timeout if (args) { char *last = strchr(args,0); StripSpaces(args); - optN=ScanCMDBool(args,"N"); - rem=ScanCMDRemain(args); - if (rem && *rem && (tolower(rem[1]) != 'c' || rem[2] != ':')) { + rem = ScanCMDRemain(args); + if (rem && *rem && (tolower(rem[1]) != 'c')) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); return; } if (args == rem) args = strchr(rem,0)+1; - if (rem) rem += 3; + if (rem) rem += 2; + if(rem && rem[0]==':') rem++; /* optional : after /c */ if (args > last) args = NULL; } - if (!args || !*args) args = defargs; - if (!rem || !*rem) rem = defchoice; + if (!rem || !*rem) rem = defchoice; /* No choices specified use YN */ ptr = rem; Bit8u c; - while ((c = *ptr)) *ptr++ = tolower(c); + if(!optS) while ((c = *ptr)) *ptr++ = toupper(c); /* When in no case-sensitive mode. make everything upcase */ + if(args && *args ) { + StripSpaces(args); + size_t argslen = strlen(args); + if(argslen>1 && args[0] == '"' && args[argslen-1] =='"') { + args[argslen-1] = 0; //Remove quotes + args++; + } + WriteOut(args); + } + /* Show question prompt of the form [a,b]? where a b are the choice values */ + if (!optN) { + if(args && *args) WriteOut(" "); + WriteOut("["); + size_t len = strlen(rem); + for(size_t t = 1; t < len; t++) { + WriteOut("%c,",rem[t-1]); + } + WriteOut("%c]?",rem[len-1]); + } - WriteOut(args); - if (!optN) WriteOut("\r\n"); Bit16u n=1; do { DOS_ReadFile (STDIN,&c,&n); - } while (!c || !(ptr = strchr(rem,tolower(c)))); - if (optN) { + } while (!c || !(ptr = strchr(rem,(optS?c:toupper(c))))); + if (!optN) { //Echo typed value ? not sure actually perhaps depend on echo DOS_WriteFile (STDOUT,&c, &n); - WriteOut("\r\n"); } dos.return_code = ptr-rem+1; } From 632f57936135b379f014ed8ec6490e77c43fe38a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 21 Apr 2006 08:23:40 +0000 Subject: [PATCH 2523/4131] Add a trick for Ishar 3 of the Ishar 3 Triology. File reads and writes take actually cycles now.(4 times the amount of transfered data) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2608 --- src/dos/dos.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index fa32a395..fc4c243e 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.93 2006-03-08 15:57:23 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.94 2006-04-21 08:23:40 qbix79 Exp $ */ #include #include @@ -41,6 +41,18 @@ void DOS_SetError(Bit16u code) { dos.errorcode=code; } +#define DATA_TRANSFERS_TAKE_CYCLES 1 +#ifdef DATA_TRANSFERS_TAKE_CYCLES +#include "cpu.h" +static inline void modify_cycles(Bitu value) { + if((4*value+5) < CPU_Cycles) CPU_Cycles -= 4*value; else CPU_Cycles = 5; +} +#else +static inline void modify_cycles(Bitu /* value */) { + return; +} +#endif + #define DOSNAMEBUF 256 static Bitu DOS_21Handler(void) { if (((reg_ah != 0x50) && (reg_ah != 0x51) && (reg_ah != 0x62) && (reg_ah != 0x64)) && (reg_ah<0x6c)) { @@ -499,6 +511,7 @@ static Bitu DOS_21Handler(void) { reg_ax=dos.errorcode; CALLBACK_SCF(true); } + modify_cycles(reg_ax); dos.echo=false; break; } @@ -513,6 +526,7 @@ static Bitu DOS_21Handler(void) { reg_ax=dos.errorcode; CALLBACK_SCF(true); } + modify_cycles(reg_ax); break; }; case 0x41: /* UNLINK Delete file */ From 4d33692c6f2c9355ffa53b6da203ed9ab2090a50 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 21 Apr 2006 08:35:31 +0000 Subject: [PATCH 2524/4131] Add the CDROM device in the device chain. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2609 --- src/dos/dos_mscdex.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 70c5d93f..0bf8fffa 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.41 2006-04-17 20:06:39 c2woody Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.42 2006-04-21 08:35:31 qbix79 Exp $ */ #include #include @@ -208,10 +208,22 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) Bit16u seg = DOS_GetMemory(driverSize/16+((driverSize%16)>0)); DOS_DeviceHeader devHeader(PhysMake(seg,0)); devHeader.SetNextDeviceHeader (0xFFFFFFFF); + devHeader.SetAttribute(0xc800); devHeader.SetDriveLetter (_drive+1); devHeader.SetNumSubUnits (1); devHeader.SetName ("MSCD001 "); + //Link it in the device chain + Bit32u start = dos_infoblock.GetDeviceChain(); + Bit16u segm = start>>16; + Bit16u offm = start&0xFFFF; + while(start != 0xFFFFFFFF) { + segm = start>>16; + offm = start&0xFFFF; + start = real_readd(segm,offm); + } + real_writed(segm,offm,seg<<16); + // Create Callback Strategy Bit16u off = sizeof(DOS_DeviceHeader::sDeviceHeader); Bitu call_strategy=CALLBACK_Allocate(); @@ -888,6 +900,8 @@ static Bit16u MSCDEX_IOCTL_Optput(PhysPt buffer,Bit8u drive_unit) { case 0x00 : // Unload /eject media if (!mscdex->LoadUnloadMedia(drive_unit,true)) return 0x02; break; + case 0x03: //Audio Channel control + MSCDEX_LOG("MSCDEX: Audio Channel Control used. Not handled. Faking succes!"); case 0x01 : // (un)Lock door // do nothing -> report as success break; From 8a10d6f33bca9d68a1acd52c6f2c0e92a07df275 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 21 Apr 2006 08:50:30 +0000 Subject: [PATCH 2525/4131] Whoops add all changes to it. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2610 --- include/dos_inc.h | 3 ++- src/dos/dos_classes.cpp | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 0d093c5f..1da5cdad 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.59 2006-02-09 11:47:47 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.60 2006-04-21 08:50:30 qbix79 Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -367,6 +367,7 @@ public: Bit16u GetStartOfUMBChain(void); Bit8u GetUMBChainState(void); RealPt GetPointer(void); + Bit32u GetDeviceChain(void); #ifdef _MSC_VER #pragma pack(1) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 40a9687c..a629969d 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.47 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.48 2006-04-21 08:50:30 qbix79 Exp $ */ #include #include @@ -168,13 +168,16 @@ RealPt DOS_InfoBlock::GetPointer(void) { return RealMake(seg,offsetof(sDIB,firstDPB)); } +Bit32u DOS_InfoBlock::GetDeviceChain(void) { + return sGet(sDIB,nulNextDriver); +} + /* program Segment prefix */ Bit16u DOS_PSP::rootpsp = 0; -void DOS_PSP::MakeNew(Bit16u mem_size) -{ +void DOS_PSP::MakeNew(Bit16u mem_size) { /* get previous */ DOS_PSP prevpsp(dos.psp()); /* Clear it first */ From 1d11c37e2380017690d41f7fcce632275cb93f1b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 21 Apr 2006 13:21:09 +0000 Subject: [PATCH 2526/4131] make default choice lowcase so case-sensitive matching shows a more reasanable number.(ykhwong) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2611 --- src/shell/shell_cmds.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 2df385fe..86289e9f 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.64 2006-04-21 08:18:51 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.65 2006-04-21 13:21:09 qbix79 Exp $ */ #include #include @@ -780,7 +780,7 @@ void DOS_Shell::CMD_LOADHIGH(char *args){ } void DOS_Shell::CMD_CHOICE(char * args){ - static char defchoice[3] = {'Y','N',0}; + static char defchoice[3] = {'y','n',0}; char *rem = NULL, *ptr; bool optN = ScanCMDBool(args,"N"); bool optS = ScanCMDBool(args,"S"); //Case-sensitive matching From 1d89346c1604cf7b8605c17136f65d53f5a2c78d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 22 Apr 2006 15:25:45 +0000 Subject: [PATCH 2527/4131] move callbacks into read-only memory (Pinball/Adventure construction kit booters) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2612 --- include/callback.h | 15 +++--- src/cpu/callback.cpp | 102 +++++++++++++++++++++++++--------------- src/ints/bios.cpp | 15 +----- src/ints/bios_disk.cpp | 38 ++++++++------- src/ints/ems.cpp | 25 +++++----- src/ints/int10_vesa.cpp | 11 ++--- src/ints/mouse.cpp | 46 +++++------------- src/ints/xms.cpp | 19 ++------ 8 files changed, 131 insertions(+), 140 deletions(-) diff --git a/include/callback.h b/include/callback.h index 85b9d246..dab0609d 100644 --- a/include/callback.h +++ b/include/callback.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.h,v 1.16 2006-02-09 11:47:47 qbix79 Exp $ */ +/* $Id: callback.h,v 1.17 2006-04-22 15:25:44 c2woody Exp $ */ #ifndef DOSBOX_CALLBACK_H #define DOSBOX_CALLBACK_H @@ -28,10 +28,10 @@ typedef Bitu (*CallBack_Handler)(void); extern CallBack_Handler CallBack_Handlers[]; -enum { CB_RETN, CB_RETF,CB_IRET,CB_IRET_STI }; +enum { CB_RETN,CB_RETF,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1,CB_HOOKABLE }; #define CB_MAX 144 -#define CB_SEG 0xC800 +#define CB_SEG 0xF100 #define CB_BASE (CB_SEG << 4) enum { @@ -42,6 +42,9 @@ extern Bit8u lastint; INLINE RealPt CALLBACK_RealPointer(Bitu callback) { return RealMake(CB_SEG,callback << 4); } +INLINE PhysPt CALLBACK_PhysPointer(Bitu callback) { + return PhysMake(CB_SEG,callback << 4); +} Bitu CALLBACK_Allocate(); @@ -52,8 +55,7 @@ void CALLBACK_RunRealInt(Bit8u intnum); void CALLBACK_RunRealFar(Bit16u seg,Bit16u off); bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* description=0); -/* Returns with the size of the extra callback */ -Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress); +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); @@ -78,7 +80,8 @@ 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=0); + 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;} diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 91f13f49..e4900460 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.31 2006-02-12 23:28:21 harekiet Exp $ */ +/* $Id: callback.cpp,v 1.32 2006-04-22 15:25:44 c2woody Exp $ */ #include #include @@ -133,42 +133,6 @@ const char* CALLBACK_GetDescription(Bitu nr) { return CallBack_Description[nr]; }; -bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* descr) { - if (callback>=CB_MAX) return false; - switch (type) { - case CB_RETF: - phys_writeb(CB_BASE+(callback<<4)+0,(Bit8u)0xFE); //GRP 4 - phys_writeb(CB_BASE+(callback<<4)+1,(Bit8u)0x38); //Extra Callback instruction - phys_writew(CB_BASE+(callback<<4)+2,callback); //The immediate word - phys_writeb(CB_BASE+(callback<<4)+4,(Bit8u)0xCB); //A RETF Instruction - break; - case CB_IRET: - phys_writeb(CB_BASE+(callback<<4)+0,(Bit8u)0xFE); //GRP 4 - phys_writeb(CB_BASE+(callback<<4)+1,(Bit8u)0x38); //Extra Callback instruction - phys_writew(CB_BASE+(callback<<4)+2,callback); //The immediate word - phys_writeb(CB_BASE+(callback<<4)+4,(Bit8u)0xCF); //An IRET Instruction - break; - case CB_IRET_STI: - phys_writeb(CB_BASE+(callback<<4)+0,(Bit8u)0xFB); //STI - phys_writeb(CB_BASE+(callback<<4)+1,(Bit8u)0xFE); //GRP 4 - phys_writeb(CB_BASE+(callback<<4)+2,(Bit8u)0x38); //Extra Callback instruction - phys_writew(CB_BASE+(callback<<4)+3,callback); //The immediate word - phys_writeb(CB_BASE+(callback<<4)+5,(Bit8u)0xCF); //An IRET Instruction - break; - default: - E_Exit("CALLBACK:Setup:Illegal type %d",type); - } - CallBack_Handlers[callback]=handler; - CALLBACK_SetDescription(callback,descr); - return true; -} - -void CALLBACK_RemoveSetup(Bitu callback) { - for (Bitu i = 0;i < 16;i++) { - phys_writeb(CB_BASE+(callback<<4)+i ,(Bit8u) 0x00); - } -} - Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress) { if (callback>=CB_MAX) return 0; @@ -191,6 +155,13 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress) { phys_writew(physAddress+2,callback); //The immediate word phys_writeb(physAddress+4,(Bit8u)0xCF); //An IRET Instruction return 5; + case CB_IRETD: + phys_writeb(physAddress+0,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+1,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+2,callback); //The immediate word + phys_writeb(physAddress+4,(Bit8u)0x66); //An IRETD Instruction + phys_writeb(physAddress+5,(Bit8u)0xCF); + return 6; case CB_IRET_STI: phys_writeb(physAddress+0,(Bit8u)0xFB); //STI phys_writeb(physAddress+1,(Bit8u)0xFE); //GRP 4 @@ -198,12 +169,59 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress) { phys_writew(physAddress+3, callback); //The immediate word phys_writeb(physAddress+5,(Bit8u)0xCF); //An IRET Instruction return 6; + case CB_IRET_EOI_PIC1: + phys_writeb(physAddress+0,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+1,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+2,callback); //The immediate word + phys_writeb(physAddress+4,(Bit8u)0x50); // push ax + phys_writeb(physAddress+5,(Bit8u)0xb0); // mov al, 0x20 + phys_writeb(physAddress+6,(Bit8u)0x20); + phys_writeb(physAddress+7,(Bit8u)0xe6); // out 0x20, al + phys_writeb(physAddress+8,(Bit8u)0x20); + phys_writeb(physAddress+9,(Bit8u)0x58); // pop ax + phys_writeb(physAddress+10,(Bit8u)0xcf);//An IRET Instruction + return 11; + case CB_HOOKABLE: + phys_writeb(physAddress+0,(Bit8u)0xEB); //jump near + phys_writeb(physAddress+1,(Bit8u)0x03); //offset + phys_writeb(physAddress+2,(Bit8u)0x90); //NOP + phys_writeb(physAddress+3,(Bit8u)0x90); //NOP + phys_writeb(physAddress+4,(Bit8u)0x90); //NOP + phys_writeb(physAddress+5,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+6,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+7,callback); //The immediate word + phys_writeb(physAddress+9,(Bit8u)0xCB); //A RETF Instruction + return 10; default: 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,CB_BASE+(callback<<4)+0); + CallBack_Handlers[callback]=handler; + CALLBACK_SetDescription(callback,descr); + return true; +} + +Bitu CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,PhysPt addr,const char* descr) { + if (callback>=CB_MAX) return 0; + Bitu csize=CALLBACK_SetupExtra(callback,type,addr); + 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(CB_BASE+(callback<<4)+i ,(Bit8u) 0x00); + } +} + CALLBACK_HandlerObject::~CALLBACK_HandlerObject(){ if(!installed) return; if(m_type == CALLBACK_HandlerObject::SETUP) { @@ -233,6 +251,14 @@ void CALLBACK_HandlerObject::Install(CallBack_Handler handler,Bitu type,const ch 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; @@ -291,7 +317,9 @@ void CALLBACK_Init(Section* sec) { rint_base+=6; } + // setup a few interrupt handlers that point to bios IRETs by default 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 diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 506494e0..15185c96 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.57 2006-02-09 11:47:55 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.58 2006-04-22 15:25:45 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -818,19 +818,8 @@ public: /* INT 8 Clock IRQ Handler */ //TODO Maybe give this a special callback that will also call int 8 instead of starting //a new system - callback[0].Install(INT8_Handler,CB_IRET,"Int 8 Clock"); + callback[0].Install(INT8_Handler,CB_IRET_EOI_PIC1,"Int 8 Clock"); callback[0].Set_RealVec(0x8); - Bit16u call_int8=callback[0].Get_callback(); - phys_writeb(CB_BASE+(call_int8<<4)+0,(Bit8u)0xFE); //GRP 4 - phys_writeb(CB_BASE+(call_int8<<4)+1,(Bit8u)0x38); //Extra Callback instruction - phys_writew(CB_BASE+(call_int8<<4)+2,call_int8); //The immediate word - phys_writeb(CB_BASE+(call_int8<<4)+4,(Bit8u)0x50); // push ax - phys_writeb(CB_BASE+(call_int8<<4)+5,(Bit8u)0xb0); // mov al, 0x20 - phys_writeb(CB_BASE+(call_int8<<4)+6,(Bit8u)0x20); - phys_writeb(CB_BASE+(call_int8<<4)+7,(Bit8u)0xe6); // out 0x20, al - phys_writeb(CB_BASE+(call_int8<<4)+8,(Bit8u)0x20); - phys_writeb(CB_BASE+(call_int8<<4)+9,(Bit8u)0x58); // pop ax - phys_writeb(CB_BASE+(call_int8<<4)+10,(Bit8u)0xcf); // iret mem_writed(BIOS_TIMER,0); //Calculate the correct time diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 90c76b8d..3c2f2695 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.28 2006-04-09 13:03:24 c2woody Exp $ */ +/* $Id: bios_disk.cpp,v 1.29 2006-04-22 15:25:45 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" @@ -63,24 +63,26 @@ Bits swapPosition; void updateDPT(void) { Bit32u tmpheads, tmpcyl, tmpsect, tmpsize; if(imageDiskList[2] != NULL) { + PhysPt dp0physaddr=CALLBACK_PhysPointer(diskparm0); imageDiskList[2]->Get_Geometry(&tmpheads, &tmpcyl, &tmpsect, &tmpsize); - real_writew(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0)),tmpcyl); - real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+2,tmpheads); - real_writew(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0x3,0); - real_writew(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0x5,(Bit16u)-1); - real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0x7,0); - real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0x8,(0xc0 | (((imageDiskList[2]->heads) > 8) << 3))); - real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0x9,0); - real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0xa,0); - real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0xb,0); - real_writew(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0xc,tmpcyl); - real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+0xe,tmpsect); + phys_writew(dp0physaddr,tmpcyl); + phys_writeb(dp0physaddr+0x2,tmpheads); + phys_writew(dp0physaddr+0x3,0); + phys_writew(dp0physaddr+0x5,(Bit16u)-1); + phys_writeb(dp0physaddr+0x7,0); + phys_writeb(dp0physaddr+0x8,(0xc0 | (((imageDiskList[2]->heads) > 8) << 3))); + phys_writeb(dp0physaddr+0x9,0); + phys_writeb(dp0physaddr+0xa,0); + phys_writeb(dp0physaddr+0xb,0); + phys_writew(dp0physaddr+0xc,tmpcyl); + phys_writeb(dp0physaddr+0xe,tmpsect); } if(imageDiskList[3] != NULL) { + PhysPt dp1physaddr=CALLBACK_PhysPointer(diskparm1); imageDiskList[3]->Get_Geometry(&tmpheads, &tmpcyl, &tmpsect, &tmpsize); - real_writew(RealSeg(CALLBACK_RealPointer(diskparm1)),RealOff(CALLBACK_RealPointer(diskparm1)),tmpcyl); - real_writeb(RealSeg(CALLBACK_RealPointer(diskparm1)),RealOff(CALLBACK_RealPointer(diskparm1))+2,tmpheads); - real_writeb(RealSeg(CALLBACK_RealPointer(diskparm1)),RealOff(CALLBACK_RealPointer(diskparm1))+0xe,tmpsect); + phys_writew(dp1physaddr,tmpcyl); + phys_writeb(dp1physaddr+0x2,tmpheads); + phys_writeb(dp1physaddr+0xe,tmpsect); } } @@ -488,9 +490,11 @@ void BIOS_SetupDisks(void) { RealSetVec(0x41,CALLBACK_RealPointer(diskparm0)); RealSetVec(0x46,CALLBACK_RealPointer(diskparm1)); + PhysPt dp0physaddr=CALLBACK_PhysPointer(diskparm0); + PhysPt dp1physaddr=CALLBACK_PhysPointer(diskparm1); for(i=0;i<16;i++) { - real_writeb(RealSeg(CALLBACK_RealPointer(diskparm0)),RealOff(CALLBACK_RealPointer(diskparm0))+i,0); - real_writeb(RealSeg(CALLBACK_RealPointer(diskparm1)),RealOff(CALLBACK_RealPointer(diskparm1))+i,0); + phys_writeb(dp0physaddr+i,0); + phys_writeb(dp1physaddr+i,0); } imgDTASeg = 0; diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 0ae57537..1493b3d6 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.50 2006-04-18 13:52:24 qbix79 Exp $ */ +/* $Id: ems.cpp,v 1.51 2006-04-22 15:25:45 c2woody Exp $ */ #include #include @@ -721,12 +721,17 @@ static Bitu INT67_Handler(void) { reg_di+=0x400; // advance pointer by 0x100*4 /* Set up three descriptor table entries */ - real_writed(SegValue(ds),reg_si+0x00,0x8000ffff); // descriptor 1 (code segment) - real_writed(SegValue(ds),reg_si+0x04,0x00009a0c); // descriptor 1 - real_writed(SegValue(ds),reg_si+0x08,0x0000ffff); // descriptor 2 (data segment) - real_writed(SegValue(ds),reg_si+0x0c,0x00009200); // descriptor 2 - real_writed(SegValue(ds),reg_si+0x10,0x0000ffff); // descriptor 3 - real_writed(SegValue(ds),reg_si+0x14,0x00009200); // descriptor 3 + Bit32u cbseg_low=(CB_BASE&0xffff)<<16; + Bit32u cbseg_high=(CB_BASE&0x1f0000)>>16; + /* Descriptor 1 (code segment, callback segment) */ + real_writed(SegValue(ds),reg_si+0x00,0x0000ffff|cbseg_low); + real_writed(SegValue(ds),reg_si+0x04,0x00009a00|cbseg_high); + /* Descriptor 2 (data segment, full access) */ + real_writed(SegValue(ds),reg_si+0x08,0x0000ffff); + real_writed(SegValue(ds),reg_si+0x0c,0x00009200); + /* Descriptor 3 (full access) */ + real_writed(SegValue(ds),reg_si+0x10,0x0000ffff); + real_writed(SegValue(ds),reg_si+0x14,0x00009200); reg_ebx=(vcpi.pm_interface&0xffff); reg_ah=EMM_NO_ERROR; @@ -1185,13 +1190,9 @@ public: if (!ENABLE_VCPI) return; /* Install a callback that handles VCPI-requests in protected mode requests */ - call_vcpi.Install(&VCPI_PM_Handler,CB_RETF,"VCPI PM"); + call_vcpi.Install(&VCPI_PM_Handler,CB_IRETD,"VCPI PM"); vcpi.pm_interface=(call_vcpi.Get_callback())<<4; - /* Use IRETD instead of IRET for this protected mode callback */ - mem_writeb(CB_BASE+vcpi.pm_interface+4,(Bit8u)0x66); - mem_writeb(CB_BASE+vcpi.pm_interface+5,(Bit8u)0xCB); //A IRETD Instruction - /* Initialize private data area and set up descriptor tables */ SetupVCPI(); diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 0330efa2..43792237 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.23 2006-02-12 23:06:15 harekiet Exp $ */ +/* $Id: int10_vesa.cpp,v 1.24 2006-04-22 15:25:45 c2woody Exp $ */ #include #include @@ -443,20 +443,17 @@ void INT10_SetupVESA(void) { int10.rom.pmode_interface_window = int10.rom.used - RealOff( int10.rom.pmode_interface ); phys_writew( Real2Phys(int10.rom.pmode_interface) + 0, int10.rom.pmode_interface_window ); callback.pmWindow=CALLBACK_Allocate(); - CALLBACK_Setup(callback.pmWindow, VESA_PMSetWindow, CB_RETF, "VESA PM Set Window"); - int10.rom.used += CALLBACK_SetupExtra( callback.pmWindow, CB_RETN, PhysMake(0xc000,int10.rom.used)); + int10.rom.used += CALLBACK_Setup(callback.pmWindow, VESA_PMSetWindow, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Window"); /* PM Set start call */ int10.rom.pmode_interface_start = int10.rom.used - RealOff( int10.rom.pmode_interface ); phys_writew( Real2Phys(int10.rom.pmode_interface) + 2, int10.rom.pmode_interface_start); callback.pmStart=CALLBACK_Allocate(); - CALLBACK_Setup(callback.pmStart, VESA_PMSetStart, CB_RETF, "VESA PM Set Start"); - int10.rom.used += CALLBACK_SetupExtra( callback.pmStart, CB_RETN, PhysMake(0xc000,int10.rom.used)); + int10.rom.used += CALLBACK_Setup(callback.pmStart, VESA_PMSetStart, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Start"); /* PM Set Palette call */ int10.rom.pmode_interface_palette = int10.rom.used - RealOff( int10.rom.pmode_interface ); phys_writew( Real2Phys(int10.rom.pmode_interface) + 4, int10.rom.pmode_interface_palette); callback.pmPalette=CALLBACK_Allocate(); - CALLBACK_Setup(callback.pmPalette, VESA_PMSetPalette, CB_RETF, "VESA PM Set Palette"); - int10.rom.used += CALLBACK_SetupExtra( callback.pmPalette, CB_RETN, PhysMake(0xc000,int10.rom.used)); + int10.rom.used += CALLBACK_Setup(callback.pmPalette, VESA_PMSetPalette, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Palette"); /* Finalize the size and clear the required ports pointer */ phys_writew( Real2Phys(int10.rom.pmode_interface) + 6, 0); int10.rom.pmode_interface_size=int10.rom.used - RealOff( int10.rom.pmode_interface ); diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index f0639d5d..257b85c9 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.61 2006-02-13 07:48:25 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.62 2006-04-22 15:25:45 c2woody Exp $ */ #include #include @@ -905,46 +905,26 @@ static Bitu INT74_Handler(void) { return CBRET_NONE; } -void WriteMouseIntVector(void) -{ - // Create a mouse vector with weird address - // for strange mouse detection routines in Sim City & Wasteland - real_writed(0,0x33<<2,RealMake(CB_SEG+1,(call_int33<<4)-0x10+1)); // +1 = Skip NOP -}; - -void CreateMouseCallback(void) -{ - // Create callback - call_int33=CALLBACK_Allocate(); - CALLBACK_Setup(call_int33,&INT33_Handler,CB_IRET,"Mouse"); - - // Create a mouse vector with weird address - // for strange mouse detection routines in Sim City & Wasteland - Bit16u ofs = call_int33<<4; - phys_writeb(CB_BASE+ofs+0,(Bit8u)0x90); //NOP - phys_writeb(CB_BASE+ofs+1,(Bit8u)0xFE); //GRP 4 - phys_writeb(CB_BASE+ofs+2,(Bit8u)0x38); //Extra Callback instruction - phys_writew(CB_BASE+ofs+3,call_int33); //The immediate word - phys_writeb(CB_BASE+ofs+5,(Bit8u)0xCF); //An IRET Instruction - // Write weird vector - WriteMouseIntVector(); -}; - void MOUSE_Init(Section* sec) { - // Callback 0x33 - CreateMouseCallback(); + // Callback for mouse interrupt 0x33 + call_int33=CALLBACK_Allocate(); + CALLBACK_Setup(call_int33,&INT33_Handler,CB_IRET,"Mouse"); + // Wasteland needs low(seg(int33))!=0 and low(ofs(int33))!=0 + real_writed(0,0x33<<2,RealMake(CB_SEG+1,(call_int33<<4)-0x10)); + + // Callback for ps2 irq call_int74=CALLBACK_Allocate(); CALLBACK_Setup(call_int74,&INT74_Handler,CB_IRET,"int 74"); - if(MOUSE_IRQ > 7) { - real_writed(0,((0x70+MOUSE_IRQ-8)<<2),CALLBACK_RealPointer(call_int74)); - } else { - real_writed(0,((0x8+MOUSE_IRQ)<<2),CALLBACK_RealPointer(call_int74)); - } + Bit8u hwvec=(MOUSE_IRQ>7)?(0x70+MOUSE_IRQ-8):(0x8+MOUSE_IRQ); + RealSetVec(hwvec,CALLBACK_RealPointer(call_int74)); + + // Callback for ps2 user callback handling useps2callback = false; ps2callbackinit = false; call_ps2=CALLBACK_Allocate(); CALLBACK_Setup(call_ps2,&PS2_Handler,CB_IRET,"ps2 bios callback"); ps2_callback=CALLBACK_RealPointer(call_ps2); + memset(&mouse,0,sizeof(mouse)); mouse.shown=-1; //Hide mouse on startup mouse_reset_hardware(); diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 3e367bbf..8dca90ce 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.40 2006-04-14 13:53:58 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.41 2006-04-22 15:25:45 c2woody Exp $ */ #include #include @@ -413,20 +413,9 @@ public: Bitu i; BIOS_ZeroExtendedSize(true); DOS_AddMultiplexHandler(multiplex_xms); - callbackhandler.Install(&XMS_Handler,CB_RETF, "XMS Handler"); - xms_callback=callbackhandler.Get_RealPointer(); - Bit16u call_xms=callbackhandler.Get_callback(); - - /* Override the callback with one that can be hooked */ - phys_writeb(CB_BASE+(call_xms<<4)+0,(Bit8u)0xeb); //jump near - phys_writeb(CB_BASE+(call_xms<<4)+1,(Bit8u)0x03); //offset - phys_writeb(CB_BASE+(call_xms<<4)+2,(Bit8u)0x90); //NOP - phys_writeb(CB_BASE+(call_xms<<4)+3,(Bit8u)0x90); //NOP - phys_writeb(CB_BASE+(call_xms<<4)+4,(Bit8u)0x90); //NOP - phys_writeb(CB_BASE+(call_xms<<4)+5,(Bit8u)0xFE); //GRP 4 - phys_writeb(CB_BASE+(call_xms<<4)+6,(Bit8u)0x38); //Extra Callback instruction - phys_writew(CB_BASE+(call_xms<<4)+7,call_xms); //The immediate word - phys_writeb(CB_BASE+(call_xms<<4)+9,(Bit8u)0xCB); //A RETF Instruction + /* place hookable callback in writable memory area */ + xms_callback=RealMake(DOS_GetMemory(0x1),0); + callbackhandler.Install(&XMS_Handler,CB_HOOKABLE,Real2Phys(xms_callback),"XMS Handler"); for (i=0;i Date: Sat, 22 Apr 2006 20:12:39 +0000 Subject: [PATCH 2528/4131] Change default search path for SDL_sound. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2613 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 00cc1f8b..119c00b4 100644 --- a/configure.in +++ b/configure.in @@ -254,7 +254,7 @@ else fi AH_TEMPLATE(C_SDL_SOUND,[Define to 1 to enable SDL_sound support]) -AC_CHECK_HEADER(SDL/SDL_sound.h,have_SDL_sound_h=yes,) +AC_CHECK_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 From e332fed532cddb678eced6358b565935fb0b2648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 23 Apr 2006 14:20:58 +0000 Subject: [PATCH 2529/4131] return drive and not-written bit for ioctl function 0 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2614 --- include/dos_system.h | 8 ++++++-- src/dos/dos_files.cpp | 4 +++- src/dos/dos_ioctl.cpp | 9 +++++++-- src/dos/drive_fat.cpp | 4 ++-- src/dos/drive_iso.cpp | 11 +++++------ src/dos/drive_local.cpp | 25 ++++++++++++++++--------- src/dos/drive_virtual.cpp | 2 +- 7 files changed, 40 insertions(+), 23 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 25a9d54b..b49a0508 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.34 2006-04-15 15:53:37 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.35 2006-04-23 14:20:57 c2woody Exp $ */ #ifndef DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H @@ -62,7 +62,7 @@ class DOS_DTA; class DOS_File { public: - DOS_File():flags(0) { name=0; refCtr = 0; }; + 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;}; @@ -78,6 +78,8 @@ public: 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;} Bit8u type; Bit32u flags; Bit16u time; @@ -88,6 +90,8 @@ public: bool open; char* name; /* Some Device Specific Stuff */ +private: + Bit8u hdrive; }; class DOS_Device : public DOS_File { diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index c007955d..0b1246b9 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.72 2006-03-10 09:38:24 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.73 2006-04-23 14:20:57 c2woody Exp $ */ #include #include @@ -410,6 +410,7 @@ bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { } bool foundit=Drives[drive]->FileCreate(&Files[handle],fullname,attributes); if (foundit) { + Files[handle]->SetDrive(drive); Files[handle]->AddRef(); psp.SetFileHandle(*entry,handle); return true; @@ -462,6 +463,7 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { Files[handle]=new DOS_Device(*Devices[devnum]); } else { exists=Drives[drive]->FileOpen(&Files[handle],fullname,flags); + if (exists) Files[handle]->SetDrive(drive); } if (exists || device ) { Files[handle]->AddRef(); diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index a9c36586..01e374f0 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.27 2006-04-07 16:34:07 c2woody Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.28 2006-04-23 14:20:57 c2woody Exp $ */ #include #include "dosbox.h" @@ -49,8 +49,13 @@ bool DOS_IOCTL(void) { if (Files[handle]->GetInformation() & 0x8000) { //Check for device reg_dx=Files[handle]->GetInformation(); } else { + Bit8u hdrive=Files[handle]->GetDrive(); + if (hdrive==0xff) { + LOG(LOG_IOCTL,LOG_NORMAL)("00:No drive set"); + hdrive=2; // defaulting to C: + } /* return drive number in lower 5 bits for block devices */ - reg_dx=(Files[handle]->GetInformation()&0xffe0)|drive; + reg_dx=(Files[handle]->GetInformation()&0xffe0)|hdrive; } reg_ax=reg_dx; //Destroyed officially return true; diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 54a6b4d2..3373476f 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.13 2006-04-17 10:45:32 qbix79 Exp $ */ +/* $Id: drive_fat.cpp,v 1.14 2006-04-23 14:20:58 c2woody Exp $ */ #include #include @@ -232,7 +232,7 @@ bool fatFile::Close() { } Bit16u fatFile::GetInformation(void) { - return 0x202; + return 0; } bool fatFile::UpdateDateTimeFromHost(void) { diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index aefa0ba0..d0d42e55 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.12 2006-02-12 13:32:30 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.13 2006-04-23 14:20:58 c2woody Exp $ */ #include #include @@ -30,7 +30,7 @@ using namespace std; class isoFile : public DOS_File { public: - isoFile(isoDrive *drive, const char *name, FileStat_Block *stat, Bit32u offset, Bit16u info); + isoFile(isoDrive *drive, const char *name, FileStat_Block *stat, Bit32u offset); bool Read(Bit8u *data, Bit16u *size); bool Write(Bit8u *data, Bit16u *size); bool Seek(Bit32u *pos, Bit32u type); @@ -46,7 +46,7 @@ private: Bit16u info; }; -isoFile::isoFile(isoDrive *drive, const char *name, FileStat_Block *stat, Bit32u offset, Bit16u info) +isoFile::isoFile(isoDrive *drive, const char *name, FileStat_Block *stat, Bit32u offset) { this->drive = drive; time = stat->time; @@ -58,7 +58,6 @@ isoFile::isoFile(isoDrive *drive, const char *name, FileStat_Block *stat, Bit32u fileEnd = fileBegin + size; cachedSector = -1; open = true; - this->info = info; this->name = NULL; SetName(name); } @@ -136,7 +135,7 @@ bool isoFile::Close() Bit16u isoFile::GetInformation(void) { - return info; + return 0x40; // read-only drive } int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit); @@ -201,7 +200,7 @@ bool isoDrive::FileOpen(DOS_File **file, char *name, Bit32u flags) file_stat.attr = DOS_ATTR_ARCHIVE | DOS_ATTR_READ_ONLY; file_stat.date = DOS_PackDate(1900 + de.dateYear, de.dateMonth, de.dateDay); file_stat.time = DOS_PackTime(de.timeHour, de.timeMin, de.timeSec); - *file = new isoFile(this, name, &file_stat, EXTENT_LOCATION(de) * ISO_FRAMESIZE, 0x202); + *file = new isoFile(this, name, &file_stat, EXTENT_LOCATION(de) * ISO_FRAMESIZE); (*file)->flags = flags; } return success; diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index cca4e2bf..38ab81d8 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.66 2006-04-17 10:45:30 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.67 2006-04-23 14:20:58 c2woody Exp $ */ #include #include @@ -33,17 +33,18 @@ class localFile : public DOS_File { public: - localFile(const char* name, FILE * handle,Bit16u devinfo); + localFile(const char* name, FILE * handle); bool Read(Bit8u * data,Bit16u * size); bool Write(Bit8u * data,Bit16u * size); bool Seek(Bit32u * pos,Bit32u type); bool Close(); Bit16u GetInformation(void); bool UpdateDateTimeFromHost(void); + void FlagReadOnlyMedium(void); private: FILE * fhandle; + bool read_only_medium; enum { NONE,READ,WRITE } last_action; - Bit16u info; }; @@ -72,7 +73,7 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) { if(!existing_file) dirCache.AddEntry(newname, true); /* Make the 16 bit device information */ - *file=new localFile(name,hand,0x202); + *file=new localFile(name,hand); return true; }; @@ -108,7 +109,7 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { return false; } - *file=new localFile(name,hand,0x202); + *file=new localFile(name,hand); (*file)->flags=flags; //for the inheritance flag and maybe check for others. // (*file)->SetFileName(newname); return true; @@ -486,13 +487,12 @@ bool localFile::Close() { } Bit16u localFile::GetInformation(void) { - return info; + return read_only_medium?0x40:0; } -localFile::localFile(const char* _name, FILE * handle,Bit16u devinfo) { +localFile::localFile(const char* _name, FILE * handle) { fhandle=handle; - info=devinfo; struct stat temp_stat; fstat(fileno(handle),&temp_stat); struct tm * ltime; @@ -505,12 +505,17 @@ localFile::localFile(const char* _name, FILE * handle,Bit16u devinfo) { size=(Bit32u)temp_stat.st_size; attr=DOS_ATTR_ARCHIVE; last_action=NONE; + read_only_medium=false; open=true; name=0; SetName(_name); } +void localFile::FlagReadOnlyMedium(void) { + read_only_medium = true; +} + bool localFile::UpdateDateTimeFromHost(void) { if(!open) return false; struct stat temp_stat; @@ -554,7 +559,9 @@ bool cdromDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) DOS_SetError(DOSERR_ACCESS_DENIED); return false; } - return localDrive::FileOpen(file,name,flags); + bool retcode = localDrive::FileOpen(file,name,flags); + ((localFile*)(*file))->FlagReadOnlyMedium(); + return retcode; }; bool cdromDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index ae1e7867..1c37f705 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -129,7 +129,7 @@ bool Virtual_File::Close(){ Bit16u Virtual_File::GetInformation(void) { - return 0; + return 0x40; // read-only drive } From 77bb709df9153574e6c11e503b3966c09903183f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 23 Apr 2006 15:17:07 +0000 Subject: [PATCH 2530/4131] Always echo the value. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2615 --- src/shell/shell_cmds.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 86289e9f..d84e815b 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.65 2006-04-21 13:21:09 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.66 2006-04-23 15:17:07 qbix79 Exp $ */ #include #include @@ -826,9 +826,8 @@ void DOS_Shell::CMD_CHOICE(char * args){ do { DOS_ReadFile (STDIN,&c,&n); } while (!c || !(ptr = strchr(rem,(optS?c:toupper(c))))); - if (!optN) { //Echo typed value ? not sure actually perhaps depend on echo - DOS_WriteFile (STDOUT,&c, &n); - } + c = optS?c:toupper(c); + DOS_WriteFile (STDOUT,&c, &n); dos.return_code = ptr-rem+1; } From eedd8cc98cdb7c7197669f169e5f97a5b155aa7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 26 Apr 2006 14:35:55 +0000 Subject: [PATCH 2531/4131] directly handle some page faults of MakeCodePage Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2616 --- src/cpu/core_dyn_x86.cpp | 6 +++++- src/cpu/core_dyn_x86/cache.h | 18 ++++++++++++------ src/cpu/core_dyn_x86/decoder.h | 4 +++- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 570a0b00..daf97fd7 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -226,7 +226,11 @@ restart_core: #if C_HEAVY_DEBUG if (DEBUG_HeavyIsBreakpoint()) return debugCallback; #endif - CodePageHandler * chandler=MakeCodePage(ip_page); + CodePageHandler * chandler=0; + if (GCC_UNLIKELY(MakeCodePage(ip_page,chandler))) { + CPU_Exception(cpu.exception.which,cpu.exception.error); + goto restart_core; + } if (!chandler) return CPU_Core_Normal_Run(); /* Find correct Dynamic Block to run */ CacheBlock * block=chandler->FindCacheBlock(ip_point&4095); diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 07ff1b94..6751cad6 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -233,18 +233,23 @@ private: }; -static CodePageHandler * MakeCodePage(Bitu lin_page) { - mem_readb(lin_page << 12); //Ensure page contains memory +static bool MakeCodePage(Bitu lin_page,CodePageHandler * &cph) { + Bit8u rdval; + //Ensure page contains memory: + if (GCC_UNLIKELY(mem_readb_checked_x86(lin_page << 12,&rdval))) return true; PageHandler * handler=paging.tlb.handler[lin_page]; - if (handler->flags & PFLAG_HASCODE) return ( CodePageHandler *)handler; + if (handler->flags & PFLAG_HASCODE) { + cph=( CodePageHandler *)handler; + return false; + } if (handler->flags & PFLAG_NOCODE) { LOG_MSG("DYNX86:Can't run code in this page"); - return 0; + cph=0; return false; } Bitu phys_page=lin_page; if (!PAGING_MakePhysPage(phys_page)) { LOG_MSG("DYNX86:Can't find physpage"); - return 0; + cph=0; return false; } /* Find a free CodePage */ if (!cache.free_pages) { @@ -260,7 +265,8 @@ static CodePageHandler * MakeCodePage(Bitu lin_page) { cpagehandler->SetupAt(phys_page,handler); MEM_SetPageHandler(phys_page,1,cpagehandler); PAGING_UnlinkPages(lin_page,1); - return cpagehandler; + cph=cpagehandler; + return false; } static INLINE void cache_addunsedblock(CacheBlock * block) { diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index e851d6c1..ad8f7292 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -61,7 +61,9 @@ static Bit8u decode_fetchb(void) { if (decode.page.index>=4096) { /* Advance to the next page */ decode.active_block->page.end=4095; - decode.page.code=MakeCodePage(++decode.page.first); + /* trigger possible page fault here */ + mem_readb((++decode.page.first) << 12); + MakeCodePage(decode.page.first,decode.page.code); CacheBlock * newblock=cache_getblock(); decode.active_block->crossblock=newblock; newblock->crossblock=decode.active_block; From 19955c36e87cdf400672f63b646e3764c5500650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 27 Apr 2006 13:22:27 +0000 Subject: [PATCH 2532/4131] use inverted stack mask in normal/full core; issue exception when calling type zero descriptor; add INVLPG opcode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2617 --- src/cpu/core_full/load.h | 4 ++-- src/cpu/core_full/op.h | 5 +++++ src/cpu/core_normal.cpp | 1 + src/cpu/core_normal/prefix_0f.h | 4 ++++ src/cpu/core_normal/prefix_66.h | 2 +- src/cpu/core_normal/prefix_66_0f.h | 4 ++++ src/cpu/core_normal/prefix_none.h | 2 +- src/cpu/cpu.cpp | 7 +++++-- 8 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 73ced332..1f47b886 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -447,12 +447,12 @@ l_M_Ed: goto nextopcode; } case D_LEAVEw: - reg_esp&=~cpu.stack.mask; + reg_esp&=cpu.stack.notmask; reg_esp|=(reg_ebp&cpu.stack.mask); reg_bp=Pop_16(); goto nextopcode; case D_LEAVEd: - reg_esp&=~cpu.stack.mask; + reg_esp&=cpu.stack.notmask; reg_esp|=(reg_ebp&cpu.stack.mask); reg_ebp=Pop_32(); goto nextopcode; diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 8f25a72d..97f85756 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -450,6 +450,11 @@ switch (inst.code.op) { FillFlags(); if (CPU_LMSW(inst_op1_w)) RunException(); goto nextopcode; + case 7: /* INVLPG */ + if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); + FillFlags(); + PAGING_ClearTLB(); + goto nextopcode; default: LOG(LOG_CPU,LOG_ERROR)("Group 7 Illegal subfunction %X",inst.rm_index); goto illegalopcode; diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 5ff39eeb..f71a6f1f 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -26,6 +26,7 @@ #include "callback.h" #include "pic.h" #include "fpu.h" +#include "paging.h" #if C_DEBUG #include "debug.h" diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index cb24f83f..cefd09ea 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -92,6 +92,10 @@ limit=LoadMw(eaa); if (CPU_LMSW(limit)) RUNEXCEPTION(); break; + case 0x07: /* INVLPG */ + if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); + PAGING_ClearTLB(); + break; } } else { GetEArw;Bitu limit; diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index a839c42b..8742716a 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -492,7 +492,7 @@ } break; CASE_D(0xc9) /* LEAVE */ - reg_esp&=~cpu.stack.mask; + reg_esp&=cpu.stack.notmask; reg_esp|=(reg_ebp&cpu.stack.mask); reg_ebp=Pop_32(); break; diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index d9cc9901..b034b783 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -94,6 +94,10 @@ limit=LoadMw(eaa); if (CPU_LMSW((Bit16u)limit)) RUNEXCEPTION(); break; + case 0x07: /* INVLPG */ + if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); + PAGING_ClearTLB(); + break; } } else { GetEArd;Bitu limit; diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 44a9a941..c2d8113a 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -712,7 +712,7 @@ } break; CASE_W(0xc9) /* LEAVE */ - reg_esp&=~cpu.stack.mask; + reg_esp&=cpu.stack.notmask; reg_esp|=(reg_ebp&cpu.stack.mask); reg_bp=Pop_16(); break; diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index abe57759..6e687e41 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.80 2006-04-18 17:44:25 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.81 2006-04-27 13:22:27 c2woody Exp $ */ #include #include "dosbox.h" @@ -1147,9 +1147,12 @@ call_code: LOG(LOG_CPU,LOG_NORMAL)("CALL:TSS to %X",selector); CPU_SwitchTask(selector,TSwitch_CALL_INT,oldeip); break; + case DESC_INVALID: + // used by some installers + CPU_Exception(EXCEPTION_GP,selector & 0xfffc); + return; default: E_Exit("CALL:Descriptor type %x unsupported",call.Type()); - } } assert(1); From de851a79a590e79c2b897fa2396c8e4c5a64b4be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 28 Apr 2006 16:38:09 +0000 Subject: [PATCH 2533/4131] set stack pointer somewhat lower when booting (Shamus booter) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2618 --- src/dos/dos_programs.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index b9ca13be..bbff4ca0 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.58 2006-04-17 10:45:32 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.59 2006-04-28 16:38:09 c2woody Exp $ */ #include #include @@ -502,14 +502,13 @@ public: SegSet16(es, 0); /* set up stack at a safe place */ SegSet16(ss, 0x7000); - reg_esp = 0xfffe; + reg_esp = 0x400; reg_esi = 0; reg_ecx = 1; reg_ebp = 0; reg_eax = 0; reg_edx = 0; //Head 0 drive 0 reg_ebx= 0x7c00; //Real code probably uses bx to load the image - //DEBUG_EnableDebugger(); } } }; From b1fb54123b9f3a7d989e967cdea3570d68035c1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 29 Apr 2006 10:05:55 +0000 Subject: [PATCH 2534/4131] raise umb segment size, update LOADHIGH help text Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2619 --- src/dos/dos_memory.cpp | 9 ++------- src/shell/shell.cpp | 4 ++-- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 5a8b737b..b588961a 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -305,13 +305,8 @@ bool DOS_FreeMemory(Bit16u segment) { void DOS_BuildUMBChain(const char* use_umbs,bool ems_active) { if ((strcmp(use_umbs,"false")!=0) && (machine!=MCH_TANDY)) { - Bit16u first_umb_seg=0xca00; - Bit16u first_umb_size=0x600; - - if (strcmp(use_umbs,"max")==0) { - first_umb_seg-=0x100; - first_umb_size+=0x100; - } + Bit16u first_umb_seg=0xc800; + Bit16u first_umb_size=0x800; dos_infoblock.SetStartOfUMBChain(UMB_START_SEG); dos_infoblock.SetUMBChainState(0); // UMBs not linked yet diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 29c272e7..855bacee 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.72 2006-02-26 15:58:49 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.73 2006-04-29 10:05:55 c2woody Exp $ */ #include #include @@ -504,7 +504,7 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_COPY_HELP","Copy files.\n"); MSG_Add("SHELL_CMD_CALL_HELP","Start a batch file from within another batch file.\n"); MSG_Add("SHELL_CMD_SUBST_HELP","Assign an internal directory to a drive.\n"); - MSG_Add("SHELL_CMD_LOADHIGH_HELP","Run a program. For batch file compatibility only.\n"); + MSG_Add("SHELL_CMD_LOADHIGH_HELP","Loads a program into upper memory (requires xms=true,umb=true).\n"); MSG_Add("SHELL_CMD_CHOICE_HELP","Waits for a keypress and sets ERRORLEVEL.\n"); MSG_Add("SHELL_CMD_ATTRIB_HELP","Does nothing. Provided for compatibility.\n"); MSG_Add("SHELL_CMD_PATH_HELP","Provided for compatibility.\n"); From 28ffbae6be14b8a1525804bf24e576f86a2185cb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 1 May 2006 14:56:35 +0000 Subject: [PATCH 2535/4131] Add patch "1479636: Improved unmount (mount -u)" from TaeWoong Yoo. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2620 --- src/dos/dos_programs.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index bbff4ca0..4479a3d5 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.59 2006-04-28 16:38:09 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.60 2006-05-01 14:56:35 qbix79 Exp $ */ #include #include @@ -56,10 +56,6 @@ public: umount[0] = toupper(umount[0]); int i_drive = umount[0]-'A'; if(i_drive < DOS_DRIVES && Drives[i_drive]) { - if(i_drive == DOS_GetDefaultDrive()) { - WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_CURRENT")); - return; - } try { /* Check if virtualdrive */ if( dynamic_cast(Drives[i_drive]) == 0 ) throw 0; } @@ -67,9 +63,11 @@ public: WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NO_VIRTUAL")); return; } - WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCES"),umount[0]); + if(i_drive == DOS_GetDefaultDrive()) + DOS_SetDrive(toupper('Z') - 'A'); delete Drives[i_drive]; Drives[i_drive] = 0; + WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCES"),umount[0]); } else { WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED"),umount[0]); } @@ -862,7 +860,6 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_MOUNT_ILL_TYPE","Illegal type %s\n"); MSG_Add("PROGRAM_MOUNT_ALLREADY_MOUNTED","Drive %c already mounted with %s\n"); MSG_Add("PROGRAM_MOUNT_USAGE","Usage \033[34;1mMOUNT Drive-Letter Local-Directory\033[0m\nSo a MOUNT c c:\\windows mounts windows directory as the c: drive in DOSBox\n"); - MSG_Add("PROGRAM_MOUNT_UMOUNT_CURRENT","You can not unMOUNT the active drive.\n"); MSG_Add("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED","Drive %c isn't mounted.\n"); MSG_Add("PROGRAM_MOUNT_UMOUNT_SUCCES","Drive %c has succesfully been removed.\n"); MSG_Add("PROGRAM_MOUNT_UMOUNT_NO_VIRTUAL","Virtual Drives can not be unMOUNTed.\n"); From 458d7e5deecacf870bbbdb195f7549c1bb8449b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 1 May 2006 19:34:41 +0000 Subject: [PATCH 2536/4131] check io permission for dyncore port access Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2621 --- src/cpu/core_dyn_x86/decoder.h | 60 +++++++++++++++++++++++++++------- src/hardware/iohandler.cpp | 16 ++++----- 2 files changed, 55 insertions(+), 21 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index ad8f7292..9be546ae 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1209,6 +1209,20 @@ static void dyn_interrupt(Bitu num) { dyn_closeblock(); } +static void dyn_add_iocheck(Bitu access_size) { + if (cpu.pmode) { + gen_call_function((void *)&CPU_IO_Exception,"%Dw%Id",DREG(EDX),access_size); + dyn_check_bool_exception_al(); + } +} + +static void dyn_add_iocheck_var(Bit8u accessed_port,Bitu access_size) { + if (cpu.pmode) { + gen_call_function((void *)&CPU_IO_Exception,"%Id%Id",accessed_port,access_size); + dyn_check_bool_exception_al(); + } +} + static CacheBlock * CreateCacheBlock(CodePageHandler * codepage,PhysPt start,Bitu max_opcodes) { Bits i; /* Init a load of variables */ @@ -1591,23 +1605,35 @@ restart_prefix: case 0xe2:dyn_loop(LOOP_NONE);goto finish_block; case 0xe3:dyn_loop(LOOP_JCXZ);goto finish_block; //IN AL/AX,imm - case 0xe4:gen_call_function((void*)&IO_ReadB,"%Id%Rl",decode_fetchb(),DREG(EAX));break; - case 0xe5: + case 0xe4: { + Bitu port=decode_fetchb(); + dyn_add_iocheck_var(port,1); + gen_call_function((void*)&IO_ReadB,"%Id%Rl",port,DREG(EAX)); + } break; + case 0xe5: { + Bitu port=decode_fetchb(); + dyn_add_iocheck_var(port,decode.big_op?4:2); if (decode.big_op) { - gen_call_function((void*)&IO_ReadD,"%Id%Rd",decode_fetchb(),DREG(EAX)); + gen_call_function((void*)&IO_ReadD,"%Id%Rd",port,DREG(EAX)); } else { - gen_call_function((void*)&IO_ReadW,"%Id%Rw",decode_fetchb(),DREG(EAX)); + gen_call_function((void*)&IO_ReadW,"%Id%Rw",port,DREG(EAX)); } - break; + } break; //OUT imm,AL - case 0xe6:gen_call_function((void*)&IO_WriteB,"%Id%Dl",decode_fetchb(),DREG(EAX));break; - case 0xe7: + case 0xe6: { + Bitu port=decode_fetchb(); + dyn_add_iocheck_var(port,1); + gen_call_function((void*)&IO_WriteB,"%Id%Dl",port,DREG(EAX)); + } break; + case 0xe7: { + Bitu port=decode_fetchb(); + dyn_add_iocheck_var(port,decode.big_op?4:2); if (decode.big_op) { - gen_call_function((void*)&IO_WriteD,"%Id%Dd",decode_fetchb(),DREG(EAX)); + gen_call_function((void*)&IO_WriteD,"%Id%Dd",port,DREG(EAX)); } else { - gen_call_function((void*)&IO_WriteW,"%Id%Dw",decode_fetchb(),DREG(EAX)); + gen_call_function((void*)&IO_WriteW,"%Id%Dw",port,DREG(EAX)); } - break; + } break; case 0xe8: /* CALL Ivx */ dyn_call_near_imm(); goto finish_block; @@ -1620,8 +1646,12 @@ restart_prefix: /* Jmp Ibx */ case 0xeb:dyn_exit_link((Bit8s)decode_fetchb());goto finish_block; /* IN AL/AX,DX*/ - case 0xec:gen_call_function((void*)&IO_ReadB,"%Dw%Rl",DREG(EDX),DREG(EAX));break; + case 0xec: + dyn_add_iocheck(1); + gen_call_function((void*)&IO_ReadB,"%Dw%Rl",DREG(EDX),DREG(EAX)); + break; case 0xed: + dyn_add_iocheck(decode.big_op?4:2); if (decode.big_op) { gen_call_function((void*)&IO_ReadD,"%Dw%Rd",DREG(EDX),DREG(EAX)); } else { @@ -1629,14 +1659,20 @@ restart_prefix: } break; /* OUT DX,AL/AX */ - case 0xee:gen_call_function((void*)&IO_WriteB,"%Dw%Dl",DREG(EDX),DREG(EAX));break; + case 0xee: + dyn_add_iocheck(1); + gen_call_function((void*)&IO_WriteB,"%Dw%Dl",DREG(EDX),DREG(EAX)); + break; case 0xef: + dyn_add_iocheck(decode.big_op?4:2); if (decode.big_op) { gen_call_function((void*)&IO_WriteD,"%Dw%Dd",DREG(EDX),DREG(EAX)); } else { gen_call_function((void*)&IO_WriteW,"%Dw%Dw",DREG(EDX),DREG(EAX)); } break; + case 0xf0: //LOCK + break; case 0xf2: //REPNE/NZ decode.rep=REP_NZ; goto restart_prefix; diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index d3f86b4e..a36672cc 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: iohandler.cpp,v 1.21 2006-04-11 19:02:33 qbix79 Exp $ */ +/* $Id: iohandler.cpp,v 1.22 2006-05-01 19:34:41 c2woody Exp $ */ #include #include "dosbox.h" @@ -162,10 +162,8 @@ static Bits IOFaultCore(void) { return 0; } -Bitu DEBUG_EnableDebugger(); - void IO_WriteB(Bitu port,Bitu val) { - if (GETFLAG(VM) && (CPU_IO_Exception(port,1))) { + if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,1)))) { LazyFlags old_lflags; memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); CPU_Decoder * old_cpudecoder; @@ -198,7 +196,7 @@ void IO_WriteB(Bitu port,Bitu val) { }; void IO_WriteW(Bitu port,Bitu val) { - if (GETFLAG(VM) && (CPU_IO_Exception(port,2))) { + if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,2)))) { LazyFlags old_lflags; memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); CPU_Decoder * old_cpudecoder; @@ -231,7 +229,7 @@ void IO_WriteW(Bitu port,Bitu val) { }; void IO_WriteD(Bitu port,Bitu val) { - if (GETFLAG(VM) && (CPU_IO_Exception(port,4))) { + if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,4)))) { LazyFlags old_lflags; memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); CPU_Decoder * old_cpudecoder; @@ -264,7 +262,7 @@ void IO_WriteD(Bitu port,Bitu val) { }; Bitu IO_ReadB(Bitu port) { - if (GETFLAG(VM) && (CPU_IO_Exception(port,1))) { + if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,1)))) { LazyFlags old_lflags; memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); CPU_Decoder * old_cpudecoder; @@ -297,7 +295,7 @@ Bitu IO_ReadB(Bitu port) { }; Bitu IO_ReadW(Bitu port) { - if (GETFLAG(VM) && (CPU_IO_Exception(port,2))) { + if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,2)))) { LazyFlags old_lflags; memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); CPU_Decoder * old_cpudecoder; @@ -330,7 +328,7 @@ Bitu IO_ReadW(Bitu port) { }; Bitu IO_ReadD(Bitu port) { - if (GETFLAG(VM) && (CPU_IO_Exception(port,4))) { + if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,4)))) { LazyFlags old_lflags; memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); CPU_Decoder * old_cpudecoder; From 42c95e065be9460dca20e7875c51fa557c68e0b4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 7 May 2006 20:00:05 +0000 Subject: [PATCH 2537/4131] Fix Resize memory. (handle information didn't have the resized size.) Fix error codes of move_memory. Implement 8f. This fixes E.EXE (an editor). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2622 --- src/ints/xms.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 8dca90ce..e6b8b455 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.41 2006-04-22 15:25:45 c2woody Exp $ */ +/* $Id: xms.cpp,v 1.42 2006-05-07 20:00:05 qbix79 Exp $ */ #include #include @@ -55,6 +55,7 @@ #define XMS_QUERY_ANY_FREE_MEMORY 0x88 #define XMS_ALLOCATE_ANY_MEMORY 0x89 #define XMS_GET_EMB_HANDLE_INFORMATION_EXT 0x8e +#define XMS_RESIZE_ANY_EXTENDED_MEMORY_BLOCK 0x8f #define XMS_FUNCTION_NOT_IMPLEMENTED 0x80 #define HIGH_MEMORY_NOT_EXIST 0x90 @@ -151,8 +152,7 @@ Bitu XMS_FreeMemory(Bitu handle) return 0; }; -Bitu XMS_MoveMemory(PhysPt bpt) -{ +Bitu XMS_MoveMemory(PhysPt bpt) { /* Read the block with mem_read's */ Bitu length=mem_readd(bpt+offsetof(XMS_MemMove,length)); Bitu src_handle=mem_readw(bpt+offsetof(XMS_MemMove,src_handle)); @@ -180,10 +180,10 @@ Bitu XMS_MoveMemory(PhysPt bpt) } if (dest_handle) { if (InvalidHandle(dest_handle)) { - return 0xa3; /* Dest Handle invalid */ + return 0xa5; /* Dest Handle invalid */ } if (dest.offset>=(xms_handles[dest_handle].size*1024U)) { - return 0xa4; /* Dest Offset invalid */ + return 0xa6; /* Dest Offset invalid */ } if (length>xms_handles[dest_handle].size*1024U-dest.offset) { return 0xa7; /* Length invalid */ @@ -235,6 +235,7 @@ Bitu XMS_ResizeMemory(Bitu handle, Bitu newSize) if (xms_handles[handle].locked>0) return XMS_BLOCK_LOCKED; Bitu pages=newSize/4 + ((newSize & 3) ? 1 : 0); if (MEM_ReAllocatePages(xms_handles[handle].mem,pages,true)) { + xms_handles[handle].size = newSize; return 0; } else return XMS_OUT_OF_SPACE; } @@ -323,6 +324,9 @@ Bitu XMS_Handler(void) { case XMS_GET_EMB_HANDLE_INFORMATION: /* 0e */ SET_RESULT(XMS_GetHandleInformation(reg_dx,reg_bh,reg_bl,reg_dx)); break; + case XMS_RESIZE_ANY_EXTENDED_MEMORY_BLOCK: /* 0x8f */ + if(reg_ebx > reg_bx) LOG_MSG("64MB memory limit!"); + //fall through case XMS_RESIZE_EXTENDED_MEMORY_BLOCK: /* 0f */ SET_RESULT(XMS_ResizeMemory(reg_dx, reg_bx)); break; From c473b8121744234ac4642dfb4bc930b896a77fdb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 14 May 2006 19:57:24 +0000 Subject: [PATCH 2538/4131] Attempt to fix bug 1487972 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2623 --- src/dos/drive_local.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 38ab81d8..4683b245 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.67 2006-04-23 14:20:58 c2woody Exp $ */ +/* $Id: drive_local.cpp,v 1.68 2006-05-14 19:57:24 qbix79 Exp $ */ #include #include @@ -560,7 +560,7 @@ bool cdromDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) return false; } bool retcode = localDrive::FileOpen(file,name,flags); - ((localFile*)(*file))->FlagReadOnlyMedium(); + if(retcode) (dynamic_cast(*file))->FlagReadOnlyMedium(); return retcode; }; From 8ece9230da250f354881c41b8f92f1c0af149b05 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 18 May 2006 11:25:46 +0000 Subject: [PATCH 2539/4131] timer mode 0 counter after passing terminal count update by h-a-l-9000.(Fixes Archon Ultra and The Horde) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2624 --- src/hardware/timer.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 43e59082..3317682d 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.36 2006-04-11 12:02:09 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.37 2006-05-18 11:25:46 qbix79 Exp $ */ #include #include "dosbox.h" @@ -126,8 +126,13 @@ static void counter_latch(Bitu counter) { /* Counter keeps on counting after passing terminal count */ if (index>p->delay) { index-=p->delay; - index=fmod(index,(1000.0/PIT_TICK_RATE)*0x1000); - p->read_latch=(Bit16u)(0xffff-index*0xffff); + if(p->bcd) { + index = fmod(index,(1000.0/PIT_TICK_RATE)*10000.0); + p->read_latch = (Bit16u)(9999-index*(PIT_TICK_RATE/1000.0)); + } else { + index = fmod(index,(1000.0/PIT_TICK_RATE)*(double)0x10000); + p->read_latch = (Bit16u)(0xffff-index*(PIT_TICK_RATE/1000.0)); + } } else { p->read_latch=(Bit16u)(p->cntr-index*(PIT_TICK_RATE/1000.0)); } From 94bbf1e01f95eacd5b84007a022116b06b43cc44 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 18 May 2006 11:32:09 +0000 Subject: [PATCH 2540/4131] Add patch "[ 1488441 ] fix for dosbox-0.65 build error on Solaris 5.8 (powf)" by Claudio Fontana. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2625 --- src/hardware/mixer.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 353af4c3..9fac2291 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.39 2006-03-27 19:41:55 qbix79 Exp $ */ +/* $Id: mixer.cpp,v 1.40 2006-05-18 11:32:09 qbix79 Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -55,6 +55,10 @@ #define MIXER_REMAIN ((1< MIN_AUDIO) From 93211188a7f55de494c0391f602d9ff63e97dd8e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 18 May 2006 11:42:02 +0000 Subject: [PATCH 2541/4131] A few small debug improvements. (Improve heavylog speed. Exit in heavydebug mode on zero code. BPINT 21 gets translated to BPINT 21 * instead of BPINT 21 reg_ah=0) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2626 --- src/debug/debug.cpp | 164 ++++++++++++++++++++++++++++++++------------ 1 file changed, 121 insertions(+), 43 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 3c4aa719..0043ca4c 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,14 +16,18 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.76 2006-03-26 11:11:56 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.77 2006-05-18 11:42:02 qbix79 Exp $ */ + +#include "dosbox.h" +#if C_DEBUG #include #include #include +#include +#include +using namespace std; -#include "dosbox.h" -#if C_DEBUG #include "debug.h" #include "cross.h" //snprintf #include "cpu.h" @@ -598,9 +602,9 @@ void CBreakpoint::ShowList(void) bool DEBUG_Breakpoint(void) { /* First get the phyiscal address and check for a set Breakpoint */ - PhysPt where=GetAddress(SegValue(cs),reg_eip); if (!CBreakpoint::CheckBreakpoint(SegValue(cs),reg_eip)) return false; // Found. Breakpoint is valid + PhysPt where=GetAddress(SegValue(cs),reg_eip); CBreakpoint::ActivateBreakpoints(where,false); // Deactivate all breakpoints return true; }; @@ -1056,9 +1060,10 @@ bool ParseCommand(char* str) found = strstr(str,"BPINT"); if (found) { // Add Interrupt Breakpoint found+=5; - Bit8u intNr = (Bit8u)GetHexValue(found,found); found++; + Bit8u intNr = (Bit8u)GetHexValue(found,found); + bool all = !(*found);found++; Bit8u valAH = (Bit8u)GetHexValue(found,found); - if ((valAH==0x00) && (*found=='*')) { + if ((valAH==0x00) && (*found=='*' || all)) { CBreakpoint::AddIntBreakpoint(intNr,BPINT_ALL,false); DEBUG_ShowMsg("DEBUG: Set interrupt breakpoint at INT %02X\n",intNr); } else { @@ -1803,39 +1808,34 @@ static void LogCPUInfo(void) static void LogInstruction(Bit16u segValue, Bit32u eipValue, char* buffer) { - static char empty[15] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,0 }; + static char empty[23] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0 }; PhysPt start = GetAddress(segValue,eipValue); char dline[200];Bitu size; size = DasmI386(dline, start, reg_eip, cpu.code.big); - Bitu len = strlen(dline); char* res = empty; if (showExtend) { res = AnalyzeInstruction(dline,false); - len = strlen(dline); -#if C_HEAVY_DEBUG - if (cpuLogType>=2) { - Bitu reslen=strlen(res); - if (reslen<24) for (Bitu i=0; i<24-reslen; i++) strcat(res," "); - } else -#endif - if (!res || (strlen(res)==0)) res = empty; + if (!res || !(*res)) res = empty; + Bitu reslen = strlen(res); + if (reslen<22) for (Bitu i=0; i<22-reslen; i++) res[reslen+i] = ' '; res[22] = 0; }; + Bitu len = strlen(dline); // Get register values #if C_HEAVY_DEBUG if (cpuLogType==1) { #endif - if (len<30) for (Bitu i=0; i<30-len; i++) strcat(dline," "); - sprintf(buffer,"%04X:%08X %s %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X IF:%01X\n",segValue,eipValue,dline,res,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss), + if (len<30) for (Bitu i=0; i<30-len; i++) dline[len + i] = ' '; dline[30] = 0; + sprintf(buffer,"%04X:%08X %s %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X IF:%01X\n",segValue,eipValue,dline,res,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss), get_CF()?1:0,get_ZF()?1:0,get_SF()?1:0,get_OF()?1:0,get_AF()?1:0,get_PF()?1:0,GETFLAGBOOL(IF)); #if C_HEAVY_DEBUG } else if (cpuLogType==0) { - if (len<27) for (Bitu i=0; i<27-len; i++) strcat(dline," "); + if (len<27) for (Bitu i=0; i<27-len; i++) dline[len+i] = ' '; dline[27] = 0; sprintf(buffer,"%04X:%04X %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X SS:%04X C%01X Z%01X S%01X O%01X I%01X\n",segValue,eipValue,dline,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(ss), get_CF()?1:0,get_ZF()?1:0,get_SF()?1:0,get_OF()?1:0,GETFLAGBOOL(IF)); } else { - if (len<34) for (Bitu i=0; i<34-len; i++) strcat(dline," "); + if (len<34) for (Bitu i=0; i<34-len; i++) dline[len+i] = ' '; dline[34] = 0; char ibytes[200]=""; char tmpc[200]; for (Bitu i=0; i=LOGCPUMAX) { - logCount = 0; +void DEBUG_HeavyLogInstruction(void) { + + static char empty[23] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0 }; + + PhysPt start = GetAddress(SegValue(cs),reg_eip); + char dline[200]; + Bitu size = DasmI386(dline, start, reg_eip, cpu.code.big); + char* res = empty; + if (showExtend) { + res = AnalyzeInstruction(dline,false); + if (!res || !(*res)) res = empty; + Bitu reslen = strlen(res); + if (reslen<22) for (Bitu i=0; i<22-reslen; i++) res[reslen+i] = ' '; res[22] = 0; }; + + Bitu len = strlen(dline); + if (len < 30) for (Bitu i=0; i < 30-len; i++) dline[len+i] = ' '; + dline[30] = 0; + + TLogInst & inst = logInst[logCount]; + strcpy(inst.dline,dline); + inst.s_cs = SegValue(cs); + inst.eip = reg_eip; + strcpy(inst.res,res); + inst.eax = reg_eax; + inst.ebx = reg_ebx; + inst.ecx = reg_ecx; + inst.edx = reg_edx; + inst.esi = reg_esi; + inst.edi = reg_edi; + inst.ebp = reg_ebp; + inst.esp = reg_esp; + inst.s_ds = SegValue(ds); + inst.s_es = SegValue(es); + inst.s_fs = SegValue(fs); + inst.s_gs = SegValue(gs); + inst.s_ss = SegValue(ss); + inst.c = get_CF(); + inst.z = get_ZF(); + inst.s = get_SF(); + inst.o = get_OF(); + inst.a = get_AF(); + inst.p = get_PF(); + inst.i = GETFLAGBOOL(IF); + + if (++logCount >= LOGCPUMAX) logCount = 0; }; -void DEBUG_HeavyWriteLogInstruction(void) -{ +void DEBUG_HeavyWriteLogInstruction(void) { if (!logHeavy) return; - logHeavy = false; DEBUG_ShowMsg("DEBUG: Creating cpu log LOGCPU_INT_CD.TXT\n"); - FILE* f = fopen("LOGCPU_INT_CD.TXT","wt"); - if (!f) { + ofstream out("LOGCPU_INT_CD.TXT"); + if (!out.is_open()) { DEBUG_ShowMsg("DEBUG: Failed.\n"); return; } - + out << hex << noshowbase << setfill('0') << uppercase; Bit32u startLog = logCount; do { // Write Intructions - fprintf(f,"%s",logInst[startLog++].buffer); - if (startLog>=LOGCPUMAX) startLog = 0; - } while (startLog!=logCount); - - fclose(f); + TLogInst & inst = logInst[startLog]; + out << setw(4) << inst.s_cs << ":" << setw(8) << inst.eip << " " + << inst.dline << " " << inst.res << " EAX:" << setw(8)<< inst.eax + << " EBX:" << setw(8) << inst.ebx << " ECX:" << setw(8) << inst.ecx + << " EDX:" << setw(8) << inst.edx << " ESI:" << setw(8) << inst.esi + << " EDI:" << setw(8) << inst.edi << " EBP:" << setw(8) << inst.ebp + << " ESP:" << setw(8) << inst.esp << " DS:" << setw(4) << inst.s_ds + << " ES:" << setw(4) << inst.s_ds<< " FS:" << setw(4) << inst.s_fs + << " GS:" << setw(4) << inst.s_gs<< " SS:" << setw(4) << inst.s_ss + << " CF:" << inst.c << " ZF:" << inst.z << " SF:" << inst.s + << " OF:" << inst.o << " AF:" << inst.a << " PF:" << inst.p + << " IF:" << inst.i << endl; +/* fprintf(f,"%04X:%08X %s %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X IF:%01X\n", + logInst[startLog].s_cs,logInst[startLog].eip,logInst[startLog].dline,logInst[startLog].res,logInst[startLog].eax,logInst[startLog].ebx,logInst[startLog].ecx,logInst[startLog].edx,logInst[startLog].esi,logInst[startLog].edi,logInst[startLog].ebp,logInst[startLog].esp, + logInst[startLog].s_ds,logInst[startLog].s_es,logInst[startLog].s_fs,logInst[startLog].s_gs,logInst[startLog].s_ss, + logInst[startLog].c,logInst[startLog].z,logInst[startLog].s,logInst[startLog].o,logInst[startLog].a,logInst[startLog].p,logInst[startLog].i);*/ + if (++startLog >= LOGCPUMAX) startLog = 0; + } while (startLog != logCount); + + out.close(); DEBUG_ShowMsg("DEBUG: Done.\n"); }; -bool DEBUG_HeavyIsBreakpoint(void) -{ +bool DEBUG_HeavyIsBreakpoint(void) { + static Bitu zero_count = 0; if (cpuLog) { if (cpuLogCounter>0) { static char buffer[4096]; @@ -2241,6 +2317,8 @@ bool DEBUG_HeavyIsBreakpoint(void) } // LogInstruction if (logHeavy) DEBUG_HeavyLogInstruction(); + if(mem_readd(SegPhys(cs) + reg_eip) == 0) zero_count++; else zero_count = 0; + if(zero_count == 10) E_Exit("running zeroed code"); if (skipFirstInstruction) { skipFirstInstruction = false; From 2cd6264d32bbbb76e7c9bbe51d72e8d938c30704 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 19 May 2006 09:03:39 +0000 Subject: [PATCH 2542/4131] Modernise it a bit and fix builtin_expect configure test Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2627 --- configure.in | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/configure.in b/configure.in index 119c00b4..037651df 100644 --- a/configure.in +++ b/configure.in @@ -51,11 +51,13 @@ AC_CHECK_SIZEOF(unsigned long long) AC_CHECK_SIZEOF(int *) AC_MSG_CHECKING(if environ can be included) -AC_TRY_LINK([#include -#include ],[*environ;], +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +#include ]],[[*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_TRY_LINK([extern char ** environ;],[*environ;], +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)) dnl Checks for libraries. @@ -63,19 +65,20 @@ dnl Checks for libraries. #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_TRY_COMPILE([], [typedef struct { } __attribute__ ((packed)) junk;], - [ AC_MSG_RESULT(yes);AC_DEFINE(C_HAS_ATTRIBUTE)],AC_MSG_RESULT(no)) +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 __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_TRY_COMPILE([],[ -int main(int argc,char* argv[]){ +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],[[ int x=10;if( __builtin_expect ((x==1),0) ) ; -return 0; -} -], [ AC_MSG_RESULT(yes);AC_DEFINE(C_HAS_BUILTIN_EXPECT)],AC_MSG_RESULT(no)) - +]])], [ AC_MSG_RESULT(yes);AC_DEFINE(C_HAS_BUILTIN_EXPECT)],AC_MSG_RESULT(no)) +#switch language back +AC_LANG_POP(C++) AM_PATH_ALSA(0.9.0, AC_DEFINE(HAVE_ALSA,1,[Define to 1 to use ALSA for MIDI]) , : ) @@ -217,12 +220,9 @@ 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([ - #include - int main(int argc,char * argv[]) { - return SDLNet_Init (); - }; - ], [AC_MSG_RESULT(yes); have_sdl_net_lib=yes], AC_MSG_RESULT(no)) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]],[[ + 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, , ) @@ -323,7 +323,7 @@ esac AC_SUBST(WINDRES) -AC_OUTPUT([ +AC_CONFIG_FILES([ Makefile src/Makefile src/cpu/Makefile @@ -348,3 +348,4 @@ visualc_net/Makefile include/Makefile docs/Makefile ]) +AC_OUTPUT From 4775cd6f42568e0bb0eb60c2bc897c8d5a7b456d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 19 May 2006 10:34:02 +0000 Subject: [PATCH 2543/4131] Synchronize timer on repeated events to compensate for lost accuracy. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2628 --- src/hardware/timer.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 3317682d..7a214203 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.37 2006-05-18 11:25:46 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.38 2006-05-19 10:34:02 qbix79 Exp $ */ #include #include "dosbox.h" @@ -65,7 +65,10 @@ static bool latched_timerstatus_locked; static void PIT0_Event(Bitu /*val*/) { PIC_ActivateIRQ(0); - if (pit[0].mode!=0) PIC_AddEvent(PIT0_Event,pit[0].delay); + if (pit[0].mode != 0) { + pit[0].start = PIC_FullIndex()-pit[0].delay; // resynchronize + PIC_AddEvent(PIT0_Event,pit[0].delay); + } } static bool counter_output(Bitu counter) { @@ -146,6 +149,10 @@ static void counter_latch(Bitu counter) { index*=2; if (index>p->delay) index-=p->delay; p->read_latch=(Bit16u)(p->cntr - (index/p->delay)*p->cntr); + // In mode 3 it never returns odd numbers LSB (if odd number is written 1 will be + // subtracted on first clock and then always 2) + // fixes "Corncob 3D" + p->read_latch&=0xfffe; break; default: LOG(LOG_PIT,LOG_ERROR)("Illegal Mode %d for reading counter %d",p->mode,counter); @@ -224,18 +231,13 @@ static Bitu read_latch(Bitu port,Bitu /*iolen*/) { pit[counter].go_read_latch = true; break; case 3: /* read LSB followed by MSB */ - // In mode 3 it never returns odd numbers LSB (if odd number is written 1 will be - // subtracted on first clock and then always 2) - // fixes "Corncob 3D" - if((pit[counter].mode&0x7) == 3) ret = (pit[counter].read_latch & 0xfe); - else ret = (pit[counter].read_latch & 0xff); + ret = pit[counter].read_latch & 0xff; if (pit[counter].mode & 0x80) pit[counter].mode &= 7; else pit[counter].read_state = 0; break; case 1: /* read LSB */ - if((pit[counter].mode&0x7) == 3) ret = (pit[counter].read_latch & 0xfe); - else ret = (pit[counter].read_latch & 0xff); + ret = pit[counter].read_latch & 0xff; pit[counter].go_read_latch = true; break; case 2: /* read MSB */ From 70a902ded26170134f65d6b32708a566fd9357d5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 19 May 2006 13:35:32 +0000 Subject: [PATCH 2544/4131] Fix a small bug in the new heavylog routine. Adapt LOG/S/L to C++ ofstream. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2629 --- src/debug/debug.cpp | 122 ++++++++++++++++++-------------------------- 1 file changed, 51 insertions(+), 71 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 0043ca4c..d6b5a53f 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.77 2006-05-18 11:42:02 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.78 2006-05-19 13:35:32 qbix79 Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -58,7 +58,6 @@ int old_cursor_state; // Forwards static void DrawCode(void); -static bool DEBUG_Log_Loop(int count); static void DEBUG_RaiseTimerIrq(void); static void SaveMemory(Bitu seg, Bitu ofs1, Bit32u num); static void SaveMemoryBin(Bitu seg, Bitu ofs1, Bit32u num); @@ -102,7 +101,7 @@ bool logHeavy = false; // Heavy Debugging Vars for logging #if C_HEAVY_DEBUG -static FILE* cpuLogFile = 0; +static ofstream cpuLogFile; static bool cpuLog = false; static int cpuLogCounter = 0; static int cpuLogType = 1; // log detail @@ -1116,12 +1115,12 @@ bool ParseCommand(char* str) if (found) { // Create Cpu log file found+=4; DEBUG_ShowMsg("DEBUG: Starting log\n"); -// DEBUG_Log_Loop(GetHexValue(found,found)); - cpuLogFile = fopen("LOGCPU.TXT","wt"); - if (!cpuLogFile) { + cpuLogFile.open("LOGCPU.TXT"); + if (!cpuLogFile.is_open()) { DEBUG_ShowMsg("DEBUG: Logfile couldn't be created.\n"); return false; } + cpuLogFile << hex << noshowbase << setfill('0') << uppercase; cpuLog = true; cpuLogType = 1; cpuLogCounter = GetHexValue(found,found); @@ -1137,11 +1136,12 @@ bool ParseCommand(char* str) if (found) { // Create Cpu log file found+=4; DEBUG_ShowMsg("DEBUG: Starting log\n"); - cpuLogFile = fopen("LOGCPU.TXT","wt"); - if (!cpuLogFile) { + cpuLogFile.open("LOGCPU.TXT"); + if (!cpuLogFile.is_open()) { DEBUG_ShowMsg("DEBUG: Logfile couldn't be created.\n"); return false; } + cpuLogFile << hex << noshowbase << setfill('0') << uppercase; cpuLog = true; cpuLogType = 0; cpuLogCounter = GetHexValue(found,found); @@ -1157,11 +1157,12 @@ bool ParseCommand(char* str) if (found) { // Create Cpu log file found+=4; DEBUG_ShowMsg("DEBUG: Starting log\n"); - cpuLogFile = fopen("LOGCPU.TXT","wt"); - if (!cpuLogFile) { + cpuLogFile.open("LOGCPU.TXT"); + if (!cpuLogFile.is_open()) { DEBUG_ShowMsg("DEBUG: Logfile couldn't be created.\n"); return false; } + cpuLogFile << hex << noshowbase << setfill('0') << uppercase; cpuLog = true; cpuLogType = 2; cpuLogCounter = GetHexValue(found,found); @@ -1806,82 +1807,63 @@ static void LogCPUInfo(void) LOG(LOG_MISC,LOG_ERROR)(out1); }; -static void LogInstruction(Bit16u segValue, Bit32u eipValue, char* buffer) -{ +#if C_HEAVY_DEBUG +static void LogInstruction(Bit16u segValue, Bit32u eipValue, ofstream& out) { static char empty[23] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0 }; PhysPt start = GetAddress(segValue,eipValue); char dline[200];Bitu size; size = DasmI386(dline, start, reg_eip, cpu.code.big); char* res = empty; - if (showExtend) { + if (showExtend && (cpuLogType > 0) ) { res = AnalyzeInstruction(dline,false); if (!res || !(*res)) res = empty; Bitu reslen = strlen(res); if (reslen<22) for (Bitu i=0; i<22-reslen; i++) res[reslen+i] = ' '; res[22] = 0; }; Bitu len = strlen(dline); + if (len<30) for (Bitu i=0; i<30-len; i++) dline[len + i] = ' '; dline[30] = 0; // Get register values -#if C_HEAVY_DEBUG - if (cpuLogType==1) { -#endif - if (len<30) for (Bitu i=0; i<30-len; i++) dline[len + i] = ' '; dline[30] = 0; - sprintf(buffer,"%04X:%08X %s %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X IF:%01X\n",segValue,eipValue,dline,res,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss), - get_CF()?1:0,get_ZF()?1:0,get_SF()?1:0,get_OF()?1:0,get_AF()?1:0,get_PF()?1:0,GETFLAGBOOL(IF)); -#if C_HEAVY_DEBUG - } else if (cpuLogType==0) { - if (len<27) for (Bitu i=0; i<27-len; i++) dline[len+i] = ' '; dline[27] = 0; - sprintf(buffer,"%04X:%04X %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X SS:%04X C%01X Z%01X S%01X O%01X I%01X\n",segValue,eipValue,dline,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(ss), - get_CF()?1:0,get_ZF()?1:0,get_SF()?1:0,get_OF()?1:0,GETFLAGBOOL(IF)); - } else { - if (len<34) for (Bitu i=0; i<34-len; i++) dline[len+i] = ' '; dline[34] = 0; + + if(cpuLogType == 0) { + out << setw(4) << SegValue(cs) << ":" << setw(4) << reg_eip << " " << dline; + } else if (cpuLogType == 1) { + out << setw(4) << SegValue(cs) << ":" << setw(8) << reg_eip << " " << dline << " " << res; + } else if (cpuLogType == 2) { char ibytes[200]=""; char tmpc[200]; for (Bitu i=0; i0) ret=(*CallBack_Handlers[ret])(); - - count--; - if (count==0) break; - - } while (!ret); - if (ret) break; - } while (count>0); - - fclose(f); - return true; -} +#endif // DEBUG.COM stuff @@ -2275,13 +2257,13 @@ void DEBUG_HeavyWriteLogInstruction(void) { do { // Write Intructions TLogInst & inst = logInst[startLog]; - out << setw(4) << inst.s_cs << ":" << setw(8) << inst.eip << " " + out << setw(4) << inst.s_cs << ":" << setw(8) << inst.eip << " " << inst.dline << " " << inst.res << " EAX:" << setw(8)<< inst.eax << " EBX:" << setw(8) << inst.ebx << " ECX:" << setw(8) << inst.ecx << " EDX:" << setw(8) << inst.edx << " ESI:" << setw(8) << inst.esi << " EDI:" << setw(8) << inst.edi << " EBP:" << setw(8) << inst.ebp << " ESP:" << setw(8) << inst.esp << " DS:" << setw(4) << inst.s_ds - << " ES:" << setw(4) << inst.s_ds<< " FS:" << setw(4) << inst.s_fs + << " ES:" << setw(4) << inst.s_es<< " FS:" << setw(4) << inst.s_fs << " GS:" << setw(4) << inst.s_gs<< " SS:" << setw(4) << inst.s_ss << " CF:" << inst.c << " ZF:" << inst.z << " SF:" << inst.s << " OF:" << inst.o << " AF:" << inst.a << " PF:" << inst.p @@ -2302,13 +2284,11 @@ bool DEBUG_HeavyIsBreakpoint(void) { static Bitu zero_count = 0; if (cpuLog) { if (cpuLogCounter>0) { - static char buffer[4096]; - LogInstruction(SegValue(cs),reg_eip,buffer); - fprintf(cpuLogFile,"%s",buffer); + LogInstruction(SegValue(cs),reg_eip,cpuLogFile); cpuLogCounter--; } if (cpuLogCounter<=0) { - fclose(cpuLogFile); + cpuLogFile.close(); DEBUG_ShowMsg("DEBUG: cpu log LOGCPU.TXT created\n"); cpuLog = false; DEBUG_EnableDebugger(); From e6af839533a9393d4779d98c6059514bdb3eca9d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 19 May 2006 19:53:22 +0000 Subject: [PATCH 2545/4131] a few warnings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2630 --- src/gui/midi_alsa.h | 3 +-- src/gui/midi_oss.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 5d02dc58..8213ff37 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_alsa.h,v 1.13 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: midi_alsa.h,v 1.14 2006-05-19 19:53:22 qbix79 Exp $ */ #define ALSA_PCM_OLD_HW_PARAMS_API #define ALSA_PCM_OLD_SW_PARAMS_API @@ -76,7 +76,6 @@ public: } void PlayMsg(Bit8u * msg) { - unsigned int midiCmd[4]; ev.type = SND_SEQ_EVENT_OSS; ev.data.raw32.d[0] = msg[0]; diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index 20db3944..d2a33f6d 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -25,7 +25,7 @@ private: Bit8u device_num; bool isOpen; public: - MidiHandler_oss() : isOpen(false),MidiHandler() {}; + MidiHandler_oss() : MidiHandler(),isOpen(false) {}; char * GetName(void) { return "oss";}; bool Open(const char * conf) { char devname[512]; From 01c7e8b454eb6e1b1d8c6b34f2fc5f32c91e064a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 21 May 2006 19:21:31 +0000 Subject: [PATCH 2546/4131] set offset of int1 higher (BioMenace fix) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2631 --- src/dos/dos_memory.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index b588961a..3033bcf8 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -414,15 +414,17 @@ void DOS_SetupMemory(void) { * buggy games, which compare against the interrupt table. (probably a * broken linked list implementation) */ callbackhandler.Allocate(&DOS_default_handler,"DOS default int"); - real_writeb(0x70,4,(Bit8u)0xFE); //GRP 4 - real_writeb(0x70,5,(Bit8u)0x38); //Extra Callback instruction - real_writew(0x70,6,callbackhandler.Get_callback()); //The immediate word - real_writeb(0x70,8,(Bit8u)0xCF); //An IRET Instruction - real_writed(0,0x01*4,0x700004); - real_writed(0,0x02*4,0x700004); //BioMenace (segment<0x8000) - real_writed(0,0x03*4,0x700004); //Alien Incident (offset!=0) - real_writed(0,0x04*4,0x700004); //Shadow President (lower byte of segment!=0) -// real_writed(0,0x0f*4,0x700004); //Always a tricky one (soundblaster irq) + Bitu ihseg = 0x70; + Bitu ihofs = 0x08; + real_writeb(ihseg,ihofs+0x00,(Bit8u)0xFE); //GRP 4 + real_writeb(ihseg,ihofs+0x01,(Bit8u)0x38); //Extra Callback instruction + real_writew(ihseg,ihofs+0x02,callbackhandler.Get_callback()); //The immediate word + real_writeb(ihseg,ihofs+0x04,(Bit8u)0xCF); //An IRET Instruction + RealSetVec(0x01,RealMake(ihseg,ihofs)); //BioMenace (offset!=4) + RealSetVec(0x02,RealMake(ihseg,ihofs)); //BioMenace (segment<0x8000) + RealSetVec(0x03,RealMake(ihseg,ihofs)); //Alien Incident (offset!=0) + RealSetVec(0x04,RealMake(ihseg,ihofs)); //Shadow President (lower byte of segment!=0) +// RealSetVec(0x0f,RealMake(ihseg,ihofs)); //Always a tricky one (soundblaster irq) // Create a dummy device MCB with PSPSeg=0x0008 DOS_MCB mcb_devicedummy((Bit16u)DOS_MEM_START); From fc4c24f231246542ca96c88329f6c1a406df126d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 22 May 2006 15:36:28 +0000 Subject: [PATCH 2547/4131] fix scanlength setting for INT10_LoadFont functions (7 Spirits of Ra) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2632 --- src/ints/int10.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 21749b28..2f2c9bbc 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -203,15 +203,19 @@ static Bitu INT10_Handler(void) { break; case 0x01: /* Load 8x14 font */ case 0x11: - INT10_LoadFont(Real2Phys(int10.rom.font_14),true,256,0,0,14); + INT10_LoadFont(Real2Phys(int10.rom.font_14),reg_al==0x11,256,0,0,14); break; case 0x02: /* Load 8x8 font */ case 0x12: - INT10_LoadFont(Real2Phys(int10.rom.font_8_first),true,256,0,0,8); + INT10_LoadFont(Real2Phys(int10.rom.font_8_first),reg_al==0x12,256,0,0,8); break; case 0x03: /* Set Block Specifier */ IO_Write(0x3c4,0x3);IO_Write(0x3c5,reg_bl); break; + case 0x04: /* Load 8x16 font */ + case 0x14: + INT10_LoadFont(Real2Phys(int10.rom.font_16),reg_al==0x14,256,0,0,16); + break; /* Graphics mode calls */ case 0x20: /* Set User 8x8 Graphics characters */ RealSetVec(0x1f,RealMake(SegValue(es),reg_bp)); From 346d4332ab0024ad3667c17fc0897c9da019a982 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 22 May 2006 15:46:13 +0000 Subject: [PATCH 2548/4131] Add cancel "Set event wait interval." Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2633 --- src/ints/bios.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 15185c96..a95d016c 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.58 2006-04-22 15:25:45 c2woody Exp $ */ +/* $Id: bios.cpp,v 1.59 2006-05-22 15:46:13 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -599,7 +599,13 @@ static Bitu INT15_Handler(void) { break; case 0x83: /* BIOS - SET EVENT WAIT INTERVAL */ { - if(reg_al == 0x01) LOG(LOG_BIOS,LOG_WARN)("Bios set event interval cancelled: not handled"); + if(reg_al == 0x01) { /* Cancel it */ + mem_writeb(BIOS_WAIT_FLAG_ACTIVE,0); + IO_Write(0x70,0xb); + IO_Write(0x71,IO_Read(0x71)&~0x40); + CALLBACK_SCF(false); + break; + } if (mem_readb(BIOS_WAIT_FLAG_ACTIVE)) { reg_ah=0x80; CALLBACK_SCF(true); @@ -861,7 +867,7 @@ public: callback[6].Set_RealVec(0x1A); /* INT 1C System Timer tick called from INT 8 */ - callback[7].Install(&INT1C_Handler,CB_IRET,"Int 1c Timer tick"); + callback[7].Install(&INT1C_Handler,CB_IRET,"Int 1c Timer"); callback[7].Set_RealVec(0x1C); /* IRQ 8 RTC Handler */ From 1f016f780109a6f454f4a651d7bc1c2aba916589 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 22 May 2006 20:29:50 +0000 Subject: [PATCH 2549/4131] Add zeroprotect option to detect zero code protection. (disabled by default because it might trigger pagefaults in an odd way) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2634 --- src/debug/debug.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index d6b5a53f..06d492fd 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.78 2006-05-19 13:35:32 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.79 2006-05-22 20:29:50 qbix79 Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -96,7 +96,6 @@ class DEBUG; DEBUG* pDebugcom = 0; bool exitLoop = false; -bool logHeavy = false; // Heavy Debugging Vars for logging @@ -105,6 +104,8 @@ static ofstream cpuLogFile; static bool cpuLog = false; static int cpuLogCounter = 0; static int cpuLogType = 1; // log detail +static bool zeroProtect = false; +bool logHeavy = false; #endif @@ -1266,6 +1267,13 @@ bool ParseCommand(char* str) else DEBUG_ShowMsg("DEBUG: Heavy cpu logging off.\n"); return true; } + found = strstr(str,"ZEROPROTECT"); + if (found) { //toggle zero protection + zeroProtect = !zeroProtect; + if (zeroProtect) DEBUG_ShowMsg("DEBUG: Zero code execution protection on.\n"); + else DEBUG_ShowMsg("DEBUG: Zero code execution protection off.\n"); + return true; + } #endif if ((*str=='H') || (*str=='?')) { DEBUG_ShowMsg("Debugger keys:\n"); @@ -1296,6 +1304,7 @@ bool ParseCommand(char* str) DEBUG_ShowMsg("LOG [num] - Write cpu log file.\n"); DEBUG_ShowMsg("LOGS/LOGL [num] - Write short/long cpu log file.\n"); DEBUG_ShowMsg("HEAVYLOG - Enable/Disable automatic cpu when dosbox exits.\n"); + DEBUG_ShowMsg("ZEROPROTECT - Enable/Disable zero code execution detecion.\n"); #endif DEBUG_ShowMsg("SR [reg] [value] - Set register value.\n"); DEBUG_ShowMsg("SM [seg]:[off] [val] [.]..- Set memory with following values.\n"); @@ -2297,8 +2306,8 @@ bool DEBUG_HeavyIsBreakpoint(void) { } // LogInstruction if (logHeavy) DEBUG_HeavyLogInstruction(); - if(mem_readd(SegPhys(cs) + reg_eip) == 0) zero_count++; else zero_count = 0; - if(zero_count == 10) E_Exit("running zeroed code"); + if(zeroProtect && mem_readd(SegPhys(cs) + reg_eip) == 0) zero_count++; else zero_count = 0; + if(zeroProtect && GCC_UNLIKELY(zero_count == 10)) E_Exit("running zeroed code"); if (skipFirstInstruction) { skipFirstInstruction = false; From 796af47e749faa34b2362215fdf942b08b55f108 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 23 May 2006 10:30:02 +0000 Subject: [PATCH 2550/4131] Move irq 2/9 to a different location. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2635 --- src/hardware/pic.cpp | 23 +---------------------- src/ints/bios.cpp | 24 ++++++++++++++++++------ 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index bc1a67a7..9a1a9866 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.34 2006-03-12 21:14:45 qbix79 Exp $ */ +/* $Id: pic.cpp,v 1.35 2006-05-23 10:30:02 qbix79 Exp $ */ #include @@ -452,20 +452,6 @@ bool PIC_RunQueue(void) { return true; } -//Irq 9-2 calling code -static Bitu INT71_Handler() { - IO_Write(0xa0,0x61); - CALLBACK_RunRealInt(0xa); - return CBRET_NONE; -} - -static Bitu INT0A_Handler() { - IO_Write(0x20,0x62); - return CBRET_NONE; -} - - - /* The TIMER Part */ struct TickerBlock { TIMER_TickHandler handler; @@ -522,7 +508,6 @@ class PIC:public Module_base{ private: IO_ReadHandleObject ReadHandler[4]; IO_WriteHandleObject WriteHandler[4]; - CALLBACK_HandlerObject callback[2]; public: PIC(Section* configuration):Module_base(configuration){ /* Setup pic0 and pic1 with initial values like DOS has normally */ @@ -575,12 +560,6 @@ public: pic.entries[PIC_QUEUESIZE-1].next=0; pic.free_entry=&pic.entries[0]; pic.next_entry=0; - /* Irq 9 and 2 thingie - * Should be done by bios but then it overwrites the mpu handler */ - callback[0].Install(&INT71_Handler,CB_IRET,"irq 9 bios"); - callback[0].Set_RealVec(0x71); - callback[1].Install(&INT0A_Handler,CB_IRET,"irq 2 bios"); - callback[1].Set_RealVec(0xA); } ~PIC(){ } diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index a95d016c..d9751bfb 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.59 2006-05-22 15:46:13 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.60 2006-05-23 10:30:02 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -61,6 +61,12 @@ static Bitu INT70_Handler(void) { IO_Write(0x20,0x20); return 0; } +// Irq 9 calls irq 2 +static Bitu INT71_Handler() { + IO_Write(0xa0,0x61); + CALLBACK_RunRealInt(0xa); + return CBRET_NONE; +} CALLBACK_HandlerObject* tandy_DAC_callback; static struct { @@ -813,7 +819,7 @@ void BIOS_SetupDisks(void); class BIOS:public Module_base{ private: - CALLBACK_HandlerObject callback[9]; + CALLBACK_HandlerObject callback[10]; public: BIOS(Section* configuration):Module_base(configuration){ /* tandy DAC can be requested in tandy_sound.cpp by initializing this field */ @@ -874,6 +880,16 @@ public: callback[8].Install(&INT70_Handler,CB_IRET,"Int 70 RTC"); callback[8].Set_RealVec(0x70); + /* Irq 9 routed to irq 2 (which is an iret at f000:ff53) */ + callback[9].Install(&INT71_Handler,CB_IRET,"irq 9 bios"); + callback[9].Set_RealVec(0x71); + + /* Some hardcoded vectors */ + phys_writeb(0xfff53,0xcf); /* bios default interrupt vector location */ + phys_writeb(0xfe987,0xea); /* original IRQ1 location (Defender booter) */ + phys_writed(0xfe988,RealGetVec(0x09)); + RealSetVec(0xA,0xf000ff53); /* Ghost busters 2 mt32 mode */ + if (machine==MCH_TANDY) phys_writeb(0xffffe,0xff) ; /* Tandy model */ else if (machine==MCH_PCJR) phys_writeb(0xffffe,0xfd); /* PCJr model */ else phys_writeb(0xffffe,0xfc); /* PC */ @@ -980,10 +996,6 @@ public: IO_Write(0x70,0x31); size_extended|=(IO_Read(0x71) << 8); - phys_writeb(0xfff53,0xcf); /* bios default interrupt vector location */ - phys_writeb(0xfe987,0xea); /* original IRQ1 location (Defender booter) */ - phys_writed(0xfe988,RealGetVec(0x09)); - if (machine==MCH_PCJR) PIC_AddEvent(RAMRefresh_Event,RAM_REFRESH_DELAY); } ~BIOS(){ From e065bf63d2e5965c800bba6478422b05cc276649 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 23 May 2006 10:30:29 +0000 Subject: [PATCH 2551/4131] Add fast irq for it came from the desert. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2636 --- src/hardware/mpu401.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index f9d1c0d2..333119c9 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.20 2006-03-19 10:24:59 qbix79 Exp $ */ +/* $Id: mpu401.cpp,v 1.21 2006-05-23 10:30:29 qbix79 Exp $ */ #include #include "dosbox.h" @@ -238,6 +238,10 @@ static void MPU401_WriteCommand(Bitu port,Bitu val,Bitu iolen) { case 0xff: /* Reset MPU-401 */ LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Reset %X",val); mpu.state.reset=1; + if (CPU_Cycles > 5) { //It came from the desert wants a fast irq + CPU_CycleLeft += CPU_Cycles; + CPU_Cycles = 5; + } MPU401_Reset(); break; case 0x3f: /* UART mode */ From a11f305138b60918c1543b46e7ac617755cda866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 24 May 2006 16:39:29 +0000 Subject: [PATCH 2552/4131] fix FindFirst for files in the root directory of the virtual drive (SimHospital) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2637 --- src/dos/drive_virtual.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 1c37f705..19c52d46 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -203,9 +203,14 @@ bool Virtual_Drive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) { search_file=first_file; Bit8u attr;char pattern[DOS_NAMELENGTH_ASCII]; dta.GetSearchParams(attr,pattern); - if(attr & DOS_ATTR_VOLUME) { + if (attr == DOS_ATTR_VOLUME) { dta.SetResult("DOSBOX",0,0,0,DOS_ATTR_VOLUME); return true; + } else if ((attr & DOS_ATTR_VOLUME) && !fcb_findfirst) { + if (WildFileCmp("DOSBOX",pattern)) { + dta.SetResult("DOSBOX",0,0,0,DOS_ATTR_VOLUME); + return true; + } } return FindNext(dta); } From c02188b774772f6b81a1bcb10f5b17c71fa775a9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 25 May 2006 15:07:33 +0000 Subject: [PATCH 2553/4131] Add shift and more const correctness Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2638 --- include/setup.h | 50 ++++++++++++++++++---------------- src/misc/setup.cpp | 67 +++++++++++++++++++++++++--------------------- 2 files changed, 64 insertions(+), 53 deletions(-) diff --git a/include/setup.h b/include/setup.h index b3475e09..76792a6e 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.24 2006-04-10 12:06:25 qbix79 Exp $ */ +/* $Id: setup.h,v 1.25 2006-05-25 15:07:32 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -46,6 +46,7 @@ public: bool FindStringRemain(char const * const name,std::string & value); bool GetStringRemain(std::string & value); unsigned int GetCount(void); + void Shift(unsigned int amount=1); private: typedef std::list::iterator cmd_it; std::list cmds; @@ -65,8 +66,8 @@ class Property { public: Property(char const * const _propname):propname(_propname) { } virtual void SetValue(char* input)=0; - virtual void GetValuestring(char* str)=0; - Value GetValue() { return value;} + virtual void GetValuestring(char* str) const=0; + Value GetValue() const { return value;} virtual ~Property(){ } std::string propname; Value value; @@ -78,7 +79,7 @@ public: value._int=_value; } void SetValue(char* input); - void GetValuestring(char* str); + void GetValuestring(char* str) const; ~Prop_int(){ } }; class Prop_float:public Property { @@ -87,7 +88,7 @@ public: value._float=_value; } void SetValue(char* input); - void GetValuestring(char* str); + void GetValuestring(char* str) const; ~Prop_float(){ } }; @@ -97,7 +98,7 @@ public: value._bool=_value; } void SetValue(char* input); - void GetValuestring(char* str); + void GetValuestring(char* str) const; ~Prop_bool(){ } }; @@ -110,7 +111,7 @@ public: delete value._string; } void SetValue(char* input); - void GetValuestring(char* str); + void GetValuestring(char* str) const; }; class Prop_hex:public Property { public: @@ -119,7 +120,7 @@ public: } void SetValue(char* input); ~Prop_hex(){ } - void GetValuestring(char* str); + void GetValuestring(char* str) const; }; class Section { @@ -145,11 +146,11 @@ public: void AddDestroyFunction(SectionFunction func,bool canchange=false) {destroyfunctions.push_front(Function_wrapper(func,canchange));} void ExecuteInit(bool initall=true); void ExecuteDestroy(bool destroyall=true); - const char* GetName() {return sectionname.c_str();} + const char* GetName() const {return sectionname.c_str();} - virtual char const * GetPropValue(char const * const _property)=0; + virtual char const * GetPropValue(char const * const _property) const =0; virtual void HandleInputline(char * _line)=0; - virtual void PrintData(FILE* outfile)=0; + virtual void PrintData(FILE* outfile) const =0; virtual ~Section() { /*Children must call executedestroy ! */} }; @@ -158,6 +159,7 @@ class Section_prop:public Section { private: std::list properties; typedef std::list::iterator it; + typedef std::list::const_iterator const_it; public: Section_prop(char const * const _sectionname):Section(_sectionname){} void Add_int(char const * const _propname, int _value=0); @@ -166,14 +168,14 @@ public: void Add_hex(char const * const _propname, int _value=0); void Add_float(char const * const _propname, float _value=0.0); - int Get_int(char const * const _propname); - const char* Get_string(char const * const _propname); - bool Get_bool(char const * const _propname); - int Get_hex(char const * const _propname); - float Get_float(char const * const _propname); + int Get_int(char const * const _propname) const; + const char* Get_string(char const * const _propname) const; + bool Get_bool(char const * const _propname) const; + int Get_hex(char const * const _propname) const; + float Get_float(char const * const _propname) const; void HandleInputline(char *gegevens); - void PrintData(FILE* outfile); - virtual char const * GetPropValue(char const * const _property); + void PrintData(FILE* outfile) const; + virtual char const * GetPropValue(char const * const _property) const; //ExecuteDestroy should be here else the destroy functions use destroyed properties virtual ~Section_prop(); }; @@ -183,8 +185,8 @@ public: Section_line(char const * const _sectionname):Section(_sectionname){} ~Section_line(){ExecuteDestroy(true);} void HandleInputline(char* gegevens); - void PrintData(FILE* outfile); - virtual const char* GetPropValue(char const * const _property); + void PrintData(FILE* outfile) const; + virtual const char* GetPropValue(char const * const _property) const; std::string data; }; @@ -195,6 +197,8 @@ private: std::list sectionlist; typedef std::list::iterator it; typedef std::list::reverse_iterator reverse_it; + typedef std::list::const_iterator const_it; + typedef std::list::const_reverse_iterator const_reverse_it; void (* _start_function)(void); public: Config(CommandLine * cmd):cmdline(cmd){} @@ -203,14 +207,14 @@ public: 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(char const* const _sectionname); - Section* GetSectionFromProperty(char const * const prop); + Section* GetSection(char const* const _sectionname) const; + Section* GetSectionFromProperty(char const * const prop) const; void SetStartUp(void (*_function)(void)); void Init(); void ShutDown(); void StartUp(); - void PrintConfig(char const * const configfilename); + void PrintConfig(char const * const configfilename) const; bool ParseConfigFile(char const * const configfilename); void ParseEnv(char ** envp); }; diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index f3bcdd7a..ea8a368c 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.35 2006-04-10 12:06:07 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.36 2006-05-25 15:07:33 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -59,23 +59,23 @@ void Prop_hex::SetValue(char* input){ if(!sscanf(input,"%X",&(value._hex))) value._hex=0; } -void Prop_int::GetValuestring(char* str){ +void Prop_int::GetValuestring(char* str) const{ sprintf(str,"%d",value._int); } -void Prop_string::GetValuestring(char* str){ +void Prop_string::GetValuestring(char* str) const{ sprintf(str,"%s",value._string->c_str()); } -void Prop_bool::GetValuestring(char* str){ +void Prop_bool::GetValuestring(char* str) const{ sprintf(str,"%s",value._bool?"true":"false"); } -void Prop_float::GetValuestring(char* str){ +void Prop_float::GetValuestring(char* str) const { sprintf(str,"%1.2f",value._float); } -void Prop_hex::GetValuestring(char* str){ +void Prop_hex::GetValuestring(char* str) const { sprintf(str,"%X",value._hex); } @@ -103,8 +103,8 @@ void Section_prop::Add_hex(const char* _propname, int _value) { Property* test=new Prop_hex(_propname,_value); properties.push_back(test); } -int Section_prop::Get_int(char const * const _propname){ - for(it tel=properties.begin();tel!=properties.end();tel++){ +int Section_prop::Get_int(char const * const _propname) const { + for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ return ((*tel)->GetValue())._int; } @@ -112,16 +112,16 @@ int Section_prop::Get_int(char const * const _propname){ return 0; } -bool Section_prop::Get_bool(char const * const _propname){ - for(it tel=properties.begin();tel!=properties.end();tel++){ +bool Section_prop::Get_bool(char const * const _propname) const { + for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ return ((*tel)->GetValue())._bool; } } return false; } -float Section_prop::Get_float(char const * const _propname){ - for(it tel=properties.begin();tel!=properties.end();tel++){ +float Section_prop::Get_float(char const * const _propname) const { + for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ return ((*tel)->GetValue())._float; } @@ -129,16 +129,16 @@ float Section_prop::Get_float(char const * const _propname){ return false; } -const char* Section_prop::Get_string(char const * const _propname){ - for(it tel=properties.begin();tel!=properties.end();tel++){ +const char* Section_prop::Get_string(char const * const _propname) const { + for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ return ((*tel)->GetValue())._string->c_str(); } } return ""; } -int Section_prop::Get_hex(char const * const _propname){ - for(it tel=properties.begin();tel!=properties.end();tel++){ +int Section_prop::Get_hex(char const * const _propname) const { + for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ return ((*tel)->GetValue())._hex; } @@ -160,18 +160,18 @@ void Section_prop::HandleInputline(char *gegevens){ } -void Section_prop::PrintData(FILE* outfile){ +void Section_prop::PrintData(FILE* outfile) const { char temp[1000]; /* Should be enough for the properties */ /* Now print out the individual section entries */ - for(it tel=properties.begin();tel!=properties.end();tel++){ + for(const_it tel=properties.begin();tel!=properties.end();tel++){ (*tel)->GetValuestring(temp); fprintf(outfile,"%s=%s\n",(*tel)->propname.c_str(),temp); } } static char buffer[1024]; -char const * Section_prop::GetPropValue(char const * const _property) { - for(it tel=properties.begin();tel!=properties.end();tel++){ +char const * Section_prop::GetPropValue(char const * const _property) const{ + for(const_it tel=properties.begin();tel!=properties.end();tel++){ if(!strcasecmp((*tel)->propname.c_str(),_property)){ (*tel)->GetValuestring(buffer); return buffer; @@ -185,19 +185,19 @@ void Section_line::HandleInputline(char* line){ data+="\n"; } -void Section_line::PrintData(FILE* outfile) { +void Section_line::PrintData(FILE* outfile) const { fprintf(outfile,"%s",data.c_str()); } -char const* Section_line::GetPropValue(char const * const /* _property*/) { +char const* Section_line::GetPropValue(char const * const /* _property*/) const { return NULL; } -void Config::PrintConfig(char const * const configfilename){ +void Config::PrintConfig(char const * const configfilename) const { char temp[50];char helpline[256]; FILE* outfile=fopen(configfilename,"w+t"); if(outfile==NULL) return; - for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ + for (const_it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ /* Print out the Section header */ strcpy(temp,(*tel)->GetName()); lowcase(temp); @@ -247,8 +247,8 @@ Section_line* Config::AddSection_line(char const * const _name,void (*_initfunct } -void Config::Init(){ - for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ +void Config::Init() { + for (const_it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ (*tel)->ExecuteInit(); } } @@ -278,15 +278,15 @@ Config::~Config() { } } -Section* Config::GetSection(char const * const _sectionname){ - for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ +Section* Config::GetSection(char const * const _sectionname) const{ + for (const_it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ if (!strcasecmp((*tel)->GetName(),_sectionname)) return (*tel); } return NULL; } -Section* Config::GetSectionFromProperty(char const * const prop){ - for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ +Section* Config::GetSectionFromProperty(char const * const prop) const{ + for (const_it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ if ((*tel)->GetPropValue(prop)) return (*tel); } return NULL; @@ -506,3 +506,10 @@ CommandLine::CommandLine(char const * const name,char const * const cmdline) { } if (inword || inquote) cmds.push_back(str); } + +void CommandLine::Shift(unsigned int amount) { + while(amount--) { + file_name = cmds.size()?(*(cmds.begin())):""; + if(cmds.size()) cmds.erase(cmds.begin()); + } +} From 1303deba3559d085570c8e899e729d5383a06a1e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 25 May 2006 15:08:40 +0000 Subject: [PATCH 2554/4131] add shift. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2639 --- include/shell.h | 10 ++++++---- src/shell/shell.cpp | 5 +++-- src/shell/shell_batch.cpp | 5 ++++- src/shell/shell_cmds.cpp | 6 +++++- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/include/shell.h b/include/shell.h index ec609c25..fbc7c80b 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.15 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: shell.h,v 1.16 2006-05-25 15:08:40 qbix79 Exp $ */ #ifndef DOSBOX_SHELL_H #define DOSBOX_SHELL_H @@ -48,6 +48,7 @@ public: ~BatchFile(); bool ReadLine(char * line); bool Goto(char * where); + void Shift(void); Bit16u file_handle; bool echo; DOS_Shell * shell; @@ -104,6 +105,7 @@ public: void CMD_CHOICE(char * args); void CMD_ATTRIB(char * args); void CMD_PATH(char * args); + void CMD_SHIFT(char * /*args*/); /* The shell's variables */ Bit16u input_handle; BatchFile * bf; @@ -113,10 +115,10 @@ public: }; struct SHELL_Cmd { - const char * name; /* Command name*/ + 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 */ + void (DOS_Shell::*handler)(char * args); /* Handler for this command */ + const char * help; /* String with command help */ }; static inline void StripSpaces(char*&args) { diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 855bacee..3d4f1f6f 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.73 2006-04-29 10:05:55 c2woody Exp $ */ +/* $Id: shell.cpp,v 1.74 2006-05-25 15:08:40 qbix79 Exp $ */ #include #include @@ -320,7 +320,7 @@ void DOS_Shell::Run(void) { if (echo) ShowPrompt(); InputCommand(input_line); ParseLine(input_line); - if (echo) WriteOut("\n"); + if (echo && !bf) WriteOut("\n"); } } while (!exit); } @@ -496,6 +496,7 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_SET_HELP","Change environment variables.\n"); MSG_Add("SHELL_CMD_IF_HELP","Performs conditional processing in batch programs.\n"); MSG_Add("SHELL_CMD_GOTO_HELP","Jump to a labeled line in a batch script.\n"); + MSG_Add("SHELL_CMD_SHIFT_HELP","Leftshift commandline parameters in a batch script.\n"); MSG_Add("SHELL_CMD_TYPE_HELP","Display the contents of a text-file.\n"); MSG_Add("SHELL_CMD_REM_HELP","Add comments in a batch file.\n"); MSG_Add("SHELL_CMD_NO_WILD","This is a simple version of the command, no wildcards allowed!\n"); diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 952dd348..b151a7ab 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.20 2006-02-23 08:13:14 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.21 2006-05-25 15:08:40 qbix79 Exp $ */ #include #include @@ -149,3 +149,6 @@ again: goto again; return false; }; +void BatchFile::Shift(void) { + cmd->Shift(1); +} diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index d84e815b..489101d7 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.66 2006-04-23 15:17:07 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.67 2006-05-25 15:08:40 qbix79 Exp $ */ #include #include @@ -46,6 +46,7 @@ static SHELL_Cmd cmd_list[]={ { "SET", 0, &DOS_Shell::CMD_SET, "SHELL_CMD_SET_HELP"}, { "IF", 0, &DOS_Shell::CMD_IF, "SHELL_CMD_IF_HELP"}, { "GOTO", 0, &DOS_Shell::CMD_GOTO, "SHELL_CMD_GOTO_HELP"}, +{ "SHIFT", 0, &DOS_Shell::CMD_SHIFT, "SHELL_CMD_SHIFT_HELP"}, { "TYPE", 0, &DOS_Shell::CMD_TYPE, "SHELL_CMD_TYPE_HELP"}, { "REM", 0, &DOS_Shell::CMD_REM, "SHELL_CMD_REM_HELP"}, { "RENAME", 0, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP"}, @@ -670,6 +671,9 @@ void DOS_Shell::CMD_GOTO(char * args) { } } +void DOS_Shell::CMD_SHIFT(char * /*args*/ ) { + if(bf) bf->Shift(); +} void DOS_Shell::CMD_TYPE(char * args) { StripSpaces(args); From 21ae8be729c76c9270ed3b53790773a19f858ad2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 27 May 2006 07:01:33 +0000 Subject: [PATCH 2555/4131] Fix a typo. Thanks ykhwong\! Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2640 --- src/gui/render.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 5dc43920..1800461c 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.45 2006-03-29 14:17:27 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.46 2006-05-27 07:01:33 qbix79 Exp $ */ #include #include @@ -446,8 +446,8 @@ void RENDER_Init(Section * sec) { else if (!strcasecmp(scaler,"normal3x")) { render.scale.op = scalerOpNormal;render.scale.size = 3; } else if (!strcasecmp(scaler,"advmame2x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 2; } else if (!strcasecmp(scaler,"advmame3x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 3; } - else if (!strcasecmp(scaler,"advinterp2x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 2; } - else if (!strcasecmp(scaler,"advinterp3x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 3; } + else if (!strcasecmp(scaler,"advinterp2x")) { render.scale.op = scalerOpAdvInterp;render.scale.size = 2; } + else if (!strcasecmp(scaler,"advinterp3x")) { render.scale.op = scalerOpAdvInterp;render.scale.size = 3; } else if (!strcasecmp(scaler,"tv2x")) { render.scale.op = scalerOpTV;render.scale.size = 2; } else if (!strcasecmp(scaler,"tv3x")) { render.scale.op = scalerOpTV;render.scale.size = 3; } else if (!strcasecmp(scaler,"rgb2x")){ render.scale.op = scalerOpRGB;render.scale.size = 2; } From b950bf43ba1a6d64fe9664a34f253bf6ea39b820 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 28 May 2006 09:40:42 +0000 Subject: [PATCH 2556/4131] 2 small patches from h-a-l-9000. Joystick equimentbit. Don't change drive when there none mounted. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2641 --- src/dos/dos_files.cpp | 4 ++-- src/ints/bios.cpp | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 0b1246b9..0eedde22 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.73 2006-04-23 14:20:57 c2woody Exp $ */ +/* $Id: dos_files.cpp,v 1.74 2006-05-28 09:40:42 qbix79 Exp $ */ #include #include @@ -49,7 +49,7 @@ Bit8u DOS_GetDefaultDrive(void) { } void DOS_SetDefaultDrive(Bit8u drive) { - if (drive<=DOS_DRIVES) dos.current_drive=drive; + if (drive<=DOS_DRIVES && Drives[drive]) dos.current_drive = drive; } bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index d9751bfb..3efd14b2 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.60 2006-05-23 10:30:02 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.61 2006-05-28 09:40:42 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -988,6 +988,8 @@ public: } // PS2 mouse config |= 0x04; + // Gameport + config |= 0x1000; mem_writew(BIOS_CONFIGURATION,config); CMOS_SetRegister(0x14,config); //Should be updated on changes /* Setup extended memory size */ From 857ba79484f197e1deff7ebb1c0c548b8e3a6e07 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 31 May 2006 14:22:00 +0000 Subject: [PATCH 2557/4131] put sensible data in date and time when opening a file. Fixes Operation Innerspace. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2642 --- src/dos/drive_fat.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 3373476f..2183a2fc 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.14 2006-04-23 14:20:58 c2woody Exp $ */ +/* $Id: drive_fat.cpp,v 1.15 2006-05-31 14:22:00 qbix79 Exp $ */ #include #include @@ -738,7 +738,9 @@ bool fatDrive::FileCreate(DOS_File **file, char *name, Bit16u attributes) { *file = new fatFile(name, fileEntry.loFirstClust, fileEntry.entrysize, this); ((fatFile *)(*file))->dirCluster = dirClust; ((fatFile *)(*file))->dirIndex = subEntry; - + /* Maybe modTime and date should be used ? (crt matches findnext) */ + ((fatFile *)(*file))->time = fileEntry.crtTime; + ((fatFile *)(*file))->date = fileEntry.crtDate; return true; } @@ -757,7 +759,9 @@ bool fatDrive::FileOpen(DOS_File **file, char *name, Bit32u flags) { *file = new fatFile(name, fileEntry.loFirstClust, fileEntry.entrysize, this); ((fatFile *)(*file))->dirCluster = dirClust; ((fatFile *)(*file))->dirIndex = subEntry; - + /* Maybe modTime and date should be used ? (crt matches findnext) */ + ((fatFile *)(*file))->time = fileEntry.crtTime; + ((fatFile *)(*file))->date = fileEntry.crtDate; return true; } From 73126067963fd0f2b4ff7344dcbd2cdf88e07e6b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 1 Jun 2006 06:44:22 +0000 Subject: [PATCH 2558/4131] Typos. (ykhwong) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2643 --- src/dos/dos_programs.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 4479a3d5..f0eef1a0 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.60 2006-05-01 14:56:35 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.61 2006-06-01 06:44:22 qbix79 Exp $ */ #include #include @@ -243,7 +243,7 @@ public: return; } if (Drives[drive-'A']) { - WriteOut(MSG_Get("PROGRAM_MOUNT_ALLREADY_MOUNTED"),drive,Drives[drive-'A']->GetInfo()); + WriteOut(MSG_Get("PROGRAM_MOUNT_ALREADY_MOUNTED"),drive,Drives[drive-'A']->GetInfo()); if (newdrive) delete newdrive; return; } @@ -739,7 +739,7 @@ public: Bit8u dummy; if (!DOS_MakeName(tmp, fullname, &dummy) || strncmp(Drives[dummy]->GetInfo(),"local directory",15)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNG_FILE_NOT_FOUND")); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FILE_NOT_FOUND")); return; } @@ -748,13 +748,13 @@ public: temp_line = tmp; if (stat(temp_line.c_str(),&test)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNG_FILE_NOT_FOUND")); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FILE_NOT_FOUND")); return; } } if ((test.st_mode & S_IFDIR)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNG_MOUNT")); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MOUNT")); return; } @@ -796,7 +796,7 @@ public: if(fstype=="fat") { if (Drives[drive-'A']) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_ALLREADY_MOUNTED")); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_ALREADY_MOUNTED")); if (newdrive) delete newdrive; return; } @@ -822,7 +822,7 @@ public: } } else if (fstype=="iso") { if (Drives[drive-'A']) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_ALLREADY_MOUNTED")); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_ALREADY_MOUNTED")); if (newdrive) delete newdrive; return; } @@ -858,7 +858,7 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_MOUNT_ERROR_1","Directory %s doesn't exist.\n"); MSG_Add("PROGRAM_MOUNT_ERROR_2","%s isn't a directory\n"); MSG_Add("PROGRAM_MOUNT_ILL_TYPE","Illegal type %s\n"); - MSG_Add("PROGRAM_MOUNT_ALLREADY_MOUNTED","Drive %c already mounted with %s\n"); + MSG_Add("PROGRAM_MOUNT_ALREADY_MOUNTED","Drive %c already mounted with %s\n"); MSG_Add("PROGRAM_MOUNT_USAGE","Usage \033[34;1mMOUNT Drive-Letter Local-Directory\033[0m\nSo a MOUNT c c:\\windows mounts windows directory as the c: drive in DOSBox\n"); MSG_Add("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED","Drive %c isn't mounted.\n"); MSG_Add("PROGRAM_MOUNT_UMOUNT_SUCCES","Drive %c has succesfully been removed.\n"); @@ -1009,9 +1009,9 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_IMGMOUNT_TYPE_UNSUPPORTED","Type \"%s\" is unsupported. Specify \"hdd\" or \"floppy\" or\"iso\".\n"); MSG_Add("PROGRAM_IMGMOUNT_FORMAT_UNSUPPORTED","Format \"%s\" is unsupported. Specify \"fat\" or \"iso\" or \"none\".\n"); MSG_Add("PROGRAM_IMGMOUNT_SPECIFY_FILE","Must specify file-image to mount.\n"); - MSG_Add("PROGRAM_IMGMOUNG_FILE_NOT_FOUND","Image file not found.\n"); - MSG_Add("PROGRAM_IMGMOUNG_MOUNT","To mount directories, use the \033[34;1mMOUNT\033[0m command, not the \033[34;1mIMGMOUNT\033[0m command.\n"); - MSG_Add("PROGRAM_IMGMOUNT_ALLREADY_MOUNTED","Drive already mounted at that letter.\n"); + MSG_Add("PROGRAM_IMGMOUNT_FILE_NOT_FOUND","Image file not found.\n"); + MSG_Add("PROGRAM_IMGMOUNT_MOUNT","To mount directories, use the \033[34;1mMOUNT\033[0m command, not the \033[34;1mIMGMOUNT\033[0m command.\n"); + MSG_Add("PROGRAM_IMGMOUNT_ALREADY_MOUNTED","Drive already mounted at that letter.\n"); MSG_Add("PROGRAM_IMGMOUNT_CANT_CREATE","Can't create drive from file.\n"); MSG_Add("PROGRAM_IMGMOUNT_MOUNT_NUMBER","Drive number %d mounted as %s\n"); From 3500ea88eb54e697b532bbdaf299aeef4a3c6303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 1 Jun 2006 08:33:52 +0000 Subject: [PATCH 2559/4131] remove more fpu exception flags and refine fpu statusword updates; add a more direct calling of fpu functions (dynamic core, thanks to kekko!); avoid temporary storing of fpu values for eatree functions (x86 fpu only) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2644 --- include/fpu.h | 111 ++++++++ src/cpu/core_dyn_x86/Makefile.am | 3 +- src/cpu/core_dyn_x86/decoder.h | 33 +++ src/fpu/Makefile.am | 2 +- src/fpu/fpu.cpp | 99 ++----- src/fpu/fpu_instructions.h | 41 ++- src/fpu/fpu_instructions_x86.h | 447 ++++++++++++++++++++++++++++++- visualc_net/dosbox.vcproj | 26 +- 8 files changed, 657 insertions(+), 105 deletions(-) diff --git a/include/fpu.h b/include/fpu.h index 6bea5cef..448ba5db 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -40,4 +40,115 @@ 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); + +INLINE void FPU_SetTag(Bit16u tag){ + for(Bitu i=0;i<8;i++) + fpu.tags[i] = static_cast((tag >>(2*i))&3); +} + +INLINE void FPU_SetCW(Bitu word){ + fpu.cw = word; + fpu.cw_mask_all = word | 0x3f; + fpu.round = (FPU_Round)((word >> 10) & 3); +} + + +INLINE Bitu FPU_GET_TOP(void) { + return (fpu.sw & 0x3800)>>11; +} + +INLINE void FPU_SET_TOP(Bitu val){ + fpu.sw &= ~0x3800; + fpu.sw |= (val&7)<<11; +} + + +INLINE void FPU_SET_C0(Bitu C){ + fpu.sw &= ~0x0100; + if(C) fpu.sw |= 0x0100; +} + +INLINE void FPU_SET_C1(Bitu C){ + fpu.sw &= ~0x0200; + if(C) fpu.sw |= 0x0200; +} + +INLINE void FPU_SET_C2(Bitu C){ + fpu.sw &= ~0x0400; + if(C) fpu.sw |= 0x0400; +} + +INLINE void FPU_SET_C3(Bitu C){ + fpu.sw &= ~0x4000; + if(C) fpu.sw |= 0x4000; +} + + #endif diff --git a/src/cpu/core_dyn_x86/Makefile.am b/src/cpu/core_dyn_x86/Makefile.am index ad1008a7..8c432515 100644 --- a/src/cpu/core_dyn_x86/Makefile.am +++ b/src/cpu/core_dyn_x86/Makefile.am @@ -1 +1,2 @@ -noinst_HEADERS = cache.h helpers.h decoder.h risc_x86.h string.h \ No newline at end of file +noinst_HEADERS = cache.h helpers.h decoder.h risc_x86.h string.h \ + dyn_fpu.h \ No newline at end of file diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 9be546ae..7d1baa13 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define X86_DYNFPU + #include "fpu.h" #define DYN_FPU_ESC(code) { \ dyn_get_modrm(); \ @@ -1223,6 +1225,10 @@ static void dyn_add_iocheck_var(Bit8u accessed_port,Bitu access_size) { } } +#ifdef X86_DYNFPU +#include "dyn_fpu.h" +#endif + static CacheBlock * CreateCacheBlock(CodePageHandler * codepage,PhysPt start,Bitu max_opcodes) { Bits i; /* Init a load of variables */ @@ -1568,6 +1574,32 @@ restart_prefix: case 0xd3:dyn_grp2_ev(grp2_cl);break; //FPU #ifdef CPU_FPU +#ifdef X86_DYNFPU + 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; +#else case 0xd8: DYN_FPU_ESC(0); break; @@ -1600,6 +1632,7 @@ restart_prefix: gen_releasereg(DREG(EA)); } break; +#endif #endif //Loop's case 0xe2:dyn_loop(LOOP_NONE);goto finish_block; diff --git a/src/fpu/Makefile.am b/src/fpu/Makefile.am index d081a682..541d5a46 100644 --- a/src/fpu/Makefile.am +++ b/src/fpu/Makefile.am @@ -1,5 +1,5 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libfpu.a -libfpu_a_SOURCES = fpu.cpp fpu_types.h fpu_instructions.h \ +libfpu_a_SOURCES = fpu.cpp fpu_instructions.h \ fpu_instructions_x86.h diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 69872c0b..ef57cf88 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu.cpp,v 1.27 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: fpu.cpp,v 1.28 2006-06-01 08:33:52 c2woody Exp $ */ #include "dosbox.h" #if C_FPU @@ -28,74 +28,20 @@ #include "fpu.h" #include "cpu.h" -typedef PhysPt EAPoint; +FPU_rec fpu; -#define TOP fpu.top -#define STV(i) ( (fpu.top+ (i) ) & 7 ) - -#define LoadMb(off) mem_readb(off) -#define LoadMw(off) mem_readw(off) -#define LoadMd(off) mem_readd(off) - -#define SaveMb(off,val) mem_writeb(off,val) -#define SaveMw(off,val) mem_writew(off,val) -#define SaveMd(off,val) mem_writed(off,val) - -#include "fpu_types.h" - -static 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; - -INLINE void FPU_SetCW(Bitu word){ - fpu.cw = word; - fpu.cw_mask_all = word | 0x3f; - fpu.round = (FPU_Round)((word >> 10) & 3); +void FPU_FLDCW(PhysPt addr){ + Bit16u temp = mem_readw(addr); + FPU_SetCW(temp); } - -static Bit16u FPU_GetTag(void){ + +Bit16u FPU_GetTag(void){ Bit16u tag=0; for(Bitu i=0;i<8;i++) tag |= ( (fpu.tags[i]&3) <<(2*i)); return tag; } -static void FPU_SetTag(Bit16u tag){ - for(Bitu i=0;i<8;i++) - fpu.tags[i]= static_cast((tag >>(2*i))&3); -} - -INLINE Bitu FPU_GET_TOP(void){ - return (fpu.sw & 0x3800)>>11; -} -INLINE void FPU_SET_TOP(Bitu val){ - fpu.sw &= ~0x3800; - fpu.sw |= (val&7)<<11; -} - -INLINE void FPU_SET_C0(Bitu C){ - fpu.sw &= ~0x0100; - if(C) fpu.sw |= 0x0100; -} -INLINE void FPU_SET_C1(Bitu C){ - fpu.sw &= ~0x0200; - if(C) fpu.sw |= 0x0200; -} -INLINE void FPU_SET_C2(Bitu C){ - fpu.sw &= ~0x0400; - if(C) fpu.sw |= 0x0400; -} -INLINE void FPU_SET_C3(Bitu C){ - fpu.sw &= ~0x4000; - if(C) fpu.sw |= 0x4000; -} - #if C_FPU_X86 #include "fpu_instructions_x86.h" #else @@ -109,32 +55,31 @@ INLINE void FPU_SET_C3(Bitu C){ static void EATREE(Bitu _rm){ Bitu group=(_rm >> 3) & 7; - /* data will allready be put in register 8 by caller */ switch(group){ case 0x00: /* FADD */ - FPU_FADD(TOP, 8); + FPU_FADD_EA(TOP); break; case 0x01: /* FMUL */ - FPU_FMUL(TOP, 8); + FPU_FMUL_EA(TOP); break; case 0x02: /* FCOM */ - FPU_FCOM(TOP,8); + FPU_FCOM_EA(TOP); break; case 0x03: /* FCOMP */ - FPU_FCOM(TOP,8); + FPU_FCOM_EA(TOP); FPU_FPOP(); break; case 0x04: /* FSUB */ - FPU_FSUB(TOP,8); + FPU_FSUB_EA(TOP); break; case 0x05: /* FSUBR */ - FPU_FSUBR(TOP,8); + FPU_FSUBR_EA(TOP); break; case 0x06: /* FDIV */ - FPU_FDIV(TOP, 8); + FPU_FDIV_EA(TOP); break; case 0x07: /* FDIVR */ - FPU_FDIVR(TOP,8); + FPU_FDIVR_EA(TOP); break; default: break; @@ -143,7 +88,7 @@ static void EATREE(Bitu _rm){ void FPU_ESC0_EA(Bitu rm,PhysPt addr) { /* REGULAR TREE WITH 32 BITS REALS */ - FPU_FLD_F32(addr,8); + FPU_FLD_F32_EA(addr); EATREE(rm); } @@ -204,10 +149,7 @@ void FPU_ESC1_EA(Bitu rm,PhysPt addr) { FPU_FLDENV(addr); break; case 0x05: /* FLDCW */ - { - Bit16u temp = mem_readw(addr); - FPU_SetCW(temp); - } + FPU_FLDCW(addr); break; case 0x06: /* FSTENV */ FPU_FSTENV(addr); @@ -364,7 +306,7 @@ void FPU_ESC1_Normal(Bitu rm) { void FPU_ESC2_EA(Bitu rm,PhysPt addr) { /* 32 bits integer operants */ - FPU_FLD_I32(addr,8); + FPU_FLD_I32_EA(addr); EATREE(rm); } @@ -457,7 +399,7 @@ void FPU_ESC3_Normal(Bitu rm) { void FPU_ESC4_EA(Bitu rm,PhysPt addr) { /* REGULAR TREE WITH 64 BITS REALS */ - FPU_FLD_F64(addr,8); + FPU_FLD_F64_EA(addr); EATREE(rm); } @@ -560,10 +502,9 @@ void FPU_ESC5_Normal(Bitu rm) { } } - void FPU_ESC6_EA(Bitu rm,PhysPt addr) { /* 16 bit (word integer) operants */ - FPU_FLD_I16(addr,8); + FPU_FLD_I16_EA(addr); EATREE(rm); } diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 8609aae0..8bdf648d 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.28 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.29 2006-06-01 08:33:52 c2woody Exp $ */ static void FPU_FINIT(void) { @@ -187,6 +187,21 @@ static void FPU_FBLD(PhysPt addr,Bitu store_to) { fpu.regs[store_to].d = temp; } + +static INLINE void FPU_FLD_F32_EA(PhysPt addr) { + FPU_FLD_F32(addr,8); +} +static INLINE void FPU_FLD_F64_EA(PhysPt addr) { + FPU_FLD_F64(addr,8); +} +static INLINE void FPU_FLD_I32_EA(PhysPt addr) { + FPU_FLD_I32(addr,8); +} +static INLINE void FPU_FLD_I16_EA(PhysPt addr) { + FPU_FLD_I16(addr,8); +} + + static void FPU_FST_F32(PhysPt addr) { union { float f; @@ -249,7 +264,6 @@ static void FPU_FBST(PhysPt addr) { mem_writeb(addr+9,p); } - static void FPU_FADD(Bitu op1, Bitu op2){ fpu.regs[op1].d+=fpu.regs[op2].d; //flags and such :) @@ -556,3 +570,26 @@ static void FPU_FLDZ(void){ fpu.regs[TOP].d = 0.0; fpu.tags[TOP] = TAG_Zero; } + + +static INLINE void FPU_FADD_EA(Bitu op1){ + FPU_FADD(op1,8); +} +static INLINE void FPU_FMUL_EA(Bitu op1){ + FPU_FMUL(op1,8); +} +static INLINE void FPU_FSUB_EA(Bitu op1){ + FPU_FSUB(op1,8); +} +static INLINE void FPU_FSUBR_EA(Bitu op1){ + FPU_FSUBR(op1,8); +} +static INLINE void FPU_FDIV_EA(Bitu op1){ + FPU_FDIV(op1,8); +} +static INLINE void FPU_FDIVR_EA(Bitu op1){ + FPU_FDIVR(op1,8); +} +static INLINE void FPU_FCOM_EA(Bitu op1){ + FPU_FCOM(op1,8); +} \ No newline at end of file diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index f3babb49..8acb2f08 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions_x86.h,v 1.3 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: fpu_instructions_x86.h,v 1.4 2006-06-01 08:33:52 c2woody Exp $ */ #define WEAK_EXCEPTIONS @@ -33,11 +33,9 @@ #ifdef WEAK_EXCEPTIONS #define FPUD_LOAD(op,szI,szA) \ __asm { \ - __asm mov eax, 8 \ - __asm shl eax, 4 \ __asm mov ebx, store_to \ __asm shl ebx, 4 \ - __asm op szI PTR fpu.p_regs[eax].m1 \ + __asm op szI PTR fpu.p_regs[128].m1 \ __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ } #else @@ -56,6 +54,37 @@ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); #endif +#ifdef WEAK_EXCEPTIONS +#define FPUD_LOAD_EA(op,szI,szA) \ + __asm { \ + __asm op szI PTR fpu.p_regs[128].m1 \ + } +#else +#define FPUD_LOAD_EA(op,szI,szA) \ + Bit16u new_sw; \ + __asm { \ + __asm mov eax, 8 \ + __asm shl eax, 4 \ + __asm fclex \ + __asm op szI PTR fpu.p_regs[eax].m1 \ + __asm fnstsw new_sw \ + } \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); +#endif + +#ifdef WEAK_EXCEPTIONS +#define FPUD_STORE(op,szI,szA) \ + Bit16u save_cw; \ + __asm { \ + __asm fnstcw save_cw \ + __asm mov eax, TOP \ + __asm fldcw fpu.cw_mask_all \ + __asm shl eax, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm op szI PTR fpu.p_regs[128].m1 \ + __asm fldcw save_cw \ + } +#else #define FPUD_STORE(op,szI,szA) \ Bit16u new_sw,save_cw; \ __asm { \ @@ -72,6 +101,7 @@ __asm fldcw save_cw \ } \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); +#endif // handles fsin,fcos,f2xm1,fchs,fabs #define FPUD_TRIG(op) \ @@ -179,6 +209,23 @@ #endif // handles fadd,fmul,fsub,fsubr +#ifdef WEAK_EXCEPTIONS +#define FPUD_ARITH1(op) \ + Bit16u save_cw; \ + __asm { \ + __asm fnstcw save_cw \ + __asm mov eax, op1 \ + __asm shl eax, 4 \ + __asm fldcw fpu.cw_mask_all \ + __asm mov ebx, op2 \ + __asm shl ebx, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ + __asm op st(1), st(0) \ + __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fldcw save_cw \ + } +#else #define FPUD_ARITH1(op) \ Bit16u new_sw,save_cw; \ __asm { \ @@ -197,8 +244,57 @@ __asm fldcw save_cw \ } \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); +#endif + +// handles fadd,fmul,fsub,fsubr +#ifdef WEAK_EXCEPTIONS +#define FPUD_ARITH1_EA(op) \ + Bit16u save_cw; \ + __asm { \ + __asm fnstcw save_cw \ + __asm mov eax, op1 \ + __asm fldcw fpu.cw_mask_all \ + __asm shl eax, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fxch \ + __asm op st(1), st(0) \ + __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fldcw save_cw \ + } +#else +#define FPUD_ARITH1_EA(op) \ + Bit16u new_sw,save_cw; \ + __asm { \ + __asm fnstcw save_cw \ + __asm fldcw fpu.cw_mask_all \ + __asm mov eax, op1 \ + __asm shl eax, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fxch \ + __asm clx \ + __asm op st(1), st(0) \ + __asm fnstsw new_sw \ + __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fldcw save_cw \ + } \ + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); +#endif // handles fsqrt,frndint +#ifdef WEAK_EXCEPTIONS +#define FPUD_ARITH2(op) \ + Bit16u save_cw; \ + __asm { \ + __asm fnstcw save_cw \ + __asm mov eax, TOP \ + __asm fldcw fpu.cw_mask_all \ + __asm shl eax, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm op \ + __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fldcw save_cw \ + } +#else #define FPUD_ARITH2(op) \ Bit16u new_sw,save_cw; \ __asm { \ @@ -214,8 +310,26 @@ __asm fldcw save_cw \ } \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); +#endif // handles fdiv,fdivr +#ifdef WEAK_EXCEPTIONS +#define FPUD_ARITH3(op) \ + Bit16u save_cw; \ + __asm { \ + __asm fnstcw save_cw \ + __asm mov eax, op1 \ + __asm shl eax, 4 \ + __asm fldcw fpu.cw_mask_all \ + __asm mov ebx, op2 \ + __asm shl ebx, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ + __asm op st(1), st(0) \ + __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fldcw save_cw \ + } +#else #define FPUD_ARITH3(op) \ Bit16u new_sw,save_cw; \ __asm { \ @@ -234,6 +348,41 @@ __asm fldcw save_cw \ } \ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); +#endif + +// handles fdiv,fdivr +#ifdef WEAK_EXCEPTIONS +#define FPUD_ARITH3_EA(op) \ + Bit16u save_cw; \ + __asm { \ + __asm fnstcw save_cw \ + __asm mov eax, op1 \ + __asm fldcw fpu.cw_mask_all \ + __asm shl eax, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fxch \ + __asm op st(1), st(0) \ + __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fldcw save_cw \ + } +#else +#define FPUD_ARITH3_EA(op) \ + Bit16u new_sw,save_cw; \ + __asm { \ + __asm fnstcw save_cw \ + __asm mov eax, op1 \ + __asm fldcw fpu.cw_mask_all \ + __asm shl eax, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fxch \ + __asm fclex \ + __asm op st(1), st(0) \ + __asm fnstsw new_sw \ + __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ + __asm fldcw save_cw \ + } \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); +#endif // handles fprem,fprem1,fscale #define FPUD_REMINDER(op) \ @@ -260,8 +409,8 @@ Bit16u new_sw; \ __asm { \ __asm mov ebx, op2 \ - __asm shl ebx, 4 \ __asm mov eax, op1 \ + __asm shl ebx, 4 \ __asm shl eax, 4 \ __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ @@ -271,6 +420,18 @@ } \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); +#define FPUD_COMPARE_EA(op) \ + Bit16u new_sw; \ + __asm { \ + __asm mov eax, op1 \ + __asm shl eax, 4 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm clx \ + __asm op \ + __asm fnstsw new_sw \ + } \ + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); + // handles fxam,ftst #define FPUD_EXAMINE(op) \ Bit16u new_sw; \ @@ -323,6 +484,22 @@ #endif // handles fyl2x +#ifdef WEAK_EXCEPTIONS +#define FPUD_FYL2X(op) \ + __asm { \ + __asm mov eax, TOP \ + __asm mov ebx, eax \ + __asm inc ebx \ + __asm and ebx, 7 \ + __asm shl ebx, 4 \ + __asm shl eax, 4 \ + __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ + __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ + __asm op \ + __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ + } \ + FPU_FPOP(); +#else #define FPUD_FYL2X(op) \ Bit16u new_sw; \ __asm { \ @@ -341,6 +518,7 @@ } \ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ FPU_FPOP(); +#endif // load math constants #define FPUD_LOAD_CONST(op) \ @@ -364,8 +542,7 @@ #ifdef WEAK_EXCEPTIONS #define FPUD_LOAD(op,szI,szA) \ __asm__ volatile ( \ - "movl $8, %%eax \n" \ - "shl $4, %%eax \n" \ + "movl $128, %%eax \n" \ "shl $4, %0 \n" \ #op #szA " (%1, %%eax) \n" \ "fstpt (%1, %0) " \ @@ -391,6 +568,47 @@ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); #endif +#ifdef WEAK_EXCEPTIONS +#define FPUD_LOAD_EA(op,szI,szA) \ + __asm__ volatile ( \ + "movl $128, %%eax \n" \ + #op #szA " (%0, %%eax) \n" \ + : \ + : "r" (fpu.p_regs) \ + : "eax", "memory" \ + ); +#else +#define FPUD_LOAD_EA(op,szI,szA) \ + Bit16u new_sw; \ + __asm__ volatile ( \ + "movl $8, %%eax \n" \ + "shl $4, %%eax \n" \ + "fclex \n" \ + #op #szA " (%1, %%eax) \n" \ + "fnstsw %0 \n" \ + : "=m" (new_sw) \ + : "r" (fpu.p_regs) \ + : "eax", "memory" \ + ); \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); +#endif + +#ifdef WEAK_EXCEPTIONS +#define FPUD_STORE(op,szI,szA) \ + Bit16u save_cw; \ + __asm__ volatile ( \ + "fnstcw %0 \n" \ + "shll $4, %1 \n" \ + "fldcw %3 \n" \ + "movl $128, %%eax \n" \ + "fldt (%2, %1) \n" \ + #op #szA " (%2, %%eax) \n" \ + "fldcw %0 " \ + : "=m" (save_cw) \ + : "r" (TOP), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ + : "eax", "memory" \ + ); +#else #define FPUD_STORE(op,szI,szA) \ Bit16u new_sw,save_cw; \ __asm__ volatile ( \ @@ -409,6 +627,7 @@ : "eax", "memory" \ ); \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); +#endif // handles fsin,fcos,f2xm1,fchs,fabs #define FPUD_TRIG(op) \ @@ -422,7 +641,7 @@ "fstpt (%2, %1) " \ : "=m" (new_sw) \ : "r" (TOP), "r" (fpu.p_regs) \ - : "memory" \ + : "memory" \ ); \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); @@ -520,6 +739,24 @@ #endif // handles fadd,fmul,fsub,fsubr +#ifdef WEAK_EXCEPTIONS +#define FPUD_ARITH1(op) \ + Bit16u save_cw; \ + __asm__ volatile ( \ + "fnstcw %0 \n" \ + "fldcw %4 \n" \ + "shll $4, %2 \n" \ + "shll $4, %1 \n" \ + "fldt (%3, %2) \n" \ + "fldt (%3, %1) \n" \ + #op" \n" \ + "fstpt (%3, %1) \n" \ + "fldcw %0 " \ + : "=m" (save_cw) \ + : "r" (op1), "r" (op2), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ + : "memory" \ + ); +#else #define FPUD_ARITH1(op) \ Bit16u new_sw,save_cw; \ __asm__ volatile ( \ @@ -539,8 +776,61 @@ : "memory" \ ); \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); +#endif + +// handles fadd,fmul,fsub,fsubr +#ifdef WEAK_EXCEPTIONS +#define FPUD_ARITH1_EA(op) \ + Bit16u save_cw; \ + __asm__ volatile ( \ + "fnstcw %0 \n" \ + "fldcw %3 \n" \ + "shll $4, %1 \n" \ + "fldt (%2, %1) \n" \ + #op" \n" \ + "fstpt (%2, %1) \n" \ + "fldcw %0 " \ + : "=m" (save_cw) \ + : "r" (op1), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ + : "memory" \ + ); +#else +#define FPUD_ARITH1_EA(op) \ + Bit16u new_sw,save_cw; \ + __asm__ volatile ( \ + "fnstcw %1 \n" \ + "fldcw %4 \n" \ + "shll $4, %2 \n" \ + "fldt (%3, %2) \n" \ + clx" \n" \ + #op" \n" \ + "fnstsw %0 \n" \ + "fstpt (%3, %2) \n" \ + "fldcw %1 " \ + : "=m" (new_sw), "=m" (save_cw) \ + : "r" (op1), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ + : "memory" \ + ); \ + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); +#endif // handles fsqrt,frndint +#ifdef WEAK_EXCEPTIONS +#define FPUD_ARITH2(op) \ + Bit16u save_cw; \ + __asm__ volatile ( \ + "fnstcw %0 \n" \ + "fldcw %3 \n" \ + "shll $4, %1 \n" \ + "fldt (%2, %1) \n" \ + #op" \n" \ + "fstpt (%2, %1) \n" \ + "fldcw %0 " \ + : "=m" (save_cw) \ + : "r" (TOP), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ + : "memory" \ + ); +#else #define FPUD_ARITH2(op) \ Bit16u new_sw,save_cw; \ __asm__ volatile ( \ @@ -558,8 +848,27 @@ : "memory" \ ); \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); +#endif // handles fdiv,fdivr +#ifdef WEAK_EXCEPTIONS +#define FPUD_ARITH3(op) \ + Bit16u save_cw; \ + __asm__ volatile ( \ + "fnstcw %0 \n" \ + "fldcw %4 \n" \ + "shll $4, %2 \n" \ + "shll $4, %1 \n" \ + "fldt (%3, %2) \n" \ + "fldt (%3, %1) \n" \ + #op" \n" \ + "fstpt (%3, %1) \n" \ + "fldcw %0 " \ + : "=m" (save_cw) \ + : "r" (op1), "r" (op2), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ + : "memory" \ + ); +#else #define FPUD_ARITH3(op) \ Bit16u new_sw,save_cw; \ __asm__ volatile ( \ @@ -579,6 +888,43 @@ : "memory" \ ); \ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); +#endif + +// handles fdiv,fdivr +#ifdef WEAK_EXCEPTIONS +#define FPUD_ARITH3_EA(op) \ + Bit16u save_cw; \ + __asm__ volatile ( \ + "fnstcw %0 \n" \ + "fldcw %3 \n" \ + "shll $4, %1 \n" \ + "fldt (%2, %1) \n" \ + #op" \n" \ + "fstpt (%2, %1) \n" \ + "fldcw %0 " \ + : "=m" (save_cw) \ + : "r" (op1), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ + : "memory" \ + ); +#else +#define FPUD_ARITH3_EA(op) \ + Bit16u new_sw,save_cw; \ + __asm__ volatile ( \ + "fnstcw %1 \n" \ + "fldcw %4 \n" \ + "shll $4, %2 \n" \ + "fldt (%3, %2) \n" \ + "fclex \n" \ + #op" \n" \ + "fnstsw %0 \n" \ + "fstpt (%3, %2) \n" \ + "fldcw %1 " \ + : "=m" (new_sw), "=m" (save_cw) \ + : "r" (op1), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ + : "memory" \ + ); \ + fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); +#endif // handles fprem,fprem1,fscale #define FPUD_REMINDER(op) \ @@ -615,7 +961,22 @@ "fnstsw %0 " \ : "=m" (new_sw) \ : "r" (op1), "r" (op2), "r" (fpu.p_regs) \ - : "memory" \ + : "memory" \ + ); \ + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); + +// handles fcom,fucom +#define FPUD_COMPARE_EA(op) \ + Bit16u new_sw; \ + __asm__ volatile ( \ + "shll $4, %1 \n" \ + "fldt (%2, %1) \n" \ + clx" \n" \ + #op" \n" \ + "fnstsw %0 " \ + : "=m" (new_sw) \ + : "r" (op1), "r" (fpu.p_regs) \ + : "memory" \ ); \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); @@ -677,6 +1038,24 @@ #endif // handles fyl2x +#ifdef WEAK_EXCEPTIONS +#define FPUD_FYL2X(op) \ + __asm__ volatile ( \ + "movl %0, %%eax \n" \ + "incl %%eax \n" \ + "andl $7, %%eax \n" \ + "shll $4, %%eax \n" \ + "shll $4, %0 \n" \ + "fldt (%1, %%eax) \n" \ + "fldt (%1, %0) \n" \ + #op" \n" \ + "fstpt (%1, %%eax) \n" \ + : \ + : "r" (TOP), "r" (fpu.p_regs) \ + : "eax", "memory" \ + ); \ + FPU_FPOP(); +#else #define FPUD_FYL2X(op) \ Bit16u new_sw; \ __asm__ volatile ( \ @@ -697,6 +1076,7 @@ ); \ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ FPU_FPOP(); +#endif // load math constants #define FPUD_LOAD_CONST(op) \ @@ -756,12 +1136,23 @@ static void FPU_FLD_F32(PhysPt addr,Bitu store_to) { FPUD_LOAD(fld,DWORD,s) } +static void FPU_FLD_F32_EA(PhysPt addr) { + fpu.p_regs[8].m1 = mem_readd(addr); + FPUD_LOAD_EA(fld,DWORD,s) +} + static void FPU_FLD_F64(PhysPt addr,Bitu store_to) { fpu.p_regs[8].m1 = mem_readd(addr); fpu.p_regs[8].m2 = mem_readd(addr+4); FPUD_LOAD(fld,QWORD,l) } +static void FPU_FLD_F64_EA(PhysPt addr) { + fpu.p_regs[8].m1 = mem_readd(addr); + fpu.p_regs[8].m2 = mem_readd(addr+4); + FPUD_LOAD_EA(fld,QWORD,l) +} + static void FPU_FLD_F80(PhysPt addr) { fpu.p_regs[TOP].m1 = mem_readd(addr); fpu.p_regs[TOP].m2 = mem_readd(addr+4); @@ -774,11 +1165,21 @@ static void FPU_FLD_I16(PhysPt addr,Bitu store_to) { FPUD_LOAD(fild,WORD,) } +static void FPU_FLD_I16_EA(PhysPt addr) { + fpu.p_regs[8].m1 = (Bit32u)mem_readw(addr); + FPUD_LOAD_EA(fild,WORD,) +} + static void FPU_FLD_I32(PhysPt addr,Bitu store_to) { fpu.p_regs[8].m1 = mem_readd(addr); FPUD_LOAD(fild,DWORD,l) } +static void FPU_FLD_I32_EA(PhysPt addr) { + fpu.p_regs[8].m1 = mem_readd(addr); + FPUD_LOAD_EA(fild,DWORD,l) +} + static void FPU_FLD_I64(PhysPt addr,Bitu store_to) { fpu.p_regs[8].m1 = mem_readd(addr); fpu.p_regs[8].m2 = mem_readd(addr+4); @@ -863,26 +1264,50 @@ static void FPU_FADD(Bitu op1, Bitu op2){ FPUD_ARITH1(faddp) } +static void FPU_FADD_EA(Bitu op1){ + FPUD_ARITH1_EA(faddp) +} + static void FPU_FDIV(Bitu op1, Bitu op2){ FPUD_ARITH3(fdivp) } +static void FPU_FDIV_EA(Bitu op1){ + FPUD_ARITH3_EA(fdivp) +} + static void FPU_FDIVR(Bitu op1, Bitu op2){ FPUD_ARITH3(fdivrp) } +static void FPU_FDIVR_EA(Bitu op1){ + FPUD_ARITH3_EA(fdivrp) +} + static void FPU_FMUL(Bitu op1, Bitu op2){ FPUD_ARITH1(fmulp) } +static void FPU_FMUL_EA(Bitu op1){ + FPUD_ARITH1_EA(fmulp) +} + static void FPU_FSUB(Bitu op1, Bitu op2){ FPUD_ARITH1(fsubp) } +static void FPU_FSUB_EA(Bitu op1){ + FPUD_ARITH1_EA(fsubp) +} + static void FPU_FSUBR(Bitu op1, Bitu op2){ FPUD_ARITH1(fsubrp) } +static void FPU_FSUBR_EA(Bitu op1){ + FPUD_ARITH1_EA(fsubrp) +} + static void FPU_FXCH(Bitu stv, Bitu other){ FPU_Tag tag = fpu.tags[other]; fpu.tags[other] = fpu.tags[stv]; @@ -916,6 +1341,10 @@ static void FPU_FCOM(Bitu op1, Bitu op2){ FPUD_COMPARE(fcompp) } +static void FPU_FCOM_EA(Bitu op1){ + FPUD_COMPARE_EA(fcompp) +} + static void FPU_FUCOM(Bitu op1, Bitu op2){ FPUD_COMPARE(fucompp) } diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index c7706767..09b10a58 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -262,6 +262,9 @@ + + @@ -368,13 +371,13 @@ - - - + + + @@ -384,15 +387,15 @@ + + - - @@ -470,15 +473,15 @@ + + - - - - Date: Thu, 1 Jun 2006 15:45:37 +0000 Subject: [PATCH 2560/4131] add/remove dynfpu/fpu support files Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2645 --- src/cpu/core_dyn_x86/dyn_fpu.h | 664 +++++++++++++++++++++++++++++++++ src/fpu/fpu_types.h | 64 ---- 2 files changed, 664 insertions(+), 64 deletions(-) create mode 100644 src/cpu/core_dyn_x86/dyn_fpu.h delete mode 100644 src/fpu/fpu_types.h diff --git a/src/cpu/core_dyn_x86/dyn_fpu.h b/src/cpu/core_dyn_x86/dyn_fpu.h new file mode 100644 index 00000000..3664bb8f --- /dev/null +++ b/src/cpu/core_dyn_x86/dyn_fpu.h @@ -0,0 +1,664 @@ +/* + * Copyright (C) 2002-2005 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.1 2006-06-01 15:45:37 c2woody Exp $ */ + +#include "dosbox.h" +#if C_FPU + +#include +#include +#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_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_load_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 diff --git a/src/fpu/fpu_types.h b/src/fpu/fpu_types.h deleted file mode 100644 index 0e5220e2..00000000 --- a/src/fpu/fpu_types.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2002-2006 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: fpu_types.h,v 1.13 2006-02-09 11:47:48 qbix79 Exp $ */ -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 -}; - -//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 From c0eb7704fcf0cf49ad98329b6eeba357263e8b54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 2 Jun 2006 16:44:46 +0000 Subject: [PATCH 2561/4131] fix a few auxiliar flag bugs Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2646 --- src/cpu/flags.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 5d878375..fe76183b 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -597,6 +597,7 @@ Bitu FillFlags(void) { case t_ORb: SET_FLAG(CF,false); + SET_FLAG(AF,false); DOFLAG_ZFb; DOFLAG_SFb; SET_FLAG(OF,false); @@ -604,6 +605,7 @@ Bitu FillFlags(void) { break; case t_ORw: SET_FLAG(CF,false); + SET_FLAG(AF,false); DOFLAG_ZFw; DOFLAG_SFw; SET_FLAG(OF,false); @@ -611,6 +613,7 @@ Bitu FillFlags(void) { break; case t_ORd: SET_FLAG(CF,false); + SET_FLAG(AF,false); DOFLAG_ZFd; DOFLAG_SFd; SET_FLAG(OF,false); @@ -621,6 +624,7 @@ Bitu FillFlags(void) { case t_TESTb: case t_ANDb: SET_FLAG(CF,false); + SET_FLAG(AF,false); DOFLAG_ZFb; DOFLAG_SFb; SET_FLAG(OF,false); @@ -629,6 +633,7 @@ Bitu FillFlags(void) { case t_TESTw: case t_ANDw: SET_FLAG(CF,false); + SET_FLAG(AF,false); DOFLAG_ZFw; DOFLAG_SFw; SET_FLAG(OF,false); @@ -637,6 +642,7 @@ Bitu FillFlags(void) { case t_TESTd: case t_ANDd: SET_FLAG(CF,false); + SET_FLAG(AF,false); DOFLAG_ZFd; DOFLAG_SFd; SET_FLAG(OF,false); @@ -646,6 +652,7 @@ Bitu FillFlags(void) { case t_XORb: SET_FLAG(CF,false); + SET_FLAG(AF,false); DOFLAG_ZFb; DOFLAG_SFb; SET_FLAG(OF,false); @@ -653,6 +660,7 @@ Bitu FillFlags(void) { break; case t_XORw: SET_FLAG(CF,false); + SET_FLAG(AF,false); DOFLAG_ZFw; DOFLAG_SFw; SET_FLAG(OF,false); @@ -660,6 +668,7 @@ Bitu FillFlags(void) { break; case t_XORd: SET_FLAG(CF,false); + SET_FLAG(AF,false); DOFLAG_ZFd; DOFLAG_SFd; SET_FLAG(OF,false); @@ -792,21 +801,21 @@ Bitu FillFlags(void) { break; case t_DECb: - SET_FLAG(AF,(lf_resb & 0x0f) == 0); + SET_FLAG(AF,(lf_resb & 0x0f) == 0x0f); DOFLAG_ZFb; DOFLAG_SFb; SET_FLAG(OF,(lf_resb == 0x7f)); DOFLAG_PF; break; case t_DECw: - SET_FLAG(AF,(lf_resw & 0x0f) == 0); + SET_FLAG(AF,(lf_resw & 0x0f) == 0x0f); DOFLAG_ZFw; DOFLAG_SFw; SET_FLAG(OF,(lf_resw == 0x7fff)); DOFLAG_PF; break; case t_DECd: - SET_FLAG(AF,(lf_resd & 0x0f) == 0); + SET_FLAG(AF,(lf_resd & 0x0f) == 0x0f); DOFLAG_ZFd; DOFLAG_SFd; SET_FLAG(OF,(lf_resd == 0x7fffffff)); @@ -815,7 +824,7 @@ Bitu FillFlags(void) { case t_NEGb: SET_FLAG(CF,(lf_var1b!=0)); - SET_FLAG(AF,(lf_resb & 0x0f) == 0); + SET_FLAG(AF,(lf_resb & 0x0f) != 0); DOFLAG_ZFb; DOFLAG_SFb; SET_FLAG(OF,(lf_var1b == 0x80)); @@ -823,7 +832,7 @@ Bitu FillFlags(void) { break; case t_NEGw: SET_FLAG(CF,(lf_var1w!=0)); - SET_FLAG(AF,(lf_resw & 0x0f) == 0); + SET_FLAG(AF,(lf_resw & 0x0f) != 0); DOFLAG_ZFw; DOFLAG_SFw; SET_FLAG(OF,(lf_var1w == 0x8000)); @@ -831,7 +840,7 @@ Bitu FillFlags(void) { break; case t_NEGd: SET_FLAG(CF,(lf_var1d!=0)); - SET_FLAG(AF,(lf_resd & 0x0f) == 0); + SET_FLAG(AF,(lf_resd & 0x0f) != 0); DOFLAG_ZFd; DOFLAG_SFd; SET_FLAG(OF,(lf_var1d == 0x80000000)); From 14456f435a18257e6bcc27939e2fe09851f61337 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 5 Jun 2006 18:01:24 +0000 Subject: [PATCH 2562/4131] Move internal dos table segment to d800. Gives some more umbs. Fixes Terminator Arcade. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2647 --- src/dos/dos_memory.cpp | 2 +- src/dos/dos_tables.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 3033bcf8..6f6956f5 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -306,7 +306,7 @@ bool DOS_FreeMemory(Bit16u segment) { void DOS_BuildUMBChain(const char* use_umbs,bool ems_active) { if ((strcmp(use_umbs,"false")!=0) && (machine!=MCH_TANDY)) { Bit16u first_umb_seg=0xc800; - Bit16u first_umb_size=0x800; + Bit16u first_umb_size=0x1000; dos_infoblock.SetStartOfUMBChain(UMB_START_SEG); dos_infoblock.SetUMBChainState(0); // UMBs not linked yet diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index b276ecde..438edce7 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.22 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: dos_tables.cpp,v 1.23 2006-06-05 18:01:24 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -73,7 +73,7 @@ static Bit8u country_info[0x22] = { }; void DOS_SetupTables(void) { - dos_memseg=0xd000; + dos_memseg=0xd800; Bit16u seg,seg2;Bitu i; dos.tables.mediaid=RealMake(DOS_GetMemory(4),0); dos.tables.tempdta=RealMake(DOS_GetMemory(4),0); From af5bb6abf312b23ca40375c98d6d572b4b6e09da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 10 Jun 2006 10:50:01 +0000 Subject: [PATCH 2563/4131] fix bug in dyncore for STD/CLD+STI/CLI opcode combination (f15/f22 et al) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2648 --- src/cpu/core_dyn_x86/decoder.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 7d1baa13..006f4dec 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1723,11 +1723,13 @@ restart_prefix: case 0xf7:dyn_grp3_ev();break; /* Change interrupt flag */ case 0xfa: //CLI + gen_releasereg(DREG(FLAGS)); gen_call_function((void *)&CPU_CLI,"%Rd",DREG(TMPB)); if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); gen_releasereg(DREG(TMPB)); break; case 0xfb: //STI + gen_releasereg(DREG(FLAGS)); gen_call_function((void *)&CPU_STI,"%Rd",DREG(TMPB)); if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); gen_releasereg(DREG(TMPB)); From b9ad197d8587974dbb9ebb68b16df2a6d95847d5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 12 Jun 2006 08:04:48 +0000 Subject: [PATCH 2564/4131] wrap around joystick buttons. Makes playing joystick games more fun on my Gravis Exterminator. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2649 --- src/gui/sdl_mapper.cpp | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 3ebf1f30..c90237d7 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.23 2006-04-08 19:41:49 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.24 2006-06-12 08:04:48 qbix79 Exp $ */ #define OLD_JOYSTICK 1 @@ -486,6 +486,7 @@ public: neg_axis_lists=new CBindList[axes]; button_lists=new CBindList[buttons]; hat_lists=new CBindList[hats]; + emulated_buttons = 2; #if OLD_JOYSTICK LOG_MSG("Using joystick %s with %d axes and %d buttons",SDL_JoystickName(stick),axes,buttons); //if the first stick is set, we must be the second @@ -528,6 +529,7 @@ public: #if OLD_JOYSTICK SDL_JoyAxisEvent * jaxis = NULL; SDL_JoyButtonEvent * jbutton = NULL; + Bitu but = 0; switch(event->type) { case SDL_JOYAXISMOTION: @@ -543,8 +545,9 @@ public: jbutton = &event->jbutton; bool state; state=jbutton->type==SDL_JOYBUTTONDOWN; - if ((jbutton->which == stick) && (jbutton->button<2)) { - JOYSTICK_Button(emustick,jbutton->button,state); + but = jbutton->button % emulated_buttons; + if (jbutton->which == stick) { + JOYSTICK_Button(emustick,but,state); } break; } @@ -572,7 +575,7 @@ protected: CBindList * neg_axis_lists; CBindList * button_lists; CBindList * hat_lists; - Bitu stick,emustick,axes,buttons,hats; + Bitu stick,emustick,axes,buttons,hats,emulated_buttons; SDL_Joystick * sdl_joystick; char configname[10]; }; @@ -580,6 +583,7 @@ protected: class C4AxisBindGroup : public CStickBindGroup { public: C4AxisBindGroup(Bitu _stick) : CStickBindGroup (_stick){ + emulated_buttons = 4; #if OLD_JOYSTICK JOYSTICK_Enable(1,true); #endif @@ -588,6 +592,7 @@ public: #if OLD_JOYSTICK SDL_JoyAxisEvent * jaxis = NULL; SDL_JoyButtonEvent * jbutton = NULL; + Bitu but = 0; switch(event->type) { case SDL_JOYAXISMOTION: @@ -603,9 +608,9 @@ public: jbutton = &event->jbutton; bool state; state=jbutton->type==SDL_JOYBUTTONDOWN; - if ((jbutton->which == stick) && (jbutton->button<4)) { - JOYSTICK_Button((jbutton->button >> 1), - (jbutton->button & 1),state); + but = jbutton->button % emulated_buttons; + if (jbutton->which == stick) { + JOYSTICK_Button((but >> 1),(but & 1),state); } break; } @@ -617,6 +622,7 @@ public: class CFCSBindGroup : public CStickBindGroup { public: CFCSBindGroup(Bitu _stick) : CStickBindGroup (_stick){ + emulated_buttons = 4; #if OLD_JOYSTICK JOYSTICK_Enable(1,true); JOYSTICK_Move_Y(1,1.0); @@ -627,6 +633,7 @@ public: SDL_JoyAxisEvent * jaxis = NULL; SDL_JoyButtonEvent * jbutton = NULL; SDL_JoyHatEvent * jhat = NULL; + Bitu but = 0; switch(event->type) { case SDL_JOYAXISMOTION: @@ -690,9 +697,9 @@ public: jbutton = &event->jbutton; bool state; state=jbutton->type==SDL_JOYBUTTONDOWN; - if ((jbutton->which == stick) && (jbutton->button<4)) { - JOYSTICK_Button((jbutton->button >> 1), - (jbutton->button & 1),state); + but = jbutton->button % emulated_buttons; + if (jbutton->which == stick) { + JOYSTICK_Button((but >> 1),(but & 1),state); } break; } @@ -704,6 +711,7 @@ public: class CCHBindGroup : public CStickBindGroup { public: CCHBindGroup(Bitu _stick) : CStickBindGroup (_stick){ + emulated_buttons = 6; #if OLD_JOYSTICK JOYSTICK_Enable(1,true); button_state=0; @@ -714,6 +722,7 @@ public: SDL_JoyAxisEvent * jaxis = NULL; SDL_JoyButtonEvent * jbutton = NULL; SDL_JoyHatEvent * jhat = NULL; + Bitu but = 0; static unsigned const button_magic[6]={0x02,0x04,0x10,0x100,0x20,0x200}; static unsigned const hat_magic[2][5]={{0x8888,0x8000,0x800,0x80,0x08}, {0x5440,0x4000,0x400,0x40,0x1000}}; @@ -743,13 +752,15 @@ public: break; case SDL_JOYBUTTONDOWN: jbutton = &event->jbutton; - if ((jbutton->which == stick) && (jbutton->button<6)) - button_state|=button_magic[jbutton->button]; + but = jbutton->button % emulated_buttons; + if (jbutton->which == stick) + button_state|=button_magic[but]; break; case SDL_JOYBUTTONUP: jbutton = &event->jbutton; - if ((jbutton->which == stick) && (jbutton->button<6)) - button_state&=~button_magic[jbutton->button]; + but = jbutton->button % emulated_buttons; + if (jbutton->which == stick) + button_state&=~button_magic[but]; break; } unsigned i; From 27225d66029dfd9ea9c6ca6bf550d1cfc9affeb6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 12 Jun 2006 08:07:39 +0000 Subject: [PATCH 2565/4131] Silence a warning. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2650 --- src/cpu/core_dyn_x86/decoder.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 006f4dec..6f17d1ae 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -154,7 +154,8 @@ static INLINE void dyn_set_eip_last(void) { enum save_info_type {exception, cycle_check, normal}; -struct { + +static struct { save_info_type type; DynState state; Bit8u * branch_pos; From 866211408bf1000fc5f5511606b7b17a18fd183b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 12 Jun 2006 08:24:28 +0000 Subject: [PATCH 2566/4131] Add patch 1503983 "quit during sdl_pause" by ykhwong and patch 1500664 "Auto-pause on minimise/focus loss" by philpem. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2651 --- src/gui/sdlmain.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 3e5ad1d1..cf46d30f 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.115 2006-04-12 18:52:50 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.116 2006-06-12 08:24:28 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -131,6 +131,7 @@ enum SCREEN_TYPES { }; enum PRIORITY_LEVELS { + PRIORITY_LEVEL_PAUSE, PRIORITY_LEVEL_LOWEST, PRIORITY_LEVEL_LOWER, PRIORITY_LEVEL_NORMAL, @@ -240,6 +241,7 @@ static void PauseDOSBox(bool pressed) { while (paused) { SDL_WaitEvent(&event); // since we're not polling, cpu usage drops to 0. switch (event.type) { + case SDL_QUIT: throw(0); break; case SDL_KEYDOWN: // Must use Pause/Break Key to resume. case SDL_KEYUP: if(event.key.keysym.sym==SDLK_PAUSE){ @@ -250,7 +252,7 @@ static void PauseDOSBox(bool pressed) { } } } - + /* Reset the screen with current values in the sdl structure */ Bitu GFX_GetBestMode(Bitu flags) { @@ -866,6 +868,7 @@ static void SetPriority(PRIORITY_LEVELS level) { #endif switch (level) { #ifdef WIN32 + case PRIORITY_LEVEL_PAUSE: // if DOSBox is paused, assume idle priority case PRIORITY_LEVEL_LOWEST: SetPriorityClass(GetCurrentProcess(),IDLE_PRIORITY_CLASS); break; @@ -883,6 +886,7 @@ static void SetPriority(PRIORITY_LEVELS level) { break; #elif C_SET_PRIORITY /* Linux use group as dosbox has mulitple threads under linux */ + case PRIORITY_LEVEL_PAUSE: // if DOSBox is paused, assume idle priority case PRIORITY_LEVEL_LOWEST: setpriority (PRIO_PGRP, 0,PRIO_MAX); break; @@ -953,6 +957,11 @@ static void GUI_StartUp(Section * sec) { sdl.priority.nofocus=PRIORITY_LEVEL_HIGHER; } else if (!strncasecmp(priority,"highest",7)) { sdl.priority.nofocus=PRIORITY_LEVEL_HIGHEST; + } else if (!strncasecmp(priority,"pause",5)) { + /* we only check for pause here, because it makes no sense + * for DOSBox to be paused while it has focus + */ + sdl.priority.nofocus=PRIORITY_LEVEL_PAUSE; } else { sdl.priority.nofocus=PRIORITY_LEVEL_NORMAL; } @@ -1162,7 +1171,7 @@ void GFX_Events() { if (event.active.state & SDL_APPINPUTFOCUS) { if (event.active.gain) { if (sdl.desktop.fullscreen && !sdl.mouse.locked) - GFX_CaptureMouse(); + GFX_CaptureMouse(); SetPriority(sdl.priority.focus); } else { if (sdl.mouse.locked) { @@ -1179,6 +1188,53 @@ void GFX_Events() { MAPPER_LosingFocus(); } } + + /* Non-focus priority is set to pause; check to see if we've lost window or input focus + * i.e. has the window been minimised or made inactive? + */ + if (sdl.priority.nofocus == PRIORITY_LEVEL_PAUSE) { + if ((event.active.state & (SDL_APPINPUTFOCUS | SDL_APPACTIVE)) && (!event.active.gain)) { + /* Window has lost focus, pause the emulator. + * This is similar to what PauseDOSBox() does, but the exit criteria is different. + * Instead of waiting for the user to hit Alt-Break, we wait for the window to + * regain window or input focus. + */ + bool paused = true; + SDL_Event ev; + + GFX_SetTitle(-1,-1,true); + KEYBOARD_ClrBuffer(); + SDL_Delay(500); + while (SDL_PollEvent(&ev)) { + // flush event queue. + } + + while (paused) { + // WaitEvent waits for an event rather than polling, so CPU usage drops to zero + SDL_WaitEvent(&ev); + + switch (ev.type) { + case SDL_QUIT: throw(0); break; // a bit redundant at linux at least as the active events gets before the quit event. + case SDL_ACTIVEEVENT: // wait until we get window focus back + if (ev.active.state & (SDL_APPINPUTFOCUS | SDL_APPACTIVE)) { + // We've got focus back, so unpause and break out of the loop + if (ev.active.gain) { + paused = false; + GFX_SetTitle(-1,-1,false); + } + + /* Now poke a "release ALT" command into the keyboard buffer + * we have to do this, otherwise ALT will 'stick' and cause + * problems with the app running in the DOSBox. + */ + KEYBOARD_AddKey(KBD_leftalt, false); + KEYBOARD_AddKey(KBD_rightalt, false); + } + break; + } + } + } + } break; case SDL_MOUSEMOTION: HandleMouseMotion(&event.motion); @@ -1309,7 +1365,7 @@ int main(int argc, char* argv[]) { "autolock -- Mouse will automatically lock, if you click on the screen.\n" "sensitiviy -- Mouse sensitivity.\n" "waitonerror -- Wait before closing the console if dosbox has an error.\n" - "priority -- Priority levels for dosbox: lowest,lower,normal,higher,highest.\n" + "priority -- Priority levels for dosbox: pause,lowest,lower,normal,higher,highest.\n" " Second entry behind the comma is for when dosbox is not focused/minimized.\n" "mapperfile -- File used to load/save the key/event mappings from.\n" "usescancodes -- Avoid usage of symkeys, might not work on all operating systems.\n" From f0ddb8d464959d6f5a9681ab6d6d4416a5e80fea Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 12 Jun 2006 19:11:14 +0000 Subject: [PATCH 2567/4131] More informative description. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2652 --- src/gui/sdlmain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index cf46d30f..47301bf0 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.116 2006-06-12 08:24:28 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.117 2006-06-12 19:11:14 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1365,7 +1365,7 @@ int main(int argc, char* argv[]) { "autolock -- Mouse will automatically lock, if you click on the screen.\n" "sensitiviy -- Mouse sensitivity.\n" "waitonerror -- Wait before closing the console if dosbox has an error.\n" - "priority -- Priority levels for dosbox: pause,lowest,lower,normal,higher,highest.\n" + "priority -- Priority levels for dosbox: lowest,lower,normal,higher,highest,pause (when not focussed).\n" " Second entry behind the comma is for when dosbox is not focused/minimized.\n" "mapperfile -- File used to load/save the key/event mappings from.\n" "usescancodes -- Avoid usage of symkeys, might not work on all operating systems.\n" From 4644aaea0e45fe562139c3700922b929136571ed Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 16 Jun 2006 14:51:31 +0000 Subject: [PATCH 2568/4131] New key input loop (no more return to enter it.). key up behaves a bit better (Kronutz). A few keybindings were removed. GetHexValues supportes +/- now (d cs+10:ax-200+bx should work now). Command parsing now based the string datatype. Make more use of mvaddstr instead of looped mvaddch. Fix a few small bugs. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2653 --- src/debug/debug.cpp | 723 ++++++++++++++++++---------------------- src/debug/debug_gui.cpp | 10 +- 2 files changed, 323 insertions(+), 410 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 06d492fd..42881792 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.79 2006-05-22 20:29:50 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.80 2006-06-16 14:51:31 qbix79 Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -26,6 +26,8 @@ #include #include #include +#include +#include using namespace std; #include "debug.h" @@ -265,8 +267,8 @@ enum EBreakpoint { BKPNT_UNKNOWN, BKPNT_PHYSICAL, BKPNT_INTERRUPT, BKPNT_MEMORY, class CBreakpoint { public: - CBreakpoint (void) { location = 0; active = once = false; segment = 0; offset = 0; intNr = 0; ahValue = 0; type = BKPNT_UNKNOWN; }; + CBreakpoint(void); void SetAddress (Bit16u seg, Bit32u off) { location = GetAddress(seg,off); type = BKPNT_PHYSICAL; segment = seg; offset = off; }; void SetAddress (PhysPt adr) { location = adr; type = BKPNT_PHYSICAL; }; void SetInt (Bit8u _intNr, Bit16u ah) { intNr = _intNr, ahValue = ah; type = BKPNT_INTERRUPT; }; @@ -320,10 +322,16 @@ public: static CBreakpoint* ignoreOnce; }; +CBreakpoint::CBreakpoint(void): +location(0), +active(false),once(false), +segment(0),offset(0),intNr(0),ahValue(0), +type(BKPNT_UNKNOWN) { }; + void CBreakpoint::Activate(bool _active) { - if (GetType()==BKPNT_PHYSICAL) { #if !C_HEAVY_DEBUG + if (GetType()==BKPNT_PHYSICAL) { if (_active) { // Set 0xCC and save old value Bit8u data = mem_readb(location); @@ -337,8 +345,8 @@ void CBreakpoint::Activate(bool _active) mem_writeb(location,oldData); }; } -#endif } +#endif active = _active; }; @@ -381,7 +389,7 @@ void CBreakpoint::ActivateBreakpoints(PhysPt adr, bool activate) std::list::iterator i; CBreakpoint* bp; for(i=BPoints.begin(); i != BPoints.end(); i++) { - bp = static_cast(*i); + bp = (*i); // Do not activate, when bp is an actual adress if (activate && (bp->GetType()==BKPNT_PHYSICAL) && (bp->GetLocation()==adr)) { // Do not activate :) @@ -404,7 +412,7 @@ bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off) std::list::iterator i; CBreakpoint* bp; for(i=BPoints.begin(); i != BPoints.end(); i++) { - bp = static_cast(*i); + bp = (*i); if ((bp->GetType()==BKPNT_PHYSICAL) && bp->IsActive() && (bp->GetSegment()==seg) && (bp->GetOffset()==off)) { // Ignore Once ? if (ignoreOnce==bp) { @@ -467,7 +475,7 @@ bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue) std::list::iterator i; CBreakpoint* bp; for(i=BPoints.begin(); i != BPoints.end(); i++) { - bp = static_cast(*i); + bp = (*i); if ((bp->GetType()==BKPNT_INTERRUPT) && bp->IsActive() && (bp->GetIntNr()==intNr)) { if ((bp->GetValue()==BPINT_ALL) || (bp->GetValue()==ahValue)) { // Ignoie it once ? @@ -497,7 +505,7 @@ void CBreakpoint::DeleteAll() std::list::iterator i; CBreakpoint* bp; for(i=BPoints.begin(); i != BPoints.end(); i++) { - bp = static_cast(*i); + bp = (*i); bp->Activate(false); delete bp; }; @@ -513,7 +521,7 @@ bool CBreakpoint::DeleteByIndex(Bit16u index) CBreakpoint* bp; for(i=BPoints.begin(); i != BPoints.end(); i++) { if (nr==index) { - bp = static_cast(*i); + bp = (*i); (BPoints.erase)(i); bp->Activate(false); delete bp; @@ -530,7 +538,7 @@ bool CBreakpoint::DeleteBreakpoint(PhysPt where) std::list::iterator i; CBreakpoint* bp; for(i=BPoints.begin(); i != BPoints.end(); i++) { - bp = static_cast(*i); + bp = (*i); if ((bp->GetType()==BKPNT_PHYSICAL) && (bp->GetLocation()==where)) { (BPoints.erase)(i); bp->Activate(false); @@ -548,7 +556,7 @@ bool CBreakpoint::IsBreakpoint(PhysPt adr) std::list::iterator i; CBreakpoint* bp; for(i=BPoints.begin(); i != BPoints.end(); i++) { - bp = static_cast(*i); + bp = (*i); if ((bp->GetType()==BKPNT_PHYSICAL) && (bp->GetSegment()==adr)) { return true; }; @@ -566,7 +574,7 @@ bool CBreakpoint::IsBreakpointDrawn(PhysPt adr) std::list::iterator i; CBreakpoint* bp; for(i=BPoints.begin(); i != BPoints.end(); i++) { - bp = static_cast(*i); + bp = (*i); if ((bp->GetType()==BKPNT_PHYSICAL) && (bp->GetLocation()==adr)) { // Only draw, if breakpoint is not only once, return !bp->GetOnce(); @@ -581,7 +589,7 @@ void CBreakpoint::ShowList(void) int nr = 0; std::list::iterator i; for(i=BPoints.begin(); i != BPoints.end(); i++) { - CBreakpoint* bp = static_cast(*i); + CBreakpoint* bp = (*i); if (bp->GetType()==BKPNT_PHYSICAL) { DEBUG_ShowMsg("%02X. BP %04X:%04X\n",nr,bp->GetSegment(),bp->GetOffset()); nr++; @@ -699,31 +707,33 @@ static void DrawRegisters(void) { SetColor(SegValue(cs)!=oldsegs[cs].val);oldsegs[cs].val=SegValue(cs);mvwprintw (dbg.win_reg,1,31,"%04X",SegValue(cs)); /*Individual flags*/ + Bitu changed_flags = reg_flags ^ oldflags; + oldflags = reg_flags; - SetColor((reg_flags ^ oldflags)&FLAG_CF); + SetColor(changed_flags&FLAG_CF); mvwprintw (dbg.win_reg,1,53,"%01X",GETFLAG(CF) ? 1:0); - SetColor((reg_flags ^ oldflags)&FLAG_ZF); + SetColor(changed_flags&FLAG_ZF); mvwprintw (dbg.win_reg,1,56,"%01X",GETFLAG(ZF) ? 1:0); - SetColor((reg_flags ^ oldflags)&FLAG_SF); + SetColor(changed_flags&FLAG_SF); mvwprintw (dbg.win_reg,1,59,"%01X",GETFLAG(SF) ? 1:0); - SetColor((reg_flags ^ oldflags)&FLAG_OF); + SetColor(changed_flags&FLAG_OF); mvwprintw (dbg.win_reg,1,62,"%01X",GETFLAG(OF) ? 1:0); - SetColor((reg_flags ^ oldflags)&FLAG_AF); + SetColor(changed_flags&FLAG_AF); mvwprintw (dbg.win_reg,1,65,"%01X",GETFLAG(AF) ? 1:0); - SetColor((reg_flags ^ oldflags)&FLAG_PF); + SetColor(changed_flags&FLAG_PF); mvwprintw (dbg.win_reg,1,68,"%01X",GETFLAG(PF) ? 1:0); - SetColor((reg_flags ^ oldflags)&FLAG_DF); + SetColor(changed_flags&FLAG_DF); mvwprintw (dbg.win_reg,1,71,"%01X",GETFLAG(DF) ? 1:0); - SetColor((reg_flags ^ oldflags)&FLAG_IF); + SetColor(changed_flags&FLAG_IF); mvwprintw (dbg.win_reg,1,74,"%01X",GETFLAG(IF) ? 1:0); - SetColor((reg_flags ^ oldflags)&FLAG_TF); + SetColor(changed_flags&FLAG_TF); mvwprintw (dbg.win_reg,1,77,"%01X",GETFLAG(TF) ? 1:0); - SetColor((reg_flags ^ oldflags)&FLAG_IOPL); + SetColor(changed_flags&FLAG_IOPL); mvwprintw (dbg.win_reg,2,72,"%01X",GETFLAG(IOPL)>>12); - oldflags=reg_flags; + SetColor(cpu.cpl ^ oldcpucpl); mvwprintw (dbg.win_reg,2,78,"%01X",cpu.cpl); @@ -737,7 +747,7 @@ static void DrawRegisters(void) { mvwprintw(dbg.win_reg,0,76,"Real"); // Selector info, if available - if ((cpu.pmode) && curSelectorName[0]) { + if ((cpu.pmode) && curSelectorName[0]) { char out1[200], out2[200]; GetDescriptorInfo(curSelectorName,out1,out2); mvwprintw(dbg.win_reg,2,28,out1); @@ -755,6 +765,7 @@ static void DrawCode(void) Bit32u disEIP = codeViewData.useEIP; PhysPt start = GetAddress(codeViewData.useCS,codeViewData.useEIP); char dline[200];Bitu size;Bitu c; + static char line20[21] = " "; for (int i=0;i<10;i++) { saveSel = false; @@ -786,19 +797,29 @@ static void DrawCode(void) if (drawsize>10) { toolarge = true; drawsize = 9; }; for (c=0;c=drawsize*2;c--) waddch(dbg.win_code,' '); - + if (toolarge) { waddstr(dbg.win_code,".."); drawsize++; }; + // Spacepad up to 20 characters + if(drawsize && (drawsize < 10)) { + line20[20 - drawsize*2] = 0; + waddstr(dbg.win_code,line20); + line20[20 - drawsize*2] = ' '; + } else waddstr(dbg.win_code,line20); + char* res = 0; if (showExtend) res = AnalyzeInstruction(dline, saveSel); + // Spacepad it up to 28 characters + size_t dline_len = strlen(dline); + if(dline_len < 28) for (c = dline_len; c < 28;c++) dline[c] = ' '; dline[28] = 0; waddstr(dbg.win_code,dline); - if (strlen(dline)<28) for (c=28-strlen(dline);c>0;c--) waddch(dbg.win_code,' '); - if (showExtend) { + // Spacepad it up to 20 characters + size_t res_len = strlen(res); + if(res_len && (res_len < 21)) { waddstr(dbg.win_code,res); - for (c=strlen(res);c<20;c++) waddch(dbg.win_code,' '); - } else { - for (c=0;c<20;c++) waddch(dbg.win_code,' '); - } + line20[20-res_len] = 0; + waddstr(dbg.win_code,line20); + line20[20-res_len] = ' '; + } else waddstr(dbg.win_code,line20); + start+=size; disEIP+=size; @@ -810,14 +831,14 @@ static void DrawCode(void) wattrset(dbg.win_code,0); if (!debugging) { - mvwprintw(dbg.win_code,10,0,"(Running)",codeViewData.inputStr); - } else if (codeViewData.inputMode) { - mvwprintw(dbg.win_code,10,0,"-> %s_ ",codeViewData.inputStr); - } else { - mvwprintw(dbg.win_code,10,0," "); - for (c=0;c<50;c++) waddch(dbg.win_code,' '); - }; - + mvwprintw(dbg.win_code,10,0,"(Running)",codeViewData.inputStr); + } else { + if(!*codeViewData.inputStr) { //Clear old commands + mvwprintw(dbg.win_code,10,0," "); + } + mvwprintw(dbg.win_code,10,0,"-> %s_ ",codeViewData.inputStr); + } + wrefresh(dbg.win_code); } @@ -842,41 +863,45 @@ static void SetCodeWinStart() Bit32u GetHexValue(char* str, char*& hex) { Bit32u value = 0; - + Bit32u regval = 0; hex = str; while (*hex==' ') hex++; - if (strstr(hex,"EAX")==hex) { hex+=3; return reg_eax; }; - if (strstr(hex,"EBX")==hex) { hex+=3; return reg_ebx; }; - if (strstr(hex,"ECX")==hex) { hex+=3; return reg_ecx; }; - if (strstr(hex,"EDX")==hex) { hex+=3; return reg_edx; }; - if (strstr(hex,"ESI")==hex) { hex+=3; return reg_esi; }; - if (strstr(hex,"EDI")==hex) { hex+=3; return reg_edi; }; - if (strstr(hex,"EBP")==hex) { hex+=3; return reg_ebp; }; - if (strstr(hex,"ESP")==hex) { hex+=3; return reg_esp; }; - if (strstr(hex,"EIP")==hex) { hex+=3; return reg_eip; }; - if (strstr(hex,"AX")==hex) { hex+=2; return reg_ax; }; - if (strstr(hex,"BX")==hex) { hex+=2; return reg_bx; }; - if (strstr(hex,"CX")==hex) { hex+=2; return reg_cx; }; - if (strstr(hex,"DX")==hex) { hex+=2; return reg_dx; }; - if (strstr(hex,"SI")==hex) { hex+=2; return reg_si; }; - if (strstr(hex,"DI")==hex) { hex+=2; return reg_di; }; - if (strstr(hex,"BP")==hex) { hex+=2; return reg_bp; }; - if (strstr(hex,"SP")==hex) { hex+=2; return reg_sp; }; - if (strstr(hex,"IP")==hex) { hex+=2; return reg_ip; }; - if (strstr(hex,"CS")==hex) { hex+=2; return SegValue(cs); }; - if (strstr(hex,"DS")==hex) { hex+=2; return SegValue(ds); }; - if (strstr(hex,"ES")==hex) { hex+=2; return SegValue(es); }; - if (strstr(hex,"FS")==hex) { hex+=2; return SegValue(fs); }; - if (strstr(hex,"GS")==hex) { hex+=2; return SegValue(gs); }; - if (strstr(hex,"SS")==hex) { hex+=2; return SegValue(ss); }; + if (strstr(hex,"EAX")==hex) { hex+=3; regval = reg_eax; }; + if (strstr(hex,"EBX")==hex) { hex+=3; regval = reg_ebx; }; + if (strstr(hex,"ECX")==hex) { hex+=3; regval = reg_ecx; }; + if (strstr(hex,"EDX")==hex) { hex+=3; regval = reg_edx; }; + if (strstr(hex,"ESI")==hex) { hex+=3; regval = reg_esi; }; + if (strstr(hex,"EDI")==hex) { hex+=3; regval = reg_edi; }; + if (strstr(hex,"EBP")==hex) { hex+=3; regval = reg_ebp; }; + if (strstr(hex,"ESP")==hex) { hex+=3; regval = reg_esp; }; + if (strstr(hex,"EIP")==hex) { hex+=3; regval = reg_eip; }; + if (strstr(hex,"AX")==hex) { hex+=2; regval = reg_ax; }; + if (strstr(hex,"BX")==hex) { hex+=2; regval = reg_bx; }; + if (strstr(hex,"CX")==hex) { hex+=2; regval = reg_cx; }; + if (strstr(hex,"DX")==hex) { hex+=2; regval = reg_dx; }; + if (strstr(hex,"SI")==hex) { hex+=2; regval = reg_si; }; + if (strstr(hex,"DI")==hex) { hex+=2; regval = reg_di; }; + if (strstr(hex,"BP")==hex) { hex+=2; regval = reg_bp; }; + if (strstr(hex,"SP")==hex) { hex+=2; regval = reg_sp; }; + if (strstr(hex,"IP")==hex) { hex+=2; regval = reg_ip; }; + if (strstr(hex,"CS")==hex) { hex+=2; regval = SegValue(cs); }; + if (strstr(hex,"DS")==hex) { hex+=2; regval = SegValue(ds); }; + if (strstr(hex,"ES")==hex) { hex+=2; regval = SegValue(es); }; + if (strstr(hex,"FS")==hex) { hex+=2; regval = SegValue(fs); }; + if (strstr(hex,"GS")==hex) { hex+=2; regval = SegValue(gs); }; + if (strstr(hex,"SS")==hex) { hex+=2; regval = SegValue(ss); }; while (*hex) { - if ((*hex>='0') && (*hex<='9')) value = (value<<4)+*hex-'0'; else - if ((*hex>='A') && (*hex<='F')) value = (value<<4)+*hex-'A'+10; - else break; // No valid char + if ((*hex>='0') && (*hex<='9')) value = (value<<4)+*hex-'0'; + else if ((*hex>='A') && (*hex<='F')) value = (value<<4)+*hex-'A'+10; + else { + if(*hex == '+') {hex++;return regval + value + GetHexValue(hex,hex); }; + if(*hex == '-') {hex++;return regval + value - GetHexValue(hex,hex); }; + break; // No valid char + } hex++; }; - return value; + return regval + value; }; bool ChangeRegister(char* str) @@ -911,34 +936,38 @@ bool ChangeRegister(char* str) if (strstr(hex,"CF")==hex) { hex+=2; SETFLAGBIT(CF,GetHexValue(hex,hex)); } else if (strstr(hex,"DF")==hex) { hex+=2; SETFLAGBIT(DF,GetHexValue(hex,hex)); } else if (strstr(hex,"IF")==hex) { hex+=2; SETFLAGBIT(IF,GetHexValue(hex,hex)); } else - if (strstr(hex,"OF")==hex) { hex+=3; SETFLAGBIT(OF,GetHexValue(hex,hex)); } else - if (strstr(hex,"ZF")==hex) { hex+=3; SETFLAGBIT(ZF,GetHexValue(hex,hex)); } else - if (strstr(hex,"PF")==hex) { hex+=3; SETFLAGBIT(PF,GetHexValue(hex,hex)); } else - if (strstr(hex,"SF")==hex) { hex+=3; SETFLAGBIT(SF,GetHexValue(hex,hex)); } else + if (strstr(hex,"OF")==hex) { hex+=2; SETFLAGBIT(OF,GetHexValue(hex,hex)); } else + if (strstr(hex,"ZF")==hex) { hex+=2; SETFLAGBIT(ZF,GetHexValue(hex,hex)); } else + if (strstr(hex,"PF")==hex) { hex+=2; SETFLAGBIT(PF,GetHexValue(hex,hex)); } else + if (strstr(hex,"SF")==hex) { hex+=2; SETFLAGBIT(SF,GetHexValue(hex,hex)); } else { return false; }; return true; }; -bool ParseCommand(char* str) -{ +bool ParseCommand(char* str) { char* found = str; for(char* idx = found;*idx != 0; idx++) *idx = toupper(*idx); found = trim(found); + string s_found(found); + istringstream stream(s_found); + string command; + stream >> command; + string::size_type next = s_found.find_first_not_of(' ',command.size()); + if(next == string::npos) next = command.size(); + s_found.erase(0,next); + found = const_cast(s_found.c_str()); - found = strstr(str,"MEMDUMP "); - if (found) { // Insert variable - found+=8; + if (command == "MEMDUMP") { // Dump memory to file Bit16u seg = (Bit16u)GetHexValue(found,found); found++; Bit32u ofs = GetHexValue(found,found); found++; Bit32u num = GetHexValue(found,found); found++; SaveMemory(seg,ofs,num); return true; }; - found = strstr(str,"MEMDUMPBIN "); - if (found) { // Insert variable - found+=11; + + if (command == "MEMDUMPBIN") { // Dump memory to file bineary Bit16u seg = (Bit16u)GetHexValue(found,found); found++; Bit32u ofs = GetHexValue(found,found); found++; Bit32u num = GetHexValue(found,found); found++; @@ -946,60 +975,52 @@ bool ParseCommand(char* str) return true; }; - found = strstr(str,"IV "); - if (found) { // Insert variable - found+=3; + if (command == "IV") { // Insert variable Bit16u seg = (Bit16u)GetHexValue(found,found); found++; Bit32u ofs = (Bit16u)GetHexValue(found,found); found++; char name[16]; for (int i=0; i<16; i++) { - if ((found[i]!=' ') && (found[i]!=0)) name[i] = found[i]; + if (found[i] && (found[i]!=' ')) name[i] = found[i]; else { name[i] = 0; break; }; }; name[15] = 0; - + + if(!name[0]) return false; DEBUG_ShowMsg("DEBUG: Created debug var %s at %04X:%04X\n",name,seg,ofs); CDebugVar::InsertVariable(name,GetAddress(seg,ofs)); return true; - } - - found = strstr(str,"SV "); - if (found) { // Save variables - found+=3; - char name[13]; - for (int i=0; i<12; i++) { - if ((found[i]!=' ') && (found[i]!=0)) name[i] = found[i]; - else { name[i] = 0; break; }; - }; - name[12] = 0; - if (CDebugVar::SaveVars(name)) DEBUG_ShowMsg("DEBUG: Variable list save (%s) : ok.\n",name); - else DEBUG_ShowMsg("DEBUG: Variable list save (%s) : failure\n",name); - return true; - } + }; - found = strstr(str,"LV "); - if (found) { // load variables - found+=3; + if (command == "SV") { // Save variables char name[13]; for (int i=0; i<12; i++) { - if ((found[i]!=' ') && (found[i]!=0)) name[i] = found[i]; + if (found[i] && (found[i]!=' ')) name[i] = found[i]; else { name[i] = 0; break; }; }; - name[12] = 0; - if (CDebugVar::LoadVars(name)) DEBUG_ShowMsg("DEBUG: Variable list load (%s) : ok.\n",name); - else DEBUG_ShowMsg("DEBUG: Variable list load (%s) : failure\n",name); + name[12] = 0; + if(!name[0]) return false; + DEBUG_ShowMsg("DEBUG: Variable list save (%s) : %s.\n",name,(CDebugVar::SaveVars(name)?"ok":"failure")); return true; - } - found = strstr(str,"SR "); - if (found) { // Set register value - found+=2; - if (ChangeRegister(found)) DEBUG_ShowMsg("DEBUG: Set Register success.\n"); - else DEBUG_ShowMsg("DEBUG: Set Register failure.\n"); + }; + + if (command == "LV") { // load variables + char name[13]; + for (int i=0; i<12; i++) { + if (found[i] && (found[i]!=' ')) name[i] = found[i]; + else { name[i] = 0; break; }; + }; + name[12] = 0; + if(!name[0]) return false; + DEBUG_ShowMsg("DEBUG: Variable list load (%s) : %s.\n",name,(CDebugVar::SaveVars(name)?"ok":"failure")); return true; - } - found = strstr(str,"SM "); - if (found) { // Set memory with following values - found+=3; + }; + + if (command == "SR") { // Set register value + DEBUG_ShowMsg("DEBUG: Set Register success.\n",(ChangeRegister(found)?"success":"failure")); + return true; + }; + + if (command == "SM") { // Set memory with following values Bit16u seg = (Bit16u)GetHexValue(found,found); found++; Bit32u ofs = GetHexValue(found,found); found++; Bit16u count = 0; @@ -1013,53 +1034,48 @@ bool ParseCommand(char* str) }; DEBUG_ShowMsg("DEBUG: Memory changed.\n"); return true; - } + }; - found = strstr(str,"BP "); - if (found) { // Add new breakpoint - found+=3; + if (command == "BP") { // Add new breakpoint Bit16u seg = (Bit16u)GetHexValue(found,found);found++; // skip ":" Bit32u ofs = GetHexValue(found,found); CBreakpoint::AddBreakpoint(seg,ofs,false); DEBUG_ShowMsg("DEBUG: Set breakpoint at %04X:%04X\n",seg,ofs); return true; - } + }; + #if C_HEAVY_DEBUG - found = strstr(str,"BPM "); - if (found) { // Add new breakpoint - found+=3; + + if (command == "BPM") { // Add new breakpoint Bit16u seg = (Bit16u)GetHexValue(found,found);found++; // skip ":" Bit32u ofs = GetHexValue(found,found); CBreakpoint::AddMemBreakpoint(seg,ofs); DEBUG_ShowMsg("DEBUG: Set memory breakpoint at %04X:%04X\n",seg,ofs); return true; - } - found = strstr(str,"BPPM "); - if (found) { // Add new breakpoint - found+=4; + }; + + if (command == "BPPM") { // Add new breakpoint Bit16u seg = (Bit16u)GetHexValue(found,found);found++; // skip ":" Bit32u ofs = GetHexValue(found,found); CBreakpoint* bp = CBreakpoint::AddMemBreakpoint(seg,ofs); - if (bp) - { + if (bp) { bp->SetType(BKPNT_MEMORY_PROT); DEBUG_ShowMsg("DEBUG: Set prot-mode memory breakpoint at %04X:%08X\n",seg,ofs); } return true; - } - found = strstr(str,"BPLM "); - if (found) { // Add new breakpoint - found+=4; - Bitu ofs = GetHexValue(found,found); + }; + + if (command == "BPLM") { // Add new breakpoint + Bit32u ofs = GetHexValue(found,found); CBreakpoint* bp = CBreakpoint::AddMemBreakpoint(0,ofs); if (bp) bp->SetType(BKPNT_MEMORY_LINEAR); DEBUG_ShowMsg("DEBUG: Set linear memory breakpoint at %08X\n",ofs); return true; - } + }; + #endif - found = strstr(str,"BPINT"); - if (found) { // Add Interrupt Breakpoint - found+=5; + + if (command == "BPINT") { // Add Interrupt Breakpoint Bit8u intNr = (Bit8u)GetHexValue(found,found); bool all = !(*found);found++; Bit8u valAH = (Bit8u)GetHexValue(found,found); @@ -1071,18 +1087,16 @@ bool ParseCommand(char* str) DEBUG_ShowMsg("DEBUG: Set interrupt breakpoint at INT %02X AH=%02X\n",intNr,valAH); } return true; - } - found = strstr(str,"BPLIST"); - if (found) { + }; + + if (command == "BPLIST") { DEBUG_ShowMsg("Breakpoint list:\n"); DEBUG_ShowMsg("-------------------------------------------------------------------------\n"); CBreakpoint::ShowList(); return true; }; - found = strstr(str,"BPDEL"); - if (found) { // Delete Breakpoints - found+=5; + if (command == "BPDEL") { // Delete Breakpoints Bit8u bpNr = (Bit8u)GetHexValue(found,found); if ((bpNr==0x00) && (*found=='*')) { // Delete all CBreakpoint::DeleteAll(); @@ -1092,202 +1106,150 @@ bool ParseCommand(char* str) CBreakpoint::DeleteByIndex(bpNr); } return true; - } - found = strstr(str,"C "); - if (found==(char*)str) { // Set code overview - found++; + }; + + if (command == "C") { // Set code overview Bit16u codeSeg = (Bit16u)GetHexValue(found,found); found++; Bit32u codeOfs = GetHexValue(found,found); DEBUG_ShowMsg("DEBUG: Set code overview to %04X:%04X\n",codeSeg,codeOfs); codeViewData.useCS = codeSeg; codeViewData.useEIP = codeOfs; return true; - } - found = strstr(str,"D "); - if (found==(char*)str) { // Set data overview - found++; + }; + + if (command == "D") { // Set data overview dataSeg = (Bit16u)GetHexValue(found,found); found++; dataOfs = GetHexValue(found,found); DEBUG_ShowMsg("DEBUG: Set data overview to %04X:%04X\n",dataSeg,dataOfs); return true; - } + }; + #if C_HEAVY_DEBUG - found = strstr(str,"LOG "); - if (found) { // Create Cpu log file - found+=4; - DEBUG_ShowMsg("DEBUG: Starting log\n"); - cpuLogFile.open("LOGCPU.TXT"); - if (!cpuLogFile.is_open()) { - DEBUG_ShowMsg("DEBUG: Logfile couldn't be created.\n"); - return false; - } - cpuLogFile << hex << noshowbase << setfill('0') << uppercase; - cpuLog = true; + + if (command == "LOG") { // Create Cpu normal log file cpuLogType = 1; - cpuLogCounter = GetHexValue(found,found); - - debugging=false; - CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); - ignoreAddressOnce = SegPhys(cs)+reg_eip; - DOSBOX_SetNormalLoop(); - return true; + command = "logcode"; } - found = strstr(str,"LOGS "); - if (found) { // Create Cpu log file - found+=4; - DEBUG_ShowMsg("DEBUG: Starting log\n"); - cpuLogFile.open("LOGCPU.TXT"); - if (!cpuLogFile.is_open()) { - DEBUG_ShowMsg("DEBUG: Logfile couldn't be created.\n"); - return false; - } - cpuLogFile << hex << noshowbase << setfill('0') << uppercase; - cpuLog = true; + if (command == "LOGS") { // Create Cpu short log file cpuLogType = 0; - cpuLogCounter = GetHexValue(found,found); - - debugging=false; - CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); - ignoreAddressOnce = SegPhys(cs)+reg_eip; - DOSBOX_SetNormalLoop(); - return true; + command = "logcode"; } - found = strstr(str,"LOGL "); - if (found) { // Create Cpu log file - found+=4; + if (command == "LOGL") { // Create Cpu long log file + cpuLogType = 2; + command = "logcode"; + } + + if (command == "logcode") { //Shared code between all logs DEBUG_ShowMsg("DEBUG: Starting log\n"); cpuLogFile.open("LOGCPU.TXT"); if (!cpuLogFile.is_open()) { DEBUG_ShowMsg("DEBUG: Logfile couldn't be created.\n"); return false; } + //Initialize log object cpuLogFile << hex << noshowbase << setfill('0') << uppercase; cpuLog = true; - cpuLogType = 2; cpuLogCounter = GetHexValue(found,found); - debugging=false; + debugging = false; CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); ignoreAddressOnce = SegPhys(cs)+reg_eip; DOSBOX_SetNormalLoop(); return true; - } + }; + #endif - found = strstr(str,"INTT "); - if (found) { // Create Cpu log file - found+=4; + + if (command == "INTT") { //trace int. Bit8u intNr = (Bit8u)GetHexValue(found,found); DEBUG_ShowMsg("DEBUG: Tracing INT %02X\n",intNr); CPU_HW_Interrupt(intNr); SetCodeWinStart(); return true; - } - found = strstr(str,"INT "); - if (found) { // Create Cpu log file - found+=4; + }; + + if (command == "INT") { // start int. Bit8u intNr = (Bit8u)GetHexValue(found,found); DEBUG_ShowMsg("DEBUG: Starting INT %02X\n",intNr); - CBreakpoint::AddBreakpoint (SegValue(cs),reg_eip, true); + CBreakpoint::AddBreakpoint(SegValue(cs),reg_eip, true); CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip-1,true); - debugging=false; + debugging = false; DrawCode(); DOSBOX_SetNormalLoop(); CPU_HW_Interrupt(intNr); return true; - } - found = strstr(str,"SELINFO "); - if (found) { - found += 8; - while (found[0]==' ') found++; + }; + + if (command == "SELINFO") { + while (found[0] == ' ') found++; char out1[200],out2[200]; GetDescriptorInfo(found,out1,out2); - DEBUG_ShowMsg("SelectorInfo %s:\n",found); - DEBUG_ShowMsg("%s\n",out1); - DEBUG_ShowMsg("%s\n",out2); + DEBUG_ShowMsg("SelectorInfo %s:\n%s\n%s\n",found,out1,out2); }; - found = strstr(str,"GDT"); - if (found) { - LogGDT(); - } + if (command == "GDT") {LogGDT(); return true;} + + if (command == "LDT") {LogLDT(); return true;} + + if (command == "IDT") {LogIDT(); return true;} + + if (command == "PAGING") {LogPages(found); return true;} - found = strstr(str,"LDT"); - if (found) { - LogLDT(); - } + if (command == "CPU") {LogCPUInfo(); return true;} - found = strstr(str,"IDT"); - if (found) { - LogIDT(); - } - - found = strstr(str,"PAGING"); - if (found) { - found += 6; - while (found[0]==' ') found++; - LogPages(found); - } - - found = strstr(str,"CPU"); - if (found) { - LogCPUInfo(); - } - - found = strstr(str,"INTVEC "); - if (found) - { - found += 7; - while (found[0]==' ') found++; - if (found[0] != 0) + if (command == "INTVEC") { + if (found[0] != 0) { OutputVecTable(found); - } + return true; + } + }; - found = strstr(str,"INTHAND "); - if (found) - { - found += 8; - while (found[0]==' ') found++; - if (found[0] != 0) - { + if (command == "INTHAND") { + if (found[0] != 0) { Bit8u intNr = (Bit8u)GetHexValue(found,found); DEBUG_ShowMsg("DEBUG: Set code overview to interrupt handler %X\n",intNr); codeViewData.useCS = mem_readw(intNr*4+2); codeViewData.useEIP = mem_readw(intNr*4); return true; } - } + }; + + if(command == "EXTEND") { //Toggle additional data. + showExtend = !showExtend; + return true; + }; + + if(command == "TIMERIRQ") { //Start a timer irq + DEBUG_RaiseTimerIrq(); + DEBUG_ShowMsg("Debug: Timer Int started.\n"); + return true; + }; + #if C_HEAVY_DEBUG - found = strstr(str,"HEAVYLOG"); - if (found) { // Create Cpu log file + if (command == "HEAVYLOG") { // Create Cpu log file logHeavy = !logHeavy; - if (logHeavy) DEBUG_ShowMsg("DEBUG: Heavy cpu logging on.\n"); - else DEBUG_ShowMsg("DEBUG: Heavy cpu logging off.\n"); + DEBUG_ShowMsg("DEBUG: Heavy cpu logging %s.\n",logHeavy?"on":"off"); return true; - } - found = strstr(str,"ZEROPROTECT"); - if (found) { //toggle zero protection + }; + + if (command == "ZEROPROTECT") { //toggle zero protection zeroProtect = !zeroProtect; - if (zeroProtect) DEBUG_ShowMsg("DEBUG: Zero code execution protection on.\n"); - else DEBUG_ShowMsg("DEBUG: Zero code execution protection off.\n"); + DEBUG_ShowMsg("DEBUG: Zero code execution protection %s.\n",zeroProtect?"on":"off"); return true; - } + }; + #endif - if ((*str=='H') || (*str=='?')) { - DEBUG_ShowMsg("Debugger keys:\n"); + if (command == "HELP" || command == "?") { + DEBUG_ShowMsg("Debugger commands (enter all values in hex or as register):\n"); DEBUG_ShowMsg("--------------------------------------------------------------------------\n"); DEBUG_ShowMsg("F5 - Run.\n"); DEBUG_ShowMsg("F9 - Set/Remove breakpoint.\n"); DEBUG_ShowMsg("F10/F11 - Step over / trace into instruction.\n"); DEBUG_ShowMsg("Up/Down - Move code view cursor.\n"); - DEBUG_ShowMsg("Return - Enable command line input.\n"); - DEBUG_ShowMsg("D/E/S/X/B - Set data view to DS:SI/ES:DI/SS:SP/DS:DX/ES:BX.\n"); - DEBUG_ShowMsg("R/F - Scroll data view.\n"); - DEBUG_ShowMsg("V - Toggle additional info.\n"); - DEBUG_ShowMsg("Debugger commands (enter all values in hex or as register):\n"); - DEBUG_ShowMsg("--------------------------------------------------------------------------\n"); + DEBUG_ShowMsg("Page Up/Down - Scroll data view.\n"); DEBUG_ShowMsg("BP [segment]:[offset] - Set breakpoint.\n"); DEBUG_ShowMsg("BPINT [intNr] * - Set interrupt breakpoint.\n"); DEBUG_ShowMsg("BPINT [intNr] [ah] - Set interrupt breakpoint with ah.\n"); @@ -1325,11 +1287,13 @@ bool ParseCommand(char* str) DEBUG_ShowMsg("LDT - Lists descriptors of the LDT.\n"); DEBUG_ShowMsg("IDT - Lists descriptors of the IDT.\n"); DEBUG_ShowMsg("PAGING [page] - Display content of page table.\n"); + DEBUG_ShowMsg("EXTEND - Toggle additional info.\n"); + DEBUG_ShowMsg("TIMERIRQ - Run the system timer.\n"); - DEBUG_ShowMsg("H - Help\n"); + DEBUG_ShowMsg("HELP - Help\n"); - return TRUE; - } + return true; + }; return false; }; @@ -1507,143 +1471,92 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) Bit32u DEBUG_CheckKeys(void) { - - if (codeViewData.inputMode) { - int key = getch(); - if (key>0) { - switch (key) { - case 0x0A: codeViewData.inputMode = FALSE; - ParseCommand(codeViewData.inputStr); - break; - case 0x107: //backspace (linux) - case 0x7f: //backspace in some terminal emulators (linux) - case 0x08: // delete - if (strlen(codeViewData.inputStr)>0) codeViewData.inputStr[strlen(codeViewData.inputStr)-1] = 0; - break; - default : if ((key>=32) && (key<=128) && (strlen(codeViewData.inputStr)<253)) { - Bit32u len = strlen(codeViewData.inputStr); - codeViewData.inputStr[len] = char(key); - codeViewData.inputStr[len+1] = 0; - } - break; - } - DEBUG_DrawScreen(); - } - return 0; - }; - - int key=getch(); Bits ret=0; + int key=getch(); if (key>0) { switch (toupper(key)) { - case '1': - CPU_Cycles = 100; - ret=(*cpudecoder)(); - break; - case '2': - CPU_Cycles = 500; - ret=(*cpudecoder)(); - break; - case '3': - CPU_Cycles = 1000; - ret=(*cpudecoder)(); - break; - case '4': - CPU_Cycles = 5000; - ret=(*cpudecoder)(); - break; - case '5': - CPU_Cycles = 10000; - ret=(*cpudecoder)(); - break; - case 'q': - CPU_Cycles = 5; - ret=(*cpudecoder)(); - break; - case 'D': dataSeg = SegValue(ds); - if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_esi; - else dataOfs = reg_si; - break; - case 'E': dataSeg = SegValue(es); - if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_edi; - else dataOfs = reg_di; - break; - case 'X': dataSeg = SegValue(ds); - if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_edx; - else dataOfs = reg_dx; - break; - case 'B': dataSeg = SegValue(es); - if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_ebx; - else dataOfs = reg_bx; - break; - case 'S': dataSeg = SegValue(ss); - if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_esp; - else dataOfs = reg_sp; - break; + case KEY_PPAGE : dataOfs -= 16; break; + case KEY_NPAGE : dataOfs += 16; break; - case 'R' : dataOfs -= 16; break; - case 'F' : dataOfs += 16; break; - case 'H' : strcpy(codeViewData.inputStr,"H "); - ParseCommand(codeViewData.inputStr); - break; - case 'T' : DEBUG_RaiseTimerIrq(); - DEBUG_ShowMsg("Debug: Timer Int started.\n"); - break; - case 'V' : showExtend = !showExtend; - break; - - case 0x0A : // Return : input - codeViewData.inputMode = true; - codeViewData.inputStr[0] = 0; - break; case KEY_DOWN: // down - if (codeViewData.cursorPos<9) codeViewData.cursorPos++; - else codeViewData.useEIP += codeViewData.firstInstSize; - break; + if (codeViewData.cursorPos<9) codeViewData.cursorPos++; + else codeViewData.useEIP += codeViewData.firstInstSize; + break; case KEY_UP: // up - if (codeViewData.cursorPos>0) codeViewData.cursorPos--; - else codeViewData.useEIP -= 1; - break; - case KEY_HOME: // Home: scroll log page up - DEBUG_RefreshPage(-1); - break; - case KEY_END: // End: scroll log page down - DEBUG_RefreshPage(1); - break; - case KEY_F(5): // Run Programm - debugging=false; - CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); - ignoreAddressOnce = SegPhys(cs)+reg_eip; - DOSBOX_SetNormalLoop(); - break; - case KEY_F(9): // Set/Remove TBreakpoint - { PhysPt ptr = GetAddress(codeViewData.cursorSeg,codeViewData.cursorOfs); - if (CBreakpoint::IsBreakpoint(ptr)) CBreakpoint::DeleteBreakpoint(ptr); - else CBreakpoint::AddBreakpoint(codeViewData.cursorSeg, codeViewData.cursorOfs, false); + if (codeViewData.cursorPos>0) codeViewData.cursorPos--; + else { + Bitu bytes = 0; + char dline[200]; + Bitu size = 0; + Bit32u newEIP = codeViewData.useEIP - 1; + if(codeViewData.useEIP) { + for (; bytes < 10; bytes++) { + PhysPt start = GetAddress(codeViewData.useCS,newEIP); + size = DasmI386(dline, start, newEIP, cpu.code.big); + if(codeViewData.useEIP == newEIP+size) break; + newEIP--; } + if (bytes>=10) newEIP = codeViewData.useEIP - 1; + } + codeViewData.useEIP = newEIP; + } + break; + case KEY_HOME: // Home: scroll log page up + DEBUG_RefreshPage(-1); + break; + case KEY_END: // End: scroll log page down + DEBUG_RefreshPage(1); + break; + case KEY_F(5): // Run Programm + debugging=false; + CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); + ignoreAddressOnce = SegPhys(cs)+reg_eip; + DOSBOX_SetNormalLoop(); + break; + case KEY_F(9): // Set/Remove TBreakpoint + { PhysPt ptr = GetAddress(codeViewData.cursorSeg,codeViewData.cursorOfs); + if (CBreakpoint::IsBreakpoint(ptr)) CBreakpoint::DeleteBreakpoint(ptr); + else CBreakpoint::AddBreakpoint(codeViewData.cursorSeg, codeViewData.cursorOfs, false); + } break; case KEY_F(10): // Step over inst - if (StepOver()) return 0; - else { - exitLoop = false; - skipFirstInstruction = true; // for heavy debugger - CPU_Cycles = 1; - Bitu ret=(*cpudecoder)(); - SetCodeWinStart(); - CBreakpoint::ignoreOnce = 0; - } - break; + if (StepOver()) return 0; + else { + exitLoop = false; + skipFirstInstruction = true; // for heavy debugger + CPU_Cycles = 1; + ret=(*cpudecoder)(); + SetCodeWinStart(); + CBreakpoint::ignoreOnce = 0; + } + break; case KEY_F(11): // trace into - exitLoop = false; - skipFirstInstruction = true; // for heavy debugger - CPU_Cycles = 1; - ret = (*cpudecoder)(); - SetCodeWinStart(); - CBreakpoint::ignoreOnce = 0; - break; + exitLoop = false; + skipFirstInstruction = true; // for heavy debugger + CPU_Cycles = 1; + ret = (*cpudecoder)(); + SetCodeWinStart(); + CBreakpoint::ignoreOnce = 0; + break; + case 0x0A: //Parse typed Command + codeViewData.inputMode = true; + if(ParseCommand(codeViewData.inputStr)) codeViewData.inputStr[0] = 0; + break; + case 0x107: //backspace (linux) + case 0x7f: //backspace in some terminal emulators (linux) + case 0x08: // delete + if (strlen(codeViewData.inputStr)>0) codeViewData.inputStr[strlen(codeViewData.inputStr)-1] = 0; + break; + default : if ((key>=32) && (key<=128) && (strlen(codeViewData.inputStr)<253)) { + Bit32u len = strlen(codeViewData.inputStr); + codeViewData.inputStr[len] = char(key); + codeViewData.inputStr[len+1] = 0; + } + break; + } - if (ret<0) return ret; - if (ret>0){ + if (ret<0) return ret; + if (ret>0) { ret=(*CallBack_Handlers[ret])(); if (ret) { exitLoop=true; @@ -1685,7 +1598,7 @@ void DEBUG_Enable(bool pressed) { DOSBOX_SetLoop(&DEBUG_Loop); if(!showhelp) { showhelp=true; - DEBUG_ShowMsg("***| PRESS \"H\" TO SHOW ALL COMMANDS. PRESS \"RETURN\" TO ENTER COMMANDMODE. |***\n"); + DEBUG_ShowMsg("***| TYPE HELP (+ENTER) TO GET AN OVERVIEW OF ALL COMMANDS |***\n"); } KEYBOARD_ClrBuffer(); } diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 0b6e8f11..44473df7 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug_gui.cpp,v 1.29 2006-04-11 19:02:33 qbix79 Exp $ */ +/* $Id: debug_gui.cpp,v 1.30 2006-06-16 14:51:31 qbix79 Exp $ */ #include "dosbox.h" @@ -144,13 +144,13 @@ static void DrawBars(void) { /* Show the Register bar */ mvaddstr(dbg.win_reg->_begy-1,0, "---(Register Overview )---"); /* Show the Data Overview bar perhaps with more special stuff in the end */ - mvaddstr(dbg.win_data->_begy-1,0,"---(Data Overview Scroll: r/f )---"); + mvaddstr(dbg.win_data->_begy-1,0,"---(Data Overview Scroll: page up/down)---"); /* Show the Code Overview perhaps with special stuff in bar too */ - mvaddstr(dbg.win_code->_begy-1,0,"---(Code Overview Scroll: up/down )---"); + mvaddstr(dbg.win_code->_begy-1,0,"---(Code Overview Scroll: up/down )---"); /* Show the Variable Overview bar */ mvaddstr(dbg.win_var->_begy-1,0, "---(Variable Overview )---"); /* Show the Output OverView */ - mvaddstr(dbg.win_out->_begy-1,0, "---(OutPut/Input Scroll: home/end )---"); + mvaddstr(dbg.win_out->_begy-1,0, "---(OutPut/Input Scroll: home/end )---"); attrset(0); } @@ -199,7 +199,7 @@ static void LOG_Init(Section * sec) { }else{ debuglog=0; } - sect->AddDestroyFunction(LOG_Destroy); + sect->AddDestroyFunction(&LOG_Destroy); char buf[1024]; for (Bitu i=1;i Date: Sat, 17 Jun 2006 08:42:38 +0000 Subject: [PATCH 2569/4131] erase is a macro on certain hosts? Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2654 --- src/debug/debug.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 42881792..ddf6dea6 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.80 2006-06-16 14:51:31 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.81 2006-06-17 08:42:38 qbix79 Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -956,7 +956,7 @@ bool ParseCommand(char* str) { stream >> command; string::size_type next = s_found.find_first_not_of(' ',command.size()); if(next == string::npos) next = command.size(); - s_found.erase(0,next); + (s_found.erase)(0,next); found = const_cast(s_found.c_str()); if (command == "MEMDUMP") { // Dump memory to file From e3fe68c847fe612acbe49eafa7e54a5add6d9d2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 20 Jun 2006 17:14:04 +0000 Subject: [PATCH 2570/4131] fix some trapflag bugs, add partial trapflag handling to the dynamic core Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2655 --- include/cpu.h | 1 + src/cpu/core_dyn_x86.cpp | 22 +++++++++++++++++++++- src/cpu/core_dyn_x86/decoder.h | 2 +- src/cpu/core_normal.cpp | 6 +----- src/cpu/core_normal/prefix_none.h | 12 ------------ src/cpu/core_simple.cpp | 3 +-- 6 files changed, 25 insertions(+), 21 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 8562ee0f..2bbbe220 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -45,6 +45,7 @@ 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); //CPU Stuff diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index daf97fd7..58ea04e4 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -112,6 +112,7 @@ enum BlockReturn { #if (C_DEBUG) BR_OpcodeFull, #endif + BR_Iret, BR_CallBack, BR_SMCBlock }; @@ -241,6 +242,13 @@ 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()) return debugCallback; +#endif + if (!GETFLAG(TF)) goto restart_core; + cpudecoder=CPU_Core_Dyn_X86_Trap_Run; + return CBRET_NONE; case BR_Normal: /* Maybe check if we staying in the same page? */ #if C_HEAVY_DEBUG @@ -283,7 +291,19 @@ run_block: } goto restart_core; } -return 0; + return CBRET_NONE; +} + +Bits CPU_Core_Dyn_X86_Trap_Run(void) { + Bits oldCycles = CPU_Cycles; + CPU_Cycles = 1; + + Bits ret=CPU_Core_Normal_Run(); + if (GETFLAG(TF)) CPU_HW_Interrupt(1); + CPU_Cycles = oldCycles-1; + cpudecoder = &CPU_Core_Dyn_X86_Run; + + return ret; } void CPU_Core_Dyn_X86_Init(void) { diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 6f17d1ae..a4bb7174 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1197,7 +1197,7 @@ static void dyn_iret(void) { dyn_set_eip_last_end(DREG(TMPW)); dyn_save_critical_regs(); gen_call_function((void*)&CPU_IRET,"%Id%Drd",decode.big_op,DREG(TMPW)); - gen_return_fast(BR_Normal); + gen_return_fast(BR_Iret); dyn_closeblock(); } diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index f71a6f1f..14e65403 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -95,9 +95,6 @@ static struct { bool rep_zero; Bitu prefixes; GetEAHandler * ea_table; - struct { - bool skip; - } trap; } core; #define GETIP (core.cseip-SegBase(cs)) @@ -191,10 +188,9 @@ decode_end: Bits CPU_Core_Normal_Trap_Run(void) { Bits oldCycles = CPU_Cycles; CPU_Cycles = 1; - core.trap.skip=false; Bits ret=CPU_Core_Normal_Run(); - if (!core.trap.skip) CPU_HW_Interrupt(1); + if (GETFLAG(TF)) CPU_HW_Interrupt(1); CPU_Cycles = oldCycles-1; cpudecoder = &CPU_Core_Normal_Run; diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index c2d8113a..97ea24d2 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -734,9 +734,6 @@ return debugCallback; #endif CPU_SW_Interrupt_NoIOPLCheck(3,GETIP); -#if CPU_TRAP_CHECK - core.trap.skip=true; -#endif continue; CASE_B(0xcd) /* INT Ib */ { @@ -748,18 +745,12 @@ } #endif CPU_SW_Interrupt(num,GETIP); -#if CPU_TRAP_CHECK - core.trap.skip=true; -#endif continue; } CASE_B(0xce) /* INTO */ if (get_OF()) { FillFlags(); CPU_SW_Interrupt(4,GETIP); -#if CPU_TRAP_CHECK - core.trap.skip=true; -#endif continue; } break; @@ -943,9 +934,6 @@ CASE_B(0xf1) /* ICEBP */ FillFlags(); CPU_SW_Interrupt_NoIOPLCheck(1,GETIP); -#if CPU_TRAP_CHECK - core.trap.skip=true; -#endif continue; CASE_B(0xf2) /* REPNZ */ DO_PREFIX_REP(false); diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp index 72d722e5..c07aeba7 100644 --- a/src/cpu/core_simple.cpp +++ b/src/cpu/core_simple.cpp @@ -185,10 +185,9 @@ Bits CPU_Core_Simple_Trap_Run(void) { Bits oldCycles = CPU_Cycles; CPU_Cycles = 1; - core.trap.skip=false; Bits ret=CPU_Core_Normal_Run(); - if (!core.trap.skip) CPU_SW_Interrupt(1,reg_eip); + if (GETFLAG(TF)) CPU_SW_Interrupt(1,reg_eip); CPU_Cycles = oldCycles-1; cpudecoder = &CPU_Core_Normal_Run; From bf6a8d4c3d65acf396e2d11b8011a50a5629920c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 21 Jun 2006 08:52:02 +0000 Subject: [PATCH 2571/4131] Don't change colours on text mode stuff. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2656 --- src/ints/int10_pal.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 62f43985..5becfce6 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -239,6 +239,8 @@ void INT10_SetColorSelect(Bit8u val) { if (machine == MCH_CGA || IS_TANDY_ARCH) IO_Write(0x3d9,temp); else if (machine == MCH_VGA) { + if (CurMode->mode <= 3) //Maybe even skip the total function! + return; val = (temp & 0x10) | 2 | val; INT10_SetSinglePaletteRegister( 1, val ); val+=2; From 35201631c9d821bf2c87ba7c8982c82735ca7d99 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Jun 2006 08:34:38 +0000 Subject: [PATCH 2572/4131] add escape and change old e,x,d keybinding to alt e,x,d Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2657 --- src/debug/debug.cpp | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index ddf6dea6..c52a1671 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.81 2006-06-17 08:42:38 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.82 2006-06-22 08:34:38 qbix79 Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -834,7 +834,7 @@ static void DrawCode(void) mvwprintw(dbg.win_code,10,0,"(Running)",codeViewData.inputStr); } else { if(!*codeViewData.inputStr) { //Clear old commands - mvwprintw(dbg.win_code,10,0," "); + mvwprintw(dbg.win_code,10,0," "); } mvwprintw(dbg.win_code,10,0,"-> %s_ ",codeViewData.inputStr); } @@ -1248,6 +1248,8 @@ bool ParseCommand(char* str) { DEBUG_ShowMsg("F5 - Run.\n"); DEBUG_ShowMsg("F9 - Set/Remove breakpoint.\n"); DEBUG_ShowMsg("F10/F11 - Step over / trace into instruction.\n"); + DEBUG_ShowMsg("ALT + D/E/S/X/B - Set data view to DS:SI/ES:DI/SS:SP/DS:DX/ES:BX.\n"); + DEBUG_ShowMsg("Escape - clear input line."); DEBUG_ShowMsg("Up/Down - Move code view cursor.\n"); DEBUG_ShowMsg("Page Up/Down - Scroll data view.\n"); DEBUG_ShowMsg("BP [segment]:[offset] - Set breakpoint.\n"); @@ -1475,6 +1477,43 @@ Bit32u DEBUG_CheckKeys(void) { int key=getch(); if (key>0) { switch (toupper(key)) { + case 27: // escape (a bit slow): Clears line. and processes alt commands. + key=getch(); + if(key < 0) { //Purely escape Clear line + codeViewData.inputStr[0] = 0; + break; + } + + switch(toupper(key)) { + case 'D' : // ALT - D: DS:SI + dataSeg = SegValue(ds); + if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_esi; + else dataOfs = reg_si; + break; + case 'E' : //ALT - E: es:di + dataSeg = SegValue(es); + if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_edi; + else dataOfs = reg_di; + break; + case 'X': //ALT - X: ds:dx + dataSeg = SegValue(ds); + if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_edx; + else dataOfs = reg_dx; + break; + case 'B' : //ALT -B: es:bx + dataSeg = SegValue(es); + if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_ebx; + else dataOfs = reg_bx; + break; + case 'S': //ALT - S: ss:sp + dataSeg = SegValue(ss); + if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_esp; + else dataOfs = reg_sp; + break; + default: + break; + } + break; case KEY_PPAGE : dataOfs -= 16; break; case KEY_NPAGE : dataOfs += 16; break; From 3ea5a913a9050d492e82a80cfdcc6b6e03679b73 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Jun 2006 13:15:07 +0000 Subject: [PATCH 2573/4131] Add rewriten form of patch "[ 1498334 ] CD Images unmounting" created by Kronutz Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2658 --- include/dos_system.h | 4 +- src/dos/dos_files.cpp | 4 +- src/dos/dos_mscdex.cpp | 205 +++++++++++++++++++++++++------------- src/dos/dos_programs.cpp | 57 ++++++++--- src/dos/drive_fat.cpp | 7 +- src/dos/drive_iso.cpp | 15 ++- src/dos/drive_local.cpp | 20 +++- src/dos/drive_virtual.cpp | 7 +- src/dos/drives.h | 9 +- 9 files changed, 239 insertions(+), 89 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index b49a0508..0e1311e1 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.35 2006-04-23 14:20:57 c2woody Exp $ */ +/* $Id: dos_system.h,v 1.36 2006-06-22 13:15:07 qbix79 Exp $ */ #ifndef DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H @@ -229,6 +229,8 @@ public: 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 curdir[DOS_PATHLENGTH]; char info[256]; diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 0eedde22..9d6d350a 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.74 2006-05-28 09:40:42 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.75 2006-06-22 13:15:07 qbix79 Exp $ */ #include #include @@ -535,7 +535,7 @@ bool DOS_SetFileAttr(char * name,Bit16u attr) Bit16u attrTemp; char fullname[DOS_PATHLENGTH];Bit8u drive; if (!DOS_MakeName(name,fullname,&drive)) return false; - if (strcmp(Drives[drive]->GetInfo(),"CDRom.")==0 || strcmp(Drives[drive]->GetInfo(),"isoDrive")==0) { + if (strncmp(Drives[drive]->GetInfo(),"CDRom ",6)==0 || strncmp(Drives[drive]->GetInfo(),"isoDrive ",9)==0) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 0bf8fffa..01aa8fdf 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.42 2006-04-21 08:35:31 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.43 2006-06-22 13:15:07 qbix79 Exp $ */ #include #include @@ -107,6 +107,7 @@ public: bool GetSubChannelData (Bit8u subUnit, Bit8u& attr, Bit8u& track, Bit8u &index, TMSF& rel, TMSF& abs); + int RemoveDrive (Bit16u _drive); int AddDrive (Bit16u _drive, char* physicalPath, Bit8u& subUnit); void GetDrives (PhysPt data); void GetDriverInfo (PhysPt data); @@ -197,10 +198,113 @@ Bit8u CMscdex::GetSubUnit(Bit16u _drive) return 0xff; }; +int CMscdex::RemoveDrive(Bit16u _drive) +{ + Bit16u idx = MSCDEX_MAX_DRIVES; + for (Bit16u i=0; i=MSCDEX_MAX_DRIVES) return 4; + if (GetNumDrives()) { + // Error check, driveletter have to be in a row + if (dinfo[0].drive-1!=_drive && dinfo[numDrives-1].drive+1!=_drive) + return 1; + } + // Set return type to ok + int result = 0; + // Get Mounttype and init needed cdrom interface + switch (CDROM_GetMountType(physicalPath,forceCD)) { + case 0x00: { + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting physical cdrom: %s" ,physicalPath); +#if defined (WIN32) + // Check OS + OSVERSIONINFO osi; + osi.dwOSVersionInfoSize = sizeof(osi); + GetVersionEx(&osi); + if ((osi.dwPlatformId==VER_PLATFORM_WIN32_NT) && (osi.dwMajorVersion>4)) { + // only WIN NT/200/XP + if (useCdromInterface==CDROM_USE_IOCTL) { + cdrom[numDrives] = new CDROM_Interface_Ioctl(); + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface."); + break; + } + } + if (useCdromInterface==CDROM_USE_ASPI) { + // all Wins - ASPI + cdrom[numDrives] = new CDROM_Interface_Aspi(); + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: ASPI Interface."); + break; + } +#endif +#if defined (LINUX) || defined(OS2) + // Always use IOCTL in Linux or OS/2 + cdrom[numDrives] = new CDROM_Interface_Ioctl(); + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface."); +#else + // Default case windows and other oses + cdrom[numDrives] = new CDROM_Interface_SDL(); + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: SDL Interface."); +#endif + } break; + case 0x01: // iso cdrom interface + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting iso file as cdrom: %s", physicalPath); + cdrom[numDrives] = new CDROM_Interface_Image((Bit8u)numDrives); + break; + case 0x02: // fake cdrom interface (directories) + cdrom[numDrives] = new CDROM_Interface_Fake; + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting directory as cdrom: %s",physicalPath); + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: You wont have full MSCDEX support !"); + result = 5; + break; + default : // weird result + return 6; + }; + + if (!cdrom[numDrives]->SetDevice(physicalPath,forceCD)) { +// delete cdrom[numDrives] ; mount seems to delete it + return 3; + } + + + if (rootDriverHeaderSeg==0) { Bit16u driverSize = sizeof(DOS_DeviceHeader::sDeviceHeader) + 10; // 10 = Bytes for 3 callbacks @@ -246,75 +350,36 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) rootDriverHeaderSeg = seg; - } else { - // Error check, driveletter have to be in a row - if (dinfo[numDrives-1].drive+1!=_drive) return 1; - }; - - if (GetNumDrives()+14)) { - // only WIN NT/200/XP - if (useCdromInterface==CDROM_USE_IOCTL) { - cdrom[numDrives] = new CDROM_Interface_Ioctl(); - LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface."); - break; - } - } - if (useCdromInterface==CDROM_USE_ASPI) { - // all Wins - ASPI - cdrom[numDrives] = new CDROM_Interface_Aspi(); - LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: ASPI Interface."); - break; - } - #endif - #if defined (LINUX) || defined(OS2) - // Always use IOCTL in Linux or OS/2 -// if (useCdromInterface==CDROM_USE_IOCTL) { - cdrom[numDrives] = new CDROM_Interface_Ioctl(); - LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface."); - break; -// } - #endif - cdrom[numDrives] = new CDROM_Interface_SDL(); - LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: SDL Interface."); - } break; - case 0x01 : // iso cdrom interface - LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting iso file as cdrom: %s", physicalPath); - cdrom[numDrives] = new CDROM_Interface_Image((Bit8u)numDrives); - break; - case 0x02 : // fake cdrom interface (directories) - cdrom[numDrives] = new CDROM_Interface_Fake; - LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting directory as cdrom: %s",physicalPath); - LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: You wont have full MSCDEX support !"); - result = 5; - break; - default : // weird result - return 6; - }; - if (!cdrom[numDrives]->SetDevice(physicalPath,forceCD)) return 3; - subUnit = (Bit8u)numDrives; - // Set drive + } else if (GetNumDrives() == 0) { DOS_DeviceHeader devHeader(PhysMake(rootDriverHeaderSeg,0)); - devHeader.SetNumSubUnits(devHeader.GetNumSubUnits()+1); + Bit16u off = sizeof(DOS_DeviceHeader::sDeviceHeader); + devHeader.SetDriveLetter(_drive+1); + devHeader.SetStrategy(off); + devHeader.SetInterrupt(off+5); + } + + subUnit = (Bit8u)numDrives; + // Set drive + DOS_DeviceHeader devHeader(PhysMake(rootDriverHeaderSeg,0)); + devHeader.SetNumSubUnits(devHeader.GetNumSubUnits()+1); + + if (dinfo[0].drive-1==_drive) { + CDROM_Interface *_cdrom = cdrom[numDrives]; + for (Bit16u i=GetNumDrives(); i>0; i--) { + dinfo[i] = dinfo[i-1]; + cdrom[i] = cdrom[i-1]; + } + cdrom[0] = _cdrom; + dinfo[0].drive = (Bit8u)_drive; + dinfo[0].physDrive = toupper(physicalPath[0]); + } else { dinfo[numDrives].drive = (Bit8u)_drive; dinfo[numDrives].physDrive = toupper(physicalPath[0]); - numDrives++; - // stop audio - StopAudio(subUnit); - return result; } - return 4; + numDrives++; + // stop audio + StopAudio(subUnit); + return result; }; PhysPt CMscdex::GetDefaultBuffer(void) @@ -1134,6 +1199,12 @@ int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit) return result; }; +int MSCDEX_RemoveDrive(char driveLetter) +{ + if(!mscdex) return 0; + return mscdex->RemoveDrive(driveLetter-'A'); +}; + bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name) { return mscdex->GetVolumeName(subUnit,name); diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index f0eef1a0..6a43bf0b 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.61 2006-06-01 06:44:22 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.62 2006-06-22 13:15:07 qbix79 Exp $ */ #include #include @@ -51,23 +51,26 @@ public: DOS_Drive * newdrive;char drive; std::string label; std::string umount; + /* Check for unmounting */ if (cmd->FindString("-u",umount,false)) { umount[0] = toupper(umount[0]); int i_drive = umount[0]-'A'; if(i_drive < DOS_DRIVES && Drives[i_drive]) { - try { /* Check if virtualdrive */ - if( dynamic_cast(Drives[i_drive]) == 0 ) throw 0; - } - catch(...) { + switch (Drives[i_drive]->UnMount()) { + case 0: + Drives[i_drive] = 0; + if(i_drive == DOS_GetDefaultDrive()) + DOS_SetDrive(toupper('Z') - 'A'); + WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCES"),umount[0]); + break; + case 1: WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NO_VIRTUAL")); - return; + break; + case 2: + WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS")); + break; } - if(i_drive == DOS_GetDefaultDrive()) - DOS_SetDrive(toupper('Z') - 'A'); - delete Drives[i_drive]; - Drives[i_drive] = 0; - WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCES"),umount[0]); } else { WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED"),umount[0]); } @@ -229,6 +232,10 @@ public: case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break; default : WriteOut(MSG_Get("MSCDEX_UNKNOWN_ERROR")); break; }; + if (error && error!=5) { + delete newdrive; + return; + } } else { /* Give a warning when mount c:\ or the / */ #if defined (WIN32) || defined(OS2) @@ -657,6 +664,32 @@ public: Bit32u imagesize; char drive; std::string label; + std::string umount; + /* Check for unmounting */ + if (cmd->FindString("-u",umount,false)) { + umount[0] = toupper(umount[0]); + int i_drive = umount[0]-'A'; + if (i_drive < DOS_DRIVES && Drives[i_drive]) { + switch (Drives[i_drive]->UnMount()) { + case 0: + Drives[i_drive] = 0; + if (i_drive == DOS_GetDefaultDrive()) + DOS_SetDrive(toupper('Z') - 'A'); + WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCES"),umount[0]); + break; + case 1: + WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NO_VIRTUAL")); + break; + case 2: + WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS")); + break; + } + } else { + WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED"),umount[0]); + } + return; + } + std::string type="hdd"; std::string fstype="fat"; @@ -777,7 +810,7 @@ public: case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break; default : WriteOut(MSG_Get("MSCDEX_UNKNOWN_ERROR")); break; }; - if (error) { + if (error && error!=5) { delete newdrive; return; } diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 2183a2fc..c7921c0f 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.15 2006-05-31 14:22:00 qbix79 Exp $ */ +/* $Id: drive_fat.cpp,v 1.16 2006-06-22 13:15:07 qbix79 Exp $ */ #include #include @@ -704,6 +704,11 @@ Bit32u fatDrive::getFirstFreeClust(void) { bool fatDrive::isRemote(void) { return false; } bool fatDrive::isRemovable(void) { return false; } +Bits fatDrive::UnMount(void) { + delete this; + return 0; +} + Bit8u fatDrive::GetMediaByte(void) { return loadedDisk->GetBiosType(); } bool fatDrive::FileCreate(DOS_File **file, char *name, Bit16u attributes) { diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index d0d42e55..8fde0b10 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.13 2006-04-23 14:20:58 c2woody Exp $ */ +/* $Id: drive_iso.cpp,v 1.14 2006-06-22 13:15:07 qbix79 Exp $ */ #include #include @@ -138,6 +138,7 @@ Bit16u isoFile::GetInformation(void) return 0x40; // read-only drive } +int MSCDEX_RemoveDrive(char driveLetter); int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit); bool MSCDEX_HasMediaChanged(Bit8u subUnit); bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name); @@ -153,7 +154,9 @@ isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &e if (!error) { if (loadImage()) { - strcpy(info, "isoDrive"); + strcpy(info, "isoDrive "); + strcat(info, fileName); + this->driveLetter = driveLetter; this->mediaid = mediaid; char buffer[32] = { 0 }; if (!MSCDEX_GetVolumeName(subUnit, buffer)) strcpy(buffer, ""); @@ -373,6 +376,14 @@ bool isoDrive::isRemovable(void) return true; } +Bits isoDrive::UnMount(void) { + if(MSCDEX_RemoveDrive(driveLetter)) { + delete this; + return 0; + } + return 2; +} + int isoDrive::GetDirIterator(const isoDirEntry* de) { int dirIterator = nextFreeDirIterator; diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 4683b245..699745c6 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.68 2006-05-14 19:57:24 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.69 2006-06-22 13:15:07 qbix79 Exp $ */ #include #include @@ -411,6 +411,11 @@ bool localDrive::isRemovable(void) { return false; } +Bits localDrive::UnMount(void) { + delete this; + return 0; +} + localDrive::localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid) { strcpy(basedir,startdir); sprintf(info,"local directory %s",startdir); @@ -535,6 +540,7 @@ bool localFile::UpdateDateTimeFromHost(void) { // CDROM DRIVE // ******************************************** +int MSCDEX_RemoveDrive(char driveLetter); int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit); bool MSCDEX_HasMediaChanged(Bit8u subUnit); bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name); @@ -545,7 +551,9 @@ cdromDrive::cdromDrive(const char driveLetter, const char * startdir,Bit16u _byt { // Init mscdex error = MSCDEX_AddDrive(driveLetter,startdir,subUnit); - strcpy(info,"CDRom."); + strcpy(info, "CDRom "); + strcat(info, startdir); + this->driveLetter = driveLetter; // Get Volume Label char name[32]; if (MSCDEX_GetVolumeName(subUnit,name)) dirCache.SetLabel(name); @@ -632,3 +640,11 @@ bool cdromDrive::isRemote(void) { bool cdromDrive::isRemovable(void) { return true; } + +Bits cdromDrive::UnMount(void) { + if(MSCDEX_RemoveDrive(driveLetter)) { + delete this; + return 0; + } + return 2; +} diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 19c52d46..7ac1d0e2 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -176,7 +176,7 @@ bool Virtual_Drive::TestDir(char * dir) { } bool Virtual_Drive::FileStat(const char* name, FileStat_Block * const stat_block){ - VFILE_Block * cur_file=first_file; + VFILE_Block * cur_file=first_file; while (cur_file) { if (strcasecmp(name,cur_file->name)==0) { stat_block->attr=DOS_ATTR_ARCHIVE; @@ -267,3 +267,8 @@ bool Virtual_Drive::isRemote(void) { bool Virtual_Drive::isRemovable(void) { return false; } + +Bits Virtual_Drive::UnMount(void) { + return 1; +} + diff --git a/src/dos/drives.h b/src/dos/drives.h index 30503d1e..e7c1707d 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.32 2006-04-17 10:45:32 qbix79 Exp $ */ +/* $Id: drives.h,v 1.33 2006-06-22 13:15:07 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ @@ -50,6 +50,7 @@ public: virtual Bit8u GetMediaByte(void); virtual bool isRemote(void); virtual bool isRemovable(void); + virtual Bits UnMount(void); private: char basedir[CROSS_LEN]; friend void DOS_Shell::CMD_SUBST(char* args); @@ -142,6 +143,7 @@ public: virtual Bit8u GetMediaByte(void); virtual bool isRemote(void); virtual bool isRemovable(void); + virtual Bits UnMount(void); public: Bit32u getAbsoluteSectFromBytePos(Bit32u startClustNum, Bit32u bytePos); Bit32u getSectorSize(void); @@ -204,8 +206,10 @@ public: virtual void SetDir(const char* path); virtual bool isRemote(void); virtual bool isRemovable(void); + virtual Bits UnMount(void); private: Bit8u subUnit; + char driveLetter; }; #ifdef _MSC_VER @@ -304,6 +308,7 @@ public: virtual void EmptyCache(void){} virtual bool isRemote(void); virtual bool isRemovable(void); + virtual Bits UnMount(void); bool readSector(Bit8u *buffer, Bit32u sector); virtual char const* GetLabel(void) {return discLabel;}; private: @@ -335,6 +340,7 @@ private: isoDirEntry rootEntry; Bit8u mediaid; Bit8u subUnit; + char driveLetter; char discLabel[32]; }; @@ -360,6 +366,7 @@ public: void EmptyCache(void){} bool isRemote(void); virtual bool isRemovable(void); + virtual Bits UnMount(void); private: VFILE_Block * search_file; }; From caf6a80ef4e2cc1c9d4ae29ca99bcc3c5177dca5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 24 Jun 2006 17:29:39 +0000 Subject: [PATCH 2574/4131] add scancode modifications for os2 (thanks to josch) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2659 --- src/gui/sdl_mapper.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index c90237d7..822d43dc 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.24 2006-06-12 08:04:48 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.25 2006-06-24 17:29:39 c2woody Exp $ */ #define OLD_JOYSTICK 1 @@ -1654,6 +1654,25 @@ void MAPPER_StartUp(Section * sec) { /* Note: table has to be tested/updated for various OSs */ #if defined (MACOSX) /* nothing */ +#elif defined(OS2) + sdlkey_map[0x61]=SDLK_UP; + sdlkey_map[0x66]=SDLK_DOWN; + sdlkey_map[0x63]=SDLK_LEFT; + sdlkey_map[0x64]=SDLK_RIGHT; + sdlkey_map[0x60]=SDLK_HOME; + sdlkey_map[0x65]=SDLK_END; + sdlkey_map[0x62]=SDLK_PAGEUP; + sdlkey_map[0x67]=SDLK_PAGEDOWN; + sdlkey_map[0x68]=SDLK_INSERT; + sdlkey_map[0x69]=SDLK_DELETE; + sdlkey_map[0x5C]=SDLK_KP_DIVIDE; + sdlkey_map[0x5A]=SDLK_KP_ENTER; + sdlkey_map[0x5B]=SDLK_RCTRL; + sdlkey_map[0x5F]=SDLK_PAUSE; +// sdlkey_map[0x00]=SDLK_PRINT; + sdlkey_map[0x5E]=SDLK_RALT; + sdlkey_map[0x40]=SDLK_KP5; + sdlkey_map[0x41]=SDLK_KP6; #elif !defined (WIN32) /* => Linux */ sdlkey_map[0x5a]=SDLK_UP; sdlkey_map[0x60]=SDLK_DOWN; From 97470261fb4f4d9e779fe463be623fdc59b15062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 25 Jun 2006 18:49:32 +0000 Subject: [PATCH 2575/4131] tweak size of auto-cycle interval (ih8regs); switch to auto-cycle guessing if appropriate Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2660 --- include/cpu.h | 3 ++- src/cpu/callback.cpp | 4 ++-- src/cpu/cpu.cpp | 34 +++++++++++++++++++++++++--------- src/dosbox.cpp | 10 +++++----- src/gui/sdlmain.cpp | 8 ++++---- 5 files changed, 38 insertions(+), 21 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 2bbbe220..20f25870 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -33,7 +33,8 @@ extern Bits CPU_Cycles; extern Bits CPU_CycleLeft; extern Bits CPU_CycleMax; -extern bool CPU_CycleAuto; +extern bool CPU_CycleAutoAdjust; +extern bool CPU_AutoDetermineMode; /* Some common Defines */ /* A CPU Handler */ diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index e4900460..45a56f32 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.32 2006-04-22 15:25:44 c2woody Exp $ */ +/* $Id: callback.cpp,v 1.33 2006-06-25 18:49:32 c2woody Exp $ */ #include #include @@ -70,7 +70,7 @@ void CALLBACK_Idle(void) { reg_eip=oldeip; SegSet16(cs,oldcs); SETFLAGBIT(IF,oldIF); - if (!CPU_CycleAuto && CPU_Cycles>0) + if (!CPU_CycleAutoAdjust && CPU_Cycles>0) CPU_Cycles=0; } diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 6e687e41..719e36e1 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.81 2006-04-27 13:22:27 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.82 2006-06-25 18:49:32 c2woody Exp $ */ #include #include "dosbox.h" @@ -29,6 +29,7 @@ #include "support.h" Bitu DEBUG_EnableDebugger(void); +extern void GFX_SetTitle(Bits cycles ,Bits frameskip,bool paused); #if 1 #undef LOG @@ -45,7 +46,8 @@ Bits CPU_CycleMax = 2500; Bits CPU_CycleUp = 0; Bits CPU_CycleDown = 0; CPU_Decoder * cpudecoder; -bool CPU_CycleAuto; +bool CPU_CycleAutoAdjust; +bool CPU_AutoDetermineMode; void CPU_Core_Full_Init(void); void CPU_Core_Normal_Init(void); @@ -1431,13 +1433,26 @@ void CPU_SET_CRX(Bitu cr,Bitu value) { switch (cr) { case 0: { - Bitu changed=cpu.cr0 ^ value; + Bitu changed=cpu.cr0 ^ value; if (!changed) return; cpu.cr0=value; if (value & CR0_PROTECTION) { cpu.pmode=true; LOG(LOG_CPU,LOG_NORMAL)("Protected mode"); PAGING_Enable((value & CR0_PAGING)>0); + + if (!CPU_AutoDetermineMode) break; + + CPU_AutoDetermineMode=false; + CPU_CycleAutoAdjust=true; + CPU_CycleLeft=0; + CPU_Cycles=0; + CPU_CycleMax=0; +/* #if (C_DYNAMIC_X86) + CPU_Core_Dyn_X86_Cache_Init(true); + cpudecoder=&CPU_Core_Dyn_X86_Run; +#endif */ + GFX_SetTitle(-1,-1,false); } else { cpu.pmode=false; if (value & CR0_PAGING) LOG_MSG("Paging requested without PE=1"); @@ -1889,9 +1904,8 @@ void CPU_ENTER(bool use32,Bitu bytes,Bitu level) { reg_esp=(reg_esp&cpu.stack.notmask)|((sp_index)&cpu.stack.mask); } -extern void GFX_SetTitle(Bits cycles ,Bits frameskip,bool paused); static void CPU_CycleIncrease(bool pressed) { - if (!pressed || CPU_CycleAuto) + if (!pressed || CPU_CycleAutoAdjust) return; Bits old_cycles=CPU_CycleMax; if(CPU_CycleUp < 100){ @@ -1907,7 +1921,7 @@ static void CPU_CycleIncrease(bool pressed) { } static void CPU_CycleDecrease(bool pressed) { - if (!pressed || CPU_CycleAuto) + if (!pressed || CPU_CycleAutoAdjust) return; if(CPU_CycleDown < 100){ CPU_CycleMax = (Bits)(CPU_CycleMax / (1 + (float)CPU_CycleDown / 100.0)); @@ -1978,12 +1992,14 @@ public: CPU_CycleLeft=0;//needed ? CPU_Cycles=0; const char *cyclesLine = section->Get_string("cycles"); - if (!strcasecmp(cyclesLine,"auto")) { + CPU_AutoDetermineMode=false; + if (!strcasecmp(cyclesLine,"max")) { CPU_CycleMax=0; - CPU_CycleAuto=true; + CPU_CycleAutoAdjust=true; } else { + if (!strcasecmp(cyclesLine,"auto")) CPU_AutoDetermineMode=true; CPU_CycleMax=atoi(cyclesLine); - CPU_CycleAuto=false; + CPU_CycleAutoAdjust=false; } CPU_CycleUp=section->Get_int("cycleup"); CPU_CycleDown=section->Get_int("cycledown"); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 34e35952..2cd62f02 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.99 2006-03-28 10:17:34 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.100 2006-06-25 18:49:32 c2woody Exp $ */ #include #include @@ -158,7 +158,7 @@ increaseticks: ticksRemain = 20; } ticksAdded = ticksRemain; - if (CPU_CycleAuto && (ticksScheduled >= 1000 || ticksDone >= 1000) ) { + if (CPU_CycleAutoAdjust && (ticksAdded > 15 || ticksScheduled >= 250 || ticksDone >= 250) ) { /* ratio we are aiming for is around 90% usage*/ Bits ratio = (ticksScheduled * (90*1024/100)) / ticksDone ; // LOG_MSG("Done %d schedulded %d ratio %d cycles %d", ticksDone, ticksScheduled, ratio, CPU_CycleMax); @@ -276,7 +276,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("cpu",&CPU_Init,true);//done secprop->Add_string("core","normal"); - secprop->Add_string("cycles","3000"); + secprop->Add_string("cycles","auto"); secprop->Add_int("cycleup",500); secprop->Add_int("cycledown",20); MSG_Add("CPU_CONFIGFILE_HELP", @@ -287,8 +287,8 @@ void DOSBOX_Init(void) { ".\n" "cycles -- Amount of instructions dosbox tries to emulate each millisecond.\n" " Setting this higher than your machine can handle is bad!\n" - " You can also let DOSBox guess the correct value by setting it to auto.\n" - " Please note that this guessing feature is still experimental.\n" + " You can also let DOSBox guess the correct value by setting it to max.\n" + " The default setting (auto) switches to max if appropriate.\n" "cycleup -- Amount of cycles to increase/decrease with keycombo.\n" "cycledown Setting it lower than 100 will be a percentage.\n" ); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 47301bf0..9c405362 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.117 2006-06-12 19:11:14 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.118 2006-06-25 18:49:32 c2woody Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -208,7 +208,7 @@ struct SDL_Block { static SDL_Block sdl; extern const char* RunningProgram; -extern bool CPU_CycleAuto; +extern bool CPU_CycleAutoAdjust; //Globals for keyboard initialisation bool startup_state_numlock=false; bool startup_state_capslock=false; @@ -218,8 +218,8 @@ void GFX_SetTitle(Bits cycles,Bits frameskip,bool paused){ static Bits internal_frameskip=0; if(cycles != -1) internal_cycles = cycles; if(frameskip != -1) internal_frameskip = frameskip; - if(CPU_CycleAuto) - sprintf(title,"DOSBox %s, Cpu Cycles: auto, Frameskip %2d, Program: %8s",VERSION,internal_frameskip,RunningProgram); + if(CPU_CycleAutoAdjust) + sprintf(title,"DOSBox %s, Cpu Cycles: max, Frameskip %2d, Program: %8s",VERSION,internal_frameskip,RunningProgram); else sprintf(title,"DOSBox %s, Cpu Cycles: %8d, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram); From 1a6a92a423f332031a6b70c005df313aebb8be64 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 27 Jun 2006 07:00:56 +0000 Subject: [PATCH 2576/4131] Fix Set Memory. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2661 --- src/debug/debug.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index c52a1671..977f27c3 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.82 2006-06-22 08:34:38 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.83 2006-06-27 07:00:56 qbix79 Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -1027,7 +1027,8 @@ bool ParseCommand(char* str) { while (*found) { while (*found==' ') found++; if (*found) { - Bit8u value = (Bit8u)GetHexValue(found,found); found++; + Bit8u value = (Bit8u)GetHexValue(found,found); + if(*found) found++; mem_writeb(GetAddress(seg,ofs+count),value); count++; } From 930207e20951782f9ad51411ddce084d4b9f9d5f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 27 Jun 2006 07:32:42 +0000 Subject: [PATCH 2577/4131] Add support for character fonts wrapping around segment limits Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2662 --- src/ints/int10_char.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 8dda0539..9e8b04cb 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.47 2006-03-27 19:31:54 c2woody Exp $ */ +/* $Id: int10_char.cpp,v 1.48 2006-06-27 07:32:42 harekiet Exp $ */ /* Character displaying moving functions */ @@ -438,7 +438,7 @@ void INT10_ReadCharAttr(Bit16u * result,Bit8u page) { } void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useattr) { /* Externally used by the mouse routine */ - PhysPt fontdata; + RealPt fontdata; Bitu x,y; Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); switch (CurMode->type) { @@ -458,14 +458,17 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt case M_CGA4: case M_CGA2: case M_TANDY16: - if (chr<128) fontdata=Real2Phys(RealGetVec(0x43))+chr*cheight; + if (chr<128) + fontdata=RealGetVec(0x43); else { chr-=128; - fontdata=Real2Phys(RealGetVec(0x1F))+(chr)*cheight; + fontdata=RealGetVec(0x1f); } + fontdata=RealMake(RealSeg(fontdata), RealOff(fontdata) + chr*cheight); break; default: - fontdata=Real2Phys(RealGetVec(0x43))+chr*cheight; + fontdata=RealGetVec(0x43); + fontdata=RealMake(RealSeg(fontdata), RealOff(fontdata) + chr*cheight); break; } @@ -503,7 +506,8 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt } for (Bit8u h=0;h Date: Thu, 29 Jun 2006 09:10:10 +0000 Subject: [PATCH 2578/4131] add automatic core selection; switch back to default cycles/core on program exit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2663 --- include/cpu.h | 9 ++++++++- src/cpu/cpu.cpp | 41 ++++++++++++++++++++++++++--------------- src/dos/dos_execute.cpp | 22 +++++++++++++++++++++- src/dosbox.cpp | 5 +++-- 4 files changed, 58 insertions(+), 19 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 20f25870..6a1bb85c 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -29,12 +29,19 @@ #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 + /* CPU Cycle Timing */ extern Bits CPU_Cycles; extern Bits CPU_CycleLeft; extern Bits CPU_CycleMax; extern bool CPU_CycleAutoAdjust; -extern bool CPU_AutoDetermineMode; +extern Bitu CPU_AutoDetermineMode; /* Some common Defines */ /* A CPU Handler */ diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 719e36e1..edae46ef 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.82 2006-06-25 18:49:32 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.83 2006-06-29 09:10:09 c2woody Exp $ */ #include #include "dosbox.h" @@ -47,7 +47,7 @@ Bits CPU_CycleUp = 0; Bits CPU_CycleDown = 0; CPU_Decoder * cpudecoder; bool CPU_CycleAutoAdjust; -bool CPU_AutoDetermineMode; +Bitu CPU_AutoDetermineMode; void CPU_Core_Full_Init(void); void CPU_Core_Normal_Init(void); @@ -1441,17 +1441,21 @@ void CPU_SET_CRX(Bitu cr,Bitu value) { LOG(LOG_CPU,LOG_NORMAL)("Protected mode"); PAGING_Enable((value & CR0_PAGING)>0); - if (!CPU_AutoDetermineMode) break; + if (!(CPU_AutoDetermineMode&CPU_AUTODETERMINE_MASK)) break; - CPU_AutoDetermineMode=false; - CPU_CycleAutoAdjust=true; - CPU_CycleLeft=0; - CPU_Cycles=0; - CPU_CycleMax=0; -/* #if (C_DYNAMIC_X86) - CPU_Core_Dyn_X86_Cache_Init(true); - cpudecoder=&CPU_Core_Dyn_X86_Run; -#endif */ + if (CPU_AutoDetermineMode&CPU_AUTODETERMINE_CYCLES) { + CPU_CycleAutoAdjust=true; + CPU_CycleLeft=0; + CPU_Cycles=0; + CPU_CycleMax=0; + } + #if (C_DYNAMIC_X86) + if (CPU_AutoDetermineMode&CPU_AUTODETERMINE_CORE) { + CPU_Core_Dyn_X86_Cache_Init(true); + cpudecoder=&CPU_Core_Dyn_X86_Run; + } +#endif + CPU_AutoDetermineMode<<=CPU_AUTODETERMINE_SHIFT; GFX_SetTitle(-1,-1,false); } else { cpu.pmode=false; @@ -1989,16 +1993,20 @@ public: } bool Change_Config(Section* newconfig){ Section_prop * section=static_cast(newconfig); + CPU_AutoDetermineMode=CPU_AUTODETERMINE_NONE; CPU_CycleLeft=0;//needed ? CPU_Cycles=0; const char *cyclesLine = section->Get_string("cycles"); - CPU_AutoDetermineMode=false; if (!strcasecmp(cyclesLine,"max")) { CPU_CycleMax=0; CPU_CycleAutoAdjust=true; } else { - if (!strcasecmp(cyclesLine,"auto")) CPU_AutoDetermineMode=true; - CPU_CycleMax=atoi(cyclesLine); + if (!strcasecmp(cyclesLine,"auto")) { + CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CYCLES; + CPU_CycleMax=3000; + } else { + CPU_CycleMax=atoi(cyclesLine); + } CPU_CycleAutoAdjust=false; } CPU_CycleUp=section->Get_int("cycleup"); @@ -2015,6 +2023,9 @@ public: #if (C_DYNAMIC_X86) else if (!strcasecmp(core,"dynamic")) { cpudecoder=&CPU_Core_Dyn_X86_Run; + } else if (!strcasecmp(core,"auto")) { + cpudecoder=&CPU_Core_Normal_Run; + CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CORE; } #endif else { diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index c7acbae6..e938537d 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.55 2006-04-08 11:25:41 qbix79 Exp $ */ +/* $Id: dos_execute.cpp,v 1.56 2006-06-29 09:10:09 c2woody Exp $ */ #include #include @@ -26,6 +26,7 @@ #include "regs.h" #include "callback.h" #include "debug.h" +#include "cpu.h" const char * RunningProgram="DOSBOX"; @@ -137,6 +138,25 @@ bool DOS_Terminate(bool tsr) { // Free memory owned by process if (!tsr) DOS_FreeProcessMemory(mempsp); DOS_UpdatePSPName(); + + if ((!(CPU_AutoDetermineMode>>CPU_AUTODETERMINE_SHIFT)) || (cpu.pmode)) return true; + + CPU_AutoDetermineMode>>=CPU_AUTODETERMINE_SHIFT; + if (CPU_AutoDetermineMode&CPU_AUTODETERMINE_CYCLES) { + CPU_CycleAutoAdjust=false; + CPU_CycleLeft=0; + CPU_Cycles=0; + CPU_CycleMax=3000; + } + #if (C_DYNAMIC_X86) + if (CPU_AutoDetermineMode&CPU_AUTODETERMINE_CORE) { + cpudecoder=&CPU_Core_Normal_Run; + CPU_CycleLeft=0; + CPU_Cycles=0; + } +#endif + GFX_SetTitle(-1,-1,false); + return true; } diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 2cd62f02..47c746c6 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.100 2006-06-25 18:49:32 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.101 2006-06-29 09:10:10 c2woody Exp $ */ #include #include @@ -282,7 +282,8 @@ void DOSBOX_Init(void) { MSG_Add("CPU_CONFIGFILE_HELP", "core -- CPU Core used in emulation: simple,normal,full" #if (C_DYNAMIC_X86) - ",dynamic" + ",dynamic,auto.\n" + " auto switches from normal to dynamic if appropriate" #endif ".\n" "cycles -- Amount of instructions dosbox tries to emulate each millisecond.\n" From 7cac8ec376a13b8ef87b69b756d8b41f9d7958a6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 29 Jun 2006 19:05:54 +0000 Subject: [PATCH 2579/4131] Make gcc happy. (thanks Ludwig). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2664 --- src/gui/sdlmain.cpp | 4 ++-- src/hardware/sblaster.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 9c405362..a470d9c4 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.118 2006-06-25 18:49:32 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.119 2006-06-29 19:05:54 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -382,7 +382,7 @@ Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,G sdl.draw.scaley=scaley; Bitu bpp; - Bitu retFlags; + Bitu retFlags = 0; if (sdl.blit.surface) { SDL_FreeSurface(sdl.blit.surface); diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index d75278dd..561df6a1 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.53 2006-03-13 20:01:55 qbix79 Exp $ */ +/* $Id: sblaster.cpp,v 1.54 2006-06-29 19:05:54 qbix79 Exp $ */ #include #include @@ -1189,7 +1189,7 @@ public: sb.mixer.enabled=section->Get_bool("mixer"); Bitu oplrate=section->Get_int("oplrate"); sb.mixer.stereo=false; - OPL_Mode opl_mode; + OPL_Mode opl_mode = OPL_none; Find_Type_And_Opl(section,sb.type,opl_mode); switch (opl_mode) { @@ -1240,7 +1240,7 @@ public: ~SBLASTER() { Section_prop * section=static_cast(m_configuration); - OPL_Mode opl_mode; + OPL_Mode opl_mode = OPL_none; Find_Type_And_Opl(section,sb.type,opl_mode); switch (opl_mode) { From 43d7055361ab4b0ab5b6cb64a7ba8e1aa8d7ac08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 30 Jun 2006 12:47:07 +0000 Subject: [PATCH 2580/4131] some fixes to the fat drive handling (thanks to h-a-l9000) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2665 --- include/dos_inc.h | 9 ++++++--- src/dos/drive_fat.cpp | 15 ++++++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 1da5cdad..931c3094 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.60 2006-04-21 08:50:30 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.61 2006-06-30 12:47:06 c2woody Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -439,8 +439,10 @@ public: 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 SetDirID(Bit16u entry) { sSave(sDTA,dirID,entry); }; + void SetDirIDCluster(Bit16u entry) { sSave(sDTA,dirCluster,entry); }; Bit16u GetDirID(void) { return sGet(sDTA,dirID); }; + Bit16u GetDirIDCluster(void) { return sGet(sDTA,dirCluster); }; private: #ifdef _MSC_VER #pragma pack(1) @@ -451,7 +453,8 @@ private: 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 */ - Bit8u fill[6]; + Bit16u dirCluster; /* custom (drive_fat only): cluster number for multiple searches at the same time */ + Bit8u fill[4]; Bit8u attr; Bit16u time; Bit16u date; diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index c7921c0f..90d168c2 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.16 2006-06-22 13:15:07 qbix79 Exp $ */ +/* $Id: drive_fat.cpp,v 1.17 2006-06-30 12:47:07 c2woody Exp $ */ #include #include @@ -186,6 +186,7 @@ bool fatFile::Write(Bit8u * data, Bit16u *size) { --sizedec; sizecount++; } + if(curSectOff>0 && loadedSector) myDrive->loadedDisk->Write_AbsoluteSector(currentSector, sectorBuffer); finalizeWrite: myDrive->directoryBrowse(dirCluster, &tmpentry, dirIndex); @@ -610,6 +611,9 @@ fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, loadedDisk->Set_Geometry(headscyl, cylinders,cylsector, bytesector); loadedDisk->Read_Sector(0,0,1,&mbrData); + + if(mbrData.magic1!= 0x55 || mbrData.magic2!= 0xaa) LOG_MSG("Possibly invalid partition table in disk image."); + startSector = 63; int m; for(m=0;m<4;m++) { @@ -621,6 +625,8 @@ fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, } } + if(m==4) LOG_MSG("No good partiton found in image."); + partSectOff = startSector; } else { /* Floppy disks don't have partitions */ @@ -808,6 +814,7 @@ bool fatDrive::FindFirst(char *_dir, DOS_DTA &dta,bool fcb_findfirst) { return false; } dta.SetDirID(0); + dta.SetDirIDCluster((Bit16u)(cwdDirCluster&0xffff)); return FindNextInternal(cwdDirCluster, dta, &dummyClust); } @@ -879,7 +886,7 @@ nextfile: memcpy(extension,§buf[entryoffset].entryname[8],3); trimString(&find_name[0]); trimString(&extension[0]); - if(!(sectbuf[entryoffset].attrib & DOS_ATTR_DIRECTORY)) { + if(!(sectbuf[entryoffset].attrib & DOS_ATTR_DIRECTORY) || extension[0]!=0) { strcat(find_name, "."); strcat(find_name, extension); } @@ -900,7 +907,7 @@ nextfile: bool fatDrive::FindNext(DOS_DTA &dta) { direntry dummyClust; - return FindNextInternal(cwdDirCluster, dta, &dummyClust); + return FindNextInternal(dta.GetDirIDCluster(), dta, &dummyClust); } bool fatDrive::GetFileAttr(char *name, Bit16u *attr) { @@ -919,6 +926,7 @@ bool fatDrive::GetFileAttr(char *name, Bit16u *attr) { /* Find directory entry in parent directory */ Bit32s fileidx = 2; + if (dirClust==0) fileidx = 0; // root directory while(directoryBrowse(dirClust, &fileEntry, fileidx)) { if(memcmp(&fileEntry.entryname, &pathName[0], 11) == 0) { *attr=fileEntry.attrib; @@ -1143,6 +1151,7 @@ bool fatDrive::RemoveDir(char *dir) { Bit32u filecount = 0; /* Set to 2 to skip first 2 entries, [.] and [..] */ Bit32s fileidx = 2; + if (dirClust==0) fileidx = 0; // root directory while(directoryBrowse(dummyClust, &tmpentry, fileidx)) { /* Check for non-deleted files */ if(tmpentry.entryname[0] != 0xe5) filecount++; From 49eea1af58ca9b7c40be61730b3dfe2833471362 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 30 Jun 2006 20:04:21 +0000 Subject: [PATCH 2581/4131] Make valgrind happy and set a few strings to zero. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2666 --- src/dos/dos_files.cpp | 10 +++++----- src/shell/shell.cpp | 6 +++--- src/shell/shell_batch.cpp | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 9d6d350a..8c3e6082 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.75 2006-06-22 13:15:07 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.76 2006-06-30 20:04:21 qbix79 Exp $ */ #include #include @@ -655,10 +655,10 @@ static bool isvalid(const char in){ Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u *change) { char * string_begin=string;Bit8u ret=0; - DOS_FCB fcb(seg,offset); - bool hasdrive,hasname,hasext; - hasdrive=hasname=hasext=false; - Bitu index;bool finished;Bit8u fill; + DOS_FCB fcb(seg,offset); + bool hasdrive,hasname,hasext,finished; + hasdrive=hasname=hasext=finished=false; + Bitu index=0;Bit8u fill=' '; /* First get the old data from the fcb */ #ifdef _MSC_VER #pragma pack (1) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 3d4f1f6f..cdba628f 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.74 2006-05-25 15:08:40 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.75 2006-06-30 20:04:21 qbix79 Exp $ */ #include #include @@ -263,7 +263,7 @@ void DOS_Shell::ParseLine(char * line) { void DOS_Shell::RunInternal(void) { - char input_line[CMD_MAXLINE]; + char input_line[CMD_MAXLINE] = {0}; std::string line; while(bf && bf->ReadLine(input_line)) { @@ -281,7 +281,7 @@ void DOS_Shell::RunInternal(void) void DOS_Shell::Run(void) { - char input_line[CMD_MAXLINE]; + char input_line[CMD_MAXLINE] = {0}; std::string line; if (cmd->FindStringRemain("/C",line)) { strcpy(input_line,line.c_str()); diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index b151a7ab..e9ac29f2 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.21 2006-05-25 15:08:40 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.22 2006-06-30 20:04:21 qbix79 Exp $ */ #include #include @@ -43,7 +43,7 @@ BatchFile::~BatchFile() { } bool BatchFile::ReadLine(char * line) { - Bit8u c;Bit16u n; + Bit8u c=0;Bit16u n=1; char temp[CMD_MAXLINE]; emptyline: char * cmd_write=temp; From ec1c4700203b8068902345810a45c8cbb033da27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 5 Jul 2006 21:18:14 +0000 Subject: [PATCH 2582/4131] some more drive_fat fixes, cleanups and removal of some compiler warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2667 --- src/dos/drive_fat.cpp | 159 ++++++++++++++++++++++++------------------ 1 file changed, 91 insertions(+), 68 deletions(-) diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 90d168c2..9ec8d786 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.17 2006-06-30 12:47:07 c2woody Exp $ */ +/* $Id: drive_fat.cpp,v 1.18 2006-07-05 21:18:14 c2woody Exp $ */ #include #include @@ -72,9 +72,8 @@ private: /* OUT - char * filearray: Name in DOS directory format, eleven char, e.g. bob txt */ static void convToDirFile(char *filename, char *filearray) { Bit32u charidx = 0; - Bit32u flen; - int i; - flen = strlen(filename); + Bit32u flen,i; + flen = (Bit32u)strlen(filename); memset(filearray, 32, 11); for(i=0;i= 11) break; @@ -87,7 +86,7 @@ static void convToDirFile(char *filename, char *filearray) { } } -fatFile::fatFile(const char* name, Bit32u startCluster, Bit32u fileLen, fatDrive *useDrive) { +fatFile::fatFile(const char* /*name*/, Bit32u startCluster, Bit32u fileLen, fatDrive *useDrive) { Bit32u seekto = 0; firstCluster = startCluster; myDrive = useDrive; @@ -98,8 +97,8 @@ fatFile::fatFile(const char* name, Bit32u startCluster, Bit32u fileLen, fatDrive memset(§orBuffer[0], 0, sizeof(sectorBuffer)); if(filelength > 0) { - Seek(&seekto, DOS_SEEK_SET); - myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); + Seek(&seekto, DOS_SEEK_SET); + myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); loadedSector = true; } } @@ -111,6 +110,19 @@ bool fatFile::Read(Bit8u * data, Bit16u *size) { return true; } + if (!loadedSector) { + currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); + if(currentSector == 0) { + /* EOC reached before EOF */ + *size = 0; + loadedSector = false; + return true; + } + curSectOff = 0; + myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); + loadedSector = true; + } + sizedec = *size; sizecount = 0; while(sizedec != 0) { @@ -118,8 +130,7 @@ bool fatFile::Read(Bit8u * data, Bit16u *size) { *size = sizecount; return true; } - data[sizecount] = sectorBuffer[curSectOff]; - curSectOff++; + data[sizecount++] = sectorBuffer[curSectOff++]; seekpos++; if(curSectOff >= myDrive->getSectorSize()) { currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); @@ -127,14 +138,15 @@ bool fatFile::Read(Bit8u * data, Bit16u *size) { /* EOC reached before EOF */ //LOG_MSG("EOC reached before EOF, seekpos %d, filelen %d", seekpos, filelength); *size = sizecount; + loadedSector = false; return true; } curSectOff = 0; myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); + loadedSector = true; //LOG_MSG("Reading absolute sector at %d for seekpos %d", currentSector, seekpos); } --sizedec; - sizecount++; } *size =sizecount; return true; @@ -159,9 +171,25 @@ bool fatFile::Write(Bit8u * data, Bit16u *size) { loadedSector = true; } filelength = seekpos+1; + if (!loadedSector) { + currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); + if(currentSector == 0) { + /* EOC reached before EOF - try to increase file allocation */ + myDrive->appendCluster(firstCluster); + /* Try getting sector again */ + currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); + if(currentSector == 0) { + /* No can do. lets give up and go home. We must be out of room */ + goto finalizeWrite; + } + } + curSectOff = 0; + myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); + + loadedSector = true; + } } - sectorBuffer[curSectOff] = data[sizecount]; - curSectOff++; + sectorBuffer[curSectOff++] = data[sizecount++]; seekpos++; if(curSectOff >= myDrive->getSectorSize()) { if(loadedSector) myDrive->loadedDisk->Write_AbsoluteSector(currentSector, sectorBuffer); @@ -174,8 +202,8 @@ bool fatFile::Write(Bit8u * data, Bit16u *size) { currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); if(currentSector == 0) { /* No can do. lets give up and go home. We must be out of room */ + loadedSector = false; goto finalizeWrite; - } } curSectOff = 0; @@ -184,14 +212,13 @@ bool fatFile::Write(Bit8u * data, Bit16u *size) { loadedSector = true; } --sizedec; - sizecount++; } if(curSectOff>0 && loadedSector) myDrive->loadedDisk->Write_AbsoluteSector(currentSector, sectorBuffer); finalizeWrite: myDrive->directoryBrowse(dirCluster, &tmpentry, dirIndex); tmpentry.entrysize = filelength; - tmpentry.loFirstClust = firstCluster; + tmpentry.loFirstClust = (Bit16u)firstCluster; myDrive->directoryChange(dirCluster, &tmpentry, dirIndex); *size =sizecount; @@ -199,7 +226,7 @@ finalizeWrite: } bool fatFile::Seek(Bit32u *pos, Bit32u type) { - Bit32s seekto; + Bit32s seekto=0; switch(type) { case DOS_SEEK_SET: @@ -213,14 +240,19 @@ bool fatFile::Seek(Bit32u *pos, Bit32u type) { seekto = (Bit32s)filelength + (Bit32s)*pos; break; } - LOG_MSG("Seek to %d with type %d (absolute value %d)", *pos, type, seekto); +// LOG_MSG("Seek to %d with type %d (absolute value %d)", *pos, type, seekto); if((Bit32u)seekto > filelength) seekto = (Bit32s)filelength; if(seekto<0) seekto = 0; seekpos = (Bit32u)seekto; currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); - curSectOff = seekpos % myDrive->getSectorSize(); - myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); + if (currentSector == 0) { + /* not within file size, thus no sector is available */ + loadedSector = false; + } else { + curSectOff = seekpos % myDrive->getSectorSize(); + myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); + } *pos = seekpos; return true; } @@ -245,10 +277,10 @@ Bit32u fatDrive::getClustFirstSect(Bit32u clustNum) { } Bit32u fatDrive::getClusterValue(Bit32u clustNum) { - Bit32u fatoffset; + Bit32u fatoffset=0; Bit32u fatsectnum; Bit32u fatentoff; - Bit32u clustValue; + Bit32u clustValue=0; switch(fattype) { case FAT12: @@ -292,10 +324,9 @@ Bit32u fatDrive::getClusterValue(Bit32u clustNum) { } void fatDrive::setClusterValue(Bit32u clustNum, Bit32u clustValue) { - Bit32u fatoffset; + Bit32u fatoffset=0; Bit32u fatsectnum; Bit32u fatentoff; - Bit32u tmpValue; switch(fattype) { case FAT12: @@ -319,23 +350,24 @@ void fatDrive::setClusterValue(Bit32u clustNum, Bit32u clustValue) { } switch(fattype) { - case FAT12: - tmpValue = *((Bit16u *)&fatSectBuffer[fatentoff]); + case FAT12: { + Bit16u tmpValue = *((Bit16u *)&fatSectBuffer[fatentoff]); if(clustNum & 0x1) { clustValue &= 0xfff; clustValue <<= 4; tmpValue &= 0xf; - tmpValue |= clustValue; + tmpValue |= (Bit16u)clustValue; } else { clustValue &= 0xfff; tmpValue &= 0xf000; - tmpValue |= clustValue; + tmpValue |= (Bit16u)clustValue; } *((Bit16u *)&fatSectBuffer[fatentoff]) = tmpValue; break; + } case FAT16: - *((Bit16u *)&fatSectBuffer[fatentoff]) = clustValue; + *((Bit16u *)&fatSectBuffer[fatentoff]) = (Bit16u)clustValue; break; case FAT32: *((Bit32u *)&fatSectBuffer[fatentoff]) = clustValue; @@ -349,11 +381,8 @@ void fatDrive::setClusterValue(Bit32u clustNum, Bit32u clustValue) { } bool fatDrive::getEntryName(char *fullname, char *entname) { - Bit16u len = strlen(fullname); char dirtoken[DOS_PATHLENGTH]; - Bit32u currentClust = 0; - direntry foundEntry; char * findDir; char * findFile; strcpy(dirtoken,fullname); @@ -370,7 +399,7 @@ bool fatDrive::getEntryName(char *fullname, char *entname) { } bool fatDrive::getFileDirEntry(char * filename, direntry * useEntry, Bit32u * dirClust, Bit32u * subEntry) { - Bit16u len = strlen(filename); + Bit32u len = (Bit32u)strlen(filename); char dirtoken[DOS_PATHLENGTH]; Bit32u currentClust = 0; @@ -405,7 +434,7 @@ bool fatDrive::getFileDirEntry(char * filename, direntry * useEntry, Bit32u * di } /* Search found directory for our file */ - imgDTA->SetupSearch(0,0x5,findFile); + imgDTA->SetupSearch(0,0x7,findFile); imgDTA->SetDirID(0); if(!FindNextInternal(currentClust, *imgDTA, &foundEntry)) return false; @@ -416,7 +445,7 @@ bool fatDrive::getFileDirEntry(char * filename, direntry * useEntry, Bit32u * di } bool fatDrive::getDirClustNum(char *dir, Bit32u *clustNum, bool parDir) { - Bit16u len = strlen(dir); + Bit32u len = (Bit32u)strlen(dir); char dirtoken[DOS_PATHLENGTH]; Bit32u currentClust = 0; direntry foundEntry; @@ -444,13 +473,11 @@ bool fatDrive::getDirClustNum(char *dir, Bit32u *clustNum, bool parDir) { } *clustNum = currentClust; - return true; } else { /* Set to root directory */ *clustNum = 0; - return true; } - return false; + return true; } Bit32u fatDrive::getSectorSize(void) { @@ -685,14 +712,22 @@ fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, bool fatDrive::AllocationInfo(Bit16u *_bytes_sector, Bit8u *_sectors_cluster, Bit16u *_total_clusters, Bit16u *_free_clusters) { Bit32u hs, cy, sect,sectsize; Bit32u countFree = 0; - int i; + Bit32u i; loadedDisk->Get_Geometry(&hs, &cy, §, §size); *_bytes_sector = (Bit16u)sectsize; *_sectors_cluster = bootbuffer.sectorspercluster; - *_total_clusters = CountOfClusters; + if (CountOfClusters<65536) *_total_clusters = (Bit16u)CountOfClusters; + else { + // maybe some special handling needed for fat32 + *_total_clusters = 65535; + } for(i=0;i=0) { @@ -978,15 +1009,11 @@ bool fatDrive::directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s } bool fatDrive::directoryChange(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum) { - direntry sectbuf[16]; /* 16 directory entries per sector */ - Bit32u logentsector; /* Logical entry sector */ - Bit32u entryoffset; /* Index offset within sector */ + direntry sectbuf[16]; /* 16 directory entries per sector */ + Bit32u logentsector; /* Logical entry sector */ + Bit32u entryoffset = 0; /* Index offset within sector */ Bit32u tmpsector = 0; - Bit8u attrs; Bit16u dirPos = 0; - char srch_pattern[DOS_NAMELENGTH_ASCII]; - char find_name[DOS_NAMELENGTH_ASCII]; - char extension[4]; while(entNum>=0) { @@ -1024,13 +1051,9 @@ bool fatDrive::addDirectoryEntry(Bit32u dirClustNumber, direntry useEntry) { Bit32u logentsector; /* Logical entry sector */ Bit32u entryoffset; /* Index offset within sector */ Bit32u tmpsector; - Bit8u attrs; Bit16u dirPos = 0; - char srch_pattern[DOS_NAMELENGTH_ASCII]; - char find_name[DOS_NAMELENGTH_ASCII]; - char extension[4]; - while(true) { + for(;;) { logentsector = dirPos / 16; entryoffset = dirPos % 16; @@ -1058,11 +1081,11 @@ bool fatDrive::addDirectoryEntry(Bit32u dirClustNumber, direntry useEntry) { if ((sectbuf[entryoffset].entryname[0] == 0xe5) || (sectbuf[entryoffset].entryname[0] == 0x00)) { sectbuf[entryoffset] = useEntry; loadedDisk->Write_AbsoluteSector(tmpsector,sectbuf); - return true; + break; } } - return false; + return true; } void fatDrive::zeroOutCluster(Bit32u clustNumber) { @@ -1151,7 +1174,6 @@ bool fatDrive::RemoveDir(char *dir) { Bit32u filecount = 0; /* Set to 2 to skip first 2 entries, [.] and [..] */ Bit32s fileidx = 2; - if (dirClust==0) fileidx = 0; // root directory while(directoryBrowse(dummyClust, &tmpentry, fileidx)) { /* Check for non-deleted files */ if(tmpentry.entryname[0] != 0xe5) filecount++; @@ -1162,7 +1184,8 @@ bool fatDrive::RemoveDir(char *dir) { if(filecount > 0) return false; /* Find directory entry in parent directory */ - fileidx = 2; + if (dirClust==0) fileidx = 0; // root directory + else fileidx = 2; bool found = false; while(directoryBrowse(dirClust, &tmpentry, fileidx)) { if(memcmp(&tmpentry.entryname, &pathName[0], 11) == 0) { @@ -1181,7 +1204,7 @@ bool fatDrive::RemoveDir(char *dir) { return true; } -bool fatDrive::Rename(char *oldname, char*newname) { +bool fatDrive::Rename(char * /*oldname*/, char * /*newname*/) { return false; } From 7a842811f02fbb2372432fedf66eb25e7026d65d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 8 Jul 2006 16:32:26 +0000 Subject: [PATCH 2583/4131] fix for virtual pool (vasyl) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2668 --- include/vga.h | 17 ++++++++++++++++- src/hardware/vga_memory.cpp | 28 +++++++++++++++------------- src/hardware/vga_s3.cpp | 25 +++++++++++++------------ 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/include/vga.h b/include/vga.h index 8c365c9c..dcf0bd5d 100644 --- a/include/vga.h +++ b/include/vga.h @@ -140,8 +140,23 @@ typedef struct { Bit8u mc[64][64]; } VGA_HWCURSOR; +typedef union { + Bit32u fullbank; +#ifndef WORDS_BIGENDIAN + struct { + Bit16u lowerbank; + Bit16u bank; + } b; +#else + struct { + Bit16u bank; + Bit16u lowerbank; + } b; +#endif +} VGA_S3_BANK; + typedef struct { - Bit8u bank; + VGA_S3_BANK svga_bank; Bit8u reg_lock1; Bit8u reg_lock2; Bit8u reg_31; diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 6138229a..0a4a5e8d 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -83,6 +83,7 @@ static struct { class VGA_UnchainedRead_Handler : public PageHandler { public: Bitu readHandler(PhysPt start) { + start += vga.s3.svga_bank.fullbank; vga.latch.d=vga.mem.latched[start].d; switch (vga.config.read_mode) { case 0: @@ -253,10 +254,10 @@ public: vga.mem.linear[((addr&~3)<<2)|(addr&3)] = val; // Linearized version for faster rendering vga.mem.linear[512*1024+addr] = val; + if (addr >= 320) return; // And replicate the first line - if (addr < 320) - vga.mem.linear[512*1024+addr+64*1024] = val; - } + vga.mem.linear[512*1024+addr+64*1024] = val; + } public: VGA_ChainedVGA_Handler() { flags=PFLAG_NOCODE; @@ -282,13 +283,13 @@ public: class VGA_UnchainedVGA_Handler : public VGA_UnchainedRead_Handler { public: void writeHandler( PhysPt addr, Bit8u val ) { + addr += vga.s3.svga_bank.fullbank; Bit32u data=ModeOperation(val); VGA_Latch pixels; pixels.d=vga.mem.latched[addr].d; pixels.d&=vga.config.full_not_map_mask; pixels.d|=(data & vga.config.full_map_mask); vga.mem.latched[addr].d=pixels.d; - vga.mem.latched[addr+64*1024].d=pixels.d; } public: VGA_UnchainedVGA_Handler() { @@ -336,11 +337,11 @@ public: } HostPt GetHostReadPt(Bitu phys_page) { phys_page-=vgapages.base; - return &vga.mem.linear[vga.s3.bank*64*1024+phys_page*4096]; + return &vga.mem.linear[vga.s3.svga_bank.fullbank+phys_page*4096]; } HostPt GetHostWritePt(Bitu phys_page) { phys_page-=vgapages.base; - return &vga.mem.linear[vga.s3.bank*64*1024+phys_page*4096]; + return &vga.mem.linear[vga.s3.svga_bank.fullbank+phys_page*4096]; } }; @@ -392,18 +393,18 @@ public: flags=PFLAG_NOCODE; } void writeb(PhysPt addr,Bitu val) { - addr = vga.s3.bank*64*1024 + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff); addr &= (512*1024-1); writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { - addr = vga.s3.bank*64*1024 + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff); addr &= (512*1024-1); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { - addr = vga.s3.bank*64*1024 + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff); addr &= (512*1024-1); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); @@ -411,19 +412,19 @@ public: writeHandler(addr+3,(Bit8u)(val >> 24)); } Bitu readb(PhysPt addr) { - addr = vga.s3.bank*64*1024 + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff); addr &= (512*1024-1); return readHandler(addr); } Bitu readw(PhysPt addr) { - addr = vga.s3.bank*64*1024 + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff); addr &= (512*1024-1); return (readHandler(addr+0) << 0) | (readHandler(addr+1) << 8); } Bitu readd(PhysPt addr) { - addr = vga.s3.bank*64*1024 + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff); addr &= (512*1024-1); return (readHandler(addr+0) << 0) | @@ -634,12 +635,12 @@ void VGA_SetupHandlers(void) { case M_LIN4: range_handler=&vgaph.l4banked; break; - case M_LIN8: case M_LIN15: case M_LIN16: case M_LIN32: range_handler=&vgaph.map; break; + case M_LIN8: case M_VGA: if (vga.config.chained) { if(vga.config.compatible_chain4) @@ -727,6 +728,7 @@ void VGA_UnmapMMIO(void) { void VGA_SetupMemory() { memset((void *)&vga.mem,0,512*1024*4); + vga.s3.svga_bank.fullbank=0; if (machine==MCH_PCJR) { /* PCJr does not have dedicated graphics memory but uses conventional memory below 128k */ diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index 8668cac8..c2459f3d 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_s3.cpp,v 1.3 2006-02-14 12:44:38 qbix79 Exp $ */ +/* $Id: vga_s3.cpp,v 1.4 2006-07-08 16:32:26 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -26,7 +26,8 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { switch (reg) { case 0x31: /* CR31 Memory Configuration */ //TODO Base address - vga.s3.reg_31 = val; + vga.s3.reg_31 = val; + vga.config.compatible_chain4 = !(val&0x08); VGA_DetermineMode(); break; /* @@ -46,9 +47,9 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { case 0x35: /* CR35 CRT Register Lock */ if (vga.s3.reg_lock1 != 0x48) return; //Needed for uvconfig detection vga.s3.reg_35=val & 0xf0; - if ((vga.s3.bank & 0xf) ^ (val & 0xf)) { - vga.s3.bank&=0xf0; - vga.s3.bank|=val & 0xf; + if ((vga.s3.svga_bank.b.bank & 0xf) ^ (val & 0xf)) { + vga.s3.svga_bank.b.bank&=0xf0; + vga.s3.svga_bank.b.bank|=val & 0xf; VGA_SetupHandlers(); } break; @@ -128,9 +129,9 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { //TODO Display start vga.config.display_start&=0xFCFFFF; vga.config.display_start|=(val & 3) << 16; - if ((vga.s3.bank&0xcf) ^ ((val&0xc)<<2)) { - vga.s3.bank&=0xcf; - vga.s3.bank|=(val&0xc)<<2; + if ((vga.s3.svga_bank.b.bank&0xcf) ^ ((val&0xc)<<2)) { + vga.s3.svga_bank.b.bank&=0xcf; + vga.s3.svga_bank.b.bank|=(val&0xc)<<2; VGA_SetupHandlers(); } if (((val & 0x30) ^ (vga.config.scan_len >> 4)) & 0x30) { @@ -297,7 +298,7 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { } break; case 0x6a: /* Extended System Control 4 */ - vga.s3.bank=val & 0x3f; + vga.s3.svga_bank.b.bank=val & 0x3f; VGA_SetupHandlers(); break; default: @@ -323,7 +324,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { //TODO mix in bits from baseaddress; return vga.s3.reg_31; case 0x35: /* CR35 CRT Register Lock */ - return vga.s3.reg_35|(vga.s3.bank & 0xf); + return vga.s3.reg_35|(vga.s3.svga_bank.b.bank & 0xf); case 0x36: /* CR36 Reset State Read 1 */ //return 0x8f; return 0x8e; /* PCI version */ @@ -344,7 +345,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { return vga.s3.hgc.curmode; case 0x51: /* Extended System Control 2 */ return ((vga.config.display_start >> 16) & 3 ) | - ((vga.s3.bank & 0x30) >> 2) | + ((vga.s3.svga_bank.b.bank & 0x30) >> 2) | ((vga.config.scan_len & 0x300) >> 4) | vga.s3.reg_51; case 0x53: @@ -366,7 +367,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { case 0x69: /* Extended System Control 3 */ return (Bit8u)((vga.config.display_start & 0x1f0000)>>16); case 0x6a: /* Extended System Control 4 */ - return (Bit8u)(vga.s3.bank & 0x3f); + return (Bit8u)(vga.s3.svga_bank.b.bank & 0x3f); default: return 0x00; } From 06297a72aecd0c71fa2a05e77f80695cd1ecb745 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 10 Jul 2006 09:27:37 +0000 Subject: [PATCH 2584/4131] Don't raise irq 0 when programming a new timer instantatanously. Take in account that the hardware requires some time to be setup as well. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2669 --- src/hardware/timer.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 7a214203..bc2a6763 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.38 2006-05-19 10:34:02 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.39 2006-07-10 09:27:37 qbix79 Exp $ */ #include #include "dosbox.h" @@ -295,8 +295,11 @@ static void write_p43(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { if (latch == 0) { PIC_RemoveEvents(PIT0_Event); - if (!counter_output(0) && mode) + if (!counter_output(0) && mode) { PIC_ActivateIRQ(0); + //Don't raise instantaniously. (Origamo) + if(CPU_Cycles < 25) CPU_Cycles = 25; + } if(!mode) PIC_DeActivateIRQ(0); } From dca519a601d876c02fb4e49ffda63a35a225a47b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 10 Jul 2006 19:32:15 +0000 Subject: [PATCH 2585/4131] fix keyboard handling for sdl windib driver as far as possible Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2670 --- include/video.h | 4 ++++ src/gui/sdl_mapper.cpp | 21 ++++++++++++++++++++- src/gui/sdlmain.cpp | 39 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/include/video.h b/include/video.h index e439369e..3f192e81 100644 --- a/include/video.h +++ b/include/video.h @@ -64,6 +64,10 @@ void GFX_SwitchFullScreen(void); bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch); void GFX_EndUpdate( const Bit16u *changedLines ); +#if defined (WIN32) +bool GFX_SDLUsingWinDIB(void); +#endif + /* Mouse related */ void GFX_CaptureMouse(void); extern bool mouselocked; //true if mouse is confined to window diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 822d43dc..dfe4918b 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.25 2006-06-24 17:29:39 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.26 2006-07-10 19:32:15 c2woody Exp $ */ #define OLD_JOYSTICK 1 @@ -333,6 +333,25 @@ Bitu GetKeyCode(SDL_keysym keysym) { #if !defined (WIN32) && !defined (MACOSX) /* Linux adds 8 to all scancodes */ else key-=8; +#endif +#if defined (WIN32) + switch (key) { + case 0x1c: // ENTER + case 0x35: // SLASH + case 0x45: // PAUSE + case 0x47: // HOME + case 0x48: // cursor UP + case 0x49: // PAGE UP + case 0x4b: // cursor LEFT + case 0x4d: // cursor RIGHT + case 0x4f: // END + case 0x50: // cursor DOWN + case 0x51: // PAGE DOWN + case 0x52: // INSERT + case 0x53: // DELETE + if (GFX_SDLUsingWinDIB()) key=scancode_map[(Bitu)keysym.sym]; + break; + } #endif return key; } else { diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index a470d9c4..5e3488d6 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.119 2006-06-29 19:05:54 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.120 2006-07-10 19:32:15 c2woody Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -203,6 +203,9 @@ struct SDL_Block { Bitu sensitivity; } mouse; SDL_Rect updateRects[1024]; +#if defined (WIN32) + bool using_windib; +#endif }; static SDL_Block sdl; @@ -253,6 +256,11 @@ static void PauseDOSBox(bool pressed) { } } +#if defined (WIN32) +bool GFX_SDLUsingWinDIB(void) { + return sdl.using_windib; +} +#endif /* Reset the screen with current values in the sdl structure */ Bitu GFX_GetBestMode(Bitu flags) { @@ -423,6 +431,7 @@ dosurface: SDL_QuitSubSystem(SDL_INIT_VIDEO); putenv("SDL_VIDEODRIVER=windib"); SDL_InitSubSystem(SDL_INIT_VIDEO); + sdl.using_windib=true; sdl.surface = SDL_SetVideoMode(width,height,bpp,SDL_HWSURFACE); } #endif @@ -525,6 +534,9 @@ dosurface: goto dosurface; } SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); +#if defined (WIN32) && SDL_VERSION_ATLEAST(1, 2, 11) + SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 0 ); +#endif GFX_SetupSurfaceScaled(SDL_OPENGL,0); if (!sdl.surface || sdl.surface->format->BitsPerPixel<15) { LOG_MSG("SDL:OPENGL:Can't open drawing surface, are you running in 16bpp(or higher) mode?"); @@ -1335,6 +1347,31 @@ int main(int argc, char* argv[]) { |SDL_INIT_JOYSTICK #endif ) < 0 ) E_Exit("Can't init SDL %s",SDL_GetError()); +#if defined (WIN32) +#if SDL_VERSION_ATLEAST(1, 2, 10) + sdl.using_windib=true; +#else + sdl.using_windib=false; +#endif + char sdl_drv_name[128]; + if (getenv("SDL_VIDEODRIVER")==NULL) { + if (SDL_VideoDriverName(sdl_drv_name,128)!=NULL) { + if (strcmp(sdl_drv_name,"directx")!=0) { + SDL_QuitSubSystem(SDL_INIT_VIDEO); + putenv("SDL_VIDEODRIVER=directx"); + SDL_InitSubSystem(SDL_INIT_VIDEO); + } + sdl.using_windib=false; + } + } else { + char* sdl_videodrv = getenv("SDL_VIDEODRIVER"); + if (strcmp(sdl_videodrv,"directx")==0) sdl.using_windib = false; + else if (strcmp(sdl_videodrv,"windib")==0) sdl.using_windib = true; + } + if (SDL_VideoDriverName(sdl_drv_name,128)!=NULL) { + if (strcmp(sdl_drv_name,"windib")==0) LOG_MSG("SDL_Init: Starting up with SDL windib video driver.\n Try to update your video card and directx drivers!"); + } +#endif Section_prop * sdl_sec=control->AddSection_prop("sdl",&GUI_StartUp); sdl_sec->AddInitFunction(&MAPPER_StartUp); sdl_sec->Add_bool("fullscreen",false); From 58561958ffbf7d292e2c4e755c9ae37f53acf4dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 15 Jul 2006 20:41:42 +0000 Subject: [PATCH 2586/4131] fix AAM instruction Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2671 --- src/cpu/instructions.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index d2830733..bcda9acb 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -18,7 +18,7 @@ /* Jumps */ -/* All Byte genereal instructions */ +/* All Byte general instructions */ #define ADDB(op1,op2,load,save) \ lf_var1b=load(op1);lf_var2b=op2; \ lf_resb=lf_var1b+lf_var2b; \ @@ -578,7 +578,7 @@ SETFLAGBIT(PF,parity_lookup[reg_al]); #define AAM(op1) \ - { \ + if ((Bit8u)op1!=0) { \ Bit8u BLAH=op1; \ reg_ah=reg_al / BLAH; \ reg_al=reg_al % BLAH; \ @@ -589,7 +589,7 @@ SETFLAGBIT(OF,0); \ SETFLAGBIT(AF,0); \ lflags.type=t_UNKNOWN; \ - } + } else EXCEPTION(0); //Took this from bochs, i seriously hate these weird bcd opcodes From 72c6d40dbc2b79b90a7b96e569746bc91a4b8359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 18 Jul 2006 15:31:29 +0000 Subject: [PATCH 2587/4131] always allow changing to floppy drives (fixes Sokoban) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2672 --- src/dos/dos_files.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 8c3e6082..e6817cc5 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.76 2006-06-30 20:04:21 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.77 2006-07-18 15:31:29 c2woody Exp $ */ #include #include @@ -49,7 +49,7 @@ Bit8u DOS_GetDefaultDrive(void) { } void DOS_SetDefaultDrive(Bit8u drive) { - if (drive<=DOS_DRIVES && Drives[drive]) dos.current_drive = drive; + if (drive<=DOS_DRIVES && ((drive<2) || Drives[drive])) dos.current_drive = drive; } bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { From a2c6e8305a8e60a0bfbdc4647152b14ad044f16c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 19 Jul 2006 10:30:29 +0000 Subject: [PATCH 2588/4131] merge AAM-fixes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2673 --- src/cpu/instructions.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index bcda9acb..93a79584 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -578,10 +578,11 @@ SETFLAGBIT(PF,parity_lookup[reg_al]); #define AAM(op1) \ - if ((Bit8u)op1!=0) { \ - Bit8u BLAH=op1; \ - reg_ah=reg_al / BLAH; \ - reg_al=reg_al % BLAH; \ +{ \ + Bit8u dv=op1; \ + if (dv!=0) { \ + reg_ah=reg_al / dv; \ + reg_al=reg_al % dv; \ SETFLAGBIT(SF,(reg_al & 0x80)); \ SETFLAGBIT(ZF,(reg_al == 0)); \ SETFLAGBIT(PF,parity_lookup[reg_al]); \ @@ -589,7 +590,8 @@ SETFLAGBIT(OF,0); \ SETFLAGBIT(AF,0); \ lflags.type=t_UNKNOWN; \ - } else EXCEPTION(0); + } else EXCEPTION(0); \ +} //Took this from bochs, i seriously hate these weird bcd opcodes From 39bcdda8c2206ff275cbb6e09ad80985c7a04460 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 21 Jul 2006 09:40:10 +0000 Subject: [PATCH 2589/4131] Add (set)ver. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2674 --- include/shell.h | 3 ++- src/shell/shell.cpp | 4 +++- src/shell/shell_cmds.cpp | 15 +++++++++++++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/include/shell.h b/include/shell.h index fbc7c80b..5589e64b 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.16 2006-05-25 15:08:40 qbix79 Exp $ */ +/* $Id: shell.h,v 1.17 2006-07-21 09:40:10 qbix79 Exp $ */ #ifndef DOSBOX_SHELL_H #define DOSBOX_SHELL_H @@ -106,6 +106,7 @@ public: 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; diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index cdba628f..01fc6272 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.75 2006-06-30 20:04:21 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.76 2006-07-21 09:40:10 qbix79 Exp $ */ #include #include @@ -509,6 +509,8 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_CHOICE_HELP","Waits for a keypress and sets ERRORLEVEL.\n"); MSG_Add("SHELL_CMD_ATTRIB_HELP","Does nothing. Provided for compatibility.\n"); MSG_Add("SHELL_CMD_PATH_HELP","Provided for compatibility.\n"); + MSG_Add("SHELL_CMD_VER_HELP","View and set the reported DOS version.\n"); + MSG_Add("SHELL_CMD_VER_VER","DOSBox version %s. Reported DOS version %d.%d.\n"); /* Regular startup */ call_shellstop=CALLBACK_Allocate(); diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 489101d7..53b4a774 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.67 2006-05-25 15:08:40 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.68 2006-07-21 09:40:10 qbix79 Exp $ */ #include #include @@ -59,6 +59,7 @@ static SHELL_Cmd cmd_list[]={ { "CHOICE", 0, &DOS_Shell::CMD_CHOICE, "SHELL_CMD_CHOICE_HELP"}, { "ATTRIB", 0, &DOS_Shell::CMD_ATTRIB, "SHELL_CMD_ATTRIB_HELP"}, { "PATH", 1, &DOS_Shell::CMD_PATH, "SHELL_CMD_PATH_HELP"}, +{ "VER", 0, &DOS_Shell::CMD_VER, "SHELL_CMD_VER_HELP"}, {0,0,0,0} }; bool DOS_Shell::CheckConfig(char* cmd,char*line) { @@ -500,7 +501,7 @@ void DOS_Shell::CMD_COPY(char * args) { bool ret=DOS_FindFirst(source,0xffff & ~DOS_ATTR_VOLUME); if (!ret) { - WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); + WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),source); dos.dta(save_dta); return; } @@ -857,3 +858,13 @@ void DOS_Shell::CMD_PATH(char *args){ } } } + +void DOS_Shell::CMD_VER(char *args) { + if(args && *args) { + char* word = StripWord(args); + if(strcasecmp(word,"set")) return; + word = StripWord(args); + dos.version.major = atoi(word); + dos.version.minor = atoi(args); + } else WriteOut(MSG_Get("SHELL_CMD_VER_VER"),VERSION,dos.version.major,dos.version.minor); +} From 1880321b6c9f3e3f6ef49350977410d26456004a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 22 Jul 2006 08:34:30 +0000 Subject: [PATCH 2590/4131] Documentation corrections. Forwarded from the debian package. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2675 --- docs/dosbox.1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dosbox.1 b/docs/dosbox.1 index f5c30658..cfe18ada 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -158,7 +158,7 @@ the emulated soundcards and many .LP The language file controls all visible ouput of the internal commands and the internal dos. -.RB "See the secion " FILES " for more information." +.RB "See the section " FILES " for more information." .TP .B LOADFIX [\-size] [programname] [parameters] .LP @@ -295,7 +295,7 @@ games (or earlier). Also note that "protected mode" games need substantially mor .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 occured." +.BR dosbox " will exit without warning if an error occurred." .SH "SEE ALSO" The README in /usr/share/doc/dosbox .SH AUTHOR From fcd1a968080ce1ff7309fe7525fff121318177ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 22 Jul 2006 18:32:29 +0000 Subject: [PATCH 2591/4131] implement different joystick querying, reduce polling intervall (thanks hal for the ideas) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2676 --- include/video.h | 6 + src/gui/sdl_mapper.cpp | 501 +++++++++++++++++++++++++++-------------- src/gui/sdlmain.cpp | 19 +- 3 files changed, 353 insertions(+), 173 deletions(-) diff --git a/include/video.h b/include/video.h index 3f192e81..b80e1af3 100644 --- a/include/video.h +++ b/include/video.h @@ -19,6 +19,8 @@ #ifndef DOSBOX_VIDEO_H #define DOSBOX_VIDEO_H +#define REDUCE_JOYSTICK_POLLING + typedef enum { GFX_CallBackReset, GFX_CallBackStop, @@ -68,6 +70,10 @@ void GFX_EndUpdate( const Bit16u *changedLines ); 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 diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index dfe4918b..9c3bc3da 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.26 2006-07-10 19:32:15 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.27 2006-07-22 18:32:29 c2woody Exp $ */ #define OLD_JOYSTICK 1 @@ -491,6 +491,8 @@ protected: Bitu mask; }; +static bool autofire=false; + class CStickBindGroup : public CBindGroup { public: CStickBindGroup(Bitu _stick) : CBindGroup (){ @@ -506,12 +508,13 @@ public: button_lists=new CBindList[buttons]; hat_lists=new CBindList[hats]; emulated_buttons = 2; + for (Bitu i=0; itype==SDL_JOYAXISMOTION) { - if (event->jaxis .which!=stick) return 0; + if (event->jaxis.which!=stick) return 0; if (abs(event->jaxis.value)<25000) return 0; return CreateAxisBind(event->jaxis.axis,event->jaxis.value>0); } else if (event->type==SDL_JOYBUTTONDOWN) { - if (event->jaxis .which!=stick) return 0; + if (event->jaxis.which!=stick) return 0; return CreateButtonBind(event->jbutton.button); } else return 0; } + virtual bool CheckEvent(SDL_Event * event) { #if OLD_JOYSTICK SDL_JoyAxisEvent * jaxis = NULL; SDL_JoyButtonEvent * jbutton = NULL; Bitu but = 0; - switch(event->type) { - case SDL_JOYAXISMOTION: - jaxis = &event->jaxis; - if(jaxis->which == stick) - if(jaxis->axis == 0) - JOYSTICK_Move_X(emustick,(float)(jaxis->value/32768.0)); - else if(jaxis->axis == 1) - JOYSTICK_Move_Y(emustick,(float)(jaxis->value/32768.0)); - break; - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - jbutton = &event->jbutton; - bool state; - state=jbutton->type==SDL_JOYBUTTONDOWN; - but = jbutton->button % emulated_buttons; - if (jbutton->which == stick) { - JOYSTICK_Button(emustick,but,state); - } - break; - } + switch(event->type) { + case SDL_JOYAXISMOTION: + jaxis = &event->jaxis; + if(jaxis->which == stick) { + if(jaxis->axis == 0) + JOYSTICK_Move_X(emustick,(float)(jaxis->value/32768.0)); + else if(jaxis->axis == 1) + JOYSTICK_Move_Y(emustick,(float)(jaxis->value/32768.0)); + } + break; + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + jbutton = &event->jbutton; + bool state; + state=jbutton->type==SDL_JOYBUTTONDOWN; + but = jbutton->button % emulated_buttons; + if (jbutton->which == stick) { + JOYSTICK_Button(emustick,but,state); + } + break; + } #endif return false; } + + virtual void UpdateJoystick() { + Sint16 axis_pos=SDL_JoystickGetAxis(sdl_joystick,0); + JOYSTICK_Move_X(emustick,(float)(axis_pos/32768.0)); + axis_pos=SDL_JoystickGetAxis(sdl_joystick,1); + JOYSTICK_Move_Y(emustick,(float)(axis_pos/32768.0)); + + bool button_pressed[16]; + Bitu i; + for (i=0; i<16; i++) button_pressed[i]=false; + for (i=0; itype) { - case SDL_JOYAXISMOTION: - jaxis = &event->jaxis; - if(jaxis->which == stick && jaxis->axis < 4) - if(jaxis->axis & 1) - JOYSTICK_Move_Y(jaxis->axis>>1 & 1,(float)(jaxis->value/32768.0)); - else - JOYSTICK_Move_X(jaxis->axis>>1 & 1,(float)(jaxis->value/32768.0)); - break; - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - jbutton = &event->jbutton; - bool state; - state=jbutton->type==SDL_JOYBUTTONDOWN; - but = jbutton->button % emulated_buttons; - if (jbutton->which == stick) { - JOYSTICK_Button((but >> 1),(but & 1),state); - } - break; - } + switch(event->type) { + case SDL_JOYAXISMOTION: + jaxis = &event->jaxis; + if(jaxis->which == stick && jaxis->axis < 4) { + if(jaxis->axis & 1) + JOYSTICK_Move_Y(jaxis->axis>>1 & 1,(float)(jaxis->value/32768.0)); + else + JOYSTICK_Move_X(jaxis->axis>>1 & 1,(float)(jaxis->value/32768.0)); + } + break; + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + jbutton = &event->jbutton; + bool state; + state=jbutton->type==SDL_JOYBUTTONDOWN; + but = jbutton->button % emulated_buttons; + if (jbutton->which == stick) { + JOYSTICK_Button((but >> 1),(but & 1),state); + } + break; + } #endif return false; } + + virtual void UpdateJoystick() { + Sint16 axis_pos=SDL_JoystickGetAxis(sdl_joystick,0); + JOYSTICK_Move_X(0,(float)(axis_pos/32768.0)); + axis_pos=SDL_JoystickGetAxis(sdl_joystick,1); + JOYSTICK_Move_Y(0,(float)(axis_pos/32768.0)); + + axis_pos=SDL_JoystickGetAxis(sdl_joystick,2); + JOYSTICK_Move_X(1,(float)(axis_pos/32768.0)); + axis_pos=SDL_JoystickGetAxis(sdl_joystick,3); + JOYSTICK_Move_Y(1,(float)(axis_pos/32768.0)); + + bool button_pressed[16]; + Bitu i; + for (i=0; i<16; i++) button_pressed[i]=false; + for (i=0; i> 1,(i & 1),(++button_autofire[i])&1); + else + JOYSTICK_Button(i >> 1,(i & 1),button_pressed[i]); + } + } }; class CFCSBindGroup : public CStickBindGroup { public: CFCSBindGroup(Bitu _stick) : CStickBindGroup (_stick){ emulated_buttons = 4; + old_hat_position=0; + for (Bitu i=0; itype) { - case SDL_JOYAXISMOTION: - jaxis = &event->jaxis; - if(jaxis->which == stick) - if(jaxis->axis == 0) - JOYSTICK_Move_X(0,(float)(jaxis->value/32768.0)); - else if(jaxis->axis == 1) - JOYSTICK_Move_Y(0,(float)(jaxis->value/32768.0)); - else if(jaxis->axis == 2) - JOYSTICK_Move_X(1,(float)(jaxis->value/32768.0)); - break; - case SDL_JOYHATMOTION: - jhat = &event->jhat; - if(jhat->which == stick) { - switch(jhat->value) { - case SDL_HAT_CENTERED: - JOYSTICK_Move_Y(1,1.0); - break; - case SDL_HAT_UP: - JOYSTICK_Move_Y(1,-1.0); - break; - case SDL_HAT_RIGHT: - JOYSTICK_Move_Y(1,-0.5); - break; - case SDL_HAT_DOWN: - JOYSTICK_Move_Y(1,0.0); - break; - case SDL_HAT_LEFT: - JOYSTICK_Move_Y(1,0.5); - break; - case SDL_HAT_LEFTUP: - if(JOYSTICK_GetMove_Y(1) < 0) - JOYSTICK_Move_Y(1,0.5); - else - JOYSTICK_Move_Y(1,-1.0); - break; - case SDL_HAT_RIGHTUP: - if(JOYSTICK_GetMove_Y(1) < -0.7) - JOYSTICK_Move_Y(1,-0.5); - else - JOYSTICK_Move_Y(1,-1.0); - break; - case SDL_HAT_RIGHTDOWN: - if(JOYSTICK_GetMove_Y(1) < -0.2) - JOYSTICK_Move_Y(1,0.0); - else - JOYSTICK_Move_Y(1,-0.5); - break; - case SDL_HAT_LEFTDOWN: - if(JOYSTICK_GetMove_Y(1) > 0.2) - JOYSTICK_Move_Y(1,0.0); - else - JOYSTICK_Move_Y(1,0.5); - break; + switch(event->type) { + case SDL_JOYAXISMOTION: + jaxis = &event->jaxis; + if(jaxis->which == stick) { + if(jaxis->axis == 0) + JOYSTICK_Move_X(0,(float)(jaxis->value/32768.0)); + else if(jaxis->axis == 1) + JOYSTICK_Move_Y(0,(float)(jaxis->value/32768.0)); + else if(jaxis->axis == 2) + JOYSTICK_Move_X(1,(float)(jaxis->value/32768.0)); } - } - - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - jbutton = &event->jbutton; - bool state; - state=jbutton->type==SDL_JOYBUTTONDOWN; - but = jbutton->button % emulated_buttons; - if (jbutton->which == stick) { - JOYSTICK_Button((but >> 1),(but & 1),state); - } - break; - } + break; + case SDL_JOYHATMOTION: + jhat = &event->jhat; + if(jhat->which == stick) DecodeHatPosition(jhat->value); + break; + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + jbutton = &event->jbutton; + bool state; + state=jbutton->type==SDL_JOYBUTTONDOWN; + but = jbutton->button % emulated_buttons; + if (jbutton->which == stick) { + JOYSTICK_Button((but >> 1),(but & 1),state); + } + break; + } #endif return false; } + + void UpdateJoystick() { + Sint16 axis_pos=SDL_JoystickGetAxis(sdl_joystick,0); + JOYSTICK_Move_X(emustick,(float)(axis_pos/32768.0)); + axis_pos=SDL_JoystickGetAxis(sdl_joystick,1); + JOYSTICK_Move_Y(emustick,(float)(axis_pos/32768.0)); + + axis_pos=SDL_JoystickGetAxis(sdl_joystick,2); + JOYSTICK_Move_X(1,(float)(axis_pos/32768.0)); + + Uint8 hat_position=SDL_JoystickGetHat(sdl_joystick,0); + if (hat_position!=old_hat_position) { + DecodeHatPosition(hat_position); + old_hat_position=hat_position; + } + + bool button_pressed[16]; + Bitu i; + for (i=0; i<16; i++) button_pressed[i]=false; + for (i=0; i> 1,(i & 1),(++button_autofire[i])&1); + else + JOYSTICK_Button(i >> 1,(i & 1),button_pressed[i]); + } + } + +private: + Uint8 old_hat_position; + + void DecodeHatPosition(Uint8 hat_pos) { + switch(hat_pos) { + case SDL_HAT_CENTERED: + JOYSTICK_Move_Y(1,1.0); + break; + case SDL_HAT_UP: + JOYSTICK_Move_Y(1,-1.0); + break; + case SDL_HAT_RIGHT: + JOYSTICK_Move_Y(1,-0.5); + break; + case SDL_HAT_DOWN: + JOYSTICK_Move_Y(1,0.0); + break; + case SDL_HAT_LEFT: + JOYSTICK_Move_Y(1,0.5); + break; + case SDL_HAT_LEFTUP: + if(JOYSTICK_GetMove_Y(1) < 0) + JOYSTICK_Move_Y(1,0.5); + else + JOYSTICK_Move_Y(1,-1.0); + break; + case SDL_HAT_RIGHTUP: + if(JOYSTICK_GetMove_Y(1) < -0.7) + JOYSTICK_Move_Y(1,-0.5); + else + JOYSTICK_Move_Y(1,-1.0); + break; + case SDL_HAT_RIGHTDOWN: + if(JOYSTICK_GetMove_Y(1) < -0.2) + JOYSTICK_Move_Y(1,0.0); + else + JOYSTICK_Move_Y(1,-0.5); + break; + case SDL_HAT_LEFTDOWN: + if(JOYSTICK_GetMove_Y(1) > 0.2) + JOYSTICK_Move_Y(1,0.0); + else + JOYSTICK_Move_Y(1,0.5); + break; + } + } }; class CCHBindGroup : public CStickBindGroup { @@ -734,54 +832,58 @@ public: #if OLD_JOYSTICK JOYSTICK_Enable(1,true); button_state=0; -#endif +#endif } - bool CheckEvent(SDL_Event * event) { + + + bool CheckEvent(SDL_Event * event) { #if OLD_JOYSTICK - SDL_JoyAxisEvent * jaxis = NULL; + SDL_JoyAxisEvent * jaxis = NULL; SDL_JoyButtonEvent * jbutton = NULL; SDL_JoyHatEvent * jhat = NULL; Bitu but = 0; static unsigned const button_magic[6]={0x02,0x04,0x10,0x100,0x20,0x200}; static unsigned const hat_magic[2][5]={{0x8888,0x8000,0x800,0x80,0x08}, - {0x5440,0x4000,0x400,0x40,0x1000}}; - switch(event->type) { - case SDL_JOYAXISMOTION: - jaxis = &event->jaxis; - if(jaxis->which == stick && jaxis->axis < 4) - if(jaxis->axis & 1) - JOYSTICK_Move_Y(jaxis->axis>>1 & 1,(float)(jaxis->value/32768.0)); - else - JOYSTICK_Move_X(jaxis->axis>>1 & 1,(float)(jaxis->value/32768.0)); - break; - case SDL_JOYHATMOTION: - jhat = &event->jhat; - if(jhat->which == stick && jhat->hat < 2) { - if(jhat->value == SDL_HAT_CENTERED) - button_state&=~hat_magic[jhat->hat][0]; - if(jhat->value & SDL_HAT_UP) - button_state|=hat_magic[jhat->hat][1]; - if(jhat->value & SDL_HAT_RIGHT) - button_state|=hat_magic[jhat->hat][2]; - if(jhat->value & SDL_HAT_DOWN) - button_state|=hat_magic[jhat->hat][3]; - if(jhat->value & SDL_HAT_LEFT) - button_state|=hat_magic[jhat->hat][4]; - } - break; - case SDL_JOYBUTTONDOWN: - jbutton = &event->jbutton; - but = jbutton->button % emulated_buttons; - if (jbutton->which == stick) - button_state|=button_magic[but]; - break; - case SDL_JOYBUTTONUP: - jbutton = &event->jbutton; - but = jbutton->button % emulated_buttons; - if (jbutton->which == stick) - button_state&=~button_magic[but]; - break; - } + {0x5440,0x4000,0x400,0x40,0x1000}}; + switch(event->type) { + case SDL_JOYAXISMOTION: + jaxis = &event->jaxis; + if(jaxis->which == stick && jaxis->axis < 4) { + if(jaxis->axis & 1) + JOYSTICK_Move_Y(jaxis->axis>>1 & 1,(float)(jaxis->value/32768.0)); + else + JOYSTICK_Move_X(jaxis->axis>>1 & 1,(float)(jaxis->value/32768.0)); + } + break; + case SDL_JOYHATMOTION: + jhat = &event->jhat; + if(jhat->which == stick && jhat->hat < 2) { + if(jhat->value == SDL_HAT_CENTERED) + button_state&=~hat_magic[jhat->hat][0]; + if(jhat->value & SDL_HAT_UP) + button_state|=hat_magic[jhat->hat][1]; + if(jhat->value & SDL_HAT_RIGHT) + button_state|=hat_magic[jhat->hat][2]; + if(jhat->value & SDL_HAT_DOWN) + button_state|=hat_magic[jhat->hat][3]; + if(jhat->value & SDL_HAT_LEFT) + button_state|=hat_magic[jhat->hat][4]; + } + break; + case SDL_JOYBUTTONDOWN: + jbutton = &event->jbutton; + but = jbutton->button % emulated_buttons; + if (jbutton->which == stick) + button_state|=button_magic[but]; + break; + case SDL_JOYBUTTONUP: + jbutton = &event->jbutton; + but = jbutton->button % emulated_buttons; + if (jbutton->which == stick) + button_state&=~button_magic[but]; + break; + } + unsigned i; Bit16u j; j=button_state; @@ -791,9 +893,56 @@ public: JOYSTICK_Button(1,0,i>>2&0x01); JOYSTICK_Button(1,1,i>>3&0x01); #endif - return false; } + + void UpdateJoystick() { + static unsigned const button_priority[6]={7,11,13,14,5,6}; + static unsigned const hat_priority[2][4]={{0,1,2,3},{8,9,10,12}}; + + Sint16 axis_pos=SDL_JoystickGetAxis(sdl_joystick,0); + JOYSTICK_Move_X(0,(float)(axis_pos/32768.0)); + axis_pos=SDL_JoystickGetAxis(sdl_joystick,1); + JOYSTICK_Move_Y(0,(float)(axis_pos/32768.0)); + + axis_pos=SDL_JoystickGetAxis(sdl_joystick,2); + JOYSTICK_Move_X(1,(float)(axis_pos/32768.0)); + axis_pos=SDL_JoystickGetAxis(sdl_joystick,3); + JOYSTICK_Move_Y(1,(float)(axis_pos/32768.0)); + + Bitu bt_state=15; + + Bitu i; + for (i=0; i<(hats<2?hats:2); i++) { + Uint8 hat_position=SDL_JoystickGetHat(sdl_joystick,i); + if (hat_position & SDL_HAT_UP) + if (bt_state>hat_priority[i][0]) bt_state=hat_priority[i][0]; + if (hat_position & SDL_HAT_DOWN) + if (bt_state>hat_priority[i][1]) bt_state=hat_priority[i][1]; + if (hat_position & SDL_HAT_RIGHT) + if (bt_state>hat_priority[i][2]) bt_state=hat_priority[i][2]; + if (hat_position & SDL_HAT_LEFT) + if (bt_state>hat_priority[i][3]) bt_state=hat_priority[i][3]; + } + + bool button_pressed[6]; + for (i=0; i<6; i++) button_pressed[i]=false; + for (i=0; ibutton_priority[i]) bt_state=button_priority[i]; + } + + if (bt_state>15) bt_state=15; + JOYSTICK_Button(0,0,(bt_state&8)==0); + JOYSTICK_Button(0,1,(bt_state&4)==0); + JOYSTICK_Button(1,0,(bt_state&2)==0); + JOYSTICK_Button(1,1,(bt_state&1)==0); + } + protected: Bit16u button_state; }; @@ -808,13 +957,9 @@ static struct { bool redraw; bool addbind; Bitu mods; - struct { - CKeyBindGroup * keys; - CStickBindGroup * stick[MAXSTICKS]; - } grp; struct { Bitu num; - SDL_Joystick * opened[MAXSTICKS]; + CStickBindGroup * stick[MAXSTICKS]; } sticks; const char * filename; } mapper; @@ -992,7 +1137,7 @@ public: } void Draw(void) { if (!enabled) return; - bool checked; + bool checked=false; switch (type) { case BC_Mod1: checked=(mapper.abind->mods&BMOD_Mod1)>0; @@ -1587,33 +1732,48 @@ void BIND_MappingEvents(void) { static void CreateBindGroups(void) { bindgroups.clear(); new CKeyBindGroup(SDLK_LAST); + mapper.sticks.num=0; if (joytype != JOY_NONE) { Bitu numsticks=SDL_NumJoysticks(); +#if defined (REDUCE_JOYSTICK_POLLING) + // direct access to the SDL joystick, thus removed from the event handling + if (numsticks) SDL_JoystickEventState(SDL_DISABLE); +#else + // enable joystick event handling if (numsticks) SDL_JoystickEventState(SDL_ENABLE); +#endif #if OLD_JOYSTICK else return; #endif Bit8u joyno=0; switch (joytype) { case JOY_4AXIS: - new C4AxisBindGroup(joyno); + mapper.sticks.stick[mapper.sticks.num++]=new C4AxisBindGroup(joyno); break; case JOY_FCS: - new CFCSBindGroup(joyno); + mapper.sticks.stick[mapper.sticks.num++]=new CFCSBindGroup(joyno); break; case JOY_CH: - new CCHBindGroup(joyno); + mapper.sticks.stick[mapper.sticks.num++]=new CCHBindGroup(joyno); break; case JOY_2AXIS: default: - new CStickBindGroup(joyno); + mapper.sticks.stick[mapper.sticks.num++]=new CStickBindGroup(joyno); if((joyno+1U) < numsticks) - new CStickBindGroup(joyno+1U); + mapper.sticks.stick[mapper.sticks.num++]=new CStickBindGroup(joyno+1U); break; } } } +#if defined (REDUCE_JOYSTICK_POLLING) +void MAPPER_UpdateJoysticks(void) { + for (Bitu i=0; iUpdateJoystick(); + } +} +#endif + void MAPPER_LosingFocus(void) { for (CEventVector_it evit=events.begin();evit!=events.end();evit++) { (*evit)->DeActivateAll(); @@ -1665,6 +1825,7 @@ void MAPPER_Init(void) { void MAPPER_StartUp(Section * sec) { Section_prop * section=static_cast(sec); + mapper.sticks.num=0; usescancodes=false; if (section->Get_bool("usescancodes")) { diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 5e3488d6..d02c0c62 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.120 2006-07-10 19:32:15 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.121 2006-07-22 18:32:29 c2woody Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -203,6 +203,7 @@ struct SDL_Block { Bitu sensitivity; } mouse; SDL_Rect updateRects[1024]; + Bitu num_joysticks; #if defined (WIN32) bool using_windib; #endif @@ -1177,8 +1178,19 @@ static Bit8u raltstate = SDL_KEYUP; void GFX_Events() { SDL_Event event; +#if defined (REDUCE_JOYSTICK_POLLING) + if (sdl.num_joysticks>0) { + static int poll_delay=0; + int time=SDL_GetTicks(); + if (time-poll_delay>20) { + poll_delay=time; + SDL_JoystickUpdate(); + MAPPER_UpdateJoysticks(); + } + } +#endif while (SDL_PollEvent(&event)) { - switch (event.type) { + switch (event.type) { case SDL_ACTIVEEVENT: if (event.active.state & SDL_APPINPUTFOCUS) { if (event.active.gain) { @@ -1277,7 +1289,7 @@ void GFX_Events() { void MAPPER_CheckEvent(SDL_Event * event); MAPPER_CheckEvent(&event); } - } + } } /* static variable to show wether there is not a valid stdout. @@ -1372,6 +1384,7 @@ int main(int argc, char* argv[]) { if (strcmp(sdl_drv_name,"windib")==0) LOG_MSG("SDL_Init: Starting up with SDL windib video driver.\n Try to update your video card and directx drivers!"); } #endif + sdl.num_joysticks=SDL_NumJoysticks(); Section_prop * sdl_sec=control->AddSection_prop("sdl",&GUI_StartUp); sdl_sec->AddInitFunction(&MAPPER_StartUp); sdl_sec->Add_bool("fullscreen",false); From 6215071ebc9a63c4e8982462b2888bad52a46c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 24 Jul 2006 19:06:55 +0000 Subject: [PATCH 2592/4131] change callback code; get rid of several calls to DOSBOX_RunMachine() Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2677 --- include/callback.h | 23 ++- src/cpu/callback.cpp | 352 ++++++++++++++++++++++++++++--------- src/dos/dos.cpp | 32 ++-- src/ints/bios.cpp | 178 ++++++++++--------- src/ints/bios_keyboard.cpp | 136 ++++++-------- src/ints/ems.cpp | 18 +- src/ints/mouse.cpp | 71 +++++--- src/ints/xms.cpp | 45 ++--- 8 files changed, 527 insertions(+), 328 deletions(-) diff --git a/include/callback.h b/include/callback.h index dab0609d..1056e620 100644 --- a/include/callback.h +++ b/include/callback.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.h,v 1.17 2006-04-22 15:25:44 c2woody Exp $ */ +/* $Id: callback.h,v 1.18 2006-07-24 19:06:55 c2woody Exp $ */ #ifndef DOSBOX_CALLBACK_H #define DOSBOX_CALLBACK_H @@ -28,22 +28,29 @@ typedef Bitu (*CallBack_Handler)(void); extern CallBack_Handler CallBack_Handlers[]; -enum { CB_RETN,CB_RETF,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1,CB_HOOKABLE }; +enum { CB_RETN,CB_RETF,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1, + CB_IRQ0,CB_IRQ1,CB_IRQ9,CB_IRQ12,CB_IRQ12_RET,CB_IRQ6_PCJR, + CB_INT29,CB_INT16,CB_HOOKABLE,CB_TDE_IRET,CB_IPXESR,CB_IPXESR_RET }; -#define CB_MAX 144 +#define CB_MAX 128 +#define CB_SIZE 32 #define CB_SEG 0xF100 -#define CB_BASE (CB_SEG << 4) enum { CBRET_NONE=0,CBRET_STOP=1 }; extern Bit8u lastint; + INLINE RealPt CALLBACK_RealPointer(Bitu callback) { - return RealMake(CB_SEG,callback << 4); + return RealMake(CB_SEG,callback*CB_SIZE); } INLINE PhysPt CALLBACK_PhysPointer(Bitu callback) { - return PhysMake(CB_SEG,callback << 4); + return PhysMake(CB_SEG,callback*CB_SIZE); +} + +INLINE PhysPt CALLBACK_GetBase(void) { + return CB_SEG << 4; } Bitu CALLBACK_Allocate(); @@ -54,7 +61,7 @@ void CALLBACK_Idle(void); void CALLBACK_RunRealInt(Bit8u intnum); void CALLBACK_RunRealFar(Bit16u seg,Bit16u off); -bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* description=0); +bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* descr); Bitu CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,PhysPt addr,const char* descr); const char* CALLBACK_GetDescription(Bitu callback); @@ -85,7 +92,7 @@ public: //Only allocate a callback number void Allocate(CallBack_Handler handler,const char* description=0); Bit16u Get_callback(){return m_callback;} - RealPt Get_RealPointer(){ return RealMake(CB_SEG,m_callback << 4);} + RealPt Get_RealPointer(){ return CALLBACK_RealPointer(m_callback);} void Set_RealVec(Bit8u vec); }; #endif diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 45a56f32..fe4cfde4 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.33 2006-06-25 18:49:32 c2woody Exp $ */ +/* $Id: callback.cpp,v 1.34 2006-07-24 19:06:55 c2woody Exp $ */ #include #include @@ -26,7 +26,7 @@ #include "mem.h" #include "cpu.h" -/* CallBack are located at 0xC800:0 +/* CallBack are located at 0xF100:0 (see CB_SEG in callback.h) And they are 16 bytes each and you can define them to behave in certain ways like a far return or and IRET */ @@ -65,7 +65,7 @@ void CALLBACK_Idle(void) { Bit16u oldcs=SegValue(cs); Bit32u oldeip=reg_eip; SegSet16(cs,CB_SEG); - reg_eip=call_idle<<4; + reg_eip=call_idle*CB_SIZE; DOSBOX_RunMachine(); reg_eip=oldeip; SegSet16(cs,oldcs); @@ -87,7 +87,7 @@ static Bitu stop_handler(void) { void CALLBACK_RunRealFar(Bit16u seg,Bit16u off) { reg_sp-=4; - mem_writew(SegPhys(ss)+reg_sp,call_stop<<4); + mem_writew(SegPhys(ss)+reg_sp,call_stop*CB_SIZE); mem_writew(SegPhys(ss)+reg_sp+2,CB_SEG); Bit32u oldeip=reg_eip; Bit16u oldcs=SegValue(cs); @@ -101,7 +101,7 @@ void CALLBACK_RunRealFar(Bit16u seg,Bit16u off) { void CALLBACK_RunRealInt(Bit8u intnum) { Bit32u oldeip=reg_eip; Bit16u oldcs=SegValue(cs); - reg_eip=(CB_MAX*16)+(intnum*6); + reg_eip=(CB_MAX*CB_SIZE)+(intnum*6); SegSet16(cs,CB_SEG); DOSBOX_RunMachine(); reg_eip=oldeip; @@ -133,65 +133,254 @@ const char* CALLBACK_GetDescription(Bitu nr) { return CallBack_Description[nr]; }; -Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress) { +Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_cb=true) { if (callback>=CB_MAX) return 0; switch (type) { case CB_RETN: - phys_writeb(physAddress+0,(Bit8u)0xFE); //GRP 4 - phys_writeb(physAddress+1,(Bit8u)0x38); //Extra Callback instruction - phys_writew(physAddress+2, callback); //The immediate word - phys_writeb(physAddress+4,(Bit8u)0xC3); //A RETN Instruction - return 5; + 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: - phys_writeb(physAddress+0,(Bit8u)0xFE); //GRP 4 - phys_writeb(physAddress+1,(Bit8u)0x38); //Extra Callback instruction - phys_writew(physAddress+2, callback); //The immediate word - phys_writeb(physAddress+4,(Bit8u)0xCB); //A RETF Instruction - return 5; + 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)0xCB); //A RETF Instruction + return (use_cb?5:1); case CB_IRET: - phys_writeb(physAddress+0,(Bit8u)0xFE); //GRP 4 - phys_writeb(physAddress+1,(Bit8u)0x38); //Extra Callback instruction - phys_writew(physAddress+2,callback); //The immediate word - phys_writeb(physAddress+4,(Bit8u)0xCF); //An IRET Instruction - return 5; + 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?5:1); case CB_IRETD: - phys_writeb(physAddress+0,(Bit8u)0xFE); //GRP 4 - phys_writeb(physAddress+1,(Bit8u)0x38); //Extra Callback instruction - phys_writew(physAddress+2,callback); //The immediate word - phys_writeb(physAddress+4,(Bit8u)0x66); //An IRETD Instruction - phys_writeb(physAddress+5,(Bit8u)0xCF); - return 6; + 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+0,(Bit8u)0xFB); //STI - phys_writeb(physAddress+1,(Bit8u)0xFE); //GRP 4 - phys_writeb(physAddress+2,(Bit8u)0x38); //Extra Callback instruction - phys_writew(physAddress+3, callback); //The immediate word - phys_writeb(physAddress+5,(Bit8u)0xCF); //An IRET Instruction - return 6; + 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: - phys_writeb(physAddress+0,(Bit8u)0xFE); //GRP 4 - phys_writeb(physAddress+1,(Bit8u)0x38); //Extra Callback instruction - phys_writew(physAddress+2,callback); //The immediate word - phys_writeb(physAddress+4,(Bit8u)0x50); // push ax - phys_writeb(physAddress+5,(Bit8u)0xb0); // mov al, 0x20 - phys_writeb(physAddress+6,(Bit8u)0x20); - phys_writeb(physAddress+7,(Bit8u)0xe6); // out 0x20, al - phys_writeb(physAddress+8,(Bit8u)0x20); - phys_writeb(physAddress+9,(Bit8u)0x58); // pop ax - phys_writeb(physAddress+10,(Bit8u)0xcf);//An IRET Instruction - return 11; + 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)0xfb); // sti + 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 + return 0x09; + 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_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,(Bit8u)0x0eb4); // mov ah, 0x0e + phys_writew(physAddress+0x03,(Bit8u)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+0,(Bit8u)0xEB); //jump near - phys_writeb(physAddress+1,(Bit8u)0x03); //offset - phys_writeb(physAddress+2,(Bit8u)0x90); //NOP - phys_writeb(physAddress+3,(Bit8u)0x90); //NOP - phys_writeb(physAddress+4,(Bit8u)0x90); //NOP - phys_writeb(physAddress+5,(Bit8u)0xFE); //GRP 4 - phys_writeb(physAddress+6,(Bit8u)0x38); //Extra Callback instruction - phys_writew(physAddress+7,callback); //The immediate word - phys_writeb(physAddress+9,(Bit8u)0xCB); //A RETF Instruction - return 10; + 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; */ default: E_Exit("CALLBACK:Setup:Illegal type %d",type); } @@ -200,7 +389,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress) { bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* descr) { if (callback>=CB_MAX) return false; - CALLBACK_SetupExtra(callback,type,CB_BASE+(callback<<4)+0); + CALLBACK_SetupExtra(callback,type,CALLBACK_PhysPointer(callback)+0,(handler!=NULL)); CallBack_Handlers[callback]=handler; CALLBACK_SetDescription(callback,descr); return true; @@ -208,7 +397,7 @@ bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* Bitu CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,PhysPt addr,const char* descr) { if (callback>=CB_MAX) return 0; - Bitu csize=CALLBACK_SetupExtra(callback,type,addr); + Bitu csize=CALLBACK_SetupExtra(callback,type,addr,(handler!=NULL)); if (csize>0) { CallBack_Handlers[callback]=handler; CALLBACK_SetDescription(callback,descr); @@ -218,7 +407,7 @@ Bitu CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,PhysPt addr void CALLBACK_RemoveSetup(Bitu callback) { for (Bitu i = 0;i < 16;i++) { - phys_writeb(CB_BASE+(callback<<4)+i ,(Bit8u) 0x00); + phys_writeb(CALLBACK_PhysPointer(callback)+i ,(Bit8u) 0x00); } } @@ -259,6 +448,7 @@ void CALLBACK_HandlerObject::Install(CallBack_Handler handler,Bitu type,PhysPt a 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; @@ -282,21 +472,23 @@ void CALLBACK_Init(Section* sec) { for (i=0;i #include @@ -981,21 +981,19 @@ static Bitu DOS_21Handler(void) { }; - static Bitu DOS_20Handler(void) { - reg_ax=0x4c00; DOS_21Handler(); return CBRET_NONE; } -static Bitu DOS_27Handler(void) -{ +static Bitu DOS_27Handler(void) { // Terminate & stay resident Bit16u para = (reg_dx/16)+((reg_dx % 16)>0); if (DOS_ResizeMemory(dos.psp(),¶)) DOS_Terminate(true); return CBRET_NONE; } + static Bitu DOS_25Handler(void) { if(Drives[reg_al]==0){ reg_ax=0x8002; @@ -1020,20 +1018,6 @@ static Bitu DOS_26Handler(void) { } return CBRET_NONE; } -static Bitu DOS_28Handler(void) { - return CBRET_NONE; -} - -static Bitu DOS_29Handler(void) { - static bool int29warn=false; - if(!int29warn) { - LOG(LOG_DOSMISC,LOG_WARN)("Int 29 called. Redirecting to int 10:0x0e"); - int29warn=true; - } - reg_ah=0x0e; - CALLBACK_RunRealInt(0x10); - return CBRET_NONE; -} class DOS:public Module_base{ @@ -1056,11 +1040,17 @@ public: callback[4].Install(DOS_27Handler,CB_IRET,"DOS Int 27"); callback[4].Set_RealVec(0x27); - callback[5].Install(DOS_28Handler,CB_IRET,"DOS Int 28"); + callback[5].Install(NULL,CB_IRET,"DOS Int 28"); callback[5].Set_RealVec(0x28); - callback[6].Install(DOS_29Handler,CB_IRET,"CON Output Int 29"); + callback[6].Install(NULL,CB_INT29,"CON Output Int 29"); callback[6].Set_RealVec(0x29); + // pseudocode for CB_INT29: + // push ax + // mov ah, 0x0e + // int 0x10 + // pop ax + // iret DOS_SetupFiles(); /* Setup system File tables */ DOS_SetupDevices(); /* Setup dos devices */ diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 3efd14b2..6f6fa121 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.61 2006-05-28 09:40:42 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.62 2006-07-24 19:06:55 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -61,14 +61,8 @@ static Bitu INT70_Handler(void) { IO_Write(0x20,0x20); return 0; } -// Irq 9 calls irq 2 -static Bitu INT71_Handler() { - IO_Write(0xa0,0x61); - CALLBACK_RunRealInt(0xa); - return CBRET_NONE; -} -CALLBACK_HandlerObject* tandy_DAC_callback; +CALLBACK_HandlerObject* tandy_DAC_callback[2]; static struct { Bit16u port; Bit8u irq; @@ -143,9 +137,9 @@ static void Tandy_SetupTransfer(PhysPt bufpt,bool isplayback) { /* revector IRQ-handler if necessary */ RealPt current_irq=RealGetVec(tandy_sb.irq+8); - if (current_irq!=tandy_DAC_callback->Get_RealPointer()) { + if (current_irq!=tandy_DAC_callback[0]->Get_RealPointer()) { real_writed(0x40,0xd6,current_irq); - RealSetVec(tandy_sb.irq+8,tandy_DAC_callback->Get_RealPointer()); + RealSetVec(tandy_sb.irq+8,tandy_DAC_callback[0]->Get_RealPointer()); } IO_Write(tandy_sb.port+0xc,0xd0); /* stop DMA transfer */ @@ -222,12 +216,8 @@ static Bitu IRQ_TandyDAC(void) { IO_Read(tandy_sb.port+0xe); /* issue BIOS tandy sound device busy callout */ - Bit16u oldax=reg_ax; - reg_ax=0x91fb; - CALLBACK_RunRealInt(0x15); - reg_ax = oldax; - - IO_Write(0x20,0x20); + SegSet16(cs, RealSeg(tandy_DAC_callback[1]->Get_RealPointer())); + reg_ip = RealOff(tandy_DAC_callback[1]->Get_RealPointer()); } return CBRET_NONE; } @@ -338,16 +328,6 @@ static Bitu INT8_Handler(void) { if (val) mem_writeb(BIOS_DISK_MOTOR_TIMEOUT,val-1); /* and running drive */ mem_writeb(BIOS_DRIVE_RUNNING,mem_readb(BIOS_DRIVE_RUNNING) & 0xF0); - // Save ds,dx,ax - Bit16u oldds = SegValue(ds); - Bit16u olddx = reg_dx; - Bit16u oldax = reg_ax; - // run int 1c - CALLBACK_RunRealInt(0x1c); - // restore old values - SegSet16(ds,oldds); - reg_dx = olddx; - reg_ax = oldax; return CBRET_NONE; }; @@ -824,14 +804,24 @@ public: BIOS(Section* configuration):Module_base(configuration){ /* tandy DAC can be requested in tandy_sound.cpp by initializing this field */ bool use_tandyDAC=(real_readb(0x40,0xd4)==0xff); + /* Clear the Bios Data Area (0x400-0x5ff, 0x600- is accounted to DOS) */ for (Bit16u i=0;i<0x200;i++) real_writeb(0x40,i,0); + /* Setup all the interrupt handlers the bios controls */ /* INT 8 Clock IRQ Handler */ - //TODO Maybe give this a special callback that will also call int 8 instead of starting - //a new system - callback[0].Install(INT8_Handler,CB_IRET_EOI_PIC1,"Int 8 Clock"); + callback[0].Install(INT8_Handler,CB_IRQ0,"Int 8 Clock"); callback[0].Set_RealVec(0x8); + // pseudocode for CB_IRQ0: + // callback INT8_Handler + // push ax,dx,ds + // int 0x1c + // cli + // pop ds,dx + // mov al, 0x20 + // out 0x20, al + // pop ax + // iret mem_writed(BIOS_TIMER,0); //Calculate the correct time @@ -880,15 +870,20 @@ public: callback[8].Install(&INT70_Handler,CB_IRET,"Int 70 RTC"); callback[8].Set_RealVec(0x70); - /* Irq 9 routed to irq 2 (which is an iret at f000:ff53) */ - callback[9].Install(&INT71_Handler,CB_IRET,"irq 9 bios"); + /* Irq 9 rerouted to irq 2 */ + callback[9].Install(NULL,CB_IRQ9,"irq 9 bios"); callback[9].Set_RealVec(0x71); + /* Irq 2 */ + RealPt irq2pt=RealMake(0xf000,0xff55); /* Ghost busters 2 mt32 mode */ + Bitu call_irq2=CALLBACK_Allocate(); + CALLBACK_Setup(call_irq2,NULL,CB_IRET_EOI_PIC1,Real2Phys(irq2pt),"irq 2 bios"); + RealSetVec(0x0a,irq2pt); + /* Some hardcoded vectors */ phys_writeb(0xfff53,0xcf); /* bios default interrupt vector location */ phys_writeb(0xfe987,0xea); /* original IRQ1 location (Defender booter) */ phys_writed(0xfe988,RealGetVec(0x09)); - RealSetVec(0xA,0xf000ff53); /* Ghost busters 2 mt32 mode */ if (machine==MCH_TANDY) phys_writeb(0xffffe,0xff) ; /* Tandy model */ else if (machine==MCH_PCJR) phys_writeb(0xffffe,0xfd); /* PCJr model */ @@ -902,8 +897,20 @@ public: real_writeb(0x40,0xd4,0xff); /* tandy DAC init value */ real_writed(0x40,0xd6,0x00000000); /* install the DAC callback handler */ - tandy_DAC_callback=new CALLBACK_HandlerObject(); - tandy_DAC_callback->Install(&IRQ_TandyDAC,CB_IRET,"Tandy DAC IRQ"); + tandy_DAC_callback[0]=new CALLBACK_HandlerObject(); + tandy_DAC_callback[1]=new CALLBACK_HandlerObject(); + tandy_DAC_callback[0]->Install(&IRQ_TandyDAC,CB_IRET,"Tandy DAC IRQ"); + tandy_DAC_callback[1]->Install(NULL,CB_TDE_IRET,"Tandy DAC end transfer"); + // pseudocode for CB_TDE_IRET: + // push ax + // mov ax, 0x91fb + // int 15 + // cli + // mov al, 0x20 + // out 0x20, al + // pop ax + // iret + RealPt current_irq=RealGetVec(tandy_sb.irq+8); real_writed(0x40,0xd6,current_irq); for (Bitu i=0; i<0x10; i++) phys_writeb(PhysMake(0xf000,0xa084+i),0x80); @@ -912,60 +919,59 @@ public: /* Setup some stuff in 0x40 bios segment */ /* detect parallel ports */ - Bit8u DEFAULTPORTTIMEOUT = 10; // 10 whatevers - Bitu ppindex=0; // number of lpt ports - if ((IO_Read(0x378)!=0xff)|(IO_Read(0x379)!=0xff)) { - // this is our LPT1 - mem_writew(BIOS_ADDRESS_LPT1,0x378); - mem_writeb(BIOS_LPT1_TIMEOUT,DEFAULTPORTTIMEOUT); - ppindex++; - if((IO_Read(0x278)!=0xff)|(IO_Read(0x279)!=0xff)) { - // this is our LPT2 - mem_writew(BIOS_ADDRESS_LPT2,0x278); - mem_writeb(BIOS_LPT2_TIMEOUT,DEFAULTPORTTIMEOUT); + Bit8u DEFAULTPORTTIMEOUT = 10; // 10 whatevers + Bitu ppindex=0; // number of lpt ports + if ((IO_Read(0x378)!=0xff)|(IO_Read(0x379)!=0xff)) { + // this is our LPT1 + mem_writew(BIOS_ADDRESS_LPT1,0x378); + mem_writeb(BIOS_LPT1_TIMEOUT,DEFAULTPORTTIMEOUT); ppindex++; - if((IO_Read(0x3bc)!=0xff)|(IO_Read(0x3be)!=0xff)) { - // this is our LPT3 - mem_writew(BIOS_ADDRESS_LPT3,0x3bc); - mem_writeb(BIOS_LPT3_TIMEOUT,DEFAULTPORTTIMEOUT); + if((IO_Read(0x278)!=0xff)|(IO_Read(0x279)!=0xff)) { + // this is our LPT2 + mem_writew(BIOS_ADDRESS_LPT2,0x278); + mem_writeb(BIOS_LPT2_TIMEOUT,DEFAULTPORTTIMEOUT); + ppindex++; + if((IO_Read(0x3bc)!=0xff)|(IO_Read(0x3be)!=0xff)) { + // this is our LPT3 + mem_writew(BIOS_ADDRESS_LPT3,0x3bc); + mem_writeb(BIOS_LPT3_TIMEOUT,DEFAULTPORTTIMEOUT); + ppindex++; + } + } else if((IO_Read(0x3bc)!=0xff)|(IO_Read(0x3be)!=0xff)) { + // this is our LPT2 + mem_writew(BIOS_ADDRESS_LPT2,0x3bc); + mem_writeb(BIOS_LPT2_TIMEOUT,DEFAULTPORTTIMEOUT); ppindex++; } } else if((IO_Read(0x3bc)!=0xff)|(IO_Read(0x3be)!=0xff)) { - // this is our LPT2 - mem_writew(BIOS_ADDRESS_LPT2,0x3bc); - mem_writeb(BIOS_LPT2_TIMEOUT,DEFAULTPORTTIMEOUT); + // this is our LPT1 + mem_writew(BIOS_ADDRESS_LPT1,0x3bc); + mem_writeb(BIOS_LPT1_TIMEOUT,DEFAULTPORTTIMEOUT); + ppindex++; + if((IO_Read(0x278)!=0xff)|(IO_Read(0x279)!=0xff)) { + // this is our LPT2 + mem_writew(BIOS_ADDRESS_LPT2,0x278); + mem_writeb(BIOS_LPT2_TIMEOUT,DEFAULTPORTTIMEOUT); + ppindex++; + } + } else if((IO_Read(0x278)!=0xff)|(IO_Read(0x279)!=0xff)) { + // this is our LPT1 + mem_writew(BIOS_ADDRESS_LPT1,0x278); + mem_writeb(BIOS_LPT1_TIMEOUT,DEFAULTPORTTIMEOUT); ppindex++; } - } else if((IO_Read(0x3bc)!=0xff)|(IO_Read(0x3be)!=0xff)) { - // this is our LPT1 - mem_writew(BIOS_ADDRESS_LPT1,0x3bc); - mem_writeb(BIOS_LPT1_TIMEOUT,DEFAULTPORTTIMEOUT); - ppindex++; - if((IO_Read(0x278)!=0xff)|(IO_Read(0x279)!=0xff)) { - // this is our LPT2 - mem_writew(BIOS_ADDRESS_LPT2,0x278); - mem_writeb(BIOS_LPT2_TIMEOUT,DEFAULTPORTTIMEOUT); - ppindex++; - } - } - else if((IO_Read(0x278)!=0xff)|(IO_Read(0x279)!=0xff)) { - // this is our LPT1 - mem_writew(BIOS_ADDRESS_LPT1,0x278); - mem_writeb(BIOS_LPT1_TIMEOUT,DEFAULTPORTTIMEOUT); - ppindex++; - } - /* Setup equipment list */ - // look http://www.bioscentral.com/misc/bda.htm - - //Bitu config=0x4400; //1 Floppy, 2 serial and 1 parrallel - Bitu config = 0x0; - - // set number of parallel ports - // if(ppindex == 0) config |= 0x8000; // looks like 0 ports are not specified - //else if(ppindex == 1) config |= 0x0000; - if(ppindex == 2) config |= 0x4000; - else config |= 0xc000; // 3 ports + /* Setup equipment list */ + // look http://www.bioscentral.com/misc/bda.htm + + //Bitu config=0x4400; //1 Floppy, 2 serial and 1 parrallel + Bitu config = 0x0; + + // set number of parallel ports + // if(ppindex == 0) config |= 0x8000; // looks like 0 ports are not specified + //else if(ppindex == 1) config |= 0x0000; + if(ppindex == 2) config |= 0x4000; + else config |= 0xc000; // 3 ports #if (C_FPU) //FPU config|=0x2; @@ -1007,15 +1013,17 @@ public: IO_Write(tandy_sb.port+0xc,0xd0); } real_writeb(0x40,0xd4,0x00); - if (tandy_DAC_callback) { + if (tandy_DAC_callback[0]) { Bit32u orig_vector=real_readd(0x40,0xd6); - if (orig_vector==tandy_DAC_callback->Get_RealPointer()) { + if (orig_vector==tandy_DAC_callback[0]->Get_RealPointer()) { /* set IRQ vector to old value */ RealSetVec(tandy_sb.irq+8,real_readd(0x40,0xd6)); real_writed(0x40,0xd6,0x00000000); } - delete tandy_DAC_callback; - tandy_DAC_callback=NULL; + delete tandy_DAC_callback[0]; + delete tandy_DAC_callback[1]; + tandy_DAC_callback[0]=NULL; + tandy_DAC_callback[1]=NULL; } } }; diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 0a524e95..fae8a6e6 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -223,32 +223,14 @@ static bool check_key(Bit16u &code) { */ - +/* the scancode is in reg_al */ static Bitu IRQ1_Handler(void) { -/* handling of the locks key is difficult as sdl only gives states for - * numlock capslock. +/* handling of the locks key is difficult as sdl only gives + * states for numlock capslock. */ -/* in reg_al is the scancode */ - - /* Read the code */ - Bitu scancode; //,ascii,mod; -#if 1 - scancode=reg_al; //IO_Read(0x60); moved out of handler - - -#else - /* Old code capable of unicode keys. Dropped Readkey disabled in keyboard.cpp */ - KEYBOARD_ReadKey(scancode,ascii,mod); - LOG_MSG("Got code %X ascii %C mod %X",scancode,ascii,mod); -#endif - Bit16u old_ax=reg_ax; - reg_flags|=1; - reg_ah=0x4f;reg_al=scancode; - CALLBACK_RunRealInt(0x15); - reg_ax=old_ax;Bit8u flags1,flags2,flags3,leds; - if (!(reg_flags&1)) goto irq1_return; - + Bitu scancode=reg_al; /* Read the code */ + Bit8u flags1,flags2,flags3,leds; flags1=mem_readb(BIOS_KEYBOARD_FLAGS1); flags2=mem_readb(BIOS_KEYBOARD_FLAGS2); flags3=mem_readb(BIOS_KEYBOARD_FLAGS3); @@ -334,7 +316,7 @@ static Bitu IRQ1_Handler(void) { mem_writeb(BIOS_KEYBOARD_FLAGS2,flags2|8); IO_Write(0x20,0x20); while (mem_readb(BIOS_KEYBOARD_FLAGS2)&8) CALLBACK_Idle(); // pause loop - reg_ip+=4; // skip out 20,20 + reg_ip+=5; // skip out 20,20 return CBRET_NONE; } } else { @@ -460,7 +442,6 @@ irq1_end: mem_writeb(BIOS_KEYBOARD_FLAGS2,flags2); mem_writeb(BIOS_KEYBOARD_FLAGS3,flags3); mem_writeb(BIOS_KEYBOARD_LEDS,leds); -irq1_return: /* IO_Write(0x20,0x20); moved out of handler to be virtualizable */ #if 0 /* Signal the keyboard for next code */ @@ -472,22 +453,6 @@ irq1_return: return CBRET_NONE; } -static Bitu IRQ6_Handler(void) { - Bit8u scancode=IO_Read(0x60); - /* skip extended keys, all of them should map quite nicely - onto corresponding non-extended keys */ - if (scancode!=0xe0) { - Bit16u old_ax=reg_ax; - reg_al=scancode; - /* call the real keyboard IRQ now, with the scancode in AL */ - CALLBACK_RunRealInt(0x09); - reg_ax=old_ax; - } - - IO_Write(0x20,0x20); - return CBRET_NONE; -} - /* check whether key combination is enhanced or not, translate key if necessary */ @@ -519,30 +484,25 @@ static Bitu INT16_Handler(void) { Bit16u temp=0; switch (reg_ah) { case 0x00: /* GET KEYSTROKE */ - for (;;) { - if (get_key(temp)) { - if (!IsEnhancedKey(temp)) { - /* normal key, exit scanning for keys */ - break; - } - } - CALLBACK_Idle(); + if ((get_key(temp)) && (!IsEnhancedKey(temp))) { + /* normal key found, return translated key in ax */ + reg_ax=temp; + } else { + /* enter small idle loop to allow for irqs to happen */ + reg_ip+=1; } - /* normal key found, return translated key in ax */ - reg_ax=temp; break; case 0x10: /* GET KEYSTROKE (enhanced keyboards only) */ - for (;;) { - if (get_key(temp)) { - if (((temp&0xff)==0xf0) && (temp>>8)) { - /* special enhanced key, clear low part before returning key */ - temp&=0xff00; - } - break; + if (get_key(temp)) { + if (((temp&0xff)==0xf0) && (temp>>8)) { + /* special enhanced key, clear low part before returning key */ + temp&=0xff00; } - CALLBACK_Idle(); + reg_ax=temp; + } else { + /* enter small idle loop to allow for irqs to happen */ + reg_ip+=1; } - reg_ax=temp; break; case 0x01: /* CHECK FOR KEYSTROKE */ for (;;) { @@ -561,7 +521,7 @@ static Bitu INT16_Handler(void) { CALLBACK_SZF(true); break; } - CALLBACK_Idle(); +// CALLBACK_Idle(); } break; case 0x11: /* CHECK FOR KEYSTROKE (enhanced keyboards only) */ @@ -630,37 +590,51 @@ static void InitBiosSegment(void) { mem_writeb(BIOS_KEYBOARD_FLAGS3,16); /* Enhanced keyboard installed */ mem_writeb(BIOS_KEYBOARD_TOKEN,0); mem_writeb(BIOS_KEYBOARD_LEDS,leds); - } void BIOS_SetupKeyboard(void) { /* Init the variables */ InitBiosSegment(); - /* Allocate a callback for int 0x16 and for standard IRQ 1 handler */ + + /* Allocate/setup a callback for int 0x16 and for standard IRQ 1 handler */ call_int16=CALLBACK_Allocate(); - call_irq1=CALLBACK_Allocate(); - CALLBACK_Setup(call_int16,&INT16_Handler,CB_IRET_STI,"keyboard"); + CALLBACK_Setup(call_int16,&INT16_Handler,CB_INT16,"keyboard"); RealSetVec(0x16,CALLBACK_RealPointer(call_int16)); - CALLBACK_Setup(call_irq1,&IRQ1_Handler,CB_IRET,"keyboard irq"); + + call_irq1=CALLBACK_Allocate(); + CALLBACK_Setup(call_irq1,&IRQ1_Handler,CB_IRQ1,"keyboard irq"); RealSetVec(0x9,CALLBACK_RealPointer(call_irq1)); + // pseudocode for CB_IRQ1: + // push ax + // in al, 0x60 + // mov ah, 0x4f + // stc + // int 15 + // jc skip + // callback IRQ1_Handler + // label skip: + // cli + // mov al, 0x20 + // out 0x20, al + // pop ax + // iret + if (machine==MCH_PCJR) { call_irq6=CALLBACK_Allocate(); - CALLBACK_Setup(call_irq6,&IRQ6_Handler,CB_IRET,"PCJr kb irq"); + CALLBACK_Setup(call_irq6,NULL,CB_IRQ6_PCJR,"PCJr kb irq"); RealSetVec(0x0e,CALLBACK_RealPointer(call_irq6)); + // pseudocode for CB_IRQ6_PCJR: + // push ax + // in al, 0x60 + // cmp al, 0xe0 + // je skip + // int 0x09 + // label skip: + // cli + // mov al, 0x20 + // out 0x20, al + // pop ax + // iret } - - /* bring the all port operations outside the callback */ - phys_writeb(CB_BASE+(call_irq1<<4)+0x00,(Bit8u)0x50); // push ax - phys_writeb(CB_BASE+(call_irq1<<4)+0x01,(Bit8u)0xe4); // in al, 0x60 - phys_writeb(CB_BASE+(call_irq1<<4)+0x02,(Bit8u)0x60); - phys_writeb(CB_BASE+(call_irq1<<4)+0x03,(Bit8u)0xFE); //GRP 4 - phys_writeb(CB_BASE+(call_irq1<<4)+0x04,(Bit8u)0x38); //Extra Callback instruction - phys_writew(CB_BASE+(call_irq1<<4)+0x05,call_irq1); //The immediate word - phys_writeb(CB_BASE+(call_irq1<<4)+0x07,(Bit8u)0xb0); // mov al, 0x20 - phys_writeb(CB_BASE+(call_irq1<<4)+0x08,(Bit8u)0x20); - phys_writeb(CB_BASE+(call_irq1<<4)+0x09,(Bit8u)0xe6); // out 0x20, al - phys_writeb(CB_BASE+(call_irq1<<4)+0x0a,(Bit8u)0x20); - phys_writeb(CB_BASE+(call_irq1<<4)+0x0b,(Bit8u)0x58); // pop ax - phys_writeb(CB_BASE+(call_irq1<<4)+0x0c,(Bit8u)0xcf); // iret } diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 1493b3d6..5cb157aa 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.51 2006-04-22 15:25:45 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.52 2006-07-24 19:06:55 c2woody Exp $ */ #include #include @@ -721,8 +721,8 @@ static Bitu INT67_Handler(void) { reg_di+=0x400; // advance pointer by 0x100*4 /* Set up three descriptor table entries */ - Bit32u cbseg_low=(CB_BASE&0xffff)<<16; - Bit32u cbseg_high=(CB_BASE&0x1f0000)>>16; + Bit32u cbseg_low=(CALLBACK_GetBase()&0xffff)<<16; + Bit32u cbseg_high=(CALLBACK_GetBase()&0x1f0000)>>16; /* Descriptor 1 (code segment, callback segment) */ real_writed(SegValue(ds),reg_si+0x00,0x0000ffff|cbseg_low); real_writed(SegValue(ds),reg_si+0x04,0x00009a00|cbseg_high); @@ -1161,21 +1161,23 @@ public: int67.Install(&INT67_Handler,CB_IRET,"Int 67 ems"); Bit16u call_int67=int67.Get_callback(); - /* Register the ems device */ + /* Register the ems device */ //TODO MAYBE put it in the class. DOS_Device * newdev = new device_EMM(); DOS_AddDevice(newdev); - /* Add a little hack so it appears that there is an actual ems device installed */ + /* Add a little hack so it appears that there is an actual ems device installed */ char * emsname="EMMXXXX0"; if(!emsnameseg) emsnameseg=DOS_GetMemory(2); //We have 32 bytes MEM_BlockWrite(PhysMake(emsnameseg,0xa),emsname,strlen(emsname)+1); - /* Copy the callback piece into the beginning, and set the interrupt vector to it*/ + + /* Copy the callback piece into the beginning, and set the interrupt vector to it*/ char buf[16]; - MEM_BlockRead(PhysMake(CB_SEG,call_int67<<4),buf,0xa); + MEM_BlockRead(CALLBACK_PhysPointer(call_int67),buf,0xa); MEM_BlockWrite(PhysMake(emsnameseg,0),buf,0xa); RealSetVec(0x67,RealMake(emsnameseg,0),old67_pointer); - /* Clear handle and page tables */ + + /* Clear handle and page tables */ Bitu i; for (i=0;i #include @@ -34,7 +34,7 @@ #include "bios.h" -static Bitu call_int33,call_int74; +static Bitu call_int33,call_int74,int74_ret_callback; static Bit16u ps2cbseg,ps2cbofs; static bool useps2callback,ps2callbackinit; static Bit16u call_ps2; @@ -870,35 +870,32 @@ static Bitu INT74_Handler(void) { mouse.events--; /* Check for an active Interrupt Handler that will get called */ if (mouse.sub_mask & mouse.event_queue[mouse.events].type) { - /* Save lot's of registers */ - Bit32u oldeax,oldebx,oldecx,oldedx,oldesi,oldedi,oldebp,oldesp; - Bit16u oldds,oldes,oldss; - oldeax=reg_eax;oldebx=reg_ebx;oldecx=reg_ecx;oldedx=reg_edx; - oldesi=reg_esi;oldedi=reg_edi;oldebp=reg_ebp;oldesp=reg_esp; - oldds=SegValue(ds); oldes=SegValue(es); oldss=SegValue(ss); // Save segments reg_ax=mouse.event_queue[mouse.events].type; reg_bx=mouse.event_queue[mouse.events].buttons; reg_cx=POS_X; reg_dx=POS_Y; reg_si=(Bit16s)(mouse.mickey_x*mouse.mickeysPerPixel_x); reg_di=(Bit16s)(mouse.mickey_y*mouse.mickeysPerPixel_y); - // Hmm... this look ok, but moonbase wont work with it - /*if (mouse.event_queue[mouse.events].type==MOUSE_MOVED) { - mouse.mickey_x=0; - mouse.mickey_y=0; - }*/ - CALLBACK_RunRealFar(mouse.sub_seg,mouse.sub_ofs); - reg_eax=oldeax;reg_ebx=oldebx;reg_ecx=oldecx;reg_edx=oldedx; - reg_esi=oldesi;reg_edi=oldedi;reg_ebp=oldebp;reg_esp=oldesp; - SegSet16(ds,oldds); SegSet16(es,oldes); SegSet16(ss,oldss); // Save segments - + CPU_Push16(RealSeg(CALLBACK_RealPointer(int74_ret_callback))); + CPU_Push16(RealOff(CALLBACK_RealPointer(int74_ret_callback))); + SegSet16(cs, mouse.sub_seg); + reg_ip = mouse.sub_ofs; + } else if (useps2callback) { + CPU_Push16(RealSeg(CALLBACK_RealPointer(int74_ret_callback))); + CPU_Push16(RealOff(CALLBACK_RealPointer(int74_ret_callback))); + DoPS2Callback(mouse.event_queue[mouse.events].buttons, POS_X, POS_Y); + } else { + SegSet16(cs, RealSeg(CALLBACK_RealPointer(int74_ret_callback))); + reg_ip = RealOff(CALLBACK_RealPointer(int74_ret_callback)); } - DoPS2Callback(mouse.event_queue[mouse.events].buttons, POS_X, POS_Y); - + } else { + SegSet16(cs, RealSeg(CALLBACK_RealPointer(int74_ret_callback))); + reg_ip = RealOff(CALLBACK_RealPointer(int74_ret_callback)); } - IO_Write(0xa0,0x20); - IO_Write(0x20,0x20); - /* Check for more Events if so reactivate IRQ */ + return CBRET_NONE; +} + +Bitu MOUSE_UserInt_CB_Handler(void) { if (mouse.events) { PIC_ActivateIRQ(MOUSE_IRQ); } @@ -911,18 +908,40 @@ void MOUSE_Init(Section* sec) { call_int33=CALLBACK_Allocate(); CALLBACK_Setup(call_int33,&INT33_Handler,CB_IRET,"Mouse"); // Wasteland needs low(seg(int33))!=0 and low(ofs(int33))!=0 - real_writed(0,0x33<<2,RealMake(CB_SEG+1,(call_int33<<4)-0x10)); + real_writed(0,0x33<<2,RealMake(CB_SEG+1,(call_int33*CB_SIZE)-0x10)); // Callback for ps2 irq call_int74=CALLBACK_Allocate(); - CALLBACK_Setup(call_int74,&INT74_Handler,CB_IRET,"int 74"); + CALLBACK_Setup(call_int74,&INT74_Handler,CB_IRQ12,"int 74"); + // pseudocode for CB_IRQ12: + // push ds + // push es + // pushad + // sti + // callback INT74_Handler + // doesn't return here, but rather to CB_IRQ12_RET + // (ps2 callback/user callback inbetween if requested) + + int74_ret_callback=CALLBACK_Allocate(); + CALLBACK_Setup(int74_ret_callback,&MOUSE_UserInt_CB_Handler,CB_IRQ12_RET,"int 74 ret"); + // pseudocode for CB_IRQ12_RET: + // callback MOUSE_UserInt_CB_Handler + // cli + // mov al, 0x20 + // out 0xa0, al + // out 0x20, al + // popad + // pop es + // pop ds + // iret + Bit8u hwvec=(MOUSE_IRQ>7)?(0x70+MOUSE_IRQ-8):(0x8+MOUSE_IRQ); RealSetVec(hwvec,CALLBACK_RealPointer(call_int74)); // Callback for ps2 user callback handling useps2callback = false; ps2callbackinit = false; call_ps2=CALLBACK_Allocate(); - CALLBACK_Setup(call_ps2,&PS2_Handler,CB_IRET,"ps2 bios callback"); + CALLBACK_Setup(call_ps2,&PS2_Handler,CB_RETF,"ps2 bios callback"); ps2_callback=CALLBACK_RealPointer(call_ps2); memset(&mouse,0,sizeof(mouse)); diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index e6b8b455..1dd25635 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.42 2006-05-07 20:00:05 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.43 2006-07-24 19:06:55 c2woody Exp $ */ #include #include @@ -64,6 +64,11 @@ #define XMS_OUT_OF_SPACE 0xa0 #define XMS_OUT_OF_HANDLES 0xa1 #define XMS_INVALID_HANDLE 0xa2 +#define XMS_INVALID_SOURCE_HANDLE 0xa3 +#define XMS_INVALID_SOURCE_OFFSET 0xa4 +#define XMS_INVALID_DEST_HANDLE 0xa5 +#define XMS_INVALID_DEST_OFFSET 0xa6 +#define XMS_INVALID_LENGTH 0xa7 #define XMS_BLOCK_NOT_LOCKED 0xaa #define XMS_BLOCK_LOCKED 0xab #define UMB_ONLY_SMALLER_BLOCK 0xb0 @@ -123,9 +128,7 @@ Bitu XMS_QueryFreeMemory(Bit16u& largestFree, Bit16u& totalFree) { return 0; }; -Bitu XMS_AllocateMemory(Bitu size, Bit16u& handle) -// size = kb -{ +Bitu XMS_AllocateMemory(Bitu size, Bit16u& handle) { // size = kb /* Find free handle */ Bit16u index=1; while (!xms_handles[index].free) { @@ -142,8 +145,7 @@ Bitu XMS_AllocateMemory(Bitu size, Bit16u& handle) return 0; }; -Bitu XMS_FreeMemory(Bitu handle) -{ +Bitu XMS_FreeMemory(Bitu handle) { if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; MEM_ReleasePages(xms_handles[handle].mem); xms_handles[handle].mem=-1; @@ -166,13 +168,13 @@ Bitu XMS_MoveMemory(PhysPt bpt) { PhysPt srcpt,destpt; if (src_handle) { if (InvalidHandle(src_handle)) { - return 0xa3; /* Src Handle invalid */ + return XMS_INVALID_SOURCE_HANDLE; } if (src.offset>=(xms_handles[src_handle].size*1024U)) { - return 0xa4; /* Src Offset invalid */ + return XMS_INVALID_SOURCE_OFFSET; } if (length>xms_handles[src_handle].size*1024U-src.offset) { - return 0xa7; /* Length invalid */ + return XMS_INVALID_LENGTH; } srcpt=(xms_handles[src_handle].mem*4096)+src.offset; } else { @@ -180,13 +182,13 @@ Bitu XMS_MoveMemory(PhysPt bpt) { } if (dest_handle) { if (InvalidHandle(dest_handle)) { - return 0xa5; /* Dest Handle invalid */ + return XMS_INVALID_DEST_HANDLE; } if (dest.offset>=(xms_handles[dest_handle].size*1024U)) { - return 0xa6; /* Dest Offset invalid */ + return XMS_INVALID_DEST_OFFSET; } if (length>xms_handles[dest_handle].size*1024U-dest.offset) { - return 0xa7; /* Length invalid */ + return XMS_INVALID_LENGTH; } destpt=(xms_handles[dest_handle].mem*4096)+dest.offset; } else { @@ -197,16 +199,14 @@ Bitu XMS_MoveMemory(PhysPt bpt) { return 0; } -Bitu XMS_LockMemory(Bitu handle, Bit32u& address) -{ +Bitu XMS_LockMemory(Bitu handle, Bit32u& address) { if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; if (xms_handles[handle].locked<255) xms_handles[handle].locked++; address = xms_handles[handle].mem*4096; return 0; }; -Bitu XMS_UnlockMemory(Bitu handle) -{ +Bitu XMS_UnlockMemory(Bitu handle) { if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; if (xms_handles[handle].locked) { xms_handles[handle].locked--; @@ -215,8 +215,7 @@ Bitu XMS_UnlockMemory(Bitu handle) return XMS_BLOCK_NOT_LOCKED; }; -Bitu XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFree, Bit16u& size) -{ +Bitu XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFree, Bit16u& size) { if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; lockCount = xms_handles[handle].locked; /* Find available blocks */ @@ -228,8 +227,7 @@ Bitu XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFree, Bit return 0; }; -Bitu XMS_ResizeMemory(Bitu handle, Bitu newSize) -{ +Bitu XMS_ResizeMemory(Bitu handle, Bitu newSize) { if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; // Block has to be unlocked if (xms_handles[handle].locked>0) return XMS_BLOCK_LOCKED; @@ -417,9 +415,16 @@ public: Bitu i; BIOS_ZeroExtendedSize(true); DOS_AddMultiplexHandler(multiplex_xms); + /* place hookable callback in writable memory area */ xms_callback=RealMake(DOS_GetMemory(0x1),0); callbackhandler.Install(&XMS_Handler,CB_HOOKABLE,Real2Phys(xms_callback),"XMS Handler"); + // pseudocode for CB_HOOKABLE: + // jump near skip + // nop,nop,nop + // label skip: + // callback XMS_Handler + // retf for (i=0;i Date: Wed, 26 Jul 2006 11:36:30 +0000 Subject: [PATCH 2593/4131] Add slightly modified help system of ykhwong. Added a few of the descriptions as well. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2678 --- include/shell.h | 4 ++-- src/shell/shell.cpp | 29 +++++++++++++++++++++++++---- src/shell/shell_cmds.cpp | 40 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 64 insertions(+), 9 deletions(-) diff --git a/include/shell.h b/include/shell.h index 5589e64b..ca8615cc 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.17 2006-07-21 09:40:10 qbix79 Exp $ */ +/* $Id: shell.h,v 1.18 2006-07-26 11:36:30 qbix79 Exp $ */ #ifndef DOSBOX_SHELL_H #define DOSBOX_SHELL_H @@ -105,7 +105,7 @@ public: void CMD_CHOICE(char * args); void CMD_ATTRIB(char * args); void CMD_PATH(char * args); - void CMD_SHIFT(char * /*args*/); + void CMD_SHIFT(char * args); void CMD_VER(char * args); /* The shell's variables */ Bit16u input_handle; diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 01fc6272..146bd425 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.76 2006-07-21 09:40:10 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.77 2006-07-26 11:36:30 qbix79 Exp $ */ #include #include @@ -485,28 +485,49 @@ void SHELL_Init() { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC\033[0m\n" //"\n" //Breaks the startup message if you type a mount and a drive change. ); - MSG_Add("SHELL_CMD_CHDIR_HELP","Change Directory.\n"); + MSG_Add("SHELL_CMD_CHDIR_HELP","Displays/changes the current directory.\n"); + MSG_Add("SHELL_CMD_CHDIR_HELP_LONG","CHDIR [drive:][path]\n" + "CHDIR [..]\n" + "CD [drive:][path]\n" + "CD [..]\n\n" + " .. Specifies that you want to change to the parent directory.\n\n" + "Type CD drive: to display the current directory in the specified drive.\n" + "Type CD without parameters to display the current drive and directory.\n"); MSG_Add("SHELL_CMD_CLS_HELP","Clear screen.\n"); MSG_Add("SHELL_CMD_DIR_HELP","Directory View.\n"); MSG_Add("SHELL_CMD_ECHO_HELP","Display messages and enable/disable command echoing.\n"); MSG_Add("SHELL_CMD_EXIT_HELP","Exit from the shell.\n"); MSG_Add("SHELL_CMD_HELP_HELP","Show help.\n"); MSG_Add("SHELL_CMD_MKDIR_HELP","Make Directory.\n"); + MSG_Add("SHELL_CMD_MKDIR_HELP_LONG","MKDIR [drive:][path]\n" + "MD [drive:][path]\n"); MSG_Add("SHELL_CMD_RMDIR_HELP","Remove Directory.\n"); + MSG_Add("SHELL_CMD_RMDIR_HELP_LONG","RMDIR [drive:][path]\n" + "RD [drive:][path]\n"); MSG_Add("SHELL_CMD_SET_HELP","Change environment variables.\n"); MSG_Add("SHELL_CMD_IF_HELP","Performs conditional processing in batch programs.\n"); MSG_Add("SHELL_CMD_GOTO_HELP","Jump to a labeled line in a batch script.\n"); MSG_Add("SHELL_CMD_SHIFT_HELP","Leftshift commandline parameters in a batch script.\n"); MSG_Add("SHELL_CMD_TYPE_HELP","Display the contents of a text-file.\n"); + MSG_Add("SHELL_CMD_TYPE_HELP_LONG","TYPE [drive:][path][filename]\n"); MSG_Add("SHELL_CMD_REM_HELP","Add comments in a batch file.\n"); + MSG_Add("SHELL_CMD_REM_HELP_LONG","REM [comment]\n"); MSG_Add("SHELL_CMD_NO_WILD","This is a simple version of the command, no wildcards allowed!\n"); - MSG_Add("SHELL_CMD_RENAME_HELP","Renames files.\n"); - MSG_Add("SHELL_CMD_DELETE_HELP","Removes files.\n"); + MSG_Add("SHELL_CMD_RENAME_HELP","Renames one or more files.\n"); + MSG_Add("SHELL_CMD_RENAME_HELP_LONG","RENAME [drive:][path]filename1 filename2.\n" + "REN [drive:][path]filename1 filename2.\n\n" + "Note that you can not specify a new drive or path for your destination file.\n"); + MSG_Add("SHELL_CMD_DELETE_HELP","Removes one or more files.\n"); MSG_Add("SHELL_CMD_COPY_HELP","Copy files.\n"); MSG_Add("SHELL_CMD_CALL_HELP","Start a batch file from within another batch file.\n"); MSG_Add("SHELL_CMD_SUBST_HELP","Assign an internal directory to a drive.\n"); MSG_Add("SHELL_CMD_LOADHIGH_HELP","Loads a program into upper memory (requires xms=true,umb=true).\n"); MSG_Add("SHELL_CMD_CHOICE_HELP","Waits for a keypress and sets ERRORLEVEL.\n"); + MSG_Add("SHELL_CMD_CHOICE_HELP_LONG","CHOICE [/C:choices] [/N] [/S] text\n" + " /C[:]choices - Specifies allowable keys. Default is: yn.\n" + " /N - Do not display the choices at end of prompt.\n" + " /S - Enables case-sensitive choices to be selected.\n" + " text - The text to display as a prompt.\n"); MSG_Add("SHELL_CMD_ATTRIB_HELP","Does nothing. Provided for compatibility.\n"); MSG_Add("SHELL_CMD_PATH_HELP","Provided for compatibility.\n"); MSG_Add("SHELL_CMD_VER_HELP","View and set the reported DOS version.\n"); diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 53b4a774..6d02e414 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.68 2006-07-21 09:40:10 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.69 2006-07-26 11:36:30 qbix79 Exp $ */ #include #include @@ -117,13 +117,24 @@ void DOS_Shell::DoCommand(char * line) { WriteOut(MSG_Get("SHELL_EXECUTE_ILLEGAL_COMMAND"),cmd); } +#define HELP(command) \ + if (ScanCMDBool(args,"?")) { \ + WriteOut(MSG_Get("SHELL_CMD_" command "_HELP")); \ + const char* long_m = MSG_Get("SHELL_CMD_" command "_HELP_LONG"); \ + WriteOut("\n"); \ + if(strcmp("Message not Found!\n",long_m)) WriteOut(long_m); \ + else WriteOut(command "\n"); \ + return; \ + } void DOS_Shell::CMD_CLS(char * args) { + HELP("CLS"); reg_ax=0x0003; CALLBACK_RunRealInt(0x10); }; void DOS_Shell::CMD_DELETE(char * args) { + HELP("DELETE"); /* Command uses dta so set it to our internal dta */ RealPt save_dta=dos.dta(); dos.dta(dos.tables.tempdta); @@ -163,6 +174,7 @@ void DOS_Shell::CMD_DELETE(char * args) { } void DOS_Shell::CMD_HELP(char * args){ + HELP("HELP"); /* Print the help */ WriteOut(MSG_Get("SHELL_CMD_HELP")); Bit32u cmd_index=0; @@ -174,6 +186,7 @@ void DOS_Shell::CMD_HELP(char * args){ } void DOS_Shell::CMD_RENAME(char * args){ + HELP("RENAME"); StripSpaces(args); if(!*args) {SyntaxError();return;} if((strchr(args,'*')!=NULL) || (strchr(args,'?')!=NULL) ) { WriteOut(MSG_Get("SHELL_CMD_NO_WILD"));return;} @@ -207,6 +220,7 @@ void DOS_Shell::CMD_RENAME(char * args){ } void DOS_Shell::CMD_ECHO(char * args){ + HELP("ECHO"); if (!*args) { if (echo) { WriteOut(MSG_Get("SHELL_CMD_ECHO_ON"));} else { WriteOut(MSG_Get("SHELL_CMD_ECHO_OFF"));} @@ -230,10 +244,12 @@ void DOS_Shell::CMD_ECHO(char * args){ void DOS_Shell::CMD_EXIT(char * args) { - exit=true; + HELP("EXIT"); + exit = true; }; void DOS_Shell::CMD_CHDIR(char * args) { + HELP("CHDIR"); StripSpaces(args); if (!*args) { Bit8u drive=DOS_GetDefaultDrive()+'A'; @@ -248,6 +264,7 @@ void DOS_Shell::CMD_CHDIR(char * args) { }; void DOS_Shell::CMD_MKDIR(char * args) { + HELP("MKDIR"); StripSpaces(args); char * rem=ScanCMDRemain(args); if (rem) { @@ -260,6 +277,7 @@ void DOS_Shell::CMD_MKDIR(char * args) { }; void DOS_Shell::CMD_RMDIR(char * args) { + HELP("RMDIR"); StripSpaces(args); char * rem=ScanCMDRemain(args); if (rem) { @@ -296,6 +314,7 @@ static void FormatNumber(Bitu num,char * buf) { } void DOS_Shell::CMD_DIR(char * args) { + HELP("DIR"); char numformat[16]; char path[DOS_PATHLENGTH]; @@ -437,6 +456,7 @@ void DOS_Shell::CMD_DIR(char * args) { } void DOS_Shell::CMD_COPY(char * args) { + HELP("COPY"); static char defaulttarget[] = "."; StripSpaces(args); /* Command uses dta so set it to our internal dta */ @@ -550,6 +570,7 @@ void DOS_Shell::CMD_COPY(char * args) { } void DOS_Shell::CMD_SET(char * args) { + HELP("SET"); StripSpaces(args); std::string line; if (!*args) { @@ -595,6 +616,7 @@ void DOS_Shell::CMD_SET(char * args) { } void DOS_Shell::CMD_IF(char * args) { + HELP("IF"); StripSpaces(args); bool has_not=false; char * comp=strchr(args,'='); @@ -659,6 +681,7 @@ void DOS_Shell::CMD_IF(char * args) { } void DOS_Shell::CMD_GOTO(char * args) { + HELP("GOTO"); StripSpaces(args); if (!bf) return; if (*args &&(*args==':')) args++; @@ -672,11 +695,13 @@ void DOS_Shell::CMD_GOTO(char * args) { } } -void DOS_Shell::CMD_SHIFT(char * /*args*/ ) { +void DOS_Shell::CMD_SHIFT(char * args ) { + HELP("SHIFT"); if(bf) bf->Shift(); } void DOS_Shell::CMD_TYPE(char * args) { + HELP("TYPE"); StripSpaces(args); if (!*args) { WriteOut(MSG_Get("SHELL_SYNTAXERROR")); @@ -701,15 +726,18 @@ nextfile: } void DOS_Shell::CMD_REM(char * args) { + HELP("REM"); } void DOS_Shell::CMD_PAUSE(char * args){ + HELP("PAUSE"); WriteOut(MSG_Get("SHELL_CMD_PAUSE")); Bit8u c;Bit16u n=1; DOS_ReadFile (STDIN,&c,&n); } void DOS_Shell::CMD_CALL(char * args){ + HELP("CALL"); this->call=true; /* else the old batchfile will be closed first */ this->ParseLine(args); this->call=false; @@ -719,6 +747,7 @@ void DOS_Shell::CMD_SUBST (char * args) { /* If more that one type can be substed think of something else * E.g. make basedir member dos_drive instead of localdrive */ + HELP("SUBST"); localDrive* ldp=0; char mountstring[DOS_PATHLENGTH+CROSS_LEN+20]; char temp_str[2] = { 0,0 }; @@ -771,6 +800,7 @@ void DOS_Shell::CMD_SUBST (char * args) { } void DOS_Shell::CMD_LOADHIGH(char *args){ + HELP("LOADHIGH"); Bit16u umb_start=dos_infoblock.GetStartOfUMBChain(); Bit8u umb_flag=dos_infoblock.GetUMBChainState(); Bit8u old_memstrat=DOS_GetMemAllocStrategy()&0xff; @@ -785,6 +815,7 @@ void DOS_Shell::CMD_LOADHIGH(char *args){ } void DOS_Shell::CMD_CHOICE(char * args){ + HELP("CHOICE"); static char defchoice[3] = {'y','n',0}; char *rem = NULL, *ptr; bool optN = ScanCMDBool(args,"N"); @@ -837,10 +868,12 @@ void DOS_Shell::CMD_CHOICE(char * args){ } void DOS_Shell::CMD_ATTRIB(char *args){ + HELP("ATTRIB"); // No-Op for now. } void DOS_Shell::CMD_PATH(char *args){ + HELP("PATH"); if(args && *args && strlen(args)){ char pathstring[DOS_PATHLENGTH+CROSS_LEN+20]={ 0 }; strcpy(pathstring,"set PATH="); @@ -860,6 +893,7 @@ void DOS_Shell::CMD_PATH(char *args){ } void DOS_Shell::CMD_VER(char *args) { + HELP("VER"); if(args && *args) { char* word = StripWord(args); if(strcasecmp(word,"set")) return; From 55092736b370a633cb70d794a7f2902d8252ac23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 1 Aug 2006 20:57:28 +0000 Subject: [PATCH 2594/4131] fix file operations on deleted files Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2679 --- src/dos/drive_local.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 699745c6..fb5a7988 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.69 2006-06-22 13:15:07 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.70 2006-08-01 20:57:28 c2woody Exp $ */ #include #include @@ -154,16 +154,22 @@ bool localDrive::FileUnlink(char * name) { //File exists and can technically be deleted, nevertheless it failed. //This means that the file is probably open by some process. //See if We have it open. - DOS_File* found_file = 0; + bool found_file = false; for(Bitu i = 0;i < DOS_FILES;i++){ - if(Files[i] && Files[i]->IsName(name)) - if(!found_file) found_file=Files[i]; - else return false; + if(Files[i] && Files[i]->IsName(name)) { + Bitu max = DOS_FILES; + while(Files[i]->IsOpen() && max--) { + Files[i]->Close(); + if (Files[i]->RemoveRef()<=0) { + delete Files[i]; + Files[i]=0; + break; + } + } + found_file=true; + } } if(!found_file) return false; - Bitu max = DOS_FILES; - while(found_file->IsOpen() && max--) - found_file->Close(); if (!unlink(fullname)) { dirCache.DeleteEntry(newname); return true; From 3b2a10e63be5a4d28d1f30d732d691bce3f1b9a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 3 Aug 2006 19:36:12 +0000 Subject: [PATCH 2595/4131] timer fix for 1000 Miglia (hal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2680 --- src/hardware/timer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index bc2a6763..96cbbcc1 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.39 2006-07-10 09:27:37 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.40 2006-08-03 19:36:12 c2woody Exp $ */ #include #include "dosbox.h" @@ -195,7 +195,6 @@ static void write_latch(Bitu port,Bitu val,Bitu /*iolen*/) { switch (counter) { case 0x00: /* Timer hooked to IRQ 0 */ if (p->new_mode || p->mode == 0 ) { - p->new_mode=false; PIC_AddEvent(PIT0_Event,p->delay); } else LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer set without new control word"); LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.2f Hz mode %d",1000.0/p->delay,p->mode); @@ -207,6 +206,7 @@ static void write_latch(Bitu port,Bitu val,Bitu /*iolen*/) { default: LOG(LOG_PIT,LOG_ERROR)("PIT:Illegal timer selected for writing"); } + p->new_mode=false; } } From 196d204ccf7cb2d997fdc2f13741eab7f3f9f35b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 4 Aug 2006 17:30:46 +0000 Subject: [PATCH 2596/4131] adapt vcpi interface offset to callback size Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2681 --- src/ints/ems.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 5cb157aa..5f9d09d2 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.52 2006-07-24 19:06:55 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.53 2006-08-04 17:30:46 c2woody Exp $ */ #include #include @@ -1193,7 +1193,7 @@ public: /* Install a callback that handles VCPI-requests in protected mode requests */ call_vcpi.Install(&VCPI_PM_Handler,CB_IRETD,"VCPI PM"); - vcpi.pm_interface=(call_vcpi.Get_callback())<<4; + vcpi.pm_interface=(call_vcpi.Get_callback())*CB_SIZE; /* Initialize private data area and set up descriptor tables */ SetupVCPI(); From 7db3da30f65bb4b5525c61938f9589c902aba422 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 5 Aug 2006 09:06:44 +0000 Subject: [PATCH 2597/4131] add patch 1485766 from Kronuz. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2682 --- src/dosbox.cpp | 6 +- src/gui/Makefile.am | 2 + src/gui/render.cpp | 39 +- src/gui/render_scalers.cpp | 55 + src/gui/render_scalers.h | 14 +- src/gui/render_templates.h | 101 +- src/gui/render_templates_hq.h | 85 + src/gui/render_templates_hq2x.h | 1896 ++++++++++++++++++++ src/gui/render_templates_hq3x.h | 2872 +++++++++++++++++++++++++++++++ src/gui/render_templates_sai.h | 229 +++ 10 files changed, 5294 insertions(+), 5 deletions(-) create mode 100644 src/gui/render_templates_hq.h create mode 100644 src/gui/render_templates_hq2x.h create mode 100644 src/gui/render_templates_hq3x.h create mode 100644 src/gui/render_templates_sai.h diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 47c746c6..2c8ae63b 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.101 2006-06-29 09:10:10 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.102 2006-08-05 09:06:44 qbix79 Exp $ */ #include #include @@ -271,7 +271,9 @@ void DOSBOX_Init(void) { "frameskip -- How many frames dosbox skips before drawing one.\n" "aspect -- Do aspect correction, if your output method doesn't support scaling this can slow things down!.\n" "scaler -- Scaler used to enlarge/enhance low resolution modes.\n" - " Supported are none,normal2x,normal3x,advmame2x,advmame3x,advinterp2x,advinterp3x,tv2x,tv3x,rgb2x,rgb3x,scan2x,scan3x.\n" + " Supported are none,normal2x,normal3x,advmame2x,advmame3x,hq2x,hq3x,\n" + " 2xsai,super2xsai,supereagle,advinterp2x,advinterp3x,\n" + " tv2x,tv3x,rgb2x,rgb3x,scan2x,scan3x.\n" ); secprop=control->AddSection_prop("cpu",&CPU_Init,true);//done diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 12695b17..17819379 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -4,5 +4,7 @@ noinst_LIBRARIES = libgui.a libgui_a_SOURCES = sdlmain.cpp sdl_mapper.cpp dosbox_logo.h \ render.cpp render_scalers.cpp render_scalers.h \ render_templates.h render_loops.h render_simple.h \ + render_templates_hq.h render_templates_hq.h \ + render_templates_hq2x.h render_templates_hq3x.h \ midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h midi_alsa.h diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 1800461c..180c0417 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.46 2006-05-27 07:01:33 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.47 2006-08-05 09:06:44 qbix79 Exp $ */ #include #include @@ -238,6 +238,24 @@ void RENDER_CallBack( GFX_CallBackFunctions_t function ) { else if (render.scale.size == 3) complexBlock = &ScaleAdvMame3x; break; + case scalerOpHQ: + if (render.scale.size == 2) + complexBlock = &ScaleHQ2x; + else if (render.scale.size == 3) + complexBlock = &ScaleHQ3x; + break; + case scalerOpSuperSaI: + if (render.scale.size == 2) + complexBlock = &ScaleSuper2xSaI; + break; + case scalerOpSuperEagle: + if (render.scale.size == 2) + complexBlock = &ScaleSuperEagle; + break; + case scalerOpSaI: + if (render.scale.size == 2) + complexBlock = &Scale2xSaI; + break; case scalerOpTV: if (render.scale.size == 2) simpleBlock = &ScaleTV2x; @@ -274,10 +292,12 @@ forcenormal: gfx_flags = complexBlock->gfxFlags; xscale = complexBlock->xscale; yscale = complexBlock->yscale; +// LOG_MSG("Scaler:%s",complexBlock->name); } else { gfx_flags = simpleBlock->gfxFlags; xscale = simpleBlock->xscale; yscale = simpleBlock->yscale; +// LOG_MSG("Scaler:%s",simpleBlock->name); } switch (render.src.bpp) { case 8: @@ -421,6 +441,18 @@ static void DecreaseFrameSkip(bool pressed) { LOG_MSG("Frame Skip at %d",render.frameskip.max); GFX_SetTitle(-1,render.frameskip.max,false); } +/* Disabled as I don't want to waste a keybind for that. Might be used in the future (Qbix) +static void ChangeScaler(bool pressed) { + if (!pressed) + return; + render.scale.op = (scalerOperation)((int)render.scale.op+1); + if((render.scale.op) >= scalerLast || render.scale.size == 1) { + render.scale.op = (scalerOperation)0; + if(++render.scale.size > 3) + render.scale.size = 1; + } + RENDER_CallBack( GFX_CallBackReset ); +} */ void RENDER_Init(Section * sec) { Section_prop * section=static_cast(sec); @@ -448,6 +480,11 @@ void RENDER_Init(Section * sec) { else if (!strcasecmp(scaler,"advmame3x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 3; } else if (!strcasecmp(scaler,"advinterp2x")) { render.scale.op = scalerOpAdvInterp;render.scale.size = 2; } else if (!strcasecmp(scaler,"advinterp3x")) { render.scale.op = scalerOpAdvInterp;render.scale.size = 3; } + else if (!strcasecmp(scaler,"hq2x")) { render.scale.op = scalerOpHQ;render.scale.size = 2; } + else if (!strcasecmp(scaler,"hq3x")) { render.scale.op = scalerOpHQ;render.scale.size = 3; } + else if (!strcasecmp(scaler,"2xsai")) { render.scale.op = scalerOpSaI;render.scale.size = 2; } + else if (!strcasecmp(scaler,"super2xsai")) { render.scale.op = scalerOpSuperSaI;render.scale.size = 2; } + else if (!strcasecmp(scaler,"supereagle")) { render.scale.op = scalerOpSuperEagle;render.scale.size = 2; } else if (!strcasecmp(scaler,"tv2x")) { render.scale.op = scalerOpTV;render.scale.size = 2; } else if (!strcasecmp(scaler,"tv3x")) { render.scale.op = scalerOpTV;render.scale.size = 3; } else if (!strcasecmp(scaler,"rgb2x")){ render.scale.op = scalerOpRGB;render.scale.size = 2; } diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index dc7d084e..a4bc776c 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -158,6 +158,7 @@ ScalerLineBlock_t ScalerCache = { }; ScalerSimpleBlock_t ScaleNormal1x = { + "Normal", GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, 1,1, Normal1x_8_8_L, Normal1x_8_15_L, Normal1x_8_16_L, Normal1x_8_32_L, @@ -173,6 +174,7 @@ ScalerSimpleBlock_t ScaleNormal1x = { }; ScalerSimpleBlock_t ScaleNormalDw = { + "Normal", GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, 2,1, NormalDw_8_8_L, NormalDw_8_15_L, NormalDw_8_16_L, NormalDw_8_32_L, @@ -188,6 +190,7 @@ ScalerSimpleBlock_t ScaleNormalDw = { }; ScalerSimpleBlock_t ScaleNormalDh = { + "Normal", GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, 1,2, NormalDh_8_8_L, NormalDh_8_15_L, NormalDh_8_16_L, NormalDh_8_32_L, @@ -203,6 +206,7 @@ ScalerSimpleBlock_t ScaleNormalDh = { }; ScalerSimpleBlock_t ScaleNormal2x = { + "Normal2x", GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, 2,2, Normal2x_8_8_L, Normal2x_8_15_L, Normal2x_8_16_L, Normal2x_8_32_L, @@ -218,6 +222,7 @@ ScalerSimpleBlock_t ScaleNormal2x = { }; ScalerSimpleBlock_t ScaleNormal3x = { + "Normal3x", GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, 3,3, Normal3x_8_8_L, Normal3x_8_15_L, Normal3x_8_16_L, Normal3x_8_32_L, @@ -233,6 +238,7 @@ ScalerSimpleBlock_t ScaleNormal3x = { }; ScalerSimpleBlock_t ScaleTV2x = { + "TV2x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 2,2, 0, TV2x_8_15_L, TV2x_8_16_L, TV2x_8_32_L, @@ -248,6 +254,7 @@ ScalerSimpleBlock_t ScaleTV2x = { }; ScalerSimpleBlock_t ScaleTV3x = { + "TV3x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 3,3, 0, TV3x_8_15_L, TV3x_8_16_L, TV3x_8_32_L, @@ -263,6 +270,7 @@ ScalerSimpleBlock_t ScaleTV3x = { }; ScalerSimpleBlock_t ScaleScan2x = { + "Scan2x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 2,2, 0, Scan2x_8_15_L, Scan2x_8_16_L, Scan2x_8_32_L, @@ -278,6 +286,7 @@ ScalerSimpleBlock_t ScaleScan2x = { }; ScalerSimpleBlock_t ScaleScan3x = { + "Scan3x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 3,3, 0, Scan3x_8_15_L, Scan3x_8_16_L, Scan3x_8_32_L, @@ -293,6 +302,7 @@ ScalerSimpleBlock_t ScaleScan3x = { }; ScalerSimpleBlock_t ScaleRGB2x = { + "RGB2x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 2,2, 0, RGB2x_8_15_L, RGB2x_8_16_L, RGB2x_8_32_L, @@ -308,6 +318,7 @@ ScalerSimpleBlock_t ScaleRGB2x = { }; ScalerSimpleBlock_t ScaleRGB3x = { + "RGB3x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 3,3, 0, RGB3x_8_15_L, RGB3x_8_16_L, RGB3x_8_32_L, @@ -326,6 +337,7 @@ ScalerSimpleBlock_t ScaleRGB3x = { /* Complex scalers */ ScalerComplexBlock_t ScaleAdvMame2x ={ + "AdvMame2x", GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, 2,2, AdvMame2x_8_L,AdvMame2x_16_L,AdvMame2x_16_L,AdvMame2x_32_L, @@ -333,6 +345,7 @@ ScalerComplexBlock_t ScaleAdvMame2x ={ }; ScalerComplexBlock_t ScaleAdvMame3x = { + "AdvMame3x", GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, 3,3, AdvMame3x_8_L,AdvMame3x_16_L,AdvMame3x_16_L,AdvMame3x_32_L, @@ -340,7 +353,48 @@ ScalerComplexBlock_t ScaleAdvMame3x = { }; /* These need specific 15bpp versions */ +ScalerComplexBlock_t ScaleHQ2x ={ + "HQ2x", + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, + 2,2, + 0,HQ2x_16_L,HQ2x_16_L,HQ2x_32_L, + 0,HQ2x_16_R,HQ2x_16_R,HQ2x_32_R +}; + +ScalerComplexBlock_t ScaleHQ3x ={ + "HQ3x", + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, + 3,3, + 0,HQ3x_16_L,HQ3x_16_L,HQ3x_32_L, + 0,HQ3x_16_R,HQ3x_16_R,HQ3x_32_R +}; + +ScalerComplexBlock_t ScaleSuper2xSaI ={ + "Super2xSaI", + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, + 2,2, + 0,Super2xSaI_16_L,Super2xSaI_16_L,Super2xSaI_32_L, + 0,Super2xSaI_16_R,Super2xSaI_16_R,Super2xSaI_32_R +}; + +ScalerComplexBlock_t Scale2xSaI ={ + "2xSaI", + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, + 2,2, + 0,_2xSaI_16_L,_2xSaI_16_L,_2xSaI_32_L, + 0,_2xSaI_16_R,_2xSaI_16_R,_2xSaI_32_R +}; + +ScalerComplexBlock_t ScaleSuperEagle ={ + "SuperEagle", + GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, + 2,2, + 0,SuperEagle_16_L,SuperEagle_16_L,SuperEagle_32_L, + 0,SuperEagle_16_R,SuperEagle_16_R,SuperEagle_32_R +}; + ScalerComplexBlock_t ScaleAdvInterp2x = { + "AdvInterp2x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 2,2, 0,AdvInterp2x_15_L,AdvInterp2x_16_L,AdvInterp2x_32_L, @@ -348,6 +402,7 @@ ScalerComplexBlock_t ScaleAdvInterp2x = { }; ScalerComplexBlock_t ScaleAdvInterp3x = { + "AdvInterp3x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 3,3, 0,AdvInterp3x_15_L,AdvInterp3x_16_L,AdvInterp3x_32_L, diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index 7cc419b2..81fc0ddc 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -33,13 +33,18 @@ typedef enum { scalerMode8, scalerMode15, scalerMode16, scalerMode32 } scalerMode_t; -typedef enum { +typedef enum scalerOperation { scalerOpNormal, scalerOpAdvMame, scalerOpAdvInterp, + scalerOpHQ, + scalerOpSaI, + scalerOpSuperSaI, + scalerOpSuperEagle, scalerOpTV, scalerOpRGB, scalerOpScan, + scalerLast, } scalerOperation_t; typedef void (*ScalerLineHandler_t)(const void *src); @@ -66,6 +71,7 @@ extern scalerChangeCache_t scalerChangeCache; typedef ScalerLineHandler_t ScalerLineBlock_t[5][4]; typedef struct { + char *name; Bitu gfxFlags; Bitu xscale,yscale; ScalerComplexHandler_t Linear[4]; @@ -73,6 +79,7 @@ typedef struct { } ScalerComplexBlock_t; typedef struct { + char *name; Bitu gfxFlags; Bitu xscale,yscale; ScalerLineBlock_t Linear; @@ -97,6 +104,11 @@ extern ScalerSimpleBlock_t ScaleRGB3x; extern ScalerSimpleBlock_t ScaleScan2x; extern ScalerSimpleBlock_t ScaleScan3x; /* Complex scalers */ +extern ScalerComplexBlock_t ScaleHQ2x; +extern ScalerComplexBlock_t ScaleHQ3x; +extern ScalerComplexBlock_t Scale2xSaI; +extern ScalerComplexBlock_t ScaleSuper2xSaI; +extern ScalerComplexBlock_t ScaleSuperEagle; extern ScalerComplexBlock_t ScaleAdvMame2x; extern ScalerComplexBlock_t ScaleAdvMame3x; extern ScalerComplexBlock_t ScaleAdvInterp2x; diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index ea234529..a5ef8abe 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -25,6 +25,12 @@ #define redMask 0 #define greenMask 0 #define blueMask 0 +#define redBits 0 +#define greenBits 0 +#define blueBits 0 +#define redShift 0 +#define greenShift 0 +#define blueShift 0 #elif DBPP == 15 || DBPP == 16 #define PSIZE 2 #define PTYPE Bit16u @@ -35,10 +41,22 @@ #define redMask 0x7C00 #define greenMask 0x03E0 #define blueMask 0x001F +#define redBits 5 +#define greenBits 5 +#define blueBits 5 +#define redShift 10 +#define greenShift 5 +#define blueShift 0 #elif DBPP == 16 #define redMask 0xF800 #define greenMask 0x07E0 #define blueMask 0x001F +#define redBits 5 +#define greenBits 6 +#define blueBits 5 +#define redShift 11 +#define greenShift 5 +#define blueShift 0 #endif #elif DBPP == 32 #define PSIZE 4 @@ -49,6 +67,12 @@ #define redMask 0xff0000 #define greenMask 0x00ff00 #define blueMask 0x0000ff +#define redBits 8 +#define greenBits 8 +#define blueBits 8 +#define redShift 16 +#define greenShift 8 +#define blueShift 0 #endif #define redblueMask (redMask | blueMask) @@ -104,6 +128,11 @@ #define SRCTYPE Bit32u #endif +// C0 C1 C2 D3 +// C3 C4 C5 D4 +// C6 C7 C8 D5 +// D0 D1 D2 D6 + #define C0 fc[-1 - SCALER_COMPLEXWIDTH] #define C1 fc[+0 - SCALER_COMPLEXWIDTH] #define C2 fc[+1 - SCALER_COMPLEXWIDTH] @@ -114,6 +143,15 @@ #define C7 fc[+0 + SCALER_COMPLEXWIDTH] #define C8 fc[+1 + SCALER_COMPLEXWIDTH] +#define D0 fc[-1 + 2*SCALER_COMPLEXWIDTH] +#define D1 fc[+0 + 2*SCALER_COMPLEXWIDTH] +#define D2 fc[+1 + 2*SCALER_COMPLEXWIDTH] +#define D3 fc[+2 - SCALER_COMPLEXWIDTH] +#define D4 fc[+2] +#define D5 fc[+2 + SCALER_COMPLEXWIDTH] +#define D6 fc[+2 + 2*SCALER_COMPLEXWIDTH] + + static void conc3d(Cache,SBPP,DBPP) (const void * s) { const SRCTYPE * src = (SRCTYPE*)s; PTYPE *fc= &FC[render.scale.inLine+1][1]; @@ -352,6 +390,62 @@ static void conc3d(Cache,SBPP,DBPP) (const void * s) { #if (DBPP > 8) +#include "render_templates_hq.h" + +#define SCALERNAME HQ2x +#define SCALERWIDTH 2 +#define SCALERHEIGHT 2 +#include "render_templates_hq2x.h" +#define SCALERFUNC conc2d(Hq2x,SBPP)(line0, line1, fc) +#include "render_loops.h" +#undef SCALERNAME +#undef SCALERWIDTH +#undef SCALERHEIGHT +#undef SCALERFUNC + +#define SCALERNAME HQ3x +#define SCALERWIDTH 3 +#define SCALERHEIGHT 3 +#include "render_templates_hq3x.h" +#define SCALERFUNC conc2d(Hq3x,SBPP)(line0, line1, line2, fc) +#include "render_loops.h" +#undef SCALERNAME +#undef SCALERWIDTH +#undef SCALERHEIGHT +#undef SCALERFUNC + +#include "render_templates_sai.h" + +#define SCALERNAME Super2xSaI +#define SCALERWIDTH 2 +#define SCALERHEIGHT 2 +#define SCALERFUNC conc2d(Super2xSaI,SBPP)(line0, line1, fc) +#include "render_loops.h" +#undef SCALERNAME +#undef SCALERWIDTH +#undef SCALERHEIGHT +#undef SCALERFUNC + +#define SCALERNAME SuperEagle +#define SCALERWIDTH 2 +#define SCALERHEIGHT 2 +#define SCALERFUNC conc2d(SuperEagle,SBPP)(line0, line1, fc) +#include "render_loops.h" +#undef SCALERNAME +#undef SCALERWIDTH +#undef SCALERHEIGHT +#undef SCALERFUNC + +#define SCALERNAME _2xSaI +#define SCALERWIDTH 2 +#define SCALERHEIGHT 2 +#define SCALERFUNC conc2d(_2xSaI,SBPP)(line0, line1, fc) +#include "render_loops.h" +#undef SCALERNAME +#undef SCALERWIDTH +#undef SCALERHEIGHT +#undef SCALERFUNC + #define SCALERNAME AdvInterp2x #define SCALERWIDTH 2 #define SCALERHEIGHT 2 @@ -458,5 +552,10 @@ static void conc3d(Cache,SBPP,DBPP) (const void * s) { #undef greenMask #undef blueMask #undef redblueMask +#undef redBits +#undef greenBits +#undef blueBits +#undef redShift +#undef greenShift +#undef blueShift #undef SRCTYPE - diff --git a/src/gui/render_templates_hq.h b/src/gui/render_templates_hq.h new file mode 100644 index 00000000..9d884030 --- /dev/null +++ b/src/gui/render_templates_hq.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2002-2006 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. + */ + +/* + * The HQ3x high quality 3x graphics filter. + * Original author Maxim Stepin (see http://www.hiend3d.com/hq3x.html). + * Adapted for DOSBox from ScummVM and HiEnd3D code by Kronuz. + */ + +#include + +#ifndef RENDER_TEMPLATES_HQNX_TABLE_H +#define RENDER_TEMPLATES_HQNX_TABLE_H + +static Bit32u *_RGBtoYUV = 0; +static inline bool diffYUV(Bit32u yuv1, Bit32u yuv2) +{ + static const Bit32u Ymask = 0x00FF0000; + static const Bit32u Umask = 0x0000FF00; + static const Bit32u Vmask = 0x000000FF; + static const Bit32u trY = 0x00300000; + static const Bit32u trU = 0x00000700; + static const Bit32u trV = 0x00000006; + + Bit32u diff; + Bit32u mask; + + diff = ((yuv1 & Ymask) - (yuv2 & Ymask)); + mask = diff >> 31; // -1 if value < 0, 0 otherwise + diff = (diff ^ mask) - mask; //-1: ~value + 1; 0: value + if (diff > trY) return true; + + diff = ((yuv1 & Umask) - (yuv2 & Umask)); + mask = diff >> 31; // -1 if value < 0, 0 otherwise + diff = (diff ^ mask) - mask; //-1: ~value + 1; 0: value + if (diff > trU) return true; + + diff = ((yuv1 & Vmask) - (yuv2 & Vmask)); + mask = diff >> 31; // -1 if value < 0, 0 otherwise + diff = (diff ^ mask) - mask; //-1: ~value + 1; 0: value + if (diff > trV) return true; + + return false; +} + +#endif + +static inline void conc2d(InitLUTs,SBPP)(void) +{ + int r, g, b; + int Y, u, v; + + _RGBtoYUV = (Bit32u *)malloc(65536 * sizeof(Bit32u)); + + for (int color = 0; color < 65536; ++color) { +#if SBPP == 32 + r = ((color & 0xF800) >> 11) << (8 - 5); + g = ((color & 0x07E0) >> 5) << (8 - 6); + b = ((color & 0x001F) >> 0) << (8 - 5); +#else + r = ((color & redMask) >> redShift) << (8 - redBits); + g = ((color & greenMask) >> greenShift) << (8 - greenBits); + b = ((color & blueMask) >> blueShift) << (8 - blueBits); +#endif + Y = (r + g + b) >> 2; + u = 128 + ((r - b) >> 2); + v = 128 + ((-r + 2 * g - b) >> 3); + _RGBtoYUV[color] = (Y << 16) | (u << 8) | v; + } +} diff --git a/src/gui/render_templates_hq2x.h b/src/gui/render_templates_hq2x.h new file mode 100644 index 00000000..d4deb6fe --- /dev/null +++ b/src/gui/render_templates_hq2x.h @@ -0,0 +1,1896 @@ +/* + * Copyright (C) 2002-2006 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. + */ + +/* + * The HQ2x high quality 2x graphics filter. + * Original author Maxim Stepin (see http://www.hiend3d.com/hq2x.html). + * Adapted for DOSBox from ScummVM and HiEnd3D code by Kronuz. + */ + +#ifndef RENDER_TEMPLATES_HQ2X_TABLE_H +#define RENDER_TEMPLATES_HQ2X_TABLE_H + +#define PIXEL00_0 line0[0] = C4; +#define PIXEL00_10 line0[0] = interp_w2(C4,C0,3U,1U); +#define PIXEL00_11 line0[0] = interp_w2(C4,C3,3U,1U); +#define PIXEL00_12 line0[0] = interp_w2(C4,C1,3U,1U); +#define PIXEL00_20 line0[0] = interp_w3(C4,C3,C1,2U,1U,1U); +#define PIXEL00_21 line0[0] = interp_w3(C4,C0,C1,2U,1U,1U); +#define PIXEL00_22 line0[0] = interp_w3(C4,C0,C3,2U,1U,1U); +#define PIXEL00_60 line0[0] = interp_w3(C4,C1,C3,5U,2U,1U); +#define PIXEL00_61 line0[0] = interp_w3(C4,C3,C1,5U,2U,1U); +#define PIXEL00_70 line0[0] = interp_w3(C4,C3,C1,6U,1U,1U); +#define PIXEL00_90 line0[0] = interp_w3(C4,C3,C1,2U,3U,3U); +#define PIXEL00_100 line0[0] = interp_w3(C4,C3,C1,14U,1U,1U); + +#define PIXEL01_0 line0[1] = C4; +#define PIXEL01_10 line0[1] = interp_w2(C4,C2,3U,1U); +#define PIXEL01_11 line0[1] = interp_w2(C4,C1,3U,1U); +#define PIXEL01_12 line0[1] = interp_w2(C4,C5,3U,1U); +#define PIXEL01_20 line0[1] = interp_w3(C4,C1,C5,2U,1U,1U); +#define PIXEL01_21 line0[1] = interp_w3(C4,C2,C5,2U,1U,1U); +#define PIXEL01_22 line0[1] = interp_w3(C4,C2,C1,2U,1U,1U); +#define PIXEL01_60 line0[1] = interp_w3(C4,C5,C1,5U,2U,1U); +#define PIXEL01_61 line0[1] = interp_w3(C4,C1,C5,5U,2U,1U); +#define PIXEL01_70 line0[1] = interp_w3(C4,C1,C5,6U,1U,1U); +#define PIXEL01_90 line0[1] = interp_w3(C4,C1,C5,2U,3U,3U); +#define PIXEL01_100 line0[1] = interp_w3(C4,C1,C5,14U,1U,1U); + +#define PIXEL10_0 line1[0] = C4; +#define PIXEL10_10 line1[0] = interp_w2(C4,C6,3U,1U); +#define PIXEL10_11 line1[0] = interp_w2(C4,C7,3U,1U); +#define PIXEL10_12 line1[0] = interp_w2(C4,C3,3U,1U); +#define PIXEL10_20 line1[0] = interp_w3(C4,C7,C3,2U,1U,1U); +#define PIXEL10_21 line1[0] = interp_w3(C4,C6,C3,2U,1U,1U); +#define PIXEL10_22 line1[0] = interp_w3(C4,C6,C7,2U,1U,1U); +#define PIXEL10_60 line1[0] = interp_w3(C4,C3,C7,5U,2U,1U); +#define PIXEL10_61 line1[0] = interp_w3(C4,C7,C3,5U,2U,1U); +#define PIXEL10_70 line1[0] = interp_w3(C4,C7,C3,6U,1U,1U); +#define PIXEL10_90 line1[0] = interp_w3(C4,C7,C3,2U,3U,3U); +#define PIXEL10_100 line1[0] = interp_w3(C4,C7,C3,14U,1U,1U); + +#define PIXEL11_0 line1[1] = C4; +#define PIXEL11_10 line1[1] = interp_w2(C4,C8,3U,1U); +#define PIXEL11_11 line1[1] = interp_w2(C4,C5,3U,1U); +#define PIXEL11_12 line1[1] = interp_w2(C4,C7,3U,1U); +#define PIXEL11_20 line1[1] = interp_w3(C4,C5,C7,2U,1U,1U); +#define PIXEL11_21 line1[1] = interp_w3(C4,C8,C7,2U,1U,1U); +#define PIXEL11_22 line1[1] = interp_w3(C4,C8,C5,2U,1U,1U); +#define PIXEL11_60 line1[1] = interp_w3(C4,C7,C5,5U,2U,1U); +#define PIXEL11_61 line1[1] = interp_w3(C4,C5,C7,5U,2U,1U); +#define PIXEL11_70 line1[1] = interp_w3(C4,C5,C7,6U,1U,1U); +#define PIXEL11_90 line1[1] = interp_w3(C4,C5,C7,2U,3U,3U); +#define PIXEL11_100 line1[1] = interp_w3(C4,C5,C7,14U,1U,1U); + +#endif + +#if SBPP == 32 +#define RGBtoYUV(c) _RGBtoYUV[((c & 0xf80000) >> 8) | ((c & 0x00fc00) >> 12) | ((c & 0x0000f8) >> 3)] +#else +#define RGBtoYUV(c) _RGBtoYUV[c] +#endif + +inline void conc2d(Hq2x,SBPP)(PTYPE * line0, PTYPE * line1, const PTYPE * fc) +{ + if (_RGBtoYUV == 0) conc2d(InitLUTs,SBPP)(); + + Bit32u pattern = 0; + const Bit32u YUV4 = RGBtoYUV(C4); + if (C4 != C0 && diffYUV(YUV4, RGBtoYUV(C0))) pattern |= 0x0001; + if (C4 != C1 && diffYUV(YUV4, RGBtoYUV(C1))) pattern |= 0x0002; + if (C4 != C2 && diffYUV(YUV4, RGBtoYUV(C2))) pattern |= 0x0004; + if (C4 != C3 && diffYUV(YUV4, RGBtoYUV(C3))) pattern |= 0x0008; + if (C4 != C5 && diffYUV(YUV4, RGBtoYUV(C5))) pattern |= 0x0010; + if (C4 != C6 && diffYUV(YUV4, RGBtoYUV(C6))) pattern |= 0x0020; + if (C4 != C7 && diffYUV(YUV4, RGBtoYUV(C7))) pattern |= 0x0040; + if (C4 != C8 && diffYUV(YUV4, RGBtoYUV(C8))) pattern |= 0x0080; + + switch (pattern) { + case 0: + case 1: + case 4: + case 32: + case 128: + case 5: + case 132: + case 160: + case 33: + case 129: + case 36: + case 133: + case 164: + case 161: + case 37: + case 165: + PIXEL00_20 + PIXEL01_20 + PIXEL10_20 + PIXEL11_20 + break; + case 2: + case 34: + case 130: + case 162: + PIXEL00_22 + PIXEL01_21 + PIXEL10_20 + PIXEL11_20 + break; + case 16: + case 17: + case 48: + case 49: + PIXEL00_20 + PIXEL01_22 + PIXEL10_20 + PIXEL11_21 + break; + case 64: + case 65: + case 68: + case 69: + PIXEL00_20 + PIXEL01_20 + PIXEL10_21 + PIXEL11_22 + break; + case 8: + case 12: + case 136: + case 140: + PIXEL00_21 + PIXEL01_20 + PIXEL10_22 + PIXEL11_20 + break; + case 3: + case 35: + case 131: + case 163: + PIXEL00_11 + PIXEL01_21 + PIXEL10_20 + PIXEL11_20 + break; + case 6: + case 38: + case 134: + case 166: + PIXEL00_22 + PIXEL01_12 + PIXEL10_20 + PIXEL11_20 + break; + case 20: + case 21: + case 52: + case 53: + PIXEL00_20 + PIXEL01_11 + PIXEL10_20 + PIXEL11_21 + break; + case 144: + case 145: + case 176: + case 177: + PIXEL00_20 + PIXEL01_22 + PIXEL10_20 + PIXEL11_12 + break; + case 192: + case 193: + case 196: + case 197: + PIXEL00_20 + PIXEL01_20 + PIXEL10_21 + PIXEL11_11 + break; + case 96: + case 97: + case 100: + case 101: + PIXEL00_20 + PIXEL01_20 + PIXEL10_12 + PIXEL11_22 + break; + case 40: + case 44: + case 168: + case 172: + PIXEL00_21 + PIXEL01_20 + PIXEL10_11 + PIXEL11_20 + break; + case 9: + case 13: + case 137: + case 141: + PIXEL00_12 + PIXEL01_20 + PIXEL10_22 + PIXEL11_20 + break; + case 18: + case 50: + PIXEL00_22 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_10 + } else { + PIXEL01_20 + } + PIXEL10_20 + PIXEL11_21 + break; + case 80: + case 81: + PIXEL00_20 + PIXEL01_22 + PIXEL10_21 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_10 + } else { + PIXEL11_20 + } + break; + case 72: + case 76: + PIXEL00_21 + PIXEL01_20 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_10 + } else { + PIXEL10_20 + } + PIXEL11_22 + break; + case 10: + case 138: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_10 + } else { + PIXEL00_20 + } + PIXEL01_21 + PIXEL10_22 + PIXEL11_20 + break; + case 66: + PIXEL00_22 + PIXEL01_21 + PIXEL10_21 + PIXEL11_22 + break; + case 24: + PIXEL00_21 + PIXEL01_22 + PIXEL10_22 + PIXEL11_21 + break; + case 7: + case 39: + case 135: + PIXEL00_11 + PIXEL01_12 + PIXEL10_20 + PIXEL11_20 + break; + case 148: + case 149: + case 180: + PIXEL00_20 + PIXEL01_11 + PIXEL10_20 + PIXEL11_12 + break; + case 224: + case 228: + case 225: + PIXEL00_20 + PIXEL01_20 + PIXEL10_12 + PIXEL11_11 + break; + case 41: + case 169: + case 45: + PIXEL00_12 + PIXEL01_20 + PIXEL10_11 + PIXEL11_20 + break; + case 22: + case 54: + PIXEL00_22 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_20 + PIXEL11_21 + break; + case 208: + case 209: + PIXEL00_20 + PIXEL01_22 + PIXEL10_21 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + case 104: + case 108: + PIXEL00_21 + PIXEL01_20 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_22 + break; + case 11: + case 139: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_21 + PIXEL10_22 + PIXEL11_20 + break; + case 19: + case 51: + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL00_11 + PIXEL01_10 + } else { + PIXEL00_60 + PIXEL01_90 + } + PIXEL10_20 + PIXEL11_21 + break; + case 146: + case 178: + PIXEL00_22 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_10 + PIXEL11_12 + } else { + PIXEL01_90 + PIXEL11_61 + } + PIXEL10_20 + break; + case 84: + case 85: + PIXEL00_20 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL01_11 + PIXEL11_10 + } else { + PIXEL01_60 + PIXEL11_90 + } + PIXEL10_21 + break; + case 112: + case 113: + PIXEL00_20 + PIXEL01_22 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL10_12 + PIXEL11_10 + } else { + PIXEL10_61 + PIXEL11_90 + } + break; + case 200: + case 204: + PIXEL00_21 + PIXEL01_20 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_10 + PIXEL11_11 + } else { + PIXEL10_90 + PIXEL11_60 + } + break; + case 73: + case 77: + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL00_12 + PIXEL10_10 + } else { + PIXEL00_61 + PIXEL10_90 + } + PIXEL01_20 + PIXEL11_22 + break; + case 42: + case 170: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_10 + PIXEL10_11 + } else { + PIXEL00_90 + PIXEL10_60 + } + PIXEL01_21 + PIXEL11_20 + break; + case 14: + case 142: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_10 + PIXEL01_12 + } else { + PIXEL00_90 + PIXEL01_61 + } + PIXEL10_22 + PIXEL11_20 + break; + case 67: + PIXEL00_11 + PIXEL01_21 + PIXEL10_21 + PIXEL11_22 + break; + case 70: + PIXEL00_22 + PIXEL01_12 + PIXEL10_21 + PIXEL11_22 + break; + case 28: + PIXEL00_21 + PIXEL01_11 + PIXEL10_22 + PIXEL11_21 + break; + case 152: + PIXEL00_21 + PIXEL01_22 + PIXEL10_22 + PIXEL11_12 + break; + case 194: + PIXEL00_22 + PIXEL01_21 + PIXEL10_21 + PIXEL11_11 + break; + case 98: + PIXEL00_22 + PIXEL01_21 + PIXEL10_12 + PIXEL11_22 + break; + case 56: + PIXEL00_21 + PIXEL01_22 + PIXEL10_11 + PIXEL11_21 + break; + case 25: + PIXEL00_12 + PIXEL01_22 + PIXEL10_22 + PIXEL11_21 + break; + case 26: + case 31: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_20 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_22 + PIXEL11_21 + break; + case 82: + case 214: + PIXEL00_22 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_21 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + case 88: + case 248: + PIXEL00_21 + PIXEL01_22 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_20 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + case 74: + case 107: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_21 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_22 + break; + case 27: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_10 + PIXEL10_22 + PIXEL11_21 + break; + case 86: + PIXEL00_22 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_21 + PIXEL11_10 + break; + case 216: + PIXEL00_21 + PIXEL01_22 + PIXEL10_10 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + case 106: + PIXEL00_10 + PIXEL01_21 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_22 + break; + case 30: + PIXEL00_10 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_22 + PIXEL11_21 + break; + case 210: + PIXEL00_22 + PIXEL01_10 + PIXEL10_21 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + case 120: + PIXEL00_21 + PIXEL01_22 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_10 + break; + case 75: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_21 + PIXEL10_10 + PIXEL11_22 + break; + case 29: + PIXEL00_12 + PIXEL01_11 + PIXEL10_22 + PIXEL11_21 + break; + case 198: + PIXEL00_22 + PIXEL01_12 + PIXEL10_21 + PIXEL11_11 + break; + case 184: + PIXEL00_21 + PIXEL01_22 + PIXEL10_11 + PIXEL11_12 + break; + case 99: + PIXEL00_11 + PIXEL01_21 + PIXEL10_12 + PIXEL11_22 + break; + case 57: + PIXEL00_12 + PIXEL01_22 + PIXEL10_11 + PIXEL11_21 + break; + case 71: + PIXEL00_11 + PIXEL01_12 + PIXEL10_21 + PIXEL11_22 + break; + case 156: + PIXEL00_21 + PIXEL01_11 + PIXEL10_22 + PIXEL11_12 + break; + case 226: + PIXEL00_22 + PIXEL01_21 + PIXEL10_12 + PIXEL11_11 + break; + case 60: + PIXEL00_21 + PIXEL01_11 + PIXEL10_11 + PIXEL11_21 + break; + case 195: + PIXEL00_11 + PIXEL01_21 + PIXEL10_21 + PIXEL11_11 + break; + case 102: + PIXEL00_22 + PIXEL01_12 + PIXEL10_12 + PIXEL11_22 + break; + case 153: + PIXEL00_12 + PIXEL01_22 + PIXEL10_22 + PIXEL11_12 + break; + case 58: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_10 + } else { + PIXEL00_70 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_10 + } else { + PIXEL01_70 + } + PIXEL10_11 + PIXEL11_21 + break; + case 83: + PIXEL00_11 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_10 + } else { + PIXEL01_70 + } + PIXEL10_21 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + case 92: + PIXEL00_21 + PIXEL01_11 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_10 + } else { + PIXEL10_70 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + case 202: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_10 + } else { + PIXEL00_70 + } + PIXEL01_21 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_10 + } else { + PIXEL10_70 + } + PIXEL11_11 + break; + case 78: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_10 + } else { + PIXEL00_70 + } + PIXEL01_12 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_10 + } else { + PIXEL10_70 + } + PIXEL11_22 + break; + case 154: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_10 + } else { + PIXEL00_70 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_10 + } else { + PIXEL01_70 + } + PIXEL10_22 + PIXEL11_12 + break; + case 114: + PIXEL00_22 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_10 + } else { + PIXEL01_70 + } + PIXEL10_12 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + case 89: + PIXEL00_12 + PIXEL01_22 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_10 + } else { + PIXEL10_70 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + case 90: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_10 + } else { + PIXEL00_70 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_10 + } else { + PIXEL01_70 + } + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_10 + } else { + PIXEL10_70 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + case 55: + case 23: + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL00_11 + PIXEL01_0 + } else { + PIXEL00_60 + PIXEL01_90 + } + PIXEL10_20 + PIXEL11_21 + break; + case 182: + case 150: + PIXEL00_22 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + PIXEL11_12 + } else { + PIXEL01_90 + PIXEL11_61 + } + PIXEL10_20 + break; + case 213: + case 212: + PIXEL00_20 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL01_11 + PIXEL11_0 + } else { + PIXEL01_60 + PIXEL11_90 + } + PIXEL10_21 + break; + case 241: + case 240: + PIXEL00_20 + PIXEL01_22 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL10_12 + PIXEL11_0 + } else { + PIXEL10_61 + PIXEL11_90 + } + break; + case 236: + case 232: + PIXEL00_21 + PIXEL01_20 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + PIXEL11_11 + } else { + PIXEL10_90 + PIXEL11_60 + } + break; + case 109: + case 105: + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL00_12 + PIXEL10_0 + } else { + PIXEL00_61 + PIXEL10_90 + } + PIXEL01_20 + PIXEL11_22 + break; + case 171: + case 43: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + PIXEL10_11 + } else { + PIXEL00_90 + PIXEL10_60 + } + PIXEL01_21 + PIXEL11_20 + break; + case 143: + case 15: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + PIXEL01_12 + } else { + PIXEL00_90 + PIXEL01_61 + } + PIXEL10_22 + PIXEL11_20 + break; + case 124: + PIXEL00_21 + PIXEL01_11 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_10 + break; + case 203: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_21 + PIXEL10_10 + PIXEL11_11 + break; + case 62: + PIXEL00_10 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_11 + PIXEL11_21 + break; + case 211: + PIXEL00_11 + PIXEL01_10 + PIXEL10_21 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + case 118: + PIXEL00_22 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_12 + PIXEL11_10 + break; + case 217: + PIXEL00_12 + PIXEL01_22 + PIXEL10_10 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + case 110: + PIXEL00_10 + PIXEL01_12 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_22 + break; + case 155: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_10 + PIXEL10_22 + PIXEL11_12 + break; + case 188: + PIXEL00_21 + PIXEL01_11 + PIXEL10_11 + PIXEL11_12 + break; + case 185: + PIXEL00_12 + PIXEL01_22 + PIXEL10_11 + PIXEL11_12 + break; + case 61: + PIXEL00_12 + PIXEL01_11 + PIXEL10_11 + PIXEL11_21 + break; + case 157: + PIXEL00_12 + PIXEL01_11 + PIXEL10_22 + PIXEL11_12 + break; + case 103: + PIXEL00_11 + PIXEL01_12 + PIXEL10_12 + PIXEL11_22 + break; + case 227: + PIXEL00_11 + PIXEL01_21 + PIXEL10_12 + PIXEL11_11 + break; + case 230: + PIXEL00_22 + PIXEL01_12 + PIXEL10_12 + PIXEL11_11 + break; + case 199: + PIXEL00_11 + PIXEL01_12 + PIXEL10_21 + PIXEL11_11 + break; + case 220: + PIXEL00_21 + PIXEL01_11 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_10 + } else { + PIXEL10_70 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + case 158: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_10 + } else { + PIXEL00_70 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_22 + PIXEL11_12 + break; + case 234: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_10 + } else { + PIXEL00_70 + } + PIXEL01_21 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_11 + break; + case 242: + PIXEL00_22 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_10 + } else { + PIXEL01_70 + } + PIXEL10_12 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + case 59: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_20 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_10 + } else { + PIXEL01_70 + } + PIXEL10_11 + PIXEL11_21 + break; + case 121: + PIXEL00_12 + PIXEL01_22 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_20 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + case 87: + PIXEL00_11 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_21 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + case 79: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_12 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_10 + } else { + PIXEL10_70 + } + PIXEL11_22 + break; + case 122: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_10 + } else { + PIXEL00_70 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_10 + } else { + PIXEL01_70 + } + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_20 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + case 94: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_10 + } else { + PIXEL00_70 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_20 + } + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_10 + } else { + PIXEL10_70 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + case 218: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_10 + } else { + PIXEL00_70 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_10 + } else { + PIXEL01_70 + } + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_10 + } else { + PIXEL10_70 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + case 91: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_20 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_10 + } else { + PIXEL01_70 + } + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_10 + } else { + PIXEL10_70 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + case 229: + PIXEL00_20 + PIXEL01_20 + PIXEL10_12 + PIXEL11_11 + break; + case 167: + PIXEL00_11 + PIXEL01_12 + PIXEL10_20 + PIXEL11_20 + break; + case 173: + PIXEL00_12 + PIXEL01_20 + PIXEL10_11 + PIXEL11_20 + break; + case 181: + PIXEL00_20 + PIXEL01_11 + PIXEL10_20 + PIXEL11_12 + break; + case 186: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_10 + } else { + PIXEL00_70 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_10 + } else { + PIXEL01_70 + } + PIXEL10_11 + PIXEL11_12 + break; + case 115: + PIXEL00_11 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_10 + } else { + PIXEL01_70 + } + PIXEL10_12 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + case 93: + PIXEL00_12 + PIXEL01_11 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_10 + } else { + PIXEL10_70 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + case 206: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_10 + } else { + PIXEL00_70 + } + PIXEL01_12 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_10 + } else { + PIXEL10_70 + } + PIXEL11_11 + break; + case 205: + case 201: + PIXEL00_12 + PIXEL01_20 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_10 + } else { + PIXEL10_70 + } + PIXEL11_11 + break; + case 174: + case 46: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_10 + } else { + PIXEL00_70 + } + PIXEL01_12 + PIXEL10_11 + PIXEL11_20 + break; + case 179: + case 147: + PIXEL00_11 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_10 + } else { + PIXEL01_70 + } + PIXEL10_20 + PIXEL11_12 + break; + case 117: + case 116: + PIXEL00_20 + PIXEL01_11 + PIXEL10_12 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + case 189: + PIXEL00_12 + PIXEL01_11 + PIXEL10_11 + PIXEL11_12 + break; + case 231: + PIXEL00_11 + PIXEL01_12 + PIXEL10_12 + PIXEL11_11 + break; + case 126: + PIXEL00_10 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_20 + } + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_10 + break; + case 219: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_10 + PIXEL10_10 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + case 125: + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL00_12 + PIXEL10_0 + } else { + PIXEL00_61 + PIXEL10_90 + } + PIXEL01_11 + PIXEL11_10 + break; + case 221: + PIXEL00_12 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL01_11 + PIXEL11_0 + } else { + PIXEL01_60 + PIXEL11_90 + } + PIXEL10_10 + break; + case 207: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + PIXEL01_12 + } else { + PIXEL00_90 + PIXEL01_61 + } + PIXEL10_10 + PIXEL11_11 + break; + case 238: + PIXEL00_10 + PIXEL01_12 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + PIXEL11_11 + } else { + PIXEL10_90 + PIXEL11_60 + } + break; + case 190: + PIXEL00_10 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + PIXEL11_12 + } else { + PIXEL01_90 + PIXEL11_61 + } + PIXEL10_11 + break; + case 187: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + PIXEL10_11 + } else { + PIXEL00_90 + PIXEL10_60 + } + PIXEL01_10 + PIXEL11_12 + break; + case 243: + PIXEL00_11 + PIXEL01_10 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL10_12 + PIXEL11_0 + } else { + PIXEL10_61 + PIXEL11_90 + } + break; + case 119: + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL00_11 + PIXEL01_0 + } else { + PIXEL00_60 + PIXEL01_90 + } + PIXEL10_12 + PIXEL11_10 + break; + case 237: + case 233: + PIXEL00_12 + PIXEL01_20 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_100 + } + PIXEL11_11 + break; + case 175: + case 47: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_100 + } + PIXEL01_12 + PIXEL10_11 + PIXEL11_20 + break; + case 183: + case 151: + PIXEL00_11 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_100 + } + PIXEL10_20 + PIXEL11_12 + break; + case 245: + case 244: + PIXEL00_20 + PIXEL01_11 + PIXEL10_12 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_100 + } + break; + case 250: + PIXEL00_10 + PIXEL01_10 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_20 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + case 123: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_10 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_10 + break; + case 95: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_20 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_10 + PIXEL11_10 + break; + case 222: + PIXEL00_10 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_10 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + case 252: + PIXEL00_21 + PIXEL01_11 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_20 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_100 + } + break; + case 249: + PIXEL00_12 + PIXEL01_22 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_100 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + case 235: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_21 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_100 + } + PIXEL11_11 + break; + case 111: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_100 + } + PIXEL01_12 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_22 + break; + case 63: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_100 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_11 + PIXEL11_21 + break; + case 159: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_20 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_100 + } + PIXEL10_22 + PIXEL11_12 + break; + case 215: + PIXEL00_11 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_100 + } + PIXEL10_21 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + case 246: + PIXEL00_22 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_12 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_100 + } + break; + case 254: + PIXEL00_10 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_20 + } + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_20 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_100 + } + break; + case 253: + PIXEL00_12 + PIXEL01_11 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_100 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_100 + } + break; + case 251: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_10 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_100 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + case 239: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_100 + } + PIXEL01_12 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_100 + } + PIXEL11_11 + break; + case 127: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_100 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_20 + } + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_10 + break; + case 191: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_100 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_100 + } + PIXEL10_11 + PIXEL11_12 + break; + case 223: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_20 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_100 + } + PIXEL10_10 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + case 247: + PIXEL00_11 + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_100 + } + PIXEL10_12 + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_100 + } + break; + case 255: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_0 + } else { + PIXEL00_100 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_0 + } else { + PIXEL01_100 + } + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_0 + } else { + PIXEL10_100 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL11_0 + } else { + PIXEL11_100 + } + break; + } +} + +#undef RGBtoYUV diff --git a/src/gui/render_templates_hq3x.h b/src/gui/render_templates_hq3x.h new file mode 100644 index 00000000..9baa4e7d --- /dev/null +++ b/src/gui/render_templates_hq3x.h @@ -0,0 +1,2872 @@ +/* + * Copyright (C) 2002-2006 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. + */ + +/* + * The HQ3x high quality 3x graphics filter. + * Original author Maxim Stepin (see http://www.hiend3d.com/hq3x.html). + * Adapted for DOSBox from ScummVM and HiEnd3D code by Kronuz. + */ + +#ifndef RENDER_TEMPLATES_HQ3X_TABLE_H +#define RENDER_TEMPLATES_HQ3X_TABLE_H + +#define PIXEL00_1M line0[0] = interp_w2(C4,C0,3U,1U); +#define PIXEL00_1U line0[0] = interp_w2(C4,C1,3U,1U); +#define PIXEL00_1L line0[0] = interp_w2(C4,C3,3U,1U); +#define PIXEL00_2 line0[0] = interp_w3(C4,C3,C1,2U,1U,1U); +#define PIXEL00_4 line0[0] = interp_w3(C4,C3,C1,2U,7U,7U); +#define PIXEL00_5 line0[0] = interp_w2(C3,C1,1U,1U); +#define PIXEL00_C line0[0] = C4; + +#define PIXEL01_1 line0[1] = interp_w2(C4,C1,3U,1U); +#define PIXEL01_3 line0[1] = interp_w2(C4,C1,7U,1U); +#define PIXEL01_6 line0[1] = interp_w2(C1,C4,3U,1U); +#define PIXEL01_C line0[1] = C4; + +#define PIXEL02_1M line0[2] = interp_w2(C4,C2,3U,1U); +#define PIXEL02_1U line0[2] = interp_w2(C4,C1,3U,1U); +#define PIXEL02_1R line0[2] = interp_w2(C4,C5,3U,1U); +#define PIXEL02_2 line0[2] = interp_w3(C4,C1,C5,2U,1U,1U); +#define PIXEL02_4 line0[2] = interp_w3(C4,C1,C5,2U,7U,7U); +#define PIXEL02_5 line0[2] = interp_w2(C1,C5,1U,1U); +#define PIXEL02_C line0[2] = C4; + +#define PIXEL10_1 line1[0] = interp_w2(C4,C3,3U,1U); +#define PIXEL10_3 line1[0] = interp_w2(C4,C3,7U,1U); +#define PIXEL10_6 line1[0] = interp_w2(C3,C4,3U,1U); +#define PIXEL10_C line1[0] = C4; + +#define PIXEL11 line1[1] = C4; + +#define PIXEL12_1 line1[2] = interp_w2(C4,C5,3U,1U); +#define PIXEL12_3 line1[2] = interp_w2(C4,C5,7U,1U); +#define PIXEL12_6 line1[2] = interp_w2(C5,C4,3U,1U); +#define PIXEL12_C line1[2] = C4; + +#define PIXEL20_1M line2[0] = interp_w2(C4,C6,3U,1U); +#define PIXEL20_1D line2[0] = interp_w2(C4,C7,3U,1U); +#define PIXEL20_1L line2[0] = interp_w2(C4,C3,3U,1U); +#define PIXEL20_2 line2[0] = interp_w3(C4,C7,C3,2U,1U,1U); +#define PIXEL20_4 line2[0] = interp_w3(C4,C7,C3,2U,7U,7U); +#define PIXEL20_5 line2[0] = interp_w2(C7,C3,1U,1U); +#define PIXEL20_C line2[0] = C4; + +#define PIXEL21_1 line2[1] = interp_w2(C4,C7,3U,1U); +#define PIXEL21_3 line2[1] = interp_w2(C4,C7,7U,1U); +#define PIXEL21_6 line2[1] = interp_w2(C7,C4,3U,1U); +#define PIXEL21_C line2[1] = C4; + +#define PIXEL22_1M line2[2] = interp_w2(C4,C8,3U,1U); +#define PIXEL22_1D line2[2] = interp_w2(C4,C7,3U,1U); +#define PIXEL22_1R line2[2] = interp_w2(C4,C5,3U,1U); +#define PIXEL22_2 line2[2] = interp_w3(C4,C5,C7,2U,1U,1U); +#define PIXEL22_4 line2[2] = interp_w3(C4,C5,C7,2U,7U,7U); +#define PIXEL22_5 line2[2] = interp_w2(C5,C7,1U,1U); +#define PIXEL22_C line2[2] = C4; + +#endif + +#if SBPP == 32 +#define RGBtoYUV(c) _RGBtoYUV[((c & 0xf80000) >> 8) | ((c & 0x00fc00) >> 12) | ((c & 0x0000f8) >> 3)] +#else +#define RGBtoYUV(c) _RGBtoYUV[c] +#endif + +inline void conc2d(Hq3x,SBPP)(PTYPE * line0, PTYPE * line1, PTYPE * line2, const PTYPE * fc) +{ + if (_RGBtoYUV == 0) conc2d(InitLUTs,SBPP)(); + + Bit32u pattern = 0; + const Bit32u YUV4 = RGBtoYUV(C4); + + if (C4 != C0 && diffYUV(YUV4, RGBtoYUV(C0))) pattern |= 0x0001; + if (C4 != C1 && diffYUV(YUV4, RGBtoYUV(C1))) pattern |= 0x0002; + if (C4 != C2 && diffYUV(YUV4, RGBtoYUV(C2))) pattern |= 0x0004; + if (C4 != C3 && diffYUV(YUV4, RGBtoYUV(C3))) pattern |= 0x0008; + if (C4 != C5 && diffYUV(YUV4, RGBtoYUV(C5))) pattern |= 0x0010; + if (C4 != C6 && diffYUV(YUV4, RGBtoYUV(C6))) pattern |= 0x0020; + if (C4 != C7 && diffYUV(YUV4, RGBtoYUV(C7))) pattern |= 0x0040; + if (C4 != C8 && diffYUV(YUV4, RGBtoYUV(C8))) pattern |= 0x0080; + + switch (pattern) { + case 0: + case 1: + case 4: + case 32: + case 128: + case 5: + case 132: + case 160: + case 33: + case 129: + case 36: + case 133: + case 164: + case 161: + case 37: + case 165: + PIXEL00_2 + PIXEL01_1 + PIXEL02_2 + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_2 + PIXEL21_1 + PIXEL22_2 + break; + case 2: + case 34: + case 130: + case 162: + PIXEL00_1M + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_2 + PIXEL21_1 + PIXEL22_2 + break; + case 16: + case 17: + case 48: + case 49: + PIXEL00_2 + PIXEL01_1 + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_2 + PIXEL21_1 + PIXEL22_1M + break; + case 64: + case 65: + case 68: + case 69: + PIXEL00_2 + PIXEL01_1 + PIXEL02_2 + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1M + break; + case 8: + case 12: + case 136: + case 140: + PIXEL00_1M + PIXEL01_1 + PIXEL02_2 + PIXEL10_C + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_1 + PIXEL22_2 + break; + case 3: + case 35: + case 131: + case 163: + PIXEL00_1L + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_2 + PIXEL21_1 + PIXEL22_2 + break; + case 6: + case 38: + case 134: + case 166: + PIXEL00_1M + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_2 + PIXEL21_1 + PIXEL22_2 + break; + case 20: + case 21: + case 52: + case 53: + PIXEL00_2 + PIXEL01_1 + PIXEL02_1U + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_2 + PIXEL21_1 + PIXEL22_1M + break; + case 144: + case 145: + case 176: + case 177: + PIXEL00_2 + PIXEL01_1 + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_2 + PIXEL21_1 + PIXEL22_1D + break; + case 192: + case 193: + case 196: + case 197: + PIXEL00_2 + PIXEL01_1 + PIXEL02_2 + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1R + break; + case 96: + case 97: + case 100: + case 101: + PIXEL00_2 + PIXEL01_1 + PIXEL02_2 + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1M + break; + case 40: + case 44: + case 168: + case 172: + PIXEL00_1M + PIXEL01_1 + PIXEL02_2 + PIXEL10_C + PIXEL11 + PIXEL12_1 + PIXEL20_1D + PIXEL21_1 + PIXEL22_2 + break; + case 9: + case 13: + case 137: + case 141: + PIXEL00_1U + PIXEL01_1 + PIXEL02_2 + PIXEL10_C + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_1 + PIXEL22_2 + break; + case 18: + case 50: + PIXEL00_1M + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_C + PIXEL02_1M + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_1 + PIXEL11 + PIXEL20_2 + PIXEL21_1 + PIXEL22_1M + break; + case 80: + case 81: + PIXEL00_2 + PIXEL01_1 + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL20_1M + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL12_C + PIXEL21_C + PIXEL22_1M + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + case 72: + case 76: + PIXEL00_1M + PIXEL01_1 + PIXEL02_2 + PIXEL11 + PIXEL12_1 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_C + PIXEL20_1M + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + case 10: + case 138: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_1M + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + PIXEL02_1M + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_1 + PIXEL22_2 + break; + case 66: + PIXEL00_1M + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1M + break; + case 24: + PIXEL00_1M + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1M + break; + case 7: + case 39: + case 135: + PIXEL00_1L + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_2 + PIXEL21_1 + PIXEL22_2 + break; + case 148: + case 149: + case 180: + PIXEL00_2 + PIXEL01_1 + PIXEL02_1U + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_2 + PIXEL21_1 + PIXEL22_1D + break; + case 224: + case 228: + case 225: + PIXEL00_2 + PIXEL01_1 + PIXEL02_2 + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1R + break; + case 41: + case 169: + case 45: + PIXEL00_1U + PIXEL01_1 + PIXEL02_2 + PIXEL10_C + PIXEL11 + PIXEL12_1 + PIXEL20_1D + PIXEL21_1 + PIXEL22_2 + break; + case 22: + case 54: + PIXEL00_1M + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_1 + PIXEL11 + PIXEL20_2 + PIXEL21_1 + PIXEL22_1M + break; + case 208: + case 209: + PIXEL00_2 + PIXEL01_1 + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL20_1M + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + case 104: + case 108: + PIXEL00_1M + PIXEL01_1 + PIXEL02_2 + PIXEL11 + PIXEL12_1 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + case 11: + case 139: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + PIXEL02_1M + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_1 + PIXEL22_2 + break; + case 19: + case 51: + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL00_1L + PIXEL01_C + PIXEL02_1M + PIXEL12_C + } else { + PIXEL00_2 + PIXEL01_6 + PIXEL02_5 + PIXEL12_1 + } + PIXEL10_1 + PIXEL11 + PIXEL20_2 + PIXEL21_1 + PIXEL22_1M + break; + case 146: + case 178: + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_C + PIXEL02_1M + PIXEL12_C + PIXEL22_1D + } else { + PIXEL01_1 + PIXEL02_5 + PIXEL12_6 + PIXEL22_2 + } + PIXEL00_1M + PIXEL10_1 + PIXEL11 + PIXEL20_2 + PIXEL21_1 + break; + case 84: + case 85: + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL02_1U + PIXEL12_C + PIXEL21_C + PIXEL22_1M + } else { + PIXEL02_2 + PIXEL12_6 + PIXEL21_1 + PIXEL22_5 + } + PIXEL00_2 + PIXEL01_1 + PIXEL10_1 + PIXEL11 + PIXEL20_1M + break; + case 112: + case 113: + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL12_C + PIXEL20_1L + PIXEL21_C + PIXEL22_1M + } else { + PIXEL12_1 + PIXEL20_2 + PIXEL21_6 + PIXEL22_5 + } + PIXEL00_2 + PIXEL01_1 + PIXEL02_1M + PIXEL10_1 + PIXEL11 + break; + case 200: + case 204: + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_C + PIXEL20_1M + PIXEL21_C + PIXEL22_1R + } else { + PIXEL10_1 + PIXEL20_5 + PIXEL21_6 + PIXEL22_2 + } + PIXEL00_1M + PIXEL01_1 + PIXEL02_2 + PIXEL11 + PIXEL12_1 + break; + case 73: + case 77: + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL00_1U + PIXEL10_C + PIXEL20_1M + PIXEL21_C + } else { + PIXEL00_2 + PIXEL10_6 + PIXEL20_5 + PIXEL21_1 + } + PIXEL01_1 + PIXEL02_2 + PIXEL11 + PIXEL12_1 + PIXEL22_1M + break; + case 42: + case 170: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_1M + PIXEL01_C + PIXEL10_C + PIXEL20_1D + } else { + PIXEL00_5 + PIXEL01_1 + PIXEL10_6 + PIXEL20_2 + } + PIXEL02_1M + PIXEL11 + PIXEL12_1 + PIXEL21_1 + PIXEL22_2 + break; + case 14: + case 142: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_1M + PIXEL01_C + PIXEL02_1R + PIXEL10_C + } else { + PIXEL00_5 + PIXEL01_6 + PIXEL02_2 + PIXEL10_1 + } + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_1 + PIXEL22_2 + break; + case 67: + PIXEL00_1L + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1M + break; + case 70: + PIXEL00_1M + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1M + break; + case 28: + PIXEL00_1M + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1M + break; + case 152: + PIXEL00_1M + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1D + break; + case 194: + PIXEL00_1M + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1R + break; + case 98: + PIXEL00_1M + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1M + break; + case 56: + PIXEL00_1M + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1M + break; + case 25: + PIXEL00_1U + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1M + break; + case 26: + case 31: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL10_3 + } + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_C + PIXEL12_C + } else { + PIXEL02_4 + PIXEL12_3 + } + PIXEL11 + PIXEL20_1M + PIXEL21_1 + PIXEL22_1M + break; + case 82: + case 214: + PIXEL00_1M + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_C + PIXEL02_C + } else { + PIXEL01_3 + PIXEL02_4 + } + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_1M + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL21_C + PIXEL22_C + } else { + PIXEL21_3 + PIXEL22_4 + } + break; + case 88: + case 248: + PIXEL00_1M + PIXEL01_1 + PIXEL02_1M + PIXEL11 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_C + PIXEL20_C + } else { + PIXEL10_3 + PIXEL20_4 + } + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL12_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL22_4 + } + break; + case 74: + case 107: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL01_C + } else { + PIXEL00_4 + PIXEL01_3 + } + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_1 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_C + PIXEL21_C + } else { + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + case 27: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + PIXEL02_1M + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1M + break; + case 86: + PIXEL00_1M + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_1 + PIXEL11 + PIXEL20_1M + PIXEL21_C + PIXEL22_1M + break; + case 216: + PIXEL00_1M + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL20_1M + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + case 106: + PIXEL00_1M + PIXEL01_C + PIXEL02_1M + PIXEL11 + PIXEL12_1 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + case 30: + PIXEL00_1M + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_C + PIXEL11 + PIXEL20_1M + PIXEL21_1 + PIXEL22_1M + break; + case 210: + PIXEL00_1M + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL20_1M + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + case 120: + PIXEL00_1M + PIXEL01_1 + PIXEL02_1M + PIXEL11 + PIXEL12_C + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + case 75: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + PIXEL02_1M + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1M + break; + case 29: + PIXEL00_1U + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1M + break; + case 198: + PIXEL00_1M + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1R + break; + case 184: + PIXEL00_1M + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1D + break; + case 99: + PIXEL00_1L + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1M + break; + case 57: + PIXEL00_1U + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1M + break; + case 71: + PIXEL00_1L + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1M + break; + case 156: + PIXEL00_1M + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1D + break; + case 226: + PIXEL00_1M + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1R + break; + case 60: + PIXEL00_1M + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1M + break; + case 195: + PIXEL00_1L + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1R + break; + case 102: + PIXEL00_1M + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1M + break; + case 153: + PIXEL00_1U + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1D + break; + case 58: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1M + break; + case 83: + PIXEL00_1L + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + case 92: + PIXEL00_1M + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + case 202: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_1 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + PIXEL22_1R + break; + case 78: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + PIXEL02_1R + PIXEL10_C + PIXEL11 + PIXEL12_1 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + PIXEL22_1M + break; + case 154: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1D + break; + case 114: + PIXEL00_1M + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_1L + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + case 89: + PIXEL00_1U + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + case 90: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_C + PIXEL11 + PIXEL12_C + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + case 55: + case 23: + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL00_1L + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL00_2 + PIXEL01_6 + PIXEL02_5 + PIXEL12_1 + } + PIXEL10_1 + PIXEL11 + PIXEL20_2 + PIXEL21_1 + PIXEL22_1M + break; + case 182: + case 150: + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + PIXEL22_1D + } else { + PIXEL01_1 + PIXEL02_5 + PIXEL12_6 + PIXEL22_2 + } + PIXEL00_1M + PIXEL10_1 + PIXEL11 + PIXEL20_2 + PIXEL21_1 + break; + case 213: + case 212: + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL02_1U + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL02_2 + PIXEL12_6 + PIXEL21_1 + PIXEL22_5 + } + PIXEL00_2 + PIXEL01_1 + PIXEL10_1 + PIXEL11 + PIXEL20_1M + break; + case 241: + case 240: + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL12_C + PIXEL20_1L + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_1 + PIXEL20_2 + PIXEL21_6 + PIXEL22_5 + } + PIXEL00_2 + PIXEL01_1 + PIXEL02_1M + PIXEL10_1 + PIXEL11 + break; + case 236: + case 232: + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + PIXEL22_1R + } else { + PIXEL10_1 + PIXEL20_5 + PIXEL21_6 + PIXEL22_2 + } + PIXEL00_1M + PIXEL01_1 + PIXEL02_2 + PIXEL11 + PIXEL12_1 + break; + case 109: + case 105: + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL00_1U + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL00_2 + PIXEL10_6 + PIXEL20_5 + PIXEL21_1 + } + PIXEL01_1 + PIXEL02_2 + PIXEL11 + PIXEL12_1 + PIXEL22_1M + break; + case 171: + case 43: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + PIXEL20_1D + } else { + PIXEL00_5 + PIXEL01_1 + PIXEL10_6 + PIXEL20_2 + } + PIXEL02_1M + PIXEL11 + PIXEL12_1 + PIXEL21_1 + PIXEL22_2 + break; + case 143: + case 15: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL01_C + PIXEL02_1R + PIXEL10_C + } else { + PIXEL00_5 + PIXEL01_6 + PIXEL02_2 + PIXEL10_1 + } + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_1 + PIXEL22_2 + break; + case 124: + PIXEL00_1M + PIXEL01_1 + PIXEL02_1U + PIXEL11 + PIXEL12_C + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + case 203: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + PIXEL02_1M + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1R + break; + case 62: + PIXEL00_1M + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_C + PIXEL11 + PIXEL20_1D + PIXEL21_1 + PIXEL22_1M + break; + case 211: + PIXEL00_1L + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL20_1M + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + case 118: + PIXEL00_1M + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_1 + PIXEL11 + PIXEL20_1L + PIXEL21_C + PIXEL22_1M + break; + case 217: + PIXEL00_1U + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL20_1M + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + case 110: + PIXEL00_1M + PIXEL01_C + PIXEL02_1R + PIXEL11 + PIXEL12_1 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + case 155: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + PIXEL02_1M + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1D + break; + case 188: + PIXEL00_1M + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1D + break; + case 185: + PIXEL00_1U + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1D + break; + case 61: + PIXEL00_1U + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1M + break; + case 157: + PIXEL00_1U + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1D + break; + case 103: + PIXEL00_1L + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1M + break; + case 227: + PIXEL00_1L + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1R + break; + case 230: + PIXEL00_1M + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1R + break; + case 199: + PIXEL00_1L + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1R + break; + case 220: + PIXEL00_1M + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_1M + } else { + PIXEL20_2 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + case 158: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_1M + } else { + PIXEL00_2 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_C + PIXEL11 + PIXEL20_1M + PIXEL21_1 + PIXEL22_1D + break; + case 234: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + PIXEL02_1M + PIXEL11 + PIXEL12_1 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1R + break; + case 242: + PIXEL00_1M + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_1 + PIXEL11 + PIXEL20_1L + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + case 59: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1M + break; + case 121: + PIXEL00_1U + PIXEL01_1 + PIXEL02_1M + PIXEL11 + PIXEL12_C + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + case 87: + PIXEL00_1L + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_1 + PIXEL11 + PIXEL20_1M + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + case 79: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + PIXEL02_1R + PIXEL11 + PIXEL12_1 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + PIXEL22_1M + break; + case 122: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL11 + PIXEL12_C + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + case 94: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_1M + } else { + PIXEL00_2 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_C + PIXEL11 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + case 218: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_C + PIXEL11 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_1M + } else { + PIXEL20_2 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + case 91: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL11 + PIXEL12_C + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + case 229: + PIXEL00_2 + PIXEL01_1 + PIXEL02_2 + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1R + break; + case 167: + PIXEL00_1L + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_2 + PIXEL21_1 + PIXEL22_2 + break; + case 173: + PIXEL00_1U + PIXEL01_1 + PIXEL02_2 + PIXEL10_C + PIXEL11 + PIXEL12_1 + PIXEL20_1D + PIXEL21_1 + PIXEL22_2 + break; + case 181: + PIXEL00_2 + PIXEL01_1 + PIXEL02_1U + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_2 + PIXEL21_1 + PIXEL22_1D + break; + case 186: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1D + break; + case 115: + PIXEL00_1L + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_1L + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + case 93: + PIXEL00_1U + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + case 206: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + PIXEL02_1R + PIXEL10_C + PIXEL11 + PIXEL12_1 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + PIXEL22_1R + break; + case 205: + case 201: + PIXEL00_1U + PIXEL01_1 + PIXEL02_2 + PIXEL10_C + PIXEL11 + PIXEL12_1 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + PIXEL22_1R + break; + case 174: + case 46: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + PIXEL02_1R + PIXEL10_C + PIXEL11 + PIXEL12_1 + PIXEL20_1D + PIXEL21_1 + PIXEL22_2 + break; + case 179: + case 147: + PIXEL00_1L + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_2 + PIXEL21_1 + PIXEL22_1D + break; + case 117: + case 116: + PIXEL00_2 + PIXEL01_1 + PIXEL02_1U + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_1L + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + case 189: + PIXEL00_1U + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1D + break; + case 231: + PIXEL00_1L + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1R + break; + case 126: + PIXEL00_1M + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL11 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + case 219: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + PIXEL02_1M + PIXEL11 + PIXEL20_1M + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + case 125: + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL00_1U + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL00_2 + PIXEL10_6 + PIXEL20_5 + PIXEL21_1 + } + PIXEL01_1 + PIXEL02_1U + PIXEL11 + PIXEL12_C + PIXEL22_1M + break; + case 221: + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL02_1U + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL02_2 + PIXEL12_6 + PIXEL21_1 + PIXEL22_5 + } + PIXEL00_1U + PIXEL01_1 + PIXEL10_C + PIXEL11 + PIXEL20_1M + break; + case 207: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL01_C + PIXEL02_1R + PIXEL10_C + } else { + PIXEL00_5 + PIXEL01_6 + PIXEL02_2 + PIXEL10_1 + } + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1R + break; + case 238: + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + PIXEL22_1R + } else { + PIXEL10_1 + PIXEL20_5 + PIXEL21_6 + PIXEL22_2 + } + PIXEL00_1M + PIXEL01_C + PIXEL02_1R + PIXEL11 + PIXEL12_1 + break; + case 190: + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + PIXEL22_1D + } else { + PIXEL01_1 + PIXEL02_5 + PIXEL12_6 + PIXEL22_2 + } + PIXEL00_1M + PIXEL10_C + PIXEL11 + PIXEL20_1D + PIXEL21_1 + break; + case 187: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + PIXEL20_1D + } else { + PIXEL00_5 + PIXEL01_1 + PIXEL10_6 + PIXEL20_2 + } + PIXEL02_1M + PIXEL11 + PIXEL12_C + PIXEL21_1 + PIXEL22_1D + break; + case 243: + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL12_C + PIXEL20_1L + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_1 + PIXEL20_2 + PIXEL21_6 + PIXEL22_5 + } + PIXEL00_1L + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + break; + case 119: + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL00_1L + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL00_2 + PIXEL01_6 + PIXEL02_5 + PIXEL12_1 + } + PIXEL10_1 + PIXEL11 + PIXEL20_1L + PIXEL21_C + PIXEL22_1M + break; + case 237: + case 233: + PIXEL00_1U + PIXEL01_1 + PIXEL02_2 + PIXEL10_C + PIXEL11 + PIXEL12_1 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_C + } else { + PIXEL20_2 + } + PIXEL21_C + PIXEL22_1R + break; + case 175: + case 47: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + } else { + PIXEL00_2 + } + PIXEL01_C + PIXEL02_1R + PIXEL10_C + PIXEL11 + PIXEL12_1 + PIXEL20_1D + PIXEL21_1 + PIXEL22_2 + break; + case 183: + case 151: + PIXEL00_1L + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_C + } else { + PIXEL02_2 + } + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_2 + PIXEL21_1 + PIXEL22_1D + break; + case 245: + case 244: + PIXEL00_2 + PIXEL01_1 + PIXEL02_1U + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_1L + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_C + } else { + PIXEL22_2 + } + break; + case 250: + PIXEL00_1M + PIXEL01_C + PIXEL02_1M + PIXEL11 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_C + PIXEL20_C + } else { + PIXEL10_3 + PIXEL20_4 + } + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL12_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL22_4 + } + break; + case 123: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL01_C + } else { + PIXEL00_4 + PIXEL01_3 + } + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_C + PIXEL21_C + } else { + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + case 95: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL10_3 + } + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_C + PIXEL12_C + } else { + PIXEL02_4 + PIXEL12_3 + } + PIXEL11 + PIXEL20_1M + PIXEL21_C + PIXEL22_1M + break; + case 222: + PIXEL00_1M + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_C + PIXEL02_C + } else { + PIXEL01_3 + PIXEL02_4 + } + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL21_C + PIXEL22_C + } else { + PIXEL21_3 + PIXEL22_4 + } + break; + case 252: + PIXEL00_1M + PIXEL01_1 + PIXEL02_1U + PIXEL11 + PIXEL12_C + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_C + PIXEL20_C + } else { + PIXEL10_3 + PIXEL20_4 + } + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_C + } else { + PIXEL22_2 + } + break; + case 249: + PIXEL00_1U + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_C + } else { + PIXEL20_2 + } + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL12_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL22_4 + } + break; + case 235: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL01_C + } else { + PIXEL00_4 + PIXEL01_3 + } + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_1 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_C + } else { + PIXEL20_2 + } + PIXEL21_C + PIXEL22_1R + break; + case 111: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + } else { + PIXEL00_2 + } + PIXEL01_C + PIXEL02_1R + PIXEL10_C + PIXEL11 + PIXEL12_1 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_C + PIXEL21_C + } else { + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + case 63: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + } else { + PIXEL00_2 + } + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_C + PIXEL12_C + } else { + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_C + PIXEL11 + PIXEL20_1D + PIXEL21_1 + PIXEL22_1M + break; + case 159: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL10_3 + } + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_C + } else { + PIXEL02_2 + } + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1D + break; + case 215: + PIXEL00_1L + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_C + } else { + PIXEL02_2 + } + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_1M + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL21_C + PIXEL22_C + } else { + PIXEL21_3 + PIXEL22_4 + } + break; + case 246: + PIXEL00_1M + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_C + PIXEL02_C + } else { + PIXEL01_3 + PIXEL02_4 + } + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_1L + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_C + } else { + PIXEL22_2 + } + break; + case 254: + PIXEL00_1M + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_C + PIXEL02_C + } else { + PIXEL01_3 + PIXEL02_4 + } + PIXEL11 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_C + PIXEL20_C + } else { + PIXEL10_3 + PIXEL20_4 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_2 + } + break; + case 253: + PIXEL00_1U + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_C + } else { + PIXEL20_2 + } + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_C + } else { + PIXEL22_2 + } + break; + case 251: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL01_C + } else { + PIXEL00_4 + PIXEL01_3 + } + PIXEL02_1M + PIXEL11 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_2 + PIXEL21_3 + } + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL12_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL22_4 + } + break; + case 239: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + } else { + PIXEL00_2 + } + PIXEL01_C + PIXEL02_1R + PIXEL10_C + PIXEL11 + PIXEL12_1 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_C + } else { + PIXEL20_2 + } + PIXEL21_C + PIXEL22_1R + break; + case 127: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_2 + PIXEL01_3 + PIXEL10_3 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_C + PIXEL12_C + } else { + PIXEL02_4 + PIXEL12_3 + } + PIXEL11 + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_C + PIXEL21_C + } else { + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + case 191: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + } else { + PIXEL00_2 + } + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_C + } else { + PIXEL02_2 + } + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1D + break; + case 223: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL10_3 + } + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_2 + PIXEL12_3 + } + PIXEL11 + PIXEL20_1M + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL21_C + PIXEL22_C + } else { + PIXEL21_3 + PIXEL22_4 + } + break; + case 247: + PIXEL00_1L + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_C + } else { + PIXEL02_2 + } + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_1L + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_C + } else { + PIXEL22_2 + } + break; + case 255: + if (diffYUV(RGBtoYUV(C3), RGBtoYUV(C1))) { + PIXEL00_C + } else { + PIXEL00_2 + } + PIXEL01_C + if (diffYUV(RGBtoYUV(C1), RGBtoYUV(C5))) { + PIXEL02_C + } else { + PIXEL02_2 + } + PIXEL10_C + PIXEL11 + PIXEL12_C + if (diffYUV(RGBtoYUV(C7), RGBtoYUV(C3))) { + PIXEL20_C + } else { + PIXEL20_2 + } + PIXEL21_C + if (diffYUV(RGBtoYUV(C5), RGBtoYUV(C7))) { + PIXEL22_C + } else { + PIXEL22_2 + } + break; + } +} + +#undef RGBtoYUV diff --git a/src/gui/render_templates_sai.h b/src/gui/render_templates_sai.h new file mode 100644 index 00000000..8f938571 --- /dev/null +++ b/src/gui/render_templates_sai.h @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2002-2006 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. + */ + +static inline int conc2d(GetResult,SBPP)(PTYPE A, PTYPE B, PTYPE C, PTYPE D) { + const bool ac = (A==C); + const bool bc = (B==C); + const int x1 = ac; + const int y1 = (bc & !ac); + const bool ad = (A==D); + const bool bd = (B==D); + const int x2 = ad; + const int y2 = (bd & !ad); + const int x = x1+x2; + const int y = y1+y2; + static const int rmap[3][3] = { + {0, 0, -1}, + {0, 0, -1}, + {1, 1, 0} + }; + return rmap[y][x]; +} + +inline void conc2d(Super2xSaI,SBPP)(PTYPE * line0, PTYPE * line1, const PTYPE * fc) +{ + //-------------------------------------- + if (C7 == C5 && C4 != C8) { + line1[1] = line0[1] = C7; + } else if (C4 == C8 && C7 != C5) { + line1[1] = line0[1] = C4; + } else if (C4 == C8 && C7 == C5) { + register int r = 0; + r += conc2d(GetResult,SBPP)(C5,C4,C6,D1); + r += conc2d(GetResult,SBPP)(C5,C4,C3,C1); + r += conc2d(GetResult,SBPP)(C5,C4,D2,D5); + r += conc2d(GetResult,SBPP)(C5,C4,C2,D4); + + if (r > 0) + line1[1] = line0[1] = C5; + else if (r < 0) + line1[1] = line0[1] = C4; + else { + line1[1] = line0[1] = interp_w2(C4,C5,1U,1U); + } + } else { + if (C5 == C8 && C8 == D1 && C7 != D2 && C8 != D0) + line1[1] = interp_w2(C8,C7,3U,1U); + else if (C4 == C7 && C7 == D2 && D1 != C8 && C7 != D6) + line1[1] = interp_w2(C7,C8,3U,1U); + else + line1[1] = interp_w2(C7,C8,1U,1U); + + if (C5 == C8 && C5 == C1 && C4 != C2 && C5 != C0) + line0[1] = interp_w2(C5,C4,3U,1U); + else if (C4 == C7 && C4 == C2 && C1 != C5 && C4 != D3) + line0[1] = interp_w2(C4,C5,3U,1U); + else + line0[1] = interp_w2(C4,C5,1U,1U); + } + + if (C4 == C8 && C7 != C5 && C3 == C4 && C4 != D2) + line1[0] = interp_w2(C7,C4,1U,1U); + else if (C4 == C6 && C5 == C4 && C3 != C7 && C4 != D0) + line1[0] = interp_w2(C7,C4,1U,1U); + else + line1[0] = C7; + + if (C7 == C5 && C4 != C8 && C6 == C7 && C7 != C2) + line0[0] = interp_w2(C7,C4,1U,1U); + else if (C3 == C7 && C8 == C7 && C6 != C4 && C7 != C0) + line0[0] = interp_w2(C7,C4,1U,1U); + else + line0[0] = C4; +} + +inline void conc2d(SuperEagle,SBPP)(PTYPE * line0, PTYPE * line1, const PTYPE * fc) +{ + // -------------------------------------- + if (C4 != C8) { + if (C7 == C5) { + line0[1] = line1[0] = C7; + if ((C6 == C7) || (C5 == C2)) { + line0[0] = interp_w2(C7,C4,3U,1U); + } else { + line0[0] = interp_w2(C4,C5,1U,1U); + } + + if ((C5 == D4) || (C7 == D1)) { + line1[1] = interp_w2(C7,C8,3U,1U); + } else { + line1[1] = interp_w2(C7,C8,1U,1U); + } + } else { + line1[1] = interp_w3(C8,C7,C5,6U,1U,1U); + line0[0] = interp_w3(C4,C7,C5,6U,1U,1U); + + line1[0] = interp_w3(C7,C4,C8,6U,1U,1U); + line0[1] = interp_w3(C5,C4,C8,6U,1U,1U); + } + } else { + if (C7 != C5) { + line1[1] = line0[0] = C4; + + if ((C1 == C4) || (C8 == D5)) { + line0[1] = interp_w2(C4,C5,3U,1U); + } else { + line0[1] = interp_w2(C4,C5,1U,1U); + } + + if ((C8 == D2) || (C3 == C4)) { + line1[0] = interp_w2(C4,C7,3U,1U); + } else { + line1[0] = interp_w2(C7,C8,1U,1U); + } + } else { + register int r = 0; + r += conc2d(GetResult,SBPP)(C5,C4,C6,D1); + r += conc2d(GetResult,SBPP)(C5,C4,C3,C1); + r += conc2d(GetResult,SBPP)(C5,C4,D2,D5); + r += conc2d(GetResult,SBPP)(C5,C4,C2,D4); + + if (r > 0) { + line0[1] = line1[0] = C7; + line0[0] = line1[1] = interp_w2(C4,C5,1U,1U); + } else if (r < 0) { + line1[1] = line0[0] = C4; + line0[1] = line1[0] = interp_w2(C4,C5,1U,1U); + } else { + line1[1] = line0[0] = C4; + line0[1] = line1[0] = C7; + } + } + } +} + +inline void conc2d(_2xSaI,SBPP)(PTYPE * line0, PTYPE * line1, const PTYPE * fc) +{ + if ((C4 == C8) && (C5 != C7)) { + if (((C4 == C1) && (C5 == D5)) || + ((C4 == C7) && (C4 == C2) && (C5 != C1) && (C5 == D3))) { + line0[1] = C4; + } else { + line0[1] = interp_w2(C4,C5,1U,1U); + } + + if (((C4 == C3) && (C7 == D2)) || + ((C4 == C5) && (C4 == C6) && (C3 != C7) && (C7 == D0))) { + line1[0] = C4; + } else { + line1[0] = interp_w2(C4,C7,1U,1U); + } + line1[1] = C4; + } else if ((C5 == C7) && (C4 != C8)) { + if (((C5 == C2) && (C4 == C6)) || + ((C5 == C1) && (C5 == C8) && (C4 != C2) && (C4 == C0))) { + line0[1] = C5; + } else { + line0[1] = interp_w2(C4,C5,1U,1U); + } + + if (((C7 == C6) && (C4 == C2)) || + ((C7 == C3) && (C7 == C8) && (C4 != C6) && (C4 == C0))) { + line1[0] = C7; + } else { + line1[0] = interp_w2(C4,C7,1U,1U); + } + line1[1] = C5; + } else if ((C4 == C8) && (C5 == C7)) { + if (C4 == C5) { + line0[1] = C4; + line1[0] = C4; + line1[1] = C4; + } else { + register int r = 0; + r += conc2d(GetResult,SBPP)(C4,C5,C3,C1); + r -= conc2d(GetResult,SBPP)(C5,C4,D4,C2); + r -= conc2d(GetResult,SBPP)(C5,C4,C6,D1); + r += conc2d(GetResult,SBPP)(C4,C5,D5,D2); + + if (r > 0) + line1[1] = C4; + else if (r < 0) + line1[1] = C5; + else { + line1[1] = interp_w4(C4,C5,C7,C8,1U,1U,1U,1U); + } + + line1[0] = interp_w2(C4,C7,1U,1U); + line0[1] = interp_w2(C4,C5,1U,1U); + } + } else { + line1[1] = interp_w4(C4,C5,C7,C8,1U,1U,1U,1U); + + if ((C4 == C7) && (C4 == C2) + && (C5 != C1) && (C5 == D3)) { + line0[1] = C4; + } else if ((C5 == C1) && (C5 == C8) + && (C4 != C2) && (C4 == C0)) { + line0[1] = C5; + } else { + line0[1] = interp_w2(C4,C5,1U,1U); + } + + if ((C4 == C5) && (C4 == C6) + && (C3 != C7) && (C7 == D0)) { + line1[0] = C4; + } else if ((C7 == C3) && (C7 == C8) + && (C4 != C6) && (C4 == C0)) { + line1[0] = C7; + } else { + line1[0] = interp_w2(C4,C7,1U,1U); + } + } + line0[0] = C4; +} From 46226e685ad0ce8ebedd59090f1347f7b15ec65a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 5 Aug 2006 10:39:44 +0000 Subject: [PATCH 2598/4131] Fix bug: "1328858 cd .. from root directory causes crash" Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2683 --- src/dos/dos_files.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index e6817cc5..a2208227 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.77 2006-07-18 15:31:29 c2woody Exp $ */ +/* $Id: dos_files.cpp,v 1.78 2006-08-05 10:39:44 qbix79 Exp $ */ #include #include @@ -122,7 +122,7 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { continue; } - Bit32u iDown, cDots; + Bit32s iDown, cDots; bool dots = true; Bit32u templen =strlen(tempdir); for(iDown=0;(iDown < templen) && dots;iDown++) From 190e290e83f33edb744aa27a2c80ac04c253de10 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 6 Aug 2006 19:43:14 +0000 Subject: [PATCH 2599/4131] Small error. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2684 --- src/gui/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 17819379..6efa58f9 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -4,7 +4,7 @@ noinst_LIBRARIES = libgui.a libgui_a_SOURCES = sdlmain.cpp sdl_mapper.cpp dosbox_logo.h \ render.cpp render_scalers.cpp render_scalers.h \ render_templates.h render_loops.h render_simple.h \ - render_templates_hq.h render_templates_hq.h \ + render_templates_sai.h render_templates_hq.h \ render_templates_hq2x.h render_templates_hq3x.h \ midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h midi_alsa.h From 5f90852ff6d9210fdef9dc41fba1af7261f0cbcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 8 Aug 2006 20:11:43 +0000 Subject: [PATCH 2600/4131] disable some vs2005 warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2685 --- src/platform/visualc/config.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 06e87ca5..ca48fead 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -54,6 +54,10 @@ #define GCC_ATTRIBUTE(x) /* attribute not supported */ #define GCC_UNLIKELY(x) (x) +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma warning(disable : 4996) +#endif + typedef double Real64; /* The internal types */ typedef unsigned char Bit8u; From 7a452cbf72a0ea6038d87ad16d5ab6ac08f64756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 16 Aug 2006 16:08:24 +0000 Subject: [PATCH 2601/4131] prevent rare crashes when forcing sb16 when no second dma controller is present Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2686 --- src/hardware/sblaster.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 561df6a1..dd2efd4b 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.54 2006-06-29 19:05:54 qbix79 Exp $ */ +/* $Id: sblaster.cpp,v 1.55 2006-08-16 16:08:24 c2woody Exp $ */ #include #include @@ -591,8 +591,14 @@ static void DSP_PrepareDMA_New(DMA_MODES mode,Bitu length,bool autoinit,bool ste sb.dma.total=length; sb.dma.autoinit=autoinit; if (mode==DSP_DMA_16) { - if (sb.hw.dma16!=0xff) sb.dma.chan=GetDMAChannel(sb.hw.dma16); - else { + if (sb.hw.dma16!=0xff) { + sb.dma.chan=GetDMAChannel(sb.hw.dma16); + if (sb.dma.chan==NULL) { + sb.dma.chan=GetDMAChannel(sb.hw.dma8); + mode=DSP_DMA_16_ALIASED; + freq/=2; + } + } else { sb.dma.chan=GetDMAChannel(sb.hw.dma8); mode=DSP_DMA_16_ALIASED; freq/=2; From 181f65ee5f0e8a2c88e0be99cb5e65948994e6e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 17 Aug 2006 12:07:22 +0000 Subject: [PATCH 2602/4131] adapt FindFirst to support mscdex behaviour of cdrom label searches Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2687 --- src/dos/drive_local.cpp | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index fb5a7988..a9ebcfe8 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.70 2006-08-01 20:57:28 c2woody Exp $ */ +/* $Id: drive_local.cpp,v 1.71 2006-08-17 12:07:22 c2woody Exp $ */ #include #include @@ -208,23 +208,31 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) { Bit8u sAttr; dta.GetSearchParams(sAttr,tempDir); - if (sAttr == DOS_ATTR_VOLUME) { - if ( strcmp(dirCache.GetLabel(), "") == 0 ) { -// LOG(LOG_DOSMISC,LOG_ERROR)("DRIVELABEL REQUESTED: none present, returned NOLABEL"); -// dta.SetResult("NO_LABEL",0,0,0,DOS_ATTR_VOLUME); -// return true; - DOS_SetError(DOSERR_NO_MORE_FILES); - return false; - } - dta.SetResult(dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME); - return true; - } else if ((sAttr & DOS_ATTR_VOLUME) && (*_dir == 0) && !fcb_findfirst) { - //should check for a valid leading directory instead of 0 - //exists==true if the volume label matches the searchmask and the path is valid - if (WildFileCmp(dirCache.GetLabel(),tempDir)) { + if (this->isRemote() && this->isRemovable()) { + // cdroms behave a bit different than regular drives + if (sAttr == DOS_ATTR_VOLUME) { dta.SetResult(dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME); return true; } + } else { + if (sAttr == DOS_ATTR_VOLUME) { + if ( strcmp(dirCache.GetLabel(), "") == 0 ) { +// LOG(LOG_DOSMISC,LOG_ERROR)("DRIVELABEL REQUESTED: none present, returned NOLABEL"); +// dta.SetResult("NO_LABEL",0,0,0,DOS_ATTR_VOLUME); +// return true; + DOS_SetError(DOSERR_NO_MORE_FILES); + return false; + } + dta.SetResult(dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME); + return true; + } else if ((sAttr & DOS_ATTR_VOLUME) && (*_dir == 0) && !fcb_findfirst) { + //should check for a valid leading directory instead of 0 + //exists==true if the volume label matches the searchmask and the path is valid + if (WildFileCmp(dirCache.GetLabel(),tempDir)) { + dta.SetResult(dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME); + return true; + } + } } return FindNext(dta); } From af59fbc915e078037f961daf099c182e484d2213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 18 Aug 2006 18:23:02 +0000 Subject: [PATCH 2603/4131] fix int15 returnflags for unimplemented functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2688 --- src/ints/bios.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 6f6fa121..258122c2 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.62 2006-07-24 19:06:55 c2woody Exp $ */ +/* $Id: bios.cpp,v 1.63 2006-08-18 18:23:02 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -707,10 +707,6 @@ static Bitu INT15_Handler(void) { CALLBACK_SCF(false); reg_ah=0; break; - case 0xc3: /* set carry flag so BorlandRTM doesn't assume a VECTRA/PS2 */ - reg_ah=0x86; - CALLBACK_SCF(true); - break; case 0xc2: /* BIOS PS2 Pointing Device Support */ switch (reg_al) { case 0x00: // enable/disable @@ -769,6 +765,10 @@ static Bitu INT15_Handler(void) { break; } break; + case 0xc3: /* set carry flag so BorlandRTM doesn't assume a VECTRA/PS2 */ + reg_ah=0x86; + CALLBACK_SCF(true); + break; case 0xc4: /* BIOS POS Programm option Select */ LOG(LOG_BIOS,LOG_NORMAL)("INT15:Function %X called, bios mouse not supported",reg_ah); CALLBACK_SCF(true); @@ -776,7 +776,11 @@ static Bitu INT15_Handler(void) { default: LOG(LOG_BIOS,LOG_ERROR)("INT15:Unknown call %4X",reg_ax); reg_ah=0x86; - CALLBACK_SCF(false); + CALLBACK_SCF(true); + if ((machine==MCH_VGA) || (machine==MCH_CGA)) { + /* relict from comparisons, as int15 exits with a retf2 instead of an iret */ + CALLBACK_SZF(false); + } } return CBRET_NONE; } From 2bb31be5325a03784e119a01bfbbcde11c074766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 20 Aug 2006 15:41:55 +0000 Subject: [PATCH 2604/4131] update readme Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2689 --- README | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README b/README index 1a6eac88..6ce98d72 100644 --- a/README +++ b/README @@ -88,7 +88,7 @@ A: To mount your CD-ROM in DOSBox you have to specify some additional options To enable low-level ioctl-support(win2k/xp/linux): - mount d f:\ -t cdrom -usecd 0 -ioctl To enable low-level aspi-support (win98 with aspi-layer installed): - - mount d f:\ -t cdrom -usecd 0 -apsi + - mount d f:\ -t cdrom -usecd 0 -aspi In the commands: - d driveletter you will get in DOSBox - f:\ location of cdrom on your PC. @@ -513,8 +513,11 @@ BOOT Boot will start floppy images or hard disk images independent of the operating system emulation offered by DOSBox. This will allow you to play booter floppies or boot to other operating systems inside DOSBox. + If the target emulated system is PCJr (machine=pcjr) the boot-command + can be used to load PCJr cartridges (.jrc). BOOT [diskimg1.img diskimg2.img .. diskimgN.img] [-l driveletter] + BOOT [cart.jrc] (PCJr only) diskimgN.img This can be any number of floppy disk images one wants mounted after @@ -619,8 +622,8 @@ ALT-ENTER Switch to full screen and back. ALT-PAUSE Pause emulation. CTRL-F1 Start the keymapper. CTRL-F4 Change between mounted disk-images. Update directory cache for all drives! -CTRL-ALT-F5 Start/Stop creating a movie of the screen. -CTRL-F5 Save a screenshot.(png) +CTRL-ALT-F5 Start/Stop creating a movie of the screen. (avi video capturing) +CTRL-F5 Save a screenshot. (png) CTRL-F6 Start/Stop recording sound output to a wave file. CTRL-ALT-F7 Start/Stop recording of OPL commands. CTRL-ALT-F8 Start/Stop the recording of raw MIDI commands. From be9a70adfdfbfd710992b9663a8c9d0e5a8b08b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 21 Aug 2006 20:08:26 +0000 Subject: [PATCH 2605/4131] fix unsigned 16bit samples sb16 output Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2690 --- include/mixer.h | 4 +++- src/hardware/mixer.cpp | 36 ++++++++++++++++++++++++++---------- src/hardware/sblaster.cpp | 5 +++-- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/include/mixer.h b/include/mixer.h index c778bf5d..af232b99 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -50,12 +50,14 @@ public: void SetFreq(Bitu _freq); void Mix(Bitu _needed); void AddSilence(void); //Fill up until needed - template + template void AddSamples(Bitu len,void * data); void AddSamples_m8(Bitu len,Bit8u * data); void AddSamples_s8(Bitu len,Bit8u * data); void AddSamples_m16(Bitu len,Bit16s * data); void AddSamples_s16(Bitu len,Bit16s * data); + void AddSamples_m16u(Bitu len,Bit16u * data); + void AddSamples_s16u(Bitu len,Bit16u * data); void AddStretched(Bitu len,Bit16s * data); //Strech block up into needed data void FillUp(void); void Enable(bool _yesno); diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 9fac2291..d2f4db11 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.40 2006-05-18 11:32:09 qbix79 Exp $ */ +/* $Id: mixer.cpp,v 1.41 2006-08-21 20:08:26 c2woody Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -178,11 +178,12 @@ void MixerChannel::AddSilence(void) { } } -template +template INLINE void MixerChannel::AddSamples(Bitu len,void * data) { Bits diff[2]; Bit8u * data8=(Bit8u*)data; Bit16s * data16=(Bit16s*)data; + Bit16u * data16u=(Bit16u*)data; Bitu mixpos=mixer.pos+done; freq_index&=MIXER_REMAIN; Bitu pos=0;Bitu new_pos; @@ -204,11 +205,20 @@ thestart: diff[0]=(((Bit8s)(data8[pos] ^ 0x80)) << 8)-last[0]; } } else { - if (stereo) { - diff[0]=data16[pos*2+0]-last[0]; - diff[1]=data16[pos*2+1]-last[1]; + if (signeddata) { + if (stereo) { + diff[0]=data16[pos*2+0]-last[0]; + diff[1]=data16[pos*2+1]-last[1]; + } else { + diff[0]=data16[pos]-last[0]; + } } else { - diff[0]=data16[pos]-last[0]; + if (stereo) { + diff[0]=data16u[pos*2+0]-last[0]; + diff[1]=data16u[pos*2+1]-last[1]; + } else { + diff[0]=data16u[pos]-last[0]; + } } } } @@ -252,16 +262,22 @@ void MixerChannel::AddStretched(Bitu len,Bit16s * data) { }; void MixerChannel::AddSamples_m8(Bitu len,Bit8u * data) { - AddSamples(len,data); + AddSamples(len,data); } void MixerChannel::AddSamples_s8(Bitu len,Bit8u * data) { - AddSamples(len,data); + AddSamples(len,data); } void MixerChannel::AddSamples_m16(Bitu len,Bit16s * data) { - AddSamples(len,data); + AddSamples(len,data); } void MixerChannel::AddSamples_s16(Bitu len,Bit16s * data) { - AddSamples(len,data); + AddSamples(len,data); +} +void MixerChannel::AddSamples_m16u(Bitu len,Bit16u * data) { + AddSamples(len,data); +} +void MixerChannel::AddSamples_s16u(Bitu len,Bit16u * data) { + AddSamples(len,data); } void MixerChannel::FillUp(void) { diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index dd2efd4b..805bed23 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.55 2006-08-16 16:08:24 c2woody Exp $ */ +/* $Id: sblaster.cpp,v 1.56 2006-08-21 20:08:26 c2woody Exp $ */ #include #include @@ -418,7 +418,8 @@ static void GenerateDMASound(Bitu size) { if (sb.dma.stereo) { read=sb.dma.chan->Read(size,(Bit8u *)&sb.dma.buf.b16[sb.dma.remain_size]); Bitu total=read+sb.dma.remain_size; - sb.chan->AddSamples_s16(total>>1,sb.dma.buf.b16); + if (sb.dma.sign) sb.chan->AddSamples_s16(total>>1,sb.dma.buf.b16); + else sb.chan->AddSamples_s16u(total>>1,(Bit16u *)sb.dma.buf.b16); if (total&1) { sb.dma.remain_size=1; sb.dma.buf.b16[0]=sb.dma.buf.b16[total-1]; From 85603ac5eb3ca5ca4f0a59f8ca2b5f424cd9fba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 23 Aug 2006 20:09:52 +0000 Subject: [PATCH 2606/4131] fix odd situation where searchslot overrunning was not detected (see sf bug #1543663) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2691 --- src/dos/drive_cache.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index adff3b51..056731be 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.47 2006-04-10 12:52:47 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.48 2006-08-23 20:09:52 c2woody Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -690,11 +690,13 @@ bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bit16u entryNr) bool DOS_Drive_Cache::FindFirst(char* path, Bitu& id) { Bit16u dirID; - Bitu dirFindFirstID = this->nextFreeFindFirst++; //increase it for the next search + Bitu dirFindFirstID = this->nextFreeFindFirst; // Cache directory in if (!OpenDir(path,dirID)) return false; + this->nextFreeFindFirst++; //increase it for the next search + if (dirFindFirstID == MAX_OPENDIRS) { // no free slot found... LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst/Next: All slots full. Resetting"); From e11274fe6e3c276a3087c0a6d3855515b2154e72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 25 Aug 2006 09:40:19 +0000 Subject: [PATCH 2607/4131] add/fix some more soundblaster modes (Srecko) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2692 --- include/mixer.h | 2 ++ src/hardware/mixer.cpp | 32 ++++++++++++++++++++++++-------- src/hardware/sblaster.cpp | 39 ++++++++++++++++++++++++--------------- 3 files changed, 50 insertions(+), 23 deletions(-) diff --git a/include/mixer.h b/include/mixer.h index af232b99..60221139 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -54,6 +54,8 @@ public: void AddSamples(Bitu len,void * data); void AddSamples_m8(Bitu len,Bit8u * data); void AddSamples_s8(Bitu len,Bit8u * data); + void AddSamples_m8s(Bitu len,Bit8s * data); + void AddSamples_s8s(Bitu len,Bit8s * data); void AddSamples_m16(Bitu len,Bit16s * data); void AddSamples_s16(Bitu len,Bit16s * data); void AddSamples_m16u(Bitu len,Bit16u * data); diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index d2f4db11..f33bdfb2 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.41 2006-08-21 20:08:26 c2woody Exp $ */ +/* $Id: mixer.cpp,v 1.42 2006-08-25 09:40:19 c2woody Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -182,6 +182,7 @@ template INLINE void MixerChannel::AddSamples(Bitu len,void * data) { Bits diff[2]; Bit8u * data8=(Bit8u*)data; + Bit8s * data8s=(Bit8s*)data; Bit16s * data16=(Bit16s*)data; Bit16u * data16u=(Bit16u*)data; Bitu mixpos=mixer.pos+done; @@ -198,11 +199,20 @@ INLINE void MixerChannel::AddSamples(Bitu len,void * data) { thestart: if (pos>=len) return; if (_8bits) { - if (stereo) { - diff[0]=(((Bit8s)(data8[pos*2+0] ^ 0x80)) << 8)-last[0]; - diff[1]=(((Bit8s)(data8[pos*2+1] ^ 0x80)) << 8)-last[1]; + if (!signeddata) { + if (stereo) { + diff[0]=(((Bit8s)(data8[pos*2+0] ^ 0x80)) << 8)-last[0]; + diff[1]=(((Bit8s)(data8[pos*2+1] ^ 0x80)) << 8)-last[1]; + } else { + diff[0]=(((Bit8s)(data8[pos] ^ 0x80)) << 8)-last[0]; + } } else { - diff[0]=(((Bit8s)(data8[pos] ^ 0x80)) << 8)-last[0]; + if (stereo) { + diff[0]=(data8s[pos*2+0] << 8)-last[0]; + diff[1]=(data8s[pos*2+1] << 8)-last[1]; + } else { + diff[0]=(data8s[pos] << 8)-last[0]; + } } } else { if (signeddata) { @@ -214,10 +224,10 @@ thestart: } } else { if (stereo) { - diff[0]=data16u[pos*2+0]-last[0]; - diff[1]=data16u[pos*2+1]-last[1]; + diff[0]=(Bits)data16u[pos*2+0]-32768-last[0]; + diff[1]=(Bits)data16u[pos*2+1]-32768-last[1]; } else { - diff[0]=data16u[pos]-last[0]; + diff[0]=(Bits)data16u[pos]-32768-last[0]; } } } @@ -267,6 +277,12 @@ void MixerChannel::AddSamples_m8(Bitu len,Bit8u * data) { void MixerChannel::AddSamples_s8(Bitu len,Bit8u * data) { AddSamples(len,data); } +void MixerChannel::AddSamples_m8s(Bitu len,Bit8s * data) { + AddSamples(len,data); +} +void MixerChannel::AddSamples_s8s(Bitu len,Bit8s * data) { + AddSamples(len,data); +} void MixerChannel::AddSamples_m16(Bitu len,Bit16s * data) { AddSamples(len,data); } diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 805bed23..7870c9b7 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.56 2006-08-21 20:08:26 c2woody Exp $ */ +/* $Id: sblaster.cpp,v 1.57 2006-08-25 09:40:19 c2woody Exp $ */ #include #include @@ -404,19 +404,26 @@ static void GenerateDMASound(Bitu size) { if (sb.dma.stereo) { read=sb.dma.chan->Read(size,&sb.dma.buf.b8[sb.dma.remain_size]); Bitu total=read+sb.dma.remain_size; - sb.chan->AddSamples_s8(total>>1,sb.dma.buf.b8); + if (!sb.dma.sign) sb.chan->AddSamples_s8(total>>1,sb.dma.buf.b8); + else sb.chan->AddSamples_s8s(total>>1,(Bit8s*)sb.dma.buf.b8); if (total&1) { sb.dma.remain_size=1; sb.dma.buf.b8[0]=sb.dma.buf.b8[total-1]; } else sb.dma.remain_size=0; } else { read=sb.dma.chan->Read(size,sb.dma.buf.b8); - sb.chan->AddSamples_m8(read,sb.dma.buf.b8); + if (!sb.dma.sign) sb.chan->AddSamples_m8(read,sb.dma.buf.b8); + else sb.chan->AddSamples_m8s(read,(Bit8s *)sb.dma.buf.b8); } break; case DSP_DMA_16: + case DSP_DMA_16_ALIASED: if (sb.dma.stereo) { - read=sb.dma.chan->Read(size,(Bit8u *)&sb.dma.buf.b16[sb.dma.remain_size]); + /* In DSP_DMA_16_ALIASED mode temporarily divide by 2 to get number of 16-bit + samples, because 8-bit DMA Read returns byte size, while in DSP_DMA_16 mode + 16-bit DMA Read returns word size */ + read=sb.dma.chan->Read(size,(Bit8u *)&sb.dma.buf.b16[sb.dma.remain_size]) + >> (sb.dma.mode==DSP_DMA_16_ALIASED ? 1:0); Bitu total=read+sb.dma.remain_size; if (sb.dma.sign) sb.chan->AddSamples_s16(total>>1,sb.dma.buf.b16); else sb.chan->AddSamples_s16u(total>>1,(Bit16u *)sb.dma.buf.b16); @@ -425,16 +432,13 @@ static void GenerateDMASound(Bitu size) { sb.dma.buf.b16[0]=sb.dma.buf.b16[total-1]; } else sb.dma.remain_size=0; } else { - read=sb.dma.chan->Read(size,sb.dma.buf.b8); - sb.chan->AddSamples_m16(read,sb.dma.buf.b16); - } - break; - case DSP_DMA_16_ALIASED: - if (sb.dma.stereo) { - sb.chan->AddSamples_s16(read>>2,sb.dma.buf.b16); - } else { - sb.chan->AddSamples_m16(read>>1,sb.dma.buf.b16); + read=sb.dma.chan->Read(size,(Bit8u *)sb.dma.buf.b16) + >> (sb.dma.mode==DSP_DMA_16_ALIASED ? 1:0); + if (sb.dma.sign) sb.chan->AddSamples_m16(read,sb.dma.buf.b16); + else sb.chan->AddSamples_m16u(read,(Bit16u *)sb.dma.buf.b16); } + //restore buffer length value to byte size in aliased mode + if (sb.dma.mode==DSP_DMA_16_ALIASED) read=read<<1; break; default: LOG_MSG("Unhandled dma mode %d",sb.dma.mode); @@ -589,6 +593,7 @@ static void DSP_PrepareDMA_Old(DMA_MODES mode,bool autoinit) { static void DSP_PrepareDMA_New(DMA_MODES mode,Bitu length,bool autoinit,bool stereo) { Bitu freq=sb.freq; + //equal length if data format and dma channel are both 16-bit or 8-bit sb.dma.total=length; sb.dma.autoinit=autoinit; if (mode==DSP_DMA_16) { @@ -597,12 +602,15 @@ static void DSP_PrepareDMA_New(DMA_MODES mode,Bitu length,bool autoinit,bool ste if (sb.dma.chan==NULL) { sb.dma.chan=GetDMAChannel(sb.hw.dma8); mode=DSP_DMA_16_ALIASED; - freq/=2; + sb.dma.total<<=1; } } else { sb.dma.chan=GetDMAChannel(sb.hw.dma8); mode=DSP_DMA_16_ALIASED; - freq/=2; + //UNDOCUMENTED: + //In aliased mode sample length is written to DSP as number of + //16-bit samples so we need double 8-bit DMA buffer length + sb.dma.total<<=1; } } else sb.dma.chan=GetDMAChannel(sb.hw.dma8); DSP_DoDMATransfer(mode,freq,stereo); @@ -631,6 +639,7 @@ static void DSP_Reset(void) { sb.dma.left=0; sb.dma.total=0; sb.dma.stereo=false; + sb.dma.sign=false; sb.dma.autoinit=false; sb.dma.mode=DSP_DMA_NONE; sb.dma.remain_size=0; From 2b5eb217481593aef4693840ecb5ede1da522149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 28 Aug 2006 17:02:31 +0000 Subject: [PATCH 2608/4131] extend soundblaster mixer controls (Srecko) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2693 --- src/hardware/sblaster.cpp | 82 ++++++++++++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 9 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 7870c9b7..2bf49e59 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.57 2006-08-25 09:40:19 c2woody Exp $ */ +/* $Id: sblaster.cpp,v 1.58 2006-08-28 17:02:31 c2woody Exp $ */ #include #include @@ -920,10 +920,13 @@ static Bit8u DSP_ReadData(void) { static void CTMIXER_UpdateVolumes(void) { if (!sb.mixer.enabled) return; MixerChannel * chan; + //adjust to get linear master volume slider in trackers chan=MIXER_FindChannel("SB"); - if (chan) chan->SetVolume(CALCVOL(sb.mixer.dac[0]),CALCVOL(sb.mixer.dac[1])); + if (chan) chan->SetVolume(float(sb.mixer.master[0])/31.0f*CALCVOL(sb.mixer.dac[0]), + float(sb.mixer.master[1])/31.0f*CALCVOL(sb.mixer.dac[1])); chan=MIXER_FindChannel("FM"); - if (chan) chan->SetVolume(CALCVOL(sb.mixer.fm[0]),CALCVOL(sb.mixer.fm[1])); + if (chan) chan->SetVolume(float(sb.mixer.master[0])/31.0f*CALCVOL(sb.mixer.fm[0]), + float(sb.mixer.master[1])/31.0f*CALCVOL(sb.mixer.fm[1])); } static void CTMIXER_Reset(void) { @@ -931,12 +934,32 @@ static void CTMIXER_Reset(void) { sb.mixer.fm[1]= sb.mixer.dac[0]= sb.mixer.dac[1]=31; + sb.mixer.master[0]= + sb.mixer.master[1]=31; CTMIXER_UpdateVolumes(); } -#define SETPROVOL(_WHICH_,_VAL_) \ - _WHICH_[0]= 0x1 | ((_VAL_ & 0xf0) >> 3); \ - _WHICH_[1]= 0x1 | ((_VAL_ & 0x0f) << 1); +#define SETPROVOL(_WHICH_,_VAL_) \ + _WHICH_[0]= ((sb.type==SBT_16) ? ((_VAL_) & 0x1) :0x1) | (((_VAL_) & 0xf0) >> 3); \ + _WHICH_[1]= ((sb.type==SBT_16) ? (((_VAL_) >> 4) & 0x1) :0x1) | (((_VAL_) & 0x0f) << 1); \ + +#define MAKEPROVOL(_WHICH_) \ + (((_WHICH_[0] & 0x1e) << 3) | ((_WHICH_[1] & 0x1e) >> 1)) + +static void DSP_ChangeStereo(bool stereo) { + if (!sb.dma.stereo && stereo) { + sb.chan->SetFreq(sb.freq/2); + sb.dma.mul*=2; + sb.dma.rate=(sb.freq*sb.dma.mul) >> SB_SH; + sb.dma.min=(sb.dma.rate*3)/1000; + } else if (sb.dma.stereo && !stereo) { + sb.chan->SetFreq(sb.freq); + sb.dma.mul/=2; + sb.dma.rate=(sb.freq*sb.dma.mul) >> SB_SH; + sb.dma.min=(sb.dma.rate*3)/1000; + } + sb.dma.stereo=stereo; +} static void CTMIXER_Write(Bit8u val) { switch (sb.mixer.index) { @@ -947,6 +970,7 @@ static void CTMIXER_Write(Bit8u val) { case 0x02: /* Master Voulme (SBPRO) Obsolete? */ case 0x22: /* Master Volume (SBPRO) */ SETPROVOL(sb.mixer.master,val); + CTMIXER_UpdateVolumes(); break; case 0x04: /* DAC Volume (SBPRO) */ SETPROVOL(sb.mixer.dac,val); @@ -966,6 +990,7 @@ static void CTMIXER_Write(Bit8u val) { case 0x0e: /* Output/Stereo Select */ sb.mixer.stereo=(val & 0x2) > 0; sb.mixer.filtered=(val & 0x20) > 0; + DSP_ChangeStereo(sb.mixer.stereo); LOG(LOG_SB,LOG_WARN)("Mixer set to %s",sb.dma.stereo ? "STEREO" : "MONO"); break; case 0x26: /* FM Volume (SBPRO) */ @@ -978,6 +1003,32 @@ static void CTMIXER_Write(Bit8u val) { case 0x2e: /* Line-IN Volume (SBPRO) */ SETPROVOL(sb.mixer.lin,val); break; + //case 0x20: /* Master Volume Left (SBPRO) ? */ + case 0x30: /* Master Volume Left (SB16) */ + if (sb.type>=SBT_PRO2) { + SETPROVOL(sb.mixer.master,(val&0xf0)|(MAKEPROVOL(sb.mixer.master)&0x0f)); + CTMIXER_UpdateVolumes(); + } + break; + //case 0x21: /* Master Volume Right (SBPRO) ? */ + case 0x31: /* Master Volume Right (S16) */ + if (sb.type>=SBT_PRO2) { + SETPROVOL(sb.mixer.master,((val>>4)&0x0f)|(MAKEPROVOL(sb.mixer.master)&0xf0)); + CTMIXER_UpdateVolumes(); + } + break; + case 0x32: /* DAC Volume Left (S16) */ + if (sb.type>=SBT_PRO2) { + SETPROVOL(sb.mixer.dac,(val&0xf0)|(MAKEPROVOL(sb.mixer.dac)&0x0f)); + CTMIXER_UpdateVolumes(); + } + break; + case 0x33: /* DAC Volume Right (S16) */ + if (sb.type>=SBT_PRO2) { + SETPROVOL(sb.mixer.dac,((val>>4)&0x0f)|(MAKEPROVOL(sb.mixer.dac)&0xf0)); + CTMIXER_UpdateVolumes(); + } + break; case 0x80: /* IRQ Select */ sb.hw.irq=0xff; if (val & 0x1) sb.hw.irq=2; @@ -1004,9 +1055,6 @@ static void CTMIXER_Write(Bit8u val) { LOG(LOG_SB,LOG_WARN)("MIXER:Write %X to unhandled index %X",val,sb.mixer.index); } } - -#define MAKEPROVOL(_WHICH_) \ - (((_WHICH_[0] & 0x1e) << 3) | ((_WHICH_[1] & 0x1e) >> 1)) static Bit8u CTMIXER_Read(void) { Bit8u ret; @@ -1030,6 +1078,22 @@ static Bit8u CTMIXER_Read(void) { return MAKEPROVOL(sb.mixer.cda); case 0x2e: /* Line-IN Volume (SBPRO) */ return MAKEPROVOL(sb.mixer.lin); + case 0x30: /* Master Volume Left (SB16) */ + if (sb.type>=SBT_PRO2) return sb.mixer.master[0]<<3; + ret=0xa; + break; + case 0x31: /* Master Volume Right (S16) */ + if (sb.type>=SBT_PRO2) return sb.mixer.master[1]<<3; + ret=0xa; + break; + case 0x32: /* DAC Volume Left (S16) */ + if (sb.type>=SBT_PRO2) return sb.mixer.dac[0]<<3; + ret=0xa; + break; + case 0x33: /* DAC Volume Right (S16) */ + if (sb.type>=SBT_PRO2) return sb.mixer.dac[1]<<3; + ret=0xa; + break; case 0x80: /* IRQ Select */ switch (sb.hw.irq) { case 2: return 0x1; From 3055f3bdd50de4e44cf59a4ef51d457ffc56ee0d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 30 Aug 2006 12:19:04 +0000 Subject: [PATCH 2609/4131] reallocate allocates on handle 0 now as well. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2694 --- src/hardware/memory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index c14cf5cd..f4168e8a 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: memory.cpp,v 1.44 2006-02-09 11:47:49 qbix79 Exp $ */ +/* $Id: memory.cpp,v 1.45 2006-08-30 12:19:04 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -300,7 +300,7 @@ void MEM_ReleasePages(MemHandle handle) { } bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence) { - if (handle<0) { + if (handle<=0) { if (!pages) return true; handle=MEM_AllocatePages(pages,sequence); return (handle>0); From 941cca12b90a31571676f975c6b5ad03553689d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 1 Sep 2006 17:34:36 +0000 Subject: [PATCH 2610/4131] fix fast console output code (evo) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2695 --- src/cpu/callback.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index fe4cfde4..b5d84cde 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.34 2006-07-24 19:06:55 c2woody Exp $ */ +/* $Id: callback.cpp,v 1.35 2006-09-01 17:34:36 c2woody Exp $ */ #include #include @@ -320,8 +320,8 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ physAddress+=4; } phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax - phys_writew(physAddress+0x01,(Bit8u)0x0eb4); // mov ah, 0x0e - phys_writew(physAddress+0x03,(Bit8u)0x10cd); // int 10 + 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); From 1a17ed9833ef7caf9d65d8f0a92caf8f0e11c960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 2 Sep 2006 17:03:43 +0000 Subject: [PATCH 2611/4131] change mouse swap subroutine default parameters a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2696 --- src/ints/mouse.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 767bb292..7e805b48 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.63 2006-07-24 19:06:55 c2woody Exp $ */ +/* $Id: mouse.cpp,v 1.64 2006-09-02 17:03:43 c2woody Exp $ */ #include #include @@ -604,12 +604,9 @@ static void mouse_reset(void) { Mouse_NewVideoMode(); mouse.sub_mask=0; - mouse.sub_seg=0; - mouse.sub_ofs=0; + mouse.senv_x=1.0; - mouse.senv_y=1.0; - } static Bitu INT33_Handler(void) { @@ -946,6 +943,11 @@ void MOUSE_Init(Section* sec) { memset(&mouse,0,sizeof(mouse)); mouse.shown=-1; //Hide mouse on startup + + mouse.sub_mask=0; + mouse.sub_seg=0x6362; // magic value + mouse.sub_ofs=0; + mouse_reset_hardware(); mouse_reset(); } From aea9c0fa8356fc0b1e9cb370bdda147bbc547ea8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 9 Sep 2006 16:06:32 +0000 Subject: [PATCH 2612/4131] Patch "[ 1555185 ] Fix for SVGA Harrier" from Vasyl Tsvirkunov Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2697 --- src/hardware/vga_s3.cpp | 3 ++- src/shell/shell_misc.cpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index c2459f3d..fb92b984 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_s3.cpp,v 1.4 2006-07-08 16:32:26 c2woody Exp $ */ +/* $Id: vga_s3.cpp,v 1.5 2006-09-09 16:06:31 qbix79 Exp $ */ #include "dosbox.h" #include "inout.h" @@ -29,6 +29,7 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { vga.s3.reg_31 = val; vga.config.compatible_chain4 = !(val&0x08); VGA_DetermineMode(); + VGA_SetupHandlers(); break; /* 0 Enable Base Address Offset (CPUA BASE). Enables bank operation if diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index d383e77f..0fed3ec0 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.44 2006-04-07 19:56:45 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.45 2006-09-09 16:06:32 qbix79 Exp $ */ #include #include @@ -368,7 +368,7 @@ bool DOS_Shell::Execute(char * name,char * args) { }; /* check for a drive change */ - if ((strcmp(name + 1, ":") == 0) && isalpha(*name)) + if (((strcmp(name + 1, ":") == 0) || (strcmp(name + 1, ":\\") == 0)) && isalpha(*name)) { if (!DOS_SetDrive(toupper(name[0])-'A')) { WriteOut(MSG_Get("SHELL_EXECUTE_DRIVE_NOT_FOUND"),toupper(name[0])); From 0cee9f42c715a56f05278a1e9b0ca00b1a06e900 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 10 Sep 2006 13:21:43 +0000 Subject: [PATCH 2613/4131] Appy patch "[ 1555189 ] Fix for Alien Breed" from Vasyl Tsvirkunov Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2698 --- src/hardware/vga_memory.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 0a4a5e8d..37ac179b 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -290,6 +290,8 @@ public: pixels.d&=vga.config.full_not_map_mask; pixels.d|=(data & vga.config.full_map_mask); vga.mem.latched[addr].d=pixels.d; + if(vga.config.compatible_chain4) + vga.mem.latched[addr+64*1024].d=pixels.d; } public: VGA_UnchainedVGA_Handler() { From acce481653503ed2575b14dcc46ae6ed734a573c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 14 Sep 2006 18:46:48 +0000 Subject: [PATCH 2614/4131] Fix bug 1542808 (BaK doesn't work on AMD 64). Apply patch 1555327 (A few less warnings) by Guido de Jong. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2699 --- src/cpu/cpu.cpp | 5 +++-- src/cpu/instructions.h | 9 ++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index edae46ef..478c929b 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.83 2006-06-29 09:10:09 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.84 2006-09-14 18:46:48 qbix79 Exp $ */ #include #include "dosbox.h" @@ -33,7 +33,8 @@ extern void GFX_SetTitle(Bits cycles ,Bits frameskip,bool paused); #if 1 #undef LOG -#define LOG(X,Y) +#define LOG(X,Y) CPU_LOG +#define CPU_LOG(...) #endif CPU_Regs cpu_regs; diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 93a79584..27b276be 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -599,7 +599,6 @@ { \ Bit16u ax1 = reg_ah * op1; \ Bit16u ax2 = ax1 + reg_al; \ - Bit8u old_al = reg_al; \ reg_al = (Bit8u) ax2; \ reg_ah = 0; \ SETFLAGBIT(CF,0); \ @@ -666,7 +665,7 @@ { \ Bitu val=load(op1); \ if (val==0) EXCEPTION(0); \ - Bitu num=(reg_dx<<16)|reg_ax; \ + Bitu num=((Bit32u)reg_dx<<16)|reg_ax; \ Bitu quo=num/val; \ Bit16u rem=(Bit16u)(num % val); \ Bit16u quo16=(Bit16u)(quo&0xffff); \ @@ -678,7 +677,7 @@ #define DIVD(op1,load,save) \ { \ Bitu val=load(op1); \ - if (!val) EXCEPTION(0); \ + if (val==0) EXCEPTION(0); \ Bit64u num=(((Bit64u)reg_edx)<<32)|reg_eax; \ Bit64u quo=num/val; \ Bit32u rem=(Bit32u)(num % val); \ @@ -705,7 +704,7 @@ #define IDIVW(op1,load,save) \ { \ Bits val=(Bit16s)(load(op1)); \ - if (!val) EXCEPTION(0); \ + if (val==0) EXCEPTION(0); \ Bits num=(Bit32s)((reg_dx<<16)|reg_ax); \ Bits quo=num/val; \ Bit16s rem=(Bit16s)(num % val); \ @@ -718,7 +717,7 @@ #define IDIVD(op1,load,save) \ { \ Bits val=(Bit32s)(load(op1)); \ - if (!val) EXCEPTION(0); \ + if (val==0) EXCEPTION(0); \ Bit64s num=(((Bit64u)reg_edx)<<32)|reg_eax; \ Bit64s quo=num/val; \ Bit32s rem=(Bit32s)(num % val); \ From bd65320c7eb962c491203ffc4f99f4c1d7f074f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 17 Sep 2006 13:38:30 +0000 Subject: [PATCH 2615/4131] add TRx handling opcodes (fixes JetFighter2, thanks to vasyl) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2700 --- include/cpu.h | 4 ++++ src/cpu/core_full/op.h | 6 +++++ src/cpu/core_full/optable.h | 8 +++---- src/cpu/core_full/support.h | 1 + src/cpu/core_normal/prefix_0f.h | 26 ++++++++++++++++++++++ src/cpu/cpu.cpp | 39 +++++++++++++++++++++++++++++++-- 6 files changed, 78 insertions(+), 6 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 6a1bb85c..90ab3d95 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -81,6 +81,9 @@ 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); + void CPU_SMSW(Bitu & word); Bitu CPU_LMSW(Bitu word); @@ -442,6 +445,7 @@ struct CPUBlock { } exception; Bits direction; Bit32u drx[8]; + Bit32u trx[8]; }; extern CPUBlock cpu; diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 97f85756..d7a454f2 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -472,6 +472,12 @@ switch (inst.code.op) { case O_M_Rd_DRx: if (CPU_READ_DRX(inst.rm_index,inst_op1_d)) RunException(); break; + case O_M_TRx_Rd: + if (CPU_WRITE_TRX(inst.rm_index,inst_op1_d)) RunException(); + break; + case O_M_Rd_TRx: + if (CPU_READ_TRX(inst.rm_index,inst_op1_d)) RunException(); + break; case O_LAR: { if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode; diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index cf119948..1d21d4b5 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -206,8 +206,8 @@ static OpCode OpCodeTable[1024]={ /* 0x120 - 0x127 */ {L_MODRM ,O_M_Rd_CRx ,S_Ed ,0 },{L_MODRM ,O_M_Rd_DRx ,S_Ed ,0 }, {L_MODRM ,O_M_CRx_Rd ,0 ,M_Ed },{L_MODRM ,O_M_DRx_Rd ,0 ,M_Ed }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_M_Rd_TRx ,S_Ed ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_M_TRx_Rd ,0 ,M_Ed },{0 ,0 ,0 ,0 }, /* 0x128 - 0x12f */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, @@ -562,8 +562,8 @@ static OpCode OpCodeTable[1024]={ /* 0x320 - 0x327 */ {L_MODRM ,O_M_Rd_CRx ,S_Ed ,0 },{L_MODRM ,O_M_Rd_DRx ,S_Ed ,0 }, {L_MODRM ,O_M_CRx_Rd ,0 ,M_Ed },{L_MODRM ,O_M_DRx_Rd ,0 ,M_Ed }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_M_Rd_TRx ,S_Ed ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_M_TRx_Rd ,0 ,M_Ed },{0 ,0 ,0 ,0 }, /* 0x328 - 0x32f */ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index d7f68f70..f7f54b00 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -86,6 +86,7 @@ enum { O_GRP7w,O_GRP7d, O_M_CRx_Rd,O_M_Rd_CRx, O_M_DRx_Rd,O_M_Rd_DRx, + O_M_TRx_Rd,O_M_Rd_TRx, O_LAR,O_LSL, O_ARPL, diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index cefd09ea..1349c2d4 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -201,6 +201,32 @@ if (CPU_WRITE_DRX(which,*eard)) RUNEXCEPTION(); } break; + CASE_0F_B(0x24) /* MOV Rd,TRx */ + { + GetRM; + Bitu which=(rm >> 3) & 7; + if (rm < 0xc0 ) { + rm |= 0xc0; + LOG(LOG_CPU,LOG_ERROR)("MOV XXX,TR% with non-register",which); + } + GetEArd; + Bit32u trx_value; + if (CPU_READ_TRX(which,trx_value)) RUNEXCEPTION(); + *eard=trx_value; + } + break; + CASE_0F_B(0x26) /* MOV TRx,Rd */ + { + GetRM; + Bitu which=(rm >> 3) & 7; + if (rm < 0xc0 ) { + rm |= 0xc0; + LOG(LOG_CPU,LOG_ERROR)("MOV TR%,XXX with non-register",which); + } + GetEArd; + if (CPU_WRITE_TRX(which,*eard)) RUNEXCEPTION(); + } + break; CASE_0F_W(0x80) /* JO */ JumpCond16_w(TFLG_O);break; CASE_0F_W(0x81) /* JNO */ diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 478c929b..f662a7a8 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.84 2006-09-14 18:46:48 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.85 2006-09-17 13:38:30 c2woody Exp $ */ #include #include "dosbox.h" @@ -1561,6 +1561,38 @@ bool CPU_READ_DRX(Bitu dr,Bit32u & retvalue) { return false; } +bool CPU_WRITE_TRX(Bitu tr,Bitu value) { + /* Check if privileged to access control registers */ + if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); + switch (tr) { +// case 3: + case 6: + case 7: + cpu.trx[tr]=value; + return false; + default: + LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV TR%d,%X",tr,value); + break; + } + return CPU_PrepareException(EXCEPTION_UD,0); +} + +bool CPU_READ_TRX(Bitu tr,Bit32u & retvalue) { + /* Check if privileged to access control registers */ + if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); + switch (tr) { +// case 3: + case 6: + case 7: + retvalue=cpu.trx[tr]; + return false; + default: + LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV XXX, TR%d",tr); + break; + } + return CPU_PrepareException(EXCEPTION_UD,0); +} + void CPU_SMSW(Bitu & word) { word=cpu.cr0; @@ -1976,7 +2008,10 @@ public: cpu.idt.SetBase(0); cpu.idt.SetLimit(1023); - for (Bitu i=0; i<7; i++) cpu.drx[i]=0; + for (Bitu i=0; i<7; i++) { + cpu.drx[i]=0; + cpu.trx[i]=0; + } cpu.drx[6]=0xffff1ff0; cpu.drx[7]=0x00000400; From d5376a59f9288c76e6d7d3a87f13ee48762ad378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 19 Sep 2006 16:27:58 +0000 Subject: [PATCH 2616/4131] fix two bugs in the dyn_fpu generated code (thanks to Folken for reporting them) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2701 --- src/cpu/core_dyn_x86/dyn_fpu.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_dyn_x86/dyn_fpu.h b/src/cpu/core_dyn_x86/dyn_fpu.h index 3664bb8f..cabfeb83 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu.h +++ b/src/cpu/core_dyn_x86/dyn_fpu.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dyn_fpu.h,v 1.1 2006-06-01 15:45:37 c2woody Exp $ */ +/* $Id: dyn_fpu.h,v 1.2 2006-09-19 16:27:58 c2woody Exp $ */ #include "dosbox.h" #if C_FPU @@ -559,6 +559,7 @@ static void dyn_fpu_esc6(){ } 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; @@ -607,7 +608,7 @@ static void dyn_fpu_esc7(){ case 0x00: /* FNSTSW AX*/ gen_load_host(&TOP,DREG(TMPB),4); gen_call_function((void*)&FPU_SET_TOP,"%Ddr",DREG(TMPB)); - gen_load_host(&fpu.sw,DREG(EAX),2); + gen_mov_host(&fpu.sw,DREG(EAX),2); break; default: LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub); From 50a7684df157b78cdf19ac7133e8f2dd29453238 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 Sep 2006 08:47:37 +0000 Subject: [PATCH 2617/4131] Fix cdrom detection Inherit the earth under image and SDL cdrom emulation Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2702 --- src/dos/cdrom.cpp | 4 ++-- src/dos/cdrom_image.cpp | 13 +++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 96a17ae6..8ceade10 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -86,7 +86,7 @@ bool CDROM_Interface_SDL::GetAudioTrackInfo (int track, TMSF& start, unsigned ch { if (CD_INDRIVE(SDL_CDStatus(cd))) { FRAMES_TO_MSF(cd->track[track-1].offset+150,&start.min,&start.sec,&start.fr); - attr = cd->track[track-1].type; + attr = cd->track[track-1].type<<4;//sdl uses 0 for audio and 4 for data. instead of 0x00 and 0x40 } return CD_INDRIVE(SDL_CDStatus(cd)); }; @@ -96,7 +96,7 @@ bool CDROM_Interface_SDL::GetAudioSub (unsigned char& attr, unsigned char& track if (CD_INDRIVE(SDL_CDStatus(cd))) { track = cd->cur_track; index = cd->cur_track; - attr = cd->track[track].type; + attr = cd->track[track].type<<4; FRAMES_TO_MSF(cd->cur_frame,&relPos.min,&relPos.sec,&relPos.fr); FRAMES_TO_MSF(cd->cur_frame+cd->track[track].offset,&absPos.min,&absPos.sec,&absPos.fr); } diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index cbf10d41..fd65c4fc 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.11 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: cdrom_image.cpp,v 1.12 2006-09-25 08:47:37 qbix79 Exp $ */ #include #include @@ -348,7 +348,7 @@ bool CDROM_Interface_Image::LoadIsoFile(char* filename) return false; } track.number = 1; - track.attr = 4; + track.attr = 0x40;//data // try to detect iso type if (CanReadPVD(track.file, COOKED_SECTOR_SIZE, false)) { @@ -452,19 +452,19 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) track.mode2 = false; } else if (type == "MODE1/2048") { track.sectorSize = COOKED_SECTOR_SIZE; - track.attr = 4; + track.attr = 0x40; track.mode2 = false; } else if (type == "MODE1/2352") { track.sectorSize = RAW_SECTOR_SIZE; - track.attr = 4; + track.attr = 0x40; track.mode2 = false; } else if (type == "MODE2/2336") { track.sectorSize = 2336; - track.attr = 4; + track.attr = 0x40; track.mode2 = true; } else if (type == "MODE2/2352") { track.sectorSize = RAW_SECTOR_SIZE; - track.attr = 4; + track.attr = 0x40; track.mode2 = true; } else success = false; @@ -522,6 +522,7 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) // add leadout track track.number++; + track.attr = 0;//sync with load iso track.start = 0; track.length = 0; track.file = NULL; From 14d8f44e0ec892776ac97e65c29bcf07a7e5cf95 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 30 Sep 2006 12:33:36 +0000 Subject: [PATCH 2618/4131] Add patch "DAC on LPT1, covox emulation added." from zbiggy. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2703 --- src/hardware/disney.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index e33e46e9..9aea748e 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -44,17 +44,15 @@ static void disney_write(Bitu port,Bitu val,Bitu iolen) { switch (port-DISNEY_BASE) { case 0: /* Data Port */ disney.data=val; + if (disney.used Date: Wed, 4 Oct 2006 19:24:52 +0000 Subject: [PATCH 2619/4131] adapt dynamic core for OSX (adhere to 16 byte stack alignment, move link blocks to dynamic memory); thanks to Mark Laws for his help and information Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2704 --- src/cpu/core_dyn_x86.cpp | 4 ++ src/cpu/core_dyn_x86/cache.h | 49 ++++++++++++------- src/cpu/core_dyn_x86/risc_x86.h | 87 ++++++++++++++++++++++++++++++++- src/cpu/cpu.cpp | 6 ++- 4 files changed, 125 insertions(+), 21 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 58ea04e4..e77cb969 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -374,4 +374,8 @@ void CPU_Core_Dyn_X86_Cache_Init(bool enable_cache) { cache_init(enable_cache); } +void CPU_Core_Dyn_X86_Cache_Close(void) { + cache_close(); +} + #endif diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 6751cad6..ecee1b9e 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -42,12 +42,6 @@ static struct { CodePageHandler * last_page; } cache; -#if (C_HAVE_MPROTECT) -static Bit8u cache_code_link_blocks[2][16] GCC_ATTRIBUTE(aligned(PAGESIZE)); -#else -static Bit8u cache_code_link_blocks[2][16]; -#endif - static CacheBlock link_blocks[2]; class CodePageHandler :public PageHandler { @@ -396,19 +390,21 @@ static INLINE void cache_addd(Bit32u val) { 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 1 +#define PAGESIZE_TEMP 4096 #endif +static bool cache_initialized = false; static void cache_init(bool enable) { - static bool cache_initialized = false; Bits i; if (enable) { if (cache_initialized) return; @@ -424,16 +420,17 @@ static void cache_init(bool enable) { cache_blocks[i].cache.next=&cache_blocks[i+1]; } } + if (cache_code_start_ptr==NULL) { + cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP); + if(!cache_code_start_ptr) E_Exit("Allocating dynamic cache 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,sizeof(cache_code_link_blocks),PROT_WRITE|PROT_READ|PROT_EXEC)) - LOG_MSG("Setting excute permission on cache code link blocks has failed"); -#endif - if (cache_code==NULL) { - cache_code=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1); - if(!cache_code) E_Exit("Allocating dynamic cache failed"); -#if (C_HAVE_MPROTECT) - cache_code=(Bit8u*)(((int)cache_code + PAGESIZE-1) & ~(PAGESIZE-1)); //MEM LEAK. store old pointer if you want to free it. - if(mprotect(cache_code,CACHE_TOTAL+CACHE_MAXSIZE,PROT_WRITE|PROT_READ|PROT_EXEC)) + 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(); @@ -444,10 +441,10 @@ static void cache_init(bool enable) { block->cache.next=0; //Last block in the list } /* Setup the default blocks for block linkage returns */ - cache.pos=&cache_code_link_blocks[0][0]; + cache.pos=&cache_code_link_blocks[0]; link_blocks[0].cache.start=cache.pos; gen_return(BR_Link1); - cache.pos=&cache_code_link_blocks[1][0]; + cache.pos=&cache_code_link_blocks[32]; link_blocks[1].cache.start=cache.pos; gen_return(BR_Link2); cache.free_pages=0; @@ -461,3 +458,17 @@ static void cache_init(bool enable) { } } } + +static void cache_close(void) { +/* if (cache_blocks != NULL) { + free(cache_blocks); + cache_blocks = NULL; + } + if (cache_code_start_ptr != NULL) { + free(cache_code_start_ptr); + cache_code_start_ptr = NULL; + } + cache_code = NULL; + cache_code_link_blocks = NULL; + cache_initialized = false; */ +} \ No newline at end of file diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index f3a809a3..191e4ab5 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -110,6 +110,22 @@ return_address: pop ebx mov [retval],eax } +#elif defined (MACOSX) + register Bit32u tempflags=reg_flags & FMASK_TEST; + __asm__ volatile ( + "pushl %%ebx \n" + "pushl %%ebp \n" + "pushl $(run_return_adress) \n" + "pushl %2 \n" + "jmp *%3 \n" + "run_return_adress: \n" + "popl %%ebp \n" + "popl %%ebx \n" + :"=a" (retval), "=c" (tempflags) + :"r" (tempflags),"r" (code) + :"%edx","%edi","%esi","cc","memory" + ); + reg_flags=(reg_flags & ~FMASK_TEST) | (tempflags & FMASK_TEST); #else register Bit32u tempflags=reg_flags & FMASK_TEST; __asm__ volatile ( @@ -629,15 +645,42 @@ static void gen_call_function(void * func,char * ops,...) { if (ops) { va_list params; va_start(params,ops); + Bitu stack_used=0; + bool free_flags=false; Bits pindex=0; while (*ops) { if (*ops=='%') { pinfo[pindex].line=ops+1; pinfo[pindex].value=va_arg(params,Bitu); +#if defined (MACOSX) + char * scan=pinfo[pindex].line; + if ((*scan=='I') || (*scan=='D')) stack_used+=4; + else if (*scan=='F') free_flags=true; +#endif pindex++; } ops++; } + +#if defined (MACOSX) + /* align stack */ + stack_used+=4; // saving esp on stack as well + + cache_addw(0xc48b); // mov eax,esp + cache_addb(0x2d); // sub eax,stack_used + cache_addd(stack_used); + cache_addw(0xe083); // and eax,0xfffffff0 + cache_addb(0xf0); + cache_addb(0x05); // sub eax,stack_used + cache_addd(stack_used); + cache_addb(0x94); // xchg eax,esp + if (free_flags) { + cache_addw(0xc083); // add eax,4 + cache_addb(0x04); + } + cache_addb(0x50); // push eax (==old esp) +#endif + paramcount=0; while (pindex) { pindex--; @@ -694,7 +737,24 @@ static void gen_call_function(void * func,char * ops,...) { IllegalOption("gen_call_function unknown param"); } } +#if defined (MACOSX) + if (free_flags) release_flags=false; + } else { + /* align stack */ + Bit32u stack_used=8; // saving esp and return address on the stack + + cache_addw(0xc48b); // mov eax,esp + cache_addb(0x2d); // sub eax,stack_used + cache_addd(stack_used); + cache_addw(0xe083); // and eax,0xfffffff0 + cache_addb(0xf0); + cache_addb(0x05); // sub eax,stack_used + cache_addd(stack_used); + cache_addb(0x94); // xchg eax,esp + cache_addb(0x50); // push esp (==old esp) +#endif } + /* Clear some unprotected registers */ x86gen.regs[X86_REG_ECX]->Clear(); x86gen.regs[X86_REG_EDX]->Clear(); @@ -733,6 +793,11 @@ static void gen_call_function(void * func,char * ops,...) { } /* Restore EAX registers to be used again */ x86gen.regs[X86_REG_EAX]->notusable=false; + +#if defined (MACOSX) + /* restore stack */ + cache_addb(0x5c); // pop esp +#endif } static void gen_call_write(DynReg * dr,Bit32u val,Bitu write_size) { @@ -741,6 +806,21 @@ static void gen_call_write(DynReg * dr,Bit32u val,Bitu write_size) { x86gen.regs[X86_REG_EAX]->notusable=true; gen_protectflags(); +#if defined (MACOSX) + /* align stack */ + Bitu stack_used=12; + + cache_addw(0xc48b); // mov eax,esp + cache_addb(0x2d); // sub eax,stack_used + cache_addd(stack_used); + cache_addw(0xe083); // and eax,0xfffffff0 + cache_addb(0xf0); + cache_addb(0x05); // sub eax,stack_used + cache_addd(stack_used); + cache_addb(0x94); // xchg eax,esp + cache_addb(0x50); // push eax (==old esp) +#endif + cache_addb(0x68); //PUSH val cache_addd(val); GenReg * genreg=FindDynReg(dr); @@ -762,6 +842,11 @@ static void gen_call_write(DynReg * dr,Bit32u val,Bitu write_size) { cache_addb(2*4); x86gen.regs[X86_REG_EAX]->notusable=false; gen_releasereg(dr); + +#if defined (MACOSX) + /* restore stack */ + cache_addb(0x5c); // pop esp +#endif } static Bit8u * gen_create_branch(BranchTypes type) { @@ -774,7 +859,7 @@ static void gen_fill_branch(Bit8u * data,Bit8u * from=cache.pos) { #if C_DEBUG Bits len=from-data; if (len<0) len=-len; - if (len>126) LOG_MSG("BIg jump %d",len); + if (len>126) LOG_MSG("Big jump %d",len); #endif *data=(from-data-1); } diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index f662a7a8..1b25e1bc 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.85 2006-09-17 13:38:30 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.86 2006-10-04 19:24:52 c2woody Exp $ */ #include #include "dosbox.h" @@ -55,6 +55,7 @@ void CPU_Core_Normal_Init(void); void CPU_Core_Simple_Init(void); void CPU_Core_Dyn_X86_Init(void); void CPU_Core_Dyn_X86_Cache_Init(bool enable_cache); +void CPU_Core_Dyn_X86_Cache_Close(void); /* In debug mode exceptions are tested and dosbox exits when * a unhandled exception state is detected. @@ -2084,6 +2085,9 @@ public: static CPU * test; void CPU_ShutDown(Section* sec) { +#if (C_DYNAMIC_X86) + CPU_Core_Dyn_X86_Cache_Close(); +#endif delete test; } From 54b29e831c6bbebc46f26e124a93871f51c3dea8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 8 Oct 2006 19:26:04 +0000 Subject: [PATCH 2620/4131] Change configfile loading support. Introduce some sort of global configfile parsing and add some additional settings from local configuration files. Allow multiple configuration files to be specified at the commandline like patch 1513790. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2705 --- README | 9 ++++++--- docs/dosbox.1 | 12 ++++++++---- src/gui/sdlmain.cpp | 34 ++++++++++++++++------------------ src/misc/setup.cpp | 8 ++++++-- 4 files changed, 36 insertions(+), 27 deletions(-) diff --git a/README b/README index 6ce98d72..fbf0ff68 100644 --- a/README +++ b/README @@ -226,6 +226,7 @@ dosbox -version -conf configfile Start DOSBox with the options specified in "configfile". + Multiple -conf options may be present. See Chapter 9 for more details. -lang languagefile @@ -770,9 +771,11 @@ Some sections have options you can set. The generated configfile contains the current settings. You can alter them and start DOSBox with the -conf switch to load the file and use these settings. -If no configfile is specified with the -conf switch, DOSBox will look in the -current directory for dosbox.conf. Then it will look for ~/.dosboxrc (Linux), -~\dosbox.conf (Win32) or "~/Library/Preferences/DOSBox Preferences" (MACOSX). +DOSBox will first parse the settings in ~/.dosboxrc (Linux), +~\dosbox.conf (Win32) or "~/Library/Preferences/DOSBox Preferences" +(MACOSX). Afterwards DOSBox will parse all configfiles specified with the +-conf switch. If no configfile is specified with the -conf switch, DOSBox will +look in the current directory for dosbox.conf. diff --git a/docs/dosbox.1 b/docs/dosbox.1 index cfe18ada..8751a594 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -49,7 +49,8 @@ an Internal Program, a DOS command or an executable on a mounted drive. .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. +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 " @@ -211,9 +212,12 @@ Boot will start floppy images or hard disk images independent of the .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. If a file named -.BR dosbox.conf " is found in the current directory, it will be" -automatically loaded, else ~/.dosboxrc (if present) will be loaded. +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 diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index d02c0c62..69e12a93 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.121 2006-07-22 18:32:29 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.122 2006-10-08 19:26:04 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1423,24 +1423,22 @@ int main(int argc, char* argv[]) { /* Init all the dosbox subsystems */ DOSBOX_Init(); std::string config_file; - if (control->cmdline->FindString("-conf",config_file,true)) { - - } else { - config_file="dosbox.conf"; - } - /* Parse the config file - * try open config file in $HOME if can't open dosbox.conf or specified file - */ - if (control->ParseConfigFile(config_file.c_str()) == false) { - if ((getenv("HOME") != NULL)) { - config_file = (std::string)getenv("HOME") + - (std::string)DEFAULT_CONFIG_FILE; - if (control->ParseConfigFile(config_file.c_str()) == false) { - LOG_MSG("CONFIG: Using default settings. Create a configfile to change them"); - } - - } + bool parsed_anyconfigfile = false; + // First parse the configfile in the $HOME directory + if ((getenv("HOME") != NULL)) { + config_file = (std::string)getenv("HOME") + + (std::string)DEFAULT_CONFIG_FILE; + if (control->ParseConfigFile(config_file.c_str())) parsed_anyconfigfile = true; } + // Add extra settings from dosbox.conf in the local directory if there is no configfile specified at the commandline + if (!control->cmdline->FindString("-conf",config_file,true)) config_file="dosbox.conf"; + if (control->ParseConfigFile(config_file.c_str())) parsed_anyconfigfile = true; + // Add extra settings from additional configfiles at the commandline + while(control->cmdline->FindString("-conf",config_file,true)) + if (control->ParseConfigFile(config_file.c_str())) parsed_anyconfigfile = true; + // Give a message if no configfile whatsoever was found. + if(!parsed_anyconfigfile) LOG_MSG("CONFIG: Using default settings. Create a configfile to change them"); + #if (ENVIRON_LINKED) control->ParseEnv(environ); #endif diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index ea8a368c..b2850377 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.36 2006-05-25 15:07:33 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.37 2006-10-08 19:26:04 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -291,10 +291,14 @@ Section* Config::GetSectionFromProperty(char const * const prop) const{ } return NULL; } + bool Config::ParseConfigFile(char const * const configfilename){ + static bool first_configfile = true; ifstream in(configfilename); if (!in) return false; - LOG_MSG("CONFIG:Loading settings from config file %s", configfilename); + const char * settings_type = first_configfile?"primary":"additional"; + first_configfile = false; + LOG_MSG("CONFIG:Loading %s settings from config file %s", settings_type,configfilename); char gegevens[1024]; Section* currentsection = NULL; Section* testsec = NULL; From da0bb016c57de52552fefb1bac429f8992ab5d84 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 11 Oct 2006 08:01:11 +0000 Subject: [PATCH 2621/4131] fix a warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2706 --- src/fpu/fpu_instructions.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 8bdf648d..26ed9e9f 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.29 2006-06-01 08:33:52 c2woody Exp $ */ +/* $Id: fpu_instructions.h,v 1.30 2006-10-11 08:01:11 qbix79 Exp $ */ static void FPU_FINIT(void) { @@ -592,4 +592,5 @@ static INLINE void FPU_FDIVR_EA(Bitu op1){ } static INLINE void FPU_FCOM_EA(Bitu op1){ FPU_FCOM(op1,8); -} \ No newline at end of file +} + From 3cb1e884bdf03a53292a117a496512b6c6e2d2d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 12 Oct 2006 15:18:32 +0000 Subject: [PATCH 2622/4131] utilize host fpu directly (dynamic core) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2707 --- src/cpu/core_dyn_x86.cpp | 79 ++++++++++++++- src/cpu/core_dyn_x86/Makefile.am | 2 +- src/cpu/core_dyn_x86/decoder.h | 165 +++++++++++++++++++++---------- src/cpu/cpu.cpp | 9 +- visualc_net/dosbox.vcproj | 3 + 5 files changed, 199 insertions(+), 59 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index e77cb969..d6e41ed1 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -43,6 +43,7 @@ #include "debug.h" #include "paging.h" #include "inout.h" +#include "fpu.h" #define CACHE_MAXSIZE (4096*2) #define CACHE_PAGES (128*8) @@ -163,6 +164,15 @@ static struct { Bitu callback,readdata; } core_dyn; +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" @@ -219,6 +229,30 @@ static void dyn_restoreregister(DynReg * src_reg, DynReg * dst_reg) { #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: @@ -232,7 +266,10 @@ restart_core: CPU_Exception(cpu.exception.which,cpu.exception.error); goto restart_core; } - if (!chandler) return CPU_Core_Normal_Run(); + 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) { @@ -244,10 +281,15 @@ run_block: switch (ret) { case BR_Iret: #if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) return debugCallback; + 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? */ @@ -259,8 +301,12 @@ run_block: #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); @@ -269,11 +315,13 @@ run_block: 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: @@ -291,6 +339,7 @@ run_block: } goto restart_core; } + if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT return CBRET_NONE; } @@ -366,6 +415,28 @@ void CPU_Core_Dyn_X86_Init(void) { 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; } @@ -378,4 +449,8 @@ 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 diff --git a/src/cpu/core_dyn_x86/Makefile.am b/src/cpu/core_dyn_x86/Makefile.am index 8c432515..3d9be090 100644 --- a/src/cpu/core_dyn_x86/Makefile.am +++ b/src/cpu/core_dyn_x86/Makefile.am @@ -1,2 +1,2 @@ noinst_HEADERS = cache.h helpers.h decoder.h risc_x86.h string.h \ - dyn_fpu.h \ No newline at end of file + dyn_fpu.h dyn_fpu_dh.h \ No newline at end of file diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index a4bb7174..272b28e3 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -16,19 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define X86_DYNFPU - -#include "fpu.h" -#define DYN_FPU_ESC(code) { \ - dyn_get_modrm(); \ - if (decode.modrm.val >= 0xc0) { \ - gen_call_function((void*)&FPU_ESC ## code ## _Normal,"%Id",decode.modrm.val); \ - } else { \ - dyn_fill_ea(); \ - gen_call_function((void*)&FPU_ESC ## code ## _EA,"%Id%Dd",decode.modrm.val,DREG(EA)); \ - gen_releasereg(DREG(EA)); \ - } \ -} +#define X86_DYNFPU_DH_ENABLED enum REP_Type { REP_NONE=0,REP_NZ,REP_Z @@ -152,7 +140,7 @@ static INLINE void dyn_set_eip_last(void) { } -enum save_info_type {exception, cycle_check, normal}; +enum save_info_type {exception, cycle_check, normal, fpu_restore}; static struct { @@ -161,6 +149,7 @@ static struct { Bit8u * branch_pos; Bit32u eip_change; Bitu cycles; + Bit8u * return_pos; } save_info[512]; Bitu used_save_info=0; @@ -220,6 +209,21 @@ static void dyn_fill_blocks(void) { dyn_save_critical_regs(); gen_return(BR_Cycles); break; + case fpu_restore: + dyn_loadstate(&save_info[sct].state); + gen_load_host(&dyn_dh_fpu.state_used,DREG(TMPB),4); + gen_sop_word(SOP_INC,true,DREG(TMPB)); + GenReg * gr1=FindDynReg(DREG(TMPB)); + cache_addb(0xdd); // FRSTOR fpu.state (fpu_restore) + cache_addb(0x25); + cache_addd((Bit32u)(&(dyn_dh_fpu.state[0]))); + cache_addb(0x89); // mov fpu.state_used,1 + cache_addb(0x05|(gr1->index<<3)); + cache_addd((Bit32u)(&(dyn_dh_fpu.state_used))); + gen_releasereg(DREG(TMPB)); + dyn_synchstate(&save_info[sct].state); + gen_create_jump(save_info[sct].return_pos); + break; } } used_save_info=0; @@ -1226,9 +1230,22 @@ static void dyn_add_iocheck_var(Bit8u accessed_port,Bitu access_size) { } } -#ifdef X86_DYNFPU -#include "dyn_fpu.h" +#ifdef X86_DYNFPU_DH_ENABLED +#include "dyn_fpu_dh.h" +#define dh_fpu_startup() { \ + fpu_used=true; \ + gen_protectflags(); \ + gen_load_host(&dyn_dh_fpu.state_used,DREG(TMPB),4); \ + gen_dop_word_imm(DOP_CMP,true,DREG(TMPB),0); \ + gen_releasereg(DREG(TMPB)); \ + save_info[used_save_info].branch_pos=gen_create_branch_long(BR_Z); \ + dyn_savestate(&save_info[used_save_info].state); \ + save_info[used_save_info].return_pos=cache.pos; \ + save_info[used_save_info].type=fpu_restore; \ + used_save_info++; \ +} #endif +#include "dyn_fpu.h" static CacheBlock * CreateCacheBlock(CodePageHandler * codepage,PhysPt start,Bitu max_opcodes) { Bits i; @@ -1258,6 +1275,9 @@ static CacheBlock * CreateCacheBlock(CodePageHandler * codepage,PhysPt start,Bit used_save_info++; gen_releasereg(DREG(CYCLES)); decode.cycles=0; +#ifdef X86_DYNFPU_DH_ENABLED + bool fpu_used=false; +#endif while (max_opcodes--) { /* Init prefixes */ decode.big_addr=cpu.code.big; @@ -1467,8 +1487,8 @@ restart_prefix: case 0x8e:dyn_mov_seg_ev();break; /* POP Ev */ case 0x8f:dyn_pop_ev();break; - //NOP - case 0x90: + case 0x90: //NOP + case 0x9b: //WAIT/FWAIT break; //XCHG ax,reg case 0x91:case 0x92:case 0x93:case 0x94:case 0x95:case 0x96:case 0x97: @@ -1575,67 +1595,104 @@ restart_prefix: case 0xd3:dyn_grp2_ev(grp2_cl);break; //FPU #ifdef CPU_FPU -#ifdef X86_DYNFPU case 0xd8: +#ifdef X86_DYNFPU_DH_ENABLED + if (dyn_dh_fpu.dh_fpu_enabled) { + if (fpu_used) dh_fpu_esc0(); + else { + dh_fpu_startup(); + dh_fpu_esc0(); + } + } else +#endif dyn_fpu_esc0(); break; case 0xd9: +#ifdef X86_DYNFPU_DH_ENABLED + if (dyn_dh_fpu.dh_fpu_enabled) { + if (fpu_used) dh_fpu_esc1(); + else { + dh_fpu_startup(); + dh_fpu_esc1(); + } + } else +#endif dyn_fpu_esc1(); break; case 0xda: +#ifdef X86_DYNFPU_DH_ENABLED + if (dyn_dh_fpu.dh_fpu_enabled) { + if (fpu_used) dh_fpu_esc2(); + else { + dh_fpu_startup(); + dh_fpu_esc2(); + } + } else +#endif dyn_fpu_esc2(); break; case 0xdb: +#ifdef X86_DYNFPU_DH_ENABLED + if (dyn_dh_fpu.dh_fpu_enabled) { + if (fpu_used) dh_fpu_esc3(); + else { + dh_fpu_startup(); + dh_fpu_esc3(); + } + } else +#endif dyn_fpu_esc3(); break; case 0xdc: +#ifdef X86_DYNFPU_DH_ENABLED + if (dyn_dh_fpu.dh_fpu_enabled) { + if (fpu_used) dh_fpu_esc4(); + else { + dh_fpu_startup(); + dh_fpu_esc4(); + } + } else +#endif dyn_fpu_esc4(); break; case 0xdd: +#ifdef X86_DYNFPU_DH_ENABLED + if (dyn_dh_fpu.dh_fpu_enabled) { + if (fpu_used) dh_fpu_esc5(); + else { + dh_fpu_startup(); + dh_fpu_esc5(); + } + } else +#endif dyn_fpu_esc5(); break; case 0xde: +#ifdef X86_DYNFPU_DH_ENABLED + if (dyn_dh_fpu.dh_fpu_enabled) { + if (fpu_used) dh_fpu_esc6(); + else { + dh_fpu_startup(); + dh_fpu_esc6(); + } + } else +#endif dyn_fpu_esc6(); break; case 0xdf: +#ifdef X86_DYNFPU_DH_ENABLED + if (dyn_dh_fpu.dh_fpu_enabled) { + if (fpu_used) dh_fpu_esc7(); + else { + dh_fpu_startup(); + dh_fpu_esc7(); + } + } else +#endif dyn_fpu_esc7(); break; -#else - case 0xd8: - DYN_FPU_ESC(0); - break; - case 0xd9: - DYN_FPU_ESC(1); - break; - case 0xda: - DYN_FPU_ESC(2); - break; - case 0xdb: - DYN_FPU_ESC(3); - break; - case 0xdc: - DYN_FPU_ESC(4); - break; - case 0xdd: - DYN_FPU_ESC(5); - break; - case 0xde: - DYN_FPU_ESC(6); - break; - case 0xdf: - dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { - if (decode.modrm.val == 0xe0) gen_releasereg(DREG(EAX)); /* FSTSW */ - gen_call_function((void*)&FPU_ESC7_Normal,"%Id",decode.modrm.val); - } else { - dyn_fill_ea(); - gen_call_function((void*)&FPU_ESC7_EA,"%Id%Dd",decode.modrm.val,DREG(EA)); - gen_releasereg(DREG(EA)); - } - break; #endif -#endif - //Loop's + //Loops case 0xe2:dyn_loop(LOOP_NONE);goto finish_block; case 0xe3:dyn_loop(LOOP_JCXZ);goto finish_block; //IN AL/AX,imm diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 1b25e1bc..243966be 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.86 2006-10-04 19:24:52 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.87 2006-10-12 15:18:31 c2woody Exp $ */ #include #include "dosbox.h" @@ -56,6 +56,7 @@ void CPU_Core_Simple_Init(void); void CPU_Core_Dyn_X86_Init(void); void CPU_Core_Dyn_X86_Cache_Init(bool enable_cache); void CPU_Core_Dyn_X86_Cache_Close(void); +void CPU_Core_Dyn_X86_SetFPUMode(bool dh_fpu); /* In debug mode exceptions are tested and dosbox exits when * a unhandled exception state is detected. @@ -2060,6 +2061,10 @@ public: #if (C_DYNAMIC_X86) else if (!strcasecmp(core,"dynamic")) { cpudecoder=&CPU_Core_Dyn_X86_Run; + CPU_Core_Dyn_X86_SetFPUMode(true); + } else if (!strcasecmp(core,"dynamic_nodhfpu")) { + cpudecoder=&CPU_Core_Dyn_X86_Run; + CPU_Core_Dyn_X86_SetFPUMode(false); } else if (!strcasecmp(core,"auto")) { cpudecoder=&CPU_Core_Normal_Run; CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CORE; @@ -2070,7 +2075,7 @@ public: } #if (C_DYNAMIC_X86) - CPU_Core_Dyn_X86_Cache_Init(!strcasecmp(core,"dynamic")); + CPU_Core_Dyn_X86_Cache_Init(!strcasecmp(core,"dynamic") || !strcasecmp(core,"dynamic_nodhfpu")); #endif if(CPU_CycleMax <= 0) CPU_CycleMax = 2500; diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 09b10a58..f8c9714d 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -265,6 +265,9 @@ + + From d0a2e8859e74dfa2f83808899ba240c471879ae5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 13 Oct 2006 16:33:24 +0000 Subject: [PATCH 2623/4131] Make ansi use current page instead of page 0 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2708 --- src/dos/dev_con.h | 48 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 1e7c62d2..b108c38a 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.25 2006-04-07 16:34:07 c2woody Exp $ */ +/* $Id: dev_con.h,v 1.26 2006-10-13 16:33:24 qbix79 Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" @@ -50,7 +50,6 @@ private: Bit8s savecol; Bit8s saverow; } ansi; - }; bool device_CON::Read(Bit8u * data,Bit16u * size) { @@ -157,6 +156,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { continue; } /*ansi.esc and ansi.sci are true */ + Bit8u page = real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); switch(data[count]){ case '0': case '1': @@ -267,47 +267,47 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { case 'H':/* Cursor Pos*/ if(ansi.data[0]==0) ansi.data[0]=1; if(ansi.data[1]==0) ansi.data[1]=1; - INT10_SetCursorPos(--(ansi.data[0]),--(ansi.data[1]),0); /*ansi=1 based, int10 is 0 based */ + INT10_SetCursorPos(--(ansi.data[0]),--(ansi.data[1]),page); /*ansi=1 based, int10 is 0 based */ ClearAnsi(); break; /* cursor up down and forward and backward only change the row or the col not both */ case 'A': /* cursor up*/ - col=CURSOR_POS_COL(0) ; - row=CURSOR_POS_ROW(0) ; + col=CURSOR_POS_COL(page) ; + row=CURSOR_POS_ROW(page) ; tempdata = (ansi.data[0]? ansi.data[0] : 1); if(tempdata > row) { row=0; } else { row-=tempdata;} - INT10_SetCursorPos(row,col,0); + INT10_SetCursorPos(row,col,page); ClearAnsi(); break; case 'B': /*cursor Down */ - col=CURSOR_POS_COL(0) ; - row=CURSOR_POS_ROW(0) ; + col=CURSOR_POS_COL(page) ; + row=CURSOR_POS_ROW(page) ; tempdata = (ansi.data[0]? ansi.data[0] : 1); if(tempdata + static_cast(row) >= ansi.nrows) { row = ansi.nrows - 1;} else { row += tempdata; } - INT10_SetCursorPos(row,col,0); + INT10_SetCursorPos(row,col,page); ClearAnsi(); break; case 'C': /*cursor forward */ - col=CURSOR_POS_COL(0); - row=CURSOR_POS_ROW(0); + col=CURSOR_POS_COL(page); + row=CURSOR_POS_ROW(page); tempdata=(ansi.data[0]? ansi.data[0] : 1); if(tempdata + static_cast(col) >= ansi.ncols) { col = ansi.ncols - 1;} else { col += tempdata;} - INT10_SetCursorPos(row,col,0); + INT10_SetCursorPos(row,col,page); ClearAnsi(); break; case 'D': /*Cursor Backward */ - col=CURSOR_POS_COL(0); - row=CURSOR_POS_ROW(0); + col=CURSOR_POS_COL(page); + row=CURSOR_POS_ROW(page); tempdata=(ansi.data[0]? ansi.data[0] : 1); if(tempdata > col) {col = 0;} else { col -= tempdata;} - INT10_SetCursorPos(row,col,0); + INT10_SetCursorPos(row,col,page); ClearAnsi(); break; case 'J': /*erase screen and move cursor home*/ @@ -315,9 +315,9 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { if(ansi.data[0]!=2) {/* every version behaves like type 2 */ LOG(LOG_IOCTL,LOG_NORMAL)("ANSI: esc[%dJ called : not supported handling as 2",ansi.data[0]); } - INT10_ScrollWindow(0,0,255,255,0,ansi.attr,0xFF); + INT10_ScrollWindow(0,0,255,255,0,ansi.attr,page); ClearAnsi(); - INT10_SetCursorPos(0,0,0); + INT10_SetCursorPos(0,0,page); break; case 'h': /* SET MODE (if code =7 enable linewrap) */ case 'I': /* RESET MODE */ @@ -325,20 +325,20 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { ClearAnsi(); break; case 'u': /* Restore Cursor Pos */ - INT10_SetCursorPos(ansi.saverow,ansi.savecol,0); + INT10_SetCursorPos(ansi.saverow,ansi.savecol,page); ClearAnsi(); break; case 's': /* SAVE CURSOR POS */ - ansi.savecol=CURSOR_POS_COL(0); - ansi.saverow=CURSOR_POS_ROW(0); + ansi.savecol=CURSOR_POS_COL(page); + ansi.saverow=CURSOR_POS_ROW(page); ClearAnsi(); break; case 'K':/* erase till end of line (don't touch cursor) */ - col = CURSOR_POS_COL(0); - row = CURSOR_POS_ROW(0); - INT10_WriteChar(' ',ansi.attr,0,ansi.ncols-col,true); //Use this one to prevent scrolling when end of screen is reached + col = CURSOR_POS_COL(page); + row = CURSOR_POS_ROW(page); + INT10_WriteChar(' ',ansi.attr,page,ansi.ncols-col,true); //Use this one to prevent scrolling when end of screen is reached //for(i = col;i<(Bitu) ansi.ncols; i++) INT10_TeletypeOutputAttr(' ',ansi.attr,true); - INT10_SetCursorPos(row,col,0); + INT10_SetCursorPos(row,col,page); ClearAnsi(); break; case 'l':/* (if code =7) disable linewrap */ From 0e087c2f57ee6d90fc11344b495f2ab6c43958b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 13 Oct 2006 17:42:48 +0000 Subject: [PATCH 2624/4131] add dyn_fpu_dh.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2709 --- src/cpu/core_dyn_x86/dyn_fpu_dh.h | 498 ++++++++++++++++++++++++++++++ 1 file changed, 498 insertions(+) create mode 100644 src/cpu/core_dyn_x86/dyn_fpu_dh.h diff --git a/src/cpu/core_dyn_x86/dyn_fpu_dh.h b/src/cpu/core_dyn_x86/dyn_fpu_dh.h new file mode 100644 index 00000000..10fdeb3f --- /dev/null +++ b/src/cpu/core_dyn_x86/dyn_fpu_dh.h @@ -0,0 +1,498 @@ +/* + * Copyright (C) 2002-2005 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.1 2006-10-13 17:42:48 c2woody Exp $ */ + +#include "dosbox.h" +#if C_FPU + +static void FPU_FLD_16(PhysPt addr) { + dyn_dh_fpu.temp.m1 = (Bit32u)mem_readw_dyncorex86(addr); +} + +static void FPU_FST_16(PhysPt addr) { + mem_writew_dyncorex86(addr,(Bit16u)dyn_dh_fpu.temp.m1); +} + +static void FPU_FLD_32(PhysPt addr) { + dyn_dh_fpu.temp.m1 = mem_readd_dyncorex86(addr); +} + +static void FPU_FST_32(PhysPt addr) { + mem_writed_dyncorex86(addr,dyn_dh_fpu.temp.m1); +} + +static void FPU_FLD_64(PhysPt addr) { + dyn_dh_fpu.temp.m1 = mem_readd_dyncorex86(addr); + dyn_dh_fpu.temp.m2 = mem_readd_dyncorex86(addr+4); +} + +static void FPU_FST_64(PhysPt addr) { + mem_writed_dyncorex86(addr,dyn_dh_fpu.temp.m1); + mem_writed_dyncorex86(addr+4,dyn_dh_fpu.temp.m2); +} + +static void FPU_FLD_80(PhysPt addr) { + dyn_dh_fpu.temp.m1 = mem_readd_dyncorex86(addr); + dyn_dh_fpu.temp.m2 = mem_readd_dyncorex86(addr+4); + dyn_dh_fpu.temp.m3 = mem_readw_dyncorex86(addr+8); +} + +static void FPU_FST_80(PhysPt addr) { + mem_writed_dyncorex86(addr,dyn_dh_fpu.temp.m1); + mem_writed_dyncorex86(addr+4,dyn_dh_fpu.temp.m2); + mem_writew_dyncorex86(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,dyn_dh_fpu.cw); +} + +static void FPU_FNINIT_DH(void){ + dyn_dh_fpu.cw = 0x37f; +} + +static void FPU_FSTENV_DH(PhysPt addr){ + if(!cpu.code.big) { + mem_writew_dyncorex86(addr+0,(Bit16u)dyn_dh_fpu.cw); + mem_writew_dyncorex86(addr+2,(Bit16u)dyn_dh_fpu.temp.m2); + mem_writew_dyncorex86(addr+4,dyn_dh_fpu.temp.m3); + } else { + mem_writed_dyncorex86(addr+0,dyn_dh_fpu.temp.m1); + mem_writew_dyncorex86(addr+0,(Bit16u)dyn_dh_fpu.cw); + mem_writed_dyncorex86(addr+4,dyn_dh_fpu.temp.m2); + mem_writed_dyncorex86(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_dyncorex86(addr); + dyn_dh_fpu.temp.m1 = dyn_dh_fpu.cw|0x3f; + dyn_dh_fpu.temp.m2 = (Bit32u)mem_readw_dyncorex86(addr+2); + dyn_dh_fpu.temp.m3 = mem_readw_dyncorex86(addr+4); + } else { + dyn_dh_fpu.cw = (Bit32u)mem_readw_dyncorex86(addr); + dyn_dh_fpu.temp.m1 = mem_readd_dyncorex86(addr)|0x3f; + dyn_dh_fpu.temp.m2 = mem_readd_dyncorex86(addr+4); + dyn_dh_fpu.temp.m3 = mem_readw_dyncorex86(addr+8); + dyn_dh_fpu.temp.d1 = mem_readw_dyncorex86(addr+10); + } +} + +static void FPU_FSAVE_DH(PhysPt addr){ + if (!cpu.code.big) { + mem_writew_dyncorex86(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_dyncorex86(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_dyncorex86(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_dyncorex86(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 */ +// LOG_MSG("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 */ +// LOG_MSG("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 */ + LOG_MSG("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 */ + LOG_MSG("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 From 63fd72d9561577a5950aaedb9646258b4aabbd66 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 23 Oct 2006 18:57:43 +0000 Subject: [PATCH 2625/4131] Fix bug 1577423: "Name collision when building with Sun Studio 11 on Solaris." Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2710 --- src/hardware/mpu401.cpp | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 333119c9..44b4fa67 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.21 2006-05-23 10:30:29 qbix79 Exp $ */ +/* $Id: mpu401.cpp,v 1.22 2006-10-23 18:57:43 qbix79 Exp $ */ #include #include "dosbox.h" @@ -39,7 +39,7 @@ static void MPU401_EOIHandler(void); #define MPU401_TIMECONSTANT (60000000/1000.0f) enum MpuMode { M_UART,M_INTELLIGENT }; -enum MpuDataType {OVERFLOW,MARK,MIDI_SYS,MIDI_NORM,COMMAND}; +enum MpuDataType {T_OVERFLOW,T_MARK,T_MIDI_SYS,T_MIDI_NORM,T_COMMAND}; /* Messages sent to MPU-401 from host */ #define MSG_EOX 0xf7 @@ -226,10 +226,10 @@ static void MPU401_WriteCommand(Bitu port,Bitu val,Bitu iolen) { } for (Bitu i=0;i<8;i++) { mpu.playbuf[i].counter=0; - mpu.playbuf[i].type=OVERFLOW; + mpu.playbuf[i].type=T_OVERFLOW; } mpu.condbuf.counter=0; - mpu.condbuf.type=OVERFLOW; + mpu.condbuf.type=T_OVERFLOW; if (!(mpu.state.conductor=mpu.state.cond_set)) mpu.state.cond_req=0; mpu.state.amask=mpu.state.tmask; mpu.state.req_mask=0; @@ -389,8 +389,8 @@ static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) { mpu.condbuf.counter=val; break; case 1: /* Command byte #1 */ - mpu.condbuf.type=COMMAND; - if (val==0xf8 || val==0xf9) mpu.condbuf.type=OVERFLOW; + mpu.condbuf.type=T_COMMAND; + if (val==0xf8 || val==0xf9) mpu.condbuf.type=T_OVERFLOW; mpu.condbuf.value[mpu.condbuf.vlength]=val; mpu.condbuf.vlength++; if ((val&0xf0)!=0xe0) MPU401_EOIHandler(); @@ -425,28 +425,28 @@ static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) { switch (val&0xf0) { case 0xf0: /* System message or mark */ if (val>0xf7) { - mpu.playbuf[mpu.state.channel].type=MARK; + mpu.playbuf[mpu.state.channel].type=T_MARK; mpu.playbuf[mpu.state.channel].sys_val=val; length=1; } else { LOG(LOG_MISC,LOG_ERROR)("MPU-401:Illegal message"); - mpu.playbuf[mpu.state.channel].type=MIDI_SYS; + mpu.playbuf[mpu.state.channel].type=T_MIDI_SYS; mpu.playbuf[mpu.state.channel].sys_val=val; length=1; } break; case 0xc0: case 0xd0: /* MIDI Message */ - mpu.playbuf[mpu.state.channel].type=MIDI_NORM; + mpu.playbuf[mpu.state.channel].type=T_MIDI_NORM; length=mpu.playbuf[mpu.state.channel].length=2; break; case 0x80: case 0x90: case 0xa0: case 0xb0: case 0xe0: - mpu.playbuf[mpu.state.channel].type=MIDI_NORM; + mpu.playbuf[mpu.state.channel].type=T_MIDI_NORM; length=mpu.playbuf[mpu.state.channel].length=3; break; default: /* MIDI data with running status */ posd++; mpu.playbuf[mpu.state.channel].vlength++; - mpu.playbuf[mpu.state.channel].type=MIDI_NORM; + mpu.playbuf[mpu.state.channel].type=T_MIDI_NORM; length=mpu.playbuf[mpu.state.channel].length; break; } @@ -459,9 +459,9 @@ static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) { static void MPU401_IntelligentOut(Bit8u chan) { Bitu val; switch (mpu.playbuf[chan].type) { - case OVERFLOW: + case T_OVERFLOW: break; - case MARK: + case T_MARK: val=mpu.playbuf[chan].sys_val; if (val==0xfc) { MIDI_RawOutByte(val); @@ -469,7 +469,7 @@ static void MPU401_IntelligentOut(Bit8u chan) { mpu.state.req_mask&=~(1< Date: Fri, 27 Oct 2006 12:00:29 +0000 Subject: [PATCH 2626/4131] Add Beta1 patch: "Add functions needed by netbios.exe, Fix some trouble with armada in protected mode" by h-a-l-9000. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2711 --- include/ipx.h | 26 ++- include/pic.h | 1 + src/hardware/ipx.cpp | 369 ++++++++++++++++++++----------------- src/hardware/ipxserver.cpp | 4 +- src/hardware/pic.cpp | 26 ++- 5 files changed, 250 insertions(+), 176 deletions(-) diff --git a/include/ipx.h b/include/ipx.h index 5d2bc6e6..f99f0959 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.h,v 1.9 2006-02-26 13:46:31 qbix79 Exp $ */ +/* $Id: ipx.h,v 1.10 2006-10-27 12:00:25 qbix79 Exp $ */ #ifndef DOSBOX_IPX_H #define DOSBOX_IPX_H @@ -24,6 +24,12 @@ // Uncomment this for a lot of debug messages: //#define IPX_DEBUGMSG +#ifdef IPX_DEBUGMSG +#define LOG_IPX LOG_MSG +#else +#define LOG_IPX(...) +#endif + #ifndef DOSBOX_DOSBOX_H #include "dosbox.h" #endif @@ -70,7 +76,7 @@ struct PackedIP { struct nodeType { Uint8 node[6]; -}GCC_ATTRIBUTE(packed) ; +} GCC_ATTRIBUTE(packed) ; struct IPXHeader { Uint8 checkSum[2]; @@ -100,13 +106,18 @@ class ECBClass { public: RealPt ECBAddr; bool isInESRList; - ECBClass *prevECB; + ECBClass *prevECB; // Linked List ECBClass *nextECB; - Bit8u iuflag; + + Bit8u iuflag; // Need to save data since we are not always in + Bit16u mysocket; // real mode - #ifdef IPX_DEBUGMSG + Bit8u* databuffer; // received data is stored here until we get called + Bitu buflen; // by Interrupt + +#ifdef IPX_DEBUGMSG Bitu SerialNumber; - #endif +#endif ECBClass(Bit16u segment, Bit16u offset); Bit16u getSocket(void); @@ -119,6 +130,9 @@ public: Bit16u getFragCount(void); + bool writeData(); + void writeDataBuffer(Bit8u* buffer, Bit16u length); + void getFragDesc(Bit16u descNum, fragmentDescriptor *fragDesc); RealPt getESRAddr(void); diff --git a/include/pic.h b/include/pic.h index 90a49b47..37e61c9d 100644 --- a/include/pic.h +++ b/include/pic.h @@ -57,6 +57,7 @@ bool PIC_RunQueue(void); //Delay in milliseconds void PIC_AddEvent(PIC_EventHandler handler,float delay,Bitu val=0); void PIC_RemoveEvents(PIC_EventHandler handler); +void PIC_RemoveSpecificEvents(PIC_EventHandler handler, Bitu val); void PIC_SetIRQMask(Bitu irq, bool masked); #endif diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index 907c6ca2..90930a12 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.cpp,v 1.10 2006-02-26 13:46:31 qbix79 Exp $ */ +/* $Id: ipx.cpp,v 1.11 2006-10-27 12:00:29 qbix79 Exp $ */ #include "dosbox.h" @@ -49,14 +49,13 @@ struct ipxnetaddr { Uint8 netnode[6]; } localIpxAddr; -Bit32u tcpPort; +Bit32u udpPort; bool isIpxServer; bool isIpxConnected; -IPaddress ipxClientIp; // IPAddress for client connection to server -IPaddress ipxServConnIp; // IPAddress for client connection to server +IPaddress ipxServConnIp; // IPAddress for client connection to server UDPsocket ipxClientSocket; -int UDPChannel; // Channel used by UDP connection -Bit8u recvBuffer[IPXBUFFERSIZE]; // Incoming packet buffer +int UDPChannel; // Channel used by UDP connection +Bit8u recvBuffer[IPXBUFFERSIZE]; // Incoming packet buffer static RealPt ipx_callback; @@ -92,13 +91,14 @@ Bitu ECBAmount = 0; ECBClass::ECBClass(Bit16u segment, Bit16u offset) { ECBAddr = RealMake(segment, offset); + databuffer = 0; #ifdef IPX_DEBUGMSG SerialNumber = ECBSerialNumber; ECBSerialNumber++; ECBAmount++; - LOG_MSG("ECB: SN%7d created. Number of ECBs: %3d, ESR %4x:%4x, ECB %4x:%4x", + LOG_IPX("ECB: SN%7d created. Number of ECBs: %3d, ESR %4x:%4x, ECB %4x:%4x", SerialNumber,ECBAmount, real_readw(RealSeg(ECBAddr), RealOff(ECBAddr)+6), @@ -121,6 +121,41 @@ ECBClass::ECBClass(Bit16u segment, Bit16u offset) { useECB->nextECB = this; this->prevECB = useECB; } + + iuflag = getInUseFlag(); + mysocket = getSocket(); +} +void ECBClass::writeDataBuffer(Bit8u* buffer, Bit16u length) { + if(databuffer!=0) delete [] databuffer; + databuffer = new Bit8u[length]; + memcpy(databuffer,buffer,length); + buflen=length; + +} +bool ECBClass::writeData() { + Bitu length=buflen; + Bit8u* buffer = databuffer; + fragmentDescriptor tmpFrag; + setInUseFlag(USEFLAG_AVAILABLE); + Bitu fragCount = getFragCount(); + Bitu bufoffset = 0; + for(Bitu i = 0;i < fragCount;i++) { + getFragDesc(i,&tmpFrag); + for(Bitu t = 0;t < tmpFrag.size;t++) { + real_writeb(tmpFrag.segment, tmpFrag.offset + t, buffer[bufoffset]); + bufoffset++; + if(bufoffset >= length) { + setCompletionFlag(COMP_SUCCESS); + setImmAddress(&buffer[22]); // Write in source node + return true; + } + } + } + if(bufoffset < length) { + setCompletionFlag(COMP_MALFORMED); + return false; + } + return false; } Bit16u ECBClass::getSocket(void) { @@ -162,10 +197,8 @@ RealPt ECBClass::getESRAddr(void) { void ECBClass::NotifyESR(void) { Bit32u ESRval = real_readd(RealSeg(ECBAddr), RealOff(ECBAddr)+4); - if(ESRval) { -#ifdef IPX_DEBUGMSG - LOG_MSG("ECB: SN%7d to be notified.", SerialNumber); -#endif + if(ESRval || databuffer) { // databuffer: write data at realmode/v86 time + // LOG_IPX("ECB: SN%7d to be notified.", SerialNumber); // take the ECB out of the current list if(prevECB == NULL) { // was the first in the list ECBList = nextECB; @@ -190,7 +223,6 @@ void ECBClass::NotifyESR(void) { prevECB = useECB; } isInESRList = true; - //LOG_MSG("ECB put to notification list"); PIC_ActivateIRQ(11); } // this one does not want to be notified, delete it right away @@ -210,7 +242,7 @@ void ECBClass::getImmAddress(Bit8u* immAddr) { ECBClass::~ECBClass() { #ifdef IPX_DEBUGMSG ECBAmount--; - LOG_MSG("ECB: SN%7d destroyed. Remaining ECBs: %3d", SerialNumber,ECBAmount); + LOG_IPX("ECB: SN%7d destroyed. Remaining ECBs: %3d", SerialNumber,ECBAmount); #endif if(isInESRList) { @@ -225,6 +257,7 @@ ECBClass::~ECBClass() { if(nextECB != NULL) nextECB->prevECB = prevECB; } } + if(databuffer!=0) delete [] databuffer; } @@ -238,7 +271,6 @@ static bool sockInUse(Bit16u sockNum) { static void OpenSocket(void) { Bit16u sockNum, sockAlloc; - //LOG_MSG("IPX: DOSINT used."); sockNum = swapByte(reg_dx); if(socketCount >= SOCKTABLESIZE) { @@ -251,7 +283,8 @@ static void OpenSocket(void) { sockAlloc = 0x4002; while(sockInUse(sockAlloc) && (sockAlloc < 0x7fff)) sockAlloc++; if(sockAlloc > 0x7fff) { - // I have no idea how this could happen if the IPX driver is limited to 150 open sockets at a time + // I have no idea how this could happen if the IPX driver + // is limited to 150 open sockets at a time LOG_MSG("IPX: Out of dynamic sockets"); } sockNum = sockAlloc; @@ -311,46 +344,59 @@ static bool IPX_Multiplex(void) { return true; } +static void IPX_AES_EventHandler(Bitu param) +{ + ECBClass* tmpECB = ECBList; + ECBClass* tmp2ECB; + while(tmpECB!=0) { + tmp2ECB = tmpECB->nextECB; + if(tmpECB->iuflag==USEFLAG_AESCOUNT && param==(Bitu)tmpECB->ECBAddr) { + tmpECB->setCompletionFlag(COMP_SUCCESS); + tmpECB->setInUseFlag(USEFLAG_AVAILABLE); + tmpECB->NotifyESR(); + // LOG_IPX("AES Notification: ECB S/N %d",tmpECB->SerialNumber); + return; + } + tmpECB = tmp2ECB; + } + LOG_MSG("!!!! Rouge AES !!!!" ); +} + static void sendPacket(ECBClass* sendecb); static void handleIpxRequest(void) { ECBClass *tmpECB; switch (reg_bx) { - case 0x0000: // Open socket + case 0x0000: // Open socket OpenSocket(); -#ifdef IPX_DEBUGMSG - LOG_MSG("IPX: Open socket %4x", swapByte(reg_dx)); -#endif + LOG_IPX("IPX: Open socket %4x", swapByte(reg_dx)); break; - case 0x0001: // Close socket -#ifdef IPX_DEBUGMSG - LOG_MSG("IPX: Close socket %4x", swapByte(reg_dx)); -#endif + case 0x0001: // Close socket + LOG_IPX("IPX: Close socket %4x", swapByte(reg_dx)); CloseSocket(); break; case 0x0002: // get local target - // es:si - // Currently no support for multiple networks + // es:si + // Currently no support for multiple networks for(Bitu i = 0; i < 6; i++) real_writeb(SegValue(es),reg_di+i,real_readb(SegValue(es),reg_si+i+4)); - reg_cx=1; // time ticks expected - reg_al=0x00;//success + reg_cx=1; // time ticks expected + reg_al=0x00; //success break; - case 0x0003: // Send packet + case 0x0003: // Send packet + tmpECB = new ECBClass(SegValue(es),reg_si); if(!incomingPacket.connected) { - tmpECB = new ECBClass(SegValue(es),reg_si); tmpECB->setInUseFlag(USEFLAG_AVAILABLE); tmpECB->setCompletionFlag(COMP_UNDELIVERABLE); delete tmpECB; // not notify? reg_al = 0xff; // Failure } else { - tmpECB = new ECBClass(SegValue(es),reg_si); tmpECB->setInUseFlag(USEFLAG_SENDING); - //LOG_MSG("IPX: Sending packet on %4x", tmpECB->getSocket()); + //LOG_IPX("IPX: Sending packet on %4x", tmpECB->getSocket()); reg_al = 0x00; // Success sendPacket(tmpECB); } @@ -358,6 +404,7 @@ static void handleIpxRequest(void) { break; case 0x0004: // Listen for packet tmpECB = new ECBClass(SegValue(es),reg_si); + // LOG_IPX("ECB: SN%7d RECEIVE.", tmpECB->SerialNumber); if(!sockInUse(tmpECB->getSocket())) { // Socket is not open reg_al = 0xff; tmpECB->setInUseFlag(USEFLAG_AVAILABLE); @@ -366,73 +413,86 @@ static void handleIpxRequest(void) { } else { reg_al = 0x00; // Success tmpECB->setInUseFlag(USEFLAG_LISTENING); - /*LOG_MSG("IPX: Listen for packet on 0x%4x - ESR address %4x:%4x", + /*LOG_IPX("IPX: Listen for packet on 0x%4x - ESR address %4x:%4x", tmpECB->getSocket(), RealSeg(tmpECB->getESRAddr()), RealOff(tmpECB->getESRAddr()));*/ } - - break; - case 0x0006: // cancel operation - { - RealPt ecbaddress = RealMake(SegValue(es),reg_si); - ECBClass* tmpECB= ECBList; - ECBClass* tmp2ECB; - while(tmpECB) { - tmp2ECB=tmpECB->nextECB; - if(tmpECB->ECBAddr == ecbaddress) { - tmpECB->setInUseFlag(USEFLAG_AVAILABLE); - tmpECB->setCompletionFlag(COMP_CANCELLED); - delete tmpECB; - reg_al=0; // Success -#ifdef IPX_DEBUGMSG - LOG_MSG("IPX: ECB canceled."); -#endif - return; - } - tmpECB=tmp2ECB; - } - reg_al=0xff; // Fail - break; - } - case 0x0008: // Get interval marker - // ???? - break; - case 0x0009: // Get internetwork address - { -#ifdef IPX_DEBUGMSG - LOG_MSG("IPX: Get internetwork address %2x:%2x:%2x:%2x:%2x:%2x", localIpxAddr.netnode[5], localIpxAddr.netnode[4], localIpxAddr.netnode[3], localIpxAddr.netnode[2], localIpxAddr.netnode[1], localIpxAddr.netnode[0]); -#endif - Bit8u * addrptr = (Bit8u *)&localIpxAddr; - for(Bit16u i=0;i<10;i++) { - real_writeb(SegValue(es),reg_si+i,addrptr[i]); - } - break; - } - case 0x000a: // Relinquish control - // Idle thingy - break; - case 0x000b: // Disconnect from Target - // We don't even connect - break; - case 0x0010: // SPX install check - { - reg_al=0; // SPX not installed - break; - } - case 0x001a: // get driver maximum packet size - { - reg_cx=0; // retry count - reg_ax=IPXBUFFERSIZE; // max packet size - break; + case 0x0005: // SCHEDULE IPX EVENT + case 0x0007: // SCHEDULE SPECIAL IPX EVENT + { + tmpECB = new ECBClass(SegValue(es),reg_si); + // LOG_IPX("ECB: SN%7d AES. T=%fms.", tmpECB->SerialNumber, + // (1000.0f/(1193182.0f/65536.0f))*(float)reg_ax); + PIC_AddEvent(IPX_AES_EventHandler, + (1000.0f/(1193182.0f/65536.0f))*(float)reg_ax,(Bitu)tmpECB->ECBAddr); + tmpECB->setInUseFlag(USEFLAG_AESCOUNT); + break; + } + case 0x0006: // cancel operation + { + RealPt ecbaddress = RealMake(SegValue(es),reg_si); + ECBClass* tmpECB= ECBList; + ECBClass* tmp2ECB; + while(tmpECB) { + tmp2ECB=tmpECB->nextECB; + if(tmpECB->ECBAddr == ecbaddress) { + if(tmpECB->getInUseFlag()==USEFLAG_AESCOUNT) + PIC_RemoveSpecificEvents(IPX_AES_EventHandler,(Bitu)ecbaddress); + tmpECB->setInUseFlag(USEFLAG_AVAILABLE); + tmpECB->setCompletionFlag(COMP_CANCELLED); + delete tmpECB; + reg_al=0; // Success + LOG_IPX("IPX: ECB canceled."); + return; + } + tmpECB=tmp2ECB; } + reg_al=0xff; // Fail + break; + } + case 0x0008: // Get interval marker + reg_ax = mem_readw(0x46c); // BIOS_TIMER + break; + case 0x0009: // Get internetwork address + { + LOG_IPX("IPX: Get internetwork address %2x:%2x:%2x:%2x:%2x:%2x", + localIpxAddr.netnode[5], localIpxAddr.netnode[4], + localIpxAddr.netnode[3], localIpxAddr.netnode[2], + localIpxAddr.netnode[1], localIpxAddr.netnode[0]); + + Bit8u * addrptr = (Bit8u *)&localIpxAddr; + for(Bit16u i=0;i<10;i++) + real_writeb(SegValue(es),reg_si+i,addrptr[i]); + break; + } + case 0x000a: // Relinquish control + break; // Idle thingy + + case 0x000b: // Disconnect from Target + break; // We don't even connect + + case 0x000d: // get packet size + reg_cx=0; // retry count + reg_ax=1024; // real implementation returns 1024 + break; + + case 0x0010: // SPX install check + reg_al=0; // SPX not installed + break; + + case 0x001a: // get driver maximum packet size + reg_cx=0; // retry count + reg_ax=IPXBUFFERSIZE; // max packet size: something near the + // ethernet packet size + break; + default: LOG_MSG("Unhandled IPX function: %4x", reg_bx); break; } - } // Entrypoint handler @@ -506,19 +566,16 @@ static void pingSend(void) { static void receivePacket(Bit8u *buffer, Bit16s bufSize) { ECBClass *useECB; ECBClass *nextECB; - fragmentDescriptor tmpFrag; - Bit16u i, fragCount,t; - Bit16s bufoffset; Bit16u *bufword = (Bit16u *)buffer; Bit16u useSocket = swapByte(bufword[8]); - Bit32u hostaddr; IPXHeader * tmpHeader; tmpHeader = (IPXHeader *)buffer; // Check to see if ping packet if(useSocket == 0x2) { // Is this a broadcast? - if((tmpHeader->dest.addr.byIP.host == 0xffffffff) && (tmpHeader->dest.addr.byIP.port == 0xffff)) { + if((tmpHeader->dest.addr.byIP.host == 0xffffffff) && + (tmpHeader->dest.addr.byIP.port == 0xffff)) { // Yes. We should return the ping back to the sender IPaddress tmpAddr; UnpackIP(tmpHeader->src.addr.byIP, &tmpAddr); @@ -531,40 +588,14 @@ static void receivePacket(Bit8u *buffer, Bit16s bufSize) { while(useECB != NULL) { nextECB = useECB->nextECB; - if(useECB->getInUseFlag() == USEFLAG_LISTENING) { - if(useECB->getSocket() == useSocket) { - useECB->setInUseFlag(USEFLAG_AVAILABLE); - fragCount = useECB->getFragCount(); - bufoffset = 0; - for(i=0;igetFragDesc(i,&tmpFrag); - for(t=0;t=bufSize) { - useECB->setCompletionFlag(COMP_SUCCESS); - useECB->setImmAddress(&buffer[22]); // Write in source node - hostaddr = *((Bit32u *)&buffer[24]); -#ifdef IPX_DEBUGMSG - LOG_MSG("IPX: Received packet of %d bytes from %d.%d.%d.%d (%x CRC)", bufSize, CONVIP(hostaddr), packetCRC(&buffer[30], bufSize-30)); -#endif - useECB->NotifyESR(); - return; - } - } - } - if(bufoffset < bufSize) { - useECB->setCompletionFlag(COMP_MALFORMED); - useECB->NotifyESR(); - return; - } - } + if(useECB->iuflag == USEFLAG_LISTENING && useECB->mysocket == useSocket) { + useECB->writeDataBuffer(buffer, bufSize); + useECB->NotifyESR(); + return; } useECB = nextECB; } -#ifdef IPX_DEBUGMSG - LOG_MSG("IPX: RX Packet loss!"); -#endif + LOG_IPX("IPX: RX Packet loss!"); } static void IPX_ClientLoop(void) { @@ -608,15 +639,23 @@ static void sendPacket(ECBClass* sendecb) { // Must put source address into header Bit8u * addrptr; + // source netnum addrptr = (Bit8u *)&localIpxAddr.netnum; for(Bit16u m=0;m<4;m++) { real_writeb(tmpFrag.segment,tmpFrag.offset+m+18,addrptr[m]); } + // source node number addrptr = (Bit8u *)&localIpxAddr.netnode; for(Bit16u m=0;m<6;m++) { real_writeb(tmpFrag.segment,tmpFrag.offset+m+22,addrptr[m]); } + // Source socket + real_writew(tmpFrag.segment,tmpFrag.offset+28, swapByte(sendecb->getSocket())); + + // blank checksum + real_writew(tmpFrag.segment,tmpFrag.offset, 0xffff); } + for(t=0;tgetSocket()); + //wordptr[14] = swapByte(sendecb->getSocket()); + + sendecb->getFragDesc(0,&tmpFrag); + real_writew(tmpFrag.segment,tmpFrag.offset+2, swapByte(packetsize)); + Bit8u immedAddr[6]; sendecb->getImmAddress(immedAddr); @@ -657,7 +700,7 @@ static void sendPacket(ECBClass* sendecb) { if(addrptr[m]!=outbuffer[m+0xa])isloopback=false; if(immedAddr[m]!=0xff) islocalbroadcast=false; } - + LOG_IPX("SEND crc:%2x",packetCRC(&outbuffer[0], packetsize)); if(!isloopback) { outPacket.channel = UDPChannel; outPacket.data = (Uint8 *)&outbuffer[0]; @@ -674,16 +717,15 @@ static void sendPacket(ECBClass* sendecb) { return; } else { sendecb->setCompletionFlag(COMP_SUCCESS); -#ifdef IPX_DEBUGMSG - LOG_MSG("Packet sent: size: %d",packetsize); -#endif + LOG_IPX("Packet sent: size: %d",packetsize); } } + else sendecb->setCompletionFlag(COMP_SUCCESS); + if(isloopback||islocalbroadcast) { + // Send packet back to ourselves. receivePacket(&outbuffer[0],packetsize); -#ifdef IPX_DEBUGMSG - LOG_MSG("Packet back: loopback:%d, broadcast:%d",isloopback,isbroadcast); -#endif + LOG_IPX("Packet back: loopback:%d, broadcast:%d",isloopback,islocalbroadcast); } sendecb->NotifyESR(); } @@ -710,14 +752,13 @@ bool ConnectToServer(char *strAddr) { int numsent; UDPpacket regPacket; IPXHeader regHeader; + if(!SDLNet_ResolveHost(&ipxServConnIp, strAddr, (Bit16u)udpPort)) { - if(!SDLNet_ResolveHost(&ipxServConnIp, strAddr, (Bit16u)tcpPort)) { // Generate the MAC address. This is made by zeroing out the first two // octets and then using the actual IP address for the last 4 octets. // This idea is from the IPX over IP implementation as specified in RFC 1234: // http://www.faqs.org/rfcs/rfc1234.html - // Select an anonymous UDP port ipxClientSocket = SDLNet_UDP_Open(0); if(ipxClientSocket) { @@ -743,7 +784,8 @@ bool ConnectToServer(char *strAddr) { regPacket.len = sizeof(regHeader); regPacket.maxlen = sizeof(regHeader); regPacket.channel = UDPChannel; - // Send registration string to server. If server doesn't get this, client will not be registered + // Send registration string to server. If server doesn't get + // this, client will not be registered numsent = SDLNet_UDP_Send(ipxClientSocket, regPacket.channel, ®Packet); if(!numsent) { @@ -751,7 +793,8 @@ bool ConnectToServer(char *strAddr) { SDLNet_UDP_Close(ipxClientSocket); return false; } else { - // Wait for return packet from server. This will contain our IPX address and port num + // Wait for return packet from server. + // This will contain our IPX address and port num Bits result; Bit32u ticks, elapsed; ticks = GetTicks(); @@ -898,11 +941,11 @@ public: } bool startsuccess; if(!cmd->FindCommand(2, temp_line)) { - tcpPort = 213; + udpPort = 213; } else { - tcpPort = strtol(temp_line.c_str(), NULL, 10); + udpPort = strtol(temp_line.c_str(), NULL, 10); } - startsuccess = IPX_StartServer((Bit16u)tcpPort); + startsuccess = IPX_StartServer((Bit16u)udpPort); if(startsuccess) { WriteOut("IPX Tunneling Server started\n"); isIpxServer = true; @@ -923,7 +966,6 @@ public: DisconnectFromServer(false); IPX_StopServer(); WriteOut("IPX Tunneling Server stopped."); - // Don't know how to stop the timer just yet. } return; } @@ -940,9 +982,9 @@ public: strcpy(strHost, temp_line.c_str()); if(!cmd->FindCommand(3, temp_line)) { - tcpPort = 213; + udpPort = 213; } else { - tcpPort = strtol(temp_line.c_str(), NULL, 10); + udpPort = strtol(temp_line.c_str(), NULL, 10); } if(ConnectToServer(strHost)) { @@ -959,7 +1001,6 @@ public: return; } // TODO: Send a packet to the server notifying of disconnect - WriteOut("IPX Tunneling Client disconnected from server.\n"); DisconnectFromServer(false); return; @@ -971,7 +1012,7 @@ public: if(isIpxServer) WriteOut("ACTIVE\n"); else WriteOut("INACTIVE\n"); WriteOut("Client status: "); if(incomingPacket.connected) { - WriteOut("CONNECTED -- Server at %d.%d.%d.%d port %d\n", CONVIP(ipxServConnIp.host), tcpPort); + WriteOut("CONNECTED -- Server at %d.%d.%d.%d port %d\n", CONVIP(ipxServConnIp.host), udpPort); } else { WriteOut("DISCONNECTED\n"); } @@ -1017,30 +1058,25 @@ static void IPXNET_ProgramStart(Program * * make) { *make=new IPXNET; } -Bitu IPX_ESRHandler1(void) { -#ifdef IPX_DEBUGMSG - LOG_MSG("ESRhandler entered" ); -#endif +Bitu IPX_ESRHandler(void) { + LOG_IPX("ESR: >>>>>>>>>>>>>>>" ); while(ESRList!=NULL) { -#ifdef IPX_DEBUGMSG - LOG_MSG("ECB: SN%7d notified.", ESRList->SerialNumber); -#endif - - // setup registers - SegSet16(es, RealSeg(ESRList->ECBAddr)); - reg_si = RealOff(ESRList->ECBAddr); - reg_al = 0xff; - CALLBACK_RunRealFar(RealSeg(ESRList->getESRAddr()), RealOff(ESRList->getESRAddr())); + // LOG_IPX("ECB: SN%7d notified.", ESRList->SerialNumber); + if(ESRList->databuffer) ESRList->writeData(); + if(ESRList->getESRAddr()) { + // setup registers + SegSet16(es, RealSeg(ESRList->ECBAddr)); + reg_si = RealOff(ESRList->ECBAddr); + reg_al = 0xff; + CALLBACK_RunRealFar(RealSeg(ESRList->getESRAddr()), + RealOff(ESRList->getESRAddr())); + } delete ESRList; } // while IO_WriteB(0xa0,0x63); //EOI11 IO_WriteB(0x20,0x62); //EOI2 - -#ifdef IPX_DEBUGMSG - LOG_MSG("ESR loop done."); -#endif - + LOG_IPX("ESR: <<<<<<<<<<<<<<<"); return CBRET_NONE; } @@ -1079,17 +1115,15 @@ public: callback_ipxint.Install(&IPX_IntHandler,CB_IRET,"IPX (int 7a)"); callback_ipxint.Set_RealVec(0x7a); - callback_esr.Allocate(&IPX_ESRHandler1,"IPX_ESR"); + callback_esr.Allocate(&IPX_ESRHandler,"IPX_ESR"); Bit16u call_ipxesr1 = callback_esr.Get_callback(); if(!dospage) dospage = DOS_GetMemory(2); // can not be freed yet PhysPt phyDospage = PhysMake(dospage,0); -#ifdef IPX_DEBUGMSG - LOG_MSG("IPX INT address: %x", ipx_intcallback); - LOG_MSG("ESR callback address: %x, HandlerID %d", phyDospage,call_ipxesr1); -#endif + LOG_IPX("ESR callback address: %x, HandlerID %d", phyDospage,call_ipxesr1); + //save registers phys_writeb(phyDospage+0,(Bit8u)0xFA); // CLI phys_writeb(phyDospage+1,(Bit8u)0x60); // PUSHA @@ -1127,6 +1161,7 @@ public: ~IPX() { Section_prop * section = static_cast(m_configuration); + PIC_RemoveEvents(IPX_AES_EventHandler); if(!section->Get_bool("ipx")) return; if(isIpxServer) { diff --git a/src/hardware/ipxserver.cpp b/src/hardware/ipxserver.cpp index f5d84ae3..5bd4d160 100644 --- a/src/hardware/ipxserver.cpp +++ b/src/hardware/ipxserver.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipxserver.cpp,v 1.7 2006-02-09 11:47:49 qbix79 Exp $ */ +/* $Id: ipxserver.cpp,v 1.8 2006-10-27 12:00:29 qbix79 Exp $ */ #include "dosbox.h" @@ -135,7 +135,7 @@ static void ackClient(IPaddress clientAddr) { PackIP(clientAddr, ®Header.dest.addr.byIP); SDLNet_Write16(0x2, regHeader.dest.socket); - SDLNet_Write32(0, regHeader.src.network); + SDLNet_Write32(1, regHeader.src.network); PackIP(ipxServerIp, ®Header.src.addr.byIP); SDLNet_Write16(0x2, regHeader.src.socket); regHeader.transControl = 0; diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 9a1a9866..90e35073 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.35 2006-05-23 10:30:02 qbix79 Exp $ */ +/* $Id: pic.cpp,v 1.36 2006-10-27 12:00:29 qbix79 Exp $ */ #include @@ -393,6 +393,30 @@ void PIC_AddEvent(PIC_EventHandler handler,float delay,Bitu val) { AddEntry(entry); } +void PIC_RemoveSpecificEvents(PIC_EventHandler handler, Bitu val) { + PICEntry * entry=pic.next_entry; + PICEntry * prev_entry; + prev_entry = 0; + while (entry) { + if ((entry->event == handler) && (entry->value == val)) { + if (prev_entry) { + prev_entry->next=entry->next; + entry->next=pic.free_entry; + pic.free_entry=entry; + entry=prev_entry->next; + continue; + } else { + pic.next_entry=entry->next; + entry->next=pic.free_entry; + pic.free_entry=entry; + entry=pic.next_entry; + continue; + } + } + prev_entry=entry; + entry=entry->next; + } +} void PIC_RemoveEvents(PIC_EventHandler handler) { PICEntry * entry=pic.next_entry; From ded957188a45de1222ddb45ebdfe2b1633904739 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 27 Oct 2006 12:01:52 +0000 Subject: [PATCH 2627/4131] Add Beta1 patch: "Add very basic Clipper support." by wd. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2712 --- src/cpu/core_normal.cpp | 3 +++ src/cpu/core_normal/prefix_none.h | 12 +++++++++++- src/cpu/core_simple.cpp | 3 +++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 14e65403..e74b9ee1 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -71,6 +71,7 @@ extern Bitu cycle_count; #define DO_PREFIX_SEG(_SEG) \ BaseDS=SegBase(_SEG); \ BaseSS=SegBase(_SEG); \ + core.base_val_ds=_SEG; \ goto restart_opcode; #define DO_PREFIX_ADDR() \ @@ -92,6 +93,7 @@ static struct { Bitu opcode_index; PhysPt cseip; PhysPt base_ds,base_ss; + SegNames base_val_ds; bool rep_zero; Bitu prefixes; GetEAHandler * ea_table; @@ -142,6 +144,7 @@ Bits CPU_Core_Normal_Run(void) { core.ea_table=&EATable[cpu.code.big*256]; BaseDS=SegBase(ds); BaseSS=SegBase(ss); + core.base_val_ds=ds; #if C_DEBUG #if C_HEAVY_DEBUG if (DEBUG_HeavyIsBreakpoint()) { diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 97ea24d2..b7b4f174 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -431,7 +431,17 @@ { GetRMrb; if (rm >= 0xc0 ) {GetEArb;*earb=*rmrb;} - else {GetEAa;SaveMb(eaa,*rmrb);} + else { + if (cpu.pmode) { + Descriptor desc; + cpu.gdt.GetDescriptor(SegValue(core.base_val_ds),desc); + if ((desc.Type()==DESC_CODE_R_NC_A) || (desc.Type()==DESC_CODE_R_NC_NA)) { + CPU_Exception(EXCEPTION_GP,SegValue(core.base_val_ds) & 0xfffc); + continue; + } + } + GetEAa;SaveMb(eaa,*rmrb); + } break; } CASE_W(0x89) /* MOV Ew,Gw */ diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp index c07aeba7..e79514ab 100644 --- a/src/cpu/core_simple.cpp +++ b/src/cpu/core_simple.cpp @@ -63,6 +63,7 @@ extern Bitu cycle_count; #define DO_PREFIX_SEG(_SEG) \ BaseDS=SegBase(_SEG); \ BaseSS=SegBase(_SEG); \ + core.base_val_ds=_SEG; \ goto restart_opcode; #define DO_PREFIX_ADDR() \ @@ -84,6 +85,7 @@ static struct { Bitu opcode_index; HostPt cseip; PhysPt base_ds,base_ss; + SegNames base_val_ds; bool rep_zero; Bitu prefixes; GetEAHandler * ea_table; @@ -137,6 +139,7 @@ Bits CPU_Core_Simple_Run(void) { core.ea_table=&EATable[cpu.code.big*256]; BaseDS=SegBase(ds); BaseSS=SegBase(ss); + core.base_val_ds=ds; #if C_DEBUG #if C_HEAVY_DEBUG if (DEBUG_HeavyIsBreakpoint()) { From 648eaeb2a2f1312b9f0ce59e4ae5b720245c1d61 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 27 Oct 2006 12:03:22 +0000 Subject: [PATCH 2628/4131] Add Beta1 patch: "Require devices to have valid leading directories." Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2713 --- src/dos/dos_devices.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index ed436f10..06fedc32 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_devices.cpp,v 1.13 2006-04-16 14:02:39 qbix79 Exp $ */ +/* $Id: dos_devices.cpp,v 1.14 2006-10-27 12:03:22 qbix79 Exp $ */ #include #include "dosbox.h" @@ -132,6 +132,15 @@ Bit8u DOS_FindDevice(char * name) { char* dot= strrchr(temp,'.'); if(dot && *dot) *dot=0; //no ext checking + char* leading = strrchr(temp,'\\'); + if(leading) { + *leading = 0; + Bit8u drive;char fulldir[DOS_PATHLENGTH]; + if (!DOS_MakeName(temp,fulldir,&drive)) return DOS_DEVICES; + if(!Drives[drive]->TestDir(fulldir)) return DOS_DEVICES; + *leading='\\'; + } + /* loop through devices */ for(Bit8u index = 0;index < DOS_DEVICES;index++) { if (Devices[index]) { From 712a055b7bf16f00755b37b097d6e92a544e1681 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 27 Oct 2006 12:07:41 +0000 Subject: [PATCH 2629/4131] Add Beta1 patch: "Remove ida4 mouse unhiding. It's a but in the application afterall. Change type of mouse.shown." Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2714 --- src/ints/mouse.cpp | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 7e805b48..0f8fe0e6 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.64 2006-09-02 17:03:43 c2woody Exp $ */ +/* $Id: mouse.cpp,v 1.65 2006-10-27 12:07:41 qbix79 Exp $ */ #include #include @@ -86,7 +86,7 @@ static struct { Bit16u last_released_y[MOUSE_BUTTONS]; Bit16u last_pressed_x[MOUSE_BUTTONS]; Bit16u last_pressed_y[MOUSE_BUTTONS]; - Bit16s shown; + Bit16u shown; float add_x,add_y; Bit16u min_x,max_x,min_y,max_y; float mickey_x,mickey_y; @@ -116,7 +116,7 @@ static struct { Bit16u doubleSpeedThreshold; Bit16u language; Bit16u cursorType; - Bit16s oldshown; + Bit16u oldshown; Bit8u page; bool enabled; @@ -216,7 +216,7 @@ extern void ReadCharAttr(Bit16u col,Bit16u row,Bit8u page,Bit16u * result); void RestoreCursorBackgroundText() { - if (mouse.shown<0) return; + if (mouse.shown) return; if (mouse.background) { WriteChar(mouse.backposx,mouse.backposy,0,mouse.backData[0],mouse.backData[1],true); @@ -303,7 +303,7 @@ void ClipCursorArea(Bit16s& x1, Bit16s& x2, Bit16s& y1, Bit16s& y2, Bit16u& addx void RestoreCursorBackground() { - if (mouse.shown<0) return; + if (mouse.shown) return; SaveVgaRegisters(); if (mouse.background) { @@ -332,7 +332,7 @@ void RestoreCursorBackground() }; void DrawCursor() { - if (mouse.shown<0) return; + if (mouse.shown) return; // Check video page if (real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE)!=mouse.page) return; // Check if cursor in update region @@ -525,7 +525,8 @@ void Mouse_NewVideoMode(void) } else { real_writed(0,((0x8+MOUSE_IRQ)<<2),CALLBACK_RealPointer(call_int74)); } -// mouse.shown=-1;//Disabled as ida doesn't have mousecursor anymore + mouse.shown = 1;//Disabled as ida doesn't have mousecursor anymore + //enabled again as it seems to be a bug in ida4 /* Get the correct resolution from the current video mode */ Bitu mode=mem_readb(BIOS_VIDEO_MODE); switch (mode) { @@ -557,7 +558,7 @@ void Mouse_NewVideoMode(void) mouse.max_y=199; LOG(LOG_MOUSE,LOG_ERROR)("Unhandled videomode %X on reset",mode); // Hide mouse cursor on non supported modi. Pirates Gold - mouse.shown = -1; + mouse.shown = 1; break; } mouse.max_x = 639; @@ -586,7 +587,7 @@ void Mouse_NewVideoMode(void) mouse.updateRegion_y[1] = 1; mouse.cursorType = 0; mouse.enabled=true; - mouse.oldshown=-1; + mouse.oldshown=1; SetMickeyPixelRate(8,16); oldmouseX = static_cast(mouse.x); @@ -599,7 +600,7 @@ static void mouse_reset(void) { /* Remove drawn mouse Legends of Valor */ if (CurMode->type!=M_TEXT) RestoreCursorBackground(); else RestoreCursorBackgroundText(); - mouse.shown = -1; + mouse.shown = 1; Mouse_NewVideoMode(); @@ -622,16 +623,15 @@ static Bitu INT33_Handler(void) { Mouse_AutoLock(true); break; case 0x01: /* Show Mouse */ - mouse.shown++; + if(mouse.shown) mouse.shown--; Mouse_AutoLock(true); - if (mouse.shown>0) mouse.shown=0; DrawCursor(); break; case 0x02: /* Hide Mouse */ { if (CurMode->type!=M_TEXT) RestoreCursorBackground(); else RestoreCursorBackgroundText(); - mouse.shown--; + mouse.shown++; } break; case 0x03: /* Return position and Button Status */ @@ -820,7 +820,7 @@ static Bitu INT33_Handler(void) { SegSet16(es,0); mouse.enabled=false; /* Just for reporting not doing a thing with it */ mouse.oldshown=mouse.shown; - mouse.shown=-1; + mouse.shown=1; break; case 0x20: /* Enable Mousedriver */ mouse.enabled=true; @@ -900,7 +900,6 @@ Bitu MOUSE_UserInt_CB_Handler(void) { } void MOUSE_Init(Section* sec) { - // Callback for mouse interrupt 0x33 call_int33=CALLBACK_Allocate(); CALLBACK_Setup(call_int33,&INT33_Handler,CB_IRET,"Mouse"); @@ -942,7 +941,7 @@ void MOUSE_Init(Section* sec) { ps2_callback=CALLBACK_RealPointer(call_ps2); memset(&mouse,0,sizeof(mouse)); - mouse.shown=-1; //Hide mouse on startup + mouse.shown = 1; //Hide mouse on startup mouse.sub_mask=0; mouse.sub_seg=0x6362; // magic value From 76478e8cec607ea1eaa2bcde90229496543a8032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 27 Oct 2006 13:37:14 +0000 Subject: [PATCH 2630/4131] add dos keyboard layout support Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2715 --- include/bios.h | 7 + include/dos_inc.h | 17 +- src/dos/Makefile.am | 4 +- src/dos/dos.cpp | 6 +- src/dos/dos_codepages.h | 1131 ++++++++++++++++++++++++++++ src/dos/dos_keyboard_layout.cpp | 1058 ++++++++++++++++++++++++++ src/dos/dos_keyboard_layout_data.h | 796 ++++++++++++++++++++ src/dos/dos_programs.cpp | 81 +- src/dosbox.cpp | 5 +- src/ints/bios_keyboard.cpp | 8 +- src/ints/int10_memory.cpp | 24 +- visualc_net/dosbox.vcproj | 3 + 12 files changed, 3127 insertions(+), 13 deletions(-) create mode 100644 src/dos/dos_codepages.h create mode 100644 src/dos/dos_keyboard_layout.cpp create mode 100644 src/dos/dos_keyboard_layout_data.h diff --git a/include/bios.h b/include/bios.h index 902e5525..e16f7900 100644 --- a/include/bios.h +++ b/include/bios.h @@ -101,6 +101,9 @@ #define BIOS_VIDEO_SAVEPTR 0x4a8 +/* maximum of scancodes handled by keyboard bios routines */ +#define MAX_SCAN_CODE 0x58 + /* The Section handling Bios Disk Access */ #define BIOS_MAX_DISK 10 @@ -170,4 +173,8 @@ void INT2F_StartUp(void); void INT33_StartUp(void); void INT13_StartUp(void); +bool BIOS_AddKeyToBuffer(Bit16u code); + +void INT10_ReloadRomFonts(); + #endif diff --git a/include/dos_inc.h b/include/dos_inc.h index 931c3094..7be5fdb9 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.61 2006-06-30 12:47:06 c2woody Exp $ */ +/* $Id: dos_inc.h,v 1.62 2006-10-27 13:37:13 c2woody Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -187,6 +187,20 @@ void DOS_SetupTables(void); /* Internal DOS Setup Programs */ void DOS_SetupPrograms(void); +/* Initialize Keyboard Layout */ +void DOS_KeyboardLayout_Init(Section* sec); + +bool DOS_LayoutKey(Bitu key, Bit8u flags1, Bit8u flags2, Bit8u flags3); + +enum { + KEYB_NOERROR=0, + KEYB_FILENOTFOUND, + KEYB_INVALIDFILE, + KEYB_LAYOUTNOTFOUND, + KEYB_INVALIDCPFILE +}; + + INLINE Bit16u long2para(Bit32u size) { if (size>0xFFFF0) return 0xffff; if (size&0xf) return (Bit16u)((size>>4)+1); @@ -605,6 +619,7 @@ struct DOS_Block { RealPt dcbs; Bit8u* country;//Will be copied to dos memory. resides in real mem } tables; + Bit16u loaded_codepage; }; extern DOS_Block dos; diff --git a/src/dos/Makefile.am b/src/dos/Makefile.am index 0beeb4aa..3bdfbf51 100644 --- a/src/dos/Makefile.am +++ b/src/dos/Makefile.am @@ -1,10 +1,10 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libdos.a -EXTRA_DIST = scsidefs.h wnaspi32.h +EXTRA_DIST = scsidefs.h wnaspi32.h dos_codepages.h dos_keyboard_layout_data.h libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioctl.cpp dos_memory.cpp \ dos_misc.cpp dos_classes.cpp dos_programs.cpp dos_tables.cpp \ drives.cpp drives.h drive_virtual.cpp drive_local.cpp drive_cache.cpp drive_fat.cpp \ - drive_iso.cpp dev_con.h dos_mscdex.cpp \ + drive_iso.cpp dev_con.h dos_mscdex.cpp dos_keyboard_layout.cpp \ cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp cdrom_ioctl_linux.cpp cdrom_image.cpp \ cdrom_ioctl_os2.cpp diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index cd2273ca..99a92cb4 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.95 2006-07-24 19:06:55 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.96 2006-10-27 13:37:13 c2woody Exp $ */ #include #include @@ -862,7 +862,7 @@ static Bitu DOS_21Handler(void) { mem_writeb(data + 0x00,reg_al); mem_writew(data + 0x01,0x26); mem_writew(data + 0x03,1); - if(reg_cx > 0x06 ) mem_writew(data+0x05,0x01b5); + if(reg_cx > 0x06 ) mem_writew(data+0x05,dos.loaded_codepage); if(reg_cx > 0x08 ) { Bitu amount = (reg_cx>=0x29)?0x22:(reg_cx-7); MEM_BlockWrite(data + 0x07,dos.tables.country,amount); @@ -914,7 +914,7 @@ static Bitu DOS_21Handler(void) { case 0x66: /* Get/Set global code page table */ if (reg_al==1) { LOG(LOG_DOSMISC,LOG_ERROR)("Getting global code page table"); - reg_bx=reg_dx=437; + reg_bx=reg_dx=dos.loaded_codepage; CALLBACK_SCF(false); break; } diff --git a/src/dos/dos_codepages.h b/src/dos/dos_codepages.h new file mode 100644 index 00000000..9b69f61c --- /dev/null +++ b/src/dos/dos_codepages.h @@ -0,0 +1,1131 @@ +/* + * Copyright (C) Henrique Peron + * + * 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. + */ + + +/* This file contains data of .CPI/.CPX-files. They have been + generated by Henrique Peron */ + +/* The font files have been created/edited with CPIadd V1.20 + Copyright (C) 1993-1996 by kostis@acm.org (Kosta Kostis) */ + +/* This file contains data of UPX-compressed CPI files. + UPX, The Ultimate Packer for eXecutables + Copyright (c) 1996-2002 Markus Oberhumer & Laszlo Molnar + http://upx.sourceforge.net */ + + +Bit8u font_ega_cpx[6322] = { +0x81, 0xfc, 0xce, 0xe7, 0x77, 0x02, 0xcd, 0x20, 0xb9, 0xb2, 0x18, 0xbe, 0xb2, 0x19, 0xbf, 0x6e, +0xe7, 0xbb, 0x00, 0x80, 0xfd, 0xf3, 0xa4, 0xfc, 0x87, 0xf7, 0x83, 0xee, 0xc6, 0x19, 0xed, 0x57, +0x57, 0xe9, 0xed, 0xe5, 0x55, 0x50, 0x58, 0x21, 0x0b, 0x01, 0x04, 0x08, 0x6c, 0xfa, 0x36, 0x54, +0x99, 0xe8, 0x0b, 0xa9, 0x00, 0xe6, 0x1a, 0x18, 0x06, 0x74, 0xbb, 0xfc, 0xff, 0x46, 0x4f, 0x4e, +0x54, 0x20, 0x00, 0x00, 0x01, 0x6e, 0x39, 0x01, 0x17, 0x06, 0xfd, 0xfd, 0x06, 0x00, 0x1c, 0x00, +0x4d, 0x26, 0x0e, 0x45, 0x47, 0x41, 0xc9, 0xcd, 0x1e, 0x20, 0xb5, 0x01, 0xfe, 0xd8, 0x35, 0x24, +0x03, 0x00, 0x12, 0x26, 0x10, 0x08, 0x95, 0xc5, 0x0a, 0x00, 0x6d, 0xff, 0x7e, 0x81, 0xa5, 0x81, +0x81, 0xbd, 0x99, 0x03, 0x7e, 0xfe, 0x83, 0x0f, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, +0xe6, 0x77, 0x00, 0x6c, 0xfe, 0x3e, 0xec, 0x7c, 0x38, 0x10, 0x30, 0x10, 0x38, 0x7c, 0xfd, 0xc0, +0x0e, 0x18, 0x3c, 0x3c, 0xe7, 0xb2, 0xb6, 0x00, 0x18, 0x06, 0x0f, 0x65, 0x6e, 0x7e, 0x3b, 0x0f, +0xb3, 0xb3, 0x22, 0x18, 0x09, 0xde, 0xb1, 0xff, 0x00, 0xe7, 0xc3, 0x5f, 0x3f, 0xf6, 0x00, 0x1f, +0x3c, 0x66, 0x42, 0x42, 0x66, 0xff, 0x92, 0x3c, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xfe, 0x21, +0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xde, 0xeb, 0x00, 0x78, 0x20, 0x2d, 0xb9, 0xe6, 0x00, 0x4f, +0x61, 0xbb, 0x9f, 0x0f, 0x3f, 0x33, 0x3f, 0x30, 0x00, 0x70, 0xf0, 0xf9, 0xc8, 0xe0, 0x00, 0x7f, +0x63, 0x7f, 0x63, 0x9e, 0xbd, 0x67, 0xe7, 0xe6, 0xc0, 0x7c, 0x18, 0xdb, 0x87, 0xdd, 0xa0, 0x3c, +0xdb, 0x2e, 0x80, 0xbb, 0xfd, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0x2d, 0xc0, 0x80, 0xbf, 0xfe, +0x1f, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x6b, 0x49, 0x2b, 0x5e, +0x7c, 0x67, 0x3c, 0x00, 0x66, 0x98, 0x9b, 0x07, 0x5f, 0xe7, 0x36, 0xdb, 0x00, 0x7b, 0x1b, 0xff, +0x9b, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0x06, 0xe4, 0xc6, 0x7c, +0x00, 0xfe, 0x43, 0x66, 0x4f, 0x7e, 0x6f, 0x60, 0x0f, 0x00, 0xbd, 0x60, 0x0f, 0x00, 0xfe, 0x96, +0x70, 0x11, 0x0c, 0xfe, 0x0c, 0x77, 0xc9, 0x0c, 0x00, 0x30, 0x60, 0xfe, 0x06, 0xe4, 0x60, 0x30, +0x00, 0xc0, 0x61, 0x56, 0x5c, 0xa1, 0x76, 0x39, 0x28, 0x6c, 0x28, 0x0e, 0x50, 0x58, 0x9f, 0xb2, +0xb7, 0xa0, 0x7c, 0x7d, 0x8a, 0x0e, 0x5b, 0x0e, 0x38, 0xaf, 0xbc, 0xc0, 0x00, 0x18, 0x3c, 0x66, +0xaf, 0x8c, 0x8f, 0x21, 0xeb, 0xe9, 0x24, 0x20, 0x8b, 0xb9, 0x6c, 0x5e, 0x03, 0xad, 0xfe, 0x36, +0xf1, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0x1e, 0xd6, 0xef, 0xc1, 0xc2, 0xc6, 0x26, 0xdf, 0xae, +0x30, 0x60, 0xc6, 0x86, 0x2e, 0x14, 0x0e, 0x0c, 0x76, 0xdc, 0xc1, 0x1a, 0xaf, 0x76, 0xbd, 0x81, +0x6d, 0x00, 0x60, 0x4e, 0x8b, 0xb9, 0x2b, 0x00, 0xe5, 0xb9, 0x59, 0x0f, 0x08, 0x96, 0x8d, 0x00, +0x18, 0xe2, 0x15, 0x16, 0xde, 0xff, 0xe5, 0x84, 0x81, 0xa2, 0xed, 0x06, 0xb6, 0x14, 0x6c, 0xc0, +0x31, 0xfe, 0xd7, 0x96, 0xad, 0x31, 0xf9, 0x15, 0xe2, 0x9f, 0xc0, 0x80, 0xf8, 0x30, 0xae, 0xd6, +0xd6, 0x0e, 0x76, 0xb2, 0x27, 0x38, 0x78, 0x59, 0x10, 0x81, 0x2e, 0xf6, 0xe4, 0x7c, 0xc6, 0xc6, +0xfe, 0x0f, 0xd8, 0x4e, 0x06, 0x3c, 0x02, 0x06, 0xfd, 0x43, 0xdf, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, +0xfe, 0x9c, 0xd0, 0xb0, 0x1e, 0x8d, 0xfe, 0x03, 0xd6, 0xfc, 0x1f, 0x38, 0x90, 0xbb, 0x60, 0x0f, +0xc6, 0xc6, 0xc6, 0x66, 0xee, 0xfe, 0x3f, 0xf3, 0x73, 0xc3, 0x4f, 0x1a, 0x1f, 0x7d, 0x01, 0x0b, +0x7e, 0x0b, 0xdb, 0x3f, 0x0c, 0x78, 0xba, 0x0b, 0x7b, 0x04, 0x0f, 0x62, 0x93, 0x30, 0x9e, 0x92, +0x1a, 0x35, 0x06, 0xc2, 0xc9, 0xde, 0x02, 0x00, 0xf6, 0x62, 0x1b, 0x23, 0x5f, 0x25, 0x4c, 0x0c, +0xdf, 0xb6, 0xb3, 0x10, 0xde, 0x00, 0xdc, 0x61, 0x14, 0xc4, 0x2e, 0x3b, 0xdb, 0x6c, 0x90, 0xfe, +0x0f, 0x6c, 0x3c, 0xfc, 0x66, 0xf1, 0x7c, 0x86, 0xf4, 0xfc, 0x6f, 0xd4, 0x15, 0xef, 0x00, 0xc2, +0xf2, 0xe9, 0xa1, 0x10, 0xf8, 0x6c, 0x3f, 0x7b, 0x6c, 0xf8, 0x0f, 0xfe, 0x66, 0x62, 0x68, 0x84, +0xfc, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0xc0, 0xb6, 0x00, 0xf0, 0x3f, 0x4d, 0x7e, 0xde, 0xc6, +0xc6, 0x66, 0x3a, 0x61, 0xef, 0x69, 0x6e, 0x6f, 0x6b, 0xc2, 0x3c, 0x7d, 0x30, 0x31, 0x26, 0x1e, +0x0d, 0x77, 0x49, 0xef, 0xe6, 0x6a, 0xb3, 0x6e, 0x78, 0x78, 0x74, 0xe6, 0x0f, 0xb3, 0xd8, 0xf0, +0x60, 0x00, 0x6f, 0x92, 0x7f, 0x4f, 0xee, 0xfe, 0xfe, 0xd6, 0xf2, 0xdb, 0x0f, 0xe6, 0xf6, 0xfe, +0xde, 0xce, 0x79, 0x58, 0x6f, 0xc6, 0x9b, 0x2d, 0xdf, 0x41, 0x27, 0xec, 0xf0, 0x1f, 0xd6, 0xde, +0x97, 0xe4, 0x7c, 0x0c, 0x0e, 0xe3, 0x29, 0xd9, 0xe6, 0x1f, 0xe2, 0xb2, 0x42, 0x50, 0x3f, 0x09, +0x7b, 0x7e, 0x7e, 0x5a, 0xaf, 0x16, 0xb2, 0xc6, 0x5f, 0x0f, 0x25, 0x0f, 0x6c, 0x38, 0x10, 0x43, +0xfe, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x6b, 0xa6, 0x6c, 0x8e, 0x61, 0x9f, 0x66, 0x0d, 0xce, +0x0b, 0xcb, 0x4f, 0x1b, 0x86, 0x21, 0x1f, 0x7f, 0xc2, 0x16, 0xec, 0x3c, 0x30, 0x00, 0x1f, 0xfe, +0x0a, 0xc1, 0x70, 0x38, 0x1c, 0x76, 0xb2, 0xaf, 0x3c, 0x0c, 0x00, 0x62, 0x0c, 0x3c, 0xdc, 0x8d, +0x90, 0xe6, 0xec, 0x34, 0x6c, 0xff, 0x18, 0xe9, 0x03, 0x78, 0x0c, 0x7c, 0xaf, 0x16, 0x2e, 0xe0, +0x19, 0x78, 0x66, 0x11, 0xe2, 0xcf, 0x1c, 0x13, 0x02, 0x00, 0xb9, 0xc3, 0xdf, 0x1c, 0x69, 0x2d, +0x2b, 0x00, 0x2f, 0x80, 0x8c, 0x1f, 0xfe, 0xc6, 0xfb, 0x36, 0x32, 0x30, 0x78, 0xaf, 0xcf, 0xf0, +0x5d, 0x76, 0x2e, 0xcc, 0xdf, 0xa1, 0x5f, 0xd2, 0x5f, 0x6c, 0x32, 0x9e, 0x76, 0xe6, 0xdc, 0x03, +0x61, 0x38, 0x4f, 0x6b, 0x4b, 0x09, 0x00, 0xdb, 0x00, 0xcc, 0x10, 0x17, 0x2f, 0x71, 0xc6, 0x00, +0xe6, 0x90, 0x9c, 0x2f, 0x38, 0x35, 0xba, 0x00, 0xec, 0x00, 0x4c, 0xd6, 0x00, 0xc6, 0x0f, 0xdc, +0xcb, 0x66, 0xa1, 0x9f, 0x6c, 0x09, 0x9f, 0x1f, 0xf6, 0xb1, 0x04, 0xf0, 0x9f, 0x90, 0x16, 0xd2, +0x19, 0xed, 0xdc, 0x9f, 0x1f, 0x4c, 0x60, 0xe4, 0x76, 0x09, 0xdf, 0x10, 0xd9, 0xb2, 0xdf, 0xfc, +0xde, 0x36, 0x1c, 0x1f, 0x10, 0x5e, 0x3d, 0x0f, 0x82, 0x31, 0x00, 0x47, 0xc0, 0x0f, 0x00, 0xb7, +0x84, 0x9a, 0x1b, 0x30, 0x53, 0x38, 0x75, 0x2f, 0xd4, 0xb5, 0x04, 0x0c, 0x03, 0x87, 0x52, 0xcc, +0x4f, 0xcd, 0xd9, 0xfe, 0xef, 0x0e, 0x70, 0x64, 0x3d, 0x0e, 0xf7, 0x09, 0x83, 0x3f, 0xda, 0x7b, +0x1b, 0x23, 0x24, 0x40, 0xf8, 0xc9, 0xdc, 0xdf, 0x8b, 0x34, 0xe2, 0x4f, 0x17, 0xd2, 0xcf, 0x18, +0xd8, 0x59, 0x72, 0xcc, 0xbf, 0xe0, 0x4a, 0x39, 0xb8, 0x84, 0xcf, 0x3b, 0x6e, 0x61, 0x1f, 0x2f, +0x7c, 0x60, 0x0f, 0xc0, 0x60, 0x30, 0xb6, 0x84, 0x2e, 0x38, 0x46, 0xc8, 0x2f, 0x3f, 0xde, 0x4b, +0x6f, 0x4f, 0x5c, 0xc2, 0x5f, 0xfd, 0x57, 0xc2, 0x0f, 0xbd, 0x18, 0x32, 0x1f, 0x66, 0x5a, 0xc2, +0x1f, 0x06, 0xde, 0xc2, 0x0f, 0x2f, 0x6b, 0xc0, 0x0f, 0xc6, 0xcf, 0x73, 0x0b, 0x8d, 0x0f, 0x72, +0x09, 0xdc, 0xc7, 0xc8, 0xaf, 0x3f, 0x4e, 0xfe, 0x36, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x3e, 0x1e, +0x3a, 0xdc, 0xfe, 0x0f, 0xce, 0x18, 0xc9, 0xff, 0x3f, 0x84, 0x5d, 0xc6, 0x0f, 0x65, 0xb3, 0xaf, +0x0f, 0x08, 0x8d, 0xf6, 0x4f, 0x71, 0x58, 0x1f, 0xc2, 0x85, 0x1f, 0xc6, 0xef, 0x59, 0x07, 0xc6, +0x9f, 0x65, 0x0d, 0xc6, 0x4f, 0x70, 0x22, 0x71, 0x37, 0xe1, 0x0d, 0xef, 0xd2, 0x70, 0xe0, 0x64, +0x60, 0x03, 0xa1, 0x21, 0x9f, 0x0c, 0xc9, 0x38, 0x7e, 0x0f, 0xdb, 0xb7, 0xf8, 0x69, 0xf8, 0xc4, +0xcc, 0xde, 0x05, 0xc6, 0xe5, 0x19, 0x1f, 0x0e, 0x1b, 0x70, 0x9a, 0x7e, 0xd8, 0x0b, 0xe1, 0x01, +0xaf, 0x42, 0x6a, 0x84, 0x7f, 0xcb, 0xde, 0x0f, 0xcf, 0x21, 0x7b, 0x2f, 0xbf, 0x92, 0x1c, 0x62, +0x5f, 0x04, 0xdc, 0x0c, 0x6f, 0x6e, 0x8d, 0x1c, 0x6c, 0x36, 0x0c, 0x0c, 0x8e, 0xd6, 0x5e, 0x0f, +0x51, 0x0f, 0x98, 0x58, 0x07, 0x48, 0x5d, 0x11, 0xc0, 0x8f, 0x7a, 0x1c, 0xfe, 0x90, 0x34, 0x10, +0x3c, 0xc1, 0xe0, 0xfd, 0xcc, 0xa6, 0x85, 0xe0, 0xa8, 0x6c, 0x0d, 0xac, 0x81, 0xdc, 0x14, 0x3e, +0x0f, 0x60, 0xbf, 0x66, 0xce, 0x9a, 0x3f, 0x22, 0xe8, 0xb9, 0xf7, 0xbc, 0x63, 0xc9, 0x62, 0x85, +0x36, 0xcb, 0xcc, 0x6c, 0xd8, 0x00, 0x6d, 0x76, 0x0d, 0x6c, 0xd8, 0x11, 0x44, 0xe4, 0x85, 0x01, +0x55, 0xaa, 0x21, 0x2f, 0xdd, 0x77, 0x05, 0x76, 0x18, 0x00, 0x0b, 0xd9, 0xf8, 0x0d, 0x0f, 0xcf, +0x26, 0x36, 0x00, 0xf6, 0x36, 0xb0, 0x20, 0xd0, 0x4b, 0xd8, 0x0f, 0x2f, 0xce, 0x23, 0xf6, 0x06, +0x96, 0xc0, 0x00, 0x3d, 0x85, 0x6c, 0x1f, 0x25, 0xa3, 0x2f, 0xba, 0xc9, 0x82, 0x11, 0x0f, 0xac, +0x61, 0x8f, 0x00, 0xc8, 0x86, 0xf8, 0xbf, 0x27, 0x6c, 0x1f, 0x2f, 0x18, 0x18, 0x19, 0x92, 0xff, +0xff, 0x58, 0x23, 0x72, 0x59, 0x5b, 0x1f, 0x3f, 0x21, 0x1b, 0x2d, 0x86, 0x84, 0x1f, 0x0f, 0x37, +0x7b, 0xc2, 0xbf, 0x37, 0x30, 0x3f, 0x6d, 0x52, 0x09, 0xbf, 0xbb, 0xb0, 0x1f, 0xf7, 0x5f, 0x83, +0x2d, 0x6d, 0xf7, 0x2c, 0x64, 0x3f, 0x2f, 0x6c, 0x96, 0x1f, 0x2f, 0x6c, 0xb6, 0x3f, 0x2f, 0x0c, +0xb6, 0xdd, 0xff, 0x2c, 0x24, 0x2f, 0x5f, 0xc8, 0x8e, 0xff, 0xdf, 0x42, 0xc2, 0x86, 0x61, 0xc9, +0xaf, 0xdf, 0x97, 0xb0, 0x3f, 0xef, 0xb9, 0xb0, 0x3f, 0x3f, 0x64, 0x21, 0x4f, 0x10, 0x84, 0x2d, +0x84, 0x91, 0x5f, 0xaf, 0x93, 0x8d, 0x4f, 0xff, 0x2c, 0x64, 0x00, 0x9f, 0x1c, 0x36, 0x00, 0xf0, +0xc9, 0x90, 0x0f, 0x0b, 0x0b, 0x36, 0xf2, 0x61, 0x00, 0x76, 0xdc, 0xd8, 0x08, 0xd2, 0xdc, 0xcf, +0xd3, 0x06, 0x5b, 0xd8, 0xcc, 0xbe, 0x86, 0x45, 0xcc, 0x7f, 0x48, 0x07, 0xad, 0x91, 0x9d, 0x4a, +0xff, 0x35, 0xcc, 0x00, 0x1f, 0xcb, 0xc0, 0xf2, 0x9f, 0x78, 0x7e, 0x00, 0x7e, 0xd8, 0x70, 0x64, +0x92, 0x5f, 0x66, 0x0c, 0x3b, 0xc0, 0x6f, 0x2b, 0x20, 0x1c, 0x8b, 0x20, 0x40, 0xc1, 0x2f, 0xa9, +0x8f, 0xfe, 0xc6, 0x83, 0x25, 0xab, 0xd1, 0x17, 0x6e, 0xee, 0xd6, 0x9c, 0xce, 0x1e, 0x3e, 0x31, +0xb0, 0x2c, 0x6f, 0xb2, 0x0a, 0x82, 0x61, 0x6c, 0xf7, 0x03, 0x06, 0x0f, 0xf3, 0x7e, 0x6c, 0x68, +0x3b, 0x1c, 0x9a, 0x60, 0x09, 0x7d, 0xdf, 0x30, 0x1c, 0xff, 0x25, 0x0b, 0xcd, 0xb2, 0x9a, 0x02, +0x5d, 0x4a, 0x36, 0x50, 0x59, 0x90, 0x3e, 0x10, 0x41, 0x2a, 0x6e, 0x07, 0x66, 0x0f, 0x4f, 0x01, +0xac, 0x1b, 0x11, 0x77, 0x60, 0xff, 0x18, 0x2a, 0x12, 0x42, 0x18, 0x6e, 0x0c, 0x24, 0x97, 0xac, +0x0e, 0x0f, 0xac, 0x61, 0x81, 0x42, 0xf3, 0xb0, 0x00, 0x0f, 0x0c, 0x60, 0xdb, 0xec, 0x34, 0x3c, +0xcf, 0x06, 0xd6, 0x6c, 0x58, 0x5b, 0x24, 0xcf, 0xa0, 0x32, 0xbe, 0x64, 0xbc, 0x00, 0x7e, 0x40, +0x4e, 0x00, 0x2f, 0x18, 0x0e, 0x05, 0x84, 0x05, 0x03, 0x58, 0x70, 0x7e, 0x01, 0x12, 0x1c, 0x7e, +0xff, 0x82, 0x00, 0x12, 0x4c, 0xfd, 0xfb, 0x09, 0x56, 0xf9, 0x04, 0x29, 0x92, 0xe0, 0xf7, 0xf5, +0x49, 0x30, 0xf3, 0x92, 0x60, 0xf1, 0x49, 0x30, 0xef, 0x60, 0x76, 0x78, 0x27, 0xc1, 0x92, 0xec, +0x24, 0x38, 0xeb, 0xea, 0x4e, 0xb0, 0xe9, 0xc1, 0x09, 0xe8, 0x2a, 0x25, 0xe7, 0x4a, 0x60, 0x24, +0xe5, 0x2c, 0x09, 0xe4, 0xa9, 0x12, 0xe3, 0x32, 0x25, 0xc1, 0xe1, 0x90, 0x20, 0xde, 0x48, 0x90, +0xdd, 0x90, 0x60, 0xdb, 0x24, 0xc1, 0xda, 0x82, 0x72, 0x00, 0xde, 0x48, 0xd7, 0x0d, 0xc1, 0x32, +0xe4, 0x20, 0x24, 0xd2, 0x12, 0x9c, 0xd1, 0xcf, 0x82, 0x10, 0x12, 0x4c, 0xcd, 0xcb, 0x09, 0x56, +0xc9, 0x49, 0x30, 0xc7, 0x09, 0x52, 0xc3, 0x02, 0x17, 0x76, 0x12, 0x4c, 0xc1, 0xbe, 0x82, 0x10, +0x12, 0x4c, 0xbd, 0xbc, 0x27, 0x58, 0xbb, 0x20, 0xc1, 0x66, 0xc6, 0xb9, 0x49, 0x70, 0x76, 0x5f, +0x24, 0x48, 0xb5, 0x82, 0xd3, 0x06, 0x64, 0x4b, 0xb3, 0x20, 0x70, 0x82, 0xb0, 0x02, 0x49, 0xae, +0x63, 0xc0, 0x4b, 0xfe, 0xfb, 0x41, 0x08, 0x6b, 0x25, 0xa5, 0x14, 0x49, 0x30, 0xa3, 0x49, 0x70, +0x7e, 0xa1, 0xc1, 0x6b, 0x80, 0x87, 0x25, 0x9f, 0xa3, 0x97, 0x04, 0x9d, 0x1e, 0x80, 0x04, 0x9b, +0x12, 0xbc, 0x1b, 0x99, 0xc1, 0x5b, 0x0d, 0x30, 0x3b, 0x97, 0xd4, 0x1c, 0x48, 0x95, 0x7c, 0x02, +0x12, 0x93, 0x04, 0x8f, 0xaf, 0x82, 0x95, 0x90, 0x58, 0x40, 0x8e, 0xb3, 0x04, 0xaf, 0x1e, 0x82, +0x95, 0x8b, 0x41, 0x42, 0x88, 0xf0, 0x22, 0x87, 0x3c, 0x4a, 0x49, 0x84, 0x41, 0x32, 0xa3, 0x75, +0x20, 0x81, 0xfc, 0x82, 0x25, 0xaf, 0x13, 0x4c, 0x7e, 0x7d, 0x4b, 0x82, 0x7c, 0x68, 0x46, 0xcb, +0x5a, 0xf6, 0xca, 0x0d, 0x12, 0xbc, 0xb8, 0x77, 0x27, 0x58, 0x76, 0x96, 0x04, 0x75, 0x03, 0x09, +0x73, 0x40, 0x82, 0x3c, 0x71, 0x93, 0xe0, 0x78, 0x6f, 0x80, 0x1b, 0x06, 0x78, 0x6c, 0x82, 0x41, +0x6e, 0xf0, 0x04, 0x4b, 0x6c, 0x92, 0xe0, 0x6b, 0x6a, 0x92, 0xd0, 0xf9, 0x26, 0x04, 0x67, 0x7c, +0x03, 0x09, 0x65, 0xc1, 0xb2, 0xf0, 0x1b, 0x24, 0x30, 0x62, 0x61, 0x09, 0x0e, 0xe6, 0x5f, 0x86, +0x2d, 0x37, 0xd9, 0x09, 0x5d, 0x99, 0x42, 0x2a, 0x0a, 0x21, 0xc1, 0x58, 0x91, 0x20, 0x57, 0xb1, +0x19, 0xd7, 0x0d, 0xf0, 0x4a, 0x1c, 0x66, 0x1b, 0x48, 0x53, 0x45, 0xc1, 0x36, 0xf7, 0x8c, 0x82, +0x25, 0x50, 0x82, 0x41, 0x4f, 0x3c, 0xc1, 0x4a, 0x4c, 0xc1, 0x20, 0x4b, 0x3c, 0x0c, 0x24, 0x49, +0xff, 0x01, 0x12, 0x45, 0x18, 0xa9, 0x53, 0x76, 0x0d, 0x24, 0x41, 0xa9, 0x64, 0x35, 0xc0, 0x48, +0x30, 0x3d, 0x97, 0x1d, 0x76, 0x1b, 0xfe, 0x82, 0x24, 0x24, 0x58, 0x39, 0x7c, 0x38, 0x03, 0x06, +0x76, 0x96, 0x48, 0x10, 0x35, 0x12, 0x0c, 0xe6, 0x33, 0x04, 0x07, 0x3c, 0x09, 0x96, 0x31, 0x2f, +0x08, 0x09, 0xbf, 0x5e, 0x6c, 0x26, 0x29, 0x09, 0x09, 0x2b, 0x84, 0x04, 0x09, 0xc3, 0xb2, 0x8b, +0x6b, 0x98, 0xb0, 0x1b, 0x7c, 0x58, 0x76, 0xc1, 0x8b, 0x0e, 0x24, 0x21, 0xf0, 0xc9, 0xcb, 0x37, +0x70, 0x1c, 0x4c, 0x82, 0x1d, 0x58, 0x12, 0x1c, 0x24, 0x24, 0x1a, 0xb3, 0x25, 0xbf, 0x0d, 0x80, +0x04, 0x16, 0x12, 0xb8, 0x19, 0x14, 0x04, 0x58, 0x22, 0x92, 0xe0, 0x7c, 0x11, 0x82, 0x47, 0x83, +0x82, 0x4b, 0x0f, 0x0e, 0x41, 0x42, 0x0d, 0x70, 0x20, 0x0b, 0x70, 0x12, 0x48, 0x09, 0x48, 0x93, +0x66, 0x55, 0xdc, 0x5b, 0x2b, 0xa5, 0x53, 0xc0, 0xa7, 0xb2, 0xb7, 0x04, 0x95, 0x33, 0x0d, 0x84, +0xdb, 0xb4, 0xcc, 0x29, 0x0d, 0xb0, 0xcc, 0xf8, 0x0d, 0x30, 0x19, 0xf9, 0x76, 0xbd, 0x85, 0xf7, +0x61, 0xb7, 0xec, 0x45, 0x53, 0xdd, 0xd7, 0x32, 0x0d, 0x26, 0x98, 0xb0, 0x1b, 0x66, 0x5a, 0x40, +0xdb, 0x05, 0xde, 0xc0, 0x0d, 0x29, 0x01, 0xc9, 0x0d, 0x03, 0x96, 0xe9, 0xe7, 0x5e, 0x09, 0x94, +0x10, 0xb2, 0x19, 0x86, 0x1e, 0xe3, 0xf5, 0xc0, 0x80, 0x6e, 0xe1, 0x30, 0xe0, 0xce, 0xdf, 0x03, +0x36, 0x99, 0xc6, 0x37, 0x90, 0xc6, 0x0d, 0xcb, 0x80, 0xd9, 0x84, 0x65, 0xfb, 0xdb, 0x12, 0x26, +0xc6, 0xb1, 0x09, 0xeb, 0xc6, 0x0b, 0x84, 0xa4, 0xc6, 0xc5, 0x83, 0x07, 0xcf, 0x7f, 0x06, 0x24, +0xcd, 0x30, 0x6b, 0xeb, 0x2b, 0x19, 0xcb, 0x43, 0xde, 0x0e, 0x7c, 0xc1, 0x6f, 0x66, 0xf3, 0x01, +0x03, 0xc7, 0x60, 0x42, 0x66, 0x09, 0x33, 0xc5, 0xb1, 0x2d, 0x61, 0x17, 0xb7, 0xec, 0x0d, 0xb5, +0x29, 0xc0, 0xb2, 0xa7, 0x80, 0x65, 0xbd, 0x40, 0xc2, 0xbb, 0x60, 0x65, 0xb9, 0x90, 0x30, 0xb7, +0xb3, 0x18, 0xb5, 0x53, 0x48, 0x06, 0x5a, 0x24, 0x0c, 0xb1, 0x73, 0x06, 0xaf, 0x63, 0xb0, 0x6d, +0x6e, 0xc3, 0x85, 0x1f, 0x0d, 0x0c, 0xf8, 0x36, 0x6e, 0xda, 0xac, 0x03, 0xdc, 0xd8, 0xaa, 0x01, +0x0b, 0x32, 0xe0, 0xa8, 0xa6, 0x19, 0x10, 0xa3, 0x03, 0x02, 0x9f, 0xe0, 0x2a, 0xf8, 0xb0, 0x32, +0x9b, 0x5b, 0x18, 0x99, 0xb6, 0x03, 0xce, 0x95, 0x01, 0x2b, 0x60, 0x90, 0x93, 0xb0, 0x32, 0x8f, +0x03, 0x1e, 0x8d, 0x8b, 0x01, 0x29, 0x80, 0x95, 0x89, 0x60, 0xc8, 0x87, 0x1f, 0xac, 0x30, 0x83, +0x42, 0x06, 0x51, 0x2b, 0x03, 0x7d, 0x94, 0x01, 0x7b, 0xd9, 0x80, 0x77, 0x1f, 0xc0, 0x08, 0x03, +0x66, 0x75, 0x73, 0x01, 0x2b, 0x30, 0xe0, 0x71, 0x6f, 0x07, 0x8c, 0x6d, 0xca, 0x80, 0x6b, 0x65, +0x40, 0x69, 0xc8, 0x80, 0x67, 0x65, 0xc0, 0x65, 0x01, 0x6e, 0x1b, 0x70, 0x85, 0x61, 0x3f, 0x46, +0x18, 0x5d, 0x18, 0xf0, 0xd1, 0x59, 0x01, 0x53, 0xff, 0x70, 0x85, 0x55, 0xf8, 0x02, 0x18, 0x51, +0x20, 0x03, 0x4d, 0x64, 0x40, 0x49, 0x0c, 0x08, 0x47, 0x30, 0xad, 0x3f, 0x38, 0x0c, 0x44, 0x78, +0xb0, 0x0c, 0x42, 0x60, 0x19, 0x41, 0x90, 0x30, 0x3f, 0x20, 0x19, 0x3d, 0x18, 0x30, 0x3c, 0x7e, +0x0c, 0x0c, 0x3a, 0x60, 0x06, 0x38, 0x30, 0x30, 0x37, 0x6b, 0x19, 0x35, 0x1d, 0x93, 0x91, 0x1d, +0xfe, 0x03, 0x26, 0x31, 0x03, 0x2e, 0xee, 0x2f, 0x80, 0x03, 0x3c, 0x80, 0xc9, 0x2c, 0x7e, 0x96, +0xc0, 0x2a, 0x29, 0x6b, 0xad, 0x78, 0x0b, 0x8f, 0xc2, 0x62, 0x1e, 0xbf, 0x65, 0x40, 0x25, 0x32, +0x60, 0x22, 0x65, 0xc0, 0x20, 0x32, 0x20, 0x1e, 0x60, 0xc0, 0x1c, 0x0c, 0x48, 0x19, 0x01, 0x23, +0x03, 0x96, 0x17, 0x15, 0x64, 0xc0, 0x12, 0x06, 0x0c, 0x18, 0x0f, 0x80, 0x43, 0x3c, 0x1c, 0xc0, +0xca, 0x0d, 0x20, 0x64, 0x0b, 0x2e, 0x30, 0x08, 0x08, 0x2c, 0x03, 0x05, 0x80, 0x03, 0xfc, 0x0c, +0x70, 0xfb, 0xf6, 0xa0, 0x01, 0xf5, 0x6c, 0x00, 0x13, 0xee, 0xda, 0x82, 0xe9, 0x06, 0x38, 0x6b, +0x85, 0x61, 0x0d, 0x0f, 0xd0, 0xda, 0x10, 0x05, 0x20, 0x08, 0xd7, 0x40, 0x10, 0xd1, 0x80, 0x20, +0xcb, 0xf0, 0x41, 0xc5, 0x0f, 0x07, 0x0f, 0x7d, 0x01, 0x0c, 0xbf, 0xba, 0x03, 0x04, 0xb4, 0x50, +0x80, 0xb3, 0xc0, 0x0f, 0xae, 0x67, 0xe6, 0xc0, 0x06, 0x30, 0xa7, 0xa8, 0x75, 0x80, 0x80, 0xa1, +0x03, 0x2c, 0xef, 0x02, 0x9b, 0x38, 0xc0, 0x02, 0x42, 0x00, 0x06, 0x33, 0x06, 0x98, 0x8f, 0x8a, +0xc0, 0x00, 0x89, 0xbb, 0xdb, 0xae, 0x61, 0x49, 0x3c, 0x86, 0x7c, 0xd0, 0xef, 0x05, 0x27, 0x26, +0x4d, 0x80, 0xff, 0x72, 0xc0, 0x3b, 0x35, 0x0f, 0x80, 0x24, 0x65, 0x09, 0x70, 0x5f, 0x59, 0x03, +0x7c, 0x24, 0x66, 0xff, 0x12, 0xf1, 0x80, 0x9f, 0xc0, 0x8b, 0xef, 0x2e, 0x6f, 0x20, 0x3d, 0x46, +0x00, 0x1d, 0x7c, 0x24, 0x8f, 0x86, 0x31, 0x57, 0xdb, 0xea, 0x18, 0x3e, 0x60, 0x58, 0x7c, 0x29, +0x80, 0x86, 0xd7, 0x07, 0x78, 0x23, 0x38, 0x1e, 0x24, 0xab, 0x76, 0xcc, 0xc3, 0x34, 0xf9, 0x30, +0x0f, 0x00, 0xe6, 0x0c, 0x01, 0x92, 0x06, 0x00, 0x83, 0x2d, 0x2b, 0x7e, 0x1a, 0x08, 0xd6, 0xc7, +0xb0, 0xe8, 0xb7, 0xab, 0x47, 0xd6, 0xc3, 0xdd, 0xab, 0x58, 0xc2, 0xc9, 0xf7, 0xe2, 0x1c, 0xe5, +0x07, 0xea, 0x55, 0x3c, 0xb3, 0x0f, 0xce, 0xca, 0x1e, 0x6a, 0x5c, 0xbd, 0xfc, 0x0f, 0xbf, 0xa6, +0xae, 0xbe, 0x7c, 0x43, 0x3d, 0x62, 0x79, 0xb1, 0xab, 0xef, 0x02, 0x07, 0x7e, 0xab, 0xab, 0x17, +0x74, 0x62, 0xbc, 0x37, 0x77, 0x67, 0xb2, 0x7a, 0xaa, 0x94, 0xab, 0x47, 0xa6, 0x8d, 0xcd, 0xea, +0x7c, 0x88, 0xed, 0xca, 0x07, 0x82, 0xc0, 0x78, 0xc4, 0xe2, 0x87, 0x37, 0xaf, 0x4e, 0x6f, 0x75, +0x60, 0x68, 0xc3, 0x38, 0xf5, 0xca, 0xd0, 0x6b, 0x58, 0x7c, 0x69, 0xfe, 0x4a, 0xa1, 0xd9, 0xfe, +0x07, 0xf5, 0x57, 0x9f, 0x1f, 0xce, 0x57, 0x05, 0x2b, 0x52, 0x2d, 0x58, 0x4d, 0x2f, 0x06, 0xab, +0x1e, 0x45, 0xe6, 0x1a, 0x8c, 0x7f, 0xf0, 0x55, 0xb0, 0x39, 0x27, 0x26, 0xa1, 0x6d, 0xa0, 0x13, +0x6c, 0x7a, 0xc3, 0x5e, 0x6f, 0xfc, 0x3d, 0x45, 0x0f, 0xce, 0x7c, 0x0e, 0xda, 0x8b, 0x37, 0x5f, +0x2b, 0xe7, 0xa8, 0x7f, 0x0b, 0x2c, 0xde, 0x57, 0x3d, 0x08, 0x35, 0x56, 0x41, 0x2a, 0xf8, 0x53, +0xbd, 0x00, 0x0c, 0x46, 0x7a, 0x0f, 0x67, 0x27, 0xea, 0x9e, 0xe7, 0x32, 0x6f, 0x3c, 0x40, 0x90, +0xdf, 0x99, 0x3a, 0x97, 0xd9, 0xc5, 0x49, 0xd5, 0x3c, 0x40, 0xe0, 0xe9, 0x91, 0xa9, 0xc3, 0xba, +0xbc, 0xa9, 0x01, 0x76, 0x39, 0x35, 0x80, 0x75, 0xdc, 0x87, 0x09, 0xb8, 0x7f, 0x86, 0x44, 0x26, +0xbb, 0x87, 0x9e, 0x7c, 0x97, 0x60, 0xf8, 0x75, 0x46, 0xf5, 0x76, 0xca, 0x35, 0x09, 0xf8, 0x2f, +0x8b, 0x76, 0x92, 0xaf, 0x7c, 0x15, 0xde, 0x7f, 0x69, 0x70, 0x4f, 0x84, 0x3c, 0x17, 0x24, 0x7a, +0x00, 0xe6, 0x56, 0x22, 0xb5, 0x74, 0x30, 0xa4, 0x52, 0x2c, 0x18, 0x6d, 0x0f, 0x9a, 0x6c, 0x7c, +0x4f, 0x1e, 0x67, 0x91, 0x56, 0x5f, 0x7e, 0xa1, 0x04, 0xa3, 0x87, 0xea, 0x54, 0x4a, 0x58, 0x4c, +0x49, 0xbf, 0x90, 0x62, 0x26, 0x86, 0x54, 0x37, 0x63, 0x11, 0x00, 0x17, 0x7e, 0x83, 0x73, 0x2f, +0x37, 0xdf, 0xf5, 0x54, 0x7e, 0x21, 0x70, 0x90, 0x3a, 0x1f, 0x19, 0xe5, 0xde, 0x0c, 0x12, 0x92, +0x9a, 0x6b, 0x07, 0xa3, 0xc3, 0xc6, 0xff, 0x36, 0x1b, 0xcc, 0x5f, 0x3b, 0x46, 0xb3, 0xe7, 0xf0, +0xb3, 0x6e, 0x6f, 0xcc, 0x07, 0xb6, 0xc9, 0x60, 0x30, 0x17, 0x38, 0x09, 0x4d, 0xbf, 0x82, 0xd1, +0x70, 0xd2, 0x9d, 0x19, 0x97, 0x07, 0x30, 0x8c, 0x82, 0x3f, 0xc0, 0x98, 0x1b, 0x3c, 0x1f, 0x07, +0x8e, 0xb9, 0x17, 0x07, 0xc6, 0x10, 0x73, 0x33, 0x68, 0x47, 0x27, 0x33, 0x81, 0x0d, 0x2c, 0x3a, +0x69, 0xf8, 0xa1, 0xec, 0xa3, 0x85, 0x7f, 0x6e, 0x97, 0xd4, 0xd1, 0x96, 0xce, 0xa3, 0x60, 0x90, +0x47, 0x9b, 0x0d, 0x57, 0x07, 0x82, 0x91, 0x7e, 0x9d, 0xf0, 0x8f, 0x0f, 0xc6, 0x70, 0x9a, 0xf7, +0x98, 0x7a, 0xef, 0x17, 0x0e, 0x27, 0xa6, 0x66, 0x4a, 0x55, 0x80, 0x23, 0x47, 0x5a, 0x59, 0xc8, +0x11, 0x1d, 0x42, 0xc5, 0x53, 0x18, 0x1d, 0xfd, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7, 0x48, 0x3c, 0xa3, +0x47, 0x47, 0x42, 0xb3, 0x37, 0xf7, 0x9f, 0xf6, 0x62, 0xff, 0x3f, 0x5f, 0x30, 0x0a, 0x2a, 0x31, +0xdc, 0x07, 0xb8, 0x4a, 0x46, 0x1f, 0xd1, 0x30, 0x19, 0x93, 0x9b, 0x12, 0x08, 0xa1, 0x0d, 0xa3, +0x06, 0xe6, 0xbf, 0x07, 0x63, 0xe6, 0x6c, 0x7e, 0x33, 0x66, 0xcc, 0x0f, 0xa1, 0xf6, 0x7a, 0x36, +0x6a, 0xdf, 0x11, 0xf4, 0xee, 0x35, 0x10, 0x16, 0xdd, 0xc3, 0x66, 0x33, 0xcf, 0x66, 0x09, 0x22, +0x42, 0xb3, 0x88, 0x01, 0xd9, 0x10, 0x1a, 0xd4, 0x95, 0xd0, 0xca, 0x34, 0xa1, 0x9a, 0xa1, 0x21, +0xbe, 0xb8, 0x08, 0x0d, 0xb2, 0x48, 0x68, 0xac, 0x96, 0xd0, 0xa0, 0xd0, 0x84, 0x9a, 0x84, 0x86, +0x94, 0x8e, 0x84, 0x0e, 0xf8, 0x82, 0x08, 0x05, 0x7c, 0x08, 0x1d, 0xff, 0x70, 0x16, 0x0b, 0x0f, +0x1f, 0x10, 0x1a, 0x5e, 0x3c, 0x14, 0x52, 0x37, 0xa1, 0x84, 0x4c, 0x25, 0x34, 0x46, 0xd0, 0xa1, +0x40, 0x84, 0x96, 0x3a, 0x34, 0x21, 0x34, 0x2e, 0x0d, 0xa1, 0x28, 0x6e, 0x09, 0x22, 0x0f, 0xa1, +0x61, 0x6f, 0x10, 0x42, 0x01, 0x0a, 0x31, 0x5b, 0x77, 0x6f, 0x60, 0xfe, 0x27, 0x06, 0x16, 0xf2, +0x78, 0xc3, 0xd7, 0x27, 0x31, 0xb0, 0xdd, 0x62, 0x60, 0xd7, 0xc4, 0xc0, 0xcb, 0x17, 0x93, 0x81, +0xc8, 0xc1, 0x88, 0x45, 0x78, 0xbc, 0xb3, 0xd8, 0x5d, 0xfe, 0xb6, 0x18, 0x16, 0xb0, 0x16, 0xb1, +0xab, 0xa9, 0x60, 0x71, 0x7e, 0xa3, 0xe2, 0x8b, 0x9c, 0xc0, 0x16, 0xc3, 0x98, 0x92, 0xf1, 0x22, +0x91, 0xc7, 0xe9, 0xd6, 0x97, 0x86, 0xe2, 0x8b, 0x85, 0x0e, 0x2c, 0xc6, 0x80, 0x3c, 0x7a, 0xef, +0xd5, 0x8f, 0x07, 0x0b, 0x17, 0x73, 0x6f, 0xf5, 0xa2, 0x7e, 0x6d, 0xde, 0x9b, 0xff, 0x66, 0x01, +0x36, 0x0c, 0x2e, 0x29, 0x17, 0x81, 0x9e, 0x07, 0x5e, 0x38, 0x05, 0x4f, 0x25, 0x2c, 0x4b, 0xcc, +0xe2, 0x7f, 0x3e, 0x63, 0x59, 0x38, 0x87, 0x90, 0xc5, 0x2c, 0x2c, 0xbe, 0x06, 0x0f, 0x1f, 0x62, +0x31, 0x1b, 0xc2, 0xbd, 0xdd, 0x50, 0x5d, 0x45, 0x3d, 0x79, 0x3c, 0x88, 0x24, 0x20, 0x37, 0x33, +0x81, 0x4c, 0x1c, 0x39, 0x52, 0x03, 0x69, 0x26, 0x11, 0x84, 0x20, 0x90, 0x16, 0x22, 0x00, 0x78, +0xf9, 0x04, 0x7c, 0xce, 0xd6, 0xe6, 0x7c, 0x40, 0x2b, 0x83, 0x33, 0xda, 0x7b, 0x1c, 0x1d, 0x1e, +0x50, 0xc3, 0x1f, 0x10, 0xe7, 0x7c, 0x01, 0x61, 0x33, 0x76, 0x3f, 0x7c, 0x82, 0xb2, 0xaa, 0xaa, +0x02, 0x82, 0x7c, 0xc2, 0x20, 0x33, 0xd4, 0x2a, 0x2c, 0xa2, 0x8d, 0xa3, 0x85, 0x85, 0x0f, 0x2d, +0xe4, 0x60, 0x30, 0xdd, 0xc5, 0xef, 0x9a, 0xa2, 0x00, 0x9a, 0x20, 0x62, 0xef, 0x84, 0xca, 0x33, +0x95, 0x45, 0x53, 0xb2, 0x88, 0x43, 0x06, 0x11, 0x33, 0x1a, 0x44, 0x11, 0xb3, 0xd0, 0xb9, 0x64, +0x93, 0x0c, 0x88, 0x84, 0xff, 0x28, 0x32, 0x33, 0x6a, 0x52, 0x0f, 0x82, 0x31, 0x41, 0xc6, 0xf3, +0xb1, 0x83, 0x34, 0x18, 0x2c, 0x06, 0x92, 0xa0, 0x03, 0x43, 0xe4, 0xf6, 0xbf, 0x30, 0x8a, 0x53, +0x0b, 0xbb, 0xc6, 0x0f, 0x30, 0x8a, 0x30, 0x73, 0x46, 0x0c, 0x1c, 0xe4, 0x48, 0x0f, 0x5a, 0x12, +0x03, 0x61, 0x06, 0xc4, 0x0f, 0x42, 0x72, 0x00, 0xca, 0x20, 0x33, 0x9b, 0x85, 0x40, 0x47, 0xec, +0x05, 0x9f, 0x7f, 0x85, 0x85, 0x36, 0x04, 0xbd, 0x9f, 0x88, 0x91, 0x43, 0xde, 0x32, 0x33, 0xff, +0xec, 0xc2, 0x1f, 0x30, 0x2f, 0x30, 0xac, 0xd2, 0x16, 0xa4, 0xf4, 0x0c, 0x31, 0x5b, 0x0f, 0x56, +0x06, 0x33, 0xfa, 0x00, 0xc3, 0x7c, 0x01, 0x01, 0xa3, 0x14, 0xb3, 0xf0, 0x0e, 0x90, 0xef, 0x2c, +0x8f, 0xc6, 0x49, 0x37, 0x7f, 0xc6, 0x09, 0x0b, 0x0f, 0xe2, 0x55, 0x11, 0xb7, 0xa4, 0x73, 0x0c, +0x90, 0x20, 0x73, 0x85, 0x91, 0x39, 0x81, 0xbd, 0x5f, 0x00, 0x2d, 0x21, 0xbb, 0x42, 0x16, 0x10, +0x09, 0xa1, 0xe7, 0x8a, 0x6f, 0xbd, 0x30, 0x62, 0x36, 0xec, 0xd1, 0x32, 0xa3, 0x56, 0x59, 0x33, +0xc8, 0x20, 0x33, 0x59, 0xd1, 0x0b, 0x59, 0x34, 0x78, 0x1d, 0xcd, 0x18, 0x94, 0xb0, 0x95, 0x2a, +0x0a, 0x1e, 0x11, 0xd0, 0x82, 0xcb, 0x0f, 0x7c, 0x20, 0x9a, 0x21, 0x7c, 0x22, 0xc0, 0x33, 0x45, +0x8a, 0x03, 0x5a, 0x1d, 0xcf, 0x83, 0xb8, 0xe6, 0x7c, 0x80, 0x33, 0x01, 0x23, 0x0c, 0x98, 0xcb, +0xca, 0x02, 0x90, 0x13, 0x0c, 0x62, 0x33, 0x8c, 0x02, 0x00, 0x07, 0xb3, 0x06, 0xf1, 0xb2, 0x33, +0x02, 0x05, 0x01, 0x03, 0x9b, 0x84, 0x01, 0x99, 0xc2, 0x80, 0x97, 0x65, 0x40, 0x95, 0xf1, 0x80, +0x94, 0x44, 0x06, 0x33, 0x2c, 0x22, 0x0f, 0x07, 0x8c, 0x89, 0x41, 0x98, 0x02, 0x90, 0x33, 0x2e, +0x03, 0x79, 0x76, 0x03, 0x03, 0x77, 0x83, 0x70, 0xdf, 0x33, 0xa4, 0x0a, 0x4b, 0x06, 0x67, 0x03, +0x60, 0x40, 0x65, 0x04, 0x68, 0xe9, 0x16, 0x99, 0xf6, 0x95, 0x10, 0x8a, 0xcf, 0x03, 0x3b, 0xc6, +0x0d, 0x12, 0x8a, 0x30, 0xeb, 0x42, 0xb1, 0x0b, 0x32, 0x60, 0x59, 0x90, 0xdf, 0x0d, 0x3c, 0x66, +0x09, 0x39, 0x00, 0x64, 0x10, 0x33, 0xc4, 0x42, 0x38, 0x80, 0x20, 0x57, 0xec, 0xc0, 0x49, 0x3c, +0x22, 0x03, 0xce, 0x45, 0x88, 0x23, 0x7c, 0x10, 0x32, 0x33, 0x60, 0x19, 0x41, 0x64, 0x26, 0x56, +0x29, 0x30, 0x60, 0x30, 0xb7, 0x6c, 0x7c, 0x0a, 0x0d, 0x32, 0x88, 0x33, 0x1e, 0xb0, 0x37, 0xe4, +0x03, 0x35, 0xe0, 0x1e, 0x30, 0x34, 0x2e, 0x03, 0x33, 0x7c, 0x42, 0xc6, 0x6f, 0xc6, 0x60, 0x59, +0x0d, 0xc5, 0x32, 0x2d, 0x03, 0x1c, 0xcb, 0x2b, 0x13, 0x2c, 0x1a, 0xca, 0x80, 0x27, 0x56, 0x34, +0x56, 0x80, 0x14, 0x78, 0xc0, 0x1f, 0x63, 0x36, 0xec, 0x34, 0xa3, 0x15, 0x54, 0x46, 0x73, 0xc0, +0x80, 0x19, 0x06, 0x3c, 0x18, 0x70, 0x15, 0x32, 0x60, 0x13, 0x03, 0x06, 0x18, 0x0f, 0xc0, 0x02, +0x20, 0x62, 0x0d, 0x00, 0xc2, 0x33, 0x47, 0x83, 0x5f, 0xc4, 0xa3, 0x5e, 0x3d, 0x18, 0x33, 0x00, +0x3a, 0x6c, 0x30, 0xda, 0x0f, 0x6c, 0xb8, 0x4e, 0x18, 0xc4, 0x33, 0x28, 0x14, 0x0e, 0xcd, 0x0c, +0x39, 0xc2, 0x20, 0x33, 0x68, 0x09, 0x97, 0x16, 0x89, 0x6b, 0x9c, 0xc9, 0xb3, 0x07, 0x60, 0x30, +0xd0, 0xa1, 0xb2, 0x0c, 0xe2, 0xb1, 0x33, 0x11, 0xa1, 0x88, 0x20, 0x43, 0x44, 0x90, 0x3b, 0x10, +0x19, 0x33, 0x30, 0xa1, 0x5e, 0xc4, 0xec, 0x17, 0x7f, 0x10, 0x19, 0x33, 0xdf, 0xa1, 0x28, 0xcd, +0x76, 0xe2, 0xd0, 0x18, 0x6c, 0x22, 0x95, 0x8f, 0x9b, 0xf6, 0x22, 0x0e, 0x19, 0xb1, 0xd6, 0x44, +0x59, 0x06, 0x45, 0x6c, 0x07, 0x30, 0x10, 0x92, 0x53, 0x9f, 0x22, 0x50, 0xe6, 0x16, 0x2c, 0xfb, +0x06, 0x10, 0x6e, 0x07, 0x0a, 0x65, 0x33, 0x1b, 0x24, 0x20, 0x30, 0x3f, 0x86, 0x05, 0x1b, 0x1c, +0x11, 0x57, 0x12, 0xc1, 0x20, 0x33, 0xf0, 0x0e, 0x5f, 0x0f, 0x16, 0xef, 0x5f, 0x07, 0x9f, 0x8b, +0x0d, 0x7c, 0xef, 0x27, 0x19, 0xc4, 0x33, 0x3c, 0x8a, 0x5a, 0x2f, 0x5e, 0x89, 0x93, 0x45, 0x73, +0x07, 0x47, 0x98, 0x9b, 0x6f, 0xbf, 0x07, 0x23, 0xd8, 0x30, 0x0f, 0x4f, 0x5f, 0x84, 0xd3, 0x0c, +0xf1, 0x0e, 0x79, 0x77, 0x63, 0x65, 0x6b, 0x4d, 0x19, 0xc4, 0x33, 0xc1, 0x22, 0x53, 0x40, 0xff, +0xe1, 0x32, 0xe4, 0x3a, 0xf6, 0x2a, 0x5f, 0x86, 0xa0, 0x20, 0x34, 0x45, 0x12, 0x33, 0x8b, 0x81, +0x3e, 0x35, 0x8b, 0x87, 0x87, 0x2e, 0x8b, 0x21, 0x18, 0x21, 0x20, 0x0e, 0x3c, 0x6c, 0xf1, 0x2b, +0x7a, 0x78, 0x90, 0x41, 0x33, 0x01, 0x39, 0xb5, 0x72, 0xc1, 0x93, 0x54, 0x9d, 0x4c, 0x44, 0x56, +0x67, 0x4a, 0x52, 0x09, 0x80, 0x68, 0x44, 0x35, 0xca, 0x2a, 0xa7, 0x05, 0xe6, 0xc0, 0x5a, 0x59, +0x67, 0x80, 0x1f, 0xff, 0x1a, 0x1e, 0x1c, 0x8b, 0x8d, 0x37, 0x58, 0xd6, 0x56, 0xc1, 0x67, 0xa5, +0x46, 0x49, 0x64, 0x01, 0x83, 0x4c, 0x36, 0x33, 0x12, 0x7c, 0x65, 0x15, 0x67, 0x10, 0x6e, 0x6c, +0x60, 0x49, 0x97, 0x29, 0xab, 0x67, 0x88, 0x70, 0x1f, 0x05, 0x4b, 0x27, 0x4b, 0x59, 0x67, 0x37, +0x16, 0x44, 0xb7, 0xac, 0x12, 0x3f, 0x48, 0x16, 0x5f, 0xca, 0x2a, 0x67, 0x65, 0x9f, 0x00, 0xf6, +0x62, 0x64, 0x3f, 0xc8, 0xbb, 0x00, 0x76, 0x32, 0x34, 0x30, 0x88, 0xd9, 0x78, 0x4f, 0x2c, 0x2c, +0xa7, 0x80, 0x38, 0x1f, 0x05, 0xcb, 0xb7, 0x17, 0x59, 0x67, 0x36, 0x2c, 0x88, 0x1c, 0xd7, 0x88, +0x87, 0x06, 0x12, 0x34, 0x0d, 0x0c, 0xe7, 0x93, 0xbf, 0xbf, 0x64, 0x6c, 0x78, 0x70, 0xe0, 0xe0, +0x65, 0x10, 0x33, 0x09, 0x20, 0xd6, 0x58, 0x82, 0x8f, 0xca, 0x2a, 0x67, 0x25, 0xac, 0x5f, 0x09, +0xd5, 0x18, 0xa1, 0xdc, 0xb0, 0x4f, 0x0f, 0x90, 0xd0, 0x6d, 0x8f, 0x41, 0xbc, 0x7f, 0x21, 0x21, +0x37, 0x7f, 0x92, 0x2d, 0x3f, 0x59, 0x10, 0xff, 0x0f, 0x57, 0x85, 0xaf, 0x29, 0x1e, 0x54, 0xf0, +0xe8, 0x65, 0xc3, 0x8f, 0x3f, 0x21, 0xb8, 0xf4, 0xcf, 0x0b, 0x22, 0x07, 0x1e, 0x03, 0x5f, 0xc8, +0x20, 0x33, 0x25, 0x8b, 0x41, 0x0b, 0xfd, 0x18, 0x59, 0x63, 0x70, 0xcb, 0x0f, 0xaf, 0x2a, 0x83, +0x33, 0xc8, 0x18, 0x18, 0xff, 0x84, 0xd9, 0x12, 0x2f, 0x19, 0xc4, 0x33, 0x6d, 0x15, 0xd4, 0x68, +0x61, 0xff, 0x61, 0x9c, 0x49, 0x1f, 0x30, 0x88, 0x33, 0x9c, 0x00, 0x0c, 0x7e, 0x21, 0x45, 0x27, +0x0c, 0x22, 0x33, 0xe2, 0xb0, 0xaf, 0x0b, 0x81, 0x47, 0x91, 0x90, 0xc6, 0x29, 0xc2, 0x7f, 0x67, +0xe2, 0x2d, 0x2f, 0x2c, 0x09, 0x67, 0x95, 0x41, 0x33, 0x0e, 0x69, 0x8f, 0xfe, 0x06, 0x71, 0x33, +0x62, 0x55, 0x03, 0x2b, 0xf7, 0x06, 0x1c, 0x4f, 0x8d, 0x62, 0x59, 0x3f, 0xaa, 0x0c, 0x33, 0xc2, +0xdc, 0x2f, 0xdf, 0x62, 0x52, 0x8f, 0x2d, 0x29, 0xc7, 0xb7, 0xec, 0xcf, 0x0f, 0x0d, 0x8d, 0x2c, +0xef, 0xcd, 0x9a, 0xef, 0xef, 0x81, 0xe2, 0x4f, 0xc7, 0x20, 0x26, 0xf6, 0xd8, 0xca, 0x33, 0x5f, +0x29, 0x22, 0xe7, 0x78, 0x30, 0x0f, 0x08, 0x83, 0x33, 0x15, 0xb1, 0x86, 0x80, 0x07, 0x0f, 0x65, +0x10, 0x33, 0x98, 0x0b, 0x5f, 0x00, 0x96, 0x56, 0x43, 0x3c, 0x12, 0x00, 0xfc, 0x51, 0x10, 0x88, +0x85, 0x71, 0x28, 0x30, 0x33, 0xa4, 0xec, 0x18, 0x37, 0x04, 0x1e, 0xff, 0x7f, 0x04, 0xb7, 0x3a, +0x3f, 0x96, 0xb0, 0x7f, 0x05, 0x13, 0x2f, 0x45, 0x59, 0x67, 0x68, 0x14, 0x55, 0x60, 0x6d, 0xcc, +0x91, 0x9f, 0xc0, 0xb2, 0x0a, 0x67, 0x18, 0x30, 0xf5, 0xf0, 0x22, 0xa4, 0x84, 0x55, 0x67, 0xcb, +0x80, 0xf1, 0xc0, 0x80, 0x7c, 0xef, 0xab, 0xe0, 0x7c, 0x67, 0x70, 0x21, 0x5e, 0x40, 0x82, 0x31, +0x65, 0x40, 0xe9, 0x41, 0xbc, 0x1b, 0x82, 0x65, 0x8f, 0x2c, 0xac, 0x67, 0x1b, 0x06, 0xe3, 0x0d, +0x19, 0x10, 0xe1, 0x55, 0x70, 0x3c, 0x20, 0x94, 0x67, 0x62, 0x33, 0xdb, 0x37, 0x2e, 0x03, 0xd9, +0x78, 0x2c, 0x03, 0xd7, 0x96, 0x10, 0x9b, 0x30, 0x20, 0x6d, 0x56, 0xc1, 0x67, 0x80, 0x15, 0x80, +0xcb, 0xcf, 0x3c, 0x40, 0xc0, 0xcd, 0x6f, 0x67, 0xcc, 0x78, 0x08, 0x3c, 0x38, 0x70, 0xa2, 0xd0, +0xf2, 0x36, 0x3f, 0x8d, 0x0c, 0x33, 0x87, 0x19, 0x47, 0x4f, 0x59, 0x05, 0x67, 0x84, 0x41, 0x33, +0x00, 0x94, 0xcd, 0x82, 0xb6, 0x45, 0x82, 0xa1, 0x0d, 0xca, 0x5d, 0x0c, 0x58, 0xb7, 0x61, 0xb6, +0xfb, 0x4f, 0x86, 0x2d, 0x37, 0x62, 0x13, 0xbf, 0x0d, 0x3b, 0x03, 0xb1, 0x66, 0x7d, 0x86, 0x25, +0x37, 0x96, 0xe0, 0xd5, 0x95, 0x92, 0x20, 0x93, 0x88, 0xc7, 0x13, 0xaa, 0x30, 0x33, 0x02, 0x49, +0x56, 0xf0, 0xed, 0x9d, 0x12, 0x06, 0xcd, 0x20, 0x5a, 0x99, 0x86, 0xc8, 0x33, 0x18, 0xb6, 0x30, +0x9f, 0x10, 0x31, 0x61, 0x09, 0x15, 0x06, 0x33, 0x0c, 0x58, 0x79, 0x06, 0x04, 0x77, 0x10, 0x07, +0x76, 0x01, 0x65, 0x33, 0xc1, 0x80, 0x65, 0x32, 0x88, 0x76, 0x33, 0x19, 0x10, 0x61, 0x10, 0x2f, +0x0d, 0x20, 0x61, 0x33, 0xe0, 0x32, 0x5d, 0x76, 0x91, 0x30, 0x5b, 0x45, 0x06, 0x33, 0x19, 0xa4, +0x1d, 0xfe, 0x19, 0xc4, 0x33, 0x88, 0x14, 0xb1, 0xa4, 0xe5, 0x32, 0xa0, 0x05, 0x49, 0x0c, 0xe2, +0x7c, 0x33, 0x40, 0x8a, 0x20, 0x60, 0x3f, 0x90, 0x30, 0x3d, 0x4b, 0x18, 0x3b, 0x0b, 0x16, 0xd6, +0x51, 0x66, 0xcd, 0xd1, 0x51, 0x2e, 0x03, 0x35, 0xe6, 0xc8, 0x20, 0x33, 0x65, 0x40, 0x31, 0x78, +0xc0, 0xf0, 0x2f, 0x02, 0x83, 0x33, 0x14, 0x11, 0x88, 0x97, 0x13, 0x0c, 0x38, 0x04, 0x32, 0x33, +0x14, 0x06, 0x23, 0x0c, 0xf8, 0x30, 0x1c, 0x6c, 0x38, 0x1d, 0x10, 0x2b, 0x01, 0x60, 0x33, 0xc0, +0x8c, 0xf5, 0x63, 0x65, 0x0f, 0x21, 0x80, 0x30, 0x17, 0xcb, 0x80, 0x0b, 0xac, 0x82, 0xf0, 0x67, +0x08, 0x02, 0x70, 0x10, 0x09, 0xc9, 0x2a, 0x87, 0xb1, 0x07, 0x61, 0x05, 0x87, 0x5c, 0xb5, 0xac, +0xab, 0xe0, 0x30, 0x70, 0xdc, 0x67, 0x0a, 0x06, 0x63, 0x18, 0x4d, 0x73, 0xc0, 0x55, 0x30, 0x7c, +0xfe, 0x83, 0x67, 0x0c, 0x18, 0xfe, 0x86, 0x1c, 0x70, 0xc2, 0xfe, 0x68, 0x41, 0x0f, 0xc4, 0x2a, +0xe1, 0x60, 0x15, 0x67, 0x67, 0xe8, 0x0c, 0xd8, 0x21, 0x07, 0xc6, 0x68, 0x06, 0x6c, 0xa5, 0x3c, +0xb2, 0x0a, 0x67, 0xef, 0x16, 0x07, 0xc2, 0xc4, 0x1f, 0xa3, 0x02, 0x88, 0x8d, 0x60, 0x17, 0x37, +0x7e, 0xc2, 0x0b, 0xdc, 0x17, 0x86, 0xfc, 0xdb, 0x00, 0x5e, 0x10, 0x08, 0xb2, 0x0a, 0x67, 0x78, +0x14, 0x63, 0xed, 0xb1, 0x2d, 0x23, 0x61, 0xf2, 0x2e, 0x1b, 0x88, 0x68, 0xd9, 0x3c, 0x78, 0xc3, +0xe8, 0xf0, 0x30, 0x3e, 0x4e, 0x31, 0x6b, 0x04, 0xc1, 0x50, 0x06, 0x33, 0x1e, 0xbd, 0xad, 0x27, +0x1e, 0xcd, 0x25, 0x21, 0xe2, 0xcd, 0xc7, 0x5f, 0x99, 0x01, 0xcf, 0xbd, 0x8b, 0xb9, 0x1f, 0xfd, +0x07, 0x7c, 0x74, 0x7c, 0xc2, 0x05, 0xc2, 0xc5, 0x1e, 0x67, 0x1f, 0xd9, 0xac, 0x27, 0xe7, 0xa5, +0x10, 0x86, 0x2f, 0x05, 0x60, 0x33, 0x40, 0xb8, 0xbf, 0x3c, 0xe1, 0x5b, 0x05, 0x30, 0xe0, 0x95, +0x41, 0x33, 0xf2, 0x2c, 0xb7, 0x18, 0x18, 0x0c, 0x62, 0x33, 0x43, 0x88, 0xf9, 0xc9, 0x87, 0x11, +0xc6, 0x7c, 0x32, 0x88, 0x33, 0x12, 0xa1, 0xc8, 0x98, 0xd0, 0x3e, 0x9f, 0x30, 0x83, 0x33, 0xc4, +0x60, 0xcd, 0xfc, 0x3f, 0x18, 0x33, 0x00, 0x3b, 0x19, 0x1a, 0x78, 0xc2, 0xc4, 0xd8, 0xd8, 0x18, +0x11, 0x0b, 0xa0, 0x42, 0x06, 0x33, 0x38, 0x1c, 0xc7, 0x79, 0x28, 0x83, 0x33, 0x4e, 0x6a, 0x7e, +0x0d, 0x38, 0x18, 0x2c, 0xd1, 0x7c, 0x28, 0x83, 0x33, 0xcc, 0x5a, 0x17, 0x6f, 0xbd, 0x5f, 0x56, +0xe6, 0xc6, 0x11, 0x13, 0x86, 0x07, 0x71, 0x11, 0x0c, 0xff, 0xd1, 0x6e, 0x6b, 0x1f, 0xaa, 0xfc, +0x39, 0x32, 0x88, 0x0c, 0x23, 0x63, 0x7b, 0xce, 0xf0, 0xe0, 0xb8, 0x63, 0x88, 0x19, 0xc4, 0x33, +0xf1, 0x5d, 0x18, 0x88, 0x0e, 0x0c, 0xa2, 0x07, 0x33, 0x58, 0x84, 0x5f, 0xf1, 0x58, 0x67, 0x62, +0x61, 0x4d, 0x08, 0x0c, 0x33, 0x6f, 0x42, 0xb1, 0x4f, 0xb9, 0x19, 0xbf, 0x1c, 0xb6, 0xf6, 0xa0, +0xce, 0x07, 0x97, 0xd8, 0x06, 0x61, 0x33, 0xc9, 0x53, 0xe9, 0x74, 0x50, 0x7a, 0x72, 0x55, 0xd1, +0x72, 0xc8, 0x88, 0x9b, 0x49, 0x8a, 0x01, 0x50, 0x85, 0x24, 0x22, 0x06, 0x83, 0x51, 0x0f, 0x33, +0x55, 0x19, 0x9b, 0xf1, 0x68, 0x5f, 0x40, 0x06, 0x33, 0x36, 0xa1, 0x6a, 0xaf, 0x98, 0x5b, 0x0c, +0x2f, 0x88, 0x4a, 0xa1, 0xc0, 0x9b, 0x30, 0x82, 0x18, 0x53, 0x11, 0xb5, 0x2f, 0x95, 0x9b, 0x7f, +0x09, 0x54, 0xdb, 0xab, 0x60, 0x67, 0x7a, 0x0b, 0xdf, 0x4b, 0xa2, 0xfb, 0x65, 0x10, 0x33, 0x57, +0x7c, 0x08, 0x1c, 0x36, 0x88, 0x2c, 0x22, 0x7d, 0x46, 0xd4, 0x9b, 0x0b, 0x15, 0x34, 0x1b, 0x99, +0x8f, 0x12, 0x6e, 0x99, 0xbf, 0xcc, 0x59, 0x54, 0x9b, 0x54, 0x6f, 0xcc, 0x1b, 0x19, 0xab, 0x00, +0x44, 0x2d, 0x6e, 0x65, 0x9b, 0xcc, 0x5e, 0x54, 0xbb, 0x06, 0x71, 0x33, 0x56, 0x05, 0xb3, 0x0a, +0x67, 0x20, 0x22, 0xaa, 0xc8, 0x33, 0x0a, 0xda, 0xeb, 0x52, 0xc8, 0x33, 0x3f, 0xaf, 0x60, 0x33, +0x60, 0x10, 0x33, 0x2c, 0x01, 0x00, 0x28, 0x23, 0xc2, 0x2a, 0x67, 0x59, 0x80, 0xbf, 0x2a, 0x08, +0xa1, 0xc2, 0x67, 0x4a, 0x6a, 0x55, 0xdf, 0x92, 0x5c, 0x12, 0xdf, 0x56, 0xc1, 0x67, 0xd9, 0x52, +0x0c, 0xff, 0x0d, 0x6b, 0x7e, 0x2f, 0x25, 0x3d, 0xd1, 0xf8, 0xef, 0xac, 0x82, 0x67, 0xc4, 0x28, +0x21, 0x73, 0x41, 0xbf, 0xc2, 0x72, 0x74, 0x9f, 0x57, 0x41, 0x67, 0x15, 0xc8, 0x18, 0xa6, 0x8c, +0x02, 0x6c, 0x55, 0x2a, 0x84, 0x37, 0xbb, 0x77, 0xec, 0xb8, 0xae, 0xc4, 0xb1, 0x2c, 0xef, 0x45, +0x06, 0x33, 0x04, 0x4b, 0x00, 0x65, 0x15, 0x67, 0x55, 0x41, 0x31, 0xa3, 0xe9, 0xa8, 0x07, 0x33, +0x8a, 0x8c, 0x9b, 0x08, 0x37, 0x26, 0x8c, 0x30, 0x33, 0x48, 0x06, 0xe3, 0x16, 0x23, 0x51, 0x29, +0x88, 0x5a, 0x21, 0xc0, 0x9b, 0x97, 0x01, 0xd5, 0x3c, 0x64, 0x10, 0x33, 0x35, 0x4b, 0x6f, 0x96, +0x40, 0x73, 0xb2, 0x0a, 0x67, 0x64, 0xc0, 0xcb, 0xc1, 0xa3, 0x5a, 0x56, 0x56, 0x67, 0x12, 0xa8, +0x81, 0x46, 0xd4, 0x9b, 0x4b, 0x05, 0x2d, 0x5b, 0x98, 0x7d, 0x10, 0x6e, 0x98, 0xa7, 0xb2, 0x96, +0x01, 0xb4, 0x2c, 0x03, 0xb3, 0x52, 0x06, 0xb2, 0x30, 0xa2, 0x9b, 0x19, 0x30, 0xad, 0x06, 0x71, +0x78, 0x33, 0x12, 0x01, 0x33, 0x03, 0x97, 0x32, 0x88, 0x33, 0x90, 0x00, 0x63, 0x18, 0x79, 0x67, +0x15, 0x2c, 0x83, 0x98, 0x73, 0x33, 0x0d, 0x28, 0x24, 0x58, 0x5e, 0x9c, 0xc9, 0x60, 0x15, 0x67, +0x60, 0x50, 0x38, 0x33, 0x49, 0xc2, 0x2a, 0x67, 0x59, 0x03, 0x7b, 0xb7, 0xa4, 0x63, 0x10, 0xb0, +0xac, 0x0b, 0x85, 0x55, 0x67, 0xc3, 0x80, 0x37, 0x81, 0x01, 0x35, 0x56, 0xc1, 0xe6, 0x67, 0x20, +0x10, 0xd9, 0x32, 0x2d, 0xa7, 0x01, 0xa6, 0x86, 0xc1, 0x85, 0x2a, 0x18, 0x55, 0x56, 0x67, 0xc0, +0x80, 0x21, 0x1e, 0xb0, 0x20, 0x2c, 0x03, 0x1f, 0x90, 0x41, 0x33, 0x03, 0x12, 0x0d, 0x55, 0x30, +0x54, 0x80, 0x67, 0x20, 0x06, 0x44, 0xcd, 0x33, 0x17, 0x65, 0x9b, 0x7e, 0x30, 0x88, 0xc3, 0x33, +0xcc, 0x95, 0xe1, 0x51, 0x19, 0xc4, 0x4b, 0x8c, 0xa8, 0x9b, 0x51, 0x08, 0x10, 0x83, 0x75, 0x3c, +0x2e, 0x64, 0x33, 0x3f, 0x5e, 0x51, 0x3b, 0xb0, 0x0a, 0x67, 0xcc, 0x5d, 0x4f, 0x7e, 0xc0, 0xce, +0x1e, 0x8c, 0x4e, 0x1e, 0x33, 0x00, 0x82, 0x87, 0x93, 0x78, 0x28, 0xac, 0x67, 0xc5, 0x5c, 0x41, +0x47, 0x51, 0xcc, 0x07, 0x5f, 0xc7, 0xc0, 0xaf, 0xa1, 0x0e, 0xdb, 0xc0, 0x6d, 0xb5, 0xf8, 0x30, +0x15, 0x4c, 0x92, 0xff, 0x64, 0x67, 0x70, 0xd8, 0x07, 0x03, 0x03, 0x73, 0x63, 0x30, 0x88, 0x3e, +0x33, 0x41, 0x28, 0x08, 0x56, 0x67, 0x22, 0x83, 0x33, 0xbe, 0x87, 0x7c, 0x82, 0x7c, 0x71, 0x7c, +0x62, 0x8e, 0xd5, 0xd1, 0xca, 0x20, 0x33, 0x90, 0x8d, 0x00, 0xac, 0x82, 0x67, 0x16, 0x22, 0x5f, +0x2a, 0x18, 0x85, 0xc2, 0x67, 0xc2, 0xd0, 0xf1, 0xc6, 0xef, 0x09, 0x05, 0xe9, 0xef, 0x8c, 0xa8, +0x9b, 0x70, 0x31, 0x99, 0x58, 0xbc, 0x98, 0x93, 0x55, 0x30, 0xe6, 0x23, 0x84, 0x67, 0xc1, 0xe4, +0xc7, 0x4f, 0xcc, 0x78, 0x98, 0xc5, 0x00, 0xca, 0x2a, 0x67, 0x58, 0xc2, 0x00, 0xc5, 0xbf, 0x56, +0xbc, 0xc0, 0x40, 0x80, 0x83, 0x88, 0xea, 0x33, 0x16, 0x22, 0x00, 0x2a, 0x48, 0x3c, 0xca, 0x67, +0x1d, 0xbf, 0xc9, 0x80, 0x59, 0xa2, 0xe0, 0x05, 0x99, 0x8a, 0xc8, 0xcf, 0x50, 0x49, 0x24, 0x41, +0x14, 0x8a, 0xa0, 0x04, 0xbf, 0xc2, 0xa2, 0xcf, 0xc4, 0x0a, 0x54, 0x18, 0x33, 0x8f, 0xa8, 0x9b, +0x02, 0x21, 0x30, 0x0a, 0xc7, 0x54, 0x30, 0x88, 0x85, 0x87, 0xa8, 0x32, 0x33, 0x46, 0xd4, 0x9b, +0x40, 0x56, 0x84, 0xa2, 0x49, 0x15, 0x5f, 0xaa, 0x08, 0x41, 0xcc, 0x71, 0x18, 0x91, 0x33, 0x43, +0x82, 0x17, 0x18, 0x51, 0x9b, 0x16, 0x04, 0xe2, 0xcc, 0x00, 0xad, 0x8c, 0xd3, 0x61, 0x44, 0x9b, +0x20, 0x52, 0xb1, 0x0c, 0xbf, 0x65, 0x00, 0x1f, 0x23, 0x6a, 0x9b, 0x0d, 0x02, 0x23, 0xca, 0x00, +0x9b, 0x80, 0x00, 0x47, 0x89, 0xa1, 0x8b, 0x02, 0xcf, 0x03, 0x02, 0x61, 0x10, 0x33, 0xa2, 0x02, +0x80, 0x38, 0x9b, 0x28, 0x58, 0x05, 0xcb, 0xfb, 0x08, 0x49, 0xa3, 0x22, 0x83, 0x33, 0x44, 0x25, +0x64, 0x64, 0x9b, 0xaa, 0x00, 0x61, 0x40, 0x65, 0x33, 0x20, 0x63, 0x61, 0x10, 0x33, 0x20, 0x46, +0x54, 0x30, 0xc1, 0x54, 0x46, 0x9b, 0x03, 0x02, 0x35, 0x01, 0x2b, 0x23, 0xea, 0x34, 0x9b, 0x31, +0x08, 0x58, 0x52, 0x65, 0x12, 0x80, 0x75, 0x11, 0x15, 0x4b, 0x95, 0x9b, 0x00, 0x46, 0x94, 0x9b, +0x40, 0x10, 0x42, 0x0e, 0x00, 0x00, 0x10, 0x09, 0x0a, 0x61, 0x33, 0xc2, 0x88, 0x9b, 0x02, 0x11, +0x63, 0x81, 0x08, 0xc3, 0x41, 0x04, 0x0a, 0x95, 0x33, 0xc0, 0x88, 0x9b, 0x14, 0xaa, 0x74, 0x22, +0x23, 0x20, 0x26, 0x1d, 0x31, 0xc2, 0x33, 0x82, 0x00, 0xbf, 0x30, 0xa2, 0x9b, 0x11, 0x02, 0x62, +0x64, 0x92, 0x21, 0x0c, 0x33, 0x20, 0x14, 0x2b, 0xa9, 0x82, 0x77, 0x44, 0x05, 0x06, 0x60, 0x9b, +0x11, 0xe5, 0x00, 0x53, 0x90, 0x9b, 0x51, 0x30, 0x88, 0xe5, 0x33, 0x3c, 0x19, 0x5a, 0x39, 0xbf, +0x59, 0x14, 0xcf, 0x59, 0x11, 0xa8, 0x00, 0x25, 0x09, 0x42, 0x05, 0xc0, 0x20, 0x33, 0x10, 0x2a, +0x64, 0x51, 0xcf, 0x50, 0x41, 0x0c, 0x22, 0x33, 0x04, 0xaa, 0x58, 0x14, 0xcf, 0x01, 0x00, 0x83, +0x18, 0x33, 0xa1, 0x00, 0x16, 0x05, 0xcf, 0x43, 0x40, 0x0d, 0xdb, 0xff, 0x0a, 0x54, 0x68, 0x69, +0x73, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x04, 0x69, 0x7f, 0xfb, 0x6c, 0x65, 0x20, 0x68, 0x61, 0x0d, +0x62, 0x65, 0x65, 0x6e, 0x20, 0x63, 0xdb, 0xfe, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x2f, 0x02, +0x69, 0x06, 0xfd, 0x9b, 0x13, 0x79, 0x20, 0x43, 0x50, 0x49, 0x61, 0x64, 0x6f, 0xbf, 0x09, 0x56, +0x31, 0x2e, 0x32, 0x30, 0x37, 0x43, 0x6f, 0x70, 0x7f, 0xf9, 0x79, 0x72, 0x69, 0x67, 0x68, 0x28, +0x43, 0x29, 0x20, 0x31, 0x39, 0xbf, 0xee, 0x39, 0x33, 0x2d, 0x04, 0x36, 0x28, 0x6b, 0x6f, 0xfe, +0xdb, 0x73, 0x74, 0x54, 0x40, 0x61, 0x63, 0x6d, 0x2e, 0x6f, 0x72, 0x67, 0xbb, 0xdb, 0x1f, 0x4b, +0x0f, 0x61, 0x20, 0x4b, 0x15, 0x07, 0x1b, 0x29, 0x71, 0x70, 0x72, 0xbb, 0xff, 0x6f, 0x67, 0x72, +0x61, 0x6d, 0x20, 0x6d, 0x61, 0x79, 0x6f, 0x20, 0x75, 0xd6, 0xba, 0x73, 0x63, 0x66, 0x72, 0x09, +0x6b, 0xed, 0x6f, 0x66, 0x7a, 0x84, 0x36, 0xdf, 0x5a, 0x09, 0x7e, 0x20, 0x79, 0x6f, 0x75, 0xd6, +0xb6, 0x72, 0x11, 0x77, 0x8d, 0x69, 0x00, 0xfc, 0x73, 0x6b, 0x2e, 0x0d, 0x0a, 0x00, 0x00, 0x00, +0x00, 0x00, 0x12, 0xff, 0xa4, 0xe8, 0x3a, 0x00, 0x72, 0xfa, 0x41, 0xe8, 0x2f, 0x00, 0xe3, 0x3b, +0x73, 0xf9, 0x83, 0xe9, 0x03, 0x72, 0x06, 0x88, 0xcc, 0xac, 0xf7, 0xd0, 0x95, 0x31, 0xc9, 0xe8, +0x1b, 0x00, 0x11, 0xc9, 0x75, 0x08, 0x41, 0xe8, 0x13, 0x00, 0x73, 0xfb, 0x41, 0x41, 0x81, 0xfd, +0x00, 0xf3, 0x83, 0xd1, 0x01, 0x8d, 0x03, 0x96, 0xf3, 0xa4, 0x96, 0xeb, 0xc8, 0xe8, 0x02, 0x00, +0x11, 0xc9, 0x01, 0xdb, 0x75, 0x04, 0xad, 0x11, 0xc0, 0x93, 0xc3, 0x5e, 0xb9, 0x01, 0x00, 0xac, +0x2c, 0xe8, 0x3c, 0x01, 0x77, 0xf9, 0x8b, 0x1c, 0x86, 0xdf, 0x29, 0xf3, 0x89, 0x1c, 0xad, 0xe2, +0xee, 0xc3 }; + +Bit8u font_ega3_cpx[5455] = { +0x81, 0xfc, 0xce, 0xe7, 0x77, 0x02, 0xcd, 0x20, 0xb9, 0x4f, 0x15, 0xbe, 0x4f, 0x16, 0xbf, 0x6e, +0xe7, 0xbb, 0x00, 0x80, 0xfd, 0xf3, 0xa4, 0xfc, 0x87, 0xf7, 0x83, 0xee, 0xc6, 0x19, 0xed, 0x57, +0x57, 0xe9, 0xed, 0xe5, 0x55, 0x50, 0x58, 0x21, 0x0b, 0x01, 0x04, 0x08, 0x10, 0x40, 0x37, 0xe4, +0x59, 0xc7, 0x7f, 0x53, 0x00, 0xe6, 0xb7, 0x14, 0x06, 0x45, 0xbb, 0xfc, 0xff, 0x46, 0x4f, 0x4e, +0x54, 0x20, 0x00, 0x00, 0x01, 0x6e, 0x39, 0x01, 0x17, 0x06, 0xfd, 0xfd, 0x06, 0x00, 0x1c, 0x00, +0x4d, 0x26, 0x0e, 0x45, 0x47, 0x41, 0xc9, 0xcd, 0x1e, 0x20, 0x03, 0x03, 0xb7, 0xd8, 0x35, 0x24, +0x0c, 0x12, 0x26, 0xb2, 0xd8, 0x10, 0x08, 0x0a, 0x00, 0xed, 0xbf, 0x7e, 0x81, 0xa5, 0x81, 0x81, +0xbd, 0x99, 0x03, 0x7f, 0xb0, 0x7e, 0x0f, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xfc, 0xce, 0xff, +0xff, 0x00, 0x6c, 0xfe, 0x87, 0xdd, 0x7c, 0x38, 0x10, 0x30, 0x10, 0x1f, 0xd8, 0x38, 0x7c, 0x0e, +0x18, 0x3c, 0x3c, 0xd6, 0xb6, 0xe7, 0x00, 0x18, 0x06, 0x0f, 0xcc, 0x4d, 0x7e, 0x3b, 0x0f, 0x76, +0xb6, 0x22, 0x18, 0x09, 0x3b, 0x76, 0xff, 0x00, 0xe7, 0xc3, 0x5f, 0xc7, 0xde, 0x00, 0x1f, 0x3c, +0x66, 0x5f, 0xf2, 0x42, 0x42, 0x66, 0x3c, 0xc3, 0x99, 0xbd, 0x3f, 0xe4, 0xbd, 0x99, 0xc3, 0x1e, +0x0e, 0x1a, 0x32, 0x7b, 0xdd, 0x78, 0xcc, 0x00, 0x78, 0x20, 0x2d, 0xd7, 0xdc, 0x00, 0x4f, 0x61, +0xf7, 0x33, 0x0f, 0x3f, 0x33, 0x3f, 0x30, 0x00, 0x1f, 0x79, 0x70, 0xf0, 0xe0, 0x00, 0x7f, 0x63, +0x7f, 0x63, 0xb3, 0x37, 0x67, 0xe7, 0xe6, 0xc0, 0x7c, 0xb0, 0xdb, 0x18, 0xdb, 0xa0, 0x3c, 0xdb, +0x2e, 0xb7, 0xff, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0x2d, 0xc0, 0x80, 0xff, 0x63, 0xbf, +0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x2d, 0xc9, 0x06, 0x02, 0x2b, 0xef, 0x6c, +0x5e, 0x3c, 0x00, 0x73, 0x93, 0x66, 0x07, 0x5f, 0xdc, 0x06, 0xdb, 0x00, 0x7b, 0x1b, 0x7f, 0xf3, +0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x80, 0xfc, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, +0xc8, 0xcc, 0xfe, 0x4f, 0x0d, 0x6c, 0x7e, 0x0f, 0x17, 0xec, 0x00, 0x0f, 0x00, 0xdf, 0xb2, 0x70, +0x11, 0x0c, 0x2e, 0xd9, 0xfe, 0x0c, 0x0c, 0x00, 0x80, 0xfc, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, +0xcc, 0xca, 0xc0, 0x5c, 0x2e, 0x27, 0xa1, 0x28, 0x6c, 0x28, 0x0a, 0xcb, 0x0e, 0x9f, 0xf6, 0x16, +0xa0, 0x7c, 0x7d, 0x8a, 0x61, 0x4b, 0x0e, 0x38, 0xaf, 0x17, 0xd8, 0x00, 0x18, 0xec, 0x95, 0x3c, +0x8c, 0x8f, 0x64, 0xdd, 0xe9, 0x24, 0x20, 0x31, 0x37, 0x6c, 0x5e, 0x03, 0xdf, 0x66, 0xad, 0xf1, +0xc2, 0xc0, 0x7c, 0x06, 0xc3, 0xda, 0x06, 0x86, 0xef, 0xc1, 0xe4, 0xdb, 0xc2, 0xc6, 0xae, 0x30, +0x60, 0xc6, 0x86, 0x85, 0xc2, 0x0e, 0x0c, 0x58, 0xc3, 0x76, 0xdc, 0xaf, 0x76, 0xbd, 0xb0, 0x2d, +0x00, 0x60, 0x4e, 0x31, 0x37, 0x2b, 0x00, 0x37, 0x6b, 0xe5, 0x0f, 0x08, 0xb2, 0x31, 0x00, 0x18, +0xe2, 0xc2, 0xc2, 0xde, 0xff, 0xe5, 0x30, 0xb0, 0xa2, 0xc0, 0x96, 0xed, 0x14, 0x0d, 0xd8, 0x31, +0xfe, 0xb2, 0x95, 0xd7, 0x31, 0xbf, 0xc2, 0xe2, 0x9f, 0xc0, 0x80, 0x1f, 0x26, 0xae, 0xd6, 0xd6, +0xc1, 0x0e, 0xb2, 0x27, 0x0b, 0xc2, 0x38, 0x78, 0x81, 0x2e, 0x9e, 0x3c, 0x7c, 0xc6, 0xc6, 0xfe, +0xdb, 0xc9, 0x0f, 0x06, 0x3c, 0x02, 0x06, 0x7f, 0x08, 0xdf, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0x13, +0xba, 0xfe, 0xb0, 0x1e, 0x8d, 0xc0, 0x9a, 0xfe, 0xfc, 0x1f, 0x72, 0x77, 0x38, 0x60, 0x0f, 0xc6, +0xc6, 0xc6, 0xcc, 0x1d, 0xfe, 0x3f, 0xf3, 0x6e, 0xd8, 0x4f, 0x1a, 0x2f, 0x60, 0x1f, 0x0b, 0x61, +0xbb, 0x7e, 0x3f, 0x0c, 0x78, 0xba, 0x61, 0x6f, 0x04, 0x0f, 0x6c, 0x72, 0x30, 0x9e, 0x52, 0x43, +0x35, 0x06, 0xc2, 0xd9, 0x5b, 0x02, 0x00, 0x5e, 0x2c, 0x1b, 0x23, 0x84, 0xc9, 0x5f, 0x0c, 0xdf, +0x76, 0xb6, 0x10, 0xde, 0x00, 0x8c, 0xc2, 0xdc, 0xc4, 0x2e, 0x67, 0x3b, 0x6c, 0x90, 0xfe, 0x8d, +0x67, 0x0f, 0xfc, 0x66, 0xf1, 0x90, 0x9e, 0x7c, 0xfc, 0x6f, 0xba, 0xc2, 0xef, 0x00, 0xc2, 0x3e, +0x9d, 0xa1, 0x10, 0xf8, 0x6c, 0x67, 0x4f, 0x6c, 0xf8, 0x0f, 0xfe, 0x90, 0xff, 0x66, 0x62, 0x68, +0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0xd8, 0x96, 0x00, 0xf0, 0x3f, 0xc9, 0x0f, 0xde, 0xc6, 0xc6, +0x66, 0x3a, 0xec, 0xbd, 0x69, 0x6e, 0x6f, 0x4d, 0x38, 0x3c, 0x7d, 0xc6, 0x64, 0x30, 0x1e, 0x0d, +0x2e, 0x29, 0xef, 0xe6, 0xd6, 0xed, 0x6a, 0x78, 0x78, 0x74, 0xe6, 0x0f, 0x16, 0x7b, 0xf0, 0x60, +0x00, 0x6f, 0xf2, 0x6f, 0x4f, 0xee, 0xfe, 0xfe, 0xd6, 0x7e, 0x5b, 0x0f, 0xe6, 0xf6, 0xfe, 0xde, +0xce, 0x0f, 0x4b, 0x6f, 0xc6, 0xb3, 0x25, 0xdf, 0x84, 0x7d, 0x41, 0xf0, 0x1f, 0x92, 0xfc, 0xd6, +0xde, 0x7c, 0x0c, 0x0e, 0x25, 0xfb, 0xe3, 0xe6, 0x1f, 0x56, 0x28, 0xe2, 0x50, 0x3f, 0x61, 0x4f, +0x7e, 0x7e, 0x5a, 0xaf, 0x42, 0x36, 0xc6, 0x5f, 0xe4, 0xc1, 0x0f, 0x6c, 0x38, 0x10, 0xc8, 0xbf, +0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0xcd, 0x74, 0x6c, 0x8e, 0x61, 0xac, 0x61, 0x9f, 0xce, 0x61, +0xd9, 0x4f, 0x1b, 0xe4, 0x63, 0x86, 0x7f, 0xc2, 0x82, 0x3d, 0x3c, 0x30, 0x00, 0x5f, 0xc1, 0x1f, +0xc1, 0x70, 0x4e, 0xd6, 0x38, 0x1c, 0xaf, 0x3c, 0x0c, 0x8c, 0xc1, 0x00, 0x3c, 0xdc, 0x11, 0x52, +0xe6, 0x9d, 0xa6, 0x6c, 0xff, 0x7d, 0x80, 0x18, 0x78, 0x0c, 0x7c, 0xc2, 0x25, 0xaf, 0xe0, 0x19, +0x2c, 0xc2, 0x78, 0xe2, 0xcf, 0x63, 0xc2, 0x02, 0x00, 0x77, 0x98, 0xdf, 0x1c, 0x69, 0x65, 0x25, +0x00, 0x2f, 0x90, 0xb1, 0x1f, 0xfe, 0x78, 0x1f, 0x36, 0x32, 0x30, 0x78, 0xaf, 0xbe, 0xcb, 0xcf, +0x76, 0x2e, 0xcc, 0x3b, 0x14, 0x5f, 0xd2, 0x5f, 0xc6, 0xf3, 0x6c, 0x76, 0xe6, 0xdc, 0x20, 0x4c, +0x38, 0x4f, 0x6d, 0x69, 0x09, 0x00, 0xdb, 0x19, 0x62, 0x00, 0x17, 0xce, 0x98, 0x2f, 0x00, 0xe6, +0x92, 0x33, 0x2f, 0x38, 0x46, 0x17, 0x00, 0xec, 0x00, 0xc9, 0xba, 0x00, 0xc6, 0x0f, 0xd9, 0x8c, +0xdc, 0xa1, 0x9f, 0x2d, 0x61, 0x9f, 0x3e, 0x96, 0x1f, 0x04, 0xf0, 0xd2, 0xc2, 0x9f, 0xd2, 0xa3, +0x1d, 0xdc, 0x9f, 0x1f, 0x09, 0x2c, 0xe4, 0x2e, 0x81, 0xdf, 0x10, 0xf6, 0xdb, 0xd9, 0xfc, 0xde, +0x36, 0x1c, 0x1f, 0xc2, 0x4b, 0x3d, 0x0f, 0x30, 0x06, 0x00, 0x08, 0x58, 0x0f, 0x96, 0xf0, 0x00, +0x9a, 0x66, 0xea, 0x1b, 0x38, 0x75, 0x2f, 0xba, 0x16, 0x04, 0x0c, 0xe0, 0x90, 0x52, 0xcc, 0x39, +0x7b, 0x4f, 0xfe, 0xef, 0x0e, 0xac, 0xa7, 0x70, 0x0e, 0xf7, 0x61, 0x90, 0x3f, 0x7b, 0x2f, 0x1b, +0x23, 0x24, 0x08, 0x5f, 0xc9, 0xdc, 0xdf, 0x91, 0x06, 0xe2, 0xf4, 0x61, 0x4f, 0x1e, 0x36, 0x66, +0xf9, 0x84, 0xef, 0xfe, 0x62, 0x60, 0x60, 0x25, 0x2d, 0xff, 0x92, 0x69, 0xcf, 0x71, 0x4b, 0x76, +0xf0, 0x3f, 0x00, 0x2d, 0x31, 0xa7, 0x81, 0x1b, 0x20, 0xff, 0xe9, 0x6b, 0x70, 0x54, 0x54, 0x70, +0x03, 0x04, 0x5a, 0x07, 0x3f, 0x77, 0x0b, 0x78, 0xce, 0xde, 0xf6, 0x73, 0xb3, 0xe6, 0x7f, 0x14, +0x0f, 0x48, 0x09, 0xef, 0x1d, 0xce, 0x6c, 0xef, 0xd2, 0x85, 0x6f, 0xc6, 0xef, 0xac, 0x10, 0x4f, +0x14, 0xd2, 0xef, 0x58, 0xb3, 0x1b, 0xdf, 0x52, 0x5b, 0xe0, 0xff, 0xb1, 0x12, 0xdf, 0x13, 0x49, +0xdf, 0x7e, 0xc7, 0x65, 0xbf, 0x7c, 0x6b, 0xe4, 0xa5, 0xcf, 0x7c, 0x10, 0x38, 0x64, 0x0b, 0x6e, +0xec, 0xd0, 0xff, 0x84, 0x3f, 0xc8, 0xb6, 0x00, 0x00, 0x76, 0xc8, 0xd6, 0xfe, 0x0f, 0xc1, 0x42, +0x2f, 0x6e, 0xe9, 0xf8, 0xb0, 0xb0, 0xea, 0x36, 0x00, 0x0e, 0x58, 0x4f, 0xf6, 0xde, 0xcb, 0xea, +0x00, 0xf6, 0xff, 0x18, 0x08, 0x9f, 0x4b, 0x6e, 0x5f, 0x26, 0x3e, 0x26, 0x7b, 0xba, 0xcc, 0x4f, +0xf6, 0xcc, 0xcf, 0x7a, 0x04, 0xda, 0x40, 0x7a, 0xb0, 0xce, 0xef, 0x18, 0xbc, 0x06, 0x7c, 0xaf, +0x4e, 0x58, 0x22, 0x7c, 0x18, 0xc9, 0x5f, 0x22, 0x12, 0xd2, 0x62, 0x0f, 0x3d, 0x1c, 0x92, 0xff, +0xc3, 0xe4, 0x25, 0x5f, 0xfe, 0xc0, 0xf0, 0xb1, 0x02, 0x7c, 0xcc, 0x92, 0xff, 0xa2, 0x01, 0x6b, +0x01, 0x1f, 0x2c, 0x08, 0xf1, 0x0f, 0x16, 0xf2, 0xc6, 0x7c, 0x26, 0x3d, 0x02, 0xef, 0x59, 0xc8, +0x6f, 0x0f, 0xd2, 0x63, 0x02, 0xef, 0x30, 0x06, 0x01, 0x14, 0x52, 0xef, 0x9e, 0xbd, 0x1c, 0x1f, +0x11, 0x44, 0xf2, 0xc2, 0x01, 0x55, 0xaa, 0x90, 0x17, 0xdd, 0x77, 0x02, 0xbb, 0x18, 0x00, 0x85, +0xec, 0xf8, 0x0d, 0x67, 0x93, 0x0f, 0x36, 0x00, 0xf6, 0x58, 0x90, 0x36, 0x80, 0x25, 0x6c, 0x0f, +0xe7, 0x91, 0x2f, 0xf6, 0x06, 0x4b, 0x60, 0x00, 0x3d, 0x42, 0x36, 0x1f, 0x64, 0xd1, 0x2f, 0xee, +0x59, 0xb0, 0x11, 0x0f, 0x35, 0x2c, 0x8f, 0xd9, 0x90, 0x00, 0xf8, 0xbf, 0x84, 0x0d, 0x1f, 0x2f, +0x43, 0xf2, 0x18, 0x18, 0xff, 0xff, 0x6b, 0x24, 0x72, 0x6b, 0x0b, 0x1f, 0x3f, 0x64, 0x23, 0x2d, +0x90, 0x30, 0x1f, 0x0f, 0x4f, 0xd8, 0x37, 0xbf, 0x37, 0x30, 0x3f, 0x2a, 0x61, 0x6d, 0x17, 0x56, +0xbf, 0x1f, 0xf7, 0xb0, 0x65, 0x5f, 0x6d, 0x85, 0x6c, 0xf7, 0x3f, 0xcd, 0x92, 0x2f, 0x1f, 0xcd, +0x96, 0x2f, 0x3f, 0xc1, 0x96, 0x2f, 0xdd, 0x85, 0x84, 0xff, 0x2f, 0xd9, 0x91, 0x5f, 0xff, 0xdf, +0x48, 0x18, 0x86, 0x2c, 0x59, 0xaf, 0xdf, 0x12, 0x36, 0x3f, 0x17, 0xf6, 0xef, 0x3f, 0x3f, 0x2c, +0x24, 0x4f, 0x82, 0x90, 0x2d, 0x30, 0x12, 0x5f, 0xb2, 0x91, 0xaf, 0x4f, 0x85, 0x6c, 0xff, 0x00, +0x48, 0x08, 0xaf, 0x90, 0x36, 0x24, 0x1e, 0xcf, 0x03, 0x97, 0x0f, 0x94, 0x90, 0x90, 0xaf, 0xc4, +0x8b, 0x87, 0x30, 0x98, 0xbf, 0xff, 0x91, 0xad, 0x1f, 0x38, 0x81, 0x01, 0x3c, 0x90, 0x32, 0x9f, +0x93, 0x27, 0x02, 0x38, 0x10, 0x0c, 0xca, 0x7c, 0x10, 0xcf, 0x59, 0x83, 0xcf, 0x7a, 0xb3, 0x0f, +0x3d, 0xd6, 0x32, 0xaf, 0xff, 0xcb, 0x12, 0x0f, 0x81, 0x64, 0x2f, 0x02, 0xcc, 0x80, 0x01, 0x8f, +0x26, 0xb0, 0x01, 0x09, 0xbc, 0xff, 0x02, 0x09, 0x2b, 0x9f, 0x20, 0x5d, 0x5f, 0x3e, 0x23, 0x70, +0xcc, 0x01, 0xcc, 0x81, 0x65, 0xcf, 0x01, 0x32, 0x1a, 0xce, 0xaf, 0x98, 0x30, 0x3f, 0xdc, 0xb2, +0xbf, 0x0f, 0x65, 0xd0, 0xf5, 0xcf, 0x60, 0x2e, 0x12, 0x1f, 0x23, 0xa3, 0xaf, 0x2c, 0x66, 0x3f, +0xbf, 0x05, 0xb7, 0x0f, 0x08, 0x46, 0x46, 0x2f, 0x16, 0x13, 0x7f, 0x3f, 0x32, 0x58, 0x1f, 0x2c, +0xde, 0x6f, 0x3f, 0xf4, 0x25, 0x0f, 0xfe, 0x6d, 0x64, 0x4f, 0x1f, 0xd8, 0x90, 0xfc, 0x4d, 0x23, +0xa3, 0x1f, 0xb0, 0x78, 0x5f, 0x2f, 0x33, 0x97, 0xee, 0x00, 0x06, 0x90, 0x00, 0x0e, 0xc1, 0x0b, +0x05, 0x1c, 0x61, 0x03, 0x7e, 0x07, 0x16, 0x01, 0x7e, 0x80, 0x04, 0xff, 0x93, 0x20, 0xfd, 0x95, +0x04, 0xfb, 0x4a, 0x82, 0xf9, 0x38, 0x41, 0xf7, 0x8c, 0x24, 0xf5, 0x58, 0x12, 0xf3, 0x8c, 0x24, +0xf1, 0x5d, 0x12, 0xef, 0x78, 0x24, 0x98, 0x27, 0xec, 0x4e, 0xb0, 0xeb, 0x2c, 0x09, 0xea, 0x82, +0x13, 0xe9, 0x49, 0x70, 0xe8, 0xe7, 0x98, 0x4a, 0x24, 0x82, 0x12, 0xe5, 0x04, 0x4b, 0xe4, 0x70, +0xaa, 0xe3, 0x32, 0x48, 0x49, 0xe1, 0x24, 0x24, 0xde, 0x18, 0x12, 0xdd, 0x30, 0x24, 0xdb, 0x1c, +0x49, 0xda, 0x00, 0x92, 0xa0, 0xd7, 0xac, 0x37, 0x0d, 0x01, 0x49, 0xb0, 0xd2, 0x27, 0x08, 0xd1, +0x84, 0x04, 0xcf, 0x93, 0x20, 0xcd, 0x95, 0x04, 0xcb, 0x4c, 0x82, 0xc9, 0x54, 0x12, 0xc7, 0x45, +0x82, 0xc3, 0x93, 0xc0, 0x76, 0xc1, 0x84, 0x04, 0xbe, 0x93, 0x20, 0xbd, 0x96, 0x04, 0xbc, 0xd0, +0x09, 0xbb, 0x92, 0xe0, 0x5a, 0xb9, 0x92, 0xe0, 0x76, 0x5f, 0x48, 0x90, 0xb5, 0x04, 0x2d, 0xc8, +0xb2, 0x80, 0xb3, 0x20, 0x38, 0x41, 0xb0, 0x81, 0x24, 0xae, 0x30, 0x60, 0x4b, 0xfe, 0x16, 0x48, +0xa8, 0x2b, 0x09, 0xa5, 0x60, 0x52, 0x44, 0xe0, 0x92, 0xa3, 0x7e, 0x11, 0x90, 0xa1, 0xcb, 0xe8, +0xf0, 0x5f, 0x09, 0x0e, 0xa3, 0x9d, 0x09, 0x2e, 0x1e, 0x9b, 0x78, 0x01, 0x1b, 0xb7, 0x24, 0x99, +0x0d, 0x76, 0x82, 0x97, 0xd4, 0x90, 0x60, 0x95, 0x24, 0x38, 0x7c, 0x93, 0x49, 0xb0, 0x92, 0x93, +0x20, 0x80, 0x95, 0x04, 0x8e, 0x04, 0xb1, 0xb3, 0x92, 0xc0, 0x71, 0x8b, 0x48, 0xb0, 0x88, 0x24, +0x48, 0x87, 0x09, 0x5e, 0x3c, 0x84, 0x02, 0x29, 0xd3, 0x90, 0x4a, 0x81, 0x24, 0x98, 0xfc, 0x7f, +0x21, 0xb0, 0xce, 0x70, 0x82, 0x7d, 0xb2, 0x4e, 0x7c, 0xcb, 0xb2, 0xd7, 0xaa, 0x0d, 0xe0, 0xc0, +0xd5, 0xf5, 0x92, 0x77, 0x66, 0x3a, 0x6b, 0x21, 0x25, 0xc3, 0x82, 0x09, 0x3c, 0xea, 0x40, 0x71, +0x78, 0x52, 0x4b, 0x7f, 0x7e, 0x12, 0x4c, 0xf0, 0x6c, 0x1d, 0x5a, 0x78, 0x60, 0x49, 0x7a, 0xd9, +0x92, 0x69, 0xd1, 0x26, 0xac, 0xb6, 0xfc, 0x25, 0xa4, 0x64, 0x9c, 0xe0, 0x1b, 0x62, 0x07, 0x12, +0x61, 0xe6, 0x96, 0x04, 0x5f, 0x53, 0xc3, 0x37, 0x7d, 0xc0, 0xb2, 0x99, 0x82, 0x85, 0x0a, 0x41, +0x42, 0x58, 0x33, 0x22, 0x57, 0xd7, 0x95, 0x62, 0x0d, 0x1c, 0x90, 0xe0, 0x66, 0x53, 0x6d, 0x36, +0x45, 0xf7, 0x2c, 0x81, 0x8c, 0x30, 0x1c, 0x12, 0x4f, 0x3c, 0x56, 0x12, 0x4c, 0x06, 0x09, 0x4b, +0x3c, 0x20, 0x09, 0x49, 0x90, 0x60, 0xff, 0x45, 0x48, 0x0c, 0x83, 0x20, 0xc1, 0x76, 0x41, 0x12, +0x6f, 0xb5, 0x5f, 0xc1, 0x4b, 0xc3, 0xd9, 0x25, 0x3d, 0x76, 0x1b, 0x48, 0x72, 0xfe, 0x82, 0x25, +0x39, 0x7c, 0x60, 0x40, 0x38, 0x76, 0x04, 0x31, 0x96, 0xc1, 0x80, 0x35, 0xe6, 0x70, 0x20, 0x33, +0x3c, 0x60, 0x49, 0x31, 0x90, 0x90, 0x2f, 0xc5, 0x86, 0xbf, 0x26, 0x90, 0xe0, 0x29, 0x2b, 0x61, +0x91, 0x09, 0x42, 0x6a, 0x37, 0x26, 0x6c, 0x7c, 0x1b, 0x7c, 0x96, 0x1d, 0xc1, 0x8b, 0x03, 0x09, +0x21, 0xf2, 0xb2, 0xf0, 0x37, 0x70, 0x1c, 0x93, 0x60, 0x1d, 0x96, 0x04, 0x1c, 0x09, 0x09, 0x1a, +0x6c, 0x09, 0xbf, 0x0d, 0x20, 0xc1, 0x16, 0x16, 0x2e, 0x19, 0x44, 0x2c, 0x02, 0x72, 0x24, 0x18, +0x7c, 0x11, 0xe0, 0x91, 0x83, 0xe0, 0x92, 0x0f, 0x0e, 0x90, 0x90, 0x0d, 0x1c, 0x48, 0x0b, 0x70, +0x04, 0x12, 0x09, 0xc1, 0xa4, 0x66, 0x2a, 0x21, 0x05, 0x00, 0xc1, 0xe0, 0x4a, 0x9a, 0x52, 0x7f, +0x61, 0xc0, 0xff, 0xe0, 0xbd, 0xed, 0x37, 0xd2, 0x32, 0xfc, 0x7f, 0xd0, 0x42, 0xcc, 0xac, 0x19, +0xf8, 0x97, 0x06, 0xac, 0xe5, 0x0c, 0x48, 0xf3, 0x25, 0x25, 0x71, 0x98, 0x6c, 0x61, 0xc6, 0x25, +0x0c, 0xed, 0x69, 0x25, 0xc5, 0x71, 0x01, 0x21, 0x90, 0x86, 0xe7, 0x7f, 0x72, 0x2d, 0x43, 0xb0, +0x42, 0x63, 0x28, 0x19, 0xde, 0x80, 0x43, 0xda, 0x38, 0x01, 0xc9, 0xdb, 0x03, 0x86, 0xda, 0xd8, +0x01, 0x09, 0x03, 0x86, 0xd7, 0xd4, 0x24, 0xa4, 0x00, 0x13, 0x06, 0xd2, 0xf0, 0x32, 0xe0, 0xf0, +0xb0, 0xbc, 0xd0, 0x61, 0x40, 0xce, 0x82, 0x2b, 0x5f, 0x79, 0x0c, 0x58, 0xcb, 0x80, 0xd9, 0x8b, +0xa0, 0xf9, 0xc9, 0xf6, 0xcc, 0x3a, 0x30, 0xc7, 0xce, 0x10, 0x40, 0x71, 0x8c, 0x19, 0xc3, 0xbb, +0x0c, 0xb8, 0xfc, 0xc0, 0x07, 0x0c, 0xbf, 0x65, 0xc0, 0xf0, 0x4d, 0xf4, 0x80, 0xbc, 0xb1, 0x94, +0x7f, 0xb8, 0x92, 0x0a, 0xc1, 0x1d, 0x92, 0xdb, 0x1b, 0x1c, 0x06, 0x65, 0xc0, 0xa4, 0x65, 0x87, +0xc2, 0x0d, 0x49, 0x87, 0xc2, 0x71, 0x36, 0x6c, 0x61, 0x0d, 0x60, 0x48, 0xc2, 0x63, 0x19, 0xac, +0x75, 0x25, 0x2d, 0x71, 0xb0, 0x60, 0xc6, 0x64, 0x40, 0xa3, 0x0c, 0x08, 0x9f, 0x80, 0xab, 0xf8, +0xc0, 0xca, 0x9b, 0x6f, 0x61, 0x99, 0x70, 0x0c, 0x38, 0x95, 0x06, 0xac, 0x93, 0x80, 0x41, 0xc0, +0xca, 0x8f, 0x0c, 0x78, 0x8d, 0x8b, 0x06, 0xa4, 0x89, 0x03, 0x56, 0x87, 0x80, 0x21, 0x1f, 0xb0, +0xc2, 0x83, 0x08, 0x19, 0x51, 0xac, 0x0c, 0x7d, 0x52, 0x06, 0x7b, 0x64, 0x03, 0x77, 0x1f, 0x01, +0x23, 0x0c, 0x98, 0x75, 0x73, 0x07, 0xac, 0x71, 0xc2, 0x80, 0x6f, 0x1e, 0x30, 0x6d, 0x29, 0x03, +0x6b, 0x96, 0x01, 0x69, 0x23, 0x03, 0x67, 0x95, 0x01, 0x65, 0x06, 0xb8, 0x1b, 0x61, 0xc0, 0x15, +0x3f, 0x1b, 0x61, 0x5d, 0xd1, 0x61, 0xc0, 0x59, 0x06, 0x4c, 0xff, 0x55, 0xc0, 0x15, 0xf8, 0x08, +0x60, 0x51, 0x29, 0x0c, 0x4d, 0xa4, 0x03, 0x4f, 0x55, 0x81, 0xb6, 0x0d, 0xc1, 0x96, 0x85, 0x79, +0x2c, 0x03, 0x47, 0x46, 0x18, 0x1f, 0xd6, 0xc2, 0x1b, 0x61, 0x24, 0x30, 0x3c, 0xcb, 0x19, 0x30, +0xfc, 0x3d, 0xc0, 0x6b, 0x61, 0x60, 0x84, 0xf5, 0xc0, 0x30, 0x38, 0x2b, 0x61, 0x36, 0x5f, 0x92, +0x2d, 0x0d, 0x58, 0xc9, 0x29, 0x61, 0x40, 0xb2, 0x7d, 0x30, 0x61, 0x2e, 0xf0, 0x1c, 0x18, 0x2c, +0xfc, 0xb3, 0x06, 0x2a, 0x89, 0xae, 0x59, 0x62, 0x61, 0xc0, 0x80, 0xcc, 0x27, 0x42, 0xe8, 0xce, +0x59, 0xac, 0xc3, 0x17, 0x27, 0xa0, 0xbd, 0x30, 0x1c, 0xd6, 0x5c, 0x48, 0xf5, 0x10, 0x08, 0xcd, +0x1b, 0x59, 0xc4, 0x5b, 0x37, 0xd6, 0x96, 0xa7, 0x0d, 0xe6, 0x0b, 0x8b, 0xe9, 0x89, 0x09, 0x4f, +0x37, 0x85, 0xc5, 0xe9, 0x49, 0xbc, 0x37, 0x37, 0xd1, 0x6e, 0x0d, 0xfe, 0x00, 0x2c, 0x64, 0xc0, +0x1b, 0x8b, 0x17, 0x43, 0xdb, 0x78, 0x0b, 0x53, 0xc0, 0x92, 0x29, 0x80, 0x61, 0x09, 0xe4, 0xc8, +0x05, 0x08, 0x0e, 0xb0, 0xfc, 0xc0, 0x01, 0xfb, 0x06, 0x30, 0xf6, 0xf5, 0x4c, 0x80, 0x6c, 0xee, +0x0b, 0x02, 0xe9, 0x06, 0xe6, 0x60, 0x38, 0x83, 0x0d, 0x1c, 0xbe, 0x0f, 0xfe, 0xb7, 0x60, 0x02, +0xd7, 0x40, 0x10, 0xd1, 0x80, 0x20, 0xcb, 0xf0, 0x41, 0xc5, 0x0f, 0x07, 0x0f, 0x7d, 0x01, 0x0c, +0xbf, 0xba, 0x03, 0x04, 0xb4, 0x50, 0x80, 0xb3, 0xc0, 0x0f, 0xae, 0x67, 0xe6, 0xc0, 0x06, 0x30, +0xa7, 0xa8, 0x75, 0x80, 0x80, 0xa1, 0x03, 0x2c, 0xef, 0x02, 0x9b, 0x38, 0xc0, 0x02, 0x42, 0x00, +0x06, 0x33, 0x06, 0x98, 0x8f, 0x8a, 0xdd, 0x00, 0x89, 0x00, 0x3e, 0x61, 0xde, 0xdb, 0x49, 0x3c, +0x86, 0xfd, 0xd0, 0xc0, 0xf7, 0x27, 0x26, 0xff, 0x9d, 0x26, 0x72, 0x35, 0x12, 0xe0, 0x0f, 0x65, +0x38, 0x40, 0x5f, 0xb8, 0x04, 0x59, 0x24, 0x03, 0x14, 0xed, 0x12, 0xf0, 0x80, 0x9f, 0xf0, 0x1e, +0x72, 0x2e, 0x1b, 0x08, 0x3d, 0x46, 0xf0, 0xda, 0x72, 0x25, 0xa3, 0x09, 0x31, 0x57, 0x94, 0xf8, +0x18, 0x3e, 0x60, 0xc0, 0x68, 0x28, 0x90, 0x9c, 0xcc, 0x80, 0x07, 0x23, 0x38, 0xb2, 0x7a, 0x1e, +0x76, 0xcc, 0x8b, 0x55, 0x3e, 0x74, 0x22, 0x40, 0x0d, 0x09, 0xf0, 0x13, 0x06, 0x4b, 0x80, 0x00, +0x84, 0x61, 0x2b, 0x83, 0x2b, 0xb7, 0x18, 0xe8, 0x74, 0x0c, 0xf7, 0xd6, 0xb9, 0x72, 0xfe, 0xdd, +0x3e, 0x88, 0xc2, 0xfd, 0x1c, 0x02, 0x1d, 0xbb, 0x2e, 0xb3, 0x0a, 0xca, 0xef, 0xab, 0x1e, 0xc5, +0xfc, 0x0f, 0x47, 0x57, 0xbf, 0xfc, 0x05, 0x62, 0x85, 0xf3, 0x79, 0xef, 0x3d, 0x4f, 0x02, 0x07, +0x17, 0xab, 0x7e, 0xab, 0x74, 0x37, 0xab, 0x62, 0x77, 0x5e, 0xbd, 0x67, 0x81, 0x95, 0xac, 0x94, +0xbe, 0x7a, 0x8f, 0x8d, 0x7c, 0xdc, 0xac, 0x88, 0x07, 0xde, 0x26, 0x86, 0xc0, 0x78, 0x87, 0x02, +0xbd, 0x01, 0xf6, 0x43, 0x1b, 0xc3, 0x38, 0x57, 0x06, 0xd0, 0x6b, 0xe3, 0xab, 0x69, 0xfe, 0xee, +0x34, 0x1b, 0xfe, 0x07, 0xab, 0xcf, 0xef, 0x1f, 0xce, 0x57, 0x20, 0x90, 0x76, 0xdb, 0x8c, 0xf3, +0x2f, 0x1e, 0x0d, 0x56, 0x45, 0xe6, 0x35, 0x18, 0x7f, 0xf0, 0x2c, 0x66, 0x39, 0xc3, 0x7a, 0x35, +0x2f, 0x02, 0xbd, 0x2e, 0x9e, 0xc4, 0x1b, 0x6f, 0xe4, 0xef, 0x97, 0x0f, 0xce, 0x7c, 0x0e, 0xd7, +0x5e, 0x37, 0x5f, 0xa8, 0xb0, 0x3a, 0x7f, 0x7e, 0x45, 0x1a, 0x46, 0xfd, 0x15, 0x84, 0x56, 0xde, +0x20, 0xf8, 0x00, 0x0c, 0x1e, 0x2f, 0x9b, 0x67, 0xf7, 0xf4, 0x27, 0x0b, 0x32, 0x6f, 0x82, 0x54, +0x3c, 0xdf, 0xd4, 0x01, 0x97, 0x4e, 0xca, 0xd9, 0xd5, 0x3c, 0x18, 0xb8, 0xea, 0x61, 0x71, 0x48, +0xba, 0x86, 0x65, 0x4a, 0xd7, 0x1a, 0x8b, 0xe0, 0x8a, 0xdc, 0x3a, 0xcc, 0xcc, 0x7f, 0x34, 0x24, +0x26, 0x62, 0xf7, 0xe0, 0x7c, 0x97, 0x60, 0xf8, 0xa6, 0xce, 0x47, 0x76, 0x09, 0x4e, 0xb9, 0xf8, +0x2f, 0x92, 0xef, 0xd4, 0xaf, 0xe4, 0x7f, 0xa7, 0x0a, 0x69, 0x84, 0x3d, 0xb8, 0x3c, 0x17, 0x00, +0xe6, 0x5a, 0x46, 0xd6, 0x02, 0x91, 0x74, 0x32, 0x0c, 0x18, 0x6d, 0x36, 0x16, 0x0f, 0x7c, 0x4f, +0x48, 0x4d, 0x1e, 0x56, 0xb5, 0xb3, 0x5f, 0x7e, 0x6d, 0x9d, 0x72, 0xa3, 0x4a, 0xa9, 0x49, 0x49, +0x43, 0x46, 0x0d, 0x56, 0x90, 0x0a, 0x37, 0x2c, 0xc2, 0x00, 0x17, 0x9c, 0x40, 0x5d, 0x7e, 0x4f, +0x35, 0xdf, 0x7e, 0x21, 0x70, 0xa9, 0x53, 0x1f, 0x19, 0xee, 0x0d, 0x0c, 0x12, 0xa9, 0x53, 0x11, +0x07, 0xa9, 0x09, 0x3e, 0x02, 0xc0, 0x35, 0xcf, 0x21, 0x4c, 0x21, 0xff, 0x1e, 0xb9, 0x0f, 0x39, +0x34, 0x3d, 0x7f, 0x0a, 0xc6, 0x81, 0x24, 0xff, 0xb5, 0x71, 0xa8, 0x38, 0x1d, 0x8c, 0x86, 0x9f, +0xc4, 0x30, 0x3b, 0x7c, 0x07, 0x8c, 0x92, 0xf7, 0xc1, 0x2d, 0xe1, 0xc6, 0xf7, 0x4b, 0x88, 0x66, +0xf7, 0xc1, 0x78, 0x0c, 0x6f, 0x2b, 0x62, 0xff, 0x7e, 0x58, 0x31, 0x76, 0xb0, 0x62, 0x6b, 0xcc, +0x60, 0x7c, 0x27, 0xac, 0x24, 0xe7, 0xf6, 0x51, 0x61, 0xfe, 0x65, 0x8c, 0x86, 0x77, 0x71, 0x60, +0x30, 0x0a, 0xc5, 0xa3, 0x67, 0xac, 0x78, 0x36, 0x2e, 0x59, 0x11, 0x26, 0xc3, 0x8a, 0x1e, 0x98, +0x15, 0x16, 0xb0, 0xac, 0x0e, 0x54, 0x9a, 0xf7, 0xe3, 0x33, 0x9a, 0x57, 0x36, 0x1c, 0x0e, 0x47, +0x01, 0x88, 0x3d, 0x87, 0x3c, 0xff, 0xe1, 0x4d, 0xff, 0x1f, 0x00, 0x66, 0x14, 0x18, 0x9a, 0xc5, +0x2f, 0xf8, 0x51, 0x30, 0x0c, 0xfa, 0x82, 0x06, 0x07, 0x3e, 0x41, 0x10, 0xff, 0x10, 0x3a, 0x2f, +0xf4, 0x58, 0xc2, 0xf7, 0x66, 0x4f, 0x01, 0x22, 0x88, 0x01, 0x34, 0x84, 0xd9, 0xa1, 0x21, 0xd4, +0xca, 0x42, 0x2b, 0x9a, 0x43, 0x68, 0xbe, 0x1a, 0x42, 0xb8, 0xd0, 0x10, 0xb2, 0xa1, 0x91, 0xac, +0xa0, 0x09, 0x2d, 0x9a, 0x0d, 0xa1, 0x94, 0x1d, 0x08, 0x8e, 0xf8, 0x0a, 0x08, 0x82, 0x3a, 0x10, +0x7c, 0xff, 0x16, 0x10, 0x70, 0x0f, 0x34, 0x2c, 0x1f, 0x28, 0x20, 0x5e, 0x09, 0x79, 0x52, 0x37, +0x68, 0x42, 0x4c, 0x43, 0x4b, 0x46, 0x40, 0x2d, 0xa1, 0x3a, 0x68, 0x08, 0x34, 0x42, 0x43, 0x2e, +0x28, 0x12, 0x1a, 0x22, 0xc3, 0xdc, 0x0f, 0x6f, 0x02, 0x42, 0x10, 0xb6, 0x84, 0x0a, 0x77, 0xc0, +0x62, 0xfe, 0x2c, 0xde, 0x27, 0xf2, 0x87, 0x0d, 0xd7, 0x1f, 0x02, 0x16, 0xe3, 0x4c, 0xb3, 0xd6, +0x07, 0x17, 0x11, 0xe5, 0xd1, 0x4a, 0xaf, 0xb8, 0x9f, 0x69, 0x24, 0x89, 0xc0, 0x7f, 0x36, 0x19, +0xfc, 0x0f, 0xf4, 0x48, 0x81, 0x33, 0xe0, 0xaf, 0x79, 0x8d, 0x17, 0xaa, 0x80, 0x08, 0x48, 0x67, +0x9b, 0xcd, 0x7f, 0x1f, 0x07, 0x86, 0xc5, 0x91, 0x68, 0x33, 0x7f, 0x00, 0x71, 0xf6, 0x80, 0x3f, +0xf6, 0xce, 0xc2, 0x7f, 0x7a, 0xfc, 0x17, 0x2c, 0x74, 0x07, 0x16, 0x8d, 0x81, 0x6d, 0x78, 0x71, +0x7e, 0x67, 0x39, 0xd8, 0x52, 0xf8, 0x9f, 0x14, 0xc3, 0x9f, 0x5d, 0x19, 0xec, 0xa2, 0x11, 0x18, +0xb0, 0x38, 0x3c, 0x39, 0x8b, 0x57, 0x5e, 0x41, 0x5b, 0x3c, 0x7e, 0xc2, 0x2f, 0x86, 0x06, 0xae, +0xfc, 0x11, 0x98, 0xc9, 0x22, 0x2f, 0x0b, 0x16, 0x29, 0x88, 0x86, 0x40, 0x57, 0xbf, 0xcd, 0x11, +0x2f, 0xfe, 0x86, 0x1c, 0x70, 0xc2, 0x66, 0x99, 0xfe, 0x17, 0xd2, 0x35, 0xce, 0x00, 0x00, 0x83, +0x18, 0x33, 0x03, 0x72, 0x81, 0x4c, 0x04, 0x90, 0x27, 0x69, 0x26, 0x32, 0x82, 0x14, 0x11, 0x0a, +0x06, 0x41, 0x48, 0xc3, 0x48, 0x49, 0xb3, 0x2c, 0x23, 0x83, 0x95, 0x11, 0x93, 0x32, 0x88, 0x33, +0x15, 0xa1, 0x23, 0x98, 0xa5, 0xb3, 0xc4, 0x0a, 0x11, 0x19, 0x33, 0xa4, 0x20, 0x13, 0x14, 0x8c, +0x88, 0x85, 0x03, 0x28, 0x32, 0x33, 0x49, 0x41, 0x63, 0x81, 0x48, 0x63, 0x10, 0x09, 0x48, 0x20, +0x53, 0x24, 0x2b, 0x43, 0x95, 0x15, 0x33, 0xb0, 0x82, 0x23, 0x56, 0x30, 0x13, 0x0a, 0x56, 0x41, +0xc2, 0x03, 0x58, 0x48, 0xf3, 0x21, 0x29, 0xe3, 0x61, 0x10, 0x33, 0xf9, 0x56, 0x00, 0xff, 0x48, +0x0e, 0xf0, 0x85, 0x64, 0x0f, 0x88, 0x84, 0x36, 0x00, 0x30, 0x33, 0x90, 0x06, 0x6c, 0x7f, 0x88, +0xb0, 0x91, 0x96, 0x6c, 0xff, 0xc6, 0xfc, 0x4d, 0x08, 0xe9, 0x1a, 0x02, 0xe7, 0x37, 0x21, 0xa2, +0x0f, 0x90, 0xa2, 0x4b, 0xad, 0xbd, 0x24, 0x48, 0x01, 0x05, 0x25, 0x05, 0xc1, 0x90, 0x2e, 0x2a, +0x18, 0x4a, 0x11, 0xac, 0x24, 0x29, 0xaf, 0xe8, 0x14, 0x99, 0x2b, 0x8c, 0xe0, 0xb0, 0x61, 0x42, +0x00, 0xdb, 0xf3, 0x0f, 0x0c, 0xec, 0x34, 0x3c, 0x46, 0xb0, 0x1c, 0x76, 0xf8, 0x23, 0x58, 0x1b, +0xd8, 0x36, 0xa0, 0x32, 0x9b, 0x30, 0x88, 0x33, 0x08, 0x80, 0x18, 0xb0, 0x9b, 0x2b, 0x08, 0x03, +0x05, 0x29, 0x20, 0x20, 0x15, 0x24, 0xa4, 0x07, 0x91, 0x41, 0x33, 0x0c, 0x08, 0x8b, 0x49, 0xc1, +0x23, 0x83, 0x58, 0x33, 0x04, 0x20, 0x85, 0x14, 0x77, 0x90, 0x82, 0x69, 0x06, 0x31, 0x33, 0x48, +0x15, 0x21, 0x29, 0xbd, 0x20, 0x10, 0x7d, 0x04, 0x22, 0x6f, 0x15, 0xac, 0x0a, 0x86, 0x81, 0xc1, +0xc8, 0x73, 0x60, 0x59, 0x65, 0x8c, 0xac, 0x57, 0x80, 0x15, 0x49, 0xb2, 0x82, 0x3b, 0x59, 0xc1, +0x2d, 0x83, 0x08, 0x33, 0x30, 0x08, 0x60, 0x19, 0x4d, 0x05, 0x32, 0x49, 0x31, 0x99, 0x30, 0x45, +0x06, 0x33, 0x10, 0x57, 0x6c, 0x79, 0x61, 0x17, 0x00, 0x6c, 0x06, 0x24, 0x20, 0x03, 0x42, 0x1e, +0x03, 0xce, 0x1b, 0x40, 0x2a, 0x03, 0x66, 0x19, 0x17, 0x01, 0x2b, 0x30, 0xe0, 0x15, 0x12, 0x03, +0xae, 0x18, 0x0f, 0xc0, 0x21, 0x3c, 0x1c, 0x60, 0x65, 0x0d, 0xc2, 0x3c, 0x0b, 0x2a, 0x0c, 0x33, +0x10, 0x08, 0x60, 0x56, 0xfb, 0x30, 0xac, 0xf3, 0x60, 0x56, 0x59, 0x31, 0xac, 0x63, 0x50, 0x06, +0x33, 0x10, 0xa1, 0x94, 0x58, 0x56, 0x73, 0x22, 0x83, 0x33, 0x26, 0x14, 0x4d, 0xc9, 0x0a, 0x9b, +0x64, 0x10, 0x33, 0x0a, 0x42, 0x10, 0xc1, 0xcb, 0x88, 0x20, 0xcb, 0xc4, 0x10, 0xc3, 0x6c, 0x08, +0x3b, 0x09, 0x02, 0x11, 0x2b, 0x04, 0x62, 0x23, 0x02, 0x11, 0x1b, 0x81, 0x08, 0x13, 0x40, 0x04, +0x20, 0x82, 0x0b, 0x11, 0xc2, 0x33, 0x8b, 0x61, 0xda, 0xd1, 0x61, 0x23, 0x1b, 0x32, 0x88, 0x33, +0x45, 0xa8, 0x50, 0xdc, 0x64, 0x62, 0x78, 0x60, 0x62, 0xb6, 0x8b, 0x6c, 0xef, 0x62, 0xf1, 0x57, +0x55, 0x64, 0xe1, 0x05, 0x4f, 0x16, 0xef, 0xcc, 0x66, 0x01, 0x3e, 0x2c, 0x42, 0x38, 0x78, 0x11, +0x33, 0x17, 0xb2, 0x2c, 0x06, 0x86, 0xc5, 0x0f, 0x1f, 0x51, 0x2c, 0x1b, 0x17, 0xee, 0x88, 0x50, +0xb9, 0x32, 0x88, 0x33, 0x80, 0x3c, 0xb5, 0x72, 0xe0, 0xc9, 0x28, 0x9d, 0x4c, 0x22, 0xab, 0x67, +0x24, 0x29, 0x41, 0x15, 0x0c, 0x62, 0x33, 0xa1, 0x22, 0xbc, 0x05, 0xbf, 0xc8, 0xf8, 0xc8, 0x85, +0x45, 0x43, 0x56, 0x88, 0x9c, 0x0f, 0x44, 0x71, 0x66, 0x82, 0x91, 0x17, 0x88, 0x58, 0xf2, 0x38, +0xc9, 0xc3, 0x97, 0xc6, 0x7c, 0x0d, 0x1b, 0x12, 0xe2, 0x50, 0x3b, 0xaa, 0x0c, 0x33, 0x15, 0xff, +0xcf, 0xcd, 0xef, 0xec, 0xff, 0xdc, 0x8b, 0x0c, 0xc8, 0x27, 0xd1, 0x05, 0x9c, 0xf0, 0x0a, 0x1c, +0x4c, 0x80, 0xb0, 0x67, 0xb2, 0x08, 0x00, 0x01, 0x0c, 0x62, 0x33, 0x01, 0x0a, 0x98, 0x01, 0x21, +0x4b, 0x80, 0x55, 0x34, 0x01, 0xbb, 0x7e, 0x07, 0x06, 0x1d, 0x3c, 0x81, 0x01, 0x1b, 0xc0, 0xb9, +0x0d, 0x2d, 0x96, 0x30, 0x18, 0x10, 0x3c, 0x60, 0x15, 0x91, 0x41, 0x33, 0x0c, 0x58, 0x0d, 0x19, +0x30, 0x0b, 0x34, 0x60, 0x0a, 0x61, 0x15, 0x67, 0x40, 0x50, 0x28, 0x90, 0x41, 0x84, 0x51, 0x84, +0x33, 0xc9, 0xa0, 0x66, 0xc5, 0x17, 0x50, 0x7e, 0x17, 0x83, 0x4c, 0x3c, 0x55, 0xd1, 0x5e, 0x38, +0x07, 0x19, 0xe7, 0x66, 0x2d, 0x21, 0x08, 0x19, 0xc4, 0x7c, 0x33, 0x16, 0x47, 0x8f, 0x1b, 0xd8, +0xc5, 0xfc, 0x19, 0x7c, 0xc2, 0x10, 0xbf, 0x13, 0xc2, 0x7c, 0x3c, 0x65, 0x33, 0xe9, 0x74, 0x50, +0x27, 0x97, 0x57, 0xd1, 0x22, 0x92, 0x72, 0x50, 0x92, 0x5f, 0x50, 0x60, 0x60, 0xf8, 0x18, 0x41, +0x0f, 0x5d, 0xf0, 0xe6, 0x06, 0x06, 0x77, 0xfc, 0xac, 0xa0, 0x60, 0xf6, 0x83, 0xea, 0xec, 0xf9, +0x44, 0x05, 0xa2, 0x78, 0xae, 0xea, 0x45, 0x9c, 0x0c, 0x2c, 0x23, 0x9b, 0x25, 0x10, 0x97, 0x81, +0x20, 0xb7, 0x01, 0x2b, 0x60, 0x20, 0x63, 0x25, 0x27, 0x83, 0x89, 0x20, 0x97, 0x02, 0xd5, 0xfb, +0xa2, 0x56, 0xb0, 0xb2, 0xab, 0x41, 0x12, 0xa3, 0x93, 0x80, 0xc3, 0x59, 0x51, 0xdb, 0xa8, 0x02, +0x17, 0x32, 0xeb, 0xf2, 0xd8, 0xf6, 0x58, 0x5c, 0x5a, 0x00, 0xdc, 0x0c, 0xb2, 0x77, 0x58, 0x0e, +0x0f, 0xe5, 0x5d, 0x00, 0xd8, 0xd8, 0xfc, 0xda, 0xde, 0xb0, 0xdc, 0x0c, 0x0e, 0x09, 0xcb, 0x0f, +0x3e, 0x8c, 0xa0, 0x7c, 0xec, 0x90, 0x3f, 0x0f, 0xea, 0xb0, 0x3f, 0x2d, 0x21, 0x5b, 0x29, 0xea, +0x0c, 0x6b, 0x05, 0x2c, 0x80, 0x91, 0x43, 0xb7, 0xb2, 0x63, 0x00, 0xd9, 0x67, 0xee, 0x6c, 0xfe, +0x10, 0x0c, 0xd4, 0x6c, 0x0f, 0x56, 0x02, 0x7b, 0x32, 0xa2, 0x8b, 0x00, 0x95, 0xa8, 0x84, 0xdb, +0x92, 0x8d, 0xeb, 0xf0, 0x46, 0xd4, 0x9b, 0xa2, 0x56, 0x15, 0xb2, 0xab, 0x90, 0x11, 0xab, 0x44, +0x8d, 0x0c, 0x6a, 0x09, 0xb8, 0x2b, 0x03, 0x7b, 0x49, 0x51, 0x8b, 0x88, 0x0a, 0x54, 0xc8, 0xbb, +0x42, 0x56, 0xcb, 0x32, 0xa2, 0xcb, 0x94, 0x11, 0x3f, 0x0c, 0xa8, 0xfb, 0x45, 0x2d, 0x2a, 0x64, +0x0b, 0x21, 0x29, 0x2b, 0x4a, 0x19, 0x9f, 0xfd, 0xab, 0x05, 0x6c, 0xd8, 0x6c, 0x36, 0xb9, 0x80, +0x0f, 0x0d, 0x23, 0xaa, 0x11, 0x9b, 0xad, 0x02, 0x25, 0x41, 0x9b, 0x2b, 0x6a, 0xab, 0x51, 0x21, +0x1a, 0x49, 0x8b, 0x4b, 0xa0, 0x8b, 0x59, 0x05, 0x67, 0xa8, 0x55, 0xb5, 0xa4, 0xdb, 0x95, 0x40, +0xeb, 0xac, 0x82, 0x67, 0xb5, 0x8a, 0x90, 0x15, 0x5b, 0xb0, 0x8c, 0xff, 0x91, 0x55, 0x67, 0x10, +0x56, 0x21, 0x21, 0x46, 0xce, 0x0f, 0x66, 0x2c, 0x92, 0x32, 0xa8, 0xfb, 0x15, 0xb5, 0xaa, 0x95, +0xfb, 0x8d, 0x24, 0x0b, 0x24, 0x50, 0x0b, 0x8b, 0x28, 0x2f, 0x40, 0x35, 0x6a, 0x84, 0x1b, 0x35, +0x89, 0x2b, 0x95, 0x40, 0x2b, 0xac, 0x82, 0x67, 0xd5, 0xaa, 0x56, 0x12, 0x7b, 0x93, 0x82, 0x63, +0xa7, 0xa0, 0x3c, 0x64, 0x93, 0x60, 0x36, 0x18, 0x54, 0xab, 0xa2, 0x46, 0xd5, 0x32, 0xab, 0x52, +0x12, 0xbb, 0x3c, 0xa2, 0xbb, 0x89, 0xea, 0xcb, 0x51, 0x2b, 0x5a, 0x19, 0xcb, 0x75, 0xa2, 0xdb, +0x85, 0x11, 0xdb, 0x2b, 0x6b, 0xef, 0x19, 0x54, 0xcb, 0x8b, 0x6a, 0xdb, 0x54, 0x2b, 0xaa, 0x49, +0x2b, 0x23, 0x84, 0x3b, 0x19, 0x51, 0xab, 0xa2, 0x0a, 0x44, 0x48, 0xbb, 0x0a, 0x09, 0x63, 0x4a, +0x82, 0x20, 0x06, 0xd0, 0xcc, 0x8b, 0x6a, 0x0b, 0x54, 0x2b, 0x5a, 0x49, 0x5b, 0x4d, 0xa8, 0x6b, +0xaa, 0x85, 0xbf, 0x01, 0x2c, 0x6b, 0xa4, 0xa8, 0xfe, 0x3b, 0x51, 0xad, 0x6a, 0x65, 0x4b, 0x21, +0x29, 0x9b, 0xea, 0x65, 0x3f, 0x07, 0x07, 0x2b, 0x29, 0xdb, 0x58, 0x54, 0xeb, 0x02, 0x58, 0x38, +0x13, 0x1b, 0x28, 0x83, 0x33, 0x04, 0x22, 0x48, 0x12, 0x04, 0x04, 0x27, 0x03, 0x09, 0x96, 0x02, +0x01, 0x03, 0x26, 0xf0, 0xff, 0x82, 0x03, 0xf0, 0x8c, 0x0c, 0x71, 0x64, 0x10, 0x8d, 0x2c, 0x60, +0x3d, 0x16, 0xb0, 0x59, 0x51, 0x67, 0x48, 0x49, 0xc1, 0x4b, 0x28, 0x81, 0x59, 0x51, 0x69, 0x0b, +0x18, 0x75, 0xc0, 0x08, 0xa2, 0x66, 0xeb, 0x85, 0xb0, 0x93, 0x65, 0x50, 0x61, 0xcb, 0x80, 0xe5, +0xc0, 0x80, 0xdc, 0xe3, 0x30, 0xe0, 0xdc, 0xe1, 0x0c, 0x38, 0xdc, 0xdf, 0x12, 0x0e, 0xdc, 0x17, +0x03, 0xce, 0xdb, 0x80, 0x03, 0xe6, 0x53, 0xcb, 0xd9, 0xc8, 0xc3, 0x80, 0xd7, 0x82, 0x53, 0xd6, +0x10, 0x12, 0x01, 0x46, 0x42, 0x1d, 0x30, 0x03, 0xc4, 0xbd, 0x19, 0xc0, 0x0a, 0x80, 0x9a, 0x0d, +0x54, 0xca, 0x1f, 0x5a, 0x46, 0x8d, 0xc8, 0x80, 0x73, 0x46, 0xd4, 0xe1, 0x88, 0x5a, 0xc0, 0xc8, +0x9b, 0x94, 0x79, 0xc3, 0x57, 0x46, 0xa9, 0xfe, 0x90, 0x01, 0xbe, 0xa4, 0xa8, 0x5f, 0x9a, 0x85, +0x0d, 0xc8, 0x88, 0xb7, 0x56, 0xd4, 0x85, 0x88, 0x5a, 0xc2, 0xc8, 0xc5, 0xf7, 0xa0, 0x42, 0x35, +0x90, 0x6f, 0x96, 0x14, 0xdd, 0x92, 0xa2, 0x19, 0x90, 0x31, 0x4b, 0xc8, 0x80, 0xa8, 0x7a, 0xc0, +0xa6, 0xc0, 0x88, 0x9b, 0x50, 0x21, 0x1a, 0x49, 0xfb, 0xcb, 0x8a, 0x69, 0x49, 0x51, 0x6d, 0x0c, +0x48, 0x35, 0x55, 0x10, 0x1a, 0x94, 0x67, 0x4b, 0x8a, 0xb3, 0x89, 0x01, 0x89, 0x55, 0x10, 0x16, +0x90, 0x67, 0xb0, 0xa2, 0x23, 0x96, 0x91, 0x9f, 0xb0, 0x0a, 0x67, 0xd8, 0xaa, 0xfd, 0x30, 0x20, +0x66, 0xea, 0x31, 0x40, 0x2b, 0x83, 0x6f, 0x59, 0x51, 0xaf, 0x0e, 0x08, 0x5f, 0x8a, 0x3a, 0xc0, +0xca, 0xbd, 0xa2, 0x66, 0x5b, 0x0c, 0xb0, 0xcb, 0xa8, 0x07, 0x57, 0xac, 0xac, 0xd9, 0x64, 0x15, +0x67, 0x03, 0x42, 0x4b, 0x51, 0x03, 0x0b, 0x09, 0xad, 0x30, 0x66, 0x0b, 0x18, 0xb0, 0x03, 0x63, +0xcc, 0xce, 0x95, 0x55, 0x75, 0xc1, 0x80, 0x41, 0x84, 0xaa, 0xf0, 0x9b, 0x06, 0xac, 0x3d, 0x11, +0x35, 0xc2, 0xaa, 0x95, 0xc5, 0x85, 0x24, 0x33, 0x2f, 0x59, 0xf7, 0x2b, 0x5a, 0x59, 0x51, 0xcb, +0xa0, 0x45, 0x59, 0x54, 0x13, 0x83, 0x6a, 0x99, 0x72, 0x23, 0x8b, 0x44, 0x4d, 0xfd, 0x6a, 0x65, +0xa9, 0x2c, 0x89, 0x17, 0x91, 0x40, 0x7d, 0xc8, 0x80, 0x24, 0x65, 0xc0, 0x22, 0xc8, 0x80, 0x20, +0x06, 0xd5, 0xc3, 0x0c, 0x58, 0x1d, 0x6a, 0xd9, 0xa7, 0x2b, 0x89, 0xb1, 0xa4, 0xa8, 0xfe, 0x27, +0x51, 0xad, 0xa8, 0x25, 0x95, 0x8d, 0xa4, 0x7b, 0x51, 0xe7, 0x37, 0x58, 0x49, 0xb3, 0x90, 0x0c, +0x0d, 0x26, 0x01, 0x4b, 0x41, 0x4c, 0x10, 0x80, 0x33, 0x05, 0x02, 0x9f, 0xd0, 0x58, 0xfe, 0x0c, +0xa1, 0xcf, 0xe5, 0x07, 0x6c, 0xd3, 0xf6, 0xa2, 0x7e, 0x9c, 0x07, 0x5e, 0x8b, 0xe7, 0x00, 0xb0, +0x08, 0xff, 0x0a, 0x5a, 0x06, 0x04, 0x31, 0xcf, 0xa8, 0x60, 0xcb, 0x51, 0x4b, 0xde, 0xa8, 0x48, +0x43, 0x45, 0x4d, 0xce, 0xa3, 0x21, 0xa3, 0xa5, 0x19, 0xc1, 0xeb, 0x8c, 0x60, 0xfb, 0xa3, 0x36, +0x69, 0xa0, 0xa8, 0x96, 0x9e, 0x34, 0xac, 0xc3, 0x16, 0x7f, 0x97, 0x5e, 0x5b, 0xde, 0x15, 0x9a, +0xd1, 0x58, 0xa9, 0xb9, 0x3f, 0x8b, 0xfe, 0xdb, 0xde, 0x05, 0xb0, 0x19, 0x9d, 0xa0, 0xc6, 0x5a, +0x1f, 0x9f, 0x66, 0x11, 0x65, 0xfc, 0xed, 0xfc, 0x07, 0xc6, 0xcc, 0xf8, 0xf8, 0xcc, 0xc6, 0x82, +0x14, 0x3b, 0x41, 0x0a, 0x4b, 0x0d, 0x12, 0x2e, 0x38, 0xd4, 0x8b, 0x06, 0x07, 0x6a, 0x16, 0x0b, +0xd4, 0x12, 0x2e, 0xa3, 0x17, 0x3b, 0x49, 0xf5, 0x91, 0x48, 0x3c, 0x86, 0x11, 0x9b, 0x90, 0xa2, +0xa3, 0x46, 0x54, 0xa3, 0x29, 0x6a, 0xab, 0xa2, 0x0e, 0x00, 0x7b, 0x91, 0x0b, 0x05, 0x07, 0x46, +0xd4, 0xab, 0x8a, 0x1a, 0x11, 0x75, 0xb3, 0xa2, 0x96, 0xb3, 0x50, 0x93, 0xbb, 0x6a, 0x58, 0xcb, +0x35, 0x29, 0x53, 0x86, 0x11, 0xe3, 0x27, 0xf1, 0x05, 0x0d, 0x33, 0x1b, 0x05, 0x33, 0x33, 0xca, +0x7d, 0x97, 0x66, 0x09, 0x02, 0x23, 0x9b, 0x10, 0x15, 0xa2, 0x86, 0x1b, 0x42, 0x93, 0xa3, 0xb8, +0x24, 0x1a, 0xf6, 0x55, 0x10, 0x28, 0x94, 0x67, 0xb3, 0x49, 0x94, 0x7c, 0x06, 0x59, 0x05, 0x67, +0xa8, 0x10, 0x34, 0xa4, 0x7b, 0x82, 0x49, 0xde, 0x88, 0xac, 0x67, 0x84, 0x5e, 0x91, 0x27, 0x53, +0xd4, 0xc3, 0xac, 0xa8, 0xcb, 0x14, 0x95, 0x10, 0x9a, 0xcb, 0x11, 0x86, 0xd0, 0x0a, 0x2d, 0x89, +0x6e, 0xa2, 0x08, 0x60, 0x16, 0x4b, 0x5e, 0xaf, 0xab, 0x20, 0x67, 0x51, 0x28, 0xa8, 0x25, 0x6e, +0x61, 0x8f, 0x13, 0x1b, 0xac, 0xa8, 0xa3, 0x11, 0xb5, 0xf5, 0xe2, 0xa3, 0x2b, 0x81, 0x11, 0xab, +0xf5, 0xa0, 0xf6, 0x96, 0x11, 0xb3, 0x11, 0xf5, 0x05, 0x8b, 0x80, 0xbb, 0x9d, 0x45, 0x2d, 0xa8, +0x62, 0xb3, 0x66, 0x13, 0xbb, 0x4f, 0x12, 0xa8, 0xeb, 0x46, 0xd4, 0xa3, 0xb3, 0x08, 0x6f, 0x10, +0x88, 0x7c, 0xcb, 0xf2, 0x45, 0x5c, 0x7e, 0x06, 0x5d, 0xf6, 0x86, 0x8a, 0x5a, 0x19, 0xf4, 0xfb, +0x76, 0xcc, 0x62, 0x35, 0x6a, 0x59, 0x3d, 0x1d, 0x23, 0xeb, 0xf8, 0x0c, 0x8b, 0xd7, 0x06, 0x0c, +0xfa, 0x1c, 0x61, 0x11, 0x32, 0x55, 0xb0, 0x9f, 0x1a, 0x02, 0xc3, 0x49, 0xa8, 0xdb, 0x59, 0x05, +0x67, 0x40, 0x0e, 0x1d, 0xbf, 0xf2, 0x64, 0x62, 0x05, 0x99, 0x52, 0x44, 0x0a, 0x4a, 0x21, 0x0b, +0x50, 0x45, 0x00, 0x90, 0x14, 0xa1, 0xc1, 0x39, 0x13, 0x50, 0x56, 0x67, 0x09, 0x44, 0x00, 0x08, +0x94, 0x84, 0x22, 0x11, 0x30, 0x2f, 0xb7, 0xc0, 0x2a, 0x67, 0x01, 0x08, 0x45, 0x21, 0x40, 0x42, +0x11, 0x02, 0x48, 0x12, 0xa3, 0x21, 0x83, 0x33, 0x0c, 0xc8, 0x51, 0xe5, 0x68, 0x0a, 0x9e, 0x39, +0xbf, 0x22, 0xb2, 0x67, 0x50, 0xb2, 0x49, 0x50, 0xa2, 0x02, 0x41, 0x85, 0xc1, 0x39, 0xbb, 0x50, +0x56, 0x67, 0x12, 0x45, 0xbc, 0xa0, 0x17, 0xab, 0xc0, 0x67, 0x02, 0x02, 0x51, 0xa1, 0x20, 0x08, +0x2b, 0x0a, 0xab, 0x67, 0x7f, 0xa8, 0x0d, 0x0a, 0x54, 0x68, 0x69, 0x73, 0x7f, 0xfb, 0x20, 0x66, +0x6f, 0x6e, 0x74, 0x04, 0x69, 0x6c, 0x65, 0x20, 0x68, 0x61, 0xff, 0x6f, 0x0d, 0x62, 0x65, 0x65, +0x6e, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0xdb, 0x64, 0x2f, 0x02, 0x69, 0x06, 0x13, +0xb7, 0x7f, 0x79, 0x20, 0x43, 0x50, 0x49, 0x61, 0x64, 0x09, 0x56, 0x31, 0xff, 0xed, 0x2e, 0x32, +0x30, 0x37, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0xfd, 0x2f, 0x28, 0x43, 0x29, 0x20, +0x31, 0x39, 0x39, 0x33, 0x2d, 0xfb, 0xd7, 0x04, 0x36, 0x28, 0x6b, 0x6f, 0x73, 0x74, 0x54, 0xdb, +0x7f, 0x40, 0x61, 0x63, 0x6d, 0x2e, 0x6f, 0x72, 0x67, 0x1f, 0x4b, 0x63, 0x77, 0x0f, 0x61, 0x20, +0x4b, 0x15, 0x29, 0xff, 0x60, 0x71, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x77, 0xf7, 0x20, +0x6d, 0x61, 0x79, 0x6f, 0x20, 0x75, 0x73, 0x63, 0xdd, 0x5a, 0x66, 0x72, 0x09, 0x6f, 0x66, 0x6b, +0xad, 0x7a, 0x84, 0x36, 0x09, 0xf6, 0x5b, 0x7e, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x11, 0xdf, 0xda, +0x77, 0x8d, 0x69, 0x73, 0x6b, 0x2e, 0x0d, 0x00, 0x80, 0x0a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, +0xff, 0xa4, 0xe8, 0x3a, 0x00, 0x72, 0xfa, 0x41, 0xe8, 0x2f, 0x00, 0xe3, 0x3b, 0x73, 0xf9, 0x83, +0xe9, 0x03, 0x72, 0x06, 0x88, 0xcc, 0xac, 0xf7, 0xd0, 0x95, 0x31, 0xc9, 0xe8, 0x1b, 0x00, 0x11, +0xc9, 0x75, 0x08, 0x41, 0xe8, 0x13, 0x00, 0x73, 0xfb, 0x41, 0x41, 0x81, 0xfd, 0x00, 0xf3, 0x83, +0xd1, 0x01, 0x8d, 0x03, 0x96, 0xf3, 0xa4, 0x96, 0xeb, 0xc8, 0xe8, 0x02, 0x00, 0x11, 0xc9, 0x01, +0xdb, 0x75, 0x04, 0xad, 0x11, 0xc0, 0x93, 0xc3, 0x5e, 0xb9, 0x01, 0x00, 0xac, 0x2c, 0xe8, 0x3c, +0x01, 0x77, 0xf9, 0x8b, 0x1c, 0x86, 0xdf, 0x29, 0xf3, 0x89, 0x1c, 0xad, 0xe2, 0xee, 0xc3 }; + +Bit8u font_ega5_cpx[5720] = { +0x81, 0xfc, 0x9a, 0xc1, 0x77, 0x02, 0xcd, 0x20, 0xb9, 0x58, 0x16, 0xbe, 0x58, 0x17, 0xbf, 0x3a, +0xc1, 0xbb, 0x00, 0x80, 0xfd, 0xf3, 0xa4, 0xfc, 0x87, 0xf7, 0x83, 0xee, 0xc6, 0x19, 0xed, 0x57, +0x57, 0xe9, 0xb9, 0xbf, 0x55, 0x50, 0x58, 0x21, 0x0b, 0x01, 0x04, 0x08, 0xcf, 0xfc, 0xfe, 0x92, +0xf9, 0xe1, 0xc2, 0x32, 0xcc, 0xbf, 0xc0, 0x15, 0x06, 0xcf, 0xbb, 0xfc, 0xff, 0x46, 0x4f, 0x4e, +0x54, 0x20, 0x00, 0x00, 0x01, 0x6e, 0x39, 0x01, 0x17, 0x06, 0xfd, 0xfd, 0x05, 0x00, 0x1c, 0x00, +0x4d, 0x26, 0x0e, 0x45, 0x47, 0x41, 0xc9, 0xcd, 0x1e, 0x20, 0xe1, 0x02, 0xfe, 0xd8, 0x35, 0x24, +0x03, 0x00, 0x12, 0x26, 0x10, 0x08, 0x95, 0xc5, 0x0a, 0x00, 0x6d, 0xff, 0x7e, 0x81, 0xa5, 0x81, +0x81, 0xbd, 0x99, 0x03, 0x7e, 0xfe, 0x83, 0x0f, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, +0xe6, 0x77, 0x00, 0x6c, 0xfe, 0x3e, 0xec, 0x7c, 0x38, 0x10, 0x30, 0x10, 0x38, 0x7c, 0xfd, 0xc0, +0x0e, 0x18, 0x3c, 0x3c, 0xe7, 0xb2, 0xb6, 0x00, 0x18, 0x06, 0x0f, 0x65, 0x6e, 0x7e, 0x3b, 0x0f, +0xb3, 0xb3, 0x22, 0x18, 0x09, 0xde, 0xb1, 0xff, 0x00, 0xe7, 0xc3, 0x5f, 0x3f, 0xf6, 0x00, 0x1f, +0x3c, 0x66, 0x42, 0x42, 0x66, 0xff, 0x92, 0x3c, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xfe, 0x21, +0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xde, 0xeb, 0x00, 0x78, 0x20, 0x2d, 0xb9, 0xe6, 0x00, 0x4f, +0x61, 0xbb, 0x9f, 0x0f, 0x3f, 0x33, 0x3f, 0x30, 0x00, 0x70, 0xf0, 0xf9, 0xc8, 0xe0, 0x00, 0x7f, +0x63, 0x7f, 0x63, 0x9e, 0xbd, 0x67, 0xe7, 0xe6, 0xc0, 0x7c, 0x18, 0xdb, 0x87, 0xdd, 0xa0, 0x3c, +0xdb, 0x2e, 0x80, 0xbb, 0xfd, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0x2d, 0xc0, 0x80, 0xbf, 0xfe, +0x1f, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x6b, 0x49, 0x2b, 0x5e, +0x7c, 0x67, 0x3c, 0x00, 0x66, 0x98, 0x9b, 0x07, 0x5f, 0xe7, 0x36, 0xdb, 0x00, 0x7b, 0x1b, 0xff, +0x9b, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0x06, 0xe4, 0xc6, 0x7c, +0x00, 0xfe, 0x43, 0x66, 0x4f, 0x7e, 0x6f, 0x60, 0x0f, 0x00, 0xbd, 0x60, 0x0f, 0x00, 0xfe, 0x96, +0x70, 0x11, 0x0c, 0xfe, 0x0c, 0x77, 0xc9, 0x0c, 0x00, 0x30, 0x60, 0xfe, 0x06, 0xe4, 0x60, 0x30, +0x00, 0xc0, 0x61, 0x56, 0x5c, 0xa1, 0x76, 0x39, 0x28, 0x6c, 0x28, 0x0e, 0x50, 0x58, 0x9f, 0xb2, +0xb7, 0xa0, 0x7c, 0x7d, 0x8a, 0x0e, 0x5b, 0x0e, 0x38, 0xaf, 0xbc, 0xc0, 0x00, 0x18, 0x3c, 0x66, +0xaf, 0x8c, 0x8f, 0x21, 0xeb, 0xe9, 0x24, 0x20, 0x8b, 0xb9, 0x6c, 0x5e, 0x03, 0xad, 0xfe, 0x36, +0xf1, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0x1e, 0xd6, 0xef, 0xc1, 0xc2, 0xc6, 0x26, 0xdf, 0xae, +0x30, 0x60, 0xc6, 0x86, 0x2e, 0x14, 0x0e, 0x0c, 0x76, 0xdc, 0xc1, 0x1a, 0xaf, 0x76, 0xbd, 0x81, +0x6d, 0x00, 0x60, 0x4e, 0x8b, 0xb9, 0x2b, 0x00, 0xe5, 0xb9, 0x59, 0x0f, 0x08, 0x96, 0x8d, 0x00, +0x18, 0xe2, 0x15, 0x16, 0xde, 0xff, 0xe5, 0x84, 0x81, 0xa2, 0xed, 0x06, 0xb6, 0x14, 0x6c, 0xc0, +0x31, 0xfe, 0xd7, 0x96, 0xad, 0x31, 0xf9, 0x15, 0xe2, 0x9f, 0xc0, 0x80, 0xf8, 0x30, 0xae, 0xd6, +0xd6, 0x0e, 0x76, 0xb2, 0x27, 0x38, 0x78, 0x59, 0x10, 0x81, 0x2e, 0xf6, 0xe4, 0x7c, 0xc6, 0xc6, +0xfe, 0x0f, 0xd8, 0x4e, 0x06, 0x3c, 0x02, 0x06, 0xfd, 0x43, 0xdf, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, +0xfe, 0x9c, 0xd0, 0xb0, 0x1e, 0x8d, 0xfe, 0x03, 0xd6, 0xfc, 0x1f, 0x38, 0x90, 0xbb, 0x60, 0x0f, +0xc6, 0xc6, 0xc6, 0x66, 0xee, 0xfe, 0x3f, 0xf3, 0x73, 0xc3, 0x4f, 0x1a, 0x1f, 0x7d, 0x01, 0x0b, +0x7e, 0x0b, 0xdb, 0x3f, 0x0c, 0x78, 0xba, 0x0b, 0x7b, 0x04, 0x0f, 0x62, 0x93, 0x30, 0x9e, 0x92, +0x1a, 0x35, 0x06, 0xc2, 0xc9, 0xde, 0x02, 0x00, 0xf6, 0x62, 0x1b, 0x23, 0x5f, 0x25, 0x4c, 0x0c, +0xdf, 0xb6, 0xb3, 0x10, 0xde, 0x00, 0xdc, 0x61, 0x14, 0xc4, 0x2e, 0x3b, 0xdb, 0x6c, 0x90, 0xfe, +0x0f, 0x6c, 0x3c, 0xfc, 0x66, 0xf1, 0x7c, 0x86, 0xf4, 0xfc, 0x6f, 0xd4, 0x15, 0xef, 0x00, 0xc2, +0xf2, 0xe9, 0xa1, 0x10, 0xf8, 0x6c, 0x3f, 0x7b, 0x6c, 0xf8, 0x0f, 0xfe, 0x66, 0x62, 0x68, 0x84, +0xfc, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0xc0, 0xb6, 0x00, 0xf0, 0x3f, 0x4d, 0x7e, 0xde, 0xc6, +0xc6, 0x66, 0x3a, 0x61, 0xef, 0x69, 0x6e, 0x6f, 0x6b, 0xc2, 0x3c, 0x7d, 0x30, 0x31, 0x26, 0x1e, +0x0d, 0x77, 0x49, 0xef, 0xe6, 0x6a, 0xb3, 0x6e, 0x78, 0x78, 0x74, 0xe6, 0x0f, 0xb3, 0xd8, 0xf0, +0x60, 0x00, 0x6f, 0x92, 0x7f, 0x4f, 0xee, 0xfe, 0xfe, 0xd6, 0xf2, 0xdb, 0x0f, 0xe6, 0xf6, 0xfe, +0xde, 0xce, 0x79, 0x58, 0x6f, 0xc6, 0x9b, 0x2d, 0xdf, 0x41, 0x27, 0xec, 0xf0, 0x1f, 0xd6, 0xde, +0x97, 0xe4, 0x7c, 0x0c, 0x0e, 0xe3, 0x29, 0xd9, 0xe6, 0x1f, 0xe2, 0xb2, 0x42, 0x50, 0x3f, 0x09, +0x7b, 0x7e, 0x7e, 0x5a, 0xaf, 0x16, 0xb2, 0xc6, 0x5f, 0x0f, 0x25, 0x0f, 0x6c, 0x38, 0x10, 0x43, +0xfe, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x6b, 0xa6, 0x6c, 0x8e, 0x61, 0x9f, 0x66, 0x0d, 0xce, +0x0b, 0xcb, 0x4f, 0x1b, 0x86, 0x21, 0x1f, 0x7f, 0xc2, 0x16, 0xec, 0x3c, 0x30, 0x00, 0x1f, 0xfe, +0x0a, 0xc1, 0x70, 0x38, 0x1c, 0x76, 0xb2, 0xaf, 0x3c, 0x0c, 0x00, 0x62, 0x0c, 0x3c, 0xdc, 0x8d, +0x90, 0xe6, 0xec, 0x34, 0x6c, 0xff, 0x18, 0xe9, 0x03, 0x78, 0x0c, 0x7c, 0xaf, 0x16, 0x2e, 0xe0, +0x19, 0x78, 0x66, 0x11, 0xe2, 0xcf, 0x1c, 0x13, 0x02, 0x00, 0xb9, 0xc3, 0xdf, 0x1c, 0x69, 0x2d, +0x2b, 0x00, 0x2f, 0x80, 0x8c, 0x1f, 0xfe, 0xc6, 0xfb, 0x36, 0x32, 0x30, 0x78, 0xaf, 0xcf, 0xf0, +0x5d, 0x76, 0x2e, 0xcc, 0xdf, 0xa1, 0x5f, 0xd2, 0x5f, 0x6c, 0x32, 0x9e, 0x76, 0xe6, 0xdc, 0x03, +0x61, 0x38, 0x4f, 0x6b, 0x4b, 0x09, 0x00, 0xdb, 0x00, 0xcc, 0x10, 0x17, 0x2f, 0x71, 0xc6, 0x00, +0xe6, 0x90, 0x9c, 0x2f, 0x38, 0x35, 0xba, 0x00, 0xec, 0x00, 0x4c, 0xd6, 0x00, 0xc6, 0x0f, 0xdc, +0xcb, 0x66, 0xa1, 0x9f, 0x6c, 0x09, 0x9f, 0x1f, 0xf6, 0xb1, 0x04, 0xf0, 0x9f, 0x90, 0x16, 0xd2, +0x19, 0xed, 0xdc, 0x9f, 0x1f, 0x4c, 0x60, 0xe4, 0x76, 0x09, 0xdf, 0x10, 0xd9, 0xb2, 0xdf, 0xfc, +0xde, 0x36, 0x1c, 0x1f, 0x10, 0x5e, 0x3d, 0x0f, 0x82, 0x31, 0x00, 0x47, 0xc0, 0x0f, 0x00, 0xb7, +0x84, 0x9a, 0x1b, 0x30, 0x53, 0x38, 0x75, 0x2f, 0xd4, 0xb5, 0x04, 0x0c, 0x03, 0x87, 0x52, 0xcc, +0x4f, 0xcd, 0xd9, 0xfe, 0xef, 0x0e, 0x70, 0x64, 0x3d, 0x0e, 0xf7, 0x09, 0x83, 0x3f, 0xda, 0x7b, +0x1b, 0x23, 0x24, 0x40, 0xf8, 0xc9, 0xdc, 0xdf, 0x8b, 0x34, 0xe2, 0x4f, 0x95, 0x34, 0xef, 0x76, +0x7a, 0xfe, 0x62, 0x1c, 0xff, 0xe6, 0x5e, 0x10, 0x10, 0xab, 0x3f, 0x2b, 0x69, 0xef, 0x5a, 0x19, +0xaf, 0x69, 0x4a, 0xdf, 0x7c, 0xef, 0x40, 0x0e, 0x7c, 0x91, 0xb4, 0xdf, 0x69, 0xb2, 0x6f, 0xc6, +0xdf, 0x52, 0x08, 0xe0, 0x30, 0x48, 0xde, 0x6d, 0xed, 0x82, 0x63, 0x5b, 0x82, 0x02, 0xa9, 0x07, +0xef, 0x0e, 0xe9, 0xfe, 0xff, 0xc6, 0xb6, 0x40, 0x1f, 0x6b, 0xe0, 0x62, 0x30, 0x5b, 0x62, 0xbf, +0x56, 0xd2, 0xdf, 0xb4, 0x92, 0x9f, 0xf6, 0xb1, 0xd7, 0x7c, 0x6d, 0x7c, 0xa6, 0x0b, 0xa4, 0xcf, +0xd8, 0x7b, 0x1c, 0x1e, 0x1f, 0x17, 0x61, 0x7b, 0x24, 0x2f, 0x69, 0x28, 0xee, 0x0f, 0xdc, 0xd8, +0x60, 0x6c, 0x00, 0xdc, 0x2f, 0xe0, 0x8b, 0xdb, 0xd8, 0x3c, 0xf8, 0x30, 0xfc, 0xa1, 0xbe, 0x64, +0x1f, 0x35, 0x7c, 0xda, 0x04, 0x3f, 0x9e, 0x21, 0xc5, 0xd3, 0x8f, 0x24, 0x3b, 0x78, 0xc0, 0xdf, +0x61, 0x3a, 0x7d, 0x9f, 0x61, 0x34, 0x94, 0x3c, 0xff, 0x90, 0x69, 0x49, 0x6b, 0x9d, 0x2f, 0x3e, +0xbd, 0xc4, 0x2b, 0xd9, 0x3f, 0x4f, 0x97, 0x31, 0xbf, 0xc6, 0x6f, 0xf6, 0xcc, 0xf8, 0xf8, 0xcc, +0xbf, 0x8f, 0x78, 0x5f, 0x4b, 0x6c, 0x0f, 0xee, 0xc2, 0xdf, 0xf6, 0x63, 0x21, 0x09, 0xb2, 0xb3, +0x06, 0xa1, 0x30, 0x4f, 0x38, 0x63, 0x17, 0x4a, 0x3c, 0x60, 0x7f, 0x1c, 0x42, 0x48, 0x6f, 0x72, +0x2f, 0x3f, 0x00, 0x6c, 0x48, 0x8f, 0xfc, 0x4f, 0xe3, 0x9d, 0x7e, 0xd8, 0x00, 0xbf, 0x86, 0xc1, +0x32, 0xb2, 0xe6, 0x1a, 0x54, 0x4f, 0x21, 0x69, 0xfe, 0x6f, 0x03, 0x7b, 0x7f, 0xcf, 0x3a, 0x84, +0x5c, 0x72, 0x10, 0x9d, 0x40, 0x5f, 0x10, 0xd6, 0xb0, 0x93, 0x1f, 0x11, 0x44, 0x01, 0x85, 0xbc, +0x55, 0xaa, 0x2e, 0xe4, 0xdd, 0x77, 0x18, 0xbb, 0xc0, 0x00, 0xf8, 0x0d, 0x64, 0x21, 0x0f, 0xe4, +0xd9, 0x36, 0x00, 0xf6, 0x36, 0x1b, 0x16, 0xc0, 0x0f, 0x64, 0x09, 0x2f, 0xd8, 0x79, 0xf6, 0x06, +0x00, 0xcd, 0x12, 0x3d, 0xb4, 0x90, 0x1f, 0x2f, 0x2c, 0x59, 0xee, 0x11, 0x4b, 0x16, 0x0f, 0x8f, +0x64, 0x0d, 0x00, 0x43, 0x36, 0xf8, 0xbf, 0x1f, 0x3c, 0x61, 0x2f, 0x18, 0x18, 0xff, 0xc9, 0x90, +0xff, 0xc2, 0x1a, 0x72, 0xc8, 0xda, 0x1f, 0x3f, 0x0c, 0xd9, 0x2d, 0x1f, 0x36, 0x24, 0x0f, 0x37, +0xbf, 0xd8, 0x13, 0x37, 0x30, 0x3f, 0x6d, 0x95, 0x4a, 0xbf, 0xd9, 0x85, 0x1f, 0xf7, 0x5f, 0x1b, +0x6c, 0x6d, 0xf7, 0x3f, 0x64, 0x21, 0x2f, 0x65, 0xb3, 0x1f, 0x2f, 0x65, 0xb3, 0x3f, 0x2f, 0x61, +0xb0, 0xdd, 0xff, 0x2f, 0x64, 0x21, 0x5f, 0x46, 0x76, 0xff, 0xdf, 0x16, 0x12, 0x86, 0xaf, 0x0d, +0x4b, 0xdf, 0xbd, 0x84, 0x3f, 0xef, 0xc9, 0x85, 0x3f, 0x3f, 0x24, 0x0b, 0x4f, 0x84, 0x20, 0x2d, +0x5f, 0x24, 0x8c, 0xaf, 0x9b, 0x6c, 0x4f, 0xff, 0x00, 0x61, 0x21, 0x9f, 0xe4, 0xb0, 0x00, 0xf0, +0x48, 0x86, 0x0f, 0x58, 0x58, 0x36, 0xe4, 0x30, 0x8f, 0x44, 0x58, 0x0f, 0x08, 0x10, 0x8f, 0x96, +0x5b, 0x0f, 0x5f, 0xe5, 0x12, 0x0f, 0x1e, 0x96, 0x4f, 0xf5, 0x66, 0xb2, 0x41, 0x0e, 0x1f, 0x12, +0x56, 0x4f, 0x81, 0xf4, 0x3f, 0xff, 0x21, 0xe9, 0x04, 0x08, 0xaf, 0xb7, 0xb0, 0x66, 0x0f, 0x2f, +0x1c, 0x30, 0x8f, 0x40, 0x80, 0x5b, 0x18, 0x9f, 0x0f, 0x68, 0x60, 0x7e, 0xaa, 0x78, 0xcd, 0x1e, +0xaf, 0x7e, 0x0f, 0x2c, 0xf6, 0x3a, 0x7e, 0x40, 0x0f, 0x85, 0xc1, 0x4f, 0x08, 0xb4, 0x0f, 0xff, +0x3b, 0x5b, 0x2f, 0x3c, 0x1f, 0x02, 0x01, 0x8f, 0xac, 0x52, 0x5d, 0x96, 0xd4, 0x41, 0x16, 0xa4, +0x3e, 0x10, 0x90, 0x4a, 0x6e, 0xf6, 0x5e, 0x0f, 0xbc, 0x6f, 0x06, 0x17, 0x66, 0x1f, 0xe7, 0x52, +0x50, 0x2a, 0x02, 0x0f, 0x09, 0xee, 0x90, 0x58, 0x97, 0x0c, 0x30, 0x1f, 0x81, 0xac, 0xac, 0xb0, +0x61, 0x42, 0x00, 0xdb, 0xf3, 0x0f, 0x0c, 0xec, 0x34, 0x3c, 0x35, 0x08, 0x5f, 0x6c, 0x81, 0x81, +0x58, 0x2c, 0xd9, 0x16, 0xa0, 0x32, 0xbc, 0x93, 0x2f, 0x00, 0x7e, 0x06, 0x90, 0x00, 0x0e, 0xc1, +0x0b, 0x05, 0x1c, 0x61, 0x03, 0x7e, 0x07, 0x16, 0x01, 0x7e, 0x80, 0x04, 0xff, 0x93, 0x20, 0xfd, +0x95, 0x04, 0xfb, 0x4a, 0x82, 0xf9, 0x38, 0x41, 0xf7, 0x8c, 0x24, 0xf5, 0x58, 0x12, 0xf3, 0x8c, +0x24, 0xf1, 0x5d, 0x12, 0xef, 0x78, 0x24, 0x98, 0x27, 0xec, 0x4e, 0xb0, 0xeb, 0x2c, 0x09, 0xea, +0x82, 0x13, 0xe9, 0x49, 0x70, 0xe8, 0xe7, 0x98, 0x4a, 0x24, 0x82, 0x12, 0xe5, 0x04, 0x4b, 0xe4, +0x70, 0xaa, 0xe3, 0x32, 0x48, 0x49, 0xe1, 0x24, 0x24, 0xde, 0x18, 0x12, 0xdd, 0x30, 0x24, 0xdb, +0x1c, 0x49, 0xda, 0x00, 0x92, 0xa0, 0xd7, 0xac, 0x37, 0x0d, 0x01, 0x49, 0xb0, 0xd2, 0x27, 0x08, +0xd1, 0x84, 0x04, 0xcf, 0x93, 0x20, 0xcd, 0x95, 0x04, 0xcb, 0x4c, 0x82, 0xc9, 0x54, 0x12, 0xc7, +0x45, 0x82, 0xc3, 0x93, 0xc0, 0x76, 0xc1, 0x84, 0x04, 0xbe, 0x93, 0x20, 0xbd, 0x96, 0x04, 0xbc, +0xf0, 0x09, 0xbb, 0x66, 0xc6, 0x1c, 0x48, 0xb9, 0x76, 0x52, 0x12, 0x5f, 0x34, 0x09, 0xb5, 0x92, +0xe0, 0x06, 0xb3, 0x20, 0xd9, 0x20, 0x12, 0x9c, 0xb0, 0xae, 0xb0, 0x40, 0x4b, 0xc2, 0x18, 0xfe, +0xfb, 0x49, 0x10, 0xa5, 0x93, 0x5a, 0x44, 0x97, 0x04, 0xa3, 0x7e, 0x96, 0x04, 0xa1, 0x04, 0xa7, +0x20, 0x1c, 0x96, 0x9f, 0xa3, 0x5c, 0x12, 0x9d, 0x1e, 0x02, 0x12, 0x9b, 0x49, 0xf0, 0x1b, 0x99, +0x04, 0x6f, 0x0d, 0xc1, 0xec, 0x97, 0xd4, 0x70, 0x20, 0x95, 0x7c, 0x60, 0x49, 0x93, 0x41, 0x92, +0x92, 0x09, 0x26, 0x80, 0x8e, 0x62, 0x2b, 0xb3, 0x12, 0xbc, 0x1e, 0x8b, 0x09, 0x56, 0x88, 0x04, +0x09, 0xc1, 0x8b, 0x87, 0x3c, 0x2b, 0x25, 0x84, 0xf3, 0x48, 0x25, 0x91, 0x12, 0x4c, 0xfc, 0x7f, +0x24, 0x58, 0x7e, 0x4e, 0x10, 0x7d, 0xd4, 0x09, 0x7c, 0xa7, 0x96, 0x8b, 0x8a, 0xa3, 0x65, 0x0d, +0xd8, 0x25, 0xc1, 0x77, 0x42, 0xea, 0x66, 0x3a, 0x95, 0x84, 0xd4, 0x83, 0x20, 0xc1, 0x3c, 0x71, +0xea, 0x6c, 0xed, 0xe6, 0x64, 0x59, 0x8e, 0x6c, 0x6c, 0x24, 0x18, 0xf0, 0x6c, 0x3a, 0xb5, 0x8b, +0x35, 0x90, 0x8a, 0x75, 0x21, 0x88, 0x7c, 0xc8, 0x20, 0x65, 0x7c, 0x96, 0x4d, 0xf0, 0x1b, 0x81, +0x09, 0x62, 0x70, 0x20, 0x61, 0xe6, 0x6c, 0x49, 0x5f, 0x37, 0x3b, 0x35, 0x7d, 0x99, 0x48, 0x2d, +0xca, 0x24, 0x58, 0x58, 0x12, 0x24, 0x57, 0x36, 0x23, 0xd7, 0x0d, 0x5e, 0x29, 0x1c, 0x66, 0x25, +0xa4, 0xb3, 0x6a, 0x9b, 0x45, 0xf7, 0x8c, 0x04, 0xcb, 0xa0, 0x04, 0x87, 0x4f, 0x3c, 0x82, 0x95, +0x4c, 0x82, 0x41, 0x4b, 0x3c, 0x18, 0x48, 0x49, 0xff, 0x03, 0x24, 0x45, 0xf0, 0x04, 0x43, 0x76, +0x1c, 0x48, 0x41, 0x7c, 0x02, 0x12, 0x3f, 0x49, 0xf0, 0xc3, 0x3d, 0x5c, 0x76, 0x76, 0x1b, 0xfe, +0x09, 0x92, 0x39, 0x90, 0x60, 0x7c, 0x38, 0x0c, 0x18, 0x76, 0x96, 0x20, 0x41, 0x35, 0x48, 0x30, +0xe6, 0x33, 0x12, 0x1c, 0x3c, 0x31, 0x24, 0x58, 0x2f, 0x21, 0x24, 0xbf, 0x78, 0xb1, 0x26, 0x29, +0x24, 0x24, 0x2b, 0x12, 0x12, 0x09, 0x26, 0xa4, 0x97, 0x7c, 0x61, 0xc2, 0x1b, 0x7c, 0xc1, 0x60, +0xd9, 0x8b, 0x3b, 0x90, 0x21, 0xf0, 0x37, 0x26, 0x2f, 0x70, 0x1c, 0xd4, 0x09, 0x1d, 0x82, 0x84, +0xac, 0x42, 0x42, 0x1a, 0xbf, 0x31, 0x5b, 0x0d, 0xab, 0x65, 0x86, 0xf5, 0x80, 0x0d, 0x29, 0x82, +0xa7, 0x83, 0x7c, 0x1e, 0x49, 0x11, 0x83, 0x2e, 0x09, 0x0f, 0x0e, 0x09, 0x09, 0x0d, 0x81, 0x04, +0x0b, 0x20, 0xc1, 0x70, 0x09, 0x4d, 0x4a, 0x66, 0x1b, 0x20, 0x71, 0x08, 0xac, 0x98, 0x03, 0x35, +0x20, 0x96, 0x00, 0x3b, 0x30, 0x8f, 0xfe, 0x1b, 0x04, 0x26, 0xf0, 0xb1, 0xcd, 0x9a, 0xfe, 0xb3, +0x29, 0xe9, 0x0d, 0x63, 0x83, 0x01, 0xf7, 0x7c, 0x60, 0x65, 0xa7, 0x0d, 0x16, 0x70, 0xd8, 0xc3, +0x18, 0xf0, 0xf0, 0xd8, 0xcc, 0xc6, 0xf1, 0x4a, 0x4a, 0x63, 0xbe, 0x97, 0x67, 0x4f, 0xfe, 0xb0, +0x92, 0x71, 0x2c, 0x19, 0xe7, 0xd1, 0x48, 0xb6, 0xc3, 0x01, 0x0f, 0xe3, 0x61, 0x87, 0xe2, 0x7e, +0x8b, 0xc9, 0x22, 0xbf, 0x96, 0x01, 0xdd, 0x04, 0x03, 0xdc, 0x76, 0x38, 0xad, 0x94, 0x53, 0x10, +0x60, 0x65, 0xa1, 0x97, 0x16, 0x46, 0x0c, 0x03, 0x71, 0x91, 0x8c, 0x44, 0x03, 0x3e, 0xbf, 0xf8, +0xcc, 0xd2, 0xc0, 0x2d, 0x47, 0x06, 0x3c, 0xd0, 0xcf, 0x40, 0x5a, 0x1d, 0xc0, 0x64, 0x70, 0xc7, +0x64, 0xcb, 0x78, 0xf3, 0xb1, 0x8c, 0x9f, 0x32, 0xc0, 0xe0, 0xc7, 0x4a, 0x46, 0xc9, 0xc0, 0x32, +0x74, 0xb0, 0x64, 0xc3, 0x7d, 0x61, 0x40, 0xc0, 0x30, 0x60, 0xbe, 0x65, 0x41, 0x70, 0x20, 0xd8, +0x30, 0x6f, 0x80, 0xd6, 0x13, 0x01, 0x25, 0xcd, 0xba, 0x01, 0x31, 0x60, 0xb7, 0x4c, 0x48, 0x1d, +0xfc, 0x07, 0x06, 0xb3, 0x70, 0x96, 0x01, 0xb1, 0x2e, 0x09, 0x80, 0xfe, 0x97, 0x90, 0x01, 0x6f, +0x18, 0x30, 0xb5, 0x5c, 0x18, 0x41, 0x44, 0xf3, 0x08, 0x03, 0x10, 0x60, 0x32, 0x60, 0xa3, 0x06, +0x04, 0x9f, 0xc0, 0x55, 0xf8, 0x60, 0x65, 0x9b, 0xc0, 0x32, 0x99, 0x20, 0x65, 0x97, 0xc0, 0x32, +0x95, 0x58, 0x64, 0x93, 0xac, 0x0c, 0x8f, 0x80, 0x07, 0x8d, 0x40, 0xca, 0x8b, 0x60, 0x65, 0x89, +0x18, 0x32, 0x87, 0x1f, 0x2b, 0x0c, 0x83, 0x90, 0x01, 0x51, 0xca, 0x80, 0x7d, 0x65, 0xc0, 0x7b, +0x36, 0x20, 0x77, 0x1f, 0x30, 0x42, 0x80, 0x19, 0x75, 0xc0, 0xca, 0x73, 0x0c, 0x78, 0x71, 0x6f, +0x01, 0x23, 0x32, 0xe0, 0x6d, 0x6b, 0x19, 0x90, 0x69, 0x32, 0x60, 0x67, 0x19, 0x30, 0x65, 0x80, +0x5b, 0x1b, 0x5c, 0x61, 0x61, 0x3f, 0x11, 0x06, 0x5d, 0x06, 0xbc, 0xd1, 0x59, 0xc0, 0x14, 0xff, +0x5c, 0x61, 0x55, 0xf8, 0x00, 0x06, 0x51, 0xc2, 0x80, 0x4d, 0x18, 0xb0, 0x4b, 0x0c, 0x58, 0x47, +0x81, 0xa9, 0x44, 0xbd, 0x49, 0x2f, 0x08, 0x10, 0xfd, 0x49, 0x6f, 0x0d, 0xd3, 0x49, 0x6f, 0x0d, +0xc5, 0x32, 0x60, 0x3d, 0x30, 0x60, 0x0e, 0x3b, 0x2d, 0x3b, 0x1c, 0x37, 0x03, 0x26, 0x7f, 0x37, +0x52, 0x2c, 0x86, 0x2d, 0x0b, 0x0d, 0xb0, 0xec, 0x29, 0x7d, 0x60, 0x19, 0x31, 0x38, 0x30, 0x2f, +0x7e, 0x25, 0x0c, 0x2d, 0x49, 0x88, 0x0d, 0x1c, 0x81, 0x01, 0x29, 0x61, 0xc0, 0x7c, 0x27, 0x56, +0x2c, 0x0d, 0xdd, 0x0c, 0x58, 0x22, 0x06, 0xa4, 0x20, 0x0c, 0x58, 0x1e, 0xe0, 0x2d, 0xdc, 0x92, +0x4b, 0x5b, 0x66, 0x19, 0x10, 0x19, 0x0c, 0x08, 0x17, 0x1e, 0xb0, 0x15, 0x20, 0x03, 0x12, 0x32, +0x60, 0x18, 0x0f, 0x06, 0x1c, 0x3c, 0x1c, 0x0d, 0x03, 0x56, 0x0b, 0x01, 0x21, 0x70, 0x81, 0x08, +0x08, 0x60, 0x19, 0x05, 0x03, 0x1c, 0xfc, 0xfb, 0x60, 0x80, 0xf6, 0x00, 0x0d, 0xf5, 0x6c, 0x04, +0x98, 0xee, 0xe9, 0xd0, 0x16, 0x06, 0x38, 0x5f, 0x2b, 0x81, 0x0d, 0x0f, 0xfe, 0x80, 0x07, 0x19, +0x02, 0x4c, 0xd7, 0xd1, 0x04, 0x08, 0xcb, 0x08, 0x10, 0xc5, 0x01, 0x3e, 0x0f, 0x07, 0x0f, 0x7d, +0xbf, 0x20, 0x80, 0xba, 0x70, 0x80, 0xb4, 0x01, 0x0a, 0xb3, 0xae, 0x06, 0xf8, 0x67, 0xe6, 0xc0, +0xa7, 0xd0, 0x00, 0xa8, 0x80, 0x0d, 0x0e, 0xa1, 0x20, 0x78, 0x80, 0x02, 0x9b, 0x02, 0x00, 0x07, +0x42, 0x13, 0xc0, 0x33, 0x8f, 0xc0, 0x00, 0x8a, 0xbb, 0x1b, 0x89, 0x00, 0x3e, 0x61, 0x49, 0x3c, +0x86, 0x5e, 0xb0, 0x7c, 0xd0, 0x27, 0x04, 0xf8, 0x26, 0xff, 0x72, 0xbc, 0xc3, 0x72, 0x0f, 0x48, +0x02, 0x65, 0x00, 0x07, 0x5f, 0xc0, 0x97, 0x59, 0x24, 0x66, 0xff, 0x0f, 0x38, 0x12, 0x9f, 0xbc, +0x18, 0xef, 0x2e, 0x06, 0x02, 0x3d, 0xd0, 0xf0, 0x46, 0xad, 0x24, 0x68, 0x08, 0x31, 0x56, 0xfc, +0x57, 0x18, 0x3e, 0x83, 0xf0, 0xe0, 0x7c, 0x18, 0x5b, 0x00, 0x0f, 0x23, 0x38, 0x64, 0xf5, 0x1e, +0x76, 0xcc, 0x98, 0x86, 0xf9, 0x30, 0xc0, 0x7c, 0x0f, 0x0c, 0x40, 0x12, 0x06, 0xb0, 0x25, 0x00, +0x2b, 0x03, 0x61, 0x7e, 0xd6, 0x18, 0x56, 0xe8, 0xbd, 0xea, 0x63, 0xd6, 0xe1, 0xc5, 0x5a, 0xdd, +0xc2, 0x17, 0x5f, 0xc9, 0x1c, 0xe5, 0xaf, 0xba, 0x07, 0x3c, 0xb3, 0x71, 0x56, 0xca, 0x1e, 0xe0, +0x7d, 0x73, 0xfc, 0x0f, 0xf1, 0xe8, 0xa9, 0xfc, 0xad, 0x53, 0xac, 0xea, 0x79, 0x2c, 0xf5, 0xbd, +0x02, 0x07, 0x7e, 0xf5, 0x62, 0xab, 0x74, 0xf7, 0x66, 0x62, 0x77, 0x67, 0x56, 0x8f, 0xaa, 0x94, +0xf5, 0x48, 0xa6, 0x59, 0x7d, 0x8d, 0x7c, 0x88, 0x5c, 0xb9, 0x07, 0x82, 0x7a, 0x25, 0x6b, 0x87, +0xac, 0x46, 0x3d, 0xfc, 0x76, 0xcc, 0x60, 0xfc, 0xcc, 0xbd, 0x32, 0xd0, 0x6b, 0x56, 0x5f, 0x69, +0xfe, 0x64, 0x68, 0x36, 0xfe, 0x07, 0xd5, 0x67, 0xf5, 0x1f, 0xce, 0xc1, 0xc2, 0x57, 0xe0, 0x0b, +0x56, 0x4d, 0x2f, 0xc1, 0x6a, 0x1e, 0x45, 0x06, 0xa3, 0xe6, 0x7f, 0xf0, 0x14, 0xac, 0x39, 0x8b, +0x49, 0xc1, 0xcb, 0xe2, 0xc5, 0xca, 0xde, 0x30, 0x1e, 0x6f, 0x7f, 0x8f, 0x45, 0x0f, 0xce, 0x7c, +0x0e, 0xf1, 0x22, 0x37, 0xca, 0x7d, 0x21, 0x0c, 0x7f, 0xa4, 0xf7, 0x0b, 0x57, 0xa5, 0x08, 0x35, +0x56, 0x41, 0x2a, 0xf8, 0x22, 0x16, 0x9d, 0x9d, 0xf4, 0x9b, 0x64, 0x3c, 0xdd, 0x48, 0xe7, 0x32, +0x6f, 0x3c, 0x08, 0x52, 0xdf, 0x53, 0x07, 0x97, 0xd9, 0x3a, 0x29, 0xd5, 0x3c, 0x61, 0xe0, 0x26, +0x61, 0xd4, 0x21, 0xba, 0xd4, 0x80, 0xbc, 0x76, 0x1a, 0xc0, 0x39, 0x75, 0xdc, 0xc3, 0xa4, 0xb0, +0x7f, 0x43, 0xaa, 0x16, 0xdd, 0x53, 0xa4, 0x7c, 0x97, 0x60, 0x3a, 0xa3, 0xf8, 0xf5, 0x76, 0xe5, +0x9a, 0x09, 0xf8, 0x2f, 0x54, 0x3b, 0x92, 0xaf, 0x0a, 0xef, 0x8c, 0x7f, 0x69, 0xb8, 0xa7, 0x84, +0x3c, 0x17, 0x46, 0x3d, 0x00, 0xe6, 0xd6, 0x91, 0x5a, 0x74, 0x18, 0x16, 0xce, 0x16, 0x0c, 0x6d, +0x0f, 0x4d, 0x36, 0x7c, 0x4f, 0x1e, 0xb3, 0x48, 0x56, 0x5f, 0x82, 0x8b, 0x7e, 0x4b, 0x87, 0xc5, +0xa9, 0x4a, 0x90, 0x9a, 0x47, 0x43, 0x60, 0xd4, 0x56, 0x30, 0xac, 0xfb, 0x1b, 0x8b, 0x00, 0x17, +0x7e, 0x2f, 0x1a, 0x9c, 0x37, 0xdf, 0x7e, 0x81, 0xa7, 0x21, 0x70, 0x61, 0x1b, 0xd6, 0x89, 0x0c, +0xb3, 0xdc, 0x12, 0x6b, 0x58, 0x46, 0xfc, 0x54, 0x4a, 0xf7, 0x91, 0x3b, 0xf9, 0x7f, 0x25, 0x9c, +0x8e, 0xfe, 0xf7, 0xc2, 0x84, 0x57, 0xef, 0x23, 0x4c, 0x7c, 0xf7, 0x7c, 0x84, 0x24, 0xef, 0x60, +0x34, 0xc6, 0xa5, 0x84, 0xef, 0xd4, 0x42, 0xa0, 0x38, 0x49, 0x28, 0x9f, 0xf7, 0x08, 0x46, 0xa9, +0x6c, 0x49, 0xff, 0x0f, 0x60, 0x84, 0x13, 0xcd, 0xef, 0x86, 0x30, 0xcf, 0x10, 0x8c, 0x8a, 0xa1, +0x92, 0xe7, 0x76, 0xe0, 0x05, 0x0c, 0xa0, 0x4d, 0x99, 0xd2, 0xd1, 0xf6, 0x73, 0x57, 0xfc, 0x37, +0x8b, 0x69, 0x26, 0x97, 0x53, 0x21, 0xd3, 0x17, 0x37, 0xa3, 0x5a, 0x6f, 0x42, 0xa6, 0x38, 0xe1, +0xe8, 0x61, 0x7f, 0x06, 0x0c, 0xe8, 0x1f, 0x7e, 0xed, 0x87, 0xc1, 0x7b, 0xc6, 0xa3, 0x47, 0xad, +0x37, 0xcd, 0xe8, 0x3c, 0xeb, 0xa3, 0x18, 0x2e, 0x2a, 0x47, 0x07, 0x38, 0x7e, 0x23, 0x12, 0x5e, +0xe0, 0x3f, 0xb7, 0x8b, 0xd1, 0x18, 0x0f, 0x66, 0x14, 0x0f, 0xbd, 0x8f, 0x0c, 0x70, 0x07, 0x08, +0x83, 0x67, 0xfe, 0xb7, 0x60, 0x30, 0xe6, 0xb1, 0x12, 0xde, 0x5c, 0xb8, 0xaf, 0x76, 0xec, 0x10, +0xc8, 0x22, 0x88, 0x01, 0x43, 0x68, 0xd9, 0x1a, 0x42, 0xd4, 0xb4, 0x12, 0xca, 0x84, 0x26, 0x9a, +0xbe, 0x21, 0x34, 0xb8, 0x0d, 0xa1, 0xb2, 0x1a, 0x09, 0xac, 0xd0, 0x12, 0xa0, 0x10, 0x9a, 0x9a, +0x94, 0x81, 0xd0, 0x8e, 0x80, 0xd0, 0xf8, 0x82, 0x03, 0xa1, 0x7c, 0x01, 0xa1, 0xff, 0x70, 0xc3, +0x62, 0x0f, 0x1f, 0x02, 0x42, 0x5e, 0x90, 0x87, 0x52, 0x37, 0x26, 0x94, 0x4c, 0xb4, 0x84, 0x46, +0x12, 0x3a, 0x40, 0x3a, 0x86, 0xd0, 0x34, 0x34, 0x84, 0x2e, 0xa1, 0x21, 0x28, 0x22, 0xcc, 0x2d, +0x0f, 0x6f, 0x20, 0x34, 0x10, 0x4b, 0x28, 0x0a, 0x2c, 0x66, 0x77, 0xfe, 0xe2, 0x0d, 0x27, 0xd8, +0xc0, 0xf2, 0xd7, 0x16, 0x6f, 0x27, 0xdd, 0x2c, 0x06, 0xd7, 0x58, 0x0c, 0xcb, 0xb0, 0x18, 0xc2, +0x8b, 0xd3, 0x47, 0xbc, 0xb8, 0xc7, 0x47, 0x07, 0xe1, 0x62, 0x2f, 0x07, 0x93, 0x98, 0x27, 0xcd, +0x06, 0x8b, 0x0e, 0xa4, 0x1c, 0x44, 0xc6, 0x1f, 0xc6, 0x66, 0x27, 0xd7, 0x66, 0x07, 0x3a, 0xe6, +0x0f, 0x47, 0x40, 0xb8, 0x5c, 0x4f, 0x4f, 0x40, 0xbe, 0x7c, 0xd9, 0xde, 0x02, 0x3e, 0x40, 0xb6, +0xa7, 0x3e, 0x9b, 0xb4, 0x40, 0xbc, 0x27, 0x07, 0x62, 0x50, 0xf6, 0xef, 0xf6, 0x17, 0x4c, 0x08, +0x1c, 0x2f, 0x83, 0x18, 0xc7, 0x2e, 0x3c, 0x38, 0x7e, 0x47, 0xb8, 0x58, 0x55, 0x05, 0x83, 0x5e, +0x4f, 0x6a, 0x72, 0x30, 0x51, 0x59, 0x4c, 0x0f, 0x3e, 0xcc, 0x62, 0x38, 0x18, 0x58, 0x33, 0x45, +0x32, 0x6e, 0x2f, 0x82, 0x21, 0x1f, 0x6b, 0x16, 0x1b, 0xdd, 0xab, 0xdc, 0x50, 0x4a, 0x48, 0x17, +0x00, 0x00, 0x0d, 0x62, 0x33, 0x0e, 0xc8, 0x81, 0x4c, 0x52, 0x03, 0x21, 0x47, 0x69, 0x26, 0x64, +0x04, 0x82, 0xa2, 0x46, 0x11, 0x03, 0x02, 0x4d, 0x18, 0x99, 0x06, 0x31, 0xcc, 0xf3, 0x03, 0x06, +0x68, 0x58, 0x44, 0x03, 0x06, 0x18, 0x69, 0x65, 0x11, 0x53, 0x84, 0xbd, 0x2f, 0x0f, 0x56, 0x80, +0x98, 0x0f, 0x09, 0x12, 0x58, 0x08, 0x59, 0x2f, 0x0d, 0x8b, 0x73, 0x61, 0xef, 0x6f, 0x4f, 0x5f, +0x66, 0x2a, 0x48, 0x0f, 0x01, 0x12, 0xe7, 0x0c, 0x59, 0x1f, 0x66, 0x81, 0x45, 0x53, 0x85, 0xb5, +0x06, 0x0f, 0x80, 0xbd, 0x2f, 0x0f, 0x48, 0xc4, 0xc6, 0x13, 0x98, 0x4b, 0x8d, 0x0f, 0x84, 0x4b, +0xdc, 0x08, 0x19, 0xf3, 0x42, 0x06, 0xd2, 0x5a, 0xac, 0xa9, 0xf5, 0x6e, 0x0c, 0x16, 0xea, 0x3e, +0xd2, 0xfe, 0xc9, 0x1e, 0x0f, 0xce, 0xff, 0x21, 0x10, 0x03, 0x32, 0x20, 0xf4, 0x6c, 0x59, 0xaf, +0x0f, 0x21, 0xbc, 0x30, 0x78, 0x4f, 0xd9, 0x61, 0x1f, 0x0f, 0x2e, 0x62, 0x23, 0xd9, 0x92, 0xc6, +0x4c, 0xd9, 0x2c, 0x3f, 0x1c, 0x30, 0x68, 0xba, 0xae, 0x1e, 0x04, 0x7c, 0xce, 0x64, 0x07, 0xe1, +0xe6, 0x7c, 0x40, 0x60, 0x64, 0x60, 0xca, 0x04, 0x8d, 0x73, 0xb3, 0x52, 0x1c, 0x1d, 0xcd, 0xda, +0x1e, 0x1f, 0x53, 0x42, 0x7c, 0x0e, 0x1a, 0xa3, 0x1b, 0x93, 0x18, 0x0e, 0xb1, 0xd4, 0x01, 0xb0, +0x10, 0xaf, 0x03, 0xe1, 0xef, 0x4f, 0x2d, 0x7b, 0x0f, 0xcf, 0x85, 0xec, 0x2f, 0xbf, 0x28, 0x1c, +0xad, 0x70, 0x49, 0x93, 0x0c, 0x21, 0xa9, 0xa3, 0x62, 0xa3, 0x3c, 0xc9, 0x36, 0xd1, 0x12, 0x23, +0x24, 0x9b, 0xd9, 0xcb, 0x3b, 0x03, 0xa7, 0x02, 0x60, 0xc0, 0x24, 0x40, 0x33, 0xa2, 0xfb, 0x82, +0xb2, 0xaa, 0xaa, 0x02, 0x82, 0xb5, 0x0c, 0x63, 0x00, 0x4c, 0x01, 0x16, 0x4e, 0x77, 0xe0, 0xa8, +0x6c, 0x62, 0x0b, 0xe8, 0xdc, 0xb2, 0x2d, 0x98, 0x3e, 0x0f, 0x9a, 0xfd, 0x66, 0xce, 0x9a, 0x3f, +0x22, 0xe8, 0x9d, 0x2e, 0xbc, 0x36, 0x2c, 0x96, 0x85, 0xcc, 0x3c, 0x36, 0x6c, 0xd8, 0x00, 0x66, +0xb7, 0x0d, 0x6c, 0xd8, 0x60, 0x10, 0x33, 0xb4, 0x50, 0x94, 0x6c, 0x64, 0x6f, 0x0f, 0x21, 0x2f, +0x60, 0x30, 0x77, 0x6c, 0xef, 0x9a, 0xa2, 0x00, 0x88, 0x58, 0x9a, 0xef, 0xa1, 0x32, 0x33, 0x9d, +0x62, 0xff, 0x5e, 0x92, 0x04, 0xc1, 0x10, 0x29, 0xa8, 0x0c, 0xe2, 0xf1, 0x33, 0xb1, 0x8a, 0xcb, +0x98, 0x12, 0x5f, 0x09, 0x73, 0x0c, 0xff, 0x64, 0x10, 0x33, 0xa4, 0x50, 0x0f, 0x62, 0xd0, 0x89, +0x7e, 0x10, 0x7f, 0x34, 0x18, 0x2c, 0x06, 0x3e, 0x04, 0x3d, 0xbe, 0x22, 0x97, 0x03, 0xf6, 0x64, +0x1d, 0xbf, 0x1f, 0x17, 0x36, 0xc6, 0x0f, 0x30, 0x12, 0x58, 0x3f, 0xc7, 0x92, 0x3f, 0x0f, 0xb0, +0x02, 0x53, 0xcc, 0x35, 0xac, 0x0f, 0x48, 0x26, 0x00, 0x19, 0x44, 0x33, 0xb3, 0x50, 0x40, 0xbd, +0x60, 0x47, 0x9f, 0xb0, 0x90, 0x7f, 0x36, 0xac, 0xb7, 0x9f, 0x6f, 0x51, 0x84, 0xb6, 0x9c, 0xb3, +0xcc, 0xcc, 0xff, 0x26, 0x6c, 0x1f, 0x30, 0xc3, 0xca, 0x2f, 0xd2, 0xb6, 0x2c, 0x1f, 0x0c, 0x01, +0x4a, 0x93, 0x90, 0x03, 0x66, 0x0c, 0x60, 0xc0, 0xc3, 0x04, 0x68, 0x7c, 0xa3, 0xcc, 0x06, 0xf0, +0x0e, 0xbe, 0x53, 0x2c, 0x8f, 0xc6, 0xdd, 0x40, 0x7f, 0xc6, 0x32, 0x24, 0xc6, 0xbc, 0x16, 0x9f, +0x6e, 0x09, 0x3f, 0x0c, 0x21, 0x10, 0xb3, 0x0b, 0x23, 0x39, 0x02, 0x7b, 0x5f, 0x00, 0x5a, 0x42, +0xbb, 0x85, 0x2c, 0x10, 0x12, 0x42, 0xe7, 0x58, 0xdf, 0xbd, 0x30, 0x62, 0x36, 0xec, 0x6f, 0x2b, +0x4a, 0x33, 0x51, 0x2a, 0xca, 0x66, 0x19, 0x00, 0xe8, 0x41, 0xff, 0x11, 0xb2, 0x1d, 0x2b, 0x9b, +0x94, 0x2a, 0x22, 0x60, 0x0a, 0x12, 0xb1, 0x90, 0x4c, 0x29, 0x58, 0x21, 0x0c, 0xa2, 0x7c, 0x33, +0xaa, 0xa0, 0x42, 0x11, 0x89, 0x09, 0x1e, 0x18, 0x70, 0x03, 0x09, 0x2e, 0x76, 0x01, 0x13, 0x01, +0xd0, 0xcb, 0x80, 0xff, 0xd9, 0x7b, 0x1b, 0x29, 0x0d, 0x32, 0x60, 0xfb, 0x30, 0x60, 0x76, 0xf9, +0x8b, 0x38, 0x76, 0x2b, 0x7b, 0x09, 0x61, 0x45, 0x62, 0xd9, 0x53, 0x5b, 0x76, 0xf6, 0x0d, 0x44, +0x60, 0x59, 0x6f, 0xe0, 0x32, 0xef, 0x3c, 0x37, 0x30, 0xed, 0x0d, 0x96, 0xbd, 0x29, 0x0d, 0x2c, +0x03, 0xe9, 0x12, 0x06, 0xe7, 0x2d, 0x03, 0xe5, 0x60, 0x19, 0xa4, 0x42, 0x35, 0xe3, 0x18, 0x60, +0xc0, 0x6e, 0xe1, 0x18, 0x70, 0xce, 0xdf, 0x01, 0x1b, 0x99, 0x1b, 0xc8, 0xc6, 0xc6, 0x0d, 0x65, +0xc0, 0xd9, 0xd9, 0xb2, 0xfb, 0x0d, 0x11, 0x6f, 0x37, 0xb3, 0x24, 0xe5, 0x42, 0xf4, 0x66, 0x37, +0x18, 0x70, 0x64, 0x20, 0x02, 0xc0, 0x1d, 0xcf, 0xe6, 0x7c, 0x80, 0x80, 0x65, 0xcd, 0x19, 0xf0, +0xcc, 0xcb, 0xcb, 0x80, 0xca, 0xe0, 0x54, 0x63, 0x9c, 0x30, 0xc7, 0xd8, 0x70, 0x58, 0x06, 0xc5, +0x09, 0x4b, 0xb1, 0x17, 0x65, 0x6f, 0x0d, 0xb5, 0x96, 0xbd, 0x29, 0xa7, 0x2c, 0x03, 0xbd, 0x12, +0x06, 0xbb, 0x2b, 0x03, 0xb9, 0x84, 0x01, 0xb7, 0xc5, 0x80, 0xb5, 0x0f, 0x98, 0x53, 0xb3, 0x84, +0x01, 0xb2, 0xe0, 0x80, 0xb1, 0xcd, 0x19, 0xaf, 0x63, 0x6e, 0xc3, 0xb6, 0xc3, 0x85, 0x1f, 0x0d, +0xcc, 0xe8, 0x36, 0x6e, 0xda, 0x3c, 0x80, 0x07, 0xab, 0x18, 0xf0, 0xaa, 0xa8, 0x03, 0x16, 0xa6, +0x06, 0x31, 0x33, 0x60, 0x55, 0xb0, 0x30, 0x9b, 0x48, 0x18, 0x99, 0x24, 0x0c, 0x97, 0x58, 0x06, +0x95, 0x10, 0x0f, 0x94, 0x42, 0x64, 0x33, 0x30, 0x03, 0x8b, 0x03, 0x1e, 0x8a, 0x89, 0x10, 0x09, +0x00, 0x64, 0x33, 0xcb, 0x80, 0x79, 0xc0, 0x80, 0x76, 0x77, 0x20, 0xdc, 0xdf, 0xa9, 0xc2, 0x33, +0x92, 0x01, 0x67, 0x18, 0xd0, 0x03, 0x65, 0x01, 0x1a, 0xe9, 0x45, 0x26, 0xf6, 0x09, 0xa9, 0x95, +0x9b, 0x3a, 0xb0, 0xc6, 0x0d, 0x30, 0xc6, 0x4a, 0xb7, 0xd7, 0x0c, 0x48, 0x59, 0x64, 0xb7, 0x0d, +0x3c, 0x66, 0x42, 0x0e, 0x00, 0x19, 0x44, 0x33, 0xb1, 0x10, 0x38, 0x3b, 0x73, 0x0e, 0x06, 0x30, +0x6f, 0x61, 0x09, 0x30, 0xd2, 0x69, 0x60, 0xd3, 0x01, 0x13, 0x78, 0xbd, 0x92, 0x42, 0x4e, 0x64, +0x97, 0x1b, 0x30, 0x29, 0x30, 0x60, 0x30, 0xc0, 0x6c, 0x7c, 0x0a, 0x20, 0x64, 0x3a, 0x01, 0x33, +0x28, 0x03, 0x96, 0x37, 0x35, 0x30, 0x64, 0xe0, 0x03, 0x1e, 0x34, 0x33, 0xc6, 0x2e, 0x7c, 0x6f, +0xc6, 0x59, 0x42, 0x0d, 0x35, 0x6b, 0x0b, 0x03, 0x92, 0x97, 0x2b, 0x13, 0x2c, 0x1a, 0xca, 0x80, +0x27, 0x0c, 0x38, 0xfe, 0x22, 0x01, 0x8b, 0xa9, 0x8c, 0x1f, 0x63, 0xe1, 0x46, 0x34, 0x73, 0x80, +0x54, 0x30, 0xc0, 0x19, 0xbc, 0x62, 0x81, 0x6d, 0x40, 0x06, 0x13, 0x60, 0xc0, 0x18, 0x0f, 0x0c, +0x58, 0x0d, 0x18, 0x44, 0x33, 0x40, 0x01, 0x26, 0x62, 0xfa, 0x28, 0x46, 0xff, 0x8c, 0x4e, 0xd6, +0x76, 0xf6, 0x30, 0x1a, 0x7c, 0xf0, 0x63, 0x6e, 0x76, 0x17, 0x07, 0x60, 0x6c, 0x93, 0x30, 0x17, +0x38, 0x93, 0x98, 0xe3, 0x05, 0xa3, 0x70, 0xd2, 0xba, 0x09, 0xef, 0x07, 0x30, 0x46, 0xc1, 0x3f, +0xc0, 0xcc, 0x0d, 0x3c, 0x1f, 0x07, 0xc7, 0x5c, 0x17, 0x07, 0xc6, 0x10, 0x62, 0x10, 0xa4, 0x28, +0xe7, 0x47, 0x27, 0xb1, 0x19, 0x41, 0x2c, 0xf8, 0x35, 0x42, 0xd5, 0xec, 0x47, 0x0b, 0x7f, 0x6e, +0x97, 0xa0, 0xa3, 0x96, 0xce, 0x46, 0xc1, 0x41, 0x47, 0x37, 0x1b, 0x57, 0x07, 0x37, 0x23, 0x7e, +0x8f, 0x70, 0xb3, 0x07, 0x1f, 0xda, 0x89, 0x2b, 0x06, 0x17, 0x29, 0x81, 0x0e, 0x1e, 0xbd, 0x27, +0x5f, 0x47, 0x8f, 0x5e, 0x5a, 0x3d, 0x23, 0x59, 0x3a, 0x6c, 0x30, 0xda, 0x0f, 0x6c, 0xb8, 0x4e, +0xd4, 0xd1, 0x48, 0x3c, 0x33, 0x7a, 0x47, 0x42, 0x30, 0x7b, 0xf7, 0x9f, 0xe6, 0x66, 0xd5, 0xd9, +0x5f, 0x30, 0x0a, 0x2a, 0x20, 0xdc, 0x07, 0x64, 0xf4, 0xfc, 0x1f, 0x0d, 0xa3, 0x19, 0xd1, 0x19, +0x12, 0x7c, 0x31, 0x9a, 0x0c, 0x0b, 0xed, 0x83, 0xfe, 0x04, 0x63, 0x6b, 0xbd, 0xfb, 0x7e, 0x33, +0x66, 0xcc, 0x0f, 0x07, 0x7a, 0x36, 0x6a, 0xdf, 0x4c, 0xa8, 0x11, 0xf4, 0xed, 0x0e, 0xc1, 0x16, +0x66, 0x33, 0x70, 0x5f, 0x44, 0x66, 0x09, 0x02, 0x83, 0x33, 0x84, 0x16, 0x97, 0x37, 0xcf, 0xda, +0x9c, 0x07, 0x60, 0x30, 0x87, 0x26, 0xb2, 0x88, 0x43, 0xb1, 0x84, 0x32, 0x33, 0x14, 0x1c, 0xbc, +0x65, 0x0e, 0x1c, 0xbf, 0xfa, 0x62, 0x42, 0x8d, 0x82, 0x0c, 0x33, 0x98, 0xd0, 0x5e, 0x62, 0x76, +0x17, 0x7f, 0x88, 0x0c, 0x33, 0xef, 0x50, 0x28, 0xcd, 0x71, 0xe8, 0x76, 0x18, 0x6c, 0x22, 0xca, +0x47, 0x9b, 0xf6, 0x7b, 0x18, 0xf7, 0x10, 0x59, 0x38, 0x63, 0x00, 0x17, 0x30, 0x08, 0xcb, 0x1f, +0x9f, 0x11, 0x28, 0xe6, 0x0b, 0x16, 0xfb, 0x06, 0x08, 0x37, 0x07, 0x85, 0x32, 0x33, 0x0d, 0x12, +0x20, 0x30, 0xc3, 0x82, 0x3f, 0x1b, 0x3d, 0x0e, 0x57, 0x37, 0xc6, 0xa2, 0xd5, 0xbc, 0xcc, 0xe1, +0x1d, 0x5f, 0x0f, 0x5f, 0x2c, 0xde, 0x07, 0x9f, 0xc5, 0x1b, 0x7c, 0xef, 0x8b, 0x09, 0xab, 0x82, +0x8f, 0xe2, 0xc0, 0x5a, 0x8b, 0x17, 0x89, 0x93, 0xd1, 0xdc, 0x07, 0x47, 0xb3, 0x98, 0x77, 0x89, +0xcd, 0x1e, 0xaf, 0x0f, 0x38, 0xa3, 0x17, 0x9f, 0x0c, 0x8b, 0x77, 0x79, 0x77, 0x6b, 0x62, 0x00, +0x7e, 0x62, 0xcb, 0x5d, 0x0a, 0xfd, 0x1f, 0x2a, 0xe1, 0x32, 0xe4, 0x3a, 0xf6, 0x2a, 0x5f, 0x86, +0x82, 0x00, 0x34, 0x49, 0x80, 0x33, 0x06, 0x16, 0x3e, 0x78, 0x98, 0xb7, 0x87, 0x18, 0xb2, 0x2e, +0x18, 0xe2, 0xb0, 0x21, 0x3c, 0x16, 0x0f, 0x2b, 0x7a, 0x19, 0xc4, 0x78, 0x33, 0x90, 0x03, 0xb5, +0x72, 0x3c, 0x19, 0x53, 0x9d, 0x4c, 0x14, 0x91, 0x82, 0x92, 0xc8, 0x82, 0x20, 0x51, 0x21, 0x83, +0x27, 0x61, 0x10, 0x33, 0x82, 0x50, 0x84, 0x0c, 0x87, 0x85, 0x41, 0x33, 0x0c, 0x82, 0x97, 0x64, +0xa3, 0x00, 0x83, 0x60, 0xa7, 0x10, 0x21, 0x08, 0x65, 0x33, 0xc8, 0x20, 0xc7, 0x19, 0x44, 0x33, +0x08, 0x42, 0x11, 0x32, 0xe7, 0x54, 0x06, 0x33, 0x2c, 0x82, 0x07, 0x41, 0x84, 0x08, 0x96, 0x33, +0xac, 0xb2, 0x17, 0x65, 0x11, 0x07, 0x8b, 0x20, 0x27, 0xd9, 0x09, 0x04, 0x08, 0x0f, 0x11, 0x9c, +0x58, 0x65, 0x27, 0xc8, 0x80, 0xa7, 0x10, 0xa3, 0x22, 0x64, 0x33, 0x2a, 0x03, 0xb7, 0x19, 0x44, +0x33, 0x62, 0x10, 0x2a, 0x09, 0x27, 0x06, 0x11, 0x33, 0x62, 0x55, 0x28, 0x09, 0x67, 0x19, 0x44, +0x33, 0x22, 0x14, 0x20, 0x09, 0xd7, 0x19, 0xc4, 0x33, 0x22, 0x14, 0x02, 0x0b, 0x47, 0x10, 0xa1, +0x46, 0x65, 0x33, 0xb6, 0x20, 0x87, 0x60, 0xb6, 0x42, 0x36, 0x31, 0x09, 0x95, 0x05, 0x97, 0xae, +0x04, 0xcf, 0x61, 0x10, 0x33, 0x20, 0x42, 0x2b, 0xb0, 0xc7, 0x60, 0x10, 0x33, 0x82, 0x08, 0x10, +0xcb, 0xd7, 0x1c, 0x65, 0x33, 0x66, 0x88, 0x94, 0xb1, 0x0c, 0x07, 0x95, 0x00, 0x97, 0x20, 0xb6, +0xce, 0xc6, 0x84, 0x10, 0xa7, 0x94, 0x41, 0x33, 0x02, 0x11, 0xa9, 0x40, 0x96, 0x01, 0xf9, 0xc2, +0x20, 0x33, 0x04, 0x0b, 0x48, 0x48, 0x43, 0xb0, 0x0c, 0xe9, 0x91, 0x44, 0x51, 0x30, 0x60, 0xe1, +0x20, 0x86, 0x7c, 0xb0, 0xc8, 0x33, 0x62, 0x19, 0xdb, 0x8b, 0x0c, 0x33, 0x48, 0x04, 0x97, 0x83, +0x48, 0x33, 0x41, 0x22, 0x12, 0x16, 0x93, 0xcb, 0x20, 0x33, 0x59, 0x04, 0xa1, 0x08, 0x16, 0xc1, +0xb2, 0x93, 0x42, 0x16, 0xaf, 0x04, 0x87, 0x13, 0x56, 0x59, 0xaf, 0x32, 0x20, 0x5f, 0x44, 0x00, +0x48, 0x18, 0x33, 0xc8, 0x80, 0x6d, 0x06, 0x91, 0x33, 0x58, 0x14, 0xc8, 0x80, 0xcf, 0x41, 0x84, +0x58, 0x91, 0x33, 0x48, 0x82, 0x07, 0x06, 0x11, 0x33, 0x48, 0x15, 0x42, 0x82, 0x69, 0x06, 0x31, +0x33, 0x48, 0x15, 0x40, 0x82, 0xcb, 0x44, 0x20, 0x11, 0x19, 0x33, 0x2c, 0x88, 0x03, 0x66, 0x2b, +0x30, 0x41, 0x4c, 0x41, 0x64, 0x11, 0x83, 0x78, 0x08, 0x10, 0x33, 0xb1, 0x02, 0x95, 0x05, 0x3b, +0x0c, 0x62, 0x33, 0x41, 0xac, 0x88, 0x64, 0x49, 0x0c, 0x32, 0x33, 0x56, 0x06, 0x13, 0x12, 0x20, +0xd3, 0x02, 0xc4, 0x71, 0xf1, 0x5a, 0xdb, 0x81, 0x00, 0x7f, 0x0c, 0x22, 0x33, 0x80, 0x00, 0x14, +0x12, 0xa1, 0x20, 0x47, 0x41, 0x04, 0x08, 0x85, 0x33, 0x41, 0x28, 0x77, 0x60, 0x10, 0x33, 0x84, +0x82, 0x7f, 0x19, 0x85, 0x98, 0xa1, 0x20, 0x87, 0x06, 0x31, 0x33, 0x0a, 0x42, 0x44, 0x10, 0x97, +0x08, 0x19, 0x33, 0x41, 0x28, 0xa7, 0x64, 0x10, 0x33, 0xa3, 0x20, 0x37, 0x41, 0x04, 0x0a, 0x82, +0x33, 0x10, 0x32, 0x3f, 0x82, 0x51, 0x37, 0x30, 0x0a, 0x47, 0xc1, 0xec, 0xd3, 0x07, 0x46, 0x46, +0x47, 0x12, 0x20, 0x87, 0x10, 0x0b, 0x88, 0x60, 0x33, 0x8c, 0x04, 0x8f, 0x90, 0x41, 0x33, 0x80, +0x58, 0x11, 0x4a, 0xc7, 0x50, 0x06, 0x33, 0x04, 0x88, 0xe7, 0x41, 0x8c, 0x58, 0x90, 0x33, 0xc8, +0x80, 0x1f, 0x19, 0x44, 0x33, 0x88, 0x11, 0x08, 0x0c, 0x57, 0x06, 0xb1, 0x33, 0x88, 0x50, 0x85, +0x0c, 0x77, 0x20, 0x86, 0x1b, 0x88, 0x32, 0x7f, 0x98, 0x45, 0x68, 0x2b, 0x83, 0x33, 0x18, 0x10, +0x97, 0x20, 0x16, 0x10, 0xc9, 0x33, 0x88, 0x18, 0x9f, 0x10, 0x32, 0x33, 0x20, 0x0e, 0xf1, 0xc1, +0x12, 0x37, 0x1c, 0x56, 0xff, 0xd3, 0x21, 0x40, 0x07, 0x0c, 0x22, 0x33, 0x92, 0xa7, 0xe9, 0x74, +0x50, 0xf0, 0xe4, 0x5a, 0xd1, 0x72, 0x91, 0x55, 0x67, 0x92, 0x14, 0x80, 0xa0, 0x15, 0xc8, 0x22, +0x15, 0xa3, 0x16, 0x7a, 0xf8, 0x4e, 0xab, 0xa0, 0x66, 0x67, 0x20, 0x28, 0x01, 0xab, 0x15, 0x9c, +0x5b, 0x66, 0x15, 0x60, 0x67, 0x7a, 0x50, 0x7c, 0xc2, 0x05, 0x1f, 0x03, 0xc2, 0x7c, 0x41, 0x58, +0x67, 0x90, 0x53, 0x1d, 0xbf, 0x3c, 0x19, 0x65, 0x05, 0x99, 0x91, 0x41, 0x33, 0x92, 0x14, 0x82, +0x82, 0x42, 0xde, 0x00, 0x05, 0x2b, 0x48, 0x59, 0x67, 0x2d, 0x21, 0x53, 0x25, 0x00, 0x6a, 0x0b, +0x6a, 0x8b, 0x54, 0x21, 0xb2, 0x60, 0x34, 0x07, 0x5b, 0xf6, 0x10, 0x08, 0x28, 0x0f, 0x49, 0xd0, +0xa6, 0xab, 0x60, 0x67, 0x54, 0x2b, 0x20, 0x61, 0xad, 0x2a, 0xab, 0x67, 0x45, 0x70, 0x66, 0x00, +0x4b, 0x24, 0x0f, 0xef, 0xc0, 0x2a, 0x82, 0x03, 0x8b, 0x0a, 0x23, 0xdf, 0xde, 0xff, 0x3c, 0x42, +0x99, 0xa5, 0xa1, 0xa5, 0x99, 0x42, 0x0e, 0xb2, 0x0a, 0x67, 0x05, 0x90, 0x28, 0x65, 0x83, 0x32, +0x03, 0x6d, 0xac, 0x82, 0x67, 0x00, 0x2a, 0x01, 0x10, 0xb0, 0xec, 0x09, 0x00, 0x95, 0x55, 0x67, +0x46, 0x00, 0x0a, 0x03, 0xf9, 0x10, 0x0c, 0x70, 0x92, 0xef, 0x07, 0x18, 0xf4, 0xfe, 0x84, 0x01, +0xf2, 0x60, 0xc0, 0x00, 0xef, 0x0c, 0x18, 0xed, 0x55, 0xb0, 0x80, 0x91, 0x67, 0x05, 0xcb, 0xe9, +0x17, 0x59, 0x67, 0x66, 0x29, 0x82, 0x00, 0xc7, 0x40, 0x0a, 0x16, 0x60, 0xdb, 0xa4, 0x08, 0x9d, +0x50, 0xaf, 0x38, 0x44, 0xb1, 0x5f, 0xcd, 0x44, 0x38, 0x2a, 0xac, 0x82, 0xb8, 0x67, 0x19, 0xb0, +0xd3, 0x0f, 0x08, 0xd1, 0x2a, 0x30, 0x00, 0xc2, 0x67, 0x01, 0x2b, 0x82, 0x81, 0x17, 0x02, 0xac, +0x67, 0x94, 0xa0, 0x52, 0x61, 0xe0, 0xb3, 0x0a, 0x67, 0x20, 0x05, 0xc3, 0x01, 0xa3, 0xd2, 0x0e, +0x51, 0x93, 0x14, 0x8c, 0xbf, 0xa3, 0x64, 0xc1, 0xbb, 0x15, 0x0c, 0xa3, 0x60, 0x67, 0xb0, 0x15, +0x0c, 0x2a, 0x64, 0x67, 0x14, 0x1c, 0x82, 0x6c, 0x09, 0xef, 0x77, 0x15, 0xa4, 0x0a, 0x66, 0x67, +0x15, 0x04, 0xd7, 0x82, 0x10, 0x93, 0x0c, 0x0a, 0x0f, 0x04, 0x35, 0xd0, 0x9b, 0x7b, 0x07, 0x02, +0x13, 0xc9, 0x28, 0xac, 0x67, 0x74, 0xa8, 0x08, 0xd3, 0x2a, 0x98, 0x18, 0x87, 0xca, 0x67, 0x0d, +0x0a, 0xb7, 0xff, 0x54, 0x68, 0x69, 0x73, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x04, 0x69, 0x6c, 0xff, +0xf6, 0x65, 0x20, 0x68, 0x61, 0x0d, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x63, 0x72, 0xb7, 0xfd, 0x65, +0x61, 0x74, 0x65, 0x64, 0x2f, 0x02, 0x69, 0x06, 0xfb, 0x37, 0x13, 0x79, 0x20, 0x43, 0x50, 0x49, +0x61, 0x64, 0x09, 0xdf, 0x7e, 0x56, 0x31, 0x2e, 0x32, 0x30, 0x37, 0x43, 0x6f, 0x70, 0x79, 0xff, +0xf2, 0x72, 0x69, 0x67, 0x68, 0x28, 0x43, 0x29, 0x20, 0x31, 0x39, 0x39, 0x7f, 0xdd, 0x33, 0x2d, +0x04, 0x36, 0x28, 0x6b, 0x6f, 0x73, 0xfd, 0xb7, 0x74, 0x54, 0x40, 0x61, 0x63, 0x6d, 0x2e, 0x6f, +0x72, 0x67, 0x76, 0xb7, 0x1f, 0x4b, 0x0f, 0x61, 0x20, 0x4b, 0x15, 0x0f, 0x36, 0x29, 0x71, 0x70, +0x72, 0x6f, 0x77, 0xff, 0x67, 0x72, 0x61, 0x6d, 0x20, 0x6d, 0x61, 0x79, 0x6f, 0x20, 0x75, 0x73, +0xad, 0x75, 0x63, 0x66, 0x72, 0x09, 0xd6, 0xda, 0x6f, 0x66, 0x7a, 0x84, 0x36, 0xbf, 0xb5, 0x09, +0x7e, 0x20, 0x79, 0x6f, 0x75, 0x72, 0xad, 0x6d, 0x11, 0x77, 0x8d, 0x69, 0x00, 0xf8, 0x73, 0x6b, +0x2e, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0xff, 0xa4, 0xe8, 0x3a, 0x00, 0x72, 0xfa, +0x41, 0xe8, 0x2f, 0x00, 0xe3, 0x3b, 0x73, 0xf9, 0x83, 0xe9, 0x03, 0x72, 0x06, 0x88, 0xcc, 0xac, +0xf7, 0xd0, 0x95, 0x31, 0xc9, 0xe8, 0x1b, 0x00, 0x11, 0xc9, 0x75, 0x08, 0x41, 0xe8, 0x13, 0x00, +0x73, 0xfb, 0x41, 0x41, 0x81, 0xfd, 0x00, 0xf3, 0x83, 0xd1, 0x01, 0x8d, 0x03, 0x96, 0xf3, 0xa4, +0x96, 0xeb, 0xc8, 0xe8, 0x02, 0x00, 0x11, 0xc9, 0x01, 0xdb, 0x75, 0x04, 0xad, 0x11, 0xc0, 0x93, +0xc3, 0x5e, 0xb9, 0x01, 0x00, 0xac, 0x2c, 0xe8, 0x3c, 0x01, 0x77, 0xf9, 0x8b, 0x1c, 0x86, 0xdf, +0x29, 0xf3, 0x89, 0x1c, 0xad, 0xe2, 0xee, 0xc3 }; diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp new file mode 100644 index 00000000..22f855cb --- /dev/null +++ b/src/dos/dos_keyboard_layout.cpp @@ -0,0 +1,1058 @@ +/* + * Copyright (C) 2002-2006 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" +#include "bios.h" +#include "setup.h" +#include "support.h" +#include "../ints/int10.h" +#include "regs.h" +#include "callback.h" +#include "mapper.h" +#include "drives.h" +#include "dos_inc.h" + +#include "dos_codepages.h" +#include "dos_keyboard_layout_data.h" + + +static FILE* OpenDosboxFile(const char* name) { + Bit8u drive; + char fullname[DOS_PATHLENGTH]; + + localDrive* ldp=0; + // try to build dos name + if (DOS_MakeName((char*)name,fullname,&drive)) { + try { + // try to open file on mounted drive first + ldp=dynamic_cast(Drives[drive]); + if (ldp) { + FILE *tmpfile=ldp->GetSystemFilePtr(fullname, "rb"); + if (tmpfile != NULL) return tmpfile; + } + } + catch(...) {} + } + FILE *tmpfile=fopen(name, "rb"); + return tmpfile; +} + + +class keyboard_layout { +public: + keyboard_layout() { + this->reset(); + language_codes=NULL; + use_foreign_layout=false; + sprintf(current_keyboard_file_name, "none"); + }; + + ~keyboard_layout(); + + // read in a codepage from a .cpi-file + Bitu read_codepage_file(const char* codepage_file_name, Bit32s codepage_id); + Bit16u extract_codepage(const char* keyboard_file_name); + // read in a keyboard layout from a .kl-file + Bitu read_keyboard_file(const char* keyboard_file_name, Bit32s req_cp); + + // call layout_key to apply the current language layout + bool layout_key(Bitu key, Bit8u flags1, Bit8u flags2, Bit8u flags3); + + Bitu switch_keyboard_layout(const char* new_layout, keyboard_layout* &created_layout); + void switch_foreign_layout(); + + +private: + static const Bit8u layout_pages=12; + Bit16u current_layout[(MAX_SCAN_CODE+1)*layout_pages]; + struct { + Bit16u required_flags,forbidden_flags; + Bit16u required_userflags,forbidden_userflags; + } current_layout_planes[layout_pages-4]; + Bit8u additional_planes,used_lock_modifiers; + + // diacritics table + Bit8u diacritics[2048]; + Bit16u diacritics_entries; + Bit16u diacritics_character; + Bit16u user_keys; + + char current_keyboard_file_name[256]; + bool use_foreign_layout; + + // language code storage used when switching layouts + char** language_codes; + Bitu language_code_count; + + void reset(); + void read_keyboard_file(Bit32s specific_layout); + Bitu read_keyboard_file(const char* keyboard_file_name, Bit32s specific_layout, Bit32s requested_codepage); + bool map_key(Bitu key, Bit16u layouted_key, bool is_command, bool is_keypair); +}; + + +keyboard_layout::~keyboard_layout() { + if (language_codes) { + for (Bitu i=0; iread_keyboard_file(keyboard_file_name, -1, req_cp); +} + +// switch to a different layout +void keyboard_layout::read_keyboard_file(Bit32s specific_layout) { + if (strcmp(current_keyboard_file_name,"none")) + this->read_keyboard_file(current_keyboard_file_name, specific_layout, dos.loaded_codepage); +} + +static Bit32u read_kcl_file(const char* kcl_file_name, const char* layout_id) { + FILE* tempfile = OpenDosboxFile(kcl_file_name); + if (tempfile==0) return 0; + + static Bit8u rbuf[8192]; + + // check ID-bytes of file + Bit32u dr=(Bit32u)fread(rbuf, sizeof(Bit8u), 7, tempfile); + if ((dr<7) || (rbuf[0]!=0x4b) || (rbuf[1]!=0x43) || (rbuf[2]!=0x46)) { + fclose(tempfile); + return 0; + } + + fseek(tempfile, 7+rbuf[6], SEEK_SET); + + for (;;) { + Bit32u cur_pos=(Bit32u)(ftell(tempfile)); + dr=(Bit32u)fread(rbuf, sizeof(Bit8u), 5, tempfile); + if (dr<5) break; + Bit16u len=host_readw(&rbuf[0]); + + Bit8u data_len=rbuf[2]; + + char lng_codes[256]; + // get all language codes for this layout + for (Bitu i=0; ireset(); + + if (specific_layout==-1) strcpy(current_keyboard_file_name, keyboard_file_name); + if (!strcmp(keyboard_file_name,"none")) return KEYB_NOERROR; + + static Bit8u read_buf[65535]; + Bit32u read_buf_size, read_buf_pos, bytes_read; + Bit32u start_pos=5; + + char nbuf[512]; + sprintf(nbuf, "%s.kl", keyboard_file_name); + FILE* tempfile = OpenDosboxFile(nbuf); + if (tempfile==NULL) { + // see if build-in keyboard layout is available, then copy it + if (!strncasecmp(keyboard_file_name,"BG",2)) { + read_buf_size=687; + for (Bitu i=0; i(layout_pages-4)) additional_planes=(layout_pages-4); + + // seek to plane descriptor + read_buf_pos=start_pos+0x14+submappings*8; + for (Bit16u cplane=0; cplane0)) { + // add all available mappings + for (Bit16u addmap=0; addmapadditional_planes+2) break; + Bitu charptr=read_buf_pos+addmap*((read_buf[read_buf_pos-2]&0x80)?2:1); + Bit16u kchar=read_buf[charptr]; + if (read_buf[read_buf_pos-2]&0x80) kchar|=read_buf[charptr+1]<<8; // scancode/char pair + + if (kchar!=0) { // key remapped + // overwrite mapping + current_layout[scan*layout_pages+addmap]=kchar; + // clear command bit + current_layout[scan*layout_pages+layout_pages-2]&=~(1<use_foreign_layout=true; + return KEYB_NOERROR; + } + + LOG(LOG_BIOS,LOG_ERROR)("No matching keyboard layout found in %s",keyboard_file_name); + + // reset layout data (might have been changed by general layout) + this->reset(); + + return KEYB_LAYOUTNOTFOUND; +} + +bool keyboard_layout::layout_key(Bitu key, Bit8u flags1, Bit8u flags2, Bit8u flags3) { + if (key>MAX_SCAN_CODE) return false; + if (!this->use_foreign_layout) return false; + + bool is_special_pair=(current_layout[key*layout_pages+layout_pages-1] & 0x80)==0x80; + + if ((((flags1&used_lock_modifiers)&0x7c)==0) && ((flags3&2)==0)) { + // check if shift/caps is active: + // (left_shift OR right_shift) XOR (key_affected_by_caps AND caps_locked) + if ((((flags1&2)>>1) | (flags1&1)) ^ (((current_layout[key*layout_pages+layout_pages-1] & 0x40) & (flags1 & 0x40))>>6)) { + // shift plane + if (current_layout[key*layout_pages+1]!=0) { + // check if command-bit is set for shift plane + bool is_command=(current_layout[key*layout_pages+layout_pages-2]&2)!=0; + if (this->map_key(key, current_layout[key*layout_pages+1], + is_command, is_special_pair)) return true; + } + } else { + // normal plane + if (current_layout[key*layout_pages]!=0) { + // check if command-bit is set for normal plane + bool is_command=(current_layout[key*layout_pages+layout_pages-2]&1)!=0; + if (this->map_key(key, current_layout[key*layout_pages], + is_command, is_special_pair)) return true; + } + } + } + + // calculate current flags + Bit16u current_flags=(flags1&0x7f) | (((flags2&3) | (flags3&0xc))<<8); + if (flags1&3) current_flags|=0x4000; // either shift key active + if (flags3&2) current_flags|=0x1000; // e0 prefixed + + // check all planes if flags fit + for (Bit16u cplane=0; cplane>(cplane+2))&1)!=0; + if (this->map_key(key, current_layout[key*layout_pages+2+cplane], + is_command, is_special_pair)) return true; + } else break; // abort plane checking + } + } + + if (diacritics_character>0) { + // ignore state-changing keys + switch(key) { + case 0x1d: /* Ctrl Pressed */ + case 0x2a: /* Left Shift Pressed */ + case 0x36: /* Right Shift Pressed */ + case 0x38: /* Alt Pressed */ + case 0x3a: /* Caps Lock */ + case 0x45: /* Num Lock */ + case 0x46: /* Scroll Lock */ + break; + default: + if (diacritics_character-200>=diacritics_entries) { + diacritics_character=0; + return true; + } + Bit16u diacritics_start=0; + // search start of subtable + for (Bit16u i=0; i=200) && (key_command<235)) { + // diacritics command + diacritics_character=key_command; + if (diacritics_character-200>=diacritics_entries) diacritics_character=0; + return true; + } else if ((key_command>=120) && (key_command<129)) { + // switch layout command + this->read_keyboard_file(key_command-119); + return true; + } else if ((key_command>=180) && (key_command<188)) { + // switch user key off + user_keys&=~(1<<(key_command-180)); + return true; + } else if ((key_command>=188) && (key_command<196)) { + // switch user key on + user_keys|=(1<<(key_command-188)); + return true; + } else if (key_command==160) return true; // nop command + } else { + // non-command + if (diacritics_character>0) { + if (diacritics_character-200>=diacritics_entries) diacritics_character = 0; + else { + Bit16u diacritics_start=0; + // search start of subtable + for (Bit16u i=0; i(&nbuf[strsz-1])); + if (plc=='I') { + // try CPX-extension as well + nbuf[strsz-1]='X'; + tempfile=OpenDosboxFile(nbuf); + } else if (plc=='X') { + // try CPI-extension as well + nbuf[strsz-1]='I'; + tempfile=OpenDosboxFile(nbuf); + } + } + } + + static Bit8u cpi_buf[65536]; + Bit32u cpi_buf_size=0,size_of_cpxdata=0;; + bool upxfound=false; + Bit16u found_at_pos=5; + if (tempfile==NULL) { + // check if build-in codepage is available + switch (codepage_id) { + case 437: case 850: case 852: case 853: case 857: case 858: + for (Bitu bct=0; bct<6322; bct++) cpi_buf[bct]=font_ega_cpx[bct]; + cpi_buf_size=6322; + break; + case 771: case 772: case 808: case 855: case 866: case 872: + for (Bitu bct=0; bct<5455; bct++) cpi_buf[bct]=font_ega3_cpx[bct]; + cpi_buf_size=5455; + break; + case 737: case 851: case 869: + for (Bitu bct=0; bct<5720; bct++) cpi_buf[bct]=font_ega5_cpx[bct]; + cpi_buf_size=5720; + break; + default: + return KEYB_INVALIDCPFILE; + break; + } + upxfound=true; + found_at_pos=0x29; + size_of_cpxdata=cpi_buf_size; + } else { + Bit32u dr=(Bit32u)fread(cpi_buf, sizeof(Bit8u), 5, tempfile); + // check if file is valid + if (dr<5) { + LOG(LOG_BIOS,LOG_ERROR)("Codepage file %s invalid",cp_filename); + return KEYB_INVALIDCPFILE; + } + // check if non-compressed cpi file + if ((cpi_buf[0]!=0xff) || (cpi_buf[1]!=0x46) || (cpi_buf[2]!=0x4f) || + (cpi_buf[3]!=0x4e) || (cpi_buf[4]!=0x54)) { + // check if dr-dos custom cpi file + if ((cpi_buf[0]==0x7f) && (cpi_buf[1]!=0x44) && (cpi_buf[2]!=0x52) && + (cpi_buf[3]!=0x46) && (cpi_buf[4]!=0x5f)) { + LOG(LOG_BIOS,LOG_ERROR)("Codepage file %s has unsupported DR-DOS format",cp_filename); + return KEYB_INVALIDCPFILE; + } + // check if compressed cpi file + Bit8u next_byte=0; + for (Bitu i=0; i<100; i++) { + fread(&next_byte, sizeof(Bit8u), 1, tempfile); found_at_pos++; + while (next_byte==0x55) { + fread(&next_byte, sizeof(Bit8u), 1, tempfile); found_at_pos++; + if (next_byte==0x50) { + fread(&next_byte, sizeof(Bit8u), 1, tempfile); found_at_pos++; + if (next_byte==0x58) { + fread(&next_byte, sizeof(Bit8u), 1, tempfile); found_at_pos++; + if (next_byte==0x21) { + // read version ID + fread(&next_byte, sizeof(Bit8u), 1, tempfile); + found_at_pos++; + upxfound=true; + break; + } + } + } + } + if (upxfound) break; + } + if (!upxfound) { + LOG(LOG_BIOS,LOG_ERROR)("Codepage file %s invalid: %x",cp_filename,cpi_buf[0]); + return KEYB_INVALIDCPFILE; + } else { + if (next_byte<10) E_Exit("UPX-compressed cpi file, but upx-version too old"); + + // read in compressed CPX-file + fseek(tempfile, 0, SEEK_SET); + size_of_cpxdata=(Bitu)fread(cpi_buf, sizeof(Bit8u), 65536, tempfile); + } + } else { + // standard uncompressed cpi-file + fseek(tempfile, 0, SEEK_SET); + cpi_buf_size=(Bit32u)fread(cpi_buf, sizeof(Bit8u), 65536, tempfile); + } + } + + if (upxfound) { + if (size_of_cpxdata>0xfe00) E_Exit("Size of cpx-compressed data too big"); + + found_at_pos+=19; + // prepare for direct decompression + cpi_buf[found_at_pos]=0xcb; + + Bit16u seg=0; + Bit16u size=0x2000; + if (!DOS_AllocateMemory(&seg,&size)) E_Exit("Not enough free low memory to unpack data"); + MEM_BlockWrite((seg<<4)+0x100,cpi_buf,size_of_cpxdata); + + // setup segments + Bit16u save_ds=SegValue(ds); + Bit16u save_es=SegValue(es); + Bit16u save_ss=SegValue(ss); + Bit32u save_esp=reg_esp; + SegSet16(ds,seg); + SegSet16(es,seg); + SegSet16(ss,seg+0x1000); + reg_esp=0xfffe; + + // let UPX unpack the file + CALLBACK_RunRealFar(seg,0x100); + + SegSet16(ds,save_ds); + SegSet16(es,save_es); + SegSet16(ss,save_ss); + reg_esp=save_esp; + + // get unpacked content + MEM_BlockRead((seg<<4)+0x100,cpi_buf,65536); + cpi_buf_size=65536; + + DOS_FreeMemory(seg); + } + + + start_pos=host_readd(&cpi_buf[0x13]); + number_of_codepages=host_readw(&cpi_buf[start_pos]); + start_pos+=4; + + // search if codepage is provided by file + for (Bit16u test_codepage=0; test_codepagetype==M_TEXT) && (machine==MCH_VGA)) { + INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); + } + INT10_SetupRomMemoryChecksum(); + + return KEYB_NOERROR; + } + + start_pos=host_readd(&cpi_buf[start_pos]); + start_pos+=2; + } + + LOG(LOG_BIOS,LOG_ERROR)("Codepage %i not found",codepage_id); + + return KEYB_INVALIDCPFILE; +} + +Bitu keyboard_layout::switch_keyboard_layout(const char* new_layout, keyboard_layout*& created_layout) { + if (strncasecmp(new_layout,"US",2)) { + // switch to a foreign layout + char tbuf[256]; + strcpy(tbuf, new_layout); + size_t newlen=strlen(tbuf); + + bool language_code_found=false; + // check if language code is present in loaded foreign layout + for (Bitu i=0; iuse_foreign_layout) { + // switch to foreign layout + this->use_foreign_layout=true; + diacritics_character=0; + LOG(LOG_BIOS,LOG_NORMAL)("Switched to layout %s",tbuf); + } + } else { + keyboard_layout * temp_layout=new keyboard_layout(); + Bitu req_codepage=temp_layout->extract_codepage(new_layout); + Bitu kerrcode=temp_layout->read_keyboard_file(new_layout, req_codepage); + if (kerrcode) { + delete temp_layout; + return kerrcode; + } + // ...else keyboard layout loaded successfully, change codepage accordingly + kerrcode=temp_layout->read_codepage_file("auto", req_codepage); + if (kerrcode) { + delete temp_layout; + return kerrcode; + } + // Everything went fine, switch to new layout + created_layout=temp_layout; + } + } else if (this->use_foreign_layout) { + // switch to the US layout + this->use_foreign_layout=false; + diacritics_character=0; + LOG(LOG_BIOS,LOG_NORMAL)("Switched to US layout"); + } + return KEYB_NOERROR; +} + +void keyboard_layout::switch_foreign_layout() { + this->use_foreign_layout=!this->use_foreign_layout; + diacritics_character=0; + if (this->use_foreign_layout) LOG(LOG_BIOS,LOG_NORMAL)("Switched to foreign layout"); + else LOG(LOG_BIOS,LOG_NORMAL)("Switched to US layout"); +} + + +static keyboard_layout* loaded_layout=NULL; + +// CTRL-ALT-F2 switches between foreign and US-layout using this function +static void switch_keyboard_layout(bool pressed) { + if (!pressed) + return; + if (loaded_layout) loaded_layout->switch_foreign_layout(); +} + +// called by int9-handler +bool DOS_LayoutKey(Bitu key, Bit8u flags1, Bit8u flags2, Bit8u flags3) { + if (loaded_layout) return loaded_layout->layout_key(key, flags1, flags2, flags3); + else return false; +} + +Bitu DOS_LoadKeyboardLayout(const char * layoutname, Bit32s codepage, const char * codepagefile) { + keyboard_layout * temp_layout=new keyboard_layout(); + // try to read the layout for the specified codepage + Bitu kerrcode=temp_layout->read_keyboard_file(layoutname, codepage); + if (kerrcode) { + delete temp_layout; + return kerrcode; + } + // ...else keyboard layout loaded successfully, change codepage accordingly + kerrcode=temp_layout->read_codepage_file(codepagefile, codepage); + if (kerrcode) { + delete temp_layout; + return kerrcode; + } + // Everything went fine, switch to new layout + loaded_layout=temp_layout; + return KEYB_NOERROR; +} + +Bitu DOS_SwitchKeyboardLayout(const char* new_layout) { + if (loaded_layout) { + keyboard_layout* changed_layout=NULL; + Bitu ret_code=loaded_layout->switch_keyboard_layout(new_layout, changed_layout); + if (changed_layout) { + // Remove old layout, activate new layout + delete loaded_layout; + loaded_layout=changed_layout; + } + return ret_code; + } else return 0xff; +} + + +class DOS_KeyboardLayout: public Module_base { +public: + DOS_KeyboardLayout(Section* configuration):Module_base(configuration){ + Section_prop * section=static_cast(configuration); + dos.loaded_codepage=437; // US codepage already initialized + loaded_layout=new keyboard_layout(); + + const char * layoutname=section->Get_string("keyboardlayout"); + // try to find a good codepage for the requested layout + Bitu req_codepage=loaded_layout->extract_codepage(layoutname); + + loaded_layout->read_codepage_file("auto", req_codepage); + if (loaded_layout->read_keyboard_file(layoutname, dos.loaded_codepage)) + LOG_MSG("Error loading keyboard layout %s",layoutname); + } + + ~DOS_KeyboardLayout(){ + if ((dos.loaded_codepage!=437) && (CurMode->type==M_TEXT)) { + INT10_ReloadRomFonts(); + dos.loaded_codepage=437; // US codepage + } + if (loaded_layout) { + delete loaded_layout; + loaded_layout=NULL; + } + } +}; + +static DOS_KeyboardLayout* test; + +void DOS_KeyboardLayout_ShutDown(Section* /*sec*/) { + delete test; +} + +void DOS_KeyboardLayout_Init(Section* sec) { + test = new DOS_KeyboardLayout(sec); + sec->AddDestroyFunction(&DOS_KeyboardLayout_ShutDown,true); + MAPPER_AddHandler(switch_keyboard_layout,MK_f2,MMOD1|MMOD2,"sw_layout","Switch Layout"); +} diff --git a/src/dos/dos_keyboard_layout_data.h b/src/dos/dos_keyboard_layout_data.h new file mode 100644 index 00000000..4b200b5c --- /dev/null +++ b/src/dos/dos_keyboard_layout_data.h @@ -0,0 +1,796 @@ +/* + * Copyright (C) Henrique Peron + * + * 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. + */ + + +/* This file contains data of .KL-files. They have been generated + by Henrique Peron using FreeDOS KC */ + +/* KC: compiles keyboard descriptors in KEY language to a KeybCB, + wrapped in a KL file (for use of FD-KEYB 2.X) + Copyright (C) 2004 by Aitor SANTAMARIA_MERINO */ + + +// Bulgaria (101-key) +Bit8u layout_BG[687] = { +0x4b, 0x4c, 0x46, 0x00, 0x01, 0x09, 0x00, 0x00, 0x42, 0x47, 0x2c, 0xba, 0x01, 0x42, 0x47, 0x07, +0x03, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x03, 0x99, 0x01, 0x00, +0x00, 0x00, 0x00, 0x68, 0x03, 0xae, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x03, 0x97, 0x02, 0x00, +0x00, 0x00, 0x00, 0x57, 0x03, 0xae, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x03, 0xa7, 0x00, 0x00, +0x00, 0x00, 0x00, 0x52, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x03, 0x02, 0x03, 0x00, 0x00, 0x40, 0x04, 0x02, 0x03, 0x00, 0x00, 0x23, 0x05, +0x02, 0x03, 0x00, 0x00, 0xcf, 0x07, 0x02, 0x03, 0x00, 0x00, 0x5e, 0x08, 0x02, 0x03, 0x00, 0x00, +0x26, 0x09, 0x02, 0x03, 0x00, 0x00, 0x24, 0x1a, 0x02, 0x03, 0x00, 0x00, 0x5b, 0x1b, 0x02, 0x03, +0x00, 0x00, 0x5d, 0x2b, 0x02, 0x03, 0x00, 0x00, 0x7c, 0x33, 0x02, 0x03, 0x00, 0x00, 0x3c, 0x34, +0x02, 0x03, 0x00, 0x00, 0x3e, 0x00, 0x12, 0x42, 0x03, 0x00, 0x00, 0xd5, 0x00, 0x03, 0x01, 0x01, +0x00, 0x3f, 0x04, 0x01, 0x01, 0x00, 0x2b, 0x05, 0x02, 0x05, 0x00, 0x22, 0xa0, 0x07, 0x01, 0x01, +0x00, 0x3d, 0x08, 0x01, 0x01, 0x00, 0x3a, 0x09, 0x01, 0x01, 0x00, 0x2f, 0x0a, 0x03, 0x05, 0x00, +0x5f, 0x00, 0x1f, 0x0b, 0x01, 0x01, 0x00, 0xef, 0x0c, 0x01, 0x01, 0x00, 0x49, 0x0d, 0x01, 0x00, +0x2e, 0x56, 0x10, 0x01, 0x00, 0x2c, 0xf2, 0x11, 0x41, 0x00, 0xe7, 0xe8, 0x12, 0x42, 0x00, 0xa8, +0xa9, 0xcf, 0x13, 0x41, 0x00, 0xb7, 0xb8, 0x14, 0x41, 0x00, 0xf5, 0xf6, 0x15, 0x41, 0x00, 0xf9, +0xfa, 0x16, 0x41, 0x00, 0xc6, 0xc7, 0x17, 0x41, 0x00, 0xe3, 0xe4, 0x18, 0x41, 0x00, 0xa6, 0xa7, +0x19, 0x41, 0x00, 0xf3, 0xf4, 0x1a, 0x41, 0x00, 0xa4, 0xa5, 0x1b, 0x01, 0x00, 0x3b, 0xfd, 0x1e, +0x41, 0x00, 0xed, 0xee, 0x1f, 0xc1, 0x00, 0xde, 0x1f, 0xe0, 0x00, 0x20, 0x41, 0x00, 0xa0, 0xa1, +0x21, 0x41, 0x00, 0xd6, 0xd7, 0x22, 0x41, 0x00, 0xe9, 0xea, 0x23, 0x41, 0x00, 0xac, 0xad, 0x24, +0x41, 0x00, 0xe5, 0xe6, 0x25, 0x41, 0x00, 0xd4, 0xd5, 0x26, 0x41, 0x00, 0xeb, 0xec, 0x27, 0x41, +0x00, 0xd2, 0xd3, 0x28, 0x41, 0x00, 0xfb, 0xfc, 0x2a, 0x04, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x78, +0x2b, 0x01, 0x00, 0x29, 0x28, 0x2c, 0x41, 0x00, 0x9c, 0x9d, 0x2d, 0x41, 0x00, 0xbd, 0xbe, 0x2e, +0x41, 0x00, 0x9e, 0x9f, 0x2f, 0x41, 0x00, 0xf7, 0xf8, 0x30, 0x41, 0x00, 0xaa, 0xab, 0x31, 0x41, +0x00, 0xb5, 0xb6, 0x32, 0x41, 0x00, 0xd8, 0xdd, 0x33, 0x41, 0x00, 0xe1, 0xe2, 0x34, 0x41, 0x00, +0xd0, 0xd1, 0x35, 0x41, 0x00, 0xa2, 0xa3, 0x00, 0x05, 0x02, 0x07, 0x00, 0x00, 0xa0, 0x12, 0x42, +0x03, 0x00, 0x00, 0xcf, 0x36, 0x04, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0x03, 0x01, 0x01, +0x00, 0x3f, 0x04, 0x01, 0x01, 0x00, 0x2b, 0x05, 0x01, 0x01, 0x00, 0x22, 0x07, 0x01, 0x01, 0x00, +0x3d, 0x08, 0x01, 0x01, 0x00, 0x3a, 0x09, 0x01, 0x01, 0x00, 0x2f, 0x0a, 0x03, 0x05, 0x00, 0x5f, +0x00, 0x1f, 0x0b, 0x01, 0x01, 0x00, 0xef, 0x0c, 0x01, 0x01, 0x00, 0x49, 0x0d, 0x01, 0x00, 0x2e, +0x56, 0x10, 0x01, 0x00, 0x2c, 0xf2, 0x11, 0x41, 0x00, 0xe7, 0xe8, 0x12, 0x41, 0x00, 0xa8, 0xa9, +0x13, 0x41, 0x00, 0xb7, 0xb8, 0x14, 0x41, 0x00, 0xf5, 0xf6, 0x15, 0x41, 0x00, 0xf9, 0xfa, 0x16, +0x41, 0x00, 0xc6, 0xc7, 0x17, 0x41, 0x00, 0xe3, 0xe4, 0x18, 0x41, 0x00, 0xa6, 0xa7, 0x19, 0x41, +0x00, 0xf3, 0xf4, 0x1a, 0x41, 0x00, 0xa4, 0xa5, 0x1b, 0x01, 0x00, 0x3b, 0xfd, 0x1e, 0x41, 0x00, +0xed, 0xee, 0x1f, 0xc1, 0x00, 0xde, 0x1f, 0xe0, 0x00, 0x20, 0x41, 0x00, 0xa0, 0xa1, 0x21, 0x41, +0x00, 0xd6, 0xd7, 0x22, 0x41, 0x00, 0xe9, 0xea, 0x23, 0x41, 0x00, 0xac, 0xad, 0x24, 0x41, 0x00, +0xe5, 0xe6, 0x25, 0x41, 0x00, 0xd4, 0xd5, 0x26, 0x41, 0x00, 0xeb, 0xec, 0x27, 0x41, 0x00, 0xd2, +0xd3, 0x28, 0x41, 0x00, 0xfb, 0xfc, 0x2a, 0x04, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x2b, 0x01, +0x00, 0x29, 0x28, 0x2c, 0x41, 0x00, 0x9c, 0x9d, 0x2d, 0x41, 0x00, 0xbd, 0xbe, 0x2e, 0x41, 0x00, +0x9e, 0x9f, 0x2f, 0x41, 0x00, 0xf7, 0xf8, 0x30, 0x41, 0x00, 0xaa, 0xab, 0x31, 0x41, 0x00, 0xb5, +0xb6, 0x32, 0x41, 0x00, 0xd8, 0xdd, 0x33, 0x41, 0x00, 0xe1, 0xe2, 0x34, 0x41, 0x00, 0xd0, 0xd1, +0x35, 0x41, 0x00, 0xa2, 0xa3, 0x00, 0x36, 0x04, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00 }; + +// Czech Republic (Standard) +Bit8u layout_CZ243[1003] = { +0x4b, 0x4c, 0x46, 0x00, 0x01, 0x04, 0xf3, 0x00, 0x43, 0x5a, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, +0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x03, 0x36, 0x01, 0xb8, 0x01, 0x00, 0x00, 0x5a, 0x03, +0x79, 0x02, 0x80, 0x02, 0x00, 0x00, 0x52, 0x03, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x63, 0x03, +0x07, 0x03, 0x74, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x04, 0x2b, 0x31, 0xc8, 0x03, 0x01, 0x01, 0xa0, +0x32, 0x04, 0x03, 0x05, 0xa0, 0x33, 0xc9, 0x1e, 0x05, 0x01, 0x01, 0xa0, 0x34, 0x06, 0x02, 0x05, +0xa0, 0x35, 0xca, 0x07, 0x01, 0x01, 0xa0, 0x36, 0x08, 0x02, 0x04, 0xec, 0x37, 0xcb, 0x09, 0x02, +0x00, 0xa0, 0x38, 0xfa, 0x0a, 0x02, 0x04, 0xa1, 0x39, 0xcc, 0x0b, 0x01, 0x00, 0x82, 0x30, 0x0c, +0x02, 0x04, 0x3d, 0x25, 0xcd, 0x0d, 0x02, 0x07, 0xcc, 0xa0, 0xce, 0x10, 0x42, 0x03, 0x00, 0x00, +0x5c, 0x11, 0x42, 0x03, 0x00, 0x00, 0x7c, 0x12, 0x41, 0x00, 0x65, 0x45, 0x15, 0x43, 0x04, 0x7a, +0x5a, 0x00, 0x1a, 0x16, 0x41, 0x00, 0x75, 0x55, 0x17, 0x41, 0x00, 0x69, 0x49, 0x18, 0x41, 0x00, +0x6f, 0x4f, 0x1a, 0x02, 0x00, 0xa3, 0x2f, 0xf6, 0x1b, 0x02, 0x00, 0x29, 0x28, 0x9e, 0x1e, 0x42, +0x00, 0x61, 0x41, 0x3c, 0x21, 0x42, 0x03, 0x00, 0x00, 0x5b, 0x22, 0x42, 0x03, 0x00, 0x00, 0x5d, +0x27, 0x02, 0x01, 0xa0, 0x22, 0x24, 0x28, 0x02, 0x00, 0xf5, 0x21, 0xe1, 0x29, 0x01, 0x02, 0x3b, +0xca, 0x2b, 0x02, 0x01, 0xcd, 0x27, 0xcf, 0x2c, 0x43, 0x00, 0x79, 0x59, 0x3e, 0x19, 0x2d, 0x42, +0x03, 0x00, 0x00, 0x23, 0x2e, 0x42, 0x00, 0x63, 0x43, 0x26, 0x2f, 0x42, 0x03, 0x00, 0x00, 0x40, +0x30, 0x42, 0x03, 0x00, 0x00, 0x7b, 0x31, 0x42, 0x00, 0x6e, 0x4e, 0x7d, 0x32, 0x42, 0x03, 0x00, +0x00, 0xe6, 0x33, 0x01, 0x01, 0x00, 0x3f, 0x34, 0x02, 0x01, 0x00, 0x3a, 0x2a, 0x35, 0x03, 0x04, +0x2d, 0x5f, 0x00, 0x1f, 0x39, 0x00, 0x00, 0x20, 0x56, 0x03, 0x00, 0x26, 0x2a, 0x3c, 0x1c, 0x00, +0x02, 0x02, 0x03, 0x00, 0x00, 0x7e, 0x03, 0x02, 0x06, 0xd8, 0x00, 0xc8, 0x04, 0x00, 0x00, 0xe7, +0x05, 0x02, 0x06, 0x9f, 0x00, 0xca, 0x06, 0x02, 0x06, 0xfd, 0x00, 0xcb, 0x07, 0x02, 0x06, 0xa7, +0x00, 0xcc, 0x08, 0x02, 0x03, 0x00, 0x00, 0x60, 0x09, 0x02, 0x07, 0x00, 0x00, 0xcd, 0x0a, 0x02, +0x07, 0x00, 0x00, 0xce, 0x0b, 0x02, 0x07, 0x00, 0x00, 0xcf, 0x0c, 0x02, 0x07, 0x00, 0x00, 0xd0, +0x0d, 0x02, 0x07, 0xce, 0xc8, 0xd1, 0x12, 0x42, 0x03, 0x00, 0x00, 0xaa, 0x13, 0x41, 0x00, 0x72, +0x52, 0x14, 0x41, 0x00, 0x74, 0x54, 0x1f, 0x42, 0x00, 0x73, 0x53, 0xd0, 0x20, 0x42, 0x00, 0x64, +0x44, 0xd1, 0x25, 0x42, 0x03, 0x00, 0x00, 0x88, 0x26, 0x42, 0x00, 0x6c, 0x4c, 0x9d, 0x27, 0x00, +0x00, 0x85, 0x29, 0x01, 0x03, 0x00, 0xcb, 0x2b, 0x00, 0x01, 0xd0, 0x32, 0x02, 0x07, 0x00, 0x00, +0xa0, 0x00, 0xf3, 0x13, 0x63, 0x9f, 0x64, 0xd4, 0x65, 0xd8, 0x6c, 0x96, 0x6e, 0xe5, 0x72, 0xfd, +0x73, 0xe7, 0x74, 0x9c, 0x7a, 0xa7, 0x43, 0xac, 0x44, 0xd2, 0x45, 0xb7, 0x4c, 0x95, 0x4e, 0xd5, +0x52, 0xfc, 0x53, 0xe6, 0x54, 0x9b, 0x5a, 0xa6, 0x20, 0xf3, 0x5e, 0x07, 0x61, 0x83, 0x69, 0x8c, +0x6f, 0x93, 0x41, 0xb6, 0x49, 0xd7, 0x4f, 0xe2, 0x20, 0x5e, 0xf4, 0x03, 0x61, 0xc7, 0x41, 0xc6, +0x20, 0xf4, 0xf8, 0x03, 0x75, 0x85, 0x55, 0xde, 0x20, 0xf8, 0xf2, 0x05, 0x61, 0xa5, 0x65, 0xa9, +0x41, 0xa4, 0x45, 0xa8, 0x20, 0xf2, 0xfa, 0x03, 0x7a, 0xbe, 0x5a, 0xbd, 0x20, 0xfa, 0x27, 0x19, +0x61, 0xa0, 0x63, 0x86, 0x65, 0x82, 0x69, 0xa1, 0x6c, 0x92, 0x6e, 0xe4, 0x6f, 0xa2, 0x72, 0xea, +0x73, 0x98, 0x75, 0xa3, 0x79, 0xec, 0x7a, 0xab, 0x41, 0xb5, 0x43, 0x8f, 0x45, 0x90, 0x49, 0xd6, +0x4c, 0x91, 0x4e, 0xe3, 0x4f, 0xe0, 0x52, 0xe8, 0x53, 0x97, 0x55, 0xe9, 0x59, 0xed, 0x5a, 0x8d, +0x20, 0xef, 0xf1, 0x05, 0x6f, 0x8b, 0x75, 0xfb, 0x4f, 0x8a, 0x55, 0xeb, 0x20, 0xf1, 0xf9, 0x09, +0x61, 0x84, 0x65, 0x89, 0x6f, 0x94, 0x75, 0x81, 0x41, 0x8e, 0x45, 0xd3, 0x4f, 0x99, 0x55, 0x9a, +0x20, 0xf9, 0xf7, 0x07, 0x63, 0x87, 0x73, 0xad, 0x74, 0xee, 0x43, 0x80, 0x53, 0xb8, 0x54, 0xdd, +0x20, 0xf7, 0x00, 0x12, 0x42, 0x03, 0x00, 0x00, 0xd5, 0x00, 0x7e, 0x07, 0x61, 0xc6, 0x6e, 0xa4, +0x6f, 0xe4, 0x41, 0xc7, 0x4e, 0xa5, 0x4f, 0xe5, 0x20, 0x7e, 0x5e, 0x0b, 0x61, 0x83, 0x65, 0x88, +0x69, 0x8c, 0x6f, 0x93, 0x75, 0x96, 0x41, 0xb6, 0x45, 0xd2, 0x49, 0xd7, 0x4f, 0xe2, 0x55, 0xea, +0x20, 0x5e, 0xf8, 0x03, 0x61, 0x86, 0x41, 0x8f, 0x20, 0xf8, 0x60, 0x0b, 0x61, 0x85, 0x65, 0x8a, +0x69, 0x8d, 0x6f, 0x95, 0x75, 0x97, 0x41, 0xb7, 0x45, 0xd4, 0x49, 0xde, 0x4f, 0xe3, 0x55, 0xeb, +0x20, 0x60, 0xef, 0x0d, 0x61, 0xa0, 0x65, 0x82, 0x69, 0xa1, 0x6f, 0xa2, 0x75, 0xa3, 0x79, 0xec, +0x41, 0xb5, 0x45, 0x90, 0x49, 0xd6, 0x4f, 0xe0, 0x55, 0xe9, 0x59, 0xed, 0x20, 0xef, 0xf9, 0x0c, +0x61, 0x84, 0x65, 0x89, 0x69, 0x8b, 0x6f, 0x94, 0x75, 0x81, 0x79, 0x98, 0x41, 0x8e, 0x45, 0xd3, +0x49, 0xd8, 0x4f, 0x99, 0x55, 0x9a, 0x20, 0xf9, 0xf7, 0x03, 0x63, 0x87, 0x43, 0x80, 0x20, 0xf7, +0x00, 0x02, 0x02, 0x03, 0x00, 0x00, 0x7e, 0x03, 0x02, 0x06, 0x88, 0x00, 0xc8, 0x04, 0x00, 0x00, +0xa8, 0x05, 0x00, 0x00, 0x87, 0x06, 0x00, 0x00, 0xa9, 0x07, 0x00, 0x00, 0x91, 0x08, 0x02, 0x02, +0x98, 0x00, 0x60, 0x09, 0x02, 0x07, 0x00, 0x00, 0xa0, 0x0a, 0x02, 0x07, 0x00, 0x00, 0xcb, 0x0c, +0x02, 0x07, 0x00, 0x00, 0xcc, 0x0d, 0x02, 0x07, 0xcb, 0xc8, 0xa0, 0x13, 0x41, 0x00, 0x72, 0x52, +0x14, 0x41, 0x00, 0x74, 0x54, 0x1b, 0x02, 0x07, 0x00, 0x00, 0xa0, 0x1f, 0x41, 0x00, 0x73, 0x53, +0x20, 0x41, 0x00, 0x64, 0x44, 0x26, 0x41, 0x00, 0x6c, 0x4c, 0x27, 0x00, 0x00, 0x96, 0x28, 0x00, +0x00, 0xad, 0x29, 0x01, 0x03, 0x00, 0xca, 0x2b, 0x02, 0x07, 0xcc, 0x00, 0xa0, 0x00, 0x76, 0x13, +0x63, 0x87, 0x64, 0x83, 0x65, 0x88, 0x6c, 0x8c, 0x6e, 0xa4, 0x72, 0xa9, 0x73, 0xa8, 0x74, 0x9f, +0x7a, 0x91, 0x43, 0x80, 0x44, 0x85, 0x45, 0x89, 0x4c, 0x9c, 0x4e, 0xa5, 0x52, 0x9e, 0x53, 0x9b, +0x54, 0x86, 0x5a, 0x92, 0x20, 0x76, 0x5e, 0x03, 0x6f, 0x93, 0x4f, 0xa7, 0x20, 0x5e, 0xf8, 0x03, +0x75, 0x96, 0x55, 0xa6, 0x20, 0xf8, 0x27, 0x11, 0x61, 0xa0, 0x65, 0x82, 0x69, 0xa1, 0x6c, 0x8d, +0x6f, 0xa2, 0x72, 0xaa, 0x75, 0xa3, 0x79, 0x98, 0x41, 0x8f, 0x45, 0x90, 0x49, 0x8b, 0x4c, 0x8a, +0x4f, 0x95, 0x52, 0xab, 0x55, 0x97, 0x59, 0x9d, 0x20, 0x27, 0x22, 0x07, 0x61, 0x84, 0x6f, 0x94, +0x75, 0x81, 0x41, 0x8e, 0x4f, 0x99, 0x55, 0x9a, 0x20, 0x22, 0x00 }; + +// France (Standard) +Bit8u layout_FR[581] = { +0x4b, 0x4c, 0x46, 0x00, 0x01, 0x09, 0x00, 0x00, 0x46, 0x52, 0x2c, 0xbd, 0x00, 0x46, 0x52, 0x05, +0x03, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x03, 0x68, 0x01, 0x6f, +0x01, 0x00, 0x00, 0x52, 0x03, 0x00, 0x00, 0x6f, 0x01, 0x00, 0x00, 0x5b, 0x03, 0xca, 0x01, 0xd9, +0x01, 0x00, 0x00, 0xb5, 0x01, 0x1c, 0x01, 0x2d, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, +0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x41, 0x00, 0x26, 0x31, 0x03, 0x42, 0x04, 0x82, 0x32, 0xc9, 0x04, 0x42, +0x00, 0x22, 0x33, 0x23, 0x05, 0x42, 0x00, 0x27, 0x34, 0x7b, 0x06, 0x43, 0x00, 0x28, 0x35, 0x5b, +0x1b, 0x07, 0x43, 0x00, 0x2d, 0x36, 0x7c, 0x1f, 0x08, 0x42, 0x04, 0x8a, 0x37, 0xc8, 0x09, 0x43, +0x00, 0x5f, 0x38, 0x5c, 0x1c, 0x0a, 0x42, 0x00, 0x87, 0x39, 0x5e, 0x0b, 0x42, 0x00, 0x85, 0x30, +0x40, 0x0c, 0x43, 0x00, 0x29, 0xf8, 0x5d, 0x1d, 0x0d, 0x42, 0x03, 0x00, 0x00, 0x7d, 0x10, 0x43, +0x04, 0x61, 0x41, 0x00, 0x01, 0x11, 0x43, 0x04, 0x7a, 0x5a, 0x00, 0x1a, 0x12, 0x41, 0x00, 0x65, +0x45, 0x15, 0x41, 0x00, 0x79, 0x59, 0x16, 0x41, 0x00, 0x75, 0x55, 0x17, 0x41, 0x00, 0x69, 0x49, +0x18, 0x41, 0x00, 0x6f, 0x4f, 0x1a, 0x43, 0x07, 0xca, 0xcb, 0x00, 0x1e, 0x1b, 0x42, 0x00, 0x24, +0x9c, 0xcf, 0x1e, 0x43, 0x04, 0x71, 0x51, 0x00, 0x11, 0x27, 0x43, 0x04, 0x6d, 0x4d, 0x00, 0x0d, +0x28, 0x41, 0x00, 0x97, 0x25, 0x29, 0x41, 0x00, 0xfd, 0xfc, 0x2b, 0x41, 0x00, 0x2a, 0xe6, 0x2c, +0x43, 0x04, 0x77, 0x57, 0x00, 0x17, 0x31, 0x41, 0x00, 0x6e, 0x4e, 0x32, 0x41, 0x00, 0x2c, 0x3f, +0x33, 0x42, 0x00, 0x3b, 0x2e, 0x3c, 0x34, 0x42, 0x00, 0x3a, 0x2f, 0x3e, 0x35, 0x41, 0x00, 0x21, +0xf5, 0x39, 0x00, 0x00, 0x20, 0x56, 0x41, 0x00, 0x3c, 0x3e, 0x00, 0x1b, 0x42, 0x07, 0x00, 0x00, +0xa0, 0x29, 0x41, 0x03, 0x00, 0xa0, 0x35, 0x41, 0x01, 0x00, 0x15, 0x00, 0x60, 0x06, 0x61, 0x85, +0x65, 0x8a, 0x69, 0x8d, 0x6f, 0x95, 0x75, 0x97, 0x20, 0x60, 0x7e, 0x03, 0x6e, 0xa4, 0x4e, 0xa5, +0x20, 0x7e, 0x5e, 0x06, 0x61, 0x83, 0x65, 0x88, 0x69, 0x8c, 0x6f, 0x93, 0x75, 0x96, 0x20, 0x5e, +0x22, 0x0a, 0x61, 0x84, 0x65, 0x89, 0x69, 0x8b, 0x6f, 0x94, 0x75, 0x81, 0x79, 0x98, 0x41, 0x8e, +0x4f, 0x99, 0x55, 0x9a, 0x20, 0x22, 0x00, 0x12, 0x42, 0x03, 0x00, 0x00, 0xd5, 0x00, 0x60, 0x0b, +0x61, 0x85, 0x65, 0x8a, 0x69, 0x8d, 0x6f, 0x95, 0x75, 0x97, 0x41, 0xb7, 0x45, 0xd4, 0x49, 0xde, +0x4f, 0xe3, 0x55, 0xeb, 0x20, 0x60, 0x7e, 0x07, 0x61, 0xc6, 0x6e, 0xa4, 0x6f, 0xe4, 0x41, 0xc7, +0x4e, 0xa5, 0x4f, 0xe5, 0x20, 0x7e, 0x5e, 0x0b, 0x61, 0x83, 0x65, 0x88, 0x69, 0x8c, 0x6f, 0x93, +0x75, 0x96, 0x41, 0xb6, 0x45, 0xd2, 0x49, 0xd7, 0x4f, 0xe2, 0x55, 0xea, 0x20, 0x5e, 0xf9, 0x0c, +0x61, 0x84, 0x65, 0x89, 0x69, 0x8b, 0x6f, 0x94, 0x75, 0x81, 0x79, 0x98, 0x41, 0x8e, 0x45, 0xd3, +0x49, 0xd8, 0x4f, 0x99, 0x55, 0x9a, 0x20, 0xf9, 0x00, 0x12, 0x42, 0x03, 0x00, 0x00, 0xd5, 0x18, +0x44, 0x0b, 0x00, 0x00, 0xab, 0x00, 0xac, 0x00, 0x60, 0x0b, 0x61, 0x85, 0x65, 0x8a, 0x69, 0x8d, +0x6f, 0x95, 0x75, 0x97, 0x41, 0xb7, 0x45, 0xd4, 0x49, 0xde, 0x4f, 0xe3, 0x55, 0xeb, 0x20, 0x60, +0x7e, 0x07, 0x61, 0xc6, 0x6e, 0xa4, 0x6f, 0xe4, 0x41, 0xc7, 0x4e, 0xa5, 0x4f, 0xe5, 0x20, 0x7e, +0x5e, 0x0b, 0x61, 0x83, 0x65, 0x88, 0x69, 0x8c, 0x6f, 0x93, 0x75, 0x96, 0x41, 0xb6, 0x45, 0xd2, +0x49, 0xd7, 0x4f, 0xe2, 0x55, 0xea, 0x20, 0x5e, 0x22, 0x0d, 0x61, 0x84, 0x65, 0x89, 0x69, 0x8b, +0x6f, 0x94, 0x75, 0x81, 0x79, 0x98, 0x41, 0x8e, 0x45, 0xd3, 0x49, 0xd8, 0x4f, 0x99, 0x55, 0x9a, +0x59, 0xf3, 0x20, 0x22, 0x00 }; + +// Greece (319) +Bit8u layout_GK[1117] = { +0x4b, 0x4c, 0x46, 0x00, 0x01, 0x13, 0x00, 0x00, 0x47, 0x4b, 0x2c, 0x00, 0x00, 0x45, 0x4c, 0x2c, +0x3f, 0x01, 0x47, 0x4b, 0x2c, 0x3f, 0x01, 0x45, 0x4c, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0d, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, +0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x03, 0x3a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x65, 0x03, 0x79, +0x01, 0x49, 0x02, 0x00, 0x00, 0xe1, 0x02, 0x24, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x02, 0x7e, +0x02, 0x2d, 0x03, 0x00, 0x00, 0x53, 0x03, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x53, 0x03, 0x5a, +0x03, 0x13, 0x04, 0x00, 0x00, 0x5a, 0x03, 0xf7, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x52, 0x03, 0x00, +0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, +0x00, 0x22, 0x07, 0x01, 0x01, 0x00, 0x26, 0x08, 0x01, 0x01, 0x00, 0x2f, 0x09, 0x01, 0x01, 0x00, +0x28, 0x0a, 0x01, 0x01, 0x00, 0x29, 0x0b, 0x01, 0x01, 0x00, 0x3d, 0x0c, 0x01, 0x00, 0x27, 0x3f, +0x0d, 0x01, 0x00, 0x2b, 0x2a, 0x12, 0x41, 0x00, 0x65, 0x45, 0x15, 0x41, 0x00, 0x79, 0x59, 0x16, +0x41, 0x00, 0x75, 0x55, 0x17, 0x41, 0x00, 0x69, 0x49, 0x18, 0x41, 0x00, 0x6f, 0x4f, 0x1e, 0x41, +0x00, 0x61, 0x41, 0x27, 0x01, 0x03, 0xcb, 0xcc, 0x28, 0x01, 0x03, 0xca, 0xc9, 0x29, 0x03, 0x04, +0x5c, 0x7c, 0x00, 0x1c, 0x2b, 0x01, 0x01, 0xc8, 0x40, 0x2e, 0x41, 0x00, 0x63, 0x43, 0x31, 0x41, +0x00, 0x6e, 0x4e, 0x33, 0x02, 0x00, 0x2c, 0x3b, 0x3c, 0x34, 0x02, 0x00, 0x2e, 0x3a, 0x3e, 0x35, +0x03, 0x04, 0x2d, 0x5f, 0x00, 0x1f, 0x39, 0x00, 0x00, 0x20, 0x56, 0x01, 0x00, 0x3c, 0x3e, 0x00, +0x12, 0x42, 0x03, 0x00, 0x00, 0xd5, 0x00, 0x60, 0x0b, 0x61, 0x85, 0x65, 0x8a, 0x69, 0x8d, 0x6f, +0x95, 0x75, 0x97, 0x41, 0xb7, 0x45, 0xd4, 0x49, 0xde, 0x4f, 0xe3, 0x55, 0xeb, 0x20, 0x60, 0x7e, +0x07, 0x61, 0xc6, 0x6e, 0xa4, 0x6f, 0xe4, 0x41, 0xc7, 0x4e, 0xa5, 0x4f, 0xe5, 0x20, 0x7e, 0x5e, +0x0b, 0x61, 0x83, 0x65, 0x88, 0x69, 0x8c, 0x6f, 0x93, 0x75, 0x96, 0x41, 0xb6, 0x45, 0xd2, 0x49, +0xd7, 0x4f, 0xe2, 0x55, 0xea, 0x20, 0x5e, 0xef, 0x0f, 0x61, 0xa0, 0x63, 0x87, 0x65, 0x82, 0x69, +0xa1, 0x6f, 0xa2, 0x75, 0xa3, 0x79, 0xec, 0x41, 0xb5, 0x43, 0x80, 0x45, 0x90, 0x49, 0xd6, 0x4f, +0xe0, 0x55, 0xe9, 0x59, 0xed, 0x20, 0xef, 0xf9, 0x0c, 0x61, 0x84, 0x65, 0x89, 0x69, 0x8b, 0x6f, +0x94, 0x75, 0x81, 0x79, 0x98, 0x41, 0x8e, 0x45, 0xd3, 0x49, 0xd8, 0x4f, 0x99, 0x55, 0x9a, 0x20, +0xf9, 0x00, 0x04, 0x01, 0x01, 0x00, 0x9c, 0x07, 0x01, 0x01, 0x00, 0x89, 0x0c, 0x01, 0x01, 0x00, +0xf8, 0x10, 0x01, 0x00, 0x88, 0x8e, 0x11, 0x01, 0x00, 0xed, 0x8a, 0x12, 0x42, 0x00, 0xde, 0xa8, +0x87, 0x13, 0x41, 0x00, 0xeb, 0xc7, 0x14, 0x41, 0x00, 0xee, 0xd0, 0x15, 0x41, 0x00, 0xf2, 0xd1, +0x16, 0x41, 0x00, 0xe2, 0xac, 0x17, 0x41, 0x00, 0xe3, 0xad, 0x18, 0x41, 0x00, 0xe9, 0xbe, 0x19, +0x41, 0x00, 0xea, 0xc6, 0x1a, 0x01, 0x01, 0x00, 0xae, 0x1b, 0x01, 0x01, 0x00, 0xaf, 0x1e, 0x41, +0x00, 0xd6, 0xa4, 0x1f, 0x41, 0x00, 0xec, 0xcf, 0x20, 0x41, 0x00, 0xdd, 0xa7, 0x21, 0x41, 0x00, +0xf3, 0xd2, 0x22, 0x41, 0x00, 0xd8, 0xa6, 0x23, 0x41, 0x00, 0xe1, 0xaa, 0x24, 0x41, 0x00, 0xe8, +0xbd, 0x25, 0x41, 0x00, 0xe4, 0xb5, 0x26, 0x41, 0x00, 0xe5, 0xb6, 0x27, 0x02, 0x07, 0xc8, 0xc9, +0xca, 0x28, 0x01, 0x00, 0x8c, 0x8b, 0x29, 0x01, 0x00, 0xab, 0xf1, 0x2a, 0x04, 0x1f, 0x00, 0x00, +0x00, 0x00, 0x78, 0x2b, 0x01, 0x00, 0x99, 0x9a, 0x2c, 0xc1, 0x00, 0xe0, 0x00, 0xa9, 0x2c, 0x2d, +0x41, 0x00, 0xf4, 0xd3, 0x2e, 0x41, 0x00, 0xf6, 0xd4, 0x2f, 0x41, 0x00, 0xfa, 0xd5, 0x30, 0x41, +0x00, 0xd7, 0xa5, 0x31, 0x41, 0x00, 0xe7, 0xb8, 0x32, 0x41, 0x00, 0xe6, 0xb7, 0x56, 0x01, 0x00, +0xf5, 0x97, 0x00, 0x12, 0x42, 0x03, 0x00, 0x00, 0x87, 0x36, 0x04, 0x1f, 0x00, 0x00, 0x00, 0x00, +0x79, 0x00, 0xef, 0x0f, 0xd6, 0x9b, 0xde, 0x9d, 0xe1, 0x9e, 0xe3, 0x9f, 0xe9, 0xa2, 0xf2, 0xa3, +0xfa, 0xfd, 0xa4, 0x86, 0xa8, 0x8d, 0xaa, 0x8f, 0xad, 0x90, 0xbe, 0x92, 0xd1, 0x95, 0xd5, 0x98, +0x20, 0xef, 0xf9, 0x05, 0xe3, 0xa0, 0xf2, 0xfb, 0xad, 0x91, 0xd1, 0x96, 0x20, 0xf9, 0xf7, 0x03, +0xe3, 0xa1, 0xf2, 0xfc, 0x20, 0xf7, 0x00, 0x0c, 0x01, 0x01, 0x00, 0xf8, 0x10, 0x01, 0x00, 0xf9, +0x51, 0x11, 0x01, 0x00, 0xaa, 0x57, 0x12, 0x41, 0x00, 0x9c, 0x84, 0x13, 0x41, 0x00, 0xa8, 0x90, +0x14, 0x41, 0x00, 0xab, 0x92, 0x15, 0x41, 0x00, 0xac, 0x93, 0x16, 0x41, 0x00, 0x9f, 0x87, 0x17, +0x41, 0x00, 0xa0, 0x88, 0x18, 0x41, 0x00, 0xa6, 0x8e, 0x19, 0x41, 0x00, 0xa7, 0x8f, 0x1e, 0x41, +0x00, 0x98, 0x80, 0x1f, 0x41, 0x00, 0xa9, 0x91, 0x20, 0x41, 0x00, 0x9b, 0x83, 0x21, 0x41, 0x00, +0xad, 0x94, 0x22, 0x41, 0x00, 0x9a, 0x82, 0x23, 0x41, 0x00, 0x9e, 0x86, 0x24, 0x41, 0x00, 0xa5, +0x8d, 0x25, 0x41, 0x00, 0xa1, 0x89, 0x26, 0x41, 0x00, 0xa2, 0x8a, 0x27, 0x01, 0x03, 0xc8, 0xc9, +0x29, 0x01, 0x00, 0x60, 0xf1, 0x2a, 0x04, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x2b, 0x01, 0x00, +0xfd, 0x7c, 0x2c, 0x41, 0x00, 0x9d, 0x85, 0x2d, 0x41, 0x00, 0xae, 0x95, 0x2e, 0x41, 0x00, 0xaf, +0x96, 0x2f, 0xc1, 0x00, 0xe0, 0x00, 0x97, 0x2f, 0x30, 0x41, 0x00, 0x99, 0x81, 0x31, 0x41, 0x00, +0xa4, 0x8c, 0x32, 0x41, 0x00, 0xa3, 0x8b, 0x56, 0x01, 0x00, 0x15, 0x7c, 0x00, 0x36, 0x04, 0x1f, +0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x27, 0x0f, 0x98, 0xe1, 0x9c, 0xe2, 0x9e, 0xe3, 0xa0, 0xe5, +0xa6, 0xe6, 0xac, 0xe7, 0xe0, 0xe9, 0x80, 0xea, 0x84, 0xeb, 0x86, 0xec, 0x88, 0xed, 0x8e, 0xee, +0x93, 0xef, 0x97, 0xf0, 0x20, 0x27, 0x22, 0x05, 0xa0, 0xe4, 0xac, 0xe8, 0x88, 0xf4, 0x93, 0xf5, +0x20, 0x22, 0x00, 0x0c, 0x01, 0x01, 0x00, 0xf8, 0x10, 0x10, 0x00, 0x00, 0x11, 0x01, 0x00, 0xed, +0x7c, 0x12, 0x41, 0x00, 0xde, 0xa8, 0x13, 0x41, 0x00, 0xeb, 0xc7, 0x14, 0x41, 0x00, 0xee, 0xd0, +0x15, 0x41, 0x00, 0xf2, 0xd1, 0x16, 0x41, 0x00, 0xe2, 0xac, 0x17, 0x41, 0x00, 0xe3, 0xad, 0x18, +0x41, 0x00, 0xe9, 0xbe, 0x19, 0x41, 0x00, 0xea, 0xc6, 0x1a, 0x01, 0x01, 0x00, 0xae, 0x1b, 0x01, +0x01, 0x00, 0xaf, 0x1e, 0x41, 0x00, 0xd6, 0xa4, 0x1f, 0x41, 0x00, 0xec, 0xcf, 0x20, 0x41, 0x00, +0xdd, 0xa7, 0x21, 0x41, 0x00, 0xf3, 0xd2, 0x22, 0x41, 0x00, 0xd8, 0xa6, 0x23, 0x41, 0x00, 0xe1, +0xaa, 0x24, 0x41, 0x00, 0xe8, 0xbd, 0x25, 0x41, 0x00, 0xe4, 0xb5, 0x26, 0x41, 0x00, 0xe5, 0xb6, +0x27, 0x02, 0x07, 0xc8, 0xc9, 0xca, 0x29, 0x01, 0x00, 0xab, 0xf1, 0x2a, 0x04, 0x1f, 0x00, 0x00, +0x00, 0x00, 0x7c, 0x2b, 0x01, 0x00, 0x5c, 0x7c, 0x2c, 0xc1, 0x00, 0xe0, 0x00, 0xa9, 0x2c, 0x2d, +0x41, 0x00, 0xf4, 0xd3, 0x2e, 0x41, 0x00, 0xf6, 0xd4, 0x2f, 0x41, 0x00, 0xfa, 0xd5, 0x30, 0x41, +0x00, 0xd7, 0xa5, 0x31, 0x41, 0x00, 0xe7, 0xb8, 0x32, 0x41, 0x00, 0xe6, 0xb7, 0x56, 0x01, 0x00, +0xf5, 0x7c, 0x00, 0x36, 0x04, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0xef, 0x0f, 0xd6, 0x9b, +0xde, 0x9d, 0xe1, 0x9e, 0xe3, 0x9f, 0xe9, 0xa2, 0xf2, 0xa3, 0xfa, 0xfd, 0xa4, 0x86, 0xa8, 0x8d, +0xaa, 0x8f, 0xad, 0x90, 0xbe, 0x92, 0xd1, 0x95, 0xd5, 0x98, 0x20, 0xef, 0xf9, 0x03, 0xe3, 0xa0, +0xf2, 0xfb, 0x20, 0xf9, 0x27, 0x03, 0xe3, 0xa1, 0xf2, 0xfc, 0x20, 0x27, 0x00 }; + +// Germany (Standard) +Bit8u layout_GR[596] = { +0x4b, 0x4c, 0x46, 0x00, 0x01, 0x13, 0x00, 0x00, 0x47, 0x52, 0x2c, 0x00, 0x00, 0x44, 0x45, 0x2c, +0x81, 0x00, 0x47, 0x52, 0x2c, 0x81, 0x00, 0x44, 0x45, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x05, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, +0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x03, 0x19, 0x01, 0x20, 0x01, 0x00, 0x00, 0x52, 0x03, 0x00, +0x00, 0x20, 0x01, 0x00, 0x00, 0xb5, 0x01, 0x12, 0x01, 0x71, 0x01, 0x00, 0x00, 0x54, 0x03, 0xa2, +0x01, 0xd8, 0x01, 0x00, 0x00, 0x55, 0x03, 0x01, 0x02, 0x1e, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, +0x00, 0x00, 0x7c, 0x03, 0x02, 0x01, 0x00, 0x22, 0xfd, 0x04, 0x02, 0x01, 0x00, 0xf5, 0xfc, 0x07, +0x01, 0x01, 0x00, 0x26, 0x08, 0x02, 0x01, 0x00, 0x2f, 0x7b, 0x09, 0x03, 0x01, 0x00, 0x28, 0x5b, +0x1b, 0x0a, 0x03, 0x01, 0x00, 0x29, 0x5d, 0x1d, 0x0b, 0x02, 0x01, 0x00, 0x3d, 0x7d, 0x0c, 0x03, +0x00, 0xe1, 0x3f, 0x5c, 0x1c, 0x0d, 0x01, 0x03, 0xca, 0xc8, 0x10, 0x42, 0x03, 0x00, 0x00, 0x40, +0x12, 0x41, 0x00, 0x65, 0x45, 0x15, 0x43, 0x04, 0x7a, 0x5a, 0x00, 0x1a, 0x16, 0x41, 0x00, 0x75, +0x55, 0x17, 0x41, 0x00, 0x69, 0x49, 0x18, 0x41, 0x00, 0x6f, 0x4f, 0x1a, 0x41, 0x00, 0x81, 0x9a, +0x1b, 0x02, 0x00, 0x2b, 0x2a, 0x7e, 0x1e, 0x41, 0x00, 0x61, 0x41, 0x27, 0x41, 0x00, 0x94, 0x99, +0x28, 0x41, 0x00, 0x84, 0x8e, 0x29, 0x03, 0x05, 0xc9, 0xf8, 0x00, 0x1e, 0x2b, 0x01, 0x00, 0x23, +0x27, 0x2c, 0x43, 0x00, 0x79, 0x59, 0x3c, 0x19, 0x2d, 0x42, 0x03, 0x00, 0x00, 0x3e, 0x2e, 0x41, +0x00, 0x63, 0x43, 0x31, 0x42, 0x03, 0x00, 0x00, 0x23, 0x32, 0x42, 0x03, 0x00, 0x00, 0xe6, 0x33, +0x01, 0x01, 0x00, 0x3b, 0x34, 0x01, 0x01, 0x00, 0x3a, 0x35, 0x03, 0x04, 0x2d, 0x5f, 0x00, 0x1f, +0x39, 0x00, 0x00, 0x20, 0x56, 0x02, 0x00, 0x3c, 0x3e, 0x7c, 0x00, 0x04, 0x02, 0x05, 0x00, 0x15, +0xa0, 0x00, 0x12, 0x42, 0x03, 0x00, 0x00, 0xd5, 0x00, 0x60, 0x0b, 0x61, 0x85, 0x65, 0x8a, 0x69, +0x8d, 0x6f, 0x95, 0x75, 0x97, 0x41, 0xb7, 0x45, 0xd4, 0x49, 0xde, 0x4f, 0xe3, 0x55, 0xeb, 0x20, +0x60, 0x5e, 0x0b, 0x61, 0x83, 0x65, 0x88, 0x69, 0x8c, 0x6f, 0x93, 0x75, 0x96, 0x41, 0xb6, 0x45, +0xd2, 0x49, 0xd7, 0x4f, 0xe2, 0x55, 0xea, 0x20, 0x5e, 0xef, 0x0f, 0x61, 0xa0, 0x63, 0x87, 0x65, +0x82, 0x69, 0xa1, 0x6f, 0xa2, 0x75, 0xa3, 0x79, 0xec, 0x41, 0xb5, 0x43, 0x80, 0x45, 0x90, 0x49, +0xd6, 0x4f, 0xe0, 0x55, 0xe9, 0x59, 0xed, 0x20, 0xef, 0x00, 0x60, 0x06, 0x61, 0x85, 0x65, 0x8a, +0x69, 0x8d, 0x6f, 0x95, 0x75, 0x97, 0x20, 0x60, 0x5e, 0x06, 0x61, 0x83, 0x65, 0x88, 0x69, 0x8c, +0x6f, 0x93, 0x75, 0x96, 0x20, 0x5e, 0x27, 0x09, 0x61, 0xa0, 0x63, 0x87, 0x65, 0x82, 0x69, 0xa1, +0x6f, 0xa2, 0x75, 0xa3, 0x43, 0x80, 0x45, 0x90, 0x20, 0x27, 0x00, 0x03, 0x02, 0x07, 0x00, 0x00, +0xa0, 0x04, 0x02, 0x07, 0x00, 0x00, 0xa0, 0x0d, 0x01, 0x03, 0xc8, 0xa0, 0x12, 0x42, 0x03, 0x00, +0x00, 0xaa, 0x1f, 0x41, 0x00, 0x73, 0x53, 0x26, 0x41, 0x00, 0x6c, 0x4c, 0x29, 0x00, 0x01, 0xa0, +0x2d, 0x41, 0x00, 0x78, 0x58, 0x31, 0x41, 0x00, 0x6e, 0x4e, 0x32, 0x42, 0x07, 0x00, 0x00, 0xa0, +0x00, 0xef, 0x13, 0x61, 0xa5, 0x63, 0x86, 0x65, 0xa9, 0x6c, 0x88, 0x6e, 0xe4, 0x6f, 0xa2, 0x73, +0x98, 0x78, 0xab, 0x7a, 0xbe, 0x41, 0xa4, 0x43, 0x8f, 0x45, 0xa8, 0x4c, 0x9d, 0x4e, 0xe3, 0x4f, +0xe0, 0x53, 0x97, 0x58, 0x8d, 0x5a, 0xbd, 0x20, 0xef, 0x00, 0x0d, 0x10, 0x00, 0x00, 0x1f, 0x41, +0x00, 0x73, 0x53, 0x22, 0x41, 0x00, 0x67, 0x47, 0x23, 0x41, 0x00, 0x68, 0x48, 0x24, 0x41, 0x00, +0x6a, 0x4a, 0x29, 0x00, 0x01, 0xc8, 0x00, 0x5e, 0x0d, 0x63, 0x86, 0x67, 0x9b, 0x68, 0xa9, 0x6a, +0x9f, 0x73, 0xc7, 0x75, 0xed, 0x43, 0x8f, 0x47, 0x9d, 0x48, 0xa8, 0x4a, 0xac, 0x53, 0xc6, 0x55, +0xec, 0x20, 0x5e, 0x00 }; + +// Croatia +Bit8u layout_HR[993] = { +0x4b, 0x4c, 0x46, 0x00, 0x01, 0x27, 0x00, 0x00, 0x42, 0x41, 0x2c, 0x00, 0x00, 0x48, 0x52, 0x2c, +0x00, 0x00, 0x53, 0x49, 0x2c, 0x00, 0x00, 0x59, 0x55, 0x2c, 0xea, 0x00, 0x42, 0x41, 0x2c, 0xea, +0x00, 0x48, 0x52, 0x2c, 0xea, 0x00, 0x53, 0x49, 0x2c, 0xea, 0x00, 0x59, 0x55, 0x05, 0x02, 0x00, +0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x03, 0xde, 0x01, 0x65, 0x02, 0x00, +0x00, 0x71, 0x00, 0x29, 0x01, 0x7f, 0x01, 0x00, 0x00, 0x5a, 0x03, 0x26, 0x03, 0x2d, 0x03, 0x00, +0x00, 0x52, 0x03, 0x00, 0x00, 0x2d, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x07, 0x00, 0x00, 0xc8, 0x03, +0x01, 0x01, 0x00, 0x22, 0x04, 0x03, 0x07, 0x00, 0x00, 0xc9, 0x1e, 0x06, 0x02, 0x07, 0x00, 0x00, +0xca, 0x07, 0x01, 0x01, 0x00, 0x26, 0x08, 0x02, 0x05, 0x00, 0x2f, 0xcb, 0x09, 0x02, 0x01, 0x00, +0x28, 0xfa, 0x0a, 0x02, 0x05, 0x00, 0x29, 0xcc, 0x0b, 0x01, 0x01, 0x00, 0x3d, 0x0c, 0x02, 0x04, +0x27, 0x3f, 0xcd, 0x0d, 0x02, 0x04, 0x2b, 0x2a, 0xce, 0x10, 0x42, 0x03, 0x00, 0x00, 0x5c, 0x11, +0x42, 0x03, 0x00, 0x00, 0x7c, 0x12, 0x41, 0x00, 0x65, 0x45, 0x15, 0x43, 0x04, 0x7a, 0x5a, 0x00, +0x1a, 0x16, 0x41, 0x00, 0x75, 0x55, 0x17, 0x41, 0x00, 0x69, 0x49, 0x18, 0x41, 0x00, 0x6f, 0x4f, +0x1a, 0x42, 0x03, 0xa0, 0xa0, 0xf6, 0x1b, 0x42, 0x03, 0xa0, 0xa0, 0x9e, 0x1e, 0x41, 0x00, 0x61, +0x41, 0x21, 0x42, 0x03, 0x00, 0x00, 0x5b, 0x22, 0x42, 0x03, 0x00, 0x00, 0x5d, 0x27, 0x43, 0x07, +0xa0, 0xa0, 0x00, 0x1d, 0x28, 0x42, 0x03, 0xa0, 0xa0, 0xe1, 0x29, 0x01, 0x03, 0xce, 0xcd, 0x2b, +0x42, 0x03, 0xa0, 0xa0, 0xcf, 0x2c, 0x43, 0x04, 0x79, 0x59, 0x00, 0x19, 0x2e, 0x41, 0x00, 0x63, +0x43, 0x2f, 0x42, 0x03, 0x00, 0x00, 0x40, 0x30, 0x42, 0x03, 0x00, 0x00, 0x7b, 0x31, 0x42, 0x00, +0x6e, 0x4e, 0x7d, 0x32, 0x42, 0x03, 0x00, 0x00, 0xf5, 0x33, 0x02, 0x01, 0x00, 0x3b, 0x3c, 0x34, +0x02, 0x01, 0x00, 0x3a, 0x3e, 0x35, 0x03, 0x04, 0x2d, 0x5f, 0x00, 0x1f, 0x39, 0x00, 0x00, 0x20, +0x56, 0x01, 0x00, 0x3c, 0x3e, 0x00, 0x02, 0x02, 0x03, 0x00, 0x00, 0x7e, 0x03, 0x02, 0x07, 0x00, +0x00, 0xc8, 0x06, 0x02, 0x03, 0x00, 0x00, 0xf8, 0x08, 0x02, 0x07, 0x00, 0x00, 0xca, 0x0a, 0x02, +0x07, 0x00, 0x00, 0xcb, 0x0c, 0x02, 0x07, 0x00, 0x00, 0xcc, 0x0d, 0x02, 0x07, 0x00, 0x00, 0xcd, +0x1a, 0x41, 0x00, 0xa4, 0xa5, 0x1b, 0x42, 0x04, 0x9b, 0x9d, 0xa0, 0x1f, 0x41, 0x00, 0x73, 0x53, +0x27, 0x41, 0x00, 0x91, 0x92, 0x28, 0x41, 0x00, 0x86, 0x8f, 0x29, 0x01, 0x03, 0xcd, 0xcc, 0x2b, +0x42, 0x04, 0xa6, 0xa7, 0xa0, 0x32, 0x42, 0x03, 0x00, 0x00, 0x15, 0x00, 0x76, 0x07, 0x63, 0x91, +0x73, 0xa4, 0x7a, 0xa6, 0x43, 0x92, 0x53, 0xa5, 0x5a, 0xa7, 0x20, 0x76, 0x5e, 0x06, 0x61, 0x83, +0x65, 0x88, 0x69, 0x8c, 0x6f, 0x93, 0x75, 0x96, 0x20, 0x5e, 0x60, 0x06, 0x61, 0x85, 0x65, 0x8a, +0x69, 0x8d, 0x6f, 0x95, 0x75, 0x97, 0x20, 0x60, 0x27, 0x09, 0x61, 0xa0, 0x63, 0x86, 0x65, 0x82, +0x69, 0xa1, 0x6f, 0xa2, 0x75, 0xa3, 0x43, 0x8f, 0x45, 0x90, 0x20, 0x27, 0x22, 0x0a, 0x61, 0x84, +0x65, 0x89, 0x69, 0x8b, 0x6f, 0x94, 0x75, 0x81, 0x79, 0x98, 0x41, 0x8e, 0x4f, 0x99, 0x55, 0x9a, +0x20, 0x22, 0x2c, 0x03, 0x63, 0x87, 0x43, 0x80, 0x20, 0x2c, 0x00, 0x02, 0x02, 0x03, 0x00, 0x00, +0x7e, 0x03, 0x02, 0x07, 0x00, 0x00, 0xc8, 0x05, 0x02, 0x07, 0x00, 0x00, 0xca, 0x06, 0x02, 0x07, +0x00, 0x00, 0xcb, 0x07, 0x02, 0x07, 0x00, 0x00, 0xcc, 0x08, 0x02, 0x03, 0x00, 0x00, 0x60, 0x09, +0x02, 0x07, 0x00, 0x00, 0xcd, 0x0a, 0x02, 0x07, 0x00, 0x00, 0xce, 0x0b, 0x02, 0x07, 0x00, 0x00, +0xcf, 0x0c, 0x02, 0x07, 0x00, 0x00, 0xd0, 0x0d, 0x02, 0x07, 0x00, 0x00, 0xd1, 0x12, 0x42, 0x03, +0x00, 0x00, 0xaa, 0x13, 0x41, 0x00, 0x72, 0x52, 0x14, 0x41, 0x00, 0x74, 0x54, 0x1a, 0x41, 0x00, +0xe7, 0xe6, 0x1b, 0x41, 0x00, 0xd0, 0xd1, 0x1f, 0x41, 0x00, 0x73, 0x53, 0x20, 0x41, 0x00, 0x64, +0x44, 0x25, 0x42, 0x03, 0x00, 0x00, 0x88, 0x26, 0x42, 0x00, 0x6c, 0x4c, 0x9d, 0x27, 0x41, 0x00, +0x9f, 0xac, 0x28, 0x41, 0x00, 0x86, 0x8f, 0x29, 0x01, 0x03, 0xd1, 0xd0, 0x2b, 0x41, 0x00, 0xa7, +0xa6, 0x00, 0xf3, 0x13, 0x63, 0x9f, 0x64, 0xd4, 0x65, 0xd8, 0x6c, 0x96, 0x6e, 0xe5, 0x72, 0xfd, +0x73, 0xe7, 0x74, 0x9c, 0x7a, 0xa7, 0x43, 0xac, 0x44, 0xd2, 0x45, 0xb7, 0x4c, 0x95, 0x4e, 0xd5, +0x52, 0xfc, 0x53, 0xe6, 0x54, 0x9b, 0x5a, 0xa6, 0x20, 0xf3, 0x5e, 0x07, 0x61, 0x83, 0x69, 0x8c, +0x6f, 0x93, 0x41, 0xb6, 0x49, 0xd7, 0x4f, 0xe2, 0x20, 0x5e, 0xf4, 0x03, 0x61, 0xc7, 0x41, 0xc6, +0x20, 0xf4, 0xf8, 0x03, 0x75, 0x85, 0x55, 0xde, 0x20, 0xf8, 0xf2, 0x05, 0x61, 0xa5, 0x65, 0xa9, +0x41, 0xa4, 0x45, 0xa8, 0x20, 0xf2, 0xfa, 0x03, 0x7a, 0xbe, 0x5a, 0xbd, 0x20, 0xfa, 0xef, 0x19, +0x61, 0xa0, 0x63, 0x86, 0x65, 0x82, 0x69, 0xa1, 0x6c, 0x92, 0x6e, 0xe4, 0x6f, 0xa2, 0x72, 0xea, +0x73, 0x98, 0x75, 0xa3, 0x79, 0xec, 0x7a, 0xab, 0x41, 0xb5, 0x43, 0x8f, 0x45, 0x90, 0x49, 0xd6, +0x4c, 0x91, 0x4e, 0xe3, 0x4f, 0xe0, 0x52, 0xe8, 0x53, 0x97, 0x55, 0xe9, 0x59, 0xed, 0x5a, 0x8d, +0x20, 0xef, 0xf1, 0x05, 0x6f, 0x8b, 0x75, 0xfb, 0x4f, 0x8a, 0x55, 0xeb, 0x20, 0xf1, 0xf9, 0x09, +0x61, 0x84, 0x65, 0x89, 0x6f, 0x94, 0x75, 0x81, 0x41, 0x8e, 0x45, 0xd3, 0x4f, 0x99, 0x55, 0x9a, +0x20, 0xf9, 0xf7, 0x07, 0x63, 0x87, 0x73, 0xad, 0x74, 0xee, 0x43, 0x80, 0x53, 0xb8, 0x54, 0xdd, +0x20, 0xf7, 0x00, 0x12, 0x42, 0x03, 0x00, 0x00, 0xd5, 0x00, 0x7e, 0x07, 0x61, 0xc6, 0x6e, 0xa4, +0x6f, 0xe4, 0x41, 0xc7, 0x4e, 0xa5, 0x4f, 0xe5, 0x20, 0x7e, 0x5e, 0x0b, 0x61, 0x83, 0x65, 0x88, +0x69, 0x8c, 0x6f, 0x93, 0x75, 0x96, 0x41, 0xb6, 0x45, 0xd2, 0x49, 0xd7, 0x4f, 0xe2, 0x55, 0xea, +0x20, 0x5e, 0xf8, 0x03, 0x61, 0x86, 0x41, 0x8f, 0x20, 0xf8, 0x60, 0x0b, 0x61, 0x85, 0x65, 0x8a, +0x69, 0x8d, 0x6f, 0x95, 0x75, 0x97, 0x41, 0xb7, 0x45, 0xd4, 0x49, 0xde, 0x4f, 0xe3, 0x55, 0xeb, +0x20, 0x60, 0xef, 0x0d, 0x61, 0xa0, 0x65, 0x82, 0x69, 0xa1, 0x6f, 0xa2, 0x75, 0xa3, 0x79, 0xec, +0x41, 0xb5, 0x45, 0x90, 0x49, 0xd6, 0x4f, 0xe0, 0x55, 0xe9, 0x59, 0xed, 0x20, 0xef, 0xf9, 0x0c, +0x61, 0x84, 0x65, 0x89, 0x69, 0x8b, 0x6f, 0x94, 0x75, 0x81, 0x79, 0x98, 0x41, 0x8e, 0x45, 0xd3, +0x49, 0xd8, 0x4f, 0x99, 0x55, 0x9a, 0x20, 0xf9, 0xf7, 0x03, 0x63, 0x87, 0x43, 0x80, 0x20, 0xf7, +0x00 }; + +// Hungary (101-key) +Bit8u layout_HU[964] = { +0x4b, 0x4c, 0x46, 0x00, 0x01, 0x04, 0x00, 0x00, 0x48, 0x55, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, +0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x03, 0xd3, 0x01, 0x44, 0x02, 0x00, 0x00, 0x5a, 0x03, +0x45, 0x01, 0x4c, 0x01, 0x00, 0x00, 0x52, 0x03, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x00, 0xb5, 0xe1, +0x05, 0x03, 0x59, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x07, 0x00, 0xcc, 0xc8, 0x03, 0x01, 0x03, 0x00, +0xcd, 0x04, 0x03, 0x05, 0x00, 0x2b, 0xc9, 0x1e, 0x05, 0x01, 0x01, 0x00, 0x21, 0x06, 0x02, 0x07, +0x00, 0x00, 0xca, 0x07, 0x01, 0x01, 0x00, 0x2f, 0x08, 0x02, 0x05, 0x00, 0x3d, 0xcb, 0x09, 0x02, +0x01, 0x00, 0x28, 0xfa, 0x0a, 0x02, 0x01, 0x00, 0x29, 0xef, 0x0b, 0x41, 0x00, 0x94, 0x99, 0x0c, +0x42, 0x00, 0x81, 0x9a, 0xf9, 0x0d, 0xc2, 0x04, 0xa2, 0x0d, 0xe0, 0x00, 0xce, 0x83, 0x10, 0x42, +0x03, 0x00, 0x00, 0x5c, 0x11, 0x42, 0x03, 0x00, 0x00, 0x7c, 0x12, 0x42, 0x00, 0x65, 0x45, 0x8e, +0x13, 0x42, 0x03, 0x00, 0x00, 0xf5, 0x14, 0x42, 0x03, 0x00, 0x00, 0xcf, 0x15, 0x41, 0x00, 0x79, +0x59, 0x16, 0x41, 0x00, 0x75, 0x55, 0x17, 0x42, 0x00, 0x69, 0x49, 0xd6, 0x18, 0x41, 0x00, 0x6f, +0x4f, 0x1a, 0x42, 0x03, 0xa0, 0xa0, 0xf6, 0x1b, 0x42, 0x00, 0xa3, 0xe9, 0x9e, 0x1e, 0x42, 0x00, +0x61, 0x41, 0x84, 0x21, 0x42, 0x03, 0x00, 0x00, 0x5b, 0x22, 0x42, 0x03, 0x00, 0x00, 0x5d, 0x24, +0x42, 0x03, 0x00, 0x00, 0xa1, 0x27, 0x42, 0x00, 0x82, 0x90, 0x24, 0x28, 0x42, 0x00, 0xa0, 0xb5, +0xe1, 0x29, 0x42, 0x00, 0xa1, 0xd6, 0x30, 0x2b, 0x42, 0x03, 0xa0, 0xa0, 0x5c, 0x2c, 0x42, 0x00, +0x7a, 0x5a, 0x3e, 0x2d, 0x42, 0x03, 0x00, 0x00, 0x23, 0x2e, 0x42, 0x00, 0x63, 0x43, 0x26, 0x2f, +0x42, 0x03, 0x00, 0x00, 0x40, 0x30, 0x42, 0x03, 0x00, 0x00, 0x7b, 0x31, 0x42, 0x00, 0x6e, 0x4e, +0x7d, 0x32, 0x42, 0x03, 0x00, 0x00, 0x3c, 0x33, 0x02, 0x00, 0x2c, 0x3f, 0x3b, 0x34, 0x02, 0x00, +0x2e, 0x3a, 0x3e, 0x35, 0x03, 0x00, 0x2d, 0x5f, 0x2a, 0x1f, 0x39, 0x00, 0x00, 0x20, 0x00, 0x16, +0x42, 0x03, 0x00, 0x00, 0xd5, 0x00, 0x7e, 0x07, 0x61, 0xc6, 0x6e, 0xa4, 0x6f, 0xe4, 0x41, 0xc7, +0x4e, 0xa5, 0x4f, 0xe5, 0x20, 0x7e, 0x5e, 0x0b, 0x61, 0x83, 0x65, 0x88, 0x69, 0x8c, 0x6f, 0x93, +0x75, 0x96, 0x41, 0xb6, 0x45, 0xd2, 0x49, 0xd7, 0x4f, 0xe2, 0x55, 0xea, 0x20, 0x5e, 0xf8, 0x03, +0x61, 0x86, 0x41, 0x8f, 0x20, 0xf8, 0x60, 0x0b, 0x61, 0x85, 0x65, 0x8a, 0x69, 0x8d, 0x6f, 0x95, +0x75, 0x97, 0x41, 0xb7, 0x45, 0xd4, 0x49, 0xde, 0x4f, 0xe3, 0x55, 0xeb, 0x20, 0x60, 0x27, 0x0d, +0x61, 0xa0, 0x65, 0x82, 0x69, 0xa1, 0x6f, 0xa2, 0x75, 0xa3, 0x79, 0xec, 0x41, 0xb5, 0x45, 0x90, +0x49, 0xd6, 0x4f, 0xe0, 0x55, 0xe9, 0x59, 0xed, 0x20, 0x27, 0x22, 0x0c, 0x61, 0x84, 0x65, 0x89, +0x69, 0x8b, 0x6f, 0x94, 0x75, 0x81, 0x79, 0x98, 0x41, 0x8e, 0x45, 0xd3, 0x49, 0xd8, 0x4f, 0x99, +0x55, 0x9a, 0x20, 0x22, 0xf7, 0x03, 0x63, 0x87, 0x43, 0x80, 0x20, 0xf7, 0x00, 0x02, 0x02, 0x03, +0x00, 0xce, 0x7e, 0x03, 0x02, 0x07, 0x00, 0xd0, 0xc8, 0x04, 0x01, 0x03, 0x00, 0xcf, 0x05, 0x02, +0x07, 0x00, 0x00, 0xca, 0x06, 0x02, 0x07, 0x00, 0x00, 0xcb, 0x07, 0x02, 0x07, 0x00, 0x00, 0xcc, +0x08, 0x02, 0x03, 0x00, 0x00, 0x60, 0x09, 0x02, 0x07, 0x00, 0x00, 0xcd, 0x0b, 0x42, 0x03, 0x00, +0x00, 0xf1, 0x0d, 0xc2, 0x05, 0x00, 0x0d, 0xe0, 0x00, 0xd1, 0x83, 0x13, 0x41, 0x00, 0x72, 0x52, +0x14, 0x41, 0x00, 0x74, 0x54, 0x16, 0x42, 0x03, 0x00, 0x00, 0xaa, 0x1a, 0x41, 0x00, 0x8b, 0x8a, +0x1f, 0x42, 0x00, 0x73, 0x53, 0xd0, 0x20, 0x42, 0x00, 0x64, 0x44, 0xd1, 0x25, 0x42, 0x03, 0x00, +0x00, 0x88, 0x26, 0x42, 0x00, 0x6c, 0x4c, 0x9d, 0x2b, 0x41, 0x00, 0xfb, 0xeb, 0x00, 0xf3, 0x13, +0x63, 0x9f, 0x64, 0xd4, 0x65, 0xd8, 0x6c, 0x96, 0x6e, 0xe5, 0x72, 0xfd, 0x73, 0xe7, 0x74, 0x9c, +0x7a, 0xa7, 0x43, 0xac, 0x44, 0xd2, 0x45, 0xb7, 0x4c, 0x95, 0x4e, 0xd5, 0x52, 0xfc, 0x53, 0xe6, +0x54, 0x9b, 0x5a, 0xa6, 0x20, 0xf3, 0x5e, 0x07, 0x61, 0x83, 0x69, 0x8c, 0x6f, 0x93, 0x41, 0xb6, +0x49, 0xd7, 0x4f, 0xe2, 0x20, 0x5e, 0xf4, 0x03, 0x61, 0xc7, 0x41, 0xc6, 0x20, 0xf4, 0xf8, 0x03, +0x75, 0x85, 0x55, 0xde, 0x20, 0xf8, 0xf2, 0x05, 0x61, 0xa5, 0x65, 0xa9, 0x41, 0xa4, 0x45, 0xa8, +0x20, 0xf2, 0xfa, 0x03, 0x7a, 0xbe, 0x5a, 0xbd, 0x20, 0xfa, 0x27, 0x19, 0x61, 0xa0, 0x63, 0x86, +0x65, 0x82, 0x69, 0xa1, 0x6c, 0x92, 0x6e, 0xe4, 0x6f, 0xa2, 0x72, 0xea, 0x73, 0x98, 0x75, 0xa3, +0x79, 0xec, 0x7a, 0xab, 0x41, 0xb5, 0x43, 0x8f, 0x45, 0x90, 0x49, 0xd6, 0x4c, 0x91, 0x4e, 0xe3, +0x4f, 0xe0, 0x52, 0xe8, 0x53, 0x97, 0x55, 0xe9, 0x59, 0xed, 0x5a, 0x8d, 0x20, 0x27, 0x2b, 0x05, +0x6f, 0x8b, 0x75, 0xfb, 0x4f, 0x8a, 0x55, 0xeb, 0x20, 0x2b, 0x22, 0x09, 0x61, 0x84, 0x65, 0x89, +0x6f, 0x94, 0x75, 0x81, 0x41, 0x8e, 0x45, 0xd3, 0x4f, 0x99, 0x55, 0x9a, 0x20, 0x22, 0xf7, 0x07, +0x63, 0x87, 0x73, 0xad, 0x74, 0xee, 0x43, 0x80, 0x53, 0xb8, 0x54, 0xdd, 0x20, 0xf7, 0x00, 0x02, +0x01, 0x03, 0x00, 0xcc, 0x03, 0x01, 0x03, 0x00, 0xce, 0x04, 0x01, 0x03, 0x00, 0xcd, 0x0a, 0x02, +0x07, 0x00, 0x00, 0xcc, 0x0b, 0x42, 0x07, 0x00, 0x00, 0xcd, 0x0c, 0x42, 0x07, 0x00, 0x00, 0xce, +0x0d, 0x42, 0x05, 0x00, 0x95, 0xcf, 0x13, 0x42, 0x03, 0x00, 0x00, 0x15, 0x14, 0x42, 0x07, 0x00, +0x00, 0xa0, 0x17, 0x42, 0x03, 0x00, 0x00, 0x8d, 0x1a, 0x41, 0x00, 0x93, 0xa7, 0x1b, 0x42, 0x05, +0x00, 0x97, 0xa0, 0x28, 0x41, 0x01, 0x00, 0x8f, 0x29, 0x41, 0x01, 0x00, 0x8d, 0x2b, 0x41, 0x00, +0x96, 0x98, 0x00, 0x7e, 0x03, 0x6e, 0xa4, 0x4e, 0xa5, 0x20, 0x7e, 0x5e, 0x04, 0x61, 0x83, 0x65, +0x88, 0x69, 0x8c, 0x20, 0x5e, 0xf8, 0x02, 0x61, 0x86, 0x20, 0xf8, 0x60, 0x03, 0x61, 0x85, 0x65, +0x8a, 0x20, 0x60, 0x27, 0x0b, 0x61, 0xa0, 0x65, 0x82, 0x69, 0xa1, 0x6f, 0xa2, 0x75, 0xa3, 0x41, +0x8f, 0x45, 0x90, 0x49, 0x8d, 0x4f, 0x95, 0x55, 0x97, 0x20, 0x27, 0x2b, 0x05, 0x6f, 0x93, 0x75, +0x96, 0x4f, 0xa7, 0x55, 0x98, 0x20, 0x2b, 0x22, 0x09, 0x61, 0x84, 0x65, 0x89, 0x69, 0x8b, 0x6f, +0x94, 0x75, 0x81, 0x41, 0x8e, 0x4f, 0x99, 0x55, 0x9a, 0x20, 0x22, 0x2c, 0x03, 0x63, 0x87, 0x43, +0x80, 0x20, 0x2c, 0x00 }; + +// Italy (Standard) +Bit8u layout_IT[236] = { +0x4b, 0x4c, 0x46, 0x00, 0x01, 0x09, 0x00, 0x00, 0x49, 0x54, 0x2c, 0x8d, 0x00, 0x49, 0x54, 0x04, +0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x03, 0xd0, 0x00, 0x00, +0x00, 0x00, 0x00, 0x52, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x01, 0xca, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x22, +0x04, 0x02, 0x01, 0x00, 0x9c, 0x23, 0x07, 0x01, 0x01, 0x00, 0x26, 0x08, 0x02, 0x01, 0x00, 0x2f, +0x7b, 0x09, 0x03, 0x01, 0x00, 0x28, 0x5b, 0x1b, 0x0a, 0x03, 0x01, 0x00, 0x29, 0x5d, 0x1d, 0x0b, +0x02, 0x01, 0x00, 0x3d, 0x7d, 0x0c, 0x01, 0x00, 0x27, 0x3f, 0x0d, 0x03, 0x00, 0x8d, 0x5e, 0x7e, +0x1e, 0x10, 0x42, 0x03, 0x00, 0x00, 0x40, 0x1a, 0x04, 0x08, 0x8a, 0x82, 0x5b, 0x00, 0x7b, 0x1b, +0x04, 0x08, 0x2b, 0x2a, 0x5d, 0x00, 0x7d, 0x27, 0x02, 0x00, 0x95, 0x87, 0x40, 0x28, 0x02, 0x00, +0x85, 0xf8, 0x23, 0x29, 0x03, 0x04, 0x5c, 0x7c, 0x00, 0x1c, 0x2b, 0x02, 0x00, 0x97, 0xf5, 0x60, +0x33, 0x02, 0x01, 0x00, 0x3b, 0x3c, 0x34, 0x02, 0x01, 0x00, 0x3a, 0x3e, 0x35, 0x03, 0x04, 0x2d, +0x5f, 0x00, 0x1f, 0x56, 0x01, 0x00, 0x3c, 0x3e, 0x00, 0x2b, 0x01, 0x01, 0x00, 0x15, 0x00, 0x06, +0x02, 0x03, 0x00, 0x00, 0xd5, 0x12, 0x42, 0x03, 0x00, 0x00, 0xd5, 0x00 }; + +// Netherlands (102-key) +Bit8u layout_NL[552] = { +0x4b, 0x4c, 0x46, 0x00, 0x01, 0x09, 0x00, 0x00, 0x4e, 0x4c, 0x2c, 0x8f, 0x00, 0x4e, 0x4c, 0x04, +0x02, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x03, 0x93, 0x01, 0x9a, +0x01, 0x00, 0x00, 0x52, 0x03, 0x00, 0x00, 0x9a, 0x01, 0x00, 0x00, 0xb5, 0x01, 0x16, 0x01, 0x40, +0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x00, 0x00, 0xfb, 0x03, 0x02, 0x01, 0x00, 0x22, 0xfd, 0x04, +0x02, 0x03, 0x00, 0x00, 0xfc, 0x05, 0x02, 0x03, 0x00, 0x00, 0xac, 0x06, 0x02, 0x03, 0x00, 0x00, +0xab, 0x07, 0x02, 0x01, 0x00, 0x26, 0xf3, 0x08, 0x03, 0x01, 0x00, 0x5f, 0x9c, 0x1f, 0x09, 0x02, +0x01, 0x00, 0x28, 0x7b, 0x0a, 0x02, 0x01, 0x00, 0x29, 0x7d, 0x0b, 0x01, 0x01, 0x00, 0x27, 0x0c, +0x03, 0x00, 0x2f, 0x3f, 0x5c, 0x1c, 0x0d, 0x02, 0x06, 0xf8, 0xc9, 0xcd, 0x12, 0x41, 0x00, 0x65, +0x45, 0x13, 0x42, 0x03, 0x00, 0x00, 0xf4, 0x15, 0x41, 0x00, 0x79, 0x59, 0x16, 0x41, 0x00, 0x75, +0x55, 0x17, 0x41, 0x00, 0x69, 0x49, 0x18, 0x41, 0x00, 0x6f, 0x4f, 0x1a, 0x03, 0x07, 0xcc, 0xca, +0x00, 0x1e, 0x1b, 0x02, 0x00, 0x2a, 0x7c, 0xdd, 0x1e, 0x41, 0x00, 0x61, 0x41, 0x1f, 0x42, 0x03, +0x00, 0x00, 0xe1, 0x27, 0x01, 0x00, 0x2b, 0xf1, 0x28, 0x01, 0x03, 0xcb, 0xc8, 0x29, 0x02, 0x00, +0x40, 0xf5, 0xaa, 0x2b, 0x01, 0x00, 0x3c, 0x3e, 0x2c, 0x42, 0x03, 0x00, 0x00, 0xae, 0x2d, 0x42, +0x03, 0x00, 0x00, 0xaf, 0x2e, 0x42, 0x00, 0x63, 0x43, 0xbd, 0x31, 0x41, 0x00, 0x6e, 0x4e, 0x32, +0x42, 0x03, 0x00, 0x00, 0xe6, 0x33, 0x03, 0x01, 0x00, 0x3b, 0x5b, 0x1b, 0x34, 0x02, 0x01, 0x00, +0x3a, 0xfa, 0x35, 0x03, 0x00, 0x2d, 0x3d, 0x5d, 0x1d, 0x39, 0x00, 0x00, 0x20, 0x56, 0x03, 0x00, +0x5d, 0x5b, 0x7c, 0x1d, 0x00, 0x02, 0x02, 0x07, 0x00, 0x00, 0xa0, 0x04, 0x02, 0x07, 0x00, 0x00, +0xa0, 0x07, 0x02, 0x07, 0x00, 0x00, 0xa0, 0x13, 0x42, 0x03, 0x00, 0x00, 0x14, 0x1b, 0x02, 0x07, +0x00, 0x00, 0xa0, 0x29, 0x01, 0x01, 0x00, 0x15, 0x2e, 0x42, 0x03, 0x00, 0x00, 0x9b, 0x00, 0x60, +0x06, 0x61, 0x85, 0x65, 0x8a, 0x69, 0x8d, 0x6f, 0x95, 0x75, 0x97, 0x20, 0x60, 0x7e, 0x03, 0x6e, +0xa4, 0x4e, 0xa5, 0x20, 0x7e, 0x5e, 0x06, 0x61, 0x83, 0x65, 0x88, 0x69, 0x8c, 0x6f, 0x93, 0x75, +0x96, 0x20, 0x5e, 0x27, 0x07, 0x61, 0xa0, 0x65, 0x82, 0x69, 0xa1, 0x6f, 0xa2, 0x75, 0xa3, 0x45, +0x90, 0x20, 0x27, 0x22, 0x0a, 0x61, 0x84, 0x65, 0x89, 0x69, 0x8b, 0x6f, 0x94, 0x75, 0x81, 0x79, +0x98, 0x41, 0x8e, 0x4f, 0x99, 0x55, 0x9a, 0x20, 0x22, 0x2c, 0x03, 0x63, 0x87, 0x43, 0x80, 0x20, +0x2c, 0x00, 0x12, 0x42, 0x03, 0x00, 0x00, 0xd5, 0x00, 0x60, 0x0b, 0x61, 0x85, 0x65, 0x8a, 0x69, +0x8d, 0x6f, 0x95, 0x75, 0x97, 0x41, 0xb7, 0x45, 0xd4, 0x49, 0xde, 0x4f, 0xe3, 0x55, 0xeb, 0x20, +0x60, 0x7e, 0x07, 0x61, 0xc6, 0x6e, 0xa4, 0x6f, 0xe4, 0x41, 0xc7, 0x4e, 0xa5, 0x4f, 0xe5, 0x20, +0x7e, 0x5e, 0x0b, 0x61, 0x83, 0x65, 0x88, 0x69, 0x8c, 0x6f, 0x93, 0x75, 0x96, 0x41, 0xb6, 0x45, +0xd2, 0x49, 0xd7, 0x4f, 0xe2, 0x55, 0xea, 0x20, 0x5e, 0xef, 0x0d, 0x61, 0xa0, 0x65, 0x82, 0x69, +0xa1, 0x6f, 0xa2, 0x75, 0xa3, 0x79, 0xec, 0x41, 0xb5, 0x45, 0x90, 0x49, 0xd6, 0x4f, 0xe0, 0x55, +0xe9, 0x59, 0xed, 0x20, 0xef, 0xf9, 0x0c, 0x61, 0x84, 0x65, 0x89, 0x69, 0x8b, 0x6f, 0x94, 0x75, +0x81, 0x79, 0x98, 0x41, 0x8e, 0x45, 0xd3, 0x49, 0xd8, 0x4f, 0x99, 0x55, 0x9a, 0x20, 0xf9, 0xf7, +0x03, 0x63, 0x87, 0x43, 0x80, 0x20, 0xf7, 0x00 }; + +// Norway +Bit8u layout_NO[477] = { +0x4b, 0x4c, 0x46, 0x00, 0x01, 0x09, 0x00, 0x00, 0x4e, 0x4f, 0x2c, 0x9b, 0x00, 0x4e, 0x4f, 0x04, +0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x03, 0xec, 0x00, 0xf9, +0x00, 0x00, 0x00, 0x52, 0x03, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x61, 0x03, 0x74, 0x01, 0x7f, +0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0x22, 0x40, 0x04, 0x02, 0x03, 0x00, 0x00, 0x9c, 0x05, +0x02, 0x01, 0x00, 0xcf, 0x24, 0x07, 0x01, 0x01, 0x00, 0x26, 0x08, 0x02, 0x01, 0x00, 0x2f, 0x7b, +0x09, 0x03, 0x01, 0x00, 0x28, 0x5b, 0x1b, 0x0a, 0x03, 0x01, 0x00, 0x29, 0x5d, 0x1d, 0x0b, 0x02, +0x01, 0x00, 0x3d, 0x7d, 0x0c, 0x01, 0x00, 0x2b, 0x3f, 0x0d, 0x03, 0x06, 0x5c, 0xc8, 0xcb, 0x1c, +0x12, 0x41, 0x00, 0x65, 0x45, 0x15, 0x41, 0x00, 0x79, 0x59, 0x16, 0x41, 0x00, 0x75, 0x55, 0x17, +0x41, 0x00, 0x69, 0x49, 0x18, 0x41, 0x00, 0x6f, 0x4f, 0x1a, 0x41, 0x00, 0x86, 0x8f, 0x1b, 0x03, +0x07, 0xcc, 0xca, 0xc9, 0x1e, 0x1e, 0x41, 0x00, 0x61, 0x41, 0x27, 0x41, 0x00, 0x9b, 0x9d, 0x28, +0x41, 0x00, 0x91, 0x92, 0x29, 0x01, 0x00, 0x7c, 0xf5, 0x2b, 0x01, 0x00, 0x27, 0x2a, 0x2e, 0x41, +0x00, 0x63, 0x43, 0x31, 0x41, 0x00, 0x6e, 0x4e, 0x32, 0x42, 0x03, 0x00, 0x00, 0xe6, 0x33, 0x02, +0x01, 0x00, 0x3b, 0x3c, 0x34, 0x02, 0x01, 0x00, 0x3a, 0x3e, 0x35, 0x03, 0x04, 0x2d, 0x5f, 0x00, +0x1f, 0x39, 0x00, 0x00, 0x20, 0x56, 0x01, 0x00, 0x3c, 0x3e, 0x00, 0x06, 0x02, 0x03, 0x00, 0x00, +0xd5, 0x12, 0x42, 0x03, 0x00, 0x00, 0xd5, 0x00, 0x60, 0x0b, 0x61, 0x85, 0x65, 0x8a, 0x69, 0x8d, +0x6f, 0x95, 0x75, 0x97, 0x41, 0xb7, 0x45, 0xd4, 0x49, 0xde, 0x4f, 0xe3, 0x55, 0xeb, 0x20, 0x60, +0x7e, 0x07, 0x61, 0xc6, 0x6e, 0xa4, 0x6f, 0xe4, 0x41, 0xc7, 0x4e, 0xa5, 0x4f, 0xe5, 0x20, 0x7e, +0x5e, 0x0b, 0x61, 0x83, 0x65, 0x88, 0x69, 0x8c, 0x6f, 0x93, 0x75, 0x96, 0x41, 0xb6, 0x45, 0xd2, +0x49, 0xd7, 0x4f, 0xe2, 0x55, 0xea, 0x20, 0x5e, 0xef, 0x0f, 0x61, 0xa0, 0x63, 0x87, 0x65, 0x82, +0x69, 0xa1, 0x6f, 0xa2, 0x75, 0xa3, 0x79, 0xec, 0x41, 0xb5, 0x43, 0x80, 0x45, 0x90, 0x49, 0xd6, +0x4f, 0xe0, 0x55, 0xe9, 0x59, 0xed, 0x20, 0xef, 0xf9, 0x0c, 0x61, 0x84, 0x65, 0x89, 0x69, 0x8b, +0x6f, 0x94, 0x75, 0x81, 0x79, 0x98, 0x41, 0x8e, 0x45, 0xd3, 0x49, 0xd8, 0x4f, 0x99, 0x55, 0x9a, +0x20, 0xf9, 0x00, 0x05, 0x01, 0x01, 0x00, 0xaf, 0x29, 0x01, 0x01, 0x00, 0x15, 0x00, 0x60, 0x06, +0x61, 0x85, 0x65, 0x8a, 0x69, 0x8d, 0x6f, 0x95, 0x75, 0x97, 0x20, 0x60, 0x7e, 0x03, 0x6e, 0xa4, +0x4e, 0xa5, 0x20, 0x7e, 0x5e, 0x06, 0x61, 0x83, 0x65, 0x88, 0x69, 0x8c, 0x6f, 0x93, 0x75, 0x96, +0x20, 0x5e, 0x27, 0x09, 0x61, 0xa0, 0x63, 0x87, 0x65, 0x82, 0x69, 0xa1, 0x6f, 0xa2, 0x75, 0xa3, +0x43, 0x80, 0x45, 0x90, 0x20, 0x27, 0x22, 0x0a, 0x61, 0x84, 0x65, 0x89, 0x69, 0x8b, 0x6f, 0x94, +0x75, 0x81, 0x79, 0x98, 0x41, 0x8e, 0x4f, 0x99, 0x55, 0x9a, 0x20, 0x22, 0x00 }; + +// Poland (101-key, prog.) +Bit8u layout_PL[261] = { +0x4b, 0x4c, 0x46, 0x00, 0x01, 0x09, 0x00, 0x00, 0x50, 0x4c, 0x2c, 0xc9, 0x01, 0x50, 0x4c, 0x08, +0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x03, 0x70, 0x00, 0x00, +0x00, 0x00, 0x00, 0x9c, 0x02, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0x03, 0xaf, 0x00, 0x00, +0x00, 0x00, 0x00, 0x16, 0x03, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x02, 0xaf, 0x00, 0x00, +0x00, 0x00, 0x00, 0x5a, 0x03, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x03, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x18, 0xc3, 0x03, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x00, 0xe0, 0x00, 0x00, 0x12, +0x43, 0x03, 0x00, 0x00, 0xa9, 0xa8, 0x16, 0x42, 0x03, 0x00, 0x00, 0xaa, 0x1e, 0x43, 0x03, 0x00, +0x00, 0xa5, 0xa4, 0x1f, 0x43, 0x03, 0x00, 0x00, 0x98, 0x97, 0x26, 0x43, 0x03, 0x00, 0x00, 0x88, +0x9d, 0x2c, 0x43, 0x03, 0x00, 0x00, 0xbe, 0xbd, 0x2d, 0x43, 0x03, 0x00, 0x00, 0xab, 0x8d, 0x2e, +0x43, 0x03, 0x00, 0x00, 0x86, 0x8f, 0x31, 0x43, 0x03, 0x00, 0x00, 0xe4, 0xe3, 0x00, 0x12, 0x43, +0x03, 0x00, 0x00, 0x91, 0x90, 0x18, 0x43, 0x07, 0x00, 0x00, 0x00, 0xa3, 0x1e, 0x43, 0x03, 0x00, +0x00, 0x86, 0x8f, 0x1f, 0x43, 0x03, 0x00, 0x00, 0x9e, 0x98, 0x26, 0x43, 0x03, 0x00, 0x00, 0x92, +0x9c, 0x2c, 0x43, 0x03, 0x00, 0x00, 0xa7, 0xa1, 0x2d, 0x43, 0x03, 0x00, 0x00, 0xa6, 0xa0, 0x2e, +0x43, 0x03, 0x00, 0x00, 0x8d, 0x95, 0x31, 0x43, 0x03, 0x00, 0x00, 0xa4, 0xa5, 0x00, 0x16, 0x42, +0x03, 0x00, 0x00, 0xd5, 0x00 }; + +// Russian Federation (Standard) +Bit8u layout_RU[1130] = { +0x4b, 0x4c, 0x46, 0x00, 0x01, 0x09, 0x00, 0x00, 0x52, 0x55, 0x2c, 0xb9, 0x01, 0x52, 0x55, 0x0b, +0x02, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x03, 0xa2, 0x01, 0x00, +0x00, 0x00, 0x00, 0x28, 0x03, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x03, 0x8b, 0x02, 0x00, +0x00, 0x00, 0x00, 0x62, 0x03, 0xb6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x68, 0x03, 0x6d, 0x03, 0x00, +0x00, 0x00, 0x00, 0x68, 0x03, 0x99, 0x02, 0x00, 0x00, 0x00, 0x00, 0x57, 0x03, 0x53, 0x04, 0x00, +0x00, 0x00, 0x00, 0x57, 0x03, 0x81, 0x03, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x03, 0xc5, 0x00, 0x00, +0x00, 0x00, 0x00, 0x52, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x03, 0x00, 0x00, +0x40, 0x04, 0x02, 0x03, 0x00, 0x00, 0x23, 0x05, 0x02, 0x03, 0x00, 0x00, 0xcf, 0x07, 0x02, 0x03, +0x00, 0x00, 0x5e, 0x08, 0x02, 0x03, 0x00, 0x00, 0x26, 0x09, 0x02, 0x03, 0x00, 0x00, 0x24, 0x1a, +0x02, 0x03, 0x00, 0x00, 0x5b, 0x1b, 0x02, 0x03, 0x00, 0x00, 0x5d, 0x2b, 0x02, 0x03, 0x00, 0x00, +0x7c, 0x33, 0x02, 0x03, 0x00, 0x00, 0x3c, 0x34, 0x02, 0x03, 0x00, 0x00, 0x3e, 0x35, 0x02, 0x03, +0x00, 0x00, 0x2f, 0x00, 0x12, 0x42, 0x03, 0x00, 0x00, 0xd5, 0x00, 0x03, 0x01, 0x01, 0x00, 0x22, +0x04, 0x01, 0x01, 0x00, 0xfc, 0x05, 0x02, 0x05, 0x00, 0x3b, 0xa0, 0x07, 0x01, 0x01, 0x00, 0x3a, +0x08, 0x01, 0x01, 0x00, 0x3f, 0x10, 0x41, 0x00, 0xa9, 0x89, 0x11, 0x41, 0x00, 0xe6, 0x96, 0x12, +0x41, 0x00, 0xe3, 0x93, 0x13, 0x41, 0x00, 0xaa, 0x8a, 0x14, 0x42, 0x00, 0xa5, 0x85, 0xfd, 0x15, +0x41, 0x00, 0xad, 0x8d, 0x16, 0x41, 0x00, 0xa3, 0x83, 0x17, 0x41, 0x00, 0xe8, 0x98, 0x18, 0x41, +0x00, 0xe9, 0x99, 0x19, 0x41, 0x00, 0xa7, 0x87, 0x1a, 0x41, 0x00, 0xe5, 0x95, 0x1b, 0x41, 0x00, +0xea, 0x9a, 0x1e, 0x41, 0x00, 0xe4, 0x94, 0x1f, 0x41, 0x00, 0xeb, 0x9b, 0x20, 0x41, 0x00, 0xa2, +0x82, 0x21, 0x41, 0x00, 0xa0, 0x80, 0x22, 0x41, 0x00, 0xaf, 0x8f, 0x23, 0xc1, 0x00, 0xe0, 0x00, +0x90, 0x23, 0x24, 0x41, 0x00, 0xae, 0x8e, 0x25, 0x41, 0x00, 0xab, 0x8b, 0x26, 0x41, 0x00, 0xa4, +0x84, 0x27, 0x41, 0x00, 0xa6, 0x86, 0x28, 0x41, 0x00, 0xed, 0x9d, 0x29, 0xc1, 0x00, 0xf1, 0x29, +0xf0, 0x00, 0x2a, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x78, 0x2b, 0x01, 0x01, 0x00, 0x2f, 0x2c, 0x41, +0x00, 0xef, 0x9f, 0x2d, 0x41, 0x00, 0xe7, 0x97, 0x2e, 0x41, 0x00, 0xe1, 0x91, 0x2f, 0x41, 0x00, +0xac, 0x8c, 0x30, 0x41, 0x00, 0xa8, 0x88, 0x31, 0x41, 0x00, 0xe2, 0x92, 0x32, 0x41, 0x00, 0xec, +0x9c, 0x33, 0x41, 0x00, 0xa1, 0x81, 0x34, 0x41, 0x00, 0xee, 0x9e, 0x35, 0x01, 0x00, 0x2e, 0x2c, +0x00, 0x05, 0x02, 0x07, 0x00, 0x00, 0xa0, 0x12, 0x42, 0x03, 0x00, 0x00, 0xfd, 0x36, 0x03, 0x0f, +0x00, 0x00, 0x00, 0x79, 0x00, 0x03, 0x01, 0x01, 0x00, 0x22, 0x04, 0x01, 0x01, 0x00, 0xfc, 0x05, +0x02, 0x01, 0x00, 0x3b, 0xfd, 0x07, 0x01, 0x01, 0x00, 0x3a, 0x08, 0x01, 0x01, 0x00, 0x3f, 0x10, +0x41, 0x00, 0xa9, 0x89, 0x11, 0x41, 0x00, 0xe6, 0x96, 0x12, 0x41, 0x00, 0xe3, 0x93, 0x13, 0x41, +0x00, 0xaa, 0x8a, 0x14, 0x41, 0x00, 0xa5, 0x85, 0x15, 0x41, 0x00, 0xad, 0x8d, 0x16, 0x41, 0x00, +0xa3, 0x83, 0x17, 0x41, 0x00, 0xe8, 0x98, 0x18, 0x41, 0x00, 0xe9, 0x99, 0x19, 0x41, 0x00, 0xa7, +0x87, 0x1a, 0x41, 0x00, 0xe5, 0x95, 0x1b, 0x41, 0x00, 0xea, 0x9a, 0x1e, 0x41, 0x00, 0xe4, 0x94, +0x1f, 0x41, 0x00, 0xeb, 0x9b, 0x20, 0x41, 0x00, 0xa2, 0x82, 0x21, 0x41, 0x00, 0xa0, 0x80, 0x22, +0x41, 0x00, 0xaf, 0x8f, 0x23, 0xc1, 0x00, 0xe0, 0x00, 0x90, 0x23, 0x24, 0x41, 0x00, 0xae, 0x8e, +0x25, 0x41, 0x00, 0xab, 0x8b, 0x26, 0x41, 0x00, 0xa4, 0x84, 0x27, 0x41, 0x00, 0xa6, 0x86, 0x28, +0x41, 0x00, 0xed, 0x9d, 0x29, 0xc1, 0x00, 0xf1, 0x29, 0xf0, 0x00, 0x2a, 0x03, 0x0f, 0x00, 0x00, +0x00, 0x7a, 0x2b, 0x01, 0x01, 0x00, 0x2f, 0x2c, 0x41, 0x00, 0xef, 0x9f, 0x2d, 0x41, 0x00, 0xe7, +0x97, 0x2e, 0x41, 0x00, 0xe1, 0x91, 0x2f, 0x41, 0x00, 0xac, 0x8c, 0x30, 0x41, 0x00, 0xa8, 0x88, +0x31, 0x41, 0x00, 0xe2, 0x92, 0x32, 0x41, 0x00, 0xec, 0x9c, 0x33, 0x41, 0x00, 0xa1, 0x81, 0x34, +0x41, 0x00, 0xee, 0x9e, 0x35, 0x01, 0x00, 0x2e, 0x2c, 0x00, 0x05, 0x02, 0x03, 0x00, 0x00, 0xfd, +0x36, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x03, 0x01, 0x01, 0x00, 0x22, 0x04, 0x01, 0x01, +0x00, 0xef, 0x05, 0x02, 0x05, 0x00, 0x3b, 0xa0, 0x07, 0x01, 0x01, 0x00, 0x3a, 0x08, 0x01, 0x01, +0x00, 0x3f, 0x10, 0x41, 0x00, 0xbd, 0xbe, 0x11, 0x41, 0x00, 0xa4, 0xa5, 0x12, 0x41, 0x00, 0xe7, +0xe8, 0x13, 0x41, 0x00, 0xc6, 0xc7, 0x14, 0x42, 0x00, 0xa8, 0xa9, 0xcf, 0x15, 0x41, 0x00, 0xd4, +0xd5, 0x16, 0x41, 0x00, 0xac, 0xad, 0x17, 0x41, 0x00, 0xf5, 0xf6, 0x18, 0x41, 0x00, 0xf9, 0xfa, +0x19, 0x41, 0x00, 0xf3, 0xf4, 0x1a, 0x41, 0x00, 0xb5, 0xb6, 0x1b, 0x41, 0x00, 0x9e, 0x9f, 0x1e, +0x41, 0x00, 0xaa, 0xab, 0x1f, 0x41, 0x00, 0xf1, 0xf2, 0x20, 0x41, 0x00, 0xeb, 0xec, 0x21, 0x41, +0x00, 0xa0, 0xa1, 0x22, 0x41, 0x00, 0xd8, 0xdd, 0x23, 0x41, 0x00, 0xe1, 0xe2, 0x24, 0x41, 0x00, +0xd6, 0xd7, 0x25, 0x41, 0x00, 0xd0, 0xd1, 0x26, 0x41, 0x00, 0xa6, 0xa7, 0x27, 0x41, 0x00, 0xe9, +0xea, 0x28, 0x41, 0x00, 0xf7, 0xf8, 0x29, 0x41, 0x00, 0x84, 0x85, 0x2a, 0x03, 0x0f, 0x00, 0x00, +0x00, 0x7c, 0x2b, 0x01, 0x01, 0x00, 0x2f, 0x2c, 0xc1, 0x00, 0xde, 0x2c, 0xe0, 0x00, 0x2d, 0x41, +0x00, 0xfb, 0xfc, 0x2e, 0x41, 0x00, 0xe3, 0xe4, 0x2f, 0x41, 0x00, 0xd2, 0xd3, 0x30, 0x41, 0x00, +0xb7, 0xb8, 0x31, 0x41, 0x00, 0xe5, 0xe6, 0x32, 0x41, 0x00, 0xed, 0xee, 0x33, 0x41, 0x00, 0xa2, +0xa3, 0x34, 0x41, 0x00, 0x9c, 0x9d, 0x35, 0x01, 0x00, 0x2e, 0x2c, 0x00, 0x05, 0x02, 0x07, 0x00, +0x00, 0xa0, 0x12, 0x42, 0x03, 0x00, 0x00, 0xcf, 0x36, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x7d, 0x00, +0x03, 0x01, 0x01, 0x00, 0x22, 0x04, 0x01, 0x01, 0x00, 0xef, 0x05, 0x01, 0x01, 0x00, 0x3b, 0x07, +0x01, 0x01, 0x00, 0x3a, 0x08, 0x01, 0x01, 0x00, 0x3f, 0x10, 0x41, 0x00, 0xbd, 0xbe, 0x11, 0x41, +0x00, 0xa4, 0xa5, 0x12, 0x41, 0x00, 0xe7, 0xe8, 0x13, 0x41, 0x00, 0xc6, 0xc7, 0x14, 0x41, 0x00, +0xa8, 0xa9, 0x15, 0x41, 0x00, 0xd4, 0xd5, 0x16, 0x41, 0x00, 0xac, 0xad, 0x17, 0x41, 0x00, 0xf5, +0xf6, 0x18, 0x41, 0x00, 0xf9, 0xfa, 0x19, 0x41, 0x00, 0xf3, 0xf4, 0x1a, 0x41, 0x00, 0xb5, 0xb6, +0x1b, 0x41, 0x00, 0x9e, 0x9f, 0x1e, 0x41, 0x00, 0xaa, 0xab, 0x1f, 0x41, 0x00, 0xf1, 0xf2, 0x20, +0x41, 0x00, 0xeb, 0xec, 0x21, 0x41, 0x00, 0xa0, 0xa1, 0x22, 0x41, 0x00, 0xd8, 0xdd, 0x23, 0x41, +0x00, 0xe1, 0xe2, 0x24, 0x41, 0x00, 0xd6, 0xd7, 0x25, 0x41, 0x00, 0xd0, 0xd1, 0x26, 0x41, 0x00, +0xa6, 0xa7, 0x27, 0x41, 0x00, 0xe9, 0xea, 0x28, 0x41, 0x00, 0xf7, 0xf8, 0x29, 0x41, 0x00, 0x84, +0x85, 0x2a, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x7e, 0x2b, 0x01, 0x01, 0x00, 0x2f, 0x2c, 0xc1, 0x00, +0xde, 0x2c, 0xe0, 0x00, 0x2d, 0x41, 0x00, 0xfb, 0xfc, 0x2e, 0x41, 0x00, 0xe3, 0xe4, 0x2f, 0x41, +0x00, 0xd2, 0xd3, 0x30, 0x41, 0x00, 0xb7, 0xb8, 0x31, 0x41, 0x00, 0xe5, 0xe6, 0x32, 0x41, 0x00, +0xed, 0xee, 0x33, 0x41, 0x00, 0xa2, 0xa3, 0x34, 0x41, 0x00, 0x9c, 0x9d, 0x35, 0x01, 0x00, 0x2e, +0x2c, 0x00, 0x36, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x7f, 0x00 }; + +// Slovakia +Bit8u layout_SK[993] = { +0x4b, 0x4c, 0x46, 0x00, 0x01, 0x09, 0x00, 0x00, 0x53, 0x4b, 0x2c, 0xf5, 0x00, 0x53, 0x4b, 0x05, +0x02, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x03, 0x35, 0x01, 0xad, +0x01, 0x00, 0x00, 0x5a, 0x03, 0x44, 0x03, 0x4b, 0x03, 0x00, 0x00, 0x52, 0x03, 0x00, 0x00, 0x4b, +0x03, 0x00, 0x00, 0x63, 0x03, 0x6e, 0x02, 0xd7, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x04, 0x2b, 0x31, +0xc8, 0x03, 0x01, 0x01, 0xa0, 0x32, 0x04, 0x03, 0x05, 0xa0, 0x33, 0xc9, 0x1e, 0x05, 0x01, 0x01, +0xa0, 0x34, 0x06, 0x02, 0x05, 0xa0, 0x35, 0xca, 0x07, 0x01, 0x01, 0xa0, 0x36, 0x08, 0x02, 0x04, +0xec, 0x37, 0xcb, 0x09, 0x02, 0x00, 0xa0, 0x38, 0xfa, 0x0a, 0x02, 0x04, 0xa1, 0x39, 0xcc, 0x0b, +0x01, 0x00, 0x82, 0x30, 0x0c, 0x02, 0x04, 0x3d, 0x25, 0xcd, 0x0d, 0x02, 0x07, 0xcc, 0xa0, 0xce, +0x10, 0x42, 0x03, 0x00, 0x00, 0x5c, 0x11, 0x42, 0x03, 0x00, 0x00, 0x7c, 0x12, 0x41, 0x00, 0x65, +0x45, 0x15, 0x43, 0x04, 0x7a, 0x5a, 0x00, 0x1a, 0x16, 0x41, 0x00, 0x75, 0x55, 0x17, 0x41, 0x00, +0x69, 0x49, 0x18, 0x41, 0x00, 0x6f, 0x4f, 0x19, 0x42, 0x03, 0x00, 0x00, 0x27, 0x1a, 0x02, 0x00, +0xa3, 0x2f, 0xf6, 0x1b, 0x02, 0x00, 0x84, 0x28, 0x9e, 0x1e, 0x42, 0x00, 0x61, 0x41, 0x3c, 0x21, +0x42, 0x03, 0x00, 0x00, 0x5b, 0x22, 0x42, 0x03, 0x00, 0x00, 0x5d, 0x27, 0x02, 0x00, 0x93, 0x22, +0x24, 0x28, 0x02, 0x00, 0xf5, 0x21, 0xe1, 0x29, 0x01, 0x02, 0x3b, 0xca, 0x2b, 0x02, 0x01, 0xa0, +0x29, 0xcf, 0x2c, 0x43, 0x00, 0x79, 0x59, 0x3e, 0x19, 0x2d, 0x42, 0x03, 0x00, 0x00, 0x23, 0x2e, +0x42, 0x00, 0x63, 0x43, 0x26, 0x2f, 0x42, 0x03, 0x00, 0x00, 0x40, 0x30, 0x42, 0x03, 0x00, 0x00, +0x7b, 0x31, 0x42, 0x00, 0x6e, 0x4e, 0x7d, 0x33, 0x01, 0x01, 0x00, 0x3f, 0x34, 0x02, 0x01, 0x00, +0x3a, 0x2a, 0x35, 0x03, 0x04, 0x2d, 0x5f, 0x00, 0x1f, 0x39, 0x00, 0x00, 0x20, 0x56, 0x02, 0x00, +0x26, 0x2a, 0x3c, 0x00, 0x02, 0x02, 0x03, 0x00, 0x00, 0x7e, 0x03, 0x02, 0x06, 0x96, 0x00, 0xc8, +0x04, 0x00, 0x00, 0xe7, 0x05, 0x02, 0x06, 0x9f, 0x00, 0xca, 0x06, 0x02, 0x06, 0x9c, 0x00, 0xcb, +0x07, 0x02, 0x06, 0xa7, 0x00, 0xcc, 0x08, 0x02, 0x03, 0x00, 0x00, 0x60, 0x09, 0x02, 0x07, 0x00, +0x00, 0xcd, 0x0a, 0x02, 0x07, 0x00, 0x00, 0xce, 0x0b, 0x02, 0x07, 0x00, 0x00, 0xcf, 0x0c, 0x02, +0x07, 0x00, 0x00, 0xd0, 0x0d, 0x02, 0x07, 0xce, 0xc8, 0xd1, 0x12, 0x42, 0x03, 0x00, 0x00, 0xaa, +0x13, 0x41, 0x00, 0x72, 0x52, 0x14, 0x41, 0x00, 0x74, 0x54, 0x1f, 0x42, 0x00, 0x73, 0x53, 0xd0, +0x20, 0x42, 0x00, 0x64, 0x44, 0xd1, 0x25, 0x42, 0x03, 0x00, 0x00, 0x88, 0x26, 0x42, 0x00, 0x6c, +0x4c, 0x9d, 0x29, 0x01, 0x03, 0x00, 0xcb, 0x2b, 0x00, 0x00, 0xe5, 0x00, 0xf3, 0x13, 0x63, 0x9f, +0x64, 0xd4, 0x65, 0xd8, 0x6c, 0x96, 0x6e, 0xe5, 0x72, 0xfd, 0x73, 0xe7, 0x74, 0x9c, 0x7a, 0xa7, +0x43, 0xac, 0x44, 0xd2, 0x45, 0xb7, 0x4c, 0x95, 0x4e, 0xd5, 0x52, 0xfc, 0x53, 0xe6, 0x54, 0x9b, +0x5a, 0xa6, 0x20, 0xf3, 0x5e, 0x07, 0x61, 0x83, 0x69, 0x8c, 0x6f, 0x93, 0x41, 0xb6, 0x49, 0xd7, +0x4f, 0xe2, 0x20, 0x5e, 0xf4, 0x03, 0x61, 0xc7, 0x41, 0xc6, 0x20, 0xf4, 0xf8, 0x03, 0x75, 0x85, +0x55, 0xde, 0x20, 0xf8, 0xf2, 0x05, 0x61, 0xa5, 0x65, 0xa9, 0x41, 0xa4, 0x45, 0xa8, 0x20, 0xf2, +0xfa, 0x03, 0x7a, 0xbe, 0x5a, 0xbd, 0x20, 0xfa, 0xef, 0x19, 0x61, 0xa0, 0x63, 0x86, 0x65, 0x82, +0x69, 0xa1, 0x6c, 0x92, 0x6e, 0xe4, 0x6f, 0xa2, 0x72, 0xea, 0x73, 0x98, 0x75, 0xa3, 0x79, 0xec, +0x7a, 0xab, 0x41, 0xb5, 0x43, 0x8f, 0x45, 0x90, 0x49, 0xd6, 0x4c, 0x91, 0x4e, 0xe3, 0x4f, 0xe0, +0x52, 0xe8, 0x53, 0x97, 0x55, 0xe9, 0x59, 0xed, 0x5a, 0x8d, 0x20, 0xef, 0xf1, 0x05, 0x6f, 0x8b, +0x75, 0xfb, 0x4f, 0x8a, 0x55, 0xeb, 0x20, 0xf1, 0xf9, 0x09, 0x61, 0x84, 0x65, 0x89, 0x6f, 0x94, +0x75, 0x81, 0x41, 0x8e, 0x45, 0xd3, 0x4f, 0x99, 0x55, 0x9a, 0x20, 0xf9, 0xf7, 0x07, 0x63, 0x87, +0x73, 0xad, 0x74, 0xee, 0x43, 0x80, 0x53, 0xb8, 0x54, 0xdd, 0x20, 0xf7, 0x00, 0x02, 0x02, 0x03, +0x00, 0x00, 0x7e, 0x03, 0x02, 0x06, 0x8c, 0x00, 0xc8, 0x04, 0x00, 0x00, 0xa8, 0x05, 0x00, 0x00, +0x87, 0x06, 0x00, 0x00, 0x9f, 0x07, 0x00, 0x00, 0x91, 0x08, 0x02, 0x02, 0x98, 0x00, 0x60, 0x09, +0x02, 0x07, 0x00, 0x00, 0xa0, 0x0a, 0x02, 0x07, 0x00, 0x00, 0xcb, 0x0c, 0x02, 0x07, 0x00, 0x00, +0xcc, 0x0d, 0x02, 0x07, 0xcb, 0xc8, 0xa0, 0x13, 0x41, 0x00, 0x72, 0x52, 0x14, 0x41, 0x00, 0x74, +0x54, 0x1b, 0x02, 0x07, 0x00, 0x00, 0xa0, 0x1f, 0x41, 0x00, 0x73, 0x53, 0x20, 0x41, 0x00, 0x64, +0x44, 0x26, 0x41, 0x00, 0x6c, 0x4c, 0x28, 0x00, 0x00, 0xad, 0x29, 0x01, 0x03, 0x00, 0xca, 0x2b, +0x02, 0x06, 0xa4, 0x00, 0xa0, 0x00, 0x76, 0x13, 0x63, 0x87, 0x64, 0x83, 0x65, 0x88, 0x6c, 0x8c, +0x6e, 0xa4, 0x72, 0xa9, 0x73, 0xa8, 0x74, 0x9f, 0x7a, 0x91, 0x43, 0x80, 0x44, 0x85, 0x45, 0x89, +0x4c, 0x9c, 0x4e, 0xa5, 0x52, 0x9e, 0x53, 0x9b, 0x54, 0x86, 0x5a, 0x92, 0x20, 0x76, 0x5e, 0x03, +0x6f, 0x93, 0x4f, 0xa7, 0x20, 0x5e, 0xf8, 0x03, 0x75, 0x96, 0x55, 0xa6, 0x20, 0xf8, 0x27, 0x11, +0x61, 0xa0, 0x65, 0x82, 0x69, 0xa1, 0x6c, 0x8d, 0x6f, 0xa2, 0x72, 0xaa, 0x75, 0xa3, 0x79, 0x98, +0x41, 0x8f, 0x45, 0x90, 0x49, 0x8b, 0x4c, 0x8a, 0x4f, 0x95, 0x52, 0xab, 0x55, 0x97, 0x59, 0x9d, +0x20, 0x27, 0x22, 0x07, 0x61, 0x84, 0x6f, 0x94, 0x75, 0x81, 0x41, 0x8e, 0x4f, 0x99, 0x55, 0x9a, +0x20, 0x22, 0x00, 0x12, 0x42, 0x03, 0x00, 0x00, 0xd5, 0x00, 0x7e, 0x07, 0x61, 0xc6, 0x6e, 0xa4, +0x6f, 0xe4, 0x41, 0xc7, 0x4e, 0xa5, 0x4f, 0xe5, 0x20, 0x7e, 0x5e, 0x0b, 0x61, 0x83, 0x65, 0x88, +0x69, 0x8c, 0x6f, 0x93, 0x75, 0x96, 0x41, 0xb6, 0x45, 0xd2, 0x49, 0xd7, 0x4f, 0xe2, 0x55, 0xea, +0x20, 0x5e, 0xf8, 0x03, 0x61, 0x86, 0x41, 0x8f, 0x20, 0xf8, 0x60, 0x0b, 0x61, 0x85, 0x65, 0x8a, +0x69, 0x8d, 0x6f, 0x95, 0x75, 0x97, 0x41, 0xb7, 0x45, 0xd4, 0x49, 0xde, 0x4f, 0xe3, 0x55, 0xeb, +0x20, 0x60, 0x27, 0x0d, 0x61, 0xa0, 0x65, 0x82, 0x69, 0xa1, 0x6f, 0xa2, 0x75, 0xa3, 0x79, 0xec, +0x41, 0xb5, 0x45, 0x90, 0x49, 0xd6, 0x4f, 0xe0, 0x55, 0xe9, 0x59, 0xed, 0x20, 0xef, 0xf9, 0x0c, +0x61, 0x84, 0x65, 0x89, 0x69, 0x8b, 0x6f, 0x94, 0x75, 0x81, 0x79, 0x98, 0x41, 0x8e, 0x45, 0xd3, +0x49, 0xd8, 0x4f, 0x99, 0x55, 0x9a, 0x20, 0xf9, 0xf7, 0x03, 0x63, 0x87, 0x43, 0x80, 0x20, 0xf7, +0x00 }; + +// Spain +Bit8u layout_SP[471] = { +0x4b, 0x4c, 0x46, 0x00, 0x01, 0x1d, 0x00, 0x00, 0x53, 0x50, 0x2c, 0x00, 0x00, 0x45, 0x53, 0x2c, +0xac, 0x00, 0x53, 0x50, 0x2c, 0xac, 0x00, 0x45, 0x53, 0x2c, 0xad, 0x00, 0x53, 0x50, 0x2c, 0xad, +0x00, 0x45, 0x53, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, +0x03, 0x30, 0x01, 0x3d, 0x01, 0x00, 0x00, 0x52, 0x03, 0x00, 0x00, 0x3d, 0x01, 0x00, 0x00, 0xb5, +0x01, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x00, 0x00, 0x7c, 0x03, 0x02, 0x01, +0x00, 0x22, 0x40, 0x04, 0x02, 0x01, 0x00, 0xfa, 0x23, 0x05, 0x02, 0x07, 0x00, 0x00, 0xc9, 0x07, +0x02, 0x01, 0x00, 0x26, 0xaa, 0x08, 0x01, 0x01, 0x00, 0x2f, 0x09, 0x01, 0x01, 0x00, 0x28, 0x0a, +0x01, 0x01, 0x00, 0x29, 0x0b, 0x01, 0x01, 0x00, 0x3d, 0x0c, 0x01, 0x00, 0x27, 0x3f, 0x0d, 0x01, +0x00, 0xad, 0xa8, 0x12, 0x41, 0x00, 0x65, 0x45, 0x15, 0x41, 0x00, 0x79, 0x59, 0x16, 0x41, 0x00, +0x75, 0x55, 0x17, 0x41, 0x00, 0x69, 0x49, 0x18, 0x41, 0x00, 0x6f, 0x4f, 0x1a, 0x02, 0x03, 0xc8, +0xca, 0x5b, 0x1b, 0x02, 0x00, 0x2b, 0x2a, 0x5d, 0x1e, 0x41, 0x00, 0x61, 0x41, 0x27, 0x42, 0x00, +0xa4, 0xa5, 0x7e, 0x28, 0x02, 0x03, 0xcb, 0xcc, 0x7b, 0x29, 0x03, 0x00, 0xa7, 0xa6, 0x5c, 0x1c, +0x2b, 0x42, 0x00, 0x87, 0x80, 0x7d, 0x31, 0x41, 0x00, 0x6e, 0x4e, 0x33, 0x02, 0x01, 0x00, 0x3b, +0x3c, 0x34, 0x02, 0x01, 0x00, 0x3a, 0x3e, 0x35, 0x03, 0x00, 0x2d, 0x5f, 0x5c, 0x1f, 0x39, 0x00, +0x00, 0x20, 0x56, 0x01, 0x00, 0x3c, 0x3e, 0x00, 0x60, 0x06, 0x61, 0x85, 0x65, 0x8a, 0x69, 0x8d, +0x6f, 0x95, 0x75, 0x97, 0x20, 0x60, 0x7e, 0x03, 0x6e, 0xa4, 0x4e, 0xa5, 0x20, 0x7e, 0x5e, 0x06, +0x61, 0x83, 0x65, 0x88, 0x69, 0x8c, 0x6f, 0x93, 0x75, 0x96, 0x20, 0x5e, 0x27, 0x07, 0x61, 0xa0, +0x65, 0x82, 0x69, 0xa1, 0x6f, 0xa2, 0x75, 0xa3, 0x45, 0x90, 0x20, 0x27, 0x22, 0x0a, 0x61, 0x84, +0x65, 0x89, 0x69, 0x8b, 0x6f, 0x94, 0x75, 0x81, 0x79, 0x98, 0x41, 0x8e, 0x4f, 0x99, 0x55, 0x9a, +0x20, 0x22, 0x00, 0x06, 0x02, 0x03, 0x00, 0x00, 0xd5, 0x12, 0x42, 0x03, 0x00, 0x00, 0xd5, 0x00, +0x60, 0x0b, 0x61, 0x85, 0x65, 0x8a, 0x69, 0x8d, 0x6f, 0x95, 0x75, 0x97, 0x41, 0xb7, 0x45, 0xd4, +0x49, 0xde, 0x4f, 0xe3, 0x55, 0xeb, 0x20, 0x60, 0x7e, 0x07, 0x61, 0xc6, 0x6e, 0xa4, 0x6f, 0xe4, +0x41, 0xc7, 0x4e, 0xa5, 0x4f, 0xe5, 0x20, 0x7e, 0x5e, 0x0b, 0x61, 0x83, 0x65, 0x88, 0x69, 0x8c, +0x6f, 0x93, 0x75, 0x96, 0x41, 0xb6, 0x45, 0xd2, 0x49, 0xd7, 0x4f, 0xe2, 0x55, 0xea, 0x20, 0x5e, +0xef, 0x0d, 0x61, 0xa0, 0x65, 0x82, 0x69, 0xa1, 0x6f, 0xa2, 0x75, 0xa3, 0x79, 0xec, 0x41, 0xb5, +0x45, 0x90, 0x49, 0xd6, 0x4f, 0xe0, 0x55, 0xe9, 0x59, 0xed, 0x20, 0xef, 0xf9, 0x0c, 0x61, 0x84, +0x65, 0x89, 0x69, 0x8b, 0x6f, 0x94, 0x75, 0x81, 0x79, 0x98, 0x41, 0x8e, 0x45, 0xd3, 0x49, 0xd8, +0x4f, 0x99, 0x55, 0x9a, 0x20, 0xf9, 0x00 }; + +// Finland +Bit8u layout_SU[683] = { +0x4b, 0x4c, 0x46, 0x00, 0x01, 0x1d, 0x00, 0x00, 0x53, 0x55, 0x2c, 0x00, 0x00, 0x53, 0x56, 0x2c, +0x00, 0x00, 0x46, 0x49, 0x2c, 0x99, 0x00, 0x53, 0x55, 0x2c, 0x99, 0x00, 0x53, 0x56, 0x2c, 0x99, +0x00, 0x46, 0x49, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, +0x03, 0x55, 0x01, 0x62, 0x01, 0x00, 0x00, 0x5b, 0x03, 0xdd, 0x01, 0xff, 0x01, 0x00, 0x00, 0x52, +0x03, 0x00, 0x00, 0x62, 0x01, 0x00, 0x00, 0xb5, 0x01, 0xfc, 0x00, 0x06, 0x01, 0x00, 0x00, 0x00, +0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, +0x02, 0x01, 0x00, 0x22, 0x40, 0x04, 0x02, 0x03, 0x00, 0x00, 0x9c, 0x05, 0x02, 0x01, 0x00, 0xcf, +0x24, 0x07, 0x01, 0x01, 0x00, 0x26, 0x08, 0x02, 0x01, 0x00, 0x2f, 0x7b, 0x09, 0x03, 0x01, 0x00, +0x28, 0x5b, 0x1b, 0x0a, 0x03, 0x01, 0x00, 0x29, 0x5d, 0x1d, 0x0b, 0x02, 0x01, 0x00, 0x3d, 0x7d, +0x0c, 0x03, 0x00, 0x2b, 0x3f, 0x5c, 0x1c, 0x0d, 0x02, 0x03, 0xcb, 0xc8, 0x7c, 0x10, 0x42, 0x03, +0x00, 0x00, 0x40, 0x12, 0x41, 0x00, 0x65, 0x45, 0x15, 0x41, 0x00, 0x79, 0x59, 0x16, 0x41, 0x00, +0x75, 0x55, 0x17, 0x41, 0x00, 0x69, 0x49, 0x18, 0x41, 0x00, 0x6f, 0x4f, 0x1a, 0x41, 0x00, 0x86, +0x8f, 0x1b, 0x03, 0x07, 0xcc, 0xca, 0xc9, 0x1e, 0x1e, 0x41, 0x00, 0x61, 0x41, 0x27, 0x41, 0x00, +0x94, 0x99, 0x28, 0x41, 0x00, 0x84, 0x8e, 0x29, 0x01, 0x00, 0xf5, 0xab, 0x2b, 0x01, 0x00, 0x27, +0x2a, 0x2e, 0x41, 0x00, 0x63, 0x43, 0x31, 0x41, 0x00, 0x6e, 0x4e, 0x32, 0x42, 0x03, 0x00, 0x00, +0xe6, 0x33, 0x02, 0x01, 0x00, 0x3b, 0x3c, 0x34, 0x02, 0x01, 0x00, 0x3a, 0x3e, 0x35, 0x03, 0x04, +0x2d, 0x5f, 0x00, 0x1f, 0x39, 0x00, 0x00, 0x20, 0x56, 0x02, 0x00, 0x3c, 0x3e, 0x7c, 0x00, 0x05, +0x01, 0x03, 0x00, 0xa0, 0x29, 0x00, 0x00, 0x15, 0x00, 0x60, 0x06, 0x61, 0x85, 0x65, 0x8a, 0x69, +0x8d, 0x6f, 0x95, 0x75, 0x97, 0x20, 0x60, 0x7e, 0x03, 0x6e, 0xa4, 0x4e, 0xa5, 0x20, 0x7e, 0x5e, +0x06, 0x61, 0x83, 0x65, 0x88, 0x69, 0x8c, 0x6f, 0x93, 0x75, 0x96, 0x20, 0x5e, 0x27, 0x09, 0x61, +0xa0, 0x63, 0x87, 0x65, 0x82, 0x69, 0xa1, 0x6f, 0xa2, 0x75, 0xa3, 0x43, 0x80, 0x45, 0x90, 0x20, +0x27, 0x22, 0x0a, 0x61, 0x84, 0x65, 0x89, 0x69, 0x8b, 0x6f, 0x94, 0x75, 0x81, 0x79, 0x98, 0x41, +0x8e, 0x4f, 0x99, 0x55, 0x9a, 0x20, 0x22, 0x00, 0x06, 0x02, 0x03, 0x00, 0x00, 0xd5, 0x12, 0x42, +0x03, 0x00, 0x00, 0xd5, 0x00, 0x60, 0x0b, 0x61, 0x85, 0x65, 0x8a, 0x69, 0x8d, 0x6f, 0x95, 0x75, +0x97, 0x41, 0xb7, 0x45, 0xd4, 0x49, 0xde, 0x4f, 0xe3, 0x55, 0xeb, 0x20, 0x60, 0x7e, 0x07, 0x61, +0xc6, 0x6e, 0xa4, 0x6f, 0xe4, 0x41, 0xc7, 0x4e, 0xa5, 0x4f, 0xe5, 0x20, 0x7e, 0x5e, 0x0b, 0x61, +0x83, 0x65, 0x88, 0x69, 0x8c, 0x6f, 0x93, 0x75, 0x96, 0x41, 0xb6, 0x45, 0xd2, 0x49, 0xd7, 0x4f, +0xe2, 0x55, 0xea, 0x20, 0x5e, 0xef, 0x0f, 0x61, 0xa0, 0x63, 0x87, 0x65, 0x82, 0x69, 0xa1, 0x6f, +0xa2, 0x75, 0xa3, 0x79, 0xec, 0x41, 0xb5, 0x43, 0x80, 0x45, 0x90, 0x49, 0xd6, 0x4f, 0xe0, 0x55, +0xe9, 0x59, 0xed, 0x20, 0xef, 0xf9, 0x0c, 0x61, 0x84, 0x65, 0x89, 0x69, 0x8b, 0x6f, 0x94, 0x75, +0x81, 0x79, 0x98, 0x41, 0x8e, 0x45, 0xd3, 0x49, 0xd8, 0x4f, 0x99, 0x55, 0x9a, 0x20, 0xf9, 0x00, +0x06, 0x02, 0x03, 0x00, 0x00, 0xd5, 0x12, 0x42, 0x03, 0x00, 0x00, 0xd5, 0x1f, 0x41, 0x00, 0x73, +0x53, 0x28, 0x42, 0x07, 0x00, 0x00, 0xcd, 0x29, 0x01, 0x03, 0x00, 0xa0, 0x2c, 0x41, 0x00, 0x7a, +0x5a, 0x00, 0x60, 0x0b, 0x61, 0x85, 0x65, 0x8a, 0x69, 0x8d, 0x6f, 0x95, 0x75, 0x97, 0x41, 0xb7, +0x45, 0xd4, 0x49, 0xde, 0x4f, 0xe3, 0x55, 0xeb, 0x20, 0x60, 0x7e, 0x07, 0x61, 0xc6, 0x6e, 0xa4, +0x6f, 0xe4, 0x41, 0xc7, 0x4e, 0xa5, 0x4f, 0xe5, 0x20, 0x7e, 0x5e, 0x0b, 0x61, 0x83, 0x65, 0x88, +0x69, 0x8c, 0x6f, 0x93, 0x75, 0x96, 0x41, 0xb6, 0x45, 0xd2, 0x49, 0xd7, 0x4f, 0xe2, 0x55, 0xea, +0x20, 0x5e, 0x27, 0x0f, 0x61, 0xa0, 0x63, 0x87, 0x65, 0x82, 0x69, 0xa1, 0x6f, 0xa2, 0x75, 0xa3, +0x79, 0xec, 0x41, 0xb5, 0x43, 0x80, 0x45, 0x90, 0x49, 0xd6, 0x4f, 0xe0, 0x55, 0xe9, 0x59, 0xed, +0x20, 0x27, 0x22, 0x0d, 0x61, 0x84, 0x65, 0x89, 0x69, 0x8b, 0x6f, 0x94, 0x75, 0x81, 0x79, 0x98, +0x41, 0x8e, 0x45, 0xd3, 0x49, 0xd8, 0x4f, 0x99, 0x55, 0x9a, 0x59, 0xf3, 0x20, 0x22, 0x76, 0x05, +0x73, 0xf9, 0x7a, 0xf7, 0x53, 0xdd, 0x5a, 0xef, 0x20, 0x76, 0x00 }; + +// Sweden +Bit8u layout_SV[683] = { +0x4b, 0x4c, 0x46, 0x00, 0x01, 0x1d, 0x00, 0x00, 0x53, 0x55, 0x2c, 0x00, 0x00, 0x53, 0x56, 0x2c, +0x00, 0x00, 0x46, 0x49, 0x2c, 0x99, 0x00, 0x53, 0x55, 0x2c, 0x99, 0x00, 0x53, 0x56, 0x2c, 0x99, +0x00, 0x46, 0x49, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, +0x03, 0x55, 0x01, 0x62, 0x01, 0x00, 0x00, 0x5b, 0x03, 0xdd, 0x01, 0xff, 0x01, 0x00, 0x00, 0x52, +0x03, 0x00, 0x00, 0x62, 0x01, 0x00, 0x00, 0xb5, 0x01, 0xfc, 0x00, 0x06, 0x01, 0x00, 0x00, 0x00, +0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, +0x02, 0x01, 0x00, 0x22, 0x40, 0x04, 0x02, 0x03, 0x00, 0x00, 0x9c, 0x05, 0x02, 0x01, 0x00, 0xcf, +0x24, 0x07, 0x01, 0x01, 0x00, 0x26, 0x08, 0x02, 0x01, 0x00, 0x2f, 0x7b, 0x09, 0x03, 0x01, 0x00, +0x28, 0x5b, 0x1b, 0x0a, 0x03, 0x01, 0x00, 0x29, 0x5d, 0x1d, 0x0b, 0x02, 0x01, 0x00, 0x3d, 0x7d, +0x0c, 0x03, 0x00, 0x2b, 0x3f, 0x5c, 0x1c, 0x0d, 0x02, 0x03, 0xcb, 0xc8, 0x7c, 0x10, 0x42, 0x03, +0x00, 0x00, 0x40, 0x12, 0x41, 0x00, 0x65, 0x45, 0x15, 0x41, 0x00, 0x79, 0x59, 0x16, 0x41, 0x00, +0x75, 0x55, 0x17, 0x41, 0x00, 0x69, 0x49, 0x18, 0x41, 0x00, 0x6f, 0x4f, 0x1a, 0x41, 0x00, 0x86, +0x8f, 0x1b, 0x03, 0x07, 0xcc, 0xca, 0xc9, 0x1e, 0x1e, 0x41, 0x00, 0x61, 0x41, 0x27, 0x41, 0x00, +0x94, 0x99, 0x28, 0x41, 0x00, 0x84, 0x8e, 0x29, 0x01, 0x00, 0xf5, 0xab, 0x2b, 0x01, 0x00, 0x27, +0x2a, 0x2e, 0x41, 0x00, 0x63, 0x43, 0x31, 0x41, 0x00, 0x6e, 0x4e, 0x32, 0x42, 0x03, 0x00, 0x00, +0xe6, 0x33, 0x02, 0x01, 0x00, 0x3b, 0x3c, 0x34, 0x02, 0x01, 0x00, 0x3a, 0x3e, 0x35, 0x03, 0x04, +0x2d, 0x5f, 0x00, 0x1f, 0x39, 0x00, 0x00, 0x20, 0x56, 0x02, 0x00, 0x3c, 0x3e, 0x7c, 0x00, 0x05, +0x01, 0x03, 0x00, 0xa0, 0x29, 0x00, 0x00, 0x15, 0x00, 0x60, 0x06, 0x61, 0x85, 0x65, 0x8a, 0x69, +0x8d, 0x6f, 0x95, 0x75, 0x97, 0x20, 0x60, 0x7e, 0x03, 0x6e, 0xa4, 0x4e, 0xa5, 0x20, 0x7e, 0x5e, +0x06, 0x61, 0x83, 0x65, 0x88, 0x69, 0x8c, 0x6f, 0x93, 0x75, 0x96, 0x20, 0x5e, 0x27, 0x09, 0x61, +0xa0, 0x63, 0x87, 0x65, 0x82, 0x69, 0xa1, 0x6f, 0xa2, 0x75, 0xa3, 0x43, 0x80, 0x45, 0x90, 0x20, +0x27, 0x22, 0x0a, 0x61, 0x84, 0x65, 0x89, 0x69, 0x8b, 0x6f, 0x94, 0x75, 0x81, 0x79, 0x98, 0x41, +0x8e, 0x4f, 0x99, 0x55, 0x9a, 0x20, 0x22, 0x00, 0x06, 0x02, 0x03, 0x00, 0x00, 0xd5, 0x12, 0x42, +0x03, 0x00, 0x00, 0xd5, 0x00, 0x60, 0x0b, 0x61, 0x85, 0x65, 0x8a, 0x69, 0x8d, 0x6f, 0x95, 0x75, +0x97, 0x41, 0xb7, 0x45, 0xd4, 0x49, 0xde, 0x4f, 0xe3, 0x55, 0xeb, 0x20, 0x60, 0x7e, 0x07, 0x61, +0xc6, 0x6e, 0xa4, 0x6f, 0xe4, 0x41, 0xc7, 0x4e, 0xa5, 0x4f, 0xe5, 0x20, 0x7e, 0x5e, 0x0b, 0x61, +0x83, 0x65, 0x88, 0x69, 0x8c, 0x6f, 0x93, 0x75, 0x96, 0x41, 0xb6, 0x45, 0xd2, 0x49, 0xd7, 0x4f, +0xe2, 0x55, 0xea, 0x20, 0x5e, 0xef, 0x0f, 0x61, 0xa0, 0x63, 0x87, 0x65, 0x82, 0x69, 0xa1, 0x6f, +0xa2, 0x75, 0xa3, 0x79, 0xec, 0x41, 0xb5, 0x43, 0x80, 0x45, 0x90, 0x49, 0xd6, 0x4f, 0xe0, 0x55, +0xe9, 0x59, 0xed, 0x20, 0xef, 0xf9, 0x0c, 0x61, 0x84, 0x65, 0x89, 0x69, 0x8b, 0x6f, 0x94, 0x75, +0x81, 0x79, 0x98, 0x41, 0x8e, 0x45, 0xd3, 0x49, 0xd8, 0x4f, 0x99, 0x55, 0x9a, 0x20, 0xf9, 0x00, +0x06, 0x02, 0x03, 0x00, 0x00, 0xd5, 0x12, 0x42, 0x03, 0x00, 0x00, 0xd5, 0x1f, 0x41, 0x00, 0x73, +0x53, 0x28, 0x42, 0x07, 0x00, 0x00, 0xcd, 0x29, 0x01, 0x03, 0x00, 0xa0, 0x2c, 0x41, 0x00, 0x7a, +0x5a, 0x00, 0x60, 0x0b, 0x61, 0x85, 0x65, 0x8a, 0x69, 0x8d, 0x6f, 0x95, 0x75, 0x97, 0x41, 0xb7, +0x45, 0xd4, 0x49, 0xde, 0x4f, 0xe3, 0x55, 0xeb, 0x20, 0x60, 0x7e, 0x07, 0x61, 0xc6, 0x6e, 0xa4, +0x6f, 0xe4, 0x41, 0xc7, 0x4e, 0xa5, 0x4f, 0xe5, 0x20, 0x7e, 0x5e, 0x0b, 0x61, 0x83, 0x65, 0x88, +0x69, 0x8c, 0x6f, 0x93, 0x75, 0x96, 0x41, 0xb6, 0x45, 0xd2, 0x49, 0xd7, 0x4f, 0xe2, 0x55, 0xea, +0x20, 0x5e, 0x27, 0x0f, 0x61, 0xa0, 0x63, 0x87, 0x65, 0x82, 0x69, 0xa1, 0x6f, 0xa2, 0x75, 0xa3, +0x79, 0xec, 0x41, 0xb5, 0x43, 0x80, 0x45, 0x90, 0x49, 0xd6, 0x4f, 0xe0, 0x55, 0xe9, 0x59, 0xed, +0x20, 0x27, 0x22, 0x0d, 0x61, 0x84, 0x65, 0x89, 0x69, 0x8b, 0x6f, 0x94, 0x75, 0x81, 0x79, 0x98, +0x41, 0x8e, 0x45, 0xd3, 0x49, 0xd8, 0x4f, 0x99, 0x55, 0x9a, 0x59, 0xf3, 0x20, 0x22, 0x76, 0x05, +0x73, 0xf9, 0x7a, 0xf7, 0x53, 0xdd, 0x5a, 0xef, 0x20, 0x76, 0x00 }; diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 6a43bf0b..c6dd2146 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.62 2006-06-22 13:15:07 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.63 2006-10-27 13:37:14 c2woody Exp $ */ #include #include @@ -882,6 +882,70 @@ void IMGMOUNT_ProgramStart(Program * * make) { } +Bitu DOS_SwitchKeyboardLayout(const char* new_layout); +Bitu DOS_LoadKeyboardLayout(const char * layoutname, Bit32s codepage, const char * codepagefile); + +class KEYB : public Program { +public: + void Run(void); +}; + +void KEYB::Run(void) { + if (cmd->FindCommand(1,temp_line)) { + if (cmd->FindString("?",temp_line,false)) { + WriteOut(MSG_Get("PROGRAM_KEYB_SHOWHELP")); + } else { + /* first parameter is layout ID */ + Bitu keyb_error=0; + std::string cp_string; + if (cmd->FindCommand(2,cp_string)) { + /* second parameter is codepage number */ + Bit32s par_cp=atoi(cp_string.c_str()); + char cp_file_name[256]; + if (cmd->FindCommand(3,cp_string)) { + /* third parameter is codepage file */ + strcpy(cp_file_name, cp_string.c_str()); + } else { + /* no codepage file specified, use automatic selection */ + strcpy(cp_file_name, "auto"); + } + + keyb_error=DOS_LoadKeyboardLayout(temp_line.c_str(), par_cp, cp_file_name); + } else keyb_error=DOS_SwitchKeyboardLayout(temp_line.c_str()); + switch (keyb_error) { + case KEYB_NOERROR: + WriteOut(MSG_Get("PROGRAM_KEYB_NOERROR"),temp_line.c_str(),dos.loaded_codepage); + break; + case KEYB_FILENOTFOUND: + WriteOut(MSG_Get("PROGRAM_KEYB_FILENOTFOUND"),temp_line.c_str()); + WriteOut(MSG_Get("PROGRAM_KEYB_SHOWHELP")); + break; + case KEYB_INVALIDFILE: + WriteOut(MSG_Get("PROGRAM_KEYB_INVALIDFILE"),temp_line.c_str()); + break; + case KEYB_LAYOUTNOTFOUND: + WriteOut(MSG_Get("PROGRAM_KEYB_LAYOUTNOTFOUND"),temp_line.c_str(),dos.loaded_codepage); + break; + case KEYB_INVALIDCPFILE: + WriteOut(MSG_Get("PROGRAM_KEYB_INVCPFILE"),temp_line.c_str()); + WriteOut(MSG_Get("PROGRAM_KEYB_SHOWHELP")); + break; + default: + LOG(LOG_DOSMISC,LOG_ERROR)("KEYB:Invalid returncode %x",keyb_error); + break; + } + } + } else { + /* no parameter in the command line, just output codepage info */ + WriteOut(MSG_Get("PROGRAM_KEYB_INFO"),dos.loaded_codepage); + } +}; + +static void KEYB_ProgramStart(Program * * make) { + *make=new KEYB; +} + + void DOS_SetupPrograms(void) { /*Add Messages */ @@ -1048,6 +1112,20 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_IMGMOUNT_CANT_CREATE","Can't create drive from file.\n"); MSG_Add("PROGRAM_IMGMOUNT_MOUNT_NUMBER","Drive number %d mounted as %s\n"); + MSG_Add("PROGRAM_KEYB_INFO","Codepage %i has been loaded\n"); + MSG_Add("PROGRAM_KEYB_SHOWHELP", + "\033[32;1mKEYB\033[0m [keyboard layout ID[ codepage number[ codepage file]]]\n\n" + "Some examples:\n" + " \033[32;1mKEYB\033[0m: Display currently loaded codepage.\n" + " \033[32;1mKEYB\033[0m sp: Load the spanish (SP) layout, use an appropriate codepage.\n" + " \033[32;1mKEYB\033[0m sp 850: Load the spanish (SP) layout, use codepage 850.\n" + " \033[32;1mKEYB\033[0m sp 850 mycp.cpi: Same as above, but use file mycp.cpi.\n"); + MSG_Add("PROGRAM_KEYB_NOERROR","Keyboard layout %s loaded for codepage %i\n"); + MSG_Add("PROGRAM_KEYB_FILENOTFOUND","Keyboard file %s not found\n\n"); + MSG_Add("PROGRAM_KEYB_INVALIDFILE","Keyboard file %s invalid\n"); + MSG_Add("PROGRAM_KEYB_LAYOUTNOTFOUND","No layout in %s for codepage %i\n"); + MSG_Add("PROGRAM_KEYB_INVCPFILE","None or invalid codepage file for layout %s\n\n"); + /*regular setup*/ PROGRAMS_MakeFile("MOUNT.COM",MOUNT_ProgramStart); PROGRAMS_MakeFile("MEM.COM",MEM_ProgramStart); @@ -1056,4 +1134,5 @@ void DOS_SetupPrograms(void) { PROGRAMS_MakeFile("INTRO.COM",INTRO_ProgramStart); PROGRAMS_MakeFile("BOOT.COM",BOOT_ProgramStart); PROGRAMS_MakeFile("IMGMOUNT.COM", IMGMOUNT_ProgramStart); + PROGRAMS_MakeFile("KEYB.COM", KEYB_ProgramStart); } diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 2c8ae63b..54c4c33b 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.102 2006-08-05 09:06:44 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.103 2006-10-27 13:37:14 c2woody Exp $ */ #include #include @@ -432,10 +432,13 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&EMS_Init,true);//done secprop->Add_bool("ems",true); secprop->Add_string("umb","true"); + secprop->AddInitFunction(&DOS_KeyboardLayout_Init,true); + secprop->Add_string("keyboardlayout", "none"); MSG_Add("DOS_CONFIGFILE_HELP", "xms -- Enable XMS support.\n" "ems -- Enable EMS support.\n" "umb -- Enable UMB support (false,true,max).\n" + "keyboardlayout -- Language code of the keyboard layout (or none).\n" ); // Mscdex secprop->AddInitFunction(&MSCDEX_Init); diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index fae8a6e6..aa99c174 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -33,7 +33,6 @@ static Bitu call_int16,call_irq1,call_irq6; /* Nice table from BOCHS i should feel bad for ripping this */ #define none 0 -#define MAX_SCAN_CODE 0x58 static struct { Bit16u normal; Bit16u shift; @@ -131,7 +130,7 @@ static struct { { 0x8600, 0x8800, 0x8a00, 0x8c00 } /* F12 */ }; -static bool add_key_forced(Bit16u code) { +bool BIOS_AddKeyToBuffer(Bit16u code) { if (mem_readb(BIOS_KEYBOARD_FLAGS2)&8) return true; Bit16u start,end,head,tail,ttail; if (machine==MCH_PCJR) { @@ -157,7 +156,7 @@ static bool add_key_forced(Bit16u code) { } static void add_key(Bit16u code) { - if (code!=0) add_key_forced(code); + if (code!=0) BIOS_AddKeyToBuffer(code); } static bool get_key(Bit16u &code) { @@ -240,6 +239,7 @@ static Bitu IRQ1_Handler(void) { #else flags2&=~(0x40+0x20);//remove numlock/capslock pressed (hack for sdl only reporting states) #endif + if (DOS_LayoutKey(scancode,flags1,flags2,flags3)) return CBRET_NONE; switch (scancode) { /* First the hard ones */ case 0xfa: /* ack. Do nothing for now */ @@ -551,7 +551,7 @@ static Bitu INT16_Handler(void) { } break; case 0x05: /* STORE KEYSTROKE IN KEYBOARD BUFFER */ - if (add_key_forced(reg_cx)) reg_al=0; + if (BIOS_AddKeyToBuffer(reg_cx)) reg_al=0; else reg_al=1; break; case 0x12: /* GET EXTENDED SHIFT STATES */ diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 7079e45c..3a7c8fbf 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -117,7 +117,29 @@ void INT10_SetupRomMemory(void) { //Reserve checksum location checksumlocation = int10.rom.used++; } -}; +} + +void INT10_ReloadRomFonts(void) { + // 16x8 font + PhysPt font16pt=Real2Phys(int10.rom.font_16); + for (Bitu i=0;i<256*16;i++) { + phys_writeb(font16pt+i,int10_font_16[i]); + } + // 14x8 font + PhysPt font14pt=Real2Phys(int10.rom.font_14); + for (Bitu i=0;i<256*14;i++) { + phys_writeb(font14pt+i,int10_font_14[i]); + } + // 8x8 fonts + PhysPt font8pt=Real2Phys(int10.rom.font_8_first); + for (Bitu i=0;i<128*8;i++) { + phys_writeb(font8pt+i,int10_font_08[i]); + } + font8pt=Real2Phys(int10.rom.font_8_second); + for (Bitu i=0;i<128*8;i++) { + phys_writeb(font8pt+i,int10_font_08[i+128*8]); + } +} void INT10_SetupRomMemoryChecksum(void) { if (machine == MCH_VGA) { //EGA/VGA. Just to be safe diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index f8c9714d..26e93462 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -325,6 +325,9 @@ + + From cd64154623a1fdf76834ff526fb4e26dd59a094d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 31 Oct 2006 17:29:32 +0000 Subject: [PATCH 2631/4131] Warning instead of exit when joystick init fails. Fixes bug:1577125 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2716 --- src/gui/sdlmain.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 69e12a93..f4268761 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.122 2006-10-08 19:26:04 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.123 2006-10-31 17:29:32 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1355,10 +1355,14 @@ int main(int argc, char* argv[]) { if ( SDL_Init( SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM |SDL_INIT_NOPARACHUTE -#ifndef DISABLE_JOYSTICK - |SDL_INIT_JOYSTICK -#endif ) < 0 ) E_Exit("Can't init SDL %s",SDL_GetError()); + +#ifndef DISABLE_JOYSTICK + //Initialise Joystick seperately. This way we can warn when it fails instead + //of exiting the application + if( SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0 ) LOG_MSG("Failed to init joystick support"); +#endif + #if defined (WIN32) #if SDL_VERSION_ATLEAST(1, 2, 10) sdl.using_windib=true; From 60b6c06b542a32efe868d8946dc7d3b0da61dacc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 5 Nov 2006 17:30:54 +0000 Subject: [PATCH 2632/4131] increase iso image directory entry name size (prompt/hakonrk) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2717 --- src/dos/drives.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/drives.h b/src/dos/drives.h index e7c1707d..dbb9962f 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.33 2006-06-22 13:15:07 qbix79 Exp $ */ +/* $Id: drives.h,v 1.34 2006-11-05 17:30:54 c2woody Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ @@ -262,7 +262,7 @@ struct isoDirEntry { Bit16u VolumeSeqNumberL; Bit16u VolumeSeqNumberM; Bit8u fileIdentLength; - Bit8u ident[100]; + Bit8u ident[222]; } GCC_ATTRIBUTE(packed); #ifdef _MSC_VER From 45108072696a1e11541d0f4094f8adce053f783a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 7 Nov 2006 11:43:13 +0000 Subject: [PATCH 2633/4131] rewrite powf stuff a bit. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2718 --- configure.in | 2 ++ include/cross.h | 12 +++++++++++- src/hardware/mixer.cpp | 6 +----- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/configure.in b/configure.in index 037651df..5591b7ac 100644 --- a/configure.in +++ b/configure.in @@ -60,6 +60,8 @@ 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_CHECK_LIB([m],[powf],,[AC_DEFINE([DB_HAVE_NO_POWF],[1],[libm doesn't include powf])]) + dnl Checks for libraries. #Check if the compiler support attributes diff --git a/include/cross.h b/include/cross.h index e7a7b04c..671b4719 100644 --- a/include/cross.h +++ b/include/cross.h @@ -16,11 +16,15 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.h,v 1.16 2006-02-09 11:47:47 qbix79 Exp $ */ +/* $Id: cross.h,v 1.17 2006-11-07 11:43:12 qbix79 Exp $ */ #ifndef DOSBOX_CROSS_H #define DOSBOX_CROSS_H +#ifndef DOSBOX_DOSBOX_H +#include "dosbox.h" +#endif + #include #include #include @@ -56,4 +60,10 @@ #define ftruncate(blah,blah2) chsize(blah,blah2) #endif +//Solaris maybe others +#if defined (DB_HAVE_NO_POWF) +#include +static inline float powf (float x, float y) { return (float) pow (x,y); } +#endif + #endif diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index f33bdfb2..0badfbab 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.42 2006-08-25 09:40:19 c2woody Exp $ */ +/* $Id: mixer.cpp,v 1.43 2006-11-07 11:43:13 qbix79 Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -55,10 +55,6 @@ #define MIXER_REMAIN ((1< MIN_AUDIO) From 51dda5a3f6c62bce21c8e3239087ef436b19cd81 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 8 Nov 2006 20:20:09 +0000 Subject: [PATCH 2634/4131] Make valgrind happy. (and maybe us as well) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2719 --- src/shell/shell_misc.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 0fed3ec0..1241cbbd 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.45 2006-09-09 16:06:32 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.46 2006-11-08 20:20:09 qbix79 Exp $ */ #include #include @@ -441,6 +441,8 @@ bool DOS_Shell::Execute(char * name,char * args) { MEM_BlockWrite(Real2Phys(file_name),fullname,strlen(fullname)+1); /* Fill the command line */ CommandTail cmdtail; + cmdtail.count = 0; + memset(&cmdtail.buffer,0,126); //Else some part of the string is unitialized (valgrind) if (strlen(line)>126) line[126]=0; cmdtail.count=strlen(line); memcpy(cmdtail.buffer,line,strlen(line)); From 32e3a625d4ff5b5d75f243349964e92f5af49f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 11 Nov 2006 14:42:38 +0000 Subject: [PATCH 2635/4131] remove logging Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2720 --- src/cpu/core_dyn_x86/dyn_fpu_dh.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/cpu/core_dyn_x86/dyn_fpu_dh.h b/src/cpu/core_dyn_x86/dyn_fpu_dh.h index 10fdeb3f..267dbcd5 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu_dh.h +++ b/src/cpu/core_dyn_x86/dyn_fpu_dh.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dyn_fpu_dh.h,v 1.1 2006-10-13 17:42:48 c2woody Exp $ */ +/* $Id: dyn_fpu_dh.h,v 1.2 2006-11-11 14:42:38 c2woody Exp $ */ #include "dosbox.h" #if C_FPU @@ -195,7 +195,6 @@ static void dh_fpu_esc1(){ gen_call_function((void*)&FPU_FST_32,"%Ddr",DREG(EA)); break; case 0x04: /* FLDENV */ -// LOG_MSG("fldenv"); gen_call_function((void*)&FPU_FLDENV_DH,"%Ddr",DREG(EA)); cache_addb(0xd9); cache_addb(0x05|(decode.modrm.reg<<3)); @@ -208,7 +207,6 @@ static void dh_fpu_esc1(){ cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); break; case 0x06: /* FSTENV */ -// LOG_MSG("fstenv"); cache_addb(0xd9); cache_addb(0x05|(decode.modrm.reg<<3)); cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); @@ -363,14 +361,12 @@ static void dh_fpu_esc5(){ gen_call_function((void*)&FPU_FST_64,"%Ddr",DREG(EA)); break; case 0x04: /* FRSTOR */ - LOG_MSG("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 */ - LOG_MSG("fsave"); cache_addb(0xdd); cache_addb(0x05|(decode.modrm.reg<<3)); cache_addd((Bit32u)(&(dyn_dh_fpu.temp_state[0]))); From 26bc8da23d7d75a3cbd92bd2b7b6321852b7c8aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 14 Nov 2006 14:12:00 +0000 Subject: [PATCH 2636/4131] favoured use of old simple core; default to automatic core selection; some processor usage limiting capabilities for max cycles Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2721 --- include/cpu.h | 8 ++-- include/pic.h | 6 +-- src/cpu/core_simple.cpp | 4 ++ src/cpu/cpu.cpp | 87 +++++++++++++++++++++++++---------------- src/cpu/paging.cpp | 2 +- src/dos/dos_execute.cpp | 16 +++++--- src/dosbox.cpp | 14 +++++-- src/gui/render.cpp | 4 +- src/gui/sdlmain.cpp | 16 +++++--- 9 files changed, 99 insertions(+), 58 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 90ab3d95..ada9d691 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -37,9 +37,11 @@ #define CPU_AUTODETERMINE_MASK 0x03 /* CPU Cycle Timing */ -extern Bits CPU_Cycles; -extern Bits CPU_CycleLeft; -extern Bits CPU_CycleMax; +extern Bit32s CPU_Cycles; +extern Bit32s CPU_CycleLeft; +extern Bit32s CPU_CycleMax; +extern Bit32s CPU_OldCycleMax; +extern Bit32s CPU_CyclePercUsed; extern bool CPU_CycleAutoAdjust; extern Bitu CPU_AutoDetermineMode; diff --git a/include/pic.h b/include/pic.h index 37e61c9d..e74a3f32 100644 --- a/include/pic.h +++ b/include/pic.h @@ -21,9 +21,9 @@ /* CPU Cycle Timing */ -extern Bits CPU_Cycles; -extern Bits CPU_CycleLeft; -extern Bits CPU_CycleMax; +extern Bit32s CPU_Cycles; +extern Bit32s CPU_CycleLeft; +extern Bit32s CPU_CycleMax; typedef void (PIC_EOIHandler) (void); typedef void (* PIC_EventHandler)(Bitu val); diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp index e79514ab..a7d9c188 100644 --- a/src/cpu/core_simple.cpp +++ b/src/cpu/core_simple.cpp @@ -83,7 +83,11 @@ static const Bit32u AddrMaskTable[2]={0x0000ffff,0xffffffff}; static struct { Bitu opcode_index; +#if defined (_MSC_VER) + volatile HostPt cseip; +#else HostPt cseip; +#endif PhysPt base_ds,base_ss; SegNames base_val_ds; bool rep_zero; diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 243966be..2d8bddc8 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.87 2006-10-12 15:18:31 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.88 2006-11-14 14:11:59 c2woody Exp $ */ #include #include "dosbox.h" @@ -29,7 +29,7 @@ #include "support.h" Bitu DEBUG_EnableDebugger(void); -extern void GFX_SetTitle(Bits cycles ,Bits frameskip,bool paused); +extern void GFX_SetTitle(Bit32s cycles ,Bits frameskip,bool paused); #if 1 #undef LOG @@ -41,11 +41,13 @@ CPU_Regs cpu_regs; CPUBlock cpu; Segments Segs; -Bits CPU_Cycles = 0; -Bits CPU_CycleLeft = 0; -Bits CPU_CycleMax = 2500; -Bits CPU_CycleUp = 0; -Bits CPU_CycleDown = 0; +Bit32s CPU_Cycles = 0; +Bit32s CPU_CycleLeft = 0; +Bit32s CPU_CycleMax = 2500; +Bit32s CPU_OldCycleMax = 2500; +Bit32s CPU_CyclePercUsed = 100; +Bit32s CPU_CycleUp = 0; +Bit32s CPU_CycleDown = 0; CPU_Decoder * cpudecoder; bool CPU_CycleAutoAdjust; Bitu CPU_AutoDetermineMode; @@ -1450,7 +1452,11 @@ void CPU_SET_CRX(Bitu cr,Bitu value) { CPU_CycleAutoAdjust=true; CPU_CycleLeft=0; CPU_Cycles=0; + CPU_OldCycleMax=CPU_CycleMax; CPU_CycleMax=0; + GFX_SetTitle(CPU_CyclePercUsed,-1,false); + } else { + GFX_SetTitle(-1,-1,false); } #if (C_DYNAMIC_X86) if (CPU_AutoDetermineMode&CPU_AUTODETERMINE_CORE) { @@ -1459,7 +1465,6 @@ void CPU_SET_CRX(Bitu cr,Bitu value) { } #endif CPU_AutoDetermineMode<<=CPU_AUTODETERMINE_SHIFT; - GFX_SetTitle(-1,-1,false); } else { cpu.pmode=false; if (value & CR0_PAGING) LOG_MSG("Paging requested without PE=1"); @@ -1944,33 +1949,45 @@ void CPU_ENTER(bool use32,Bitu bytes,Bitu level) { } static void CPU_CycleIncrease(bool pressed) { - if (!pressed || CPU_CycleAutoAdjust) - return; - Bits old_cycles=CPU_CycleMax; - if(CPU_CycleUp < 100){ - CPU_CycleMax = (Bits)(CPU_CycleMax * (1 + (float)CPU_CycleUp / 100.0)); + if (!pressed) return; + if (CPU_CycleAutoAdjust) { + CPU_CyclePercUsed+=5; + if (CPU_CyclePercUsed>100) CPU_CyclePercUsed=100; + LOG_MSG("CPU:%d percent",CPU_CyclePercUsed); + GFX_SetTitle(CPU_CyclePercUsed,-1,false); } else { - CPU_CycleMax = (Bits)(CPU_CycleMax + CPU_CycleUp); + Bit32s old_cycles=CPU_CycleMax; + if (CPU_CycleUp < 100) { + CPU_CycleMax = (Bit32s)(CPU_CycleMax * (1 + (float)CPU_CycleUp / 100.0)); + } else { + CPU_CycleMax = (Bit32s)(CPU_CycleMax + CPU_CycleUp); + } + + CPU_CycleLeft=0;CPU_Cycles=0; + if (CPU_CycleMax==old_cycles) CPU_CycleMax++; + LOG_MSG("CPU:%d cycles",CPU_CycleMax); + GFX_SetTitle(CPU_CycleMax,-1,false); } - - CPU_CycleLeft=0;CPU_Cycles=0; - if (CPU_CycleMax==old_cycles) CPU_CycleMax++; - LOG_MSG("CPU:%d cycles",CPU_CycleMax); - GFX_SetTitle(CPU_CycleMax,-1,false); } static void CPU_CycleDecrease(bool pressed) { - if (!pressed || CPU_CycleAutoAdjust) - return; - if(CPU_CycleDown < 100){ - CPU_CycleMax = (Bits)(CPU_CycleMax / (1 + (float)CPU_CycleDown / 100.0)); + if (!pressed) return; + if (CPU_CycleAutoAdjust) { + CPU_CyclePercUsed-=5; + if (CPU_CyclePercUsed<=0) CPU_CyclePercUsed=1; + LOG_MSG("CPU:%d percent",CPU_CyclePercUsed); + GFX_SetTitle(CPU_CyclePercUsed,-1,false); } else { - CPU_CycleMax = (Bits)(CPU_CycleMax - CPU_CycleDown); + if (CPU_CycleDown < 100) { + CPU_CycleMax = (Bit32s)(CPU_CycleMax / (1 + (float)CPU_CycleDown / 100.0)); + } else { + CPU_CycleMax = (Bit32s)(CPU_CycleMax - CPU_CycleDown); + } + CPU_CycleLeft=0;CPU_Cycles=0; + if (CPU_CycleMax <= 0) CPU_CycleMax=1; + LOG_MSG("CPU:%d cycles",CPU_CycleMax); + GFX_SetTitle(CPU_CycleMax,-1,false); } - CPU_CycleLeft=0;CPU_Cycles=0; - if (CPU_CycleMax <= 0) CPU_CycleMax=1; - LOG_MSG("CPU:%d cycles",CPU_CycleMax); - GFX_SetTitle(CPU_CycleMax,-1,false); } class CPU: public Module_base { @@ -2037,11 +2054,14 @@ public: const char *cyclesLine = section->Get_string("cycles"); if (!strcasecmp(cyclesLine,"max")) { CPU_CycleMax=0; + CPU_CyclePercUsed=100; CPU_CycleAutoAdjust=true; } else { if (!strcasecmp(cyclesLine,"auto")) { CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CYCLES; CPU_CycleMax=3000; + CPU_OldCycleMax=3000; + CPU_CyclePercUsed=100; } else { CPU_CycleMax=atoi(cyclesLine); } @@ -2050,11 +2070,11 @@ public: CPU_CycleUp=section->Get_int("cycleup"); CPU_CycleDown=section->Get_int("cycledown"); const char * core=section->Get_string("core"); - cpudecoder=&CPU_Core_Normal_Run; + cpudecoder=&CPU_Core_Simple_Run; if (!strcasecmp(core,"normal")) { - cpudecoder=&CPU_Core_Normal_Run; - } else if (!strcasecmp(core,"simple")) { cpudecoder=&CPU_Core_Simple_Run; + } else if (!strcasecmp(core,"force_normal")) { + cpudecoder=&CPU_Core_Normal_Run; } else if (!strcasecmp(core,"full")) { cpudecoder=&CPU_Core_Full_Run; } @@ -2066,7 +2086,7 @@ public: cpudecoder=&CPU_Core_Dyn_X86_Run; CPU_Core_Dyn_X86_SetFPUMode(false); } else if (!strcasecmp(core,"auto")) { - cpudecoder=&CPU_Core_Normal_Run; + cpudecoder=&CPU_Core_Simple_Run; CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CORE; } #endif @@ -2081,7 +2101,8 @@ public: if(CPU_CycleMax <= 0) CPU_CycleMax = 2500; if(CPU_CycleUp <= 0) CPU_CycleUp = 500; if(CPU_CycleDown <= 0) CPU_CycleDown = 20; - GFX_SetTitle(CPU_CycleMax,-1,false); + if (CPU_CycleAutoAdjust) GFX_SetTitle(CPU_CyclePercUsed,-1,false); + else GFX_SetTitle(CPU_CycleMax,-1,false); return true; } ~CPU(){ /* empty */}; diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 0fdb6dca..c2d1f934 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -395,7 +395,7 @@ void PAGING_Enable(bool enabled) { // LOG(LOG_PAGING,LOG_NORMAL)("Disabled"); } else { if (cpudecoder==CPU_Core_Simple_Run) { - LOG_MSG("CPU core simple won't run this game,switching to normal"); +// LOG_MSG("CPU core simple won't run this game,switching to normal"); cpudecoder=CPU_Core_Normal_Run; CPU_CycleLeft+=CPU_Cycles; CPU_Cycles=0; diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index e938537d..bc8e1c21 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.56 2006-06-29 09:10:09 c2woody Exp $ */ +/* $Id: dos_execute.cpp,v 1.57 2006-11-14 14:11:59 c2woody Exp $ */ #include #include @@ -27,6 +27,7 @@ #include "callback.h" #include "debug.h" #include "cpu.h" +#include "paging.h" const char * RunningProgram="DOSBOX"; @@ -94,7 +95,7 @@ static void RestoreRegisters(void) { reg_sp+=18; } -extern void GFX_SetTitle(Bits cycles,Bits frameskip,bool paused); +extern void GFX_SetTitle(Bit32s cycles,Bits frameskip,bool paused); void DOS_UpdatePSPName(void) { DOS_MCB mcb(dos.psp()-1); static char name[9]; @@ -146,16 +147,19 @@ bool DOS_Terminate(bool tsr) { CPU_CycleAutoAdjust=false; CPU_CycleLeft=0; CPU_Cycles=0; - CPU_CycleMax=3000; + CPU_CycleMax=CPU_OldCycleMax; + GFX_SetTitle(CPU_OldCycleMax,-1,false); + } else { + GFX_SetTitle(-1,-1,false); } - #if (C_DYNAMIC_X86) +#if (C_DYNAMIC_X86) if (CPU_AutoDetermineMode&CPU_AUTODETERMINE_CORE) { - cpudecoder=&CPU_Core_Normal_Run; + if (PAGING_Enabled()) cpudecoder=&CPU_Core_Normal_Run; + else cpudecoder=&CPU_Core_Simple_Run; CPU_CycleLeft=0; CPU_Cycles=0; } #endif - GFX_SetTitle(-1,-1,false); return true; } diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 54c4c33b..25ea6d1b 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.103 2006-10-27 13:37:14 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.104 2006-11-14 14:11:59 c2woody Exp $ */ #include #include @@ -101,6 +101,8 @@ void MSCDEX_Init(Section*); void EMS_Init(Section*); void XMS_Init(Section*); +void DOS_KeyboardLayout_Init(Section*); + void AUTOEXEC_Init(Section*); void SHELL_Init(void); @@ -148,7 +150,7 @@ increaseticks: ticksScheduled = 0; } else { Bit32u ticksNew; - ticksNew=GetTicks(); + ticksNew=GetTicks(); ticksScheduled += ticksAdded; if (ticksNew > ticksLast) { ticksRemain = ticksNew-ticksLast; @@ -160,7 +162,7 @@ increaseticks: ticksAdded = ticksRemain; if (CPU_CycleAutoAdjust && (ticksAdded > 15 || ticksScheduled >= 250 || ticksDone >= 250) ) { /* ratio we are aiming for is around 90% usage*/ - Bits ratio = (ticksScheduled * (90*1024/100)) / ticksDone ; + Bits ratio = (ticksScheduled * (CPU_CyclePercUsed*90*1024/100/100)) / ticksDone; // LOG_MSG("Done %d schedulded %d ratio %d cycles %d", ticksDone, ticksScheduled, ratio, CPU_CycleMax); if (ratio <= 1024) CPU_CycleMax = (CPU_CycleMax * ratio) / 1024; @@ -277,12 +279,16 @@ void DOSBOX_Init(void) { ); secprop=control->AddSection_prop("cpu",&CPU_Init,true);//done +#if (C_DYNAMIC_X86) + secprop->Add_string("core","auto"); +#else secprop->Add_string("core","normal"); +#endif secprop->Add_string("cycles","auto"); secprop->Add_int("cycleup",500); secprop->Add_int("cycledown",20); MSG_Add("CPU_CONFIGFILE_HELP", - "core -- CPU Core used in emulation: simple,normal,full" + "core -- CPU Core used in emulation: normal" #if (C_DYNAMIC_X86) ",dynamic,auto.\n" " auto switches from normal to dynamic if appropriate" diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 180c0417..a1e476e5 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.47 2006-08-05 09:06:44 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.48 2006-11-14 14:12:00 c2woody Exp $ */ #include #include @@ -425,7 +425,7 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool RENDER_CallBack( GFX_CallBackReset ); } -extern void GFX_SetTitle(Bits cycles, Bits frameskip,bool paused); +extern void GFX_SetTitle(Bit32s cycles, Bits frameskip,bool paused); static void IncreaseFrameSkip(bool pressed) { if (!pressed) return; diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index f4268761..bb6480d0 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.123 2006-10-31 17:29:32 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.124 2006-11-14 14:12:00 c2woody Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -216,16 +216,20 @@ extern bool CPU_CycleAutoAdjust; //Globals for keyboard initialisation bool startup_state_numlock=false; bool startup_state_capslock=false; -void GFX_SetTitle(Bits cycles,Bits frameskip,bool paused){ +void GFX_SetTitle(Bit32s cycles,Bits frameskip,bool paused){ char title[200]={0}; - static Bits internal_cycles=0; + static Bit32s internal_cycles=0; static Bits internal_frameskip=0; if(cycles != -1) internal_cycles = cycles; if(frameskip != -1) internal_frameskip = frameskip; - if(CPU_CycleAutoAdjust) - sprintf(title,"DOSBox %s, Cpu Cycles: max, Frameskip %2d, Program: %8s",VERSION,internal_frameskip,RunningProgram); - else + if(CPU_CycleAutoAdjust) { + if (internal_cycles>=100) + sprintf(title,"DOSBox %s, Cpu Cycles: max, Frameskip %2d, Program: %8s",VERSION,internal_frameskip,RunningProgram); + else + sprintf(title,"DOSBox %s, Cpu Cycles: [%3d%%], Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram); + } else { sprintf(title,"DOSBox %s, Cpu Cycles: %8d, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram); + } if(paused) strcat(title," PAUSED"); SDL_WM_SetCaption(title,VERSION); From af1673c6f2ffd32729ab531e5bda30cf5f770cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 14 Nov 2006 20:01:42 +0000 Subject: [PATCH 2637/4131] re-fix deleting of hostwise open files (makes Alien Carnage work again without breaking Abuse) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2722 --- include/dos_system.h | 8 ++++++-- src/dos/dos_files.cpp | 18 ++++++++++-------- src/dos/drive_fat.cpp | 3 ++- src/dos/drive_local.cpp | 8 ++------ src/dos/drive_virtual.cpp | 1 + 5 files changed, 21 insertions(+), 17 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 0e1311e1..5e48e278 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.36 2006-06-22 13:15:07 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.37 2006-11-14 20:01:42 c2woody Exp $ */ #ifndef DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H @@ -96,10 +96,14 @@ private: class DOS_Device : public DOS_File { public: - DOS_Device(const DOS_Device& orig):DOS_File(orig) {devnum=orig.devnum; } + DOS_Device(const DOS_Device& orig):DOS_File(orig) { + devnum=orig.devnum; + open=true; + } DOS_Device & operator= (const DOS_Device & orig) { DOS_File::operator=(orig); devnum=orig.devnum; + open=true; return *this; } DOS_Device():DOS_File(),devnum(0){}; diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index a2208227..b4d29e1e 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.78 2006-08-05 10:39:44 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.79 2006-11-14 20:01:42 c2woody Exp $ */ #include #include @@ -307,7 +307,7 @@ bool DOS_ReadFile(Bit16u entry,Bit8u * data,Bit16u * amount) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; - if (!Files[handle]) { + if (!Files[handle] || !Files[handle]->IsOpen()) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; @@ -330,7 +330,7 @@ bool DOS_WriteFile(Bit16u entry,Bit8u * data,Bit16u * amount) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; - if (!Files[handle]) { + if (!Files[handle] || !Files[handle]->IsOpen()) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; @@ -353,7 +353,7 @@ bool DOS_SeekFile(Bit16u entry,Bit32u * pos,Bit32u type) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; - if (!Files[handle]) { + if (!Files[handle] || !Files[handle]->IsOpen()) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; @@ -370,7 +370,9 @@ bool DOS_CloseFile(Bit16u entry) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; - Files[handle]->Close(); + if (Files[handle]->IsOpen()) { + Files[handle]->Close(); + } DOS_PSP psp(dos.psp()); psp.SetFileHandle(entry,0xff); if (Files[handle]->RemoveRef()<=0) { @@ -576,7 +578,7 @@ bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; - if (!Files[handle]) { + if (!Files[handle] || !Files[handle]->IsOpen()) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; @@ -601,7 +603,7 @@ bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; - if (!Files[orig]) { + if (!Files[orig] || !Files[orig]->IsOpen()) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; @@ -1037,7 +1039,7 @@ bool DOS_GetFileDate(Bit16u entry, Bit16u* otime, Bit16u* odate) DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; - if (!Files[handle]) { + if (!Files[handle] || !Files[handle]->IsOpen()) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 9ec8d786..b1323cda 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.18 2006-07-05 21:18:14 c2woody Exp $ */ +/* $Id: drive_fat.cpp,v 1.19 2006-11-14 20:01:42 c2woody Exp $ */ #include #include @@ -91,6 +91,7 @@ fatFile::fatFile(const char* /*name*/, Bit32u startCluster, Bit32u fileLen, fatD firstCluster = startCluster; myDrive = useDrive; filelength = fileLen; + open = true; loadedSector = false; curSectOff = 0; seekpos = 0; diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index a9ebcfe8..3afab93e 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.71 2006-08-17 12:07:22 c2woody Exp $ */ +/* $Id: drive_local.cpp,v 1.72 2006-11-14 20:01:42 c2woody Exp $ */ #include #include @@ -160,11 +160,7 @@ bool localDrive::FileUnlink(char * name) { Bitu max = DOS_FILES; while(Files[i]->IsOpen() && max--) { Files[i]->Close(); - if (Files[i]->RemoveRef()<=0) { - delete Files[i]; - Files[i]=0; - break; - } + if (Files[i]->RemoveRef()<=0) break; } found_file=true; } diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 7ac1d0e2..2f900b6c 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -85,6 +85,7 @@ Virtual_File::Virtual_File(Bit8u * in_data,Bit32u in_size) { file_pos=0; date=DOS_PackDate(2002,10,1); time=DOS_PackTime(12,34,56); + open=true; } bool Virtual_File::Read(Bit8u * data,Bit16u * size) { From 61fffb166eac2d971214905bb64f8461bb18ba9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 20 Nov 2006 17:35:53 +0000 Subject: [PATCH 2638/4131] enable interrupts when leaving int16/ax=1 as bios uses sti/retf2 (fixes Joust) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2723 --- src/ints/bios_keyboard.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index aa99c174..58350f70 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -505,6 +505,8 @@ static Bitu INT16_Handler(void) { } break; case 0x01: /* CHECK FOR KEYSTROKE */ + // enable interrupt-flag after IRET of this int16 + mem_writew(SegPhys(ss)+reg_sp+4,(mem_readw(SegPhys(ss)+reg_sp+4) | FLAG_IF)); for (;;) { if (check_key(temp)) { if (!IsEnhancedKey(temp)) { From 563f6af7fe158ef8fedfdf7af0bedc1d9dcb7a9d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 21 Nov 2006 15:12:39 +0000 Subject: [PATCH 2639/4131] Make creative sb16 drivers whatcard.exe happy(no need to replace it anymore). Hopefully windows sb16 sound support still works. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2724 --- src/hardware/sblaster.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 2bf49e59..03d28771 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.58 2006-08-28 17:02:31 c2woody Exp $ */ +/* $Id: sblaster.cpp,v 1.59 2006-11-21 15:12:39 qbix79 Exp $ */ #include #include @@ -158,7 +158,8 @@ static SB_INFO sb; static char * copyright_string="COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; static Bit8u DSP_cmd_len[256] = { - 0,0,0,0, 0,2,0,0, 0,0,0,0, 0,0,0,0, // 0x00 +// 0,0,0,0, 1,2,0,0, 0,0,0,0, 0,0,2,1, // 0x00 for SB16. but breaks sbpro + 0,0,0,0, 0,2,0,0, 0,0,0,0, 0,0,2,1, // 0x00 1,0,0,0, 2,0,2,2, 0,0,0,0, 0,0,0,0, // 0x10 0,0,0,0, 2,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 0,0,0,0, 0,0,0,0, 1,0,0,0, 0,0,0,0, // 0x30 @@ -682,7 +683,7 @@ static void DSP_ADC_CallBack(DmaChannel * chan, DMAEvent event) { if (event!=DMA_UNMASKED) return; Bit8u val=128; DmaChannel * ch=GetDMAChannel(sb.hw.dma8); - while (sb.dma.left--) { + while (sb.dma.left--) { ch->Write(1,&val); } SB_RaiseIRQ(SB_IRQ_8); @@ -697,7 +698,7 @@ Bitu DEBUG_EnableDebugger(void); static void DSP_DoCommand(void) { // LOG_MSG("DSP Command %X",sb.dsp.cmd); switch (sb.dsp.cmd) { - case 0x04: /* DSP Status SB 2.0/pro version */ + case 0x04: /* DSP Status SB 2.0/pro version. NOT SB16. */ DSP_FlushData(); DSP_AddData(0xff); //Everthing enabled break; @@ -879,6 +880,12 @@ static void DSP_DoCommand(void) { case 0xa0: case 0xa8: /* Documented only for DSP 3.x */ LOG(LOG_SB,LOG_ERROR)("DSP:Unimplemented input command %2X",sb.dsp.cmd); break; + case 0x0f: /* SB16 ASP get register */ + DSP_AddData(0xff); //Fall through + case 0x0e: /* SB16 ASP Command ? */ + case 0x05: /* SB16 ASP set register */ + LOG(LOG_SB,LOG_NORMAL)("DSP Unhandled SB16ASP command %X",sb.dsp.cmd); + break; default: LOG(LOG_SB,LOG_ERROR)("DSP:Unhandled (undocumented) command %2X",sb.dsp.cmd); break; From d197ac5ee82db497a8ba21dd270c4f732a4ece2c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 1 Dec 2006 20:48:53 +0000 Subject: [PATCH 2640/4131] Fix ACAD R11. SaveSelector after modifying the setbusy bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2725 --- src/cpu/cpu.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 2d8bddc8..30204361 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.88 2006-11-14 14:11:59 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.89 2006-12-01 20:48:53 qbix79 Exp $ */ #include #include "dosbox.h" @@ -408,7 +408,8 @@ doconforming: CPU_SetSegGeneral(fs,new_fs); CPU_SetSegGeneral(gs,new_gs); if (!cpu_tss.SetSelector(new_tss_selector)) LOG(LOG_CPU,LOG_NORMAL)("TaskSwitch: set tss selector %X failed",new_tss_selector); - cpu_tss.desc.SetBusy(true); +// cpu_tss.desc.SetBusy(true); +// cpu_tss.SaveSelector(); // LOG_MSG("Task CPL %X CS:%X IP:%X SS:%X SP:%X eflags %x",cpu.cpl,SegValue(cs),reg_eip,SegValue(ss),reg_esp,reg_flags); return true; } @@ -1403,6 +1404,7 @@ bool CPU_LTR(Bitu selector) { } if (!cpu_tss.SetSelector(selector)) E_Exit("LTR failed, selector=%X",selector); cpu_tss.desc.SetBusy(true); + cpu_tss.SaveSelector(); } else { /* Descriptor was no available TSS descriptor */ LOG(LOG_CPU,LOG_NORMAL)("LTR failed, selector=%X (type=%X)",selector,desc.Type()); From ed121c32e1872586f7e896e99e7cba60ddc6b0ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 4 Dec 2006 15:49:01 +0000 Subject: [PATCH 2641/4131] start with better max cycles value when autoswitching to cycles=max (thanks gulikoza) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2726 --- src/cpu/cpu.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 30204361..f2e6c6b1 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.89 2006-12-01 20:48:53 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.90 2006-12-04 15:49:01 c2woody Exp $ */ #include #include "dosbox.h" @@ -1455,7 +1455,6 @@ void CPU_SET_CRX(Bitu cr,Bitu value) { CPU_CycleLeft=0; CPU_Cycles=0; CPU_OldCycleMax=CPU_CycleMax; - CPU_CycleMax=0; GFX_SetTitle(CPU_CyclePercUsed,-1,false); } else { GFX_SetTitle(-1,-1,false); From 454422c97070d13549192cc7436614d54f15ffd3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 12 Dec 2006 21:25:50 +0000 Subject: [PATCH 2642/4131] Type specifiers for unsigned values. Makes g++ happy. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2727 --- src/ints/int10_put_pixel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 93db017b..3f80d441 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -21,8 +21,8 @@ #include "inout.h" #include "int10.h" -static Bit8u cga_masks[4]={~192,~48,~12,~3}; -static Bit8u cga_masks2[8]={~128,~64,~32,~16,~8,~4,~2,~1}; +static Bit8u cga_masks[4]={~192U,~48U,~12U,~3U}; +static Bit8u cga_masks2[8]={~128U,~64U,~32U,~16U,~8U,~4U,~2U,~1U}; void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { switch (CurMode->type) { From fdd16dea1afd5086e6b1a777ce8915ae9418c98a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 8 Jan 2007 19:45:42 +0000 Subject: [PATCH 2643/4131] Happy New Year\! Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2728 --- acinclude.m4 | 2 +- include/bios.h | 2 +- include/callback.h | 4 ++-- include/cpu.h | 2 +- include/cross.h | 4 ++-- include/debug.h | 2 +- include/dma.h | 4 ++-- include/dos_inc.h | 4 ++-- include/dos_system.h | 4 ++-- include/dosbox.h | 2 +- include/fpu.h | 2 +- include/hardware.h | 2 +- include/inout.h | 4 ++-- include/ipx.h | 4 ++-- include/ipxserver.h | 2 +- include/joystick.h | 4 ++-- include/keyboard.h | 2 +- include/mapper.h | 2 +- include/mem.h | 2 +- include/mixer.h | 2 +- include/mouse.h | 4 ++-- include/paging.h | 4 ++-- include/pic.h | 2 +- include/programs.h | 2 +- include/regs.h | 2 +- include/render.h | 2 +- include/serialport.h | 4 ++-- include/setup.h | 4 ++-- include/shell.h | 4 ++-- include/support.h | 2 +- include/timer.h | 2 +- include/vga.h | 2 +- include/video.h | 2 +- src/cpu/callback.cpp | 4 ++-- src/cpu/core_dyn_x86.cpp | 2 +- src/cpu/core_dyn_x86/decoder.h | 2 +- src/cpu/core_dyn_x86/risc_x86.h | 2 +- src/cpu/core_dyn_x86/string.h | 2 +- src/cpu/core_full.cpp | 2 +- src/cpu/core_normal.cpp | 2 +- src/cpu/core_normal/helpers.h | 2 +- src/cpu/core_normal/prefix_0f.h | 2 +- src/cpu/core_normal/prefix_66.h | 2 +- src/cpu/core_normal/prefix_66_0f.h | 2 +- src/cpu/core_normal/prefix_none.h | 2 +- src/cpu/core_normal/support.h | 2 +- src/cpu/core_normal/table_ea.h | 2 +- src/cpu/core_simple.cpp | 2 +- src/cpu/cpu.cpp | 4 ++-- src/cpu/flags.cpp | 2 +- src/cpu/instructions.h | 2 +- src/cpu/lazyflags.h | 2 +- src/cpu/modrm.cpp | 2 +- src/cpu/modrm.h | 2 +- src/cpu/paging.cpp | 2 +- src/debug/debug.cpp | 4 ++-- src/debug/debug_gui.cpp | 4 ++-- src/debug/debug_inc.h | 4 ++-- src/debug/debug_win32.cpp | 2 +- src/debug/disasm_tables.h | 2 +- src/dos/cdrom.cpp | 2 +- src/dos/cdrom_aspi_win32.cpp | 4 ++-- src/dos/cdrom_image.cpp | 4 ++-- src/dos/cdrom_ioctl_linux.cpp | 2 +- src/dos/cdrom_ioctl_os2.cpp | 4 ++-- src/dos/cdrom_ioctl_win32.cpp | 4 ++-- src/dos/dev_con.h | 4 ++-- src/dos/dos.cpp | 4 ++-- src/dos/dos_classes.cpp | 4 ++-- src/dos/dos_devices.cpp | 4 ++-- src/dos/dos_execute.cpp | 4 ++-- src/dos/dos_files.cpp | 4 ++-- src/dos/dos_ioctl.cpp | 4 ++-- src/dos/dos_keyboard_layout.cpp | 2 +- src/dos/dos_memory.cpp | 2 +- src/dos/dos_misc.cpp | 4 ++-- src/dos/dos_mscdex.cpp | 4 ++-- src/dos/dos_programs.cpp | 4 ++-- src/dos/dos_tables.cpp | 4 ++-- src/dos/drive_cache.cpp | 4 ++-- src/dos/drive_fat.cpp | 4 ++-- src/dos/drive_iso.cpp | 4 ++-- src/dos/drive_local.cpp | 4 ++-- src/dos/drive_virtual.cpp | 2 +- src/dos/drives.cpp | 2 +- src/dos/drives.h | 4 ++-- src/dosbox.cpp | 4 ++-- src/fpu/fpu.cpp | 4 ++-- src/fpu/fpu_instructions.h | 4 ++-- src/fpu/fpu_instructions_x86.h | 4 ++-- src/gui/dosbox_logo.h | 4 ++-- src/gui/midi.cpp | 2 +- src/gui/midi_alsa.h | 4 ++-- src/gui/midi_coreaudio.h | 2 +- src/gui/midi_oss.h | 2 +- src/gui/midi_win32.h | 4 ++-- src/gui/render.cpp | 4 ++-- src/gui/render_loops.h | 2 +- src/gui/render_scalers.cpp | 2 +- src/gui/render_scalers.h | 2 +- src/gui/render_simple.h | 2 +- src/gui/render_templates.h | 2 +- src/gui/render_templates_hq.h | 2 +- src/gui/render_templates_hq2x.h | 2 +- src/gui/render_templates_hq3x.h | 2 +- src/gui/render_templates_sai.h | 2 +- src/gui/sdl_mapper.cpp | 4 ++-- src/gui/sdlmain.cpp | 4 ++-- src/hardware/adlib.cpp | 2 +- src/hardware/cmos.cpp | 2 +- src/hardware/disney.cpp | 2 +- src/hardware/dma.cpp | 2 +- src/hardware/gameblaster.cpp | 2 +- src/hardware/gus.cpp | 2 +- src/hardware/hardware.cpp | 4 ++-- src/hardware/iohandler.cpp | 4 ++-- src/hardware/ipx.cpp | 4 ++-- src/hardware/ipxserver.cpp | 4 ++-- src/hardware/joystick.cpp | 4 ++-- src/hardware/keyboard.cpp | 4 ++-- src/hardware/memory.cpp | 4 ++-- src/hardware/mixer.cpp | 4 ++-- src/hardware/mpu401.cpp | 4 ++-- src/hardware/pcspeaker.cpp | 4 ++-- src/hardware/pic.cpp | 4 ++-- src/hardware/sblaster.cpp | 4 ++-- src/hardware/serialport/directserial_os2.cpp | 4 ++-- src/hardware/serialport/directserial_os2.h | 4 ++-- src/hardware/serialport/directserial_win32.cpp | 4 ++-- src/hardware/serialport/directserial_win32.h | 4 ++-- src/hardware/serialport/serialdummy.cpp | 4 ++-- src/hardware/serialport/serialdummy.h | 4 ++-- src/hardware/serialport/serialport.cpp | 4 ++-- src/hardware/serialport/softmodem.cpp | 4 ++-- src/hardware/serialport/softmodem.h | 4 ++-- src/hardware/tandy_sound.cpp | 2 +- src/hardware/timer.cpp | 4 ++-- src/hardware/vga.cpp | 2 +- src/hardware/vga_attr.cpp | 2 +- src/hardware/vga_crtc.cpp | 2 +- src/hardware/vga_dac.cpp | 2 +- src/hardware/vga_draw.cpp | 2 +- src/hardware/vga_gfx.cpp | 2 +- src/hardware/vga_memory.cpp | 2 +- src/hardware/vga_misc.cpp | 2 +- src/hardware/vga_other.cpp | 4 ++-- src/hardware/vga_s3.cpp | 4 ++-- src/hardware/vga_seq.cpp | 2 +- src/hardware/vga_xga.cpp | 2 +- src/ints/bios.cpp | 4 ++-- src/ints/bios_disk.cpp | 4 ++-- src/ints/bios_keyboard.cpp | 2 +- src/ints/ems.cpp | 4 ++-- src/ints/int10.cpp | 2 +- src/ints/int10.h | 2 +- src/ints/int10_char.cpp | 4 ++-- src/ints/int10_memory.cpp | 2 +- src/ints/int10_misc.cpp | 2 +- src/ints/int10_modes.cpp | 2 +- src/ints/int10_pal.cpp | 2 +- src/ints/int10_put_pixel.cpp | 2 +- src/ints/int10_vesa.cpp | 4 ++-- src/ints/mouse.cpp | 4 ++-- src/ints/xms.cpp | 4 ++-- src/ints/xms.h | 2 +- src/libs/zmbv/drvproc.cpp | 2 +- src/libs/zmbv/zmbv.cpp | 2 +- src/libs/zmbv/zmbv.h | 2 +- src/libs/zmbv/zmbv_vfw.cpp | 2 +- src/misc/messages.cpp | 4 ++-- src/misc/programs.cpp | 4 ++-- src/misc/setup.cpp | 4 ++-- src/misc/support.cpp | 4 ++-- src/shell/shell.cpp | 4 ++-- src/shell/shell_batch.cpp | 4 ++-- src/shell/shell_cmds.cpp | 4 ++-- src/shell/shell_misc.cpp | 4 ++-- 177 files changed, 264 insertions(+), 264 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 7ee06924..2b5d94a1 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -305,7 +305,7 @@ AC_SUBST(ALSA_LIBS) AH_TOP([ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/bios.h b/include/bios.h index e16f7900..0184fc8f 100644 --- a/include/bios.h +++ b/include/bios.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/callback.h b/include/callback.h index 1056e620..bf9f23f3 100644 --- a/include/callback.h +++ b/include/callback.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.h,v 1.18 2006-07-24 19:06:55 c2woody Exp $ */ +/* $Id: callback.h,v 1.19 2007-01-08 19:45:37 qbix79 Exp $ */ #ifndef DOSBOX_CALLBACK_H #define DOSBOX_CALLBACK_H diff --git a/include/cpu.h b/include/cpu.h index ada9d691..525ebfae 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/cross.h b/include/cross.h index 671b4719..5b0ae608 100644 --- a/include/cross.h +++ b/include/cross.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.h,v 1.17 2006-11-07 11:43:12 qbix79 Exp $ */ +/* $Id: cross.h,v 1.18 2007-01-08 19:45:37 qbix79 Exp $ */ #ifndef DOSBOX_CROSS_H #define DOSBOX_CROSS_H diff --git a/include/debug.h b/include/debug.h index ce8a0028..88cc2541 100644 --- a/include/debug.h +++ b/include/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/dma.h b/include/dma.h index 655a7984..74080d6d 100644 --- a/include/dma.h +++ b/include/dma.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dma.h,v 1.16 2006-02-09 11:47:47 qbix79 Exp $ */ +/* $Id: dma.h,v 1.17 2007-01-08 19:45:37 qbix79 Exp $ */ #ifndef DOSBOX_DMA_H #define DOSBOX_DMA_H diff --git a/include/dos_inc.h b/include/dos_inc.h index 7be5fdb9..fcd5a37a 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.62 2006-10-27 13:37:13 c2woody Exp $ */ +/* $Id: dos_inc.h,v 1.63 2007-01-08 19:45:37 qbix79 Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H diff --git a/include/dos_system.h b/include/dos_system.h index 5e48e278..47c9a43e 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.37 2006-11-14 20:01:42 c2woody Exp $ */ +/* $Id: dos_system.h,v 1.38 2007-01-08 19:45:37 qbix79 Exp $ */ #ifndef DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H diff --git a/include/dosbox.h b/include/dosbox.h index 47c6953d..d74eb8ee 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/fpu.h b/include/fpu.h index 448ba5db..50511eaf 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/hardware.h b/include/hardware.h index fcfa4ace..680ae50a 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/inout.h b/include/inout.h index 741bf8c7..db48d783 100644 --- a/include/inout.h +++ b/include/inout.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: inout.h,v 1.9 2006-02-09 11:47:47 qbix79 Exp $ */ +/* $Id: inout.h,v 1.10 2007-01-08 19:45:37 qbix79 Exp $ */ #ifndef DOSBOX_INOUT_H #define DOSBOX_INOUT_H diff --git a/include/ipx.h b/include/ipx.h index f99f0959..962a751a 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.h,v 1.10 2006-10-27 12:00:25 qbix79 Exp $ */ +/* $Id: ipx.h,v 1.11 2007-01-08 19:45:37 qbix79 Exp $ */ #ifndef DOSBOX_IPX_H #define DOSBOX_IPX_H diff --git a/include/ipxserver.h b/include/ipxserver.h index 041e541f..9cb6db97 100644 --- a/include/ipxserver.h +++ b/include/ipxserver.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/joystick.h b/include/joystick.h index 8eda8b03..fdeb421c 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: joystick.h,v 1.8 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: joystick.h,v 1.9 2007-01-08 19:45:37 qbix79 Exp $ */ #ifndef DOSBOX_JOYSTICK_H #define DOSBOX_JOYSTICK_H void JOYSTICK_Enable(Bitu which,bool enabled); diff --git a/include/keyboard.h b/include/keyboard.h index 76878d78..d56affdf 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/mapper.h b/include/mapper.h index 9fdab5c8..c9b51f1f 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/mem.h b/include/mem.h index b91ff93f..a0d0fda1 100644 --- a/include/mem.h +++ b/include/mem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/mixer.h b/include/mixer.h index 60221139..da3fea70 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/mouse.h b/include/mouse.h index 37bbb3dc..f0467fe1 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.h,v 1.12 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: mouse.h,v 1.13 2007-01-08 19:45:37 qbix79 Exp $ */ #ifndef DOSBOX_MOUSE_H #define DOSBOX_MOUSE_H diff --git a/include/paging.h b/include/paging.h index 64751c96..82ad4832 100644 --- a/include/paging.h +++ b/include/paging.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.23 2006-04-11 19:02:33 qbix79 Exp $ */ +/* $Id: paging.h,v 1.24 2007-01-08 19:45:37 qbix79 Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H diff --git a/include/pic.h b/include/pic.h index e74a3f32..47bb2a56 100644 --- a/include/pic.h +++ b/include/pic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/programs.h b/include/programs.h index 17c7a5c5..868a436d 100644 --- a/include/programs.h +++ b/include/programs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/regs.h b/include/regs.h index 02eb2557..636b676c 100644 --- a/include/regs.h +++ b/include/regs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/render.h b/include/render.h index 539e40ea..c3dc8603 100644 --- a/include/render.h +++ b/include/render.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/serialport.h b/include/serialport.h index 75785ccf..53142c64 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.h,v 1.12 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: serialport.h,v 1.13 2007-01-08 19:45:37 qbix79 Exp $ */ #ifndef DOSBOX_SERIALPORT_H #define DOSBOX_SERIALPORT_H diff --git a/include/setup.h b/include/setup.h index 76792a6e..53517198 100644 --- a/include/setup.h +++ b/include/setup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.25 2006-05-25 15:07:32 qbix79 Exp $ */ +/* $Id: setup.h,v 1.26 2007-01-08 19:45:37 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H diff --git a/include/shell.h b/include/shell.h index ca8615cc..b7d0ade7 100644 --- a/include/shell.h +++ b/include/shell.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.18 2006-07-26 11:36:30 qbix79 Exp $ */ +/* $Id: shell.h,v 1.19 2007-01-08 19:45:37 qbix79 Exp $ */ #ifndef DOSBOX_SHELL_H #define DOSBOX_SHELL_H diff --git a/include/support.h b/include/support.h index 73d20813..2b7e66ea 100644 --- a/include/support.h +++ b/include/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/timer.h b/include/timer.h index b6ebab9c..5ba2696d 100644 --- a/include/timer.h +++ b/include/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/vga.h b/include/vga.h index dcf0bd5d..6f60c63b 100644 --- a/include/vga.h +++ b/include/vga.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/include/video.h b/include/video.h index b80e1af3..fab6cfdb 100644 --- a/include/video.h +++ b/include/video.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index b5d84cde..0afe1074 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.35 2006-09-01 17:34:36 c2woody Exp $ */ +/* $Id: callback.cpp,v 1.36 2007-01-08 19:45:38 qbix79 Exp $ */ #include #include diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index d6e41ed1..021528ab 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 272b28e3..35328bd9 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 191e4ab5..afbbe4f2 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index 61384269..f0d29247 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 6e372c34..72f8f489 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index e74b9ee1..672105db 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_normal/helpers.h b/src/cpu/core_normal/helpers.h index 237144b3..f0956f65 100644 --- a/src/cpu/core_normal/helpers.h +++ b/src/cpu/core_normal/helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 1349c2d4..59244371 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 8742716a..a76e43fa 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index b034b783..3022ba58 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index b7b4f174..d0e73555 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index 2d1aeb1d..8a789552 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_normal/table_ea.h b/src/cpu/core_normal/table_ea.h index bfe5ed0a..d09012e6 100644 --- a/src/cpu/core_normal/table_ea.h +++ b/src/cpu/core_normal/table_ea.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp index a7d9c188..c593fed7 100644 --- a/src/cpu/core_simple.cpp +++ b/src/cpu/core_simple.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index f2e6c6b1..357629ed 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.90 2006-12-04 15:49:01 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.91 2007-01-08 19:45:38 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index fe76183b..b6830206 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 27b276be..5f3505b4 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index 227d5f2c..0d936502 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/modrm.cpp b/src/cpu/modrm.cpp index 15e4cd0d..830daf0c 100644 --- a/src/cpu/modrm.cpp +++ b/src/cpu/modrm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/modrm.h b/src/cpu/modrm.h index e98f139d..7fb3059b 100644 --- a/src/cpu/modrm.h +++ b/src/cpu/modrm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index c2d1f934..9a0462c6 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 977f27c3..9b85ed02 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.83 2006-06-27 07:00:56 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.84 2007-01-08 19:45:39 qbix79 Exp $ */ #include "dosbox.h" #if C_DEBUG diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 44473df7..6965055e 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug_gui.cpp,v 1.30 2006-06-16 14:51:31 qbix79 Exp $ */ +/* $Id: debug_gui.cpp,v 1.31 2007-01-08 19:45:39 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h index 43b629a1..870751c8 100644 --- a/src/debug/debug_inc.h +++ b/src/debug/debug_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -18,7 +18,7 @@ /* Local Debug Function */ -/* $Id: debug_inc.h,v 1.10 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: debug_inc.h,v 1.11 2007-01-08 19:45:39 qbix79 Exp $ */ #include #include "mem.h" diff --git a/src/debug/debug_win32.cpp b/src/debug/debug_win32.cpp index c3c48e51..01a229cc 100644 --- a/src/debug/debug_win32.cpp +++ b/src/debug/debug_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/debug/disasm_tables.h b/src/debug/disasm_tables.h index b0d3c4cc..3ce7fb08 100644 --- a/src/debug/disasm_tables.h +++ b/src/debug/disasm_tables.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 8ceade10..ad92feac 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index 830788d6..64c97f40 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_aspi_win32.cpp,v 1.16 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: cdrom_aspi_win32.cpp,v 1.17 2007-01-08 19:45:39 qbix79 Exp $ */ #if defined (WIN32) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index fd65c4fc..6b1e5652 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.12 2006-09-25 08:47:37 qbix79 Exp $ */ +/* $Id: cdrom_image.cpp,v 1.13 2007-01-08 19:45:39 qbix79 Exp $ */ #include #include diff --git a/src/dos/cdrom_ioctl_linux.cpp b/src/dos/cdrom_ioctl_linux.cpp index a05e0ab1..368f9312 100644 --- a/src/dos/cdrom_ioctl_linux.cpp +++ b/src/dos/cdrom_ioctl_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/dos/cdrom_ioctl_os2.cpp b/src/dos/cdrom_ioctl_os2.cpp index bbda0f16..4c0e27eb 100644 --- a/src/dos/cdrom_ioctl_os2.cpp +++ b/src/dos/cdrom_ioctl_os2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_ioctl_os2.cpp,v 1.2 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: cdrom_ioctl_os2.cpp,v 1.3 2007-01-08 19:45:39 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index 8c8f7f2b..7afdc965 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_ioctl_win32.cpp,v 1.13 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: cdrom_ioctl_win32.cpp,v 1.14 2007-01-08 19:45:39 qbix79 Exp $ */ #if defined (WIN32) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index b108c38a..040a054d 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.26 2006-10-13 16:33:24 qbix79 Exp $ */ +/* $Id: dev_con.h,v 1.27 2007-01-08 19:45:39 qbix79 Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 99a92cb4..80f02c29 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.96 2006-10-27 13:37:13 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.97 2007-01-08 19:45:39 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index a629969d..089df86c 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.48 2006-04-21 08:50:30 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.49 2007-01-08 19:45:39 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 06fedc32..933f0cb1 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_devices.cpp,v 1.14 2006-10-27 12:03:22 qbix79 Exp $ */ +/* $Id: dos_devices.cpp,v 1.15 2007-01-08 19:45:39 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index bc8e1c21..d23a45cc 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.57 2006-11-14 14:11:59 c2woody Exp $ */ +/* $Id: dos_execute.cpp,v 1.58 2007-01-08 19:45:39 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index b4d29e1e..45d91f57 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.79 2006-11-14 20:01:42 c2woody Exp $ */ +/* $Id: dos_files.cpp,v 1.80 2007-01-08 19:45:39 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 01e374f0..38ecf1e9 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.28 2006-04-23 14:20:57 c2woody Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.29 2007-01-08 19:45:39 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 22f855cb..9fc70a92 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 6f6956f5..1572d7d2 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index df08976b..36c48122 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_misc.cpp,v 1.16 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: dos_misc.cpp,v 1.17 2007-01-08 19:45:39 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 01aa8fdf..ca749200 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.43 2006-06-22 13:15:07 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.44 2007-01-08 19:45:39 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index c6dd2146..76f9c5af 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.63 2006-10-27 13:37:14 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.64 2007-01-08 19:45:39 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 438edce7..73038bd4 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.23 2006-06-05 18:01:24 qbix79 Exp $ */ +/* $Id: dos_tables.cpp,v 1.24 2007-01-08 19:45:39 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 056731be..c0f22057 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -1,6 +1,6 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.48 2006-08-23 20:09:52 c2woody Exp $ */ +/* $Id: drive_cache.cpp,v 1.49 2007-01-08 19:45:39 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index b1323cda..4b532584 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.19 2006-11-14 20:01:42 c2woody Exp $ */ +/* $Id: drive_fat.cpp,v 1.20 2007-01-08 19:45:39 qbix79 Exp $ */ #include #include diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 8fde0b10..5cc31b84 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.14 2006-06-22 13:15:07 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.15 2007-01-08 19:45:39 qbix79 Exp $ */ #include #include diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 3afab93e..ed7c930a 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.72 2006-11-14 20:01:42 c2woody Exp $ */ +/* $Id: drive_local.cpp,v 1.73 2007-01-08 19:45:39 qbix79 Exp $ */ #include #include diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 2f900b6c..628201d1 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index 8b821627..9720ff33 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/dos/drives.h b/src/dos/drives.h index dbb9962f..052b618c 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.34 2006-11-05 17:30:54 c2woody Exp $ */ +/* $Id: drives.h,v 1.35 2007-01-08 19:45:39 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 25ea6d1b..982b3c8e 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.104 2006-11-14 14:11:59 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.105 2007-01-08 19:45:38 qbix79 Exp $ */ #include #include diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index ef57cf88..7e39e1f3 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu.cpp,v 1.28 2006-06-01 08:33:52 c2woody Exp $ */ +/* $Id: fpu.cpp,v 1.29 2007-01-08 19:45:39 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 26ed9e9f..e0971d31 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.30 2006-10-11 08:01:11 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.31 2007-01-08 19:45:39 qbix79 Exp $ */ static void FPU_FINIT(void) { diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index 8acb2f08..f83586ca 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions_x86.h,v 1.4 2006-06-01 08:33:52 c2woody Exp $ */ +/* $Id: fpu_instructions_x86.h,v 1.5 2007-01-08 19:45:39 qbix79 Exp $ */ #define WEAK_EXCEPTIONS diff --git a/src/gui/dosbox_logo.h b/src/gui/dosbox_logo.h index c0502ba5..93f5b9d3 100644 --- a/src/gui/dosbox_logo.h +++ b/src/gui/dosbox_logo.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox_logo.h,v 1.3 2006-03-29 12:26:41 qbix79 Exp $ */ +/* $Id: dosbox_logo.h,v 1.4 2007-01-08 19:45:39 qbix79 Exp $ */ /* DOSBox icon designed by Ido Beeri */ diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index a6ca7961..08613663 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 8213ff37..0219ad87 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_alsa.h,v 1.14 2006-05-19 19:53:22 qbix79 Exp $ */ +/* $Id: midi_alsa.h,v 1.15 2007-01-08 19:45:39 qbix79 Exp $ */ #define ALSA_PCM_OLD_HW_PARAMS_API #define ALSA_PCM_OLD_SW_PARAMS_API diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index 1af883b4..8fc00575 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index d2a33f6d..c4a945ae 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index 39953f2a..707d4b6b 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_win32.h,v 1.12 2006-02-09 11:47:48 qbix79 Exp $ */ +/* $Id: midi_win32.h,v 1.13 2007-01-08 19:45:39 qbix79 Exp $ */ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN diff --git a/src/gui/render.cpp b/src/gui/render.cpp index a1e476e5..e25c9087 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.48 2006-11-14 14:12:00 c2woody Exp $ */ +/* $Id: render.cpp,v 1.49 2007-01-08 19:45:39 qbix79 Exp $ */ #include #include diff --git a/src/gui/render_loops.h b/src/gui/render_loops.h index 40fb97bf..bc6799cc 100644 --- a/src/gui/render_loops.h +++ b/src/gui/render_loops.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index a4bc776c..baeb3d59 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index 81fc0ddc..9f1b1636 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/gui/render_simple.h b/src/gui/render_simple.h index bbdce56b..c1c9cfb4 100644 --- a/src/gui/render_simple.h +++ b/src/gui/render_simple.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index a5ef8abe..f697ef77 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/gui/render_templates_hq.h b/src/gui/render_templates_hq.h index 9d884030..fd9e14bb 100644 --- a/src/gui/render_templates_hq.h +++ b/src/gui/render_templates_hq.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/gui/render_templates_hq2x.h b/src/gui/render_templates_hq2x.h index d4deb6fe..c74d790a 100644 --- a/src/gui/render_templates_hq2x.h +++ b/src/gui/render_templates_hq2x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/gui/render_templates_hq3x.h b/src/gui/render_templates_hq3x.h index 9baa4e7d..c4c2a59d 100644 --- a/src/gui/render_templates_hq3x.h +++ b/src/gui/render_templates_hq3x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/gui/render_templates_sai.h b/src/gui/render_templates_sai.h index 8f938571..4088a637 100644 --- a/src/gui/render_templates_sai.h +++ b/src/gui/render_templates_sai.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 9c3bc3da..a393fb0c 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.27 2006-07-22 18:32:29 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.28 2007-01-08 19:45:40 qbix79 Exp $ */ #define OLD_JOYSTICK 1 diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index bb6480d0..1790f37b 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.124 2006-11-14 14:12:00 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.125 2007-01-08 19:45:40 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 9cdba658..113039b4 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 0596ec2a..706427fc 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 9aea748e..896faa5b 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 02a23378..681082e6 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index e4169f4d..bd13f447 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 6395325b..3e3d9a72 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 13f4e06e..01f187de 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: hardware.cpp,v 1.17 2006-04-12 18:52:50 qbix79 Exp $ */ +/* $Id: hardware.cpp,v 1.18 2007-01-08 19:45:40 qbix79 Exp $ */ #include #include diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index a36672cc..b6778cf8 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: iohandler.cpp,v 1.22 2006-05-01 19:34:41 c2woody Exp $ */ +/* $Id: iohandler.cpp,v 1.23 2007-01-08 19:45:40 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index 90930a12..21fa18cf 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.cpp,v 1.11 2006-10-27 12:00:29 qbix79 Exp $ */ +/* $Id: ipx.cpp,v 1.12 2007-01-08 19:45:40 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/ipxserver.cpp b/src/hardware/ipxserver.cpp index 5bd4d160..b4045224 100644 --- a/src/hardware/ipxserver.cpp +++ b/src/hardware/ipxserver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipxserver.cpp,v 1.8 2006-10-27 12:00:29 qbix79 Exp $ */ +/* $Id: ipxserver.cpp,v 1.9 2007-01-08 19:45:40 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index fdaff0b1..4fece5ed 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: joystick.cpp,v 1.14 2006-02-09 11:47:49 qbix79 Exp $ */ +/* $Id: joystick.cpp,v 1.15 2007-01-08 19:45:40 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index acbc3fd6..47c711d2 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.35 2006-02-09 11:47:49 qbix79 Exp $ */ +/* $Id: keyboard.cpp,v 1.36 2007-01-08 19:45:40 qbix79 Exp $ */ #include "dosbox.h" #include "keyboard.h" diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index f4168e8a..a742bef1 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: memory.cpp,v 1.45 2006-08-30 12:19:04 qbix79 Exp $ */ +/* $Id: memory.cpp,v 1.46 2007-01-08 19:45:40 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 0badfbab..eee53355 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.43 2006-11-07 11:43:13 qbix79 Exp $ */ +/* $Id: mixer.cpp,v 1.44 2007-01-08 19:45:40 qbix79 Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 44b4fa67..756ad1b5 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.22 2006-10-23 18:57:43 qbix79 Exp $ */ +/* $Id: mpu401.cpp,v 1.23 2007-01-08 19:45:40 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index b90b0764..2369d46c 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /* $Id: pcspeaker.cpp,v 1.22 2006-02-09 11:47:49 qbix79 Exp $ */ + /* $Id: pcspeaker.cpp,v 1.23 2007-01-08 19:45:40 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 90e35073..08246300 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.36 2006-10-27 12:00:29 qbix79 Exp $ */ +/* $Id: pic.cpp,v 1.37 2007-01-08 19:45:40 qbix79 Exp $ */ #include diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 03d28771..83b3c24c 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.59 2006-11-21 15:12:39 qbix79 Exp $ */ +/* $Id: sblaster.cpp,v 1.60 2007-01-08 19:45:40 qbix79 Exp $ */ #include #include diff --git a/src/hardware/serialport/directserial_os2.cpp b/src/hardware/serialport/directserial_os2.cpp index d2c1ef73..d48eee51 100644 --- a/src/hardware/serialport/directserial_os2.cpp +++ b/src/hardware/serialport/directserial_os2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_os2.cpp,v 1.2 2006-02-09 11:47:54 qbix79 Exp $ */ +/* $Id: directserial_os2.cpp,v 1.3 2007-01-08 19:45:40 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/directserial_os2.h b/src/hardware/serialport/directserial_os2.h index a1488670..53385938 100644 --- a/src/hardware/serialport/directserial_os2.h +++ b/src/hardware/serialport/directserial_os2.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_os2.h,v 1.2 2006-02-09 11:47:54 qbix79 Exp $ */ +/* $Id: directserial_os2.h,v 1.3 2007-01-08 19:45:40 qbix79 Exp $ */ // include guard #ifndef DOSBOX_DIRECTSERIAL_OS2_H diff --git a/src/hardware/serialport/directserial_win32.cpp b/src/hardware/serialport/directserial_win32.cpp index 4b13fa4f..ee546370 100644 --- a/src/hardware/serialport/directserial_win32.cpp +++ b/src/hardware/serialport/directserial_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_win32.cpp,v 1.3 2006-02-09 11:47:54 qbix79 Exp $ */ +/* $Id: directserial_win32.cpp,v 1.4 2007-01-08 19:45:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/directserial_win32.h b/src/hardware/serialport/directserial_win32.h index 63adb893..e78beaea 100644 --- a/src/hardware/serialport/directserial_win32.h +++ b/src/hardware/serialport/directserial_win32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_win32.h,v 1.2 2006-02-09 11:47:54 qbix79 Exp $ */ +/* $Id: directserial_win32.h,v 1.3 2007-01-08 19:45:41 qbix79 Exp $ */ // include guard #ifndef DOSBOX_DIRECTSERIAL_WIN32_H diff --git a/src/hardware/serialport/serialdummy.cpp b/src/hardware/serialport/serialdummy.cpp index 749e9e67..64065974 100644 --- a/src/hardware/serialport/serialdummy.cpp +++ b/src/hardware/serialport/serialdummy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialdummy.cpp,v 1.2 2006-02-09 11:47:54 qbix79 Exp $ */ +/* $Id: serialdummy.cpp,v 1.3 2007-01-08 19:45:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/serialdummy.h b/src/hardware/serialport/serialdummy.h index dbff5e70..e339d1b9 100644 --- a/src/hardware/serialport/serialdummy.h +++ b/src/hardware/serialport/serialdummy.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialdummy.h,v 1.2 2006-02-09 11:47:55 qbix79 Exp $ */ +/* $Id: serialdummy.h,v 1.3 2007-01-08 19:45:41 qbix79 Exp $ */ #ifndef INCLUDEGUARD_SERIALDUMMY_H #define INCLUDEGUARD_SERIALDUMMY_H diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index 2f2ce439..87bb7f3d 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.cpp,v 1.4 2006-02-09 11:47:55 qbix79 Exp $ */ +/* $Id: serialport.cpp,v 1.5 2007-01-08 19:45:41 qbix79 Exp $ */ #include #include diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index 423ce994..541ed436 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.cpp,v 1.5 2006-03-24 17:11:35 qbix79 Exp $ */ +/* $Id: softmodem.cpp,v 1.6 2007-01-08 19:45:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index 259f27ce..7cbf65b4 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.h,v 1.5 2006-02-26 13:48:06 qbix79 Exp $ */ +/* $Id: softmodem.h,v 1.6 2007-01-08 19:45:41 qbix79 Exp $ */ #ifndef DOSBOX_SERIALMODEM_H #define DOSBOX_SERIALMODEM_H diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 84f34df3..ab48087d 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 96cbbcc1..dd1cbf97 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.40 2006-08-03 19:36:12 c2woody Exp $ */ +/* $Id: timer.cpp,v 1.41 2007-01-08 19:45:40 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 696a5be9..ec47222d 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 1f2f1f9c..0ca6b54f 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index cf47441c..3d8fb2ae 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index b6648e39..8075343d 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 1aac3051..b23e4761 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index 7a8190b0..e6d378a3 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 37ac179b..03e0fc5c 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 141bfba4..6afaf91c 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index b200d557..8edb0ee4 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_other.cpp,v 1.18 2006-02-12 23:55:53 harekiet Exp $ */ +/* $Id: vga_other.cpp,v 1.19 2007-01-08 19:45:40 qbix79 Exp $ */ #include #include diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index fb92b984..7bdc3c09 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_s3.cpp,v 1.5 2006-09-09 16:06:31 qbix79 Exp $ */ +/* $Id: vga_s3.cpp,v 1.6 2007-01-08 19:45:40 qbix79 Exp $ */ #include "dosbox.h" #include "inout.h" diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 406baba7..63de93da 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index c998eae7..4a448c95 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 258122c2..ce2cb729 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.63 2006-08-18 18:23:02 c2woody Exp $ */ +/* $Id: bios.cpp,v 1.64 2007-01-08 19:45:41 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 3c2f2695..c5aa2fbf 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.29 2006-04-22 15:25:45 c2woody Exp $ */ +/* $Id: bios_disk.cpp,v 1.30 2007-01-08 19:45:41 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 58350f70..46d70585 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 5f9d09d2..a5599d6d 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.53 2006-08-04 17:30:46 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.54 2007-01-08 19:45:41 qbix79 Exp $ */ #include #include diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 2f2c9bbc..0b860dbf 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/ints/int10.h b/src/ints/int10.h index 2438ea2f..7c9671d3 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 9e8b04cb..4d21f028 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.48 2006-06-27 07:32:42 harekiet Exp $ */ +/* $Id: int10_char.cpp,v 1.49 2007-01-08 19:45:41 qbix79 Exp $ */ /* Character displaying moving functions */ diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 3a7c8fbf..7e8d74e1 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 9bce3d6d..0c56c2d6 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 5e865beb..8f4db1b7 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 5becfce6..9544f86f 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 3f80d441..c76adf4c 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 43792237..417a01b8 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.24 2006-04-22 15:25:45 c2woody Exp $ */ +/* $Id: int10_vesa.cpp,v 1.25 2007-01-08 19:45:41 qbix79 Exp $ */ #include #include diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 0f8fe0e6..4c0aa588 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.65 2006-10-27 12:07:41 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.66 2007-01-08 19:45:41 qbix79 Exp $ */ #include #include diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 1dd25635..ca81a67d 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.43 2006-07-24 19:06:55 c2woody Exp $ */ +/* $Id: xms.cpp,v 1.44 2007-01-08 19:45:41 qbix79 Exp $ */ #include #include diff --git a/src/ints/xms.h b/src/ints/xms.h index 59449115..863d27c8 100644 --- a/src/ints/xms.h +++ b/src/ints/xms.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/libs/zmbv/drvproc.cpp b/src/libs/zmbv/drvproc.cpp index 53e7c8c2..27611cb9 100644 --- a/src/libs/zmbv/drvproc.cpp +++ b/src/libs/zmbv/drvproc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/libs/zmbv/zmbv.cpp b/src/libs/zmbv/zmbv.cpp index 06812514..2eb0fcb3 100644 --- a/src/libs/zmbv/zmbv.cpp +++ b/src/libs/zmbv/zmbv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/libs/zmbv/zmbv.h b/src/libs/zmbv/zmbv.h index eae58d93..db619405 100644 --- a/src/libs/zmbv/zmbv.h +++ b/src/libs/zmbv/zmbv.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/libs/zmbv/zmbv_vfw.cpp b/src/libs/zmbv/zmbv_vfw.cpp index 9b8927b2..a20c8444 100644 --- a/src/libs/zmbv/zmbv_vfw.cpp +++ b/src/libs/zmbv/zmbv_vfw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 0cae1e0d..4d15dc47 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: messages.cpp,v 1.18 2006-02-09 11:47:57 qbix79 Exp $ */ +/* $Id: messages.cpp,v 1.19 2007-01-08 19:45:41 qbix79 Exp $ */ #include #include diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 76f05c96..fb751413 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.26 2006-04-11 19:02:33 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.27 2007-01-08 19:45:41 qbix79 Exp $ */ #include #include diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index b2850377..9dbc928c 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.37 2006-10-08 19:26:04 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.38 2007-01-08 19:45:41 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 0b8bd8dc..7d7473f7 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.30 2006-04-11 19:02:33 qbix79 Exp $ */ +/* $Id: support.cpp,v 1.31 2007-01-08 19:45:41 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 146bd425..d0bedbfe 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.77 2006-07-26 11:36:30 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.78 2007-01-08 19:45:42 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index e9ac29f2..78edfe4e 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.22 2006-06-30 20:04:21 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.23 2007-01-08 19:45:42 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 6d02e414..e0787563 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.69 2006-07-26 11:36:30 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.70 2007-01-08 19:45:42 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 1241cbbd..ebd986f0 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.46 2006-11-08 20:20:09 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.47 2007-01-08 19:45:42 qbix79 Exp $ */ #include #include From d78d597f92312c3d30f1891a316792396e93bbd7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 8 Jan 2007 19:59:06 +0000 Subject: [PATCH 2644/4131] Add Beta2 patch: Fix autoexec overflow. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2729 --- include/shell.h | 10 +++---- src/hardware/gus.cpp | 24 ++++++++++------ src/hardware/sblaster.cpp | 22 +++++++++------ src/shell/shell.cpp | 58 ++++++++++++++++++--------------------- 4 files changed, 62 insertions(+), 52 deletions(-) diff --git a/include/shell.h b/include/shell.h index b7d0ade7..e264cb00 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.19 2007-01-08 19:45:37 qbix79 Exp $ */ +/* $Id: shell.h,v 1.20 2007-01-08 19:59:06 qbix79 Exp $ */ #ifndef DOSBOX_SHELL_H #define DOSBOX_SHELL_H @@ -154,11 +154,11 @@ static inline char* ExpandDot(char*args, char* buffer) { class AutoexecObject{ private: bool installed; - char buf[256]; + std::string buf; public: - AutoexecObject():installed(false){}; - void Install(char * line,...); - void InstallBefore(char* line, ...); + AutoexecObject():installed(false){ }; + void Install(std::string const &in); + void InstallBefore(std::string const &in); ~AutoexecObject(); private: void CreateAutoexec(void); diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 3e3d9a72..e29d4975 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -17,6 +17,8 @@ */ #include +#include +#include #include "dosbox.h" #include "inout.h" #include "mixer.h" @@ -26,6 +28,7 @@ #include "shell.h" #include "math.h" #include "regs.h" +using namespace std; //Extra bits of precision over normal gus #define WAVE_BITS 2 @@ -82,12 +85,12 @@ struct GFGus { float delay; } timers[2]; Bit32u rate; - Bit16u portbase; - Bit8u dma1; - Bit8u dma2; + Bitu portbase; + Bitu dma1; + Bitu dma2; - Bit16u irq1; - Bit16u irq2; + Bitu irq1; + Bitu irq2; char ultradir[512]; bool irqenabled; @@ -861,10 +864,15 @@ public: myGUS.gRegData=0x0; int portat = 0x200+GUS_BASE; // ULTRASND=Port,DMA1,DMA2,IRQ1,IRQ2 - autoexecline[0].Install("SET ULTRASND=%3X,%d,%d,%d,%d",portat,myGUS.dma1,myGUS.dma2,myGUS.irq1,myGUS.irq2); - autoexecline[1].Install("SET ULTRADIR=%s", myGUS.ultradir); + // Create autoexec.bat lines + ostringstream temp; + temp << "SET ULTRASND=" << hex << setw(3) << portat << "," + << dec << myGUS.dma1 << "," << myGUS.dma2 << "," + << myGUS.irq1 << "," << myGUS.irq2 << ends; + autoexecline[0].Install(temp.str()); + autoexecline[1].Install(std::string("SET ULTRADIR=")+ myGUS.ultradir); } - + ~GUS() { if(machine!=MCH_VGA) return; diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 83b3c24c..be63f8ba 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,8 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.60 2007-01-08 19:45:40 qbix79 Exp $ */ +/* $Id: sblaster.cpp,v 1.61 2007-01-08 19:59:06 qbix79 Exp $ */ +#include +#include #include #include #include "dosbox.h" @@ -29,6 +31,7 @@ #include "setup.h" #include "support.h" #include "shell.h" +using namespace std; void MIDI_RawOutByte(Bit8u data); bool MIDI_Available(void); @@ -141,8 +144,8 @@ struct SB_INFO { } adpcm; struct { Bitu base; - Bit8u irq; - Bit8u dma8,dma16; + Bitu irq; + Bitu dma8,dma16; } hw; struct { Bits value; @@ -1314,11 +1317,14 @@ public: if (sb.type == SBT_16) sb.chan->Enable(true); else sb.chan->Enable(false); - char hdma[8]=""; - if (sb.type==SBT_16) { - sprintf(hdma,"H%d ",sb.hw.dma16); - } - autoexecline.Install("SET BLASTER=A%3X I%d D%d %sT%d",sb.hw.base,sb.hw.irq,sb.hw.dma8,hdma,sb.type); + // Create set blaster line + ostringstream temp; + temp << "SET BLASTER=A" << setw(3)<< hex << sb.hw.base + << " I" << dec << sb.hw.irq << " D"<< sb.hw.dma8; + if (sb.type==SBT_16) temp << " H" << sb.hw.dma16; + temp << " T" << static_cast(sb.type) << ends; + + autoexecline.Install(temp.str()); /* Soundblaster midi interface */ if (!MIDI_Available()) sb.midi = false; diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index d0bedbfe..865d5871 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.78 2007-01-08 19:45:42 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.79 2007-01-08 19:59:06 qbix79 Exp $ */ #include #include @@ -48,16 +48,11 @@ typedef std::list::iterator auto_it; void VFILE_Remove(const char *name); -void AutoexecObject::Install(char* line,...) { - if(GCC_UNLIKELY(installed)) E_Exit("autoexec: allready created %s",buf); +void AutoexecObject::Install(const std::string &in) { + if(GCC_UNLIKELY(installed)) E_Exit("autoexec: allready created %s",buf.c_str()); installed = true; - va_list msg; - - va_start(msg,line); - vsprintf(buf,line,msg); - va_end(msg); - autoexec_strings.push_back(std::string(buf)); - + buf = in; + autoexec_strings.push_back(buf); this->CreateAutoexec(); //autoexec.bat is normally created AUTOEXEC_Init. @@ -65,7 +60,10 @@ void AutoexecObject::Install(char* line,...) { //we have to update the envirionment to display changes if(first_shell) { - char buf2[256]; strcpy(buf2,buf);//used in shell.h + //create a copy as the string will be modified + std::string::size_type n = buf.size(); + char* buf2 = new char[n + 1]; + safe_strncpy(buf2, buf.c_str(), n + 1); if((strncasecmp(buf2,"set ",4) == 0) && (strlen(buf2) > 4)){ char* after_set = buf2 + 4;//move to variable that is being set char* test = strpbrk(after_set,"="); @@ -74,18 +72,15 @@ void AutoexecObject::Install(char* line,...) { //If the shell is running/exists update the environment first_shell->SetEnv(after_set,test); } + delete [] buf2; } } -void AutoexecObject::InstallBefore(char* line,...) { - if(GCC_UNLIKELY(installed)) E_Exit("autoexec: allready created %s",buf); +void AutoexecObject::InstallBefore(const std::string &in) { + if(GCC_UNLIKELY(installed)) E_Exit("autoexec: allready created %s",buf.c_str()); installed = true; - va_list msg; - - va_start(msg,line); - vsprintf(buf,line,msg); - va_end(msg); - autoexec_strings.push_front(std::string(buf)); + buf = in; + autoexec_strings.push_front(buf); this->CreateAutoexec(); } @@ -98,7 +93,7 @@ void AutoexecObject::CreateAutoexec(void) { size_t auto_len; for(auto_it it= autoexec_strings.begin(); it != autoexec_strings.end(); it++) { auto_len = strlen(autoexec_data); - if ((auto_len+strlen((*it).c_str())+3)>AUTOEXEC_SIZE) { + if ((auto_len+(*it).length()+3)>AUTOEXEC_SIZE) { E_Exit("SYSTEM:Autoexec.bat file overflow"); } sprintf((autoexec_data+auto_len),"%s\r\n",(*it).c_str()); @@ -113,15 +108,19 @@ AutoexecObject::~AutoexecObject(){ for(auto_it it = autoexec_strings.begin(); it != autoexec_strings.end(); ) { if((*it) == buf) { it = autoexec_strings.erase(it); + std::string::size_type n = buf.size(); + char* buf2 = new char[n + 1]; + safe_strncpy(buf2, buf.c_str(), n + 1); // If it's a environment variable remove it from there as well - if((strncasecmp(buf,"set ",4) == 0) && (strlen(buf) > 4)){ - char* after_set = buf + 4;//move to variable that is being set + if((strncasecmp(buf2,"set ",4) == 0) && (strlen(buf2) > 4)){ + char* after_set = buf2 + 4;//move to variable that is being set char* test = strpbrk(after_set,"="); if(!test) continue; *test = 0; //If the shell is running/exists update the environment if(first_shell) first_shell->SetEnv(after_set,""); } + delete [] buf2; } else it++; } this->CreateAutoexec(); @@ -350,14 +349,14 @@ public: if(echo_off) autoexec_echo.InstallBefore("@echo off"); /* Install the stuff from the configfile */ - autoexec[0].Install("%s",extra); + autoexec[0].Install(section->data); } /* Check to see for extra command line options to be added (before the command specified on commandline) */ /* Maximum of extra commands: 10 */ Bitu i = 1; while (control->cmdline->FindString("-c",line,true) && (i <= 11)) - autoexec[i++].Install((char *)line.c_str()); + autoexec[i++].Install(line); /* Check for the -exit switch which causes dosbox to when the command on the commandline has finished */ bool addexit = control->cmdline->FindExist("-exit",true); @@ -375,7 +374,7 @@ public: if (stat(buffer,&test)) goto nomount; } if (test.st_mode & S_IFDIR) { - autoexec[12].Install("MOUNT C \"%s\"",buffer); + autoexec[12].Install(std::string("MOUNT C \"") + buffer + "\""); autoexec[13].Install("C:"); } else { char* name = strrchr(buffer,CROSS_FILESPLIT); @@ -390,17 +389,14 @@ public: } *name++ = 0; if (access(buffer,F_OK)) goto nomount; - autoexec[12].Install("MOUNT C \"%s\"",buffer); + autoexec[12].Install(std::string("MOUNT C \"") + buffer + "\""); autoexec[13].Install("C:"); upcase(name); if(strstr(name,".BAT") == 0) { autoexec[14].Install(name); } else { - /* BATch files are called else exit will not work */ - char call[CROSS_LEN] = { 0 }; - strcpy(call,"CALL "); - strcat(call,name); - autoexec[14].Install(call); + /* BATch files are called else exit will not work */ + autoexec[14].Install(std::string("CALL ") + name); } if(addexit) autoexec[15].Install("exit"); } From 24b3c2a1b897115d90ecba7b45ed402919139c3b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 8 Jan 2007 20:10:34 +0000 Subject: [PATCH 2645/4131] Add beta2 patch: Move dos tables to c800 to make easier umb management. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2730 --- include/dos_inc.h | 4 ++-- src/dos/dos_memory.cpp | 30 +++++------------------------- src/dos/dos_tables.cpp | 6 +++--- src/dosbox.cpp | 6 +++--- src/ints/xms.cpp | 6 +++--- 5 files changed, 16 insertions(+), 36 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index fcd5a37a..8226a295 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.63 2007-01-08 19:45:37 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.64 2007-01-08 20:10:34 qbix79 Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -158,7 +158,7 @@ void DOS_FreeProcessMemory(Bit16u pspseg); Bit16u DOS_GetMemory(Bit16u pages); bool DOS_SetMemAllocStrategy(Bit16u strat); Bit16u DOS_GetMemAllocStrategy(void); -void DOS_BuildUMBChain(const char* use_umbs,bool ems_active); +void DOS_BuildUMBChain(bool umb_active,bool ems_active); bool DOS_LinkUMBsToMemChain(Bit16u linkstate); /* FCB stuff */ diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 1572d7d2..0fa042f7 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -303,10 +303,11 @@ bool DOS_FreeMemory(Bit16u segment) { } -void DOS_BuildUMBChain(const char* use_umbs,bool ems_active) { - if ((strcmp(use_umbs,"false")!=0) && (machine!=MCH_TANDY)) { - Bit16u first_umb_seg=0xc800; - Bit16u first_umb_size=0x1000; +void DOS_BuildUMBChain(bool umb_active,bool ems_active) { + if (umb_active && (machine!=MCH_TANDY)) { + Bit16u first_umb_seg = 0xd000; + Bit16u first_umb_size = 0x2000; + if(ems_active || (machine == MCH_PCJR)) first_umb_size = 0x1000; dos_infoblock.SetStartOfUMBChain(UMB_START_SEG); dos_infoblock.SetUMBChainState(0); // UMBs not linked yet @@ -333,27 +334,6 @@ void DOS_BuildUMBChain(const char* use_umbs,bool ems_active) { mcb.SetSize(first_umb_seg-cover_mcb-1); mcb.SetFileName("SC "); - if (!ems_active && (strcmp(use_umbs,"max")==0) && (machine!=MCH_PCJR)) { - Bit16u ems_umb_seg=0xe000; - Bit16u ems_umb_size=0x1000; - - /* Continue UMB-chain */ - umb_mcb.SetSize(first_umb_size-2); - umb_mcb.SetType(0x4d); - - DOS_MCB umb2_mcb(ems_umb_seg); - umb2_mcb.SetPSPSeg(0); // currently free - umb2_mcb.SetSize(ems_umb_size-1); - umb2_mcb.SetType(0x5a); - - /* A system MCB has to take out the space between the previous and this UMB */ - cover_mcb=(Bit16u)(first_umb_seg+umb_mcb.GetSize()+1); - mcb.SetPt(cover_mcb); - mcb.SetType(0x4d); - mcb.SetPSPSeg(0x0008); - mcb.SetSize(ems_umb_seg-cover_mcb-1); - mcb.SetFileName("SC "); - } } else { dos_infoblock.SetStartOfUMBChain(0xffff); dos_infoblock.SetUMBChainState(0); diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 73038bd4..f886421e 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.24 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: dos_tables.cpp,v 1.25 2007-01-08 20:10:34 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -43,7 +43,7 @@ static Bitu call_casemap; static Bit16u dos_memseg; Bit16u DOS_GetMemory(Bit16u pages) { - if (pages+dos_memseg>=0xe000) { + if (pages+dos_memseg>=0xd000) { E_Exit("DOS:Not enough memory for internal tables"); } Bit16u page=dos_memseg; @@ -73,7 +73,7 @@ static Bit8u country_info[0x22] = { }; void DOS_SetupTables(void) { - dos_memseg=0xd800; + dos_memseg=0xc800; Bit16u seg,seg2;Bitu i; dos.tables.mediaid=RealMake(DOS_GetMemory(4),0); dos.tables.tempdta=RealMake(DOS_GetMemory(4),0); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 982b3c8e..62b1cadc 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.105 2007-01-08 19:45:38 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.106 2007-01-08 20:10:34 qbix79 Exp $ */ #include #include @@ -437,13 +437,13 @@ void DOSBOX_Init(void) { secprop->Add_bool("xms",true); secprop->AddInitFunction(&EMS_Init,true);//done secprop->Add_bool("ems",true); - secprop->Add_string("umb","true"); + secprop->Add_bool("umb","true"); secprop->AddInitFunction(&DOS_KeyboardLayout_Init,true); secprop->Add_string("keyboardlayout", "none"); MSG_Add("DOS_CONFIGFILE_HELP", "xms -- Enable XMS support.\n" "ems -- Enable EMS support.\n" - "umb -- Enable UMB support (false,true,max).\n" + "umb -- Enable UMB support.\n" "keyboardlayout -- Language code of the keyboard layout (or none).\n" ); // Mscdex diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index ca81a67d..71927a01 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.44 2007-01-08 19:45:41 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.45 2007-01-08 20:10:34 qbix79 Exp $ */ #include #include @@ -436,8 +436,8 @@ public: xms_handles[0].free = false; /* Set up UMB chain */ - umb_available=strcmp(section->Get_string("umb"),"false")!=0; - DOS_BuildUMBChain(section->Get_string("umb"),section->Get_bool("ems")); + umb_available=section->Get_bool("umb"); + DOS_BuildUMBChain(section->Get_bool("umb"),section->Get_bool("ems")); } ~XMS(){ From ca8b788e12e678d45fbc4b481a0394639674417c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 8 Jan 2007 20:36:53 +0000 Subject: [PATCH 2646/4131] Add Beta2 patch:Fix nc5 installer. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2731 --- include/dos_inc.h | 6 ++++-- src/dos/dos.cpp | 22 ++++++++++++++++------ src/dos/dos_tables.cpp | 35 ++++++++++++++++++++++++++++++++--- 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 8226a295..04c91b72 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.64 2007-01-08 20:10:34 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.65 2007-01-08 20:36:53 qbix79 Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -616,7 +616,9 @@ struct DOS_Block { RealPt mediaid; RealPt tempdta; RealPt tempdta_fcbdelete; - RealPt dcbs; + RealPt dbcs; + RealPt filenamechar; + RealPt collatingseq; Bit8u* country;//Will be copied to dos memory. resides in real mem } tables; Bit16u loaded_codepage; diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 80f02c29..46fdb74d 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.97 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.98 2007-01-08 20:36:53 qbix79 Exp $ */ #include #include @@ -838,8 +838,8 @@ static Bitu DOS_21Handler(void) { break; case 0x63: /* DOUBLE BYTE CHARACTER SET */ if(reg_al == 0) { - SegSet16(ds,RealSeg(dos.tables.dcbs)); - reg_si=RealOff(dos.tables.dcbs); + SegSet16(ds,RealSeg(dos.tables.dbcs)); + reg_si=RealOff(dos.tables.dbcs); reg_al = 0; CALLBACK_SCF(false); //undocumented } else reg_al = 0xff; //Doesn't officially touch carry flag @@ -870,14 +870,24 @@ static Bitu DOS_21Handler(void) { } CALLBACK_SCF(false); break; + case 0x05: // Get pointer to filename terminator table + mem_writeb(data + 0x00, reg_al); + mem_writed(data + 0x01, dos.tables.filenamechar); + reg_cx = 5; + CALLBACK_SCF(false); + break; + case 0x06: // Get pointer to collating sequence table + mem_writeb(data + 0x00, reg_al); + mem_writed(data + 0x01, dos.tables.collatingseq); + reg_cx = 5; + CALLBACK_SCF(false); + break; case 0x02: // Get pointer to uppercase table case 0x03: // Get pointer to lowercase table case 0x04: // Get pointer to filename uppercase table - case 0x05: // Get pointer to filename terminator table - case 0x06: // Get pointer to collating sequence table case 0x07: // Get pointer to double byte char set table mem_writeb(data + 0x00, reg_al); - mem_writed(data + 0x01, dos.tables.dcbs); //used to be 0 + mem_writed(data + 0x01, dos.tables.dbcs); //used to be 0 reg_cx = 5; CALLBACK_SCF(false); break; diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index f886421e..5962f524 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.25 2007-01-08 20:10:34 qbix79 Exp $ */ +/* $Id: dos_tables.cpp,v 1.26 2007-01-08 20:36:53 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -108,8 +108,37 @@ void DOS_SetupTables(void) { /* Allocate DCBS DOUBLE BYTE CHARACTER SET LEAD-BYTE TABLE */ - dos.tables.dcbs=RealMake(DOS_GetMemory(12),0); - mem_writed(Real2Phys(dos.tables.dcbs),0); //empty table + dos.tables.dbcs=RealMake(DOS_GetMemory(12),0); + mem_writed(Real2Phys(dos.tables.dbcs),0); //empty table + /* FILENAME CHARACTER TABLE */ + dos.tables.filenamechar=RealMake(DOS_GetMemory(2),0); + mem_writew(Real2Phys(dos.tables.filenamechar)+0x00,0x16); + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x02,0x01); + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x03,0x00); // allowed chars from + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x04,0xff); // ...to + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x05,0x00); + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x06,0x00); // excluded chars from + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x07,0x20); // ...to + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x08,0x02); + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x09,0x0e); // number of illegal separators + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x0a,0x2e); + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x0b,0x22); + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x0c,0x2f); + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x0d,0x5c); + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x0e,0x5b); + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x0f,0x5d); + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x10,0x3a); + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x11,0x7c); + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x12,0x3c); + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x13,0x3e); + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x14,0x2b); + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x15,0x3d); + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x16,0x3b); + mem_writeb(Real2Phys(dos.tables.filenamechar)+0x17,0x2c); + /* COLLATING SEQUENCE TABLE */ + dos.tables.collatingseq=RealMake(DOS_GetMemory(17),0); + mem_writew(Real2Phys(dos.tables.collatingseq),0x100); + for (i=0; i<256; i++) mem_writeb(Real2Phys(dos.tables.collatingseq)+i+2,i); /* Create a fake FCB SFT */ seg=DOS_GetMemory(4); From c773dded4bcdc601984a0c73e509c1cc45bfd7f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 8 Jan 2007 20:58:47 +0000 Subject: [PATCH 2647/4131] better workaround for clipper programs (doesn't break wc3) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2732 --- src/cpu/core_normal/prefix_none.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index d0e73555..24e6c177 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -433,11 +433,13 @@ if (rm >= 0xc0 ) {GetEArb;*earb=*rmrb;} else { if (cpu.pmode) { - Descriptor desc; - cpu.gdt.GetDescriptor(SegValue(core.base_val_ds),desc); - if ((desc.Type()==DESC_CODE_R_NC_A) || (desc.Type()==DESC_CODE_R_NC_NA)) { - CPU_Exception(EXCEPTION_GP,SegValue(core.base_val_ds) & 0xfffc); - continue; + if (GCC_UNLIKELY((rm==0x05) && (!cpu.code.big))) { + Descriptor desc; + cpu.gdt.GetDescriptor(SegValue(core.base_val_ds),desc); + if ((desc.Type()==DESC_CODE_R_NC_A) || (desc.Type()==DESC_CODE_R_NC_NA)) { + CPU_Exception(EXCEPTION_GP,SegValue(core.base_val_ds) & 0xfffc); + continue; + } } } GetEAa;SaveMb(eaa,*rmrb); From 384f3703eb2ae82f22adaeb372930cc671796935 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 8 Jan 2007 21:07:39 +0000 Subject: [PATCH 2648/4131] Some OS/2 specific fix.(Josch) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2733 --- src/gui/sdl_mapper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index a393fb0c..4be259b3 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.28 2007-01-08 19:45:40 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.29 2007-01-08 21:07:39 qbix79 Exp $ */ #define OLD_JOYSTICK 1 @@ -330,7 +330,7 @@ Bitu GetKeyCode(SDL_keysym keysym) { /* try to retrieve key from symbolic key as scancode is zero */ if (keysym.sym Date: Mon, 8 Jan 2007 21:20:23 +0000 Subject: [PATCH 2649/4131] Add beta2 patch. Add some basic file/path not found error. Fixes some installer. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2734 --- src/dos/dos_files.cpp | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 45d91f57..86d449f8 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.80 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.81 2007-01-08 21:20:23 qbix79 Exp $ */ #include #include @@ -382,6 +382,20 @@ bool DOS_CloseFile(Bit16u entry) { return true; } +static bool PathExists(char* name) { + char* leading = strrchr(name,'\\'); + if(!leading) return true; + char temp[CROSS_LEN]; + strcpy(temp,name); + leading = strrchr(temp,'\\'); + *leading = 0; + Bit8u drive;char fulldir[DOS_PATHLENGTH]; + if (!DOS_MakeName(temp,fulldir,&drive)) return false; + if(!Drives[drive]->TestDir(fulldir)) return false; + return true; +} + + bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { // Creation of a device is the same as opening it // Tc201 installer @@ -417,6 +431,8 @@ bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { psp.SetFileHandle(*entry,handle); return true; } else { + if(!PathExists(name)) DOS_SetError(DOSERR_PATH_NOT_FOUND); + else DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } } @@ -475,8 +491,10 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { //Test if file exists, but opened in read-write mode (and writeprotected) if(((flags&3) != OPEN_READ) && Drives[drive]->FileExists(fullname)) DOS_SetError(DOSERR_ACCESS_DENIED); - else - DOS_SetError(DOSERR_FILE_NOT_FOUND); + else { + if(!PathExists(name)) DOS_SetError(DOSERR_PATH_NOT_FOUND); + else DOS_SetError(DOSERR_FILE_NOT_FOUND); + } return false; } } From 0cca0c96cf27b0062986611ee04d4bb88a609405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 8 Jan 2007 21:29:27 +0000 Subject: [PATCH 2650/4131] enable instant irq checking after STI for the dynamic core Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2735 --- src/cpu/core_dyn_x86/decoder.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 35328bd9..10973317 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -188,6 +188,22 @@ static void dyn_check_bool_exception_al(void) { used_save_info++; } +#include "pic.h" + +static void dyn_check_irqrequest(void) { + gen_load_host(&PIC_IRQCheck,DREG(TMPB),4); + gen_dop_word(DOP_OR,true,DREG(TMPB),DREG(TMPB)); + save_info[used_save_info].branch_pos=gen_create_branch_long(BR_NZ); + gen_releasereg(DREG(TMPB)); + dyn_savestate(&save_info[used_save_info].state); + if (!decode.cycles) decode.cycles++; + save_info[used_save_info].cycles=decode.cycles; + save_info[used_save_info].eip_change=decode.code-decode.code_start; + if (!cpu.code.big) save_info[used_save_info].eip_change&=0xffff; + save_info[used_save_info].type=normal; + used_save_info++; +} + static void dyn_fill_blocks(void) { for (Bitu sct=0; sct Date: Mon, 8 Jan 2007 21:40:15 +0000 Subject: [PATCH 2651/4131] Add beta2 patch: Some hack to make SKYRICA work. (allocate a zero xms page to get a pointer to xms memory area) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2736 --- include/mem.h | 1 + src/hardware/memory.cpp | 6 +++++- src/ints/xms.cpp | 14 ++++++++++---- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/include/mem.h b/include/mem.h index a0d0fda1..9c3a5dfa 100644 --- a/include/mem.h +++ b/include/mem.h @@ -44,6 +44,7 @@ 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 MemHandle MEM_AllocatePages(Bitu pages,bool sequence); +MemHandle MEM_GetNextFreePage(void); PhysPt MEM_AllocatePage(void); void MEM_ReleasePages(MemHandle handle); bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence); diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index a742bef1..db613400 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: memory.cpp,v 1.46 2007-01-08 19:45:40 qbix79 Exp $ */ +/* $Id: memory.cpp,v 1.47 2007-01-08 21:40:15 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -291,6 +291,10 @@ MemHandle MEM_AllocatePages(Bitu pages,bool sequence) { return ret; } +MemHandle MEM_GetNextFreePage(void) { + return (MemHandle)BestMatch(1); +} + void MEM_ReleasePages(MemHandle handle) { while (handle>0) { MemHandle next=memory.mhandles[handle]; diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 71927a01..f5d1aa42 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.45 2007-01-08 20:10:34 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.46 2007-01-08 21:40:15 qbix79 Exp $ */ #include #include @@ -134,9 +134,15 @@ Bitu XMS_AllocateMemory(Bitu size, Bit16u& handle) { // size = kb while (!xms_handles[index].free) { if (++index>=XMS_HANDLES) return XMS_OUT_OF_HANDLES; } - Bitu pages=(size/4) + ((size & 3) ? 1 : 0); - MemHandle mem=MEM_AllocatePages(pages,true); - if ((!mem) && (size != 0)) return XMS_OUT_OF_SPACE; + MemHandle mem; + if (size!=0) { + Bitu pages=(size/4) + ((size & 3) ? 1 : 0); + mem=MEM_AllocatePages(pages,true); + if (!mem) return XMS_OUT_OF_SPACE; + } else { + mem=MEM_GetNextFreePage(); + if (mem==0) LOG(LOG_MISC,LOG_ERROR)("XMS:Allocate zero pages with no memory left"); + } xms_handles[index].free=false; xms_handles[index].mem=mem; xms_handles[index].locked=0; From fbd74e52d356910014e109b5e89bf1a35c834e50 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 8 Jan 2007 21:44:10 +0000 Subject: [PATCH 2652/4131] Add beta2 patch: [ 1557646 ] Support for 15/16/24-bit color in Win3 from vasyl. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2737 --- src/hardware/vga_draw.cpp | 167 +++++++++++++++++++++++++- src/hardware/vga_memory.cpp | 7 +- src/hardware/vga_xga.cpp | 228 ++++++++++++++++++++++++++---------- 3 files changed, 333 insertions(+), 69 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index b23e4761..b699f2bf 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -177,7 +177,7 @@ static void VGA_StartFrame_VGA() { static Bit8u * VGA_Draw_VGA_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) { if(vga.s3.hgc.curmode & 0x1) { - Bitu lineat = vidstart / ((160 * vga.draw.height) / 480); + Bitu lineat = 4 * vidstart / vga.draw.width; if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) { return VGA_Draw_VGA_Line(vidstart, panning, line); } else { @@ -235,6 +235,138 @@ static Bit8u * VGA_Draw_VGA_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) } } +static Bit8u * VGA_Draw_LIN16_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) { + if(vga.s3.hgc.curmode & 0x1) { + Bitu lineat = 2 * vidstart / vga.draw.width; + if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) { + return VGA_Draw_LIN16_Line(vidstart, panning, line); + } else { + memcpy(TempLine, VGA_Draw_LIN16_Line(vidstart, panning, line), 2*vga.draw.width); + /* Draw mouse cursor */ + Bits moff = ((Bits)lineat - (Bits)vga.s3.hgc.originy) + (Bits)vga.s3.hgc.posy; + if(moff>63) return VGA_Draw_LIN16_Line(vidstart, panning, line); + if(moff<0) moff+=64; + Bitu xat = 2*vga.s3.hgc.originx; + Bitu m, mapat; + Bits r, z; + mapat = 0; + + Bitu mouseaddr = (Bit32u)vga.s3.hgc.startaddr * (Bit32u)1024; + mouseaddr+=(moff * 16); + + Bit16u bitsA, bitsB; + Bit8u mappoint; + for(m=0;m<4;m++) { + bitsA = *(Bit16u *)&vga.mem.linear[mouseaddr]; + mouseaddr+=2; + bitsB = *(Bit16u *)&vga.mem.linear[mouseaddr]; + mouseaddr+=2; + z = 7; + for(r=15;r>=0;--r) { + mappoint = (((bitsA >> z) & 0x1) << 1) | ((bitsB >> z) & 0x1); + if(mapat >= vga.s3.hgc.posx) { + switch(mappoint) { + case 0: + TempLine[xat] = vga.s3.hgc.backstack[0]; + TempLine[xat+1] = vga.s3.hgc.backstack[1]; + break; + case 1: + TempLine[xat] = vga.s3.hgc.forestack[0]; + TempLine[xat+1] = vga.s3.hgc.forestack[1]; + break; + case 2: + //Transparent + break; + case 3: + // Invert screen data + TempLine[xat] = ~TempLine[xat]; + TempLine[xat+1] = ~TempLine[xat+1]; + break; + } + xat+=2; + } + mapat++; + --z; + if(z<0) z=15; + } + } + return TempLine; + } + } else { + /* HW Mouse not enabled, use the tried and true call */ + return VGA_Draw_LIN16_Line(vidstart, panning, line); + } +} + +static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) { + if(vga.s3.hgc.curmode & 0x1) { + Bitu lineat = vidstart / vga.draw.width; + if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) { + return VGA_Draw_LIN32_Line(vidstart, panning, line); + } else { + memcpy(TempLine, VGA_Draw_LIN32_Line(vidstart, panning, line), 4*vga.draw.width); + /* Draw mouse cursor */ + Bits moff = ((Bits)lineat - (Bits)vga.s3.hgc.originy) + (Bits)vga.s3.hgc.posy; + if(moff>63) return VGA_Draw_LIN32_Line(vidstart, panning, line); + if(moff<0) moff+=64; + Bitu xat = 4*vga.s3.hgc.originx; + Bitu m, mapat; + Bits r, z; + mapat = 0; + + Bitu mouseaddr = (Bit32u)vga.s3.hgc.startaddr * (Bit32u)1024; + mouseaddr+=(moff * 16); + + Bit16u bitsA, bitsB; + Bit8u mappoint; + for(m=0;m<4;m++) { + bitsA = *(Bit16u *)&vga.mem.linear[mouseaddr]; + mouseaddr+=2; + bitsB = *(Bit16u *)&vga.mem.linear[mouseaddr]; + mouseaddr+=2; + z = 7; + for(r=15;r>=0;--r) { + mappoint = (((bitsA >> z) & 0x1) << 1) | ((bitsB >> z) & 0x1); + if(mapat >= vga.s3.hgc.posx) { + switch(mappoint) { + case 0: + TempLine[xat] = vga.s3.hgc.backstack[0]; + TempLine[xat+1] = vga.s3.hgc.backstack[1]; + TempLine[xat+2] = vga.s3.hgc.backstack[2]; + TempLine[xat+3] = 255; + break; + case 1: + TempLine[xat] = vga.s3.hgc.forestack[0]; + TempLine[xat+1] = vga.s3.hgc.forestack[1]; + TempLine[xat+2] = vga.s3.hgc.forestack[2]; + TempLine[xat+3] = 255; + break; + case 2: + //Transparent + break; + case 3: + // Invert screen data + TempLine[xat] = ~TempLine[xat]; + TempLine[xat+1] = ~TempLine[xat+1]; + TempLine[xat+2] = ~TempLine[xat+2]; + TempLine[xat+2] = ~TempLine[xat+3]; + break; + } + xat+=4; + } + mapat++; + --z; + if(z<0) z=15; + } + } + return TempLine; + } + } else { + /* HW Mouse not enabled, use the tried and true call */ + return VGA_Draw_LIN32_Line(vidstart, panning, line); + } +} + static Bit32u FontMask[2]={0xffffffff,0x0}; static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { Bitu font_addr; @@ -397,9 +529,29 @@ void VGA_CheckScanLength(void) { void VGA_ActivateHardwareCursor(void) { if(vga.s3.hgc.curmode & 0x1) { - VGA_DrawLine=VGA_Draw_VGA_Line_HWMouse; + switch(vga.mode) { + case M_LIN32: + VGA_DrawLine=VGA_Draw_LIN32_Line_HWMouse; + break; + case M_LIN15: + case M_LIN16: + VGA_DrawLine=VGA_Draw_LIN16_Line_HWMouse; + break; + default: + VGA_DrawLine=VGA_Draw_VGA_Line_HWMouse; + } } else { - VGA_DrawLine=VGA_Draw_VGA_Line; + switch(vga.mode) { + case M_LIN32: + VGA_DrawLine=VGA_Draw_LIN32_Line; + break; + case M_LIN15: + case M_LIN16: + VGA_DrawLine=VGA_Draw_LIN16_Line; + break; + default: + VGA_DrawLine=VGA_Draw_VGA_Line; + } } } @@ -523,7 +675,8 @@ void VGA_SetupDrawing(Bitu val) { doublewidth = true; width >>= 1; } - VGA_DrawLine=VGA_Draw_LIN16_Line; + /* Use HW mouse cursor drawer if enabled */ + VGA_ActivateHardwareCursor(); break; case M_LIN16: bpp = 16; @@ -532,7 +685,8 @@ void VGA_SetupDrawing(Bitu val) { doublewidth = true; width >>= 1; } - VGA_DrawLine=VGA_Draw_LIN16_Line; + /* Use HW mouse cursor drawer if enabled */ + VGA_ActivateHardwareCursor(); break; case M_LIN32: bpp = 32; @@ -541,7 +695,8 @@ void VGA_SetupDrawing(Bitu val) { doublewidth = true; width >>= 1; } - VGA_DrawLine=VGA_Draw_LIN32_Line; + /* Use HW mouse cursor drawer if enabled */ + VGA_ActivateHardwareCursor(); break; case M_LIN4: doublewidth=(vga.seq.clocking_mode & 0x8) > 0; diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 03e0fc5c..fc078f70 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -542,8 +542,9 @@ public: } Bitu readb(PhysPt addr) { + Bitu port = PAGING_GetPhysicalAddress(addr) & 0xffff; + if(port >= 0x82E8) return IO_ReadB(port); //LOG_MSG("MMIO: Read byte from %x", addr); - return 0x00; } Bitu readw(PhysPt addr) { @@ -553,6 +554,8 @@ public: return 0x00; } Bitu readd(PhysPt addr) { + Bitu port = PAGING_GetPhysicalAddress(addr) & 0xffff; + if(port >= 0x82E8) return IO_ReadD(port); //LOG_MSG("MMIO: Read dword from %x", addr); return 0x00; } @@ -699,7 +702,7 @@ range_b800: break; } - if(((vga.s3.ext_mem_ctrl & 0x10) != 0x00) && (vga.mode == M_LIN8)) + if(((vga.s3.ext_mem_ctrl & 0x10) != 0x00) /*&& (vga.mode == M_LIN8)*/) MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio); PAGING_ClearTLB(); diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index 4a448c95..83b4a634 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -35,8 +35,8 @@ struct XGAStatus { Bit32u readmask; Bit32u writemask; - Bit8u forecolor; - Bit8u backcolor; + Bit32u forecolor; + Bit32u backcolor; Bitu curcommand; @@ -51,6 +51,8 @@ struct XGAStatus { Bit16u MAPcount; Bit16u pix_cntl; + Bit16u control1; + Bit16u control2; Bit16u read_sel; struct XGA_WaitCmd { @@ -59,6 +61,8 @@ struct XGAStatus { Bit16u cmd; Bit16u curx, cury; Bit16u x1, y1, x2, y2, sizex, sizey; + Bit32u data; /* transient data passed by multiple calls */ + Bitu datasize; } waitcmd; } xga; @@ -85,6 +89,12 @@ void XGA_Write_Multifunc(Bitu val, Bitu len) { case 0xa: xga.pix_cntl = dataval; break; + case 0xd: + xga.control2 = dataval; + break; + case 0xe: + xga.control1 = dataval; + break; case 0xf: xga.read_sel = dataval; break; @@ -94,7 +104,26 @@ void XGA_Write_Multifunc(Bitu val, Bitu len) { } } -void XGA_DrawPoint8(Bitu x, Bitu y, Bit8u c) { +Bitu XGA_Read_Multifunc() +{ + switch(xga.read_sel++) { + case 0: return xga.MIPcount; + case 1: return xga.scissors.y1; + case 2: return xga.scissors.x1; + case 3: return xga.scissors.y2; + case 4: return xga.scissors.x2; + case 5: return xga.pix_cntl; + case 6: return xga.control1; + case 7: return 0; // TODO + case 8: return 0; // TODO + case 9: return 0; // TODO + case 10: return xga.control2; + default: return 0; + } +} + + +void XGA_DrawPoint(Bitu x, Bitu y, Bitu c) { if(!(xga.curcommand & 0x1)) return; if(!(xga.curcommand & 0x10)) return; @@ -105,23 +134,28 @@ void XGA_DrawPoint8(Bitu x, Bitu y, Bit8u c) { if(y > xga.scissors.y2) return; Bit32u memaddr = (y * XGA_SCREEN_WIDTH) + x; - vga.mem.linear[memaddr] = c; + /* Need to zero out all unused bits in modes that have any (15-bit or "32"-bit -- the last + one is actually 24-bit. Without this step there may be some graphics corruption (mainly, + during windows dragging. */ + switch(vga.mode) { + case M_LIN8: vga.mem.linear[memaddr] = c; break; + case M_LIN15: ((Bit16u*)(vga.mem.linear))[memaddr] = c&0x7fff; break; + case M_LIN16: ((Bit16u*)(vga.mem.linear))[memaddr] = c; break; + case M_LIN32: ((Bit32u*)(vga.mem.linear))[memaddr] = c&0x00ffffff; break; + } } -Bit8u XGA_GetPoint8(Bitu x, Bitu y) { +Bitu XGA_GetPoint(Bitu x, Bitu y) { Bit32u memaddr = (y * XGA_SCREEN_WIDTH) + x; - return vga.mem.linear[memaddr]; - - + switch(vga.mode) { + case M_LIN8: return vga.mem.linear[memaddr]; + case M_LIN15: case M_LIN16: return ((Bit16u*)(vga.mem.linear))[memaddr]; + case M_LIN32: return ((Bit32u*)(vga.mem.linear))[memaddr]; + } + return 0; } -void XGA_DrawPoint16(Bitu x, Bitu y, Bit16u c) { - Bit16u *memptr; - Bit32u memaddr = (y * XGA_SCREEN_WIDTH) + x; - memptr = (Bit16u *)&vga.mem.linear[memaddr]; - *memptr = c; -} Bitu XGA_GetMixResult(Bitu mixmode, Bitu srcval, Bitu dstdata) { Bitu destval = 0; @@ -133,7 +167,7 @@ Bitu XGA_GetMixResult(Bitu mixmode, Bitu srcval, Bitu dstdata) { destval = 0; break; case 0x02: /* 1 (true) */ - destval = 0xff; + destval = 0xffffffff; break; case 0x03: /* 2 DST */ destval = dstdata; @@ -184,9 +218,9 @@ Bitu XGA_GetMixResult(Bitu mixmode, Bitu srcval, Bitu dstdata) { void XGA_DrawLineVector(Bitu val) { Bits xat, yat; - Bit8u srcval; - Bit8u destval; - Bit8u dstdata; + Bitu srcval; + Bitu destval; + Bitu dstdata; Bits i; Bits dx, sx, sy; @@ -260,11 +294,11 @@ void XGA_DrawLineVector(Bitu val) { LOG_MSG("XGA: DrawRect: Shouldn't be able to get here!"); break; } - dstdata = XGA_GetPoint8(xat,yat); + dstdata = XGA_GetPoint(xat,yat); destval = XGA_GetMixResult(mixmode, srcval, dstdata); - XGA_DrawPoint8(xat,yat, destval); + XGA_DrawPoint(xat,yat, destval); break; default: LOG_MSG("XGA: DrawLine: Needs mixmode %x", mixmode); @@ -283,9 +317,9 @@ void XGA_DrawLineVector(Bitu val) { void XGA_DrawLineBresenham(Bitu val) { Bits xat, yat; - Bit8u srcval; - Bit8u destval; - Bit8u dstdata; + Bitu srcval; + Bitu destval; + Bitu dstdata; Bits i; Bits tmpswap; bool steep; @@ -353,17 +387,17 @@ void XGA_DrawLineBresenham(Bitu val) { } if(steep) { - dstdata = XGA_GetPoint8(xat,yat); + dstdata = XGA_GetPoint(xat,yat); } else { - dstdata = XGA_GetPoint8(yat,xat); + dstdata = XGA_GetPoint(yat,xat); } destval = XGA_GetMixResult(mixmode, srcval, dstdata); if(steep) { - XGA_DrawPoint8(xat,yat, destval); + XGA_DrawPoint(xat,yat, destval); } else { - XGA_DrawPoint8(yat,xat, destval); + XGA_DrawPoint(yat,xat, destval); } break; @@ -393,9 +427,9 @@ void XGA_DrawLineBresenham(Bitu val) { void XGA_DrawRectangle(Bitu val) { Bit32u xat, yat; - Bit8u srcval; - Bit8u destval; - Bit8u dstdata; + Bitu srcval; + Bitu destval; + Bitu dstdata; Bits srcx, srcy, dx, dy; @@ -433,11 +467,11 @@ void XGA_DrawRectangle(Bitu val) { LOG_MSG("XGA: DrawRect: Shouldn't be able to get here!"); break; } - dstdata = XGA_GetPoint8(srcx,srcy); + dstdata = XGA_GetPoint(srcx,srcy); destval = XGA_GetMixResult(mixmode, srcval, dstdata); - XGA_DrawPoint8(srcx,srcy, destval); + XGA_DrawPoint(srcx,srcy, destval); break; default: LOG_MSG("XGA: DrawRect: Needs mixmode %x", mixmode); @@ -476,10 +510,10 @@ void XGA_DrawWait(Bitu val, Bitu len) { //if(!(xga.curcommand & 0x2)) return; Bitu mixmode = (xga.pix_cntl >> 6) & 0x3; - Bit8u srcval; - Bit8u destval; - Bit8u dstdata; - Bitu tmpval; + Bitu srcval; + Bitu destval; + Bitu dstdata; + //Bitu tmpval; Bits bitneed; switch(xga.waitcmd.cmd) { @@ -489,7 +523,6 @@ void XGA_DrawWait(Bitu val, Bitu len) { mixmode = xga.foremix; Bitu t; for(t=0;t> (8 * t)) & 0xff; switch((mixmode >> 5) & 0x03) { case 0x00: /* Src is background color */ srcval = xga.backcolor; @@ -498,7 +531,29 @@ void XGA_DrawWait(Bitu val, Bitu len) { srcval = xga.forecolor; break; case 0x02: /* Src is pixel data from PIX_TRANS register */ - srcval = tmpval; + /* This register is 16 bit. In theory, it is possible to access it as 8-bit + or 32-bit but all calls from Win3 drivers are 16-bit. 8-bit color modes + would work regardless of the access size (although something else in this + function may break), other color modes may require more complex code to + collect transient data or break incoming data in chunks. */ + if(vga.mode == M_LIN8) + srcval = (val >> (8 * t)) & 0xff; + else if(vga.mode == M_LIN32) { /* May need transient data */ + if(xga.waitcmd.datasize == 0) { + xga.waitcmd.data = val; + xga.waitcmd.datasize = 2; + return; + } else { + srcval = (val<<16)|xga.waitcmd.data; + xga.waitcmd.data = 0; + xga.waitcmd.datasize = 0; + t = len; /* All data used */ + } + } + else { + srcval = val; + t = len; /* All data used */ + } //LOG_MSG("XGA: DrawBlitWait: Wants data from PIX_TRANS register"); break; case 0x03: /* Src is bitmap data */ @@ -512,13 +567,13 @@ void XGA_DrawWait(Bitu val, Bitu len) { - dstdata = XGA_GetPoint8(xga.waitcmd.curx, xga.waitcmd.cury); + dstdata = XGA_GetPoint(xga.waitcmd.curx, xga.waitcmd.cury); destval = XGA_GetMixResult(mixmode, srcval, dstdata); //LOG_MSG("XGA: DrawPattern: Mixmode: %x srcval: %x", mixmode, srcval); - XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, destval); + XGA_DrawPoint(xga.waitcmd.curx++, xga.waitcmd.cury, destval); XGA_CheckX(); if(xga.waitcmd.newline) break; @@ -582,11 +637,11 @@ void XGA_DrawWait(Bitu val, Bitu len) { break; } - Bit8u dstdata = XGA_GetPoint8(xga.waitcmd.curx, xga.waitcmd.cury); + Bitu dstdata = XGA_GetPoint(xga.waitcmd.curx, xga.waitcmd.cury); destval = XGA_GetMixResult(mixmode, srcval, dstdata); - XGA_DrawPoint8(xga.waitcmd.curx, xga.waitcmd.cury, destval); + XGA_DrawPoint(xga.waitcmd.curx, xga.waitcmd.cury, destval); --i; if(i < 0) break; @@ -621,11 +676,11 @@ void XGA_BlitRect(Bitu val) { //Bit8u *destptr; //Bit8u *destline; //Bit8u *srcline; - Bit8u srcdata; - Bit8u dstdata; + Bitu srcdata; + Bitu dstdata; - Bit8u srcval; - Bit8u destval; + Bitu srcval; + Bitu destval; Bits srcx, srcy, tarx, tary, dx, dy; //bool incx = false; @@ -674,8 +729,8 @@ void XGA_BlitRect(Bitu val) { tarx = xga.destx; for(xat=0;xat<=xga.MAPcount;xat++) { - srcdata = XGA_GetPoint8(srcx, srcy); - dstdata = XGA_GetPoint8(tarx, tary); + srcdata = XGA_GetPoint(srcx, srcy); + dstdata = XGA_GetPoint(tarx, tary); if(mixselect == 0x3) { if(srcdata == xga.forecolor) { @@ -713,7 +768,7 @@ void XGA_BlitRect(Bitu val) { //LOG_MSG("XGA: DrawPattern: Mixmode: %x Mixselect: %x", mixmode, mixselect); //*smallptr++ = destval; - XGA_DrawPoint8(tarx, tary, destval); + XGA_DrawPoint(tarx, tary, destval); srcx += dx; tarx += dx; @@ -725,11 +780,11 @@ void XGA_BlitRect(Bitu val) { } void XGA_DrawPattern(Bitu val) { - Bit8u srcdata; - Bit8u dstdata; + Bitu srcdata; + Bitu dstdata; - Bit8u srcval; - Bit8u destval; + Bitu srcval; + Bitu destval; Bits xat, yat, srcx, srcy, tarx, tary, dx, dy; @@ -765,8 +820,8 @@ void XGA_DrawPattern(Bitu val) { tarx = xga.destx; for(xat=0;xat<=xga.MAPcount;xat++) { - srcdata = XGA_GetPoint8(srcx + (tarx & 0x7), srcy + (tary & 0x7)); - dstdata = XGA_GetPoint8(tarx, tary); + srcdata = XGA_GetPoint(srcx + (tarx & 0x7), srcy + (tary & 0x7)); + dstdata = XGA_GetPoint(tarx, tary); if(mixselect == 0x3) { @@ -802,7 +857,7 @@ void XGA_DrawPattern(Bitu val) { destval = XGA_GetMixResult(mixmode, srcval, dstdata); - XGA_DrawPoint8(tarx, tary, destval); + XGA_DrawPoint(tarx, tary, destval); tarx += dx; } @@ -858,6 +913,9 @@ void XGA_DrawCmd(Bitu val, Bitu len) { xga.waitcmd.sizey = xga.MIPcount + 1; xga.waitcmd.cmd = 2; + xga.waitcmd.data = 0; + xga.waitcmd.datasize = 0; + #if XGA_SHOW_COMMAND_TRACE == 1 LOG_MSG("XGA: Draw wait rect, width %d, heigth %d", xga.MAPcount, xga.MIPcount+1); #endif @@ -882,6 +940,42 @@ void XGA_DrawCmd(Bitu val, Bitu len) { } } +void XGA_SetDualReg(Bit32u& reg, Bitu val) +{ + switch(vga.mode) { + case M_LIN8: reg = val&0x000000ff; break; + case M_LIN15: case M_LIN16: reg = val&0x0000ffff; break; + case M_LIN32: { + if(xga.control1 & 0x200) + reg = val; + else if(xga.control1 & 0x10) + reg = (reg&0x0000ffff)|(val<<16); + else + reg = (reg&0xffff0000)|(val&0x0000ffff); + xga.control1 ^= 0x10; + } + break; + } +} + +Bitu XGA_GetDualReg(Bit32u reg) +{ + switch(vga.mode) { + case M_LIN8: return reg&0x000000ff; + case M_LIN15: case M_LIN16: return reg&0x0000ffff; + case M_LIN32: { + if(xga.control1 & 0x200) + return reg; + xga.control1 ^= 0x10; + if(xga.control1 & 0x10) + return reg&0x0000ffff; + else + return reg>>16; + } + } + return 0; +} + void XGA_Write(Bitu port, Bitu val, Bitu len) { switch(port) { case 0x92e8: @@ -894,16 +988,16 @@ void XGA_Write(Bitu port, Bitu val, Bitu len) { XGA_DrawCmd(val, len); break; case 0xa2e8: - xga.backcolor = val; + XGA_SetDualReg(xga.backcolor, val); break; case 0xa6e8: - xga.forecolor = val; + XGA_SetDualReg(xga.forecolor, val); break; case 0xaae8: - xga.writemask = val; + XGA_SetDualReg(xga.writemask, val); break; case 0xaee8: - xga.readmask = val; + XGA_SetDualReg(xga.readmask, val); break; case 0x82e8: xga.cury = val; @@ -958,8 +1052,20 @@ Bitu XGA_Read(Bitu port, Bitu len) { } else { return 0x0; } + case 0xbee8: + return XGA_Read_Multifunc(); case 0xa2e8: - return xga.backcolor; + return XGA_GetDualReg(xga.backcolor); + break; + case 0xa6e8: + return XGA_GetDualReg(xga.forecolor); + break; + case 0xaae8: + return XGA_GetDualReg(xga.writemask); + break; + case 0xaee8: + return XGA_GetDualReg(xga.readmask); + break; default: LOG_MSG("XGA: Read from port %x, len %x", port, len); return 0x0; From aad5eb3e23b71b17148a2bfadf1512f8bd4697ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 8 Jan 2007 21:58:37 +0000 Subject: [PATCH 2653/4131] fully clear display start on graphics mode switches (duke3d vesa exit) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2738 --- src/ints/int10_modes.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 8f4db1b7..24066be4 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -681,6 +681,9 @@ bool INT10_SetVideoMode(Bitu mode) { /* This register actually has more bits but only use the extended offset ones */ IO_Write(crtc_base,0x51); IO_Write(crtc_base + 1,(offset & 0x300) >> 4); + /* Clear remaining bits of the display start */ + IO_Write(crtc_base,0x69); + IO_Write(crtc_base + 1,0); /* Extended Vertical Overflow */ IO_Write(crtc_base,0x5e);IO_Write(crtc_base+1,ver_overflow); From f65e4b3423042d35549a781bdc0bbfde7883bdc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 8 Jan 2007 22:04:20 +0000 Subject: [PATCH 2654/4131] Add beta2 patch: allow some non-pageframe segments to be remapped through the ems interface (Synnergist/Overlord) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2739 --- src/ints/ems.cpp | 96 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 84 insertions(+), 12 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index a5599d6d..8e8fe04f 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.54 2007-01-08 19:45:41 qbix79 Exp $ */ +/* $Id: ems.cpp,v 1.55 2007-01-08 22:04:20 c2woody Exp $ */ #include #include @@ -176,6 +176,7 @@ struct EMM_Handle { static EMM_Handle emm_handles[EMM_MAX_HANDLES]; static EMM_Mapping emm_mappings[EMM_MAX_PHYS]; +static EMM_Mapping emm_segmentmappings[0x40]; static struct { bool enabled; @@ -274,6 +275,56 @@ static Bit8u EMM_MapPage(Bitu phys_page,Bit16u handle,Bit16u log_page) { } } +static Bit8u EMM_MapSegment(Bitu segment,Bit16u handle,Bit16u log_page) { +// LOG_MSG("EMS MapSegment handle %d segment %d log %d",handle,segment,log_page); + + if (((segment>=0xa000) && (segment<0xb000)) || ((segment>=EMM_PAGEFRAME-0x1000) && (segment=0) && (tphysPage>10].handle=NULL_HANDLE; + emm_segmentmappings[segment>>10].page=NULL_PAGE; + } + for (Bitu i=0;i<4;i++) + PAGING_MapPage(segment*16/4096+i,segment*16/4096+i); + PAGING_ClearTLB(); + return EMM_NO_ERROR; + } + /* Check for valid handle */ + if (!ValidHandle(handle)) return EMM_INVALID_HANDLE; + + if (log_page=0) && (tphysPage>10].handle=handle; + emm_segmentmappings[segment>>10].page=log_page; + } + + MemHandle memh=MEM_NextHandleAt(emm_handles[handle].mem,log_page*4);; + for (Bitu i=0;i<4;i++) { + PAGING_MapPage(segment*16/4096+i,memh); + memh=MEM_NextHandle(memh); + } + PAGING_ClearTLB(); + return EMM_NO_ERROR; + } else { + /* Illegal logical page it is */ + return EMM_LOG_OUT_RANGE; + } + } + + return EMM_ILL_PHYS; +} + static Bit8u EMM_ReleaseMemory(Bit16u handle) { /* Check for valid handle */ if (!ValidHandle(handle)) return EMM_INVALID_HANDLE; @@ -305,6 +356,11 @@ static Bit8u EMM_SavePageMap(Bit16u handle) { static Bit8u EMM_RestoreMappingTable(void) { Bit8u result; /* Move through the mappings table and setup mapping accordingly */ + for (Bitu i=0;i<0x40;i++) { + /* Skip the pageframe */ + if ((i>=EMM_PAGEFRAME/0x400) && (i<(EMM_PAGEFRAME/0x400)+EMM_MAX_PHYS)) continue; + result=EMM_MapSegment(i<<10,emm_segmentmappings[i].handle,emm_segmentmappings[i].page); + } for (Bitu i=0;i0;count--) { - Bit16u page=mem_readw(list);list+=2; - if ((page=EMM_PAGEFRAME+0x1000)) return EMM_ILL_PHYS; - page = (page-EMM_PAGEFRAME) / (EMM_PAGE_SIZE>>4); - mem_writew(data,page);data+=2; - MEM_BlockWrite(data,&emm_mappings[page],sizeof(EMM_Mapping)); - data+=sizeof(EMM_Mapping); + Bit16u segment=mem_readw(list);list+=2; + if ((segment>=EMM_PAGEFRAME) && (segment>4); + mem_writew(data,segment);data+=2; + MEM_BlockWrite(data,&emm_mappings[page],sizeof(EMM_Mapping)); + data+=sizeof(EMM_Mapping); + } else if (((segment>=EMM_PAGEFRAME-0x1000) && (segment=0xa000) && (segment<0xb000))) { + mem_writew(data,segment);data+=2; + MEM_BlockWrite(data,&emm_segmentmappings[segment>>10],sizeof(EMM_Mapping)); + data+=sizeof(EMM_Mapping); + } else { + return EMM_ILL_PHYS; + } } break; case 0x01: /* Restore Partial Page Map */ data = SegPhys(ds)+reg_si; count= mem_readw(data);data+=2; for (;count>0;count--) { - Bit16u page=mem_readw(data);data+=2; - if (page>=EMM_MAX_PHYS) return EMM_ILL_PHYS; - MEM_BlockRead(data,&emm_mappings[page],sizeof(EMM_Mapping)); + Bit16u segment=mem_readw(data);data+=2; + if ((segment>=EMM_PAGEFRAME) && (segment>4); + MEM_BlockRead(data,&emm_mappings[page],sizeof(EMM_Mapping)); + } else if (((segment>=EMM_PAGEFRAME-0x1000) && (segment=0xa000) && (segment<0xb000))) { + MEM_BlockRead(data,&emm_segmentmappings[segment>>10],sizeof(EMM_Mapping)); + } else { + return EMM_ILL_PHYS; + } data+=sizeof(EMM_Mapping); } return EMM_RestoreMappingTable(); @@ -636,8 +705,7 @@ static Bitu INT67_Handler(void) { { PhysPt data = SegPhys(ds)+reg_si; for (int i=0; i Date: Mon, 8 Jan 2007 22:25:32 +0000 Subject: [PATCH 2655/4131] Add beta2 patch: fix Psycho Pinball tilt causing mode changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2740 --- src/hardware/vga_crtc.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 3d8fb2ae..efbc61d6 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -16,12 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include #include "dosbox.h" #include "inout.h" #include "vga.h" #include "debug.h" #include "cpu.h" #include "video.h" +#include "pic.h" #define crtc(blah) vga.crtc.blah @@ -215,6 +217,10 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { break; case 0x12: /* Vertical Display End Register */ if (val!=crtc(vertical_display_end)) { + if (abs((Bits)val-(Bits)crtc(vertical_display_end))<3) { + PIC_RemoveEvents(VGA_SetupDrawing); + vga.draw.resizing=false; + } crtc(vertical_display_end)=val; VGA_StartResize(); } From 4b6d005406b650e984e2318a6a3de1c992524325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 9 Jan 2007 17:18:52 +0000 Subject: [PATCH 2656/4131] Add beta2 patch: merge in old trap skip logic again; give trap priority over hw interrupts Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2741 --- include/cpu.h | 1 + src/cpu/core_dyn_x86.cpp | 3 ++- src/cpu/core_normal.cpp | 3 ++- src/cpu/core_normal/prefix_none.h | 12 ++++++++++++ src/cpu/core_simple.cpp | 10 ++++------ src/cpu/cpu.cpp | 3 ++- src/hardware/pic.cpp | 3 ++- 7 files changed, 25 insertions(+), 10 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 525ebfae..38bb2e42 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -446,6 +446,7 @@ struct CPUBlock { Bitu which,error; } exception; Bits direction; + bool trap_skip; Bit32u drx[8]; Bit32u trx[8]; }; diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 021528ab..659ca600 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -346,9 +346,10 @@ run_block: 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 (GETFLAG(TF)) CPU_HW_Interrupt(1); + if (!cpu.trap_skip) CPU_HW_Interrupt(1); CPU_Cycles = oldCycles-1; cpudecoder = &CPU_Core_Dyn_X86_Run; diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 672105db..d5495b9e 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -191,9 +191,10 @@ decode_end: Bits CPU_Core_Normal_Trap_Run(void) { Bits oldCycles = CPU_Cycles; CPU_Cycles = 1; + cpu.trap_skip = false; Bits ret=CPU_Core_Normal_Run(); - if (GETFLAG(TF)) CPU_HW_Interrupt(1); + if (!cpu.trap_skip) CPU_HW_Interrupt(1); CPU_Cycles = oldCycles-1; cpudecoder = &CPU_Core_Normal_Run; diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 24e6c177..36739a3f 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -746,6 +746,9 @@ return debugCallback; #endif CPU_SW_Interrupt_NoIOPLCheck(3,GETIP); +#if CPU_TRAP_CHECK + cpu.trap_skip=true; +#endif continue; CASE_B(0xcd) /* INT Ib */ { @@ -757,12 +760,18 @@ } #endif CPU_SW_Interrupt(num,GETIP); +#if CPU_TRAP_CHECK + cpu.trap_skip=true; +#endif continue; } CASE_B(0xce) /* INTO */ if (get_OF()) { FillFlags(); CPU_SW_Interrupt(4,GETIP); +#if CPU_TRAP_CHECK + cpu.trap_skip=true; +#endif continue; } break; @@ -946,6 +955,9 @@ CASE_B(0xf1) /* ICEBP */ FillFlags(); CPU_SW_Interrupt_NoIOPLCheck(1,GETIP); +#if CPU_TRAP_CHECK + cpu.trap_skip=true; +#endif continue; CASE_B(0xf2) /* REPNZ */ DO_PREFIX_REP(false); diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp index c593fed7..cfe68d57 100644 --- a/src/cpu/core_simple.cpp +++ b/src/cpu/core_simple.cpp @@ -93,9 +93,6 @@ static struct { bool rep_zero; Bitu prefixes; GetEAHandler * ea_table; - struct { - bool skip; - } trap; } core; #define GETIP (core.cseip-SegBase(cs)-MemBase) @@ -188,15 +185,16 @@ decode_end: return CBRET_NONE; } +// not really used Bits CPU_Core_Simple_Trap_Run(void) { - Bits oldCycles = CPU_Cycles; CPU_Cycles = 1; + cpu.trap_skip = false; Bits ret=CPU_Core_Normal_Run(); - if (GETFLAG(TF)) CPU_SW_Interrupt(1,reg_eip); + if (!cpu.trap_skip) CPU_HW_Interrupt(1); CPU_Cycles = oldCycles-1; - cpudecoder = &CPU_Core_Normal_Run; + cpudecoder = &CPU_Core_Simple_Run; return ret; } diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 357629ed..747ca345 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.91 2007-01-08 19:45:38 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.92 2007-01-09 17:18:52 c2woody Exp $ */ #include #include "dosbox.h" @@ -2025,6 +2025,7 @@ public: cpu.stack.mask=0xffff; cpu.stack.notmask=0xffff0000; cpu.stack.big=false; + cpu.trap_skip=false; cpu.idt.SetBase(0); cpu.idt.SetLimit(1023); diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 08246300..3b79e162 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.37 2007-01-08 19:45:40 qbix79 Exp $ */ +/* $Id: pic.cpp,v 1.38 2007-01-09 17:18:52 c2woody Exp $ */ #include @@ -282,6 +282,7 @@ static inline bool PIC_startIRQ(Bitu i) { void PIC_runIRQs(void) { if (!GETFLAG(IF)) return; if (!PIC_IRQCheck) return; + if (cpudecoder==CPU_Core_Normal_Trap_Run) return; static Bitu IRQ_priority_order[16] = { 0,1,2,8,9,10,11,12,13,14,15,3,4,5,6,7 }; From d3f72c5938d44f3fbba5710c328c421b09798fb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 9 Jan 2007 17:44:20 +0000 Subject: [PATCH 2657/4131] xtale: fix flag bug when opening files in readwrite mode on cdroms (sf patch #1622004) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2742 --- src/dos/drive_local.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index ed7c930a..279e18b6 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.73 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.74 2007-01-09 17:44:20 c2woody Exp $ */ #include #include @@ -571,9 +571,9 @@ cdromDrive::cdromDrive(const char driveLetter, const char * startdir,Bit16u _byt bool cdromDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { - if (flags==OPEN_READWRITE) { - flags = OPEN_READ; - } else if (flags==OPEN_WRITE) { + if ((flags&3)==OPEN_READWRITE) { + flags &= ~OPEN_READWRITE; + } else if ((flags&3)==OPEN_WRITE) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } From d6037bb2fe8cd09fc3c570fd22b7e350f31c29f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 9 Jan 2007 18:24:50 +0000 Subject: [PATCH 2658/4131] Add beta2 patch: add rtc irq acknowledging (fixes Fury) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2743 --- src/hardware/cmos.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 706427fc..f5ff406e 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -35,6 +35,7 @@ static struct { bool enabled; Bit8u div; float delay; + bool acknowledged; } timer; struct { double timer; @@ -45,7 +46,10 @@ static struct { } cmos; static void cmos_timerevent(Bitu val) { - PIC_ActivateIRQ(8); + if (cmos.timer.acknowledged) { + cmos.timer.acknowledged=false; + PIC_ActivateIRQ(8); + } if (cmos.timer.enabled) { PIC_AddEvent(cmos_timerevent,cmos.timer.delay); cmos.regs[0xc] = 0xC0;//Contraption Zack (music) @@ -155,6 +159,7 @@ static Bitu cmos_readreg(Bitu port,Bitu iolen) { return (cmos.regs[0x0a]&0x7f); } case 0x0c: /* Status register C */ + cmos.timer.acknowledged=true; if (cmos.timer.enabled) { /* In periodic interrupt mode only care for those flags */ Bit8u val=cmos.regs[0xc]; @@ -286,6 +291,7 @@ public: WriteHandler[1].Install(0x71,cmos_writereg,IO_MB); ReadHandler[0].Install(0x71,cmos_readreg,IO_MB); cmos.timer.enabled=false; + cmos.timer.acknowledged=true; cmos.reg=0xa; cmos_writereg(0x71,0x26,1); cmos.reg=0xb; From ab0d4104e201c3fd727aee35f0dfeeeb793314e6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Jan 2007 09:04:33 +0000 Subject: [PATCH 2659/4131] Improve copy so it supports appending of files. Fixes a few installers. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2744 --- src/shell/shell.cpp | 3 +- src/shell/shell_cmds.cpp | 224 ++++++++++++++++++++++++--------------- 2 files changed, 141 insertions(+), 86 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 865d5871..5b2ccb2d 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.79 2007-01-08 19:59:06 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.80 2007-01-10 09:04:33 qbix79 Exp $ */ #include #include @@ -424,6 +424,7 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_ECHO_ON","ECHO is on.\n"); MSG_Add("SHELL_CMD_ECHO_OFF","ECHO is off.\n"); MSG_Add("SHELL_ILLEGAL_SWITCH","Illegal switch: %s.\n"); + MSG_Add("SHELL_MISSING_PARAMETER","Required parameter missing.\n"); MSG_Add("SHELL_CMD_CHDIR_ERROR","Unable to change to: %s.\n"); MSG_Add("SHELL_CMD_CHDIR_HINT","To change to different drive type \033[31m%c:\033[0m\n"); MSG_Add("SHELL_CMD_MKDIR_ERROR","Unable to make: %s.\n"); diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index e0787563..aeb80f78 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,11 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.70 2007-01-08 19:45:42 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.71 2007-01-10 09:04:33 qbix79 Exp $ */ #include #include - +#include +#include #include "shell.h" #include "callback.h" #include "regs.h" @@ -97,7 +98,7 @@ void DOS_Shell::DoCommand(char * line) { } cmd_index++; } - } + } *cmd_write++=*line++; } *cmd_write=0; @@ -454,6 +455,14 @@ void DOS_Shell::CMD_DIR(char * args) { WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_FREE"),dir_count,numformat); dos.dta(save_dta); } +struct copysource { + std::string filename; + bool concat; + copysource(std::string filein,bool concatin): + filename(filein),concat(concatin){ }; + copysource():filename(""),concat(false){ }; +}; + void DOS_Shell::CMD_COPY(char * args) { HELP("COPY"); @@ -465,10 +474,13 @@ void DOS_Shell::CMD_COPY(char * args) { DOS_DTA dta(dos.dta()); Bit32u size;Bit16u date;Bit16u time;Bit8u attr; char name[DOS_NAMELENGTH_ASCII]; - + std::vector sources; // ignore /b and /t switches: always copy binary - ScanCMDBool(args,"B"); - ScanCMDBool(args,"T"); + while(ScanCMDBool(args,"B")) ; + while(ScanCMDBool(args,"T")) ; //Shouldn't this be A ? + while(ScanCMDBool(args,"A")) ; + ScanCMDBool(args,"Y"); + ScanCMDBool(args,"-Y"); char * rem=ScanCMDRemain(args); if (rem) { @@ -476,95 +488,137 @@ void DOS_Shell::CMD_COPY(char * args) { dos.dta(save_dta); return; } - // source/target - char* source = StripWord(args); - char* target = NULL; - if (args && *args) target = StripWord(args); - if (!target || !*target) target = defaulttarget; - - // Target and Source have to be there - if (!source || !strlen(source)) { - WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); + // Gather all sources (extension to copy more then 1 file specified at commandline) + // Concatating files go as follows: All parts except for the last bear the concat flag. + // This construction allows them to be counted (only the non concat set) + char* source_p = NULL; + while ( (source_p = StripWord(args)) && *source_p ) { + do { + char* plus = strchr(source_p,'+'); + if(plus) *plus++ = 0; + sources.push_back(copysource(source_p,(plus)?true:false)); + source_p = plus; + } while(source_p && *source_p); + } + // At least one source has to be there + if (!sources.size() || !sources[0].filename.size()) { + WriteOut(MSG_Get("SHELL_MISSING_PARAMETER")); dos.dta(save_dta); - return; + return; }; - /* Make a full path in the args */ - char pathSource[DOS_PATHLENGTH]; - char pathTarget[DOS_PATHLENGTH]; - - if (!DOS_Canonicalize(source,pathSource)) { - WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); - dos.dta(save_dta); - return; - } - // cut search pattern - char* pos = strrchr(pathSource,'\\'); - if (pos) *(pos+1) = 0; - - if (!DOS_Canonicalize(target,pathTarget)) { - WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); - dos.dta(save_dta); - return; - } - char* temp = strstr(pathTarget,"*.*"); - if(temp) *temp = 0;//strip off *.* from target - - // add '\\' if target is a directoy - if (pathTarget[strlen(pathTarget)-1]!='\\') { - if (DOS_FindFirst(pathTarget,0xffff & ~DOS_ATTR_VOLUME)) { - dta.GetResult(name,size,date,time,attr); - if (attr & DOS_ATTR_DIRECTORY) - strcat(pathTarget,"\\"); - } - }; - - bool ret=DOS_FindFirst(source,0xffff & ~DOS_ATTR_VOLUME); - if (!ret) { - WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),source); - dos.dta(save_dta); - return; + copysource target; + // If more then one object exists and last target is not part of a + // concat sequence then make it the target. + if(sources.size()>1 && !sources[sources.size()-2].concat){ + target = sources.back(); + sources.pop_back(); } + //If no target => default target with concat flag true to detect a+b+c + if(target.filename.size() == 0) target = copysource(defaulttarget,true); + copysource oldsource; + copysource source; Bit32u count = 0; + while(sources.size()) { + /* Get next source item and keep track of old source for concat start end */ + oldsource = source; + source = sources[0]; + sources.erase(sources.begin()); - Bit16u sourceHandle,targetHandle; - char nameTarget[DOS_PATHLENGTH]; - char nameSource[DOS_PATHLENGTH]; + //Skip first file if doing a+b+c. Set target to first file + if(!oldsource.concat && source.concat && target.concat) { + target = source; + continue; + } - while (ret) { - dta.GetResult(name,size,date,time,attr); + /* Make a full path in the args */ + char pathSource[DOS_PATHLENGTH]; + char pathTarget[DOS_PATHLENGTH]; - if ((attr & DOS_ATTR_DIRECTORY)==0) { - strcpy(nameSource,pathSource); - strcat(nameSource,name); - // Open Source - if (DOS_OpenFile(nameSource,0,&sourceHandle)) { - // Create Target - strcpy(nameTarget,pathTarget); - if (nameTarget[strlen(nameTarget)-1]=='\\') strcat(nameTarget,name); - - if (DOS_CreateFile(nameTarget,0,&targetHandle)) { - // Copy - static Bit8u buffer[0x8000]; // static, otherwise stack overflow possible. - bool failed = false; - Bit16u toread = 0x8000; - do { - failed |= DOS_ReadFile(sourceHandle,buffer,&toread); - failed |= DOS_WriteFile(targetHandle,buffer,&toread); - } while (toread==0x8000); - failed |= DOS_CloseFile(sourceHandle); - failed |= DOS_CloseFile(targetHandle); - WriteOut(" %s\n",name); - count++; - } else { - DOS_CloseFile(sourceHandle); - WriteOut(MSG_Get("SHELL_CMD_COPY_FAILURE"),target); - } - } else WriteOut(MSG_Get("SHELL_CMD_COPY_FAILURE"),source); + if (!DOS_Canonicalize(const_cast(source.filename.c_str()),pathSource)) { + WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); + dos.dta(save_dta); + return; + } + // cut search pattern + char* pos = strrchr(pathSource,'\\'); + if (pos) *(pos+1) = 0; + + if (!DOS_Canonicalize(const_cast(target.filename.c_str()),pathTarget)) { + WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); + dos.dta(save_dta); + return; + } + char* temp = strstr(pathTarget,"*.*"); + if(temp) *temp = 0;//strip off *.* from target + + // add '\\' if target is a directoy + if (pathTarget[strlen(pathTarget)-1]!='\\') { + if (DOS_FindFirst(pathTarget,0xffff & ~DOS_ATTR_VOLUME)) { + dta.GetResult(name,size,date,time,attr); + if (attr & DOS_ATTR_DIRECTORY) + strcat(pathTarget,"\\"); + } }; - ret=DOS_FindNext(); - }; + + //Find first sourcefile + bool ret = DOS_FindFirst(const_cast(source.filename.c_str()),0xffff & ~DOS_ATTR_VOLUME); + if (!ret) { + WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),const_cast(source.filename.c_str())); + dos.dta(save_dta); + return; + } + + Bit16u sourceHandle,targetHandle; + char nameTarget[DOS_PATHLENGTH]; + char nameSource[DOS_PATHLENGTH]; + + while (ret) { + dta.GetResult(name,size,date,time,attr); + + if ((attr & DOS_ATTR_DIRECTORY)==0) { + strcpy(nameSource,pathSource); + strcat(nameSource,name); + // Open Source + if (DOS_OpenFile(nameSource,0,&sourceHandle)) { + // Create Target or open it if in concat mode + strcpy(nameTarget,pathTarget); + if (nameTarget[strlen(nameTarget)-1]=='\\') strcat(nameTarget,name); + + //Don't create a newfile when in concat mode + if (oldsource.concat || DOS_CreateFile(nameTarget,0,&targetHandle)) { + Bit32u dummy=0; + //In concat mode. Open the target and seek to the eof + if (!oldsource.concat || (DOS_OpenFile(nameTarget,OPEN_READWRITE,&targetHandle) && + DOS_SeekFile(targetHandle,&dummy,DOS_SEEK_END))) { + // Copy + static Bit8u buffer[0x8000]; // static, otherwise stack overflow possible. + bool failed = false; + Bit16u toread = 0x8000; + do { + failed |= DOS_ReadFile(sourceHandle,buffer,&toread); + failed |= DOS_WriteFile(targetHandle,buffer,&toread); + } while (toread==0x8000); + failed |= DOS_CloseFile(sourceHandle); + failed |= DOS_CloseFile(targetHandle); + WriteOut(" %s\n",name); + if(!source.concat) count++; //Only count concat files once + } else { + DOS_CloseFile(sourceHandle); + WriteOut(MSG_Get("SHELL_CMD_COPY_FAILURE"),const_cast(target.filename.c_str())); + } + } else { + DOS_CloseFile(sourceHandle); + WriteOut(MSG_Get("SHELL_CMD_COPY_FAILURE"),const_cast(target.filename.c_str())); + } + } else WriteOut(MSG_Get("SHELL_CMD_COPY_FAILURE"),const_cast(source.filename.c_str())); + }; + //On the next file + ret = DOS_FindNext(); + }; + } + WriteOut(MSG_Get("SHELL_CMD_COPY_SUCCESS"),count); dos.dta(save_dta); } From 064cef2a7fe1dc06674e584a86cd4b96f2f53f34 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Jan 2007 10:47:08 +0000 Subject: [PATCH 2660/4131] Silence a warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2745 --- src/dos/drive_iso.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 5cc31b84..710764e4 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.15 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.16 2007-01-10 10:47:08 qbix79 Exp $ */ #include #include @@ -474,8 +474,8 @@ inline bool isoDrive :: readSector(Bit8u *buffer, Bit32u sector) int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) { // copy data into isoDirEntry struct, data[0] = length of DirEntry - if (data[0] > sizeof(isoDirEntry)) return -1; - memcpy(de, data, data[0]); +// if (data[0] > sizeof(isoDirEntry)) return -1;//check disabled as isoDirentry is currently 258 bytes large. So it always fits + memcpy(de, data, data[0]);//Perharps care about a zero at the end. // xa not supported if (de->extAttrLength != 0) return -1; From 7d57a8d5e5ba871f39fee96ca8bb26fe4d364c62 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Jan 2007 12:04:35 +0000 Subject: [PATCH 2661/4131] Give a dos errorcode instead of E_Exiting on illegal execution mode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2746 --- src/dos/dos_execute.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index d23a45cc..ae43c9ea 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.58 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: dos_execute.cpp,v 1.59 2007-01-10 12:04:35 qbix79 Exp $ */ #include #include @@ -261,12 +261,20 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { DOS_ParamBlock block(block_pt); block.LoadData(); + //Remove the loadhigh flag for the moment! + if(flags&0x80) LOG(LOG_EXEC,LOG_ERROR)("using loadhigh flag!!!!!. dropping it"); + flags &= 0x7f; if (flags!=LOADNGO && flags!=OVERLAY && flags!=LOAD) { - E_Exit("DOS:Not supported execute mode %d for file %s",flags,name); + DOS_SetError(DOSERR_FORMAT_INVALID); + return false; +// E_Exit("DOS:Not supported execute mode %d for file %s",flags,name); } /* Check for EXE or COM File */ bool iscom=false; - if (!DOS_OpenFile(name,OPEN_READ,&fhandle)) return false; + if (!DOS_OpenFile(name,OPEN_READ,&fhandle)) { + DOS_SetError(DOSERR_FILE_NOT_FOUND); + return false; + } len=sizeof(EXE_Header); if (!DOS_ReadFile(fhandle,(Bit8u *)&head,&len)) { DOS_CloseFile(fhandle); From e529cae44681f21fc875a85d7219c1c0a2dac21d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 10 Jan 2007 15:01:15 +0000 Subject: [PATCH 2662/4131] Add beta2 patch: enable full joystick remapping Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2747 --- include/joystick.h | 3 +- src/dosbox.cpp | 15 +- src/gui/sdl_mapper.cpp | 773 ++++++++++++++++++++++++++++---------- src/gui/sdlmain.cpp | 16 +- src/hardware/joystick.cpp | 6 +- 5 files changed, 586 insertions(+), 227 deletions(-) diff --git a/include/joystick.h b/include/joystick.h index fdeb421c..0afef907 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: joystick.h,v 1.9 2007-01-08 19:45:37 qbix79 Exp $ */ +/* $Id: joystick.h,v 1.10 2007-01-10 15:00:38 c2woody Exp $ */ #ifndef DOSBOX_JOYSTICK_H #define DOSBOX_JOYSTICK_H void JOYSTICK_Enable(Bitu which,bool enabled); @@ -37,6 +37,7 @@ float JOYSTICK_GetMove_Y(Bitu which); enum JoystickType { JOY_NONE, + JOY_AUTO, JOY_2AXIS, JOY_4AXIS, JOY_FCS, diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 62b1cadc..9c4b2f9f 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.106 2007-01-08 20:10:34 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.107 2007-01-10 15:00:38 c2woody Exp $ */ #include #include @@ -400,18 +400,19 @@ void DOSBOX_Init(void) { "disney -- Enable Disney Sound Source emulation.\n" ); - secprop=control->AddSection_prop("bios",&BIOS_Init,false);//done - MSG_Add("BIOS_CONFIGFILE_HELP", - "joysticktype -- Type of joystick to emulate: none, 2axis, 4axis,\n" - " fcs (Thrustmaster) ,ch (CH Flightstick).\n" + secprop=control->AddSection_prop("joystick",&BIOS_Init,false);//done + MSG_Add("JOYSTICK_CONFIGFILE_HELP", + "joysticktype -- Type of joystick to emulate: auto (default), none,\n" + " 2axis (supports two joysticks), 4axis,\n" + " fcs (Thrustmaster), ch (CH Flightstick).\n" " none disables joystick emulation.\n" - " 2axis is the default and supports two joysticks.\n" + " auto chooses emulation depending on real joystick(s).\n" ); secprop->AddInitFunction(&INT10_Init); secprop->AddInitFunction(&MOUSE_Init); //Must be after int10 as it uses CurMode secprop->AddInitFunction(&JOYSTICK_Init); - secprop->Add_string("joysticktype","2axis"); + secprop->Add_string("joysticktype","auto"); // had to rename these to serial due to conflicts in config secprop=control->AddSection_prop("serial",&SERIAL_Init,true); diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 4be259b3..6118b0d9 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,9 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.29 2007-01-08 21:07:39 qbix79 Exp $ */ - -#define OLD_JOYSTICK 1 +/* $Id: sdl_mapper.cpp,v 1.30 2007-01-10 15:01:15 c2woody Exp $ */ #include #include @@ -99,26 +97,89 @@ public: events.push_back(this); bindlist.clear(); activity=0; + current_value=0; } void AddBind(CBind * bind); virtual ~CEvent() {} virtual void Active(bool yesno)=0; - INLINE void Activate(void) { - if (!activity) Active(true); - activity++; - } - INLINE void DeActivate(void) { - activity--; - if (!activity) Active(false); - } + virtual INLINE void Activate(bool ev_trigger)=0; + virtual INLINE void DeActivate(bool ev_trigger)=0; void DeActivateAll(void); - void SetValue(Bits /*value*/){ - }; - char * GetName(void) { return entry;} + void SetValue(Bits value){ + current_value=value; + } + Bits GetValue(void) { + return current_value; + } + char * GetName(void) { return entry; } + virtual bool IsTrigger(void)=0; CBindList bindlist; protected: Bitu activity; char entry[16]; + Bits current_value; +}; + +/* class for events which can be ON/OFF only: key presses, joystick buttons, joystick hat */ +class CTriggeredEvent : public CEvent { +public: + CTriggeredEvent(char const * const _entry) : CEvent(_entry) {} + virtual bool IsTrigger(void) { + return true; + } + INLINE void Activate(bool ev_trigger) { + if (current_value>25000) { + /* value exceeds boundary, trigger event if not active */ + if (!activity) Active(true); + if (activity<32767) activity++; + } else { + if (activity>0) { + /* untrigger event if it is fully inactive */ + DeActivate(ev_trigger); + activity=0; + } + } + } + INLINE void DeActivate(bool /*ev_trigger*/) { + activity--; + if (!activity) Active(false); + } +}; + +/* class for events which have a non-boolean state: joystick axis movement */ +class CContinuousEvent : public CEvent { +public: + CContinuousEvent(char const * const _entry) : CEvent(_entry) {} + virtual bool IsTrigger(void) { + return false; + } + INLINE void Activate(bool ev_trigger) { + if (ev_trigger) { + activity++; + Active(true); + } else { + /* test if no trigger-activity is present, this cares especially + about activity of the opposite-direction joystick axis for example */ + if (!GetActivityCount()) Active(true); + } + } + INLINE void DeActivate(bool ev_trigger) { + if (ev_trigger) { + if (activity>0) activity--; + if (activity==0) { + /* test if still some trigger-activity is present, + adjust the state in this case accordingly */ + if (GetActivityCount()) RepostActivity(); + else Active(false); + } + } else { + if (!GetActivityCount()) Active(false); + } + } + virtual Bitu GetActivityCount(void) { + return activity; + } + virtual void RepostActivity(void) {} }; class CBind { @@ -149,26 +210,46 @@ public: if (!strcasecmp(word,"hold")) flags|=BFLG_Hold; } } - void Activate(Bits _value) { - event->SetValue(_value); - if (active) return; - event->Activate(); - active=true; - } - void DeActivate(void) { - if (!active) return; - active=false; - if (flags & BFLG_Hold) { - if (!holding) { - holdlist.push_back(this); - holding=true; - return; + void Activate(Bits _value,bool ev_trigger) { + if (event->IsTrigger()) { + /* use value-boundary for on/off events */ + if (_value>25000) { + event->SetValue(_value); + if (active) return; + event->Activate(ev_trigger); + active=true; } else { - holdlist.remove(this); - holding=false; + if (active) { + event->DeActivate(ev_trigger); + active=false; + } } + } else { + /* store value for possible later use in the activated event */ + event->SetValue(_value); + event->Activate(ev_trigger); + } + } + void DeActivate(bool ev_trigger) { + if (event->IsTrigger()) { + if (!active) return; + active=false; + if (flags & BFLG_Hold) { + if (!holding) { + holdlist.push_back(this); + holding=true; + return; + } else { + holdlist.remove(this); + holding=false; + } + } + event->DeActivate(ev_trigger); + } else { + /* store value for possible later use in the activated event */ + event->SetValue(0); + event->DeActivate(ev_trigger); } - event->DeActivate(); } virtual void ConfigName(char * buf)=0; virtual void BindName(char * buf)=0; @@ -187,7 +268,7 @@ void CEvent::AddBind(CBind * bind) { } void CEvent::DeActivateAll(void) { for (CBindList_it bit=bindlist.begin();bit!=bindlist.end();bit++) { - (*bit)->DeActivate(); + (*bit)->DeActivate(true); } } @@ -198,8 +279,8 @@ public: CBindGroup() { bindgroups.push_back(this); } - void ActivateBindList(CBindList * list,Bits value); - void DeactivateBindList(CBindList * list); + void ActivateBindList(CBindList * list,Bits value,bool ev_trigger); + void DeactivateBindList(CBindList * list,bool ev_trigger); virtual CBind * CreateConfigBind(char *&buf)=0; virtual CBind * CreateEventBind(SDL_Event * event)=0; @@ -411,8 +492,8 @@ public: Bitu key=GetKeyCode(event->key.keysym); // LOG_MSG("key type %i is %x [%x %x]",event->type,key,event->key.keysym.sym,event->key.keysym.scancode); assert(Bitu(event->key.keysym.sym)type==SDL_KEYDOWN) ActivateBindList(&lists[key],0x7fff); - else DeactivateBindList(&lists[key]); + if (event->type==SDL_KEYDOWN) ActivateBindList(&lists[key],0x7fff,true); + else DeactivateBindList(&lists[key],true); return 0; } CBind * CreateKeyBind(SDLKey _key) { @@ -432,6 +513,13 @@ protected: Bitu keys; }; +#define MAX_VJOY_BUTTONS 8 + +struct { + bool button_pressed[MAX_VJOY_BUTTONS]; + Bit16s axis_pos[8]; + bool hat_pressed[16]; +} virtual_joysticks[2]; class CJAxisBind; class CJButtonBind; @@ -475,46 +563,77 @@ protected: class CJHatBind : public CBind { public: - CJHatBind(CBindList * _list,CBindGroup * _group,Bitu _hat) : CBind(_list) { + CJHatBind(CBindList * _list,CBindGroup * _group,Bitu _hat,Bit8u _dir) : CBind(_list) { group = _group; - hat=_hat; + hat = _hat; + dir = _dir; + /* allow only one hat position */ + if (dir&SDL_HAT_UP) dir=SDL_HAT_UP; + else if (dir&SDL_HAT_RIGHT) dir=SDL_HAT_RIGHT; + else if (dir&SDL_HAT_DOWN) dir=SDL_HAT_DOWN; + else if (dir&SDL_HAT_LEFT) dir=SDL_HAT_LEFT; + else E_Exit("MAPPER:JOYSTICK:Invalid hat position"); } void ConfigName(char * buf) { - sprintf(buf,"%s hat %d",group->ConfigStart(),hat); + sprintf(buf,"%s hat %d %d",group->ConfigStart(),hat,dir); } void BindName(char * buf) { - sprintf(buf,"%s hat %d",group->BindStart(),hat); + sprintf(buf,"%s Hat %d %s",group->BindStart(),hat,(dir==SDL_HAT_UP)?"up": + ((dir==SDL_HAT_RIGHT)?"right": + ((dir==SDL_HAT_DOWN)?"down":"left"))); } protected: CBindGroup * group; Bitu hat; - Bitu mask; + Bit8u dir; }; static bool autofire=false; class CStickBindGroup : public CBindGroup { public: - CStickBindGroup(Bitu _stick) : CBindGroup (){ + CStickBindGroup(Bitu _stick,bool _dummy=false) : CBindGroup (){ stick=_stick; sprintf(configname,"stick_%d",stick); - sdl_joystick=SDL_JoystickOpen(stick); - assert(sdl_joystick); + is_dummy=_dummy; + if (_dummy) { + sdl_joystick=NULL; + axes=0; buttons=0; hats=0; + return; + } + + // initialize emulated joystick state + emulated_axes=2; + emulated_buttons=2; + pos_axis_lists=new CBindList[4]; + neg_axis_lists=new CBindList[4]; + button_lists=new CBindList[6]; + hat_lists=new CBindList[4]; + Bitu i; + for (i=0; i<16; i++) { + button_autofire[i]=0; + old_button_state[i]=0; + old_hat_state[i]=0; + } + for (i=0; i<4; i++) { + old_pos_axis_state[i]=false; + old_neg_axis_state[i]=false; + } + + //if the first stick is set, we must be the second +// emustick=JOYSTICK_IsEnabled(0); + emustick=stick; + JOYSTICK_Enable(emustick,true); + + sdl_joystick=SDL_JoystickOpen(_stick); + if (sdl_joystick==NULL) { + axes=0; buttons=0; hats=0; + return; + } axes=SDL_JoystickNumAxes(sdl_joystick); buttons=SDL_JoystickNumButtons(sdl_joystick); hats=SDL_JoystickNumHats(sdl_joystick); - pos_axis_lists=new CBindList[axes]; - neg_axis_lists=new CBindList[axes]; - button_lists=new CBindList[buttons]; - hat_lists=new CBindList[hats]; - emulated_buttons = 2; - for (Bitu i=0; itype==SDL_JOYAXISMOTION) { if (event->jaxis.which!=stick) return 0; +#if defined (REDUCE_JOYSTICK_POLLING) + if (event->jaxis.axis>=emulated_axes) return 0; +#endif if (abs(event->jaxis.value)<25000) return 0; return CreateAxisBind(event->jaxis.axis,event->jaxis.value>0); } else if (event->type==SDL_JOYBUTTONDOWN) { - if (event->jaxis.which!=stick) return 0; + if (event->button.which!=stick) return 0; +#if defined (REDUCE_JOYSTICK_POLLING) + return CreateButtonBind(event->jbutton.button%emulated_buttons); +#else return CreateButtonBind(event->jbutton.button); +#endif + } else if (event->type==SDL_JOYHATMOTION) { + if (event->jhat.which!=stick) return 0; + if (event->jhat.value==0) return 0; + if (event->jhat.value>(SDL_HAT_UP|SDL_HAT_RIGHT|SDL_HAT_DOWN|SDL_HAT_LEFT)) return 0; + return CreateHatBind(event->jhat.hat,event->jhat.value); } else return 0; } virtual bool CheckEvent(SDL_Event * event) { -#if OLD_JOYSTICK SDL_JoyAxisEvent * jaxis = NULL; SDL_JoyButtonEvent * jbutton = NULL; Bitu but = 0; @@ -576,21 +710,19 @@ public: } break; } -#endif return false; } virtual void UpdateJoystick() { - Sint16 axis_pos=SDL_JoystickGetAxis(sdl_joystick,0); - JOYSTICK_Move_X(emustick,(float)(axis_pos/32768.0)); - axis_pos=SDL_JoystickGetAxis(sdl_joystick,1); - JOYSTICK_Move_Y(emustick,(float)(axis_pos/32768.0)); + if (is_dummy) return; + /* query SDL joystick and activate bindings */ + ActivateJoystickBoundEvents(); bool button_pressed[16]; Bitu i; for (i=0; i<16; i++) button_pressed[i]=false; - for (i=0; i0) ActivateBindList(&pos_axis_lists[i],caxis_pos,false); + else if (caxis_pos<0) { + if (caxis_pos!=-32768) caxis_pos=(Sint16)abs(caxis_pos); + else caxis_pos=32767; + ActivateBindList(&neg_axis_lists[i],caxis_pos,false); + } + } + + for (i=0; i> 1,(i & 1),(++button_autofire[i])&1); + JOYSTICK_Button(i>>1,i&1,(++button_autofire[i])&1); else - JOYSTICK_Button(i >> 1,(i & 1),button_pressed[i]); + JOYSTICK_Button(i>>1,i&1,button_pressed[i]); } + + JOYSTICK_Move_X(0,((float)virtual_joysticks[0].axis_pos[0])/32768.0f); + JOYSTICK_Move_Y(0,((float)virtual_joysticks[0].axis_pos[1])/32768.0f); + JOYSTICK_Move_X(1,((float)virtual_joysticks[0].axis_pos[2])/32768.0f); + JOYSTICK_Move_Y(1,((float)virtual_joysticks[0].axis_pos[3])/32768.0f); } }; class CFCSBindGroup : public CStickBindGroup { public: CFCSBindGroup(Bitu _stick) : CStickBindGroup (_stick){ - emulated_buttons = 4; + emulated_axes=4; + emulated_buttons=4; old_hat_position=0; - for (Bitu i=0; i> 1,(i & 1),(++button_autofire[i])&1); + JOYSTICK_Button(i>>1,i&1,(++button_autofire[i])&1); else - JOYSTICK_Button(i >> 1,(i & 1),button_pressed[i]); + JOYSTICK_Button(i>>1,i&1,button_pressed[i]); + } + + JOYSTICK_Move_X(0,((float)virtual_joysticks[0].axis_pos[0])/32768.0f); + JOYSTICK_Move_Y(0,((float)virtual_joysticks[0].axis_pos[1])/32768.0f); + JOYSTICK_Move_X(1,((float)virtual_joysticks[0].axis_pos[2])/32768.0f); + + Uint8 hat_pos=0; + if (virtual_joysticks[0].hat_pressed[0]) hat_pos|=SDL_HAT_UP; + else if (virtual_joysticks[0].hat_pressed[2]) hat_pos|=SDL_HAT_DOWN; + if (virtual_joysticks[0].hat_pressed[3]) hat_pos|=SDL_HAT_LEFT; + else if (virtual_joysticks[0].hat_pressed[1]) hat_pos|=SDL_HAT_RIGHT; + + if (hat_pos!=old_hat_position) { + DecodeHatPosition(hat_pos); + old_hat_position=hat_pos; } } @@ -828,16 +1033,13 @@ private: class CCHBindGroup : public CStickBindGroup { public: CCHBindGroup(Bitu _stick) : CStickBindGroup (_stick){ - emulated_buttons = 6; -#if OLD_JOYSTICK + emulated_axes=4; + emulated_buttons=6; JOYSTICK_Enable(1,true); button_state=0; -#endif } - bool CheckEvent(SDL_Event * event) { -#if OLD_JOYSTICK SDL_JoyAxisEvent * jaxis = NULL; SDL_JoyButtonEvent * jbutton = NULL; SDL_JoyHatEvent * jhat = NULL; @@ -874,7 +1076,7 @@ public: jbutton = &event->jbutton; but = jbutton->button % emulated_buttons; if (jbutton->which == stick) - button_state|=button_magic[but]; + button_state|=button_magic[but]; break; case SDL_JOYBUTTONUP: jbutton = &event->jbutton; @@ -888,11 +1090,10 @@ public: Bit16u j; j=button_state; for(i=0;i<16;i++) if (j & 1) break; else j>>=1; - JOYSTICK_Button(0,0,i&0x01); - JOYSTICK_Button(0,1,i>>1&0x01); - JOYSTICK_Button(1,0,i>>2&0x01); - JOYSTICK_Button(1,1,i>>3&0x01); -#endif + JOYSTICK_Button(0,0,i&1); + JOYSTICK_Button(0,1,(i>>1)&1); + JOYSTICK_Button(1,0,(i>>2)&1); + JOYSTICK_Button(1,1,(i>>3)&1); return false; } @@ -900,40 +1101,44 @@ public: static unsigned const button_priority[6]={7,11,13,14,5,6}; static unsigned const hat_priority[2][4]={{0,1,2,3},{8,9,10,12}}; - Sint16 axis_pos=SDL_JoystickGetAxis(sdl_joystick,0); - JOYSTICK_Move_X(0,(float)(axis_pos/32768.0)); - axis_pos=SDL_JoystickGetAxis(sdl_joystick,1); - JOYSTICK_Move_Y(0,(float)(axis_pos/32768.0)); + /* query SDL joystick and activate bindings */ + ActivateJoystickBoundEvents(); - axis_pos=SDL_JoystickGetAxis(sdl_joystick,2); - JOYSTICK_Move_X(1,(float)(axis_pos/32768.0)); - axis_pos=SDL_JoystickGetAxis(sdl_joystick,3); - JOYSTICK_Move_Y(1,(float)(axis_pos/32768.0)); + JOYSTICK_Move_X(0,((float)virtual_joysticks[0].axis_pos[0])/32768.0f); + JOYSTICK_Move_Y(0,((float)virtual_joysticks[0].axis_pos[1])/32768.0f); + JOYSTICK_Move_X(1,((float)virtual_joysticks[0].axis_pos[2])/32768.0f); + JOYSTICK_Move_Y(1,((float)virtual_joysticks[0].axis_pos[3])/32768.0f); Bitu bt_state=15; Bitu i; for (i=0; i<(hats<2?hats:2); i++) { - Uint8 hat_position=SDL_JoystickGetHat(sdl_joystick,i); - if (hat_position & SDL_HAT_UP) + Uint8 hat_pos=0; + if (virtual_joysticks[0].hat_pressed[(i<<2)+0]) hat_pos|=SDL_HAT_UP; + else if (virtual_joysticks[0].hat_pressed[(i<<2)+2]) hat_pos|=SDL_HAT_DOWN; + if (virtual_joysticks[0].hat_pressed[(i<<2)+3]) hat_pos|=SDL_HAT_LEFT; + else if (virtual_joysticks[0].hat_pressed[(i<<2)+1]) hat_pos|=SDL_HAT_RIGHT; + + if (hat_pos & SDL_HAT_UP) if (bt_state>hat_priority[i][0]) bt_state=hat_priority[i][0]; - if (hat_position & SDL_HAT_DOWN) + if (hat_pos & SDL_HAT_DOWN) if (bt_state>hat_priority[i][1]) bt_state=hat_priority[i][1]; - if (hat_position & SDL_HAT_RIGHT) + if (hat_pos & SDL_HAT_RIGHT) if (bt_state>hat_priority[i][2]) bt_state=hat_priority[i][2]; - if (hat_position & SDL_HAT_LEFT) + if (hat_pos & SDL_HAT_LEFT) if (bt_state>hat_priority[i][3]) bt_state=hat_priority[i][3]; } bool button_pressed[6]; for (i=0; i<6; i++) button_pressed[i]=false; - for (i=0; ibutton_priority[i]) bt_state=button_priority[i]; + if ((button_pressed[i]) && (bt_state>button_priority[i])) + bt_state=button_priority[i]; } if (bt_state>15) bt_state=15; @@ -958,13 +1163,13 @@ static struct { bool addbind; Bitu mods; struct { - Bitu num; + Bitu num_groups,num; CStickBindGroup * stick[MAXSTICKS]; } sticks; const char * filename; } mapper; -void CBindGroup::ActivateBindList(CBindList * list,Bits value) { +void CBindGroup::ActivateBindList(CBindList * list,Bits value,bool ev_trigger) { Bitu validmod=0; CBindList_it it; for (it=list->begin();it!=list->end();it++) { @@ -974,14 +1179,14 @@ void CBindGroup::ActivateBindList(CBindList * list,Bits value) { } for (it=list->begin();it!=list->end();it++) { /*BUG:CRASH if keymapper key is removed*/ - if (validmod==(*it)->mods) (*it)->Activate(value); + if (validmod==(*it)->mods) (*it)->Activate(value,ev_trigger); } } -void CBindGroup::DeactivateBindList(CBindList * list) { +void CBindGroup::DeactivateBindList(CBindList * list,bool ev_trigger) { CBindList_it it; for (it=list->begin();it!=list->end();it++) { - (*it)->DeActivate(); + (*it)->DeActivate(ev_trigger); } } @@ -1182,9 +1387,9 @@ protected: BC_Types type; }; -class CKeyEvent : public CEvent { +class CKeyEvent : public CTriggeredEvent { public: - CKeyEvent(char const * const _entry,KBD_KEYS _key) : CEvent(_entry) { + CKeyEvent(char const * const _entry,KBD_KEYS _key) : CTriggeredEvent(_entry) { key=_key; } void Active(bool yesno) { @@ -1193,34 +1398,67 @@ public: KBD_KEYS key; }; -class CJAxisEvent : public CEvent { +class CJAxisEvent : public CContinuousEvent { public: - CJAxisEvent(char const * const _entry,Bitu _stick,bool _yaxis,bool _positive) : CEvent(_entry) { + CJAxisEvent(char const * const _entry,Bitu _stick,Bitu _axis,bool _positive,CJAxisEvent * _opposite_axis) : CContinuousEvent(_entry) { stick=_stick; - yaxis=_yaxis; + axis=_axis; positive=_positive; + opposite_axis=_opposite_axis; + if (_opposite_axis) { + _opposite_axis->SetOppositeAxis(this); + } } - void Active(bool /*yesno*/) { - }; - Bitu stick; - bool yaxis,positive; + void Active(bool /*moved*/) { + virtual_joysticks[stick].axis_pos[axis]=(Bit16s)(GetValue()*(positive?1:-1)); + } + virtual Bitu GetActivityCount(void) { + return activity|opposite_axis->activity; + } + virtual void RepostActivity(void) { + /* caring for joystick movement into the opposite direction */ + opposite_axis->Active(true); + } +protected: + void SetOppositeAxis(CJAxisEvent * _opposite_axis) { + opposite_axis=_opposite_axis; + } + Bitu stick,axis; + bool positive; + CJAxisEvent * opposite_axis; }; -class CJButtonEvent : public CEvent { +class CJButtonEvent : public CTriggeredEvent { public: - CJButtonEvent(char const * const _entry,Bitu _stick,Bitu _button) : CEvent(_entry) { + CJButtonEvent(char const * const _entry,Bitu _stick,Bitu _button) : CTriggeredEvent(_entry) { stick=_stick; button=_button; } - void Active(bool /*yesno*/) { - }; + void Active(bool pressed) { + virtual_joysticks[stick].button_pressed[button]=pressed; + } +protected: Bitu stick,button; }; - -class CModEvent : public CEvent { +class CJHatEvent : public CTriggeredEvent { public: - CModEvent(char const * const _entry,Bitu _wmod) : CEvent(_entry) { + CJHatEvent(char const * const _entry,Bitu _stick,Bitu _hat,Bitu _dir) : CTriggeredEvent(_entry) { + stick=_stick; + hat=_hat; + dir=_dir; + } + void Active(bool pressed) { + virtual_joysticks[stick].hat_pressed[(hat<<2)+dir]=pressed; + } +protected: + Bitu stick,hat,dir; +}; + + +class CModEvent : public CTriggeredEvent { +public: + CModEvent(char const * const _entry,Bitu _wmod) : CTriggeredEvent(_entry) { wmod=_wmod; } void Active(bool yesno) { @@ -1231,9 +1469,9 @@ protected: Bitu wmod; }; -class CHandlerEvent : public CEvent { +class CHandlerEvent : public CTriggeredEvent { public: - CHandlerEvent(char const * const _entry,MAPPER_Handler * _handler,MapKeys _key,Bitu _mod,char const * const _buttonname) : CEvent(_entry) { + CHandlerEvent(char const * const _entry,MAPPER_Handler * _handler,MapKeys _key,Bitu _mod,char const * const _buttonname) : CTriggeredEvent(_entry) { handler=_handler; defmod=_mod; defkey=_key; @@ -1358,21 +1596,38 @@ static void AddKeyButtonEvent(Bitu x,Bitu y,Bitu dx,Bitu dy,char const * const t CKeyEvent * event=new CKeyEvent(buf,key); new CEventButton(x,y,dx,dy,title,event); } -#if 0 //unused code -static void AddJAxisButton(Bitu x,Bitu y,Bitu dx,Bitu dy,char const * const title,Bitu stick,bool yaxis,bool positive) { + +static CJAxisEvent * AddJAxisButton(Bitu x,Bitu y,Bitu dx,Bitu dy,char const * const title,Bitu stick,Bitu axis,bool positive,CJAxisEvent * opposite_axis) { char buf[64]; - sprintf(buf,"jaxis_%d%s%s",stick,yaxis ? "Y":"X",positive ? "+" : "-"); - CJAxisEvent * event=new CJAxisEvent(buf,stick,yaxis,positive); + sprintf(buf,"jaxis_%d_%d%s",stick,axis,positive ? "+" : "-"); + CJAxisEvent * event=new CJAxisEvent(buf,stick,axis,positive,opposite_axis); new CEventButton(x,y,dx,dy,title,event); + return event; +} +static CJAxisEvent * AddJAxisButton_hidden(Bitu stick,Bitu axis,bool positive,CJAxisEvent * opposite_axis) { + char buf[64]; + sprintf(buf,"jaxis_%d_%d%s",stick,axis,positive ? "+" : "-"); + return new CJAxisEvent(buf,stick,axis,positive,opposite_axis); } -static void AddJButtonButton(Bitu x,Bitu y,Bitu dx,Bitu dy,char const * const title,Bitu _stick,Bitu _button) { +static void AddJButtonButton(Bitu x,Bitu y,Bitu dx,Bitu dy,char const * const title,Bitu stick,Bitu button) { char buf[64]; - sprintf(buf,"jbutton_%d_%d",_stick,_button); - CJButtonEvent * event=new CJButtonEvent(buf,_stick,_button); + sprintf(buf,"jbutton_%d_%d",stick,button); + CJButtonEvent * event=new CJButtonEvent(buf,stick,button); + new CEventButton(x,y,dx,dy,title,event); +} +static void AddJButtonButton_hidden(Bitu stick,Bitu button) { + char buf[64]; + sprintf(buf,"jbutton_%d_%d",stick,button); + new CJButtonEvent(buf,stick,button); +} + +static void AddJHatButton(Bitu x,Bitu y,Bitu dx,Bitu dy,char const * const title,Bitu _stick,Bitu _hat,Bitu _dir) { + char buf[64]; + sprintf(buf,"jhat_%d_%d_%d",_stick,_hat,_dir); + CJHatEvent * event=new CJHatEvent(buf,_stick,_hat,_dir); new CEventButton(x,y,dx,dy,title,event); } -#endif static void AddModButton(Bitu x,Bitu y,Bitu dx,Bitu dy,char const * const title,Bitu _mod) { char buf[64]; @@ -1491,28 +1746,76 @@ static void CreateLayout(void) { AddKeyButtonEvent(PX(4),PY(11),BW*2,BH,"0","kp_0",KBD_kp0); AddKeyButtonEvent(PX(6),PY(11),BW,BH,".","kp_period",KBD_kpperiod); -#if (!OLD_JOYSTICK) /* Joystick Buttons/Texts */ - AddJButtonButton(PX(17),PY(0),BW,BH,"1" ,0,0); - AddJAxisButton (PX(18),PY(0),BW,BH,"Y-",0,true,false); - AddJButtonButton(PX(19),PY(0),BW,BH,"2" ,0,1); - AddJAxisButton (PX(17),PY(1),BW,BH,"X-",0,false,false); - AddJAxisButton (PX(18),PY(1),BW,BH,"Y+",0,true,true); - AddJAxisButton (PX(19),PY(1),BW,BH,"X+",0,false,true); + /* Buttons 1+2 of 1st Joystick */ + AddJButtonButton(PX(18),PY(0),BW,BH,"1" ,0,0); + AddJButtonButton(PX(20),PY(0),BW,BH,"2" ,0,1); + /* Axes 1+2 (X+Y) of 1st Joystick */ + CJAxisEvent * cjaxis=AddJAxisButton(PX(19),PY(0),BW,BH,"Y-",0,1,false,NULL); + AddJAxisButton (PX(19),PY(1),BW,BH,"Y+",0,1,true,cjaxis); + cjaxis=AddJAxisButton (PX(18),PY(1),BW,BH,"X-",0,0,false,NULL); + AddJAxisButton (PX(20),PY(1),BW,BH,"X+",0,0,true,cjaxis); + + if (joytype==JOY_2AXIS) { + /* Buttons 1+2 of 2nd Joystick */ + AddJButtonButton(PX(18),PY(3),BW,BH,"1" ,1,0); + AddJButtonButton(PX(20),PY(3),BW,BH,"2" ,1,1); + /* Buttons 3+4 of 1st Joystick, not accessible */ + AddJButtonButton_hidden(0,2); + AddJButtonButton_hidden(0,3); + + /* Axes 1+2 (X+Y) of 2nd Joystick */ + cjaxis= AddJAxisButton(PX(18),PY(4),BW,BH,"X-",1,0,false,NULL); + AddJAxisButton(PX(20),PY(4),BW,BH,"X+",1,0,true,cjaxis); + cjaxis= AddJAxisButton(PX(19),PY(3),BW,BH,"Y-",1,1,false,NULL); + AddJAxisButton(PX(19),PY(4),BW,BH,"Y+",1,1,true,cjaxis); + /* Axes 3+4 (X+Y) of 1st Joystick, not accessible */ + cjaxis= AddJAxisButton_hidden(0,2,false,NULL); + AddJAxisButton_hidden(0,2,true,cjaxis); + cjaxis= AddJAxisButton_hidden(0,3,false,NULL); + AddJAxisButton_hidden(0,3,true,cjaxis); + } else { + /* Buttons 3+4 of 1st Joystick */ + AddJButtonButton(PX(18),PY(3),BW,BH,"3" ,0,2); + AddJButtonButton(PX(20),PY(3),BW,BH,"4" ,0,3); + /* Buttons 1+2 of 2nd Joystick, not accessible */ + AddJButtonButton_hidden(1,0); + AddJButtonButton_hidden(1,1); + + /* Axes 3+4 (X+Y) of 1st Joystick */ + cjaxis= AddJAxisButton(PX(18),PY(4),BW,BH,"X-",0,2,false,NULL); + AddJAxisButton(PX(20),PY(4),BW,BH,"X+",0,2,true,cjaxis); + cjaxis= AddJAxisButton(PX(19),PY(3),BW,BH,"Y-",0,3,false,NULL); + AddJAxisButton(PX(19),PY(4),BW,BH,"Y+",0,3,true,cjaxis); + /* Axes 1+2 (X+Y) of 2nd Joystick , not accessible*/ + cjaxis= AddJAxisButton_hidden(1,0,false,NULL); + AddJAxisButton_hidden(1,0,true,cjaxis); + cjaxis= AddJAxisButton_hidden(1,1,false,NULL); + AddJAxisButton_hidden(1,1,true,cjaxis); + } + + if (joytype==JOY_CH) { + /* Buttons 5+6 of 1st Joystick */ + AddJButtonButton(PX(18),PY(6),BW,BH,"5" ,0,4); + AddJButtonButton(PX(20),PY(6),BW,BH,"6" ,0,5); + } else { + /* Buttons 5+6 of 1st Joystick, not accessible */ + AddJButtonButton_hidden(0,4); + AddJButtonButton_hidden(0,5); + } + + /* Hat directions up, left, down, right */ + AddJHatButton(PX(19),PY(6),BW,BH,"UP",0,0,0); + AddJHatButton(PX(18),PY(7),BW,BH,"LFT",0,0,3); + AddJHatButton(PX(19),PY(7),BW,BH,"DWN",0,0,2); + AddJHatButton(PX(20),PY(7),BW,BH,"RGT",0,0,1); - AddJButtonButton(PX(17),PY(3),BW,BH,"1" ,1,0); - AddJAxisButton (PX(18),PY(3),BW,BH,"Y-",1,true,false); - AddJButtonButton(PX(19),PY(3),BW,BH,"2" ,1,1); - AddJAxisButton (PX(17),PY(4),BW,BH,"X-",1,false,false); - AddJAxisButton (PX(18),PY(4),BW,BH,"Y+",1,true,true); - AddJAxisButton (PX(19),PY(4),BW,BH,"X+",1,false,true); -#endif /* The modifier buttons */ AddModButton(PX(0),PY(13),50,20,"Mod1",1); AddModButton(PX(2),PY(13),50,20,"Mod2",2); AddModButton(PX(4),PY(13),50,20,"Mod3",3); /* Create Handler buttons */ - Bitu xpos=3;Bitu ypos=7; + Bitu xpos=3;Bitu ypos=10; for (CHandlerEventVector_it hit=handlergroup.begin();hit!=handlergroup.end();hit++) { new CEventButton(PX(xpos*3),PY(ypos),BW*3,BH,(*hit)->ButtonName(),(*hit)); xpos++; @@ -1522,9 +1825,8 @@ static void CreateLayout(void) { } /* Create some text buttons */ new CTextButton(PX(6),00,124,20,"Keyboard Layout"); -#if (!OLD_JOYSTICK) - new CTextButton(PX(16),00,124,20,"Joystick Layout"); -#endif + new CTextButton(PX(17),00,124,20,"Joystick Layout"); + bind_but.action=new CCaptionButton(200,330,0,0); bind_but.event_title=new CCaptionButton(0,350,0,0); @@ -1644,11 +1946,38 @@ static void CreateDefaultBinds(void) { (*hit)->MakeDefaultBind(buffer); CreateStringBind(buffer); } - /* JOYSTICK */ - if (SDL_NumJoysticks()>0) { -// default mapping - } - + + /* joystick1, buttons 1-6 */ + sprintf(buffer,"jbutton_0_0 \"stick_0 button 0\" ");CreateStringBind(buffer); + sprintf(buffer,"jbutton_0_1 \"stick_0 button 1\" ");CreateStringBind(buffer); + sprintf(buffer,"jbutton_0_2 \"stick_0 button 2\" ");CreateStringBind(buffer); + sprintf(buffer,"jbutton_0_3 \"stick_0 button 3\" ");CreateStringBind(buffer); + sprintf(buffer,"jbutton_0_4 \"stick_0 button 4\" ");CreateStringBind(buffer); + sprintf(buffer,"jbutton_0_5 \"stick_0 button 5\" ");CreateStringBind(buffer); + /* joystick2, buttons 1-2 */ + sprintf(buffer,"jbutton_1_0 \"stick_1 button 0\" ");CreateStringBind(buffer); + sprintf(buffer,"jbutton_1_1 \"stick_1 button 1\" ");CreateStringBind(buffer); + + /* joystick1, axes 1-4 */ + sprintf(buffer,"jaxis_0_0- \"stick_0 axis 0 0\" ");CreateStringBind(buffer); + sprintf(buffer,"jaxis_0_0+ \"stick_0 axis 0 1\" ");CreateStringBind(buffer); + sprintf(buffer,"jaxis_0_1- \"stick_0 axis 1 0\" ");CreateStringBind(buffer); + sprintf(buffer,"jaxis_0_1+ \"stick_0 axis 1 1\" ");CreateStringBind(buffer); + sprintf(buffer,"jaxis_0_2- \"stick_0 axis 2 0\" ");CreateStringBind(buffer); + sprintf(buffer,"jaxis_0_2+ \"stick_0 axis 2 1\" ");CreateStringBind(buffer); + sprintf(buffer,"jaxis_0_3- \"stick_0 axis 3 0\" ");CreateStringBind(buffer); + sprintf(buffer,"jaxis_0_3+ \"stick_0 axis 3 1\" ");CreateStringBind(buffer); + /* joystick2, axes 1-2 */ + sprintf(buffer,"jaxis_1_0- \"stick_1 axis 0 0\" ");CreateStringBind(buffer); + sprintf(buffer,"jaxis_1_0+ \"stick_1 axis 0 1\" ");CreateStringBind(buffer); + sprintf(buffer,"jaxis_1_1- \"stick_1 axis 1 0\" ");CreateStringBind(buffer); + sprintf(buffer,"jaxis_1_1+ \"stick_1 axis 1 1\" ");CreateStringBind(buffer); + + /* joystick1, hat */ + sprintf(buffer,"jhat_0_0_0 \"stick_0 hat 0 1\" ");CreateStringBind(buffer); + sprintf(buffer,"jhat_0_0_1 \"stick_0 hat 0 2\" ");CreateStringBind(buffer); + sprintf(buffer,"jhat_0_0_2 \"stick_0 hat 0 4\" ");CreateStringBind(buffer); + sprintf(buffer,"jhat_0_0_3 \"stick_0 hat 0 8\" ");CreateStringBind(buffer); } void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char const * const eventname,char const * const buttonname) { @@ -1733,34 +2062,43 @@ static void CreateBindGroups(void) { bindgroups.clear(); new CKeyBindGroup(SDLK_LAST); mapper.sticks.num=0; + mapper.sticks.num_groups=0; if (joytype != JOY_NONE) { - Bitu numsticks=SDL_NumJoysticks(); + mapper.sticks.num=SDL_NumJoysticks(); #if defined (REDUCE_JOYSTICK_POLLING) // direct access to the SDL joystick, thus removed from the event handling - if (numsticks) SDL_JoystickEventState(SDL_DISABLE); + if (mapper.sticks.num) SDL_JoystickEventState(SDL_DISABLE); #else // enable joystick event handling if (numsticks) SDL_JoystickEventState(SDL_ENABLE); -#endif -#if OLD_JOYSTICK else return; #endif Bit8u joyno=0; + if (joytype==JOY_AUTO) { + if (mapper.sticks.num>1) joytype=JOY_2AXIS; + else if (mapper.sticks.num) joytype=JOY_4AXIS; + else joytype=JOY_NONE; + } switch (joytype) { + case JOY_NONE: + break; case JOY_4AXIS: - mapper.sticks.stick[mapper.sticks.num++]=new C4AxisBindGroup(joyno); + mapper.sticks.stick[mapper.sticks.num_groups++]=new C4AxisBindGroup(joyno); + new CStickBindGroup(joyno+1U); break; case JOY_FCS: - mapper.sticks.stick[mapper.sticks.num++]=new CFCSBindGroup(joyno); + mapper.sticks.stick[mapper.sticks.num_groups++]=new CFCSBindGroup(joyno); + new CStickBindGroup(joyno+1U); break; case JOY_CH: - mapper.sticks.stick[mapper.sticks.num++]=new CCHBindGroup(joyno); + mapper.sticks.stick[mapper.sticks.num_groups++]=new CCHBindGroup(joyno); + new CStickBindGroup(joyno+1U); break; case JOY_2AXIS: default: - mapper.sticks.stick[mapper.sticks.num++]=new CStickBindGroup(joyno); - if((joyno+1U) < numsticks) - mapper.sticks.stick[mapper.sticks.num++]=new CStickBindGroup(joyno+1U); + mapper.sticks.stick[mapper.sticks.num_groups++]=new CStickBindGroup(joyno); + if((joyno+1U) < mapper.sticks.num) + mapper.sticks.stick[mapper.sticks.num_groups++]=new CStickBindGroup(joyno+1U); break; } } @@ -1768,7 +2106,7 @@ static void CreateBindGroups(void) { #if defined (REDUCE_JOYSTICK_POLLING) void MAPPER_UpdateJoysticks(void) { - for (Bitu i=0; iUpdateJoystick(); } } @@ -1805,6 +2143,9 @@ void MAPPER_Run(bool pressed) { mapper.exit=false; mapper.redraw=true; SetActiveEvent(0); +#if defined (REDUCE_JOYSTICK_POLLING) + SDL_JoystickEventState(SDL_ENABLE); +#endif while (!mapper.exit) { if (mapper.redraw) { mapper.redraw=false; @@ -1813,6 +2154,9 @@ void MAPPER_Run(bool pressed) { BIND_MappingEvents(); SDL_Delay(1); } +#if defined (REDUCE_JOYSTICK_POLLING) + SDL_JoystickEventState(SDL_DISABLE); +#endif if(mousetoggle) GFX_CaptureMouse(); GFX_ResetScreen(); } @@ -1826,6 +2170,19 @@ void MAPPER_Init(void) { void MAPPER_StartUp(Section * sec) { Section_prop * section=static_cast(sec); mapper.sticks.num=0; + mapper.sticks.num_groups=0; + Bitu i; + for (i=0; i<16; i++) { + virtual_joysticks[0].button_pressed[i]=false; + virtual_joysticks[1].button_pressed[i]=false; + virtual_joysticks[0].hat_pressed[i]=false; + virtual_joysticks[1].hat_pressed[i]=false; + } + for (i=0; i<8; i++) { + virtual_joysticks[0].axis_pos[i]=0; + virtual_joysticks[0].axis_pos[i]=0; + } + usescancodes=false; if (section->Get_bool("usescancodes")) { @@ -1893,7 +2250,7 @@ void MAPPER_StartUp(Section * sec) { for (i=0; i0) { - static int poll_delay=0; - int time=SDL_GetTicks(); - if (time-poll_delay>20) { - poll_delay=time; - SDL_JoystickUpdate(); - MAPPER_UpdateJoysticks(); - } + static int poll_delay=0; + int time=SDL_GetTicks(); + if (time-poll_delay>20) { + poll_delay=time; + if (sdl.num_joysticks>0) SDL_JoystickUpdate(); + MAPPER_UpdateJoysticks(); } #endif while (SDL_PollEvent(&event)) { diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index 4fece5ed..ef6b8bec 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: joystick.cpp,v 1.15 2007-01-08 19:45:40 qbix79 Exp $ */ +/* $Id: joystick.cpp,v 1.16 2007-01-10 15:01:15 c2woody Exp $ */ #include #include "dosbox.h" @@ -146,11 +146,13 @@ public: Section_prop * section=static_cast(configuration); const char * type=section->Get_string("joysticktype"); if (!strcasecmp(type,"none")) joytype=JOY_NONE; + else if (!strcasecmp(type,"false")) joytype=JOY_NONE; + else if (!strcasecmp(type,"auto")) joytype=JOY_AUTO; else if (!strcasecmp(type,"2axis")) joytype=JOY_2AXIS; else if (!strcasecmp(type,"4axis")) joytype=JOY_4AXIS; else if (!strcasecmp(type,"fcs")) joytype=JOY_FCS; else if (!strcasecmp(type,"ch")) joytype=JOY_CH; - else joytype=JOY_2AXIS; + else joytype=JOY_AUTO; ReadHandler.Install(0x201,read_p201,IO_MB); WriteHandler.Install(0x201,write_p201,IO_MB); stick[0].enabled=false; From 6e5b843ebc2cfd5620a48040571809fde296a3d1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Jan 2007 15:07:12 +0000 Subject: [PATCH 2663/4131] Updated Icon. Thanks Chaosfish Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2748 --- src/dosbox.ico | Bin 114926 -> 83966 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/dosbox.ico b/src/dosbox.ico index 1602b2a621562076d0d572cc12f73a211a79ac32..7467ae5e7647d7f19a4150cde5c6295892c281a3 100644 GIT binary patch literal 83966 zcmd?Sk6+Yv*7yHmWIeuh@0#qDRu!#^*8AlU@(9A)$SZ&oT(~8A5 zq?$5AV@r&Fkf{p<741sb&bmfdm$kIEV{{qm)wi-_>|0kj-QHc<{XCzs`?~MP4 zWLCeRWO$!Z%*FR8p4Pp}tkw4@&SU45*}ra9*8lOSa((Sxis`!Bl*PaQgOa|WO)1{6 zLn(duBjx6;I~66ts$6&cN5%fm_sY~e{;K3}|5EWj(xoha;w2^a+9k^DfB#vD&MH-k zgBO+AzdNa1+c>0Lz5m~p`rUtIaxqH9gYC*Kk3O#yfAX_3W7Q@lyZ(?;XHV< zdEdV)3xC(4OfFoYWDR_#TwT?n%>L-2vV!?d-uYK$ay?)GNx`7l)Ksd$=&#YlKj+BWqQ@^%9_prW!V$^mBM$ zwNm(x|5B{02bH>~dz97B4Jx(IBexYzO2fW0N=6^NpINP#iXT>%?&wq|&HkN|ap+U{ z`=;XF_=w^P{+E*f!T(T7?tc$HH!IgR3@S?>e@VIg##SX~&47~kz-i^0%GFBZj(<_& zZ``Ha_J>!MlDnT!DtB~&o%{LBBT9TuxpL#^&r0$7KPqV*|Ef&6rBiX<@nCXSH;!1P4PYdXQlA2e^G9D;(}t{^Ny0Y;y21<#}cKXb5Kco;%z1O?hz#y z3|!anic+@iDdo=n0cGmoSIU)@k12WZbk4@d6eZ<)r4)SM*sxnkz3E{kqxO$VcHKec z>Pnx|`23%go9=#GS@&{4(dGU|$@!Q6R2DwGS6Tk#0VQSOvr6HLb;?y;|4?pj{)1wf zyI3jT_M~!E<&#R%4fiQ`ym(ltYkyUl{lG`cub)4xR6^6j-|thVHNCCm*RNBuYrE0+ zTNJfolTx(iUS-DWKPWlNnv^MPk0|b~?aGqJPbzc#=dmmQKOadAFTOYQ;(M1yTH4V6 z9_jMzy`iCW{>j%+x(w~Hp<%S)mvQOE2JNru@+xl{8g1a|FQ4QmFUl*I2A>{fM1G4r z(SFe$BG(w=)AGef`QWJBUAv?<1-XUX@4qh@xqD=a^0%Qhd80OO?N36BHr{(LZRowU zwD(>ddhbDF62eb%{y8lztu~DhMSgPEA)zlaztPbo?a5Huki5h_Wxm{5CiV*((wSyj z?a)wKT0^?rxFMZSHKg-xtmV?YChVyddU;v9gwQ{l#L%Abpphx>sMRjOhiaKt!)Owp zNgCBIz$b+wnX1f18+<^f!i;5F>5)gd!=+1KdZXNxH;Q<*pAZ`ij%wIX(*2{y;oxRz zwY5fv!^lr#t?-VYMkCMVAI#*pS{XuM+K|I3pWtmg@pkTw~4a2mNF zlVWc2E1zzttz}}`ue>qxw;`c`OUPA?M$bR2qf?OodpxRtbUKU%kHPD7It)B@IE6T_ zhD_6IYaRR(;R<)W9*@W1;4%&#`Tk`HZ4#p&clXYG*DknVAMm@3a@w%pqXmoz47 z+~yO)Yo^2xrp84h+&;`7d@l<%ug_xHNnXbX1UB>Bj_Bi;1 zKma?TPuI*5gu@5-r(#pc|sfjpNZ#P_ z9A-+06N#WQf_OozKs#MzjY5cSMPQO9D92PF`k+zfUJLh}Jv|b^5!%?;qz(u6CH5&c=@zQ1h8ozfOR4mc{4f-Wn42D)(1kiM_mm` z18c$!$p5{h^uT4kQ<99gj+kJuL8p^BISgvhq^br(t+$7X1WjHC>@yloK?mkT^jHLL zN_RjfI57mho*>dUf%aMh01B#lRrUD1ra&lQav-`|j|q~Poq!1#pqb!-$B2;97<>VZ0ZyN>7S;iLO%|f^(5`)ur@o-q;1Q09LW2?`^LM7D`AkkDRtmBW9?Y~U z*yHtLA>oSZb_PvOU&XDpqf?TfOZKIs|L-+;tk-{gF=^C$YkyBqz!6lvkc^?z2Lj=M z-r)7BDxx+H)jCZfj~8KZY3``Hk@^rAfpBaE#?#|9gkX^aNc5PTCZG3kfzGX(g2A31 zOtcsjc*tZ8J}@kl!$QFklNH**iqUvjL$uK3aE83ShK5>%?f`(iuBj!U7)lpYW)LDV z!vbs%@Z&SJLtNS^IzNQ!BP(XA>H~Vc$_@C0p~q9J_IRu-dPb9;Td|_a-ZKFG=?;%G z`21B%evM?#2Rbr%G5M^rDOK{$xR=nKkZgCR{7#oCE}V*&)R(BU+~AE5+-01ptyf?}7Q zo;(LP_4I%v?5YRrB38-dXRKIGifp2kdy9K6J;Ysy(U!)z(-1 zOxW}84HlinAB6t2Q6nbR^~|kFQ;fGJ>w{Lk4W6m;cHSLURZy$%?^lC8VtNb#2n&Wn zL5J9*kke~|?qDbo^z?WDhaf|&5ei`P=v9;IMKOFLW_*U`N0~M#hj612Ok-!f9_EP2 z>@gy|G&q5;a(XpWmFDFZXcd&Y4ctg$v8wX~VUgS!0D6Oh1uy*Ycziuh(57b=SmHn! zsR10l$tQICpx>km>OH~Y6~?5b=hh7LxGg$I(Ud7equ#I@uv&!ywQHKp;gBw<1_QdV zY7;IPgr{!3LFe`aVXf296Es0;j~BoPbzDEF*N5GCXs9g;Pz(lJn z918RpnHcbaBM21hn?5?^s1?L=F`-B>;Dbk4HKXHXNW};OCgg7PnY<>!LY#%?^V_4<1uW~yH((fNNve0(x!~A zSus+)?E0qST08Pj>T&l3^maq?n$aX9f66L{-! zpku@vI=#)M5;}RjVrN4kkf`c<{5n%0U^iO|j)X%doi%_1!Ahd(wZ5Rh0l#F@dwduI z1kN{#iVcMe25$%`ISeOp!-kWhZC=zcgd!GTO3@0{i#WnIzbzcLOz73HmFak#J*w(f zRhpW^OY_X{Uuju@4!e}vBZCAcm~z( zHQjncLy}?5fF*2o1gA376HNvyEBC!r`!*2j}%nMJ+g@cbd3ffi6IpptIQuRJUFP0|cBt ze3{8=)0hbpIxspyj8Nvt$tma-@Z;u+%>Bg+O3X9IgJ@WDb6_!@3&1$vvsv$jZ zbGr+AZB~31NHrLOo}ezEQ^%}9V~5gf75hIrr0Nak z5o3Q*@|yHf&vWk<>0E(UtE<4Gvs%nLYe9j&-)_?vI2?$&z=>DP3#mc9(+I=G%W2O; zA#RbEhq1NU_l8Zy6T9;K1-21Pj4t5xs3xy(EacX?Z9%vH6P?~|)0y2qLIpI{bI$89 zxb-H}In&9!0-HOpz>^m`=?&%OnT~i(I={=N^XtuF*Df{OYwv|3o4(g>c8A2V7P+qH~3dclDeM?3(Zg05gsR^VJh{ zhr)ip)r~S1=;4LQtW${^bzz-Nx7TbduoUfW_1Wy|-hp17+N$a-)=%=#d5>G4r>d~k zOHhG{2B!p!N8Cq_s5ZY&^@rSfV@KQpz4N3l5D1N#%@bye&OZ?z)0u+!GoWB@MKoYA zq!zdXCPEeXh|vgH`r*WwF6f#Fhl9jr;W5?4Y+Tl$!_+h8Uyk zCcTmPPw;PWxQ;kgvpHD&oOepvyEhbB&0(v#qM*WVafRIlz|3l$u!MWV7XO6Hud{?L z=71L~RG@}}ctDdADm+-|f`C4RV(V1h5u0nG)fDpT-TJ)&o$KV`JjR`Qx;(x06P->M zC!1H=q_3 zTh)qW)mCwd{&W^rz$2&@^%&lLE4s!f-8E3uYfdgUo9!bb7MrfuJJ#B3x4`)@ z-&Qjw22U7NO~_IWx&toNZE%P6E*F8LS3Ri@nkRIjlX@KbIivB_!>=;Fd^PW-&(6KX z{Ei%H)qR3l3i6E>$)eKZBb+&R&gi+#_v+z0zdTF;Y!C=s7bQTm~HEdx_HzKMqTl$NNT?G@n&;(o2a|1(D)aTyy zs7*Gj*-{*~1q`zOdoO9ofY&$cbm5V(Ix+t(Ei3lx0|h#l#Wqo_ zt7!H2;uywsHj~Mxv-OUtIwTz)3*%c=bqq7DS_23lVAu+9aYRBPomFr8M1}m9UVZ7d z+irXLw$FHcwZLsS>GYiRfDfEBEI5fPI2<|>`ZDjOFJF53<=f7ECht4<>Ph^s&L6-a zVph5C5!Eg3DX+(r7d)cZyTh)%?jUx5OrjKnS4Z&S)4N*3Bjy4>Hc}0ZjZBy)DzKNu zYbJ)K1XkFKRDUueO)j1ouz1sw1^*5;;L%x)s=dM){JALkhTkfAu)>KrMuCJ)$Z(f^?&0*^F6WVIK0d`-#8BhS4%B~5=r zQ@`7$su&N84Nq&qA0ph5BD+q1Qf~_M2fU^+9hW!Buwmcyjw6H(I&%PvY4Ty4U6xkW zqVwgw`qE3#^76|sf5y1~Hl%yo;XChiAHf)gd?yXC%6BqkIvmP7cMdk)FRbECyc-0( zn&oi3J@$hT}TbMLtbJAlhG6K=>ymskf9UrsI$5(<}fRhFnaIOqX`5` zKD|$0yvEQlC3%IdxVXvN)0AwtTI>dFTsrYzdJ;K^G%s=t_L{tYvnya-^X?R5@`@F^ z%=RJ}Sz)g*+lwb$7HF@q4@|V$EP;M=YuIKF2U_7TVQkOgo{*ksBZLR?`10~tgb~?! zPC7!W=T(4z{|`w1ej#5laNGT#z3O?@{fW)(KBAMafKEqThmJtByi49IA9?xJbLS2p z?#Uy%k}DEHc`%@Pgue!Y=YTa2ocnwA1-KepZI#OW)BxAt>vnyhn%|@!W*zPL*JRXv;cbx2m>f_?$qm zs=w{rOD}=xAGFahdjI_|zwz=*FP+Q#WUu)XwZKpORG7VRieHi)_In3--Q8KS45s^$+2AkJD>2_e|&ptd@bMf&Szo%Zlfc z(t|fNsRnE=x=oC(H~0XVK5TMZkLZYsLm^Y|Nk^-mKlyrmZ~~u(Yxn32SnoRw!N7!7 z*Kb~C)4%lUmv4Ob&_fSB`Orgm+;NAZ?El*XlP}Nv@{>E=R)2xsX4C6jgn{mJ&ilz3 zKlJ32Pd;>qay8|_7nV$(wBX#Up}n8z+&Z%)<%}R*PsHpb=C&1(Bw$(PP+J`)zt@DT z#Yp;OO>B~NRY(>PtWXG43`J`kqf>rPR;?CwVxY+EZ?X*NlZ$(;6(;8d`rpuCbn0EI zYUKr+%Uoo&Hx(uSydtT=^xO^4-LPiOtumg!_0eaZx%K%+Z@ucOtG>PJ(W@T4^_fSt zm!E&;(MO-T>d{A^fBsf^`sgzLysP-Ci;q74@WqE8e)!^Ld*5I{KeS(cHDuj0chcq8 zeS6u%7a5mb_VB}(UB;7#AO7RN{`HeLUWR%hfB*g${yBFt@B1&_aq;4#7oUIh;*ZkMxG^ z;UFs*Td=so?y?Nnt$Iff`u`sJK=N3QepPR=*XNRMG(f zt5?s8-m7z9s#UTwtbLq^186QGDC+M#%<4ilk)^|x$->?klvIzyc-s$BKM=`Zef0}} z``bNBCV#NyiYxBFAKQNJoaC>Z4teIh|Nb9-Xc$HKUtPWb#((~E$=#C<-E`9xKio#z z;hYmwCzte*0AP`T9Wb3F+tuSS;n+!7uv{b;=gB)s-bUY}dQBmp4!6h`!H~xW`9+q1 zI+9G}bVNU5F6wm^lb{N!4i*28{0YL{)?iOyqSx#%YMNl36V&zWT0v>#zlT<;_~q9~ z-Qt(u{y%<_SSPhEe~47qM5Zs?_`s3}=1yL8-4!=oA+P>lAB((g3iMyS|8Gm?-aUEJ z7T(7D(RJNfB_(fuv}56?Gyne3SNmUpNs~Xg?xrjFTDPvO z>iw!y%fFHF;kIw&?kiXFxKgI^q0Hu2+qW$)7n-i1RdGyrEQ%4t9o%(M3#*J00*Om>gUAwxhYTxR%y0$%aeWjgk zZ5?HugK%YIS!Y>U#~0uK^yZ8m3q|~pHEGfZmqY&*SN!yG<;T#Ul9JM$ni?Pdd3iigVuSdagwqM9Pd9|poO&<8C{eVv;`*ZAfeF7k zXmWWq{Es$}Blmd-u>!W@4P0Mz*T2#*(r;t5ocz8JH!mvm`_CkJ3O^yt2-jLwv=f10u5vHdsR1NDb4 zUvS+`H$m1-KfPI5UVi-Z)aa6u_|*9LlH=vEOMiS2`tP{GE!`_;s!^=|20@c>0(FpF0(DUw>7ya*xOImBH19KkA?gk z$QSt!$K)TYNm;k9?TfZA_UvhsN$u&Y>nQD9TiS_;21`2;e_LJW?%jjv#!OERG?KK^*+jHRG|)~qM**#Cg0B9}ux^nd*M=bxwW zmC~2BXU`W|@hRV@M8k>F?V3iMI{M8w-+i}y+qUghtE-mpLl-j=V`7GxHsS~WFhIk9 zk~3Yh#I^1TgBms$C0j=N$?8oct3p4O>VT*k~!9fR@=q&BvN!h9G?<0Q@fFWp0Dfzncqr1@k zNsAU-x8)N3*HwO0nV9);Vo6DNR#ta(W_j#m>kv~O!MBQg@WP|bmwn%LnB z`CZ4VV^aq^I_k;>%LWGrv3g}|moHzwQR6^rX4NyK0|UnW`$p{yrub)7MwilARp`SZg32x)00|J{&lmWK2T*K9WQx zb8tjAQqgO+7L8b3UWbPNQ8)Q^Vz3GpIJ*WaEEQ&om|^3$X$fLTYq%6pN&x>cG5K-X z*nre3Y;D=vvd*>4XmGG|-^x;yA$3n`$DY)-x>Udl`6;RBYF~Wj$CYm;%!pkI`I8nw z*_JI^ZrXwgobl0{AfO~MF*7qUVTPvsi2siLOC~)lj*st~uBiO@>-hMT6u{P*D!6JZ zMa!y|FW-I&Zy?`C0okeLM=`bQI!imVVq5a_kHusQ0%Xn!HL;oih5lN~?52RzR1~bR zj99|vfc<);?IixEV<1eK(`_`EE9~atVvBv3i+te`$G7PM{W+KrVPZ`z=07_>KN}3h zW@VI?mTm0JShsE+hIwOIMn+vKVv>iHtiDwFxu>rW>z)z~0FJ-;(Tp8SCrz4kXv-FC zztF~*@sX%NV&d`2gjh}a=RflITdw}+>;>0c!(aKn=BJN;Dk=HA8wKFn9X!-$v}JVe z+qm&4-)O+bqk~oAX*YHbX0&y-MaOpK$HZiVfSlMl2ToVQ0E`wKIFMu#RfmBK19e=tgQ5HcH6H!^g*G9pkMwS zn6p$|->gRj{j(R{B=ldy__!o7^YiHF?&#>$J{$lD5c~x0sV5!>~54G zqYS^Bk`tE?@sNLE7`cng#ANYI=pUlUqgu#f+srJEdPi)@{Z@0p5W#<#`jEAE*O)&X zw(qizRoL}o)X|_nwni+!#zh{7;cou1^ZD7ws)wV+;9~$&nOhr1K-^zOT}NA8^ygX8 z(Iv-$H6!u(@ytX#U1j-lJVgs+Z;;kzxD}TzYEU&~pitBsik*99C`mRa8 z*Zv5HU`=LXyl8)FRtI;;7~BZaRbo|-e)C<~?o;AqH6<9V!aBs~R3FRFKOYAZa96S7 z05$Cu^OaOPnx0O++T{(JD_9*C71^y#I)9NyKaDebr?=Xu{2T8_o#$3TA0a1O{7#T5sD z{OSIoz7%lw*s1!d6~!YJMQ)4T-9!F+Xf#R6_tcHjie0_-PknXc+(nDd_mZ7{zAOCBfc^+`eY_$WmQKJ5>ss3T8|M- z=}w7`@9r+q3_;=n=wBM~f{PYRpT2X_R2Z-bs~~Y7s7RTzwC(e{eZphZ4$5;u~R}kPh)U zfvl|P_-HQKm(|fGaLCF+<5KDYTn4(|C3Fh{=I{d>rRo1LHZZb!1ON0E1sx>LytZPJ znFCG9MNP?ST8{<#ladVXpuua?=e3U5EX%^y0dw+LkuL9I8j`Qc5f*|as2_%I`G+6S ztYBAuW4%~GnFY#-YQDb}pyH`h>$cW0K^!2|qXmuF`SKdg)?ou8JeV{I9?V|29`Vl? z^o#F1q~ZVaax5n_BYGH!3BU#723abm^ocz{y|M^1Pz&VWSwG&@h2X{aUC7oVlzilm z5&!^xF#Uw27t?D^PL~OVAF~!u6i=8(NOcUj(ubg*{0Hp?Myk0X3LFzfF55`JVzL<= zkEcugmmp45)M+>;J39{hiuo5)6BpM~IITH>S#{%@w*vaMy7~-6Uthl!Xl~uA0iauB z05L%3@x=1-0}0@rKzQheb=WmXU@O&+Si}DW7XWLmtVeMf#`l^;_>m4%ukS$3w&E5Vk^Y4oC`RltaDWJi07%n+pdTy#8~tw} z#qDq#ykjoAt=LbVCp5ClW|01mp`@gSTCfoc>+G(H2?~C_-U7Yqti3)xmg~SsEWfZ5 zp+j?XbK$Y(_U1wv^QN^Ai-XH#iSkPTRL3MWg9Ucu8#Bif#~U*n$1^h{rl%mojUd4vs*6T5<4RyfwyknJTAd8SJ=EcaXgbeffisvx|ms_ zZk$0zSy?8yM=hZ`KL!@$Yaw6^Mi352xF&y0s)a=Q3CZ)S)(P8yeZplwG7*F;*#Cwk zkCp0M*pNrPptz`F!Zr~I?Dd``{>9WmH|8G33X5a1kF^vYD?C=+KCfE7+uL(ZVNxuOv2tMG5le#Kdx;UwD`)SIA1uAP#`^dVp|=$y>K>?m8i8JOdz!e!)M6K;Upe zU_hWEMj=PyzciAOK?61DVwc%$Rg1=Ky+046_lo_iO?T$$&7?nji^%*ITLwm~MIq=P zl1Ne*iRN=jVR2z$dtqTqb9;63ym`We>fC9u1Um!)7-m?2=JP|0Q(p?G7xbgLJc5Dp z&E<&)5@rnVSa=Bl)2Bau_r0r>TW-1KtNnM)o;r2G0ulrg6eVoVBsBo+fejbXzJ$T4 zsn{3%igtauUG#zK_LjJ=77dMsg=g~P3cFwhhyblJ=WKC@!_c3erW#b6*EZ7MR9rM* z_9ySMTb*GC`S0`wz(H=EB&*3aVjgh!4!E2qx3l)~^y~`)08&7);`L!HT3=XrEUvH_ z9z;~2u)Vq_8i5lFp!70D26h_fhw}cS{li;Z z1I5I%5gj&*kZlh1Lt+UzR#mmJ7-mN=0+7s0Md&?huAgaNt3j>~hdiLFS-+S-9cf$(I!PEtp56`G! zwS?C5p>fP=7KqR4<|k}T%|h)7eE=5M1OaoVO`8|j(sH7(g}65+E{>I%NGRe2pH%;fSf#MH^Fr!}xf^i9%ef z008C32Fle@D`5c~;HygzcdT$)?r;ehO$7#;@{{*KNyUE)d>POW4fRVKoyDGwmbks_m9|Prry;;CVoS{70#y)H-xMVUyo7U=BD!I*YzH%_#H_rPDj$^cwnU6B;QRu#6PZi$huF z@rIgau6{}8T@jMy()syvN9|cxR~Lamd;6T!)Y8((^jNHjEz}4Q*&|Ax3;Lmdd~?F) z*o4@H_bt5ZuDk9P`T@c8-!hQ?rWwTQ;_Gl4giHeQR5ZU^0zWZ*n%NfwXhvpEJEkwL z@Wct3!Wo$*)Jp)sV+>e8V#6Y{uKaPKpA3kUC)KdsW)53ax+<)$U>N+<4^Q*8>NNzy z{eD7Y0HV5VC*3C>ZzxTuZm$*wXt39GU#Lg+=mM|765(_{4k0#Ln-mW+yS}UxZTSc0 zi4MeriSWlW%MTn#OspAR`q*PXt{1fj`4Q@2z@~$!K1pGDpI8jOV5sky9@zf5{u1XO$M01tP?st+T5&GXL-P}A+v#4AflS*JI@dUar_|m?Qgk71_yaeP3V#pAB%p-?;mdM)H=zH(7#GeTTc(5t<^@4-$_HyqKE<*~)jOu>NDyOs&bHT3y!SVuMR>wW}_}h*|JY07TO}-hq}5osHr^vcEtz z)jA({@L-WM(i8<=85PPnI*uEeU9+ukAjn?#eX(Lwc7=eF9N<`I4J zh?UI%lK%kybQ%XufeHPXrFUeE^1s~{@|iA6-$s@3=y;3pTEmsb(@V&Q6>=xB0XSW7 zP(3Xsku|Ew4tv#y*NUV+HOz8IvwuU1chkk7(O*lnWAv3$Z{RF`dRATNgNQIIG8lo5F z+ zT_Z>Ko@5Wl^$j0NfqC1}k~7U+f&f7m!8TzQ1{b>dO$!G22?~h4=f%WpMo?skuo{`K zMs(viQ6SMj3E>)&-H=blJ#G|PrdWb;*~3t(ni_j;0!tf13`;{)}bQ0 zXXz&mSf&2W9t&E~4fM$8dCenXldH&v1w8C|ykYyw<*%%+T3xoed0Km6*LjHmgnG=5 zjAL=fnyCk}AUI!GSY6#*Se=`Dew^t_e3CUz3IpvQr^Hc0&^IR`CLysTu{<_5lJC3r z*RQ|*)hg`&r6KX(f~hzFEFd;85u+(#ufRyV9}e?)Q%9^ev&-fR3H|S}Wi5@(6hT*z4p@J3@dzcLfYs!@Ed8CuRjb|h@;XY z>Aq_pdHXAk{9gd@^wW|PS|rJj%HxCpVlg5-z>;>;13@fMUlt#OE$-?%qeVOyNN%A6 zm;q=O-OrDa6kdUwsbiV#cS)`BqQALC_d@2ri;pCs!zD}Cr|0sq{I00S1F3~^*b261+tiD#g>^^PL=<)ne#>YA3^%E=$rlv{gYV#O(!8N$qzyR&`;zm zfwTla8J%Q$wr1?^mRy$@{TOlf#JAZn;sW+gzOi~aWGK3{v`p7{S=I8zi}$_r&MS*w zVf~vl%0@f(Rk6W}Eep0_K-JN5te5(?!|@0SzEPO zO3dr3R+kC`rcJA!SIAmRTp(0STo8jHM%hpW3_*1>_^6J70p$N8L)LGp2rxP;UIL#u zK|lGvNB;8FZ&>nA$M$Iqm^6DfGpZZ!;8 zx%i!xNiQ}uIGyzB+bUF=DGf&kmQCm_6K12t|3mD-)v=4uBn_+;1!0%X->P~-C-W{F zeP{7%t=`l*xOQ+|Tjso|D2)M<0|WiX7)V2723ZGrp*gMvOE|B3vm`3;VEBPZ8ia`8 zbZqu|sq|>%WBN92n)=&Kn>JDYTR43x%b@8~H!V1LaKX-C zxtb*p(RkMxP3q8pL5v>Umx=Hz2$VoPH|oTAM@MPty0*@$ecO@$HhSFH_DllQsT!Sb zvzLZ1{>}DNrxq_SYs_xP zuoQ~flNbPZfFv}#Qz&Z#2Q`?#2Ra9q+0ZlY2}|9Q5)Kv3c4OM9cbs z0zrRnOD4s!&N2+u|Nc-ar=F{&f93j)>_K@~L!b)!_Y$1!|k zR(7b!?isu4vAA8b|C`;{X?h1cw>$wq;m;9kYk`vuUZKO6$@*vcuRh$q?LWRF5?r~m z>S%mdE^YunD4>^k5d9YhXfc6A9ZXPuZ>erMAaNUhJC#IeV@Y|&wQoTQr>q`rPJ!-$*Q>Mt^=b zxwt}!LAn}g$&4yyj#^~`Mv)ZlpfGvRh(f`^b&Jeq8+0$Zm z(-vtj@Z0+PPlA8x^!)I{Q{SChyKyxQHl_6?=cnbiSEFahLQ-L*0%GzDB`GYpKSnBo za7f~V6V;o^h!DlXgZM z7*DB7j9^KlWPj(hPpj6-`z=JA+zBs)4u~3P2$WZ-NKDI(ifT`kH9|^CT}K)1prxV& zW!QhQ@s2b$Uz)-e+Whpcfe{OB&9eS;ie+HydN3G9Ei5C&c6(95$&*I#FAIQe+Xrc{ z8kE{IT{xLtQK$gqvC(=4PPLniWyED+#Ie&LDDlD4BCqC1lYAJ#lG#qpv0 zB)fnAdl;~D=RwK$)R6Fv-EsGlduMC$fZ(4|i3U(JsZ1mtR+4xjY8sBWnIIc3K)VKd z7T(+s`D?^iSI-mj3lnLXk){OFP^6^4XrnQzG$}2K;}+O9?8OJ@T&`lX&CXsYdiGiW zq_h8;lLg3mc=LkA0k&=CshGx)@%m9ZY|;P4t5*-w@6}0%E5+T+Y@*!U_I8$pk{A&L zPuxKx@Q%Bmc&P9rvw&jj-?aYah|bKgifbBN#z3{Sld)r6#as zi2xvi03fjQCt4rN$%X=f%nN88#TKG$k}WL7H2<$Xoi6PEI5Y zWZlg|STj8m_C%eRs+@E`(L$o?c#St|2am$z{vpYxD6O4tiA%bK4_v0 z2>yR(9A&Ga$r~_--Da1C8W0=ceTR(~N7t>U|C|oT)m4j^(_2g^Ok4ZLvaDgy*xaJ6 zw8aw3GKgtO3j)gmVgm|f&|fIkQOX$QGv+Lf^tb&*S+!)+!D}wjFG&(v9Z)77ucTE^ z3ju$7@ZeiCe@P4AN975XL_dHZ(z}}H(c~bE)+#%c<8eHE$x9^QFnzgE*+TwSv{Y*g zSzET6p6Gr1RxT#~q5dZuZ8=599oW_XuHD=;FcCEMhOz(YzvE>&9Kt~xRKOYVx+VMR zNlUw!L`Uu7#o7vhb<{?>PB+qQLL{D*!%Co#xj;B!kVd~u1Z%*`hycB%>wI?CiDn|v z3$#AP?)Z@or<)0SA%DR&5#e7`S(!BtK2SwFa-% zO@Ci;g{8;m@IimWpII1kWQ$%u5gHqCS?u=Syu$ zt`f-C@|)4!CCBNI+#yczX>{Nqwvn-*@~6b?NW=};Bm+lhZw*ZyIW*!^>EzzryoHck z%-?VddGRmmGD_R%$SKVrWZSoRdt|4?lovO4|RU1Y$lFCZIw^5LWp$sXbWw;g?78ttT^d-os>$9Tgml(L#g@C+hBA!SL5 z{^v-$i7Z29ae`Wi3e23QCA?VkJoS~frE9?gdfc8}z%qYx`Q}EdoSEY#G>c}X z(wf@2Z}lrxtM^sCvJd(>cgVrnFFr~Dc5^_-`hO%CZVgHQ>z^e7#_=o0kVDt%v>FEr z0u}7#c3e!7;74|x{Kuv7Asy!%cfbGs?v0(PHG}~~|0E#=i5mH=z@$Pv-Ier4ZW`p&{ko> zR|@^I$II*Wc|vNxf6VA(ySUL7^hN9+nqfF+^7Wf4{JtXFyCWfUz^peSf3lx!y7_J! zMzm`8`$x-;?k=m^&CVW{Bz1Gpo~lcWY&Q{u2*EE2yI~6ARRIj_&3K%j++FxR*M%67$)n$ zB7}hOQrL&?OU0Fdi@xKm)X!7C*wfLL(pR>xYTI&6|3@i*u-S|~VS3IO2pfA`W{Z&| zzr;UI5+ic@gxYIx>3YmX#l?<*jl-IrPujL}+jiQGY3=G5tlyon`&9kbviIw^reXtA z>jeSigCqu!kQ{k4OXwC60Rwy?^pg`kyW#c?vu=L!7KNQ12tPs^(x=1;<+8*l(T4+| z3H--Tr4=GVKg1uJK8Xc)d$XjK^7FNRu9#uk@3=IHUJ3i8?1JHs8pcnGC6Tt1)V}Dx zy0(;zy3Vqr+qQ$=4?mppBHi!wcz}SQK45Mo2V(c{A`;g8AM1b2zthPUaGNgAR#cFD z*fqgfCCHz>Ro~HRzkT~Ywp*N%9W8^YWMU<)QQFykAU6stP)OfJSAHZRO|J<030C0- zDj_9^sI#njZ@=ZMtC9ZYi-i2kKloq~tDen?$ElG<@`EKMi3ivKw0`DS`voLgCUE+q z>60d%oe2k;rL9*ijAjBg){<<%@KJaJ`;Z@>6)pYdQYr4EGp??_Eu-qYQ``STTfhA3 zS7QGq{+Hv1JU+I{a)N`{zp)_lZ=g70bgEXT&TVY9jj{8qi4#jqrnHBXzLDK+V(@S$ zgX}qB4NRA-FaQpqW;G}tM(|j(_$Gk>s7L;!=5T|e8Tp0H(@=m7w|})?U@g>3i{A%} z=mnA_Ckam6pTt0!r)ONCDyppFeGvv6I<)A6NkaZSI?h;Vi^U_@L)t&#Q$fAU_=8p`uLpR})v;D?C4-|m?kJu;y6t`MAmBaIJ((-qz$o{V-`9Z^7 z8G%nmy+%E2a`G!;1UD1nv=>$v;-TV>;q_x;s6}A}BreI3*gS3;3NU}elGzcz&%TH2 zwy?1&5%|*?$RGxmqA+X39NI$I{j+G%mIdHMtpA}yQLhn6OOgrM=ZG21$)UwHhs)#o zNx4spns%V0LkdIyQmTuaC2ts?($>lD#O*-flKxZTb@p(u8f#pC1&4;HdRtfyDY%UF z4+mp%+#5YF0TcV(`)z(#tJ$rdG+s>Fz8&{3HjrHhgaBF&2rksu4@y>7?wWM~2CyuV zCIrx_)ycspb#ZNxa_kKB&zyO7*6am@w3p&K+24WnD-qel04>oOADu~$^^P5rcS`gB zg6r`9>=atCrM((aqxoPdW=;$Vf7*|S2?Fu^*jCC7(>8Z>kZF@PR9dY|=&~G-X2U>M zM_pfAC;KB#om#$4^na+<;qy4c*06;Q5JhsliH)tnCdvOvZ3x%MxjuSbtJ&tV>h+vT z5O6%7wEerq`>Kec--mn#(f`Jb!FmF~ja#KeOKLNvy9N=E5P${DRLjdrS_0>EhE#1_ zSC^KQh$6Fj@Fw}E?S8p#i{|%Gdo2JaOO%oo&sL}d35Xr4BhlZMLx&ci{LL6YO`V2O zDG-2e;croY!k(!1gseKyj~mg3Xw&#{sTbh}Iy%@ftHm$)e{ug#XRp~(GywFe{#nR= zdYq4A|B^s}VTc6)=a=~XdcQ58_Xmzxy_Y2|-@bDDI}{O4ee?eN1i{3=G+$_AtFW8f zklm%7V}>{z^JUHROsp zWhKN)KfZ)rKf}aKGiN^d8oED^AX_pE5>9FXrdI1h9U=?<>T;HQ0!1mZP%0D{kZ`~S ze6gplBV+M5vSS$ie^0i!b6B3&WYmuZtehRAH&|(U8SFrtS$$>+7#$YFuOBV{+czSRsOS@@>+$fY_{@I*LG8!^){@6aP$R(VVsY|oiI6HwVFr$dD__ z3Rr$SA=#d32SAQSx0D-!q?DV17L5l4!xWF&>N>tCJ5|N{PfnTT@H&0aGbTG9i+g+R z_2!PlB{mR6@8KvRo&+1sjm=n+xcow>&!^nm#SSN~dLEpST8TP4 z?*MzF;?Wu@l8E?4u_9W)B$+8(U_I2g8u_#PgVjGJ0683GOlL6%bsXfQYVs#HKw?m} z@+*gSj8t&mScSQm{SQfO^X#lItE&eDb+Vr!QqGVyD{in}2JKm>Le}XM%o!y>3r?Is zW#gnJSEh~Ul0^`PTEf(*sIzBdB&jD-q9p?AyHQ=J*G6}D<2dA><$W*!x57t}Iee6T z$5L)#QBD4jpdb2kDKtYpgo{yOh$F$ezz6y-Bnw6?yk}2G=_{{@|3At3oYLaT(J#Fr zn^~Q(aBg0jCVzUvgPg&n(;Gr&eep8CoHBv|xR@mM@71!4Thi$f)koTz)U^`?9;8Q?NT)?+COiQPntZe*NEsE} z<%9Fcn}B?F%aOdpK9Bp=bAOyd`CBq6 z8`;w&$}e$0vqWA3FIrPl2)p66l({zx1AqWZa6;0Ngl8>Os-z^Q*()qUA&uJYQ8S~o z9Rp;2H%pU0%@Lb7lMB)4?@o{v1tr!(NvaS&!$0jilH!FSI2Ebz<(|z=;O2A%X|;7} zIZKok?2h<~ltiEWf>ui$Al-&m6Ne~D7GPW_Ma9LjAg+*8eZ!SIwcY?a0VL&)&WMRvRaly?WbUr<8pD{r4p$ zUw`})ZmW{BK#sGcu%>2)oCzYCc~)E9DcJu=vz}HP(^kZIeLAOc1TDltU_fLjJ11nv zh@@#F44}SCs~_}hHVgR^N@0+N>8ANI#j zN#jg?P9Y}&5}ue?rnl}I2voQO6%NBLE&ew;LV-LEZ|k?2ssA1Mpp7BH~|23DcNzhIh+p{QkL%a}xc)W9gWA_?>wmm&=?->B zlEuaGXp8u)`fjZHSO->p zw-_2}e@Jg|n({cLH|*a<^zRRbILlD-|D$Pgh_=q8^A^~OEw;n2etG9@_p@R2FcFg`N5fV?EW7EKHRr(DHE55^@s*{XViDcFn=bG7l3A(HE7k+s`BC*BiIH3M1mV` zkGjNMlnHHG8nuBm;aN%d$OU9oEr~BoLE#BNFP&xbd0|jKRSvDSR;)1_>v!ZVMI({X z!pG*__t?Vq^A-Y4c#=^0)7Q}{d)hb`Mr2F{pqAr94K8;2Sp1v^MbERXM?3$3^rtiA zH}v<9RE)T+7T|x|XQK*7R>^T?^2q63oL~0jQ%~J|^UaSu!o$r^J@xi2UjYG)0W>RO z3pMS_?21G$qR3Jv)~vofKnq5WjwZY;mq4N%%9H!LFk``)NvH; z#E?Wz+7&RJyrOAOOt%(?qi`6{gc);0H-BU-{E-UtYp=0vTK{82JLxC>{!e?>5dl#D zB>zJLpwFYT2Y1;Aik8_-db{7|Vf_PVNR4rPp*hfB;Id28*R zVC&P@=JPvD*)Sgj%%s$fs?U?1HS$U6E0m#0Kk7pF7i2oFzNLVlauYvO)jiiE{ zy=rf(pT4lYU%v73{XanZ{uf^O+uv?{;f4MC_j7XF)$CJ)liusow$Te;d7R>zg(;rdKkAC|8Pc%Xa z{kQ;*=`@*Dhg~)MIZLyXVeb^1wa!-1ERv+V*R-9b1yeBNHJAh(JKwm&cM& zNGDrK6s+aKG}gnrIH@#;B9xnjUFFyS)$ zTGIE*xnmz5dAS zkNo|qhaS4+j<4=OofPdGe2EIoe2`B`{3i>4qR5!+GpG^p&!x&CX|gt z&gV*UW+Epm?qBr+0NuX|z^+<#;|qUVvg4zVzV7>fJ2m`c{y71S^QrwDUaa@~EOrh6 z#s9PYqoD!+XVZCGi<2h?_S(PP`{m2`&z>}O%N0<1kbP;iB}`?5+Lc$n#kf*R_g7qT z<&|3&!GX!_l#Cze! zzuoh~3ux6U(XjoiZbSiQ=DzmYJlWRRQg{OU*NiujzOLLk(h5cax-)}4fQhjSsVZ;S z03)B0L-ROSQFfNgjONaLV97u4TC#*)rjy_N9v1-pqty6l{_%NKzm+r7eL5$nzl6m8 zvHdYUopO)K(9f!HY_A^r-}vl@>A$~8>hy12dGPo2DP8%*m9j@i$d~p6wkbpZvl;`q z;|_XO6B8>XpNk*bF|=g4Ze1 zcuuK}4|Oo!7_mKAEg5*~J#j2AkL7uP_5|D4^Zao(kc1FszH9Hb*Is+A&-yHHm+wl{ zmx|_)zZ=Ie9&}hCzdsH4ot0w$|I7VaYmf>zfm4z6)Tg}01PGjQ!wtkTNzaekxPKIH zr2$^^JscrPPecMh!)4>j2)43~EBk4pRnmPezQk9(H-Y~7Fu{os?a0QXybcBhbF!Ag z$XlfX0z8pp$MSJ($mg$Dz!?pwSxThvL-@jEOTYi}Z+@lM`YNr?%kgL%^QrrWb#M{jQcE_z=e3K>SPL;A0#F`;z1(`rwG{Yb#L{h#-{wl@B>boJ_w zUY+>l#D^bVua#%~aN=B?3$6jfb`qtXO{`Xv%@|fN&-i2rFCYBSU=zj>XlXm{uYz@Y zT3NoAUk3a9;-lBi=Q+*q+0bDT@XhNIx{EsG<9|9sb$*&Fpm88enE?dGM2 z&QL;mj2Gm^eq{2BQ>L&c0|WVa>ACq#BQ!fN&C&Xk<_bC5Gajh3lRW`60TNY5NcOK$ zdBHf{B5cd!Z+Z^;FNpD7|NQ%(mLAyk>L0020HuuTn<-d7*ND$;XxPFjvo{_cb@b>^ z%>W6#_jCkm^>vj!G@@#d4gurG8DyH2Uq=7sJMRJfJKvBXu~s~@IKfO-=xwc;8M2?c z44GlPzIvglP0*41=7=*@T7JYgS!MJ{uVduSe^90Y#htQ$zZC2vY&=1}l6btSsoLMx z7WTrE>v04;?GE7|z(!I3m2T&cuQJuYDCK_NaU37`r=_pH`sFQm3zIQ%y>>q{aO8;K z*)8+nL%Zb`)D|Wq#>S&_j{;bx&X0>wUIQr4H4`8UDBGRi`-Ku8j<1Pee9UIO`au!@ zDQKEU_B`Igh^`vArk5z8p?ZPX3=UjW(FSNH38;(LF~UK^Vw?QTp_Myu0(E zcQ^?jzTveSo_z92Y@y_*L_=3MLusb9CsR3pKD&b3Tnn)*?)CMGabG6!W!8}-ozeZm zLQo*Ty5^1R=6@x<+?HDzv*EimilB)&3i!dukL5G>#=RTFe?;0z7kl#CXT%qW_)m#2 z44zc8_OrPLa5>lR-1)`zQ$`(S?ME@cnrLn_^qq1Q+opK}EJxOW{96A);vX;vAEyCF zC{UhEL4ompG z2tYy=uw#e45U2OL+tB~8^#4RRp^*ga7Xho;O8PyiRCBY(hIqTJ^p9||zIdPH|Kb0U z?99Mx3p=^<5CsyU)$T8tfcbL=cAf$P1ue+0&}Kd04rzcCz$icBb9K7s#qZ8A1aCmx zaMT~?q(63S%`uSi({I&|)k{fv8Pji`sm0HWPpDbx7ZZOc(lQMBaUbruZGQe|Z@NjM zGpe`;i)QDpH3N?}@b56>=F2?W0Dy}k9_n`4KjEK=jfHHhyf>D0+i7=K6AdjAv5PL& zALi1#Zp_P{xBqP@q6;+n$1!tK>(F4)uMW5I!PRU|Y=*QH7IgqXNk@EgZZWkqM|cjEip z_>=F>IC}MGCAQg@tPPLG%6xG5-7}z29+=I-lEOwP5L`}wKdC>D+XD!I^UvV_$o>Xh zRD3|8AFK%VKiAboD+fDxv7(e|eEi!t{saY>$nMv;VfMn#&Rc5P;zF$Kyz4HUtf7;S zyPbY^WQcU@E51u6gK^_W1GU0Nh%F`0Fr3&1oH#)_w#e#`OctvMY@bfL134#CJ>yOF+}@6EWmx-e`Mp4 zjm+nik!RR%ilmN&r*i^NjrhO(!a|EK>) zLqpn0x1(%=vWUvmqD8*)<8~m7{(tcJkG_2kTMtqz*D6}Rm0W~mf8W=&W z1TXdw%;zw}?Uz1%=jK}6DJ7Y(e+a)!*%%=80(zX8pLZEHZalJo%7y}RNjwzif9Gx$ z*K?%)=G!m6bDiWjqped>S+~n--?0I1iXz@*X`WdNi-K5II?d; zA0Nv4i1Oa`9mN0E-@p8;YuJ&jsywFo$JUT47(Rq69!WAqdM052fQemm-&zo$+&K*j zqJTT)z}8o?m2@NZ1SCpCuAy8E%%ZHtJggA~R`s`lyV*3;6j)MahHnIuws9;+O&LY_ zk5fLDKGExOEb`}Q4V3dHdo!~C>OdK!KUdHb%|$(){#LIyW>*|fcuQ}gXhr&uC7nol zrdhj92IvUEU}xu4X8OXdg0_7Z`S~^Uy4@T>1#nnMbh3QRL2c*4#~;A+k>dxp>*&OZ zlK*kSr>r}10a1y7wQ{N48$`6td57Zm<05NV~cjRN5R80>CXUp!HEYD`81O~{T>wLyXZCI4~5Tf*e$T; z3EIFeAR5qDTea|uTTy=;KhWP;N)g>me0IUu*i6D$ zlZPF1NEhz1!5b8PAF*;|zQpK)*8YJ9z6G1)jc?32dIX=^4E(=F_3lk)ijqkRJTe(d zJU9if)&6&>jRuY7PFnOe3HQ=YC209hmWNA4O8)I@aDZm${O6%=I5PVdNZbha;Nxs4 z0Ef&3ptAxu>Jl)2KF0&mAUKE7ex8dA1ALmZ_b6(F_(vulIYNME6V{JNH|TY~ zI6aez#7lb0YyjdNuI*{}i~X^gD@ptbJti#3Lqt^x93wW~yEe!v{nZhy!^}-RB?Z=I1Dn zn`|}-UeJ`<0&=4=aw?TDlc3nAmVdzX&FY(1zi{^^op@KJXRBfQhMGPD=Inc#7++(d z%Zrf@WLq=QXt*-tjpiD-|B(M9{zHRlnoGvheyhpji&}2*p>{07`tSaNYliIK#QhWZ zuU|hGhl5Kl0>Wd2Y#X%czS;m#SF#82!{Ki1lRt(D7};m)esBH$uRgi)A-4Z|W7=*w z^7y1ptiSMqh_AwJ)*qnw1CswSP8)3ixS~hZ77$htx@T4%BSvCVupX=eCxB{;%eaS{ z6W{1Qn*Z|mf2AG@Z*%({2r<0+D)K{e8=%`TG!G3iU%xw;jAR?!mebt-i=FiCrm1G6 zjs8HXR3PlPDiRkT)cVW*89!1_B*xlN3ny^@F&01uVEiVCoU~@#0&oG5pW|N?9?<@v z0ayuile_wzlsrF#{;$^^f?M7((Mkbg1s^~S0l$WuOLF)3A;n=cnYTJht-vdSO27om zW+&lk;62(@QhpFbv*;TEd-f*c;5zjF9v@S0gf)gpabS#k_0^|K)s7zd=@=~ey>8?W z1R6YP$QM_tFV7wj zyEa5#a)D&q?!Io1&h?}7wL4_|^;@J@s(d9>^GoUfP|mgWPp*Fw`?qQPZuUR;F1CSS z)8l6jn$G#Jee&pS#G5!Je($Lu!s1C!(PhA_Emf~&X??iqBY}Uf9>=WA=Hu6rQw2yL) zWN?R?I~Vhh_!M;k>%bCV1%wm-j`aV=M{$68J7x(IaCnfxcA)Q?Py8yuM_GO{t{X`I zVOwyVude;~pW?83^tz)PiF*yK{vVN^_&?zv_DSq zN4M8#s=q7gZtHOedVUrzeTA3*wg~`mXkh^M!_T^VH#k&SaclWqH3YMJ>+Njr7Xf%P zII(JBxe@0p>!gd&N;NjQYX6M<6Zi0Q$Bymg@?$b%)K6dvw&O~&{}mfvd)o~8KL~MT zHVpt^0|VuAh`oeIp^F!QF|=!>?jIz;%;KB1XW!pJeVt66TC5QIIY0Vo`myXH{?GAu zLg$||n6oWfV9}~NU`O-kAGbn^f6Ki#%>`*~=Iw2=LOqG&<^L-G=L4?4YjOVx|J`t8 zKQ8HM5XdkqW0!c637a05{H*_DlynvuU%LYS<4{}UwO6)!KotKVFRE5up`5QB{^Mjn4N&^&>-MwvOI5Vb`s0v3sqmlNpX(RyCIZ+wtbje< zS8!Qw3m4n_);>d7s~H9jq98Z}Yc=b`s)ffM=++UD4o9K3QH8KgJqD2v-Y8l=(D9pShhy-KgmF4WWP*pRgML3(cpk*jHoru-bVvo+vv% zg6<*O{{r~}fOR(5;bheBwt8uudG-F|qP-v;NPB6t-IVgt3e%=jaVUWNoPXEcsOyiB z-mDzrQ-*;5kNursI2}~e{@61E;@9ICXz;*!59PzE-Q0ik^5+*{6R>8Ju723P)5C{Q z%?U_Y8yWxa8km43zXmTUs5G`tG*YZQ)#8xqm2Cj@V>skE^S)1E;rEmRn$OyNl?DNt z#34joz=&})C(!=yCip=Gblm0egrlj77-09X+ndGzIZ;SpFda{@0b(w@(wC(Gz9&F$ z$#CgBvTWojSvjQu&6ut5KT-bL7My_bJT+DQciwZ~-IG}^4Hk&gT4^8+z8rZOv5;S< z$iw;9IC2B~f0JPnqd;&tFkvDfCjQgS{^z#+LlbP)1SkMtb`ow6zxAccTsT$od!Gat zyN?53AxLRI!Nn=uK}pFMpeGn$P7m^b2K^B%4rOToLJvzH(XVPpE^|WnUqyz%|Hf&r z9I)HM{jv{Se@^~u=_>>P@c-Dka@%B-Cr$+KF%S2S#n^DmRQa9X;i`GxZ4~XA!FJWH zS0D6MS>J?PbtRGg)62l}_V9WR0D@npU<9fZoPW{w$ozMAWB;*}6U}tLMvi&VE$3xQ zasKiCb?=eaH=26+g?GUyK=$|h*ga_sd-H}P@)$kj!q+#-l)veZ;0{Ew)TU$LsEqh*7**G3 z5DPTk3#_eISW)wADOs+A^6n#VG6;)9iWB-x{AI#uap*yg@r`98?wQi z8~Xov&MK$gC14x;C#``(u7uaup7QkMGEA+!C zs8@7M@}vHbP}42%m+nBkWd`jNOc*$yH+1DB}OO54v2d`36;i_@-WtD>cWisB}z>kCrm|foEzi=dAo0 z(6MK}{E+qk@{fN!uN-G#cd)pmF;De(!c3uT4|l(k$I zm6F82=Ne*4`eFTH+bj74#c&_|Nh+u$5w>&KyRUr7{huxuG&unx3 z8u^dH-&|1JQbwdk-rr!#V@ZBe|A+kdaE&0ci|D-0Q+8UwM`Y&rn;C2CjuuK2T5$UgWB`9IUY z_X!sO)?eal>}CSQEI&k{5BB!AUcTp!>kJkIJ{x0o%J6#zuLJ=h@s+>TG+pzeBKyVw z5=X`WP~N8GA9FzVho6y|=q7YyI5PI{7f-;bQL3F}4C>@0DXZ0%66UpFg4X{xU>}4d zIXYjD1#_g{y>A0x#93uz=gE+P++Fj<7fgVWznhZoV2RTW`frur<8HIkaC{@b@L$Ef zbgzdKINR?#PI1^GSL9>}`~&Cz7ZP6y;2#PC0sM#H2Xj2Keh3y@;{W}xZoJL-okwP? zCV(BP+ZpwoLxg`|0)+SF2gwtWCE$`sq!fOi3y-f^LpgvbZDwwtX@d5cf0;jANqMn2 zz}Hg%H_2dTZ!Wl6bf$u<5w*AMJ~sV(f;~}HtXTQnx$hQyDHOOOE_mOB=7`MYdkL%G z@X)!WARs@Z$PqU`n@W3CI;}2fIxyJL8KWSjlCI@~qO&0P|U=pE&=ZR2A7KKO&fjLka z8;$aFGP5@HA7Ss)SO#1iAYC@^#Mw8o0fLF+^mWLEd*juSWWd|&N&3q3_z$Q7Xb$FR zN`|`JzJA)@l-obMct7?Z`Ty$w=<2o}j`o5L^I9gDi?6i*^%rl$>i`QxWQ@~afiY-5 z`-TYjK=~p~QU)f#pxurVBv5v5{!xL!5AuCo?)W66dPCb|?{=Bi*3?2$f;Yl{ zKwzz-PuhRyHQxpQ!EdtyeI$K|daf+%BylZz2*P_5>Vo}4LPK!1XFbFYG6uPJ-W8dl1<>i8 zQ%Oq-4-Gbqpd;CNl#?bmC9dP4ay!@-ai*H+51%e~l?MXIU*ZHBMf1z1UUx+i#X;50 ziyl0_b!(#q{{I8wf7<^F$e0k&L{1dJ0+eCo2zu%hak**eqCSGlAF-*y!auV7;J-<3 zvwV{XZr*x3*kQIl*q%KKZO$dRt-&2e4iW)sa)eTUygsv?uE##WCC!Jg_+a|?i0#cFa7X@wLH-|@ zkt{!hBooh@f7&A=Z6B-?3gy?{NBi~YD&GghH0W_=Kwz24h|V}V`{+<3IikxyRs(0f z+zQ`6AS=}IPGuCvu;l^>4E91y^Z}Z{BudG$ASV3Zk+zg{-y{2@OyRb zK3*!4`h56zuB11YAgX{wX2u&RqmB3s9+}t#Yh$85Sbmv3ps!HWQwsF4`0+R0jIML= z%_Tl1SQ_x@+aApeZ`K~^%{>alO8y$l@c{9~Odw#}OyQ6GsPSUbC-M!Y7N$vUbl}vO zyKz6X67$*c21LW^8>KS7A#J1w1^~zs7mOG2Kr-!hr?Sn&xM?FU{8wYBxZCwyv?{K^RN4Osi!EZdHMTyazlP}hA~yF|MgstW-ft9l)>_|13=KS2dIA-K);`vM{yeZ zv}a)Z?HM}bZsZq^4Edk>5x&to*Nrk$$zHVUO+Ub^B6b{~xw~-rcB@j~9RPhE7jq?YX5hhIJG}VK)>b3Ynp+(AG(hU8wvnke256@)qlE)lTp6$5^6{| zKUjW&!1EI@SVy3`3XZIO_uaYcN%G~#+{rT@dFKwjn97zo_GzUFHp=`XYpepGMh?JG zEZ0O6taeDSxdD2O|4aTm;|TTl2mH-l&#h{D{}2Ci|JH7>=x@C7@7Liw@D5)|&lfjL zRNJCQz?SjaMtt426_&*9?VFnS`Xs+5002Ctz|?H=@P-89!qw;1gI&K7;^Rkd!;X<* zX4QE)z2Z%S#QgxLh9p-l5dU3ZXfpxg_#^Q(;>?EHR|*P9C0!K~H1g0Hx842D8*jYv z=vo|ujd|I58{xk}xd($i+19k}pz&?k+ZKQXA{OtL{U`mMg$%~$i*hUSBp3bX{aZgT zeB+&e=XAX~y|`rjy87&|9l45ml>El)H_{I-`%Gp^)(`RmS%7Wk7bVNuzxlhMnKFGa zlSkH=tkM7?G(Vl!vw`#i%p6tFs-dLEktrxNCFGaKbacqftQ>i!_T5?||J8}xIM={* z@UZi#Z_V*dH|<)D{EdZhykydrBkOG=0P45n-V7H&;XhA6iq{iz#nbJcq^G}nQU8Nm zxBko4cUb%VvtQFz)#@uGs~{*}vhMQGH3+sLJwaM3*|qxYeRJtyv2?RR^+npLahCaD z0&sWO0t4f!ZRRtOzx*I^cLC@t*jKEkG9za>L2#n@V9J0{h0Eh==nTSMJ2Udkd+*8j z$iE(7F!RNLh2?8mt=X%oe^dCEDkpe8i(^r*Gj4SO|FHsIx9rUGB9W^4{d<) zYVe4b5wsc7i@~Qi*C597e<2Z1@Q8Dnv1`uq=h5*7(jU+~Gz9IoSc4sb`aj?a1lo!J zix@Fvdmw~oK0MXc)&2+XzyDwEA4&rGuS2h7VoVBiZAA8sa^dzX-l6rc<<2{6!#1QJ zBvoeuFyC12si(JX1Lg#I0R>F?s~j_M`>m(-oXCsdKDgZ}89b25O)Mt{t*7o>lZee(u5d|L}i}$_sDcLuRd~Y$U`sSJaFq z+{h$Ia%2}EhKS#WC9FPGn;0$hT{TalZxFh{BzX_w26EGvCwl<`fcHkuW8?G8$Zp1{ z`NK95>(R-{Oo?IIjNvdp!YHizdGViqtU4-qUJrqV5)N$hv!e%75O`kGi3ad&45O<& z=Swfmfd-Q{@xpimat_6~{6c*ez7h`D*|y$LTKG=_!$JOL;{ki4Q5v9B_y6H%KYRZV z|NPU^r(Zq)ALn0v^;Q0y=MUYOMT4NU=6Q&EzWkCn8#xv(y(`a@!GK{N9_|W}V1R9c zwrYZMTd=f`ha6|`OcjI54tAf*d^nBmj|s z_+*SCO=1h=QBW^Y3Q9&m+y~48&LKn%gU^%qdv)}yFMY(~BmM%_KLh@U|27j(X9JO* zA}e6q{gGJC#{Qpx{RL(mwm>}Ku7>}=BKx!B7vaCSminJvyFPmQqnG&o(l|27qtDNx z#vGB)Q1eQyxuho;po@Ri&2oD5fI$>DhNJ{E5sx&=^L}u0AWVY8cmCNR))OD zdA^1SL7nHtfHbG$!19{qhZku54gZD9nE~hTx373Dx`5?8O@{wjo^eAQHYAsW`+s%H zV|gF^S$TQSUrJXjU;WXprYuJWHy z;p9zQ$#_wgS{GlEo1o&~w10AjtXOY4)bCwY+0~qUKiV8kz5j>56t1pWy?Xh9n$-sm zsOokplgso%F=VhvhHVf)K76C&S_}aY2i94(sk&pz{=Ob$Q62AbJT>gqTb%7SL2CdrTkVQ|L)AN>r37zy?BF z2D)`GbV!u_8bWBcwa8zH9hx{M5MC6>1dKMoT1VUtJPY{c@tOds0JM+O)Yp}cMi>BG zASjhgk54E8&T^d6|cMT zIpUAxlF3}wVetQ)4CRi7NIYRh!zlnzZp*50$Kd~}Sq%B{a_D~;FsZ-;#d>RZ369DD zkE^nzJ~5yn{xofJF`fv}4P&uLYuVA?=YZvE$fK>YZ{i#&H@41ta9w+=~_wIlJ^PDDN zEbQ;RDlb2dS*8>RMl_1DbQvYffq2`rRFrE&iq0t|a2HOC_?mG3O^6%uC)JZ0C5%s; zKwCiCkJ{&FVI>oRLE#rkBj!`yBM5me(7cWk?<179%V7<9)vNzyQ`+J)z;(@4F`46gpX${lR*5qh! za(9(`JUz6Csc6q$TL^jLrE@g@KzcUV)6y|9ifIP&gD=Omu==d>Hri3a*CLKSK4Y@@ zeefVG;T(E86WFnn>SxJ#i1Sn65T}lN;OqhXDy$%Hw^!$qap`J zFy37Jhb$Dno*{h|IU%qP(VybCLEgsIUH(5NdvC3xV=OSvl5&~+Vf_cx04%d<7KQlZ z4sBopIPPFlI(rtsAF@Muj!kC~G=Vz-t!}{%%L?v=1`6xXw=&ex<=$b z1$!gx$Jl@IAG(0~N78{_{&*vPUpfurV@UhIyRkJ$|AVyE=50dxi&6nk)SHgLfBUs9 zrxrsXc}~6EQF&aB&FXEA*xF+1@go9IPPemAF^d71#^asCaCtg$U2%Kl!I@(p-Yb;f zRH&fl$`WXhreennE=cS^rhrL7KTwapgY@u`ABh{hUHxuQe;5HofR1{hTT~3l8NjsE z>RF@&%l0k99`U3w)k4*M?$fted+~p={_x*o`<$*^dqta@{wMBLm6g?Dt5W#iUqg-S za`iX^=?JJGpRdakqe|B8PUP2L4B($$I&}{E+kG7!`#Ox*k(YnWfw3)nZ&r!3DB9p* z9}oF8*|E!_KHUzw%S689@e%mAFjcMO;RhEwoJck03NY4~&hn;c5eJaE8rcB(m$ge^ z)iizp5LrXCPlF?X_dpKSa0uTJ8@q&NOE;@Fl%jC6K73Z001)|(bqB_-*jHBvb^l?> z-wpMz?K}~u$8*}YED+9~wsfn<{(ml zoD&1;zJ2@FiCl`s*SR-tjN!ip%4#+~B;DHlQhg{pWdT^AnF`&K+`F)8JOSF>r-zT< zZ5VGR>>N)a0Tru!clhq9uW@sOGEu%gBigh#rs;hZ^LFpj+zZM4@N?`w??8|GR;3-d2I_bpz zb2p|r6wrt^P;b7X{z{r-Ih@5o_>ZB^{O#8u5rzZ&5r%!?xo7Q|msV51q?ffB7zv-^s!=dQlFZ%nY;mi)m zvidxu5a$G2zz_++B5F9c#fGLA@8s2m8>Gnsdw|e76TnhX9kh(n=*{rH?W@~Y2lHFU z;kvh0yme~9xl7_drUQ5=*5rsh2g5x95O0^)3&>0HFB+gg{u#I2S+z!K@4Av&)Kn2k zX#XQVe|`rCwiG~PAGE(?jV)YyNUIM|3)&Ban@3VVIv8q^e}Mm*CMZVy+b?Xoi{LZ? zP*doc&wQ!slhRiWCBoLs{9@Cl;XAb{41#tXY+9TvvV(c~1r+2BAi$;cN&{vs+$$oh zH@A#FFjkC|6bFvM{w;>C_Z*EMc6`dZZP_CJW2L|7ec}#eV85t<<kv41>C&fa0Kok63!iW-z2}!K`55KoS+oII z8Q6(CA?js`rjCaYmQz8jAK$rE+*u~uHJ$M6)i3l}v{D3Z`K3t!6tbK0!YTn=2Ook< z$=FuHASeJl`*d>GTRtNebgXkt!$t;weEtqs0um};%R*c(E#o{xE8!1q{r-gW`RjCQ!W}{d08JX znKZLr+P|&?y4sFYr)t=%rxvfMW7Q1(GxBr);|kz{^b_toxBp5}k~Z(&fa(9v?XQ(q z$Z2ArKEF56lp+s|jR^kt!h4^8UIggN>vm`dumzw%AIqQ}&{ETVoL#T}2efA3(G2;! zmIymI1Y5;6Ws`EDn|jwV1^K^k*naYaKjP3b!+cv`Jp}`hW&q|UCV(np4gyVp(m&go zUFg+WaOM?0#7?A^=tDY(OhEmVVXPl>KnH)_x>KhX|FvI(Y2P6IC&ph4$%|zN%OO5@ z_yXB5$-lNrv;Ob`vp162jP3S={`UL&V|Jnq{%=WN0|_w7|J#8xKu*@2u?NN=z9Bfn zC_{BFg&e}})X>5!WHlW2Gjwy%ObQep|BWR4)ji+l*Xysp{;OZT{yKa`_wX4CAb#fu ztVN$-C7`aNh|0jsHW&?{m&|Dq2{PG6eA;WswUF$nz{hylxI$IqVEjh@nti5G$En4f zSL$Ai3#avOpaFvI%49N-{{|dMk0%g~`qFL6e-#H$P#GETr3D_`@2Sd4cXj%?UJLnY zdd3VcSiJb~r)>DV6ZGunkLW&r`DTczA*aJ7#TOA(5#~>wcdP1w#;`fHF9Ens8nlfn z>0{G>BjF(^QdULj4pE5Z>9k;#dX(P~YKa2q8ZsAaz7V&d_=HIHUN#p24nj44V;fZA zULic!419o(xge_xi^8mXJ9R5TH#z(1`?HSLKW{ClTTBnk!wby%2ZQP0$(*m!SDA~` z;5p!qy1ib`Kf<3by8o0{q&;a*K(3E3nXqGV>HoclcjyMV0#icMi(SwubMS4J_>dED z=qb7fJ2%>i3ZM!&Kpf+ps_9cNM$Y~r6sV9cf1L~u`RcphxZ@#l9WlhFrM!nJ9Hep- z`kTAg=Kt{yBmYQ(yEw>0bjZ+b2X~KPfQI&hxe=)WnnElTQ1V`TFT)TcdZ2ZuH~^oo zTU@v9dD`F6xu;J1A0MaHmC2?ZF@LVLDC+HPZu3U^75@&lCeq%Vm3Fv$Er&N%T}=?c zlSY2^f2w<)AP`-U4(yr(2k_HeH9i_MV!XMZ5#Y#Mezqe;ZybHNbQ30^rLq{Hq;5$>R*9yrGtN?m9hyOL}& zp3pRI5xgO>WZn$LmvO-@&YwJlN4R24>Kp@6HyrJCl6~>wy5$`-ZdkpV`!Diy`uh@T z%NKA|=CakvT)>@kWPQlb%n$&z!f8kI4;FPblL1dvM=Sl|*k8IAEFgRe{Wm+F>%Y10 zj2XRo)>Lk%qUY1>%QB((R36Jl8xbDpbZ*D1M|ATN!Q~s9Cd8#83I1W6ioYPru;vbEUxY~b)LN-l- z-JX8G)dM~vc5U~)_paEn<=l=_Z?U7+b#U~ebIlY$uj=x7vlaCJllA-B7C7WDZ8^8E z?$RZU;Ia`z6v|=!O^geZ#Bs#BPvEIAdLq5W7_m-xCA1}hpd7UNyxRRh9+XYmn8y)< zB)EZcLcm+fs;Je0Kp&7c?J-5>uy;{PzH`{f^M~l=H)dQFo)%#x+S!X-eYolcwD;-$ zHerISfkH2M+C10Pm1=$W(Jq>HbkO;5G3@u^zgPb|SE$?($(G~ddVFm~u0VS>Zbfwd z5&r=En1=o%UF~VEOu5r3f1oFe{B+Pj{vGG=e=c2GeCb@xfw6}!%jGA$M`m;TH0eC{ zm|r-2lymV^1bom@=iOX+{L zt79Dv8wNUn6#kkX2gNZ52_Pu0s^PdPBGK1n<;oTREGY?4{%0l9@Pha%+WLJl8pK#u z?Apc!+?{v4b$Ico>-M4l*nnrthAY^$7ng)*K@%12Fq@DH9^fua!s*Y{3Wu;~i(-@F zD^R84A@zW*9kv@9LChZe{z<@;peeca3baNcACs^U4haxKLP#ksc=Q(1N{W+=8w0=i z5;m45_cKxgf>iKfIBjQfw6M3#{%Mwj1836k5zFQr7<+)g_otuI{YO_=>A%{)(dMN* z<}CO0rz`rKiYon-yczs6sBpVA9_p#^dVBrAKa>4#C?W!XX?&CBA6wM>qK;l_IKCgv zI;hw*F;4aS)iE>#)tBNk_<&EQWEUE-eSDwpNld^9Lc~NgFy`~%WqN2WAmDr%pujYs z>A3GfrGjq2GJMw~%n$YfgD^_@OrVy8v{nB$qWqJ%2s7u< zbJFb9c;(|o@~-tD=&jjUaji4 z@A&l7OX_}w3ef+91o(-NEd~Tvpt>!Q@m6~2g>CvDlm7u0*2;><5h&C14d{|@_V9D@43D2r2rjO+_yqGXns>DzAUE=r9=BE3@id+DI ztIjJ_5pcAT0M50xwu=Ab*Q7s#tpO|NPlJkU#`$+deEw7-cx^HJUmZY}FP~F34c(_) zi#;ad3iFsb8Zct@iW>S~*4-=lyJ7eRs;k)(w!BtU_Mel%84nQqZ?&qe=b}ZG zz9!3RvU;v9In3>^j?3SiJ|$!zWMzp3NMO}@ADzb7eGL+`xTtbL$Cu>~ygW&Tay-;S zDA!>sHj)2Dis=lQrXkcM+Q-SyHX6?C0I2^C^-qsI^W?zlQ~%5*NVrPG$BhE}U3*$* z5Z3`YAzFJWpLT#OfWj^sAA=ia3lIWW!1d?1rvEu4pU%)pcO;ulg#*<-ProPZ33!SB z|5^knm96efjz4!2Kh_2u_ zYcG#@(#_-h2D)0QR#lGQzzodlt2gyR)VCV_NBD;ye)7qOiTZPEUO0Ta#Ao@x_3|&T zVg2XM$NibI5we{E`UEPizY?ty_un}BZ{vXRhVnnL_|(rEnT;CcS3{2nR_tIO@;`qs zK0MsFDu2#8-sReOQdBJurT>S;7NYhRCXZq&jyg*o!vWRmd-s`YLz9xU@@+q1GSx^c)61efC5lX zVa9rpFYt&C2fA%m|6A0Pu>RDU&7BCT>JbY4XMwq(1oV)>8*E-SXY-*>wH?*K{xLdD z>H+H~RnQ_`W?%3`Q@4*Fd`{jk{$DZl$E~42D3=PjAMX)z)S!u(61pJHgZ{q(w zbcF-~QRGazd*Fjc|7m?*GiM~}&9id0_|5*(M|2Gn$gLmFE&jsb?Uqa$veM*5$j8X} z)dY|yWeU`#YTmH%*gsV(QwMCS>GXlJg@w>o5dt?Q3#$KmC|@NzkxB^xiwFc$Ss_y* zUqG3cvhhop0iFW+FOMf4s=l~71$Zt!oa_Q54XEbSL#K@YSBU@DSR8Yn@Os+3F|Xf| zioyWeTj8*D{{sLlu=*yY4G%^q7H&E`C^tT&HqVsPY0$V~rleO54BC(S z-}spMhdmSL?kOv1=~FUrFfXC=R9W{iFC7|FHi4XzX*jBxM-w|)3ZBK>1vm?l-h_w` zo}D`4l39QJzsBMK{Vg*d3+kVEb*0rC?mg*L|1WBz8$yn@Si3hEZ3=g-YW_D)z^3Mg zo@*Q5T(Np=0c~zo$-t1q!{Ns%BSWJ%M0~|10Vy0@GV}7_d{%fF34#MUu-OA<6KG3} z>w^bv`t2$jpb#D^c{3&sqmJbmT%LiKr(-dVVVm&p%8ZKO!%GV|OeR3_80UQEx7}C>E`@F!OL8 za{h__g~)i1oenKZMM;2P@jH6#o?l%|IkmSMXmR2dmkJg*FlcJfh4?0Fn2DfkT zl1{`oz!Sl75Lg^_EItc|`#%`EdU0il1`P?X%KywG_kD8DQ+K{h@dv`IMf81-C^$rz z;3(7w)DsFU#u369h(~dCjGJ{CCmZ93E6fc<6M!OU-IXOma=skK#Td-&XCoB<0RKb$ zGe}vdx2Y{vlxWKNx*|;p`h6JvZ)_-j&bHeE)r&m7A`rk{z+jH!*EZferNc@BmCr{T>j1G*Y4LLGK;O1XF-)c**v03J!err9sAmi47LHQ&L8HZQ$Yc# z=d^=;>p1@#Pmlm3#q0BAywydz{iLXQb7mC(JJE=1=*z?-aoF#oZu*~A2GXQTu5GNT zHx9QkZ>SgBUavZV*OmF#ob!PhphTfc_dJO%dMdaH&A}(X2ifWGJ#u6f02&+{M+ z*nf!CCqMJZV{0FJNaX)S{zZ|1{1Yec*~!HaE@8^|RZOorWMY@f6V`b4*=I-B6AsoR z$P3j3$P1Ii=Aq1UYQ@F_N87L*`HSgt7>GdmXZid6jyAfSM*@kEiT@QB!wQt3HA5YiH0qjKnZQJV2HCLD(hWNQyG78}- z1|x{A`_IVwg^)$up6B<1P3d8-0P+C{f)ElUB>aey0V2pFDzKZ_AM3AjS`=Si#E21y zJ!V{HYb*%dVu~=RTRE z{L2&YN&gEAV=zO78tnFFa$nU=DWKq%5BW=o^O1T(v2@mJHZ==;qTxN(kgG129>S7m zw-fCE4kJvAF#+bxlL^3Z%Xd>zAO*v?IJmd0F_IJhdXkD_A@o&Nz<6>!lkr3G3_Yo8 zMj~UibaNsCDA$(*z}OUkew)X9G!C$*dgbAifeekX@@~fEA;N!9Z5hv=Z2@&K2g!{A5JJqblgR`HI^w!d zAQ;KH_vVM#)Ty+__#?kw4;oNjmmL7QeRHyQx@D*IQJFRCUr;&nFs zsRZv*yInR_TYiZ4fcBaazRc@sH9tRi_TUEk;ci|!cG&@;F!Ohx{Hc!-ETcmgI7jH3 z(0{7t3=bMSC^;X{@pm!awxYIfVauTLM85uZczFqgG$?qir$=Q$L2ej3a3K-m?nyqM{7Iv9PjY z3gq*sB|G1zCJ^qjkt^$msLC7r2b;jde*Icx~`UjTq7veAr- zystYMcATUL%mM9%{69K_s1pEP;hIzbR(++&y{a1PXb1mNjL=BlIf3ca954w)yJhmt zwF?j;?ae3EW1UqKAO}^g3|A^(rBh$$mGnRxnDf6=6jyoscXjn2eweCV^#R+xaQDug z3W$hdf-!mW(fN~AX|KDl+Pul4uP@{JFea#g)ceXrq zZ3)H%VcAmB0c|Etf&w4NkH^cgH)+x>I-&UmY)!~D{$|7m$!X#r$S%%?vX%7{w#)u0 z{sW!Bz?i6guGFcRI(F`yOsAo|_eTu)=qQ+5RM2lKYb8Ac`@f7k5El%<&0Gp*)lZtF zyP#r^+YCBXexP1ZE5cnWRcZfIZuuj2oABrtlq~urc|2hM2z{15=T*01J03Ev^j6o;}2V zNf*|hk>iU&(TWRr#25<%iGI}NVnKIfZ#QfwCMvs!Plk!cHleMeXEu!hKm72+mJhN2 zjlp7i{KRap$Dd3A0QERPKgGmL;t%F_R&qTSzL6s`1u0bCVMc>{lGKzXF}`lR2T z+W%51DHm@weCo;r zT31Ii95Qo*0Y=F*>&c||I{6ADe+z0mtYzefACmuRfZj3_ZcX@lQ~s3ST^Vh1r`k@O z0RJay*!HGew960qcTtzmk?}h!Gm+lx4~mTfvGT@@U`%-Jyg^}$O}M;${D>MrN6NQ@ zh}w6mW8c29>rRaYblI^ikCj=rxn|umkhx}9w81z zzsZv82OcN-OZcA-QyMqjr2d*5EK&ezKQCQVbLkXNT%d@!g2?|?P0ffQ!-w!-6A-?o zo~7Y|KZJxEBA}L$XITEeLYG<`WP-5#WWv?`&8Z^F+*Yk}6t_x#N@H8`fGzr>x>tR3 zRhPTS3Lg)}Lw_pawJ=V+oS6WOig^$11o7XHW~l>l2F|{Q&m92I>S|8y>kvv-54Mkg z;8VxgWgTqaF)L*N9v4$2>z^OUUptS!Q5rbNhA4A@ZBq)MGWdBqS=jzd!LxF!M&eVz z+RiZ+ckBY`vF`b|fV>SJW^6uzM4nBLTUAisg4`&-MxXS*vDg`E%jTk2iu(OUG=R(X zw%H9KpYDH!L8mL4%VsNx42LUyy{q6s&4xnPx-fm6I!xIE`Y?pop3teQkB$Jq7V56M znUDP9>4b?yJ$XvN$FfwM(qoq4w_+d;jUHLG6W#>)S+)Q39uNK=0ltxEMvMgOHxf>l zJef9hZWFoQ!$2e1#}d0|0n*( z^%t(htHXE-hwZ8#RYp5;Z^W*3Dds4lg z-dMue|KfOSka8$byWP|rT~(2;^p#ii^u(_%<{V*Cb?{G+CoqI-waotb@tInU3IQW=`0v5LLX6}|RJ3^{ z;Z4PFKm`#74rUQ*9Vs@Jka?6S0h}CbbML+<$3Wray>TUiva4K8S^KS|J^?d0jN&-l|-FLl%{{_T$6?jXUs0Ei*UMuU+3R7h#cC3HNUd+SukTkG&z(0@>1pa7?v z{GW;cN_GXo=DjlS%lGEh?=&RYgaIZ08`n`0op0PQYcLMQ({tv4yh71x05nT_k~+)5 zcbWHR7S6E{3l?AMXwmhT{R%xTtKL_3hBJk(7+`62|8vEHkz@#9uiG0*CcAt^3UkE% zo7Nv@gjQH#X#n0->0f0fl8#X1WIFhFCzw4fe|<{ffhf7_;s97R7;=-G%GAa!rf~=fRaf5FY(`j0Qls|@4h<^B9Db? z*h2^uF2x^xn=TPw$$$Q(rBBPia_+Ie_`PDeP;J5^rdRKO8)*y$!;S9+B%T^Y3r z2DtuIOj@q9%50(!sa*luK7PEQR#i(Wi(Cw_gelN^FXrRo#bC{Tcka^fwwyZ09P9&w z$yumsfu*C%Uct9fMHANK``NOb+TvHuP$?g&&gIjSo_hF3;CO>SSqpXC4PC{>H@dMKZc`YA zUS79AnT0LqK*yb<)M&@zqu>gqrr*J<^~K08`15LjOkv)oE!0@3N1 zOP&~|xc)FR;;j*DjT&UV0hyi=e&dwURPrwUNKOy_)jBB^a?{RuMcv_n_x~-Ez6Aw1 zb?*)oW6Rie)emA$P1GHTS$#}%nsObj~z`nyW8Bkt}c(y4zm8##@p~++U@RW zQFImX-=b8~XXV<8|K#HQ(0|8;GA~#_80hry`Z;wSHOrTq+Un(;J_J5E^zg?!>c%{~ zZt0w5%g!yXd#gsu-@(d_Ie!Kkbwb}}eB12)BRA0IOXIay#8YSFpFW-VFPB4zbOnfo zYy_QO@fIkS-~CQ8e2pzN9pW?i|Gqz709%7b&(Dr&Iel>a1fH5_MsEkyAN?;R#Yy*b zdY-hU{8v(`YP!I=D;-Y7|GSGFb}$qw&!xMXo84h+l|K=#pi1x`gE~Kr4zT(-(^bO= zC$=1Tv+m8qb%&p?+W|O!^_)4}#||v#^XkNEN!jK1cOd&RkZR3M=S zb&L7Vike+QB&E)0u%YEV?a_)wz#|}ovxB*x zmj3N1%>TuFD$IZU+kgHqzJ{uCC=BJu1_&Nr8X?{RI7}Heno_5@rhu9^8emUlY5an;3LLuc|(bRH1QvSV;jQRfUm-D@h{OUDXYEf z?_f-BrEvhMWBuljz7UhRK8R3DO@$b0t*1Zwl>f*-Q*S6rLw<~BD=fTw#!=|$nSd$k zYBWmFHikOi@*zL?M>DSHKmB!>m*AbucX&mHd6TPO>bdka{|?0`pLq;^M10p~@U7zR z($a_>3g)7jY}lsjgWuO%8H(FDlByU^#A!^ z|NF;R#}hyQ`Hz46^B+HvA3y*3&!6D$6ZjTiJfW|D&X+%bBJ_mw320XT{KSv{{KTLC z{O2eBC$!@wB}3<4WxL{DdsSlAJWsKtt3H49src8Tsphl-tpsCJ@QFYFoLBktkDvJS z6V9Msn#bUceyry(Z<~Kt-uQ_poV<64r{TAgpURIP|M-9ZxUsO*XO-JlJVcFeg-wsU zUK-t5fndn^za`FK%g(r3BjLB)T&Pn>9VHN+sn2s<5>tNL?IUEf$$S{V5O z5z=^^hX}$P9SXTZiFnW%i_t3=AZ-wjA;iORv2Fla#zz+vTRbdeYN3QpJ+Vz$HP6kr zi(U6`-HKQ|upa7jecjC`K9_v{c}e~&J?++FNe@+x;iS44L?Siq3lx2++aW73EnsR~kH&>Mw`~T?&>GA+&P}t0jU7n7&wx%PL30l;U z#PKDWhfFM#i6vSEtdrmZ7?NX@F=1s+uoO%Sn!=+o2S~e>KZu6J8vGUM8T_NZt#4`B z8&EL*@c(#0R^G`p7ZQh(D^ajy0H8T#yTp>qKjM_~~cS121h=+jIJQ&Z2>Z#S) z+8Sd*0Dd@s5e+n!y8jNAcj_GM{*$>TuNBJ1VvVYQF4Sbfe$SO4`#9pW@ zcZx2MoN+5n!+KZ-UdfRT@I3sAJC#r7U4vxKoeA>*PWC-*gq(n^)loghe+g-Fv^W>< zzyE%hOOxQ*TKxIe`_Tyf=6kNKpBHZ}F5cQu{JCV;-VcQ?UgVW&R}ptQ;|XWnhPWI2 z9?wIM4yiy;^T7_Fqn{LxY0}U0e_OLQ|KE7~ocQ^IucIKmwWI3kkAN zMi=$&;#FiunED`-gv_w1^X3SS=-RY05XkuX=Ua;}UcBFR|IaRNr5@MSa6g=E_x~Qz z^ULlEUQEb-@L%}vv4kTK;s@x?;7BmVyc6F=N=n&+4aMD!FjobM>+l{x*f`yJUstF# z%QCoZu5>nU&)`4N_b&GrXJe`3ACk`%*}<;rbTAsVDl2ovI{)ea5r|t&j{DGL(iUvJn(Nk)bODNV%SPmUrsOIC_vc7VimV1MGwl3IWMNESBIA zW44V&akBn;1TxPdY=8{9u@nu#1iJ)lW;TYI2w5+wi4-(pYMLBN@$l zQ%R3I1;)`E)BZm}ZYUVaWg>RAGU2@P^>k@N(bp^6ayf_J6F3P^y5;p%WDz@&fjx%K z$eD~Ip3Oob<_xuh8@F5Scq==C8BiA)N1!$4B%qq0hE(6xEB;b7$Zhw8djj;L<$@w1d658JJE&yg_;&J<2S+_a z<%x0#%|vhSbaIomTbYOi>^|9e+|i5Ct6*6&-hc2kmL^`f;*6&(E9~t`TY-?||8@5X zwn;@KRPOfJi@qK&E&jK!;{yaDId9ggphu=%9w0f+uaF%NwjzIdx;*X0#_)vN2TXn- z5HEM69q~*&PA7G{yp=-Z3{Nd(rS!rT>?yyP;8?g=e(`uYSR2+z)*XGn=#<&ws6ZK9 zp^F?ZcA`AN8577b(V0M;R*d$^3}o##C5l0o*~S9JV)U!EA@EFiE#4>we$`If$jg4U zsq)K205tLy(~}8gLK(yEck+LvN=ltCRA>B)thlEd!UMYjAD7xFMKBR& zTd#aG8qSo5vfgky60mH<;yer5cI2d$@%eo4gp(XVK@(Db%a+P#Sq<62K-}qa(n^rl zN>(P|WCH>^MU%Bk&S1u}Bg`1H(W70$;uja2LmkCnx1%T8D{$0hLKsw9@?}^<+reBU z*kWwK3=}TZuHeM5yjY41be5b$2%cs}^g}$GgJZIyEv_?~vIb1a_#@)Q3_WI{=|3-+&XmUOp%{Tr#AFAWKtBb;^g=CY9p!eAgMkMgCx zR@!dOa*MD7K^K>)beJ_q14F=x*%z!+z}xS&di*|b#@V1Xh@h1^12EnEFK;aCJqZTe z>f!umca$3&B{PkwWJYAHLpL*!se%F3ba2;$%6^g2LfQuD62S#pAI$@odD?)az^Wv{NDy z4>M0W+wIF)j&!>(>XNcBIikcGgR34^=~>NDQ_;$MjMKguW$$0X) zTw9yl6ZRy%Ian0}aYq=CVJ?t!pv`Rbki~79!J!dLl!wxg%U}p%<<3YJlY6l@9Vky6 zcSIZx>tqa23N3m>$Ca))$;Nj&!&XIqTM}cO^hey@fHRZx1tP7ETrQc;`jUYRmCH`2 z$LE8v$P1rASGvF5OJna`+RkG9ZOakv_oTh$s0`BJJ$5TPSBwsVH8nAn^>0WO|uQ%MDOL_ni z#Vb6KUicK+X(<%;_P00r`kR~6;U))Vj+3%@nw~{y`4l4qm z-^pA692e=+_a@lU7A<^9V)zT@8#hLk@`Tu*q=Y8Ji$mpaYbm7D zq_hvG4$VjibfC)^$b%Azj4INRgiMB!!;v*8q?E+h=}1zCjH6KDDq7VGfmF&Jm*B)g z5yswD3(`^Te5ant6in(DTnYu|FR1C$*z~v-6>|_$1k{SzNiIfb6saTv3U`_!(II2# z)TENa6<~T^fdB*7B1qLqvF?`XIG>TCo*@a0=EdbwNSxM-97IKVMJl7kN|cjaE<=O_ zm=#T;D3dDGq>xfm?q_3jygWO7S|T+^{CBGo^POL)e;JcQlY@*WJ;2%P~+SRg_6;SQ6z9lMTPo> zLZ!s83ivmJjYIM^B5VpiQe#pe6pGNeou0&mi!%LslZx4Nfl$iOa@8UMS0okTfV>jt z>tm7%hEl1|OFg8-xcwNr1nWYG_Dw`W87B5ZBOMiq z<&aXxr82a5zeHMrN*Z&VNez_(s^&QL6Px35Ig{b9w|{I{f>DC=NqR&LNl`L%*_v5P zwDu_kq0nNUbV~+7D!KY-F%*e{ui@kRc#2wpLF6P79G@^`q5eN*lYg6H!-_tRYvQAs zGLnnjPvB$#Tm?Z=W(e*im&AF&e1<}ckzp80l|sqKmRBL=k*QHSX>mSDA498BVKZaD zQERm%t}w<#lGqU`Qi@2T&@Z-9;1{(>NU6|`V^gE`jMgBPl0U7k&?|>oy^VqAu@hHJ z3UMS>ARtH_sZ=Xb<1rM`3X)NS?Kq<)1TzX1DdCDJ1O~D}1|+yT>{_Vv7!&&Jtr*u? z#Z_YiA_bKSHD#KLDpXCKR?pz7UhWJQNg|fi5MPAgW2Pd7sfRzEuR?I;wX{|`2a(zk7GIk zS#-3P$(-oZYQ)iE>M#Q%rh&bQo-zGg>*W7_QfWqGbaeK27BNP&R)PIW;zms`QbrAP;^>` z4rR4kBH_+(m3pQ_v5Bi3HKa%(pJ^PaDb^AX0?SFv zzd$HwvXu&kf=e=HsRR|f#6^ixJ0oUHXc_ndCYFSu4_~6x&0ys3{&D=7AP9{@ zg83oH85A)TG*WTbVVX29A<<~GDEU#w;o=CaB#IQSW+ePJz*OJ@ETk3+2$HJLHI5A;Kz9;KzDxmS1~U+-B&r#S zUe_RrFg}5XtKdfS#e(c{G+ks2F^V6CN-#?@R7g(L!ZJR-8M#!W;WBhG8AGNKGbAEZ zr9yrCi!j$K=Cwp!fIFHaQj|w(WH&CCi;P#UVc9rf`(p;6nsTvqmiF`%KBr>JG@W^C}apY$-j*$a&1c@q9|B;KL?~O&k7xR%_Gz5+z=@Us~4^*or zspz1xq-F}ROA`#)1S!%FKuHJ%NluRU;W#uJKZu|zBxu*q3Mi@g7iP%L+qW%{Mkc63NUSPwZ z{f^+Q0xcQ7xDWf9TE>`}MO-AKs8HFcX3$N7lVy?EIB=G&Mb1Q%NrhZ4o1yBtKpX8m z5$&uY__*?hz}e+`vCPH(I6aA|tl~R_YKRWsBwwGklybQ`J;>tr5h?{&!N;5VnhEs_ zzj4Z}-z?^>BuOp42ZbIV*KVLmf$fFXBdQIO;LfVl)5t_RE_wz8*trldzj-!d3iJ*l z{6tZL&>3Z{PL1wN%yurN9A>hx`ZmIj*F7g`^R(BawAZiadvK%CXwI7X9u0n&e@&zH zIOBgYo}2HPpLgz>@1b?|M9WYYB1y16^z?{nUCupX=Pug3^Sn&lBc7+xUNbbb9zN~$ zKOZsrn$|NqI!X&14SYxh;>HLJ)G}1E(b2%b(NP?Z*SR0*e$_q`)Et7Adeu zfkg@|Qecq+ixgO-z#;_}DX>U^MG7oZV37ig6j-FdA_W#HutLb!3REHrBG4L$Vab$7ElhH{IlS;@(2W0 zw}aEE=aAEL8iJm_0+*Z<;PuW|kc;0_+7E$&PyzmregvoNlVG3Nf%V!9fgftIT&KY~ zu>@Q*)FyWc=|&oFr1p93SeWdO_|Sc%^Q zA88@DupWq!k3m@0ie>x>yzYDh>DUHNajSrxSPX(yjS$_`3(MLML&~lp@R!#^Jkn8$ z^q|Ka0+-A~0A5YNd-o*-J<&nQpbA)thrm8=FF0Yj{qP-LcW1#nw+^Ju`#{pD1Xgkv zB)1&|=jHoAT-gi;Zbe|fY!CQMeg{snE-?4a1ybGsY}Ka_R^AMW+xoyowj0vBPXUpB z2#WZtrObEo}n-ygCpe?L1c@Zdj@>)9{(vVu+oPhw4@P$&I5Md8Kh|)n31Vi&)pDQ)QCJc0FtT} z$i+4>unz{wnr&cz^g}T4ZUOoJ^GJgx@GWftUwoFNsu_gX_IB|Ka82oeCH_fZzx)7% zP5%R|Vg`YoGX#;1J;1*7IRq3mfPMNf_+a}-A#I&beuVYVfdrpNq^iId`G{LK4ngZX zU}fhCAQGFwDQOR|vyXx4(k^g1^9gvXzl9*p&)`%z4)n-IV8v{Nps63g*fk#57e52v z2Xk1SpTP6#U%-0ldf?vr8d4RBj)?v)b z*GD;;Qm8dKWpXN|&v&H>h4Qe_#N-skgwogdQ2Ed_1PY?QA1uO^?IZtoHvMz&c^_tT8lHK}V z&VTxp?{w>)Rj8F!B;Dx#<64t8N5V=j50(2{-DL9l{5a^@Vz4&5AvIMXOdLzAe8l|y zNT|P+|E=rRbdqjdYcgcy!Mx{xc0n$;lEYYaBfJhi`7D9KYXOT&@3gUXHy4Vgrq15G z4%Q)UzQ(MhbB@F#sH^i24YeA%E{tnj*0qJ2?y61>?g8c)XKZ>QV|s8$1q+%BDhsCXUGlp$D6fOKF>88=sGLRVB|Ub! zahSgwSqQZXeP7+-LsbotVWPDq2lX8ri*YOWvIBErR|L;p1SSaIktec zp7MLYidveN8qxT=d4hLM;D70+nOyEK2Mdca{y?Gc49nQW)QG?)bn{NU=Px&NnzGy+ z+sSo*-PmG4OTGJ<-`*)Jv6YKGbIi?cz|_ZwRjUn&@_72x&CP49dZF&pATB=r`gBR0 zy@h>iPEM*{M#kXCg1b9F<0J3L5XTT!ZJ(*k)BX;ov*dHeit0k;ewLqAnPZ$lX6t8` z8D?@T@kr0Ip61u~%<4$f`ys})DMPZq-8u5wz0v-WMS;_;w+F9W9UV0nENdMPu=HE7 z5(nTcayI@L_h{g|s5Vw@q3qp#G0&*=)cTWbrv0?o>gu-5n>Jm&x@nW)XGoc|%j$Ef z)TU=A*%meQ`*=NN^4+)ow81suAFei^vJ2ck6z|!TAG;=*=6ulEaGUtUM<X>+#2?K|2f*%FY`^a8G|K=n-7a|F68e(mi`dzvfCtoyP9O9E^Ao_Dw_f ziOdJ4_lL@jO>P7wQI}l27-O)O_EAeu^SMp7f4X?p((>2}=k<51Z{Kd^rk*pnT>9HP zudEBB=E_+nAwfx(W0RA&gw_AH`!8LB7OEzDy`SHeru-$zB~We8-r8c2Zae=@`>TPE zMM~rc89qPu)oz2Z+zqLxg=_&;k(!E&9Ixhoky`SaE%@}=fppDpKeYeQ{N{S&LM+ea zc}7Io=ee;FFRGc%D>g6~SCFXrOBjsTjcjVV?cb$R>8CAhYf97*%lOpfpOX$~E?(@8 zDLt6_s(?9_zk!>4_39qO{M8pPu3E-!vUOE|bm2l~7yAL_%#bnC|HmiKVpH2&p5^7V zGrx5jH*_v}wP#P$rhJ>zk^rYi1~zwJ1%GZ(?|S+H-Ny&pH|X7c)C3+c^DSNklj#%? zx^0yABEoRwQ#b12ZJvbs_s{wUMPR_6?Sfy)=Y(a()L`ATOLYWKBFW*U4VVsvu#7+Uy}zA_As6lK3qU?%bAI<@!BthGTedcD&D`32$SO2r z@7_yw)76hKF~g%rk-fgf<&O(VM`9;#`~rDhhLhRCw#|m=r3Z2kCMr4#z7JpU+}_ z9P-jLj^iQ@z`$B{b!T0w-Ps1ey($aq=5otUR~9T-T}Qzr78h_h19V@qoOQI#(IXB< zkTQ7vJ(uc&*O}D6M=-)-sCT75Fvnc3*WrV#MtLTW7s zZEncNhnykF-Wwr9lcpc{nVQ}RnH!3q3CW`S%#l8HQ#!rkgO}wGKAD*bsfc%cS#iJk zWyMP)N4zEK{t#V6A0mBcieDC2h>CrpDu#M{eNE})2gC0@DF3;TzYs zp)p{k>;;c^zJ@^gb|^e}5!^0+0pZnckcJqIec_Mbe(fs=tl15rYfnM+x?SL$x*t*$ z$H6oA5MrC3AqeeqJtoOS972z7hM4v3z(K4>rqn^i+IGaYec%vZ3bAzx2rN4SoZM4j zgm^4s?GCUIH$vRj0Z83_0&(uoAjsJQWYrCbt5*QG{0cbAI$_10Vc@F2K^!>(-tT=6 zzVeO0d+ud29njS zz)akY*jWY9H9KL6R~pzQ^?>jDKY+A;54dL5fNa+hknS9UOnjGozaGz=1^4uQkkGsz zan%}##QWm5ABG^r$$nMs5R4ehKCT%ew)I0EUhngP7Qz~PLEd*B=$YqXIpR6nnC*zA z6hIaq25wp>*r0Khg}B4QC+7`jCNc-X9sL7(oE=)<4gUGq9z_=+r0Osvv>isgb{Is6 zMT}e%prHReVmmGP6m9`m`3N{9Y=@w#A;`ye^C-Ixa>V>@vZ^=uDF@5$|M({`aSj0q z;yerf3Z(CD2+;flW*&)%;}3v+>H)Cu&IUL6dGJ75dak|!BBY@+V)D?sE--UTK>XMS zo=A5h{Vi2nrNh^?12d`-JS(pOxAY?7QXK>!o{d4jNC4752XS{mMJouaI}oRD2LBI!gdoK4 z7P4VjTH6WX8#{rY-w&p4$sj~ugzw#N5$g`YmVz)gyL)%{?$%$~YkytKX0Huf+x=@d zyStk`Jlq<%r6ApkmtL3tZD(gVCGRMci7CyQ5^ms>))+hHZcF z3JUACdc4#!^8L&lRUs|gyE;P~oCT@|BLk!NuUI;`c=fXvN&}ozOg>f`H856ReYq#? ze$$s<<|K|5UQFq8u=iZcrkq{M>2owO&CE=2ziRFsV{_uzXicK2$;A}M#s!yO!>rD- z?D|q1CC>zWsW#1TZqB`@Vf6jy&Saz=_n>`Ll+|P67{|oXM3j4}JovuN{+5Z&)25OX zM@JLE%)5Nk33Hi?UK??Fyvj8 zVeGcwGtJG*SM!}CQwC-0LbDI~ewHFiUGc>)io;8-g8JEQe>bDQ7K^1{_NB_4jQ<)# zy`L)i#?5?**!aG~`g8reqffhvtK(tL-F?@c8*`^l#oYzxORIh0R`%ci5*-oMAO4Xm zwJ9Te&q?Ws6TSAxkB!vtm;JChG`l>jsVRE>j{dflu1jn)ei0Y{z}HZZ4<5R+#D+oB zP8rwQx^sE!-)?O??Mi<+uh7kH`ch`xbZFh3B~5&H?TbApSD$!q+%t;3{j}@-Iocm5 z5_8Tx6wjS{Ap6vo+8)z}+2$J!F?NyjC!6wkBvR@WFW;PcmFT<=i)PBY;sLf98EYX{5|M=ztv8b>dJt#rHScuf_8~Ve0FX1=3L41 zfs1xEhUbLMts%1&S1e;=pPSYz-8FQ~w_bZfIcoZ6XUi13_v|CWx`Rps9G#sxxeZ1Q z3294?$1k@jRvHj%#rpmcP!wOO4LVsGPh zg}9u%X6+UABq>6;KB6*cqu1=Uv7oW1>+RRCe_VQPefx*!uAh7BtIJyoilWZzmklY*i^eNe)v{;;|52KM*(sTW;}E-d z6pD{r2FPdtUiKPDZ94+4s7qI$z5~8x=YT}H%&Wc&oUDF)KoI(?kAPs~Bd`(XL-N*s zs6KNCj2j0aw4oQNd=mI;ZUW6O7isG9Qa=>0L3>6s!rcR{cr{#E*~-#CxMQ>X)B*hd~YA{ zs@?$zOagRff@kp66 zLNe;jbhNc7HNC*Ay$9U9AvEmPg3nhA;Q!YJAeOZOGkhI*6^{a0cn*pWU4rGUXg3U? zo@zS^@te{9slEk}jC8BI29+mof)y_rz&H|s5JGn6DFBZ^@G3k3GPGg9)B%#v)=6wa zpYZD2ux8{A(y$Onw8hF!yaV>(HTeEYpogvo5S2noOFy_IpzbUm1MkAKK=aK3H!Qnb z-ZAi8*^k#%foXmV(9q_g`DH`?_Y08s!ve^0kN$Q6?W4mWYZ=74Ux(!H7C`v*0@R$n zi|u*~YR=sSukvfKV%IT9YC;HE;e3?Xrm4SzwA6fY$dp)?E&ttVc_pR14Rc_K;x%D*8BqSt8YUB(#dPrX|M~9 zhw72rP=wEf=yGhgOn|f|NNqg?Jfs0Vs0hf<7r<}NIat|s8f>;62A8Z}0NG|p#`091 zx((jQkKDrZu;z>!TyqbDZ{-D$e6s+)Yp(&6?gF*C`x9$O!e?LG# z7T6&D%8y>dx(vYbp7TfxHJF8E<2c3+u;fYseB+^P_#H^xx(~dnu-uAa2&q?sZ_z2V zA9|q-+t&km*9&cEw^nR}9k{ojfEE2JC^>osY(sJZ>h{7)Y=@%3F4do11@QdK0@6VZ{DKqUS#Szm^UzjWeFdOK30}w-AVnLz;}noPPhuNQ01s^< zUg;GqS3lSabHO8T7;J;`!O|xk+|Y*O`*9h1J#Q;m349>|rA=BQ+ry9NA8)l2DZ_;Q!c0ScU13vbd_Dgw|jBE4X zFRNMmod?5`7sj*nFb})n;PbW0eZ2QiYfO1be;MN?z0b~FbAfICbDf>IMz-5KV`@)e zy&${c!}Fis$?1;Vw}kUI=4WlIR&Dq4QrDB&Tl&1by#F4V8gbput~FP&BQlS*CnTu7 z{alKT_ohuZp1Zs(a(J0k7`kKCW^Z!i@fBPDv3;}kj?j_>Gl$^-ZQ-5dJR>8g=|jIt z*Sl`IuXu0UTdkZ8->|d%Uv%ZU8v65pSWh?lO}-{1G5q+?^%dOs{kOOqvn;k!DIeE6R(zC@)?vr|Y@_rP@igyY*&n4xALc)ZJ|Ojc zE2fAR6MOp1FSl=Ob~V&27a1A7+w~RkR~NB^{gTx-+md~aj9y!;box-V$*A)8%{Io& z4*P?-Ey*`FpYXQ8#Ip^=e{K51+sTD*6_gLBB@MNGyPIVaRIiJRyOgqh*Y3gogeC`? zU-*tsthY-F@6|UpHm)!zVeQ)OTlG7K4OX9R?##)M6dtP=#>M?)V3QGLEsLICWu`ZY z3z&W<{gwroJ@zYJ)|5UPu-ZY{;m{Ghb7x{=X<|7iv9u$&d|ilrQOM+fXq5jaAN6|7 z8g~xv|JGws|I%G}N`LarmW=%>31!?e-2L>jJFEz-5R(DF5XTI=!OT4#90D^zfPKT1 z!voB#2dvw|-3%_t+#`l6TCkEI_ z84q!rdch3Gp=sVIyRFz@6R`)ZyhFerF*_f}Pd&a|fWXyl086(31Mm03p%ll+jfm5B z0n;-ASP5-lDaLX7gq>hOM1#-DUNCj#1J&FL=n<)4kFwFoDFkWw7QR;oyu1c5!ScIi ztifk)20OpyV9H>DiJKJ9M}j561y<}9AdrqGZgJS&#W+4b4310lP@m)YH2Oi{qn{CP zD?o($&udi!Fnv?N5$6q1W>8N45qG;lu=UFX6JZt5B36LopBE7CMuS^YF*u2fA-tgr z=sqD}>FEyvh$CGROCe~(9^?ek<&22arUm~6;`5T(UgN>ayusNvhjWE+He1W^r&8&eL0+(`1)<=^dEsR%BL zI>0TxklOqH)CUKz9XZtLCibaV{$QEcEgJ(UT=6czrJV-QVr6vBWXTOU2G{Sx&HItC zlw%fG@(xI0>t=&cHl=@W@|IZNa(J6cOEkFCopaRTR0LzY!Fze`RD+9S8+Su~W_YdB macfevwo>T-Ve6VI)zyG|19panXWCsxPFk9cqrv!pxBWLbt?cmt literal 114926 zcmd?SkAIWpz4(1&D%BPUDc<33X$)bs2$q`~QZh6&X{14_(h`eeMaoR831I_TK-;bZ z4OX-!$N7t)SaR5=wy(g!?^flt>HO~NCOyaFG#=*+E2}=o=Q%$Fc7UCy&+~%iJnzpH z*mvL8>-!%(7c{?m=en=Y@1NIIO`D<>Yci&2*JwA)pQ7#J^`1SK-`}BWLwvSrQ{nyV zHJbMRwkcX|?dA6~H0?XDOws1fz5MjO+RT}S_tC30ZQ$oq zv>UhwH`KJN3ZKhcZLWN9d0c*Z%X|N>E&J9ZntS9kZE18w>wMvLZP`ywX}52GT-%UL zYv26Y|Dmn^#|zrc55K2X)~(Z;cRi&A-}_p-b=PsNF8+pgXZJp>w*8;DIjfn_X{fRjVJ?Zsof6XAWykz2Das z-}8*Ndh1?oaZ9h}zOP$b|Kuy$lC~GLK=wbin;&{qyS3{nZSAAHk3Xh$KKo z8`mW@-*3)qD<679o4x!YZT_lmEiiUg`^L(x+D#Fz`N4=*edliN#=reXE%4!a?ZM|i z($+rzui6dGd$enH4T zlJ8Zl8qiwz9n>0QecG)9C$-hNi(2z1|BqI4-vQSAnD))BqgwsjUuo{n*R(~i{Jl1N zVNkp2?k(EANGXf85jUWA|cKm>Qk&b_ck*{^kwZ-2(@-dlJuUjo{n=!8xsF?L*payHeUc`(Dy+XRXcOeOBA@ zcG<-{|fAG6n`03wr|EIOUM}N}hH9w_Q)ZU@F!p~~;|NURI z(67&EH?4k1TekJMws1pQtGOq|wFBCUPyQ3U{Yb0%)~njWJ05^u7qo`0PiXBg{h!*( z&o65Cg4cVV{e!lW&sY8ZAGHN5quK`65W~*t@=HD}<-EjB!!R?S1fk!tz`?}`vuhZ7?zJBwM zwGQ5|_|Aald-Drz@x~#|Z2P|E-*!xkvF@AxE~mBc`-QghgA3Y{*fDLvx*urYdiF=m zzeijB?Z>olJ@X@;_wfEP?SW@sMK<;z2S3u4WCYGtNE-G{{7Z7uL9R&+D4x5 z1jaleq0geV zPic2VpVn5zdboGLc7N(O@b_cdO?U0qR{Z~cw3Y7J)AiJz_C0FU*LQVw)wj!|yr{3= z!zcA!dw3{(Sh%38tF*MMR6VNe+SQ{x@S#kwr?iXD+V|A&+0*{A{I73s=UuzZ#^6CN zWAJvk&_Wb2Dxucq$ zncCay_dHeq@>BLUsNd%PFMh@JrLr`6X0p5U&^`}T%gv# zSKICU2+(qudM4H@A)U*?-~8~MDnURKKM!dhkhtuo~8fDBnCKQc|>xvPFO)e88H zD_ULuX?Q%Wp5=Sg3%gwb*Uk#$AItFYRUY{*gGuc5ZilDcZf8C6iCp3K)OV>R+Y30f zcNx3|*$NWA>Q2eGnba-wcnm|nA=4U$r(Iy>YMJUhI0IkIrm$vr)Z1mvOe7a^OPQ7{ z6@ug&p0tNcz`V>ZgUk6f*T`GJmfQxAWCG!XdTwXf^npg`zo)gaHTB=z9=pTg@TJ`z z2QNM8G}p%zlX8CC&t%lp3=2sp_=k_`bZ#r$*+ugqQym8*` z_IR03pidiS+U-ai4t{O8f!b>TxXfXsJ$ARD=8}m_`J8J&RK5J(unT;Kn@b$r6ga_z z(1m-u`SExRw-7GvNIQJ2Ug*OWK;I75kW+S+HVXngAL?2QA- z84)f3FqzNJcfF(M7vQVyYdu8#) zaLO=~qdwoTnarophd>__c|7^y(Ii*89lYTdf;WfaTF}etkfZ`Tsf*JdxlDM;lQz?Q zjXB&NBM+jDNHSsgyoN9DfV;UN>w({7a3>MOdb;h6F>JyQW&(Bq zKYRj@;I{M9H#%$^cKD(`ug~EdHC?9Z%ct`p!v{@aC7BbMhG_Nzc(6av zz!g3tj|_t6v`6GDZ-`Jbxsmn-c<1){Afx~*+-bmq5P)C8Wg;fLlqcRmAcL>L0pJDR zgFOuom%?+YsOgI6@7PM)DsPFF0{@=YuH+}S##Z}77M~+O>TtP)zdXihXgCmnPJGLd zH{6`LLZfM=l$7xKQuXP)+X#hxMqt<%$d4MMD0{mR$@@%K)aCLG2h3PEP0{C+cg9JFEyh7 z_{lqMt-gnBhLQB-N4?yF+nO$5NJ8L50-%sEBb9&%h8ILQjI`+rd42UP%@-JkK3?xI z3p7y~Y2UCfA27_}K*DB=#h4}#@VMasJgKszy7|x@CSRPX`LLnfq!`F^<(w7gh ze)-hr3Jm#>g1j#s2)MYE7akZB0>F7(;6XvPLt+OjLJLCedZZ&=kIakiwx1tHI!x1* zOa{C~2CeH<@y|M!k7J%gZf2 zc~jI9Tww$PBHgSI#RV_g4No8?3$de$K}p)^S+d;+8i~jv(+};re{sarlfD! zNMvEERJ3|DF^oC^m%|_w6@V&1PE$TdfHm^@a0n?3a2M$3O}86)Gc8mc_Id3{xX%=x zG#nuxav+k9u=;%G%_NYb;@oh9Fx4m*3!c!MOb+Xfg6TkVXt%ws@%Hb=V|Bq0@YfFj zhTZngLv4-rEtO_IYU+WcE0r>#Ys#!P1L?Ha6$~Z=J~3F{>I8F`e2SLzCJcDq;f|QG zQK;h+NoDn3uLA)H_^Pv}E8sHo5fBesy4_yXWIlx?1{_@LNCxs~2XoXhjK+zKrbB@g zq!8KjMN*)_ZU^RMz+}Er7tF&zL`>Z`D&l@VxcCl8UD5+7AOu#krfoLiPgf88c@EWL#M8r%5Ldj|y0NShd%uw9s z(o>Gm=xBb}kz3%f~T!dIP6N5*zyE~K!z(lS< z!UL&Y`E1tAGkrESeBN{+ccFyK^tuw~;ZB(bSrQEr@fqk_mjMAnW&o`h3RDj#d6)M_ zjDTM9SbJmZEw@+)t(Ma*?Uu$B^{ocNI%;uL-a61~e{4&}6)|0@>WC{;?TUwO+zAY) ze34`%8;{1~kz_Iv$wT2ZG6ptumn~?*8EAM60Mg^mC-w7j9VYL$SZvicmuZXZu52Xf z3V0o0O!N1SU zC(Wd8i`#U4lO=0bgZp8x!)KbXe$0l&$$L}Dq#n!ruvCT_s*dXc7trFDZ*JzvbrAHpgRw@oL@X8qxK9%3;QBNnO_ip@_rbO4>3* zVT;8QwguyY7M~ss>Mj?s!)HEU#Iz+-v8W!?lcr&b+q`<*X0b7{u4E`1O+{mTpy!h# z;gNXI7S&zBa5x^-^=hzfgn$!@CF?eUsz3}nr?nAV}Yn1LOo<%HnZC0vRNN$YfJOt0JI(xXvVFasXk?rbnvZKSw0|6LA` zX-1RSb~BJwuVcYP!j*Let#MnVB-3Kn+2WO!F!(b<(WDuP$MiFLIHp_bSY+7NuP5BT zNC?Rf;VkMpNZM+~f_2<1g6u_HuB~P?V(Q^|T(7IP=p!vjeZ(4%Mw2Yg8crsX$yhd< z4L}9k$Y>;K>L^-Mua4UiUd(7d8?H99uB-`(0=k(^>XB^3^2ROh)~;LL*ljgV@6KAS zA^RZoA85~}(iWRNIA{+3puWvGeM=^uFpX%PB_6lcWo%yVB!C3gTB^b3t&sgi~V);lYqT6ECdc4k- zG`$g&mB$eYxWrW0)`Tt4H?}5rMvv-IZvftN*(@1r#-eY^Ff9&AG8?vyST^al5gQU^ z>Zk+5j7TVvb|glEsZp0+J!%W^xzxW zOi9u{L&1+Xr(#aRgVj6)5OqKEliG?WUt zVD&&Cg#N(1`cN;nXbhQ-=`J1ctYI($9ATR+oY)$Ry&F3ddnRTJ*PV&SgLT!hHJfxj zX^REp$@7RV@CR*c^6y8YTVwA>*2F$WL~Piipv@YL#w$04MgD@C&EA8oe)62Koo}QA=e& zx0oLBe_Bhi-qF!yK4A43x4#f=w4eTNiO{~JB_1xR92&~>XTmmpByX#O@xqXyuG(g^ z1oc1)K}aUdBqqXD9Y+;pZP9ofdl3M7nn=X*I?Nn1hmn~` z#8sVzxnkAkd2C0FVT;${V8SFxToYqBDwaQq60wF+Hlmtz>ri-T2nHCuCEV4Ry~Scp z1WUqUOUYokGVZHK|Ltk@;9X{Q`>18eoqEGs^4-BkyY0KX>s-lT5cRD`lTk}c*fkUg z>cL72&QUU&j|2$QFlnwxGMY>p$s|VChp9siMWb0Plnq^s>O>CLB-TK68TZ}y^=)7O z`tv8ASo6DZY%98o%U!-ygt#f?ioP3N^YrJRKmO+Dx83&jeP7G9kH7iqtI@4`Bpk*M zM+*tWx|vLwVudWWkvd2m3)oCEN z-1LIg@Wbv7Z|o!4e#lalFSRYlR*9MY2*t_8x0Nx5qE?* zfOPj)_G6P`5q(5YMR0BPC`dLF@gY4MbpSbXfxrjN6bfS~V~JYNBw||=kKcA1T5H(VDyV*xoyriw?C@58oW>G3y#y>QjzPw?vNHxscnk+iur>cWhf@vxq?z;fAW z)|GO2e8{_wWesHYkfG!%)VT^qMU{FiKaH{J_@IQsVROF0n*M zEJidQ?Xm)YTUWiO-Z$zBgn~Yw;_6#&Z}jZON2<%T#9i@B#$vHnTH;|~&-9mM(1H30 z8X?{fVqkb&)l>qH-xG=@t7E}X2!7zKF%8LsJ+w zUyA>S|5Kk&+kJMAYsjltzLBwIN0)A| zB<4tL4J3WutSuM>>v3!4rf9e%=8f4b`p0iV@m~PaO*aAjO*g>`zkcHLci;aw(_d+^ zh5ON?;eKl-xMt1gpa1#^g(0~N;C~^C;N5qFdNh)4smsPI!FM)j3)-@7N8P59pe^PY zjiR}eBBzi(*wT^-V=99!8Cy1}kD7WmG-}56NO16tWLsm&8)4lHmRR-k)}SLD^_pRy z_&+PU2D)%7ZDH?Fwh}{gx-wYVAHU^=wywx`-!P2;DHoh^w-NJ(&}P-aWOcmS7LQfO zT;@>17>XK>d?XcdWl@7RJa_b>?!qn3+6Lj1{u0Z_i6@@^#cdDV&3NGTd+)vLoA-Qr z_1dLRKW(WylNq$ct=2d=u$>7eUj6!}pZ)Ch2OfCf_1Euu@2+ot@2ab>(Uw2{e)M;B z=$(EYhd+&?t0p4#;+oY3lWDwYk0UnZ7!8XZint=akb`JhVkaX>PRXItWgesdG0#BT zmXc9@BoMB&j@VAeE6tLA>_Xl>g#TY!>T#H8k!aN7!&LX{mfig&x8KrQntI{8FTC*B zpa1;Wt+(F#=Ra>LJnWXSWjF7(@ZrsWzWLTITW;OGWy{Ss-^$Bdw^Z_5es0}z^PlDS zw{H2}uYd9DU)&8?!2Z4O-2+(rc0DK8%WrSxYyABA=9{<7n8B5D*}dvAu%zu;Fvv}~ z`>i)~kKIhWyK)P+<5o9sVGRska=~s^!!Jwtf9sY%v!dO6jm7ZspZTt*wXMV&)Gg6e zP%O?MUKW}>n)G;)|2>i`CJ7S^m?JtIS<>Hf`x`^n-M6>4Mk-@wOeZVGf3jn^mjRo@ zm%y!&WB@83<7d-d#KXiF$w(}QDC9BaZ-OYgDd1^V58Qhf;D7YdHP>jXHZr)ZFx2zqsSBUTcVroDJP*h+)KE*h{GdK$-W4k>qxETf z-sLqdBW7I~$JB-)*KI~#{QuJWl#$1o#<&3Sk2hPL~f#L zQQuq7{{+@Y?hD{An6+`i>f);XRmH^({%wAL@r2*GZ5x-}IA#9b_lkbFX5T(-`K+%N zY~1+MpB63ShRe7eH$A&}@!4g|WCeV<`0QqRIJ>!MaYeDy-@rr-tiZpmue|)|rK7#Q z%}2{moji4_xw*MZx7*2(;6ad*$%IQXgRnW_NgyKrUssopOfx~V8LTd;L?iWE>Tr&d zrz0nuPd1-AS$^^)bI4P9?X)Agn#swU+!&8eXD&DHcaD$e{JDwohHVYow)GVI8yXtM zoi*TTvSzGe!td`{)HiqGjRorO)3l|_7c5vXYgXCnvY!2*3#?5{fQN>%zDIuY=zM`+ z^xjgDky#67EvPynNXpgZa${p-H8n?$9PvAyPXAa%1*@2>DVm%tnk+iIxMG5T6%{%D z9hp|!bgH@hXfrEk)$+f$G|=vF5n*R_vJQAj!NIUCJe{+4E zvi~bLaiV+C+=ahUMAdffT@LIrRxc`Bw5X?HqL>MC4GkxH7R`PBhAH#cJ#g1OpI*at z3!YoBckhzDOS-FixPt$TZ4F1dyAK{b*wejZTW&D~0QSkr#gj#wmlc7Y9Nbm`_)Seh zu6fO;jyCu9o@$;qZ|c0(WGOkuKr&Mz(OftaFUe$D^l03X&a4pl^*~oLDK322RuYVt zv_wX@E>L2?@r)(~K6pHNvZ=On>JC6X(XfBpHrC!Ft7|Cs=lo7Z7bkcqZWxC)K)<+% zk@KG@0|D^#T5aib3U&qm>eXey4`?}OMR9Rex8nZ!>s}Y~?^>{T!IJ0pKDXpK;IG=h ze_M}$&&(&f4|ex-Z`*dzzZfBqJE#Y64dILUH{rhm{=D8^gcl}g?rrXEbx{9uc-zge zk;;x(OX3;KT_9W%acAKFfzoW=jwd@B%w*!H2U|{;Y>L}#b?qhYlMG=X9t4f^ns?R; z2lP0LAv>JDt)T}l;1vuE+=w7D=r68VwsP^x%`1^vm>>smi~0b6pSE<>fdf}CP`0QH z*kC3lL?_DTE`Hy z-k(4M{2k>@<+9qTQ>S)J?VUFdG&BRhyOo-sK}O1~hW59Yl(djs3irE=7UBPaq{AJG zMkNUosI#>6XENcTu+3g+SKuqynQ!VmbU93LM?`o||ALPY@sPN9?E zkF0`$Jr zaDQQR1OG9<6Ag=wRU!`573da74+40B5GXWEOrVaob#yk>Hk~{Lt2C)y9EZ`Q1@uD>4RcYRq;73@{)bWTkA z{o^Rv+=Sc=?Z0_5D(0-%1CfA=+&Bx$9c=ErSlfxTBKRH9AAW^*Po3%oetT&>2GH%Z z=7-{$cx+P=M?M)yTN)dwl}CM;MvoD;WQGP?p2=9x_(&S1XVi=QpK4~NnKPLTOCYKM zC2-*&ikr2dik-P}wC?!0qQ5*SeV{b^F@Yal(E|s}ee12IOLw9Dfb6>KuD|~J7hl|7 zRt5s9s;YVbALX}h-2)H2chA-PR`L56U%cbR>+a}Y-Cd>htFS(I~5~DMO*Q&{M5XTnKL`)%~JrJYHsrkkgV?VcqB>>-nX-(Cf2+|HT(CBVct^5Ab6kMEB2s0Of!6zNOdQamR~l ztlkg#1%+Z@0A`i(Bfm5f-PaQql+h!l= z^7uUF2nl+^ZPOOC=q03a1b)%~QG8iKTA~ZxlCklVwNa^<(FO3pd#d@QXg?GQlOtci zj}nCKbHzsl!fnop33!1e$RbhJ*o7TCy3y1D!S37+}LJ5TM3&*S+{b)!||= zfamiQ;J>@T{Tt-B0{`mO-TQlrov_)svjQL|@pS-w<>IqNxL=cq04i1-F@D4SyPN0K z!k-9eIsTexzp)r>G_+pqQ+a<+9$HQ>XUwAO5F(hH9nD;kA&%k68LML)Jhr95ASV z(W!La5buy|STJrWv1A6Vq})vN9ecU*9&tsfmdH7!8 zA%~SJKz~pW04Az10-^-_Lv4{ZfIm;H76Zb`)6r9{FAogRY2b)EywQj+Ks}BaKd(nohbvalgXVE~?4wq+AIY7P zmT)DR42RcI+0}8O_d*AnbebrWj;R;Gf_PO^doN6d2hahKMXYj-e*&&7Dq6XDa#B8! zcxVD`Ah>aY2eEN*I=~_TNWg&&8-RZmcqrRWaBzcw|DAhreU|Q8r37R_)v;r_`-?#) znjbI2Io?n)p)9J{L2M5{eC)>tzyvkj7l0lECGv{7pNH3W*>#cUlcz-fOS=rWE#(?I zT|y#nFsvt|HgCN8=@vF@;4}LKYzxq`^3{dVatHJWwS@02C}042TQ>{i;>VxBrFw z4=C_=;UeK9bywa0r9UUU&p@ryR-tC1Wv@3kN{rc%|EhOrlkMQ4x@ULIa=Wzew`@j5>dEulY@Td%nf_I#`@PY=~%I11M~qhP_-H}fD#ln0Pq6;+TV!j1AOs(U<*{k@&_M0c8rJ;gYP7{AcRN9 zPFCRT67q`vtEqwUxlawQ|Jj4Rnxeyp{;O|mE47cNlV-F!6QsHw)Hj9nY|OB?VE+ZL<@nPDO(NzW6SMR3 zBhg^(v~H|h4^YDI{CAEE8pefokgcEukz282M0r&`tINvZfC2)RuV4SlzH0>j2kupl z->MA<_CB|FZ&`Ow)qXLY0=LM{L5VV*6*X`a*$0t%wEi+lf?x;^UO3v@0sN?WSX5Y5 z0)JWWRFrhVB(~Y9@p;H`yL|ylGJ_QHEas+=XP^}OSK8{+X~WQsfJ?UxwpefgqtR!m zrp>6w$|)C+FhGQhIm>r8mG3OT4<>3m=gbiVND`-@sdA$D#!v|p6KJUhe-A)_9QcFC zt$2Uc;i^StkB9`I=~k`!?6c`>Ke}Pcd+(9#-M4DPhFP=m`d4>%WB4SblTwz^hG7ot?F;6Z&`6lf)i%1Y+@i zO4fQL6V-#KTS|lC|Jl394TMcs-AMoGmXb;`puxdp1o)epE;W<=V$$YQ%!iF?jb3> z_Q?&aW)U5Kg-?89KT)yzht$iYB1Spldx5*6hR_Q~7@IheJF?>$VLp{6K4UJ!4=ZOkrO z$Jy7!5+R3LN%J7>yc(AXlON1tA9Of%NkTL{Gh7n2Ml!ajtY%p-zk)y) zFN*w2%V5H^4<#wJ5#p58;RCr075{Y6#+S9x>l>v!lBpYPK|tcjf9V{=2M)lv5=Wr` zl!@gDahuvvz%Mtd?VLtd67W&?0G*o{gHlev*a1)?)(c9>Gfdzw-v1!*Z{Iha@yaVt zJ~@5*zP0>~(#Pk(aylfV4swXa>v|5XPz z5b{)sArYh$Q2Y;@!}Sv^P>i=SUy=~yzZ%2>$NU7tePjeh?BV=hUaQ7y zue~;V_38&71bjgo9Khqs&Hq85TZnR1q6_L{{RII>rlI+TCB@knHx0@Q`Gq{<48x*I zTZ@JEx4m3Sm#aMzNYS^pDY%K|9KD4;Nw@1075}3g6T?0lCCu!Ijm8NhZaGt(m{B^u zZ5r^apc-t-%^2K6-9_+#h>6rG4j_}Qq#Qh;sB&a(1Z1GW^${jeZ;&+t@D04Qpiu0L zx9kpv<8+}$@~Ii6MMYzM$j?QwtO}MFnbLB3Dep>#gU1^OGB{{%GHmzZBrr*uH)BVIe;pByz6A358cv<0Pz>XGDR4 z*E5!b`b|>d68-~XqBEW)NhjdTqF@8D(n5Wl5a4GcOuaocBE5P2Ee^VKECHKg84>=+ z0Hy;;x0jyJV3gpee|OjxOL%-Ux+t+t_SGK0c=6(;Q@s~@d*_i+S6YT!NFXHdcqJ$x z7`V_)z*Zr-@j~Q}ky4>w17RwWjHvF4iJ}k3Pjr*+{>cqD+;A1}UwZ}oJIl709X_$Y z7&SSzc%|gEHlM}ef#{Qy6QT_9s6{3~A>d1n_re8Y(q2h)PMbEZ;{rMF4w4;2XGe+H zjw;QM?E7;Q!vC$(((ewNBiV#*anxm!6hIU1Pz(MKsUiI0L?mjV02J@HWlj(F$7yVO zr;9ja@z}KEh`>cDs41_y@TlZK@!Ic2E@TJ-B=IQ}SB?Nm3So9S8yZxi=8sr0Dl`-R zD(XRGyr#T&)zu$ONBLdBzy}Zh+m}E6Df~`FQ!Q_*l zAnutq6Zj=cpEj+K_6G~SlB@5WbG%Oi(_GujB)Pi+UeAb6r@cRJWGpm|#S#u5^k;(_ zUDLFON5cu*?vj#dc+eJ4h9XI!|Kg$=|BmCp-vmy3e-D_@8i3(`l@*#PzOf8`QCr)* z!^sMz3Ltpkwb(n;-7*@!3lkfW8)oY>u zU&aOyaF~=I+ymnY2N3R#QA{V)Rcs)OnVh7=S8&D%_W*P%c^NbSKa!O=dg>I3YJxUG z)H$7fV>RMPjkmQA46uVN;C59;f)1Niw?>0eI_Z)+{og-lkA>{939wZq6mHQI@xgf9 zNNx?y=yKw}3mK<%iWLBIp}v4G;|qS8li$R2f}diVFd96lqQOpK zxH&r)3Bwn(fLH-1>F{DA?l?=Wa2$iX z4gQyHckDPBF+(Y<9=NzuilxSTLd6`kyJO?C+-s>Wt}qryT_*4H^iv zAYcxWw4%R2t#BZ0a1!PdGeEqpG6GFI5P5|*(F1U^*m6k^_{o7$=D!R+>CUUJQ4s*J z%UBNvNPd;AUR~8d$rGTF8*t`y){Iw-IbnTrjAyr9C_mME3E)ZgkeL;+FMu!XPjZe- zz|l+PO~+ALJ8GzuR^(8>+ur`U^f<6>ED)`BWh+O5M87m0S7(Q0{~MmMgKai0I?we? zGTtw}p6tkSzhf6FAdSG_>^olYg$V}=PLP0JU|Z=k99AR0gd7PK8{VO~j> zh`2P=@Bd2puUh-$`fJy(f9a(H_>iA`=<>3%5B49sU)%_mF3OAlWO|mZT)C2x&yfqK zM9W?1RVHsHiP_%^`8%cwE_gfh0-_He&Y5#@(O8Y#dO|#})}ONx8vD;CP9!}^hklBl zX|}nU|ou{@+SCx|tL0~8A=&4==X*#KQ^ zfno<(qlxlEdHIEdxB;xXFfbv@D*ng^6He)bAlW}<3c3&KKe=j^=)PY9In;jz@b_+b zP8i_uiDP&Q+_Ml+V8B+c6zVTNG7Yg;lqLh;t9TH%2M6HtU^Qa)fdAr-F|u$IP=bK8 zg8at-yJ0-u(QL?-9U}Ur^`2cUT_Ym@Y~}ShXbyC_`roLewZ1Mh*k6|!aXnND`@sQt zB;&cU;zhL*42TRAKrW~NTrL4$-f(NthqbjAc8IIGSa84#^!OivKbKQ}kE(Qihc=IE zrf=8)^sl{Ew*9luK3o6FQlx*wf#>!v*)Ad=W`Ncp?u+k7wv(wQC%1Ko*dyJiKmtMs z1#tbu3%Nw-hwWF9h)}6%7N7kGDNl+C}$Vz_eLLadM61U?!Z5hetfFmKBYA z*f6LEyfoH%y)LSs@!+PgD^FMXI|I&f6~(~?H3;zz;Q;J_$|)*t|AO1X03!a%6%>Kk z$?wZ|NCptrQR&(mNnAReCl>W7%}=2d@IRV9Yr}@w8(w>jl=xd4HmrXI?LS-UezOj2 zSG^%8a2<#Q$t-{f?ms@ZqnwZj(^_RSRCqbQ=vv*Pm3sof#iLvKNQ3CG0# z*LSh6*pZ;qE9~<`Tyfyf8j}Cr!|ug^H0x zv*VIv6UF_J8=l-L0xxnfkCz25xcs}OOFPDDzm8?I#a56Y=y4uNBM> zI9JX-`R($Z;9rTN^7^DMBRng<$2jog|KsD=r-#{9?Da%4HeW=~=z2Jip#Immhuxx) z6m9$twqlgjS*(Nct%G42EoTfYQ!RJ2*^zccA}O+7&Ic&41rI`Yma|hnz$D1Z0~1GuqZU!?ys&^#+=SQvt}?ij;=lS0Kr1=b9=ui*7k=e!HU5BLWJQW74A4_6&7 zlQhtJ+N1dF0EzL#|NhTE`eRXU<>tkb1450gJlH|XO;xv4l3Q-d4+HL#(L5EOpd8iL zd8r$51NdA81{5w3`v1JEU3P}BIiDyu8r;O@L2O;tmi+|!qyJC|p%mLk(Es7Oe#+nR zp&{}gcwDO6f+AB*1ykk54qoaM8=!jZMDd`8q|2t@7(oEhgc2MOf9x15n#6BmIMIAi zU)(;Lz+wKiugsQQ_w3oTj}?FU<^A_RST>z>*pq?)*nbrmIK2PLc2!%Z+UawGX);5!&_XQ3Q{?9(zs$(2k3?lu$95la4_@-O@CeQeVe1!r^FDl>8R zlfwV?>=7pc>ZOO=MxS}OztY-2NHes1MyX&P1x_AX1Q)s6S08*{?$6O3(?jv6p+}|q0GpDAcpZ=(T!0FomvCSFPw_xeedRlVU7{|D!l}HI znB3Mw{+9z~d?tI_QvtesTB!eIqU=_T(f{3U)H~R;O8JL9MU~Y)n&fB%PQ}un4A5DM z;jJJcNkf~Hz=Q~#K9f1Z1N25nVpupp79*r+?jZLhiBeq9URqFhpuA9^75=imh0p&4 zuNUwsbgfn3i?Uz6-$_jCY@jv{0tym<04Omy{NVlfQwUSZZb|e)bAewtO>sSPC;TUR zw*b7D{W+KD&Qzuo_1`0|-?l}Ic67J3x5{}f>`Zr%0XySh_ny@nW#gr3h5x_7Q6-!& zV7k0{AB~X#OEgj)%g4O$lwxxw4pYvYWVX>|IsZWrpn`#u(jEf)vmRNJtco8ZFen3V zC_MDlR1{4VI~$Pw8>P&tn1A2;+1Jg!?z-zXZWJpo2HIIH-4W1#{iP6MevVR;3;k~AT|x*-f8Mu=b4D(au=mTpYRMFT&4P`qu&qV7cp@qaLK z6u-Un(x-yHaQ_*$is;Ev6aT0E8**#_s?id3vH!smKV3o;6b$+vD#icE@t;5p6pWM9 zoe;eO0>Jg3NW9@nxyb42lpGkA!8=as* zX8Myaty+a#fEqPcul}IB=gZs#RSuFpR3L=27)Tu1E}ponVmlth>!F(a(|*fo>N>&pNAuk-+Cez3vXVvDiMDcE0UbHyU2`=J4l zFL?~g5t5OSydz^-k-q~!fP8o%`OA`60g3=kAfE^uDEOOcNSlTiBHeG|_7>Xvmd?Hc z{@?%01TG>vqJrcGNP2~M;57liaKVdZ-DT9miiP@2isu8!3dtSQrjqIr0g$^fq%Rfl zn-BWOF?i5R$TZ<(;n=_*IVXU>3-WVxP`e}P$^>t>gilw7Q~4nA|B5}(-|ms!^K6KU zdS#n=EaBtajfYzOPNu_{j7^9bNGKvD$g!Fu7mgpN&vf3@OP53)3pXMM1$mTkOkQ{N zvStv_KyP!OBz#nR-`eR1u7LmGu`h`WB(d=!H66){zw!#%;Msp+k2}iBsDpQi$1Sd& zm=)F3hx4oaUQxaZ2QxdsPVI5ZaL6YPAFhgWe1&%_CI|x>fu9a2IfRF8E4pb(>VuX# z4$Tn%uj^YJq+tvvvXcKRsSEe_4ciF;+D~>ih}X;Rk6DzsXU*Dp{e#8#|1$|e+`F^OCX2|7paO6L zURu9lmgolQ0^HdBK^5KnvWr2GOQ0i(E;4-`)Fb82_&s8K3;M6)hzfT>f$+e%YRs9$ zheB+DpYu^1oECH5!zS)*HBA5^-SAbX$p3Zym&fk&rV_)Upix~Jr2~paNZD`s+g8VcMhnmRltMZ1xfB6P7@nsDtS_a+M zIj7?wc^8#Gywk^pDKm*Ib0&;OHum_XJZ!2h&4r#Q}X}c@{j=Y*u80& zLl1j{=@MHslV>;IL#-n40KQmqvYY>7^WXlMytG8(7)8>;WJQk>i4%b-dncJ_6@*K# zltP8VKWZqHzozo<1M79LgN7YHpKTc3FNi-?O3jO7TB@WRl2k5X(oJ|A+vsh)trnNA;f5 zmP5%{q7ae)`g%?Yk-cLHn}VO{*B0<8|A+9OQ@KK}Azxe%Sq3XB4Lwdf#BbXOU-97y zpq<4NPGq0Z+U{?z}8^pVi6bESkYd&O^Qb=J;=KRDp^q-E?jt&Cw zgHARR{<1h+;mhLr*9h2oXv(^WpZ(sabhfjf2ihy>_U}I-`#PLt2vvJS4*gGpVBx2b ze~I)!E@7VtmmWHV0u;+9D)tZa=KTSq3-$R(H8`PzaYm=ne?)r>;VzCuh0{5P*cVYa z6|E&5;){WQU;zFfmLsifI=xQO7E4?XS{j1>oE2vGrIQ?Xl(r0pt=3Ju+5F{;rEY#3 z@7xJf<;0zUyJXiJi)L?=I0LYTWJO5`DOJo0$;17x2tWop{%~&2{P_>V*1IliKBWNm z7qk0Kd@I6pe1Hk=ga&*B_%#K+!hpbkj&{33qC=TeJfT9O<0M^Z1+S;T{9^NRv|o_# zN1q~E;;sqsKmPHLH#e?B|D*qWX2Qh=ah=mGINKs`WQXzppW=YTdbc}}XLqZ$Kd!g* zSBB#*TRimJHdIs2>6E>8!u2&o^r!=oD3L2sj1`oIC`U*{23cm#oA(#_SBMaVd~pc) z*R7qtLDabnmE<`F`vd(rT~c5d9Q#R-&>}9Ie-><?nGhv}2|*~@Of4FG81G$%k#}nYyrzd}oOLzj8(-r`-jR4LS2APV>_m8%H4F|5dP?6<@MQj2;LOd1BKk zIQVf9D#j0Uj5!xwlE8UeXsQ{~)7Z&{NBa-WFOHG$Q2$_M3+LI`!cm$&9ppc{h>h!gb^-vbw2WT+9AxSplb_rbsdt{mYlmfBW*-{SPiWH098tN5R^;rawrQ zS1KI%7)Ss(5NCrD2wjaZfBBAa;e8Px(I%q!k$s+(EgV<-gjspx&&B!ox$U80Pf`x; zNO9tcP8PVH{ZD&Ju?yy~kJKP1M{LRrR$A1VGTwJup^}tysYhc(l_$sx1}Q-tfW`P0 z3=mN81Exwz4&{u3>LpZBG(&LbokW9uaqiF|Y?%}XmEQADfIvYX9)_5cilPr`Y0VYi zUtGL@(K)UJ{+&C|?G%ju37A!h53ZsKLp-i|^CaS>$b-gbN}yN&fgATvXwQRWPI$4+ zU*l|~|C8+xhA-;kyeMM)K}x)tP;^B0f3$b8HIj3b0(tiN2RZPE%>lYClQ-TW{^9%5 zzT;Oqm3nNhW`eGSLVX?t6x7SXOUG$4lrCH$x-fo6p+E(pgc)}JkCRQ%9|Uyv^;Df8 z=XpYCg{=mA(#u*j`5`U^DohgPeONTyo^ywGej&*&$*C#@C`AvpqfqxH=2UjSb_caN zdMNdA|Du@)zM>blR%sDZEy{ed)oK$&|mcAl#}grmx?SF$?j>j`*(tQssPI)E`ru82x&Q)lhYo#Ycwp8OwE|MVx6J zj-F2>75#|~9caH`lJ39^hlj-38EY*G#vW=@hDj{H@G4!$)M40x2MSaaNJ1QKxN;em zvAY*HKyp4*U?mIQL4znc3N^%EyON}=om1Ne-V4kiD!4> z+==8Dg1&;whlQ26Pr1G@f2}Gsi=G2i5vqb5s6-{qBzz&s&xYa&;-4;$$pL$Y4;7De z2W&%}gh0!iUHpGK139gco$=Maq$LXbSAVR(%0XTawc(u$b%Z#}79*o-l|prb;6g{5 z97I4u#JS@Vj?g8#^A8kCsSPX3wi^+Bsc}IUQTf8`G7Hc)^!Ud`T1k3fS}<8dS6^0k6b+R5%r+@V#`ILHupqoJpV*O9Q*( zm2OgbTUmDF&*}eT2P_5PR4{9`1)_1o5>6zl1CswKZ8uV>q{U^SE7Iz-4u&&pUQL{N z_tj4tt4^FaA-u&d-4iF+#HHBmnBUKTvbx3W`{5XZ0z0fECq|!~l<3gVz$(6n(9kOiG8tfgt%G z{J*Yt!oRGABaW*3D?@d4;c(se*F5q0o1Zi;DpP~)tA!UQ*wflwRwjE|PgI>iDHKgi zQlk>uEnYd+0r=(QgCH2)8A9(XeF*{yTgb6x;GnQ$00uyN!TnB{Ok6DFXb1ba#AIOY z1ZToC%I{DXwL35QPry7UPPrxL&s{{z3BQ((QL zqq-FhNDsKdafLx|>T>@d@Q>I=LM}^*Zha;gUbFRyH=p=A+}L+{%w_LpA3yS_#@xO| z>|H%Un?Alljeq>Z8vmrfTR1=^1ZYE3FkB%akn}3GrE>VFw?5SV`1moD);3Yx(kwqo zeY>{&((k3hExjyPP#}JJP;MYK13d(t zqE{6{CMO$T?vew->p88K7I$k>&s0M1ti^30{}TNe$tb5()Anqk{~q)>{jCqds|L?p$zCR)v#YF+slv{cZ=x{2j^+N_1fzH_Ha*3v6Grt zKk*J<<QXzCot5&W@To9bB?kwf7E~)?#R_|Ad%e4>%SZ)=IVzIlKQ_gJ zkpzbu6aUq7HcH;@&`0$Y2bPAPNxb^`({JAQvzvbQ#0q+JFOMlVsDD$gyuSeyy!FUj zZYldUh=XvHYyS4flhar~DKT1eFK?ZNjipBtno2u5ZcS6I1cd9>Jvw(T%)~|j#YugK z)~%Z(9}pFYlc}V{A9CU7`PBX&{$7B= zhDS?v9jy_T!QXxVX-=z?bJ*m>vTyz`g9FUIcaIuZahTWDkBAPy5Rk?z_^^@}7dv=~ zCTwwrMQjUzi1x>Mf%XFY!_PkZ!*wtb<3`5(XPo;tpX1Ift(epPdp1e``Q@X0B+#o{w8?f+*tZp@8kXvDIZRHPw)cZK( zG3sEGGy4EA1J$lkseiQcrzH%I4IXl_{fF=$-JbfB5ZhKP#(cOnLZ+KLh~}gM#@} z=FB;F@=t%l+N~Ym&aa(}RK(hahKR=M?xJua^K>f4scTfNNi6`!pQ`k7QhwW*9 zfmrQWku$88Y8w3tYdOyAnrr&{%2s!CNDWS{B(rlB&S|pgQp&^gFk&b|kRV1teAh=M z7xpl~3;1_))SVI~ktWW(0|N-b{3(zAD_1rv$63BFjzsTK3HOg5pGF3)lA=HHs-qr>4F3BRGcebZf*6XyBwpjtR-rxM9T%kKCyMx@f9m% zXAGx=r$#J8R!e0|W&iKqefo*pZjwETQjva%)|7p0R#LU8m#&riwA5%fZdg^o!oGcT z%c{z-J*b*LPAF%juxSQgM&J-a62dDNR?hel&Ik4ffL@@!B22^LU?M{Ot;gFVcuXQw7AQtKtEfiizadJpM6+QyEu_7C7;xv+?D(a9Xt|>5>td}=v!7EA-x0gfQP$SK~($6g&z2evqi_z9xCE%-`lDl7LCjq>A%|3Wj zI8zuCUX@ey_H8fYn7I|`zj}v5CadF(V=RkAo5F+lSNMgm1(`ZM-hp z|8Ds6uW#D7zEFeQu&br3z&;&Jb8CNDz(%BjTp6Xm2eob<{_aoE__k;^+l+ ztL=6RhX6)7|AN*yj^SpQX_VlIrp25{L_AE~hZfu^;9q8bIqG3O zWe^3mRCx0aM`c@d_JxNt zo2>m-tL}X>;r(RAgS4*5=6uk$TzD*RL&{2;w#|qLyl;dpaHIl1i(!PCpZUbw;CXRJ`g_fgkywJzEt2b!v}R zF^H~OUDhWOwj3?Can@H~p%^5NB_$#0C`nFACL2T81og$~`Sw511tG29%V%w*!o`vS z{mPgxB$L*^*-9(SnlV221Mb~q- zPFZ&kmRJs0*gp3+OSS1x2i~~;`dMFfmEKg!pJp@gd-)R?K{`N&F7rS6AGUvbIYyjQ zvHNutU`ff~U?vuMb&a)AP9~GHDfazRZPC5+PP9J!Uq!&Ze?R_L-y=(>FI|3MW8u8E z?KqqCoB%#)S587LE+C+`_8f*!z?T)X=j*_Wg#++_uu$c>@!XA%f(PN)S+FtZ!|`y( zp>rqyP~LR$;_*udrI2}cB{`-E32B`Q{u|_k=(S6)bd#yHRF51dC;f)o-}=o$dWl%u zbuTjAi!c7F^li3zdO`vIu8Av}<*@xECm|=L{k8FHD-|HT*`|J7Z{pURn?)jDZb>G){UFUV4=XL)0o{K1f zA^YnTN$3Cq1{W=%mVhu3k`GrCo@1a?sHAvs7BIovmY(`skq=(jf{9>=oQS*(wvrt*9e<%i+ z{Dw*uxGuaEf6b0APW%6B*-AFRC8*fBi!S)ww>6Mu%YJhR7LZep(|{aw6A2DpB+>V+ zFT(w91{jJ{(OohAqq7YCM0+5glYwqFcfAyuqQHm-_RkV(NuC_Vi>*2sC8W%r(6tXh z#d{#1sRSsIi;4;U3h6s07Qi_8^y`;ju8q5NrtZY`(-(h=o{tCWWy|jCYxG$KZ^H6f zX8p;H@>i)0PT0wE>9DWSpifJ~DIZvPkLbs?{Q0&=sL|nC^alD5{8Rb6OeyD&1neoW zUKH6o@64FE%#G_aUUN+#K5oco{SCky9J>XDNq!IHA3gf^U1+&W-~RPo+5wl{jQyi2 zkXDgQ(>*K{rr{otR325HBGODy2zyk7cRq>@h+9hZJ%T~es1 zYwp~ob4kjafxB}0*lun1VGtK z>({gSkN(5kFTYF{Dc6l}9~J#~qind_Tvv9_yXxkfZ(qm368MMdWa20ZkqXdjufh5y zUwGTxnOiV=NGIDebKr`D-RB zghRrD_L)w}ZEf?&?BZIygLS|VhIDzNg;_Ow?L|iR8%xbVJEJpD@WglDBrv#S+S?z< z(K$;(@@^etZrV0icFV2v9@uj8(Y0_I7C%;>N#y_qn{XTc58$*&rGrb9DF*%Su0!hV zP@#$OgBUvt`YEYkY2g0nvT^8dQ0Ca6iBKOkpz8mE{8Ph4a=~L(v*-k=e<}wPH(0Cx z*;#nc>$5KZV^)o$Fl(>%U%!6SotxI3zm7|;Cv7v0xoxh=YNB=x?htep;Sr)6Xe-ix zKYjNXfA+IK{Zpwv{!qYY>*uY%cNXMx#KkLg9`2q?-<vz$T=c-s2Oc2C z1q-41weuAvgm{AH9c25Vfw^!ZgB8W0b06`q4W!ZI091YL&6gQSF*5GfUnNMj^*_D3 zlNNm0LZ{sq_BCj|MU0!ySjvAUG0IOWP&7bjv;hFj$Z(=oOcY=7EEFuO_@8~G0zH;( z{rXGfXWalU^;(Kr5W{D2)YcAgCtwrekpri3>T?og4%S?8$G<-mzhsl_4551(1vu++bC5knzia@OqJs@U zz>tu>O!WsZ`(pce{-+l9RzB`MItwqK92^Rh66d`1%}1ps%)=%xHJXOKy;APW2}-*W z&?V-t;?00dPv;B78v&zF%rt5C@FV^($Y=FcUXHMJvkh6BpLTYF0MQxn+uijKL_~_PcD6feTkEOt&*(Rfk>Jk z@j!P2%rl97Tktn*SVv?}&iCmj-Uki?aWw0)FLLNp3ZSX*p~MH>|MJ^J^q2zN14Q^Q zy$kwp{+7W1Z<@UHTB2x z4f#4{aR3mO^p=@wR!s$HHbUb!3OqddJosOYgk{#B!0=!*6&|6PLJ_xM#+L}79d2kW zlq3=TjOf;LRj>E-g$zj|j$z@0btk~=*}3Q|O!{w#0oWWf*0B6scq;+>`N8Gp%zIAT zQtkoH&rb5%ehvAGh?~TIW#g^ z7gH>2b0T2uDljvs5=^4NG=-ZsykzkE4OYl(7U0D|*7RG=$cHc!QOBSZe%!Y^a~ z$3w?LDY}JG7N7H4&Tya-&j0f_q5tx;wEb_o57(D_QM1JM?ij@m9i2$<1zqE=zm6dn zFJF!bBAx|*D6q|fQU5jK+- zUC8nqFuV=>_Dz&(V~xe-q%|nC1#2Pl7z8uZu?)CfC6BwTf7#9d0d;q{am3;;Jk$b5Pa-t?AOBC%Pm8_+y|Qe_$@nba z;asD*`WJ@&%TDco;gd0_ogh>wd#3{(|60ce&@5iZ&_c1{%#zJE6ZyZ7u&B;~3cll} z{aB04g{`?L@p|;=+pNC<)mF8jq5mxS-<@r&P0qmc*Z_+OvFdrC!Qox(BIOR!b?Nz- zyJ#50`l>I&UdA8vT@;qwOH7^y#K+FaCeRZ zT?;rvp4OtqjRpryU4HLfFJFpNoWPigbi@CI1`PeA$;;YaDva2xt^y1KW@7!NQwemN z{jR(L^L+NdIfcsLfqFRu-Tp#tS`6b@`^FX^HU1U-ruHGm@pqhl>Hq$~NRv){b=rai zb5PE0HYyrwL$4 zHK89kg6QwAHNb4^3_iZ`#rdwW&R%pEp8>%@GuF)S@9p0@mnwNwv#)ib*zcW%@yn_!)nQ!zp#bg{|FixSLP`O!fhmK9*^zwo zS5Yz_MLwDY*nwnOLf=yPhV|uC$5dtZ+U7A5GZc}pGx5avRDZ$cK%fKjMMtcxO&w4% zep>z=qd7*?4%dM`_4>fa^;CU!_^%tM>6iX9_=G#R%v7L#thm)?v1clST*uf>-EXbyIgdDBNB zAG2DsfaNLvgZxcM{g0_PY=|S=)K;6pJihzT?n8&Vx)y@*)axIV{u`t*ZI0SEnr4oW z>L~f|A3PQS79vA~)S|~nLq$&}MJv)9Wd9iE#v*w`8tK9<3~3W_N6|05zk_Qpd5{4> zKg#w(xo(zEWxYB~4ho6Ks+{dQpFy5Q^$S+Sco+c*fNzH&C*E<%0L&{Q^Q>NPt~5nL#LkqiST&xX?cp1aTt@?<{}ko#hu_tkx;yuXYgs zBFDWm5E@AphJuL_7=QoD{t^CDH9$8;;-8M?tC!0(xJ|G2asEO7>-hih)1O!93+25W z14msc%ptGC749nSnT%RD&X_|Oz8qKpCZ_g)q(PijKf3n`wlx7Y-Gz%koCV2ei}5i4 zmFMK@|GW9SQ`Uyg^~;y9T@0gju$edp2~tmThm9vZ1@V=PCaFBCi;T?Is^jp}_3g!L znLG-t`R9e;9{_(CqR`hLuF^4<^G~1b-?a9B=U|QA)uDhjJX`|)(-#cV0>w&l{z11H z`v>|ZwRK&L{M$g5?nD)?sIdD7m-BGdbdS5D4t2;tH76FThNh1#IRBDacmK>7k<8*$ zL;dGIr?Q3*pnsCizRbY~uKo8#cedR}sSgHTtqlvO$JJ#$&RxRwr{Gn-jXK&J<&XgKHr$Fz{Qlk$4bN-FBS|o?2 ztY|9bcrz_)IBega$y(44b0fGB{~D22cV=v zDQJ>@Ov?~+&Q*?z%$>G*EIDs(?+B8Lkka69aXKJTk^SEu?1^b#rh1Ha|wi%c<>8@K}#nm`E z#;CwEqOP0u7yqkki@9(@5(5RJ5vetXjoPv4A|-oBHcPG%L?MQB0ruZ4&OgfYxJ$zS z&41AG?^{p&Y}`&zxY2C5+pqW)B#)hTr^)ig^)>^cDli#EfP|vAl!+yJAd7*n8dvCu z$}xocapd2=4f|aAN1a=|6({!-1DGJ#Fzx0;uKy=>tWc#YA`@&l1N2bM)icF#~P4{KsU<2Ed%^>O!Re7$KwD z1i(1yY+J;mnE_4=TUdG}z@a1cp`t|P;I~|{>{rA&+1aDJG5*p1I@tqiAl`2@Bwal z;2W1+cKfD%5G@o2QI9B~XdXb3dwwADO;It(=^`Ety@i!08AUE|*EUpc9Tz<=+Pk;L z@PCIxH0AbqvNQxPfQ2?9{0kDpI#aP)W_UPQY8>|Xa%HDjDLT%99?t(C`@i0J1dP7* z^AIcwf1sB3F$nyu@-uE5x3^X<>*yj862VVSKe2kj#mN8vttU=7_GCrl|6=|B;cbc; zPhD@{CGq#ICzQ&;;e|ipy6P&jp)R|9(gwsHhal`<>Ax;qN@7fN*pcYPU5sIlaZUhc z!#)f?d@~EW4yx&j5+jKR>Ws6sJqZMOtGANd?3BU(k7j9;U3KMuD&9t1XC zdZcFZ#RC3c^q=ehbN$~s0VvM0L0##_GceS-;gfCbyO}c|ct8&Dt}&doTzIXXp)f|d z`jBSmZ!?Do9Dwu4fy4w*TDQ4gzUv~_OYXXfCd<*NNbp$~UB=rcS(|KSCIB_K0Fzqn z!gSVC08rj?Ghdv{IC_$@j&00@(O1aLiq!hI_jhkiar_St7R%ngAaTG9y`c^NcWwn6 ziuTd1XeyI;8m&@@E_uEh_Mg#zhJO6NngRJ`4gHz}&OU69%fK@GyL0Bb^gq6mlKzRa zRVjESAG=N}6OMe(ar$op;Y4mUOyIK~CDoHl8SQ)_M0S~yLw*K0l0XvN^@T*42#WjcU?Un#Tt86o*@w0Y(I z6$8lpG#ZGuHFJ@C5`VuX4~~pm^`#^MK;%y&Z_%W?BK{TGF!sOVJH)ria4?rC;Kz=G ze%EO|nZ3W>lu0Z8$94OrXP5z{{F@!%TAhC)S%Kd{eN=E32sx5Xf^SZS37oHlQ1SpT zfAG_nkmJMwC?6OM^(Q@55MF#Vw6+Vafa(85{+FMASCt4ofqbQkj{r!(ww@yY!RUWu zx}pDF8;v@Veam+*TZUCA*~kaL!3HgD8uV)eKtJq{UmN1- ze{&fEkTR#E2EyVlqCX}`B=*N~g*a2GPc^tZnu2y_V73`Pg4iDNOngw;<~ns?p{?cK@M6!izH>0%U&TlxowM{MEWclL)! z4j*ZyqjgWpS0V(GIQ+`}ji;X4J74l0{V)HYG&1q;3oqnM_2lR%JV?7zP(9fF=d6cz zE}=K0pC$ONJkfOp_z$lV#9KDPDCsM$LWjvk%1NkSWgCGrgCRT*o%`88liI49< z^6|drj`xkz?FW~$I9k2Qn$Vvr%AckMM!2sSp!Zw4=;T^OJE8nH@K2fndK}XO*t;3< zM`!adD*jupuFscxmqn%o05Iy61$Zv|Y=-9FxSS;X&zUEy^MVUdJo`ou&ZZS9)*ofj zq_K0n<&C0!L!tqA+IhjPTek2{=8GcWTsW=_@Bi#)KSP}xY&5q__~>1~CKY@m(b2a~ zG68`3l354#!fYfUyIX-r;z>JiU4){zgzOV(I@ORX2FBC2#TTjbucV?Q zA<>@z=CKfsQSwawV`qxE&`1W{JDP(89V<8x{Q6&0|IkPNKi0jW|KW4rc;j5&kpCpV zsbL+zI*VMcPn@GDG?y@vCUoov?rzk8qo@|>?6aSxl8Fq)qgvu^+sH>TUJd!?c8YF! zY`GL5B}VvPOb0ZqKE{hg#X>|sDu3$I@$6TV{(~z3ztbf@QcqRlZd-tqU;;J)qew3` za^c;iSZ+$lQRcw|3X*R5=?mn)Q1MX9dy0Addz1lYnkAe5S6IdDjb@`TJUna-_+R-W)rzKXq zR2oMA^^zCSS*zRNVw5sIU(o0I#SQOXcl8TDyFe@(XUA+jfqjU8&%rUbAU( zqm%%(`~p`0*Mx=M{CgRRE}A)=3^0K3yx{ZZ==o`)4rCteoGGY`c@!r-I17d6W|9yD zGPdztW0>%X^q*e9&yuxpA15GhwcN0Qe-ZuN&dq(EsHZH{9~I>wfy; z*XF~bI{z#G&0T*q6Uh}qG6c>F&NyeTk}Du*H=cQ+L$C*CPXaL?;YTSSv>Wne<{d@c zohAMk`8an-A1C8i8KH*tP1FMN`7M_m#BX2936ZHYB_x^vsy`-mu)Baup^XkRU?i%$ zS(JuRm(jvpwH*puanw>Kshi zBlWV^<862y@BjF(U%mReKUM(@p%i2N;J8Q4C;{&2N4EX^6MyujKQxZ^o92mn!d{%V zgjI)EaP*lKfCHlWRI6w9uCo6TfhNi6ETv;WKJQGxwsSs7^P?~QT^$RahNe-(eKaRdSi$0PNkMs6U4^llx9FG~ZeD;j7o(@&cs^oLO#adt|5Ui{f6NoBDY^PhB)uB@uJynJ%S@FD@n> z0MirWhqffoyVW1lbh)@doO8&4z3Zp}K{)Hw-9)LFfP39UqWa`T&VAh@t98${waMaA~#U4E&GhZn@j;35kH;nB0y*%txe4(;0)zaxX__iy*@ zZ=2j#Rlv(LDj5RIzurN9=EjpweCILsLs+0Q*jm6tMq?A5NNm#{@P25hzZ4E6Hu+(qQ=4-}~|o zugzeWJvj>fy}hwG{a$bZdI)|~{s0tA)v7E0(K{Hg6|8JJVwDGcG=Olv{E zUA2Wkk}lcU+N}vf~ z3JkH5%cO9jy!B4AdtLM9>Ad$SP3AD3@C}>L;CLx5s2a~w2le6eE4mJ@?HcRo*nR%) zLlbwKL?PzSOrbuZ?R6{VrE^i4H3r5(tT##hYdRiFyYSZlemK?eu<$=Rfrg3F``f}b zS`P+;<*z57`|5QhD(ad!J_E|lzF;RY8BMbZFY1fyWy9G7>=eML=DRszwevu85^5MTf1*S|K`#VRw$aF%6@x#@V3g)v|*n5mU_--uCk z?RrZ)pNtmy^o0K)`iXFjli`{{{Bp_dk8aw1XxZ-H;xA&=$EN`D&;Nj>m*6*ZC)zay z!hJGfGL_PhEW|$g@WU1RF}4IP{r>+PUG_sDlv$lEJK;yD*9>TSXU_cX#6xJLv9bNs zzd|GKk8nC-*X`1tBVa%DS%Cuh@3Mcv{;fv~GzDoiHXjZKeK%BIVFsp9{{VXnja~`= zyO)u3w~RyfvfaP=&2J7ZTd4yVXC6f)Chl9X_N2-7H-B(vkzgwK)P{KLOv}&ao%m>7Rrf2 z=!v1(y3lFVTkd93??QTglQE30}Ab!Y-; zNyoK&A0A)jJ>rELCHZYP9;tnDx2dnk8pt;#e@i&As^k%+r^G%pc;RE}QqPVXr=46! za7^ie#(<&Kr(ggGbD6ZN4&Yz3d&akq=1=!fhTz#Zf+!1P2zB`+PSum^I>x$yW943B zijKYyUO4NmB_AE_7@hvZC!YkbNU;Oqp9=p2@V}^S5%;QXrVx%YNKZJe{y%E}l(L7c zLb8$Blf(Oc#5YhroVa0CPZv^sbQv5(09sYSb=W|uMJOD7Xd;+vxqYp-RLryXie9lu|pkt0sIfvgIXLggQwYmeemX6 zWJ;;aiv$d&(DNJD5*Q=R+IWSod|%UmrTX{*6DH%C`d9DtfO} z^HnGTiqHttlK)?6VQCvci~z}Ro2h-tKNZdde-U2w;zY1B$YBlhou!{4Da zRA?Z~L0oS7blm(Dd#O;9_wgw(N>A%}=?Wsfe8;$_(HMaf99hvMPrWu<3)Mkd3$Fc9 zZ7_xEHsChAi@p*}80yn(0ZC9HjEaq1`sq7}4A{sPP=_WBkas1;vRqmo+`xz``HSg8 zN6rBBE62OjA8H}uJQZKDp=N(}w5a@F(js8~INguzMxU1sSb$$2!9W84O2l!2tHJb| zdC;0SH>)>EnT;-9k@^9c;{OlvVs}mC7NqktvrH;k zQU{+gc};xMicJIt#5JHUJ^M{pi9(NKdU?q+7e z^zM*w2LG1&SK(h}Z7Y|-0q9i|+`dA(QdRzcXP_FZM&n@qmIlh@2K4t4B8%qtb_+m{ zTn+<+DnUz3YjjM{famDU$1hcoVgTTloD>YIk9Dj*T!Wp!2WRm# zhZqB=CS}XmQDIk~ZWE)WnY-9@%Yj{>}R7Eg72DIUoib8HE zVJGhBVxC<28pkAd7kNnB6Z%PV4g>)IrM;C^^+iCyuz`C~{Rf$$t-;Vxyj}+z#ghXX zHENgXkR4goZ9L9|v4N3csr0VlkKx}Ft}Y)`CAj1>Vz=1cs4eK`(r4L#l84xGZ!I}{ z*BC8{kQAKa^qzGvagJ2F_t8AsWw-t3shMo z5Ng8s?dq5S*dMns_ceEBfv^!2IXC!su`Kv^BZJ{cEn6bK0Rn3LB(B!-LhjS2F7<RN z1}(eg>;)6vf1foWqnpK|j9Z)5ED%3ZbRQvp<@;oJ)8qH3VIQe(*;<(TFX3O&8)_&} zu7*Gs4d`CXt1@rDj0- zWR6HC_1Us{KjDZ5sPJG&%Pi&gBL`e^>q2pA-L$52jPa zLL?dn|03tfdc5UEqw>pc@_4Ab)0?`Gm>a)`{O>r}LHPlP@GB<>|CCl3VppL(N#!#E z0=|UvOy*E$lDQ5 z5De5vtDaW>FT$UGe_*5#sfMkA!zE9>)y#yGiRx#%$>4&URC9E#=9RB^Tzg^^;&~VE zcZ}oT>Zl`Ktpyj^2JuLR|3(84-6D#89sp7xND+@$1|g6=AcrVCO)pseOy4PftMVbX zTF0(Q)1GDLb4vt?A^g-Qod%3lg#p+B^my!mXM{rt^(Yi@Y6Y#w_{a|KLcx;%2L3Ho zp8ie>zv~%n09xDyokXMr{x$W_y`9Mvq2an^M@pL;!NZMGq2&+w!G9L<FeVN(7YmM8UPfAoE zx0duS?Frf&3tU_+4##)ZDf-1*h!q6NT{46~Al?MQ2jza9u)k~66iTxZFo#|Ptq@r) z{O|6q-5hgTPBC0+7J#|(S!D|xM8!YRf1RX5kr5lV6MaD^cRl%mCA%{C%N}sBs9;=M(dR!LrnM08oAh z)+vzcSXQ!Mv0jY)=kyZ*_`@^c0scHlo!3CHoH6x}aZdl~%y1)P1vh)0V9@eZ0(Lkc z{BKiuV#;n@TaV?3&6M6ll!GA0NxX8$5mdl_n&lrqs*X!5`EKbB{wTx~m@p7pIOvUw zo^MWF1QYa9v!U$)4ZycxIonSG5e8TiQ#XvC49&evBNkFo!Jk|pU z&5TlNU#RVT2>%iLr@glpx9yP<{*A^S`dpCcUN!yC=zdV60WR^+REfs7j@NMlk&+eo zWw#^|tgbzU4v-pnk1{;fHcqDj1VJ8-rHH5Fl7FoK_!1fJH?P?OXV1Clu6yqJ0YE>3 zeEEsFn8*Neqx|-UI(@bR54O)i6wLD1QSk{5Vo}Bpx%rr$X%Ik>`jcT6&sH~ zOM-y>;s&J|%KyNSz&-runWv4aFGPo(Cie`f}24pvuXHBa>eLI^y`Wh z7{Y>vdVW%u>__c+b?wqP0ZS46Ff95n-rq~{9|53}Cs%EjoW82ZV?|2fpK>blCtIzk zMM-4C*-Z6oBWMAHp9TN=1bM9Qb6ge9CFp|MO%nX0YmVdUGM5}3oK=DBW0d2nirs0f z9;xU#XKzv#3B(KWhRaZCKDmHDLg_J={Putsee#n(x(7wDR(L{V)1TQS`rR{?ObWyN zI!@?>jBv#UGMIu)!HO=%sgc6*oKE*MY-~1F390`FISzx(!GfL1WpagVu3=RjPaQ8H z_Fp_Ucntgt8iUxLW*rX@=(zaD0>9j`gIK!sFx*c`QwL}NQOH+WKO^IqB4?eB zdnhEGbqx=&_V6mFzB$t-5v!&&3wS2Q>w)+=1*au=BE>yaQ_Y3fULZhjJy~;q@+4*kh5$Y>gHR90%NPJn7+W1Pr9<@7|Hkhh z0st=(PBrWnJ{}tdQ1vMPEmX_W_{}O5JQf_m`g;%iNDUVK9h@flf2h_@&@~YwRvoa6 zugfeAo?5d*#hc@XAAGOLcyrF2NrY+%OFyXeSEBXfxJ01*n3&H}IhBpy9>4NV6AN;A zVH>UBcaOcMbgnM9(LGbGGqffF#|pCm(dO~Y3%g8P;Pw?==sYftmuS5SV+Z+f&eZh( zmHZ2&GDC$(hBLn%4RZE(Z~|sTKZUWOw3R3na+?QoWnW_e1Q3K|dR04ZDMU86(L3Qy zO@R7eiF^~}ksYqJr+`)d9_eM+l7N-O*0d#?CYs)NRLPrEg$IbzDt5*-`98PE<5szp z-4gBPiV2^>Z6cv%-){0*fVrdv5R^i{o(Md!gn@eoGSgw6sNTzJ041wW962;;d;W;DjTx56w2{0I)bT6Jl}Cv`S4wfYq6FTy8{j~>Vv zNC!+zNo&fdR(wIR3&n4y?p$gRfY=Oeo9?`V>Su~uXOC_=$v!6p%5C2Q4otkSi$};y zhHGIOQov-&(E$r{Uyf08@MG+}ow$ zvWr=SL)jNRJkVDv9vPg{j`Ty9ileS&N2xFSgwb8cg}>`gfOe))OE3VOV5E|kNHPmA z?WQh{Ca>Wj-7#YxYpih0A{yP&=@wA2r_VJLKy1nU!X(gvfU{`55eG;;+WW zw3*jED@_af`Lm|giZB)3y$@8dAkqX7rheZSUG&ykIh0^o(7M^Yc!ki}6UO`BMVsMD zI+GblSS4?qcF(OynDqz$^;oTH7Xq}#2zqk(e{FBM5RE`Txy)2tGllFZdSG75IbD)p zd2PBdz%lyS?8Y+({gOyfFXrd-y8T^@9r;UF5`5DuY4v$0)YIf^yqe(Y3vb;-`_CDV z11Pm}w?K=?;gvmqLH|R4su0gxk>Lhe?!nET;AUS${a;xB-exFTuxfVQQ^qLv zC2*6`4mrEGom>kJ*CaHP(9W?6KNX-(EWXL>a|5(S(J8_y%E!4<0{YFj)*0&=`wNc; zEXf3{Tzsb>*(N_iD$#g0<;s;ncTD{4%Eupnb@Adm*&ZZws_;!IJ2TIpq43o~RuOFA zH;Jeid2eQzjRv0)Bt-ZcVTcOQ3|w^kv|XG84uVUJ9)xyG_bcBs{lD>Yb|%xQK-zJN zwkP2&d!pm{&v9D6)<}i{7|1F&f)oHZ=zv*R)!%^>!Pb@5C!d`@&}->_DL+3;%yJvq zXPhzGi~0^x>;|oGT(JwE0WP^~I^Y`&=;=TF)$YZ2f~NIzaCyjYS3V6Xbp}ldEG5vi z;0`rFQ%(mHKp>cmLaP79@CphXS?yoV#@9p4L>u|fTpL-)+#nz&1g7o63wG^)=hVjY z-+OQLn(y2}|5HCPo}oaonWp`NV{!WTR2xmzzu_CED>h}p%}5FJ7xxbeut7XHI%R7I z3r8`}Y&@T1PofA-^G`!Q5w16JQ;TeOR7MaXj>H3U_pZYr$Ipl8kN|lfS-ea|E2LDA zn;HT(IQ-I1GMS74~^avqci8Ebo>LcI;J1*mgd6@hvnaR_Ou&! z$@au-z6Mtxu1&eM=x}t&r%g@?)wF8*t&$RUKdA#sW!ON*_KzMM$A3}Mn&^LghrA)Q z9Kz)QIyjW_6tmBeFaU_?VmO)#e!~mn6+O95{zdosSDwHn>h?bljSR-JsdzM3LJ8!^ z^RHHulK=f24AUdc!caP2PTWw;WvWM@Ui7ar<8r8v6M8CuWcLzaI1lqVZ7E zlZ~efPSbHBDe!N|f9MainuQF&|J26iJl7Ke4tmPb@Tz`!kvCom^ajuU3=}W<4cUu&0`G7jDr)0tZ&&HW*(4%vQ9o+ z*Y*3)$Np&#grd=^Mc<32oh$~+o&qWG@d)ex7xAqjP!XbPoCjCxRt6u7zo#AHmP1SiwPDMiWh~r0BnC^26u8 zbnZ(^sebymzan@6{a_lB(@Dm@skWos(xk3TojUqM$#9&H*ItV*#Vcwa0hSl)PCxlC=szJtx3a0`NHmf! z73mI8s1#|4xGJ_E+T}x08gn;&U?xnL!bjO1es%!3BEFn!I9OW1xQ zUn9WJs^=R{WJ4M~C_6w}V9ph@KYo7qUv+nr0TieEXDk~kL}`CP{ZlHH68^`Z$AG`C zHSG+Y0lc(^3i|9wU(TBjtnxE~s8X&jR^LtR67T7m62XRM8GvROEI-pT=gqa+&;&`x zuzQ5pA=xqJVix|uttO@p_|!$}7=iDJ_`U^Zj3>xsTQ4HlZajBO$Cs{yxM3ItudqLK z-c^85yU?W7Xc@Ezc$X3oQZzF_e~{D9@23AvHh>9C^JkJjJ&Db9dCSo7%cK71em||B zn$>E(W(Vzr?{M&b4uT$Q_1<1qkyt-xp3_i{)7;K1X38}YZ)w-T1<=mk;K9dtb?C@( z5VGCtU~XMp6AeH(yJ7Iu%xDn3<9Ozp4MpPCkvTF5OqfN`25 z(yp_Id-~Eki0>GL`J#1@9F`EkFW#jQ==sP$s(%Rp7VF`3I+%&(tP&MKrHYAv0F6&? z@O-k6vYeVHu-PdEqgK9}p3*tGfHp0}(nUT`B%f3FHx%YmnIzg- zaXiGh3=p5hCfN`(427ne#I1vu6^#8e<8fMF5(997n}lY2(|uI(VE_RUdHxPnJM-Ti z3()9e+^mE12hlcj=}^dMunRP(zaL)+GXmLi%NQ|K=wiESw{=iFYAm|BXr*zWfN{`$G>pwq@{zf=?72e;-S%izygc}V5 z8ac#FESa+c;}e-jmsA2razn`zWiH7-N>U{MsHQ^xx!0>QeEE&3SOCAo;JH4s=nX)E zFoBluARIDAcn?3mdX6G0Crp24#fJokak$FNhVReQQJc4ojEp2v_5i;%d2$rZxX*|F zt?^@lXvhv$>Z!f~D@gb^6Ap(B{!uTLA<=AU5Gr@|6_FFE`@r$@bW}*j#SO2^q=ynC%<&xOI&;+ zy9(B)5dfuhB-;zM>gSU=8FDb@#7L>hKKx*GS5Smkr#dEs6R2?siGJu-dYJJGu>kBt zlX464yvdM23z+9i|F?H01D#fB*iPDwY7mqU93IuC`XA95IZ$g24c7y8@`AkeJq4dP ziixzhv#V=#tjk0><}7*Z*=NT&U)sh9TO)AY-Jq$5e1w$Db+h8EygU0khDiTianFxl zcj-6O8(?KYl|sEL)ewFx|CcDGSDB$eqL$$WMwo(tbpk!4CX5oST^$=%Ue)ml&~W;4 zhjZ7HAnysrD|`D7Qb@W2wXe-D(}stdCmCsDUPN8gf(i0W~PH=VRA8qocsKTn-sNU{kNtJ`X^0}3P*eaPp;_oS>ZtX z0P7!1b+!UlI%)?7h<*osdvbQAT1lt(;{S4ET*mBSiIv)7_P(BLxPZrMW-vQGq%*@9 z5(;^TwQo{<_>BLAq=aiuy#M}gQ?)o=O==+Jq5nQpOz;ze1Ey9FSa53D4c5@2dCIht z|BrWyKA-98Fc_GoV_b*Z6?UE-Hl10RUvPLVKOj+W6y7zeT_N)^mq2g(`0>@ zz<5rT3brp=N@DKK7ytLi{RtwYVX)syo5=t^QY%^ZYR>;_#zTDUee}J;+%OwC3EBYS zwT*lb`a}lf>6EZ#0$_qspg47C(51uyzMRIvat*wPA7=lb`_jWEXa96eKu{xE`bE?; zQ_qHFuuQ6x5Bj=tZ;s-mBJc!-h7kLN0eCi_O_dnKl2N3S0S3S*trvN@4C{@#uw5LJ!PYwW(q7|^hd)pTrNA!vJxzv=0fUKDU z9e?EVfP5LAh`tXebwMMhE*3+_D4Ujb;{^k!2Nhe`#Q_^flT$g33}75V58pR=+f6tH zT-U#FCgm3dWnF2f``CUgzSdv8vPn0?6{HIlqu}5)X5QWNMjk=6Iac{zm_+s0^PV zZVx$zCQp7?F40@5F*|?pN|p2C${Up-*+DASmFSfTru{fOYWmnFqXqE&F%pw?XB;GE z0u&e41dLlk$9w)_EA0XXJJg8jEnwZ56g}jv8#$J4>LO`FryXN_Ih80ZDkY%k`}4P7B>HiG#Q{IEv!y=T9t`3KFC==Y|EB(>|5$*oxFZ2O z7(DFtX7-eaJ(j1C+}m%MpVmdtEJF)U*Y+|`(Dv8Eb>dM*?|U3mh!tV>@j=R*i4t>c zCtU>Fy~}`wVBn9Rf5)vKzL-fca7WNjZw0gdLfMyR4B3y=qq6Xt6Z$IZUvtyin1v3^ z(m8UrLn)C^mgQNq0T`ILQ!T) z=RO+*kUdozpi&;1jZf)RkV`DC*%kdr9F%~zoF)Nd3pO}OPN$lp6BMR10h2&&3PMVF z)m&s>&@{4xHl3XBC>S^VzYYB_31BWJ0I&};4f=HMxh5)bt8n%oNBeb*!2o!VrVHlM zEWcQQd4LzX=r(ooMlHYcLM57r1sI*kjyTC!pH<}$?&=|RG}Gf6gl1Zm3)Ue z7Zqd`#;d|AFsb&xuumzJ-rmh0QTP&fF|$_3ht4$ zJ_xC1;jd&)C@0h*XoS{G=bS^R=;D&956X!5a-vAY(X+ z5_t!ejl^Bj!39plTL&DA+v)`J3d2|V2Z(|R;D90jIR6Mv{xtotxk>=2sa-=;d`LLUel_~uS6EG)Qez_VZtz9E9++7>=PX03Bw+9hdEZ1xBs|Jm{!YJ1H z7aYugNB^rUXUuqY?W?MQSiDq$F_l7fv6YHD_`eEf<#RSL-j z==@`f+2kBT1-wRGvG$NY2*$a-FvKA<+~vvu+2h)#SU*z9YyedY$V(}O#rn4oc4lMM zOqk0z(JX|GPV7SEB`NLtkUFZ{W!Nn|*uwyrsyhxNgar*OjfL+PErK z=~rq*%>iRAx@iJ=HrE(&$7}dh&?n@gie~m}*L#l)wy zaNmQKch9Hse_`Uk^s)aBy!>T{{uct`&~BQo(6+#Y#|-@{;QTgdyB%DJ6CJ6f08Vgk z7yYLp{FQQCN&krt)~uXEhQnrWZu919 zXVOvso2~w1SirW&SNH7sgTpz`VXLn~q>%k@3>+zZvz<6#LpW(?yh{e`qBF4JNY)(2 zR3}&t{p6sLCi>nT-_do)V;p@Sn?Qzp2mJrwtbgnO1K*hl*Vq_Qa{2#Xzg+I2N8V8X z2dKaJ;MpFO^!2lS_Q z@E>ve)(?9fj~A2+Qh{3jK^y(wzI8AeBO$12S>a}4pp-eR_IQEh-nh}KY%R$VZ3Q>n zzL7m4*WWt!ItLuAecq&;0H>FvlBhB|4|5&;&o?OR3Hv}SnC0rf$&!4MfKNZY_;Fku zqkt)P8Jx@?xLCU2q`DP+Gs%`Vs#UfHY=F`ew{?+^G@H}LspogBJHEtpUN*L>Nek3w zU?Q{|Hs08c{R{j@AQ8ygm0A_-hfMi!*0wv7*#GoD1sH*}_KdC)WWQq+IYdgol+y{)B54E(@y0@#ErXcD8Xu#h3U7?t zf5`t+7J$0R?B2Hq195}GV`oW0;vW=5D%G)90qG^BYK#laiv`A$%8^LZKHBl|^GA1W zWUVksStV^#=r&(4fu*v#|EixNzfiQ43S~e)E|km8@Iawt2TcBByT4Wo*@aTQG~$#S zhb?=cMEJ9k-s>05to1nkDoW+0PCZNJytP*9tpiOjOU$^ZNRv@-KItm-6qCVPLHz`Z zK3;ombg`ii%m@U)eOSND!P0Y=k^+zR8|&!Ww^m>~<8Ui;-w;9!?d7go46Fibeu025 zcdeN?hH*KzU&jnN#DD+!ngBGtX+n=EI88sVp553@|5JP%fo3R4lg~tyGd@{>B~P?v z@*n-_R-is)57&zx;GYwT!?{8!pEvuTZmiQVE0BYl1QBlb#D~Xsu@fguH%v*6td@Ji zY?E=v;^T9J>A|h%7)17j41sa=f7W*u0K)%?>q{Sxtemm(SN~0wZ);^80a?QY0jwbK zyLswcKxy@c4KgYh$PmC4#xcM(ga7UGcOB=f!T@z1)Y{_=;n;$y%DePme<+^Lq_U-Y z*<+LBWp6H&%77jy|C83ht-cYfC`ZM;>{2 z>8pz$U-?@kAEI9lP(weUR=~fRy5PsDJUz&gi)Ql~yBB8DHu!hXCtqA=ULA*wXIiO} zFoIIZp}#Ypj8#jaP=%(C4*bM>^Wi& zG@`Yn6`SJM&NuQzIlahH_oOlB_!=y`6BGXOJMg)@+|UoyG1WHYTHSH2=0oq4B4GlU z$Sy8^2{-6BXhK3$XYIK_Q&KA*LD#5{DgJ-re{BZ&T%bPt6#Ns>9HW(g)IpCyEx)`B z|H1S3Pon$uk|og3ifIBEHnz$}_CMVZJ3&8QN8oODGJq3f0-wPa9dH>Di7_7Q;?vv?juJ_+ZqWn(RU+VhZU;geI zIT+Xyda`@{o9C}xp$rX4KVu5>Ld(Cg+uu!%SBMP1G?l%a@5%kQt%NTe!2SmtqgflI zHrguE`Oi~|>;VJP!cLeHkmJL+7pd%&`OArC&WZ(N9a2A|2a)~;j!-8wJhkFg=7VgW z4!lA9!B__$V_>mS`|`)%6<8@5@RI&Zjk`zgt_vU82K>#J{x4Mn{6uHN(>S^y3ICAv zAqs9VBER#y#~xEgKUNatBNG18=Q9Cw?qbw-}wImgDINAdcsZ}=J#H|$LGnEq5;l-#FY4VO`*)G<0m11t%}q-x;k)l zA5@*yIN{6$-VesdR}dFeB1Qa{ks7ql%fI_wDgcxLe-2pkCcFn+EA%hL`weIh`Ty$v zOIu7AvxM~@ebRJ(!jgUr>K}XTFaPo}=;wLv^D%<{!{_f}0SzI9byuZWfdu$$zo`ZsD!u~-hjKKh=RqHGYJcR5I1myY$)JTS; zUjh7HC=4XGku(S2rOJAObY=bkTf#XSnFpLO+ll-iX;KmZ=zT3q@IQV2GpZTE`z80M zoR*3acgNB3gW#VL)gtf7XAL-3;#kXS<>7zmNB@I{Q?h)+B>9q=Gru1W}Fh{5UyPbk#KZk5c#Id3YajmjD|SZxnJsIVWHL^A6E zEaY&Hg-^FfzU2o3u$xCByurm1`q|XwGdenmahT*8c!{9bbbaO!NI0G&;s5FRCpK|v z!wTAnZ&tWbz@1DO-_`a;94cR+srh_oe%JK9`|hJ`E){(nbIbOx}2{G{$X=bicU-ADiaUH*@+8Q<>>$b579@AdeP;-Fu}Qn93k|KBM)Q8>UZ+My)z&o5H| z2{N+3RHRG!k)4U0 zUv1sWADI^~YRa%_0e*u>^=x|pTp@sJz-tlpOa{=GX_dJpB z+^3n>3`I}phx)BvsL#EAWd`N`s(0(ch2dHtW_y5t%Vs@5-`M3)E8EJ(S%2&w48Xjd zP8SM^l%TQ0M}l>q_X|DU@dM|7|9}7EkAM6{rI2s z;-lNX_cwp@y}!{9KlRZ^AMx?M+xP|laoa~R|J8oKFgW3B5$rDZDQaDknHp_+z6^fq zQ=!180)bC`^r=q;24kP%7P`;h@YIh2+&G|T|BZ(8(MKA{kM&eDA|9)Mx{XKQb{qf4 zXI-amb>y{9Kr$Y%?!P`H+l92;;P>VTYLG>-j0zke$LU`cy8Sz28#9w~dv5nny> zh0peE9bDxIG{xUb_W+uQb`nA*fh?|WSpn23=P7@GDo$gGzu-0D1%C{faln+QG~>7# zqo_QYtps9M$3ySN1;r-RFCeq%`#MgnAgY#MeDNvTmoI;z{pzc4x#epAyWEYOqyQ5@ z+H#5qwscc`m@%HGMy7*21vb>$1=>3Y%`gGDiUa1fIn8HK)ITx zgIgfPCmVSb5Hr+af8+b*O9sii^$xj-{ZF`gI=PvV`ufSdV4)xVAPEOZVO(#fdL z6KOT9Pz)3(CspYc|M#$3ovEQ{wq>P~Ivy1uzt{JLy>_%&$PTumRjR}6Xsu=!Qe;q9 zE43(dFp{b@v&2o)Bak18F)s3`Sg|CAR;X9`*1dyfI3XsB(?{}MT~N=(O!%SPe5X&m z^81;Rxc(%ROeI5sq-ctTP+GMV6vx%UfCcu$3xhFOu|MVyw8&e@w`z2+O$L%J;JpSz z$!hJ`U_J`eQ*|hLtkoKn)E`XNJ=OO4&XiC*87?M=Ja{+lLa35VwmZ;|Z5$&xCRJ$o zLIHv!&i2FeJ5!$-h$bN|l^UuHrJ~hzYbZ1n2+$Zdl>#k4l}^QDL#Y7o>GZKyEtyJX z`P_a_=bn4+T}=ga z^EL3CNKa<7`Fy3842)E(H9#weKGPzv{oc{QyB!oBnL09?Kr~1^>*q zu($Y`a-@}tR?_*ARw_w&EKKVNl}I$1guoDd&XR_B2}cT7jq#;PBH$-OyyWTpWQc(! z;nG2tQftXhdiUMfE3Z8D+*5!3%DeCS-%SRddhXrl_yC)QZ=OqXLJ5n%W1&E6Xe1rA zfaqoiWD7Rj#_IAs%oq_1n$=cRnm^PDmmw5jJ;uq)01FUE#?ymC#dHWU0S9S%lJ=@V z`~2`{OGh>j4f+O}gC0+Dpd1nZf4RGVFxtZ3T`c$_`9|X*YoXuwnPAwq1d=`+ZMACI zYOxx&vsD_#rqZoww3!Tq(&0iSl^&v@7{IaN7QIE7{ZOmb8iD+5xEhP4hnNI$P#~Jm z#sb-75(1MUI6GT>Di*q$z0Br}#n>C65a?vtBy@+8HKu{GR3Nb`+`cgTg_0+4 z2Q&94g5^@#N_HChfkp@w^3__UoC@sO-dyPSZXYPwcGFi6N9Yn;pc_y)-AZRcj|w*d z$v_y8I#{f>0wc9*mCmWifI&KFX$(V!=18lR96@Y_DYk(vn4okkTLW*Bwv(%~_*zr> zVltPWqsC#ca@rTB9=blz3KohW{1+q9 z5cJdk7SDLxu7>iCQ!8(8E$qDh&pg#kwP;fjY(>J=8lmFWP$~<#BY_d<2RqQtR9Vgx z4Da_d`OR=NO!vf*YC3-`n~a7>!d0>>v*N@U>9wI`xR9>a;Fv-h2~vceV4mb)GMUfk zDNIDaK)ghLG&)p_GP7i(6~pjVB#L~A(y%kkbfs%7b8Q3$CtNX9Ll31|R-{s4rH8U< zo=_c0XDMWgW-CP^8bj$M43my>3#3pjRQ#7<`@+EXfqcVPXe9<}kwn%n`nx-;wGi#l zG6T_p&-C`B_B`atq|>3Om5CI?b~;kbXKSh+C`RlmeN!UgN>%$hHq<&ck_JS0s5M0K zWGY)bmTIO^eEC8lObSi7NwxXr(oRh)rda zDJB@!YDHTZ>nvcnS&g)^;cU1WEi&;)!B!e(jIz8fup9%u?5-3tFG2xl3nmDUz&e95 z(l^qu6rv*#ZRPXPJRKfGQTuxDU{B|EZ((yI<~xkDH!b@6yZcl5P^s>>8o__*-jD~&zdISFq+9P|u&y_|NF$Uo@sYRmHonJ+PhQR50^{o0@+upL<7ZA zhACj@rs)xi=uIOK$eXHr`fRJpfe}AZlvXlUp)i~&mHLJWAr13GyXIKYbfjj{R4$SQ zOsl~5h=%E}S{jLfzT>Hv?0gI~@@9r6JSb?kGg6>hVGpG<02EcSRXb64>ZL*3E;TUN5`Zx2~tf= z!Gfwo>6Vk}^W=tyX&V)>9MNC0hBJ*}r_{&|*iOBWNl;_cppLZg|IlkJL4iHZl|6+@ zH04hf*~AzH`D`=*d%-j?l2t6i*?Gb;^xv}KVod0?<@8aF*>LLFYKgD~yl3BEv@1<& zl>@B;Vf%ExiK0&MN6Y}uEz0@a8P4OFrTPx{D|P7fXe(i+0n`OA@Lw6EO`#g5JCpmzY?4$9KH@&+kH}f0uo=l) zM7v}X1G!Q$pXYb{z^>eY3@e07;)KHw4fgbGf2f?yXI96B|In_gpkGc|*pqzduxA)X zbu2he*>KDsRRY9IGXv1$$$M~+!0LT)#Bh}Qx$1Dl=kwK_VMlH=PoK68bK?+UXR4xh zvx0blH8OAvyV6N`D6XZ!IvI9-M_8T&Dyxv;`&BK`!Al$}hez!Z>#l;e*{Mt3}Y zee|Vv?!VvZD>XCVbY$#mUj`Y#X7^CG3jIuOU)?j1a}vXe0!Mq9JqbIRtrZH?az|9%}yWfmJ+pyZ`TY)`pNCqTL(BgUZr8yo9YNuSrUz!>2W0mPGRVXsv1^`M?yN_Jj7KJuIE{a;af$PPW zs3-V4$I3U;*+QBdnGL{w5u2jSLsx2#l5vW7>a0F6naYGCXv)h@I8ux@6J>Sj)_*CH zjct=>x@;O3depw1S+Po)YHLtX|1gc!WMLc#z$&kx!mA`YSIgV0TYDb*$``!#kkSAB z(F4N^wyht;8zB*8So8opw5HoJ`EXt6ph)hrDUn<>%e2RPotHYj@r z5YJ6{P!mq6!lKl1s@X@h@OajPPQyFkX)t|-NFEt(Wdck#|5-wMv)%|9Ixv!hp36AC zJw7X#$QJ4erXvR=1-#Hm(6cGxOEf(6sGv}fT@$rzd^W6x<>YceH?uj5(E{7dI&vh! zD6K%aSV~aOUP;AM$z;OGTXw$a-5%K5<9#R?XczrG{_huh+6Nv26dz!Gi`-wwDL^y- z4ezlLN;ZY!MXjk|&XARyhAO8mt?xBKiVrk;sepvVIv0W_IWj zYo>&KP8SX41omw37Y(J>_*jY{y3^BOcHl@jI|_vm%Zf2x>Pt!#+}T(JtT_E{(12EOu;x3?$#*^25Pzvo}rUf%9Qa_THa0c0a{Lx~1S zY(J;Pur2rR`@2RIWp(B>e6IyV4EATR;b9Ps6k zsN6*|&e!mI-~?)KJ!O)R*c5%9I*a1IW5+dNdx!Q6cwp(mQU{}zI($^vu+y*xXieea zpS?N$U+^W;m?iL=XI*&XjKsZ;2UPJ27o=XYth0(zW$!xDY)7fZr%KqT&Z4QqZEXVhdqf{ z;?xXAE)U@cR1C9!`&cpd0UyW(gp^j8Od>eYj0Es}Ae0bOIU38@g{IX<77>H4j=oVvHmVrTS)mkIJ{h8LNsNk_m=~G4y!pz)YSJ zHaM$MuVeYb`ppdSnzF}AVCcc4t#jvbKBCA{Jd}=5hPFFdTak#MSfI@4p(I6YE*J{}H z26&-X6H}1sKt1vYaHx+Q3W-9@FaYLYfz6w}n}aMHEAR6%cT52+j;RC|X{GA=M>r6M znJ}k5%oe5yg_UHIaKa<_fn^@H!y&M0v2r~bjt})Z`nKMrUtzP*Y+^5ww_!zxBTybY!BPj+Q=Y<&4aB}9)}8^ml_dIRviPNnb)7JUS0Ttw}0XM`7h>I?LF|zy;G*_ zJuqeO-UGU(aODo-DJ3>Dg&>u{h;>+nz_pWN> z^gpY3Ic1f3ckjiG^;dk#P z2D60-(oeVzqh>QsIpAX?2O5y#J8*z~(cmR7_|iBqMK2FbS=E^GOH1poXp{S4zWGl+ z>2J(+`o*aq{F|?*et+ugzxnmQ`quo-zx%^~_k(}+KmXr+bNU&=S~_!`nSnDiaApS1 z%)pr$I5PuhX5h>WoSA_$GjL`G&dk7>88|ZoXJ+8c44j#PGc#~z2F}dDnHe}U17~L7 z%nY2Ffip93W(Lm8z?m61GXwwso`K65{+C6`RakT z#23HccHtGDZJV*=p0@OBzia!0mw(fC)v}#!b9(yQKKq3)x6OO;|8D#2FaNo1>3zG} zuK%-dw*5ij-nQhL=i9Dr{$tzR@Be+gc?r6K< zvUzP+-tth}qEfl7`)hyEcI6*^qb)G+_O_Xy+tfB^_?K-ruD`D>_1})P6?Y7`eQxuE zZIRD^scpr#zSH)Z{D!vcM*nx)wRb9)mxdT-mp;>NaB+rQg(`Hf$0n{nN`w&>IUz3orF`D9!7|I6OH_%(HH`=d)9Mlpy+ zlNg8*F(`p3h7f@S2m}Nq5fTLDErIY#N+@@T$7iSyd1 zrCVC4(7X!DE8ai_U+$;4Vht6Nt)~<{gJ{2%3Mjci`2o)h-ff^XmG4uYrmv_OTh3D{ z=!0u)Jr%KH9VJ`#2^9s{>F<9?sa9{KJQvkd+1n0M!M(pxTHrM7=C9O(6>F&!v^OI> zg_>W{MJWrbsTqqJDbbPdDCNp^)Z%s9sFb=r!1;&hE9Nn?mCD-oG36e+fm#Y2c_~*@ zJ~^LI-XHZ+Np&V_c3d8nxT%>6|L!&A`{{jZ*7hzcbK6Ih=fW(?H8`6}s%fG;(_5&B zWoxO>l{M6y4|^!zWgS$=ijS#TakZ5E#;=sRrkN6F9iYNiwNrERj!Z%3s$^1!LY*49!$f&KfFp%ZF6V`VXi@ z8=I+_3o@u|%yC5NX7u|bYANQ=bIEqfH+?JRhilR{@1xw}n<(9mgOns4G>~qh5^DES z0orZU!c`lnSs!#$!OJ&LzPXs|h<7Q^#f`vqE9D(iLTQ21sCU*=aqF9?fGho!aPbyO zar-yQVf-XYqH6)(H&Wp}zf!EZaTxO^N`ZOzKl6Z^lY5kkey56xTK*oD`Tl-Nmb{)y ztlJA3+DIki|I~SlDJPzoq6;)saN#jZa`Y~hy1A7aH$8+}h&44MY&jL4qo=aAeoW#4cG6fHE{PpkchyVS?`t|?5{Pi>W;s@&={#y_7 z!~Zn#KX0Z0^6lG+*Q26hqMF$AqN1KWiHVAN@+2yz3E#v#iHc%J#l%EK;YYl~cR6^^ z?r&nV`z1|H_!8gd??C($ALjBz6*PSB;W{;6Iy<7fFAJgvYbPPCvVTo}6cgGw@poTOtYJ+wo8z zDul-ik=WVc5n>mD6GB2HO=tzD@#G=sCA$fihJ>KY{pcN=jdo-3j~&u)$7{l;^EsOn zZRhe4*<(bhM&-@6GBq0F9maxe? zHt8YGCH=ywA$Dp$Uye&c`XwPeK01eU`g!;nCrhlo#BV%1;p!$8H^=tL(bP z;puwY?Jy3B9iPvWpi#cOpQo1dg?g@vtG45-<@@Aven=B~ferx&AvlGP zuZ4CJ9^VY;5?%-!LqMZ=Cz15aB^Wij6C&5Qqu)H9TD>~aG>ZS7ZA{4dOSY?NXj|Vd zm+Sa;YCS)MFW1R+YK(y=x3lA85_o*MTpzK7t5WSF0|vHudUQc9e}t3xJT-=9r^cK} z_`Hw^Ihi%N8q)*ZVZ=OjyH1Y*$@zHl&`;#*CLos@W5f`;wv z_OPIx0ntg3eEsN>!-xEP9_^&qHT^`$G!Stjz?Uw zN~PB^RH9y$UTrWWi;{cIY7tkb=E);OI<82pGl{y42GNo_RF&ae>+0&F(YPwTK7y}* zRHxsCFYENzR7+5<=deu3pozo=k-nE9N~VeQDsC^0#^=d}I3cnO5grSz9gCR^5wP9mb`qq z4q6xRSx38eZOK0Wb*pgr*8%9uYsveTe73J{ANj(6mH$_DOZ10192zd6sW9qZ8iT=2 zrjhy6(L@FYgT{zsvA6}RbJohVj5w`9k~k$t&TnU^3{IoweLPBq6Bvi%7|9$PbU0bA zBaH}?^?I&|LE~Oa7Sk54TL(z~U-^IW>d?Z^cA-0lXt(c*ZCQxf|nay3^J#~9UQ9Hlh@$wpS3 z%w#gk3}P8-{6?6CT%HKiB35(imUOLpwaS0~eE<2t!n$1tcFA^i$##7K_~a}9SF2Wi zcI^>IE>0G4l0&!*njQqOpTQ6t4KkyVVPMdN3{HXQ$y%X|M(a&B3njKwaza!DO*TfG zQIhlIj@5hjez@1;CzH)jI6m~)yL$Cc9v-V#+nB_w*Ltj7yYSE#UvB^MojvQ*k2vA8 z2YDP`H-GWsFMq>#bK^+WtJPwYY4vK4wLe|`c(2FapMHvqyDDD&;p)|UKgQGJkEjBM zD9)gbGni<0wzf|sJiVU5aMBhqoWK;pU?mbZ_%OR492#%H=?OP)Y69<$>FD_HpFhfY z$18NA!(7i#I>-+EsZ%?C{PCm38D7)29a}Tula7uUh>*9J5Xr$NoSxkj1GWpUj!#c= zXzfOkjG<*1l6(1ywlO>%sM1DjGHN+afyEV;d&SPqE8NS1gM*)ApV+WM;ohl<76=sH zweG_k^L>|Jd1ueGZ4O6TJYB+Y7Xtc2ms69*UtIiK=(f=<)S8Wo;b%(a1$Xya_u4bT z&x3>Ap6?hI4C5Z?D=e1ZD=I9Oz+T+!KqWGmOa=qtKRG%(ols;GS0H0?f3jGdQ-YeE zn-7-OXliPrqw&;O@1cQz7oI;?eqA5tI4N{u`e=L9*FJs9*CpJgJKXU~+L-NIw%vp_ zf5e4OZ;USNJl@#YNWXv~1V49sUhZDI!`*eLxVXBS$s8OsOXRpyCc`GqKr`B5{>?lQ zS1hwB(8~121WU1{IB<|zJWyJb87;u=d^3j?nVL>bXQx0}>#o?Cf7*BX#B`q{q`vop z8K-81hle@dnK@?hI}@{8T3V=zk@o^F3@+}3g9PMr!rb!x`h@fXKrO!L`Fj??spPQWf1Rwz-YkQ~9ms8k@hpP8unN@+-4rGFG zG=QBcz@G*)+SnKt7ItF>Fff<$B!}bjNdUj{%TOQk$%P(Ucrw3Msl>FCnYSM9(Z{O- zf&zj9djhMfFa^y17zt0|c9am+fX$=f+zb)=rqZaiV4J?_7p}JI6b-ArA z6&(PvFb6HA!?oq^?!nKMZVE+txqJPvps%yR1s!nweDqBMayr5O%8d2XQLOJstW;Vu zEVbeaFPOW`Oz$_r_e(8I)Q84!@X8EquK0ITh)yk+8RKl?j8V2z5+!n>N@kSp=Oo*m z$KE#USt&!7=H`@?fT5i=HJaga?{YMT>o`mpp z9FvyCGB7}Y;J>|QuGVBD5{0M&oSmzf6->;RbD*=Oxwyi)x<)We3gv+lW-5lghc$hg z&c~R8*6_LZ_AU0=4(Sd@JUv@lzzYitI~CrTsNqb3clmH9R?YCad(IY1MTK**GuR60 zfwRRqDzQI=s}_lpSt>3M^lzu*bHyfB9EZVE`2|?+VXDZP_^S%6us9Fx)PS7I72e<~ zJ3s-M`I^31`svp28KbkOA3>#lLWlOJLHj4A`On`xuO)*IR$j==>>NJsJY;b$W)51L z0~&fP&OrfDITDFZ$1th51`+5l3Q8W0W@FKJ1N~~^jv$?qxAG_J>C7Vp|4L$_|2POyuK+bb61=r-6v!h zSd|L80`Ip3`31~-0tR4a7(~!(%(hdSn(XAZK$BbK1#l#XIw1{J9XeU@9 z)?p@ufK;Q&mlno8Jl*Oz>B^P#>^0UhW2ahOx?@k4lnjI60sNacwQrPV7tU4Ry9``b z4HA}G6-Z>;(7-_BJlG(~B9Tq9N+ieq;GRfyat2KtR}h!1J|CRv958gRsv0O890cO3 z0)c>_p$&xpU_vtq53W`GLs}Wzy8O<_$atZ?2*h7Xy7ZuDt1j~gD|APYYu)FE%&qNGLRZjtHF^j7SsEh{_Y zzJmzu@(7JIjtBV#IVV`~up|^W_keyu5d#}AdO>GqXLMmh*o_-ur>tx@V?9JZp}r$WTA>NV z#^$4kCFSLq1-EmSihI>ngMn>iCaXZxsrM`azeA#RM#Zr0_)zghTxj}=W&pA_BF6jJsVt>C~yN+R?!K_G} zg5}TP+Q^Jhy|0}||A)Ohhy1V(nLRzs9`H@F5}Q-*Iq$4JbLPTxrLw&Kq|5RvBWa5> z)@LUr-AW?7r=`W-KHTMDWvoE)OnC-t;9PYTVdc1#-1vqF-khrt23*cvnOWgC5M*giXl`yMEHe<&&@wc%p?rro7;!%R#`3o^ z@AHrl>+ zi#aqo@Xs@g+Qr)avSg8P_Ad~cSiXu)egV!F2x78$0JZoEylX9&IAu7 zjB#F!M6Fk;82b$>hKP(G_90EIwTWX0Npa;jWjISy?H3T#T!q<7EpBd3umn~GGTQ<- zxGSFhqtbErNZQKnd%j<@CT~G^cQ+Kk(b+HZ*5Hszp&~@nT>}ylEO_7vT@Ev!666=@ z+}K$IH419XyeDjaNIO(MMx2UE#?Ncln`L?$r`J3i8e1)<<~3y*Bd933H6CnHnY{ehq(rs6RS%%8#Clxex~*e z$gC7oP+ZI;G}r^h5u7_EA;>kh(edo~v@iF3|1IG=Cr?UGN*{*#&V3PY9Nr-CfvF;?iRhz zHP?a@+py@`fIBRos=%QES8oO6H&mh>%Gz4+U$|@3DjJK%hy1+`Zwu`HWE*j>{sCz3 zd9a(?FGO<-b`2P+s4l(SRt-kz>NH z$QmMvT!X;y!E>y!(X=qfTf$WwV42VXTTP5HZvb z-UNe%m%kyMPzK*$;pdD+4Blx4Uy3@1%!G@PSHARG|2bIBk=V-0d}&F3EKGv46Md#H z072U4Hur#L+e%AaCl6XI&6eh%06$mAO#)w&3C-xu8_YjO%ryuZGMzASNl@2CEF1-j-$DZ)q*oMOV{CcSr4B_my z(MPBw_V&|r52h3izMU{;LbJ0oDBracVgvJkANTY81(=-&{gZFzCW{ON|F&@T!T!Qd ze}ho?gDS`6@Eh%&>jH4w3HBGYF2J;9*TmJxh^Rw5p0w~-t^JK>GSri;)EtcU==6~u_s6gJSKA-tu8yUm08AvD-P;4tLS|6|yEb1%mzlZiP?{!rBJ zPzJ+pbtCpe?R|H20Gt?NoPY)wNM$D6#SJcs9&aouIr$H8if5QE<+F`ghYdvs?~c9O z(?hfkP)gh7)ESS!UC9O}6ikLhvXk zIZ_xM5M;{Q3m4vO7znUb6Vs(_5Q03l$8tC8MC4s!ddF&@ab`*t3TX)x!n=_uI@VkS zo?8k7>Rw^34mVCBkb4f{kZG8#E+_T!RVQvd*p~WkALMIGtyL`Et*_K)gkuu0^zI!k$ z44wyJBKzDfpxrZwRD|5N8?{eQ8VK>4W9~Pe6 z=>1HQh){vNm&=gRR3aVdkH_cISO>aZzMMaQ>ZD0$|E^$rcGB79j=qhLJEfV5vU5X2 z&Q(=dh?ki~DJfY8b0fzregFL{Lh zbGvciMBf|qSZRG?&J%XKoW_dNnmNG#laL5CLwwk{@QeAMd@?eAWQ6Raw;oq^Pg?Fv zhlEkomem9dz=2a-U6oK&ba!ml%%w{|_~6q|)5v)zKKS5$bl}9@th+r$2@sSi;5q|4 z`x+X3&q7s5n@QTlD{1aVV{ATH4qLB!#4=z7>S6z|&6s}EfrVfAdwF?n*|G=6mMyqL z-`I;@fXu%$@t8)N1mbSDk&!crCJ2f2dgh5NfdAba4jZW^Z26T8ucvd-#-dX* zX24bGm^b&ukp)Rfwo|7{dEiteT{A-uL|NK@*Xi`>H?i8GR;p4{L z8aHd!*6=X6HHiq@nR_wvB1TVKF0jW02C6h=bY37aPccy)B zPqf6=Q!~)ospY$U-kQr(ziSFniQ%FL{u6B>jjvscpqc)4=+GBaCyk#r@$)0(<}@>A zxO8{7PM;1xujj4Gld<$dO-V_9O%N8|dy6rvBPW5uwpuH*c98i{QY?=zudBoINUJZ zceAp_LL4uB9}fBHutn`3my|<&zVN*4zCfA@<-8A0DVG_94~-eK*lVJ7XrD|)u$H&g0NPm$sLtgZ~HG7*{2>Dd>`|`vT(!{A_aCDJ=T1aJZNEJVj~hmIW}b3m?bE(&2dk zi5>xOT5tmJ?~d*1c?&=Ni06V9s{7&NPEBDn{G@aU|I??);K77}vg`$*V~Pr+1HM`w zLEv)$-lKN$#$5{!t;71mM9#IsKXv1Dc=*{n_=2!7&)AdsQmF>>KMCVU7eQ+$ zpl{+Bd)GStbj-<`HL;bDm-OSu=}`6PVL;!^ix~SBK(`(bL5{X0ti(R^*6tRO8@>_v z?|-^yqE8+;&{h{LRDo1e6Aeu>Yy||+7%OyQE#A82;?n)_Vg7d=@IUYmi&?s>R{Cp~ z^J!dD7ZxDaUmBL5Cy8Vbmeu_b#^#=7a|wLG*E`^YESLID`T(a)AYXy{K>%aN68ii5 zvM`s&g$P#_V)%#@jmM(PnD#kgI^)JUI)>3*!W!td9Zg6DV92y8kqqO1A`zNJLYi1c z@PBqZrW>~WxLe?UE~mqRKd@SmZTZ(VgCHzsyOg|PXw1KPu~Uc`T+V1D{?{)|UkyG;`+CPv843 zG(8(mC@R+_KYzGhs)^43hYR9jL;!+#sUwIJ5%`YF9UW~y`Hn4VXK85+8ck^Bf6)J& z#5TKD9RmLU=061gWbIgE8}{~Eki;JoAj{0~0O2>sr=ye|4} zK#-(R6W!1N?FTx_MB<(!vMfB@g$`}hafNM1;#X`t79zmCdidXRqIBvdG!y5*u0wyp zw?;M~GBJN?7Z-C-N!2|K-V=j_i@JL>EtSn)D(FYJ#dw(t?BOV(wx zYnOi%*5A`(#Fw)OlnVS^TGaPK4jN32bv44?~E`0z+T2S|bv z>{oF=*bScGS||YE6nVJZr5o_2|MZ=7WqZb+r^nWOQYU{Tx@I)MuTX31{8FP))g1QxfKT7WyfHKLc!Z1YDQ|>c|&U?e^)#LL+0p82V>a z6qhD8I@v5-<^SU+X=z^T-v(DnToG!3Tn*c%=g z>q9hAjQ*YVR#g-XAq6p;A-{m*C4zc-n6K~XY{;aRBLqC)6RnK`;--ew?Gw{%5P#4? z|7EMMu@0DQ{^dW_>m9Ex-)B$QN|;Ohv29P6WfM*`4(4ND$?*WrrrfQx)J4w7_Z%&Q!3_|JC=SlL+bmbs((c>G|$y7ng?o;l_a6T!hZxQ0p0sxFE#?pdd_uc725X)P&fQPPB@3GmM(jZ@f8m9Tjd zj$A0FaTrAY>m&3cn}P$^){VwWCkN5ma6p{8oQB$=(QL>a2mtXBFASVpJR_IaSt3H9DEKSFwi9IlN@ ztfB$`a+SWz;N&D*^76CIeGebTYV!NQXd!O%D`OwV!gufDk>P;joiqry9rDf|KtIeC5hk%>@0ic4TpKYbhsYggc39=Er-u45xE%r zUXIE}gd``Tf3)i&I8IK74;VRr0IpP;Uzq=x-j{zeKfkX}P}14C0={r(cv6`dUmJ1i z7Nx)eL$5EXgpSr77VZ-JFf0r17vlQC@ZtBW3M7#}zYW8~$_ur%%G!G9LsD|U6Ik*D z?msz)mdp~-3?%*&qEf46PEM@P4lMaYT3?UgbqVRFw7ypP40c!T26(_oAOR1|E})OS zn-zKR1{6y;e;(37WI8Z=uncy>g;iU=W5@7DsYY5^*%w<_ zSX1~U#*QuTGBUI*gNVoHuoa-$WAdFbM0#5i%a6A$4 z@Gdan`+*I(oXBy4HH<7DrDY{XdGUT_yU3uXRpd#?17$?Jt3<=)d3nsoN;@>6i_&?mzKbs0S+?pIeh3acz|z`81SC?G({@RgW?+Bfh&L*Zk< z0c3>#1@@PYX3!RBO=6Ym!5efH7(fq#gD+eN-T;?D3th$p2Aml zBkW;A>A{2^I0>!iwqZ6dS5>0}Wu!$C)Ubv(=0zd?(+=TJ6Ej$dKicWw4A456Sj7Kb zi_{4?J{1V}XO`v$1PmpR(AQuaIsm3p4Da*VJ6@sdCr*6&bp6w1-@{dN%m*GIxPTme zZ#>+X@0yZO3?DQ+(5XxWfr=6P3J7q$?_T!iISFm-*x`-%M?WI|3>JfB*v~*+Rz&|< zCZkhFcA2B zonFK;I)MYJ&Vy6ABX7kT|4c#r67EKl4Fb*EA z7WB_+7YPkC7RQ*(olVkwkY}U$9Rcu)s=?+2@EkZj6G-Y(#Rg^Bj`HF1la;3(C&5iL zofx!`e#Esj32qXEpX~EW>JdBGfGHp|Pz6F9MCY4R5PYxB1YW@bF#aZ_L8}dNgdpI5 ziQ)+vEE>vAn^@*cB+IG1oW#F@Z^#;?jKSTX;EV*Cpbg$g!YV-m1{7(SX;!y{=U-j| zxVlEKiH~2jsJ84mqBlE{>XKrq0u`o~5}$2g!ceZ?@100tDZhVz-V} zJH!n8hZQI080?M$x_5b}GYP+wI1Z*hflPqKQjF-gpqymiz^4Kq$d+YqZBV!gk$*Un z7W%!_N}VMI+r|iXI$J;jRXtS+OiUpfsvz-yWG~zwcDLpq=z3W)B*?0){71)Sp*JiB z_Y&fSnXobfhHy0kzes@q77#%W3fe$aa0LV@v=aCLwoLR{Gj0({0feFq-P&v0kz4S; z-J+A2AOr_)z8C~`4M{XTh~oG3Sc>73cRq(E%1QnOQoM}}5pu1G{cq+njI6a<6Qlh+ zlH33u;g)*{+zwVDeF1Y&0ey0(yF1~EZs5x0^{0rL>|jrn#a6g?0RGD@J|rYKp}V2) zBv>fYwRR$IcMlP>HiWJ~gGeT-t_b-3K3F^QzvOC`%4o!bPe%MH1UdCAC?Hx!#HCCD z^lT(y5&G>RaYw9T=rTh)hsz-s03SJ^%5o$?z>InUpX=*Z*r+3E+mU~`0E|fLLNf43 zx~X^hPG~K_;M+DZiB*IZ|9&6vpY+RBG!=`pUn@fXBfDQGR5_Un3RE2K`C$TnD6qI1 znoepUp3LHENkb4j4!*cwkyBtelJ98JDPY0Z2+ z6a9Nd6%k)ZCBy?$N)jOkcFube#WU;n!}(|6BL0%Y=bE`TPBud~kEutN{XElb09Y!WEB9kZ!pDhM##OX|a~1 zK_UID!h#`K^S|y@2mW4tZ)gDdXCZc&aVMI{$Uy#ej9oiT#V~0L3=H0RzaUF-6=)B$ zMNo$1Gt2Lp_pvGw5G|{9f1`94Z0xi80O2M9`+xl!es?PxU;}ub?(UA2ZXDh*OyEP+ za*wt+qyLZr$o>kfW>#!M0@?ub-|RSghM1wHk^I*vHJ4#9tu1iU8uuLyvJ7FlLuyyw z1Ib#3Ab>a2&}+ysOp@Tr%AUb8!2EkXb$Ahv4ur$GKI7CHd;0|l$lJRhB;F?|f1`X8 zO!&AWbLS9AJq-$K4oa!OYTktW*PwqtLBbou#wIS#$kN%`CfeyaVy%-_D`v>ggKHE+ z-MYL9*`N2oxPzPd25nD zfce9<$bk#4Evqea7j!lvZG@!r5pIOFY{4pQ!uZ>TGLsetARGCwdL;kGIUUy8uoy?N z=)m_br``*!n%vfQxp-411ZEio$6xyEg)?WAU;hKiXaB?h$US_){~fXsHo<{lCzdKw zaBE2_5%~RmFaU&3k$rXu7|&pmH>zDs{ts1fXd84>J; zIZ*6C47sfs860h!kXQ=^4jpL9X|hWeX$>ZsL4?ZhF>*caD#wU)bO!h65R#3MIn)f2 zO{j2giw4=bmlLfOlOIenGKPmwp6nw&VDO&_a5&F^0Gt8uzSmQ01_V-&>GYatk~4}m zOA_A|?wOOp27rCoFyI5#f&Yg7O*T}3;~V7Qe{vO|NW$55%_ zxsp&a79P-#!Q0zVbWz$3E;X8HH^J6tXIpiUqyqqMrZ z8r$0>ykwe8%rFxE8>0qzqYc^lVm?pQ91_BZ^*k9WTksoiSbz|`P#cj85e&B${RT!4 zH_^7ykbelRkyO02ceXeXH^ZW@pDC@n_Aj*%LW2LjUQmh%KCBpIWmH#1#n|z=T$ag% zd!Qo!{t0$%(XbV0t(al{m}#{%C$|L#OwL5A6w=Q-kvD?OA%asR$86jfwtV-OUm~#g zIb48nYvg@Cam$`9Z~&3x>#u>OU&w)+d1P$<@AaLN1CUKhREfZQ5_tR!dK&g0aAes3 zf&2$O1AB&y;=?*I$ulbkjSRUW)47vm;viuUW&@Ps;4@`qwZkQt?mbYx;OZqg*YJQ$ zAMG=D0?B=vpn>v*1TGkSwLln>HUD4NySrMd0;{2x4KhQTutiOe{TGJ~oJYj}ZKucn zBO8N_N{gK%IXQUXNX*FrZz6C0K1h*&Y?b`s2P{2k-JT@+3KtDUwU9Rpez0zPe0!2@ zBK9@m5C8Fw{IkBZzPGhiOOhYaXj+; zd#|pySC4IKILCw@Sl(O{`1-FujaGyH4obl&2kA3 z`Gv@E!!qZ=(hfljWcwm^@{#>{Jl;3*oS)(Y*pm-BIbh4g&2(Fn?DmjjAL=)l0`B*vj0J+LjDQae@2tBWE>Tu z!usT1VXqK|ks7vHFCSa`)Izmf&)3WO>bgh#eRXwpU)k-e^Cy`2if`>fUEQNPzFH;Z z>xDcskEg@_MLED>hobxu&?r}%<-&F|@}7FR>ec5HJq$949dSSQ|EYCq1LMOd9v;cU z!y+12h`ob)M5KCqg}AES4qMlBLY)~2lh_}KQG#6e?fdN7zJ1v62gtzDSJ;hMr&mQp zLI}4j)da*7N)KZNIo}tJn?X19cG1q z|LU$W_9m_^U|{DRvVd_u_JYuG4uJMDXvqea_Nsw#73><@=Y%3*7hFerY;aRA5dsJM z#G;q9F3z>&&uC~@EubkSK=GRI(G95oVj0%L5PwWBGO+P_F)qEx9=xFvA1%)|Dl zy~(h@u>Uq^)ZxRlF0NUmMNnuzHVZPeMjHeNSaEUi48|F*#$k69 zj_O+PVZf!~AvOVdar*&X3(d+%>y;U`2J%BM#uR5`!fq#(?piWU)rF`J?-93`BU+oY zdK8JjZDx;h!d?{Cei57^TErsaSWr#&?*|-gQHn!iGD~ZUv%z6vVQTiXfF=OMbO}XV z21ABC4jO|a!nRA5NCmahMpj^oGszI%!5)|W1a(@LiC`&N%)m}FS~6G95pg-9IP5p% z<|O|6$yyrHVN6<_fOdbU>_v*gF4x0<4iW#o(2uc6jxw#m1V$ZY@Nj)JZJ_E zHn_rp6NhW!v@GN_kjtQ3nHbp8vmbJmbro}G(29C7M~r0owO(w7y=GvUu}^bt(;qpv zpX{X}^_PMBG;?%%73fw42u2n*!0x{al*3DOHO__w{}`wM_Z^3wqSe|s;eW431gEkTHzdX$r*PH?*NwF}N6-s@<#?f-MNKpH-x9Po}Mn!v6QS z!U95q$POYRtTMwYKK_y>|MSydV&v@^fB*Q`eR9NpTN*uq8(o}7y!chmyLtRbDGEgfDHLFM+uu%N&yZi(dQv50E zi@l@-p$U|C>Mlx#`d!n*S5Z3D)(Xq7u+|xiM-47v#(rykFhRoml(PJNDhSt*I$d)! z_EBD~*C}Drb}BHpiV~u>n1A6JYHrp?R61&Wg=7_5>vHimb=3T#T5AohAe|nywl-3c zC7Z2v!blx3Ug!!c95u;8PyrqV1sgs1Y_bP={JxSE-QPcPUX`JL++5pahBAsSwnjnx!g7 zJ0@$LGg2eWebM`rK$%I2^V?AqY@fB38GnHuHPO(={7PyGV3Rs)(*m{B5{xJE+hM@m zhq`Xz)GW;=YDvvbDmbT{3Ii;rS0oj5?FE&E{(GaY7OCwe&s{@>;u($_W}@6SYDPmR zYK9F`?AZ$_1!{LqjapC5`RFF)f9f7JYr$$tn7)q+T~>t}WiP1!U8S`Sm0(FD@Q=D+ znQhecs4{AfI)|F6d>8%MMJ+Y9SnG++S-O`}@|#1{BAid^qXl1hO3Aa=Q_{Qx zROC1RZLJd)dh0hT6m{+-oj*{a*M6b=GS^Vv3-hRXY41{kl)Y2}YKytbbFFpSe08mq z1ogo}ZoHx<%?zfZP&d#2>;o!lbq#8x?WF=U-lK9*gG{mPJt|OJO1UTOqLNW7Ev#TI zB}c8dl+7)a-?2NCd-w{E^wZdqg3XXxIZ-<-m!7@ zZBfIrZl~dHr)7(~@n)Hm6Wgg9H(+7SL-(>}c;ImA9!7JIyJ?Z%FN;qL`rw0{oV2u{w3wWroMr4FHajQgbxu%2%=|QE z!*O=d@fhP%eEYQ9_bHq0i@3#8oD#&&VF$%De9({+hPt*%g*qn zO64U$Q5Jp>L#Kbx(12HDJIBNn#?WW-3hj=w9~g~n3_; zH+=9xObmT~3`QH1Mo;^I-jGHwL{53`m)$Qjwid^JcS*MJI|frGEsU4aFBLvsAj>Um zn6FgQU(*Yfxjbgwwr#RPrBEwO;qmH(g?10@9?a)y3+ER~m36%Mcznr^m&VIvvO=CT zSDA)>U6Ro+<;n)W+nph17RNeWDjc=&yMa-Uw|Zb>arku{Nu~B z(q2v!yH#X(WF#edxNUQrDO1)-r88%4leX{{pzrHQ`&#a1?nQ1*&Bb2wd7Yh9nxfp+ z(t>g3VrLJN>7n(Jt?=iclz~OxY0;p%5e&WTX1jPZu7`MxlK%Q&xP{DNQzN)U1hHkG`?b&Q4CY zUtQ4D@2AuGE%j?^N>A5y2*Mk?9HzB8vp)LhqpmLhkuC?(FP)t;0`T#p{tmxzT}P;5 zO3xIs{Msh_fc8cV0gk2*T>=uz3qtKZRcM{TXh8nyN7g6!l|*#)Z$vYQ(H z8vV-9J|JAbzHh|kq$T(d*12;h&PDsXI0UD5-v4;#m2>CL_4k`qeggEpr)SC(#jE}H zoYe&(r;_dMe@$!1&3&z>s}YxL?1{PovSPmSaDw z%b}Bp4xO}N^_95x9hw$gWw@WP{tu-1d1?G`k6@Hg?CI&*v7>QS!Rpl#dwbv@`PYU9 zKHqJtcq{O;tYOrstr=n&^8&h`oct4pmz^E`O7QAH#L@_XpPwo^dZerCkV_Y<&(*cW zX4-7`&V(7~T_?Gk%^IMwzh4l3phGaF=Qk2pvp)COPabApdMvJ}@JJ){$&1&&5PNLB z@Du6{CfgU_v;xU0o!=`(#H-NISK(%_>t50RU0p7Hu0Ol70%rfRWcnY7%5-Qns_5%F zzs6VL2Lz#0ezPYNYhRGPC)-vsIf$;jbW|)p8WT(Fp3h?*N%GjnqzceqKs~Fkk9B_h)bTcQSJ&&&`O()$qQfIz;VeZ9KdtE5Y$T&JmivFibmExp|c-dIYEa`gz9t9H4F+T*?I&}RSKeHDA;CX#Hi)G{E z>{Igd&#w5S!|wu}F4UZ!Za%i1(6)8#Xn`}jJ4h*Yn>i}JaOKs-G4tca6>c-*DbLkt zxWIl7IZ+~6eJtGXmB3GMUFGF<9TrDpvE@j%Z}$xB_cBLgZb!OY@()e>!QBwI(}!eNmT1hFeVt!N2f!R# zEhz{A1duhlS1>2=z=6q5V9GouGdDMKB|C=4cRM0(8TF}7*MG`!&UOiqgTq#mILABi zy4l=xy+3+{G;iqqWV+7;u$?huCgkT|zpl{<$|9yXNF?^zAt8H0K;HHRt33l15skk( z1?5O(OgFwXa^kJGOZo+q@rtObi56zY#DUaD^GplQy~LUzbmqFlN)|Xgf6GRp9p9 z9L{YHFuMKr9tnCc5cq{hOdbv@l*;0_@*hVQv+0Gr1!51k7oSe)DOJ1@1Uk-HZHpAn zA938?ZhJcrb9+cse(c z{A9gP*he2>FdZFUPo9i9cW#XT$UnUk=gj%>Ho>Q4^&B*>N;juB?LUV8(+S&QN+XM% zatiBG+!pXg-PibqBabU0!ohR(ZO)H*w{M_~Y+iYu_dgG*e=tD}ucrXjst{l#pFI}+JjsGPDF;r@u zgJW~%Y$uoO*@IcLz47ihqF)j|UT@Ra=ViviHAlM~vIN+Sk#E|BQ@|2Kek}iylj!NG z_EPCokb9wm$s2(6mX?-yUh&HBUekGX6Fq81QRwdt&(c^78N~Li6e-U4OdSEFiLG^04oG-Zr-vGwH>#%Yu|VL`H`WQxMRK9`t`onP11M zIdlF-t*x!e`{wU!fc-IM;78M;fxMYSb{?-m=SdH4m(THB)gOI5`u(oxesjbW#pDe! z^W7#Ux$);mUhO_!$lI1wa}nj4!@5 zoAbLQ-tWHqW8Mv0(52*dxufT?=bL>ylb{N5_^$DE@(`Vz1)B(pRrKqUU%f{>aG#05o*_ z$D%}+e8~DP7q2qaZO}a6hV1#~-J+tKj*ch6W22*8Mxy&QWf6joj?qEBMxJ;k&kg7*E;R5!PBOZ zj2j%&)Q7tKuX}|`Jj*2@)Z6dAYjSji3RpFJ_H5B?q7FLVG`)+?&++zloO8(k;55-} zk%&|gn&#lL{CdY|_F`jU%T_lfkKji-RKx9E_jDOaNlZ;eVQ4fm?POQJs-r2<(c4s> z_wJ2vzVW8UZpqAaPyJyd6wt9_?>l+}HE7*&PFKEzsOlGY_g^-q{*pR-cCcmD-O8R5_*IEOd4|QGl(p=x}SoF>9UDn=1XAZD&b!GVkwBqNRrXrKc zQPMBa9E3tz88_8=-lTap&H>i~oJU44?pC%C%Vq)ep9f0b<{GZupI?3TXVmGaufkT~ zSo8V3dGn&N49Yb2j$o1mIiGx3y@~AS95-&v=O~E%`AzSejuK>jE?58HzGS`gS?m}J z3tRE~yr@4njUHZH=%H_!$piiu+iA5aj~;2=#&$$Q`}k-@b>@#muQQk-6o=n;_X51XdkXL1UuOFN?d;Lxufc?yWB>x_OEu^NqM}@n|W?ym#bR?SSNn|IT~D`gvA1Y{4Qi_xNJx7f35s@s_TiL zO(s*(H{a}f7ezo_Crz@2hTEa(vP`SC88hJuScg}%gF4`k5^$zPY$T9%XsnKt)udmO+ z;@}_(I1hf`=i&l6?mvy1jPCbMn$)(dZP%`i8@(y&Tj$R=ZF;XPv@A4~3?dY&qNYm? zDf-`2eV_qcVH=GL^mQ%hzwhz+DJ`2f*Lr**N?kJb5Bx|92CJvFo`<6F^C6e(8ZXQ2 zv2im3z@T@11MF;k_a?Pvdh0xr*(C7O2sDBYjk({e-$mr!c_Cp&>lmb#$bFyAuSrt! zx1s%~r2R*=7c-%GPyOR(*PkIpyfA6w2`m?vk^Jk>P2$!&Z<5PxH-1yJYvVUq3m@(T zrMl+(Lk)uN3&!UlO2s1hczu8?OoK^m_G@fe;z{|%SAE%qDcmH2A5rRzoi^yDKa_p7 zX!cYeaQJ*QF%k>{oN5CJuyI$>Hydql+#j3y;rJ->>j)TLmx~4LA=Tae<0b1`KSxQ5 zF%w3!*~jM>F5oHo#j)(;(iAS23;YD9uCJc=(YXIQgd_|B!VnTHlRy)}1t?zr%d++D>|NFf6KJW9n2M&iMC;RNP_da{A z?{}@WmnS>yP<;Hln`oe&M=@MG+5bFrC|)z}e9W1FOlXMSJ6ug zaX&UTSJ3y)&bI;hF05YtGt;)%QhZaUXNH74+?XtK(}mHn2T zhX;oL;PpGG{*$>V4!w_&cJVf}mz-QSo;QzY*nFYB%yh_h_$^;Hq;N}|wd8bdU*r0_ zKX%W4bbhYu@2}dt3Iy$a9_kc2YJ6`~Y>d@)tV{rf2Wqp_>JBp%Jpn+)Kr^dz#uUPg zE-&^94A;rY>6&L}AOsR0hM1g|`G|xn%>TdnCI95oU#ggW?@=z(%BJcw{=J7?nJ5*f9}Ek z(J1}~q?+Tn2J8WwnYaHYzi95i&injfSLk-oe^9>OE%WNUFMrZM@BeWPgvNfO7G`|K zx4r!}GuNu0iYFbd0&YOeV%)DrweVWx)w%dSLq z9L+t*w!>WNP>VIWl7)(fS=PS^8fACaKLmqu4j(MVZt*Q9;x{kKQ!YaFkPbr9)(!3) zylG*9^8d5d;ZcD6wW>cbIbP|@Ts+?5pTXB6jK2NW!eU9tX}4~E{=iVfRR>k7i_6{h zenuW`Oq(*Bokz4s<+Ep#&+<^b6mlFD9UPR_bJ>beV2gT5=;*lb^wV?a z7!42D%;SowDaNNss!*vHC=;(**Vgux`M7j*%m4@(x*|@EUX@>Te&!s2(($}v#=LP8 z!hF>M%{WxU%45>&*QJ9yp`SoQacq`s*)%!{mCUpa8Z|Rf_ryUzQMn290=*LRTdiAP zJ}3F}G71kD7e7@4dyaydsdP4|IfJWK8T2dYuoL6ram)tCj>(VVvK8yFF$n5@o-`n3 zw79q!Y9CX%y->qv&T-hNOcn`}(LUC-sS3{X z0tpDp@*5l9C#bf=45uIl4iGPwUf&XWgVAqqRIHL-Co3p!&aa#~a||)YuQ;Envw|E3 z!h!Bm;kYFrV7XYFfY!yPR*S{69Zs7J3Aub>aw7O8H^FlbUzUCyAA7J<@B*7!-LyQQp3ys@ATw9E zZ*~1%?%Z6gi~#NKj}7|W?TYJpH~xh$LPIf5mk%?;FRmEP0Q^;}eLlb`8DQF9>DKyO zCP=>{j>R2*43K&X@Cy}34hvN7#*OVqkvKLyb`+Fa7DxyHU`D^kcZ~yL zAph7A!DC}iPGez)2e2n>EO^XF{^9kThEB#1aC8KCKV|4)v@iI9)MUO^#R3j^PQet}SUv%5~Gx{3HFMc^M8CQHT9S$Qlg zBG@jv#Z)sLnb!=Y?^uC8Fm!U3fen4~>zvCy=-8XIqs;0}tP z4x{~R0UulW;D2se3bc=(>jzl>C>~A#JA__~vG7*;reiiibq6cRefdve$a$G)&^25P!hfm@^ zrhHc?!_#H>17!p(XbpHuJn+kL-%P85Uj>Kj2!7SUQXrBk`HFUwFW`=par7*5MCrK0 zMW_R4%D)#E$A;^M!E`>IMoC$Q`a`K;#2}-Bn?_G!p4DJh1Lt%KEss0EB~Zbt`k9v& zD+RIv5i7Of>MaGU)rT`8;$Ofi4;X$PByTs8#oKTFz5;r}CFE1|{DUn$&ySk*D^?0PUL_2T+Z3D84F)=*&1rO~?NDAz*PN>D>&QZ|rT!W#5 zYDPydy8HXH?V(BdPR2fEuFhO#JHGY+Wg~31VD_)SmMcrjMr0YwG94~+Suz=i``!g` z)H6bj847*-aJZpnPcb>fibs7fo&h?6_Ui;_GAVu~=w6W*8|ciw`r@XPNf0)%Vx0dA zhR%!vT;jol*$;8u6?k8x0R6;hN%PshnI2&^lGoS z7dr_W*rd7tqu#lmzqddQ+AJ2M^>GWJy?AlMFn%mL8+o>1(af&JsR|LF5BYT!_S46* zkr6Hn_7~jTgZf2j!z({tiH;LLO-L{hTGd(phmRcgV*lO)mDXN3iU`{BAy6w0D4ABSgY=hD9alT9o z`_!dv_;;n>m|#^~aW&crD448T-uW$DecfJ@@Yq4M*mD!?&;= zBHpmfP_STsWGND_F4}t85t)s0%1~z`5Ncpv~AmPHuIPH^1Sz8M{VV^YGMC!$WTtnY`eZIVJWrRDTK$k zA^Z+&)@5WYwp7*5QJq$OX`)iW{BH6ktja2t$;K~DPMDa~BI}k)^-u*P{T$F?8TiMt z7B=?Fmh;g#m);)`@RbV7OxTxU>9O5rTQV>J%d>JyixsY5K(9@O5#2JC`Hv|YKYppD zDAwdl{K2JECT^)FeYKV_y{j^;Ly&vy<=TvGskN8OEi+&pKmO}?tX4hx7v-nI+KdoH zaP-_M)Ss(`eOzIgT8`B~Y7vN|`tr*!6>dX?3b!9qO-`IpG3A#Q!uk$_yc_K0<;?9` zrYg$a$`x*x1(z=?wA@tK$J1MdBG?CS)e6$PcFP{KxF=a$v=9qc_;La4RYJa=#pgF_ zYx|UarEY~ojr!01O5JKzDnCVGpPQn)+eIN1Gzx`70-;tb6!Kwjc|4$njbF)vZGrW} zuePEA!LqA!E+4;TE93JAPQot!7`A#?Zc#4laS5NL*UM!5Az@*1V{&(Lp`x(V4P3?N zg>Hp~pRX_M6LvQyC-XtF37A6p{KqVoUd!T7DY-(eK){8C|0Js+v+H|nTMw z2Tnfb%SIkUH0WDPPRd$kLYYj6N;Woj!$KoV?sMx)?j9N{{3#!Z8ACe%d48jkFXAV& zxB@-Dq)f&Vq)u_C^n9fy%sb!RvOU?JIKON6fKUYaf?ZZt;^QL|$wZB1BW10!GLFv( zCm%2Qd_4-(yYvkW{p9k~kT4mcUuYJtNaoYZX%(?hp~qZ32vs;L3~;BoT%{XVIHlcf z$<3Z+{klNQm2vq~S}vDgB5N%fk%_Q&U`cE1h^&M&B70ociisrOM+PIMi%i%Dr-kmu zMwH4Q;5Q2OvJw$r*7*43NfB;C#1gu31?5wUTEP@c2_K6t_|IT9E@o?Jz@CU#hBw;( zc=L}}*?+v%-rn8-XP$jJh%ICTmv85VTy#0F_Vi}TC@YXX7>@3@7FF2e!}o) zPF&JT;wGd3CWD9cJ$Q95$c#>1DD$z#mq1ZHyh@}%j8 z{Kwv@og~l>82p&+;S(%KSx@QkRTXQx{>TqJ@gw;oudj5$ZupJvL7wCmgU_<;)SoGG zNf$}yEg|o@{p6F;Zpi%`v%JTUk2wl;mz}*sD)=7D|8$okb*m^ie**;`okafGgA`u@ zpJUvA^wKV}Q+5(RZYj-!uQKC{%j9GBQZ-Rf*?tN-`4>aZV(E#`DC~`|;0xVJ3*ej0 zAUfDi0JgWoQbr@07y;Xi+nLYJH(|Ew1D**=O!c}z}X-+7zh2i=UEx@##5 z?HP@B2`bq|5oJvVKk2l(9&!%Ng`e(L^2tKZ>da0`sNX=^b$iGyvdrMu8~@1@iuw2{ z`f(kF6fC2Nk`>6Ez1xsC*iBJHT%nR;ku$gezS6NDKgPK~Q1nMXQuO#E%7u?}?1ztO z4t6J5HpL=;aKzj9aJ?Pmodv&c_^}J};6si3^2r&1U-wS3_f=B_^86~_xQnrkoYlxX zoR91Ir1z1!zK`M>`X~)~lpTCkBtgDt$6(|phM%*d3S)oMA&R~E3oS&BXusT-;6wZ~ zIm_mf3OTn`7)v3@T^tP`=g{H?O8n$!3OkARjW2-j@}DVcSud%YkdqpI(JAn$mcfrZ zss_2IH3R6c8>FsTOYSihB$+=%@yG$Ktb)HalUKQTn<1yS?A0$wcIpd?fnPe7t)(R7 zw~ibCf&7d2!6$zg<-(7e@%hf}9VD0FERr4hgaU>qNVfPOMZG6UIh_mx~*x9e*kII=zAn2^Z@v1ZPVagwyv+C%vqZ{+xR^!*)arJ69xBUF{ z!F;IGc;RU7W^T@W!u-!{ZjNrfy+>8O8^5is9ZVk{cFRxCAKX;yx+#BfFgQKmZ7?x^ zFu1lCKk&TF&vzRR<}Cc}nsfTLh1)m^4JnGQUk~2A*?0F_NpJ0T6{P1SCFSLDGy*JM zF9@zJQs5tjQB7D%zCxbp?ha3BcX$7(sXcSffqwHkH|w0?=t$r}WyI`Bz(6baWK!=kg{d zG9peq*>c9(FH#(^wXdPU5(yr7QC1e!)g9T69HSoRtN9#x;-ZdFNwp+2!DoV})Abeb zr8X=4gu;RbhKtjACUjU;SBG}k4=HRF&gXHyzo&hN6(|fzy{BbE-+pb?%)-~W+^6b^ zwl-s)Wr+UDl`Hk3_H&0g9F0nqPV!V9vc5{No_R;;+~kH6eE!Ag<<_GtnOZkt$4jeM zUQz0+Lwy>C1RTY+up*8eOtnvTaeVcWYKcCAtz{K9Wu4j@u(eA2k)354E_}oy)ZSCa z?o@E-T3EWTt$&-{gr|LR{Sk?UL|^c<@SVo)?y4Kz2lf}dU5%DGBFVP@J;HPD{p%dt zYro|C+FoWGx3%)>LoFSp~^$l8CX7~EHk65IISfHAomX_>^&Rz|LsRn(G zK0q_H*;&?C>qDY;#vgj-w^iGxW=U-VPI@b^>_q9F4Gp}u)=pp2sLtoR_V}|W?AqEU zbO{o@Qg2bZ;)ZZXvX1@s^tABN&Yj8*tBCz4JR2tLDmikF>U@#l$31;&H9N!DZXzwz zLa&T}II!+Sfh_s$Y;WaGi_q+jS1z3{*q_|MuJrA}`N6IaQq}7HT6J;;+cN5fQh9Hz zv~*p8EPNo_Td(gJD1P$fbU}kIgFSIy(8CE!3I6fT+3(%GyLay!>txC7v~0=4pxnT~ zm1BXqhsTZ_$xe{HS6+Cryl~ymABi~3`GXtYyztjw|NM^&ISbZ` z;nZCk#Y=u8hs%wT`mH$lWC-;+tIGE^@%pCB+IpsRhRqq4tgkB9<2&o1hhwF=b^N72W%axwH0)QrT=K+HJ&A$FOB)8Ot@IvS2g}jC^VdpBgXcY!f%>PUz-*R zWz6|!Rl`jA;+BtN;#QV%*JrS`x#AY?!-qlJ-xasC^r;IjMtdwf{_@LGe!)<>Tys{H zzTtsalj)f=G4D6!WRCJCzFaFlbt)*R^wzss*4FWto|L05XYSl#ZNd5doUrr3Kgzx4 zJ!?L|x|=oqC!H>2(V@vvVQFc5;M(sNcNa(L)-5sN|4Ym#Wvy=z~^l#+LP=`j8Oi!$VE)jDIuln|T*!hFd8^ zqC)i5^_F&Rc%(WxW=36M*QtMMf@f^(6WXCyhU~N`E;oIa_4QX@iNy=}e2K-Co%I%> z^}NU?wa{f)88!bf#ZGW?YQZsm#U3mP*W=c;fAS?Cd%@nwn3;dNoG= zI?Pvi+alD;$5^MWD*T??5_h|>`NI}9+tW&d5AX#~W6Xz|E@zbQ|9iIm5g4JYu0$BO z8E0tkK6Cov&KIVqMr3`KJf8&2-un7#d&|z69?bu}zZs=whgMtYt2;t;Jf1OcKkJ*U zR~H}fTQ$8;ro${?nTF+6G2v!+YUG$t6h`trq1DQIeSLywgpY1QrZeVO-8W-q-hFL)$%zJZE>9O_ zrB^B~DsAOPD%9UBwOYRul|i2{=RaN<{cOdEG}6OQI6YxE!JELO9u*pLrQXq2ZU*^9 za({@AC?88Ugb7cV{Km5!zW||i$&BVqG&&D6r{x4YDpX=+UITdtd1~YUS?ccZ;E)K3 zzBF-mCf4*bY)h9qm@kENcUx-ikm&G%xg7FE)m!tek-W#Y##Z6$tMFC07HxX#_1Aaj ziW-dn8jxNOd+j88w+|0}frZgjbMQ*0y*m4k{M`rzy(KQ+~IR_q1 zMGD(*MaPa_>$-OBQzor8vmM0`^V=16b{7u2x}25R%#HPNv@z|epH{=aGg z2B&&pkHP*QoN9s>|K9$EQ)f^A)g`WEg@wcle4{?tEd3pn`imBX2 zIfw%lA%=D#@NF6N`^XReZoqu&S`pt{(oIZEr>kZwg;t*i?mIvMz||>@ z{gi|_Rt5`-vwKKg-Dbe23dDwn&aX#2>ZiaO<-oaJ2CNrZ*@1g+r*Opb#sGt50tYh~ zc#du(;*KAachMoL*ml$qhZ+mKAzpx(+`R1utS>{%t0=9En3&oHz=sU}4q3R3f)*d6 zu-Cq%kXLV0#HGK{yfu1KmLVQAdjqidS}Fua6=t*qM?R$l z;I~xtci3BZ$t5h;fDhB^dkrzV_QFWSgSG;fuBR--rKY#(fx&=*fT@`nQU?DeAg+_a zhk?LE5r}zaxQsc)t0^#V0|g*fIT$!BsiBv&?E|C+7SkbSwivj30pd%25ignp9L3;b zpSisxE!a$nz*r%b$AMY<&~GI$Z_yF%R4C?STq%UN@pk)Mq?On#y8IdnJQdezk{WBM)FWJ%IAuCVzK>S z{xbgN%l@ICo~?AzZFjL3^LXMH!vyxpMzwd>W_;DY{dI?fq6^Cxe$k$^ z!|w>)z1xzqUf#aOD^5!pYlXYlhb1_a1V%fnPy70R*uCDpm5c&v_oZYVi=!5!(o+8q z72I7VA}eQg^OFyL4Bg$HW^`-ut8TOMLX9$>zT#hft~zhVh@Hs1?pKR*=L<|(Z_3yH zJ{O4=JwNsSc}KUgAadJVrppiX1=cOFm~9fd?=zF#PTBwHk1@)g-S4-fd)u~^SOss; zIw$b(0*fS)^?YlKR0I8dfs}(a+j{l%kOrYKbCw@ zWd7wsEI%qR4f9KDF*5QNmB)B`zcC0G9z;d#>dbN506y{CSMiui7`^7nZ7ZHiTIx5!9Bz^ z8woU*R1KAs92|BSkPI)sa|cY4#9FfJhja&rOv%BSi$v_roDu5-2fl%qi1kRxh(l&_ z=4}q=p!G(M#KB?X_v}t~&he9QA8W(T97H*6c1~LxR#!b97l-sq9f{Qj2=j#_V)6>tuS%*M& zNayb&|LhLPoHp{y=?7PuL;jl8IQM08x&OkzeN$Kt_}Nwp1kX;2d;`bL$Z5-n6v(12 zI!28Ms=JW-a;6T?6iaH5prRAXBpqGS@jU0$lSTcv?02 zgNv0iGCsH8z}q?oWf8gfLMNC@-0US({P!0IPIvyJ7Y3QX07vEDUXX)dlEJpY@YgBR zFDR>NgF*iA@cmNA!vM&wBAm;}IEL#N#8-gl-bzVbI}Pie*rOdBai9M4pdaL-{qi@H zPi8x0e<$jOd+FT;9daFXK+Mmog}C-1e71(9EBg()f(*KatYinxauJXkx?$3)jpQba zGH~yVp2O%6A>X_p4fGOrd=AD-Z=ezKqDgYzzdeMFqOlqhKt`J+yzvps0u_b(`< z4DuiPlQ^}Jq}mSh#8?zRM4w}gjez>~G~@0IBF`Y`$_I(0YO)GZkxg_aIm(i;PDwLa zr7nP-U=JlgrwxQ|8V$WxgSM4nTx**9X>RjIvPqdwjzMV@kG5w+p9!fxMHF2Oow$Xx zeS;K*wLlyLQpkMjg~4Xy58XxE`V!fTVzCBC9oFL5N1B#?gH9Gy@RC6nWb}E7c7ws* zleQc>YgQ)}pzleZNipBzsK_zcx&r6*U_4<=W#Aq)=#Qdp6p&eDuy0x9Ehn3W&19o% zCA+fKl;6FboT1|{#25|E>of4@lB{lGbb7{ilnwpPOI1T2o(m;8OPBgBob+6ruOfg>;Qqd>?EMwr&a&n%TkcVLGG=z*t!2j6v!dc2 z_5b4PU6uCR)^+PHJWvNJ7duy2|E$PdWtFf%R4P3DMsr`q(Ri2f#s2q-^34agM<&ab zrhZqxq|)to=c4@b$`Jp)cgxF{xCQU8UuyMz*QFJ+}F$SCzZnjoLhoye(e|Jk;l0@%T-zn_t&CH>;yJxSIsXQZsz2 zx{uY>4a_v(;dP~=jxMM9MDhyS8dYiC$D9k7&n#zZ_;E#&@rkNcU7TMUSNv>kTyslq zUe0oK+}7f2Tw^VWGYRmVf56(<*jHQ?Uk(zd_q{A%md9%IzH; z%{KXnTaAW{sarydikI4%}8#OM0lIpv28EfI^?n0d-vLo zMULg>I`I6;KA3OP)YNq+_WjtqcOy(eeC3)E5Z2#cFh?q#GlxG%S~iEzk#abT z+GPD<|3jkuANiM&V>Z}5u>V_*#r#Wl;jRDJg;T$KK`EF6lCewi%)2T}h%M1zPA(?9 zxQ%4yr6!(COMVYtkg125Of0O)DZGeG9K&gbr46~J_7E?1E6w&xB~zbFa!K8cxj2?w zB1*{0JAr1p#}bKP*NfKRvrWWOfX)#wAQxpZ@v|$*+J7F7)nwxxKw%YK6j8IDB9``& znIoUPw0hzMWRsUFVXim&zbZcycwFh1QZ|S}8frt08V&4s7CTvJ03? zcHtWGgsiahiy=9%q`6Q{35}b`EO-%F`)Y~U?!<}OKx|(*^oLfgakPR2m~&;7Yly;{ zX*RwuDqK#E(G4WXTnC$I6gefXAuB}-j@`s^jRlvniA+5uWNg7EyQoZZz`QxbS&lYb zi|eM5xL^g%Lj66nt59YW*-JAp-#gJPz6$S0la;GCImI`VE81}uKLPz+O8mTo69-Xj9KMJQyFX#NV~2BecCD= zW(ZQq8U5*^C??m$g=8O?g<}bsa-At`Nhetd0wA;6(3e`+Z(kxCymko5Bcsq3l9#U` zHb0VhzAqyEU$Qshh~(WPPWlKWQVc+|LZn5?vU2HCg0T5 z_oK$d)#5Sf!6h?a*14RS=^DGrv9n&bLd~L){_{lHSu{cO4_#bfR7(S_<#SnAjg}GD z@4|I+viQX4xTjv|WVCa?-G*6pIV69{@`zDN&lXxLv5lL@QVK$hS*0t}cT?ev$hBwR zUzgV#UJ|q2yX-{frVl>6w&V3ZyZZPF|HTRi4+{Lay{h8mYr&Vc*_)WW(&cvefR)*+mH)f__P+p#8JB?o From 293fc7679fae27d2e528224058062c20092f2b02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 10 Jan 2007 21:41:00 +0000 Subject: [PATCH 2664/4131] keep OSX gcc happy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2749 --- src/cpu/core_dyn_x86.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 659ca600..7e50cfb3 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -242,7 +242,7 @@ static void dyn_restoreregister(DynReg * src_reg, DynReg * dst_reg) { #define DH_FPU_SAVE_REINIT \ { \ __asm__ volatile ( \ - "fnsave (%0) \n" \ + "fnsave %0 \n" \ : \ : "m" (dyn_dh_fpu.state[0]) \ : "memory" \ @@ -430,8 +430,8 @@ void CPU_Core_Dyn_X86_Init(void) { #else __asm__ volatile ( "finit \n" - "fsave (%0) \n" - "fstcw (%1) \n" + "fsave %0 \n" + "fstcw %1 \n" : : "m" (dyn_dh_fpu.state[0]), "m" (dyn_dh_fpu.host_cw) : "memory" From 91eb2fa61262628ea3c2efec90a1925c20a10707 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 11 Jan 2007 09:51:37 +0000 Subject: [PATCH 2665/4131] Add timed joystick support (Justice and others) and silence a few warnings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2750 --- src/dosbox.cpp | 12 ++++-- src/gui/sdl_mapper.cpp | 19 ++++---- src/hardware/joystick.cpp | 91 ++++++++++++++++++++++++++++++++------- 3 files changed, 95 insertions(+), 27 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 9c4b2f9f..0d6860fd 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.107 2007-01-10 15:00:38 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.108 2007-01-11 09:51:37 qbix79 Exp $ */ #include #include @@ -402,17 +402,23 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("joystick",&BIOS_Init,false);//done MSG_Add("JOYSTICK_CONFIGFILE_HELP", - "joysticktype -- Type of joystick to emulate: auto (default), none,\n" - " 2axis (supports two joysticks), 4axis,\n" + "joysticktype -- Type of joystick to emulate: auto (default), none,\n" + " 2axis (supports two joysticks), 4axis,\n" " fcs (Thrustmaster), ch (CH Flightstick).\n" " none disables joystick emulation.\n" " auto chooses emulation depending on real joystick(s).\n" + "timed -- enable timed intervals for axis. (false is old style behaviour).\n" + "autofire -- continuously fires as long as you keep the button pressed.\n" + "swap34 -- swap the 3rd and the 4th axis. can be useful for certain joysticks.\n" ); secprop->AddInitFunction(&INT10_Init); secprop->AddInitFunction(&MOUSE_Init); //Must be after int10 as it uses CurMode secprop->AddInitFunction(&JOYSTICK_Init); secprop->Add_string("joysticktype","auto"); + secprop->Add_bool("timed","true"); + secprop->Add_bool("autofire","false"); + secprop->Add_bool("swap34","false"); // had to rename these to serial due to conflicts in config secprop=control->AddSection_prop("serial",&SERIAL_Init,true); diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 6118b0d9..f915de2c 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.30 2007-01-10 15:01:15 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.31 2007-01-11 09:51:37 qbix79 Exp $ */ #include #include @@ -102,8 +102,8 @@ public: void AddBind(CBind * bind); virtual ~CEvent() {} virtual void Active(bool yesno)=0; - virtual INLINE void Activate(bool ev_trigger)=0; - virtual INLINE void DeActivate(bool ev_trigger)=0; + virtual void Activate(bool ev_trigger)=0; + virtual void DeActivate(bool ev_trigger)=0; void DeActivateAll(void); void SetValue(Bits value){ current_value=value; @@ -127,7 +127,7 @@ public: virtual bool IsTrigger(void) { return true; } - INLINE void Activate(bool ev_trigger) { + void Activate(bool ev_trigger) { if (current_value>25000) { /* value exceeds boundary, trigger event if not active */ if (!activity) Active(true); @@ -140,7 +140,7 @@ public: } } } - INLINE void DeActivate(bool /*ev_trigger*/) { + void DeActivate(bool /*ev_trigger*/) { activity--; if (!activity) Active(false); } @@ -153,7 +153,7 @@ public: virtual bool IsTrigger(void) { return false; } - INLINE void Activate(bool ev_trigger) { + void Activate(bool ev_trigger) { if (ev_trigger) { activity++; Active(true); @@ -163,7 +163,7 @@ public: if (!GetActivityCount()) Active(true); } } - INLINE void DeActivate(bool ev_trigger) { + void DeActivate(bool ev_trigger) { if (ev_trigger) { if (activity>0) activity--; if (activity==0) { @@ -515,12 +515,13 @@ protected: #define MAX_VJOY_BUTTONS 8 -struct { +static struct { bool button_pressed[MAX_VJOY_BUTTONS]; Bit16s axis_pos[8]; bool hat_pressed[16]; } virtual_joysticks[2]; + class CJAxisBind; class CJButtonBind; class CJHatBind; @@ -588,7 +589,7 @@ protected: Bit8u dir; }; -static bool autofire=false; +bool autofire = false; class CStickBindGroup : public CBindGroup { public: diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index ef6b8bec..76764529 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: joystick.cpp,v 1.16 2007-01-10 15:01:15 c2woody Exp $ */ +/* $Id: joystick.cpp,v 1.17 2007-01-11 09:51:37 qbix79 Exp $ */ #include #include "dosbox.h" @@ -29,9 +29,14 @@ #define RANGE 64 #define TIMEOUT 10 +#define OHMS 120000/2 +#define JOY_S_CONSTANT 0.0000242 +#define S_PER_OHM 0.000000011 + struct JoyStick { bool enabled; float xpos,ypos; + double xtick,ytick; Bitu xcount,ycount; bool button[2]; }; @@ -41,6 +46,9 @@ static JoyStick stick[2]; static Bit32u last_write = 0; static bool write_active = false; +static bool swap34 = false; + +extern bool autofire; //sdl_mapper.cpp static Bitu read_p201(Bitu port,Bitu iolen) { /* Reset Joystick to 0 after TIMEOUT ms */ @@ -78,6 +86,29 @@ static Bitu read_p201(Bitu port,Bitu iolen) { return ret; } +static Bitu read_p201_timed(Bitu port,Bitu iolen) { + Bit8u ret=0xff; + double currentTick = PIC_FullIndex(); + if( stick[0].enabled ){ + if( stick[0].xtick < currentTick ) ret &=~1; + if( stick[0].ytick < currentTick ) ret &=~2; + } + if( stick[1].enabled ){ + if( stick[1].xtick < currentTick ) ret &=~4; + if( stick[1].ytick < currentTick ) ret &=~8; + } + + if (stick[0].enabled) { + if (stick[0].button[0]) ret&=~16; + if (stick[0].button[1]) ret&=~32; + } + if (stick[1].enabled) { + if (stick[1].button[0]) ret&=~64; + if (stick[1].button[1]) ret&=~128; + } + return ret; +} + static void write_p201(Bitu port,Bitu val,Bitu iolen) { /* Store writetime index */ write_active = true; @@ -87,11 +118,30 @@ static void write_p201(Bitu port,Bitu val,Bitu iolen) { stick[0].ycount=(Bitu)((stick[0].ypos*RANGE)+RANGE); } if (stick[1].enabled) { - stick[1].xcount=(Bitu)((stick[1].xpos*RANGE)+RANGE); - stick[1].ycount=(Bitu)((stick[1].ypos*RANGE)+RANGE); + stick[1].xcount=(Bitu)(((swap34? stick[1].ypos : stick[1].xpos)*RANGE)+RANGE); + stick[1].ycount=(Bitu)(((swap34? stick[1].xpos : stick[1].ypos)*RANGE)+RANGE); } } +static void write_p201_timed(Bitu port,Bitu val,Bitu iolen) { + // Store writetime index + // Axes take time = 24.2 microseconds + ( 0.011 microsecons/ohm * resistance ) + // to reset to 0 + // Precalculate the time at which each axis hits 0 here + double currentTick = PIC_FullIndex(); + if (stick[0].enabled) { + stick[0].xtick = currentTick + 1000.0*( JOY_S_CONSTANT + S_PER_OHM * + (double)(((stick[0].xpos+1.0)* OHMS)) ); + stick[0].ytick = currentTick + 1000.0*( JOY_S_CONSTANT + S_PER_OHM * + (double)(((stick[0].ypos+1.0)* OHMS)) ); + } + if (stick[1].enabled) { + stick[1].xtick = currentTick + 1000.0*( JOY_S_CONSTANT + S_PER_OHM * + (double)((swap34? stick[1].ypos : stick[1].xpos)+1.0) * OHMS); + stick[1].ytick = currentTick + 1000.0*( JOY_S_CONSTANT + S_PER_OHM * + (double)((swap34? stick[1].xpos : stick[1].ypos)+1.0) * OHMS); + } +} void JOYSTICK_Enable(Bitu which,bool enabled) { if (which<2) stick[which].enabled=enabled; @@ -145,18 +195,29 @@ public: JOYSTICK(Section* configuration):Module_base(configuration){ Section_prop * section=static_cast(configuration); const char * type=section->Get_string("joysticktype"); - if (!strcasecmp(type,"none")) joytype=JOY_NONE; - else if (!strcasecmp(type,"false")) joytype=JOY_NONE; - else if (!strcasecmp(type,"auto")) joytype=JOY_AUTO; - else if (!strcasecmp(type,"2axis")) joytype=JOY_2AXIS; - else if (!strcasecmp(type,"4axis")) joytype=JOY_4AXIS; - else if (!strcasecmp(type,"fcs")) joytype=JOY_FCS; - else if (!strcasecmp(type,"ch")) joytype=JOY_CH; - else joytype=JOY_AUTO; - ReadHandler.Install(0x201,read_p201,IO_MB); - WriteHandler.Install(0x201,write_p201,IO_MB); - stick[0].enabled=false; - stick[1].enabled=false; + if (!strcasecmp(type,"none")) joytype = JOY_NONE; + else if (!strcasecmp(type,"false")) joytype = JOY_NONE; + else if (!strcasecmp(type,"auto")) joytype = JOY_AUTO; + else if (!strcasecmp(type,"2axis")) joytype = JOY_2AXIS; + else if (!strcasecmp(type,"4axis")) joytype = JOY_4AXIS; + else if (!strcasecmp(type,"fcs")) joytype = JOY_FCS; + else if (!strcasecmp(type,"ch")) joytype = JOY_CH; + else joytype = JOY_AUTO; + + bool timed = section->Get_bool("timed"); + if(timed) { + ReadHandler.Install(0x201,read_p201_timed,IO_MB); + WriteHandler.Install(0x201,write_p201_timed,IO_MB); + } else { + ReadHandler.Install(0x201,read_p201,IO_MB); + WriteHandler.Install(0x201,write_p201,IO_MB); + } + autofire = section->Get_bool("autofire"); + swap34 = section->Get_bool("swap34"); + stick[0].enabled = false; + stick[1].enabled = false; + stick[0].xtick = stick[0].ytick = stick[1].xtick = + stick[1].ytick = PIC_FullIndex(); } }; static JOYSTICK* test; From 267d7bfeb19839c6d4c2dfa82bac0a315e317cc5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 11 Jan 2007 16:25:21 +0000 Subject: [PATCH 2666/4131] bools aren't strings. (rcblanke) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2751 --- src/dosbox.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 0d6860fd..73ebc7a4 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.108 2007-01-11 09:51:37 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.109 2007-01-11 16:25:21 qbix79 Exp $ */ #include #include @@ -416,9 +416,9 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&MOUSE_Init); //Must be after int10 as it uses CurMode secprop->AddInitFunction(&JOYSTICK_Init); secprop->Add_string("joysticktype","auto"); - secprop->Add_bool("timed","true"); - secprop->Add_bool("autofire","false"); - secprop->Add_bool("swap34","false"); + secprop->Add_bool("timed",true); + secprop->Add_bool("autofire",false); + secprop->Add_bool("swap34",false); // had to rename these to serial due to conflicts in config secprop=control->AddSection_prop("serial",&SERIAL_Init,true); From 872b63bb49ec6636e653b6555362494fa01df8cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 11 Jan 2007 16:31:10 +0000 Subject: [PATCH 2667/4131] swap simple/normal core again; have some stack exception executed instead of exiting dosbox Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2752 --- src/cpu/cpu.cpp | 14 +++++++------- src/dos/dos_execute.cpp | 6 ++---- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 747ca345..942fabe4 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.92 2007-01-09 17:18:52 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.93 2007-01-11 16:31:10 c2woody Exp $ */ #include #include "dosbox.h" @@ -1813,8 +1813,8 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) { } if (!desc.saved.seg.p) { - E_Exit("CPU_SetSegGeneral: Stack segment not present"); // or #SS(sel) -// return CPU_PrepareException(EXCEPTION_SS,value & 0xfffc); +// E_Exit("CPU_SetSegGeneral: Stack segment not present"); // or #SS(sel) + return CPU_PrepareException(EXCEPTION_SS,value & 0xfffc); } Segs.val[seg]=value; @@ -2072,11 +2072,11 @@ public: CPU_CycleUp=section->Get_int("cycleup"); CPU_CycleDown=section->Get_int("cycledown"); const char * core=section->Get_string("core"); - cpudecoder=&CPU_Core_Simple_Run; + cpudecoder=&CPU_Core_Normal_Run; if (!strcasecmp(core,"normal")) { - cpudecoder=&CPU_Core_Simple_Run; - } else if (!strcasecmp(core,"force_normal")) { cpudecoder=&CPU_Core_Normal_Run; + } else if (!strcasecmp(core,"simple")) { + cpudecoder=&CPU_Core_Simple_Run; } else if (!strcasecmp(core,"full")) { cpudecoder=&CPU_Core_Full_Run; } @@ -2088,7 +2088,7 @@ public: cpudecoder=&CPU_Core_Dyn_X86_Run; CPU_Core_Dyn_X86_SetFPUMode(false); } else if (!strcasecmp(core,"auto")) { - cpudecoder=&CPU_Core_Simple_Run; + cpudecoder=&CPU_Core_Normal_Run; CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CORE; } #endif diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index ae43c9ea..6d3ea569 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.59 2007-01-10 12:04:35 qbix79 Exp $ */ +/* $Id: dos_execute.cpp,v 1.60 2007-01-11 16:31:10 c2woody Exp $ */ #include #include @@ -27,7 +27,6 @@ #include "callback.h" #include "debug.h" #include "cpu.h" -#include "paging.h" const char * RunningProgram="DOSBOX"; @@ -154,8 +153,7 @@ bool DOS_Terminate(bool tsr) { } #if (C_DYNAMIC_X86) if (CPU_AutoDetermineMode&CPU_AUTODETERMINE_CORE) { - if (PAGING_Enabled()) cpudecoder=&CPU_Core_Normal_Run; - else cpudecoder=&CPU_Core_Simple_Run; + cpudecoder=&CPU_Core_Normal_Run; CPU_CycleLeft=0; CPU_Cycles=0; } From c9ba894dc909e162b91954b5973fa4378535f2d0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 11 Jan 2007 16:47:10 +0000 Subject: [PATCH 2668/4131] That includes the umb section as well Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2753 --- src/dosbox.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 73ebc7a4..8ed5e690 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.109 2007-01-11 16:25:21 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.110 2007-01-11 16:47:10 qbix79 Exp $ */ #include #include @@ -444,7 +444,7 @@ void DOSBOX_Init(void) { secprop->Add_bool("xms",true); secprop->AddInitFunction(&EMS_Init,true);//done secprop->Add_bool("ems",true); - secprop->Add_bool("umb","true"); + secprop->Add_bool("umb",true); secprop->AddInitFunction(&DOS_KeyboardLayout_Init,true); secprop->Add_string("keyboardlayout", "none"); MSG_Add("DOS_CONFIGFILE_HELP", From a02b03cd47ed8c45b0ba027ce5e0ab440050f060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 11 Jan 2007 18:08:54 +0000 Subject: [PATCH 2669/4131] Add beta2 patch: remove zero-entries when scanning for available keys in CON Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2754 --- src/dos/dev_con.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 040a054d..5ce1bdc6 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.27 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: dev_con.h,v 1.28 2007-01-11 18:08:54 c2woody Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" @@ -369,8 +369,16 @@ Bit16u device_CON::GetInformation(void) { Bit16u head=mem_readw(BIOS_KEYBOARD_BUFFER_HEAD); Bit16u tail=mem_readw(BIOS_KEYBOARD_BUFFER_TAIL); - if ((head==tail) && !readcache) return 0x80D3; /* No Key Available */ - return 0x8093; /* Key Available */ + if ((head==tail) && !readcache) return 0x80D3; /* No Key Available */ + if (real_readw(0x40,head)) return 0x8093; /* Key Available */ + + /* remove the zero from keyboard buffer */ + Bit16u start=mem_readw(BIOS_KEYBOARD_BUFFER_START); + Bit16u end =mem_readw(BIOS_KEYBOARD_BUFFER_END); + head+=2; + if (head>=end) head=start; + mem_writew(BIOS_KEYBOARD_BUFFER_HEAD,head); + return 0x80D3; /* No Key Available */ }; device_CON::device_CON() { From f7f853ddf7ead50be0c44abf45669a0f08d2911b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 12 Jan 2007 17:33:43 +0000 Subject: [PATCH 2670/4131] add 0x6a vesa mode (dupe of 0x102) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2755 --- src/ints/int10_modes.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 24066be4..cc877cc3 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -55,6 +55,8 @@ VideoModeBlock ModeList_VGA[]={ { 0x054 ,M_TEXT ,1056,688, 132,43, 8, 8, 1 ,0xB8000 ,0x4000, 192, 800, 132,688, 0 }, { 0x055 ,M_TEXT ,1056,400, 132,25, 8, 16, 1 ,0xB8000 ,0x2000, 192, 449, 132,400, 0 }, +{ 0x06A ,M_LIN4 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, + /* Follow vesa 1.2 for first 0x20 */ { 0x100 ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, { 0x101 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, From 89d0cd57780324cb1f16015f1a3d02cd139ba54b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 12 Jan 2007 18:31:11 +0000 Subject: [PATCH 2671/4131] adjust cga machine htotal/vtotal (thanks to MobyGamer and reenigne!) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2756 --- src/hardware/vga_draw.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index b699f2bf..a67432f1 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -609,10 +609,10 @@ void VGA_SetupDrawing(Bitu val) { vga.draw.double_scan=(vga.crtc.maximum_scan_line&0x80)>0; } else { vga.draw.address_line_total=vga.other.max_scanline+1; - htotal=vga.other.htotal; + htotal=vga.other.htotal+1; hdispend=vga.other.hdend; hrstart=vga.other.hsyncp; - vtotal=vga.draw.address_line_total*vga.other.vtotal+vga.other.vadjust; + vtotal=vga.draw.address_line_total*(vga.other.vtotal+1)+vga.other.vadjust; vdispend=vga.draw.address_line_total*vga.other.vdend; vrstart=vga.draw.address_line_total*vga.other.vsyncp; vga.draw.double_scan=false; From 46d89dc3b3edb6a62fb74d4774726eb7f151a048 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 12 Jan 2007 20:59:04 +0000 Subject: [PATCH 2672/4131] Add beta 2 patch: Fix inherit the earth harddisk size detection. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2757 --- src/ints/bios_disk.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index c5aa2fbf..ae2973f4 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.30 2007-01-08 19:45:41 qbix79 Exp $ */ +/* $Id: bios_disk.cpp,v 1.31 2007-01-12 20:59:04 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" @@ -253,7 +253,7 @@ Bit32u imageDisk::getSectSize(void) { static Bitu GetDosDriveNumber(Bitu biosNum) { switch(biosNum) { - case 0x0: + case 0x0: return 0x0; case 0x1: return 0x1; @@ -300,15 +300,16 @@ static Bitu INT13_DiskHandler(void) { int i,t; last_drive = reg_dl; drivenum = GetDosDriveNumber(reg_dl); + bool any_images = false; + for(Bitu i = 0;i < MAX_DISK_IMAGES;i++) { + if(imageDiskList[i]) any_images=true; + } + //drivenum = 0; //LOG_MSG("INT13: Function %x called on drive %x (dos drive %d)", reg_ah, reg_dl, drivenum); switch(reg_ah) { case 0x0: /* Reset disk */ { - bool any_images = false; - for(Bitu i = 0;i < MAX_DISK_IMAGES;i++) { - if(imageDiskList[i]) any_images=true; - } /* if there aren't any diskimages (so only localdrives and virtual drives) * always succeed on reset disk. If there are diskimages then and only then * do real checks @@ -344,6 +345,11 @@ static Bitu INT13_DiskHandler(void) { CALLBACK_SCF(true); return CBRET_NONE; } + if(!any_images && (reg_dh == 0)) { // Inherit the Earth cdrom (uses it as disk test) + reg_ah = 0; + CALLBACK_SCF(false); + return CBRET_NONE; + } if(driveInactive(drivenum)) { reg_ah = 0xff; CALLBACK_SCF(true); @@ -367,7 +373,7 @@ static Bitu INT13_DiskHandler(void) { } } reg_ah = 0x00; - CALLBACK_SCF(false); + CALLBACK_SCF(false); break; case 0x3: /* Write sectors */ From 85af8429ac48e155b151e1790d485c12e26f90a7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 13 Jan 2007 08:35:49 +0000 Subject: [PATCH 2673/4131] Add beta2 patch: nullmodem and serial update. Add some more configure tests for OS/2 and Mac OS X Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2758 --- configure.in | 58 +- include/bios.h | 2 + include/ipx.h | 6 +- include/serialport.h | 233 ++- src/cpu/cpu.cpp | 6 +- src/dos/dos.cpp | 23 +- src/dos/dos_devices.cpp | 6 +- src/dosbox.cpp | 11 +- src/hardware/serialport/Makefile.am | 6 +- .../serialport/directserial_posix.cpp | 361 ++++ src/hardware/serialport/directserial_posix.h | 69 + .../serialport/directserial_win32.cpp | 409 +++-- src/hardware/serialport/directserial_win32.h | 50 +- src/hardware/serialport/misc_util.cpp | 318 ++++ src/hardware/serialport/misc_util.h | 79 + src/hardware/serialport/nullmodem.cpp | 496 ++++++ src/hardware/serialport/nullmodem.h | 105 ++ src/hardware/serialport/serialdummy.cpp | 84 +- src/hardware/serialport/serialdummy.h | 39 +- src/hardware/serialport/serialport.cpp | 1580 +++++++++-------- src/hardware/serialport/softmodem.cpp | 513 +++--- src/hardware/serialport/softmodem.h | 52 +- src/ints/bios.cpp | 193 +- visualc_net/dosbox.vcproj | 32 +- 24 files changed, 3195 insertions(+), 1536 deletions(-) create mode 100644 src/hardware/serialport/directserial_posix.cpp create mode 100644 src/hardware/serialport/directserial_posix.h create mode 100644 src/hardware/serialport/misc_util.cpp create mode 100644 src/hardware/serialport/misc_util.h create mode 100644 src/hardware/serialport/nullmodem.cpp create mode 100644 src/hardware/serialport/nullmodem.h diff --git a/configure.in b/configure.in index 5591b7ac..7028e908 100644 --- a/configure.in +++ b/configure.in @@ -60,7 +60,18 @@ 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)) +dnl Check for powf +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 ]],[[ + 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. @@ -230,7 +241,7 @@ 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" + LIBS="$LIBS -lSDL_net" AC_DEFINE(C_MODEM,1) AC_DEFINE(C_IPX,1) else @@ -239,20 +250,31 @@ fi AH_TEMPLATE(C_OPENGL,[Define to 1 to use opengl display output support]) AC_ARG_ENABLE(opengl,AC_HELP_STRING([--disable-opengl],[Disable opengl support]),,enable_opengl=yes) -AC_CHECK_LIB(GL, main, have_gl_lib=yes, have_gl_lib=no , ) -AC_CHECK_LIB(opengl32, main, have_opengl32_lib=yes,have_opengl32_lib=no , ) -AC_CHECK_HEADER(GL/gl.h, have_gl_h=yes , have_gl_h=no , ) AC_MSG_CHECKING(whether opengl display output will be enabled) -if test x$enable_opengl = xyes -a x$have_gl_h = xyes -a x$have_gl_lib = xyes ; then - AC_MSG_RESULT(yes) - LIBS="$LIBS -lGL" - AC_DEFINE(C_OPENGL,1) -elif test x$enable_opengl = xyes -a x$have_gl_h = xyes -a x$have_opengl32_lib = xyes ; then - AC_MSG_RESULT(yes) - LIBS="$LIBS -lopengl32" - AC_DEFINE(C_OPENGL,1) -else - AC_MSG_RESULT(no) +if test x$enable_opengl = xyes; then +case "$target" in + *-*-darwin*) + AC_MSG_RESULT(yes) + LIBS="$LIBS -framework OpenGL" + AC_DEFINE(C_OPENGL,1) + ;; + *) + 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 , ) + 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]) @@ -292,7 +314,10 @@ 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 and OS/2 only).]) + 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 MacOS X and Darwin report @@ -304,10 +329,11 @@ case "$target" in ;; *-*-linux-gnu*) 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).]) ;; *-*-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 and OS/2 only).]) + AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).]) ;; esac diff --git a/include/bios.h b/include/bios.h index 0184fc8f..39b06531 100644 --- a/include/bios.h +++ b/include/bios.h @@ -177,4 +177,6 @@ bool BIOS_AddKeyToBuffer(Bit16u code); void INT10_ReloadRomFonts(); +void BIOS_SetComPorts (Bit16u baseaddr[]); + #endif diff --git a/include/ipx.h b/include/ipx.h index 962a751a..884b4946 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.h,v 1.11 2007-01-08 19:45:37 qbix79 Exp $ */ +/* $Id: ipx.h,v 1.12 2007-01-13 08:35:49 qbix79 Exp $ */ #ifndef DOSBOX_IPX_H #define DOSBOX_IPX_H @@ -27,8 +27,12 @@ #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" diff --git a/include/serialport.h b/include/serialport.h index 53142c64..bc55b0cd 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -16,13 +16,15 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.h,v 1.13 2007-01-08 19:45:37 qbix79 Exp $ */ +/* $Id: serialport.h,v 1.14 2007-01-13 08:35:49 qbix79 Exp $ */ #ifndef DOSBOX_SERIALPORT_H #define DOSBOX_SERIALPORT_H +#define SERIAL_DEBUG 0 + // Uncomment this for a lot of debug messages: -// #define SERIALPORT_DEBUGMSG +//#define LOG_UART #ifndef DOSBOX_DOSBOX_H #include "dosbox.h" @@ -34,31 +36,70 @@ #include "timer.h" #endif +#include "dos_inc.h" +#include "setup.h" -// Serial port interface // +#if SERIAL_DEBUG +#include "hardware.h" +#endif + +// Serial port interface class CSerial { public: - // Constructor takes base port (0x3f8, 0x2f8, 0x2e8, etc.), IRQ, and initial bps // - CSerial(IO_ReadHandler* rh, IO_WriteHandler* wh, - TIMER_TickHandler TimerHandler, - Bit16u initbase, Bit8u initirq, Bit32u initbps, - Bit8u bytesize, const char* parity, Bit8u stopbits); +#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); - TIMER_TickHandler TimerHnd; virtual ~CSerial(); - void InstallTimerHandler(TIMER_TickHandler); - + IO_ReadHandleObject ReadHandler[8]; IO_WriteHandleObject WriteHandler[8]; - void Timer(void); - virtual void Timer2(void)=0; + 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; - Bitu base; + // 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(); @@ -72,75 +113,75 @@ public: 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); - Bitu Read_RHR(); - Bitu Read_IER(); void Write_IER(Bit8u data); - Bitu Read_ISR(); - Bitu Read_LCR(); + void Write_FCR(Bit8u data); void Write_LCR(Bit8u data); - Bitu Read_MCR(); void Write_MCR(Bit8u data); - Bitu Read_LSR(); - // Really old hardware seems to have the delta part of this register writable void Write_MSR(Bit8u data); - - Bitu Read_MSR(); - Bitu Read_SPR(); 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 wherever(loopback or real port or maybe - // that softmodem thingy), put it in here. + // 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(); - // Virtual app has read the received data - virtual void RXBufferEmpty()=0; - - // real transmit - virtual void transmitByte(Bit8u val)=0; + // 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; - // set output lines - virtual void updateModemControlLines(/*Bit8u mcr*/)=0; - // change baudrate, number of bits, parity, word length al at once - virtual void updatePortConfig(Bit8u dll, Bit8u dlm, Bit8u lcr)=0; + virtual void updatePortConfig(Bit16u divider, Bit8u lcr)=0; - // CSerial requests an update of the input lines - virtual void updateMSR()=0; + void Init_Registers(); + + bool Putchar(Bit8u data, bool wait_dtr, bool wait_rts, Bitu timeout); + bool Getchar(Bit8u* data, bool wait_dsr, Bitu timeout); - // after update request, or some "real" changes, - // modify MSR here - void changeMSR(Bit8u data); // make public - - void Init_Registers(Bit32u initbps, - Bit8u bytesize, const char* parity, Bit8u stopbits); private: + DOS_Device* mydosdevice; + // I used this spec: http://www.exar.com/products/st16c450v420.pdf - void changeMSR_Loopback(Bit8u data); + void ComputeInterrupts(); - void WriteRealIER(Bit8u data); - // reason for an interrupt has occured - functions triggers interrupt - // if it is enabled and no higher-priority irq pending + // a sub-interrupt is triggered void rise(Bit8u priority); - // clears the pending interrupt + // clears the pending sub-interrupt void clear(Bit8u priority); #define ERROR_PRIORITY 4 // overrun, parity error, frame error, break @@ -149,18 +190,12 @@ private: #define MSR_PRIORITY 8 // CRS, DSR, RI, DCD change #define NONE_PRIORITY 0 - - Bit8u pending_interrupts; // stores triggered interupts - Bit8u current_priority; Bit8u waiting_interrupts; // these are on, but maybe not enabled // 16C450 (no FIFO) // read/write name - - Bit8u DLL; // r Baudrate divider low byte - Bit8u DLM; // r "" high byte - + Bit16u baud_divider; Bit8u RHR; // r Receive Holding Register, also LSB of Divisor Latch (r/w) #define RHR_OFFSET 0 // Data: whole byte @@ -169,13 +204,10 @@ private: #define THR_OFFSET 0 // Data: whole byte - Bit8u IER; // r/w Interrupt Enable Register, also MSB of Divisor Latch (r/w) + Bit8u IER; // r/w Interrupt Enable Register, also MSB of Divisor Latch #define IER_OFFSET 1 - // Data: - // bit0 receive holding register - // bit1 transmit holding register - // bit2 receive line status interrupt - // bit3 modem status interrupt + + bool irq_active; #define RHR_INT_Enable_MASK 0x1 #define THR_INT_Enable_MASK 0x2 @@ -222,23 +254,24 @@ private: #define LCR_STOPBITS_1 0x0 #define LCR_STOPBITS_MORE_THAN_1 0x4 - Bit8u MCR; // r/w Modem Control Register + // Modem Control Register + // r/w #define MCR_OFFSET 4 - // bit0: DTR - // bit1: RTS - // bit2: OP1 - // bit3: OP2 - // bit4: loop back enable + bool dtr; // bit0: DTR + bool rts; // bit1: RTS + bool op1; // bit2: OP1 + bool op2; // bit3: OP2 + bool loopback; // bit4: loop back enable - #define MCR_LOOPBACK_Enable_MASK 0x10 - #define MCR_LEVELS_MASK 0xf - #define MCR_DTR_MASK 0x1 #define MCR_RTS_MASK 0x2 #define MCR_OP1_MASK 0x4 - #define MCR_OP2_MASK 0x8 - + #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 @@ -251,17 +284,26 @@ private: #define LSR_ERROR_MASK 0x1e + // error printing + bool errormsg_pending; + Bitu framingErrors; + Bitu parityErrors; + Bitu overrunErrors; + Bitu overrunIF0; + Bitu breakErrors; - Bit8u MSR; // r Modem Status Register + + // Modem Status Register + // r #define MSR_OFFSET 6 - // bit0: deltaCTS - // bit1: deltaDSR - // bit2: deltaRI - // bit3: deltaCD - // bit4: CTS - // bit5: DSR - // bit6: RI - // bit7: CD + 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 @@ -280,20 +322,37 @@ private: // For loopback purposes... - bool loopback_pending; Bit8u loopback_data; - void transmitLoopbackByte(Bit8u val); + void transmitLoopbackByte(Bit8u val, bool value); // 16C550 (FIFO) // TODO + #define FCR_OFFSET 2 + bool fifo_warn; //Bit8u FCR; // FIFO Control Register }; -#define COM1_BASE 0x3f8 -#define COM2_BASE 0x2f8 -#define COM3_BASE 0x3e8 -#define COM4_BASE 0x2e8 +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 diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 942fabe4..53b01ec9 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.93 2007-01-11 16:31:10 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.94 2007-01-13 08:35:49 qbix79 Exp $ */ #include #include "dosbox.h" @@ -33,9 +33,13 @@ extern void GFX_SetTitle(Bit32s cycles ,Bits frameskip,bool paused); #if 1 #undef LOG +#if defined (_MSC_VER) +#define LOG(X,Y) +#else #define LOG(X,Y) CPU_LOG #define CPU_LOG(...) #endif +#endif CPU_Regs cpu_regs; CPUBlock cpu; diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 46fdb74d..98237bec 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.98 2007-01-08 20:36:53 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.99 2007-01-13 08:35:49 qbix79 Exp $ */ #include #include @@ -30,6 +30,7 @@ #include "dos_inc.h" #include "setup.h" #include "support.h" +#include "serialport.h" DOS_Block dos; DOS_InfoBlock dos_infoblock; @@ -79,7 +80,27 @@ static Bitu DOS_21Handler(void) { } break; case 0x03: /* Read character from STDAUX */ + { + Bit16u port = real_readw(0x40,0); + if(port!=0 && serialports[0]) { + // RTS/DTR on + IO_WriteB(port+4,0x3); + serialports[0]->Getchar(®_al,true, 0xFFFFFFFF); + } + } + break; case 0x04: /* Write Character to STDAUX */ + { + Bit16u port = real_readw(0x40,0); + if(port!=0 && serialports[0]) { + // RTS/DTR on + IO_WriteB(port+4,0x3); + serialports[0]->Putchar(reg_dl,true,true, 0xFFFFFFFF); + // RTS off + IO_WriteB(port+4,0x1); + } + } + break; case 0x05: /* Write Character to PRINTER */ E_Exit("DOS:Unhandled call %02X",reg_ah); break; diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 933f0cb1..d20ce408 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_devices.cpp,v 1.15 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: dos_devices.cpp,v 1.16 2007-01-13 08:35:49 qbix79 Exp $ */ #include #include "dosbox.h" @@ -126,6 +126,10 @@ DOS_File & DOS_File::operator= (const DOS_File & orig) { Bit8u DOS_FindDevice(char * name) { /* should only check for the names before the dot and spacepadded */ + // STDAUX is alias for COM1 + // A bit of a hack, but no application will probably use stdaux to determine wether a directory exists + if (strcasecmp(name, "STDAUX") == 0) name = "COM1"; + char temp[CROSS_LEN];//TODO if(!name || !(*name)) return DOS_DEVICES; strcpy(temp,name); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 8ed5e690..23433d71 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.110 2007-01-11 16:47:10 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.111 2007-01-13 08:35:49 qbix79 Exp $ */ #include #include @@ -428,12 +428,13 @@ void DOSBOX_Init(void) { secprop->Add_string("serial4","disabled"); MSG_Add("SERIAL_CONFIGFILE_HELP", "serial1-4 -- set type of device connected to com port.\n" - " Can be disabled, dummy, modem, directserial.\n" + " Can be disabled, dummy, modem, nullmodem, directserial.\n" " Additional parameters must be in the same line in the form of\n" - " parameter:value. Parameters for all types are irq, startbps, bytesize,\n" - " stopbits, parity (all optional).\n" - " for directserial: realport (required).\n" + " parameter:value. Parameter for all types is irq.\n" + " for directserial: realport (required), rxdelay (optional).\n" " for modem: listenport (optional).\n" + " for nullmodem: server, rxdelay, txdelay, telnet, usedtr,\n" + " transparent, port, inhsocket (all optional).\n" " Example: serial1=modem listenport:5000\n" ); diff --git a/src/hardware/serialport/Makefile.am b/src/hardware/serialport/Makefile.am index 4ae53b23..af7b803c 100644 --- a/src/hardware/serialport/Makefile.am +++ b/src/hardware/serialport/Makefile.am @@ -4,5 +4,7 @@ noinst_LIBRARIES = libserial.a libserial_a_SOURCES = directserial_win32.cpp directserial_win32.h \ serialdummy.cpp serialdummy.h serialport.cpp \ - softmodem.cpp softmodem.h \ - directserial_os2.h directserial_os2.cpp + softmodem.cpp softmodem.h misc_util.cpp misc_util.h \ + directserial_os2.h directserial_os2.cpp \ + directserial_posix.h directserial_posix.cpp \ + nullmodem.cpp nullmodem.h diff --git a/src/hardware/serialport/directserial_posix.cpp b/src/hardware/serialport/directserial_posix.cpp new file mode 100644 index 00000000..58f2d0bc --- /dev/null +++ b/src/hardware/serialport/directserial_posix.cpp @@ -0,0 +1,361 @@ +/* + * 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: directserial_posix.cpp,v 1.1 2007-01-13 08:35:49 qbix79 Exp $ */ + +#include "dosbox.h" + +#if C_DIRECTSERIAL + +// Posix version +#if defined (LINUX) + +#include "serialport.h" +#include "directserial_posix.h" +#include "pic.h" + +#include +#include +#include + +#include +#include + +/* This is a serial passthrough class. Its amazingly simple to */ +/* write now that the serial ports themselves were abstracted out */ + +CDirectSerial::CDirectSerial (Bitu id, CommandLine* cmd) + :CSerial (id, cmd) { + InstallationSuccessful = false; + + rx_retry = 0; + rx_retry_max = 0; + + std::string prefix="/dev/"; + std::string tmpstring; + if(!cmd->FindStringBegin("realport:",tmpstring,false)) return; + +#if SERIAL_DEBUG + if(dbg_modemcontrol) + fprintf(debugfp,"%12.3f Port type directserial realport %s\r\n", + PIC_FullIndex(),tmpstring.c_str()); +#endif + + prefix.append(tmpstring); + + // rxdelay: How many milliseconds to wait before causing an + // overflow when the application is unresponsive. + if(getBituSubstring("rxdelay:", &rx_retry_max, cmd)) { + if(!(rx_retry_max<=10000)) rx_retry_max=0; + } + + const char* tmpchar=prefix.c_str(); + + LOG_MSG ("Serial%d: Opening %s", COMNUMBER, tmpchar); + + fileHandle = open (tmpchar, O_RDWR | O_NOCTTY | O_NONBLOCK); + + if (fileHandle < 0) { + LOG_MSG ("Serial%d: Serial Port \"%s\" could not be opened.", + COMNUMBER, tmpchar); + if (errno == 2) { + LOG_MSG ("The specified port does not exist."); + } else if (errno == EBUSY) { + LOG_MSG ("The specified port is already in use."); + } else { + LOG_MSG ("Errno %d occurred.", errno); + } + return; + } + + int result = tcgetattr(fileHandle, &termInfo); + + + if (result==-1) { + // Handle the error. + LOG_MSG ("tcgetattr failed with error %d.\n", errno); + return; + } + + // save it here to restore in destructor + tcgetattr(fileHandle,&backup); + + // initialize the port + termInfo.c_cflag = CS8 | CREAD | CLOCAL; // noparity, 1 stopbit + termInfo.c_iflag = PARMRK | INPCK; + termInfo.c_oflag = 0; + termInfo.c_lflag = 0; + + cfsetospeed (&termInfo, B9600); + cfsetispeed (&termInfo, B9600); + + termInfo.c_cc[VMIN] = 0; + termInfo.c_cc[VTIME] = 0; + + tcflush (fileHandle, TCIFLUSH); + tcsetattr (fileHandle, TCSANOW, &termInfo); + + //initialise base class + CSerial::Init_Registers(); + InstallationSuccessful = true; + receiveblock=false; + + setEvent(SERIAL_POLLING_EVENT, 1); // millisecond tick +} + +CDirectSerial::~CDirectSerial () { + if (fileHandle >= 0) + { + tcsetattr(fileHandle, TCSANOW, &backup); + close(fileHandle); + } + // We do not use own events so we don't have to clear them. +} + +void CDirectSerial::handleUpperEvent(Bit16u type) { + + switch(type) { + case SERIAL_POLLING_EVENT: { + setEvent(SERIAL_POLLING_EVENT, 1); + if(!receiveblock) { + if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )) + { + ReadCharacter(); + } else rx_retry++; + } + // check for errors + CheckErrors(); + // update Modem input line states + updateMSR (); + break; + } + case 40: { + // receive time is up + receiveblock=false; + // check if there is something to receive + if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )) + { + ReadCharacter(); + } else rx_retry++; + break; + } + case SERIAL_TX_EVENT: { + if(!receiveblock) { + if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )) + { + ReadCharacter(); + } else rx_retry++; + } + ByteTransmitted(); + break; + } + case SERIAL_THR_EVENT: { + ByteTransmitting(); + setEvent(SERIAL_TX_EVENT,bytetime+0.03f); + break; + } + } +} + +void CDirectSerial::ReadCharacter() +{ + Bit8u chRead = 0; + int dwRead = 0; + rx_retry=0; + + dwRead=read(fileHandle,&chRead,1); + if (dwRead==1) { + if(chRead==0xff) // error escape + { + dwRead=read(fileHandle,&chRead,1); + if(chRead==0x00) // an error + { + dwRead=read(fileHandle,&chRead,1); + if(chRead==0x0)receiveError(LSR_RX_BREAK_MASK); + else receiveError(LSR_PARITY_ERROR_MASK); + } + } + receiveByte (chRead); + setEvent(40, bytetime-0.03f); // receive timing + receiveblock=true; + } +} + +void CDirectSerial::CheckErrors() { + +} + +/*****************************************************************************/ +/* updatePortConfig is called when emulated app changes the serial port **/ +/* parameters baudrate, stopbits, number of databits, parity. **/ +/*****************************************************************************/ +void CDirectSerial::updatePortConfig (Bit16u divider, Bit8u lcr) { + Bit8u parity = 0; + Bit8u bytelength = 0; + int baudrate=0; + + // baud + termInfo.c_cflag = CREAD | CLOCAL; + + if (divider == 0x1) baudrate = B115200; + else if (divider == 0x2) baudrate = B57600; + else if (divider == 0x3) baudrate = B38400; + else if (divider == 0x6) baudrate = B19200; + else if (divider == 0xc) baudrate = B9600; + else if (divider == 0x18) baudrate = B4800; + else if (divider == 0x30) baudrate = B2400; + else if (divider == 0x60) baudrate = B1200; + else if (divider == 0xc0) baudrate = B600; + else if (divider == 0x180) baudrate = B300; + else if (divider == 0x417) baudrate = B110; + + // Don't think termios supports nonstandard baudrates + else baudrate = B9600; + + // byte length + bytelength = lcr & 0x3; + bytelength += 5; + + switch (bytelength) { + case 5: + termInfo.c_cflag |= CS5; + break; + + case 6: + termInfo.c_cflag |= CS6; + break; + + case 7: + termInfo.c_cflag |= CS7; + break; + + case 8: + default: + termInfo.c_cflag |= CS8; + break; + } + + // parity + parity = lcr & 0x38; + parity >>= 3; + switch (parity) { + case 0x1: + termInfo.c_cflag |= PARODD; + termInfo.c_cflag |= PARENB; + break; + case 0x3: + termInfo.c_cflag |= PARENB; + break; + case 0x5: + +// "works on many systems" +#define CMSPAR 010000000000 + + termInfo.c_cflag |= PARODD; + termInfo.c_cflag |= PARENB; + termInfo.c_cflag |= CMSPAR; + //LOG_MSG("Serial%d: Mark parity not supported.", COMNUMBER); + break; + case 0x7: + termInfo.c_cflag |= PARENB; + termInfo.c_cflag |= CMSPAR; + //LOG_MSG("Serial%d: Space parity not supported.", COMNUMBER); + break; + default: // no parity + break; + } + + // stopbits + if (lcr & 0x4) termInfo.c_cflag |= CSTOPB; + + cfsetospeed (&termInfo, baudrate); + cfsetispeed (&termInfo, baudrate); + + int retval = tcsetattr(fileHandle, TCSANOW, &termInfo); + + if(retval==-1) + LOG_MSG ("Serial%d: Desired serial mode not supported", COMNUMBER); + +} + +void CDirectSerial::updateMSR () { + long flags = 0; + ioctl (fileHandle, TIOCMGET, &flags); + + if (flags & TIOCM_CTS) setCTS(true); + else setCTS(false); + + if (flags & TIOCM_DSR) setDSR(true); + else setDSR(false); + + if (flags & TIOCM_RI) setRI(true); + else setRI(false); + + if (flags & TIOCM_CD) setCD(true); + else setCD(false); +} + +void CDirectSerial::transmitByte (Bit8u val, bool first) { + if((LCR&LCR_BREAK_MASK) == 0) { + + int bytesWritten = write(fileHandle, &val, 1); + if (bytesWritten != 1) + LOG_MSG ("Serial%d: COM port error: write failed!", idnumber); + } + if(first) setEvent(SERIAL_THR_EVENT, bytetime/8); + else setEvent(SERIAL_TX_EVENT, bytetime); +} + +/*****************************************************************************/ +/* setBreak(val) switches break on or off **/ +/*****************************************************************************/ +void CDirectSerial::setBreak (bool value) { + if (value) ioctl (fileHandle, TIOCSBRK); + else ioctl (fileHandle, TIOCCBRK); +} + +/*****************************************************************************/ +/* updateModemControlLines(mcr) sets DTR and RTS. **/ +/*****************************************************************************/ +void CDirectSerial::setRTSDTR(bool rts, bool dtr) { + + long setflags = 0; + long clearflags = 0; + + if(rts) setflags |= TIOCM_RTS; + else clearflags |= TIOCM_RTS; + + if(dtr) setflags |= TIOCM_DTR; + else clearflags |= TIOCM_DTR; + + if(setflags) ioctl (fileHandle, TIOCMBIS, &setflags); + if(clearflags) ioctl (fileHandle, TIOCMBIC, &clearflags); +} +void CDirectSerial::setRTS(bool val) { + long flag = TIOCM_RTS; + if(val) ioctl(fileHandle, TIOCMBIS, &flag); + else ioctl(fileHandle, TIOCMBIC, &flag); +} +void CDirectSerial::setDTR(bool val) { + long flag = TIOCM_DTR; + if(val) ioctl(fileHandle, TIOCMBIS, &flag); + else ioctl(fileHandle, TIOCMBIC, &flag); +} + +#endif +#endif diff --git a/src/hardware/serialport/directserial_posix.h b/src/hardware/serialport/directserial_posix.h new file mode 100644 index 00000000..f57102a2 --- /dev/null +++ b/src/hardware/serialport/directserial_posix.h @@ -0,0 +1,69 @@ +/* + * 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: directserial_posix.h,v 1.1 2007-01-13 08:35:49 qbix79 Exp $ */ + +// include guard +#ifndef DOSBOX_DIRECTSERIAL_POSIX_H +#define DOSBOX_DIRECTSERIAL_POSIX_H + +#include "dosbox.h" + +#if C_DIRECTSERIAL +#ifdef LINUX + + + +#define DIRECTSERIAL_AVAILIBLE +#include "serialport.h" +#include +#include + +class CDirectSerial : public CSerial { +public: + termios termInfo; + termios backup; + int fileHandle; + + CDirectSerial(Bitu id, CommandLine* cmd); + ~CDirectSerial(); + bool receiveblock; // It's not a block of data it rather blocks + + Bitu rx_retry; // counter of retries + + Bitu rx_retry_max; // how many POLL_EVENTS to wait before causing + // a overrun error. + + void ReadCharacter(); + void CheckErrors(); + + void updatePortConfig(Bit16u divider, Bit8u lcr); + void updateMSR(); + void transmitByte(Bit8u val, bool first); + void setBreak(bool value); + + void setRTSDTR(bool rts, bool dtr); + void setRTS(bool val); + void setDTR(bool val); + void handleUpperEvent(Bit16u type); + +}; + +#endif // WIN32 +#endif // C_DIRECTSERIAL +#endif // include guard diff --git a/src/hardware/serialport/directserial_win32.cpp b/src/hardware/serialport/directserial_win32.cpp index ee546370..5b88721d 100644 --- a/src/hardware/serialport/directserial_win32.cpp +++ b/src/hardware/serialport/directserial_win32.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_win32.cpp,v 1.4 2007-01-08 19:45:41 qbix79 Exp $ */ +/* $Id: directserial_win32.cpp,v 1.5 2007-01-13 08:35:49 qbix79 Exp $ */ #include "dosbox.h" @@ -27,6 +27,8 @@ #include "serialport.h" #include "directserial_win32.h" +#include "misc_util.h" +#include "pic.h" // Win32 related headers #include @@ -34,17 +36,41 @@ /* This is a serial passthrough class. Its amazingly simple to */ /* write now that the serial ports themselves were abstracted out */ -CDirectSerial::CDirectSerial (IO_ReadHandler * rh, IO_WriteHandler * wh, - TIMER_TickHandler th, Bit16u baseAddr, Bit8u initIrq, - Bit32u initBps, Bit8u bytesize, const char *parity, - Bit8u stopbits,const char *realPort) - :CSerial (rh, wh, th,baseAddr,initIrq, initBps, - bytesize, parity,stopbits) { +CDirectSerial::CDirectSerial (Bitu id, CommandLine* cmd) + :CSerial (id, cmd) { InstallationSuccessful = false; - InstallTimerHandler(th); - lastChance = 0; - LOG_MSG ("Serial port at %x: Opening %s", base, realPort); - hCom = CreateFile (realPort, GENERIC_READ | GENERIC_WRITE, 0, // must be opened with exclusive-access + + rx_retry = 0; + rx_retry_max = 0; + + // open the port in NT object space (recommended by Microsoft) + // allows the user to open COM10+ and custom port names. + std::string prefix="\\\\.\\"; + std::string tmpstring; + if(!cmd->FindStringBegin("realport:",tmpstring,false)) return; + +#if SERIAL_DEBUG + if(dbg_modemcontrol) + fprintf(debugfp,"%12.3f Port type directserial realport %s\r\n", + PIC_FullIndex(),tmpstring.c_str()); +#endif + + prefix.append(tmpstring); + + // rxdelay: How many milliseconds to wait before causing an + // overflow when the application is unresponsive. + if(getBituSubstring("rxdelay:", &rx_retry_max, cmd)) { + if(!(rx_retry_max<=10000)) { + rx_retry_max=0; + } + } + + const char* tmpchar=prefix.c_str(); + + LOG_MSG ("Serial%d: Opening %s", COMNUMBER, tmpstring.c_str()); + hCom = CreateFile (tmpchar, + GENERIC_READ | GENERIC_WRITE, 0, + // must be opened with exclusive-access NULL, // no security attributes OPEN_EXISTING, // must use OPEN_EXISTING 0, // non overlapped I/O @@ -53,7 +79,8 @@ CDirectSerial::CDirectSerial (IO_ReadHandler * rh, IO_WriteHandler * wh, if (hCom == INVALID_HANDLE_VALUE) { int error = GetLastError (); - LOG_MSG ("Serial port \"%s\" could not be opened.", realPort); + LOG_MSG ("Serial%d: Serial Port \"%s\" could not be opened.", + COMNUMBER, tmpstring.c_str()); if (error == 2) { LOG_MSG ("The specified port does not exist."); } else if (error == 5) { @@ -61,19 +88,48 @@ CDirectSerial::CDirectSerial (IO_ReadHandler * rh, IO_WriteHandler * wh, } else { LOG_MSG ("Windows error %d occurred.", error); } - - hCom = 0; return; } + dcb.DCBlength=sizeof(dcb); fSuccess = GetCommState (hCom, &dcb); if (!fSuccess) { // Handle the error. LOG_MSG ("GetCommState failed with error %d.\n", GetLastError ()); - hCom = 0; + hCom = INVALID_HANDLE_VALUE; return; } + + // initialize the port + dcb.BaudRate=CBR_9600; + dcb.fBinary=true; + dcb.fParity=true; + dcb.fOutxCtsFlow=false; + dcb.fOutxDsrFlow=false; + dcb.fDtrControl=DTR_CONTROL_DISABLE; + dcb.fDsrSensitivity=false; + + dcb.fOutX=false; + dcb.fInX=false; + dcb.fErrorChar=0; + dcb.fNull=false; + dcb.fRtsControl=RTS_CONTROL_DISABLE; + dcb.fAbortOnError=false; + + dcb.ByteSize=8; + dcb.Parity=NOPARITY; + dcb.StopBits=ONESTOPBIT; + + fSuccess = SetCommState (hCom, &dcb); + + if (!fSuccess) { + // Handle the error. + LOG_MSG ("SetCommState failed with error %d.\n", GetLastError ()); + hCom = INVALID_HANDLE_VALUE; + return; + } + // Configure timeouts to effectively use polling COMMTIMEOUTS ct; ct.ReadIntervalTimeout = MAXDWORD; @@ -83,50 +139,103 @@ CDirectSerial::CDirectSerial (IO_ReadHandler * rh, IO_WriteHandler * wh, ct.WriteTotalTimeoutMultiplier = 0; SetCommTimeouts (hCom, &ct); - CSerial::Init_Registers (initBps, bytesize, parity, stopbits); + CSerial::Init_Registers(); InstallationSuccessful = true; - //LOG_MSG("InstSuccess"); + receiveblock=false; + + ClearCommBreak (hCom); + setEvent(SERIAL_POLLING_EVENT, 1); // millisecond tick } CDirectSerial::~CDirectSerial () { - if (hCom != INVALID_HANDLE_VALUE) - CloseHandle (hCom); + if (hCom != INVALID_HANDLE_VALUE) CloseHandle (hCom); + // We do not use own events so we don't have to clear them. } -Bitu lastChance; - -void CDirectSerial::RXBufferEmpty () { - DWORD dwRead; - DWORD errors; - Bit8u chRead; - if (lastChance > 0) { - receiveByte (ChanceChar); - lastChance = 0; - } else { - // update RX - if (ReadFile (hCom, &chRead, 1, &dwRead, NULL)) { - if (dwRead != 0) { - //LOG_MSG("UART 0x%x: RX 0x%x", base,chRead); - receiveByte (chRead); +void CDirectSerial::handleUpperEvent(Bit16u type) { + + switch(type) { + case SERIAL_POLLING_EVENT: { + DWORD dwRead = 0; + DWORD errors = 0; + Bit8u chRead = 0; + + setEvent(SERIAL_POLLING_EVENT, 1); + if(!receiveblock) { + if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )) + { + rx_retry=0; + if (ReadFile (hCom, &chRead, 1, &dwRead, NULL)) { + if (dwRead) { + receiveByte (chRead); + setEvent(40, bytetime-0.03f); // receive timing + receiveblock=true; + } + } + } else rx_retry++; } + // check for errors + CheckErrors(); + // update Modem input line states + updateMSR (); + break; + } + case 40: { + // receive time is up + DWORD dwRead = 0; + Bit8u chRead = 0; + receiveblock=false; + // check if there is something to receive + if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )) + { + rx_retry=0; + if (ReadFile (hCom, &chRead, 1, &dwRead, NULL)) { + if (dwRead) { + receiveByte (chRead); + setEvent(40, bytetime-0.03f); // receive timing + receiveblock=true; + } + } + } else rx_retry++; + break; + } + case SERIAL_TX_EVENT: { + DWORD dwRead = 0; + Bit8u chRead = 0; + if(!receiveblock) { + if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )) + { + rx_retry=0; + if (ReadFile (hCom, &chRead, 1, &dwRead, NULL)) { + if (dwRead) { + receiveByte (chRead); + setEvent(40, bytetime-0.03f); // receive timing + receiveblock=true; + } + } + } else rx_retry++; + } + ByteTransmitted(); + break; + } + case SERIAL_THR_EVENT: { + ByteTransmitting(); + setEvent(SERIAL_TX_EVENT,bytetime+0.03f); + break; } } +} + +void CDirectSerial::CheckErrors() { + + DWORD errors=0; // check for errors if (ClearCommError (hCom, &errors, NULL)) if (errors & (CE_BREAK | CE_FRAME | CE_RXPARITY)) { Bit8u errreg = 0; - if (errors & CE_BREAK) { - LOG_MSG ("Serial port at 0x%x: line error: break received.", base); - errreg |= LSR_RX_BREAK_MASK; - } - if (errors & CE_FRAME) { - LOG_MSG ("Serial port at 0x%x: line error: framing error.", base); - errreg |= LSR_FRAMING_ERROR_MASK; - } - if (errors & CE_RXPARITY) { - LOG_MSG ("Serial port at 0x%x: line error: parity error.", base); - errreg |= LSR_PARITY_ERROR_MASK; - } + if (errors & CE_BREAK) errreg |= LSR_RX_BREAK_MASK; + if (errors & CE_FRAME) errreg |= LSR_FRAMING_ERROR_MASK; + if (errors & CE_RXPARITY) errreg |= LSR_PARITY_ERROR_MASK; receiveError (errreg); } } @@ -135,45 +244,37 @@ void CDirectSerial::RXBufferEmpty () { /* updatePortConfig is called when emulated app changes the serial port **/ /* parameters baudrate, stopbits, number of databits, parity. **/ /*****************************************************************************/ -void CDirectSerial::updatePortConfig (Bit8u dll, Bit8u dlm, Bit8u lcr) { +void CDirectSerial::updatePortConfig (Bit16u divider, Bit8u lcr) { Bit8u parity = 0; Bit8u bytelength = 0; - Bit16u baudrate = 0; // baud - baudrate = dlm; - baudrate = baudrate << 8; - baudrate |= dll; - if (baudrate <= 0x1) + if (divider == 0x1) dcb.BaudRate = CBR_115200; - else if (baudrate <= 0x2) + else if (divider == 0x2) dcb.BaudRate = CBR_57600; - else if (baudrate <= 0x3) + else if (divider == 0x3) dcb.BaudRate = CBR_38400; - else if (baudrate <= 0x6) + else if (divider == 0x6) dcb.BaudRate = CBR_19200; - else if (baudrate <= 0xc) + else if (divider == 0xc) dcb.BaudRate = CBR_9600; - else if (baudrate <= 0x18) + else if (divider == 0x18) dcb.BaudRate = CBR_4800; - else if (baudrate <= 0x30) + else if (divider == 0x30) dcb.BaudRate = CBR_2400; - else if (baudrate <= 0x60) + else if (divider == 0x60) dcb.BaudRate = CBR_1200; - else if (baudrate <= 0xc0) + else if (divider == 0xc0) dcb.BaudRate = CBR_600; - else if (baudrate <= 0x180) + else if (divider == 0x180) dcb.BaudRate = CBR_300; - else if (baudrate <= 0x417) + else if (divider == 0x417) dcb.BaudRate = CBR_110; // I read that windows can handle nonstandard baudrates: else - dcb.BaudRate = 115200 / baudrate; - -#ifdef SERIALPORT_DEBUGMSG - LOG_MSG ("Serial port at %x: new baud rate: %d", base, dcb.BaudRate); -#endif + dcb.BaudRate = 115200 / divider; // byte length bytelength = lcr & 0x3; @@ -211,9 +312,25 @@ void CDirectSerial::updatePortConfig (Bit8u dll, Bit8u dlm, Bit8u lcr) { dcb.StopBits = ONESTOPBIT; } - if (!SetCommState (hCom, &dcb)) - LOG_MSG ("Serial port at 0x%x: API did not like the new values.", base); - //LOG_MSG("Serial port at 0x%x: Port params changed: %d Baud", base,dcb.BaudRate); +#ifdef SERIALPORT_DEBUGMSG + LOG_MSG ("__________________________"); + LOG_MSG ("Serial%d: new baud rate: %d", COMNUMBER, dcb.BaudRate); + LOG_MSG ("Serial%d: new bytelen: %d", COMNUMBER, dcb.ByteSize); + LOG_MSG ("Serial%d: new parity: %d", COMNUMBER, dcb.Parity); + LOG_MSG ("Serial%d: new stopbits: %d", COMNUMBER, dcb.StopBits); +#endif + + if (!SetCommState (hCom, &dcb)) { + +#if SERIAL_DEBUG + if(dbg_modemcontrol) + fprintf(debugfp,"%12.3f serial mode not supported: rate=%d,LCR=%x.\r\n", + PIC_FullIndex(),dcb.BaudRate,lcr); +#endif + + LOG_MSG ("Serial%d: Desired serial mode not supported (%d,%d,%d,%d", + dcb.BaudRate,dcb.ByteSize,dcb.Parity,dcb.StopBits, COMNUMBER); + } } void CDirectSerial::updateMSR () { @@ -226,153 +343,53 @@ void CDirectSerial::updateMSR () { #endif //return; } - if (dptr & MS_CTS_ON) - newmsr |= MSR_CTS_MASK; - if (dptr & MS_DSR_ON) - newmsr |= MSR_DSR_MASK; - if (dptr & MS_RING_ON) - newmsr |= MSR_RI_MASK; - if (dptr & MS_RLSD_ON) - newmsr |= MSR_CD_MASK; - changeMSR (newmsr); + setCTS((dptr & MS_CTS_ON)!=0); + setDSR((dptr & MS_DSR_ON)!=0); + setRI ((dptr & MS_RING_ON)!=0); + setCD((dptr & MS_RLSD_ON)!=0); } -void CDirectSerial::transmitByte (Bit8u val) { +void CDirectSerial::transmitByte (Bit8u val, bool first) { // mean bug: with break = 1, WriteFile will never return. if((LCR&LCR_BREAK_MASK) == 0) { - DWORD bytesWritten = 0; WriteFile (hCom, &val, 1, &bytesWritten, NULL); - if (bytesWritten > 0) { - ByteTransmitted (); - //LOG_MSG("UART 0x%x: TX 0x%x", base,val); - } else { - LOG_MSG ("UART 0x%x: NO BYTE WRITTEN! PORT HANGS NOW!", base); - } - } else { - // have a delay here, it's the only sense of sending - // data with break=1 - Bitu ticks; - Bitu elapsed = 0; - ticks = GetTicks(); - - while(elapsed < 10) { - elapsed = GetTicks() - ticks; - } - ByteTransmitted(); + if (bytesWritten != 1) + LOG_MSG ("Serial%d: COM port error: write failed!", idnumber); } + if(first) setEvent(SERIAL_THR_EVENT, bytetime/8); + else setEvent(SERIAL_TX_EVENT, bytetime); } /*****************************************************************************/ /* setBreak(val) switches break on or off **/ /*****************************************************************************/ - void CDirectSerial::setBreak (bool value) { - //#ifdef SERIALPORT_DEBUGMSG - //LOG_MSG("UART 0x%x: Break toggeled: %d", base, value); - //#endif - if (value) - SetCommBreak (hCom); - else - ClearCommBreak (hCom); + if (value) SetCommBreak (hCom); + else ClearCommBreak (hCom); } /*****************************************************************************/ /* updateModemControlLines(mcr) sets DTR and RTS. **/ /*****************************************************************************/ -void CDirectSerial::updateModemControlLines ( /*Bit8u mcr */ ) { - bool change = false; +void CDirectSerial::setRTSDTR(bool rts, bool dtr) { + if(rts) dcb.fRtsControl = RTS_CONTROL_ENABLE; + else dcb.fRtsControl = RTS_CONTROL_DISABLE; + if(dtr) dcb.fDtrControl = DTR_CONTROL_ENABLE; + else dcb.fDtrControl = DTR_CONTROL_DISABLE; + SetCommState (hCom, &dcb); - /*** DTR ***/ - if (CSerial::getDTR ()) { // DTR on - if (dcb.fDtrControl == DTR_CONTROL_DISABLE) { - dcb.fDtrControl = DTR_CONTROL_ENABLE; - change = true; - } - } else { - if (dcb.fDtrControl == DTR_CONTROL_ENABLE) { - dcb.fDtrControl = DTR_CONTROL_DISABLE; - change = true; - } - } - /*** RTS ***/ - if (CSerial::getRTS ()) { // RTS on - if (dcb.fRtsControl == RTS_CONTROL_DISABLE) { - dcb.fRtsControl = RTS_CONTROL_ENABLE; - change = true; - } - } else { - if (dcb.fRtsControl == RTS_CONTROL_ENABLE) { - dcb.fRtsControl = RTS_CONTROL_DISABLE; - change = true; - } - } - if (change) - SetCommState (hCom, &dcb); } - -void CDirectSerial::Timer2(void) { - DWORD dwRead = 0; - DWORD errors = 0; - Bit8u chRead = 0; - - - if (lastChance == 0) { // lastChance = 0 - if (CanReceiveByte ()) { - if (ReadFile (hCom, &chRead, 1, &dwRead, NULL)) { - if (dwRead) - receiveByte (chRead); - } - } else { - if (ReadFile (hCom, &chRead, 1, &dwRead, NULL)) { - if (dwRead) { - ChanceChar = chRead; - lastChance++; - } - } - } - } else if (lastChance > 10) { - receiveByte (0); // this causes RX Overrun now - lastChance = 0; - // empty serial buffer - dwRead = 1; - while (dwRead > 0) { // throw away bytes in buffer - ReadFile (hCom, &chRead, 1, &dwRead, NULL); - } - } else { // lastChance>0 // already one waiting - if (CanReceiveByte ()) { // chance used - receiveByte (ChanceChar); - lastChance = 0; - } else - lastChance++; - } - - // check for errors - if (ClearCommError (hCom, &errors, NULL)) - if (errors & (CE_BREAK | CE_FRAME | CE_RXPARITY)) { - Bit8u errreg = 0; - - if (errors & CE_BREAK) { - LOG_MSG ("Serial port at 0x%x: line error: break received.", base); - errreg |= LSR_RX_BREAK_MASK; - } - if (errors & CE_FRAME) { - LOG_MSG ("Serial port at 0x%x: line error: framing error.", base); - errreg |= LSR_FRAMING_ERROR_MASK; - } - if (errors & CE_RXPARITY) { - LOG_MSG ("Serial port at 0x%x: line error: parity error.", base); - errreg |= LSR_PARITY_ERROR_MASK; - } - - receiveError (errreg); - } - // update Modem input line states - updateMSR (); +void CDirectSerial::setRTS(bool val) { + if(val) dcb.fRtsControl = RTS_CONTROL_ENABLE; + else dcb.fRtsControl = RTS_CONTROL_DISABLE; + SetCommState (hCom, &dcb); +} +void CDirectSerial::setDTR(bool val) { + if(val) dcb.fDtrControl = DTR_CONTROL_ENABLE; + else dcb.fDtrControl = DTR_CONTROL_DISABLE; + SetCommState (hCom, &dcb); } - - -#else /*linux and others oneday maybe */ #endif #endif diff --git a/src/hardware/serialport/directserial_win32.h b/src/hardware/serialport/directserial_win32.h index e78beaea..225da117 100644 --- a/src/hardware/serialport/directserial_win32.h +++ b/src/hardware/serialport/directserial_win32.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_win32.h,v 1.3 2007-01-08 19:45:41 qbix79 Exp $ */ +/* $Id: directserial_win32.h,v 1.4 2007-01-13 08:35:49 qbix79 Exp $ */ // include guard #ifndef DOSBOX_DIRECTSERIAL_WIN32_H @@ -39,43 +39,27 @@ public: DCB dcb; BOOL fSuccess; - CDirectSerial( - IO_ReadHandler* rh, - IO_WriteHandler* wh, - TIMER_TickHandler th, - Bit16u baseAddr, - Bit8u initIrq, - Bit32u initBps, - Bit8u bytesize, - const char *parity, - Bit8u stopbits, - const char * realPort - ); - - + CDirectSerial(Bitu id, CommandLine* cmd/*const char* configstring*/); ~CDirectSerial(); + bool receiveblock; // It's not a block of data it rather blocks + + Bitu rx_retry; // counter of retries + + Bitu rx_retry_max; // how many POLL_EVENTS to wait before causing + // a overrun error. + + + void CheckErrors(); - - Bitu lastChance; // If there is no space for new - // received data, it gets a little chance - Bit8u ChanceChar; - - bool CanRecv(void); - bool CanSend(void); - - bool InstallationSuccessful; // check after constructing. If - // something was wrong, delete it right away. - - void RXBufferEmpty(); - - - void updatePortConfig(Bit8u dll, Bit8u dlm, Bit8u lcr); + void updatePortConfig(Bit16u divider, Bit8u lcr); void updateMSR(); - void transmitByte(Bit8u val); + void transmitByte(Bit8u val, bool first); void setBreak(bool value); - void updateModemControlLines(/*Bit8u mcr*/); - void Timer2(void); + void setRTSDTR(bool rts, bool dtr); + void setRTS(bool val); + void setDTR(bool val); + void handleUpperEvent(Bit16u type); }; diff --git a/src/hardware/serialport/misc_util.cpp b/src/hardware/serialport/misc_util.cpp new file mode 100644 index 00000000..84ee29d3 --- /dev/null +++ b/src/hardware/serialport/misc_util.cpp @@ -0,0 +1,318 @@ +#include "config.h" + +#include "misc_util.h" + +#if C_MODEM + +/*****************************************************************************/ +// C++ SDLnet wrapper + +// Socket inheritance +#ifdef LINUX +#define CAPWORD (NETWRAPPER_TCP|NETWRAPPER_TCP_NATIVESOCKET) +#include +#include +#include +#define SOCKET int + +#elif defined WIN32 +#define CAPWORD (NETWRAPPER_TCP|NETWRAPPER_TCP_NATIVESOCKET) +#include +typedef int socklen_t; + +#else +#define CAPWORD NETWRAPPER_TCP +#endif + +struct _TCPsocketX { + int ready; + SOCKET channel; + IPaddress remoteAddress; + IPaddress localAddress; + int sflag; +}; + +Bit32u Netwrapper_GetCapabilities() +{ + Bit32u retval=0; + retval = CAPWORD; + return retval; +} + +#ifdef NATIVESOCKETS +TCPClientSocket::TCPClientSocket(int platformsocket) { + sendbuffer=0; + nativetcpstruct = new Bit8u[sizeof(struct _TCPsocketX)]; + + mysock = (TCPsocket)nativetcpstruct; + isopen = false; + if(!SDLNetInited) { + if(SDLNet_Init()==-1) { + LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); + return; + } + SDLNetInited = true; + } + // fill the SDL socket manually + ((struct _TCPsocketX*)nativetcpstruct)->ready=0; + ((struct _TCPsocketX*)nativetcpstruct)->sflag=0; + ((struct _TCPsocketX*)nativetcpstruct)->channel=platformsocket; + sockaddr_in sa; + socklen_t sz; + sz=sizeof(sa); + if(getpeername(platformsocket, (sockaddr *)(&sa), &sz)==0) { + ((struct _TCPsocketX*)nativetcpstruct)-> + remoteAddress.host=/*ntohl(*/sa.sin_addr.s_addr;//); + ((struct _TCPsocketX*)nativetcpstruct)-> + remoteAddress.port=/*ntohs(*/sa.sin_port;//); + } + else { + mysock=0; + return; + } + sz=sizeof(sa); + if(getsockname(platformsocket, (sockaddr *)(&sa), &sz)==0) { + ((struct _TCPsocketX*)nativetcpstruct)-> + localAddress.host=/*ntohl(*/sa.sin_addr.s_addr;//); + ((struct _TCPsocketX*)nativetcpstruct)-> + localAddress.port=/*ntohs(*/sa.sin_port;//); + } + else { + mysock=0; + return; + } + if(mysock!=0) { + listensocketset = SDLNet_AllocSocketSet(1); + if(!listensocketset) return; + SDLNet_TCP_AddSocket(listensocketset, mysock); + isopen=true; + return; + } + mysock=0; + return; +} +#endif // NATIVESOCKETS + +TCPClientSocket::TCPClientSocket(TCPsocket source) { +#ifdef NATIVESOCKETS + nativetcpstruct=0; +#endif + sendbuffer=0; + isopen = false; + if(!SDLNetInited) { + if(SDLNet_Init()==-1) { + LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); + return; + } + SDLNetInited = true; + } + + mysock=0; + listensocketset=0; + if(source!=0) { + mysock = source; + listensocketset = SDLNet_AllocSocketSet(1); + if(!listensocketset) return; + SDLNet_TCP_AddSocket(listensocketset, source); + + isopen=true; + } +} +TCPClientSocket::TCPClientSocket(const char* destination, Bit16u port) { +#ifdef NATIVESOCKETS + nativetcpstruct=0; +#endif + sendbuffer=0; + isopen = false; + if(!SDLNetInited) { + if(SDLNet_Init()==-1) { + LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); + return; + } + SDLNetInited = true; + } + mysock=0; + listensocketset=0; + + IPaddress openip; + if (!SDLNet_ResolveHost(&openip,destination,port)) { + listensocketset = SDLNet_AllocSocketSet(1); + if(!listensocketset) return; + mysock = SDLNet_TCP_Open(&openip); + if(!mysock) return; + SDLNet_TCP_AddSocket(listensocketset, mysock); + isopen=true; + } +} + +TCPClientSocket::~TCPClientSocket() { + + if(sendbuffer) delete [] sendbuffer; +#ifdef NATIVESOCKETS + if(nativetcpstruct) delete [] nativetcpstruct; + else +#endif + if(mysock) { + if(listensocketset) SDLNet_TCP_DelSocket(listensocketset,mysock); + SDLNet_TCP_Close(mysock); + } + + if(listensocketset) SDLNet_FreeSocketSet(listensocketset); +} +bool TCPClientSocket::GetRemoteAddressString(Bit8u* buffer) { + IPaddress* remote_ip; + Bit8u b1, b2, b3, b4; + remote_ip=SDLNet_TCP_GetPeerAddress(mysock); + if(!remote_ip) return false; + b4=remote_ip->host>>24; + b3=(remote_ip->host>>16)&0xff; + b2=(remote_ip->host>>8)&0xff; + b1=remote_ip->host&0xff; + sprintf((char*)buffer,"%u.%u.%u.%u",b1,b2,b3,b4); + return true; +} + +bool TCPClientSocket::ReceiveArray(Bit8u* data, Bitu* size) { + if(SDLNet_CheckSockets(listensocketset,0)) + { + Bitu retval = SDLNet_TCP_Recv(mysock, data, *size); + if(retval<1) { + isopen=false; + *size=0; + return false; + } else { + *size=retval; + return true; + } + } + else { + *size=0; + return true; + } +} + + +Bits TCPClientSocket::GetcharNonBlock() { +// return: +// -1: no data +// -2: socket closed +// 0..255: data + if(SDLNet_CheckSockets(listensocketset,0)) + { + Bitu retval =0; + if(SDLNet_TCP_Recv(mysock, &retval, 1)!=1) { + isopen=false; + return -2; + } else return retval; + } + else return -1; +} +bool TCPClientSocket::Putchar(Bit8u data) { + if(SDLNet_TCP_Send(mysock, &data, 1)!=1) { + isopen=false; + return false; + } + return true; +} + +bool TCPClientSocket::SendArray(Bit8u* data, Bitu bufsize) { + if(SDLNet_TCP_Send(mysock, data, bufsize)!=bufsize) { + isopen=false; + return false; + } + return true; +} + +bool TCPClientSocket::SendByteBuffered(Bit8u data) { + + if(sendbufferindex==(sendbuffersize-1)) { + // buffer is full, get rid of it + sendbuffer[sendbufferindex]=data; + sendbufferindex=0; + + if(SDLNet_TCP_Send(mysock, sendbuffer, sendbuffersize)!=sendbuffersize) { + isopen=false; + return false; + } + } else { + sendbuffer[sendbufferindex]=data; + sendbufferindex++; + } + return true; +} +/* +bool TCPClientSocket::SendArrayBuffered(Bit8u* data, Bitu bufsize) { + + Bitu bytes + while( + + // first case, buffer already full + /*if(sendbufferindex==(sendbuffersize-1)) { + // buffer is full, get rid of it + sendbuffer[sendbufferindex]=data; + sendbufferindex=0; + + if(SDLNet_TCP_Send(mysock, sendbuffer, sendbuffersize)!=sendbuffersize) { + isopen=false; + return false; + } + }*/ +//} + +void TCPClientSocket::FlushBuffer() { + if(sendbufferindex) { + if(SDLNet_TCP_Send(mysock, sendbuffer, + sendbufferindex)!=sendbufferindex) { + isopen=false; + return; + } + sendbufferindex=0; + } +} + +void TCPClientSocket::SetSendBufferSize(Bitu bufsize) { + if(sendbuffer) delete [] sendbuffer; + sendbuffer = new Bit8u[bufsize]; + sendbuffersize=bufsize; + sendbufferindex=0; +} + + +TCPServerSocket::TCPServerSocket(Bit16u port) +{ + isopen = false; + mysock = 0; + if(!SDLNetInited) { + if(SDLNet_Init()==-1) { + LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); + return; + } + SDLNetInited = true; + } + if (port) { + IPaddress listen_ip; + SDLNet_ResolveHost(&listen_ip, NULL, port); + mysock=SDLNet_TCP_Open(&listen_ip); + if(!mysock) return; + } + else return; + isopen = true; +} + +TCPServerSocket::~TCPServerSocket() { + if(mysock) SDLNet_TCP_Close(mysock); +} + +TCPClientSocket* TCPServerSocket::Accept() { + + TCPsocket new_tcpsock; + + new_tcpsock=SDLNet_TCP_Accept(mysock); + if(!new_tcpsock) { + //printf("SDLNet_TCP_Accept: %s\n", SDLNet_GetError()); + return 0; + } + + return new TCPClientSocket(new_tcpsock); +} +#endif // #if C_MODEM diff --git a/src/hardware/serialport/misc_util.h b/src/hardware/serialport/misc_util.h new file mode 100644 index 00000000..62f8809d --- /dev/null +++ b/src/hardware/serialport/misc_util.h @@ -0,0 +1,79 @@ +#ifndef SDLNETWRAPPER_H +#define SDLNETWRAPPER_H + +#if C_MODEM + +#include "SDL_net.h" +#include "support.h" + +#ifdef LINUX +#define NATIVESOCKETS + +#elif defined WIN32 +#define NATIVESOCKETS + +#else +#endif + +// Netwrapper Capabilities +#define NETWRAPPER_TCP 1 +#define NETWRAPPER_TCP_NATIVESOCKET 2 + +Bit32u Netwrapper_GetCapabilities(); + + +class TCPClientSocket { + public: + TCPClientSocket(TCPsocket source); + TCPClientSocket(const char* destination, Bit16u port); +#ifdef NATIVESOCKETS + void* nativetcpstruct; + TCPClientSocket(int platformsocket); +#endif + ~TCPClientSocket(); + + // return: + // -1: no data + // -2: socket closed + // >0: data char + Bits GetcharNonBlock(); + + + bool Putchar(Bit8u data); + bool SendArray(Bit8u* data, Bitu bufsize); + bool ReceiveArray(Bit8u* data, Bitu* size); + bool isopen; + + bool GetRemoteAddressString(Bit8u* buffer); + + void FlushBuffer(); + void SetSendBufferSize(Bitu bufsize); + + // buffered send functions + bool SendByteBuffered(Bit8u data); + bool SendArrayBuffered(Bit8u* data, Bitu bufsize); + + private: + TCPsocket mysock; + SDLNet_SocketSet listensocketset; + + // Items for send buffering + Bitu sendbuffersize; + Bitu sendbufferindex; + + Bit8u* sendbuffer; +}; + +class TCPServerSocket { + public: + bool isopen; + TCPsocket mysock; + TCPServerSocket(Bit16u port); + ~TCPServerSocket(); + TCPClientSocket* Accept(); +}; + + +#endif + +#endif //#if C_MODEM diff --git a/src/hardware/serialport/nullmodem.cpp b/src/hardware/serialport/nullmodem.cpp new file mode 100644 index 00000000..7f8cb47b --- /dev/null +++ b/src/hardware/serialport/nullmodem.cpp @@ -0,0 +1,496 @@ +/* + * 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. + */ + +#include "dosbox.h" + +#if C_MODEM + +#include "setup.h" // CommandLine +#include "serialport.h" +#include "nullmodem.h" + +CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) { + Bitu temptcpport=23; + memset(&telClient, 0, sizeof(telClient)); + InstallationSuccessful = false; + serversocket = 0; + clientsocket = 0; + serverport = 0; + clientport = 0; + + rx_retry = 0; + rx_retry_max = 100; + + tx_gather = 12; + + dtrrespect=false; + tx_block=false; + receiveblock=false; + transparent=false; + telnet=false; + + Bitu bool_temp=0; + + // usedtr: The nullmodem will + // 1) when it is client connect to the server not immediately but + // as soon as a modem-aware application is started (DTR is switched on). + // 2) only transfer data when DTR is on. + if(getBituSubstring("usedtr:", &bool_temp, cmd)) { + if(bool_temp==1) { + dtrrespect=true; + transparent=true; + } + } + // transparent: don't add additional handshake control. + if(getBituSubstring("transparent:", &bool_temp, cmd)) { + if(bool_temp==1) transparent=true; + else transparent=false; + } + // telnet: interpret telnet commands. + if(getBituSubstring("telnet:", &bool_temp, cmd)) { + if(bool_temp==1) { + transparent=true; + telnet=true; + } + } + // rxdelay: How many milliseconds to wait before causing an + // overflow when the application is unresponsive. + if(getBituSubstring("rxdelay:", &rx_retry_max, cmd)) { + if(!(rx_retry_max<=10000)) { + rx_retry_max=50; + } + } + // txdelay: How many milliseconds to wait before sending data. + // This reduces network overhead quite a lot. + if(getBituSubstring("txdelay:", &tx_gather, cmd)) { + if(!(tx_gather<=500)) { + tx_gather=12; + } + } + // port is for both server and client + if(getBituSubstring("port:", &temptcpport, cmd)) { + if(!(temptcpport>0&&temptcpport<65536)) { + temptcpport=23; + } + } + // socket inheritance + if(getBituSubstring("inhsocket:", &bool_temp, cmd)) { + if(Netwrapper_GetCapabilities()&NETWRAPPER_TCP_NATIVESOCKET) { + if(bool_temp==1) { + int sock; + if (control->cmdline->FindInt("-socket",sock,true)) { + dtrrespect=false; + transparent=true; + // custom connect + Bit8u peernamebuf[16]; + LOG_MSG("inheritance port: %d",sock); + clientsocket = new TCPClientSocket(sock); + if(!clientsocket->isopen) { + LOG_MSG("Serial%d: Connection failed.",COMNUMBER); + delete clientsocket; + clientsocket=0; + return; + } + clientsocket->SetSendBufferSize(256); + clientsocket->GetRemoteAddressString(peernamebuf); + // transmit the line status + if(!transparent) setRTSDTR(getRTS(), getDTR()); + + LOG_MSG("Serial%d: Connected to %s",COMNUMBER,peernamebuf); + setEvent(SERIAL_POLLING_EVENT, 1); + + CSerial::Init_Registers (); + InstallationSuccessful = true; + + setCTS(true); + setDSR(true); + setRI (false); + setCD (true); + return; + } else { + LOG_MSG("Serial%d: -socket start parameter missing.",COMNUMBER); + return; + } + } + } else { + LOG_MSG("Serial%d: socket inheritance not supported on this platform.", + COMNUMBER); + return; + } + } + std::string tmpstring; + if(cmd->FindStringBegin("server:",tmpstring,false)) { + // we are a client + const char* hostnamechar=tmpstring.c_str(); + Bitu hostlen=strlen(hostnamechar)+1; + if(hostlen>sizeof(hostnamebuffer)) { + hostlen=sizeof(hostnamebuffer); + hostnamebuffer[sizeof(hostnamebuffer)-1]=0; + } + memcpy(hostnamebuffer,hostnamechar,hostlen); + clientport=temptcpport; + if(dtrrespect) { + // we connect as soon as DTR is switched on + setEvent(SERIAL_NULLMODEM_DTR_EVENT, 50); + LOG_MSG("Serial%d: Waiting for DTR...",COMNUMBER); + } else ClientConnect(); + } else { + // we are a server + serverport = (Bit16u)temptcpport; + serversocket = new TCPServerSocket(serverport); + if(!serversocket->isopen) return; + LOG_MSG("Serial%d: Nullmodem server waiting for connection on port %d...", + COMNUMBER,serverport); + setEvent(SERIAL_SERVER_POLLING_EVENT, 50); + } + + // .... + + CSerial::Init_Registers (); + InstallationSuccessful = true; + + setCTS(dtrrespect||transparent); + setDSR(dtrrespect||transparent); + setRI (false); + setCD (dtrrespect); +} + +CNullModem::~CNullModem () { + if(serversocket) delete serversocket; + if(clientsocket) delete clientsocket; + // remove events + for(Bitu i = SERIAL_BASE_EVENT_COUNT+1; + i <= SERIAL_NULLMODEM_EVENT_COUNT; i++) + removeEvent(i); +} + +void CNullModem::WriteChar(Bit8u data) { + + if(clientsocket)clientsocket->SendByteBuffered(data); + if(!tx_block) { + //LOG_MSG("setevreduct"); + setEvent(SERIAL_TX_REDUCTION, (float)tx_gather); + tx_block=true; + } +} + +Bits CNullModem::readChar() { + + Bits rxchar = clientsocket->GetcharNonBlock(); + if(telnet && rxchar>=0) return TelnetEmulation(rxchar); + else if(rxchar==0xff && !transparent) {// escape char + // get the next char + Bits rxchar = clientsocket->GetcharNonBlock(); + if(rxchar==0xff) return rxchar; // 0xff 0xff -> 0xff was meant + rxchar&0x1? setCTS(true) : setCTS(false); + rxchar&0x2? setDSR(true) : setDSR(false); + if(rxchar&0x4) receiveError(0x10); + return -1; // no "payload" received + } else return rxchar; +} + +void CNullModem::ClientConnect(){ + Bit8u peernamebuf[16]; + clientsocket = new TCPClientSocket((char*)hostnamebuffer, + (Bit16u)clientport); + if(!clientsocket->isopen) { + LOG_MSG("Serial%d: Connection failed.",idnumber+1); + delete clientsocket; + clientsocket=0; + return; + } + clientsocket->SetSendBufferSize(256); + clientsocket->GetRemoteAddressString(peernamebuf); + // transmit the line status + if(!transparent) setRTSDTR(getRTS(), getDTR()); + + LOG_MSG("Serial%d: Connected to %s",idnumber+1,peernamebuf); + setEvent(SERIAL_POLLING_EVENT, 1); +} + +void CNullModem::Disconnect() { + // it was disconnected; free the socket and restart the server socket + LOG_MSG("Serial%d: Disconnected.",idnumber+1); + delete clientsocket; + clientsocket=0; + setDTR(false); + setCTS(false); + if(serverport) { + serversocket = new TCPServerSocket(serverport); + if(serversocket->isopen) + setEvent(SERIAL_SERVER_POLLING_EVENT, 50); + else delete serversocket; + } +} + +void CNullModem::handleUpperEvent(Bit16u type) { + + switch(type) { + case SERIAL_POLLING_EVENT: { + // periodically check if new data arrived, disconnect + // if required. Add it back. + if(!receiveblock && clientsocket) { + if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max ) + &&(!dtrrespect | (dtrrespect&& getDTR()) )) { + rx_retry=0; + Bits rxchar = readChar(); + if(rxchar>=0) { + receiveblock=true; + setEvent(SERIAL_RX_EVENT, bytetime-0.01f); + receiveByte((Bit8u)rxchar); + } + else if(rxchar==-2) Disconnect(); + else setEvent(SERIAL_POLLING_EVENT, 1); + } else { + rx_retry++; + setEvent(SERIAL_POLLING_EVENT, 1); + } + } + break; + } + case SERIAL_RX_EVENT: { + // receive time is up, try to receive another byte. + receiveblock=false; + + if((!(LSR&LSR_RX_DATA_READY_MASK) || rx_retry>=rx_retry_max) + &&(!dtrrespect | (dtrrespect&& getDTR()) ) + ) { + rx_retry=0; + Bits rxchar = readChar(); + if(rxchar>=0) { + receiveblock=true; + setEvent(SERIAL_RX_EVENT, bytetime-0.01f); + receiveByte((Bit8u)rxchar); + } + else if(rxchar==-2) Disconnect(); + else setEvent(SERIAL_POLLING_EVENT, 1); + } else { + setEvent(SERIAL_POLLING_EVENT, 1); + rx_retry++; + } + break; + } + case SERIAL_TX_EVENT: { + ByteTransmitted(); + break; + } + case SERIAL_THR_EVENT: { + ByteTransmitting(); + // actually send it + setEvent(SERIAL_TX_EVENT,bytetime+0.01f); + break; + } + case SERIAL_SERVER_POLLING_EVENT: { + // As long as nothing is connected to out server poll the + // connection. + if((clientsocket=serversocket->Accept())) { + Bit8u peeripbuf[16]; + clientsocket->GetRemoteAddressString(peeripbuf); + LOG_MSG("Serial%d: A client (%s) has connected.",idnumber+1,peeripbuf); + // new socket found... + clientsocket->SetSendBufferSize(256); + setEvent(SERIAL_POLLING_EVENT, 1); + + // we don't accept further connections + delete serversocket; + serversocket=0; + + // transmit the line status + setRTSDTR(getRTS(), getDTR()); + } else { + // continue looking + setEvent(SERIAL_SERVER_POLLING_EVENT, 50); + } + break; + } + case SERIAL_TX_REDUCTION: { + // Flush the data in the transmitting buffer. + if(clientsocket) clientsocket->FlushBuffer(); + tx_block=false; + break; + } + case SERIAL_NULLMODEM_DTR_EVENT: { + if(getDTR()) ClientConnect(); + else setEvent(SERIAL_NULLMODEM_DTR_EVENT,50); + break; + } + } +} + +/*****************************************************************************/ +/* updatePortConfig is called when emulated app changes the serial port **/ +/* parameters baudrate, stopbits, number of databits, parity. **/ +/*****************************************************************************/ +void CNullModem::updatePortConfig (Bit16u divider, Bit8u lcr) { + +} + +void CNullModem::updateMSR () { + +} + +void CNullModem::transmitByte (Bit8u val, bool first) { + + // transmit it later in THR_Event + if(first) { + setEvent(SERIAL_THR_EVENT, bytetime/8); + } + else { + //if(clientsocket) clientsocket->Putchar(val); + setEvent(SERIAL_TX_EVENT, bytetime); + } + /*****************************/ + if(val==0xff) WriteChar(0xff); + + WriteChar(val); +} + +Bits CNullModem::TelnetEmulation(Bit8u data) { + Bit8u response[3]; + if(telClient.inIAC) { + if(telClient.recCommand) { + if((data != 0) && (data != 1) && (data != 3)) { + LOG_MSG("Serial%d: Unrecognized telnet option %d",COMNUMBER, data); + if(telClient.command>250) { + /* Reject anything we don't recognize */ + response[0]=0xff; + response[1]=252; + response[2]=data; /* We won't do crap! */ + if(clientsocket) clientsocket->SendArray(response, 3); + } + } + switch(telClient.command) { + case 251: /* Will */ + if(data == 0) telClient.binary[TEL_SERVER] = true; + if(data == 1) telClient.echo[TEL_SERVER] = true; + if(data == 3) telClient.supressGA[TEL_SERVER] = true; + break; + case 252: /* Won't */ + if(data == 0) telClient.binary[TEL_SERVER] = false; + if(data == 1) telClient.echo[TEL_SERVER] = false; + if(data == 3) telClient.supressGA[TEL_SERVER] = false; + break; + case 253: /* Do */ + if(data == 0) { + telClient.binary[TEL_CLIENT] = true; + response[0]=0xff; + response[1]=251; + response[2]=0; /* Will do binary transfer */ + if(clientsocket) clientsocket->SendArray(response, 3); + } + if(data == 1) { + telClient.echo[TEL_CLIENT] = false; + response[0]=0xff; + response[1]=252; + response[2]=1; /* Won't echo (too lazy) */ + if(clientsocket) clientsocket->SendArray(response, 3); + } + if(data == 3) { + telClient.supressGA[TEL_CLIENT] = true; + response[0]=0xff; + response[1]=251; + response[2]=3; /* Will Suppress GA */ + if(clientsocket) clientsocket->SendArray(response, 3); + } + break; + case 254: /* Don't */ + if(data == 0) { + telClient.binary[TEL_CLIENT] = false; + response[0]=0xff; + response[1]=252; + response[2]=0; /* Won't do binary transfer */ + if(clientsocket) clientsocket->SendArray(response, 3); + } + if(data == 1) { + telClient.echo[TEL_CLIENT] = false; + response[0]=0xff; + response[1]=252; + response[2]=1; /* Won't echo (fine by me) */ + if(clientsocket) clientsocket->SendArray(response, 3); + } + if(data == 3) { + telClient.supressGA[TEL_CLIENT] = true; + response[0]=0xff; + response[1]=251; + response[2]=3; /* Will Suppress GA (too lazy) */ + if(clientsocket) clientsocket->SendArray(response, 3); + } + break; + default: + LOG_MSG("MODEM: Telnet client sent IAC %d", telClient.command); + break; + } + telClient.inIAC = false; + telClient.recCommand = false; + return -1; //continue; + } else { + if(data==249) { + /* Go Ahead received */ + telClient.inIAC = false; + return -1; //continue; + } + telClient.command = data; + telClient.recCommand = true; + + if((telClient.binary[TEL_SERVER]) && (data == 0xff)) { + /* Binary data with value of 255 */ + telClient.inIAC = false; + telClient.recCommand = false; + return 0xff; + } + } + } else { + if(data == 0xff) { + telClient.inIAC = true; + return -1; + } + return data; + } + return -1; // ??? +} + + +/*****************************************************************************/ +/* setBreak(val) switches break on or off **/ +/*****************************************************************************/ + +void CNullModem::setBreak (bool value) { + CNullModem::setRTSDTR(getRTS(), getDTR()); +} + +/*****************************************************************************/ +/* updateModemControlLines(mcr) sets DTR and RTS. **/ +/*****************************************************************************/ +void CNullModem::setRTSDTR(bool xrts, bool xdtr) { + if(!transparent) { + Bit8u control[2]; + control[0]=0xff; + control[1]=0x0; + if(xrts) control[1]|=1; + if(xdtr) control[1]|=2; + if(LCR&LCR_BREAK_MASK) control[1]|=4; + if(clientsocket) clientsocket->SendArray(control, 2); + } +} +void CNullModem::setRTS(bool val) { + setRTSDTR(val, getDTR()); +} +void CNullModem::setDTR(bool val) { + setRTSDTR(getRTS(), val); +} +#endif diff --git a/src/hardware/serialport/nullmodem.h b/src/hardware/serialport/nullmodem.h new file mode 100644 index 00000000..226e1182 --- /dev/null +++ b/src/hardware/serialport/nullmodem.h @@ -0,0 +1,105 @@ +/* + * 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: nullmodem.h,v 1.1 2007-01-13 08:35:49 qbix79 Exp $ */ + +// include guard +#ifndef DOSBOX_NULLMODEM_WIN32_H +#define DOSBOX_NULLMODEM_WIN32_H + +#include "dosbox.h" + +#if C_MODEM + +#include "misc_util.h" +#include "serialport.h" + +#define SERIAL_SERVER_POLLING_EVENT SERIAL_BASE_EVENT_COUNT+1 +#define SERIAL_TX_REDUCTION SERIAL_BASE_EVENT_COUNT+2 +#define SERIAL_NULLMODEM_DTR_EVENT SERIAL_BASE_EVENT_COUNT+3 +#define SERIAL_NULLMODEM_EVENT_COUNT SERIAL_BASE_EVENT_COUNT+ 3 + +class CNullModem : public CSerial { +public: + TCPServerSocket* serversocket; + TCPClientSocket* clientsocket; + + CNullModem(Bitu id, CommandLine* cmd); + ~CNullModem(); + bool receiveblock; // It's not a block of data it rather blocks + Bit16u serverport; // we are a server if this is nonzero + Bit16u clientport; + + Bit8u hostnamebuffer[128]; // the name passed to us by the user + + void updatePortConfig(Bit16u divider, Bit8u lcr); + void updateMSR(); + void transmitByte(Bit8u val, bool first); + void setBreak(bool value); + + void setRTSDTR(bool rts, bool dtr); + void setRTS(bool val); + void setDTR(bool val); + void handleUpperEvent(Bit16u type); + + void ClientConnect(); + void Disconnect(); + Bits readChar(); + void WriteChar(Bit8u data); + + bool tx_block; // true while the SERIAL_TX_REDUCTION event + // is pending + + Bitu rx_retry; // counter of retries + + Bitu rx_retry_max; // how many POLL_EVENTS to wait before causing + // a overrun error. + + Bitu tx_gather; // how long to gather tx data before + // sending all of them [milliseconds] + + + bool dtrrespect; // dtr behavior - only send data to the serial + // port when DTR is on + + bool transparent; // if true, don't send 0xff 0xXX to toggle + // DSR/CTS. + + bool telnet; // Do Telnet parsing. + + // Telnet's brain +#define TEL_CLIENT 0 +#define TEL_SERVER 1 + + Bits TelnetEmulation(Bit8u data); + + // Telnet's memory + struct { + bool binary[2]; + bool echo[2]; + bool supressGA[2]; + bool timingMark[2]; + + bool inIAC; + bool recCommand; + Bit8u command; + } telClient; +}; + +#endif // C_MODEM +#endif // include guard diff --git a/src/hardware/serialport/serialdummy.cpp b/src/hardware/serialport/serialdummy.cpp index 64065974..df8c6d88 100644 --- a/src/hardware/serialport/serialdummy.cpp +++ b/src/hardware/serialport/serialdummy.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialdummy.cpp,v 1.3 2007-01-08 19:45:41 qbix79 Exp $ */ +/* $Id: serialdummy.cpp,v 1.4 2007-01-13 08:35:49 qbix79 Exp $ */ #include "dosbox.h" @@ -24,46 +24,54 @@ #include "serialdummy.h" #include "serialport.h" - -CSerialDummy::CSerialDummy( - IO_ReadHandler* rh, - IO_WriteHandler* wh, - TIMER_TickHandler th, - Bit16u baseAddr, - Bit8u initIrq, - Bit32u initBps, - Bit8u bytesize, - const char* parity, - Bit8u stopbits - ) : CSerial( - rh, wh, th, - baseAddr,initIrq,initBps,bytesize,parity,stopbits) - { - CSerial::Init_Registers(initBps,bytesize,parity,stopbits); - } - -CSerialDummy::~CSerialDummy() { +CSerialDummy::CSerialDummy(Bitu id, CommandLine* cmd):CSerial(id, cmd) { + CSerial::Init_Registers(); + setRI(false); + setDSR(false); + setCD(false); + setCTS(false); + InstallationSuccessful=true; } -void CSerialDummy::RXBufferEmpty() { -// no external buffer, not used here +CSerialDummy::~CSerialDummy() { + // clear events + removeEvent(SERIAL_TX_EVENT); +} + +void CSerialDummy::handleUpperEvent(Bit16u type) { + if(type==SERIAL_TX_EVENT) { + //LOG_MSG("SERIAL_TX_EVENT"); +#ifdef CHECKIT_TESTPLUG + receiveByte(loopbackdata); +#endif + ByteTransmitted(); // tx timeout + } + else if(type==SERIAL_THR_EVENT){ + //LOG_MSG("SERIAL_THR_EVENT"); + ByteTransmitting(); + setEvent(SERIAL_TX_EVENT,bytetime); + } + } /*****************************************************************************/ /* updatePortConfig is called when emulated app changes the serial port **/ /* parameters baudrate, stopbits, number of databits, parity. **/ /*****************************************************************************/ -void CSerialDummy::updatePortConfig(Bit8u dll, Bit8u dlm, Bit8u lcr) { +void CSerialDummy::updatePortConfig(Bit16u divider, Bit8u lcr) { //LOG_MSG("Serial port at 0x%x: Port params changed: %d Baud", base,dcb.BaudRate); } void CSerialDummy::updateMSR() { - changeMSR(0); } +void CSerialDummy::transmitByte(Bit8u val, bool first) { -void CSerialDummy::transmitByte(Bit8u val) { - ByteTransmitted(); - //LOG_MSG("UART 0x%x: TX 0x%x", base,val); + if(first) setEvent(SERIAL_THR_EVENT, bytetime/10); + else setEvent(SERIAL_TX_EVENT, bytetime); + +#ifdef CHECKIT_TESTPLUG + loopbackdata=val; +#endif } /*****************************************************************************/ @@ -75,11 +83,21 @@ void CSerialDummy::setBreak(bool value) { } /*****************************************************************************/ -/* updateModemControlLines(mcr) sets DTR and RTS. **/ +/* setRTSDTR sets the modem control lines **/ /*****************************************************************************/ -void CSerialDummy::updateModemControlLines(/*Bit8u mcr*/) { +void CSerialDummy::setRTSDTR(bool rts, bool dtr) { + setRTS(rts); + setDTR(dtr); +} +void CSerialDummy::setRTS(bool val) { +#ifdef CHECKIT_TESTPLUG + setCTS(val); +#endif +} +void CSerialDummy::setDTR(bool val) { +#ifdef CHECKIT_TESTPLUG + setDSR(val); + setRI(val); + setCD(val); +#endif } - -void CSerialDummy::Timer2(void) { -} - diff --git a/src/hardware/serialport/serialdummy.h b/src/hardware/serialport/serialdummy.h index e339d1b9..95b9d412 100644 --- a/src/hardware/serialport/serialdummy.h +++ b/src/hardware/serialport/serialdummy.h @@ -16,39 +16,34 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialdummy.h,v 1.3 2007-01-08 19:45:41 qbix79 Exp $ */ +/* $Id: serialdummy.h,v 1.4 2007-01-13 08:35:49 qbix79 Exp $ */ #ifndef INCLUDEGUARD_SERIALDUMMY_H #define INCLUDEGUARD_SERIALDUMMY_H #include "serialport.h" +//#define CHECKIT_TESTPLUG + class CSerialDummy : public CSerial { public: - - CSerialDummy( - IO_ReadHandler* rh, - IO_WriteHandler* wh, - TIMER_TickHandler th, - Bit16u baseAddr, - Bit8u initIrq, - Bit32u initBps, - Bit8u bytesize, - const char* parity, - Bit8u stopbits - ); - - + CSerialDummy(Bitu id, CommandLine* cmd); ~CSerialDummy(); - bool CanRecv(void); - bool CanSend(void); - void RXBufferEmpty(); - void updatePortConfig(Bit8u dll, Bit8u dlm, Bit8u lcr); + + void setRTSDTR(bool rts, bool dtr); + void setRTS(bool val); + void setDTR(bool val); + + void updatePortConfig(Bit16u, Bit8u lcr); void updateMSR(); - void transmitByte(Bit8u val); + void transmitByte(Bit8u val, bool first); void setBreak(bool value); - void updateModemControlLines(/*Bit8u mcr*/); - void Timer2(void); + void handleUpperEvent(Bit16u type); + +#ifdef CHECKIT_TESTPLUG + Bit8u loopbackdata; +#endif + }; #endif // INCLUDEGUARD diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index 87bb7f3d..1f5b27df 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -16,270 +16,312 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.cpp,v 1.5 2007-01-08 19:45:41 qbix79 Exp $ */ - +/* $Id: serialport.cpp,v 1.6 2007-01-13 08:35:49 qbix79 Exp $ */ #include #include #include "dosbox.h" -#include "support.h" #include "inout.h" #include "pic.h" #include "setup.h" -#include "timer.h" +#include "bios.h" // SetComPorts(..) +#include "callback.h" // CALLBACK_Idle #include "serialport.h" #include "directserial_win32.h" +#include "directserial_posix.h" #include "directserial_os2.h" #include "serialdummy.h" #include "softmodem.h" +#include "nullmodem.h" + +#include "cpu.h" + + +bool device_COM::Read(Bit8u * data,Bit16u * size) { + // DTR + RTS on + sclass->Write_MCR(0x03); + for (Bit16u i=0; i<*size; i++) + { + if(!(sclass->Getchar(&data[i],true,1000))) { + *size=i; + return true; + } + } + return true; +} + + +bool device_COM::Write(Bit8u * data,Bit16u * size) { + // DTR + RTS on + sclass->Write_MCR(0x03); + for (Bit16u i=0; i<*size; i++) + { + if(!(sclass->Putchar(data[i],true,true,1000))) { + *size=i; + sclass->Write_MCR(0x01); + return false; + } + } + // RTS off + sclass->Write_MCR(0x01); + return true; +} + +bool device_COM::Seek(Bit32u * pos,Bit32u type) { + *pos = 0; + return true; +} + +bool device_COM::Close() { + return false; +} + +Bit16u device_COM::GetInformation(void) { + return 0x80A0; +}; + +device_COM::device_COM(class CSerial* sc) { + sclass = sc; + SetName(serial_comname[sclass->idnumber]); +} + +device_COM::~device_COM() { +} -#define LOG_UART LOG_MSG // COM1 - COM4 objects -static CSerial *serial1 = 0; -static CSerial *serial2 = 0; -static CSerial *serial3 = 0; -static CSerial *serial4 = 0; -//static CSerial** serialPortObjects[] = {NULL, &serial1,&serial2,&serial3,&serial4}; +CSerial* serialports[4] ={0,0,0,0}; -Bit8u serialGetComnumberByBaseAddress (Bit16u base) { - if (base == COM1_BASE) - return 1; - else if (base == COM2_BASE) - return 2; - else if (base == COM3_BASE) - return 3; - else if (base == COM4_BASE) - return 4; - else - return 255; // send thispointer to nirwana ;) -} +static Bitu SERIAL_Read (Bitu port, Bitu iolen) { + for(Bitu i = 0; i < 4; i++) { + if(serial_baseaddr[i]==(port&0xfff8) && (serialports[i]!=0)) { + Bitu retval=0xff; + switch (port & 0x7) { + case RHR_OFFSET: + retval = serialports[i]->Read_RHR(); + break; + case IER_OFFSET: + retval = serialports[i]->Read_IER(); + break; + case ISR_OFFSET: + retval = serialports[i]->Read_ISR(); + break; + case LCR_OFFSET: + retval = serialports[i]->Read_LCR(); + break; + case MCR_OFFSET: + retval = serialports[i]->Read_MCR(); + break; + case LSR_OFFSET: + retval = serialports[i]->Read_LSR(); + break; + case MSR_OFFSET: + retval = serialports[i]->Read_MSR(); + break; + case SPR_OFFSET: + retval = serialports[i]->Read_SPR(); + break; + } -// Usage of FastDelegates (http://www.codeproject.com/cpp/FastDelegate.asp) -// as I/O-Array would make many of these unneccessary. (member function pointer) - -//Some defines for repeated functions - -#define SERIAL_UPDATE(number) \ -void SERIAL##number##_Update(void) { \ - serial##number->Timer (); \ -} - -#define SERIAL_WRITE_TREE(number) \ -static void SERIAL##number##_Write (Bitu port, Bitu val, Bitu iolen) { \ - switch (port & 0x7) { \ - case THR_OFFSET: \ - serial##number ->Write_THR (val); \ - return; \ - case IER_OFFSET: \ - serial##number ->Write_IER (val); \ - return; \ - case LCR_OFFSET: \ - serial##number ->Write_LCR (val); \ - return; \ - case MCR_OFFSET: \ - serial##number ->Write_MCR (val); \ - return; \ - case MSR_OFFSET: \ - serial##number ->Write_MSR (val); \ - return; \ - case SPR_OFFSET: \ - serial##number ->Write_SPR (val); \ - return; \ - default: \ - serial##number ->Write_reserved (val, port & 0x7); \ - } \ -} - -#define SERIAL_READ_TREE(number) \ -static Bitu SERIAL##number##_Read (Bitu port, Bitu iolen) { \ - switch (port & 0x7) { \ - case RHR_OFFSET: \ - return serial##number ->Read_RHR (); \ - case IER_OFFSET: \ - return serial##number ->Read_IER (); \ - case ISR_OFFSET: \ - return serial##number ->Read_ISR (); \ - case LCR_OFFSET: \ - return serial##number ->Read_LCR (); \ - case MCR_OFFSET: \ - return serial##number ->Read_MCR (); \ - case LSR_OFFSET: \ - return serial##number ->Read_LSR (); \ - case MSR_OFFSET: \ - return serial##number ->Read_MSR (); \ - case SPR_OFFSET: \ - return serial##number ->Read_SPR (); \ - } \ - return 0; \ -} - -//The Functions - -SERIAL_UPDATE(1); -SERIAL_UPDATE(2); -SERIAL_UPDATE(3); -SERIAL_UPDATE(4); - -SERIAL_WRITE_TREE(1); -SERIAL_WRITE_TREE(2); -SERIAL_WRITE_TREE(3); -SERIAL_WRITE_TREE(4); - -SERIAL_READ_TREE(1); -SERIAL_READ_TREE(2); -SERIAL_READ_TREE(3); -SERIAL_READ_TREE(4); - -#undef SERIAL_UPDATE -#undef SERIAL_WRITE_TREE -#undef SERIAL_READ_TREE - -void CSerial::Timer (void) { - //LOG_UART("Serial port at %x: Timer", base); - if (loopback_pending) { -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Loopback sent back", base); +#if SERIAL_DEBUG + const char* const dbgtext[]= + {"RHR","IER","ISR","LCR","MCR","LSR","MSR","SPR"}; + if(serialports[i]->dbg_register) + fprintf(serialports[i]->debugfp,"%12.3f read 0x%x from %s.\r\n", + PIC_FullIndex(),retval,dbgtext[port&0x7]); #endif - loopback_pending = false; - receiveByte (loopback_data); - ByteTransmitted (); + + return retval; + } + } + return 0xff; +} +static void SERIAL_Write (Bitu port, Bitu val, Bitu) { + + for(Bitu i = 0; i < 4; i++) { + if(serial_baseaddr[i]==(port&0xfff8) && serialports[i]) { + +#if SERIAL_DEBUG + const char* const dbgtext[]={"THR","IER","FCR","LCR","MCR","!LSR","MSR","SPR"}; + if(serialports[i]->dbg_register) + fprintf(serialports[i]->debugfp,"%12.3f write 0x%x to %s.\r\n", + PIC_FullIndex(),val,dbgtext[port&0x7]); +#endif + + switch (port & 0x7) { + case THR_OFFSET: + serialports[i]->Write_THR (val); + return; + case IER_OFFSET: + serialports[i]->Write_IER (val); + return; + case FCR_OFFSET: + serialports[i]->Write_FCR (val); + return; + case LCR_OFFSET: + serialports[i]->Write_LCR (val); + return; + case MCR_OFFSET: + serialports[i]->Write_MCR (val); + return; + case MSR_OFFSET: + serialports[i]->Write_MSR (val); + return; + case SPR_OFFSET: + serialports[i]->Write_SPR (val); + return; + default: + serialports[i]->Write_reserved (val, port & 0x7); + } + } + } +} + +void CSerial::changeLineProperties() { + // update the event wait time + + float bitlen = (1000.0f/115200.0f)*(float)baud_divider; + bytetime=bitlen*(float)(1+5+1); // startbit + minimum length + stopbit + bytetime+= bitlen*(float)(LCR&0x3); // databits + if(LCR&0x4) bytetime+=bitlen; // stopbit + updatePortConfig (baud_divider, LCR); +} + +static void Serial_EventHandler(Bitu val) { + Bitu serclassid=val&0x3; + if(serialports[serclassid]!=0) + serialports[serclassid]->handleEvent(val>>2); +} + +void CSerial::setEvent(Bit16u type, float duration) { + PIC_AddEvent(Serial_EventHandler,duration,(type<<2)|idnumber); +} + +void CSerial::removeEvent(Bit16u type) { + // TODO + PIC_RemoveSpecificEvents(Serial_EventHandler,(type<<2)|idnumber); +} + +void CSerial::handleEvent(Bit16u type) { + switch(type) { + case SERIAL_TX_LOOPBACK_EVENT: { + +#if SERIAL_DEBUG + if(dbg_serialtraffic) + fprintf(debugfp,loopback_data<0x10? "%12.3f tx 0x%02x (%u) (loopback)\r\n": + "%12.3f tx 0x%02x (%c) (loopback)\r\n", + PIC_FullIndex(),loopback_data, + loopback_data); +#endif + + receiveByte (loopback_data); + ByteTransmitted (); + break; + } + case SERIAL_THR_LOOPBACK_EVENT: { + ByteTransmitting(); + loopback_data=THR; + setEvent(SERIAL_TX_LOOPBACK_EVENT,bytetime); + break; + } + case SERIAL_ERRMSG_EVENT: { + LOG_MSG("Serial%d: Errors occured: "\ + "Framing %d, Parity %d, Overrun %d (IF0:%d), Break %d", COMNUMBER, + framingErrors, parityErrors, overrunErrors, overrunIF0, breakErrors); + errormsg_pending=false; + framingErrors=0; + parityErrors=0; + overrunErrors=0; + overrunIF0=0; + breakErrors=0; + break; + } + default: handleUpperEvent(type); } - Timer2 (); } /*****************************************************************************/ /* Interrupt control routines **/ /*****************************************************************************/ void CSerial::rise (Bit8u priority) { - //LOG_UART("Serial port at %x: Rise priority 0x%x", base, priority); +#if SERIAL_DEBUG + if(dbg_interrupt) + { + if(priority&TX_PRIORITY && !(waiting_interrupts&TX_PRIORITY)) + fprintf(debugfp,"%12.3f tx interrupt on.\r\n",PIC_FullIndex()); + + if(priority&RX_PRIORITY && !(waiting_interrupts&RX_PRIORITY)) + fprintf(debugfp,"%12.3f rx interrupt on.\r\n",PIC_FullIndex()); + + if(priority&MSR_PRIORITY && !(waiting_interrupts&MSR_PRIORITY)) + fprintf(debugfp,"%12.3f msr interrupt on.\r\n",PIC_FullIndex()); + + if(priority&ERROR_PRIORITY && !(waiting_interrupts&ERROR_PRIORITY)) + fprintf(debugfp,"%12.3f error interrupt on.\r\n",PIC_FullIndex()); + } +#endif + waiting_interrupts |= priority; - WriteRealIER (IER); + ComputeInterrupts(); } // clears the pending interrupt, triggers other waiting interrupt void CSerial::clear (Bit8u priority) { - //LOG_UART("Serial port at %x: cleared priority 0x%x", base, priority); + +#if SERIAL_DEBUG + if(dbg_interrupt) + { + if(priority&TX_PRIORITY && (waiting_interrupts&TX_PRIORITY)) + fprintf(debugfp,"%12.3f tx interrupt off.\r\n",PIC_FullIndex()); + + if(priority&RX_PRIORITY && (waiting_interrupts&RX_PRIORITY)) + fprintf(debugfp,"%12.3f rx interrupt off.\r\n",PIC_FullIndex()); + + if(priority&MSR_PRIORITY && (waiting_interrupts&MSR_PRIORITY)) + fprintf(debugfp,"%12.3f msr interrupt off.\r\n",PIC_FullIndex()); + + if(priority&ERROR_PRIORITY && (waiting_interrupts&ERROR_PRIORITY)) + fprintf(debugfp,"%12.3f error interrupt off.\r\n",PIC_FullIndex()); + } +#endif + + waiting_interrupts &= (~priority); - WriteRealIER (IER); + ComputeInterrupts(); } -void CSerial::WriteRealIER (Bit8u data) { -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: write IER, value 0x%x", base, data); +void CSerial::ComputeInterrupts () { + + Bitu val = IER & waiting_interrupts; + + if (val & ERROR_PRIORITY) ISR = ISR_ERROR_VAL; + else if (val & RX_PRIORITY) ISR = ISR_RX_VAL; + else if (val & TX_PRIORITY) ISR = ISR_TX_VAL; + else if (val & MSR_PRIORITY) ISR = ISR_MSR_VAL; + else ISR = ISR_CLEAR_VAL; + + if(val && !irq_active) { + irq_active=true; + PIC_ActivateIRQ(irq); + +#if SERIAL_DEBUG + if(dbg_interrupt) + fprintf(debugfp,"%12.3f IRQ%d on.\r\n",PIC_FullIndex(),irq); #endif - data = data & 0xF; // THE UPPER ONES ALWAYS READ 0! NOTHIN' ELSE! - Bit8u old_pending_interrupts = pending_interrupts; - Bit8u difference_pending_interrupts; + } - // rise TX AGAIN when present and is being enabled - if ((data & TX_PRIORITY) && (!(IER & TX_PRIORITY))) - if (LSR & LSR_TX_HOLDING_EMPTY_MASK) - waiting_interrupts |= TX_PRIORITY; + if(!val && irq_active) { + irq_active=false; + PIC_DeActivateIRQ(irq); - pending_interrupts = waiting_interrupts & data; - if ((difference_pending_interrupts = (pending_interrupts ^ old_pending_interrupts))) { // something in pending interrupts has changed - if (difference_pending_interrupts & pending_interrupts) { // some new bits were set - if (!current_priority) { // activate interrupt.. - if (pending_interrupts & ERROR_PRIORITY) { - current_priority = ERROR_PRIORITY; - ISR = ISR_ERROR_VAL; - } else if (pending_interrupts & RX_PRIORITY) { - current_priority = RX_PRIORITY; - ISR = ISR_RX_VAL; - } else if (pending_interrupts & TX_PRIORITY) { - current_priority = TX_PRIORITY; - ISR = ISR_TX_VAL; - } else if (pending_interrupts & MSR_PRIORITY) { - current_priority = MSR_PRIORITY; - ISR = ISR_MSR_VAL; - } -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Interrupt activated: priority %d", base, current_priority); +#if SERIAL_DEBUG + if(dbg_interrupt) + fprintf(debugfp,"%12.3f IRQ%d off.\r\n",PIC_FullIndex(),irq); #endif - PIC_ActivateIRQ (irq); - }// else the new interrupts were already - // written into pending_interrupts - }// else no new bits were set - - if (difference_pending_interrupts & (~pending_interrupts)) { // some bits were reset - if (pending_interrupts) { // some more are waiting - if (!(current_priority & pending_interrupts)) { // the current interrupt has been cleared - // choose the next one - if (pending_interrupts & ERROR_PRIORITY) { - current_priority = ERROR_PRIORITY; - ISR = ISR_ERROR_VAL; - } else if (pending_interrupts & RX_PRIORITY) { - current_priority = RX_PRIORITY; - ISR = ISR_RX_VAL; - } else if (pending_interrupts & TX_PRIORITY) { - current_priority = TX_PRIORITY; - ISR = ISR_TX_VAL; - } else if (pending_interrupts & MSR_PRIORITY) { - current_priority = MSR_PRIORITY; - ISR = ISR_MSR_VAL; - } - } - } else { - current_priority = NONE_PRIORITY; - ISR = ISR_CLEAR_VAL; - PIC_DeActivateIRQ (irq); -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Interrupt deactivated.", base); -#endif - } - } } - IER = data; -} - - - -/*****************************************************************************/ -/* Internal register modification **/ -/*****************************************************************************/ -void CSerial::changeMSR (Bit8u data) { - if (!(MCR & MCR_LOOPBACK_Enable_MASK)) { - // see if something changed - if ((MSR & MSR_LINE_MASK) != data) { - Bit8u change = (MSR & MSR_LINE_MASK) ^ data; - // set new deltas - MSR |= (change >> 4); - // set new line states - MSR &= MSR_delta_MASK; - MSR |= data; - rise (MSR_PRIORITY); - } - } -} - -void CSerial::changeMSR_Loopback (Bit8u data) { - // see if something changed - if ((MSR & MSR_LINE_MASK) != data) { - Bit8u change = (MSR & MSR_LINE_MASK) ^ data; - // set new deltas - MSR |= (change >> 4); - // set new line states - MSR &= MSR_delta_MASK; - MSR |= data; - rise (MSR_PRIORITY); - } - -/* - Bit8u temp=MSR; - // look for signal changes - if(temp|=((data&MSR_LINE_MASK)^(MSR&MSR_LINE_MASK))>>4) - { // some signals changed - temp&=MSR_delta_MASK;// clear line states - temp|=(data&MSR_LINE_MASK); // set new line states - - MSR=temp; - rise(MSR_PRIORITY); - } - // else nothing happened*/ } /*****************************************************************************/ @@ -293,12 +335,29 @@ bool CSerial::CanReceiveByte() { /* A byte was received **/ /*****************************************************************************/ void CSerial::receiveByte (Bit8u data) { -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: byte received: %d", base, data); + +#if SERIAL_DEBUG + if(dbg_serialtraffic) + fprintf(debugfp,loopback_data<0x10? "%12.3f rx 0x%02x (%u)\r\n": + "%12.3f rx 0x%02x (%c)\r\n", + PIC_FullIndex(), data, data); #endif if (LSR & LSR_RX_DATA_READY_MASK) { // Overrun error ;o - LOG_UART ("Serial port at %x: RX Overrun!", base, data); + if(!errormsg_pending) { + errormsg_pending=true; + setEvent(SERIAL_ERRMSG_EVENT,1000); + } + overrunErrors++; + Bitu iflag= GETFLAG(IF); + if(!iflag)overrunIF0++; + +#if SERIAL_DEBUG + if(dbg_serialtraffic) + fprintf(debugfp, "%12.3f rx overrun (IF=%d)\r\n", + PIC_FullIndex(), iflag); +#endif + LSR |= LSR_OVERRUN_ERROR_MASK; rise (ERROR_PRIORITY); } else { @@ -312,67 +371,166 @@ void CSerial::receiveByte (Bit8u data) { /* A line error was received **/ /*****************************************************************************/ void CSerial::receiveError (Bit8u errorword) { + + if(!errormsg_pending) { + errormsg_pending=true; + setEvent(SERIAL_ERRMSG_EVENT,1000); + } + if(errorword&LSR_PARITY_ERROR_MASK) { + parityErrors++; + +#if SERIAL_DEBUG + if(dbg_serialtraffic) + fprintf(debugfp, "%12.3f parity error\r\n", + PIC_FullIndex()); +#endif + + } + if(errorword&LSR_FRAMING_ERROR_MASK) { + framingErrors++; + +#if SERIAL_DEBUG + if(dbg_serialtraffic) + fprintf(debugfp, "%12.3f framing error\r\n", + PIC_FullIndex()); +#endif + + } + if(errorword&LSR_RX_BREAK_MASK) { + breakErrors++; + +#if SERIAL_DEBUG + if(dbg_serialtraffic) + fprintf(debugfp, "%12.3f break received\r\n", + PIC_FullIndex()); +#endif + + } LSR |= errorword; rise (ERROR_PRIORITY); } +/*****************************************************************************/ +/* ByteTransmitting: Byte has made it from THR to TX. **/ +/*****************************************************************************/ +void CSerial::ByteTransmitting() { + switch(LSR&(LSR_TX_HOLDING_EMPTY_MASK|LSR_TX_EMPTY_MASK)) + { + case LSR_TX_HOLDING_EMPTY_MASK|LSR_TX_EMPTY_MASK: + // bad case there must have been one + case LSR_TX_HOLDING_EMPTY_MASK: + case LSR_TX_EMPTY_MASK: // holding full but workreg empty impossible + LOG_MSG("Internal error in serial port(1)(0x%x).",LSR); + break; + case 0: // THR is empty now. + LSR |= LSR_TX_HOLDING_EMPTY_MASK; + + // trigger interrupt + rise (TX_PRIORITY); + break; + } +} + + /*****************************************************************************/ /* ByteTransmitted: When a byte was sent, notify here. **/ /*****************************************************************************/ void CSerial::ByteTransmitted () { - if (LSR & LSR_TX_HOLDING_EMPTY_MASK) { // one space was empty - // now both are - LSR |= LSR_TX_EMPTY_MASK; - } else { // both were full, now 1 is empty - if (MCR & MCR_LOOPBACK_Enable_MASK) { // loopback mode - transmitLoopbackByte (THR); - } else { // direct "real" mode - transmitByte (THR); - } - LSR |= LSR_TX_HOLDING_EMPTY_MASK; + switch(LSR&(LSR_TX_HOLDING_EMPTY_MASK|LSR_TX_EMPTY_MASK)) + { + case LSR_TX_HOLDING_EMPTY_MASK|LSR_TX_EMPTY_MASK: + // bad case there must have been one + case LSR_TX_EMPTY_MASK: // holding full but workreg empty impossible + LOG_MSG("Internal error in serial port(2)."); + break; + + case LSR_TX_HOLDING_EMPTY_MASK: // now both are empty + LSR |= LSR_TX_EMPTY_MASK; + break; + + case 0: // now one is empty, send the other one + LSR |= LSR_TX_HOLDING_EMPTY_MASK; + if (loopback) { + loopback_data=THR; + setEvent(SERIAL_TX_LOOPBACK_EVENT, bytetime); + } + else { + + #if SERIAL_DEBUG + if(dbg_serialtraffic) + fprintf(debugfp,THR<0x10? "%12.3f tx 0x%02x (%u) (from THR)\r\n": + "%12.3f tx 0x%02x (%c) (from THR)\r\n", + PIC_FullIndex(),THR, + THR); + #endif + + transmitByte(THR,false); + } + // It's ok here. + rise (TX_PRIORITY); + break; } - rise (TX_PRIORITY); } /*****************************************************************************/ /* Transmit Holding Register, also LSB of Divisor Latch (r/w) **/ /*****************************************************************************/ void CSerial::Write_THR (Bit8u data) { + // 0-7 transmit data + if ((LCR & LCR_DIVISOR_Enable_MASK)) { -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Write to DLL value 0x%x", base, data); -#endif // write to DLL - DLL = data; - updatePortConfig (DLL, DLM, LCR); + baud_divider&=0xFF00; + baud_divider |= data; + changeLineProperties(); } else { -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Write to THR value 0x%x", base, data); -#endif - // write to THR clear (TX_PRIORITY); - if (LSR & LSR_TX_HOLDING_EMPTY_MASK) { // one is empty - if (LSR & LSR_TX_EMPTY_MASK) { // both are empty - LSR &= (~LSR_TX_EMPTY_MASK); - - if (MCR & MCR_LOOPBACK_Enable_MASK) { // loopback mode - transmitLoopbackByte (data); - } else { // direct "real" mode - transmitByte (data); - } - rise (TX_PRIORITY); - } else { // only THR is empty; add byte and clear holding bit + switch(LSR&(LSR_TX_HOLDING_EMPTY_MASK|LSR_TX_EMPTY_MASK)) + { + case 0: // both full - overflow +#if SERIAL_DEBUG + if(dbg_serialtraffic) fprintf(debugfp, "%12.3f tx overflow\r\n", + PIC_FullIndex()); +#endif + // overwrite THR + THR = data; + break; + + case LSR_TX_EMPTY_MASK: // holding full but workreg empty impossible + LOG_MSG("Internal error in serial port(3)."); + break; + + case LSR_TX_HOLDING_EMPTY_MASK: // now both are full LSR &= (~LSR_TX_HOLDING_EMPTY_MASK); THR = data; - } - } else { -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: TX Overflow!", base); -#endif - // TX overflow; how does real hardware respond to that... I do nothing + break; + + case LSR_TX_HOLDING_EMPTY_MASK|LSR_TX_EMPTY_MASK: + // both are full until the first delay has passed + THR=data; + LSR &= (~LSR_TX_EMPTY_MASK); + LSR &= (~LSR_TX_HOLDING_EMPTY_MASK); + if(loopback) setEvent(SERIAL_THR_LOOPBACK_EVENT, bytetime/10); + else { + +#if SERIAL_DEBUG + if(dbg_serialtraffic) + fprintf(debugfp,data<0x10? "%12.3f tx 0x%02x (%u)\r\n": + "%12.3f tx 0x%02x (%c)\r\n", + PIC_FullIndex(),data, + data); +#endif + + transmitByte (data,true); + } + + // triggered + // when holding gets empty + // rise (TX_PRIORITY); + break; } } } @@ -382,23 +540,12 @@ void CSerial::Write_THR (Bit8u data) { /* Receive Holding Register, also LSB of Divisor Latch (r/w) **/ /*****************************************************************************/ Bitu CSerial::Read_RHR () { - Bit8u retval; - if ((LCR & LCR_DIVISOR_Enable_MASK)) { -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Read from DLL value 0x%x", base, DLL); -#endif - return DLL; - } else { + // 0-7 received data + if ((LCR & LCR_DIVISOR_Enable_MASK)) return baud_divider&0xff; + else { clear (RX_PRIORITY); LSR &= (~LSR_RX_DATA_READY_MASK); - retval = RHR; - RXBufferEmpty (); // <--- this one changes RHR - -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Read from RHR value 0x%x", base, retval); -#endif - - return retval; + return RHR; } } @@ -408,32 +555,28 @@ Bitu CSerial::Read_RHR () { // Modified by: // - writing to it. Bitu CSerial::Read_IER () { - if ((LCR & LCR_DIVISOR_Enable_MASK)) { // IER or MSB? -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Read from DLM value 0x%x", base, DLM); -#endif - return DLM; - } else { -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Read from IER value 0x%x", base, IER); -#endif - return IER; - } + // 0 receive holding register (byte received) + // 1 transmit holding register (byte sent) + // 2 receive line status (overrun, parity error, frame error, break) + // 3 modem status + // 4-7 0 + + if (LCR & LCR_DIVISOR_Enable_MASK) return baud_divider>>8; + else return IER; } void CSerial::Write_IER (Bit8u data) { if ((LCR & LCR_DIVISOR_Enable_MASK)) { // write to DLM -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Write to DLM value 0x%x", base, data); -#endif - - DLM = data; - updatePortConfig (DLL, DLM, LCR); + baud_divider&=0xff; + baud_divider |= ((Bit16u)data)<<8; + changeLineProperties(); } else { -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Write to IER value 0x%x", base, data); -#endif - WriteRealIER (data); + + IER = data&0xF; + if ((LSR & LSR_TX_HOLDING_EMPTY_MASK) && (IER&TX_PRIORITY)) + waiting_interrupts |= TX_PRIORITY; + + ComputeInterrupts(); } } @@ -444,16 +587,29 @@ void CSerial::Write_IER (Bit8u data) { // - incoming interrupts // - loopback mode Bitu CSerial::Read_ISR () { + // 0 0:interrupt pending 1: no interrupt + // 1-3 identification + // 011 LSR + // 010 RXRDY + // 001 TXRDY + // 000 MSR + // 4-7 0 + + if(IER&Modem_Status_INT_Enable_MASK) updateMSR(); Bit8u retval = ISR; // clear changes ISR!! mean.. - clear (TX_PRIORITY); -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Read from ISR value 0x%x", base, retval); -#endif + if(ISR==ISR_TX_VAL) clear (TX_PRIORITY); return retval; } +void CSerial::Write_FCR (Bit8u data) { + if((!fifo_warn) && (data&0x1)) { + fifo_warn=true; + LOG_MSG("Serial%d: Warning: Tried to activate FIFO.",COMNUMBER); + } +} + /*****************************************************************************/ /* Line Control Register (r/w) **/ /*****************************************************************************/ @@ -464,39 +620,31 @@ Bitu CSerial::Read_ISR () { // Modified by: // - writing to it. Bitu CSerial::Read_LCR () { -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Read from LCR value 0x%x", base, LCR); -#endif + // 0-1 word length + // 2 stop bits + // 3 parity enable + // 4-5 parity type + // 6 set break + // 7 divisor latch enable return LCR; } void CSerial::Write_LCR (Bit8u data) { Bit8u lcr_old = LCR; LCR = data; -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Write to LCR value 0x%x", base, data); - - // for debug output - if (((data ^ lcr_old) & LCR_DIVISOR_Enable_MASK) != 0) { - if ((data & LCR_DIVISOR_Enable_MASK) != 0) - LOG_UART ("Serial port at %x: Divisor-mode entered", base); - - else - LOG_UART ("Serial port at %x: Divisor-mode exited", base); - } -#endif if (((data ^ lcr_old) & LCR_PORTCONFIG_MASK) != 0) { -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: comm parameters changed", base); -#endif - updatePortConfig (DLL, DLM, LCR); + changeLineProperties(); } if (((data ^ lcr_old) & LCR_BREAK_MASK) != 0) { - setBreak ((LCR & LCR_BREAK_MASK) != 0); - -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: break toggled: %d", base, - (LCR & LCR_BREAK_MASK) != 0); + if(!loopback) setBreak ((LCR & LCR_BREAK_MASK)!=0); + else { + // TODO: set loopback break event to reveiveError after + } +#if SERIAL_DEBUG + if(dbg_serialtraffic) + fprintf(debugfp,((LCR & LCR_BREAK_MASK)!=0)? + "%12.3f break on.\r\n": + "%12.3f break off.\r\n", PIC_FullIndex()); #endif } } @@ -508,66 +656,99 @@ void CSerial::Write_LCR (Bit8u data) { // Modified by: // - writing to it. Bitu CSerial::Read_MCR () { -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Read from MCR value 0x%x", base, MCR); -#endif - return MCR; + // 0 -DTR + // 1 -RTS + // 2 -OP1 + // 3 -OP2 + // 4 loopback enable + // 5-7 0 + Bit8u retval=0; + if(dtr) retval|=MCR_DTR_MASK; + if(rts) retval|=MCR_RTS_MASK; + if(op1) retval|=MCR_OP1_MASK; + if(op2) retval|=MCR_OP2_MASK; + if(loopback) retval|=MCR_LOOPBACK_Enable_MASK; + return retval; } void CSerial::Write_MCR (Bit8u data) { -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Write to MCR value 0x%x", base, data); -#endif - data &= 0x1F; // UPPER BITS ALWAYS 0!!! + // WARNING: At the time setRTSDTR is called rts and dsr members are still wrong. - if (MCR & MCR_LOOPBACK_Enable_MASK) - if (data & MCR_LOOPBACK_Enable_MASK) { // was on, is now on - Bit8u param = 0; + bool temp_dtr = data & MCR_DTR_MASK? true:false; + bool temp_rts = data & MCR_RTS_MASK? true:false; + bool temp_op1 = data & MCR_OP1_MASK? true:false; + bool temp_op2 = data & MCR_OP2_MASK? true:false; + bool temp_loopback = data & MCR_LOOPBACK_Enable_MASK? true:false; + if(loopback!=temp_loopback) { + if(temp_loopback) setRTSDTR(false,false); + else setRTSDTR(temp_rts,temp_dtr); + } - // RTS->CD - // DTR->RI - // OP1->DSR - // OP2->CTS - - if (data & MCR_RTS_MASK) - param |= MSR_CD_MASK; - if (data & MCR_DTR_MASK) - param |= MSR_RI_MASK; - if (data & MCR_OP1_MASK) - param |= MSR_DSR_MASK; - if (data & MCR_OP2_MASK) - param |= MSR_CTS_MASK; - - changeMSR_Loopback (param); - - } else { - MCR = data; - updateModemControlLines (); - // is switched off now + if (temp_loopback) { // is on: + // DTR->DSR + // RTS->CTS + // OP1->RI + // OP2->CD + if(temp_dtr!=dtr && !d_dsr) { + d_dsr=true; + rise (MSR_PRIORITY); + } + if(temp_rts!=rts && !d_cts) { + d_cts=true; + rise (MSR_PRIORITY); + } + if(temp_op1!=op1 && !d_ri) { + // interrupt only at trailing edge + if(!temp_op1) { + d_ri=true; + rise (MSR_PRIORITY); + } + } + if(temp_op2!=op2 && !d_cd) { + d_cd=true; + rise (MSR_PRIORITY); + } } else { - if (data & MCR_LOOPBACK_Enable_MASK) { // is switched on: - Bit8u par = 0; - if (data & MCR_RTS_MASK) - par |= MSR_CD_MASK; - if (data & MCR_DTR_MASK) - par |= MSR_RI_MASK; - if (data & MCR_OP1_MASK) - par |= MSR_DSR_MASK; - if (data & MCR_OP2_MASK) - par |= MSR_CTS_MASK; + // loopback is off + if(temp_rts!=rts) { + // RTS difference + if(temp_dtr!=dtr) { + // both difference - changeMSR_Loopback (par); +#if SERIAL_DEBUG + if(dbg_modemcontrol) + { + fprintf(debugfp,temp_rts?"%12.3f RTS on.\r\n": + "%12.3f RTS off.\r\n", PIC_FullIndex()); + fprintf(debugfp,temp_dtr?"%12.3f DTR on.\r\n": + "%12.3f DTR off.\r\n", PIC_FullIndex()); + } +#endif + setRTSDTR(temp_rts, temp_dtr); + } else { + // only RTS - // go back to empty state - LSR &= (LSR_TX_EMPTY_MASK | LSR_TX_HOLDING_EMPTY_MASK); +#if SERIAL_DEBUG + if(dbg_modemcontrol) + fprintf(debugfp,temp_rts?"%12.3f RTS on.\r\n":"%12.3f RTS off.\r\n", PIC_FullIndex()); +#endif - } else { - MCR = data; - updateModemControlLines (); - // loopback is off + setRTS(temp_rts); + } + } else if(temp_dtr!=dtr) { + // only DTR +#if SERIAL_DEBUG + if(dbg_modemcontrol) + fprintf(debugfp,temp_dtr?"%12.3f DTR on.\r\n":"%12.3f DTR off.\r\n", PIC_FullIndex()); +#endif + setDTR(temp_dtr); } } - MCR = data; + dtr=temp_dtr; + rts=temp_rts; + op1=temp_op1; + op2=temp_op2; + loopback=temp_loopback; } /*****************************************************************************/ @@ -581,19 +762,14 @@ Bitu CSerial::Read_LSR () { Bitu retval = LSR; LSR &= (~LSR_ERROR_MASK); // clear error bits on read clear (ERROR_PRIORITY); - -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Read from LSR value 0x%x", base, retval); -#endif return retval; } void CSerial::Write_MSR (Bit8u val) { -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Write to MSR, value 0x%x", base, val); -#endif - MSR &= MSR_LINE_MASK; - MSR |= val & MSR_delta_MASK; + d_cts = (val&MSR_dCTS_MASK)?true:false; + d_dsr = (val&MSR_dDSR_MASK)?true:false; + d_cd = (val&MSR_dCD_MASK)?true:false; + d_ri = (val&MSR_dRI_MASK)?true:false; } /*****************************************************************************/ @@ -605,17 +781,36 @@ void CSerial::Write_MSR (Bit8u val) { // - real values // - write operation to MCR in loopback mode Bitu CSerial::Read_MSR () { - Bit8u retval; - if (!(MCR & MCR_LOOPBACK_Enable_MASK)) { - updateMSR (); + Bit8u retval=0; + + if (loopback) { + + if (rts) retval |= MSR_CTS_MASK; + if (dtr) retval |= MSR_DSR_MASK; + if (op1) retval |= MSR_RI_MASK; + if (op2) retval |= MSR_CD_MASK; + + } else { + + updateMSR(); + if (cd) retval |= MSR_CD_MASK; + if (ri) retval |= MSR_RI_MASK; + if (dsr) retval |= MSR_DSR_MASK; + if (cts) retval |= MSR_CTS_MASK; + } - retval = MSR; + // new delta flags + if(d_cd) retval|=MSR_dCD_MASK; + if(d_ri) retval|=MSR_dRI_MASK; + if(d_cts) retval|=MSR_dCTS_MASK; + if(d_dsr) retval|=MSR_dDSR_MASK; + + d_cd = false; + d_ri = false; + d_cts = false; + d_dsr = false; + clear (MSR_PRIORITY); - // clear deltas - MSR &= MSR_LINE_MASK; -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Read from MSR value 0x%x", base, retval); -#endif return retval; } @@ -624,16 +819,10 @@ Bitu CSerial::Read_MSR () { /*****************************************************************************/ // Just a memory register. Not much to do here. Bitu CSerial::Read_SPR () { -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Read from SPR value 0x%x", base, SPR); -#endif return SPR; } void CSerial::Write_SPR (Bit8u data) { -#ifdef SERIALPORT_DEBUGMSG - LOG_UART ("Serial port at %x: Write to SPR value 0x%x", base, data); -#endif SPR = data; } @@ -641,96 +830,100 @@ void CSerial::Write_SPR (Bit8u data) { /* Write_reserved **/ /*****************************************************************************/ void CSerial::Write_reserved (Bit8u data, Bit8u address) { - LOG_UART("Serial port at %x: Write to reserved register, value 0x%x, register %x", base, data, address); -} - -/*****************************************************************************/ -/* Loopback: add byte to loopback buffer; it is received next time Timer **/ -/* function is invoked; (time needed is not emulated correctly, but I don't **/ -/* think this is sooooo important....) **/ -/*****************************************************************************/ -void CSerial::transmitLoopbackByte (Bit8u val) { - //LOG_MSG("Serial port at %x: Loopback requested", base); - loopback_pending = true; - loopback_data = val; + /*LOG_UART("Serial%d: Write to reserved register, value 0x%x, register %x", + COMNUMBER, data, address);*/ } /*****************************************************************************/ /* MCR Access: returns cirquit state as boolean. **/ /*****************************************************************************/ bool CSerial::getDTR () { - return (MCR & MCR_DTR_MASK) != 0; + if(loopback) return false; + else return dtr; } bool CSerial::getRTS () { - return (MCR & MCR_RTS_MASK) != 0; + if(loopback) return false; + else return rts; } /*****************************************************************************/ /* MSR Access **/ /*****************************************************************************/ bool CSerial::getRI () { - return (MSR & MSR_RI_MASK) != 0; + return ri; } bool CSerial::getCD () { - return (MSR & MSR_CD_MASK) != 0; + return cd; } bool CSerial::getDSR () { - return (MSR & MSR_DSR_MASK) != 0; + return dsr; } bool CSerial::getCTS () { - return (MSR & MSR_CTS_MASK) != 0; + return cts; } -// these give errors if invoked while loopback mode... but who cares. void CSerial::setRI (bool value) { - bool compare = ((MSR & MSR_RI_MASK) != 0); - if (value != compare) { - if (value) - MSR |= MSR_RI_MASK; - else - MSR &= (~MSR_RI_MASK); - MSR |= MSR_dRI_MASK; - rise (MSR_PRIORITY); + if (value != ri) { + +#if SERIAL_DEBUG + if(dbg_modemcontrol) + fprintf(debugfp,value?"%12.3f RI on.\r\n":"%12.3f RI off.\r\n", PIC_FullIndex()); +#endif + // don't change delta when in loopback mode + ri=value; + if(!loopback) { + if(value==false) d_ri=true; + rise (MSR_PRIORITY); + } } //else no change } void CSerial::setDSR (bool value) { - bool compare = ((MSR & MSR_DSR_MASK) != 0); - if (value != compare) { - if (value) - MSR |= MSR_DSR_MASK; - else - MSR &= (~MSR_DSR_MASK); - MSR |= MSR_dDSR_MASK; - rise (MSR_PRIORITY); + if (value != dsr) { +#if SERIAL_DEBUG + if(dbg_modemcontrol) + fprintf(debugfp,value?"%12.3f DSR on.\r\n":"%12.3f DSR off.\r\n", PIC_FullIndex()); +#endif + // don't change delta when in loopback mode + dsr=value; + if(!loopback) { + d_dsr=true; + rise (MSR_PRIORITY); + } } //else no change } void CSerial::setCD (bool value) { - bool compare = ((MSR & MSR_CD_MASK) != 0); - if (value != compare) { - if (value) - MSR |= MSR_CD_MASK; - else - MSR &= (~MSR_CD_MASK); - MSR |= MSR_dCD_MASK; - rise (MSR_PRIORITY); + if (value != cd) { +#if SERIAL_DEBUG + if(dbg_modemcontrol) + fprintf(debugfp,value?"%12.3f CD on.\r\n":"%12.3f CD off.\r\n", PIC_FullIndex()); +#endif + // don't change delta when in loopback mode + cd=value; + if(!loopback) { + d_cd=true; + rise (MSR_PRIORITY); + } } //else no change } void CSerial::setCTS (bool value) { - bool compare = ((MSR & MSR_CTS_MASK) != 0); - if (value != compare) { - if (value) - MSR |= MSR_CTS_MASK; - else - MSR &= (~MSR_CTS_MASK); - MSR |= MSR_dCTS_MASK; - rise (MSR_PRIORITY); + if (value != cts) { +#if SERIAL_DEBUG + if(dbg_modemcontrol) + fprintf(debugfp,value?"%12.3f CTS on.\r\n":"%12.3f CTS off.\r\n", PIC_FullIndex()); +#endif + // don't change delta when in loopback mode + cts=value; + if(!loopback) { + d_cts=true; + rise (MSR_PRIORITY); + } } //else no change } @@ -738,8 +931,16 @@ void CSerial::setCTS (bool value) { /*****************************************************************************/ /* Initialisation **/ /*****************************************************************************/ -void CSerial::Init_Registers (Bit32u initbps, Bit8u bytesize, - const char *parity, Bit8u stopbits) { +void CSerial::Init_Registers () { + // The "power on" settings + irq_active=false; + waiting_interrupts = 0x0; + + Bit32u initbps = 9600; + Bit8u bytesize = 8; + char parity = 'N'; + Bit8u stopbits = 1; + Bit8u lcrresult = 0; Bit16u baudresult = 0; @@ -748,20 +949,27 @@ void CSerial::Init_Registers (Bit32u initbps, Bit8u bytesize, IER = 0; ISR = 0x1; LCR = 0; - MCR = 0; + //MCR = 0xff; + loopback; + dtr=true; + rts=true; + op1=true; + op2=true; + + LSR = 0x60; - MSR = 0; + d_cts = true; + d_dsr = true; + d_ri = true; + d_cd = true; + cts = true; + dsr = true; + ri = true; + cd = true; SPR = 0xFF; - DLL = 0x0; - DLM = 0x0; - - pending_interrupts = 0x0; - current_priority = 0x0; - waiting_interrupts = 0x0; - loopback_pending = false; - + baud_divider=0x0; // make lcr: byte size, parity, stopbits, baudrate @@ -774,313 +982,259 @@ void CSerial::Init_Registers (Bit32u initbps, Bit8u bytesize, else lcrresult |= LCR_DATABITS_8; - if (parity[0] == 'O' || parity[0] == 'o') - lcrresult |= LCR_PARITY_ODD; - else if (parity[0] == 'E' || parity[0] == 'e') - lcrresult |= LCR_PARITY_EVEN; - else if (parity[0] == 'M' || parity[0] == 'm') - lcrresult |= LCR_PARITY_MARK; - else if (parity[0] == 'S' || parity[0] == 's') - lcrresult |= LCR_PARITY_SPACE; - else + switch(parity) + { + case 'N': + case 'n': lcrresult |= LCR_PARITY_NONE; - - if (stopbits == 2) - lcrresult |= LCR_STOPBITS_MORE_THAN_1; - else - lcrresult |= LCR_STOPBITS_1; + break; + case 'O': + case 'o': + lcrresult |= LCR_PARITY_ODD; + break; + case 'E': + case 'e': + lcrresult |= LCR_PARITY_EVEN; + break; + case 'M': + case 'm': + lcrresult |= LCR_PARITY_MARK; + break; + case 'S': + case 's': + lcrresult |= LCR_PARITY_SPACE; + break; + } // baudrate - if (initbps > 0) baudresult = (Bit16u) (115200 / initbps); else baudresult = 12; // = 9600 baud + Write_MCR (0); Write_LCR (LCR_DIVISOR_Enable_MASK); Write_THR ((Bit8u) baudresult & 0xff); Write_IER ((Bit8u) (baudresult >> 8)); Write_LCR (lcrresult); + updateMSR(); + Read_MSR(); } -CSerial::CSerial(IO_ReadHandler * rh, IO_WriteHandler * wh, TIMER_TickHandler, - Bit16u initbase, Bit8u initirq, Bit32u initbps, Bit8u bytesize, - const char *parity, Bit8u stopbits) { - base = initbase; - irq = initirq; - TimerHnd = NULL; - //TimerHnd = th; // for destructor - //TIMER_AddTickHandler(TimerHnd); +CSerial::CSerial(Bitu id, CommandLine* cmd) { + +#if SERIAL_DEBUG + dbg_serialtraffic = cmd->FindExist("dbgtr", false); + dbg_modemcontrol = cmd->FindExist("dbgmd", false); + dbg_register = cmd->FindExist("dbgreg", false); + dbg_interrupt = cmd->FindExist("dbgirq", false); + dbg_aux = cmd->FindExist("dbgaux", false); + + + if(dbg_serialtraffic|dbg_modemcontrol|dbg_register|dbg_interrupt|dbg_aux) + debugfp=OpenCaptureFile("serlog",".serlog.txt"); + else debugfp=0; + +#endif + + + + idnumber=id; + mydosdevice=new device_COM(this); + DOS_AddDevice(mydosdevice); + Bit16u base = serial_baseaddr[id]; + fifo_warn=false; + + errormsg_pending=false; + framingErrors=0; + parityErrors=0; + overrunErrors=0; + overrunIF0=0; + breakErrors=0; + + // find the IRQ + irq = serial_defaultirq[id]; + getBituSubstring("irq:",&irq, cmd); + if (irq < 2 || irq > 15) irq = serial_defaultirq[id]; + for (Bitu i = 0; i <= 7; i++) { - WriteHandler[i].Install (i + base, wh, IO_MB); - ReadHandler[i].Install (i + base, rh, IO_MB); + WriteHandler[i].Install (i + base, SERIAL_Write, IO_MB); + ReadHandler[i].Install (i + base, SERIAL_Read, IO_MB); } + +#if SERIAL_DEBUG + if(debugfp) fprintf(debugfp,"COM%d: BASE %3x, IRQ %d\r\n\r\n", + COMNUMBER,base,irq); +#endif }; +bool CSerial::getBituSubstring(const char* name,Bitu* data, CommandLine* cmd) { + std::string tmpstring; + if(!(cmd->FindStringBegin(name,tmpstring,false))) return false; + const char* tmpchar=tmpstring.c_str(); + if(sscanf(tmpchar,"%u",data)!=1) return false; + return true; +} + CSerial::~CSerial(void) { - - if(TimerHnd) TIMER_DelTickHandler(TimerHnd); + DOS_DelDevice(mydosdevice); + for(Bitu i = 0; i <= SERIAL_BASE_EVENT_COUNT; i++) + removeEvent(i); }; - -void CSerial::InstallTimerHandler(TIMER_TickHandler th) -{ - if(TimerHnd==NULL) { - TimerHnd=th; - TIMER_AddTickHandler(th); - } -} - -bool getParameter(char *input, char *buffer, const char *parametername, - Bitu buffersize) { - Bitu outputPos = 0; - Bitu currentState = 0; // 0 = before '=' 1 = after '=' 2 = in word - Bitu startInputPos; - Bitu inputPos; - char *res1 = strstr(input, parametername); - if (res1 == 0) - return false; - inputPos = res1 - input; - inputPos += strlen (parametername); - startInputPos = inputPos; - while (input[inputPos] != 0 && outputPos + 2 < buffersize) { - if (currentState == 0) { - if (input[inputPos] == ' ') - inputPos++; - else if (input[inputPos] == ':') { - currentState = 1; - inputPos++; - } else - return false; - } else if (currentState == 1) { - if (input[inputPos] == ' ') - inputPos++; - else { - currentState = 2; - buffer[outputPos] = input[inputPos]; - outputPos++; - inputPos++; - } - - } else { - if (input[inputPos] == ' ') { - buffer[outputPos] = 0; - return true; - } else { - buffer[outputPos] = input[inputPos]; - outputPos++; - inputPos++; - } - } - } - buffer[outputPos] = 0; - if (inputPos == startInputPos) - return false; - return true; -} - -// functions for parsing the config line -bool scanNumber (char *scan, Bitu * retval) { - *retval = 0; - - while (char c = *scan) { - if (c >= '0' && c <= '9') { - *retval *= 10; - *retval += c - '0'; - scan++; - } else +bool CSerial::Getchar(Bit8u* data, bool wait_dsr, Bitu timeout) { + + double starttime=PIC_FullIndex(); + // wait for it to become empty + // wait for DSR on + if(wait_dsr) { + while((!(Read_MSR()&0x20))&&(starttime>PIC_FullIndex()-timeout)) + CALLBACK_Idle(); + if(!(starttime>PIC_FullIndex()-timeout)) { + #if SERIAL_DEBUG +if(dbg_aux) + fprintf(debugfp,"%12.3f API read timeout: MSR 0x%x\r\n", PIC_FullIndex(),Read_MSR()); +#endif return false; + } } + // wait for a byte to arrive + while((!(Read_LSR()&0x1))&&(starttime>PIC_FullIndex()-timeout)) + CALLBACK_Idle(); + + if(!(starttime>PIC_FullIndex()-timeout)) { + #if SERIAL_DEBUG +if(dbg_aux) + fprintf(debugfp,"%12.3f API read timeout: MSR 0x%x\r\n", PIC_FullIndex(),Read_MSR()); +#endif + return false; + } + + + *data=Read_RHR(); + +#if SERIAL_DEBUG + if(dbg_aux) + fprintf(debugfp,"%12.3f API read success: 0x%x\r\n", PIC_FullIndex(),*data); +#endif + return true; } -bool getFirstWord (char *input, char *buffer, Bitu buffersize) { - Bitu outputPointer = 0; - Bitu currentState = 0; // 0 = scanning spaces 1 = in word - Bitu currentPos = 0; - while (input[currentPos] != 0 && outputPointer + 2 < buffersize) { - if (currentState == 0) { - if (input[currentPos] != ' ') { - currentState = 1; - buffer[outputPointer] = input[currentPos]; - outputPointer++; - } - } else { - if (input[currentPos] == ' ') { - buffer[outputPointer] = 0; - return true; - } else { - buffer[outputPointer] = input[currentPos]; - outputPointer++; - } - } - currentPos++; - } - buffer[outputPointer] = 0; // end of string - if (currentState == 0) - return false; - else - return true; -} -void BIOS_SetComPorts (Bit16u baseaddr[]); +bool CSerial::Putchar(Bit8u data, bool wait_dsr, bool wait_cts, Bitu timeout) { + + double starttime=PIC_FullIndex(); + //Bit16u starttime= + // wait for it to become empty + while(!(LSR&0x20)) { + CALLBACK_Idle(); + } + // wait for DSR+CTS on + if(wait_dsr||wait_cts) { + if(wait_dsr||wait_cts) { + while(((Read_MSR()&0x30)!=0x30)&&(starttime>PIC_FullIndex()-timeout)) + CALLBACK_Idle(); + } else if(wait_dsr) { + while(!(Read_MSR()&0x20)&&(starttime>PIC_FullIndex()-timeout)) + CALLBACK_Idle(); + } else if(wait_cts) { + while(!(Read_MSR()&0x10)&&(starttime>PIC_FullIndex()-timeout)) + CALLBACK_Idle(); + + } + if(!(starttime>PIC_FullIndex()-timeout)) { +#if SERIAL_DEBUG + if(dbg_aux) + fprintf(debugfp,"%12.3f API write timeout: MSR 0x%x\r\n", + PIC_FullIndex(),Read_MSR()); +#endif + return false; + } + } + Write_THR(data); + +#if SERIAL_DEBUG + if(dbg_aux) + fprintf(debugfp,"%12.3f API write success: 0x%x\r\n", PIC_FullIndex(),data); +#endif + + return true; +} class SERIALPORTS:public Module_base { public: - CSerial ** serialPortObjects[4]; SERIALPORTS (Section * configuration):Module_base (configuration) { - // put handlers into arrays - IO_ReadHandler *serialReadHandlers[] = { - &SERIAL1_Read, &SERIAL2_Read, &SERIAL3_Read, &SERIAL4_Read - }; - IO_WriteHandler *serialWriteHandlers[] = { - &SERIAL1_Write, &SERIAL2_Write, &SERIAL3_Write, &SERIAL4_Write - }; - TIMER_TickHandler serialTimerHandlers[] = { - &SERIAL1_Update, &SERIAL2_Update, &SERIAL3_Update, &SERIAL4_Update - }; - - // default ports & interrupts - Bit16u addresses[] = { COM1_BASE, COM2_BASE, COM3_BASE, COM4_BASE }; - Bit8u defaultirq[] = { 4, 3, 4, 3 }; + Bit16u biosParameter[4] = { 0, 0, 0, 0 }; Section_prop *section = static_cast (configuration); - char tmpbuffer[15]; - const char *configstringsconst[4] = { + const char *configstrings[4] = { section->Get_string ("serial1"), section->Get_string ("serial2"), section->Get_string ("serial3"), section->Get_string ("serial4") }; - /* Create copies so they can be modified */ - char *configstrings[4] = { 0 }; - for(Bitu i = 0;i < 4;i++) { - size_t len = strlen(configstringsconst[i]); - configstrings[i] = new char[len+1]; - strcpy(configstrings[i],configstringsconst[i]); - configstrings[i] = upcase(configstrings[i]); - } - - serialPortObjects[0] = &serial1; - serialPortObjects[1] = &serial2; - serialPortObjects[2] = &serial3; - serialPortObjects[3] = &serial4; - // iterate through all 4 com ports for (Bitu i = 0; i < 4; i++) { - Bit16u baseAddress = addresses[i]; - Bitu irq = defaultirq[i]; - Bitu bps = 9600; - Bitu bytesize = 8; - Bitu stopbits = 1; - char parity = 'N'; - biosParameter[i] = baseAddress; + biosParameter[i] = serial_baseaddr[i]; - // parameter: irq - if (getParameter(configstrings[i], tmpbuffer, "IRQ", sizeof (tmpbuffer))) { - if (scanNumber (tmpbuffer, &irq)) { - if (irq < 0 || irq == 2 || irq > 15) - irq = defaultirq[i]; - } else - irq = defaultirq[i]; + CommandLine* cmd; + std::string str; + cmd=new CommandLine(0,configstrings[i]); + cmd->FindCommand(1,str); + + if(!str.compare("dummy")) { + serialports[i] = new CSerialDummy (i, cmd); } - // parameter: bps - if (getParameter(configstrings[i], tmpbuffer, "STARTBPS", sizeof (tmpbuffer))) { - if (scanNumber (tmpbuffer, &bps)) { - if (bps <= 0) - bps = 9600; - } else - bps = 9600; - } - // parameter: bytesize - if (getParameter(configstrings[i], tmpbuffer, "BYTESIZE", sizeof (tmpbuffer))) { - if (scanNumber (tmpbuffer, &bytesize)) { - if (bytesize < 5 || bytesize > 8) - bytesize = 8; - } else - bytesize = 8; - } - // parameter: stopbits - if (getParameter(configstrings[i], tmpbuffer, "STOPBITS", sizeof (tmpbuffer))) { - if (scanNumber (tmpbuffer, &stopbits)) { - if (stopbits < 1 || stopbits > 2) - stopbits = 1; - } else - stopbits = 1; - } - // parameter: parity - if (getParameter(configstrings[i], tmpbuffer, "PARITY", sizeof (tmpbuffer))) { - if (!(tmpbuffer[0] == 'N' || tmpbuffer[0] == 'O' || tmpbuffer[0] == 'E' - || tmpbuffer[0] == 'M' || tmpbuffer[0] == 'S')) - tmpbuffer[0] = 'N'; - parity = tmpbuffer[0]; - } - //LOG_MSG("COM%d: %s",i+1,configstrings[i]); - if (getFirstWord (configstrings[i], tmpbuffer, sizeof (tmpbuffer))) { - //LOG_MSG("COM%d: %s",i+1,tmpbuffer); - if (!strcmp (tmpbuffer, "DUMMY")) { - *serialPortObjects[i] = new CSerialDummy (serialReadHandlers[i], serialWriteHandlers[i],serialTimerHandlers[i], baseAddress, irq, bps,bytesize, &parity, stopbits); - } #ifdef DIRECTSERIAL_AVAILIBLE - else if (!strcmp (tmpbuffer, "DIRECTSERIAL")) { - // parameter: realport - if (getParameter (configstrings[i], tmpbuffer, "REALPORT", sizeof (tmpbuffer))) { // realport is required - CDirectSerial *cdstemp = new CDirectSerial (serialReadHandlers[i], serialWriteHandlers[i], serialTimerHandlers[i], baseAddress, irq, bps,bytesize, &parity,stopbits,tmpbuffer); - - if (cdstemp->InstallationSuccessful) { - *serialPortObjects[i] = cdstemp; - } else { // serial port name was wrong or already in use - delete cdstemp; - *serialPortObjects[i] = NULL; - biosParameter[i] = 0; - } - - } else { - *serialPortObjects[i] = NULL; - biosParameter[i] = 0; - } + else if(!str.compare("directserial")) { + serialports[i] = new CDirectSerial (i, cmd); + if (!serialports[i]->InstallationSuccessful) { + // serial port name was wrong or already in use + delete serialports[i]; + serialports[i] = NULL; + biosParameter[i] = 0; } + } #endif + #if C_MODEM - else if (!strcmp (tmpbuffer, "MODEM")) { - Bitu listenport = 23; - // parameter: listenport - if (getParameter(configstrings[i], tmpbuffer, "LISTENPORT", sizeof (tmpbuffer))) { - if (scanNumber (tmpbuffer, &listenport)) { - if (listenport <= 0 || listenport > 65535) - listenport = 23; - } else - listenport = 23; - } - - *serialPortObjects[i] = new CSerialModem (serialReadHandlers[i], serialWriteHandlers[i], serialTimerHandlers[i], baseAddress, irq, bps,bytesize, &parity, stopbits, 0, listenport); + else if(!str.compare("modem")) { + serialports[i] = new CSerialModem (i, cmd); + if (!serialports[i]->InstallationSuccessful) { + delete serialports[i]; + serialports[i] = NULL; + biosParameter[i] = 0; } + } + else if(!str.compare("nullmodem")) { + serialports[i] = new CNullModem (i, cmd); + if (!serialports[i]->InstallationSuccessful) { + delete serialports[i]; + serialports[i] = NULL; + biosParameter[i] = 0; + } + } #endif - else if (!strcmp (tmpbuffer, "DISABLED")) { - *serialPortObjects[i] = NULL; - biosParameter[i] = 0; - } else { - LOG_MSG ("Invalid type for COM%d.", i + 1); - *serialPortObjects[i] = NULL; - biosParameter[i] = 0; - } + else if(!str.compare("disabled")) { + serialports[i] = NULL; + biosParameter[i] = 0; } else { - *serialPortObjects[i] = NULL; + LOG_MSG ("Invalid type for COM%d.", i + 1); + serialports[i] = NULL; biosParameter[i] = 0; } - } - - delete [] configstrings[0];delete [] configstrings[1]; - delete [] configstrings[2];delete [] configstrings[3]; + delete cmd; + } // for BIOS_SetComPorts (biosParameter); } ~SERIALPORTS () { for (Bitu i = 0; i < 4; i++) - if (*serialPortObjects[i]) { - delete *(serialPortObjects[i]); - *(serialPortObjects[i]) = 0; + if (serialports[i]) { + delete serialports[i]; + serialports[i] = 0; } } }; diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index 541ed436..112a0cfe 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.cpp,v 1.6 2007-01-08 19:45:41 qbix79 Exp $ */ +/* $Id: softmodem.cpp,v 1.7 2007-01-13 08:35:49 qbix79 Exp $ */ #include "dosbox.h" @@ -26,90 +26,88 @@ #include #include -#include "SDL_net.h" - #include "support.h" -#include "timer.h" #include "serialport.h" #include "softmodem.h" +#include "misc_util.h" //#include "mixer.h" -CSerialModem::CSerialModem( - IO_ReadHandler* rh, - IO_WriteHandler* wh, - TIMER_TickHandler th, - Bit16u baseAddr, - Bit8u initIrq, - Bit32u initBps, - Bit8u bytesize, - const char* parity, - Bit8u stopbits, - const char *remotestr, - Bit16u lport) - : CSerial(rh, wh, th, - baseAddr, initIrq, initBps, bytesize, parity, stopbits) { - socket=0; - incomingsocket=0; - InstallTimerHandler(th); +CSerialModem::CSerialModem(Bitu id, CommandLine* cmd):CSerial(id, cmd) { + InstallationSuccessful=false; + connected=false; - if(!SDLNetInited) { - if(SDLNet_Init()==-1) { - LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); - return; - } - SDLNetInited = true; - } rqueue=new CFifo(MODEM_BUFFER_QUEUE_SIZE); tqueue=new CFifo(MODEM_BUFFER_QUEUE_SIZE); - /* Default to direct null modem connection. Telnet mode interprets IAC codes */ + // Default to direct null modem connection. Telnet mode interprets IAC codes telnetmode = false; - /* Initialize the sockets and setup the listening port */ - socketset = SDLNet_AllocSocketSet(1); - listensocketset = SDLNet_AllocSocketSet(1); - if (!socketset || !listensocketset) { - LOG_MSG("MODEM:Can't open socketset:%s",SDLNet_GetError()); - //TODO Should probably just exit - return; - } - socket=0; - listenport=lport; - if (listenport) { - IPaddress listen_ip; - SDLNet_ResolveHost(&listen_ip, NULL, listenport); - listensocket=SDLNet_TCP_Open(&listen_ip); - if (!listensocket) LOG_MSG("MODEM:Can't open listen port: %s",SDLNet_GetError()); - - else LOG_MSG("MODEM: Port listener installed at port %d",listenport); - - } - else listensocket=0; - - // TODO: Fix dialtones if requested - //mhd.chan=MIXER_AddChannel((MIXER_MixHandler)this->MODEM_CallBack,8000,"MODEM"); - //MIXER_Enable(mhd.chan,false); - //MIXER_SetMode(mhd.chan,MIXER_16MONO); + // Initialize the sockets and setup the listening port + listenport = 23; + waitingclientsocket=0; + clientsocket = 0; + serversocket = 0; + getBituSubstring("listenport:", &listenport, cmd); + + // TODO: Fix dialtones if requested + //mhd.chan=MIXER_AddChannel((MIXER_MixHandler)this->MODEM_CallBack,8000,"MODEM"); + //MIXER_Enable(mhd.chan,false); + //MIXER_SetMode(mhd.chan,MIXER_16MONO); - Reset(); - //EnterIdleState(); - CSerial::Init_Registers(initBps,bytesize,parity,stopbits); - } + CSerial::Init_Registers(); + Reset(); // reset calls EnterIdleState + + setEvent(SERIAL_POLLING_EVENT,1); + InstallationSuccessful=true; +} - CSerialModem::~CSerialModem() { - if(socket) { - SDLNet_TCP_DelSocket(socketset,socket); - SDLNet_TCP_Close(socket); +CSerialModem::~CSerialModem() { + if(serversocket) delete serversocket; + if(clientsocket) delete clientsocket; + if(waitingclientsocket) delete waitingclientsocket; + + delete rqueue; + delete tqueue; + + // remove events + for(Bitu i = SERIAL_BASE_EVENT_COUNT+1; i <= SERIAL_MODEM_EVENT_COUNT; i++) + removeEvent(i); +} + +void CSerialModem::handleUpperEvent(Bit16u type) { + switch(type) + { + case SERIAL_RX_EVENT: + { + break; + } + case MODEM_TX_EVENT: + { + if(tqueue->left()) { + tqueue->addb(waiting_tx_character); + if(tqueue->left() < 2) { + CSerial::setCTS(false); + } + } else LOG_MSG("MODEM: TX Buffer overflow!"); + ByteTransmitted(); + + break; + } + case SERIAL_POLLING_EVENT: + { + Timer2(); + setEvent(SERIAL_POLLING_EVENT,1); + break; } - if(listensocket) SDLNet_TCP_Close(listensocket); - if(socketset) SDLNet_FreeSocketSet(socketset); - - delete rqueue; - delete tqueue; + case MODEM_RING_EVENT: + { + break; + } } +} void CSerialModem::SendLine(const char *line) { rqueue->addb(0xd); @@ -164,18 +162,9 @@ void CSerialModem::SendRes(ResTypes response) { } } -void CSerialModem::openConnection(void) { - if (socket) { - LOG_MSG("Huh? already connected"); - SDLNet_TCP_DelSocket(socketset,socket); - SDLNet_TCP_Close(socket); - } - socket = SDLNet_TCP_Open(&openip); -} - bool CSerialModem::Dial(char * host) { - /* Scan host for port */ + // Scan host for port Bit16u port; char * hasport=strrchr(host,':'); if (hasport) { @@ -183,26 +172,30 @@ bool CSerialModem::Dial(char * host) { port=(Bit16u)atoi(hasport); } else port=MODEM_DEFAULT_PORT; - /* Resolve host we're gonna dial */ + // Resolve host we're gonna dial LOG_MSG("Connecting to host %s port %d",host,port); - if (!SDLNet_ResolveHost(&openip,host,port)) { - openConnection(); - EnterConnectedState(); - return true; - } else { - LOG_MSG("Failed to resolve host %s: %s",host,SDLNet_GetError()); - SendRes(ResNODIALTONE); + clientsocket = new TCPClientSocket(host, port); + if(!clientsocket->isopen) { + delete clientsocket; + clientsocket=0; + LOG_MSG("Failed to connect."); + SendRes(ResNOCARRIER); EnterIdleState(); return false; + } else { + EnterConnectedState(); + return true; } } void CSerialModem::AcceptIncomingCall(void) { -// assert(!socket); - socket=incomingsocket; - SDLNet_TCP_AddSocket(socketset,socket); - incomingsocket = 0; - EnterConnectedState(); + if(waitingclientsocket) { + clientsocket=waitingclientsocket; + waitingclientsocket=0; + EnterConnectedState(); + } else { + EnterIdleState(); + } } Bitu CSerialModem::ScanNumber(char * & scan) { @@ -224,7 +217,10 @@ void CSerialModem::Reset(){ oldDTRstate = getDTR(); flowcontrol = 0; plusinc = 0; - incomingsocket = 0; + if(clientsocket) { + delete clientsocket; + clientsocket=0; + } memset(®,0,sizeof(reg)); reg[MREG_AUTOANSWER_COUNT]=0; // no autoanswer reg[MREG_RING_COUNT] = 1; @@ -246,23 +242,29 @@ void CSerialModem::EnterIdleState(void){ connected=false; ringing=false; - if(socket) { // clear current socket - SDLNet_TCP_DelSocket(socketset,socket); - SDLNet_TCP_Close(socket); - socket=0; + if(clientsocket) { + delete clientsocket; + clientsocket=0; } - if(incomingsocket) { // clear current incoming socket - SDLNet_TCP_DelSocket(socketset,incomingsocket); - SDLNet_TCP_Close(incomingsocket); + + if(waitingclientsocket) { // clear current incoming socket + delete waitingclientsocket; + waitingclientsocket=0; } // get rid of everything - if(listensocket) { - while(incomingsocket=SDLNet_TCP_Accept(listensocket)) { - SDLNet_TCP_DelSocket(socketset,incomingsocket); - SDLNet_TCP_Close(incomingsocket); - } + if(serversocket) { + while(waitingclientsocket=serversocket->Accept()) + delete waitingclientsocket; + } else if (listenport) { + + serversocket=new TCPServerSocket(listenport); + if(!serversocket->isopen) { + LOG_MSG("Serial%d: Modem could not open TCP port %d.",COMNUMBER,listenport); + delete serversocket; + serversocket=0; + } else LOG_MSG("Serial%d: Modem listening on port %d...",COMNUMBER,listenport); } - incomingsocket=0; + waitingclientsocket=0; commandmode = true; CSerial::setCD(false); @@ -273,19 +275,18 @@ void CSerialModem::EnterIdleState(void){ } void CSerialModem::EnterConnectedState(void) { - if(socket) { - SDLNet_TCP_AddSocket(socketset,socket); - SendRes(ResCONNECT); - commandmode = false; - memset(&telClient, 0, sizeof(telClient)); - connected = true; - ringing = false; - CSerial::setCD(true); - CSerial::setRI(false); - } else { - SendRes(ResNOCARRIER); - EnterIdleState(); + if(serversocket) { + // we don't accept further calls + delete serversocket; + serversocket=0; } + SendRes(ResCONNECT); + commandmode = false; + memset(&telClient, 0, sizeof(telClient)); + connected = true; + ringing = false; + CSerial::setCD(true); + CSerial::setRI(false); } void CSerialModem::DoCommand() { @@ -309,7 +310,7 @@ void CSerialModem::DoCommand() { if ((cmdbuf[0] != 'A') || (cmdbuf[1] != 'T')) { SendRes(ResERROR); - return;//goto ret_error; + return; } if (strstr(cmdbuf,"NET0")) { @@ -329,7 +330,7 @@ void CSerialModem::DoCommand() { if (*foundstr=='T' || *foundstr=='P') foundstr++; /* Small protection against empty line */ if (!foundstr[0]) { - SendRes(ResERROR);//goto ret_error; + SendRes(ResERROR); return; } char* helper; @@ -397,7 +398,7 @@ void CSerialModem::DoCommand() { if (connected) { SendRes(ResNOCARRIER); EnterIdleState(); - return;//goto ret_none; + return; } //Else return ok };break; @@ -405,12 +406,12 @@ void CSerialModem::DoCommand() { switch (num=ScanNumber(scanbuf)) { case 0: - if (socket) { + if (clientsocket) { commandmode = false; - return;//goto ret_none; + return; } else { SendRes(ResERROR); - return;//goto ret_none; + return; } };break; case 'T': //Tone Dial @@ -421,18 +422,18 @@ void CSerialModem::DoCommand() { ScanNumber(scanbuf); break; case 'A': //Answer call - if (incomingsocket) { + if (waitingclientsocket) { AcceptIncomingCall(); } else { SendRes(ResERROR); - return;//goto ret_none; + return; } - return;//goto ret_none; + return; case 'Z': //Reset and load profiles { // scan the number away, if any ScanNumber(scanbuf); - if (socket) SendRes(ResNOCARRIER); + if (clientsocket/*socket*/) SendRes(ResNOCARRIER); Reset(); break; } @@ -525,107 +526,103 @@ void CSerialModem::TelnetEmulation(Bit8u * data, Bitu size) { LOG_MSG("MODEM: Unrecognized option %d", c); if(telClient.command>250) { /* Reject anything we don't recognize */ + tqueue->addb(0xff); + tqueue->addb(252); + tqueue->addb(c); /* We won't do crap! */ + } + } + switch(telClient.command) { + case 251: /* Will */ + if(c == 0) telClient.binary[TEL_SERVER] = true; + if(c == 1) telClient.echo[TEL_SERVER] = true; + if(c == 3) telClient.supressGA[TEL_SERVER] = true; + break; + case 252: /* Won't */ + if(c == 0) telClient.binary[TEL_SERVER] = false; + if(c == 1) telClient.echo[TEL_SERVER] = false; + if(c == 3) telClient.supressGA[TEL_SERVER] = false; + break; + case 253: /* Do */ + if(c == 0) { + telClient.binary[TEL_CLIENT] = true; + tqueue->addb(0xff); + tqueue->addb(251); + tqueue->addb(0); /* Will do binary transfer */ + } + if(c == 1) { + telClient.echo[TEL_CLIENT] = false; tqueue->addb(0xff); tqueue->addb(252); - tqueue->addb(c); /* We won't do crap! */ + tqueue->addb(1); /* Won't echo (too lazy) */ } - } - switch(telClient.command) { - case 251: /* Will */ - if(c == 0) telClient.binary[TEL_SERVER] = true; - if(c == 1) telClient.echo[TEL_SERVER] = true; - if(c == 3) telClient.supressGA[TEL_SERVER] = true; - break; - case 252: /* Won't */ - if(c == 0) telClient.binary[TEL_SERVER] = false; - if(c == 1) telClient.echo[TEL_SERVER] = false; - if(c == 3) telClient.supressGA[TEL_SERVER] = false; - break; - case 253: /* Do */ - if(c == 0) { - telClient.binary[TEL_CLIENT] = true; - tqueue->addb(0xff); - tqueue->addb(251); - tqueue->addb(0); /* Will do binary transfer */ - } - if(c == 1) { - telClient.echo[TEL_CLIENT] = false; - tqueue->addb(0xff); - tqueue->addb(252); - tqueue->addb(1); /* Won't echo (too lazy) */ - } - if(c == 3) { - telClient.supressGA[TEL_CLIENT] = true; - tqueue->addb(0xff); - tqueue->addb(251); - tqueue->addb(3); /* Will Suppress GA */ - } - break; - case 254: /* Don't */ - if(c == 0) { - telClient.binary[TEL_CLIENT] = false; - tqueue->addb(0xff); - tqueue->addb(252); - tqueue->addb(0); /* Won't do binary transfer */ - } - if(c == 1) { - telClient.echo[TEL_CLIENT] = false; - tqueue->addb(0xff); - tqueue->addb(252); - tqueue->addb(1); /* Won't echo (fine by me) */ - } - if(c == 3) { - telClient.supressGA[TEL_CLIENT] = true; - tqueue->addb(0xff); - tqueue->addb(251); - tqueue->addb(3); /* Will Suppress GA (too lazy) */ - } - break; - default: - LOG_MSG("MODEM: Telnet client sent IAC %d", telClient.command); - break; - } - + if(c == 3) { + telClient.supressGA[TEL_CLIENT] = true; + tqueue->addb(0xff); + tqueue->addb(251); + tqueue->addb(3); /* Will Suppress GA */ + } + break; + case 254: /* Don't */ + if(c == 0) { + telClient.binary[TEL_CLIENT] = false; + tqueue->addb(0xff); + tqueue->addb(252); + tqueue->addb(0); /* Won't do binary transfer */ + } + if(c == 1) { + telClient.echo[TEL_CLIENT] = false; + tqueue->addb(0xff); + tqueue->addb(252); + tqueue->addb(1); /* Won't echo (fine by me) */ + } + if(c == 3) { + telClient.supressGA[TEL_CLIENT] = true; + tqueue->addb(0xff); + tqueue->addb(251); + tqueue->addb(3); /* Will Suppress GA (too lazy) */ + } + break; + default: + LOG_MSG("MODEM: Telnet client sent IAC %d", telClient.command); + break; + } + telClient.inIAC = false; + telClient.recCommand = false; + continue; + } else { + if(c==249) { + /* Go Ahead received */ + telClient.inIAC = false; + continue; + } + telClient.command = c; + telClient.recCommand = true; + + if((telClient.binary[TEL_SERVER]) && (c == 0xff)) { + /* Binary data with value of 255 */ telClient.inIAC = false; telClient.recCommand = false; + rqueue->addb(0xff); continue; - - } else { - if(c==249) { - /* Go Ahead received */ - telClient.inIAC = false; - continue; - } - telClient.command = c; - telClient.recCommand = true; - - if((telClient.binary[TEL_SERVER]) && (c == 0xff)) { - /* Binary data with value of 255 */ - telClient.inIAC = false; - telClient.recCommand = false; - rqueue->addb(0xff); - continue; - } - - } - } else { - if(c == 0xff) { - telClient.inIAC = true; - continue; - } - rqueue->addb(c); } } + } else { + if(c == 0xff) { + telClient.inIAC = true; + continue; + } + rqueue->addb(c); + } } +} void CSerialModem::Timer2(void) { - int result =0; + unsigned long args = 1; bool sendbyte = true; Bitu usesize; Bit8u txval; Bitu txbuffersize =0; - Bitu testres = 0; // check for bytes to be sent to port if(CSerial::CanReceiveByte()) @@ -634,13 +631,11 @@ void CSerialModem::Timer2(void) { //LOG_MSG("Modem: sending byte %2x back to UART3",rbyte); CSerial::receiveByte(rbyte); } - /* Check for eventual break command */ + // Check for eventual break command if (!commandmode) cmdpause++; - /* Handle incoming data from serial port, read as much as available */ - //Bitu tx_size=tqueue->inuse(); - //Bitu tx_first = tx_size; // TODO:comment out + // Handle incoming data from serial port, read as much as available CSerial::setCTS(true); // buffer will get 'emptier', new data can be received - while (/*tx_size--*/tqueue->inuse()) { + while (tqueue->inuse()) { txval = tqueue->getb(); if (commandmode) { if (echo) { @@ -658,9 +653,9 @@ void CSerialModem::Timer2(void) { } } else {// + character - /* 1000 ticks have passed, can check for pause command */ + // 1000 ticks have passed, can check for pause command if (cmdpause > 1000) { - if(txval ==/* '+')*/reg[MREG_ESCAPE_CHAR]) + if(txval ==reg[MREG_ESCAPE_CHAR]) // + { plusinc++; if(plusinc>=3) { @@ -673,46 +668,37 @@ void CSerialModem::Timer2(void) { } else { plusinc=0; } - //If not a special pause command, should go for bigger blocks to send + // If not a special pause command, should go for bigger blocks to send } tmpbuf[txbuffersize] = txval; txbuffersize++; } } // while loop - if (socket && sendbyte && txbuffersize) { + if (clientsocket && sendbyte && txbuffersize) { // down here it saves a lot of network traffic - SDLNet_TCP_Send(socket, tmpbuf,txbuffersize); + clientsocket->SendArray(tmpbuf,txbuffersize); //TODO error testing } - SDLNet_CheckSockets(socketset,0); - /* Handle incoming to the serial port */ - if(!commandmode && socket) { - if(rqueue->left() && SDLNet_SocketReady(socket) /*&& CSerial::getRTS()*/) - { - usesize = rqueue->left(); - if (usesize>16) usesize=16; - result = SDLNet_TCP_Recv(socket, tmpbuf, usesize); - if (result>0) { - if(telnetmode) { - /* Filter telnet commands */ - TelnetEmulation(tmpbuf, result); - } else { - rqueue->adds(tmpbuf,result); - } - cmdpause = 0; - } else { - SendRes(ResNOCARRIER); - EnterIdleState(); - } - } + // Handle incoming to the serial port + if(!commandmode && clientsocket && rqueue->left()) { + usesize = rqueue->left(); + if (usesize>16) usesize=16; + if(!clientsocket->ReceiveArray(tmpbuf, &usesize)) { + SendRes(ResNOCARRIER); + EnterIdleState(); + } else if(usesize) { + // LOG_MSG("rcv:%d", result); + // Filter telnet commands + if(telnetmode) TelnetEmulation(tmpbuf, usesize); + else rqueue->adds(tmpbuf,usesize); + cmdpause = 0; + } } - /* Check for incoming calls */ - if (!connected && !incomingsocket && listensocket) { - incomingsocket = SDLNet_TCP_Accept(listensocket); - if (incomingsocket) { - SDLNet_TCP_AddSocket(listensocketset, incomingsocket); - + // Check for incoming calls + if (!connected && !waitingclientsocket && serversocket) { + waitingclientsocket=serversocket->Accept(); + if(waitingclientsocket) { if(!CSerial::getDTR()) { // accept no calls with DTR off; TODO: AT &Dn EnterIdleState(); @@ -754,18 +740,14 @@ void CSerialModem::RXBufferEmpty() { } } -void CSerialModem::transmitByte(Bit8u val) { +void CSerialModem::transmitByte(Bit8u val, bool first) { + waiting_tx_character=val; + setEvent(MODEM_TX_EVENT, bytetime); // TX event + if(first) ByteTransmitting(); //LOG_MSG("MODEM: Byte %x to be transmitted",val); - if(tqueue->left()) { - tqueue->addb(val); - if(tqueue->left() < 2) { - CSerial::setCTS(false); - } - } else LOG_MSG("MODEM: TX Buffer overflow!"); - CSerial::ByteTransmitted(); } -void CSerialModem::updatePortConfig(Bit8u dll, Bit8u dlm, Bit8u lcr) { +void CSerialModem::updatePortConfig(Bit16u, Bit8u lcr) { // nothing to do here right? } @@ -777,6 +759,21 @@ void CSerialModem::setBreak(bool) { // TODO: handle this } +void CSerialModem::setRTSDTR(bool rts, bool dtr) { + setDTR(dtr); +} +void CSerialModem::setRTS(bool val) { + +} +void CSerialModem::setDTR(bool val) { + if(!val && connected) { + // If DTR goes low, hang up. + SendRes(ResNOCARRIER); + EnterIdleState(); + LOG_MSG("Modem: Hang up due to dropped DTR."); + } +} +/* void CSerialModem::updateModemControlLines() { //bool txrdy=tqueue->left(); //if(CSerial::getRTS() && txrdy) CSerial::setCTS(true); @@ -793,7 +790,7 @@ void CSerialModem::updateModemControlLines() { oldDTRstate = getDTR(); } - +*/ #endif diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index 7cbf65b4..c51d915e 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -16,16 +16,17 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.h,v 1.6 2007-01-08 19:45:41 qbix79 Exp $ */ +/* $Id: softmodem.h,v 1.7 2007-01-13 08:35:49 qbix79 Exp $ */ #ifndef DOSBOX_SERIALMODEM_H #define DOSBOX_SERIALMODEM_H #include "dosbox.h" #if C_MODEM -#include "SDL_net.h" #include "serialport.h" +#include "misc_util.h" + #define MODEMSPD 57600 #define SREGS 100 @@ -34,6 +35,12 @@ #define MODEM_DEFAULT_PORT 23 +#define MODEM_TX_EVENT SERIAL_BASE_EVENT_COUNT + 1 +#define MODEM_RX_POLLING SERIAL_BASE_EVENT_COUNT + 2 +#define MODEM_RING_EVENT SERIAL_BASE_EVENT_COUNT + 3 +#define SERIAL_MODEM_EVENT_COUNT SERIAL_BASE_EVENT_COUNT+3 + + enum ResTypes { ResNONE, ResOK,ResERROR, @@ -118,9 +125,6 @@ public: private: Bit8u * data; Bitu size,pos,used; - //Bit8u tmpbuf[MODEM_BUFFER_QUEUE_SIZE]; - - }; #define MREG_AUTOANSWER_COUNT 0 #define MREG_RING_COUNT 1 @@ -136,20 +140,7 @@ public: CFifo *rqueue; CFifo *tqueue; - CSerialModem( - IO_ReadHandler* rh, - IO_WriteHandler* wh, - TIMER_TickHandler th, - Bit16u baseAddr, - Bit8u initIrq, - Bit32u initBps, - Bit8u bytesize, - const char* parity, - Bit8u stopbits, - - const char *remotestr = NULL, - Bit16u lport = 23); - + CSerialModem(Bitu id, CommandLine* cmd); ~CSerialModem(); void Reset(); @@ -172,17 +163,21 @@ public: void TelnetEmulation(Bit8u * data, Bitu size); + //TODO void Timer2(void); + void handleUpperEvent(Bit16u type); void RXBufferEmpty(); - void transmitByte(Bit8u val); - void updatePortConfig(Bit8u dll, Bit8u dlm, Bit8u lcr); + void transmitByte(Bit8u val, bool first); + void updatePortConfig(Bit16u divider, Bit8u lcr); void updateMSR(); void setBreak(bool); - void updateModemControlLines(/*Bit8u mcr*/); + void setRTSDTR(bool rts, bool dtr); + void setRTS(bool val); + void setDTR(bool val); protected: char cmdbuf[255]; @@ -199,7 +194,7 @@ protected: bool connected; Bitu doresponse; - + Bit8u waiting_tx_character; Bitu cmdpause; Bits ringtimer; @@ -208,18 +203,15 @@ protected: Bitu cmdpos; Bitu flowcontrol; - //Bit8u mctrl; Bit8u tmpbuf[MODEM_BUFFER_QUEUE_SIZE]; Bitu listenport; Bit8u reg[SREGS]; - IPaddress openip; - TCPsocket incomingsocket; - TCPsocket socket; - TCPsocket listensocket; - SDLNet_SocketSet socketset; - SDLNet_SocketSet listensocketset; + + TCPServerSocket* serversocket; + TCPClientSocket* clientsocket; + TCPClientSocket* waitingclientsocket; struct { bool binary[2]; diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index ce2cb729..1865691f 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.64 2007-01-08 19:45:41 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.65 2007-01-13 08:35:49 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -29,6 +29,7 @@ #include "joystick.h" #include "mouse.h" #include "setup.h" +#include "serialport.h" /* if mem_systems 0 then size_extended is reported as the real size else @@ -361,10 +362,15 @@ static Bitu INT17_Handler(void) { static Bitu INT14_Handler(void) { + if(reg_ah > 0x3 || reg_dx > 0x3) { // 0-3 serial port functions + // and no more than 4 serial ports + LOG_MSG("BIOS INT14: Unhandled call AH=%2X DX=%4x",reg_dx); + return CBRET_NONE; + } + Bit16u port = real_readw(0x40,reg_dx*2); // DX is always port number - if(reg_dx > 0x3 || port==0) // no more than 4 serial ports - { - LOG_MSG("BIOS INT14: port %d does not exist.",reg_dx); + if(port==0) { + LOG(LOG_BIOS,LOG_NORMAL)("BIOS INT14: port %d does not exist.",reg_dx); return CBRET_NONE; } switch (reg_ah) @@ -402,12 +408,11 @@ static Bitu INT14_Handler(void) // disable interrupts IO_WriteB(port+1, 0); IO_ReadB(port+2); - // put RTS and DTR on - IO_WriteB(port+4,0x3); // get result reg_ah=IO_ReadB(port+5); reg_al=IO_ReadB(port+6); + CALLBACK_SCF(false); } break; case 0x01: /* Write character */ @@ -417,126 +422,49 @@ static Bitu INT14_Handler(void) // AH: line status // AL: modem status { - if((IO_ReadB(port+5)&&0x20)==0) - { - // TODO: should wait until they become empty->timeout - LOG_MSG("BIOS INT14: port %d: transmit register not empty.",reg_dx); - reg_ah = IO_ReadB(port+5)|0x80; - return CBRET_NONE; + if(serialports[reg_dx]) { + bool timeout; + // switch modem lines on + IO_WriteB(port+4,0x3); + timeout = !serialports[reg_dx]->Putchar(reg_al,true,true, + mem_readb(BIOS_COM1_TIMEOUT+reg_dx)*1000); + // get result + reg_ah=IO_ReadB(port+5); + if(timeout) reg_ah |= 0x80; + reg_al=IO_ReadB(port+6); } - // transmit it - IO_WriteB(port,reg_al); - - if((IO_ReadB(port+5)&&0x60)==0) - { - // TODO: should wait until they become empty->timeout - LOG_MSG("BIOS INT14: port %d: transmit register not empty after write.",reg_dx); - reg_ah = IO_ReadB(port+5)|0x80; - return CBRET_NONE; - } - - // get result - reg_ah=IO_ReadB(port+5); - reg_al=IO_ReadB(port+6); + CALLBACK_SCF(false); } break; case 0x02: /* Read character */ { - if((IO_ReadB(port+5)&0x1)!=0) - { - reg_al=IO_ReadB(port); + if(serialports[reg_dx]) { + bool timeout; + Bit8u buffer; + // switch modem lines on + IO_WriteB(port+4,0x3); + // wait for something + timeout = !serialports[reg_dx]->Getchar(&buffer,true, + mem_readb(BIOS_COM1_TIMEOUT+reg_dx)*1000); + + // RTS off + IO_WriteB(port+4,0x1); + // get result + reg_ah=IO_ReadB(port+5); + if(timeout) reg_ah |= 0x80; + else reg_al=buffer; } - else - { - // TODO: should wait until timeout - LOG_MSG("BIOS INT14: port %d: nothing received.",reg_dx); - reg_ah = IO_ReadB(port+5)|0x80; - return CBRET_NONE; - } - reg_ah=IO_ReadB(port+5); + CALLBACK_SCF(false); + break; } - break; case 0x03: // get status { reg_ah=IO_ReadB(port+5); - //LOG_MSG("status reg_ah: %x",reg_ah); reg_al=IO_ReadB(port+6); + CALLBACK_SCF(false); } - break; - case 0x04: // extended initialisation - // Parameters: - // AL: break - // BH: parity - // BL: stopbit - // CH: word length - // CL: baudrate - { - Bit8u lcr = 0; - - // baud rate - Bitu baudrate = 9600; - Bit16u baudresult; - Bitu rawbaud=reg_cl; - - if(rawbaud==0){ baudrate=110;} - else if (rawbaud==1){ baudrate=150;} - else if (rawbaud==2){ baudrate=300;} - else if (rawbaud==3){ baudrate=600;} - else if (rawbaud==4){ baudrate=1200;} - else if (rawbaud==5){ baudrate=2400;} - else if (rawbaud==6){ baudrate=4800;} - else if (rawbaud==7){ baudrate=9600;} - else if (rawbaud==8){ baudrate=19200;} - - baudresult = (Bit16u)(115200 / baudrate); - - IO_WriteB(port+3, 0x80); // enable divider access - IO_WriteB(port,(Bit8u)baudresult&0xff); - IO_WriteB(port+1,(Bit8u)(baudresult>>8)); - - // line configuration - // break - if(reg_al!=0) lcr=0x40; - // parity - if(reg_bh!=0) - { - if(reg_bh==1)lcr|=0x8;// odd - else if(reg_bh==2)lcr|=0x18;// even - else if(reg_bh==3)lcr|=0x28;// mark - else if(reg_bh==4)lcr|=0x38;// mark - } - // stopbit - if(reg_bl!=0) - { - lcr|=0x4; - } - // data length - lcr|=(reg_ch&0x3); - IO_WriteB(port+3,lcr); - - reg_ah=IO_ReadB(port+5); - reg_al=IO_ReadB(port+6); - } - break; - case 0x05: // modem control - { - if(reg_al==0) // read MCR - { - reg_bl=IO_ReadB(port+4); - } - else if(reg_al==1) // write MCR - { - IO_WriteB(port+4,reg_bl); - } - else LOG_MSG("BIOS INT14: port %d, function 5: invalid subfunction.",reg_dx); - reg_ah=IO_ReadB(port+5); - reg_al=IO_ReadB(port+6); - } - break; - default: - LOG_MSG("Unhandled INT 14 call %2X",reg_ah); - + break; } return CBRET_NONE; } @@ -848,7 +776,7 @@ public: BIOS_SetupDisks(); /* INT 14 Serial Ports */ - callback[3].Install(&INT14_Handler,CB_IRET,"Int 14 COM-port"); + callback[3].Install(&INT14_Handler,CB_IRET_STI,"Int 14 COM-port"); callback[3].Set_RealVec(0x14); /* INT 15 Misc Calls */ @@ -922,46 +850,49 @@ public: } /* Setup some stuff in 0x40 bios segment */ + + // port timeouts + // always 1 second even if the port does not exist + mem_writeb(BIOS_LPT1_TIMEOUT,1); + mem_writeb(BIOS_LPT2_TIMEOUT,1); + mem_writeb(BIOS_LPT3_TIMEOUT,1); + mem_writeb(BIOS_COM1_TIMEOUT,1); + mem_writeb(BIOS_COM2_TIMEOUT,1); + mem_writeb(BIOS_COM3_TIMEOUT,1); + mem_writeb(BIOS_COM4_TIMEOUT,1); + /* detect parallel ports */ - Bit8u DEFAULTPORTTIMEOUT = 10; // 10 whatevers Bitu ppindex=0; // number of lpt ports if ((IO_Read(0x378)!=0xff)|(IO_Read(0x379)!=0xff)) { // this is our LPT1 mem_writew(BIOS_ADDRESS_LPT1,0x378); - mem_writeb(BIOS_LPT1_TIMEOUT,DEFAULTPORTTIMEOUT); ppindex++; if((IO_Read(0x278)!=0xff)|(IO_Read(0x279)!=0xff)) { // this is our LPT2 mem_writew(BIOS_ADDRESS_LPT2,0x278); - mem_writeb(BIOS_LPT2_TIMEOUT,DEFAULTPORTTIMEOUT); ppindex++; if((IO_Read(0x3bc)!=0xff)|(IO_Read(0x3be)!=0xff)) { // this is our LPT3 mem_writew(BIOS_ADDRESS_LPT3,0x3bc); - mem_writeb(BIOS_LPT3_TIMEOUT,DEFAULTPORTTIMEOUT); ppindex++; } } else if((IO_Read(0x3bc)!=0xff)|(IO_Read(0x3be)!=0xff)) { // this is our LPT2 mem_writew(BIOS_ADDRESS_LPT2,0x3bc); - mem_writeb(BIOS_LPT2_TIMEOUT,DEFAULTPORTTIMEOUT); ppindex++; } } else if((IO_Read(0x3bc)!=0xff)|(IO_Read(0x3be)!=0xff)) { // this is our LPT1 mem_writew(BIOS_ADDRESS_LPT1,0x3bc); - mem_writeb(BIOS_LPT1_TIMEOUT,DEFAULTPORTTIMEOUT); ppindex++; if((IO_Read(0x278)!=0xff)|(IO_Read(0x279)!=0xff)) { // this is our LPT2 mem_writew(BIOS_ADDRESS_LPT2,0x278); - mem_writeb(BIOS_LPT2_TIMEOUT,DEFAULTPORTTIMEOUT); ppindex++; } } else if((IO_Read(0x278)!=0xff)|(IO_Read(0x279)!=0xff)) { // this is our LPT1 mem_writew(BIOS_ADDRESS_LPT1,0x278); - mem_writeb(BIOS_LPT1_TIMEOUT,DEFAULTPORTTIMEOUT); ppindex++; } @@ -1035,24 +966,14 @@ public: // set com port data in bios data area // parameter: array of 4 com port base addresses, 0 = none void BIOS_SetComPorts(Bit16u baseaddr[]) { - Bit8u DEFAULTPORTTIMEOUT = 10; // 10 whatevers Bit16u portcount=0; Bit16u equipmentword; for(Bitu i = 0; i < 4; i++) { if(baseaddr[i]!=0) portcount++; - if(i==0) { // com1 - mem_writew(BIOS_BASE_ADDRESS_COM1,baseaddr[i]); - mem_writeb(BIOS_COM1_TIMEOUT,DEFAULTPORTTIMEOUT); - } else if(i==1) { - mem_writew(BIOS_BASE_ADDRESS_COM2,baseaddr[i]); - mem_writeb(BIOS_COM2_TIMEOUT,DEFAULTPORTTIMEOUT); - } else if(i==2) { - mem_writew(BIOS_BASE_ADDRESS_COM3,baseaddr[i]); - mem_writeb(BIOS_COM3_TIMEOUT,DEFAULTPORTTIMEOUT); - } else { - mem_writew(BIOS_BASE_ADDRESS_COM4,baseaddr[i]); - mem_writeb(BIOS_COM4_TIMEOUT,DEFAULTPORTTIMEOUT); - } + if(i==0) mem_writew(BIOS_BASE_ADDRESS_COM1,baseaddr[i]); + else if(i==1) mem_writew(BIOS_BASE_ADDRESS_COM2,baseaddr[i]); + else if(i==2) mem_writew(BIOS_BASE_ADDRESS_COM3,baseaddr[i]); + else mem_writew(BIOS_BASE_ADDRESS_COM4,baseaddr[i]); } // set equipment word equipmentword = mem_readw(BIOS_CONFIGURATION); diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 26e93462..5512e72f 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -113,7 +113,7 @@ Name="VCCustomBuildTool"/> + + + + + + + + + + + + + + + + + + + From e92b82a8e26aa68e6b120c0b2fe8339d0a5c6b42 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 13 Jan 2007 09:44:50 +0000 Subject: [PATCH 2674/4131] Readme update from h-a-l-9000 and wd Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2759 --- README | 437 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 317 insertions(+), 120 deletions(-) diff --git a/README b/README index fbf0ff68..447ff1ac 100644 --- a/README +++ b/README @@ -1,19 +1,15 @@ -DOSBox v0.65 +DOSBox v0.66 ===== NOTE: ===== -While we are hoping that one day, DOSBox will run all programs -ever made for the PC, we are not there yet. At present, DOSBox running on a -high-end machine will roughly be the equivalent of a 486 PC. The 0.60 -release has added support for "protected mode" allowing for more complex and -recent programs, but note that this support is still in an early stage of -development and unlike the support for 386 real-mode games (or earlier) hasn't -been completed yet. Also note that "protected mode" games need substantially -more resources and may require a much faster processor for you to run them -properly in DOSBox. +While we are hoping that one day DOSBox will run all programs ever +made for the PC, we are not there yet. At present, DOSBox running +on a high-end machine will roughly be the equivalent of a 486 PC. +DOSBox can be configured to run a wide range of DOS games, from +CGA/Tandy/PCjr classics up to games from the Quake era. @@ -25,14 +21,15 @@ INDEX: 3. Usage 4. Internal Programs 5. Special Keys -6. Keymapper -7. System Requirements -8. To run resource-demanding games -9. The config file -10. The language file -11. Building your own version of DOSBox -12. Special thanks -13. Contact +6. Mapper +7. Keyboard Layout +8. Serial Multiplayer feature +9. To run resource-demanding games +10. The config file +11. The language file +12. Building your own version of DOSBox +13. Special thanks +14. Contact ============== @@ -49,13 +46,13 @@ Type INTRO in DOSBox. That's it. Some Frequently Asked Questions: Q: I've got a Z instead of a C at the prompt. -Q: My game crashes when using opengl/nb or is much slower. Q: My CD-ROM doesn't work. Q: The mouse doesn't work. Q: The sound stutters or sounds stretched/weird. Q: I can't type \ or : in DOSBox. Q: The game/application can't find its CD-ROM. Q: The game/application runs much too slow! +Q: Can DOSBox harm my computer? Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. Q: What sound hardware does DOSBox presently emulate? Q: DOSBox crashes on startup and I'm running arts @@ -71,11 +68,8 @@ A: You have to make your directories available as drives in DOSBox by using you a C drive in DOSBox which points to your Windows D:\GAMES directory. In Linux, "mount c /home/username" will give you a C drive in DOSBox which points to /home/username in Linux. - - -Q: My game crashes when using opengl/nb or is much slower. -A: Somehow our opengl code isn't entirely stable on some platforms. - Use surface instead. + To change to the drive mounted like above, type "C:". If everything went + fine, DOSBox will display the prompt "C:\>". Q: My CD-ROM doesn't work. @@ -112,34 +106,42 @@ A: You're using too much cpu power to keep DOSBox running at the current speed. Q: I can't type \ or : in DOSBox. A: This is a known problem. It only occurs if your keyboard layout isn't US. Some possible fixes: - 1. Switch your keyboard layout. + 1. Switch the keyboard layout of your operating system. 2. Use / instead. 3. Open dosbox.conf and change usescancodes=false to usescancodes=true. 4. Add the commands you want to execute to the "configfile". - 5. Start the keymapper (CTRL-F1 or add -startmapper switch to DOSBox). + 5. Change the dos keyboard layout (see Section 7 Keyboard Layout). 6. Use ALT-58 for : and ALT-92 for \. 7. for \ try the keys around "enter". For ":" try shift and the keys between "enter" and "l" (US keyboard layout). - 8. Use keyb.com from FreeDOS (http://projects.freedos.net/keyb/). + 8. Try keyb.com from FreeDOS (http://projects.freedos.net/keyb/). Q: The game/application can't find its CD-ROM. -A: Be sure to mount the CD-ROM with -t cdrom switch. Also try adding the - correct label (-label LABEL). To enable more low-level CD-ROM support, add - the following switch to mount: -usecd #, where # is the number of your - CD-ROM drive reported by mount -cd. If you run Win32 you can specify -ioctl - or -aspi. Look at the description elsewhere in this document for their - meaning. +A: Be sure to mount the CD-ROM with -t cdrom switch, this will enable the + MSCDEX interface required by DOS games to interface with CD-ROMs. + Also try adding the correct label (-label LABEL). To enable lower-level + CD-ROM support, add the following switch to mount: -usecd #, where # is + the number of your CD-ROM drive reported by mount -cd. Under Windows you + can specify -ioctl or -aspi. Look at the description elsewhere in this + document for their meaning. Q: The game/application runs much too slow! A: Look at the section "To run resource-demanding games" for more information. +Q: Can DOSBox harm my computer? +A: DOSBox can not harm your computer more than any other resource demanding + program. Increasing the cycles does not overclock your real CPU. + Setting the cycles too high has a negative performance effect on the + software running inside DOSBox. + + Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. -A: This is possible! Just create a config file: config -writeconf configfile . - Start your favourite editor and look at all the settings present. To - start DOSBox with your new settings: dosbox -conf configfile +A: This is possible! Just create a config file: config -writeconf configfile. + Start your favourite editor and look through the settings. To start DOSBox + with your new settings: dosbox -conf configfile Q: What sound hardware does DOSBox presently emulate? @@ -155,6 +157,10 @@ A: DOSBox emulates several legacy sound devices: The emulation of this sound hardware is complete with the exception of the noise channel. The noise channel is not very well documented and as such is only a best guess as to the sound's accuracy. + - Tandy DAC + Emulation of the Tandy DAC utilizes the soundblaster emulation, thus + be sure the soundblaster is not disabled in the DOSBox configuration + file. The Tandy DAC is only emulated at the BIOS level. - Adlib Borrowed from MAME, this emulation is almost perfect and includes the Adlib's ability to almost play digitized sound. @@ -172,15 +178,16 @@ A: DOSBox emulates several legacy sound devices: A MIDI passthrough interface is also emulated. This method of sound output will only work when used with a General Midi or MT-32 device. + Q: DOSBox crashes on startup and I'm running arts. A: This isn't really a DOSBox problem, but the solution is to set the environment variable SDL_AUDIODRIVER to alsa or oss. + Q: Great README, but I still don't get it. -A: While unlikely, this seems to happen. A look at "The Newbie's - pictorial guide to DOSBox" located at +A: A look at "The Newbie's pictorial guide to DOSBox" located at http://vogons.zetafleet.com/viewforum.php?f=39 might help you. - You could also try the wiki of dosbox: + Also try the wiki of dosbox: http://dosbox.sourceforge.net/wiki/ @@ -283,21 +290,19 @@ MOUNT -u "Emulated Drive letter" "Emulated Drive letter" The driveletter inside dosbox (eg. C). - "Real Drive letter or Directory" - The local directory you want to have inside dosbox. - (Under Win32 usually the same as "Emulated Drive letter". - For Example: mount c c:\ ) + "Real Drive letter (usually for CD-ROMs in Windows) or Directory" + The local directory you want accessible inside dosbox. -t type - Type of the mounted directory. Supported are: dir (standard), + Type of the mounted directory. Supported are: dir (default), floppy, cdrom. -size drivesize Sets the size of the drive. -freesize size_in_mb - Sets the amount of free space available on a drive in MB's. This - is a simpler version of -size. + Sets the amount of free space available on a drive in megabytes. + This is a simpler version of -size. -label drivelabel Sets the name of the drive to "drivelabel". Needed on some @@ -331,21 +336,23 @@ MOUNT -u "Emulated Drive letter" Note: It's possible to mount a local directory as cdrom drive. Hardware support is then missing. - Basically, MOUNT allows you to connect real hardware to DOSBox's "emulated" - PC. So MOUNT C C:\GAMES tells DOSBox to use your C:\GAMES directory as drive - C: in DOSBox. It also allows you to change the drive's letter identification + Basically MOUNT allows you to connect real hardware to DOSBox's emulated PC. + So MOUNT C C:\GAMES tells DOSBox to use your C:\GAMES directory as drive C: + in DOSBox. It also allows you to change the drive's letter identification for programs that demand specific drive letters. For example: Touche: Adventures of The Fifth Musketeer must be run on your C: drive. Using DOSBox and its mount command, you can trick the game into believing it is on the C drive, while you can still place it where you - want it. For example, if the game is in D:\TOUCHE, the command MOUNT C D:\ - will allow you to run Touche from the D drive. + like. For example, if the game is in D:\OLDGAMES\TOUCHE, the command + MOUNT C D:\OLDGAMES will allow you to run Touche from the D drive. - Mounting your entire C drive with MOUNT C C:\ is NOT recommended! - If you or DOSBox makes a mistake you may loose all your files. - It's recommended to put all your applications/games in a subdirectory and - mount that. + Mounting your entire C drive with MOUNT C C:\ is NOT recommended! The same + is true for mounting the root of any other drive, except for CD-ROMs (due to + their read-only nature). Otherwise if you or DOSBox make a mistakes you may + loose all your files. + It is recommended to put all your applications/games into a subdirectory + and mount that. General MOUNT Examples: 1. To mount c:\DirX as a floppy : @@ -362,9 +369,11 @@ MOUNT -u "Emulated Drive letter" 6. To mount /home/user/dirY as drive C in DOSBox: mount c /home/user/dirY + MEM Program to display the amount of free memory. + CONFIG [-writeconf] [-writelang] localfile CONFIG -set "section property=value" CONFIG -get "section property" @@ -372,7 +381,7 @@ CONFIG -get "section property" CONFIG can be used to change or query various settings of DOSBox during runtime. It can save the current settings and language strings to disk. Information about all possible sections and properties can - be found in section 9 (The Config File). + be found in section 10 (The Config File). -writeconf localfile Write the current configuration settings to file. "localfile" is @@ -380,7 +389,7 @@ CONFIG -get "section property" The configuration file controls various settings of DOSBox: the amount of emulated memory, the emulated soundcards and many more things. It allows access to AUTOEXEC.BAT as well. - See section 9 (The Config File) for more information. + See section 10 (The Config File) for more information. -writelang localfile Write the current language settings to file. "localfile" is @@ -410,13 +419,14 @@ CONFIG -get "section property" 4. To check which cpu core is being used. config -get "cpu core" + LOADFIX [-size] [program] [program-parameters] LOADFIX -f Program to reduce the amount of memory available. Useful for old programs which don't expect much memory to be free. -size - number of kb to "eat up", default = 64kb + number of kilobytes to "eat up", default = 64kb -f frees all previously allocated memory @@ -503,7 +513,7 @@ IMGMOUNT The Cylinders, Heads and Sectors specification of the drive. Required to mount hard drive images. - An example of CD-ROM images: + An example how to mount CD-ROM images: 1a. mount c /tmp 1b. imgmount d c:\myiso.iso -t iso or (which also works): @@ -512,9 +522,9 @@ IMGMOUNT BOOT Boot will start floppy images or hard disk images independent of the - operating system emulation offered by DOSBox. This will allow you to play - booter floppies or boot to other operating systems inside DOSBox. - If the target emulated system is PCJr (machine=pcjr) the boot-command + operating system emulation offered by DOSBox. This will allow you to + play booter floppies or boot other operating systems inside DOSBox. + If the target emulated system is PCJr (machine=pcjr) the boot command can be used to load PCJr cartridges (.jrc). BOOT [diskimg1.img diskimg2.img .. diskimgN.img] [-l driveletter] @@ -532,6 +542,10 @@ BOOT The default is the A drive, the floppy drive. You can also boot a hard drive image mounted as master by specifying "-l C" without the quotes, or the drive as slave by specifying "-l D" + + cart.jrc (PCJr only) + When emulation of a PCJr is enabled, cartridges can be loaded with + the BOOT command. Support is still limited. IPX @@ -552,6 +566,10 @@ IPX For example, if your server is at bob.dosbox.com, you would type "IPXNET CONNECT bob.dosbox.com" on every non-server system. + To play games that need Netbios a file named NETBIOS.EXE from Novell is + needed. Establish the IPX connection as explained above, then run + "netbios.exe". + The following is an IPXNET command reference: IPXNET CONNECT @@ -582,6 +600,12 @@ IPX The syntax for IPXNET STARTSERVER is: IPXNET STARTSERVER + If the server is behind a router, UDP port needs to be forwarded + to that computer. + + On Linux/Unix-based systems port numbers smaller than 1023 can only be + used with root privileges. Use ports greater than 1023 on those systems. + IPXNET STOPSERVER IPXNET STOPSERVER stops the IPX tunnelling server running on this DOSBox @@ -607,8 +631,42 @@ IPX IPX tunnelling network. For a list of all computers connected to the network use the IPXNET PING command. -The syntax for IPXNET STATUS is: -IPXNET STATUS + The syntax for IPXNET STATUS is: + IPXNET STATUS + + +KEYB [languagecode [codepage [codepagefile]]] + Change the keyboard layout. For detailed information about keyboard + layouts please see Section 7. + + [languagecode] is a string consisting of two (in special cases more) + characters, examples are GK (Greece) or IT (Italy). It specifies + the keyboard layout to be used. + + [codepage] is the number of the codepage to be used. The keyboard layout + has to provide support for the specified codepage, otherwise the layout + loading will fail. + If no codepage is specified, an appropriate codepage for the requested + layout is chosen automatically. + + [codepagefile] can be used to load codepages that are yet not compiled + into DOSBox. This is only needed when DOSBox does not find the codepage. + + + Examples: + 1) To load the german keyboard layout (automatically uses codepage 858): + keyb gr + 2) To load the russian keyboard layout with codepage 866: + keyb ru 866 + In order to type russian characters press ALT+RIGHT-SHIFT. + 3) To load the french keyboard layout with codepage 850 (where the + codepage is defined in EGACPI.DAT): + keyb fr 850 EGACPI.DAT + 4) To load codepage 858 (without a keyboard layout): + keyb none 858 + This can be used to change the codepage for the freedos keyb2 utility. + + For more information use the /? command line switch with the programs. @@ -646,21 +704,22 @@ gets saved/recorded ! 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. +This maximum will vary from computer to computer. ============= -6. Keymapper: +6. Mapper: ============= -When you start the keymapper (either with CTRL-F1 or -startmapper as a -command line argument to the DOSBox executable) you are presented with -a virtual keyboard. +When you start the DOSBox mapper (either with CTRL-F1 or -startmapper as +a command line argument to the DOSBox executable) you are presented with +a virtual keyboard and a virtual joystick. -This virtual keyboard corresponds to the keys DOSBox will report to its -applications. If you click on a key with your mouse, you can see in the -lower left corner which key on your keyboard corresponds to it. +These virtual devices correspond to the keys DOSBox will report to the +DOS applications. If you click on a key with your mouse, you can see in +the lower left corner with which event it is associated (EVENT) and to +what events it is currently bound. Event: EVENT BIND: BIND @@ -671,22 +730,24 @@ mod3 EVENT - The key DOSBox will report to the applications being emulated. + The key or joystick axis/button/hat DOSBox will report to DOS applications. BIND - The key on your keyboard (as reported by SDL) which is connected to the - EVENT. + The key on your real keyboard or the axis/button/hat on your real + joystick(s) (as reported by SDL) which is connected to the EVENT. mod1,2,3 - Modfiers. These are keys you need to have pressed as well, while pressing - BIND. mod1 = CTRL and mod2 = ALT. These are generally only used when you + Modfiers. These are keys you need to have to be pressed while pressing + BIND. mod1 = CTRL and mod2 = ALT. These are generally only used when you want to change the special keys of DOSBox. Add - Add a new BIND to this EVENT. Basically add a key from your keyboard which - will produce the key EVENT in DOSBox. + Add a new BIND to this EVENT. Basically add a key from your keyboard or an + event from the joystick (button press, axis/hat movement) which will + produce the EVENT in DOSBox. Del - Delete the BIND to this EVENT. If an EVENT has no BINDS, then it's not - possible to type this key in DOSBox. + Delete the BIND to this EVENT. If an EVENT has no BINDS, then it is not + possible to trigger this event in DOSBox (that is there's no way to type + the key or use the respective action of the joystick). Next - Go through the list of keys(BINDS) which map to this EVENT. + Go through the list of bindings which map to this EVENT. Example: @@ -706,59 +767,195 @@ Q3. If you try it out in DOSBox, you will notice that pressing X makes ZX mapped key X. Click "Del". -If you change the default mapping, you can save your changes by pressing +Examples about remapping the joystick: + You have a joystick attached, it is working fine under DOSBox and you + want to play some keyboard-only game with the joystick (it is assumed + that the game is controlled by the arrows on the keyboard): + 1) Start the mapper, then klick on one of the arrows in the middle + of the left part of the screen (right above the Mod1/Mod2 buttons). + EVENT should be key_left. Now klick on Add and move your joystick + in the respective direction, this should add an event to the BIND. + 2) Repeat the above for the missing three directions, additionally + the buttons of the joystick can be remapped as well (fire/jump). + 3) Click on Save, then on Exit and test it with some game. + + You want to swap the y-axis of the joystick because some flightsim uses + the up/down joystick movement in a way you don't like, and it is not + configurable in the game itself: + 1) Start the mapper and klick on Y- in the upper joystick field (this + is for the first joystick if you have two joysticks attached) or the + lower joystick field (second joystick or, if you have only one + joystick attached, the second axes cross). + EVENT should be jaxis_0_1- (or jaxis_1_1-). + 2) Click on Del to remove the current binding, then klick Add and move + your joystick downwards. A new bind should be created. + 3) Repeat this for Y+, save the layout and finally test it with some game. + + + +If you change the default mapping, you can save your changes by clicking on "Save". DOSBox will save the mapping to a location specified in the configfile -(mapperfile=mapper.txt). At startup, DOSBox will load your mapperfile, if it's -present in the configfile. +(mapperfile=mapper.txt). At startup, DOSBox will load your mapperfile, if it +is present in the configfile. -======================= -7. System requirements: -======================= +==================== +7. Keyboard Layout: +==================== -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 - don't expect -them to run fast, though! Be sure to read the next section on how to speed -it up somewhat. +To switch to a different keyboard layout, either the entry "keyboardlayout" +in the [dos]-section in dosbox.conf can be used, or the internal DOSBox +program keyb.com. Both accept dos-conform language codes (see below), but +only by using keyb.com a custom codepage can be specified. + +Layout switching + DOSBox supports a number of keyboard layouts and codepages by default, + in this case just the layout identifier needs to be specified (like + keyboardlayout=sv in the DOSBox config file, or using "keyb sv" at + the DOSBox command prompt). + + Internally supported keyboard layouts: + BG (Bulgaria), CZ243 (Czech Republic), FR (France), GK (Greece), + GR (Germany), HR (Croatia), HU (Hungary), IT (Italy), NL (Netherlands), + NO (Norway), PL (Poland), RU (Russian Federation), SK (Slovakia), SP (Spain), + SU (Finland), SV (Sweden) + + When a keyboard layout is loaded, it is possible to switch between the + foreign layout and the US-layout by pressing CTRL+ALT+F2. + Some keyboard layouts (for example layout GK codepage 869 and layout RU + codepage 808) have support for dual-layouts that can be activated by + pressing LEFT-ALT+RIGHT-SHIFT and deactivated by LEFT-ALT+LEFT-SHIFT. + +Supported external files + The freedos .kl files are supported (freedos keyb2 keyboard layoutfiles) as + well as the freedos keyboard.sys/keybrd2.sys/keybrd3.sys libraries which + consist of all available .kl files. + See http://projects.freedos.net/keyb/ for precompiled keyboard layouts. + + Both .CPI (MSDOS/compatible codepage files) and .CPX (freedos UPX-compressed + codepage files) can be used. Some codepages are compiled into DOSBox so it + is mostly not needed to care about external codepage files. If you need + a different (or custom) codepage file, copy it into the directory of the + DOSBox configuration file so it is accessible for DOSBox. + + Additional layouts can be added by copying the corresponding .kl-file into + the directory of dosbox.conf and using the first part of the filename as + language code. + Example: For the file UZ.KL (keyboard layout for Uzbekistan) specify + "keyboardlayout=uz" in dosbox.conf. + + +Note that the keyboard layout allows foreign characters to be entered, but +there is NO support for them in filenames. Try to avoid them both inside +DOSBox as well as in files on your host operating system that are accessible +by DOSBox. + + + +============================== +8. Serial Multiplayer feature: +============================== + +DOSBox can emulate a serial nullmodem cable over network and internet. +It can be configured through the [serialports] section in the DOSBox +configuration file. + +To create a nullmodem connection, one side needs to act as the server and +one as the client. + +The server needs to be set up in the DOSBox configuration file like this: + serial1=nullmodem + +The client: + serial1=nullmodem server: + +Now start your game and choose nullmodem / serial cable / already connected +as multiplayer method on COM1. Set the same baudrate on both computers. + +Furthermore, additional parameters can be specified to control the behavior +of the nullmodem connection. These are all parameters: + + * port: - TCP port number. Default: 23 + * rxdelay: - how long (milliseconds) to delay received data if the + interface is not ready. Increase this value if you encounter + overrun errors in the DOSBox Status Window. Default: 100 + * txdelay: - how long to gather data before sending a packet. Default: 12 + (reduces Network overhead) + * server: - This nullmodem will be a client connecting to the specified + server. (No server argument: be a server.) + * transparent:1 - Only send the serial data, no RTS/DTR handshake. Use this + when connecting to anyting other than a nullmodem. + * telnet:1 - Interpret Telnet data from the remote site. Automatically + sets transparent. + * usedtr:1 - The connection will not be established until DTR is switched + on by the DOS program. Useful for modem terminals. + Automatically sets transparent. + * inhsocket:1 - Use a socket passed to DOSBox by command line. Automatically + sets transparent. (Socket Inheritance: It is used for + playing old DOS door games on new BBS software.) + +Example: Be a server listening on TCP port 5000. + serial1=nullmodem server: port:5000 rxdelay:1000 =================================== -8. To run resource-demanding games: +9. To run resource-demanding games: =================================== -DOSBox emulates the CPU, the sound and graphic cards, and some other -stuff, all at the same time. You can overclock DOSBox by using CTRL-F12, but -you'll be limited by the power of your actual CPU. You can see how much free -time your true CPU has by looking at the Task Manager in Windows 2000/XP and -the System Monitor in Windows 95/98/ME. Once 100% of your real CPU time is -used there is no further way to speed up DOSBox unless you reduce the load -generated by the non-CPU parts of DOSBox. +DOSBox emulates the CPU, the sound and graphic cards, and other peripherals +of a PC, all at the same time. The speed of an emulated DOS application +depends on how many instructions can be emulated, which is adjustable +(number of cycles). -So: +CPU Cycles + By default (cycles=auto) DOSBox tries to detect whether a game needs to + be run with as many instructions emulated per time interval as possible. + You can force this behaviour by setting cycles=max in the DOSBox + configuration file. The DOSBox window will display a line "Cpu Cyles: max" + at the top then. In this mode you can reduce the amount of cycles on a + percentage-basis (hit CTRL-F11) or raise it again (CTRL-F12). + + Sometimes customly setting the number of cycles achieves better results, + in the DOSBox configuration file specify for example cycles=30000. When + running some DOS application you can raise the cycles with CTRL-F12 even + more, but you will be limited by the power of your actual CPU. You can see + how much free time your true CPU has by looking at the Task Manager in + Windows 2000/XP and the System Monitor in Windows 95/98/ME. Once 100% of + your real CPU time is used there is no further way to speed up DOSBox + unless you reduce the load generated by the non-CPU parts of DOSBox. -Close every program but DOSBox +CPU Cores + On x86 architectures you can try to force the usage of a dynamically + recompiling core (set core=dynamic in the DOSBox configuration file). + This usually gives better results if the auto detection (core=auto) fails. + It is best accompanied by cycles=max. Note that there might be games + that work worse with the dynamic core, or do not work at all! -Overclock DOSBox until 100% of your CPU is used (use the utilities above to -check) +Graphics emulation + VGA emulation is a very demanding part of DOSBox in terms of actual CPU + usage. Increase the number of frames skipped (in increments of one) by + pressing CTRL-F8. Your CPU usage should decrease when using a fixed + cycle setting. + 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. -Since VGA emulation is the most demanding part of DOSBox in terms of actual -CPU usage, we'll start there. 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 +Sound emulation + You can also try to disable the sound through the setup utility of the game + to reduce load on your CPU further. Setting nosound=true does NOT disable + the emulation of sound devices, just the sound output will be disabled. -You can also try to disable the sound through the setup utility of the game -to reduce load on your CPU further. +Also try to close every program but DOSBox to reserve as much resources +as possible for DOSBox. -=================== -9. The Config File: -=================== + +==================== +10. The Config File: +==================== A config file can be generated by CONFIG.COM, which can be found on the internal dosbox Z: drive when you start up dosbox. Look in the internal @@ -780,7 +977,7 @@ look in the current directory for dosbox.conf. ====================== -10. The Language File: +11. The Language File: ====================== A language file can be generated by CONFIG.COM. @@ -792,7 +989,7 @@ section. There's a language= entry that can be changed with the filename. ======================================== -11. Building your own version of DOSBox: +12. Building your own version of DOSBox: ======================================== Download the source. @@ -801,7 +998,7 @@ Check the INSTALL in the source distribution. =================== -12. Special Thanks: +13. Special Thanks: =================== Vlad R. of the VDMSound project for excellent SoundBlaster info. @@ -815,7 +1012,7 @@ The Beta Testers. ============ -13. Contact: +14. Contact: ============ See the site: From bc0a6460acfbc09e535bbb3cc297ac3e32699969 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 13 Jan 2007 09:57:25 +0000 Subject: [PATCH 2675/4131] Keeping the timer more in sync.(h-a-l-9000) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2760 --- src/hardware/timer.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index dd1cbf97..78256d8f 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.41 2007-01-08 19:45:40 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.42 2007-01-13 09:57:25 qbix79 Exp $ */ #include #include "dosbox.h" @@ -66,8 +66,9 @@ static bool latched_timerstatus_locked; static void PIT0_Event(Bitu /*val*/) { PIC_ActivateIRQ(0); if (pit[0].mode != 0) { - pit[0].start = PIC_FullIndex()-pit[0].delay; // resynchronize - PIC_AddEvent(PIT0_Event,pit[0].delay); + pit[0].start += pit[0].delay; + double error = pit[0].start - PIC_FullIndex(); + PIC_AddEvent(PIT0_Event,pit[0].delay + error); } } @@ -112,6 +113,7 @@ static void status_latch(Bitu counter) { else if(p->read_state==1) latched_timerstatus|=0x10; else if(p->read_state==2) latched_timerstatus|=0x20; if(counter_output(counter)) latched_timerstatus|=0x80; + if(p->new_mode) latched_timerstatus|=0x40; // The first thing that is being read from this counter now is the // counter status. p->counterstatus_set=true; From 29a8ba31c166b1d467625506738e2cc10977fd9f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 13 Jan 2007 09:58:26 +0000 Subject: [PATCH 2676/4131] change startup message a bit. (suggestions by Red_Avatar) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2761 --- src/shell/shell.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 5b2ccb2d..4707419e 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.80 2007-01-10 09:04:33 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.81 2007-01-13 09:58:26 qbix79 Exp $ */ #include #include @@ -456,10 +456,11 @@ void SHELL_Init() { "\033[44;1m\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n" - "\xBA \033[32mDOSBox Shell v" VERSION "\033[37m \xBA\n" - "\xBA DOSBox runs real and protected mode games. \xBA\n" + "\xBA \033[32mWelcome to DOSBox v" VERSION "\033[37m \xBA\n" + "\xBA \xBA\n" +// "\xBA DOSBox runs real and protected mode games. \xBA\n" + "\xBA For a short introduction for new users type: \033[33mINTRO\033[37m \xBA\n" "\xBA For supported shell commands type: \033[33mHELP\033[37m \xBA\n" - "\xBA For a short introduction type: \033[33mINTRO\033[37m \xBA\n" "\xBA \xBA\n" "\xBA If you want more speed, try \033[31mctrl-F8\033[37m and \033[31mctrl-F12\033[37m. \xBA\n" "\xBA To activate the keymapper \033[31mctrl-F1\033[37m. \xBA\n" From c05b3e6810f7473d7210a290048a32bf5860c8f3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 13 Jan 2007 10:17:39 +0000 Subject: [PATCH 2677/4131] Make some compilers more happy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2762 --- src/hardware/serialport/misc_util.cpp | 5 +++-- src/hardware/serialport/misc_util.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hardware/serialport/misc_util.cpp b/src/hardware/serialport/misc_util.cpp index 84ee29d3..e32841d4 100644 --- a/src/hardware/serialport/misc_util.cpp +++ b/src/hardware/serialport/misc_util.cpp @@ -1,7 +1,5 @@ #include "config.h" -#include "misc_util.h" - #if C_MODEM /*****************************************************************************/ @@ -24,6 +22,9 @@ typedef int socklen_t; #define CAPWORD NETWRAPPER_TCP #endif +#include "misc_util.h" + + struct _TCPsocketX { int ready; SOCKET channel; diff --git a/src/hardware/serialport/misc_util.h b/src/hardware/serialport/misc_util.h index 62f8809d..0c0122f1 100644 --- a/src/hardware/serialport/misc_util.h +++ b/src/hardware/serialport/misc_util.h @@ -27,7 +27,7 @@ class TCPClientSocket { TCPClientSocket(TCPsocket source); TCPClientSocket(const char* destination, Bit16u port); #ifdef NATIVESOCKETS - void* nativetcpstruct; + Bit8u* nativetcpstruct; TCPClientSocket(int platformsocket); #endif ~TCPClientSocket(); From 1d3b064824cdc71bcb554da1a31b58dc44d65a28 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 13 Jan 2007 10:43:40 +0000 Subject: [PATCH 2678/4131] add io delay patch from h-al-9000 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2763 --- src/hardware/iohandler.cpp | 50 ++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index b6778cf8..ce1ba9c2 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: iohandler.cpp,v 1.23 2007-01-08 19:45:40 qbix79 Exp $ */ +/* $Id: iohandler.cpp,v 1.24 2007-01-13 10:43:40 qbix79 Exp $ */ #include #include "dosbox.h" @@ -162,6 +162,34 @@ static Bits IOFaultCore(void) { return 0; } + +/* Some code to make io operations take some virtual time. Helps certain + * games with their timing of certain operations + */ + +extern Bit32s CPU_CycleMax; + +#define IODELAY_READ_MICROS 1.0 +#define IODELAY_WRITE_MICROS 0.75 + +inline void IO_USEC_read_delay() { + if(CPU_CycleMax > static_cast((IODELAY_READ_MICROS*1000.0))) { + // this could be calculated whenever CPU_CycleMax changes + Bitu delaycyc = static_cast((CPU_CycleMax/1000)*IODELAY_READ_MICROS); + if(CPU_Cycles > delaycyc) CPU_Cycles -= delaycyc; + else CPU_Cycles = 0; + } +} + +inline void IO_USEC_write_delay() { + if(CPU_CycleMax > static_cast((IODELAY_WRITE_MICROS*1000.0))) { + // this could be calculated whenever CPU_CycleMax changes + Bitu delaycyc = static_cast((CPU_CycleMax/1000)*IODELAY_WRITE_MICROS); + if(CPU_Cycles > delaycyc) CPU_Cycles -= delaycyc; + else CPU_Cycles = 0; + } +} + void IO_WriteB(Bitu port,Bitu val) { if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,1)))) { LazyFlags old_lflags; @@ -192,7 +220,10 @@ void IO_WriteB(Bitu port,Bitu val) { memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); cpudecoder=old_cpudecoder; } - else io_writehandlers[0][port](port,val,1); + else { + IO_USEC_write_delay(); + io_writehandlers[0][port](port,val,1); + } }; void IO_WriteW(Bitu port,Bitu val) { @@ -225,7 +256,10 @@ void IO_WriteW(Bitu port,Bitu val) { memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); cpudecoder=old_cpudecoder; } - else io_writehandlers[1][port](port,val,2); + else { + IO_USEC_write_delay(); + io_writehandlers[1][port](port,val,2); + } }; void IO_WriteD(Bitu port,Bitu val) { @@ -291,7 +325,10 @@ Bitu IO_ReadB(Bitu port) { cpudecoder=old_cpudecoder; return retval; } - else return io_readhandlers[0][port](port,1); + else { + IO_USEC_read_delay(); + return io_readhandlers[0][port](port,1); + } }; Bitu IO_ReadW(Bitu port) { @@ -324,7 +361,10 @@ Bitu IO_ReadW(Bitu port) { cpudecoder=old_cpudecoder; return retval; } - else return io_readhandlers[1][port](port,2); + else { + IO_USEC_read_delay(); + return io_readhandlers[1][port](port,2); + } }; Bitu IO_ReadD(Bitu port) { From d3cb9bd1b83971e37df108c080300e2ba1706c00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 14 Jan 2007 18:44:01 +0000 Subject: [PATCH 2679/4131] different PCJr cart loading supported Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2764 --- include/bios.h | 2 + src/dos/dos_programs.cpp | 206 ++++++++++++++++++++++++++++++++++----- src/hardware/memory.cpp | 9 +- src/ints/bios_disk.cpp | 3 +- 4 files changed, 194 insertions(+), 26 deletions(-) diff --git a/include/bios.h b/include/bios.h index 39b06531..66b09ba4 100644 --- a/include/bios.h +++ b/include/bios.h @@ -107,6 +107,8 @@ /* 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 */ diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 76f9c5af..285c5baf 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.64 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.65 2007-01-14 18:44:01 c2woody Exp $ */ #include #include @@ -356,7 +356,7 @@ extern Bit32u floppytype; class BOOT : public Program { private: - FILE *getFSFile(Bit8u * filename, Bit32u *ksize, Bit32u *bsize) { + FILE *getFSFile(Bit8u * filename, Bit32u *ksize, Bit32u *bsize,bool tryload=false) { Bit8u drive; FILE *tmpfile; char fullname[DOS_PATHLENGTH]; @@ -370,13 +370,13 @@ private: tmpfile = ldp->GetSystemFilePtr(fullname, "r"); if(tmpfile == NULL) { - WriteOut(MSG_Get("PROGRAM_BOOT_NOT_EXIST")); + if (!tryload) WriteOut(MSG_Get("PROGRAM_BOOT_NOT_EXIST")); return NULL; } fclose(tmpfile); tmpfile = ldp->GetSystemFilePtr(fullname, "rb+"); if(tmpfile == NULL) { - WriteOut(MSG_Get("PROGRAM_BOOT_NOT_OPEN")); + if (!tryload) WriteOut(MSG_Get("PROGRAM_BOOT_NOT_OPEN")); return NULL; } @@ -411,10 +411,14 @@ private: public: void Run(void) { - FILE *usefile; + FILE *usefile_1=NULL; + FILE *usefile_2=NULL; Bitu i; - Bit32u floppysize, rombytesize; + Bit32u floppysize; + Bit32u rombytesize_1=0; + Bit32u rombytesize_2=0; Bit8u drive; + std::string cart_cmd=""; if(!cmd->GetCount()) { printError(); @@ -442,12 +446,33 @@ public: continue; } + if((temp_line == "-e") || (temp_line == "-E")) { + /* Command mode for PCJr cartridges */ + i++; + if(cmd->FindCommand(i+1, temp_line)) { + for(size_t i=0;i0x1000) break; + clen=rombuf[ct]; + } + if (ct>6) { + WriteOut(MSG_Get("PROGRAM_BOOT_CART_LIST_CMDS"),cmdlist); + } else { + WriteOut(MSG_Get("PROGRAM_BOOT_CART_NO_CMDS")); + } + for(Bitu dct=0;dct0x1000) break; + clen=rombuf[ct]; + } + if (cfound_at<=0) { + if (ct>6) { + WriteOut(MSG_Get("PROGRAM_BOOT_CART_LIST_CMDS"),cmdlist); + } else { + WriteOut(MSG_Get("PROGRAM_BOOT_CART_NO_CMDS")); + } + for(Bitu dct=0;dct0) { + /* run cartridge setup */ + SegSet16(ds,dos.psp()); + SegSet16(es,dos.psp()); + CALLBACK_RunRealFar(romseg,cfound_at); + } else { + for(Bitu dct=0;dct Date: Sun, 14 Jan 2007 20:26:34 +0000 Subject: [PATCH 2680/4131] Some entries Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2765 --- ChangeLog | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/ChangeLog b/ChangeLog index 4608e009..be164c7f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,60 @@ +0.66 + - Improve register handling and support with XMS. + - Fix some issues with deleting open files.(windows only issue) + - Add dummpy 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 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. + - Dynamic core supports io exceptions. + - Move some interrupt handlers to XT Bios locations. + - Add a dynamic fpu on x86. + - Improve fpu on non-x86. + - Fix a 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 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-eses. + - 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. + - Try to reduce the impact of using an analog joystick. + - Make dynamic core handle certain types of self modifying code. + - 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. + - Change configuration file loading support. It now supports + multiple configuration files. + - Make dynamic core capable of running some win32s programs. + - Make soundblaster installation under windows much easier. + - Add device control channel handling. (GEMMIS support (ems under windows)) + - Support more colours in win 3. + - Don't show unmounted drives in windows filemanager. + - Many timer improvements. + - Some pcjr fixes. + - Some booter fixes. + - Many small fixes. + 0.65 - Fixed FAT writing. - Added some more missing DOS functions. From 961a49cd49dcc578fa8508fe7f4beab6c2e8f933 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 14 Jan 2007 21:00:32 +0000 Subject: [PATCH 2681/4131] updates suggested by wd Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2766 --- ChangeLog | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index be164c7f..f97f92f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,7 +12,7 @@ - Move some interrupt handlers to XT Bios locations. - Add a dynamic fpu on x86. - Improve fpu on non-x86. - - Fix a rarely used character functions. + - Fix a few rarely used character functions. - Improve auto cycle guessing code. - Improve and extend the joystick support. - Add autofire support. @@ -24,12 +24,12 @@ - Improve MSCDEX. - Improve dynamic core support under intel macs. - Add basic support for clipper programs. - - Add support for different keyboard layouts + - Add support for different keyboard layouts. - Add auto core guessing. - 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-eses. + - 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. @@ -38,7 +38,7 @@ - Improve DOS functions when dealing with virtual drive. - Improve FAT drives. - Try to reduce the impact of using an analog joystick. - - Make dynamic core handle certain types of self modifying code. + - Make dynamic core handle more types of self modifying code. - A few small mouse improvements. (some games are using things they shouldn't) - Add nullmodem emulation.(h-a-l-9000) @@ -47,7 +47,8 @@ multiple configuration files. - Make dynamic core capable of running some win32s programs. - Make soundblaster installation under windows much easier. - - Add device control channel handling. (GEMMIS support (ems under windows)) + - Add device control channel handling. + - GEMMIS support (ems under windows) - Support more colours in win 3. - Don't show unmounted drives in windows filemanager. - Many timer improvements. From 20222d628d000b13808cbffbebd693d977ddddee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 14 Jan 2007 21:50:28 +0000 Subject: [PATCH 2682/4131] lower kl temporary memory size used during decompression Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2767 --- src/dos/dos_keyboard_layout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 9fc70a92..84459d3a 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -799,7 +799,7 @@ Bitu keyboard_layout::read_codepage_file(const char* codepage_file_name, Bit32s cpi_buf[found_at_pos]=0xcb; Bit16u seg=0; - Bit16u size=0x2000; + Bit16u size=0x1500; if (!DOS_AllocateMemory(&seg,&size)) E_Exit("Not enough free low memory to unpack data"); MEM_BlockWrite((seg<<4)+0x100,cpi_buf,size_of_cpxdata); From 6296e3fff4cb9e92061e3d520dacac8c9abd6df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 18 Jan 2007 14:29:48 +0000 Subject: [PATCH 2683/4131] remove some debugging aid in non-debug mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2768 --- src/cpu/cpu.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 53b01ec9..b8fa7255 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.94 2007-01-13 08:35:49 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.95 2007-01-18 14:29:48 c2woody Exp $ */ #include #include "dosbox.h" @@ -450,8 +450,9 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { #if C_HEAVY_DEBUG LOG(LOG_CPU,LOG_ERROR)("Call to interrupt 0xCD this is BAD"); DEBUG_HeavyWriteLogInstruction(); -#endif E_Exit("Call to interrupt 0xCD this is BAD"); +#endif + break; case 0x03: if (DEBUG_Breakpoint()) { CPU_Cycles=0; From 76f1d11252a5772441ee92eaf03e29f0be4f8ae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 18 Jan 2007 14:57:59 +0000 Subject: [PATCH 2684/4131] avoid code invalidation on certain types of self modification and adjust cache sizes (dynamic core); add partial memory function inlining for dynamic core memory access; remove a float div in the pic Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2769 --- include/pic.h | 4 + src/cpu/core_dyn_x86.cpp | 22 +- src/cpu/core_dyn_x86/cache.h | 92 ++++- src/cpu/core_dyn_x86/decoder.h | 648 ++++++++++++++++++++++++++++++-- src/cpu/core_dyn_x86/risc_x86.h | 121 ++++-- src/hardware/pic.cpp | 8 +- 6 files changed, 815 insertions(+), 80 deletions(-) diff --git a/include/pic.h b/include/pic.h index 47bb2a56..4d37dedb 100644 --- a/include/pic.h +++ b/include/pic.h @@ -40,6 +40,10 @@ INLINE float PIC_TickIndex(void) { return (CPU_CycleMax-CPU_CycleLeft-CPU_Cycles)/(float)CPU_CycleMax; } +INLINE Bits PIC_TickIndexND(void) { + return CPU_CycleMax-CPU_CycleLeft-CPU_Cycles; +} + INLINE Bits PIC_MakeCycles(double amount) { return (Bits)(CPU_CycleMax*amount); } diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 7e50cfb3..ebfa816b 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -46,8 +46,8 @@ #include "fpu.h" #define CACHE_MAXSIZE (4096*2) -#define CACHE_PAGES (128*8) -#define CACHE_TOTAL (CACHE_PAGES*4096) +#define CACHE_TOTAL (1024*1024*8) +#define CACHE_PAGES (512) #define CACHE_BLOCKS (64*1024) #define CACHE_ALIGN (16) #define DYN_HASH_SHIFT (4) @@ -161,7 +161,8 @@ static void IllegalOption(const char* msg) { #include "core_dyn_x86/cache.h" static struct { - Bitu callback,readdata; + Bitu callback; + Bit32u readdata; } core_dyn; struct { @@ -273,7 +274,20 @@ restart_core: /* Find correct Dynamic Block to run */ CacheBlock * block=chandler->FindCacheBlock(ip_point&4095); if (!block) { - block=CreateCacheBlock(chandler,ip_point,32); + 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; diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index ecee1b9e..41512c32 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -28,7 +28,6 @@ public: CacheBlock * crossblock; }; -class CacheBlock; static struct { struct { CacheBlock * first; @@ -44,9 +43,11 @@ static struct { static CacheBlock link_blocks[2]; -class CodePageHandler :public PageHandler { +class CodePageHandler : public PageHandler { public: - CodePageHandler() {} + CodePageHandler() { + invalidation_map=NULL; + } void SetupAt(Bitu _phys_page,PageHandler * _old_pagehandler) { phys_page=_phys_page; old_pagehandler=_old_pagehandler; @@ -56,6 +57,10 @@ public: 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+(start>>DYN_HASH_SHIFT); @@ -81,69 +86,114 @@ public: } 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(); - } else InvalidateRange(addr,addr); + 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(); - } else InvalidateRange(addr,addr+1); + 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(); - } else InvalidateRange(addr,addr+3); + 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 (InvalidateRange(addr,addr)) { - cpu.exception.which=SMC_CURRENT_BLOCK; - return true; + } 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 (InvalidateRange(addr,addr+1)) { - cpu.exception.which=SMC_CURRENT_BLOCK; - return true; + } 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 (InvalidateRange(addr,addr+3)) { - cpu.exception.which=SMC_CURRENT_BLOCK; - return true; + } 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; @@ -216,6 +266,7 @@ public: } public: Bit8u write_map[4096]; + Bit8u * invalidation_map; CodePageHandler * next, * prev; private: PageHandler * old_pagehandler; @@ -460,7 +511,16 @@ static void cache_init(bool enable) { } static void cache_close(void) { -/* if (cache_blocks != NULL) { +/* 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; } diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 10973317..35cdd147 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -17,6 +17,8 @@ */ #define X86_DYNFPU_DH_ENABLED +#define X86_INLINED_MEMACCESS + enum REP_Type { REP_NONE=0,REP_NZ,REP_Z @@ -36,6 +38,7 @@ static struct DynDecode { CodePageHandler * code; Bitu index; Bit8u * wmap; + Bit8u * invmap; Bitu first; } page; struct { @@ -48,7 +51,7 @@ static struct DynDecode { } decode; static Bit8u decode_fetchb(void) { - if (decode.page.index>=4096) { + if (GCC_UNLIKELY(decode.page.index>=4096)) { /* Advance to the next page */ decode.active_block->page.end=4095; /* trigger possible page fault here */ @@ -61,6 +64,7 @@ static Bit8u decode_fetchb(void) { decode.active_block->page.start=0; decode.page.code->AddCrossBlock(decode.active_block); decode.page.wmap=decode.page.code->write_map; + decode.page.invmap=decode.page.code->invalidation_map; decode.page.index=0; } decode.page.wmap[decode.page.index]+=0x01; @@ -69,7 +73,7 @@ static Bit8u decode_fetchb(void) { return mem_readb(decode.code-1); } static Bit16u decode_fetchw(void) { - if (decode.page.index>=4095) { + if (GCC_UNLIKELY(decode.page.index>=4095)) { Bit16u val=decode_fetchb(); val|=decode_fetchb() << 8; return val; @@ -79,7 +83,7 @@ static Bit16u decode_fetchw(void) { return mem_readw(decode.code-2); } static Bit32u decode_fetchd(void) { - if (decode.page.index>=4093) { + if (GCC_UNLIKELY(decode.page.index>=4093)) { Bit32u val=decode_fetchb(); val|=decode_fetchb() << 8; val|=decode_fetchb() << 16; @@ -92,6 +96,46 @@ static Bit32u decode_fetchd(void) { return mem_readd(decode.code-4); } +static bool decode_fetchb_imm(Bitu & val) { + if (decode.page.index<4096) { + Bitu index=(decode.code>>12); + if (paging.tlb.read[index]) { + val=(Bitu)(paging.tlb.read[index]+decode.code); + decode.code++; + decode.page.index++; + return true; + } + } + val=(Bit32u)decode_fetchb(); + return false; +} +static bool decode_fetchw_imm(Bitu & val) { + if (decode.page.index<4095) { + Bitu index=(decode.code>>12); + if (paging.tlb.read[index]) { + val=(Bitu)(paging.tlb.read[index]+decode.code); + decode.code+=2; + decode.page.index+=2; + return true; + } + } + val=decode_fetchw(); + return false; +} +static bool decode_fetchd_imm(Bitu & val) { + if (decode.page.index<4093) { + Bitu index=(decode.code>>12); + if (paging.tlb.read[index]) { + val=(Bitu)(paging.tlb.read[index]+decode.code); + decode.code+=4; + decode.page.index+=4; + return true; + } + } + val=decode_fetchd(); + return false; +} + static void dyn_reduce_cycles(void) { gen_protectflags(); @@ -204,6 +248,17 @@ static void dyn_check_irqrequest(void) { used_save_info++; } +static void dyn_check_bool_exception_ne(void) { + save_info[used_save_info].branch_pos=gen_create_branch_long(BR_Z); + dyn_savestate(&save_info[used_save_info].state); + if (!decode.cycles) decode.cycles++; + save_info[used_save_info].cycles=decode.cycles; + save_info[used_save_info].eip_change=decode.op_start-decode.code_start; + if (!cpu.code.big) save_info[used_save_info].eip_change&=0xffff; + save_info[used_save_info].type=exception; + used_save_info++; +} + static void dyn_fill_blocks(void) { for (Bitu sct=0; sctgenreg) { + // addr already in a register + Bit8u reg_idx=(Bit8u)addr->genreg->index; + x86gen.regs[X86_REG_ECX]->Clear(); + if (reg_idx!=1) { + cache_addw(0xc88b+(reg_idx<<8)); //Mov ecx,reg + } + x86gen.regs[X86_REG_EAX]->Clear(); + if (release_addr) gen_releasereg(addr); + } else { + // addr still in memory, directly move into ecx + x86gen.regs[X86_REG_EAX]->Clear(); + x86gen.regs[X86_REG_ECX]->Clear(); + cache_addw(0x0d8b); //Mov ecx,[data] + cache_addd((Bit32u)addr->data); + } + x86gen.regs[X86_REG_EDX]->Clear(); + + cache_addw(0xc18b); // mov eax,ecx +} + +bool mem_readb_checked_x86x(PhysPt address) { + Bitu index=(address>>12); + Bitu uval; + bool retval; + retval=paging.tlb.handler[index]->readb_checked(address, &uval); + core_dyn.readdata=(Bit8u)uval; + return retval; +} + +static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { + dyn_read_intro(addr,false); + + cache_addw(0xe8c1); // shr eax,0x0c + cache_addb(0x0c); + cache_addw(0x048b); // mov eax,paging.tlb.read[eax*TYPE Bit32u] + cache_addb(0x85); + cache_addd((Bit32u)(&paging.tlb.read[0])); + cache_addw(0xc085); // test eax,eax + Bit8u* je_loc=gen_create_branch(BR_Z); + + + cache_addw(0x048a); // mov al,[eax+ecx] + cache_addb(0x08); + + Bit8u* jmp_loc=gen_create_jump(); + gen_fill_branch(je_loc); + cache_addb(0x51); // push ecx + cache_addb(0xe8); + cache_addd(((Bit32u)&mem_readb_checked_x86x) - (Bit32u)cache.pos-4); + cache_addw(0xc483); // add esp,4 + cache_addb(0x04); + cache_addw(0x012c); // sub al,1 + + dyn_check_bool_exception_ne(); + + cache_addw(0x058a); //mov al,[] + cache_addd((Bit32u)(&core_dyn.readdata)); + + gen_fill_jump(jmp_loc); + + x86gen.regs[X86_REG_EAX]->notusable=true; + GenReg * genreg=FindDynReg(dst); + x86gen.regs[X86_REG_EAX]->notusable=false; + cache_addw(0xc08a+(genreg->index<<11)+(high?0x2000:0)); + dst->flags|=DYNFLG_CHANGED; +} + +static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) { + dyn_read_intro(addr); + + cache_addw(0xe8c1); // shr eax,0x0c + cache_addb(0x0c); + cache_addw(0x048b); // mov eax,paging.tlb.read[eax*TYPE Bit32u] + cache_addb(0x85); + cache_addd((Bit32u)(&paging.tlb.read[0])); + cache_addw(0xc085); // test eax,eax + Bit8u* je_loc=gen_create_branch(BR_Z); + + + cache_addw(0x048a); // mov al,[eax+ecx] + cache_addb(0x08); + + Bit8u* jmp_loc=gen_create_jump(); + gen_fill_branch(je_loc); + cache_addb(0x51); // push ecx + cache_addb(0xe8); + cache_addd(((Bit32u)&mem_readb_checked_x86x) - (Bit32u)cache.pos-4); + cache_addw(0xc483); // add esp,4 + cache_addb(0x04); + cache_addw(0x012c); // sub al,1 + + dyn_check_bool_exception_ne(); + + cache_addw(0x058a); //mov al,[] + cache_addd((Bit32u)(&core_dyn.readdata)); + + gen_fill_jump(jmp_loc); + + x86gen.regs[X86_REG_EAX]->notusable=true; + GenReg * genreg=FindDynReg(dst); + x86gen.regs[X86_REG_EAX]->notusable=false; + cache_addw(0xc08a+(genreg->index<<11)+(high?0x2000:0)); + dst->flags|=DYNFLG_CHANGED; +} + +bool mem_readd_checked_x86x(PhysPt address) { + if ((address & 0xfff)<0xffd) { + Bitu index=(address>>12); + if (paging.tlb.read[index]) { + core_dyn.readdata=host_readd(paging.tlb.read[index]+address); + return false; + } else { + Bitu uval; + bool retval; + retval=paging.tlb.handler[index]->readd_checked(address, &uval); + core_dyn.readdata=(Bit32u)uval; + return retval; + } + } else return mem_unalignedreadd_checked_x86(address, &core_dyn.readdata); +} + +static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) { + if (dword) { + dyn_read_intro(addr,false); + + cache_addw(0xe8d1); // shr eax,0x1 + Bit8u* jb_loc1=gen_create_branch(BR_B); + cache_addw(0xe8d1); // shr eax,0x1 + Bit8u* jb_loc2=gen_create_branch(BR_B); + cache_addw(0xe8c1); // shr eax,0x0a + cache_addb(0x0a); + cache_addw(0x048b); // mov eax,paging.tlb.read[eax*TYPE Bit32u] + cache_addb(0x85); + cache_addd((Bit32u)(&paging.tlb.read[0])); + cache_addw(0xc085); // test eax,eax + Bit8u* je_loc=gen_create_branch(BR_Z); + + GenReg * genreg=FindDynReg(dst,true); + + cache_addw(0x048b+(genreg->index <<(8+3))); // mov dest,[eax+ecx] + cache_addb(0x08); + + Bit8u* jmp_loc=gen_create_jump(); + gen_fill_branch(jb_loc1); + gen_fill_branch(jb_loc2); + gen_fill_branch(je_loc); + cache_addb(0x51); // push ecx + cache_addb(0xe8); + cache_addd(((Bit32u)&mem_readd_checked_x86x) - (Bit32u)cache.pos-4); + cache_addw(0xc483); // add esp,4 + cache_addb(0x04); + cache_addw(0x012c); // sub al,1 + + dyn_check_bool_exception_ne(); + + gen_mov_host(&core_dyn.readdata,dst,4); + dst->flags|=DYNFLG_CHANGED; + + gen_fill_jump(jmp_loc); + } else { + gen_protectflags(); + gen_call_function((void *)&mem_readw_checked_x86,"%Dd%Id",addr,&core_dyn.readdata); + dyn_check_bool_exception_al(); + gen_mov_host(&core_dyn.readdata,dst,2); + } +} + +static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) { + if (dword) { + dyn_read_intro(addr); + + cache_addw(0xe8d1); // shr eax,0x1 + Bit8u* jb_loc1=gen_create_branch(BR_B); + cache_addw(0xe8d1); // shr eax,0x1 + Bit8u* jb_loc2=gen_create_branch(BR_B); + cache_addw(0xe8c1); // shr eax,0x0a + cache_addb(0x0a); + cache_addw(0x048b); // mov eax,paging.tlb.read[eax*TYPE Bit32u] + cache_addb(0x85); + cache_addd((Bit32u)(&paging.tlb.read[0])); + cache_addw(0xc085); // test eax,eax + Bit8u* je_loc=gen_create_branch(BR_Z); + + GenReg * genreg=FindDynReg(dst,true); + + cache_addw(0x048b+(genreg->index <<(8+3))); // mov dest,[eax+ecx] + cache_addb(0x08); + + Bit8u* jmp_loc=gen_create_jump(); + gen_fill_branch(jb_loc1); + gen_fill_branch(jb_loc2); + gen_fill_branch(je_loc); + cache_addb(0x51); // push ecx + cache_addb(0xe8); + cache_addd(((Bit32u)&mem_readd_checked_x86x) - (Bit32u)cache.pos-4); + cache_addw(0xc483); // add esp,4 + cache_addb(0x04); + cache_addw(0x012c); // sub al,1 + + dyn_check_bool_exception_ne(); + + gen_mov_host(&core_dyn.readdata,dst,4); + dst->flags|=DYNFLG_CHANGED; + + gen_fill_jump(jmp_loc); + } else { + gen_protectflags(); + gen_call_function((void *)&mem_readw_checked_x86,"%Ddr%Id",addr,&core_dyn.readdata); + dyn_check_bool_exception_al(); + gen_mov_host(&core_dyn.readdata,dst,2); + } +} + +static void dyn_write_intro(DynReg * addr,bool release_addr=true) { + gen_protectflags(); + + if (addr->genreg) { + // addr in a register + Bit8u reg_idx_addr=(Bit8u)addr->genreg->index; + + x86gen.regs[X86_REG_EAX]->Clear(); + x86gen.regs[X86_REG_EAX]->notusable=true; + x86gen.regs[X86_REG_ECX]->Clear(); + x86gen.regs[X86_REG_ECX]->notusable=true; + + if (reg_idx_addr) { + // addr!=eax + cache_addb(0x8b); //Mov eax,reg + cache_addb(0xc0+reg_idx_addr); + } + if (release_addr) gen_releasereg(addr); + } else { + // addr still in memory, directly move into eax + x86gen.regs[X86_REG_EAX]->Clear(); + x86gen.regs[X86_REG_EAX]->notusable=true; + x86gen.regs[X86_REG_ECX]->Clear(); + x86gen.regs[X86_REG_ECX]->notusable=true; + cache_addb(0xa1); //Mov eax,[data] + cache_addd((Bit32u)addr->data); + } + + cache_addw(0xc88b); // mov ecx,eax +} + +static void dyn_write_byte(DynReg * addr,DynReg * val,bool high) { + dyn_write_intro(addr,false); + + GenReg * genreg=FindDynReg(val); + cache_addw(0xe9c1); // shr ecx,0x0c + cache_addb(0x0c); + cache_addw(0x0c8b); // mov ecx,paging.tlb.read[ecx*TYPE Bit32u] + cache_addb(0x8d); + cache_addd((Bit32u)(&paging.tlb.write[0])); + cache_addw(0xc985); // test ecx,ecx + Bit8u* je_loc=gen_create_branch(BR_Z); + + cache_addw(0x0488+(genreg->index<<11)+(high?0x2000:0)); // mov [eax+ecx],reg + cache_addb(0x08); + + Bit8u* jmp_loc=gen_create_jump(); + gen_fill_branch(je_loc); + + if (GCC_UNLIKELY(high)) cache_addw(0xe086+((genreg->index+(genreg->index<<3))<<8)); + cache_addb(0x52); // push edx + cache_addb(0x50+genreg->index); + cache_addb(0x50); // push eax + if (GCC_UNLIKELY(high)) cache_addw(0xe086+((genreg->index+(genreg->index<<3))<<8)); + cache_addb(0xe8); + cache_addd(((Bit32u)&mem_writeb_checked_x86) - (Bit32u)cache.pos-4); + cache_addw(0xc483); // add esp,8 + cache_addb(0x08); + cache_addw(0x012c); // sub al,1 + cache_addb(0x5a); // pop edx + + // Restore registers to be used again + x86gen.regs[X86_REG_EAX]->notusable=false; + x86gen.regs[X86_REG_ECX]->notusable=false; + + dyn_check_bool_exception_ne(); + + gen_fill_jump(jmp_loc); +} + +static void dyn_write_byte_release(DynReg * addr,DynReg * val,bool high) { + dyn_write_intro(addr); + + GenReg * genreg=FindDynReg(val); + cache_addw(0xe9c1); // shr ecx,0x0c + cache_addb(0x0c); + cache_addw(0x0c8b); // mov ecx,paging.tlb.read[ecx*TYPE Bit32u] + cache_addb(0x8d); + cache_addd((Bit32u)(&paging.tlb.write[0])); + cache_addw(0xc985); // test ecx,ecx + Bit8u* je_loc=gen_create_branch(BR_Z); + + cache_addw(0x0488+(genreg->index<<11)+(high?0x2000:0)); // mov [eax+ecx],reg + cache_addb(0x08); + + Bit8u* jmp_loc=gen_create_jump(); + gen_fill_branch(je_loc); + + cache_addb(0x52); // push edx + if (GCC_UNLIKELY(high)) cache_addw(0xe086+((genreg->index+(genreg->index<<3))<<8)); + cache_addb(0x50+genreg->index); + cache_addb(0x50); // push eax + if (GCC_UNLIKELY(high)) cache_addw(0xe086+((genreg->index+(genreg->index<<3))<<8)); + cache_addb(0xe8); + cache_addd(((Bit32u)&mem_writeb_checked_x86) - (Bit32u)cache.pos-4); + cache_addw(0xc483); // add esp,8 + cache_addb(0x08); + cache_addw(0x012c); // sub al,1 + cache_addb(0x5a); // pop edx + + // Restore registers to be used again + x86gen.regs[X86_REG_EAX]->notusable=false; + x86gen.regs[X86_REG_ECX]->notusable=false; + + dyn_check_bool_exception_ne(); + + gen_fill_jump(jmp_loc); +} + +static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { + if (dword) { + dyn_write_intro(addr,false); + + GenReg * genreg=FindDynReg(val); + cache_addw(0xe9d1); // shr ecx,0x1 + Bit8u* jb_loc1=gen_create_branch(BR_B); + cache_addw(0xe9d1); // shr ecx,0x1 + Bit8u* jb_loc2=gen_create_branch(BR_B); + cache_addw(0xe9c1); // shr ecx,0x0a + cache_addb(0x0a); + cache_addw(0x0c8b); // mov ecx,paging.tlb.read[ecx*TYPE Bit32u] + cache_addb(0x8d); + cache_addd((Bit32u)(&paging.tlb.write[0])); + cache_addw(0xc985); // test ecx,ecx + Bit8u* je_loc=gen_create_branch(BR_Z); + + cache_addw(0x0489+(genreg->index <<(8+3))); // mov [eax+ecx],reg + cache_addb(0x08); + + Bit8u* jmp_loc=gen_create_jump(); + gen_fill_branch(jb_loc1); + gen_fill_branch(jb_loc2); + gen_fill_branch(je_loc); + + cache_addb(0x52); // push edx + cache_addb(0x50+genreg->index); + cache_addb(0x50); // push eax + cache_addb(0xe8); + cache_addd(((Bit32u)&mem_writed_checked_x86) - (Bit32u)cache.pos-4); + cache_addw(0xc483); // add esp,8 + cache_addb(0x08); + cache_addw(0x012c); // sub al,1 + cache_addb(0x5a); // pop edx + + // Restore registers to be used again + x86gen.regs[X86_REG_EAX]->notusable=false; + x86gen.regs[X86_REG_ECX]->notusable=false; + + dyn_check_bool_exception_ne(); + + gen_fill_jump(jmp_loc); + } else { + gen_protectflags(); + gen_call_function((void *)&mem_writew_checked_x86,"%Dd%Dd",addr,val); + dyn_check_bool_exception_al(); + } +} + +static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) { + if (dword) { + dyn_write_intro(addr); + + GenReg * genreg=FindDynReg(val); + cache_addw(0xe9d1); // shr ecx,0x1 + Bit8u* jb_loc1=gen_create_branch(BR_B); + cache_addw(0xe9d1); // shr ecx,0x1 + Bit8u* jb_loc2=gen_create_branch(BR_B); + cache_addw(0xe9c1); // shr ecx,0x0a + cache_addb(0x0a); + cache_addw(0x0c8b); // mov ecx,paging.tlb.read[ecx*TYPE Bit32u] + cache_addb(0x8d); + cache_addd((Bit32u)(&paging.tlb.write[0])); + cache_addw(0xc985); // test ecx,ecx + Bit8u* je_loc=gen_create_branch(BR_Z); + + cache_addw(0x0489+(genreg->index <<(8+3))); // mov [eax+ecx],reg + cache_addb(0x08); + + Bit8u* jmp_loc=gen_create_jump(); + gen_fill_branch(jb_loc1); + gen_fill_branch(jb_loc2); + gen_fill_branch(je_loc); + + cache_addb(0x52); // push edx + cache_addb(0x50+genreg->index); + cache_addb(0x50); // push eax + cache_addb(0xe8); + cache_addd(((Bit32u)&mem_writed_checked_x86) - (Bit32u)cache.pos-4); + cache_addw(0xc483); // add esp,8 + cache_addb(0x08); + cache_addw(0x012c); // sub al,1 + cache_addb(0x5a); // pop edx + + // Restore registers to be used again + x86gen.regs[X86_REG_EAX]->notusable=false; + x86gen.regs[X86_REG_ECX]->notusable=false; + + dyn_check_bool_exception_ne(); + + gen_fill_jump(jmp_loc); + } else { + gen_protectflags(); + gen_call_function((void *)&mem_writew_checked_x86,"%Ddr%Dd",addr,val); + dyn_check_bool_exception_al(); + } +} + +#endif + + static void dyn_push_unchecked(DynReg * dynreg) { gen_protectflags(); gen_lea(DREG(STACK),DREG(ESP),0,0,decode.big_op?(-4):(-2)); @@ -436,6 +922,12 @@ skip_extend_word: case 4: /* SIB */ { Bitu sib=decode_fetchb(); + static DynReg * scaledtable[8]={ + DREG(EAX),DREG(ECX),DREG(EDX),DREG(EBX), + 0,DREG(EBP),DREG(ESI),DREG(EDI), + }; + scaled=scaledtable[(sib >> 3) &7]; + scale=(sib >> 6); switch (sib & 7) { case 0:base=DREG(EAX);segbase=DREG(DS);break; case 1:base=DREG(ECX);segbase=DREG(DS);break; @@ -446,18 +938,25 @@ skip_extend_word: if (decode.modrm.mod) { base=DREG(EBP);segbase=DREG(SS); } else { - imm=(Bit32s)decode_fetchd();segbase=DREG(DS); + segbase=DREG(DS); + Bitu val; + if (decode_fetchd_imm(val)) { + gen_mov_host((void*)val,DREG(EA),4); + if (!addseg) { + gen_lea(reg_ea,DREG(EA),scaled,scale,0); + } else { + DynReg** seg = decode.segprefix ? &decode.segprefix : &segbase; + gen_lea(DREG(EA),DREG(EA),scaled,scale,0); + gen_lea(reg_ea,DREG(EA),*seg,0,0); + } + return; + } + imm=(Bit32s)val; } break; case 6:base=DREG(ESI);segbase=DREG(DS);break; case 7:base=DREG(EDI);segbase=DREG(DS);break; } - static DynReg * scaledtable[8]={ - DREG(EAX),DREG(ECX),DREG(EDX),DREG(EBX), - 0,DREG(EBP),DREG(ESI),DREG(EDI), - }; - scaled=scaledtable[(sib >> 3) &7]; - scale=(sib >> 6); } break; /* SIB Break */ case 5: @@ -472,7 +971,33 @@ skip_extend_word: } switch (decode.modrm.mod) { case 1:imm=(Bit8s)decode_fetchb();break; - case 2:imm=(Bit32s)decode_fetchd();break; + case 2: { + Bitu val; + if (decode_fetchd_imm(val)) { + gen_mov_host((void*)val,DREG(EA),4); + if (!addseg) { + gen_lea(DREG(EA),DREG(EA),scaled,scale,0); + gen_lea(reg_ea,DREG(EA),base,0,0); + } else { + DynReg** seg = decode.segprefix ? &decode.segprefix : &segbase; + if (!base) { + gen_lea(DREG(EA),DREG(EA),scaled,scale,0); + gen_lea(reg_ea,DREG(EA),*seg,0,0); + } else if (!scaled) { + gen_lea(DREG(EA),DREG(EA),*seg,0,0); + gen_lea(reg_ea,DREG(EA),base,0,0); + } else { + gen_lea(DREG(EA),DREG(EA),scaled,scale,0); + gen_lea(DREG(EA),DREG(EA),base,0,0); + gen_lea(reg_ea,DREG(EA),decode.segprefix ? decode.segprefix : segbase,0,0); + } + } + return; + } + + imm=(Bit32s)val; + break; + } } if (!addseg) { gen_lea(reg_ea,base,scaled,scale,imm); @@ -481,13 +1006,40 @@ skip_extend_word: if (!base) gen_lea(reg_ea,*seg,scaled,scale,imm); else if (!scaled) gen_lea(reg_ea,base,*seg,0,imm); else { - gen_lea(reg_ea,base,scaled,scale,imm); - gen_lea(reg_ea,reg_ea,decode.segprefix ? decode.segprefix : segbase,0,0); + gen_lea(DREG(EA),base,scaled,scale,imm); + gen_lea(reg_ea,DREG(EA),decode.segprefix ? decode.segprefix : segbase,0,0); } } } } + +static void dyn_dop_word_imm(DualOps op,bool dword,DynReg * dr1) { + Bitu val; + if (dword) { + if (decode_fetchd_imm(val)) { + gen_dop_word_imm_mem(op,true,dr1,(void*)val); + return; + } + } else { + if (decode_fetchw_imm(val)) { + gen_dop_word_imm_mem(op,false,dr1,(void*)val); + return; + } + } + gen_dop_word_imm(op,dword,dr1,val); +} + +static void dyn_dop_byte_imm(DualOps op,DynReg * dr1,Bit8u di1) { + Bitu val; + if (decode_fetchb_imm(val)) { + gen_dop_byte_imm_mem(op,dr1,di1,(void*)val); + } else { + gen_dop_byte_imm(op,dr1,di1,(Bit8u)val); + } +} + + #include "helpers.h" #include "string.h" @@ -734,7 +1286,7 @@ static void dyn_grp1_eb_ib(void) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else gen_discardflags(); } - gen_dop_byte_imm(op,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,decode_fetchb()); + dyn_dop_byte_imm(op,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); } } @@ -745,22 +1297,28 @@ static void dyn_grp1_ev_ivx(bool withbyte) { dyn_fill_ea(); if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); - Bits imm=withbyte ? (Bit8s)decode_fetchb() : (decode.big_op ? decode_fetchd(): decode_fetchw()); if (op<=DOP_TEST) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else set_skipflags(false); } - gen_dop_word_imm(op,decode.big_op,DREG(TMPW),imm); + if (!withbyte) { + dyn_dop_word_imm(op,decode.big_op,DREG(TMPW)); + } else { + gen_dop_word_imm(op,decode.big_op,DREG(TMPW),(Bit8s)decode_fetchb()); + } if (op!=DOP_CMP) dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); else gen_releasereg(DREG(EA)); gen_releasereg(DREG(TMPW)); } else { - Bits imm=withbyte ? (Bit8s)decode_fetchb() : (decode.big_op ? decode_fetchd(): decode_fetchw()); if (op<=DOP_TEST) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else gen_discardflags(); } - gen_dop_word_imm(op,decode.big_op,&DynRegs[decode.modrm.rm],imm); + if (!withbyte) { + dyn_dop_word_imm(op,decode.big_op,&DynRegs[decode.modrm.rm]); + } else { + gen_dop_word_imm(op,decode.big_op,&DynRegs[decode.modrm.rm],(Bit8s)decode_fetchb()); + } } } @@ -822,7 +1380,16 @@ static void dyn_grp2_ev(grp2_types type) { gen_shift_word_imm(decode.modrm.reg,decode.big_op,src,1); break; case grp2_imm: { - Bit8u imm=decode_fetchb(); + Bitu val; + if (decode_fetchb_imm(val)) { + if (decode.modrm.reg < 4) gen_needflags(); + else gen_discardflags(); + gen_load_host((void*)val,DREG(TMPB),1); + gen_shift_word_cl(decode.modrm.reg,decode.big_op,src,DREG(TMPB)); + gen_releasereg(DREG(TMPB)); + break; + } + Bit8u imm=(Bit8u)val; if (imm) { /* rotates (first 4 ops) alter cf/of only; shifts (last 4 ops) alter all flags */ if (decode.modrm.reg < 4) gen_needflags(); @@ -1272,6 +1839,7 @@ static CacheBlock * CreateCacheBlock(CodePageHandler * codepage,PhysPt start,Bit 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=decode.page.index; @@ -1303,7 +1871,18 @@ static CacheBlock * CreateCacheBlock(CodePageHandler * codepage,PhysPt start,Bit decode.cycles++; decode.op_start=decode.code; restart_prefix: - Bitu opcode=decode_fetchb(); + Bitu opcode; + if (!decode.page.invmap) opcode=decode_fetchb(); + else { + if (decode.page.index<4096) { + if (GCC_UNLIKELY(decode.page.invmap[decode.page.index]>=4)) goto illegalopcode; + opcode=decode_fetchb(); + } else { + opcode=decode_fetchb(); + if (GCC_UNLIKELY(decode.page.invmap && + (decode.page.invmap[decode.page.index-1]>=4))) goto illegalopcode; + } + } switch (opcode) { case 0x00:dyn_dop_ebgb(DOP_ADD);break; @@ -1311,7 +1890,7 @@ restart_prefix: case 0x02:dyn_dop_gbeb(DOP_ADD);break; case 0x03:dyn_dop_gvev(DOP_ADD);break; case 0x04:gen_discardflags();gen_dop_byte_imm(DOP_ADD,DREG(EAX),0,decode_fetchb());break; - case 0x05:gen_discardflags();gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; + case 0x05:gen_discardflags();dyn_dop_word_imm(DOP_ADD,decode.big_op,DREG(EAX));break; case 0x06:dyn_push_seg(es);break; case 0x07:dyn_pop_seg(es);break; @@ -1384,7 +1963,7 @@ restart_prefix: case 0x22:dyn_dop_gbeb(DOP_AND);break; case 0x23:dyn_dop_gvev(DOP_AND);break; case 0x24:gen_discardflags();gen_dop_byte_imm(DOP_AND,DREG(EAX),0,decode_fetchb());break; - case 0x25:gen_discardflags();gen_dop_word_imm(DOP_AND,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; + case 0x25:gen_discardflags();dyn_dop_word_imm(DOP_AND,decode.big_op,DREG(EAX));break; case 0x26:dyn_segprefix(es);goto restart_prefix; case 0x28:dyn_dop_ebgb(DOP_SUB);break; @@ -1488,7 +2067,7 @@ restart_prefix: case 0x8b:dyn_mov_gvev();break; /* MOV ev,seg */ case 0x8c:dyn_mov_ev_seg();break; - /* LEA Gv */ + /* LEA Gv */ case 0x8d: dyn_get_modrm(); if (decode.big_op) { @@ -1550,9 +2129,18 @@ restart_prefix: break; /* MOV direct address,AL */ case 0xa2: - gen_lea(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),0,0, - decode.big_addr ? decode_fetchd() : decode_fetchw()); - dyn_write_byte_release(DREG(EA),DREG(EAX),false); + if (decode.big_addr) { + Bitu val; + if (decode_fetchd_imm(val)) { + gen_lea_imm_mem(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),(void*)val); + } else { + gen_lea(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),0,0,(Bits)val); + } + dyn_write_byte_release(DREG(EA),DREG(EAX),false); + } else { + gen_lea(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),0,0,decode_fetchw()); + dyn_write_byte_release(DREG(EA),DREG(EAX),false); + } break; /* MOV direct addresses,AX */ case 0xa3: @@ -1578,7 +2166,11 @@ restart_prefix: break; //Mov word reg imm byte,word, case 0xb8:case 0xb9:case 0xba:case 0xbb:case 0xbc:case 0xbd:case 0xbe:case 0xbf: - gen_dop_word_imm(DOP_MOV,decode.big_op,&DynRegs[opcode&7],decode.big_op ? decode_fetchd() : decode_fetchw());break; + if (decode.big_op) { + dyn_dop_word_imm(DOP_MOV,decode.big_op,&DynRegs[opcode&7]);break; + } else { + gen_dop_word_imm(DOP_MOV,decode.big_op,&DynRegs[opcode&7],decode_fetchw());break; + } break; //GRP2 Eb/Ev,Ib case 0xc0:dyn_grp2_eb(grp2_imm);break; diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index afbbe4f2..d5f15bf7 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -283,6 +283,36 @@ static void gen_reinit(void) { } } + +static void gen_load_host(void * data,DynReg * dr1,Bitu size) { + GenReg * gr1=FindDynReg(dr1,true); + switch (size) { + case 1:cache_addw(0xb60f);break; //movzx byte + case 2:cache_addw(0xb70f);break; //movzx word + case 4:cache_addb(0x8b);break; //mov + default: + IllegalOption("gen_load_host"); + } + cache_addb(0x5+(gr1->index<<3)); + cache_addd((Bit32u)data); + dr1->flags|=DYNFLG_CHANGED; +} + +static void gen_mov_host(void * data,DynReg * dr1,Bitu size,Bit8u di1=0) { + GenReg * gr1=FindDynReg(dr1,(size==4)); + switch (size) { + case 1:cache_addb(0x8a);break; //mov byte + case 2:cache_addb(0x66); //mov word + case 4:cache_addb(0x8b);break; //mov + default: + IllegalOption("gen_load_host"); + } + cache_addb(0x5+((gr1->index+(di1?4:0))<<3)); + cache_addd((Bit32u)data); + dr1->flags|=DYNFLG_CHANGED; +} + + static void gen_dop_byte(DualOps op,DynReg * dr1,Bit8u di1,DynReg * dr2,Bit8u di2) { GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2); Bit8u tmp; @@ -332,6 +362,29 @@ finish: cache_addb(imm); } +static void gen_dop_byte_imm_mem(DualOps op,DynReg * dr1,Bit8u di1,void* data) { + GenReg * gr1=FindDynReg(dr1); + Bit16u tmp; + switch (op) { + case DOP_ADD: tmp=0x0502; break; + case DOP_ADC: tmp=0x0512; break; + case DOP_SUB: tmp=0x052a; break; + case DOP_SBB: tmp=0x051a; break; + case DOP_CMP: tmp=0x053a; goto nochange; //Doesn't change + case DOP_XOR: tmp=0x0532; break; + case DOP_AND: tmp=0x0522; break; + case DOP_OR: tmp=0x050a; break; + case DOP_TEST: tmp=0x0584; goto nochange; //Doesn't change + case DOP_MOV: tmp=0x0585; break; + default: + IllegalOption("gen_dop_byte_imm_mem"); + } + dr1->flags|=DYNFLG_CHANGED; +nochange: + cache_addw(tmp+((gr1->index+di1)<<11)); + cache_addd((Bit32u)data); +} + static void gen_sop_byte(SingleOps op,DynReg * dr1,Bit8u di1) { GenReg * gr1=FindDynReg(dr1); Bit16u tmp; @@ -413,6 +466,19 @@ static void gen_lea(DynReg * ddr,DynReg * dsr1,DynReg * dsr2,Bitu scale,Bits imm ddr->flags|=DYNFLG_CHANGED; } +static void gen_lea_imm_mem(DynReg * ddr,DynReg * dsr,void* data) { + GenReg * gdr=FindDynReg(ddr); + Bit8u rm_base=(gdr->index << 3); + cache_addw(0x058b+(rm_base<<8)); + cache_addd((Bit32u)data); + GenReg * gsr=FindDynReg(dsr); + cache_addb(0x8d); //LEA + cache_addb(rm_base+0x44); + cache_addb(rm_base+gsr->index); + cache_addb(0x00); + ddr->flags|=DYNFLG_CHANGED; +} + static void gen_dop_word(DualOps op,bool dword,DynReg * dr1,DynReg * dr2) { GenReg * gr2=FindDynReg(dr2); GenReg * gr1=FindDynReg(dr1,dword && op==DOP_MOV); @@ -473,6 +539,33 @@ finish: else cache_addw(imm); } +static void gen_dop_word_imm_mem(DualOps op,bool dword,DynReg * dr1,void* data) { + GenReg * gr1=FindDynReg(dr1,dword && op==DOP_MOV); + Bit16u tmp; + switch (op) { + case DOP_ADD: tmp=0x0503; break; + case DOP_ADC: tmp=0x0513; break; + case DOP_SUB: tmp=0x052b; break; + case DOP_SBB: tmp=0x051b; break; + case DOP_CMP: tmp=0x053b; goto nochange; //Doesn't change + case DOP_XOR: tmp=0x0533; break; + case DOP_AND: tmp=0x0523; break; + case DOP_OR: tmp=0x050b; break; + case DOP_TEST: tmp=0x0585; goto nochange; //Doesn't change + case DOP_MOV: + gen_mov_host(data,dr1,dword?4:2); + dr1->flags|=DYNFLG_CHANGED; + return; + default: + IllegalOption("gen_dop_word_imm_mem"); + } + dr1->flags|=DYNFLG_CHANGED; +nochange: + if (!dword) cache_addb(0x66); + cache_addw(tmp+(gr1->index<<11)); + cache_addd((Bit32u)data); +} + static void gen_dop_word_var(DualOps op,bool dword,DynReg * dr1,void* drd) { GenReg * gr1=FindDynReg(dr1,dword && op==DOP_MOV); Bit8u tmp; @@ -923,34 +1016,6 @@ static void gen_save_host_direct(void * data,Bits imm) { cache_addd(imm); } -static void gen_load_host(void * data,DynReg * dr1,Bitu size) { - GenReg * gr1=FindDynReg(dr1); - switch (size) { - case 1:cache_addw(0xb60f);break; //movzx byte - case 2:cache_addw(0xb70f);break; //movzx word - case 4:cache_addb(0x8b);break; //mov - default: - IllegalOption("gen_load_host"); - } - cache_addb(0x5+(gr1->index<<3)); - cache_addd((Bit32u)data); - dr1->flags|=DYNFLG_CHANGED; -} - -static void gen_mov_host(void * data,DynReg * dr1,Bitu size,Bit8u di1=0) { - GenReg * gr1=FindDynReg(dr1); - switch (size) { - case 1:cache_addb(0x8a);break; //mov byte - case 2:cache_addb(0x66); //mov word - case 4:cache_addb(0x8b);break; //mov - default: - IllegalOption("gen_load_host"); - } - cache_addb(0x5+((gr1->index+(di1?4:0))<<3)); - cache_addd((Bit32u)data); - dr1->flags|=DYNFLG_CHANGED; -} - static void gen_return(BlockReturn retcode) { gen_protectflags(); cache_addb(0x59); //POP ECX, the flags diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 3b79e162..ebe58f01 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.38 2007-01-09 17:18:52 c2woody Exp $ */ +/* $Id: pic.cpp,v 1.39 2007-01-18 14:57:59 c2woody Exp $ */ #include @@ -453,8 +453,8 @@ bool PIC_RunQueue(void) { return false; } /* Check the queue for an entry */ - double index=PIC_TickIndex(); - while (pic.next_entry && pic.next_entry->index<=index) { + Bits index_nd=PIC_TickIndexND(); + while (pic.next_entry && (pic.next_entry->index*CPU_CycleMax<=index_nd)) { PICEntry * entry=pic.next_entry; pic.next_entry=entry->next; (entry->event)(entry->value); @@ -464,7 +464,7 @@ bool PIC_RunQueue(void) { } /* Check when to set the new cycle end */ if (pic.next_entry) { - Bits cycles=PIC_MakeCycles(pic.next_entry->index-index); + Bits cycles=(Bits)(pic.next_entry->index*CPU_CycleMax-index_nd); if (!cycles) cycles=1; if (cycles Date: Fri, 19 Jan 2007 18:48:31 +0000 Subject: [PATCH 2685/4131] Some fixes so Ballade midi sequencer works. (Srecko) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2770 --- src/hardware/mpu401.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 756ad1b5..c1532748 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.23 2007-01-08 19:45:40 qbix79 Exp $ */ +/* $Id: mpu401.cpp,v 1.24 2007-01-19 18:48:31 qbix79 Exp $ */ #include #include "dosbox.h" @@ -66,7 +66,7 @@ static struct { MpuDataType type; } playbuf[8],condbuf; struct { - bool conductor,cond_req,cond_set; + bool conductor,cond_req,cond_set, block_ack; bool playing,reset; bool wsd,wsm,wsd_start; bool run_irq,irq_pending; @@ -90,6 +90,7 @@ static struct { static void QueueByte(Bit8u data) { + if (mpu.state.block_ack) {mpu.state.block_ack=false;return;} if (mpu.queue_used==0 && mpu.intelligent) { mpu.state.irq_pending=true; PIC_ActivateIRQ(mpu.irq); @@ -116,7 +117,7 @@ static Bitu MPU401_ReadStatus(Bitu port,Bitu iolen) { static void MPU401_WriteCommand(Bitu port,Bitu val,Bitu iolen) { mpu.state.reset=0; - if (val && val<=0x2f) { + if (val<=0x2f) { switch (val&3) { /* MIDI stop, start, continue */ case 1: {MIDI_RawOutByte(0xfc);break;} case 2: {MIDI_RawOutByte(0xfa);break;} @@ -269,10 +270,13 @@ static Bitu MPU401_ReadData(Bitu port,Bitu iolen) { mpu.state.channel=ret&7; mpu.state.data_onoff=0; mpu.state.cond_req=false; + mpu.state.command_byte=0; } if (ret==MSG_MPU_COMMAND_REQ) { mpu.state.data_onoff=0; mpu.state.cond_req=true; + mpu.state.wsd=mpu.state.wsm=false; + mpu.state.command_byte=0; } if (ret==MSG_MPU_END || ret==MSG_MPU_CLOCK || ret==MSG_MPU_ACK) { mpu.state.data_onoff=-1; @@ -292,7 +296,8 @@ static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) { return; case 0xe1: /* Set relative tempo */ mpu.state.command_byte=0; - LOG(LOG_MISC,LOG_ERROR)("MPU-401:Relative tempo not implemented"); + if (val!=0x40) //default value + LOG(LOG_MISC,LOG_ERROR)("MPU-401:Relative tempo change not implemented"); return; case 0xe7: /* Set internal clock to host interval */ mpu.state.command_byte=0; @@ -492,6 +497,7 @@ static void UpdateTrack(Bit8u chan) { static void UpdateConductor(void) { if (mpu.condbuf.type!=T_OVERFLOW) { + mpu.state.block_ack=true; MPU401_WriteCommand(0x331,mpu.condbuf.value[0],1); if (mpu.state.command_byte) MPU401_WriteData(0x330,mpu.condbuf.value[1],1); } @@ -563,6 +569,7 @@ static void MPU401_Reset(void) { mpu.state.midi_mask=0xffff; mpu.state.data_onoff=0; mpu.state.command_byte=0; + mpu.state.block_ack=false; mpu.clock.tempo=mpu.clock.old_tempo=100; mpu.clock.timebase=mpu.clock.old_timebase=120; mpu.clock.tempo_rel=mpu.clock.old_tempo_rel=40; From 4a4452534117faefeb894d0f38ca8a6aba2ff8a0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 21 Jan 2007 11:01:54 +0000 Subject: [PATCH 2686/4131] Fix Schleichfart (Moe). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2771 --- src/hardware/keyboard.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 47c711d2..8a828bb2 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.36 2007-01-08 19:45:40 qbix79 Exp $ */ +/* $Id: keyboard.cpp,v 1.37 2007-01-21 11:01:54 qbix79 Exp $ */ #include "dosbox.h" #include "keyboard.h" @@ -150,6 +150,7 @@ static void write_p60(Bitu port,Bitu val,Bitu iolen) { return; case CMD_SETOUTPORT: MEM_A20_Enable((val & 2)>0); + keyb.command = CMD_NONE; break; case CMD_SETTYPERATE: { From 9c2799085c6cb638a17016295a7e907c8e2a10ad Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 21 Jan 2007 11:04:58 +0000 Subject: [PATCH 2687/4131] Add a question in the faq about fullscreen Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2772 --- README | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README b/README index 447ff1ac..4f43a978 100644 --- a/README +++ b/README @@ -46,6 +46,7 @@ Type INTRO in DOSBox. That's it. Some Frequently Asked Questions: Q: I've got a Z instead of a C at the prompt. +Q: How do I change to fullscreen ? Q: My CD-ROM doesn't work. Q: The mouse doesn't work. Q: The sound stutters or sounds stretched/weird. @@ -71,6 +72,13 @@ A: You have to make your directories available as drives in DOSBox by using To change to the drive mounted like above, type "C:". If everything went fine, DOSBox will display the prompt "C:\>". +Q: How do I change to fullscreen ? +A: Press alt-enter. Alternatively: Edit the configuration file of DOSBox and + change the option fullscreen=false to fullscreen=true. If fullscreen looks + wrong in your opinion: Play with the option fullresolution in the + configuration file of DOSBox. To get back from fullscreen mode: + Press alt-enter again. + Q: My CD-ROM doesn't work. A: To mount your CD-ROM in DOSBox you have to specify some additional options From 8794a1f8444d27b2dd6112c5046072833f247122 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 21 Jan 2007 13:00:42 +0000 Subject: [PATCH 2688/4131] Clarification for the sdl_sound part. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2773 --- INSTALL | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/INSTALL b/INSTALL index e500002d..56e62818 100644 --- a/INSTALL +++ b/INSTALL @@ -22,10 +22,11 @@ SDL_Net SDL_Sound For compressed audio on diskimages. (optional) + This is for cue/bin cdrom images with compressed (mp3/ogg) audio tracks. ALSA_Headers (optional) - ???????? for Alsa support under linux + for Alsa support under linux. Part of the linux kernel sources 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 From 1780e725284cf6a4b6dc3acf269b53bedc3923ed Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 21 Jan 2007 14:10:14 +0000 Subject: [PATCH 2689/4131] Fix a few warnings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2774 --- src/cpu/core_dyn_x86.cpp | 2 +- src/cpu/core_dyn_x86/cache.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index ebfa816b..fc342519 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -165,7 +165,7 @@ static struct { Bit32u readdata; } core_dyn; -struct { +static struct { Bit32u state[32]; FPU_P_Reg temp,temp2; Bit32u dh_fpu_enabled; diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 41512c32..bd2b51ac 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -531,4 +531,4 @@ static void cache_close(void) { cache_code = NULL; cache_code_link_blocks = NULL; cache_initialized = false; */ -} \ No newline at end of file +} From beb406943712975fdb299e592657a73ed60c58ad Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 21 Jan 2007 14:12:02 +0000 Subject: [PATCH 2690/4131] lines starting with cd will only get directories when doing tabcompletion. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2775 --- src/shell/shell_misc.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index ebd986f0..dbdfe404 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.47 2007-01-08 19:45:42 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.48 2007-01-21 14:12:02 qbix79 Exp $ */ #include #include @@ -215,6 +215,8 @@ void DOS_Shell::InputCommand(char * line) { if (it_completion == l_completion.end()) it_completion = l_completion.begin(); } else { // build new completion list + // Lines starting with CD will only get directories in the list + bool dir_only = (strncasecmp(line,"CD ",3)==0); // get completion mask char *p_completion_start = strrchr(line, ' '); @@ -266,14 +268,17 @@ void DOS_Shell::InputCommand(char * line) { char *ext; // file extension if (strcmp(name, ".") && strcmp(name, "..")) { - ext = strrchr(name, '.'); - if (ext && (strcmp(ext, ".BAT") == 0 || strcmp(ext, ".COM") == 0 || strcmp(ext, ".EXE") == 0)) - // we add executables to the a seperate list and place that list infront of the normal files - executable.push_front(name); - else - l_completion.push_back(name); + if (dir_only) { //Handle the dir only case different (line starts with cd) + if(att & DOS_ATTR_DIRECTORY) l_completion.push_back(name); + } else { + ext = strrchr(name, '.'); + if (ext && (strcmp(ext, ".BAT") == 0 || strcmp(ext, ".COM") == 0 || strcmp(ext, ".EXE") == 0)) + // we add executables to the a seperate list and place that list infront of the normal files + executable.push_front(name); + else + l_completion.push_back(name); + } } - res=DOS_FindNext(); } /* Add excutable list to front of completion list. */ From e3f7faf86223a817b6cacec76c26e6326e1009bb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 21 Jan 2007 14:13:21 +0000 Subject: [PATCH 2691/4131] Improve help a bit. Introduce help /all. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2776 --- src/shell/shell.cpp | 4 ++-- src/shell/shell_cmds.cpp | 48 ++++++++++++++++++++-------------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 4707419e..6fba8246 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.81 2007-01-13 09:58:26 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.82 2007-01-21 14:13:21 qbix79 Exp $ */ #include #include @@ -420,7 +420,7 @@ static char * init_line="/INIT AUTOEXEC.BAT"; void SHELL_Init() { /* Add messages */ MSG_Add("SHELL_ILLEGAL_PATH","Illegal Path.\n"); - MSG_Add("SHELL_CMD_HELP","supported commands are:\n"); + MSG_Add("SHELL_CMD_HELP","If you want a list of all supported commands type \033[33;1mhelp /all\033[0m .\nA short list of the most often used commands:\n"); MSG_Add("SHELL_CMD_ECHO_ON","ECHO is on.\n"); MSG_Add("SHELL_CMD_ECHO_OFF","ECHO is off.\n"); MSG_Add("SHELL_ILLEGAL_SWITCH","Illegal switch: %s.\n"); diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index aeb80f78..70227fb4 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.71 2007-01-10 09:04:33 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.72 2007-01-21 14:13:21 qbix79 Exp $ */ #include #include @@ -29,36 +29,36 @@ #include "support.h" static SHELL_Cmd cmd_list[]={ -{ "CHDIR", 0, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"}, -{ "CD", 1, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"}, +{ "CHDIR", 1, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"}, +{ "CD", 0, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"}, { "CLS", 0, &DOS_Shell::CMD_CLS, "SHELL_CMD_CLS_HELP"}, { "COPY", 0, &DOS_Shell::CMD_COPY, "SHELL_CMD_COPY_HELP"}, { "DIR", 0, &DOS_Shell::CMD_DIR, "SHELL_CMD_DIR_HELP"}, -{ "DEL", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, -{ "DELETE", 0, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, +{ "DEL", 0, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, +{ "DELETE", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, { "ERASE", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, -{ "ECHO", 0, &DOS_Shell::CMD_ECHO, "SHELL_CMD_ECHO_HELP"}, +{ "ECHO", 1, &DOS_Shell::CMD_ECHO, "SHELL_CMD_ECHO_HELP"}, { "EXIT", 0, &DOS_Shell::CMD_EXIT, "SHELL_CMD_EXIT_HELP"}, { "HELP", 1, &DOS_Shell::CMD_HELP, "SHELL_CMD_HELP_HELP"}, -{ "MKDIR", 0, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP"}, -{ "MD", 1, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP"}, -{ "RMDIR", 0, &DOS_Shell::CMD_RMDIR, "SHELL_CMD_RMDIR_HELP"}, -{ "RD", 1, &DOS_Shell::CMD_RMDIR, "SHELL_CMD_RMDIR_HELP"}, -{ "SET", 0, &DOS_Shell::CMD_SET, "SHELL_CMD_SET_HELP"}, -{ "IF", 0, &DOS_Shell::CMD_IF, "SHELL_CMD_IF_HELP"}, -{ "GOTO", 0, &DOS_Shell::CMD_GOTO, "SHELL_CMD_GOTO_HELP"}, -{ "SHIFT", 0, &DOS_Shell::CMD_SHIFT, "SHELL_CMD_SHIFT_HELP"}, +{ "MKDIR", 1, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP"}, +{ "MD", 0, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP"}, +{ "RMDIR", 1, &DOS_Shell::CMD_RMDIR, "SHELL_CMD_RMDIR_HELP"}, +{ "RD", 0, &DOS_Shell::CMD_RMDIR, "SHELL_CMD_RMDIR_HELP"}, +{ "SET", 1, &DOS_Shell::CMD_SET, "SHELL_CMD_SET_HELP"}, +{ "IF", 1, &DOS_Shell::CMD_IF, "SHELL_CMD_IF_HELP"}, +{ "GOTO", 1, &DOS_Shell::CMD_GOTO, "SHELL_CMD_GOTO_HELP"}, +{ "SHIFT", 1, &DOS_Shell::CMD_SHIFT, "SHELL_CMD_SHIFT_HELP"}, { "TYPE", 0, &DOS_Shell::CMD_TYPE, "SHELL_CMD_TYPE_HELP"}, -{ "REM", 0, &DOS_Shell::CMD_REM, "SHELL_CMD_REM_HELP"}, -{ "RENAME", 0, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP"}, -{ "REN", 1, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP"}, -{ "PAUSE", 0, &DOS_Shell::CMD_PAUSE, "SHELL_CMD_PAUSE_HELP"}, -{ "CALL", 0, &DOS_Shell::CMD_CALL, "SHELL_CMD_CALL_HELP"}, -{ "SUBST", 0, &DOS_Shell::CMD_SUBST, "SHELL_CMD_SUBST_HELP"}, +{ "REM", 1, &DOS_Shell::CMD_REM, "SHELL_CMD_REM_HELP"}, +{ "RENAME", 1, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP"}, +{ "REN", 0, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP"}, +{ "PAUSE", 1, &DOS_Shell::CMD_PAUSE, "SHELL_CMD_PAUSE_HELP"}, +{ "CALL", 1, &DOS_Shell::CMD_CALL, "SHELL_CMD_CALL_HELP"}, +{ "SUBST", 1, &DOS_Shell::CMD_SUBST, "SHELL_CMD_SUBST_HELP"}, { "LOADHIGH", 0, &DOS_Shell::CMD_LOADHIGH, "SHELL_CMD_LOADHIGH_HELP"}, { "LH", 1, &DOS_Shell::CMD_LOADHIGH, "SHELL_CMD_LOADHIGH_HELP"}, { "CHOICE", 0, &DOS_Shell::CMD_CHOICE, "SHELL_CMD_CHOICE_HELP"}, -{ "ATTRIB", 0, &DOS_Shell::CMD_ATTRIB, "SHELL_CMD_ATTRIB_HELP"}, +{ "ATTRIB", 1, &DOS_Shell::CMD_ATTRIB, "SHELL_CMD_ATTRIB_HELP"}, { "PATH", 1, &DOS_Shell::CMD_PATH, "SHELL_CMD_PATH_HELP"}, { "VER", 0, &DOS_Shell::CMD_VER, "SHELL_CMD_VER_HELP"}, {0,0,0,0} @@ -176,14 +176,14 @@ void DOS_Shell::CMD_DELETE(char * args) { void DOS_Shell::CMD_HELP(char * args){ HELP("HELP"); + bool optall=ScanCMDBool(args,"ALL"); /* Print the help */ - WriteOut(MSG_Get("SHELL_CMD_HELP")); + if(!optall) WriteOut(MSG_Get("SHELL_CMD_HELP")); Bit32u cmd_index=0; while (cmd_list[cmd_index].name) { - if (!cmd_list[cmd_index].flags) WriteOut("%-8s %s",cmd_list[cmd_index].name,MSG_Get(cmd_list[cmd_index].help)); + if (optall || !cmd_list[cmd_index].flags) WriteOut("<\033[34;1m%-8s\033[0m> %s",cmd_list[cmd_index].name,MSG_Get(cmd_list[cmd_index].help)); cmd_index++; } - } void DOS_Shell::CMD_RENAME(char * args){ From 235c630cef536f3047a5204fd8e23e23895de1b1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 21 Jan 2007 16:18:12 +0000 Subject: [PATCH 2692/4131] Make help/all wrap like dir/p Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2777 --- src/shell/shell_cmds.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 70227fb4..5c020a21 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.72 2007-01-21 14:13:21 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.73 2007-01-21 16:18:12 qbix79 Exp $ */ #include #include @@ -179,9 +179,12 @@ void DOS_Shell::CMD_HELP(char * args){ bool optall=ScanCMDBool(args,"ALL"); /* Print the help */ if(!optall) WriteOut(MSG_Get("SHELL_CMD_HELP")); - Bit32u cmd_index=0; + Bit32u cmd_index=0,write_count=0; while (cmd_list[cmd_index].name) { - if (optall || !cmd_list[cmd_index].flags) WriteOut("<\033[34;1m%-8s\033[0m> %s",cmd_list[cmd_index].name,MSG_Get(cmd_list[cmd_index].help)); + if (optall || !cmd_list[cmd_index].flags) { + WriteOut("<\033[34;1m%-8s\033[0m> %s",cmd_list[cmd_index].name,MSG_Get(cmd_list[cmd_index].help)); + if(!(++write_count%22)) CMD_PAUSE(""); + } cmd_index++; } } @@ -432,7 +435,7 @@ void DOS_Shell::CMD_DIR(char * args) { } if(optP) { if(!(++p_count%(22*w_size))) { - CMD_PAUSE(args); + CMD_PAUSE(""); } } } while ( (ret=DOS_FindNext()) ); From e608297aae222c08a9a8ab4a8ab3aad17a218463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 21 Jan 2007 16:21:22 +0000 Subject: [PATCH 2693/4131] add imagedisk swapping capabilities (prompt, slightly modified sf patch #1505951); fix int13 write sectors return code Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2778 --- README | 19 +++-- include/dos_system.h | 5 +- src/dos/cdrom_image.cpp | 21 +++-- src/dos/dos_mscdex.cpp | 24 +++++- src/dos/dos_programs.cpp | 160 ++++++++++++++++++++++++--------------- src/dos/drive_iso.cpp | 30 +++++++- src/dos/drives.cpp | 111 +++++++++++++++++++++++++++ src/dos/drives.h | 25 +++++- src/dosbox.cpp | 6 +- src/ints/bios_disk.cpp | 5 +- 10 files changed, 319 insertions(+), 87 deletions(-) diff --git a/README b/README index 4f43a978..8e0e5fd6 100644 --- a/README +++ b/README @@ -72,6 +72,7 @@ A: You have to make your directories available as drives in DOSBox by using To change to the drive mounted like above, type "C:". If everything went fine, DOSBox will display the prompt "C:\>". + Q: How do I change to fullscreen ? A: Press alt-enter. Alternatively: Edit the configuration file of DOSBox and change the option fullscreen=false to fullscreen=true. If fullscreen looks @@ -486,9 +487,11 @@ IMGMOUNT -size [sectorsbytesize, sectorsperhead, heads, cylinders] imagefile - Location of the image files to mount in DOSBox. The location is on a - mounted drive inside DOSBox. CD-ROM images can be mounted - directly as well. They don't have to be on a mounted drive. + Location of the image files to mount in DOSBox. The location can + be on a mounted drive inside DOSBox, or on your real disk. It is + possible to mount CD-ROM images (ISOs or CUE/BIN) as well, if you + need CD swapping capabilities specify all images in succession. + The CDs can be swapped with CTRL-F4 at any time. -t The following are valid image types: @@ -532,11 +535,11 @@ BOOT Boot will start floppy images or hard disk images independent of the operating system emulation offered by DOSBox. This will allow you to play booter floppies or boot other operating systems inside DOSBox. - If the target emulated system is PCJr (machine=pcjr) the boot command - can be used to load PCJr cartridges (.jrc). + If the target emulated system is PCjr (machine=pcjr) the boot command + can be used to load PCjr cartridges (.jrc). BOOT [diskimg1.img diskimg2.img .. diskimgN.img] [-l driveletter] - BOOT [cart.jrc] (PCJr only) + BOOT [cart.jrc] (PCjr only) diskimgN.img This can be any number of floppy disk images one wants mounted after @@ -551,8 +554,8 @@ BOOT a hard drive image mounted as master by specifying "-l C" without the quotes, or the drive as slave by specifying "-l D" - cart.jrc (PCJr only) - When emulation of a PCJr is enabled, cartridges can be loaded with + cart.jrc (PCjr only) + When emulation of a PCjr is enabled, cartridges can be loaded with the BOOT command. Support is still limited. diff --git a/include/dos_system.h b/include/dos_system.h index 47c9a43e..8b30d5e3 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.38 2007-01-08 19:45:37 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.39 2007-01-21 16:21:22 c2woody Exp $ */ #ifndef DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H @@ -242,6 +242,9 @@ public: 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}; diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 6b1e5652..1cae4927 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.13 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: cdrom_image.cpp,v 1.14 2007-01-21 16:21:22 c2woody Exp $ */ #include #include @@ -136,9 +136,6 @@ CDROM_Interface_Image::CDROM_Interface_Image(Bit8u subUnit) { images[subUnit] = this; if (refCount == 0) { -#if defined(C_SDL_SOUND) - Sound_Init(); -#endif player.mutex = SDL_CreateMutex(); if (!player.channel) { player.channel = MIXER_AddChannel(&CDAudioCallBack, 44100, "CDAUDIO"); @@ -154,9 +151,6 @@ CDROM_Interface_Image::~CDROM_Interface_Image() if (player.cd == this) player.cd = NULL; ClearTracks(); if (refCount == 0) { -#if defined(C_SDL_SOUND) - Sound_Quit(); -#endif SDL_DestroyMutex(player.mutex); player.channel->Enable(false); } @@ -663,3 +657,16 @@ void CDROM_Interface_Image::ClearTracks() } tracks.clear(); } + +void CDROM_Image_Destroy(Section*) { +#if defined(C_SDL_SOUND) + Sound_Quit(); +#endif +} + +void CDROM_Image_Init(Section* section) { +#if defined(C_SDL_SOUND) + Sound_Init(); + section->AddDestroyFunction(CDROM_Image_Destroy, false); +#endif +} diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index ca749200..3753337a 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.44 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.45 2007-01-21 16:21:22 c2woody Exp $ */ #include #include @@ -109,6 +109,8 @@ public: int RemoveDrive (Bit16u _drive); int AddDrive (Bit16u _drive, char* physicalPath, Bit8u& subUnit); + bool HasDrive (Bit16u drive); + void ReplaceDrive (CDROM_Interface* newCdrom, Bit8u subUnit); void GetDrives (PhysPt data); void GetDriverInfo (PhysPt data); bool GetVolumeName (Bit8u subUnit, char* name); @@ -382,6 +384,16 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) return result; }; +bool CMscdex::HasDrive(Bit16u drive) { + return (GetSubUnit(drive) != 0xff); +} + +void CMscdex::ReplaceDrive(CDROM_Interface* newCdrom, Bit8u subUnit) { + delete cdrom[subUnit]; + cdrom[subUnit] = newCdrom; + StopAudio(subUnit); +} + PhysPt CMscdex::GetDefaultBuffer(void) { if (defaultBufSeg==0) { @@ -1205,6 +1217,16 @@ int MSCDEX_RemoveDrive(char driveLetter) return mscdex->RemoveDrive(driveLetter-'A'); }; +bool MSCDEX_HasDrive(char driveLetter) +{ + return mscdex->HasDrive(driveLetter-'A'); +}; + +void MSCDEX_ReplaceDrive(CDROM_Interface* cdrom, Bit8u subUnit) +{ + mscdex->ReplaceDrive(cdrom, subUnit); +}; + bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name) { return mscdex->GetVolumeName(subUnit,name); diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 285c5baf..41cce0fb 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,11 +16,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.65 2007-01-14 18:44:01 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.66 2007-01-21 16:21:22 c2woody Exp $ */ #include #include #include +#include +#include #include "programs.h" #include "support.h" #include "drives.h" @@ -57,7 +59,7 @@ public: umount[0] = toupper(umount[0]); int i_drive = umount[0]-'A'; if(i_drive < DOS_DRIVES && Drives[i_drive]) { - switch (Drives[i_drive]->UnMount()) { + switch (DriveManager::UnmountDrive(i_drive)) { case 0: Drives[i_drive] = 0; if(i_drive == DOS_GetDefaultDrive()) @@ -822,13 +824,14 @@ public: Bit32u imagesize; char drive; std::string label; + std::vector paths; std::string umount; /* Check for unmounting */ if (cmd->FindString("-u",umount,false)) { umount[0] = toupper(umount[0]); int i_drive = umount[0]-'A'; if (i_drive < DOS_DRIVES && Drives[i_drive]) { - switch (Drives[i_drive]->UnMount()) { + switch (DriveManager::UnmountDrive(i_drive)) { case 0: Drives[i_drive] = 0; if (i_drive == DOS_GetDefaultDrive()) @@ -912,40 +915,47 @@ public: WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FORMAT_UNSUPPORTED")); return; } - - if (!cmd->FindCommand(2,temp_line)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_FILE")); - return; - } - if (!temp_line.size()) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_FILE")); - return; - } - struct stat test; - if (stat(temp_line.c_str(),&test)) { - // convert dosbox filename to system filename - char fullname[CROSS_LEN]; - char tmp[CROSS_LEN]; - safe_strncpy(tmp, temp_line.c_str(), CROSS_LEN); - - Bit8u dummy; - if (!DOS_MakeName(tmp, fullname, &dummy) || strncmp(Drives[dummy]->GetInfo(),"local directory",15)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FILE_NOT_FOUND")); - return; - } - - localDrive *ldp = (localDrive*)Drives[dummy]; - ldp->GetSystemFilename(tmp, fullname); - temp_line = tmp; - - if (stat(temp_line.c_str(),&test)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FILE_NOT_FOUND")); - return; - } - } - if ((test.st_mode & S_IFDIR)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MOUNT")); + // find all file parameters, assuming that all option parameters have been removed + while(cmd->FindCommand(paths.size() + 2, temp_line) && temp_line.size()) { + + struct stat test; + if (stat(temp_line.c_str(),&test)) { + // convert dosbox filename to system filename + char fullname[CROSS_LEN]; + char tmp[CROSS_LEN]; + safe_strncpy(tmp, temp_line.c_str(), CROSS_LEN); + + Bit8u dummy; + if (!DOS_MakeName(tmp, fullname, &dummy) || strncmp(Drives[dummy]->GetInfo(),"local directory",15)) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_NON_LOCAL_DRIVE")); + return; + } + + localDrive *ldp = (localDrive*)Drives[dummy]; + ldp->GetSystemFilename(tmp, fullname); + temp_line = tmp; + + if (stat(temp_line.c_str(),&test)) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNG_FILE_NOT_FOUND")); + return; + } + + if ((test.st_mode & S_IFDIR)) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNG_MOUNT")); + return; + } + } + paths.push_back(temp_line); + } + if (paths.size() == 0) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_FILE")); + return; + } + if (paths.size() == 1) + temp_line = paths[0]; + if (paths.size() > 1 && fstype != "iso") { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MULTIPLE_NON_CUEISO_FILES")); return; } @@ -956,22 +966,6 @@ public: newdrive = 0; } } else if (fstype=="iso") { - int error; - MSCDEX_SetCDInterface(CDROM_USE_SDL, -1); - newdrive = new isoDrive(drive, temp_line.c_str(), mediaid, error); - switch (error) { - case 0 : WriteOut(MSG_Get("MSCDEX_SUCCESS")); break; - case 1 : WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS")); break; - case 2 : WriteOut(MSG_Get("MSCDEX_ERROR_NOT_SUPPORTED")); break; - case 3 : WriteOut(MSG_Get("MSCDEX_ERROR_PATH")); break; - case 4 : WriteOut(MSG_Get("MSCDEX_TOO_MANY_DRIVES")); break; - case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break; - default : WriteOut(MSG_Get("MSCDEX_UNKNOWN_ERROR")); break; - }; - if (error && error!=5) { - delete newdrive; - return; - } } else { FILE *newDisk = fopen(temp_line.c_str(), "rb+"); fseek(newDisk,0L, SEEK_END); @@ -1014,14 +1008,50 @@ public: } else if (fstype=="iso") { if (Drives[drive-'A']) { WriteOut(MSG_Get("PROGRAM_IMGMOUNT_ALREADY_MOUNTED")); - if (newdrive) delete newdrive; return; } - if (!newdrive) WriteOut(MSG_Get("PROGRAM_IMGMOUNT_CANT_CREATE")); - Drives[drive-'A']=newdrive; + MSCDEX_SetCDInterface(CDROM_USE_SDL, -1); + // create new drives for all images + std::vector isoDisks; + for (int i = 0; i < paths.size(); i++) { + int error = -1; + DOS_Drive* newDrive = new isoDrive(drive, paths[i].c_str(), mediaid, error); + isoDisks.push_back(newDrive); + switch (error) { + case 0 : break; + case 1 : WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS")); break; + case 2 : WriteOut(MSG_Get("MSCDEX_ERROR_NOT_SUPPORTED")); break; + case 3 : WriteOut(MSG_Get("MSCDEX_ERROR_PATH")); break; + case 4 : WriteOut(MSG_Get("MSCDEX_TOO_MANY_DRIVES")); break; + case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break; + case 6 : WriteOut(MSG_Get("MSCDEX_INVALID_FILEFORMAT")); break; + default : WriteOut(MSG_Get("MSCDEX_UNKNOWN_ERROR")); break; + } + // error: clean up and leave + if (error) { + for(int i = 0; i < isoDisks.size(); i++) { + delete isoDisks[i]; + } + return; + } + } + // Update DriveManager + for(int i = 0; i < isoDisks.size(); i++) { + DriveManager::AppendDisk(drive - 'A', isoDisks[i]); + } + DriveManager::InitializeDrive(drive - 'A'); + // Set the correct media byte in the table - mem_writeb(Real2Phys(dos.tables.mediaid)+(drive-'A')*2,mediaid); - WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,temp_line.c_str()); + mem_writeb(Real2Phys(dos.tables.mediaid) + (drive - 'A') * 2, mediaid); + + // Print status message (success) + WriteOut(MSG_Get("MSCDEX_SUCCESS")); + std::string tmp(paths[0]); + for (int i = 1; i < paths.size(); i++) { + tmp += "; " + paths[i]; + } + WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"), drive, tmp.c_str()); + } else if (fstype=="none") { if(imageDiskList[drive-'0'] != NULL) delete imageDiskList[drive-'0']; imageDiskList[drive-'0'] = newImage; @@ -1137,6 +1167,7 @@ void DOS_SetupPrograms(void) { MSG_Add("MSCDEX_ERROR_PATH","MSCDEX: Failure: Path not valid.\n"); MSG_Add("MSCDEX_TOO_MANY_DRIVES","MSCDEX: Failure: Too many CDRom-drives (max: 5). MSCDEX Installation failed.\n"); MSG_Add("MSCDEX_LIMITED_SUPPORT","MSCDEX: Mounted subdirectory: limited support.\n"); + MSG_Add("MSCDEX_INVALID_FILEFORMAT","MSCDEX: Failure: File is either no iso/cue image or contains errors.\n"); MSG_Add("MSCDEX_UNKNOWN_ERROR","MSCDEX: Failure: Unknown error.\n"); MSG_Add("PROGRAM_RESCAN_SUCCESS","Drive cache cleared.\n"); @@ -1238,7 +1269,7 @@ void DOS_SetupPrograms(void) { ); MSG_Add("PROGRAM_BOOT_NOT_EXIST","Bootdisk file does not exist. Failing.\n"); MSG_Add("PROGRAM_BOOT_NOT_OPEN","Cannot open bootdisk file. Failing.\n"); - MSG_Add("PROGRAM_BOOT_PRINT_ERROR","This command boots DosBox from either a floppy or hard disk image.\n\n" + MSG_Add("PROGRAM_BOOT_PRINT_ERROR","This command boots DOSBox from either a floppy or hard disk image.\n\n" "For this command, one can specify a succession of floppy disks swappable\n" "by pressing Ctrl-F4, and -l specifies the mounted drive to boot from. If\n" "no drive letter is specified, this defaults to booting from the A drive.\n" @@ -1252,17 +1283,18 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_BOOT_IMAGE_OPEN","Opening image file: %s\n"); MSG_Add("PROGRAM_BOOT_IMAGE_NOT_OPEN","Cannot open %s"); MSG_Add("PROGRAM_BOOT_BOOT","Booting from drive %c...\n"); - MSG_Add("PROGRAM_BOOT_CART_WO_PCJR","PCJr cartridge found, but machine is not PCJr"); - MSG_Add("PROGRAM_BOOT_CART_LIST_CMDS","Available PCJr cartridge commandos:%s"); - MSG_Add("PROGRAM_BOOT_CART_NO_CMDS","No PCJr cartridge commandos found"); + MSG_Add("PROGRAM_BOOT_CART_WO_PCJR","PCjr cartridge found, but machine is not PCjr"); + MSG_Add("PROGRAM_BOOT_CART_LIST_CMDS","Available PCjr cartridge commandos:%s"); + MSG_Add("PROGRAM_BOOT_CART_NO_CMDS","No PCjr cartridge commandos found"); MSG_Add("PROGRAM_IMGMOUNT_SPECIFY_DRIVE","Must specify drive letter to mount image at.\n"); MSG_Add("PROGRAM_IMGMOUNT_SPECIFY2","Must specify drive number (0 or 3) to mount image at (0,1=fda,fdb;2,3=hda,hdb).\n"); MSG_Add("PROGRAM_IMGMOUNT_SPECIFY_GEOMETRY", - "For \033[33mCD-ROM\033[0m images: \033[34;1mimgmount Drive-Letter location-of-image -t iso\033[0m\n" + "For \033[33mCD-ROM\033[0m images: \033[34;1mIMGMOUNT drive-letter location-of-image -t iso\033[0m\n" "\n" "For \033[33mhardrive\033[0m images: Must specify drive geometry for hard drives:\n" - "bytes_per_sector, sectors_per_cylinder, heads_per_cylinder, cylinder_count.\n"); + "bytes_per_sector, sectors_per_cylinder, heads_per_cylinder, cylinder_count.\n" + "\033[34;1mIMGMOUNT drive-letter location-of-image -size bps,spc,hpc,cyl\033[0m\n"); MSG_Add("PROGRAM_IMGMOUNT_TYPE_UNSUPPORTED","Type \"%s\" is unsupported. Specify \"hdd\" or \"floppy\" or\"iso\".\n"); MSG_Add("PROGRAM_IMGMOUNT_FORMAT_UNSUPPORTED","Format \"%s\" is unsupported. Specify \"fat\" or \"iso\" or \"none\".\n"); MSG_Add("PROGRAM_IMGMOUNT_SPECIFY_FILE","Must specify file-image to mount.\n"); @@ -1271,6 +1303,8 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_IMGMOUNT_ALREADY_MOUNTED","Drive already mounted at that letter.\n"); MSG_Add("PROGRAM_IMGMOUNT_CANT_CREATE","Can't create drive from file.\n"); MSG_Add("PROGRAM_IMGMOUNT_MOUNT_NUMBER","Drive number %d mounted as %s\n"); + MSG_Add("PROGRAM_IMGMOUNT_NON_LOCAL_DRIVE", "The image must be on a host or local drive.\n"); + MSG_Add("PROGRAM_IMGMOUNT_MULTIPLE_NON_CUEISO_FILES", "Using multiple files is only supported for cue/iso images.\n"); MSG_Add("PROGRAM_KEYB_INFO","Codepage %i has been loaded\n"); MSG_Add("PROGRAM_KEYB_SHOWHELP", diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 710764e4..dd5ec85b 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.16 2007-01-10 10:47:08 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.17 2007-01-21 16:21:22 c2woody Exp $ */ #include #include @@ -140,7 +140,8 @@ Bit16u isoFile::GetInformation(void) int MSCDEX_RemoveDrive(char driveLetter); int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit); -bool MSCDEX_HasMediaChanged(Bit8u subUnit); +void MSCDEX_ReplaceDrive(CDROM_Interface* cdrom, Bit8u subUnit); +bool MSCDEX_HasDrive(char driveLetter); bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name); isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &error) @@ -150,7 +151,8 @@ isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &e memset(sectorHashEntries, 0, sizeof(sectorHashEntries)); memset(&rootEntry, 0, sizeof(isoDirEntry)); - error = MSCDEX_AddDrive(driveLetter, fileName, subUnit); + safe_strncpy(this->fileName, fileName, CROSS_LEN); + error = UpdateMscdex(driveLetter, fileName, subUnit); if (!error) { if (loadImage()) { @@ -187,6 +189,28 @@ isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &e isoDrive::~isoDrive() { } +int isoDrive::UpdateMscdex(char driveLetter, const char* path, Bit8u& subUnit) { + if (MSCDEX_HasDrive(driveLetter)) { + CDROM_Interface_Image* oldCdrom = CDROM_Interface_Image::images[subUnit]; + CDROM_Interface* cdrom = new CDROM_Interface_Image(subUnit); + char pathCopy[CROSS_LEN]; + safe_strncpy(pathCopy, path, CROSS_LEN); + if (!cdrom->SetDevice(pathCopy, 0)) { + CDROM_Interface_Image::images[subUnit] = oldCdrom; + delete cdrom; + return 3; + } + MSCDEX_ReplaceDrive(cdrom, subUnit); + return 0; + } else { + return MSCDEX_AddDrive(driveLetter, path, subUnit); + } +} + +void isoDrive::Activate(void) { + UpdateMscdex(driveLetter, fileName, subUnit); +} + bool isoDrive::FileOpen(DOS_File **file, char *name, Bit32u flags) { if (flags == OPEN_WRITE) { diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index 9720ff33..fa5f50fc 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -19,6 +19,7 @@ #include "dosbox.h" #include "dos_system.h" #include "drives.h" +#include "mapper.h" #include "support.h" bool WildFileCmp(const char * file, const char * wild) @@ -82,3 +83,113 @@ DOS_Drive::DOS_Drive() { char * DOS_Drive::GetInfo(void) { return info; } + +// static members variables +int DriveManager::currentDrive; +DriveManager::DriveInfo DriveManager::driveInfos[26]; + +void DriveManager::AppendDisk(int drive, DOS_Drive* disk) { + driveInfos[drive].disks.push_back(disk); +} + +void DriveManager::InitializeDrive(int drive) { + currentDrive = drive; + DriveInfo& driveInfo = driveInfos[currentDrive]; + if (driveInfo.disks.size() > 0) { + driveInfo.currentDisk = 0; + DOS_Drive* disk = driveInfo.disks[driveInfo.currentDisk]; + Drives[currentDrive] = disk; + disk->Activate(); + } +} + +/* +void DriveManager::CycleDrive(bool pressed) { + if (!pressed) return; + + // do one round through all drives or stop at the next drive with multiple disks + int oldDrive = currentDrive; + do { + currentDrive = (currentDrive + 1) % DOS_DRIVES; + int numDisks = driveInfos[currentDrive].disks.size(); + if (numDisks > 1) break; + } while (currentDrive != oldDrive); +} + +void DriveManager::CycleDisk(bool pressed) { + if (!pressed) return; + + int numDisks = driveInfos[currentDrive].disks.size(); + if (numDisks > 1) { + // cycle disk + int currentDisk = driveInfos[currentDrive].currentDisk; + DOS_Drive* oldDisk = driveInfos[currentDrive].disks[currentDisk]; + currentDisk = (currentDisk + 1) % numDisks; + DOS_Drive* newDisk = driveInfos[currentDrive].disks[currentDisk]; + driveInfos[currentDrive].currentDisk = currentDisk; + + // copy working directory, acquire system resources and finally switch to next drive + strcpy(newDisk->curdir, oldDisk->curdir); + newDisk->Activate(); + Drives[currentDrive] = newDisk; + } +} +*/ + +void DriveManager::CycleAllDisks(void) { + for (int idrive=0; idrive 1) { + // cycle disk + int currentDisk = driveInfos[idrive].currentDisk; + DOS_Drive* oldDisk = driveInfos[idrive].disks[currentDisk]; + currentDisk = (currentDisk + 1) % numDisks; + DOS_Drive* newDisk = driveInfos[idrive].disks[currentDisk]; + driveInfos[idrive].currentDisk = currentDisk; + + // copy working directory, acquire system resources and finally switch to next drive + strcpy(newDisk->curdir, oldDisk->curdir); + newDisk->Activate(); + Drives[idrive] = newDisk; + LOG_MSG("Drive %c: disk %d of %d now active", 'A'+idrive, currentDisk+1, numDisks); + } + } +} + +int DriveManager::UnmountDrive(int drive) { + int result = 0; + // unmanaged drive + if (driveInfos[drive].disks.size() == 0) { + result = Drives[drive]->UnMount(); + } else { + // managed drive + int currentDisk = driveInfos[drive].currentDisk; + result = driveInfos[drive].disks[currentDisk]->UnMount(); + // only delete on success, current disk set to NULL because of UnMount + if (result == 0) { + driveInfos[drive].disks[currentDisk] = NULL; + for (int i = 0; i < (int)driveInfos[drive].disks.size(); i++) { + delete driveInfos[drive].disks[i]; + } + driveInfos[drive].disks.clear(); + } + } + + return result; +} + +void DriveManager::Init(Section* /* sec */) { + + // setup driveInfos structure + currentDrive = 0; + for(int i = 0; i < DOS_DRIVES; i++) { + driveInfos[i].currentDisk = 0; + } + +// MAPPER_AddHandler(&CycleDisk, MK_f3, MMOD1, "cycledisk", "Cycle Disk"); +// MAPPER_AddHandler(&CycleDrive, MK_f3, MMOD2, "cycledrive", "Cycle Drv"); +} + +void DRIVES_Init(Section* sec) { + DriveManager::Init(sec); +} diff --git a/src/dos/drives.h b/src/dos/drives.h index 052b618c..51d618fd 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.35 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: drives.h,v 1.36 2007-01-21 16:21:22 c2woody Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ @@ -29,6 +29,25 @@ bool WildFileCmp(const char * file, const char * wild); +class DriveManager { +public: + static void AppendDisk(int drive, DOS_Drive* disk); + static void InitializeDrive(int drive); + static int UnmountDrive(int drive); +// static void CycleDrive(bool pressed); +// static void CycleDisk(bool pressed); + static void CycleAllDisks(void); + static void Init(Section* sec); + +private: + static struct DriveInfo { + std::vector disks; + Bit32u currentDisk; + } driveInfos[DOS_DRIVES]; + + static int currentDrive; +}; + class localDrive : public DOS_Drive { public: localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid); @@ -311,12 +330,13 @@ public: virtual Bits UnMount(void); bool readSector(Bit8u *buffer, Bit32u sector); virtual char const* GetLabel(void) {return discLabel;}; + virtual void Activate(void); private: int readDirEntry(isoDirEntry *de, Bit8u *data); bool loadImage(); bool lookupSingle(isoDirEntry *de, const char *name, Bit32u sectorStart, Bit32u length); bool lookup(isoDirEntry *de, const char *path); - + int UpdateMscdex(char driveLetter, const char* physicalPath, Bit8u& subUnit); int GetDirIterator(const isoDirEntry* de); bool GetNextDirEntry(const int dirIterator, isoDirEntry* de); void FreeDirIterator(const int dirIterator); @@ -339,6 +359,7 @@ private: isoDirEntry rootEntry; Bit8u mediaid; + char fileName[CROSS_LEN]; Bit8u subUnit; char driveLetter; char discLabel[32]; diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 23433d71..0bd3b423 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.111 2007-01-13 08:35:49 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.112 2007-01-21 16:21:22 c2woody Exp $ */ #include #include @@ -96,6 +96,8 @@ void DEBUG_Init(Section*); void CMOS_Init(Section*); void MSCDEX_Init(Section*); +void DRIVES_Init(Section*); +void CDROM_Image_Init(Section*); /* Dos Internal mostly */ void EMS_Init(Section*); @@ -456,6 +458,8 @@ void DOSBOX_Init(void) { ); // Mscdex secprop->AddInitFunction(&MSCDEX_Init); + secprop->AddInitFunction(&DRIVES_Init); + secprop->AddInitFunction(&CDROM_Image_Init); #if C_IPX secprop=control->AddSection_prop("ipx",&IPX_Init,true); secprop->Add_bool("ipx", false); diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 34c03ea3..48e4196e 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.32 2007-01-14 18:44:01 c2woody Exp $ */ +/* $Id: bios_disk.cpp,v 1.33 2007-01-21 16:21:22 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" @@ -24,6 +24,7 @@ #include "regs.h" #include "mem.h" #include "dos_inc.h" /* for Drives[] */ +#include "../dos/drives.h" #include "mapper.h" #define MAX_DISK_IMAGES 4 @@ -124,6 +125,7 @@ void swapInNextDisk(bool pressed) { if (!pressed) return; /* Hack/feature: rescan all disks as well */ + DriveManager::CycleAllDisks(); for(Bitu i=0;iEmptyCache(); } @@ -396,6 +398,7 @@ static Bitu INT13_DiskHandler(void) { return CBRET_NONE; } } + reg_ah = 0x00; CALLBACK_SCF(false); break; case 0x04: /* Verify sectors */ From 103cd7f6c9d2fc577b433b55bf081e533c195939 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 21 Jan 2007 16:36:38 +0000 Subject: [PATCH 2694/4131] Easier startup maintainance this way. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2779 --- src/shell/shell.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 6fba8246..72365880 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.82 2007-01-21 14:13:21 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.83 2007-01-21 16:36:38 qbix79 Exp $ */ #include #include @@ -291,7 +291,7 @@ void DOS_Shell::Run(void) { return; } /* Start a normal shell and check for a first command init */ - WriteOut(MSG_Get("SHELL_STARTUP_BEGIN")); + WriteOut(MSG_Get("SHELL_STARTUP_BEGIN"),VERSION); #if C_DEBUG WriteOut(MSG_Get("SHELL_STARTUP_DEBUG")); #endif @@ -456,7 +456,7 @@ void SHELL_Init() { "\033[44;1m\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n" - "\xBA \033[32mWelcome to DOSBox v" VERSION "\033[37m \xBA\n" + "\xBA \033[32mWelcome to DOSBox v%-8s\033[37m \xBA\n" "\xBA \xBA\n" // "\xBA DOSBox runs real and protected mode games. \xBA\n" "\xBA For a short introduction for new users type: \033[33mINTRO\033[37m \xBA\n" From 667c756775e20f7f7a54bbd4473ff4e1fdcb7401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 21 Jan 2007 18:14:52 +0000 Subject: [PATCH 2695/4131] enhance cycles config variable a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2780 --- include/cpu.h | 1 + src/cpu/cpu.cpp | 72 +++++++++++++++++++++++++++++++++++++++++++------ src/dosbox.cpp | 5 +++- 3 files changed, 69 insertions(+), 9 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 38bb2e42..f8429d7d 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -42,6 +42,7 @@ extern Bit32s CPU_CycleLeft; extern Bit32s CPU_CycleMax; extern Bit32s CPU_OldCycleMax; extern Bit32s CPU_CyclePercUsed; +extern Bit32s CPU_CycleLimit; extern bool CPU_CycleAutoAdjust; extern Bitu CPU_AutoDetermineMode; diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index b8fa7255..359c43db 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,9 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.95 2007-01-18 14:29:48 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.96 2007-01-21 18:14:52 c2woody Exp $ */ #include +#include #include "dosbox.h" #include "cpu.h" #include "memory.h" @@ -47,9 +48,10 @@ Segments Segs; Bit32s CPU_Cycles = 0; Bit32s CPU_CycleLeft = 0; -Bit32s CPU_CycleMax = 2500; -Bit32s CPU_OldCycleMax = 2500; +Bit32s CPU_CycleMax = 3000; +Bit32s CPU_OldCycleMax = 3000; Bit32s CPU_CyclePercUsed = 100; +Bit32s CPU_CycleLimit = -1; Bit32s CPU_CycleUp = 0; Bit32s CPU_CycleDown = 0; CPU_Decoder * cpudecoder; @@ -2058,19 +2060,73 @@ public: CPU_AutoDetermineMode=CPU_AUTODETERMINE_NONE; CPU_CycleLeft=0;//needed ? CPU_Cycles=0; - const char *cyclesLine = section->Get_string("cycles"); - if (!strcasecmp(cyclesLine,"max")) { + + std::string str; + CommandLine* cmd = new CommandLine(0,section->Get_string("cycles")); + cmd->FindCommand(1,str); + + if (str=="max") { CPU_CycleMax=0; CPU_CyclePercUsed=100; CPU_CycleAutoAdjust=true; + CPU_CycleLimit=-1; + for (Bitu cmdnum=2; cmdnum<=cmd->GetCount(); cmdnum++) { + if (cmd->FindCommand(cmdnum,str)) { + if (str.find('%')==str.length()-1) { + str.erase(str.find('%')); + int percval=0; + std::istringstream stream(str); + stream >> percval; + if ((percval>0) && (percval<=100)) CPU_CyclePercUsed=(Bit32s)percval; + } else if (str=="limit") { + cmdnum++; + if (cmd->FindCommand(cmdnum,str)) { + int cyclimit=0; + std::istringstream stream(str); + stream >> cyclimit; + if (cyclimit>0) CPU_CycleLimit=cyclimit; + } + } + } + } } else { - if (!strcasecmp(cyclesLine,"auto")) { + if (str=="auto") { CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CYCLES; CPU_CycleMax=3000; CPU_OldCycleMax=3000; CPU_CyclePercUsed=100; + for (Bitu cmdnum=2; cmdnum<=cmd->GetCount(); cmdnum++) { + if (cmd->FindCommand(cmdnum,str)) { + if (str.find('%')==str.length()-1) { + str.erase(str.find('%')); + int percval=0; + std::istringstream stream(str); + stream >> percval; + if ((percval>0) && (percval<=100)) CPU_CyclePercUsed=(Bit32s)percval; + } else if (str=="limit") { + cmdnum++; + if (cmd->FindCommand(cmdnum,str)) { + int cyclimit=0; + std::istringstream stream(str); + stream >> cyclimit; + if (cyclimit>0) CPU_CycleLimit=cyclimit; + } + } else { + int rmdval=0; + std::istringstream stream(str); + stream >> rmdval; + if (rmdval>0) { + CPU_CycleMax=(Bit32s)rmdval; + CPU_OldCycleMax=(Bit32s)rmdval; + } + } + } + } } else { - CPU_CycleMax=atoi(cyclesLine); + int rmdval=0; + std::istringstream stream(str); + stream >> rmdval; + CPU_CycleMax=(Bit32s)rmdval; } CPU_CycleAutoAdjust=false; } @@ -2105,7 +2161,7 @@ public: CPU_Core_Dyn_X86_Cache_Init(!strcasecmp(core,"dynamic") || !strcasecmp(core,"dynamic_nodhfpu")); #endif - if(CPU_CycleMax <= 0) CPU_CycleMax = 2500; + if(CPU_CycleMax <= 0) CPU_CycleMax = 3000; if(CPU_CycleUp <= 0) CPU_CycleUp = 500; if(CPU_CycleDown <= 0) CPU_CycleDown = 20; if (CPU_CycleAutoAdjust) GFX_SetTitle(CPU_CyclePercUsed,-1,false); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 0bd3b423..c4ae9c41 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.112 2007-01-21 16:21:22 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.113 2007-01-21 18:14:40 c2woody Exp $ */ #include #include @@ -170,6 +170,9 @@ increaseticks: CPU_CycleMax = (CPU_CycleMax * ratio) / 1024; else CPU_CycleMax = 1 + (CPU_CycleMax >> 1) + (CPU_CycleMax * ratio) / 2048; + if (CPU_CycleLimit>0) { + if (CPU_CycleMax>CPU_CycleLimit) CPU_CycleMax=CPU_CycleLimit; + } ticksDone = 0; ticksScheduled = 0; } From 5660ee18561aa3d48c732008726e641bfddf48a2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 24 Jan 2007 16:29:09 +0000 Subject: [PATCH 2696/4131] 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 added Renderer does initial pass to check for needing to lock buffer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2781 --- include/render.h | 11 +- include/vga.h | 86 ++++-- src/gui/render.cpp | 153 +++++++--- src/gui/render_loops.h | 26 +- src/gui/render_scalers.cpp | 10 + src/gui/render_simple.h | 33 ++- src/gui/render_templates.h | 8 + src/gui/sdlmain.cpp | 17 +- src/hardware/vga.cpp | 1 - src/hardware/vga_crtc.cpp | 24 ++ src/hardware/vga_draw.cpp | 546 +++++++++++++++++++++------------- src/hardware/vga_memory.cpp | 566 +++++++++++++++++++++++------------- src/hardware/vga_misc.cpp | 56 ++-- src/hardware/vga_other.cpp | 133 ++++++--- src/ints/int10.cpp | 5 +- src/ints/int10_modes.cpp | 22 +- 16 files changed, 1132 insertions(+), 565 deletions(-) diff --git a/include/render.h b/include/render.h index c3dc8603..93d20f29 100644 --- a/include/render.h +++ b/include/render.h @@ -21,6 +21,10 @@ #include "../src/gui/render_scalers.h" +#define RENDER_SKIP_CACHE 16 +//Enable this for scalers to support 0 input for empty lines +//#define RENDER_NULL_INPUT + typedef struct { struct { Bit8u red; @@ -40,7 +44,7 @@ typedef struct { typedef struct { struct { - Bitu width; + Bitu width, start; Bitu height; Bitu bpp; bool dblw,dblh; @@ -50,6 +54,8 @@ typedef struct { struct { Bitu count; Bitu max; + Bitu index; + Bit8u hadSkip[RENDER_SKIP_CACHE]; } frameskip; struct { Bitu size; @@ -71,13 +77,14 @@ typedef struct { 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( bool fullUpdate ); +void RENDER_EndUpdate( ); void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue); diff --git a/include/vga.h b/include/vga.h index 6f60c63b..0c6fb456 100644 --- a/include/vga.h +++ b/include/vga.h @@ -23,8 +23,18 @@ #include "dosbox.h" #endif +//Don't enable keeping changes and mapping lfb probably... +#define VGA_LFB_MAPPED +//#define VGA_KEEP_CHANGES +#define VGA_MEMORY (2*1024*1024) +#define VGA_CHANGE_SHIFT 9 + +//Offset inside VGA_MEMORY that will be used for certain types of caching +#define VGA_CACHE_OFFSET (512*1024) + class PageHandler; + enum VGAModes { M_CGA2, M_CGA4, M_EGA, M_VGA, @@ -70,6 +80,7 @@ typedef struct { 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 */ @@ -97,6 +108,10 @@ typedef struct { Bitu blocks; Bitu panning; Bitu address; + Bit8u *linear_base; + Bitu linear_mask; + Bitu address_mask; + Bitu address_last; Bitu address_add; Bitu address_line_total; Bitu address_line; @@ -108,13 +123,14 @@ typedef struct { Bitu parts_lines; Bitu parts_left; struct { - float vtotal; - float vstart; - float vend; - float htotal; - float hstart; - float hend; - float parts; + 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; bool double_scan; bool doublewidth,doubleheight; @@ -194,31 +210,36 @@ typedef struct { Bit8u htotal; Bit8u hdend; Bit8u hsyncp; - Bit8u hsyncw; + 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 mem_bank; Bit8u disp_bank; Bit8u reg_index; Bit8u gfx_control; Bit8u palette_mask; + Bit8u extended_ram; Bit8u border_color; - bool is_32k_mode; - bool pcjr_flipflop; + 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; @@ -281,11 +302,11 @@ typedef struct { Bit8u bit_mask; } VGA_Gfx; -struct RGBEntry { +typedef struct { Bit8u red; Bit8u green; Bit8u blue; -}; +} RGBEntry; typedef struct { Bit8u bits; /* DAC bits, usually 6 or 8 */ @@ -298,16 +319,30 @@ typedef struct { RGBEntry rgb[0x100]; } VGA_Dac; -union VGA_Latch { +typedef struct { + Bitu readStart, writeStart; + Bitu bankMask; +} VGA_SVGA; + +typedef union { Bit32u d; Bit8u b[4]; -}; +} VGA_Latch; -union VGA_Memory { - Bit8u linear[512*1024*4]; - Bit8u paged[512*1024][4]; - VGA_Latch latched[512*1024]; -}; +typedef struct { + Bit8u linear[VGA_MEMORY]; +} VGA_Memory; + +typedef struct { + //Add a few more just to be safe + Bit8u map[(VGA_MEMORY >> VGA_CHANGE_SHIFT) + 32]; + Bit8u checkMask, frame, writeMask; + bool active; + Bit32u lineWidth; + Bit32u clearMask; + Bit32u start, last; + Bit32u lastAddress; +} VGA_Changes; typedef struct { Bit32u page; @@ -316,8 +351,6 @@ typedef struct { PageHandler *handler; } VGA_LFB; -#define VGA_CHANGE_SHIFT 9 -typedef Bit8u VGA_Changed[(2*1024*1024) >> VGA_CHANGE_SHIFT]; typedef struct { VGAModes mode; /* The mode the vga system is in */ VGAModes lastmode; @@ -333,13 +366,15 @@ typedef struct { VGA_Dac dac; VGA_Latch latch; VGA_S3 s3; + VGA_SVGA svga; VGA_HERC herc; VGA_TANDY tandy; VGA_OTHER other; VGA_Memory mem; +#ifdef VGA_KEEP_CHANGES + VGA_Changes changes; +#endif VGA_LFB lfb; - VGA_Changed changed; - Bit8u * gfxmem_start; } VGA_Type; @@ -351,6 +386,7 @@ void VGA_SetupHandlers(void); void VGA_StartResize(void); 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); diff --git a/src/gui/render.cpp b/src/gui/render.cpp index e25c9087..37316ea7 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.49 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.50 2007-01-24 16:29:09 harekiet Exp $ */ #include #include @@ -37,6 +37,8 @@ Render_t render; ScalerLineHandler_t RENDER_DrawLine; +static void RENDER_CallBack( GFX_CallBackFunctions_t function ); + static void Check_Palette(void) { /* Clean up any previous changed palette data */ if (render.pal.changed) { @@ -95,6 +97,30 @@ void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue) { static void RENDER_EmptyLineHandler(const void * src) { } +static void RENDER_StartLineHandler(const void * s) { + if (s) { + const Bitu *src = (Bitu*)s; + Bitu *cache = (Bitu*)(render.scale.cacheRead); + for (Bits x=render.src.start;x>0;) { + if (GCC_UNLIKELY(src[0] != cache[0])) { + if (!GFX_StartUpdate( render.scale.outWrite, render.scale.outPitch )) { + RENDER_DrawLine = RENDER_EmptyLineHandler; + return; + } + render.scale.outWrite += render.scale.outPitch * Scaler_ChangedLines[0]; + RENDER_DrawLine = render.scale.lineHandler; + RENDER_DrawLine( s ); + return; + } + x--; src++; cache++; + } + } + render.scale.cacheRead += render.scale.cachePitch; + Scaler_ChangedLines[0] += Scaler_Aspect[ render.scale.inLine ]; + render.scale.inLine++; + render.scale.outLine++; +} + static void RENDER_ClearCacheHandler(const void * src) { Bitu x, width; Bit32u *srcLine, *cacheLine; @@ -119,33 +145,54 @@ bool RENDER_StartUpdate(void) { if (render.scale.inMode == scalerMode8) { Check_Palette(); } - if (GCC_UNLIKELY(!GFX_StartUpdate(render.scale.outWrite,render.scale.outPitch))) - return false; render.scale.inLine = 0; render.scale.outLine = 0; render.scale.cacheRead = (Bit8u*)&scalerSourceCache; + render.scale.outWrite = 0; + render.scale.outPitch = 0; Scaler_ChangedLines[0] = 0; Scaler_ChangedLineIndex = 0; /* Clearing the cache will first process the line to make sure it's never the same */ if (GCC_UNLIKELY( render.scale.clearCache) ) { // LOG_MSG("Clearing cache"); + //Will always have to update the screen with this one anyway, so let's update already + if (GCC_UNLIKELY(!GFX_StartUpdate( render.scale.outWrite, render.scale.outPitch ))) + return false; + render.fullFrame = true; render.scale.clearCache = false; RENDER_DrawLine = RENDER_ClearCacheHandler; } else { - if (render.pal.changed) + if (render.pal.changed) { + /* Assume pal changes always do a full screen update anyway */ + if (GCC_UNLIKELY(!GFX_StartUpdate( render.scale.outWrite, render.scale.outPitch ))) + return false; RENDER_DrawLine = render.scale.linePalHandler; - else - RENDER_DrawLine = render.scale.lineHandler; + render.fullFrame = true; + } else { + RENDER_DrawLine = RENDER_StartLineHandler; + if (GCC_UNLIKELY(CaptureState & (CAPTURE_IMAGE|CAPTURE_VIDEO))) + render.fullFrame = true; + else + render.fullFrame = false; + } } - render.updating=true; + render.updating = true; return true; } -void RENDER_EndUpdate( bool fullUpdate ) { - if (!render.updating) +static void RENDER_Halt( void ) { + RENDER_DrawLine = RENDER_EmptyLineHandler; + GFX_EndUpdate( 0 ); + render.updating=false; + render.active=false; +} + +extern Bitu PIC_Ticks; +void RENDER_EndUpdate( void ) { + if (GCC_UNLIKELY(!render.updating)) return; RENDER_DrawLine = RENDER_EmptyLineHandler; - if (CaptureState & (CAPTURE_IMAGE|CAPTURE_VIDEO)) { + if (GCC_UNLIKELY(CaptureState & (CAPTURE_IMAGE|CAPTURE_VIDEO))) { Bitu pitch, flags; flags = 0; if (render.src.dblw != render.src.dblh) { @@ -159,40 +206,46 @@ void RENDER_EndUpdate( bool fullUpdate ) { CAPTURE_AddImage( render.src.width, render.src.height, render.src.bpp, pitch, flags, fps, (Bit8u *)&scalerSourceCache, (Bit8u*)&render.pal.rgb ); } - GFX_EndUpdate( fullUpdate ? Scaler_ChangedLines : 0); + if ( render.scale.outWrite ) { + GFX_EndUpdate( Scaler_ChangedLines ); + render.frameskip.hadSkip[render.frameskip.index] = 0; + } else { +#if 0 + Bitu total = 0, i; + render.frameskip.hadSkip[render.frameskip.index] = 1; + for (i = 0;i=miny) { - Bitu templines=(Bitu)lines; - lines-=templines; - linesadded+=templines; - Scaler_Aspect[1+i]=templines-miny; - } else Scaler_Aspect[1+i]=0; + for (i=0;i= miny) { + Bitu templines = (Bitu)lines; + lines -= templines; + linesadded += templines; + Scaler_Aspect[i] = templines; + } else { + Scaler_Aspect[i] = 0; + } } return linesadded; } -void RENDER_CallBack( GFX_CallBackFunctions_t function ) { - if (render.updating) { - /* Still updating the current screen, shut it down correctly */ - RENDER_EndUpdate( false ); - } - - if (function == GFX_CallBackStop) - return; - - if (function == GFX_CallBackRedraw) { - //LOG_MSG("redraw"); - render.scale.clearCache = true; - return; - } +static void RENDER_Reset( void ) { Bitu width=render.src.width; Bitu height=render.src.height; bool dblw=render.src.dblw; @@ -301,20 +354,24 @@ forcenormal: } switch (render.src.bpp) { case 8: + render.src.start = ( render.src.width * 1) / sizeof(Bitu); if (gfx_flags & GFX_CAN_8) gfx_flags |= GFX_LOVE_8; else gfx_flags |= GFX_LOVE_32; break; case 15: + render.src.start = ( render.src.width * 2) / sizeof(Bitu); gfx_flags |= GFX_LOVE_15; gfx_flags = (gfx_flags & ~GFX_CAN_8) | GFX_RGBONLY; break; case 16: + render.src.start = ( render.src.width * 2) / sizeof(Bitu); gfx_flags |= GFX_LOVE_16; gfx_flags = (gfx_flags & ~GFX_CAN_8) | GFX_RGBONLY; break; case 32: + render.src.start = ( render.src.width * 4) / sizeof(Bitu); gfx_flags |= GFX_LOVE_32; gfx_flags = (gfx_flags & ~GFX_CAN_8) | GFX_RGBONLY; break; @@ -327,15 +384,16 @@ forcenormal: goto forcenormal; } width *= xscale; + Bitu skip = complexBlock ? 1 : 0; if (gfx_flags & GFX_SCALING) { - height = MakeAspectTable(render.src.height, yscale, yscale ); + height = MakeAspectTable(skip, render.src.height, yscale, yscale ); } else { if ((gfx_flags & GFX_CAN_RANDOM) && gfx_scaleh > 1) { gfx_scaleh *= yscale; - height = MakeAspectTable(render.src.height, gfx_scaleh, yscale ); + height = MakeAspectTable( skip, render.src.height, gfx_scaleh, yscale ); } else { gfx_flags &= ~GFX_CAN_RANDOM; //Hardware surface when possible - height = MakeAspectTable(render.src.height, yscale, yscale); + height = MakeAspectTable( skip, render.src.height, yscale, yscale); } } /* Setup the scaler variables */ @@ -409,12 +467,26 @@ forcenormal: render.active=true; } +static void RENDER_CallBack( GFX_CallBackFunctions_t function ) { + if (function == GFX_CallBackStop) { + RENDER_Halt( ); + return; + } else if (function == GFX_CallBackRedraw) { + render.scale.clearCache = true; + return; + } else if ( function == GFX_CallBackReset) { + GFX_EndUpdate( 0 ); + RENDER_Reset(); + } else { + E_Exit("Unhandled GFX_CallBackReset %d", function ); + } +} + void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool dblw,bool dblh) { + RENDER_Halt( ); if (!width || !height || width > SCALER_MAXWIDTH || height > SCALER_MAXHEIGHT) { - render.active=false; return; } - RENDER_EndUpdate( false ); render.src.width=width; render.src.height=height; render.src.bpp=bpp; @@ -422,7 +494,7 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool render.src.dblh=dblh; render.src.fps=fps; render.src.ratio=ratio; - RENDER_CallBack( GFX_CallBackReset ); + RENDER_Reset( ); } extern void GFX_SetTitle(Bit32s cycles, Bits frameskip,bool paused); @@ -499,6 +571,7 @@ void RENDER_Init(Section * sec) { //If something changed that needs a ReInit if(running && (render.aspect != aspect || render.scale.op != scaleOp)) RENDER_CallBack( GFX_CallBackReset ); + if(!running) render.updating=true; running = true; diff --git a/src/gui/render_loops.h b/src/gui/render_loops.h index bc6799cc..a87c7fb8 100644 --- a/src/gui/render_loops.h +++ b/src/gui/render_loops.h @@ -21,6 +21,7 @@ static void conc3d(SCALERNAME,SBPP,L)(void) { #else static void conc3d(SCALERNAME,SBPP,R)(void) { #endif +//Skip the first one for multiline input scalers if (!render.scale.outLine) { render.scale.outLine++; return; @@ -30,14 +31,9 @@ lastagain: #if defined(SCALERLINEAR) Bitu scaleLines = SCALERHEIGHT; #else - Bitu scaleLines = SCALERHEIGHT + Scaler_Aspect[ render.scale.outLine ]; + Bitu scaleLines = Scaler_Aspect[ render.scale.outLine ]; #endif - render.scale.outWrite += render.scale.outPitch * scaleLines; - if (!(Scaler_ChangedLineIndex & 1)) { - Scaler_ChangedLines[Scaler_ChangedLineIndex] += scaleLines; - } else { - Scaler_ChangedLines[++Scaler_ChangedLineIndex] = scaleLines; - } + ScalerAddLines( 0, scaleLines ); if (++render.scale.outLine == render.scale.inHeight) goto lastagain; return; @@ -141,25 +137,15 @@ lastagain: } #if defined(SCALERLINEAR) Bitu scaleLines = SCALERHEIGHT; - render.scale.outWrite += render.scale.outPitch * scaleLines; #else - Bitu scaleLines = SCALERHEIGHT; - if ( Scaler_Aspect[ render.scale.outLine ] ) { - scaleLines++; + Bitu scaleLines = Scaler_Aspect[ render.scale.outLine ]; + if ( ((Bits)(scaleLines - SCALERHEIGHT)) > 0 ) { BituMove( render.scale.outWrite + render.scale.outPitch * SCALERHEIGHT, render.scale.outWrite + render.scale.outPitch * (SCALERHEIGHT-1), render.src.width * SCALERWIDTH * PSIZE); - render.scale.outWrite += render.scale.outPitch * (SCALERHEIGHT + 1); - } else { - render.scale.outWrite += render.scale.outPitch * SCALERHEIGHT; } #endif - /* Keep track of changed lines */ - if (Scaler_ChangedLineIndex & 1) { - Scaler_ChangedLines[Scaler_ChangedLineIndex] += scaleLines; - } else { - Scaler_ChangedLines[++Scaler_ChangedLineIndex] = scaleLines; - } + ScalerAddLines( 1, scaleLines ); if (++render.scale.outLine == render.scale.inHeight) goto lastagain; } diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index baeb3d59..ad6ae67d 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -59,6 +59,16 @@ static INLINE void BituMove( void *_dst, const void * _src, Bitu size) { dst[x] = src[x]; } +static INLINE void ScalerAddLines( Bitu changed, Bitu count ) { + if ((Scaler_ChangedLineIndex & 1) == changed ) { + Scaler_ChangedLines[Scaler_ChangedLineIndex] += count; + } else { + Scaler_ChangedLines[++Scaler_ChangedLineIndex] = count; + } + render.scale.outWrite += render.scale.outPitch * count; +} + + #define BituMove2(_DST,_SRC,_SIZE) \ { \ Bitu bsize=(_SIZE)/sizeof(Bitu); \ diff --git a/src/gui/render_simple.h b/src/gui/render_simple.h index c1c9cfb4..4581a5e2 100644 --- a/src/gui/render_simple.h +++ b/src/gui/render_simple.h @@ -20,13 +20,25 @@ static void conc4d(SCALERNAME,SBPP,DBPP,L)(const void *s) { #else static void conc4d(SCALERNAME,SBPP,DBPP,R)(const void *s) { +#endif +#ifdef RENDER_NULL_INPUT + if (!s) { + render.scale.cacheRead += render.scale.cachePitch; +#if defined(SCALERLINEAR) + Bitu skipLines = SCALERHEIGHT; +#else + Bitu skipLines = Scaler_Aspect[ render.scale.outLine++ ]; +#endif + ScalerAddLines( 0, skipLines ); + return; + } #endif /* Clear the complete line marker */ + Bitu hadChange; const SRCTYPE *src = (SRCTYPE*)s; SRCTYPE *cache = (SRCTYPE*)(render.scale.cacheRead); render.scale.cacheRead += render.scale.cachePitch; PTYPE * line0=(PTYPE *)(render.scale.outWrite); - Bitu hadChange = 0; #if (SBPP == 9) for (Bits x=render.src.width;x>0;) { if (*(Bit32u const*)src == *(Bit32u*)cache && !( @@ -90,26 +102,15 @@ static void conc4d(SCALERNAME,SBPP,DBPP,R)(const void *s) { } #if defined(SCALERLINEAR) Bitu scaleLines = SCALERHEIGHT; - render.scale.outWrite += render.scale.outPitch * scaleLines; #else - Bitu scaleLines = SCALERHEIGHT; - if ( Scaler_Aspect[ render.scale.outLine++ ] ) { - scaleLines++; - if (hadChange) - BituMove( render.scale.outWrite + render.scale.outPitch * SCALERHEIGHT, + Bitu scaleLines = Scaler_Aspect[ render.scale.outLine++ ]; + if ( scaleLines - SCALERHEIGHT && hadChange ) { + BituMove( render.scale.outWrite + render.scale.outPitch * SCALERHEIGHT, render.scale.outWrite + render.scale.outPitch * (SCALERHEIGHT-1), render.src.width * SCALERWIDTH * PSIZE); - render.scale.outWrite += render.scale.outPitch * (SCALERHEIGHT + 1); - } else { - render.scale.outWrite += render.scale.outPitch * SCALERHEIGHT; - } - /* Keep track of changed lines */ - if ((Scaler_ChangedLineIndex & 1) == hadChange) { - Scaler_ChangedLines[Scaler_ChangedLineIndex] += scaleLines; - } else { - Scaler_ChangedLines[++Scaler_ChangedLineIndex] = scaleLines; } #endif + ScalerAddLines( hadChange, scaleLines ); } #if !defined(SCALERLINEAR) diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index f697ef77..a3ce579b 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -153,6 +153,14 @@ static void conc3d(Cache,SBPP,DBPP) (const void * s) { +#ifdef RENDER_NULL_INPUT + if (!s) { + render.scale.cacheRead += render.scale.cachePitch; + render.scale.inLine++; + render.scale.complexHandler(); + return; + } +#endif const SRCTYPE * src = (SRCTYPE*)s; PTYPE *fc= &FC[render.scale.inLine+1][1]; SRCTYPE *sc = (SRCTYPE*)(render.scale.cacheRead); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index d8097360..7f885a10 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.126 2007-01-10 15:01:15 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.127 2007-01-24 16:29:09 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -328,7 +328,8 @@ check_gotbpp: void GFX_ResetScreen(void) { GFX_Stop(); - if (sdl.draw.callback) (sdl.draw.callback)( GFX_CallBackReset ); + if (sdl.draw.callback) + (sdl.draw.callback)( GFX_CallBackReset ); GFX_Start(); } @@ -661,7 +662,8 @@ static void SwitchFullScreen(bool pressed) { bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) { - if (!sdl.active || sdl.updating) return false; + if (!sdl.active || sdl.updating) + return false; switch (sdl.desktop.type) { case SCREEN_SURFACE: if (sdl.blit.surface) { @@ -710,7 +712,8 @@ bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) { void GFX_EndUpdate( const Bit16u *changedLines ) { int ret; - if (!sdl.updating) return; + if (!sdl.updating) + return; sdl.updating=false; switch (sdl.desktop.type) { case SCREEN_SURFACE: @@ -745,15 +748,11 @@ void GFX_EndUpdate( const Bit16u *changedLines ) { } if (rectCount) SDL_UpdateRects( sdl.surface, rectCount, sdl.updateRects ); - } else { - SDL_Flip(sdl.surface); } break; #if (HAVE_DDRAW_H) && defined(WIN32) case SCREEN_SURFACE_DDRAW: - if (SDL_MUSTLOCK(sdl.blit.surface)) { - SDL_UnlockSurface(sdl.blit.surface); - } + SDL_UnlockSurface(sdl.blit.surface); ret=IDirectDrawSurface3_Blt( sdl.surface->hwdata->dd_writebuf,&sdl.blit.rect, sdl.blit.surface->hwdata->dd_surface,0, diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index ec47222d..b6d0f661 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -64,7 +64,6 @@ void VGA_DetermineMode(void) { VGA_SetMode(M_LIN4); else VGA_SetMode(M_EGA); - } } else { VGA_SetMode(M_TEXT); diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index efbc61d6..0f8fcf52 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -242,6 +242,13 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { break; case 0x14: /* Underline Location Register */ crtc(underline_location)=val; + //Byte,word,dword mode + if ( crtc(underline_location) & 0x20 ) + vga.config.addr_shift = 2; + else if ( crtc( mode_control) & 0x40 ) + vga.config.addr_shift = 0; + else + vga.config.addr_shift = 1; /* 0-4 Position of underline within Character cell. 5 If set memory address is only changed every fourth character clock. @@ -268,7 +275,24 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { break; case 0x17: /* Mode Control Register */ crtc(mode_control)=val; + vga.tandy.line_mask = (~val) & 3; + //Byte,word,dword mode + if ( crtc(underline_location) & 0x20 ) + vga.config.addr_shift = 2; + else if ( crtc( mode_control) & 0x40 ) + vga.config.addr_shift = 0; + else + vga.config.addr_shift = 1; + + if ( vga.tandy.line_mask ) { + vga.tandy.line_shift = 13; + vga.tandy.addr_mask = (1 << 13) - 1; + } else { + vga.tandy.addr_mask = ~0; + vga.tandy.line_shift = 0; + } VGA_DetermineMode(); + //Should we really need to do a determinemode here? /* 0 If clear use CGA compatible memory addressing system by substituting character row scan counter bit 0 for address bit 13, diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index a67432f1..1de5a1b3 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -27,46 +27,41 @@ #define VGA_PARTS 4 -typedef Bit8u * (* VGA_Line_Handler)(Bitu vidstart,Bitu panning,Bitu line); -typedef void (* VGA_FrameStart_Handler)(); +typedef Bit8u * (* VGA_Line_Handler)(Bitu vidstart, Bitu line); static VGA_Line_Handler VGA_DrawLine; -static VGA_FrameStart_Handler VGA_FrameStart; static Bit8u TempLine[SCALER_MAXWIDTH * 4]; -static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { - line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; - for (Bitu x=vga.draw.blocks;x>0;x--) { - Bitu val=vga.gfxmem_start[vidstart+line]; - vidstart++; - if((vga.crtc.mode_control & 0x01) == 0) // CGA compatible addressing - vidstart &= 0x1dfff; +static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart, Bitu line) { + const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift); + Bit32u *draw = (Bit32u *)TempLine; + for (Bitu x=vga.draw.blocks;x>0;x--, vidstart++) { + Bitu val = base[(vidstart & (8 * 1024 -1))]; *draw++=CGA_2_Table[val >> 4]; *draw++=CGA_2_Table[val & 0xf]; } return TempLine; } -static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { - line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; +static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart, Bitu line) { + const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift); + Bit32u * draw=(Bit32u *)TempLine; for (Bitu x=0;x>4)|(val2&0xf0)]; *draw++=CGA_4_HiRes_Table[(val1&0x0f)|((val2&0x0f)<<4)]; } @@ -75,8 +70,9 @@ static Bit8u * VGA_Draw_2BPPHiRes_Line(Bitu vidstart,Bitu panning,Bitu line) { static Bitu temp[643]={0}; -static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart,Bitu panning,Bitu line) { - const Bit8u * reader=&vga.mem.linear[vidstart + (line * 8 * 1024)]; +static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart, Bitu line) { + const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift); + const Bit8u *reader = base + vidstart; Bit32u * draw=(Bit32u *)TempLine; //Generate a temporary bitline to calculate the avarage //over bit-2 bit-1 bit bit+1. @@ -114,17 +110,14 @@ static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart,Bitu panning,Bitu line) { return TempLine; } -static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { - line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; +static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart, Bitu line) { + const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift); + Bit32u * draw=(Bit32u *)TempLine; for (Bitu x=0;x> 4 | (val2 & 0x0f) << 24 | @@ -133,13 +126,12 @@ static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { return TempLine; } -static Bit8u * VGA_Draw_4BPP_Line_Double(Bitu vidstart,Bitu panning,Bitu line) { - line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; +static Bit8u * VGA_Draw_4BPP_Line_Double(Bitu vidstart, Bitu line) { + const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift); + Bit32u * draw=(Bit32u *)TempLine; for (Bitu x=0;x> 4 | (val & 0xf0) << 4 | (val & 0x0f) << 16 | @@ -148,43 +140,48 @@ static Bit8u * VGA_Draw_4BPP_Line_Double(Bitu vidstart,Bitu panning,Bitu line) { return TempLine; } -static Bit8u * VGA_Draw_LIN4_Line(Bitu vidstart,Bitu panning,Bitu line) { - return &vga.mem.linear[512*1024+vidstart*8+panning]; -} -static Bit8u * VGA_Draw_EGA_Line(Bitu vidstart,Bitu panning,Bitu line) { - return &vga.mem.linear[512*1024+vidstart*8+panning]; -} -static Bit8u * VGA_Draw_VGA_Line(Bitu vidstart,Bitu panning,Bitu line) { - return &vga.mem.linear[vidstart*4+panning]; -} -static Bit8u * VGA_Draw_LIN16_Line(Bitu vidstart,Bitu panning,Bitu line) { - return &vga.mem.linear[vidstart*4+panning]; -} -static Bit8u * VGA_Draw_LIN32_Line(Bitu vidstart,Bitu panning,Bitu line) { - return &vga.mem.linear[vidstart*4+panning]; +#ifdef VGA_KEEP_CHANGES +static Bit8u * VGA_Draw_Changes_Line(Bitu vidstart, Bitu line) { + Bitu checkMask = vga.changes.checkMask; + Bit8u *map = vga.changes.map; + Bitu start = (vidstart >> VGA_CHANGE_SHIFT); + Bitu end = ((vidstart + vga.changes.lineWidth ) >> VGA_CHANGE_SHIFT); + for (; start <= end;start++) { + if ( map[start] & checkMask ) { + return &vga.draw.linear_base[ vidstart & vga.draw.linear_mask ]; + } + } +// memset( TempLine, 0x30, vga.changes.lineWidth ); +// return TempLine; + return 0; } -static Bit8u * VGA_Draw_VGAChained_Line(Bitu vidstart,Bitu panning,Bitu line) { - return &vga.mem.linear[512*1024+((vidstart*4+panning)&0xffff)]; +#endif + +static Bit8u * VGA_Draw_Linear_Line(Bitu vidstart, Bitu line) { + return &vga.draw.linear_base[ vidstart & vga.draw.linear_mask ]; } -static void VGA_StartFrame_VGA() { - if(vga.config.compatible_chain4 && (vga.crtc.underline_location & 0x40)) - VGA_DrawLine=VGA_Draw_VGAChained_Line; - else - VGA_DrawLine = VGA_Draw_VGA_Line; +static Bit8u * VGA_Draw_Chain_Line(Bitu vidstart, Bitu line) { + Bitu i = 0; + for ( i = 0; i < vga.draw.width;i++ ) { + Bitu addr = vidstart + i; + TempLine[i] = vga.mem.linear[((addr&~3)<<2)+(addr&3)]; + } + return TempLine; } -static Bit8u * VGA_Draw_VGA_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) { + +static Bit8u * VGA_Draw_VGA_Line_HWMouse( Bitu vidstart, Bitu line) { if(vga.s3.hgc.curmode & 0x1) { - Bitu lineat = 4 * vidstart / vga.draw.width; + Bitu lineat = vidstart / vga.draw.width; if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) { - return VGA_Draw_VGA_Line(vidstart, panning, line); + return &vga.mem.linear[ vidstart ]; } else { - memcpy(TempLine, VGA_Draw_VGA_Line(vidstart, panning, line), vga.draw.width); + memcpy(TempLine, &vga.mem.linear[ vidstart ], vga.draw.width); /* Draw mouse cursor */ Bits moff = ((Bits)lineat - (Bits)vga.s3.hgc.originy) + (Bits)vga.s3.hgc.posy; - if(moff>63) return VGA_Draw_VGA_Line(vidstart, panning, line); + if(moff>63) return &vga.mem.linear[ vidstart ]; if(moff<0) moff+=64; Bitu xat = vga.s3.hgc.originx; Bitu m, mapat; @@ -231,20 +228,20 @@ static Bit8u * VGA_Draw_VGA_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) } } else { /* HW Mouse not enabled, use the tried and true call */ - return VGA_Draw_VGA_Line(vidstart, panning, line); + return &vga.mem.linear[ vidstart ]; } } -static Bit8u * VGA_Draw_LIN16_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) { +static Bit8u * VGA_Draw_LIN16_Line_HWMouse(Bitu vidstart, Bitu line) { if(vga.s3.hgc.curmode & 0x1) { - Bitu lineat = 2 * vidstart / vga.draw.width; + Bitu lineat = (vidstart >> 1) / vga.draw.width; if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) { - return VGA_Draw_LIN16_Line(vidstart, panning, line); + return &vga.mem.linear[ vidstart ]; } else { - memcpy(TempLine, VGA_Draw_LIN16_Line(vidstart, panning, line), 2*vga.draw.width); + memcpy(TempLine, &vga.mem.linear[ vidstart ], 2*vga.draw.width); /* Draw mouse cursor */ Bits moff = ((Bits)lineat - (Bits)vga.s3.hgc.originy) + (Bits)vga.s3.hgc.posy; - if(moff>63) return VGA_Draw_LIN16_Line(vidstart, panning, line); + if(moff>63) return &vga.mem.linear[ vidstart ]; if(moff<0) moff+=64; Bitu xat = 2*vga.s3.hgc.originx; Bitu m, mapat; @@ -294,20 +291,20 @@ static Bit8u * VGA_Draw_LIN16_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu lin } } else { /* HW Mouse not enabled, use the tried and true call */ - return VGA_Draw_LIN16_Line(vidstart, panning, line); + return &vga.mem.linear[ vidstart ]; } } -static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) { +static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart, Bitu line) { if(vga.s3.hgc.curmode & 0x1) { - Bitu lineat = vidstart / vga.draw.width; + Bitu lineat = (vidstart >> 2) / vga.draw.width; if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) { - return VGA_Draw_LIN32_Line(vidstart, panning, line); + return &vga.mem.linear[ vidstart ]; } else { - memcpy(TempLine, VGA_Draw_LIN32_Line(vidstart, panning, line), 4*vga.draw.width); + memcpy(TempLine, &vga.mem.linear[ vidstart ], 4*vga.draw.width); /* Draw mouse cursor */ Bits moff = ((Bits)lineat - (Bits)vga.s3.hgc.originy) + (Bits)vga.s3.hgc.posy; - if(moff>63) return VGA_Draw_LIN32_Line(vidstart, panning, line); + if(moff>63) return &vga.mem.linear[ vidstart ]; if(moff<0) moff+=64; Bitu xat = 4*vga.s3.hgc.originx; Bitu m, mapat; @@ -363,15 +360,15 @@ static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu lin } } else { /* HW Mouse not enabled, use the tried and true call */ - return VGA_Draw_LIN32_Line(vidstart, panning, line); + return &vga.mem.linear[ vidstart ]; } } static Bit32u FontMask[2]={0xffffffff,0x0}; -static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { +static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart, Bitu line) { Bitu font_addr; Bit32u * draw=(Bit32u *)TempLine; - Bit8u * vidmem=&vga.gfxmem_start[vidstart]; + const Bit8u *vidmem = &vga.tandy.draw_base[vidstart]; for (Bitu cx=0;cxvga.draw.cursor.eline) goto skip_cursor; draw=(Bit32u *)&TempLine[font_addr*8]; - Bit32u att=TXT_FG_Table[vga.gfxmem_start[vga.draw.cursor.address+1]&0xf]; + Bit32u att=TXT_FG_Table[vga.tandy.draw_base[vga.draw.cursor.address+1]&0xf]; *draw++=att;*draw++=att; } skip_cursor: @@ -397,7 +394,7 @@ skip_cursor: } static void VGA_VerticalDisplayEnd(Bitu val) { - vga.config.retrace=true; +// vga.config.retrace=true; vga.config.real_start=vga.config.display_start & ((2*1024*1024)-1); } @@ -405,28 +402,55 @@ static void VGA_HorizontalTimer(void) { } +#ifdef VGA_KEEP_CHANGES +static INLINE void VGA_ChangesEnd(void ) { + if ( vga.changes.active ) { +// vga.changes.active = false; + Bitu end = vga.draw.address >> VGA_CHANGE_SHIFT; + Bitu total = 4 + end - vga.changes.start; + Bit32u clearMask = vga.changes.clearMask; + total >>= 2; + Bit32u *clear = (Bit32u *)&vga.changes.map[ vga.changes.start & ~3 ]; + while ( total-- ) { + clear[0] &= clearMask; + clear++; + } + } +} +#endif + + static void VGA_DrawPart(Bitu lines) { while (lines--) { - vga.draw.lines_done++; - Bit8u * data=VGA_DrawLine(vga.draw.address,vga.draw.panning,vga.draw.address_line); + Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line ); RENDER_DrawLine(data); vga.draw.address_line++; if (vga.draw.address_line>=vga.draw.address_line_total) { vga.draw.address_line=0; vga.draw.address+=vga.draw.address_add; } + vga.draw.lines_done++; if (vga.draw.split_line==vga.draw.lines_done) { +#ifdef VGA_KEEP_CHANGES + VGA_ChangesEnd( ); +#endif vga.draw.address=0; - if(vga.attr.mode_control&0x20) - vga.draw.panning=0; + if(!(vga.attr.mode_control&0x20)) + vga.draw.address += vga.draw.panning; vga.draw.address_line=0; +#ifdef VGA_KEEP_CHANGES + vga.changes.start = vga.draw.address >> VGA_CHANGE_SHIFT; +#endif } } if (--vga.draw.parts_left) { - PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts, + PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts, (vga.draw.parts_left!=1) ? vga.draw.parts_lines : (vga.draw.lines_total - vga.draw.lines_done)); } else { - RENDER_EndUpdate( true ); +#ifdef VGA_KEEP_CHANGES + VGA_ChangesEnd(); +#endif + RENDER_EndUpdate(); } } @@ -445,26 +469,81 @@ void VGA_SetBlinking(Bitu enabled) { for (Bitu i=0;i<8;i++) TXT_BG_Table[i+8]=(b+i) | ((b+i) << 8)| ((b+i) <<16) | ((b+i) << 24); } -static void VGA_VerticalTimer(Bitu val) { - if (VGA_FrameStart) - VGA_FrameStart(); - vga.config.retrace=false; - PIC_AddEvent(VGA_VerticalTimer,vga.draw.delay.vtotal); - PIC_AddEvent(VGA_VerticalDisplayEnd,vga.draw.delay.vend); - bool bDoDraw = RENDER_StartUpdate(); - if (bDoDraw) { -// if (RENDER_StartUpdate()) { - vga.draw.parts_left=vga.draw.parts_total; - vga.draw.lines_done=0; - vga.draw.address=vga.config.real_start; - vga.draw.address_line=vga.config.hlines_skip; - vga.draw.split_line=(vga.config.line_compare/vga.draw.lines_scaled); - vga.draw.panning=vga.config.pel_panning; -// PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts,vga.draw.parts_lines); +#ifdef VGA_KEEP_CHANGES +static void INLINE VGA_ChangesStart( void ) { + vga.changes.start = vga.draw.address >> VGA_CHANGE_SHIFT; + vga.changes.last = vga.changes.start; + if ( vga.changes.lastAddress != vga.draw.address ) { +// LOG_MSG("Address"); + VGA_DrawLine = VGA_Draw_Linear_Line; + vga.changes.lastAddress = vga.draw.address; + } else if ( render.fullFrame ) { +// LOG_MSG("Full Frame"); + VGA_DrawLine = VGA_Draw_Linear_Line; + } else { +// LOG_MSG("Changes"); + VGA_DrawLine = VGA_Draw_Changes_Line; } + vga.changes.active = true; + vga.changes.checkMask = vga.changes.writeMask; + vga.changes.clearMask = ~( 0x01010101 << (vga.changes.frame & 7)); + vga.changes.frame++; + vga.changes.writeMask = 1 << (vga.changes.frame & 7); +} +#endif + + +static void VGA_VerticalTimer(Bitu val) { + double error = vga.draw.delay.framestart; + vga.draw.delay.framestart = PIC_FullIndex(); + error = vga.draw.delay.framestart - error - vga.draw.delay.vtotal; +// if (abs(error) > 0.001 ) +// LOG_MSG("vgaerror: %f",error); + PIC_AddEvent(VGA_VerticalTimer, (float)vga.draw.delay.vtotal ); + if ( GCC_UNLIKELY( vga.draw.parts_left )) { + LOG_MSG( "parts left: %d", vga.draw.parts_left ); + PIC_RemoveEvents( &VGA_DrawPart ); + } + //Check if we can actually render, else skip the rest + if (!RENDER_StartUpdate()) + return; + //TODO Maybe check for an active frame on parts_left and clear that first? + vga.draw.parts_left=vga.draw.parts_total; + vga.draw.lines_done=0; + vga.draw.address=vga.config.display_start; + vga.draw.address_line=vga.config.hlines_skip; + vga.draw.split_line=(vga.config.line_compare/vga.draw.lines_scaled); switch (vga.mode) { + case M_EGA: + vga.draw.address *= 8; + vga.draw.address += vga.config.pel_panning; +#ifdef VGA_KEEP_CHANGES + VGA_ChangesStart(); +#endif + break; + case M_VGA: + if(vga.config.compatible_chain4 && (vga.crtc.underline_location & 0x40)) { + vga.draw.linear_base = vga.mem.linear + VGA_CACHE_OFFSET; + vga.draw.linear_mask = 0xffff; + VGA_DrawLine = VGA_Draw_Chain_Line; + } else { + vga.draw.linear_base = vga.mem.linear; + vga.draw.linear_mask = VGA_MEMORY - 1; + VGA_DrawLine = VGA_Draw_Linear_Line; + } + case M_LIN8: + case M_LIN15: + case M_LIN16: + case M_LIN32: + vga.draw.address *= 4; + vga.draw.address += vga.config.pel_panning; +#ifdef VGA_KEEP_CHANGES + VGA_ChangesStart(); +#endif + break; case M_TEXT: - vga.draw.address=(vga.draw.address*2); + vga.draw.address *= 2; + vga.draw.panning = vga.config.pel_panning; case M_TANDY_TEXT: case M_HERC_TEXT: vga.draw.cursor.address=vga.config.cursor_start*2; @@ -473,30 +552,32 @@ static void VGA_VerticalTimer(Bitu val) { FontMask[1]=(vga.draw.blinking & (vga.draw.cursor.count >> 4)) ? 0 : 0xffffffff; break; - case M_CGA4:case M_CGA2:case M_CGA16: - case M_TANDY2:case M_TANDY4:case M_TANDY16: + case M_HERC_GFX: + break; + case M_CGA4:case M_CGA2: vga.draw.address=(vga.draw.address*2)&0x1fff; break; + case M_CGA16: + case M_TANDY2:case M_TANDY4:case M_TANDY16: + vga.draw.address *= 2; + break; } - if (IS_TANDY_ARCH) { - vga.draw.address+=vga.tandy.disp_bank << 14; - vga.draw.cursor.address+=vga.tandy.disp_bank << 14; - } - if (bDoDraw) -// VGA_DrawPart(vga.draw.parts_lines); - PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts/2,vga.draw.parts_lines); //Else tearline in Tyrian and second reality + VGA_DrawPart( vga.draw.parts_lines ); +// PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts/2,vga.draw.parts_lines); //Else tearline in Tyrian and second reality } void VGA_CheckScanLength(void) { switch (vga.mode) { case M_EGA: - case M_VGA: case M_LIN4: + vga.draw.address_add=vga.config.scan_len*16; + break; + case M_VGA: case M_LIN8: case M_LIN15: case M_LIN16: case M_LIN32: - vga.draw.address_add=vga.config.scan_len*2; + vga.draw.address_add=vga.config.scan_len*8; break; case M_TEXT: vga.draw.address_add=vga.config.scan_len*4; @@ -541,17 +622,7 @@ void VGA_ActivateHardwareCursor(void) { VGA_DrawLine=VGA_Draw_VGA_Line_HWMouse; } } else { - switch(vga.mode) { - case M_LIN32: - VGA_DrawLine=VGA_Draw_LIN32_Line; - break; - case M_LIN15: - case M_LIN16: - VGA_DrawLine=VGA_Draw_LIN16_Line; - break; - default: - VGA_DrawLine=VGA_Draw_VGA_Line; - } + VGA_DrawLine=VGA_Draw_Linear_Line; } } @@ -563,24 +634,49 @@ void VGA_SetupDrawing(Bitu val) { } /* Calculate the FPS for this screen */ float fps;Bitu clock; - Bitu htotal,hdispend,hbstart,hrstart; - Bitu vtotal,vdispend,vbstart,vrstart; + Bitu htotal, hdend, hbstart, hbend, hrstart, hrend; + Bitu vtotal, vdend, vbstart, vbend, vrstart, vrend; if (machine==MCH_VGA) { + htotal = 5 + vga.crtc.horizontal_total; + hdend = 1 + vga.crtc.horizontal_display_end; + hbstart = vga.crtc.start_horizontal_blanking; + hbend = vga.crtc.end_horizontal_blanking&0x1F | + ((vga.crtc.end_horizontal_retrace&0x80)>>2); + hbend = hbstart + ((hbend - hbstart) & 0x3F); + hrstart = vga.crtc.start_horizontal_retrace; + hrend = vga.crtc.end_horizontal_retrace & 0x1f; + hrend = (hrend - hrstart) & 0x1f; + if ( !hrend ) + hrend = hrstart + 0x1f + 1; + else + hrend = hrstart + hrend; + vtotal=2 + vga.crtc.vertical_total | ((vga.crtc.overflow & 1) << 8) | ((vga.crtc.overflow & 0x20) << 4); - htotal=5 + vga.crtc.horizontal_total; - vdispend = 1 + (vga.crtc.vertical_display_end | - ((vga.crtc.overflow & 2)<<7) | ((vga.crtc.overflow & 0x40) << 3) | + vdend = 1 + (vga.crtc.vertical_display_end | + ((vga.crtc.overflow & 2)<<7) | + ((vga.crtc.overflow & 0x40) << 3) | ((vga.s3.ex_ver_overflow & 0x2) << 9)); - hdispend = 1 + (vga.crtc.horizontal_display_end); - hbstart = vga.crtc.start_horizontal_blanking; - vbstart = vga.crtc.start_vertical_blanking | ((vga.crtc.overflow & 0x08) << 5) | - ((vga.crtc.maximum_scan_line & 0x20) << 4) ; - hrstart = vga.crtc.start_horizontal_retrace; - vrstart = vga.crtc.vertical_retrace_start + ((vga.crtc.overflow & 0x04) << 6) | + vrstart = vga.crtc.vertical_retrace_start + + ((vga.crtc.overflow & 0x04) << 6) | ((vga.crtc.overflow & 0x80) << 2); - if (hbstart0; } else { - vga.draw.address_line_total=vga.other.max_scanline+1; - htotal=vga.other.htotal+1; - hdispend=vga.other.hdend; - hrstart=vga.other.hsyncp; - vtotal=vga.draw.address_line_total*(vga.other.vtotal+1)+vga.other.vadjust; - vdispend=vga.draw.address_line_total*vga.other.vdend; - vrstart=vga.draw.address_line_total*vga.other.vsyncp; + htotal = vga.other.htotal + 1; + hdend = vga.other.hdend; + hbstart = hdend; + hbend = htotal; + hrstart = vga.other.hsyncp; + hrend = hrstart + (vga.other.syncw & 0xf) ; + + vga.draw.address_line_total = vga.other.max_scanline + 1; + vtotal = vga.draw.address_line_total * (vga.other.vtotal+1)+vga.other.vadjust; + vdend = vga.draw.address_line_total * vga.other.vdend; + vrstart = vga.draw.address_line_total * vga.other.vsyncp; + vrend = (vga.other.syncw >> 4); + if (!vrend) + vrend = vrstart + 0xf + 1; + else + vrend = vrstart + vrend; + vbstart = vdend; + vbend = vtotal; vga.draw.double_scan=false; switch (machine) { case MCH_CGA: @@ -627,69 +734,92 @@ void VGA_SetupDrawing(Bitu val) { break; } } - LOG(LOG_VGA,LOG_NORMAL)("H total %d, V Total %d",htotal,vtotal); - LOG(LOG_VGA,LOG_NORMAL)("H D End %d, V D End %d",hdispend,vdispend); + LOG(LOG_VGA,LOG_NORMAL)("h total %d end %d blank (%d/%d) retrace (%d/%d)", + htotal, hdend, hbstart, hbend, hrstart, hrend ); + LOG(LOG_VGA,LOG_NORMAL)("v total %d end %d blank (%d/%d) retrace (%d/%d)", + vtotal, vdend, vbstart, vbend, vrstart, vrend ); + if (!htotal) return; if (!vtotal) return; + fps=(float)clock/(vtotal*htotal); - float linetime=1000.0f/fps; - vga.draw.parts_total=VGA_PARTS; - vga.draw.delay.vtotal=linetime; - linetime/=vtotal; //Really make it the line_delay - vga.draw.delay.vend=linetime*vrstart; - vga.draw.delay.parts=(linetime*vdispend)/vga.draw.parts_total; - vga.draw.delay.htotal=linetime; - vga.draw.delay.hend=(linetime/htotal)*hrstart; + // The time a complete video frame takes + vga.draw.delay.vtotal = (1000.0 * (double)(vtotal*htotal)) / (double)clock; + // Horizontal total (that's how long a line takes with whistles and bells) + vga.draw.delay.htotal = htotal*1000.0/clock; //in milliseconds + // Start and End of horizontal blanking + vga.draw.delay.hblkstart = hbstart*1000.0/clock; //in milliseconds + vga.draw.delay.hblkend = hbend*1000.0/clock; + vga.draw.delay.hrstart = 0; + + // Start and End of vertical blanking + vga.draw.delay.vblkstart = vbstart * vga.draw.delay.htotal; + vga.draw.delay.vblkend = vbend * vga.draw.delay.htotal; + // Start and End of vertical retrace pulse + vga.draw.delay.vrstart = vrstart * vga.draw.delay.htotal; + vga.draw.delay.vrend = vrend * vga.draw.delay.htotal; + // Display end + vga.draw.delay.vdend = vdend * vga.draw.delay.htotal; + /* + // just curious + LOG_MSG("H total %d, V Total %d",htotal,vtotal); + LOG_MSG("H D End %d, V D End %d",hdispend,vdispend); + LOG_MSG("vrstart: %d, vrend: %d\n",vrstart,vrend); + LOG_MSG("htotal: %2.6f, vtotal: %2.6f,\n"\ + "hblkstart: %2.6f, hblkend: %2.6f,\n"\ + "vblkstart: %2.6f, vblkend: %2.6f,\n"\ + "vrstart: %2.6f, vrend: %2.6f,\n"\ + "vdispend: %2.6f", + vga.draw.delay.htotal, vga.draw.delay.vtotal, + vga.draw.delay.hblkstart, vga.draw.delay.hblkend, + vga.draw.delay.vblkstart, vga.draw.delay.vblkend, + vga.draw.delay.vrstart, vga.draw.delay.vrend, + vga.draw.delay.vend); + */ + vga.draw.parts_total=VGA_PARTS; double correct_ratio=(100.0/525.0); double aspect_ratio=((double)htotal/((double)vtotal)/correct_ratio); vga.draw.resizing=false; - Bitu width=hdispend; - Bitu height=vdispend; - Bitu bpp=8; + + //Check to prevent useless black areas + if (hbstart>= 1; - } - /* Use HW mouse cursor drawer if enabled */ - VGA_ActivateHardwareCursor(); - break; case M_LIN15: - bpp = 15; - width<<=3; - if (vga.crtc.mode_control & 0x8) { - doublewidth = true; - width >>= 1; - } - /* Use HW mouse cursor drawer if enabled */ - VGA_ActivateHardwareCursor(); - break; case M_LIN16: - bpp = 16; - width<<=3; - if (vga.crtc.mode_control & 0x8) { - doublewidth = true; - width >>= 1; - } - /* Use HW mouse cursor drawer if enabled */ - VGA_ActivateHardwareCursor(); - break; case M_LIN32: - bpp = 32; width<<=3; if (vga.crtc.mode_control & 0x8) { doublewidth = true; @@ -702,13 +832,17 @@ void VGA_SetupDrawing(Bitu val) { doublewidth=(vga.seq.clocking_mode & 0x8) > 0; vga.draw.blocks = width; width<<=3; - VGA_DrawLine=VGA_Draw_LIN4_Line; + VGA_DrawLine=VGA_Draw_Linear_Line; + vga.draw.linear_base = vga.mem.linear + VGA_CACHE_OFFSET; + vga.draw.linear_mask = 1024 * 1024 - 1; break; case M_EGA: doublewidth=(vga.seq.clocking_mode & 0x8) > 0; vga.draw.blocks = width; width<<=3; - VGA_DrawLine=VGA_Draw_EGA_Line; + VGA_DrawLine=VGA_Draw_Linear_Line; + vga.draw.linear_base = vga.mem.linear + VGA_CACHE_OFFSET; + vga.draw.linear_mask = 512 * 1024 - 1; break; case M_CGA16: doubleheight=true; @@ -758,18 +892,26 @@ void VGA_SetupDrawing(Bitu val) { vga.draw.blocks=width * 2; width=vga.draw.blocks*4; if ((machine==MCH_TANDY && (vga.tandy.gfx_control & 0x8)) || - (machine==MCH_PCJR && (vga.tandy.mode_control==0x0b))) VGA_DrawLine=VGA_Draw_2BPPHiRes_Line; + (machine==MCH_PCJR && (vga.tandy.mode_control==0x0b))) + VGA_DrawLine=VGA_Draw_2BPPHiRes_Line; else VGA_DrawLine=VGA_Draw_2BPP_Line; break; case M_TANDY16: aspect_ratio=1.2; doubleheight=true; - doublewidth=true; vga.draw.blocks=width*2; if (vga.tandy.mode_control & 0x1) { - width=vga.draw.blocks*2; + if ( vga.tandy.mode_control & 0x10 ) { + doublewidth = false; + vga.draw.blocks*=2; + width=vga.draw.blocks*2; + } else { + doublewidth = true; + width=vga.draw.blocks*2; + } VGA_DrawLine=VGA_Draw_4BPP_Line; } else { + doublewidth=true; width=vga.draw.blocks*4; VGA_DrawLine=VGA_Draw_4BPP_Line_Double; } @@ -799,6 +941,13 @@ void VGA_SetupDrawing(Bitu val) { } vga.draw.lines_total=height; vga.draw.parts_lines=vga.draw.lines_total/vga.draw.parts_total; + +#ifdef VGA_KEEP_CHANGES + vga.changes.active = false; + vga.changes.lineWidth = width * ((bpp + 1) / 8); + vga.changes.frame = 0; + vga.changes.writeMask = 1; +#endif if (( width != vga.draw.width) || (height != vga.draw.height) || (vga.mode != vga.lastmode)) { vga.lastmode = vga.mode; PIC_RemoveEvents(VGA_VerticalTimer); @@ -816,7 +965,8 @@ void VGA_SetupDrawing(Bitu val) { doublewidth ? "double":"normal",doubleheight ? "double":"normal",aspect_ratio); #endif RENDER_SetSize(width,height,bpp,fps,aspect_ratio,doublewidth,doubleheight); - PIC_AddEvent(VGA_VerticalTimer,vga.draw.delay.vtotal); + vga.draw.delay.framestart = PIC_FullIndex(); + PIC_AddEvent( VGA_VerticalTimer , vga.draw.delay.vtotal ); } }; diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index fc078f70..2588264e 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -25,6 +25,37 @@ #include "pic.h" #include "inout.h" +#ifdef VGA_KEEP_CHANGES +#define MEM_CHANGED( _MEM ) vga.changes.map[ (_MEM) >> VGA_CHANGE_SHIFT ] |= vga.changes.writeMask; +//#define MEM_CHANGED( _MEM ) vga.changes.map[ (_MEM) >> VGA_CHANGE_SHIFT ] = 1; +#else +#define MEM_CHANGED( _MEM ) +#endif + +#define TANDY_VIDBASE(_X_) &MemBase[ 0x80000 + (_X_)] + +template +static INLINE void hostWrite(HostPt off, Bitu val) { + if ( sizeof( Size ) == 1) + host_writeb( off, (Bit8u)val ); + else if ( sizeof( Size ) == 2) + host_writew( off, (Bit16u)val ); + else if ( sizeof( Size ) == 4) + host_writed( off, (Bit32u)val ); +} + +template +static INLINE Bitu hostRead(HostPt off ) { + if ( sizeof( Size ) == 1) + return host_readb( off ); + else if ( sizeof( Size ) == 2) + return host_readw( off ); + else if ( sizeof( Size ) == 4) + return host_readd( off ); + return 0; +} + + void VGA_MapMMIO(void); //Nice one from DosEmu INLINE static Bit32u RasterOp(Bit32u input,Bit32u mask) { @@ -83,8 +114,7 @@ static struct { class VGA_UnchainedRead_Handler : public PageHandler { public: Bitu readHandler(PhysPt start) { - start += vga.s3.svga_bank.fullbank; - vga.latch.d=vga.mem.latched[start].d; + vga.latch.d=((Bit32u*)vga.mem.linear)[start]; switch (vga.config.read_mode) { case 0: return (vga.latch.b[vga.config.read_map_select]); @@ -116,45 +146,20 @@ public: } }; -class VGA_Chained_ReadHandler : public PageHandler { +class VGA_ChainedEGA_Handler : public PageHandler { public: Bitu readHandler(PhysPt addr) { - if(vga.mode == M_VGA) - return vga.mem.linear[((addr&~3)<<2)|(addr&3)]; return vga.mem.linear[addr]; } -public: - Bitu readb(PhysPt addr) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - return readHandler(addr); - } - Bitu readw(PhysPt addr) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - return - (readHandler(addr+0) << 0) | - (readHandler(addr+1) << 8); - } - Bitu readd(PhysPt addr) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - return - (readHandler(addr+0) << 0) | - (readHandler(addr+1) << 8) | - (readHandler(addr+2) << 16) | - (readHandler(addr+3) << 24); - } -}; - -class VGA_ChainedEGA_Handler : public VGA_Chained_ReadHandler { -public: void writeHandler(PhysPt start, Bit8u val) { Bit32u data=ModeOperation(val); /* Update video memory and the pixel buffer */ VGA_Latch pixels; vga.mem.linear[start] = val; start >>= 2; - pixels.d=vga.mem.latched[start].d; + pixels.d=((Bit32u*)vga.mem.linear)[start]; - Bit8u * write_pixels=&vga.mem.linear[512*1024+(start<<3)]; + Bit8u * write_pixels=&vga.mem.linear[VGA_CACHE_OFFSET+(start<<3)]; Bit32u colors0_3, colors4_7; VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f; @@ -178,33 +183,55 @@ public: } void writeb(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + MEM_CHANGED( addr << 3); writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + MEM_CHANGED( addr << 3); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + MEM_CHANGED( addr << 3); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); writeHandler(addr+2,(Bit8u)(val >> 16)); writeHandler(addr+3,(Bit8u)(val >> 24)); } + Bitu readb(PhysPt addr) { + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + return readHandler(addr); + } + Bitu readw(PhysPt addr) { + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + return + (readHandler(addr+0) << 0) | + (readHandler(addr+1) << 8); + } + Bitu readd(PhysPt addr) { + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + return + (readHandler(addr+0) << 0) | + (readHandler(addr+1) << 8) | + (readHandler(addr+2) << 16) | + (readHandler(addr+3) << 24); + } }; class VGA_UnchainedEGA_Handler : public VGA_UnchainedRead_Handler { public: + template< bool wrapping> void writeHandler(PhysPt start, Bit8u val) { Bit32u data=ModeOperation(val); /* Update video memory and the pixel buffer */ VGA_Latch pixels; - pixels.d=vga.mem.latched[start].d; + pixels.d=((Bit32u*)vga.mem.linear)[start]; pixels.d&=vga.config.full_not_map_mask; pixels.d|=(data & vga.config.full_map_mask); - vga.mem.latched[start].d=pixels.d; - Bit8u * write_pixels=&vga.mem.linear[512*1024+(start<<3)]; + ((Bit32u*)vga.mem.linear)[start]=pixels.d; + Bit8u * write_pixels=&vga.mem.linear[VGA_CACHE_OFFSET+(start<<3)]; Bit32u colors0_3, colors4_7; VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f; @@ -214,7 +241,6 @@ public: Expand16Table[2][temp.b[2]] | Expand16Table[3][temp.b[3]]; *(Bit32u *)write_pixels=colors0_3; - *(Bit32u *)(write_pixels+512*1024)=colors0_3; temp.d=pixels.d & 0x0f0f0f0f; colors4_7 = Expand16Table[0][temp.b[0]] | @@ -222,7 +248,10 @@ public: Expand16Table[2][temp.b[2]] | Expand16Table[3][temp.b[3]]; *(Bit32u *)(write_pixels+4)=colors4_7; - *(Bit32u *)(write_pixels+512*1024+4)=colors4_7; + if (wrapping && GCC_UNLIKELY( start < 512)) { + *(Bit32u *)(write_pixels+512*1024)=colors0_3; + *(Bit32u *)(write_pixels+512*1024+4)=colors4_7; + } } public: VGA_UnchainedEGA_Handler() { @@ -230,68 +259,147 @@ public: } void writeb(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - writeHandler(addr+0,(Bit8u)(val >> 0)); + MEM_CHANGED( addr << 3); + writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - writeHandler(addr+0,(Bit8u)(val >> 0)); - writeHandler(addr+1,(Bit8u)(val >> 8)); + MEM_CHANGED( addr << 3); + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - writeHandler(addr+0,(Bit8u)(val >> 0)); - writeHandler(addr+1,(Bit8u)(val >> 8)); - writeHandler(addr+2,(Bit8u)(val >> 16)); - writeHandler(addr+3,(Bit8u)(val >> 24)); + MEM_CHANGED( addr << 3); + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); + writeHandler(addr+2,(Bit8u)(val >> 16)); + writeHandler(addr+3,(Bit8u)(val >> 24)); } }; - -class VGA_ChainedVGA_Handler : public VGA_Chained_ReadHandler { +//Slighly unusual version, will directly write 8,16,32 bits values +class VGA_ChainedVGA_Handler : public PageHandler { public: - void writeHandler(PhysPt addr, Bitu val) { - // No need to check for compatible chains here, this one is only enabled if that bit is set - vga.mem.linear[((addr&~3)<<2)|(addr&3)] = val; - // Linearized version for faster rendering - vga.mem.linear[512*1024+addr] = val; - if (addr >= 320) return; - // And replicate the first line - vga.mem.linear[512*1024+addr+64*1024] = val; - } -public: VGA_ChainedVGA_Handler() { flags=PFLAG_NOCODE; } - void writeb(PhysPt addr,Bitu val) { + template + static INLINE Bitu readHandler(PhysPt addr ) { + return hostRead( &vga.mem.linear[((addr&~3)<<2)+(addr&3)] ); + } + template + static INLINE void writeCache(PhysPt addr, Bitu val) { + hostWrite( &vga.mem.linear[VGA_CACHE_OFFSET+addr], val ); + if (GCC_UNLIKELY(addr < 320)) { + // And replicate the first line + hostWrite( &vga.mem.linear[VGA_CACHE_OFFSET+addr+64*1024], val ); + } + } + template + static INLINE void writeHandler(PhysPt addr, Bitu val) { + // No need to check for compatible chains here, this one is only enabled if that bit is set + hostWrite( &vga.mem.linear[((addr&~3)<<2)+(addr&3)], val ); + } + Bitu readb(PhysPt addr ) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - writeHandler(addr+0,(Bit8u)(val >> 0)); + return readHandler( addr ); + } + Bitu readw(PhysPt addr ) { + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + return readHandler( addr ); + } + Bitu readd(PhysPt addr ) { + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + return readHandler( addr ); + } + bool readw_checked( PhysPt addr,Bitu *val ) { + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + if ( addr & 1) { + *val = + (readHandler( addr+0 ) << 0 ) | + (readHandler( addr+1 ) << 8 ); + } else { + *val = readHandler( addr ); + } + return false; + } + bool readd_checked( PhysPt addr,Bitu *val ) { + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + if ( addr & 3) { + *val = + (readHandler( addr+0 ) << 0 ) | + (readHandler( addr+1 ) << 8 ) | + (readHandler( addr+2 ) << 16 ) | + (readHandler( addr+3 ) << 24 ); + } else { + *val = readHandler( addr ); + } + return false; + } + void writeb(PhysPt addr, Bitu val ) { + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + MEM_CHANGED( addr ); + writeHandler( addr, val ); + writeCache( addr, val ); } void writew(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - writeHandler(addr+0,(Bit8u)(val >> 0)); - writeHandler(addr+1,(Bit8u)(val >> 8)); + MEM_CHANGED( addr ); + writeHandler( addr, val ); + writeCache( addr, val ); } void writed(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - writeHandler(addr+0,(Bit8u)(val >> 0)); - writeHandler(addr+1,(Bit8u)(val >> 8)); - writeHandler(addr+2,(Bit8u)(val >> 16)); - writeHandler(addr+3,(Bit8u)(val >> 24)); + MEM_CHANGED( addr ); + writeHandler( addr, val ); + writeCache( addr, val ); + } + bool writew_checked( PhysPt addr,Bitu val ) { + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + if ( addr & 1 ) { + MEM_CHANGED( addr ); + MEM_CHANGED( addr + 1); + writeHandler( addr+0, val >> 0 ); + writeHandler( addr+1, val >> 8 ); + writeCache( addr, val ); + } else { + MEM_CHANGED( addr ); + writeHandler( addr, val ); + writeCache( addr, val ); + } + return false; + } + bool writed_checked( PhysPt addr,Bitu val ) { + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + if ( addr & 3) { + MEM_CHANGED( addr ); + MEM_CHANGED( addr + 3); + writeHandler( addr+0, val >> 0 ); + writeHandler( addr+1, val >> 8 ); + writeHandler( addr+2, val >> 16 ); + writeHandler( addr+3, val >> 24 ); + writeCache( addr, val ); + } else { + MEM_CHANGED( addr ); + writeHandler( addr, val ); + writeCache( addr, val ); + } + return false; } }; class VGA_UnchainedVGA_Handler : public VGA_UnchainedRead_Handler { public: void writeHandler( PhysPt addr, Bit8u val ) { - addr += vga.s3.svga_bank.fullbank; Bit32u data=ModeOperation(val); VGA_Latch pixels; - pixels.d=vga.mem.latched[addr].d; + pixels.d=((Bit32u*)vga.mem.linear)[addr]; pixels.d&=vga.config.full_not_map_mask; pixels.d|=(data & vga.config.full_map_mask); - vga.mem.latched[addr].d=pixels.d; + ((Bit32u*)vga.mem.linear)[addr]=pixels.d; if(vga.config.compatible_chain4) - vga.mem.latched[addr+64*1024].d=pixels.d; + ((Bit32u*)vga.mem.linear)[addr+64*1024]=pixels.d; } public: VGA_UnchainedVGA_Handler() { @@ -299,15 +407,21 @@ public: } void writeb(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.s3.svga_bank.fullbank; + MEM_CHANGED( addr << 2 ); writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.s3.svga_bank.fullbank; + MEM_CHANGED( addr << 2); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.s3.svga_bank.fullbank; + MEM_CHANGED( addr << 2); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); writeHandler(addr+2,(Bit8u)(val >> 16)); @@ -332,9 +446,9 @@ public: } }; -class VGA_MAP_PageHandler : public PageHandler { +class VGA_Map_Handler : public PageHandler { public: - VGA_MAP_PageHandler() { + VGA_Map_Handler() { flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; } HostPt GetHostReadPt(Bitu phys_page) { @@ -347,87 +461,88 @@ public: } }; - -class VGA_LIN4Linear_Handler : public VGA_UnchainedEGA_Handler { +class VGA_Changes_Handler : public PageHandler { public: - VGA_LIN4Linear_Handler() { - flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; - } - void writeb(PhysPt addr,Bitu val) { - addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1); - writeHandler(addr+0,(Bit8u)(val >> 0)); - } - void writew(PhysPt addr,Bitu val) { - addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1); - writeHandler(addr+0,(Bit8u)(val >> 0)); - writeHandler(addr+1,(Bit8u)(val >> 8)); - } - void writed(PhysPt addr,Bitu val) { - addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1); - writeHandler(addr+0,(Bit8u)(val >> 0)); - writeHandler(addr+1,(Bit8u)(val >> 8)); - writeHandler(addr+2,(Bit8u)(val >> 16)); - writeHandler(addr+3,(Bit8u)(val >> 24)); + VGA_Changes_Handler() { + flags=PFLAG_NOCODE; } Bitu readb(PhysPt addr) { - addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1); - return readHandler(addr); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.s3.svga_bank.fullbank; + return hostRead( &vga.mem.linear[addr] ); } Bitu readw(PhysPt addr) { - addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1); - return - (readHandler(addr+0) << 0) | - (readHandler(addr+1) << 8); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.s3.svga_bank.fullbank; + return hostRead( &vga.mem.linear[addr] ); } Bitu readd(PhysPt addr) { - addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1); - return - (readHandler(addr+0) << 0) | - (readHandler(addr+1) << 8) | - (readHandler(addr+2) << 16) | - (readHandler(addr+3) << 24); + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.s3.svga_bank.fullbank; + return hostRead( &vga.mem.linear[addr] ); + } + void writeb(PhysPt addr,Bitu val) { + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.s3.svga_bank.fullbank; + MEM_CHANGED( addr ); + hostWrite( &vga.mem.linear[addr], val ); + } + void writew(PhysPt addr,Bitu val) { + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.s3.svga_bank.fullbank; + MEM_CHANGED( addr ); + hostWrite( &vga.mem.linear[addr], val ); + } + void writed(PhysPt addr,Bitu val) { + addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.s3.svga_bank.fullbank; + MEM_CHANGED( addr ); + hostWrite( &vga.mem.linear[addr], val ); } }; -class VGA_LIN4Banked_Handler : public VGA_UnchainedEGA_Handler { +class VGA_LIN4_Handler : public VGA_UnchainedEGA_Handler { public: - VGA_LIN4Banked_Handler() { + VGA_LIN4_Handler() { flags=PFLAG_NOCODE; } void writeb(PhysPt addr,Bitu val) { addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff); - addr &= (512*1024-1); - writeHandler(addr+0,(Bit8u)(val >> 0)); + addr &= (128*1024-1); + MEM_CHANGED( addr << 3 ); + writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff); - addr &= (512*1024-1); - writeHandler(addr+0,(Bit8u)(val >> 0)); - writeHandler(addr+1,(Bit8u)(val >> 8)); + addr &= (128*1024-1); + MEM_CHANGED( addr << 3 ); + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff); - addr &= (512*1024-1); - writeHandler(addr+0,(Bit8u)(val >> 0)); - writeHandler(addr+1,(Bit8u)(val >> 8)); - writeHandler(addr+2,(Bit8u)(val >> 16)); - writeHandler(addr+3,(Bit8u)(val >> 24)); + addr &= (128*1024-1); + MEM_CHANGED( addr << 3 ); + writeHandler(addr+0,(Bit8u)(val >> 0)); + writeHandler(addr+1,(Bit8u)(val >> 8)); + writeHandler(addr+2,(Bit8u)(val >> 16)); + writeHandler(addr+3,(Bit8u)(val >> 24)); } Bitu readb(PhysPt addr) { addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff); - addr &= (512*1024-1); + addr &= (128*1024-1); return readHandler(addr); } Bitu readw(PhysPt addr) { addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff); - addr &= (512*1024-1); + addr &= (128*1024-1); return (readHandler(addr+0) << 0) | (readHandler(addr+1) << 8); } Bitu readd(PhysPt addr) { addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff); - addr &= (512*1024-1); + addr &= (128*1024-1); return (readHandler(addr+0) << 0) | (readHandler(addr+1) << 8) | @@ -444,31 +559,38 @@ public: } Bitu readb(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; - return *(Bit8u*)(&vga.mem.linear[addr]); + return hostRead( &vga.mem.linear[addr] ); } Bitu readw(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; - return *(Bit16u*)(&vga.mem.linear[addr]); + return hostRead( &vga.mem.linear[addr] ); } Bitu readd(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; - return *(Bit32u*)(&vga.mem.linear[addr]); + return hostRead( &vga.mem.linear[addr] ); } void writeb(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; - *(Bit8u*)(&vga.mem.linear[addr]) = val; - vga.changed[addr >> VGA_CHANGE_SHIFT] = 1; + hostWrite( &vga.mem.linear[addr], val ); + MEM_CHANGED( addr ); } void writew(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; - *(Bit16u*)(&vga.mem.linear[addr]) = val; - vga.changed[addr >> VGA_CHANGE_SHIFT] = 1; + hostWrite( &vga.mem.linear[addr], val ); + MEM_CHANGED( addr ); } void writed(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; - *(Bit32u*)(&vga.mem.linear[addr]) = val; - vga.changed[addr >> VGA_CHANGE_SHIFT] = 1; + hostWrite( &vga.mem.linear[addr], val ); + MEM_CHANGED( addr ); } + bool writed_checked( PhysPt addr,Bitu val ) { + addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + hostWrite( &vga.mem.linear[addr], val ); + MEM_CHANGED( addr ); + return false; + } + }; class VGA_LFB_Handler : public PageHandler { @@ -569,156 +691,207 @@ public: // |PFLAG_NOCODE; } HostPt GetHostReadPt(Bitu phys_page) { - if (phys_page>=0xb8) { - phys_page-=0xb8; - return &vga.mem.linear[(vga.tandy.mem_bank << 14)+(phys_page * 4096)]; - } else { - if (machine==MCH_TANDY) phys_page-=0x80; - return &vga.mem.linear[phys_page * 4096]; - } + if (vga.tandy.mem_bank & 1) + phys_page&=0x03; + else + phys_page&=0x07; + return vga.tandy.mem_base + (phys_page * 4096); } HostPt GetHostWritePt(Bitu phys_page) { return GetHostReadPt( phys_page ); } }; -class VGA_PCJR_PageHandler : public PageHandler { + +class VGA_PCJR_Handler : public PageHandler { public: - VGA_PCJR_PageHandler() { + VGA_PCJR_Handler() { flags=PFLAG_READABLE|PFLAG_WRITEABLE; } HostPt GetHostReadPt(Bitu phys_page) { phys_page-=0xb8; - if (!vga.tandy.is_32k_mode) phys_page&=0x03; - return MemBase+(vga.tandy.mem_bank << 14)+(phys_page * 4096); + //test for a unaliged bank, then replicate 2x16kb + if (vga.tandy.mem_bank & 1) + phys_page&=0x03; + return vga.tandy.mem_base + (phys_page * 4096); } HostPt GetHostWritePt(Bitu phys_page) { return GetHostReadPt( phys_page ); } }; +class VGA_Empty_Handler : public PageHandler { +public: + VGA_Empty_Handler() { + flags=PFLAG_NOCODE; + } + Bitu readb(PhysPt addr) { +// LOG(LOG_VGA, LOG_NORMAL ) ( "Read from empty memory space at %x", addr ); + return 0xff; + } + void writeb(PhysPt addr,Bitu val) { +// LOG(LOG_VGA, LOG_NORMAL ) ( "Write %x to empty memory space at %x", val, addr ); + } +}; static struct vg { - VGA_MAP_PageHandler map; + VGA_Map_Handler map; + VGA_Changes_Handler changes; VGA_TEXT_PageHandler text; VGA_TANDY_PageHandler tandy; VGA_ChainedEGA_Handler cega; VGA_ChainedVGA_Handler cvga; VGA_UnchainedEGA_Handler uega; VGA_UnchainedVGA_Handler uvga; - VGA_PCJR_PageHandler hpcjr; - VGA_LIN4Banked_Handler l4banked; - VGA_LIN4Linear_Handler l4linear; + VGA_PCJR_Handler pcjr; + VGA_LIN4_Handler lin4; VGA_LFB_Handler lfb; VGA_LFBChanges_Handler lfbchanges; VGA_MMIO_Handler mmio; + VGA_Empty_Handler empty; } vgaph; +void VGA_ChangedBank(void) { +#ifndef VGA_LFB_MAPPED + //If the mode is accurate than the correct mapper must have been installed already + if ( vga.mode >= M_LIN4 && vga.mode <= M_LIN32 ) { + return; + } +#endif + VGA_SetupHandlers(); +} void VGA_SetupHandlers(void) { - PageHandler * range_handler; + PageHandler *newHandler; switch (machine) { case MCH_CGA: - range_handler=&vgaph.map; - goto range_b800; - case MCH_HERC: - range_handler=&vgaph.map; - if (vga.herc.mode_control&0x80) goto range_b800; - else goto range_b000; - case MCH_TANDY: - range_handler=&vgaph.tandy; - MEM_SetPageHandler(0x80,32,range_handler); - goto range_b800; case MCH_PCJR: - range_handler=&vgaph.hpcjr; + MEM_SetPageHandler( VGA_PAGE_B8, 8, &vgaph.pcjr ); + goto range_done; + case MCH_HERC: + vgapages.base=VGA_PAGE_B0; + if (vga.herc.enable_bits & 0x2) { + vgapages.mask=0xffff; + MEM_SetPageHandler(VGA_PAGE_B0,16,&vgaph.map); + } else { + vgapages.mask=0x7fff; + /* With hercules in 32kb mode it leaves a memory hole on 0xb800 */ + MEM_SetPageHandler(VGA_PAGE_B0,8,&vgaph.map); + MEM_SetPageHandler(VGA_PAGE_B8,8,&vgaph.empty); + } + goto range_done; + case MCH_TANDY: + /* Always map 0xa000 - 0xbfff, might overwrite 0xb800 */ + vgapages.base=VGA_PAGE_A0; + vgapages.mask=0x1ffff; + MEM_SetPageHandler(VGA_PAGE_A0, 32, &vgaph.map ); + if ( vga.tandy.extended_ram & 1 ) { + //You seem to be able to also map different 64kb banks, but have to figure that out + //This seems to work so far though + vga.tandy.draw_base = vga.mem.linear; + vga.tandy.mem_base = vga.mem.linear; + } else { + vga.tandy.draw_base = TANDY_VIDBASE( vga.tandy.draw_bank * 16 * 1024); + vga.tandy.mem_base = TANDY_VIDBASE( vga.tandy.mem_bank * 16 * 1024); + MEM_SetPageHandler( 0xb8, 8, &vgaph.tandy ); + } + goto range_done; // MEM_SetPageHandler(vga.tandy.mem_bank<<2,vga.tandy.is_32k_mode ? 0x08 : 0x04,range_handler); - goto range_b800; + case MCH_VGA: + break; + default: + LOG_MSG("Illegal machine type %d", machine ); + return; } + + /* This should be vga only */ switch (vga.mode) { case M_ERROR: return; case M_LIN4: - range_handler=&vgaph.l4banked; + newHandler = &vgaph.lin4; break; case M_LIN15: case M_LIN16: case M_LIN32: - range_handler=&vgaph.map; +#ifdef VGA_LFB_MAPPED + newHandler = &vgaph.map; +#else + newHandler = &vgaph.changes; +#endif break; case M_LIN8: case M_VGA: if (vga.config.chained) { if(vga.config.compatible_chain4) - range_handler = &vgaph.cvga; - else - range_handler=&vgaph.map; + newHandler = &vgaph.cvga; + else +#ifdef VGA_LFB_MAPPED + newHandler = &vgaph.map; +#else + newHandler = &vgaph.changes; +#endif } else { - range_handler=&vgaph.uvga; + newHandler = &vgaph.uvga; } break; case M_EGA: if (vga.config.chained) - range_handler=&vgaph.cega; + newHandler = &vgaph.cega; else - range_handler=&vgaph.uega; + newHandler = &vgaph.uega; break; case M_TEXT: /* Check if we're not in odd/even mode */ - if (vga.gfx.miscellaneous & 0x2) range_handler=&vgaph.map; - else range_handler=&vgaph.text; + if (vga.gfx.miscellaneous & 0x2) newHandler = &vgaph.map; + else newHandler = &vgaph.text; break; case M_CGA4: case M_CGA2: - range_handler=&vgaph.map; + newHandler = &vgaph.map; break; } switch ((vga.gfx.miscellaneous >> 2) & 3) { case 0: - vgapages.base=VGA_PAGE_A0; - vgapages.mask=0x1ffff; - MEM_SetPageHandler(VGA_PAGE_A0,32,range_handler); + vgapages.base = VGA_PAGE_A0; + vgapages.mask = 0x1ffff; + MEM_SetPageHandler(VGA_PAGE_A0, 32, newHandler ); break; case 1: - vgapages.base=VGA_PAGE_A0; - vgapages.mask=0xffff; - MEM_SetPageHandler(VGA_PAGE_A0,16,range_handler); - MEM_ResetPageHandler(VGA_PAGE_B0,16); + vgapages.base = VGA_PAGE_A0; + vgapages.mask = 0xffff; + MEM_SetPageHandler( VGA_PAGE_A0, 16, newHandler ); + MEM_ResetPageHandler( VGA_PAGE_B0, 16); break; case 2: -range_b000: - vgapages.base=VGA_PAGE_B0; - vgapages.mask=0x7fff; - MEM_SetPageHandler(VGA_PAGE_B0,8,range_handler); - MEM_ResetPageHandler(VGA_PAGE_A0,16); - MEM_ResetPageHandler(VGA_PAGE_B8,8); + vgapages.base = VGA_PAGE_B0; + vgapages.mask = 0x7fff; + MEM_SetPageHandler( VGA_PAGE_B0, 8, newHandler ); + MEM_ResetPageHandler( VGA_PAGE_A0, 16 ); + MEM_ResetPageHandler( VGA_PAGE_B8, 8 ); break; case 3: -range_b800: - vgapages.base=VGA_PAGE_B8; - vgapages.mask=0x7fff; - MEM_SetPageHandler(VGA_PAGE_B8,8,range_handler); - MEM_ResetPageHandler(VGA_PAGE_A0,16); - MEM_ResetPageHandler(VGA_PAGE_B0,8); + vgapages.base = VGA_PAGE_B8; + vgapages.mask = 0x7fff; + MEM_SetPageHandler( VGA_PAGE_B8, 8, newHandler ); + MEM_ResetPageHandler( VGA_PAGE_A0, 16 ); + MEM_ResetPageHandler( VGA_PAGE_B0, 8 ); break; } - if(((vga.s3.ext_mem_ctrl & 0x10) != 0x00) /*&& (vga.mode == M_LIN8)*/) MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio); - +range_done: PAGING_ClearTLB(); } void VGA_StartUpdateLFB(void) { vga.lfb.page = vga.s3.la_window << 4; vga.lfb.addr = vga.s3.la_window << 16; - switch (vga.mode) { - case M_LIN4: - vga.lfb.handler = &vgaph.l4linear; - break; - default: - vga.lfb.handler = &vgaph.lfbchanges; - break; - } +#ifdef VGA_LFB_MAPPED + vga.lfb.handler = &vgaph.lfb; +#else + vga.lfb.handler = &vgaph.lfbchanges; +#endif MEM_SetLFB(vga.s3.la_window << 4 ,sizeof(vga.mem.linear)/4096, vga.lfb.handler ); } @@ -732,11 +905,14 @@ void VGA_UnmapMMIO(void) { void VGA_SetupMemory() { - memset((void *)&vga.mem,0,512*1024*4); + memset( &vga.mem, 0, VGA_MEMORY ); +#ifdef VGA_KEEP_CHANGES + memset( &vga.changes, 0, sizeof( vga.changes )); +#endif vga.s3.svga_bank.fullbank=0; if (machine==MCH_PCJR) { /* PCJr does not have dedicated graphics memory but uses conventional memory below 128k */ - vga.gfxmem_start=GetMemBase(); - } else vga.gfxmem_start=&vga.mem.linear[0]; + //TODO map? + } } diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 6afaf91c..9306acf9 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -20,6 +20,7 @@ #include "inout.h" #include "pic.h" #include "vga.h" +#include static Bit8u flip=0; @@ -31,24 +32,45 @@ Bitu vga_read_p3d5(Bitu port,Bitu iolen); static Bitu vga_read_p3da(Bitu port,Bitu iolen) { vga.internal.attrindex=false; vga.tandy.pcjr_flipflop=false; - if (vga.config.retrace) { - switch (machine) { - case MCH_HERC: - return 0x81; - default: - return 9; - } - } - flip++; - if (flip>20) flip=0; - if (flip>10) return 1; - return 0; - /* - 0 Either Vertical or Horizontal Retrace active if set - 3 Vertical Retrace in progress if set - */ -} + Bit8u retval=0; + double timeInFrame = PIC_FullIndex()-vga.draw.delay.framestart; + vga.internal.attrindex=false; + vga.tandy.pcjr_flipflop=false; + + double timeInLine=fmod(timeInFrame,vga.draw.delay.htotal); + + switch (machine) { + case MCH_HERC: + // 3BAh (R): Status Register + // bit 0 Horizontal sync + // 3 Video signal + // 7 Vertical sync + if(timeInFrame >= vga.draw.delay.vrstart && + timeInFrame <= vga.draw.delay.vrend) + retval |= 0x80; + if(timeInLine >= vga.draw.delay.hrstart && + timeInLine <= vga.draw.delay.hrend) + retval |= 1; + retval |= 0x10; //Hercules ident + break; + default: + // 3DAh (R): Status Register + // bit 0 Horizontal or Vertical blanking + // 3 Vertical sync + + if(timeInFrame >= vga.draw.delay.vrstart && + timeInFrame <= vga.draw.delay.vrend) + retval |= 8; + if(timeInFrame >= vga.draw.delay.vblkstart && + timeInFrame <= vga.draw.delay.vblkend) + retval |= 1; + else if(timeInLine >= vga.draw.delay.hblkstart && + timeInLine <= vga.draw.delay.hblkend) + retval |= 1; + } + return retval; +} static void write_p3c2(Bitu port,Bitu val,Bitu iolen) { vga.misc_output=val; diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 8edb0ee4..a57765d4 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -16,13 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_other.cpp,v 1.19 2007-01-08 19:45:40 qbix79 Exp $ */ +/* $Id: vga_other.cpp,v 1.20 2007-01-24 16:29:09 harekiet Exp $ */ #include #include #include "dosbox.h" #include "inout.h" #include "vga.h" +#include "mem.h" #include "render.h" #include "mapper.h" @@ -47,8 +48,8 @@ static void write_crtc_data_other(Bitu port,Bitu val,Bitu iolen) { case 0x02: //Horizontal sync position vga.other.hsyncp=val; break; - case 0x03: //Horizontal sync width - vga.other.hsyncw=val; + case 0x03: //Horizontal and vertical sync width + vga.other.syncw=val; break; case 0x04: //Vertical total if (vga.other.vtotal ^ val) VGA_StartResize(); @@ -70,10 +71,12 @@ static void write_crtc_data_other(Bitu port,Bitu val,Bitu iolen) { vga.other.max_scanline=val; break; case 0x0A: /* Cursor Start Register */ + vga.other.cursor_start = val & 0x3f; vga.draw.cursor.sline = val&0x1f; vga.draw.cursor.enabled = ((val & 0x60) != 0x20); break; case 0x0B: /* Cursor End Register */ + vga.other.cursor_end = val&0x1f; vga.draw.cursor.eline = val&0x1f; break; case 0x0C: /* Start Address High Register */ @@ -90,6 +93,12 @@ static void write_crtc_data_other(Bitu port,Bitu val,Bitu iolen) { vga.config.cursor_start&=0xff00; vga.config.cursor_start|=val; break; + case 0x10: /* Light Pen High */ + vga.other.lpen_high = val & 0x1f; //only 6 bits + break; + case 0x11: /* Light Pen Low */ + vga.other.lpen_low = val; + break; default: LOG(LOG_VGAMISC,LOG_NORMAL)("MC6845:Write %X to illegal index %x",val,vga.other.index); } @@ -102,8 +111,8 @@ static Bitu read_crtc_data_other(Bitu port,Bitu iolen) { return vga.other.hdend; case 0x02: //Horizontal sync position return vga.other.hsyncp; - case 0x03: //Horizontal sync width - return vga.other.hsyncw; + case 0x03: //Horizontal and vertical sync width + return vga.other.syncw; case 0x04: //Vertical total return vga.other.vtotal; case 0x05: //Vertical display adjust @@ -114,6 +123,10 @@ static Bitu read_crtc_data_other(Bitu port,Bitu iolen) { return vga.other.vsyncp; case 0x09: //Max scanline return vga.other.max_scanline; + case 0x0A: /* Cursor Start Register */ + return vga.other.cursor_start; + case 0x0B: /* Cursor End Register */ + return vga.other.cursor_end; case 0x0C: /* Start Address High Register */ return vga.config.display_start >> 8; case 0x0D: /* Start Address Low Register */ @@ -122,10 +135,14 @@ static Bitu read_crtc_data_other(Bitu port,Bitu iolen) { return vga.config.cursor_start>>8; case 0x0F: /* Cursor Location Low Register */ return vga.config.cursor_start; + case 0x10: /* Light Pen High */ + return vga.other.lpen_high; + case 0x11: /* Light Pen Low */ + return vga.other.lpen_low; default: LOG(LOG_VGAMISC,LOG_NORMAL)("MC6845:Read from illegal index %x",vga.other.index); } - return (Bitu)-1; + return ~0; } static double hue_offset = 0.0; @@ -241,25 +258,16 @@ static void write_color_select(Bit8u val) { } } -static void write_mode_control(Bit8u val) { - /* Check if someone changes the blinking/hi intensity bit */ - vga.tandy.mode_control=val; - VGA_SetBlinking((val & 0x20)); - if (val & 0x2) { - if (val & 0x10) { - } else VGA_SetMode(M_CGA4); - write_color_select(vga.tandy.color_select); //Setup the correct palette - } else { - VGA_SetMode(M_TEXT); - } -} - static void TANDY_FindMode(void) { if (vga.tandy.mode_control & 0x2) { - if (vga.tandy.gfx_control & 0x10) VGA_SetMode(M_TANDY16); - else if (vga.tandy.gfx_control & 0x08) VGA_SetMode(M_TANDY4); - else if (vga.tandy.mode_control & 0x10) VGA_SetMode(M_TANDY2); - else VGA_SetMode(M_TANDY4); + if (vga.tandy.gfx_control & 0x10) + VGA_SetMode(M_TANDY16); + else if (vga.tandy.gfx_control & 0x08) + VGA_SetMode(M_TANDY4); + else if (vga.tandy.mode_control & 0x10) + VGA_SetMode(M_TANDY2); + else + VGA_SetMode(M_TANDY4); write_color_select(vga.tandy.color_select); } else { VGA_SetMode(M_TANDY_TEXT); @@ -284,6 +292,21 @@ static void PCJr_FindMode(void) { } } +static void TandyCheckLineMask(void ) { + if ( vga.tandy.extended_ram & 1 ) { + vga.tandy.line_mask = 0; + } else if ( vga.tandy.mode_control & 0x2) { + vga.tandy.line_mask |= 1; + } + if ( vga.tandy.line_mask ) { + vga.tandy.line_shift = 13; + vga.tandy.addr_mask = (1 << 13) - 1; + } else { + vga.tandy.addr_mask = ~0; + vga.tandy.line_shift = 0; + } +} + static void write_tandy_reg(Bit8u val) { switch (vga.tandy.reg_index) { case 0x0: @@ -291,7 +314,10 @@ static void write_tandy_reg(Bit8u val) { vga.tandy.mode_control=val; VGA_SetBlinking(val & 0x20); PCJr_FindMode(); - } else LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index); + } else { + LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index); + } + break; case 0x2: /* Border color */ vga.tandy.border_color=val; break; @@ -300,6 +326,19 @@ static void write_tandy_reg(Bit8u val) { if (machine==MCH_TANDY) TANDY_FindMode(); else PCJr_FindMode(); break; + case 0x5: /* Extended ram page register */ + // Bit 0 enables extended ram + // Bit 7 Switches clock, 0 -> cga 28.6 , 1 -> mono 32.5 + vga.tandy.extended_ram = val; + //This is a bit of a hack to enable mapping video memory differently for highres mode + TandyCheckLineMask(); + VGA_SetupHandlers(); + break; + case 0x8: /* Monitor mode seletion */ + //Bit 1 select mode e, for 640x200x16, some double clocking thing? + //Bit 4 select 350 line mode for hercules emulation + LOG(LOG_VGAMISC,LOG_NORMAL)("Write %2X to tandy monitor mode",val ); + break; /* palette colors */ case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: @@ -340,6 +379,7 @@ static void write_tandy(Bitu port,Bitu val,Bitu iolen) { switch (port) { case 0x3d8: vga.tandy.mode_control=val; + TandyCheckLineMask(); VGA_SetBlinking(val & 0x20); TANDY_FindMode(); break; @@ -349,13 +389,20 @@ static void write_tandy(Bitu port,Bitu val,Bitu iolen) { case 0x3da: vga.tandy.reg_index=val; break; +// case 0x3db: //Clear lightpen latch + break; +// case 0x3dc: //Preset lightpen latch + break; +// case 0x3dd: //Extended ram page address register: + break; case 0x3de: write_tandy_reg(val); break; case 0x3df: - vga.tandy.is_32k_mode=(val & 0x80)==0x80; - vga.tandy.disp_bank=val & ((val & 0x80) ? 0x6 : 0x7); - vga.tandy.mem_bank=(val >> 3) & ((val & 0x80) ? 0x6 : 0x7); + vga.tandy.line_mask = val >> 6; + vga.tandy.draw_bank = val & 0x7; + vga.tandy.mem_bank = (val >> 3) & 0x7; + TandyCheckLineMask(); VGA_SetupHandlers(); break; } @@ -372,9 +419,12 @@ static void write_pcjr(Bitu port,Bitu val,Bitu iolen) { vga.tandy.pcjr_flipflop=!vga.tandy.pcjr_flipflop; break; case 0x3df: - vga.tandy.is_32k_mode=(val & 0x80)==0x80; - vga.tandy.disp_bank=val & (vga.tandy.is_32k_mode ? 0x6 : 0x7); - vga.tandy.mem_bank=(val >> 3) & 0x7; + vga.tandy.line_mask = val >> 6; + vga.tandy.draw_bank = val & 0x7; + vga.tandy.mem_bank = (val >> 3) & 0x7; + vga.tandy.draw_base = &MemBase[vga.tandy.draw_bank * 16 * 1024]; + vga.tandy.mem_base = &MemBase[vga.tandy.mem_bank * 16 * 1024]; + TandyCheckLineMask(); VGA_SetupHandlers(); break; } @@ -383,7 +433,7 @@ static void write_pcjr(Bitu port,Bitu val,Bitu iolen) { static void write_hercules(Bitu port,Bitu val,Bitu iolen) { switch (port) { case 0x3b8: - if (vga.herc.enable_bits & 1) { + if (vga.herc.enable_bits & 1 ) { vga.herc.mode_control&=~0x2; vga.herc.mode_control|=(val&0x2); if (val & 0x2) { @@ -394,11 +444,14 @@ static void write_hercules(Bitu port,Bitu val,Bitu iolen) { } if ((vga.herc.enable_bits & 0x2) && ((vga.herc.mode_control ^ val)&0x80)) { vga.herc.mode_control^=0x80; - VGA_SetupHandlers(); } + vga.tandy.draw_base = &vga.mem.linear[(vga.herc.mode_control & 0x80 ) ? 32*1024 : 0]; break; case 0x3bf: - vga.herc.enable_bits=val; + if ( vga.herc.enable_bits ^ val) { + vga.herc.enable_bits=val; + VGA_SetupHandlers(); + } break; } } @@ -411,6 +464,14 @@ static Bitu read_hercules(Bitu port,Bitu iolen) { void VGA_SetupOther(void) { Bitu i; + memset( &vga.tandy, 0, sizeof( vga.tandy )); + //Initialize values common for most machines, can be overwritten + vga.tandy.draw_base = vga.mem.linear; + vga.tandy.mem_base = vga.mem.linear; + vga.tandy.addr_mask = 8*1024 - 1; + vga.tandy.line_mask = 3; + vga.tandy.line_shift = 13; + if (machine==MCH_CGA || IS_TANDY_ARCH) { extern Bit8u int10_font_08[256 * 8]; for (i=0;i<256;i++) memcpy(&vga.draw.font[i*32],&int10_font_08[i*8],8); @@ -434,7 +495,7 @@ void VGA_SetupOther(void) { IO_RegisterWriteHandler(0x3bf,write_hercules,IO_MB); } if (machine==MCH_TANDY) { - vga.tandy.is_32k_mode=false; + write_tandy( 0x3df, 0x0, 0 ); IO_RegisterWriteHandler(0x3d8,write_tandy,IO_MB); IO_RegisterWriteHandler(0x3d9,write_tandy,IO_MB); IO_RegisterWriteHandler(0x3de,write_tandy,IO_MB); @@ -442,8 +503,8 @@ void VGA_SetupOther(void) { IO_RegisterWriteHandler(0x3da,write_tandy,IO_MB); } if (machine==MCH_PCJR) { - vga.tandy.mem_bank=7;vga.tandy.disp_bank=7; - vga.tandy.is_32k_mode=false;vga.tandy.pcjr_flipflop=false; + //write_pcjr will setup base address + write_pcjr( 0x3df, 0x7 | (0x7 << 3), 0 ); IO_RegisterWriteHandler(0x3d9,write_pcjr,IO_MB); IO_RegisterWriteHandler(0x3da,write_pcjr,IO_MB); IO_RegisterWriteHandler(0x3df,write_pcjr,IO_MB); diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 0b860dbf..3cab386e 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -195,6 +195,8 @@ static Bitu INT10_Handler(void) { } break; case 0x11: /* Character generator functions */ + if (machinemode]; @@ -400,6 +407,12 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { default: IO_WriteB(0x3de,0x0);break; } + //Clear extended mapping + IO_WriteB(0x3da,0x5); + IO_WriteB(0x3de,0x0); + //Clear monitor mode + IO_WriteB(0x3da,0x8); + IO_WriteB(0x3de,0x0); crtpage=(CurMode->mode>=0x9) ? 0xf6 : 0x3f; IO_WriteB(0x3df,crtpage); real_writeb(BIOSMEM_SEG,BIOSMEM_CRTCPU_PAGE,crtpage); @@ -974,7 +987,6 @@ dac_text16: } IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,reg_31); //Enable banked memory and 256k+ access IO_Write(crtc_base,0x58);IO_Write(crtc_base+1,0x3); //Enable 8 mb of linear addressing - IO_Write(crtc_base,0x58);IO_Write(crtc_base+1,0x3); //Enable 8 mb of linear addressing IO_Write(crtc_base,0x38);IO_Write(crtc_base+1,0x48); //Register lock 1 IO_Write(crtc_base,0x39);IO_Write(crtc_base+1,0xa5); //Register lock 2 From 576d1c6eff85ecc4468c1663039b79841563e08a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 24 Jan 2007 16:29:53 +0000 Subject: [PATCH 2697/4131] Fix setwindow position setting for 15/16/32bpp modes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2782 --- src/ints/int10_vesa.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 417a01b8..04f7bd60 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.25 2007-01-08 19:45:41 qbix79 Exp $ */ +/* $Id: int10_vesa.cpp,v 1.26 2007-01-24 16:29:53 harekiet Exp $ */ #include #include @@ -292,6 +292,7 @@ Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u val, Bit16u & bytes,Bit16u & pixe Bit8u bpp; switch (CurMode->type) { case M_LIN4: + bpp = 1; break; case M_LIN8: bpp=1; @@ -356,11 +357,11 @@ Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y) { break; case M_LIN16: case M_LIN15: - start=vga.config.scan_len*8*y+x; + start=vga.config.scan_len*8*y+x*2; vga.config.display_start=start/4; break; case M_LIN32: - start=vga.config.scan_len*8*y+x; + start=vga.config.scan_len*8*y+x*4; vga.config.display_start=start/4; break; default: From 5bd556e219a27c128911454216c476d0600dc347 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 24 Jan 2007 16:54:00 +0000 Subject: [PATCH 2698/4131] Only show resolution log message in debug version Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2783 --- src/hardware/vga_draw.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 1de5a1b3..fdd0d723 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -734,11 +734,12 @@ void VGA_SetupDrawing(Bitu val) { break; } } +#if C_DEBUG LOG(LOG_VGA,LOG_NORMAL)("h total %d end %d blank (%d/%d) retrace (%d/%d)", htotal, hdend, hbstart, hbend, hrstart, hrend ); LOG(LOG_VGA,LOG_NORMAL)("v total %d end %d blank (%d/%d) retrace (%d/%d)", vtotal, vdend, vbstart, vbend, vrstart, vrend ); - +#endif if (!htotal) return; if (!vtotal) return; From b9e934fd97e71df4c219f39d14a482edb9ee671d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 25 Jan 2007 07:35:06 +0000 Subject: [PATCH 2699/4131] Fix uninitialized value Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2784 --- src/gui/render_simple.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/render_simple.h b/src/gui/render_simple.h index 4581a5e2..84b50333 100644 --- a/src/gui/render_simple.h +++ b/src/gui/render_simple.h @@ -34,7 +34,7 @@ static void conc4d(SCALERNAME,SBPP,DBPP,R)(const void *s) { } #endif /* Clear the complete line marker */ - Bitu hadChange; + Bitu hadChange = 0; const SRCTYPE *src = (SRCTYPE*)s; SRCTYPE *cache = (SRCTYPE*)(render.scale.cacheRead); render.scale.cacheRead += render.scale.cachePitch; From a1e661ddbb02af6a02ab01cd7ee189da6e9e7c51 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 25 Jan 2007 08:08:14 +0000 Subject: [PATCH 2700/4131] Add suppport for the dac pel mask Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2785 --- src/hardware/vga_dac.cpp | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index 8075343d..980e0654 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -50,10 +50,22 @@ Note: Each read or write of this register will cycle through first the enum {DAC_READ,DAC_WRITE}; +static INLINE void VGA_DAC_UpdateColor( Bitu index ) { + Bitu maskIndex = index & vga.dac.pel_mask; + RENDER_SetPal( index, + vga.dac.rgb[maskIndex].red << 2, + vga.dac.rgb[maskIndex].green << 2, + vga.dac.rgb[maskIndex].blue << 2 + ); +} static void write_p3c6(Bitu port,Bitu val,Bitu iolen) { - if (val!=0xff) LOG(LOG_VGAGFX,LOG_NORMAL)("VGA:Pel Mask not 0xff"); - vga.dac.pel_mask=val; + if ( vga.dac.pel_mask != val ) { + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:DCA:Pel Mask set to %X", val); + vga.dac.pel_mask = val; + for ( Bitu i = 0;i<256;i++) + VGA_DAC_UpdateColor( i ); + } } @@ -100,12 +112,15 @@ static void write_p3c9(Bitu port,Bitu val,Bitu iolen) { switch (vga.mode) { case M_VGA: case M_LIN8: - case M_LIN16: - RENDER_SetPal(vga.dac.write_index, - vga.dac.rgb[vga.dac.write_index].red << 2, - vga.dac.rgb[vga.dac.write_index].green << 2, - vga.dac.rgb[vga.dac.write_index].blue << 2 - ); + VGA_DAC_UpdateColor( vga.dac.write_index ); + if ( GCC_UNLIKELY( vga.dac.pel_mask != 0xff)) { + Bitu index = vga.dac.write_index; + if ( (index & vga.dac.pel_mask) == index ) { + for ( Bitu i = index+1;i<256;i++) + if ( (i & vga.dac.pel_mask) == index ) + VGA_DAC_UpdateColor( i ); + } + } break; default: /* Check for attributes and DAC entry link */ @@ -168,15 +183,10 @@ void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal) { } void VGA_DAC_SetEntry(Bitu entry,Bit8u red,Bit8u green,Bit8u blue) { + //Should only be called in machine != vga vga.dac.rgb[entry].red=red; vga.dac.rgb[entry].green=green; vga.dac.rgb[entry].blue=blue; - switch (vga.mode) { - case M_VGA: - case M_LIN8: - case M_LIN16: - return; - } for (Bitu i=0;i<16;i++) if (vga.attr.palette[i]==entry) RENDER_SetPal(i,red << 2,green << 2,blue << 2); From 87cd8a180e6696be83eaf3763df21b3945e8b7ef Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 25 Jan 2007 08:08:32 +0000 Subject: [PATCH 2701/4131] Use the cached data for chained mode rendering Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2786 --- src/hardware/vga_draw.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index fdd0d723..3cfebf31 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -162,6 +162,7 @@ static Bit8u * VGA_Draw_Linear_Line(Bitu vidstart, Bitu line) { return &vga.draw.linear_base[ vidstart & vga.draw.linear_mask ]; } +//Test version, might as well keep it static Bit8u * VGA_Draw_Chain_Line(Bitu vidstart, Bitu line) { Bitu i = 0; for ( i = 0; i < vga.draw.width;i++ ) { @@ -171,7 +172,6 @@ static Bit8u * VGA_Draw_Chain_Line(Bitu vidstart, Bitu line) { return TempLine; } - static Bit8u * VGA_Draw_VGA_Line_HWMouse( Bitu vidstart, Bitu line) { if(vga.s3.hgc.curmode & 0x1) { Bitu lineat = vidstart / vga.draw.width; @@ -525,11 +525,9 @@ static void VGA_VerticalTimer(Bitu val) { if(vga.config.compatible_chain4 && (vga.crtc.underline_location & 0x40)) { vga.draw.linear_base = vga.mem.linear + VGA_CACHE_OFFSET; vga.draw.linear_mask = 0xffff; - VGA_DrawLine = VGA_Draw_Chain_Line; } else { vga.draw.linear_base = vga.mem.linear; vga.draw.linear_mask = VGA_MEMORY - 1; - VGA_DrawLine = VGA_Draw_Linear_Line; } case M_LIN8: case M_LIN15: From 79c55d9ebf5b3f3c4541c1f366dc4f1692733bc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 26 Jan 2007 16:22:43 +0000 Subject: [PATCH 2702/4131] typo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2787 --- src/dos/dos_programs.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 41cce0fb..e8a2c500 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.66 2007-01-21 16:21:22 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.67 2007-01-26 16:22:43 c2woody Exp $ */ #include #include @@ -937,12 +937,12 @@ public: temp_line = tmp; if (stat(temp_line.c_str(),&test)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNG_FILE_NOT_FOUND")); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FILE_NOT_FOUND")); return; } if ((test.st_mode & S_IFDIR)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNG_MOUNT")); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MOUNT")); return; } } From 5c20be0f85e9a54aaafe051b8d0aa6187ee33e40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 26 Jan 2007 18:02:28 +0000 Subject: [PATCH 2703/4131] disable shortcut Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2788 --- src/dos/dos_keyboard_layout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 84459d3a..79e8af3c 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -1054,5 +1054,5 @@ void DOS_KeyboardLayout_ShutDown(Section* /*sec*/) { void DOS_KeyboardLayout_Init(Section* sec) { test = new DOS_KeyboardLayout(sec); sec->AddDestroyFunction(&DOS_KeyboardLayout_ShutDown,true); - MAPPER_AddHandler(switch_keyboard_layout,MK_f2,MMOD1|MMOD2,"sw_layout","Switch Layout"); +// MAPPER_AddHandler(switch_keyboard_layout,MK_f2,MMOD1|MMOD2,"sw_layout","Switch Layout"); } From 5ef29db80625c9532985a16540113477edc95ba5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 28 Jan 2007 20:08:52 +0000 Subject: [PATCH 2704/4131] Fix small bug in readdata. Causes problems on every 32 reads. Thanks Srecko Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2789 --- src/hardware/mpu401.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index c1532748..29e083ea 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.24 2007-01-19 18:48:31 qbix79 Exp $ */ +/* $Id: mpu401.cpp,v 1.25 2007-01-28 20:08:52 qbix79 Exp $ */ #include #include "dosbox.h" @@ -258,8 +258,8 @@ static void MPU401_WriteCommand(Bitu port,Bitu val,Bitu iolen) { static Bitu MPU401_ReadData(Bitu port,Bitu iolen) { Bit8u ret=MSG_MPU_ACK; if (mpu.queue_used) { - ret=mpu.queue[mpu.queue_pos]; if (mpu.queue_pos>=MPU401_QUEUE) mpu.queue_pos-=MPU401_QUEUE; + ret=mpu.queue[mpu.queue_pos]; mpu.queue_pos++;mpu.queue_used--; } if (!mpu.intelligent) return ret; From 42adb8617ce0df0efcd9c79650d1d09a4d880e15 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 31 Jan 2007 11:08:35 +0000 Subject: [PATCH 2705/4131] Vesa 16 color modes use the highres vga/textmode palette Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2790 --- src/ints/int10_modes.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index dca2fc14..c5c9ae17 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -802,8 +802,8 @@ bool INT10_SetVideoMode(Bitu mode) { att_data[0x12]=0xf; //Always have all color planes enabled /* Program Attribute Controller */ switch (CurMode->type) { - case M_LIN4: case M_EGA: + case M_LIN4: att_data[0x10]=0x01; //Color Graphics switch (CurMode->mode) { case 0x0f: @@ -820,6 +820,8 @@ bool INT10_SetVideoMode(Bitu mode) { case 0x10: case 0x12: goto att_text16; default: + if ( CurMode->type == M_LIN4 ) + goto att_text16; for (i=0;i<8;i++) { att_data[i]=i; att_data[i+8]=i+0x10; From 477a30e2bd293ccbd0e51a5ea711bfef14d2af86 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 31 Jan 2007 11:09:42 +0000 Subject: [PATCH 2706/4131] 16 color vesa modes start address setting added Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2791 --- src/hardware/vga_draw.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 3cfebf31..2c0f5880 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -515,6 +515,7 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.split_line=(vga.config.line_compare/vga.draw.lines_scaled); switch (vga.mode) { case M_EGA: + case M_LIN4: vga.draw.address *= 8; vga.draw.address += vga.config.pel_panning; #ifdef VGA_KEEP_CHANGES From 28cc8c5c9f9166ece5c9a508c1e8c061a8542980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 1 Feb 2007 15:32:19 +0000 Subject: [PATCH 2707/4131] fix pcjr sysrom location Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2792 --- src/dos/dos_programs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index e8a2c500..50d79877 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.67 2007-01-26 16:22:43 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.68 2007-02-01 15:32:19 c2woody Exp $ */ #include #include @@ -582,7 +582,7 @@ public: fseek(tfile, 0x3000L, SEEK_SET); Bit32u drd=fread(rombuf, 1, 0xb000, tfile); if (drd==0xb000) { - for(i=0;i<0xb000;i++) phys_writeb(0xfb000+i,rombuf[i]); + for(i=0;i<0xb000;i++) phys_writeb(0xf3000+i,rombuf[i]); } fclose(tfile); } From c0c80145d61469c9b6263e6709621ebca71193c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 1 Feb 2007 16:24:03 +0000 Subject: [PATCH 2708/4131] clear banking bit0 for 32k tandy modes; fix some pcjr mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2793 --- src/hardware/vga_draw.cpp | 2 +- src/hardware/vga_other.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 2c0f5880..56f7da8c 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -901,7 +901,7 @@ void VGA_SetupDrawing(Bitu val) { doubleheight=true; vga.draw.blocks=width*2; if (vga.tandy.mode_control & 0x1) { - if ( vga.tandy.mode_control & 0x10 ) { + if (( machine==MCH_TANDY ) && ( vga.tandy.mode_control & 0x10 )) { doublewidth = false; vga.draw.blocks*=2; width=vga.draw.blocks*2; diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index a57765d4..1c723d93 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_other.cpp,v 1.20 2007-01-24 16:29:09 harekiet Exp $ */ +/* $Id: vga_other.cpp,v 1.21 2007-02-01 16:24:03 c2woody Exp $ */ #include #include @@ -400,8 +400,8 @@ static void write_tandy(Bitu port,Bitu val,Bitu iolen) { break; case 0x3df: vga.tandy.line_mask = val >> 6; - vga.tandy.draw_bank = val & 0x7; - vga.tandy.mem_bank = (val >> 3) & 0x7; + vga.tandy.draw_bank = val & ((vga.tandy.line_mask&2) ? 0x6 : 0x7); + vga.tandy.mem_bank = (val >> 3) & ((vga.tandy.line_mask&2) ? 0x6 : 0x7); TandyCheckLineMask(); VGA_SetupHandlers(); break; @@ -420,8 +420,8 @@ static void write_pcjr(Bitu port,Bitu val,Bitu iolen) { break; case 0x3df: vga.tandy.line_mask = val >> 6; - vga.tandy.draw_bank = val & 0x7; - vga.tandy.mem_bank = (val >> 3) & 0x7; + vga.tandy.draw_bank = val & ((vga.tandy.line_mask&2) ? 0x6 : 0x7); + vga.tandy.mem_bank = (val >> 3) & ((vga.tandy.line_mask&2) ? 0x6 : 0x7); vga.tandy.draw_base = &MemBase[vga.tandy.draw_bank * 16 * 1024]; vga.tandy.mem_base = &MemBase[vga.tandy.mem_bank * 16 * 1024]; TandyCheckLineMask(); From 2b577443e021b2e3a3e1fcb369330c32b879081b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 2 Feb 2007 17:23:14 +0000 Subject: [PATCH 2709/4131] avoid selfpage removal for crossblocks when codepages run out Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2794 --- src/cpu/core_dyn_x86/cache.h | 38 +---------------------------- src/cpu/core_dyn_x86/decoder.h | 44 ++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index bd2b51ac..ce3f2556 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -278,42 +278,6 @@ private: }; -static bool MakeCodePage(Bitu lin_page,CodePageHandler * &cph) { - Bit8u rdval; - //Ensure page contains memory: - if (GCC_UNLIKELY(mem_readb_checked_x86(lin_page << 12,&rdval))) return true; - PageHandler * handler=paging.tlb.handler[lin_page]; - if (handler->flags & PFLAG_HASCODE) { - cph=( CodePageHandler *)handler; - return false; - } - if (handler->flags & PFLAG_NOCODE) { - LOG_MSG("DYNX86:Can't run code in this page"); - cph=0; return false; - } - Bitu phys_page=lin_page; - if (!PAGING_MakePhysPage(phys_page)) { - LOG_MSG("DYNX86:Can't find physpage"); - cph=0; return false; - } - /* Find a free CodePage */ - if (!cache.free_pages) { - cache.used_pages->ClearRelease(); - } - CodePageHandler * cpagehandler=cache.free_pages; - cache.free_pages=cache.free_pages->next; - cpagehandler->prev=cache.last_page; - cpagehandler->next=0; - if (cache.last_page) cache.last_page->next=cpagehandler; - cache.last_page=cpagehandler; - if (!cache.used_pages) cache.used_pages=cpagehandler; - cpagehandler->SetupAt(phys_page,handler); - MEM_SetPageHandler(phys_page,1,cpagehandler); - PAGING_UnlinkPages(lin_page,1); - cph=cpagehandler; - return false; -} - static INLINE void cache_addunsedblock(CacheBlock * block) { block->cache.next=cache.block.free; cache.block.free=block; @@ -502,7 +466,7 @@ static void cache_init(bool enable) { cache.last_page=0; cache.used_pages=0; /* Setup the code pages */ - for (i=0;inext=cache.free_pages; cache.free_pages=newpage; diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 35cdd147..caec4c29 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -50,6 +50,50 @@ static struct DynDecode { DynReg * segprefix; } decode; +static bool MakeCodePage(Bitu lin_page,CodePageHandler * &cph) { + Bit8u rdval; + //Ensure page contains memory: + if (GCC_UNLIKELY(mem_readb_checked_x86(lin_page << 12,&rdval))) return true; + PageHandler * handler=paging.tlb.handler[lin_page]; + if (handler->flags & PFLAG_HASCODE) { + cph=( CodePageHandler *)handler; + return false; + } + if (handler->flags & PFLAG_NOCODE) { + LOG_MSG("DYNX86:Can't run code in this page"); + cph=0; return false; + } + Bitu phys_page=lin_page; + if (!PAGING_MakePhysPage(phys_page)) { + LOG_MSG("DYNX86:Can't find physpage"); + cph=0; return false; + } + /* Find a free CodePage */ + if (!cache.free_pages) { + if (cache.used_pages!=decode.page.code) cache.used_pages->ClearRelease(); + else { + if ((cache.used_pages->next) && (cache.used_pages->next!=decode.page.code)) + cache.used_pages->next->ClearRelease(); + else { + LOG_MSG("DYNX86:Invalid cache links"); + cache.used_pages->ClearRelease(); + } + } + } + CodePageHandler * cpagehandler=cache.free_pages; + cache.free_pages=cache.free_pages->next; + cpagehandler->prev=cache.last_page; + cpagehandler->next=0; + if (cache.last_page) cache.last_page->next=cpagehandler; + cache.last_page=cpagehandler; + if (!cache.used_pages) cache.used_pages=cpagehandler; + cpagehandler->SetupAt(phys_page,handler); + MEM_SetPageHandler(phys_page,1,cpagehandler); + PAGING_UnlinkPages(lin_page,1); + cph=cpagehandler; + return false; +} + static Bit8u decode_fetchb(void) { if (GCC_UNLIKELY(decode.page.index>=4096)) { /* Advance to the next page */ From ac97451586baacad2b6ef2f67d98edf52657c866 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 3 Feb 2007 08:53:58 +0000 Subject: [PATCH 2710/4131] Fix ending the previous frame if it didn't finish in time Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2795 --- src/hardware/vga_draw.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 56f7da8c..57660d66 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -501,8 +501,10 @@ static void VGA_VerticalTimer(Bitu val) { // LOG_MSG("vgaerror: %f",error); PIC_AddEvent(VGA_VerticalTimer, (float)vga.draw.delay.vtotal ); if ( GCC_UNLIKELY( vga.draw.parts_left )) { - LOG_MSG( "parts left: %d", vga.draw.parts_left ); + LOG(LOG_VGAMISC,LOG_NORMAL)( "Parts left: %d", vga.draw.parts_left ); PIC_RemoveEvents( &VGA_DrawPart ); + RENDER_EndUpdate(); + vga.draw.parts_left = 0; } //Check if we can actually render, else skip the rest if (!RENDER_StartUpdate()) From a76a07d2c93e8a7100b9b6e84f1ef0a5c52b8bb1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 3 Feb 2007 13:00:16 +0000 Subject: [PATCH 2711/4131] Finish the frame without drawing if there's screen reset Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2796 --- src/gui/render.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 37316ea7..d82f39f7 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.50 2007-01-24 16:29:09 harekiet Exp $ */ +/* $Id: render.cpp,v 1.51 2007-02-03 13:00:16 harekiet Exp $ */ #include #include @@ -121,6 +121,19 @@ static void RENDER_StartLineHandler(const void * s) { render.scale.outLine++; } +static void RENDER_FinishLineHandler(const void * s) { + if (s) { + const Bitu *src = (Bitu*)s; + Bitu *cache = (Bitu*)(render.scale.cacheRead); + for (Bits x=render.src.start;x>0;) { + cache[0] = src[0]; + x--; src++; cache++; + } + } + render.scale.cacheRead += render.scale.cachePitch; +} + + static void RENDER_ClearCacheHandler(const void * src) { Bitu x, width; Bit32u *srcLine, *cacheLine; @@ -462,6 +475,9 @@ forcenormal: render.pal.last = 255; render.pal.changed = false; memset(render.pal.modified, 0, sizeof(render.pal.modified)); + //Finish this frame using a copy only handler + RENDER_DrawLine = RENDER_FinishLineHandler; + render.scale.outWrite = 0; /* Signal the next frame to first reinit the cache */ render.scale.clearCache = true; render.active=true; From 88c948bc000685e0d9b4bc8528d3693c84311599 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 3 Feb 2007 14:04:23 +0000 Subject: [PATCH 2712/4131] Fix bug "[ 1647131 ] PATH env var not handled properly." Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2797 --- src/shell/shell_misc.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index dbdfe404..cb2c7fb3 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.48 2007-01-21 14:12:02 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.49 2007-02-03 14:04:23 qbix79 Exp $ */ #include #include @@ -356,7 +356,8 @@ void DOS_Shell::InputCommand(char * line) { bool DOS_Shell::Execute(char * name,char * args) { /* return true => don't check for hardware changes in do_command * return false => check for hardware changes in do_command */ - char * fullname; + char fullname[DOS_PATHLENGTH+4]; //stores results from Which + char* p_fullname; char line[CMD_MAXLINE]; if(strlen(args)!= 0){ if(*args != ' '){ //put a space in front @@ -381,15 +382,17 @@ bool DOS_Shell::Execute(char * name,char * args) { return true; } /* Check for a full name */ - fullname=Which(name); - if (!fullname) return false; - - const char* extension =strrchr(fullname,'.'); + p_fullname = Which(name); + if (!p_fullname) return false; + strcpy(fullname,p_fullname); + const char* extension = strrchr(fullname,'.'); /*always disallow files without extension from being executed. */ /*only internal commands can be run this way and they never get in this handler */ if(extension == 0) { + //Check if the result will fit in the parameters. Else abort + if(strlen(fullname) >( DOS_PATHLENGTH - 1) ) return false; char temp_name[DOS_PATHLENGTH+4],* temp_fullname; //try to add .com, .exe and .bat extensions to filename From 4f7838f172fc056610722efe99f5bf3ca077dc93 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 3 Feb 2007 14:11:38 +0000 Subject: [PATCH 2713/4131] Add improved fix for the ballad sequencer. Thanks Srecko Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2798 --- src/hardware/mpu401.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 29e083ea..43c48661 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.25 2007-01-28 20:08:52 qbix79 Exp $ */ +/* $Id: mpu401.cpp,v 1.26 2007-02-03 14:11:38 qbix79 Exp $ */ #include #include "dosbox.h" @@ -41,6 +41,8 @@ static void MPU401_EOIHandler(void); enum MpuMode { M_UART,M_INTELLIGENT }; enum MpuDataType {T_OVERFLOW,T_MARK,T_MIDI_SYS,T_MIDI_NORM,T_COMMAND}; +static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen); + /* Messages sent to MPU-401 from host */ #define MSG_EOX 0xf7 #define MSG_OVERFLOW 0xf8 @@ -270,13 +272,16 @@ static Bitu MPU401_ReadData(Bitu port,Bitu iolen) { mpu.state.channel=ret&7; mpu.state.data_onoff=0; mpu.state.cond_req=false; - mpu.state.command_byte=0; } if (ret==MSG_MPU_COMMAND_REQ) { mpu.state.data_onoff=0; mpu.state.cond_req=true; - mpu.state.wsd=mpu.state.wsm=false; - mpu.state.command_byte=0; + if (mpu.condbuf.type!=T_OVERFLOW) { + mpu.state.block_ack=true; + MPU401_WriteCommand(0x331,mpu.condbuf.value[0],1); + if (mpu.state.command_byte) MPU401_WriteData(0x330,mpu.condbuf.value[1],1); + } + mpu.condbuf.type=T_OVERFLOW; } if (ret==MSG_MPU_END || ret==MSG_MPU_CLOCK || ret==MSG_MPU_ACK) { mpu.state.data_onoff=-1; @@ -496,13 +501,7 @@ static void UpdateTrack(Bit8u chan) { } static void UpdateConductor(void) { - if (mpu.condbuf.type!=T_OVERFLOW) { - mpu.state.block_ack=true; - MPU401_WriteCommand(0x331,mpu.condbuf.value[0],1); - if (mpu.state.command_byte) MPU401_WriteData(0x330,mpu.condbuf.value[1],1); - } mpu.condbuf.vlength=0; - mpu.condbuf.type=T_OVERFLOW; mpu.condbuf.counter=0xf0; mpu.state.req_mask|=(1<<9); } From 49d47cfb2fe832197c7862fef79744bf68d2bf4d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 4 Feb 2007 10:34:23 +0000 Subject: [PATCH 2714/4131] Add 64 bit windows topic Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2799 --- docs/README.video | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/README.video b/docs/README.video index a79f8028..1d15b4f9 100644 --- a/docs/README.video +++ b/docs/README.video @@ -30,3 +30,6 @@ A: 1. Start DOSBox like this: dosbox -startmapper 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 From 6622f2de24df916525335444450fd67ba3de9118 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 4 Feb 2007 10:37:18 +0000 Subject: [PATCH 2715/4131] 0.66 release candidate 1 installer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2800 --- scripts/dosbox-installer.nsi | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index df265ad9..5783d202 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -1,5 +1,5 @@ !define VER_MAYOR 0 -!define VER_MINOR 65 +!define VER_MINOR 66rc1 ; The name of the installer Name "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer" @@ -38,20 +38,30 @@ Section "ThisNameIsIgnoredSoWhyBother?" File /oname=zmbv\zmbv.dll zmbv.dll File /oname=zmbv\zmbv.inf zmbv.inf File /oname=zmbv\README.txt README.video -; File libpng12.dll -; File libogg-0.dll -; File libvorbis-0.dll -; File libvorbisfile-3.dll 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$\"" + 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}\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" - CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Install movie codec.lnk" "rundll32" "syssetup,SetupInfObjectInstallAction DefaultInstall 128 $INSTDIR\zmbv\zmbv.inf" +;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" SectionEnd ; end the section @@ -74,10 +84,6 @@ Section "Uninstall" Delete $INSTDIR\zmbv\zmbv.dll Delete $INSTDIR\zmbv\zmbv.inf Delete $INSTDIR\zmbv\README.txt -; Delete $INSTDIR\libpng12.dll -; Delete $INSTDIR\libogg-0.dll -; Delete $INSTDIR\libvorbis-0.dll -; Delete $INSTDIR\libvorbisfile-3.dll ;Files left by sdl taking over the console Delete $INSTDIR\stdout.txt Delete $INSTDIR\stderr.txt From f28020edb30133bb3bd91061d33c680aa6eabdee Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 4 Feb 2007 10:46:34 +0000 Subject: [PATCH 2716/4131] Allow less beautiful version numbers. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2801 --- autogen.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autogen.sh b/autogen.sh index 5e6dff91..4d7d5ba7 100755 --- a/autogen.sh +++ b/autogen.sh @@ -7,7 +7,7 @@ echo "This may take a while ..." aclocal autoheader -automake --gnits --include-deps --add-missing --copy +automake --include-deps --add-missing --copy autoconf echo "Now you are ready to run ./configure." From 0bf5025feaafca78a037024d8e0424d425211bd7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 4 Feb 2007 11:10:22 +0000 Subject: [PATCH 2717/4131] iodelay aware cycle adjustment code. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2802 --- include/cpu.h | 1 + src/cpu/cpu.cpp | 3 ++- src/dosbox.cpp | 44 +++++++++++++++++++++++++++----------- src/hardware/iohandler.cpp | 28 ++++++++++++++++++++---- 4 files changed, 58 insertions(+), 18 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index f8429d7d..16e0d4ca 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -43,6 +43,7 @@ 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 Bitu CPU_AutoDetermineMode; diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 359c43db..1f0be6e3 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.96 2007-01-21 18:14:52 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.97 2007-02-04 11:10:22 qbix79 Exp $ */ #include #include @@ -54,6 +54,7 @@ Bit32s CPU_CyclePercUsed = 100; Bit32s CPU_CycleLimit = -1; Bit32s CPU_CycleUp = 0; Bit32s CPU_CycleDown = 0; +Bit64s CPU_IODelayRemoved = 0; CPU_Decoder * cpudecoder; bool CPU_CycleAutoAdjust; Bitu CPU_AutoDetermineMode; diff --git a/src/dosbox.cpp b/src/dosbox.cpp index c4ae9c41..8a3e7f0e 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.113 2007-01-21 18:14:40 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.114 2007-02-04 11:10:22 qbix79 Exp $ */ #include #include @@ -162,19 +162,37 @@ increaseticks: ticksRemain = 20; } ticksAdded = ticksRemain; - if (CPU_CycleAutoAdjust && (ticksAdded > 15 || ticksScheduled >= 250 || ticksDone >= 250) ) { - /* ratio we are aiming for is around 90% usage*/ - Bits ratio = (ticksScheduled * (CPU_CyclePercUsed*90*1024/100/100)) / ticksDone; -// LOG_MSG("Done %d schedulded %d ratio %d cycles %d", ticksDone, ticksScheduled, ratio, CPU_CycleMax); - if (ratio <= 1024) - CPU_CycleMax = (CPU_CycleMax * ratio) / 1024; - else - CPU_CycleMax = 1 + (CPU_CycleMax >> 1) + (CPU_CycleMax * ratio) / 2048; - if (CPU_CycleLimit>0) { - if (CPU_CycleMax>CPU_CycleLimit) CPU_CycleMax=CPU_CycleLimit; + if (CPU_CycleAutoAdjust) { + if(ticksScheduled >= 250 || ticksDone >= 250 || (ticksAdded > 15 && ticksScheduled >= 5) ) { + /* ratio we are aiming for is around 90% usage*/ + Bits ratio = (ticksScheduled * (CPU_CyclePercUsed*90*1024/100/100)) / ticksDone; + Bit32s new_cmax = CPU_CycleMax; + Bit64s cproc = (Bit64s)CPU_CycleMax * (Bit64s)ticksScheduled; + if(cproc > 0) { + double ratioremoved = (double) CPU_IODelayRemoved / (double) cproc; + if(ratioremoved < 1.0) { + ratio = (Bits)((double)ratio * (1 - ratioremoved)); + if (ratio <= 1024) + new_cmax = (CPU_CycleMax * ratio) / 1024; + else + new_cmax = 1 + (CPU_CycleMax >> 1) + (CPU_CycleMax * ratio) / 2048; + } + } + + // maybe care about not going negative + if (new_cmax > 0) + CPU_CycleMax = new_cmax; + if (CPU_CycleLimit > 0) { + if (CPU_CycleMax>CPU_CycleLimit) CPU_CycleMax = CPU_CycleLimit; + } + CPU_IODelayRemoved = 0; + ticksDone = 0; + ticksScheduled = 0; + } else if (ticksAdded > 15) { + CPU_CycleMax /= 3; + if (CPU_CycleMax < 100) + CPU_CycleMax = 100; } - ticksDone = 0; - ticksScheduled = 0; } } else { ticksAdded = 0; diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index ce1ba9c2..5fc3f19a 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: iohandler.cpp,v 1.24 2007-01-13 10:43:40 qbix79 Exp $ */ +/* $Id: iohandler.cpp,v 1.25 2007-02-04 11:10:22 qbix79 Exp $ */ #include #include "dosbox.h" @@ -167,12 +167,11 @@ static Bits IOFaultCore(void) { * games with their timing of certain operations */ -extern Bit32s CPU_CycleMax; #define IODELAY_READ_MICROS 1.0 #define IODELAY_WRITE_MICROS 0.75 -inline void IO_USEC_read_delay() { +inline void IO_USEC_read_delay_old() { if(CPU_CycleMax > static_cast((IODELAY_READ_MICROS*1000.0))) { // this could be calculated whenever CPU_CycleMax changes Bitu delaycyc = static_cast((CPU_CycleMax/1000)*IODELAY_READ_MICROS); @@ -181,7 +180,7 @@ inline void IO_USEC_read_delay() { } } -inline void IO_USEC_write_delay() { +inline void IO_USEC_write_delay_old() { if(CPU_CycleMax > static_cast((IODELAY_WRITE_MICROS*1000.0))) { // this could be calculated whenever CPU_CycleMax changes Bitu delaycyc = static_cast((CPU_CycleMax/1000)*IODELAY_WRITE_MICROS); @@ -190,6 +189,27 @@ inline void IO_USEC_write_delay() { } } + +#define IODELAY_READ_MICROSk (Bit32u)(1024/1.0) +#define IODELAY_WRITE_MICROSk (Bit32u)(1024/0.75) + +inline void IO_USEC_read_delay() { + Bitu delaycyc = CPU_CycleMax/IODELAY_READ_MICROSk; + if(CPU_Cycles > delaycyc) { + CPU_Cycles -= delaycyc; + CPU_IODelayRemoved += delaycyc; + } else CPU_Cycles = 0; +} + +inline void IO_USEC_write_delay() { + Bitu delaycyc = CPU_CycleMax/IODELAY_WRITE_MICROSk; + if(CPU_Cycles > delaycyc) { + CPU_Cycles -= delaycyc; + CPU_IODelayRemoved += delaycyc; + } else CPU_Cycles = 0; +} + + void IO_WriteB(Bitu port,Bitu val) { if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,1)))) { LazyFlags old_lflags; From 89cc28568b55396e79eb4d8be971cf81bee0aa17 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 4 Feb 2007 11:15:30 +0000 Subject: [PATCH 2718/4131] Beta 3 changes from h-a-l-9000. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2803 --- src/hardware/vga_draw.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 57660d66..be422a8e 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -563,7 +563,8 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.address *= 2; break; } - VGA_DrawPart( vga.draw.parts_lines ); + //VGA_DrawPart( vga.draw.parts_lines ); + PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts,vga.draw.parts_lines); // PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts/2,vga.draw.parts_lines); //Else tearline in Tyrian and second reality } @@ -782,7 +783,7 @@ void VGA_SetupDrawing(Bitu val) { vga.draw.parts_total=VGA_PARTS; double correct_ratio=(100.0/525.0); double aspect_ratio=((double)htotal/((double)vtotal)/correct_ratio); - + vga.draw.delay.parts = vga.draw.delay.vdend/vga.draw.parts_total; vga.draw.resizing=false; //Check to prevent useless black areas From 392818ac532c1ea6a711d9a2c918befbe4d982fe Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 4 Feb 2007 11:16:58 +0000 Subject: [PATCH 2719/4131] update so it is aware of 9x and NT systems Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2804 --- src/libs/zmbv/zmbv.inf | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/libs/zmbv/zmbv.inf b/src/libs/zmbv/zmbv.inf index d1b81c98..736f51db 100644 --- a/src/libs/zmbv/zmbv.inf +++ b/src/libs/zmbv/zmbv.inf @@ -1,21 +1,24 @@ -; -; Zip Motion Block Video AVI codec -; -; Copyright (c) 2000 Ben Rudiak-Gould -; -; This Windows 9x Installation INF File by Rainbow Software -; [version] signature="$CHICAGO$" [DefaultInstall] CopyFiles=ZMBV.Files.Inf,ZMBV.Files.Dll -AddReg=ZMBV.Reg +AddReg=ZMBV.Reg9x +UpdateInis=ZMBV.INIs + +[DefaultInstall.ntx86] +CopyFiles=ZMBV.Files.Inf,ZMBV.Files.Dll +AddReg=ZMBV.RegNT UpdateInis=ZMBV.INIs [DefaultUnInstall] DelFiles=ZMBV.Files.Dll,ZMBV.Files.Inf,ZMBV.Files.Ini -DelReg=ZMBV.Reg +DelReg=ZMBV.Reg9x +UpdateInis=ZMBV.INIs.Del + +[DefaultUnInstall.ntx86] +DelFiles=ZMBV.Files.Dll,ZMBV.Files.Inf,ZMBV.Files.Ini +DelReg=ZMBV.RegNT UpdateInis=ZMBV.INIs.Del [SourceDisksNames] @@ -38,7 +41,7 @@ zmbv.dll [ZMBV.Files.Ini] zmbv.ini -[ZMBV.Reg] +[ZMBV.Reg9x] HKLM,SYSTEM\CurrentControlSet\Control\MediaResources\icm\VIDC.ZMBV,Description,,"Zip Motion Block Video [ZMBV]" HKLM,SYSTEM\CurrentControlSet\Control\MediaResources\icm\VIDC.ZMBV,Driver,,"zmbv.dll" HKLM,SYSTEM\CurrentControlSet\Control\MediaResources\icm\VIDC.ZMBV,FriendlyName,,"Zip Motion Block Video [ZMBV]" @@ -47,8 +50,16 @@ HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,DisplayName,,"Zip Motion Block Video codec (Remove Only)" HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,UninstallString,,"rundll.exe setupx.dll,InstallHinfSection DefaultUninstall 132 %17%\ZMBV.INF" +[ZMBV.RegNT] +HKLM,SOFTWARE\Microsoft\Windows NT\CurrentVersion\drivers.desc,zmbv.dll,,"Zip Motion Block Video [ZMBV]" +HKLM,SOFTWARE\Microsoft\Windows NT\CurrentVersion\drivers32,VIDC.ZMBV,,zmbv.dll + +HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV +HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,DisplayName,,"Zip Motion Block Video codec (Remove Only)" +HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,UninstallString,,"rundll32.exe setupapi,InstallHinfSection DefaultUninstall 132 %17%\ZMBV.INF" + [ZMBV.INIs] system.ini, drivers32,, "VIDC.ZMBV=zmbv.dll" [ZMBV.INIs.Del] -system.ini, drivers32, "VIDC.ZMBV=zmbv.dll" \ No newline at end of file +system.ini, drivers32, "VIDC.ZMBV=zmbv.dll" From 93c278d376d556452819b887836ef1a640082c8c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 4 Feb 2007 11:41:25 +0000 Subject: [PATCH 2720/4131] administrative changes for 66rc1. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2805 --- NEWS | 2 ++ VERSION | 2 +- configure.in | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 705cb4f4..a8d255f3 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +0.66rc1 + - todo 0.65 - Fixed FAT writing. - Added some more missing DOS functions. diff --git a/VERSION b/VERSION index f429be05..4a1a5e6f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.65 +0.66rc1 diff --git a/configure.in b/configure.in index 7028e908..bcb1bb18 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Init. -AC_INIT(dosbox,0.65) +AC_INIT(dosbox,0.66rc1) AC_PREREQ(2.50) AC_CONFIG_SRCDIR(README) From b789d10fc3188e661fda46000424cee2bd36496d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 15 Feb 2007 21:02:04 +0000 Subject: [PATCH 2721/4131] add entries Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2806 --- ChangeLog | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index f97f92f3..559b3939 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,10 +8,14 @@ - 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 strickt 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. @@ -26,6 +30,7 @@ - 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) @@ -37,20 +42,29 @@ 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. - - Make dynamic core handle more types of self modifying code. + - 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. + - 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. - Many timer improvements. - Some pcjr fixes. - Some booter fixes. From 4f5516925d81178d7ca319597bd32ccd0c0eb1fd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Feb 2007 08:30:47 +0000 Subject: [PATCH 2722/4131] Fix 2 memcpy overflows causing stack corruption. (Ludwig) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2807 --- src/hardware/ipx.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index 21fa18cf..ccedba14 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.cpp,v 1.12 2007-01-08 19:45:40 qbix79 Exp $ */ +/* $Id: ipx.cpp,v 1.13 2007-02-22 08:30:47 qbix79 Exp $ */ #include "dosbox.h" @@ -520,7 +520,7 @@ static void pingAck(IPaddress retAddr) { SDLNet_Write16(0x2, regHeader.dest.socket); SDLNet_Write32(0, regHeader.src.network); - memcpy(regHeader.src.addr.byNode.node, localIpxAddr.netnode, sizeof(localIpxAddr)); + memcpy(regHeader.src.addr.byNode.node, localIpxAddr.netnode, sizeof(regHeader.src.addr.byNode.node)); SDLNet_Write16(0x2, regHeader.src.socket); regHeader.transControl = 0; regHeader.pType = 0x0; @@ -547,7 +547,7 @@ static void pingSend(void) { SDLNet_Write16(0x2, regHeader.dest.socket); SDLNet_Write32(0, regHeader.src.network); - memcpy(regHeader.src.addr.byNode.node, localIpxAddr.netnode, sizeof(localIpxAddr)); + memcpy(regHeader.src.addr.byNode.node, localIpxAddr.netnode, sizeof(regHeader.src.addr.byNode.node)); SDLNet_Write16(0x2, regHeader.src.socket); regHeader.transControl = 0; regHeader.pType = 0x0; From 8dbee51bd390a06b7dd2f43db5f1da5e3d34fc53 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Feb 2007 08:32:21 +0000 Subject: [PATCH 2723/4131] Workaround(partly) 16 port acces setting cycles to zero thereby invalidating one of the ports. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2808 --- src/hardware/iohandler.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 5fc3f19a..05fc52fc 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: iohandler.cpp,v 1.25 2007-02-04 11:10:22 qbix79 Exp $ */ +/* $Id: iohandler.cpp,v 1.26 2007-02-22 08:32:21 qbix79 Exp $ */ #include #include "dosbox.h" @@ -195,18 +195,16 @@ inline void IO_USEC_write_delay_old() { inline void IO_USEC_read_delay() { Bitu delaycyc = CPU_CycleMax/IODELAY_READ_MICROSk; - if(CPU_Cycles > delaycyc) { - CPU_Cycles -= delaycyc; - CPU_IODelayRemoved += delaycyc; - } else CPU_Cycles = 0; + if(GCC_UNLIKELY(CPU_Cycles < 3*delaycyc)) delaycyc = 0; //Else port acces will set cycles to 0. which might trigger problem with games which read 16 bit values + CPU_Cycles -= delaycyc; + CPU_IODelayRemoved += delaycyc; } inline void IO_USEC_write_delay() { Bitu delaycyc = CPU_CycleMax/IODELAY_WRITE_MICROSk; - if(CPU_Cycles > delaycyc) { - CPU_Cycles -= delaycyc; - CPU_IODelayRemoved += delaycyc; - } else CPU_Cycles = 0; + if(GCC_UNLIKELY(CPU_Cycles < 3*delaycyc)) delaycyc=0; + CPU_Cycles -= delaycyc; + CPU_IODelayRemoved += delaycyc; } From e24c554ec0de704846fbeea8535717875c47e7dd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Feb 2007 08:33:15 +0000 Subject: [PATCH 2724/4131] Hack for Jurresic (game comparing stuff against interrupt table) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2809 --- src/ints/bios.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 1865691f..13801d9f 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.65 2007-01-13 08:35:49 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.66 2007-02-22 08:33:15 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -816,6 +816,7 @@ public: phys_writeb(0xfff53,0xcf); /* bios default interrupt vector location */ phys_writeb(0xfe987,0xea); /* original IRQ1 location (Defender booter) */ phys_writed(0xfe988,RealGetVec(0x09)); + phys_writew(Real2Phys(RealGetVec(0x12))+0x12,0x20); //Hack for Jurresic if (machine==MCH_TANDY) phys_writeb(0xffffe,0xff) ; /* Tandy model */ else if (machine==MCH_PCJR) phys_writeb(0xffffe,0xfd); /* PCJr model */ From b193341d59bb01d1cb425d9cb5319f0e8ff2bb80 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Feb 2007 08:34:10 +0000 Subject: [PATCH 2725/4131] Hide hercules startup screen. Allow single quotes within double quotes under windows and os2. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2810 --- src/shell/shell.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 72365880..417d1d32 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.83 2007-01-21 16:36:38 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.84 2007-02-22 08:34:10 qbix79 Exp $ */ #include #include @@ -291,12 +291,15 @@ void DOS_Shell::Run(void) { return; } /* Start a normal shell and check for a first command init */ - WriteOut(MSG_Get("SHELL_STARTUP_BEGIN"),VERSION); + if(machine != MCH_HERC) { //Hide it for hercules as that looks too weird + WriteOut(MSG_Get("SHELL_STARTUP_BEGIN"),VERSION); #if C_DEBUG - WriteOut(MSG_Get("SHELL_STARTUP_DEBUG")); + WriteOut(MSG_Get("SHELL_STARTUP_DEBUG")); #endif - if(machine == MCH_CGA) WriteOut(MSG_Get("SHELL_STARTUP_CGA")); - WriteOut(MSG_Get("SHELL_STARTUP_END")); + if(machine == MCH_CGA) WriteOut(MSG_Get("SHELL_STARTUP_CGA")); + WriteOut(MSG_Get("SHELL_STARTUP_END")); + } + if (cmd->FindString("/INIT",line,true)) { strcpy(input_line,line.c_str()); line.erase(); @@ -355,9 +358,14 @@ public: /* Check to see for extra command line options to be added (before the command specified on commandline) */ /* Maximum of extra commands: 10 */ Bitu i = 1; - while (control->cmdline->FindString("-c",line,true) && (i <= 11)) + while (control->cmdline->FindString("-c",line,true) && (i <= 11)) { +#if defined (WIN32) || defined (OS2) + //replace single with double quotes so that mount commands can contain spaces + for(Bitu temp = 0;temp < line.size();++temp) if(line[temp] == '\'') line[temp]='\"'; +#endif //Linux users can simply use \" in their shell autoexec[i++].Install(line); - + } + /* Check for the -exit switch which causes dosbox to when the command on the commandline has finished */ bool addexit = control->cmdline->FindExist("-exit",true); From 12222e680b3e40e7cfdfb2322c47ede613c747f7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Feb 2007 08:35:34 +0000 Subject: [PATCH 2726/4131] No need to use new here (memleak) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2811 --- src/cpu/cpu.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 1f0be6e3..ca92fdf7 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.97 2007-02-04 11:10:22 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.98 2007-02-22 08:35:34 qbix79 Exp $ */ #include #include @@ -2063,16 +2063,16 @@ public: CPU_Cycles=0; std::string str; - CommandLine* cmd = new CommandLine(0,section->Get_string("cycles")); - cmd->FindCommand(1,str); + CommandLine cmd(0,section->Get_string("cycles")); + cmd.FindCommand(1,str); if (str=="max") { CPU_CycleMax=0; CPU_CyclePercUsed=100; CPU_CycleAutoAdjust=true; CPU_CycleLimit=-1; - for (Bitu cmdnum=2; cmdnum<=cmd->GetCount(); cmdnum++) { - if (cmd->FindCommand(cmdnum,str)) { + for (Bitu cmdnum=2; cmdnum<=cmd.GetCount(); cmdnum++) { + if (cmd.FindCommand(cmdnum,str)) { if (str.find('%')==str.length()-1) { str.erase(str.find('%')); int percval=0; @@ -2081,7 +2081,7 @@ public: if ((percval>0) && (percval<=100)) CPU_CyclePercUsed=(Bit32s)percval; } else if (str=="limit") { cmdnum++; - if (cmd->FindCommand(cmdnum,str)) { + if (cmd.FindCommand(cmdnum,str)) { int cyclimit=0; std::istringstream stream(str); stream >> cyclimit; @@ -2096,8 +2096,8 @@ public: CPU_CycleMax=3000; CPU_OldCycleMax=3000; CPU_CyclePercUsed=100; - for (Bitu cmdnum=2; cmdnum<=cmd->GetCount(); cmdnum++) { - if (cmd->FindCommand(cmdnum,str)) { + for (Bitu cmdnum=2; cmdnum<=cmd.GetCount(); cmdnum++) { + if (cmd.FindCommand(cmdnum,str)) { if (str.find('%')==str.length()-1) { str.erase(str.find('%')); int percval=0; @@ -2106,7 +2106,7 @@ public: if ((percval>0) && (percval<=100)) CPU_CyclePercUsed=(Bit32s)percval; } else if (str=="limit") { cmdnum++; - if (cmd->FindCommand(cmdnum,str)) { + if (cmd.FindCommand(cmdnum,str)) { int cyclimit=0; std::istringstream stream(str); stream >> cyclimit; From 6cfc6950c49417e6fd3a8105af8ed6c7c254148a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Feb 2007 08:36:25 +0000 Subject: [PATCH 2727/4131] Fix some bug in readsectors.(prompt) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2812 --- src/dos/cdrom_image.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 1cae4927..7f6a6713 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.14 2007-01-21 16:21:22 c2woody Exp $ */ +/* $Id: cdrom_image.cpp,v 1.15 2007-02-22 08:36:25 qbix79 Exp $ */ #include #include @@ -255,7 +255,7 @@ bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long s bool success = true; //Gobliiins reads 0 sectors for(int i = 0; i < num; i++) { - success = ReadSector(&buf[i * sectorSize], raw, sector); + success = ReadSector(&buf[i * sectorSize], raw, sector + i); if (!success) break; } From 8146e48c4c457f89d18bf37a96c2c7d35d11e4d4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Feb 2007 08:37:12 +0000 Subject: [PATCH 2728/4131] Enable boot to use non-mounted locations as well (for the images) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2813 --- src/dos/dos_programs.cpp | 42 ++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 50d79877..66833a38 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.68 2007-02-01 15:32:19 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.69 2007-02-22 08:37:12 qbix79 Exp $ */ #include #include @@ -358,13 +358,17 @@ extern Bit32u floppytype; class BOOT : public Program { private: - FILE *getFSFile(Bit8u * filename, Bit32u *ksize, Bit32u *bsize,bool tryload=false) { + + FILE *getFSFile_mounted(char const* filename, Bit32u *ksize, Bit32u *bsize, Bit8u *error) { + //if return NULL then put in error the errormessage code if an error was requested + bool tryload = (*error)?true:false; + *error = 0; Bit8u drive; FILE *tmpfile; char fullname[DOS_PATHLENGTH]; localDrive* ldp=0; - if (!DOS_MakeName((char *)filename,fullname,&drive)) return NULL; + if (!DOS_MakeName(const_cast(filename),fullname,&drive)) return NULL; try { ldp=dynamic_cast(Drives[drive]); @@ -372,13 +376,13 @@ private: tmpfile = ldp->GetSystemFilePtr(fullname, "r"); if(tmpfile == NULL) { - if (!tryload) WriteOut(MSG_Get("PROGRAM_BOOT_NOT_EXIST")); + if (!tryload) *error=1; return NULL; } fclose(tmpfile); tmpfile = ldp->GetSystemFilePtr(fullname, "rb+"); if(tmpfile == NULL) { - if (!tryload) WriteOut(MSG_Get("PROGRAM_BOOT_NOT_OPEN")); + if (!tryload) *error=2; return NULL; } @@ -390,7 +394,29 @@ private: catch(...) { return NULL; } - + } + + FILE *getFSFile(char const * filename, Bit32u *ksize, Bit32u *bsize,bool tryload=false) { + Bit8u error = tryload?1:0; + FILE* tmpfile = getFSFile_mounted(filename,ksize,bsize,&error); + if(tmpfile) return tmpfile; + //File not found on mounted filesystem. Try regular filesystem + tmpfile = fopen(filename,"rb+"); + if(!tmpfile) { + if( (tmpfile = fopen(filename,"r")) ) { + //File exists; So can't be opened in correct mode => error 2 + fclose(tmpfile); + if(tryload) error = 2; + } + // Give the delayed errormessages from the mounted variant (or from above) + if(error == 1) WriteOut(MSG_Get("PROGRAM_BOOT_NOT_EXIST")); + if(error == 2) WriteOut(MSG_Get("PROGRAM_BOOT_NOT_OPEN")); + return NULL; + } + fseek(tmpfile,0L, SEEK_END); + *ksize = (ftell(tmpfile) / 1024); + *bsize = ftell(tmpfile); + return tmpfile; } void printError(void) { @@ -464,7 +490,7 @@ public: WriteOut(MSG_Get("PROGRAM_BOOT_IMAGE_OPEN"), temp_line.c_str()); Bit32u rombytesize; - FILE *usefile = getFSFile((Bit8u *)temp_line.c_str(), &floppysize, &rombytesize); + FILE *usefile = getFSFile(temp_line.c_str(), &floppysize, &rombytesize); if(usefile != NULL) { if(diskSwap[i] != NULL) delete diskSwap[i]; diskSwap[i] = new imageDisk(usefile, (Bit8u *)temp_line.c_str(), floppysize, false); @@ -577,7 +603,7 @@ public: if (usefile_1==NULL) return; Bit32u sz1,sz2; - FILE *tfile = getFSFile((Bit8u *)"system.rom", &sz1, &sz2, true); + FILE *tfile = getFSFile("system.rom", &sz1, &sz2, true); if (tfile!=NULL) { fseek(tfile, 0x3000L, SEEK_SET); Bit32u drd=fread(rombuf, 1, 0xb000, tfile); From d0cb27424f2c0b962ee0ed847bc30da2cdd8e3ce Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Feb 2007 08:37:52 +0000 Subject: [PATCH 2729/4131] Improve 16 bit playback. (Srecko) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2814 --- src/hardware/gus.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index e29d4975..0b53a857 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -741,7 +741,7 @@ static void GUS_DMA_Callback(DmaChannel * chan,DMAEvent event) { for(i=dmaaddr;i<(dmaaddr+read);i++) GUSRam[i] ^= 0x80; } else { // 16-bit data - for(i=dmaaddr+1;i<(dmaaddr+read-1);i+=2) GUSRam[i] ^= 0x80; + for(i=dmaaddr+1;i<(dmaaddr+read);i+=2) GUSRam[i] ^= 0x80; } } } else { From 6027e7710fc4974d734ced4683a1f322bb377247 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Feb 2007 08:39:06 +0000 Subject: [PATCH 2730/4131] improve mixer controls a bit. (Srecko) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2815 --- src/hardware/sblaster.cpp | 157 +++++++++++++++++++++++++++----------- 1 file changed, 111 insertions(+), 46 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index be63f8ba..99ddbcac 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.61 2007-01-08 19:59:06 qbix79 Exp $ */ +/* $Id: sblaster.cpp,v 1.62 2007-02-22 08:39:06 qbix79 Exp $ */ #include #include @@ -949,12 +949,12 @@ static void CTMIXER_Reset(void) { CTMIXER_UpdateVolumes(); } -#define SETPROVOL(_WHICH_,_VAL_) \ - _WHICH_[0]= ((sb.type==SBT_16) ? ((_VAL_) & 0x1) :0x1) | (((_VAL_) & 0xf0) >> 3); \ - _WHICH_[1]= ((sb.type==SBT_16) ? (((_VAL_) >> 4) & 0x1) :0x1) | (((_VAL_) & 0x0f) << 1); \ +#define SETPROVOL(_WHICH_,_VAL_) \ + _WHICH_[0]= ((((_VAL_) & 0xf0) >> 3)|(sb.type==SBT_16 ? 1:3)); \ + _WHICH_[1]= ((((_VAL_) & 0x0f) << 1)|(sb.type==SBT_16 ? 1:3)); \ #define MAKEPROVOL(_WHICH_) \ - (((_WHICH_[0] & 0x1e) << 3) | ((_WHICH_[1] & 0x1e) >> 1)) + (((_WHICH_[0] & 0x1e) << 3) | ((_WHICH_[1] & 0x1e) >> 1) & (sb.type==SBT_16 ? 0xff:0xee)) static void DSP_ChangeStereo(bool stereo) { if (!sb.dma.stereo && stereo) { @@ -967,7 +967,7 @@ static void DSP_ChangeStereo(bool stereo) { sb.dma.mul/=2; sb.dma.rate=(sb.freq*sb.dma.mul) >> SB_SH; sb.dma.min=(sb.dma.rate*3)/1000; - } + } sb.dma.stereo=stereo; } @@ -977,25 +977,27 @@ static void CTMIXER_Write(Bit8u val) { CTMIXER_Reset(); LOG(LOG_SB,LOG_WARN)("Mixer reset value %x",val); break; - case 0x02: /* Master Voulme (SBPRO) Obsolete? */ - case 0x22: /* Master Volume (SBPRO) */ - SETPROVOL(sb.mixer.master,val); + case 0x02: /* Master Volume (SB2 Only) */ + SETPROVOL(sb.mixer.master,(val&0xf)|(val<<4)); CTMIXER_UpdateVolumes(); break; case 0x04: /* DAC Volume (SBPRO) */ SETPROVOL(sb.mixer.dac,val); CTMIXER_UpdateVolumes(); break; - case 0x06: /* FM output selection, Somewhat obsolete with dual OPL SBpro */ - //SETPROVOL(sb.mixer.fm,val); + case 0x06: /* FM output selection, Somewhat obsolete with dual OPL SBpro + FM volume (SB2 Only) */ //volume controls both channels - sb.mixer.fm[0]=sb.mixer.fm[1] = 0x1| ((val&0x0f)<<1); + SETPROVOL(sb.mixer.fm,(val&0xf)|(val<<4)); CTMIXER_UpdateVolumes(); if(val&0x60) LOG(LOG_SB,LOG_WARN)("Turned FM one channel off. not implemented %X",val); //TODO Change FM Mode if only 1 fm channel is selected break; - case 0x0a: /* Mic Level */ - sb.mixer.mic=(val & 0xf) << 1; + case 0x08: /* CDA Volume (SB2 Only) */ + SETPROVOL(sb.mixer.cda,(val&0xf)|(val<<4)); + break; + case 0x0a: /* Mic Level (SBPRO) or DAC Volume (SB2): 2-bit, 3-bit on SB16 */ + if (sb.type==SBT_2) sb.mixer.dac[0]=sb.mixer.dac[1]=((val & 0x6) << 2)|3; + else sb.mixer.mic=((val & 0x7) << 2)|(sb.type==SBT_16?1:3); break; case 0x0e: /* Output/Stereo Select */ sb.mixer.stereo=(val & 0x2) > 0; @@ -1003,42 +1005,73 @@ static void CTMIXER_Write(Bit8u val) { DSP_ChangeStereo(sb.mixer.stereo); LOG(LOG_SB,LOG_WARN)("Mixer set to %s",sb.dma.stereo ? "STEREO" : "MONO"); break; + case 0x22: /* Master Volume (SBPRO) */ + SETPROVOL(sb.mixer.master,val); + CTMIXER_UpdateVolumes(); + break; case 0x26: /* FM Volume (SBPRO) */ SETPROVOL(sb.mixer.fm,val); - CTMIXER_UpdateVolumes(); + CTMIXER_UpdateVolumes(); break; case 0x28: /* CD Audio Volume (SBPRO) */ SETPROVOL(sb.mixer.cda,val); break; - case 0x2e: /* Line-IN Volume (SBPRO) */ + case 0x2e: /* Line-in Volume (SBPRO) */ SETPROVOL(sb.mixer.lin,val); break; //case 0x20: /* Master Volume Left (SBPRO) ? */ case 0x30: /* Master Volume Left (SB16) */ - if (sb.type>=SBT_PRO2) { - SETPROVOL(sb.mixer.master,(val&0xf0)|(MAKEPROVOL(sb.mixer.master)&0x0f)); + if (sb.type==SBT_16) { + sb.mixer.master[0]=val>>3; CTMIXER_UpdateVolumes(); } break; //case 0x21: /* Master Volume Right (SBPRO) ? */ - case 0x31: /* Master Volume Right (S16) */ - if (sb.type>=SBT_PRO2) { - SETPROVOL(sb.mixer.master,((val>>4)&0x0f)|(MAKEPROVOL(sb.mixer.master)&0xf0)); + case 0x31: /* Master Volume Right (SB16) */ + if (sb.type==SBT_16) { + sb.mixer.master[1]=val>>3; CTMIXER_UpdateVolumes(); } break; - case 0x32: /* DAC Volume Left (S16) */ - if (sb.type>=SBT_PRO2) { - SETPROVOL(sb.mixer.dac,(val&0xf0)|(MAKEPROVOL(sb.mixer.dac)&0x0f)); + case 0x32: /* DAC Volume Left (SB16) */ + if (sb.type==SBT_16) { + sb.mixer.dac[0]=val>>3; CTMIXER_UpdateVolumes(); } break; - case 0x33: /* DAC Volume Right (S16) */ - if (sb.type>=SBT_PRO2) { - SETPROVOL(sb.mixer.dac,((val>>4)&0x0f)|(MAKEPROVOL(sb.mixer.dac)&0xf0)); + case 0x33: /* DAC Volume Right (SB16) */ + if (sb.type==SBT_16) { + sb.mixer.dac[1]=val>>3; CTMIXER_UpdateVolumes(); } break; + case 0x34: /* FM Volume Left (SB16) */ + if (sb.type==SBT_16) { + sb.mixer.fm[0]=val>>3; + CTMIXER_UpdateVolumes(); + } + break; + case 0x35: /* FM Volume Right (SB16) */ + if (sb.type==SBT_16) { + sb.mixer.fm[1]=val>>3; + CTMIXER_UpdateVolumes(); + } + break; + case 0x36: /* CD Volume Left (SB16) */ + if (sb.type==SBT_16) sb.mixer.cda[0]=val>>3; + break; + case 0x37: /* CD Volume Right (SB16) */ + if (sb.type==SBT_16) sb.mixer.cda[1]=val>>3; + break; + case 0x38: /* Line-in Volume Left (SB16) */ + if (sb.type==SBT_16) sb.mixer.lin[0]=val>>3; + break; + case 0x39: /* Line-in Volume Right (SB16) */ + if (sb.type==SBT_16) sb.mixer.lin[1]=val>>3; + break; + case 0x3a: + if (sb.type==SBT_16) sb.mixer.mic=val>>3; + break; case 0x80: /* IRQ Select */ sb.hw.irq=0xff; if (val & 0x1) sb.hw.irq=2; @@ -1058,28 +1091,33 @@ static void CTMIXER_Write(Bit8u val) { LOG(LOG_SB,LOG_NORMAL)("Mixer select dma8:%x dma16:%x",sb.hw.dma8,sb.hw.dma16); break; default: - if ((sb.type == SBT_2 && sb.mixer.index==0x08) || /* CD volume on SB2 */ - ((sb.type == SBT_PRO1 || sb.type == SBT_PRO2) && sb.mixer.index==0x0c) || /* Input control on SBPro */ - (sb.type == SBT_16 && sb.mixer.index >= 0x30 && sb.mixer.index <= 0x47)) /* New SB16 registers */ + + if( ((sb.type == SBT_PRO1 || sb.type == SBT_PRO2) && sb.mixer.index==0x0c) || /* Input control on SBPro */ + (sb.type == SBT_16 && sb.mixer.index >= 0x3b && sb.mixer.index <= 0x47)) /* New SB16 registers */ sb.mixer.unhandled[sb.mixer.index] = val; LOG(LOG_SB,LOG_WARN)("MIXER:Write %X to unhandled index %X",val,sb.mixer.index); } } - + static Bit8u CTMIXER_Read(void) { Bit8u ret; // if ( sb.mixer.index< 0x80) LOG_MSG("Read mixer %x",sb.mixer.index); switch (sb.mixer.index) { case 0x00: /* RESET */ return 0x00; - case 0x02: /* Master Voulme (SBPRO) Obsolete? */ + case 0x02: /* Master Volume (SB2 Only) */ + return ((sb.mixer.master[1]>>1) & 0xe); case 0x22: /* Master Volume (SBPRO) */ return MAKEPROVOL(sb.mixer.master); case 0x04: /* DAC Volume (SBPRO) */ return MAKEPROVOL(sb.mixer.dac); -// case 0x06: /* FM output selection, Somewhat obsolete with dual OPL SBpro */ - case 0x0a: /* Mic Level (SBPRO) */ - return (sb.mixer.mic >> 1); + case 0x06: /* FM Volume (SB2 Only) + FM output selection */ + return ((sb.mixer.fm[1]>>1) & 0xe); + case 0x08: /* CD Volume (SB2 Only) */ + return ((sb.mixer.cda[1]>>1) & 0xe); + case 0x0a: /* Mic Level (SBPRO) or Voice (SB2 Only) */ + if (sb.type==SBT_2) return (sb.mixer.dac[0]>>2); + else return ((sb.mixer.mic >> 2) & (sb.type==SBT_16 ? 7:6)); case 0x0e: /* Output/Stereo Select */ return 0x11|(sb.mixer.stereo ? 0x02 : 0x00)|(sb.mixer.filtered ? 0x20 : 0x00); case 0x26: /* FM Volume (SBPRO) */ @@ -1089,19 +1127,47 @@ static Bit8u CTMIXER_Read(void) { case 0x2e: /* Line-IN Volume (SBPRO) */ return MAKEPROVOL(sb.mixer.lin); case 0x30: /* Master Volume Left (SB16) */ - if (sb.type>=SBT_PRO2) return sb.mixer.master[0]<<3; + if (sb.type==SBT_16) return sb.mixer.master[0]<<3; ret=0xa; break; case 0x31: /* Master Volume Right (S16) */ - if (sb.type>=SBT_PRO2) return sb.mixer.master[1]<<3; + if (sb.type==SBT_16) return sb.mixer.master[1]<<3; ret=0xa; break; - case 0x32: /* DAC Volume Left (S16) */ - if (sb.type>=SBT_PRO2) return sb.mixer.dac[0]<<3; + case 0x32: /* DAC Volume Left (SB16) */ + if (sb.type==SBT_16) return sb.mixer.dac[0]<<3; ret=0xa; break; - case 0x33: /* DAC Volume Right (S16) */ - if (sb.type>=SBT_PRO2) return sb.mixer.dac[1]<<3; + case 0x33: /* DAC Volume Right (SB16) */ + if (sb.type==SBT_16) return sb.mixer.dac[1]<<3; + ret=0xa; + break; + case 0x34: /* FM Volume Left (SB16) */ + if (sb.type==SBT_16) return sb.mixer.fm[0]<<3; + ret=0xa; + break; + case 0x35: /* FM Volume Right (SB16) */ + if (sb.type==SBT_16) return sb.mixer.fm[1]<<3; + ret=0xa; + break; + case 0x36: /* CD Volume Left (SB16) */ + if (sb.type==SBT_16) return sb.mixer.cda[0]<<3; + ret=0xa; + break; + case 0x37: /* CD Volume Right (SB16) */ + if (sb.type==SBT_16) return sb.mixer.cda[1]<<3; + ret=0xa; + break; + case 0x38: /* Line-in Volume Left (SB16) */ + if (sb.type==SBT_16) return sb.mixer.lin[0]<<3; + ret=0xa; + break; + case 0x39: /* Line-in Volume Right (SB16) */ + if (sb.type==SBT_16) return sb.mixer.lin[1]<<3; + ret=0xa; + break; + case 0x3a: /* Mic Volume (SB16) */ + if (sb.type==SBT_16) return sb.mixer.mic<<3; ret=0xa; break; case 0x80: /* IRQ Select */ @@ -1124,13 +1190,12 @@ static Bit8u CTMIXER_Read(void) { case 7:ret|=0x80;break; } return ret; - case 0x82: + case 0x82: /* IRQ Status */ return (sb.irq.pending_8bit ? 0x1 : 0) | (sb.irq.pending_16bit ? 0x2 : 0); - default: /* IRQ Status */ - if ((sb.type == SBT_2 && sb.mixer.index==0x08) || /* CD volume on SB2 */ - ((sb.type == SBT_PRO1 || sb.type == SBT_PRO2) && sb.mixer.index==0x0c) || /* Input control on SBPro */ - (sb.type == SBT_16 && sb.mixer.index >= 0x30 && sb.mixer.index <= 0x47)) /* New SB16 registers */ + default: + if ( ((sb.type == SBT_PRO1 || sb.type == SBT_PRO2) && sb.mixer.index==0x0c) || /* Input control on SBPro */ + (sb.type == SBT_16 && sb.mixer.index >= 0x3b && sb.mixer.index <= 0x47)) /* New SB16 registers */ ret = sb.mixer.unhandled[sb.mixer.index]; else ret=0xa; From cfa3a9d4668d964a6e935ded7acce89a52f3ae9e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Feb 2007 08:41:16 +0000 Subject: [PATCH 2731/4131] Update os2 serial support(Josch). Add some fixes for Mac OS X. Fix uninitialized variable. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2816 --- src/hardware/serialport/directserial_os2.cpp | 471 +++++++++++-------- src/hardware/serialport/directserial_os2.h | 48 +- src/hardware/serialport/misc_util.cpp | 12 +- src/hardware/serialport/misc_util.h | 2 +- src/hardware/serialport/nullmodem.cpp | 4 +- src/hardware/serialport/nullmodem.h | 10 +- src/hardware/serialport/serialport.cpp | 4 +- 7 files changed, 327 insertions(+), 224 deletions(-) diff --git a/src/hardware/serialport/directserial_os2.cpp b/src/hardware/serialport/directserial_os2.cpp index d48eee51..4bf88921 100644 --- a/src/hardware/serialport/directserial_os2.cpp +++ b/src/hardware/serialport/directserial_os2.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_os2.cpp,v 1.3 2007-01-08 19:45:40 qbix79 Exp $ */ +/* $Id: directserial_os2.cpp,v 1.4 2007-02-22 08:41:16 qbix79 Exp $ */ #include "dosbox.h" @@ -26,6 +26,8 @@ #if defined(OS2) #include "serialport.h" #include "directserial_os2.h" +#include "misc_util.h" +#include "pic.h" // OS/2 related headers #define INCL_DOSFILEMGR @@ -38,24 +40,46 @@ /* This is a serial passthrough class. Its amazingly simple to */ /* write now that the serial ports themselves were abstracted out */ -CDirectSerial::CDirectSerial (IO_ReadHandler * rh, IO_WriteHandler * wh, - TIMER_TickHandler th, Bit16u baseAddr, Bit8u initIrq, - Bit32u initBps, Bit8u bytesize, const char *parity, - Bit8u stopbits,const char *realPort) - :CSerial (rh, wh, th,baseAddr,initIrq, initBps, - bytesize, parity,stopbits) { +CDirectSerial::CDirectSerial (Bitu id, CommandLine *cmd) + : CSerial(id, cmd) { InstallationSuccessful = false; - InstallTimerHandler(th); - lastChance = 0; - LOG_MSG ("OS/2 Serial port at %x: Opening %s", base, realPort); - LOG_MSG("Opening OS2 serial port"); + + + rx_retry = 0; + rx_retry_max = 0; + + std::string tmpstring; + + if (!cmd->FindStringBegin("realport:", tmpstring, false)) + { + return; + } +#if SERIAL_DEBUG + if (dbg_modemcontrol) + { + fprintf(debugfp, "%12.3f Port type directserial realport %s\r\n", PIC_FullIndex(), tmpstring.c_str()); + } +#endif + + + // rxdelay: How many milliseconds to wait before causing an + // overflow when the application is unresponsive. + if(getBituSubstring("rxdelay:", &rx_retry_max, cmd)) { + if(!(rx_retry_max<=10000)) { + rx_retry_max=0; + } + } + + const char* tmpchar=tmpstring.c_str(); + + LOG_MSG ("Serial%d: Opening %s", COMNUMBER, tmpstring.c_str()); ULONG ulAction = 0; - APIRET rc = DosOpen((unsigned char*)realPort, &hCom, &ulAction, 0L, FILE_NORMAL, FILE_OPEN, + APIRET rc = DosOpen((unsigned char*)tmpstring.c_str(), &hCom, &ulAction, 0L, FILE_NORMAL, FILE_OPEN, OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | OPEN_FLAGS_SEQUENTIAL, 0L); if (rc != NO_ERROR) { - LOG_MSG ("Serial port \"%s\" could not be opened.", realPort); + LOG_MSG ("Serial%d: Serial port \"%s\" could not be opened.", COMNUMBER, tmpstring.c_str()); if (rc == 2) { LOG_MSG ("The specified port does not exist."); } else if (rc == 99) { @@ -73,135 +97,125 @@ CDirectSerial::CDirectSerial (IO_ReadHandler * rh, IO_WriteHandler * wh, rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &dcb, ulParmLen, &ulParmLen); if ( rc != NO_ERROR) { - DosClose(hCom); - hCom = 0; - return; - } - dcb.usWriteTimeout = 0; - dcb.usReadTimeout = 0; //65535; - dcb.fbTimeout |= 6; - rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0); - if ( rc != NO_ERROR) - { + LOG_MSG("GetCommState failed with error %d.\n", rc); DosClose(hCom); hCom = 0; return; } - CSerial::Init_Registers (initBps, bytesize, parity, stopbits); - InstallationSuccessful = true; - //LOG_MSG("InstSuccess"); + dcb.usWriteTimeout = 0; + dcb.usReadTimeout = 0; //65535; + dcb.fbCtlHndShake = dcb.fbFlowReplace = 0; + dcb.fbTimeout = 6; + rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0); + if ( rc != NO_ERROR) + { + LOG_MSG("SetDCBInfo failed with error %d.\n", rc); + DosClose(hCom); + hCom = 0; + return; + } + + + struct { + ULONG baud; + BYTE fraction; + } setbaud; + setbaud.baud = 9600; + setbaud.fraction = 0; + ulParmLen = sizeof(setbaud); + rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_EXTSETBAUDRATE, &setbaud, ulParmLen, &ulParmLen, 0, 0, 0); + if (rc != NO_ERROR) + { + LOG_MSG("ExtSetBaudrate failed with error %d.\n", rc); + DosClose (hCom); + hCom = 0; + return; } + struct { + UCHAR data; + UCHAR parity; + UCHAR stop; + } paramline; + + // byte length + paramline.data = 8; + paramline.parity = 0; + paramline.stop = 0; + ulParmLen = sizeof(paramline); + rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETLINECTRL, ¶mline, ulParmLen, &ulParmLen, 0, 0, 0); + if ( rc != NO_ERROR) + { + LOG_MSG ("SetLineCtrl failed with error %d.\n", rc); + } + + CSerial::Init_Registers(); + InstallationSuccessful = true; + receiveblock = false; + + // Clears comm errors + USHORT errors = 0; + ulParmLen = sizeof(errors); + DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMERROR, 0, 0, 0, &errors, ulParmLen, &ulParmLen); + setEvent(SERIAL_POLLING_EVENT, 1); + } + CDirectSerial::~CDirectSerial () { if (hCom != 0) DosClose (hCom); } -Bitu lastChance; -void CDirectSerial::RXBufferEmpty () { - ULONG dwRead; - Bit8u chRead; - USHORT errors = 0; - ULONG ulParmLen = sizeof(errors); - - if (lastChance > 0) { - receiveByte (ChanceChar); - lastChance = 0; - } else { - // update RX - if (DosRead (hCom, &chRead, 1, &dwRead) != NO_ERROR) { - if (dwRead != 0) { - //LOG_MSG("UART 0x%x: RX 0x%x", base,chRead); - receiveByte (chRead); - } - } - } - // check for errors - Bit8u errreg = 0; - APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMERROR, 0, 0, 0, &errors, ulParmLen, &ulParmLen); - if (rc != NO_ERROR && errors) - { - if (errors & 8) { - LOG_MSG ("Serial port at 0x%x: line error: framing error.", base); - errreg |= LSR_FRAMING_ERROR_MASK; - } - if (errors & 4) { - LOG_MSG ("Serial port at 0x%x: line error: parity error.", base); - errreg |= LSR_PARITY_ERROR_MASK; - } - } - errors = 0; - rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMEVENT, 0, 0, 0, &errors, ulParmLen, &ulParmLen); - if (rc != NO_ERROR && errors) - { - if (errors & 6) { - LOG_MSG ("Serial port at 0x%x: line error: break received.", base); - errreg |= LSR_RX_BREAK_MASK; - } - } - if (errreg != 0) - { - receiveError (errreg); - } - -} /*****************************************************************************/ /* updatePortConfig is called when emulated app changes the serial port **/ /* parameters baudrate, stopbits, number of databits, parity. **/ /*****************************************************************************/ -void CDirectSerial::updatePortConfig (Bit8u dll, Bit8u dlm, Bit8u lcr) { +void CDirectSerial::updatePortConfig (Bit16u divider, Bit8u lcr) { Bit8u parity = 0; Bit8u bytelength = 0; - Bit16u baudrate = 0, baud = 0; - - // baud - baudrate = dlm; - baudrate = baudrate << 8; - baudrate |= dll; - if (baudrate <= 0x1) - baud = 115200; - else if (baudrate <= 0x2) - baud = 57600; - else if (baudrate <= 0x3) - baud = 38400; - else if (baudrate <= 0x6) - baud = 19200; - else if (baudrate <= 0xc) - baud = 9600; - else if (baudrate <= 0x18) - baud = 4800; - else if (baudrate <= 0x30) - baud = 2400; - else if (baudrate <= 0x60) - baud = 1200; - else if (baudrate <= 0xc0) - baud = 600; - else if (baudrate <= 0x180) - baud = 300; - else if (baudrate <= 0x417) - baud = 110; - - // I read that windows can handle nonstandard baudrates: - else - baud = 115200 / baudrate; - -#ifdef SERIALPORT_DEBUGMSG - LOG_MSG ("Serial port at %x: new baud rate: %d", base, dcb.BaudRate); -#endif - struct { ULONG baud; BYTE fraction; } setbaud; - setbaud.baud = baud; + + // baud + if (divider <= 0x1) + setbaud.baud = 115200; + else if (divider <= 0x2) + setbaud.baud = 57600; + else if (divider <= 0x3) + setbaud.baud = 38400; + else if (divider <= 0x6) + setbaud.baud = 19200; + else if (divider <= 0xc) + setbaud.baud = 9600; + else if (divider <= 0x18) + setbaud.baud = 4800; + else if (divider <= 0x30) + setbaud.baud = 2400; + else if (divider <= 0x60) + setbaud.baud = 1200; + else if (divider <= 0xc0) + setbaud.baud = 600; + else if (divider <= 0x180) + setbaud.baud = 300; + else if (divider <= 0x417) + setbaud.baud = 110; + + // I read that windows can handle nonstandard baudrates: + else + setbaud.baud = 115200 / divider; + + setbaud.fraction = 0; ULONG ulParmLen = sizeof(setbaud); APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_EXTSETBAUDRATE, &setbaud, ulParmLen, &ulParmLen, 0, 0, 0); if (rc != NO_ERROR) { + LOG_MSG("Serial%d: Desired serial mode not supported (Baud: %d, %d, Error: %d)", + COMNUMBER, setbaud.baud, divider, rc); } @@ -248,12 +262,28 @@ void CDirectSerial::updatePortConfig (Bit8u dll, Bit8u dlm, Bit8u lcr) { } +#ifdef SERIAL_DEBUG + LOG_MSG("_____________________________________________________"); + LOG_MSG("Serial%d, new baud rate: %d", COMNUMBER, setbaud.baud); + LOG_MSG("Serial%d: new bytelen: %d", COMNUMBER, paramline.data); + LOG_MSG("Serial%d: new parity: %d", COMNUMBER, paramline.parity); + LOG_MSG("Serial%d: new stopbits: %d", COMNUMBER, paramline.stop); +#endif + ulParmLen = sizeof(paramline); rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETLINECTRL, ¶mline, ulParmLen, &ulParmLen, 0, 0, 0); if ( rc != NO_ERROR) { - LOG_MSG ("Serial port at 0x%x: API did not like the new values.", base); +#ifdef SERIAL_DEBUG + if (dbg_modemcontrol) + { + fprintf(debugfp, "%12.3f serial mode not supported: rate=%d, LCR=%x.\r\n", PIC_FullIndex(), setbaud.baud, lcr); } +#endif + LOG_MSG("Serial%d: Desired serial mode not supported (%d,%d,%d,%d)", + COMNUMBER, setbaud.baud, paramline.data, paramline.parity, lcr); + } + } @@ -262,33 +292,29 @@ void CDirectSerial::updateMSR () { UCHAR dptr = 0; ULONG ulParmLen = sizeof(dptr); - APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETMODEMINPUT, &dptr, ulParmLen, &ulParmLen, 0, 0, 0); + APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETMODEMINPUT, 0, 0, 0, &dptr, ulParmLen, &ulParmLen); if (rc != NO_ERROR) { -#ifdef SERIALPORT_DEBUGMSG -// LOG_MSG ("Serial port at %x: GetCommModemStatus failed!", base); -#endif - //return; + LOG_MSG ("Serial port at %x: GetModemInput failed with %d !", idnumber, dptr); } - if (dptr & 16) - newmsr |= MSR_CTS_MASK; - if (dptr & 32) - newmsr |= MSR_DSR_MASK; - if (dptr & 64) - newmsr |= MSR_RI_MASK; - if (dptr & 128) - newmsr |= MSR_CD_MASK; - changeMSR (newmsr); + setCTS( (dptr & 16) != 0); + setDSR( (dptr & 32) != 0); + setRI( (dptr & 64) != 0); + setCD( (dptr & 128) != 0); } -void CDirectSerial::transmitByte (Bit8u val) { - // mean bug: with break = 1, WriteFile will never return. +void CDirectSerial::transmitByte (Bit8u val, bool first) { ULONG bytesWritten = 0; APIRET rc = DosWrite (hCom, &val, 1, &bytesWritten); if (rc == NO_ERROR && bytesWritten > 0) { - ByteTransmitted (); //LOG_MSG("UART 0x%x: TX 0x%x", base,val); } else { - LOG_MSG ("UART 0x%x: NO BYTE WRITTEN!", base); + LOG_MSG ("Serial%d: NO BYTE WRITTEN!", idnumber); + } + if (first) + { + setEvent(SERIAL_THR_EVENT, bytetime / 8); + } else { + setEvent(SERIAL_TX_EVENT, bytetime); } } @@ -297,9 +323,6 @@ void CDirectSerial::transmitByte (Bit8u val) { /*****************************************************************************/ void CDirectSerial::setBreak (bool value) { - //#ifdef SERIALPORT_DEBUGMSG - //LOG_MSG("UART 0x%x: Break toggeled: %d", base, value); - //#endif USHORT error; ULONG ulParmLen = sizeof(error); if (value) @@ -311,7 +334,8 @@ void CDirectSerial::setBreak (bool value) { /*****************************************************************************/ /* updateModemControlLines(mcr) sets DTR and RTS. **/ /*****************************************************************************/ -void CDirectSerial::updateModemControlLines ( /*Bit8u mcr */ ) { +void CDirectSerial::setRTSDTR(bool rts, bool dtr) +{ bool change = false; DCBINFO dcb; ULONG ulParmLen = sizeof(dcb); @@ -319,7 +343,7 @@ void CDirectSerial::updateModemControlLines ( /*Bit8u mcr */ ) { DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &dcb, ulParmLen, &ulParmLen); /*** DTR ***/ - if (CSerial::getDTR ()) { // DTR on + if (dtr) { // DTR on if (dcb.fbCtlHndShake && 3 == 0) { // DTR disabled dcb.fbCtlHndShake |= 1; change = true; @@ -331,7 +355,7 @@ void CDirectSerial::updateModemControlLines ( /*Bit8u mcr */ ) { } } /*** RTS ***/ - if (CSerial::getRTS ()) { // RTS on + if (rts) { // RTS on if (dcb.fbFlowReplace && 192 == 0) { //RTS disabled dcb.fbFlowReplace |= 64; change = true; @@ -346,72 +370,145 @@ void CDirectSerial::updateModemControlLines ( /*Bit8u mcr */ ) { DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0); } -void CDirectSerial::Timer2(void) { - ULONG dwRead = 0; - USHORT errors = 0; - Bit8u chRead = 0; - ULONG ulParmLen = sizeof(errors); +void CDirectSerial::setRTS(bool val) +{ + bool change = false; + DCBINFO dcb; + ULONG ulParmLen = sizeof(dcb); + DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &dcb, ulParmLen, &ulParmLen); - if (lastChance == 0) { // lastChance = 0 - if (CanReceiveByte ()) { - if (DosRead (hCom, &chRead, 1, &dwRead)) { - if (dwRead) - receiveByte (chRead); + /*** RTS ***/ + if (val) { // RTS on + if (dcb.fbFlowReplace && 192 == 0) { //RTS disabled + dcb.fbFlowReplace |= 64; + change = true; } } else { - if (DosRead (hCom, &chRead, 1, &dwRead)) { - if (dwRead) { - ChanceChar = chRead; - lastChance++; + if (dcb.fbFlowReplace && 192 == 1) { // RTS enabled + dcb.fbFlowReplace &= ~192; + change = true; } } + if (change) + DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0); } - } else if (lastChance > 10) { - receiveByte (0); // this causes RX Overrun now - lastChance = 0; - // empty serial buffer - dwRead = 1; - while (dwRead > 0) { // throw away bytes in buffer - DosRead (hCom, &chRead, 1, &dwRead); + +void CDirectSerial::setDTR(bool val) +{ + bool change = false; + DCBINFO dcb; + ULONG ulParmLen = sizeof(dcb); + + DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &dcb, ulParmLen, &ulParmLen); + + /*** DTR ***/ + if (val) { // DTR on + if (dcb.fbCtlHndShake && 3 == 0) { // DTR disabled + dcb.fbCtlHndShake |= 1; + change = true; } - } else { // lastChance>0 // already one waiting - if (CanReceiveByte ()) { // chance used - receiveByte (ChanceChar); - lastChance = 0; - } else - lastChance++; + } else { + if (dcb.fbCtlHndShake && 3 == 1) { // DTR enabled + dcb.fbCtlHndShake &= ~3; + change = true; + } + } + if (change) + DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0); } - // check for errors - Bit8u errreg = 0; - APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMERROR, 0, 0, 0, &errors, ulParmLen, &ulParmLen); - if (rc != NO_ERROR && errors) + +void CDirectSerial::handleUpperEvent(Bit16u type) { - if (errors & 8) { - LOG_MSG ("Serial port at 0x%x: line error: framing error.", base); - errreg |= LSR_FRAMING_ERROR_MASK; + switch(type) { + case SERIAL_POLLING_EVENT: { + ULONG dwRead = 0; + ULONG errors = 0; + Bit8u chRead = 0; + + setEvent(SERIAL_POLLING_EVENT, 1); + if(!receiveblock) { + if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )) + { + rx_retry=0; + if (DosRead (hCom, &chRead, 1, &dwRead) == NO_ERROR) { + if (dwRead) { + receiveByte (chRead); + setEvent(40, bytetime-0.03f); // receive timing + receiveblock=true; } - if (errors & 4) { - LOG_MSG ("Serial port at 0x%x: line error: parity error.", base); - errreg |= LSR_PARITY_ERROR_MASK; + } + } else rx_retry++; + } + // check for errors + CheckErrors(); + // update Modem input line states + updateMSR (); + break; + } + case 40: { + // receive time is up + ULONG dwRead = 0; + Bit8u chRead = 0; + receiveblock=false; + // check if there is something to receive + if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )) + { + rx_retry=0; + if (DosRead (hCom, &chRead, 1, &dwRead) == NO_ERROR) { + if (dwRead) { + receiveByte (chRead); + setEvent(40, bytetime-0.03f); // receive timing + receiveblock=true; + } + } + } else rx_retry++; + break; + } + case SERIAL_TX_EVENT: { + ULONG dwRead = 0; + Bit8u chRead = 0; + if(!receiveblock) { + if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )) + { + rx_retry=0; + if (DosRead (hCom, &chRead, 1, &dwRead) == NO_ERROR) { + if (dwRead) { + receiveByte (chRead); + setEvent(40, bytetime-0.03f); // receive timing + receiveblock=true; + } + } + } else rx_retry++; + } + ByteTransmitted(); + break; + } + case SERIAL_THR_EVENT: { + ByteTransmitting(); + setEvent(SERIAL_TX_EVENT,bytetime+0.03f); + break; } } - errors = 0; - rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMEVENT, 0, 0, 0, &errors, ulParmLen, &ulParmLen); - if (rc != NO_ERROR && errors) - { - if (errors & 6) { - LOG_MSG ("Serial port at 0x%x: line error: break received.", base); - errreg |= LSR_RX_BREAK_MASK; + +} + +void CDirectSerial::CheckErrors() { + + USHORT errors = 0, event = 0; + ULONG ulParmLen = sizeof(errors); + DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMEVENT, 0, 0, 0, &event, ulParmLen, &ulParmLen); + if (event & (64 + 128) ) { // Break (Bit 6) or Frame or Parity (Bit 7) error + Bit8u errreg = 0; + if (event & 64) errreg |= LSR_RX_BREAK_MASK; + if (event & 128) { + DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMERROR, 0, 0, 0, &errors, ulParmLen, &ulParmLen); + if (errors & 8) errreg |= LSR_FRAMING_ERROR_MASK; + if (errors & 4) errreg |= LSR_PARITY_ERROR_MASK; } - } - if (errreg != 0) - { receiveError (errreg); } - // update Modem input line states - updateMSR (); } #endif diff --git a/src/hardware/serialport/directserial_os2.h b/src/hardware/serialport/directserial_os2.h index 53385938..99e4d1d1 100644 --- a/src/hardware/serialport/directserial_os2.h +++ b/src/hardware/serialport/directserial_os2.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_os2.h,v 1.3 2007-01-08 19:45:40 qbix79 Exp $ */ +/* $Id: directserial_os2.h,v 1.4 2007-02-22 08:41:16 qbix79 Exp $ */ // include guard #ifndef DOSBOX_DIRECTSERIAL_OS2_H @@ -40,42 +40,38 @@ public: HFILE hCom; BOOL fSuccess; - CDirectSerial( - IO_ReadHandler* rh, - IO_WriteHandler* wh, - TIMER_TickHandler th, - Bit16u baseAddr, - Bit8u initIrq, - Bit32u initBps, - Bit8u bytesize, - const char *parity, - Bit8u stopbits, - const char * realPort - ); - - + CDirectSerial(Bitu id, CommandLine* cmd); ~CDirectSerial(); - Bitu lastChance; // If there is no space for new + //Bitu lastChance; // If there is no space for new // received data, it gets a little chance - Bit8u ChanceChar; + //Bit8u ChanceChar; - bool CanRecv(void); - bool CanSend(void); + //bool CanRecv(void); + //bool CanSend(void); - bool InstallationSuccessful; // check after constructing. If - // something was wrong, delete it right away. - void RXBufferEmpty(); + //void RXBufferEmpty(); + bool receiveblock; + Bitu rx_retry; + Bitu rx_retry_max; + void CheckErrors(); - void updatePortConfig(Bit8u dll, Bit8u dlm, Bit8u lcr); + void updatePortConfig(Bit16u divider, Bit8u lcr); void updateMSR(); - void transmitByte(Bit8u val); + void transmitByte(Bit8u val, bool first); void setBreak(bool value); - void updateModemControlLines(/*Bit8u mcr*/); - void Timer2(void); + + void setRTSDTR(bool rts, bool dtr); + void setRTS(bool val); + void setDTR(bool val); + void handleUpperEvent(Bit16u type); + + + //void updateModemControlLines(/*Bit8u mcr*/); + //void Timer2(void); }; diff --git a/src/hardware/serialport/misc_util.cpp b/src/hardware/serialport/misc_util.cpp index e32841d4..5b999719 100644 --- a/src/hardware/serialport/misc_util.cpp +++ b/src/hardware/serialport/misc_util.cpp @@ -6,8 +6,11 @@ // C++ SDLnet wrapper // Socket inheritance -#ifdef LINUX +#if defined LINUX || defined OS2 #define CAPWORD (NETWRAPPER_TCP|NETWRAPPER_TCP_NATIVESOCKET) +#ifdef OS2 +typedef int socklen_t; +#endif #include #include #include @@ -18,6 +21,13 @@ #include typedef int socklen_t; +#elif defined __APPLE__ +#define CAPWORD (NETWRAPPER_TCP|NETWRAPPER_TCP_NATIVESOCKET) +#include +#include +#include +#define SOCKET socklen_t + #else #define CAPWORD NETWRAPPER_TCP #endif diff --git a/src/hardware/serialport/misc_util.h b/src/hardware/serialport/misc_util.h index 0c0122f1..9b89ac18 100644 --- a/src/hardware/serialport/misc_util.h +++ b/src/hardware/serialport/misc_util.h @@ -6,7 +6,7 @@ #include "SDL_net.h" #include "support.h" -#ifdef LINUX +#if defined LINUX || defined OS2 #define NATIVESOCKETS #elif defined WIN32 diff --git a/src/hardware/serialport/nullmodem.cpp b/src/hardware/serialport/nullmodem.cpp index 7f8cb47b..c0ca3f35 100644 --- a/src/hardware/serialport/nullmodem.cpp +++ b/src/hardware/serialport/nullmodem.cpp @@ -34,7 +34,7 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) { clientport = 0; rx_retry = 0; - rx_retry_max = 100; + rx_retry_max = 100; tx_gather = 12; @@ -99,7 +99,7 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) { // custom connect Bit8u peernamebuf[16]; LOG_MSG("inheritance port: %d",sock); - clientsocket = new TCPClientSocket(sock); + clientsocket = new TCPClientSocket(sock); if(!clientsocket->isopen) { LOG_MSG("Serial%d: Connection failed.",COMNUMBER); delete clientsocket; diff --git a/src/hardware/serialport/nullmodem.h b/src/hardware/serialport/nullmodem.h index 226e1182..419b3681 100644 --- a/src/hardware/serialport/nullmodem.h +++ b/src/hardware/serialport/nullmodem.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: nullmodem.h,v 1.1 2007-01-13 08:35:49 qbix79 Exp $ */ +/* $Id: nullmodem.h,v 1.2 2007-02-22 08:41:16 qbix79 Exp $ */ // include guard #ifndef DOSBOX_NULLMODEM_WIN32_H @@ -29,10 +29,10 @@ #include "misc_util.h" #include "serialport.h" -#define SERIAL_SERVER_POLLING_EVENT SERIAL_BASE_EVENT_COUNT+1 -#define SERIAL_TX_REDUCTION SERIAL_BASE_EVENT_COUNT+2 -#define SERIAL_NULLMODEM_DTR_EVENT SERIAL_BASE_EVENT_COUNT+3 -#define SERIAL_NULLMODEM_EVENT_COUNT SERIAL_BASE_EVENT_COUNT+ 3 +#define SERIAL_SERVER_POLLING_EVENT SERIAL_BASE_EVENT_COUNT+1 +#define SERIAL_TX_REDUCTION SERIAL_BASE_EVENT_COUNT+2 +#define SERIAL_NULLMODEM_DTR_EVENT SERIAL_BASE_EVENT_COUNT+3 +#define SERIAL_NULLMODEM_EVENT_COUNT SERIAL_BASE_EVENT_COUNT+3 class CNullModem : public CSerial { public: diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index 1f5b27df..e535ed0f 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.cpp,v 1.6 2007-01-13 08:35:49 qbix79 Exp $ */ +/* $Id: serialport.cpp,v 1.7 2007-02-22 08:41:16 qbix79 Exp $ */ #include #include @@ -950,7 +950,7 @@ void CSerial::Init_Registers () { ISR = 0x1; LCR = 0; //MCR = 0xff; - loopback; + loopback = true; dtr=true; rts=true; op1=true; From c392dcfc90cf08f50c3a51c2896217f7b85df501 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Feb 2007 08:44:07 +0000 Subject: [PATCH 2732/4131] Add new option: buttonwrap. For people who like to map a lot of keys to their joystick. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2817 --- include/joystick.h | 3 ++- src/dosbox.cpp | 8 +++++--- src/gui/sdl_mapper.cpp | 28 +++++++++++++++++----------- src/hardware/joystick.cpp | 4 +++- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/include/joystick.h b/include/joystick.h index 0afef907..d590250f 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: joystick.h,v 1.10 2007-01-10 15:00:38 c2woody Exp $ */ +/* $Id: joystick.h,v 1.11 2007-02-22 08:44:06 qbix79 Exp $ */ #ifndef DOSBOX_JOYSTICK_H #define DOSBOX_JOYSTICK_H void JOYSTICK_Enable(Bitu which,bool enabled); @@ -45,4 +45,5 @@ enum JoystickType { }; extern JoystickType joytype; +extern bool button_wrapping_enabled; #endif diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 8a3e7f0e..ced21783 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.114 2007-02-04 11:10:22 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.115 2007-02-22 08:44:06 qbix79 Exp $ */ #include #include @@ -311,14 +311,14 @@ void DOSBOX_Init(void) { secprop->Add_int("cycleup",500); secprop->Add_int("cycledown",20); MSG_Add("CPU_CONFIGFILE_HELP", - "core -- CPU Core used in emulation: normal" + "core -- CPU Core used in emulation: normal,simple" #if (C_DYNAMIC_X86) ",dynamic,auto.\n" " auto switches from normal to dynamic if appropriate" #endif ".\n" "cycles -- Amount of instructions dosbox tries to emulate each millisecond.\n" - " Setting this higher than your machine can handle is bad!\n" + " Setting this value too high results in sound dropouts and lags.\n" " You can also let DOSBox guess the correct value by setting it to max.\n" " The default setting (auto) switches to max if appropriate.\n" "cycleup -- Amount of cycles to increase/decrease with keycombo.\n" @@ -433,6 +433,7 @@ void DOSBOX_Init(void) { "timed -- enable timed intervals for axis. (false is old style behaviour).\n" "autofire -- continuously fires as long as you keep the button pressed.\n" "swap34 -- swap the 3rd and the 4th axis. can be useful for certain joysticks.\n" + "buttonwrap -- enable button wrapping at the number of emulated buttons.\n" ); secprop->AddInitFunction(&INT10_Init); @@ -442,6 +443,7 @@ void DOSBOX_Init(void) { secprop->Add_bool("timed",true); secprop->Add_bool("autofire",false); secprop->Add_bool("swap34",false); + secprop->Add_bool("buttonwrap",true); // had to rename these to serial due to conflicts in config secprop=control->AddSection_prop("serial",&SERIAL_Init,true); diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index f915de2c..58b7da48 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.31 2007-01-11 09:51:37 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.32 2007-02-22 08:44:07 qbix79 Exp $ */ #include #include @@ -608,7 +608,7 @@ public: emulated_buttons=2; pos_axis_lists=new CBindList[4]; neg_axis_lists=new CBindList[4]; - button_lists=new CBindList[6]; + button_lists=new CBindList[16]; hat_lists=new CBindList[4]; Bitu i; for (i=0; i<16; i++) { @@ -634,6 +634,9 @@ public: axes=SDL_JoystickNumAxes(sdl_joystick); buttons=SDL_JoystickNumButtons(sdl_joystick); hats=SDL_JoystickNumHats(sdl_joystick); + button_wrap=buttons; + if (button_wrapping_enabled) button_wrap=emulated_buttons; + if (button_wrap>16) button_wrap=16; LOG_MSG("Using joystick %s with %d axes and %d buttons",SDL_JoystickName(stick),axes,buttons); } ~CStickBindGroup() { @@ -673,7 +676,7 @@ public: } else if (event->type==SDL_JOYBUTTONDOWN) { if (event->button.which!=stick) return 0; #if defined (REDUCE_JOYSTICK_POLLING) - return CreateButtonBind(event->jbutton.button%emulated_buttons); + return CreateButtonBind(event->jbutton.button%button_wrap); #else return CreateButtonBind(event->jbutton.button); #endif @@ -724,7 +727,7 @@ public: for (i=0; i<16; i++) button_pressed[i]=false; for (i=0; i #include "dosbox.h" @@ -47,6 +47,7 @@ static JoyStick stick[2]; static Bit32u last_write = 0; static bool write_active = false; static bool swap34 = false; +bool button_wrapping_enabled = true; extern bool autofire; //sdl_mapper.cpp @@ -214,6 +215,7 @@ public: } autofire = section->Get_bool("autofire"); swap34 = section->Get_bool("swap34"); + button_wrapping_enabled = section->Get_bool("buttonwrap"); stick[0].enabled = false; stick[1].enabled = false; stick[0].xtick = stick[0].ytick = stick[1].xtick = From 34ccfaec462159524c050a42af14c974008728f0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Feb 2007 08:45:14 +0000 Subject: [PATCH 2733/4131] Add writemap. Fixes stonekeep in dynamic core. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2818 --- src/cpu/core_dyn_x86/cache.h | 25 ++++++++++++++++++++-- src/cpu/core_dyn_x86/decoder.h | 39 +++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index ce3f2556..7fe2965e 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -15,6 +15,9 @@ public: Bit8u * start; //Where in the cache are we Bitu size; CacheBlock * next; + Bit8u * wmapmask; + Bit16u maskstart; + Bit16u masklen; } cache; struct { Bitu index; @@ -222,8 +225,22 @@ public: //Will crash if a block isn't found, which should never happen. } *where=block->hash.next; - for (Bitu i=block->page.start;i<=block->page.end;i++) { - if (write_map[i]) write_map[i]--; + if (GCC_UNLIKELY(block->cache.wmapmask!=NULL)) { + for (Bitu i=block->page.start;icache.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) { @@ -324,6 +341,10 @@ void CacheBlock::Clear(void) { page.handler->DelCacheBlock(this); page.handler=0; } + if (cache.wmapmask){ + free(cache.wmapmask); + cache.wmapmask=NULL; + } } diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index caec4c29..ba03a074 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -140,11 +140,43 @@ static Bit32u decode_fetchd(void) { return mem_readd(decode.code-4); } +#define START_WMMEM 64 + +static void INLINE decode_increase_wmapmask(Bitu size) { + Bitu mapidx; + CacheBlock* activecb=decode.active_block; + if (GCC_UNLIKELY(!activecb->cache.wmapmask)) { + activecb->cache.wmapmask=(Bit8u*)malloc(START_WMMEM); + memset(activecb->cache.wmapmask,0,START_WMMEM); + activecb->cache.maskstart=decode.page.index; + activecb->cache.masklen=START_WMMEM; + mapidx=0; + } else { + mapidx=decode.page.index-activecb->cache.maskstart; + if (GCC_UNLIKELY(mapidx+size>=activecb->cache.masklen)) { + Bitu newmasklen=activecb->cache.masklen*4; + if (newmasklencache.wmapmask,activecb->cache.masklen); + free(activecb->cache.wmapmask); + activecb->cache.wmapmask=tempmem; + activecb->cache.masklen=newmasklen; + } + } + switch (size) { + case 1 : activecb->cache.wmapmask[mapidx]+=0x01; break; + case 2 : (*(Bit16u*)&activecb->cache.wmapmask[mapidx])+=0x0101; break; + case 4 : (*(Bit32u*)&activecb->cache.wmapmask[mapidx])+=0x01010101; break; + } +} + static bool decode_fetchb_imm(Bitu & val) { if (decode.page.index<4096) { Bitu index=(decode.code>>12); if (paging.tlb.read[index]) { val=(Bitu)(paging.tlb.read[index]+decode.code); + decode_increase_wmapmask(1); decode.code++; decode.page.index++; return true; @@ -158,6 +190,7 @@ static bool decode_fetchw_imm(Bitu & val) { Bitu index=(decode.code>>12); if (paging.tlb.read[index]) { val=(Bitu)(paging.tlb.read[index]+decode.code); + decode_increase_wmapmask(2); decode.code+=2; decode.page.index+=2; return true; @@ -171,6 +204,7 @@ static bool decode_fetchd_imm(Bitu & val) { Bitu index=(decode.code>>12); if (paging.tlb.read[index]) { val=(Bitu)(paging.tlb.read[index]+decode.code); + decode_increase_wmapmask(4); decode.code+=4; decode.page.index+=4; return true; @@ -1919,7 +1953,10 @@ restart_prefix: if (!decode.page.invmap) opcode=decode_fetchb(); else { if (decode.page.index<4096) { - if (GCC_UNLIKELY(decode.page.invmap[decode.page.index]>=4)) goto illegalopcode; + if (GCC_UNLIKELY(decode.page.invmap[decode.page.index]>=4)) { + decode.page.index++; + goto illegalopcode; + } opcode=decode_fetchb(); } else { opcode=decode_fetchb(); From a32707e4e1b7847a19bd07d5db57ebcb4d635221 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Feb 2007 08:47:45 +0000 Subject: [PATCH 2734/4131] Change the video card timing a bit. Fix a few bugs related to the palette registers. Fix pel_panning. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2819 --- src/hardware/vga_attr.cpp | 7 +++++-- src/hardware/vga_dac.cpp | 7 +++---- src/hardware/vga_draw.cpp | 42 ++++++++++++++++++++++++++------------- 3 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 0ca6b54f..3a0e3f90 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -23,10 +23,13 @@ #define attr(blah) vga.attr.blah void VGA_ATTR_SetPalette(Bit8u index,Bit8u val) { - if (vga.attr.mode_control & 0x80) val=(val&0xf) | (vga.attr.color_select << 4); - else val=(val & 63) | (vga.attr.color_select & 0xc) << 4; + vga.attr.palette[index] = val; + if (vga.attr.mode_control & 0x80) val = (val&0xf) | (vga.attr.color_select << 4); + val &= 63; + val |= (vga.attr.color_select & 0xc) << 4; VGA_DAC_CombineColor(index,val); } + Bitu read_p3c0(Bitu port,Bitu iolen) { //Wcharts return 0x0; diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index 980e0654..9aee8848 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -125,7 +125,7 @@ static void write_p3c9(Bitu port,Bitu val,Bitu iolen) { default: /* Check for attributes and DAC entry link */ for (Bitu i=0;i<16;i++) { - if (vga.attr.palette[i]==vga.dac.write_index) { + if (vga.dac.combine[i]==vga.dac.write_index) { RENDER_SetPal(i, vga.dac.rgb[vga.dac.write_index].red << 2, vga.dac.rgb[vga.dac.write_index].green << 2, @@ -167,11 +167,10 @@ static Bitu read_p3c9(Bitu port,Bitu iolen) { void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal) { /* Check if this is a new color */ - vga.attr.palette[attr]=pal; + vga.dac.combine[attr]=pal; switch (vga.mode) { case M_VGA: case M_LIN8: - case M_LIN16: break; default: RENDER_SetPal(attr, @@ -188,7 +187,7 @@ void VGA_DAC_SetEntry(Bitu entry,Bit8u red,Bit8u green,Bit8u blue) { vga.dac.rgb[entry].green=green; vga.dac.rgb[entry].blue=blue; for (Bitu i=0;i<16;i++) - if (vga.attr.palette[i]==entry) + if (vga.dac.combine[i]==entry) RENDER_SetPal(i,red << 2,green << 2,blue << 2); } diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index be422a8e..6a79b16d 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -145,10 +145,17 @@ static Bit8u * VGA_Draw_Changes_Line(Bitu vidstart, Bitu line) { Bitu checkMask = vga.changes.checkMask; Bit8u *map = vga.changes.map; Bitu start = (vidstart >> VGA_CHANGE_SHIFT); - Bitu end = ((vidstart + vga.changes.lineWidth ) >> VGA_CHANGE_SHIFT); + Bitu end = ((vidstart + vga.draw.line_length ) >> VGA_CHANGE_SHIFT); for (; start <= end;start++) { if ( map[start] & checkMask ) { - return &vga.draw.linear_base[ vidstart & vga.draw.linear_mask ]; + Bit8u *ret = &vga.draw.linear_base[ vidstart & vga.draw.linear_mask ]; +#if !defined(C_UNALIGNED_MEMORY) + if (GCC_UNLIKELY( ((Bitu)ret) & (sizeof(Bitu)-1)) ) { + memcpy( TempLine, ret, vga.draw.line_length ); + return TempLine; + } +#endif + return ret; } } // memset( TempLine, 0x30, vga.changes.lineWidth ); @@ -159,7 +166,14 @@ static Bit8u * VGA_Draw_Changes_Line(Bitu vidstart, Bitu line) { #endif static Bit8u * VGA_Draw_Linear_Line(Bitu vidstart, Bitu line) { - return &vga.draw.linear_base[ vidstart & vga.draw.linear_mask ]; + Bit8u *ret = &vga.draw.linear_base[ vidstart & vga.draw.linear_mask ]; +#if !defined(C_UNALIGNED_MEMORY) + if (GCC_UNLIKELY( ((Bitu)ret) & (sizeof(Bitu)-1)) ) { + memcpy( TempLine, ret, vga.draw.line_length ); + return TempLine; + } +#endif + return ret; } //Test version, might as well keep it @@ -436,7 +450,7 @@ static void VGA_DrawPart(Bitu lines) { #endif vga.draw.address=0; if(!(vga.attr.mode_control&0x20)) - vga.draw.address += vga.draw.panning; + vga.draw.address += vga.config.pel_panning; vga.draw.address_line=0; #ifdef VGA_KEEP_CHANGES vga.changes.start = vga.draw.address >> VGA_CHANGE_SHIFT; @@ -499,7 +513,8 @@ static void VGA_VerticalTimer(Bitu val) { error = vga.draw.delay.framestart - error - vga.draw.delay.vtotal; // if (abs(error) > 0.001 ) // LOG_MSG("vgaerror: %f",error); - PIC_AddEvent(VGA_VerticalTimer, (float)vga.draw.delay.vtotal ); + PIC_AddEvent( VGA_VerticalTimer, (float)vga.draw.delay.vtotal ); + PIC_AddEvent( VGA_VerticalDisplayEnd, (float)vga.draw.delay.vrstart ); if ( GCC_UNLIKELY( vga.draw.parts_left )) { LOG(LOG_VGAMISC,LOG_NORMAL)( "Parts left: %d", vga.draw.parts_left ); PIC_RemoveEvents( &VGA_DrawPart ); @@ -510,11 +525,12 @@ static void VGA_VerticalTimer(Bitu val) { if (!RENDER_StartUpdate()) return; //TODO Maybe check for an active frame on parts_left and clear that first? - vga.draw.parts_left=vga.draw.parts_total; - vga.draw.lines_done=0; - vga.draw.address=vga.config.display_start; - vga.draw.address_line=vga.config.hlines_skip; - vga.draw.split_line=(vga.config.line_compare/vga.draw.lines_scaled); + vga.draw.parts_left = vga.draw.parts_total; + vga.draw.lines_done = 0; +// vga.draw.address=vga.config.display_start; + vga.draw.address = vga.config.real_start; + vga.draw.address_line = vga.config.hlines_skip; + vga.draw.split_line = (vga.config.line_compare/vga.draw.lines_scaled); switch (vga.mode) { case M_EGA: case M_LIN4: @@ -543,8 +559,7 @@ static void VGA_VerticalTimer(Bitu val) { #endif break; case M_TEXT: - vga.draw.address *= 2; - vga.draw.panning = vga.config.pel_panning; + vga.draw.address = vga.config.display_start * 2; case M_TANDY_TEXT: case M_HERC_TEXT: vga.draw.cursor.address=vga.config.cursor_start*2; @@ -944,10 +959,9 @@ void VGA_SetupDrawing(Bitu val) { } vga.draw.lines_total=height; vga.draw.parts_lines=vga.draw.lines_total/vga.draw.parts_total; - + vga.draw.line_length = width * ((bpp + 1) / 8); #ifdef VGA_KEEP_CHANGES vga.changes.active = false; - vga.changes.lineWidth = width * ((bpp + 1) / 8); vga.changes.frame = 0; vga.changes.writeMask = 1; #endif From 03837aa491743493523c6e8208a079791ddda5c0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Feb 2007 08:48:19 +0000 Subject: [PATCH 2735/4131] commit the header as well Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2820 --- include/vga.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/vga.h b/include/vga.h index 0c6fb456..07736551 100644 --- a/include/vga.h +++ b/include/vga.h @@ -106,13 +106,11 @@ typedef struct { Bitu width; Bitu height; Bitu blocks; - Bitu panning; Bitu address; Bit8u *linear_base; Bitu linear_mask; - Bitu address_mask; - Bitu address_last; Bitu address_add; + Bitu line_length; Bitu address_line_total; Bitu address_line; Bitu lines_total; @@ -316,6 +314,7 @@ typedef struct { Bit8u write_index; Bit8u read_index; Bitu first_changed; + Bit8u combine[16]; RGBEntry rgb[0x100]; } VGA_Dac; @@ -338,7 +337,6 @@ typedef struct { Bit8u map[(VGA_MEMORY >> VGA_CHANGE_SHIFT) + 32]; Bit8u checkMask, frame, writeMask; bool active; - Bit32u lineWidth; Bit32u clearMask; Bit32u start, last; Bit32u lastAddress; From ef7ce0307f5b17eaab1d719c5d51871a549ace1f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Feb 2007 08:49:02 +0000 Subject: [PATCH 2736/4131] Documentation update. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2821 --- README | 53 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/README b/README index 8e0e5fd6..94af7305 100644 --- a/README +++ b/README @@ -24,7 +24,7 @@ INDEX: 6. Mapper 7. Keyboard Layout 8. Serial Multiplayer feature -9. To run resource-demanding games +9. How to run resource-demanding games 10. The config file 11. The language file 12. Building your own version of DOSBox @@ -49,6 +49,7 @@ Q: I've got a Z instead of a C at the prompt. Q: How do I change to fullscreen ? Q: My CD-ROM doesn't work. Q: The mouse doesn't work. +Q: There is no sound. Q: The sound stutters or sounds stretched/weird. Q: I can't type \ or : in DOSBox. Q: The game/application can't find its CD-ROM. @@ -106,10 +107,26 @@ A: Usually, DOSBox detects when a game uses mouse control. When you click on you will have to lock the mouse manually by pressing CTRL-F10. +Q: There is no sound. +A: Be sure that the sound is correctly configured in the game. This might be + done during the installation or with a setup/setsound utility that + accompanies the game. First see if an autodetection option is provided. If + there is none try selecting soundblaster or soundblaster16 with the default + settings being "address=220 irq=7 dma=1". You might also want to select + midi at address 330 as music device. + The parameters of the emulated soundcards can be changed in the DOSBox + configuration file. + If you still don't get any sound set the core to normal and use some lower + fixed cycles value (like cycles=2000). Also assure that your host operating + sound does provide sound. + + Q: The sound stutters or sounds stretched/weird. A: You're using too much cpu power to keep DOSBox running at the current speed. You can lower the cycles, skip frames or get a faster machine. You can also increase the prebuffer in the configfile. + If you are using cycles=max or =auto, then make sure that there no + background processes interfering! (especially if they acces the harddisk) Q: I can't type \ or : in DOSBox. @@ -124,6 +141,8 @@ A: This is a known problem. It only occurs if your keyboard layout isn't US. 7. for \ try the keys around "enter". For ":" try shift and the keys between "enter" and "l" (US keyboard layout). 8. Try keyb.com from FreeDOS (http://projects.freedos.net/keyb/). + Look for keyb2.0 pre4 as older and newer versions are known to + have a bug in the loader routines. Q: The game/application can't find its CD-ROM. @@ -137,7 +156,8 @@ A: Be sure to mount the CD-ROM with -t cdrom switch, this will enable the Q: The game/application runs much too slow! -A: Look at the section "To run resource-demanding games" for more information. +A: Look at the section "How to run resource-demanding games" for more + information. Q: Can DOSBox harm my computer? @@ -243,14 +263,14 @@ dosbox -version -conf configfile Start DOSBox with the options specified in "configfile". Multiple -conf options may be present. - See Chapter 9 for more details. + See Chapter 10 for more details. -lang languagefile Start DOSBox using the language specified in "languagefile". -noconsole (Windows Only) Start DOSBox without showing the console window. Output will - be redirected to stdout.txt and stderr.txt + be redirected to stdout.txt and stderr.txt -machine machinetype Setup DOSBox to emulate a specific type of machine. Valid choices are: @@ -269,7 +289,13 @@ dosbox -version Note: If a name/command/configfile/languagefile contains a space, put the whole name/command/configfile/languagefile between quotes - ("command or file name"). + ("command or file name"). If you need to use quotes within quotes + (most likely with -c and mount). + Windows and OS/2 users can use single quotes inside the double quotes. + Other people should be able to use escaped double quotes inside the + double quotes. + win -c "mount c 'c:\program files\'" + linux -c "mount c \"/tmp/name with space\"" For example: @@ -911,9 +937,9 @@ Example: Be a server listening on TCP port 5000. -=================================== -9. To run resource-demanding games: -=================================== +======================================= +9. How to run resource-demanding games: +======================================= DOSBox emulates the CPU, the sound and graphic cards, and other peripherals of a PC, all at the same time. The speed of an emulated DOS application @@ -962,6 +988,17 @@ Also try to close every program but DOSBox to reserve as much resources as possible for DOSBox. +Advanced cycles configuration: +The cycles=auto and cycles=max settings can be parametrized to have +different startup defaults. The syntax is + cycles= auto ["realmode default"] ["protected mode default"%] + [limit "cycle limit"] + cycles=max ["protected mode default"%] [limit "cycle limit"] +Example: + cycles=auto 1000 80% limit 20000 + will use cycles=1000 for real mode games, 80% cpu throttling for + protected mode games along with a hard cycles limit of 20000 + ==================== From 260fd8e719bf43a7d3aa1644ecc377716d45931f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Feb 2007 08:49:36 +0000 Subject: [PATCH 2737/4131] We are on release candidate 3. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2822 --- NEWS | 2 +- VERSION | 2 +- configure.in | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index a8d255f3..db8d856e 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -0.66rc1 +0.66rc3 - todo 0.65 - Fixed FAT writing. diff --git a/VERSION b/VERSION index 4a1a5e6f..069e28e3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.66rc1 +0.66rc3 diff --git a/configure.in b/configure.in index bcb1bb18..d76b6228 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Init. -AC_INIT(dosbox,0.66rc1) +AC_INIT(dosbox,0.66rc3) AC_PREREQ(2.50) AC_CONFIG_SRCDIR(README) From 3e591eb615872c81b702c6b81a85ff5a3e7430b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 22 Feb 2007 15:12:48 +0000 Subject: [PATCH 2738/4131] initialize variable in dummy case Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2823 --- src/gui/sdl_mapper.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 58b7da48..6c15ed2a 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.32 2007-02-22 08:44:07 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.33 2007-02-22 15:12:48 c2woody Exp $ */ #include #include @@ -600,6 +600,7 @@ public: if (_dummy) { sdl_joystick=NULL; axes=0; buttons=0; hats=0; + button_wrap=16; return; } From fd916a72a8304184fd5416190f17f8d8ccccbb99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 22 Feb 2007 15:15:00 +0000 Subject: [PATCH 2739/4131] update VS project file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2824 --- visualc_net/dosbox.vcproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 5512e72f..9c7bef85 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -39,7 +39,7 @@ Name="VCCustomBuildTool"/> Date: Sat, 24 Feb 2007 21:07:22 +0000 Subject: [PATCH 2740/4131] fix operator priority Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2825 --- src/hardware/sblaster.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 99ddbcac..e1a2fb47 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.62 2007-02-22 08:39:06 qbix79 Exp $ */ +/* $Id: sblaster.cpp,v 1.63 2007-02-24 21:07:22 c2woody Exp $ */ #include #include @@ -954,7 +954,7 @@ static void CTMIXER_Reset(void) { _WHICH_[1]= ((((_VAL_) & 0x0f) << 1)|(sb.type==SBT_16 ? 1:3)); \ #define MAKEPROVOL(_WHICH_) \ - (((_WHICH_[0] & 0x1e) << 3) | ((_WHICH_[1] & 0x1e) >> 1) & (sb.type==SBT_16 ? 0xff:0xee)) + ((((_WHICH_[0] & 0x1e) << 3) | ((_WHICH_[1] & 0x1e) >> 1)) & (sb.type==SBT_16 ? 0xff:0xee)) static void DSP_ChangeStereo(bool stereo) { if (!sb.dma.stereo && stereo) { From 0280c7ee4cae3c7f385a30f28d642d5dcc659f6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 25 Feb 2007 18:38:00 +0000 Subject: [PATCH 2741/4131] fix some special keys inside the debugger under windows (thanks etil); fix debug.exe argument handling (thanks efry); correct condjump target prediction display of the debugger Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2826 --- src/debug/debug.cpp | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 9b85ed02..5ab20652 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.84 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.85 2007-02-25 18:38:00 c2woody Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -1402,7 +1402,7 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) case 'A' : { jmp = (get_CF()?false:true) && (get_ZF()?false:true); // JA } break; case 'B' : { if (instu[2] == 'E') { - jmp = (get_CF()?true:false) && (get_ZF()?true:false); // JBE + jmp = (get_CF()?true:false) || (get_ZF()?true:false); // JBE } else { jmp = get_CF()?true:false; // JB } @@ -1416,15 +1416,15 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) case 'E' : { jmp = get_ZF()?true:false; // JE } break; case 'G' : { if (instu[2] == 'E') { - jmp = get_SF()?false:true; // JGE + jmp = (get_SF()?true:false)==(get_OF()?true:false); // JGE } else { - jmp = (get_SF()?false:true) && (get_ZF()?false:true); // JG + jmp = (get_ZF()?false:true) && ((get_SF()?true:false)==(get_OF()?true:false)); // JG } } break; case 'L' : { if (instu[2] == 'E') { - jmp = (get_SF()?true:false) || (get_ZF()?true:false) ; // JLE + jmp = (get_ZF()?true:false) || ((get_SF()?true:false)!=(get_OF()?true:false)); // JLE } else { - jmp = get_SF()?true:false; // JL + jmp = (get_SF()?true:false)!=(get_OF()?true:false); // JL } } break; case 'M' : { jmp = true; // JMP @@ -1445,7 +1445,7 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) } break; } } break; - case 'O' : { jmp = get_OF()?true:false; // JMP + case 'O' : { jmp = get_OF()?true:false; // JO } break; case 'P' : { if (instu[2] == 'O') { jmp = get_PF()?false:true; // JPO @@ -1477,6 +1477,25 @@ Bit32u DEBUG_CheckKeys(void) { Bits ret=0; int key=getch(); if (key>0) { +#if defined(WIN32) && defined(__PDCURSES__) + switch (key) { + case ALT_D: + if (ungetch('D') != ERR) key=27; + break; + case ALT_E: + if (ungetch('E') != ERR) key=27; + break; + case ALT_X: + if (ungetch('X') != ERR) key=27; + break; + case ALT_B: + if (ungetch('B') != ERR) key=27; + break; + case ALT_S: + if (ungetch('S') != ERR) key=27; + break; + } +#endif switch (toupper(key)) { case 27: // escape (a bit slow): Clears line. and processes alt commands. key=getch(); @@ -1846,11 +1865,10 @@ public: Bit16u i =2; bool ok = false; args[0] = 0; - do { - ok = cmd->FindCommand(i++,temp_line); + for (;cmd->FindCommand(i++,temp_line)==true;) { strncat(args,temp_line.c_str(),256); strncat(args," ",256); - } while (ok); + } // Start new shell and execute prog active = true; // Save cpu state.... From 2d4ce67ff8308e82b7b272886f4c8e2d951572a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 26 Feb 2007 16:59:16 +0000 Subject: [PATCH 2742/4131] fix dc blocklength Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2827 --- src/cpu/core_dyn_x86/decoder.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index ba03a074..9bdf8514 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1953,10 +1953,7 @@ restart_prefix: if (!decode.page.invmap) opcode=decode_fetchb(); else { if (decode.page.index<4096) { - if (GCC_UNLIKELY(decode.page.invmap[decode.page.index]>=4)) { - decode.page.index++; - goto illegalopcode; - } + if (GCC_UNLIKELY(decode.page.invmap[decode.page.index]>=4)) goto illegalopcode; opcode=decode_fetchb(); } else { opcode=decode_fetchb(); From 486d5ca7a832dcd742b483f41dfe9ae053dcafeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 27 Feb 2007 19:48:46 +0000 Subject: [PATCH 2743/4131] fully ignore screen-off bit (fixes Darklands, Skyroads3d) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2828 --- src/hardware/vga_seq.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 63de93da..6ca66344 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -40,7 +40,9 @@ void write_p3c5(Bitu port,Bitu val,Bitu iolen) { case 1: /* Clocking Mode */ if (val!=seq(clocking_mode)) { seq(clocking_mode)=val; - VGA_StartResize(); + // don't resize if only the screen off bit was changed + if ((val&(~0x20))!=(seq(clocking_mode)&(~0x20))) + VGA_StartResize(); } /* TODO Figure this out :) 0 If set character clocks are 8 dots wide, else 9. From 889a641cb701ec7abf901abd29ebbec55544e3d9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 Mar 2007 09:51:24 +0000 Subject: [PATCH 2744/4131] Remove visual C project files. (outdated and buggy code) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2829 --- visualc/Makefile.am | 1 - visualc/dosbox.dsp | 779 -------------------------------------------- visualc/dosbox.dsw | 29 -- 3 files changed, 809 deletions(-) delete mode 100644 visualc/Makefile.am delete mode 100644 visualc/dosbox.dsp delete mode 100644 visualc/dosbox.dsw diff --git a/visualc/Makefile.am b/visualc/Makefile.am deleted file mode 100644 index f484b932..00000000 --- a/visualc/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -EXTRA_DIST = dosbox.dsw dosbox.dsp \ No newline at end of file diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp deleted file mode 100644 index 306f9f76..00000000 --- a/visualc/dosbox.dsp +++ /dev/null @@ -1,779 +0,0 @@ -# Microsoft Developer Studio Project File - Name="dosbox" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=dosbox - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "dosbox.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "dosbox.mak" CFG="dosbox - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "dosbox - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "dosbox - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "dosbox - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /G6 /MD /W3 /GX /O1 /Op /Ob2 /I "../include" /I "../src/platform/visualc" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FAs /FR /FD /QxMi /bQipo /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 winmm.lib zlib.lib libpng.lib sdl_net.lib sdlmain.lib sdl.lib curses.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "dosbox - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../include" /I "../src/platform/visualc" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c -# SUBTRACT CPP /YX /Yc /Yu -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 sdl_net.lib winmm.lib zlib.lib libpng.lib sdlmain.lib sdl.lib curses.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "dosbox - Win32 Release" -# Name "dosbox - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Group "cpu" - -# PROP Default_Filter "" -# Begin Group "core_full" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\src\cpu\core_full\ea_lookup.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_full\load.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_full\loadwrite.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_full\main.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_full\op.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_full\optable.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_full\save.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_full\string.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_full\support.h -# End Source File -# End Group -# Begin Group "core_normal" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\src\cpu\core_normal\helpers.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_normal\prefix_0f.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_normal\prefix_66.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_normal\prefix_66_0f.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_normal\prefix_none.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_normal\string.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_normal\support.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_normal\table_ea.h -# End Source File -# End Group -# Begin Source File - -SOURCE=..\src\cpu\callback.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_full.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\core_normal.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\cpu.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\flags.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\instructions.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\lazyflags.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\modrm.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\modrm.h -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\paging.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\cpu\slow_16.cpp -# End Source File -# End Group -# Begin Group "debug" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\src\debug\debug.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\debug\debug_disasm.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\debug\debug_gui.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\debug\debug_inc.h -# End Source File -# Begin Source File - -SOURCE=..\src\debug\debug_win32.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\debug\disasm_tables.h -# End Source File -# End Group -# Begin Group "dos" - -# PROP Default_Filter "" -# Begin Group "devices" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\src\dos\dev_con.h -# End Source File -# End Group -# Begin Group "drives" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\src\dos\drive_cache.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\dos\drive_local.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\dos\drive_virtual.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\dos\drives.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\dos\drives.h -# End Source File -# End Group -# Begin Source File - -SOURCE=..\src\dos\cdrom.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\dos\cdrom.h -# End Source File -# Begin Source File - -SOURCE=..\src\dos\cdrom_aspi_win32.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\dos\cdrom_ioctl_win32.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\dos\dos.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\dos\dos_classes.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\dos\dos_devices.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\dos\dos_execute.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\dos\dos_files.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\dos\dos_ioctl.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\dos\dos_memory.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\dos\dos_misc.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\dos\dos_mscdex.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\dos\dos_programs.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\dos\dos_tables.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\dos\scsidefs.h -# End Source File -# Begin Source File - -SOURCE=..\src\dos\wnaspi32.h -# End Source File -# End Group -# Begin Group "gui" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\src\gui\midi.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\gui\midi_win32.h -# End Source File -# Begin Source File - -SOURCE=..\src\gui\render.cpp -# End Source File -# Begin Source File - -SOURCE=..\include\render.h -# End Source File -# Begin Source File - -SOURCE=..\src\gui\render_normal.h -# End Source File -# Begin Source File - -SOURCE=..\src\gui\render_scale2x.h -# End Source File -# Begin Source File - -SOURCE=..\src\gui\sdlmain.cpp -# End Source File -# Begin Source File - -SOURCE=..\include\video.h -# End Source File -# End Group -# Begin Group "hardware" - -# PROP Default_Filter "" -# Begin Group "vga" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\src\hardware\vga.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\vga.h -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\vga_attr.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\vga_crtc.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\vga_dac.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\vga_draw.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\vga_gfx.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\vga_memory.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\vga_misc.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\vga_seq.cpp -# End Source File -# End Group -# Begin Source File - -SOURCE=..\src\hardware\adlib.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\cmos.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\disney.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\dma.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\gameblaster.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\gus.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\hardware.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\iohandler.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\joystick.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\keyboard.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\memory.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\mixer.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\mpu401.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\pcspeaker.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\pic.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\sblaster.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\serialport.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\softmodem.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\tandy_sound.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\hardware\timer.cpp -# End Source File -# End Group -# Begin Group "ints" - -# PROP Default_Filter "" -# Begin Group "int10" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\src\ints\int10.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\ints\int10.h -# End Source File -# Begin Source File - -SOURCE=..\src\ints\int10_char.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\ints\int10_memory.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\ints\int10_misc.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\ints\int10_modes.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\ints\int10_pal.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\ints\int10_put_pixel.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\ints\int10_vesa.cpp -# End Source File -# End Group -# Begin Source File - -SOURCE=..\src\ints\bios.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\ints\bios_disk.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\ints\bios_keyboard.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\ints\dpmi.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\ints\ems.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\ints\mouse.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\ints\xms.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\ints\xms.h -# End Source File -# End Group -# Begin Group "misc" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\src\misc\messages.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\misc\programs.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\misc\setup.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\misc\support.cpp -# End Source File -# End Group -# Begin Group "shell" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\src\shell\shell.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\shell\shell_batch.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\shell\shell_cmds.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\shell\shell_inc.h -# End Source File -# Begin Source File - -SOURCE=..\src\shell\shell_misc.cpp -# End Source File -# End Group -# Begin Group "fpu" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\src\fpu\fpu.cpp -# End Source File -# Begin Source File - -SOURCE=..\src\fpu\fpu_instructions.h -# End Source File -# Begin Source File - -SOURCE=..\src\fpu\fpu_instructions_x86.h -# End Source File -# Begin Source File - -SOURCE=..\src\fpu\fpu_types.h -# End Source File -# End Group -# Begin Group "visualc" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\src\platform\visualc\config.h -# End Source File -# Begin Source File - -SOURCE=..\src\platform\visualc\dirent.c -# End Source File -# Begin Source File - -SOURCE=..\src\platform\visualc\dirent.h -# End Source File -# Begin Source File - -SOURCE=..\src\platform\visualc\unistd.h -# End Source File -# End Group -# Begin Source File - -SOURCE=..\src\dosbox.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\include\bios.h -# End Source File -# Begin Source File - -SOURCE=..\include\callback.h -# End Source File -# Begin Source File - -SOURCE=..\include\cpu.h -# End Source File -# Begin Source File - -SOURCE=..\include\cross.h -# End Source File -# Begin Source File - -SOURCE=..\include\debug.h -# End Source File -# Begin Source File - -SOURCE=..\include\dma.h -# End Source File -# Begin Source File - -SOURCE=..\include\dos_inc.h -# End Source File -# Begin Source File - -SOURCE=..\include\dos_system.h -# End Source File -# Begin Source File - -SOURCE=..\include\dosbox.h -# End Source File -# Begin Source File - -SOURCE=..\include\fpu.h -# End Source File -# Begin Source File - -SOURCE=..\include\hardware.h -# End Source File -# Begin Source File - -SOURCE=..\include\inout.h -# End Source File -# Begin Source File - -SOURCE=..\include\joystick.h -# End Source File -# Begin Source File - -SOURCE=..\include\keyboard.h -# End Source File -# Begin Source File - -SOURCE=..\include\logging.h -# End Source File -# Begin Source File - -SOURCE=..\include\mem.h -# End Source File -# Begin Source File - -SOURCE=..\include\mixer.h -# End Source File -# Begin Source File - -SOURCE=..\include\mouse.h -# End Source File -# Begin Source File - -SOURCE=..\include\paging.h -# End Source File -# Begin Source File - -SOURCE=..\include\pic.h -# End Source File -# Begin Source File - -SOURCE=..\include\programs.h -# End Source File -# Begin Source File - -SOURCE=..\include\regs.h -# End Source File -# Begin Source File - -SOURCE=..\include\setup.h -# End Source File -# Begin Source File - -SOURCE=..\include\support.h -# End Source File -# Begin Source File - -SOURCE=..\include\timer.h -# End Source File -# End Group -# End Target -# End Project diff --git a/visualc/dosbox.dsw b/visualc/dosbox.dsw deleted file mode 100644 index a17f1ddd..00000000 --- a/visualc/dosbox.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "dosbox"=".\dosbox.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - From f48a969a9f31b035b47372f75af2d3daa24f3a16 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 Mar 2007 10:21:44 +0000 Subject: [PATCH 2745/4131] 0.70 administrative changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2830 --- ChangeLog | 12 ++++- Makefile.am | 2 +- NEWS | 82 +++++++++++++++++++++++++++++++++- README | 83 ++++++++++++++++++++++++++--------- THANKS | 4 ++ VERSION | 2 +- configure.in | 3 +- scripts/dosbox-installer.nsi | 2 +- src/platform/visualc/config.h | 2 +- 9 files changed, 161 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 559b3939..35738962 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,10 +1,10 @@ -0.66 +0.70 - Improve register handling and support with XMS. - Fix some issues with deleting open files.(windows only issue) - Add dummpy 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 as some sort of detection thing) + 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. @@ -65,6 +65,14 @@ - 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. diff --git a/Makefile.am b/Makefile.am index 6376bf3a..31fcda10 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ # Main Makefile for DOSBox EXTRA_DIST = autogen.sh -SUBDIRS = src include visualc docs visualc_net +SUBDIRS = src include docs visualc_net diff --git a/NEWS b/NEWS index db8d856e..df852521 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,83 @@ -0.66rc3 - - todo +0.70 + - Improve register handling and support with XMS. + - Fix some issues with deleting open files.(windows only issue) + - Add dummpy 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 strickt 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. diff --git a/README b/README index 94af7305..e1ed8f40 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -DOSBox v0.66 +DOSBox v0.70 ===== @@ -25,11 +25,12 @@ INDEX: 7. Keyboard Layout 8. Serial Multiplayer feature 9. How to run resource-demanding games -10. The config file -11. The language file -12. Building your own version of DOSBox -13. Special thanks -14. Contact +10. Troubleshooting +11. The config file +12. The language file +13. Building your own version of DOSBox +14. Special thanks +15. Contact ============== @@ -311,7 +312,9 @@ In Windows, you can also drag directories/files onto the DOSBox executable. 4. Internal Programs: ===================== -DOSBox supports most of the DOS commands found in command.com. +DOSBox supports most of the DOS commands found in command.com. +To get a list of the internal commands type "HELP" at the prompt. + In addition, the following commands are available: MOUNT "Emulated Drive letter" "Real Drive or Directory" @@ -416,7 +419,7 @@ CONFIG -get "section property" CONFIG can be used to change or query various settings of DOSBox during runtime. It can save the current settings and language strings to disk. Information about all possible sections and properties can - be found in section 10 (The Config File). + be found in section 11 (The Config File). -writeconf localfile Write the current configuration settings to file. "localfile" is @@ -424,7 +427,7 @@ CONFIG -get "section property" The configuration file controls various settings of DOSBox: the amount of emulated memory, the emulated soundcards and many more things. It allows access to AUTOEXEC.BAT as well. - See section 10 (The Config File) for more information. + See section 11 (The Config File) for more information. -writelang localfile Write the current language settings to file. "localfile" is @@ -745,9 +748,9 @@ This maximum will vary from computer to computer. -============= +========== 6. Mapper: -============= +========== When you start the DOSBox mapper (either with CTRL-F1 or -startmapper as a command line argument to the DOSBox executable) you are presented with @@ -837,9 +840,9 @@ is present in the configfile. -==================== +=================== 7. Keyboard Layout: -==================== +=================== To switch to a different keyboard layout, either the entry "keyboardlayout" in the [dos]-section in dosbox.conf can be used, or the internal DOSBox @@ -991,18 +994,53 @@ as possible for DOSBox. Advanced cycles configuration: The cycles=auto and cycles=max settings can be parametrized to have different startup defaults. The syntax is - cycles= auto ["realmode default"] ["protected mode default"%] - [limit "cycle limit"] + cycles=auto ["realmode default"] ["protected mode default"%] + [limit "cycle limit"] cycles=max ["protected mode default"%] [limit "cycle limit"] Example: cycles=auto 1000 80% limit 20000 will use cycles=1000 for real mode games, 80% cpu throttling for - protected mode games along with a hard cycles limit of 20000 + protected mode games along with a hard cycle limit of 20000 ==================== -10. The Config File: +10. Troubleshooting: +==================== + +DOSBox crashes right after starting it: + - use different values for the output= entry in your DOSBox + configuration file + - try to update your graphics card driver and DirectX + +Running a certain game closes DOSBox, crashes with some message or hangs: + - see if it works with a default DOSBox installation + (unmodified configuration file) + - try it with sound disabled (use the sound configuration + program that comes with the game, additionally you can + use sbtype=none and gus=false) + - change some entries of the DOSBox configuration file, especially try: + core=normal + fixed cycles (for example cycles=10000) + ems=false + xms=false + or combinations of the above settings + - use loadfix before starting the game + +The game exits to the DOSBox prompt with some error message: + - read the error message closely and try to locate the error + - try the hints at the above sections + - mount differently as some games are picky about the locations, + for example if you used "mount d d:\oldgames\game" try + "mount c d:\oldgames\game" and "mount c d:\oldgames" + - if the game requires a cdrom be sure you used "-t cdrom" when + mounting and try different additional parameters + - check the file permissions of the game files (remove read-only + attributes, add write permissions etc.) + - try reinstalling the game within dosbox + +==================== +11. The Config File: ==================== A config file can be generated by CONFIG.COM, which can be found on the @@ -1025,7 +1063,7 @@ look in the current directory for dosbox.conf. ====================== -11. The Language File: +12. The Language File: ====================== A language file can be generated by CONFIG.COM. @@ -1037,7 +1075,7 @@ section. There's a language= entry that can be changed with the filename. ======================================== -12. Building your own version of DOSBox: +13. Building your own version of DOSBox: ======================================== Download the source. @@ -1046,7 +1084,7 @@ Check the INSTALL in the source distribution. =================== -13. Special Thanks: +14. Special thanks: =================== Vlad R. of the VDMSound project for excellent SoundBlaster info. @@ -1055,12 +1093,15 @@ The Bochs and DOSemu projects, which I used for information. Freedos for ideas in making my shell. Pierre-Yves Gérardy for hosting the old Beta Board. Colin Snover for hosting our forum. +Jantien for the version management. +Shawn and Johannes for creating the MAC OS X PPC version. +Ido Beeri for the icon. The Beta Testers. ============ -14. Contact: +15. Contact: ============ See the site: diff --git a/THANKS b/THANKS index b3454f3a..d48a61da 100644 --- a/THANKS +++ b/THANKS @@ -14,6 +14,10 @@ Colin Snover for hosting our forum. Sourceforge for hosting our homepage and other development tools. Mirek Luza for his moderation of the forums. c2woody for his debug work. + +Jantien for the version management. +Shawn and Johannes for creating the MAC OS X PPC version. +Ido Beeri for the icon. All the people who submitted a bug. The Beta Testers. diff --git a/VERSION b/VERSION index 069e28e3..ac37bbea 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.66rc3 +0.70 diff --git a/configure.in b/configure.in index d76b6228..c2fd3576 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Init. -AC_INIT(dosbox,0.66rc3) +AC_INIT(dosbox,0.70) AC_PREREQ(2.50) AC_CONFIG_SRCDIR(README) @@ -371,7 +371,6 @@ src/misc/Makefile src/shell/Makefile src/platform/Makefile src/platform/visualc/Makefile -visualc/Makefile visualc_net/Makefile include/Makefile docs/Makefile diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index 5783d202..e7f028e7 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -1,5 +1,5 @@ !define VER_MAYOR 0 -!define VER_MINOR 66rc1 +!define VER_MINOR 70 ; The name of the installer Name "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer" diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index ca48fead..45cfa5b0 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -1,6 +1,6 @@ #define INLINE __forceinline -#define VERSION "0.65" +#define VERSION "0.70" /* Define to 1 to enable internal debugger, requires libcurses */ From bd718ada6a0f390f3c0023f0f1c3daa5a4ac2ffc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 7 Mar 2007 10:47:12 +0000 Subject: [PATCH 2746/4131] Fix amount of arguments in LOG_MSG. Thanks Ludwig. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2832 --- src/ints/bios.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 13801d9f..6428f5a3 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.66 2007-02-22 08:33:15 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.67 2007-03-07 10:47:12 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -364,7 +364,7 @@ static Bitu INT14_Handler(void) { if(reg_ah > 0x3 || reg_dx > 0x3) { // 0-3 serial port functions // and no more than 4 serial ports - LOG_MSG("BIOS INT14: Unhandled call AH=%2X DX=%4x",reg_dx); + LOG_MSG("BIOS INT14: Unhandled call AH=%2X DX=%4x",reg_ah,reg_dx); return CBRET_NONE; } From b6e72ef8e1d5cfa6f6074172709b6e5f56b28c9d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 23 Mar 2007 08:27:39 +0000 Subject: [PATCH 2747/4131] Zero pad the correct buffer. Fixes cyrus chess. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2833 --- src/dos/dos_files.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 86d449f8..746b0b03 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.81 2007-01-08 21:20:23 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.82 2007-03-23 08:27:39 qbix79 Exp $ */ #include #include @@ -878,10 +878,9 @@ Bit8u DOS_FCBRead(Bit16u seg,Bit16u offset,Bit16u recno) { Bit16u toread=rec_size; if (!DOS_ReadFile(fhandle,dos_copybuf,&toread)) return FCB_READ_NODATA; if (toread==0) return FCB_READ_NODATA; - if (toread0;i--) mem_writeb(fill++,0); + if (toread < rec_size) { //Zero pad copybuffer to rec_size + Bitu i = toread; + while(i < rec_size) dos_copybuf[i++] = 0; } MEM_BlockWrite(Real2Phys(dos.dta())+recno*rec_size,dos_copybuf,rec_size); if (++cur_rec>127) { cur_block++;cur_rec=0; } @@ -927,6 +926,10 @@ Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { * random read updates old block and old record to reflect the random data * before the read!!!!!!!!! and the random data is not updated! (user must do this) * Random block read updates these fields to reflect the state after the read! + */ + +/* BUG: numRec should return the amount of records read! + * Not implemented yet as I'm unsure how to count on error states (partial/failed) */ DOS_FCB fcb(seg,offset); From 2147dc647b8dd014f9c71111a469eca2508b9c16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 14 Apr 2007 11:16:29 +0000 Subject: [PATCH 2748/4131] issue an exception for some invalid selector type on pmode CALL instead of exiting (vbdos) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2834 --- src/cpu/cpu.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index ca92fdf7..d7a77c33 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.98 2007-02-22 08:35:34 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.99 2007-04-14 11:16:29 c2woody Exp $ */ #include #include @@ -1163,8 +1163,8 @@ call_code: LOG(LOG_CPU,LOG_NORMAL)("CALL:TSS to %X",selector); CPU_SwitchTask(selector,TSwitch_CALL_INT,oldeip); break; - case DESC_INVALID: - // used by some installers + case DESC_DATA_EU_RW_NA: // vbdos + case DESC_INVALID: // used by some installers CPU_Exception(EXCEPTION_GP,selector & 0xfffc); return; default: From 9afe1037a725dbf1c1bbdc5cd412b1b2ecc1c8ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 14 Apr 2007 13:11:48 +0000 Subject: [PATCH 2749/4131] correct range invalidation start index (dynamic core, fixes Archimedean Dynasty) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2835 --- src/cpu/core_dyn_x86/cache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 7fe2965e..a5f10b7b 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -66,7 +66,7 @@ public: } } bool InvalidateRange(Bitu start,Bitu end) { - Bits index=1+(start>>DYN_HASH_SHIFT); + Bits index=1+(end>>DYN_HASH_SHIFT); bool is_current_block=false; Bit32u ip_point=SegPhys(cs)+reg_eip; ip_point=((paging.tlb.phys_page[ip_point>>12]-phys_page)<<12)+(ip_point&0xfff); From d8f68648d13961cff3d805c9cbac9ea9fa7e2230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 14 Apr 2007 14:08:51 +0000 Subject: [PATCH 2750/4131] precise pagefault address for block starts; fix upper part of eip content for certain instructions in real/v86 mode (dynamic core; fixes Inner Worlds) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2836 --- src/cpu/core_dyn_x86.cpp | 3 +-- src/cpu/core_dyn_x86/decoder.h | 17 +++++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index fc342519..50d78e8d 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -258,12 +258,11 @@ Bits CPU_Core_Dyn_X86_Run(void) { /* Determine the linear address of CS:EIP */ restart_core: PhysPt ip_point=SegPhys(cs)+reg_eip; - Bitu ip_page=ip_point>>12; #if C_HEAVY_DEBUG if (DEBUG_HeavyIsBreakpoint()) return debugCallback; #endif CodePageHandler * chandler=0; - if (GCC_UNLIKELY(MakeCodePage(ip_page,chandler))) { + if (GCC_UNLIKELY(MakeCodePage(ip_point,chandler))) { CPU_Exception(cpu.exception.which,cpu.exception.error); goto restart_core; } diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 9bdf8514..a18f3a17 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -50,10 +50,11 @@ static struct DynDecode { DynReg * segprefix; } decode; -static bool MakeCodePage(Bitu lin_page,CodePageHandler * &cph) { +static bool MakeCodePage(Bitu lin_addr,CodePageHandler * &cph) { Bit8u rdval; //Ensure page contains memory: - if (GCC_UNLIKELY(mem_readb_checked_x86(lin_page << 12,&rdval))) return true; + if (GCC_UNLIKELY(mem_readb_checked_x86(lin_addr,&rdval))) return true; + Bitu lin_page=lin_addr >> 12; PageHandler * handler=paging.tlb.handler[lin_page]; if (handler->flags & PFLAG_HASCODE) { cph=( CodePageHandler *)handler; @@ -99,8 +100,10 @@ static Bit8u decode_fetchb(void) { /* Advance to the next page */ decode.active_block->page.end=4095; /* trigger possible page fault here */ - mem_readb((++decode.page.first) << 12); - MakeCodePage(decode.page.first,decode.page.code); + decode.page.first++; + Bitu fetchaddr=decode.page.first << 12; + mem_readb(fetchaddr); + MakeCodePage(fetchaddr,decode.page.code); CacheBlock * newblock=cache_getblock(); decode.active_block->crossblock=newblock; newblock->crossblock=decode.active_block; @@ -252,7 +255,8 @@ static INLINE void dyn_set_eip_end(void) { static INLINE void dyn_set_eip_end(DynReg * endreg) { gen_protectflags(); - gen_dop_word(DOP_MOV,cpu.code.big,DREG(TMPW),DREG(EIP)); + if (cpu.code.big) gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(EIP)); + else gen_extend_word(false,DREG(TMPW),DREG(EIP)); gen_dop_word_imm(DOP_ADD,cpu.code.big,DREG(TMPW),decode.code-decode.code_start); } @@ -1810,7 +1814,8 @@ static void dyn_call_near_imm(void) { dyn_set_eip_end(DREG(TMPW)); dyn_push(DREG(TMPW)); gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(TMPW),imm); - gen_dop_word(DOP_MOV,decode.big_op,DREG(EIP),DREG(TMPW)); + if (cpu.code.big) gen_dop_word(DOP_MOV,true,DREG(EIP),DREG(TMPW)); + else gen_extend_word(false,DREG(EIP),DREG(TMPW)); dyn_reduce_cycles(); dyn_save_critical_regs(); gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); From d104eea1755b16ed7c32d5f2e7b01ec6ca2b77cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 15 Apr 2007 10:34:02 +0000 Subject: [PATCH 2751/4131] fix windib fallback; fix ddraw->surface fallback Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2837 --- src/gui/sdlmain.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 7f885a10..870a11fe 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.127 2007-01-24 16:29:09 harekiet Exp $ */ +/* $Id: sdlmain.cpp,v 1.128 2007-04-15 10:34:02 c2woody Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -433,11 +433,17 @@ dosurface: sdl.surface=SDL_SetVideoMode(width,height,bpp,(flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE); #ifdef WIN32 if (sdl.surface == NULL) { - LOG_MSG("Failed to create hardware surface.\nRestarting video subsystem with windib enabled."); SDL_QuitSubSystem(SDL_INIT_VIDEO); - putenv("SDL_VIDEODRIVER=windib"); + if (!sdl.using_windib) { + LOG_MSG("Failed to create hardware surface.\nRestarting video subsystem with windib enabled."); + putenv("SDL_VIDEODRIVER=windib"); + sdl.using_windib=true; + } else { + LOG_MSG("Failed to create hardware surface.\nRestarting video subsystem with directx enabled."); + putenv("SDL_VIDEODRIVER=directx"); + sdl.using_windib=true; + } SDL_InitSubSystem(SDL_INIT_VIDEO); - sdl.using_windib=true; sdl.surface = SDL_SetVideoMode(width,height,bpp,SDL_HWSURFACE); } #endif @@ -490,6 +496,10 @@ dosurface: sdl.surface->format->Bmask, 0); if (!sdl.blit.surface || (!sdl.blit.surface->flags&SDL_HWSURFACE)) { + if (sdl.blit.surface) { + SDL_FreeSurface(sdl.blit.surface); + sdl.blit.surface=0; + } LOG_MSG("Failed to create ddraw surface, back to normal surface."); goto dosurface; } @@ -1373,12 +1383,16 @@ int main(int argc, char* argv[]) { char sdl_drv_name[128]; if (getenv("SDL_VIDEODRIVER")==NULL) { if (SDL_VideoDriverName(sdl_drv_name,128)!=NULL) { + sdl.using_windib=false; if (strcmp(sdl_drv_name,"directx")!=0) { SDL_QuitSubSystem(SDL_INIT_VIDEO); putenv("SDL_VIDEODRIVER=directx"); - SDL_InitSubSystem(SDL_INIT_VIDEO); + if (SDL_InitSubSystem(SDL_INIT_VIDEO)<0) { + putenv("SDL_VIDEODRIVER=windib"); + if (SDL_InitSubSystem(SDL_INIT_VIDEO)<0) E_Exit("Can't init SDL Video %s",SDL_GetError()); + sdl.using_windib=true; + } } - sdl.using_windib=false; } } else { char* sdl_videodrv = getenv("SDL_VIDEODRIVER"); From 04ade3cc821165dfd0f445a710fea88d98b5566e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 15 Apr 2007 11:39:33 +0000 Subject: [PATCH 2752/4131] fix mscdex get audio position Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2838 --- src/dos/dos_mscdex.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 3753337a..cab04d47 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.45 2007-01-21 16:21:22 c2woody Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.46 2007-04-15 11:39:33 c2woody Exp $ */ #include #include @@ -876,7 +876,10 @@ static Bit16u MSCDEX_IOCTL_Input(PhysPt buffer,Bit8u drive_unit) { mscdex->GetCurrentPos(drive_unit,pos); Bit8u addr_mode = mem_readb(buffer+1); if (addr_mode==0) { // HSG - mem_writed(buffer+2,MSF_TO_FRAMES (pos.min, pos.sec, pos.fr)); + Bit32u frames=MSF_TO_FRAMES(pos.min, pos.sec, pos.fr); + if (frames<150) LOG_MSG("MSCDEX: Get position: invalid position %d:%d:%d", pos.min, pos.sec, pos.fr); + else frames-=150; + mem_writed(buffer+2,frames); } else if (addr_mode==1) { // Red book mem_writeb(buffer+2,pos.fr); mem_writeb(buffer+3,pos.sec); From 17c683f8ada43a51c0c4c4ee826bc0c39dfd3ef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 15 Apr 2007 12:13:16 +0000 Subject: [PATCH 2753/4131] fix shifted cd-audio with sdl-interface (prompt, sf bug #883811) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2839 --- src/dos/cdrom.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index ad92feac..3e13ac39 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -85,7 +85,7 @@ bool CDROM_Interface_SDL::GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) bool CDROM_Interface_SDL::GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr) { if (CD_INDRIVE(SDL_CDStatus(cd))) { - FRAMES_TO_MSF(cd->track[track-1].offset+150,&start.min,&start.sec,&start.fr); + FRAMES_TO_MSF(cd->track[track-1].offset,&start.min,&start.sec,&start.fr); attr = cd->track[track-1].type<<4;//sdl uses 0 for audio and 4 for data. instead of 0x00 and 0x40 } return CD_INDRIVE(SDL_CDStatus(cd)); From 15ea05cff91ab22cfb0aa518330601c8ab449c4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 16 Apr 2007 12:23:23 +0000 Subject: [PATCH 2754/4131] fully implement dos subfunction 0x0c, fix CON GetInformation (Kippesoep; sf patch #1691918, fixes Wing Commander 3 exit dialog) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2840 --- src/dos/dev_con.h | 4 ++-- src/dos/dos.cpp | 15 +++++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 5ce1bdc6..b7b8f0b9 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.28 2007-01-11 18:08:54 c2woody Exp $ */ +/* $Id: dev_con.h,v 1.29 2007-04-16 12:23:23 c2woody Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" @@ -370,7 +370,7 @@ Bit16u device_CON::GetInformation(void) { Bit16u tail=mem_readw(BIOS_KEYBOARD_BUFFER_TAIL); if ((head==tail) && !readcache) return 0x80D3; /* No Key Available */ - if (real_readw(0x40,head)) return 0x8093; /* Key Available */ + if (readcache || real_readw(0x40,head)) return 0x8093; /* Key Available */ /* remove the zero from keyboard buffer */ Bit16u start=mem_readw(BIOS_KEYBOARD_BUFFER_START); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 98237bec..5cc538ce 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.99 2007-01-13 08:35:49 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.100 2007-04-16 12:23:23 c2woody Exp $ */ #include #include @@ -191,14 +191,12 @@ static Bitu DOS_21Handler(void) { break; case 0x0c: /* Flush Buffer and read STDIN call */ { + /* flush STDIN-buffer */ + Bit8u c;Bit16u n; + while (DOS_GetSTDINStatus()) { + n=1; DOS_ReadFile(STDIN,&c,&n); + } switch (reg_al) { - case 0x0: - /* flush STDIN-buffer */ - Bit8u c;Bit16u n; - while (DOS_GetSTDINStatus()) { - n=1; DOS_ReadFile(STDIN,&c,&n); - } - break; case 0x1: case 0x6: case 0x7: @@ -213,6 +211,7 @@ static Bitu DOS_21Handler(void) { break; default: // LOG_ERROR("DOS:0C:Illegal Flush STDIN Buffer call %d",reg_al); + reg_al=0; break; } } From 220d61976a7a2e0a56284d2db71042c2819f7334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 16 Apr 2007 13:25:06 +0000 Subject: [PATCH 2755/4131] don't exit on special fully-nested PIC mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2841 --- src/hardware/pic.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index ebe58f01..f7c11ca5 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.39 2007-01-18 14:57:59 c2woody Exp $ */ +/* $Id: pic.cpp,v 1.40 2007-04-16 13:25:06 c2woody Exp $ */ #include @@ -203,7 +203,7 @@ static void write_data(Bitu port,Bitu val,Bitu iolen) { LOG(LOG_PIC,LOG_NORMAL)("%d:ICW 4 %X",port==0x21 ? 0 : 1,val); if ((val&0x01)==0) E_Exit("PIC:ICW4: %x, 8085 mode not handled",val); - if ((val&0x10)!=0) E_Exit("PIC:ICW4: %x, special fully-nested mode not handled",val); + if ((val&0x10)!=0) LOG_MSG("PIC:ICW4: %x, special fully-nested mode not handled",val); if(pic->icw_index++ >= pic->icw_words) pic->icw_index=0; break; From 12d417e58c6db8ab237c92bff6e4afdca33e62b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 17 Apr 2007 15:48:53 +0000 Subject: [PATCH 2756/4131] add hd image file size detection Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2842 --- src/dos/dos_programs.cpp | 65 ++++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 66833a38..46dfd857 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.69 2007-02-22 08:37:12 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.70 2007-04-17 15:48:53 c2woody Exp $ */ #include #include @@ -886,6 +886,7 @@ public: Bit8u mediaid; if (type=="floppy" || type=="hdd" || type=="iso") { Bit16u sizes[4]; + bool autosizedetect=false; std::string str_size; mediaid=0xF8; @@ -899,21 +900,26 @@ public: } cmd->FindString("-size",str_size,true); if ((type=="hdd") && (str_size.size()==0)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_GEOMETRY")); - return; + if (!cmd->FindExist("-autosize",true)) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_GEOMETRY")); + return; + } else { + autosizedetect=true; + } + } else { + char number[20]; + const char * scan=str_size.c_str(); + Bitu index=0;Bitu count=0; + + while (*scan) { + if (*scan==',') { + number[index]=0;sizes[count++]=atoi(number); + index=0; + } else number[index++]=*scan; + scan++; + } + number[index]=0;sizes[count++]=atoi(number); } - char number[20]; - const char * scan=str_size.c_str(); - Bitu index=0;Bitu count=0; - - while (*scan) { - if (*scan==',') { - number[index]=0;sizes[count++]=atoi(number); - index=0; - } else number[index++]=*scan; - scan++; - } - number[index]=0;sizes[count++]=atoi(number); if(fstype=="fat" || fstype=="iso") { // get the drive letter @@ -986,6 +992,35 @@ public: } if(fstype=="fat") { + if (autosizedetect) { + FILE * diskfile = fopen(temp_line.c_str(), "rb+"); + if(!diskfile) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_GEOMETRY")); + return; + } + fseek(diskfile, 0L, SEEK_END); + Bit32u fcsize = (Bit32u)(ftell(diskfile) / 512L); + Bit8u buf[512]; + fseek(diskfile, 0L, SEEK_SET); + if (fread(buf,sizeof(Bit8u),512,diskfile)<512) { + fclose(diskfile); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_GEOMETRY")); + return; + } + fclose(diskfile); + if ((buf[510]!=0x55) || (buf[511]!=0xaa)) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_GEOMETRY")); + return; + } + Bitu sectors=(Bitu)(fcsize/(16*63)); + if (sectors*16*63!=fcsize) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_GEOMETRY")); + return; + } + sizes[0]=512; sizes[1]=63; sizes[2]=16; sizes[3]=sectors; + LOG_MSG("autosized image file: %d:%d:%d:%d",sizes[0],sizes[1],sizes[2],sizes[3]); + } + newdrive=new fatDrive(temp_line.c_str(),sizes[0],sizes[1],sizes[2],sizes[3],0); if(!(dynamic_cast(newdrive))->created_succesfully) { delete newdrive; From a0232dbf2ef1c8fe799199570a775e4a70ad9fb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 17 Apr 2007 18:48:41 +0000 Subject: [PATCH 2757/4131] fix CreateTempFile error handling (namiltd, sf patch #1674288) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2843 --- src/dos/dos_files.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 746b0b03..38515d3a 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.82 2007-03-23 08:27:39 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.83 2007-04-17 18:48:41 c2woody Exp $ */ #include #include @@ -639,9 +639,9 @@ bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry) { bool DOS_CreateTempFile(char * name,Bit16u * entry) { /* First add random crap to the end of the name and try to open */ - /* Todo maybe check for euhm existence of the path name */ char * tempname; tempname=name+strlen(name); + dos.errorcode=0; do { Bit32u i; for (i=0;i<8;i++) { @@ -652,7 +652,8 @@ bool DOS_CreateTempFile(char * name,Bit16u * entry) { tempname[i]=(rand()%26)+'A'; } tempname[12]=0; - } while (!DOS_CreateFile(name,0,entry)); + } while ((!DOS_CreateFile(name,0,entry)) && (dos.errorcode==DOSERR_FILE_ALREADY_EXISTS)); + if (dos.errorcode) return false; return true; } From 75b028da9e85cf31ee3d11a4b21927ebb592c5ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 18 Apr 2007 16:40:48 +0000 Subject: [PATCH 2758/4131] fix digital joystick centering (royalozma, sf bug #1673772); correct joystick display in mapper Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2844 --- src/gui/sdl_mapper.cpp | 49 ++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 6c15ed2a..dc091b0b 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.33 2007-02-22 15:12:48 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.34 2007-04-18 16:40:48 c2woody Exp $ */ #include #include @@ -765,11 +765,32 @@ public: for (i=0; i0) ActivateBindList(&pos_axis_lists[i],caxis_pos,false); - else if (caxis_pos<0) { + if (caxis_pos>1) { + if (old_neg_axis_state[i]) { + DeactivateBindList(&neg_axis_lists[i],false); + old_neg_axis_state[i] = false; + } + ActivateBindList(&pos_axis_lists[i],caxis_pos,false); + old_pos_axis_state[i] = true; + } else if (caxis_pos<-1) { + if (old_pos_axis_state[i]) { + DeactivateBindList(&pos_axis_lists[i],false); + old_pos_axis_state[i] = false; + } if (caxis_pos!=-32768) caxis_pos=(Sint16)abs(caxis_pos); else caxis_pos=32767; ActivateBindList(&neg_axis_lists[i],caxis_pos,false); + old_neg_axis_state[i] = true; + } else { + /* center */ + if (old_pos_axis_state[i]) { + DeactivateBindList(&pos_axis_lists[i],false); + old_pos_axis_state[i] = false; + } + if (old_neg_axis_state[i]) { + DeactivateBindList(&neg_axis_lists[i],false); + old_neg_axis_state[i] = false; + } } } @@ -2066,13 +2087,23 @@ void BIND_MappingEvents(void) { } } -static void CreateBindGroups(void) { - bindgroups.clear(); - new CKeyBindGroup(SDLK_LAST); +static void InitializeJoysticks(void) { mapper.sticks.num=0; mapper.sticks.num_groups=0; if (joytype != JOY_NONE) { mapper.sticks.num=SDL_NumJoysticks(); + if (joytype==JOY_AUTO) { + if (mapper.sticks.num>1) joytype=JOY_2AXIS; + else if (mapper.sticks.num) joytype=JOY_4AXIS; + else joytype=JOY_NONE; + } + } +} + +static void CreateBindGroups(void) { + bindgroups.clear(); + new CKeyBindGroup(SDLK_LAST); + if (joytype != JOY_NONE) { #if defined (REDUCE_JOYSTICK_POLLING) // direct access to the SDL joystick, thus removed from the event handling if (mapper.sticks.num) SDL_JoystickEventState(SDL_DISABLE); @@ -2082,11 +2113,6 @@ static void CreateBindGroups(void) { else return; #endif Bit8u joyno=0; - if (joytype==JOY_AUTO) { - if (mapper.sticks.num>1) joytype=JOY_2AXIS; - else if (mapper.sticks.num) joytype=JOY_4AXIS; - else joytype=JOY_NONE; - } switch (joytype) { case JOY_NONE: break; @@ -2170,6 +2196,7 @@ void MAPPER_Run(bool pressed) { } void MAPPER_Init(void) { + InitializeJoysticks(); CreateLayout(); CreateBindGroups(); if (!MAPPER_LoadBinds()) CreateDefaultBinds(); From cb98d87b7a6b236d60de83b8b04261ee9fd41581 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 19 Apr 2007 13:11:49 +0000 Subject: [PATCH 2759/4131] Make textmode 54 and 55 work again Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2845 --- src/gui/render_scalers.h | 4 ++-- src/ints/int10_modes.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index 9f1b1636..9fe6691d 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -21,8 +21,8 @@ //#include "render.h" #include "video.h" - -#define SCALER_MAXWIDTH 1024 +//MAXWIDTH: increased it for the large text modi +#define SCALER_MAXWIDTH 1280 #define SCALER_MAXHEIGHT 768 #define SCALER_COMPLEXWIDTH 512 diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index c5c9ae17..a5331424 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -52,7 +52,7 @@ VideoModeBlock ModeList_VGA[]={ { 0x012 ,M_EGA ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, { 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x2000 ,100 ,449 ,80 ,400 ,0 }, -{ 0x054 ,M_TEXT ,1056,688, 132,43, 8, 8, 1 ,0xB8000 ,0x4000, 192, 800, 132,688, 0 }, +{ 0x054 ,M_TEXT ,1056,688, 132,43, 8, 16, 1 ,0xB8000 ,0x4000, 192, 800, 132,688, 0 }, { 0x055 ,M_TEXT ,1056,400, 132,25, 8, 16, 1 ,0xB8000 ,0x2000, 192, 449, 132,400, 0 }, { 0x06A ,M_LIN4 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, From 9a495a6bbc3f2c40e7ca857df7385bc6b3676efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 30 Apr 2007 18:35:34 +0000 Subject: [PATCH 2760/4131] add some NANSI-only escape sequence (PC Larn) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2846 --- src/dos/dev_con.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index b7b8f0b9..f103a60d 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.29 2007-04-16 12:23:23 c2woody Exp $ */ +/* $Id: dev_con.h,v 1.30 2007-04-30 18:35:34 c2woody Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" @@ -333,7 +333,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { ansi.saverow=CURSOR_POS_ROW(page); ClearAnsi(); break; - case 'K':/* erase till end of line (don't touch cursor) */ + case 'K': /* erase till end of line (don't touch cursor) */ col = CURSOR_POS_COL(page); row = CURSOR_POS_ROW(page); INT10_WriteChar(' ',ansi.attr,page,ansi.ncols-col,true); //Use this one to prevent scrolling when end of screen is reached @@ -341,6 +341,12 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { INT10_SetCursorPos(row,col,page); ClearAnsi(); break; + case 'M': /* delete line (NANSI) */ + col = CURSOR_POS_COL(page); + row = CURSOR_POS_ROW(page); + INT10_ScrollWindow(row,0,ansi.nrows-1,ansi.ncols-1,ansi.data[0]? -ansi.data[0] : -1,ansi.attr,0xFF); + ClearAnsi(); + break; case 'l':/* (if code =7) disable linewrap */ case 'p':/* reassign keys (needs strings) */ case 'i':/* printer stuff */ From af5b21b0130a5a988c000da03c3fcbf1c7b12e41 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 1 May 2007 12:24:58 +0000 Subject: [PATCH 2761/4131] reset pelmask on a new mode. Fixes univbe 5.0lite with panzer general Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2847 --- src/ints/int10_modes.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index a5331424..9e5a8824 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -880,6 +880,7 @@ att_text16: IO_Write(0x3c0,0x20); IO_Write(0x3c0,0x00); //Disable palette access /* Setup the DAC */ IO_Write(0x3c8,0); + IO_Write(0x3c6,0xff); //Reset Pelmask switch (CurMode->type) { case M_EGA: if (CurMode->mode>0xf) goto dac_text16; From 201d9b65922fdc1b4d3db3716c207610d4d4356b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 1 May 2007 18:57:19 +0000 Subject: [PATCH 2762/4131] fix mixer underflow (muted pcspeaker in unlocked speed mode; thanks to ykhwong for his report) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2848 --- src/hardware/mixer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index eee53355..f89a6fba 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.44 2007-01-08 19:45:40 qbix79 Exp $ */ +/* $Id: mixer.cpp,v 1.45 2007-05-01 18:57:19 c2woody Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -429,7 +429,7 @@ static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { } /* Reduce done count in all channels */ for (MixerChannel * chan=mixer.channels;chan;chan=chan->next) { - if (chan->done>need) chan->done-=reduce; + if (chan->done>reduce) chan->done-=reduce; else chan->done=0; } From e54e2cd8d512dce451969989bcfb3017e660b38e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 1 May 2007 20:00:45 +0000 Subject: [PATCH 2763/4131] set variables correctly for some fallback code Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2849 --- src/gui/sdlmain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 870a11fe..bb0b7ead 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.128 2007-04-15 10:34:02 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.129 2007-05-01 20:00:45 c2woody Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -441,7 +441,7 @@ dosurface: } else { LOG_MSG("Failed to create hardware surface.\nRestarting video subsystem with directx enabled."); putenv("SDL_VIDEODRIVER=directx"); - sdl.using_windib=true; + sdl.using_windib=false; } SDL_InitSubSystem(SDL_INIT_VIDEO); sdl.surface = SDL_SetVideoMode(width,height,bpp,SDL_HWSURFACE); From eb90bbf252eb58aeac01d5ba76a679ff2db13f77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 2 May 2007 16:32:34 +0000 Subject: [PATCH 2764/4131] always check for pushf/popf exception in the dynamic core (prevents discrepancy if instruction is executed in realmode and v86) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2850 --- src/cpu/core_dyn_x86/decoder.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index a18f3a17..61f04308 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -2187,14 +2187,14 @@ restart_prefix: gen_releasereg(DREG(ESP)); dyn_flags_gen_to_host(); gen_call_function((void *)&CPU_PUSHF,"%Rd%Id",DREG(TMPB),decode.big_op); - if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); + dyn_check_bool_exception(DREG(TMPB)); gen_releasereg(DREG(TMPB)); break; case 0x9d: //POPF gen_releasereg(DREG(ESP)); gen_releasereg(DREG(FLAGS)); gen_call_function((void *)&CPU_POPF,"%Rd%Id",DREG(TMPB),decode.big_op); - if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); + dyn_check_bool_exception(DREG(TMPB)); dyn_flags_host_to_gen(); gen_releasereg(DREG(TMPB)); break; From 2a7805656aae018fb36e26139fd3f5b4143a928e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 2 May 2007 18:56:15 +0000 Subject: [PATCH 2765/4131] return maximal cylinder number instead of cylinder count on int13/get driveparams (thanks to formatc) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2851 --- src/ints/bios_disk.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 48e4196e..6b868666 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.33 2007-01-21 16:21:22 c2woody Exp $ */ +/* $Id: bios_disk.cpp,v 1.34 2007-05-02 18:56:15 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" @@ -436,16 +436,20 @@ static Bitu INT13_DiskHandler(void) { if(driveInactive(drivenum)) { last_status = 0x07; reg_ah = last_status; - CALLBACK_SCF(true); + CALLBACK_SCF(true); return CBRET_NONE; } reg_ax = 0x00; reg_bl = imageDiskList[drivenum]->GetBiosType(); Bit32u tmpheads, tmpcyl, tmpsect, tmpsize; imageDiskList[drivenum]->Get_Geometry(&tmpheads, &tmpcyl, &tmpsect, &tmpsize); + if (tmpcyl==0) LOG(LOG_BIOS,LOG_ERROR)("INT13 DrivParm: cylinder count zero!"); + else tmpcyl--; // cylinder count -> max cylinder + if (tmpheads==0) LOG(LOG_BIOS,LOG_ERROR)("INT13 DrivParm: head count zero!"); + else tmpheads--; // head count -> max head reg_ch = tmpcyl & 0xff; reg_cl = (((tmpcyl >> 2) & 0xc0) | (tmpsect & 0x3f)); - reg_dh = tmpheads-1; + reg_dh = tmpheads; last_status = 0x00; if (reg_dl&0x80) { // harddisks reg_dl = 0; From e2cc1b1a226719cf7edb52c96884312fdb0bd282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 9 May 2007 13:15:27 +0000 Subject: [PATCH 2766/4131] typos, small readme updates (TeaRex, sf patch #1672904) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2852 --- ChangeLog | 4 ++-- NEWS | 4 ++-- README | 35 +++++++++++++++++------------------ 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index 35738962..e92956ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,7 @@ 0.70 - Improve register handling and support with XMS. - Fix some issues with deleting open files.(windows only issue) - - Add dummpy LPT1 class. (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) @@ -13,7 +13,7 @@ - Move some interrupt handlers to XT Bios locations. - Add a dynamic fpu on x86. - Improve fpu on non-x86. - - Trapflag gets strickt priority over hardware IRQs. + - Trapflag gets strict priority over hardware IRQs. - Trapflag support for the dynamic core. - Add dummy TRx handling. - Fix a few rarely used character functions. diff --git a/NEWS b/NEWS index df852521..8aafd742 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,7 @@ 0.70 - Improve register handling and support with XMS. - Fix some issues with deleting open files.(windows only issue) - - Add dummpy LPT1 class. (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) @@ -13,7 +13,7 @@ - Move some interrupt handlers to XT Bios locations. - Add a dynamic fpu on x86. - Improve fpu on non-x86. - - Trapflag gets strickt priority over hardware IRQs. + - Trapflag gets strict priority over hardware IRQs. - Trapflag support for the dynamic core. - Add dummy TRx handling. - Fix a few rarely used character functions. diff --git a/README b/README index e1ed8f40..fe1606f8 100644 --- a/README +++ b/README @@ -137,7 +137,7 @@ A: This is a known problem. It only occurs if your keyboard layout isn't US. 2. Use / instead. 3. Open dosbox.conf and change usescancodes=false to usescancodes=true. 4. Add the commands you want to execute to the "configfile". - 5. Change the dos keyboard layout (see Section 7 Keyboard Layout). + 5. Change the DOS keyboard layout (see Section 7 Keyboard Layout). 6. Use ALT-58 for : and ALT-92 for \. 7. for \ try the keys around "enter". For ":" try shift and the keys between "enter" and "l" (US keyboard layout). @@ -217,7 +217,7 @@ A: This isn't really a DOSBox problem, but the solution is to set the Q: Great README, but I still don't get it. A: A look at "The Newbie's pictorial guide to DOSBox" located at http://vogons.zetafleet.com/viewforum.php?f=39 might help you. - Also try the wiki of dosbox: + Also try the wiki of DOSBox: http://dosbox.sourceforge.net/wiki/ @@ -326,10 +326,10 @@ MOUNT -u "Emulated Drive letter" Program to mount local directories as drives inside DOSBox. "Emulated Drive letter" - The driveletter inside dosbox (eg. C). + The driveletter inside DOSBox (eg. C). "Real Drive letter (usually for CD-ROMs in Windows) or Directory" - The local directory you want accessible inside dosbox. + The local directory you want accessible inside DOSBox. -t type Type of the mounted directory. Supported are: dir (default), @@ -398,7 +398,7 @@ MOUNT -u "Emulated Drive letter" 2. To mount system cdrom drive E as cdrom drive D in DOSBox: mount d e:\ -t cdrom 3. To mount system cdrom drive at mountpoint /media/cdrom as cdrom drive D - in dosbox: + in DOSBox: mount d /media/cdrom -t cdrom -usecd 0 4. To mount a drive with 870 mb free diskspace (simple version): mount c d:\ -freesize 870 @@ -433,7 +433,7 @@ CONFIG -get "section property" Write the current language settings to file. "localfile" is located on the local drive, not a mounted drive in DOSBox. The language file controls all visible ouput of the internal commands - and the internal dos. + and the internal DOS. -set "section property=value" CONFIG will attempt to set the property to new value. At this moment @@ -632,7 +632,7 @@ IPX IPXNET STARTSERVER - IPXNET STARTSERVER starts and IPX tunneling server on this DOSBox + IPXNET STARTSERVER starts an IPX tunneling server on this DOSBox session. By default, the server will accept connections on UDP port 213, though this can be changed. Once the server is started, DOSBox will automatically start a client connection to the IPX tunnelling server. @@ -728,7 +728,7 @@ CTRL-ALT-F7 Start/Stop recording of OPL commands. CTRL-ALT-F8 Start/Stop the recording of raw MIDI commands. CTRL-F7 Decrease frameskip. CTRL-F8 Increase frameskip. -CTRL-F9 Kill dosbox. +CTRL-F9 Kill DOSBox. CTRL-F10 Capture/Release the mouse. CTRL-F11 Slow down emulation (Decrease DOSBox Cycles). CTRL-F12 Speed up emulation (Increase DOSBox Cycles). @@ -845,8 +845,8 @@ is present in the configfile. =================== To switch to a different keyboard layout, either the entry "keyboardlayout" -in the [dos]-section in dosbox.conf can be used, or the internal DOSBox -program keyb.com. Both accept dos-conform language codes (see below), but +in the [dos] section in dosbox.conf can be used, or the internal DOSBox +program keyb.com. Both accept DOS conforming language codes (see below), but only by using keyb.com a custom codepage can be specified. Layout switching @@ -861,10 +861,8 @@ Layout switching NO (Norway), PL (Poland), RU (Russian Federation), SK (Slovakia), SP (Spain), SU (Finland), SV (Sweden) - When a keyboard layout is loaded, it is possible to switch between the - foreign layout and the US-layout by pressing CTRL+ALT+F2. Some keyboard layouts (for example layout GK codepage 869 and layout RU - codepage 808) have support for dual-layouts that can be activated by + codepage 808) have support for dual layouts that can be activated by pressing LEFT-ALT+RIGHT-SHIFT and deactivated by LEFT-ALT+LEFT-SHIFT. Supported external files @@ -874,12 +872,12 @@ Supported external files See http://projects.freedos.net/keyb/ for precompiled keyboard layouts. Both .CPI (MSDOS/compatible codepage files) and .CPX (freedos UPX-compressed - codepage files) can be used. Some codepages are compiled into DOSBox so it + codepage files) can be used. Some codepages are compiled into DOSBox, so it is mostly not needed to care about external codepage files. If you need a different (or custom) codepage file, copy it into the directory of the DOSBox configuration file so it is accessible for DOSBox. - Additional layouts can be added by copying the corresponding .kl-file into + Additional layouts can be added by copying the corresponding .kl file into the directory of dosbox.conf and using the first part of the filename as language code. Example: For the file UZ.KL (keyboard layout for Uzbekistan) specify @@ -1034,17 +1032,18 @@ The game exits to the DOSBox prompt with some error message: for example if you used "mount d d:\oldgames\game" try "mount c d:\oldgames\game" and "mount c d:\oldgames" - if the game requires a cdrom be sure you used "-t cdrom" when - mounting and try different additional parameters + mounting and try different additional parameters (the ioctl, + usecd and label switches, see the appropriate section) - check the file permissions of the game files (remove read-only attributes, add write permissions etc.) - - try reinstalling the game within dosbox + - try reinstalling the game within DOSBox ==================== 11. The Config File: ==================== A config file can be generated by CONFIG.COM, which can be found on the -internal dosbox Z: drive when you start up dosbox. Look in the internal +internal DOSBox Z: drive when you start up DOSBox. Look in the internal programs section of the readme for usage of CONFIG.COM. You can edit the generated configfile to customize DOSBox. From c13c209d3e6c3102a56e85f94f9c3cea2e7717f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 9 May 2007 14:35:51 +0000 Subject: [PATCH 2767/4131] debugger fixes (etillite, sf bug #1707206) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2853 --- src/debug/debug.cpp | 6 +++--- src/debug/debug_gui.cpp | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 5ab20652..45a91020 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.85 2007-02-25 18:38:00 c2woody Exp $ */ +/* $Id: debug.cpp,v 1.86 2007-05-09 14:35:51 c2woody Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -755,7 +755,7 @@ static void DrawRegisters(void) { } wattrset(dbg.win_reg,0); - mvwprintw(dbg.win_reg,3,60,"%d ",cycle_count); + mvwprintw(dbg.win_reg,3,60,"%u ",cycle_count); wrefresh(dbg.win_reg); }; @@ -805,7 +805,7 @@ static void DrawCode(void) line20[20 - drawsize*2] = ' '; } else waddstr(dbg.win_code,line20); - char* res = 0; + char* res = ""; if (showExtend) res = AnalyzeInstruction(dline, saveSel); // Spacepad it up to 28 characters size_t dline_len = strlen(dline); diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 6965055e..fff27f17 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug_gui.cpp,v 1.31 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: debug_gui.cpp,v 1.32 2007-05-09 14:35:51 c2woody Exp $ */ #include "dosbox.h" @@ -106,7 +106,7 @@ void LOG::operator() (char const* format, ...){ if (d_type>=LOG_MAX) return; if ((d_severity!=LOG_ERROR) && (!loggrp[d_type].enabled)) return; - DEBUG_ShowMsg("%10d: %s:%s\n",cycle_count,loggrp[d_type].front,buf); + DEBUG_ShowMsg("%10u: %s:%s\n",cycle_count,loggrp[d_type].front,buf); } @@ -250,6 +250,7 @@ void LOG_StartUp(void) { lowcase(buf); sect->Add_bool(buf,true); } + MSG_Add("LOG_CONFIGFILE_HELP","Logging related options for the debugger.\n"); } From 481d37adf6f85f54382d01e5fc6c2aacde0a0995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 10 May 2007 20:27:48 +0000 Subject: [PATCH 2768/4131] fix file open error code for root files (Kippesoep, sf patch #1691919) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2854 --- src/dos/dos_files.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 38515d3a..d767e00a 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.83 2007-04-17 18:48:41 c2woody Exp $ */ +/* $Id: dos_files.cpp,v 1.84 2007-05-10 20:27:48 c2woody Exp $ */ #include #include @@ -388,6 +388,7 @@ static bool PathExists(char* name) { char temp[CROSS_LEN]; strcpy(temp,name); leading = strrchr(temp,'\\'); + if (leading == temp) return true; *leading = 0; Bit8u drive;char fulldir[DOS_PATHLENGTH]; if (!DOS_MakeName(temp,fulldir,&drive)) return false; From 0911359ee958b674aac54d2b556fbd9bae2bec8e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 15 May 2007 15:51:30 +0000 Subject: [PATCH 2769/4131] Make it possible to disable alsa. Fix various compiler and configure related bugs. Hopefully fixes 1677839, 1678736, 1693635,1697017 and the various email reports Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2855 --- configure.in | 53 +++++++++++++++++++++++++-- src/hardware/serialport/misc_util.cpp | 35 +++--------------- src/hardware/serialport/misc_util.h | 46 +++++++++++++++++------ src/hardware/serialport/nullmodem.cpp | 2 + 4 files changed, 92 insertions(+), 44 deletions(-) diff --git a/configure.in b/configure.in index c2fd3576..13fea9ce 100644 --- a/configure.in +++ b/configure.in @@ -50,6 +50,42 @@ 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 +AC_CHECK_HEADERS([stdlib.h sys/types.h]) +AC_CHECK_HEADERS([sys/socket.h netinet/in.h], [], [], +[#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_SYS_TYPES_H +# include +#endif +]) + +dnl check for the socklen_t (darwin doesn't always have it) +AC_COMPILE_IFELSE([ +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#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 @@ -93,7 +129,18 @@ int x=10;if( __builtin_expect ((x==1),0) ) ; #switch language back AC_LANG_POP(C++) -AM_PATH_ALSA(0.9.0, AC_DEFINE(HAVE_ALSA,1,[Define to 1 to use ALSA for MIDI]) , : ) +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 @@ -327,8 +374,8 @@ case "$target" in AC_DEFINE(MACOSX, 1, [Compiling on Mac OS X]) LIBS="$LIBS -framework AudioUnit" ;; - *-*-linux-gnu*) - AC_DEFINE(LINUX, 1, [Compiling on GNU/Linux]) + *-*-freebsd* | *-*-linux*) + AC_DEFINE(LINUX, 1, [Compiling on GNU/Linux or *BSD]) AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).]) ;; *-*-os2-emx*) diff --git a/src/hardware/serialport/misc_util.cpp b/src/hardware/serialport/misc_util.cpp index 5b999719..97379094 100644 --- a/src/hardware/serialport/misc_util.cpp +++ b/src/hardware/serialport/misc_util.cpp @@ -5,39 +5,13 @@ /*****************************************************************************/ // C++ SDLnet wrapper -// Socket inheritance -#if defined LINUX || defined OS2 -#define CAPWORD (NETWRAPPER_TCP|NETWRAPPER_TCP_NATIVESOCKET) -#ifdef OS2 -typedef int socklen_t; -#endif -#include -#include -#include -#define SOCKET int - -#elif defined WIN32 -#define CAPWORD (NETWRAPPER_TCP|NETWRAPPER_TCP_NATIVESOCKET) -#include -typedef int socklen_t; - -#elif defined __APPLE__ -#define CAPWORD (NETWRAPPER_TCP|NETWRAPPER_TCP_NATIVESOCKET) -#include -#include -#include -#define SOCKET socklen_t - -#else -#define CAPWORD NETWRAPPER_TCP -#endif - #include "misc_util.h" - struct _TCPsocketX { int ready; +#ifdef NATIVESOCKETS SOCKET channel; +#endif IPaddress remoteAddress; IPaddress localAddress; int sflag; @@ -67,7 +41,7 @@ TCPClientSocket::TCPClientSocket(int platformsocket) { // fill the SDL socket manually ((struct _TCPsocketX*)nativetcpstruct)->ready=0; ((struct _TCPsocketX*)nativetcpstruct)->sflag=0; - ((struct _TCPsocketX*)nativetcpstruct)->channel=platformsocket; + ((struct _TCPsocketX*)nativetcpstruct)->channel=(SOCKET) platformsocket; sockaddr_in sa; socklen_t sz; sz=sizeof(sa); @@ -146,7 +120,8 @@ TCPClientSocket::TCPClientSocket(const char* destination, Bit16u port) { listensocketset=0; IPaddress openip; - if (!SDLNet_ResolveHost(&openip,destination,port)) { + //Ancient versions of SDL_net had this as char*. People still appear to be using this one. + if (!SDLNet_ResolveHost(&openip,const_cast(destination),port)) { listensocketset = SDLNet_AllocSocketSet(1); if(!listensocketset) return; mysock = SDLNet_TCP_Open(&openip); diff --git a/src/hardware/serialport/misc_util.h b/src/hardware/serialport/misc_util.h index 9b89ac18..08a36123 100644 --- a/src/hardware/serialport/misc_util.h +++ b/src/hardware/serialport/misc_util.h @@ -1,24 +1,48 @@ #ifndef SDLNETWRAPPER_H #define SDLNETWRAPPER_H +#ifndef DOSBOX_DOSBOX_H +#include "dosbox.h" +#endif + #if C_MODEM -#include "SDL_net.h" +# ifndef DOSBOX_SUPPORT_H #include "support.h" - -#if defined LINUX || defined OS2 -#define NATIVESOCKETS - -#elif defined WIN32 -#define NATIVESOCKETS - -#else #endif // Netwrapper Capabilities #define NETWRAPPER_TCP 1 #define NETWRAPPER_TCP_NATIVESOCKET 2 +#if defined WIN32 + #define NATIVESOCKETS + #include + #include //for socklen_t + //typedef int socklen_t; + +//Tests for BSD/OS2/LINUX +#elif defined HAVE_STDLIB_H && defined HAVE_SYS_TYPES_H && defined HAVE_SYS_SOCKET_H && defined HAVE_NETINET_IN_H + #define NATIVESOCKETS + #define SOCKET int + #include //darwin + #include //darwin + #include + #include + #include + //socklen_t should be handled by configure +#endif + +#ifdef NATIVESOCKETS + #define CAPWORD (NETWRAPPER_TCP|NETWRAPPER_TCP_NATIVESOCKET) +#else + #define CAPWORD NETWRAPPER_TCP +#endif + +#include "SDL_net.h" + + + Bit32u Netwrapper_GetCapabilities(); @@ -74,6 +98,6 @@ class TCPServerSocket { }; -#endif +#endif //C_MODEM -#endif //#if C_MODEM +#endif //# SDLNETWRAPPER_H diff --git a/src/hardware/serialport/nullmodem.cpp b/src/hardware/serialport/nullmodem.cpp index c0ca3f35..f0853c17 100644 --- a/src/hardware/serialport/nullmodem.cpp +++ b/src/hardware/serialport/nullmodem.cpp @@ -90,6 +90,7 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) { } // socket inheritance if(getBituSubstring("inhsocket:", &bool_temp, cmd)) { +#ifdef NATIVESOCKETS if(Netwrapper_GetCapabilities()&NETWRAPPER_TCP_NATIVESOCKET) { if(bool_temp==1) { int sock; @@ -128,6 +129,7 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) { } } } else { +#endif LOG_MSG("Serial%d: socket inheritance not supported on this platform.", COMNUMBER); return; From c37b2c2eee902865f23face7726e6a42ed6ec89d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 15 May 2007 18:55:23 +0000 Subject: [PATCH 2770/4131] Fix an old bug in goto that prevented having the else on the same line. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2856 --- src/shell/shell_cmds.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 5c020a21..a7bee72a 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.73 2007-01-21 16:18:12 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.74 2007-05-15 18:55:23 qbix79 Exp $ */ #include #include @@ -742,6 +742,13 @@ void DOS_Shell::CMD_GOTO(char * args) { StripSpaces(args); if (!bf) return; if (*args &&(*args==':')) args++; + //label ends at the first space + char* non_space = args; + while (*non_space) { + if((*non_space == ' ') || (*non_space == '\t')) + *non_space = 0; + else non_space++; + } if (!*args) { WriteOut(MSG_Get("SHELL_CMD_GOTO_MISSING_LABEL")); return; From 9a9b883cbf30a2ec32522d232fdc0f0ef684bea3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 23 May 2007 08:05:22 +0000 Subject: [PATCH 2771/4131] Fix compilation problems with winsock Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2857 --- src/hardware/serialport/directserial_win32.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hardware/serialport/directserial_win32.h b/src/hardware/serialport/directserial_win32.h index 225da117..9b978369 100644 --- a/src/hardware/serialport/directserial_win32.h +++ b/src/hardware/serialport/directserial_win32.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_win32.h,v 1.4 2007-01-13 08:35:49 qbix79 Exp $ */ +/* $Id: directserial_win32.h,v 1.5 2007-05-23 08:05:22 qbix79 Exp $ */ // include guard #ifndef DOSBOX_DIRECTSERIAL_WIN32_H @@ -31,6 +31,7 @@ #define DIRECTSERIAL_AVAILIBLE #include "serialport.h" +#include //To prevent compilation problems with windows.h including winsock.h #include class CDirectSerial : public CSerial { From 028f99fb8f74f1b9e2e364175a079ffbff4b8159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 26 May 2007 19:42:09 +0000 Subject: [PATCH 2772/4131] default to automatic hd size detection for disk images; adapt error messages on image load failure a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2858 --- src/dos/dos_programs.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 46dfd857..89152ac6 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.70 2007-04-17 15:48:53 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.71 2007-05-26 19:42:09 c2woody Exp $ */ #include #include @@ -886,7 +886,7 @@ public: Bit8u mediaid; if (type=="floppy" || type=="hdd" || type=="iso") { Bit16u sizes[4]; - bool autosizedetect=false; + bool imgsizedetect=false; std::string str_size; mediaid=0xF8; @@ -900,12 +900,7 @@ public: } cmd->FindString("-size",str_size,true); if ((type=="hdd") && (str_size.size()==0)) { - if (!cmd->FindExist("-autosize",true)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_GEOMETRY")); - return; - } else { - autosizedetect=true; - } + imgsizedetect=true; } else { char number[20]; const char * scan=str_size.c_str(); @@ -992,10 +987,10 @@ public: } if(fstype=="fat") { - if (autosizedetect) { + if (imgsizedetect) { FILE * diskfile = fopen(temp_line.c_str(), "rb+"); if(!diskfile) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_GEOMETRY")); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_INVALID_IMAGE")); return; } fseek(diskfile, 0L, SEEK_END); @@ -1004,17 +999,17 @@ public: fseek(diskfile, 0L, SEEK_SET); if (fread(buf,sizeof(Bit8u),512,diskfile)<512) { fclose(diskfile); - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_GEOMETRY")); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_INVALID_IMAGE")); return; } fclose(diskfile); if ((buf[510]!=0x55) || (buf[511]!=0xaa)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_GEOMETRY")); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_INVALID_GEOMETRY")); return; } Bitu sectors=(Bitu)(fcsize/(16*63)); if (sectors*16*63!=fcsize) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_GEOMETRY")); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_INVALID_GEOMETRY")); return; } sizes[0]=512; sizes[1]=63; sizes[2]=16; sizes[3]=sectors; @@ -1356,6 +1351,10 @@ void DOS_SetupPrograms(void) { "For \033[33mhardrive\033[0m images: Must specify drive geometry for hard drives:\n" "bytes_per_sector, sectors_per_cylinder, heads_per_cylinder, cylinder_count.\n" "\033[34;1mIMGMOUNT drive-letter location-of-image -size bps,spc,hpc,cyl\033[0m\n"); + MSG_Add("PROGRAM_IMGMOUNT_INVALID_IMAGE","Could not load image file.\n" + "Check that the path is correct and the image is accessible.\n"); + MSG_Add("PROGRAM_IMGMOUNT_INVALID_GEOMETRY","Could not extract drive geometry from image.\n" + "Use parameter -size bps,spc,hpc,cyl to specify the geometry.\n"); MSG_Add("PROGRAM_IMGMOUNT_TYPE_UNSUPPORTED","Type \"%s\" is unsupported. Specify \"hdd\" or \"floppy\" or\"iso\".\n"); MSG_Add("PROGRAM_IMGMOUNT_FORMAT_UNSUPPORTED","Format \"%s\" is unsupported. Specify \"fat\" or \"iso\" or \"none\".\n"); MSG_Add("PROGRAM_IMGMOUNT_SPECIFY_FILE","Must specify file-image to mount.\n"); From 784b579c284f0664780737b243421ce06f9eb5a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 27 May 2007 16:11:35 +0000 Subject: [PATCH 2773/4131] use ioctl cdrom access by default if possible Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2859 --- src/dos/dos_programs.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 89152ac6..28c90cca 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.71 2007-05-26 19:42:09 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.72 2007-05-27 16:11:35 c2woody Exp $ */ #include #include @@ -220,9 +220,15 @@ public: int num = -1; cmd->FindInt("-usecd",num,true); int error; - if (cmd->FindExist("-aspi",false)) MSCDEX_SetCDInterface(CDROM_USE_ASPI, num); else - if (cmd->FindExist("-ioctl",false)) MSCDEX_SetCDInterface(CDROM_USE_IOCTL, num); - else MSCDEX_SetCDInterface(CDROM_USE_SDL, num); + if (cmd->FindExist("-aspi",false)) { + MSCDEX_SetCDInterface(CDROM_USE_ASPI, num); + } else if (cmd->FindExist("-ioctl",false)) { + MSCDEX_SetCDInterface(CDROM_USE_IOCTL, num); + } else if (cmd->FindExist("-noioctl",false)) { + MSCDEX_SetCDInterface(CDROM_USE_SDL, num); + } else { + MSCDEX_SetCDInterface(CDROM_USE_IOCTL, num); + } newdrive = new cdromDrive(drive,temp_line.c_str(),sizes[0],bit8size,sizes[2],0,mediaid,error); // Check Mscdex, if it worked out... switch (error) { From 49b1c7254886af5a54c2bed35812b74af1512657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 27 May 2007 20:19:50 +0000 Subject: [PATCH 2774/4131] update readme Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2860 --- README | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/README b/README index fe1606f8..52dca299 100644 --- a/README +++ b/README @@ -53,6 +53,7 @@ Q: The mouse doesn't work. Q: There is no sound. Q: The sound stutters or sounds stretched/weird. Q: I can't type \ or : in DOSBox. +Q: The keyboard lags. Q: The game/application can't find its CD-ROM. Q: The game/application runs much too slow! Q: Can DOSBox harm my computer? @@ -86,10 +87,10 @@ A: Press alt-enter. Alternatively: Edit the configuration file of DOSBox and Q: My CD-ROM doesn't work. A: To mount your CD-ROM in DOSBox you have to specify some additional options when mounting the CD-ROM. - To enable the most basic CD-ROM support: + To enable CD-ROM support: - mount d f:\ -t cdrom To enable low-level SDL-support: - - mount d f:\ -t cdrom -usecd 0 + - mount d f:\ -t cdrom -usecd 0 -noioctl To enable low-level ioctl-support(win2k/xp/linux): - mount d f:\ -t cdrom -usecd 0 -ioctl To enable low-level aspi-support (win98 with aspi-layer installed): @@ -146,6 +147,12 @@ A: This is a known problem. It only occurs if your keyboard layout isn't US. have a bug in the loader routines. +Q: The keyboard lags. +A: Lower the priority setting in the DOSBox configuration file + like set "priority=normal,normal". You might also want to + try lowering the cycles. + + Q: The game/application can't find its CD-ROM. A: Be sure to mount the CD-ROM with -t cdrom switch, this will enable the MSCDEX interface required by DOS games to interface with CD-ROMs. @@ -318,7 +325,7 @@ To get a list of the internal commands type "HELP" at the prompt. In addition, the following commands are available: MOUNT "Emulated Drive letter" "Real Drive or Directory" - [-t type] [-aspi] [-ioctl] [-usecd number] [-size drivesize] + [-t type] [-aspi] [-ioctl] [-noioctl] [-usecd number] [-size drivesize] [-label drivelabel] [-freesize size_in_mb] MOUNT -cd MOUNT -u "Emulated Drive letter" @@ -346,7 +353,8 @@ MOUNT -u "Emulated Drive letter" 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 - lowlevel support is selected (-usecd # and/or -ioctl/aspi): + lowlevel support is selected (that is omitting the -usecd # and/or + -aspi parameters or specifying -noioctl): For win32: label is extracted from "Real Drive". For Linux: label is set to NO_LABEL. @@ -361,6 +369,9 @@ MOUNT -u "Emulated Drive letter" Forces use of ioctl commands. Only valid if mounting a cdrom under a Windows OS which support them (Win2000/XP/NT). + -noioctl + Forces use of the SDL cdrom layer. Valid on all systems. + -usecd number Forces use of SDL cdrom support for drive number. Number can be found by -cd. Valid on all systems. From 89c9f7d9ad54efd4cf7ff34a11018346639ab785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 28 May 2007 16:29:11 +0000 Subject: [PATCH 2775/4131] fix reading vga sequencer data port for invalid indices, thanks to vasyl (see sf bug #1173098); fixes some svga detection routines (Grandest Fleet 2, sf bug #1723717) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2861 --- src/hardware/vga_s3.cpp | 7 ++++++- src/hardware/vga_seq.cpp | 2 -- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index 7bdc3c09..ec418544 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_s3.cpp,v 1.6 2007-01-08 19:45:40 qbix79 Exp $ */ +/* $Id: vga_s3.cpp,v 1.7 2007-05-28 16:29:11 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -375,6 +375,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { } void SVGA_S3_WriteSEQ(Bitu reg,Bitu val,Bitu iolen) { + if (reg>0x8 && vga.s3.pll.lock!=0x6) return; switch (reg) { case 0x08: vga.s3.pll.lock=val; @@ -405,6 +406,10 @@ void SVGA_S3_WriteSEQ(Bitu reg,Bitu val,Bitu iolen) { Bitu SVGA_S3_ReadSEQ(Bitu reg,Bitu iolen) { /* S3 specific group */ + if (reg>0x8 && vga.s3.pll.lock!=0x6) { + if (reg<0x1b) return 0; + else return reg; + } switch (reg) { case 0x08: /* PLL Unlock */ return vga.s3.pll.lock; diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 6ca66344..04d29aa6 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -31,7 +31,6 @@ void write_p3c4(Bitu port,Bitu val,Bitu iolen) { }; void write_p3c5(Bitu port,Bitu val,Bitu iolen) { - if (seq(index)>0x8 && vga.s3.pll.lock!=0x6) return; // LOG_MSG("SEQ WRITE reg %X val %X",seq(index),val); switch(seq(index)) { case 0: /* Reset */ @@ -114,7 +113,6 @@ void write_p3c5(Bitu port,Bitu val,Bitu iolen) { Bitu read_p3c5(Bitu port,Bitu iolen) { // LOG_MSG("VGA:SEQ:Read from index %2X",seq(index)); - if (seq(index)>0x8 && vga.s3.pll.lock!=0x6) return seq(index); switch(seq(index)) { case 0: /* Reset */ return seq(reset); From a9843a9297956857f7b60a412bae1427e8934810 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 29 May 2007 13:36:45 +0000 Subject: [PATCH 2776/4131] Fix jewels of darkness. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2862 --- src/dos/dos_classes.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 089df86c..1a35be3b 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.49 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.50 2007-05-29 13:36:45 qbix79 Exp $ */ #include #include @@ -461,7 +461,7 @@ void DOS_FCB::FileOpen(Bit8u _fhandle) { sSave(sFCB,file_handle,_fhandle); sSave(sFCB,cur_block,0); sSave(sFCB,rec_size,128); - sSave(sFCB,rndm,0); +// sSave(sFCB,rndm,0); // breaks Jewels of darkness. Bit8u temp=RealHandle(_fhandle); sSave(sFCB,filesize,Files[temp]->size); sSave(sFCB,time,Files[temp]->time); From fb1ef3c95d5350781df130d4b2431636fc1d464b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 1 Jun 2007 13:47:28 +0000 Subject: [PATCH 2777/4131] Prepare config.h for dynrec cpu core. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2863 --- configure.in | 60 ++++++++++++++++++++++++++--------- src/platform/visualc/config.h | 8 +++-- 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/configure.in b/configure.in index 13fea9ce..722ba7bb 100644 --- a/configure.in +++ b/configure.in @@ -20,7 +20,7 @@ AC_PROG_INSTALL AC_PROG_RANLIB dnl Some needed libaries for OS2 -dnl perharps join this with the other host depended checks. move them upwards +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" @@ -182,29 +182,35 @@ AC_ARG_ENABLE(core-inline,AC_HELP_STRING([--enable-core-inline],[Enable inlined dnl The target cpu checks for dynamic cores -AH_TEMPLATE(C_HOSTCPU,[The type of cpu this host has]) +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_HOSTCPU,X86) + AC_DEFINE(C_TARGETCPU,X86) AC_MSG_RESULT(x86 compatible) - c_hostcpu="x86" + c_targetcpu="x86" c_unalignedmemory=yes ;; powerpc*) - AC_DEFINE(C_HOSTCPU,POWERPC) + AC_DEFINE(C_TARGETCPU,POWERPC) AC_MSG_RESULT(Power PC) - c_hostcpu="powerpc" + c_targetcpu="powerpc" c_unalignedmemory=yes ;; m68k*) - AC_DEFINE(C_HOSTCPU,M68K) + AC_DEFINE(C_TARGETCPU,M68K) AC_MSG_RESULT(Motorola 68000) - c_hostcpu="m68k" + c_targetcpu="m68k" c_unalignedmemory=yes ;; *) - AC_DEFINE(C_HOSTCPU,UNKOWN) + AC_DEFINE(C_TARGETCPU,UNKNOWN) AC_MSG_RESULT(unknown) c_unalignedmemory=no ;; @@ -216,7 +222,7 @@ AC_MSG_CHECKING(whether x86 dynamic cpu core will be enabled) if test x$enable_dynamic_x86 = xno ; then AC_MSG_RESULT(no) else - if test x$c_hostcpu = xx86 ; then + if test x$c_targetcpu = xx86 ; then AC_DEFINE(C_DYNAMIC_X86,1) AC_MSG_RESULT(yes) else @@ -224,6 +230,30 @@ else 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 ; 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) @@ -241,7 +271,7 @@ if test x$enable_fpu_x86 = xno ; then AC_MSG_RESULT(no) else if test x$enable_fpu = xyes; then - if test x$c_hostcpu = xx86 ; then + if test x$c_targetcpu = xx86 ; then AC_DEFINE(C_FPU_X86,1) AC_MSG_RESULT(yes) else @@ -296,6 +326,9 @@ else 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 @@ -306,9 +339,6 @@ case "$target" in AC_DEFINE(C_OPENGL,1) ;; *) - 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 , ) if test x$have_gl_h = xyes -a x$have_gl_lib = xyes ; then AC_MSG_RESULT(yes) LIBS="$LIBS -lGL" @@ -356,7 +386,7 @@ int main(int argc,char * argv[]) { ],AC_MSG_RESULT(yes);AC_DEFINE(C_SET_PRIORITY,1),AC_MSG_RESULT(no)) -dnl Some host detection and actions for them +dnl Some target detection and actions for them case "$target" in *-*-cygwin* | *-*-mingw32*) LIBS="$LIBS -lwinmm" diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 45cfa5b0..088d23a1 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -4,7 +4,7 @@ /* Define to 1 to enable internal debugger, requires libcurses */ -#define C_DEBUG 1 +#define C_DEBUG 0 /* Define to 1 to enable screenshots, requires libpng */ #define C_SSHOT 1 @@ -22,11 +22,15 @@ #define C_HEAVY_DEBUG 0 /* The type of cpu this host has */ -#define C_HOSTCPU X86 +#define C_TARGETCPU X86 +//#define C_TARGETCPU X86_64 /* Define to 1 to use x86 dynamic cpu core */ #define C_DYNAMIC_X86 1 +/* Define to 1 to use recompiling cpu core. Can not be used together with the dynamic-x86 core */ +#define C_DYNREC 0 + /* Enable memory function inlining in */ #define C_CORE_INLINE 0 From 43de744e01d213180a75def4b0d07fc808e75b81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 1 Jun 2007 16:40:40 +0000 Subject: [PATCH 2778/4131] move some FillFlags calls into their respective cpu function; change some cpu functions to directly return values Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2864 --- include/cpu.h | 14 +++++---- src/cpu/core_full/load.h | 5 --- src/cpu/core_full/loadwrite.h | 1 - src/cpu/core_full/op.h | 46 +++++++--------------------- src/cpu/core_normal/prefix_0f.h | 27 ++++++---------- src/cpu/core_normal/prefix_66.h | 4 --- src/cpu/core_normal/prefix_66_0f.h | 27 ++++++---------- src/cpu/core_normal/prefix_none.h | 10 ++---- src/cpu/core_normal/support.h | 1 - src/cpu/cpu.cpp | 49 +++++++++++++++++++++--------- src/cpu/flags.cpp | 21 +++++++------ src/cpu/lazyflags.h | 13 ++++---- src/debug/debug.cpp | 7 ++--- src/hardware/iohandler.cpp | 8 +---- 14 files changed, 99 insertions(+), 134 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 16e0d4ca..430e1821 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -68,10 +68,12 @@ bool CPU_LTR(Bitu selector); void CPU_LIDT(Bitu limit,Bitu base); void CPU_LGDT(Bitu limit,Bitu base); -void CPU_STR(Bitu & selector); -void CPU_SLDT(Bitu & selector); -void CPU_SIDT(Bitu & limit,Bitu & base); -void CPU_SGDT(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); @@ -88,8 +90,8 @@ bool CPU_READ_DRX(Bitu dr,Bit32u & retvalue); bool CPU_WRITE_TRX(Bitu dr,Bitu value); bool CPU_READ_TRX(Bitu dr,Bit32u & retvalue); -void CPU_SMSW(Bitu & word); -Bitu CPU_LMSW(Bitu word); +Bitu CPU_SMSW(void); +bool CPU_LMSW(Bitu word); void CPU_VERR(Bitu selector); void CPU_VERW(Bitu selector); diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 1f47b886..ec63d572 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -284,14 +284,12 @@ l_M_Ed: inst_op1_d=4; break; case D_IRETw: - FillFlags(); CPU_IRET(false,GetIP()); if (GETFLAG(IF) && PIC_IRQCheck) { return CBRET_NONE; } continue; case D_IRETd: - FillFlags(); CPU_IRET(true,GetIP()); if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; @@ -407,12 +405,10 @@ l_M_Ed: cpu.direction=-1; goto nextopcode; case D_PUSHF: - FillFlags(); if (CPU_PUSHF(inst.code.extra)) RunException(); goto nextopcode; case D_POPF: if (CPU_POPF(inst.code.extra)) RunException(); - lflags.type=t_UNKNOWN; if (GETFLAG(IF) && PIC_IRQCheck) { SaveIP(); return CBRET_NONE; @@ -481,7 +477,6 @@ l_M_Ed: cpu.cr0&=(~CR0_TASKSWITCH); goto nextopcode; case D_ICEBP: - FillFlags(); CPU_SW_Interrupt_NoIOPLCheck(1,GetIP()); continue; default: diff --git a/src/cpu/core_full/loadwrite.h b/src/cpu/core_full/loadwrite.h index 37670d2a..aca53c49 100644 --- a/src/cpu/core_full/loadwrite.h +++ b/src/cpu/core_full/loadwrite.h @@ -3,7 +3,6 @@ #define GetIP() (inst.cseip-SegBase(cs)) #define RunException() { \ - FillFlags(); \ CPU_Exception(cpu.exception.which,cpu.exception.error); \ continue; \ } diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index d7a454f2..ed407a3a 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -338,8 +338,8 @@ switch (inst.code.op) { CPU_JMP(true,inst_op2_d,inst_op1_d,GetIP()); continue; case O_INT: - FillFlags(); #if C_DEBUG + FillFlags(); if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint()) return debugCallback; else if (DEBUG_IntBreakpoint(inst_op1_b)) @@ -379,18 +379,10 @@ switch (inst.code.op) { if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode; switch (inst.rm_index) { case 0x00: /* SLDT */ - { - Bitu selector; - CPU_SLDT(selector); - inst_op1_d=(Bit32u)selector; - } + inst_op1_d=(Bit32u)CPU_SLDT(); break; case 0x01: /* STR */ - { - Bitu selector; - CPU_STR(selector); - inst_op1_d=(Bit32u)selector; - } + inst_op1_d=(Bit32u)CPU_STR(); break; case 0x02: /* LLDT */ if (cpu.cpl) EXCEPTION(EXCEPTION_GP); @@ -401,11 +393,9 @@ switch (inst.code.op) { if (CPU_LTR(inst_op1_d)) RunException(); goto nextopcode; /* Else value will saved */ case 0x04: /* VERR */ - FillFlags(); CPU_VERR(inst_op1_d); goto nextopcode; /* Else value will saved */ case 0x05: /* VERW */ - FillFlags(); CPU_VERW(inst_op1_d); goto nextopcode; /* Else value will saved */ default: @@ -417,21 +407,13 @@ switch (inst.code.op) { case O_GRP7d: switch (inst.rm_index) { case 0: /* SGDT */ - { - Bitu limit,base; - CPU_SGDT(limit,base); - SaveMw(inst.rm_eaa,limit); - SaveMd(inst.rm_eaa+2,base); - goto nextopcode; - } + SaveMw(inst.rm_eaa,CPU_SGDT_limit()); + SaveMd(inst.rm_eaa+2,CPU_SGDT_base()); + goto nextopcode; case 1: /* SIDT */ - { - Bitu limit,base; - CPU_SIDT(limit,base); - SaveMw(inst.rm_eaa,limit); - SaveMd(inst.rm_eaa+2,base); - goto nextopcode; - } + SaveMw(inst.rm_eaa,CPU_SIDT_limit()); + SaveMd(inst.rm_eaa+2,CPU_SIDT_base()); + goto nextopcode; case 2: /* LGDT */ if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); CPU_LGDT(LoadMw(inst.rm_eaa),LoadMd(inst.rm_eaa+2)&((inst.code.op == O_GRP7w) ? 0xFFFFFF : 0xFFFFFFFF)); @@ -441,11 +423,8 @@ switch (inst.code.op) { CPU_LIDT(LoadMw(inst.rm_eaa),LoadMd(inst.rm_eaa+2)&((inst.code.op == O_GRP7w) ? 0xFFFFFF : 0xFFFFFFFF)); goto nextopcode; case 4: /* SMSW */ - { - Bitu word;CPU_SMSW(word); - inst_op1_d=word; - break; - } + inst_op1_d=CPU_SMSW(); + break; case 6: /* LMSW */ FillFlags(); if (CPU_LMSW(inst_op1_w)) RunException(); @@ -481,7 +460,6 @@ switch (inst.code.op) { case O_LAR: { if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode; - FillFlags(); Bitu ar=inst_op2_d; CPU_LAR(inst_op1_w,ar); inst_op1_d=(Bit32u)ar; @@ -490,7 +468,6 @@ switch (inst.code.op) { case O_LSL: { if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode; - FillFlags(); Bitu limit=inst_op2_d; CPU_LSL(inst_op1_w,limit); inst_op1_d=(Bit32u)limit; @@ -499,7 +476,6 @@ switch (inst.code.op) { case O_ARPL: { if ((reg_flags & FLAG_VM) || !cpu.pmode) goto illegalopcode; - FillFlags(); Bitu new_sel=inst_op1_d; CPU_ARPL(new_sel,inst_op2_d); inst_op1_d=(Bit32u)new_sel; diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 59244371..086771b7 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -25,15 +25,14 @@ case 0x01: /* STR */ { Bitu saveval; - if (!which) CPU_SLDT(saveval); - else CPU_STR(saveval); + if (!which) saveval=CPU_SLDT(); + else saveval=CPU_STR(); if (rm >= 0xc0) {GetEArw;*earw=saveval;} else {GetEAa;SaveMw(eaa,saveval);} } break; case 0x02:case 0x03:case 0x04:case 0x05: { - FillFlags(); Bitu loadval; if (rm >= 0xc0 ) {GetEArw;loadval=*earw;} else {GetEAa;loadval=LoadMw(eaa);} @@ -64,17 +63,15 @@ { GetRM;Bitu which=(rm>>3)&7; if (rm < 0xc0) { //First ones all use EA - GetEAa;Bitu limit,base; + GetEAa;Bitu limit; switch (which) { case 0x00: /* SGDT */ - CPU_SGDT(limit,base); - SaveMw(eaa,limit); - SaveMd(eaa+2,base); + SaveMw(eaa,CPU_SGDT_limit()); + SaveMd(eaa+2,CPU_SGDT_base()); break; case 0x01: /* SIDT */ - CPU_SIDT(limit,base); - SaveMw(eaa,limit); - SaveMd(eaa+2,base); + SaveMw(eaa,CPU_SIDT_limit()); + SaveMd(eaa+2,CPU_SIDT_base()); break; case 0x02: /* LGDT */ if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); @@ -85,8 +82,7 @@ CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF); break; case 0x04: /* SMSW */ - CPU_SMSW(limit); - SaveMw(eaa,limit); + SaveMw(eaa,CPU_SMSW()); break; case 0x06: /* LMSW */ limit=LoadMw(eaa); @@ -98,7 +94,7 @@ break; } } else { - GetEArw;Bitu limit; + GetEArw; switch (which) { case 0x02: /* LGDT */ if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); @@ -107,8 +103,7 @@ if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); goto illegal_opcode; case 0x04: /* SMSW */ - CPU_SMSW(limit); - *earw=limit; + *earw=CPU_SMSW(); break; case 0x06: /* LMSW */ if (CPU_LMSW(*earw)) RUNEXCEPTION(); @@ -122,7 +117,6 @@ CASE_0F_W(0x02) /* LAR Gw,Ew */ { if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - FillFlags(); GetRMrw;Bitu ar=*rmrw; if (rm >= 0xc0) { GetEArw;CPU_LAR(*earw,ar); @@ -135,7 +129,6 @@ CASE_0F_W(0x03) /* LSL Gw,Ew */ { if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - FillFlags(); GetRMrw;Bitu limit=*rmrw; if (rm >= 0xc0) { GetEArw;CPU_LSL(*earw,limit); diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index a76e43fa..f2aef294 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -170,7 +170,6 @@ CASE_D(0x63) /* ARPL Ed,Rd */ { if (((cpu.pmode) && (reg_flags & FLAG_VM)) || (!cpu.pmode)) goto illegal_opcode; - FillFlags(); GetRMrw; if (rm >= 0xc0 ) { GetEArd;Bitu new_sel=(Bit16u)*eard; @@ -398,12 +397,10 @@ continue; } CASE_D(0x9c) /* PUSHFD */ - FillFlags(); if (CPU_PUSHF(true)) RUNEXCEPTION(); break; CASE_D(0x9d) /* POPFD */ if (CPU_POPF(true)) RUNEXCEPTION(); - lflags.type=t_UNKNOWN; #if CPU_TRAP_CHECK if (GETFLAG(TF)) { cpudecoder=CPU_Core_Normal_Trap_Run; @@ -511,7 +508,6 @@ } CASE_D(0xcf) /* IRET */ { - FillFlags(); CPU_IRET(true,GETIP); #if CPU_TRAP_CHECK if (GETFLAG(TF)) { diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 3022ba58..8c00c268 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -25,8 +25,8 @@ case 0x01: /* STR */ { Bitu saveval; - if (!which) CPU_SLDT(saveval); - else CPU_STR(saveval); + if (!which) saveval=CPU_SLDT(); + else saveval=CPU_STR(); if (rm >= 0xc0) {GetEArw;*earw=(Bit16u)saveval;} else {GetEAa;SaveMw(eaa,saveval);} } @@ -34,7 +34,6 @@ case 0x02:case 0x03:case 0x04:case 0x05: { /* Just use 16-bit loads since were only using selectors */ - FillFlags(); Bitu loadval; if (rm >= 0xc0 ) {GetEArw;loadval=*earw;} else {GetEAa;loadval=LoadMw(eaa);} @@ -66,17 +65,15 @@ { GetRM;Bitu which=(rm>>3)&7; if (rm < 0xc0) { //First ones all use EA - GetEAa;Bitu limit,base; + GetEAa;Bitu limit; switch (which) { case 0x00: /* SGDT */ - CPU_SGDT(limit,base); - SaveMw(eaa,(Bit16u)limit); - SaveMd(eaa+2,(Bit32u)base); + SaveMw(eaa,(Bit16u)CPU_SGDT_limit()); + SaveMd(eaa+2,(Bit32u)CPU_SGDT_base()); break; case 0x01: /* SIDT */ - CPU_SIDT(limit,base); - SaveMw(eaa,(Bit16u)limit); - SaveMd(eaa+2,(Bit32u)base); + SaveMw(eaa,(Bit16u)CPU_SIDT_limit()); + SaveMd(eaa+2,(Bit32u)CPU_SIDT_base()); break; case 0x02: /* LGDT */ if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); @@ -87,8 +84,7 @@ CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2)); break; case 0x04: /* SMSW */ - CPU_SMSW(limit); - SaveMw(eaa,(Bit16u)limit); + SaveMw(eaa,(Bit16u)CPU_SMSW()); break; case 0x06: /* LMSW */ limit=LoadMw(eaa); @@ -100,7 +96,7 @@ break; } } else { - GetEArd;Bitu limit; + GetEArd; switch (which) { case 0x02: /* LGDT */ if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); @@ -109,8 +105,7 @@ if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); goto illegal_opcode; case 0x04: /* SMSW */ - CPU_SMSW(limit); - *eard=(Bit32u)limit; + *eard=(Bit32u)CPU_SMSW(); break; case 0x06: /* LMSW */ if (CPU_LMSW(*eard)) RUNEXCEPTION(); @@ -127,7 +122,6 @@ CASE_0F_D(0x02) /* LAR Gd,Ed */ { if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - FillFlags(); GetRMrd;Bitu ar=*rmrd; if (rm >= 0xc0) { GetEArw;CPU_LAR(*earw,ar); @@ -140,7 +134,6 @@ CASE_0F_D(0x03) /* LSL Gd,Ew */ { if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - FillFlags(); GetRMrd;Bitu limit=*rmrd; /* Just load 16-bit values for selectors */ if (rm >= 0xc0) { diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 36739a3f..9622294f 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -239,7 +239,6 @@ CASE_W(0x63) /* ARPL Ew,Rw */ { if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - FillFlags(); GetRMrw; if (rm >= 0xc0 ) { GetEArw;Bitu new_sel=*earw; @@ -574,12 +573,10 @@ CASE_B(0x9b) /* WAIT */ break; /* No waiting here */ CASE_W(0x9c) /* PUSHF */ - FillFlags(); if (CPU_PUSHF(false)) RUNEXCEPTION(); break; CASE_W(0x9d) /* POPF */ if (CPU_POPF(false)) RUNEXCEPTION(); - lflags.type=t_UNKNOWN; #if CPU_TRAP_CHECK if (GETFLAG(TF)) { cpudecoder=CPU_Core_Normal_Trap_Run; @@ -740,8 +737,8 @@ CPU_RET(false,0,GETIP); continue; CASE_B(0xcc) /* INT3 */ - FillFlags(); #if C_DEBUG + FillFlags(); if (DEBUG_Breakpoint()) return debugCallback; #endif @@ -753,8 +750,8 @@ CASE_B(0xcd) /* INT Ib */ { Bit8u num=Fetchb(); - FillFlags(); #if C_DEBUG + FillFlags(); if (DEBUG_IntBreakpoint(num)) { return debugCallback; } @@ -767,7 +764,6 @@ } CASE_B(0xce) /* INTO */ if (get_OF()) { - FillFlags(); CPU_SW_Interrupt(4,GETIP); #if CPU_TRAP_CHECK cpu.trap_skip=true; @@ -777,7 +773,6 @@ break; CASE_W(0xcf) /* IRET */ { - FillFlags(); CPU_IRET(false,GETIP); #if CPU_TRAP_CHECK if (GETFLAG(TF)) { @@ -953,7 +948,6 @@ LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK"); /* FIXME: see case D_LOCK in core_full/load.h */ break; CASE_B(0xf1) /* ICEBP */ - FillFlags(); CPU_SW_Interrupt_NoIOPLCheck(1,GETIP); #if CPU_TRAP_CHECK cpu.trap_skip=true; diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index 8a789552..65dbfa3e 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -42,7 +42,6 @@ static INLINE Bit32s Fetchds() { #define RUNEXCEPTION() { \ - FillFlags(); \ CPU_Exception(cpu.exception.which,cpu.exception.error); \ continue; \ } diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index d7a77c33..ba6e72a7 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.99 2007-04-14 11:16:29 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.100 2007-06-01 16:40:40 c2woody Exp $ */ #include #include @@ -27,6 +27,7 @@ #include "mapper.h" #include "setup.h" #include "paging.h" +#include "lazyflags.h" #include "support.h" Bitu DEBUG_EnableDebugger(void); @@ -62,10 +63,12 @@ Bitu CPU_AutoDetermineMode; void CPU_Core_Full_Init(void); void CPU_Core_Normal_Init(void); void CPU_Core_Simple_Init(void); +#if (C_DYNAMIC_X86) void CPU_Core_Dyn_X86_Init(void); void CPU_Core_Dyn_X86_Cache_Init(bool enable_cache); void CPU_Core_Dyn_X86_Cache_Close(void); void CPU_Core_Dyn_X86_SetFPUMode(bool dh_fpu); +#endif /* In debug mode exceptions are tested and dosbox exits when * a unhandled exception state is detected. @@ -178,6 +181,7 @@ bool CPU_POPF(Bitu use32) { if (use32) CPU_SetFlags(CPU_Pop32(),mask); else CPU_SetFlags(CPU_Pop16(),mask & 0xffff); + DestroyConditionFlags(); return false; } @@ -186,6 +190,7 @@ bool CPU_PUSHF(Bitu use32) { /* Not enough privileges to execute PUSHF */ return CPU_PrepareException(EXCEPTION_GP,0); } + FillFlags(); if (use32) CPU_Push32(reg_flags & 0xfcffff); else CPU_Push16(reg_flags); @@ -258,6 +263,7 @@ enum TSwitchType { }; bool CPU_SwitchTask(Bitu new_tss_selector,TSwitchType tstype,Bitu old_eip) { + FillFlags(); TaskStateSegment new_tss; if (!new_tss.SetSelector(new_tss_selector)) E_Exit("Illegal TSS for switch, selector=%x, switchtype=%x",new_tss_selector,tstype); @@ -447,6 +453,7 @@ void CPU_Exception(Bitu which,Bitu error ) { Bit8u lastint; void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { lastint=num; + FillFlags(); #if C_DEBUG switch (num) { case 0xcd: @@ -666,6 +673,7 @@ void CPU_IRET(bool use32,Bitu oldeip) { CPU_SetFlags(CPU_Pop16(),FMASK_ALL & 0xffff); } cpu.code.big=false; + DestroyConditionFlags(); return; } else { /* Protected mode IRET */ if (reg_flags & FLAG_VM) { @@ -686,6 +694,7 @@ void CPU_IRET(bool use32,Bitu oldeip) { CPU_SetFlags(CPU_Pop16(),FMASK_NORMAL|FLAG_NT); } cpu.code.big=false; + DestroyConditionFlags(); return; } } @@ -717,6 +726,7 @@ void CPU_IRET(bool use32,Bitu oldeip) { n_gs=CPU_Pop32() & 0xffff; CPU_SetFlags(n_flags,FMASK_ALL | FLAG_VM); + DestroyConditionFlags(); cpu.cpl=3; CPU_SetSegGeneral(ss,n_ss); @@ -779,6 +789,7 @@ void CPU_IRET(bool use32,Bitu oldeip) { Bitu mask=cpu.cpl ? (FMASK_NORMAL | FLAG_NT) : FMASK_ALL; if (GETFLAG_IOPL0)) return CPU_PrepareException(EXCEPTION_GP,0); word&=0xf; if (cpu.cr0 & 1) word|=1; @@ -1624,6 +1640,7 @@ Bitu CPU_LMSW(Bitu word) { } void CPU_ARPL(Bitu & dest_sel,Bitu src_sel) { + FillFlags(); if ((dest_sel & 3) < (src_sel & 3)) { dest_sel=(dest_sel & 0xfffc) + (src_sel & 3); // dest_sel|=0xff3f0000; @@ -1634,6 +1651,7 @@ void CPU_ARPL(Bitu & dest_sel,Bitu src_sel) { } void CPU_LAR(Bitu selector,Bitu & ar) { + FillFlags(); if (selector == 0) { SETFLAGBIT(ZF,false); return; @@ -1685,6 +1703,7 @@ void CPU_LAR(Bitu selector,Bitu & ar) { } void CPU_LSL(Bitu selector,Bitu & limit) { + FillFlags(); if (selector == 0) { SETFLAGBIT(ZF,false); return; @@ -1727,6 +1746,7 @@ void CPU_LSL(Bitu selector,Bitu & limit) { } void CPU_VERR(Bitu selector) { + FillFlags(); if (selector == 0) { SETFLAGBIT(ZF,false); return; @@ -1759,6 +1779,7 @@ void CPU_VERR(Bitu selector) { } void CPU_VERW(Bitu selector) { + FillFlags(); if (selector == 0) { SETFLAGBIT(ZF,false); return; diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index b6830206..f56b876e 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -31,7 +31,7 @@ LazyFlags lflags; /* CF Carry Flag -- Set on high-order bit carry or borrow; cleared otherwise. */ -Bitu get_CF(void) { +Bit32u get_CF(void) { switch (lflags.type) { case t_UNKNOWN: @@ -43,7 +43,6 @@ Bitu get_CF(void) { case t_DECd: case t_MUL: return GETFLAG(CF); - break; case t_ADDb: return (lf_resb #include "dosbox.h" @@ -227,7 +227,6 @@ void IO_WriteB(Bitu port,Bitu val) { RealPt icb = CALLBACK_RealPointer(call_priv_io); SegSet16(cs,RealSeg(icb)); reg_eip = RealOff(icb)+0x08; - FillFlags(); CPU_Exception(cpu.exception.which,cpu.exception.error); DOSBOX_RunMachine(); @@ -263,7 +262,6 @@ void IO_WriteW(Bitu port,Bitu val) { RealPt icb = CALLBACK_RealPointer(call_priv_io); SegSet16(cs,RealSeg(icb)); reg_eip = RealOff(icb)+0x0a; - FillFlags(); CPU_Exception(cpu.exception.which,cpu.exception.error); DOSBOX_RunMachine(); @@ -299,7 +297,6 @@ void IO_WriteD(Bitu port,Bitu val) { RealPt icb = CALLBACK_RealPointer(call_priv_io); SegSet16(cs,RealSeg(icb)); reg_eip = RealOff(icb)+0x0c; - FillFlags(); CPU_Exception(cpu.exception.which,cpu.exception.error); DOSBOX_RunMachine(); @@ -330,7 +327,6 @@ Bitu IO_ReadB(Bitu port) { RealPt icb = CALLBACK_RealPointer(call_priv_io); SegSet16(cs,RealSeg(icb)); reg_eip = RealOff(icb)+0x00; - FillFlags(); CPU_Exception(cpu.exception.which,cpu.exception.error); DOSBOX_RunMachine(); @@ -366,7 +362,6 @@ Bitu IO_ReadW(Bitu port) { RealPt icb = CALLBACK_RealPointer(call_priv_io); SegSet16(cs,RealSeg(icb)); reg_eip = RealOff(icb)+0x02; - FillFlags(); CPU_Exception(cpu.exception.which,cpu.exception.error); DOSBOX_RunMachine(); @@ -402,7 +397,6 @@ Bitu IO_ReadD(Bitu port) { RealPt icb = CALLBACK_RealPointer(call_priv_io); SegSet16(cs,RealSeg(icb)); reg_eip = RealOff(icb)+0x04; - FillFlags(); CPU_Exception(cpu.exception.which,cpu.exception.error); DOSBOX_RunMachine(); From f65e8e5f09417c48476deee2bb7ebb54223e634b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 2 Jun 2007 11:47:06 +0000 Subject: [PATCH 2779/4131] add recompiling core that uses highlevel function calls and the existing lazyflags system for better portability; thanks to gulikoza for the x86_64 backend Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2865 --- configure.in | 1 + include/cpu.h | 2 + src/cpu/Makefile.am | 4 +- src/cpu/core_dynrec.cpp | 314 +++++ src/cpu/core_dynrec/Makefile.am | 2 + src/cpu/core_dynrec/cache.h | 633 +++++++++ src/cpu/core_dynrec/decoder.h | 582 ++++++++ src/cpu/core_dynrec/decoder_basic.h | 1091 +++++++++++++++ src/cpu/core_dynrec/decoder_opcodes.h | 1415 +++++++++++++++++++ src/cpu/core_dynrec/dyn_fpu.h | 679 +++++++++ src/cpu/core_dynrec/operators.h | 1812 +++++++++++++++++++++++++ src/cpu/core_dynrec/risc_x64.h | 631 +++++++++ src/cpu/core_dynrec/risc_x86.h | 427 ++++++ src/cpu/cpu.cpp | 16 +- visualc_net/dosbox.vcproj | 31 + 15 files changed, 7637 insertions(+), 3 deletions(-) create mode 100644 src/cpu/core_dynrec.cpp create mode 100644 src/cpu/core_dynrec/Makefile.am create mode 100644 src/cpu/core_dynrec/cache.h create mode 100644 src/cpu/core_dynrec/decoder.h create mode 100644 src/cpu/core_dynrec/decoder_basic.h create mode 100644 src/cpu/core_dynrec/decoder_opcodes.h create mode 100644 src/cpu/core_dynrec/dyn_fpu.h create mode 100644 src/cpu/core_dynrec/operators.h create mode 100644 src/cpu/core_dynrec/risc_x64.h create mode 100644 src/cpu/core_dynrec/risc_x86.h diff --git a/configure.in b/configure.in index 722ba7bb..39207092 100644 --- a/configure.in +++ b/configure.in @@ -435,6 +435,7 @@ src/cpu/Makefile src/cpu/core_full/Makefile src/cpu/core_normal/Makefile src/cpu/core_dyn_x86/Makefile +src/cpu/core_dynrec/Makefile src/debug/Makefile src/dos/Makefile src/fpu/Makefile diff --git a/include/cpu.h b/include/cpu.h index 430e1821..fd868341 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -58,6 +58,8 @@ 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); //CPU Stuff diff --git a/src/cpu/Makefile.am b/src/cpu/Makefile.am index 62cc988d..0d6c542f 100644 --- a/src/cpu/Makefile.am +++ b/src/cpu/Makefile.am @@ -1,7 +1,7 @@ -SUBDIRS = core_full core_normal core_dyn_x86 +SUBDIRS = core_full core_normal core_dyn_x86 core_dynrec AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libcpu.a libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h core_full.cpp instructions.h \ paging.cpp lazyflags.h core_normal.cpp core_simple.cpp \ - core_dyn_x86.cpp \ No newline at end of file + core_dyn_x86.cpp core_dynrec.cpp diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp new file mode 100644 index 00000000..e73b8b2b --- /dev/null +++ b/src/cpu/core_dynrec.cpp @@ -0,0 +1,314 @@ +/* + * Copyright (C) 2002-2006 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_DYNREC) + +#include +#include +#include +#include +#include +#include + +#if (C_HAVE_MPROTECT) +#include + +#include +#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" + +#define CACHE_MAXSIZE (4096) +#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(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 + +#if C_TARGETCPU == X86_64 +#include "core_dynrec/risc_x64.h" +#elif C_TARGETCPU == X86 +#include "core_dynrec/risc_x86.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; + Bitu temp_page=temp_ip >> 12; + CodePageHandlerDynRec * temp_handler=(CodePageHandlerDynRec *)paging.tlb.handler[temp_page]; + 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 diff --git a/src/cpu/core_dynrec/Makefile.am b/src/cpu/core_dynrec/Makefile.am new file mode 100644 index 00000000..ad75110f --- /dev/null +++ b/src/cpu/core_dynrec/Makefile.am @@ -0,0 +1,2 @@ +noinst_HEADERS = cache.h decoder.h decoder_basic.h decoder_opcodes.h \ + dyn_fpu.h operators.h risc_x64.h risc_x86.h \ No newline at end of file diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h new file mode 100644 index 00000000..f0517150 --- /dev/null +++ b/src/cpu/core_dynrec/cache.h @@ -0,0 +1,633 @@ +/* + * Copyright (C) 2002-2006 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; + +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.tlb.phys_page[ip_point>>12]-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 (!*(Bit8u*)&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 (!*(Bit16u*)&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); + } + (*(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); + // see if there's code where we are writing to + if (!*(Bit32u*)&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); + } + (*(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; + // see if there's code where we are writing to + if (!*(Bit8u*)&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 (!*(Bit16u*)&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); + } + (*(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; + // see if there's code where we are writing to + if (!*(Bit32u*)&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); + } + (*(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; + } + + // 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;icache.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 (sizecache.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) { +// 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); + +// 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; + +/* 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;icache.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;inext=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) { + free(cache_code_start_ptr); + cache_code_start_ptr = NULL; + } + cache_code = NULL; + cache_code_link_blocks = NULL; + cache_initialized = false; */ +} diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h new file mode 100644 index 00000000..ffa6faa3 --- /dev/null +++ b/src/cpu/core_dynrec/decoder.h @@ -0,0 +1,582 @@ +/* + * Copyright (C) 2002-2006 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 "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; + + case 0xb4:dyn_load_seg_off_ea(DRC_SEG_FS);break; + case 0xb5: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_get_modrm(); + dyn_fill_ea(FC_ADDR,false); + gen_mov_word_from_reg(FC_ADDR,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + 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; + + case 0xc4:dyn_load_seg_off_ea(DRC_SEG_ES);break; + case 0xc5: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); + if (cpu.pmode) dyn_check_exception(FC_RETOP); + break; + case 0xfb: //STI + gen_call_function_raw((void *)&CPU_STI); + if (cpu.pmode) 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; +} diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h new file mode 100644 index 00000000..ebef1cb7 --- /dev/null +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -0,0 +1,1091 @@ +/* + * Copyright (C) 2002-2006 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. + */ + + +/* + This file provides some definitions and basic level functions + that use code generating functions from risc_?.h + Important is the function call generation including parameter + loading, the effective address calculation and the memory + access functions. +*/ + + +// instructions that use one operand +enum SingleOps { + SOP_INC,SOP_DEC, + SOP_NOT,SOP_NEG, +}; + +// instructions that use two operand +enum DualOps { + DOP_ADD,DOP_ADC, + DOP_SUB,DOP_SBB, + DOP_CMP,DOP_XOR, + DOP_AND,DOP_OR, + DOP_TEST, + DOP_MOV, + DOP_XCHG, +}; + +// shift and rotate functions +enum ShiftOps { + SHIFT_ROL,SHIFT_ROR, + SHIFT_RCL,SHIFT_RCR, + SHIFT_SHL,SHIFT_SHR, + SHIFT_SAL,SHIFT_SAR, +}; + +// branch conditions +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 +}; + +// string instructions +enum StringOps { + 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, +}; + +// repeat prefix type (for string operations) +enum REP_Type { + REP_NONE=0,REP_NZ,REP_Z +}; + +// loop type +enum LoopTypes { + LOOP_NONE,LOOP_NE,LOOP_E,LOOP_JCXZ +}; + +// rotate operand type +enum grp2_types { + grp2_1,grp2_imm,grp2_cl, +}; + +// opcode mapping for group1 instructions +static DualOps grp1_table[8]={ + DOP_ADD,DOP_OR,DOP_ADC,DOP_SBB,DOP_AND,DOP_SUB,DOP_XOR,DOP_CMP +}; + + +// decoding information used during translation of a code block +static struct DynDecode { + PhysPt code; // pointer to next byte in the instruction stream + PhysPt code_start; // pointer to the start of the current code block + PhysPt op_start; // pointer to the start of the current instruction + bool big_op; // operand modifier + bool big_addr; // address modifier + REP_Type rep; // current repeat prefix + Bitu cycles; // number cycles used by currently translated code + bool seg_prefix_used; // segment overridden + Bit8u seg_prefix; // segment prefix (if seg_prefix_used==true) + + // block that contains the first instruction translated + CacheBlockDynRec * block; + // block that contains the current byte of the instruction stream + CacheBlockDynRec * active_block; + + // the active page (containing the current byte of the instruction stream) + struct { + CodePageHandlerDynRec * code; + Bitu index; // index to the current byte of the instruction stream + Bit8u * wmap; // write map that indicates code presence for every byte of this page + Bit8u * invmap; // invalidation map + Bitu first; // page number + } page; + + // modrm state of the current instruction (if used) + struct { + Bitu val; + Bitu mod; + Bitu rm; + Bitu reg; + } modrm; +} decode; + + +static bool MakeCodePage(Bitu lin_addr,CodePageHandlerDynRec * &cph) { + Bit8u rdval; + //Ensure page contains memory: + if (GCC_UNLIKELY(mem_readb_checked_x86(lin_addr,&rdval))) return true; + + Bitu lin_page=lin_addr >> 12; + + PageHandler * handler=paging.tlb.handler[lin_page]; + if (handler->flags & PFLAG_HASCODE) { + // this is a codepage handler, and the one that we're looking for + cph=(CodePageHandlerDynRec *)handler; + return false; + } + if (handler->flags & PFLAG_NOCODE) { + LOG_MSG("DYNREC:Can't run code in this page"); + cph=0; + return false; + } + Bitu phys_page=lin_page; + // find the physical page that the linear page is mapped to + if (!PAGING_MakePhysPage(phys_page)) { + LOG_MSG("DYNREC:Can't find physpage"); + cph=0; + return false; + } + // find a free CodePage + if (!cache.free_pages) { + if (cache.used_pages!=decode.page.code) cache.used_pages->ClearRelease(); + else { + // try another page to avoid clearing our source-crosspage + if ((cache.used_pages->next) && (cache.used_pages->next!=decode.page.code)) + cache.used_pages->next->ClearRelease(); + else { + LOG_MSG("DYNREC:Invalid cache links"); + cache.used_pages->ClearRelease(); + } + } + } + CodePageHandlerDynRec * cpagehandler=cache.free_pages; + cache.free_pages=cache.free_pages->next; + + // adjust previous and next page pointer + cpagehandler->prev=cache.last_page; + cpagehandler->next=0; + if (cache.last_page) cache.last_page->next=cpagehandler; + cache.last_page=cpagehandler; + if (!cache.used_pages) cache.used_pages=cpagehandler; + + // initialize the code page handler and add the handler to the memory page + cpagehandler->SetupAt(phys_page,handler); + MEM_SetPageHandler(phys_page,1,cpagehandler); + PAGING_UnlinkPages(lin_page,1); + cph=cpagehandler; + return false; +} + +static void decode_advancepage(void) { + // Advance to the next page + decode.active_block->page.end=4095; + // trigger possible page fault here + decode.page.first++; + Bitu faddr=decode.page.first << 12; + mem_readb(faddr); + MakeCodePage(faddr,decode.page.code); + CacheBlockDynRec * newblock=cache_getblock(); + decode.active_block->crossblock=newblock; + newblock->crossblock=decode.active_block; + decode.active_block=newblock; + decode.active_block->page.start=0; + decode.page.code->AddCrossBlock(decode.active_block); + decode.page.wmap=decode.page.code->write_map; + decode.page.invmap=decode.page.code->invalidation_map; + decode.page.index=0; +} + +// fetch the next byte of the instruction stream +static Bit8u decode_fetchb(void) { + if (GCC_UNLIKELY(decode.page.index>=4096)) { + decode_advancepage(); + } + decode.page.wmap[decode.page.index]+=0x01; + decode.page.index++; + decode.code+=1; + return mem_readb(decode.code-1); +} +// fetch the next word of the instruction stream +static Bit16u decode_fetchw(void) { + if (GCC_UNLIKELY(decode.page.index>=4095)) { + Bit16u val=decode_fetchb(); + val|=decode_fetchb() << 8; + return val; + } + *(Bit16u *)&decode.page.wmap[decode.page.index]+=0x0101; + decode.code+=2;decode.page.index+=2; + return mem_readw(decode.code-2); +} +// fetch the next dword of the instruction stream +static Bit32u decode_fetchd(void) { + if (GCC_UNLIKELY(decode.page.index>=4093)) { + Bit32u val=decode_fetchb(); + val|=decode_fetchb() << 8; + val|=decode_fetchb() << 16; + val|=decode_fetchb() << 24; + return val; + /* Advance to the next page */ + } + *(Bit32u *)&decode.page.wmap[decode.page.index]+=0x01010101; + decode.code+=4;decode.page.index+=4; + return mem_readd(decode.code-4); +} + +#define START_WMMEM 64 + +// adjust writemap mask to care for map holes due to special +// codefetch functions +static void INLINE decode_increase_wmapmask(Bitu size) { + Bitu mapidx; + CacheBlockDynRec* activecb=decode.active_block; + if (GCC_UNLIKELY(!activecb->cache.wmapmask)) { + // no mask memory yet allocated, start with a small buffer + activecb->cache.wmapmask=(Bit8u*)malloc(START_WMMEM); + memset(activecb->cache.wmapmask,0,START_WMMEM); + activecb->cache.maskstart=decode.page.index; // start of buffer is current code position + activecb->cache.masklen=START_WMMEM; + mapidx=0; + } else { + mapidx=decode.page.index-activecb->cache.maskstart; + if (GCC_UNLIKELY(mapidx+size>=activecb->cache.masklen)) { + // mask buffer too small, increase + Bitu newmasklen=activecb->cache.masklen*4; + if (newmasklencache.wmapmask,activecb->cache.masklen); + free(activecb->cache.wmapmask); + activecb->cache.wmapmask=tempmem; + activecb->cache.masklen=newmasklen; + } + } + // update mask entries + switch (size) { + case 1 : activecb->cache.wmapmask[mapidx]+=0x01; break; + case 2 : (*(Bit16u*)&activecb->cache.wmapmask[mapidx])+=0x0101; break; + case 4 : (*(Bit32u*)&activecb->cache.wmapmask[mapidx])+=0x01010101; break; + } +} + +// fetch a byte, val points to the code location if possible, +// otherwise val contains the current value read from the position +static bool decode_fetchb_imm(Bitu & val) { + if (GCC_UNLIKELY(decode.page.index>=4096)) { + decode_advancepage(); + } + Bitu index=(decode.code>>12); + // see if position is directly accessible + if (paging.tlb.read[index]) { + val=(Bitu)(paging.tlb.read[index]+decode.code); + decode_increase_wmapmask(1); + decode.code++; + decode.page.index++; + return true; + } + // not directly accessible, just fetch the value + val=(Bit32u)decode_fetchb(); + return false; +} + +// fetch a word, val points to the code location if possible, +// otherwise val contains the current value read from the position +static bool decode_fetchw_imm(Bitu & val) { + if (decode.page.index<4095) { + Bitu index=(decode.code>>12); + // see if position is directly accessible + if (paging.tlb.read[index]) { + val=(Bitu)(paging.tlb.read[index]+decode.code); + decode_increase_wmapmask(2); + decode.code+=2; + decode.page.index+=2; + return true; + } + } + // not directly accessible, just fetch the value + val=decode_fetchw(); + return false; +} + +// fetch a dword, val points to the code location if possible, +// otherwise val contains the current value read from the position +static bool decode_fetchd_imm(Bitu & val) { + if (decode.page.index<4093) { + Bitu index=(decode.code>>12); + // see if position is directly accessible + if (paging.tlb.read[index]) { + val=(Bitu)(paging.tlb.read[index]+decode.code); + decode_increase_wmapmask(4); + decode.code+=4; + decode.page.index+=4; + return true; + } + } + // not directly accessible, just fetch the value + val=decode_fetchd(); + return false; +} + + +// modrm decoding helper +static void INLINE dyn_get_modrm(void) { + decode.modrm.val=decode_fetchb(); + decode.modrm.mod=(decode.modrm.val >> 6) & 3; + decode.modrm.reg=(decode.modrm.val >> 3) & 7; + decode.modrm.rm=(decode.modrm.val & 7); +} + + + +// adjust CPU_Cycles value +static void dyn_reduce_cycles(void) { + if (!decode.cycles) decode.cycles++; + gen_sub_direct_word(&CPU_Cycles,decode.cycles,true); +} + + +// set reg to the start of the next instruction +// set reg_eip to the start of the current instruction +static INLINE void dyn_set_eip_last_end(HostReg reg) { + gen_mov_word_to_reg(reg,®_eip,true); + gen_add_imm(reg,(Bit32u)(decode.code-decode.code_start)); + gen_add_direct_word(®_eip,decode.op_start-decode.code_start,decode.big_op); +} + +// set reg_eip to the start of the current instruction +static INLINE void dyn_set_eip_last(void) { + gen_add_direct_word(®_eip,decode.op_start-decode.code_start,cpu.code.big); +} + +// set reg_eip to the start of the next instruction +static INLINE void dyn_set_eip_end(void) { + gen_add_direct_word(®_eip,decode.code-decode.code_start,cpu.code.big); +} + +// set reg_eip to the start of the next instruction plus an offset (imm) +static INLINE void dyn_set_eip_end(HostReg reg,Bit32u imm=0) { + gen_mov_word_to_reg(reg,®_eip,decode.big_op); + gen_add_imm(reg,(Bit32u)(decode.code-decode.code_start+imm)); + if (!decode.big_op) gen_extend_word(false,reg); +} + + + +// the following functions generate function calls +// parameters are loaded by generating code using gen_load_param_ which +// is architecture dependent +// R=host register; I=32bit immediate value; A=address value; m=memory + +static DRC_PTR_SIZE_IM INLINE gen_call_function_R(void * func,Bitu op) { + gen_load_param_reg(op,0); + return gen_call_function_setup(func, 1); +} + +static DRC_PTR_SIZE_IM INLINE gen_call_function_R3(void * func,Bitu op) { + gen_load_param_reg(op,2); + return gen_call_function_setup(func, 3, true); +} + +static DRC_PTR_SIZE_IM INLINE gen_call_function_RI(void * func,Bitu op1,Bitu op2) { + gen_load_param_imm(op2,1); + gen_load_param_reg(op1,0); + return gen_call_function_setup(func, 2); +} + +static DRC_PTR_SIZE_IM INLINE gen_call_function_RA(void * func,Bitu op1,DRC_PTR_SIZE_IM op2) { + gen_load_param_addr(op2,1); + gen_load_param_reg(op1,0); + return gen_call_function_setup(func, 2); +} + +static DRC_PTR_SIZE_IM INLINE gen_call_function_RR(void * func,Bitu op1,Bitu op2) { + gen_load_param_reg(op2,1); + gen_load_param_reg(op1,0); + return gen_call_function_setup(func, 2); +} + +static DRC_PTR_SIZE_IM INLINE gen_call_function_IR(void * func,Bitu op1,Bitu op2) { + gen_load_param_reg(op2,1); + gen_load_param_imm(op1,0); + return gen_call_function_setup(func, 2); +} + +static DRC_PTR_SIZE_IM INLINE gen_call_function_I(void * func,Bitu op) { + gen_load_param_imm(op,0); + return gen_call_function_setup(func, 1); +} + +static DRC_PTR_SIZE_IM INLINE gen_call_function_II(void * func,Bitu op1,Bitu op2) { + gen_load_param_imm(op2,1); + gen_load_param_imm(op1,0); + return gen_call_function_setup(func, 2); +} + +static DRC_PTR_SIZE_IM INLINE gen_call_function_III(void * func,Bitu op1,Bitu op2,Bitu op3) { + gen_load_param_imm(op3,2); + gen_load_param_imm(op2,1); + gen_load_param_imm(op1,0); + return gen_call_function_setup(func, 3); +} + +static DRC_PTR_SIZE_IM INLINE gen_call_function_IA(void * func,Bitu op1,DRC_PTR_SIZE_IM op2) { + gen_load_param_addr(op2,1); + gen_load_param_imm(op1,0); + return gen_call_function_setup(func, 2); +} + +static DRC_PTR_SIZE_IM INLINE gen_call_function_IIR(void * func,Bitu op1,Bitu op2,Bitu op3) { + gen_load_param_reg(op3,2); + gen_load_param_imm(op2,1); + gen_load_param_imm(op1,0); + return gen_call_function_setup(func, 3); +} + +static DRC_PTR_SIZE_IM INLINE gen_call_function_IIIR(void * func,Bitu op1,Bitu op2,Bitu op3,Bitu op4) { + gen_load_param_reg(op4,3); + gen_load_param_imm(op3,2); + gen_load_param_imm(op2,1); + gen_load_param_imm(op1,0); + return gen_call_function_setup(func, 4); +} + +static DRC_PTR_SIZE_IM INLINE gen_call_function_IRRR(void * func,Bitu op1,Bitu op2,Bitu op3,Bitu op4) { + gen_load_param_reg(op4,3); + gen_load_param_reg(op3,2); + gen_load_param_reg(op2,1); + gen_load_param_imm(op1,0); + return gen_call_function_setup(func, 4); +} + +static DRC_PTR_SIZE_IM INLINE gen_call_function_m(void * func,Bitu op) { + gen_load_param_mem(op,2); + return gen_call_function_setup(func, 3, true); +} + +static DRC_PTR_SIZE_IM INLINE gen_call_function_mm(void * func,Bitu op1,Bitu op2) { + gen_load_param_mem(op2,3); + gen_load_param_mem(op1,2); + return gen_call_function_setup(func, 4, true); +} + + + +enum save_info_type {exception, cycle_check, string_break}; + + +// function that is called on exceptions +static BlockReturn DynRunException(Bit32u eip_add,Bit32u cycle_sub) { + reg_eip+=eip_add; + CPU_Cycles-=cycle_sub; + if (cpu.exception.which==SMC_CURRENT_BLOCK) return BR_SMCBlock; + CPU_Exception(cpu.exception.which,cpu.exception.error); + return BR_Normal; +} + + +// array with information about code that is generated at the +// end of a cache block because it is rarely reached (like exceptions) +static struct { + save_info_type type; + DRC_PTR_SIZE_IM branch_pos; + Bit32u eip_change; + Bitu cycles; +} save_info_dynrec[512]; + +Bitu used_save_info_dynrec=0; + + +// return from current block, with returncode +static void dyn_return(BlockReturn retcode,bool ret_exception=false) { + if (!ret_exception) { + gen_mov_dword_to_reg_imm(FC_RETOP,retcode); + } + gen_return_function(); +} + +static void dyn_run_code(void) { + gen_run_code(); + gen_return_function(); +} + +// fill in code at the end of the block that contains rarely-executed code +// which is executed conditionally (like exceptions) +static void dyn_fill_blocks(void) { + for (Bitu sct=0; sct>12); + if (paging.tlb.read[index]) { + *((Bit8u*)(&core_dynrec.readdata))=host_readb(paging.tlb.read[index]+address); + return false; + } else { + Bitu uval; + bool retval; + retval=paging.tlb.handler[index]->readb_checked(address, &uval); + *((Bit8u*)(&core_dynrec.readdata))=(Bit8u)uval; + return retval; + } +} + +bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) { + Bitu index=(address>>12); + if (paging.tlb.write[index]) { + host_writeb(paging.tlb.write[index]+address,val); + return false; + } else return paging.tlb.handler[index]->writeb_checked(address,val); +} + +bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) { +#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) + if (!(address & 1)) { +#else + if ((address & 0xfff)<0xfff) { +#endif + Bitu index=(address>>12); + if (paging.tlb.read[index]) { + *((Bit16u*)(&core_dynrec.readdata))=host_readw(paging.tlb.read[index]+address); + return false; + } else { + Bitu uval; + bool retval; + retval=paging.tlb.handler[index]->readw_checked(address, &uval); + *((Bit16u*)(&core_dynrec.readdata))=(Bit16u)uval; + return retval; + } + } else return mem_unalignedreadw_checked_x86(address, ((Bit16u*)(&core_dynrec.readdata))); +} + +bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) { +#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) + if (!(address & 3)) { +#else + if ((address & 0xfff)<0xffd) { +#endif + Bitu index=(address>>12); + if (paging.tlb.read[index]) { + *((Bit32u*)(&core_dynrec.readdata))=host_readd(paging.tlb.read[index]+address); + return false; + } else { + Bitu uval; + bool retval; + retval=paging.tlb.handler[index]->readd_checked(address, &uval); + *((Bit32u*)(&core_dynrec.readdata))=(Bit32u)uval; + return retval; + } + } else return mem_unalignedreadd_checked_x86(address, ((Bit32u*)(&core_dynrec.readdata))); +} + +bool DRC_CALL_CONV mem_writew_checked_drc(PhysPt address,Bit16u val) { +#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) + if (!(address & 1)) { +#else + if ((address & 0xfff)<0xfff) { +#endif + Bitu index=(address>>12); + if (paging.tlb.write[index]) { + host_writew(paging.tlb.write[index]+address,val); + return false; + } else return paging.tlb.handler[index]->writew_checked(address,val); + } else return mem_unalignedwritew_checked_x86(address,val); +} + +bool DRC_CALL_CONV mem_writed_checked_drc(PhysPt address,Bit32u val) { +#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) + if (!(address & 3)) { +#else + if ((address & 0xfff)<0xffd) { +#endif + Bitu index=(address>>12); + if (paging.tlb.write[index]) { + host_writed(paging.tlb.write[index]+address,val); + return false; + } else return paging.tlb.handler[index]->writed_checked(address,val); + } else return mem_unalignedwrited_checked_x86(address,val); +} + + +// functions that enable access to the memory + +// read a byte from a given address and store it in reg_dst +static void dyn_read_byte(HostReg reg_addr,HostReg reg_dst) { + gen_mov_regs(FC_OP1,reg_addr); + gen_call_function_raw((void *)&mem_readb_checked_drc); + dyn_check_exception(FC_RETOP); + gen_mov_byte_to_reg_low(reg_dst,&core_dynrec.readdata); +} +static void dyn_read_byte_canuseword(HostReg reg_addr,HostReg reg_dst) { + gen_mov_regs(FC_OP1,reg_addr); + gen_call_function_raw((void *)&mem_readb_checked_drc); + dyn_check_exception(FC_RETOP); + gen_mov_byte_to_reg_low_canuseword(reg_dst,&core_dynrec.readdata); +} + +// write a byte from reg_val into the memory given by the address +static void dyn_write_byte(HostReg reg_addr,HostReg reg_val) { + gen_mov_regs(FC_OP2,reg_val); + gen_mov_regs(FC_OP1,reg_addr); + gen_call_function_raw((void *)&mem_writeb_checked_drc); + dyn_check_exception(FC_RETOP); +} + +// read a 32bit (dword=true) or 16bit (dword=false) value +// from a given address and store it in reg_dst +static void dyn_read_word(HostReg reg_addr,HostReg reg_dst,bool dword) { + gen_mov_regs(FC_OP1,reg_addr); + if (dword) gen_call_function_raw((void *)&mem_readd_checked_drc); + else gen_call_function_raw((void *)&mem_readw_checked_drc); + dyn_check_exception(FC_RETOP); + gen_mov_word_to_reg(reg_dst,&core_dynrec.readdata,dword); +} + +// write a 32bit (dword=true) or 16bit (dword=false) value +// from reg_val into the memory given by the address +static void dyn_write_word(HostReg reg_addr,HostReg reg_val,bool dword) { +// if (!dword) gen_extend_word(false,reg_val); + gen_mov_regs(FC_OP2,reg_val); + gen_mov_regs(FC_OP1,reg_addr); + if (dword) gen_call_function_raw((void *)&mem_writed_checked_drc); + else gen_call_function_raw((void *)&mem_writew_checked_drc); + dyn_check_exception(FC_RETOP); +} + + + +// effective address calculation helper, op2 has to be present! +// loads op1 into ea_reg and adds the scaled op2 and the immediate to it +static void dyn_lea(HostReg ea_reg,void* op1,void* op2,Bitu scale,Bits imm) { + if (scale || imm) { + if (op1!=NULL) { + gen_mov_word_to_reg(ea_reg,op1,true); + gen_mov_word_to_reg(TEMP_REG_DRC,op2,true); + + gen_lea(ea_reg,TEMP_REG_DRC,scale,imm); + } else { + gen_mov_word_to_reg(ea_reg,op2,true); + gen_lea(ea_reg,scale,imm); + } + } else { + gen_mov_word_to_reg(ea_reg,op2,true); + if (op1!=NULL) gen_add(ea_reg,op1); + } +} + +// calculate the effective address and store it in ea_reg +static void dyn_fill_ea(HostReg ea_reg,bool addseg=true) { + Bit8u seg_base=DRC_SEG_DS; + if (!decode.big_addr) { + Bits imm; + switch (decode.modrm.mod) { + case 0:imm=0;break; + case 1:imm=(Bit8s)decode_fetchb();break; + case 2:imm=(Bit16s)decode_fetchw();break; + } + switch (decode.modrm.rm) { + case 0:// BX+SI + dyn_lea(ea_reg,DRCD_REG(DRC_REG_EBX),DRCD_REG(DRC_REG_ESI),0,imm); + break; + case 1:// BX+DI + dyn_lea(ea_reg,DRCD_REG(DRC_REG_EBX),DRCD_REG(DRC_REG_EDI),0,imm); + break; + case 2:// BP+SI + dyn_lea(ea_reg,DRCD_REG(DRC_REG_EBP),DRCD_REG(DRC_REG_ESI),0,imm); + seg_base=DRC_SEG_SS; + break; + case 3:// BP+DI + dyn_lea(ea_reg,DRCD_REG(DRC_REG_EBP),DRCD_REG(DRC_REG_EDI),0,imm); + seg_base=DRC_SEG_SS; + break; + case 4:// SI + gen_mov_word_to_reg(ea_reg,DRCD_REG(DRC_REG_ESI),true); + if (imm) gen_add_imm(ea_reg,(Bit32u)imm); + break; + case 5:// DI + gen_mov_word_to_reg(ea_reg,DRCD_REG(DRC_REG_EDI),true); + if (imm) gen_add_imm(ea_reg,(Bit32u)imm); + break; + case 6:// imm/BP + if (!decode.modrm.mod) { + imm=decode_fetchw(); + gen_mov_dword_to_reg_imm(ea_reg,(Bit32u)imm); + goto skip_extend_word; + } else { + gen_mov_word_to_reg(ea_reg,DRCD_REG(DRC_REG_EBP),true); + gen_add_imm(ea_reg,(Bit32u)imm); + seg_base=DRC_SEG_SS; + } + break; + case 7: // BX + gen_mov_word_to_reg(ea_reg,DRCD_REG(DRC_REG_EBX),true); + if (imm) gen_add_imm(ea_reg,(Bit32u)imm); + break; + } + // zero out the high 16bit so ea_reg can be used as full register + gen_extend_word(false,ea_reg); +skip_extend_word: + if (addseg) { + // add the physical segment value if requested + gen_add(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); + } + } else { + Bits imm=0; + Bit8u base_reg; + Bit8u scaled_reg; + Bitu scale=0; + switch (decode.modrm.rm) { + case 0:base_reg=DRC_REG_EAX;break; + case 1:base_reg=DRC_REG_ECX;break; + case 2:base_reg=DRC_REG_EDX;break; + case 3:base_reg=DRC_REG_EBX;break; + case 4: // SIB + { + Bitu sib=decode_fetchb(); + bool scaled_reg_used=false; + static Bit8u scaledtable[8]={ + DRC_REG_EAX,DRC_REG_ECX,DRC_REG_EDX,DRC_REG_EBX, + 0,DRC_REG_EBP,DRC_REG_ESI,DRC_REG_EDI + }; + // see if scaling should be used and which register is to be scaled in this case + if (((sib >> 3) &7)!=4) scaled_reg_used=true; + scaled_reg=scaledtable[(sib >> 3) &7]; + scale=(sib >> 6); + + switch (sib & 7) { + case 0:base_reg=DRC_REG_EAX;break; + case 1:base_reg=DRC_REG_ECX;break; + case 2:base_reg=DRC_REG_EDX;break; + case 3:base_reg=DRC_REG_EBX;break; + case 4:base_reg=DRC_REG_ESP;seg_base=DRC_SEG_SS;break; + case 5: + if (decode.modrm.mod) { + base_reg=DRC_REG_EBP;seg_base=DRC_SEG_SS; + } else { + // no basereg, maybe scalereg + Bitu val; + // try to get a pointer to the next dword code position + if (decode_fetchd_imm(val)) { + // succeeded, use the pointer to avoid code invalidation + if (!addseg) { + if (!scaled_reg_used) { + gen_mov_word_to_reg(ea_reg,(void*)val,true); + } else { + dyn_lea(ea_reg,NULL,DRCD_REG(scaled_reg),scale,0); + gen_add(ea_reg,(void*)val); + } + } else { + if (!scaled_reg_used) { + gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); + } else { + dyn_lea(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),DRCD_REG(scaled_reg),scale,0); + } + gen_add(ea_reg,(void*)val); + } + return; + } + // couldn't get a pointer, use the current value + imm=(Bit32s)val; + + if (!addseg) { + if (!scaled_reg_used) { + gen_mov_dword_to_reg_imm(ea_reg,(Bit32u)imm); + } else { + dyn_lea(ea_reg,NULL,DRCD_REG(scaled_reg),scale,imm); + } + } else { + if (!scaled_reg_used) { + gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); + if (imm) gen_add_imm(ea_reg,(Bit32u)imm); + } else { + dyn_lea(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),DRCD_REG(scaled_reg),scale,imm); + } + } + + return; + } + break; + case 6:base_reg=DRC_REG_ESI;break; + case 7:base_reg=DRC_REG_EDI;break; + } + // basereg, maybe scalereg + switch (decode.modrm.mod) { + case 1: + imm=(Bit8s)decode_fetchb(); + break; + case 2: { + Bitu val; + // try to get a pointer to the next dword code position + if (decode_fetchd_imm(val)) { + // succeeded, use the pointer to avoid code invalidation + if (!addseg) { + if (!scaled_reg_used) { + gen_mov_word_to_reg(ea_reg,DRCD_REG(base_reg),true); + gen_add(ea_reg,(void*)val); + } else { + dyn_lea(ea_reg,DRCD_REG(base_reg),DRCD_REG(scaled_reg),scale,0); + gen_add(ea_reg,(void*)val); + } + } else { + if (!scaled_reg_used) { + gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); + } else { + dyn_lea(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),DRCD_REG(scaled_reg),scale,0); + } + gen_add(ea_reg,DRCD_REG(base_reg)); + gen_add(ea_reg,(void*)val); + } + return; + } + // couldn't get a pointer, use the current value + imm=(Bit32s)val; + break; + } + } + + if (!addseg) { + if (!scaled_reg_used) { + gen_mov_word_to_reg(ea_reg,DRCD_REG(base_reg),true); + gen_add_imm(ea_reg,(Bit32u)imm); + } else { + dyn_lea(ea_reg,DRCD_REG(base_reg),DRCD_REG(scaled_reg),scale,imm); + } + } else { + if (!scaled_reg_used) { + gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); + gen_add(ea_reg,DRCD_REG(base_reg)); + if (imm) gen_add_imm(ea_reg,(Bit32u)imm); + } else { + dyn_lea(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),DRCD_REG(scaled_reg),scale,imm); + gen_add(ea_reg,DRCD_REG(base_reg)); + } + } + + return; + } + break; // SIB Break + case 5: + if (decode.modrm.mod) { + base_reg=DRC_REG_EBP;seg_base=DRC_SEG_SS; + } else { + // no base, no scalereg + + imm=(Bit32s)decode_fetchd(); + if (!addseg) { + gen_mov_dword_to_reg_imm(ea_reg,(Bit32u)imm); + } else { + gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); + if (imm) gen_add_imm(ea_reg,(Bit32u)imm); + } + + return; + } + break; + case 6:base_reg=DRC_REG_ESI;break; + case 7:base_reg=DRC_REG_EDI;break; + } + + // no scalereg, but basereg + + switch (decode.modrm.mod) { + case 1: + imm=(Bit8s)decode_fetchb(); + break; + case 2: { + Bitu val; + // try to get a pointer to the next dword code position + if (decode_fetchd_imm(val)) { + // succeeded, use the pointer to avoid code invalidation + if (!addseg) { + gen_mov_word_to_reg(ea_reg,DRCD_REG(base_reg),true); + gen_add(ea_reg,(void*)val); + } else { + gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); + gen_add(ea_reg,DRCD_REG(base_reg)); + gen_add(ea_reg,(void*)val); + } + return; + } + // couldn't get a pointer, use the current value + imm=(Bit32s)val; + break; + } + } + + if (!addseg) { + gen_mov_word_to_reg(ea_reg,DRCD_REG(base_reg),true); + if (imm) gen_add_imm(ea_reg,(Bit32u)imm); + } else { + gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); + gen_add(ea_reg,DRCD_REG(base_reg)); + if (imm) gen_add_imm(ea_reg,(Bit32u)imm); + } + } +} + + + +// add code that checks if port access is allowed +// the port is given in a register +static void dyn_add_iocheck(HostReg reg_port,Bitu access_size) { + if (cpu.pmode) { + gen_call_function_RI((void *)&CPU_IO_Exception,reg_port,access_size); + dyn_check_exception(FC_RETOP); + } +} + +// add code that checks if port access is allowed +// the port is a constant +static void dyn_add_iocheck_var(Bit8u accessed_port,Bitu access_size) { + if (cpu.pmode) { + gen_call_function_II((void *)&CPU_IO_Exception,accessed_port,access_size); + dyn_check_exception(FC_RETOP); + } +} + + + +// save back the address register +static void gen_protect_addr_reg(void) { + gen_mov_word_from_reg(FC_ADDR,&core_dynrec.protected_regs[FC_ADDR],true); +} + +// restore the address register +static void gen_restore_addr_reg(void) { + gen_mov_word_to_reg(FC_ADDR,&core_dynrec.protected_regs[FC_ADDR],true); +} + +// save back an arbitrary register +static void gen_protect_reg(HostReg reg) { + gen_mov_word_from_reg(reg,&core_dynrec.protected_regs[reg],true); +} + +// restore an arbitrary register +static void gen_restore_reg(HostReg reg) { + gen_mov_word_to_reg(reg,&core_dynrec.protected_regs[reg],true); +} + +// restore an arbitrary register into a different register +static void gen_restore_reg(HostReg reg,HostReg dest_reg) { + gen_mov_word_to_reg(dest_reg,&core_dynrec.protected_regs[reg],true); +} + + + +#include "lazyflags.h" + +// flags optimization functions +// they try to find out if a function can be replaced by another +// one that does not generate any flags at all + +static Bitu mf_functions_num=0; +static struct { + DRC_PTR_SIZE_IM pos; + Bit32u fct_ptr; +} mf_functions[64]; + +static void InitFlagsOptimization(void) { + mf_functions_num=0; +} + +// replace all queued functions with their simpler variants +// because the current instruction destroys all condition flags and +// the flags are not required before +static void InvalidateFlags(void) { +#ifdef DRC_FLAGS_INVALIDATION + for (Bitu ct=0; ct>2)&1)); + dyn_dop_byte_gencall(op); + + if ((op!=DOP_CMP) && (op!=DOP_TEST)) { + gen_restore_addr_reg(); + dyn_write_byte(FC_ADDR,FC_RETOP); + } + } else { + gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + dyn_dop_byte_gencall(op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + } +} + +static void dyn_dop_ebgb_mov(void) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + dyn_write_byte(FC_ADDR,FC_TMP_BA1); + } else { + gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + } +} + +static void dyn_dop_ebib_mov(void) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + gen_mov_byte_to_reg_low_imm(FC_TMP_BA1,decode_fetchb()); + dyn_write_byte(FC_ADDR,FC_TMP_BA1); + } else { + gen_mov_byte_to_reg_low_imm(FC_TMP_BA1,decode_fetchb()); + gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + } +} + +static void dyn_dop_ebgb_xchg(void) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + gen_protect_addr_reg(); + dyn_read_byte(FC_ADDR,FC_TMP_BA1); + gen_mov_byte_to_reg_low(FC_TMP_BA2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + + gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + gen_restore_addr_reg(); + dyn_write_byte(FC_ADDR,FC_TMP_BA2); + } else { + gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + gen_mov_byte_to_reg_low(FC_TMP_BA2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + gen_mov_byte_from_reg_low(FC_TMP_BA2,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + } +} + +static void dyn_dop_gbeb(DualOps op) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + dyn_read_byte_canuseword(FC_ADDR,FC_OP2); + gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + dyn_dop_byte_gencall(op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + } else { + gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + dyn_dop_byte_gencall(op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + } +} + +static void dyn_dop_gbeb_mov(void) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + dyn_read_byte(FC_ADDR,FC_TMP_BA1); + gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + } else { + gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + } +} + +static void dyn_dop_evgv(DualOps op) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); + gen_protect_addr_reg(); + gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + dyn_dop_word_gencall(op,decode.big_op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) { + gen_restore_addr_reg(); + dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); + } + } else { + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + dyn_dop_word_gencall(op,decode.big_op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + } +} + +static void dyn_dop_evgv_mov(void) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + dyn_write_word(FC_ADDR,FC_OP1,decode.big_op); + } else { + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + } +} + +static void dyn_dop_eviv_mov(void) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP1,decode_fetchd()); + else gen_mov_word_to_reg_imm(FC_OP1,decode_fetchw()); + dyn_write_word(FC_ADDR,FC_OP1,decode.big_op); + } else { + if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP1,decode_fetchd()); + else gen_mov_word_to_reg_imm(FC_OP1,decode_fetchw()); + gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + } +} + +static void dyn_dop_evgv_xchg(void) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + gen_protect_addr_reg(); + dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); + gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + + gen_protect_reg(FC_OP1); + gen_restore_addr_reg(); + dyn_write_word(FC_ADDR,FC_OP2,decode.big_op); + gen_restore_reg(FC_OP1); + gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + } else { + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + gen_mov_word_from_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + } +} + +static void dyn_xchg_ax(Bit8u reg) { + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); + gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + gen_mov_word_from_reg(FC_OP2,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); +} + +static void dyn_dop_gvev(DualOps op) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + gen_protect_addr_reg(); + dyn_read_word(FC_ADDR,FC_OP2,decode.big_op); + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + dyn_dop_word_gencall(op,decode.big_op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) { + gen_restore_addr_reg(); + gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + } + } else { + gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + dyn_dop_word_gencall(op,decode.big_op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + } +} + +static void dyn_dop_gvev_mov(void) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); + gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + } else { + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + } +} + +static void dyn_dop_byte_imm(DualOps op,Bit8u reg,Bit8u idx) { + gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(reg,idx)); + gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,decode_fetchb()); + dyn_dop_byte_gencall(op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(reg,idx)); +} + +static void dyn_dop_byte_imm_mem(DualOps op,Bit8u reg,Bit8u idx) { + gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(reg,idx)); + Bitu val; + if (decode_fetchb_imm(val)) { + gen_mov_byte_to_reg_low_canuseword(FC_OP2,(void*)val); + } else { + gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,(Bit8u)val); + } + dyn_dop_byte_gencall(op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(reg,idx)); +} + +static void dyn_prep_word_imm(Bit8u reg) { + Bitu val; + if (decode.big_op) { + if (decode_fetchd_imm(val)) { + gen_mov_word_to_reg(FC_OP2,(void*)val,true); + return; + } + } else { + if (decode_fetchw_imm(val)) { + gen_mov_word_to_reg(FC_OP2,(void*)val,false); + return; + } + } + if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)val); + else gen_mov_word_to_reg_imm(FC_OP2,(Bit16u)val); +} + +static void dyn_dop_word_imm(DualOps op,Bit8u reg) { + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + dyn_prep_word_imm(reg); + dyn_dop_word_gencall(op,decode.big_op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); +} + +static void dyn_dop_word_imm_old(DualOps op,Bit8u reg,Bitu imm) { + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)imm); + else gen_mov_word_to_reg_imm(FC_OP2,(Bit16u)imm); + dyn_dop_word_gencall(op,decode.big_op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); +} + +static void dyn_mov_byte_imm(Bit8u reg,Bit8u idx,Bit8u imm) { + gen_mov_byte_to_reg_low_imm(FC_TMP_BA1,imm); + gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(reg,idx)); +} + +static void dyn_mov_word_imm(Bit8u reg) { + Bitu val; + if (decode.big_op) { + if (decode_fetchd_imm(val)) { + gen_mov_word_to_reg(FC_OP1,(void*)val,true); + gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(reg,true),true); + return; + } + } else { + if (decode_fetchw_imm(val)) { + gen_mov_word_to_reg(FC_OP1,(void*)val,false); + gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(reg,false),false); + return; + } + } + if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP1,(Bit32u)val); + else gen_mov_word_to_reg_imm(FC_OP1,(Bit16u)val); + gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); +} + + +static void dyn_sop_word(SingleOps op,Bit8u reg) { + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + dyn_sop_word_gencall(op,decode.big_op); + gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); +} + + +static void dyn_mov_byte_al_direct(Bitu imm) { + gen_mov_word_to_reg(FC_ADDR,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS),true); + gen_add_imm(FC_ADDR,imm); + dyn_read_byte(FC_ADDR,FC_TMP_BA1); + gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(DRC_REG_EAX,0)); +} + +static void dyn_mov_byte_ax_direct(Bitu imm) { + gen_mov_word_to_reg(FC_ADDR,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS),true); + gen_add_imm(FC_ADDR,imm); + dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); + gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); +} + +static void dyn_mov_byte_direct_al() { + gen_mov_word_to_reg(FC_ADDR,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS),true); + if (decode.big_addr) { + Bitu val; + if (decode_fetchd_imm(val)) { + gen_add(FC_ADDR,(void*)val); + } else { + gen_add_imm(FC_ADDR,(Bit32u)val); + } + } else { + gen_add_imm(FC_ADDR,decode_fetchw()); + } + gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(DRC_REG_EAX,0)); + dyn_write_byte(FC_ADDR,FC_TMP_BA1); +} + +static void dyn_mov_byte_direct_ax(Bitu imm) { + gen_mov_word_to_reg(FC_ADDR,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS),true); + gen_add_imm(FC_ADDR,imm); + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); + dyn_write_word(FC_ADDR,FC_OP1,decode.big_op); +} + + +static void dyn_movx_ev_gb(bool sign) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + dyn_read_byte(FC_ADDR,FC_TMP_BA1); + gen_extend_byte(sign,FC_TMP_BA1); + gen_mov_word_from_reg(FC_TMP_BA1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + } else { + gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + gen_extend_byte(sign,FC_TMP_BA1); + gen_mov_word_from_reg(FC_TMP_BA1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + } +} + +static void dyn_movx_ev_gw(bool sign) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + dyn_read_word(FC_ADDR,FC_OP1,false); + gen_extend_word(sign,FC_OP1); + gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + } else { + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,false),false); + gen_extend_word(sign,FC_OP1); + gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + } +} + + +static void dyn_mov_ev_seg(void) { + dyn_get_modrm(); + gen_mov_word_to_reg(FC_OP1,DRCD_SEG_VAL(decode.modrm.reg),false); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + dyn_write_word(FC_ADDR,FC_OP1,false); + } else { + if (decode.big_op) gen_extend_word(false,FC_OP1); + gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + } +} + + +static void dyn_push_seg(Bit8u seg) { + gen_mov_word_to_reg(FC_OP1,DRCD_SEG_VAL(seg),false); + if (decode.big_op) { + gen_extend_word(false,FC_OP1); + gen_call_function_raw((void*)&dynrec_push_dword); + } else { + gen_call_function_raw((void*)&dynrec_push_word); + } +} + +static void dyn_pop_seg(Bit8u seg) { + gen_call_function_II((void *)&CPU_PopSeg,seg,decode.big_op); + if (cpu.pmode) dyn_check_exception(FC_RETOP); +} + +static void dyn_push_reg(Bit8u reg) { + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + if (decode.big_op) gen_call_function_raw((void*)&dynrec_push_dword); + else gen_call_function_raw((void*)&dynrec_push_word); +} + +static void dyn_pop_reg(Bit8u reg) { + if (decode.big_op) gen_call_function_raw((void*)&dynrec_pop_dword); + else gen_call_function_raw((void*)&dynrec_pop_word); + gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); +} + +static void dyn_push_byte_imm(Bit8s imm) { + gen_mov_dword_to_reg_imm(FC_OP1,(Bit32u)imm); + if (decode.big_op) gen_call_function_raw((void*)&dynrec_push_dword); + else gen_call_function_raw((void*)&dynrec_push_word); +} + +static void dyn_push_word_imm(Bitu imm) { + if (decode.big_op) { + gen_mov_dword_to_reg_imm(FC_OP1,imm); + gen_call_function_raw((void*)&dynrec_push_dword); + } else { + gen_mov_word_to_reg_imm(FC_OP1,(Bit16u)imm); + gen_call_function_raw((void*)&dynrec_push_word); + } +} + +static void dyn_pop_ev(void) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { +/* dyn_fill_ea(FC_ADDR); + gen_protect_addr_reg(); + dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); // dummy read to trigger possible page faults */ + if (decode.big_op) gen_call_function_raw((void*)&dynrec_pop_dword); + else gen_call_function_raw((void*)&dynrec_pop_word); + dyn_fill_ea(FC_ADDR); +// gen_restore_addr_reg(); + dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); + } else { + if (decode.big_op) gen_call_function_raw((void*)&dynrec_pop_dword); + else gen_call_function_raw((void*)&dynrec_pop_word); + gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + } +} + + +static void dyn_segprefix(Bit8u seg) { + if (GCC_UNLIKELY(decode.seg_prefix_used)) IllegalOptionDynrec("dyn_segprefix"); + decode.seg_prefix=seg; + decode.seg_prefix_used=true; +} + + static void dyn_mov_seg_ev(void) { + dyn_get_modrm(); + if (GCC_UNLIKELY(decode.modrm.reg==DRC_SEG_CS)) IllegalOptionDynrec("dyn_mov_seg_ev"); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + dyn_read_word(FC_ADDR,FC_RETOP,false); + } else { + gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); + } + gen_call_function_IR((void *)&CPU_SetSegGeneral,decode.modrm.reg,FC_RETOP); + if (cpu.pmode) dyn_check_exception(FC_RETOP); +} + +static void dyn_load_seg_off_ea(Bit8u seg) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + gen_protect_addr_reg(); + dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); + gen_protect_reg(FC_OP1); + + gen_restore_addr_reg(); + gen_add_imm(FC_ADDR,decode.big_op ? 4:2); + dyn_read_word(FC_ADDR,FC_RETOP,false); + + gen_call_function_IR((void *)&CPU_SetSegGeneral,seg,FC_RETOP); + if (cpu.pmode) dyn_check_exception(FC_RETOP); + + gen_restore_reg(FC_OP1); + gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + } else { + IllegalOptionDynrec("dyn_load_seg_off_ea"); + } +} + + + +static void dyn_imul_gvev(Bitu immsize) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); + } else { + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + } + + switch (immsize) { + case 0: + gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + break; + case 1: + if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit8s)decode_fetchb()); + else gen_mov_word_to_reg_imm(FC_OP2,(Bit8s)decode_fetchb()); + break; + case 2: + if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit16s)decode_fetchw()); + else gen_mov_word_to_reg_imm(FC_OP2,(Bit16s)decode_fetchw()); + break; + case 4: + if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit32s)decode_fetchd()); + else gen_mov_word_to_reg_imm(FC_OP2,(Bit16u)((Bit32s)decode_fetchd())); + break; + } + + if (decode.big_op) gen_call_function_raw((void*)dynrec_dimul_dword); + else gen_call_function_raw((void*)dynrec_dimul_word); + + gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); +} + +static void dyn_dshift_ev_gv(bool left,bool immediate) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + gen_protect_addr_reg(); + dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); + } else { + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + } + gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + if (immediate) gen_mov_byte_to_reg_low_imm(FC_RETOP,decode_fetchb()); + else gen_mov_byte_to_reg_low(FC_RETOP,DRCD_REG_BYTE(DRC_REG_ECX,0)); + if (decode.big_op) dyn_dpshift_dword_gencall(left); + else dyn_dpshift_word_gencall(left); + + if (decode.modrm.mod<3) { + gen_restore_addr_reg(); + dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); + } else { + gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + } +} + + +static void dyn_grp1_eb_ib(void) { + dyn_get_modrm(); + DualOps op=grp1_table[decode.modrm.reg]; + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + gen_protect_addr_reg(); + dyn_read_byte_canuseword(FC_ADDR,FC_OP1); + gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,decode_fetchb()); + dyn_dop_byte_gencall(op); + + if ((op!=DOP_CMP) && (op!=DOP_TEST)) { + gen_restore_addr_reg(); + dyn_write_byte(FC_ADDR,FC_RETOP); + } + } else { + dyn_dop_byte_imm_mem(op,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); + } +} + +static void dyn_grp1_ev_iv(bool withbyte) { + dyn_get_modrm(); + DualOps op=grp1_table[decode.modrm.reg]; + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + gen_protect_addr_reg(); + dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); + + if (!withbyte) { + dyn_prep_word_imm(FC_OP2); + } else { + Bits imm=(Bit8s)decode_fetchb(); + if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)imm); + else gen_mov_word_to_reg_imm(FC_OP2,(Bit16u)imm); + } + + dyn_dop_word_gencall(op,decode.big_op); + + if ((op!=DOP_CMP) && (op!=DOP_TEST)) { + gen_restore_addr_reg(); + dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); + } + } else { + if (!withbyte) { + dyn_dop_word_imm(op,decode.modrm.rm); + } else { + Bits imm=withbyte ? (Bit8s)decode_fetchb() : (decode.big_op ? decode_fetchd(): decode_fetchw()); + dyn_dop_word_imm_old(op,decode.modrm.rm,imm); + } + } +} + + +static void dyn_grp2_eb(grp2_types type) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + gen_protect_addr_reg(); + dyn_read_byte_canuseword(FC_ADDR,FC_OP1); + } else { + gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + } + switch (type) { + case grp2_1: + gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,1); + dyn_shift_byte_gencall((ShiftOps)decode.modrm.reg); + break; + case grp2_imm: { + Bit8u imm=decode_fetchb(); + if (imm) { + gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,imm&0x1f); + dyn_shift_byte_gencall((ShiftOps)decode.modrm.reg); + } else return; + } + break; + case grp2_cl: + gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(DRC_REG_ECX,0)); + gen_and_imm(FC_OP2,0x1f); + dyn_shift_byte_gencall((ShiftOps)decode.modrm.reg); + break; + } + if (decode.modrm.mod<3) { + gen_restore_addr_reg(); + dyn_write_byte(FC_ADDR,FC_RETOP); + } else { + gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + } +} + +static void dyn_grp2_ev(grp2_types type) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + gen_protect_addr_reg(); + dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); + } else { + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + } + switch (type) { + case grp2_1: + gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,1); + dyn_shift_word_gencall((ShiftOps)decode.modrm.reg,decode.big_op); + break; + case grp2_imm: { + Bitu val; + if (decode_fetchb_imm(val)) { + gen_mov_byte_to_reg_low_canuseword(FC_OP2,(void*)val); + gen_and_imm(FC_OP2,0x1f); + dyn_shift_word_gencall((ShiftOps)decode.modrm.reg,decode.big_op); + break; + } + Bit8u imm=(Bit8u)val; + if (imm) { + gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,imm&0x1f); + dyn_shift_word_gencall((ShiftOps)decode.modrm.reg,decode.big_op); + } else return; + } + break; + case grp2_cl: + gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(DRC_REG_ECX,0)); + gen_and_imm(FC_OP2,0x1f); + dyn_shift_word_gencall((ShiftOps)decode.modrm.reg,decode.big_op); + break; + } + if (decode.modrm.mod<3) { + gen_restore_addr_reg(); + dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); + } else { + gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + } +} + + +static void dyn_grp3_eb(void) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + if ((decode.modrm.reg==2) || (decode.modrm.reg==3)) gen_protect_addr_reg(); + dyn_read_byte_canuseword(FC_ADDR,FC_OP1); + } else { + gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + } + switch (decode.modrm.reg) { + case 0x0: // test eb,ib + gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,decode_fetchb()); + dyn_dop_byte_gencall(DOP_TEST); + return; + case 0x2: // NOT Eb + dyn_sop_byte_gencall(SOP_NOT); + break; + case 0x3: // NEG Eb + dyn_sop_byte_gencall(SOP_NEG); + break; + case 0x4: // mul Eb + gen_call_function_raw((void*)&dynrec_mul_byte); + return; + case 0x5: // imul Eb + gen_call_function_raw((void*)&dynrec_imul_byte); + return; + case 0x6: // div Eb + gen_call_function_raw((void*)&dynrec_div_byte); + dyn_check_exception(FC_RETOP); + return; + case 0x7: // idiv Eb + gen_call_function_raw((void*)&dynrec_idiv_byte); + dyn_check_exception(FC_RETOP); + return; + } + // Save the result if memory op + if (decode.modrm.mod<3) { + gen_restore_addr_reg(); + dyn_write_byte(FC_ADDR,FC_RETOP); + } else { + gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + } +} + +static void dyn_grp3_ev(void) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + if ((decode.modrm.reg==2) || (decode.modrm.reg==3)) gen_protect_addr_reg(); + dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); + } else { + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + } + switch (decode.modrm.reg) { + case 0x0: // test ev,iv + if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,decode_fetchd()); + else gen_mov_word_to_reg_imm(FC_OP2,decode_fetchw()); + dyn_dop_word_gencall(DOP_TEST,decode.big_op); + return; + case 0x2: // NOT Ev + dyn_sop_word_gencall(SOP_NOT,decode.big_op); + break; + case 0x3: // NEG Eb + dyn_sop_word_gencall(SOP_NEG,decode.big_op); + break; + case 0x4: // mul Eb + if (decode.big_op) gen_call_function_raw((void*)&dynrec_mul_dword); + else gen_call_function_raw((void*)&dynrec_mul_word); + return; + case 0x5: // imul Eb + if (decode.big_op) gen_call_function_raw((void*)&dynrec_imul_dword); + else gen_call_function_raw((void*)&dynrec_imul_word); + return; + case 0x6: // div Eb + if (decode.big_op) gen_call_function_raw((void*)&dynrec_div_dword); + else gen_call_function_raw((void*)&dynrec_div_word); + dyn_check_exception(FC_RETOP); + return; + case 0x7: // idiv Eb + if (decode.big_op) gen_call_function_raw((void*)&dynrec_idiv_dword); + else gen_call_function_raw((void*)&dynrec_idiv_word); + dyn_check_exception(FC_RETOP); + return; + } + // Save the result if memory op + if (decode.modrm.mod<3) { + gen_restore_addr_reg(); + dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); + } else { + gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + } +} + + +static bool dyn_grp4_eb(void) { + dyn_get_modrm(); + switch (decode.modrm.reg) { + case 0x0://INC Eb + case 0x1://DEC Eb + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + gen_protect_addr_reg(); + dyn_read_byte_canuseword(FC_ADDR,FC_OP1); + dyn_sop_byte_gencall(decode.modrm.reg==0 ? SOP_INC : SOP_DEC); + gen_restore_addr_reg(); + dyn_write_byte(FC_ADDR,FC_RETOP); + } else { + gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + dyn_sop_byte_gencall(decode.modrm.reg==0 ? SOP_INC : SOP_DEC); + gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + } + break; + case 0x7: //CALBACK Iw + gen_mov_direct_dword(&core_dynrec.callback,decode_fetchw()); + dyn_set_eip_end(); + dyn_reduce_cycles(); + dyn_return(BR_CallBack); + dyn_closeblock(); + return true; + default: + IllegalOptionDynrec("dyn_grp4_eb"); + break; + } + return false; +} + +static bool dyn_grp4_ev(void) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + if (decode.modrm.reg<2) gen_protect_addr_reg(); + dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); + } else { + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + } + switch (decode.modrm.reg) { + case 0x0://INC Ev + case 0x1://DEC Ev + dyn_sop_word_gencall(decode.modrm.reg==0 ? SOP_INC : SOP_DEC,decode.big_op); + if (decode.modrm.mod<3) { + gen_restore_addr_reg(); + dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); + } else { + gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + } + break; + case 0x2: // CALL Ev + gen_mov_regs(FC_ADDR,FC_OP1); + gen_protect_addr_reg(); + gen_mov_word_to_reg(FC_OP1,decode.big_op?(void*)(®_eip):(void*)(®_ip),decode.big_op); + gen_add_imm(FC_OP1,(Bit32u)(decode.code-decode.code_start)); + if (decode.big_op) gen_call_function_raw((void*)&dynrec_push_dword); + else gen_call_function_raw((void*)&dynrec_push_word); + + gen_restore_addr_reg(); + gen_mov_word_from_reg(FC_ADDR,decode.big_op?(void*)(®_eip):(void*)(®_ip),decode.big_op); + return true; + case 0x4: // JMP Ev + gen_mov_word_from_reg(FC_OP1,decode.big_op?(void*)(®_eip):(void*)(®_ip),decode.big_op); + return true; + case 0x3: // CALL Ep + case 0x5: // JMP Ep + if (!decode.big_op) gen_extend_word(false,FC_OP1); + gen_protect_reg(FC_OP1); + gen_add_imm(FC_ADDR,decode.big_op?4:2); + dyn_read_word(FC_ADDR,FC_OP2,decode.big_op); + gen_extend_word(false,FC_OP2); + + dyn_set_eip_last_end(FC_RETOP); + gen_restore_reg(FC_OP1,FC_ADDR); + gen_call_function_IRRR(decode.modrm.reg == 3 ? (void*)(&CPU_CALL) : (void*)(&CPU_JMP), + decode.big_op,FC_OP2,FC_ADDR,FC_RETOP); + return true; + case 0x6: // PUSH Ev + if (decode.big_op) gen_call_function_raw((void*)&dynrec_push_dword); + else gen_call_function_raw((void*)&dynrec_push_word); + break; + default: + IllegalOptionDynrec("dyn_grp4_ev"); + } + return false; +} + + +static bool dyn_grp6(void) { + dyn_get_modrm(); + switch (decode.modrm.reg) { + case 0x00: // SLDT + case 0x01: // STR + if (decode.modrm.reg==0) gen_call_function_raw((void*)CPU_SLDT); + else gen_call_function_raw((void*)CPU_STR); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + dyn_write_word(FC_ADDR,FC_RETOP,false); + } else { + gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); + } + break; + case 0x02: // LLDT + case 0x03: // LTR + case 0x04: // VERR + case 0x05: // VERW + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + dyn_read_word(FC_ADDR,FC_RETOP,false); + } else { + gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); + } + gen_extend_word(false,FC_RETOP); + switch (decode.modrm.reg) { + case 0x02: // LLDT +// if (cpu.cpl) return CPU_PrepareException(EXCEPTION_GP,0); + if (cpu.cpl) E_Exit("lldt cpl>0"); + gen_call_function_R((void*)CPU_LLDT,FC_RETOP); + dyn_check_exception(FC_RETOP); + break; + case 0x03: // LTR +// if (cpu.cpl) return CPU_PrepareException(EXCEPTION_GP,0); + if (cpu.cpl) E_Exit("ltr cpl>0"); + gen_call_function_R((void*)CPU_LTR,FC_RETOP); + dyn_check_exception(FC_RETOP); + break; + case 0x04: // VERR + gen_call_function_R((void*)CPU_VERR,FC_RETOP); + break; + case 0x05: // VERW + gen_call_function_R((void*)CPU_VERW,FC_RETOP); + break; + } + break; + default: IllegalOptionDynrec("dyn_grp6"); + } + return false; +} + +static bool dyn_grp7(void) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + switch (decode.modrm.reg) { + case 0x00: // SGDT + gen_call_function_raw((void*)CPU_SGDT_limit); + dyn_fill_ea(FC_ADDR); + gen_protect_addr_reg(); + dyn_write_word(FC_ADDR,FC_RETOP,false); + gen_call_function_raw((void*)CPU_SGDT_base); + gen_restore_addr_reg(); + gen_add_imm(FC_ADDR,2); + dyn_write_word(FC_ADDR,FC_RETOP,true); + break; + case 0x01: // SIDT + gen_call_function_raw((void*)CPU_SIDT_limit); + dyn_fill_ea(FC_ADDR); + gen_protect_addr_reg(); + dyn_write_word(FC_ADDR,FC_RETOP,false); + gen_call_function_raw((void*)CPU_SIDT_base); + gen_restore_addr_reg(); + gen_add_imm(FC_ADDR,2); + dyn_write_word(FC_ADDR,FC_RETOP,true); + break; + case 0x02: // LGDT + case 0x03: // LIDT +// if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); + if (cpu.pmode && cpu.cpl) IllegalOptionDynrec("lgdt nonpriviledged"); + dyn_fill_ea(FC_ADDR); + gen_protect_addr_reg(); + dyn_read_word(FC_ADDR,FC_OP1,false); + gen_extend_word(false,FC_OP1); + gen_protect_reg(FC_OP1); + + gen_restore_addr_reg(); + gen_add_imm(FC_ADDR,2); + dyn_read_word(FC_ADDR,FC_OP2,true); + if (!decode.big_op) gen_and_imm(FC_OP2,0xffffff); + + gen_restore_reg(FC_OP1); + if (decode.modrm.reg==2) gen_call_function_RR((void*)CPU_LGDT,FC_OP1,FC_OP2); + else gen_call_function_RR((void*)CPU_LIDT,FC_OP1,FC_OP2); + break; + case 0x04: // SMSW + gen_call_function_raw((void*)CPU_SMSW); + dyn_fill_ea(FC_ADDR); + dyn_write_word(FC_ADDR,FC_RETOP,false); + break; + case 0x06: // LMSW + dyn_fill_ea(FC_ADDR); + dyn_read_word(FC_ADDR,FC_RETOP,false); + gen_call_function_R((void*)CPU_LMSW,FC_RETOP); + dyn_check_exception(FC_RETOP); + dyn_set_eip_end(); + dyn_reduce_cycles(); + dyn_return(BR_Normal); + dyn_closeblock(); + return true; + default: IllegalOptionDynrec("dyn_grp7_1"); + } + } else { + switch (decode.modrm.reg) { + case 0x04: // SMSW + gen_call_function_raw((void*)CPU_SMSW); + gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); + break; + case 0x06: // LMSW + gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); + gen_call_function_R((void*)CPU_LMSW,FC_RETOP); + dyn_check_exception(FC_RETOP); + dyn_set_eip_end(); + dyn_reduce_cycles(); + dyn_return(BR_Normal); + dyn_closeblock(); + return true; + default: IllegalOptionDynrec("dyn_grp7_2"); + } + } + return false; +} + + +/* +static void dyn_larlsl(bool is_lar) { + dyn_get_modrm(); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + dyn_read_word(FC_ADDR,FC_RETOP,false); + } else { + gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); + } + gen_extend_word(false,FC_RETOP); + if (is_lar) gen_call_function((void*)CPU_LAR,"%R%A",FC_RETOP,(DRC_PTR_SIZE_IM)&core_dynrec.readdata); + else gen_call_function((void*)CPU_LSL,"%R%A",FC_RETOP,(DRC_PTR_SIZE_IM)&core_dynrec.readdata); + DRC_PTR_SIZE_IM brnz=gen_create_branch_on_nonzero(FC_RETOP,true); + gen_mov_word_to_reg(FC_OP2,&core_dynrec.readdata,true); + gen_mov_word_from_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + gen_fill_branch(brnz); +} +*/ + + +static void dyn_mov_from_crx(void) { + dyn_get_modrm(); + gen_call_function_IA((void*)CPU_READ_CRX,decode.modrm.reg,(DRC_PTR_SIZE_IM)&core_dynrec.readdata); + dyn_check_exception(FC_RETOP); + gen_mov_word_to_reg(FC_OP2,&core_dynrec.readdata,true); + gen_mov_word_from_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.rm,true),true); +} + +static void dyn_mov_to_crx(void) { + dyn_get_modrm(); + gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,true),true); + gen_call_function_IR((void*)CPU_WRITE_CRX,decode.modrm.reg,FC_RETOP); + dyn_check_exception(FC_RETOP); + dyn_set_eip_end(); + dyn_reduce_cycles(); + dyn_return(BR_Normal); + dyn_closeblock(); +} + + +static void dyn_cbw(void) { + if (decode.big_op) { + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,false),false); + gen_call_function_raw((void *)&dynrec_cwde); + gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EAX,true),true); + } else { + gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(DRC_REG_EAX,0)); + gen_call_function_raw((void *)&dynrec_cbw); + gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EAX,false),false); + } +} + +static void dyn_cwd(void) { + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); + if (decode.big_op) { + gen_call_function_raw((void *)&dynrec_cdq); + gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EDX,true),true); + } else { + gen_call_function_raw((void *)&dynrec_cwd); + gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EDX,false),false); + } +} + +static void dyn_sahf(void) { + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,false),false); + gen_call_function_raw((void *)&dynrec_sahf); + InvalidateFlags(); +} + + +static void dyn_exit_link(Bits eip_change) { + gen_add_direct_word(®_eip,(decode.code-decode.code_start)+eip_change,decode.big_op); + dyn_reduce_cycles(); + gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlockDynRec,cache.start)); + dyn_closeblock(); +} + + +static void dyn_branched_exit(BranchTypes btype,Bit32s eip_add) { + Bitu eip_base=decode.code-decode.code_start; + dyn_reduce_cycles(); + + dyn_branchflag_to_reg(btype); + DRC_PTR_SIZE_IM data=gen_create_branch_on_nonzero(FC_RETOP,true); + + // Branch not taken + gen_add_direct_word(®_eip,eip_base,decode.big_op); + gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlockDynRec,cache.start)); + gen_fill_branch(data); + + // Branch taken + gen_add_direct_word(®_eip,eip_base+eip_add,decode.big_op); + gen_jmp_ptr(&decode.block->link[1].to,offsetof(CacheBlockDynRec,cache.start)); + dyn_closeblock(); +} + +/* +static void dyn_set_byte_on_condition(BranchTypes btype) { + dyn_get_modrm(); + dyn_branchflag_to_reg(btype); + gen_and_imm(FC_RETOP,1); + if (decode.modrm.mod<3) { + dyn_fill_ea(FC_ADDR); + dyn_write_byte(FC_ADDR,FC_RETOP); + } else { + gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + } +} +*/ + +static void dyn_loop(LoopTypes type) { + dyn_reduce_cycles(); + Bits eip_add=(Bit8s)decode_fetchb(); + Bitu eip_base=decode.code-decode.code_start; + DRC_PTR_SIZE_IM branch1=0; + DRC_PTR_SIZE_IM branch2=0; + switch (type) { + case LOOP_E: + dyn_branchflag_to_reg(BR_NZ); + branch1=gen_create_branch_on_nonzero(FC_RETOP,true); + break; + case LOOP_NE: + dyn_branchflag_to_reg(BR_Z); + branch1=gen_create_branch_on_nonzero(FC_RETOP,true); + break; + } + switch (type) { + case LOOP_E: + case LOOP_NE: + case LOOP_NONE: + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + gen_add_imm(FC_OP1,(Bit32u)(-1)); + gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + branch2=gen_create_branch_on_zero(FC_OP1,decode.big_addr); + break; + case LOOP_JCXZ: + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + branch2=gen_create_branch_on_nonzero(FC_OP1,decode.big_addr); + break; + } + gen_add_direct_word(®_eip,eip_base+eip_add,true); + gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlockDynRec,cache.start)); + if (branch1) { + gen_fill_branch(branch1); + gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + gen_add_imm(FC_OP1,(Bit32u)(-1)); + gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + } + // Branch taken + gen_fill_branch(branch2); + gen_add_direct_word(®_eip,eip_base,decode.big_op); + gen_jmp_ptr(&decode.block->link[1].to,offsetof(CacheBlockDynRec,cache.start)); + dyn_closeblock(); +} + + +static void dyn_ret_near(Bitu bytes) { + dyn_reduce_cycles(); + + if (decode.big_op) gen_call_function_raw((void*)&dynrec_pop_dword); + else { + gen_call_function_raw((void*)&dynrec_pop_word); + gen_extend_word(false,FC_RETOP); + } + gen_mov_word_from_reg(FC_RETOP,decode.big_op?(void*)(®_eip):(void*)(®_ip),true); + + if (bytes) gen_add_direct_word(®_esp,bytes,true); + dyn_return(BR_Normal); + dyn_closeblock(); +} + +static void dyn_call_near_imm(void) { + Bits imm; + if (decode.big_op) imm=(Bit32s)decode_fetchd(); + else imm=(Bit16s)decode_fetchw(); + dyn_set_eip_end(FC_OP1); + if (decode.big_op) gen_call_function_raw((void*)&dynrec_push_dword); + else gen_call_function_raw((void*)&dynrec_push_word); + + dyn_set_eip_end(FC_OP1,imm); + gen_mov_word_from_reg(FC_OP1,decode.big_op?(void*)(®_eip):(void*)(®_ip),decode.big_op); + + dyn_reduce_cycles(); + gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlockDynRec,cache.start)); + dyn_closeblock(); +} + +static void dyn_ret_far(Bitu bytes) { + dyn_reduce_cycles(); + dyn_set_eip_last_end(FC_RETOP); + gen_call_function_IIR((void*)&CPU_RET,decode.big_op,bytes,FC_RETOP); + dyn_return(BR_Normal); + dyn_closeblock(); +} + +static void dyn_call_far_imm(void) { + Bitu sel,off; + off=decode.big_op ? decode_fetchd() : decode_fetchw(); + sel=decode_fetchw(); + dyn_reduce_cycles(); + dyn_set_eip_last_end(FC_RETOP); + gen_call_function_IIIR((void*)&CPU_CALL,decode.big_op,sel,off,FC_RETOP); + dyn_return(BR_Normal); + dyn_closeblock(); +} + +static void dyn_jmp_far_imm(void) { + Bitu sel,off; + off=decode.big_op ? decode_fetchd() : decode_fetchw(); + sel=decode_fetchw(); + dyn_reduce_cycles(); + dyn_set_eip_last_end(FC_RETOP); + gen_call_function_IIIR((void*)&CPU_JMP,decode.big_op,sel,off,FC_RETOP); + dyn_return(BR_Normal); + dyn_closeblock(); +} + +static void dyn_iret(void) { + dyn_reduce_cycles(); + dyn_set_eip_last_end(FC_RETOP); + gen_call_function_IR((void*)&CPU_IRET,decode.big_op,FC_RETOP); + dyn_return(BR_Iret); + dyn_closeblock(); +} + +static void dyn_interrupt(Bit8u num) { + dyn_reduce_cycles(); + dyn_set_eip_last_end(FC_RETOP); + gen_call_function_IIR((void*)&CPU_Interrupt,num,CPU_INT_SOFTWARE,FC_RETOP); + dyn_return(BR_Normal); + dyn_closeblock(); +} + + + +static void dyn_string(StringOps op) { + if (decode.rep) gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + else gen_mov_dword_to_reg_imm(FC_OP1,1); + gen_mov_word_to_reg(FC_OP2,&cpu.direction,true); + Bit8u di_base_addr=decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS; + switch (op) { + case STR_MOVSB: + if (decode.big_addr) gen_call_function_mm((void*)&dynrec_movsb_dword,(Bitu)DRCD_SEG_PHYS(di_base_addr),(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); + else gen_call_function_mm((void*)&dynrec_movsb_word,(Bitu)DRCD_SEG_PHYS(di_base_addr),(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); + break; + case STR_MOVSW: + if (decode.big_addr) gen_call_function_mm((void*)&dynrec_movsw_dword,(Bitu)DRCD_SEG_PHYS(di_base_addr),(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); + else gen_call_function_mm((void*)&dynrec_movsw_word,(Bitu)DRCD_SEG_PHYS(di_base_addr),(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); + break; + case STR_MOVSD: + if (decode.big_addr) gen_call_function_mm((void*)&dynrec_movsd_dword,(Bitu)DRCD_SEG_PHYS(di_base_addr),(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); + else gen_call_function_mm((void*)&dynrec_movsd_word,(Bitu)DRCD_SEG_PHYS(di_base_addr),(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); + break; + + case STR_LODSB: + if (decode.big_addr) gen_call_function_m((void*)&dynrec_lodsb_dword,(Bitu)DRCD_SEG_PHYS(di_base_addr)); + else gen_call_function_m((void*)&dynrec_lodsb_word,(Bitu)DRCD_SEG_PHYS(di_base_addr)); + break; + case STR_LODSW: + if (decode.big_addr) gen_call_function_m((void*)&dynrec_lodsw_dword,(Bitu)DRCD_SEG_PHYS(di_base_addr)); + else gen_call_function_m((void*)&dynrec_lodsw_word,(Bitu)DRCD_SEG_PHYS(di_base_addr)); + break; + case STR_LODSD: + if (decode.big_addr) gen_call_function_m((void*)&dynrec_lodsd_dword,(Bitu)DRCD_SEG_PHYS(di_base_addr)); + else gen_call_function_m((void*)&dynrec_lodsd_word,(Bitu)DRCD_SEG_PHYS(di_base_addr)); + break; + + case STR_STOSB: + if (decode.big_addr) gen_call_function_m((void*)&dynrec_stosb_dword,(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); + else gen_call_function_m((void*)&dynrec_stosb_word,(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); + break; + case STR_STOSW: + if (decode.big_addr) gen_call_function_m((void*)&dynrec_stosw_dword,(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); + else gen_call_function_m((void*)&dynrec_stosw_word,(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); + break; + case STR_STOSD: + if (decode.big_addr) gen_call_function_m((void*)&dynrec_stosd_dword,(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); + else gen_call_function_m((void*)&dynrec_stosd_word,(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); + break; + default: IllegalOptionDynrec("dyn_string"); + } + if (decode.rep) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + + if (op +#include +#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_call_function_raw((void*)&FPU_PREP_PUSH); + gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); + 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); + gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); + dyn_fill_ea(FC_OP1); + 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); + gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); + dyn_fill_ea(FC_OP1); + 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); + gen_mov_word_to_reg(FC_OP2,(void*)(&fpu.sw),true); + dyn_fill_ea(FC_OP1); + 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); + gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,false),false); + 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); + gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); + dyn_fill_ea(FC_OP1); + 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); + gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); + dyn_fill_ea(FC_OP1); + gen_call_function_RR((void*)&FPU_FBLD,FC_OP1,FC_OP2); + break; + case 0x05: /* FILD Bit64s */ + gen_call_function_raw((void*)&FPU_PREP_PUSH); + gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); + dyn_fill_ea(FC_OP1); + 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 diff --git a/src/cpu/core_dynrec/operators.h b/src/cpu/core_dynrec/operators.h new file mode 100644 index 00000000..21a6dfd4 --- /dev/null +++ b/src/cpu/core_dynrec/operators.h @@ -0,0 +1,1812 @@ +/* + * Copyright (C) 2002-2006 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. + */ + + +static Bit8u DRC_CALL_CONV dynrec_add_byte(Bit8u op1,Bit8u op2) { + lf_var1b=op1; + lf_var2b=op2; + lf_resb=(Bit8u)(lf_var1b+lf_var2b); + lflags.type=t_ADDb; + return lf_resb; +} + +static Bit8u DRC_CALL_CONV dynrec_add_byte_simple(Bit8u op1,Bit8u op2) { + return op1+op2; +} + +static Bit8u DRC_CALL_CONV dynrec_adc_byte(Bit8u op1,Bit8u op2) { + lflags.oldcf=get_CF()!=0; + lf_var1b=op1; + lf_var2b=op2; + lf_resb=(Bit8u)(lf_var1b+lf_var2b+lflags.oldcf); + lflags.type=t_ADCb; + return lf_resb; +} + +static Bit8u DRC_CALL_CONV dynrec_adc_byte_simple(Bit8u op1,Bit8u op2) { + return (Bit8u)(op1+op2+(Bitu)(get_CF()!=0)); +} + +static Bit8u DRC_CALL_CONV dynrec_sub_byte(Bit8u op1,Bit8u op2) { + lf_var1b=op1; + lf_var2b=op2; + lf_resb=(Bit8u)(lf_var1b-lf_var2b); + lflags.type=t_SUBb; + return lf_resb; +} + +static Bit8u DRC_CALL_CONV dynrec_sub_byte_simple(Bit8u op1,Bit8u op2) { + return op1-op2; +} + +static Bit8u DRC_CALL_CONV dynrec_sbb_byte(Bit8u op1,Bit8u op2) { + lflags.oldcf=get_CF()!=0; + lf_var1b=op1; + lf_var2b=op2; + lf_resb=(Bit8u)(lf_var1b-(lf_var2b+lflags.oldcf)); + lflags.type=t_SBBb; + return lf_resb; +} + +static Bit8u DRC_CALL_CONV dynrec_sbb_byte_simple(Bit8u op1,Bit8u op2) { + return (Bit8u)(op1-(op2+(Bitu)(get_CF()!=0))); +} + +static void DRC_CALL_CONV dynrec_cmp_byte(Bit8u op1,Bit8u op2) { + lf_var1b=op1; + lf_var2b=op2; + lf_resb=(Bit8u)(lf_var1b-lf_var2b); + lflags.type=t_CMPb; +} + +static void DRC_CALL_CONV dynrec_cmp_byte_simple(Bit8u op1,Bit8u op2) { +} + +static Bit8u DRC_CALL_CONV dynrec_xor_byte(Bit8u op1,Bit8u op2) { + lf_var1b=op1; + lf_var2b=op2; + lf_resb=lf_var1b ^ lf_var2b; + lflags.type=t_XORb; + return lf_resb; +} + +static Bit8u DRC_CALL_CONV dynrec_xor_byte_simple(Bit8u op1,Bit8u op2) { + return op1 ^ op2; +} + +static Bit8u DRC_CALL_CONV dynrec_and_byte(Bit8u op1,Bit8u op2) { + lf_var1b=op1; + lf_var2b=op2; + lf_resb=lf_var1b & lf_var2b; + lflags.type=t_ANDb; + return lf_resb; +} + +static Bit8u DRC_CALL_CONV dynrec_and_byte_simple(Bit8u op1,Bit8u op2) { + return op1 & op2; +} + +static Bit8u DRC_CALL_CONV dynrec_or_byte(Bit8u op1,Bit8u op2) { + lf_var1b=op1; + lf_var2b=op2; + lf_resb=lf_var1b | lf_var2b; + lflags.type=t_ORb; + return lf_resb; +} + +static Bit8u DRC_CALL_CONV dynrec_or_byte_simple(Bit8u op1,Bit8u op2) { + return op1 | op2; +} + +static void DRC_CALL_CONV dynrec_test_byte(Bit8u op1,Bit8u op2) { + lf_var1b=op1; + lf_var2b=op2; + lf_resb=lf_var1b & lf_var2b; + lflags.type=t_TESTb; +} + +static void DRC_CALL_CONV dynrec_test_byte_simple(Bit8u op1,Bit8u op2) { +} + +static Bit16u DRC_CALL_CONV dynrec_add_word(Bit16u op1,Bit16u op2) { + lf_var1w=op1; + lf_var2w=op2; + lf_resw=(Bit16u)(lf_var1w+lf_var2w); + lflags.type=t_ADDw; + return lf_resw; +} + +static Bit16u DRC_CALL_CONV dynrec_add_word_simple(Bit16u op1,Bit16u op2) { + return op1+op2; +} + +static Bit16u DRC_CALL_CONV dynrec_adc_word(Bit16u op1,Bit16u op2) { + lflags.oldcf=get_CF()!=0; + lf_var1w=op1; + lf_var2w=op2; + lf_resw=(Bit16u)(lf_var1w+lf_var2w+lflags.oldcf); + lflags.type=t_ADCw; + return lf_resw; +} + +static Bit16u DRC_CALL_CONV dynrec_adc_word_simple(Bit16u op1,Bit16u op2) { + return (Bit16u)(op1+op2+(Bitu)(get_CF()!=0)); +} + +static Bit16u DRC_CALL_CONV dynrec_sub_word(Bit16u op1,Bit16u op2) { + lf_var1w=op1; + lf_var2w=op2; + lf_resw=(Bit16u)(lf_var1w-lf_var2w); + lflags.type=t_SUBw; + return lf_resw; +} + +static Bit16u DRC_CALL_CONV dynrec_sub_word_simple(Bit16u op1,Bit16u op2) { + return op1-op2; +} + +static Bit16u DRC_CALL_CONV dynrec_sbb_word(Bit16u op1,Bit16u op2) { + lflags.oldcf=get_CF()!=0; + lf_var1w=op1; + lf_var2w=op2; + lf_resw=(Bit16u)(lf_var1w-(lf_var2w+lflags.oldcf)); + lflags.type=t_SBBw; + return lf_resw; +} + +static Bit16u DRC_CALL_CONV dynrec_sbb_word_simple(Bit16u op1,Bit16u op2) { + return (Bit16u)(op1-(op2+(Bitu)(get_CF()!=0))); +} + +static void DRC_CALL_CONV dynrec_cmp_word(Bit16u op1,Bit16u op2) { + lf_var1w=op1; + lf_var2w=op2; + lf_resw=(Bit16u)(lf_var1w-lf_var2w); + lflags.type=t_CMPw; +} + +static void DRC_CALL_CONV dynrec_cmp_word_simple(Bit16u op1,Bit16u op2) { +} + +static Bit16u DRC_CALL_CONV dynrec_xor_word(Bit16u op1,Bit16u op2) { + lf_var1w=op1; + lf_var2w=op2; + lf_resw=lf_var1w ^ lf_var2w; + lflags.type=t_XORw; + return lf_resw; +} + +static Bit16u DRC_CALL_CONV dynrec_xor_word_simple(Bit16u op1,Bit16u op2) { + return op1 ^ op2; +} + +static Bit16u DRC_CALL_CONV dynrec_and_word(Bit16u op1,Bit16u op2) { + lf_var1w=op1; + lf_var2w=op2; + lf_resw=lf_var1w & lf_var2w; + lflags.type=t_ANDw; + return lf_resw; +} + +static Bit16u DRC_CALL_CONV dynrec_and_word_simple(Bit16u op1,Bit16u op2) { + return op1 & op2; +} + +static Bit16u DRC_CALL_CONV dynrec_or_word(Bit16u op1,Bit16u op2) { + lf_var1w=op1; + lf_var2w=op2; + lf_resw=lf_var1w | lf_var2w; + lflags.type=t_ORw; + return lf_resw; +} + +static Bit16u DRC_CALL_CONV dynrec_or_word_simple(Bit16u op1,Bit16u op2) { + return op1 | op2; +} + +static void DRC_CALL_CONV dynrec_test_word(Bit16u op1,Bit16u op2) { + lf_var1w=op1; + lf_var2w=op2; + lf_resw=lf_var1w & lf_var2w; + lflags.type=t_TESTw; +} + +static void DRC_CALL_CONV dynrec_test_word_simple(Bit16u op1,Bit16u op2) { +} + +static Bit32u DRC_CALL_CONV dynrec_add_dword(Bit32u op1,Bit32u op2) { + lf_var1d=op1; + lf_var2d=op2; + lf_resd=lf_var1d+lf_var2d; + lflags.type=t_ADDd; + return lf_resd; +} + +static Bit32u DRC_CALL_CONV dynrec_add_dword_simple(Bit32u op1,Bit32u op2) { + return op1 + op2; +} + +static Bit32u DRC_CALL_CONV dynrec_adc_dword(Bit32u op1,Bit32u op2) { + lflags.oldcf=get_CF()!=0; + lf_var1d=op1; + lf_var2d=op2; + lf_resd=lf_var1d+lf_var2d+lflags.oldcf; + lflags.type=t_ADCd; + return lf_resd; +} + +static Bit32u DRC_CALL_CONV dynrec_adc_dword_simple(Bit32u op1,Bit32u op2) { + return op1+op2+(Bitu)(get_CF()!=0); +} + +static Bit32u DRC_CALL_CONV dynrec_sub_dword(Bit32u op1,Bit32u op2) { + lf_var1d=op1; + lf_var2d=op2; + lf_resd=lf_var1d-lf_var2d; + lflags.type=t_SUBd; + return lf_resd; +} + +static Bit32u DRC_CALL_CONV dynrec_sub_dword_simple(Bit32u op1,Bit32u op2) { + return op1-op2; +} + +static Bit32u DRC_CALL_CONV dynrec_sbb_dword(Bit32u op1,Bit32u op2) { + lflags.oldcf=get_CF()!=0; + lf_var1d=op1; + lf_var2d=op2; + lf_resd=lf_var1d-(lf_var2d+lflags.oldcf); + lflags.type=t_SBBd; + return lf_resd; +} + +static Bit32u DRC_CALL_CONV dynrec_sbb_dword_simple(Bit32u op1,Bit32u op2) { + return op1-(op2+(Bitu)(get_CF()!=0)); +} + +static void DRC_CALL_CONV dynrec_cmp_dword(Bit32u op1,Bit32u op2) { + lf_var1d=op1; + lf_var2d=op2; + lf_resd=lf_var1d-lf_var2d; + lflags.type=t_CMPd; +} + +static void DRC_CALL_CONV dynrec_cmp_dword_simple(Bit32u op1,Bit32u op2) { +} + +static Bit32u DRC_CALL_CONV dynrec_xor_dword(Bit32u op1,Bit32u op2) { + lf_var1d=op1; + lf_var2d=op2; + lf_resd=lf_var1d ^ lf_var2d; + lflags.type=t_XORd; + return lf_resd; +} + +static Bit32u DRC_CALL_CONV dynrec_xor_dword_simple(Bit32u op1,Bit32u op2) { + return op1 ^ op2; +} + +static Bit32u DRC_CALL_CONV dynrec_and_dword(Bit32u op1,Bit32u op2) { + lf_var1d=op1; + lf_var2d=op2; + lf_resd=lf_var1d & lf_var2d; + lflags.type=t_ANDd; + return lf_resd; +} + +static Bit32u DRC_CALL_CONV dynrec_and_dword_simple(Bit32u op1,Bit32u op2) { + return op1 & op2; +} + +static Bit32u DRC_CALL_CONV dynrec_or_dword(Bit32u op1,Bit32u op2) { + lf_var1d=op1; + lf_var2d=op2; + lf_resd=lf_var1d | lf_var2d; + lflags.type=t_ORd; + return lf_resd; +} + +static Bit32u DRC_CALL_CONV dynrec_or_dword_simple(Bit32u op1,Bit32u op2) { + return op1 | op2; +} + +static void DRC_CALL_CONV dynrec_test_dword(Bit32u op1,Bit32u op2) { + lf_var1d=op1; + lf_var2d=op2; + lf_resd=lf_var1d & lf_var2d; + lflags.type=t_TESTd; +} + +static void DRC_CALL_CONV dynrec_test_dword_simple(Bit32u op1,Bit32u op2) { +} + + +static void dyn_dop_byte_gencall(DualOps op) { + switch (op) { + case DOP_ADD: + InvalidateFlags((void*)&dynrec_add_byte_simple); + gen_call_function_raw((void*)&dynrec_add_byte); + break; + case DOP_ADC: + AcquireFlags(FLAG_CF); + InvalidateFlagsPartially((void*)&dynrec_adc_byte_simple); + gen_call_function_raw((void*)&dynrec_adc_byte); + break; + case DOP_SUB: + InvalidateFlags((void*)&dynrec_sub_byte_simple); + gen_call_function_raw((void*)&dynrec_sub_byte); + break; + case DOP_SBB: + AcquireFlags(FLAG_CF); + InvalidateFlagsPartially((void*)&dynrec_sbb_byte_simple); + gen_call_function_raw((void*)&dynrec_sbb_byte); + break; + case DOP_CMP: + InvalidateFlags((void*)&dynrec_cmp_byte_simple); + gen_call_function_raw((void*)&dynrec_cmp_byte); + break; + case DOP_XOR: + InvalidateFlags((void*)&dynrec_xor_byte_simple); + gen_call_function_raw((void*)&dynrec_xor_byte); + break; + case DOP_AND: + InvalidateFlags((void*)&dynrec_and_byte_simple); + gen_call_function_raw((void*)&dynrec_and_byte); + break; + case DOP_OR: + InvalidateFlags((void*)&dynrec_or_byte_simple); + gen_call_function_raw((void*)&dynrec_or_byte); + break; + case DOP_TEST: + InvalidateFlags((void*)&dynrec_test_byte_simple); + gen_call_function_raw((void*)&dynrec_test_byte); + break; + default: IllegalOptionDynrec("dyn_dop_byte_gencall"); + } +} + +static void dyn_dop_word_gencall(DualOps op,bool dword) { + if (dword) { + switch (op) { + case DOP_ADD: + InvalidateFlags((void*)&dynrec_add_dword_simple); + gen_call_function_raw((void*)&dynrec_add_dword); + break; + case DOP_ADC: + AcquireFlags(FLAG_CF); + InvalidateFlagsPartially((void*)&dynrec_adc_dword_simple); + gen_call_function_raw((void*)&dynrec_adc_dword); + break; + case DOP_SUB: + InvalidateFlags((void*)&dynrec_sub_dword_simple); + gen_call_function_raw((void*)&dynrec_sub_dword); + break; + case DOP_SBB: + AcquireFlags(FLAG_CF); + InvalidateFlagsPartially((void*)&dynrec_sbb_dword_simple); + gen_call_function_raw((void*)&dynrec_sbb_dword); + break; + case DOP_CMP: + InvalidateFlags((void*)&dynrec_cmp_dword_simple); + gen_call_function_raw((void*)&dynrec_cmp_dword); + break; + case DOP_XOR: + InvalidateFlags((void*)&dynrec_xor_dword_simple); + gen_call_function_raw((void*)&dynrec_xor_dword); + break; + case DOP_AND: + InvalidateFlags((void*)&dynrec_and_dword_simple); + gen_call_function_raw((void*)&dynrec_and_dword); + break; + case DOP_OR: + InvalidateFlags((void*)&dynrec_or_dword_simple); + gen_call_function_raw((void*)&dynrec_or_dword); + break; + case DOP_TEST: + InvalidateFlags((void*)&dynrec_test_dword_simple); + gen_call_function_raw((void*)&dynrec_test_dword); + break; + default: IllegalOptionDynrec("dyn_dop_dword_gencall"); + } + } else { + switch (op) { + case DOP_ADD: + InvalidateFlags((void*)&dynrec_add_word_simple); + gen_call_function_raw((void*)&dynrec_add_word); + break; + case DOP_ADC: + AcquireFlags(FLAG_CF); + InvalidateFlagsPartially((void*)&dynrec_adc_word_simple); + gen_call_function_raw((void*)&dynrec_adc_word); + break; + case DOP_SUB: + InvalidateFlags((void*)&dynrec_sub_word_simple); + gen_call_function_raw((void*)&dynrec_sub_word); + break; + case DOP_SBB: + AcquireFlags(FLAG_CF); + InvalidateFlagsPartially((void*)&dynrec_sbb_word_simple); + gen_call_function_raw((void*)&dynrec_sbb_word); + break; + case DOP_CMP: + InvalidateFlags((void*)&dynrec_cmp_word_simple); + gen_call_function_raw((void*)&dynrec_cmp_word); + break; + case DOP_XOR: + InvalidateFlags((void*)&dynrec_xor_word_simple); + gen_call_function_raw((void*)&dynrec_xor_word); + break; + case DOP_AND: + InvalidateFlags((void*)&dynrec_and_word_simple); + gen_call_function_raw((void*)&dynrec_and_word); + break; + case DOP_OR: + InvalidateFlags((void*)&dynrec_or_word_simple); + gen_call_function_raw((void*)&dynrec_or_word); + break; + case DOP_TEST: + InvalidateFlags((void*)&dynrec_test_word_simple); + gen_call_function_raw((void*)&dynrec_test_word); + break; + default: IllegalOptionDynrec("dyn_dop_word_gencall"); + } + } +} + + +static Bit8u DRC_CALL_CONV dynrec_inc_byte(Bit8u op) { + LoadCF; + lf_var1b=op; + lf_resb=lf_var1b+1; + lflags.type=t_INCb; + return lf_resb; +} + +static Bit8u DRC_CALL_CONV dynrec_inc_byte_simple(Bit8u op) { + return op+1; +} + +static Bit8u DRC_CALL_CONV dynrec_dec_byte(Bit8u op) { + LoadCF; + lf_var1b=op; + lf_resb=lf_var1b-1; + lflags.type=t_DECb; + return lf_resb; +} + +static Bit8u DRC_CALL_CONV dynrec_dec_byte_simple(Bit8u op) { + return op-1; +} + +static Bit8u DRC_CALL_CONV dynrec_not_byte(Bit8u op) { + return ~op; +} + +static Bit8u DRC_CALL_CONV dynrec_neg_byte(Bit8u op) { + lf_var1b=op; + lf_resb=0-lf_var1b; + lflags.type=t_NEGb; + return lf_resb; +} + +static Bit8u DRC_CALL_CONV dynrec_neg_byte_simple(Bit8u op) { + return 0-op; +} + +static Bit16u DRC_CALL_CONV dynrec_inc_word(Bit16u op) { + LoadCF; + lf_var1w=op; + lf_resw=lf_var1w+1; + lflags.type=t_INCw; + return lf_resw; +} + +static Bit16u DRC_CALL_CONV dynrec_inc_word_simple(Bit16u op) { + return op+1; +} + +static Bit16u DRC_CALL_CONV dynrec_dec_word(Bit16u op) { + LoadCF; + lf_var1w=op; + lf_resw=lf_var1w-1; + lflags.type=t_DECw; + return lf_resw; +} + +static Bit16u DRC_CALL_CONV dynrec_dec_word_simple(Bit16u op) { + return op-1; +} + +static Bit16u DRC_CALL_CONV dynrec_not_word(Bit16u op) { + return ~op; +} + +static Bit16u DRC_CALL_CONV dynrec_neg_word(Bit16u op) { + lf_var1w=op; + lf_resw=0-lf_var1w; + lflags.type=t_NEGw; + return lf_resw; +} + +static Bit16u DRC_CALL_CONV dynrec_neg_word_simple(Bit16u op) { + return 0-op; +} + +static Bit32u DRC_CALL_CONV dynrec_inc_dword(Bit32u op) { + LoadCF; + lf_var1d=op; + lf_resd=lf_var1d+1; + lflags.type=t_INCd; + return lf_resd; +} + +static Bit32u DRC_CALL_CONV dynrec_inc_dword_simple(Bit32u op) { + return op+1; +} + +static Bit32u DRC_CALL_CONV dynrec_dec_dword(Bit32u op) { + LoadCF; + lf_var1d=op; + lf_resd=lf_var1d-1; + lflags.type=t_DECd; + return lf_resd; +} + +static Bit32u DRC_CALL_CONV dynrec_dec_dword_simple(Bit32u op) { + return op-1; +} + +static Bit32u DRC_CALL_CONV dynrec_not_dword(Bit32u op) { + return ~op; +} + +static Bit32u DRC_CALL_CONV dynrec_neg_dword(Bit32u op) { + lf_var1d=op; + lf_resd=0-lf_var1d; + lflags.type=t_NEGd; + return lf_resd; +} + +static Bit32u DRC_CALL_CONV dynrec_neg_dword_simple(Bit32u op) { + return 0-op; +} + + +static void dyn_sop_byte_gencall(SingleOps op) { + switch (op) { + case SOP_INC: + InvalidateFlagsPartially((void*)&dynrec_inc_byte_simple); + gen_call_function_raw((void*)&dynrec_inc_byte); + break; + case SOP_DEC: + InvalidateFlagsPartially((void*)&dynrec_dec_byte_simple); + gen_call_function_raw((void*)&dynrec_dec_byte); + break; + case SOP_NOT: + gen_call_function_raw((void*)&dynrec_not_byte); + break; + case SOP_NEG: + InvalidateFlags((void*)&dynrec_neg_byte_simple); + gen_call_function_raw((void*)&dynrec_neg_byte); + break; + default: IllegalOptionDynrec("dyn_sop_byte_gencall"); + } +} + +static void dyn_sop_word_gencall(SingleOps op,bool dword) { + if (dword) { + switch (op) { + case SOP_INC: + InvalidateFlagsPartially((void*)&dynrec_inc_dword_simple); + gen_call_function_raw((void*)&dynrec_inc_dword); + break; + case SOP_DEC: + InvalidateFlagsPartially((void*)&dynrec_dec_dword_simple); + gen_call_function_raw((void*)&dynrec_dec_dword); + break; + case SOP_NOT: + gen_call_function_raw((void*)&dynrec_not_dword); + break; + case SOP_NEG: + InvalidateFlags((void*)&dynrec_neg_dword_simple); + gen_call_function_raw((void*)&dynrec_neg_dword); + break; + default: IllegalOptionDynrec("dyn_sop_dword_gencall"); + } + } else { + switch (op) { + case SOP_INC: + InvalidateFlagsPartially((void*)&dynrec_inc_word_simple); + gen_call_function_raw((void*)&dynrec_inc_word); + break; + case SOP_DEC: + InvalidateFlagsPartially((void*)&dynrec_dec_word_simple); + gen_call_function_raw((void*)&dynrec_dec_word); + break; + case SOP_NOT: + gen_call_function_raw((void*)&dynrec_not_word); + break; + case SOP_NEG: + InvalidateFlags((void*)&dynrec_neg_word_simple); + gen_call_function_raw((void*)&dynrec_neg_word); + break; + default: IllegalOptionDynrec("dyn_sop_word_gencall"); + } + } +} + + +static Bit8u DRC_CALL_CONV dynrec_rol_byte(Bit8u op1,Bit8u op2) { + if (!(op2&0x7)) { + if (op2&0x18) { + FillFlags(); + SETFLAGBIT(CF,op1 & 1); + SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 7)); + } + return op1; + } + FillFlags(); + lf_var1b=op1; + lf_var2b=op2&0x07; + lf_resb=(lf_var1b << lf_var2b) | (lf_var1b >> (8-lf_var2b)); + SETFLAGBIT(CF,lf_resb & 1); + SETFLAGBIT(OF,(lf_resb & 1) ^ (lf_resb >> 7)); + return lf_resb; +} + +static Bit8u DRC_CALL_CONV dynrec_rol_byte_simple(Bit8u op1,Bit8u op2) { + if (!(op2&0x7)) return op1; + return (op1 << (op2&0x07)) | (op1 >> (8-(op2&0x07))); +} + +static Bit8u DRC_CALL_CONV dynrec_ror_byte(Bit8u op1,Bit8u op2) { + if (!(op2&0x7)) { + if (op2&0x10) { + FillFlags(); + SETFLAGBIT(CF,op1>>7); + SETFLAGBIT(OF,(op1>>7) ^ ((op1>>6) & 1)); + } + return op1; + } + FillFlags(); + lf_var1b=op1; + lf_var2b=op2&0x07; + lf_resb=(lf_var1b >> lf_var2b) | (lf_var1b << (8-lf_var2b)); + SETFLAGBIT(CF,lf_resb & 0x80); + if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resb ^ lf_var1b) & 0x80); + return lf_resb; +} + +static Bit8u DRC_CALL_CONV dynrec_ror_byte_simple(Bit8u op1,Bit8u op2) { + if (!(op2&0x7)) return op1; + return (op1 >> (op2&0x07)) | (op1 << (8-(op2&0x07))); +} + +static Bit8u DRC_CALL_CONV dynrec_rcl_byte(Bit8u op1,Bit8u op2) { + if (op2%9) { + Bit8u cf=(Bit8u)FillFlags()&0x1; + lf_var1b=op1; + lf_var2b=op2%9; + lf_resb=(lf_var1b << lf_var2b) | (cf << (lf_var2b-1)) | (lf_var1b >> (9-lf_var2b)); + SETFLAGBIT(CF,((lf_var1b >> (8-lf_var2b)) & 1)); + SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resb >> 7)); + return lf_resb; + } else return op1; +} + +static Bit8u DRC_CALL_CONV dynrec_rcr_byte(Bit8u op1,Bit8u op2) { + if (op2%9) { + Bit8u cf=(Bit8u)FillFlags()&0x1; + lf_var1b=op1; + lf_var2b=op2%9; + lf_resb=(lf_var1b >> lf_var2b) | (cf << (8-lf_var2b)) | (lf_var1b << (9-lf_var2b)); \ + SETFLAGBIT(CF,(lf_var1b >> (lf_var2b - 1)) & 1); + SETFLAGBIT(OF,(lf_resb ^ lf_var1b) & 0x80); + return lf_resb; + } else return op1; +} + +static Bit8u DRC_CALL_CONV dynrec_shl_byte(Bit8u op1,Bit8u op2) { + if (!op2) return op1; + lf_var1b=op1; + lf_var2b=op2; + lf_resb=lf_var1b << lf_var2b; + lflags.type=t_SHLb; + return lf_resb; +} + +static Bit8u DRC_CALL_CONV dynrec_shl_byte_simple(Bit8u op1,Bit8u op2) { + if (!op2) return op1; + return op1 << op2; +} + +static Bit8u DRC_CALL_CONV dynrec_shr_byte(Bit8u op1,Bit8u op2) { + if (!op2) return op1; + lf_var1b=op1; + lf_var2b=op2; + lf_resb=lf_var1b >> lf_var2b; + lflags.type=t_SHRb; + return lf_resb; +} + +static Bit8u DRC_CALL_CONV dynrec_shr_byte_simple(Bit8u op1,Bit8u op2) { + if (!op2) return op1; + return op1 >> op2; +} + +static Bit8u DRC_CALL_CONV dynrec_sar_byte(Bit8u op1,Bit8u op2) { + if (!op2) return op1; + lf_var1b=op1; + lf_var2b=op2; + if (lf_var2b>8) lf_var2b=8; + if (lf_var1b & 0x80) { + lf_resb=(lf_var1b >> lf_var2b)| (0xff << (8 - lf_var2b)); + } else { + lf_resb=lf_var1b >> lf_var2b; + } + lflags.type=t_SARb; + return lf_resb; +} + +static Bit8u DRC_CALL_CONV dynrec_sar_byte_simple(Bit8u op1,Bit8u op2) { + if (!op2) return op1; + if (op2>8) op2=8; + if (op1 & 0x80) return (op1 >> op2) | (0xff << (8 - op2)); + else return op1 >> op2; +} + +static Bit16u DRC_CALL_CONV dynrec_rol_word(Bit16u op1,Bit8u op2) { + if (!(op2&0xf)) { + if (op2&0x10) { + FillFlags(); + SETFLAGBIT(CF,op1 & 1); + } + return op1; + } + FillFlags(); + lf_var1w=op1; + lf_var2b=op2&0xf; + lf_resw=(lf_var1w << lf_var2b) | (lf_var1w >> (16-lf_var2b)); + SETFLAGBIT(CF,lf_resw & 1); + SETFLAGBIT(OF,(lf_resw & 1) ^ (lf_resw >> 15)); + return lf_resw; +} + +static Bit16u DRC_CALL_CONV dynrec_rol_word_simple(Bit16u op1,Bit8u op2) { + if (!(op2&0xf)) return op1; + return (op1 << (op2&0xf)) | (op1 >> (16-(op2&0xf))); +} + +static Bit16u DRC_CALL_CONV dynrec_ror_word(Bit16u op1,Bit8u op2) { + if (!(op2&0xf)) { + if (op2&0x10) { + FillFlags(); + SETFLAGBIT(CF,op1>>15); + } + return op1; + } + FillFlags(); + lf_var1w=op1; + lf_var2b=op2&0xf; + lf_resw=(lf_var1w >> lf_var2b) | (lf_var1w << (16-lf_var2b)); + SETFLAGBIT(CF,lf_resw & 0x8000); + if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resw ^ lf_var1w) & 0x8000); + return lf_resw; +} + +static Bit16u DRC_CALL_CONV dynrec_ror_word_simple(Bit16u op1,Bit8u op2) { + if (!(op2&0xf)) return op1; + return (op1 >> (op2&0xf)) | (op1 << (16-(op2&0xf))); +} + +static Bit16u DRC_CALL_CONV dynrec_rcl_word(Bit16u op1,Bit8u op2) { + if (op2%17) { + Bit16u cf=(Bit16u)FillFlags()&0x1; + lf_var1w=op1; + lf_var2b=op2%17; + lf_resw=(lf_var1w << lf_var2b) | (cf << (lf_var2b-1)) | (lf_var1w >> (17-lf_var2b)); + SETFLAGBIT(CF,((lf_var1w >> (16-lf_var2b)) & 1)); + SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resw >> 15)); + return lf_resw; + } else return op1; +} + +static Bit16u DRC_CALL_CONV dynrec_rcr_word(Bit16u op1,Bit8u op2) { + if (op2%17) { + Bit16u cf=(Bit16u)FillFlags()&0x1; + lf_var1w=op1; + lf_var2b=op2%17; + lf_resw=(lf_var1w >> lf_var2b) | (cf << (16-lf_var2b)) | (lf_var1w << (17-lf_var2b)); + SETFLAGBIT(CF,(lf_var1w >> (lf_var2b - 1)) & 1); + SETFLAGBIT(OF,(lf_resw ^ lf_var1w) & 0x8000); + return lf_resw; + } else return op1; +} + +static Bit16u DRC_CALL_CONV dynrec_shl_word(Bit16u op1,Bit8u op2) { + if (!op2) return op1; + lf_var1w=op1; + lf_var2b=op2; + lf_resw=lf_var1w << lf_var2b; + lflags.type=t_SHLw; + return lf_resw; +} + +static Bit16u DRC_CALL_CONV dynrec_shl_word_simple(Bit16u op1,Bit8u op2) { + if (!op2) return op1; + return op1 << op2; +} + +static Bit16u DRC_CALL_CONV dynrec_shr_word(Bit16u op1,Bit8u op2) { + if (!op2) return op1; + lf_var1w=op1; + lf_var2b=op2; + lf_resw=lf_var1w >> lf_var2b; + lflags.type=t_SHRw; + return lf_resw; +} + +static Bit16u DRC_CALL_CONV dynrec_shr_word_simple(Bit16u op1,Bit8u op2) { + if (!op2) return op1; + return op1 >> op2; +} + +static Bit16u DRC_CALL_CONV dynrec_sar_word(Bit16u op1,Bit8u op2) { + if (!op2) return op1; + lf_var1w=op1; + lf_var2b=op2; + if (lf_var2b>16) lf_var2b=16; + if (lf_var1w & 0x8000) { + lf_resw=(lf_var1w >> lf_var2b) | (0xffff << (16 - lf_var2b)); + } else { + lf_resw=lf_var1w >> lf_var2b; + } + lflags.type=t_SARw; + return lf_resw; +} + +static Bit16u DRC_CALL_CONV dynrec_sar_word_simple(Bit16u op1,Bit8u op2) { + if (!op2) return op1; + if (op2>16) op2=16; + if (op1 & 0x8000) return (op1 >> op2) | (0xffff << (16 - op2)); + else return op1 >> op2; +} + +static Bit32u DRC_CALL_CONV dynrec_rol_dword(Bit32u op1,Bit8u op2) { + if (!op2) return op1; + FillFlags(); + lf_var1d=op1; + lf_var2b=op2; + lf_resd=(lf_var1d << lf_var2b) | (lf_var1d >> (32-lf_var2b)); + SETFLAGBIT(CF,lf_resd & 1); + SETFLAGBIT(OF,(lf_resd & 1) ^ (lf_resd >> 31)); + return lf_resd; +} + +static Bit32u DRC_CALL_CONV dynrec_rol_dword_simple(Bit32u op1,Bit8u op2) { + if (!op2) return op1; + return (op1 << op2) | (op1 >> (32-op2)); +} + +static Bit32u DRC_CALL_CONV dynrec_ror_dword(Bit32u op1,Bit8u op2) { + if (!op2) return op1; + FillFlags(); + lf_var1d=op1; + lf_var2b=op2; + lf_resd=(lf_var1d >> lf_var2b) | (lf_var1d << (32-lf_var2b)); + SETFLAGBIT(CF,lf_resd & 0x80000000); + if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resd ^ lf_var1d) & 0x80000000); + return lf_resd; +} + +static Bit32u DRC_CALL_CONV dynrec_ror_dword_simple(Bit32u op1,Bit8u op2) { + if (!op2) return op1; + return (op1 >> op2) | (op1 << (32-op2)); +} + +static Bit32u DRC_CALL_CONV dynrec_rcl_dword(Bit32u op1,Bit8u op2) { + if (!op2) return op1; + Bit32u cf=(Bit32u)FillFlags()&0x1; + lf_var1d=op1; + lf_var2b=op2; + if (lf_var2b==1) { + lf_resd=(lf_var1d << 1) | cf; + } else { + lf_resd=(lf_var1d << lf_var2b) | (cf << (lf_var2b-1)) | (lf_var1d >> (33-lf_var2b)); + } + SETFLAGBIT(CF,((lf_var1d >> (32-lf_var2b)) & 1)); + SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resd >> 31)); + return lf_resd; +} + +static Bit32u DRC_CALL_CONV dynrec_rcr_dword(Bit32u op1,Bit8u op2) { + if (op2) { + Bit32u cf=(Bit32u)FillFlags()&0x1; + lf_var1d=op1; + lf_var2b=op2; + if (lf_var2b==1) { + lf_resd=lf_var1d >> 1 | cf << 31; + } else { + lf_resd=(lf_var1d >> lf_var2b) | (cf << (32-lf_var2b)) | (lf_var1d << (33-lf_var2b)); + } + SETFLAGBIT(CF,(lf_var1d >> (lf_var2b - 1)) & 1); + SETFLAGBIT(OF,(lf_resd ^ lf_var1d) & 0x80000000); + return lf_resd; + } else return op1; +} + +static Bit32u DRC_CALL_CONV dynrec_shl_dword(Bit32u op1,Bit8u op2) { + if (!op2) return op1; + lf_var1d=op1; + lf_var2b=op2; + lf_resd=lf_var1d << lf_var2b; + lflags.type=t_SHLd; + return lf_resd; +} + +static Bit32u DRC_CALL_CONV dynrec_shl_dword_simple(Bit32u op1,Bit8u op2) { + if (!op2) return op1; + return op1 << op2; +} + +static Bit32u DRC_CALL_CONV dynrec_shr_dword(Bit32u op1,Bit8u op2) { + if (!op2) return op1; + lf_var1d=op1; + lf_var2b=op2; + lf_resd=lf_var1d >> lf_var2b; + lflags.type=t_SHRd; + return lf_resd; +} + +static Bit32u DRC_CALL_CONV dynrec_shr_dword_simple(Bit32u op1,Bit8u op2) { + if (!op2) return op1; + return op1 >> op2; +} + +static Bit32u DRC_CALL_CONV dynrec_sar_dword(Bit32u op1,Bit8u op2) { + if (!op2) return op1; + lf_var2b=op2; + lf_var1d=op1; + if (lf_var1d & 0x80000000) { + lf_resd=(lf_var1d >> lf_var2b) | (0xffffffff << (32 - lf_var2b)); + } else { + lf_resd=lf_var1d >> lf_var2b; + } + lflags.type=t_SARd; + return lf_resd; +} + +static Bit32u DRC_CALL_CONV dynrec_sar_dword_simple(Bit32u op1,Bit8u op2) { + if (!op2) return op1; + if (op1 & 0x80000000) return (op1 >> op2) | (0xffffffff << (32 - op2)); + else return op1 >> op2; +} + +static void dyn_shift_byte_gencall(ShiftOps op) { + switch (op) { + case SHIFT_ROL: + InvalidateFlagsPartially((void*)&dynrec_rol_byte_simple); + gen_call_function_raw((void*)&dynrec_rol_byte); + break; + case SHIFT_ROR: + InvalidateFlagsPartially((void*)&dynrec_ror_byte_simple); + gen_call_function_raw((void*)&dynrec_ror_byte); + break; + case SHIFT_RCL: + AcquireFlags(FLAG_CF); + gen_call_function_raw((void*)&dynrec_rcl_byte); + break; + case SHIFT_RCR: + AcquireFlags(FLAG_CF); + gen_call_function_raw((void*)&dynrec_rcr_byte); + break; + case SHIFT_SHL: + case SHIFT_SAL: + InvalidateFlagsPartially((void*)&dynrec_shl_byte_simple); + gen_call_function_raw((void*)&dynrec_shl_byte); + break; + case SHIFT_SHR: + InvalidateFlagsPartially((void*)&dynrec_shr_byte_simple); + gen_call_function_raw((void*)&dynrec_shr_byte); + break; + case SHIFT_SAR: + InvalidateFlagsPartially((void*)&dynrec_sar_byte_simple); + gen_call_function_raw((void*)&dynrec_sar_byte); + break; + default: IllegalOptionDynrec("dyn_shift_byte_gencall"); + } +} + +static void dyn_shift_word_gencall(ShiftOps op,bool dword) { + if (dword) { + switch (op) { + case SHIFT_ROL: + InvalidateFlagsPartially((void*)&dynrec_rol_dword_simple); + gen_call_function_raw((void*)&dynrec_rol_dword); + break; + case SHIFT_ROR: + InvalidateFlagsPartially((void*)&dynrec_ror_dword_simple); + gen_call_function_raw((void*)&dynrec_ror_dword); + break; + case SHIFT_RCL: + AcquireFlags(FLAG_CF); + gen_call_function_raw((void*)&dynrec_rcl_dword); + break; + case SHIFT_RCR: + AcquireFlags(FLAG_CF); + gen_call_function_raw((void*)&dynrec_rcr_dword); + break; + case SHIFT_SHL: + case SHIFT_SAL: + InvalidateFlagsPartially((void*)&dynrec_shl_dword_simple); + gen_call_function_raw((void*)&dynrec_shl_dword); + break; + case SHIFT_SHR: + InvalidateFlagsPartially((void*)&dynrec_shr_dword_simple); + gen_call_function_raw((void*)&dynrec_shr_dword); + break; + case SHIFT_SAR: + InvalidateFlagsPartially((void*)&dynrec_sar_dword_simple); + gen_call_function_raw((void*)&dynrec_sar_dword); + break; + default: IllegalOptionDynrec("dyn_shift_dword_gencall"); + } + } else { + switch (op) { + case SHIFT_ROL: + InvalidateFlagsPartially((void*)&dynrec_rol_word_simple); + gen_call_function_raw((void*)&dynrec_rol_word); + break; + case SHIFT_ROR: + InvalidateFlagsPartially((void*)&dynrec_ror_word_simple); + gen_call_function_raw((void*)&dynrec_ror_word); + break; + case SHIFT_RCL: + AcquireFlags(FLAG_CF); + gen_call_function_raw((void*)&dynrec_rcl_word); + break; + case SHIFT_RCR: + AcquireFlags(FLAG_CF); + gen_call_function_raw((void*)&dynrec_rcr_word); + break; + case SHIFT_SHL: + case SHIFT_SAL: + InvalidateFlagsPartially((void*)&dynrec_shl_word_simple); + gen_call_function_raw((void*)&dynrec_shl_word); + break; + case SHIFT_SHR: + InvalidateFlagsPartially((void*)&dynrec_shr_word_simple); + gen_call_function_raw((void*)&dynrec_shr_word); + break; + case SHIFT_SAR: + InvalidateFlagsPartially((void*)&dynrec_sar_word_simple); + gen_call_function_raw((void*)&dynrec_sar_word); + break; + default: IllegalOptionDynrec("dyn_shift_word_gencall"); + } + } +} + +static Bit16u DRC_CALL_CONV dynrec_dshl_word(Bit16u op1,Bit16u op2,Bit8u op3) { + Bit8u val=op3 & 0x1f; + if (!val) return op1; + lf_var2b=val; + lf_var1d=(op1<<16)|op2; + Bit32u tempd=lf_var1d << lf_var2b; + if (lf_var2b>16) tempd |= (op2 << (lf_var2b - 16)); + lf_resw=(Bit16u)(tempd >> 16); + lflags.type=t_DSHLw; + return lf_resw; +} + +static Bit16u DRC_CALL_CONV dynrec_dshl_word_simple(Bit16u op1,Bit16u op2,Bit8u op3) { + Bit8u val=op3 & 0x1f; + if (!val) return op1; + Bit32u tempd=(Bit32u)((((Bit32u)op1)<<16)|op2) << val; + if (val>16) tempd |= (op2 << (val - 16)); + return (Bit16u)(tempd >> 16); +} + +static Bit32u DRC_CALL_CONV dynrec_dshl_dword(Bit32u op1,Bit32u op2,Bit8u op3) { + Bit8u val=op3 & 0x1f; + if (!val) return op1; + lf_var2b=val; + lf_var1d=op1; + lf_resd=(lf_var1d << lf_var2b) | (op2 >> (32-lf_var2b)); + lflags.type=t_DSHLd; + return lf_resd; +} + +static Bit32u DRC_CALL_CONV dynrec_dshl_dword_simple(Bit32u op1,Bit32u op2,Bit8u op3) { + Bit8u val=op3 & 0x1f; + if (!val) return op1; + return (op1 << val) | (op2 >> (32-val)); +} + +static Bit16u DRC_CALL_CONV dynrec_dshr_word(Bit16u op1,Bit16u op2,Bit8u op3) { + Bit8u val=op3 & 0x1f; + if (!val) return op1; + lf_var2b=val; + lf_var1d=(op2<<16)|op1; + Bit32u tempd=lf_var1d >> lf_var2b; + if (lf_var2b>16) tempd |= (op2 << (32-lf_var2b )); + lf_resw=(Bit16u)(tempd); + lflags.type=t_DSHRw; + return lf_resw; +} + +static Bit16u DRC_CALL_CONV dynrec_dshr_word_simple(Bit16u op1,Bit16u op2,Bit8u op3) { + Bit8u val=op3 & 0x1f; + if (!val) return op1; + Bit32u tempd=(Bit32u)((((Bit32u)op2)<<16)|op1) >> val; + if (val>16) tempd |= (op2 << (32-val)); + return (Bit16u)(tempd); +} + +static Bit32u DRC_CALL_CONV dynrec_dshr_dword(Bit32u op1,Bit32u op2,Bit8u op3) { + Bit8u val=op3 & 0x1f; + if (!val) return op1; + lf_var2b=val; + lf_var1d=op1; + lf_resd=(lf_var1d >> lf_var2b) | (op2 << (32-lf_var2b)); + lflags.type=t_DSHRd; + return lf_resd; +} + +static Bit32u DRC_CALL_CONV dynrec_dshr_dword_simple(Bit32u op1,Bit32u op2,Bit8u op3) { + Bit8u val=op3 & 0x1f; + if (!val) return op1; + return (op1 >> val) | (op2 << (32-val)); +} + +static void dyn_dpshift_word_gencall(bool left) { + if (left) { + DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshl_word,FC_RETOP); + InvalidateFlagsPartially((void*)&dynrec_dshl_word_simple,proc_addr); + } else { + DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshr_word,FC_RETOP); + InvalidateFlagsPartially((void*)&dynrec_dshr_word_simple,proc_addr); + } +} + +static void dyn_dpshift_dword_gencall(bool left) { + if (left) { + DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshl_dword,FC_RETOP); + InvalidateFlagsPartially((void*)&dynrec_dshl_dword_simple,proc_addr); + } else { + DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshr_dword,FC_RETOP); + InvalidateFlagsPartially((void*)&dynrec_dshr_dword_simple,proc_addr); + } +} + + + +static Bit32u DRC_CALL_CONV dynrec_get_of(void) { return TFLG_O; } +static Bit32u DRC_CALL_CONV dynrec_get_nof(void) { return TFLG_NO; } +static Bit32u DRC_CALL_CONV dynrec_get_cf(void) { return TFLG_B; } +static Bit32u DRC_CALL_CONV dynrec_get_ncf(void) { return TFLG_NB; } +static Bit32u DRC_CALL_CONV dynrec_get_zf(void) { return TFLG_Z; } +static Bit32u DRC_CALL_CONV dynrec_get_nzf(void) { return TFLG_NZ; } +static Bit32u DRC_CALL_CONV dynrec_get_sf(void) { return TFLG_S; } +static Bit32u DRC_CALL_CONV dynrec_get_nsf(void) { return TFLG_NS; } +static Bit32u DRC_CALL_CONV dynrec_get_pf(void) { return TFLG_P; } +static Bit32u DRC_CALL_CONV dynrec_get_npf(void) { return TFLG_NP; } + +static Bit32u DRC_CALL_CONV dynrec_get_cf_or_zf(void) { return TFLG_BE; } +static Bit32u DRC_CALL_CONV dynrec_get_ncf_and_nzf(void) { return TFLG_NBE; } +static Bit32u DRC_CALL_CONV dynrec_get_sf_neq_of(void) { return TFLG_L; } +static Bit32u DRC_CALL_CONV dynrec_get_sf_eq_of(void) { return TFLG_NL; } +static Bit32u DRC_CALL_CONV dynrec_get_zf_or_sf_neq_of(void) { return TFLG_LE; } +static Bit32u DRC_CALL_CONV dynrec_get_nzf_and_sf_eq_of(void) { return TFLG_NLE; } + + +static void dyn_branchflag_to_reg(BranchTypes btype) { + switch (btype) { + case BR_O:gen_call_function_raw((void*)&dynrec_get_of);break; + case BR_NO:gen_call_function_raw((void*)&dynrec_get_nof);break; + case BR_B:gen_call_function_raw((void*)&dynrec_get_cf);break; + case BR_NB:gen_call_function_raw((void*)&dynrec_get_ncf);break; + case BR_Z:gen_call_function_raw((void*)&dynrec_get_zf);break; + case BR_NZ:gen_call_function_raw((void*)&dynrec_get_nzf);break; + case BR_BE:gen_call_function_raw((void*)&dynrec_get_cf_or_zf);break; + case BR_NBE:gen_call_function_raw((void*)&dynrec_get_ncf_and_nzf);break; + + case BR_S:gen_call_function_raw((void*)&dynrec_get_sf);break; + case BR_NS:gen_call_function_raw((void*)&dynrec_get_nsf);break; + case BR_P:gen_call_function_raw((void*)&dynrec_get_pf);break; + case BR_NP:gen_call_function_raw((void*)&dynrec_get_npf);break; + case BR_L:gen_call_function_raw((void*)&dynrec_get_sf_neq_of);break; + case BR_NL:gen_call_function_raw((void*)&dynrec_get_sf_eq_of);break; + case BR_LE:gen_call_function_raw((void*)&dynrec_get_zf_or_sf_neq_of);break; + case BR_NLE:gen_call_function_raw((void*)&dynrec_get_nzf_and_sf_eq_of);break; + } +} + + +static void DRC_CALL_CONV dynrec_mul_byte(Bit8u op) { + FillFlags(); + reg_ax=reg_al*op; + SETFLAGBIT(ZF,reg_al == 0); + if (reg_ax & 0xff00) { + SETFLAGBIT(CF,true); + SETFLAGBIT(OF,true); + } else { + SETFLAGBIT(CF,false); + SETFLAGBIT(OF,false); + } +} + +static void DRC_CALL_CONV dynrec_imul_byte(Bit8u op) { + FillFlags(); + reg_ax=((Bit8s)reg_al) * ((Bit8s)op); + if ((reg_ax & 0xff80)==0xff80 || (reg_ax & 0xff80)==0x0000) { + SETFLAGBIT(CF,false); + SETFLAGBIT(OF,false); + } else { + SETFLAGBIT(CF,true); + SETFLAGBIT(OF,true); + } +} + +static void DRC_CALL_CONV dynrec_mul_word(Bit16u op) { + FillFlags(); + Bitu tempu=(Bitu)reg_ax*(Bitu)op; + reg_ax=(Bit16u)(tempu); + reg_dx=(Bit16u)(tempu >> 16); + SETFLAGBIT(ZF,reg_ax == 0); + if (reg_dx) { + SETFLAGBIT(CF,true); + SETFLAGBIT(OF,true); + } else { + SETFLAGBIT(CF,false); + SETFLAGBIT(OF,false); + } +} + +static void DRC_CALL_CONV dynrec_imul_word(Bit16u op) { + FillFlags(); + Bits temps=((Bit16s)reg_ax)*((Bit16s)op); + reg_ax=(Bit16s)(temps); + reg_dx=(Bit16s)(temps >> 16); + if (((temps & 0xffff8000)==0xffff8000 || (temps & 0xffff8000)==0x0000)) { + SETFLAGBIT(CF,false); + SETFLAGBIT(OF,false); + } else { + SETFLAGBIT(CF,true); + SETFLAGBIT(OF,true); + } +} + +static void DRC_CALL_CONV dynrec_mul_dword(Bit32u op) { + FillFlags(); + Bit64u tempu=(Bit64u)reg_eax*(Bit64u)op; + reg_eax=(Bit32u)(tempu); + reg_edx=(Bit32u)(tempu >> 32); + SETFLAGBIT(ZF,reg_eax == 0); + if (reg_edx) { + SETFLAGBIT(CF,true); + SETFLAGBIT(OF,true); + } else { + SETFLAGBIT(CF,false); + SETFLAGBIT(OF,false); + } +} + +static void DRC_CALL_CONV dynrec_imul_dword(Bit32u op) { + FillFlags(); + Bit64s temps=((Bit64s)((Bit32s)reg_eax))*((Bit64s)((Bit32s)op)); + reg_eax=(Bit32u)(temps); + reg_edx=(Bit32u)(temps >> 32); + if ((reg_edx==0xffffffff) && (reg_eax & 0x80000000) ) { + SETFLAGBIT(CF,false); + SETFLAGBIT(OF,false); + } else if ( (reg_edx==0x00000000) && (reg_eax< 0x80000000) ) { + SETFLAGBIT(CF,false); + SETFLAGBIT(OF,false); + } else { + SETFLAGBIT(CF,true); + SETFLAGBIT(OF,true); + } +} + + +static bool DRC_CALL_CONV dynrec_div_byte(Bit8u op) { + Bitu val=op; + if (val==0) 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 DRC_CALL_CONV dynrec_idiv_byte(Bit8u op) { + Bits val=(Bit8s)op; + if (val==0) 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 DRC_CALL_CONV dynrec_div_word(Bit16u op) { + Bitu val=op; + if (val==0) return CPU_PrepareException(0,0); + Bitu num=((Bit32u)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 DRC_CALL_CONV dynrec_idiv_word(Bit16u op) { + Bits val=(Bit16s)op; + if (val==0) return CPU_PrepareException(0,0); + Bits num=(Bit32s)((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 DRC_CALL_CONV dynrec_div_dword(Bit32u op) { + Bitu val=op; + if (val==0) 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 DRC_CALL_CONV dynrec_idiv_dword(Bit32u op) { + Bits val=(Bit32s)op; + if (val==0) 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; +} + + +static Bit16u DRC_CALL_CONV dynrec_dimul_word(Bit16u op1,Bit16u op2) { + FillFlags(); + Bits res=((Bit16s)op1) * ((Bit16s)op2); + if ((res>-32768) && (res<32767)) { + SETFLAGBIT(CF,false); + SETFLAGBIT(OF,false); + } else { + SETFLAGBIT(CF,true); + SETFLAGBIT(OF,true); + } + return (Bit16u)(res & 0xffff); +} + +static Bit32u DRC_CALL_CONV dynrec_dimul_dword(Bit32u op1,Bit32u op2) { + FillFlags(); + Bit64s res=((Bit64s)((Bit32s)op1))*((Bit64s)((Bit32s)op2)); + if ((res>-((Bit64s)(2147483647)+1)) && (res<(Bit64s)2147483647)) { + SETFLAGBIT(CF,false); + SETFLAGBIT(OF,false); + } else { + SETFLAGBIT(CF,true); + SETFLAGBIT(OF,true); + } + return (Bit32s)res; +} + + + +static Bit16u DRC_CALL_CONV dynrec_cbw(Bit8u op) { + return (Bit8s)op; +} + +static Bit32u DRC_CALL_CONV dynrec_cwde(Bit16u op) { + return (Bit16s)op; +} + +static Bit16u DRC_CALL_CONV dynrec_cwd(Bit16u op) { + if (op & 0x8000) return 0xffff; + else return 0; +} + +static Bit32u DRC_CALL_CONV dynrec_cdq(Bit32u op) { + if (op & 0x80000000) return 0xffffffff; + else return 0; +} + + +static void DRC_CALL_CONV dynrec_sahf(Bit16u op) { + SETFLAGBIT(OF,get_OF()); + lflags.type=t_UNKNOWN; + CPU_SetFlags(op>>8,FMASK_NORMAL & 0xff); +} + + +static void DRC_CALL_CONV dynrec_cmc(void) { + FillFlags(); + SETFLAGBIT(CF,!(reg_flags & FLAG_CF)); +} +static void DRC_CALL_CONV dynrec_clc(void) { + FillFlags(); + SETFLAGBIT(CF,false); +} +static void DRC_CALL_CONV dynrec_stc(void) { + FillFlags(); + SETFLAGBIT(CF,true); +} +static void DRC_CALL_CONV dynrec_cld(void) { + SETFLAGBIT(DF,false); + cpu.direction=1; +} +static void DRC_CALL_CONV dynrec_std(void) { + SETFLAGBIT(DF,true); + cpu.direction=-1; +} + + +static Bit16u DRC_CALL_CONV dynrec_movsb_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) { + Bit16u count_left; + if (count<(Bitu)CPU_Cycles) { + count_left=0; + } else { + count_left=(Bit16u)(count-CPU_Cycles); + count=(Bit16u)CPU_Cycles; + CPU_Cycles=0; + } + for (;count>0;count--) { + mem_writeb(di_base+reg_di,mem_readb(si_base+reg_si)); + reg_si+=add_index; + reg_di+=add_index; + } + return count_left; +} + +static Bit32u DRC_CALL_CONV dynrec_movsb_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) { + Bit32u count_left; + if (count<(Bitu)CPU_Cycles) { + count_left=0; + } else { + count_left=count-CPU_Cycles; + count=CPU_Cycles; + CPU_Cycles=0; + } + for (;count>0;count--) { + mem_writeb(di_base+reg_edi,mem_readb(si_base+reg_esi)); + reg_esi+=add_index; + reg_edi+=add_index; + } + return count_left; +} + +static Bit16u DRC_CALL_CONV dynrec_movsw_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) { + Bit16u count_left; + if (count<(Bitu)CPU_Cycles) { + count_left=0; + } else { + count_left=(Bit16u)(count-CPU_Cycles); + count=(Bit16u)CPU_Cycles; + CPU_Cycles=0; + } + add_index<<=1; + for (;count>0;count--) { + mem_writew(di_base+reg_di,mem_readw(si_base+reg_si)); + reg_si+=add_index; + reg_di+=add_index; + } + return count_left; +} + +static Bit32u DRC_CALL_CONV dynrec_movsw_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) { + Bit32u count_left; + if (count<(Bitu)CPU_Cycles) { + count_left=0; + } else { + count_left=count-CPU_Cycles; + count=CPU_Cycles; + CPU_Cycles=0; + } + add_index<<=1; + for (;count>0;count--) { + mem_writew(di_base+reg_edi,mem_readw(si_base+reg_esi)); + reg_esi+=add_index; + reg_edi+=add_index; + } + return count_left; +} + +static Bit16u DRC_CALL_CONV dynrec_movsd_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) { + Bit16u count_left; + if (count<(Bitu)CPU_Cycles) { + count_left=0; + } else { + count_left=(Bit16u)(count-CPU_Cycles); + count=(Bit16u)CPU_Cycles; + CPU_Cycles=0; + } + add_index<<=2; + for (;count>0;count--) { + mem_writed(di_base+reg_di,mem_readd(si_base+reg_si)); + reg_si+=add_index; + reg_di+=add_index; + } + return count_left; +} + +static Bit32u DRC_CALL_CONV dynrec_movsd_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) { + Bit32u count_left; + if (count<(Bitu)CPU_Cycles) { + count_left=0; + } else { + count_left=count-CPU_Cycles; + count=CPU_Cycles; + CPU_Cycles=0; + } + add_index<<=2; + for (;count>0;count--) { + mem_writed(di_base+reg_edi,mem_readd(si_base+reg_esi)); + reg_esi+=add_index; + reg_edi+=add_index; + } + return count_left; +} + + +static Bit16u DRC_CALL_CONV dynrec_lodsb_word(Bit16u count,Bit16s add_index,PhysPt si_base) { + Bit16u count_left; + if (count<(Bitu)CPU_Cycles) { + count_left=0; + } else { + count_left=(Bit16u)(count-CPU_Cycles); + count=(Bit16u)CPU_Cycles; + CPU_Cycles=0; + } + for (;count>0;count--) { + reg_al=mem_readb(si_base+reg_si); + reg_si+=add_index; + } + return count_left; +} + +static Bit32u DRC_CALL_CONV dynrec_lodsb_dword(Bit32u count,Bit32s add_index,PhysPt si_base) { + Bit32u count_left; + if (count<(Bitu)CPU_Cycles) { + count_left=0; + } else { + count_left=count-CPU_Cycles; + count=CPU_Cycles; + CPU_Cycles=0; + } + for (;count>0;count--) { + reg_al=mem_readb(si_base+reg_esi); + reg_esi+=add_index; + } + return count_left; +} + +static Bit16u DRC_CALL_CONV dynrec_lodsw_word(Bit16u count,Bit16s add_index,PhysPt si_base) { + Bit16u count_left; + if (count<(Bitu)CPU_Cycles) { + count_left=0; + } else { + count_left=(Bit16u)(count-CPU_Cycles); + count=(Bit16u)CPU_Cycles; + CPU_Cycles=0; + } + add_index<<=1; + for (;count>0;count--) { + reg_ax=mem_readw(si_base+reg_si); + reg_si+=add_index; + } + return count_left; +} + +static Bit32u DRC_CALL_CONV dynrec_lodsw_dword(Bit32u count,Bit32s add_index,PhysPt si_base) { + Bit32u count_left; + if (count<(Bitu)CPU_Cycles) { + count_left=0; + } else { + count_left=count-CPU_Cycles; + count=CPU_Cycles; + CPU_Cycles=0; + } + add_index<<=1; + for (;count>0;count--) { + reg_ax=mem_readw(si_base+reg_esi); + reg_esi+=add_index; + } + return count_left; +} + +static Bit16u DRC_CALL_CONV dynrec_lodsd_word(Bit16u count,Bit16s add_index,PhysPt si_base) { + Bit16u count_left; + if (count<(Bitu)CPU_Cycles) { + count_left=0; + } else { + count_left=(Bit16u)(count-CPU_Cycles); + count=(Bit16u)CPU_Cycles; + CPU_Cycles=0; + } + add_index<<=2; + for (;count>0;count--) { + reg_eax=mem_readd(si_base+reg_si); + reg_si+=add_index; + } + return count_left; +} + +static Bit32u DRC_CALL_CONV dynrec_lodsd_dword(Bit32u count,Bit32s add_index,PhysPt si_base) { + Bit32u count_left; + if (count<(Bitu)CPU_Cycles) { + count_left=0; + } else { + count_left=count-CPU_Cycles; + count=CPU_Cycles; + CPU_Cycles=0; + } + add_index<<=2; + for (;count>0;count--) { + reg_eax=mem_readd(si_base+reg_esi); + reg_esi+=add_index; + } + return count_left; +} + + +static Bit16u DRC_CALL_CONV dynrec_stosb_word(Bit16u count,Bit16s add_index,PhysPt di_base) { + Bit16u count_left; + if (count<(Bitu)CPU_Cycles) { + count_left=0; + } else { + count_left=(Bit16u)(count-CPU_Cycles); + count=(Bit16u)CPU_Cycles; + CPU_Cycles=0; + } + for (;count>0;count--) { + mem_writeb(di_base+reg_di,reg_al); + reg_di+=add_index; + } + return count_left; +} + +static Bit32u DRC_CALL_CONV dynrec_stosb_dword(Bit32u count,Bit32s add_index,PhysPt di_base) { + Bit32u count_left; + if (count<(Bitu)CPU_Cycles) { + count_left=0; + } else { + count_left=count-CPU_Cycles; + count=CPU_Cycles; + CPU_Cycles=0; + } + for (;count>0;count--) { + mem_writeb(di_base+reg_edi,reg_al); + reg_edi+=add_index; + } + return count_left; +} + +static Bit16u DRC_CALL_CONV dynrec_stosw_word(Bit16u count,Bit16s add_index,PhysPt di_base) { + Bit16u count_left; + if (count<(Bitu)CPU_Cycles) { + count_left=0; + } else { + count_left=(Bit16u)(count-CPU_Cycles); + count=(Bit16u)CPU_Cycles; + CPU_Cycles=0; + } + add_index<<=1; + for (;count>0;count--) { + mem_writew(di_base+reg_di,reg_ax); + reg_di+=add_index; + } + return count_left; +} + +static Bit32u DRC_CALL_CONV dynrec_stosw_dword(Bit32u count,Bit32s add_index,PhysPt di_base) { + Bit32u count_left; + if (count<(Bitu)CPU_Cycles) { + count_left=0; + } else { + count_left=count-CPU_Cycles; + count=CPU_Cycles; + CPU_Cycles=0; + } + add_index<<=1; + for (;count>0;count--) { + mem_writew(di_base+reg_edi,reg_ax); + reg_edi+=add_index; + } + return count_left; +} + +static Bit16u DRC_CALL_CONV dynrec_stosd_word(Bit16u count,Bit16s add_index,PhysPt di_base) { + Bit16u count_left; + if (count<(Bitu)CPU_Cycles) { + count_left=0; + } else { + count_left=(Bit16u)(count-CPU_Cycles); + count=(Bit16u)CPU_Cycles; + CPU_Cycles=0; + } + add_index<<=2; + for (;count>0;count--) { + mem_writed(di_base+reg_di,reg_eax); + reg_di+=add_index; + } + return count_left; +} + +static Bit32u DRC_CALL_CONV dynrec_stosd_dword(Bit32u count,Bit32s add_index,PhysPt di_base) { + Bit32u count_left; + if (count<(Bitu)CPU_Cycles) { + count_left=0; + } else { + count_left=count-CPU_Cycles; + count=CPU_Cycles; + CPU_Cycles=0; + } + add_index<<=2; + for (;count>0;count--) { + mem_writed(di_base+reg_edi,reg_eax); + reg_edi+=add_index; + } + return count_left; +} + + +static void DRC_CALL_CONV dynrec_push_word(Bit16u value) { + Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-2)&cpu.stack.mask); + mem_writew(SegPhys(ss) + (new_esp & cpu.stack.mask),value); + reg_esp=new_esp; +} + +static void DRC_CALL_CONV dynrec_push_dword(Bit32u value) { + Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-4)&cpu.stack.mask); + mem_writed(SegPhys(ss) + (new_esp & cpu.stack.mask) ,value); + reg_esp=new_esp; +} + +static Bit16u DRC_CALL_CONV dynrec_pop_word(void) { + Bit16u val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); + reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+2)&cpu.stack.mask); + return val; +} + +static Bit32u DRC_CALL_CONV dynrec_pop_dword(void) { + Bit32u val=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask)); + reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+4)&cpu.stack.mask); + return val; +} diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h new file mode 100644 index 00000000..e75667e5 --- /dev/null +++ b/src/cpu/core_dynrec/risc_x64.h @@ -0,0 +1,631 @@ +/* + * Copyright (C) 2002-2006 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. + */ + + +// some configuring defines that specify the capabilities of this architecture +// or aspects of the recompiling + +// try to use non-flags generating functions if possible +// #define DRC_FLAGS_INVALIDATION + +// type with the same size as a pointer +#define DRC_PTR_SIZE_IM Bit64u + +// calling convention modifier +#define DRC_CALL_CONV + + +// register mapping +typedef Bit8u HostReg; + +#define HOST_EAX 0 +#define HOST_ECX 1 +#define HOST_EDX 2 +#define HOST_EBX 3 +#define HOST_ESI 6 +#define HOST_EDI 7 + + +// register that holds function return values +#define FC_RETOP HOST_EAX + +// register used for address calculations, +#define FC_ADDR HOST_EBX + +// register that holds the first parameter +#define FC_OP1 HOST_EDI + +// register that holds the second parameter +#define FC_OP2 HOST_ESI + +// register that holds byte-accessible temporary values +#define FC_TMP_BA1 HOST_ECX + +// register that holds byte-accessible temporary values +#define FC_TMP_BA2 HOST_EDX + + +// temporary register for LEA +#define TEMP_REG_DRC HOST_ESI + + +// move a full register from reg_src to reg_dst +static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { + cache_addb(0x8b); // mov reg_dst,reg_src + cache_addb(0xc0+(reg_dst<<3)+reg_src); +} + + +static INLINE void gen_memaddr(HostReg reg,void* data) { + Bit64s diff = (Bit64s)data-((Bit64s)cache.pos+5); + if ((diff<0x80000000LL) && (diff>-0x80000000LL)) { + cache_addb(0x05+(reg<<3)); + // RIP-relative addressing is offset after the instruction + cache_addd((Bit32u)(((Bit64u)diff)&0xffffffffLL)); + } else if ((Bit64u)data<0x100000000LL) { + cache_addw(0x2504+(reg<<3)); + cache_addd((Bit32u)(((Bit64u)data)&0xffffffffLL)); + } else { + E_Exit("DRC64:Unhandled memory reference"); + } +} + + +// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg +// 16bit moves must preserve the upper 16bit of the destination register +static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { + if (!dword) cache_addb(0x66); + cache_addb(0x8b); // mov reg,[data] + gen_memaddr(dest_reg,data); +} + + +// move a 16bit constant value into dest_reg +// the upper 16bit of the destination register must be preserved +static void gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { + cache_addb(0x66); + cache_addb(0xb8+dest_reg); // mov reg,imm + cache_addw(imm); +} + +// move a 32bit constant value into dest_reg +static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { + cache_addb(0xb8+dest_reg); // mov reg,imm + cache_addd(imm); +} + +// move 32bit (dword==true) or 16bit (dword==false) of a register into memory +static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { + if (!dword) cache_addb(0x66); + cache_addb(0x89); // mov [data],reg + gen_memaddr(src_reg,dest); +} + +// move an 8bit value from memory into dest_reg +// the upper 24bit of the destination register must be preserved +static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { + cache_addb(0x8a); // mov reg,[data] + gen_memaddr(dest_reg,data); +} + +// move an 8bit value from memory into dest_reg +// the upper 16bit of the destination register must be preserved +// this function is allowed to load 16bit from memory as well if the host architecture +// does not provide 8bit register access for function parameter operands (FC_OP1/FC_OP2) +static void gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { + cache_addb(0x66); + cache_addb(0x8b); // mov reg,[data] + gen_memaddr(dest_reg,data); +} + +// move an 8bit constant value into dest_reg +// the upper 16bit of the destination register must be preserved +static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { + cache_addb(0xb0+dest_reg); // mov reg,imm + cache_addb(imm); +} + +// move an 8bit constant value into dest_reg +// the upper 16bit of the destination register must be preserved +// this function is allowed to load 16bit from memory as well if the host architecture +// does not provide 8bit register access for function parameter operands (FC_OP1/FC_OP2) +static void gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { + cache_addb(0x66); + cache_addb(0xb8+dest_reg); // mov reg,imm + cache_addw(imm); +} + +// move the lowest 8bit of a register into memory +static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { + cache_addb(0x88); // mov [data],reg + gen_memaddr(src_reg,dest); +} + + + +// convert an 8bit word to a 32bit dword +// the register is zero-extended (sign==false) or sign-extended (sign==true) +static void gen_extend_byte(bool sign,HostReg reg) { + cache_addw(0xb60f+(sign?0x800:0)); // movsx/movzx + cache_addb(0xc0+(reg<<3)+reg); +} + +// convert a 16bit word to a 32bit dword +// the register is zero-extended (sign==false) or sign-extended (sign==true) +static void gen_extend_word(bool sign,HostReg reg) { + cache_addw(0xb70f+(sign?0x800:0)); // movsx/movzx + cache_addb(0xc0+(reg<<3)+reg); +} + + + +// add a 32bit value from memory to a full register +static void gen_add(HostReg reg,void* op) { + cache_addb(0x03); // add reg,[data] + gen_memaddr(reg,op); +} + +// add a 32bit constant value to a full register +static void gen_add_imm(HostReg reg,Bit32u imm) { + cache_addw(0xc081+(reg<<8)); // add reg,imm + cache_addd(imm); +} + +// and a 32bit constant value with a full register +static void gen_and_imm(HostReg reg,Bit32u imm) { + cache_addw(0xe081+(reg<<8)); // and reg,imm + cache_addd(imm); +} + + + +// move a 32bit constant value into memory +static void gen_mov_direct_dword(void* dest,Bit32u imm) { + cache_addw(0x04c7); // mov [data],imm + cache_addb(0x25); + cache_addd((Bit32u)(((Bit64u)dest)&0xffffffffLL)); + cache_addd(imm); +} + +// move a 64bit constant value into a full register +static void gen_mov_reg_qword(HostReg dest_reg,Bit64u imm) { + cache_addb(0x48); + cache_addb(0xb8+dest_reg); // mov dest_reg,imm + cache_addq(imm); +} + +// move an address into memory +static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { + gen_mov_reg_qword(HOST_EAX,imm); + cache_addb(0x48); + gen_mov_word_from_reg(HOST_EAX,dest,true); +} + + +// add an 8bit constant value to a memory value +static void gen_add_direct_byte(void* dest,Bit8s imm) { + cache_addw(0x0483); // add [data],imm + cache_addb(0x25); + cache_addd((Bit32u)(((Bit64u)dest)&0xffffffffLL)); + cache_addb(imm); +} + +// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value +static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { + if ((imm<128) && dword) { + gen_add_direct_byte(dest,(Bit8s)imm); + return; + } + if (!dword) cache_addb(0x66); + cache_addw(0x0481); // add [data],imm + cache_addb(0x25); + cache_addd((Bit32u)(((Bit64u)dest)&0xffffffffLL)); + if (dword) cache_addd((Bit32u)imm); + else cache_addw((Bit16u)imm); +} +/* +// add an 8bit constant value to a memory value +static void gen_add_direct_byte(void* dest,Bit8s imm) { + cache_addb(0x83); // add [data],imm + gen_memaddr(0,dest,1); + cache_addb(imm); +} + +// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value +static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { + if ((imm<128) && dword) { + gen_add_direct_byte(dest,(Bit8s)imm); + return; + } + if (!dword) cache_addb(0x66); + cache_addw(0x81); // add [data],imm + gen_memaddr(0,dest,dword?1:2); + if (dword) cache_addd((Bit32u)imm); + else cache_addw((Bit16u)imm); +} +*/ + +// subtract an 8bit constant value from a memory value +static void gen_sub_direct_byte(void* dest,Bit8s imm) { + cache_addw(0x2c83); // sub [data],imm + cache_addb(0x25); + cache_addd((Bit32u)(((Bit64u)dest)&0xffffffffLL)); + cache_addb(imm); +} + +// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value +static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { + if ((imm<128) && dword) { + gen_sub_direct_byte(dest,(Bit8s)imm); + return; + } + if (!dword) cache_addb(0x66); + cache_addw(0x2c81); // sub [data],imm + cache_addb(0x25); + cache_addd((Bit32u)(((Bit64u)dest)&0xffffffffLL)); + if (dword) cache_addd((Bit32u)imm); + else cache_addw((Bit16u)imm); +} +/* +// subtract an 8bit constant value from a memory value +static void gen_sub_direct_byte(void* dest,Bit8s imm) { + cache_addb(0x83); // sub [data],imm + gen_memaddr(5,dest,1); + cache_addb(imm); +} + +// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value +static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { + if ((imm<128) && dword) { + gen_sub_direct_byte(dest,(Bit8s)imm); + return; + } + if (!dword) cache_addb(0x66); + cache_addb(0x81); // sub [data],imm + gen_memaddr(5,dest,dword?1:2); + if (dword) cache_addd((Bit32u)imm); + else cache_addw((Bit16u)imm); +} +*/ + + +// effective address calculation, destination is dest_reg +// scale_reg is scaled by scale (scale_reg*(2^scale)) and +// added to dest_reg, then the immediate value is added +static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { + Bit8u rm_base; + Bitu imm_size; + if (!imm) { + imm_size=0; rm_base=0x0; //no imm + } else if ((imm>=-128 && imm<=127)) { + imm_size=1; rm_base=0x40; //Signed byte imm + } else { + imm_size=4; rm_base=0x80; //Signed dword imm + } + + // ea_reg := ea_reg+TEMP_REG_DRC*(2^scale)+imm + // ea_reg := op1 + op2 *(2^scale)+imm + cache_addb(0x48); + cache_addb(0x8d); //LEA + cache_addb(0x04+(dest_reg << 3)+rm_base); //The sib indicator + cache_addb(dest_reg+(TEMP_REG_DRC<<3)+(scale<<6)); + + switch (imm_size) { + case 0: break; + case 1:cache_addb(imm);break; + case 4:cache_addd(imm);break; + } +} + +// effective address calculation, destination is dest_reg +// dest_reg is scaled by scale (dest_reg*(2^scale)), +// then the immediate value is added +static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { + // ea_reg := ea_reg*(2^scale)+imm + // ea_reg := op2 *(2^scale)+imm + cache_addb(0x48); + cache_addb(0x8d); //LEA + cache_addb(0x04+(dest_reg<<3)); + cache_addb(0x05+(dest_reg<<3)+(scale<<6)); + + cache_addd(imm); // always add dword immediate +} + + + +// generate a call to a parameterless function +static void INLINE gen_call_function_raw(void * func) { + cache_addb(0x48); + cache_addb(0xb8); // mov reg,imm64 + cache_addq((Bit64u)func); + cache_addw(0xd0ff); +} + +// generate a call to a function with paramcount parameters +// note: the parameters are loaded in the architecture specific way +// using the gen_load_param_ functions below +static Bit64u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { + // align the stack + cache_addb(0x48); + cache_addw(0xc48b); // mov rax,rsp + + cache_addb(0x48); + cache_addw(0xec83); // sub rsp,0x08 + cache_addb(0x08); // 0x08==return address pushed onto stack by call + + cache_addb(0x48); + cache_addw(0xe483); // and esp,0xfffffffffffffff0 + cache_addb(0xf0); + + cache_addb(0x48); + cache_addw(0xc483); // add rsp,0x08 + cache_addb(0x08); + + cache_addb(0x50); // push rax (==old rsp) + + Bit64u proc_addr=(Bit64u)cache.pos; + + // Do the actual call to the procedure + cache_addb(0x48); + cache_addb(0xb8); // mov reg,imm64 + cache_addq((Bit64u)func); + + cache_addw(0xd0ff); + + // restore stack + cache_addb(0x5c); // pop rsp + + return proc_addr; +} + + +// load an immediate value as param'th function parameter +static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { + // move an immediate 32bit value into a 64bit param reg + switch (param) { + case 0: // mov param1,imm32 + gen_mov_dword_to_reg_imm(FC_OP1,(Bit32u)imm); + break; + case 1: // mov param2,imm32 + gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)imm); + break; +#if defined (_MSC_VER) + case 2: // mov r8,imm32 + cache_addw(0xb849); + cache_addq((Bit32u)imm); + break; + case 3: // mov r9,imm32 + cache_addw(0xb949); + cache_addq((Bit32u)imm); + break; +#else + case 2: // mov rdx,imm32 + gen_mov_dword_to_reg_imm(HOST_EDX,(Bit32u)imm); + break; + case 3: // mov rcx,imm32 + gen_mov_dword_to_reg_imm(HOST_ECX,(Bit32u)imm); + break; +#endif + default: + E_Exit("I(mm) >4 params unsupported"); + break; + } +} + +// load an address as param'th function parameter +static void INLINE gen_load_param_addr(DRC_PTR_SIZE_IM addr,Bitu param) { + // move an immediate 64bit value into a 64bit param reg + switch (param) { + case 0: // mov param1,addr64 + gen_mov_reg_qword(FC_OP1,addr); + break; + case 1: // mov param2,addr64 + gen_mov_reg_qword(FC_OP2,addr); + break; +#if defined (_MSC_VER) + case 2: // mov r8,addr64 + cache_addw(0xb849); + cache_addq(addr); + break; + case 3: // mov r9,addr64 + cache_addw(0xb949); + cache_addq(addr); + break; +#else + case 2: // mov rdx,addr64 + gen_mov_reg_qword(HOST_EDX,addr); + break; + case 3: // mov rcx,addr64 + gen_mov_reg_qword(HOST_ECX,addr); + break; +#endif + default: + E_Exit("A(ddr) >4 params unsupported"); + break; + } +} + +// load a host-register as param'th function parameter +static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { + // move a register into a 64bit param reg, {inputregs}!={outputregs} + switch (param) { + case 0: // mov param1,reg&7 + gen_mov_regs(FC_OP1,reg&7); + break; + case 1: // mov param2,reg&7 + gen_mov_regs(FC_OP2,reg&7); + break; +#if defined (_MSC_VER) + case 2: // mov r8,reg&7 + cache_addb(0x49); + gen_mov_regs(0,reg&7); + break; + case 3: // mov r9,reg&7 + cache_addb(0x49); + gen_mov_regs(1,reg&7); + break; +#else + case 2: // mov rdx,reg&7 + gen_mov_regs(HOST_EDX,reg&7); + break; + case 3: // mov rcx,reg&7 + gen_mov_regs(HOST_ECX,reg&7); + break; +#endif + default: + E_Exit("R(eg) >4 params unsupported"); + break; + } +} + +// load a value from memory as param'th function parameter +static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { + // move memory content into a 64bit param reg + switch (param) { + case 0: // mov param1,[mem] + gen_mov_word_to_reg(FC_OP1,(void*)mem,true); + break; + case 1: // mov param2,[mem] + gen_mov_word_to_reg(FC_OP2,(void*)mem,true); + break; +#if defined (_MSC_VER) + case 2: // mov r8,[mem] + cache_addb(0x49); + gen_mov_word_to_reg(0,(void*)mem,true); + break; + case 3: // mov r9,[mem] + cache_addb(0x49); + gen_mov_word_to_reg(1,(void*)mem,true); + break; +#else + case 2: // mov rdx,[mem] + gen_mov_word_to_reg(HOST_EDX,(void*)mem,true); + break; + case 3: // mov rcx,[mem] + gen_mov_word_to_reg(HOST_ECX,(void*)mem,true); + break; +#endif + default: + E_Exit("R(eg) >4 params unsupported"); + break; + } +} + + + +// jump to an address pointed at by ptr, offset is in imm +static void gen_jmp_ptr(void * ptr,Bits imm=0) { + cache_addw(0xa148); // mov rax,[data] + cache_addq((Bit64u)ptr); + + cache_addb(0xff); // jmp [rax+imm] + if (!imm) { + cache_addb(0x20); + } else if ((imm>=-128 && imm<=127)) { + cache_addb(0x60); + cache_addb(imm); + } else { + cache_addb(0xa0); + cache_addd(imm); + } +} + + +// short conditional jump (+-127 bytes) if register is zero +// the destination is set by gen_fill_branch() later +static Bit64u gen_create_branch_on_zero(HostReg reg,bool dword) { + if (!dword) cache_addb(0x66); + cache_addb(0x0b); // or reg,reg + cache_addb(0xc0+reg+(reg<<3)); + + cache_addw(0x0074); // jz addr + return ((Bit64u)cache.pos-1); +} + +// short conditional jump (+-127 bytes) if register is nonzero +// the destination is set by gen_fill_branch() later +static Bit64u gen_create_branch_on_nonzero(HostReg reg,bool dword) { + if (!dword) cache_addb(0x66); + cache_addb(0x0b); // or reg,reg + cache_addb(0xc0+reg+(reg<<3)); + + cache_addw(0x0075); // jnz addr + return ((Bit64u)cache.pos-1); +} + +// short conditional jump (+-127 bytes) if register +// (as set by a boolean operation) is nonzero +// the destination is set by gen_fill_branch() later +static Bit64u gen_create_branch_on_nonzero_bool(HostReg reg) { + cache_addb(0x0a); // or reg,reg + cache_addb(0xc0+reg+(reg<<3)); + + cache_addw(0x0075); // jnz addr + return ((Bit64u)cache.pos-1); +} + +// calculate relative offset and fill it into the location pointed to by data +static void gen_fill_branch(DRC_PTR_SIZE_IM data) { +#if C_DEBUG + Bit64s len=(Bit64u)cache.pos-data; + if (len<0) len=-len; + if (len>126) LOG_MSG("Big jump %d",len); +#endif + *(Bit8u*)data=(Bit8u)((Bit64u)cache.pos-data-1); +} + +// conditional jump if register is nonzero +// for isdword==true the 32bit of the register are tested +// for isdword==false the lowest 8bit of the register are tested +static Bit64u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { + // isdword: cmp reg32,0 + // not isdword: cmp reg8,0 + cache_addb(0x0a+(isdword?1:0)); // or reg,reg + cache_addb(0xc0+reg+(reg<<3)); + + cache_addw(0x850f); // jnz + cache_addd(0); + return ((Bit64u)cache.pos-4); +} + +// compare 32bit-register against zero and jump if value less/equal than zero +static Bit64u gen_create_branch_long_leqzero(HostReg reg) { + cache_addw(0xf883+(reg<<8)); + cache_addb(0x00); // cmp reg,0 + + cache_addw(0x8e0f); // jle + cache_addd(0); + return ((Bit64u)cache.pos-4); +} + +// calculate long relative offset and fill it into the location pointed to by data +static void gen_fill_branch_long(Bit64u data) { + *(Bit32u*)data=(Bit32u)((Bit64u)cache.pos-data-4); +} + + +static void gen_run_code(void) { + cache_addb(0x53); // push rbx + cache_addw(0xd0ff+(FC_OP1<<8)); // call rdi + cache_addb(0x5b); // pop rbx +} + +// return from a function +static void gen_return_function(void) { + cache_addb(0xc3); // ret +} diff --git a/src/cpu/core_dynrec/risc_x86.h b/src/cpu/core_dynrec/risc_x86.h new file mode 100644 index 00000000..00b0e432 --- /dev/null +++ b/src/cpu/core_dynrec/risc_x86.h @@ -0,0 +1,427 @@ +/* + * Copyright (C) 2002-2006 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. + */ + + +// some configuring defines that specify the capabilities of this architecture +// or aspects of the recompiling + +// try to use non-flags generating functions if possible +#define DRC_FLAGS_INVALIDATION + +// type with the same size as a pointer +#define DRC_PTR_SIZE_IM Bit32u + +// calling convention modifier +#define DRC_CALL_CONV _fastcall + + +// register mapping +enum HostReg { + HOST_EAX=0, + HOST_ECX, + HOST_EDX, + HOST_EBX, + HOST_ESP, + HOST_EBP, + HOST_ESI, + HOST_EDI +}; + + +// register that holds function return values +#define FC_RETOP HOST_EAX + +// register used for address calculations, +#define FC_ADDR HOST_EBX + +// register that holds the first parameter +#define FC_OP1 HOST_ECX + +// register that holds the second parameter +#define FC_OP2 HOST_EDX + +// register that holds byte-accessible temporary values +#define FC_TMP_BA1 HOST_ECX + +// register that holds byte-accessible temporary values +#define FC_TMP_BA2 HOST_EDX + + +// temporary register for LEA +#define TEMP_REG_DRC HOST_ESI + + +// move a full register from reg_src to reg_dst +static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { + cache_addb(0x8b); // mov reg_dst,reg_src + cache_addb(0xc0+(reg_dst<<3)+reg_src); +} + +// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg +// 16bit moves must preserve the upper 16bit of the destination register +static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { + if (!dword) cache_addb(0x66); + cache_addw(0x058b+(dest_reg<<11)); // mov reg,[data] + cache_addd((Bit32u)data); +} + +// move a 16bit constant value into dest_reg +// the upper 16bit of the destination register must be preserved +static void gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { + cache_addb(0x66); + cache_addb(0xb8+dest_reg); // mov reg,imm + cache_addw(imm); +} + +// move a 32bit constant value into dest_reg +static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { + cache_addb(0xb8+dest_reg); // mov reg,imm + cache_addd(imm); +} + +// move 32bit (dword==true) or 16bit (dword==false) of a register into memory +static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { + if (!dword) cache_addb(0x66); + cache_addw(0x0589+(src_reg<<11)); // mov [data],reg + cache_addd((Bit32u)dest); +} + +// move an 8bit value from memory into dest_reg +// the upper 16bit of the destination register must be preserved +static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { + cache_addw(0x058a+(dest_reg<<11)); // mov reg,[data] + cache_addd((Bit32u)data); +} + +// move an 8bit value from memory into dest_reg +// the upper 16bit of the destination register must be preserved +// this function is allowed to load 16bit from memory as well if the host architecture +// does not provide 8bit register access for function parameter operands (FC_OP1/FC_OP2) +static void gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { + cache_addb(0x66); + cache_addw(0x058b+(dest_reg<<11)); // mov reg,[data] + cache_addd((Bit32u)data); +} + +// move an 8bit constant value into dest_reg +// the upper 16bit of the destination register must be preserved +static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { + cache_addb(0xb0+dest_reg); // mov reg,imm + cache_addb(imm); +} + +// move an 8bit constant value into dest_reg +// the upper 16bit of the destination register must be preserved +// this function is allowed to load 16bit from memory as well if the host architecture +// does not provide 8bit register access for function parameter operands (FC_OP1/FC_OP2) +static void gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { + cache_addb(0x66); + cache_addb(0xb8+dest_reg); // mov reg,imm + cache_addw(imm); +} + +// move the lowest 8bit of a register into memory +static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { + cache_addw(0x0588+(src_reg<<11)); // mov [data],reg + cache_addd((Bit32u)dest); +} + + + +// convert an 8bit word to a 32bit dword +// the register is zero-extended (sign==false) or sign-extended (sign==true) +static void gen_extend_byte(bool sign,HostReg reg) { + cache_addw(0xb60f+(sign?0x800:0)); // movsx/movzx + cache_addb(0xc0+(reg<<3)+reg); +} + +// convert a 16bit word to a 32bit dword +// the register is zero-extended (sign==false) or sign-extended (sign==true) +static void gen_extend_word(bool sign,HostReg reg) { + cache_addw(0xb70f+(sign?0x800:0)); // movsx/movzx + cache_addb(0xc0+(reg<<3)+reg); +} + + + +// add a 32bit value from memory to a full register +static void gen_add(HostReg reg,void* op) { + cache_addw(0x0503+(reg<<11)); // add reg,[data] + cache_addd((Bit32u)op); +} + +// add a 32bit constant value to a full register +static void gen_add_imm(HostReg reg,Bit32u imm) { + cache_addw(0xc081+(reg<<8)); // add reg,imm + cache_addd(imm); +} + +// and a 32bit constant value with a full register +static void gen_and_imm(HostReg reg,Bit32u imm) { + cache_addw(0xe081+(reg<<8)); // and reg,imm + cache_addd(imm); +} + + + +// move a 32bit constant value into memory +static void gen_mov_direct_dword(void* dest,Bit32u imm) { + cache_addw(0x05c7); // mov [data],imm + cache_addd((Bit32u)dest); + cache_addd(imm); +} + +// move an address into memory +static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { + gen_mov_direct_dword(dest,(Bit32u)imm); +} + + +// add an 8bit constant value to a memory value +static void gen_add_direct_byte(void* dest,Bit8s imm) { + cache_addw(0x0583); // add [data],imm + cache_addd((Bit32u)dest); + cache_addb(imm); +} + +// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value +static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { + if ((imm<128) && dword) { + gen_add_direct_byte(dest,(Bit8s)imm); + return; + } + if (!dword) cache_addb(0x66); + cache_addw(0x0581); // add [data],imm + cache_addd((Bit32u)dest); + if (dword) cache_addd((Bit32u)imm); + else cache_addw((Bit16u)imm); +} + +// subtract an 8bit constant value from a memory value +static void gen_sub_direct_byte(void* dest,Bit8s imm) { + cache_addw(0x2d83); // sub [data],imm + cache_addd((Bit32u)dest); + cache_addb(imm); +} + +// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value +static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { + if ((imm<128) && dword) { + gen_sub_direct_byte(dest,(Bit8s)imm); + return; + } + if (!dword) cache_addb(0x66); + cache_addw(0x2d81); // sub [data],imm + cache_addd((Bit32u)dest); + if (dword) cache_addd((Bit32u)imm); + else cache_addw((Bit16u)imm); +} + + + +// effective address calculation, destination is dest_reg +// scale_reg is scaled by scale (scale_reg*(2^scale)) and +// added to dest_reg, then the immediate value is added +static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { + Bit8u rm_base; + Bitu imm_size; + if (!imm) { + imm_size=0; rm_base=0x0; //no imm + } else if ((imm>=-128 && imm<=127)) { + imm_size=1; rm_base=0x40; //Signed byte imm + } else { + imm_size=4; rm_base=0x80; //Signed dword imm + } + + // ea_reg := ea_reg+TEMP_REG_DRC*(2^scale)+imm + // ea_reg := op1 + op2 *(2^scale)+imm + cache_addb(0x8d); //LEA + cache_addb(0x04+(dest_reg << 3)+rm_base); //The sib indicator + cache_addb(dest_reg+(TEMP_REG_DRC<<3)+(scale<<6)); + + switch (imm_size) { + case 0: break; + case 1:cache_addb(imm);break; + case 4:cache_addd(imm);break; + } +} + +// effective address calculation, destination is dest_reg +// dest_reg is scaled by scale (dest_reg*(2^scale)), +// then the immediate value is added +static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { + // ea_reg := ea_reg*(2^scale)+imm + // ea_reg := op2 *(2^scale)+imm + cache_addb(0x8d); //LEA + cache_addb(0x04+(dest_reg<<3)); + cache_addb(0x05+(dest_reg<<3)+(scale<<6)); + + cache_addd(imm); // always add dword immediate +} + + + +// generate a call to a parameterless function +static void INLINE gen_call_function_raw(void * func) { + cache_addb(0xe8); + cache_addd((Bit32u)func - (Bit32u)cache.pos-4); +} + +// generate a call to a function with paramcount parameters +// note: the parameters are loaded in the architecture specific way +// using the gen_load_param_ functions below +static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { + // Do the actual call to the procedure + cache_addb(0xe8); + Bit32u proc_addr=(Bit32u)cache.pos; + cache_addd((Bit32u)func - (Bit32u)cache.pos-4); + + // Restore the params of the stack + if (paramcount) { + cache_addw(0xc483); //add ESP,imm byte + cache_addb((!fastcall)?paramcount*4:0); + } + return proc_addr; +} + + +// load an immediate value as param'th function parameter +static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { + cache_addb(0x68); // push immediate + cache_addd(imm); +} + +// load an address as param'th function parameter +static void INLINE gen_load_param_addr(Bitu addr,Bitu param) { + cache_addb(0x68); // push immediate (address) + cache_addd(addr); +} + +// load a host-register as param'th function parameter +static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { + cache_addb(0x50+(reg&7)); // push reg +} + +// load a value from memory as param'th function parameter +static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { + cache_addw(0x35ff); // push [] + cache_addd(mem); +} + + + +// jump to an address pointed at by ptr, offset is in imm +static void gen_jmp_ptr(void * ptr,Bits imm=0) { + gen_mov_word_to_reg(HOST_EAX,ptr,true); + cache_addb(0xff); // jmp [eax+imm] + if (!imm) { + cache_addb(0x20); + } else if ((imm>=-128 && imm<=127)) { + cache_addb(0x60); + cache_addb(imm); + } else { + cache_addb(0xa0); + cache_addd(imm); + } +} + + +// short conditional jump (+-127 bytes) if register is zero +// the destination is set by gen_fill_branch() later +static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { + if (!dword) cache_addb(0x66); + cache_addb(0x0b); // or reg,reg + cache_addb(0xc0+reg+(reg<<3)); + + cache_addw(0x0074); // jz addr + return ((Bit32u)cache.pos-1); +} + +// short conditional jump (+-127 bytes) if register is nonzero +// the destination is set by gen_fill_branch() later +static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { + if (!dword) cache_addb(0x66); + cache_addb(0x0b); // or reg,reg + cache_addb(0xc0+reg+(reg<<3)); + + cache_addw(0x0075); // jnz addr + return ((Bit32u)cache.pos-1); +} + +// short conditional jump (+-127 bytes) if register +// (as set by a boolean operation) is nonzero +// the destination is set by gen_fill_branch() later +static Bit32u gen_create_branch_on_nonzero_bool(HostReg reg) { + cache_addb(0x0a); // or reg,reg + cache_addb(0xc0+reg+(reg<<3)); + + cache_addw(0x0075); // jnz addr + return ((Bit32u)cache.pos-1); +} + +// calculate relative offset and fill it into the location pointed to by data +static void gen_fill_branch(DRC_PTR_SIZE_IM data) { +#if C_DEBUG + Bits len=(Bit32u)cache.pos-data; + if (len<0) len=-len; + if (len>126) LOG_MSG("Big jump %d",len); +#endif + *(Bit8u*)data=(Bit8u)((Bit32u)cache.pos-data-1); +} + +// conditional jump if register is nonzero +// for isdword==true the 32bit of the register are tested +// for isdword==false the lowest 8bit of the register are tested +static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { + // isdword: cmp reg32,0 + // not isdword: cmp reg8,0 + cache_addb(0x0a+(isdword?1:0)); // or reg,reg + cache_addb(0xc0+reg+(reg<<3)); + + cache_addw(0x850f); // jnz + cache_addd(0); + return ((Bit32u)cache.pos-4); +} + +// compare 32bit-register against zero and jump if value less/equal than zero +static Bit32u gen_create_branch_long_leqzero(HostReg reg) { + cache_addw(0xf883+(reg<<8)); + cache_addb(0x00); // cmp reg,0 + + cache_addw(0x8e0f); // jle + cache_addd(0); + return ((Bit32u)cache.pos-4); +} + +// calculate long relative offset and fill it into the location pointed to by data +static void gen_fill_branch_long(Bit32u data) { + *(Bit32u*)data=((Bit32u)cache.pos-data-4); +} + + +static void gen_run_code(void) { + cache_addd(0x0424448b); // mov eax,[esp+4] + cache_addb(0x53); // push ebx + cache_addw(0xd0ff); // call eax + cache_addb(0x5b); // pop ebx +} + +// return from a function +static void gen_return_function(void) { + cache_addb(0xc3); // ret +} diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index ba6e72a7..ad9a8b11 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.100 2007-06-01 16:40:40 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.101 2007-06-02 11:47:05 c2woody Exp $ */ #include #include @@ -68,6 +68,10 @@ void CPU_Core_Dyn_X86_Init(void); void CPU_Core_Dyn_X86_Cache_Init(bool enable_cache); void CPU_Core_Dyn_X86_Cache_Close(void); void CPU_Core_Dyn_X86_SetFPUMode(bool dh_fpu); +#elif (C_DYNREC) +void CPU_Core_Dynrec_Init(void); +void CPU_Core_Dynrec_Cache_Init(bool enable_cache); +void CPU_Core_Dynrec_Cache_Close(void); #endif /* In debug mode exceptions are tested and dosbox exits when @@ -2071,6 +2075,8 @@ public: CPU_Core_Full_Init(); #if (C_DYNAMIC_X86) CPU_Core_Dyn_X86_Init(); +#elif (C_DYNREC) + CPU_Core_Dynrec_Init(); #endif MAPPER_AddHandler(CPU_CycleDecrease,MK_f11,MMOD1,"cycledown","Dec Cycles"); MAPPER_AddHandler(CPU_CycleIncrease,MK_f12,MMOD1,"cycleup" ,"Inc Cycles"); @@ -2174,6 +2180,10 @@ public: cpudecoder=&CPU_Core_Normal_Run; CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CORE; } +#elif (C_DYNREC) + else if (!strcasecmp(core,"dynamic")) { + cpudecoder=&CPU_Core_Dynrec_Run; + } #endif else { LOG_MSG("CPU:Unknown core type %s, switching back to normal.",core); @@ -2181,6 +2191,8 @@ public: #if (C_DYNAMIC_X86) CPU_Core_Dyn_X86_Cache_Init(!strcasecmp(core,"dynamic") || !strcasecmp(core,"dynamic_nodhfpu")); +#elif (C_DYNREC) + CPU_Core_Dynrec_Cache_Init(!strcasecmp(core,"dynamic")); #endif if(CPU_CycleMax <= 0) CPU_CycleMax = 3000; @@ -2198,6 +2210,8 @@ static CPU * test; void CPU_ShutDown(Section* sec) { #if (C_DYNAMIC_X86) CPU_Core_Dyn_X86_Cache_Close(); +#elif (C_DYNREC) + CPU_Core_Dynrec_Cache_Close(); #endif delete test; } diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 9c7bef85..4a454829 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -167,6 +167,9 @@ + + @@ -278,6 +281,34 @@ RelativePath="..\src\cpu\core_dyn_x86\string.h"> + + + + + + + + + + + + + + + + + + Date: Sun, 3 Jun 2007 10:59:46 +0000 Subject: [PATCH 2780/4131] don't crash when closing the console window (win only), thanks to etil for the patch Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2866 --- src/gui/sdlmain.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index bb0b7ead..f25f3805 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.129 2007-05-01 20:00:45 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.130 2007-06-03 10:59:46 c2woody Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -28,6 +28,9 @@ #include #include #include +#ifdef WIN32 +#include +#endif #include "SDL.h" @@ -1303,6 +1306,23 @@ void GFX_Events() { } } +#if defined (WIN32) +static BOOL WINAPI ConsoleEventHandler(DWORD event) { + switch (event) { + case CTRL_SHUTDOWN_EVENT: + case CTRL_LOGOFF_EVENT: + case CTRL_CLOSE_EVENT: + case CTRL_BREAK_EVENT: + raise(SIGTERM); + return TRUE; + case CTRL_C_EVENT: + default: //pass to the next handler + return FALSE; + } +} +#endif + + /* static variable to show wether there is not a valid stdout. * Fixes some bugs when -noconsole is used in a read only directory */ static bool no_stdout = false; @@ -1355,6 +1375,10 @@ int main(int argc, char* argv[]) { DEBUG_SetupConsole(); #endif +#if defined(WIN32) + SetConsoleCtrlHandler((PHANDLER_ROUTINE) ConsoleEventHandler,TRUE); +#endif + #ifdef OS2 PPIB pib; PTIB tib; From 8112ac82e8e07f0eb9eb5f3749b5d430d48bfa5c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 3 Jun 2007 13:50:42 +0000 Subject: [PATCH 2781/4131] introduce option to disable both dynamic cores with one option Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2867 --- configure.in | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 39207092..bd6fa5d0 100644 --- a/configure.in +++ b/configure.in @@ -216,10 +216,12 @@ case "$target_cpu" in ;; 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 ; then +if test x$enable_dynamic_x86 = xno || test x$enable_dynamic_core=xno; then AC_MSG_RESULT(no) else if test x$c_targetcpu = xx86 ; then @@ -233,7 +235,7 @@ 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 ; then +if test x$enable_dynrec = xno || test x$enable_dynamic_core = xno; then AC_MSG_RESULT(no) else dnl x86 only enable it if dynamic-x86 is disabled. From 432c61d1fa3d3cfaac023f3db3c1fffec4f56522 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 3 Jun 2007 13:55:16 +0000 Subject: [PATCH 2782/4131] Add patch 1713574: "timer precision fix" by wjp. Fixes vret problems under 64 bit hosts. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2868 --- include/pic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pic.h b/include/pic.h index 4d37dedb..420a1fe5 100644 --- a/include/pic.h +++ b/include/pic.h @@ -49,7 +49,7 @@ INLINE Bits PIC_MakeCycles(double amount) { } INLINE double PIC_FullIndex(void) { - return PIC_Ticks+PIC_TickIndex(); + return PIC_Ticks+(double)PIC_TickIndex(); } void PIC_ActivateIRQ(Bitu irq); From 7859569c6d331dcac3befeaffaa4ffd8bff2d69e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 3 Jun 2007 16:46:33 +0000 Subject: [PATCH 2783/4131] add mouse driver backdoor entry point (enables mouse in Last half of Darkness, PC-BLOX) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2869 --- include/callback.h | 6 ++-- src/cpu/callback.cpp | 24 ++++++++++++- src/ints/mouse.cpp | 81 +++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 103 insertions(+), 8 deletions(-) diff --git a/include/callback.h b/include/callback.h index bf9f23f3..72da8222 100644 --- a/include/callback.h +++ b/include/callback.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.h,v 1.19 2007-01-08 19:45:37 qbix79 Exp $ */ +/* $Id: callback.h,v 1.20 2007-06-03 16:46:33 c2woody Exp $ */ #ifndef DOSBOX_CALLBACK_H #define DOSBOX_CALLBACK_H @@ -28,8 +28,8 @@ typedef Bitu (*CallBack_Handler)(void); extern CallBack_Handler CallBack_Handlers[]; -enum { CB_RETN,CB_RETF,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1, - CB_IRQ0,CB_IRQ1,CB_IRQ9,CB_IRQ12,CB_IRQ12_RET,CB_IRQ6_PCJR, +enum { CB_RETN,CB_RETF,CB_RETF8,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1, + 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 }; #define CB_MAX 128 diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 0afe1074..ea1e167f 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.36 2007-01-08 19:45:38 qbix79 Exp $ */ +/* $Id: callback.cpp,v 1.37 2007-06-03 16:46:33 c2woody Exp $ */ #include #include @@ -155,6 +155,16 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ } 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: if (use_cb) { phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4 @@ -300,6 +310,18 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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) { diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 4c0aa588..b038727d 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.66 2007-01-08 19:45:41 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.67 2007-06-03 16:46:33 c2woody Exp $ */ #include #include @@ -34,7 +34,7 @@ #include "bios.h" -static Bitu call_int33,call_int74,int74_ret_callback; +static Bitu call_int33,call_int74,int74_ret_callback,call_mouse_bd; static Bit16u ps2cbseg,ps2cbofs; static bool useps2callback,ps2callbackinit; static Bit16u call_ps2; @@ -862,6 +862,65 @@ static Bitu INT33_Handler(void) { return CBRET_NONE; } +static Bitu MOUSE_BD_Handler(void) { + // the stack contains offsets to register values + Bit16u raxpt=real_readw(SegValue(ss),reg_sp+0x0a); + Bit16u rbxpt=real_readw(SegValue(ss),reg_sp+0x08); + Bit16u rcxpt=real_readw(SegValue(ss),reg_sp+0x06); + Bit16u rdxpt=real_readw(SegValue(ss),reg_sp+0x04); + + // read out the actual values, registers ARE overwritten + Bit16u rax=real_readw(SegValue(ds),raxpt); + reg_ax=rax; + reg_bx=real_readw(SegValue(ds),rbxpt); + reg_cx=real_readw(SegValue(ds),rcxpt); + reg_dx=real_readw(SegValue(ds),rdxpt); +// LOG_MSG("MOUSE BD: %04X %X %X %X %d %d",reg_ax,reg_bx,reg_cx,reg_dx,POS_X,POS_Y); + + // some functions are treated in a special way (additional registers) + switch (rax) { + case 0x09: /* Define GFX Cursor */ + case 0x16: /* Save driver state */ + case 0x17: /* load driver state */ + SegSet16(es,SegValue(ds)); + break; + case 0x0c: /* Define interrupt subroutine parameters */ + case 0x14: /* Exchange event-handler */ + if (reg_bx!=0) SegSet16(es,reg_bx); + else SegSet16(es,SegValue(ds)); + break; + case 0x10: /* Define screen region for updating */ + reg_cx=real_readw(SegValue(ds),rdxpt); + reg_dx=real_readw(SegValue(ds),rdxpt+2); + reg_si=real_readw(SegValue(ds),rdxpt+4); + reg_di=real_readw(SegValue(ds),rdxpt+6); + break; + default: + break; + } + + INT33_Handler(); + + // save back the registers, too + real_writew(SegValue(ds),raxpt,reg_ax); + real_writew(SegValue(ds),rbxpt,reg_bx); + real_writew(SegValue(ds),rcxpt,reg_cx); + real_writew(SegValue(ds),rdxpt,reg_dx); + switch (rax) { + case 0x1f: /* Disable Mousedriver */ + real_writew(SegValue(ds),rbxpt,SegValue(es)); + break; + case 0x14: /* Exchange event-handler */ + real_writew(SegValue(ds),rcxpt,SegValue(es)); + break; + default: + break; + } + + reg_ax=rax; + return CBRET_NONE; +} + static Bitu INT74_Handler(void) { if (mouse.events>0) { mouse.events--; @@ -902,9 +961,23 @@ Bitu MOUSE_UserInt_CB_Handler(void) { void MOUSE_Init(Section* sec) { // Callback for mouse interrupt 0x33 call_int33=CALLBACK_Allocate(); - CALLBACK_Setup(call_int33,&INT33_Handler,CB_IRET,"Mouse"); + RealPt i33loc=RealMake(CB_SEG+1,(call_int33*CB_SIZE)-0x10); +// RealPt i33loc=RealMake(DOS_GetMemory(0x1)-1,0x10); // need another location + CALLBACK_Setup(call_int33,&INT33_Handler,CB_MOUSE,Real2Phys(i33loc),"Mouse"); // Wasteland needs low(seg(int33))!=0 and low(ofs(int33))!=0 - real_writed(0,0x33<<2,RealMake(CB_SEG+1,(call_int33*CB_SIZE)-0x10)); + real_writed(0,0x33<<2,i33loc); + + call_mouse_bd=CALLBACK_Allocate(); + CALLBACK_Setup(call_mouse_bd,&MOUSE_BD_Handler,CB_RETF8, + PhysMake(RealSeg(i33loc),RealOff(i33loc)+2),"MouseBD"); + // pseudocode for CB_MOUSE (including the special backdoor entry point): + // jump near i33hd + // callback MOUSE_BD_Handler + // retf 8 + // label i33hd: + // callback INT33_Handler + // iret + // Callback for ps2 irq call_int74=CALLBACK_Allocate(); From b8920454e45b416e42947d48e1ddfc1e77340c0a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 3 Jun 2007 18:07:54 +0000 Subject: [PATCH 2784/4131] Fix compilation of dynrec core on 32 bit linux Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2870 --- src/cpu/core_dynrec/decoder_basic.h | 6 + src/cpu/core_dynrec/operators.h | 181 ++++++++++++++++++++++++++++ src/cpu/core_dynrec/risc_x86.h | 6 + 3 files changed, 193 insertions(+) diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index ebef1cb7..afb606bb 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -563,6 +563,7 @@ static void dyn_check_exception(HostReg reg) { +bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) DRC_FC; bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) { Bitu index=(address>>12); if (paging.tlb.read[index]) { @@ -577,6 +578,7 @@ bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) { } } +bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) DRC_FC; bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) { Bitu index=(address>>12); if (paging.tlb.write[index]) { @@ -585,6 +587,7 @@ bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) { } else return paging.tlb.handler[index]->writeb_checked(address,val); } +bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) DRC_FC; bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) { #if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) if (!(address & 1)) { @@ -605,6 +608,7 @@ bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) { } else return mem_unalignedreadw_checked_x86(address, ((Bit16u*)(&core_dynrec.readdata))); } +bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) DRC_FC; bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) { #if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) if (!(address & 3)) { @@ -625,6 +629,7 @@ bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) { } else return mem_unalignedreadd_checked_x86(address, ((Bit32u*)(&core_dynrec.readdata))); } +bool DRC_CALL_CONV mem_writew_checked_drc(PhysPt address,Bit16u val) DRC_FC; bool DRC_CALL_CONV mem_writew_checked_drc(PhysPt address,Bit16u val) { #if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) if (!(address & 1)) { @@ -639,6 +644,7 @@ bool DRC_CALL_CONV mem_writew_checked_drc(PhysPt address,Bit16u val) { } else return mem_unalignedwritew_checked_x86(address,val); } +bool DRC_CALL_CONV mem_writed_checked_drc(PhysPt address,Bit32u val) DRC_FC; bool DRC_CALL_CONV mem_writed_checked_drc(PhysPt address,Bit32u val) { #if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) if (!(address & 3)) { diff --git a/src/cpu/core_dynrec/operators.h b/src/cpu/core_dynrec/operators.h index 21a6dfd4..03aa714c 100644 --- a/src/cpu/core_dynrec/operators.h +++ b/src/cpu/core_dynrec/operators.h @@ -17,6 +17,7 @@ */ +static Bit8u DRC_CALL_CONV dynrec_add_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_add_byte(Bit8u op1,Bit8u op2) { lf_var1b=op1; lf_var2b=op2; @@ -25,10 +26,12 @@ static Bit8u DRC_CALL_CONV dynrec_add_byte(Bit8u op1,Bit8u op2) { return lf_resb; } +static Bit8u DRC_CALL_CONV dynrec_add_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_add_byte_simple(Bit8u op1,Bit8u op2) { return op1+op2; } +static Bit8u DRC_CALL_CONV dynrec_adc_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_adc_byte(Bit8u op1,Bit8u op2) { lflags.oldcf=get_CF()!=0; lf_var1b=op1; @@ -38,10 +41,12 @@ static Bit8u DRC_CALL_CONV dynrec_adc_byte(Bit8u op1,Bit8u op2) { return lf_resb; } +static Bit8u DRC_CALL_CONV dynrec_adc_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_adc_byte_simple(Bit8u op1,Bit8u op2) { return (Bit8u)(op1+op2+(Bitu)(get_CF()!=0)); } +static Bit8u DRC_CALL_CONV dynrec_sub_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_sub_byte(Bit8u op1,Bit8u op2) { lf_var1b=op1; lf_var2b=op2; @@ -50,10 +55,12 @@ static Bit8u DRC_CALL_CONV dynrec_sub_byte(Bit8u op1,Bit8u op2) { return lf_resb; } +static Bit8u DRC_CALL_CONV dynrec_sub_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_sub_byte_simple(Bit8u op1,Bit8u op2) { return op1-op2; } +static Bit8u DRC_CALL_CONV dynrec_sbb_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_sbb_byte(Bit8u op1,Bit8u op2) { lflags.oldcf=get_CF()!=0; lf_var1b=op1; @@ -63,10 +70,12 @@ static Bit8u DRC_CALL_CONV dynrec_sbb_byte(Bit8u op1,Bit8u op2) { return lf_resb; } +static Bit8u DRC_CALL_CONV dynrec_sbb_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_sbb_byte_simple(Bit8u op1,Bit8u op2) { return (Bit8u)(op1-(op2+(Bitu)(get_CF()!=0))); } +static void DRC_CALL_CONV dynrec_cmp_byte(Bit8u op1,Bit8u op2) DRC_FC; static void DRC_CALL_CONV dynrec_cmp_byte(Bit8u op1,Bit8u op2) { lf_var1b=op1; lf_var2b=op2; @@ -74,9 +83,11 @@ static void DRC_CALL_CONV dynrec_cmp_byte(Bit8u op1,Bit8u op2) { lflags.type=t_CMPb; } +static void DRC_CALL_CONV dynrec_cmp_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; static void DRC_CALL_CONV dynrec_cmp_byte_simple(Bit8u op1,Bit8u op2) { } +static Bit8u DRC_CALL_CONV dynrec_xor_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_xor_byte(Bit8u op1,Bit8u op2) { lf_var1b=op1; lf_var2b=op2; @@ -85,10 +96,12 @@ static Bit8u DRC_CALL_CONV dynrec_xor_byte(Bit8u op1,Bit8u op2) { return lf_resb; } +static Bit8u DRC_CALL_CONV dynrec_xor_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_xor_byte_simple(Bit8u op1,Bit8u op2) { return op1 ^ op2; } +static Bit8u DRC_CALL_CONV dynrec_and_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_and_byte(Bit8u op1,Bit8u op2) { lf_var1b=op1; lf_var2b=op2; @@ -97,10 +110,12 @@ static Bit8u DRC_CALL_CONV dynrec_and_byte(Bit8u op1,Bit8u op2) { return lf_resb; } +static Bit8u DRC_CALL_CONV dynrec_and_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_and_byte_simple(Bit8u op1,Bit8u op2) { return op1 & op2; } +static Bit8u DRC_CALL_CONV dynrec_or_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_or_byte(Bit8u op1,Bit8u op2) { lf_var1b=op1; lf_var2b=op2; @@ -109,10 +124,12 @@ static Bit8u DRC_CALL_CONV dynrec_or_byte(Bit8u op1,Bit8u op2) { return lf_resb; } +static Bit8u DRC_CALL_CONV dynrec_or_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_or_byte_simple(Bit8u op1,Bit8u op2) { return op1 | op2; } +static void DRC_CALL_CONV dynrec_test_byte(Bit8u op1,Bit8u op2) DRC_FC; static void DRC_CALL_CONV dynrec_test_byte(Bit8u op1,Bit8u op2) { lf_var1b=op1; lf_var2b=op2; @@ -120,9 +137,11 @@ static void DRC_CALL_CONV dynrec_test_byte(Bit8u op1,Bit8u op2) { lflags.type=t_TESTb; } +static void DRC_CALL_CONV dynrec_test_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; static void DRC_CALL_CONV dynrec_test_byte_simple(Bit8u op1,Bit8u op2) { } +static Bit16u DRC_CALL_CONV dynrec_add_word(Bit16u op1,Bit16u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_add_word(Bit16u op1,Bit16u op2) { lf_var1w=op1; lf_var2w=op2; @@ -131,10 +150,12 @@ static Bit16u DRC_CALL_CONV dynrec_add_word(Bit16u op1,Bit16u op2) { return lf_resw; } +static Bit16u DRC_CALL_CONV dynrec_add_word_simple(Bit16u op1,Bit16u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_add_word_simple(Bit16u op1,Bit16u op2) { return op1+op2; } +static Bit16u DRC_CALL_CONV dynrec_adc_word(Bit16u op1,Bit16u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_adc_word(Bit16u op1,Bit16u op2) { lflags.oldcf=get_CF()!=0; lf_var1w=op1; @@ -144,10 +165,12 @@ static Bit16u DRC_CALL_CONV dynrec_adc_word(Bit16u op1,Bit16u op2) { return lf_resw; } +static Bit16u DRC_CALL_CONV dynrec_adc_word_simple(Bit16u op1,Bit16u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_adc_word_simple(Bit16u op1,Bit16u op2) { return (Bit16u)(op1+op2+(Bitu)(get_CF()!=0)); } +static Bit16u DRC_CALL_CONV dynrec_sub_word(Bit16u op1,Bit16u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_sub_word(Bit16u op1,Bit16u op2) { lf_var1w=op1; lf_var2w=op2; @@ -156,10 +179,12 @@ static Bit16u DRC_CALL_CONV dynrec_sub_word(Bit16u op1,Bit16u op2) { return lf_resw; } +static Bit16u DRC_CALL_CONV dynrec_sub_word_simple(Bit16u op1,Bit16u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_sub_word_simple(Bit16u op1,Bit16u op2) { return op1-op2; } +static Bit16u DRC_CALL_CONV dynrec_sbb_word(Bit16u op1,Bit16u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_sbb_word(Bit16u op1,Bit16u op2) { lflags.oldcf=get_CF()!=0; lf_var1w=op1; @@ -169,10 +194,12 @@ static Bit16u DRC_CALL_CONV dynrec_sbb_word(Bit16u op1,Bit16u op2) { return lf_resw; } +static Bit16u DRC_CALL_CONV dynrec_sbb_word_simple(Bit16u op1,Bit16u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_sbb_word_simple(Bit16u op1,Bit16u op2) { return (Bit16u)(op1-(op2+(Bitu)(get_CF()!=0))); } +static void DRC_CALL_CONV dynrec_cmp_word(Bit16u op1,Bit16u op2) DRC_FC; static void DRC_CALL_CONV dynrec_cmp_word(Bit16u op1,Bit16u op2) { lf_var1w=op1; lf_var2w=op2; @@ -180,9 +207,11 @@ static void DRC_CALL_CONV dynrec_cmp_word(Bit16u op1,Bit16u op2) { lflags.type=t_CMPw; } +static void DRC_CALL_CONV dynrec_cmp_word_simple(Bit16u op1,Bit16u op2) DRC_FC; static void DRC_CALL_CONV dynrec_cmp_word_simple(Bit16u op1,Bit16u op2) { } +static Bit16u DRC_CALL_CONV dynrec_xor_word(Bit16u op1,Bit16u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_xor_word(Bit16u op1,Bit16u op2) { lf_var1w=op1; lf_var2w=op2; @@ -191,10 +220,12 @@ static Bit16u DRC_CALL_CONV dynrec_xor_word(Bit16u op1,Bit16u op2) { return lf_resw; } +static Bit16u DRC_CALL_CONV dynrec_xor_word_simple(Bit16u op1,Bit16u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_xor_word_simple(Bit16u op1,Bit16u op2) { return op1 ^ op2; } +static Bit16u DRC_CALL_CONV dynrec_and_word(Bit16u op1,Bit16u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_and_word(Bit16u op1,Bit16u op2) { lf_var1w=op1; lf_var2w=op2; @@ -203,10 +234,12 @@ static Bit16u DRC_CALL_CONV dynrec_and_word(Bit16u op1,Bit16u op2) { return lf_resw; } +static Bit16u DRC_CALL_CONV dynrec_and_word_simple(Bit16u op1,Bit16u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_and_word_simple(Bit16u op1,Bit16u op2) { return op1 & op2; } +static Bit16u DRC_CALL_CONV dynrec_or_word(Bit16u op1,Bit16u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_or_word(Bit16u op1,Bit16u op2) { lf_var1w=op1; lf_var2w=op2; @@ -215,10 +248,12 @@ static Bit16u DRC_CALL_CONV dynrec_or_word(Bit16u op1,Bit16u op2) { return lf_resw; } +static Bit16u DRC_CALL_CONV dynrec_or_word_simple(Bit16u op1,Bit16u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_or_word_simple(Bit16u op1,Bit16u op2) { return op1 | op2; } +static void DRC_CALL_CONV dynrec_test_word(Bit16u op1,Bit16u op2) DRC_FC; static void DRC_CALL_CONV dynrec_test_word(Bit16u op1,Bit16u op2) { lf_var1w=op1; lf_var2w=op2; @@ -226,9 +261,11 @@ static void DRC_CALL_CONV dynrec_test_word(Bit16u op1,Bit16u op2) { lflags.type=t_TESTw; } +static void DRC_CALL_CONV dynrec_test_word_simple(Bit16u op1,Bit16u op2) DRC_FC; static void DRC_CALL_CONV dynrec_test_word_simple(Bit16u op1,Bit16u op2) { } +static Bit32u DRC_CALL_CONV dynrec_add_dword(Bit32u op1,Bit32u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_add_dword(Bit32u op1,Bit32u op2) { lf_var1d=op1; lf_var2d=op2; @@ -237,10 +274,12 @@ static Bit32u DRC_CALL_CONV dynrec_add_dword(Bit32u op1,Bit32u op2) { return lf_resd; } +static Bit32u DRC_CALL_CONV dynrec_add_dword_simple(Bit32u op1,Bit32u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_add_dword_simple(Bit32u op1,Bit32u op2) { return op1 + op2; } +static Bit32u DRC_CALL_CONV dynrec_adc_dword(Bit32u op1,Bit32u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_adc_dword(Bit32u op1,Bit32u op2) { lflags.oldcf=get_CF()!=0; lf_var1d=op1; @@ -250,10 +289,12 @@ static Bit32u DRC_CALL_CONV dynrec_adc_dword(Bit32u op1,Bit32u op2) { return lf_resd; } +static Bit32u DRC_CALL_CONV dynrec_adc_dword_simple(Bit32u op1,Bit32u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_adc_dword_simple(Bit32u op1,Bit32u op2) { return op1+op2+(Bitu)(get_CF()!=0); } +static Bit32u DRC_CALL_CONV dynrec_sub_dword(Bit32u op1,Bit32u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_sub_dword(Bit32u op1,Bit32u op2) { lf_var1d=op1; lf_var2d=op2; @@ -262,10 +303,12 @@ static Bit32u DRC_CALL_CONV dynrec_sub_dword(Bit32u op1,Bit32u op2) { return lf_resd; } +static Bit32u DRC_CALL_CONV dynrec_sub_dword_simple(Bit32u op1,Bit32u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_sub_dword_simple(Bit32u op1,Bit32u op2) { return op1-op2; } +static Bit32u DRC_CALL_CONV dynrec_sbb_dword(Bit32u op1,Bit32u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_sbb_dword(Bit32u op1,Bit32u op2) { lflags.oldcf=get_CF()!=0; lf_var1d=op1; @@ -275,10 +318,12 @@ static Bit32u DRC_CALL_CONV dynrec_sbb_dword(Bit32u op1,Bit32u op2) { return lf_resd; } +static Bit32u DRC_CALL_CONV dynrec_sbb_dword_simple(Bit32u op1,Bit32u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_sbb_dword_simple(Bit32u op1,Bit32u op2) { return op1-(op2+(Bitu)(get_CF()!=0)); } +static void DRC_CALL_CONV dynrec_cmp_dword(Bit32u op1,Bit32u op2) DRC_FC; static void DRC_CALL_CONV dynrec_cmp_dword(Bit32u op1,Bit32u op2) { lf_var1d=op1; lf_var2d=op2; @@ -286,9 +331,11 @@ static void DRC_CALL_CONV dynrec_cmp_dword(Bit32u op1,Bit32u op2) { lflags.type=t_CMPd; } +static void DRC_CALL_CONV dynrec_cmp_dword_simple(Bit32u op1,Bit32u op2) DRC_FC; static void DRC_CALL_CONV dynrec_cmp_dword_simple(Bit32u op1,Bit32u op2) { } +static Bit32u DRC_CALL_CONV dynrec_xor_dword(Bit32u op1,Bit32u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_xor_dword(Bit32u op1,Bit32u op2) { lf_var1d=op1; lf_var2d=op2; @@ -297,10 +344,12 @@ static Bit32u DRC_CALL_CONV dynrec_xor_dword(Bit32u op1,Bit32u op2) { return lf_resd; } +static Bit32u DRC_CALL_CONV dynrec_xor_dword_simple(Bit32u op1,Bit32u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_xor_dword_simple(Bit32u op1,Bit32u op2) { return op1 ^ op2; } +static Bit32u DRC_CALL_CONV dynrec_and_dword(Bit32u op1,Bit32u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_and_dword(Bit32u op1,Bit32u op2) { lf_var1d=op1; lf_var2d=op2; @@ -309,10 +358,12 @@ static Bit32u DRC_CALL_CONV dynrec_and_dword(Bit32u op1,Bit32u op2) { return lf_resd; } +static Bit32u DRC_CALL_CONV dynrec_and_dword_simple(Bit32u op1,Bit32u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_and_dword_simple(Bit32u op1,Bit32u op2) { return op1 & op2; } +static Bit32u DRC_CALL_CONV dynrec_or_dword(Bit32u op1,Bit32u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_or_dword(Bit32u op1,Bit32u op2) { lf_var1d=op1; lf_var2d=op2; @@ -321,10 +372,12 @@ static Bit32u DRC_CALL_CONV dynrec_or_dword(Bit32u op1,Bit32u op2) { return lf_resd; } +static Bit32u DRC_CALL_CONV dynrec_or_dword_simple(Bit32u op1,Bit32u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_or_dword_simple(Bit32u op1,Bit32u op2) { return op1 | op2; } +static void DRC_CALL_CONV dynrec_test_dword(Bit32u op1,Bit32u op2) DRC_FC; static void DRC_CALL_CONV dynrec_test_dword(Bit32u op1,Bit32u op2) { lf_var1d=op1; lf_var2d=op2; @@ -332,6 +385,7 @@ static void DRC_CALL_CONV dynrec_test_dword(Bit32u op1,Bit32u op2) { lflags.type=t_TESTd; } +static void DRC_CALL_CONV dynrec_test_dword_simple(Bit32u op1,Bit32u op2) DRC_FC; static void DRC_CALL_CONV dynrec_test_dword_simple(Bit32u op1,Bit32u op2) { } @@ -469,6 +523,7 @@ static void dyn_dop_word_gencall(DualOps op,bool dword) { } +static Bit8u DRC_CALL_CONV dynrec_inc_byte(Bit8u op) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_inc_byte(Bit8u op) { LoadCF; lf_var1b=op; @@ -477,10 +532,12 @@ static Bit8u DRC_CALL_CONV dynrec_inc_byte(Bit8u op) { return lf_resb; } +static Bit8u DRC_CALL_CONV dynrec_inc_byte_simple(Bit8u op) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_inc_byte_simple(Bit8u op) { return op+1; } +static Bit8u DRC_CALL_CONV dynrec_dec_byte(Bit8u op) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_dec_byte(Bit8u op) { LoadCF; lf_var1b=op; @@ -489,14 +546,17 @@ static Bit8u DRC_CALL_CONV dynrec_dec_byte(Bit8u op) { return lf_resb; } +static Bit8u DRC_CALL_CONV dynrec_dec_byte_simple(Bit8u op) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_dec_byte_simple(Bit8u op) { return op-1; } +static Bit8u DRC_CALL_CONV dynrec_not_byte(Bit8u op) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_not_byte(Bit8u op) { return ~op; } +static Bit8u DRC_CALL_CONV dynrec_neg_byte(Bit8u op) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_neg_byte(Bit8u op) { lf_var1b=op; lf_resb=0-lf_var1b; @@ -504,10 +564,12 @@ static Bit8u DRC_CALL_CONV dynrec_neg_byte(Bit8u op) { return lf_resb; } +static Bit8u DRC_CALL_CONV dynrec_neg_byte_simple(Bit8u op) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_neg_byte_simple(Bit8u op) { return 0-op; } +static Bit16u DRC_CALL_CONV dynrec_inc_word(Bit16u op) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_inc_word(Bit16u op) { LoadCF; lf_var1w=op; @@ -516,10 +578,12 @@ static Bit16u DRC_CALL_CONV dynrec_inc_word(Bit16u op) { return lf_resw; } +static Bit16u DRC_CALL_CONV dynrec_inc_word_simple(Bit16u op) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_inc_word_simple(Bit16u op) { return op+1; } +static Bit16u DRC_CALL_CONV dynrec_dec_word(Bit16u op) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_dec_word(Bit16u op) { LoadCF; lf_var1w=op; @@ -528,14 +592,17 @@ static Bit16u DRC_CALL_CONV dynrec_dec_word(Bit16u op) { return lf_resw; } +static Bit16u DRC_CALL_CONV dynrec_dec_word_simple(Bit16u op) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_dec_word_simple(Bit16u op) { return op-1; } +static Bit16u DRC_CALL_CONV dynrec_not_word(Bit16u op) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_not_word(Bit16u op) { return ~op; } +static Bit16u DRC_CALL_CONV dynrec_neg_word(Bit16u op) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_neg_word(Bit16u op) { lf_var1w=op; lf_resw=0-lf_var1w; @@ -543,10 +610,12 @@ static Bit16u DRC_CALL_CONV dynrec_neg_word(Bit16u op) { return lf_resw; } +static Bit16u DRC_CALL_CONV dynrec_neg_word_simple(Bit16u op) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_neg_word_simple(Bit16u op) { return 0-op; } +static Bit32u DRC_CALL_CONV dynrec_inc_dword(Bit32u op) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_inc_dword(Bit32u op) { LoadCF; lf_var1d=op; @@ -555,10 +624,12 @@ static Bit32u DRC_CALL_CONV dynrec_inc_dword(Bit32u op) { return lf_resd; } +static Bit32u DRC_CALL_CONV dynrec_inc_dword_simple(Bit32u op) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_inc_dword_simple(Bit32u op) { return op+1; } +static Bit32u DRC_CALL_CONV dynrec_dec_dword(Bit32u op) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_dec_dword(Bit32u op) { LoadCF; lf_var1d=op; @@ -567,14 +638,17 @@ static Bit32u DRC_CALL_CONV dynrec_dec_dword(Bit32u op) { return lf_resd; } +static Bit32u DRC_CALL_CONV dynrec_dec_dword_simple(Bit32u op) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_dec_dword_simple(Bit32u op) { return op-1; } +static Bit32u DRC_CALL_CONV dynrec_not_dword(Bit32u op) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_not_dword(Bit32u op) { return ~op; } +static Bit32u DRC_CALL_CONV dynrec_neg_dword(Bit32u op) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_neg_dword(Bit32u op) { lf_var1d=op; lf_resd=0-lf_var1d; @@ -582,6 +656,7 @@ static Bit32u DRC_CALL_CONV dynrec_neg_dword(Bit32u op) { return lf_resd; } +static Bit32u DRC_CALL_CONV dynrec_neg_dword_simple(Bit32u op) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_neg_dword_simple(Bit32u op) { return 0-op; } @@ -651,6 +726,7 @@ static void dyn_sop_word_gencall(SingleOps op,bool dword) { } +static Bit8u DRC_CALL_CONV dynrec_rol_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_rol_byte(Bit8u op1,Bit8u op2) { if (!(op2&0x7)) { if (op2&0x18) { @@ -669,11 +745,13 @@ static Bit8u DRC_CALL_CONV dynrec_rol_byte(Bit8u op1,Bit8u op2) { return lf_resb; } +static Bit8u DRC_CALL_CONV dynrec_rol_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_rol_byte_simple(Bit8u op1,Bit8u op2) { if (!(op2&0x7)) return op1; return (op1 << (op2&0x07)) | (op1 >> (8-(op2&0x07))); } +static Bit8u DRC_CALL_CONV dynrec_ror_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_ror_byte(Bit8u op1,Bit8u op2) { if (!(op2&0x7)) { if (op2&0x10) { @@ -692,11 +770,13 @@ static Bit8u DRC_CALL_CONV dynrec_ror_byte(Bit8u op1,Bit8u op2) { return lf_resb; } +static Bit8u DRC_CALL_CONV dynrec_ror_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_ror_byte_simple(Bit8u op1,Bit8u op2) { if (!(op2&0x7)) return op1; return (op1 >> (op2&0x07)) | (op1 << (8-(op2&0x07))); } +static Bit8u DRC_CALL_CONV dynrec_rcl_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_rcl_byte(Bit8u op1,Bit8u op2) { if (op2%9) { Bit8u cf=(Bit8u)FillFlags()&0x1; @@ -709,6 +789,7 @@ static Bit8u DRC_CALL_CONV dynrec_rcl_byte(Bit8u op1,Bit8u op2) { } else return op1; } +static Bit8u DRC_CALL_CONV dynrec_rcr_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_rcr_byte(Bit8u op1,Bit8u op2) { if (op2%9) { Bit8u cf=(Bit8u)FillFlags()&0x1; @@ -721,6 +802,7 @@ static Bit8u DRC_CALL_CONV dynrec_rcr_byte(Bit8u op1,Bit8u op2) { } else return op1; } +static Bit8u DRC_CALL_CONV dynrec_shl_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_shl_byte(Bit8u op1,Bit8u op2) { if (!op2) return op1; lf_var1b=op1; @@ -730,11 +812,13 @@ static Bit8u DRC_CALL_CONV dynrec_shl_byte(Bit8u op1,Bit8u op2) { return lf_resb; } +static Bit8u DRC_CALL_CONV dynrec_shl_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_shl_byte_simple(Bit8u op1,Bit8u op2) { if (!op2) return op1; return op1 << op2; } +static Bit8u DRC_CALL_CONV dynrec_shr_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_shr_byte(Bit8u op1,Bit8u op2) { if (!op2) return op1; lf_var1b=op1; @@ -744,11 +828,13 @@ static Bit8u DRC_CALL_CONV dynrec_shr_byte(Bit8u op1,Bit8u op2) { return lf_resb; } +static Bit8u DRC_CALL_CONV dynrec_shr_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_shr_byte_simple(Bit8u op1,Bit8u op2) { if (!op2) return op1; return op1 >> op2; } +static Bit8u DRC_CALL_CONV dynrec_sar_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_sar_byte(Bit8u op1,Bit8u op2) { if (!op2) return op1; lf_var1b=op1; @@ -763,6 +849,7 @@ static Bit8u DRC_CALL_CONV dynrec_sar_byte(Bit8u op1,Bit8u op2) { return lf_resb; } +static Bit8u DRC_CALL_CONV dynrec_sar_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_sar_byte_simple(Bit8u op1,Bit8u op2) { if (!op2) return op1; if (op2>8) op2=8; @@ -770,6 +857,7 @@ static Bit8u DRC_CALL_CONV dynrec_sar_byte_simple(Bit8u op1,Bit8u op2) { else return op1 >> op2; } +static Bit16u DRC_CALL_CONV dynrec_rol_word(Bit16u op1,Bit8u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_rol_word(Bit16u op1,Bit8u op2) { if (!(op2&0xf)) { if (op2&0x10) { @@ -787,11 +875,13 @@ static Bit16u DRC_CALL_CONV dynrec_rol_word(Bit16u op1,Bit8u op2) { return lf_resw; } +static Bit16u DRC_CALL_CONV dynrec_rol_word_simple(Bit16u op1,Bit8u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_rol_word_simple(Bit16u op1,Bit8u op2) { if (!(op2&0xf)) return op1; return (op1 << (op2&0xf)) | (op1 >> (16-(op2&0xf))); } +static Bit16u DRC_CALL_CONV dynrec_ror_word(Bit16u op1,Bit8u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_ror_word(Bit16u op1,Bit8u op2) { if (!(op2&0xf)) { if (op2&0x10) { @@ -809,11 +899,13 @@ static Bit16u DRC_CALL_CONV dynrec_ror_word(Bit16u op1,Bit8u op2) { return lf_resw; } +static Bit16u DRC_CALL_CONV dynrec_ror_word_simple(Bit16u op1,Bit8u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_ror_word_simple(Bit16u op1,Bit8u op2) { if (!(op2&0xf)) return op1; return (op1 >> (op2&0xf)) | (op1 << (16-(op2&0xf))); } +static Bit16u DRC_CALL_CONV dynrec_rcl_word(Bit16u op1,Bit8u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_rcl_word(Bit16u op1,Bit8u op2) { if (op2%17) { Bit16u cf=(Bit16u)FillFlags()&0x1; @@ -826,6 +918,7 @@ static Bit16u DRC_CALL_CONV dynrec_rcl_word(Bit16u op1,Bit8u op2) { } else return op1; } +static Bit16u DRC_CALL_CONV dynrec_rcr_word(Bit16u op1,Bit8u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_rcr_word(Bit16u op1,Bit8u op2) { if (op2%17) { Bit16u cf=(Bit16u)FillFlags()&0x1; @@ -838,6 +931,7 @@ static Bit16u DRC_CALL_CONV dynrec_rcr_word(Bit16u op1,Bit8u op2) { } else return op1; } +static Bit16u DRC_CALL_CONV dynrec_shl_word(Bit16u op1,Bit8u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_shl_word(Bit16u op1,Bit8u op2) { if (!op2) return op1; lf_var1w=op1; @@ -847,11 +941,13 @@ static Bit16u DRC_CALL_CONV dynrec_shl_word(Bit16u op1,Bit8u op2) { return lf_resw; } +static Bit16u DRC_CALL_CONV dynrec_shl_word_simple(Bit16u op1,Bit8u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_shl_word_simple(Bit16u op1,Bit8u op2) { if (!op2) return op1; return op1 << op2; } +static Bit16u DRC_CALL_CONV dynrec_shr_word(Bit16u op1,Bit8u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_shr_word(Bit16u op1,Bit8u op2) { if (!op2) return op1; lf_var1w=op1; @@ -861,11 +957,13 @@ static Bit16u DRC_CALL_CONV dynrec_shr_word(Bit16u op1,Bit8u op2) { return lf_resw; } +static Bit16u DRC_CALL_CONV dynrec_shr_word_simple(Bit16u op1,Bit8u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_shr_word_simple(Bit16u op1,Bit8u op2) { if (!op2) return op1; return op1 >> op2; } +static Bit16u DRC_CALL_CONV dynrec_sar_word(Bit16u op1,Bit8u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_sar_word(Bit16u op1,Bit8u op2) { if (!op2) return op1; lf_var1w=op1; @@ -880,6 +978,7 @@ static Bit16u DRC_CALL_CONV dynrec_sar_word(Bit16u op1,Bit8u op2) { return lf_resw; } +static Bit16u DRC_CALL_CONV dynrec_sar_word_simple(Bit16u op1,Bit8u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_sar_word_simple(Bit16u op1,Bit8u op2) { if (!op2) return op1; if (op2>16) op2=16; @@ -887,6 +986,7 @@ static Bit16u DRC_CALL_CONV dynrec_sar_word_simple(Bit16u op1,Bit8u op2) { else return op1 >> op2; } +static Bit32u DRC_CALL_CONV dynrec_rol_dword(Bit32u op1,Bit8u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_rol_dword(Bit32u op1,Bit8u op2) { if (!op2) return op1; FillFlags(); @@ -898,11 +998,13 @@ static Bit32u DRC_CALL_CONV dynrec_rol_dword(Bit32u op1,Bit8u op2) { return lf_resd; } +static Bit32u DRC_CALL_CONV dynrec_rol_dword_simple(Bit32u op1,Bit8u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_rol_dword_simple(Bit32u op1,Bit8u op2) { if (!op2) return op1; return (op1 << op2) | (op1 >> (32-op2)); } +static Bit32u DRC_CALL_CONV dynrec_ror_dword(Bit32u op1,Bit8u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_ror_dword(Bit32u op1,Bit8u op2) { if (!op2) return op1; FillFlags(); @@ -914,11 +1016,13 @@ static Bit32u DRC_CALL_CONV dynrec_ror_dword(Bit32u op1,Bit8u op2) { return lf_resd; } +static Bit32u DRC_CALL_CONV dynrec_ror_dword_simple(Bit32u op1,Bit8u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_ror_dword_simple(Bit32u op1,Bit8u op2) { if (!op2) return op1; return (op1 >> op2) | (op1 << (32-op2)); } +static Bit32u DRC_CALL_CONV dynrec_rcl_dword(Bit32u op1,Bit8u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_rcl_dword(Bit32u op1,Bit8u op2) { if (!op2) return op1; Bit32u cf=(Bit32u)FillFlags()&0x1; @@ -934,6 +1038,7 @@ static Bit32u DRC_CALL_CONV dynrec_rcl_dword(Bit32u op1,Bit8u op2) { return lf_resd; } +static Bit32u DRC_CALL_CONV dynrec_rcr_dword(Bit32u op1,Bit8u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_rcr_dword(Bit32u op1,Bit8u op2) { if (op2) { Bit32u cf=(Bit32u)FillFlags()&0x1; @@ -950,6 +1055,7 @@ static Bit32u DRC_CALL_CONV dynrec_rcr_dword(Bit32u op1,Bit8u op2) { } else return op1; } +static Bit32u DRC_CALL_CONV dynrec_shl_dword(Bit32u op1,Bit8u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_shl_dword(Bit32u op1,Bit8u op2) { if (!op2) return op1; lf_var1d=op1; @@ -959,11 +1065,13 @@ static Bit32u DRC_CALL_CONV dynrec_shl_dword(Bit32u op1,Bit8u op2) { return lf_resd; } +static Bit32u DRC_CALL_CONV dynrec_shl_dword_simple(Bit32u op1,Bit8u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_shl_dword_simple(Bit32u op1,Bit8u op2) { if (!op2) return op1; return op1 << op2; } +static Bit32u DRC_CALL_CONV dynrec_shr_dword(Bit32u op1,Bit8u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_shr_dword(Bit32u op1,Bit8u op2) { if (!op2) return op1; lf_var1d=op1; @@ -973,11 +1081,13 @@ static Bit32u DRC_CALL_CONV dynrec_shr_dword(Bit32u op1,Bit8u op2) { return lf_resd; } +static Bit32u DRC_CALL_CONV dynrec_shr_dword_simple(Bit32u op1,Bit8u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_shr_dword_simple(Bit32u op1,Bit8u op2) { if (!op2) return op1; return op1 >> op2; } +static Bit32u DRC_CALL_CONV dynrec_sar_dword(Bit32u op1,Bit8u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_sar_dword(Bit32u op1,Bit8u op2) { if (!op2) return op1; lf_var2b=op2; @@ -991,6 +1101,7 @@ static Bit32u DRC_CALL_CONV dynrec_sar_dword(Bit32u op1,Bit8u op2) { return lf_resd; } +static Bit32u DRC_CALL_CONV dynrec_sar_dword_simple(Bit32u op1,Bit8u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_sar_dword_simple(Bit32u op1,Bit8u op2) { if (!op2) return op1; if (op1 & 0x80000000) return (op1 >> op2) | (0xffffffff << (32 - op2)); @@ -1102,6 +1213,7 @@ static void dyn_shift_word_gencall(ShiftOps op,bool dword) { } } +static Bit16u DRC_CALL_CONV dynrec_dshl_word(Bit16u op1,Bit16u op2,Bit8u op3) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_dshl_word(Bit16u op1,Bit16u op2,Bit8u op3) { Bit8u val=op3 & 0x1f; if (!val) return op1; @@ -1114,6 +1226,7 @@ static Bit16u DRC_CALL_CONV dynrec_dshl_word(Bit16u op1,Bit16u op2,Bit8u op3) { return lf_resw; } +static Bit16u DRC_CALL_CONV dynrec_dshl_word_simple(Bit16u op1,Bit16u op2,Bit8u op3) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_dshl_word_simple(Bit16u op1,Bit16u op2,Bit8u op3) { Bit8u val=op3 & 0x1f; if (!val) return op1; @@ -1122,6 +1235,7 @@ static Bit16u DRC_CALL_CONV dynrec_dshl_word_simple(Bit16u op1,Bit16u op2,Bit8u return (Bit16u)(tempd >> 16); } +static Bit32u DRC_CALL_CONV dynrec_dshl_dword(Bit32u op1,Bit32u op2,Bit8u op3) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_dshl_dword(Bit32u op1,Bit32u op2,Bit8u op3) { Bit8u val=op3 & 0x1f; if (!val) return op1; @@ -1132,12 +1246,14 @@ static Bit32u DRC_CALL_CONV dynrec_dshl_dword(Bit32u op1,Bit32u op2,Bit8u op3) { return lf_resd; } +static Bit32u DRC_CALL_CONV dynrec_dshl_dword_simple(Bit32u op1,Bit32u op2,Bit8u op3) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_dshl_dword_simple(Bit32u op1,Bit32u op2,Bit8u op3) { Bit8u val=op3 & 0x1f; if (!val) return op1; return (op1 << val) | (op2 >> (32-val)); } +static Bit16u DRC_CALL_CONV dynrec_dshr_word(Bit16u op1,Bit16u op2,Bit8u op3) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_dshr_word(Bit16u op1,Bit16u op2,Bit8u op3) { Bit8u val=op3 & 0x1f; if (!val) return op1; @@ -1150,6 +1266,7 @@ static Bit16u DRC_CALL_CONV dynrec_dshr_word(Bit16u op1,Bit16u op2,Bit8u op3) { return lf_resw; } +static Bit16u DRC_CALL_CONV dynrec_dshr_word_simple(Bit16u op1,Bit16u op2,Bit8u op3) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_dshr_word_simple(Bit16u op1,Bit16u op2,Bit8u op3) { Bit8u val=op3 & 0x1f; if (!val) return op1; @@ -1158,6 +1275,7 @@ static Bit16u DRC_CALL_CONV dynrec_dshr_word_simple(Bit16u op1,Bit16u op2,Bit8u return (Bit16u)(tempd); } +static Bit32u DRC_CALL_CONV dynrec_dshr_dword(Bit32u op1,Bit32u op2,Bit8u op3) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_dshr_dword(Bit32u op1,Bit32u op2,Bit8u op3) { Bit8u val=op3 & 0x1f; if (!val) return op1; @@ -1168,6 +1286,7 @@ static Bit32u DRC_CALL_CONV dynrec_dshr_dword(Bit32u op1,Bit32u op2,Bit8u op3) { return lf_resd; } +static Bit32u DRC_CALL_CONV dynrec_dshr_dword_simple(Bit32u op1,Bit32u op2,Bit8u op3) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_dshr_dword_simple(Bit32u op1,Bit32u op2,Bit8u op3) { Bit8u val=op3 & 0x1f; if (!val) return op1; @@ -1196,22 +1315,38 @@ static void dyn_dpshift_dword_gencall(bool left) { +static Bit32u DRC_CALL_CONV dynrec_get_of(void) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_get_of(void) { return TFLG_O; } +static Bit32u DRC_CALL_CONV dynrec_get_nof(void) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_get_nof(void) { return TFLG_NO; } +static Bit32u DRC_CALL_CONV dynrec_get_cf(void) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_get_cf(void) { return TFLG_B; } +static Bit32u DRC_CALL_CONV dynrec_get_ncf(void) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_get_ncf(void) { return TFLG_NB; } +static Bit32u DRC_CALL_CONV dynrec_get_zf(void) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_get_zf(void) { return TFLG_Z; } +static Bit32u DRC_CALL_CONV dynrec_get_nzf(void) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_get_nzf(void) { return TFLG_NZ; } +static Bit32u DRC_CALL_CONV dynrec_get_sf(void) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_get_sf(void) { return TFLG_S; } +static Bit32u DRC_CALL_CONV dynrec_get_nsf(void) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_get_nsf(void) { return TFLG_NS; } +static Bit32u DRC_CALL_CONV dynrec_get_pf(void) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_get_pf(void) { return TFLG_P; } +static Bit32u DRC_CALL_CONV dynrec_get_npf(void) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_get_npf(void) { return TFLG_NP; } +static Bit32u DRC_CALL_CONV dynrec_get_cf_or_zf(void) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_get_cf_or_zf(void) { return TFLG_BE; } +static Bit32u DRC_CALL_CONV dynrec_get_ncf_and_nzf(void) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_get_ncf_and_nzf(void) { return TFLG_NBE; } +static Bit32u DRC_CALL_CONV dynrec_get_sf_neq_of(void) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_get_sf_neq_of(void) { return TFLG_L; } +static Bit32u DRC_CALL_CONV dynrec_get_sf_eq_of(void) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_get_sf_eq_of(void) { return TFLG_NL; } +static Bit32u DRC_CALL_CONV dynrec_get_zf_or_sf_neq_of(void) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_get_zf_or_sf_neq_of(void) { return TFLG_LE; } +static Bit32u DRC_CALL_CONV dynrec_get_nzf_and_sf_eq_of(void) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_get_nzf_and_sf_eq_of(void) { return TFLG_NLE; } @@ -1238,6 +1373,7 @@ static void dyn_branchflag_to_reg(BranchTypes btype) { } +static void DRC_CALL_CONV dynrec_mul_byte(Bit8u op) DRC_FC; static void DRC_CALL_CONV dynrec_mul_byte(Bit8u op) { FillFlags(); reg_ax=reg_al*op; @@ -1251,6 +1387,7 @@ static void DRC_CALL_CONV dynrec_mul_byte(Bit8u op) { } } +static void DRC_CALL_CONV dynrec_imul_byte(Bit8u op) DRC_FC; static void DRC_CALL_CONV dynrec_imul_byte(Bit8u op) { FillFlags(); reg_ax=((Bit8s)reg_al) * ((Bit8s)op); @@ -1263,6 +1400,7 @@ static void DRC_CALL_CONV dynrec_imul_byte(Bit8u op) { } } +static void DRC_CALL_CONV dynrec_mul_word(Bit16u op) DRC_FC; static void DRC_CALL_CONV dynrec_mul_word(Bit16u op) { FillFlags(); Bitu tempu=(Bitu)reg_ax*(Bitu)op; @@ -1278,6 +1416,7 @@ static void DRC_CALL_CONV dynrec_mul_word(Bit16u op) { } } +static void DRC_CALL_CONV dynrec_imul_word(Bit16u op) DRC_FC; static void DRC_CALL_CONV dynrec_imul_word(Bit16u op) { FillFlags(); Bits temps=((Bit16s)reg_ax)*((Bit16s)op); @@ -1292,6 +1431,7 @@ static void DRC_CALL_CONV dynrec_imul_word(Bit16u op) { } } +static void DRC_CALL_CONV dynrec_mul_dword(Bit32u op) DRC_FC; static void DRC_CALL_CONV dynrec_mul_dword(Bit32u op) { FillFlags(); Bit64u tempu=(Bit64u)reg_eax*(Bit64u)op; @@ -1307,6 +1447,7 @@ static void DRC_CALL_CONV dynrec_mul_dword(Bit32u op) { } } +static void DRC_CALL_CONV dynrec_imul_dword(Bit32u op) DRC_FC; static void DRC_CALL_CONV dynrec_imul_dword(Bit32u op) { FillFlags(); Bit64s temps=((Bit64s)((Bit32s)reg_eax))*((Bit64s)((Bit32s)op)); @@ -1325,6 +1466,7 @@ static void DRC_CALL_CONV dynrec_imul_dword(Bit32u op) { } +static bool DRC_CALL_CONV dynrec_div_byte(Bit8u op) DRC_FC; static bool DRC_CALL_CONV dynrec_div_byte(Bit8u op) { Bitu val=op; if (val==0) return CPU_PrepareException(0,0); @@ -1337,6 +1479,7 @@ static bool DRC_CALL_CONV dynrec_div_byte(Bit8u op) { return false; } +static bool DRC_CALL_CONV dynrec_idiv_byte(Bit8u op) DRC_FC; static bool DRC_CALL_CONV dynrec_idiv_byte(Bit8u op) { Bits val=(Bit8s)op; if (val==0) return CPU_PrepareException(0,0); @@ -1349,6 +1492,7 @@ static bool DRC_CALL_CONV dynrec_idiv_byte(Bit8u op) { return false; } +static bool DRC_CALL_CONV dynrec_div_word(Bit16u op) DRC_FC; static bool DRC_CALL_CONV dynrec_div_word(Bit16u op) { Bitu val=op; if (val==0) return CPU_PrepareException(0,0); @@ -1362,6 +1506,7 @@ static bool DRC_CALL_CONV dynrec_div_word(Bit16u op) { return false; } +static bool DRC_CALL_CONV dynrec_idiv_word(Bit16u op) DRC_FC; static bool DRC_CALL_CONV dynrec_idiv_word(Bit16u op) { Bits val=(Bit16s)op; if (val==0) return CPU_PrepareException(0,0); @@ -1375,6 +1520,7 @@ static bool DRC_CALL_CONV dynrec_idiv_word(Bit16u op) { return false; } +static bool DRC_CALL_CONV dynrec_div_dword(Bit32u op) DRC_FC; static bool DRC_CALL_CONV dynrec_div_dword(Bit32u op) { Bitu val=op; if (val==0) return CPU_PrepareException(0,0); @@ -1388,6 +1534,7 @@ static bool DRC_CALL_CONV dynrec_div_dword(Bit32u op) { return false; } +static bool DRC_CALL_CONV dynrec_idiv_dword(Bit32u op) DRC_FC; static bool DRC_CALL_CONV dynrec_idiv_dword(Bit32u op) { Bits val=(Bit32s)op; if (val==0) return CPU_PrepareException(0,0); @@ -1402,6 +1549,7 @@ static bool DRC_CALL_CONV dynrec_idiv_dword(Bit32u op) { } +static Bit16u DRC_CALL_CONV dynrec_dimul_word(Bit16u op1,Bit16u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_dimul_word(Bit16u op1,Bit16u op2) { FillFlags(); Bits res=((Bit16s)op1) * ((Bit16s)op2); @@ -1415,6 +1563,7 @@ static Bit16u DRC_CALL_CONV dynrec_dimul_word(Bit16u op1,Bit16u op2) { return (Bit16u)(res & 0xffff); } +static Bit32u DRC_CALL_CONV dynrec_dimul_dword(Bit32u op1,Bit32u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_dimul_dword(Bit32u op1,Bit32u op2) { FillFlags(); Bit64s res=((Bit64s)((Bit32s)op1))*((Bit64s)((Bit32s)op2)); @@ -1430,25 +1579,30 @@ static Bit32u DRC_CALL_CONV dynrec_dimul_dword(Bit32u op1,Bit32u op2) { +static Bit16u DRC_CALL_CONV dynrec_cbw(Bit8u op) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_cbw(Bit8u op) { return (Bit8s)op; } +static Bit32u DRC_CALL_CONV dynrec_cwde(Bit16u op) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_cwde(Bit16u op) { return (Bit16s)op; } +static Bit16u DRC_CALL_CONV dynrec_cwd(Bit16u op) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_cwd(Bit16u op) { if (op & 0x8000) return 0xffff; else return 0; } +static Bit32u DRC_CALL_CONV dynrec_cdq(Bit32u op) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_cdq(Bit32u op) { if (op & 0x80000000) return 0xffffffff; else return 0; } +static void DRC_CALL_CONV dynrec_sahf(Bit16u op) DRC_FC; static void DRC_CALL_CONV dynrec_sahf(Bit16u op) { SETFLAGBIT(OF,get_OF()); lflags.type=t_UNKNOWN; @@ -1456,28 +1610,34 @@ static void DRC_CALL_CONV dynrec_sahf(Bit16u op) { } +static void DRC_CALL_CONV dynrec_cmc(void) DRC_FC; static void DRC_CALL_CONV dynrec_cmc(void) { FillFlags(); SETFLAGBIT(CF,!(reg_flags & FLAG_CF)); } +static void DRC_CALL_CONV dynrec_clc(void) DRC_FC; static void DRC_CALL_CONV dynrec_clc(void) { FillFlags(); SETFLAGBIT(CF,false); } +static void DRC_CALL_CONV dynrec_stc(void) DRC_FC; static void DRC_CALL_CONV dynrec_stc(void) { FillFlags(); SETFLAGBIT(CF,true); } +static void DRC_CALL_CONV dynrec_cld(void) DRC_FC; static void DRC_CALL_CONV dynrec_cld(void) { SETFLAGBIT(DF,false); cpu.direction=1; } +static void DRC_CALL_CONV dynrec_std(void) DRC_FC; static void DRC_CALL_CONV dynrec_std(void) { SETFLAGBIT(DF,true); cpu.direction=-1; } +static Bit16u DRC_CALL_CONV dynrec_movsb_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_movsb_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) { Bit16u count_left; if (count<(Bitu)CPU_Cycles) { @@ -1495,6 +1655,7 @@ static Bit16u DRC_CALL_CONV dynrec_movsb_word(Bit16u count,Bit16s add_index,Phys return count_left; } +static Bit32u DRC_CALL_CONV dynrec_movsb_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_movsb_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) { Bit32u count_left; if (count<(Bitu)CPU_Cycles) { @@ -1512,6 +1673,7 @@ static Bit32u DRC_CALL_CONV dynrec_movsb_dword(Bit32u count,Bit32s add_index,Phy return count_left; } +static Bit16u DRC_CALL_CONV dynrec_movsw_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_movsw_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) { Bit16u count_left; if (count<(Bitu)CPU_Cycles) { @@ -1530,6 +1692,7 @@ static Bit16u DRC_CALL_CONV dynrec_movsw_word(Bit16u count,Bit16s add_index,Phys return count_left; } +static Bit32u DRC_CALL_CONV dynrec_movsw_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_movsw_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) { Bit32u count_left; if (count<(Bitu)CPU_Cycles) { @@ -1548,6 +1711,7 @@ static Bit32u DRC_CALL_CONV dynrec_movsw_dword(Bit32u count,Bit32s add_index,Phy return count_left; } +static Bit16u DRC_CALL_CONV dynrec_movsd_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_movsd_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) { Bit16u count_left; if (count<(Bitu)CPU_Cycles) { @@ -1566,6 +1730,7 @@ static Bit16u DRC_CALL_CONV dynrec_movsd_word(Bit16u count,Bit16s add_index,Phys return count_left; } +static Bit32u DRC_CALL_CONV dynrec_movsd_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_movsd_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) { Bit32u count_left; if (count<(Bitu)CPU_Cycles) { @@ -1585,6 +1750,7 @@ static Bit32u DRC_CALL_CONV dynrec_movsd_dword(Bit32u count,Bit32s add_index,Phy } +static Bit16u DRC_CALL_CONV dynrec_lodsb_word(Bit16u count,Bit16s add_index,PhysPt si_base) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_lodsb_word(Bit16u count,Bit16s add_index,PhysPt si_base) { Bit16u count_left; if (count<(Bitu)CPU_Cycles) { @@ -1601,6 +1767,7 @@ static Bit16u DRC_CALL_CONV dynrec_lodsb_word(Bit16u count,Bit16s add_index,Phys return count_left; } +static Bit32u DRC_CALL_CONV dynrec_lodsb_dword(Bit32u count,Bit32s add_index,PhysPt si_base) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_lodsb_dword(Bit32u count,Bit32s add_index,PhysPt si_base) { Bit32u count_left; if (count<(Bitu)CPU_Cycles) { @@ -1617,6 +1784,7 @@ static Bit32u DRC_CALL_CONV dynrec_lodsb_dword(Bit32u count,Bit32s add_index,Phy return count_left; } +static Bit16u DRC_CALL_CONV dynrec_lodsw_word(Bit16u count,Bit16s add_index,PhysPt si_base) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_lodsw_word(Bit16u count,Bit16s add_index,PhysPt si_base) { Bit16u count_left; if (count<(Bitu)CPU_Cycles) { @@ -1634,6 +1802,7 @@ static Bit16u DRC_CALL_CONV dynrec_lodsw_word(Bit16u count,Bit16s add_index,Phys return count_left; } +static Bit32u DRC_CALL_CONV dynrec_lodsw_dword(Bit32u count,Bit32s add_index,PhysPt si_base) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_lodsw_dword(Bit32u count,Bit32s add_index,PhysPt si_base) { Bit32u count_left; if (count<(Bitu)CPU_Cycles) { @@ -1651,6 +1820,7 @@ static Bit32u DRC_CALL_CONV dynrec_lodsw_dword(Bit32u count,Bit32s add_index,Phy return count_left; } +static Bit16u DRC_CALL_CONV dynrec_lodsd_word(Bit16u count,Bit16s add_index,PhysPt si_base) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_lodsd_word(Bit16u count,Bit16s add_index,PhysPt si_base) { Bit16u count_left; if (count<(Bitu)CPU_Cycles) { @@ -1668,6 +1838,7 @@ static Bit16u DRC_CALL_CONV dynrec_lodsd_word(Bit16u count,Bit16s add_index,Phys return count_left; } +static Bit32u DRC_CALL_CONV dynrec_lodsd_dword(Bit32u count,Bit32s add_index,PhysPt si_base) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_lodsd_dword(Bit32u count,Bit32s add_index,PhysPt si_base) { Bit32u count_left; if (count<(Bitu)CPU_Cycles) { @@ -1686,6 +1857,7 @@ static Bit32u DRC_CALL_CONV dynrec_lodsd_dword(Bit32u count,Bit32s add_index,Phy } +static Bit16u DRC_CALL_CONV dynrec_stosb_word(Bit16u count,Bit16s add_index,PhysPt di_base) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_stosb_word(Bit16u count,Bit16s add_index,PhysPt di_base) { Bit16u count_left; if (count<(Bitu)CPU_Cycles) { @@ -1702,6 +1874,7 @@ static Bit16u DRC_CALL_CONV dynrec_stosb_word(Bit16u count,Bit16s add_index,Phys return count_left; } +static Bit32u DRC_CALL_CONV dynrec_stosb_dword(Bit32u count,Bit32s add_index,PhysPt di_base) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_stosb_dword(Bit32u count,Bit32s add_index,PhysPt di_base) { Bit32u count_left; if (count<(Bitu)CPU_Cycles) { @@ -1718,6 +1891,7 @@ static Bit32u DRC_CALL_CONV dynrec_stosb_dword(Bit32u count,Bit32s add_index,Phy return count_left; } +static Bit16u DRC_CALL_CONV dynrec_stosw_word(Bit16u count,Bit16s add_index,PhysPt di_base) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_stosw_word(Bit16u count,Bit16s add_index,PhysPt di_base) { Bit16u count_left; if (count<(Bitu)CPU_Cycles) { @@ -1735,6 +1909,7 @@ static Bit16u DRC_CALL_CONV dynrec_stosw_word(Bit16u count,Bit16s add_index,Phys return count_left; } +static Bit32u DRC_CALL_CONV dynrec_stosw_dword(Bit32u count,Bit32s add_index,PhysPt di_base) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_stosw_dword(Bit32u count,Bit32s add_index,PhysPt di_base) { Bit32u count_left; if (count<(Bitu)CPU_Cycles) { @@ -1752,6 +1927,7 @@ static Bit32u DRC_CALL_CONV dynrec_stosw_dword(Bit32u count,Bit32s add_index,Phy return count_left; } +static Bit16u DRC_CALL_CONV dynrec_stosd_word(Bit16u count,Bit16s add_index,PhysPt di_base) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_stosd_word(Bit16u count,Bit16s add_index,PhysPt di_base) { Bit16u count_left; if (count<(Bitu)CPU_Cycles) { @@ -1769,6 +1945,7 @@ static Bit16u DRC_CALL_CONV dynrec_stosd_word(Bit16u count,Bit16s add_index,Phys return count_left; } +static Bit32u DRC_CALL_CONV dynrec_stosd_dword(Bit32u count,Bit32s add_index,PhysPt di_base) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_stosd_dword(Bit32u count,Bit32s add_index,PhysPt di_base) { Bit32u count_left; if (count<(Bitu)CPU_Cycles) { @@ -1787,24 +1964,28 @@ static Bit32u DRC_CALL_CONV dynrec_stosd_dword(Bit32u count,Bit32s add_index,Phy } +static void DRC_CALL_CONV dynrec_push_word(Bit16u value) DRC_FC; static void DRC_CALL_CONV dynrec_push_word(Bit16u value) { Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-2)&cpu.stack.mask); mem_writew(SegPhys(ss) + (new_esp & cpu.stack.mask),value); reg_esp=new_esp; } +static void DRC_CALL_CONV dynrec_push_dword(Bit32u value) DRC_FC; static void DRC_CALL_CONV dynrec_push_dword(Bit32u value) { Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-4)&cpu.stack.mask); mem_writed(SegPhys(ss) + (new_esp & cpu.stack.mask) ,value); reg_esp=new_esp; } +static Bit16u DRC_CALL_CONV dynrec_pop_word(void) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_pop_word(void) { Bit16u val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+2)&cpu.stack.mask); return val; } +static Bit32u DRC_CALL_CONV dynrec_pop_dword(void) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_pop_dword(void) { Bit32u val=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask)); reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+4)&cpu.stack.mask); diff --git a/src/cpu/core_dynrec/risc_x86.h b/src/cpu/core_dynrec/risc_x86.h index 00b0e432..dc47aca3 100644 --- a/src/cpu/core_dynrec/risc_x86.h +++ b/src/cpu/core_dynrec/risc_x86.h @@ -27,7 +27,13 @@ #define DRC_PTR_SIZE_IM Bit32u // calling convention modifier +#if defined (WIN32) #define DRC_CALL_CONV _fastcall +#define DRC_FC /* nothing */ +#else +#define DRC_CALL_CONV /* nothing */ +#define DRC_FC GCC_ATTRIBUTE(fastcall) +#endif // register mapping From b20606dee144ca98d72db29eb872684eda4e6f15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 4 Jun 2007 16:43:05 +0000 Subject: [PATCH 2785/4131] add calling convention modifier to all drc backends Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2871 --- src/cpu/core_dynrec/risc_x64.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index e75667e5..c18e31c9 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -27,7 +27,8 @@ #define DRC_PTR_SIZE_IM Bit64u // calling convention modifier -#define DRC_CALL_CONV +#define DRC_CALL_CONV /* nothing */ +#define DRC_FC /* nothing */ // register mapping From daea1f9a2959aa40ffce917b2e49360287dc53de Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 4 Jun 2007 17:59:18 +0000 Subject: [PATCH 2786/4131] So much for posix compliance ;) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2872 --- configure.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.in b/configure.in index bd6fa5d0..586776e3 100644 --- a/configure.in +++ b/configure.in @@ -52,7 +52,7 @@ AC_CHECK_SIZEOF(int *) dnl some semi complex check for sys/socket so it works on darwin as well AC_CHECK_HEADERS([stdlib.h sys/types.h]) -AC_CHECK_HEADERS([sys/socket.h netinet/in.h], [], [], +AC_CHECK_HEADERS([sys/socket.h netinet/in.h pwd.h], [], [], [#include #ifdef STDC_HEADERS # include @@ -221,7 +221,7 @@ AC_ARG_ENABLE(dynamic-core,AC_HELP_STRING([--disable-dynamic-core],[Disable all 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 || test x$enable_dynamic_core=xno; then +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 @@ -235,7 +235,7 @@ 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 || test x$enable_dynamic_core = xno; then +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. From def259b02edd6a9e335fc94ea787da67442abc87 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 4 Jun 2007 18:09:27 +0000 Subject: [PATCH 2787/4131] Add support for ~username to mount and imgmount. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2873 --- src/dos/dos_programs.cpp | 88 +++++++++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 29 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 28c90cca..a1176c0e 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,8 +16,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.72 2007-05-27 16:11:35 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.73 2007-06-04 18:09:27 qbix79 Exp $ */ +#include "dosbox.h" #include #include #include @@ -34,6 +35,12 @@ #include "dos_inc.h" #include "bios.h" +#if defined HAVE_SYS_TYPES_H && defined HAVE_PWD_H +#include +#include +#endif + + #if defined(OS2) #define INCL DOSFILEMGR #define INCL_DOSERRORS @@ -46,6 +53,24 @@ Bitu DEBUG_EnableDebugger(void); void MSCDEX_SetCDInterface(int intNr, int forceCD); +//Helper function for mount and imgmount to correctly find the path +static void ResolveHomedir(std::string & temp_line) { + if(!temp_line.size() || temp_line[0] != '~') return; //No ~ + + if(temp_line.size() == 1 || temp_line[1] == CROSS_FILESPLIT) { //The ~ and ~/ variant + char * home = getenv("HOME"); + if(home) temp_line.replace(0,1,std::string(home)); +#if defined HAVE_SYS_TYPES_H && defined HAVE_PWD_H + } else { // The ~username variant + std::string::size_type namelen = temp_line.find(CROSS_FILESPLIT); + if(namelen == std::string::npos) namelen = temp_line.size(); + std::string username = temp_line.substr(1,namelen - 1); + struct passwd* pass = getpwnam(username.c_str()); + if(pass) temp_line.replace(0,namelen,pass->pw_dir); //namelen -1 +1(for the ~) +#endif // USERNAME lookup code + } +} + class MOUNT : public Program { public: void Run(void) @@ -184,11 +209,9 @@ public: #else if (stat(temp_line.c_str(),&test)) { failed = true; - if(temp_line.size() && temp_line[0] == '~') { - char * home = getenv("HOME"); - if(home) temp_line.replace(0,1,std::string(home)); - if(!stat(temp_line.c_str(),&test)) failed = false; - } + ResolveHomedir(temp_line); + //Try again after resolving ~ + if(!stat(temp_line.c_str(),&test)) failed = false; } if(failed) { #endif @@ -954,29 +977,36 @@ public: struct stat test; if (stat(temp_line.c_str(),&test)) { - // convert dosbox filename to system filename - char fullname[CROSS_LEN]; - char tmp[CROSS_LEN]; - safe_strncpy(tmp, temp_line.c_str(), CROSS_LEN); - - Bit8u dummy; - if (!DOS_MakeName(tmp, fullname, &dummy) || strncmp(Drives[dummy]->GetInfo(),"local directory",15)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_NON_LOCAL_DRIVE")); - return; - } - - localDrive *ldp = (localDrive*)Drives[dummy]; - ldp->GetSystemFilename(tmp, fullname); - temp_line = tmp; - - if (stat(temp_line.c_str(),&test)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FILE_NOT_FOUND")); - return; - } - - if ((test.st_mode & S_IFDIR)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MOUNT")); - return; + //See if it works if the ~ are written out + std::string homedir(temp_line); + ResolveHomedir(homedir); + if(!stat(homedir.c_str(),&test)) { + temp_line = homedir; + } else { + // convert dosbox filename to system filename + char fullname[CROSS_LEN]; + char tmp[CROSS_LEN]; + safe_strncpy(tmp, temp_line.c_str(), CROSS_LEN); + + Bit8u dummy; + if (!DOS_MakeName(tmp, fullname, &dummy) || strncmp(Drives[dummy]->GetInfo(),"local directory",15)) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_NON_LOCAL_DRIVE")); + return; + } + + localDrive *ldp = (localDrive*)Drives[dummy]; + ldp->GetSystemFilename(tmp, fullname); + temp_line = tmp; + + if (stat(temp_line.c_str(),&test)) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FILE_NOT_FOUND")); + return; + } + + if ((test.st_mode & S_IFDIR)) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MOUNT")); + return; + } } } paths.push_back(temp_line); From 131553c47950259dcf2c0d1d41617f6fa91c6749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 6 Jun 2007 15:44:40 +0000 Subject: [PATCH 2788/4131] initialize private dos segment early; move int33 handler out of rom (Kippesoep) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2874 --- include/dos_inc.h | 5 ++++- src/dos/dos_tables.cpp | 7 +++---- src/ints/mouse.cpp | 6 +++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 04c91b72..14a594b3 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.65 2007-01-08 20:36:53 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.66 2007-06-06 15:44:40 c2woody Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -85,6 +85,9 @@ enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; #define DOS_SDA_OFS 0 #define DOS_MEM_START 0x102 //First Segment that DOS can use +#define DOS_PRIVATE_SEGMENT 0xc800 +#define DOS_PRIVATE_SEGMENT_END 0xd000 + /* internal Dos Tables */ extern DOS_File * Files[DOS_FILES]; diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 5962f524..e8a4b26e 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.26 2007-01-08 20:36:53 qbix79 Exp $ */ +/* $Id: dos_tables.cpp,v 1.27 2007-06-06 15:44:40 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -40,10 +40,10 @@ RealPt DOS_TableLowCase; static Bitu call_casemap; -static Bit16u dos_memseg; +static Bit16u dos_memseg=DOS_PRIVATE_SEGMENT; Bit16u DOS_GetMemory(Bit16u pages) { - if (pages+dos_memseg>=0xd000) { + if (pages+dos_memseg>=DOS_PRIVATE_SEGMENT_END) { E_Exit("DOS:Not enough memory for internal tables"); } Bit16u page=dos_memseg; @@ -73,7 +73,6 @@ static Bit8u country_info[0x22] = { }; void DOS_SetupTables(void) { - dos_memseg=0xc800; Bit16u seg,seg2;Bitu i; dos.tables.mediaid=RealMake(DOS_GetMemory(4),0); dos.tables.tempdta=RealMake(DOS_GetMemory(4),0); diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index b038727d..a0c8711b 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.67 2007-06-03 16:46:33 c2woody Exp $ */ +/* $Id: mouse.cpp,v 1.68 2007-06-06 15:44:40 c2woody Exp $ */ #include #include @@ -961,8 +961,8 @@ Bitu MOUSE_UserInt_CB_Handler(void) { void MOUSE_Init(Section* sec) { // Callback for mouse interrupt 0x33 call_int33=CALLBACK_Allocate(); - RealPt i33loc=RealMake(CB_SEG+1,(call_int33*CB_SIZE)-0x10); -// RealPt i33loc=RealMake(DOS_GetMemory(0x1)-1,0x10); // need another location +// RealPt i33loc=RealMake(CB_SEG+1,(call_int33*CB_SIZE)-0x10); + RealPt i33loc=RealMake(DOS_GetMemory(0x1)-1,0x10); CALLBACK_Setup(call_int33,&INT33_Handler,CB_MOUSE,Real2Phys(i33loc),"Mouse"); // Wasteland needs low(seg(int33))!=0 and low(ofs(int33))!=0 real_writed(0,0x33<<2,i33loc); From 7ca4e50bf8192799a32d7ee1b03e3b42372b0961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 7 Jun 2007 17:34:30 +0000 Subject: [PATCH 2789/4131] set int44 to first character(8) table for pcjr/tandy (personal deskmate 2) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2875 --- src/ints/int10_memory.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 7e8d74e1..2fd73d0e 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -113,6 +113,9 @@ void INT10_SetupRomMemory(void) { } RealSetVec(0x1F,int10.rom.font_8_second); + if (IS_TANDY_ARCH) { + RealSetVec(0x44,int10.rom.font_8_first); + } if (machine == MCH_VGA) { //EGA/VGA. Just to be safe //Reserve checksum location checksumlocation = int10.rom.used++; From 44fd176892add03f04c877e02f9cbaa65ac90cc2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 8 Jun 2007 08:21:45 +0000 Subject: [PATCH 2790/4131] Some patches by h-a-l-9000. Simple implementation of the gate of timer 2. Only switch to bcd when programming. Don't fire the same irq twice when reprogramming. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2876 --- src/hardware/keyboard.cpp | 10 ++++++--- src/hardware/timer.cpp | 46 ++++++++++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 8a828bb2..ab23ade3 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.37 2007-01-21 11:01:54 qbix79 Exp $ */ +/* $Id: keyboard.cpp,v 1.38 2007-06-08 08:21:45 qbix79 Exp $ */ #include "dosbox.h" #include "keyboard.h" @@ -179,9 +179,13 @@ static Bitu read_p61(Bitu port,Bitu iolen) { return port_61_data; } +extern void TIMER_SetGate2(bool); static void write_p61(Bitu port,Bitu val,Bitu iolen) { - if ((port_61_data ^ val) & 3) PCSPEAKER_SetType(val & 3); - port_61_data=val; + if ((port_61_data ^ val) & 3) { + if((port_61_data ^ val) & 1) TIMER_SetGate2(val&0x1); + PCSPEAKER_SetType(val & 3); + } + port_61_data = val; } static void write_p64(Bitu port,Bitu val,Bitu iolen) { diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 78256d8f..8075980a 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.42 2007-01-13 09:57:25 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.43 2007-06-08 08:21:45 qbix79 Exp $ */ #include #include "dosbox.h" @@ -57,6 +57,7 @@ struct PIT_Block { }; static PIT_Block pit[3]; +static bool gate2; static Bit8u latched_timerstatus; // the timer status can not be overwritten until it is read or the timer was @@ -124,6 +125,10 @@ static void counter_latch(Bitu counter) { /* Fill the read_latch of the selected counter with current count */ PIT_Block * p=&pit[counter]; p->go_read_latch=false; + + //If gate2 is disabled don't update the read_latch + if(counter == 2 && !gate2) return; + double index=PIC_FullIndex()-p->start; switch (p->mode) { case 4: /* Software Triggered Strobe */ @@ -197,6 +202,7 @@ static void write_latch(Bitu port,Bitu val,Bitu /*iolen*/) { switch (counter) { case 0x00: /* Timer hooked to IRQ 0 */ if (p->new_mode || p->mode == 0 ) { + if(p->mode==0) PIC_RemoveEvents(PIT0_Event); // DoWhackaDo demo PIC_AddEvent(PIT0_Event,p->delay); } else LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer set without new control word"); LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.2f Hz mode %d",1000.0/p->delay,p->mode); @@ -262,15 +268,15 @@ static void write_p43(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { case 0: case 1: case 2: - pit[latch].bcd = (val&1)>0; - if (val & 1) { - if(pit[latch].cntr>=9999) pit[latch].cntr=9999; - } - if ((val & 0x30) == 0) { /* Counter latch command */ counter_latch(latch); } else { + pit[latch].bcd = (val&1)>0; + if (val & 1) { + if(pit[latch].cntr>=9999) pit[latch].cntr=9999; + } + // Timer is being reprogrammed, unlock the status if(pit[latch].counterstatus_set) { pit[latch].counterstatus_set=false; @@ -326,6 +332,33 @@ static void write_p43(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { } } +void TIMER_SetGate2(bool in) { + //No changes if gate doesn't change + if(gate2 == in) return; + Bit8u & mode=pit[2].mode; + switch(mode) { + case 0: + if(in) pit[2].start = PIC_FullIndex(); + else { + //Fill readlatch and store it. + counter_latch(2); + pit[2].cntr = pit[2].read_latch; + } + break; + case 2: + case 3: + //If gate is enabled restart counting. If disable store the current read_latch + if(in) pit[2].start = PIC_FullIndex(); + else counter_latch(2); + break; + case 1: + case 4: + case 5: + LOG(LOG_MISC,LOG_WARN)("unsupported gate 2 mode %x",mode); + break; + } + gate2 = in; //Set it here so the counter_latch above works +} class TIMER:public Module_base{ private: @@ -374,6 +407,7 @@ public: pit[2].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[2].cntr)); latched_timerstatus_locked=false; + gate2 = true; PIC_AddEvent(PIT0_Event,pit[0].delay); } ~TIMER(){ From 9a36682b3a7ebae8ba1578b997968acb062bd8e0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 8 Jun 2007 08:26:37 +0000 Subject: [PATCH 2791/4131] patch by h-a-l-9000 to exclude the overscan area when dealing with the blanking period. makes the scanline count 400 instead of 415. Should improve scrolling. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2877 --- src/hardware/vga_misc.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 9306acf9..6ef43451 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -38,10 +38,9 @@ static Bitu vga_read_p3da(Bitu port,Bitu iolen) { vga.internal.attrindex=false; vga.tandy.pcjr_flipflop=false; - double timeInLine=fmod(timeInFrame,vga.draw.delay.htotal); - switch (machine) { case MCH_HERC: + { // 3BAh (R): Status Register // bit 0 Horizontal sync // 3 Video signal @@ -49,11 +48,13 @@ static Bitu vga_read_p3da(Bitu port,Bitu iolen) { if(timeInFrame >= vga.draw.delay.vrstart && timeInFrame <= vga.draw.delay.vrend) retval |= 0x80; + double timeInLine=fmod(timeInFrame,vga.draw.delay.htotal); if(timeInLine >= vga.draw.delay.hrstart && timeInLine <= vga.draw.delay.hrend) retval |= 1; retval |= 0x10; //Hercules ident break; + } default: // 3DAh (R): Status Register // bit 0 Horizontal or Vertical blanking @@ -62,12 +63,15 @@ static Bitu vga_read_p3da(Bitu port,Bitu iolen) { if(timeInFrame >= vga.draw.delay.vrstart && timeInFrame <= vga.draw.delay.vrend) retval |= 8; - if(timeInFrame >= vga.draw.delay.vblkstart && - timeInFrame <= vga.draw.delay.vblkend) - retval |= 1; - else if(timeInLine >= vga.draw.delay.hblkstart && - timeInLine <= vga.draw.delay.hblkend) + if(timeInFrame >= vga.draw.delay.vdend) retval |= 1; + else { + double timeInLine=fmod(timeInFrame,vga.draw.delay.htotal); + if(timeInLine >= (vga.draw.delay.hblkstart) && + timeInLine <= vga.draw.delay.hblkend){ + retval |= 1; + } + } } return retval; } From b6aff7b628e9ecf920e2cd6ae90196feb1c0158b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 9 Jun 2007 07:56:17 +0000 Subject: [PATCH 2792/4131] clean up gus a bit. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2878 --- src/hardware/gus.cpp | 59 ++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 35 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 0b53a857..33cd96f9 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -45,7 +45,7 @@ using namespace std; #define GUS_BASE myGUS.portbase #define GUS_RATE myGUS.rate -#define LOG_GUS +#define LOG_GUS 0 Bit8u adlib_commandreg; static MixerChannel * gus_chan; @@ -58,7 +58,6 @@ static Bit16u vol16bit[4096]; #endif static Bit32u pantable[16]; -static Bitu show_test=0; class GUSChannels; static void CheckVoiceIrq(void); @@ -239,26 +238,6 @@ public: double realadd = (frameadd*(double)myGUS.basefreq/(double)GUS_RATE) * (double)(1 << RAMP_FRACT); RampAdd = (Bit32u)realadd; } - void ShowWave(void) { - LOG_GUS("Wave %2d Ctrl %02x Current %d Start %d End %d Add %3.3f ", - channum, - ReadWaveCtrl(), - WaveAddr>>WAVE_FRACT, - WaveStart>>WAVE_FRACT, - WaveEnd>>WAVE_FRACT, - (float)WaveAdd/(float)(1 << WAVE_FRACT) - ); - } - void ShowRamp(void) { - LOG_GUS("Ramp %2d Ctrl %02X Current %d Start %d End %d Add %d", - channum, - ReadRampCtrl(), - RampVol >> RAMP_FRACT, - RampStart >> RAMP_FRACT, - RampEnd >> RAMP_FRACT, - RampAdd >> RAMP_FRACT - ); - } INLINE void WaveUpdate(void) { if (WaveCtrl & 0x3) return; Bit32s WaveLeft; @@ -334,12 +313,7 @@ public: bool eightbit; if (RampCtrl & WaveCtrl & 3) return; eightbit = ((WaveCtrl & 0x4) == 0); -#if 0 - if (!(show_test & 1023)) { - ShowWave(); - ShowRamp(); - } -#endif + for(i=0;i<(int)len;i++) { // Get sample tmpsamp = GetSample(WaveAdd, WaveAddr, eightbit); @@ -463,7 +437,9 @@ static Bit16u ExecuteReadRegister(void) { CheckVoiceIrq(); return (Bit16u)(tmpreg << 8); default: - LOG_GUS("Read Register num 0x%x", myGUS.gRegSelect); +#if LOG_GUS + LOG_MSG("Read Register num 0x%x", myGUS.gRegSelect); +#endif return myGUS.gRegData; } } @@ -564,7 +540,9 @@ static void ExecuteGlobRegister(void) { myGUS.ActiveMask=0xffffffffU >> (32-myGUS.ActiveChannels); gus_chan->Enable(true); myGUS.basefreq = (Bit32u)((float)1000000/(1.619695497*(float)(myGUS.ActiveChannels))); - LOG_GUS("GUS set to %d channels", myGUS.ActiveChannels); +#if LOG_GUS + LOG_MSG("GUS set to %d channels", myGUS.ActiveChannels); +#endif for (i=0;iUpdateWaveRamp(); break; case 0x10: // Undocumented register used in Fast Tracker 2 @@ -607,7 +585,10 @@ static void ExecuteGlobRegister(void) { GUSReset(); break; default: - LOG_GUS("Unimplemented global register %x -- %x", myGUS.gRegSelect, myGUS.gRegData); +#if LOG_GUS + LOG_MSG("Unimplemented global register %x -- %x", myGUS.gRegSelect, myGUS.gRegData); +#endif + break; } return; } @@ -645,7 +626,9 @@ static Bitu read_gus(Bitu port,Bitu iolen) { return 0; } default: - LOG_GUS("Read GUS at port 0x%x", port); +#if LOG_GUS + LOG_MSG("Read GUS at port 0x%x", port); +#endif break; } @@ -692,11 +675,15 @@ static void write_gus(Bitu port,Bitu val,Bitu iolen) { if (myGUS.mixControl & 0x40) { // IRQ configuration, only use low bits for irq 1 if (irqtable[val & 0x7]) myGUS.irq1=irqtable[val & 0x7]; - LOG_GUS("Assigned GUS to IRQ %d", myGUS.irq1); +#if LOG_GUS + LOG_MSG("Assigned GUS to IRQ %d", myGUS.irq1); +#endif } else { // DMA configuration, only use low bits for dma 1 if (dmatable[val & 0x7]) myGUS.dma1=dmatable[val & 0x7]; - LOG_GUS("Assigned GUS to DMA %d", myGUS.dma1); +#if LOG_GUS + LOG_MSG("Assigned GUS to DMA %d", myGUS.dma1); +#endif } break; case 0x302: @@ -721,7 +708,9 @@ static void write_gus(Bitu port,Bitu val,Bitu iolen) { if(myGUS.gDramAddr < sizeof(GUSRam)) GUSRam[myGUS.gDramAddr] = val; break; default: - LOG_GUS("Write GUS at port 0x%x with %x", port, val); +#if LOG_GUS + LOG_MSG("Write GUS at port 0x%x with %x", port, val); +#endif break; } } From 24eba30d2354ecbb4bbc7d0847de6716842e2477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 9 Jun 2007 17:57:28 +0000 Subject: [PATCH 2793/4131] enable full execution privileges for the dynamic core cache (windows DEP); raise generated data per block overflow buffer a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2879 --- src/cpu/core_dyn_x86.cpp | 7 ++++++- src/cpu/core_dyn_x86/cache.h | 11 ++++++++++- src/cpu/core_dynrec.cpp | 5 +++++ src/cpu/core_dynrec/cache.h | 9 +++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 50d78e8d..27aef301 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -27,6 +27,11 @@ #include #include +#if defined (_MSC_VER) +#include +#include +#endif + #if (C_HAVE_MPROTECT) #include @@ -45,7 +50,7 @@ #include "inout.h" #include "fpu.h" -#define CACHE_MAXSIZE (4096*2) +#define CACHE_MAXSIZE (4096*3) #define CACHE_TOTAL (1024*1024*8) #define CACHE_PAGES (512) #define CACHE_BLOCKS (64*1024) diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index a5f10b7b..8f51e880 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -457,8 +457,15 @@ static void cache_init(bool enable) { } } if (cache_code_start_ptr==NULL) { +#if defined (_MSC_VER) + 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); - if(!cache_code_start_ptr) E_Exit("Allocating dynamic cache failed"); +#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. @@ -510,6 +517,8 @@ static void cache_close(void) { 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; } diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index e73b8b2b..0cc2cbf6 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -27,6 +27,11 @@ #include #include +#if defined (_MSC_VER) +#include +#include +#endif + #if (C_HAVE_MPROTECT) #include diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index f0517150..6fdc537b 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -562,7 +562,14 @@ static void cache_init(bool enable) { } if (cache_code_start_ptr==NULL) { // allocate the code cache memory +#if defined (_MSC_VER) + 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 @@ -624,6 +631,8 @@ static void cache_close(void) { 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; } From a4d1439cce4de727f58e37dc173d1a47fb04a9c6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 12 Jun 2007 19:11:38 +0000 Subject: [PATCH 2794/4131] Add virtual destructor. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2880 --- src/dos/cdrom.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index 705f8429..c6dccc41 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -112,6 +112,7 @@ private: public: virtual bool read(Bit8u *buffer, int seek, int count) = 0; virtual int getLength() = 0; + virtual ~TrackFile() = 0; }; class BinaryFile : public TrackFile { From dd42270cf791487ebe4e496ea86a7eacfbbd97fa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 12 Jun 2007 19:17:43 +0000 Subject: [PATCH 2795/4131] less warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2881 --- src/hardware/memory.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 5eed6b96..fd93ff00 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: memory.cpp,v 1.48 2007-01-14 18:44:01 c2woody Exp $ */ +/* $Id: memory.cpp,v 1.49 2007-06-12 19:17:43 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -143,12 +143,12 @@ Bitu mem_strlen(PhysPt pt) { if (!mem_readb_inline(pt+x)) return x; x++; } - return 0; //Hope this doesn't happend + return 0; //Hope this doesn't happen } void mem_strcpy(PhysPt dest,PhysPt src) { Bit8u r; - while (r=mem_readb(src++)) mem_writeb_inline(dest++,r); + while ( (r = mem_readb(src++)) ) mem_writeb_inline(dest++,r); mem_writeb_inline(dest,0); } From 8c6d24bb619e09aa6cee1a2f78673f46fa0eb148 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 12 Jun 2007 19:32:34 +0000 Subject: [PATCH 2796/4131] making it an abc didn't work somehow. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2882 --- src/dos/cdrom.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index c6dccc41..08008336 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -112,7 +112,7 @@ private: public: virtual bool read(Bit8u *buffer, int seek, int count) = 0; virtual int getLength() = 0; - virtual ~TrackFile() = 0; + virtual ~TrackFile() { }; }; class BinaryFile : public TrackFile { From 0c24e87fdce50d636527d7db88d4484b09d3219d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 12 Jun 2007 20:22:09 +0000 Subject: [PATCH 2797/4131] silence some warnings, add most of sf patch #1185267 by Moe Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2883 --- include/callback.h | 6 +- include/dos_inc.h | 30 +++++----- include/fpu.h | 4 +- include/inout.h | 4 +- include/paging.h | 8 +-- include/regs.h | 2 +- src/cpu/core_dyn_x86/decoder.h | 7 +-- src/cpu/core_dyn_x86/dyn_fpu_dh.h | 4 +- src/cpu/core_dyn_x86/risc_x86.h | 4 +- src/cpu/cpu.cpp | 4 +- src/debug/debug.cpp | 14 ++--- src/dos/cdrom_aspi_win32.cpp | 4 +- src/dos/cdrom_image.cpp | 10 ++-- src/dos/dos.cpp | 6 +- src/dos/dos_classes.cpp | 4 +- src/dos/dos_files.cpp | 12 ++-- src/dos/dos_mscdex.cpp | 10 ++-- src/dos/dos_programs.cpp | 16 ++--- src/dos/dos_tables.cpp | 4 +- src/dos/drive_cache.cpp | 6 +- src/dos/drive_fat.cpp | 3 +- src/dos/drive_iso.cpp | 10 ++-- src/gui/sdlmain.cpp | 13 +++-- src/hardware/fmopl.c | 84 +++++++++++++-------------- src/hardware/iohandler.cpp | 10 ++-- src/hardware/keyboard.cpp | 3 +- src/hardware/mixer.cpp | 4 +- src/hardware/pic.cpp | 11 ++-- src/hardware/serialport/misc_util.cpp | 8 +-- src/hardware/timer.cpp | 4 +- src/hardware/vga.cpp | 3 +- src/hardware/vga_dac.cpp | 3 + src/hardware/vga_draw.cpp | 10 ++-- src/hardware/vga_memory.cpp | 2 + src/hardware/vga_misc.cpp | 1 - src/hardware/ymf262.c | 84 +++++++++++++-------------- src/ints/bios.cpp | 4 +- src/ints/bios_disk.cpp | 32 +++++----- src/ints/int10_char.cpp | 5 +- src/ints/int10_misc.cpp | 4 +- src/ints/int10_modes.cpp | 1 + src/ints/int10_pal.cpp | 4 +- src/ints/int10_put_pixel.cpp | 4 +- src/ints/int10_vesa.cpp | 4 +- src/ints/mouse.cpp | 12 ++-- src/ints/xms.cpp | 6 +- src/misc/programs.cpp | 11 ++-- src/misc/support.cpp | 3 +- src/shell/shell_cmds.cpp | 18 +++--- 49 files changed, 265 insertions(+), 255 deletions(-) diff --git a/include/callback.h b/include/callback.h index 72da8222..1bfc3526 100644 --- a/include/callback.h +++ b/include/callback.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.h,v 1.20 2007-06-03 16:46:33 c2woody Exp $ */ +/* $Id: callback.h,v 1.21 2007-06-12 20:22:07 c2woody Exp $ */ #ifndef DOSBOX_CALLBACK_H #define DOSBOX_CALLBACK_H @@ -43,10 +43,10 @@ enum { extern Bit8u lastint; INLINE RealPt CALLBACK_RealPointer(Bitu callback) { - return RealMake(CB_SEG,callback*CB_SIZE); + return RealMake(CB_SEG,(Bit16u)(callback*CB_SIZE)); } INLINE PhysPt CALLBACK_PhysPointer(Bitu callback) { - return PhysMake(CB_SEG,callback*CB_SIZE); + return PhysMake(CB_SEG,(Bit16u)(callback*CB_SIZE)); } INLINE PhysPt CALLBACK_GetBase(void) { diff --git a/include/dos_inc.h b/include/dos_inc.h index 14a594b3..3333e3a3 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.66 2007-06-06 15:44:40 c2woody Exp $ */ +/* $Id: dos_inc.h,v 1.67 2007-06-12 20:22:07 c2woody Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -260,9 +260,9 @@ public: } INLINE void SaveIt(Bitu size,PhysPt addr,Bitu val) { switch (size) { - case 1:mem_writeb(pt+addr,val);break; - case 2:mem_writew(pt+addr,val);break; - case 4:mem_writed(pt+addr,val);break; + case 1:mem_writeb(pt+addr,(Bit8u)val);break; + case 2:mem_writew(pt+addr,(Bit16u)val);break; + case 4:mem_writed(pt+addr,(Bit32u)val);break; } } INLINE void SetPt(Bit16u seg) { pt=PhysMake(seg,0);} @@ -283,14 +283,14 @@ public: void SaveVectors (void); void RestoreVectors (void); void SetSize (Bit16u size) { sSave(sPSP,next_seg,size); }; - Bit16u GetSize (void) { return sGet(sPSP,next_seg); }; + Bit16u GetSize (void) { return (Bit16u)sGet(sPSP,next_seg); }; void SetEnvironment (Bit16u envseg) { sSave(sPSP,environment,envseg); }; - Bit16u GetEnvironment (void) { return sGet(sPSP,environment); }; + 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 sGet(sPSP,psp_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); }; @@ -458,8 +458,8 @@ public: void SetDirID(Bit16u entry) { sSave(sDTA,dirID,entry); }; void SetDirIDCluster(Bit16u entry) { sSave(sDTA,dirCluster,entry); }; - Bit16u GetDirID(void) { return sGet(sDTA,dirID); }; - Bit16u GetDirIDCluster(void) { return sGet(sDTA,dirCluster); }; + Bit16u GetDirID(void) { return (Bit16u)sGet(sDTA,dirID); }; + Bit16u GetDirIDCluster(void) { return (Bit16u)sGet(sDTA,dirCluster); }; private: #ifdef _MSC_VER #pragma pack(1) @@ -540,9 +540,9 @@ public: void SetType(Bit8u _type) { sSave(sMCB,type,_type);} void SetSize(Bit16u _size) { sSave(sMCB,size,_size);} void SetPSPSeg(Bit16u _pspseg) { sSave(sMCB,psp_segment,_pspseg);} - Bit8u GetType(void) { return sGet(sMCB,type);} - Bit16u GetSize(void) { return sGet(sMCB,size);} - Bit16u GetPSPSeg(void) { return sGet(sMCB,psp_segment);} + 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) @@ -566,9 +566,9 @@ public: void SetDrive(Bit8u _drive) { sSave(sSDA,current_drive, _drive); } void SetDTA(Bit32u _dta) { sSave(sSDA,current_dta, _dta); } void SetPSP(Bit16u _psp) { sSave(sSDA,current_psp, _psp); } - Bit8u GetDrive(void) { return sGet(sSDA,current_drive); } - Bit16u GetPSP(void) { return sGet(sSDA,current_psp); } - Bit32u GetDTA(void) { return sGet(sSDA,current_dta); } + 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: diff --git a/include/fpu.h b/include/fpu.h index 50511eaf..2c071801 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -114,8 +114,8 @@ INLINE void FPU_SetTag(Bit16u tag){ } INLINE void FPU_SetCW(Bitu word){ - fpu.cw = word; - fpu.cw_mask_all = word | 0x3f; + fpu.cw = (Bit16u)word; + fpu.cw_mask_all = (Bit16u)(word | 0x3f); fpu.round = (FPU_Round)((word >> 10) & 3); } diff --git a/include/inout.h b/include/inout.h index db48d783..06987c51 100644 --- a/include/inout.h +++ b/include/inout.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: inout.h,v 1.10 2007-01-08 19:45:37 qbix79 Exp $ */ +/* $Id: inout.h,v 1.11 2007-06-12 20:22:07 c2woody Exp $ */ #ifndef DOSBOX_INOUT_H #define DOSBOX_INOUT_H @@ -72,7 +72,7 @@ INLINE void IO_Write(Bitu port,Bit8u val) { IO_WriteB(port,val); } INLINE Bit8u IO_Read(Bitu port){ - return IO_ReadB(port); + return (Bit8u)IO_ReadB(port); } #endif diff --git a/include/paging.h b/include/paging.h index 82ad4832..e0b53d69 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.24 2007-01-08 19:45:37 qbix79 Exp $ */ +/* $Id: paging.h,v 1.25 2007-06-12 20:22:07 c2woody Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H @@ -179,7 +179,7 @@ bool mem_unalignedwrited_checked_x86(PhysPt address,Bit32u val); INLINE Bit8u mem_readb_inline(PhysPt address) { Bitu index=(address>>12); if (paging.tlb.read[index]) return host_readb(paging.tlb.read[index]+address); - else return paging.tlb.handler[index]->readb(address); + else return (Bit8u)paging.tlb.handler[index]->readb(address); } INLINE Bit16u mem_readw_inline(PhysPt address) { @@ -187,7 +187,7 @@ INLINE Bit16u mem_readw_inline(PhysPt address) { Bitu index=(address>>12); if (paging.tlb.read[index]) return host_readw(paging.tlb.read[index]+address); - else return paging.tlb.handler[index]->readw(address); + else return (Bit16u) paging.tlb.handler[index]->readw(address); } else return mem_unalignedreadw(address); } @@ -231,7 +231,7 @@ INLINE Bit16u mem_readw_dyncorex86(PhysPt address) { Bitu index=(address>>12); if (paging.tlb.read[index]) return host_readw(paging.tlb.read[index]+address); - else return paging.tlb.handler[index]->readw(address); + else return (Bit16u)paging.tlb.handler[index]->readw(address); } else return mem_unalignedreadw(address); } diff --git a/include/regs.h b/include/regs.h index 636b676c..0f5a0c41 100644 --- a/include/regs.h +++ b/include/regs.h @@ -98,7 +98,7 @@ INLINE PhysPt SegPhys(SegNames index) { } INLINE Bit16u SegValue(SegNames index) { - return Segs.val[index]; + return (Bit16u)Segs.val[index]; } INLINE RealPt RealMakeSeg(SegNames index,Bit16u off) { diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 61f04308..c7418d32 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -145,7 +145,7 @@ static Bit32u decode_fetchd(void) { #define START_WMMEM 64 -static void INLINE decode_increase_wmapmask(Bitu size) { +static INLINE void decode_increase_wmapmask(Bitu size) { Bitu mapidx; CacheBlock* activecb=decode.active_block; if (GCC_UNLIKELY(!activecb->cache.wmapmask)) { @@ -927,7 +927,7 @@ static void dyn_pop(DynReg * dynreg,bool checked=true) { } } -static void INLINE dyn_get_modrm(void) { +static INLINE void dyn_get_modrm(void) { decode.modrm.val=decode_fetchb(); decode.modrm.mod=(decode.modrm.val >> 6) & 3; decode.modrm.reg=(decode.modrm.val >> 3) & 7; @@ -1187,7 +1187,7 @@ static void dyn_mov_ebgb(void) { DynReg * rm_reg=&DynRegs[decode.modrm.reg&3];Bitu rm_regi=decode.modrm.reg&4; if (decode.modrm.mod<3) { dyn_fill_ea(); - dyn_write_byte_release(DREG(EA),rm_reg,rm_regi); + dyn_write_byte_release(DREG(EA),rm_reg,rm_regi==4); } else { gen_dop_byte(DOP_MOV,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,rm_reg,rm_regi); } @@ -2594,7 +2594,6 @@ illegalopcode: dyn_closeblock(); goto finish_block; #if (C_DEBUG) -illegalopcodefull: dyn_set_eip_last(); dyn_reduce_cycles(); dyn_save_critical_regs(); diff --git a/src/cpu/core_dyn_x86/dyn_fpu_dh.h b/src/cpu/core_dyn_x86/dyn_fpu_dh.h index 267dbcd5..17af7d1f 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu_dh.h +++ b/src/cpu/core_dyn_x86/dyn_fpu_dh.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dyn_fpu_dh.h,v 1.2 2006-11-11 14:42:38 c2woody Exp $ */ +/* $Id: dyn_fpu_dh.h,v 1.3 2007-06-12 20:22:07 c2woody Exp $ */ #include "dosbox.h" #if C_FPU @@ -65,7 +65,7 @@ static void FPU_FLDCW_DH(PhysPt addr){ } static void FPU_FNSTCW_DH(PhysPt addr){ - mem_writew(addr,dyn_dh_fpu.cw); + mem_writew(addr,(Bit16u)(dyn_dh_fpu.cw&0xffff)); } static void FPU_FNINIT_DH(void){ diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index d5f15bf7..94b79c70 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -163,7 +163,7 @@ static GenReg * FindDynReg(DynReg * dynreg,bool stale=false) { genreg->Load(dynreg,stale); return genreg; } - if (genreg->last_usedlast_used<(Bitu)first_used) { first_used=genreg->last_used; first_index=i; } @@ -176,7 +176,7 @@ static GenReg * FindDynReg(DynReg * dynreg,bool stale=false) { genreg->Load(dynreg,stale); return genreg; } - if (genreg->last_usedlast_used<(Bitu)first_used) { first_used=genreg->last_used; first_index=i; } diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index ad9a8b11..fd4e6d61 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.101 2007-06-02 11:47:05 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.102 2007-06-12 20:22:07 c2woody Exp $ */ #include #include @@ -94,7 +94,7 @@ void CPU_Core_Dynrec_Cache_Close(void); #if defined(CPU_CHECK_IGNORE) #define CPU_CHECK_COND(cond,msg,exc,sel) { \ - cond; \ + if (cond) do {} while (0); \ } #elif defined(CPU_CHECK_EXCEPT) #define CPU_CHECK_COND(cond,msg,exc,sel) { \ diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 8a24e221..4bfec5db 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.87 2007-06-01 16:40:40 c2woody Exp $ */ +/* $Id: debug.cpp,v 1.88 2007-06-12 20:22:07 c2woody Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -2209,12 +2209,12 @@ void DEBUG_HeavyLogInstruction(void) { inst.s_fs = SegValue(fs); inst.s_gs = SegValue(gs); inst.s_ss = SegValue(ss); - inst.c = get_CF(); - inst.z = get_ZF(); - inst.s = get_SF(); - inst.o = get_OF(); - inst.a = get_AF(); - inst.p = get_PF(); + inst.c = get_CF()>0; + inst.z = get_ZF()>0; + inst.s = get_SF()>0; + inst.o = get_OF()>0; + inst.a = get_AF()>0; + inst.p = get_PF()>0; inst.i = GETFLAGBOOL(IF); if (++logCount >= LOGCPUMAX) logCount = 0; diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index 64c97f40..1da3ba23 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_aspi_win32.cpp,v 1.17 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: cdrom_aspi_win32.cpp,v 1.18 2007-06-12 20:22:07 c2woody Exp $ */ #if defined (WIN32) @@ -148,7 +148,6 @@ bool CDROM_Interface_Aspi::ScanRegistryFindKey(HKEY& hKeyBase) ULONG result,newKeyResult; char subKey[256]; char buffer[256]; - ULONG bufferSize = 256; ULONG subKeySize = 256; HKEY hNewKey; @@ -596,7 +595,6 @@ bool CDROM_Interface_Aspi::GetUPC(unsigned char& attr, char* upcdata) // attr = (upc.ADR<<4) | upc.Control; attr = 0; - int pos = 0; // Convert to mscdex format for (int i=0; i<7; i++) upcdata[i] = upc.MediaCatalog[i]; for (int i=0; i<7; i++) upcdata[i] = (upc.MediaCatalog[i*2] << 4) | (upc.MediaCatalog[i*2+1] & 0x0F); diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 7f6a6713..5cf0b764 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.15 2007-02-22 08:36:25 qbix79 Exp $ */ +/* $Id: cdrom_image.cpp,v 1.16 2007-06-12 20:22:08 c2woody Exp $ */ #include #include @@ -190,7 +190,7 @@ bool CDROM_Interface_Image::GetAudioTracks(int& stTrack, int& end, TMSF& leadOut bool CDROM_Interface_Image::GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr) { - if (track < 1 || track > tracks.size()) return false; + if (track < 1 || track > (int)tracks.size()) return false; FRAMES_TO_MSF(tracks[track - 1].start + 150, &start.min, &start.sec, &start.fr); attr = tracks[track - 1].attr; return true; @@ -254,7 +254,7 @@ bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long s Bit8u* buf = new Bit8u[buflen]; bool success = true; //Gobliiins reads 0 sectors - for(int i = 0; i < num; i++) { + for(unsigned long i = 0; i < num; i++) { success = ReadSector(&buf[i * sectorSize], raw, sector + i); if (!success) break; } @@ -308,7 +308,7 @@ void CDROM_Interface_Image::CDAudioCallBack(Bitu len) } SDL_mutexP(player.mutex); - while (player.bufLen < len) { + while (player.bufLen < (Bits)len) { bool success; if (player.targetFrame > player.currFrame) success = player.cd->ReadSector(&player.buffer[player.bufLen], true, player.currFrame); @@ -607,7 +607,7 @@ bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) bool CDROM_Interface_Image::GetCueKeyword(string &keyword, istream &in) { in >> keyword; - for(int i = 0; i < keyword.size(); i++) keyword[i] = toupper(keyword[i]); + for(Bitu i = 0; i < keyword.size(); i++) keyword[i] = toupper(keyword[i]); return true; } diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 5cc538ce..fbc8d81a 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.100 2007-04-16 12:23:23 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.101 2007-06-12 20:22:08 c2woody Exp $ */ #include #include @@ -45,11 +45,11 @@ void DOS_SetError(Bit16u code) { #define DATA_TRANSFERS_TAKE_CYCLES 1 #ifdef DATA_TRANSFERS_TAKE_CYCLES #include "cpu.h" -static inline void modify_cycles(Bitu value) { +static inline void modify_cycles(Bits value) { if((4*value+5) < CPU_Cycles) CPU_Cycles -= 4*value; else CPU_Cycles = 5; } #else -static inline void modify_cycles(Bitu /* value */) { +static inline void modify_cycles(Bits /* value */) { return; } #endif diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 1a35be3b..804998ee 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.50 2007-05-29 13:36:45 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.51 2007-06-12 20:22:08 c2woody Exp $ */ #include #include @@ -179,7 +179,7 @@ Bit16u DOS_PSP::rootpsp = 0; void DOS_PSP::MakeNew(Bit16u mem_size) { /* get previous */ - DOS_PSP prevpsp(dos.psp()); +// DOS_PSP prevpsp(dos.psp()); /* Clear it first */ Bitu i; for (i=0;i #include @@ -124,7 +124,7 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { Bit32s iDown, cDots; bool dots = true; - Bit32u templen =strlen(tempdir); + Bit32s templen=(Bit32s)strlen(tempdir); for(iDown=0;(iDown < templen) && dots;iDown++) if(tempdir[iDown] != '.') dots = false; @@ -133,7 +133,7 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { cDots = templen - 1; if(dots && (cDots > 0)) { - for(iDown=strlen(fullname)-1;iDown>=0;iDown--) + for(iDown=(Bit32s)strlen(fullname)-1;iDown>=0;iDown--) { if(fullname[iDown]=='\\' || iDown==0) { @@ -935,7 +935,8 @@ Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { */ DOS_FCB fcb(seg,offset); - Bit32u random;Bit16u old_block;Bit8u old_rec;Bit8u error; + Bit32u random;Bit16u old_block;Bit8u old_rec; + Bit8u error=0; /* Set the correct record from the random data */ fcb.GetRandom(random); @@ -957,7 +958,8 @@ Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { Bit8u DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { /* see FCB_RandomRead */ DOS_FCB fcb(seg,offset); - Bit32u random;Bit16u old_block;Bit8u old_rec;Bit8u error; + Bit32u random;Bit16u old_block;Bit8u old_rec; + Bit8u error=0; /* Set the correct record from the random data */ fcb.GetRandom(random); diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index cab04d47..e1cf3784 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.46 2007-04-15 11:39:33 c2woody Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.47 2007-06-12 20:22:08 c2woody Exp $ */ #include #include @@ -321,11 +321,11 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) //Link it in the device chain Bit32u start = dos_infoblock.GetDeviceChain(); - Bit16u segm = start>>16; - Bit16u offm = start&0xFFFF; + Bit16u segm = (Bit16u)(start>>16); + Bit16u offm = (Bit16u)(start&0xFFFF); while(start != 0xFFFFFFFF) { - segm = start>>16; - offm = start&0xFFFF; + segm = (Bit16u)(start>>16); + offm = (Bit16u)(start&0xFFFF); start = real_readd(segm,offm); } real_writed(segm,offm,seg<<16); diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index a1176c0e..61504b47 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.73 2007-06-04 18:09:27 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.74 2007-06-12 20:22:08 c2woody Exp $ */ #include "dosbox.h" #include @@ -1105,7 +1105,9 @@ public: MSCDEX_SetCDInterface(CDROM_USE_SDL, -1); // create new drives for all images std::vector isoDisks; - for (int i = 0; i < paths.size(); i++) { + std::vector::size_type i; + std::vector::size_type ct; + for (i = 0; i < paths.size(); i++) { int error = -1; DOS_Drive* newDrive = new isoDrive(drive, paths[i].c_str(), mediaid, error); isoDisks.push_back(newDrive); @@ -1121,15 +1123,15 @@ public: } // error: clean up and leave if (error) { - for(int i = 0; i < isoDisks.size(); i++) { - delete isoDisks[i]; + for(ct = 0; ct < isoDisks.size(); ct++) { + delete isoDisks[ct]; } return; } } // Update DriveManager - for(int i = 0; i < isoDisks.size(); i++) { - DriveManager::AppendDisk(drive - 'A', isoDisks[i]); + for(ct = 0; ct < isoDisks.size(); ct++) { + DriveManager::AppendDisk(drive - 'A', isoDisks[ct]); } DriveManager::InitializeDrive(drive - 'A'); @@ -1139,7 +1141,7 @@ public: // Print status message (success) WriteOut(MSG_Get("MSCDEX_SUCCESS")); std::string tmp(paths[0]); - for (int i = 1; i < paths.size(); i++) { + for (i = 1; i < paths.size(); i++) { tmp += "; " + paths[i]; } WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"), drive, tmp.c_str()); diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index e8a4b26e..3f2546ac 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.27 2007-06-06 15:44:40 c2woody Exp $ */ +/* $Id: dos_tables.cpp,v 1.28 2007-06-12 20:22:08 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -73,7 +73,7 @@ static Bit8u country_info[0x22] = { }; void DOS_SetupTables(void) { - Bit16u seg,seg2;Bitu i; + Bit16u seg;Bitu i; dos.tables.mediaid=RealMake(DOS_GetMemory(4),0); dos.tables.tempdta=RealMake(DOS_GetMemory(4),0); dos.tables.tempdta_fcbdelete=RealMake(DOS_GetMemory(4),0); diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index c0f22057..be28b824 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.49 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.50 2007-06-12 20:22:08 c2woody Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -242,7 +242,7 @@ void DOS_Drive_Cache::AddEntry(const char* path, bool checkExists) Bit32u i; // Check if there are any open search dir that are affected by this... if (dir) for (i=0; inextEntry)) + if ((dirSearch[i]==dir) && ((Bit32u)index<=dirSearch[i]->nextEntry)) dirSearch[i]->nextEntry++; } }; @@ -378,7 +378,7 @@ Bit16u DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name) do { foundNr = curDir->longNameList[mid]->shortNr; mid++; - } while(midlongNameList.size() && (CompareShortname(name,curDir->longNameList[mid]->shortname)==0)); + } while((Bitu)midlongNameList.size() && (CompareShortname(name,curDir->longNameList[mid]->shortname)==0)); break; }; } diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 4b532584..e21e7847 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.20 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: drive_fat.cpp,v 1.21 2007-06-12 20:22:08 c2woody Exp $ */ #include #include @@ -408,6 +408,7 @@ bool fatDrive::getFileDirEntry(char * filename, direntry * useEntry, Bit32u * di char * findDir; char * findFile; strcpy(dirtoken,filename); + findFile=dirtoken; /* Skip if testing in root directory */ if ((len>0) && (filename[len-1]!='\\')) { diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index dd5ec85b..dc1eec41 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.17 2007-01-21 16:21:22 c2woody Exp $ */ +/* $Id: drive_iso.cpp,v 1.18 2007-06-12 20:22:08 c2woody Exp $ */ #include #include @@ -65,11 +65,11 @@ isoFile::isoFile(isoDrive *drive, const char *name, FileStat_Block *stat, Bit32u bool isoFile::Read(Bit8u *data, Bit16u *size) { if (filePos + *size > fileEnd) - *size = fileEnd - filePos; + *size = (Bit16u)(fileEnd - filePos); Bit16u nowSize = 0; int sector = filePos / ISO_FRAMESIZE; - Bit16u sectorPos = filePos % ISO_FRAMESIZE; + Bit16u sectorPos = (Bit16u)(filePos % ISO_FRAMESIZE); if (sector != cachedSector) { if (drive->readSector(buffer, sector)) cachedSector = sector; @@ -272,7 +272,7 @@ bool isoDrive::FindFirst(char *dir, DOS_DTA &dta, bool fcb_findfirst) } // get a directory iterator and save its id in the dta - dta.SetDirID(GetDirIterator(&de)); + dta.SetDirID((Bit16u)GetDirIterator(&de)); Bit8u attr; char pattern[ISO_MAXPATHNAME]; @@ -532,7 +532,7 @@ bool isoDrive :: loadImage() isoPVD pvd; readSector((Bit8u*)(&pvd), ISO_FIRST_VD); if (pvd.type != 1 || strncmp((char*)pvd.standardIdent, "CD001", 5) || pvd.version != 1) return false; - return (readDirEntry(&this->rootEntry, pvd.rootEntry)); + return (readDirEntry(&this->rootEntry, pvd.rootEntry)>0); } bool isoDrive :: lookup(isoDirEntry *de, const char *path) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index f25f3805..d86ab4e3 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.130 2007-06-03 10:59:46 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.131 2007-06-12 20:22:08 c2woody Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -281,6 +281,7 @@ check_surface: else if (flags & GFX_LOVE_15) testbpp=15; else if (flags & GFX_LOVE_16) testbpp=16; else if (flags & GFX_LOVE_32) testbpp=32; + else testbpp=0; check_gotbpp: if (sdl.desktop.fullscreen) gotbpp=SDL_VideoModeOK(640,480,testbpp,SDL_FULLSCREEN|SDL_HWSURFACE|SDL_HWPALETTE); else gotbpp=sdl.desktop.bpp; @@ -398,7 +399,7 @@ Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,G sdl.draw.scalex=scalex; sdl.draw.scaley=scaley; - Bitu bpp; + Bitu bpp=0; Bitu retFlags = 0; if (sdl.blit.surface) { @@ -1146,7 +1147,11 @@ void Mouse_AutoLock(bool enable) { static void HandleMouseMotion(SDL_MouseMotionEvent * motion) { if (sdl.mouse.locked || !sdl.mouse.autoenable) - Mouse_CursorMoved((float)motion->xrel*sdl.mouse.sensitivity/100,(float)motion->yrel*sdl.mouse.sensitivity/100,(float)(motion->x-sdl.clip.x)/(sdl.clip.w-1)*sdl.mouse.sensitivity/100,(float)(motion->y-sdl.clip.y)/(sdl.clip.h-1)*sdl.mouse.sensitivity/100.0,sdl.mouse.locked); + Mouse_CursorMoved((float)motion->xrel*sdl.mouse.sensitivity/100.0f, + (float)motion->yrel*sdl.mouse.sensitivity/100.0f, + (float)(motion->x-sdl.clip.x)/(sdl.clip.w-1)*sdl.mouse.sensitivity/100.0f, + (float)(motion->y-sdl.clip.y)/(sdl.clip.h-1)*sdl.mouse.sensitivity/100.0f, + sdl.mouse.locked); } static void HandleMouseButton(SDL_MouseButtonEvent * button) { @@ -1196,7 +1201,7 @@ void GFX_Events() { SDL_Event event; #if defined (REDUCE_JOYSTICK_POLLING) static int poll_delay=0; - int time=SDL_GetTicks(); + int time=GetTicks(); if (time-poll_delay>20) { poll_delay=time; if (sdl.num_joysticks>0) SDL_JoystickUpdate(); diff --git a/src/hardware/fmopl.c b/src/hardware/fmopl.c index 94274475..9e1500a6 100644 --- a/src/hardware/fmopl.c +++ b/src/hardware/fmopl.c @@ -329,51 +329,51 @@ static const int slot_array[32]= /* key scale level */ /* table is 3dB/octave , DV converts this into 6dB/octave */ /* 0.1875 is bit 0 weight of the envelope counter (volume) expressed in the 'decibel' scale */ -#define DV (0.1875/2.0) +#define SC(x) ((UINT32)((x)/(0.1875/2.0))) static const UINT32 ksl_tab[8*16]= { /* OCT 0 */ - 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, - 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, - 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, - 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), /* OCT 1 */ - 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, - 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, - 0.000/DV, 0.750/DV, 1.125/DV, 1.500/DV, - 1.875/DV, 2.250/DV, 2.625/DV, 3.000/DV, + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.750), SC(1.125), SC(1.500), + SC(1.875), SC(2.250), SC(2.625), SC(3.000), /* OCT 2 */ - 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, - 0.000/DV, 1.125/DV, 1.875/DV, 2.625/DV, - 3.000/DV, 3.750/DV, 4.125/DV, 4.500/DV, - 4.875/DV, 5.250/DV, 5.625/DV, 6.000/DV, + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(1.125), SC(1.875), SC(2.625), + SC(3.000), SC(3.750), SC(4.125), SC(4.500), + SC(4.875), SC(5.250), SC(5.625), SC(6.000), /* OCT 3 */ - 0.000/DV, 0.000/DV, 0.000/DV, 1.875/DV, - 3.000/DV, 4.125/DV, 4.875/DV, 5.625/DV, - 6.000/DV, 6.750/DV, 7.125/DV, 7.500/DV, - 7.875/DV, 8.250/DV, 8.625/DV, 9.000/DV, + SC(0.000), SC(0.000), SC(0.000), SC(1.875), + SC(3.000), SC(4.125), SC(4.875), SC(5.625), + SC(6.000), SC(6.750), SC(7.125), SC(7.500), + SC(7.875), SC(8.250), SC(8.625), SC(9.000), /* OCT 4 */ - 0.000/DV, 0.000/DV, 3.000/DV, 4.875/DV, - 6.000/DV, 7.125/DV, 7.875/DV, 8.625/DV, - 9.000/DV, 9.750/DV,10.125/DV,10.500/DV, - 10.875/DV,11.250/DV,11.625/DV,12.000/DV, + SC(0.000), SC(0.000), SC(3.000), SC(4.875), + SC(6.000), SC(7.125), SC(7.875), SC(8.625), + SC(9.000), SC(9.750),SC(10.125),SC(10.500), + SC(10.875),SC(11.250),SC(11.625),SC(12.000), /* OCT 5 */ - 0.000/DV, 3.000/DV, 6.000/DV, 7.875/DV, - 9.000/DV,10.125/DV,10.875/DV,11.625/DV, - 12.000/DV,12.750/DV,13.125/DV,13.500/DV, - 13.875/DV,14.250/DV,14.625/DV,15.000/DV, + SC(0.000), SC(3.000), SC(6.000), SC(7.875), + SC(9.000),SC(10.125),SC(10.875),SC(11.625), + SC(12.000),SC(12.750),SC(13.125),SC(13.500), + SC(13.875),SC(14.250),SC(14.625),SC(15.000), /* OCT 6 */ - 0.000/DV, 6.000/DV, 9.000/DV,10.875/DV, - 12.000/DV,13.125/DV,13.875/DV,14.625/DV, - 15.000/DV,15.750/DV,16.125/DV,16.500/DV, - 16.875/DV,17.250/DV,17.625/DV,18.000/DV, + SC(0.000), SC(6.000), SC(9.000),SC(10.875), + SC(12.000),SC(13.125),SC(13.875),SC(14.625), + SC(15.000),SC(15.750),SC(16.125),SC(16.500), + SC(16.875),SC(17.250),SC(17.625),SC(18.000), /* OCT 7 */ - 0.000/DV, 9.000/DV,12.000/DV,13.875/DV, - 15.000/DV,16.125/DV,16.875/DV,17.625/DV, - 18.000/DV,18.750/DV,19.125/DV,19.500/DV, - 19.875/DV,20.250/DV,20.625/DV,21.000/DV + SC(0.000), SC(9.000),SC(12.000),SC(13.875), + SC(15.000),SC(16.125),SC(16.875),SC(17.625), + SC(18.000),SC(18.750),SC(19.125),SC(19.500), + SC(19.875),SC(20.250),SC(20.625),SC(21.000) }; -#undef DV +#undef SC /* sustain level table (3dB per step) */ /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ @@ -493,13 +493,13 @@ O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), /* multiple table */ -#define ML 2 +#define SC(x) ((UINT32)((x)*2)) static const UINT8 mul_tab[16]= { /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,10,12,12,15,15 */ - 0.50*ML, 1.00*ML, 2.00*ML, 3.00*ML, 4.00*ML, 5.00*ML, 6.00*ML, 7.00*ML, - 8.00*ML, 9.00*ML,10.00*ML,10.00*ML,12.00*ML,12.00*ML,15.00*ML,15.00*ML + SC(0.50), SC(1.00), SC(2.00), SC(3.00), SC(4.00), SC(5.00), SC(6.00), SC(7.00), + SC(8.00), SC(9.00),SC(10.00),SC(10.00),SC(12.00),SC(12.00),SC(15.00),SC(15.00) }; -#undef ML +#undef SC /* TL_TAB_LEN is calculated as: * 12 - sinus amplitude bits (Y axis) @@ -1301,17 +1301,17 @@ static void OPL_initalize(FM_OPL *OPL) /* Amplitude modulation: 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */ /* One entry from LFO_AM_TABLE lasts for 64 samples */ - OPL->lfo_am_inc = (1.0 / 64.0 ) * (1<freqbase; + OPL->lfo_am_inc = (UINT32)((1.0 / 64.0 ) * (1<freqbase); /* Vibrato: 8 output levels (triangle waveform); 1 level takes 1024 samples */ - OPL->lfo_pm_inc = (1.0 / 1024.0) * (1<freqbase; + OPL->lfo_pm_inc = (UINT32)((1.0 / 1024.0) * (1<freqbase); /*logerror ("OPL->lfo_am_inc = %8x ; OPL->lfo_pm_inc = %8x\n", OPL->lfo_am_inc, OPL->lfo_pm_inc);*/ /* Noise generator: a step takes 1 sample */ - OPL->noise_f = (1.0 / 1.0) * (1<freqbase; + OPL->noise_f = (UINT32)((1.0 / 1.0) * (1<freqbase); - OPL->eg_timer_add = (1<freqbase; + OPL->eg_timer_add = (UINT32)((1<freqbase); OPL->eg_timer_overflow = ( 1 ) * (1<eg_timer_add, OPL->eg_timer_overflow);*/ diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index adcff0b7..4de2561a 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: iohandler.cpp,v 1.27 2007-06-01 16:40:40 c2woody Exp $ */ +/* $Id: iohandler.cpp,v 1.28 2007-06-12 20:22:08 c2woody Exp $ */ #include #include "dosbox.h" @@ -174,7 +174,7 @@ static Bits IOFaultCore(void) { inline void IO_USEC_read_delay_old() { if(CPU_CycleMax > static_cast((IODELAY_READ_MICROS*1000.0))) { // this could be calculated whenever CPU_CycleMax changes - Bitu delaycyc = static_cast((CPU_CycleMax/1000)*IODELAY_READ_MICROS); + Bits delaycyc = static_cast((CPU_CycleMax/1000)*IODELAY_READ_MICROS); if(CPU_Cycles > delaycyc) CPU_Cycles -= delaycyc; else CPU_Cycles = 0; } @@ -183,7 +183,7 @@ inline void IO_USEC_read_delay_old() { inline void IO_USEC_write_delay_old() { if(CPU_CycleMax > static_cast((IODELAY_WRITE_MICROS*1000.0))) { // this could be calculated whenever CPU_CycleMax changes - Bitu delaycyc = static_cast((CPU_CycleMax/1000)*IODELAY_WRITE_MICROS); + Bits delaycyc = static_cast((CPU_CycleMax/1000)*IODELAY_WRITE_MICROS); if(CPU_Cycles > delaycyc) CPU_Cycles -= delaycyc; else CPU_Cycles = 0; } @@ -194,14 +194,14 @@ inline void IO_USEC_write_delay_old() { #define IODELAY_WRITE_MICROSk (Bit32u)(1024/0.75) inline void IO_USEC_read_delay() { - Bitu delaycyc = CPU_CycleMax/IODELAY_READ_MICROSk; + Bits delaycyc = CPU_CycleMax/IODELAY_READ_MICROSk; if(GCC_UNLIKELY(CPU_Cycles < 3*delaycyc)) delaycyc = 0; //Else port acces will set cycles to 0. which might trigger problem with games which read 16 bit values CPU_Cycles -= delaycyc; CPU_IODelayRemoved += delaycyc; } inline void IO_USEC_write_delay() { - Bitu delaycyc = CPU_CycleMax/IODELAY_WRITE_MICROSk; + Bits delaycyc = CPU_CycleMax/IODELAY_WRITE_MICROSk; if(GCC_UNLIKELY(CPU_Cycles < 3*delaycyc)) delaycyc=0; CPU_Cycles -= delaycyc; CPU_IODelayRemoved += delaycyc; diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index ab23ade3..bc4ef238 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.38 2007-06-08 08:21:45 qbix79 Exp $ */ +/* $Id: keyboard.cpp,v 1.39 2007-06-12 20:22:08 c2woody Exp $ */ #include "dosbox.h" #include "keyboard.h" @@ -66,7 +66,6 @@ static void KEYBOARD_TransferBuffer(Bitu val) { LOG(LOG_KEYBOARD,LOG_NORMAL)("Transfer started with empty buffer"); return; } - Bit8u data=keyb.buffer[keyb.pos]; KEYBOARD_SetPort60(keyb.buffer[keyb.pos]); if (++keyb.pos>=KEYBUFSIZE) keyb.pos-=KEYBUFSIZE; keyb.used--; diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index f89a6fba..4be4072d 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.45 2007-05-01 18:57:19 c2woody Exp $ */ +/* $Id: mixer.cpp,v 1.46 2007-06-12 20:22:08 c2woody Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -595,7 +595,7 @@ void MIXER_Init(Section* sec) { spec.channels=2; spec.callback=MIXER_CallBack; spec.userdata=NULL; - spec.samples=mixer.blocksize; + spec.samples=(Uint16)mixer.blocksize; mixer.tick_remain=0; if (mixer.nosound) { diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index f7c11ca5..f44037b1 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.40 2007-04-16 13:25:06 c2woody Exp $ */ +/* $Id: pic.cpp,v 1.41 2007-06-12 20:22:08 c2woody Exp $ */ #include @@ -83,7 +83,7 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { if (val&0x04) E_Exit("PIC: 4 byte interval not handled"); if (val&0x08) E_Exit("PIC: level triggered mode not handled"); if (val&0xe0) E_Exit("PIC: 8080/8085 mode not handled"); - pic->single=val&0x02; + pic->single=(val&0x02)==0x02; pic->icw_index=1; // next is ICW2 pic->icw_words=2 + (val&0x01); // =3 if ICW4 needed } else if (GCC_UNLIKELY(val&0x08)) { // OCW3 issued @@ -118,7 +118,7 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { } } } - if (val&0x80); // perform rotation +// if (val&0x80); // perform rotation } else { // nonspecific EOI if (PIC_IRQActive<(irq_base+8)) { irqs[PIC_IRQActive].inservice=false; @@ -130,7 +130,7 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { } } } - if (val&0x80); // perform rotation +// if (val&0x80); // perform rotation } } else { if ((val&0x40)==0) { // rotate in auto EOI mode @@ -232,7 +232,6 @@ static Bitu read_command(Bitu port,Bitu iolen) { } static Bitu read_data(Bitu port,Bitu iolen) { - PIC_Controller * pic=&pics[port==0x21 ? 0 : 1]; Bitu irq_base=(port==0x21) ? 0 : 8; Bitu i;Bit8u ret=0;Bit8u b=1; for (i=irq_base;i<=irq_base+7;i++) { @@ -387,7 +386,7 @@ void PIC_AddEvent(PIC_EventHandler handler,float delay,Bitu val) { return; } PICEntry * entry=pic.free_entry; - entry->index=delay+PIC_TickIndex();; + entry->index=delay+PIC_TickIndex(); entry->event=handler; entry->value=val; pic.free_entry=pic.free_entry->next; diff --git a/src/hardware/serialport/misc_util.cpp b/src/hardware/serialport/misc_util.cpp index 97379094..9968cd9b 100644 --- a/src/hardware/serialport/misc_util.cpp +++ b/src/hardware/serialport/misc_util.cpp @@ -233,7 +233,7 @@ bool TCPClientSocket::SendArrayBuffered(Bit8u* data, Bitu bufsize) { while( // first case, buffer already full - /*if(sendbufferindex==(sendbuffersize-1)) { + if(sendbufferindex==(sendbuffersize-1)) { // buffer is full, get rid of it sendbuffer[sendbufferindex]=data; sendbufferindex=0; @@ -242,9 +242,9 @@ bool TCPClientSocket::SendArrayBuffered(Bit8u* data, Bitu bufsize) { isopen=false; return false; } - }*/ -//} - + } +} +*/ void TCPClientSocket::FlushBuffer() { if(sendbufferindex) { if(SDLNet_TCP_Send(mysock, sendbuffer, diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 8075980a..0341bd4e 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.43 2007-06-08 08:21:45 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.44 2007-06-12 20:22:08 c2woody Exp $ */ #include #include "dosbox.h" @@ -69,7 +69,7 @@ static void PIT0_Event(Bitu /*val*/) { if (pit[0].mode != 0) { pit[0].start += pit[0].delay; double error = pit[0].start - PIC_FullIndex(); - PIC_AddEvent(PIT0_Event,pit[0].delay + error); + PIC_AddEvent(PIT0_Event,(float)(pit[0].delay + error)); } } diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index b6d0f661..f8e4d953 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -84,7 +84,8 @@ void VGA_SetClock(Bitu which,Bitu target) { Bits err; } best; best.err=target; - Bitu n,m,r; + Bitu n,r; + Bits m; for (r = 0; r <= 3; r++) { Bitu f_vco = target * (1 << r); diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index 9aee8848..955a6cb6 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -139,6 +139,7 @@ static void write_p3c9(Bitu port,Bitu val,Bitu iolen) { break; default: LOG(LOG_VGAGFX,LOG_NORMAL)("VGA:DAC:Illegal Pel Index"); //If this can actually happen that will be the day + break; }; } @@ -161,6 +162,8 @@ static Bitu read_p3c9(Bitu port,Bitu iolen) { break; default: LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:DAC:Illegal Pel Index"); //If this can actually happen that will be the day + ret=0; + break; } return ret; } diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 6a79b16d..64f0baad 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -380,7 +380,7 @@ static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart, Bitu line) { static Bit32u FontMask[2]={0xffffffff,0x0}; static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart, Bitu line) { - Bitu font_addr; + Bits font_addr; Bit32u * draw=(Bit32u *)TempLine; const Bit8u *vidmem = &vga.tandy.draw_base[vidstart]; for (Bitu cx=0;cx> 1; - if (font_addr>=0 && font_addr=0 && font_addr<(Bits)vga.draw.blocks) { if (linevga.draw.cursor.eline) goto skip_cursor; draw=(Bit32u *)&TempLine[font_addr*8]; @@ -579,8 +579,8 @@ static void VGA_VerticalTimer(Bitu val) { break; } //VGA_DrawPart( vga.draw.parts_lines ); - PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts,vga.draw.parts_lines); -// PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts/2,vga.draw.parts_lines); //Else tearline in Tyrian and second reality + PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts,vga.draw.parts_lines); +// PIC_AddEvent(VGA_DrawPart,(float)(vga.draw.delay.parts/2),vga.draw.parts_lines); //Else tearline in Tyrian and second reality } void VGA_CheckScanLength(void) { @@ -983,7 +983,7 @@ void VGA_SetupDrawing(Bitu val) { #endif RENDER_SetSize(width,height,bpp,fps,aspect_ratio,doublewidth,doubleheight); vga.draw.delay.framestart = PIC_FullIndex(); - PIC_AddEvent( VGA_VerticalTimer , vga.draw.delay.vtotal ); + PIC_AddEvent( VGA_VerticalTimer , (float)vga.draw.delay.vtotal ); } }; diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 2588264e..19a573f3 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -96,6 +96,8 @@ INLINE static Bit32u ModeOperation(Bit8u val) { break; default: LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:Unsupported write mode %d",vga.config.write_mode); + full=0; + break; } return full; } diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 6ef43451..58ae7cd8 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -22,7 +22,6 @@ #include "vga.h" #include -static Bit8u flip=0; void vga_write_p3d4(Bitu port,Bitu val,Bitu iolen); Bitu vga_read_p3d4(Bitu port,Bitu iolen); diff --git a/src/hardware/ymf262.c b/src/hardware/ymf262.c index e9bd41f2..6e044fc6 100644 --- a/src/hardware/ymf262.c +++ b/src/hardware/ymf262.c @@ -280,51 +280,51 @@ static const int slot_array[32]= /* key scale level */ /* table is 3dB/octave , DV converts this into 6dB/octave */ /* 0.1875 is bit 0 weight of the envelope counter (volume) expressed in the 'decibel' scale */ -#define DV (0.1875/2.0) +#define SC(x) ((UINT32)((x)/(0.1875/2.0))) static const UINT32 ksl_tab[8*16]= { /* OCT 0 */ - 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, - 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, - 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, - 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), /* OCT 1 */ - 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, - 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, - 0.000/DV, 0.750/DV, 1.125/DV, 1.500/DV, - 1.875/DV, 2.250/DV, 2.625/DV, 3.000/DV, + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.750), SC(1.125), SC(1.500), + SC(1.875), SC(2.250), SC(2.625), SC(3.000), /* OCT 2 */ - 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, - 0.000/DV, 1.125/DV, 1.875/DV, 2.625/DV, - 3.000/DV, 3.750/DV, 4.125/DV, 4.500/DV, - 4.875/DV, 5.250/DV, 5.625/DV, 6.000/DV, + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(1.125), SC(1.875), SC(2.625), + SC(3.000), SC(3.750), SC(4.125), SC(4.500), + SC(4.875), SC(5.250), SC(5.625), SC(6.000), /* OCT 3 */ - 0.000/DV, 0.000/DV, 0.000/DV, 1.875/DV, - 3.000/DV, 4.125/DV, 4.875/DV, 5.625/DV, - 6.000/DV, 6.750/DV, 7.125/DV, 7.500/DV, - 7.875/DV, 8.250/DV, 8.625/DV, 9.000/DV, + SC(0.000), SC(0.000), SC(0.000), SC(1.875), + SC(3.000), SC(4.125), SC(4.875), SC(5.625), + SC(6.000), SC(6.750), SC(7.125), SC(7.500), + SC(7.875), SC(8.250), SC(8.625), SC(9.000), /* OCT 4 */ - 0.000/DV, 0.000/DV, 3.000/DV, 4.875/DV, - 6.000/DV, 7.125/DV, 7.875/DV, 8.625/DV, - 9.000/DV, 9.750/DV,10.125/DV,10.500/DV, - 10.875/DV,11.250/DV,11.625/DV,12.000/DV, + SC(0.000), SC(0.000), SC(3.000), SC(4.875), + SC(6.000), SC(7.125), SC(7.875), SC(8.625), + SC(9.000), SC(9.750),SC(10.125),SC(10.500), + SC(10.875),SC(11.250),SC(11.625),SC(12.000), /* OCT 5 */ - 0.000/DV, 3.000/DV, 6.000/DV, 7.875/DV, - 9.000/DV,10.125/DV,10.875/DV,11.625/DV, - 12.000/DV,12.750/DV,13.125/DV,13.500/DV, - 13.875/DV,14.250/DV,14.625/DV,15.000/DV, + SC(0.000), SC(3.000), SC(6.000), SC(7.875), + SC(9.000),SC(10.125),SC(10.875),SC(11.625), + SC(12.000),SC(12.750),SC(13.125),SC(13.500), + SC(13.875),SC(14.250),SC(14.625),SC(15.000), /* OCT 6 */ - 0.000/DV, 6.000/DV, 9.000/DV,10.875/DV, - 12.000/DV,13.125/DV,13.875/DV,14.625/DV, - 15.000/DV,15.750/DV,16.125/DV,16.500/DV, - 16.875/DV,17.250/DV,17.625/DV,18.000/DV, + SC(0.000), SC(6.000), SC(9.000),SC(10.875), + SC(12.000),SC(13.125),SC(13.875),SC(14.625), + SC(15.000),SC(15.750),SC(16.125),SC(16.500), + SC(16.875),SC(17.250),SC(17.625),SC(18.000), /* OCT 7 */ - 0.000/DV, 9.000/DV,12.000/DV,13.875/DV, - 15.000/DV,16.125/DV,16.875/DV,17.625/DV, - 18.000/DV,18.750/DV,19.125/DV,19.500/DV, - 19.875/DV,20.250/DV,20.625/DV,21.000/DV + SC(0.000), SC(9.000),SC(12.000),SC(13.875), + SC(15.000),SC(16.125),SC(16.875),SC(17.625), + SC(18.000),SC(18.750),SC(19.125),SC(19.500), + SC(19.875),SC(20.250),SC(20.625),SC(21.000) }; -#undef DV +#undef SC /* sustain level table (3dB per step) */ /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ @@ -444,13 +444,13 @@ O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), /* multiple table */ -#define ML 2 +#define SC(x) ((UINT32)((x)*2)) static const UINT8 mul_tab[16]= { /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,10,12,12,15,15 */ - 0.50*ML, 1.00*ML, 2.00*ML, 3.00*ML, 4.00*ML, 5.00*ML, 6.00*ML, 7.00*ML, - 8.00*ML, 9.00*ML,10.00*ML,10.00*ML,12.00*ML,12.00*ML,15.00*ML,15.00*ML + SC(0.50), SC(1.00), SC(2.00), SC(3.00), SC(4.00), SC(5.00), SC(6.00), SC(7.00), + SC(8.00), SC(9.00),SC(10.00),SC(10.00),SC(12.00),SC(12.00),SC(15.00),SC(15.00) }; -#undef ML +#undef SC /* TL_TAB_LEN is calculated as: @@ -1344,17 +1344,17 @@ static void OPL3_initalize(OPL3 *chip) /* Amplitude modulation: 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */ /* One entry from LFO_AM_TABLE lasts for 64 samples */ - chip->lfo_am_inc = (1.0 / 64.0 ) * (1<freqbase; + chip->lfo_am_inc = (UINT32)((1.0 / 64.0 ) * (1<freqbase); /* Vibrato: 8 output levels (triangle waveform); 1 level takes 1024 samples */ - chip->lfo_pm_inc = (1.0 / 1024.0) * (1<freqbase; + chip->lfo_pm_inc = (UINT32)((1.0 / 1024.0) * (1<freqbase); /*logerror ("chip->lfo_am_inc = %8x ; chip->lfo_pm_inc = %8x\n", chip->lfo_am_inc, chip->lfo_pm_inc);*/ /* Noise generator: a step takes 1 sample */ - chip->noise_f = (1.0 / 1.0) * (1<freqbase; + chip->noise_f = (UINT32)((1.0 / 1.0) * (1<freqbase); - chip->eg_timer_add = (1<freqbase; + chip->eg_timer_add = (UINT32)((1<freqbase); chip->eg_timer_overflow = ( 1 ) * (1<eg_timer_add, chip->eg_timer_overflow);*/ diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 6428f5a3..7aa3bf92 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.67 2007-03-07 10:47:12 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.68 2007-06-12 20:22:08 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -981,7 +981,7 @@ void BIOS_SetComPorts(Bit16u baseaddr[]) { equipmentword &= (~0x0E00); equipmentword |= (portcount << 9); mem_writew(BIOS_CONFIGURATION,equipmentword); - CMOS_SetRegister(0x14,equipmentword); //Should be updated on changes + CMOS_SetRegister(0x14,(Bit8u)(equipmentword&0xff)); //Should be updated on changes } diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 6b868666..b97a5b1f 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.34 2007-05-02 18:56:15 c2woody Exp $ */ +/* $Id: bios_disk.cpp,v 1.35 2007-06-12 20:22:08 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" @@ -40,7 +40,7 @@ diskGeo DiskGeometryList[] = { {1200, 15, 2, 80, 2}, {1440, 18, 2, 80, 4}, {2880, 36, 2, 80, 6}, - {0, 0, 0 , 0}, + {0, 0, 0, 0, 0} }; Bitu call_int13; @@ -65,8 +65,8 @@ void updateDPT(void) { if(imageDiskList[2] != NULL) { PhysPt dp0physaddr=CALLBACK_PhysPointer(diskparm0); imageDiskList[2]->Get_Geometry(&tmpheads, &tmpcyl, &tmpsect, &tmpsize); - phys_writew(dp0physaddr,tmpcyl); - phys_writeb(dp0physaddr+0x2,tmpheads); + phys_writew(dp0physaddr,(Bit16u)tmpcyl); + phys_writeb(dp0physaddr+0x2,(Bit8u)tmpheads); phys_writew(dp0physaddr+0x3,0); phys_writew(dp0physaddr+0x5,(Bit16u)-1); phys_writeb(dp0physaddr+0x7,0); @@ -74,15 +74,15 @@ void updateDPT(void) { phys_writeb(dp0physaddr+0x9,0); phys_writeb(dp0physaddr+0xa,0); phys_writeb(dp0physaddr+0xb,0); - phys_writew(dp0physaddr+0xc,tmpcyl); - phys_writeb(dp0physaddr+0xe,tmpsect); + phys_writew(dp0physaddr+0xc,(Bit16u)tmpcyl); + phys_writeb(dp0physaddr+0xe,(Bit8u)tmpsect); } if(imageDiskList[3] != NULL) { PhysPt dp1physaddr=CALLBACK_PhysPointer(diskparm1); imageDiskList[3]->Get_Geometry(&tmpheads, &tmpcyl, &tmpsect, &tmpsize); - phys_writew(dp1physaddr,tmpcyl); - phys_writeb(dp1physaddr+0x2,tmpheads); - phys_writeb(dp1physaddr+0xe,tmpsect); + phys_writew(dp1physaddr,(Bit16u)tmpcyl); + phys_writeb(dp1physaddr+0x2,(Bit8u)tmpheads); + phys_writeb(dp1physaddr+0xe,(Bit8u)tmpsect); } } @@ -222,7 +222,7 @@ imageDisk::imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHard equipment|=(numofdisks<<6); } else equipment|=1; mem_writew(BIOS_CONFIGURATION,equipment); - CMOS_SetRegister(0x14, equipment); + CMOS_SetRegister(0x14, (Bit8u)(equipment&0xff)); } } } @@ -244,7 +244,7 @@ void imageDisk::Get_Geometry(Bit32u * getHeads, Bit32u *getCyl, Bit32u *getSect, Bit8u imageDisk::GetBiosType(void) { if(!hardDrive) { - return DiskGeometryList[floppytype].biosval; + return (Bit8u)DiskGeometryList[floppytype].biosval; } else return 0; } @@ -298,11 +298,11 @@ static Bitu INT13_DiskHandler(void) { Bit16u segat, bufptr; Bit8u sectbuf[512]; Bitu drivenum; - int i,t; + Bitu i,t; last_drive = reg_dl; drivenum = GetDosDriveNumber(reg_dl); bool any_images = false; - for(Bitu i = 0;i < MAX_DISK_IMAGES;i++) { + for(i = 0;i < MAX_DISK_IMAGES;i++) { if(imageDiskList[i]) any_images=true; } @@ -447,9 +447,9 @@ static Bitu INT13_DiskHandler(void) { else tmpcyl--; // cylinder count -> max cylinder if (tmpheads==0) LOG(LOG_BIOS,LOG_ERROR)("INT13 DrivParm: head count zero!"); else tmpheads--; // head count -> max head - reg_ch = tmpcyl & 0xff; - reg_cl = (((tmpcyl >> 2) & 0xc0) | (tmpsect & 0x3f)); - reg_dh = tmpheads; + reg_ch = (Bit8u)(tmpcyl & 0xff); + reg_cl = (Bit8u)(((tmpcyl >> 2) & 0xc0) | (tmpsect & 0x3f)); + reg_dh = (Bit8u)tmpheads; last_status = 0x00; if (reg_dl&0x80) { // harddisks reg_dl = 0; diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 4d21f028..4130958e 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.49 2007-01-08 19:45:41 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.50 2007-06-12 20:22:08 c2woody Exp $ */ /* Character displaying moving functions */ @@ -534,7 +534,7 @@ void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); - BIOS_NCOLS;BIOS_NROWS; + BIOS_NCOLS; while (count>0) { WriteChar(cur_col,cur_row,page,chr,attr,showattr); count--; @@ -600,7 +600,6 @@ void INT10_TeletypeOutput(Bit8u chr,Bit8u attr) { } void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,Bit16u count,Bit8u page) { - BIOS_NCOLS;BIOS_NROWS; Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 0c56c2d6..7b31e24b 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -218,7 +218,7 @@ void INT10_EGA_RIL_ReadRegisterRange(Bit8u & bl, Bit8u ch, Bit8u cl, Bit16u dx, LOG(LOG_INT10,LOG_ERROR)("EGA RIL range read with port %x called",port); } else { if(chregs) cl=regs-ch; + if ((Bitu)ch+cl>regs) cl=(Bit8u)(regs-ch); for (Bitu i=0; iregs) cl=regs-ch; + if ((Bitu)ch+cl>regs) cl=(Bit8u)(regs-ch); if(port == 0x3c0) { IO_Read(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS) + 6); for (Bitu i=0; ivdispend+1) << 8); //Maximum scanline Bit8u scanline,crtpage; + scanline=8; switch(CurMode->type) { case M_TEXT: if (machine==MCH_HERC) scanline=14; diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 9544f86f..810343cb 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -210,7 +210,7 @@ void INT10_GetPelMask(Bit8u & mask) { } void INT10_SetBackgroundBorder(Bit8u val) { - Bitu temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL); + Bit8u temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL); temp=(temp & 0xe0) | (val & 0x1f); real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp); if (machine == MCH_CGA || IS_TANDY_ARCH) @@ -233,7 +233,7 @@ void INT10_SetBackgroundBorder(Bit8u val) { } void INT10_SetColorSelect(Bit8u val) { - Bitu temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL); + Bit8u temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL); temp=(temp & 0xdf) | ((val & 1) ? 0x20 : 0x0); real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp); if (machine == MCH_CGA || IS_TANDY_ARCH) diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index c76adf4c..b6445ead 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -21,8 +21,8 @@ #include "inout.h" #include "int10.h" -static Bit8u cga_masks[4]={~192U,~48U,~12U,~3U}; -static Bit8u cga_masks2[8]={~128U,~64U,~32U,~16U,~8U,~4U,~2U,~1U}; +static Bit8u cga_masks[4]={0x3f,0xcf,0xf3,0xfc}; +static Bit8u cga_masks2[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}; void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { switch (CurMode->type) { diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 04f7bd60..b2bde54a 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.26 2007-01-24 16:29:53 harekiet Exp $ */ +/* $Id: int10_vesa.cpp,v 1.27 2007-06-12 20:22:09 c2woody Exp $ */ #include #include @@ -228,7 +228,7 @@ Bit8u VESA_SetSVGAMode(Bit16u mode) { }; Bit8u VESA_GetSVGAMode(Bit16u & mode) { - mode=CurMode->mode; + mode=(Bit16u)(CurMode->mode); return 0x00; } diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index a0c8711b..4056fe86 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.68 2007-06-06 15:44:40 c2woody Exp $ */ +/* $Id: mouse.cpp,v 1.69 2007-06-12 20:22:09 c2woody Exp $ */ #include #include @@ -236,12 +236,12 @@ void DrawCursorText() Bit16u result; ReadCharAttr(mouse.backposx,mouse.backposy,0,&result); - mouse.backData[0] = result & 0xFF; - mouse.backData[1] = result>>8; + mouse.backData[0] = (Bit8u)(result & 0xFF); + mouse.backData[1] = (Bit8u)(result>>8); mouse.background = true; // Write Cursor result = (result & mouse.textAndMask) ^ mouse.textXorMask; - WriteChar(mouse.backposx,mouse.backposy,0,result&0xFF,result>>8,true); + WriteChar(mouse.backposx,mouse.backposy,0,(Bit8u)(result&0xFF),(Bit8u)(result>>8),true); }; // *************************************************************************** @@ -508,8 +508,8 @@ static void SetSensitivity(Bit16s px, Bit16s py){ if ((px!=0) && (py!=0)) { px--; //Inspired by cutemouse py--; //Although their cursor update routine is far more complex then ours - mouse.senv_x=(static_cast(px)*px)/3600.0 +1.0/3.0; - mouse.senv_y=(static_cast(py)*py)/3600.0 +1.0/3.0; + mouse.senv_x=(static_cast(px)*px)/3600.0f +1.0f/3.0f; + mouse.senv_y=(static_cast(py)*py)/3600.0f +1.0f/3.0f; } }; diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index f5d1aa42..539f5d54 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.46 2007-01-08 21:40:15 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.47 2007-06-12 20:22:09 c2woody Exp $ */ #include #include @@ -229,7 +229,7 @@ Bitu XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFree, Bit for (Bitu i=1;i #include @@ -54,11 +54,12 @@ static std::vector internal_progs; void PROGRAMS_MakeFile(char const * const name,PROGRAMS_Main * main) { Bit8u * comdata=(Bit8u *)malloc(32); //MEM LEAK memcpy(comdata,&exe_block,sizeof(exe_block)); - comdata[CB_POS]=call_program&0xff; - comdata[CB_POS+1]=(call_program>>8)&0xff; + comdata[CB_POS]=(Bit8u)(call_program&0xff); + comdata[CB_POS+1]=(Bit8u)((call_program>>8)&0xff); /* Copy save the pointer in the vector and save it's index */ - Bit8u index = internal_progs.size(); + if (internal_progs.size()>255) E_Exit("PROGRAMS_MakeFile program size too large (%d)",internal_progs.size()); + Bit8u index = (Bit8u)internal_progs.size(); internal_progs.push_back(main); memcpy(&comdata[sizeof(exe_block)],&index,sizeof(index)); @@ -329,7 +330,7 @@ static void CONFIG_ProgramStart(Program * * make) { } -void PROGRAMS_Init(Section* sec) { +void PROGRAMS_Init(Section* /*sec*/) { /* Setup a special callback to start virtual programs */ call_program=CALLBACK_Allocate(); CALLBACK_Setup(call_program,&PROGRAMS_Handler,CB_RETF,"internal program"); diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 7d7473f7..cdb3ee27 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.31 2007-01-08 19:45:41 qbix79 Exp $ */ +/* $Id: support.cpp,v 1.32 2007-06-12 20:22:09 c2woody Exp $ */ #include #include @@ -91,7 +91,6 @@ char * ScanCMDRemain(char * cmd) { } char * StripWord(char *&line) { - bool quoted=false; char * scan=line; scan=ltrim(scan); if (*scan=='"') { diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index a7bee72a..afd882ea 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.74 2007-05-15 18:55:23 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.75 2007-06-12 20:22:09 c2woody Exp $ */ #include #include @@ -405,11 +405,11 @@ void DOS_Shell::CMD_DIR(char * args) { if (!ext) ext = ""; else *ext++ = '\0'; } - Bit8u day = date & 0x001f; - Bit8u month = (date >> 5) & 0x000f; - Bit16u year = (date >> 9) + 1980; - Bit8u hour = (time >> 5 ) >> 6; - Bit8u minute = (time >> 5) & 0x003f; + Bit8u day = (Bit8u)(date & 0x001f); + Bit8u month = (Bit8u)((date >> 5) & 0x000f); + Bit16u year = (Bit16u)((date >> 9) + 1980); + Bit8u hour = (Bit8u)((time >> 5 ) >> 6); + Bit8u minute = (Bit8u)((time >> 5) & 0x003f); /* output the file */ if (attr & DOS_ATTR_DIRECTORY) { @@ -867,7 +867,7 @@ void DOS_Shell::CMD_LOADHIGH(char *args){ HELP("LOADHIGH"); Bit16u umb_start=dos_infoblock.GetStartOfUMBChain(); Bit8u umb_flag=dos_infoblock.GetUMBChainState(); - Bit8u old_memstrat=DOS_GetMemAllocStrategy()&0xff; + Bit8u old_memstrat=(Bit8u)(DOS_GetMemAllocStrategy()&0xff); if (umb_start==0x9fff) { if ((umb_flag&1)==0) DOS_LinkUMBsToMemChain(1); DOS_SetMemAllocStrategy(0x80); // search in UMBs first @@ -962,7 +962,7 @@ void DOS_Shell::CMD_VER(char *args) { char* word = StripWord(args); if(strcasecmp(word,"set")) return; word = StripWord(args); - dos.version.major = atoi(word); - dos.version.minor = atoi(args); + dos.version.major = (Bit8u)(atoi(word)); + dos.version.minor = (Bit8u)(atoi(args)); } else WriteOut(MSG_Get("SHELL_CMD_VER_VER"),VERSION,dos.version.major,dos.version.minor); } From e42291ec7a0a734e705fe9165bfc6b92612393be Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 13 Jun 2007 07:22:17 +0000 Subject: [PATCH 2798/4131] Unshadow a few parameters. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2884 --- src/shell/shell_batch.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 78edfe4e..3cc3341a 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.23 2007-01-08 19:45:42 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.24 2007-06-13 07:22:17 qbix79 Exp $ */ #include #include @@ -100,9 +100,9 @@ emptyline: /* Not a command line number has to be an environment */ char * first=strchr(cmd_read,'%'); if (!first) continue; *first++=0; - std::string temp; - if (shell->GetEnvStr(cmd_read,temp)) { - const char * equals=strchr(temp.c_str(),'='); + std::string env; + if (shell->GetEnvStr(cmd_read,env)) { + const char * equals=strchr(env.c_str(),'='); if (!equals) continue; equals++; strcpy(cmd_write,equals); @@ -120,14 +120,14 @@ emptyline: bool BatchFile::Goto(char * where) { Bit32u pos=0; - char cmd[CMD_MAXLINE]; + char cmd_buffer[CMD_MAXLINE]; char * cmd_write; DOS_SeekFile(file_handle,&pos,DOS_SEEK_SET); /* Scan till we have a match or return false */ Bit8u c;Bit16u n; again: - cmd_write=cmd; + cmd_write=cmd_buffer; do { n=1; DOS_ReadFile(file_handle,&c,&n); @@ -137,7 +137,7 @@ again: } } while (c!='\n' && n); *cmd_write++=0; - char *nospace = trim(cmd); + char *nospace = trim(cmd_buffer); if (nospace[0] == ':') { char* nonospace = trim(nospace+1); if (strcasecmp(nonospace,where)==0) return true; From df0f8ee9d67b8bf083d4543700091e9509f7cbed Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 13 Jun 2007 07:25:14 +0000 Subject: [PATCH 2799/4131] Remove from DOS_File type and size. type wasn't used at all. size was only implemented in 50% of the drives. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2885 --- include/dos_inc.h | 4 ++-- include/dos_system.h | 4 +--- src/dos/dos.cpp | 4 ++-- src/dos/dos_classes.cpp | 10 +++++++--- src/dos/dos_devices.cpp | 6 +----- src/dos/dos_files.cpp | 9 +++++---- src/dos/drive_iso.cpp | 5 ++--- src/dos/drive_local.cpp | 3 +-- 8 files changed, 21 insertions(+), 24 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 3333e3a3..5155acdd 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.67 2007-06-12 20:22:07 c2woody Exp $ */ +/* $Id: dos_inc.h,v 1.68 2007-06-13 07:25:14 qbix79 Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -174,7 +174,7 @@ 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,Bit16u numRec); +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); diff --git a/include/dos_system.h b/include/dos_system.h index 8b30d5e3..dfb8638f 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.39 2007-01-21 16:21:22 c2woody Exp $ */ +/* $Id: dos_system.h,v 1.40 2007-06-13 07:25:14 qbix79 Exp $ */ #ifndef DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H @@ -80,12 +80,10 @@ public: virtual bool UpdateDateTimeFromHost() { return true; } void SetDrive(Bit8u drv) { hdrive=drv;} Bit8u GetDrive(void) { return hdrive;} - Bit8u type; Bit32u flags; Bit16u time; Bit16u date; Bit16u attr; - Bit32u size; Bits refCtr; bool open; char* name; diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index fbc8d81a..168efe4a 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.101 2007-06-12 20:22:08 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.102 2007-06-13 07:25:14 qbix79 Exp $ */ #include #include @@ -288,7 +288,7 @@ static Bitu DOS_21Handler(void) { LOG(LOG_FCB,LOG_NORMAL)("DOS:0x22 FCB-Random write used, result:al=%d",reg_al); break; case 0x23: /* Get file size for FCB */ - if (DOS_FCBGetFileSize(SegValue(ds),reg_dx,reg_cx)) reg_al = 0x00; + if (DOS_FCBGetFileSize(SegValue(ds),reg_dx)) reg_al = 0x00; else reg_al = 0xFF; break; case 0x24: /* Set Random Record number for FCB */ diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 804998ee..5ac6d4e7 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.51 2007-06-12 20:22:08 c2woody Exp $ */ +/* $Id: dos_classes.cpp,v 1.52 2007-06-13 07:25:14 qbix79 Exp $ */ #include #include @@ -462,8 +462,12 @@ void DOS_FCB::FileOpen(Bit8u _fhandle) { sSave(sFCB,cur_block,0); sSave(sFCB,rec_size,128); // sSave(sFCB,rndm,0); // breaks Jewels of darkness. - Bit8u temp=RealHandle(_fhandle); - sSave(sFCB,filesize,Files[temp]->size); + Bit8u temp = RealHandle(_fhandle); + Bit32u size = 0; + Files[temp]->Seek(&size,DOS_SEEK_END); + sSave(sFCB,filesize,size); + size = 0; + Files[temp]->Seek(&size,DOS_SEEK_SET); sSave(sFCB,time,Files[temp]->time); sSave(sFCB,date,Files[temp]->date); } diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index d20ce408..a3efa85a 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_devices.cpp,v 1.16 2007-01-13 08:35:49 qbix79 Exp $ */ +/* $Id: dos_devices.cpp,v 1.17 2007-06-13 07:25:14 qbix79 Exp $ */ #include #include "dosbox.h" @@ -92,12 +92,10 @@ bool DOS_Device::WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcod } DOS_File::DOS_File(const DOS_File& orig) { - type=orig.type; flags=orig.flags; time=orig.time; date=orig.date; attr=orig.attr; - size=orig.size; refCtr=orig.refCtr; open=orig.open; name=0; @@ -107,12 +105,10 @@ DOS_File::DOS_File(const DOS_File& orig) { } DOS_File & DOS_File::operator= (const DOS_File & orig) { - type=orig.type; flags=orig.flags; time=orig.time; date=orig.date; attr=orig.attr; - size=orig.size; refCtr=orig.refCtr; open=orig.open; if(name) { diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 90b702f6..3abf5004 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.85 2007-06-12 20:22:08 c2woody Exp $ */ +/* $Id: dos_files.cpp,v 1.86 2007-06-13 07:25:14 qbix79 Exp $ */ #include #include @@ -978,13 +978,14 @@ Bit8u DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { return error; } -bool DOS_FCBGetFileSize(Bit16u seg,Bit16u offset,Bit16u numRec) { +bool DOS_FCBGetFileSize(Bit16u seg,Bit16u offset) { char shortname[DOS_PATHLENGTH];Bit16u entry;Bit8u handle;Bit16u rec_size; DOS_FCB fcb(seg,offset); fcb.GetName(shortname); if (!DOS_OpenFile(shortname,0,&entry)) return false; - handle=RealHandle(entry); - Bit32u size=Files[handle]->size; + handle = RealHandle(entry); + Bit32u size = 0; + Files[handle]->Seek(&size,DOS_SEEK_END); DOS_CloseFile(entry);fcb.GetSeqData(handle,rec_size); Bit32u random=(size/rec_size); if (size % rec_size) random++; diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index dc1eec41..7ed9962c 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.18 2007-06-12 20:22:08 c2woody Exp $ */ +/* $Id: drive_iso.cpp,v 1.19 2007-06-13 07:25:14 qbix79 Exp $ */ #include #include @@ -52,10 +52,9 @@ isoFile::isoFile(isoDrive *drive, const char *name, FileStat_Block *stat, Bit32u time = stat->time; date = stat->date; attr = stat->attr; - size = stat->size; fileBegin = offset; filePos = fileBegin; - fileEnd = fileBegin + size; + fileEnd = fileBegin + stat->size; cachedSector = -1; open = true; this->name = NULL; diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 279e18b6..aa93af5d 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.74 2007-01-09 17:44:20 c2woody Exp $ */ +/* $Id: drive_local.cpp,v 1.75 2007-06-13 07:25:14 qbix79 Exp $ */ #include #include @@ -517,7 +517,6 @@ localFile::localFile(const char* _name, FILE * handle) { } else { time=1;date=1; } - size=(Bit32u)temp_stat.st_size; attr=DOS_ATTR_ARCHIVE; last_action=NONE; read_only_medium=false; From a5ac3216bac8b21f2823fd3ede6e7b44429a64f4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 14 Jun 2007 08:23:46 +0000 Subject: [PATCH 2800/4131] Some more const stuff. Silences a few warnings and removes a few casts. Update description of dss. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2886 --- include/dos_inc.h | 38 ++-- include/mem.h | 2 +- include/setup.h | 6 +- include/shell.h | 4 +- src/cpu/core_dyn_x86/decoder.h | 2 +- src/cpu/core_dyn_x86/risc_x86.h | 10 +- src/dos/cdrom.h | 12 +- src/dos/dos_devices.cpp | 4 +- src/dos/dos_files.cpp | 65 ++++--- src/dos/dos_keyboard_layout.cpp | 2 +- src/dos/dos_memory.cpp | 2 +- src/dos/drive_fat.cpp | 8 +- src/dos/drives.h | 4 +- src/dosbox.cpp | 4 +- src/gui/midi.cpp | 11 +- src/gui/midi_alsa.h | 6 +- src/gui/midi_coreaudio.h | 2 +- src/gui/midi_oss.h | 2 +- src/gui/midi_win32.h | 4 +- src/gui/render_scalers.cpp | 321 +++++++++++++++++--------------- src/gui/render_scalers.h | 4 +- src/hardware/memory.cpp | 8 +- src/hardware/sblaster.cpp | 8 +- src/misc/setup.cpp | 10 +- src/shell/shell.cpp | 10 +- src/shell/shell_cmds.cpp | 51 ++--- 26 files changed, 312 insertions(+), 288 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 5155acdd..d748a016 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.68 2007-06-13 07:25:14 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.69 2007-06-14 08:23:46 qbix79 Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -115,35 +115,35 @@ bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry); bool DOS_GetFileDate(Bit16u entry, Bit16u* otime, Bit16u* odate); /* Routines for Drive Class */ -bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry); -bool DOS_OpenFileExtended(char *name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status); -bool DOS_CreateFile(char * name,Bit16u attribute,Bit16u * entry); -bool DOS_UnlinkFile(char * name); +bool DOS_OpenFile(char const * 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 const * name,Bit16u attribute,Bit16u * entry); +bool DOS_UnlinkFile(char const * const name); bool DOS_FindFirst(char *search,Bit16u attr,bool fcb_findfirst=false); bool DOS_FindNext(void); -bool DOS_Canonicalize(char * name,char * big); -bool DOS_CreateTempFile(char * name,Bit16u * entry); -bool DOS_FileExists(char * name); +bool DOS_Canonicalize(char const * const name,char * const big); +bool DOS_CreateTempFile(char * const name,Bit16u * entry); +bool DOS_FileExists(char const * const name); /* Helper Functions */ -bool DOS_MakeName(char * name,char * fullname,Bit8u * drive); +bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive); /* Drive Handing Routines */ Bit8u DOS_GetDefaultDrive(void); void DOS_SetDefaultDrive(Bit8u drive); bool DOS_SetDrive(Bit8u drive); -bool DOS_GetCurrentDir(Bit8u drive,char * bugger); -bool DOS_ChangeDir(char * dir); -bool DOS_MakeDir(char * dir); -bool DOS_RemoveDir(char * dir); -bool DOS_Rename(char * oldname,char * newname); +bool DOS_GetCurrentDir(Bit8u drive,char * const buffer); +bool DOS_ChangeDir(char const * const dir); +bool DOS_MakeDir(char const * const dir); +bool DOS_RemoveDir(char const * const dir); +bool DOS_Rename(char const * const oldname,char const * const newname); bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit8u * sectors,Bit16u * clusters,Bit16u * free); -bool DOS_GetFileAttr(char * name,Bit16u * attr); -bool DOS_SetFileAttr(char * name,Bit16u attr); +bool DOS_GetFileAttr(char const * const name,Bit16u * attr); +bool DOS_SetFileAttr(char const * const name,Bit16u attr); /* IOCTL Stuff */ bool DOS_IOCTL(void); bool DOS_GetSTDINStatus(); -Bit8u DOS_FindDevice(char * name); +Bit8u DOS_FindDevice(char const * name); void DOS_SetupDevices(void); /* Execute and new process creation */ @@ -535,8 +535,8 @@ private: class DOS_MCB : public MemStruct{ public: DOS_MCB(Bit16u seg) { SetPt(seg); } - void SetFileName(char * _name) { MEM_BlockWrite(pt+offsetof(sMCB,filename),_name,8); } - void GetFileName(char * _name) { MEM_BlockRead(pt+offsetof(sMCB,filename),_name,8);_name[8]=0;} + void 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);} diff --git a/include/mem.h b/include/mem.h index 9c3a5dfa..436dc384 100644 --- a/include/mem.h +++ b/include/mem.h @@ -150,7 +150,7 @@ INLINE Bit32u phys_readd(PhysPt addr){ /* These don't check for alignment, better be sure it's correct */ -void MEM_BlockWrite(PhysPt pt,void * data,Bitu size); +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); diff --git a/include/setup.h b/include/setup.h index 53517198..39f57604 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.26 2007-01-08 19:45:37 qbix79 Exp $ */ +/* $Id: setup.h,v 1.27 2007-06-14 08:23:46 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -142,8 +142,8 @@ private: public: Section(char const * const _sectionname):sectionname(_sectionname) { } - void AddInitFunction(SectionFunction func,bool canchange=false) {initfunctions.push_back(Function_wrapper(func,canchange));} - void AddDestroyFunction(SectionFunction func,bool canchange=false) {destroyfunctions.push_front(Function_wrapper(func,canchange));} + 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();} diff --git a/include/shell.h b/include/shell.h index e264cb00..a238e3e1 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.20 2007-01-08 19:59:06 qbix79 Exp $ */ +/* $Id: shell.h,v 1.21 2007-06-14 08:23:46 qbix79 Exp $ */ #ifndef DOSBOX_SHELL_H #define DOSBOX_SHELL_H @@ -77,7 +77,7 @@ public: void DoCommand(char * cmd); bool Execute(char * name,char * args); /* Checks if it matches a hardware-property */ - bool CheckConfig(char* cmd,char*line); + bool CheckConfig(char* cmd_in,char*line); /* Some internal used functions */ char * Which(char * name); /* Some supported commands */ diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index c7418d32..d9456f4f 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -2561,7 +2561,7 @@ restart_prefix: dyn_save_critical_regs(); gen_call_function( decode.modrm.reg == 3 ? (void*)&CPU_CALL : (void*)&CPU_JMP, - decode.big_op ? (char *)"%Id%Drw%Drd%Drd" : (char *)"%Id%Drw%Drw%Drd", + decode.big_op ? "%Id%Drw%Drd%Drd" : "%Id%Drw%Drw%Drd", decode.big_op,DREG(EA),DREG(TMPW),DREG(TMPB)); dyn_flags_host_to_gen(); goto core_close_block; diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 94b79c70..08ea139e 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -721,11 +721,11 @@ static void gen_dshift_cl(bool dword,bool left,DynReg * dr1,DynReg * dr2,DynReg dr1->flags|=DYNFLG_CHANGED; } -static void gen_call_function(void * func,char * ops,...) { +static void gen_call_function(void * func,char const* ops,...) { Bits paramcount=0; bool release_flags=false; struct ParamInfo { - char * line; + const char * line; Bitu value; } pinfo[32]; ParamInfo * retparam=0; @@ -743,10 +743,10 @@ static void gen_call_function(void * func,char * ops,...) { Bits pindex=0; while (*ops) { if (*ops=='%') { - pinfo[pindex].line=ops+1; + pinfo[pindex].line=ops+1; pinfo[pindex].value=va_arg(params,Bitu); #if defined (MACOSX) - char * scan=pinfo[pindex].line; + const char * scan=pinfo[pindex].line; if ((*scan=='I') || (*scan=='D')) stack_used+=4; else if (*scan=='F') free_flags=true; #endif @@ -777,7 +777,7 @@ static void gen_call_function(void * func,char * ops,...) { paramcount=0; while (pindex) { pindex--; - char * scan=pinfo[pindex].line; + const char * scan=pinfo[pindex].line; switch (*scan++) { case 'I': /* immediate value */ paramcount++; diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index 08008336..bad8406b 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -76,7 +76,7 @@ public: virtual bool PlayAudioSector (unsigned long start,unsigned long len); virtual bool PauseAudio (bool resume); virtual bool StopAudio (void); - virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) { return false; }; + virtual bool ReadSectors (PhysPt /*buffer*/, bool /*raw*/, unsigned long /*sector*/, unsigned long /*num*/) { return false; }; virtual bool LoadUnloadMedia (bool unload); private: @@ -91,18 +91,18 @@ private: class CDROM_Interface_Fake : public CDROM_Interface { public: - bool SetDevice (char* path, int forceCD) { return true; }; + bool SetDevice (char* /*path*/, int /*forceCD*/) { return true; }; bool GetUPC (unsigned char& attr, char* upc) { attr = 0; strcpy(upc,"UPC"); return true; }; bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr); bool GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); bool GetAudioStatus (bool& playing, bool& pause); bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); - bool PlayAudioSector (unsigned long start,unsigned long len) { return true; }; - bool PauseAudio (bool resume) { return true; }; + bool PlayAudioSector (unsigned long /*start*/,unsigned long /*len*/) { return true; }; + bool PauseAudio (bool /*resume*/) { return true; }; bool StopAudio (void) { return true; }; - bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) { return true; }; - bool LoadUnloadMedia (bool unload) { return true; }; + bool ReadSectors (PhysPt /*buffer*/, bool /*raw*/, unsigned long /*sector*/, unsigned long /*num*/) { return true; }; + bool LoadUnloadMedia (bool /*unload*/) { return true; }; }; class CDROM_Interface_Image : public CDROM_Interface diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index a3efa85a..48396751 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_devices.cpp,v 1.17 2007-06-13 07:25:14 qbix79 Exp $ */ +/* $Id: dos_devices.cpp,v 1.18 2007-06-14 08:23:46 qbix79 Exp $ */ #include #include "dosbox.h" @@ -120,7 +120,7 @@ DOS_File & DOS_File::operator= (const DOS_File & orig) { return *this; } -Bit8u DOS_FindDevice(char * name) { +Bit8u DOS_FindDevice(char const * name) { /* should only check for the names before the dot and spacepadded */ // STDAUX is alias for COM1 // A bit of a hack, but no application will probably use stdaux to determine wether a directory exists diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 3abf5004..3fc64416 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.86 2007-06-13 07:25:14 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.87 2007-06-14 08:23:46 qbix79 Exp $ */ #include #include @@ -52,7 +52,7 @@ void DOS_SetDefaultDrive(Bit8u drive) { if (drive<=DOS_DRIVES && ((drive<2) || Drives[drive])) dos.current_drive = drive; } -bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { +bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { if(!name || *name == 0 || *name == ' ') { /* Both \0 and space are seperators and @@ -60,23 +60,23 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } - + const char * name_int = name; char tempdir[DOS_PATHLENGTH]; char upname[DOS_PATHLENGTH]; Bitu r,w; *drive=dos.current_drive; /* First get the drive */ - if (name[1]==':') { - *drive=(name[0] | 0x20)-'a'; - name+=2; + if (name_int[1]==':') { + *drive=(name_int[0] | 0x20)-'a'; + name_int+=2; } if (*drive>=DOS_DRIVES || !Drives[*drive]) { DOS_SetError(DOSERR_PATH_NOT_FOUND); return false; } r=0;w=0; - while (name[r]!=0 && (r='a') && (c<='z')) {upname[w++]=c-32;continue;} if ((c>='A') && (c<='Z')) {upname[w++]=c;continue;} if ((c>='0') && (c<='9')) {upname[w++]=c;continue;} @@ -105,7 +105,7 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { else fullname[0]=0; Bit32u lastdir=0;Bit32u t=0; while (fullname[t]!=0) { - if ((fullname[t]=='\\') && (fullname[t+1]!=0))lastdir=t; + if ((fullname[t]=='\\') && (fullname[t+1]!=0))lastdir=t; t++; }; r=0;w=0; @@ -144,7 +144,7 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { } } fullname[lastdir]=0; - Bit32u t=0;lastdir=0; + t=0;lastdir=0; while (fullname[t]!=0) { if ((fullname[t]=='\\') && (fullname[t+1]!=0))lastdir=t; t++; @@ -173,7 +173,7 @@ bool DOS_MakeName(char * name,char * fullname,Bit8u * drive) { return true; } -bool DOS_GetCurrentDir(Bit8u drive,char * buffer) { +bool DOS_GetCurrentDir(Bit8u drive,char * const buffer) { if (drive==0) drive=DOS_GetDefaultDrive(); else drive--; if ((drive>DOS_DRIVES) || (!Drives[drive])) { @@ -184,7 +184,7 @@ bool DOS_GetCurrentDir(Bit8u drive,char * buffer) { return true; } -bool DOS_ChangeDir(char * dir) { +bool DOS_ChangeDir(char const * const dir) { Bit8u drive;char fulldir[DOS_PATHLENGTH]; if (!DOS_MakeName(dir,fulldir,&drive)) return false; @@ -197,7 +197,7 @@ bool DOS_ChangeDir(char * dir) { return false; } -bool DOS_MakeDir(char * dir) { +bool DOS_MakeDir(char const * const dir) { Bit8u drive;char fulldir[DOS_PATHLENGTH]; size_t len = strlen(dir); if(!len || dir[len-1] == '\\') { @@ -215,7 +215,7 @@ bool DOS_MakeDir(char * dir) { return false; } -bool DOS_RemoveDir(char * dir) { +bool DOS_RemoveDir(char const * const dir) { /* We need to do the test before the removal as can not rely on * the host to forbid removal of the current directory. * We never change directory. Everything happens in the drives. @@ -243,7 +243,7 @@ bool DOS_RemoveDir(char * dir) { return false; } -bool DOS_Rename(char * oldname,char * newname) { +bool DOS_Rename(char const * const oldname,char const * const newname) { Bit8u driveold;char fullold[DOS_PATHLENGTH]; Bit8u drivenew;char fullnew[DOS_PATHLENGTH]; if (!DOS_MakeName(oldname,fullold,&driveold)) return false; @@ -382,14 +382,14 @@ bool DOS_CloseFile(Bit16u entry) { return true; } -static bool PathExists(char* name) { - char* leading = strrchr(name,'\\'); +static bool PathExists(char const * const name) { + const char* leading = strrchr(name,'\\'); if(!leading) return true; char temp[CROSS_LEN]; strcpy(temp,name); - leading = strrchr(temp,'\\'); - if (leading == temp) return true; - *leading = 0; + char * lead = strrchr(temp,'\\'); + if (lead == temp) return true; + *lead = 0; Bit8u drive;char fulldir[DOS_PATHLENGTH]; if (!DOS_MakeName(temp,fulldir,&drive)) return false; if(!Drives[drive]->TestDir(fulldir)) return false; @@ -397,7 +397,7 @@ static bool PathExists(char* name) { } -bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { +bool DOS_CreateFile(char const * name,Bit16u attributes,Bit16u * entry) { // Creation of a device is the same as opening it // Tc201 installer if (DOS_FindDevice(name) != DOS_DEVICES) @@ -438,14 +438,14 @@ bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { } } -bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { +bool DOS_OpenFile(char const * name,Bit8u flags,Bit16u * entry) { /* First check for devices */ if (flags>2) LOG(LOG_FILES,LOG_ERROR)("Special file open command %X file %s",flags,name); else LOG(LOG_FILES,LOG_NORMAL)("file open command %X file %s",flags,name); DOS_PSP psp(dos.psp()); Bit16u attr = 0; - Bit8u devnum = DOS_FindDevice((char *)name); + Bit8u devnum = DOS_FindDevice(name); bool device = (devnum != DOS_DEVICES); if(!device && DOS_GetFileAttr(name,&attr)) { //DON'T ALLOW directories to be openened.(skip test if file is device). @@ -500,7 +500,7 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { } } -bool DOS_OpenFileExtended(char *name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status) +bool DOS_OpenFileExtended(char const * name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status) // FIXME: Not yet supported : Bit 13 of flags (int 0x24 on critical error { Bit16u result = 0; @@ -526,7 +526,7 @@ bool DOS_OpenFileExtended(char *name, Bit16u flags, Bit16u createAttr, Bit16u ac return true; }; -bool DOS_UnlinkFile(char * name) { +bool DOS_UnlinkFile(char const * const name) { char fullname[DOS_PATHLENGTH];Bit8u drive; if (!DOS_MakeName(name,fullname,&drive)) return false; if(Drives[drive]->FileUnlink(fullname)){ @@ -537,7 +537,7 @@ bool DOS_UnlinkFile(char * name) { } } -bool DOS_GetFileAttr(char * name,Bit16u * attr) { +bool DOS_GetFileAttr(char const * const name,Bit16u * attr) { char fullname[DOS_PATHLENGTH];Bit8u drive; if (!DOS_MakeName(name,fullname,&drive)) return false; if (Drives[drive]->GetFileAttr(fullname,attr)) { @@ -548,7 +548,7 @@ bool DOS_GetFileAttr(char * name,Bit16u * attr) { } } -bool DOS_SetFileAttr(char * name,Bit16u attr) +bool DOS_SetFileAttr(char const * const name,Bit16u attr) // this function does not change the file attributs // it just does some tests if file is available // returns false when using on cdrom (stonekeep) @@ -563,7 +563,7 @@ bool DOS_SetFileAttr(char * name,Bit16u attr) return Drives[drive]->GetFileAttr(fullname,&attrTemp); } -bool DOS_Canonicalize(char * name,char * big) { +bool DOS_Canonicalize(char const * const name,char * const big) { //TODO Add Better support for devices and shit but will it be needed i doubt it :) Bit8u drive; char fullname[DOS_PATHLENGTH]; @@ -638,7 +638,7 @@ bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry) { -bool DOS_CreateTempFile(char * name,Bit16u * entry) { +bool DOS_CreateTempFile(char * const name,Bit16u * entry) { /* First add random crap to the end of the name and try to open */ char * tempname; tempname=name+strlen(name); @@ -775,7 +775,7 @@ savefcb: return ret; } -static void DTAExtendName(char * name,char * filename,char * ext) { +static void DTAExtendName(char * const name,char * const filename,char * const ext) { char * find=strchr(name,'.'); if (find) { strcpy(ext,find+1); @@ -1032,7 +1032,7 @@ void DOS_FCBSetRandomRecord(Bit16u seg, Bit16u offset) { } -bool DOS_FileExists(char * name) { +bool DOS_FileExists(char const * const name) { char fullname[DOS_PATHLENGTH];Bit8u drive; if (!DOS_MakeName(name,fullname,&drive)) return false; return Drives[drive]->FileExists(fullname); @@ -1058,8 +1058,7 @@ bool DOS_SetDrive(Bit8u drive) { } }; -bool DOS_GetFileDate(Bit16u entry, Bit16u* otime, Bit16u* odate) -{ +bool DOS_GetFileDate(Bit16u entry, Bit16u* otime, Bit16u* odate) { Bit32u handle=RealHandle(entry); if (handle>=DOS_FILES) { DOS_SetError(DOSERR_INVALID_HANDLE); diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 79e8af3c..f19b49dc 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -37,7 +37,7 @@ static FILE* OpenDosboxFile(const char* name) { localDrive* ldp=0; // try to build dos name - if (DOS_MakeName((char*)name,fullname,&drive)) { + if (DOS_MakeName(name,fullname,&drive)) { try { // try to open file on mounted drive first ldp=dynamic_cast(Drives[drive]); diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 0fa042f7..9785e879 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -352,7 +352,7 @@ bool DOS_LinkUMBsToMemChain(Bit16u linkstate) { /* Scan MCB-chain for last block before UMB-chain */ Bit16u mcb_segment=dos.firstMCB; - Bit16u prev_mcb_segment; + Bit16u prev_mcb_segment=dos.firstMCB; DOS_MCB mcb(mcb_segment); while ((mcb_segment!=umb_start) && (mcb.GetType()!=0x5a)) { prev_mcb_segment=mcb_segment; diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index e21e7847..5ecf09c2 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.21 2007-06-12 20:22:08 c2woody Exp $ */ +/* $Id: drive_fat.cpp,v 1.22 2007-06-14 08:23:46 qbix79 Exp $ */ #include #include @@ -399,8 +399,8 @@ bool fatDrive::getEntryName(char *fullname, char *entname) { return true; } -bool fatDrive::getFileDirEntry(char * filename, direntry * useEntry, Bit32u * dirClust, Bit32u * subEntry) { - Bit32u len = (Bit32u)strlen(filename); +bool fatDrive::getFileDirEntry(char const * const filename, direntry * useEntry, Bit32u * dirClust, Bit32u * subEntry) { + size_t len = strlen(filename); char dirtoken[DOS_PATHLENGTH]; Bit32u currentClust = 0; @@ -795,7 +795,7 @@ bool fatDrive::FileCreate(DOS_File **file, char *name, Bit16u attributes) { bool fatDrive::FileExists(const char *name) { direntry fileEntry; Bit32u dummy1, dummy2; - if(!getFileDirEntry((char *)name, &fileEntry, &dummy1, &dummy2)) return false; + if(!getFileDirEntry(name, &fileEntry, &dummy1, &dummy2)) return false; return true; } diff --git a/src/dos/drives.h b/src/dos/drives.h index 51d618fd..371cb01b 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.36 2007-01-21 16:21:22 c2woody Exp $ */ +/* $Id: drives.h,v 1.37 2007-06-14 08:23:46 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ @@ -181,7 +181,7 @@ private: Bit32u getClustFirstSect(Bit32u clustNum); bool FindNextInternal(Bit32u dirClustNumber, DOS_DTA & dta, direntry *foundEntry); bool getDirClustNum(char * dir, Bit32u * clustNum, bool parDir); - bool getFileDirEntry(char * filename, direntry * useEntry, Bit32u * dirClust, Bit32u * subEntry); + bool getFileDirEntry(char const * const filename, direntry * useEntry, Bit32u * dirClust, Bit32u * subEntry); bool addDirectoryEntry(Bit32u dirClustNumber, direntry useEntry); void zeroOutCluster(Bit32u clustNumber); bool getEntryName(char *fullname, char *entname); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index ced21783..ec935eb4 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.115 2007-02-22 08:44:06 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.116 2007-06-14 08:23:46 qbix79 Exp $ */ #include #include @@ -420,7 +420,7 @@ void DOSBOX_Init(void) { "tandy -- Enable Tandy Sound System emulation (off,on,auto).\n" " For auto Tandysound emulation is present only if machine is set to tandy.\n" "tandyrate -- Sample rate of the Tandy 3-Voice generation.\n" - "disney -- Enable Disney Sound Source emulation.\n" + "disney -- Enable Disney Sound Source emulation. Covox Voice Master and Speech Thing compatible.\n" ); secprop=control->AddSection_prop("joystick",&BIOS_Init,false);//done diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 08613663..22407130 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -64,11 +64,12 @@ public: next=handler_list; handler_list=this; }; - virtual bool Open(const char * conf) { return true; }; + virtual bool Open(const char * /*conf*/) { return true; }; virtual void Close(void) {}; - virtual void PlayMsg(Bit8u * msg) {}; - virtual void PlaySysex(Bit8u * sysex,Bitu len) {}; - virtual char * GetName(void) { return "none"; }; + virtual void PlayMsg(Bit8u * /*msg*/) {}; + virtual void PlaySysex(Bit8u * /*sysex*/,Bitu /*len*/) {}; + virtual const char * GetName(void) { return "none"; }; + virtual ~MidiHandler() { }; MidiHandler * next; }; @@ -199,7 +200,7 @@ getdefault: static MIDI* test; -void MIDI_Destroy(Section* sec){ +void MIDI_Destroy(Section* /*sec*/){ delete test; } void MIDI_Init(Section * sec) { diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 0219ad87..475a2082 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_alsa.h,v 1.15 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: midi_alsa.h,v 1.16 2007-06-14 08:23:46 qbix79 Exp $ */ #define ALSA_PCM_OLD_HW_PARAMS_API #define ALSA_PCM_OLD_SW_PARAMS_API @@ -50,7 +50,7 @@ private: snd_seq_flush_output(seq_handle); } - int parse_addr(char *arg, int *client, int *port) { + int parse_addr(const char *arg, int *client, int *port) { char *p; if (isdigit(*arg)) { @@ -69,7 +69,7 @@ private: } public: MidiHandler_alsa() : MidiHandler() {}; - char* GetName(void) { return "alsa"; } + const char* GetName(void) { return "alsa"; } void PlaySysex(Bit8u * sysex,Bitu len) { snd_seq_ev_set_sysex(&ev, len, sysex); send_event(1); diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index 8fc00575..923f1615 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -24,7 +24,7 @@ private: AudioUnit m_outputUnit; public: MidiHandler_coreaudio() : m_musicDevice(0), m_outputUnit(0) {} - char * GetName(void) { return "coreaudio"; } + const char * GetName(void) { return "coreaudio"; } bool Open(const char * conf) { int err; AudioUnitConnection auconnect; diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index c4a945ae..b4ae3069 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -26,7 +26,7 @@ private: bool isOpen; public: MidiHandler_oss() : MidiHandler(),isOpen(false) {}; - char * GetName(void) { return "oss";}; + const char * GetName(void) { return "oss";}; bool Open(const char * conf) { char devname[512]; if (conf && conf[0]) safe_strncpy(devname,conf,512); diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index 707d4b6b..e4042a49 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_win32.h,v 1.13 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: midi_win32.h,v 1.14 2007-06-14 08:23:46 qbix79 Exp $ */ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN @@ -34,7 +34,7 @@ private: bool isOpen; public: MidiHandler_win32() : isOpen(false),MidiHandler() {}; - char * GetName(void) { return "win32";}; + const char * GetName(void) { return "win32";}; bool Open(const char * conf) { if (isOpen) return false; m_event = CreateEvent (NULL, true, true, NULL); diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index ad6ae67d..9c45a78d 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -160,188 +160,199 @@ static INLINE void ScalerAddLines( Bitu changed, Bitu count ) { ScalerLineBlock_t ScalerCache = { - Cache_8_8, Cache_8_15, Cache_8_16, Cache_8_32, - 0, Cache_15_15, Cache_15_16, Cache_15_32, - 0, Cache_16_15, Cache_16_16, Cache_16_32, - 0, Cache_32_15, Cache_32_16, Cache_32_32, - Cache_8_8, Cache_9_15, Cache_9_16, Cache_9_32, +{ Cache_8_8, Cache_8_15 , Cache_8_16 , Cache_8_32 }, +{ 0, Cache_15_15, Cache_15_16, Cache_15_32}, +{ 0, Cache_16_15, Cache_16_16, Cache_16_32}, +{ 0, Cache_32_15, Cache_32_16, Cache_32_32}, +{ Cache_8_8, Cache_9_15 , Cache_9_16 , Cache_9_32 } }; ScalerSimpleBlock_t ScaleNormal1x = { "Normal", GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, - 1,1, - Normal1x_8_8_L, Normal1x_8_15_L, Normal1x_8_16_L, Normal1x_8_32_L, - 0, Normal1x_15_15_L, Normal1x_15_16_L, Normal1x_15_32_L, - 0, Normal1x_16_15_L, Normal1x_16_16_L, Normal1x_16_32_L, - 0, Normal1x_32_15_L, Normal1x_32_16_L, Normal1x_32_32_L, - Normal1x_8_8_L, Normal1x_9_15_L, Normal1x_9_16_L, Normal1x_9_32_L, - Normal1x_8_8_R, Normal1x_8_15_R, Normal1x_8_16_R, Normal1x_8_32_R, - 0, Normal1x_15_15_R, Normal1x_15_16_R, Normal1x_15_32_R, - 0, Normal1x_16_15_R, Normal1x_16_16_R, Normal1x_16_32_R, - 0, Normal1x_32_15_R, Normal1x_32_16_R, Normal1x_32_32_R, - Normal1x_8_8_R, Normal1x_9_15_R, Normal1x_9_16_R, Normal1x_9_32_R, -}; + 1,1,{ +{ Normal1x_8_8_L, Normal1x_8_15_L , Normal1x_8_16_L , Normal1x_8_32_L }, +{ 0, Normal1x_15_15_L, Normal1x_15_16_L, Normal1x_15_32_L}, +{ 0, Normal1x_16_15_L, Normal1x_16_16_L, Normal1x_16_32_L}, +{ 0, Normal1x_32_15_L, Normal1x_32_16_L, Normal1x_32_32_L}, +{ Normal1x_8_8_L, Normal1x_9_15_L , Normal1x_9_16_L , Normal1x_9_32_L } +},{ +{ Normal1x_8_8_R, Normal1x_8_15_R , Normal1x_8_16_R , Normal1x_8_32_R }, +{ 0, Normal1x_15_15_R, Normal1x_15_16_R, Normal1x_15_32_R}, +{ 0, Normal1x_16_15_R, Normal1x_16_16_R, Normal1x_16_32_R}, +{ 0, Normal1x_32_15_R, Normal1x_32_16_R, Normal1x_32_32_R}, +{ Normal1x_8_8_R, Normal1x_9_15_R , Normal1x_9_16_R , Normal1x_9_32_R } +}}; ScalerSimpleBlock_t ScaleNormalDw = { "Normal", GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, - 2,1, - NormalDw_8_8_L, NormalDw_8_15_L, NormalDw_8_16_L, NormalDw_8_32_L, - 0, NormalDw_15_15_L, NormalDw_15_16_L, NormalDw_15_32_L, - 0, NormalDw_16_15_L, NormalDw_16_16_L, NormalDw_16_32_L, - 0, NormalDw_32_15_L, NormalDw_32_16_L, NormalDw_32_32_L, - NormalDw_8_8_L, NormalDw_9_15_L, NormalDw_9_16_L, NormalDw_9_32_L, - NormalDw_8_8_R, NormalDw_8_15_R, NormalDw_8_16_R, NormalDw_8_32_R, - 0, NormalDw_15_15_R, NormalDw_15_16_R, NormalDw_15_32_R, - 0, NormalDw_16_15_R, NormalDw_16_16_R, NormalDw_16_32_R, - 0, NormalDw_32_15_R, NormalDw_32_16_R, NormalDw_32_32_R, - NormalDw_8_8_R, NormalDw_9_15_R, NormalDw_9_16_R, NormalDw_9_32_R, -}; + 2,1,{ +{ NormalDw_8_8_L, NormalDw_8_15_L , NormalDw_8_16_L , NormalDw_8_32_L }, +{ 0, NormalDw_15_15_L, NormalDw_15_16_L, NormalDw_15_32_L}, +{ 0, NormalDw_16_15_L, NormalDw_16_16_L, NormalDw_16_32_L}, +{ 0, NormalDw_32_15_L, NormalDw_32_16_L, NormalDw_32_32_L}, +{ NormalDw_8_8_L, NormalDw_9_15_L , NormalDw_9_16_L , NormalDw_9_32_L } +},{ +{ NormalDw_8_8_R, NormalDw_8_15_R , NormalDw_8_16_R , NormalDw_8_32_R }, +{ 0, NormalDw_15_15_R, NormalDw_15_16_R, NormalDw_15_32_R}, +{ 0, NormalDw_16_15_R, NormalDw_16_16_R, NormalDw_16_32_R}, +{ 0, NormalDw_32_15_R, NormalDw_32_16_R, NormalDw_32_32_R}, +{ NormalDw_8_8_R, NormalDw_9_15_R , NormalDw_9_16_R , NormalDw_9_32_R } +}}; ScalerSimpleBlock_t ScaleNormalDh = { "Normal", GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, - 1,2, - NormalDh_8_8_L, NormalDh_8_15_L, NormalDh_8_16_L, NormalDh_8_32_L, - 0, NormalDh_15_15_L, NormalDh_15_16_L, NormalDh_15_32_L, - 0, NormalDh_16_15_L, NormalDh_16_16_L, NormalDh_16_32_L, - 0, NormalDh_32_15_L, NormalDh_32_16_L, NormalDh_32_32_L, - NormalDh_8_8_L, NormalDh_9_15_L, NormalDh_9_16_L, NormalDh_9_32_L, - NormalDh_8_8_R, NormalDh_8_15_R, NormalDh_8_16_R, NormalDh_8_32_R, - 0, NormalDh_15_15_R, NormalDh_15_16_R, NormalDh_15_32_R, - 0, NormalDh_16_15_R, NormalDh_16_16_R, NormalDh_16_32_R, - 0, NormalDh_32_15_R, NormalDh_32_16_R, NormalDh_32_32_R, - NormalDh_8_8_R, NormalDh_9_15_R, NormalDh_9_16_R, NormalDh_9_32_R, -}; + 1,2,{ +{ NormalDh_8_8_L, NormalDh_8_15_L , NormalDh_8_16_L , NormalDh_8_32_L }, +{ 0, NormalDh_15_15_L, NormalDh_15_16_L, NormalDh_15_32_L}, +{ 0, NormalDh_16_15_L, NormalDh_16_16_L, NormalDh_16_32_L}, +{ 0, NormalDh_32_15_L, NormalDh_32_16_L, NormalDh_32_32_L}, +{ NormalDh_8_8_L, NormalDh_9_15_L , NormalDh_9_16_L , NormalDh_9_32_L } +},{ +{ NormalDh_8_8_R, NormalDh_8_15_R , NormalDh_8_16_R , NormalDh_8_32_R }, +{ 0, NormalDh_15_15_R, NormalDh_15_16_R, NormalDh_15_32_R}, +{ 0, NormalDh_16_15_R, NormalDh_16_16_R, NormalDh_16_32_R}, +{ 0, NormalDh_32_15_R, NormalDh_32_16_R, NormalDh_32_32_R}, +{ NormalDh_8_8_R, NormalDh_9_15_R , NormalDh_9_16_R , NormalDh_9_32_R } +}}; ScalerSimpleBlock_t ScaleNormal2x = { "Normal2x", GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, - 2,2, - Normal2x_8_8_L, Normal2x_8_15_L, Normal2x_8_16_L, Normal2x_8_32_L, - 0, Normal2x_15_15_L, Normal2x_15_16_L, Normal2x_15_32_L, - 0, Normal2x_16_15_L, Normal2x_16_16_L, Normal2x_16_32_L, - 0, Normal2x_32_15_L, Normal2x_32_16_L, Normal2x_32_32_L, - Normal2x_8_8_L, Normal2x_9_15_L, Normal2x_9_16_L, Normal2x_9_32_L, - Normal2x_8_8_R, Normal2x_8_15_R, Normal2x_8_16_R, Normal2x_8_32_R, - 0, Normal2x_15_15_R, Normal2x_15_16_R, Normal2x_15_32_R, - 0, Normal2x_16_15_R, Normal2x_16_16_R, Normal2x_16_32_R, - 0, Normal2x_32_15_R, Normal2x_32_16_R, Normal2x_32_32_R, - Normal2x_8_8_R, Normal2x_9_15_R, Normal2x_9_16_R, Normal2x_9_32_R, -}; + 2,2,{ +{ Normal2x_8_8_L, Normal2x_8_15_L, Normal2x_8_16_L, Normal2x_8_32_L }, +{ 0, Normal2x_15_15_L, Normal2x_15_16_L, Normal2x_15_32_L}, +{ 0, Normal2x_16_15_L, Normal2x_16_16_L, Normal2x_16_32_L}, +{ 0, Normal2x_32_15_L, Normal2x_32_16_L, Normal2x_32_32_L}, +{ Normal2x_8_8_L, Normal2x_9_15_L , Normal2x_9_16_L, Normal2x_9_32_L } +},{ +{ Normal2x_8_8_R, Normal2x_8_15_R , Normal2x_8_16_R, Normal2x_8_32_R }, +{ 0, Normal2x_15_15_R, Normal2x_15_16_R, Normal2x_15_32_R}, +{ 0, Normal2x_16_15_R, Normal2x_16_16_R, Normal2x_16_32_R}, +{ 0, Normal2x_32_15_R, Normal2x_32_16_R, Normal2x_32_32_R}, +{ Normal2x_8_8_R, Normal2x_9_15_R , Normal2x_9_16_R, Normal2x_9_32_R }, +}}; ScalerSimpleBlock_t ScaleNormal3x = { "Normal3x", GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, - 3,3, - Normal3x_8_8_L, Normal3x_8_15_L, Normal3x_8_16_L, Normal3x_8_32_L, - 0, Normal3x_15_15_L, Normal3x_15_16_L, Normal3x_15_32_L, - 0, Normal3x_16_15_L, Normal3x_16_16_L, Normal3x_16_32_L, - 0, Normal3x_32_15_L, Normal3x_32_16_L, Normal3x_32_32_L, - Normal3x_8_8_L, Normal3x_9_15_L, Normal3x_9_16_L, Normal3x_9_32_L, - Normal3x_8_8_R, Normal3x_8_15_R, Normal3x_8_16_R, Normal3x_8_32_R, - 0, Normal3x_15_15_R, Normal3x_15_16_R, Normal3x_15_32_R, - 0, Normal3x_16_15_R, Normal3x_16_16_R, Normal3x_16_32_R, - 0, Normal3x_32_15_R, Normal3x_32_16_R, Normal3x_32_32_R, - Normal3x_8_8_R, Normal3x_9_15_R, Normal3x_9_16_R, Normal3x_9_32_R, -}; + 3,3,{ +{ Normal3x_8_8_L, Normal3x_8_15_L , Normal3x_8_16_L , Normal3x_8_32_L }, +{ 0, Normal3x_15_15_L, Normal3x_15_16_L, Normal3x_15_32_L}, +{ 0, Normal3x_16_15_L, Normal3x_16_16_L, Normal3x_16_32_L}, +{ 0, Normal3x_32_15_L, Normal3x_32_16_L, Normal3x_32_32_L}, +{ Normal3x_8_8_L, Normal3x_9_15_L , Normal3x_9_16_L , Normal3x_9_32_L } +},{ +{ Normal3x_8_8_R, Normal3x_8_15_R , Normal3x_8_16_R , Normal3x_8_32_R }, +{ 0, Normal3x_15_15_R, Normal3x_15_16_R, Normal3x_15_32_R}, +{ 0, Normal3x_16_15_R, Normal3x_16_16_R, Normal3x_16_32_R}, +{ 0, Normal3x_32_15_R, Normal3x_32_16_R, Normal3x_32_32_R}, +{ Normal3x_8_8_R, Normal3x_9_15_R , Normal3x_9_16_R , Normal3x_9_32_R } +}}; ScalerSimpleBlock_t ScaleTV2x = { "TV2x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, - 2,2, - 0, TV2x_8_15_L, TV2x_8_16_L, TV2x_8_32_L, - 0, TV2x_15_15_L, TV2x_15_16_L, TV2x_15_32_L, - 0, TV2x_16_15_L, TV2x_16_16_L, TV2x_16_32_L, - 0, TV2x_32_15_L, TV2x_32_16_L, TV2x_32_32_L, - 0, TV2x_9_15_L, TV2x_9_16_L, TV2x_9_32_L, - 0, TV2x_8_15_R, TV2x_8_16_R, TV2x_8_32_R, - 0, TV2x_15_15_R, TV2x_15_16_R, TV2x_15_32_R, - 0, TV2x_16_15_R, TV2x_16_16_R, TV2x_16_32_R, - 0, TV2x_32_15_R, TV2x_32_16_R, TV2x_32_32_R, - 0, TV2x_9_15_R, TV2x_9_16_R, TV2x_9_32_R, -}; + 2,2,{ +{ 0, TV2x_8_15_L , TV2x_8_16_L , TV2x_8_32_L }, +{ 0, TV2x_15_15_L, TV2x_15_16_L, TV2x_15_32_L}, +{ 0, TV2x_16_15_L, TV2x_16_16_L, TV2x_16_32_L}, +{ 0, TV2x_32_15_L, TV2x_32_16_L, TV2x_32_32_L}, +{ 0, TV2x_9_15_L , TV2x_9_16_L , TV2x_9_32_L } +},{ +{ 0, TV2x_8_15_R , TV2x_8_16_R , TV2x_8_32_R }, +{ 0, TV2x_15_15_R, TV2x_15_16_R, TV2x_15_32_R}, +{ 0, TV2x_16_15_R, TV2x_16_16_R, TV2x_16_32_R}, +{ 0, TV2x_32_15_R, TV2x_32_16_R, TV2x_32_32_R}, +{ 0, TV2x_9_15_R , TV2x_9_16_R , TV2x_9_32_R } +}}; ScalerSimpleBlock_t ScaleTV3x = { "TV3x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, - 3,3, - 0, TV3x_8_15_L, TV3x_8_16_L, TV3x_8_32_L, - 0, TV3x_15_15_L, TV3x_15_16_L, TV3x_15_32_L, - 0, TV3x_16_15_L, TV3x_16_16_L, TV3x_16_32_L, - 0, TV3x_32_15_L, TV3x_32_16_L, TV3x_32_32_L, - 0, TV3x_9_15_L, TV3x_9_16_L, TV3x_9_32_L, - 0, TV3x_8_15_R, TV3x_8_16_R, TV3x_8_32_R, - 0, TV3x_15_15_R, TV3x_15_16_R, TV3x_15_32_R, - 0, TV3x_16_15_R, TV3x_16_16_R, TV3x_16_32_R, - 0, TV3x_32_15_R, TV3x_32_16_R, TV3x_32_32_R, - 0, TV3x_9_15_R, TV3x_9_16_R, TV3x_9_32_R, -}; + 3,3,{ +{ 0, TV3x_8_15_L , TV3x_8_16_L , TV3x_8_32_L }, +{ 0, TV3x_15_15_L, TV3x_15_16_L, TV3x_15_32_L}, +{ 0, TV3x_16_15_L, TV3x_16_16_L, TV3x_16_32_L}, +{ 0, TV3x_32_15_L, TV3x_32_16_L, TV3x_32_32_L}, +{ 0, TV3x_9_15_L , TV3x_9_16_L , TV3x_9_32_L } +},{ +{ 0, TV3x_8_15_R , TV3x_8_16_R , TV3x_8_32_R }, +{ 0, TV3x_15_15_R, TV3x_15_16_R, TV3x_15_32_R}, +{ 0, TV3x_16_15_R, TV3x_16_16_R, TV3x_16_32_R}, +{ 0, TV3x_32_15_R, TV3x_32_16_R, TV3x_32_32_R}, +{ 0, TV3x_9_15_R , TV3x_9_16_R , TV3x_9_32_R } +}}; ScalerSimpleBlock_t ScaleScan2x = { "Scan2x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, - 2,2, - 0, Scan2x_8_15_L, Scan2x_8_16_L, Scan2x_8_32_L, - 0, Scan2x_15_15_L, Scan2x_15_16_L, Scan2x_15_32_L, - 0, Scan2x_16_15_L, Scan2x_16_16_L, Scan2x_16_32_L, - 0, Scan2x_32_15_L, Scan2x_32_16_L, Scan2x_32_32_L, - 0, Scan2x_9_15_L, Scan2x_9_16_L, Scan2x_9_32_L, - 0, Scan2x_8_15_R, Scan2x_8_16_R, Scan2x_8_32_R, - 0, Scan2x_15_15_R, Scan2x_15_16_R, Scan2x_15_32_R, - 0, Scan2x_16_15_R, Scan2x_16_16_R, Scan2x_16_32_R, - 0, Scan2x_32_15_R, Scan2x_32_16_R, Scan2x_32_32_R, - 0, Scan2x_9_15_R, Scan2x_9_16_R, Scan2x_9_32_R, -}; + 2,2,{ +{ 0, Scan2x_8_15_L , Scan2x_8_16_L , Scan2x_8_32_L }, +{ 0, Scan2x_15_15_L, Scan2x_15_16_L, Scan2x_15_32_L}, +{ 0, Scan2x_16_15_L, Scan2x_16_16_L, Scan2x_16_32_L}, +{ 0, Scan2x_32_15_L, Scan2x_32_16_L, Scan2x_32_32_L}, +{ 0, Scan2x_9_15_L , Scan2x_9_16_L , Scan2x_9_32_L } +},{ +{ 0, Scan2x_8_15_R , Scan2x_8_16_R , Scan2x_8_32_R }, +{ 0, Scan2x_15_15_R, Scan2x_15_16_R, Scan2x_15_32_R}, +{ 0, Scan2x_16_15_R, Scan2x_16_16_R, Scan2x_16_32_R}, +{ 0, Scan2x_32_15_R, Scan2x_32_16_R, Scan2x_32_32_R}, +{ 0, Scan2x_9_15_R , Scan2x_9_16_R , Scan2x_9_32_R } +}}; ScalerSimpleBlock_t ScaleScan3x = { "Scan3x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, - 3,3, - 0, Scan3x_8_15_L, Scan3x_8_16_L, Scan3x_8_32_L, - 0, Scan3x_15_15_L, Scan3x_15_16_L, Scan3x_15_32_L, - 0, Scan3x_16_15_L, Scan3x_16_16_L, Scan3x_16_32_L, - 0, Scan3x_32_15_L, Scan3x_32_16_L, Scan3x_32_32_L, - 0, Scan3x_9_15_L, Scan3x_9_16_L, Scan3x_9_32_L, - 0, Scan3x_8_15_R, Scan3x_8_16_R, Scan3x_8_32_R, - 0, Scan3x_15_15_R, Scan3x_15_16_R, Scan3x_15_32_R, - 0, Scan3x_16_15_R, Scan3x_16_16_R, Scan3x_16_32_R, - 0, Scan3x_32_15_R, Scan3x_32_16_R, Scan3x_32_32_R, - 0, Scan3x_9_15_R, Scan3x_9_16_R, Scan3x_9_32_R, -}; + 3,3,{ +{ 0, Scan3x_8_15_L , Scan3x_8_16_L , Scan3x_8_32_L }, +{ 0, Scan3x_15_15_L, Scan3x_15_16_L, Scan3x_15_32_L}, +{ 0, Scan3x_16_15_L, Scan3x_16_16_L, Scan3x_16_32_L}, +{ 0, Scan3x_32_15_L, Scan3x_32_16_L, Scan3x_32_32_L}, +{ 0, Scan3x_9_15_L , Scan3x_9_16_L , Scan3x_9_32_L }, +},{ +{ 0, Scan3x_8_15_R , Scan3x_8_16_R , Scan3x_8_32_R }, +{ 0, Scan3x_15_15_R, Scan3x_15_16_R, Scan3x_15_32_R}, +{ 0, Scan3x_16_15_R, Scan3x_16_16_R, Scan3x_16_32_R}, +{ 0, Scan3x_32_15_R, Scan3x_32_16_R, Scan3x_32_32_R}, +{ 0, Scan3x_9_15_R , Scan3x_9_16_R , Scan3x_9_32_R } +}}; ScalerSimpleBlock_t ScaleRGB2x = { "RGB2x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, - 2,2, - 0, RGB2x_8_15_L, RGB2x_8_16_L, RGB2x_8_32_L, - 0, RGB2x_15_15_L, RGB2x_15_16_L, RGB2x_15_32_L, - 0, RGB2x_16_15_L, RGB2x_16_16_L, RGB2x_16_32_L, - 0, RGB2x_32_15_L, RGB2x_32_16_L, RGB2x_32_32_L, - 0, RGB2x_9_15_L, RGB2x_9_16_L, RGB2x_9_32_L, - 0, RGB2x_8_15_R, RGB2x_8_16_R, RGB2x_8_32_R, - 0, RGB2x_15_15_R, RGB2x_15_16_R, RGB2x_15_32_R, - 0, RGB2x_16_15_R, RGB2x_16_16_R, RGB2x_16_32_R, - 0, RGB2x_32_15_R, RGB2x_32_16_R, RGB2x_32_32_R, - 0, RGB2x_9_15_R, RGB2x_9_16_R, RGB2x_9_32_R, -}; + 2,2,{ +{ 0, RGB2x_8_15_L , RGB2x_8_16_L , RGB2x_8_32_L }, +{ 0, RGB2x_15_15_L, RGB2x_15_16_L, RGB2x_15_32_L}, +{ 0, RGB2x_16_15_L, RGB2x_16_16_L, RGB2x_16_32_L}, +{ 0, RGB2x_32_15_L, RGB2x_32_16_L, RGB2x_32_32_L}, +{ 0, RGB2x_9_15_L , RGB2x_9_16_L , RGB2x_9_32_L } +},{ +{ 0, RGB2x_8_15_R , RGB2x_8_16_R , RGB2x_8_32_R }, +{ 0, RGB2x_15_15_R, RGB2x_15_16_R, RGB2x_15_32_R}, +{ 0, RGB2x_16_15_R, RGB2x_16_16_R, RGB2x_16_32_R}, +{ 0, RGB2x_32_15_R, RGB2x_32_16_R, RGB2x_32_32_R}, +{ 0, RGB2x_9_15_R , RGB2x_9_16_R , RGB2x_9_32_R } +}}; ScalerSimpleBlock_t ScaleRGB3x = { "RGB3x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, - 3,3, - 0, RGB3x_8_15_L, RGB3x_8_16_L, RGB3x_8_32_L, - 0, RGB3x_15_15_L, RGB3x_15_16_L, RGB3x_15_32_L, - 0, RGB3x_16_15_L, RGB3x_16_16_L, RGB3x_16_32_L, - 0, RGB3x_32_15_L, RGB3x_32_16_L, RGB3x_32_32_L, - 0, RGB3x_9_15_L, RGB3x_9_16_L, RGB3x_9_32_L, - 0, RGB3x_8_15_R, RGB3x_8_16_R, RGB3x_8_32_R, - 0, RGB3x_15_15_R, RGB3x_15_16_R, RGB3x_15_32_R, - 0, RGB3x_16_15_R, RGB3x_16_16_R, RGB3x_16_32_R, - 0, RGB3x_32_15_R, RGB3x_32_16_R, RGB3x_32_32_R, - 0, RGB3x_9_15_R, RGB3x_9_16_R, RGB3x_9_32_R, -}; + 3,3,{ +{ 0, RGB3x_8_15_L , RGB3x_8_16_L , RGB3x_8_32_L }, +{ 0, RGB3x_15_15_L, RGB3x_15_16_L, RGB3x_15_32_L}, +{ 0, RGB3x_16_15_L, RGB3x_16_16_L, RGB3x_16_32_L}, +{ 0, RGB3x_32_15_L, RGB3x_32_16_L, RGB3x_32_32_L}, +{ 0, RGB3x_9_15_L , RGB3x_9_16_L , RGB3x_9_32_L } +},{ +{ 0, RGB3x_8_15_R , RGB3x_8_16_R , RGB3x_8_32_R }, +{ 0, RGB3x_15_15_R, RGB3x_15_16_R, RGB3x_15_32_R}, +{ 0, RGB3x_16_15_R, RGB3x_16_16_R, RGB3x_16_32_R}, +{ 0, RGB3x_32_15_R, RGB3x_32_16_R, RGB3x_32_32_R}, +{ 0, RGB3x_9_15_R , RGB3x_9_16_R , RGB3x_9_32_R } +}}; /* Complex scalers */ @@ -350,16 +361,16 @@ ScalerComplexBlock_t ScaleAdvMame2x ={ "AdvMame2x", GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, 2,2, - AdvMame2x_8_L,AdvMame2x_16_L,AdvMame2x_16_L,AdvMame2x_32_L, - AdvMame2x_8_R,AdvMame2x_16_R,AdvMame2x_16_R,AdvMame2x_32_R +{ AdvMame2x_8_L,AdvMame2x_16_L,AdvMame2x_16_L,AdvMame2x_32_L}, +{ AdvMame2x_8_R,AdvMame2x_16_R,AdvMame2x_16_R,AdvMame2x_32_R} }; ScalerComplexBlock_t ScaleAdvMame3x = { "AdvMame3x", GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, 3,3, - AdvMame3x_8_L,AdvMame3x_16_L,AdvMame3x_16_L,AdvMame3x_32_L, - AdvMame3x_8_R,AdvMame3x_16_R,AdvMame3x_16_R,AdvMame3x_32_R +{ AdvMame3x_8_L,AdvMame3x_16_L,AdvMame3x_16_L,AdvMame3x_32_L}, +{ AdvMame3x_8_R,AdvMame3x_16_R,AdvMame3x_16_R,AdvMame3x_32_R} }; /* These need specific 15bpp versions */ @@ -367,56 +378,56 @@ ScalerComplexBlock_t ScaleHQ2x ={ "HQ2x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 2,2, - 0,HQ2x_16_L,HQ2x_16_L,HQ2x_32_L, - 0,HQ2x_16_R,HQ2x_16_R,HQ2x_32_R +{ 0,HQ2x_16_L,HQ2x_16_L,HQ2x_32_L}, +{ 0,HQ2x_16_R,HQ2x_16_R,HQ2x_32_R} }; ScalerComplexBlock_t ScaleHQ3x ={ "HQ3x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 3,3, - 0,HQ3x_16_L,HQ3x_16_L,HQ3x_32_L, - 0,HQ3x_16_R,HQ3x_16_R,HQ3x_32_R +{ 0,HQ3x_16_L,HQ3x_16_L,HQ3x_32_L}, +{ 0,HQ3x_16_R,HQ3x_16_R,HQ3x_32_R} }; ScalerComplexBlock_t ScaleSuper2xSaI ={ "Super2xSaI", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 2,2, - 0,Super2xSaI_16_L,Super2xSaI_16_L,Super2xSaI_32_L, - 0,Super2xSaI_16_R,Super2xSaI_16_R,Super2xSaI_32_R +{ 0,Super2xSaI_16_L,Super2xSaI_16_L,Super2xSaI_32_L}, +{ 0,Super2xSaI_16_R,Super2xSaI_16_R,Super2xSaI_32_R} }; ScalerComplexBlock_t Scale2xSaI ={ "2xSaI", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 2,2, - 0,_2xSaI_16_L,_2xSaI_16_L,_2xSaI_32_L, - 0,_2xSaI_16_R,_2xSaI_16_R,_2xSaI_32_R +{ 0,_2xSaI_16_L,_2xSaI_16_L,_2xSaI_32_L}, +{ 0,_2xSaI_16_R,_2xSaI_16_R,_2xSaI_32_R} }; ScalerComplexBlock_t ScaleSuperEagle ={ "SuperEagle", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 2,2, - 0,SuperEagle_16_L,SuperEagle_16_L,SuperEagle_32_L, - 0,SuperEagle_16_R,SuperEagle_16_R,SuperEagle_32_R +{ 0,SuperEagle_16_L,SuperEagle_16_L,SuperEagle_32_L}, +{ 0,SuperEagle_16_R,SuperEagle_16_R,SuperEagle_32_R} }; ScalerComplexBlock_t ScaleAdvInterp2x = { "AdvInterp2x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 2,2, - 0,AdvInterp2x_15_L,AdvInterp2x_16_L,AdvInterp2x_32_L, - 0,AdvInterp2x_15_R,AdvInterp2x_16_R,AdvInterp2x_32_R +{ 0,AdvInterp2x_15_L,AdvInterp2x_16_L,AdvInterp2x_32_L}, +{ 0,AdvInterp2x_15_R,AdvInterp2x_16_R,AdvInterp2x_32_R} }; ScalerComplexBlock_t ScaleAdvInterp3x = { "AdvInterp3x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, 3,3, - 0,AdvInterp3x_15_L,AdvInterp3x_16_L,AdvInterp3x_32_L, - 0,AdvInterp3x_15_R,AdvInterp3x_16_R,AdvInterp3x_32_R +{ 0,AdvInterp3x_15_L,AdvInterp3x_16_L,AdvInterp3x_32_L}, +{ 0,AdvInterp3x_15_R,AdvInterp3x_16_R,AdvInterp3x_32_R} }; diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index 9fe6691d..3f2b34db 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -71,7 +71,7 @@ extern scalerChangeCache_t scalerChangeCache; typedef ScalerLineHandler_t ScalerLineBlock_t[5][4]; typedef struct { - char *name; + const char *name; Bitu gfxFlags; Bitu xscale,yscale; ScalerComplexHandler_t Linear[4]; @@ -79,7 +79,7 @@ typedef struct { } ScalerComplexBlock_t; typedef struct { - char *name; + const char *name; Bitu gfxFlags; Bitu xscale,yscale; ScalerLineBlock_t Linear; diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index fd93ff00..64c0743c 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: memory.cpp,v 1.49 2007-06-12 19:17:43 qbix79 Exp $ */ +/* $Id: memory.cpp,v 1.50 2007-06-14 08:23:46 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -157,14 +157,14 @@ void mem_memcpy(PhysPt dest,PhysPt src,Bitu size) { } void MEM_BlockRead(PhysPt pt,void * data,Bitu size) { - Bit8u * write=(Bit8u *) data; + Bit8u * write=reinterpret_cast(data); while (size--) { *write++=mem_readb_inline(pt++); } } -void MEM_BlockWrite(PhysPt pt,void * data,Bitu size) { - Bit8u * read=(Bit8u *) data; +void MEM_BlockWrite(PhysPt pt,void const * const data,Bitu size) { + Bit8u const * read = reinterpret_cast(data); while (size--) { mem_writeb_inline(pt++,*read++); } diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index e1a2fb47..ff705b00 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.63 2007-02-24 21:07:22 c2woody Exp $ */ +/* $Id: sblaster.cpp,v 1.64 2007-06-14 08:23:46 qbix79 Exp $ */ #include #include @@ -158,7 +158,7 @@ struct SB_INFO { static SB_INFO sb; -static char * copyright_string="COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; +static char const * const copyright_string="COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; static Bit8u DSP_cmd_len[256] = { // 0,0,0,0, 1,2,0,0, 0,0,0,0, 0,0,2,1, // 0x00 for SB16. but breaks sbpro @@ -534,7 +534,7 @@ static void DSP_RaiseIRQEvent(Bitu val) { } static void DSP_DoDMATransfer(DMA_MODES mode,Bitu freq,bool stereo) { - char * type; + char const * type; sb.mode=MODE_DMA_MASKED; sb.chan->FillUp(); sb.dma.left=sb.dma.total; @@ -847,7 +847,7 @@ static void DSP_DoCommand(void) { case 0xe3: /* DSP Copyright */ { DSP_FlushData(); - for (Bit32u i=0;i<=strlen(copyright_string);i++) { + for (size_t i=0;i<=strlen(copyright_string);i++) { DSP_AddData(copyright_string[i]); } } diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 9dbc928c..139f44e9 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.38 2007-01-08 19:45:41 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.39 2007-06-14 08:23:46 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -252,6 +252,14 @@ void Config::Init() { (*tel)->ExecuteInit(); } } +void Section::AddInitFunction(SectionFunction func,bool canchange) { + initfunctions.push_back(Function_wrapper(func,canchange)); +} + +void Section::AddDestroyFunction(SectionFunction func,bool canchange) { + destroyfunctions.push_front(Function_wrapper(func,canchange)); +} + void Section::ExecuteInit(bool initall) { typedef std::list::iterator func_it; diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 417d1d32..2eccad01 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.84 2007-02-22 08:34:10 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.85 2007-06-14 08:23:46 qbix79 Exp $ */ #include #include @@ -420,10 +420,10 @@ void AUTOEXEC_Init(Section * sec) { test = new AUTOEXEC(sec); } -static char * path_string="PATH=Z:\\"; -static char * comspec_string="COMSPEC=Z:\\COMMAND.COM"; -static char * full_name="Z:\\COMMAND.COM"; -static char * init_line="/INIT AUTOEXEC.BAT"; +static char const * const path_string="PATH=Z:\\"; +static char const * const comspec_string="COMSPEC=Z:\\COMMAND.COM"; +static char const * const full_name="Z:\\COMMAND.COM"; +static char const * const init_line="/INIT AUTOEXEC.BAT"; void SHELL_Init() { /* Add messages */ diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index afd882ea..14fd0ad8 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.75 2007-06-12 20:22:09 c2woody Exp $ */ +/* $Id: shell_cmds.cpp,v 1.76 2007-06-14 08:23:46 qbix79 Exp $ */ #include #include @@ -62,18 +62,22 @@ static SHELL_Cmd cmd_list[]={ { "PATH", 1, &DOS_Shell::CMD_PATH, "SHELL_CMD_PATH_HELP"}, { "VER", 0, &DOS_Shell::CMD_VER, "SHELL_CMD_VER_HELP"}, {0,0,0,0} -}; -bool DOS_Shell::CheckConfig(char* cmd,char*line) { - Section* test = control->GetSectionFromProperty(cmd); +}; + +static char empty_char = 0; +static char* empty_string = &empty_char; + +bool DOS_Shell::CheckConfig(char* cmd_in,char*line) { + Section* test = control->GetSectionFromProperty(cmd_in); if(!test) return false; if(line && !line[0]) { - char const* val = test->GetPropValue(cmd); + char const* val = test->GetPropValue(cmd_in); if(val) WriteOut("%s\n",val); return true; } char newcom[1024]; newcom[0] = 0; strcpy(newcom,"z:\\config "); strcat(newcom,test->GetName()); strcat(newcom," "); - strcat(newcom,cmd);strcat(newcom,line); + strcat(newcom,cmd_in);strcat(newcom,line); DoCommand(newcom); return true; } @@ -81,8 +85,8 @@ bool DOS_Shell::CheckConfig(char* cmd,char*line) { void DOS_Shell::DoCommand(char * line) { /* First split the line into command and arguments */ line=trim(line); - char cmd[CMD_MAXLINE]; - char * cmd_write=cmd; + char cmd_buffer[CMD_MAXLINE]; + char * cmd_write=cmd_buffer; while (*line) { if (*line==32) break; if (*line=='/') break; @@ -92,7 +96,7 @@ void DOS_Shell::DoCommand(char * line) { *cmd_write=0; Bit32u cmd_index=0; while (cmd_list[cmd_index].name) { - if (strcasecmp(cmd_list[cmd_index].name,cmd)==0) { + if (strcasecmp(cmd_list[cmd_index].name,cmd_buffer)==0) { (this->*(cmd_list[cmd_index].handler))(line); return; } @@ -102,20 +106,20 @@ void DOS_Shell::DoCommand(char * line) { *cmd_write++=*line++; } *cmd_write=0; - if (strlen(cmd)==0) return; + if (strlen(cmd_buffer)==0) return; /* Check the internal list */ Bit32u cmd_index=0; while (cmd_list[cmd_index].name) { - if (strcasecmp(cmd_list[cmd_index].name,cmd)==0) { + if (strcasecmp(cmd_list[cmd_index].name,cmd_buffer)==0) { (this->*(cmd_list[cmd_index].handler))(line); return; } cmd_index++; } /* This isn't an internal command execute it */ - if(Execute(cmd,line)) return; - if(CheckConfig(cmd,line)) return; - WriteOut(MSG_Get("SHELL_EXECUTE_ILLEGAL_COMMAND"),cmd); + if(Execute(cmd_buffer,line)) return; + if(CheckConfig(cmd_buffer,line)) return; + WriteOut(MSG_Get("SHELL_EXECUTE_ILLEGAL_COMMAND"),cmd_buffer); } #define HELP(command) \ @@ -183,7 +187,7 @@ void DOS_Shell::CMD_HELP(char * args){ while (cmd_list[cmd_index].name) { if (optall || !cmd_list[cmd_index].flags) { WriteOut("<\033[34;1m%-8s\033[0m> %s",cmd_list[cmd_index].name,MSG_Get(cmd_list[cmd_index].help)); - if(!(++write_count%22)) CMD_PAUSE(""); + if(!(++write_count%22)) CMD_PAUSE(empty_string); } cmd_index++; } @@ -198,8 +202,9 @@ void DOS_Shell::CMD_RENAME(char * args){ char* slash = strrchr(arg1,'\\'); if(slash) { slash++; - //If directory specified (crystal caves installer) - // rename from c:\X : rename c:\abc.exe abc.shr. File must appear in C:\ + /* If directory specified (crystal caves installer) + * rename from c:\X : rename c:\abc.exe abc.shr. + * File must appear in C:\ */ char dir_source[DOS_PATHLENGTH]={0}; //Copy first and then modify, makes GCC happy @@ -331,7 +336,7 @@ void DOS_Shell::CMD_DIR(char * args) { } bool optW=ScanCMDBool(args,"W"); - bool optS=ScanCMDBool(args,"S"); + ScanCMDBool(args,"S"); bool optP=ScanCMDBool(args,"P"); bool optAD=ScanCMDBool(args,"AD"); char * rem=ScanCMDRemain(args); @@ -398,12 +403,12 @@ void DOS_Shell::CMD_DIR(char * args) { /* Skip non-directories if option AD is present */ if(optAD && !(attr&DOS_ATTR_DIRECTORY) ) continue; - - char * ext=""; + + char * ext = empty_string; if (!optW && (name[0] != '.')) { ext = strrchr(name, '.'); - if (!ext) ext = ""; - else *ext++ = '\0'; + if (!ext) ext = empty_string; + else *ext++ = 0; } Bit8u day = (Bit8u)(date & 0x001f); Bit8u month = (Bit8u)((date >> 5) & 0x000f); @@ -435,7 +440,7 @@ void DOS_Shell::CMD_DIR(char * args) { } if(optP) { if(!(++p_count%(22*w_size))) { - CMD_PAUSE(""); + CMD_PAUSE(empty_string); } } } while ( (ret=DOS_FindNext()) ); From bc067b875289b393313c0c074afa615056912b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 14 Jun 2007 17:47:25 +0000 Subject: [PATCH 2801/4131] minor cleanup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2887 --- src/cpu/core_dyn_x86/dyn_fpu.h | 4 +- src/cpu/core_dyn_x86/dyn_fpu_dh.h | 4 +- src/cpu/core_dynrec.cpp | 2 +- src/cpu/core_dynrec/cache.h | 2 +- src/cpu/core_dynrec/decoder.h | 2 +- src/cpu/core_dynrec/decoder_basic.h | 2 +- src/cpu/core_dynrec/decoder_opcodes.h | 2 +- src/cpu/core_dynrec/dyn_fpu.h | 2 +- src/cpu/core_dynrec/operators.h | 2 +- src/cpu/core_dynrec/risc_x64.h | 79 +++++---------------------- src/cpu/core_dynrec/risc_x86.h | 37 +++++-------- 11 files changed, 41 insertions(+), 97 deletions(-) diff --git a/src/cpu/core_dyn_x86/dyn_fpu.h b/src/cpu/core_dyn_x86/dyn_fpu.h index cabfeb83..06e3efe0 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu.h +++ b/src/cpu/core_dyn_x86/dyn_fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dyn_fpu.h,v 1.2 2006-09-19 16:27:58 c2woody Exp $ */ +/* $Id: dyn_fpu.h,v 1.3 2007-06-14 17:47:24 c2woody Exp $ */ #include "dosbox.h" #if C_FPU diff --git a/src/cpu/core_dyn_x86/dyn_fpu_dh.h b/src/cpu/core_dyn_x86/dyn_fpu_dh.h index 17af7d1f..a769e3dc 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu_dh.h +++ b/src/cpu/core_dyn_x86/dyn_fpu_dh.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dyn_fpu_dh.h,v 1.3 2007-06-12 20:22:07 c2woody Exp $ */ +/* $Id: dyn_fpu_dh.h,v 1.4 2007-06-14 17:47:24 c2woody Exp $ */ #include "dosbox.h" #if C_FPU diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index 0cc2cbf6..33d783eb 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index 6fdc537b..5a7d40a2 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h index ffa6faa3..13c47b41 100644 --- a/src/cpu/core_dynrec/decoder.h +++ b/src/cpu/core_dynrec/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index afb606bb..d0cd4e2a 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index 4fd7d76a..7ebe59a5 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_dynrec/dyn_fpu.h b/src/cpu/core_dynrec/dyn_fpu.h index 4f042e89..6d7ad518 100644 --- a/src/cpu/core_dynrec/dyn_fpu.h +++ b/src/cpu/core_dynrec/dyn_fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2005 The DOSBox Team + * 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 diff --git a/src/cpu/core_dynrec/operators.h b/src/cpu/core_dynrec/operators.h index 03aa714c..221f8b89 100644 --- a/src/cpu/core_dynrec/operators.h +++ b/src/cpu/core_dynrec/operators.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index c18e31c9..aa7bc2b9 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -88,16 +88,15 @@ static INLINE void gen_memaddr(HostReg reg,void* data) { // move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg -// 16bit moves must preserve the upper 16bit of the destination register +// 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { if (!dword) cache_addb(0x66); cache_addb(0x8b); // mov reg,[data] gen_memaddr(dest_reg,data); } - // move a 16bit constant value into dest_reg -// the upper 16bit of the destination register must be preserved +// the upper 16bit of the destination register may be destroyed static void gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { cache_addb(0x66); cache_addb(0xb8+dest_reg); // mov reg,imm @@ -118,16 +117,18 @@ static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { } // move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register must be preserved +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { cache_addb(0x8a); // mov reg,[data] gen_memaddr(dest_reg,data); } // move an 8bit value from memory into dest_reg -// the upper 16bit of the destination register must be preserved -// this function is allowed to load 16bit from memory as well if the host architecture -// does not provide 8bit register access for function parameter operands (FC_OP1/FC_OP2) +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { cache_addb(0x66); cache_addb(0x8b); // mov reg,[data] @@ -135,16 +136,18 @@ static void gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { } // move an 8bit constant value into dest_reg -// the upper 16bit of the destination register must be preserved +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { cache_addb(0xb0+dest_reg); // mov reg,imm cache_addb(imm); } // move an 8bit constant value into dest_reg -// the upper 16bit of the destination register must be preserved -// this function is allowed to load 16bit from memory as well if the host architecture -// does not provide 8bit register access for function parameter operands (FC_OP1/FC_OP2) +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { cache_addb(0x66); cache_addb(0xb8+dest_reg); // mov reg,imm @@ -239,27 +242,6 @@ static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { if (dword) cache_addd((Bit32u)imm); else cache_addw((Bit16u)imm); } -/* -// add an 8bit constant value to a memory value -static void gen_add_direct_byte(void* dest,Bit8s imm) { - cache_addb(0x83); // add [data],imm - gen_memaddr(0,dest,1); - cache_addb(imm); -} - -// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value -static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { - if ((imm<128) && dword) { - gen_add_direct_byte(dest,(Bit8s)imm); - return; - } - if (!dword) cache_addb(0x66); - cache_addw(0x81); // add [data],imm - gen_memaddr(0,dest,dword?1:2); - if (dword) cache_addd((Bit32u)imm); - else cache_addw((Bit16u)imm); -} -*/ // subtract an 8bit constant value from a memory value static void gen_sub_direct_byte(void* dest,Bit8s imm) { @@ -282,27 +264,7 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { if (dword) cache_addd((Bit32u)imm); else cache_addw((Bit16u)imm); } -/* -// subtract an 8bit constant value from a memory value -static void gen_sub_direct_byte(void* dest,Bit8s imm) { - cache_addb(0x83); // sub [data],imm - gen_memaddr(5,dest,1); - cache_addb(imm); -} -// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value -static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { - if ((imm<128) && dword) { - gen_sub_direct_byte(dest,(Bit8s)imm); - return; - } - if (!dword) cache_addb(0x66); - cache_addb(0x81); // sub [data],imm - gen_memaddr(5,dest,dword?1:2); - if (dword) cache_addd((Bit32u)imm); - else cache_addw((Bit16u)imm); -} -*/ // effective address calculation, destination is dest_reg @@ -569,17 +531,6 @@ static Bit64u gen_create_branch_on_nonzero(HostReg reg,bool dword) { return ((Bit64u)cache.pos-1); } -// short conditional jump (+-127 bytes) if register -// (as set by a boolean operation) is nonzero -// the destination is set by gen_fill_branch() later -static Bit64u gen_create_branch_on_nonzero_bool(HostReg reg) { - cache_addb(0x0a); // or reg,reg - cache_addb(0xc0+reg+(reg<<3)); - - cache_addw(0x0075); // jnz addr - return ((Bit64u)cache.pos-1); -} - // calculate relative offset and fill it into the location pointed to by data static void gen_fill_branch(DRC_PTR_SIZE_IM data) { #if C_DEBUG diff --git a/src/cpu/core_dynrec/risc_x86.h b/src/cpu/core_dynrec/risc_x86.h index dc47aca3..98dd3b60 100644 --- a/src/cpu/core_dynrec/risc_x86.h +++ b/src/cpu/core_dynrec/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2006 The DOSBox Team + * 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 @@ -79,7 +79,7 @@ static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { } // move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg -// 16bit moves must preserve the upper 16bit of the destination register +// 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { if (!dword) cache_addb(0x66); cache_addw(0x058b+(dest_reg<<11)); // mov reg,[data] @@ -87,7 +87,7 @@ static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { } // move a 16bit constant value into dest_reg -// the upper 16bit of the destination register must be preserved +// the upper 16bit of the destination register may be destroyed static void gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { cache_addb(0x66); cache_addb(0xb8+dest_reg); // mov reg,imm @@ -108,16 +108,18 @@ static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { } // move an 8bit value from memory into dest_reg -// the upper 16bit of the destination register must be preserved +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { cache_addw(0x058a+(dest_reg<<11)); // mov reg,[data] cache_addd((Bit32u)data); } // move an 8bit value from memory into dest_reg -// the upper 16bit of the destination register must be preserved -// this function is allowed to load 16bit from memory as well if the host architecture -// does not provide 8bit register access for function parameter operands (FC_OP1/FC_OP2) +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { cache_addb(0x66); cache_addw(0x058b+(dest_reg<<11)); // mov reg,[data] @@ -125,16 +127,18 @@ static void gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { } // move an 8bit constant value into dest_reg -// the upper 16bit of the destination register must be preserved +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { cache_addb(0xb0+dest_reg); // mov reg,imm cache_addb(imm); } // move an 8bit constant value into dest_reg -// the upper 16bit of the destination register must be preserved -// this function is allowed to load 16bit from memory as well if the host architecture -// does not provide 8bit register access for function parameter operands (FC_OP1/FC_OP2) +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { cache_addb(0x66); cache_addb(0xb8+dest_reg); // mov reg,imm @@ -369,17 +373,6 @@ static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { return ((Bit32u)cache.pos-1); } -// short conditional jump (+-127 bytes) if register -// (as set by a boolean operation) is nonzero -// the destination is set by gen_fill_branch() later -static Bit32u gen_create_branch_on_nonzero_bool(HostReg reg) { - cache_addb(0x0a); // or reg,reg - cache_addb(0xc0+reg+(reg<<3)); - - cache_addw(0x0075); // jnz addr - return ((Bit32u)cache.pos-1); -} - // calculate relative offset and fill it into the location pointed to by data static void gen_fill_branch(DRC_PTR_SIZE_IM data) { #if C_DEBUG From 1773cb623fd94acd0da56c394ae70c7c59406781 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 14 Jun 2007 18:06:59 +0000 Subject: [PATCH 2802/4131] Change dma routine a bit. allow games in autoinit mode to fill dma buffer at the last moment. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2888 --- src/hardware/sblaster.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index ff705b00..f90a6598 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.64 2007-06-14 08:23:46 qbix79 Exp $ */ +/* $Id: sblaster.cpp,v 1.65 2007-06-14 18:06:59 qbix79 Exp $ */ #include #include @@ -355,9 +355,11 @@ INLINE Bit8u decode_ADPCM_3_sample(Bit8u sample,Bit8u & reference,Bits& scale) { static void GenerateDMASound(Bitu size) { Bitu read=0;Bitu done=0;Bitu i=0; - if (sb.dma.left<=sb.dma.min) { - size=sb.dma.left; - } + + if(sb.dma.autoinit) { + if (sb.dma.left <= size) size = sb.dma.left; + } else if (sb.dma.left <= sb.dma.min) size = sb.dma.left; + switch (sb.dma.mode) { case DSP_DMA_2: read=sb.dma.chan->Read(size,sb.dma.buf.b8); From 3d1ac8d7f03cfb7510184671f9e1da825c9660c0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 14 Jun 2007 18:47:27 +0000 Subject: [PATCH 2803/4131] Make valgrind happy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2889 --- src/gui/sdl_mapper.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index dc091b0b..142ba1a1 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.34 2007-04-18 16:40:48 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.35 2007-06-14 18:47:27 qbix79 Exp $ */ #include #include @@ -630,6 +630,7 @@ public: sdl_joystick=SDL_JoystickOpen(_stick); if (sdl_joystick==NULL) { axes=0; buttons=0; hats=0; + button_wrap=0; return; } axes=SDL_JoystickNumAxes(sdl_joystick); From 7d2d97e148208ef20a2acf5b8f0518c6decf8f43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 15 Jun 2007 19:05:48 +0000 Subject: [PATCH 2804/4131] enable hidden-flag to be returned by getattrib (cdrom images only; fixes Player Manager 2 extra cdrom check) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2890 --- src/dos/drive_iso.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 7ed9962c..9ad4a3ca 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.19 2007-06-13 07:25:14 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.20 2007-06-15 19:05:48 c2woody Exp $ */ #include #include @@ -348,6 +348,7 @@ bool isoDrive::GetFileAttr(char *name, Bit16u *attr) bool success = lookup(&de, name); if (success) { *attr = DOS_ATTR_ARCHIVE | DOS_ATTR_READ_ONLY; + if (IS_HIDDEN(de.fileFlags)) *attr |= DOS_ATTR_HIDDEN; if (IS_DIR(de.fileFlags)) *attr |= DOS_ATTR_DIRECTORY; } return success; From 5f965cc48bd287e3226a49ae07be8cb742bf2ac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 17 Jun 2007 12:26:35 +0000 Subject: [PATCH 2805/4131] allow read-only disk images to be booted (fixes some booter games) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2891 --- src/dos/dos_programs.cpp | 41 ++++++++++++++++++++++++++++------------ src/ints/bios_disk.cpp | 6 +++--- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 61504b47..dc9a4e33 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.74 2007-06-12 20:22:08 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.75 2007-06-17 12:26:35 c2woody Exp $ */ #include "dosbox.h" #include @@ -403,21 +403,30 @@ private: ldp=dynamic_cast(Drives[drive]); if(!ldp) return NULL; - tmpfile = ldp->GetSystemFilePtr(fullname, "r"); + tmpfile = ldp->GetSystemFilePtr(fullname, "rb"); if(tmpfile == NULL) { if (!tryload) *error=1; return NULL; } - fclose(tmpfile); - tmpfile = ldp->GetSystemFilePtr(fullname, "rb+"); - if(tmpfile == NULL) { - if (!tryload) *error=2; - return NULL; - } + // get file size fseek(tmpfile,0L, SEEK_END); *ksize = (ftell(tmpfile) / 1024); *bsize = ftell(tmpfile); + fclose(tmpfile); + + tmpfile = ldp->GetSystemFilePtr(fullname, "rb+"); + if(tmpfile == NULL) { +// if (!tryload) *error=2; +// return NULL; + WriteOut(MSG_Get("PROGRAM_BOOT_WRITE_PROTECTED")); + tmpfile = ldp->GetSystemFilePtr(fullname, "rb"); + if(tmpfile == NULL) { + if (!tryload) *error=1; + return NULL; + } + } + return tmpfile; } catch(...) { @@ -430,12 +439,19 @@ private: FILE* tmpfile = getFSFile_mounted(filename,ksize,bsize,&error); if(tmpfile) return tmpfile; //File not found on mounted filesystem. Try regular filesystem - tmpfile = fopen(filename,"rb+"); + std::string filename_s(filename); + ResolveHomedir(filename_s); + tmpfile = fopen(filename_s.c_str(),"rb+"); if(!tmpfile) { - if( (tmpfile = fopen(filename,"r")) ) { + if( (tmpfile = fopen(filename_s.c_str(),"rb")) ) { //File exists; So can't be opened in correct mode => error 2 - fclose(tmpfile); - if(tryload) error = 2; +// fclose(tmpfile); +// if(tryload) error = 2; + WriteOut(MSG_Get("PROGRAM_BOOT_WRITE_PROTECTED")); + fseek(tmpfile,0L, SEEK_END); + *ksize = (ftell(tmpfile) / 1024); + *bsize = ftell(tmpfile); + return tmpfile; } // Give the delayed errormessages from the mounted variant (or from above) if(error == 1) WriteOut(MSG_Get("PROGRAM_BOOT_NOT_EXIST")); @@ -1363,6 +1379,7 @@ void DOS_SetupPrograms(void) { ); MSG_Add("PROGRAM_BOOT_NOT_EXIST","Bootdisk file does not exist. Failing.\n"); MSG_Add("PROGRAM_BOOT_NOT_OPEN","Cannot open bootdisk file. Failing.\n"); + MSG_Add("PROGRAM_BOOT_WRITE_PROTECTED","Image file is read-only! Might create problems.\n"); MSG_Add("PROGRAM_BOOT_PRINT_ERROR","This command boots DOSBox from either a floppy or hard disk image.\n\n" "For this command, one can specify a succession of floppy disks swappable\n" "by pressing Ctrl-F4, and -l specifies the mounted drive to boot from. If\n" diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index b97a5b1f..5b56feba 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.35 2007-06-12 20:22:08 c2woody Exp $ */ +/* $Id: bios_disk.cpp,v 1.36 2007-06-17 12:26:35 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" @@ -173,9 +173,9 @@ Bit8u imageDisk::Write_AbsoluteSector(Bit32u sectnum, void *data) { //LOG_MSG("Writing sectors to %ld at bytenum %d", sectnum, bytenum); fseek(diskimg,bytenum,SEEK_SET); - fwrite(data, sector_size, 1, diskimg); + size_t ret=fwrite(data, sector_size, 1, diskimg); - return 0x00; + return ((ret>0)?0x00:0x05); } From d6ddccf64a823d6bc28be3e11db45b9a5f136161 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 Jun 2007 11:28:25 +0000 Subject: [PATCH 2806/4131] Add ifdefs around pragma Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2892 --- src/ints/xms.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 539f5d54..0531eb31 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.47 2007-06-12 20:22:09 c2woody Exp $ */ +/* $Id: xms.cpp,v 1.48 2007-06-25 11:28:25 qbix79 Exp $ */ #include #include @@ -81,7 +81,9 @@ struct XMS_Block { bool free; }; -#pragma pack (push,1) +#ifdef _MSC_VER +#pragma pack (1) +#endif struct XMS_MemMove{ Bit32u length; Bit16u src_handle; @@ -96,7 +98,10 @@ struct XMS_MemMove{ } dest; } GCC_ATTRIBUTE(packed); +#ifdef _MSC_VER #pragma pack (pop) +#endif + Bitu XMS_EnableA20(bool enable) { From cdfebb5bda653a8e0afa6bae1246efe3f9d03bae Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 Jun 2007 11:35:53 +0000 Subject: [PATCH 2807/4131] Add some more bsds to the configure detection Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2893 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 586776e3..d81baae0 100644 --- a/configure.in +++ b/configure.in @@ -406,7 +406,7 @@ case "$target" in AC_DEFINE(MACOSX, 1, [Compiling on Mac OS X]) LIBS="$LIBS -framework AudioUnit" ;; - *-*-freebsd* | *-*-linux*) + *-*-freebsd* | *-*-linux* | *-*-dragonfly* | *-*-netbsd* | *-*-openbsd*) AC_DEFINE(LINUX, 1, [Compiling on GNU/Linux or *BSD]) AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).]) ;; From b15b9575e43634645ca3313486784e5032063e26 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 Jun 2007 18:45:48 +0000 Subject: [PATCH 2808/4131] Remove pop as well Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2894 --- src/ints/xms.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 0531eb31..fc052383 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.48 2007-06-25 11:28:25 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.49 2007-06-25 18:45:48 qbix79 Exp $ */ #include #include @@ -99,7 +99,7 @@ struct XMS_MemMove{ } GCC_ATTRIBUTE(packed); #ifdef _MSC_VER -#pragma pack (pop) +#pragma pack () #endif From 4053f8693e12494fb3f588799a778b018b7bb630 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 27 Jun 2007 14:51:30 +0000 Subject: [PATCH 2809/4131] Add intro text to configfile. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2895 --- src/dosbox.cpp | 6 +++++- src/misc/setup.cpp | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index ec935eb4..4ef0f46f 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.116 2007-06-14 08:23:46 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.117 2007-06-27 14:51:30 qbix79 Exp $ */ #include #include @@ -236,6 +236,10 @@ static void DOSBOX_RealInit(Section * sec) { ticksLocked = false; DOSBOX_SetLoop(&Normal_Loop); MSG_Init(section); + MSG_Add("CONFIGFILE_INTRO", + "# This is the configurationfile for DOSBox %s.\n" + "# Lines starting with a # are commentlines.\n" + "# They are used to (briefly) document the effect of each option.\n"); MAPPER_AddHandler(DOSBOX_UnlockSpeed, MK_f12, MMOD2,"speedlock","Speedlock"); svgaCard = SVGA_S3Trio; diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 139f44e9..ace47e87 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.39 2007-06-14 08:23:46 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.40 2007-06-27 14:51:30 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -197,6 +197,10 @@ void Config::PrintConfig(char const * const configfilename) const { char temp[50];char helpline[256]; FILE* outfile=fopen(configfilename,"w+t"); if(outfile==NULL) return; + + /* Print start of configfile and add an return to improve readibility. */ + fprintf(outfile,MSG_Get("CONFIGFILE_INTRO"),VERSION); + fprintf(outfile,"\n"); for (const_it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ /* Print out the Section header */ strcpy(temp,(*tel)->GetName()); From 116afb95f349c1fdef8531ee838d45719bafd6fb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 27 Jun 2007 15:22:55 +0000 Subject: [PATCH 2810/4131] Make virtual Alloc win32 specific instead of visual C specific Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2896 --- src/cpu/core_dyn_x86.cpp | 2 +- src/cpu/core_dyn_x86/cache.h | 2 +- src/cpu/core_dynrec.cpp | 2 +- src/cpu/core_dynrec/cache.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 27aef301..8e78b8ad 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -27,7 +27,7 @@ #include #include -#if defined (_MSC_VER) +#if defined (WIN32) #include #include #endif diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 8f51e880..968f26c6 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -457,7 +457,7 @@ static void cache_init(bool enable) { } } if (cache_code_start_ptr==NULL) { -#if defined (_MSC_VER) +#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) diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index 33d783eb..55a631ea 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -27,7 +27,7 @@ #include #include -#if defined (_MSC_VER) +#if defined (WIN32) #include #include #endif diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index 5a7d40a2..c8f17858 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -562,7 +562,7 @@ static void cache_init(bool enable) { } if (cache_code_start_ptr==NULL) { // allocate the code cache memory -#if defined (_MSC_VER) +#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) From d0c8ac8ec118270bbae29919103a57fd52c398c6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 27 Jun 2007 19:14:59 +0000 Subject: [PATCH 2811/4131] Fix a few warnings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2897 --- src/dos/dos_files.cpp | 4 ++-- src/dos/dos_mscdex.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 3fc64416..c92fe590 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.87 2007-06-14 08:23:46 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.88 2007-06-27 19:14:59 qbix79 Exp $ */ #include #include @@ -690,7 +690,7 @@ Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u * char drive[2]; char name[9]; char ext[4]; - } part GCC_ATTRIBUTE (packed) ; + } GCC_ATTRIBUTE (packed) part; char full[DOS_FCBNAME]; } fcb_name; #ifdef _MSC_VER diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index e1cf3784..2d582c7a 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.47 2007-06-12 20:22:08 c2woody Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.48 2007-06-27 19:14:59 qbix79 Exp $ */ #include #include @@ -64,7 +64,7 @@ public: void SetDriveLetter (Bit8u letter) { sSave(sDeviceHeader,driveLetter,letter); }; void SetNumSubUnits (Bit8u num) { sSave(sDeviceHeader,numSubUnits,num); }; Bit8u GetNumSubUnits (void) { return sGet(sDeviceHeader,numSubUnits); }; - void SetName (char* _name) { MEM_BlockWrite(pt+offsetof(sDeviceHeader,name),_name,8); }; + void SetName (char const* _name) { MEM_BlockWrite(pt+offsetof(sDeviceHeader,name),_name,8); }; void SetInterrupt (Bit16u ofs) { sSave(sDeviceHeader,interrupt,ofs); }; void SetStrategy (Bit16u ofs) { sSave(sDeviceHeader,strategy,ofs); }; @@ -81,7 +81,7 @@ public: Bit16u wReserved; Bit8u driveLetter; Bit8u numSubUnits; - } TDeviceHeader; + } GCC_ATTRIBUTE(packed) TDeviceHeader; #ifdef _MSC_VER #pragma pack() #endif From dc18fb11dd19728826e3c8d74c95b54ac95bb8e9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 27 Jun 2007 19:15:31 +0000 Subject: [PATCH 2812/4131] Fix certain builds of infocom games. Add a warning when ansi is used. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2898 --- src/dos/dev_con.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index f103a60d..cf417d95 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.30 2007-04-30 18:35:34 c2woody Exp $ */ +/* $Id: dev_con.h,v 1.31 2007-06-27 19:15:31 qbix79 Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" @@ -49,6 +49,7 @@ private: Bit16u ncols; Bit8s savecol; Bit8s saverow; + bool warned; } ansi; }; @@ -265,12 +266,18 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { break; case 'f': case 'H':/* Cursor Pos*/ - if(ansi.data[0]==0) ansi.data[0]=1; - if(ansi.data[1]==0) ansi.data[1]=1; + if(!ansi.warned) { //Inform the debugger that ansi is used. + ansi.warned = true; + LOG(LOG_IOCTL,LOG_WARN)("ANSI SEQUENCES USED"); + } + /* Turn them into positions that are on the screen */ + if(ansi.data[0] == 0) ansi.data[0] = 1; + if(ansi.data[1] == 0) ansi.data[1] = 1; + if(ansi.data[0] > ansi.nrows) ansi.data[0] = ansi.nrows; + if(ansi.data[1] > ansi.ncols) ansi.data[1] = ansi.ncols; INT10_SetCursorPos(--(ansi.data[0]),--(ansi.data[1]),page); /*ansi=1 based, int10 is 0 based */ ClearAnsi(); break; - /* cursor up down and forward and backward only change the row or the col not both */ case 'A': /* cursor up*/ col=CURSOR_POS_COL(page) ; @@ -397,6 +404,7 @@ device_CON::device_CON() { ansi.nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS) + 1; ansi.saverow=0; ansi.savecol=0; + ansi.warned=false; ClearAnsi(); } From e5d178a282ca05cc3c2e7cd91ebc279274cc38db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 28 Jun 2007 10:53:05 +0000 Subject: [PATCH 2813/4131] fix some undocumented flags settings (thanks to hal for his comparisons); optimize flags filling in some cases a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2899 --- src/cpu/core_dynrec/operators.h | 50 ++--- src/cpu/flags.cpp | 352 ++++++++++++++++++++++++++++++-- src/cpu/instructions.h | 122 ++++++----- src/cpu/lazyflags.h | 1 + 4 files changed, 435 insertions(+), 90 deletions(-) diff --git a/src/cpu/core_dynrec/operators.h b/src/cpu/core_dynrec/operators.h index 221f8b89..2ae94390 100644 --- a/src/cpu/core_dynrec/operators.h +++ b/src/cpu/core_dynrec/operators.h @@ -730,13 +730,13 @@ static Bit8u DRC_CALL_CONV dynrec_rol_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_rol_byte(Bit8u op1,Bit8u op2) { if (!(op2&0x7)) { if (op2&0x18) { - FillFlags(); + FillFlagsNoCFOF(); SETFLAGBIT(CF,op1 & 1); SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 7)); } return op1; } - FillFlags(); + FillFlagsNoCFOF(); lf_var1b=op1; lf_var2b=op2&0x07; lf_resb=(lf_var1b << lf_var2b) | (lf_var1b >> (8-lf_var2b)); @@ -755,18 +755,18 @@ static Bit8u DRC_CALL_CONV dynrec_ror_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_ror_byte(Bit8u op1,Bit8u op2) { if (!(op2&0x7)) { if (op2&0x10) { - FillFlags(); + FillFlagsNoCFOF(); SETFLAGBIT(CF,op1>>7); SETFLAGBIT(OF,(op1>>7) ^ ((op1>>6) & 1)); } return op1; } - FillFlags(); + FillFlagsNoCFOF(); lf_var1b=op1; lf_var2b=op2&0x07; lf_resb=(lf_var1b >> lf_var2b) | (lf_var1b << (8-lf_var2b)); SETFLAGBIT(CF,lf_resb & 0x80); - if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resb ^ lf_var1b) & 0x80); + SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80); return lf_resb; } @@ -797,7 +797,7 @@ static Bit8u DRC_CALL_CONV dynrec_rcr_byte(Bit8u op1,Bit8u op2) { lf_var2b=op2%9; lf_resb=(lf_var1b >> lf_var2b) | (cf << (8-lf_var2b)) | (lf_var1b << (9-lf_var2b)); \ SETFLAGBIT(CF,(lf_var1b >> (lf_var2b - 1)) & 1); - SETFLAGBIT(OF,(lf_resb ^ lf_var1b) & 0x80); + SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80); return lf_resb; } else return op1; } @@ -861,12 +861,13 @@ static Bit16u DRC_CALL_CONV dynrec_rol_word(Bit16u op1,Bit8u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_rol_word(Bit16u op1,Bit8u op2) { if (!(op2&0xf)) { if (op2&0x10) { - FillFlags(); + FillFlagsNoCFOF(); SETFLAGBIT(CF,op1 & 1); + SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 15)); } return op1; } - FillFlags(); + FillFlagsNoCFOF(); lf_var1w=op1; lf_var2b=op2&0xf; lf_resw=(lf_var1w << lf_var2b) | (lf_var1w >> (16-lf_var2b)); @@ -885,17 +886,18 @@ static Bit16u DRC_CALL_CONV dynrec_ror_word(Bit16u op1,Bit8u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_ror_word(Bit16u op1,Bit8u op2) { if (!(op2&0xf)) { if (op2&0x10) { - FillFlags(); + FillFlagsNoCFOF(); SETFLAGBIT(CF,op1>>15); + SETFLAGBIT(OF,(op1>>15) ^ ((op1>>14) & 1)); } return op1; } - FillFlags(); + FillFlagsNoCFOF(); lf_var1w=op1; lf_var2b=op2&0xf; lf_resw=(lf_var1w >> lf_var2b) | (lf_var1w << (16-lf_var2b)); SETFLAGBIT(CF,lf_resw & 0x8000); - if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resw ^ lf_var1w) & 0x8000); + SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000); return lf_resw; } @@ -926,7 +928,7 @@ static Bit16u DRC_CALL_CONV dynrec_rcr_word(Bit16u op1,Bit8u op2) { lf_var2b=op2%17; lf_resw=(lf_var1w >> lf_var2b) | (cf << (16-lf_var2b)) | (lf_var1w << (17-lf_var2b)); SETFLAGBIT(CF,(lf_var1w >> (lf_var2b - 1)) & 1); - SETFLAGBIT(OF,(lf_resw ^ lf_var1w) & 0x8000); + SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000); return lf_resw; } else return op1; } @@ -989,7 +991,7 @@ static Bit16u DRC_CALL_CONV dynrec_sar_word_simple(Bit16u op1,Bit8u op2) { static Bit32u DRC_CALL_CONV dynrec_rol_dword(Bit32u op1,Bit8u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_rol_dword(Bit32u op1,Bit8u op2) { if (!op2) return op1; - FillFlags(); + FillFlagsNoCFOF(); lf_var1d=op1; lf_var2b=op2; lf_resd=(lf_var1d << lf_var2b) | (lf_var1d >> (32-lf_var2b)); @@ -1007,12 +1009,12 @@ static Bit32u DRC_CALL_CONV dynrec_rol_dword_simple(Bit32u op1,Bit8u op2) { static Bit32u DRC_CALL_CONV dynrec_ror_dword(Bit32u op1,Bit8u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_ror_dword(Bit32u op1,Bit8u op2) { if (!op2) return op1; - FillFlags(); + FillFlagsNoCFOF(); lf_var1d=op1; lf_var2b=op2; lf_resd=(lf_var1d >> lf_var2b) | (lf_var1d << (32-lf_var2b)); SETFLAGBIT(CF,lf_resd & 0x80000000); - if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resd ^ lf_var1d) & 0x80000000); + SETFLAGBIT(OF,(lf_resd ^ (lf_resd<<1)) & 0x80000000); return lf_resd; } @@ -1050,7 +1052,7 @@ static Bit32u DRC_CALL_CONV dynrec_rcr_dword(Bit32u op1,Bit8u op2) { lf_resd=(lf_var1d >> lf_var2b) | (cf << (32-lf_var2b)) | (lf_var1d << (33-lf_var2b)); } SETFLAGBIT(CF,(lf_var1d >> (lf_var2b - 1)) & 1); - SETFLAGBIT(OF,(lf_resd ^ lf_var1d) & 0x80000000); + SETFLAGBIT(OF,(lf_resd ^ (lf_resd<<1)) & 0x80000000); return lf_resd; } else return op1; } @@ -1375,7 +1377,7 @@ static void dyn_branchflag_to_reg(BranchTypes btype) { static void DRC_CALL_CONV dynrec_mul_byte(Bit8u op) DRC_FC; static void DRC_CALL_CONV dynrec_mul_byte(Bit8u op) { - FillFlags(); + FillFlagsNoCFOF(); reg_ax=reg_al*op; SETFLAGBIT(ZF,reg_al == 0); if (reg_ax & 0xff00) { @@ -1389,7 +1391,7 @@ static void DRC_CALL_CONV dynrec_mul_byte(Bit8u op) { static void DRC_CALL_CONV dynrec_imul_byte(Bit8u op) DRC_FC; static void DRC_CALL_CONV dynrec_imul_byte(Bit8u op) { - FillFlags(); + FillFlagsNoCFOF(); reg_ax=((Bit8s)reg_al) * ((Bit8s)op); if ((reg_ax & 0xff80)==0xff80 || (reg_ax & 0xff80)==0x0000) { SETFLAGBIT(CF,false); @@ -1402,7 +1404,7 @@ static void DRC_CALL_CONV dynrec_imul_byte(Bit8u op) { static void DRC_CALL_CONV dynrec_mul_word(Bit16u op) DRC_FC; static void DRC_CALL_CONV dynrec_mul_word(Bit16u op) { - FillFlags(); + FillFlagsNoCFOF(); Bitu tempu=(Bitu)reg_ax*(Bitu)op; reg_ax=(Bit16u)(tempu); reg_dx=(Bit16u)(tempu >> 16); @@ -1418,7 +1420,7 @@ static void DRC_CALL_CONV dynrec_mul_word(Bit16u op) { static void DRC_CALL_CONV dynrec_imul_word(Bit16u op) DRC_FC; static void DRC_CALL_CONV dynrec_imul_word(Bit16u op) { - FillFlags(); + FillFlagsNoCFOF(); Bits temps=((Bit16s)reg_ax)*((Bit16s)op); reg_ax=(Bit16s)(temps); reg_dx=(Bit16s)(temps >> 16); @@ -1433,7 +1435,7 @@ static void DRC_CALL_CONV dynrec_imul_word(Bit16u op) { static void DRC_CALL_CONV dynrec_mul_dword(Bit32u op) DRC_FC; static void DRC_CALL_CONV dynrec_mul_dword(Bit32u op) { - FillFlags(); + FillFlagsNoCFOF(); Bit64u tempu=(Bit64u)reg_eax*(Bit64u)op; reg_eax=(Bit32u)(tempu); reg_edx=(Bit32u)(tempu >> 32); @@ -1449,7 +1451,7 @@ static void DRC_CALL_CONV dynrec_mul_dword(Bit32u op) { static void DRC_CALL_CONV dynrec_imul_dword(Bit32u op) DRC_FC; static void DRC_CALL_CONV dynrec_imul_dword(Bit32u op) { - FillFlags(); + FillFlagsNoCFOF(); Bit64s temps=((Bit64s)((Bit32s)reg_eax))*((Bit64s)((Bit32s)op)); reg_eax=(Bit32u)(temps); reg_edx=(Bit32u)(temps >> 32); @@ -1551,7 +1553,7 @@ static bool DRC_CALL_CONV dynrec_idiv_dword(Bit32u op) { static Bit16u DRC_CALL_CONV dynrec_dimul_word(Bit16u op1,Bit16u op2) DRC_FC; static Bit16u DRC_CALL_CONV dynrec_dimul_word(Bit16u op1,Bit16u op2) { - FillFlags(); + FillFlagsNoCFOF(); Bits res=((Bit16s)op1) * ((Bit16s)op2); if ((res>-32768) && (res<32767)) { SETFLAGBIT(CF,false); @@ -1565,7 +1567,7 @@ static Bit16u DRC_CALL_CONV dynrec_dimul_word(Bit16u op1,Bit16u op2) { static Bit32u DRC_CALL_CONV dynrec_dimul_dword(Bit32u op1,Bit32u op2) DRC_FC; static Bit32u DRC_CALL_CONV dynrec_dimul_dword(Bit32u op1,Bit32u op2) { - FillFlags(); + FillFlagsNoCFOF(); Bit64s res=((Bit64s)((Bit32s)op1))*((Bit64s)((Bit32s)op2)); if ((res>-((Bit64s)(2147483647)+1)) && (res<(Bit64s)2147483647)) { SETFLAGBIT(CF,false); diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index f56b876e..d475dfeb 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -169,6 +169,18 @@ Bit32u get_AF(void) { return lf_var1w & 0x0f; case t_NEGd: return lf_var1d & 0x0f; + case t_SHLb: + case t_SHRb: + case t_SARb: + return lf_var2b & 0x1f; + case t_SHLw: + case t_SHRw: + case t_SARw: + return lf_var2w & 0x1f; + case t_SHLd: + case t_SHRd: + case t_SARd: + return lf_var2d & 0x1f; case t_ORb: case t_ORw: case t_ORd: @@ -181,15 +193,6 @@ Bit32u get_AF(void) { case t_TESTb: case t_TESTw: case t_TESTd: - case t_SHLb: - case t_SHLw: - case t_SHLd: - case t_SHRb: - case t_SHRw: - case t_SHRd: - case t_SARb: - case t_SARw: - case t_SARd: case t_DSHLw: case t_DSHLd: case t_DSHRw: @@ -386,18 +389,24 @@ Bit32u get_OF(void) { case t_NEGd: return (lf_var1d == 0x80000000); case t_SHLb: - case t_SHRb: return (lf_resb ^ lf_var1b) & 0x80; case t_SHLw: - case t_SHRw: case t_DSHRw: case t_DSHLw: return (lf_resw ^ lf_var1w) & 0x8000; case t_SHLd: - case t_SHRd: case t_DSHRd: case t_DSHLd: return (lf_resd ^ lf_var1d) & 0x80000000; + case t_SHRb: + if ((lf_var2b&0x1f)==1) return (lf_var1b > 0x80); + else return false; + case t_SHRw: + if ((lf_var2b&0x1f)==1) return (lf_var1w > 0x8000); + else return false; + case t_SHRd: + if ((lf_var2b&0x1f)==1) return (lf_var1d > 0x80000000); + else return false; case t_ORb: case t_ORw: case t_ORd: @@ -485,6 +494,7 @@ Bitu FillFlags(void) { #define SETCF(NEWBIT) reg_flags=(reg_flags & ~FLAG_CF)|(NEWBIT); #define SET_FLAG SETFLAGBIT + Bitu FillFlags(void) { switch (lflags.type) { case t_UNKNOWN: @@ -682,6 +692,7 @@ Bitu FillFlags(void) { DOFLAG_SFb; SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); DOFLAG_PF; + SET_FLAG(AF,(lf_var2b&0x1f)); break; case t_SHLw: if (lf_var2b>16) SET_FLAG(CF,false); @@ -690,6 +701,7 @@ Bitu FillFlags(void) { DOFLAG_SFw; SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); DOFLAG_PF; + SET_FLAG(AF,(lf_var2w&0x1f)); break; case t_SHLd: SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); @@ -697,6 +709,7 @@ Bitu FillFlags(void) { DOFLAG_SFd; SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); DOFLAG_PF; + SET_FLAG(AF,(lf_var2d&0x1f)); break; @@ -720,22 +733,28 @@ Bitu FillFlags(void) { SET_FLAG(CF,(lf_var1b >> (lf_var2b - 1)) & 1); DOFLAG_ZFb; DOFLAG_SFb; - SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); + if ((lf_var2b&0x1f)==1) SET_FLAG(OF,(lf_var1b >= 0x80)); + else SET_FLAG(OF,false); DOFLAG_PF; + SET_FLAG(AF,(lf_var2b&0x1f)); break; case t_SHRw: SET_FLAG(CF,(lf_var1w >> (lf_var2b - 1)) & 1); DOFLAG_ZFw; DOFLAG_SFw; - SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); + if ((lf_var2w&0x1f)==1) SET_FLAG(OF,(lf_var1w >= 0x8000)); + else SET_FLAG(OF,false); DOFLAG_PF; + SET_FLAG(AF,(lf_var2w&0x1f)); break; case t_SHRd: SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); DOFLAG_ZFd; DOFLAG_SFd; - SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); + if ((lf_var2d&0x1f)==1) SET_FLAG(OF,(lf_var1d >= 0x80000000)); + else SET_FLAG(OF,false); DOFLAG_PF; + SET_FLAG(AF,(lf_var2d&0x1f)); break; @@ -761,6 +780,7 @@ Bitu FillFlags(void) { DOFLAG_SFb; SET_FLAG(OF,false); DOFLAG_PF; + SET_FLAG(AF,(lf_var2b&0x1f)); break; case t_SARw: SET_FLAG(CF,(((Bit16s) lf_var1w) >> (lf_var2b - 1)) & 1); @@ -768,6 +788,7 @@ Bitu FillFlags(void) { DOFLAG_SFw; SET_FLAG(OF,false); DOFLAG_PF; + SET_FLAG(AF,(lf_var2w&0x1f)); break; case t_SARd: SET_FLAG(CF,(((Bit32s) lf_var1d) >> (lf_var2b - 1)) & 1); @@ -775,6 +796,7 @@ Bitu FillFlags(void) { DOFLAG_SFd; SET_FLAG(OF,false); DOFLAG_PF; + SET_FLAG(AF,(lf_var2d&0x1f)); break; case t_INCb: @@ -859,6 +881,306 @@ Bitu FillFlags(void) { return reg_flags; } +void FillFlagsNoCFOF(void) { + switch (lflags.type) { + case t_UNKNOWN: + return; + case t_ADDb: + DOFLAG_AF; + DOFLAG_ZFb; + DOFLAG_SFb; + DOFLAG_PF; + break; + case t_ADDw: + DOFLAG_AF; + DOFLAG_ZFw; + DOFLAG_SFw; + DOFLAG_PF; + break; + case t_ADDd: + DOFLAG_AF; + DOFLAG_ZFd; + DOFLAG_SFd; + DOFLAG_PF; + break; + case t_ADCb: + DOFLAG_AF; + DOFLAG_ZFb; + DOFLAG_SFb; + DOFLAG_PF; + break; + case t_ADCw: + DOFLAG_AF; + DOFLAG_ZFw; + DOFLAG_SFw; + DOFLAG_PF; + break; + case t_ADCd: + DOFLAG_AF; + DOFLAG_ZFd; + DOFLAG_SFd; + DOFLAG_PF; + break; + + + case t_SBBb: + DOFLAG_AF; + DOFLAG_ZFb; + DOFLAG_SFb; + DOFLAG_PF; + break; + case t_SBBw: + DOFLAG_AF; + DOFLAG_ZFw; + DOFLAG_SFw; + DOFLAG_PF; + break; + case t_SBBd: + DOFLAG_AF; + DOFLAG_ZFd; + DOFLAG_SFd; + DOFLAG_PF; + break; + + + case t_SUBb: + case t_CMPb: + DOFLAG_AF; + DOFLAG_ZFb; + DOFLAG_SFb; + DOFLAG_PF; + break; + case t_SUBw: + case t_CMPw: + DOFLAG_AF; + DOFLAG_ZFw; + DOFLAG_SFw; + DOFLAG_PF; + break; + case t_SUBd: + case t_CMPd: + DOFLAG_AF; + DOFLAG_ZFd; + DOFLAG_SFd; + DOFLAG_PF; + break; + + + case t_ORb: + SET_FLAG(AF,false); + DOFLAG_ZFb; + DOFLAG_SFb; + DOFLAG_PF; + break; + case t_ORw: + SET_FLAG(AF,false); + DOFLAG_ZFw; + DOFLAG_SFw; + DOFLAG_PF; + break; + case t_ORd: + SET_FLAG(AF,false); + DOFLAG_ZFd; + DOFLAG_SFd; + DOFLAG_PF; + break; + + + case t_TESTb: + case t_ANDb: + SET_FLAG(AF,false); + DOFLAG_ZFb; + DOFLAG_SFb; + DOFLAG_PF; + break; + case t_TESTw: + case t_ANDw: + SET_FLAG(AF,false); + DOFLAG_ZFw; + DOFLAG_SFw; + DOFLAG_PF; + break; + case t_TESTd: + case t_ANDd: + SET_FLAG(AF,false); + DOFLAG_ZFd; + DOFLAG_SFd; + DOFLAG_PF; + break; + + + case t_XORb: + SET_FLAG(AF,false); + DOFLAG_ZFb; + DOFLAG_SFb; + DOFLAG_PF; + break; + case t_XORw: + SET_FLAG(AF,false); + DOFLAG_ZFw; + DOFLAG_SFw; + DOFLAG_PF; + break; + case t_XORd: + SET_FLAG(AF,false); + DOFLAG_ZFd; + DOFLAG_SFd; + DOFLAG_PF; + break; + + + case t_SHLb: + DOFLAG_ZFb; + DOFLAG_SFb; + DOFLAG_PF; + SET_FLAG(AF,(lf_var2b&0x1f)); + break; + case t_SHLw: + DOFLAG_ZFw; + DOFLAG_SFw; + DOFLAG_PF; + SET_FLAG(AF,(lf_var2w&0x1f)); + break; + case t_SHLd: + DOFLAG_ZFd; + DOFLAG_SFd; + DOFLAG_PF; + SET_FLAG(AF,(lf_var2d&0x1f)); + break; + + + case t_DSHLw: + DOFLAG_ZFw; + DOFLAG_SFw; + DOFLAG_PF; + break; + case t_DSHLd: + DOFLAG_ZFd; + DOFLAG_SFd; + DOFLAG_PF; + break; + + + case t_SHRb: + DOFLAG_ZFb; + DOFLAG_SFb; + DOFLAG_PF; + SET_FLAG(AF,(lf_var2b&0x1f)); + break; + case t_SHRw: + DOFLAG_ZFw; + DOFLAG_SFw; + DOFLAG_PF; + SET_FLAG(AF,(lf_var2w&0x1f)); + break; + case t_SHRd: + DOFLAG_ZFd; + DOFLAG_SFd; + DOFLAG_PF; + SET_FLAG(AF,(lf_var2d&0x1f)); + break; + + + case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ + DOFLAG_ZFw; + DOFLAG_SFw; + DOFLAG_PF; + break; + case t_DSHRd: + DOFLAG_ZFd; + DOFLAG_SFd; + DOFLAG_PF; + break; + + + case t_SARb: + DOFLAG_ZFb; + DOFLAG_SFb; + DOFLAG_PF; + SET_FLAG(AF,(lf_var2b&0x1f)); + break; + case t_SARw: + DOFLAG_ZFw; + DOFLAG_SFw; + DOFLAG_PF; + SET_FLAG(AF,(lf_var2w&0x1f)); + break; + case t_SARd: + DOFLAG_ZFd; + DOFLAG_SFd; + DOFLAG_PF; + SET_FLAG(AF,(lf_var2d&0x1f)); + break; + + case t_INCb: + SET_FLAG(AF,(lf_resb & 0x0f) == 0); + DOFLAG_ZFb; + DOFLAG_SFb; + DOFLAG_PF; + break; + case t_INCw: + SET_FLAG(AF,(lf_resw & 0x0f) == 0); + DOFLAG_ZFw; + DOFLAG_SFw; + DOFLAG_PF; + break; + case t_INCd: + SET_FLAG(AF,(lf_resd & 0x0f) == 0); + DOFLAG_ZFd; + DOFLAG_SFd; + DOFLAG_PF; + break; + + case t_DECb: + SET_FLAG(AF,(lf_resb & 0x0f) == 0x0f); + DOFLAG_ZFb; + DOFLAG_SFb; + DOFLAG_PF; + break; + case t_DECw: + SET_FLAG(AF,(lf_resw & 0x0f) == 0x0f); + DOFLAG_ZFw; + DOFLAG_SFw; + DOFLAG_PF; + break; + case t_DECd: + SET_FLAG(AF,(lf_resd & 0x0f) == 0x0f); + DOFLAG_ZFd; + DOFLAG_SFd; + DOFLAG_PF; + break; + + case t_NEGb: + SET_FLAG(AF,(lf_resb & 0x0f) != 0); + DOFLAG_ZFb; + DOFLAG_SFb; + DOFLAG_PF; + break; + case t_NEGw: + SET_FLAG(AF,(lf_resw & 0x0f) != 0); + DOFLAG_ZFw; + DOFLAG_SFw; + DOFLAG_PF; + break; + case t_NEGd: + SET_FLAG(AF,(lf_resd & 0x0f) != 0); + DOFLAG_ZFd; + DOFLAG_SFd; + DOFLAG_PF; + break; + + + case t_DIV: + case t_MUL: + break; + + default: + LOG(LOG_CPU,LOG_ERROR)("Unhandled flag type %d",lflags.type); + break; + } + lflags.type=t_UNKNOWN; +} + void DestroyConditionFlags(void) { lflags.type=t_UNKNOWN; } diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 5f3505b4..45b2c795 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -230,13 +230,13 @@ #define ROLB(op1,op2,load,save) \ if (!(op2&0x7)) { \ if (op2&0x18) { \ - FillFlags(); \ + FillFlagsNoCFOF(); \ SETFLAGBIT(CF,op1 & 1); \ SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 7)); \ } \ break; \ } \ - FillFlags(); \ + FillFlagsNoCFOF(); \ lf_var1b=load(op1); \ lf_var2b=op2&0x07; \ lf_resb=(lf_var1b << lf_var2b) | \ @@ -248,12 +248,13 @@ #define ROLW(op1,op2,load,save) \ if (!(op2&0xf)) { \ if (op2&0x10) { \ - FillFlags(); \ + FillFlagsNoCFOF(); \ SETFLAGBIT(CF,op1 & 1); \ + SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 15)); \ } \ break; \ } \ - FillFlags(); \ + FillFlagsNoCFOF(); \ lf_var1w=load(op1); \ lf_var2b=op2&0xf; \ lf_resw=(lf_var1w << lf_var2b) | \ @@ -264,7 +265,7 @@ #define ROLD(op1,op2,load,save) \ if (!op2) break; \ - FillFlags(); \ + FillFlagsNoCFOF(); \ lf_var1d=load(op1); \ lf_var2b=op2; \ lf_resd=(lf_var1d << lf_var2b) | \ @@ -277,48 +278,49 @@ #define RORB(op1,op2,load,save) \ if (!(op2&0x7)) { \ if (op2&0x10) { \ - FillFlags(); \ + FillFlagsNoCFOF(); \ SETFLAGBIT(CF,op1>>7); \ SETFLAGBIT(OF,(op1>>7) ^ ((op1>>6) & 1)); \ } \ break; \ } \ - FillFlags(); \ + FillFlagsNoCFOF(); \ lf_var1b=load(op1); \ lf_var2b=op2&0x07; \ lf_resb=(lf_var1b >> lf_var2b) | \ (lf_var1b << (8-lf_var2b)); \ save(op1,lf_resb); \ SETFLAGBIT(CF,lf_resb & 0x80); \ - if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resb ^ lf_var1b) & 0x80); + SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80); #define RORW(op1,op2,load,save) \ if (!(op2&0xf)) { \ if (op2&0x10) { \ - FillFlags(); \ + FillFlagsNoCFOF(); \ SETFLAGBIT(CF,op1>>15); \ + SETFLAGBIT(OF,(op1>>15) ^ ((op1>>14) & 1)); \ } \ break; \ } \ - FillFlags(); \ + FillFlagsNoCFOF(); \ lf_var1w=load(op1); \ lf_var2b=op2&0xf; \ lf_resw=(lf_var1w >> lf_var2b) | \ (lf_var1w << (16-lf_var2b)); \ save(op1,lf_resw); \ SETFLAGBIT(CF,lf_resw & 0x8000); \ - if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resw ^ lf_var1w) & 0x8000); + SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000); #define RORD(op1,op2,load,save) \ if (!op2) break; \ - FillFlags(); \ + FillFlagsNoCFOF(); \ lf_var1d=load(op1); \ lf_var2b=op2; \ lf_resd=(lf_var1d >> lf_var2b) | \ (lf_var1d << (32-lf_var2b)); \ save(op1,lf_resd); \ SETFLAGBIT(CF,lf_resd & 0x80000000); \ - if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resd ^ lf_var1d) & 0x80000000); + SETFLAGBIT(OF,(lf_resd ^ (lf_resd<<1)) & 0x80000000); #define RCLB(op1,op2,load,save) \ @@ -376,7 +378,7 @@ (lf_var1b << (9-lf_var2b)); \ save(op1,lf_resb); \ SETFLAGBIT(CF,(lf_var1b >> (lf_var2b - 1)) & 1); \ - SETFLAGBIT(OF,(lf_resb ^ lf_var1b) & 0x80); \ + SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80); \ } #define RCRW(op1,op2,load,save) \ @@ -389,7 +391,7 @@ (lf_var1w << (17-lf_var2b)); \ save(op1,lf_resw); \ SETFLAGBIT(CF,(lf_var1w >> (lf_var2b - 1)) & 1); \ - SETFLAGBIT(OF,(lf_resw ^ lf_var1w) & 0x8000); \ + SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000); \ } #define RCRD(op1,op2,load,save) \ @@ -406,7 +408,7 @@ } \ save(op1,lf_resd); \ SETFLAGBIT(CF,(lf_var1d >> (lf_var2b - 1)) & 1); \ - SETFLAGBIT(OF,(lf_resd ^ lf_var1d) & 0x80000000); \ + SETFLAGBIT(OF,(lf_resd ^ (lf_resd<<1)) & 0x80000000); \ } @@ -520,12 +522,14 @@ #define DAS() \ +{ \ + Bit8u osigned=reg_al & 0x80; \ if (((reg_al & 0x0f) > 9) || get_AF()) { \ if ((reg_al>0x99) || get_CF()) { \ reg_al-=0x60; \ SETFLAGBIT(CF,true); \ } else { \ - SETFLAGBIT(CF,false); \ + SETFLAGBIT(CF,(reg_al<=0x05)); \ } \ reg_al-=6; \ SETFLAGBIT(AF,true); \ @@ -538,44 +542,61 @@ } \ SETFLAGBIT(AF,false); \ } \ + SETFLAGBIT(OF,osigned && ((reg_al&0x80)==0)); \ SETFLAGBIT(SF,(reg_al&0x80)); \ SETFLAGBIT(ZF,(reg_al==0)); \ SETFLAGBIT(PF,parity_lookup[reg_al]); \ - lflags.type=t_UNKNOWN; + lflags.type=t_UNKNOWN; \ +} #define AAA() \ - if (get_AF() || ((reg_al & 0xf) > 9)) \ - { \ + SETFLAGBIT(SF,((reg_al>=0x7a) && (reg_al<=0xf9))); \ + if ((reg_al & 0xf) > 9) { \ + SETFLAGBIT(OF,(reg_al&0xf0)==0x70); \ reg_ax += 0x106; \ - SETFLAGBIT(AF,true); \ SETFLAGBIT(CF,true); \ + SETFLAGBIT(ZF,(reg_al == 0)); \ + SETFLAGBIT(AF,true); \ + } else if (get_AF()) { \ + reg_ax += 0x106; \ + SETFLAGBIT(OF,false); \ + SETFLAGBIT(CF,true); \ + SETFLAGBIT(ZF,false); \ + SETFLAGBIT(AF,true); \ } else { \ - SETFLAGBIT(AF,false); \ + SETFLAGBIT(OF,false); \ SETFLAGBIT(CF,false); \ + SETFLAGBIT(ZF,(reg_al == 0)); \ + SETFLAGBIT(AF,false); \ } \ + SETFLAGBIT(PF,parity_lookup[reg_al]); \ reg_al &= 0x0F; \ - lflags.type=t_UNKNOWN; \ - SETFLAGBIT(SF,0); \ - SETFLAGBIT(OF,0); \ - SETFLAGBIT(ZF,(reg_al == 0)); \ - SETFLAGBIT(PF,parity_lookup[reg_al]); + lflags.type=t_UNKNOWN; #define AAS() \ - if (((reg_al & 0x0f)>9) || get_AF()) { \ + if ((reg_al & 0x0f)>9) { \ + SETFLAGBIT(SF,(reg_al>0x85)); \ reg_ax -= 0x106; \ - SETFLAGBIT(AF,true); \ + SETFLAGBIT(OF,false); \ SETFLAGBIT(CF,true); \ + SETFLAGBIT(AF,true); \ + } else if (get_AF()) { \ + SETFLAGBIT(OF,((reg_al>=0x80) && (reg_al<=0x85))); \ + SETFLAGBIT(SF,(reg_al<0x06) || (reg_al>0x85)); \ + reg_ax -= 0x106; \ + SETFLAGBIT(CF,true); \ + SETFLAGBIT(AF,true); \ } else { \ - SETFLAGBIT(AF,false); \ + SETFLAGBIT(SF,(reg_al>=0x80)); \ + SETFLAGBIT(OF,false); \ SETFLAGBIT(CF,false); \ + SETFLAGBIT(AF,false); \ } \ - reg_al &= 0x0F; \ - lflags.type=t_UNKNOWN; \ - SETFLAGBIT(SF,0); \ - SETFLAGBIT(OF,0); \ SETFLAGBIT(ZF,(reg_al == 0)); \ - SETFLAGBIT(PF,parity_lookup[reg_al]); + SETFLAGBIT(PF,parity_lookup[reg_al]); \ + reg_al &= 0x0F; \ + lflags.type=t_UNKNOWN; #define AAM(op1) \ { \ @@ -586,9 +607,9 @@ SETFLAGBIT(SF,(reg_al & 0x80)); \ SETFLAGBIT(ZF,(reg_al == 0)); \ SETFLAGBIT(PF,parity_lookup[reg_al]); \ - SETFLAGBIT(CF,0); \ - SETFLAGBIT(OF,0); \ - SETFLAGBIT(AF,0); \ + SETFLAGBIT(CF,false); \ + SETFLAGBIT(OF,false); \ + SETFLAGBIT(AF,false); \ lflags.type=t_UNKNOWN; \ } else EXCEPTION(0); \ } @@ -601,9 +622,9 @@ Bit16u ax2 = ax1 + reg_al; \ reg_al = (Bit8u) ax2; \ reg_ah = 0; \ - SETFLAGBIT(CF,0); \ - SETFLAGBIT(OF,0); \ - SETFLAGBIT(AF,0); \ + SETFLAGBIT(CF,false); \ + SETFLAGBIT(OF,false); \ + SETFLAGBIT(AF,false); \ SETFLAGBIT(SF,reg_al >= 0x80); \ SETFLAGBIT(ZF,reg_al == 0); \ SETFLAGBIT(PF,parity_lookup[reg_al]); \ @@ -611,8 +632,8 @@ } #define MULB(op1,load,save) \ - FillFlags(); \ reg_ax=reg_al*load(op1); \ + FillFlagsNoCFOF(); \ SETFLAGBIT(ZF,reg_al == 0); \ if (reg_ax & 0xff00) { \ SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ @@ -622,10 +643,10 @@ #define MULW(op1,load,save) \ { \ - FillFlags(); \ Bitu tempu=(Bitu)reg_ax*(Bitu)(load(op1)); \ reg_ax=(Bit16u)(tempu); \ reg_dx=(Bit16u)(tempu >> 16); \ + FillFlagsNoCFOF(); \ SETFLAGBIT(ZF,reg_ax == 0); \ if (reg_dx) { \ SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ @@ -636,10 +657,10 @@ #define MULD(op1,load,save) \ { \ - FillFlags(); \ Bit64u tempu=(Bit64u)reg_eax*(Bit64u)(load(op1)); \ reg_eax=(Bit32u)(tempu); \ reg_edx=(Bit32u)(tempu >> 32); \ + FillFlagsNoCFOF(); \ SETFLAGBIT(ZF,reg_eax == 0); \ if (reg_edx) { \ SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ @@ -729,8 +750,8 @@ #define IMULB(op1,load,save) \ { \ - FillFlags(); \ reg_ax=((Bit8s)reg_al) * ((Bit8s)(load(op1))); \ + FillFlagsNoCFOF(); \ if ((reg_ax & 0xff80)==0xff80 || \ (reg_ax & 0xff80)==0x0000) { \ SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ @@ -742,10 +763,10 @@ #define IMULW(op1,load,save) \ { \ - FillFlags(); \ Bits temps=((Bit16s)reg_ax)*((Bit16s)(load(op1))); \ reg_ax=(Bit16s)(temps); \ reg_dx=(Bit16s)(temps >> 16); \ + FillFlagsNoCFOF(); \ if (((temps & 0xffff8000)==0xffff8000 || \ (temps & 0xffff8000)==0x0000)) { \ SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ @@ -756,11 +777,11 @@ #define IMULD(op1,load,save) \ { \ - FillFlags(); \ Bit64s temps=((Bit64s)((Bit32s)reg_eax))* \ ((Bit64s)((Bit32s)(load(op1)))); \ reg_eax=(Bit32u)(temps); \ reg_edx=(Bit32u)(temps >> 32); \ + FillFlagsNoCFOF(); \ if ((reg_edx==0xffffffff) && \ (reg_eax & 0x80000000) ) { \ SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ @@ -774,10 +795,9 @@ #define DIMULW(op1,op2,op3,load,save) \ { \ - FillFlags(); \ - Bits res; \ - res=((Bit16s)op2) * ((Bit16s)op3); \ + Bits res=((Bit16s)op2) * ((Bit16s)op3); \ save(op1,res & 0xffff); \ + FillFlagsNoCFOF(); \ if ((res> -32768) && (res<32767)) { \ SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ } else { \ @@ -787,9 +807,9 @@ #define DIMULD(op1,op2,op3,load,save) \ { \ - FillFlags(); \ Bit64s res=((Bit64s)((Bit32s)op2))*((Bit64s)((Bit32s)op3)); \ save(op1,(Bit32s)res); \ + FillFlagsNoCFOF(); \ if ((res>-((Bit64s)(2147483647)+1)) && \ (res<(Bit64s)2147483647)) { \ SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index b710db09..2f088ec0 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -28,6 +28,7 @@ Bit32u get_OF(void); Bit32u get_PF(void); Bitu FillFlags(void); +void FillFlagsNoCFOF(void); void DestroyConditionFlags(void); #include "regs.h" From 4a079e44b0e4f1f8513abb269aeac8f1c3110fe8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 28 Jun 2007 14:55:43 +0000 Subject: [PATCH 2814/4131] fix a few warning on mac os x. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2900 --- src/Makefile.am | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index bccc59a1..870a0db5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,13 +4,15 @@ SUBDIRS = cpu debug dos fpu gui hardware libs ints misc shell platform bin_PROGRAMS = dosbox +if HAVE_WINDRES +ico_stuff = dosbox_ico.o +endif + + 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 hardware/serialport/libserial.a - -if HAVE_WINDRES -dosbox_LDADD += dosbox_ico.o -endif + ints/libints.a misc/libmisc.a shell/libshell.a hardware/serialport/libserial.a \ + $(ico_stuff) EXTRA_DIST = dosbox.rc dosbox.ico dosbox_ico.o: dosbox.rc dosbox.ico From f034692ce8db575104f0e15ab39444ac51d8aebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 28 Jun 2007 16:02:27 +0000 Subject: [PATCH 2815/4131] typo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2901 --- src/hardware/vga_s3.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index ec418544..a48ab1c4 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_s3.cpp,v 1.7 2007-05-28 16:29:11 c2woody Exp $ */ +/* $Id: vga_s3.cpp,v 1.8 2007-06-28 16:02:27 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -303,7 +303,7 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { VGA_SetupHandlers(); break; default: - LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:Write to illegal index %2X", reg ); + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:S3:CRTC:Write to illegal index %2X", reg ); break; } } From cd9b01ef6889b85da05b9e10e92ce367809c76ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 28 Jun 2007 16:32:45 +0000 Subject: [PATCH 2816/4131] add default palette skipping on modeset functionality (int10 alternate function select; fixes WW2 Battles of the South Pacific) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2902 --- src/ints/int10.cpp | 18 ++++++- src/ints/int10_modes.cpp | 110 ++++++++++++++++++++------------------- 2 files changed, 74 insertions(+), 54 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 3cab386e..ea495db0 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -299,6 +299,21 @@ graphics_chars: reg_bl=3; //256 kb reg_cx=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES) & 0x0F; break; + case 0x20: /* Set alternate printscreen */ + break; + case 0x30: /* Select vertical resolution */ + case 0x32: /* Video adressing */ + LOG(LOG_INT10,LOG_ERROR)("Function 12:Call %2X not handled",reg_bl); + reg_al=0x12; //fake a success call + break; + case 0x31: /* Palette loading on modeset */ + { + Bit8u temp = real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL) & 0xf7; + if (reg_al&1) temp|=8; // enable if al=0 + real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,temp); + reg_al=0x12; + break; + } case 0x33: /* SWITCH GRAY-SCALE SUMMING */ { Bit8u temp = real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL) & 0xfd; @@ -324,7 +339,8 @@ graphics_chars: break; default: LOG(LOG_INT10,LOG_ERROR)("Function 12:Call %2X not handled",reg_bl); - reg_al=0x12; //Always fake a success call + reg_al=0x12; // wrong!? + break; } break; case 0x13: /* Write String */ diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 97310e9c..43a23eda 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -874,65 +874,69 @@ att_text16: break; } IO_Read(mono_mode ? 0x3ba : 0x3da); - for (i=0;itype) { - case M_EGA: - if (CurMode->mode>0xf) goto dac_text16; - else if (CurMode->mode==0xf) goto dac_mtext16; - for (i=0;i<64;i++) { - IO_Write(0x3c9,ega_palette[i][0]); - IO_Write(0x3c9,ega_palette[i][1]); - IO_Write(0x3c9,ega_palette[i][2]); + if ((modeset_ctl & 8)==0) { + for (i=0;imode==7) { -dac_mtext16: + IO_Write(0x3c0,0x20); IO_Write(0x3c0,0x00); //Disable palette access + IO_Write(0x3c6,0xff); //Reset Pelmask + /* Setup the DAC */ + IO_Write(0x3c8,0); + switch (CurMode->type) { + case M_EGA: + if (CurMode->mode>0xf) goto dac_text16; + else if (CurMode->mode==0xf) goto dac_mtext16; for (i=0;i<64;i++) { - IO_Write(0x3c9,mtext_palette[i][0]); - IO_Write(0x3c9,mtext_palette[i][1]); - IO_Write(0x3c9,mtext_palette[i][2]); + IO_Write(0x3c9,ega_palette[i][0]); + IO_Write(0x3c9,ega_palette[i][1]); + IO_Write(0x3c9,ega_palette[i][2]); + } + break; + case M_CGA2: + case M_CGA4: + case M_TANDY16: + for (i=0;i<64;i++) { + IO_Write(0x3c9,cga_palette_2[i][0]); + IO_Write(0x3c9,cga_palette_2[i][1]); + IO_Write(0x3c9,cga_palette_2[i][2]); + } + break; + case M_TEXT: + if (CurMode->mode==7) { +dac_mtext16: + for (i=0;i<64;i++) { + IO_Write(0x3c9,mtext_palette[i][0]); + IO_Write(0x3c9,mtext_palette[i][1]); + IO_Write(0x3c9,mtext_palette[i][2]); + } + break; + } +dac_text16: + for (i=0;i<64;i++) { + IO_Write(0x3c9,text_palette[i][0]); + IO_Write(0x3c9,text_palette[i][1]); + IO_Write(0x3c9,text_palette[i][2]); + } + break; + case M_VGA: + case M_LIN8: + case M_LIN16: + for (i=0;i<256;i++) { + IO_Write(0x3c9,vga_palette[i][0]); + IO_Write(0x3c9,vga_palette[i][1]); + IO_Write(0x3c9,vga_palette[i][2]); } break; } -dac_text16: - for (i=0;i<64;i++) { - IO_Write(0x3c9,text_palette[i][0]); - IO_Write(0x3c9,text_palette[i][1]); - IO_Write(0x3c9,text_palette[i][2]); - } - break; - case M_VGA: - case M_LIN8: - case M_LIN16: - for (i=0;i<256;i++) { - IO_Write(0x3c9,vga_palette[i][0]); - IO_Write(0x3c9,vga_palette[i][1]); - IO_Write(0x3c9,vga_palette[i][2]); - } - break; - } - if (machine==MCH_VGA) { - /* check if gray scale summing is enabled */ - if (real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL) & 2) { - INT10_PerformGrayScaleSumming(0,256); + if (machine==MCH_VGA) { + /* check if gray scale summing is enabled */ + if (real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL) & 2) { + INT10_PerformGrayScaleSumming(0,256); + } } + } else { + IO_Write(0x3c0,0x20); //Disable palette access } /* Setup some special stuff for different modes */ Bit8u feature=real_readb(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE); From f947dae196590b785cb9fbf8201caac9397fe837 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 28 Jun 2007 19:43:32 +0000 Subject: [PATCH 2817/4131] Add bounds check. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2903 --- src/dos/dos_files.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index c92fe590..a5939872 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.88 2007-06-27 19:14:59 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.89 2007-06-28 19:43:32 qbix79 Exp $ */ #include #include @@ -1041,7 +1041,7 @@ bool DOS_FileExists(char const * const name) { bool DOS_GetAllocationInfo(Bit8u drive,Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters) { if (!drive) drive=dos.current_drive; else drive--; - if (!Drives[drive]) return false; + if (drive >= DOS_DRIVES || !Drives[drive]) return false; Bit16u _free_clusters; Drives[drive]->AllocationInfo(_bytes_sector,_sectors_cluster,_total_clusters,&_free_clusters); SegSet16(ds,RealSeg(dos.tables.mediaid)); From cb1db6bf69428286a5b4d1afce38e03154216f4f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 29 Jun 2007 10:24:43 +0000 Subject: [PATCH 2818/4131] Add 0xe5 to allowed chars. Fixes nba95 installer. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2904 --- src/dos/dos_files.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index a5939872..f057bcd2 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.89 2007-06-28 19:43:32 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.90 2007-06-29 10:24:43 qbix79 Exp $ */ #include #include @@ -90,6 +90,7 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { case '!': case '%': case '{': case '}': case '`': case '~': case '_': case '-': case '.': case '*': case '?': case '&': case '\'': case '+': case '^': case 246: case 255: case 0xa0: + case 0xe5: upname[w++]=c; break; default: From fd879f6ccc1359314be17a52ed9cfe167276ef09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 29 Jun 2007 17:56:07 +0000 Subject: [PATCH 2819/4131] fix tandy sound zero writes (NewRisingSun) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2905 --- src/hardware/tandy_sound.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index ab48087d..23d10421 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -106,7 +106,7 @@ static void SN76496Write(Bitu port,Bitu data,Bitu iolen) { case 2: /* tone 1 : frequency */ case 4: /* tone 2 : frequency */ R->Period[c] = R->UpdateStep * R->Register[r]; - if (R->Period[c] == 0) R->Period[c] = R->UpdateStep; + if (R->Period[c] == 0) R->Period[c] = 0x3fe; if (r == 4) { /* update noise shift frequency */ @@ -129,8 +129,8 @@ static void SN76496Write(Bitu port,Bitu data,Bitu iolen) { R->Period[3] = (n == 3) ? 2 * R->Period[2] : (R->UpdateStep << (5+n)); /* reset noise shifter */ - R->RNG = NG_PRESET; - R->Output[3] = R->RNG & 1; +// R->RNG = NG_PRESET; +// R->Output[3] = R->RNG & 1; } break; } @@ -147,7 +147,7 @@ static void SN76496Write(Bitu port,Bitu data,Bitu iolen) { case 4: /* tone 2 : frequency */ R->Register[r] = (R->Register[r] & 0x0f) | ((data & 0x3f) << 4); R->Period[c] = R->UpdateStep * R->Register[r]; - if (R->Period[c] == 0) R->Period[c] = R->UpdateStep; + if (R->Period[c] == 0) R->Period[c] = 0x3fe; if (r == 4) { /* update noise shift frequency */ From 21a2ac08fd735387a27f7b1a335f1ea2ad235a21 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 29 Jun 2007 18:41:59 +0000 Subject: [PATCH 2820/4131] Some changes for the upcoming next version. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2906 --- ChangeLog | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/ChangeLog b/ChangeLog index e92956ee..352ac332 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,47 @@ +0.71 + - Add a new recompiling cpu core, which should be easier to port. + - Add 64 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 and + Archmimedean Dynasty) + - Improve/Fix fallback code for certain graphics cards. + - Fix a few cd audio related bugs. + - 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 and others) + - 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) + - 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) + - Speed up flag generation and make it more 386-like. + - General code cleanup. + 0.70 - Improve register handling and support with XMS. - Fix some issues with deleting open files.(windows only issue) From d566d3fca8b8300440e8c46bed1dafb006740350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 30 Jun 2007 19:33:45 +0000 Subject: [PATCH 2821/4131] me too! Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2907 --- src/dos/dev_con.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index cf417d95..358a0448 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.31 2007-06-27 19:15:31 qbix79 Exp $ */ +/* $Id: dev_con.h,v 1.32 2007-06-30 19:33:45 c2woody Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" @@ -273,8 +273,8 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { /* Turn them into positions that are on the screen */ if(ansi.data[0] == 0) ansi.data[0] = 1; if(ansi.data[1] == 0) ansi.data[1] = 1; - if(ansi.data[0] > ansi.nrows) ansi.data[0] = ansi.nrows; - if(ansi.data[1] > ansi.ncols) ansi.data[1] = ansi.ncols; + if(ansi.data[0] > ansi.nrows) ansi.data[0] = (Bit8u)ansi.nrows; + if(ansi.data[1] > ansi.ncols) ansi.data[1] = (Bit8u)ansi.ncols; INT10_SetCursorPos(--(ansi.data[0]),--(ansi.data[1]),page); /*ansi=1 based, int10 is 0 based */ ClearAnsi(); break; From 602b0aea944a0a0ce94ab9090cb8294963e24d09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 30 Jun 2007 19:53:41 +0000 Subject: [PATCH 2822/4131] add scaler forcing option (idea from ykhwong) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2908 --- include/render.h | 1 + src/gui/render.cpp | 23 +++++++++++++++++++---- src/gui/render_scalers.h | 6 +++--- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/include/render.h b/include/render.h index 93d20f29..cfd36817 100644 --- a/include/render.h +++ b/include/render.h @@ -63,6 +63,7 @@ typedef struct { scalerMode_t outMode; scalerOperation_t op; bool clearCache; + bool forced; ScalerLineHandler_t lineHandler; ScalerLineHandler_t linePalHandler; ScalerComplexHandler_t complexHandler; diff --git a/src/gui/render.cpp b/src/gui/render.cpp index d82f39f7..eefcb800 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.51 2007-02-03 13:00:16 harekiet Exp $ */ +/* $Id: render.cpp,v 1.52 2007-06-30 19:53:41 c2woody Exp $ */ #include #include @@ -282,7 +282,7 @@ static void RENDER_Reset( void ) { gfx_scalew = 1; gfx_scaleh = 1; } - if (dblh && dblw) { + if (dblh && dblw || (render.scale.forced && !dblh && !dblw)) { /* Initialize always working defaults */ if (render.scale.size == 2) simpleBlock = &ScaleNormal2x; @@ -555,11 +555,26 @@ void RENDER_Init(Section * sec) { render.aspect=section->Get_bool("aspect"); render.frameskip.max=section->Get_int("frameskip"); render.frameskip.count=0; - const char * scaler;std::string cline; + const char * scaler; + std::string cline; + std::string scaler_str; if (control->cmdline->FindString("-scaler",cline,false)) { scaler=cline.c_str(); + render.scale.forced=false; + } else if (control->cmdline->FindString("-forcescaler",cline,false)) { + scaler=cline.c_str(); + render.scale.forced=true; } else { - scaler=section->Get_string("scaler"); + CommandLine cmd(0,section->Get_string("scaler")); + cmd.FindCommand(1,scaler_str); + scaler=scaler_str.c_str(); + render.scale.forced=false; + if (cmd.GetCount()>1) { + std::string str; + if (cmd.FindCommand(2,str)) { + if (str=="forced") render.scale.forced=true; + } + } } if (!strcasecmp(scaler,"none")) { render.scale.op = scalerOpNormal;render.scale.size = 1; } else if (!strcasecmp(scaler,"normal2x")) { render.scale.op = scalerOpNormal;render.scale.size = 2; } diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index 3f2b34db..2b9d59b5 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -23,10 +23,10 @@ #include "video.h" //MAXWIDTH: increased it for the large text modi #define SCALER_MAXWIDTH 1280 -#define SCALER_MAXHEIGHT 768 +#define SCALER_MAXHEIGHT 1024 -#define SCALER_COMPLEXWIDTH 512 -#define SCALER_COMPLEXHEIGHT 400 +#define SCALER_COMPLEXWIDTH 800 +#define SCALER_COMPLEXHEIGHT 600 #define SCALER_BLOCKSIZE 16 typedef enum { From 216fb3bbe5333681dd92f0bf6b46980aeeb54960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 2 Jul 2007 14:10:27 +0000 Subject: [PATCH 2823/4131] update some size/freesize parameters Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2909 --- src/dos/dos_programs.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index dc9a4e33..8d8eec46 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.75 2007-06-17 12:26:35 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.76 2007-07-02 14:10:27 c2woody Exp $ */ #include "dosbox.h" #include @@ -133,24 +133,30 @@ public: Bit8u mediaid; std::string str_size; if (type=="floppy") { - str_size="512,1,2847,2847";/* All space free */ + str_size="512,1,2880,2880";/* All space free */ mediaid=0xF0; /* Floppy 1.44 media */ } else if (type=="dir") { + // 512*127*16513==~1GB total size + // 512*127*1700==~100MB total free size str_size="512,127,16513,1700"; mediaid=0xF8; /* Hard Disk */ } else if (type=="cdrom") { - str_size="650,127,16513,1700"; + str_size="2048,1,65535,0"; mediaid=0xF8; /* Hard Disk */ } else { WriteOut(MSG_Get("PROGAM_MOUNT_ILL_TYPE"),type.c_str()); return; } - /* Parse the free space in mb's */ + /* Parse the free space in mb's (kb's for floppies) */ std::string mb_size; if(cmd->FindString("-freesize",mb_size,true)) { char teststr[1024]; Bit16u sizemb = static_cast(atoi(mb_size.c_str())); - sprintf(teststr,"512,127,16513,%d",sizemb*1024*1024/(512*127)); + if (type=="floppy") { + sprintf(teststr,"512,1,2880,%d",sizemb*1024/(512*1)); + } else { + sprintf(teststr,"512,127,16513,%d",sizemb*1024*1024/(512*127)); + } str_size=teststr; } From 37914fb224a9d6d5ed62ce67c599d965446a1c55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 2 Jul 2007 20:06:59 +0000 Subject: [PATCH 2824/4131] additional scaler reset checks, mention scaler forcing in the configuration file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2910 --- src/dosbox.cpp | 4 +++- src/gui/render.cpp | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 4ef0f46f..9ecfb523 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.117 2007-06-27 14:51:30 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.118 2007-07-02 20:06:59 c2woody Exp $ */ #include #include @@ -303,6 +303,8 @@ void DOSBOX_Init(void) { " Supported are none,normal2x,normal3x,advmame2x,advmame3x,hq2x,hq3x,\n" " 2xsai,super2xsai,supereagle,advinterp2x,advinterp3x,\n" " tv2x,tv3x,rgb2x,rgb3x,scan2x,scan3x.\n" + " If forced is appended (like scaler=hq2x forced), the scaler will be used\n" + " even if the result might not be desired.\n" ); secprop=control->AddSection_prop("cpu",&CPU_Init,true);//done diff --git a/src/gui/render.cpp b/src/gui/render.cpp index eefcb800..62b31d9c 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.52 2007-06-30 19:53:41 c2woody Exp $ */ +/* $Id: render.cpp,v 1.53 2007-07-02 20:06:59 c2woody Exp $ */ #include #include @@ -548,6 +548,8 @@ void RENDER_Init(Section * sec) { //For restarting the renderer. static bool running = false; bool aspect = render.aspect; + Bitu scalersize = render.scale.size; + bool scalerforced = render.scale.forced; scalerOperation_t scaleOp = render.scale.op; render.pal.first=256; @@ -600,7 +602,9 @@ void RENDER_Init(Section * sec) { } //If something changed that needs a ReInit - if(running && (render.aspect != aspect || render.scale.op != scaleOp)) + if(running &&((render.aspect != aspect) || (render.scale.op != scaleOp) || + (render.scale.size != scalersize) || (render.scale.forced != scalerforced) || + render.scale.forced)) RENDER_CallBack( GFX_CallBackReset ); if(!running) render.updating=true; From 63e3d6546064345c1f796ebe1df64041478b94c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 3 Jul 2007 13:01:40 +0000 Subject: [PATCH 2825/4131] readme updates, correct some typos Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2911 --- README | 138 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 85 insertions(+), 53 deletions(-) diff --git a/README b/README index 52dca299..5c1b17f0 100644 --- a/README +++ b/README @@ -33,11 +33,18 @@ INDEX: 15. Contact + ============== 1. Quickstart: ============== -Type INTRO in DOSBox. That's it. +Type INTRO in DOSBox for a quick tour. +It is essential that you get familiar with the idea of mounting, +DOSBox does not automatically make any drive (or parts of it) +accessible to the emulation. +See the FAQ entry "I've got a Z instead of a C at the prompt" as +well as the description of the MOUNT command (section 4). + ======= @@ -47,7 +54,8 @@ Type INTRO in DOSBox. That's it. Some Frequently Asked Questions: Q: I've got a Z instead of a C at the prompt. -Q: How do I change to fullscreen ? +Q: Do I always have to type these commands? Automation? +Q: How do I change to fullscreen? Q: My CD-ROM doesn't work. Q: The mouse doesn't work. Q: There is no sound. @@ -59,13 +67,12 @@ Q: The game/application runs much too slow! Q: Can DOSBox harm my computer? Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. Q: What sound hardware does DOSBox presently emulate? -Q: DOSBox crashes on startup and I'm running arts +Q: DOSBox crashes on startup and I'm running arts. Q: Great README, but I still don't get it. - Q: I've got a Z instead of a C at the prompt. A: You have to make your directories available as drives in DOSBox by using the "mount" command. For example, in Windows "mount C D:\GAMES" will give @@ -76,7 +83,13 @@ A: You have to make your directories available as drives in DOSBox by using fine, DOSBox will display the prompt "C:\>". -Q: How do I change to fullscreen ? +Q: Do I always have to type these commands? Automation? +A: In the DOSBox configuration file is an [autoexec] section. The commands + present there are run when DOSBox starts, so you can use this section + for the mounting. + + +Q: How do I change to fullscreen? A: Press alt-enter. Alternatively: Edit the configuration file of DOSBox and change the option fullscreen=false to fullscreen=true. If fullscreen looks wrong in your opinion: Play with the option fullresolution in the @@ -87,17 +100,17 @@ A: Press alt-enter. Alternatively: Edit the configuration file of DOSBox and Q: My CD-ROM doesn't work. A: To mount your CD-ROM in DOSBox you have to specify some additional options when mounting the CD-ROM. - To enable CD-ROM support: + To enable CD-ROM support (includes MSCDEX): - mount d f:\ -t cdrom + To enable low-level CD-ROM-support (uses ioctl if possible): + - mount d f:\ -t cdrom -usecd 0 To enable low-level SDL-support: - mount d f:\ -t cdrom -usecd 0 -noioctl - To enable low-level ioctl-support(win2k/xp/linux): - - mount d f:\ -t cdrom -usecd 0 -ioctl To enable low-level aspi-support (win98 with aspi-layer installed): - mount d f:\ -t cdrom -usecd 0 -aspi In the commands: - d driveletter you will get in DOSBox - - f:\ location of cdrom on your PC. + - f:\ location of CD-ROM on your PC. - 0 The number of the CD-ROM drive, reported by mount -cd See also the question: The game/application can't find its CD-ROM. @@ -124,11 +137,11 @@ A: Be sure that the sound is correctly configured in the game. This might be Q: The sound stutters or sounds stretched/weird. -A: You're using too much cpu power to keep DOSBox running at the current speed. +A: You're using too much CPU power to keep DOSBox running at the current speed. You can lower the cycles, skip frames or get a faster machine. You can also increase the prebuffer in the configfile. If you are using cycles=max or =auto, then make sure that there no - background processes interfering! (especially if they acces the harddisk) + background processes interfering! (especially if they access the harddisk) Q: I can't type \ or : in DOSBox. @@ -159,8 +172,11 @@ A: Be sure to mount the CD-ROM with -t cdrom switch, this will enable the Also try adding the correct label (-label LABEL). To enable lower-level CD-ROM support, add the following switch to mount: -usecd #, where # is the number of your CD-ROM drive reported by mount -cd. Under Windows you - can specify -ioctl or -aspi. Look at the description elsewhere in this - document for their meaning. + can specify -ioctl, -aspi or -noioctl. Look at the description elsewhere + in this document for their meaning. + Try creating a CD-ROM image (preferably CUE/BIN pair) and use the + DOSBox-internal IMGMOUNT tool to mount the image. This enables very + good low-level CD-ROM support on any operating system. Q: The game/application runs much too slow! @@ -234,7 +250,6 @@ http://dosbox.sourceforge.net - ========= 3. Usage: ========= @@ -247,7 +262,7 @@ description: dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] [-lang languagefile] [-machine machinetype] [-noconsole] - [-startmapper] [-noautoexec] + [-startmapper] [-noautoexec] [-scaler scaler | -forcescaler scaler] dosbox -version @@ -276,15 +291,15 @@ dosbox -version -lang languagefile Start DOSBox using the language specified in "languagefile". - -noconsole (Windows Only) - Start DOSBox without showing the console window. Output will - be redirected to stdout.txt and stderr.txt - -machine machinetype Setup DOSBox to emulate a specific type of machine. Valid choices are: hercules, cga, pcjr, tandy, vga (default). The machinetype affects both the videocard and the available soundcards. + -noconsole (Windows Only) + Start DOSBox without showing the console window. Output will + be redirected to stdout.txt and stderr.txt + -startmapper Enter the keymapper directly on startup. Useful for people with keyboard problems. @@ -292,6 +307,14 @@ dosbox -version -noautoexec Skips the [autoexec] section of the loaded configuration file. + -scaler scaler + Uses the scaler specified by "scaler". See the DOSBox configuration + file for the available scalers. + + -forcescaler scaler + Similar to the -scaler parameter, but tries to force usage of + the specified scaler even if it might not fit. + -version output version information and exit. Useful for frontends. @@ -327,6 +350,7 @@ In addition, the following commands are available: MOUNT "Emulated Drive letter" "Real Drive or Directory" [-t type] [-aspi] [-ioctl] [-noioctl] [-usecd number] [-size drivesize] [-label drivelabel] [-freesize size_in_mb] + [-freesize size_in_kb (floppies)] MOUNT -cd MOUNT -u "Emulated Drive letter" @@ -343,16 +367,23 @@ MOUNT -u "Emulated Drive letter" floppy, cdrom. -size drivesize - Sets the size of the drive. + Sets the size of the drive, where drivesize is of the form + "bps,spc,tcl,fcl": + bps: bytes per sector, by default 512 for regular drives and + 2048 for CD-ROM drives + spc: sectors per cluster, usually between 1 and 127 + tcl: total clusters, between 1 and 65534 + fcl: total free clusters, between 1 and tcl - -freesize size_in_mb - Sets the amount of free space available on a drive in megabytes. + -freesize size_in_mb | size_in_kb + Sets the amount of free space available on a drive in megabytes + (regular drives) or kilobytes (floppy drives). This is a simpler version of -size. -label drivelabel 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 + program can't find its CD-ROM. If you don't specify a label and no lowlevel support is selected (that is omitting the -usecd # and/or -aspi parameters or specifying -noioctl): For win32: label is extracted from "Real Drive". @@ -362,27 +393,27 @@ MOUNT -u "Emulated Drive letter" is mounted. It will not be updated !! -aspi - Forces use of the aspi layer. Only valid if mounting a cdrom under + Forces use of the aspi layer. Only valid if mounting a CD-ROM under Windows systems with an ASPI-Layer. -ioctl - Forces use of ioctl commands. Only valid if mounting a cdrom under + Forces use of ioctl commands. Only valid if mounting a CD-ROM under a Windows OS which support them (Win2000/XP/NT). -noioctl - Forces use of the SDL cdrom layer. Valid on all systems. + Forces use of the SDL CD-ROM layer. Valid on all systems. -usecd number - Forces use of SDL cdrom support for drive number. + Forces use of SDL CD-ROM support for drive number. Number can be found by -cd. Valid on all systems. -cd - Displays all detected cdrom drives and their numbers. Use with -usecd. + Displays all detected CD-ROM drives and their numbers. Use with -usecd. -u Removes the mount. Doesn't work for Z:\. - Note: It's possible to mount a local directory as cdrom drive. + Note: It's possible to mount a local directory as CD-ROM drive. Hardware support is then missing. Basically MOUNT allows you to connect real hardware to DOSBox's emulated PC. @@ -398,7 +429,7 @@ MOUNT -u "Emulated Drive letter" Mounting your entire C drive with MOUNT C C:\ is NOT recommended! The same is true for mounting the root of any other drive, except for CD-ROMs (due to - their read-only nature). Otherwise if you or DOSBox make a mistakes you may + their read-only nature). Otherwise if you or DOSBox make a mistake you may loose all your files. It is recommended to put all your applications/games into a subdirectory and mount that. @@ -406,15 +437,15 @@ MOUNT -u "Emulated Drive letter" General MOUNT Examples: 1. To mount c:\DirX as a floppy : mount a c:\DirX -t floppy - 2. To mount system cdrom drive E as cdrom drive D in DOSBox: + 2. To mount system CD-ROM drive E as CD-ROM drive D in DOSBox: mount d e:\ -t cdrom - 3. To mount system cdrom drive at mountpoint /media/cdrom as cdrom drive D + 3. To mount system CD-ROM drive at mountpoint /media/cdrom as CD-ROM drive D in DOSBox: mount d /media/cdrom -t cdrom -usecd 0 - 4. To mount a drive with 870 mb free diskspace (simple version): + 4. To mount a drive with ~870 mb free diskspace (simple version): mount c d:\ -freesize 870 - 5. To mount a drive with 870 mb free diskspace (experts only, full control): - mount c d:\ -size 4025,127,16513,1700 + 5. To mount a drive with ~870 mb free diskspace (experts only, full control): + mount c d:\ -size 512,127,16513,13500 6. To mount /home/user/dirY as drive C in DOSBox: mount c /home/user/dirY @@ -423,7 +454,8 @@ MEM Program to display the amount of free memory. -CONFIG [-writeconf] [-writelang] localfile +CONFIG -writeconf localfile +CONFIG -writelang localfile CONFIG -set "section property=value" CONFIG -get "section property" @@ -443,7 +475,7 @@ CONFIG -get "section property" -writelang localfile Write the current language settings to file. "localfile" is located on the local drive, not a mounted drive in DOSBox. - The language file controls all visible ouput of the internal commands + The language file controls all visible output of the internal commands and the internal DOS. -set "section property=value" @@ -480,7 +512,6 @@ LOADFIX -f -f frees all previously allocated memory - Examples: 1. To start mm2.exe and allocate 64kb memory (mm2 will have 64 kb less available) : @@ -507,14 +538,14 @@ MIXER left:right The volume levels in percentages. If you put a D in front it will be - in deciBell (example mixer gus d-10). + in decibel (example mixer gus d-10). /NOSHOW Prevents DOSBox from showing the result if you set one of the volume levels. /LISTMIDI - Lists the available midi devices on your pc (Windows). To select a + Lists the available midi devices on your PC (Windows). To select a device other than the Windows default midi-mapper, add a line 'config=id' to the [midi] section in the configuration file, where 'id' is the number for the device as listed by LISTMIDI. @@ -643,7 +674,7 @@ IPX IPXNET STARTSERVER - IPXNET STARTSERVER starts an IPX tunneling server on this DOSBox + IPXNET STARTSERVER starts an IPX tunnelling server on this DOSBox session. By default, the server will accept connections on UDP port 213, though this can be changed. Once the server is started, DOSBox will automatically start a client connection to the IPX tunnelling server. @@ -723,7 +754,6 @@ For more information use the /? command line switch with the programs. - ================ 5. Special Keys: ================ @@ -822,9 +852,9 @@ Examples about remapping the joystick: You have a joystick attached, it is working fine under DOSBox and you want to play some keyboard-only game with the joystick (it is assumed that the game is controlled by the arrows on the keyboard): - 1) Start the mapper, then klick on one of the arrows in the middle + 1) Start the mapper, then click on one of the arrows in the middle of the left part of the screen (right above the Mod1/Mod2 buttons). - EVENT should be key_left. Now klick on Add and move your joystick + EVENT should be key_left. Now click on Add and move your joystick in the respective direction, this should add an event to the BIND. 2) Repeat the above for the missing three directions, additionally the buttons of the joystick can be remapped as well (fire/jump). @@ -833,12 +863,12 @@ Examples about remapping the joystick: You want to swap the y-axis of the joystick because some flightsim uses the up/down joystick movement in a way you don't like, and it is not configurable in the game itself: - 1) Start the mapper and klick on Y- in the upper joystick field (this + 1) Start the mapper and click on Y- in the upper joystick field (this is for the first joystick if you have two joysticks attached) or the lower joystick field (second joystick or, if you have only one joystick attached, the second axes cross). EVENT should be jaxis_0_1- (or jaxis_1_1-). - 2) Click on Del to remove the current binding, then klick Add and move + 2) Click on Del to remove the current binding, then click Add and move your joystick downwards. A new bind should be created. 3) Repeat this for Y+, save the layout and finally test it with some game. @@ -934,7 +964,7 @@ of the nullmodem connection. These are all parameters: * server: - This nullmodem will be a client connecting to the specified server. (No server argument: be a server.) * transparent:1 - Only send the serial data, no RTS/DTR handshake. Use this - when connecting to anyting other than a nullmodem. + when connecting to anything other than a nullmodem. * telnet:1 - Interpret Telnet data from the remote site. Automatically sets transparent. * usedtr:1 - The connection will not be established until DTR is switched @@ -966,7 +996,7 @@ CPU Cycles at the top then. In this mode you can reduce the amount of cycles on a percentage-basis (hit CTRL-F11) or raise it again (CTRL-F12). - Sometimes customly setting the number of cycles achieves better results, + Sometimes manually setting the number of cycles achieves better results, in the DOSBox configuration file specify for example cycles=30000. When running some DOS application you can raise the cycles with CTRL-F12 even more, but you will be limited by the power of your actual CPU. You can see @@ -1001,14 +1031,14 @@ as possible for DOSBox. Advanced cycles configuration: -The cycles=auto and cycles=max settings can be parametrized to have +The cycles=auto and cycles=max settings can be parameterized to have different startup defaults. The syntax is cycles=auto ["realmode default"] ["protected mode default"%] [limit "cycle limit"] cycles=max ["protected mode default"%] [limit "cycle limit"] Example: cycles=auto 1000 80% limit 20000 - will use cycles=1000 for real mode games, 80% cpu throttling for + will use cycles=1000 for real mode games, 80% CPU throttling for protected mode games along with a hard cycle limit of 20000 @@ -1027,7 +1057,7 @@ Running a certain game closes DOSBox, crashes with some message or hangs: (unmodified configuration file) - try it with sound disabled (use the sound configuration program that comes with the game, additionally you can - use sbtype=none and gus=false) + set sbtype=none and gus=false in the DOSBox configuration file) - change some entries of the DOSBox configuration file, especially try: core=normal fixed cycles (for example cycles=10000) @@ -1042,13 +1072,15 @@ The game exits to the DOSBox prompt with some error message: - mount differently as some games are picky about the locations, for example if you used "mount d d:\oldgames\game" try "mount c d:\oldgames\game" and "mount c d:\oldgames" - - if the game requires a cdrom be sure you used "-t cdrom" when + - if the game requires a CD-ROM be sure you used "-t cdrom" when mounting and try different additional parameters (the ioctl, usecd and label switches, see the appropriate section) - check the file permissions of the game files (remove read-only attributes, add write permissions etc.) - try reinstalling the game within DOSBox + + ==================== 11. The Config File: ==================== @@ -1076,7 +1108,7 @@ look in the current directory for dosbox.conf. 12. The Language File: ====================== -A language file can be generated by CONFIG.COM. +A language file can be generated by CONFIG.COM (CONFIG -writelang langfile). Read it, and you will hopefully understand how to change it. Start DOSBox with the -lang switch to use your new language file. Alternatively, you can setup the filename in the config file in the [dosbox] From e739eeab8e1a9e2a3de57bb38691316ebd6d8c5d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 3 Jul 2007 17:32:14 +0000 Subject: [PATCH 2826/4131] Autobooting of IMG and IMA files when given as first parameter (or dropped on the executable) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2912 --- src/shell/shell.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 2eccad01..4328a5f3 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.85 2007-06-14 08:23:46 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.86 2007-07-03 17:32:14 qbix79 Exp $ */ #include #include @@ -400,12 +400,16 @@ public: autoexec[12].Install(std::string("MOUNT C \"") + buffer + "\""); autoexec[13].Install("C:"); upcase(name); - if(strstr(name,".BAT") == 0) { - autoexec[14].Install(name); - } else { + if(strstr(name,".BAT") != 0) { /* BATch files are called else exit will not work */ autoexec[14].Install(std::string("CALL ") + name); + } else if((strstr(name,".IMG") != 0) || (strstr(name,".IMA") !=0)) { + /* Boot image files */ + autoexec[14].Install(std::string("BOOT ") + name); + } else { + autoexec[14].Install(name); } + if(addexit) autoexec[15].Install("exit"); } } From 7daaf72e2d804b73eec1281b938eaefc5b725cd5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 3 Jul 2007 18:17:45 +0000 Subject: [PATCH 2827/4131] Small update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2913 --- docs/dosbox.1 | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/docs/dosbox.1 b/docs/dosbox.1 index 8751a594..cefa7018 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -1,5 +1,5 @@ .\" Hey, EMACS: -*- nroff -*- -.TH DOSBOX 1 "Mar 28, 2006" +.TH DOSBOX 1 "Jul 01, 2007" .\" Please adjust this date whenever revising the manpage. .SH NAME dosbox \- an x86/DOS emulator with sound/graphics @@ -8,6 +8,8 @@ dosbox \- an x86/DOS emulator with sound/graphics .B [\-fullscreen] .B [\-startmapper] .B [\-noautoexec] +.BI "[\-scaler " scaler ] +.BI "[\-forcescaler " scaler ] .BI "[\-conf " configfile ] .BI "[\-lang " langfile ] .B [file] @@ -39,6 +41,14 @@ A summary of options is included below. .B \-noautoexec Skips the [autoexec] section of the loaded configuration file. .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 . @@ -74,7 +84,7 @@ following extra commands are available: .HP .BI "MOUNT [\-t " type "] [\-size " size ] .I driveletter sourcedirectory -.B [\-aspi] [\-ioctl] +.B [\-ioctl] .BI "[\-usecd " number "] [\-label " drivelabel "] [\-freesize " freesize ] .LP .B MOUNT \-cd @@ -115,18 +125,13 @@ 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 \-aspi -Forces to use the aspi layer. Only valid if mounting a cdrom under -Windows systems with an ASPI-Layer. -.TP .B \-ioctl -Forces to use ioctl commands. Only valid if mounting a cdrom under -windows which support them (Win2000/XP/NT). +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 ". Valid on all systems." +.BR \-cd ". .TP .B \-cd .RB "Displays all detected cdrom drives and their numbers. Use with " \-usecd "." @@ -211,6 +216,13 @@ Boot will start floppy images or hard disk images independent of the .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 From 8f76382e7d0650b5b4c1d28c9359cff92760da9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 5 Jul 2007 16:03:49 +0000 Subject: [PATCH 2828/4131] add a define to disable additional scalers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2914 --- include/render.h | 6 ++++++ src/gui/render.cpp | 24 +++++++++++++++++++++--- src/gui/render_scalers.cpp | 9 ++++++++- src/gui/render_scalers.h | 26 ++++++++++++++++++++++++-- src/gui/render_templates.h | 11 +++++++++++ 5 files changed, 70 insertions(+), 6 deletions(-) diff --git a/include/render.h b/include/render.h index cfd36817..6e85971b 100644 --- a/include/render.h +++ b/include/render.h @@ -19,6 +19,12 @@ #ifndef DOSBOX_RENDER_H #define DOSBOX_RENDER_H +// 0: complex scalers off, scaler cache off, some simple scalers off, memory requirements reduced +// 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 diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 62b31d9c..58e263c4 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.53 2007-07-02 20:06:59 c2woody Exp $ */ +/* $Id: render.cpp,v 1.54 2007-07-05 16:03:49 c2woody Exp $ */ #include #include @@ -291,7 +291,9 @@ static void RENDER_Reset( void ) { else simpleBlock = &ScaleNormal1x; /* Maybe override them */ +#if RENDER_USE_ADVANCED_SCALERS>0 switch (render.scale.op) { +#if RENDER_USE_ADVANCED_SCALERS>2 case scalerOpAdvInterp: if (render.scale.size == 2) complexBlock = &ScaleAdvInterp2x; @@ -322,6 +324,7 @@ static void RENDER_Reset( void ) { if (render.scale.size == 2) complexBlock = &Scale2xSaI; break; +#endif case scalerOpTV: if (render.scale.size == 2) simpleBlock = &ScaleTV2x; @@ -341,6 +344,7 @@ static void RENDER_Reset( void ) { simpleBlock = &ScaleScan3x; break; } +#endif } else if (dblw) { simpleBlock = &ScaleNormalDw; } else if (dblh) { @@ -351,10 +355,14 @@ forcenormal: simpleBlock = &ScaleNormal1x; } if (complexBlock) { +#if RENDER_USE_ADVANCED_SCALERS>1 if ((width >= SCALER_COMPLEXWIDTH - 16) || height >= SCALER_COMPLEXHEIGHT - 16) { LOG_MSG("Scaler can't handle this resolution, going back to normal"); goto forcenormal; } +#else + goto forcenormal; +#endif gfx_flags = complexBlock->gfxFlags; xscale = complexBlock->xscale; yscale = complexBlock->yscale; @@ -423,18 +431,24 @@ forcenormal: E_Exit("Failed to create a rendering output"); ScalerLineBlock_t *lineBlock; if (gfx_flags & GFX_HARDWARE) { +#if RENDER_USE_ADVANCED_SCALERS>1 if (complexBlock) { lineBlock = &ScalerCache; render.scale.complexHandler = complexBlock->Linear[ render.scale.outMode ]; - } else { + } else +#endif + { render.scale.complexHandler = 0; lineBlock = &simpleBlock->Linear; } } else { +#if RENDER_USE_ADVANCED_SCALERS>1 if (complexBlock) { lineBlock = &ScalerCache; render.scale.complexHandler = complexBlock->Random[ render.scale.outMode ]; - } else { + } else +#endif + { render.scale.complexHandler = 0; lineBlock = &simpleBlock->Random; } @@ -581,6 +595,7 @@ void RENDER_Init(Section * sec) { if (!strcasecmp(scaler,"none")) { render.scale.op = scalerOpNormal;render.scale.size = 1; } else if (!strcasecmp(scaler,"normal2x")) { render.scale.op = scalerOpNormal;render.scale.size = 2; } else if (!strcasecmp(scaler,"normal3x")) { render.scale.op = scalerOpNormal;render.scale.size = 3; } +#if RENDER_USE_ADVANCED_SCALERS>2 else if (!strcasecmp(scaler,"advmame2x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 2; } else if (!strcasecmp(scaler,"advmame3x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 3; } else if (!strcasecmp(scaler,"advinterp2x")) { render.scale.op = scalerOpAdvInterp;render.scale.size = 2; } @@ -590,12 +605,15 @@ void RENDER_Init(Section * sec) { else if (!strcasecmp(scaler,"2xsai")) { render.scale.op = scalerOpSaI;render.scale.size = 2; } else if (!strcasecmp(scaler,"super2xsai")) { render.scale.op = scalerOpSuperSaI;render.scale.size = 2; } else if (!strcasecmp(scaler,"supereagle")) { render.scale.op = scalerOpSuperEagle;render.scale.size = 2; } +#endif +#if RENDER_USE_ADVANCED_SCALERS>0 else if (!strcasecmp(scaler,"tv2x")) { render.scale.op = scalerOpTV;render.scale.size = 2; } else if (!strcasecmp(scaler,"tv3x")) { render.scale.op = scalerOpTV;render.scale.size = 3; } else if (!strcasecmp(scaler,"rgb2x")){ render.scale.op = scalerOpRGB;render.scale.size = 2; } else if (!strcasecmp(scaler,"rgb3x")){ render.scale.op = scalerOpRGB;render.scale.size = 3; } else if (!strcasecmp(scaler,"scan2x")){ render.scale.op = scalerOpScan;render.scale.size = 2; } else if (!strcasecmp(scaler,"scan3x")){ render.scale.op = scalerOpScan;render.scale.size = 3; } +#endif else { render.scale.op = scalerOpNormal;render.scale.size = 1; LOG_MSG("Illegal scaler type %s,falling back to normal.",scaler); diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index 9c45a78d..c20d2661 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -36,7 +36,9 @@ static union { } scalerWriteCache; //scalerFrameCache_t scalerFrameCache; scalerSourceCache_t scalerSourceCache; +#if RENDER_USE_ADVANCED_SCALERS>1 scalerChangeCache_t scalerChangeCache; +#endif #define _conc2(A,B) A ## B #define _conc3(A,B,C) A ## B ## C @@ -159,6 +161,7 @@ static INLINE void ScalerAddLines( Bitu changed, Bitu count ) { #undef DBPP +#if RENDER_USE_ADVANCED_SCALERS>1 ScalerLineBlock_t ScalerCache = { { Cache_8_8, Cache_8_15 , Cache_8_16 , Cache_8_32 }, { 0, Cache_15_15, Cache_15_16, Cache_15_32}, @@ -166,6 +169,7 @@ ScalerLineBlock_t ScalerCache = { { 0, Cache_32_15, Cache_32_16, Cache_32_32}, { Cache_8_8, Cache_9_15 , Cache_9_16 , Cache_9_32 } }; +#endif ScalerSimpleBlock_t ScaleNormal1x = { "Normal", @@ -252,6 +256,7 @@ ScalerSimpleBlock_t ScaleNormal3x = { { Normal3x_8_8_R, Normal3x_9_15_R , Normal3x_9_16_R , Normal3x_9_32_R } }}; +#if RENDER_USE_ADVANCED_SCALERS>0 ScalerSimpleBlock_t ScaleTV2x = { "TV2x", GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY, @@ -353,10 +358,12 @@ ScalerSimpleBlock_t ScaleRGB3x = { { 0, RGB3x_32_15_R, RGB3x_32_16_R, RGB3x_32_32_R}, { 0, RGB3x_9_15_R , RGB3x_9_16_R , RGB3x_9_32_R } }}; +#endif /* Complex scalers */ +#if RENDER_USE_ADVANCED_SCALERS>2 ScalerComplexBlock_t ScaleAdvMame2x ={ "AdvMame2x", GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32, @@ -430,4 +437,4 @@ ScalerComplexBlock_t ScaleAdvInterp3x = { { 0,AdvInterp3x_15_R,AdvInterp3x_16_R,AdvInterp3x_32_R} }; - +#endif diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index 2b9d59b5..ad5b5be5 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -21,12 +21,20 @@ //#include "render.h" #include "video.h" -//MAXWIDTH: increased it for the large text modi +#if RENDER_USE_ADVANCED_SCALERS>0 #define SCALER_MAXWIDTH 1280 #define SCALER_MAXHEIGHT 1024 +#else +// reduced to save some memory +#define SCALER_MAXWIDTH 800 +#define SCALER_MAXHEIGHT 600 +#endif +#if RENDER_USE_ADVANCED_SCALERS>1 #define SCALER_COMPLEXWIDTH 800 #define SCALER_COMPLEXHEIGHT 600 +#endif + #define SCALER_BLOCKSIZE 16 typedef enum { @@ -35,16 +43,20 @@ typedef enum { typedef enum scalerOperation { scalerOpNormal, +#if RENDER_USE_ADVANCED_SCALERS>2 scalerOpAdvMame, scalerOpAdvInterp, scalerOpHQ, scalerOpSaI, scalerOpSuperSaI, scalerOpSuperEagle, +#endif +#if RENDER_USE_ADVANCED_SCALERS>0 scalerOpTV, scalerOpRGB, scalerOpScan, - scalerLast, +#endif + scalerLast } scalerOperation_t; typedef void (*ScalerLineHandler_t)(const void *src); @@ -54,6 +66,7 @@ extern Bit8u Scaler_Aspect[]; extern Bit8u diff_table[]; extern Bitu Scaler_ChangedLineIndex; extern Bit16u Scaler_ChangedLines[]; +#if RENDER_USE_ADVANCED_SCALERS>1 /* Not entirely happy about those +2's since they make a non power of 2, with muls instead of shift */ typedef Bit8u scalerChangeCache_t [SCALER_COMPLEXHEIGHT][SCALER_COMPLEXWIDTH / SCALER_BLOCKSIZE] ; typedef union { @@ -61,13 +74,16 @@ typedef union { Bit16u b16 [SCALER_COMPLEXHEIGHT] [SCALER_COMPLEXWIDTH]; Bit8u b8 [SCALER_COMPLEXHEIGHT] [SCALER_COMPLEXWIDTH]; } scalerFrameCache_t; +#endif typedef union { Bit32u b32 [SCALER_MAXHEIGHT] [SCALER_MAXWIDTH]; Bit16u b16 [SCALER_MAXHEIGHT] [SCALER_MAXWIDTH]; Bit8u b8 [SCALER_MAXHEIGHT] [SCALER_MAXWIDTH]; } scalerSourceCache_t; extern scalerSourceCache_t scalerSourceCache; +#if RENDER_USE_ADVANCED_SCALERS>1 extern scalerChangeCache_t scalerChangeCache; +#endif typedef ScalerLineHandler_t ScalerLineBlock_t[5][4]; typedef struct { @@ -97,13 +113,16 @@ extern ScalerSimpleBlock_t ScaleNormalDw; extern ScalerSimpleBlock_t ScaleNormalDh; extern ScalerSimpleBlock_t ScaleNormal2x; extern ScalerSimpleBlock_t ScaleNormal3x; +#if RENDER_USE_ADVANCED_SCALERS>0 extern ScalerSimpleBlock_t ScaleTV2x; extern ScalerSimpleBlock_t ScaleTV3x; extern ScalerSimpleBlock_t ScaleRGB2x; extern ScalerSimpleBlock_t ScaleRGB3x; extern ScalerSimpleBlock_t ScaleScan2x; extern ScalerSimpleBlock_t ScaleScan3x; +#endif /* Complex scalers */ +#if RENDER_USE_ADVANCED_SCALERS>2 extern ScalerComplexBlock_t ScaleHQ2x; extern ScalerComplexBlock_t ScaleHQ3x; extern ScalerComplexBlock_t Scale2xSaI; @@ -113,5 +132,8 @@ extern ScalerComplexBlock_t ScaleAdvMame2x; extern ScalerComplexBlock_t ScaleAdvMame3x; extern ScalerComplexBlock_t ScaleAdvInterp2x; extern ScalerComplexBlock_t ScaleAdvInterp3x; +#endif +#if RENDER_USE_ADVANCED_SCALERS>1 extern ScalerLineBlock_t ScalerCache; #endif +#endif diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index a3ce579b..ba14a5f5 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -152,6 +152,7 @@ #define D6 fc[+2 + 2*SCALER_COMPLEXWIDTH] +#if RENDER_USE_ADVANCED_SCALERS>1 static void conc3d(Cache,SBPP,DBPP) (const void * s) { #ifdef RENDER_NULL_INPUT if (!s) { @@ -208,6 +209,7 @@ static void conc3d(Cache,SBPP,DBPP) (const void * s) { render.scale.inLine++; render.scale.complexHandler(); } +#endif /* Simple scalers */ @@ -281,6 +283,8 @@ static void conc3d(Cache,SBPP,DBPP) (const void * s) { #if (DBPP > 8) +#if RENDER_USE_ADVANCED_SCALERS>0 + #define SCALERNAME TV2x #define SCALERWIDTH 2 #define SCALERHEIGHT 2 @@ -390,9 +394,14 @@ static void conc3d(Cache,SBPP,DBPP) (const void * s) { #undef SCALERHEIGHT #undef SCALERFUNC +#endif //#if RENDER_USE_ADVANCED_SCALERS>0 + #endif //#if (DBPP > 8) /* Complex scalers */ + +#if RENDER_USE_ADVANCED_SCALERS>2 + #if (SBPP == DBPP) @@ -549,6 +558,8 @@ static void conc3d(Cache,SBPP,DBPP) (const void * s) { #endif // (SBPP == DBPP) && !defined (CACHEWITHPAL) +#endif // #if RENDER_USE_ADVANCED_SCALERS>2 + #undef PSIZE #undef PTYPE #undef PMAKE From d4c94c16d5329fd1d97921e1dd793dc35fca8922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 5 Jul 2007 17:44:20 +0000 Subject: [PATCH 2829/4131] add a few porting comments Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2915 --- docs/PORTING | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 docs/PORTING diff --git a/docs/PORTING b/docs/PORTING new file mode 100644 index 00000000..7986ebb3 --- /dev/null +++ b/docs/PORTING @@ -0,0 +1,46 @@ +Some notes about porting DOSBox to systems with certain restrictions, +like handheld devices. + +If memory is a constraint: + - in paging.h reduce the size of the TLB: + #define TLB_SIZE (64*1024) + the 64 gives access to the first 256mb of linear memory + drawback: some protected mode games won't work then + gain: reduces memory requirements about ~15mb + TODO: limit vmemory access to the size of the TLB, + otherwise games which use >256mb vaddresses will crash badly + - 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 whith large directory trees + gain: ~1mb per mounted drive + - in vga.h reduce the size of the emulated graphics memory: + #define VGA_MEMORY (1*1024*1024) + drawback: some graphics modes won't work then + gain: reduces memory requirements about 1mb + TODO: remove the respective svga modes, adapt some svga registers + - remove the GUS emulation (gus.cpp, especially GUSRam[1024*1024] ) + drawback: no gravis ultrasound + gain: reduces memory requirements about 1mb + +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 From a2bcd669fcaa5cda67d8c25a9a7355cce75fe01f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 5 Jul 2007 17:49:40 +0000 Subject: [PATCH 2830/4131] Some refinements in the joystick support to work with non standard joystick layouts Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2916 --- src/gui/sdl_mapper.cpp | 87 ++++++++++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 25 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 142ba1a1..86e0de37 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.35 2007-06-14 18:47:27 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.36 2007-07-05 17:49:40 qbix79 Exp $ */ #include #include @@ -64,6 +64,8 @@ enum BC_Types { #define MAXSTICKS 8 #define MAXACTIVE 16 +#define MAXBUTTON 32 +#define MAXBUTTON_CAP 16 class CEvent; class CHandlerEvent; @@ -600,23 +602,25 @@ public: if (_dummy) { sdl_joystick=NULL; axes=0; buttons=0; hats=0; - button_wrap=16; + button_wrap=0; + button_cap=0; axes_cap=0; hats_cap=0; return; } // initialize emulated joystick state emulated_axes=2; emulated_buttons=2; + emulated_hats=0; pos_axis_lists=new CBindList[4]; neg_axis_lists=new CBindList[4]; - button_lists=new CBindList[16]; + button_lists=new CBindList[MAXBUTTON]; hat_lists=new CBindList[4]; Bitu i; - for (i=0; i<16; i++) { + for (i=0; i16) button_wrap=16; - LOG_MSG("Using joystick %s with %d axes and %d buttons",SDL_JoystickName(stick),axes,buttons); + button_cap=buttons; + if (button_wrapping_enabled) { + button_wrap=emulated_buttons; + if (buttons>MAXBUTTON_CAP) button_cap = MAXBUTTON_CAP; + } + if (button_wrap > MAXBUTTON) button_wrap = MAXBUTTON; + axes_cap=emulated_axes; + if (axes_cap>axes) axes_cap=axes; + hats_cap=emulated_hats; + if (hats_cap>axes) hats_cap=hats; + LOG_MSG("Using joystick %s with %d axes, %d buttons and %d hat(s)",SDL_JoystickName(stick),axes,buttons,hats); } ~CStickBindGroup() { SDL_JoystickClose(sdl_joystick); @@ -724,9 +737,9 @@ public: /* query SDL joystick and activate bindings */ ActivateJoystickBoundEvents(); - bool button_pressed[16]; + bool button_pressed[MAXBUTTON]; Bitu i; - for (i=0; i<16; i++) button_pressed[i]=false; + for (i=0; i1) { @@ -795,7 +808,7 @@ public: } } - for (i=0; iaxes) axes_cap=axes; + hats_cap=emulated_hats; + if (hats_cap>axes) hats_cap=hats; + JOYSTICK_Enable(1,true); } @@ -907,9 +927,9 @@ public: /* query SDL joystick and activate bindings */ ActivateJoystickBoundEvents(); - bool button_pressed[16]; + bool button_pressed[MAXBUTTON]; Bitu i; - for (i=0; i<16; i++) button_pressed[i]=false; + for (i=0; iaxes) axes_cap=axes; + hats_cap=emulated_hats; + if (hats_cap>axes) hats_cap=hats; + JOYSTICK_Enable(1,true); JOYSTICK_Move_Y(1,1.0); } @@ -980,9 +1007,9 @@ public: /* query SDL joystick and activate bindings */ ActivateJoystickBoundEvents(); - bool button_pressed[16]; + bool button_pressed[MAXBUTTON]; Bitu i; - for (i=0; i<16; i++) button_pressed[i]=false; + for (i=0; iaxes) axes_cap=axes; + hats_cap=emulated_hats; + if (hats_cap>axes) hats_cap=hats; + JOYSTICK_Enable(1,true); button_state=0; } @@ -1159,8 +1193,8 @@ public: if (bt_state>hat_priority[i][3]) bt_state=hat_priority[i][3]; } - bool button_pressed[6]; - for (i=0; i<6; i++) button_pressed[i]=false; + bool button_pressed[MAXBUTTON]; + for (i=0; i Date: Thu, 5 Jul 2007 19:26:33 +0000 Subject: [PATCH 2831/4131] typo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2917 --- src/gui/sdl_mapper.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 86e0de37..0c9cee36 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.36 2007-07-05 17:49:40 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.37 2007-07-05 19:26:33 c2woody Exp $ */ #include #include @@ -651,7 +651,7 @@ public: axes_cap=emulated_axes; if (axes_cap>axes) axes_cap=axes; hats_cap=emulated_hats; - if (hats_cap>axes) hats_cap=hats; + if (hats_cap>hats) hats_cap=hats; LOG_MSG("Using joystick %s with %d axes, %d buttons and %d hat(s)",SDL_JoystickName(stick),axes,buttons,hats); } ~CStickBindGroup() { @@ -889,7 +889,7 @@ public: axes_cap=emulated_axes; if (axes_cap>axes) axes_cap=axes; hats_cap=emulated_hats; - if (hats_cap>axes) hats_cap=hats; + if (hats_cap>hats) hats_cap=hats; JOYSTICK_Enable(1,true); } @@ -961,7 +961,7 @@ public: axes_cap=emulated_axes; if (axes_cap>axes) axes_cap=axes; hats_cap=emulated_hats; - if (hats_cap>axes) hats_cap=hats; + if (hats_cap>hats) hats_cap=hats; JOYSTICK_Enable(1,true); JOYSTICK_Move_Y(1,1.0); @@ -1097,7 +1097,7 @@ public: axes_cap=emulated_axes; if (axes_cap>axes) axes_cap=axes; hats_cap=emulated_hats; - if (hats_cap>axes) hats_cap=hats; + if (hats_cap>hats) hats_cap=hats; JOYSTICK_Enable(1,true); button_state=0; From 8afc061422d37da14dd602124fe5aae9e71a17f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 5 Jul 2007 19:36:53 +0000 Subject: [PATCH 2832/4131] disable MMIO on modeswitch Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2918 --- src/ints/int10_modes.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 43a23eda..8870f3a6 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -995,6 +995,7 @@ dac_text16: } IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,reg_31); //Enable banked memory and 256k+ access IO_Write(crtc_base,0x58);IO_Write(crtc_base+1,0x3); //Enable 8 mb of linear addressing + IO_Write(crtc_base,0x53);IO_Write(crtc_base+1,0x0); //Disable MMIO IO_Write(crtc_base,0x38);IO_Write(crtc_base+1,0x48); //Register lock 1 IO_Write(crtc_base,0x39);IO_Write(crtc_base+1,0xa5); //Register lock 2 From 6f9374b2deff02ba89f62985e49e0ae444773581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 14 Jul 2007 16:42:38 +0000 Subject: [PATCH 2833/4131] load floppy images with additional information-sector at their end Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2919 --- src/ints/bios_disk.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 5b56feba..bf6f3040 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.36 2007-06-17 12:26:35 c2woody Exp $ */ +/* $Id: bios_disk.cpp,v 1.37 2007-07-14 16:42:38 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" @@ -199,7 +199,10 @@ imageDisk::imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHard Bitu i=0; bool founddisk = false; while (DiskGeometryList[i].ksize!=0x0) { - if (DiskGeometryList[i].ksize==imgSizeK) { + if ((DiskGeometryList[i].ksize==imgSizeK) || + (DiskGeometryList[i].ksize+1==imgSizeK)) { + if (DiskGeometryList[i].ksize!=imgSizeK) + LOG_MSG("ImageLoader: image file with additional data, might not load!"); founddisk = true; active = true; floppytype = i; From 83de8ea88ca2d02ff5945e55fb3d0561bb8e73c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 15 Jul 2007 16:36:27 +0000 Subject: [PATCH 2834/4131] fix some pcspeaker mode (high-frequency reloading); fixes Test Drive/Grand Prix Cycles and similar Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2920 --- src/hardware/pcspeaker.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 2369d46c..1e063e7e 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /* $Id: pcspeaker.cpp,v 1.23 2007-01-08 19:45:40 qbix79 Exp $ */ + /* $Id: pcspeaker.cpp,v 1.24 2007-07-15 16:36:27 c2woody Exp $ */ #include #include "dosbox.h" @@ -57,6 +57,7 @@ static struct { float volwant,volcur; Bitu last_ticks; float last_index; + Bitu min_tr; DelayEntry entries[SPKR_ENTRIES]; Bitu used; } spkr; @@ -134,6 +135,9 @@ static void ForwardPIT(float newindex) { spkr.pit_last=-SPKR_VOLUME; if (spkr.mode==SPKR_PIT_ON) AddDelayEntry(delay_base,spkr.pit_last); spkr.pit_index=spkr.pit_half; + /* Load the new count */ + spkr.pit_half=spkr.pit_new_half; + spkr.pit_max=spkr.pit_new_max; } else { spkr.pit_index+=passed; return; @@ -189,8 +193,8 @@ void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode) { spkr.pit_max=(1000.0f/PIT_TICK_RATE)*cntr; break; case 3: /* Square wave generator */ - if (cntr<=40) { - /* Makes DIGGER sound better */ + if (cntr Date: Mon, 16 Jul 2007 11:02:32 +0000 Subject: [PATCH 2835/4131] Make use of the dummy parameter. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2921 --- src/gui/sdl_mapper.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 0c9cee36..a6eca022 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.37 2007-07-05 19:26:33 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.38 2007-07-16 11:02:32 qbix79 Exp $ */ #include #include @@ -2153,15 +2153,15 @@ static void CreateBindGroups(void) { break; case JOY_4AXIS: mapper.sticks.stick[mapper.sticks.num_groups++]=new C4AxisBindGroup(joyno); - new CStickBindGroup(joyno+1U); + new CStickBindGroup(joyno+1U,true); break; case JOY_FCS: mapper.sticks.stick[mapper.sticks.num_groups++]=new CFCSBindGroup(joyno); - new CStickBindGroup(joyno+1U); + new CStickBindGroup(joyno+1U,true); break; case JOY_CH: mapper.sticks.stick[mapper.sticks.num_groups++]=new CCHBindGroup(joyno); - new CStickBindGroup(joyno+1U); + new CStickBindGroup(joyno+1U,true); break; case JOY_2AXIS: default: @@ -2169,7 +2169,7 @@ static void CreateBindGroups(void) { if((joyno+1U) < mapper.sticks.num) { mapper.sticks.stick[mapper.sticks.num_groups++]=new CStickBindGroup(joyno+1U); } else { - new CStickBindGroup(joyno+1U); + new CStickBindGroup(joyno+1U,true); } break; } From 4f325587e48c73cb6d9cbd5762d05fd01bac157d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 16 Jul 2007 11:32:39 +0000 Subject: [PATCH 2836/4131] small docs update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2922 --- ChangeLog | 22 ++++++++++++---------- README | 17 +++++++++++++++-- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 352ac332..b1497906 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,44 +1,46 @@ 0.71 - Add a new recompiling cpu core, which should be easier to port. - Add 64 bit version of the recompiling core - - Fix a few small problems with FCBs, (fixes Jewels of darkness and + - 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 and - Archmimedean Dynasty) + - 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. + - 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 + - Add/Fix some ansi codes. (fixes PC Larn and certain versions of infocom games) - Several general DOS fixes. (fixes nba95 and others) - Fix digital joystick centering problem - Reenable textmode 54 and 55. - - Fix a pelmask problem with univbe 5.0 lite. (fixes panzer general) + - 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) + - Fix some svga detection routine. (fixes Grandest Fleet 2) - 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 + - 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 + - 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). + - 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. - General code cleanup. diff --git a/README b/README index 5c1b17f0..019050d8 100644 --- a/README +++ b/README @@ -62,6 +62,7 @@ Q: There is no sound. Q: The sound stutters or sounds stretched/weird. Q: I can't type \ or : in DOSBox. Q: The keyboard lags. +Q: The cursor always moves into one direction! Q: The game/application can't find its CD-ROM. Q: The game/application runs much too slow! Q: Can DOSBox harm my computer? @@ -138,8 +139,9 @@ A: Be sure that the sound is correctly configured in the game. This might be Q: The sound stutters or sounds stretched/weird. A: You're using too much CPU power to keep DOSBox running at the current speed. - You can lower the cycles, skip frames or get a faster machine. - You can also increase the prebuffer in the configfile. + You can lower the cycles, skip frames, reduce the sampling rate of + the respective sound device (see the DOSBox configuration file) or + the mixer device. You can also increase the prebuffer in the configfile. If you are using cycles=max or =auto, then make sure that there no background processes interfering! (especially if they access the harddisk) @@ -166,6 +168,15 @@ A: Lower the priority setting in the DOSBox configuration file try lowering the cycles. +Q: The cursor always moves into one direction! +A: See if it still happens if you disable the joystick emulation, + set joysticktype=none in the [joystick] section of your DOSBox + configuration file. Maybe also try unplugging any joystick. + If you want to use the joystick in the game, try setting timed=false + and be sure to calibrate the joystick (both in your OS as well as + in the game or the game's setup). + + Q: The game/application can't find its CD-ROM. A: Be sure to mount the CD-ROM with -t cdrom switch, this will enable the MSCDEX interface required by DOS games to interface with CD-ROMs. @@ -448,6 +459,8 @@ MOUNT -u "Emulated Drive letter" mount c d:\ -size 512,127,16513,13500 6. To mount /home/user/dirY as drive C in DOSBox: mount c /home/user/dirY + 7. To mount the directory where DOSBox was started as D in DOSBox: + mount d . MEM From ade6b1cd59f003c1206102f4e6ee7ce68043c3b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 17 Jul 2007 13:50:27 +0000 Subject: [PATCH 2837/4131] add some feedback to the mapper screen Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2923 --- src/gui/sdl_mapper.cpp | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index a6eca022..95773c64 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.38 2007-07-16 11:02:32 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.39 2007-07-17 13:50:27 c2woody Exp $ */ #include #include @@ -42,6 +42,8 @@ enum { CLR_BLACK=0, CLR_WHITE=1, CLR_RED=2, + CLR_BLUE=3, + CLR_GREEN=4 }; enum BB_Types { @@ -1320,6 +1322,9 @@ protected: const char * text; }; +class CEventButton; +static CEventButton * last_clicked = NULL; + class CEventButton : public CTextButton { public: CEventButton(Bitu _x,Bitu _y,Bitu _dx,Bitu _dy,const char * _text,CEvent * _event) @@ -1327,7 +1332,10 @@ public: event=_event; } void Click(void) { + if (last_clicked) last_clicked->SetColor(CLR_WHITE); + this->SetColor(CLR_GREEN); SetActiveEvent(event); + last_clicked=this; } protected: CEvent * event; @@ -1356,6 +1364,8 @@ void CCaptionButton::Change(const char * format,...) { mapper.redraw=true; } +static void change_action_text(const char* text,Bit8u col); + static void MAPPER_SaveBinds(void); class CBindButton : public CTextButton { public: @@ -1368,6 +1378,7 @@ public: case BB_Add: mapper.addbind=true; SetActiveBind(0); + change_action_text("Press a key/joystick button or move the joystick.",CLR_RED); break; case BB_Del: if (mapper.abindit!=mapper.aevent->bindlist.end()) { @@ -1602,6 +1613,13 @@ static struct { CCheckButton * mod1,* mod2,* mod3,* hold; } bind_but; + +static void change_action_text(const char* text,Bit8u col) { + bind_but.action->Change(text); + bind_but.action->SetColor(col); +} + + static void SetActiveBind(CBind * _bind) { mapper.abind=_bind; if (_bind) { @@ -1631,10 +1649,11 @@ static void SetActiveEvent(CEvent * event) { mapper.addbind=false; bind_but.event_title->Change("EVENT:%s",event ? event->GetName(): "none"); if (!event) { - bind_but.action->Change("Select an event to change"); + change_action_text("Select an event to change.",CLR_WHITE); bind_but.add->Enable(false); SetActiveBind(0); } else { + change_action_text("Select a different event or hit the Add/Del/Next buttons.",CLR_WHITE); mapper.abindit=event->bindlist.begin(); if (mapper.abindit!=event->bindlist.end()) { SetActiveBind(*(mapper.abindit)); @@ -1891,7 +1910,7 @@ static void CreateLayout(void) { new CTextButton(PX(6),00,124,20,"Keyboard Layout"); new CTextButton(PX(17),00,124,20,"Joystick Layout"); - bind_but.action=new CCaptionButton(200,330,0,0); + bind_but.action=new CCaptionButton(185,330,0,0); bind_but.event_title=new CCaptionButton(0,350,0,0); bind_but.bind_title=new CCaptionButton(00,365,0,0); @@ -1914,10 +1933,12 @@ static void CreateLayout(void) { bind_but.bind_title->Change("Bind Title"); } -static SDL_Color map_pal[4]={ +static SDL_Color map_pal[5]={ {0x00,0x00,0x00,0x00}, //0=black {0xff,0xff,0xff,0x00}, //1=white {0xff,0x00,0x00,0x00}, //2=red + {0x10,0x30,0xff,0x00}, //3=blue + {0x00,0xff,0x20,0x00} //4=green }; static void CreateStringBind(char * line) { @@ -2210,7 +2231,8 @@ void MAPPER_Run(bool pressed) { if (mapper.surface == NULL) E_Exit("Could not initialize video mode for mapper: %s",SDL_GetError()); /* Set some palette entries */ - SDL_SetPalette(mapper.surface, SDL_LOGPAL|SDL_PHYSPAL, map_pal, 0, 4); + SDL_SetPalette(mapper.surface, SDL_LOGPAL|SDL_PHYSPAL, map_pal, 0, 5); + last_clicked=NULL; /* Go in the event loop */ mapper.exit=false; mapper.redraw=true; From 6403c0e6edf8565d386a157a2498ee40ded6709a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 19 Jul 2007 18:58:39 +0000 Subject: [PATCH 2838/4131] reduce logging a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2924 --- src/dos/dos_mscdex.cpp | 6 +++--- src/hardware/memory.cpp | 18 +++++++++++++++++- src/hardware/serialport/softmodem.cpp | 10 ++++++++-- src/hardware/serialport/softmodem.h | 26 +++++++++++++++++++++----- 4 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 2d582c7a..9f7f2742 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.48 2007-06-27 19:14:59 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.49 2007-07-19 18:58:39 c2woody Exp $ */ #include #include @@ -877,7 +877,7 @@ static Bit16u MSCDEX_IOCTL_Input(PhysPt buffer,Bit8u drive_unit) { Bit8u addr_mode = mem_readb(buffer+1); if (addr_mode==0) { // HSG Bit32u frames=MSF_TO_FRAMES(pos.min, pos.sec, pos.fr); - if (frames<150) LOG_MSG("MSCDEX: Get position: invalid position %d:%d:%d", pos.min, pos.sec, pos.fr); + if (frames<150) MSCDEX_LOG("MSCDEX: Get position: invalid position %d:%d:%d", pos.min, pos.sec, pos.fr); else frames-=150; mem_writed(buffer+2,frames); } else if (addr_mode==1) { // Red book @@ -886,7 +886,7 @@ static Bit16u MSCDEX_IOCTL_Input(PhysPt buffer,Bit8u drive_unit) { mem_writeb(buffer+4,pos.min); mem_writeb(buffer+5,0x00); } else { - LOG_MSG("MSCDEX: Get position: invalid address mode %x",addr_mode); + MSCDEX_LOG("MSCDEX: Get position: invalid address mode %x",addr_mode); return 0x03; // invalid function } }break; diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 64c0743c..b0769130 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: memory.cpp,v 1.50 2007-06-14 08:23:46 qbix79 Exp $ */ +/* $Id: memory.cpp,v 1.51 2007-07-19 18:58:39 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -63,11 +63,27 @@ public: flags=PFLAG_INIT|PFLAG_NOCODE; } Bitu readb(PhysPt addr) { +#if C_DEBUG LOG_MSG("Illegal read from %x, CS:IP %8x:%8x",addr,SegValue(cs),reg_eip); +#else + static Bits lcount=0; + if (lcount<1000) { + lcount++; + LOG_MSG("Illegal read from %x, CS:IP %8x:%8x",addr,SegValue(cs),reg_eip); + } +#endif return 0; } void writeb(PhysPt addr,Bitu val) { +#if C_DEBUG LOG_MSG("Illegal write to %x, CS:IP %8x:%8x",addr,SegValue(cs),reg_eip); +#else + static Bits lcount=0; + if (lcount<1000) { + lcount++; + LOG_MSG("Illegal write to %x, CS:IP %8x:%8x",addr,SegValue(cs),reg_eip); + } +#endif } }; diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index 112a0cfe..1b08c4f6 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.cpp,v 1.7 2007-01-13 08:35:49 qbix79 Exp $ */ +/* $Id: softmodem.cpp,v 1.8 2007-07-19 18:58:39 c2woody Exp $ */ #include "dosbox.h" @@ -90,7 +90,13 @@ void CSerialModem::handleUpperEvent(Bit16u type) { if(tqueue->left() < 2) { CSerial::setCTS(false); } - } else LOG_MSG("MODEM: TX Buffer overflow!"); + } else { + static Bits lcount=0; + if (lcount<1000) { + lcount++; + LOG_MSG("MODEM: TX Buffer overflow!"); + } + } ByteTransmitted(); break; diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index c51d915e..2c128f82 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.h,v 1.7 2007-01-13 08:35:49 qbix79 Exp $ */ +/* $Id: softmodem.h,v 1.8 2007-07-19 18:58:39 c2woody Exp $ */ #ifndef DOSBOX_SERIALMODEM_H #define DOSBOX_SERIALMODEM_H @@ -73,7 +73,11 @@ public: void addb(Bit8u _val) { if(used>=size) { - LOG_MSG("FIFO Overflow!"); + static Bits lcount=0; + if (lcount<1000) { + lcount++; + LOG_MSG("MODEM: FIFO Overflow! (addb)"); + } return; } //assert(usedsize) { - LOG_MSG("FIFO Overflow!"); + static Bits lcount=0; + if (lcount<1000) { + lcount++; + LOG_MSG("MODEM: FIFO Overflow! (adds len %d)",_len); + } return; } @@ -100,7 +108,11 @@ public: } Bit8u getb(void) { if (!used) { - LOG_MSG("MODEM: FIFO UNDERFLOW!"); + static Bits lcount=0; + if (lcount<1000) { + lcount++; + LOG_MSG("MODEM: FIFO UNDERFLOW! (getb)"); + } return data[pos]; } Bitu where=pos; @@ -111,7 +123,11 @@ public: } void gets(Bit8u * _str,Bitu _len) { if (!used) { - LOG_MSG("MODEM: FIFO UNDERFLOW!"); + static Bits lcount=0; + if (lcount<1000) { + lcount++; + LOG_MSG("MODEM: FIFO UNDERFLOW! (gets len %d)",_len); + } return; } //assert(used>=_len); From f25f371575eaf92be389c9971207cb7d9c0b8603 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 20 Jul 2007 18:22:28 +0000 Subject: [PATCH 2839/4131] Only use lowerpart of CX when dealing with cdrom drives.(Fixes Genesia) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2925 --- src/dos/dos_mscdex.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 9f7f2742..dde2aba6 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.49 2007-07-19 18:58:39 c2woody Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.50 2007-07-20 18:22:28 qbix79 Exp $ */ #include #include @@ -190,12 +190,14 @@ void CMscdex::GetDrives(PhysPt data) bool CMscdex::IsValidDrive(Bit16u _drive) { + _drive &= 0xff; //Only lowerpart (Ultimate domain) for (Bit16u i=0; i Date: Fri, 20 Jul 2007 18:24:25 +0000 Subject: [PATCH 2840/4131] Make PORTING part of the sourcepackage Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2926 --- docs/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Makefile.am b/docs/Makefile.am index 7e313172..682aab2a 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -1,7 +1,7 @@ # Main Makefile for DOSBox man_MANS = dosbox.1 -EXTRA_DIST = $(man_MANS) README.video +EXTRA_DIST = $(man_MANS) README.video PORTING From f1492eb4bce0fd04fcba75809ac9a4a0e8619389 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 20 Jul 2007 18:26:10 +0000 Subject: [PATCH 2841/4131] Some more configure switches Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2927 --- INSTALL | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/INSTALL b/INSTALL index 56e62818..60ae2677 100644 --- a/INSTALL +++ b/INSTALL @@ -41,24 +41,39 @@ In step 1 you could add the following switches: --enable-debug 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 pause to enter the debugger. - ---disable-fpu - Will disable the emulated fpu. Although the fpu emulation code isn't - finished and isn't entirely accurate it's advised to leave it on. + window is active press alt-pause to enter the debugger. --enable-core-inline enables some memory increasing inlines. This greatly increases compiletime for maybe a increase in speed. ---disable-dynamic-x86 - disables the dynamic cpu core. Although it's unstable it can greatly - improve the speed of dosbox on x86 hosts. +--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 From 0620995611d74612f77e7c3a5893181c3d51f4f2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 20 Jul 2007 18:53:52 +0000 Subject: [PATCH 2842/4131] A very fake DPB for some editor. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2928 --- include/dos_inc.h | 3 ++- src/dos/dos.cpp | 41 +++++++++++++++++++++-------------------- src/dos/dos_tables.cpp | 6 +++++- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index d748a016..9f38dbe3 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.69 2007-06-14 08:23:46 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.70 2007-07-20 18:53:52 qbix79 Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -623,6 +623,7 @@ struct DOS_Block { 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; }; diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 168efe4a..db1a1731 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.102 2007-06-13 07:25:14 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.103 2007-07-20 18:53:52 qbix79 Exp $ */ #include #include @@ -385,12 +385,15 @@ static Bitu DOS_21Handler(void) { dos.return_code=reg_al; //Officially a field in the SDA dos.return_mode=RETURN_TSR; break; - case 0x32: /* Get drive parameter block for specific drive */ + case 0x1f: /* Get drive parameter block for default drive */ + case 0x32: /* Get drive parameter block for specific drive */ { /* Officially a dpb should be returned as well. The disk detection part is implemented */ - Bitu drive=reg_dl;if(!drive) drive=dos.current_drive;else drive--; + Bitu drive=reg_dl;if(!drive || reg_ah==0x1f) drive=dos.current_drive;else drive--; if(Drives[drive]) { - reg_al=0x00; - LOG(LOG_DOSMISC,LOG_ERROR)("Get drive parameter block."); + reg_al = 0x00; + SegSet16(ds,dos.tables.dpb); + reg_bx = drive;//Faking only the first entry (that is the driveletter) + LOG(LOG_DOSMISC,LOG_ERROR)("Get drive parameter block."); } else { reg_al=0xff; } @@ -987,23 +990,21 @@ static Bitu DOS_21Handler(void) { LOG(LOG_DOSMISC,LOG_NORMAL)("DOS:Windows long file name support call %2X",reg_al); break; - case 0x68: /* FFLUSH Commit file */ - CALLBACK_SCF(false); //mirek - case 0xE0: - case 0x18: /* NULL Function for CP/M compatibility or Extended rename FCB */ - case 0x1d: /* NULL Function for CP/M compatibility or Extended rename FCB */ - case 0x1e: /* NULL Function for CP/M compatibility or Extended rename FCB */ - case 0x20: /* NULL Function for CP/M compatibility or Extended rename FCB */ - case 0x6b: /* NULL Function */ - case 0x61: /* UNUSED */ - case 0xEF: /* Used in Ancient Art Of War CGA */ - case 0x1f: /* Get drive parameter block for default drive */ - + case 0x68: /* FFLUSH Commit file */ + CALLBACK_SCF(false); //mirek + case 0xE0: + case 0x18: /* NULL Function for CP/M compatibility or Extended rename FCB */ + case 0x1d: /* NULL Function for CP/M compatibility or Extended rename FCB */ + case 0x1e: /* NULL Function for CP/M compatibility or Extended rename FCB */ + case 0x20: /* NULL Function for CP/M compatibility or Extended rename FCB */ + case 0x6b: /* NULL Function */ + case 0x61: /* UNUSED */ + case 0xEF: /* Used in Ancient Art Of War CGA */ case 0x5c: /* FLOCK File region locking */ case 0x5e: /* More Network Functions */ - default: - LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Unhandled call %02X al=%02X. Set al to default of 0",reg_ah,reg_al); - reg_al=0x00; /* default value */ + default: + LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Unhandled call %02X al=%02X. Set al to default of 0",reg_ah,reg_al); + reg_al=0x00; /* default value */ break; }; return CBRET_NONE; diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 3f2546ac..4cf0a35f 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.28 2007-06-12 20:22:08 c2woody Exp $ */ +/* $Id: dos_tables.cpp,v 1.29 2007-07-20 18:53:52 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -145,6 +145,10 @@ void DOS_SetupTables(void) { real_writew(seg,4,100); //File Table supports 100 files dos_infoblock.SetFCBTable(RealMake(seg,0)); + /* Create a fake DPB */ + dos.tables.dpb=DOS_GetMemory(2); + for(Bitu d=0;d<26;d++) real_writeb(dos.tables.dpb,d,d); + /* Create a fake disk buffer head */ seg=DOS_GetMemory(6); for (Bitu ct=0; ct<0x20; ct++) real_writeb(seg,ct,0); From 2773ef7adf3171b171290ac07d3acef6ef34bd88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 21 Jul 2007 08:46:50 +0000 Subject: [PATCH 2843/4131] fix some register backsave (thanks crazyc for noting); skip addr reg saving if possible Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2929 --- src/cpu/core_dynrec/decoder_basic.h | 4 ++++ src/cpu/core_dynrec/decoder_opcodes.h | 3 ++- src/cpu/core_dynrec/dyn_fpu.h | 2 ++ src/cpu/core_dynrec/risc_x64.h | 7 ++++++- src/cpu/core_dynrec/risc_x86.h | 7 ++++++- 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index d0cd4e2a..2ec74b85 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -1000,12 +1000,16 @@ static void dyn_add_iocheck_var(Bit8u accessed_port,Bitu access_size) { // save back the address register static void gen_protect_addr_reg(void) { +#ifdef DRC_PROTECT_ADDR_REG gen_mov_word_from_reg(FC_ADDR,&core_dynrec.protected_regs[FC_ADDR],true); +#endif } // restore the address register static void gen_restore_addr_reg(void) { +#ifdef DRC_PROTECT_ADDR_REG gen_mov_word_to_reg(FC_ADDR,&core_dynrec.protected_regs[FC_ADDR],true); +#endif } // save back an arbitrary register diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index 7ebe59a5..29ba55c9 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -814,7 +814,7 @@ static bool dyn_grp4_ev(void) { dyn_get_modrm(); if (decode.modrm.mod<3) { dyn_fill_ea(FC_ADDR); - if (decode.modrm.reg<2) gen_protect_addr_reg(); + if ((decode.modrm.reg<2) || (decode.modrm.reg==3) || (decode.modrm.reg==5)) gen_protect_addr_reg(); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); } else { gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); @@ -847,6 +847,7 @@ static bool dyn_grp4_ev(void) { case 0x3: // CALL Ep case 0x5: // JMP Ep if (!decode.big_op) gen_extend_word(false,FC_OP1); + if (decode.modrm.mod<3) gen_restore_addr_reg(); gen_protect_reg(FC_OP1); gen_add_imm(FC_ADDR,decode.big_op?4:2); dyn_read_word(FC_ADDR,FC_OP2,decode.big_op); diff --git a/src/cpu/core_dynrec/dyn_fpu.h b/src/cpu/core_dynrec/dyn_fpu.h index 6d7ad518..8491da5d 100644 --- a/src/cpu/core_dynrec/dyn_fpu.h +++ b/src/cpu/core_dynrec/dyn_fpu.h @@ -149,8 +149,10 @@ static void dyn_fpu_esc1(){ 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 */ diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index aa7bc2b9..b74ccce6 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -20,6 +20,9 @@ // some configuring defines that specify the capabilities of this architecture // or aspects of the recompiling +// protect FC_ADDR over function calls if necessaray +// #define DRC_PROTECT_ADDR_REG + // try to use non-flags generating functions if possible // #define DRC_FLAGS_INVALIDATION @@ -45,7 +48,9 @@ typedef Bit8u HostReg; // register that holds function return values #define FC_RETOP HOST_EAX -// register used for address calculations, +// register used for address calculations, if the ABI does not +// state that this register is preserved across function calls +// then define DRC_PROTECT_ADDR_REG above #define FC_ADDR HOST_EBX // register that holds the first parameter diff --git a/src/cpu/core_dynrec/risc_x86.h b/src/cpu/core_dynrec/risc_x86.h index 98dd3b60..4b5759e3 100644 --- a/src/cpu/core_dynrec/risc_x86.h +++ b/src/cpu/core_dynrec/risc_x86.h @@ -20,6 +20,9 @@ // some configuring defines that specify the capabilities of this architecture // or aspects of the recompiling +// protect FC_ADDR over function calls if necessaray +// #define DRC_PROTECT_ADDR_REG + // try to use non-flags generating functions if possible #define DRC_FLAGS_INVALIDATION @@ -52,7 +55,9 @@ enum HostReg { // register that holds function return values #define FC_RETOP HOST_EAX -// register used for address calculations, +// register used for address calculations, if the ABI does not +// state that this register is preserved across function calls +// then define DRC_PROTECT_ADDR_REG above #define FC_ADDR HOST_EBX // register that holds the first parameter From 60292aed8bea3c0b5560817fee24fdd4c2863cac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 22 Jul 2007 18:48:54 +0000 Subject: [PATCH 2844/4131] move part of flags filling into backend; replace simple-function calls with code if possible during flags invalidation pass (thanks to crazyc); work around fpu bug (x86_64 only) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2930 --- src/cpu/core_dynrec.cpp | 1 + src/cpu/core_dynrec/decoder_basic.h | 32 ++++---- src/cpu/core_dynrec/dyn_fpu.h | 2 +- src/cpu/core_dynrec/operators.h | 110 ++++++++++++++-------------- src/cpu/core_dynrec/risc_x64.h | 10 +++ src/cpu/core_dynrec/risc_x86.h | 78 +++++++++++++++++++- 6 files changed, 161 insertions(+), 72 deletions(-) diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index 55a631ea..fc7b1a81 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -48,6 +48,7 @@ #include "debug.h" #include "paging.h" #include "inout.h" +#include "lazyflags.h" #define CACHE_MAXSIZE (4096) #define CACHE_TOTAL (1024*1024*8) diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index 2ec74b85..b8f515bb 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -1029,16 +1029,15 @@ static void gen_restore_reg(HostReg reg,HostReg dest_reg) { -#include "lazyflags.h" - // flags optimization functions // they try to find out if a function can be replaced by another // one that does not generate any flags at all static Bitu mf_functions_num=0; static struct { - DRC_PTR_SIZE_IM pos; - Bit32u fct_ptr; + Bit8u* pos; + void* fct_ptr; + Bitu ftype; } mf_functions[64]; static void InitFlagsOptimization(void) { @@ -1051,7 +1050,7 @@ static void InitFlagsOptimization(void) { static void InvalidateFlags(void) { #ifdef DRC_FLAGS_INVALIDATION for (Bitu ct=0; ct Date: Wed, 25 Jul 2007 21:44:21 +0000 Subject: [PATCH 2845/4131] fix some logging (see sf patch #1663965) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2931 --- src/cpu/core_normal/prefix_0f.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 086771b7..0f229830 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -148,7 +148,7 @@ Bitu which=(rm >> 3) & 7; if (rm < 0xc0 ) { rm |= 0xc0; - LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%d with non-register",which); + LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%u with non-register",which); } GetEArd; Bit32u crx_value; @@ -162,7 +162,7 @@ Bitu which=(rm >> 3) & 7; if (rm < 0xc0 ) { rm |= 0xc0; - LOG(LOG_CPU,LOG_ERROR)("MOV XXX,DR% with non-register",which); + LOG(LOG_CPU,LOG_ERROR)("MOV XXX,DR%u with non-register",which); } GetEArd; Bit32u drx_value; @@ -176,7 +176,7 @@ Bitu which=(rm >> 3) & 7; if (rm < 0xc0 ) { rm |= 0xc0; - LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR% with non-register",which); + LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%u with non-register",which); } GetEArd; if (CPU_WRITE_CRX(which,*eard)) RUNEXCEPTION(); @@ -188,7 +188,7 @@ Bitu which=(rm >> 3) & 7; if (rm < 0xc0 ) { rm |= 0xc0; - LOG(LOG_CPU,LOG_ERROR)("MOV DR%,XXX with non-register",which); + LOG(LOG_CPU,LOG_ERROR)("MOV DR%u,XXX with non-register",which); } GetEArd; if (CPU_WRITE_DRX(which,*eard)) RUNEXCEPTION(); @@ -200,7 +200,7 @@ Bitu which=(rm >> 3) & 7; if (rm < 0xc0 ) { rm |= 0xc0; - LOG(LOG_CPU,LOG_ERROR)("MOV XXX,TR% with non-register",which); + LOG(LOG_CPU,LOG_ERROR)("MOV XXX,TR%u with non-register",which); } GetEArd; Bit32u trx_value; @@ -214,7 +214,7 @@ Bitu which=(rm >> 3) & 7; if (rm < 0xc0 ) { rm |= 0xc0; - LOG(LOG_CPU,LOG_ERROR)("MOV TR%,XXX with non-register",which); + LOG(LOG_CPU,LOG_ERROR)("MOV TR%u,XXX with non-register",which); } GetEArd; if (CPU_WRITE_TRX(which,*eard)) RUNEXCEPTION(); From b6785a6f051eccf1e43831aecae688653ee49f50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 26 Jul 2007 19:09:14 +0000 Subject: [PATCH 2846/4131] enable flags invalidation for x86_64 backend; update docs Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2932 --- docs/PORTING | 12 +++++++----- src/cpu/core_dynrec/risc_x64.h | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/PORTING b/docs/PORTING index 7986ebb3..b2d0b8a1 100644 --- a/docs/PORTING +++ b/docs/PORTING @@ -24,14 +24,16 @@ If memory is a constraint: #define MAX_OPENDIRS 256 drawback: some apps might not work whith large directory trees gain: ~1mb per mounted drive - - in vga.h reduce the size of the emulated graphics memory: - #define VGA_MEMORY (1*1024*1024) - drawback: some graphics modes won't work then - gain: reduces memory requirements about 1mb - TODO: remove the respective svga modes, adapt some svga registers - remove the GUS emulation (gus.cpp, especially GUSRam[1024*1024] ) drawback: no gravis ultrasound gain: reduces memory requirements about 1mb + - in vga.h reduce the size of the emulated graphics memory: + #define VGA_MEMORY (1*1024*1024) + drawback: some graphics modes won't work then + [EDIT: many modes won't work due to pixel caches] + gain: reduces memory requirements about 1mb + TODO: get this to actually work; + remove the respective svga modes, adapt some svga registers If speed is a constraint: - see if the simple core is faster, possibly remove the normal core diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index ceba077f..8c71f534 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -24,7 +24,7 @@ // #define DRC_PROTECT_ADDR_REG // try to use non-flags generating functions if possible -// #define DRC_FLAGS_INVALIDATION +#define DRC_FLAGS_INVALIDATION // try to replace _simple functions by code // #define DRC_FLAGS_INVALIDATION_DCODE From ae6c4effb6d21d267f1b30df13c641731109b401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 27 Jul 2007 16:53:31 +0000 Subject: [PATCH 2847/4131] add MIPS32 le backend for the recompiler core (crazyc) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2933 --- src/cpu/core_dynrec.cpp | 7 +- src/cpu/core_dynrec/risc_mipsel32.h | 632 ++++++++++++++++++++++++++++ 2 files changed, 637 insertions(+), 2 deletions(-) create mode 100644 src/cpu/core_dynrec/risc_mipsel32.h diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index fc7b1a81..f9af3efa 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -133,13 +133,16 @@ static struct { #include "core_dynrec/cache.h" -#define X86 0x01 -#define X86_64 0x02 +#define X86 0x01 +#define X86_64 0x02 +#define MIPSEL32 0x03 #if C_TARGETCPU == X86_64 #include "core_dynrec/risc_x64.h" #elif C_TARGETCPU == X86 #include "core_dynrec/risc_x86.h" +#elif C_TARGETCPU == MIPSEL32 +#include "core_dynrec/risc_mipsel32.h" #endif #include "core_dynrec/decoder.h" diff --git a/src/cpu/core_dynrec/risc_mipsel32.h b/src/cpu/core_dynrec/risc_mipsel32.h new file mode 100644 index 00000000..a6718feb --- /dev/null +++ b/src/cpu/core_dynrec/risc_mipsel32.h @@ -0,0 +1,632 @@ +/* + * 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. + */ + + +/* MIPS32 (little endian) backend by crazyc */ + + +// some configuring defines that specify the capabilities of this architecture +// or aspects of the recompiling + +// protect FC_ADDR over function calls if necessaray +// #define DRC_PROTECT_ADDR_REG + +// try to use non-flags generating functions if possible +#define DRC_FLAGS_INVALIDATION +// try to replace _simple functions by code +#define DRC_FLAGS_INVALIDATION_DCODE + +// type with the same size as a pointer +#define DRC_PTR_SIZE_IM Bit32u + +// calling convention modifier +#define DRC_CALL_CONV /* nothing */ +#define DRC_FC /* nothing */ + +// register mapping +typedef Bit8u HostReg; + +#define HOST_v0 2 +#define HOST_v1 3 +#define HOST_a0 4 +#define HOST_a1 5 +#define HOST_t4 12 +#define HOST_t5 13 +#define HOST_t6 14 +#define HOST_t7 15 +#define HOST_s0 16 +#define HOST_t8 24 +#define HOST_t9 25 +#define temp1 HOST_v1 +#define temp2 HOST_t9 + +// register that holds function return values +#define FC_RETOP HOST_v0 + +// register used for address calculations, +#define FC_ADDR HOST_s0 // has to be saved across calls, see DRC_PROTECT_ADDR_REG + +// register that holds the first parameter +#define FC_OP1 HOST_a0 + +// register that holds the second parameter +#define FC_OP2 HOST_a1 + +// register that holds byte-accessible temporary values +#define FC_TMP_BA1 HOST_t5 + +// register that holds byte-accessible temporary values +#define FC_TMP_BA2 HOST_t6 + +// temporary register for LEA +#define TEMP_REG_DRC HOST_t7 + +// save some state to improve code gen +static bool temp1_valid = false; +static Bit32u temp1_value; + +// move a full register from reg_src to reg_dst +static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { + if(reg_src == reg_dst) return; + cache_addw((reg_dst<<11)+0x21); // addu reg_dst, $0, reg_src + cache_addw(reg_src); +} + +// move a 32bit constant value into dest_reg +static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { + if(imm < 65536) { + cache_addw((Bit16u)imm); // ori dest_reg, $0, imm + cache_addw(0x3400+dest_reg); + } else if(((Bit32s)imm < 0) && ((Bit32s)imm >= -32768)) { + cache_addw((Bit16u)imm); // addiu dest_reg, $0, imm + cache_addw(0x2400+dest_reg); + } else if(!(imm & 0xffff)) { + cache_addw((Bit16u)(imm >> 16)); // lui dest_reg, %hi(imm) + cache_addw(0x3c00+dest_reg); + } else { + cache_addw((Bit16u)(imm >> 16)); // lui dest_reg, %hi(imm) + cache_addw(0x3c00+dest_reg); + cache_addw((Bit16u)imm); // ori dest_reg, dest_reg, %lo(imm) + cache_addw(0x3400+(dest_reg<<5)+dest_reg); + } +} + +// this is the only place temp1 should be modified +static void INLINE mov_imm_to_temp1(Bit32u imm) { + if (temp1_valid && (temp1_value == imm)) return; + gen_mov_dword_to_reg_imm(temp1, imm); + temp1_valid = true; + temp1_value = imm; +} + +static Bit16s gen_addr_temp1(Bit32u addr) { + Bit32u hihalf = addr & 0xffff0000; + Bit16s lohalf = addr & 0xffff; + if (lohalf > 32764) { // [l,s]wl will overflow + hihalf = addr; + lohalf = 0; + } else if(lohalf < 0) hihalf += 0x10000; + mov_imm_to_temp1(hihalf); + return lohalf; +} + +// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { + Bit16s lohalf = gen_addr_temp1((Bit32u)data); + // alignment.... + if (dword) { + if ((Bit32u)data & 3) { + cache_addw(lohalf+3); // lwl dest_reg, 3(temp1) + cache_addw(0x8800+(temp1<<5)+dest_reg); + cache_addw(lohalf); // lwr dest_reg, 0(temp1) + cache_addw(0x9800+(temp1<<5)+dest_reg); + } else { + cache_addw(lohalf); // lw dest_reg, 0(temp1) + cache_addw(0x8C00+(temp1<<5)+dest_reg); + } + } else { + if ((Bit32u)data & 1) { + cache_addw(lohalf); // lbu dest_reg, 0(temp1) + cache_addw(0x9000+(temp1<<5)+dest_reg); + cache_addw(lohalf+1); // lbu temp2, 1(temp1) + cache_addw(0x9000+(temp1<<5)+temp2); +#if (_MIPS_ISA==MIPS32R2) || defined(PSP) + cache_addw(0x7a04); // ins dest_reg, temp2, 8, 8 + cache_addw(0x7c00+(temp2<<5)+dest_reg); +#else + cache_addw((temp2<<11)+0x200); // sll temp2, temp2, 8 + cache_addw(temp2); + cache_addw((dest_reg<<11)+0x25); // or dest_reg, temp2, dest_reg + cache_addw((temp2<<5)+dest_reg); +#endif + } else { + cache_addw(lohalf); // lhu dest_reg, 0(temp1); + cache_addw(0x9400+(temp1<<5)+dest_reg); + } + } +} + +// move a 16bit constant value into dest_reg +// the upper 16bit of the destination register may be destroyed +static void gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { + cache_addw(imm); // ori dest_reg, $0, imm + cache_addw(0x3400+dest_reg); +} + +// move 32bit (dword==true) or 16bit (dword==false) of a register into memory +static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { + Bit16s lohalf = gen_addr_temp1((Bit32u)dest); + // alignment.... + if (dword) { + if ((Bit32u)dest & 3) { + cache_addw(lohalf+3); // swl src_reg, 3(temp1) + cache_addw(0xA800+(temp1<<5)+src_reg); + cache_addw(lohalf); // swr src_reg, 0(temp1) + cache_addw(0xB800+(temp1<<5)+src_reg); + } else { + cache_addw(lohalf); // sw src_reg, 0(temp1) + cache_addw(0xAC00+(temp1<<5)+src_reg); + } + } else { + if((Bit32u)dest & 1) { + cache_addw(lohalf); // sb src_reg, 0(temp1) + cache_addw(0xA000+(temp1<<5)+src_reg); + cache_addw((temp2<<11)+0x202); // srl temp2, src_reg, 8 + cache_addw(src_reg); + cache_addw(lohalf+1); // sb temp2, 1(temp1) + cache_addw(0xA000+(temp1<<5)+temp2); + } else { + cache_addw(lohalf); // sh src_reg, 0(temp1); + cache_addw(0xA400+(temp1<<5)+src_reg); + } + } +} + +// move an 8bit value from memory into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { + Bit16s lohalf = gen_addr_temp1((Bit32u)data); + cache_addw(lohalf); // lbu dest_reg, 0(temp1) + cache_addw(0x9000+(temp1<<5)+dest_reg); +} + +// move an 8bit value from memory into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { + gen_mov_byte_to_reg_low(dest_reg, data); +} + +// move an 8bit constant value into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void INLINE gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { + gen_mov_word_to_reg_imm(dest_reg, imm); +} + +// move an 8bit constant value into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { + gen_mov_byte_to_reg_low_imm(dest_reg, imm); +} + +// move the lowest 8bit of a register into memory +static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { + Bit16s lohalf = gen_addr_temp1((Bit32u)dest); + cache_addw(lohalf); // sb src_reg, 0(temp1) + cache_addw(0xA000+(temp1<<5)+src_reg); +} + + + +// convert an 8bit word to a 32bit dword +// the register is zero-extended (sign==false) or sign-extended (sign==true) +static void gen_extend_byte(bool sign,HostReg reg) { + if (sign) { +#if (_MIPS_ISA==MIPS32R2) || defined(PSP) + cache_addw((reg<<11)+0x420); // seb reg, reg + cache_addw(0x7c00+reg); +#else + arch that lacks seb +#endif + } else { + cache_addw(0xff); // andi reg, reg, 0xff + cache_addw(0x3000+(reg<<5)+reg); + } +} + +// convert a 16bit word to a 32bit dword +// the register is zero-extended (sign==false) or sign-extended (sign==true) +static void gen_extend_word(bool sign,HostReg reg) { + if (sign) { +#if (_MIPS_ISA==MIPS32R2) || defined(PSP) + cache_addw((reg<<11)+0x620); // seh reg, reg + cache_addw(0x7c00+reg); +#else + arch that lacks seh +#endif + } else { + cache_addw(0xffff); // andi reg, reg, 0xffff + cache_addw(0x3000+(reg<<5)+reg); + } +} + +// add a 32bit value from memory to a full register +static void gen_add(HostReg reg,void* op) { + gen_mov_word_to_reg(temp2, op, 1); + cache_addw((reg<<11)+0x21); // addu reg, reg, temp2 + cache_addw((reg<<5)+temp2); +} + +// add a 32bit constant value to a full register +static void gen_add_imm(HostReg reg,Bit32u imm) { + if(!imm) return; + if(((Bit32s)imm >= -32768) && ((Bit32s)imm < 32768)) { + cache_addw((Bit16u)imm); // addiu reg, reg, imm + cache_addw(0x2400+(reg<<5)+reg); + } else { + mov_imm_to_temp1(imm); + cache_addw((reg<<11)+0x21); // addu reg, reg, temp1 + cache_addw((reg<<5)+temp1); + } +} + +// and a 32bit constant value with a full register +static void gen_and_imm(HostReg reg,Bit32u imm) { + if(imm < 65536) { + cache_addw((Bit16u)imm); // andi reg, reg, imm + cache_addw(0x3000+(reg<<5)+reg); + } else { + mov_imm_to_temp1((Bit32u)imm); + cache_addw((reg<<11)+0x24); // and reg, temp1, reg + cache_addw((temp1<<5)+reg); + } +} + + +// move a 32bit constant value into memory +static void INLINE gen_mov_direct_dword(void* dest,Bit32u imm) { + gen_mov_dword_to_reg_imm(temp2, imm); + gen_mov_word_from_reg(temp2, dest, 1); +} + +// move an address into memory +static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { + gen_mov_direct_dword(dest,(Bit32u)imm); +} + +// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value +static void INLINE gen_add_direct_word(void* dest,Bit32u imm,bool dword) { + if(!imm) return; + gen_mov_word_to_reg(temp2, dest, dword); + gen_add_imm(temp2, imm); + gen_mov_word_from_reg(temp2, dest, dword); +} + +// add an 8bit constant value to a dword memory value +static void INLINE gen_add_direct_byte(void* dest,Bit8s imm) { + gen_add_direct_word(dest, (Bit32s)imm, 1); +} + +// subtract an 8bit constant value from a dword memory value +static void INLINE gen_sub_direct_byte(void* dest,Bit8s imm) { + gen_add_direct_word(dest, -((Bit32s)imm), 1); +} + +// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value +static void INLINE gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { + gen_add_direct_word(dest, -(Bit32s)imm, dword); +} + +// effective address calculation, destination is dest_reg +// scale_reg is scaled by scale (scale_reg*(2^scale)) and +// added to dest_reg, then the immediate value is added +static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { + if (scale) { + cache_addw((scale_reg<<11)+(scale<<6)); // sll scale_reg, scale_reg, scale + cache_addw(scale_reg); + } + cache_addw((dest_reg<<11)+0x21); // addu dest_reg, dest_reg, scale_reg + cache_addw((dest_reg<<5)+scale_reg); + gen_add_imm(dest_reg, imm); +} + +// effective address calculation, destination is dest_reg +// dest_reg is scaled by scale (dest_reg*(2^scale)), +// then the immediate value is added +static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { + if (scale) { + cache_addw((dest_reg<<11)+(scale<<6)); // sll dest_reg, dest_reg, scale + cache_addw(dest_reg); + } + gen_add_imm(dest_reg, imm); +} + +#define DELAY cache_addd(0) // nop + +// generate a call to a parameterless function +static void INLINE gen_call_function_raw(void * func) { +#if C_DEBUG + if ((cache.pos ^ func) & 0xf0000000) LOG_MSG("jump overflow\n"); +#endif + temp1_valid = false; + cache_addd(0x0c000000+(((Bit32u)func>>2)&0x3ffffff)); // jal func + DELAY; +} + +// generate a call to a function with paramcount parameters +// note: the parameters are loaded in the architecture specific way +// using the gen_load_param_ functions below +static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { + Bit32u proc_addr = (Bit32u)cache.pos; + gen_call_function_raw(func); + return proc_addr; +} + +#ifdef __mips_eabi +// max of 8 parameters in $a0-$a3 and $t0-$t3 + +// load an immediate value as param'th function parameter +static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { + gen_mov_dword_to_reg_imm(param+4, imm); +} + +// load an address as param'th function parameter +static void INLINE gen_load_param_addr(Bitu addr,Bitu param) { + gen_mov_dword_to_reg_imm(param+4, addr); +} + +// load a host-register as param'th function parameter +static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { + gen_mov_regs(param+4, reg); +} + +// load a value from memory as param'th function parameter +static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { + gen_mov_word_to_reg(param+4, (void *)mem, 1); +} +#else + other mips abis +#endif + +// jump to an address pointed at by ptr, offset is in imm +static void INLINE gen_jmp_ptr(void * ptr,Bits imm=0) { + gen_mov_word_to_reg(temp2, ptr, 1); + if((imm < -32768) || (imm >= 32768)) { + gen_add_imm(temp2, imm); + imm = 0; + } + temp1_valid = false; + cache_addw((Bit16u)imm); // lw temp2, imm(temp2) + cache_addw(0x8C00+(temp2<<5)+temp2); + cache_addd((temp2<<21)+8); // jr temp2 + DELAY; +} + +// short conditional jump (+-127 bytes) if register is zero +// the destination is set by gen_fill_branch() later +static Bit32u INLINE gen_create_branch_on_zero(HostReg reg,bool dword) { + temp1_valid = false; + if(!dword) { + cache_addw(0xffff); // andi temp1, reg, 0xffff + cache_addw(0x3000+(reg<<5)+temp1); + } + cache_addw(0); // beq $0, reg, 0 + cache_addw(0x1000+(dword?reg:temp1)); + DELAY; + return ((Bit32u)cache.pos-8); +} + +// short conditional jump (+-127 bytes) if register is nonzero +// the destination is set by gen_fill_branch() later +static Bit32u INLINE gen_create_branch_on_nonzero(HostReg reg,bool dword) { + temp1_valid = false; + if(!dword) { + cache_addw(0xffff); // andi temp1, reg, 0xffff + cache_addw(0x3000+(reg<<5)+temp1); + } + cache_addw(0); // bne $0, reg, 0 + cache_addw(0x1400+(dword?reg:temp1)); + DELAY; + return ((Bit32u)cache.pos-8); +} + +// calculate relative offset and fill it into the location pointed to by data +static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) { +#if C_DEBUG + Bits len=(Bit32u)cache.pos-data; + if (len<0) len=-len; + if (len>126) LOG_MSG("Big jump %d",len); +#endif + temp1_valid = false; // this is a branch target + *(Bit16u*)data=((Bit16u)((Bit32u)cache.pos-data-4)>>2); +} + +#if 0 // assume for the moment no branch will go farther then +/- 128KB + +// conditional jump if register is nonzero +// for isdword==true the 32bit of the register are tested +// for isdword==false the lowest 8bit of the register are tested +static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { + temp1_valid = false; + if (!isdword) { + cache_addw(0xff); // andi temp1, reg, 0xff + cache_addw(0x3000+(reg<<5)+temp1); + } + cache_addw(3); // beq $0, reg, +12 + cache_addw(0x1000+(isdword?reg:temp1)); + DELAY; + cache_addd(0x00000000); // fill j + DELAY; + return ((Bit32u)cache.pos-8); +} + +// compare 32bit-register against zero and jump if value less/equal than zero +static Bit32u INLINE gen_create_branch_long_leqzero(HostReg reg) { + temp1_valid = false; + cache_addw(3); // bgtz reg, +12 + cache_addw(0x1c00+(reg<<5)); + DELAY; + cache_addd(0x00000000); // fill j + DELAY; + return ((Bit32u)cache.pos-8); +} + +// calculate long relative offset and fill it into the location pointed to by data +static void INLINE gen_fill_branch_long(Bit32u data) { + temp1_valid = false; + // this is an absolute branch + *(Bit32u*)data=0x08000000+(((Bit32u)cache.pos>>2)&0x3ffffff); +} +#else +// conditional jump if register is nonzero +// for isdword==true the 32bit of the register are tested +// for isdword==false the lowest 8bit of the register are tested +static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { + temp1_valid = false; + if (!isdword) { + cache_addw(0xff); // andi temp1, reg, 0xff + cache_addw(0x3000+(reg<<5)+temp1); + } + cache_addw(0); // bne $0, reg, 0 + cache_addw(0x1400+(isdword?reg:temp1)); + DELAY; + return ((Bit32u)cache.pos-8); +} + +// compare 32bit-register against zero and jump if value less/equal than zero +static Bit32u INLINE gen_create_branch_long_leqzero(HostReg reg) { + temp1_valid = false; + cache_addw(0); // blez reg, 0 + cache_addw(0x1800+(reg<<5)); + DELAY; + return ((Bit32u)cache.pos-8); +} + +// calculate long relative offset and fill it into the location pointed to by data +static void INLINE gen_fill_branch_long(Bit32u data) { + gen_fill_branch(data); +} +#endif + +static void gen_run_code(void) { + temp1_valid = false; + cache_addd(0x27bdfff0); // addiu $sp, $sp, -16 + cache_addd(0xafb00004); // sw $s0, 4($sp) + cache_addd(0x00800008); // jr $a0 + cache_addd(0xafbf0000); // sw $ra, 0($sp) +} + +// return from a function +static void gen_return_function(void) { + temp1_valid = false; + cache_addd(0x8fbf0000); // lw $ra, 0($sp) + cache_addd(0x8fb00004); // lw $s0, 4($sp) + cache_addd(0x03e00008); // jr $ra + cache_addd(0x27bd0010); // addiu $sp, $sp, 16 +} + +#ifdef DRC_FLAGS_INVALIDATION +// called when a call to a function can be replaced by a +// call to a simpler function +static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { +#ifdef DRC_FLAGS_INVALIDATION_DCODE + // try to avoid function calls but rather directly fill in code + switch (flags_type) { + case t_ADDb: + case t_ADDw: + case t_ADDd: + *(Bit32u*)pos=0x00851021; // addu $v0, $a0, $a1 + break; + case t_ORb: + case t_ORw: + case t_ORd: + *(Bit32u*)pos=0x00851025; // or $v0, $a0, $a1 + break; + case t_ANDb: + case t_ANDw: + case t_ANDd: + *(Bit32u*)pos=0x00851024; // and $v0, $a0, $a1 + break; + case t_SUBb: + case t_SUBw: + case t_SUBd: + *(Bit32u*)pos=0x00851023; // subu $v0, $a0, $a1 + break; + case t_XORb: + case t_XORw: + case t_XORd: + *(Bit32u*)pos=0x00851026; // xor $v0, $a0, $a1 + break; + case t_CMPb: + case t_CMPw: + case t_CMPd: + case t_TESTb: + case t_TESTw: + case t_TESTd: + *(Bit32u*)pos=0; // nop + break; + case t_INCb: + case t_INCw: + case t_INCd: + *(Bit32u*)pos=0x24820001; // addiu $v0, $a0, 1 + break; + case t_DECb: + case t_DECw: + case t_DECd: + *(Bit32u*)pos=0x2482ffff; // addiu $v0, $a0, -1 + break; + case t_SHLb: + case t_SHLw: + case t_SHLd: + *(Bit32u*)pos=0x00a41004; // sllv $v0, $a0, $a1 + break; + case t_SHRb: + case t_SHRw: + case t_SHRd: + *(Bit32u*)pos=0x00a41006; // srlv $v0, $a0, $a1 + break; + case t_SARd: + *(Bit32u*)pos=0x00a41007; // srav $v0, $a0, $a1 + break; +#if (_MIPS_ISA==MIPS32R2) || defined(PSP) + case t_RORd: + *(Bit32u*)pos=0x00a41046; // rotr $v0, $a0, $a1 + break; +#endif + case t_NEGb: + case t_NEGw: + case t_NEGd: + *(Bit32u*)pos=0x00041023; // subu $v0, $0, $a0 + break; + default: + *(Bit32u*)pos=0x0c000000+((((Bit32u)fct_ptr)>>2)&0x3ffffff); // jal simple_func + break; + } +#else + *(Bit32u*)pos=0x0c000000+(((Bit32u)fct_ptr)>>2)&0x3ffffff); // jal simple_func +#endif +} +#endif From 7c7e3c510c7864ad2a8a626bd9f5792efd0aab36 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 27 Jul 2007 19:17:23 +0000 Subject: [PATCH 2848/4131] Add input checking to call 0x2D Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2934 --- src/dos/dos.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index db1a1731..d81a38c9 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.103 2007-07-20 18:53:52 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.104 2007-07-27 19:17:23 qbix79 Exp $ */ #include #include @@ -359,7 +359,10 @@ static Bitu DOS_21Handler(void) { break; case 0x2d: /* Set System Time */ LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Set System Time not supported"); - reg_al=0; /* Noone is changing system time */ + //Check input parameters nonetheless + if( reg_ch > 23 || reg_cl > 59 || reg_dh > 59 || reg_dl > 99 ) + reg_al = 0xff; + else reg_al = 0; break; case 0x2e: /* Set Verify flag */ dos.verify=(reg_al==1); From 31dfc5a64405e93cf6566174fdf5a1a0f687a74d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 27 Jul 2007 19:30:36 +0000 Subject: [PATCH 2849/4131] Add mipsel32 to make dist Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2935 --- src/cpu/core_dynrec/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_dynrec/Makefile.am b/src/cpu/core_dynrec/Makefile.am index ad75110f..50c57a7a 100644 --- a/src/cpu/core_dynrec/Makefile.am +++ b/src/cpu/core_dynrec/Makefile.am @@ -1,2 +1,2 @@ noinst_HEADERS = cache.h decoder.h decoder_basic.h decoder_opcodes.h \ - dyn_fpu.h operators.h risc_x64.h risc_x86.h \ No newline at end of file + dyn_fpu.h operators.h risc_x64.h risc_x86.h risc_mipsel32.h \ No newline at end of file From a6a69be5e03e48a2af879c1ae7c1392f3c9ab9e9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 27 Jul 2007 19:45:54 +0000 Subject: [PATCH 2850/4131] Updates Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2936 --- ChangeLog | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index b1497906..bc6cfe3d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 0.71 - Add a new recompiling cpu core, which should be easier to port. - - Add 64 bit version of the recompiling core + - 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) @@ -8,21 +9,25 @@ 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 and others) - - Fix digital joystick centering problem + - 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) + - 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 From 9056649fc9f64ad7595502c6d48d2732a30cd142 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 27 Jul 2007 19:52:00 +0000 Subject: [PATCH 2851/4131] updates Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2937 --- THANKS | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/THANKS b/THANKS index d48a61da..7698f021 100644 --- a/THANKS +++ b/THANKS @@ -12,11 +12,14 @@ Pierre-Yves G Colin Snover for hosting our forum. Sourceforge for hosting our homepage and other development tools. -Mirek Luza for his moderation of the forums. -c2woody for his debug work. +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 and Johannes for creating the MAC OS X PPC version. +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. The Beta Testers. From a90f2e6e87e4a8a2ee0dc37b0d4c205cd25ecb97 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 27 Jul 2007 20:14:06 +0000 Subject: [PATCH 2852/4131] Some changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2938 --- NEWS | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ README | 14 ++------------ 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/NEWS b/NEWS index 8aafd742..08a91cde 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,54 @@ +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. + - General code cleanup. + 0.70 - Improve register handling and support with XMS. - Fix some issues with deleting open files.(windows only issue) diff --git a/README b/README index 019050d8..bc73d559 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -DOSBox v0.70 +DOSBox v0.71 ===== @@ -1142,17 +1142,7 @@ Check the INSTALL in the source distribution. 14. Special thanks: =================== -Vlad R. of the VDMSound project for excellent SoundBlaster info. -Tatsuyuki Satoh of the Mame Team for making an excellent FM emulator. -The Bochs and DOSemu projects, which I used for information. -Freedos for ideas in making my shell. -Pierre-Yves Gérardy for hosting the old Beta Board. -Colin Snover for hosting our forum. -Jantien for the version management. -Shawn and Johannes for creating the MAC OS X PPC version. -Ido Beeri for the icon. -The Beta Testers. - +See the THANKS file. ============ From fa257573f329d3837f356cea198b52b09b83b763 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 30 Jul 2007 06:39:24 +0000 Subject: [PATCH 2853/4131] Update and despam Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2939 --- AUTHORS | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/AUTHORS b/AUTHORS index 23121d5d..c7f46225 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,8 +1,11 @@ The DOSBox Team --------------- -Sjoerd v.d. Berg -Peter Veenstra -Ulf Wohlers -Tommy Frössman -Dean Beeler +Sjoerd v.d. Berg +Peter Veenstra +Ulf Wohlers +Tommy Frössman +Dean Beeler +Sebastian Strohhäcker + +nick_without_<> @ users.sourceforge.net From c3d2ddebd50ecaa1fba30650f6e648f13eaaecff Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 30 Jul 2007 07:15:26 +0000 Subject: [PATCH 2854/4131] Important update! ;) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2940 --- ChangeLog | 1 + NEWS | 1 + 2 files changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index bc6cfe3d..71da89c8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -47,6 +47,7 @@ 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 diff --git a/NEWS b/NEWS index 08a91cde..2291df19 100644 --- a/NEWS +++ b/NEWS @@ -47,6 +47,7 @@ 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 From ee260ffd5c40f81fab28d3b51472aeb86f373b24 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 30 Jul 2007 07:42:16 +0000 Subject: [PATCH 2855/4131] Administrative changes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2941 --- VERSION | 2 +- configure.in | 2 +- src/platform/visualc/config.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index ac37bbea..a55c553f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.70 +0.71 diff --git a/configure.in b/configure.in index d81baae0..c77bb4b2 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Init. -AC_INIT(dosbox,0.70) +AC_INIT(dosbox,0.71) AC_PREREQ(2.50) AC_CONFIG_SRCDIR(README) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 088d23a1..9694796d 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -1,6 +1,6 @@ #define INLINE __forceinline -#define VERSION "0.70" +#define VERSION "0.71" /* Define to 1 to enable internal debugger, requires libcurses */ From fdbb2028302e6efaa8c8ba0bca7cee8f3a6331b1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 30 Jul 2007 07:59:29 +0000 Subject: [PATCH 2856/4131] 0.71 style installer. Somewhat vista compabitible and having a desktop shortcut. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2942 --- scripts/dosbox-installer.nsi | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index e7f028e7..950ee3af 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -1,5 +1,5 @@ !define VER_MAYOR 0 -!define VER_MINOR 70 +!define VER_MINOR 71 ; The name of the installer Name "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer" @@ -12,15 +12,21 @@ 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 bzip2 +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 "ThisNameIsIgnoredSoWhyBother?" +Section "!Core files" Core ; Set output path to the installation directory. SetOutPath $INSTDIR + SectionIn RO ; Put file there CreateDirectory "$INSTDIR\capture" @@ -43,6 +49,7 @@ Section "ThisNameIsIgnoredSoWhyBother?" 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" @@ -66,9 +73,17 @@ WriteUninstaller "uninstall.exe" 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 @@ -95,6 +110,7 @@ Section "Uninstall" 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" From 8224477b9a0d9de361b6eb8cf09af1811c476cdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 3 Aug 2007 15:18:05 +0000 Subject: [PATCH 2857/4131] add flags invalidation by code generation for x86_64 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2944 --- src/cpu/core_dynrec/risc_x64.h | 75 ++++++++++++++++++++++++++++++++++ src/cpu/core_dynrec/risc_x86.h | 22 +++++----- 2 files changed, 86 insertions(+), 11 deletions(-) diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index 8c71f534..fb4f0e30 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -593,6 +593,81 @@ static void gen_return_function(void) { // called when a call to a function can be replaced by a // call to a simpler function static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { +#ifdef DRC_FLAGS_INVALIDATION_DCODE + // try to avoid function calls but rather directly fill in code + switch (flags_type) { + case t_ADDb: + case t_ADDw: + case t_ADDd: + *(Bit32u*)(pos+0)=0xd001c889; // mov eax,ecx; add eax,edx + *(Bit32u*)(pos+4)=0x909006eb; // skip + *(Bit32u*)(pos+8)=0x90909090; + break; + case t_ORb: + case t_ORw: + case t_ORd: + *(Bit32u*)(pos+0)=0xd009c889; // mov eax,ecx; or eax,edx + *(Bit32u*)(pos+4)=0x909006eb; // skip + *(Bit32u*)(pos+8)=0x90909090; + break; + case t_ANDb: + case t_ANDw: + case t_ANDd: + *(Bit32u*)(pos+0)=0xd021c889; // mov eax,ecx; and eax,edx + *(Bit32u*)(pos+4)=0x909006eb; // skip + *(Bit32u*)(pos+8)=0x90909090; + break; + case t_SUBb: + case t_SUBw: + case t_SUBd: + *(Bit32u*)(pos+0)=0xd029c889; // mov eax,ecx; sub eax,edx + *(Bit32u*)(pos+4)=0x909006eb; // skip + *(Bit32u*)(pos+8)=0x90909090; + break; + case t_XORb: + case t_XORw: + case t_XORd: + *(Bit32u*)(pos+0)=0xd031c889; // mov eax,ecx; xor eax,edx + *(Bit32u*)(pos+4)=0x909006eb; // skip + *(Bit32u*)(pos+8)=0x90909090; + break; + case t_CMPb: + case t_CMPw: + case t_CMPd: + case t_TESTb: + case t_TESTw: + case t_TESTd: + *(Bit32u*)(pos+0)=0x90900aeb; // skip + *(Bit32u*)(pos+4)=0x90909090; + *(Bit32u*)(pos+8)=0x90909090; + break; + case t_INCb: + case t_INCw: + case t_INCd: + *(Bit32u*)(pos+0)=0xffc0c889; // mov eax,ecx; inc eax + *(Bit32u*)(pos+4)=0x909006eb; // skip + *(Bit32u*)(pos+8)=0x90909090; + break; + case t_DECb: + case t_DECw: + case t_DECd: + *(Bit32u*)(pos+0)=0xffc8c889; // mov eax,ecx; dec eax + *(Bit32u*)(pos+4)=0x909006eb; // skip + *(Bit32u*)(pos+8)=0x90909090; + break; + case t_NEGb: + case t_NEGw: + case t_NEGd: + *(Bit32u*)(pos+0)=0xd8f7c889; // mov eax,ecx; neg eax + *(Bit32u*)(pos+4)=0x909006eb; // skip + *(Bit32u*)(pos+8)=0x90909090; + break; + default: + *(Bit64u*)(pos+2)=(Bit64u)fct_ptr; // fill function pointer + break; + } +#else *(Bit64u*)(pos+2)=(Bit64u)fct_ptr; +#endif } #endif diff --git a/src/cpu/core_dynrec/risc_x86.h b/src/cpu/core_dynrec/risc_x86.h index 5fe1dfd0..88fe4361 100644 --- a/src/cpu/core_dynrec/risc_x86.h +++ b/src/cpu/core_dynrec/risc_x86.h @@ -442,31 +442,31 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: - *(Bit32u*)pos=0xc203c18b; + *(Bit32u*)pos=0xc203c18b; // mov eax,ecx; add eax,edx *(pos+4)=0x90; break; case t_ORb: case t_ORw: case t_ORd: - *(Bit32u*)pos=0xc20bc18b; + *(Bit32u*)pos=0xc20bc18b; // mov eax,ecx; or eax,edx *(pos+4)=0x90; break; case t_ANDb: case t_ANDw: case t_ANDd: - *(Bit32u*)pos=0xc223c18b; + *(Bit32u*)pos=0xc223c18b; // mov eax,ecx; and eax,edx *(pos+4)=0x90; break; case t_SUBb: case t_SUBw: case t_SUBd: - *(Bit32u*)pos=0xc22bc18b; + *(Bit32u*)pos=0xc22bc18b; // mov eax,ecx; sub eax,edx *(pos+4)=0x90; break; case t_XORb: case t_XORw: case t_XORd: - *(Bit32u*)pos=0xc233c18b; + *(Bit32u*)pos=0xc233c18b; // mov eax,ecx; xor eax,edx *(pos+4)=0x90; break; case t_CMPb: @@ -475,33 +475,33 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit32u*)pos=0x909003eb; + *(Bit32u*)pos=0x909003eb; // skip *(pos+4)=0x90; break; case t_INCb: case t_INCw: case t_INCd: - *(Bit32u*)pos=0x9040c18b; + *(Bit32u*)pos=0x9040c18b; // mov eax,ecx; inc eax *(pos+4)=0x90; break; case t_DECb: case t_DECw: case t_DECd: - *(Bit32u*)pos=0x9048c18b; + *(Bit32u*)pos=0x9048c18b; // mov eax,ecx; dec eax *(pos+4)=0x90; break; case t_NEGb: case t_NEGw: case t_NEGd: - *(Bit32u*)pos=0xd8f7c18b; + *(Bit32u*)pos=0xd8f7c18b; // mov eax,ecx; neg eax *(pos+4)=0x90; break; default: - *(Bit32u*)(pos+1)=(Bit32u)((Bit8u*)fct_ptr - (pos+1+4)); + *(Bit32u*)(pos+1)=(Bit32u)((Bit8u*)fct_ptr - (pos+1+4)); // fill function pointer break; } #else - *(Bit32u*)(pos+1)=(Bit32u)((Bit8u*)fct_ptr - (pos+1+4)); + *(Bit32u*)(pos+1)=(Bit32u)((Bit8u*)fct_ptr - (pos+1+4)); // fill function pointer #endif } #endif From d42eb113edcf9800a6c916f11dab3abf51dbc3fa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 3 Aug 2007 18:22:45 +0000 Subject: [PATCH 2858/4131] Fix bug 1766436 tab key crashes dosbox. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2945 --- src/shell/shell_misc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index cb2c7fb3..e0c371eb 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.49 2007-02-03 14:04:23 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.50 2007-08-03 18:22:45 qbix79 Exp $ */ #include #include @@ -223,7 +223,7 @@ void DOS_Shell::InputCommand(char * line) { if (p_completion_start) { p_completion_start ++; - completion_index = str_index - strlen(p_completion_start); + completion_index = str_len - strlen(p_completion_start); } else { p_completion_start = line; completion_index = 0; From 0cf80b61fa99d0da0e64d289476f4471a63d5064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 4 Aug 2007 09:43:13 +0000 Subject: [PATCH 2859/4131] initialize variables, should fix some crashes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2946 --- src/gui/sdl_mapper.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 95773c64..d937f7f3 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.39 2007-07-17 13:50:27 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.40 2007-08-04 09:43:13 c2woody Exp $ */ #include #include @@ -606,6 +606,7 @@ public: axes=0; buttons=0; hats=0; button_wrap=0; button_cap=0; axes_cap=0; hats_cap=0; + emulated_buttons=0; emulated_axes=0; emulated_hats=0; return; } From 80118991542afc023182881611700d49cbe48f64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 4 Aug 2007 18:52:44 +0000 Subject: [PATCH 2860/4131] fix layout file processing (thanks to etillite, see sf bug #1760297) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2947 --- src/dos/dos_keyboard_layout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index f19b49dc..4a26b027 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -386,9 +386,9 @@ Bitu keyboard_layout::read_keyboard_file(const char* keyboard_file_name, Bit32s if (addmap>additional_planes+2) break; Bitu charptr=read_buf_pos+addmap*((read_buf[read_buf_pos-2]&0x80)?2:1); Bit16u kchar=read_buf[charptr]; - if (read_buf[read_buf_pos-2]&0x80) kchar|=read_buf[charptr+1]<<8; // scancode/char pair if (kchar!=0) { // key remapped + if (read_buf[read_buf_pos-2]&0x80) kchar|=read_buf[charptr+1]<<8; // scancode/char pair // overwrite mapping current_layout[scan*layout_pages+addmap]=kchar; // clear command bit From e60fb98981f0b309dd05919504b4c462cdb0238d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 5 Aug 2007 15:33:02 +0000 Subject: [PATCH 2861/4131] allow non-palette vga attr registers to always be modified during modeswitch (fixes Dreamweb) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2948 --- src/ints/int10_modes.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 8870f3a6..c58e0697 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -936,6 +936,11 @@ dac_text16: } } } else { + for (i=0x10;i Date: Mon, 6 Aug 2007 20:01:45 +0000 Subject: [PATCH 2862/4131] (trying to) fix parameter encoding (x86-64 drc only) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2949 --- src/cpu/core_dynrec/risc_x64.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index fb4f0e30..dbeab485 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -599,35 +599,35 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: - *(Bit32u*)(pos+0)=0xd001c889; // mov eax,ecx; add eax,edx + *(Bit32u*)(pos+0)=0xf001f889; // mov eax,edi; add eax,esi *(Bit32u*)(pos+4)=0x909006eb; // skip *(Bit32u*)(pos+8)=0x90909090; break; case t_ORb: case t_ORw: case t_ORd: - *(Bit32u*)(pos+0)=0xd009c889; // mov eax,ecx; or eax,edx + *(Bit32u*)(pos+0)=0xf009f889; // mov eax,edi; or eax,esi *(Bit32u*)(pos+4)=0x909006eb; // skip *(Bit32u*)(pos+8)=0x90909090; break; case t_ANDb: case t_ANDw: case t_ANDd: - *(Bit32u*)(pos+0)=0xd021c889; // mov eax,ecx; and eax,edx + *(Bit32u*)(pos+0)=0xf021f889; // mov eax,edi; and eax,esi *(Bit32u*)(pos+4)=0x909006eb; // skip *(Bit32u*)(pos+8)=0x90909090; break; case t_SUBb: case t_SUBw: case t_SUBd: - *(Bit32u*)(pos+0)=0xd029c889; // mov eax,ecx; sub eax,edx + *(Bit32u*)(pos+0)=0xf029f889; // mov eax,edi; sub eax,esi *(Bit32u*)(pos+4)=0x909006eb; // skip *(Bit32u*)(pos+8)=0x90909090; break; case t_XORb: case t_XORw: case t_XORd: - *(Bit32u*)(pos+0)=0xd031c889; // mov eax,ecx; xor eax,edx + *(Bit32u*)(pos+0)=0xf031f889; // mov eax,edi; xor eax,esi *(Bit32u*)(pos+4)=0x909006eb; // skip *(Bit32u*)(pos+8)=0x90909090; break; @@ -644,21 +644,21 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_INCb: case t_INCw: case t_INCd: - *(Bit32u*)(pos+0)=0xffc0c889; // mov eax,ecx; inc eax + *(Bit32u*)(pos+0)=0xc0ffc889; // mov eax,edi; inc eax *(Bit32u*)(pos+4)=0x909006eb; // skip *(Bit32u*)(pos+8)=0x90909090; break; case t_DECb: case t_DECw: case t_DECd: - *(Bit32u*)(pos+0)=0xffc8c889; // mov eax,ecx; dec eax + *(Bit32u*)(pos+0)=0xc8fff889; // mov eax,edi; dec eax *(Bit32u*)(pos+4)=0x909006eb; // skip *(Bit32u*)(pos+8)=0x90909090; break; case t_NEGb: case t_NEGw: case t_NEGd: - *(Bit32u*)(pos+0)=0xd8f7c889; // mov eax,ecx; neg eax + *(Bit32u*)(pos+0)=0xd8f7f889; // mov eax,edi; neg eax *(Bit32u*)(pos+4)=0x909006eb; // skip *(Bit32u*)(pos+8)=0x90909090; break; From 5b1d1c360c841f36836df471dc0f154194a2439d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 7 Aug 2007 19:03:43 +0000 Subject: [PATCH 2863/4131] enable dcode for x86-64 (after gulikoza (thanks!) fixed the remaining bugs) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2950 --- src/cpu/core_dynrec/risc_x64.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index dbeab485..1464ed61 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -26,7 +26,7 @@ // try to use non-flags generating functions if possible #define DRC_FLAGS_INVALIDATION // try to replace _simple functions by code -// #define DRC_FLAGS_INVALIDATION_DCODE +#define DRC_FLAGS_INVALIDATION_DCODE // type with the same size as a pointer #define DRC_PTR_SIZE_IM Bit64u @@ -644,7 +644,7 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_INCb: case t_INCw: case t_INCd: - *(Bit32u*)(pos+0)=0xc0ffc889; // mov eax,edi; inc eax + *(Bit32u*)(pos+0)=0xc0fff889; // mov eax,edi; inc eax *(Bit32u*)(pos+4)=0x909006eb; // skip *(Bit32u*)(pos+8)=0x90909090; break; From 16b9c8db8a182c66c1fdcfb351d601f7f70604dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 7 Aug 2007 21:01:08 +0000 Subject: [PATCH 2864/4131] tweak speed-unlocking a bit for cycles=max (ykhwong, see sf patch #1745756) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2951 --- src/dosbox.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 9ecfb523..b90f32cb 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.118 2007-07-02 20:06:59 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.119 2007-08-07 21:01:08 c2woody Exp $ */ #include #include @@ -221,10 +221,22 @@ void DOSBOX_RunMachine(void){ } static void DOSBOX_UnlockSpeed( bool pressed ) { - if (pressed) + static bool autoadjust = false; + if (pressed) { ticksLocked = true; - else + if (CPU_CycleAutoAdjust) { + autoadjust = true; + CPU_CycleAutoAdjust = false; + CPU_CycleMax /= 3; + if (CPU_CycleMax<1000) CPU_CycleMax=1000; + } + } else { ticksLocked = false; + if (autoadjust) { + autoadjust = false; + CPU_CycleAutoAdjust = true; + } + } } static void DOSBOX_RealInit(Section * sec) { From 5b8517762e68d4a31ab528e472ca14db2868a525 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 8 Aug 2007 08:03:48 +0000 Subject: [PATCH 2865/4131] Fix Space Quest 6 sound. (switching to old style dma transfers resets the sign of the dma transfer) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2952 --- src/hardware/sblaster.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index f90a6598..cfeeba7c 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.65 2007-06-14 18:06:59 qbix79 Exp $ */ +/* $Id: sblaster.cpp,v 1.66 2007-08-08 08:03:48 qbix79 Exp $ */ #include #include @@ -590,8 +590,9 @@ static void DSP_DoDMATransfer(DMA_MODES mode,Bitu freq,bool stereo) { #endif } -static void DSP_PrepareDMA_Old(DMA_MODES mode,bool autoinit) { +static void DSP_PrepareDMA_Old(DMA_MODES mode,bool autoinit,bool sign) { sb.dma.autoinit=autoinit; + sb.dma.sign=sign; if (!autoinit) sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); sb.dma.chan=GetDMAChannel(sb.hw.dma8); DSP_DoDMATransfer(mode,sb.freq / (sb.mixer.stereo ? 2 : 1),sb.mixer.stereo); @@ -716,18 +717,19 @@ static void DSP_DoCommand(void) { break; case 0x24: /* Singe Cycle 8-Bit DMA ADC */ sb.dma.left=sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); + sb.dma.sign=false; LOG(LOG_SB,LOG_ERROR)("DSP:Faked ADC for %d bytes",sb.dma.total); GetDMAChannel(sb.hw.dma8)->Register_Callback(DSP_ADC_CallBack); break; case 0x14: /* Singe Cycle 8-Bit DMA DAC */ case 0x91: /* Singe Cycle 8-Bit DMA High speed DAC */ /* Note: 0x91 is documented only for DSP ver.2.x and 3.x, not 4.x */ - DSP_PrepareDMA_Old(DSP_DMA_8,false); + DSP_PrepareDMA_Old(DSP_DMA_8,false,false); break; case 0x90: /* Auto Init 8-bit DMA High Speed */ case 0x1c: /* Auto Init 8-bit DMA */ DSP_SB2_ABOVE; /* Note: 0x90 is documented only for DSP ver.2.x and 3.x, not 4.x */ - DSP_PrepareDMA_Old(DSP_DMA_8,true); + DSP_PrepareDMA_Old(DSP_DMA_8,true,false); break; case 0x38: /* Write to SB MIDI Output */ if (sb.midi == true) MIDI_RawOutByte(sb.dsp.in.data[0]); @@ -736,7 +738,7 @@ static void DSP_DoCommand(void) { sb.freq=(1000000 / (256 - sb.dsp.in.data[0])); /* Nasty kind of hack to allow runtime changing of frequency */ if (sb.dma.mode != DSP_DMA_NONE && sb.dma.autoinit) { - DSP_PrepareDMA_Old(sb.dma.mode,sb.dma.autoinit); + DSP_PrepareDMA_Old(sb.dma.mode,sb.dma.autoinit,sb.dma.sign); } break; case 0x41: /* Set Output Samplerate */ @@ -752,17 +754,17 @@ static void DSP_DoCommand(void) { case 0x75: /* 075h : Single Cycle 4-bit ADPCM Reference */ sb.adpcm.haveref=true; case 0x74: /* 074h : Single Cycle 4-bit ADPCM */ - DSP_PrepareDMA_Old(DSP_DMA_4,false); + DSP_PrepareDMA_Old(DSP_DMA_4,false,false); break; case 0x77: /* 077h : Single Cycle 3-bit(2.6bit) ADPCM Reference*/ sb.adpcm.haveref=true; case 0x76: /* 074h : Single Cycle 3-bit(2.6bit) ADPCM */ - DSP_PrepareDMA_Old(DSP_DMA_3,false); + DSP_PrepareDMA_Old(DSP_DMA_3,false,false); break; case 0x17: /* 017h : Single Cycle 2-bit ADPCM Reference*/ sb.adpcm.haveref=true; case 0x16: /* 074h : Single Cycle 2-bit ADPCM */ - DSP_PrepareDMA_Old(DSP_DMA_2,false); + DSP_PrepareDMA_Old(DSP_DMA_2,false,false); break; case 0x80: /* Silence DAC */ PIC_AddEvent(&DSP_RaiseIRQEvent, From 4fdda4e51e1d548b1912dc46a2919efeaec4b54b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 8 Aug 2007 08:04:53 +0000 Subject: [PATCH 2866/4131] Query port 17:0 as well as default port Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2953 --- src/gui/midi_alsa.h | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 475a2082..f9aae8a2 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_alsa.h,v 1.16 2007-06-14 08:23:46 qbix79 Exp $ */ +/* $Id: midi_alsa.h,v 1.17 2007-08-08 08:04:53 qbix79 Exp $ */ #define ALSA_PCM_OLD_HW_PARAMS_API #define ALSA_PCM_OLD_SW_PARAMS_API @@ -125,7 +125,8 @@ public: bool Open(const char * conf) { char var[10]; unsigned int caps; - + bool defaultport = true; //try 17:0 as well. Seems to be default nowadays + // try to use port specified in config file if (conf && conf[0]) { safe_strncpy(var, conf, 10); @@ -133,6 +134,7 @@ public: LOG_MSG("ALSA:Invalid alsa port %s", var); return false; } + defaultport = false; } // default port if none specified else if (parse_addr("65:0", &seq_client, &seq_port) < 0) { @@ -153,8 +155,8 @@ public: if (seq_client == SND_SEQ_ADDRESS_SUBSCRIBERS) caps = ~SND_SEQ_PORT_CAP_SUBS_READ; my_port = - snd_seq_create_simple_port(seq_handle, "DOSBOX", caps, - SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); + snd_seq_create_simple_port(seq_handle, "DOSBOX", caps, + SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); if (my_port < 0) { snd_seq_close(seq_handle); LOG_MSG("ALSA:Can't create ALSA port"); @@ -164,9 +166,18 @@ public: if (seq_client != SND_SEQ_ADDRESS_SUBSCRIBERS) { /* subscribe to MIDI port */ if (snd_seq_connect_to(seq_handle, my_port, seq_client, seq_port) < 0) { - snd_seq_close(seq_handle); - LOG_MSG("ALSA:Can't subscribe to MIDI port (%d:%d)", seq_client, seq_port); - return false; + if (defaultport) { //if port "65:0" (default) try "17:0" as well + seq_client = 17; seq_port = 0; //Update reported values + if(snd_seq_connect_to(seq_handle,my_port,seq_client,seq_port) < 0) { + snd_seq_close(seq_handle); + LOG_MSG("ALSA:Can't subscribe to MIDI port (65:0) nor (17:0)"); + return false; + } + } else { + snd_seq_close(seq_handle); + LOG_MSG("ALSA:Can't subscribe to MIDI port (%d:%d)", seq_client, seq_port); + return false; + } } } From c7205d0750b1981302420cf19f975652ed63b9f6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 8 Aug 2007 13:16:17 +0000 Subject: [PATCH 2867/4131] Improve/fix aspect correction. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2954 --- include/vga.h | 1 + src/hardware/vga_draw.cpp | 64 ++++++++++++++++++++++++++++++++++----- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/include/vga.h b/include/vga.h index 07736551..d85b4042 100644 --- a/include/vga.h +++ b/include/vga.h @@ -130,6 +130,7 @@ typedef struct { double hdend, htotal; double parts; } delay; + double aspect_ratio; bool double_scan; bool doublewidth,doubleheight; Bit8u font[64*1024]; diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 64f0baad..9ef5836b 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -650,7 +650,7 @@ void VGA_SetupDrawing(Bitu val) { return; } /* Calculate the FPS for this screen */ - float fps;Bitu clock; + float fps; Bitu clock; Bitu htotal, hdend, hbstart, hbend, hrstart, hrend; Bitu vtotal, vdend, vbstart, vbend, vrstart, vrend; if (machine==MCH_VGA) { @@ -710,6 +710,7 @@ void VGA_SetupDrawing(Bitu val) { } break; } + /* Check for 8 for 9 character clock mode */ if (vga.seq.clocking_mode & 1 ) clock/=8; else clock/=9; /* Check for pixel doubling, master clock/2 */ @@ -796,8 +797,44 @@ void VGA_SetupDrawing(Bitu val) { vga.draw.delay.vend); */ vga.draw.parts_total=VGA_PARTS; - double correct_ratio=(100.0/525.0); - double aspect_ratio=((double)htotal/((double)vtotal)/correct_ratio); + /* + 6 Horizontal Sync Polarity. Negative if set + 7 Vertical Sync Polarity. Negative if set + Bit 6-7 indicates the number of lines on the display: + 1: 400, 2: 350, 3: 480 + */ + //Try to determine the pixel size, aspect correct is based around square pixels + + //Base pixel width around 100 clocks horizontal + //For 9 pixel text modes this should be changed, but we don't support that anyway :) + //Seems regular vga only listens to the 9 char pixel mode with character mode enabled + double pwidth = 100.0 / htotal; + //Base pixel height around vertical totals of modes that have 100 clocks horizontal + //Different sync values gives different scaling of the whole vertical range + //VGA monitor just seems to thighten or widen the whole vertical range + double pheight; + Bitu sync = vga.misc_output >> 6; + switch ( sync ) { + case 0: // This is not defined in vga specs, + // Kiet, seems to be slightly less than 350 on my monitor + //340 line mode, filled with 449 total + pheight = (480.0 / 340.0) * ( 449.0 / vtotal ); + break; + case 1: //400 line mode, filled with 449 total + pheight = (480.0 / 400.0) * ( 449.0 / vtotal ); + break; + case 2: //350 line mode, filled with 449 total + //This mode seems to get regular 640x400 timing and goes for a loong retrace + //Depends on the monitor to stretch the screen + pheight = (480.0 / 350.0) * ( 449.0 / vtotal ); + break; + case 3: //480 line mode, filled with 525 total + pheight = (480.0 / 480.0) * ( 525.0 / vtotal ); + break; + } + + double aspect_ratio = pheight / pwidth; + vga.draw.delay.parts = vga.draw.delay.vdend/vga.draw.parts_total; vga.draw.resizing=false; @@ -965,15 +1002,26 @@ void VGA_SetupDrawing(Bitu val) { vga.changes.frame = 0; vga.changes.writeMask = 1; #endif - if (( width != vga.draw.width) || (height != vga.draw.height) || (vga.mode != vga.lastmode)) { + /* + Cheap hack to just make all > 640x480 modes have 4:3 aspect ratio + */ + if ( width >= 640 && height >= 480 ) { + aspect_ratio = ((float)width / (float)height) * ( 3.0 / 4.0); + } +// LOG_MSG("ht %d vt %d ratio %f", htotal, vtotal, aspect_ratio ); + + if (( width != vga.draw.width) || (height != vga.draw.height) || + (aspect_ratio != vga.draw.aspect_ratio) || + (vga.mode != vga.lastmode)) { vga.lastmode = vga.mode; PIC_RemoveEvents(VGA_VerticalTimer); PIC_RemoveEvents(VGA_VerticalDisplayEnd); PIC_RemoveEvents(VGA_DrawPart); - vga.draw.width=width; - vga.draw.height=height; - vga.draw.doublewidth=doublewidth; - vga.draw.doubleheight=doubleheight; + vga.draw.width = width; + vga.draw.height = height; + vga.draw.doublewidth = doublewidth; + vga.draw.doubleheight = doubleheight; + vga.draw.aspect_ratio = aspect_ratio; if (doubleheight) vga.draw.lines_scaled=2; else vga.draw.lines_scaled=1; #if C_DEBUG From e112331433bb3d277ee851c4f70280fcaf93b656 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 8 Aug 2007 16:59:53 +0000 Subject: [PATCH 2868/4131] Fix compilation on bsds. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2955 --- configure.in | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index c77bb4b2..209c1979 100644 --- a/configure.in +++ b/configure.in @@ -406,8 +406,11 @@ case "$target" in AC_DEFINE(MACOSX, 1, [Compiling on Mac OS X]) LIBS="$LIBS -framework AudioUnit" ;; - *-*-freebsd* | *-*-linux* | *-*-dragonfly* | *-*-netbsd* | *-*-openbsd*) - AC_DEFINE(LINUX, 1, [Compiling on GNU/Linux or *BSD]) + *-*-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*) AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).]) ;; *-*-os2-emx*) From ef032e575c96c8c88d1f06904476d479d8f4f9ee Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 8 Aug 2007 18:31:59 +0000 Subject: [PATCH 2869/4131] Some changes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2956 --- ChangeLog | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ChangeLog b/ChangeLog index 71da89c8..87622a12 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +0.71.1 + - 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. + - 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. + 0.71 - Add a new recompiling cpu core, which should be easier to port. - Add 64 bit version of the recompiling core. From d4046475294fc49ed269842867d5e6df131b6f3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 9 Aug 2007 19:52:33 +0000 Subject: [PATCH 2870/4131] enable core=auto switching for recompiling core as well Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2957 --- src/cpu/cpu.cpp | 12 ++++++++++-- src/dos/dos_execute.cpp | 4 ++-- src/dosbox.cpp | 14 +++++++------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index fd4e6d61..311e1d58 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.102 2007-06-12 20:22:07 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.103 2007-08-09 19:52:32 c2woody Exp $ */ #include #include @@ -1487,11 +1487,16 @@ void CPU_SET_CRX(Bitu cr,Bitu value) { } else { GFX_SetTitle(-1,-1,false); } - #if (C_DYNAMIC_X86) +#if (C_DYNAMIC_X86) if (CPU_AutoDetermineMode&CPU_AUTODETERMINE_CORE) { CPU_Core_Dyn_X86_Cache_Init(true); cpudecoder=&CPU_Core_Dyn_X86_Run; } +#elif (C_DYNREC) + if (CPU_AutoDetermineMode&CPU_AUTODETERMINE_CORE) { + CPU_Core_Dynrec_Cache_Init(true); + cpudecoder=&CPU_Core_Dynrec_Run; + } #endif CPU_AutoDetermineMode<<=CPU_AUTODETERMINE_SHIFT; } else { @@ -2183,6 +2188,9 @@ public: #elif (C_DYNREC) else if (!strcasecmp(core,"dynamic")) { cpudecoder=&CPU_Core_Dynrec_Run; + } else if (!strcasecmp(core,"auto")) { + cpudecoder=&CPU_Core_Normal_Run; + CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CORE; } #endif else { diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 6d3ea569..7ceab107 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.60 2007-01-11 16:31:10 c2woody Exp $ */ +/* $Id: dos_execute.cpp,v 1.61 2007-08-09 19:52:33 c2woody Exp $ */ #include #include @@ -151,7 +151,7 @@ bool DOS_Terminate(bool tsr) { } else { GFX_SetTitle(-1,-1,false); } -#if (C_DYNAMIC_X86) +#if (C_DYNAMIC_X86) || (C_DYNREC) if (CPU_AutoDetermineMode&CPU_AUTODETERMINE_CORE) { cpudecoder=&CPU_Core_Normal_Run; CPU_CycleLeft=0; diff --git a/src/dosbox.cpp b/src/dosbox.cpp index b90f32cb..0395a6fe 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.119 2007-08-07 21:01:08 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.120 2007-08-09 19:52:33 c2woody Exp $ */ #include #include @@ -299,7 +299,7 @@ void DOSBOX_Init(void) { MSG_Add("DOSBOX_CONFIGFILE_HELP", "language -- Select another language file.\n" - "memsize -- Amount of memory dosbox has in megabytes.\n" + "memsize -- Amount of memory DOSBox has in megabytes.\n" "machine -- The type of machine tries to emulate:hercules,cga,tandy,pcjr,vga.\n" "captures -- Directory where things like wave,midi,screenshot get captured.\n" ); @@ -309,7 +309,7 @@ void DOSBOX_Init(void) { secprop->Add_bool("aspect",false); secprop->Add_string("scaler","normal2x"); MSG_Add("RENDER_CONFIGFILE_HELP", - "frameskip -- How many frames dosbox skips before drawing one.\n" + "frameskip -- How many frames DOSBox skips before drawing one.\n" "aspect -- Do aspect correction, if your output method doesn't support scaling this can slow things down!.\n" "scaler -- Scaler used to enlarge/enhance low resolution modes.\n" " Supported are none,normal2x,normal3x,advmame2x,advmame3x,hq2x,hq3x,\n" @@ -320,7 +320,7 @@ void DOSBOX_Init(void) { ); secprop=control->AddSection_prop("cpu",&CPU_Init,true);//done -#if (C_DYNAMIC_X86) +#if (C_DYNAMIC_X86) || (C_DYNREC) secprop->Add_string("core","auto"); #else secprop->Add_string("core","normal"); @@ -330,12 +330,12 @@ void DOSBOX_Init(void) { secprop->Add_int("cycledown",20); MSG_Add("CPU_CONFIGFILE_HELP", "core -- CPU Core used in emulation: normal,simple" -#if (C_DYNAMIC_X86) +#if (C_DYNAMIC_X86) || (C_DYNREC) ",dynamic,auto.\n" " auto switches from normal to dynamic if appropriate" #endif ".\n" - "cycles -- Amount of instructions dosbox tries to emulate each millisecond.\n" + "cycles -- Amount of instructions DOSBox tries to emulate each millisecond.\n" " Setting this value too high results in sound dropouts and lags.\n" " You can also let DOSBox guess the correct value by setting it to max.\n" " The default setting (auto) switches to max if appropriate.\n" @@ -395,7 +395,7 @@ void DOSBOX_Init(void) { MSG_Add("SBLASTER_CONFIGFILE_HELP", "sbtype -- Type of sblaster to emulate:none,sb1,sb2,sbpro1,sbpro2,sb16.\n" "sbbase,irq,dma,hdma -- The IO/IRQ/DMA/High DMA address of the soundblaster.\n" - "mixer -- Allow the soundblaster mixer to modify the dosbox mixer.\n" + "mixer -- Allow the soundblaster mixer to modify the DOSBox mixer.\n" "oplmode -- Type of OPL emulation: auto,cms,opl2,dualopl2,opl3.\n" " On auto the mode is determined by sblaster type.\n" " All OPL modes are 'Adlib', except for CMS.\n" From c24c5a9772b9456512390e24aa0332f273f9c117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 10 Aug 2007 18:18:29 +0000 Subject: [PATCH 2871/4131] fix color reversal of selected buttons Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2958 --- src/gui/sdl_mapper.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index d937f7f3..b0fe4852 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.40 2007-08-04 09:43:13 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.41 2007-08-10 18:18:29 c2woody Exp $ */ #include #include @@ -1908,13 +1908,13 @@ static void CreateLayout(void) { } } /* Create some text buttons */ - new CTextButton(PX(6),00,124,20,"Keyboard Layout"); - new CTextButton(PX(17),00,124,20,"Joystick Layout"); + new CTextButton(PX(6),0,124,20,"Keyboard Layout"); + new CTextButton(PX(17),0,124,20,"Joystick Layout"); - bind_but.action=new CCaptionButton(185,330,0,0); + bind_but.action=new CCaptionButton(180,330,0,0); bind_but.event_title=new CCaptionButton(0,350,0,0); - bind_but.bind_title=new CCaptionButton(00,365,0,0); + bind_but.bind_title=new CCaptionButton(0,365,0,0); /* Create binding support buttons */ @@ -2233,7 +2233,10 @@ void MAPPER_Run(bool pressed) { /* Set some palette entries */ SDL_SetPalette(mapper.surface, SDL_LOGPAL|SDL_PHYSPAL, map_pal, 0, 5); - last_clicked=NULL; + if (last_clicked) { + last_clicked->SetColor(CLR_WHITE); + last_clicked=NULL; + } /* Go in the event loop */ mapper.exit=false; mapper.redraw=true; From 636f7c79d56c11d68c3ec376f2e2c4d8352f67fc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 11 Aug 2007 12:19:00 +0000 Subject: [PATCH 2872/4131] Fix crashes when changing scaler on startup. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2959 --- src/gui/render.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 58e263c4..a3de853d 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.54 2007-07-05 16:03:49 c2woody Exp $ */ +/* $Id: render.cpp,v 1.55 2007-08-11 12:19:00 qbix79 Exp $ */ #include #include @@ -620,7 +620,8 @@ void RENDER_Init(Section * sec) { } //If something changed that needs a ReInit - if(running &&((render.aspect != aspect) || (render.scale.op != scaleOp) || + // Only ReInit when there is a src.bpp (fixes crashes on startup and directly changing the scaler without a screen specified yet) + if(running && render.src.bpp && ((render.aspect != aspect) || (render.scale.op != scaleOp) || (render.scale.size != scalersize) || (render.scale.forced != scalerforced) || render.scale.forced)) RENDER_CallBack( GFX_CallBackReset ); From 703e78806c74d87fcc3e075442a38a2ae48ea4e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 11 Aug 2007 20:13:58 +0000 Subject: [PATCH 2873/4131] add keyboard layouts Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2960 --- src/dos/dos_keyboard_layout.cpp | 201 +- src/dos/dos_keyboard_layout_data.h | 6135 ++++++++++++++++++++++++---- 2 files changed, 5462 insertions(+), 874 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 4a26b027..2fa4cb1b 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -188,6 +188,45 @@ static Bit32u read_kcl_file(const char* kcl_file_name, const char* layout_id) { return 0; } +static Bit32u read_kcl_data(Bit8u * kcl_data, Bit32u kcl_data_size, const char* layout_id) { + // check ID-bytes + if ((kcl_data[0]!=0x4b) || (kcl_data[1]!=0x43) || (kcl_data[2]!=0x46)) { + return 0; + } + + Bit32u dpos=7+kcl_data[6]; + + for (;;) { + if (dpos+5>kcl_data_size) break; + Bit32u cur_pos=dpos; + Bit16u len=host_readw(&kcl_data[dpos]); + Bit8u data_len=kcl_data[dpos+2]; + dpos+=5; + + char lng_codes[256]; + // get all language codes for this layout + for (Bitu i=0; ikcl_data_size) break; + char lc=(char)kcl_data[dpos]; + dpos++; + i++; + if (lc==',') break; + lng_codes[lcpos++]=lc; + } + lng_codes[lcpos]=0; + if (strcasecmp(lng_codes, layout_id)==0) { + // language ID found, return position + return cur_pos; + } + } + dpos=cur_pos+3+len; + } + return 0; +} + Bitu keyboard_layout::read_keyboard_file(const char* keyboard_file_name, Bit32s specific_layout, Bit32s requested_codepage) { this->reset(); @@ -202,72 +241,36 @@ Bitu keyboard_layout::read_keyboard_file(const char* keyboard_file_name, Bit32s sprintf(nbuf, "%s.kl", keyboard_file_name); FILE* tempfile = OpenDosboxFile(nbuf); if (tempfile==NULL) { - // see if build-in keyboard layout is available, then copy it - if (!strncasecmp(keyboard_file_name,"BG",2)) { - read_buf_size=687; - for (Bitu i=0; i Date: Sun, 12 Aug 2007 10:23:36 +0000 Subject: [PATCH 2874/4131] make the used joystick selectable when 4axis is specified Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2961 --- include/joystick.h | 3 ++- src/hardware/joystick.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/joystick.h b/include/joystick.h index d590250f..7cd44494 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: joystick.h,v 1.11 2007-02-22 08:44:06 qbix79 Exp $ */ +/* $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); @@ -40,6 +40,7 @@ enum JoystickType { JOY_AUTO, JOY_2AXIS, JOY_4AXIS, + JOY_4AXIS_2, JOY_FCS, JOY_CH }; diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index 8f336607..f8fc6341 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: joystick.cpp,v 1.18 2007-02-22 08:44:07 qbix79 Exp $ */ +/* $Id: joystick.cpp,v 1.19 2007-08-12 10:23:36 c2woody Exp $ */ #include #include "dosbox.h" @@ -201,6 +201,7 @@ public: else if (!strcasecmp(type,"auto")) joytype = JOY_AUTO; else if (!strcasecmp(type,"2axis")) joytype = JOY_2AXIS; else if (!strcasecmp(type,"4axis")) joytype = JOY_4AXIS; + else if (!strcasecmp(type,"4axis_2")) joytype = JOY_4AXIS_2; else if (!strcasecmp(type,"fcs")) joytype = JOY_FCS; else if (!strcasecmp(type,"ch")) joytype = JOY_CH; else joytype = JOY_AUTO; From 6741e18d60c39515bb25c4f288de8d36c7568947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 12 Aug 2007 10:23:37 +0000 Subject: [PATCH 2875/4131] make the joystick to use for 4axis selectable Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2962 --- src/gui/sdl_mapper.cpp | 84 +++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 38 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index b0fe4852..6dcdc191 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.41 2007-08-10 18:18:29 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.42 2007-08-12 10:23:36 c2woody Exp $ */ #include #include @@ -597,23 +597,21 @@ bool autofire = false; class CStickBindGroup : public CBindGroup { public: - CStickBindGroup(Bitu _stick,bool _dummy=false) : CBindGroup (){ - stick=_stick; - sprintf(configname,"stick_%d",stick); - is_dummy=_dummy; - if (_dummy) { - sdl_joystick=NULL; - axes=0; buttons=0; hats=0; - button_wrap=0; - button_cap=0; axes_cap=0; hats_cap=0; - emulated_buttons=0; emulated_axes=0; emulated_hats=0; - return; - } + CStickBindGroup(Bitu _stick,Bitu _emustick,bool _dummy=false) : CBindGroup (){ + stick=_stick; // the number of the physical device (SDL numbering|) + emustick=_emustick; // the number of the emulated device + sprintf(configname,"stick_%d",emustick); - // initialize emulated joystick state - emulated_axes=2; - emulated_buttons=2; - emulated_hats=0; + sdl_joystick=NULL; + axes=0; buttons=0; hats=0; + button_wrap=0; + button_cap=0; axes_cap=0; hats_cap=0; + emulated_buttons=0; emulated_axes=0; emulated_hats=0; + + is_dummy=_dummy; + if (_dummy) return; + + // initialize binding lists and position data pos_axis_lists=new CBindList[4]; neg_axis_lists=new CBindList[4]; button_lists=new CBindList[MAXBUTTON]; @@ -629,18 +627,18 @@ public: old_neg_axis_state[i]=false; } - //if the first stick is set, we must be the second -// emustick=JOYSTICK_IsEnabled(0); - emustick=stick; + // initialize emulated joystick state + emulated_axes=2; + emulated_buttons=2; + emulated_hats=0; JOYSTICK_Enable(emustick,true); sdl_joystick=SDL_JoystickOpen(_stick); if (sdl_joystick==NULL) { - axes=0; buttons=0; hats=0; - button_wrap=0; - button_cap=0; axes_cap=0; hats_cap=0; + button_wrap=emulated_buttons; return; } + axes=SDL_JoystickNumAxes(sdl_joystick); buttons=SDL_JoystickNumButtons(sdl_joystick); hats=SDL_JoystickNumHats(sdl_joystick); @@ -884,7 +882,7 @@ protected: class C4AxisBindGroup : public CStickBindGroup { public: - C4AxisBindGroup(Bitu _stick) : CStickBindGroup (_stick){ + C4AxisBindGroup(Bitu _stick,Bitu _emustick) : CStickBindGroup (_stick,_emustick){ emulated_axes=4; emulated_buttons=4; if (button_wrapping_enabled) button_wrap=emulated_buttons; @@ -954,7 +952,7 @@ public: class CFCSBindGroup : public CStickBindGroup { public: - CFCSBindGroup(Bitu _stick) : CStickBindGroup (_stick){ + CFCSBindGroup(Bitu _stick,Bitu _emustick) : CStickBindGroup (_stick,_emustick){ emulated_axes=4; emulated_buttons=4; old_hat_position=0; @@ -1091,7 +1089,7 @@ private: class CCHBindGroup : public CStickBindGroup { public: - CCHBindGroup(Bitu _stick) : CStickBindGroup (_stick){ + CCHBindGroup(Bitu _stick,Bitu _emustick) : CStickBindGroup (_stick,_emustick){ emulated_axes=4; emulated_buttons=6; emulated_hats=1; @@ -2150,9 +2148,15 @@ static void InitializeJoysticks(void) { if (joytype != JOY_NONE) { mapper.sticks.num=SDL_NumJoysticks(); if (joytype==JOY_AUTO) { - if (mapper.sticks.num>1) joytype=JOY_2AXIS; - else if (mapper.sticks.num) joytype=JOY_4AXIS; - else joytype=JOY_NONE; + if (mapper.sticks.num>1) { + joytype=JOY_2AXIS; + LOG_MSG("Two or more joysticks reported, initializing with 2axis"); + } else if (mapper.sticks.num) { + joytype=JOY_4AXIS; + LOG_MSG("One joystick reported, initializing with 4axis"); + } else { + joytype=JOY_NONE; + } } } } @@ -2174,24 +2178,28 @@ static void CreateBindGroups(void) { case JOY_NONE: break; case JOY_4AXIS: - mapper.sticks.stick[mapper.sticks.num_groups++]=new C4AxisBindGroup(joyno); - new CStickBindGroup(joyno+1U,true); + mapper.sticks.stick[mapper.sticks.num_groups++]=new C4AxisBindGroup(joyno,joyno); + new CStickBindGroup(joyno+1U,joyno+1U,true); + break; + case JOY_4AXIS_2: + mapper.sticks.stick[mapper.sticks.num_groups++]=new C4AxisBindGroup(joyno+1U,joyno); + new CStickBindGroup(joyno,joyno+1U,true); break; case JOY_FCS: - mapper.sticks.stick[mapper.sticks.num_groups++]=new CFCSBindGroup(joyno); - new CStickBindGroup(joyno+1U,true); + mapper.sticks.stick[mapper.sticks.num_groups++]=new CFCSBindGroup(joyno,joyno); + new CStickBindGroup(joyno+1U,joyno+1U,true); break; case JOY_CH: - mapper.sticks.stick[mapper.sticks.num_groups++]=new CCHBindGroup(joyno); - new CStickBindGroup(joyno+1U,true); + mapper.sticks.stick[mapper.sticks.num_groups++]=new CCHBindGroup(joyno,joyno); + new CStickBindGroup(joyno+1U,joyno+1U,true); break; case JOY_2AXIS: default: - mapper.sticks.stick[mapper.sticks.num_groups++]=new CStickBindGroup(joyno); + mapper.sticks.stick[mapper.sticks.num_groups++]=new CStickBindGroup(joyno,joyno); if((joyno+1U) < mapper.sticks.num) { - mapper.sticks.stick[mapper.sticks.num_groups++]=new CStickBindGroup(joyno+1U); + mapper.sticks.stick[mapper.sticks.num_groups++]=new CStickBindGroup(joyno+1U,joyno+1U); } else { - new CStickBindGroup(joyno+1U,true); + new CStickBindGroup(joyno+1U,joyno+1U,true); } break; } From 5844536adaa82d6eeb685f870aa58e677f99278d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 12 Aug 2007 12:40:49 +0000 Subject: [PATCH 2876/4131] update layout section Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2963 --- README | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/README b/README index bc73d559..75144bdb 100644 --- a/README +++ b/README @@ -909,12 +909,6 @@ Layout switching keyboardlayout=sv in the DOSBox config file, or using "keyb sv" at the DOSBox command prompt). - Internally supported keyboard layouts: - BG (Bulgaria), CZ243 (Czech Republic), FR (France), GK (Greece), - GR (Germany), HR (Croatia), HU (Hungary), IT (Italy), NL (Netherlands), - NO (Norway), PL (Poland), RU (Russian Federation), SK (Slovakia), SP (Spain), - SU (Finland), SV (Sweden) - Some keyboard layouts (for example layout GK codepage 869 and layout RU codepage 808) have support for dual layouts that can be activated by pressing LEFT-ALT+RIGHT-SHIFT and deactivated by LEFT-ALT+LEFT-SHIFT. @@ -923,7 +917,9 @@ Supported external files The freedos .kl files are supported (freedos keyb2 keyboard layoutfiles) as well as the freedos keyboard.sys/keybrd2.sys/keybrd3.sys libraries which consist of all available .kl files. - See http://projects.freedos.net/keyb/ for precompiled keyboard layouts. + See http://projects.freedos.net/keyb/ for precompiled keyboard layouts if + the DOSBox-integrated layouts don't work for some reason, or updated or + new layouts become available. Both .CPI (MSDOS/compatible codepage files) and .CPX (freedos UPX-compressed codepage files) can be used. Some codepages are compiled into DOSBox, so it @@ -936,6 +932,7 @@ Supported external files language code. Example: For the file UZ.KL (keyboard layout for Uzbekistan) specify "keyboardlayout=uz" in dosbox.conf. + The integration of keyboard layout packages (like keybrd2.sys) works similar. Note that the keyboard layout allows foreign characters to be entered, but From 0190a6e14972dc4854997621bbccceb4c72b475b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 12 Aug 2007 19:16:01 +0000 Subject: [PATCH 2877/4131] Silence a few warnings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2964 --- include/mixer.h | 6 +++--- src/hardware/mixer.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/mixer.h b/include/mixer.h index da3fea70..70162024 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -69,12 +69,12 @@ public: Bitu freq_add,freq_index; Bitu done,needed; Bits last[2]; - char * name; + const char * name; bool enabled; MixerChannel * next; }; -MixerChannel * MIXER_AddChannel(MIXER_Handler handler,Bitu freq,char * name); +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); @@ -87,7 +87,7 @@ private: char m_name[32]; public: MixerObject():installed(false){}; - MixerChannel* Install(MIXER_Handler handler,Bitu freq,char * name); + MixerChannel* Install(MIXER_Handler handler,Bitu freq,const char * name); ~MixerObject(); }; diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 4be4072d..7991c1bb 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.46 2007-06-12 20:22:08 c2woody Exp $ */ +/* $Id: mixer.cpp,v 1.47 2007-08-12 19:16:01 c2woody Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -91,7 +91,7 @@ static struct { Bit8u MixTemp[MIXER_BUFSIZE]; -MixerChannel * MIXER_AddChannel(MIXER_Handler handler,Bitu freq,char * name) { +MixerChannel * MIXER_AddChannel(MIXER_Handler handler,Bitu freq,const char * name) { MixerChannel * chan=new MixerChannel(); chan->handler=handler; chan->name=name; @@ -526,7 +526,7 @@ public: ShowVolume(chan->name,chan->volmain[0],chan->volmain[1]); } private: - void ShowVolume(char * name,float vol0,float vol1) { + void ShowVolume(const char * name,float vol0,float vol1) { WriteOut("%-8s %3.0f:%-3.0f %+3.2f:%-+3.2f \n",name, vol0*100,vol1*100, 20*log(vol0)/log(10.0f),20*log(vol1)/log(10.0f) @@ -551,7 +551,7 @@ static void MIXER_ProgramStart(Program * * make) { *make=new MIXER; } -MixerChannel* MixerObject::Install(MIXER_Handler handler,Bitu freq,char * name){ +MixerChannel* MixerObject::Install(MIXER_Handler handler,Bitu freq,const char * name){ if(!installed) { if(strlen(name) > 31) E_Exit("Too long mixer channel name"); safe_strncpy(m_name,name,32); From f8733e94cf5e69f6eef8ecf428c33cefb273b4ee Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 12 Aug 2007 19:16:09 +0000 Subject: [PATCH 2878/4131] Some more hints in CHDIR Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2965 --- src/shell/shell.cpp | 3 ++- src/shell/shell_cmds.cpp | 21 +++++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 4328a5f3..f872da8c 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.86 2007-07-03 17:32:14 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.87 2007-08-12 19:16:09 qbix79 Exp $ */ #include #include @@ -439,6 +439,7 @@ void SHELL_Init() { MSG_Add("SHELL_MISSING_PARAMETER","Required parameter missing.\n"); MSG_Add("SHELL_CMD_CHDIR_ERROR","Unable to change to: %s.\n"); MSG_Add("SHELL_CMD_CHDIR_HINT","To change to different drive type \033[31m%c:\033[0m\n"); + MSG_Add("SHELL_CMD_CHDIR_HINT_2","directoryname is longer than 8 charachters and/or contains spaces.\nTry \033[31mcd %s\033[0m\n"); MSG_Add("SHELL_CMD_MKDIR_ERROR","Unable to make: %s.\n"); MSG_Add("SHELL_CMD_RMDIR_ERROR","Unable to remove: %s.\n"); MSG_Add("SHELL_CMD_DEL_ERROR","Unable to delete: %s.\n"); diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 14fd0ad8..c9f04f5c 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.76 2007-06-14 08:23:46 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.77 2007-08-12 19:16:09 qbix79 Exp $ */ #include #include @@ -268,7 +268,24 @@ void DOS_Shell::CMD_CHDIR(char * args) { } else if(strlen(args) == 2 && args[1]==':') { WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT"),toupper(*reinterpret_cast(&args[0]))); } else if (!DOS_ChangeDir(args)) { - WriteOut(MSG_Get("SHELL_CMD_CHDIR_ERROR"),args); + /* Changedir failed. Check if the filename is longer then 8 and/or contains spaces */ + char temp[DOS_PATHLENGTH]; + safe_strncpy(temp,args,DOS_PATHLENGTH); + char* dot = strrchr(temp,'.'); + if(dot) *dot = 0; + dot = strrchr(temp,' '); + if(dot) { /* Contains spaces */ + *dot = 0; + if(strlen(temp) > 6) temp[6] = 0; + strcat(temp,"~1"); + WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_2"),temp); + } else if(strlen(temp) >8) { + temp[6] = 0; + strcat(temp,"~1"); + WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_2"),temp); + } else { + WriteOut(MSG_Get("SHELL_CMD_CHDIR_ERROR"),args); + } } }; From eeeffe43f804c6615c5ed0527ef9d4ad4b6365a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 13 Aug 2007 20:37:03 +0000 Subject: [PATCH 2879/4131] small fix for hq2x 32bpp to 16bpp conversion Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2966 --- src/gui/render_templates_hq2x.h | 2 +- src/gui/render_templates_hq3x.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/render_templates_hq2x.h b/src/gui/render_templates_hq2x.h index c74d790a..4937af56 100644 --- a/src/gui/render_templates_hq2x.h +++ b/src/gui/render_templates_hq2x.h @@ -80,7 +80,7 @@ #endif #if SBPP == 32 -#define RGBtoYUV(c) _RGBtoYUV[((c & 0xf80000) >> 8) | ((c & 0x00fc00) >> 12) | ((c & 0x0000f8) >> 3)] +#define RGBtoYUV(c) _RGBtoYUV[((c & 0xf80000) >> 8) | ((c & 0x00fc00) >> 5) | ((c & 0x0000f8) >> 3)] #else #define RGBtoYUV(c) _RGBtoYUV[c] #endif diff --git a/src/gui/render_templates_hq3x.h b/src/gui/render_templates_hq3x.h index c4c2a59d..d879de8f 100644 --- a/src/gui/render_templates_hq3x.h +++ b/src/gui/render_templates_hq3x.h @@ -82,7 +82,7 @@ #endif #if SBPP == 32 -#define RGBtoYUV(c) _RGBtoYUV[((c & 0xf80000) >> 8) | ((c & 0x00fc00) >> 12) | ((c & 0x0000f8) >> 3)] +#define RGBtoYUV(c) _RGBtoYUV[((c & 0xf80000) >> 8) | ((c & 0x00fc00) >> 5) | ((c & 0x0000f8) >> 3)] #else #define RGBtoYUV(c) _RGBtoYUV[c] #endif From 30d69b595fd3c5994346dc73dea84608e567c580 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 15 Aug 2007 19:09:25 +0000 Subject: [PATCH 2880/4131] Do touch bl on succes. Fixes Blakestone 1.0 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2967 --- src/ints/xms.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index fc052383..7ddd76f3 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.49 2007-06-25 18:45:48 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.50 2007-08-15 19:09:25 qbix79 Exp $ */ #include #include @@ -262,15 +262,13 @@ static bool multiplex_xms(void) { return false; }; -#define SET_RESULT(caller) { \ -res = caller; \ -if(res) reg_bl = (Bit8u)res; \ -reg_ax = (res==0); \ +INLINE void SET_RESULT(Bitu res,bool touch_bl_on_succes=true) { + if(touch_bl_on_succes || res) reg_bl = (Bit8u)res; + reg_ax = (res==0); } Bitu XMS_Handler(void) { // LOG(LOG_MISC,LOG_ERROR)("XMS: CALL %02X",reg_ah); - Bitu res = 0; switch (reg_ah) { case XMS_GET_VERSION: /* 00 */ @@ -315,12 +313,12 @@ Bitu XMS_Handler(void) { SET_RESULT(XMS_FreeMemory(reg_dx)); break; case XMS_MOVE_EXTENDED_MEMORY_BLOCK: /* 0b */ - SET_RESULT(XMS_MoveMemory(SegPhys(ds)+reg_si)); + SET_RESULT(XMS_MoveMemory(SegPhys(ds)+reg_si),false); break; case XMS_LOCK_EXTENDED_MEMORY_BLOCK: { /* 0c */ Bit32u address; - res = XMS_LockMemory(reg_dx, address); - if(res) reg_bl = res; + Bitu res = XMS_LockMemory(reg_dx, address); + if(res) reg_bl = (Bit8u)res; reg_ax = (res==0); if (res==0) { // success reg_bx=(Bit16u)(address & 0xFFFF); From b788b3dc94353c1ad09f35a43b71fc57fdeeb173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 16 Aug 2007 07:50:31 +0000 Subject: [PATCH 2881/4131] update joystick description Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2968 --- src/dosbox.cpp | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 0395a6fe..b54554c6 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.120 2007-08-09 19:52:33 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.121 2007-08-16 07:50:31 c2woody Exp $ */ #include #include @@ -400,7 +400,7 @@ void DOSBOX_Init(void) { " On auto the mode is determined by sblaster type.\n" " All OPL modes are 'Adlib', except for CMS.\n" "oplrate -- Sample rate of OPL music emulation.\n" - ); + ); secprop=control->AddSection_prop("gus",&GUS_Init,true); //done secprop->Add_bool("gus",true); @@ -443,15 +443,17 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("joystick",&BIOS_Init,false);//done MSG_Add("JOYSTICK_CONFIGFILE_HELP", - "joysticktype -- Type of joystick to emulate: auto (default), none,\n" - " 2axis (supports two joysticks), 4axis,\n" - " fcs (Thrustmaster), ch (CH Flightstick).\n" - " none disables joystick emulation.\n" - " auto chooses emulation depending on real joystick(s).\n" - "timed -- enable timed intervals for axis. (false is old style behaviour).\n" - "autofire -- continuously fires as long as you keep the button pressed.\n" - "swap34 -- swap the 3rd and the 4th axis. can be useful for certain joysticks.\n" - "buttonwrap -- enable button wrapping at the number of emulated buttons.\n" + "joysticktype -- Type of joystick to emulate: auto (default), none,\n" + " 2axis (supports two joysticks,\n" + " 4axis (supports one joystick, first joystick used),\n" + " 4axis_2 (supports one joystick, second joystick used),\n" + " fcs (Thrustmaster), ch (CH Flightstick).\n" + " none disables joystick emulation.\n" + " auto chooses emulation depending on real joystick(s).\n" + "timed -- enable timed intervals for axis. (false is old style behaviour).\n" + "autofire -- continuously fires as long as you keep the button pressed.\n" + "swap34 -- swap the 3rd and the 4th axis. can be useful for certain joysticks.\n" + "buttonwrap -- enable button wrapping at the number of emulated buttons.\n" ); secprop->AddInitFunction(&INT10_Init); @@ -470,15 +472,15 @@ void DOSBOX_Init(void) { secprop->Add_string("serial3","disabled"); secprop->Add_string("serial4","disabled"); MSG_Add("SERIAL_CONFIGFILE_HELP", - "serial1-4 -- set type of device connected to com port.\n" - " Can be disabled, dummy, modem, nullmodem, directserial.\n" - " Additional parameters must be in the same line in the form of\n" - " parameter:value. Parameter for all types is irq.\n" - " for directserial: realport (required), rxdelay (optional).\n" - " for modem: listenport (optional).\n" - " for nullmodem: server, rxdelay, txdelay, telnet, usedtr,\n" - " transparent, port, inhsocket (all optional).\n" - " Example: serial1=modem listenport:5000\n" + "serial1-4 -- set type of device connected to com port.\n" + " Can be disabled, dummy, modem, nullmodem, directserial.\n" + " Additional parameters must be in the same line in the form of\n" + " parameter:value. Parameter for all types is irq.\n" + " for directserial: realport (required), rxdelay (optional).\n" + " for modem: listenport (optional).\n" + " for nullmodem: server, rxdelay, txdelay, telnet, usedtr,\n" + " transparent, port, inhsocket (all optional).\n" + " Example: serial1=modem listenport:5000\n" ); /* All the DOS Related stuff, which will eventually start up in the shell */ From ca00d51a111aeaab6ba484cb64698cc21ab3c662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 16 Aug 2007 13:00:08 +0000 Subject: [PATCH 2882/4131] make the used joystick selectable when 4axis is specified Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2969 --- src/gui/sdl_mapper.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 6dcdc191..48777a87 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.42 2007-08-12 10:23:36 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.43 2007-08-16 13:00:08 c2woody Exp $ */ #include #include @@ -2095,6 +2095,7 @@ static void MAPPER_SaveBinds(void) { fprintf(savefile,"\n"); } fclose(savefile); + change_action_text("Mapper file saved.",CLR_WHITE); } static bool MAPPER_LoadBinds(void) { From f311fd4de8b0fcb783112ee1b7e8a57d3d674ccc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 17 Aug 2007 17:58:46 +0000 Subject: [PATCH 2883/4131] Add some more hints.(wd) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2970 --- src/shell/shell.cpp | 3 ++- src/shell/shell_cmds.cpp | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index f872da8c..3b0ece22 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.87 2007-08-12 19:16:09 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.88 2007-08-17 17:58:46 qbix79 Exp $ */ #include #include @@ -440,6 +440,7 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_CHDIR_ERROR","Unable to change to: %s.\n"); MSG_Add("SHELL_CMD_CHDIR_HINT","To change to different drive type \033[31m%c:\033[0m\n"); MSG_Add("SHELL_CMD_CHDIR_HINT_2","directoryname is longer than 8 charachters and/or contains spaces.\nTry \033[31mcd %s\033[0m\n"); + MSG_Add("SHELL_CMD_CHDIR_HINT_3","You are still on drive Z:, change to a mounted drive with \033[31mC:\033[0m.\n"); MSG_Add("SHELL_CMD_MKDIR_ERROR","Unable to make: %s.\n"); MSG_Add("SHELL_CMD_RMDIR_ERROR","Unable to remove: %s.\n"); MSG_Add("SHELL_CMD_DEL_ERROR","Unable to delete: %s.\n"); diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index c9f04f5c..0574bfae 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.77 2007-08-12 19:16:09 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.78 2007-08-17 17:58:46 qbix79 Exp $ */ #include #include @@ -284,7 +284,12 @@ void DOS_Shell::CMD_CHDIR(char * args) { strcat(temp,"~1"); WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_2"),temp); } else { - WriteOut(MSG_Get("SHELL_CMD_CHDIR_ERROR"),args); + Bit8u drive=DOS_GetDefaultDrive()+'A'; + if (drive=='Z') { + WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_3")); + } else { + WriteOut(MSG_Get("SHELL_CMD_CHDIR_ERROR"),args); + } } } }; From 57f5ce73adb55841d4f4e2af56131aad309c9053 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 17 Aug 2007 18:00:09 +0000 Subject: [PATCH 2884/4131] Some license info Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2971 --- src/gui/sdlmain.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index d86ab4e3..a0fba6b5 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.131 2007-06-12 20:22:08 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.132 2007-08-17 18:00:09 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1349,7 +1349,11 @@ int main(int argc, char* argv[]) { control=&myconf; if (control->cmdline->FindExist("-version") || control->cmdline->FindExist("--version") ) { - printf(VERSION "\n"); + printf("\nDOSBox version %s, Copyright 2002-2007 DOSBox Team.\n\n",VERSION); + printf("DOSBox is written by the DOSBox Team (See AUTHORS(.txt))\n"); + printf("DOSBox comes with ABSOLUTELY NO WARRANTY. This is free software,\n"); + printf("and you are welcome to redistribute it under certain conditions;\n"); + printf("please read 'COPYING(.txt)' thoroughly before doing so.\n\n"); return 0; } @@ -1369,7 +1373,7 @@ int main(int argc, char* argv[]) { fclose(stdin); fclose(stdout); fclose(stderr); - freopen("CONIN$","w",stdin); + freopen("CONIN$","r",stdin); freopen("CONOUT$","w",stdout); freopen("CONOUT$","w",stderr); } @@ -1393,6 +1397,12 @@ int main(int argc, char* argv[]) { setbuf(stderr, NULL); #endif + /* Display Welcometext in the console */ + LOG_MSG("DOSBox version %s",VERSION); + LOG_MSG("Copyright 2002-2007 DOSBox Team, published under GNU GPL."); + LOG_MSG("---"); + + /* Init SDL */ if ( SDL_Init( SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM |SDL_INIT_NOPARACHUTE ) < 0 ) E_Exit("Can't init SDL %s",SDL_GetError()); From 169cf5b3a72e6d054dceda61712a094c67939ef0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 17 Aug 2007 18:49:56 +0000 Subject: [PATCH 2885/4131] Feedback when loading a mapperfile. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2972 --- src/gui/sdl_mapper.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 48777a87..909382c4 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.43 2007-08-16 13:00:08 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.44 2007-08-17 18:49:56 qbix79 Exp $ */ #include #include @@ -2106,6 +2106,7 @@ static bool MAPPER_LoadBinds(void) { CreateStringBind(linein); } fclose(loadfile); + LOG_MSG("MAPPER: Loading mapper settings from %s", mapper.filename); return true; } From 5230623ac21dbcbe00751dcfd3dc996e41bc1479 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 18 Aug 2007 15:00:36 +0000 Subject: [PATCH 2886/4131] Add sdl changes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2973 --- src/platform/Makefile.am | 4 ++- src/platform/sdl-win32.diff | 55 +++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 src/platform/sdl-win32.diff diff --git a/src/platform/Makefile.am b/src/platform/Makefile.am index 6efd8903..34b4b57e 100644 --- a/src/platform/Makefile.am +++ b/src/platform/Makefile.am @@ -1 +1,3 @@ -SUBDIRS = visualc \ No newline at end of file +SUBDIRS = visualc + +EXTRA_DIST = sdl-win32.diff \ No newline at end of file diff --git a/src/platform/sdl-win32.diff b/src/platform/sdl-win32.diff new file mode 100644 index 00000000..efb89b74 --- /dev/null +++ b/src/platform/sdl-win32.diff @@ -0,0 +1,55 @@ +diff -ru SDL-1.2.12/src/main/win32/version.rc SDL-1.2.12release/src/main/win32/version.rc +--- SDL-1.2.12/src/main/win32/version.rc 2007-07-20 07:52:05.000000000 +0200 ++++ SDL-1.2.12release/src/main/win32/version.rc 2007-08-17 19:03:42.000000000 +0200 +@@ -13,7 +13,7 @@ + FILEVERSION 1,2,12,0 + PRODUCTVERSION 1,2,12,0 + FILEFLAGSMASK 0x3fL +- FILEFLAGS 0x0L ++ FILEFLAGS 0x4L + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +diff -ru SDL-1.2.12/src/video/SDL_video.c SDL-1.2.12release/src/video/SDL_video.c +--- SDL-1.2.12/src/video/SDL_video.c 2007-07-20 07:52:25.000000000 +0200 ++++ SDL-1.2.12release/src/video/SDL_video.c 2007-08-17 02:51:52.000000000 +0200 +@@ -75,12 +75,12 @@ + #if SDL_VIDEO_DRIVER_GAPI + &GAPI_bootstrap, + #endif +-#if SDL_VIDEO_DRIVER_WINDIB +- &WINDIB_bootstrap, +-#endif + #if SDL_VIDEO_DRIVER_DDRAW + &DIRECTX_bootstrap, + #endif ++#if SDL_VIDEO_DRIVER_WINDIB ++ &WINDIB_bootstrap, ++#endif + #if SDL_VIDEO_DRIVER_BWINDOW + &BWINDOW_bootstrap, + #endif +diff -ru SDL-1.2.12/src/video/windx5/SDL_dx5events.c SDL-1.2.12release/src/video/windx5/SDL_dx5events.c +--- SDL-1.2.12/src/video/windx5/SDL_dx5events.c 2007-07-20 07:52:25.000000000 +0200 ++++ SDL-1.2.12release/src/video/windx5/SDL_dx5events.c 2007-08-17 02:51:52.000000000 +0200 +@@ -519,7 +519,7 @@ + case WM_SYSKEYDOWN: { + /* Pass syskey to DefWindwoProc (ALT-F4, etc.) */ + } +- break; ++// break; + case WM_KEYUP: + case WM_KEYDOWN: { + /* Ignore windows keyboard messages */; +diff -ru SDL-1.2.12/src/video/windx5/SDL_dx5video.c SDL-1.2.12release/src/video/windx5/SDL_dx5video.c +--- SDL-1.2.12/src/video/windx5/SDL_dx5video.c 2007-07-20 07:52:25.000000000 +0200 ++++ SDL-1.2.12release/src/video/windx5/SDL_dx5video.c 2007-08-17 02:51:52.000000000 +0200 +@@ -1496,7 +1496,7 @@ + } + } + dd_surface3 = NULL; +-#if 0 /* FIXME: enable this when SDL consistently reports lost surfaces */ ++#if 1 /* FIXME: enable this when SDL consistently reports lost surfaces */ + if ( (flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { + video->flags |= SDL_HWSURFACE; + } else { From 04ec89a7d2ce71a9e498e571d2c54016e5aa368d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 18 Aug 2007 15:01:56 +0000 Subject: [PATCH 2887/4131] mentioning the licenses. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2974 --- INSTALL | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/INSTALL b/INSTALL index 60ae2677..6be2b895 100644 --- a/INSTALL +++ b/INSTALL @@ -2,31 +2,44 @@ Things needed for compilation. SDL 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 (optional) If you want to enable the debugger you need a curses library. ncurses should be installed on just about every unix distro. For win32 get pdcurses at http://pdcurses.sourceforge.net + License: Open source -Libpng - Needed for the screenshots. (optional) - For win32 get libpng from http://www.sourceforge.net/projects/gnuwin32 +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 - Needed by libpng. (optional) - For win32 get libz (rename to zlib) from http://www.sourceforge.net/projects/gnuwin32 +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 - For modem/ipx support(optional). Get it from http://www.libsdl.org +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 automake (>=1.6), autoconf(>=2.50). Should be available at http://www.gnu.org From 62c4a16823278fbd4a503241a1adf18d1a08cd8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 18 Aug 2007 15:36:19 +0000 Subject: [PATCH 2888/4131] wrap code cache earlier to prevent large blocks at the end of the cache (crazyc) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2975 --- src/cpu/core_dynrec/cache.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index c8f17858..c543ed3f 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -70,8 +70,16 @@ static struct { 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 { @@ -440,7 +448,7 @@ static CacheBlockDynRec * cache_openblock(void) { block->Clear(); // block size must be at least CACHE_MAXSIZE while (sizecache.size; @@ -490,7 +498,7 @@ static void cache_closeblock(void) { } } // advance the active block pointer - if (!block->cache.next) { + 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 { @@ -526,11 +534,6 @@ static INLINE void cache_addq(Bit64u val) { static void dyn_return(BlockReturn retcode,bool ret_exception); static void dyn_run_code(void); -// 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; /* Define temporary pagesize so the MPROTECT case and the regular case share as much code as possible */ #if (C_HAVE_MPROTECT) From 189b269dfc4f641be48517c25622a8e95fcd22cc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 18 Aug 2007 16:32:04 +0000 Subject: [PATCH 2889/4131] small fixes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2976 --- src/gui/sdlmain.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index a0fba6b5..4a565615 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.132 2007-08-17 18:00:09 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.133 2007-08-18 16:32:04 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1347,16 +1347,6 @@ int main(int argc, char* argv[]) { CommandLine com_line(argc,argv); Config myconf(&com_line); control=&myconf; - if (control->cmdline->FindExist("-version") || - control->cmdline->FindExist("--version") ) { - printf("\nDOSBox version %s, Copyright 2002-2007 DOSBox Team.\n\n",VERSION); - printf("DOSBox is written by the DOSBox Team (See AUTHORS(.txt))\n"); - printf("DOSBox comes with ABSOLUTELY NO WARRANTY. This is free software,\n"); - printf("and you are welcome to redistribute it under certain conditions;\n"); - printf("please read 'COPYING(.txt)' thoroughly before doing so.\n\n"); - return 0; - } - /* Can't disable the console with debugger enabled */ #if defined(WIN32) && !(C_DEBUG) @@ -1380,6 +1370,16 @@ int main(int argc, char* argv[]) { SetConsoleTitle("DOSBox Status Window"); } #endif //defined(WIN32) && !(C_DEBUG) + if (control->cmdline->FindExist("-version") || + control->cmdline->FindExist("--version") ) { + printf("\nDOSBox version %s, copyright 2002-2007 DOSBox Team.\n\n",VERSION); + printf("DOSBox is written by the DOSBox Team (See AUTHORS file))\n"); + printf("DOSBox comes with ABSOLUTELY NO WARRANTY. This is free software,\n"); + printf("and you are welcome to redistribute it under certain conditions;\n"); + printf("please read the COPYING file thoroughly before doing so.\n\n"); + return 0; + } + #if C_DEBUG DEBUG_SetupConsole(); #endif From 2b7818c02d34468a51aea43a37457dec5d7806bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 19 Aug 2007 19:23:02 +0000 Subject: [PATCH 2890/4131] fix language code extraction Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2977 --- src/dos/dos_keyboard_layout.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 2fa4cb1b..64ba936c 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -221,6 +221,7 @@ static Bit32u read_kcl_data(Bit8u * kcl_data, Bit32u kcl_data_size, const char* // language ID found, return position return cur_pos; } + dpos+=2; } dpos=cur_pos+3+len; } From 41e4b3e9e0b2499cd9bd29faf6b089f4c9bed584 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 21 Aug 2007 07:53:26 +0000 Subject: [PATCH 2891/4131] Fix line end Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2978 --- src/platform/sdl-win32.diff | 110 ++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/src/platform/sdl-win32.diff b/src/platform/sdl-win32.diff index efb89b74..0b9ae53a 100644 --- a/src/platform/sdl-win32.diff +++ b/src/platform/sdl-win32.diff @@ -1,55 +1,55 @@ -diff -ru SDL-1.2.12/src/main/win32/version.rc SDL-1.2.12release/src/main/win32/version.rc ---- SDL-1.2.12/src/main/win32/version.rc 2007-07-20 07:52:05.000000000 +0200 -+++ SDL-1.2.12release/src/main/win32/version.rc 2007-08-17 19:03:42.000000000 +0200 -@@ -13,7 +13,7 @@ - FILEVERSION 1,2,12,0 - PRODUCTVERSION 1,2,12,0 - FILEFLAGSMASK 0x3fL -- FILEFLAGS 0x0L -+ FILEFLAGS 0x4L - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -diff -ru SDL-1.2.12/src/video/SDL_video.c SDL-1.2.12release/src/video/SDL_video.c ---- SDL-1.2.12/src/video/SDL_video.c 2007-07-20 07:52:25.000000000 +0200 -+++ SDL-1.2.12release/src/video/SDL_video.c 2007-08-17 02:51:52.000000000 +0200 -@@ -75,12 +75,12 @@ - #if SDL_VIDEO_DRIVER_GAPI - &GAPI_bootstrap, - #endif --#if SDL_VIDEO_DRIVER_WINDIB -- &WINDIB_bootstrap, --#endif - #if SDL_VIDEO_DRIVER_DDRAW - &DIRECTX_bootstrap, - #endif -+#if SDL_VIDEO_DRIVER_WINDIB -+ &WINDIB_bootstrap, -+#endif - #if SDL_VIDEO_DRIVER_BWINDOW - &BWINDOW_bootstrap, - #endif -diff -ru SDL-1.2.12/src/video/windx5/SDL_dx5events.c SDL-1.2.12release/src/video/windx5/SDL_dx5events.c ---- SDL-1.2.12/src/video/windx5/SDL_dx5events.c 2007-07-20 07:52:25.000000000 +0200 -+++ SDL-1.2.12release/src/video/windx5/SDL_dx5events.c 2007-08-17 02:51:52.000000000 +0200 -@@ -519,7 +519,7 @@ - case WM_SYSKEYDOWN: { - /* Pass syskey to DefWindwoProc (ALT-F4, etc.) */ - } -- break; -+// break; - case WM_KEYUP: - case WM_KEYDOWN: { - /* Ignore windows keyboard messages */; -diff -ru SDL-1.2.12/src/video/windx5/SDL_dx5video.c SDL-1.2.12release/src/video/windx5/SDL_dx5video.c ---- SDL-1.2.12/src/video/windx5/SDL_dx5video.c 2007-07-20 07:52:25.000000000 +0200 -+++ SDL-1.2.12release/src/video/windx5/SDL_dx5video.c 2007-08-17 02:51:52.000000000 +0200 -@@ -1496,7 +1496,7 @@ - } - } - dd_surface3 = NULL; --#if 0 /* FIXME: enable this when SDL consistently reports lost surfaces */ -+#if 1 /* FIXME: enable this when SDL consistently reports lost surfaces */ - if ( (flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { - video->flags |= SDL_HWSURFACE; - } else { +diff -ru SDL-1.2.12/src/main/win32/version.rc SDL-1.2.12release/src/main/win32/version.rc +--- SDL-1.2.12/src/main/win32/version.rc 2007-07-20 07:52:05.000000000 +0200 ++++ SDL-1.2.12release/src/main/win32/version.rc 2007-08-17 19:03:42.000000000 +0200 +@@ -13,7 +13,7 @@ + FILEVERSION 1,2,12,0 + PRODUCTVERSION 1,2,12,0 + FILEFLAGSMASK 0x3fL +- FILEFLAGS 0x0L ++ FILEFLAGS 0x4L + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +diff -ru SDL-1.2.12/src/video/SDL_video.c SDL-1.2.12release/src/video/SDL_video.c +--- SDL-1.2.12/src/video/SDL_video.c 2007-07-20 07:52:25.000000000 +0200 ++++ SDL-1.2.12release/src/video/SDL_video.c 2007-08-17 02:51:52.000000000 +0200 +@@ -75,12 +75,12 @@ + #if SDL_VIDEO_DRIVER_GAPI + &GAPI_bootstrap, + #endif +-#if SDL_VIDEO_DRIVER_WINDIB +- &WINDIB_bootstrap, +-#endif + #if SDL_VIDEO_DRIVER_DDRAW + &DIRECTX_bootstrap, + #endif ++#if SDL_VIDEO_DRIVER_WINDIB ++ &WINDIB_bootstrap, ++#endif + #if SDL_VIDEO_DRIVER_BWINDOW + &BWINDOW_bootstrap, + #endif +diff -ru SDL-1.2.12/src/video/windx5/SDL_dx5events.c SDL-1.2.12release/src/video/windx5/SDL_dx5events.c +--- SDL-1.2.12/src/video/windx5/SDL_dx5events.c 2007-07-20 07:52:25.000000000 +0200 ++++ SDL-1.2.12release/src/video/windx5/SDL_dx5events.c 2007-08-17 02:51:52.000000000 +0200 +@@ -519,7 +519,7 @@ + case WM_SYSKEYDOWN: { + /* Pass syskey to DefWindwoProc (ALT-F4, etc.) */ + } +- break; ++// break; + case WM_KEYUP: + case WM_KEYDOWN: { + /* Ignore windows keyboard messages */; +diff -ru SDL-1.2.12/src/video/windx5/SDL_dx5video.c SDL-1.2.12release/src/video/windx5/SDL_dx5video.c +--- SDL-1.2.12/src/video/windx5/SDL_dx5video.c 2007-07-20 07:52:25.000000000 +0200 ++++ SDL-1.2.12release/src/video/windx5/SDL_dx5video.c 2007-08-17 02:51:52.000000000 +0200 +@@ -1496,7 +1496,7 @@ + } + } + dd_surface3 = NULL; +-#if 0 /* FIXME: enable this when SDL consistently reports lost surfaces */ ++#if 1 /* FIXME: enable this when SDL consistently reports lost surfaces */ + if ( (flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { + video->flags |= SDL_HWSURFACE; + } else { From fc25306a9b4b55b856bb95719d79a86c2c665ced Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 21 Aug 2007 20:20:58 +0000 Subject: [PATCH 2892/4131] Add %c %X %s. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2979 --- include/logging.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/logging.h b/include/logging.h index bf161734..dc04e960 100644 --- a/include/logging.h +++ b/include/logging.h @@ -52,6 +52,7 @@ struct LOG 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* ) { } From acd41dba610ff03e2f87082540e92fbb8595b3e2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 22 Aug 2007 07:34:57 +0000 Subject: [PATCH 2893/4131] Clear drive part if no drive is present. Add extra log output for illegal chars. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2980 --- src/dos/dos_files.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index f057bcd2..80ec84ad 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.90 2007-06-29 10:24:43 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.91 2007-08-22 07:34:57 qbix79 Exp $ */ #include #include @@ -94,7 +94,7 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { upname[w++]=c; break; default: - LOG(LOG_FILES,LOG_NORMAL)("Makename encountered an illegal char %c hex:%X !",c,c); + LOG(LOG_FILES,LOG_NORMAL)("Makename encountered an illegal char %c hex:%X in %s!",c,c,name); DOS_SetError(DOSERR_PATH_NOT_FOUND);return false; break; } @@ -768,9 +768,9 @@ checkext: index++; } savefcb: - if (!hasdrive & !(parser & PARSE_DFLT_DRIVE)) fcb_name.part.drive[0]=dos.current_drive+1; + if (!hasdrive & !(parser & PARSE_DFLT_DRIVE)) fcb_name.part.drive[0] = 0; if (!hasname & !(parser & PARSE_BLNK_FNAME)) strcpy(fcb_name.part.name," "); - if (!hasext & !(parser & PARSE_BLNK_FEXT)) strcpy(fcb_name.part.ext," "); + if (!hasext & !(parser & PARSE_BLNK_FEXT)) strcpy(fcb_name.part.ext," "); fcb.SetName(fcb_name.part.drive[0],fcb_name.part.name,fcb_name.part.ext); *change=(Bit8u)(string-string_begin); return ret; From d44511abce302be16ff60290e55a3dafb0e7142a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 22 Aug 2007 11:21:28 +0000 Subject: [PATCH 2894/4131] Fix small bug when for some reason an invalid drive gets selected. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2981 --- src/shell/shell_misc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index e0c371eb..4a023f3f 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.50 2007-08-03 18:22:45 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.51 2007-08-22 11:21:28 qbix79 Exp $ */ #include #include @@ -30,6 +30,7 @@ void DOS_Shell::ShowPrompt(void) { Bit8u drive=DOS_GetDefaultDrive()+'A'; char dir[DOS_PATHLENGTH]; + dir[0] = 0; //DOS_GetCurrentDir doesn't always return something. (if drive is messed up) DOS_GetCurrentDir(0,dir); WriteOut("%c:\\%s>",drive,dir); } From 0382a13bd398d3abb94627d22437b82c42aae98a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 22 Aug 2007 11:54:35 +0000 Subject: [PATCH 2895/4131] Add basic support for audio cds only when dealing with images. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2982 --- src/dos/cdrom.h | 2 ++ src/dos/cdrom_image.cpp | 18 ++++++++++++++---- src/dos/drive_iso.cpp | 41 ++++++++++++++++++++++++++++++++++++++--- src/dos/drives.h | 3 ++- 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index bad8406b..39268232 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -169,6 +169,7 @@ public: bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); bool LoadUnloadMedia (bool unload); bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector); + bool HasDataTrack (void); static CDROM_Interface_Image* images[26]; @@ -202,6 +203,7 @@ static struct imagePlayer { static int refCount; std::vector tracks; +typedef std::vector::iterator track_it; std::string mcn; Bit8u subUnit; }; diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 5cf0b764..1d035ee2 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.16 2007-06-12 20:22:08 c2woody Exp $ */ +/* $Id: cdrom_image.cpp,v 1.17 2007-08-22 11:54:35 qbix79 Exp $ */ #include #include @@ -261,7 +261,7 @@ bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long s MEM_BlockWrite(buffer, buf, buflen); delete[] buf; - + return success; } @@ -294,7 +294,7 @@ bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long se if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false; if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16; if (tracks[track].mode2 && !raw) seek += 24; - + return tracks[track].file->read(buffer, seek, length); } @@ -521,7 +521,7 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) track.length = 0; track.file = NULL; if(!AddTrack(track, shift, 0, totalPregap, 0)) return false; - + return true; } @@ -575,6 +575,16 @@ bool CDROM_Interface_Image::AddTrack(Track &curr, int &shift, int prestart, int return true; } +bool CDROM_Interface_Image::HasDataTrack(void) +{ + //Data track has attribute 0x40 + for(track_it it = tracks.begin(); it != tracks.end(); it++) { + if ((*it).attr == 0x40) return true; + } + return false; +} + + bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) { // check if file exists diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 9ad4a3ca..b339e003 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.20 2007-06-15 19:05:48 c2woody Exp $ */ +/* $Id: drive_iso.cpp,v 1.21 2007-08-22 11:54:35 qbix79 Exp $ */ #include #include @@ -182,7 +182,36 @@ isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &e //Remove trailing dot. if((labelPos > 0) && (discLabel[labelPos - 1] == '.')) discLabel[labelPos - 1] = 0; - } else error = 6; + } else if (CDROM_Interface_Image::images[subUnit]->HasDataTrack() == false) { //Audio only cdrom + strcpy(info, "isoDrive "); + strcat(info, fileName); + this->driveLetter = driveLetter; + this->mediaid = mediaid; + char buffer[32] = { 0 }; + strcpy(buffer, "Audio CD"); + + //Code Copied from drive_cache. (convert mscdex label to a dos 8.3 file) + Bitu togo = 8; + Bitu bufPos = 0; + Bitu labelPos = 0; + bool point = false; + while (togo>0) { + if (buffer[bufPos]==0) break; + if (!point && (buffer[bufPos]=='.')) { togo=4; point=true; } + discLabel[labelPos] = toupper(buffer[bufPos]); + labelPos++; bufPos++; + togo--; + if ((togo==0) && !point) { + if (buffer[bufPos]=='.') bufPos++; + discLabel[labelPos]='.'; labelPos++; point=true; togo=3; + } + }; + discLabel[labelPos]=0; + //Remove trailing dot. + if((labelPos > 0) && (discLabel[labelPos - 1] == '.')) + discLabel[labelPos - 1] = 0; + + } else error = 6; //Corrupt image } } @@ -530,13 +559,19 @@ int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) bool isoDrive :: loadImage() { isoPVD pvd; + dataCD = false; readSector((Bit8u*)(&pvd), ISO_FIRST_VD); if (pvd.type != 1 || strncmp((char*)pvd.standardIdent, "CD001", 5) || pvd.version != 1) return false; - return (readDirEntry(&this->rootEntry, pvd.rootEntry)>0); + if (readDirEntry(&this->rootEntry, pvd.rootEntry)>0) { + dataCD = true; + return true; + } + return false; } bool isoDrive :: lookup(isoDirEntry *de, const char *path) { + if (!dataCD) return false; *de = this->rootEntry; if (!strcmp(path, "")) return true; diff --git a/src/dos/drives.h b/src/dos/drives.h index 371cb01b..b80e1ac2 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.37 2007-06-14 08:23:46 qbix79 Exp $ */ +/* $Id: drives.h,v 1.38 2007-08-22 11:54:35 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ @@ -357,6 +357,7 @@ private: Bit8u data[ISO_FRAMESIZE]; } sectorHashEntries[ISO_MAX_HASH_TABLE_SIZE]; + bool dataCD; isoDirEntry rootEntry; Bit8u mediaid; char fileName[CROSS_LEN]; From a046414fdf972e6b07330a290c09013ff7355b9a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 22 Aug 2007 11:54:54 +0000 Subject: [PATCH 2896/4131] Silence a warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2983 --- src/dos/dos_programs.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 8d8eec46..645b3105 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.76 2007-07-02 14:10:27 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.77 2007-08-22 11:54:54 qbix79 Exp $ */ #include "dosbox.h" #include @@ -528,9 +528,9 @@ public: if((temp_line == "-e") || (temp_line == "-E")) { /* Command mode for PCJr cartridges */ i++; - if(cmd->FindCommand(i+1, temp_line)) { - for(size_t i=0;iFindCommand(i + 1, temp_line)) { + for(size_t ct = 0;ct < temp_line.size();ct++) temp_line[ct] = toupper(temp_line[ct]); + cart_cmd = temp_line; } else { printError(); return; From 6f814e272bcc86c3f9341652a3cbefe0cd27c13a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 22 Aug 2007 12:34:43 +0000 Subject: [PATCH 2897/4131] some space for larger blocks Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2984 --- src/cpu/core_dynrec.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index f9af3efa..7e6944f1 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -50,7 +50,7 @@ #include "inout.h" #include "lazyflags.h" -#define CACHE_MAXSIZE (4096) +#define CACHE_MAXSIZE (4096*2) #define CACHE_TOTAL (1024*1024*8) #define CACHE_PAGES (512) #define CACHE_BLOCKS (128*1024) @@ -135,13 +135,13 @@ static struct { #define X86 0x01 #define X86_64 0x02 -#define MIPSEL32 0x03 +#define MIPSEL 0x03 #if C_TARGETCPU == X86_64 #include "core_dynrec/risc_x64.h" #elif C_TARGETCPU == X86 #include "core_dynrec/risc_x86.h" -#elif C_TARGETCPU == MIPSEL32 +#elif C_TARGETCPU == MIPSEL #include "core_dynrec/risc_mipsel32.h" #endif From 9db3e82af1d2642d554ea96e4cd828b98cf922a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 22 Aug 2007 17:47:15 +0000 Subject: [PATCH 2898/4131] add version resource, add resources to msvc project files Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2985 --- src/dosbox.rc | 38 +++++++++++++++++++++++++++++++++++++- visualc_net/dosbox.vcproj | 6 ++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/dosbox.rc b/src/dosbox.rc index 024db97e..a77e6dd1 100644 --- a/src/dosbox.rc +++ b/src/dosbox.rc @@ -1 +1,37 @@ -dosbox_ico ICON dosbox.ico + +#include "afxres.h" + +// icon resource +dosbox_ico ICON "dosbox.ico" + + +// version resource +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,72,0,0 + PRODUCTVERSION 0,72,0,0 + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "© 2002-2007 DOSBox Team, published under GNU GPL" + VALUE "CompanyName", "DOSBox Team" + VALUE "FileDescription", "DOSBox DOS Emulator" + VALUE "FileVersion", "0, 72, 0, 0" + VALUE "InternalName", "DOSBox" + VALUE "LegalCopyright", "Copyright © 2002-2007 DOSBox Team" + VALUE "OriginalFilename", "dosbox.exe" + VALUE "ProductName", "DOSBox DOS Emulator" + VALUE "ProductVersion", "0, 72, 0, 0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 4a454829..11a108f4 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -158,6 +158,9 @@ + + @@ -847,6 +850,9 @@ RelativePath="..\include\video.h"> + + From dfc13fc99c0b7255c54b3f7c1fa3b2eb7bb1b691 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 Aug 2007 17:06:20 +0000 Subject: [PATCH 2899/4131] 0.72 changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2986 --- ChangeLog | 12 ++++++++++-- NEWS | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 87622a12..aec4a64b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,14 +1,22 @@ -0.71.1 +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. + - 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. diff --git a/NEWS b/NEWS index 2291df19..d629edcd 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,23 @@ +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. From 6d39ef970fc16599200099674f8d9e5368fdbd26 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 Aug 2007 17:19:46 +0000 Subject: [PATCH 2900/4131] 0.72 final changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2987 --- README | 2 +- VERSION | 2 +- configure.in | 10 ++++++++-- src/hardware/serialport/directserial_posix.cpp | 6 +++--- src/hardware/serialport/directserial_posix.h | 4 ++-- src/platform/visualc/config.h | 2 +- 6 files changed, 16 insertions(+), 10 deletions(-) diff --git a/README b/README index 75144bdb..6a5637fb 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -DOSBox v0.71 +DOSBox v0.72 ===== diff --git a/VERSION b/VERSION index a55c553f..b214dd99 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.71 +0.72 diff --git a/configure.in b/configure.in index 209c1979..d12e026f 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Init. -AC_INIT(dosbox,0.71) +AC_INIT(dosbox,0.72) AC_PREREQ(2.50) AC_CONFIG_SRCDIR(README) @@ -405,13 +405,19 @@ case "$target" in dnl For now I am lazy and do not add proper detection code. AC_DEFINE(MACOSX, 1, [Compiling on Mac OS X]) LIBS="$LIBS -framework AudioUnit" + 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*) - AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).]) + 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 + dnl 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]) diff --git a/src/hardware/serialport/directserial_posix.cpp b/src/hardware/serialport/directserial_posix.cpp index 58f2d0bc..5b6c9db4 100644 --- a/src/hardware/serialport/directserial_posix.cpp +++ b/src/hardware/serialport/directserial_posix.cpp @@ -16,14 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_posix.cpp,v 1.1 2007-01-13 08:35:49 qbix79 Exp $ */ +/* $Id: directserial_posix.cpp,v 1.2 2007-08-26 17:19:46 qbix79 Exp $ */ #include "dosbox.h" #if C_DIRECTSERIAL // Posix version -#if defined (LINUX) +#if defined (LINUX) || defined (MACOSX) #include "serialport.h" #include "directserial_posix.h" @@ -44,7 +44,7 @@ CDirectSerial::CDirectSerial (Bitu id, CommandLine* cmd) InstallationSuccessful = false; rx_retry = 0; - rx_retry_max = 0; + rx_retry_max = 0; std::string prefix="/dev/"; std::string tmpstring; diff --git a/src/hardware/serialport/directserial_posix.h b/src/hardware/serialport/directserial_posix.h index f57102a2..93c7d6a3 100644 --- a/src/hardware/serialport/directserial_posix.h +++ b/src/hardware/serialport/directserial_posix.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_posix.h,v 1.1 2007-01-13 08:35:49 qbix79 Exp $ */ +/* $Id: directserial_posix.h,v 1.2 2007-08-26 17:19:46 qbix79 Exp $ */ // include guard #ifndef DOSBOX_DIRECTSERIAL_POSIX_H @@ -25,7 +25,7 @@ #include "dosbox.h" #if C_DIRECTSERIAL -#ifdef LINUX +#if defined (LINUX) || defined (MACOSX) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 9694796d..630e8b5f 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -1,6 +1,6 @@ #define INLINE __forceinline -#define VERSION "0.71" +#define VERSION "0.72" /* Define to 1 to enable internal debugger, requires libcurses */ From 32a16e8ab9f1148d26e46289c2a3862e6f065eab Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 Aug 2007 17:34:00 +0000 Subject: [PATCH 2901/4131] Update version number Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2988 --- scripts/dosbox-installer.nsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index 950ee3af..fd026290 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -1,5 +1,5 @@ !define VER_MAYOR 0 -!define VER_MINOR 71 +!define VER_MINOR 72 ; The name of the installer Name "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer" From a3ef7e594cbe08578ae4c642e241e46e1bc585cb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 Aug 2007 17:38:48 +0000 Subject: [PATCH 2902/4131] Add .cvsignore Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2989 From 5c9a311f7b62da30b4ceebc4f998680a701091ab Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 Aug 2007 18:03:25 +0000 Subject: [PATCH 2903/4131] Disable buildin icon loading on os x Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2990 --- src/gui/sdlmain.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 4a565615..abf6d134 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.133 2007-08-18 16:32:04 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.134 2007-08-26 18:03:25 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -948,13 +948,16 @@ static void GUI_StartUp(Section * sec) { sdl.active=false; sdl.updating=false; +#if !defined(MACOSX) /* Set Icon (must be done before any sdl_setvideomode call) */ + /* But don't set it on OS X, as we use a nicer external icon there. */ #if WORDS_BIGENDIAN SDL_Surface* logos= SDL_CreateRGBSurfaceFrom((void*)logo,32,32,32,128,0xff000000,0x00ff0000,0x0000ff00,0); #else SDL_Surface* logos= SDL_CreateRGBSurfaceFrom((void*)logo,32,32,32,128,0x000000ff,0x0000ff00,0x00ff0000,0); #endif SDL_WM_SetIcon(logos,NULL); +#endif sdl.desktop.fullscreen=section->Get_bool("fullscreen"); sdl.wait_on_error=section->Get_bool("waitonerror"); From 6188566e38a0257cbd23a5178478495f8711aca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 20 Sep 2007 16:42:43 +0000 Subject: [PATCH 2904/4131] add partial ega-only machine Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2992 --- include/dosbox.h | 5 ++++ src/dos/dev_con.h | 4 +-- src/dos/dos_keyboard_layout.cpp | 2 +- src/dosbox.cpp | 11 +++++--- src/hardware/dma.cpp | 7 ++--- src/hardware/gus.cpp | 4 +-- src/hardware/sblaster.cpp | 4 +-- src/hardware/vga.cpp | 2 +- src/hardware/vga_attr.cpp | 28 ++++++++++++------- src/hardware/vga_crtc.cpp | 30 +++++++++++++-------- src/hardware/vga_dac.cpp | 18 +++++++++++-- src/hardware/vga_draw.cpp | 48 ++++++++++++++++++++------------- src/hardware/vga_gfx.cpp | 8 +++--- src/hardware/vga_memory.cpp | 2 +- src/hardware/vga_misc.cpp | 8 +++--- src/hardware/vga_seq.cpp | 24 ++++++++++------- src/hardware/vga_xga.cpp | 6 +---- src/ints/bios.cpp | 6 ++--- src/ints/int10.cpp | 34 ++++++++++++++++++----- src/ints/int10_char.cpp | 7 +++-- src/ints/int10_memory.cpp | 16 ++++++----- src/ints/int10_modes.cpp | 36 ++++++++++++++++++------- src/ints/int10_pal.cpp | 9 ++++--- 23 files changed, 208 insertions(+), 111 deletions(-) diff --git a/include/dosbox.h b/include/dosbox.h index d74eb8ee..efe7a50b 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -44,6 +44,7 @@ enum MachineType { MCH_CGA, MCH_TANDY, MCH_PCJR, + MCH_EGA, MCH_VGA }; @@ -57,7 +58,11 @@ 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" diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 358a0448..3b55ac67 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.32 2007-06-30 19:33:45 c2woody Exp $ */ +/* $Id: dev_con.h,v 1.33 2007-09-20 16:42:43 c2woody Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" @@ -62,7 +62,7 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { readcache=0; } while (*size>count) { - reg_ah=(machine==MCH_VGA)?0x10:0x0; + reg_ah=(IS_EGAVGA_ARCH)?0x10:0x0; CALLBACK_RunRealInt(0x16); switch(reg_al) { case 13: diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 64ba936c..641a3c39 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -887,7 +887,7 @@ Bitu keyboard_layout::read_codepage_file(const char* codepage_file_name, Bit32s dos.loaded_codepage=(Bit16u)(codepage_id&0xffff); // update font if necessary - if (font_changed && (CurMode->type==M_TEXT) && (machine==MCH_VGA)) { + if (font_changed && (CurMode->type==M_TEXT) && (IS_EGAVGA_ARCH)) { INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); } INT10_SetupRomMemoryChecksum(); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index b54554c6..3e831398 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.121 2007-08-16 07:50:31 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.122 2007-09-20 16:42:43 c2woody Exp $ */ #include #include @@ -254,7 +254,7 @@ static void DOSBOX_RealInit(Section * sec) { "# They are used to (briefly) document the effect of each option.\n"); MAPPER_AddHandler(DOSBOX_UnlockSpeed, MK_f12, MMOD2,"speedlock","Speedlock"); - svgaCard = SVGA_S3Trio; + svgaCard=SVGA_None; machine=MCH_VGA; std::string cmd_machine; const char * mtype; @@ -264,8 +264,11 @@ static void DOSBOX_RealInit(Section * sec) { else if (strcasecmp(mtype,"tandy")==0) machine=MCH_TANDY; else if (strcasecmp(mtype,"pcjr")==0) machine=MCH_PCJR; else if (strcasecmp(mtype,"hercules")==0) machine=MCH_HERC; - else if (strcasecmp(mtype,"vga")==0) machine=MCH_VGA; - else LOG_MSG("DOSBOX:Unknown machine type %s",mtype); + else if (strcasecmp(mtype,"ega")==0) machine=MCH_EGA; + else if (strcasecmp(mtype,"vga")==0) { + machine=MCH_VGA; + svgaCard=SVGA_S3Trio; + } else LOG_MSG("DOSBOX:Unknown machine type %s",mtype); } diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 681082e6..68de882d 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -325,7 +325,8 @@ public: DMA(Section* configuration):Module_base(configuration){ Bitu i; DmaControllers[0] = new DmaController(0); - if (machine==MCH_VGA) DmaControllers[1] = new DmaController(1); + if (IS_EGAVGA_ARCH) DmaControllers[1] = new DmaController(1); + else DmaControllers[1] = NULL; for (i=0;i<0x10;i++) { Bitu mask=IO_MB; @@ -333,7 +334,7 @@ public: /* install handler for first DMA controller ports */ DmaControllers[0]->DMA_WriteHandler[i].Install(i,DMA_Write_Port,mask); DmaControllers[0]->DMA_ReadHandler[i].Install(i,DMA_Read_Port,mask); - if (machine==MCH_VGA) { + if (IS_EGAVGA_ARCH) { /* install handler for second DMA controller ports */ DmaControllers[1]->DMA_WriteHandler[i].Install(0xc0+i*2,DMA_Write_Port,mask); DmaControllers[1]->DMA_ReadHandler[i].Install(0xc0+i*2,DMA_Read_Port,mask); @@ -343,7 +344,7 @@ public: DmaControllers[0]->DMA_WriteHandler[0x10].Install(0x81,DMA_Write_Port,IO_MB,3); DmaControllers[0]->DMA_ReadHandler[0x10].Install(0x81,DMA_Read_Port,IO_MB,3); - if (machine==MCH_VGA) { + if (IS_EGAVGA_ARCH) { /* install handlers for ports 0x81-0x83 (on the second DMA controller) */ DmaControllers[1]->DMA_WriteHandler[0x10].Install(0x89,DMA_Write_Port,IO_MB,3); DmaControllers[1]->DMA_ReadHandler[0x10].Install(0x89,DMA_Read_Port,IO_MB,3); diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 33cd96f9..c952d14a 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -791,7 +791,7 @@ private: MixerObject MixerChan; public: GUS(Section* configuration):Module_base(configuration){ - if(machine!=MCH_VGA) return; + if(!IS_EGAVGA_ARCH) return; Section_prop * section=static_cast(configuration); if(!section->Get_bool("gus")) return; @@ -864,7 +864,7 @@ public: ~GUS() { - if(machine!=MCH_VGA) return; + if(!IS_EGAVGA_ARCH) return; Section_prop * section=static_cast(m_configuration); if(!section->Get_bool("gus")) return; diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index cfeeba7c..112433ac 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.66 2007-08-08 08:03:48 qbix79 Exp $ */ +/* $Id: sblaster.cpp,v 1.67 2007-09-20 16:42:43 c2woody Exp $ */ #include #include @@ -1314,7 +1314,7 @@ private: else type=SBT_16; if (type==SBT_16) { - if ((machine!=MCH_VGA) || !SecondDMAControllerAvailable()) type=SBT_PRO2; + if ((!IS_EGAVGA_ARCH) || !SecondDMAControllerAvailable()) type=SBT_PRO2; } /* OPL/CMS Init */ diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index f8e4d953..1ef5192b 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -56,7 +56,7 @@ void VGA_DetermineMode(void) { } /* Test for graphics or alphanumeric mode */ } else if (vga.attr.mode_control & 1) { - if (vga.gfx.mode & 0x40) VGA_SetMode(M_VGA); + if (IS_VGA_ARCH && (vga.gfx.mode & 0x40)) VGA_SetMode(M_VGA); else if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4); else if ((vga.gfx.miscellaneous & 0x0c)==0x0c) VGA_SetMode(M_CGA2); else { diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 3a0e3f90..5f5ce3bf 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -27,6 +27,15 @@ void VGA_ATTR_SetPalette(Bit8u index,Bit8u val) { if (vga.attr.mode_control & 0x80) val = (val&0xf) | (vga.attr.color_select << 4); val &= 63; val |= (vga.attr.color_select & 0xc) << 4; + if (GCC_UNLIKELY(!IS_VGA_ARCH)) { + if ((vga.misc_output&0xc4)==0x40) { + if (val&0x10) val|=0x38; + else { + val&=0x7; + if (val==6) val=0x14; + } + } + } VGA_DAC_CombineColor(index,val); } @@ -61,6 +70,7 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) { */ break; case 0x10: /* Mode Control Register */ + if (!IS_VGA_ARCH) val&=0x1f; // not really correct, but should do it if ((attr(mode_control) ^ val) & 0x80) { attr(mode_control)^=0x80; for (Bitu i=0;i<0x10;i++) { @@ -143,6 +153,10 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) { */ break; case 0x14: /* Color Select Register */ + if (!IS_VGA_ARCH) { + attr(color_select)=0; + break; + } if (attr(color_select) ^ val) { attr(color_select)=val; for (Bitu i=0;i<0x10;i++) { @@ -190,16 +204,12 @@ Bitu read_p3c1(Bitu port,Bitu iolen) { }; - - - - void VGA_SetupAttr(void) { - if (machine==MCH_VGA) { - IO_RegisterReadHandler(0x3c0,read_p3c0,IO_MB); + if (IS_EGAVGA_ARCH) { IO_RegisterWriteHandler(0x3c0,write_p3c0,IO_MB); - IO_RegisterReadHandler(0x3c1,read_p3c1,IO_MB); + if (IS_VGA_ARCH) { + IO_RegisterReadHandler(0x3c0,read_p3c0,IO_MB); + IO_RegisterReadHandler(0x3c1,read_p3c1,IO_MB); + } } } - - diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 0f8fcf52..58f81b80 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -124,7 +124,8 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { case 0x08: /* Preset Row Scan Register */ crtc(preset_row_scan)=val; vga.config.hlines_skip=val&31; - vga.config.bytes_skip=(val>>5)&3; + if (IS_VGA_ARCH) vga.config.bytes_skip=(val>>5)&3; + else vga.config.bytes_skip=0; // LOG_DEBUG("Skip lines %d bytes %d",vga.config.hlines_skip,vga.config.bytes_skip); /* 0-4 Number of lines we have scrolled down in the first character row. @@ -135,7 +136,8 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { */ break; case 0x09: /* Maximum Scan Line Register */ - vga.config.line_compare=(vga.config.line_compare & 0x5ff)|(val&0x40)<<3; + if (IS_VGA_ARCH) + vga.config.line_compare=(vga.config.line_compare & 0x5ff)|(val&0x40)<<3; if ((vga.crtc.maximum_scan_line ^ val) & 0xbf) { crtc(maximum_scan_line)=val; VGA_StartResize(); @@ -154,7 +156,8 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { case 0x0A: /* Cursor Start Register */ crtc(cursor_start)=val; vga.draw.cursor.sline=val&0x1f; - vga.draw.cursor.enabled=!(val&0x20); + if (IS_VGA_ARCH) vga.draw.cursor.enabled=!(val&0x20); + else vga.draw.cursor.enabled=true; /* 0-4 First scanline of cursor within character. 5 Turns Cursor off if set @@ -203,7 +206,8 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { break; case 0x11: /* Vertical Retrace End Register */ crtc(vertical_retrace_end)=val; - crtc(read_only)=(val & 128)>0; + if (IS_VGA_ARCH) crtc(read_only)=(val & 128)>0; + else crtc(read_only)=false; /* 0-3 Vertical Retrace ends when the last 4 bits of the line counter equals this value. @@ -242,13 +246,17 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { break; case 0x14: /* Underline Location Register */ crtc(underline_location)=val; - //Byte,word,dword mode - if ( crtc(underline_location) & 0x20 ) - vga.config.addr_shift = 2; - else if ( crtc( mode_control) & 0x40 ) - vga.config.addr_shift = 0; - else + if (IS_VGA_ARCH) { + //Byte,word,dword mode + if ( crtc(underline_location) & 0x20 ) + vga.config.addr_shift = 2; + else if ( crtc( mode_control) & 0x40 ) + vga.config.addr_shift = 0; + else + vga.config.addr_shift = 1; + } else { vga.config.addr_shift = 1; + } /* 0-4 Position of underline within Character cell. 5 If set memory address is only changed every fourth character clock. @@ -291,8 +299,8 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { vga.tandy.addr_mask = ~0; vga.tandy.line_shift = 0; } - VGA_DetermineMode(); //Should we really need to do a determinemode here? +// VGA_DetermineMode(); /* 0 If clear use CGA compatible memory addressing system by substituting character row scan counter bit 0 for address bit 13, diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index 955a6cb6..d568eec0 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -202,15 +202,29 @@ void VGA_SetupDAC(void) { vga.dac.state=DAC_READ; vga.dac.read_index=0; vga.dac.write_index=0; - if (machine==MCH_VGA) { + if (IS_VGA_ARCH) { /* Setup the DAC IO port Handlers */ IO_RegisterWriteHandler(0x3c6,write_p3c6,IO_MB); IO_RegisterReadHandler(0x3c6,read_p3c6,IO_MB); IO_RegisterWriteHandler(0x3c7,write_p3c7,IO_MB); IO_RegisterReadHandler(0x3c7,read_p3c7,IO_MB); - IO_RegisterReadHandler(0x3c8,read_p3c8,IO_MB); IO_RegisterWriteHandler(0x3c8,write_p3c8,IO_MB); + IO_RegisterReadHandler(0x3c8,read_p3c8,IO_MB); IO_RegisterWriteHandler(0x3c9,write_p3c9,IO_MB); IO_RegisterReadHandler(0x3c9,read_p3c9,IO_MB); + } else if (machine==MCH_EGA) { + for (Bitu i=0;i<64;i++) { + if ((i&4)>0) vga.dac.rgb[i].red=0x2a; + else vga.dac.rgb[i].red=0; + if ((i&32)>0) vga.dac.rgb[i].red+=0x15; + + if ((i&2)>0) vga.dac.rgb[i].green=0x2a; + else vga.dac.rgb[i].green=0; + if ((i&16)>0) vga.dac.rgb[i].green+=0x15; + + if ((i&1)>0) vga.dac.rgb[i].blue=0x2a; + else vga.dac.rgb[i].blue=0; + if ((i&8)>0) vga.dac.rgb[i].blue+=0x15; + } } }; diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 9ef5836b..c8161f78 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -531,6 +531,8 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.address = vga.config.real_start; vga.draw.address_line = vga.config.hlines_skip; vga.draw.split_line = (vga.config.line_compare/vga.draw.lines_scaled); + // go figure... +// if (machine==MCH_EGA) vga.draw.split_line = ((((vga.config.line_compare&0x5ff)+1)*2-1)/vga.draw.lines_scaled); switch (vga.mode) { case M_EGA: case M_LIN4: @@ -653,12 +655,13 @@ void VGA_SetupDrawing(Bitu val) { float fps; Bitu clock; Bitu htotal, hdend, hbstart, hbend, hrstart, hrend; Bitu vtotal, vdend, vbstart, vbend, vrstart, vrend; - if (machine==MCH_VGA) { - htotal = 5 + vga.crtc.horizontal_total; + if (IS_EGAVGA_ARCH) { + htotal = 2 + vga.crtc.horizontal_total; + if (IS_VGA_ARCH) htotal += 3; hdend = 1 + vga.crtc.horizontal_display_end; hbstart = vga.crtc.start_horizontal_blanking; - hbend = vga.crtc.end_horizontal_blanking&0x1F | - ((vga.crtc.end_horizontal_retrace&0x80)>>2); + hbend = vga.crtc.end_horizontal_blanking&0x1F; + if (IS_VGA_ARCH) hbend |= (vga.crtc.end_horizontal_retrace&0x80)>>2; hbend = hbstart + ((hbend - hbstart) & 0x3F); hrstart = vga.crtc.start_horizontal_retrace; hrend = vga.crtc.end_horizontal_retrace & 0x1f; @@ -668,15 +671,17 @@ void VGA_SetupDrawing(Bitu val) { else hrend = hrstart + hrend; - vtotal=2 + vga.crtc.vertical_total | - ((vga.crtc.overflow & 1) << 8) | ((vga.crtc.overflow & 0x20) << 4); - vdend = 1 + (vga.crtc.vertical_display_end | - ((vga.crtc.overflow & 2)<<7) | - ((vga.crtc.overflow & 0x40) << 3) | - ((vga.s3.ex_ver_overflow & 0x2) << 9)); - vrstart = vga.crtc.vertical_retrace_start + - ((vga.crtc.overflow & 0x04) << 6) | - ((vga.crtc.overflow & 0x80) << 2); + vtotal= 2 + vga.crtc.vertical_total | ((vga.crtc.overflow & 1) << 8); + vdend = 1 + vga.crtc.vertical_display_end | ((vga.crtc.overflow & 2)<<7); + vrstart = vga.crtc.vertical_retrace_start + ((vga.crtc.overflow & 0x04) << 6); + if (IS_VGA_ARCH) { + // additional bits only present on vga cards + vtotal |= (vga.crtc.overflow & 0x20) << 4; + vdend |= ((vga.crtc.overflow & 0x40) << 3) | + ((vga.s3.ex_ver_overflow & 0x2) << 9); + vrstart |= ((vga.crtc.overflow & 0x80) << 2); + } + vrend = vga.crtc.vertical_retrace_end & 0xF; vrend = ( vrend - vrstart)&0xF; if ( !vrend) @@ -684,10 +689,13 @@ void VGA_SetupDrawing(Bitu val) { else vrend = vrstart + vrend; - vbstart = vga.crtc.start_vertical_blanking | - ((vga.crtc.overflow & 0x08) << 5) | - ((vga.crtc.maximum_scan_line & 0x20) << 4); - vbend = vga.crtc.end_vertical_blanking & 0x3f; + vbstart = vga.crtc.start_vertical_blanking | ((vga.crtc.overflow & 0x08) << 5); + if (IS_VGA_ARCH) { + vbstart |= ((vga.crtc.maximum_scan_line & 0x20) << 4); + vbend = vga.crtc.end_vertical_blanking & 0x3f; + } else { + vbend = vga.crtc.end_vertical_blanking & 0xf; + } vbend = (vbend - vbstart) & 0x3f; if ( !vbend) vbend = vbstart + 0x3f + 1; @@ -720,7 +728,9 @@ void VGA_SetupDrawing(Bitu val) { vga.draw.address_line_total=(vga.crtc.maximum_scan_line&0xf)+1; /* Check for dual transfer whatever thing,master clock/2 */ if (vga.s3.pll.cmd & 0x10) clock/=2; - vga.draw.double_scan=(vga.crtc.maximum_scan_line&0x80)>0; + + if (IS_VGA_ARCH) vga.draw.double_scan=(vga.crtc.maximum_scan_line&0x80)>0; + else vga.draw.double_scan=false; // might actually be a special implementation of double scanning for ega } else { htotal = vga.other.htotal + 1; hdend = vga.other.hdend; @@ -988,7 +998,7 @@ void VGA_SetupDrawing(Bitu val) { height/=2; doubleheight=true; } - //Only check for exra double heigh in vga modes + //Only check for extra double height in vga modes if (!doubleheight && (vga.mode> 4); + Bit8u font1=(val & 0x3) << 1; + if (IS_VGA_ARCH) font1|=(val & 0x10) >> 4; vga.draw.font_tables[0]=&vga.draw.font[font1*8*1024]; - Bit8u font2=((val & 0xc) >> 1) | ((val & 0x20) >> 5); + Bit8u font2=((val & 0xc) >> 1); + if (IS_VGA_ARCH) font2|=(val & 0x20) >> 5; vga.draw.font_tables[1]=&vga.draw.font[font2*8*1024]; } /* @@ -94,10 +96,12 @@ void write_p3c5(Bitu port,Bitu val,Bitu iolen) { rather than the Map Mask and Read Map Select Registers. */ seq(memory_mode)=val; - /* Changing this means changing the VGA Memory Read/Write Handler */ - if (val&0x08) vga.config.chained=true; - else vga.config.chained=false; - VGA_SetupHandlers(); + if (IS_VGA_ARCH) { + /* Changing this means changing the VGA Memory Read/Write Handler */ + if (val&0x08) vga.config.chained=true; + else vga.config.chained=false; + VGA_SetupHandlers(); + } break; default: switch (svgaCard) { @@ -139,11 +143,13 @@ Bitu read_p3c5(Bitu port,Bitu iolen) { void VGA_SetupSEQ(void) { - if (machine==MCH_VGA) { + if (IS_EGAVGA_ARCH) { IO_RegisterWriteHandler(0x3c4,write_p3c4,IO_MB); IO_RegisterWriteHandler(0x3c5,write_p3c5,IO_MB); - IO_RegisterReadHandler(0x3c4,read_p3c4,IO_MB); - IO_RegisterReadHandler(0x3c5,read_p3c5,IO_MB); + if (IS_VGA_ARCH) { + IO_RegisterReadHandler(0x3c4,read_p3c4,IO_MB); + IO_RegisterReadHandler(0x3c5,read_p3c5,IO_MB); + } } } diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index 83b4a634..e8557970 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -1073,7 +1073,7 @@ Bitu XGA_Read(Bitu port, Bitu len) { } void VGA_SetupXGA(void) { - if (machine!=MCH_VGA) return; + if (!IS_VGA_ARCH) return; memset(&xga, 0, sizeof(XGAStatus)); @@ -1165,8 +1165,4 @@ void VGA_SetupXGA(void) { IO_RegisterWriteHandler(0xe2ea,&XGA_Write,IO_MB | IO_MW | IO_MD); IO_RegisterReadHandler(0xe2ea,&XGA_Read,IO_MB | IO_MW | IO_MD); - - - } - diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 7aa3bf92..d1c9467e 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.68 2007-06-12 20:22:08 c2woody Exp $ */ +/* $Id: bios.cpp,v 1.69 2007-09-20 16:42:43 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -705,7 +705,7 @@ static Bitu INT15_Handler(void) { LOG(LOG_BIOS,LOG_ERROR)("INT15:Unknown call %4X",reg_ax); reg_ah=0x86; CALLBACK_SCF(true); - if ((machine==MCH_VGA) || (machine==MCH_CGA)) { + if ((IS_EGAVGA_ARCH) || (machine==MCH_CGA)) { /* relict from comparisons, as int15 exits with a retf2 instead of an iret */ CALLBACK_SZF(false); } @@ -917,7 +917,7 @@ public: //Startup monochrome config|=0x30; break; - case MCH_VGA: + case EGAVGA_ARCH_CASE: case MCH_CGA: case TANDY_ARCH_CASE: //Startup 80x25 color diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index ea495db0..90b13178 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -140,7 +140,9 @@ static Bitu INT10_Handler(void) { reg_al=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)|(real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL)&0x80); reg_ah=(Bit8u)real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); break; - case 0x10: /* EGA/VGA Palette functions */ + case 0x10: /* Palette functions */ + if ((machine==MCH_CGA) || ((!IS_VGA_ARCH) && (reg_al>0x02))) break; + //TODO: subfunction 0x03 for ega switch (reg_al) { case 0x00: /* SET SINGLE PALETTE REGISTER */ INT10_SetSinglePaletteRegister(reg_bl,reg_bh); @@ -195,7 +197,7 @@ static Bitu INT10_Handler(void) { } break; case 0x11: /* Character generator functions */ - if (machine7) return; mem_address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); /* Write the new page start */ real_writew(BIOSMEM_SEG,BIOSMEM_CURRENT_START,mem_address); - if (machine==MCH_VGA && CurMode->mode<0x8) mem_address>>=1; + if (IS_EGAVGA_ARCH && CurMode->mode<0x8) mem_address>>=1; /* Write the new start address in vgahardware */ Bit16u base=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); IO_Write(base,0x0c); @@ -522,7 +521,7 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) { if (CurMode->type!=M_TEXT) { switch (machine) { - case MCH_VGA: + case EGAVGA_ARCH_CASE: page%=CurMode->ptotal; break; case MCH_CGA: diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 2fd73d0e..4779f9af 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -78,14 +78,16 @@ void INT10_SetupRomMemory(void) { PhysPt rom_base=PhysMake(0xc000,0); Bitu i; int10.rom.used=3; - if (machine==MCH_VGA) { + if (IS_EGAVGA_ARCH) { // set up the start of the ROM phys_writew(rom_base+0,0xaa55); phys_writeb(rom_base+2,0x40); // Size of ROM: 64 512-blocks = 32KB - phys_writeb(rom_base+0x1e,0x49); // IBM string - phys_writeb(rom_base+0x1f,0x42); - phys_writeb(rom_base+0x20,0x4d); - phys_writeb(rom_base+0x21,0x00); + if (IS_VGA_ARCH) { + phys_writeb(rom_base+0x1e,0x49); // IBM string + phys_writeb(rom_base+0x1f,0x42); + phys_writeb(rom_base+0x20,0x4d); + phys_writeb(rom_base+0x21,0x00); + } int10.rom.used=0x100; } int10.rom.font_8_first=RealMake(0xC000,int10.rom.used); @@ -116,7 +118,7 @@ void INT10_SetupRomMemory(void) { if (IS_TANDY_ARCH) { RealSetVec(0x44,int10.rom.font_8_first); } - if (machine == MCH_VGA) { //EGA/VGA. Just to be safe + if (IS_EGAVGA_ARCH) { //EGA/VGA. Just to be safe //Reserve checksum location checksumlocation = int10.rom.used++; } @@ -145,7 +147,7 @@ void INT10_ReloadRomFonts(void) { } void INT10_SetupRomMemoryChecksum(void) { - if (machine == MCH_VGA) { //EGA/VGA. Just to be safe + if (IS_EGAVGA_ARCH) { //EGA/VGA. Just to be safe /* Sum of all bytes in rom module 256 should be 0 */ Bit8u sum = 0; PhysPt rom_base = PhysMake(0xc000,0); diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index c58e0697..0f405232 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -272,7 +272,7 @@ static void FinishSetMode(bool clearmem) { real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); // FIXME We nearly have the good tables. to be reworked - if (machine==MCH_VGA) real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08); // 8 is VGA should be ok for now + if (IS_VGA_ARCH) real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08); // 8 is VGA should be ok for now real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER,0x00); real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2,0x00); @@ -468,7 +468,11 @@ bool INT10_SetVideoMode(Bitu mode) { mode-=0x80; } LOG(LOG_INT10,LOG_NORMAL)("Set Video Mode %X",mode); - if (machine!=MCH_VGA) return INT10_SetVideoMode_OTHER(mode,clearmem); + if (!IS_EGAVGA_ARCH) return INT10_SetVideoMode_OTHER(mode,clearmem); + if ((machine==MCH_EGA) && (mode>0x10)) { + LOG(LOG_INT10,LOG_ERROR)("EGA:Trying to set illegal mode %X",mode); + return false; + } Bit8u modeset_ctl,video_ctl,vga_switches; if (!SetCurMode(ModeList_VGA,mode)){ @@ -643,7 +647,10 @@ bool INT10_SetVideoMode(Bitu mode) { ver_overflow|=(line_compare & 0x400) >> 4; Bit8u underline=0; /* Maximum scanline / Underline Location */ - if (CurMode->special & _EGA_LINE_DOUBLE) max_scanline|=0x80; + if (CurMode->special & _EGA_LINE_DOUBLE) { + if (machine==MCH_EGA) max_scanline=1; + else max_scanline|=0x80; + } switch (CurMode->type) { case M_TEXT: max_scanline|=CurMode->cheight-1; @@ -661,7 +668,8 @@ bool INT10_SetVideoMode(Bitu mode) { break; case M_CGA2: case M_CGA4: - max_scanline|=1; + if (machine==MCH_EGA) max_scanline|=2; + else max_scanline|=1; break; } if (CurMode->vdispend==350) underline=0x0f; @@ -819,13 +827,23 @@ bool INT10_SetVideoMode(Bitu mode) { for (i=1;i<16;i++) att_data[i]=0x3f; break; case 0x10: - case 0x12: goto att_text16; + case 0x12: + if (IS_VGA_ARCH) + goto att_text16; + // ega fallthrough default: if ( CurMode->type == M_LIN4 ) goto att_text16; - for (i=0;i<8;i++) { - att_data[i]=i; - att_data[i+8]=i+0x10; + if (!IS_VGA_ARCH) { + for (i=0;i<8;i++) { + att_data[i]=i; + att_data[i+8]=i+0x38; + } + } else { + for (i=0;i<8;i++) { + att_data[i]=i; + att_data[i+8]=i+0x10; + } } break; } @@ -929,7 +947,7 @@ dac_text16: } break; } - if (machine==MCH_VGA) { + if (IS_VGA_ARCH) { /* check if gray scale summing is enabled */ if (real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL) & 2) { INT10_PerformGrayScaleSumming(0,256); diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 810343cb..c017e79d 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -39,7 +39,8 @@ void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val) { IO_Read(VGAREG_TDY_RESET); WriteTandyACTL(reg+0x10,val); break; - case MCH_VGA: + case EGAVGA_ARCH_CASE: + if (!IS_VGA_ARCH) reg&=0x1f; if(reg<=ACTL_MAX_REG) { ResetACTL(); IO_Write(VGAREG_ACTL_ADDRESS,reg); @@ -70,7 +71,7 @@ void INT10_SetAllPaletteRegisters(PhysPt data) { // Then the border WriteTandyACTL(0x02,mem_readb(data)); break; - case MCH_VGA: + case EGAVGA_ARCH_CASE: ResetACTL(); // First the colors for(Bit8u i=0;i<0x10;i++) { @@ -215,7 +216,7 @@ void INT10_SetBackgroundBorder(Bit8u val) { real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp); if (machine == MCH_CGA || IS_TANDY_ARCH) IO_Write(0x3d9,temp); - else if (machine == MCH_VGA) { + else if (IS_EGAVGA_ARCH) { val = ((val << 1) & 0x10) | (val & 0x7); /* Aways set the overscan color */ INT10_SetSinglePaletteRegister( 0x11, val ); @@ -238,7 +239,7 @@ void INT10_SetColorSelect(Bit8u val) { real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp); if (machine == MCH_CGA || IS_TANDY_ARCH) IO_Write(0x3d9,temp); - else if (machine == MCH_VGA) { + else if (IS_EGAVGA_ARCH) { if (CurMode->mode <= 3) //Maybe even skip the total function! return; val = (temp & 0x10) | 2 | val; From 9b7ea9c03f83e84dc848aade22d425f86f28bead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 21 Sep 2007 15:34:13 +0000 Subject: [PATCH 2905/4131] fix line split check (thanks to ripsaw8080; fixes graphical bugs in Event Horizon games) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2993 --- src/hardware/vga_draw.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index c8161f78..6716a82d 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -443,8 +443,8 @@ static void VGA_DrawPart(Bitu lines) { vga.draw.address_line=0; vga.draw.address+=vga.draw.address_add; } - vga.draw.lines_done++; - if (vga.draw.split_line==vga.draw.lines_done) { +// vga.draw.lines_done++; + if (vga.draw.split_line==vga.draw.lines_done++) { #ifdef VGA_KEEP_CHANGES VGA_ChangesEnd( ); #endif From 208edab1acd1df630f0ff656ea99a07d40451335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 22 Sep 2007 17:01:17 +0000 Subject: [PATCH 2906/4131] fix vesa mode tables (4bpp mode plane amount; 15bpp mode reserved mask) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2994 --- src/ints/int10_vesa.cpp | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index b2bde54a..20a98344 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.27 2007-06-12 20:22:09 c2woody Exp $ */ +/* $Id: int10_vesa.cpp,v 1.28 2007-09-22 17:01:17 c2woody Exp $ */ #include #include @@ -126,7 +126,7 @@ Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off) { Bitu pageSize; Bitu i=0; - if (mode<0x100) return 0x01; + if ((mode&0x7fff)<0x100) return 0x01; mode&=0xfff; while (ModeList_VGA[i].mode!=0xffff) { if (mode==ModeList_VGA[i].mode) goto foundit; else i++; @@ -140,6 +140,7 @@ foundit: pageSize = (pageSize | 15) & ~ 15; var_write(&minfo.NumberOfImagePages,(512*1024 / pageSize)-1); var_write(&minfo.BytesPerScanLine,mblock->swidth/8); + var_write(&minfo.NumberOfPlanes,0x4); var_write(&minfo.BitsPerPixel,4); var_write(&minfo.MemoryModel,3); //ega planar mode var_write(&minfo.ModeAttributes,0x1b); //Color, graphics, no linear buffer @@ -149,6 +150,7 @@ foundit: pageSize = (pageSize | 15) & ~ 15; var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); var_write(&minfo.BytesPerScanLine,mblock->swidth); + var_write(&minfo.NumberOfPlanes,0x1); var_write(&minfo.BitsPerPixel,8); var_write(&minfo.MemoryModel,4); //packed pixel var_write(&minfo.ModeAttributes,0x9b); //Color, graphics, linear buffer @@ -158,6 +160,7 @@ foundit: pageSize = (pageSize | 15) & ~ 15; var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); var_write(&minfo.BytesPerScanLine,mblock->swidth*2); + var_write(&minfo.NumberOfPlanes,0x1); var_write(&minfo.BitsPerPixel,15); var_write(&minfo.MemoryModel,6); //HiColour var_write(&minfo.RedMaskSize,5); @@ -166,6 +169,8 @@ foundit: var_write(&minfo.GreenMaskPos,5); var_write(&minfo.BlueMaskSize,5); var_write(&minfo.BlueMaskPos,0); + var_write(&minfo.ReservedMaskSize,0x01); + var_write(&minfo.ReservedMaskPos,0x0f); var_write(&minfo.ModeAttributes,0x9b); //Color, graphics, linear buffer break; case M_LIN16: @@ -173,6 +178,7 @@ foundit: pageSize = (pageSize | 15) & ~ 15; var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); var_write(&minfo.BytesPerScanLine,mblock->swidth*2); + var_write(&minfo.NumberOfPlanes,0x1); var_write(&minfo.BitsPerPixel,16); var_write(&minfo.MemoryModel,6); //HiColour var_write(&minfo.RedMaskSize,5); @@ -188,6 +194,7 @@ foundit: pageSize = (pageSize | 15) & ~ 15; var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); var_write(&minfo.BytesPerScanLine,mblock->swidth*4); + var_write(&minfo.NumberOfPlanes,0x1); var_write(&minfo.BitsPerPixel,32); var_write(&minfo.MemoryModel,6); //HiColour var_write(&minfo.RedMaskSize,8); @@ -200,19 +207,36 @@ foundit: var_write(&minfo.ReservedMaskPos,0x18); var_write(&minfo.ModeAttributes,0x9b); //Color, graphics, linear buffer break; +/* case M_TEXT: + pageSize = mblock->sheight/8 * mblock->swidth*2/8; + pageSize = (pageSize | 15) & ~ 15; + var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); + var_write(&minfo.BytesPerScanLine,mblock->swidth*2/8); + var_write(&minfo.NumberOfPlanes,0x4); + var_write(&minfo.BitsPerPixel,4); + var_write(&minfo.MemoryModel,0); //Text + var_write(&minfo.ModeAttributes,0x0f); //Color, text, bios output + break; */ default: return 0x1; } var_write(&minfo.WinAAttributes,0x7); //Exists/readable/writable - var_write(&minfo.WinGranularity,64); - var_write(&minfo.WinSize,64); - var_write(&minfo.WinASegment,0xa000); + if (mblock->type==M_TEXT) { + var_write(&minfo.WinGranularity,32); + var_write(&minfo.WinSize,32); + var_write(&minfo.WinASegment,0xb800); + var_write(&minfo.XResolution,mblock->swidth/8); + var_write(&minfo.YResolution,mblock->sheight/8); + } else { + var_write(&minfo.WinGranularity,64); + var_write(&minfo.WinSize,64); + var_write(&minfo.WinASegment,0xa000); + var_write(&minfo.XResolution,mblock->swidth); + var_write(&minfo.YResolution,mblock->sheight); + } var_write(&minfo.WinFuncPtr,CALLBACK_RealPointer(callback.setwindow)); - var_write(&minfo.NumberOfPlanes,0x1); var_write(&minfo.NumberOfBanks,0x1); var_write(&minfo.Reserved_page,0x1); - var_write(&minfo.XResolution,mblock->swidth); - var_write(&minfo.YResolution,mblock->sheight); var_write(&minfo.XCharSize,mblock->cwidth); var_write(&minfo.YCharSize,mblock->cheight); var_write(&minfo.PhysBasePtr,S3_LFB_BASE); From d64648208aea2fff172c0dd0f922a18cc7ac81a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 24 Sep 2007 20:50:40 +0000 Subject: [PATCH 2907/4131] tweak some vga bios functions to better stick to real implementations Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2995 --- include/dosbox.h | 3 +- src/dosbox.cpp | 11 +++++-- src/hardware/vga_gfx.cpp | 5 ++- src/ints/int10.cpp | 70 +++++++++++++++++++++++++++++++--------- src/ints/int10_char.cpp | 9 +++--- src/ints/int10_pal.cpp | 31 ++++++++++++++---- src/ints/int10_vesa.cpp | 6 ++-- 7 files changed, 101 insertions(+), 34 deletions(-) diff --git a/include/dosbox.h b/include/dosbox.h index efe7a50b..19bde530 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -50,7 +50,8 @@ enum MachineType { enum SVGACards { SVGA_None, - SVGA_S3Trio + SVGA_S3Trio, + SVGA_TsengET4K }; extern SVGACards svgaCard; diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 3e831398..5be71d77 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.122 2007-09-20 16:42:43 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.123 2007-09-24 20:50:40 c2woody Exp $ */ #include #include @@ -265,9 +265,16 @@ static void DOSBOX_RealInit(Section * sec) { else if (strcasecmp(mtype,"pcjr")==0) machine=MCH_PCJR; else if (strcasecmp(mtype,"hercules")==0) machine=MCH_HERC; else if (strcasecmp(mtype,"ega")==0) machine=MCH_EGA; - else if (strcasecmp(mtype,"vga")==0) { + else if ((strcasecmp(mtype,"vga")==0) || (strcasecmp(mtype,"vga_s3")==0) || + (strcasecmp(mtype,"svga")==0) || (strcasecmp(mtype,"svga_s3")==0)) { machine=MCH_VGA; svgaCard=SVGA_S3Trio; +/* } else if ((strcasecmp(mtype,"vga_et4000")==0) || (strcasecmp(mtype,"svga_et4000")==0)) { + machine=MCH_VGA; + svgaCard=SVGA_TsengET4K; */ + } else if (strcasecmp(mtype,"vgaonly")==0) { + machine=MCH_VGA; + svgaCard=SVGA_None; } else LOG_MSG("DOSBOX:Unknown machine type %s",mtype); } diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index 7d789ef8..81d61f56 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -139,7 +139,10 @@ static void write_p3cf(Bitu port,Bitu val,Bitu iolen) { */ break; case 6: /* Miscellaneous Register */ - gfx(miscellaneous)=val; + if ((gfx(miscellaneous) ^ val) & 0x0c) { + gfx(miscellaneous)=val; + VGA_DetermineMode(); + } else gfx(miscellaneous)=val; VGA_SetupHandlers(); /* 0 Indicates Graphics Mode if set, Alphanumeric mode else. diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 90b13178..33f4dd39 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -58,17 +58,17 @@ static Bitu INT10_Handler(void) { INT10_SetCursorPos(reg_dh,reg_dl,reg_bh); break; case 0x03: /* get Cursor Pos and Cursor Shape*/ - reg_ah=0; +// reg_ah=0; reg_dl=CURSOR_POS_COL(reg_bh); reg_dh=CURSOR_POS_ROW(reg_bh); reg_cx=real_readw(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE); break; case 0x04: /* read light pen pos YEAH RIGHT */ /* Light pen is not supported */ - reg_ah=0; + reg_ax=0; break; case 0x05: /* Set Active Page */ - if (reg_al & 0x80 && IS_TANDY_ARCH) { + if ((reg_al & 0x80) && IS_TANDY_ARCH) { Bit8u crtcpu=real_readb(BIOSMEM_SEG, BIOSMEM_CRTCPU_PAGE); switch (reg_al) { case 0x80: @@ -116,13 +116,8 @@ static Bitu INT10_Handler(void) { INT10_SetBackgroundBorder(reg_bl); break; case 0x01: //Set color Select - INT10_SetColorSelect(reg_bl); - break; default: - if ((machine==MCH_CGA) || (machine==MCH_PCJR)) { - /* those BIOSes check for !=0 */ - INT10_SetColorSelect(reg_bl); - } + INT10_SetColorSelect(reg_bl); break; } break; @@ -185,6 +180,7 @@ static Bitu INT10_Handler(void) { break; case 0x19: /* undocumented - GET PEL MASK */ INT10_GetPelMask(reg_bl); + reg_bh=0; // bx for get mask break; case 0x1A: /* GET VIDEO DAC COLOR PAGE */ INT10_GetDACPage(®_bl,®_bh); @@ -192,8 +188,12 @@ static Bitu INT10_Handler(void) { case 0x1B: /* PERFORM GRAY-SCALE SUMMING */ INT10_PerformGrayScaleSumming(reg_bx,reg_cx); break; + case 0xF0: /* ET4000: SET HiColor GRAPHICS MODE */ + case 0xF1: /* ET4000: GET DAC TYPE */ + case 0xF2: /* ET4000: CHECK/SET HiColor MODE */ default: LOG(LOG_INT10,LOG_ERROR)("Function 10:Unhandled EGA/VGA Palette Function %2X",reg_al); + break; } break; case 0x11: /* Character generator functions */ @@ -287,12 +287,21 @@ graphics_chars: break; default: LOG(LOG_INT10,LOG_ERROR)("Function 11:30 Request for font %2X",reg_bh); + break; + } + if ((reg_bh<=7) || (svgaCard==SVGA_TsengET4K)) { + if (machine==MCH_EGA) { + reg_cx=0x0e; + reg_dl=0x18; + } else { + reg_cx=real_readw(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); + reg_dl=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS); + } } - reg_cx=real_readw(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); - reg_dl=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS); break; default: LOG(LOG_INT10,LOG_ERROR)("Function 11:Unsupported character generator call %2X",reg_al); + break; } break; case 0x12: /* alternate function select */ @@ -302,18 +311,25 @@ graphics_chars: case 0x10: /* Get EGA Information */ reg_bh=(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)==0x3B4); reg_bl=3; //256 kb - reg_cx=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES) & 0x0F; + reg_cl=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES) & 0x0F; + reg_ch=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES) >> 4; break; case 0x20: /* Set alternate printscreen */ break; case 0x30: /* Select vertical resolution */ if (!IS_VGA_ARCH) break; LOG(LOG_INT10,LOG_ERROR)("Function 12:Call %2X not handled",reg_bl); - reg_al=0x12; //fake a success call + if (reg_al>2) reg_al=0; //invalid subfunction + else reg_al=0x12; //fake a success call break; case 0x31: /* Palette loading on modeset */ { if (!IS_VGA_ARCH) break; + if (svgaCard==SVGA_TsengET4K) reg_al&=1; + if (reg_al>1) { + reg_al=0; //invalid subfunction + break; + } Bit8u temp = real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL) & 0xf7; if (reg_al&1) temp|=8; // enable if al=0 real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,temp); @@ -323,11 +339,18 @@ graphics_chars: case 0x32: /* Video adressing */ if (!IS_VGA_ARCH) break; LOG(LOG_INT10,LOG_ERROR)("Function 12:Call %2X not handled",reg_bl); - reg_al=0x12; //fake a success call + if (svgaCard==SVGA_TsengET4K) reg_al&=1; + if (reg_al>1) reg_al=0; //invalid subfunction + else reg_al=0x12; //fake a success call break; case 0x33: /* SWITCH GRAY-SCALE SUMMING */ { if (!IS_VGA_ARCH) break; + if (svgaCard==SVGA_TsengET4K) reg_al&=1; + if (reg_al>1) { + reg_al=0; + break; + } Bit8u temp = real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL) & 0xfd; if (!(reg_al&1)) temp|=2; // enable if al=0 real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,temp); @@ -338,6 +361,11 @@ graphics_chars: { // bit 0: 0=enable, 1=disable if (!IS_VGA_ARCH) break; + if (svgaCard==SVGA_TsengET4K) reg_al&=1; + if (reg_al>1) { + reg_al=0; + break; + } Bit8u temp = real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL) & 0xfe; real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,temp|reg_al); reg_al=0x12; @@ -350,6 +378,10 @@ graphics_chars: break; case 0x36: /* VGA Refresh control */ if (!IS_VGA_ARCH) break; + if ((svgaCard==SVGA_S3Trio) && (reg_al>1)) { + reg_al=0; + break; + } /* Call disables/enables the vga from outputting video, don't support it, but fake a success return @@ -358,7 +390,7 @@ graphics_chars: break; default: LOG(LOG_INT10,LOG_ERROR)("Function 12:Call %2X not handled",reg_bl); - reg_al=0x12; // wrong!? + if (machine!=MCH_EGA) reg_al=0; break; } break; @@ -387,6 +419,8 @@ graphics_chars: break; default: LOG(LOG_INT10,LOG_ERROR)("1B:Unhandled call BX %2X",reg_bx); + reg_al=0; + break; } break; case 0x1C: /* Video Save Area */ @@ -438,12 +472,13 @@ graphics_chars: break; case 0x01: reg_al=0x4f; - reg_bh=0x00; //Weird? + reg_bh=0x00; //reserved reg_ah=VESA_GetDisplayStart(reg_cx,reg_dx); break; default: LOG(LOG_INT10,LOG_ERROR)("Unhandled VESA Function %X Subfunction %X",reg_al,reg_bl); reg_ah=0x1; + break; } break; case 0x09: @@ -461,6 +496,7 @@ graphics_chars: default: LOG(LOG_INT10,LOG_ERROR)("Unhandled VESA Function %X Subfunction %X",reg_al,reg_bl); reg_ah=0x01; + break; } break; case 0x0a: /* Get Pmode Interface */ @@ -498,6 +534,7 @@ graphics_chars: default: LOG(LOG_INT10,LOG_ERROR)("Unhandled VESA Function %X",reg_al); reg_al=0x0; + break; } break; case 0xf0: @@ -531,6 +568,7 @@ graphics_chars: default: LOG(LOG_INT10,LOG_ERROR)("Function %2X not supported",reg_ah); reg_al=0x00; //Successfull + break; }; return CBRET_NONE; } diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index d0695a15..b244b278 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.51 2007-09-20 16:42:43 c2woody Exp $ */ +/* $Id: int10_char.cpp,v 1.52 2007-09-24 20:50:40 c2woody Exp $ */ /* Character displaying moving functions */ @@ -273,7 +273,7 @@ filling: void INT10_SetActivePage(Bit8u page) { Bit16u mem_address; - if (page>7) return; + if (page>7) E_Exit("INT10_SetActivePage page %d",page); mem_address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); /* Write the new page start */ real_writew(BIOSMEM_SEG,BIOSMEM_CURRENT_START,mem_address); @@ -348,7 +348,7 @@ dowrite: void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page) { Bit16u address; - if(page>7) return; + if (page>7) E_Exit("INT10_SetCursorPos page %d"); // Bios cursor pos real_writeb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2,col); real_writeb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2+1,row); @@ -358,7 +358,8 @@ void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page) { // Get the dimensions BIOS_NCOLS; // Calculate the address knowing nbcols nbrows and page num - address=(ncols*row)+col+real_readw(BIOSMEM_SEG,BIOSMEM_CURRENT_START); + // NOTE: BIOSMEM_CURRENT_START counts in colour/flag pairs + address=(ncols*row)+col+real_readw(BIOSMEM_SEG,BIOSMEM_CURRENT_START)/2; // CRTC regs 0x0e and 0x0f Bit16u base=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); IO_Write(base,0x0e); diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index c017e79d..8003edf3 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -53,10 +53,18 @@ void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val) { void INT10_SetOverscanBorderColor(Bit8u val) { - ResetACTL(); - IO_Write(VGAREG_ACTL_ADDRESS,0x11); - IO_Write(VGAREG_ACTL_WRITE_DATA,val); - IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette + switch (machine) { + case TANDY_ARCH_CASE: + IO_Read(VGAREG_TDY_RESET); + WriteTandyACTL(0x02,val); + break; + case EGAVGA_ARCH_CASE: + ResetACTL(); + IO_Write(VGAREG_ACTL_ADDRESS,0x11); + IO_Write(VGAREG_ACTL_WRITE_DATA,val); + IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette + break; + } } void INT10_SetAllPaletteRegisters(PhysPt data) { @@ -89,18 +97,27 @@ void INT10_SetAllPaletteRegisters(PhysPt data) { void INT10_ToggleBlinkingBit(Bit8u state) { Bit8u value; - state&=0x01; +// state&=0x01; + if ((state>1) && (svgaCard==SVGA_S3Trio)) return; ResetACTL(); IO_Write(VGAREG_ACTL_ADDRESS,0x10); value=IO_Read(VGAREG_ACTL_READ_DATA); - value&=0xf7; - value|=state<<3; + if (state<=1) { + value&=0xf7; + value|=state<<3; + } ResetACTL(); IO_Write(VGAREG_ACTL_ADDRESS,0x10); IO_Write(VGAREG_ACTL_WRITE_DATA,value); IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette + + if (state<=1) { + Bit8u msrval=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR)&0xdf; + if (state) msrval|=0x20; + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,msrval); + } } void INT10_GetSinglePaletteRegister(Bit8u reg,Bit8u * val) { diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 20a98344..b66a0d2b 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.28 2007-09-22 17:01:17 c2woody Exp $ */ +/* $Id: int10_vesa.cpp,v 1.29 2007-09-24 20:50:40 c2woody Exp $ */ #include #include @@ -126,8 +126,8 @@ Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off) { Bitu pageSize; Bitu i=0; - if ((mode&0x7fff)<0x100) return 0x01; - mode&=0xfff; + mode&=0x3fff; // vbe2 compatible, ignore lfb and keep screen content bits + if (mode<0x100) return 0x01; while (ModeList_VGA[i].mode!=0xffff) { if (mode==ModeList_VGA[i].mode) goto foundit; else i++; } From 9c45a245e8bde30ea7935a236464d8e0b49ca3d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 25 Sep 2007 17:46:18 +0000 Subject: [PATCH 2908/4131] add video state functionality Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2996 --- src/ints/Makefile.am | 4 +- src/ints/int10.cpp | 50 ++++- src/ints/int10.h | 5 + src/ints/int10_video_state.cpp | 382 +++++++++++++++++++++++++++++++++ visualc_net/dosbox.vcproj | 3 + 5 files changed, 439 insertions(+), 5 deletions(-) create mode 100644 src/ints/int10_video_state.cpp diff --git a/src/ints/Makefile.am b/src/ints/Makefile.am index 7330a855..6b6621df 100644 --- a/src/ints/Makefile.am +++ b/src/ints/Makefile.am @@ -3,5 +3,5 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libints.a libints_a_SOURCES = mouse.cpp xms.cpp xms.h ems.cpp \ int10.cpp int10.h int10_char.cpp int10_memory.cpp int10_misc.cpp int10_modes.cpp \ - int10_vesa.cpp int10_pal.cpp int10_put_pixel.cpp \ - bios.cpp bios_disk.cpp bios_keyboard.cpp + int10_vesa.cpp int10_pal.cpp int10_put_pixel.cpp int10_video_state.cpp \ + bios.cpp bios_disk.cpp bios_keyboard.cpp diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 33f4dd39..5d653dba 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -424,9 +424,29 @@ graphics_chars: } break; case 0x1C: /* Video Save Area */ - if (IS_VGA_ARCH) break; - if (reg_al==0) reg_bx = 0; - reg_al = 0x1C; + if (!IS_VGA_ARCH) break; + switch (reg_al) { + case 0: { + Bitu ret=INT10_VideoState_GetSize(reg_cx); + if (ret) { + reg_al=0x1c; + reg_bx=ret; + } else reg_al=0; + } + break; + case 1: + if (INT10_VideoState_Save(reg_cx,RealMake(SegValue(es),reg_bx))) reg_al=0x1c; + else reg_al=0; + break; + case 2: + if (INT10_VideoState_Restore(reg_cx,RealMake(SegValue(es),reg_bx))) reg_al=0x1c; + else reg_al=0; + break; + default: + if (svgaCard==SVGA_TsengET4K) reg_ax=0; + else reg_al=0; + break; + } break; case 0x4f: /* VESA Calls */ if ((!IS_VGA_ARCH) || (svgaCard==SVGA_None)) break; @@ -447,6 +467,30 @@ graphics_chars: reg_al=0x4f; reg_ah=VESA_GetSVGAMode(reg_bx); break; + case 0x04: /* Save/restore state */ + reg_al=0x4f; + switch (reg_dl) { + case 0: { + Bitu ret=INT10_VideoState_GetSize(reg_cx); + if (ret) { + reg_ah=0; + reg_bx=ret; + } else reg_ah=1; + } + break; + case 1: + if (INT10_VideoState_Save(reg_cx,RealMake(SegValue(es),reg_bx))) reg_ah=0; + else reg_ah=1; + break; + case 2: + if (INT10_VideoState_Restore(reg_cx,RealMake(SegValue(es),reg_bx))) reg_ah=0; + else reg_ah=1; + break; + default: + reg_ah=1; + break; + } + break; case 0x05: if (reg_bh==0) { /* Set CPU Window */ reg_ah=VESA_SetCPUWindow(reg_bl,reg_dl); diff --git a/src/ints/int10.h b/src/ints/int10.h index 7c9671d3..ab461176 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -212,3 +212,8 @@ void INT10_EGA_RIL_ReadRegisterRange(Bit8u & bl, Bit8u ch, Bit8u cl, Bit16u dx, void INT10_EGA_RIL_WriteRegisterRange(Bit8u & bl, Bit8u ch, Bit8u cl, Bit16u dx, PhysPt dst); void INT10_EGA_RIL_ReadRegisterSet(Bit16u cx, PhysPt tbl); void INT10_EGA_RIL_WriteRegisterSet(Bit16u cx, PhysPt tbl); + +/* Video State */ +Bitu INT10_VideoState_GetSize(Bitu state); +bool INT10_VideoState_Save(Bitu state,RealPt buffer); +bool INT10_VideoState_Restore(Bitu state,RealPt buffer); diff --git a/src/ints/int10_video_state.cpp b/src/ints/int10_video_state.cpp new file mode 100644 index 00000000..0d83a902 --- /dev/null +++ b/src/ints/int10_video_state.cpp @@ -0,0 +1,382 @@ +/* + * 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: */ + +#include "dosbox.h" +#include "mem.h" +#include "inout.h" +#include "int10.h" + +Bitu INT10_VideoState_GetSize(Bitu state) { + // state: bit0=hardware, bit1=bios data, bit2=color regs/dac state + if ((state&7)==0) return 0; + + Bitu size=0x20; + if (state&1) size+=0x46; + if (state&2) size+=0x3a; + if (state&4) size+=0x303; + if ((svgaCard==SVGA_S3Trio) && (state&8)) size+=0x43; + if (size!=0) size=(size-1)/64+1; + return size; +} + +bool INT10_VideoState_Save(Bitu state,RealPt buffer) { + Bitu ct; + if ((state&7)==0) return false; + + Bitu base_seg=RealSeg(buffer); + Bitu base_dest=RealOff(buffer)+0x20; + + if (state&1) { + real_writew(base_seg,RealOff(buffer),base_dest); + + Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + real_writew(base_seg,base_dest+0x40,crt_reg); + + real_writeb(base_seg,base_dest+0x00,IO_ReadB(0x3c4)); + real_writeb(base_seg,base_dest+0x01,IO_ReadB(0x3d4)); + real_writeb(base_seg,base_dest+0x02,IO_ReadB(0x3ce)); + IO_ReadB(crt_reg+6); + real_writeb(base_seg,base_dest+0x03,IO_ReadB(0x3c0)); + real_writeb(base_seg,base_dest+0x04,IO_ReadB(0x3ca)); + + // sequencer + for (ct=1; ct<5; ct++) { + IO_WriteB(0x3c4,ct); + real_writeb(base_seg,base_dest+0x04+ct,IO_ReadB(0x3c5)); + } + + real_writeb(base_seg,base_dest+0x09,IO_ReadB(0x3cc)); + + // crt controller + for (ct=0; ct<0x19; ct++) { + IO_WriteB(crt_reg,ct); + real_writeb(base_seg,base_dest+0x0a+ct,IO_ReadB(crt_reg+1)); + } + + // attr registers + for (ct=0; ct<4; ct++) { + IO_ReadB(crt_reg+6); + IO_WriteB(0x3c0,0x10+ct); + real_writeb(base_seg,base_dest+0x33+ct,IO_ReadB(0x3c1)); + } + + // graphics registers + for (ct=0; ct<9; ct++) { + IO_WriteB(0x3ce,ct); + real_writeb(base_seg,base_dest+0x37+ct,IO_ReadB(0x3cf)); + } + + // save some registers + IO_WriteB(0x3c4,2); + Bit8u crtc_2=IO_ReadB(0x3c5); + IO_WriteB(0x3c4,4); + Bit8u crtc_4=IO_ReadB(0x3c5); + IO_WriteB(0x3ce,6); + Bit8u gfx_6=IO_ReadB(0x3cf); + IO_WriteB(0x3ce,5); + Bit8u gfx_5=IO_ReadB(0x3cf); + IO_WriteB(0x3ce,4); + Bit8u gfx_4=IO_ReadB(0x3cf); + + // reprogram for full access to plane latches + IO_WriteW(0x3c4,0x0f02); + IO_WriteW(0x3c4,0x0704); + IO_WriteW(0x3ce,0x0406); + IO_WriteW(0x3ce,0x0105); + mem_writeb(0xaffff,0); + + for (ct=0; ct<4; ct++) { + IO_WriteW(0x3ce,0x0004+ct*0x100); + real_writeb(base_seg,base_dest+0x42+ct,mem_readb(0xaffff)); + } + + // restore registers + IO_WriteW(0x3ce,0x0004|(gfx_4<<8)); + IO_WriteW(0x3ce,0x0005|(gfx_5<<8)); + IO_WriteW(0x3ce,0x0006|(gfx_6<<8)); + IO_WriteW(0x3c4,0x0004|(crtc_4<<8)); + IO_WriteW(0x3c4,0x0002|(crtc_2<<8)); + + for (ct=0; ct<0x10; ct++) { + IO_ReadB(crt_reg+6); + IO_WriteB(0x3c0,ct); + real_writeb(base_seg,base_dest+0x23+ct,IO_ReadB(0x3c1)); + } + IO_WriteB(0x3c0,0x20); + + base_dest+=0x46; + } + + if (state&2) { + real_writew(base_seg,RealOff(buffer)+2,base_dest); + + real_writeb(base_seg,base_dest+0x00,mem_readb(0x410)&0x30); + for (ct=0; ct<0x1e; ct++) { + real_writeb(base_seg,base_dest+0x01+ct,mem_readb(0x449+ct)); + } + for (ct=0; ct<0x07; ct++) { + real_writeb(base_seg,base_dest+0x1f+ct,mem_readb(0x484+ct)); + } + real_writed(base_seg,base_dest+0x26,mem_readd(0x48a)); + real_writed(base_seg,base_dest+0x2a,mem_readd(0x14)); // int 5 + real_writed(base_seg,base_dest+0x2e,mem_readd(0x74)); // int 1d + real_writed(base_seg,base_dest+0x32,mem_readd(0x7c)); // int 1f + real_writed(base_seg,base_dest+0x36,mem_readd(0x10c)); // int 43 + + base_dest+=0x3a; + } + + if (state&4) { + real_writew(base_seg,RealOff(buffer)+4,base_dest); + + Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + + IO_ReadB(crt_reg+6); + IO_WriteB(0x3c0,0x14); + real_writeb(base_seg,base_dest+0x303,IO_ReadB(0x3c1)); + + Bitu dac_state=IO_ReadB(0x3c7)&1; + Bitu dac_windex=IO_ReadB(0x3c8); + if (dac_state!=0) dac_windex--; + real_writeb(base_seg,base_dest+0x000,dac_state); + real_writeb(base_seg,base_dest+0x001,dac_windex); + real_writeb(base_seg,base_dest+0x002,IO_ReadB(0x3c6)); + + for (ct=0; ct<0x100; ct++) { + IO_WriteB(0x3c7,ct); + real_writeb(base_seg,base_dest+0x003+ct*3+0,IO_ReadB(0x3c9)); + real_writeb(base_seg,base_dest+0x003+ct*3+1,IO_ReadB(0x3c9)); + real_writeb(base_seg,base_dest+0x003+ct*3+2,IO_ReadB(0x3c9)); + } + + IO_ReadB(crt_reg+6); + IO_WriteB(0x3c0,0x20); + + base_dest+=0x303; + } + + if ((svgaCard==SVGA_S3Trio) && (state&8)) { + real_writew(base_seg,RealOff(buffer)+6,base_dest); + + Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + + IO_WriteB(0x3c4,0x08); + Bitu seq_8=IO_ReadB(0x3c5); +// real_writeb(base_seg,base_dest+0x00,IO_ReadB(0x3c5)); + IO_WriteB(0x3c5,0x06); // unlock s3-specific registers + + // sequencer + for (ct=0; ct<0x13; ct++) { + IO_WriteB(0x3c4,0x09+ct); + real_writeb(base_seg,base_dest+0x00+ct,IO_ReadB(0x3c5)); + } + + // unlock s3-specific registers + IO_WriteW(crt_reg,0x4838); + IO_WriteW(crt_reg,0xa539); + + // crt controller + Bitu ct_dest=0x13; + for (ct=0; ct<0x40; ct++) { + if ((ct==0x4a-0x30) || (ct==0x4b-0x30)) { + IO_WriteB(crt_reg,0x45); + IO_ReadB(crt_reg+1); + IO_WriteB(crt_reg,0x30+ct); + real_writeb(base_seg,base_dest+(ct_dest++),IO_ReadB(crt_reg+1)); + real_writeb(base_seg,base_dest+(ct_dest++),IO_ReadB(crt_reg+1)); + real_writeb(base_seg,base_dest+(ct_dest++),IO_ReadB(crt_reg+1)); + } else { + IO_WriteB(crt_reg,0x30+ct); + real_writeb(base_seg,base_dest+(ct_dest++),IO_ReadB(crt_reg+1)); + } + } + } + return true; +} + +bool INT10_VideoState_Restore(Bitu state,RealPt buffer) { + Bitu ct; + if ((state&7)==0) return false; + + Bit16u base_seg=RealSeg(buffer); + Bit16u base_dest; + + if (state&1) { + base_dest=real_readw(base_seg,RealOff(buffer)); + Bit16u crt_reg=real_readw(base_seg,base_dest+0x40); + + // reprogram for full access to plane latches + IO_WriteW(0x3c4,0x0704); + IO_WriteW(0x3ce,0x0406); + IO_WriteW(0x3ce,0x0005); + + IO_WriteW(0x3c4,0x0002); + mem_writeb(0xaffff,real_readb(base_seg,base_dest+0x42)); + IO_WriteW(0x3c4,0x0102); + mem_writeb(0xaffff,real_readb(base_seg,base_dest+0x43)); + IO_WriteW(0x3c4,0x0202); + mem_writeb(0xaffff,real_readb(base_seg,base_dest+0x44)); + IO_WriteW(0x3c4,0x0402); + mem_writeb(0xaffff,real_readb(base_seg,base_dest+0x45)); + IO_WriteW(0x3c4,0x0f02); + mem_readb(0xaffff); + + IO_WriteW(0x3c4,0x0100); + + // sequencer + for (ct=1; ct<5; ct++) { + IO_WriteW(0x3c4,ct+(real_readb(base_seg,base_dest+0x04+ct)<<8)); + } + + IO_WriteB(0x3c2,real_readb(base_seg,base_dest+0x09)); + IO_WriteW(0x3c4,0x0300); + IO_WriteW(crt_reg,0x0011); + + // crt controller + for (ct=0; ct<0x19; ct++) { + IO_WriteW(crt_reg,ct+(real_readb(base_seg,base_dest+0x0a+ct)<<8)); + } + + IO_ReadB(crt_reg+6); + // attr registers + for (ct=0; ct<4; ct++) { + IO_WriteB(0x3c0,0x10+ct); + IO_WriteB(0x3c0,real_readb(base_seg,base_dest+0x33+ct)); + } + + // graphics registers + for (ct=0; ct<9; ct++) { + IO_WriteW(0x3ce,ct+(real_readb(base_seg,base_dest+0x37+ct)<<8)); + } + + IO_WriteB(crt_reg+6,real_readb(base_seg,base_dest+0x04)); + IO_ReadB(crt_reg+6); + + // attr registers + for (ct=0; ct<0x10; ct++) { + IO_WriteB(0x3c0,ct); + IO_WriteB(0x3c0,real_readb(base_seg,base_dest+0x23+ct)); + } + + IO_WriteB(0x3c4,real_readb(base_seg,base_dest+0x00)); + IO_WriteB(0x3d4,real_readb(base_seg,base_dest+0x01)); + IO_WriteB(0x3ce,real_readb(base_seg,base_dest+0x02)); + IO_ReadB(crt_reg+6); + IO_WriteB(0x3c0,real_readb(base_seg,base_dest+0x03)); + } + + if (state&2) { + base_dest=real_readw(base_seg,RealOff(buffer)+2); + + mem_writeb(0x410,(mem_readb(0x410)&0xcf) | real_readb(base_seg,base_dest+0x00)); + for (ct=0; ct<0x1e; ct++) { + mem_writeb(0x449+ct,real_readb(base_seg,base_dest+0x01+ct)); + } + for (ct=0; ct<0x07; ct++) { + mem_writeb(0x484+ct,real_readb(base_seg,base_dest+0x1f+ct)); + } + mem_writed(0x48a,real_readd(base_seg,base_dest+0x26)); + mem_writed(0x14,real_readd(base_seg,base_dest+0x2a)); // int 5 + mem_writed(0x74,real_readd(base_seg,base_dest+0x2e)); // int 1d + mem_writed(0x7c,real_readd(base_seg,base_dest+0x32)); // int 1f + mem_writed(0x10c,real_readd(base_seg,base_dest+0x36)); // int 43 + } + + if (state&4) { + base_dest=real_readw(base_seg,RealOff(buffer)+4); + + Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + + IO_WriteB(0x3c6,real_readb(base_seg,base_dest+0x002)); + + for (ct=0; ct<0x100; ct++) { + IO_WriteB(0x3c8,ct); + IO_WriteB(0x3c9,real_readb(base_seg,base_dest+0x003+ct*3+0)); + IO_WriteB(0x3c9,real_readb(base_seg,base_dest+0x003+ct*3+1)); + IO_WriteB(0x3c9,real_readb(base_seg,base_dest+0x003+ct*3+2)); + } + + IO_ReadB(crt_reg+6); + IO_WriteB(0x3c0,0x14); + IO_WriteB(0x3c0,real_readb(base_seg,base_dest+0x303)); + + Bitu dac_state=real_readb(base_seg,base_dest+0x000); + if (dac_state==0) { + IO_WriteB(0x3c8,real_readb(base_seg,base_dest+0x001)); + } else { + IO_WriteB(0x3c7,real_readb(base_seg,base_dest+0x001)); + } + } + + if ((svgaCard==SVGA_S3Trio) && (state&8)) { + base_dest=real_readw(base_seg,RealOff(buffer)+6); + + Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + + Bitu seq_idx=IO_ReadB(0x3c4); + IO_WriteB(0x3c4,0x08); + Bitu seq_8=IO_ReadB(0x3c5); +// real_writeb(base_seg,base_dest+0x00,IO_ReadB(0x3c5)); + IO_WriteB(0x3c5,0x06); // unlock s3-specific registers + + // sequencer + for (ct=0; ct<0x13; ct++) { + IO_WriteW(0x3c4,(0x09+ct)+(real_readb(base_seg,base_dest+0x00+ct)<<8)); + } + IO_WriteB(0x3c4,seq_idx); + + Bitu crtc_idx=IO_ReadB(0x3d4); + + // unlock s3-specific registers + IO_WriteW(crt_reg,0x4838); + IO_WriteW(crt_reg,0xa539); + + // crt controller + Bitu ct_dest=0x13; + for (ct=0; ct<0x40; ct++) { + if ((ct==0x4a-0x30) || (ct==0x4b-0x30)) { + IO_WriteB(crt_reg,0x45); + IO_ReadB(crt_reg+1); + IO_WriteB(crt_reg,0x30+ct); + IO_WriteB(crt_reg,real_readb(base_seg,base_dest+(ct_dest++))); + } else { + IO_WriteW(crt_reg,(0x30+ct)+(real_readb(base_seg,base_dest+(ct_dest++))<<8)); + } + } + + // mmio +/* IO_WriteB(crt_reg,0x40); + Bitu sysval1=IO_ReadB(crt_reg+1); + IO_WriteB(crt_reg+1,sysval|1); + IO_WriteB(crt_reg,0x53); + Bitu sysva2=IO_ReadB(crt_reg+1); + IO_WriteB(crt_reg+1,sysval2|0x10); + + real_writew(0xa000,0x8128,0xffff); + + IO_WriteB(crt_reg,0x40); + IO_WriteB(crt_reg,sysval1); + IO_WriteB(crt_reg,0x53); + IO_WriteB(crt_reg,sysval2); + IO_WriteB(crt_reg,crtc_idx); */ + } + + return true; +} diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 11a108f4..b2eb0668 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -689,6 +689,9 @@ + + Date: Wed, 26 Sep 2007 18:05:51 +0000 Subject: [PATCH 2909/4131] add video parameter table/generator functions (fixes Popeye2 and others) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2997 --- src/ints/int10.h | 4 + src/ints/int10_memory.cpp | 499 +++++++++++++++++++++++++++++++++++++- src/ints/int10_modes.cpp | 2 +- 3 files changed, 502 insertions(+), 3 deletions(-) diff --git a/src/ints/int10.h b/src/ints/int10.h index ab461176..72b931e5 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -122,6 +122,10 @@ typedef struct { RealPt font_14; RealPt font_16; RealPt static_state; + RealPt video_save_pointers; + RealPt video_parameter_table; + RealPt video_save_pointer_table; + RealPt video_dcc_table; RealPt oemstring; RealPt vesa_modes; RealPt pmode_interface; diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 4779f9af..76fc0927 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -32,7 +32,7 @@ static Bit8u static_functionality[0x10]= /* 8 */ 0x04, // total number of character blocks available in text modes /* 9 */ 0x02, // maximum number of active character blocks in text modes /* a */ 0xff, // Misc Flags Everthing supported - /* b */ 0x0c, // Support for Display combination and intensity/blinking + /* b */ 0x0e, // Support for Display combination, intensity/blinking and video state saving/restoring /* c */ 0x00, // reserved /* d */ 0x00, // reserved /* e */ 0x00, // Change to add new functions @@ -57,7 +57,8 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu IO_Write(0x3c4,0x2); IO_Write(0x3c5,0xf); //Enable all planes IO_Write(0x3ce,0x6); - IO_Write(0x3cf,old_6); //odd/even and b8000 adressing + if (IS_VGA_ARCH) IO_Write(0x3cf,old_6); //odd/even and b8000 adressing + else IO_Write(0x3cf,0x0e); /* Reload tables and registers with new values based on this height */ if (reload) { //Max scanline @@ -72,6 +73,239 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu } } + +static Bit8u video_parameter_table[0x40*0x1d]={ +// video parameter table for mode 0 (cga emulation) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 1 (cga emulation) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 2 (cga emulation) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 3 (cga emulation) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 4 + 0x28, 0x18, 0x08, 0x00, 0x40, // bios data + 0x09, 0x00, 0x00, 0x02, // sequencer registers + 0x63, // misc output registers + 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, 0xff, // crtc registers 16-24 + 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, // attr registers 0-7 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0f, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 5 + 0x28, 0x18, 0x08, 0x00, 0x40, // bios data + 0x09, 0x00, 0x00, 0x02, // sequencer registers + 0x63, // misc output registers + 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, 0xff, // crtc registers 16-24 + 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, // attr registers 0-7 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0f, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 6 + 0x50, 0x18, 0x08, 0x00, 0x40, // bios data + 0x09, 0x0f, 0x00, 0x02, // sequencer registers + 0x63, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2, 0xff, // crtc registers 16-24 + 0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, // attr registers 0-7 + 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, // attr registers 8-15 + 0x01, 0x00, 0x01, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 7 + 0x50, 0x18, 0x10, 0x00, 0x10, // bios data + 0x00, 0x0f, 0x00, 0x07, // sequencer registers + 0x66, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, // attr registers 0-7 + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // attr registers 8-15 + 0x0c, 0x00, 0x0f, 0x08, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 8 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 9 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode a + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode b + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode c + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode d + 0x28, 0x18, 0x08, 0x00, 0x20, // bios data + 0x09, 0x0f, 0x00, 0x02, // sequencer registers + 0x63, // misc output registers + 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // attr registers 0-7 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode e + 0x50, 0x18, 0x08, 0x00, 0x40, // bios data + 0x01, 0x0f, 0x00, 0x02, // sequencer registers + 0x63, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // attr registers 0-7 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode f (64k graphics memory) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 10 (64k graphics memory) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode f (>64k graphics memory) + 0x50, 0x18, 0x0e, 0x00, 0x80, // bios data + 0x01, 0x0f, 0x00, 0x02, // sequencer registers + 0xa2, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, 0xff, // crtc registers 16-24 + 0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, // attr registers 0-7 + 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, // attr registers 8-15 + 0x0b, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 10 (>64k graphics memory) + 0x50, 0x18, 0x0e, 0x00, 0x80, // bios data + 0x01, 0x0f, 0x00, 0x02, // sequencer registers + 0xa3, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, // attr registers 0-7 + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 0 (350 lines) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 1 (350 lines) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 2 (350 lines) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 3 (350 lines) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode e + 0x28, 0x18, 0x10, 0x00, 0x08, // bios data + 0x08, 0x0f, 0x00, 0x07, // sequencer registers + 0x67, // misc output registers + 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, // attr registers 0-7 + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // attr registers 8-15 + 0x0c, 0x00, 0x0f, 0x08, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode f + 0x50, 0x18, 0x10, 0x00, 0x10, // bios data + 0x00, 0x0f, 0x00, 0x07, // sequencer registers + 0x67, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, // attr registers 0-7 + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // attr registers 8-15 + 0x0c, 0x00, 0x0f, 0x08, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 10 + 0x50, 0x18, 0x10, 0x00, 0x10, // bios data + 0x00, 0x0f, 0x00, 0x07, // sequencer registers + 0x66, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, // attr registers 0-7 + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // attr registers 8-15 + 0x0c, 0x00, 0x0f, 0x08, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 11 + 0x50, 0x1d, 0x10, 0x00, 0xa0, // bios data + 0x01, 0x0f, 0x00, 0x02, // sequencer registers + 0xe3, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, // crtc registers 0-7 + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xc3, 0xff, // crtc registers 16-24 + 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, // attr registers 0-7 + 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 12 + 0x50, 0x1d, 0x10, 0x00, 0xa0, // bios data + 0x01, 0x0f, 0x00, 0x02, // sequencer registers + 0xe3, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, // crtc registers 0-7 + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, // attr registers 0-7 + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 13 + 0x28, 0x18, 0x08, 0x00, 0x20, // bios data + 0x01, 0x0f, 0x00, 0x0e, // sequencer registers + 0x63, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // attr registers 0-7 + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, // attr registers 8-15 + 0x41, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff, // graphics registers 0-8 +}; + static Bitu checksumlocation = 0; //Same type as int10.rom.used void INT10_SetupRomMemory(void) { /* This should fill up certain structures inside the Video Bios Rom Area */ @@ -115,6 +349,79 @@ void INT10_SetupRomMemory(void) { } RealSetVec(0x1F,int10.rom.font_8_second); + if (IS_EGAVGA_ARCH) { + int10.rom.video_parameter_table=RealMake(0xC000,int10.rom.used); + if (IS_VGA_ARCH) { + for (i=0;i<0x40*0x1d;i++) { + phys_writeb(rom_base+int10.rom.used++,video_parameter_table[i]); + } + } else { + // tables not correct (ega) + for (i=0;i<0x40*0x17;i++) { + phys_writeb(rom_base+int10.rom.used++,video_parameter_table[i]); + } + } + + if (IS_VGA_ARCH) { + int10.rom.video_dcc_table=RealMake(0xC000,int10.rom.used); + phys_writeb(rom_base+int10.rom.used++,0x10); // number of entries + phys_writeb(rom_base+int10.rom.used++,1); // version number + phys_writeb(rom_base+int10.rom.used++,8); // maximal display code + phys_writeb(rom_base+int10.rom.used++,0); // reserved + // display combination codes + phys_writew(rom_base+int10.rom.used,0x0000); int10.rom.used+=2; + phys_writew(rom_base+int10.rom.used,0x0100); int10.rom.used+=2; + phys_writew(rom_base+int10.rom.used,0x0200); int10.rom.used+=2; + phys_writew(rom_base+int10.rom.used,0x0102); int10.rom.used+=2; + phys_writew(rom_base+int10.rom.used,0x0400); int10.rom.used+=2; + phys_writew(rom_base+int10.rom.used,0x0104); int10.rom.used+=2; + phys_writew(rom_base+int10.rom.used,0x0500); int10.rom.used+=2; + phys_writew(rom_base+int10.rom.used,0x0502); int10.rom.used+=2; + phys_writew(rom_base+int10.rom.used,0x0600); int10.rom.used+=2; + phys_writew(rom_base+int10.rom.used,0x0601); int10.rom.used+=2; + phys_writew(rom_base+int10.rom.used,0x0605); int10.rom.used+=2; + phys_writew(rom_base+int10.rom.used,0x0800); int10.rom.used+=2; + phys_writew(rom_base+int10.rom.used,0x0801); int10.rom.used+=2; + phys_writew(rom_base+int10.rom.used,0x0700); int10.rom.used+=2; + phys_writew(rom_base+int10.rom.used,0x0702); int10.rom.used+=2; + phys_writew(rom_base+int10.rom.used,0x0706); int10.rom.used+=2; + + int10.rom.video_save_pointer_table=RealMake(0xC000,int10.rom.used); + phys_writew(rom_base+int10.rom.used,0x1a); // length of table + int10.rom.used+=2; + phys_writed(rom_base+int10.rom.used,int10.rom.video_dcc_table); + int10.rom.used+=4; + phys_writed(rom_base+int10.rom.used,0); // alphanumeric charset override + int10.rom.used+=4; + phys_writed(rom_base+int10.rom.used,0); // user palette table + int10.rom.used+=4; + phys_writed(rom_base+int10.rom.used,0); int10.rom.used+=4; + phys_writed(rom_base+int10.rom.used,0); int10.rom.used+=4; + phys_writed(rom_base+int10.rom.used,0); int10.rom.used+=4; + } + + // use the following to generate/update the video parameter table: +// void INT10_GenerateVideoParameterTable(); +// INT10_GenerateVideoParameterTable(); + int10.rom.video_save_pointers=RealMake(0xC000,int10.rom.used); + phys_writed(rom_base+int10.rom.used,int10.rom.video_parameter_table); + int10.rom.used+=4; + phys_writed(rom_base+int10.rom.used,0); // dynamic save area pointer + int10.rom.used+=4; + phys_writed(rom_base+int10.rom.used,0); // alphanumeric character set override + int10.rom.used+=4; + phys_writed(rom_base+int10.rom.used,0); // graphics character set override + int10.rom.used+=4; + if (IS_VGA_ARCH) { + phys_writed(rom_base+int10.rom.used,int10.rom.video_save_pointer_table); + } else { + phys_writed(rom_base+int10.rom.used,0); // secondary save pointer table + } + int10.rom.used+=4; + phys_writed(rom_base+int10.rom.used,0); int10.rom.used+=4; + phys_writed(rom_base+int10.rom.used,0); int10.rom.used+=4; + } + if (IS_TANDY_ARCH) { RealSetVec(0x44,int10.rom.font_8_first); } @@ -159,6 +466,194 @@ void INT10_SetupRomMemoryChecksum(void) { } +void INT10_GenerateVideoParameterTable(void) { + Bitu i; + for (i=0; i<4; i++) { + LOG_MSG("// video parameter table for mode %x (cga emulation)",i); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + } + for (i=4; i<0x0f; i++) { + Bitu ct; + LOG_MSG("// video parameter table for mode %x",i); + if ((i>=8) && (i<0x0d)) { + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + } else { + INT10_SetVideoMode(i); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // bios data",real_readb(0x40,0x4a),real_readb(0x40,0x84),real_readb(0x40,0x85),real_readb(0x40,0x4c),real_readb(0x40,0x4d)); + Bitu seq_regs[4]; + for (ct=0; ct<4; ct++) { + IO_WriteB(0x3c4,ct+1); + seq_regs[ct]=IO_ReadB(0x3c5); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // sequencer registers",seq_regs[0],seq_regs[1],seq_regs[2],seq_regs[3]); + LOG_MSG(" 0x%02x, // misc output registers",IO_ReadB(0x3cc)); + Bitu crtc_regs[4]; + Bit16u crt_addr=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + for (ct=0; ct<0x19; ct++) { + IO_WriteB(crt_addr,ct); + crtc_regs[ct]=IO_ReadB(crt_addr+1); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 0-7", + crtc_regs[0x00],crtc_regs[0x01],crtc_regs[0x02],crtc_regs[0x03], + crtc_regs[0x04],crtc_regs[0x05],crtc_regs[0x06],crtc_regs[0x07]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 8-15", + crtc_regs[0x08],crtc_regs[0x09],crtc_regs[0x0a],crtc_regs[0x0b], + crtc_regs[0x0c],crtc_regs[0x0d],crtc_regs[0x0e],crtc_regs[0x0f]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 16-24", + crtc_regs[0x10],crtc_regs[0x11],crtc_regs[0x12],crtc_regs[0x13], + crtc_regs[0x14],crtc_regs[0x15],crtc_regs[0x16],crtc_regs[0x17],crtc_regs[0x18]); + Bitu attr_regs[4]; + for (ct=0; ct<0x14; ct++) { + IO_ReadB(crt_addr+6); + IO_WriteB(0x3c0,ct); + attr_regs[ct]=IO_ReadB(0x3c1); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 0-7", + attr_regs[0x00],attr_regs[0x01],attr_regs[0x02],attr_regs[0x03], + attr_regs[0x04],attr_regs[0x05],attr_regs[0x06],attr_regs[0x07]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 8-15", + attr_regs[0x08],attr_regs[0x09],attr_regs[0x0a],attr_regs[0x0b], + attr_regs[0x0c],attr_regs[0x0d],attr_regs[0x0e],attr_regs[0x0f]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 16-19", + attr_regs[0x10],attr_regs[0x11],attr_regs[0x12],attr_regs[0x13]); + Bitu gfx_regs[4]; + for (ct=0; ct<0x09; ct++) { + IO_WriteB(0x3ce,ct); + gfx_regs[ct]=IO_ReadB(0x3cf); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // graphics registers 0-8", + gfx_regs[0x00],gfx_regs[0x01],gfx_regs[0x02],gfx_regs[0x03], + gfx_regs[0x04],gfx_regs[0x05],gfx_regs[0x06],gfx_regs[0x07],gfx_regs[0x08]); + } + } + for (i=0x0f; i<0x11; i++) { + LOG_MSG("// video parameter table for mode %x (64k graphics memory)",i); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + } + for (i=0x0f; i<0x11; i++) { + Bitu ct; + INT10_SetVideoMode(i); + LOG_MSG("// video parameter table for mode %x (>64k graphics memory)",i); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // bios data",real_readb(0x40,0x4a),real_readb(0x40,0x84),real_readb(0x40,0x85),real_readb(0x40,0x4c),real_readb(0x40,0x4d)); + Bitu seq_regs[4]; + for (ct=0; ct<4; ct++) { + IO_WriteB(0x3c4,ct+1); + seq_regs[ct]=IO_ReadB(0x3c5); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // sequencer registers",seq_regs[0],seq_regs[1],seq_regs[2],seq_regs[3]); + LOG_MSG(" 0x%02x, // misc output registers",IO_ReadB(0x3cc)); + Bitu crtc_regs[4]; + Bit16u crt_addr=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + for (ct=0; ct<0x19; ct++) { + IO_WriteB(crt_addr,ct); + crtc_regs[ct]=IO_ReadB(crt_addr+1); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 0-7", + crtc_regs[0x00],crtc_regs[0x01],crtc_regs[0x02],crtc_regs[0x03], + crtc_regs[0x04],crtc_regs[0x05],crtc_regs[0x06],crtc_regs[0x07]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 8-15", + crtc_regs[0x08],crtc_regs[0x09],crtc_regs[0x0a],crtc_regs[0x0b], + crtc_regs[0x0c],crtc_regs[0x0d],crtc_regs[0x0e],crtc_regs[0x0f]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 16-24", + crtc_regs[0x10],crtc_regs[0x11],crtc_regs[0x12],crtc_regs[0x13], + crtc_regs[0x14],crtc_regs[0x15],crtc_regs[0x16],crtc_regs[0x17],crtc_regs[0x18]); + Bitu attr_regs[4]; + for (ct=0; ct<0x14; ct++) { + IO_ReadB(crt_addr+6); + IO_WriteB(0x3c0,ct); + attr_regs[ct]=IO_ReadB(0x3c1); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 0-7", + attr_regs[0x00],attr_regs[0x01],attr_regs[0x02],attr_regs[0x03], + attr_regs[0x04],attr_regs[0x05],attr_regs[0x06],attr_regs[0x07]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 8-15", + attr_regs[0x08],attr_regs[0x09],attr_regs[0x0a],attr_regs[0x0b], + attr_regs[0x0c],attr_regs[0x0d],attr_regs[0x0e],attr_regs[0x0f]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 16-19", + attr_regs[0x10],attr_regs[0x11],attr_regs[0x12],attr_regs[0x13]); + Bitu gfx_regs[4]; + for (ct=0; ct<0x09; ct++) { + IO_WriteB(0x3ce,ct); + gfx_regs[ct]=IO_ReadB(0x3cf); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // graphics registers 0-8", + gfx_regs[0x00],gfx_regs[0x01],gfx_regs[0x02],gfx_regs[0x03], + gfx_regs[0x04],gfx_regs[0x05],gfx_regs[0x06],gfx_regs[0x07],gfx_regs[0x08]); + } + for (i=0; i<4; i++) { + LOG_MSG("// video parameter table for mode %x (350 lines)",i); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + } + for (i=0x0e; i<0x14; i++) { + Bitu ct=i; + if (i==0x0e) ct=1; + if (i==0x0f) ct=3; + if (i==0x010) ct=7; + INT10_SetVideoMode(ct); + LOG_MSG("// video parameter table for mode %x",i); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // bios data",real_readb(0x40,0x4a),real_readb(0x40,0x84),real_readb(0x40,0x85),real_readb(0x40,0x4c),real_readb(0x40,0x4d)); + Bitu seq_regs[4]; + for (ct=0; ct<4; ct++) { + IO_WriteB(0x3c4,ct+1); + seq_regs[ct]=IO_ReadB(0x3c5); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // sequencer registers",seq_regs[0],seq_regs[1],seq_regs[2],seq_regs[3]); + LOG_MSG(" 0x%02x, // misc output registers",IO_ReadB(0x3cc)); + Bitu crtc_regs[4]; + Bit16u crt_addr=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + for (ct=0; ct<0x19; ct++) { + IO_WriteB(crt_addr,ct); + crtc_regs[ct]=IO_ReadB(crt_addr+1); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 0-7", + crtc_regs[0x00],crtc_regs[0x01],crtc_regs[0x02],crtc_regs[0x03], + crtc_regs[0x04],crtc_regs[0x05],crtc_regs[0x06],crtc_regs[0x07]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 8-15", + crtc_regs[0x08],crtc_regs[0x09],crtc_regs[0x0a],crtc_regs[0x0b], + crtc_regs[0x0c],crtc_regs[0x0d],crtc_regs[0x0e],crtc_regs[0x0f]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 16-24", + crtc_regs[0x10],crtc_regs[0x11],crtc_regs[0x12],crtc_regs[0x13], + crtc_regs[0x14],crtc_regs[0x15],crtc_regs[0x16],crtc_regs[0x17],crtc_regs[0x18]); + Bitu attr_regs[4]; + for (ct=0; ct<0x14; ct++) { + IO_ReadB(crt_addr+6); + IO_WriteB(0x3c0,ct); + attr_regs[ct]=IO_ReadB(0x3c1); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 0-7", + attr_regs[0x00],attr_regs[0x01],attr_regs[0x02],attr_regs[0x03], + attr_regs[0x04],attr_regs[0x05],attr_regs[0x06],attr_regs[0x07]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 8-15", + attr_regs[0x08],attr_regs[0x09],attr_regs[0x0a],attr_regs[0x0b], + attr_regs[0x0c],attr_regs[0x0d],attr_regs[0x0e],attr_regs[0x0f]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 16-19", + attr_regs[0x10],attr_regs[0x11],attr_regs[0x12],attr_regs[0x13]); + Bitu gfx_regs[4]; + for (ct=0; ct<0x09; ct++) { + IO_WriteB(0x3ce,ct); + gfx_regs[ct]=IO_ReadB(0x3cf); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // graphics registers 0-8", + gfx_regs[0x00],gfx_regs[0x01],gfx_regs[0x02],gfx_regs[0x03], + gfx_regs[0x04],gfx_regs[0x05],gfx_regs[0x06],gfx_regs[0x07],gfx_regs[0x08]); + } + INT10_SetVideoMode(3); + E_Exit("done!"); +} + + Bit8u int10_font_08[256 * 8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 0f405232..c30f74ea 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -271,10 +271,10 @@ static void FinishSetMode(bool clearmem) { real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0x09); real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); - // FIXME We nearly have the good tables. to be reworked if (IS_VGA_ARCH) real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08); // 8 is VGA should be ok for now real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER,0x00); real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2,0x00); + real_writed(BIOSMEM_SEG,BIOSMEM_VS_POINTER,int10.rom.video_save_pointers); // Set cursor shape if(CurMode->type==M_TEXT) { From c1b3523d010b33fed1549f88a3e402207046ad31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 27 Sep 2007 16:11:40 +0000 Subject: [PATCH 2910/4131] use 8x14 fonts for ega text modes (350 line modes) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2998 --- src/dos/dos_keyboard_layout.cpp | 3 ++- src/ints/int10_modes.cpp | 39 ++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 641a3c39..85b5b4fa 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -888,7 +888,8 @@ Bitu keyboard_layout::read_codepage_file(const char* codepage_file_name, Bit32s // update font if necessary if (font_changed && (CurMode->type==M_TEXT) && (IS_EGAVGA_ARCH)) { - INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); + if (IS_VGA_ARCH) INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); + else INT10_LoadFont(Real2Phys(int10.rom.font_14),true,256,0,0,14); } INT10_SetupRomMemoryChecksum(); diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index c30f74ea..5ad4f0b3 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -101,6 +101,25 @@ VideoModeBlock ModeList_VGA[]={ { 0x195 ,M_LIN32 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, +{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, +}; + +VideoModeBlock ModeList_EGA[]={ +/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */ +{ 0x000 ,M_TEXT ,320 ,350 ,40 ,25 ,8 ,14 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,350 ,_EGA_HALF_CLOCK }, +{ 0x001 ,M_TEXT ,320 ,350 ,40 ,25 ,8 ,14 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,350 ,_EGA_HALF_CLOCK }, +{ 0x002 ,M_TEXT ,640 ,350 ,80 ,25 ,8 ,14 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,350 ,0 }, +{ 0x003 ,M_TEXT ,640 ,350 ,80 ,25 ,8 ,14 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,350 ,0 }, +{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x007 ,M_TEXT ,720 ,350 ,80 ,25 ,9 ,14 ,8 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,350 ,0 }, + +{ 0x00D ,M_EGA ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, +{ 0x00E ,M_EGA ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE }, +{ 0x00F ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 },/*was EGA_2*/ +{ 0x010 ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, + {0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, }; @@ -469,15 +488,18 @@ bool INT10_SetVideoMode(Bitu mode) { } LOG(LOG_INT10,LOG_NORMAL)("Set Video Mode %X",mode); if (!IS_EGAVGA_ARCH) return INT10_SetVideoMode_OTHER(mode,clearmem); - if ((machine==MCH_EGA) && (mode>0x10)) { - LOG(LOG_INT10,LOG_ERROR)("EGA:Trying to set illegal mode %X",mode); - return false; - } Bit8u modeset_ctl,video_ctl,vga_switches; - if (!SetCurMode(ModeList_VGA,mode)){ - LOG(LOG_INT10,LOG_ERROR)("Trying to set illegal mode %X",mode); - return false; + if (IS_VGA_ARCH) { + if (!SetCurMode(ModeList_VGA,mode)){ + LOG(LOG_INT10,LOG_ERROR)("VGA:Trying to set illegal mode %X",mode); + return false; + } + } else { + if (!SetCurMode(ModeList_EGA,mode)){ + LOG(LOG_INT10,LOG_ERROR)("EGA:Trying to set illegal mode %X",mode); + return false; + } } /* First read mode setup settings from bios area */ @@ -1026,7 +1048,8 @@ dac_text16: FinishSetMode(clearmem); /* Load text mode font */ if (CurMode->type==M_TEXT) { - INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); + if (IS_VGA_ARCH) INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); + else INT10_LoadFont(Real2Phys(int10.rom.font_14),true,256,0,0,14); } return true; } From e7db5a262e48cdf85ce168cd6395855962f2d7ce Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 27 Sep 2007 19:34:43 +0000 Subject: [PATCH 2911/4131] Remove path when valid. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2999 --- src/dos/dos_devices.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 48396751..64322323 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_devices.cpp,v 1.18 2007-06-14 08:23:46 qbix79 Exp $ */ +/* $Id: dos_devices.cpp,v 1.19 2007-09-27 19:34:43 qbix79 Exp $ */ #include #include "dosbox.h" @@ -129,22 +129,23 @@ Bit8u DOS_FindDevice(char const * name) { char temp[CROSS_LEN];//TODO if(!name || !(*name)) return DOS_DEVICES; strcpy(temp,name); - char* dot= strrchr(temp,'.'); - if(dot && *dot) *dot=0; //no ext checking - char* leading = strrchr(temp,'\\'); - if(leading) { - *leading = 0; + char* name_start = strrchr(temp,'\\'); + if(name_start) { + //Directory found in front of the filename. Check it's path + *name_start++ = 0; Bit8u drive;char fulldir[DOS_PATHLENGTH]; if (!DOS_MakeName(temp,fulldir,&drive)) return DOS_DEVICES; if(!Drives[drive]->TestDir(fulldir)) return DOS_DEVICES; - *leading='\\'; - } + } else name_start = temp; + + char* dot = strrchr(name_start,'.'); + if(dot) *dot = 0; //no ext checking /* loop through devices */ for(Bit8u index = 0;index < DOS_DEVICES;index++) { if (Devices[index]) { - if (WildFileCmp(temp,Devices[index]->name)) return index; + if (WildFileCmp(name_start,Devices[index]->name)) return index; } } return DOS_DEVICES; From b0855c4d63825f1b59031917b1f44b0a39a5e8e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 28 Sep 2007 15:40:46 +0000 Subject: [PATCH 2912/4131] add true 720x400/360x400 vga textmodes for vga-only setting (8+1x16 font) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3000 --- src/hardware/vga_draw.cpp | 43 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 6716a82d..70693707 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -407,6 +407,40 @@ skip_cursor: return TempLine; } +static Bit8u * VGA_TEXT_Draw_Line_9(Bitu vidstart, Bitu line) { + Bits font_addr; + Bit8u * draw=(Bit8u *)TempLine; + const Bit8u *vidmem = &vga.tandy.draw_base[vidstart]; + Bitu bitpos=0; + for (Bitu cx=0;cx> 3)&1][chr*32+line]; + Bit8u fg=col&0xf; + Bit8u bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff); + if (FontMask[col>>7]==0) font=0; + *draw++=(font&0x80)?fg:bg; *draw++=(font&0x40)?fg:bg; + *draw++=(font&0x20)?fg:bg; *draw++=(font&0x10)?fg:bg; + *draw++=(font&0x08)?fg:bg; *draw++=(font&0x04)?fg:bg; + *draw++=(font&0x02)?fg:bg; + Bit8u last=(font&0x01)?fg:bg; + *draw++=last; + *draw++=((chr<0xc0) || (chr>0xdf)) ? bg : last; + } + if (!vga.draw.cursor.enabled || !(vga.draw.cursor.count&0x8)) goto skip_cursor; + font_addr = (vga.draw.cursor.address-vidstart) >> 1; + if (font_addr>=0 && font_addr<(Bits)vga.draw.blocks) { + if (linevga.draw.cursor.eline) goto skip_cursor; + draw=&TempLine[font_addr*9]; + Bit8u fg=vga.tandy.draw_base[vga.draw.cursor.address+1]&0xf; + *draw++=fg; *draw++=fg; *draw++=fg; *draw++=fg; + *draw++=fg; *draw++=fg; *draw++=fg; *draw++=fg; + } +skip_cursor: + return TempLine; +} + static void VGA_VerticalDisplayEnd(Bitu val) { // vga.config.retrace=true; vga.config.real_start=vga.config.display_start & ((2*1024*1024)-1); @@ -931,8 +965,13 @@ void VGA_SetupDrawing(Bitu val) { aspect_ratio=1.0; vga.draw.blocks=width; doublewidth=(vga.seq.clocking_mode & 0x8) > 0; - width<<=3; /* 8 bit wide text font */ - VGA_DrawLine=VGA_TEXT_Draw_Line; + if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) { + width*=9; /* 9 bit wide text font */ + VGA_DrawLine=VGA_TEXT_Draw_Line_9; + } else { + width<<=3; /* 8 bit wide text font */ + VGA_DrawLine=VGA_TEXT_Draw_Line; + } break; case M_HERC_GFX: aspect_ratio=1.5; From c9eb0378a5e91a36850c3582b3007b0bb497ad06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 28 Sep 2007 21:06:18 +0000 Subject: [PATCH 2913/4131] add vret irq (ega only; fixes Gauntlet hanging) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3001 --- include/vga.h | 1 + src/hardware/vga_draw.cpp | 4 ++++ src/hardware/vga_misc.cpp | 10 +++++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/include/vga.h b/include/vga.h index d85b4042..d0500dbe 100644 --- a/include/vga.h +++ b/include/vga.h @@ -142,6 +142,7 @@ typedef struct { Bit8u count,delay; Bit8u enabled; } cursor; + bool vret_triggered; } VGA_Draw; typedef struct { diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 70693707..185e2a1d 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -617,6 +617,10 @@ static void VGA_VerticalTimer(Bitu val) { //VGA_DrawPart( vga.draw.parts_lines ); PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts,vga.draw.parts_lines); // PIC_AddEvent(VGA_DrawPart,(float)(vga.draw.delay.parts/2),vga.draw.parts_lines); //Else tearline in Tyrian and second reality + if (GCC_UNLIKELY(machine==MCH_EGA)) { + PIC_ActivateIRQ(2); + vga.draw.vret_triggered=true; + } } void VGA_CheckScanLength(void) { diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 4d9093b9..2da0c33e 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -139,11 +139,17 @@ static Bitu read_p3ca(Bitu port,Bitu iolen) { } static Bitu read_p3c2(Bitu port,Bitu iolen) { - return 0x70; + Bitu retcode=0x70; + if (GCC_UNLIKELY(machine==MCH_EGA)) { + retcode |= (vga.draw.vret_triggered ? 0x80 : 0x00); + vga.draw.vret_triggered=false; + } + return retcode; } void VGA_SetupMisc(void) { if (IS_EGAVGA_ARCH) { + vga.draw.vret_triggered=false; IO_RegisterReadHandler(0x3c2,read_p3c2,IO_MB); IO_RegisterWriteHandler(0x3c2,write_p3c2,IO_MB); if (IS_VGA_ARCH) { @@ -156,5 +162,3 @@ void VGA_SetupMisc(void) { IO_RegisterReadHandler(0x3ba,vga_read_p3da,IO_MB); } } - - From cd5a157a34159c1d8102a3c57f1716214d657056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 29 Sep 2007 10:30:46 +0000 Subject: [PATCH 2914/4131] make recompiler codepage handlers' writemap accesses alignment/endian aware Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3002 --- src/cpu/core_dynrec/cache.h | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index c543ed3f..52baff65 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -145,7 +145,7 @@ public: if (host_readb(hostmem+addr)==(Bit8u)val) return; host_writeb(hostmem+addr,val); // see if there's code where we are writing to - if (!*(Bit8u*)&write_map[addr]) { + 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 @@ -162,7 +162,7 @@ public: if (host_readw(hostmem+addr)==(Bit16u)val) return; host_writew(hostmem+addr,val); // see if there's code where we are writing to - if (!*(Bit16u*)&write_map[addr]) { + 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 @@ -171,7 +171,12 @@ public: 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){ @@ -179,7 +184,7 @@ public: if (host_readd(hostmem+addr)==(Bit32u)val) return; host_writed(hostmem+addr,val); // see if there's code where we are writing to - if (!*(Bit32u*)&write_map[addr]) { + 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 @@ -188,14 +193,19 @@ public: 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 (!*(Bit8u*)&write_map[addr]) { + if (!host_readb(&write_map[addr])) { if (!active_blocks) { // no blocks left in this page, still delay the page releasing a bit active_count--; @@ -219,7 +229,7 @@ public: addr&=4095; if (host_readw(hostmem+addr)==(Bit16u)val) return false; // see if there's code where we are writing to - if (!*(Bit16u*)&write_map[addr]) { + if (!host_readw(&write_map[addr])) { if (!active_blocks) { // no blocks left in this page, still delay the page releasing a bit active_count--; @@ -230,7 +240,12 @@ public: 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; @@ -243,7 +258,7 @@ public: addr&=4095; if (host_readd(hostmem+addr)==(Bit32u)val) return false; // see if there's code where we are writing to - if (!*(Bit32u*)&write_map[addr]) { + if (!host_readd(&write_map[addr])) { if (!active_blocks) { // no blocks left in this page, still delay the page releasing a bit active_count--; @@ -254,7 +269,12 @@ public: 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; From d0b4e12779630d8f16666f2c921a303bbf862ebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 29 Sep 2007 13:23:59 +0000 Subject: [PATCH 2915/4131] clean up memory access functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3003 --- include/paging.h | 74 +++++++---------------------- src/cpu/core_dyn_x86/decoder.h | 60 +++++++++++------------ src/cpu/core_dyn_x86/dyn_fpu_dh.h | 68 +++++++++++++------------- src/cpu/core_dyn_x86/risc_x86.h | 6 +-- src/cpu/core_dynrec/decoder_basic.h | 28 +++-------- src/hardware/memory.cpp | 34 ++++++------- 6 files changed, 108 insertions(+), 162 deletions(-) diff --git a/include/paging.h b/include/paging.h index e0b53d69..1faabb9e 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.25 2007-06-12 20:22:07 c2woody Exp $ */ +/* $Id: paging.h,v 1.26 2007-09-29 13:23:59 c2woody Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H @@ -169,10 +169,10 @@ Bit32u mem_unalignedreadd(PhysPt address); void mem_unalignedwritew(PhysPt address,Bit16u val); void mem_unalignedwrited(PhysPt address,Bit32u val); -bool mem_unalignedreadw_checked_x86(PhysPt address,Bit16u * val); -bool mem_unalignedreadd_checked_x86(PhysPt address,Bit32u * val); -bool mem_unalignedwritew_checked_x86(PhysPt address,Bit16u val); -bool mem_unalignedwrited_checked_x86(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); /* Special inlined memory reading/writing */ @@ -183,7 +183,7 @@ INLINE Bit8u mem_readb_inline(PhysPt address) { } INLINE Bit16u mem_readw_inline(PhysPt address) { - if (!(address & 1)) { + if ((address & 0xfff)<0xfff) { Bitu index=(address>>12); if (paging.tlb.read[index]) return host_readw(paging.tlb.read[index]+address); @@ -192,7 +192,7 @@ INLINE Bit16u mem_readw_inline(PhysPt address) { } INLINE Bit32u mem_readd_inline(PhysPt address) { - if (!(address & 3)) { + if ((address & 0xfff)<0xffd) { Bitu index=(address>>12); if (paging.tlb.read[index]) return host_readd(paging.tlb.read[index]+address); @@ -208,7 +208,7 @@ INLINE void mem_writeb_inline(PhysPt address,Bit8u val) { } INLINE void mem_writew_inline(PhysPt address,Bit16u val) { - if (!(address & 1)) { + if ((address & 0xfff)<0xfff) { Bitu index=(address>>12); if (paging.tlb.write[index]) host_writew(paging.tlb.write[index]+address,val); @@ -217,43 +217,6 @@ INLINE void mem_writew_inline(PhysPt address,Bit16u val) { } INLINE void mem_writed_inline(PhysPt address,Bit32u val) { - if (!(address & 3)) { - Bitu index=(address>>12); - - if (paging.tlb.write[index]) host_writed(paging.tlb.write[index]+address,val); - else paging.tlb.handler[index]->writed(address,val); - } else mem_unalignedwrited(address,val); -} - - -INLINE Bit16u mem_readw_dyncorex86(PhysPt address) { - if ((address & 0xfff)<0xfff) { - Bitu index=(address>>12); - - if (paging.tlb.read[index]) return host_readw(paging.tlb.read[index]+address); - else return (Bit16u)paging.tlb.handler[index]->readw(address); - } else return mem_unalignedreadw(address); -} - -INLINE Bit32u mem_readd_dyncorex86(PhysPt address) { - if ((address & 0xfff)<0xffd) { - Bitu index=(address>>12); - - if (paging.tlb.read[index]) return host_readd(paging.tlb.read[index]+address); - else return paging.tlb.handler[index]->readd(address); - } else return mem_unalignedreadd(address); -} - -INLINE void mem_writew_dyncorex86(PhysPt address,Bit16u val) { - if ((address & 0xfff)<0xfff) { - Bitu index=(address>>12); - - if (paging.tlb.write[index]) host_writew(paging.tlb.write[index]+address,val); - else paging.tlb.handler[index]->writew(address,val); - } else mem_unalignedwritew(address,val); -} - -INLINE void mem_writed_dyncorex86(PhysPt address,Bit32u val) { if ((address & 0xfff)<0xffd) { Bitu index=(address>>12); @@ -263,7 +226,7 @@ INLINE void mem_writed_dyncorex86(PhysPt address,Bit32u val) { } -INLINE bool mem_readb_checked_x86(PhysPt address, Bit8u * val) { +INLINE bool mem_readb_checked(PhysPt address, Bit8u * val) { Bitu index=(address>>12); if (paging.tlb.read[index]) { *val=host_readb(paging.tlb.read[index]+address); @@ -277,7 +240,7 @@ INLINE bool mem_readb_checked_x86(PhysPt address, Bit8u * val) { } } -INLINE bool mem_readw_checked_x86(PhysPt address, Bit16u * val) { +INLINE bool mem_readw_checked(PhysPt address, Bit16u * val) { if ((address & 0xfff)<0xfff) { Bitu index=(address>>12); if (paging.tlb.read[index]) { @@ -290,11 +253,10 @@ INLINE bool mem_readw_checked_x86(PhysPt address, Bit16u * val) { *val=(Bit16u)uval; return retval; } - } else return mem_unalignedreadw_checked_x86(address, val); + } else return mem_unalignedreadw_checked(address, val); } - -INLINE bool mem_readd_checked_x86(PhysPt address, Bit32u * val) { +INLINE bool mem_readd_checked(PhysPt address, Bit32u * val) { if ((address & 0xfff)<0xffd) { Bitu index=(address>>12); if (paging.tlb.read[index]) { @@ -307,10 +269,10 @@ INLINE bool mem_readd_checked_x86(PhysPt address, Bit32u * val) { *val=(Bit32u)uval; return retval; } - } else return mem_unalignedreadd_checked_x86(address, val); + } else return mem_unalignedreadd_checked(address, val); } -INLINE bool mem_writeb_checked_x86(PhysPt address,Bit8u val) { +INLINE bool mem_writeb_checked(PhysPt address,Bit8u val) { Bitu index=(address>>12); if (paging.tlb.write[index]) { host_writeb(paging.tlb.write[index]+address,val); @@ -318,24 +280,24 @@ INLINE bool mem_writeb_checked_x86(PhysPt address,Bit8u val) { } else return paging.tlb.handler[index]->writeb_checked(address,val); } -INLINE bool mem_writew_checked_x86(PhysPt address,Bit16u val) { +INLINE bool mem_writew_checked(PhysPt address,Bit16u val) { if ((address & 0xfff)<0xfff) { Bitu index=(address>>12); if (paging.tlb.write[index]) { host_writew(paging.tlb.write[index]+address,val); return false; } else return paging.tlb.handler[index]->writew_checked(address,val); - } else return mem_unalignedwritew_checked_x86(address,val); + } else return mem_unalignedwritew_checked(address,val); } -INLINE bool mem_writed_checked_x86(PhysPt address,Bit32u val) { +INLINE bool mem_writed_checked(PhysPt address,Bit32u val) { if ((address & 0xfff)<0xffd) { Bitu index=(address>>12); if (paging.tlb.write[index]) { host_writed(paging.tlb.write[index]+address,val); return false; } else return paging.tlb.handler[index]->writed_checked(address,val); - } else return mem_unalignedwrited_checked_x86(address,val); + } else return mem_unalignedwrited_checked(address,val); } diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index d9456f4f..e36b27b5 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -53,7 +53,7 @@ static struct DynDecode { static bool MakeCodePage(Bitu lin_addr,CodePageHandler * &cph) { Bit8u rdval; //Ensure page contains memory: - if (GCC_UNLIKELY(mem_readb_checked_x86(lin_addr,&rdval))) return true; + if (GCC_UNLIKELY(mem_readb_checked(lin_addr,&rdval))) return true; Bitu lin_page=lin_addr >> 12; PageHandler * handler=paging.tlb.handler[lin_page]; if (handler->flags & PFLAG_HASCODE) { @@ -386,52 +386,52 @@ static void dyn_fill_blocks(void) { #if !defined(X86_INLINED_MEMACCESS) static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { gen_protectflags(); - gen_call_function((void *)&mem_readb_checked_x86,"%Dd%Id",addr,&core_dyn.readdata); + gen_call_function((void *)&mem_readb_checked,"%Dd%Id",addr,&core_dyn.readdata); dyn_check_bool_exception_al(); gen_mov_host(&core_dyn.readdata,dst,1,high); } static void dyn_write_byte(DynReg * addr,DynReg * val,Bitu high) { gen_protectflags(); - if (high) gen_call_function((void *)&mem_writeb_checked_x86,"%Dd%Dh",addr,val); - else gen_call_function((void *)&mem_writeb_checked_x86,"%Dd%Dd",addr,val); + if (high) gen_call_function((void *)&mem_writeb_checked,"%Dd%Dh",addr,val); + else gen_call_function((void *)&mem_writeb_checked,"%Dd%Dd",addr,val); dyn_check_bool_exception_al(); } static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) { gen_protectflags(); - if (dword) gen_call_function((void *)&mem_readd_checked_x86,"%Dd%Id",addr,&core_dyn.readdata); - else gen_call_function((void *)&mem_readw_checked_x86,"%Dd%Id",addr,&core_dyn.readdata); + if (dword) gen_call_function((void *)&mem_readd_checked,"%Dd%Id",addr,&core_dyn.readdata); + else gen_call_function((void *)&mem_readw_checked,"%Dd%Id",addr,&core_dyn.readdata); dyn_check_bool_exception_al(); gen_mov_host(&core_dyn.readdata,dst,dword?4:2); } static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { gen_protectflags(); - if (dword) gen_call_function((void *)&mem_writed_checked_x86,"%Dd%Dd",addr,val); - else gen_call_function((void *)&mem_writew_checked_x86,"%Dd%Dd",addr,val); + if (dword) gen_call_function((void *)&mem_writed_checked,"%Dd%Dd",addr,val); + else gen_call_function((void *)&mem_writew_checked,"%Dd%Dd",addr,val); dyn_check_bool_exception_al(); } static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) { gen_protectflags(); - gen_call_function((void *)&mem_readb_checked_x86,"%Ddr%Id",addr,&core_dyn.readdata); + gen_call_function((void *)&mem_readb_checked,"%Ddr%Id",addr,&core_dyn.readdata); dyn_check_bool_exception_al(); gen_mov_host(&core_dyn.readdata,dst,1,high); } static void dyn_write_byte_release(DynReg * addr,DynReg * val,Bitu high) { gen_protectflags(); - if (high) gen_call_function((void *)&mem_writeb_checked_x86,"%Ddr%Dh",addr,val); - else gen_call_function((void *)&mem_writeb_checked_x86,"%Ddr%Dd",addr,val); + if (high) gen_call_function((void *)&mem_writeb_checked,"%Ddr%Dh",addr,val); + else gen_call_function((void *)&mem_writeb_checked,"%Ddr%Dd",addr,val); dyn_check_bool_exception_al(); } static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) { gen_protectflags(); - if (dword) gen_call_function((void *)&mem_readd_checked_x86,"%Ddr%Id",addr,&core_dyn.readdata); - else gen_call_function((void *)&mem_readw_checked_x86,"%Ddr%Id",addr,&core_dyn.readdata); + if (dword) gen_call_function((void *)&mem_readd_checked,"%Ddr%Id",addr,&core_dyn.readdata); + else gen_call_function((void *)&mem_readw_checked,"%Ddr%Id",addr,&core_dyn.readdata); dyn_check_bool_exception_al(); gen_mov_host(&core_dyn.readdata,dst,dword?4:2); } static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) { gen_protectflags(); - if (dword) gen_call_function((void *)&mem_writed_checked_x86,"%Ddr%Dd",addr,val); - else gen_call_function((void *)&mem_writew_checked_x86,"%Ddr%Dd",addr,val); + if (dword) gen_call_function((void *)&mem_writed_checked,"%Ddr%Dd",addr,val); + else gen_call_function((void *)&mem_writew_checked,"%Ddr%Dd",addr,val); dyn_check_bool_exception_al(); } @@ -559,7 +559,7 @@ bool mem_readd_checked_x86x(PhysPt address) { core_dyn.readdata=(Bit32u)uval; return retval; } - } else return mem_unalignedreadd_checked_x86(address, &core_dyn.readdata); + } else return mem_unalignedreadd_checked(address, &core_dyn.readdata); } static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) { @@ -602,7 +602,7 @@ static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) { gen_fill_jump(jmp_loc); } else { gen_protectflags(); - gen_call_function((void *)&mem_readw_checked_x86,"%Dd%Id",addr,&core_dyn.readdata); + gen_call_function((void *)&mem_readw_checked,"%Dd%Id",addr,&core_dyn.readdata); dyn_check_bool_exception_al(); gen_mov_host(&core_dyn.readdata,dst,2); } @@ -648,7 +648,7 @@ static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) { gen_fill_jump(jmp_loc); } else { gen_protectflags(); - gen_call_function((void *)&mem_readw_checked_x86,"%Ddr%Id",addr,&core_dyn.readdata); + gen_call_function((void *)&mem_readw_checked,"%Ddr%Id",addr,&core_dyn.readdata); dyn_check_bool_exception_al(); gen_mov_host(&core_dyn.readdata,dst,2); } @@ -709,7 +709,7 @@ static void dyn_write_byte(DynReg * addr,DynReg * val,bool high) { cache_addb(0x50); // push eax if (GCC_UNLIKELY(high)) cache_addw(0xe086+((genreg->index+(genreg->index<<3))<<8)); cache_addb(0xe8); - cache_addd(((Bit32u)&mem_writeb_checked_x86) - (Bit32u)cache.pos-4); + cache_addd(((Bit32u)&mem_writeb_checked) - (Bit32u)cache.pos-4); cache_addw(0xc483); // add esp,8 cache_addb(0x08); cache_addw(0x012c); // sub al,1 @@ -748,7 +748,7 @@ static void dyn_write_byte_release(DynReg * addr,DynReg * val,bool high) { cache_addb(0x50); // push eax if (GCC_UNLIKELY(high)) cache_addw(0xe086+((genreg->index+(genreg->index<<3))<<8)); cache_addb(0xe8); - cache_addd(((Bit32u)&mem_writeb_checked_x86) - (Bit32u)cache.pos-4); + cache_addd(((Bit32u)&mem_writeb_checked) - (Bit32u)cache.pos-4); cache_addw(0xc483); // add esp,8 cache_addb(0x08); cache_addw(0x012c); // sub al,1 @@ -792,7 +792,7 @@ static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { cache_addb(0x50+genreg->index); cache_addb(0x50); // push eax cache_addb(0xe8); - cache_addd(((Bit32u)&mem_writed_checked_x86) - (Bit32u)cache.pos-4); + cache_addd(((Bit32u)&mem_writed_checked) - (Bit32u)cache.pos-4); cache_addw(0xc483); // add esp,8 cache_addb(0x08); cache_addw(0x012c); // sub al,1 @@ -807,7 +807,7 @@ static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { gen_fill_jump(jmp_loc); } else { gen_protectflags(); - gen_call_function((void *)&mem_writew_checked_x86,"%Dd%Dd",addr,val); + gen_call_function((void *)&mem_writew_checked,"%Dd%Dd",addr,val); dyn_check_bool_exception_al(); } } @@ -841,7 +841,7 @@ static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) { cache_addb(0x50+genreg->index); cache_addb(0x50); // push eax cache_addb(0xe8); - cache_addd(((Bit32u)&mem_writed_checked_x86) - (Bit32u)cache.pos-4); + cache_addd(((Bit32u)&mem_writed_checked) - (Bit32u)cache.pos-4); cache_addw(0xc483); // add esp,8 cache_addb(0x08); cache_addw(0x012c); // sub al,1 @@ -856,7 +856,7 @@ static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) { gen_fill_jump(jmp_loc); } else { gen_protectflags(); - gen_call_function((void *)&mem_writew_checked_x86,"%Ddr%Dd",addr,val); + gen_call_function((void *)&mem_writew_checked,"%Ddr%Dd",addr,val); dyn_check_bool_exception_al(); } } @@ -888,10 +888,10 @@ static void dyn_push(DynReg * dynreg) { gen_dop_word(DOP_OR,true,DREG(NEWESP),DREG(STACK)); gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); if (decode.big_op) { - gen_call_function((void *)&mem_writed_checked_x86,"%Drd%Dd",DREG(STACK),dynreg); + gen_call_function((void *)&mem_writed_checked,"%Drd%Dd",DREG(STACK),dynreg); } else { //Can just push the whole 32-bit word as operand - gen_call_function((void *)&mem_writew_checked_x86,"%Drd%Dd",DREG(STACK),dynreg); + gen_call_function((void *)&mem_writew_checked,"%Drd%Dd",DREG(STACK),dynreg); } dyn_check_bool_exception_al(); /* everything was ok, change register now */ @@ -906,9 +906,9 @@ static void dyn_pop(DynReg * dynreg,bool checked=true) { gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); if (checked) { if (decode.big_op) { - gen_call_function((void *)&mem_readd_checked_x86,"%Drd%Id",DREG(STACK),&core_dyn.readdata); + gen_call_function((void *)&mem_readd_checked,"%Drd%Id",DREG(STACK),&core_dyn.readdata); } else { - gen_call_function((void *)&mem_readw_checked_x86,"%Drd%Id",DREG(STACK),&core_dyn.readdata); + gen_call_function((void *)&mem_readw_checked,"%Drd%Id",DREG(STACK),&core_dyn.readdata); } dyn_check_bool_exception_al(); gen_mov_host(&core_dyn.readdata,dynreg,decode.big_op?4:2); @@ -1654,8 +1654,8 @@ static void dyn_pop_ev(void) { if (decode.modrm.mod<3) { dyn_fill_ea(); // dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); - if (decode.big_op) gen_call_function((void *)&mem_writed_dyncorex86,"%Ddr%Dd",DREG(EA),DREG(TMPW)); - else gen_call_function((void *)&mem_writew_dyncorex86,"%Ddr%Dd",DREG(EA),DREG(TMPW)); + if (decode.big_op) gen_call_function((void *)&mem_writed_inline,"%Ddr%Dd",DREG(EA),DREG(TMPW)); + else gen_call_function((void *)&mem_writew_inline,"%Ddr%Dd",DREG(EA),DREG(TMPW)); } else { gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],DREG(TMPW)); } diff --git a/src/cpu/core_dyn_x86/dyn_fpu_dh.h b/src/cpu/core_dyn_x86/dyn_fpu_dh.h index a769e3dc..5a6ca5f7 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu_dh.h +++ b/src/cpu/core_dyn_x86/dyn_fpu_dh.h @@ -16,47 +16,47 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dyn_fpu_dh.h,v 1.4 2007-06-14 17:47:24 c2woody Exp $ */ +/* $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_dyncorex86(addr); + dyn_dh_fpu.temp.m1 = (Bit32u)mem_readw(addr); } static void FPU_FST_16(PhysPt addr) { - mem_writew_dyncorex86(addr,(Bit16u)dyn_dh_fpu.temp.m1); + mem_writew(addr,(Bit16u)dyn_dh_fpu.temp.m1); } static void FPU_FLD_32(PhysPt addr) { - dyn_dh_fpu.temp.m1 = mem_readd_dyncorex86(addr); + dyn_dh_fpu.temp.m1 = mem_readd(addr); } static void FPU_FST_32(PhysPt addr) { - mem_writed_dyncorex86(addr,dyn_dh_fpu.temp.m1); + mem_writed(addr,dyn_dh_fpu.temp.m1); } static void FPU_FLD_64(PhysPt addr) { - dyn_dh_fpu.temp.m1 = mem_readd_dyncorex86(addr); - dyn_dh_fpu.temp.m2 = mem_readd_dyncorex86(addr+4); + 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_dyncorex86(addr,dyn_dh_fpu.temp.m1); - mem_writed_dyncorex86(addr+4,dyn_dh_fpu.temp.m2); + 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_dyncorex86(addr); - dyn_dh_fpu.temp.m2 = mem_readd_dyncorex86(addr+4); - dyn_dh_fpu.temp.m3 = mem_readw_dyncorex86(addr+8); + 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_dyncorex86(addr,dyn_dh_fpu.temp.m1); - mem_writed_dyncorex86(addr+4,dyn_dh_fpu.temp.m2); - mem_writew_dyncorex86(addr+8,dyn_dh_fpu.temp.m3); + 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){ @@ -74,35 +74,35 @@ static void FPU_FNINIT_DH(void){ static void FPU_FSTENV_DH(PhysPt addr){ if(!cpu.code.big) { - mem_writew_dyncorex86(addr+0,(Bit16u)dyn_dh_fpu.cw); - mem_writew_dyncorex86(addr+2,(Bit16u)dyn_dh_fpu.temp.m2); - mem_writew_dyncorex86(addr+4,dyn_dh_fpu.temp.m3); + 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_dyncorex86(addr+0,dyn_dh_fpu.temp.m1); - mem_writew_dyncorex86(addr+0,(Bit16u)dyn_dh_fpu.cw); - mem_writed_dyncorex86(addr+4,dyn_dh_fpu.temp.m2); - mem_writed_dyncorex86(addr+8,dyn_dh_fpu.temp.m3); + 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_dyncorex86(addr); + 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_dyncorex86(addr+2); - dyn_dh_fpu.temp.m3 = mem_readw_dyncorex86(addr+4); + 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_dyncorex86(addr); - dyn_dh_fpu.temp.m1 = mem_readd_dyncorex86(addr)|0x3f; - dyn_dh_fpu.temp.m2 = mem_readd_dyncorex86(addr+4); - dyn_dh_fpu.temp.m3 = mem_readw_dyncorex86(addr+8); - dyn_dh_fpu.temp.d1 = mem_readw_dyncorex86(addr+10); + 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_dyncorex86(addr,(Bit16u)dyn_dh_fpu.cw); + 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]); @@ -118,7 +118,7 @@ static void FPU_FSAVE_DH(PhysPt addr){ 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_dyncorex86(addr,(Bit16u)dyn_dh_fpu.cw); + 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]); } @@ -126,7 +126,7 @@ static void FPU_FSAVE_DH(PhysPt addr){ static void FPU_FRSTOR_DH(PhysPt addr){ if (!cpu.code.big) { - dyn_dh_fpu.cw = (Bit32u)mem_readw_dyncorex86(addr); + 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++); @@ -143,7 +143,7 @@ static void FPU_FRSTOR_DH(PhysPt 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_dyncorex86(addr); + 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; } diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 08ea139e..709cf6b6 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -925,9 +925,9 @@ static void gen_call_write(DynReg * dr,Bit32u val,Bitu write_size) { /* Do the actual call to the procedure */ cache_addb(0xe8); switch (write_size) { - case 1: cache_addd((Bit32u)mem_writeb_checked_x86 - (Bit32u)cache.pos-4); break; - case 2: cache_addd((Bit32u)mem_writew_checked_x86 - (Bit32u)cache.pos-4); break; - case 4: cache_addd((Bit32u)mem_writed_checked_x86 - (Bit32u)cache.pos-4); break; + case 1: cache_addd((Bit32u)mem_writeb_checked - (Bit32u)cache.pos-4); break; + case 2: cache_addd((Bit32u)mem_writew_checked - (Bit32u)cache.pos-4); break; + case 4: cache_addd((Bit32u)mem_writed_checked - (Bit32u)cache.pos-4); break; default: IllegalOption("gen_call_write"); } diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index b8f515bb..198c4124 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -130,7 +130,7 @@ static struct DynDecode { static bool MakeCodePage(Bitu lin_addr,CodePageHandlerDynRec * &cph) { Bit8u rdval; //Ensure page contains memory: - if (GCC_UNLIKELY(mem_readb_checked_x86(lin_addr,&rdval))) return true; + if (GCC_UNLIKELY(mem_readb_checked(lin_addr,&rdval))) return true; Bitu lin_page=lin_addr >> 12; @@ -589,12 +589,8 @@ bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) { bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) DRC_FC; bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) { -#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) - if (!(address & 1)) { -#else if ((address & 0xfff)<0xfff) { -#endif - Bitu index=(address>>12); + Bitu index=(address>>12); if (paging.tlb.read[index]) { *((Bit16u*)(&core_dynrec.readdata))=host_readw(paging.tlb.read[index]+address); return false; @@ -605,16 +601,12 @@ bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) { *((Bit16u*)(&core_dynrec.readdata))=(Bit16u)uval; return retval; } - } else return mem_unalignedreadw_checked_x86(address, ((Bit16u*)(&core_dynrec.readdata))); + } else return mem_unalignedreadw_checked(address, ((Bit16u*)(&core_dynrec.readdata))); } bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) DRC_FC; bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) { -#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) - if (!(address & 3)) { -#else if ((address & 0xfff)<0xffd) { -#endif Bitu index=(address>>12); if (paging.tlb.read[index]) { *((Bit32u*)(&core_dynrec.readdata))=host_readd(paging.tlb.read[index]+address); @@ -626,37 +618,29 @@ bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) { *((Bit32u*)(&core_dynrec.readdata))=(Bit32u)uval; return retval; } - } else return mem_unalignedreadd_checked_x86(address, ((Bit32u*)(&core_dynrec.readdata))); + } else return mem_unalignedreadd_checked(address, ((Bit32u*)(&core_dynrec.readdata))); } bool DRC_CALL_CONV mem_writew_checked_drc(PhysPt address,Bit16u val) DRC_FC; bool DRC_CALL_CONV mem_writew_checked_drc(PhysPt address,Bit16u val) { -#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) - if (!(address & 1)) { -#else if ((address & 0xfff)<0xfff) { -#endif Bitu index=(address>>12); if (paging.tlb.write[index]) { host_writew(paging.tlb.write[index]+address,val); return false; } else return paging.tlb.handler[index]->writew_checked(address,val); - } else return mem_unalignedwritew_checked_x86(address,val); + } else return mem_unalignedwritew_checked(address,val); } bool DRC_CALL_CONV mem_writed_checked_drc(PhysPt address,Bit32u val) DRC_FC; bool DRC_CALL_CONV mem_writed_checked_drc(PhysPt address,Bit32u val) { -#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) - if (!(address & 3)) { -#else if ((address & 0xfff)<0xffd) { -#endif Bitu index=(address>>12); if (paging.tlb.write[index]) { host_writed(paging.tlb.write[index]+address,val); return false; } else return paging.tlb.handler[index]->writed_checked(address,val); - } else return mem_unalignedwrited_checked_x86(address,val); + } else return mem_unalignedwrited_checked(address,val); } diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index b0769130..99eb482e 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: memory.cpp,v 1.51 2007-07-19 18:58:39 c2woody Exp $ */ +/* $Id: memory.cpp,v 1.52 2007-09-29 13:23:59 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -447,35 +447,35 @@ void mem_unalignedwrited(PhysPt address,Bit32u val) { } -bool mem_unalignedreadw_checked_x86(PhysPt address, Bit16u * val) { +bool mem_unalignedreadw_checked(PhysPt address, Bit16u * val) { Bit8u rval1,rval2; - if (mem_readb_checked_x86(address+0, &rval1)) return true; - if (mem_readb_checked_x86(address+1, &rval2)) return true; + if (mem_readb_checked(address+0, &rval1)) return true; + if (mem_readb_checked(address+1, &rval2)) return true; *val=(Bit16u)(((Bit8u)rval1) | (((Bit8u)rval2) << 8)); return false; } -bool mem_unalignedreadd_checked_x86(PhysPt address, Bit32u * val) { +bool mem_unalignedreadd_checked(PhysPt address, Bit32u * val) { Bit8u rval1,rval2,rval3,rval4; - if (mem_readb_checked_x86(address+0, &rval1)) return true; - if (mem_readb_checked_x86(address+1, &rval2)) return true; - if (mem_readb_checked_x86(address+2, &rval3)) return true; - if (mem_readb_checked_x86(address+3, &rval4)) return true; + if (mem_readb_checked(address+0, &rval1)) return true; + if (mem_readb_checked(address+1, &rval2)) return true; + if (mem_readb_checked(address+2, &rval3)) return true; + if (mem_readb_checked(address+3, &rval4)) return true; *val=(Bit32u)(((Bit8u)rval1) | (((Bit8u)rval2) << 8) | (((Bit8u)rval3) << 16) | (((Bit8u)rval4) << 24)); return false; } -bool mem_unalignedwritew_checked_x86(PhysPt address,Bit16u val) { - if (mem_writeb_checked_x86(address,(Bit8u)(val & 0xff))) return true;val>>=8; - if (mem_writeb_checked_x86(address+1,(Bit8u)(val & 0xff))) return true; +bool mem_unalignedwritew_checked(PhysPt address,Bit16u val) { + if (mem_writeb_checked(address,(Bit8u)(val & 0xff))) return true;val>>=8; + if (mem_writeb_checked(address+1,(Bit8u)(val & 0xff))) return true; return false; } -bool mem_unalignedwrited_checked_x86(PhysPt address,Bit32u val) { - if (mem_writeb_checked_x86(address,(Bit8u)(val & 0xff))) return true;val>>=8; - if (mem_writeb_checked_x86(address+1,(Bit8u)(val & 0xff))) return true;val>>=8; - if (mem_writeb_checked_x86(address+2,(Bit8u)(val & 0xff))) return true;val>>=8; - if (mem_writeb_checked_x86(address+3,(Bit8u)(val & 0xff))) return true; +bool mem_unalignedwrited_checked(PhysPt address,Bit32u val) { + if (mem_writeb_checked(address,(Bit8u)(val & 0xff))) return true;val>>=8; + if (mem_writeb_checked(address+1,(Bit8u)(val & 0xff))) return true;val>>=8; + if (mem_writeb_checked(address+2,(Bit8u)(val & 0xff))) return true;val>>=8; + if (mem_writeb_checked(address+3,(Bit8u)(val & 0xff))) return true; return false; } From c6df37a834684c6e1f41617eb9a457b87c072598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 30 Sep 2007 14:10:08 +0000 Subject: [PATCH 2916/4131] simplify memory checking handlers a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3004 --- include/paging.h | 32 +++++++---------------------- src/cpu/core_dyn_x86/decoder.h | 25 ++++++++-------------- src/cpu/core_dynrec/decoder_basic.h | 22 +++----------------- src/cpu/paging.cpp | 18 ++++++++-------- 4 files changed, 27 insertions(+), 70 deletions(-) diff --git a/include/paging.h b/include/paging.h index 1faabb9e..29afcce8 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.26 2007-09-29 13:23:59 c2woody Exp $ */ +/* $Id: paging.h,v 1.27 2007-09-30 14:10:04 c2woody Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H @@ -57,9 +57,9 @@ public: 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, Bitu * val); - virtual bool readw_checked(PhysPt addr, Bitu * val); - virtual bool readd_checked(PhysPt addr, Bitu * val); + 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); @@ -231,13 +231,7 @@ INLINE bool mem_readb_checked(PhysPt address, Bit8u * val) { if (paging.tlb.read[index]) { *val=host_readb(paging.tlb.read[index]+address); return false; - } else { - Bitu uval; - bool retval; - retval=paging.tlb.handler[index]->readb_checked(address, &uval); - *val=(Bit8u)uval; - return retval; - } + } else return paging.tlb.handler[index]->readb_checked(address, val); } INLINE bool mem_readw_checked(PhysPt address, Bit16u * val) { @@ -246,13 +240,7 @@ INLINE bool mem_readw_checked(PhysPt address, Bit16u * val) { if (paging.tlb.read[index]) { *val=host_readw(paging.tlb.read[index]+address); return false; - } else { - Bitu uval; - bool retval; - retval=paging.tlb.handler[index]->readw_checked(address, &uval); - *val=(Bit16u)uval; - return retval; - } + } else return paging.tlb.handler[index]->readw_checked(address, val); } else return mem_unalignedreadw_checked(address, val); } @@ -262,13 +250,7 @@ INLINE bool mem_readd_checked(PhysPt address, Bit32u * val) { if (paging.tlb.read[index]) { *val=host_readd(paging.tlb.read[index]+address); return false; - } else { - Bitu uval; - bool retval; - retval=paging.tlb.handler[index]->readd_checked(address, &uval); - *val=(Bit32u)uval; - return retval; - } + } else return paging.tlb.handler[index]->readd_checked(address, val); } else return mem_unalignedreadd_checked(address, val); } diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index e36b27b5..6122415c 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -461,13 +461,8 @@ static void dyn_read_intro(DynReg * addr,bool release_addr=true) { cache_addw(0xc18b); // mov eax,ecx } -bool mem_readb_checked_x86x(PhysPt address) { - Bitu index=(address>>12); - Bitu uval; - bool retval; - retval=paging.tlb.handler[index]->readb_checked(address, &uval); - core_dyn.readdata=(Bit8u)uval; - return retval; +bool mem_readb_checked_dcx86(PhysPt address) { + return paging.tlb.handler[address>>12]->readb_checked(address, (Bit8u*)(&core_dyn.readdata)); } static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { @@ -489,7 +484,7 @@ static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { gen_fill_branch(je_loc); cache_addb(0x51); // push ecx cache_addb(0xe8); - cache_addd(((Bit32u)&mem_readb_checked_x86x) - (Bit32u)cache.pos-4); + cache_addd(((Bit32u)&mem_readb_checked_dcx86) - (Bit32u)cache.pos-4); cache_addw(0xc483); // add esp,4 cache_addb(0x04); cache_addw(0x012c); // sub al,1 @@ -527,7 +522,7 @@ static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) { gen_fill_branch(je_loc); cache_addb(0x51); // push ecx cache_addb(0xe8); - cache_addd(((Bit32u)&mem_readb_checked_x86x) - (Bit32u)cache.pos-4); + cache_addd(((Bit32u)&mem_readb_checked_dcx86) - (Bit32u)cache.pos-4); cache_addw(0xc483); // add esp,4 cache_addb(0x04); cache_addw(0x012c); // sub al,1 @@ -546,18 +541,14 @@ static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) { dst->flags|=DYNFLG_CHANGED; } -bool mem_readd_checked_x86x(PhysPt address) { +bool mem_readd_checked_dcx86(PhysPt address) { if ((address & 0xfff)<0xffd) { Bitu index=(address>>12); if (paging.tlb.read[index]) { core_dyn.readdata=host_readd(paging.tlb.read[index]+address); return false; } else { - Bitu uval; - bool retval; - retval=paging.tlb.handler[index]->readd_checked(address, &uval); - core_dyn.readdata=(Bit32u)uval; - return retval; + return paging.tlb.handler[index]->readd_checked(address, &core_dyn.readdata); } } else return mem_unalignedreadd_checked(address, &core_dyn.readdata); } @@ -589,7 +580,7 @@ static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) { gen_fill_branch(je_loc); cache_addb(0x51); // push ecx cache_addb(0xe8); - cache_addd(((Bit32u)&mem_readd_checked_x86x) - (Bit32u)cache.pos-4); + cache_addd(((Bit32u)&mem_readd_checked_dcx86) - (Bit32u)cache.pos-4); cache_addw(0xc483); // add esp,4 cache_addb(0x04); cache_addw(0x012c); // sub al,1 @@ -635,7 +626,7 @@ static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) { gen_fill_branch(je_loc); cache_addb(0x51); // push ecx cache_addb(0xe8); - cache_addd(((Bit32u)&mem_readd_checked_x86x) - (Bit32u)cache.pos-4); + cache_addd(((Bit32u)&mem_readd_checked_dcx86) - (Bit32u)cache.pos-4); cache_addw(0xc483); // add esp,4 cache_addb(0x04); cache_addw(0x012c); // sub al,1 diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index 198c4124..3e684cd1 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -570,11 +570,7 @@ bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) { *((Bit8u*)(&core_dynrec.readdata))=host_readb(paging.tlb.read[index]+address); return false; } else { - Bitu uval; - bool retval; - retval=paging.tlb.handler[index]->readb_checked(address, &uval); - *((Bit8u*)(&core_dynrec.readdata))=(Bit8u)uval; - return retval; + return paging.tlb.handler[index]->readb_checked(address, (Bit8u*)(&core_dynrec.readdata)); } } @@ -594,13 +590,7 @@ bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) { if (paging.tlb.read[index]) { *((Bit16u*)(&core_dynrec.readdata))=host_readw(paging.tlb.read[index]+address); return false; - } else { - Bitu uval; - bool retval; - retval=paging.tlb.handler[index]->readw_checked(address, &uval); - *((Bit16u*)(&core_dynrec.readdata))=(Bit16u)uval; - return retval; - } + } else return paging.tlb.handler[index]->readw_checked(address, (Bit16u*)(&core_dynrec.readdata)); } else return mem_unalignedreadw_checked(address, ((Bit16u*)(&core_dynrec.readdata))); } @@ -611,13 +601,7 @@ bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) { if (paging.tlb.read[index]) { *((Bit32u*)(&core_dynrec.readdata))=host_readd(paging.tlb.read[index]+address); return false; - } else { - Bitu uval; - bool retval; - retval=paging.tlb.handler[index]->readd_checked(address, &uval); - *((Bit32u*)(&core_dynrec.readdata))=(Bit32u)uval; - return retval; - } + } else return paging.tlb.handler[index]->readd_checked(address, (Bit32u*)(&core_dynrec.readdata)); } else return mem_unalignedreadd_checked(address, ((Bit32u*)(&core_dynrec.readdata))); } diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 9a0462c6..32857009 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -75,14 +75,14 @@ HostPt PageHandler::GetHostWritePt(Bitu /*phys_page*/) { return 0; } -bool PageHandler::readb_checked(PhysPt addr, Bitu * val) { - *val=readb(addr); return false; +bool PageHandler::readb_checked(PhysPt addr, Bit8u * val) { + *val=(Bit8u)readb(addr); return false; } -bool PageHandler::readw_checked(PhysPt addr, Bitu * val) { - *val=readw(addr); return false; +bool PageHandler::readw_checked(PhysPt addr, Bit16u * val) { + *val=(Bit16u)readw(addr); return false; } -bool PageHandler::readd_checked(PhysPt addr, Bitu * val) { - *val=readd(addr); return false; +bool PageHandler::readd_checked(PhysPt addr, Bit32u * val) { + *val=(Bit32u)readd(addr); return false; } bool PageHandler::writeb_checked(PhysPt addr,Bitu val) { writeb(addr,val); return false; @@ -185,19 +185,19 @@ public: InitPage(addr,true); mem_writed(addr,val); } - bool readb_checked(PhysPt addr, Bitu * val) { + bool readb_checked(PhysPt addr, Bit8u * val) { if (InitPage(addr,false,true)) { *val=mem_readb(addr); return false; } else return true; } - bool readw_checked(PhysPt addr, Bitu * val) { + bool readw_checked(PhysPt addr, Bit16u * val) { if (InitPage(addr,false,true)){ *val=mem_readw(addr); return false; } else return true; } - bool readd_checked(PhysPt addr, Bitu * val) { + bool readd_checked(PhysPt addr, Bit32u * val) { if (InitPage(addr,false,true)) { *val=mem_readd(addr); return false; From 138adbcf396f5364da0b9648481b60305660921a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 1 Oct 2007 20:31:16 +0000 Subject: [PATCH 2917/4131] swap parameter loading to work around register clashing for x86_64 (drc dynamic fpu) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3005 --- src/cpu/core_dynrec/dyn_fpu.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cpu/core_dynrec/dyn_fpu.h b/src/cpu/core_dynrec/dyn_fpu.h index 68c06703..a75d07f3 100644 --- a/src/cpu/core_dynrec/dyn_fpu.h +++ b/src/cpu/core_dynrec/dyn_fpu.h @@ -289,8 +289,8 @@ static void dyn_fpu_esc1(){ switch(decode.modrm.reg){ case 0x00: /* FLD float*/ gen_call_function_raw((void*)&FPU_PREP_PUSH); - gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); 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 */ @@ -532,8 +532,8 @@ static void dyn_fpu_esc5(){ case 0x07: /*FNSTSW */ 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_OP2,(void*)(&fpu.sw),true); 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: @@ -633,8 +633,8 @@ static void dyn_fpu_esc7(){ switch(decode.modrm.reg){ case 0x00: /* FILD Bit16s */ gen_call_function_raw((void*)&FPU_PREP_PUSH); - gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); 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: @@ -651,14 +651,14 @@ static void dyn_fpu_esc7(){ 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); - dyn_fill_ea(FC_OP1); 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); - dyn_fill_ea(FC_OP1); gen_call_function_RR((void*)&FPU_FLD_I64,FC_OP1,FC_OP2); break; case 0x06: /* FBSTP packed BCD */ From 733a0244db9d0408d0e4c3a8e4ae4eee96f827a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 3 Oct 2007 20:23:37 +0000 Subject: [PATCH 2918/4131] fix usermode page access privilege check (fixes dck) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3006 --- src/cpu/paging.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 32857009..15f01659 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -264,7 +264,8 @@ public: E_Exit("Pagefault didn't correct page"); } if (cpu.cpl==3) { - if ((entry.block.us==0) || (table.block.us==0) && (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { +// if (((entry.block.us==0) || (table.block.us==0)) || (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { + if (((entry.block.us==0) && (table.block.us==0)) || (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); if (check_only) { paging.cr2=lin_addr; From 72199985fa30cc61d744338db4f7d6e31f8e1564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 5 Oct 2007 17:45:53 +0000 Subject: [PATCH 2919/4131] add banked tlb (crazyc) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3007 --- include/paging.h | 184 +++++++++++++++++++--------- src/cpu/core_dyn_x86.cpp | 5 +- src/cpu/core_dyn_x86/cache.h | 2 +- src/cpu/core_dyn_x86/decoder.h | 32 ++--- src/cpu/core_dynrec.cpp | 5 +- src/cpu/core_dynrec/cache.h | 2 +- src/cpu/core_dynrec/decoder_basic.h | 71 ++++++----- src/cpu/paging.cpp | 93 ++++++++++++-- src/debug/debug.cpp | 6 +- 9 files changed, 275 insertions(+), 125 deletions(-) diff --git a/include/paging.h b/include/paging.h index 29afcce8..8a95c040 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.27 2007-09-30 14:10:04 c2woody Exp $ */ +/* $Id: paging.h,v 1.28 2007-10-05 17:45:52 c2woody Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H @@ -28,11 +28,23 @@ #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 @@ -126,6 +138,15 @@ union X86PageEntry { X86_PageEntryBlock block; }; +#if !defined(USE_FULL_TLB) +typedef struct { + HostPt read; + HostPt write; + PageHandler * handler; + Bit32u phys_page; +} tlb_entry; +#endif + struct PagingBlock { Bitu cr3; Bitu cr2; @@ -133,12 +154,17 @@ struct PagingBlock { Bitu page; PhysPt addr; } base; +#if defined(USE_FULL_TLB) struct { HostPt read[TLB_SIZE]; HostPt write[TLB_SIZE]; PageHandler * handler[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]; @@ -153,15 +179,6 @@ extern PagingBlock paging; PageHandler * MEM_GetPageHandler(Bitu phys_page); -/* Use this helper function to access linear addresses in readX/writeX functions */ -INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { - return (paging.tlb.phys_page[linePage>>12]<<12); -} - -INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { - return (paging.tlb.phys_page[linAddr>>12]<<12)|(linAddr&0xfff); -} - /* Unaligned address handlers */ Bit16u mem_unalignedreadw(PhysPt address); @@ -174,111 +191,164 @@ 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) + +INLINE HostPt get_tlb_read(PhysPt address) { + return paging.tlb.read[address>>12]; +} +INLINE HostPt get_tlb_write(PhysPt address) { + return paging.tlb.write[address>>12]; +} +INLINE PageHandler* get_tlb_handler(PhysPt address) { + return paging.tlb.handler[address>>12]; +} + +/* Use these helper functions to access linear addresses in readX/writeX functions */ +INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { + return (paging.tlb.phys_page[linePage>>12]<<12); +} + +INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { + return (paging.tlb.phys_page[linAddr>>12]<<12)|(linAddr&0xfff); +} + +#else + +void PAGING_InitTLBBank(tlb_entry **bank); + +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]; +} + +INLINE HostPt get_tlb_read(PhysPt address) { + return get_tlb_entry(address)->read; +} +INLINE HostPt get_tlb_write(PhysPt address) { + return get_tlb_entry(address)->write; +} +INLINE PageHandler* get_tlb_handler(PhysPt address) { + return get_tlb_entry(address)->handler; +} + +/* Use these helper functions to access linear addresses in readX/writeX functions */ +INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { + tlb_entry *entry = get_tlb_entry(linePage); + return (entry->phys_page<<12); +} + +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 */ INLINE Bit8u mem_readb_inline(PhysPt address) { - Bitu index=(address>>12); - if (paging.tlb.read[index]) return host_readb(paging.tlb.read[index]+address); - else return (Bit8u)paging.tlb.handler[index]->readb(address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) return host_readb(tlb_addr+address); + else return (Bit8u)(get_tlb_handler(address))->readb(address); } INLINE Bit16u mem_readw_inline(PhysPt address) { if ((address & 0xfff)<0xfff) { - Bitu index=(address>>12); - - if (paging.tlb.read[index]) return host_readw(paging.tlb.read[index]+address); - else return (Bit16u) paging.tlb.handler[index]->readw(address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) return host_readw(tlb_addr+address); + else return (Bit16u)(get_tlb_handler(address))->readw(address); } else return mem_unalignedreadw(address); } INLINE Bit32u mem_readd_inline(PhysPt address) { if ((address & 0xfff)<0xffd) { - Bitu index=(address>>12); - - if (paging.tlb.read[index]) return host_readd(paging.tlb.read[index]+address); - else return paging.tlb.handler[index]->readd(address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) return host_readd(tlb_addr+address); + else return (get_tlb_handler(address))->readd(address); } else return mem_unalignedreadd(address); } INLINE void mem_writeb_inline(PhysPt address,Bit8u val) { - Bitu index=(address>>12); - - if (paging.tlb.write[index]) host_writeb(paging.tlb.write[index]+address,val); - else paging.tlb.handler[index]->writeb(address,val); + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) host_writeb(tlb_addr+address,val); + else (get_tlb_handler(address))->writeb(address,val); } INLINE void mem_writew_inline(PhysPt address,Bit16u val) { if ((address & 0xfff)<0xfff) { - Bitu index=(address>>12); - - if (paging.tlb.write[index]) host_writew(paging.tlb.write[index]+address,val); - else paging.tlb.handler[index]->writew(address,val); + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) host_writew(tlb_addr+address,val); + else (get_tlb_handler(address))->writew(address,val); } else mem_unalignedwritew(address,val); } INLINE void mem_writed_inline(PhysPt address,Bit32u val) { if ((address & 0xfff)<0xffd) { - Bitu index=(address>>12); - - if (paging.tlb.write[index]) host_writed(paging.tlb.write[index]+address,val); - else paging.tlb.handler[index]->writed(address,val); + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) host_writed(tlb_addr+address,val); + else (get_tlb_handler(address))->writed(address,val); } else mem_unalignedwrited(address,val); } INLINE bool mem_readb_checked(PhysPt address, Bit8u * val) { - Bitu index=(address>>12); - if (paging.tlb.read[index]) { - *val=host_readb(paging.tlb.read[index]+address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) { + *val=host_readb(tlb_addr+address); return false; - } else return paging.tlb.handler[index]->readb_checked(address, val); + } else return (get_tlb_handler(address))->readb_checked(address, val); } INLINE bool mem_readw_checked(PhysPt address, Bit16u * val) { if ((address & 0xfff)<0xfff) { - Bitu index=(address>>12); - if (paging.tlb.read[index]) { - *val=host_readw(paging.tlb.read[index]+address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) { + *val=host_readw(tlb_addr+address); return false; - } else return paging.tlb.handler[index]->readw_checked(address, val); + } else return (get_tlb_handler(address))->readw_checked(address, val); } else return mem_unalignedreadw_checked(address, val); } INLINE bool mem_readd_checked(PhysPt address, Bit32u * val) { if ((address & 0xfff)<0xffd) { - Bitu index=(address>>12); - if (paging.tlb.read[index]) { - *val=host_readd(paging.tlb.read[index]+address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) { + *val=host_readd(tlb_addr+address); return false; - } else return paging.tlb.handler[index]->readd_checked(address, val); + } else return (get_tlb_handler(address))->readd_checked(address, val); } else return mem_unalignedreadd_checked(address, val); } INLINE bool mem_writeb_checked(PhysPt address,Bit8u val) { - Bitu index=(address>>12); - if (paging.tlb.write[index]) { - host_writeb(paging.tlb.write[index]+address,val); + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) { + host_writeb(tlb_addr+address,val); return false; - } else return paging.tlb.handler[index]->writeb_checked(address,val); + } else return (get_tlb_handler(address))->writeb_checked(address,val); } INLINE bool mem_writew_checked(PhysPt address,Bit16u val) { if ((address & 0xfff)<0xfff) { - Bitu index=(address>>12); - if (paging.tlb.write[index]) { - host_writew(paging.tlb.write[index]+address,val); + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) { + host_writew(tlb_addr+address,val); return false; - } else return paging.tlb.handler[index]->writew_checked(address,val); + } else return (get_tlb_handler(address))->writew_checked(address,val); } else return mem_unalignedwritew_checked(address,val); } INLINE bool mem_writed_checked(PhysPt address,Bit32u val) { if ((address & 0xfff)<0xffd) { - Bitu index=(address>>12); - if (paging.tlb.write[index]) { - host_writed(paging.tlb.write[index]+address,val); + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) { + host_writed(tlb_addr+address,val); return false; - } else return paging.tlb.handler[index]->writed_checked(address,val); + } else return (get_tlb_handler(address))->writed_checked(address,val); } else return mem_unalignedwrited_checked(address,val); } diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 8e78b8ad..a1799557 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: core_dyn_x86.cpp,v 1.33 2007-10-05 17:45:52 c2woody Exp $ */ + #include "dosbox.h" #if (C_DYNAMIC_X86) @@ -346,8 +348,7 @@ run_block: case BR_Link2: { Bitu temp_ip=SegPhys(cs)+reg_eip; - Bitu temp_page=temp_ip >> 12; - CodePageHandler * temp_handler=(CodePageHandler *)paging.tlb.handler[temp_page]; + CodePageHandler * temp_handler=(CodePageHandler *)get_tlb_handler(temp_ip); if (temp_handler->flags & PFLAG_HASCODE) { block=temp_handler->FindCacheBlock(temp_ip & 4095); if (!block) goto restart_core; diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 968f26c6..a3c43ba9 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -69,7 +69,7 @@ public: Bits index=1+(end>>DYN_HASH_SHIFT); bool is_current_block=false; Bit32u ip_point=SegPhys(cs)+reg_eip; - ip_point=((paging.tlb.phys_page[ip_point>>12]-phys_page)<<12)+(ip_point&0xfff); + 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]; diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 6122415c..4270a024 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -54,8 +54,7 @@ static bool MakeCodePage(Bitu lin_addr,CodePageHandler * &cph) { Bit8u rdval; //Ensure page contains memory: if (GCC_UNLIKELY(mem_readb_checked(lin_addr,&rdval))) return true; - Bitu lin_page=lin_addr >> 12; - PageHandler * handler=paging.tlb.handler[lin_page]; + PageHandler * handler=get_tlb_handler(lin_addr); if (handler->flags & PFLAG_HASCODE) { cph=( CodePageHandler *)handler; return false; @@ -64,6 +63,7 @@ static bool MakeCodePage(Bitu lin_addr,CodePageHandler * &cph) { LOG_MSG("DYNX86:Can't run code in this page"); cph=0; return false; } + Bitu lin_page=lin_addr >> 12; Bitu phys_page=lin_page; if (!PAGING_MakePhysPage(phys_page)) { LOG_MSG("DYNX86:Can't find physpage"); @@ -176,9 +176,9 @@ static INLINE void decode_increase_wmapmask(Bitu size) { static bool decode_fetchb_imm(Bitu & val) { if (decode.page.index<4096) { - Bitu index=(decode.code>>12); - if (paging.tlb.read[index]) { - val=(Bitu)(paging.tlb.read[index]+decode.code); + HostPt tlb_addr=get_tlb_read(decode.code); + if (tlb_addr) { + val=(Bitu)(tlb_addr+decode.code); decode_increase_wmapmask(1); decode.code++; decode.page.index++; @@ -190,9 +190,9 @@ static bool decode_fetchb_imm(Bitu & val) { } static bool decode_fetchw_imm(Bitu & val) { if (decode.page.index<4095) { - Bitu index=(decode.code>>12); - if (paging.tlb.read[index]) { - val=(Bitu)(paging.tlb.read[index]+decode.code); + HostPt tlb_addr=get_tlb_read(decode.code); + if (tlb_addr) { + val=(Bitu)(tlb_addr+decode.code); decode_increase_wmapmask(2); decode.code+=2; decode.page.index+=2; @@ -204,9 +204,9 @@ static bool decode_fetchw_imm(Bitu & val) { } static bool decode_fetchd_imm(Bitu & val) { if (decode.page.index<4093) { - Bitu index=(decode.code>>12); - if (paging.tlb.read[index]) { - val=(Bitu)(paging.tlb.read[index]+decode.code); + HostPt tlb_addr=get_tlb_read(decode.code); + if (tlb_addr) { + val=(Bitu)(tlb_addr+decode.code); decode_increase_wmapmask(4); decode.code+=4; decode.page.index+=4; @@ -462,7 +462,7 @@ static void dyn_read_intro(DynReg * addr,bool release_addr=true) { } bool mem_readb_checked_dcx86(PhysPt address) { - return paging.tlb.handler[address>>12]->readb_checked(address, (Bit8u*)(&core_dyn.readdata)); + return get_tlb_handler(address)->readb_checked(address, (Bit8u*)(&core_dyn.readdata)); } static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { @@ -543,12 +543,12 @@ static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) { bool mem_readd_checked_dcx86(PhysPt address) { if ((address & 0xfff)<0xffd) { - Bitu index=(address>>12); - if (paging.tlb.read[index]) { - core_dyn.readdata=host_readd(paging.tlb.read[index]+address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) { + core_dyn.readdata=host_readd(tlb_addr+address); return false; } else { - return paging.tlb.handler[index]->readd_checked(address, &core_dyn.readdata); + return get_tlb_handler(address)->readd_checked(address, &core_dyn.readdata); } } else return mem_unalignedreadd_checked(address, &core_dyn.readdata); } diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index 7e6944f1..e39bb8c8 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: core_dynrec.cpp,v 1.8 2007-10-05 17:45:52 c2woody Exp $ */ + #include "dosbox.h" #if (C_DYNREC) @@ -151,8 +153,7 @@ CacheBlockDynRec * LinkBlocks(BlockReturn ret) { CacheBlockDynRec * block=NULL; // the last instruction was a control flow modifying instruction Bitu temp_ip=SegPhys(cs)+reg_eip; - Bitu temp_page=temp_ip >> 12; - CodePageHandlerDynRec * temp_handler=(CodePageHandlerDynRec *)paging.tlb.handler[temp_page]; + CodePageHandlerDynRec * temp_handler=(CodePageHandlerDynRec *)get_tlb_handler(temp_ip); if (temp_handler->flags & PFLAG_HASCODE) { // see if the target is an already translated block block=temp_handler->FindCacheBlock(temp_ip & 4095); diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index 52baff65..78d671c5 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -117,7 +117,7 @@ public: 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.tlb.phys_page[ip_point>>12]-phys_page)<<12)+(ip_point&0xfff); + 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 diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index 3e684cd1..2fb7845d 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -132,9 +132,7 @@ static bool MakeCodePage(Bitu lin_addr,CodePageHandlerDynRec * &cph) { //Ensure page contains memory: if (GCC_UNLIKELY(mem_readb_checked(lin_addr,&rdval))) return true; - Bitu lin_page=lin_addr >> 12; - - PageHandler * handler=paging.tlb.handler[lin_page]; + PageHandler * handler=get_tlb_handler(lin_addr); if (handler->flags & PFLAG_HASCODE) { // this is a codepage handler, and the one that we're looking for cph=(CodePageHandlerDynRec *)handler; @@ -145,6 +143,7 @@ static bool MakeCodePage(Bitu lin_addr,CodePageHandlerDynRec * &cph) { cph=0; return false; } + Bitu lin_page=lin_addr>>12; Bitu phys_page=lin_page; // find the physical page that the linear page is mapped to if (!PAGING_MakePhysPage(phys_page)) { @@ -280,10 +279,10 @@ static bool decode_fetchb_imm(Bitu & val) { if (GCC_UNLIKELY(decode.page.index>=4096)) { decode_advancepage(); } - Bitu index=(decode.code>>12); + HostPt tlb_addr=get_tlb_read(decode.code); // see if position is directly accessible - if (paging.tlb.read[index]) { - val=(Bitu)(paging.tlb.read[index]+decode.code); + if (tlb_addr) { + val=(Bitu)(tlb_addr+decode.code); decode_increase_wmapmask(1); decode.code++; decode.page.index++; @@ -298,10 +297,10 @@ static bool decode_fetchb_imm(Bitu & val) { // otherwise val contains the current value read from the position static bool decode_fetchw_imm(Bitu & val) { if (decode.page.index<4095) { - Bitu index=(decode.code>>12); + HostPt tlb_addr=get_tlb_read(decode.code); // see if position is directly accessible - if (paging.tlb.read[index]) { - val=(Bitu)(paging.tlb.read[index]+decode.code); + if (tlb_addr) { + val=(Bitu)(tlb_addr+decode.code); decode_increase_wmapmask(2); decode.code+=2; decode.page.index+=2; @@ -317,10 +316,10 @@ static bool decode_fetchw_imm(Bitu & val) { // otherwise val contains the current value read from the position static bool decode_fetchd_imm(Bitu & val) { if (decode.page.index<4093) { - Bitu index=(decode.code>>12); + HostPt tlb_addr=get_tlb_read(decode.code); // see if position is directly accessible - if (paging.tlb.read[index]) { - val=(Bitu)(paging.tlb.read[index]+decode.code); + if (tlb_addr) { + val=(Bitu)(tlb_addr+decode.code); decode_increase_wmapmask(4); decode.code+=4; decode.page.index+=4; @@ -565,65 +564,65 @@ static void dyn_check_exception(HostReg reg) { bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) DRC_FC; bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) { - Bitu index=(address>>12); - if (paging.tlb.read[index]) { - *((Bit8u*)(&core_dynrec.readdata))=host_readb(paging.tlb.read[index]+address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) { + *((Bit8u*)(&core_dynrec.readdata))=host_readb(tlb_addr+address); return false; } else { - return paging.tlb.handler[index]->readb_checked(address, (Bit8u*)(&core_dynrec.readdata)); + return get_tlb_handler(address)->readb_checked(address, (Bit8u*)(&core_dynrec.readdata)); } } bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) DRC_FC; bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) { - Bitu index=(address>>12); - if (paging.tlb.write[index]) { - host_writeb(paging.tlb.write[index]+address,val); + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) { + host_writeb(tlb_addr+address,val); return false; - } else return paging.tlb.handler[index]->writeb_checked(address,val); + } else return get_tlb_handler(address)->writeb_checked(address,val); } bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) DRC_FC; bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) { if ((address & 0xfff)<0xfff) { - Bitu index=(address>>12); - if (paging.tlb.read[index]) { - *((Bit16u*)(&core_dynrec.readdata))=host_readw(paging.tlb.read[index]+address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) { + *((Bit16u*)(&core_dynrec.readdata))=host_readw(tlb_addr+address); return false; - } else return paging.tlb.handler[index]->readw_checked(address, (Bit16u*)(&core_dynrec.readdata)); + } else return get_tlb_handler(address)->readw_checked(address, (Bit16u*)(&core_dynrec.readdata)); } else return mem_unalignedreadw_checked(address, ((Bit16u*)(&core_dynrec.readdata))); } bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) DRC_FC; bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) { if ((address & 0xfff)<0xffd) { - Bitu index=(address>>12); - if (paging.tlb.read[index]) { - *((Bit32u*)(&core_dynrec.readdata))=host_readd(paging.tlb.read[index]+address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) { + *((Bit32u*)(&core_dynrec.readdata))=host_readd(tlb_addr+address); return false; - } else return paging.tlb.handler[index]->readd_checked(address, (Bit32u*)(&core_dynrec.readdata)); + } else return get_tlb_handler(address)->readd_checked(address, (Bit32u*)(&core_dynrec.readdata)); } else return mem_unalignedreadd_checked(address, ((Bit32u*)(&core_dynrec.readdata))); } bool DRC_CALL_CONV mem_writew_checked_drc(PhysPt address,Bit16u val) DRC_FC; bool DRC_CALL_CONV mem_writew_checked_drc(PhysPt address,Bit16u val) { if ((address & 0xfff)<0xfff) { - Bitu index=(address>>12); - if (paging.tlb.write[index]) { - host_writew(paging.tlb.write[index]+address,val); + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) { + host_writew(tlb_addr+address,val); return false; - } else return paging.tlb.handler[index]->writew_checked(address,val); + } else return get_tlb_handler(address)->writew_checked(address,val); } else return mem_unalignedwritew_checked(address,val); } bool DRC_CALL_CONV mem_writed_checked_drc(PhysPt address,Bit32u val) DRC_FC; bool DRC_CALL_CONV mem_writed_checked_drc(PhysPt address,Bit32u val) { if ((address & 0xfff)<0xffd) { - Bitu index=(address>>12); - if (paging.tlb.write[index]) { - host_writed(paging.tlb.write[index]+address,val); + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) { + host_writed(tlb_addr+address,val); return false; - } else return paging.tlb.handler[index]->writed_checked(address,val); + } else return get_tlb_handler(address)->writed_checked(address,val); } else return mem_unalignedwrited_checked(address,val); } diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 15f01659..7e960e52 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: paging.cpp,v 1.28 2007-10-05 17:45:52 c2woody Exp $ */ + #include #include #include @@ -317,6 +319,7 @@ Bitu PAGING_GetDirBase(void) { return paging.cr3; } +#if defined(USE_FULL_TLB) void PAGING_InitTLB(void) { for (Bitu i=0;i0;paging.links.used--) { + Bitu page=*entries++; + tlb_entry *entry = get_tlb_entry(page<<12); + entry->read=0; + entry->write=0; + entry->handler=&init_page_handler; + } + paging.links.used=0; +} + +void PAGING_UnlinkPages(Bitu lin_page,Bitu pages) { + tlb_entry *entry = get_tlb_entry(lin_page<<12); + for (;pages>0;pages--) { + entry->read=0; + entry->write=0; + entry->handler=&init_page_handler; + } +} + void PAGING_MapPage(Bitu lin_page,Bitu phys_page) { if (lin_page=(TLB_SIZE*(TLB_BANKS+1)) || phys_page>=(TLB_SIZE*(TLB_BANKS+1))) + E_Exit("Illegal page"); + + if (paging.links.used>=PAGING_LINKS) { + LOG(LOG_PAGING,LOG_NORMAL)("Not enough paging links, resetting cache"); + PAGING_ClearTLB(); + } + + tlb_entry *entry = get_tlb_entry(lin_base); + entry->phys_page=phys_page; + if (handler->flags & PFLAG_READABLE) entry->read=handler->GetHostReadPt(phys_page)-lin_base; + else entry->read=0; + if (handler->flags & PFLAG_WRITEABLE) entry->write=handler->GetHostWritePt(phys_page)-lin_base; + else entry->write=0; + + paging.links.entries[paging.links.used++]=lin_page; + entry->handler=handler; +} + +#endif + + void PAGING_SetDirBase(Bitu cr3) { paging.cr3=cr3; @@ -392,10 +473,8 @@ void PAGING_Enable(bool enabled) { /* If paging is disable we work from a default paging table */ if (paging.enabled==enabled) return; paging.enabled=enabled; - if (!enabled) { -// LOG(LOG_PAGING,LOG_NORMAL)("Disabled"); - } else { - if (cpudecoder==CPU_Core_Simple_Run) { + if (enabled) { + if (GCC_UNLIKELY(cpudecoder==CPU_Core_Simple_Run)) { // LOG_MSG("CPU core simple won't run this game,switching to normal"); cpudecoder=CPU_Core_Normal_Run; CPU_CycleLeft+=CPU_Cycles; diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 4bfec5db..7e0ec1b5 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.88 2007-06-12 20:22:07 c2woody Exp $ */ +/* $Id: debug.cpp,v 1.89 2007-10-05 17:45:53 c2woody Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -674,7 +674,7 @@ static void DrawData(void) { else mvwprintw (dbg.win_data,1+y,0,"%04X:%08X ",dataSeg,add); for (int x=0; x<16; x++) { address = GetAddress(dataSeg,add); - if (!(paging.tlb.handler[address >> 12]->flags & PFLAG_INIT)) { + if (!(get_tlb_handler(address)->flags & PFLAG_INIT)) { ch = mem_readb(address); } else ch = 0; mvwprintw (dbg.win_data,1+y,14+3*x,"%02X",ch); @@ -1344,7 +1344,7 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) pos++; }; Bit32u address = GetAddress(seg,adr); - if (!(paging.tlb.handler[address >> 12]->flags & PFLAG_INIT)) { + if (!(get_tlb_handler(address)->flags & PFLAG_INIT)) { static char outmask[] = "%s:[%04X]=%02X"; if (cpu.pmode) outmask[6] = '8'; From c847af53639ae35853e6b84383b65eb4462b8210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 5 Oct 2007 19:47:34 +0000 Subject: [PATCH 2920/4131] fix chained vga handler Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3008 --- src/hardware/vga_memory.cpp | 77 ++++++++++--------------------------- 1 file changed, 20 insertions(+), 57 deletions(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 31d309cd..76487aff 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -309,35 +309,23 @@ public: } Bitu readw(PhysPt addr ) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - return readHandler( addr ); + if (GCC_UNLIKELY(addr & 1)) + return + (readHandler( addr+0 ) << 0 ) | + (readHandler( addr+1 ) << 8 ); + else + return readHandler( addr ); } Bitu readd(PhysPt addr ) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - return readHandler( addr ); - } - bool readw_checked( PhysPt addr,Bitu *val ) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - if ( addr & 1) { - *val = - (readHandler( addr+0 ) << 0 ) | - (readHandler( addr+1 ) << 8 ); - } else { - *val = readHandler( addr ); - } - return false; - } - bool readd_checked( PhysPt addr,Bitu *val ) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - if ( addr & 3) { - *val = + if (GCC_UNLIKELY(addr & 3)) + return (readHandler( addr+0 ) << 0 ) | (readHandler( addr+1 ) << 8 ) | (readHandler( addr+2 ) << 16 ) | (readHandler( addr+3 ) << 24 ); - } else { - *val = readHandler( addr ); - } - return false; + else + return readHandler( addr ); } void writeb(PhysPt addr, Bitu val ) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; @@ -348,46 +336,28 @@ public: void writew(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; MEM_CHANGED( addr ); - writeHandler( addr, val ); +// MEM_CHANGED( addr + 1); + if (GCC_UNLIKELY(addr & 1)) { + writeHandler( addr+0, val >> 0 ); + writeHandler( addr+1, val >> 8 ); + } else { + writeHandler( addr, val ); + } writeCache( addr, val ); } void writed(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; MEM_CHANGED( addr ); - writeHandler( addr, val ); - writeCache( addr, val ); - } - bool writew_checked( PhysPt addr,Bitu val ) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - if ( addr & 1 ) { - MEM_CHANGED( addr ); - MEM_CHANGED( addr + 1); - writeHandler( addr+0, val >> 0 ); - writeHandler( addr+1, val >> 8 ); - writeCache( addr, val ); - } else { - MEM_CHANGED( addr ); - writeHandler( addr, val ); - writeCache( addr, val ); - } - return false; - } - bool writed_checked( PhysPt addr,Bitu val ) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - if ( addr & 3) { - MEM_CHANGED( addr ); - MEM_CHANGED( addr + 3); +// MEM_CHANGED( addr + 3); + if (GCC_UNLIKELY(addr & 3)) { writeHandler( addr+0, val >> 0 ); writeHandler( addr+1, val >> 8 ); writeHandler( addr+2, val >> 16 ); writeHandler( addr+3, val >> 24 ); - writeCache( addr, val ); } else { - MEM_CHANGED( addr ); writeHandler( addr, val ); - writeCache( addr, val ); } - return false; + writeCache( addr, val ); } }; @@ -586,13 +556,6 @@ public: hostWrite( &vga.mem.linear[addr], val ); MEM_CHANGED( addr ); } - bool writed_checked( PhysPt addr,Bitu val ) { - addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; - hostWrite( &vga.mem.linear[addr], val ); - MEM_CHANGED( addr ); - return false; - } - }; class VGA_LFB_Handler : public PageHandler { From 3fef357644450f93893fca27ec3d12f128b2be98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 6 Oct 2007 11:56:12 +0000 Subject: [PATCH 2921/4131] add textmode pel panning (see sf patch #1805880) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3009 --- src/hardware/vga_attr.cpp | 3 +-- src/hardware/vga_draw.cpp | 37 ++++++++++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 5f5ce3bf..332bdb6a 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -87,7 +87,6 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) { */ attr(mode_control)=val; VGA_DetermineMode(); - //TODO 9 bit characters /* 0 Graphics mode if set, Alphanumeric mode else. 1 Monochrome mode if set, color mode else. @@ -126,7 +125,7 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) { attr(horizontal_pel_panning)=val & 0xF; switch (vga.mode) { case M_TEXT: - if (val==0x7) vga.config.pel_panning=7; + if ((val==0x7) && (svgaCard==SVGA_None)) vga.config.pel_panning=7; if (val>0x7) vga.config.pel_panning=0; else vga.config.pel_panning=val+1; break; diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 185e2a1d..8d6191f2 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -410,14 +410,30 @@ skip_cursor: static Bit8u * VGA_TEXT_Draw_Line_9(Bitu vidstart, Bitu line) { Bits font_addr; Bit8u * draw=(Bit8u *)TempLine; + Bit8u pel_pan=vga.config.pel_panning; + if ((vga.attr.mode_control&0x20) && (vga.draw.lines_done>=vga.draw.split_line)) pel_pan=0; const Bit8u *vidmem = &vga.tandy.draw_base[vidstart]; - Bitu bitpos=0; - for (Bitu cx=0;cx> 3)&1][chr*32+line]; - Bit8u fg=col&0xf; - Bit8u bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff); + Bit8u chr=vidmem[0]; + Bit8u col=vidmem[1]; + Bit8u font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<>4]&0xff); + Bitu draw_blocks=vga.draw.blocks; + draw_blocks++; + for (Bitu cx=1;cx> 3)&1][chr*32+line]>>(8-pel_pan); + fg=col&0xf; + bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff); + } else { + chr=vidmem[(cx-1)*2]; + col=vidmem[(cx-1)*2+1]; + font=vga.draw.font_tables[(col >> 3)&1][chr*32+line]; + fg=col&0xf; + bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff); + } if (FontMask[col>>7]==0) font=0; *draw++=(font&0x80)?fg:bg; *draw++=(font&0x40)?fg:bg; *draw++=(font&0x20)?fg:bg; *draw++=(font&0x10)?fg:bg; @@ -426,6 +442,8 @@ static Bit8u * VGA_TEXT_Draw_Line_9(Bitu vidstart, Bitu line) { Bit8u last=(font&0x01)?fg:bg; *draw++=last; *draw++=((chr<0xc0) || (chr>0xdf)) ? bg : last; + if (pel_pan) + font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<> 1; @@ -595,7 +613,8 @@ static void VGA_VerticalTimer(Bitu val) { #endif break; case M_TEXT: - vga.draw.address = vga.config.display_start * 2; + if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) vga.draw.address = vga.config.real_start * 2; + else vga.draw.address = vga.config.display_start * 2; case M_TANDY_TEXT: case M_HERC_TEXT: vga.draw.cursor.address=vga.config.cursor_start*2; @@ -969,7 +988,7 @@ void VGA_SetupDrawing(Bitu val) { aspect_ratio=1.0; vga.draw.blocks=width; doublewidth=(vga.seq.clocking_mode & 0x8) > 0; - if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) { + if ((IS_VGA_ARCH) && (svgaCard==SVGA_None) && (vga.attr.mode_control&0x04)) { width*=9; /* 9 bit wide text font */ VGA_DrawLine=VGA_TEXT_Draw_Line_9; } else { From 53350b35be2053cf2fc86cd22325411f1ac40975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 6 Oct 2007 19:46:32 +0000 Subject: [PATCH 2922/4131] fix dcc functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3010 --- src/ints/int10.cpp | 45 +++++++++++++++++++++++++++++++++------- src/ints/int10_modes.cpp | 5 ++--- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 5d653dba..96af9e9b 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -399,15 +399,46 @@ graphics_chars: break; case 0x1A: /* Display Combination */ if (!IS_VGA_ARCH) break; - if (reg_al==0) { - reg_bx=real_readb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX); + if (reg_al==0) { // get dcc + // walk the tables... + RealPt vsavept=real_readd(BIOSMEM_SEG,BIOSMEM_VS_POINTER); + RealPt svstable=real_readd(RealSeg(vsavept),RealOff(vsavept)+0x10); + if (svstable) { + RealPt dcctable=real_readd(RealSeg(svstable),RealOff(svstable)+0x02); + Bit8u entries=real_readb(RealSeg(dcctable),RealOff(dcctable)+0x00); + Bit8u idx=real_readb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX); + // check if index within range + if (idx>8; + else reg_bx=dccentry; + } else reg_bx=0xffff; + } else reg_bx=0xffff; reg_al=0x1A; - break; - } - if (reg_al==1) { - real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,reg_bl); + } else if (reg_al==1) { // set dcc + Bit8u newidx=0xff; + // walk the tables... + RealPt vsavept=real_readd(BIOSMEM_SEG,BIOSMEM_VS_POINTER); + RealPt svstable=real_readd(RealSeg(vsavept),RealOff(vsavept)+0x10); + if (svstable) { + RealPt dcctable=real_readd(RealSeg(svstable),RealOff(svstable)+0x02); + Bit8u entries=real_readb(RealSeg(dcctable),RealOff(dcctable)+0x00); + if (entries) { + Bitu ct; + Bit16u swpidx=reg_bh|(reg_bl<<8); + // search the ddc index in the dcc table + for (ct=0; ct Date: Sun, 7 Oct 2007 18:38:24 +0000 Subject: [PATCH 2923/4131] several ega machine fixes (mode parameters, double scanning, palette data etc.) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3011 --- src/hardware/vga_attr.cpp | 10 ++-- src/hardware/vga_draw.cpp | 18 ++++--- src/ints/int10_modes.cpp | 98 +++++++++++++++++++++++++-------------- 3 files changed, 77 insertions(+), 49 deletions(-) diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 332bdb6a..7a06a04d 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -28,12 +28,10 @@ void VGA_ATTR_SetPalette(Bit8u index,Bit8u val) { val &= 63; val |= (vga.attr.color_select & 0xc) << 4; if (GCC_UNLIKELY(!IS_VGA_ARCH)) { - if ((vga.misc_output&0xc4)==0x40) { - if (val&0x10) val|=0x38; - else { - val&=0x7; - if (val==6) val=0x14; - } + if (val&0x10) val|=0x38; + else { + val&=0x7; + if (val==6) val=0x14; } } VGA_DAC_CombineColor(index,val); diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 8d6191f2..365abf7b 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -584,6 +584,7 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.address_line = vga.config.hlines_skip; vga.draw.split_line = (vga.config.line_compare/vga.draw.lines_scaled); // go figure... + if (machine==MCH_EGA) vga.draw.split_line*=2; // if (machine==MCH_EGA) vga.draw.split_line = ((((vga.config.line_compare&0x5ff)+1)*2-1)/vga.draw.lines_scaled); switch (vga.mode) { case M_EGA: @@ -637,8 +638,10 @@ static void VGA_VerticalTimer(Bitu val) { PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts,vga.draw.parts_lines); // PIC_AddEvent(VGA_DrawPart,(float)(vga.draw.delay.parts/2),vga.draw.parts_lines); //Else tearline in Tyrian and second reality if (GCC_UNLIKELY(machine==MCH_EGA)) { - PIC_ActivateIRQ(2); - vga.draw.vret_triggered=true; + if (!(vga.crtc.vertical_retrace_end&0x20)) { + PIC_ActivateIRQ(2); + vga.draw.vret_triggered=true; + } } } @@ -787,7 +790,7 @@ void VGA_SetupDrawing(Bitu val) { if (vga.s3.pll.cmd & 0x10) clock/=2; if (IS_VGA_ARCH) vga.draw.double_scan=(vga.crtc.maximum_scan_line&0x80)>0; - else vga.draw.double_scan=false; // might actually be a special implementation of double scanning for ega + else vga.draw.double_scan=(vga.seq.clocking_mode&0x08)>0; // not really correct... } else { htotal = vga.other.htotal + 1; hdend = vga.other.hdend; @@ -850,7 +853,7 @@ void VGA_SetupDrawing(Bitu val) { /* // just curious LOG_MSG("H total %d, V Total %d",htotal,vtotal); - LOG_MSG("H D End %d, V D End %d",hdispend,vdispend); + LOG_MSG("H D End %d, V D End %d",hdend,vdend); LOG_MSG("vrstart: %d, vrend: %d\n",vrstart,vrend); LOG_MSG("htotal: %2.6f, vtotal: %2.6f,\n"\ "hblkstart: %2.6f, hblkend: %2.6f,\n"\ @@ -861,8 +864,8 @@ void VGA_SetupDrawing(Bitu val) { vga.draw.delay.hblkstart, vga.draw.delay.hblkend, vga.draw.delay.vblkstart, vga.draw.delay.vblkend, vga.draw.delay.vrstart, vga.draw.delay.vrend, - vga.draw.delay.vend); - */ + vga.draw.delay.vdend); + */ vga.draw.parts_total=VGA_PARTS; /* 6 Horizontal Sync Polarity. Negative if set @@ -904,6 +907,7 @@ void VGA_SetupDrawing(Bitu val) { vga.draw.delay.parts = vga.draw.delay.vdend/vga.draw.parts_total; vga.draw.resizing=false; + vga.draw.vret_triggered=false; //Check to prevent useless black areas if (hbstarttype) { case M_TEXT: seq_data[2]|=0x3; //Enable plane 0 and 1 - seq_data[4]|=0x05; //Alpanumeric and odd/even enabled + seq_data[4]|=0x01; //Alpanumeric + if (IS_VGA_ARCH) seq_data[4]|=0x04; //odd/even enabled break; case M_CGA2: seq_data[2]|=0xf; //Enable plane 0 + if (machine==MCH_EGA) seq_data[4]|=0x04; //odd/even enabled + break; + case M_CGA4: + if (machine==MCH_EGA) seq_data[2]|=0x03; //Enable plane 0 and 1 break; case M_LIN4: case M_EGA: seq_data[2]|=0xf; //Enable all planes for writing + if (machine==MCH_EGA) seq_data[4]|=0x04; //odd/even enabled break; case M_LIN8: //Seems to have the same reg layout from testing case M_LIN15: @@ -669,8 +675,7 @@ bool INT10_SetVideoMode(Bitu mode) { Bit8u underline=0; /* Maximum scanline / Underline Location */ if (CurMode->special & _EGA_LINE_DOUBLE) { - if (machine==MCH_EGA) max_scanline=1; - else max_scanline|=0x80; + if (machine!=MCH_EGA) max_scanline|=0x80; } switch (CurMode->type) { case M_TEXT: @@ -689,8 +694,7 @@ bool INT10_SetVideoMode(Bitu mode) { break; case M_CGA2: case M_CGA4: - if (machine==MCH_EGA) max_scanline|=2; - else max_scanline|=1; + max_scanline|=1; break; } if (CurMode->vdispend==350) underline=0x0f; @@ -719,6 +723,9 @@ bool INT10_SetVideoMode(Bitu mode) { break; default: offset = CurMode->hdispend/2; + if ((machine==MCH_EGA) && (CurMode->type==M_EGA)) { + if (!(CurMode->special & _EGA_LINE_DOUBLE)) offset/=2; + } } IO_Write(crtc_base,0x13); IO_Write(crtc_base + 1,offset & 0xff); @@ -746,8 +753,14 @@ bool INT10_SetVideoMode(Bitu mode) { case M_EGA: if (CurMode->mode==0x11) // 0x11 also sets address wrap. thought maybe all 2 color modes did but 0x0f doesn't. mode_control=0xc3; // so.. 0x11 or 0x0f a one off? - else - mode_control=0xe3; + else { + if (machine==MCH_EGA) { + if (CurMode->special & _EGA_LINE_DOUBLE) mode_control=0xc3; + else mode_control=0x8b; + } else { + mode_control=0xe3; + } + } break; case M_TEXT: case M_VGA: @@ -760,6 +773,7 @@ bool INT10_SetVideoMode(Bitu mode) { mode_control |= 0x08; break; } + if (machine==MCH_EGA) mode_control|=0x10; IO_Write(crtc_base,0x17);IO_Write(crtc_base+1,mode_control); /* Renable write protection */ @@ -819,8 +833,15 @@ bool INT10_SetVideoMode(Bitu mode) { break; case M_CGA4: gfx_data[0x5]|=0x20; //CGA mode - case M_CGA2: gfx_data[0x6]|=0x0f; //graphics mode at at 0xb800=0xbfff + if (machine==MCH_EGA) gfx_data[0x5]|=0x10; + break; + case M_CGA2: + if (machine==MCH_EGA) { + gfx_data[0x6]|=0x0d; //graphics mode at at 0xb800=0xbfff + } else { + gfx_data[0x6]|=0x0f; //graphics mode at at 0xb800=0xbfff + } break; } for (i=0;itype == M_LIN4 ) goto att_text16; - if (!IS_VGA_ARCH) { - for (i=0;i<8;i++) { - att_data[i]=i; - att_data[i+8]=i+0x38; - } - } else { - for (i=0;i<8;i++) { - att_data[i]=i; - att_data[i+8]=i+0x10; - } + for (i=0;i<8;i++) { + att_data[i]=i; + att_data[i+8]=i+0x10; } break; } @@ -874,15 +888,27 @@ bool INT10_SetVideoMode(Bitu mode) { for (i=0;i<16;i++) att_data[i]=i; break; case M_TEXT: - att_data[0x13]=0x08; //Pel panning on 8, although we don't have 9 dot text mode - att_data[0x10]=0x0C; //Color Text with blinking + if (machine==MCH_EGA) { + att_data[0x13]=0x00; + att_data[0x10]=0x08; //8 Bit characters + } else { + att_data[0x13]=0x08; //Pel panning on 8, although we don't have 9 dot text mode + att_data[0x10]=0x0C; //Color Text with blinking + } real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x30); att_text16: - for (i=0;i<8;i++) { - att_data[i]=i; - att_data[i+8]=i+0x38; + if (machine==MCH_EGA) { + for (i=0;i<8;i++) { + att_data[i]=i; + att_data[i+8]=i+0x10; + } + } else { + for (i=0;i<8;i++) { + att_data[i]=i; + att_data[i+8]=i+0x38; + } } - att_data[0x06]=0x14; //Odd Color 6 yellow/brown. + if (IS_VGA_ARCH) att_data[0x06]=0x14; //Odd Color 6 yellow/brown. break; case M_CGA2: att_data[0x10]=0x01; //Color Graphics From e8cfa94063708422488226893937a1f7b993b964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 8 Oct 2007 20:22:13 +0000 Subject: [PATCH 2924/4131] add ega video parameter table Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3012 --- src/ints/Makefile.am | 2 +- src/ints/int10.h | 5 +- src/ints/int10_memory.cpp | 439 +---------------------- src/ints/int10_vptable.cpp | 703 +++++++++++++++++++++++++++++++++++++ visualc_net/dosbox.vcproj | 3 + 5 files changed, 714 insertions(+), 438 deletions(-) create mode 100644 src/ints/int10_vptable.cpp diff --git a/src/ints/Makefile.am b/src/ints/Makefile.am index 6b6621df..e994d09f 100644 --- a/src/ints/Makefile.am +++ b/src/ints/Makefile.am @@ -3,5 +3,5 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libints.a libints_a_SOURCES = mouse.cpp xms.cpp xms.h ems.cpp \ int10.cpp int10.h int10_char.cpp int10_memory.cpp int10_misc.cpp int10_modes.cpp \ - int10_vesa.cpp int10_pal.cpp int10_put_pixel.cpp int10_video_state.cpp \ + int10_vesa.cpp int10_pal.cpp int10_put_pixel.cpp int10_video_state.cpp int10_vptable.cpp \ bios.cpp bios_disk.cpp bios_keyboard.cpp diff --git a/src/ints/int10.h b/src/ints/int10.h index 72b931e5..0d5db7df 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -203,7 +203,7 @@ Bit8u VESA_GetDisplayStart(Bit16u & x,Bit16u & y); Bit8u VESA_SetPalette(PhysPt data,Bitu index,Bitu count); Bit8u VESA_GetPalette(PhysPt data,Bitu index,Bitu count); -/* Sup Groups */ +/* Sub Groups */ void INT10_SetupRomMemory(void); void INT10_SetupRomMemoryChecksum(void); void INT10_SetupVESA(void); @@ -221,3 +221,6 @@ void INT10_EGA_RIL_WriteRegisterSet(Bit16u cx, PhysPt tbl); Bitu INT10_VideoState_GetSize(Bitu state); bool INT10_VideoState_Save(Bitu state,RealPt buffer); bool INT10_VideoState_Restore(Bitu state,RealPt buffer); + +/* Video Parameter Tables */ +Bitu INT10_SetupVideoParameterTable(PhysPt basepos); diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 76fc0927..701e2ccd 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: int10_memory.cpp,v 1.24 2007-10-08 20:22:13 c2woody Exp $ */ + #include "dosbox.h" #include "mem.h" #include "inout.h" @@ -74,238 +76,6 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu } -static Bit8u video_parameter_table[0x40*0x1d]={ -// video parameter table for mode 0 (cga emulation) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// video parameter table for mode 1 (cga emulation) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// video parameter table for mode 2 (cga emulation) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// video parameter table for mode 3 (cga emulation) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// video parameter table for mode 4 - 0x28, 0x18, 0x08, 0x00, 0x40, // bios data - 0x09, 0x00, 0x00, 0x02, // sequencer registers - 0x63, // misc output registers - 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, // crtc registers 0-7 - 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 - 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, 0xff, // crtc registers 16-24 - 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, // attr registers 0-7 - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 - 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0f, 0x0f, 0xff, // graphics registers 0-8 -// video parameter table for mode 5 - 0x28, 0x18, 0x08, 0x00, 0x40, // bios data - 0x09, 0x00, 0x00, 0x02, // sequencer registers - 0x63, // misc output registers - 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, // crtc registers 0-7 - 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 - 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, 0xff, // crtc registers 16-24 - 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, // attr registers 0-7 - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 - 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0f, 0x0f, 0xff, // graphics registers 0-8 -// video parameter table for mode 6 - 0x50, 0x18, 0x08, 0x00, 0x40, // bios data - 0x09, 0x0f, 0x00, 0x02, // sequencer registers - 0x63, // misc output registers - 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, // crtc registers 0-7 - 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 - 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2, 0xff, // crtc registers 16-24 - 0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, // attr registers 0-7 - 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, // attr registers 8-15 - 0x01, 0x00, 0x01, 0x00, // attr registers 16-19 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0xff, // graphics registers 0-8 -// video parameter table for mode 7 - 0x50, 0x18, 0x10, 0x00, 0x10, // bios data - 0x00, 0x0f, 0x00, 0x07, // sequencer registers - 0x66, // misc output registers - 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, // crtc registers 0-7 - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 - 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, 0xff, // crtc registers 16-24 - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, // attr registers 0-7 - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // attr registers 8-15 - 0x0c, 0x00, 0x0f, 0x08, // attr registers 16-19 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff, // graphics registers 0-8 -// video parameter table for mode 8 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// video parameter table for mode 9 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// video parameter table for mode a - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// video parameter table for mode b - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// video parameter table for mode c - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// video parameter table for mode d - 0x28, 0x18, 0x08, 0x00, 0x20, // bios data - 0x09, 0x0f, 0x00, 0x02, // sequencer registers - 0x63, // misc output registers - 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, // crtc registers 0-7 - 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 - 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3, 0xff, // crtc registers 16-24 - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // attr registers 0-7 - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 - 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 -// video parameter table for mode e - 0x50, 0x18, 0x08, 0x00, 0x40, // bios data - 0x01, 0x0f, 0x00, 0x02, // sequencer registers - 0x63, // misc output registers - 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, // crtc registers 0-7 - 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 - 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3, 0xff, // crtc registers 16-24 - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // attr registers 0-7 - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 - 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 -// video parameter table for mode f (64k graphics memory) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// video parameter table for mode 10 (64k graphics memory) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// video parameter table for mode f (>64k graphics memory) - 0x50, 0x18, 0x0e, 0x00, 0x80, // bios data - 0x01, 0x0f, 0x00, 0x02, // sequencer registers - 0xa2, // misc output registers - 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, // crtc registers 0-7 - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 - 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, 0xff, // crtc registers 16-24 - 0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, // attr registers 0-7 - 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, // attr registers 8-15 - 0x0b, 0x00, 0x0f, 0x00, // attr registers 16-19 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 -// video parameter table for mode 10 (>64k graphics memory) - 0x50, 0x18, 0x0e, 0x00, 0x80, // bios data - 0x01, 0x0f, 0x00, 0x02, // sequencer registers - 0xa3, // misc output registers - 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, // crtc registers 0-7 - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 - 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, 0xff, // crtc registers 16-24 - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, // attr registers 0-7 - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // attr registers 8-15 - 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 -// video parameter table for mode 0 (350 lines) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// video parameter table for mode 1 (350 lines) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// video parameter table for mode 2 (350 lines) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// video parameter table for mode 3 (350 lines) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// video parameter table for mode e - 0x28, 0x18, 0x10, 0x00, 0x08, // bios data - 0x08, 0x0f, 0x00, 0x07, // sequencer registers - 0x67, // misc output registers - 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f, // crtc registers 0-7 - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 - 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3, 0xff, // crtc registers 16-24 - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, // attr registers 0-7 - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // attr registers 8-15 - 0x0c, 0x00, 0x0f, 0x08, // attr registers 16-19 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, // graphics registers 0-8 -// video parameter table for mode f - 0x50, 0x18, 0x10, 0x00, 0x10, // bios data - 0x00, 0x0f, 0x00, 0x07, // sequencer registers - 0x67, // misc output registers - 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, // crtc registers 0-7 - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 - 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, 0xff, // crtc registers 16-24 - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, // attr registers 0-7 - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // attr registers 8-15 - 0x0c, 0x00, 0x0f, 0x08, // attr registers 16-19 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, // graphics registers 0-8 -// video parameter table for mode 10 - 0x50, 0x18, 0x10, 0x00, 0x10, // bios data - 0x00, 0x0f, 0x00, 0x07, // sequencer registers - 0x66, // misc output registers - 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, // crtc registers 0-7 - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 - 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, 0xff, // crtc registers 16-24 - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, // attr registers 0-7 - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // attr registers 8-15 - 0x0c, 0x00, 0x0f, 0x08, // attr registers 16-19 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff, // graphics registers 0-8 -// video parameter table for mode 11 - 0x50, 0x1d, 0x10, 0x00, 0xa0, // bios data - 0x01, 0x0f, 0x00, 0x02, // sequencer registers - 0xe3, // misc output registers - 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, // crtc registers 0-7 - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 - 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xc3, 0xff, // crtc registers 16-24 - 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, // attr registers 0-7 - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, // attr registers 8-15 - 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 -// video parameter table for mode 12 - 0x50, 0x1d, 0x10, 0x00, 0xa0, // bios data - 0x01, 0x0f, 0x00, 0x02, // sequencer registers - 0xe3, // misc output registers - 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, // crtc registers 0-7 - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 - 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, 0xff, // crtc registers 16-24 - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, // attr registers 0-7 - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // attr registers 8-15 - 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 -// video parameter table for mode 13 - 0x28, 0x18, 0x08, 0x00, 0x20, // bios data - 0x01, 0x0f, 0x00, 0x0e, // sequencer registers - 0x63, // misc output registers - 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, // crtc registers 0-7 - 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 - 0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3, 0xff, // crtc registers 16-24 - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // attr registers 0-7 - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, // attr registers 8-15 - 0x41, 0x00, 0x0f, 0x00, // attr registers 16-19 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff, // graphics registers 0-8 -}; - static Bitu checksumlocation = 0; //Same type as int10.rom.used void INT10_SetupRomMemory(void) { /* This should fill up certain structures inside the Video Bios Rom Area */ @@ -351,16 +121,7 @@ void INT10_SetupRomMemory(void) { if (IS_EGAVGA_ARCH) { int10.rom.video_parameter_table=RealMake(0xC000,int10.rom.used); - if (IS_VGA_ARCH) { - for (i=0;i<0x40*0x1d;i++) { - phys_writeb(rom_base+int10.rom.used++,video_parameter_table[i]); - } - } else { - // tables not correct (ega) - for (i=0;i<0x40*0x17;i++) { - phys_writeb(rom_base+int10.rom.used++,video_parameter_table[i]); - } - } + int10.rom.used+=INT10_SetupVideoParameterTable(rom_base+int10.rom.used); if (IS_VGA_ARCH) { int10.rom.video_dcc_table=RealMake(0xC000,int10.rom.used); @@ -400,9 +161,6 @@ void INT10_SetupRomMemory(void) { phys_writed(rom_base+int10.rom.used,0); int10.rom.used+=4; } - // use the following to generate/update the video parameter table: -// void INT10_GenerateVideoParameterTable(); -// INT10_GenerateVideoParameterTable(); int10.rom.video_save_pointers=RealMake(0xC000,int10.rom.used); phys_writed(rom_base+int10.rom.used,int10.rom.video_parameter_table); int10.rom.used+=4; @@ -466,194 +224,6 @@ void INT10_SetupRomMemoryChecksum(void) { } -void INT10_GenerateVideoParameterTable(void) { - Bitu i; - for (i=0; i<4; i++) { - LOG_MSG("// video parameter table for mode %x (cga emulation)",i); - LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); - LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); - LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); - LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); - } - for (i=4; i<0x0f; i++) { - Bitu ct; - LOG_MSG("// video parameter table for mode %x",i); - if ((i>=8) && (i<0x0d)) { - LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); - LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); - LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); - LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); - } else { - INT10_SetVideoMode(i); - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // bios data",real_readb(0x40,0x4a),real_readb(0x40,0x84),real_readb(0x40,0x85),real_readb(0x40,0x4c),real_readb(0x40,0x4d)); - Bitu seq_regs[4]; - for (ct=0; ct<4; ct++) { - IO_WriteB(0x3c4,ct+1); - seq_regs[ct]=IO_ReadB(0x3c5); - } - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // sequencer registers",seq_regs[0],seq_regs[1],seq_regs[2],seq_regs[3]); - LOG_MSG(" 0x%02x, // misc output registers",IO_ReadB(0x3cc)); - Bitu crtc_regs[4]; - Bit16u crt_addr=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); - for (ct=0; ct<0x19; ct++) { - IO_WriteB(crt_addr,ct); - crtc_regs[ct]=IO_ReadB(crt_addr+1); - } - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 0-7", - crtc_regs[0x00],crtc_regs[0x01],crtc_regs[0x02],crtc_regs[0x03], - crtc_regs[0x04],crtc_regs[0x05],crtc_regs[0x06],crtc_regs[0x07]); - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 8-15", - crtc_regs[0x08],crtc_regs[0x09],crtc_regs[0x0a],crtc_regs[0x0b], - crtc_regs[0x0c],crtc_regs[0x0d],crtc_regs[0x0e],crtc_regs[0x0f]); - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 16-24", - crtc_regs[0x10],crtc_regs[0x11],crtc_regs[0x12],crtc_regs[0x13], - crtc_regs[0x14],crtc_regs[0x15],crtc_regs[0x16],crtc_regs[0x17],crtc_regs[0x18]); - Bitu attr_regs[4]; - for (ct=0; ct<0x14; ct++) { - IO_ReadB(crt_addr+6); - IO_WriteB(0x3c0,ct); - attr_regs[ct]=IO_ReadB(0x3c1); - } - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 0-7", - attr_regs[0x00],attr_regs[0x01],attr_regs[0x02],attr_regs[0x03], - attr_regs[0x04],attr_regs[0x05],attr_regs[0x06],attr_regs[0x07]); - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 8-15", - attr_regs[0x08],attr_regs[0x09],attr_regs[0x0a],attr_regs[0x0b], - attr_regs[0x0c],attr_regs[0x0d],attr_regs[0x0e],attr_regs[0x0f]); - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 16-19", - attr_regs[0x10],attr_regs[0x11],attr_regs[0x12],attr_regs[0x13]); - Bitu gfx_regs[4]; - for (ct=0; ct<0x09; ct++) { - IO_WriteB(0x3ce,ct); - gfx_regs[ct]=IO_ReadB(0x3cf); - } - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // graphics registers 0-8", - gfx_regs[0x00],gfx_regs[0x01],gfx_regs[0x02],gfx_regs[0x03], - gfx_regs[0x04],gfx_regs[0x05],gfx_regs[0x06],gfx_regs[0x07],gfx_regs[0x08]); - } - } - for (i=0x0f; i<0x11; i++) { - LOG_MSG("// video parameter table for mode %x (64k graphics memory)",i); - LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); - LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); - LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); - LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); - } - for (i=0x0f; i<0x11; i++) { - Bitu ct; - INT10_SetVideoMode(i); - LOG_MSG("// video parameter table for mode %x (>64k graphics memory)",i); - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // bios data",real_readb(0x40,0x4a),real_readb(0x40,0x84),real_readb(0x40,0x85),real_readb(0x40,0x4c),real_readb(0x40,0x4d)); - Bitu seq_regs[4]; - for (ct=0; ct<4; ct++) { - IO_WriteB(0x3c4,ct+1); - seq_regs[ct]=IO_ReadB(0x3c5); - } - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // sequencer registers",seq_regs[0],seq_regs[1],seq_regs[2],seq_regs[3]); - LOG_MSG(" 0x%02x, // misc output registers",IO_ReadB(0x3cc)); - Bitu crtc_regs[4]; - Bit16u crt_addr=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); - for (ct=0; ct<0x19; ct++) { - IO_WriteB(crt_addr,ct); - crtc_regs[ct]=IO_ReadB(crt_addr+1); - } - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 0-7", - crtc_regs[0x00],crtc_regs[0x01],crtc_regs[0x02],crtc_regs[0x03], - crtc_regs[0x04],crtc_regs[0x05],crtc_regs[0x06],crtc_regs[0x07]); - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 8-15", - crtc_regs[0x08],crtc_regs[0x09],crtc_regs[0x0a],crtc_regs[0x0b], - crtc_regs[0x0c],crtc_regs[0x0d],crtc_regs[0x0e],crtc_regs[0x0f]); - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 16-24", - crtc_regs[0x10],crtc_regs[0x11],crtc_regs[0x12],crtc_regs[0x13], - crtc_regs[0x14],crtc_regs[0x15],crtc_regs[0x16],crtc_regs[0x17],crtc_regs[0x18]); - Bitu attr_regs[4]; - for (ct=0; ct<0x14; ct++) { - IO_ReadB(crt_addr+6); - IO_WriteB(0x3c0,ct); - attr_regs[ct]=IO_ReadB(0x3c1); - } - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 0-7", - attr_regs[0x00],attr_regs[0x01],attr_regs[0x02],attr_regs[0x03], - attr_regs[0x04],attr_regs[0x05],attr_regs[0x06],attr_regs[0x07]); - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 8-15", - attr_regs[0x08],attr_regs[0x09],attr_regs[0x0a],attr_regs[0x0b], - attr_regs[0x0c],attr_regs[0x0d],attr_regs[0x0e],attr_regs[0x0f]); - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 16-19", - attr_regs[0x10],attr_regs[0x11],attr_regs[0x12],attr_regs[0x13]); - Bitu gfx_regs[4]; - for (ct=0; ct<0x09; ct++) { - IO_WriteB(0x3ce,ct); - gfx_regs[ct]=IO_ReadB(0x3cf); - } - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // graphics registers 0-8", - gfx_regs[0x00],gfx_regs[0x01],gfx_regs[0x02],gfx_regs[0x03], - gfx_regs[0x04],gfx_regs[0x05],gfx_regs[0x06],gfx_regs[0x07],gfx_regs[0x08]); - } - for (i=0; i<4; i++) { - LOG_MSG("// video parameter table for mode %x (350 lines)",i); - LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); - LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); - LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); - LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); - } - for (i=0x0e; i<0x14; i++) { - Bitu ct=i; - if (i==0x0e) ct=1; - if (i==0x0f) ct=3; - if (i==0x010) ct=7; - INT10_SetVideoMode(ct); - LOG_MSG("// video parameter table for mode %x",i); - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // bios data",real_readb(0x40,0x4a),real_readb(0x40,0x84),real_readb(0x40,0x85),real_readb(0x40,0x4c),real_readb(0x40,0x4d)); - Bitu seq_regs[4]; - for (ct=0; ct<4; ct++) { - IO_WriteB(0x3c4,ct+1); - seq_regs[ct]=IO_ReadB(0x3c5); - } - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // sequencer registers",seq_regs[0],seq_regs[1],seq_regs[2],seq_regs[3]); - LOG_MSG(" 0x%02x, // misc output registers",IO_ReadB(0x3cc)); - Bitu crtc_regs[4]; - Bit16u crt_addr=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); - for (ct=0; ct<0x19; ct++) { - IO_WriteB(crt_addr,ct); - crtc_regs[ct]=IO_ReadB(crt_addr+1); - } - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 0-7", - crtc_regs[0x00],crtc_regs[0x01],crtc_regs[0x02],crtc_regs[0x03], - crtc_regs[0x04],crtc_regs[0x05],crtc_regs[0x06],crtc_regs[0x07]); - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 8-15", - crtc_regs[0x08],crtc_regs[0x09],crtc_regs[0x0a],crtc_regs[0x0b], - crtc_regs[0x0c],crtc_regs[0x0d],crtc_regs[0x0e],crtc_regs[0x0f]); - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 16-24", - crtc_regs[0x10],crtc_regs[0x11],crtc_regs[0x12],crtc_regs[0x13], - crtc_regs[0x14],crtc_regs[0x15],crtc_regs[0x16],crtc_regs[0x17],crtc_regs[0x18]); - Bitu attr_regs[4]; - for (ct=0; ct<0x14; ct++) { - IO_ReadB(crt_addr+6); - IO_WriteB(0x3c0,ct); - attr_regs[ct]=IO_ReadB(0x3c1); - } - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 0-7", - attr_regs[0x00],attr_regs[0x01],attr_regs[0x02],attr_regs[0x03], - attr_regs[0x04],attr_regs[0x05],attr_regs[0x06],attr_regs[0x07]); - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 8-15", - attr_regs[0x08],attr_regs[0x09],attr_regs[0x0a],attr_regs[0x0b], - attr_regs[0x0c],attr_regs[0x0d],attr_regs[0x0e],attr_regs[0x0f]); - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 16-19", - attr_regs[0x10],attr_regs[0x11],attr_regs[0x12],attr_regs[0x13]); - Bitu gfx_regs[4]; - for (ct=0; ct<0x09; ct++) { - IO_WriteB(0x3ce,ct); - gfx_regs[ct]=IO_ReadB(0x3cf); - } - LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // graphics registers 0-8", - gfx_regs[0x00],gfx_regs[0x01],gfx_regs[0x02],gfx_regs[0x03], - gfx_regs[0x04],gfx_regs[0x05],gfx_regs[0x06],gfx_regs[0x07],gfx_regs[0x08]); - } - INT10_SetVideoMode(3); - E_Exit("done!"); -} - - Bit8u int10_font_08[256 * 8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, @@ -1878,6 +1448,3 @@ Bit8u int10_font_16[256 * 16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - - diff --git a/src/ints/int10_vptable.cpp b/src/ints/int10_vptable.cpp new file mode 100644 index 00000000..ad6d0692 --- /dev/null +++ b/src/ints/int10_vptable.cpp @@ -0,0 +1,703 @@ +/* + * 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: int10_vptable.cpp,v 1.1 2007-10-08 20:22:13 c2woody Exp $ */ + +#include "dosbox.h" +#include "mem.h" +#include "inout.h" +#include "int10.h" + + +static Bit8u video_parameter_table_vga[0x40*0x1d]={ +// video parameter table for mode 0 (cga emulation) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 1 (cga emulation) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 2 (cga emulation) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 3 (cga emulation) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 4 + 0x28, 0x18, 0x08, 0x00, 0x40, // bios data + 0x09, 0x00, 0x00, 0x02, // sequencer registers + 0x63, // misc output registers + 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, 0xff, // crtc registers 16-24 + 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, // attr registers 0-7 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0f, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 5 + 0x28, 0x18, 0x08, 0x00, 0x40, // bios data + 0x09, 0x00, 0x00, 0x02, // sequencer registers + 0x63, // misc output registers + 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, 0xff, // crtc registers 16-24 + 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, // attr registers 0-7 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0f, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 6 + 0x50, 0x18, 0x08, 0x00, 0x40, // bios data + 0x09, 0x0f, 0x00, 0x02, // sequencer registers + 0x63, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2, 0xff, // crtc registers 16-24 + 0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, // attr registers 0-7 + 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, // attr registers 8-15 + 0x01, 0x00, 0x01, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 7 + 0x50, 0x18, 0x10, 0x00, 0x10, // bios data + 0x00, 0x0f, 0x00, 0x07, // sequencer registers + 0x66, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, // attr registers 0-7 + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // attr registers 8-15 + 0x0c, 0x00, 0x0f, 0x08, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 8 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 9 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode a + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode b + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode c + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode d + 0x28, 0x18, 0x08, 0x00, 0x20, // bios data + 0x09, 0x0f, 0x00, 0x02, // sequencer registers + 0x63, // misc output registers + 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // attr registers 0-7 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode e + 0x50, 0x18, 0x08, 0x00, 0x40, // bios data + 0x01, 0x0f, 0x00, 0x02, // sequencer registers + 0x63, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // attr registers 0-7 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode f (64k graphics memory) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 10 (64k graphics memory) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode f (>64k graphics memory) + 0x50, 0x18, 0x0e, 0x00, 0x80, // bios data + 0x01, 0x0f, 0x00, 0x02, // sequencer registers + 0xa2, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, 0xff, // crtc registers 16-24 + 0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, // attr registers 0-7 + 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, // attr registers 8-15 + 0x0b, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 10 (>64k graphics memory) + 0x50, 0x18, 0x0e, 0x00, 0x80, // bios data + 0x01, 0x0f, 0x00, 0x02, // sequencer registers + 0xa3, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, // attr registers 0-7 + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 0 (350 lines) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 1 (350 lines) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 2 (350 lines) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 3 (350 lines) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode e + 0x28, 0x18, 0x10, 0x00, 0x08, // bios data + 0x08, 0x0f, 0x00, 0x07, // sequencer registers + 0x67, // misc output registers + 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, // attr registers 0-7 + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // attr registers 8-15 + 0x0c, 0x00, 0x0f, 0x08, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode f + 0x50, 0x18, 0x10, 0x00, 0x10, // bios data + 0x00, 0x0f, 0x00, 0x07, // sequencer registers + 0x67, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, // attr registers 0-7 + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // attr registers 8-15 + 0x0c, 0x00, 0x0f, 0x08, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 10 + 0x50, 0x18, 0x10, 0x00, 0x10, // bios data + 0x00, 0x0f, 0x00, 0x07, // sequencer registers + 0x66, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, // attr registers 0-7 + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // attr registers 8-15 + 0x0c, 0x00, 0x0f, 0x08, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 11 + 0x50, 0x1d, 0x10, 0x00, 0xa0, // bios data + 0x01, 0x0f, 0x00, 0x02, // sequencer registers + 0xe3, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, // crtc registers 0-7 + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xc3, 0xff, // crtc registers 16-24 + 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, // attr registers 0-7 + 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 12 + 0x50, 0x1d, 0x10, 0x00, 0xa0, // bios data + 0x01, 0x0f, 0x00, 0x02, // sequencer registers + 0xe3, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, // crtc registers 0-7 + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, // attr registers 0-7 + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 13 + 0x28, 0x18, 0x08, 0x00, 0x20, // bios data + 0x01, 0x0f, 0x00, 0x0e, // sequencer registers + 0x63, // misc output registers + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, // crtc registers 0-7 + 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // attr registers 0-7 + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, // attr registers 8-15 + 0x41, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff // graphics registers 0-8 +}; + +static Bit8u video_parameter_table_ega[0x40*0x17]={ +// video parameter table for mode 0 (cga emulation) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 1 (cga emulation) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 2 (cga emulation) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 3 (cga emulation) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 4 + 0x28, 0x18, 0x08, 0x00, 0x40, // bios data + 0x09, 0x03, 0x00, 0x02, // sequencer registers + 0x63, // misc output registers + 0x37, 0x27, 0x28, 0x9a, 0x2b, 0x8a, 0x04, 0x11, // crtc registers 0-7 + 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0xd4, 0x86, 0xc7, 0x14, 0x00, 0xd0, 0xfc, 0xb2, 0xff, // crtc registers 16-24 + 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, // attr registers 0-7 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 5 + 0x28, 0x18, 0x08, 0x00, 0x40, // bios data + 0x09, 0x03, 0x00, 0x02, // sequencer registers + 0x63, // misc output registers + 0x37, 0x27, 0x28, 0x9a, 0x2b, 0x8a, 0x04, 0x11, // crtc registers 0-7 + 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0xd4, 0x86, 0xc7, 0x14, 0x00, 0xd0, 0xfc, 0xb2, 0xff, // crtc registers 16-24 + 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, // attr registers 0-7 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 6 + 0x50, 0x18, 0x08, 0x00, 0x40, // bios data + 0x01, 0x0f, 0x00, 0x06, // sequencer registers + 0x63, // misc output registers + 0x73, 0x4f, 0x50, 0x96, 0x54, 0x94, 0x04, 0x11, // crtc registers 0-7 + 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0xd4, 0x86, 0xc7, 0x28, 0x00, 0xd0, 0xfc, 0xd2, 0xff, // crtc registers 16-24 + 0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, // attr registers 0-7 + 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, // attr registers 8-15 + 0x01, 0x00, 0x01, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 7 + 0x50, 0x18, 0x0e, 0x00, 0x10, // bios data + 0x00, 0x0f, 0x00, 0x03, // sequencer registers + 0xa2, // misc output registers + 0x73, 0x4f, 0x50, 0x96, 0x55, 0x95, 0xb6, 0x1f, // crtc registers 0-7 + 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xb1, 0xb3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // attr registers 0-7 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 + 0x08, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 8 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 9 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode a + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode b + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode c + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode d + 0x28, 0x18, 0x08, 0x00, 0x20, // bios data + 0x09, 0x0f, 0x00, 0x06, // sequencer registers + 0x63, // misc output registers + 0x37, 0x27, 0x28, 0x9a, 0x2b, 0x8a, 0x04, 0x11, // crtc registers 0-7 + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0xd4, 0x86, 0xc7, 0x14, 0x00, 0xd0, 0xfc, 0xd3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // attr registers 0-7 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode e + 0x50, 0x18, 0x08, 0x00, 0x40, // bios data + 0x01, 0x0f, 0x00, 0x06, // sequencer registers + 0x63, // misc output registers + 0x73, 0x4f, 0x50, 0x96, 0x54, 0x94, 0x04, 0x11, // crtc registers 0-7 + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0xd4, 0x86, 0xc7, 0x28, 0x00, 0xd0, 0xfc, 0xd3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // attr registers 0-7 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode f (64k graphics memory) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode 10 (64k graphics memory) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// video parameter table for mode f (>64k graphics memory) + 0x50, 0x18, 0x0e, 0x00, 0x80, // bios data + 0x01, 0x0f, 0x00, 0x06, // sequencer registers + 0xa2, // misc output registers + 0x73, 0x4f, 0x50, 0x96, 0x54, 0x94, 0xb6, 0x1f, // crtc registers 0-7 + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x83, 0x85, 0x5d, 0x14, 0x0f, 0x63, 0xb1, 0x9b, 0xff, // crtc registers 16-24 + 0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, // attr registers 0-7 + 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, // attr registers 8-15 + 0x0b, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 10 (>64k graphics memory) + 0x50, 0x18, 0x0e, 0x00, 0x80, // bios data + 0x01, 0x0f, 0x00, 0x06, // sequencer registers + 0xa3, // misc output registers + 0x5b, 0x4f, 0x50, 0x9e, 0x54, 0x1c, 0x4e, 0x1f, // crtc registers 0-7 + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x83, 0x85, 0x5d, 0x14, 0x0f, 0x63, 0x49, 0x9b, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // attr registers 0-7 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 + 0x01, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 0 (350 lines) + 0x28, 0x18, 0x0e, 0x00, 0x08, // bios data + 0x09, 0x0f, 0x00, 0x03, // sequencer registers + 0xa3, // misc output registers + 0x37, 0x27, 0x28, 0x9a, 0x2b, 0xaa, 0x04, 0x1f, // crtc registers 0-7 + 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x83, 0x85, 0x5d, 0x14, 0x0f, 0x63, 0xff, 0xb3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // attr registers 0-7 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 + 0x08, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 1 (350 lines) + 0x28, 0x18, 0x0e, 0x00, 0x08, // bios data + 0x09, 0x0f, 0x00, 0x03, // sequencer registers + 0xa3, // misc output registers + 0x37, 0x27, 0x28, 0x9a, 0x2b, 0xaa, 0x04, 0x1f, // crtc registers 0-7 + 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x83, 0x85, 0x5d, 0x14, 0x0f, 0x63, 0xff, 0xb3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // attr registers 0-7 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 + 0x08, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 2 (350 lines) + 0x50, 0x18, 0x0e, 0x00, 0x10, // bios data + 0x01, 0x0f, 0x00, 0x03, // sequencer registers + 0xa3, // misc output registers + 0x73, 0x4f, 0x50, 0x96, 0x55, 0x95, 0xb6, 0x1f, // crtc registers 0-7 + 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xb1, 0xb3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // attr registers 0-7 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 + 0x08, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, // graphics registers 0-8 +// video parameter table for mode 3 (350 lines) + 0x50, 0x18, 0x0e, 0x00, 0x10, // bios data + 0x01, 0x0f, 0x00, 0x03, // sequencer registers + 0xa3, // misc output registers + 0x73, 0x4f, 0x50, 0x96, 0x55, 0x95, 0xb6, 0x1f, // crtc registers 0-7 + 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, // crtc registers 8-15 + 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xb1, 0xb3, 0xff, // crtc registers 16-24 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // attr registers 0-7 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // attr registers 8-15 + 0x08, 0x00, 0x0f, 0x00, // attr registers 16-19 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff // graphics registers 0-8 +}; + + +Bitu INT10_SetupVideoParameterTable(PhysPt basepos) { + if (IS_VGA_ARCH) { + for (Bitu i=0;i<0x40*0x1d;i++) { + phys_writeb(basepos+i,video_parameter_table_vga[i]); + } + return 0x40*0x1d; + } else { + for (Bitu i=0;i<0x40*0x17;i++) { + phys_writeb(basepos+i,video_parameter_table_ega[i]); + } + return 0x40*0x17; + } +} + +void INT10_GenerateVideoParameterTable(void) { + if (!IS_VGA_ARCH) E_Exit("Be sure that all graphics registers are readable!"); + Bitu i; + for (i=0; i<4; i++) { + LOG_MSG("// video parameter table for mode %x (cga emulation)",i); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + } + for (i=4; i<0x0f; i++) { + Bitu ct; + LOG_MSG("// video parameter table for mode %x",i); + if ((i>=8) && (i<0x0d)) { + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + } else { + INT10_SetVideoMode(i); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // bios data",real_readb(0x40,0x4a),real_readb(0x40,0x84),real_readb(0x40,0x85),real_readb(0x40,0x4c),real_readb(0x40,0x4d)); + Bitu seq_regs[4]; + for (ct=0; ct<4; ct++) { + IO_WriteB(0x3c4,ct+1); + seq_regs[ct]=IO_ReadB(0x3c5); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // sequencer registers",seq_regs[0],seq_regs[1],seq_regs[2],seq_regs[3]); + LOG_MSG(" 0x%02x, // misc output registers",IO_ReadB(0x3cc)); + Bitu crtc_regs[4]; + Bit16u crt_addr=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + for (ct=0; ct<0x19; ct++) { + IO_WriteB(crt_addr,ct); + crtc_regs[ct]=IO_ReadB(crt_addr+1); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 0-7", + crtc_regs[0x00],crtc_regs[0x01],crtc_regs[0x02],crtc_regs[0x03], + crtc_regs[0x04],crtc_regs[0x05],crtc_regs[0x06],crtc_regs[0x07]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 8-15", + crtc_regs[0x08],crtc_regs[0x09],crtc_regs[0x0a],crtc_regs[0x0b], + crtc_regs[0x0c],crtc_regs[0x0d],crtc_regs[0x0e],crtc_regs[0x0f]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 16-24", + crtc_regs[0x10],crtc_regs[0x11],crtc_regs[0x12],crtc_regs[0x13], + crtc_regs[0x14],crtc_regs[0x15],crtc_regs[0x16],crtc_regs[0x17],crtc_regs[0x18]); + Bitu attr_regs[4]; + for (ct=0; ct<0x14; ct++) { + IO_ReadB(crt_addr+6); + IO_WriteB(0x3c0,ct); + attr_regs[ct]=IO_ReadB(0x3c1); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 0-7", + attr_regs[0x00],attr_regs[0x01],attr_regs[0x02],attr_regs[0x03], + attr_regs[0x04],attr_regs[0x05],attr_regs[0x06],attr_regs[0x07]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 8-15", + attr_regs[0x08],attr_regs[0x09],attr_regs[0x0a],attr_regs[0x0b], + attr_regs[0x0c],attr_regs[0x0d],attr_regs[0x0e],attr_regs[0x0f]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 16-19", + attr_regs[0x10],attr_regs[0x11],attr_regs[0x12],attr_regs[0x13]); + Bitu gfx_regs[4]; + for (ct=0; ct<0x09; ct++) { + IO_WriteB(0x3ce,ct); + gfx_regs[ct]=IO_ReadB(0x3cf); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // graphics registers 0-8", + gfx_regs[0x00],gfx_regs[0x01],gfx_regs[0x02],gfx_regs[0x03], + gfx_regs[0x04],gfx_regs[0x05],gfx_regs[0x06],gfx_regs[0x07],gfx_regs[0x08]); + } + } + for (i=0x0f; i<0x11; i++) { + LOG_MSG("// video parameter table for mode %x (64k graphics memory)",i); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + } + for (i=0x0f; i<0x11; i++) { + Bitu ct; + INT10_SetVideoMode(i); + LOG_MSG("// video parameter table for mode %x (>64k graphics memory)",i); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // bios data",real_readb(0x40,0x4a),real_readb(0x40,0x84),real_readb(0x40,0x85),real_readb(0x40,0x4c),real_readb(0x40,0x4d)); + Bitu seq_regs[4]; + for (ct=0; ct<4; ct++) { + IO_WriteB(0x3c4,ct+1); + seq_regs[ct]=IO_ReadB(0x3c5); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // sequencer registers",seq_regs[0],seq_regs[1],seq_regs[2],seq_regs[3]); + LOG_MSG(" 0x%02x, // misc output registers",IO_ReadB(0x3cc)); + Bitu crtc_regs[4]; + Bit16u crt_addr=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + for (ct=0; ct<0x19; ct++) { + IO_WriteB(crt_addr,ct); + crtc_regs[ct]=IO_ReadB(crt_addr+1); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 0-7", + crtc_regs[0x00],crtc_regs[0x01],crtc_regs[0x02],crtc_regs[0x03], + crtc_regs[0x04],crtc_regs[0x05],crtc_regs[0x06],crtc_regs[0x07]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 8-15", + crtc_regs[0x08],crtc_regs[0x09],crtc_regs[0x0a],crtc_regs[0x0b], + crtc_regs[0x0c],crtc_regs[0x0d],crtc_regs[0x0e],crtc_regs[0x0f]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 16-24", + crtc_regs[0x10],crtc_regs[0x11],crtc_regs[0x12],crtc_regs[0x13], + crtc_regs[0x14],crtc_regs[0x15],crtc_regs[0x16],crtc_regs[0x17],crtc_regs[0x18]); + Bitu attr_regs[4]; + for (ct=0; ct<0x14; ct++) { + IO_ReadB(crt_addr+6); + IO_WriteB(0x3c0,ct); + attr_regs[ct]=IO_ReadB(0x3c1); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 0-7", + attr_regs[0x00],attr_regs[0x01],attr_regs[0x02],attr_regs[0x03], + attr_regs[0x04],attr_regs[0x05],attr_regs[0x06],attr_regs[0x07]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 8-15", + attr_regs[0x08],attr_regs[0x09],attr_regs[0x0a],attr_regs[0x0b], + attr_regs[0x0c],attr_regs[0x0d],attr_regs[0x0e],attr_regs[0x0f]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 16-19", + attr_regs[0x10],attr_regs[0x11],attr_regs[0x12],attr_regs[0x13]); + Bitu gfx_regs[4]; + for (ct=0; ct<0x09; ct++) { + IO_WriteB(0x3ce,ct); + gfx_regs[ct]=IO_ReadB(0x3cf); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // graphics registers 0-8", + gfx_regs[0x00],gfx_regs[0x01],gfx_regs[0x02],gfx_regs[0x03], + gfx_regs[0x04],gfx_regs[0x05],gfx_regs[0x06],gfx_regs[0x07],gfx_regs[0x08]); + } + for (i=0; i<4; i++) { + if (IS_VGA_ARCH) { + LOG_MSG("// video parameter table for mode %x (350 lines)",i); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + LOG_MSG(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"); + } else { + Bitu ct; + INT10_SetVideoMode(i); + LOG_MSG("// video parameter table for mode %x (350 lines)",i); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // bios data",real_readb(0x40,0x4a),real_readb(0x40,0x84),real_readb(0x40,0x85),real_readb(0x40,0x4c),real_readb(0x40,0x4d)); + Bitu seq_regs[4]; + for (ct=0; ct<4; ct++) { + IO_WriteB(0x3c4,ct+1); + seq_regs[ct]=IO_ReadB(0x3c5); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // sequencer registers",seq_regs[0],seq_regs[1],seq_regs[2],seq_regs[3]); + LOG_MSG(" 0x%02x, // misc output registers",IO_ReadB(0x3cc)); + Bitu crtc_regs[4]; + Bit16u crt_addr=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + for (ct=0; ct<0x19; ct++) { + IO_WriteB(crt_addr,ct); + crtc_regs[ct]=IO_ReadB(crt_addr+1); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 0-7", + crtc_regs[0x00],crtc_regs[0x01],crtc_regs[0x02],crtc_regs[0x03], + crtc_regs[0x04],crtc_regs[0x05],crtc_regs[0x06],crtc_regs[0x07]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 8-15", + crtc_regs[0x08],crtc_regs[0x09],crtc_regs[0x0a],crtc_regs[0x0b], + crtc_regs[0x0c],crtc_regs[0x0d],crtc_regs[0x0e],crtc_regs[0x0f]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 16-24", + crtc_regs[0x10],crtc_regs[0x11],crtc_regs[0x12],crtc_regs[0x13], + crtc_regs[0x14],crtc_regs[0x15],crtc_regs[0x16],crtc_regs[0x17],crtc_regs[0x18]); + Bitu attr_regs[4]; + for (ct=0; ct<0x14; ct++) { + IO_ReadB(crt_addr+6); + IO_WriteB(0x3c0,ct); + attr_regs[ct]=IO_ReadB(0x3c1); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 0-7", + attr_regs[0x00],attr_regs[0x01],attr_regs[0x02],attr_regs[0x03], + attr_regs[0x04],attr_regs[0x05],attr_regs[0x06],attr_regs[0x07]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 8-15", + attr_regs[0x08],attr_regs[0x09],attr_regs[0x0a],attr_regs[0x0b], + attr_regs[0x0c],attr_regs[0x0d],attr_regs[0x0e],attr_regs[0x0f]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 16-19", + attr_regs[0x10],attr_regs[0x11],attr_regs[0x12],attr_regs[0x13]); + Bitu gfx_regs[4]; + for (ct=0; ct<0x09; ct++) { + IO_WriteB(0x3ce,ct); + gfx_regs[ct]=IO_ReadB(0x3cf); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // graphics registers 0-8", + gfx_regs[0x00],gfx_regs[0x01],gfx_regs[0x02],gfx_regs[0x03], + gfx_regs[0x04],gfx_regs[0x05],gfx_regs[0x06],gfx_regs[0x07],gfx_regs[0x08]); + } + } + if (IS_VGA_ARCH) { + for (i=0x0e; i<0x14; i++) { + Bitu ct=i; + if (i==0x0e) ct=1; + if (i==0x0f) ct=3; + if (i==0x010) ct=7; + INT10_SetVideoMode(ct); + LOG_MSG("// video parameter table for mode %x",i); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // bios data",real_readb(0x40,0x4a),real_readb(0x40,0x84),real_readb(0x40,0x85),real_readb(0x40,0x4c),real_readb(0x40,0x4d)); + Bitu seq_regs[4]; + for (ct=0; ct<4; ct++) { + IO_WriteB(0x3c4,ct+1); + seq_regs[ct]=IO_ReadB(0x3c5); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // sequencer registers",seq_regs[0],seq_regs[1],seq_regs[2],seq_regs[3]); + LOG_MSG(" 0x%02x, // misc output registers",IO_ReadB(0x3cc)); + Bitu crtc_regs[4]; + Bit16u crt_addr=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + for (ct=0; ct<0x19; ct++) { + IO_WriteB(crt_addr,ct); + crtc_regs[ct]=IO_ReadB(crt_addr+1); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 0-7", + crtc_regs[0x00],crtc_regs[0x01],crtc_regs[0x02],crtc_regs[0x03], + crtc_regs[0x04],crtc_regs[0x05],crtc_regs[0x06],crtc_regs[0x07]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 8-15", + crtc_regs[0x08],crtc_regs[0x09],crtc_regs[0x0a],crtc_regs[0x0b], + crtc_regs[0x0c],crtc_regs[0x0d],crtc_regs[0x0e],crtc_regs[0x0f]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 16-24", + crtc_regs[0x10],crtc_regs[0x11],crtc_regs[0x12],crtc_regs[0x13], + crtc_regs[0x14],crtc_regs[0x15],crtc_regs[0x16],crtc_regs[0x17],crtc_regs[0x18]); + Bitu attr_regs[4]; + for (ct=0; ct<0x14; ct++) { + IO_ReadB(crt_addr+6); + IO_WriteB(0x3c0,ct); + attr_regs[ct]=IO_ReadB(0x3c1); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 0-7", + attr_regs[0x00],attr_regs[0x01],attr_regs[0x02],attr_regs[0x03], + attr_regs[0x04],attr_regs[0x05],attr_regs[0x06],attr_regs[0x07]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 8-15", + attr_regs[0x08],attr_regs[0x09],attr_regs[0x0a],attr_regs[0x0b], + attr_regs[0x0c],attr_regs[0x0d],attr_regs[0x0e],attr_regs[0x0f]); + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 16-19", + attr_regs[0x10],attr_regs[0x11],attr_regs[0x12],attr_regs[0x13]); + Bitu gfx_regs[4]; + for (ct=0; ct<0x09; ct++) { + IO_WriteB(0x3ce,ct); + gfx_regs[ct]=IO_ReadB(0x3cf); + } + LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // graphics registers 0-8", + gfx_regs[0x00],gfx_regs[0x01],gfx_regs[0x02],gfx_regs[0x03], + gfx_regs[0x04],gfx_regs[0x05],gfx_regs[0x06],gfx_regs[0x07],gfx_regs[0x08]); + } + } + INT10_SetVideoMode(3); + E_Exit("done!"); +} diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index b2eb0668..1e81c5e0 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -692,6 +692,9 @@ + + Date: Tue, 9 Oct 2007 08:14:13 +0000 Subject: [PATCH 2925/4131] Fix trimming to 8.3 of files with extenstions.(world championship boxing manager) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3013 --- src/dos/dos_files.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 80ec84ad..6f2fb9a8 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.91 2007-08-22 07:34:57 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.92 2007-10-09 08:14:13 qbix79 Exp $ */ #include #include @@ -161,8 +161,8 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { if (lastdir!=0) strcat(fullname,"\\"); char * ext=strchr(tempdir,'.'); if (ext) { - ext[4]=0; - if (strlen(tempdir)>12) memmove(tempdir+8,ext,5); + ext[4] = 0; + if((strlen(tempdir) - strlen(ext)) > 8) memmove(tempdir + 8, ext, 5); } else tempdir[8]=0; strcat(fullname,tempdir); tempdir[0]=0; From e9e734d8d8983465554251d6ab27efb163460be4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 9 Oct 2007 18:15:42 +0000 Subject: [PATCH 2926/4131] Fixed %% parsing. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3014 --- src/shell/shell_batch.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 3cc3341a..53987c9e 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.24 2007-06-13 07:22:17 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.25 2007-10-09 18:15:42 qbix79 Exp $ */ #include #include @@ -77,6 +77,7 @@ emptyline: if (cmd_read[0] == '%') { cmd_read++; *cmd_write++='%'; + continue; } if (cmd_read[0] == '0') { /* Handle %0 */ const char *file_name = cmd->GetFileName(); From 993f47a01c6af292eddb165097e21216e5c175bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 13 Oct 2007 16:34:06 +0000 Subject: [PATCH 2927/4131] some more ega updates (monitor, height control, text modes) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3015 --- src/hardware/vga_attr.cpp | 16 +++++--- src/hardware/vga_draw.cpp | 4 +- src/hardware/vga_misc.cpp | 28 +++++++------ src/ints/int10_modes.cpp | 84 +++++++++++++++++++++------------------ 4 files changed, 74 insertions(+), 58 deletions(-) diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 7a06a04d..adbf4b45 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: vga_attr.cpp,v 1.26 2007-10-13 16:34:06 c2woody Exp $ */ + #include "dosbox.h" #include "inout.h" #include "vga.h" @@ -27,11 +29,15 @@ void VGA_ATTR_SetPalette(Bit8u index,Bit8u val) { if (vga.attr.mode_control & 0x80) val = (val&0xf) | (vga.attr.color_select << 4); val &= 63; val |= (vga.attr.color_select & 0xc) << 4; - if (GCC_UNLIKELY(!IS_VGA_ARCH)) { - if (val&0x10) val|=0x38; - else { - val&=0x7; - if (val==6) val=0x14; + if (GCC_UNLIKELY(machine==MCH_EGA)) { + if ((vga.crtc.vertical_total | ((vga.crtc.overflow & 1) << 8)) == 260) { + // check for intensity bit + if (val&0x10) val|=0x38; + else { + val&=0x7; + // check for special brown + if (val==6) val=0x14; + } } } VGA_DAC_CombineColor(index,val); diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 365abf7b..779461fe 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: vga_draw.cpp,v 1.86 2007-10-13 16:34:06 c2woody Exp $ */ + #include #include #include "dosbox.h" @@ -790,7 +792,7 @@ void VGA_SetupDrawing(Bitu val) { if (vga.s3.pll.cmd & 0x10) clock/=2; if (IS_VGA_ARCH) vga.draw.double_scan=(vga.crtc.maximum_scan_line&0x80)>0; - else vga.draw.double_scan=(vga.seq.clocking_mode&0x08)>0; // not really correct... + else vga.draw.double_scan=(vtotal==262); } else { htotal = vga.other.htotal + 1; hdend = vga.other.hdend; diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 2da0c33e..d3638c37 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: vga_misc.cpp,v 1.35 2007-10-13 16:34:06 c2woody Exp $ */ + #include "dosbox.h" #include "inout.h" #include "pic.h" @@ -123,28 +125,26 @@ static Bitu read_p3cc(Bitu port,Bitu iolen) { return vga.misc_output; } -/* - -Test 13: Hardware: General Registers - Mode 00h, General -- Feat Ctrl: IBM=00h Current=FFh - Mode 00h, General -- Input Status 0: IBM=70h Current=FFh - .. & modes 1,2,3,4,5,6,d,e,10,11,12,13 - -following read handlers silence the above vgatest errors. - -*/ - +// VGA feature control register static Bitu read_p3ca(Bitu port,Bitu iolen) { return 0; } +static Bitu read_p3c8(Bitu port,Bitu iolen) { + return 0x10; +} + static Bitu read_p3c2(Bitu port,Bitu iolen) { - Bitu retcode=0x70; if (GCC_UNLIKELY(machine==MCH_EGA)) { + Bitu retcode=0x60; retcode |= (vga.draw.vret_triggered ? 0x80 : 0x00); vga.draw.vret_triggered=false; + // ega colour monitor + if ((((vga.misc_output>>2)&3)==0) || (((vga.misc_output>>2)&3)==3)) retcode|=0x10; + return retcode; + } else { + return 0x70; } - return retcode; } void VGA_SetupMisc(void) { @@ -155,6 +155,8 @@ void VGA_SetupMisc(void) { if (IS_VGA_ARCH) { IO_RegisterReadHandler(0x3ca,read_p3ca,IO_MB); IO_RegisterReadHandler(0x3cc,read_p3cc,IO_MB); + } else { + IO_RegisterReadHandler(0x3c8,read_p3c8,IO_MB); } } else if (machine==MCH_CGA || IS_TANDY_ARCH) { IO_RegisterReadHandler(0x3da,vga_read_p3da,IO_MB); diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 1101147e..143327bc 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: int10_modes.cpp,v 1.68 2007-10-13 16:34:06 c2woody Exp $ */ + #include #include "dosbox.h" @@ -106,10 +108,10 @@ VideoModeBlock ModeList_VGA[]={ VideoModeBlock ModeList_EGA[]={ /* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */ -{ 0x000 ,M_TEXT ,320 ,350 ,40 ,25 ,8 ,14 ,8 ,0xB8000 ,0x0800 ,60 ,262 ,40 ,350 ,_EGA_HALF_CLOCK }, -{ 0x001 ,M_TEXT ,320 ,350 ,40 ,25 ,8 ,14 ,8 ,0xB8000 ,0x0800 ,60 ,262 ,40 ,350 ,_EGA_HALF_CLOCK }, -{ 0x002 ,M_TEXT ,640 ,350 ,80 ,25 ,8 ,14 ,8 ,0xB8000 ,0x1000 ,120 ,440 ,80 ,350 ,0 }, -{ 0x003 ,M_TEXT ,640 ,350 ,80 ,25 ,8 ,14 ,8 ,0xB8000 ,0x1000 ,120 ,440 ,80 ,350 ,0 }, +{ 0x000 ,M_TEXT ,320 ,350 ,40 ,25 ,8 ,14 ,8 ,0xB8000 ,0x0800 ,50 ,366 ,40 ,350 ,_EGA_HALF_CLOCK }, +{ 0x001 ,M_TEXT ,320 ,350 ,40 ,25 ,8 ,14 ,8 ,0xB8000 ,0x0800 ,50 ,366 ,40 ,350 ,_EGA_HALF_CLOCK }, +{ 0x002 ,M_TEXT ,640 ,350 ,80 ,25 ,8 ,14 ,8 ,0xB8000 ,0x1000 ,96 ,366 ,80 ,350 ,0 }, +{ 0x003 ,M_TEXT ,640 ,350 ,80 ,25 ,8 ,14 ,8 ,0xB8000 ,0x1000 ,96 ,366 ,80 ,350 ,0 }, { 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,60 ,262 ,40 ,200 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, { 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,60 ,262 ,40 ,200 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, { 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,120 ,262 ,80 ,200 ,_EGA_LINE_DOUBLE}, @@ -117,8 +119,8 @@ VideoModeBlock ModeList_EGA[]={ { 0x00D ,M_EGA ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,60 ,262 ,40 ,200 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, { 0x00E ,M_EGA ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,120 ,262 ,80 ,200 ,_EGA_LINE_DOUBLE }, -{ 0x00F ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,120 ,440 ,80 ,350 ,0 },/*was EGA_2*/ -{ 0x010 ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,96 ,336 ,80 ,350 ,0 }, +{ 0x00F ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,96 ,366 ,80 ,350 ,0 },/*was EGA_2*/ +{ 0x010 ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,96 ,366 ,80 ,350 ,0 }, {0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, }; @@ -538,6 +540,7 @@ bool INT10_SetVideoMode(Bitu mode) { memset(seq_data,0,SEQ_REGS); if (CurMode->cwidth==8) seq_data[1]|=1; //8 dot fonts by default if (CurMode->special & _EGA_HALF_CLOCK) seq_data[1]|=0x08; //Check for half clock + if ((machine==MCH_EGA) && (CurMode->special & _EGA_HALF_CLOCK)) seq_data[1]|=0x02; seq_data[4]|=0x02; //More than 64kb switch (CurMode->type) { case M_TEXT: @@ -621,14 +624,22 @@ bool INT10_SetVideoMode(Bitu mode) { ver_overflow|=((CurMode->vtotal-2) & 0x400) >> 10; Bitu vretrace; - switch (CurMode->vdispend) { - case 400: vretrace=CurMode->vdispend+12; - break; - case 480: vretrace=CurMode->vdispend+10; - break; - case 350: vretrace=CurMode->vdispend+37; - break; - default: vretrace=CurMode->vdispend+12; + if (IS_VGA_ARCH) { + switch (CurMode->vdispend) { + case 400: vretrace=CurMode->vdispend+12; + break; + case 480: vretrace=CurMode->vdispend+10; + break; + case 350: vretrace=CurMode->vdispend+37; + break; + default: vretrace=CurMode->vdispend+12; + } + } else { + switch (CurMode->vdispend) { + case 350: vretrace=CurMode->vdispend; + break; + default: vretrace=CurMode->vdispend+24; + } } /* Vertical Retrace Start */ @@ -647,14 +658,22 @@ bool INT10_SetVideoMode(Bitu mode) { ver_overflow|=((CurMode->vdispend-1) & 0x400) >> 9; Bitu vblank_trim; - switch (CurMode->vdispend) { - case 400: vblank_trim=6; - break; - case 480: vblank_trim=7; - break; - case 350: vblank_trim=5; - break; - default: vblank_trim=8; + if (IS_VGA_ARCH) { + switch (CurMode->vdispend) { + case 400: vblank_trim=6; + break; + case 480: vblank_trim=7; + break; + case 350: vblank_trim=5; + break; + default: vblank_trim=8; + } + } else { + switch (CurMode->vdispend) { + case 350: vblank_trim=0; + break; + default: vblank_trim+23; + } } /* Vertical Blank Start */ @@ -723,9 +742,6 @@ bool INT10_SetVideoMode(Bitu mode) { break; default: offset = CurMode->hdispend/2; - if ((machine==MCH_EGA) && (CurMode->type==M_EGA)) { - if (!(CurMode->special & _EGA_LINE_DOUBLE)) offset/=2; - } } IO_Write(crtc_base,0x13); IO_Write(crtc_base + 1,offset & 0xff); @@ -773,7 +789,6 @@ bool INT10_SetVideoMode(Bitu mode) { mode_control |= 0x08; break; } - if (machine==MCH_EGA) mode_control|=0x10; IO_Write(crtc_base,0x17);IO_Write(crtc_base+1,mode_control); /* Renable write protection */ @@ -870,9 +885,7 @@ bool INT10_SetVideoMode(Bitu mode) { break; case 0x10: case 0x12: - if (IS_VGA_ARCH) - goto att_text16; - // ega fallthrough + goto att_text16; default: if ( CurMode->type == M_LIN4 ) goto att_text16; @@ -897,16 +910,9 @@ bool INT10_SetVideoMode(Bitu mode) { } real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x30); att_text16: - if (machine==MCH_EGA) { - for (i=0;i<8;i++) { - att_data[i]=i; - att_data[i+8]=i+0x10; - } - } else { - for (i=0;i<8;i++) { - att_data[i]=i; - att_data[i+8]=i+0x38; - } + for (i=0;i<8;i++) { + att_data[i]=i; + att_data[i+8]=i+0x38; } if (IS_VGA_ARCH) att_data[0x06]=0x14; //Odd Color 6 yellow/brown. break; From 280c9c083229b41255eef221078a26ed6c3f480d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 14 Oct 2007 13:12:19 +0000 Subject: [PATCH 2928/4131] add textmode character underline feature (see sf patch #1805880) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3016 --- src/hardware/vga_draw.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 779461fe..842ec49a 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.86 2007-10-13 16:34:06 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.87 2007-10-14 13:12:19 c2woody Exp $ */ #include #include @@ -412,12 +412,14 @@ skip_cursor: static Bit8u * VGA_TEXT_Draw_Line_9(Bitu vidstart, Bitu line) { Bits font_addr; Bit8u * draw=(Bit8u *)TempLine; + bool underline=(vga.crtc.underline_location&0x1f)==line; Bit8u pel_pan=vga.config.pel_panning; if ((vga.attr.mode_control&0x20) && (vga.draw.lines_done>=vga.draw.split_line)) pel_pan=0; const Bit8u *vidmem = &vga.tandy.draw_base[vidstart]; Bit8u chr=vidmem[0]; Bit8u col=vidmem[1]; Bit8u font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<>4]&0xff); Bitu draw_blocks=vga.draw.blocks; @@ -426,13 +428,15 @@ static Bit8u * VGA_TEXT_Draw_Line_9(Bitu vidstart, Bitu line) { if (pel_pan) { chr=vidmem[cx*2]; col=vidmem[cx*2+1]; - font|=vga.draw.font_tables[(col >> 3)&1][chr*32+line]>>(8-pel_pan); + if (underline && ((col&0x07) == 0x01)) font|=0xff>>(8-pel_pan); + else font|=vga.draw.font_tables[(col >> 3)&1][chr*32+line]>>(8-pel_pan); fg=col&0xf; bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff); } else { chr=vidmem[(cx-1)*2]; col=vidmem[(cx-1)*2+1]; - font=vga.draw.font_tables[(col >> 3)&1][chr*32+line]; + if (underline && ((col&0x07) == 0x01)) font=0xff; + else font=vga.draw.font_tables[(col >> 3)&1][chr*32+line]; fg=col&0xf; bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff); } @@ -444,8 +448,10 @@ static Bit8u * VGA_TEXT_Draw_Line_9(Bitu vidstart, Bitu line) { Bit8u last=(font&0x01)?fg:bg; *draw++=last; *draw++=((chr<0xc0) || (chr>0xdf)) ? bg : last; - if (pel_pan) - font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<> 3)&1][chr*32+line])<> 1; From 63c2e24aee31364f4ec14d46ffc76c65336ef4ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 14 Oct 2007 17:31:52 +0000 Subject: [PATCH 2929/4131] fix some casts Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3017 --- src/dos/cdrom_image.cpp | 14 ++++++++------ src/dos/dos_programs.cpp | 8 ++++++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 1d035ee2..4d378f80 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.17 2007-08-22 11:54:35 qbix79 Exp $ */ +/* $Id: cdrom_image.cpp,v 1.18 2007-10-14 17:31:52 c2woody Exp $ */ #include #include @@ -604,11 +604,13 @@ bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) Bit8u drive; if (!DOS_MakeName(tmp, fullname, &drive)) return false; - localDrive *ldp = (localDrive*)Drives[drive]; - ldp->GetSystemFilename(tmp, fullname); - if (stat(tmp, &test) == 0) { - filename = tmp; - return true; + localDrive *ldp = dynamic_cast(Drives[drive]); + if (ldp) { + ldp->GetSystemFilename(tmp, fullname); + if (stat(tmp, &test) == 0) { + filename = tmp; + return true; + } } return false; diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 645b3105..108230ab 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.77 2007-08-22 11:54:54 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.78 2007-10-14 17:31:52 c2woody Exp $ */ #include "dosbox.h" #include @@ -1016,7 +1016,11 @@ public: return; } - localDrive *ldp = (localDrive*)Drives[dummy]; + localDrive *ldp = dynamic_cast(Drives[dummy]); + if (ldp==NULL) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FILE_NOT_FOUND")); + return; + } ldp->GetSystemFilename(tmp, fullname); temp_line = tmp; From b8f26b557f1ca1a86ee592dcde30068139be5ca0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 16 Oct 2007 07:29:22 +0000 Subject: [PATCH 2930/4131] Fix compilation under GCC 4.3 (ludwig). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3018 --- src/hardware/gameblaster.cpp | 4 +++- src/hardware/tandy_sound.cpp | 3 ++- src/shell/shell_cmds.cpp | 12 +++++++----- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index bd13f447..d749e984 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include #include "dosbox.h" #include "inout.h" #include "mixer.h" @@ -24,6 +23,9 @@ #include "hardware.h" #include "setup.h" #include "pic.h" +#include +#include + #define LEFT 0x00 #define RIGHT 0x01 diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 23d10421..0dcb4b5c 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -20,7 +20,6 @@ Based of sn76496.c of the M.A.M.E. project */ -#include #include "dosbox.h" #include "inout.h" #include "mixer.h" @@ -28,6 +27,8 @@ #include "setup.h" #include "pic.h" #include "dma.h" +#include +#include #define DAC_CLOCK 3570000 #define MAX_OUTPUT 0x7fff diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 0574bfae..3c1a3f48 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,17 +16,19 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.78 2007-08-17 17:58:46 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.79 2007-10-16 07:29:22 qbix79 Exp $ */ -#include -#include -#include -#include +#include "dosbox.h" #include "shell.h" #include "callback.h" #include "regs.h" #include "../dos/drives.h" #include "support.h" +#include +#include +#include +#include +#include static SHELL_Cmd cmd_list[]={ { "CHDIR", 1, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"}, From 391377b585909eabb212304b6fcdcc13371aa115 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 19 Oct 2007 12:15:40 +0000 Subject: [PATCH 2931/4131] Don't clear bl on succes as it contains the amount of free handles. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3019 --- src/ints/xms.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 7ddd76f3..473df0f3 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.50 2007-08-15 19:09:25 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.51 2007-10-19 12:15:40 qbix79 Exp $ */ #include #include @@ -329,7 +329,7 @@ Bitu XMS_Handler(void) { SET_RESULT(XMS_UnlockMemory(reg_dx)); break; case XMS_GET_EMB_HANDLE_INFORMATION: /* 0e */ - SET_RESULT(XMS_GetHandleInformation(reg_dx,reg_bh,reg_bl,reg_dx)); + SET_RESULT(XMS_GetHandleInformation(reg_dx,reg_bh,reg_bl,reg_dx),false); break; case XMS_RESIZE_ANY_EXTENDED_MEMORY_BLOCK: /* 0x8f */ if(reg_ebx > reg_bx) LOG_MSG("64MB memory limit!"); From a7e852daaca98dba6c96a77c5254e47464e4dd42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 19 Oct 2007 19:39:27 +0000 Subject: [PATCH 2932/4131] fix dos exec "load but don't run" subfunction (japheth) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3020 --- src/dos/dos_execute.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 7ceab107..b181a4c0 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.61 2007-08-09 19:52:33 c2woody Exp $ */ +/* $Id: dos_execute.cpp,v 1.62 2007-10-19 19:39:27 c2woody Exp $ */ #include #include @@ -412,14 +412,18 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { } if (flags==LOAD) { + SaveRegisters(); DOS_PSP callpsp(dos.psp()); /* Save the SS:SP on the PSP of calling program */ callpsp.SetStack(RealMakeSeg(ss,reg_sp)); + reg_sp+=18; /* Switch the psp's */ dos.psp(pspseg); DOS_PSP newpsp(dos.psp()); dos.dta(RealMake(newpsp.GetSegment(),0x80)); - block.exec.initsssp = sssp; + /* First word on the stack is the value ax should contain on startup */ + real_writew(RealSeg(sssp-2),RealOff(sssp-2),0xffff); + block.exec.initsssp = sssp-2; block.exec.initcsip = csip; block.SaveData(); return true; From ecbec7dda08311b111b7d737f1ac271319c7ec34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 19 Oct 2007 20:30:24 +0000 Subject: [PATCH 2933/4131] align vga memory Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3021 --- include/vga.h | 2 +- src/hardware/vga_memory.cpp | 5 ++++- src/ints/int10_modes.cpp | 6 +++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/include/vga.h b/include/vga.h index d0500dbe..6e080aae 100644 --- a/include/vga.h +++ b/include/vga.h @@ -331,7 +331,7 @@ typedef union { } VGA_Latch; typedef struct { - Bit8u linear[VGA_MEMORY]; + Bit8u* linear; } VGA_Memory; typedef struct { diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 76487aff..060644e5 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -870,7 +870,10 @@ void VGA_UnmapMMIO(void) { void VGA_SetupMemory() { - memset( &vga.mem, 0, VGA_MEMORY ); + // allocate 16byte-aligned memory + vga.mem.linear = new Bit8u[VGA_MEMORY+16]; + vga.mem.linear=(Bit8u*)(((Bitu)vga.mem.linear + 16-1) & ~(16-1)); + memset( vga.mem.linear, 0, VGA_MEMORY ); #ifdef VGA_KEEP_CHANGES memset( &vga.changes, 0, sizeof( vga.changes )); #endif diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 143327bc..efd1fe12 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.68 2007-10-13 16:34:06 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.69 2007-10-19 20:30:24 c2woody Exp $ */ #include @@ -277,7 +277,7 @@ static void FinishSetMode(bool clearmem) { case M_LIN16: case M_LIN32: /* Hack we just acess the memory directly */ - memset(&vga.mem,0,sizeof(vga.mem)); + memset(vga.mem.linear,0,VGA_MEMORY); } } /* Setup the BIOS */ @@ -672,7 +672,7 @@ bool INT10_SetVideoMode(Bitu mode) { switch (CurMode->vdispend) { case 350: vblank_trim=0; break; - default: vblank_trim+23; + default: vblank_trim=23; } } From 57dc3947b3ed193f6f01edca4e68499941997b7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 20 Oct 2007 16:01:40 +0000 Subject: [PATCH 2934/4131] that one, too... Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3022 --- src/hardware/vga_memory.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 060644e5..71905f75 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -15,7 +15,9 @@ * 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_memory.cpp,v 1.44 2007-10-20 16:01:40 c2woody Exp $ */ + #include #include #include "dosbox.h" @@ -857,7 +859,7 @@ void VGA_StartUpdateLFB(void) { #else vga.lfb.handler = &vgaph.lfbchanges; #endif - MEM_SetLFB(vga.s3.la_window << 4 ,sizeof(vga.mem.linear)/4096, vga.lfb.handler ); + MEM_SetLFB(vga.s3.la_window << 4 ,VGA_MEMORY/4096, vga.lfb.handler ); } void VGA_MapMMIO(void) { From de72a62e4a605ea6198ab69dddfb92638050e7b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 20 Oct 2007 19:13:59 +0000 Subject: [PATCH 2935/4131] create temp file adds a missing backslash to the path qualifier if necessary Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3023 --- src/dos/dos_files.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 6f2fb9a8..0c37e33e 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.92 2007-10-09 08:14:13 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.93 2007-10-20 19:13:59 c2woody Exp $ */ #include #include @@ -641,8 +641,15 @@ bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry) { bool DOS_CreateTempFile(char * const name,Bit16u * entry) { /* First add random crap to the end of the name and try to open */ - char * tempname; - tempname=name+strlen(name); + size_t namelen=strlen(name); + char * tempname=name+namelen; + if (namelen==0) E_Exit("DOS:Invalid call to CreateTempFile"); + else { + if ((name[namelen-1]!='\\') && (name[namelen-1]!='/')) { + tempname[0]='\\'; + tempname++; + } + } dos.errorcode=0; do { Bit32u i; From 2f33a0fd249a06c7143f69f71078bb649eed5240 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 21 Oct 2007 08:43:24 +0000 Subject: [PATCH 2936/4131] Add function to list all configuration details. (moe) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3024 --- include/setup.h | 4 +++- src/misc/setup.cpp | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/setup.h b/include/setup.h index 39f57604..ad50ddfc 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.27 2007-06-14 08:23:46 qbix79 Exp $ */ +/* $Id: setup.h,v 1.28 2007-10-21 08:43:24 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -168,6 +168,7 @@ public: void Add_hex(char const * const _propname, int _value=0); void Add_float(char const * const _propname, float _value=0.0); + Property* Get_prop(int index); int Get_int(char const * const _propname) const; const char* Get_string(char const * const _propname) const; bool Get_bool(char const * const _propname) const; @@ -207,6 +208,7 @@ public: 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(char const* const _sectionname) const; Section* GetSectionFromProperty(char const * const prop) const; diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index ace47e87..842cbdfc 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.40 2007-06-27 14:51:30 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.41 2007-10-21 08:43:24 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -129,6 +129,13 @@ float Section_prop::Get_float(char const * const _propname) const { return false; } +Property* Section_prop::Get_prop(int index){ + for(it tel=properties.begin();tel!=properties.end();tel++){ + if(!index--) return (*tel); + } + return NULL; +} + const char* Section_prop::Get_string(char const * const _propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ @@ -290,6 +297,13 @@ Config::~Config() { } } +Section* Config::GetSection(int index){ + for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ + if (!index--) return (*tel); + } + return NULL; +} + Section* Config::GetSection(char const * const _sectionname) const{ for (const_it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ if (!strcasecmp((*tel)->GetName(),_sectionname)) return (*tel); From 5a17afaca5c943e0a36fbf86e1be4a9c0846975b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 28 Oct 2007 10:58:50 +0000 Subject: [PATCH 2937/4131] Change Batchfile constructor.(Silences a few warnings). Introduce batchfile friend editor(moe). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3025 --- include/shell.h | 10 ++++++---- src/shell/shell_batch.cpp | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/include/shell.h b/include/shell.h index a238e3e1..32032f9d 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.21 2007-06-14 08:23:46 qbix79 Exp $ */ +/* $Id: shell.h,v 1.22 2007-10-28 10:58:49 qbix79 Exp $ */ #ifndef DOSBOX_SHELL_H #define DOSBOX_SHELL_H @@ -44,9 +44,9 @@ class DOS_Shell; class BatchFile { public: - BatchFile(DOS_Shell * host,char * name, char * cmd_line); - ~BatchFile(); - bool ReadLine(char * line); + 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; @@ -56,8 +56,10 @@ public: CommandLine * cmd; }; +class AutoexecEditor; class DOS_Shell : public Program { private: + friend class AutoexecEditor; std::list l_history, l_completion; char *completion_start; diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 53987c9e..84893f7b 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.25 2007-10-09 18:15:42 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.26 2007-10-28 10:58:50 qbix79 Exp $ */ #include #include @@ -24,7 +24,7 @@ #include "shell.h" #include "support.h" -BatchFile::BatchFile(DOS_Shell * host,char * name, char * cmd_line) { +BatchFile::BatchFile(DOS_Shell * host,char const * const name, char const * const cmd_line) { prev=host->bf; echo=host->echo; shell=host; From 65971d4252f4a66591d409eb7f9af50cee047246 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 28 Oct 2007 16:33:02 +0000 Subject: [PATCH 2938/4131] add menu lib from Moe. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3026 --- src/libs/gui_tk/Doxyfile | 238 ++++ src/libs/gui_tk/Makefile.am | 4 + src/libs/gui_tk/gui_tk.cpp | 1705 +++++++++++++++++++++++++++ src/libs/gui_tk/gui_tk.h | 2221 +++++++++++++++++++++++++++++++++++ 4 files changed, 4168 insertions(+) create mode 100644 src/libs/gui_tk/Doxyfile create mode 100644 src/libs/gui_tk/Makefile.am create mode 100644 src/libs/gui_tk/gui_tk.cpp create mode 100644 src/libs/gui_tk/gui_tk.h diff --git a/src/libs/gui_tk/Doxyfile b/src/libs/gui_tk/Doxyfile new file mode 100644 index 00000000..598d6fef --- /dev/null +++ b/src/libs/gui_tk/Doxyfile @@ -0,0 +1,238 @@ +# Doxyfile 1.5.2 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = gui::tk +PROJECT_NUMBER = "Version 1.0" +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = . +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = YES +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +BUILTIN_STL_SUPPORT = YES +CPP_CLI_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = NO +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = . +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = gui_tk.h \ + gui_tk.cpp +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = TESTING SDL_MAJOR_VERSION +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = DOSBox.tag +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = YES +TEMPLATE_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = YES +CALLER_GRAPH = YES +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +DOT_TRANSPARENT = YES +DOT_MULTI_TARGETS = YES +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/src/libs/gui_tk/Makefile.am b/src/libs/gui_tk/Makefile.am new file mode 100644 index 00000000..de7764ed --- /dev/null +++ b/src/libs/gui_tk/Makefile.am @@ -0,0 +1,4 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include + +noinst_LIBRARIES = libgui_tk.a +libgui_tk_a_SOURCES = gui_tk.cpp gui_tk.h diff --git a/src/libs/gui_tk/gui_tk.cpp b/src/libs/gui_tk/gui_tk.cpp new file mode 100644 index 00000000..8cbe59d6 --- /dev/null +++ b/src/libs/gui_tk/gui_tk.cpp @@ -0,0 +1,1705 @@ +/* + * gui_tk - framework-agnostic GUI toolkit + * Copyright (C) 2005-2007 Jörg Walter + * + * gui_tk 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 3 of the License, or + * (at your option) any later version. + * + * gui_tk 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, see + */ + +/* TODO: + - make menu a bufferedwindow with shadow +*/ +/* $Id: gui_tk.cpp,v 1.1 2007-10-28 16:33:02 qbix79 Exp $ */ + +/** \file + * \brief Implementation file for gui_tk. + * + * It contains implementations for all non-inlined class methods. + * + * Also contained is a small test program that demonstrates all features of + * gui_tk. It is enabled by defining the preprocessor macro TESTING. + */ + +#include +#include "gui_tk.h" + +namespace GUI { + +namespace Color { + +RGB Background3D = 0xffc0c0c0; + +RGB Light3D = 0xfffcfcfc; + +RGB Shadow3D = 0xff808080; + +RGB Border = 0xff000000; + +RGB Text = 0xff000000; + +RGB Background = 0xffc0c0c0; + +RGB SelectionBackground = 0xff000080; + +RGB SelectionForeground = 0xffffffff; + +RGB EditableBackground = 0xffffffff; + +RGB Titlebar = 0xff000080; + +RGB TitlebarText = 0xffffffff; + +} + +void Drawable::drawText(const String& text, bool interpret, Size start, Size len) { + if (interpret) { + if (len > text.size()-start) len = text.size()-start; + len += start; + + Size wordstart = start; + int width = 0; + + while (start < len) { + switch (font->toSpecial(text[start])) { + case Font::CR: + if (wordstart != start) { + drawText(text,false,wordstart,start-wordstart); + wordstart = start; + width = 0; + } + wordstart++; + gotoXY(0,y); + break; + case Font::LF: + if (wordstart != start) { + drawText(text,false,wordstart,start-wordstart); + wordstart = start; + width = 0; + } + wordstart++; + gotoXY(0,y+font->getHeight()); + break; + case Font::BS: + if (wordstart != start) { + drawText(text,false,wordstart,start-wordstart); + wordstart = start; + width = 0; + } + wordstart++; + gotoXY(imax(0,x-font->getWidth()),y); + break; + case Font::Tab: + if (wordstart != start) { + drawText(text,false,wordstart,start-wordstart); + wordstart = start; + width = 0; + } + wordstart++; + gotoXY((((int)(x/font->getWidth()/8))+1)*8*font->getWidth(),y); + break; + case Font::Space: + if (wordstart != start) { + drawText(text,false,wordstart,start-wordstart); + wordstart = start; + width = 0; + } + wordstart++; + font->drawString(this,text,start,1); + break; + case Font::ESC: // ignore ANSI sequences except for colors + if (wordstart != start) { + drawText(text,false,wordstart,start-wordstart); + wordstart = start; + width = 0; + } + wordstart++; + do { + int seqstart = start+1; + Char c; + do { + start++; + wordstart++; + c = font->toSpecial(text[start]); + } while (start < len && ((c >= '0' && c <= '9') || c == ';' || c == '[')); + if (c == 'm' && start < len) { + if (font->toSpecial(text[seqstart++]) != '[') break; + c = font->toSpecial(text[seqstart++]); + while (c != 'm') { + int param = 0; + if (c == ';') c = '0'; + while (c != 'm' && c != ';') { + param = param * 10 + c-'0'; + c = font->toSpecial(text[seqstart++]); + } + const RGB bright = 0x00808080; + const RGB intensity = (color&bright?~0:~bright); + switch (param) { + case 0: setColor(Color::Black); break; + case 1: setColor(color | 0x00808080); break; + case 30: setColor(Color::Black|bright & intensity); break; + case 31: setColor(Color::Red & intensity); break; + case 32: setColor(Color::Green & intensity); break; + case 33: setColor(Color::Yellow & intensity); break; + case 34: setColor(Color::Blue & intensity); break; + case 35: setColor(Color::Magenta & intensity); break; + case 36: setColor(Color::Cyan & intensity); break; + case 37: setColor(Color::White & intensity); break; + default: break; + } + } + } + } while (0); + default: + width += font->getWidth(text[start]); + if (x > 0 && x+width > cw) gotoXY(0,y+font->getHeight()); + } + start++; + } + if (wordstart != start) drawText(text,false,wordstart,start-wordstart); + return; + } + + font->drawString(this,text,start,len); +} + +bool ToplevelWindow::mouseDown(int x, int y, MouseButton button) { + if (button == Left && x > 32 && x < width-6 && y > 4 && y < 31) { + dragx = x; + dragy = y; + mouseChild = NULL; + systemMenu->setVisible(false); + return true; + } else if (button == Left && x < 32 && x > 6 && y > 4 && y < 31) { + mouseChild = NULL; + raise(); + systemMenu->setVisible(!systemMenu->isVisible()); + return true; + } + systemMenu->setVisible(false); + BorderedWindow::mouseDown(x,y,button); + return true; +} + +Drawable::Drawable(int w, int h, RGB clear) : + buffer(new RGB[w*h]), + width(w), height(h), + owner(true), + color(Color::Black), + font(NULL), + lineWidth(1), + tx(0), ty(0), + cx(0), cy(0), + cw(w), ch(h), + x(0), y(0) +{ + this->clear(clear); +} + +Drawable::Drawable(Drawable &src, RGB clear) : + buffer(new RGB[src.cw*src.ch]), + width(src.cw), height(src.ch), + owner(true), + color(src.color), + font(src.font), + lineWidth(src.lineWidth), + tx(0), ty(0), + cx(0), cy(0), + cw(src.cw), ch(src.ch), + x(src.x), y(src.y) +{ + if (clear != 0) { + this->clear(clear); + } else { + for (int h = 0; h < src.ch; h++) { + memcpy(buffer+src.cw*h,src.buffer+src.width*(h+src.ty)+src.tx,4*src.cw); + } + } +} + +Drawable::Drawable(Drawable &src, int x, int y, int w, int h) : + buffer(src.buffer), + width(src.width), height(src.height), + owner(false), + color(src.color), + font(src.font), + lineWidth(src.lineWidth), + tx(src.tx+x), ty(src.ty+y), + cx(imax(imax(-x,src.cx-x),0)), cy(imax(imax(-y,src.cy-y),0)), + cw(imax(0,imin(src.cw-x,w))), ch(imax(0,imin(src.ch-y,h))), + x(imax(0,imin(src.tx-tx,cw))), y(imax(0,imin(src.ty-ty,cw))) +{ +} + +Drawable::~Drawable() +{ + if (owner) delete[] buffer; +} + +void Drawable::clear(RGB clear) +{ + for (int y = cy; y < ch; y++) { + for (int x = cx; x < cw; x++) { + buffer[(y+ty)*width+x+tx] = clear; + } + } +} + +void Drawable::drawLine(int x2, int y2) +{ + int x0 = x2, x1 = x, y0 = y2, y1 = y; + int dx = x2-x1, dy = y2-y1; + drawPixel(); + + if (abs(dx) > abs(dy)) { + if (x1 > x2) { + x = x2; x2 = x1; x1 = x; + y = y2; y2 = y1; y1 = y; + } + for (x = x1; x <= x2; x++) { + y = y1+(x-x1)*dy/dx-lineWidth/2; + for (int i = 0; i < lineWidth; i++, y++) { + drawPixel(); + } + } + } else if (y1 != y2) { + if (y1 > y2) { + x = x2; x2 = x1; x1 = x; + y = y2; y2 = y1; y1 = y; + } + for (y = y1; y <= y2; y ++) { + x = x1+(y-y1)*dx/dy-lineWidth/2; + for (int i = 0; i < lineWidth; i++, x++) { + drawPixel(); + } + } + } + + drawPixel(x0,y0); +} + +void Drawable::drawCircle(int d) { + int xo = 0, yo = d/2, rest = (d+1)/2-yo, x0 = x, y0 = y, rsq = d*d/4, lwo = lineWidth/2; + + while (xo <= yo) { + while (xo*xo+(2*yo-1)*(2*yo-1)/4 > rsq) yo--; + for (int i = 0, yow = yo+lwo; i < lineWidth; i++, yow--) { + drawPixel(x0+xo,y0-yow-rest); + drawPixel(x0+yow,y0-xo-rest); + drawPixel(x0+yow,y0+xo); + drawPixel(x0+xo,y0+yow); + + drawPixel(x0-xo-rest,y0-yow-rest); + drawPixel(x0-yow-rest,y0-xo-rest); + drawPixel(x0-yow-rest,y0+xo); + drawPixel(x0-xo-rest,y0+yow); + } + + xo++; + } + gotoXY(x0,y0); +} + +void Drawable::drawRect(int w, int h) +{ + gotoXY(x-lineWidth/2,y); + drawLine(x+w+lineWidth-1,y); + gotoXY(x-(lineWidth-1)/2,y); + drawLine(x,y+h); + gotoXY(x+(lineWidth-1)/2,y); + drawLine(x-w-lineWidth+1,y); + gotoXY(x+lineWidth/2,y); + drawLine(x,y-h); +} + +void Drawable::fill() +{ + int x0 = x, xmin; + RGB color = getPixel(); + + if (color == this->color) return; + + for (x--; x >= 0 && getPixel() == color; x--) drawPixel(); + xmin = ++x; + for (x = x0; x < cw && getPixel() == color; x++) drawPixel(); + y++; + for (x--; x >= xmin; x--) { + if (getPixel() == color) fill(); + y -= 2; + if (getPixel() == color) fill(); + y += 2; + } + y--; + x = x0; +} + +void Drawable::fillCircle(int d) +{ + int xo = 0, yo = d/2, rest = (d+1)/2-yo, x0 = x, y0 = y, rsq = d*d/4; + + while (xo <= yo) { + while (xo*xo+(2*yo-1)*(2*yo-1)/4 > rsq) yo--; + x = x0+xo; + for (y = y0-yo-rest; y <= y0+yo; y++) drawPixel(); + x = x0-xo-rest; + for (y = y0-yo-rest; y <= y0+yo; y++) drawPixel(); + + y = y0-xo-rest; + for (x = x0-yo-rest; x <= x0+yo; x++) drawPixel(); + y = y0+xo; + for (x = x0-yo-rest; x <= x0+yo; x++) drawPixel(); + + xo++; + } + gotoXY(x0,y0); +} + +void Drawable::fillRect(int w, int h) +{ + int x0 = x, y0 = y, w0 = w; + for (; h > 0; h--, y++) { + for (x = x0, w = w0; w > 0; w--, x++) { + drawPixel(); + } + } + gotoXY(x0,y0); +} + +void Drawable::drawDrawable(Drawable &d, unsigned char alpha) +{ + int scw = d.cw, sch = d.ch, w, h; + RGB *src, *dest; + + for (h = imax(d.cy,-ty-y); h < sch && y+h < ch; h++) { + src = d.buffer+d.width*(h+d.ty)+d.tx; + dest = buffer+width*(y+ty+h)+tx+x; + for (w = imax(d.cx,-tx-x); w < scw && x+w < cw; w++) { + RGB srcb = src[w], destb = dest[w]; + unsigned int sop = Color::A(srcb)*((unsigned int)alpha)/255; + unsigned int rop = Color::A(destb) + sop - Color::A(destb)*sop/255; + if (rop == 0) { + dest[w] = Color::Transparent; + } else { + unsigned int dop = Color::A(destb)*(255-sop)/255; + unsigned int magval = ((destb&Color::MagentaMask)*dop+(srcb&Color::MagentaMask)*sop); + dest[w] = (((magval&0xffff)/rop)&Color::BlueMask) | + (((magval&0xffff0000)/rop)&Color::RedMask) | + ((((destb&Color::GreenMask)*dop+(srcb&Color::GreenMask)*sop)/rop)&Color::GreenMask) | + (rop<toSpecial(c)) { + case Font::CR: gotoXY(0,y); return; + case Font::LF: gotoXY(0,y+font->getHeight()); return; + case Font::BS: gotoXY(imax(0,x-font->getWidth()),y); return; + case Font::Tab: gotoXY((((int)(x/font->getWidth()/8))+1)*8*font->getWidth(),y); return; + default: break; + } + if (font->getWidth(c)+x > cw) gotoXY(0,y+font->getHeight()); + } + font->drawChar(this,c); +} + +#define move(x) (ptr += ((x)+bit)/8-(((x)+bit)<0), bit = ((x)+bit+(((x)+bit)<0?8:0))%8) +void BitmapFont::drawChar(Drawable *d, const Char c) const { + const unsigned char *ptr = bitmap; + int bit = 0; + + if (c > last) return; + + if (char_position != NULL) { + ptr = char_position[c]; + bit = 0; + } else { + move(character_step*c); + } + + int rs = row_step; + int w = (widths != NULL?widths[c]:width); + int h = (ascents != NULL?ascents[c]:height); + Drawable out(*d,d->getX(),d->getY()-ascent,w,h); + + if (rs == 0) rs = isign(col_step)*w; + if (rs < 0) move(-rs*(h-1)); + if (col_step < 0) move(abs(rs)-1); + + for (int row = height-h; row < height; row++, move(rs-w*col_step)) { + for (int col = 0; col < w; col++, move(col_step)) { + if (!background_set ^ !(*ptr&(1<gotoXY(d->getX()+w,d->getY()); +} +#undef move + +std::map Font::registry; + +void Timer::check(unsigned int ticks) +{ + if (timers.empty()) return; + + if (Timer::ticks > (Timer::ticks+ticks)) { + ticks -= -1-Timer::ticks; + check(-1-Timer::ticks); + } + + std::multimap::iterator old, i = timers.lower_bound(Timer::ticks+1); + Timer::ticks += ticks; + + while (i != timers.end() && (*i).first <= Timer::ticks) { + Timer_Callback *c = (*i).second; + unsigned int time = (*i).first; + old = i; + ++i; + timers.erase(old); + unsigned int next = c->timerExpired(time); + if (next) add(c, time+next-Timer::ticks); + } +} + +void Timer::remove(const Timer_Callback *const timer) +{ + if (timers.empty()) return; + + std::multimap::iterator old, i = timers.begin(); + + while (i != timers.end()) { + old = i; + ++i; + if ((*old).second == timer) timers.erase(old); + } +} + +unsigned int Timer::next() +{ + if (timers.empty()) return 0; + + std::multimap::iterator i = timers.upper_bound(ticks); + + if (i == timers.end()) return 0; + return (*i).first-Timer::ticks; +} + +std::multimap Timer::timers; +unsigned int Timer::ticks = 0; + +BitmapFont::BitmapFont(const unsigned char *data, int height, int ascent, bool owner, + int width, bool background_set, + int col_step, int row_step, int character_step, Char last, + const int *widths, const int *ascents, const unsigned char *const* char_position, + const Font::SpecialChar *special) : + bitmap(data), + width(width), height(height), ascent(ascent), widths(widths), ascents(ascents), + background_set(background_set), col_step(col_step), row_step(row_step), + character_step(character_step?character_step:abs((row_step?row_step:width*col_step)*height)), + char_position(char_position), special(special), owner(owner), last(last) +{ +} + +BitmapFont::~BitmapFont() { + if (owner) { + if (bitmap != NULL) delete bitmap; + if (ascents != NULL) delete ascents; + if (widths != NULL) delete widths; + if (special != NULL) delete special; + } +} + +Window::Window(Window *parent, int x, int y, int w, int h) : + width(w), height(h), + x(x), y(y), + dirty(true), + visible(true), + parent(parent), + mouseChild(NULL) +{ + parent->addChild(this); +} + +Window::Window() : + width(0), height(0), + x(0), y(0), + dirty(false), + visible(true), + parent(NULL), + mouseChild(NULL) +{ +} + + +Window::~Window() +{ + while (!children.empty()) delete children.front(); + if (parent) parent->removeChild(this); + if (parent && parent->mouseChild == this) parent->mouseChild = NULL; +} + +void Window::addChild(Window *child) +{ + children.push_back(child); + setDirty(); +} + +void Window::removeChild(Window *child) +{ + children.remove(child); + setDirty(); +} + +void Window::move(int x, int y) +{ + this->x = x; + this->y = y; + std::list::iterator i = movehandlers.begin(); + bool end = (i == movehandlers.end()); + while (!end) { + Window_Callback *c = *i; + ++i; + end = (i == movehandlers.end()); + c->windowMoved(this,x,y); + } + parent->setDirty(); +} + +void Window::resize(int w, int h) +{ + this->width = w; + this->height = h; + setDirty(); +} + +void Window::paintAll(Drawable &d) const +{ + paint(d); + std::list::const_iterator i = children.begin(); + while (i != children.end()) { + Window *child = *i; + ++i; + if (child->visible) { + Drawable *cd = new Drawable(d,child->x,child->y,child->width,child->height); + child->paintAll(*cd); + delete cd; + } + } +} + +bool Window::keyDown(const Key &key) +{ + if (children.empty()) return false; + if ((*children.rbegin())->keyDown(key)) return true; + if (key.ctrl || key.alt || key.windows || key.special != Key::Tab) return false; + + if (key.shift) { + std::list::reverse_iterator i = children.rbegin(), e = children.rend(); + ++i; + while (i != e && !(*i)->raise()) ++i; + return i != e; + } else { + std::list::iterator i = children.begin(), e = children.end(); + while (i != e && !(*i)->raise()) ++i; + return (i != e); + } +} + +bool Window::keyUp(const Key &key) +{ + if (children.empty()) return false; + return (*children.rbegin())->keyUp(key); +} + +bool Window::mouseMoved(int x, int y) +{ + std::list::reverse_iterator i = children.rbegin(); + bool end = (i == children.rend()); + while (!end) { + Window *w = *i; + i++; + end = (i == children.rend()); + if (w->visible && x >= w->x && x <= w->x+w->width + && y >= w->y && y <= w->y+w->height + && w->mouseMoved(x-w->x, y-w->y)) return true; + } + return false; +} + +bool Window::mouseDragged(int x, int y, MouseButton button) +{ + if (mouseChild == NULL) return false; + return mouseChild->mouseDragged(x-mouseChild->x, y-mouseChild->y, button); +} + +bool Window::mouseDown(int x, int y, MouseButton button) +{ + Window *last = NULL; + std::list::reverse_iterator i = children.rbegin(); + bool end = (i == children.rend()); + while (!end) { + Window *w = *i; + i++; + end = (i == children.rend()); + if (w->visible && x >= w->x && x <= w->x+w->width + && y >= w->y && y <= w->y+w->height + && (mouseChild = last = w) + && w->mouseDown(x-w->x, y-w->y, button) + && w->raise()) { + return true; + } + } + mouseChild = NULL; + if (last != NULL) last->raise(); + return false; +} + +bool Window::mouseUp(int x, int y, MouseButton button) +{ + if (mouseChild == NULL) return false; + return mouseChild->mouseUp(x-mouseChild->x, y-mouseChild->y, button); +} + +bool Window::mouseClicked(int x, int y, MouseButton button) +{ + if (mouseChild == NULL) return false; + return mouseChild->mouseClicked(x-mouseChild->x, y-mouseChild->y, button); +} + +bool Window::mouseDoubleClicked(int x, int y, MouseButton button) +{ + if (mouseChild == NULL) return false; + return mouseChild->mouseDoubleClicked(x-mouseChild->x, y-mouseChild->y, button); +} + +bool BorderedWindow::mouseDown(int x, int y, MouseButton button) +{ + mouseChild = NULL; + if (x > width-border_right || y > width-border_bottom) return false; + x -= border_left; y -= border_top; + if (x < 0 || y < 0) return false; + return Window::mouseDown(x,y,button); +} + +bool BorderedWindow::mouseMoved(int x, int y) +{ + if (x > width-border_right || y > width-border_bottom) return false; + x -= border_left; y -= border_top; + if (x < 0 || y < 0) return false; + return Window::mouseMoved(x,y); +} + +bool BorderedWindow::mouseDragged(int x, int y, MouseButton button) +{ + if (x > width-border_right || y > width-border_bottom) return false; + x -= border_left; y -= border_top; + if (x < 0 || y < 0) return false; + return Window::mouseDragged(x,y,button); +} + +void ToplevelWindow::paint(Drawable &d) const +{ + int mask = (systemMenu->isVisible()?Color::RedMask|Color::GreenMask|Color::BlueMask:0); + d.clear(Color::Background); + + d.setColor(Color::Border); + d.drawLine(0,height-1,width-1,height-1); + d.drawLine(width-1,0,width-1,height-1); + + d.setColor(Color::Shadow3D); + d.drawLine(0,0,width-2,0); + d.drawLine(0,0,0,height-2); + d.drawLine(0,height-2,width-2,height-2); + d.drawLine(width-2,0,width-2,height-2); + + d.drawLine(5,4,width-7,4); + d.drawLine(5,4,5,30); + + d.setColor(Color::Light3D); + d.drawLine(1,1,width-3,1); + d.drawLine(1,1,1,height-3); + + d.drawLine(5,31,width-6,31); + d.drawLine(width-6,5,width-6,31); + + d.setColor(Color::Background3D^mask); + d.fillRect(6,5,26,26); + d.setColor(Color::Grey50^mask); + d.fillRect(9,17,20,4); + d.setColor(Color::Black^mask); + d.fillRect(8,16,20,4); + d.setColor(Color::White^mask); + d.fillRect(9,17,18,2); + + d.setColor(Color::Border); + d.drawLine(32,5,32,30); + + d.setColor(Color::Titlebar); + d.fillRect(33,5,width-39,26); + + const Font *font = Font::getFont("title"); + d.setColor(Color::TitlebarText); + d.setFont(font); + d.drawText(31+(width-39-font->getWidth(title))/2,5+(26-font->getHeight())/2+font->getAscent(),title,false,0); +} + +void Input::paint(Drawable &d) const +{ + d.clear(Color::EditableBackground); + + d.setColor(Color::Shadow3D); + d.drawLine(0,0,width-2,0); + d.drawLine(0,0,0,height-2); + + d.setColor(Color::Background3D); + d.drawLine(1,height-2,width-2,height-2); + d.drawLine(width-2,1,width-2,height-2); + + d.setColor(Color::Text); + d.drawLine(1,1,width-3,1); + d.drawLine(1,1,1,height-3); + + const Font *f = Font::getFont("input"); + d.setFont(f); + + Drawable d1(d,3,4,width-6,height-8); + Drawable dr(d1,(multi?0:-offset),(multi?-offset:0),width-6+(multi?0:offset),height-8+(multi?offset:0)); + + const Size start = imin(start_sel, end_sel), end = imax(start_sel, end_sel); + dr.drawText(0,f->getAscent()+1,text,multi,0,start); + + int sx = dr.getX(), sy = dr.getY(); + dr.drawText(text, multi, start, end-start); + int ex = dr.getX(), ey = dr.getY(); + + if (sx != ex || sy != ey) { + dr.setColor(Color::SelectionBackground); + if (sy == ey) dr.fillRect(sx,sy-f->getAscent(),ex-sx,f->getHeight()+1); + else { + dr.fillRect(sx, sy-f->getAscent(), width-sx+offset, f->getHeight() ); + dr.fillRect(0, sy-f->getAscent()+f->getHeight(), width+offset, ey-sy-f->getHeight()); + dr.fillRect(0, ey-f->getAscent(), ex, f->getHeight() ); + } + dr.setColor(Color::SelectionForeground); + dr.drawText(sx, sy, text, multi, start, end-start); + } + + dr.setColor(Color::Text); + + dr.drawText(text, multi, end); + + if (blink && hasFocus()) { + if (insert) dr.drawLine(posx,posy,posx,posy+f->getHeight()+1); + else dr.fillRect(posx,posy,f->getWidth(text[pos]),f->getHeight()+1); + } +} + +Size Input::findPos(int x, int y) { + const Font *f = Font::getFont("input"); + if (multi) y += offset; + else x += offset; + y = (y-4) / f->getHeight(); + int line = 0; + Size pos = 0; + while (line < y && pos < text.size()) if (f->toSpecial(text[pos++]) == Font::LF) line++; + Drawable d(width-6,1); + d.setFont(f); + while (pos <= text.size() && d.getY() == 0 && x > d.getX()) { + d.drawText(String(text), multi, pos, 1); + pos++; + } + if (pos > 0) pos--; + return pos; +} + +bool Input::mouseDown(int x, int y, MouseButton button) +{ + if (button == Left || (button == Middle && start_sel == end_sel)) { + end_sel = start_sel = pos = findPos(x,y); + blink = true; + checkOffset(); + } + if (button == Middle) keyDown(Key(0,Key::Insert,true,false,false,false)); + return true; +} + +bool Input::mouseDragged(int x, int y, MouseButton button) +{ + if (button == Left) { + end_sel = pos = findPos(x,y); + blink = true; + checkOffset(); + } + return true; +} + +bool Input::keyDown(const Key &key) +{ + const Font *f = Font::getFont("input"); + switch (key.special) { + case Key::None: + if (key.ctrl) { + switch (key.character) { + case 1: + case 'a': + case 'A': + if (key.shift) { + start_sel = end_sel = pos; + } else { + start_sel = 0; + pos = end_sel = text.size(); + } + break; + case 24: + case 'x': + case 'X': + cutSelection(); + break; + case 3: + case 'c': + case 'C': + copySelection(); + break; + case 22: + case 'v': + case 'V': + pasteSelection(); + break; + default: printf("Ctrl-0x%x\n",key.character); break; + } + break; + } + if (start_sel != end_sel) clearSelection(); + if (insert || pos >= text.size() ) text.insert(text.begin()+pos++,key.character); + else text[pos++] = key.character; + break; + case Key::Left: + if (pos > 0) pos--; + break; + case Key::Right: + if (pos < text.size()) pos++; + break; + case Key::Down: + if (multi) pos = findPos(posx+3, posy-offset+f->getHeight()+4); + break; + case Key::Up: + if (multi) pos = findPos(posx+3, posy-offset-f->getHeight()+4); + break; + case Key::Home: + if (multi) { + while (pos > 0 && f->toSpecial(text[pos-1]) != Font::LF) pos--; + } else pos = 0; + break; + case Key::End: + if (multi) { + while (pos < text.size() && f->toSpecial(text[pos]) != Font::LF) pos++; + } else pos = text.size(); + break; + case Key::Backspace: + if (!key.shift && start_sel != end_sel) clearSelection(); + else if (pos > 0) text.erase(text.begin()+ --pos); + break; + case Key::Delete: + if (key.shift) cutSelection(); + else if (start_sel != end_sel) clearSelection(); + else if (pos < text.size()) text.erase(text.begin()+pos); + break; + case Key::Insert: + if (key.ctrl) copySelection(); + else if (key.shift) pasteSelection(); + else insert = !insert; + break; + case Key::Enter: + if (multi) { + if (start_sel != end_sel) clearSelection(); + if (insert || pos >= text.size() ) text.insert(text.begin()+pos++,f->fromSpecial(Font::LF)); + else text[pos++] = f->fromSpecial(Font::LF); + } else executeAction(text); + break; + case Key::Tab: + if (multi) { + if (start_sel != end_sel) clearSelection(); + if (insert || pos >= text.size() ) text.insert(text.begin()+pos++,f->fromSpecial(Font::Tab)); + else text[pos++] = f->fromSpecial(Font::Tab); + } else return false; + break; + default: + return false; + } + if (!key.ctrl) { + if (!key.shift || key.special == Key::None) start_sel = end_sel = pos; + else end_sel = pos; + } + checkOffset(); + blink = true; + return true; +} + +void BorderedWindow::paintAll(Drawable &d) const +{ + this->paint(d); + Drawable dchild(d,border_left,border_top,width-border_left-border_right,height-border_top-border_bottom); + for (std::list::const_iterator i = children.begin(); i != children.end(); ++i) { + Window *child = *i; + if (child->isVisible()) { + Drawable cd(dchild,child->getX(),child->getY(),child->getWidth(),child->getHeight()); + child->paintAll(cd); + } + } +} + +void Button::paint(Drawable &d) const +{ + int offset = -1; + + if (hasFocus()) { + offset = 0; + d.setColor(Color::Border); + d.drawLine(0,0,width,0); + d.drawLine(0,0,0,height); + + d.drawLine(0,height-1,width,height-1); + d.drawLine(width-1,0,width-1,height); + } + + d.setColor(Color::Background3D); + d.fillRect(2,2,width-4,height-4); + + if (pressed) { + d.setColor(Color::Shadow3D); + + d.drawLine(1+offset,1+offset,width-2-offset,1+offset); + d.drawLine(1+offset,1+offset,1+offset,height-2-offset); + } else { + d.setColor(Color::Background3D); + + d.drawLine(1+offset,1+offset,width-3-offset,1+offset); + d.drawLine(1+offset,1+offset,1+offset,height-3-offset); + + d.setColor(Color::Light3D); + + d.drawLine(2+offset,2+offset,width-4-offset,2+offset); + d.drawLine(2+offset,2+offset,2+offset,height-4-offset); + + d.setColor(Color::Shadow3D); + + d.drawLine(2+offset,height-3-offset,width-2-offset,height-3-offset); + d.drawLine(width-3-offset,2+offset,width-3-offset,height-2-offset); + + d.setColor(Color::Border); + + d.drawLine(width-2-offset,1+offset,width-2-offset,height-2-offset); + d.drawLine(1+offset,height-2-offset,width-2-offset,height-2-offset); + } +} + +bool Checkbox::keyDown(const Key &key) +{ + switch (key.special) { + case Key::None: + if (key.character != ' ') return false; + case Key::Enter: + break; + default: return false; + } + mouseDown(0,0,Left); + return true; +} + +bool Checkbox::keyUp(const Key &key) +{ + if (key.ctrl || key.alt || key.windows || (key.character != ' ' && key.special != Key::Enter)) return false; + mouseUp(0,0,Left); + mouseClicked(0,0,Left); + return true; +} + +void Checkbox::paint(Drawable &d) const +{ + d.setColor(Color::Background3D); + d.fillRect(2,(height/2)-7,14,14); + + d.setColor(Color::Shadow3D); + d.drawLine(2,(height/2)-7,13,(height/2)-7); + d.drawLine(2,(height/2)-7,2,(height/2)+5); + + d.setColor(Color::Light3D); + d.drawLine(2,(height/2)+5,14,(height/2)+5); + d.drawLine(14,(height/2)-7,14,(height/2)+5); + + d.setColor(Color::EditableBackground); + d.fillRect(4,(height/2)-5,9,9); + + d.setColor(Color::Border); + d.drawLine(3,(height/2)-6,12,(height/2)-6); + d.drawLine(3,(height/2)-6,3,(height/2)+4); + + if (checked) { + d.setColor(Color::Text); + d.drawLine(5,(height/2)-2,7,(height/2) ); + d.drawLine(11,(height/2)-4); + d.drawLine(5,(height/2)-1,7,(height/2)+1); + d.drawLine(11,(height/2)-3); + d.drawLine(5,(height/2) ,7,(height/2)+2); + d.drawLine(11,(height/2)-2); + } +} + +Radiobox::Radiobox(Frame *parent, int x, int y, int w, int h) : BorderedWindow(static_cast(parent),x,y,w,h,16,0,0,0), ActionEventSource("GUI::Radiobox"), checked(0) +{ + addActionHandler(parent); +} + +bool Radiobox::keyDown(const Key &key) +{ + switch (key.special) { + case Key::None: + if (key.character != ' ') return false; + case Key::Enter: + break; + default: return false; + } + mouseDown(0,0,Left); + return true; +} + +bool Radiobox::keyUp(const Key &key) +{ + if (key.ctrl || key.alt || key.windows || (key.character != ' ' && key.special != Key::Enter)) return false; + mouseUp(0,0,Left); + mouseClicked(0,0,Left); + return true; +} + +void Radiobox::paint(Drawable &d) const +{ + d.setColor(Color::Light3D); + d.drawLine(6,(height/2)+6,9,(height/2)+6); + d.drawLine(4,(height/2)+5,11,(height/2)+5); + d.drawLine(13,(height/2)-1,13,(height/2)+2); + d.drawLine(12,(height/2)-2,12,(height/2)+4); + + d.setColor(Color::Background3D); + d.drawLine(6,(height/2)+5,9,(height/2)+5); + d.drawLine(4,(height/2)+4,11,(height/2)+4); + d.drawLine(12,(height/2)-1,12,(height/2)+2); + d.drawLine(11,(height/2)-2,11,(height/2)+4); + + d.setColor(Color::Shadow3D); + d.drawLine(6,(height/2)-5,9,(height/2)-5); + d.drawLine(4,(height/2)-4,11,(height/2)-4); + d.drawLine(2,(height/2)-1,2,(height/2)+2); + d.drawLine(3,(height/2)-3,3,(height/2)+4); + + d.setColor(Color::Border); + d.drawLine(6,(height/2)-4,9,(height/2)-4); + d.drawLine(4,(height/2)-3,11,(height/2)-3); + d.drawLine(3,(height/2)-1,3,(height/2)+2); + d.drawLine(4,(height/2)-3,4,(height/2)+3); + + d.setColor(Color::EditableBackground); + d.fillRect(5,(height/2)-2,6,6); + d.fillRect(4,(height/2)-1,8,4); + d.fillRect(6,(height/2)-3,4,8); + + if (checked) { + d.setColor(Color::Text); + d.fillRect(6,(height/2),4,2); + d.fillRect(7,(height/2)-1,2,4); + } +} + +void Menu::paint(Drawable &d) const +{ + d.clear(Color::Background3D); + + d.setColor(Color::Border); + d.drawLine(0,height-1,width-1,height-1); + d.drawLine(width-1,0,width-1,height-1); + + d.setColor(Color::Shadow3D); + d.drawLine(0,0,width-2,0); + d.drawLine(0,0,0,height-2); + d.drawLine(0,height-2,width-2,height-2); + d.drawLine(width-2,0,width-2,height-2); + + d.setColor(Color::Light3D); + d.drawLine(1,1,width-3,1); + d.drawLine(1,1,1,height-3); + + d.setFont(Font::getFont("menu")); + const int asc = Font::getFont("menu")->getAscent()+1; + const int height = Font::getFont("menu")->getHeight()+2; + int y = asc+3; + int index = 0; + for (std::vector::const_iterator i = items.begin(); i != items.end(); ++i) { + if ((*i).empty()) { + d.setColor(Color::Shadow3D); + d.drawLine(4,y-asc+6,width-5,y-asc+6); + d.setColor(Color::Light3D); + d.drawLine(4,y-asc+7,width-5,y-asc+7); + y += 12; + } else { + if (index == selected && hasFocus()) { + d.setColor(Color::SelectionBackground); + d.fillRect(3,y-asc,width-6,height); + d.setColor(Color::SelectionForeground); + } else { + d.setColor(Color::Text); + } + d.drawText(20,y,(*i),false,0); + y += height; + } + index++; + } +} + +void Menubar::paint(Drawable &d) const +{ + const Font *f = Font::getFont("menu"); + + d.setColor(Color::Light3D); + d.drawLine(0,height-1,width-1,height-1); + d.setColor(Color::Shadow3D); + d.drawLine(0,height-2,width-1,height-2); + + d.gotoXY(7,f->getAscent()+2); + + int index = 0; + for (std::vector::const_iterator i = menus.begin(); i != menus.end(); ++i, ++index) { + if (index == selected && (*i)->isVisible()) { + int w = f->getWidth((*i)->getName()); + d.setColor(Color::SelectionBackground); + d.fillRect(d.getX()-7,0,w+14,height-2); + d.setColor(Color::SelectionForeground); + d.gotoXY(d.getX()+7,f->getAscent()+2); + } else { + d.setColor(Color::Text); + } + d.drawText((*i)->getName(),false); + d.gotoXY(d.getX()+14,f->getAscent()+2); + } +} + +bool Button::keyDown(const Key &key) +{ + switch (key.special) { + case Key::None: + if (key.character != ' ') return false; + case Key::Enter: + break; + default: return false; + } + mouseDown(0,0,Left); + return true; +} + +bool Button::keyUp(const Key &key) +{ + if (key.ctrl || key.alt || key.windows || (key.character != ' ' && key.special != Key::Enter)) return false; + mouseUp(0,0,Left); + mouseClicked(0,0,Left); + return true; +} + +void Frame::paint(Drawable &d) const { + const Font *f = Font::getFont("default"); + const int top = (label.empty()?1:f->getAscent()/2+1); + + d.setColor(Color::Shadow3D); + d.drawLine(1,height-2,1,top); + d.drawLine(8,top); + d.drawLine((label.empty()?8:f->getWidth(label)+14),top,width-2,top); + d.drawLine(2,height-3,width-3,height-3); + d.drawLine(width-3,top+1); + + d.setColor(Color::Light3D); + d.drawLine(2,height-3,2,top+1); + d.drawLine(8,top+1); + d.drawLine((label.empty()?8:f->getWidth(label)+14),top+1,width-3,top+1); + d.drawLine(2,height-2,width-2,height-2); + d.drawLine(width-2,top+1); + + d.setColor(Color::Text); + d.drawText(11,f->getAscent()+1,label,false,0); +} + +Screen *Window::getScreen() { return (parent == NULL?dynamic_cast(this):parent->getScreen()); } + +Screen::Screen(unsigned int width, unsigned int height) : + Window(), + buffer(new Drawable(width, height)) +{ + this->width = width; + this->height = height; +} + +Screen::Screen(Drawable *d) : + Window(), + buffer(d) +{ + this->width = d->getClipWidth(); + this->height = d->getClipHeight(); +} + +Screen::~Screen() +{ +} + +void Screen::paint(Drawable &d) const +{ + d.clear(Color::Transparent); +} + +unsigned int Screen::update(void *surface, unsigned int ticks) +{ + Timer::check(ticks); + + paintAll(*buffer); + RGB *buf = buffer->buffer; + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++, buf++) { + RGB sval = surfaceToRGB(surface); + RGB bval = *buf; + int a = Color::A(bval); + bval = ((((sval&Color::MagentaMask)*a+(bval&Color::MagentaMask)*(256-a))>>8)&Color::MagentaMask) + | ((((sval&Color::GreenMask)*a+(bval&Color::GreenMask)*(256-a))>>8)&Color::GreenMask); + rgbToSurface(bval, &surface); + } + } + + return Timer::next(); +} + +void Screen::move(int x, int y) +{ +} + +void Screen::resize(int w, int h) +{ +} + +#ifdef TESTING +static void test(Drawable &d) { + const int width = d.getClipWidth(); + const int height = d.getClipHeight(); + + d.clear(Color::rgba(0,0,255,128)); + + d.setColor(Color::Black); + for (int x = 0; x < width; x += 10) d.drawLine(x,0,x,height); + for (int y = 0; y < height; y += 10) d.drawLine(0,y,width,y); + + d.setColor(Color::Red); + for (int x = 10; x <= 130 ; x += 10) { + d.drawLine(x,10,70,70); + d.drawLine(x,130); + } + for (int y = 10; y <= 130 ; y += 10) { + d.drawLine(10,y,70,70); + d.drawLine(130,y); + } + + d.setColor(Color::Yellow); + d.fillRect(150,10,30,30); + d.setColor(Color::Blue); + d.drawRect(30,30); + + d.drawRect(150,60,30,30); + d.setColor(Color::Yellow); + d.fillRect(30,30); + + for (int x = 0; x <= 100 ; x += 10) { + d.setColor(Color::rgba(0xff,0x00,0xff,(255*x/100)&255)); + d.fillRect(200+2*x,0,20,20); + } + + d.setColor(Color::Yellow); + d.fillCircle(210,60,40); + d.setColor(Color::Blue); + d.drawCircle(40); + + d.drawCircle(210,110,40); + d.setColor(Color::Yellow); + d.fillCircle(40); + + d.setColor(Color::rgba(0,0,255,128)); + d.fillRect(251,41,9,59); + d.fillRect(251,41,59,9); + d.fillRect(301,41,9,59); + d.fillRect(291,91,19,9); + d.fillRect(291,51,9,49); + d.fillRect(261,51,39,9); + d.fillRect(261,51,9,49); + d.fillRect(261,91,29,9); + d.fillRect(281,61,9,39); + d.fillRect(271,61,19,9); + d.fillRect(271,61,9,29); + d.fillRect(241,41,9,59); + d.fillRect(241,41,19,9); + d.fillRect(241,91,19,9); + d.setColor(Color::rgba(255,0,0,128)); + d.fill(255,64); + + d.setColor(Color::Green); + Drawable(d,500,355,30,30).fillCircle(65); + + for (int i = 0; i <= 100; i += 10) { + Drawable(d,25,155+i*3,420,30).drawDrawable(0,0,d,255*i/100); + } + + d.setColor(Color::White); + d.setFont(Font::getFont("VGA14")); + d.drawText(270,110,"GUI:: Test Program\n"); + d.drawText("Still testing\tTable\n"); + d.drawText("More of...\tTable\n"); + d.drawText("Overwrite\rXXXXXXXXX\n"); + d.drawText("Fake int'l chars: O\b/e\b\"\n"); + d.drawText("Real ones: \211\222\234\345\246\321"); +} +#else +static void test(Drawable &d) { (void)d; } +#endif + + +void ScreenRGB32le::paint(Drawable &d) const +{ + parent->paint(d); + test(d); +} + +static const MouseButton SDL_to_GUI(const int button) +{ + switch (button) { + case SDL_BUTTON_LEFT: return GUI::Left; + case SDL_BUTTON_RIGHT: return GUI::Right; + case SDL_BUTTON_MIDDLE: return GUI::Middle; + case SDL_BUTTON_WHEELUP: return GUI::WheelUp; + case SDL_BUTTON_WHEELDOWN: return GUI::WheelDown; + default: return GUI::NoButton; + } +} + +static const Key SDL_to_GUI(const SDL_keysym &key) +{ + GUI::Key::Special ksym = GUI::Key::None; + switch (key.sym) { + case SDLK_ESCAPE: ksym = GUI::Key::Escape; break; + case SDLK_BACKSPACE: ksym = GUI::Key::Backspace; break; + case SDLK_TAB: ksym = GUI::Key::Tab; break; + case SDLK_LEFT: ksym = GUI::Key::Left; break; + case SDLK_RIGHT: ksym = GUI::Key::Right; break; + case SDLK_UP: ksym = GUI::Key::Up; break; + case SDLK_DOWN: ksym = GUI::Key::Down; break; + case SDLK_HOME: ksym = GUI::Key::Home; break; + case SDLK_END: ksym = GUI::Key::End; break; + case SDLK_DELETE: ksym = GUI::Key::Delete; break; + case SDLK_INSERT: ksym = GUI::Key::Insert; break; + case SDLK_RETURN: ksym = GUI::Key::Enter; break; + case SDLK_MENU: ksym = GUI::Key::Menu; break; + case SDLK_PAGEUP: ksym = GUI::Key::PageUp; break; + case SDLK_PAGEDOWN: ksym = GUI::Key::PageDown; break; + case SDLK_PRINT: ksym = GUI::Key::Print; break; + case SDLK_PAUSE: ksym = GUI::Key::Pause; break; + case SDLK_BREAK: ksym = GUI::Key::Break; break; + case SDLK_CAPSLOCK: ksym = GUI::Key::CapsLock; break; + case SDLK_NUMLOCK: ksym = GUI::Key::NumLock; break; + case SDLK_SCROLLOCK: ksym = GUI::Key::ScrollLock; break; + case SDLK_F1:case SDLK_F2:case SDLK_F3:case SDLK_F4:case SDLK_F5:case SDLK_F6: + case SDLK_F7:case SDLK_F8:case SDLK_F9:case SDLK_F10:case SDLK_F11:case SDLK_F12: + ksym = (GUI::Key::Special)(GUI::Key::F1 + key.sym-SDLK_F1); + default: break; + } + return Key(key.unicode, ksym, + key.mod&KMOD_SHIFT, + key.mod&KMOD_CTRL, + key.mod&KMOD_ALT, + key.mod&KMOD_META); +} + +/** \brief Internal class that handles different screen bit depths and layouts the SDL way */ +class SDL_Drawable : public Drawable { +protected: + SDL_Surface *const surface; + +public: + SDL_Drawable(int width, int height, RGB clear = Color::Transparent) : Drawable(width, height, clear), surface(SDL_CreateRGBSurfaceFrom(buffer, width, height, 32, width*4, Color::RedMask, Color::GreenMask, Color::BlueMask, Color::AlphaMask)) { + surface->flags |= SDL_SRCALPHA; + } + + ~SDL_Drawable() { + SDL_FreeSurface(surface); + } + + void update(SDL_Surface *dest) const { + SDL_BlitSurface(surface, NULL, dest, NULL); + } +}; + +ScreenSDL::ScreenSDL(SDL_Surface *surface) : Screen(new SDL_Drawable(surface->w, surface->h)), surface(surface), downx(0), downy(0), lastclick(0) {} + +Ticks ScreenSDL::update(Ticks ticks) +{ + Timer::check(ticks); + + paintAll(*buffer); + static_cast(buffer)->update(surface); + + return Timer::next(); +} + +void ScreenSDL::paint(Drawable &d) const { + d.clear(Color::Transparent); + test(d); +} + +bool ScreenSDL::event(const SDL_Event &event) { + bool rc; + + switch (event.type) { + case SDL_KEYUP: { + const Key &key = SDL_to_GUI(event.key.keysym); + if (key.special == GUI::Key::None && key.character == 0) break; + if (key.special == GUI::Key::CapsLock || key.special == GUI::Key::NumLock) keyDown(key); + return keyUp(key); + } + case SDL_KEYDOWN: { + const Key &key = SDL_to_GUI(event.key.keysym); + if (key.special == GUI::Key::None && key.character == 0) break; + rc = keyDown(key); + if (key.special == GUI::Key::CapsLock || key.special == GUI::Key::NumLock) keyUp(key); + return rc; + } + case SDL_MOUSEMOTION: + if (event.motion.state) { + if (abs(event.motion.x-downx) <= 10 && abs(event.motion.y-downy) <= 10) + break; + downx = -11; downy = -11; + if (event.motion.state&SDL_BUTTON(1)) + return mouseDragged(event.motion.x, event.motion.y, GUI::Left); + else if (event.motion.state&SDL_BUTTON(2)) + return mouseDragged(event.motion.x, event.motion.y, GUI::Middle); + else if (event.motion.state&SDL_BUTTON(3)) + return mouseDragged(event.motion.x, event.motion.y, GUI::Right); + break; + } + + return mouseMoved(event.motion.x, event.motion.y); + + case SDL_MOUSEBUTTONDOWN: + rc = mouseDown(event.button.x, event.button.y, SDL_to_GUI(event.button.button)); + if (abs(event.button.x-downx) > 10 || abs(event.button.y-downy) > 10) lastclick = 0; + downx = event.button.x; downy = event.button.y; + return rc; + + case SDL_MOUSEBUTTONUP: + rc = mouseUp(event.button.x, event.button.y, SDL_to_GUI(event.button.button)); + if (abs(event.button.x-downx) < 10 && abs(event.button.y-downy) < 10) { + if (lastclick == 0 || (GUI::Timer::now()-lastclick) > 20) { + lastclick = GUI::Timer::now(); + rc |= mouseClicked(downx, downy, SDL_to_GUI(event.button.button)); + } else if (lastclick != 0) { + rc |= mouseDoubleClicked(downx, downy, SDL_to_GUI(event.button.button)); + lastclick = 0; + } else { + lastclick = 0; + } + } else { + lastclick = 0; + } + return rc; + } + + return false; +} + +} + + + +#ifdef TESTING +#include + +/** \brief A test program that serves as an example for all GUI elements. + * + * Note that you need SDL installed and a file "testfont.h" for this + * to compile, which must contain a bitmap font declared as + * + * \code + * static const unsigned char testfont[256 * 14] = { ... }; + * \endcode + * + * (256 chars, 8x14 fixed-width font, for example the IBM PC VGA 14-line font, + * you can get it from DOSBox) + * + * To compile it, use a command line like this: + * + * \code + * g++ -DTESTING `sdl-config --cflags` `sdl-config --libs` gui_tk.cpp -o testgui_tk + * \endcode + * + */ + +int main(int argc, char *argv[]) +{ + printf("GUI:: test program\n"); + + SDL_Surface *screen; + + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); + exit(1); + } + + atexit(SDL_Quit); + + screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE); + if (screen == NULL) { + fprintf(stderr, "Couldn't set 640x480x32 video mode: %s\n", SDL_GetError()); + exit(1); + } + printf("GUI:: color depth %i\n",screen->format->BitsPerPixel); + + SDL_EnableUNICODE(true); + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL); + + #include "testfont.h" + GUI::Font::addFont("default",new GUI::BitmapFont(testfont,14,10)); + + GUI::ScreenSDL guiscreen(screen); + GUI::ToplevelWindow *frame = new GUI::ToplevelWindow(&guiscreen,205,100,380,250,"GUI::Frame"); + static struct delwin : public GUI::ActionEventSource_Callback { + void actionExecuted(GUI::ActionEventSource *b, const GUI::String &arg) { + dynamic_cast(dynamic_cast(b)->getParent())->close(); + } + } dw; + struct newwin : public GUI::ActionEventSource_Callback { + GUI::Screen *screen; + int n; + void actionExecuted(GUI::ActionEventSource *b, const GUI::String &arg) { + char title[256]; + sprintf(title,"Window %i",++n); + GUI::ToplevelWindow *w = new GUI::ToplevelWindow(screen,405,100,120,150,title); + GUI::Button *close = new GUI::Button(w,5,5,"Close"); + close->addActionHandler(&dw); + } + } nw; + nw.screen = &guiscreen; + nw.n = 0; + struct quit : public GUI::ActionEventSource_Callback { + GUI::ToplevelWindow *frame; + void actionExecuted(GUI::ActionEventSource *b, const GUI::String &arg) { + if (arg == "Quit" && b->getName() != "GUI::Input") exit(0); + frame->setTitle(arg); + } + } ex; + ex.frame = frame; + + GUI::Button *b = new GUI::Button(frame,8,20,"Open a new Window"); + b->addActionHandler(&nw); + (new GUI::Button(frame,200,20,"1"))->addActionHandler(&ex); + (new GUI::Button(frame,235,20,"2"))->addActionHandler(&ex); + b = new GUI::Button(frame,270,20,"Quit"); + b->addActionHandler(&ex); + (new GUI::Input(frame,16,55,150))->addActionHandler(&ex); + + printf("Title: %s\n",(const char*)frame->getTitle()); + + struct movewin : public GUI::Timer_Callback, public GUI::ToplevelWindow_Callback { + public: + GUI::ToplevelWindow *frame; + GUI::Checkbox *cb1, *cb2; + int x, y; + virtual unsigned int timerExpired(unsigned int t) { + if (cb2->isChecked()) frame->move(frame->getX()+x,frame->getY()+y); + if (frame->getX() <= -frame->getWidth()) x = 1; + if (frame->getX() >= 640) x = -1; + if (frame->getY() <= -frame->getHeight()) y = 1; + if (frame->getY() >= 480) y = -1; + return 10; + } + virtual bool windowClosing(GUI::ToplevelWindow *win) { + if (!cb1->isChecked()) return false; + return true; + } + virtual void windowClosed(GUI::ToplevelWindow *win) { + GUI::Timer::remove(this); + } + } mw; + mw.frame = frame; + mw.x = -1; + mw.y = 1; + GUI::Frame *box = new GUI::Frame(frame,16,80,300,50); + mw.cb1 = new GUI::Checkbox(box,0,0,"Allow to close this window"); + mw.cb2 = new GUI::Checkbox(box,0,20,"Move this window"); + box = new GUI::Frame(frame,16,130,300,80,"Radio Buttons"); + (new GUI::Radiobox(box,0,0,"Normal"))->setChecked(true); + new GUI::Radiobox(box,0,20,"Dynamic"); + new GUI::Radiobox(box,0,40,"Simple"); + box->addActionHandler(&ex); + GUI::Timer::add(&mw,10); + frame->addWindowHandler(&mw); + GUI::Menubar *bar = new GUI::Menubar(frame,0,0,frame->getWidth()); + bar->addMenu("File"); + bar->addItem(0,"New..."); + bar->addItem(0,"Open..."); + bar->addItem(0,""); + bar->addItem(0,"Save"); + bar->addItem(0,"Save as..."); + bar->addItem(0,""); + bar->addItem(0,"Close"); + bar->addItem(0,"Quit"); + bar->addMenu("Edit"); + bar->addItem(1,"Undo"); + bar->addItem(1,"Redo"); + bar->addItem(1,""); + bar->addItem(1,"Cut"); + bar->addItem(1,"Copy"); + bar->addItem(1,"Paste"); + bar->addItem(1,""); + bar->addItem(1,"Select all"); + bar->addItem(1,"Select none"); + bar->addMenu("View"); + bar->addItem(2,"Zoom..."); + bar->addItem(2,"Zoom in"); + bar->addItem(2,"Zoom out"); + bar->addMenu("?"); + bar->addItem(3,"Manual"); + bar->addItem(3,"Search..."); + bar->addItem(3,""); + bar->addItem(3,"About"); + bar->addActionHandler(&ex); + + SDL_Event event; + while (1) { + while (SDL_PollEvent(&event)) { + if (!guiscreen.event(event)) { + if (event.type == SDL_QUIT) exit(0); + } + } + + if (SDL_MUSTLOCK(screen)) SDL_LockSurface(screen); + memset(screen->pixels,0xff,4*640*15); + memset(((char *)screen->pixels)+4*640*15,0x00,4*640*450); + memset(((char *)screen->pixels)+4*640*465,0xff,4*640*15); + if (SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen); + guiscreen.update(4); + SDL_UpdateRect(screen, 0, 0, screen->w, screen->h); + + SDL_Delay(40); + } +} +#endif + diff --git a/src/libs/gui_tk/gui_tk.h b/src/libs/gui_tk/gui_tk.h new file mode 100644 index 00000000..a59c7fbe --- /dev/null +++ b/src/libs/gui_tk/gui_tk.h @@ -0,0 +1,2221 @@ +/** \mainpage gui::tk - framework-agnostic C++ GUI toolkit + * + * \section i Introduction + * + * gui::tk is a simple one-file C++ GUI toolkit for use with arbitrary + * memory framebuffers. + * + * \section f Features + * + * \li small source and binary code size + * \li reasonable performance and memory usage + * \li comfortable usage + * \li suitable for embedded usage: integer math only + * \li extensibility via OO + * \li non-intrusive: can be integrated with any event mechanism of your liking + * \li no dependencies apart from standards-conformant ANSI C++ (including a little STL) + * \li support for different encodings, single- and multibyte + * \li flexible font support + * + * \section o Overview + * + * The toolkit draws on a surface you provide, using any size or pixel format. + * Create a GUI::Screen with the buffer to draw on, then pass that object + * (or a GUI::Window created from it) to all other widgets' constructors. + * + * It doesn't provide an own event loop. Instead, it relies on you passing events + * and updating the screen regularly. This way, it can easily be integrated with + * any event loop available (SDL, Qt, glib, X11, Win32, selfmade, ...) + * + * Many functions and concepts were taken from other well-known toolkits, so if you + * know Qt, Java or wxWindows, you may encounter (intentional) similarities. However, + * simplicity of code has been given priority over maximum optimization and pixel-exact + * replication of their appearance. + * + * A note about font support and encodings: All text-related functions use templates to + * support any encoding. Fonts define the charset. + * + * \section g Getting Started + * + * gui::tk contains an SDL adapter, so if your program is already using SDL, + * things are really easy. The rough sequence to get up and running is: + * + * \code + * // setup a suitable video mode with SDL + * SDL_surface *screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE); + * + * // add a default font, you will most probably need it + * GUI::Font::addFont("default",new GUI::BitmapFont(testfont,14,10)); + * + * // create the root-level screen object, the parent of all top-level windows + * GUI::ScreenSDL guiscreen(screen); + * + * // create any amount of toplevel windows you like + * GUI::ToplevelWindow *frame = new GUI::ToplevelWindow(&guiscreen, 205, 100, 380, 250, "gui::tk example"); + * + * // add some GUI elements to the toplevel window + * GUI::Button *b = new GUI::Button(frame,8,20,"Quit"); + * + * // Define and add an event handler + * struct quit : public GUI::ActionEventSource_Callback { + * void actionExecuted(GUI::ActionEventSource *b, const GUI::String &arg) { + * exit(0); + * } + * } ex; + * b->addActionHandler(&ex); + * + * // Enter an event loop, calling update() regularly. + * SDL_Event event; + * while (1) { + * while (SDL_PollEvent(&event)) { + * if (!guiscreen.event(event)) { // gui::tk didn't handle that event + * if (event.type == SDL_QUIT) exit(0); + * } + * } + * + * guiscreen.update(4); // 4 ticks = 40ms + * SDL_UpdateRect(screen, 0, 0, screen->w, screen->h); + * + * SDL_Delay(40); // wait 40ms + * } + * \endcode + * + * Look at gui_tk.h for more detailed documentation and reference of all classes. + * + * A test program that shows off the capabilities of gui::tk is available as part of gui_tk.cpp. + * + * \section l License + * + * Copyright (C) 2005-2007 Jörg Walter + * + * gui::tk 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 3 of the License, or + * (at your option) any later version. + * + * gui::tk 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, see + */ + +/* $Id: gui_tk.h,v 1.1 2007-10-28 16:33:02 qbix79 Exp $ */ + +#ifndef GUI__TOOLKIT_H +#define GUI__TOOLKIT_H + +#define imin(x,y) (xy?x:y) +#define isign(x) (((x)<0?-1:1)) + +/** \file + * \brief Header file for gui::tk. + * + * All you need to do is to include "gui_tk.h". If you want SDL support, then include \c SDL.h first. + */ + +#ifdef _MSC_VER +typedef signed __int8 int8_t; +typedef signed __int16 int16_t; +typedef signed __int32 int32_t; +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +#else +#include +#endif + +#include +#include +#include +#include +#include +#include + +/// This namespace contains all GUI toolkit classes, types and functions. +namespace GUI { + +/// ARGB 24-bit color value: (a<<24)|(r<<16)|(g<<8)|(b) +typedef uint32_t RGB; + +/// Collection of all color-related constants and functions. +namespace Color { +/// A fully transparent pixel. +const RGB Transparent = 0x00ffffff; + +/// A fully opaque black pixel. +const RGB Black = 0xff000000; + +/// A fully opaque white pixel. +const RGB White = 0xffffffff; + +/// Alpha mask. +const RGB AlphaMask = 0xff000000; + +/// Offset of alpha value. +const int AlphaShift = 24; + +/// Red mask. +const RGB RedMask = 0x00ff0000; + +/// Full-intensity red. +const RGB Red = Black|RedMask; + +/// Offset of red value. +const int RedShift = 16; + +/// Green mask. +const RGB GreenMask = 0x0000ff00; + +/// Full-intensity green. +const RGB Green = Black|GreenMask; + +/// Offset of green value. +const int GreenShift = 8; + +/// Blue mask. +const RGB BlueMask = 0x000000ff; + +/// Full-intensity blue. +const RGB Blue = Black|BlueMask; + +/// Offset of blue value. +const int BlueShift = 0; + +/// Full-intensity Magenta. +const RGB Magenta = Red|Blue; + +/// Magenta mask. +const RGB MagentaMask = RedMask|BlueMask; + +/// Full-intensity Cyan. +const RGB Cyan = Green|Blue; + +/// Cyan mask. +const RGB CyanMask = GreenMask|BlueMask; + +/// Full-intensity Yellow. +const RGB Yellow = Red|Green; + +/// Yellow mask. +const RGB YellowMask = RedMask|GreenMask; + +/// 50% grey +const RGB Grey50 = 0xff808080; + +/// Background color for 3D effects. May be customized. +extern RGB Background3D; + +/// Light highlight color for 3D effects. May be customized. +extern RGB Light3D; + +/// Dark highlight color (shadow) for 3D effects. May be customized. +extern RGB Shadow3D; + +/// Generic border color for highlights or similar. May be customized. +extern RGB Border; + +/// Foreground color for regular content (mainly text). May be customized. +extern RGB Text; + +/// Background color for inactive areas. May be customized. +extern RGB Background; + +/// Background color for selected areas. May be customized. +extern RGB SelectionBackground; + +/// Foreground color for selected areas. May be customized. +extern RGB SelectionForeground; + +/// Background color for inputs / application area. May be customized. +extern RGB EditableBackground; + +/// Title bar color for windows. May be customized. +extern RGB Titlebar; + +/// Title bar text color for windows. May be customized. +extern RGB TitlebarText; + +/// Convert separate r, g, b and a values (each 0-255) to an RGB value. +static inline RGB rgba(int r, int g, int b, int a=0) { + return (((r&255)<>Color::RedShift); } +/// Get green value (0-255) from an RGB value. +static inline int G(RGB val) { return ((val&Color::GreenMask)>>Color::GreenShift); } +/// Get blue value (0-255) from an RGB value. +static inline int B(RGB val) { return ((val&Color::BlueMask)>>Color::BlueShift); } +/// Get alpha value (0-255) from an RGB value. +static inline int A(RGB val) { return ((val&Color::AlphaMask)>>Color::AlphaShift); } + +} + +/// Identifies a mouse button. +enum MouseButton { NoButton, Left, Right, Middle, WheelUp, WheelDown, WheelLeft, WheelRight }; + +/// A type which holds size values that can be very large. +typedef unsigned int Size; + +/// A type which holds a single character. Large enough for Unicode. +typedef uint32_t Char; + +/// A type which holds a number of timer ticks. +typedef unsigned int Ticks; + +/// Identifies a keyboard key. +class Key { +public: + /// Translated character value. + /** No encoding is implied. The Font that is used to display this character + * determines the appearance. */ + Char character; + /// Special keyboard keys. + /** It is modeled after PC keyboards. When you feed keyboard events to a GUI::Screen, + * try to map native keys to this set. Some special keys have a character value. Set + * to \c None if the key has no special meaning. */ + enum Special { + None, + F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, + Up, Down, Left, Right, Backspace, Tab, Backtab, Enter, Escape, + Home, End, PageUp, PageDown, Insert, Delete, Menu, + Print, Pause, Break, CapsLock, NumLock, ScrollLock, + Alt, Ctrl, Shift, Windows + } special; + /// Set if the Shift key is currently down. + bool shift; + /// Set if the Ctrl key is currently down. + bool ctrl; + /// Set if the Alt (PC) or Meta (classic Unix) key is currently down. + bool alt; + /// Set if the "Windows"/Meta (PC) or Super (classic Unix) key is currently down. + /** Do not depend too heavily on this, as many keyboards and systems do not have such a key. */ + bool windows; + + /// Constructor. + Key(int character, Special special, bool shift, bool ctrl, bool alt, bool windows) : + character(character), special(special), + shift(shift), ctrl(ctrl), alt(alt), windows(windows) {} +}; + +class Drawable; +class String; + +/** \brief Converts between strings of various types and String objects. + * + * It is used to deal with string encoding. It is intended to be used with template + * specializations. Having such a specialization means you can feed the corresponding type to + * all functions that expect a string -- without any conversion. You can add specializations + * yourself in your program's code to deal with unsupported types. + * + * As an example, see the std::string version. + * + * Encodings, as opposed to character sets, define how bytes map to character values. + * ASCII, for example, has an \em encoding where each byte is one character, while the + * ASCII \em character \em set says that values 0-127 are valid and 65 is the upper case + * letter 'A'. UTF-8 has 1-6 bytes per character, and the character set is unicode. + * + * GUI::Font deals with the character set, and this class encapsulates encodings. + * + */ +template class NativeString { +protected: + friend class String; + + /// Converts a native string into a String object + static void getString(String &dest, const STR &src) { STR::_this_string_type_is_not_supported_(); } + + /** \brief Converts a string object to native representation. + * + * If some characters cannot be converted, they should silently be skipped. Apart from that, + * \c nativeString(stringNative(String(),X)) should be value-equal to \c X. + */ + static STR& getNative(const String &src) { STR::_this_string_type_is_not_supported_();return*new STR(); } +}; + +template class NativeString { +protected: + friend class String; + static void getString(String &dest, const STR *src); + static STR* getNative(const String &src); +}; + +template class NativeString : public NativeString {}; +template class NativeString : public NativeString {}; +template class NativeString : public NativeString {}; + +/// 'less-than' comparison between pointer addresses +struct ltvoid { bool operator()(const void* s1, const void* s2) const { return s1 < s2; } }; + +/** \brief Simple STL-based string class. + * + * This is intended as internal helper class to allow gui::tk to work with any kind of + * string objects. While you can use this in normal application code, you should better + * use the string class of your application framework (like Qt). If you don't have any, + * use std::string. + * + * It supports arbitrary characters, no character set is implied. Conversion from/to usual + * string types like \c char* is automatic but not thread-safe for non-class types. + */ +class String : public std::vector { +protected: + template friend class NativeString; + /// Simple pointer encapsulation class for memory management. + class Native { public: virtual ~Native() {}; }; + /// Simple pointer encapsulation class for memory management. + template class NativeArray: public Native { + STR *data; + public: + NativeArray(STR *data) : data(data) {} + virtual ~NativeArray() { delete[] data; } + }; + template class NativeObject: public Native { + STR *data; + public: + NativeObject(STR *data) : data(data) {} + virtual ~NativeObject() { delete data; } + }; + +private: + /// Semi-static memory management for pointer string types. + mutable std::map strings; + +protected: + /// Manage a native string's memory. + void addNative(Native *dest) const { + const class std::type_info &type = typeid(dest); + if (strings[&type] != NULL) delete strings[&type]; + strings[&type] = dest; + } + +public: + /// Allocate a new String initialized from native string. + template String(const STR& src) { NativeString::getString(*this, src); } + + /// Taken from STL. + template String(InputIterator a, InputIterator b) : std::vector(a,b) {} + + /// Copy-constructor + String(const String &src) : std::vector(src), strings() {}; + + /// Allocate a new String. + String() { } + + /// Deallocate a String. + ~String() { + for (std::map::iterator i = strings.begin(); i != strings.end(); ++i) + delete (*i).second; + }; + + /// Convert to native representation. + /** For pointer types like \c char*, the returned pointer is usually only valid as long as + * this object exists, or until it is modified and cast to the same type again. */ + template operator T() const { return NativeString::getNative(*this); } + + /// Compare with native representation. + template bool operator==(const T &src) const { return *this == String(src); } + /// Compare with other Strings. + bool operator==(const String &src) const { return *(std::vector*)this == src; } + + /// Compare with native representation. + template bool operator!=(const T &src) const { return *this != String(src); } + /// Compare with other Strings. + bool operator!=(const String &src) const { return *(std::vector*)this != src; } +}; + +template void NativeString::getString(String &dest, const STR* src) { + Size strlen = 0; + while (src[strlen]) strlen++; + dest.resize(strlen); + for (strlen = 0; src[strlen]; strlen++) dest[strlen] = (sizeof(STR)==1?(unsigned char)src[strlen]:sizeof(STR)==2?(unsigned short)src[strlen]:src[strlen]); +} + +template STR* NativeString::getNative(const String &src) { + Size strlen = src.size(); + STR* dest = new STR[strlen+1]; + dest[strlen] = 0; + for (; strlen > 0; strlen--) dest[strlen-1] = src[strlen-1]; + src.addNative(new String::NativeArray(dest)); + return dest; +} + +template <> class NativeString { +protected: + friend class String; + static void getString(String &dest, const std::string *src) { + Size strlen = src->length(); + dest.resize(strlen); + for (Size i = 0; i< strlen; i++) dest[i] = (*src)[i]; + } + static std::string* getNative(const String &src) { + Size strlen = src.size(); + std::string* dest = new std::string(); + for (Size i = 0; i < strlen; i++) dest->append(1,src[i]); + src.addNative(new String::NativeObject(dest)); + return dest; + } +}; + +template <> class NativeString : public NativeString {}; + +template <> class NativeString { +protected: + friend class String; + static void getString(String &dest, const std::string &src) { + Size strlen = src.length(); + dest.resize(strlen); + for (Size i = 0; i< strlen; i++) dest[i] = src[i]; + } + static std::string& getNative(const String &src) { + Size strlen = src.size(); + std::string* dest = new std::string(); + for (Size i = 0; i < strlen; i++) dest->append(1,src[i]); + src.addNative(new String::NativeObject(dest)); + return *dest; + } +}; + +template <> class NativeString : public NativeString {}; + +class ToplevelWindow; +class Menu; +class TransientWindow; +class Screen; +class Window; + +/// Callback for window events. +struct Window_Callback { +public: + /// Called whenever this window changes position. + virtual void windowMoved(Window *win, int x, int y) = 0; + virtual ~Window_Callback() {} +}; + + +/** \brief A Window is a rectangular sub-area of another window. + * + * Windows are arranged hierarchically. A Window cannot leave its parent's + * area. They may contain their own buffer or share it with their parent. + * + * Usually, every GUI element is a subclass of Window. Note that this is + * \em not a GUI window with decorations like border and title bar. See ToplevelWindow + * for that. + */ +class Window { +protected: + friend class ToplevelWindow; + friend class TransientWindow; + friend class Menu; + + /// Width of the window. + int width; + /// Height of the window. + int height; + /// X position relative to parent. + int x; + /// Y position relative to parent. + int y; + + /// \c true if anything changed in this window or one of it's children + bool dirty; + + /// \c true if this window should be visible on screen. + bool visible; + + /// Parent window. + Window *const parent; + + /// Child window of last button-down event + /** It receives all drag/up/click/doubleclick events until an up event is received */ + Window *mouseChild; + + /// Child windows. + /** Z ordering is done in list order. The first element is the lowermost + * window. This window's content is below all children. */ + std::list children; + + /// List of registered event handlers. + std::list movehandlers; + + /// Register child window. + virtual void addChild(Window *child); + + /// Remove child window. + virtual void removeChild(Window *child); + + /// Mark this window and all parents as dirty. + void setDirty() { if (dirty) return; dirty = true; if (parent != NULL) parent->setDirty(); }; + + /// Replace clipboard content. + virtual void setClipboard(const String &s) { parent->setClipboard(s); }; + + /// Get clipboard content. + virtual const String& getClipboard() { return parent->getClipboard(); }; + + /// Default constructor. Only used in class Screen. Do not use. + Window(); + + /// Called whenever the focus changes. + virtual void focusChanged(bool gained) { + if (children.size() > 0) children.back()->focusChanged(gained); + } + +public: + + /// Add an event handler. + void addWindowHandler(Window_Callback *handler) { movehandlers.push_back(handler); } + + /// Remove an event handler. + void removeWindowHandler(Window_Callback *handler) { movehandlers.remove(handler); } + + /// Create a subwindow of the given parent window. + Window(Window *parent, int x, int y, int w, int h); + + /// Destructor. + virtual ~Window(); + + /// Resize this window to the given dimensions. + /** If that would move part of the window outside of this window's area, + * the outside area will silently be clipped while drawing. */ + virtual void resize(int w, int h); + /// Return this window's width + virtual int getWidth() const { return width; } + /// Return this window's height + virtual int getHeight() const { return height; } + + /// Move this window to the given position relative to the parent window's origin. + /** If that would move part of the window outside of this window's area, + * the outside area will silently be clipped while drawing. */ + virtual void move(int x, int y); + /// Return this window's X position relative to the parent's top left corner + virtual int getX() const { return x; } + /// Return this window's Y position relative to the parent's top left corner + virtual int getY() const { return y; } + /// Return this window's contents' X position relative to the screen's top left corner + virtual int getScreenX() const { return (parent == NULL?0:parent->getScreenX()+x); } + /// Return this window's contents' Y position relative to the screen's top left corner + virtual int getScreenY() const { return (parent == NULL?0:parent->getScreenY()+y); } + + /// Draw this window's content including all children. + virtual void paintAll(Drawable &d) const; + + /// Draw this window's content. + virtual void paint(Drawable &d) const {}; + + /// Show or hide this window. + /** By default, most windows are shown when created. Hidden windows do not receive any events. */ + virtual void setVisible(bool v) { visible = !!v; parent->setDirty(); } + + /// Returns \c true if this window is visible. + virtual bool isVisible() const { return (!parent || parent->isVisible()) && visible; } + + /// Return parent window. + /** May return NULL if this is the topmost window (the Screen). */ + Window *getParent() const { return parent; } + + /// Get the topmost window (the Screen) + Screen *getScreen(); + + /// Returns \c true if this window has currently the keyboard focus. + virtual bool hasFocus() const { return parent->hasFocus() && *parent->children.rbegin() == this; } + + /// Mouse was moved. Returns true if event was handled. + virtual bool mouseMoved(int x, int y); + /// Mouse was moved while a button was pressed. Returns true if event was handled. + virtual bool mouseDragged(int x, int y, MouseButton button); + /// Mouse was pressed. Returns true if event was handled. + virtual bool mouseDown(int x, int y, MouseButton button); + /// Mouse was released. Returns true if event was handled. + virtual bool mouseUp(int x, int y, MouseButton button); + /// Mouse was clicked. Returns true if event was handled. + /** Clicking means pressing and releasing the mouse button while not moving it. */ + virtual bool mouseClicked(int x, int y, MouseButton button); + /// Mouse was double-clicked. Returns true if event was handled. + virtual bool mouseDoubleClicked(int x, int y, MouseButton button); + + /// Key was pressed. Returns true if event was handled. + virtual bool keyDown(const Key &key); + /// Key was released. Returns true if event was handled. + virtual bool keyUp(const Key &key); + + /// Put this window on top of all it's siblings. Preserves relative order. + /** Returns true if the window accepts the raise request. */ + virtual bool raise() { + Window *last = parent->children.back(); + for (Window *cur = parent->children.back(); cur != this; cur = parent->children.back()) { + parent->children.remove(cur); + parent->children.push_front(cur); + } + if (last != this) { + focusChanged(true); + last->focusChanged(false); + } + parent->setDirty(); + return true; + } + + /// Put this window below all of it's siblings. Does not preserve relative order. + virtual void lower() { + parent->children.remove(this); + parent->children.push_front(this); + if (this != parent->children.back()) { + parent->children.back()->focusChanged(true); + focusChanged(false); + } + parent->setDirty(); + } + + /// Return the \p n th child + Window *getChild(int n) { + for (std::list::const_iterator i = children.begin(); i != children.end(); ++i) { + if (n--) return *i; + } + return NULL; + } + +}; + +/** \brief A Screen represents the framebuffer that is the final destination of the GUI. + * + * It's main purpose is to manage the current contents of the surface and to combine + * it with all GUI elements. You can't resize and move the screen. Requests to do so + * will be ignored. + * + * This is an abstract base class. You need to use a subclass which implements rgbToSurface + * and surfaceToRGB. + * + * To make things work, Screen needs events. Call the mouse and key event functions (see Window) + * whenever such an event occurs. Call update(void *surface, int ticks) regularly, if possible about + * every 40msec (25 fps). If nothing has changed, screen updates are quite fast. + */ +class Screen : public Window { +protected: + /// Screen buffer. + Drawable *const buffer; + + /// Clipboard. + String clipboard; + + /// Currently pressed mouse button. + MouseButton button; + + /// Store a single RGB triple (8 bit each) as a native pixel value and advance pointer. + virtual void rgbToSurface(RGB color, void **pixel) = 0; + + /// Map a single framebuffer pixel to an RGB value. + virtual RGB surfaceToRGB(void *pixel) = 0; + + /// Create a new screen with the given characteristics. + Screen(Size width, Size height); + + /// Create a new screen from the given GUI::Drawable. + Screen(Drawable *d); + +public: + /// Destructor. + virtual ~Screen(); + + /// Set clipboard content. + template void setClipboard(const STR s) { this->setClipboard(String(s)); } + + /// Set clipboard content. + virtual void setClipboard(const String &s) { clipboard = s; } + + /// Get clipboard content. + virtual const String& getClipboard() { return clipboard; } + + /// Do nothing. + virtual void resize(int w, int h); + + /// Do nothing. + virtual void move(int x, int y); + + /// Screen has always focus. + virtual bool hasFocus() const { return true; } + + /// Update the given surface with this screen's content, fully honouring the alpha channel. + /** \p ticks can be set to a different value depending on how much time has passed. Timing + * doesn't need to be perfect, but try to call this at least every 40 msec. Each tick + * amounts to about 10 msec. Returns the number of ticks until the next event is scheduled, or + * 0 if none. */ + Ticks update(void *surface, Ticks ticks = 1); + + /// Default: clear screen. + virtual void paint(Drawable &d) const; +}; + +class Timer; + +/// Timer callback type +struct Timer_Callback { +public: + /// The timer has expired. + /** Callbacks for timers take one parameter, the number of ticks since + * application start. Note that this value may wrap after a little less + * than 500 days. If you want callbacks to be called again, return the + * delay in ticks relative to the scheduled time of this + * callback (which may be earlier than now() ). Otherwise return 0. */ + virtual Ticks timerExpired(Ticks time) = 0; + virtual ~Timer_Callback() {} +}; + +/** \brief Timing service. + * Time is measured in ticks. A tick is about 10 msec. + * + * Note that this is not suitable as a high-accuracy timing service. Timer + * events can be off by many ticks, and a tick may be slightly more or + * slightly less than 10 msec. Because of that, Timers are only intended for + * simple animation effects, input timeouts and similar things. + * + */ +class Timer { +protected: + /// Number of ticks since application start. + static Ticks ticks; + + /// Compare two integers for 'less-than'. + struct ltuint { bool operator()(Ticks i1, Ticks i2) const { + return (i1 < i2); + } }; + + /// Active timers. + static std::multimap timers; + +public: + /// Advance time and check for expired timers. + static void check(Ticks ticks); + + /// Add a timed callback. \p ticks is a value relative to now(). + /** \p cb is not copied. */ + static void add(Timer_Callback *cb, const Ticks ticks) { timers.insert(std::pair(ticks+Timer::ticks,cb)); } + + static void remove(const Timer_Callback *const cb); + + /// Return current time (ticks since application start) + static Ticks now() { return ticks; } + + /// Return number of ticks until next scheduled timer or 0 if no timers + static Ticks next(); +}; + + +/** \brief A 24 bit per pixel RGB framebuffer aligned to 32 bit per pixel. + * + * Warning: This framebuffer type varies with CPU endiannes. It is meant as + * a testing/debugging tool. + */ +class ScreenRGB32le : public Screen { +protected: + /// Map a single RGB triple (8 bit each) to a native pixel value. + virtual void rgbToSurface(RGB color, void **pixel) { RGB **p = (RGB **)pixel; **p = color; (*p)++; }; + + /// Map a single surface pixel to an RGB value. + virtual RGB surfaceToRGB(void *pixel) { return *(RGB*)pixel; }; +public: + ScreenRGB32le(Size width, Size height) : Screen(width,height) {}; + + virtual void paint(Drawable &d) const; +}; + + +#ifdef SDL_MAJOR_VERSION +/** \brief An SDL surface adapter. + * + * This screen type will draw on an SDL surface (honouring transparency if the + * surface is already filled) and react on SDL events. It does not provide an + * application event loop, you have to call update() and event() regularly until + * you decide to quit the application. + * + * The implementation of this class could as well have been integrated into + * GUI::Screen. That might have been a little more efficient, but this way + * this class serves as an example for custom screen classes. + * + * Note that you have to include \c SDL.h \em before \c gui_tk.h for this class + * to become available. + */ +class ScreenSDL : public Screen { +protected: + /// not used. + virtual void rgbToSurface(RGB color, void **pixel) {}; + + /// not used. + virtual RGB surfaceToRGB(void *pixel) { return 0; }; + + /// The SDL surface being drawn to. + SDL_Surface *surface; + + /// Position of last mouse down. + int downx, downy; + + /// time of last click for double-click detection. + Ticks lastclick; + +public: + + /** Initialize SDL screen with a surface + * + * The dimensions of this surface will define the screen dimensions. Changing the surface + * later on will not change the available area. + */ + ScreenSDL(SDL_Surface *surface); + + /** Change current surface + * + * The new surface may have different dimensions than the current one, but + * the screen size will not change. This means that either the screen will + * not be displayed fully, or there will be borders around the screen. + */ + void setSurface(SDL_Surface *surface) { this->surface = surface; } + + /// Retrieve current surface. + SDL_Surface *getSurface() { return surface; } + + /// Overridden: makes background transparent by default. + virtual void paint(Drawable &d) const; + + /// Use this to update the SDL surface. The screen must not be locked. + Ticks update(Ticks ticks); + + /// Process an SDL event. Returns \c true if event was handled. + bool event(const SDL_Event *ev) { return event(*ev); } + + + /// Process an SDL event. Returns \c true if event was handled. + bool event(const SDL_Event& ev); +}; +#endif + +class Font; + +/** \brief A drawable represents a rectangular off-screen drawing area. + * + * It is an off-screen buffer which can be copied to other drawables or + * to a Screen's framebuffer. The drawable's origin is at the top left. All + * operations are silently clipped to the available area. The alpha channel + * is honoured while copying one drawable to another, but not during other + * drawing operations. + * + * Drawables have a current font, color and (x,y) position. Drawing takes place + * at the given point using the given font and color. The current position is + * then moved to the final point of the drawing primitive unless otherwise + * noted. Pixel width of all lines is selectable, but be aware that visual + * appearance of lines with width > 1 is not as sophisticated as in well-known + * toolkits like Java or Qt. + * + * Some drawing primitives are overloaded to take full coordinates. These ignore + * the current position, but update it just like their regular brethren. + */ +class Drawable { +protected: + friend Ticks Screen::update(void *, Ticks); + /// The actual pixel buffer. + RGB *const buffer; + /// Total width of buffer. + const int width; + /// Total height of buffer. + const int height; + /// \c true if \a buffer must be freed by this instance. + const bool owner; + + /// Current color. + RGB color; + /// Current font. + const Font *font; + /// Current line width. + int lineWidth; + + /// X translation. + const int tx; + /// Y translation. + const int ty; + /// clip x. + const int cx; + /// clip y. + const int cy; + /// clip width. + const int cw; + /// clip height. + const int ch; + + /// Current position x coordinate. + int x; + /// Current position y coordinate. + int y; + +public: + /// Create an empty drawable object with given dimensions. + /** Optionally, the area is cleared with a given color (default: fully transparent). */ + Drawable(int w, int h, RGB clear = Color::Transparent); + + /// Deep-copying copy constructor. + /** It honours clip and translate so that the resulting drawable, if drawn + * to the source drawable at (0,0), yields the same result as drawing + * directly to the source surface. If \p fill is not explicitly set, will + * copy the original surface's contents */ + Drawable(Drawable &src, RGB clear = 0); + + /// Shallow-copying copy constructor with clip & translate. See setClipTranslate(int x, int y, int w, int h). + Drawable(Drawable &src, int x, int y, int w, int h); + + /// Destructor. + virtual ~Drawable(); + + /// Clears the surface. + void clear(RGB clear = Color::Transparent); + + /// Change current drawing color. + /** The alpha part is honoured in all drawing primitives like this: + All drawing operations in this window will unconditionally overwrite + earlier content of this window. Only when combining this window with + it's parent, the alpha channel is fully honoured. */ + void setColor(RGB c) { color = c; }; + /// Return the currently selected drawing color. + RGB getColor() { return color; }; + + /// Change current drawing font. + void setFont(const Font *f) { font = f; }; + /// Return the currently selected drawing font. + const Font *getFont() { return font; }; + + /// Change current line width. + void setLineWidth(int w) { lineWidth = w; }; + /// Return the current line width. + int getLineWidth() { return lineWidth; }; + + /// Move the current position to the given coordinates. + void gotoXY(int x, int y) { this->x = x; this->y = y; }; + /// Return current position X. + int getX() { return x; } + /// Return current position Y. + int getY() { return y; } + + /// Return clip width + int getClipX() { return cx; } + /// Return clip height + int getClipY() { return cy; } + /// Return clip width + int getClipWidth() { return cw; } + /// Return clip height + int getClipHeight() { return ch; } + + /// Paint a single pixel at the current position. + void drawPixel() { if (x >= cx && x < cw && y >= cy && y < ch) buffer[x+tx+(y+ty)*width] = color; }; + /// Paint a single pixel at the given coordinates. + void drawPixel(int x, int y) { gotoXY(x,y); drawPixel(); }; + + /// Return the pixel color at the current position. + RGB getPixel() { if (x >= cx && x < cw && y >= cy && y < ch) return buffer[x+tx+(y+ty)*width]; return Color::Transparent; }; + /// Return the pixel color at the given coordinates. + RGB getPixel(int x, int y) { gotoXY(x,y); return getPixel(); }; + + /// Draw a straight line from the current position to the given coordinates. + void drawLine(int x2, int y2); + /// Draw a straight line from (\p x1,\p y1) to (\p x2,\p y2). + void drawLine(int x1, int y1, int x2, int y2) { gotoXY(x1,y1); drawLine(x2,y2); }; + + /// Draw a circle centered at the current position with diameter \p d. + /** The current position is not changed. */ + void drawCircle(int d); + /// Draw a circle centered at the given coordinates with diameter \p d. + /** The current position is set to the center. */ + void drawCircle(int x, int y, int d) { gotoXY(x, y); drawCircle(d); }; + + /// Draw a rectangle with top left at the current position and size \p w, \p h. + /** The current position is not changed. */ + void drawRect(int w, int h); + /// Draw a rectangle with top left at the given coordinates and size \p w, \p h. + /** The current position is set to the top left corner. */ + void drawRect(int x, int y, int w, int h) { gotoXY(x, y); drawRect(w, h); }; + + /// Flood-fill an area at the current position. + /** A continuous area with the same RGB value as the selected pixel is + changed to the current color. The current position is not changed. */ + void fill(); + /// Flood-fill an area at a given position. + /** see fill(), but moves current position to the given coordinates */ + void fill(int x, int y) { gotoXY(x,y); fill(); }; + + /// Draw a filled circle centered at the current position with diameter \p d. + /** The current position is not changed. */ + void fillCircle(int d); + /// Draw a filled circle centered at the given coordinates with diameter \p d. + /** The current position is set to the center. */ + void fillCircle(int x, int y, int d) { gotoXY(x, y); fillCircle(d); }; + + /// Draw a filled rectangle with top left at the current position and size \p w, \p h. + /** The current position is not changed. */ + void fillRect(int w, int h); + /// Draw a filled rectangle with top left at the given coordinates and size \p w, \p h. + /** The current position is set to the top left corner. */ + void fillRect(int x, int y, int w, int h) { gotoXY(x, y); fillRect(w, h); }; + + /// Draw a text string. + /** Current position is the leftmost pixel on the baseline of the character. + The current position is moved to the next character. Background is not + cleared. If \p interpret is \c true, some ASCII control characters like + backspace, line-feed, tab and ANSI colors are interpreted, and text is word-wrapped at + the window borders. You can optionally pass start and length of a substring + to print */ + void drawText(const String& text, bool interpret = true, Size start = 0, Size len = -1); + + /// Draw a text string at a fixed position. + /** see drawText(const String& text, bool interpret, Size start, Size len) */ + template void drawText(int x, int y, const STR text, bool interpret, Size start, Size len = -1) { gotoXY(x,y); drawText(String(text), interpret, start, len); }; + /// Draw a single character. + /** see drawText(const STR text, bool interpret), except wrapping is + performed on this character only */ + void drawText(const Char c, bool interpret = false); + /// Draw a single character at a fixed position. + /** see drawText(const Char c, bool interpret). */ + void drawText(int x, int y, const Char c, bool interpret = false) { gotoXY(x,y); drawText(c, interpret); }; + + /// Copy the contents of another Drawable to this one. + /** The top left corner of the source Drawable is put at the current + position. The alpha channel is fully honoured. Additionally, an extra + \p alpha value may be given which is multiplied with the source + alpha channel. The current position remains unchanged. */ + void drawDrawable(Drawable &d, unsigned char alpha = 1); + /// Copy the contents of another Drawable to this one at a given position. + /** see drawDrawable(Drawable &d, unsigned char alpha). The current position + is moved to the given coordinates. */ + void drawDrawable(int x, int y, Drawable &d, unsigned char alpha = 1) { gotoXY(x,y); drawDrawable(d, alpha); }; + +}; + +/** \brief A variable- or fixed-width fixed-size Font. + * + * These Fonts can't be scaled once instantiated, but it is possible + * to subclass this abstract font class to encapsulate scalable + * fonts. Fonts can be anti-aliasing and multi-coloured, depending on + * subclass. There is no encoding enforced. The font object implicitly + * knows about it's encoding. Because of that, there is a utility + * function for string examination as well. + * + * You can't instantiate objects of this class directly, use one of the + * subclasses like BitmapFont. + * + * This class provides a font registry which allows you to register + * and retrieve font objects using a name of your choice. It is recommended + * to use a naming scheme like "FontName-variant-pixelsize-encoding" where + * variant is "normal", "bold", "italic" or "bolditalic". No one enforces + * this, however. + * + * The GUI uses some special font names. You must add them before creating + * the relevant GUI item. + * \li \c default - used if a requested font was not found + * \li \c title - GUI::ToplevelWindow title + * \li \c input - GUI::Input + * + */ +class Font { +protected: + friend void Drawable::drawText(const Char c, bool interpret); + friend void Drawable::drawText(const String& s, bool interpret, Size start, Size len); + + /// Compare two strings for 'less-than'. + struct ltstr { bool operator()(const char* s1, const char* s2) const { + return strcmp(s1, s2) < 0; + } }; + /// Font registry. Contains all known font objects indexed by name. + static std::map registry; + + /// Default constructor. + Font() {}; + + /// Draw character to a drawable at the current position. + /** \p d's current position is advanced to the position of the next character. + * The y coordinate is located at the baseline before and after the call. */ + virtual void drawChar(Drawable *d, const Char c) const = 0; + + /// Draw \p len characters to a drawable at the current position, starting at string position \p start. + /** This can be used to provide kerning. */ + virtual void drawString(Drawable *d, const String &s, Size start, Size len) const { if (len > s.size()-start) len = s.size()-start; len += start; while (start < len) drawChar(d,s[start++]); } + +public: + /// Return a font with the given name (case-sensitive). + /** If no font was registered with that name, returns NULL. */ + static const Font *getFont(const char *name) { + std::map::iterator i = registry.find(name); + if (i == registry.end()) return(strcmp(name,"default")?getFont("default"):NULL); + return (*i).second; + } + + /// Add a font with a given name. + /** Don't delete this font once added. This class will do that for you. + * If a font with that name already exists, it will be replaced. */ + static void addFont(const char *name, Font *font) { + std::map::iterator i = registry.find(name); + if (i != registry.end()) delete (*i).second; + registry[name] = font; + } + + virtual ~Font() {}; + + /// Retrieve total height of font in pixels. + virtual int getHeight() const = 0; + + /// Retrieve the ascent, i.e. the number of pixels above the base line. + virtual int getAscent() const = 0; + + /// Return width of a string. + template int getWidth(const STR s, Size start = 0, Size len = (Size)-1) const { + return this->getWidth(String(s), start, len); + } + + /// Retrieve width of a character. + virtual int getWidth(Char c = 'M') const = 0; + + /// Retrieve width of a string of characters. + /** Can be used to provide kerning. */ + virtual int getWidth(const String &s, Size start = 0, Size len = (Size)-1) const { + int width = 0; + if (start+len > s.size()) len = s.size()-start; + while (len--) width += getWidth(s[start++]); + return width; + } + + /// Characters with special appearance or meaning. + enum SpecialChar { CR = '\r', LF = '\n', BS = '\b', Tab = '\t', Space = ' ', ESC = 27 }; + + /// Convert a character to an equivalent SpecialChar. May return values not in SpecialChar. + virtual SpecialChar toSpecial(Char c) const { return (SpecialChar)(c<255?c:255); } + + /// Convert a SpecialChar to an equivalent character. + virtual Char fromSpecial(SpecialChar c) const { return c; } +}; + +/** \brief A bitmap font. + * This is a font which is defined by a binary bit map. Each bit in the bitmap + * defines one pixel. Bits may be arranged in various common patterns. + * + * Encoding free, character size depends on number of characters in the font. + */ +class BitmapFont : public Font { +protected: + /// The actual font data. + const unsigned char *const bitmap; + + /// Width of a character cell. + const int width; + + /// Height of all characters. + const int height; + + /// Ascent of all characters. + const int ascent; + + /// Array of character widths. If font is fixed-width, this is NULL and \a width is used. + const int *const widths; + + /// Array of character ascents. If this is NULL, \a ascent is used for all characters. + /** This allows character data to be flush to the top or bottom of it's bitmap area. */ + const int *const ascents; + + /// True if set bits are background, false otherwise. + const bool background_set; + + /// Number of bits added to get from a column to the next column. + const int col_step; + + /// Distance between 2 rows of a character, or 0 for variable-width rows. + const int row_step; + + /// Distance of two characters in the bitmap in bits. + /** This is calculated as abs(row_step*height) unless explicitly specified. */ + const int character_step; + + /// Array of pointers to font data. If set, neither \a bitmap nor \a character_step are used. + const unsigned char *const*const char_position; + + /// Array of SpecialChar equivalents. + /** If unset, encoding is assumed ASCII-like for the first 32 characters */ + const SpecialChar *const special; + + /// If \c true, then all arrays are freed on destruction. + const bool owner; + + /// Last defined character. Characters above this will be ignored. + const Char last; + + /// Draw character to a drawable at the current position. + /** \p d's current position is advanced to the position of the next character. + * The y coordinate is located at the baseline before and after the call. */ + virtual void drawChar(Drawable *d, const Char c) const; + +public: + /// Constructor. + /** The default values provide an 8 bit wide fixed-width pixel layout with each byte a row, + * arranged top-to-bottom just like a PC's VGA font. See the individual member documentation + * for details on the parameters. */ + BitmapFont(const unsigned char *data, int height, int ascent, bool owner = false, + int width = 8, bool background_set = false, + int col_step = -1, int row_step = 8, int character_step = 0, Char last = 256, + const int *widths = NULL, const int *ascents = NULL, + const unsigned char *const* char_position = NULL, + const SpecialChar *special = NULL); + + virtual ~BitmapFont(); + + /// Retrieve total height of font in pixels. + virtual int getHeight() const { return height; }; + + /// Retrieve the ascent, i.e. the number of pixels above the base line. + virtual int getAscent() const { return ascent; }; + + /// Retrieve width of a character. + virtual int getWidth(Char c = 'M') const { return (widths != NULL?widths[c]:width); }; + + /// Convert a character to an equivalent SpecialChar. See Font::toSpecial(Char c) + virtual SpecialChar toSpecial(Char c) const { return (special != NULL?special[c]:Font::toSpecial(c)); } + + /// Convert a character to an equivalent character. See Font::fromSpecial(SpecialChar c). + virtual Char fromSpecial(SpecialChar c) const { if (special == NULL) return Font::fromSpecial(c); Char i = 0; while(special[i] != c) i++; return i; } + +}; + +class ActionEventSource; +/// Callback for action events. +struct ActionEventSource_Callback { +public: + /// Handler with optional String argument. + /** If the event source doesn't provide an additional argument, the name will be used. */ + virtual void actionExecuted(ActionEventSource *source, const String &arg) = 0; + virtual ~ActionEventSource_Callback() {} +}; + +/// Event class for action events. +/** Action events are events generated by GUI elements like Buttons, Menus and by pressing Enter in + * an Input. All of these are handled similarly: The source of such an event has a name, and the + * Event may also be connected with a String describing what was executed, like the name of the + * Menu entry or the contents of the Input. + */ +class ActionEventSource { +protected: + /// List of registered action handlers. + std::list actionHandlers; + + /// This event source's name. + /** The name is primarily meant for your own purposes, for example identification of the activated + * element. One exception are Menubars, which display the name of their Menus. */ + String name; + +public: + /// Create a named event source. + template ActionEventSource(const STR name) : name(String(name)) { } + + /// Dummy destructor. + virtual ~ActionEventSource() {} + + /// Add a button press event handler. + void addActionHandler(ActionEventSource_Callback *handler) { actionHandlers.push_back(handler); } + + /// Remove a button press event handler. + void removeActionHandler(ActionEventSource_Callback *handler) { actionHandlers.remove(handler); } + + /// Set the name of this event source. + template void setName(const STR name) { this->name = String(name); } + + /// Get the name of this event source. + const String &getName() const { return name; } + + /// Execute handlers. + void executeAction(const String &arg) { + std::list::iterator i = actionHandlers.begin(); + bool end = (i == actionHandlers.end()); + while (!end) { + ActionEventSource_Callback *c = *i; + ++i; + end = (i == actionHandlers.end()); + c->actionExecuted(this,arg); + } + } + + /// Execute handlers. + void executeAction() { executeAction(name); } +}; + +/// Internal class for windows whose child content should not span the entire area. +class BorderedWindow : public Window { +protected: + /// Borders. + int border_left, border_top, border_right, border_bottom; + + /// Create a bordered window. + BorderedWindow(Window *parent, int x, int y, int w, int h, int bl, int bt, int br, int bb) : + Window(parent,x,y,w,h), border_left(bl), border_top(bt), border_right(br), border_bottom(bb) {} + +public: + virtual void paintAll(Drawable &d) const; + virtual bool mouseMoved(int x, int y); + virtual bool mouseDown(int x, int y, MouseButton button); + virtual bool mouseDragged(int x, int y, MouseButton button); + virtual int getScreenX() const { return Window::getScreenX()+border_left; } + virtual int getScreenY() const { return Window::getScreenY()+border_top; } +}; + +/// A text label +/** Text labels are positioned relative to the top left corner of their bounding box. + * They size themselves automatically and display their text in non-interpreted mode. + */ + +class Label : public Window { + /// The Font used + const Font *font; + + /// Text color + RGB color; + + /// Text + String text; + + /// multiline text? + bool interpret; + +public: + /// Create a text label with given position, \p text, \p font and \p color. + /** If \p width is given, the resulting label is a word-wrapped multiline label */ + template Label(Window *parent, int x, int y, const STR text, int width = 0, const Font *font = Font::getFont("default"), RGB color = Color::Text) : + Window(parent, x, y, (width?width:1), 1), font(font), color(color), text(text), interpret(width != 0) + { resize(); } + + /// Set a new text. Size of the label is adjusted accordingly. + template void setText(const STR text) { this->text = text; resize(); } + /// Retrieve current text + const String& getText() { return text; } + + /// Set a new font. Size of the label is adjusted accordingly. + void setFont(const Font *font) { this->font = font; resize(); } + /// Retrieve current font + const Font *getFont() { return font; } + + /// Set a new text color. + void setColor(const RGB color) { this->color = color; resize(); } + /// Retrieve current color + RGB getColor() { return color; } + + /// Calculate label size. Parameters are ignored. + virtual void resize(int w = -1, int h = -1) { + if (w == -1) w = (interpret?getWidth():0); + else interpret = (w != 0); + Drawable d((w?w:1), 1); + d.setFont(font); + d.drawText(0, font->getAscent(), text, interpret, 0); + if (interpret) Window::resize(w, d.getY()-font->getAscent()+font->getHeight()); + else Window::resize(d.getX(), font->getHeight()); + } + + /// Paint label + virtual void paint(Drawable &d) const { d.setColor(color); d.drawText(0, font->getAscent(), text, interpret, 0); } + + virtual bool raise() { return false; } +}; + + +/// A single-line text input +/** It uses Font::getFont("input") to display content. + * It supports selection, the clipboard and all well-known key bindings (except undo). + */ +class Input : public Window, public Timer_Callback, public ActionEventSource { +protected: + /// The text entered. + String text; + + /// Current position in \a text. + Size pos; + + /// Last updated position in \a text. + Size lastpos; + + /// Coordinates according to pos. + int posx, posy; + + /// Selection in \a text. + Size start_sel, end_sel; + + /// Is cursor visible at the moment? + bool blink; + + /// Insert mode? + bool insert; + + /// Multiline? + bool multi; + + /// Horizontal scrolling offset. + int offset; + + /// Ensure that pos is visible. + void checkOffset() { + if (lastpos == pos) return; + const Font *f = Font::getFont("input"); + if (multi) { + Drawable d(width-6,1); + d.setFont(f); + d.drawText(0, 0, text, multi, 0, pos); + posy = d.getY(); + posx = d.getX(); + if (posy-offset > height-8-f->getHeight()) offset = posy-height+8+f->getHeight(); + if (posy-offset < 0) offset = posy; + } else { + posy = 0; + posx = f->getWidth(text,0,pos); + if (f->getWidth(text,0,pos+1)-offset > width-10) offset = f->getWidth(text,0,pos+1)-width+10; + if (f->getWidth(text,0,(pos>0?pos-1:0))-offset < 0) offset = f->getWidth(text,0,(pos>0?pos-1:0)); + } + lastpos = pos; + setDirty(); + } + +public: + /// Create an input with given position and width. If not set, height is calculated from the font and input is single-line. + Input(Window *parent, int x, int y, int w, int h = 0) : + Window(parent,x,y,w,(h?h:Font::getFont("input")->getHeight()+10)), ActionEventSource("GUI::Input"), + text(""), pos(0), lastpos(0), posx(0), posy(0), start_sel(0), end_sel(0), blink(true), insert(true), multi(h != 0), offset(0) + { Timer::add(this,30); } + + ~Input() { + Timer::remove(this); + } + + /// Paint input. + virtual void paint(Drawable &d) const; + + /// Clear selected area. + void clearSelection() { + text.erase(text.begin()+(pos = imin(start_sel,end_sel)),text.begin()+imax(start_sel,end_sel)); + start_sel = end_sel = pos; + } + + /// Copy selection to clipboard. + void copySelection() { + setClipboard(String(text.begin()+imin(start_sel,end_sel),text.begin()+imax(start_sel,end_sel))); + } + + /// Cut selection to clipboard. + void cutSelection() { + setClipboard(String(text.begin()+imin(start_sel,end_sel),text.begin()+imax(start_sel,end_sel))); + clearSelection(); + } + + /// Paste from clipboard. + void pasteSelection() { + String c = getClipboard(); + clearSelection(); + text.insert(text.begin()+pos,c.begin(),c.end()); + start_sel = end_sel = pos += c.size(); + } + + /// get character position corresponding to coordinates + Size findPos(int x, int y); + + /// Set text to be edited. + template void setText(const STR text) { this->text = text; setDirty(); }; + /// Get the entered text. If you need it longer, copy it immediately. + const String& getText() { return text; }; + + /// Handle text input. + virtual bool keyDown(const Key &key); + + /// Handle mouse input. + virtual bool mouseDown(int x, int y, MouseButton button); + + /// Handle mouse input. + virtual bool mouseDragged(int x, int y, MouseButton button); + + /// Timer callback function + virtual Ticks timerExpired(Ticks time) + { blink = !blink; setDirty(); return 30; } + +}; + +class ToplevelWindow; +/// Callbacks for window events. +struct ToplevelWindow_Callback { +public: + /// The window has been asked to be closed. + /** Return \c false in order to block the requested action. Do not do any + * deallocation here, as other callbacks may abort the close process. + */ + virtual bool windowClosing(ToplevelWindow *win) = 0; + + /// The window will been closed. + /** Now it is safe to deallocate all external resources that applications + * may have associated with this window, like registering this window + * with external callbacks. + */ + virtual void windowClosed(ToplevelWindow *win) = 0; + virtual ~ToplevelWindow_Callback() {} +}; + +/// An actual decorated window. +class ToplevelWindow : public BorderedWindow, public ActionEventSource_Callback { +protected: + /// Title text + String title; + + /// Drag base + int dragx, dragy; + + /// List of registered event handlers. + std::list closehandlers; + + /// System menu (top left) + Menu *systemMenu; + +public: + /// Create a new GUI Frame with title bar, border and close button + template ToplevelWindow(Screen *parent, int x, int y, int w, int h, const STR title); + + /// Call cleanup handlers + ~ToplevelWindow() { + std::list::iterator i = closehandlers.begin(); + bool end = (i == closehandlers.end()); + while (!end) { + ToplevelWindow_Callback *c = *i; + ++i; + end = (i == closehandlers.end()); + c->windowClosed(this); + } + } + + /// Menu callback function + virtual void actionExecuted(ActionEventSource *src, const String &item) { + if (item == String("Close")) close(); + } + + /// Add a window event handler. + void addCloseHandler(ToplevelWindow_Callback *handler) { closehandlers.push_back(handler); } + + /// Remove a window event handler. + void removeCloseHandler(ToplevelWindow_Callback *handler) { closehandlers.remove(handler); } + + virtual void paint(Drawable &d) const; + virtual bool mouseDown(int x, int y, MouseButton button); + virtual bool mouseDoubleClicked(int x, int y, MouseButton button) { + if (button == Left && x < 32 && x > 6 && y > 4 && y < 31) { + close(); + return true; + } + BorderedWindow::mouseClicked(x,y,button); + return true; + } + virtual bool mouseUp(int x, int y, MouseButton button) { + if (button == Left && dragx >= 0 && dragy >= 0) { + dragx = dragy = -1; + return true; + } + BorderedWindow::mouseUp(x,y,button); + return true; + } + virtual bool mouseDragged(int x, int y, MouseButton button) { + if (button == Left && dragx >= 0 && dragy >= 0) { + move(x-dragx+this->x,y-dragy+this->y); + return true; + } + BorderedWindow::mouseDragged(x,y,button); + return true; + } + virtual bool mouseMoved(int x, int y) { + BorderedWindow::mouseMoved(x,y); + return true; + } + + /// Put window on top of all other windows without changing their relative order + virtual bool raise() { + Window *last = parent->children.back(); + parent->children.remove(this); + parent->children.push_back(this); + if (last != this) { + focusChanged(true); + last->focusChanged(false); + } + return true; + } + + /// Set a new title. + template void setTitle(const STR title) { this->title = title; setDirty(); } + /// Retrieve current title. + const String& getTitle() { return title; } + + /// Close window. + void close() { + bool doit = true; + std::list::iterator i = closehandlers.begin(); + bool end = (i == closehandlers.end()); + while (!end) { + ToplevelWindow_Callback *c = *i; + ++i; + end = (i == closehandlers.end()); + doit = doit && c->windowClosing(this); + } + if (doit) delete this; + } +}; + +/// A floating temporary window that is not restricted by it's parent's area. +/** They have a parent which displays them, + * but that parent is not their real parent in the window hierarchy: They are always top-level elements, thus + * they are not clipped to their logical parent's area, they can freely overlay any part of the screen. + * As another consequence, they are not automatically deleted when their logical parent is deleted. + * + * You should observe the following points: + * \li TransientWindows behave mostly as if their logical parent was their true parent, but are not + * restricted to it's area + * \li TransientWindows are deleted automatically when the ToplevelWindow is deleted in which their logical + * parent resides; do NOT delete them in your destructor or bad things will happen + * \li only the logical parent object can show/hide a TransientWindow at will + * \li it will close automatically upon clicking other GUI elements, \em except for the + * logical parent and it's children + */ +class TransientWindow : public Window, Window_Callback, ToplevelWindow_Callback { +protected: + /// The true parent window. + Window *realparent; + + /// User selected position relative to logical parent. + int relx, rely; + +public: + /// Handle automatic hiding + virtual void focusChanged(bool gained) { + Window::focusChanged(gained); + if (isVisible() && !gained) { + if (realparent->hasFocus()) raise(); + else setVisible(false); + } + } + + /// Handle automatic delete + void windowClosed(ToplevelWindow *win) { + delete this; + } + + /// No-op + bool windowClosing(ToplevelWindow *win) { return true; } + + /// Create a transient window with given position and size + /** \a parent is the logical parent. The true parent object is + * always the screen the logical parent resides on. */ + TransientWindow(Window *parent, int x, int y, int w, int h) : + Window(parent->getScreen(),x+parent->getScreenX(),y+parent->getScreenY(),w,h), + realparent(parent), relx(x), rely(y) { + Window *p = realparent, *last = NULL, *last2 = NULL; + while (p != NULL) { + p->addWindowHandler(this); + last2 = last; + last = p; + p = p->getParent(); + } + dynamic_cast(last2)->addCloseHandler(this); + } + + ~TransientWindow() { + Window *p = realparent, *last = NULL, *last2 = NULL; + while (p != NULL) { + p->removeWindowHandler(this); + last2 = last; + last = p; + p = p->getParent(); + } + dynamic_cast(last2)->removeCloseHandler(this); + } + + virtual void move(int x, int y) { relx = x; rely = y; + Window::move(x+realparent->getScreenX(),y+realparent->getScreenY()); } + virtual int getX() { return x-realparent->getScreenX(); } + virtual int getY() { return y-realparent->getScreenY(); } + virtual void setVisible(bool v) { if (v) raise(); Window::setVisible(v); } + virtual void windowMoved(Window *src, int x, int y) { move(relx,rely); } + + /// Put window on top of all other windows without changing their relative order + virtual bool raise() { + Window *last = parent->children.back(); + parent->children.remove(this); + parent->children.push_back(this); + if (last != this) { + focusChanged(true); + last->focusChanged(false); + } + return true; + } + +}; + +/// A popup menu. +/** Popup menus are used as context menus or as part of a menu bar. Menus are not visible when created. + * Menus have a name which can be used in event handlers to identify it, and it is used in Menubars as well. + * + * Currently, menu entries are not interpreted in any way. This may change in the future. To ensure upwards + * compatibility, avoid the \c '&' character in menu entries, since it may have a special meaning in future + * versions. Menus use the Font named "menu". + * + * Please note the general remarks in GUI::TransientWindow + */ +class Menu : public TransientWindow, public ActionEventSource { +protected: + /// List of menu items (displayed text) + std::vector items; + + /// Currently selected menu item. + /** Can be -1 if no item is currently active. */ + int selected; + + /// Flag to skip the first mouseUp-event + bool firstMouseUp; + + /// Where we grabbed the mouse from. + Window *mouseTakenFrom; + + /// Selects menu item at position (x,y). + /** \a selected is set to -1 if there is no active item at that location. */ + virtual void selectItem(int x, int y) { + y -= 2; + selected = -1; + const int height = Font::getFont("menu")->getHeight()+2; + std::vector::iterator i; + for (i = items.begin(); i != items.end() && y > 0; ++i) { + selected++; + if ((*i).size() > 0) y -= height; + else y -= 12; + } + if (y > 0 || (selected >= 0 && items[selected].size() == 0)) selected = -1; + } + + virtual Size getPreferredWidth() { + Size width = 0; + const Font *f = Font::getFont("menu"); + std::vector::iterator i; + for (i = items.begin(); i != items.end() && y > 0; ++i) { + Size newwidth = f->getWidth(*i); + if (newwidth > width) width = newwidth; + } + return width+39; + } + + virtual Size getPreferredHeight() { + Size height = 0; + const Size h = Font::getFont("menu")->getHeight()+2; + std::vector::iterator i; + for (i = items.begin(); i != items.end() && y > 0; ++i) { + height += ((*i).size() > 0?h:12); + } + return height+6; + } + +public: + /// Create a menu with given position + /** Size is determined dynamically. \a parent is the logical parent. The true parent object is + * always the screen the logical parent resides on. */ + template Menu(Window *parent, int x, int y, const STR name) : + TransientWindow(parent,x,y,4,4), ActionEventSource(name), selected(-1) + { setVisible(false); } + + ~Menu() { + setVisible(false); + } + + /// Paint button. + virtual void paint(Drawable &d) const; + + /// Highlight current item. + virtual bool mouseMoved(int x, int y) { + selectItem(x,y); + return true; + } + + /// Highlight current item. + virtual bool mouseDragged(int x, int y, MouseButton b) { + selectItem(x,y); + return true; + } + + virtual bool mouseDown(int x, int y, MouseButton button) { return true; } + + /// Possibly select item. + virtual bool mouseUp(int x, int y, MouseButton button) { + selectItem(x,y); + if (firstMouseUp) firstMouseUp = false; + else setVisible(false); + execute(); + return true; + } + + /// Handle keyboard input. + virtual bool keyDown(const Key &key) { + if (key.special == Key::Up) selected--; + else if (key.special == Key::Down) selected++; + else if (key.special == Key::Enter) { execute(); return true; } + else if (key.special == Key::Escape) { setVisible(false); return true; } + else return true; + if (items[selected].size() == 0 && items.size() > 1) return keyDown(key); + if (selected < 0) selected = items.size()-1; + if (selected >= (int)items.size()) selected = 0; + return true; + } + + + /// Add a menu item at end. An empty string denotes a separator. + template void addItem(const T item) { + items.push_back(String(item)); + resize(getPreferredWidth(),getPreferredHeight()); + } + + /// Remove an existing menu item. + template void removeItem(const T item) { + const String s(item); + std::vector::iterator i = items.begin(); + while (i != items.end() && s != (*i)) ++i; + if (i != items.end()) items.erase(i); + resize(getPreferredWidth(),getPreferredHeight()); + } + + virtual void setVisible(bool v) { + TransientWindow::setVisible(v); + if (v) { + parent->mouseChild = this; + raise(); + firstMouseUp = true; + } + } + + /// Execute menu item. + void execute() { + if (selected >= 0) { + setVisible(false); + executeAction(items[selected]); + } + } +}; + +/// A push button +/** Buttons have 3D appearance and can have any child widget as content. + * There are convenience constructors for common forms of buttons. + */ +class Button : public BorderedWindow, public ActionEventSource { +protected: + /// \c true, if button is currently pressed down. + bool pressed; + +public: + /// Create a button with given position and size + Button(Window *parent, int x, int y, int w, int h) : BorderedWindow(parent,x,y,w,h,6,5,6,5), ActionEventSource("GUI::Button"), pressed(0) {} + + /// Create a text button. + /** If a size is specified, text is centered. Otherwise, button size is adjusted for the text. */ + template Button(Window *parent, int x, int y, const T text, int w = -1, int h = -1); + + /// Paint button. + virtual void paint(Drawable &d) const; + + /// Press button. + virtual bool mouseDown(int x, int y, MouseButton button) { + border_left = 7; border_right = 5; border_top = 7; border_bottom = 3; + pressed = true; + return true; + } + + /// Release button. + virtual bool mouseUp(int x, int y, MouseButton button) { + border_left = 6; border_right = 6; border_top = 5; border_bottom = 5; + pressed = false; + return true; + } + + /// Handle mouse activation. + virtual bool mouseClicked(int x, int y, MouseButton button) { + if (button == Left) { + executeAction(); + return true; + } + return false; + } + + /// Handle keyboard input. + virtual bool keyDown(const Key &key); + + /// Handle keyboard input. + virtual bool keyUp(const Key &key); + +}; + +/// A menu bar at the top of a ToplevelWindow +/** Menu bars aggregate several Menus. They have a simple border at the bottom. If your application + * has a work area with 3D sunken look, place it so that it overlaps the menu by one row. + * + * As with Menus, avoid the character \c '&' in Menu names as it may + * have a special meaning in future versions. Menubars use the Font named "menu". + */ +class Menubar : public Window, public ActionEventSource, ActionEventSource_Callback { +protected: + /// Currently activated menu index. + int selected; + + /// Horizontal position of next menu. + int lastx; + + /// List of Menus. + std::vector menus; + +public: + /// Create a menubar with given position and size + /** Height is autocalculated from font size */ + Menubar(Window *parent, int x, int y, int w) : Window(parent,x,y,w,Font::getFont("menu")->getHeight()+5), ActionEventSource("GUI::Menubar"), selected(-1), lastx(0) {} + + /// Add a Menu. + template void addMenu(const STR name) { + const String n(name); + menus.push_back(new Menu(this,lastx,height-2,n)); + menus.back()->addActionHandler(this); + lastx += Font::getFont("menu")->getWidth(n)+14; + } + + /// Add a Menuitem. + template void addItem(int index, const STR name) { menus[index]->addItem(name); } + + /// Remove a Menuitem. + template void removeItem(int index, const STR name) { menus[index]->removeItem(name); } + + /// Paint menubar. + virtual void paint(Drawable &d) const; + + /// Open menu. + virtual bool mouseDown(int x, int y, MouseButton button) { + int oldselected = selected; + if (selected >= 0 && !menus[selected]->isVisible()) oldselected = -1; + if (selected >= 0) menus[selected]->setVisible(false); + if (x < 0 || x >= lastx) return true; + for (selected = menus.size()-1; menus[selected]->getX() > x; selected--); + if (oldselected == selected) selected = -1; + else menus[selected]->setVisible(true); + return true; + } + + /// Handle keyboard input. + virtual bool keyDown(const Key &key) { return true; }; + + /// Handle keyboard input. + virtual bool keyUp(const Key &key) { return true; }; + + virtual void actionExecuted(ActionEventSource *src, const String &arg) { + std::list::iterator i = actionHandlers.begin(); + bool end = (i == actionHandlers.end()); + while (!end) { + ActionEventSource_Callback *c = *i; + ++i; + end = (i == actionHandlers.end()); + c->actionExecuted(src,arg); + } + } +}; + +/// A checkbox +/** Checkboxes can have any child widget as content. + * There are convenience constructors for common forms of checkboxes. + */ +class Checkbox : public BorderedWindow, public ActionEventSource { +protected: + /// \c true, if checkbox is currently selected. + bool checked; + +public: + /// Create a checkbox with given position and size + Checkbox(Window *parent, int x, int y, int w, int h) : BorderedWindow(parent,x,y,w,h,16,0,0,0), ActionEventSource("GUI::Checkbox"), checked(0) {} + + /// Create a checkbox with text label. + /** If a size is specified, text is centered. Otherwise, checkbox size is adjusted for the text. */ + template Checkbox(Window *parent, int x, int y, const T text, int w = -1, int h = -1); + + /// Paint checkbox. + virtual void paint(Drawable &d) const; + + /// Change checkbox state. + virtual void setChecked(bool checked) { this->checked = checked; } + + /// Get checkbox state. + virtual bool isChecked() { return checked; } + + /// Press checkbox. + virtual bool mouseDown(int x, int y, MouseButton button) { + checked = !checked; + return true; + } + + /// Release checkbox. + virtual bool mouseUp(int x, int y, MouseButton button) { + execute(); + return true; + } + + /// Handle keyboard input. + virtual bool keyDown(const Key &key); + + /// Handle keyboard input. + virtual bool keyUp(const Key &key); + + /// Execute handlers. + virtual void execute() { + String arg(name); + if (!checked) arg.insert(arg.begin(),'!'); + executeAction(arg); + } +}; + +class Frame; + +/// A radio box. +/** Radio boxes can have any child widget as content. + * There are convenience constructors for common forms of radio boxes. + */ +class Radiobox : public BorderedWindow, public ActionEventSource { +protected: + /// \c true, if radio box is currently selected. + bool checked; + +public: + /// Create a radio box with given position and size + Radiobox(Frame *parent, int x, int y, int w, int h); + + /// Create a radio box with text label. + /** If a size is specified, text is centered. Otherwise, checkbox size is adjusted for the text. */ + template Radiobox(Frame *parent, int x, int y, const T text, int w = -1, int h = -1); + + /// Paint radio box. + virtual void paint(Drawable &d) const; + + /// Change radio box state. + virtual void setChecked(bool checked) { this->checked = checked; } + + /// Get radio box state. + virtual bool isChecked() { return checked; } + + /// Press radio box. + virtual bool mouseDown(int x, int y, MouseButton button) { + checked = true; + return true; + } + + /// Release checkbox. + virtual bool mouseUp(int x, int y, MouseButton button) { + executeAction(); + return true; + } + + /// Handle keyboard input. + virtual bool keyDown(const Key &key); + + /// Handle keyboard input. + virtual bool keyUp(const Key &key); +}; + +/// A rectangular 3D sunken frame +/** These can be used as generic grouping elements and also serve as aggregators for RadioBoxes. + */ +class Frame : public BorderedWindow, public ActionEventSource, protected ActionEventSource_Callback { +protected: + friend class Radiobox; + + /// Currently selected radio box. + int selected; + + /// Label of frame. + String label; + + /// Execute handlers. + virtual void actionExecuted(ActionEventSource *src, const String &arg) { + for (std::list::iterator i = children.begin(); i != children.end(); ++i) { + Radiobox *r = dynamic_cast(*i); + if (r != NULL && src != dynamic_cast(r)) r->setChecked(false); + } + executeAction(src->getName()); + } + +public: + /// Create a non-labeled frame with given position and size + Frame(Window *parent, int x, int y, int w, int h) : BorderedWindow(parent,x,y,w,h,5,5,5,5), ActionEventSource("GUI::Frame"), selected(0) {} + + /// Create a frame with text label. + template Frame(Window *parent, int x, int y, int w, int h, const T text) : + BorderedWindow(parent,x,y,w,h,5,Font::getFont("default")->getHeight()+2,5,5), + ActionEventSource(text), selected(0), label(text) { } + + /// Paint frame. + virtual void paint(Drawable &d) const; + +}; + +/// A message box with a single "Close" button. +class MessageBox : public GUI::ToplevelWindow { +protected: + Label *message; + Button *close; +public: + /// Create a new message box + template MessageBox(Screen *parent, int x, int y, int width, const STR title, const STR text) : + ToplevelWindow(parent, x, y, width, 1, title) { + message = new Label(this, 5, 5, text, width-10); + close = new GUI::Button(this, width/2-40, 10, "Close", 70); + close->addActionHandler(this); + setText(text); + } + + /// Set a new text. Size of the box is adjusted accordingly. + template void setText(const STR text) { + message->setText(text); + close->move(width/2-40, 20+message->getHeight()); + resize(width, message->getHeight()+100); + } +}; + +template ToplevelWindow::ToplevelWindow(Screen *parent, int x, int y, int w, int h, const STR title) : + BorderedWindow(parent, x, y, w, h, 6, 33, 6, 3), title(title), + dragx(-1), dragy(-1), closehandlers(), systemMenu(new Menu(this,-1,-2,"System Menu")) { + systemMenu->addItem("Move"); + systemMenu->addItem("Resize"); + systemMenu->addItem(""); + systemMenu->addItem("Minimize"); + systemMenu->addItem("Maximize"); + systemMenu->addItem("Restore"); + systemMenu->addItem(""); + systemMenu->addItem("Close"); + systemMenu->addActionHandler(this); +} + +template Button::Button(Window *parent, int x, int y, const STR text, int w, int h) : + BorderedWindow(parent,x,y,w,h,6,5,6,5), ActionEventSource(text), pressed(0) +{ + + Label *l = new Label(this,0,0,text); + if (width < 0) resize(l->getWidth()+border_left+border_right+10,height); + if (height < 0) resize(width,l->getHeight()+border_top+border_bottom+6); + l->move((width-border_left-border_right-l->getWidth())/2, + (height-border_top-border_bottom-l->getHeight())/2); +} + +template Checkbox::Checkbox(Window *parent, int x, int y, const STR text, int w, int h) : + BorderedWindow(parent,x,y,w,h,16,0,0,0), ActionEventSource(text), checked(0) +{ + Label *l = new Label(this,0,0,text); + if (width < 0) resize(l->getWidth()+border_left+border_right+4,height); + if (height < 0) resize(width,l->getHeight()+border_top+border_bottom+4); + l->move((width-border_left-border_right-l->getWidth())/2, + (height-border_top-border_bottom-l->getHeight())/2); +} + +template Radiobox::Radiobox(Frame *parent, int x, int y, const STR text, int w, int h) : + BorderedWindow(parent,x,y,w,h,16,0,0,0), ActionEventSource(text), checked(0) +{ + Label *l = new Label(this,0,0,text); + if (width < 0) resize(l->getWidth()+border_left+border_right+4,height); + if (height < 0) resize(width,l->getHeight()+border_top+border_bottom+4); + l->move((width-border_left-border_right-l->getWidth())/2, + (height-border_top-border_bottom-l->getHeight())/2); + addActionHandler(parent); +} + +}; + +#endif From 814a5f92759b5856dc1368fe0b060c05e0c020f6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 28 Oct 2007 16:34:16 +0000 Subject: [PATCH 2939/4131] add gui_tk dir Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3027 --- configure.in | 1 + src/Makefile.am | 2 +- src/libs/Makefile.am | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index d12e026f..b453220f 100644 --- a/configure.in +++ b/configure.in @@ -456,6 +456,7 @@ src/hardware/serialport/Makefile src/ints/Makefile src/libs/Makefile src/libs/zmbv/Makefile +src/libs/gui_tk/Makefile src/misc/Makefile src/shell/Makefile src/platform/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index 870a0db5..2c45ed72 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,7 +11,7 @@ endif 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 hardware/serialport/libserial.a \ + ints/libints.a misc/libmisc.a shell/libshell.a hardware/serialport/libserial.a libs/gui_tk/libgui_tk.a\ $(ico_stuff) EXTRA_DIST = dosbox.rc dosbox.ico diff --git a/src/libs/Makefile.am b/src/libs/Makefile.am index b74bb58a..303bc370 100644 --- a/src/libs/Makefile.am +++ b/src/libs/Makefile.am @@ -1,3 +1,3 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -SUBDIRS = zmbv \ No newline at end of file +SUBDIRS = zmbv gui_tk From c4f26c724bca8d6674d54e53e2bb99029fe725fe Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 28 Oct 2007 16:36:42 +0000 Subject: [PATCH 2940/4131] Add menu to dosbox. V8 from Moe, with some fixes inspired by ykhwong Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3028 --- include/video.h | 1 + src/gui/Makefile.am | 3 +- src/gui/sdl_gui.cpp | 625 +++++++++++++++++++++++++++++++++++++++++ src/gui/sdl_mapper.cpp | 8 +- src/gui/sdlmain.cpp | 43 +-- 5 files changed, 646 insertions(+), 34 deletions(-) create mode 100644 src/gui/sdl_gui.cpp diff --git a/include/video.h b/include/video.h index fab6cfdb..40656bc0 100644 --- a/include/video.h +++ b/include/video.h @@ -65,6 +65,7 @@ void GFX_Stop(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); #if defined (WIN32) bool GFX_SDLUsingWinDIB(void); diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 6efa58f9..d397a92e 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -6,5 +6,6 @@ libgui_a_SOURCES = sdlmain.cpp sdl_mapper.cpp dosbox_logo.h \ render_templates.h render_loops.h render_simple.h \ render_templates_sai.h render_templates_hq.h \ render_templates_hq2x.h render_templates_hq3x.h \ - midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h midi_alsa.h + midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h midi_alsa.h \ + sdl_gui.cpp diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp new file mode 100644 index 00000000..cc745dbc --- /dev/null +++ b/src/gui/sdl_gui.cpp @@ -0,0 +1,625 @@ +/* + * 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: sdl_gui.cpp,v 1.1 2007-10-28 16:36:41 qbix79 Exp $ */ + +#include "SDL.h" +#include "../libs/gui_tk/gui_tk.h" + +#include "dosbox.h" +#include "keyboard.h" +#include "video.h" +#include "render.h" +#include "mapper.h" +#include "setup.h" +#include "shell.h" + +#include +#include +#include +#include +#include +#include + +extern Bit8u int10_font_14[256 * 14]; +extern Program * first_shell; +extern void MSG_Write(const char *); +extern void GFX_SetTitle(Bit32s cycles, Bits frameskip, bool paused); + +static int cursor, saved_bpp; +static int old_unicode; +static bool mousetoggle, running, shell_idle; + +static SDL_Surface *screenshot, *background; + +/* Prepare screen for UI */ +void UI_Init(void) { + GUI::Font::addFont("default",new GUI::BitmapFont(int10_font_14,14,10)); +} + +static void getPixel(Bitu x, Bitu y, int &r, int &g, int &b, int shift) +{ + if (x >= render.src.width) x = render.src.width-1; + if (y >= render.src.height) x = render.src.height-1; + if (x < 0) x = 0; + if (y < 0) y = 0; + + Bit8u* src = (Bit8u *)&scalerSourceCache; + Bit32u pixel; + switch (render.scale.inMode) { + case scalerMode8: + pixel = *(x+(Bit8u*)(src+y*render.scale.cachePitch)); + r += render.pal.rgb[pixel].red >> shift; + g += render.pal.rgb[pixel].green >> shift; + b += render.pal.rgb[pixel].blue >> shift; + break; + case scalerMode15: + pixel = *(x+(Bit16u*)(src+y*render.scale.cachePitch)); + r += (pixel >> (7+shift)) & (0xf8 >> shift); + g += (pixel >> (2+shift)) & (0xf8 >> shift); + b += (pixel << (3-shift)) & (0xf8 >> shift); + break; + case scalerMode16: + pixel = *(x+(Bit16u*)(src+y*render.scale.cachePitch)); + r += (pixel >> (8+shift)) & (0xf8 >> shift); + g += (pixel >> (3+shift)) & (0xfc >> shift); + b += (pixel << (3-shift)) & (0xf8 >> shift); + break; + case scalerMode32: + pixel = *(x+(Bit32u*)(src+y*render.scale.cachePitch)); + r += (pixel >> (16+shift)) & (0xff >> shift); + g += (pixel >> (8+shift)) & (0xff >> shift); + b += (pixel >> shift) & (0xff >> shift); + break; + } +} + +static GUI::ScreenSDL *UI_Startup(GUI::ScreenSDL *screen) { + GFX_EndUpdate(0); + GFX_SetTitle(-1,-1,true); + if(!screen) { //Coming from DOSBox. Clean up the keyboard buffer. + KEYBOARD_ClrBuffer();//Clear buffer + } + MAPPER_LosingFocus();//Release any keys pressed (buffer gets filled again). (could be in above if, but clearing the mapper input when exiting the mapper is sensible as well + SDL_Delay(500); + + // Comparable to the code of intro.com, but not the same! (the code of intro.com is called from within a com file) + shell_idle = first_shell && (DOS_PSP(dos.psp()).GetSegment() == DOS_PSP(dos.psp()).GetParent()); + + int w, h; + bool fs; + GFX_GetSize(w, h, fs); + if (w < 512) w = 640; + if (h < 350) h = 400; + + old_unicode = SDL_EnableUNICODE(1); + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL); + screenshot = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, GUI::Color::RedMask, GUI::Color::GreenMask, GUI::Color::BlueMask, 0); + + // create screenshot for fade effect + int rs = screenshot->format->Rshift, gs = screenshot->format->Gshift, bs = screenshot->format->Bshift, am = GUI::Color::AlphaMask; + for (int y = 0; y < h; y++) { + Bit32u *bg = (Bit32u*)(y*screenshot->pitch + (char*)screenshot->pixels); + for (int x = 0; x < w; x++) { + int r = 0, g = 0, b = 0; + getPixel(x *(int)render.src.width/w, y *(int)render.src.height/h, r, g, b, 0); + bg[x] = r << rs | g << gs | b << bs; + } + } + + background = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, GUI::Color::RedMask, GUI::Color::GreenMask, GUI::Color::BlueMask, GUI::Color::AlphaMask); + // use a blurred and sepia-toned screenshot as menu background + for (int y = 0; y < h; y++) { + Bit32u *bg = (Bit32u*)(y*background->pitch + (char*)background->pixels); + for (int x = 0; x < w; x++) { + int r = 0, g = 0, b = 0; + getPixel(x *(int)render.src.width/w, y *(int)render.src.height/h, r, g, b, 3); + getPixel((x-1)*(int)render.src.width/w, y *(int)render.src.height/h, r, g, b, 3); + getPixel(x *(int)render.src.width/w, (y-1)*(int)render.src.height/h, r, g, b, 3); + getPixel((x-1)*(int)render.src.width/w, (y-1)*(int)render.src.height/h, r, g, b, 3); + getPixel((x+1)*(int)render.src.width/w, y *(int)render.src.height/h, r, g, b, 3); + getPixel(x *(int)render.src.width/w, (y+1)*(int)render.src.height/h, r, g, b, 3); + getPixel((x+1)*(int)render.src.width/w, (y+1)*(int)render.src.height/h, r, g, b, 3); + getPixel((x-1)*(int)render.src.width/w, (y+1)*(int)render.src.height/h, r, g, b, 3); + int r1 = (int)((r * 393 + g * 769 + b * 189) / 1351); + int g1 = (int)((r * 349 + g * 686 + b * 168) / 1203); + int b1 = (int)((r * 272 + g * 534 + b * 131) / 2140); + bg[x] = r1 << rs | g1 << gs | b1 << bs | am; + } + } + + cursor = SDL_ShowCursor(SDL_QUERY); + SDL_ShowCursor(SDL_ENABLE); + + mousetoggle = mouselocked; + if (mouselocked) GFX_CaptureMouse(); + + SDL_Surface* sdlscreen = SDL_SetVideoMode(w, h, 32, SDL_SWSURFACE|(fs?SDL_FULLSCREEN:0)); + if (sdlscreen == NULL) E_Exit("Could not initialize video mode %ix%ix32 for UI: %s", w, h, SDL_GetError()); + + // fade out + SDL_Event event; + for (int i = 0xff; i > 0; i -= 0x11) { + SDL_SetAlpha(screenshot, SDL_SRCALPHA, i); + SDL_BlitSurface(background, NULL, sdlscreen, NULL); + SDL_BlitSurface(screenshot, NULL, sdlscreen, NULL); + SDL_UpdateRect(sdlscreen, 0, 0, 0, 0); + while (SDL_PollEvent(&event)); + SDL_Delay(40); + } + + SDL_BlitSurface(background, NULL, sdlscreen, NULL); + SDL_UpdateRect(sdlscreen, 0, 0, 0, 0); + + if (screen) screen->setSurface(sdlscreen); + else screen = new GUI::ScreenSDL(sdlscreen); + + saved_bpp = render.src.bpp; + render.src.bpp = 0; + running = true; + return screen; +} + +/* Restore screen */ +static void UI_Shutdown(GUI::ScreenSDL *screen) { + SDL_Surface *sdlscreen = screen->getSurface(); + render.src.bpp = saved_bpp; + + // fade in + SDL_Event event; + for (int i = 0x00; i < 0xff; i += 0x11) { + SDL_SetAlpha(screenshot, SDL_SRCALPHA, i); + SDL_BlitSurface(background, NULL, sdlscreen, NULL); + SDL_BlitSurface(screenshot, NULL, sdlscreen, NULL); + SDL_UpdateRect(sdlscreen, 0, 0, 0, 0); + while (SDL_PollEvent(&event)); + SDL_Delay(40); + } + + // clean up + if (mousetoggle) GFX_CaptureMouse(); + SDL_ShowCursor(cursor); + SDL_FreeSurface(background); + SDL_FreeSurface(screenshot); + SDL_FreeSurface(sdlscreen); + screen->setSurface(NULL); + GFX_ResetScreen(); + SDL_EnableUNICODE(old_unicode); + SDL_EnableKeyRepeat(0,0); + GFX_SetTitle(-1,-1,false); +} + +/* helper class for command execution */ +class VirtualBatch : public BatchFile { +protected: + std::istringstream lines; +public: + VirtualBatch(DOS_Shell *host, const std::string& cmds) : BatchFile(host, "CON", ""), lines(cmds) { + } + bool ReadLine(char *line) { + std::string l; + if (!std::getline(lines,l)) { + delete this; + return false; + } + strcpy(line,l.c_str()); + return true; + } +}; + +static void UI_RunCommands(GUI::ScreenSDL *s, const std::string &cmds) { + DOS_Shell temp; + temp.call = true; + UI_Shutdown(s); + temp.bf = new VirtualBatch(&temp, cmds); + temp.RunInternal(); + temp.ShowPrompt(); + UI_Startup(s); +} + + +/* stringification and conversion from the c++ FAQ */ +class BadConversion : public std::runtime_error { +public: BadConversion(const std::string& s) : std::runtime_error(s) { } +}; + +template inline std::string stringify(const T& x, std::ios_base& ( *pf )(std::ios_base&) = NULL) { + std::ostringstream o; + if (pf) o << pf; + if (!(o << x)) throw BadConversion(std::string("stringify(") + typeid(x).name() + ")"); + return o.str(); +} + +template inline void convert(const std::string& s, T& x, bool failIfLeftoverChars = true, std::ios_base& ( *pf )(std::ios_base&) = NULL) { + std::istringstream i(s); + if (pf) i >> pf; + char c; + if (!(i >> x) || (failIfLeftoverChars && i.get(c))) throw BadConversion(s); +} + +/*****************************************************************************************************************************************/ +/* UI classes */ + +class PropertyEditor : public GUI::Window, public GUI::ActionEventSource_Callback { +protected: + Section_prop * section; + Property *prop; +public: + PropertyEditor(Window *parent, int x, int y, Section_prop *section, Property *prop) : + Window(parent, x, y, 240, 30), section(section), prop(prop) { } + + virtual bool prepare(std::string &buffer) = 0; + + void actionExecuted(GUI::ActionEventSource *b, const GUI::String &arg) { + std::string line; + if (prepare(line)) { + if (first_shell) section->ExecuteDestroy(false); + prop->SetValue(GUI::String(line)); + if (first_shell) section->ExecuteInit(false); + } + } +}; + +class PropertyEditorBool : public PropertyEditor { + GUI::Checkbox *input; +public: + PropertyEditorBool(Window *parent, int x, int y, Section_prop *section, Property *prop) : + PropertyEditor(parent, x, y, section, prop) { + input = new GUI::Checkbox(this, 0, 3, prop->propname.c_str()); + input->setChecked(prop->GetValue()._bool); + } + + bool prepare(std::string &buffer) { + if (input->isChecked() == prop->GetValue()._bool) return false; + buffer.append(input->isChecked()?"true":"false"); + return true; + } +}; + +class PropertyEditorString : public PropertyEditor { +protected: + GUI::Input *input; +public: + PropertyEditorString(Window *parent, int x, int y, Section_prop *section, Property *prop) : + PropertyEditor(parent, x, y, section, prop) { + new GUI::Label(this, 0, 5, prop->propname); + input = new GUI::Input(this, 130, 0, 110); + input->setText(prop->GetValue()._string); + } + + bool prepare(std::string &buffer) { + if (input->getText() == GUI::String(prop->GetValue()._string)) return false; + buffer.append((const std::string&)input->getText()); + return true; + } +}; + +class PropertyEditorFloat : public PropertyEditor { +protected: + GUI::Input *input; +public: + PropertyEditorFloat(Window *parent, int x, int y, Section_prop *section, Property *prop) : + PropertyEditor(parent, x, y, section, prop) { + new GUI::Label(this, 0, 5, prop->propname); + input = new GUI::Input(this, 130, 0, 50); + input->setText(stringify(prop->GetValue()._float)); + } + + bool prepare(std::string &buffer) { + float val; + convert(input->getText(), val, false); + if (val == prop->GetValue()._float) return false; + buffer.append(stringify(val)); + return true; + } +}; + +class PropertyEditorHex : public PropertyEditor { +protected: + GUI::Input *input; +public: + PropertyEditorHex(Window *parent, int x, int y, Section_prop *section, Property *prop) : + PropertyEditor(parent, x, y, section, prop) { + new GUI::Label(this, 0, 5, prop->propname); + input = new GUI::Input(this, 130, 0, 50); + input->setText(stringify(prop->GetValue()._hex, std::hex)); + } + + bool prepare(std::string &buffer) { + int val; + convert(input->getText(), val, false, std::hex); + if (val == prop->GetValue()._hex) return false; + buffer.append(stringify(val, std::hex)); + return true; + } +}; + +class PropertyEditorInt : public PropertyEditor { +protected: + GUI::Input *input; +public: + PropertyEditorInt(Window *parent, int x, int y, Section_prop *section, Property *prop) : + PropertyEditor(parent, x, y, section, prop) { + new GUI::Label(this, 0, 5, prop->propname); + input = new GUI::Input(this, 130, 0, 50); + input->setText(stringify(prop->GetValue()._int)); + } + + bool prepare(std::string &buffer) { + int val; + convert(input->getText(), val, false); + if (val == prop->GetValue()._int) return false; + buffer.append(stringify(val)); + return true; + } +}; + +class HelpWindow : public GUI::MessageBox { +public: + HelpWindow(GUI::Screen *parent, int x, int y, Section *section) : + MessageBox(parent, x, y, 580, "", "") { + std::string title(section->GetName()); + title[0] = std::toupper(title[0]); + setTitle("Help for "+title); + std::string name = section->GetName(); + std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))std::toupper); + name += "_CONFIGFILE_HELP"; + setText(MSG_Get(name.c_str())); + } +}; + +class SectionEditor : public GUI::ToplevelWindow { + Section_prop * section; +public: + SectionEditor(GUI::Screen *parent, int x, int y, Section_prop *section) : + ToplevelWindow(parent, x, y, 510, 300, ""), section(section) { + std::string title(section->GetName()); + title[0] = std::toupper(title[0]); + setTitle("Configuration for "+title); + new GUI::Label(this, 5, 10, "Settings:"); + GUI::Button *b = new GUI::Button(this, 120, 220, "Cancel", 70); + b->addActionHandler(this); + b = new GUI::Button(this, 200, 220, "Help", 70); + b->addActionHandler(this); + b = new GUI::Button(this, 280, 220, "OK", 70); + + int i = 0; + Property *prop; + while ((prop = section->Get_prop(i))) { + Prop_bool *pbool = dynamic_cast(prop); + Prop_int *pint = dynamic_cast(prop); + Prop_float *pfloat = dynamic_cast(prop); + Prop_hex *phex = dynamic_cast(prop); + Prop_string *pstring = dynamic_cast(prop); + + PropertyEditor *p; + if (pbool) p = new PropertyEditorBool(this, 5+250*(i/6), 40+(i%6)*30, section, prop); + else if (phex) p = new PropertyEditorHex(this, 5+250*(i/6), 40+(i%6)*30, section, prop); + else if (pint) p = new PropertyEditorInt(this, 5+250*(i/6), 40+(i%6)*30, section, prop); + else if (pfloat) p = new PropertyEditorFloat(this, 5+250*(i/6), 40+(i%6)*30, section, prop); + else if (pstring) p = new PropertyEditorString(this, 5+250*(i/6), 40+(i%6)*30, section, prop); + else { i++; continue; } + b->addActionHandler(p); + i++; + } + b->addActionHandler(this); + } + + void actionExecuted(GUI::ActionEventSource *b, const GUI::String &arg) { + if (arg == "OK" || arg == "Cancel") close(); + else if (arg == "Help") new HelpWindow(static_cast(parent), getX()-10, getY()-10, section); + else ToplevelWindow::actionExecuted(b, arg); + } +}; + +class AutoexecEditor : public GUI::ToplevelWindow { + Section_line * section; + GUI::Input *content; +public: + AutoexecEditor(GUI::Screen *parent, int x, int y, Section_line *section) : + ToplevelWindow(parent, x, y, 450, 300, ""), section(section) { + std::string title(section->GetName()); + title[0] = std::toupper(title[0]); + setTitle("Edit "+title); + new GUI::Label(this, 5, 10, "Content:"); + content = new GUI::Input(this, 5, 30, 420, 185); + content->setText(section->data); + if (first_shell) (new GUI::Button(this, 5, 220, "Append History"))->addActionHandler(this); + if (shell_idle) (new GUI::Button(this, 180, 220, "Execute Now"))->addActionHandler(this); + (new GUI::Button(this, 290, 220, "Cancel", 70))->addActionHandler(this); + (new GUI::Button(this, 360, 220, "OK", 70))->addActionHandler(this); + } + + void actionExecuted(GUI::ActionEventSource *b, const GUI::String &arg) { + if (arg == "OK") section->data = *(std::string*)content->getText(); + if (arg == "OK" || arg == "Cancel") close(); + else if (arg == "Append Shell Commands") { + DOS_Shell *s = static_cast(first_shell); + std::list::reverse_iterator i = s->l_history.rbegin(); + std::string lines = *(std::string*)content->getText(); + while (i != s->l_history.rend()) { + lines += "\n"; + lines += *i; + ++i; + } + content->setText(lines); + } else if (arg == "Execute Now") { + UI_RunCommands(dynamic_cast(getScreen()), content->getText()); + } else ToplevelWindow::actionExecuted(b, arg); + } +}; + +class SaveDialog : public GUI::ToplevelWindow { +protected: + GUI::Input *name; +public: + SaveDialog(GUI::Screen *parent, int x, int y, const char *title) : + ToplevelWindow(parent, x, y, 400, 150, title) { + new GUI::Label(this, 5, 10, "Enter filename for configuration file:"); + name = new GUI::Input(this, 5, 30, 350); + name->setText("dosbox.conf"); + (new GUI::Button(this, 120, 70, "Cancel", 70))->addActionHandler(this); + (new GUI::Button(this, 210, 70, "OK", 70))->addActionHandler(this); + } + + void actionExecuted(GUI::ActionEventSource *b, const GUI::String &arg) { + if (arg == "OK") control->PrintConfig(name->getText()); + close(); + } +}; + +class SaveLangDialog : public GUI::ToplevelWindow { +protected: + GUI::Input *name; +public: + SaveLangDialog(GUI::Screen *parent, int x, int y, const char *title) : + ToplevelWindow(parent, x, y, 400, 150, title) { + new GUI::Label(this, 5, 10, "Enter filename for language file:"); + name = new GUI::Input(this, 5, 30, 350); + name->setText("messages.txt"); + (new GUI::Button(this, 120, 70, "Cancel", 70))->addActionHandler(this); + (new GUI::Button(this, 210, 70, "OK", 70))->addActionHandler(this); + } + + void actionExecuted(GUI::ActionEventSource *b, const GUI::String &arg) { + if (arg == "OK") MSG_Write(name->getText()); + close(); + } +}; + +class ConfigurationWindow : public GUI::ToplevelWindow { +public: + ConfigurationWindow(GUI::Screen *parent, GUI::Size x, GUI::Size y, GUI::String title) : + GUI::ToplevelWindow(parent, x, y, 470, 290, title) { + + (new GUI::Button(this, 180, 215, "Close", 70))->addActionHandler(this); + + GUI::Menubar *bar = new GUI::Menubar(this, 0, 0, getWidth()); + bar->addMenu("Configuration"); + bar->addItem(0,"Save..."); + bar->addItem(0,"Save Language File..."); + bar->addItem(0,""); + bar->addItem(0,"Close"); + bar->addMenu("Settings"); + bar->addMenu("Help"); + bar->addItem(2,"Introduction"); + bar->addItem(2,"Getting Started"); + bar->addItem(2,"CD-ROM Support"); + bar->addItem(2,"Special Keys"); + bar->addItem(2,""); + bar->addItem(2,"About"); + bar->addActionHandler(this); + + new GUI::Label(this, 10, 30, "Choose a settings group to configure:"); + + Section *sec; + int i = 0; + while ((sec = control->GetSection(i))) { + std::string name = sec->GetName(); + name[0] = std::toupper(name[0]); + GUI::Button *b = new GUI::Button(this, 12+(i/5)*160, 50+(i%5)*30, name, 100); + b->addActionHandler(this); + bar->addItem(1, name); + i++; + } + + if (first_shell) { + (new GUI::Button(this, 12+(i/5)*160, 50+(i%5)*30, "Keyboard", 100))->addActionHandler(this); + bar->addItem(1, ""); + bar->addItem(1, "Keyboard"); + } + } + + ~ConfigurationWindow() { running = false; } + + void actionExecuted(GUI::ActionEventSource *b, const GUI::String &arg) { + GUI::String sname = arg; + sname[0] = std::tolower(sname[0]); + Section *sec; + if (arg == "Close" || arg == "Cancel") { + running = false; + } else if (arg == "Keyboard") { + UI_Shutdown(dynamic_cast(getScreen())); + MAPPER_Run(true); + UI_Startup(dynamic_cast(getScreen())); + } else if (sname == "autoexec") { + Section_line *section = static_cast(control->GetSection((const char *)sname)); + new AutoexecEditor(getScreen(), 50, 30, section); + } else if ((sec = control->GetSection((const char *)sname))) { + Section_prop *section = static_cast(sec); + new SectionEditor(getScreen(), 50, 30, section); + } else if (arg == "About") { + new GUI::MessageBox(getScreen(), 200, 150, 280, "About DOSBox", "\nDOSBox 0.72\nAn emulator for old DOS Games\n\nCopyright 2002-2007\nThe DOSBox Team"); + } else if (arg == "Introduction") { + new GUI::MessageBox(getScreen(), 20, 50, 600, "Introduction", MSG_Get("PROGRAM_INTRO")); + } else if (arg == "Getting Started") { + std::string msg = MSG_Get("PROGRAM_INTRO_MOUNT_START"); +#ifdef WIN32 + msg += MSG_Get("PROGRAM_INTRO_MOUNT_WINDOWS"); +#else + msg += MSG_Get("PROGRAM_INTRO_MOUNT_OTHER"); +#endif + msg += MSG_Get("PROGRAM_INTRO_MOUNT_END"); + + new GUI::MessageBox(getScreen(), 20, 50, 600, std::string("Introduction"), msg); + } else if (arg == "CD-ROM Support") { + new GUI::MessageBox(getScreen(), 20, 50, 600, "Introduction", MSG_Get("PROGRAM_INTRO_CDROM")); + } else if (arg == "Special Keys") { + new GUI::MessageBox(getScreen(), 20, 50, 600, "Introduction", MSG_Get("PROGRAM_INTRO_SPECIAL")); + } else if (arg == "Save...") { + new SaveDialog(getScreen(), 90, 100, "Save Configuration..."); + } else if (arg == "Save Language File...") { + new SaveLangDialog(getScreen(), 90, 100, "Save Language File..."); + } else { + return ToplevelWindow::actionExecuted(b, arg); + } + } +}; + +/*********************************************************************************************************************/ +/* UI control functions */ + +static void UI_Execute(GUI::ScreenSDL *screen) { + SDL_Surface *sdlscreen = screen->getSurface(); + new ConfigurationWindow(screen, 30, 30, "DOSBox Configuration"); + + // event loop + SDL_Event event; + while (running) { + while (SDL_PollEvent(&event)) { + if (!screen->event(event)) { + if (event.type == SDL_QUIT) running = false; + } + } + //Selecting keyboard will create a new surface. + sdlscreen = screen->getSurface(); + SDL_BlitSurface(background, NULL, sdlscreen, NULL); + screen->update(4); + SDL_UpdateRect(sdlscreen, 0, 0, 0, 0); + + SDL_Delay(40); + } +} + +void UI_Run(bool pressed) { + if (pressed) return; + GUI::ScreenSDL *screen = UI_Startup(NULL); + UI_Execute(screen); + UI_Shutdown(screen); + delete screen; +} diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 909382c4..6462aa8a 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.44 2007-08-17 18:49:56 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.45 2007-10-28 16:36:41 qbix79 Exp $ */ #include #include @@ -2229,7 +2229,9 @@ void MAPPER_Run(bool pressed) { for (CEventVector_it evit=events.begin();evit!=events.end();evit++) { (*evit)->DeActivateAll(); } - + + int cursor = SDL_ShowCursor(SDL_QUERY); + SDL_ShowCursor(SDL_ENABLE); bool mousetoggle=false; if(mouselocked) { mousetoggle=true; @@ -2266,6 +2268,7 @@ void MAPPER_Run(bool pressed) { SDL_JoystickEventState(SDL_DISABLE); #endif if(mousetoggle) GFX_CaptureMouse(); + SDL_ShowCursor(cursor); GFX_ResetScreen(); } @@ -2364,6 +2367,5 @@ void MAPPER_StartUp(Section * sec) { } mapper.filename=section->Get_string("mapperfile"); - MAPPER_AddHandler(&MAPPER_Run,MK_f1,MMOD1,"mapper","Mapper"); } diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index abf6d134..de7f6ec9 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.134 2007-08-26 18:03:25 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.135 2007-10-28 16:36:42 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -238,32 +238,6 @@ void GFX_SetTitle(Bit32s cycles,Bits frameskip,bool paused){ SDL_WM_SetCaption(title,VERSION); } -static void PauseDOSBox(bool pressed) { - if (!pressed) - return; - GFX_SetTitle(-1,-1,true); - bool paused = true; - KEYBOARD_ClrBuffer(); - SDL_Delay(500); - SDL_Event event; - while (SDL_PollEvent(&event)) { - // flush event queue. - } - while (paused) { - SDL_WaitEvent(&event); // since we're not polling, cpu usage drops to 0. - switch (event.type) { - case SDL_QUIT: throw(0); break; - case SDL_KEYDOWN: // Must use Pause/Break Key to resume. - case SDL_KEYUP: - if(event.key.keysym.sym==SDLK_PAUSE){ - paused=false; - GFX_SetTitle(-1,-1,false); - break; - } - } - } -} - #if defined (WIN32) bool GFX_SDLUsingWinDIB(void) { return sdl.using_windib; @@ -942,6 +916,7 @@ static unsigned char logo[32*32*4]= { #include "dosbox_logo.h" }; +extern void UI_Run(bool); static void GUI_StartUp(Section * sec) { sec->AddDestroyFunction(&GUI_ShutDown); Section_prop * section=static_cast(sec); @@ -1131,7 +1106,7 @@ static void GUI_StartUp(Section * sec) { #if C_DEBUG /* Pause binds with activate-debugger */ #else - MAPPER_AddHandler(PauseDOSBox,MK_pause,MMOD2,"pause","Pause"); + MAPPER_AddHandler(&UI_Run, MK_pause, MMOD2, "ui", "UI"); #endif /* Get Keyboard state of numlock and capslock */ SDLMod keystate = SDL_GetModState(); @@ -1345,6 +1320,8 @@ void GFX_ShowMsg(char const* format,...) { if(!no_stdout) printf(buf); }; +extern void UI_Init(void); + int main(int argc, char* argv[]) { try { CommandLine com_line(argc,argv); @@ -1503,6 +1480,8 @@ int main(int argc, char* argv[]) { #if (ENVIRON_LINKED) control->ParseEnv(environ); #endif + UI_Init(); + if (control->cmdline->FindExist("-startui")) UI_Run(false); /* Init all the sections */ control->Init(); /* Some extra SDL Functions */ @@ -1514,8 +1493,6 @@ int main(int argc, char* argv[]) { /* Init the keyMapper */ MAPPER_Init(); - if (control->cmdline->FindExist("-startmapper")) MAPPER_Run(true); - /* Start up main machine */ control->StartUp(); /* Shutdown everything */ @@ -1543,3 +1520,9 @@ int main(int argc, char* argv[]) { SDL_Quit();//Let's hope sdl will quit as well when it catches an exception return 0; }; + +void GFX_GetSize(int &width, int &height, bool &fullscreen) { + width = sdl.draw.width; + height = sdl.draw.height; + fullscreen = sdl.desktop.fullscreen; +} From e2b114bfe48128ee1536fb7d48dbb5ed1b293a68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 28 Oct 2007 17:05:29 +0000 Subject: [PATCH 2941/4131] update visual studio files Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3029 --- src/libs/gui_tk/gui_tk.cpp | 10 +++++----- visualc_net/dosbox.vcproj | 6 ++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/libs/gui_tk/gui_tk.cpp b/src/libs/gui_tk/gui_tk.cpp index 8cbe59d6..d90524e4 100644 --- a/src/libs/gui_tk/gui_tk.cpp +++ b/src/libs/gui_tk/gui_tk.cpp @@ -19,7 +19,7 @@ /* TODO: - make menu a bufferedwindow with shadow */ -/* $Id: gui_tk.cpp,v 1.1 2007-10-28 16:33:02 qbix79 Exp $ */ +/* $Id: gui_tk.cpp,v 1.2 2007-10-28 17:05:28 c2woody Exp $ */ /** \file * \brief Implementation file for gui_tk. @@ -1423,10 +1423,10 @@ static const Key SDL_to_GUI(const SDL_keysym &key) default: break; } return Key(key.unicode, ksym, - key.mod&KMOD_SHIFT, - key.mod&KMOD_CTRL, - key.mod&KMOD_ALT, - key.mod&KMOD_META); + (key.mod&KMOD_SHIFT)>0, + (key.mod&KMOD_CTRL)>0, + (key.mod&KMOD_ALT)>0, + (key.mod&KMOD_META)>0); } /** \brief Internal class that handles different screen bit depths and layouts the SDL way */ diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 1e81c5e0..a98b5210 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -628,12 +628,18 @@ + + + + Date: Wed, 31 Oct 2007 11:37:38 +0000 Subject: [PATCH 2942/4131] Fix PropertyEditorString when compiling with g++ 3.4. (name the wanted explicitly) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3030 --- src/gui/sdl_gui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index cc745dbc..e91d4154 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_gui.cpp,v 1.1 2007-10-28 16:36:41 qbix79 Exp $ */ +/* $Id: sdl_gui.cpp,v 1.2 2007-10-31 11:37:38 qbix79 Exp $ */ #include "SDL.h" #include "../libs/gui_tk/gui_tk.h" @@ -304,7 +304,7 @@ public: bool prepare(std::string &buffer) { if (input->getText() == GUI::String(prop->GetValue()._string)) return false; - buffer.append((const std::string&)input->getText()); + buffer.append(static_cast(input->getText())); return true; } }; From 6182b08be9c3c74790bb2db933aeddd90c3ff5e6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 31 Oct 2007 11:45:14 +0000 Subject: [PATCH 2943/4131] Make some visual C compiler happy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3031 --- src/gui/sdl_mapper.cpp | 4 ++-- src/misc/support.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 6462aa8a..84906fdf 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.45 2007-10-28 16:36:41 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.46 2007-10-31 11:43:06 qbix79 Exp $ */ #include #include @@ -1217,7 +1217,7 @@ protected: Bit16u button_state; }; -static struct { +static struct CMapper { SDL_Surface * surface; SDL_Surface * draw_surface; bool exit; diff --git a/src/misc/support.cpp b/src/misc/support.cpp index cdb3ee27..f51ad77b 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.32 2007-06-12 20:22:09 c2woody Exp $ */ +/* $Id: support.cpp,v 1.33 2007-10-31 11:45:14 qbix79 Exp $ */ #include #include @@ -102,7 +102,7 @@ char * StripWord(char *&line) { } } char * begin=scan; - for (;char c=*scan;scan++) { + for (char c = *scan ;(c = *scan);scan++) { if (isspace(*reinterpret_cast(&c))) { *scan++=0; break; From 1b2e2b541ebf0af548b50b1f463c3379b82a67a1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 1 Nov 2007 12:11:40 +0000 Subject: [PATCH 2944/4131] Silence a warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3032 --- src/hardware/ipx.cpp | 4 ++-- src/hardware/serialport/softmodem.cpp | 4 ++-- src/ints/ems.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index ccedba14..bbc6aecd 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.cpp,v 1.13 2007-02-22 08:30:47 qbix79 Exp $ */ +/* $Id: ipx.cpp,v 1.14 2007-11-01 12:11:40 qbix79 Exp $ */ #include "dosbox.h" @@ -748,7 +748,7 @@ static bool pingCheck(IPXHeader * outHeader) { return false; } -bool ConnectToServer(char *strAddr) { +bool ConnectToServer(char const *strAddr) { int numsent; UDPpacket regPacket; IPXHeader regHeader; diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index 1b08c4f6..d5aad515 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.cpp,v 1.8 2007-07-19 18:58:39 c2woody Exp $ */ +/* $Id: softmodem.cpp,v 1.9 2007-11-01 12:11:40 qbix79 Exp $ */ #include "dosbox.h" @@ -139,7 +139,7 @@ void CSerialModem::SendNumber(Bitu val) { } void CSerialModem::SendRes(ResTypes response) { - char * string;Bitu code; + char const * string;Bitu code; switch (response) { case ResNONE: return; diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 8e8fe04f..3ea702ce 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.55 2007-01-08 22:04:20 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.56 2007-11-01 12:11:40 qbix79 Exp $ */ #include #include @@ -1235,7 +1235,7 @@ public: DOS_AddDevice(newdev); /* Add a little hack so it appears that there is an actual ems device installed */ - char * emsname="EMMXXXX0"; + char const* emsname="EMMXXXX0"; if(!emsnameseg) emsnameseg=DOS_GetMemory(2); //We have 32 bytes MEM_BlockWrite(PhysMake(emsnameseg,0xa),emsname,strlen(emsname)+1); From ac66214dabe0d7bf5ea720a1ff47e5185f3f102c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 1 Nov 2007 12:15:34 +0000 Subject: [PATCH 2945/4131] Emulate a trailing dot on volume labels of 8 characters when on a cdrom drive. mscdex weirdness. Fixes Fifa96 cdrom detection. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3033 --- include/dos_system.h | 4 ++-- src/dos/dos_programs.cpp | 11 ++++----- src/dos/drive_cache.cpp | 24 +++----------------- src/dos/drive_iso.cpp | 48 ++++------------------------------------ src/dos/drive_local.cpp | 8 +++---- src/dos/drives.cpp | 30 +++++++++++++++++++++++++ src/dos/drives.h | 3 ++- 7 files changed, 51 insertions(+), 77 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index dfb8638f..30c047a0 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.40 2007-06-13 07:25:14 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.41 2007-11-01 12:15:34 qbix79 Exp $ */ #ifndef DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H @@ -148,7 +148,7 @@ public: void DeleteEntry (const char* path, bool ignoreLastDir = false); void EmptyCache (void); - void SetLabel (const char* name,bool allowupdate=true); + void SetLabel (const char* name,bool cdrom,bool allowupdate); char* GetLabel (void) { return label; }; class CFileInfo { diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 108230ab..900b225c 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.78 2007-10-14 17:31:52 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.79 2007-11-01 12:15:34 qbix79 Exp $ */ #include "dosbox.h" #include @@ -128,6 +128,7 @@ public: std::string type="dir"; cmd->FindString("-t",type,true); + bool iscdrom = (type =="cdrom"); //Used for mscdex bug cdrom label name emulation if (type=="floppy" || type=="dir" || type=="cdrom") { Bit16u sizes[4]; Bit8u mediaid; @@ -297,16 +298,16 @@ public: mem_writeb(Real2Phys(dos.tables.mediaid)+(drive-'A')*2,newdrive->GetMediaByte()); WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,newdrive->GetInfo()); /* check if volume label is given and don't allow it to updated in the future */ - if (cmd->FindString("-label",label,true)) newdrive->dirCache.SetLabel(label.c_str(),false); + if (cmd->FindString("-label",label,true)) newdrive->dirCache.SetLabel(label.c_str(),iscdrom,false); /* For hard drives set the label to DRIVELETTER_Drive. * For floppy drives set the label to DRIVELETTER_Floppy. * This way every drive except cdroms should get a label.*/ else if(type == "dir") { label = drive; label += "_DRIVE"; - newdrive->dirCache.SetLabel(label.c_str(),true); + newdrive->dirCache.SetLabel(label.c_str(),iscdrom,true); } else if(type == "floppy") { label = drive; label += "_FLOPPY"; - newdrive->dirCache.SetLabel(label.c_str(),true); + newdrive->dirCache.SetLabel(label.c_str(),iscdrom,true); } return; showusage: @@ -1179,7 +1180,7 @@ public: WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MOUNT_NUMBER"),drive-'0',temp_line.c_str()); } - // check if volume label is given + // check if volume label is given. becareful for cdrom //if (cmd->FindString("-label",label,true)) newdrive->dirCache.SetLabel(label.c_str()); return; } diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index be28b824..440df5b0 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.50 2007-06-12 20:22:08 c2woody Exp $ */ +/* $Id: drive_cache.cpp,v 1.51 2007-11-01 12:15:34 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -115,7 +115,7 @@ void DOS_Drive_Cache::EmptyCache(void) SetBaseDir(basePath); }; -void DOS_Drive_Cache::SetLabel(const char* vname,bool allowupdate) +void DOS_Drive_Cache::SetLabel(const char* vname,bool cdrom,bool allowupdate) { /* allowupdate defaults to true. if mount sets a label then allowupdate is * false and will this function return at once after the first call. @@ -123,25 +123,7 @@ void DOS_Drive_Cache::SetLabel(const char* vname,bool allowupdate) if(!this->updatelabel) return; this->updatelabel = allowupdate; - Bitu togo = 8; - Bitu vnamePos = 0; - Bitu labelPos = 0; - bool point = false; - while (togo>0) { - if (vname[vnamePos]==0) break; - if (!point && (vname[vnamePos]=='.')) { togo=4; point=true; } - label[labelPos] = toupper(vname[vnamePos]); - labelPos++; vnamePos++; - togo--; - if ((togo==0) && !point) { - if (vname[vnamePos]=='.') vnamePos++; - label[labelPos]='.'; labelPos++; point=true; togo=3; - } - }; - label[labelPos]=0; - //Remove trailing dot. - if((labelPos > 0) && (label[labelPos-1] == '.')) - label[labelPos-1]=0; + Set_Label(vname,label,cdrom); LOG(LOG_DOSMISC,LOG_NORMAL)("DIRCACHE: Set volume label to %s",label); }; diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index b339e003..4acc006d 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.21 2007-08-22 11:54:35 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.22 2007-11-01 12:15:34 qbix79 Exp $ */ #include #include @@ -161,56 +161,16 @@ isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &e this->mediaid = mediaid; char buffer[32] = { 0 }; if (!MSCDEX_GetVolumeName(subUnit, buffer)) strcpy(buffer, ""); + Set_Label(buffer,discLabel,true); - //Code Copied from drive_cache. (convert mscdex label to a dos 8.3 file) - Bitu togo = 8; - Bitu bufPos = 0; - Bitu labelPos = 0; - bool point = false; - while (togo>0) { - if (buffer[bufPos]==0) break; - if (!point && (buffer[bufPos]=='.')) { togo=4; point=true; } - discLabel[labelPos] = toupper(buffer[bufPos]); - labelPos++; bufPos++; - togo--; - if ((togo==0) && !point) { - if (buffer[bufPos]=='.') bufPos++; - discLabel[labelPos]='.'; labelPos++; point=true; togo=3; - } - }; - discLabel[labelPos]=0; - //Remove trailing dot. - if((labelPos > 0) && (discLabel[labelPos - 1] == '.')) - discLabel[labelPos - 1] = 0; } else if (CDROM_Interface_Image::images[subUnit]->HasDataTrack() == false) { //Audio only cdrom strcpy(info, "isoDrive "); strcat(info, fileName); this->driveLetter = driveLetter; this->mediaid = mediaid; char buffer[32] = { 0 }; - strcpy(buffer, "Audio CD"); - - //Code Copied from drive_cache. (convert mscdex label to a dos 8.3 file) - Bitu togo = 8; - Bitu bufPos = 0; - Bitu labelPos = 0; - bool point = false; - while (togo>0) { - if (buffer[bufPos]==0) break; - if (!point && (buffer[bufPos]=='.')) { togo=4; point=true; } - discLabel[labelPos] = toupper(buffer[bufPos]); - labelPos++; bufPos++; - togo--; - if ((togo==0) && !point) { - if (buffer[bufPos]=='.') bufPos++; - discLabel[labelPos]='.'; labelPos++; point=true; togo=3; - } - }; - discLabel[labelPos]=0; - //Remove trailing dot. - if((labelPos > 0) && (discLabel[labelPos - 1] == '.')) - discLabel[labelPos - 1] = 0; - + strcpy(buffer, "Audio_CD"); + Set_Label(buffer,discLabel,true); } else error = 6; //Corrupt image } } diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index aa93af5d..117de89d 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.75 2007-06-13 07:25:14 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.76 2007-11-01 12:15:34 qbix79 Exp $ */ #include #include @@ -565,7 +565,7 @@ cdromDrive::cdromDrive(const char driveLetter, const char * startdir,Bit16u _byt this->driveLetter = driveLetter; // Get Volume Label char name[32]; - if (MSCDEX_GetVolumeName(subUnit,name)) dirCache.SetLabel(name); + if (MSCDEX_GetVolumeName(subUnit,name)) dirCache.SetLabel(name,true,true); }; bool cdromDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) @@ -625,7 +625,7 @@ bool cdromDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) dirCache.EmptyCache(); // Get Volume Label char name[32]; - if (MSCDEX_GetVolumeName(subUnit,name)) dirCache.SetLabel(name); + if (MSCDEX_GetVolumeName(subUnit,name)) dirCache.SetLabel(name,true,true); } return localDrive::FindFirst(_dir,dta); }; @@ -637,7 +637,7 @@ void cdromDrive::SetDir(const char* path) dirCache.EmptyCache(); // Get Volume Label char name[32]; - if (MSCDEX_GetVolumeName(subUnit,name)) dirCache.SetLabel(name); + if (MSCDEX_GetVolumeName(subUnit,name)) dirCache.SetLabel(name,true,true); } localDrive::SetDir(path); }; diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index fa5f50fc..aacb0e26 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: drives.cpp,v 1.12 2007-11-01 12:15:34 qbix79 Exp $ */ + #include "dosbox.h" #include "dos_system.h" #include "drives.h" @@ -73,6 +75,34 @@ checkext: return true; } +void Set_Label(char const * const input, char * const output, bool cdrom) { + Bitu togo = 8; + Bitu vnamePos = 0; + Bitu labelPos = 0; + bool point = false; + + //spacepadding the filenamepart to include spaces after the terminating zero is more closely to the specs. (not doing this now) + // HELLO\0' '' ' + + while (togo > 0) { + if (input[vnamePos]==0) break; + if (!point && (input[vnamePos]=='.')) { togo=4; point=true; } + + output[labelPos] = toupper(input[vnamePos]); + labelPos++; vnamePos++; + togo--; + if ((togo==0) && !point) { + if (input[vnamePos]=='.') vnamePos++; + output[labelPos]='.'; labelPos++; point=true; togo=3; + } + }; + output[labelPos]=0; + + //Remove trailing dot. except when on cdrom and filename is exactly 8 (9 including the dot) letters. MSCDEX feature/bug (fifa96 cdrom detection) + if((labelPos > 0) && (output[labelPos-1] == '.') && !(cdrom && labelPos ==9)) + output[labelPos-1] = 0; +} + DOS_Drive::DOS_Drive() { diff --git a/src/dos/drives.h b/src/dos/drives.h index b80e1ac2..c6febda2 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.38 2007-08-22 11:54:35 qbix79 Exp $ */ +/* $Id: drives.h,v 1.39 2007-11-01 12:15:34 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ @@ -28,6 +28,7 @@ #include "bios.h" /* for fatDrive */ bool WildFileCmp(const char * file, const char * wild); +void Set_Label(char const * const input, char * const output, bool cdrom); class DriveManager { public: From f80641c10f9c30fed273e951cf9d8077701e9cc6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 Nov 2007 07:50:27 +0000 Subject: [PATCH 2946/4131] Fix compilation under win32 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3034 --- src/dos/drive_cache.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 440df5b0..d2d6fc5b 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.51 2007-11-01 12:15:34 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.52 2007-11-02 07:50:27 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -144,12 +144,16 @@ void DOS_Drive_Cache::SetBaseDir(const char* baseDir) }; // Get Volume Label #if defined (WIN32) || defined (OS2) + bool cdrom = false; char labellocal[256]={ 0 }; char drive[4] = "C:\\"; drive[0] = basePath[0]; #if defined (WIN32) if (GetVolumeInformation(drive,labellocal,256,NULL,NULL,NULL,NULL,0)) { + UINT test = GetDriveType(drive); + if(test == DRIVE_CDROM) cdrom = true; #else // OS2 + //TODO determine wether cdrom or not! FSINFO fsinfo; ULONG drivenumber = drive[0]; if (drivenumber > 26) { // drive letter was lowercase @@ -159,7 +163,7 @@ void DOS_Drive_Cache::SetBaseDir(const char* baseDir) if (rc == NO_ERROR) { #endif /* Set label and allow being updated */ - SetLabel(labellocal,true); + SetLabel(labellocal,cdrom,true); } #endif }; From 53d14892a534b297c0f1029b5d0e2d5b27f15fbb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 Nov 2007 08:48:30 +0000 Subject: [PATCH 2947/4131] Make some ancient compiler happy. The breaking up makes little sense anyway Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3035 --- src/platform/visualc/ntddscsi.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/platform/visualc/ntddscsi.h b/src/platform/visualc/ntddscsi.h index 8342c23e..e0713246 100644 --- a/src/platform/visualc/ntddscsi.h +++ b/src/platform/visualc/ntddscsi.h @@ -62,11 +62,9 @@ extern "C" { CTL_CODE(IOCTL_SCSI_BASE, 0x0407, METHOD_BUFFERED, FILE_ANY_ACCESS) -DEFINE_GUID(ScsiRawInterfaceGuid, \ - 0x53f56309L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); +DEFINE_GUID(ScsiRawInterfaceGuid, 0x53f56309L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); -DEFINE_GUID(WmiScsiAddressGuid, \ - 0x53f5630fL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); +DEFINE_GUID(WmiScsiAddressGuid, 0x53f5630fL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); typedef struct _SCSI_PASS_THROUGH { USHORT Length; From eea273f2a960cc50a83ecd87a785fd048cc34af6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 3 Nov 2007 17:20:29 +0000 Subject: [PATCH 2948/4131] better not write the 2nd fat into the root directory (fs fat, fixes rare directory corruptions); add rename for disk images Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3036 --- src/dos/drive_fat.cpp | 59 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 5ecf09c2..ce411649 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.22 2007-06-14 08:23:46 qbix79 Exp $ */ +/* $Id: drive_fat.cpp,v 1.23 2007-11-03 17:20:29 c2woody Exp $ */ #include #include @@ -300,7 +300,8 @@ Bit32u fatDrive::getClusterValue(Bit32u clustNum) { if(curFatSect != fatsectnum) { /* Load two sectors at once for FAT12 */ loadedDisk->Read_AbsoluteSector(fatsectnum, &fatSectBuffer[0]); - loadedDisk->Read_AbsoluteSector(fatsectnum+1, &fatSectBuffer[512]); + if (fattype==FAT12) + loadedDisk->Read_AbsoluteSector(fatsectnum+1, &fatSectBuffer[512]); curFatSect = fatsectnum; } @@ -346,7 +347,8 @@ void fatDrive::setClusterValue(Bit32u clustNum, Bit32u clustValue) { if(curFatSect != fatsectnum) { /* Load two sectors at once for FAT12 */ loadedDisk->Read_AbsoluteSector(fatsectnum, &fatSectBuffer[0]); - loadedDisk->Read_AbsoluteSector(fatsectnum+1, &fatSectBuffer[512]); + if (fattype==FAT12) + loadedDisk->Read_AbsoluteSector(fatsectnum+1, &fatSectBuffer[512]); curFatSect = fatsectnum; } @@ -374,10 +376,12 @@ void fatDrive::setClusterValue(Bit32u clustNum, Bit32u clustValue) { *((Bit32u *)&fatSectBuffer[fatentoff]) = clustValue; break; } - int fc; - for(fc=0;fcWrite_AbsoluteSector(fatsectnum + (fc * bootbuffer.sectorsperfat), &fatSectBuffer[0]); - loadedDisk->Write_AbsoluteSector(fatsectnum+1+(fc * bootbuffer.sectorsperfat), &fatSectBuffer[512]); + if (fattype==FAT12) { + if (fatentoff>=511) + loadedDisk->Write_AbsoluteSector(fatsectnum+1+(fc * bootbuffer.sectorsperfat), &fatSectBuffer[512]); + } } } @@ -982,9 +986,9 @@ bool fatDrive::directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s Bit32u entryoffset = 0; /* Index offset within sector */ Bit32u tmpsector; Bit16u dirPos = 0; - + while(entNum>=0) { - + logentsector = dirPos / 16; entryoffset = dirPos % 16; @@ -1005,7 +1009,7 @@ bool fatDrive::directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s if (sectbuf[entryoffset].entryname[0] == 0x00) return false; --entNum; } - + memcpy(useEntry, §buf[entryoffset],sizeof(direntry)); return true; } @@ -1206,7 +1210,42 @@ bool fatDrive::RemoveDir(char *dir) { return true; } -bool fatDrive::Rename(char * /*oldname*/, char * /*newname*/) { +bool fatDrive::Rename(char * oldname, char * newname) { + direntry fileEntry1; + Bit32u dirClust1, subEntry1; + if(!getFileDirEntry(oldname, &fileEntry1, &dirClust1, &subEntry1)) return false; + /* File to be renamed really exists */ + + direntry fileEntry2; + Bit32u dirClust2, subEntry2; + + /* Check if file already exists */ + if(!getFileDirEntry(newname, &fileEntry2, &dirClust2, &subEntry2)) { + /* Target doesn't exist, can rename */ + + char dirName2[DOS_NAMELENGTH_ASCII]; + char pathName2[11]; + /* Can we even get the name of the file itself? */ + if(!getEntryName(newname, &dirName2[0])) return false; + convToDirFile(&dirName2[0], &pathName2[0]); + + /* Can we find the base directory? */ + if(!getDirClustNum(newname, &dirClust2, true)) return false; + memcpy(&fileEntry2, &fileEntry1, sizeof(direntry)); + memcpy(&fileEntry2.entryname, &pathName2[0], 11); + addDirectoryEntry(dirClust2, fileEntry2); + + /* Check if file exists now */ + if(!getFileDirEntry(newname, &fileEntry2, &dirClust2, &subEntry2)) return false; + + /* Remove old entry */ + fileEntry1.entryname[0] = 0xe5; + directoryChange(dirClust1, &fileEntry1, subEntry1); + + return true; + } + + /* Target already exists, fail */ return false; } From 92ad22418c3689b897e97ad0c6d36e12a3d1d48f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 4 Nov 2007 11:11:34 +0000 Subject: [PATCH 2949/4131] minor fix for get/set file attribute Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3037 --- src/dos/dos.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index d81a38c9..872d6a86 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.104 2007-07-27 19:17:23 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.105 2007-11-04 11:11:34 c2woody Exp $ */ #include #include @@ -579,9 +579,8 @@ static Bitu DOS_21Handler(void) { } case 0x43: /* Get/Set file attributes */ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); - switch (reg_al) + switch (reg_al) { case 0x00: /* Get */ - { if (DOS_GetFileAttr(name1,®_cx)) { reg_ax=reg_cx; /* Undocumented */ CALLBACK_SCF(false); @@ -601,7 +600,8 @@ static Bitu DOS_21Handler(void) { break; default: LOG(LOG_MISC,LOG_ERROR)("DOS:0x43:Illegal subfunction %2X",reg_al); - CALLBACK_SCF(false); + reg_ax=1; + CALLBACK_SCF(true); break; } break; From 3e1301347fc568a3fd5b3587a8f0f0b3166f9574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 4 Nov 2007 19:14:32 +0000 Subject: [PATCH 2950/4131] fix some potential overflows Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3038 --- src/misc/programs.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 452d16df..4fd87fbf 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.28 2007-06-12 20:22:09 c2woody Exp $ */ +/* $Id: programs.cpp,v 1.29 2007-11-04 19:14:32 c2woody Exp $ */ #include #include @@ -101,7 +101,7 @@ Program::Program() { MEM_BlockRead(PhysMake(dos.psp(),128),&tail,128); if (tail.count<127) tail.buffer[tail.count]=0; else tail.buffer[126]=0; - char filename[256]; + char filename[256+1]; MEM_StrCopy(envscan,filename,256); cmd = new CommandLine(filename,tail.buffer); } @@ -122,7 +122,7 @@ void Program::WriteOut(const char * format,...) { bool Program::GetEnvStr(const char * entry,std::string & result) { /* Walk through the internal environment and see for a match */ PhysPt env_read=PhysMake(psp->GetEnvironment(),0); - char env_string[1024]; + char env_string[1024+1]; result.erase(); if (!entry[0]) return false; do { @@ -144,7 +144,7 @@ bool Program::GetEnvStr(const char * entry,std::string & result) { }; bool Program::GetEnvNum(Bitu num,std::string & result) { - char env_string[1024]; + char env_string[1024+1]; PhysPt env_read=PhysMake(psp->GetEnvironment(),0); do { MEM_StrCopy(env_read,env_string,1024); @@ -170,7 +170,7 @@ Bitu Program::GetEnvCount(void) { bool Program::SetEnv(const char * entry,const char * new_string) { PhysPt env_read=PhysMake(psp->GetEnvironment(),0); PhysPt env_write=env_read; - char env_string[1024]; + char env_string[1024+1]; do { MEM_StrCopy(env_read,env_string,1024); if (!env_string[0]) break; From adf02d82dfa76ea373ba910e47fd2bd8373845d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 5 Nov 2007 17:49:17 +0000 Subject: [PATCH 2951/4131] mouse completely ignores vesa modes (fixes Waterworld and others); reset less mouse parameters on mode switches Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3039 --- src/ints/mouse.cpp | 143 +++++++++++++++++++++------------------------ 1 file changed, 67 insertions(+), 76 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 4056fe86..a95c7116 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.69 2007-06-12 20:22:09 c2woody Exp $ */ +/* $Id: mouse.cpp,v 1.70 2007-11-05 17:49:17 c2woody Exp $ */ #include #include @@ -86,7 +86,7 @@ static struct { Bit16u last_released_y[MOUSE_BUTTONS]; Bit16u last_pressed_x[MOUSE_BUTTONS]; Bit16u last_pressed_y[MOUSE_BUTTONS]; - Bit16u shown; + Bit16u hidden; float add_x,add_y; Bit16u min_x,max_x,min_y,max_y; float mickey_x,mickey_y; @@ -109,6 +109,9 @@ static struct { float mickeysPerPixel_y; float pixelPerMickey_x; float pixelPerMickey_y; + Bit16u senv_x_val; + Bit16u senv_y_val; + Bit16u dspeed_val; float senv_x; float senv_y; Bit16u updateRegion_x[2]; @@ -116,10 +119,10 @@ static struct { Bit16u doubleSpeedThreshold; Bit16u language; Bit16u cursorType; - Bit16u oldshown; + Bit16u oldhidden; Bit8u page; bool enabled; - + bool inhibit_draw; } mouse; bool Mouse_SetPS2State(bool use) { @@ -214,9 +217,8 @@ INLINE void Mouse_AddEvent(Bit16u type) { extern void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useattr); extern void ReadCharAttr(Bit16u col,Bit16u row,Bit8u page,Bit16u * result); -void RestoreCursorBackgroundText() -{ - if (mouse.shown) return; +void RestoreCursorBackgroundText() { + if (mouse.hidden || mouse.inhibit_draw) return; if (mouse.background) { WriteChar(mouse.backposx,mouse.backposy,0,mouse.backData[0],mouse.backData[1],true); @@ -224,8 +226,7 @@ void RestoreCursorBackgroundText() } }; -void DrawCursorText() -{ +void DrawCursorText() { // Restore Background RestoreCursorBackgroundText(); @@ -250,8 +251,7 @@ void DrawCursorText() static Bit8u gfxReg3CE[9]; static Bit8u index3C4,gfxReg3C5; -void SaveVgaRegisters() -{ +void SaveVgaRegisters() { for (int i=0; i<9; i++) { IO_Write (0x3CE,i); gfxReg3CE[i] = IO_Read(0x3CF); @@ -265,8 +265,7 @@ void SaveVgaRegisters() gfxReg3C5 = IO_Read(0x3C5); IO_Write(0x3C5,0xF); } -void RestoreVgaRegisters() -{ +void RestoreVgaRegisters() { for (int i=0; i<9; i++) { IO_Write(0x3CE,i); IO_Write(0x3CF,gfxReg3CE[i]); @@ -277,8 +276,8 @@ void RestoreVgaRegisters() IO_Write(0x3C4,index3C4); } -void ClipCursorArea(Bit16s& x1, Bit16s& x2, Bit16s& y1, Bit16s& y2, Bit16u& addx1, Bit16u& addx2, Bit16u& addy) -{ +void ClipCursorArea(Bit16s& x1, Bit16s& x2, Bit16s& y1, Bit16s& y2, + Bit16u& addx1, Bit16u& addx2, Bit16u& addy) { addx1 = addx2 = addy = 0; // Clip up if (y1<0) { @@ -301,9 +300,8 @@ void ClipCursorArea(Bit16s& x1, Bit16s& x2, Bit16s& y1, Bit16s& y2, Bit16u& addx }; }; -void RestoreCursorBackground() -{ - if (mouse.shown) return; +void RestoreCursorBackground() { + if (mouse.hidden || mouse.inhibit_draw) return; SaveVgaRegisters(); if (mouse.background) { @@ -332,7 +330,7 @@ void RestoreCursorBackground() }; void DrawCursor() { - if (mouse.shown) return; + if (mouse.hidden || mouse.inhibit_draw) return; // Check video page if (real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE)!=mouse.page) return; // Check if cursor in update region @@ -357,8 +355,11 @@ void DrawCursor() { mouse.clipx = CurMode->swidth-1; /* Get from bios ? */ mouse.clipy = CurMode->sheight-1; - Bit16s xratio = 640 / CurMode->swidth;/* might be vidmode == 0x13?2:1 */ - if(xratio==0) xratio = 1; + + /* might be vidmode == 0x13?2:1 */ + Bit16s xratio = 640; + if (CurMode->swidth>0) xratio/=CurMode->swidth; + if (xratio==0) xratio = 1; RestoreCursorBackground(); @@ -494,7 +495,7 @@ void Mouse_ButtonReleased(Bit8u button) { mouse.last_released_y[button]=POS_Y; } -static void SetMickeyPixelRate(Bit16s px, Bit16s py){ +static void Mouse_SetMickeyPixelRate(Bit16s px, Bit16s py){ if ((px!=0) && (py!=0)) { mouse.mickeysPerPixel_x = (float)px/X_MICKEY; mouse.mickeysPerPixel_y = (float)py/Y_MICKEY; @@ -502,9 +503,14 @@ static void SetMickeyPixelRate(Bit16s px, Bit16s py){ mouse.pixelPerMickey_y = Y_MICKEY/(float)py; } }; -static void SetSensitivity(Bit16s px, Bit16s py){ +static void Mouse_SetSensitivity(Bit16u px, Bit16u py, Bit16u dspeed){ if(px>100) px=100; if(py>100) py=100; + if(dspeed>100) dspeed=100; + // save values + mouse.senv_x_val=px; + mouse.senv_y_val=py; + mouse.dspeed_val=dspeed; if ((px!=0) && (py!=0)) { px--; //Inspired by cutemouse py--; //Although their cursor update routine is far more complex then ours @@ -514,19 +520,13 @@ static void SetSensitivity(Bit16s px, Bit16s py){ }; -static void mouse_reset_hardware(void){ +static void Mouse_ResetHardware(void){ PIC_SetIRQMask(MOUSE_IRQ,false); }; -void Mouse_NewVideoMode(void) -{ //Does way to much. Many of this stuff should be moved to mouse_reset one day - if(MOUSE_IRQ > 7) { - real_writed(0,((0x70+MOUSE_IRQ-8)<<2),CALLBACK_RealPointer(call_int74)); - } else { - real_writed(0,((0x8+MOUSE_IRQ)<<2),CALLBACK_RealPointer(call_int74)); - } - mouse.shown = 1;//Disabled as ida doesn't have mousecursor anymore - //enabled again as it seems to be a bug in ida4 +//Does way to much. Many things should be moved to mouse reset one day +void Mouse_NewVideoMode(void) { + mouse.inhibit_draw=false; /* Get the correct resolution from the current video mode */ Bitu mode=mem_readb(BIOS_VIDEO_MODE); switch (mode) { @@ -555,12 +555,11 @@ void Mouse_NewVideoMode(void) mouse.max_y=479; break; default: - mouse.max_y=199; LOG(LOG_MOUSE,LOG_ERROR)("Unhandled videomode %X on reset",mode); - // Hide mouse cursor on non supported modi. Pirates Gold - mouse.shown = 1; - break; - } + mouse.inhibit_draw=true; + return; + } + mouse.hidden = 1; mouse.max_x = 639; mouse.min_x = 0; mouse.min_y = 0; @@ -587,43 +586,38 @@ void Mouse_NewVideoMode(void) mouse.updateRegion_y[1] = 1; mouse.cursorType = 0; mouse.enabled=true; - mouse.oldshown=1; + mouse.oldhidden=1; - SetMickeyPixelRate(8,16); oldmouseX = static_cast(mouse.x); oldmouseY = static_cast(mouse.y); } -static void mouse_reset(void) { -//Much to empty Mouse_NewVideoMode contains stuff that should be in here - +//Much too empty, Mouse_NewVideoMode contains stuff that should be in here +static void Mouse_Reset(void) { /* Remove drawn mouse Legends of Valor */ if (CurMode->type!=M_TEXT) RestoreCursorBackground(); else RestoreCursorBackgroundText(); - mouse.shown = 1; + mouse.hidden = 1; Mouse_NewVideoMode(); + Mouse_SetMickeyPixelRate(8,16); mouse.sub_mask=0; - - mouse.senv_x=1.0; - mouse.senv_y=1.0; } static Bitu INT33_Handler(void) { - // LOG(LOG_MOUSE,LOG_NORMAL)("MOUSE: %04X %X %X %d %d",reg_ax,reg_bx,reg_cx,POS_X,POS_Y); switch (reg_ax) { case 0x00: /* Reset Driver and Read Status */ - mouse_reset_hardware(); /* fallthrough */ + Mouse_ResetHardware(); /* fallthrough */ case 0x21: /* Software Reset */ reg_ax=0xffff; reg_bx=MOUSE_BUTTONS; - mouse_reset(); + Mouse_Reset(); Mouse_AutoLock(true); break; case 0x01: /* Show Mouse */ - if(mouse.shown) mouse.shown--; + if(mouse.hidden) mouse.hidden--; Mouse_AutoLock(true); DrawCursor(); break; @@ -631,7 +625,7 @@ static Bitu INT33_Handler(void) { { if (CurMode->type!=M_TEXT) RestoreCursorBackground(); else RestoreCursorBackgroundText(); - mouse.shown++; + mouse.hidden++; } break; case 0x03: /* Return position and Button Status */ @@ -728,6 +722,12 @@ static Bitu INT33_Handler(void) { mouse.textAndMask = reg_cx; mouse.textXorMask = reg_dx; break; + case 0x0b: /* Read Motion Data */ + reg_cx=(Bit16s)(mouse.mickey_x*mouse.mickeysPerPixel_x); + reg_dx=(Bit16s)(mouse.mickey_y*mouse.mickeysPerPixel_y); + mouse.mickey_x=0; + mouse.mickey_y=0; + break; case 0x0c: /* Define interrupt subroutine parameters */ mouse.sub_mask=reg_cx; mouse.sub_seg=SegValue(es); @@ -735,13 +735,7 @@ static Bitu INT33_Handler(void) { Mouse_AutoLock(true); //Some games don't seem to reset the mouse before using break; case 0x0f: /* Define mickey/pixel rate */ - SetMickeyPixelRate(reg_cx,reg_dx); - break; - case 0x0B: /* Read Motion Data */ - reg_cx=(Bit16s)(mouse.mickey_x*mouse.mickeysPerPixel_x); - reg_dx=(Bit16s)(mouse.mickey_y*mouse.mickeysPerPixel_y); - mouse.mickey_x=0; - mouse.mickey_y=0; + Mouse_SetMickeyPixelRate(reg_cx,reg_dx); break; case 0x10: /* Define screen region for updating */ mouse.updateRegion_x[0]=reg_cx; @@ -789,21 +783,17 @@ static Bitu INT33_Handler(void) { } break; case 0x1a: /* Set mouse sensitivity */ - SetSensitivity(reg_bx,reg_cx); - - LOG(LOG_MOUSE,LOG_WARN)("Set sensitivity used with %d %d",reg_bx,reg_cx); - // ToDo : double mouse speed value + Mouse_SetSensitivity(reg_bx,reg_cx,reg_dx); + + LOG(LOG_MOUSE,LOG_WARN)("Set sensitivity used with %d %d (%d)",reg_bx,reg_cx,reg_dx); break; case 0x1b: /* Get mouse sensitivity */ - reg_bx = Bit16s((60.0* sqrt(mouse.senv_x- (1.0/3.0)) ) +1.0); - - reg_cx = Bit16s((60.0* sqrt(mouse.senv_y- (1.0/3.0)) ) +1.0); + reg_bx = mouse.senv_x_val; + reg_cx = mouse.senv_y_val; + reg_dx = mouse.dspeed_val; LOG(LOG_MOUSE,LOG_WARN)("Get sensitivity %d %d",reg_bx,reg_cx); - - // ToDo : double mouse speed value - reg_dx = 64; break; case 0x1c: /* Set interrupt rate */ /* Can't really set a rate this is host determined */ @@ -819,12 +809,12 @@ static Bitu INT33_Handler(void) { reg_bx=0; SegSet16(es,0); mouse.enabled=false; /* Just for reporting not doing a thing with it */ - mouse.oldshown=mouse.shown; - mouse.shown=1; + mouse.oldhidden=mouse.hidden; + mouse.hidden=1; break; case 0x20: /* Enable Mousedriver */ mouse.enabled=true; - mouse.shown=mouse.oldshown; + mouse.hidden=mouse.oldhidden; break; case 0x22: /* Set language for messages */ /* @@ -849,7 +839,7 @@ static Bitu INT33_Handler(void) { case 0x24: /* Get Software version and mouse type */ reg_bx=0x805; //Version 8.05 woohoo reg_ch=0x04; /* PS/2 type */ - reg_cl=0;//MOUSE_IRQ; /* Hmm ps2 irq 0!!!! */ + reg_cl=0; /* PS/2 (unused) */ break; case 0x26: /* Get Maximum virtual coordinates */ reg_bx=(mouse.enabled ? 0x0000 : 0xffff); @@ -1014,12 +1004,13 @@ void MOUSE_Init(Section* sec) { ps2_callback=CALLBACK_RealPointer(call_ps2); memset(&mouse,0,sizeof(mouse)); - mouse.shown = 1; //Hide mouse on startup + mouse.hidden = 1; //Hide mouse on startup mouse.sub_mask=0; mouse.sub_seg=0x6362; // magic value mouse.sub_ofs=0; - mouse_reset_hardware(); - mouse_reset(); + Mouse_ResetHardware(); + Mouse_Reset(); + Mouse_SetSensitivity(50,50,50); } From 245d35c4c8f8b675cd92ee5c7643decddaada853 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 5 Nov 2007 18:42:56 +0000 Subject: [PATCH 2952/4131] Add patch from h-a-l-9000 that deals with LIN4 palette setting (cad software) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3040 --- src/ints/int10_modes.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index efd1fe12..da24595a 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.69 2007-10-19 20:30:24 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.70 2007-11-05 18:42:56 qbix79 Exp $ */ #include @@ -982,7 +982,8 @@ dac_mtext16: IO_Write(0x3c9,mtext_palette[i][2]); } break; - } + } //FALLTHROUGH!!!! + case M_LIN4: //Added for CAD Software dac_text16: for (i=0;i<64;i++) { IO_Write(0x3c9,text_palette[i][0]); From 112ec0d6378ea258a387b10b9e6cc7c1a32f40e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 5 Nov 2007 21:46:26 +0000 Subject: [PATCH 2953/4131] don't speed up small mouse movements; skip some duplicate mouse events (don't add a move if another move is already in the queue) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3041 --- src/ints/mouse.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index a95c7116..5b1fe4ba 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.70 2007-11-05 17:49:17 c2woody Exp $ */ +/* $Id: mouse.cpp,v 1.71 2007-11-05 21:46:26 c2woody Exp $ */ #include #include @@ -198,11 +198,15 @@ Bitu PS2_Handler(void) { INLINE void Mouse_AddEvent(Bit16u type) { if (mouse.events0) { + /* Skip duplicate events */ + if ((type==MOUSE_MOVED) && (mouse.buttons==0)) return; + /* Always put the newest element in the front as that the events are + * handled backwards (prevents doubleclicks while moving) + */ + for(Bitu i = mouse.events ; i ; i--) + mouse.event_queue[i] = mouse.event_queue[i-1]; + } mouse.event_queue[0].type=type; mouse.event_queue[0].buttons=mouse.buttons; mouse.events++; @@ -415,8 +419,8 @@ void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate) { float dx = xrel * mouse.pixelPerMickey_x; float dy = yrel * mouse.pixelPerMickey_y; - if((fabs(x) > 1.0) || (mouse.senv_x < 1.0)) dx *= mouse.senv_x; - if((fabs(y) > 1.0) || (mouse.senv_y < 1.0)) dy *= mouse.senv_y; + if((fabs(xrel) > 1.0) || (mouse.senv_x < 1.0)) dx *= mouse.senv_x; + if((fabs(yrel) > 1.0) || (mouse.senv_y < 1.0)) dy *= mouse.senv_y; if (useps2callback) dy *= 2; mouse.mickey_x += dx; From 134b7f8ef2e678da2fe044eb0cac65474865f63c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 6 Nov 2007 20:08:34 +0000 Subject: [PATCH 2954/4131] Fix printfing the same string twice. Makes it possible to print %d Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3042 --- src/gui/sdlmain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index de7f6ec9..83df14fe 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.135 2007-10-28 16:36:42 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.136 2007-11-06 20:08:34 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1317,7 +1317,7 @@ void GFX_ShowMsg(char const* format,...) { vsprintf(buf,format,msg); strcat(buf,"\n"); va_end(msg); - if(!no_stdout) printf(buf); + if(!no_stdout) printf("%s",buf); //Else buf is parsed again. }; extern void UI_Init(void); From 362f9205217bc8b877999de63a9ae2c024e740f2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 6 Nov 2007 20:25:36 +0000 Subject: [PATCH 2955/4131] Fix problems with visual C.net 2003 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3043 --- src/gui/sdl_gui.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index e91d4154..59b40233 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_gui.cpp,v 1.2 2007-10-31 11:37:38 qbix79 Exp $ */ +/* $Id: sdl_gui.cpp,v 1.3 2007-11-06 20:25:36 qbix79 Exp $ */ #include "SDL.h" #include "../libs/gui_tk/gui_tk.h" @@ -374,7 +374,7 @@ public: HelpWindow(GUI::Screen *parent, int x, int y, Section *section) : MessageBox(parent, x, y, 580, "", "") { std::string title(section->GetName()); - title[0] = std::toupper(title[0]); + title.at(0) = std::toupper(title.at(0)); setTitle("Help for "+title); std::string name = section->GetName(); std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))std::toupper); @@ -549,7 +549,7 @@ public: void actionExecuted(GUI::ActionEventSource *b, const GUI::String &arg) { GUI::String sname = arg; - sname[0] = std::tolower(sname[0]); + sname.at(0) = std::tolower(sname.at(0)); Section *sec; if (arg == "Close" || arg == "Cancel") { running = false; From 0fb5e8b56d6855f70e83695144b8bddc53cc0b15 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 6 Nov 2007 20:26:27 +0000 Subject: [PATCH 2956/4131] Fix 2 warnings with g++-3.4 (Moe) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3044 --- src/libs/gui_tk/gui_tk.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/gui_tk/gui_tk.h b/src/libs/gui_tk/gui_tk.h index a59c7fbe..e852d6e7 100644 --- a/src/libs/gui_tk/gui_tk.h +++ b/src/libs/gui_tk/gui_tk.h @@ -102,7 +102,7 @@ * along with this program. If not, see */ -/* $Id: gui_tk.h,v 1.1 2007-10-28 16:33:02 qbix79 Exp $ */ +/* $Id: gui_tk.h,v 1.2 2007-11-06 20:26:27 qbix79 Exp $ */ #ifndef GUI__TOOLKIT_H #define GUI__TOOLKIT_H @@ -1060,11 +1060,11 @@ public: backspace, line-feed, tab and ANSI colors are interpreted, and text is word-wrapped at the window borders. You can optionally pass start and length of a substring to print */ - void drawText(const String& text, bool interpret = true, Size start = 0, Size len = -1); + void drawText(const String& text, bool interpret = true, Size start = 0, Size len = (Size)-1); /// Draw a text string at a fixed position. /** see drawText(const String& text, bool interpret, Size start, Size len) */ - template void drawText(int x, int y, const STR text, bool interpret, Size start, Size len = -1) { gotoXY(x,y); drawText(String(text), interpret, start, len); }; + template void drawText(int x, int y, const STR text, bool interpret, Size start, Size len = (Size)-1) { gotoXY(x,y); drawText(String(text), interpret, start, len); }; /// Draw a single character. /** see drawText(const STR text, bool interpret), except wrapping is performed on this character only */ From 5cdc1cd683b4b47e9b73f5b49acc97406ab6bdd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 7 Nov 2007 17:41:32 +0000 Subject: [PATCH 2957/4131] forward state of caps/numlock to mapper event system Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3045 --- src/gui/sdl_mapper.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 84906fdf..061f2889 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.46 2007-10-31 11:43:06 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.47 2007-11-07 17:41:32 c2woody Exp $ */ #include #include @@ -1671,12 +1671,13 @@ static void DrawButtons(void) { SDL_Flip(mapper.surface); } -static void AddKeyButtonEvent(Bitu x,Bitu y,Bitu dx,Bitu dy,char const * const title,char const * const entry,KBD_KEYS key) { +static CKeyEvent * AddKeyButtonEvent(Bitu x,Bitu y,Bitu dx,Bitu dy,char const * const title,char const * const entry,KBD_KEYS key) { char buf[64]; strcpy(buf,"key_"); strcat(buf,entry); CKeyEvent * event=new CKeyEvent(buf,key); new CEventButton(x,y,dx,dy,title,event); + return event; } static CJAxisEvent * AddJAxisButton(Bitu x,Bitu y,Bitu dx,Bitu dy,char const * const title,Bitu stick,Bitu axis,bool positive,CJAxisEvent * opposite_axis) { @@ -1762,6 +1763,8 @@ static KeyBlock combo_4[11]={ {".","period",KBD_period}, {"/","slash",KBD_slash}, }; +static CKeyEvent * caps_lock_event=NULL; +static CKeyEvent * num_lock_event=NULL; static void CreateLayout(void) { Bitu i; @@ -1780,7 +1783,7 @@ static void CreateLayout(void) { AddKeyButtonEvent(PX(14),PY(2),BW*2,BH*2,"ENTER","enter",KBD_enter); - AddKeyButtonEvent(PX(0),PY(3),BW*2,BH,"CLCK","capslock",KBD_capslock); + caps_lock_event=AddKeyButtonEvent(PX(0),PY(3),BW*2,BH,"CLCK","capslock",KBD_capslock); for (i=0;i<12;i++) AddKeyButtonEvent(PX(2+i),PY(3),BW,BH,combo_3[i].title,combo_3[i].entry,combo_3[i].key); AddKeyButtonEvent(PX(0),PY(4),BW*2,BH,"SHIFT","lshift",KBD_leftshift); @@ -1795,7 +1798,6 @@ static void CreateLayout(void) { AddKeyButtonEvent(PX(14),PY(5),BW*2,BH,"CTRL","rctrl",KBD_rightctrl); /* Arrow Keys */ - AddKeyButtonEvent(PX(0),PY(7),BW,BH,"PRT","printscreen",KBD_printscreen); AddKeyButtonEvent(PX(1),PY(7),BW,BH,"SCL","scrolllock",KBD_scrolllock); AddKeyButtonEvent(PX(2),PY(7),BW,BH,"PAU","pause",KBD_pause); @@ -1809,8 +1811,9 @@ static void CreateLayout(void) { AddKeyButtonEvent(PX(0),PY(11),BW,BH,"\x1B","left",KBD_left); AddKeyButtonEvent(PX(1),PY(11),BW,BH,"\x19","down",KBD_down); AddKeyButtonEvent(PX(2),PY(11),BW,BH,"\x1A","right",KBD_right); + /* Numeric KeyPad */ - AddKeyButtonEvent(PX(4),PY(7),BW,BH,"NUM","numlock",KBD_numlock); + num_lock_event=AddKeyButtonEvent(PX(4),PY(7),BW,BH,"NUM","numlock",KBD_numlock); AddKeyButtonEvent(PX(5),PY(7),BW,BH,"/","kp_divide",KBD_kpdivide); AddKeyButtonEvent(PX(6),PY(7),BW,BH,"*","kp_multiply",KBD_kpmultiply); AddKeyButtonEvent(PX(7),PY(7),BW,BH,"-","kp_minus",KBD_kpminus); @@ -2277,6 +2280,16 @@ void MAPPER_Init(void) { CreateLayout(); CreateBindGroups(); if (!MAPPER_LoadBinds()) CreateDefaultBinds(); + if (SDL_GetModState()&KMOD_CAPS) { + for (CBindList_it bit=caps_lock_event->bindlist.begin();bit!=caps_lock_event->bindlist.end();bit++) { + (*bit)->Activate(32767,true); + } + } + if (SDL_GetModState()&KMOD_NUM) { + for (CBindList_it bit=num_lock_event->bindlist.begin();bit!=num_lock_event->bindlist.end();bit++) { + (*bit)->Activate(32767,true); + } + } } void MAPPER_StartUp(Section * sec) { From 6d7dd9f3ae582b5216384caa96f737dd1f5413cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 7 Nov 2007 22:08:03 +0000 Subject: [PATCH 2958/4131] add sft-returning dos function (fixes file/integrity checking library of MadTV2 and Dunkle Schatten 2) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3046 --- include/dos_inc.h | 12 +++--- src/dos/dos_classes.cpp | 8 ++-- src/dos/dos_misc.cpp | 83 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 91 insertions(+), 12 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 9f38dbe3..e4a93da9 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.70 2007-07-20 18:53:52 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.71 2007-11-07 22:08:03 c2woody Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -78,12 +78,12 @@ enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; #define DOS_INFOBLOCK_SEG 0x80 -#define DOS_CDS_SEG 0x90 -#define DOS_CONSTRING_SEG 0xa0 -#define DOS_CONDRV_SEG 0xa4 -#define DOS_SDA_SEG 0xb2 +#define DOS_CDS_SEG 0xa8 +#define DOS_CONSTRING_SEG 0xb8 +#define DOS_CONDRV_SEG 0xbc +#define DOS_SDA_SEG 0xca #define DOS_SDA_OFS 0 -#define DOS_MEM_START 0x102 //First Segment that DOS can use +#define DOS_MEM_START 0x11a //First Segment that DOS can use #define DOS_PRIVATE_SEGMENT 0xc800 #define DOS_PRIVATE_SEGMENT_END 0xd000 diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 5ac6d4e7..fa648bc2 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.52 2007-06-13 07:25:14 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.53 2007-11-07 22:08:03 c2woody Exp $ */ #include #include @@ -117,10 +117,10 @@ void DOS_InfoBlock::SetLocation(Bit16u segment) { /* Create a fake SFT, so programs think there are 100 file handles */ Bit16u sftOffset=offsetof(sDIB,firstFileTable)+0xa2; sSave(sDIB,firstFileTable,RealMake(segment,sftOffset)); - real_writed(segment,sftOffset+0x00,RealMake(segment+0x11,0)); //Next File Table + real_writed(segment,sftOffset+0x00,RealMake(segment+0x26,0)); //Next File Table real_writew(segment,sftOffset+0x04,100); //File Table supports 100 files - real_writed(segment+0x11,0x00,0xffffffff); //Last File Table - real_writew(segment+0x11,0x04,100); //File Table supports 100 files + real_writed(segment+0x26,0x00,0xffffffff); //Last File Table + real_writew(segment+0x26,0x04,100); //File Table supports 100 files } void DOS_InfoBlock::SetFirstMCB(Bit16u _firstmcb) { diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index 36c48122..ddf68a22 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_misc.cpp,v 1.17 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: dos_misc.cpp,v 1.18 2007-11-07 22:08:03 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" @@ -61,10 +61,89 @@ static Bitu INT2A_Handler(void) { static bool DOS_MultiplexFunctions(void) { switch (reg_ax) { case 0x1216: /* GET ADDRESS OF SYSTEM FILE TABLE ENTRY */ - /* Should do a lot more. Let's see if we can get away with it */ + // reg_bx is a system file table entry, should coincide with + // the file handle so just use that LOG(LOG_DOSMISC,LOG_ERROR)("Some BAD filetable call used bx=%X",reg_bx); if(reg_bx <= DOS_FILES) CALLBACK_SCF(false); else CALLBACK_SCF(true); + if (reg_bx<16) { + RealPt sftrealpt=mem_readd(Real2Phys(dos_infoblock.GetPointer())+4); + PhysPt sftptr=Real2Phys(sftrealpt); + Bitu sftofs=0x06+reg_bx*0x3b; + + if (Files[reg_bx]) mem_writeb(sftptr+sftofs,Files[reg_bx]->refCtr); + else mem_writeb(sftptr+sftofs,0); + + if (!Files[reg_bx]) return true; + + Bit32u handle=RealHandle(reg_bx); + if (handle>=DOS_FILES) { + mem_writew(sftptr+sftofs+0x02,0x02); // file open mode + mem_writeb(sftptr+sftofs+0x04,0x00); // file attribute + mem_writew(sftptr+sftofs+0x05,Files[reg_bx]->GetInformation()); // device info word + mem_writed(sftptr+sftofs+0x07,0); // device driver header + mem_writew(sftptr+sftofs+0x0d,0); // packed time + mem_writew(sftptr+sftofs+0x0f,0); // packed date + mem_writew(sftptr+sftofs+0x11,0); // size + mem_writew(sftptr+sftofs+0x15,0); // current position + } else { + Bit8u drive=Files[reg_bx]->GetDrive(); + + mem_writew(sftptr+sftofs+0x02,Files[reg_bx]->flags&3); // file open mode + mem_writeb(sftptr+sftofs+0x04,(Bit8u)(Files[reg_bx]->attr)); // file attribute + mem_writew(sftptr+sftofs+0x05,0x40|drive); // device info word + mem_writed(sftptr+sftofs+0x07,RealMake(dos.tables.dpb,drive)); // dpb of the drive + mem_writew(sftptr+sftofs+0x0d,Files[reg_bx]->time); // packed file time + mem_writew(sftptr+sftofs+0x0f,Files[reg_bx]->date); // packed file date + Bit32u curpos=0; + Files[reg_bx]->Seek(&curpos,DOS_SEEK_CUR); + Bit32u endpos=0; + Files[reg_bx]->Seek(&endpos,DOS_SEEK_END); + mem_writed(sftptr+sftofs+0x11,endpos); // size + mem_writed(sftptr+sftofs+0x15,curpos); // current position + Files[reg_bx]->Seek(&curpos,DOS_SEEK_SET); + } + + // fill in filename in fcb style + // (space-padded name (8 chars)+space-padded extension (3 chars)) + const char* filename=(const char*)Files[reg_bx]->GetName(); + if (strrchr(filename,'\\')) filename=strrchr(filename,'\\')+1; + if (strrchr(filename,'/')) filename=strrchr(filename,'/')+1; + if (!filename) return true; + const char* dotpos=strrchr(filename,'.'); + if (dotpos) { + dotpos++; + size_t nlen=strlen(filename); + size_t extlen=strlen(dotpos); + Bits nmelen=(Bits)nlen-(Bits)extlen; + nmelen--; + if (nmelen<0) return true; + nlen-=(extlen+1); + + if (nlen>8) nlen=8; + for (Bitu i=0; i3) extlen=3; + for (Bitu i=0; i8) nlen=8; + for (Bitu i=0; i Date: Thu, 15 Nov 2007 21:06:18 +0000 Subject: [PATCH 2959/4131] use exception-checking code even in real mode (for code which is later ran in v86 mode), dynamic cores only Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3047 --- src/cpu/core_dyn_x86/decoder.h | 42 ++++++++++----------------- src/cpu/core_dynrec/decoder.h | 4 +-- src/cpu/core_dynrec/decoder_opcodes.h | 22 +++++++------- 3 files changed, 28 insertions(+), 40 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 4270a024..23a66dd0 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1582,11 +1582,9 @@ static void dyn_mov_ev_seg(void) { } static void dyn_load_seg(SegNames seg,DynReg * src) { - if (cpu.pmode) { - gen_call_function((void *)&CPU_SetSegGeneral,"%Rd%Id%Drw",DREG(TMPB),seg,src); - dyn_check_bool_exception(DREG(TMPB)); - gen_releasereg(DREG(TMPB)); - } else gen_call_function((void *)CPU_SetSegGeneral,"%Id%Drw",seg,src); + gen_call_function((void *)&CPU_SetSegGeneral,"%Rd%Id%Drw",DREG(TMPB),seg,src); + dyn_check_bool_exception(DREG(TMPB)); + gen_releasereg(DREG(TMPB)); gen_releasereg(&DynRegs[G_ES+seg]); } @@ -1625,18 +1623,12 @@ static void dyn_push_seg(SegNames seg) { } static void dyn_pop_seg(SegNames seg) { - if (!cpu.pmode) { - dyn_pop(DREG(TMPW)); - dyn_load_seg(seg,DREG(TMPW)); - gen_releasereg(DREG(TMPW)); - } else { - gen_releasereg(DREG(ESP)); - gen_call_function((void *)&CPU_PopSeg,"%Rd%Id%Id",DREG(TMPB),seg,decode.big_op); - dyn_check_bool_exception(DREG(TMPB)); - gen_releasereg(DREG(TMPB)); - gen_releasereg(&DynRegs[G_ES+seg]); - gen_releasereg(DREG(ESP)); - } + gen_releasereg(DREG(ESP)); + gen_call_function((void *)&CPU_PopSeg,"%Rd%Id%Id",DREG(TMPB),seg,decode.big_op); + dyn_check_bool_exception(DREG(TMPB)); + gen_releasereg(DREG(TMPB)); + gen_releasereg(&DynRegs[G_ES+seg]); + gen_releasereg(DREG(ESP)); } static void dyn_pop_ev(void) { @@ -1874,17 +1866,13 @@ static void dyn_interrupt(Bitu num) { } static void dyn_add_iocheck(Bitu access_size) { - if (cpu.pmode) { - gen_call_function((void *)&CPU_IO_Exception,"%Dw%Id",DREG(EDX),access_size); - dyn_check_bool_exception_al(); - } + gen_call_function((void *)&CPU_IO_Exception,"%Dw%Id",DREG(EDX),access_size); + dyn_check_bool_exception_al(); } static void dyn_add_iocheck_var(Bit8u accessed_port,Bitu access_size) { - if (cpu.pmode) { - gen_call_function((void *)&CPU_IO_Exception,"%Id%Id",accessed_port,access_size); - dyn_check_bool_exception_al(); - } + gen_call_function((void *)&CPU_IO_Exception,"%Id%Id",accessed_port,access_size); + dyn_check_bool_exception_al(); } #ifdef X86_DYNFPU_DH_ENABLED @@ -2465,13 +2453,13 @@ restart_prefix: case 0xfa: //CLI gen_releasereg(DREG(FLAGS)); gen_call_function((void *)&CPU_CLI,"%Rd",DREG(TMPB)); - if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); + dyn_check_bool_exception(DREG(TMPB)); gen_releasereg(DREG(TMPB)); break; case 0xfb: //STI gen_releasereg(DREG(FLAGS)); gen_call_function((void *)&CPU_STI,"%Rd",DREG(TMPB)); - if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); + dyn_check_bool_exception(DREG(TMPB)); gen_releasereg(DREG(TMPB)); dyn_check_irqrequest(); if (max_opcodes<=0) max_opcodes=1; //Allow 1 extra opcode diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h index 13c47b41..143e50a1 100644 --- a/src/cpu/core_dynrec/decoder.h +++ b/src/cpu/core_dynrec/decoder.h @@ -530,11 +530,11 @@ restart_prefix: case 0xfa: //CLI gen_call_function_raw((void *)&CPU_CLI); - if (cpu.pmode) dyn_check_exception(FC_RETOP); + dyn_check_exception(FC_RETOP); break; case 0xfb: //STI gen_call_function_raw((void *)&CPU_STI); - if (cpu.pmode) dyn_check_exception(FC_RETOP); + dyn_check_exception(FC_RETOP); if (max_opcodes<=0) max_opcodes=1; //Allow 1 extra opcode break; diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index 29ba55c9..1771f989 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -402,7 +402,7 @@ static void dyn_push_seg(Bit8u seg) { static void dyn_pop_seg(Bit8u seg) { gen_call_function_II((void *)&CPU_PopSeg,seg,decode.big_op); - if (cpu.pmode) dyn_check_exception(FC_RETOP); + dyn_check_exception(FC_RETOP); } static void dyn_push_reg(Bit8u reg) { @@ -468,7 +468,7 @@ static void dyn_segprefix(Bit8u seg) { gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); } gen_call_function_IR((void *)&CPU_SetSegGeneral,decode.modrm.reg,FC_RETOP); - if (cpu.pmode) dyn_check_exception(FC_RETOP); + dyn_check_exception(FC_RETOP); } static void dyn_load_seg_off_ea(Bit8u seg) { @@ -484,7 +484,7 @@ static void dyn_load_seg_off_ea(Bit8u seg) { dyn_read_word(FC_ADDR,FC_RETOP,false); gen_call_function_IR((void *)&CPU_SetSegGeneral,seg,FC_RETOP); - if (cpu.pmode) dyn_check_exception(FC_RETOP); + dyn_check_exception(FC_RETOP); gen_restore_reg(FC_OP1); gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); @@ -1327,9 +1327,9 @@ static void dyn_write_port_word_direct(Bit8u port) { static void dyn_read_port_byte(void) { gen_mov_word_to_reg(FC_ADDR,DRCD_REG_WORD(DRC_REG_EDX,false),false); gen_extend_word(false,FC_ADDR); - if (cpu.pmode) gen_protect_addr_reg(); + gen_protect_addr_reg(); dyn_add_iocheck(FC_ADDR,1); - if (cpu.pmode) gen_restore_addr_reg(); + gen_restore_addr_reg(); gen_call_function_R((void*)&IO_ReadB,FC_ADDR); gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(DRC_REG_EAX,0)); } @@ -1337,9 +1337,9 @@ static void dyn_read_port_byte(void) { static void dyn_read_port_word(void) { gen_mov_word_to_reg(FC_ADDR,DRCD_REG_WORD(DRC_REG_EDX,false),false); gen_extend_word(false,FC_ADDR); - if (cpu.pmode) gen_protect_addr_reg(); + gen_protect_addr_reg(); dyn_add_iocheck(FC_ADDR,decode.big_op?4:2); - if (cpu.pmode) gen_restore_addr_reg(); + gen_restore_addr_reg(); gen_call_function_R(decode.big_op?((void*)&IO_ReadD):((void*)&IO_ReadW),FC_ADDR); gen_mov_word_from_reg(FC_RETOP,DRCD_REG_BYTE(DRC_REG_EAX,decode.big_op),decode.big_op); } @@ -1347,22 +1347,22 @@ static void dyn_read_port_word(void) { static void dyn_write_port_byte(void) { gen_mov_word_to_reg(FC_ADDR,DRCD_REG_WORD(DRC_REG_EDX,false),false); gen_extend_word(false,FC_ADDR); - if (cpu.pmode) gen_protect_addr_reg(); + gen_protect_addr_reg(); dyn_add_iocheck(FC_ADDR,1); gen_mov_byte_to_reg_low(FC_RETOP,DRCD_REG_BYTE(DRC_REG_EAX,0)); gen_extend_byte(false,FC_RETOP); - if (cpu.pmode) gen_restore_addr_reg(); + gen_restore_addr_reg(); gen_call_function_RR((void*)&IO_WriteB,FC_ADDR,FC_RETOP); } static void dyn_write_port_word(void) { gen_mov_word_to_reg(FC_ADDR,DRCD_REG_WORD(DRC_REG_EDX,false),false); gen_extend_word(false,FC_ADDR); - if (cpu.pmode) gen_protect_addr_reg(); + gen_protect_addr_reg(); dyn_add_iocheck(FC_ADDR,decode.big_op?4:2); gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); if (!decode.big_op) gen_extend_word(false,FC_RETOP); - if (cpu.pmode) gen_restore_addr_reg(); + gen_restore_addr_reg(); gen_call_function_RR(decode.big_op?((void*)&IO_WriteD):((void*)&IO_WriteW),FC_ADDR,FC_RETOP); } From 10b39bc067f77a52bdf10673cf439bb849f72fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 18 Nov 2007 10:30:12 +0000 Subject: [PATCH 2960/4131] allow small .com files to be exectued with not much free memory left; int27 always clears the returned error code; fixes corncob3d music Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3048 --- include/dos_inc.h | 4 ++-- src/dos/dos.cpp | 9 ++++----- src/dos/dos_execute.cpp | 21 +++++++++++++++------ 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index e4a93da9..152afd0a 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.71 2007-11-07 22:08:03 c2woody Exp $ */ +/* $Id: dos_inc.h,v 1.72 2007-11-18 10:30:11 c2woody Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -150,7 +150,7 @@ void DOS_SetupDevices(void); bool DOS_NewPSP(Bit16u pspseg,Bit16u size); bool DOS_ChildPSP(Bit16u pspseg,Bit16u size); bool DOS_Execute(char * name,PhysPt block,Bit8u flags); -bool DOS_Terminate(bool tsr); +bool DOS_Terminate(bool tsr,Bit8u exitcode); /* Memory Handling Routines */ void DOS_SetupMemory(void); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 872d6a86..807c2b94 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.105 2007-11-04 11:11:34 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.106 2007-11-18 10:30:12 c2woody Exp $ */ #include #include @@ -384,7 +384,7 @@ static Bitu DOS_21Handler(void) { //TODO First get normal files executing // Important: This service does not set the carry flag! DOS_ResizeMemory(dos.psp(),®_dx); - DOS_Terminate(true); + DOS_Terminate(true,reg_al); dos.return_code=reg_al; //Officially a field in the SDA dos.return_mode=RETURN_TSR; break; @@ -689,7 +689,7 @@ static Bitu DOS_21Handler(void) { reg_ax=0x4c00; /* Terminate Program */ case 0x4c: /* EXIT Terminate with return code */ { - if (DOS_Terminate(false)) { + if (DOS_Terminate(false,reg_al)) { /* This can't ever return false normally */ } else { reg_ax=dos.errorcode; @@ -1011,7 +1011,6 @@ static Bitu DOS_21Handler(void) { break; }; return CBRET_NONE; -/* That's it now let's get it working */ }; @@ -1024,7 +1023,7 @@ static Bitu DOS_20Handler(void) { static Bitu DOS_27Handler(void) { // Terminate & stay resident Bit16u para = (reg_dx/16)+((reg_dx % 16)>0); - if (DOS_ResizeMemory(dos.psp(),¶)) DOS_Terminate(true); + if (DOS_ResizeMemory(dos.psp(),¶)) DOS_Terminate(true,0); return CBRET_NONE; } diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index b181a4c0..ee646230 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.62 2007-10-19 19:39:27 c2woody Exp $ */ +/* $Id: dos_execute.cpp,v 1.63 2007-11-18 10:30:12 c2woody Exp $ */ #include #include @@ -104,9 +104,9 @@ void DOS_UpdatePSPName(void) { GFX_SetTitle(-1,-1,false); } -bool DOS_Terminate(bool tsr) { +bool DOS_Terminate(bool tsr,Bit8u exitcode) { - dos.return_code=reg_al; + dos.return_code=exitcode; dos.return_mode=RETURN_EXIT; Bit16u mempsp = dos.psp(); @@ -330,9 +330,18 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { else maxsize=0xffff; } if (maxfree>4)+0x20; + } + if (maxfree Date: Sun, 18 Nov 2007 17:09:15 +0000 Subject: [PATCH 2961/4131] Add fix for dungle schatten 1. Implement timer mode 1. Flip gate2 default value (h-a-l-9000) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3049 --- src/hardware/keyboard.cpp | 4 ++-- src/hardware/timer.cpp | 27 ++++++++++++++++++++++----- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index bc4ef238..72511107 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.39 2007-06-12 20:22:08 c2woody Exp $ */ +/* $Id: keyboard.cpp,v 1.40 2007-11-18 17:09:15 qbix79 Exp $ */ #include "dosbox.h" #include "keyboard.h" @@ -171,7 +171,7 @@ static void write_p60(Bitu port,Bitu val,Bitu iolen) { } } -static Bit8u port_61_data; +static Bit8u port_61_data = 0; static Bitu read_p61(Bitu port,Bitu iolen) { port_61_data^=0x20; port_61_data^=0x10; diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 0341bd4e..ffc6b1c1 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.44 2007-06-12 20:22:08 c2woody Exp $ */ +/* $Id: timer.cpp,v 1.45 2007-11-18 17:09:15 qbix79 Exp $ */ #include #include "dosbox.h" @@ -54,6 +54,7 @@ struct PIT_Block { bool go_read_latch; bool new_mode; bool counterstatus_set; + bool counting; }; static PIT_Block pit[3]; @@ -127,7 +128,7 @@ static void counter_latch(Bitu counter) { p->go_read_latch=false; //If gate2 is disabled don't update the read_latch - if(counter == 2 && !gate2) return; + if(counter == 2 && !gate2 && p->mode !=1) return; double index=PIC_FullIndex()-p->start; switch (p->mode) { @@ -147,6 +148,15 @@ static void counter_latch(Bitu counter) { p->read_latch=(Bit16u)(p->cntr-index*(PIT_TICK_RATE/1000.0)); } break; + case 1: // countdown + if(p->counting) { + if (index>p->delay) { // has timed out + p->read_latch = 0xffff; //unconfirmed + } else { + p->read_latch=(Bit16u)(p->cntr-index*(PIT_TICK_RATE/1000.0)); + } + } + break; case 2: /* Rate Generator */ index=fmod(index,(double)p->delay); p->read_latch=(Bit16u)(p->cntr - (index/p->delay)*p->cntr); @@ -282,7 +292,7 @@ static void write_p43(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { pit[latch].counterstatus_set=false; latched_timerstatus_locked=false; } - + pit[latch].counting = false; pit[latch].read_state = (val >> 4) & 0x03; pit[latch].write_state = (val >> 4) & 0x03; Bit8u mode = (val >> 1) & 0x07; @@ -345,13 +355,19 @@ void TIMER_SetGate2(bool in) { pit[2].cntr = pit[2].read_latch; } break; + case 1: + // gate 1 on: reload counter; off: nothing + if(in) { + pit[2].counting = true; + pit[2].start = PIC_FullIndex(); + } + break; case 2: case 3: //If gate is enabled restart counting. If disable store the current read_latch if(in) pit[2].start = PIC_FullIndex(); else counter_latch(2); break; - case 1: case 4: case 5: LOG(LOG_MISC,LOG_WARN)("unsupported gate 2 mode %x",mode); @@ -401,13 +417,14 @@ public: pit[2].cntr=1320; pit[2].go_read_latch=true; pit[2].counterstatus_set = false; + pit[2].counting = false; pit[0].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[0].cntr)); pit[1].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[1].cntr)); pit[2].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[2].cntr)); latched_timerstatus_locked=false; - gate2 = true; + gate2 = false; PIC_AddEvent(PIT0_Event,pit[0].delay); } ~TIMER(){ From cb37216a20aa20c421e1b27cf6860cbaa665e0d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 24 Nov 2007 17:26:48 +0000 Subject: [PATCH 2962/4131] improve page protection handling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3050 --- include/paging.h | 47 +++--- src/cpu/core_dyn_x86.cpp | 4 +- src/cpu/core_dyn_x86/decoder.h | 6 +- src/cpu/core_dynrec.cpp | 4 +- src/cpu/core_dynrec/decoder_basic.h | 14 +- src/cpu/paging.cpp | 218 ++++++++++++++++++++-------- src/debug/debug.cpp | 6 +- 7 files changed, 204 insertions(+), 95 deletions(-) diff --git a/include/paging.h b/include/paging.h index 8a95c040..b80a2571 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.28 2007-10-05 17:45:52 c2woody Exp $ */ +/* $Id: paging.h,v 1.29 2007-11-24 17:26:48 c2woody Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H @@ -88,6 +88,7 @@ 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); @@ -142,7 +143,8 @@ union X86PageEntry { typedef struct { HostPt read; HostPt write; - PageHandler * handler; + PageHandler * readhandler; + PageHandler * writehandler; Bit32u phys_page; } tlb_entry; #endif @@ -158,7 +160,8 @@ struct PagingBlock { struct { HostPt read[TLB_SIZE]; HostPt write[TLB_SIZE]; - PageHandler * handler[TLB_SIZE]; + PageHandler * readhandler[TLB_SIZE]; + PageHandler * writehandler[TLB_SIZE]; Bit32u phys_page[TLB_SIZE]; } tlb; #else @@ -199,8 +202,11 @@ INLINE HostPt get_tlb_read(PhysPt address) { INLINE HostPt get_tlb_write(PhysPt address) { return paging.tlb.write[address>>12]; } -INLINE PageHandler* get_tlb_handler(PhysPt address) { - return paging.tlb.handler[address>>12]; +INLINE PageHandler* get_tlb_readhandler(PhysPt address) { + return paging.tlb.readhandler[address>>12]; +} +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 */ @@ -233,8 +239,11 @@ INLINE HostPt get_tlb_read(PhysPt address) { INLINE HostPt get_tlb_write(PhysPt address) { return get_tlb_entry(address)->write; } -INLINE PageHandler* get_tlb_handler(PhysPt address) { - return get_tlb_entry(address)->handler; +INLINE PageHandler* get_tlb_readhandler(PhysPt address) { + return get_tlb_entry(address)->readhandler; +} +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 */ @@ -254,14 +263,14 @@ INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { 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_handler(address))->readb(address); + else return (Bit8u)(get_tlb_readhandler(address))->readb(address); } 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_handler(address))->readw(address); + else return (Bit16u)(get_tlb_readhandler(address))->readw(address); } else return mem_unalignedreadw(address); } @@ -269,21 +278,21 @@ 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_handler(address))->readd(address); + else return (get_tlb_readhandler(address))->readd(address); } else return mem_unalignedreadd(address); } 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_handler(address))->writeb(address,val); + else (get_tlb_writehandler(address))->writeb(address,val); } 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_handler(address))->writew(address,val); + else (get_tlb_writehandler(address))->writew(address,val); } else mem_unalignedwritew(address,val); } @@ -291,7 +300,7 @@ 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_handler(address))->writed(address,val); + else (get_tlb_writehandler(address))->writed(address,val); } else mem_unalignedwrited(address,val); } @@ -301,7 +310,7 @@ INLINE bool mem_readb_checked(PhysPt address, Bit8u * val) { if (tlb_addr) { *val=host_readb(tlb_addr+address); return false; - } else return (get_tlb_handler(address))->readb_checked(address, val); + } else return (get_tlb_readhandler(address))->readb_checked(address, val); } INLINE bool mem_readw_checked(PhysPt address, Bit16u * val) { @@ -310,7 +319,7 @@ INLINE bool mem_readw_checked(PhysPt address, Bit16u * val) { if (tlb_addr) { *val=host_readw(tlb_addr+address); return false; - } else return (get_tlb_handler(address))->readw_checked(address, val); + } else return (get_tlb_readhandler(address))->readw_checked(address, val); } else return mem_unalignedreadw_checked(address, val); } @@ -320,7 +329,7 @@ INLINE bool mem_readd_checked(PhysPt address, Bit32u * val) { if (tlb_addr) { *val=host_readd(tlb_addr+address); return false; - } else return (get_tlb_handler(address))->readd_checked(address, val); + } else return (get_tlb_readhandler(address))->readd_checked(address, val); } else return mem_unalignedreadd_checked(address, val); } @@ -329,7 +338,7 @@ INLINE bool mem_writeb_checked(PhysPt address,Bit8u val) { if (tlb_addr) { host_writeb(tlb_addr+address,val); return false; - } else return (get_tlb_handler(address))->writeb_checked(address,val); + } else return (get_tlb_writehandler(address))->writeb_checked(address,val); } INLINE bool mem_writew_checked(PhysPt address,Bit16u val) { @@ -338,7 +347,7 @@ INLINE bool mem_writew_checked(PhysPt address,Bit16u val) { if (tlb_addr) { host_writew(tlb_addr+address,val); return false; - } else return (get_tlb_handler(address))->writew_checked(address,val); + } else return (get_tlb_writehandler(address))->writew_checked(address,val); } else return mem_unalignedwritew_checked(address,val); } @@ -348,7 +357,7 @@ INLINE bool mem_writed_checked(PhysPt address,Bit32u val) { if (tlb_addr) { host_writed(tlb_addr+address,val); return false; - } else return (get_tlb_handler(address))->writed_checked(address,val); + } else return (get_tlb_writehandler(address))->writed_checked(address,val); } else return mem_unalignedwrited_checked(address,val); } diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index a1799557..5e3a6d42 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: core_dyn_x86.cpp,v 1.33 2007-10-05 17:45:52 c2woody Exp $ */ +/* $Id: core_dyn_x86.cpp,v 1.34 2007-11-24 17:26:48 c2woody Exp $ */ #include "dosbox.h" @@ -348,7 +348,7 @@ run_block: case BR_Link2: { Bitu temp_ip=SegPhys(cs)+reg_eip; - CodePageHandler * temp_handler=(CodePageHandler *)get_tlb_handler(temp_ip); + 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; diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 23a66dd0..6bc6c109 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -54,7 +54,7 @@ static bool MakeCodePage(Bitu lin_addr,CodePageHandler * &cph) { Bit8u rdval; //Ensure page contains memory: if (GCC_UNLIKELY(mem_readb_checked(lin_addr,&rdval))) return true; - PageHandler * handler=get_tlb_handler(lin_addr); + PageHandler * handler=get_tlb_readhandler(lin_addr); if (handler->flags & PFLAG_HASCODE) { cph=( CodePageHandler *)handler; return false; @@ -462,7 +462,7 @@ static void dyn_read_intro(DynReg * addr,bool release_addr=true) { } bool mem_readb_checked_dcx86(PhysPt address) { - return get_tlb_handler(address)->readb_checked(address, (Bit8u*)(&core_dyn.readdata)); + return get_tlb_readhandler(address)->readb_checked(address, (Bit8u*)(&core_dyn.readdata)); } static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { @@ -548,7 +548,7 @@ bool mem_readd_checked_dcx86(PhysPt address) { core_dyn.readdata=host_readd(tlb_addr+address); return false; } else { - return get_tlb_handler(address)->readd_checked(address, &core_dyn.readdata); + return get_tlb_readhandler(address)->readd_checked(address, &core_dyn.readdata); } } else return mem_unalignedreadd_checked(address, &core_dyn.readdata); } diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index e39bb8c8..cca2c66e 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: core_dynrec.cpp,v 1.8 2007-10-05 17:45:52 c2woody Exp $ */ +/* $Id: core_dynrec.cpp,v 1.9 2007-11-24 17:26:48 c2woody Exp $ */ #include "dosbox.h" @@ -153,7 +153,7 @@ 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_handler(temp_ip); + 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); diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index 2fb7845d..1f25c474 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -132,7 +132,7 @@ static bool MakeCodePage(Bitu lin_addr,CodePageHandlerDynRec * &cph) { //Ensure page contains memory: if (GCC_UNLIKELY(mem_readb_checked(lin_addr,&rdval))) return true; - PageHandler * handler=get_tlb_handler(lin_addr); + PageHandler * handler=get_tlb_readhandler(lin_addr); if (handler->flags & PFLAG_HASCODE) { // this is a codepage handler, and the one that we're looking for cph=(CodePageHandlerDynRec *)handler; @@ -569,7 +569,7 @@ bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) { *((Bit8u*)(&core_dynrec.readdata))=host_readb(tlb_addr+address); return false; } else { - return get_tlb_handler(address)->readb_checked(address, (Bit8u*)(&core_dynrec.readdata)); + return get_tlb_readhandler(address)->readb_checked(address, (Bit8u*)(&core_dynrec.readdata)); } } @@ -579,7 +579,7 @@ bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) { if (tlb_addr) { host_writeb(tlb_addr+address,val); return false; - } else return get_tlb_handler(address)->writeb_checked(address,val); + } else return get_tlb_writehandler(address)->writeb_checked(address,val); } bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) DRC_FC; @@ -589,7 +589,7 @@ bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) { if (tlb_addr) { *((Bit16u*)(&core_dynrec.readdata))=host_readw(tlb_addr+address); return false; - } else return get_tlb_handler(address)->readw_checked(address, (Bit16u*)(&core_dynrec.readdata)); + } else return get_tlb_readhandler(address)->readw_checked(address, (Bit16u*)(&core_dynrec.readdata)); } else return mem_unalignedreadw_checked(address, ((Bit16u*)(&core_dynrec.readdata))); } @@ -600,7 +600,7 @@ bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) { if (tlb_addr) { *((Bit32u*)(&core_dynrec.readdata))=host_readd(tlb_addr+address); return false; - } else return get_tlb_handler(address)->readd_checked(address, (Bit32u*)(&core_dynrec.readdata)); + } else return get_tlb_readhandler(address)->readd_checked(address, (Bit32u*)(&core_dynrec.readdata)); } else return mem_unalignedreadd_checked(address, ((Bit32u*)(&core_dynrec.readdata))); } @@ -611,7 +611,7 @@ bool DRC_CALL_CONV mem_writew_checked_drc(PhysPt address,Bit16u val) { if (tlb_addr) { host_writew(tlb_addr+address,val); return false; - } else return get_tlb_handler(address)->writew_checked(address,val); + } else return get_tlb_writehandler(address)->writew_checked(address,val); } else return mem_unalignedwritew_checked(address,val); } @@ -622,7 +622,7 @@ bool DRC_CALL_CONV mem_writed_checked_drc(PhysPt address,Bit32u val) { if (tlb_addr) { host_writed(tlb_addr+address,val); return false; - } else return get_tlb_handler(address)->writed_checked(address,val); + } else return get_tlb_writehandler(address)->writed_checked(address,val); } else return mem_unalignedwrited_checked(address,val); } diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 7e960e52..4dc63074 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.cpp,v 1.28 2007-10-05 17:45:52 c2woody Exp $ */ +/* $Id: paging.cpp,v 1.29 2007-11-24 17:26:48 c2woody Exp $ */ #include #include @@ -132,7 +132,7 @@ Bitu DEBUG_EnableDebugger(void); bool first=false; -void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,bool writefault,Bitu faultcode) { +void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu faultcode) { /* Save the state of the cpu cores */ LazyFlags old_lflags; memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); @@ -141,14 +141,14 @@ void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,bool writefault,Bitu faultc cpudecoder=&PageFaultCore; paging.cr2=lin_addr; PF_Entry * entry=&pf_queue.entries[pf_queue.used++]; - LOG(LOG_PAGING,LOG_NORMAL)("PageFault at %X type [%x:%x] queue %d",lin_addr,writefault,faultcode,pf_queue.used); + LOG(LOG_PAGING,LOG_NORMAL)("PageFault at %X type [%x] queue %d",lin_addr,faultcode,pf_queue.used); // LOG_MSG("EAX:%04X ECX:%04X EDX:%04X EBX:%04X",reg_eax,reg_ecx,reg_edx,reg_ebx); // LOG_MSG("CS:%04X EIP:%08X SS:%04x SP:%08X",SegValue(cs),reg_eip,SegValue(ss),reg_esp); entry->cs=SegValue(cs); entry->eip=reg_eip; entry->page_addr=page_addr; //Caused by a write by default? - CPU_Exception(14,(writefault?0x02:0x00) | faultcode); + CPU_Exception(14,faultcode); #if C_DEBUG // DEBUG_EnableDebugger(); #endif @@ -176,54 +176,57 @@ public: return mem_readd(addr); } void writeb(PhysPt addr,Bitu val) { - InitPage(addr,true); + bool needs_reset=InitPage(addr,true); mem_writeb(addr,val); + if (GCC_UNLIKELY(needs_reset)) PAGING_UnlinkPages(addr>>12,1); } void writew(PhysPt addr,Bitu val) { - InitPage(addr,true); + bool needs_reset=InitPage(addr,true); mem_writew(addr,val); + if (GCC_UNLIKELY(needs_reset)) PAGING_UnlinkPages(addr>>12,1); } void writed(PhysPt addr,Bitu val) { - InitPage(addr,true); + bool needs_reset=InitPage(addr,true); mem_writed(addr,val); + if (GCC_UNLIKELY(needs_reset)) PAGING_UnlinkPages(addr>>12,1); } bool readb_checked(PhysPt addr, Bit8u * val) { - if (InitPage(addr,false,true)) { + if (InitPageCheckOnly(addr,false)) { *val=mem_readb(addr); return false; } else return true; } bool readw_checked(PhysPt addr, Bit16u * val) { - if (InitPage(addr,false,true)){ + if (InitPageCheckOnly(addr,false)){ *val=mem_readw(addr); return false; } else return true; } bool readd_checked(PhysPt addr, Bit32u * val) { - if (InitPage(addr,false,true)) { + if (InitPageCheckOnly(addr,false)) { *val=mem_readd(addr); return false; } else return true; } bool writeb_checked(PhysPt addr,Bitu val) { - if (InitPage(addr,true,true)) { + if (InitPageCheckOnly(addr,true)) { mem_writeb(addr,val); return false; } else return true; } bool writew_checked(PhysPt addr,Bitu val) { - if (InitPage(addr,true,true)) { + if (InitPageCheckOnly(addr,true)) { mem_writew(addr,val); return false; } else return true; } bool writed_checked(PhysPt addr,Bitu val) { - if (InitPage(addr,true,true)) { + if (InitPageCheckOnly(addr,true)) { mem_writed(addr,val); return false; } else return true; } - bool InitPage(Bitu lin_addr,bool writing,bool check_only=false) { + bool InitPage(Bitu lin_addr,bool writing) { Bitu lin_page=lin_addr >> 12; Bitu phys_page; if (paging.enabled) { @@ -233,64 +236,109 @@ public: X86PageEntry table; table.load=phys_readd(table_addr); if (!table.block.p) { - if (check_only) { - paging.cr2=lin_addr; - cpu.exception.which=14; - cpu.exception.error=writing?0x02:0x00; - return false; - } LOG(LOG_PAGING,LOG_NORMAL)("NP Table"); - PAGING_PageFault(lin_addr,table_addr,false,writing?0x02:0x00); + PAGING_PageFault(lin_addr,table_addr,(writing?0x02:0x00) | ((cpu.cpl==0)?0x00:0x04)); table.load=phys_readd(table_addr); if (!table.block.p) E_Exit("Pagefault didn't correct table"); } - if (!table.block.a) { - table.block.a=1; //Set access - phys_writed(table_addr,table.load); - } X86PageEntry entry; Bitu entry_addr=(table.block.base<<12)+t_index*4; entry.load=phys_readd(entry_addr); if (!entry.block.p) { - if (check_only) { - paging.cr2=lin_addr; - cpu.exception.which=14; - cpu.exception.error=writing?0x02:0x00; - return false; - } // LOG(LOG_PAGING,LOG_NORMAL)("NP Page"); - PAGING_PageFault(lin_addr,entry_addr,false,writing?0x02:0x00); + PAGING_PageFault(lin_addr,entry_addr,(writing?0x02:0x00) | ((cpu.cpl==0)?0x00:0x04)); entry.load=phys_readd(entry_addr); if (!entry.block.p) E_Exit("Pagefault didn't correct page"); } - if (cpu.cpl==3) { -// if (((entry.block.us==0) || (table.block.us==0)) || (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { - if (((entry.block.us==0) && (table.block.us==0)) || (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { - LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); - if (check_only) { - paging.cr2=lin_addr; - cpu.exception.which=14; - cpu.exception.error=0x05 | (writing?0x02:0x00); - return false; - } - PAGING_PageFault(lin_addr,entry_addr,writing,0x05 | (writing?0x02:0x00)); - } + + // 0: no action + // 1: can (but currently does not) fail a privilege check + // 2: fails a privilege check + Bitu priv_check=0; +// if ((entry.block.us==0) || (table.block.us==0)) { + if ((entry.block.us==0) && (table.block.us==0)) { + if (cpu.cpl==3) priv_check=2; + else priv_check=1; + } + if ((entry.block.wr==0) || (table.block.wr==0)) { + priv_check=1; + if (writing && (cpu.cpl==3)) priv_check=2; + } + if (priv_check==2) { + LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); + PAGING_PageFault(lin_addr,entry_addr,0x05 | (writing?0x02:0x00)); + } + + if (!table.block.a) { + table.block.a=1; //Set access + phys_writed(table_addr,table.load); } - if (check_only) return true; if ((!entry.block.a) || (!entry.block.d)) { - entry.block.a=1; //Set access - entry.block.d=1; //Set dirty + entry.block.a=1; //Set access + if (writing) entry.block.d=1; //Set dirty phys_writed(entry_addr,entry.load); } phys_page=entry.block.base; + if (priv_check==0) PAGING_LinkPage(lin_page,phys_page); + else { + if (writing) { + PAGING_LinkPage(lin_page,phys_page); + return true; + } else { + PAGING_LinkPage_ReadOnly(lin_page,phys_page); + } + } } else { if (lin_page> 12; + if (paging.enabled) { + Bitu d_index=lin_page >> 10; + Bitu t_index=lin_page & 0x3ff; + Bitu table_addr=(paging.base.page<<12)+d_index*4; + X86PageEntry table; + table.load=phys_readd(table_addr); + if (!table.block.p) { + paging.cr2=lin_addr; + cpu.exception.which=14; + cpu.exception.error=(writing?0x02:0x00) | ((cpu.cpl==0)?0x00:0x04); + return false; + } + X86PageEntry entry; + Bitu entry_addr=(table.block.base<<12)+t_index*4; + entry.load=phys_readd(entry_addr); + if (!entry.block.p) { + paging.cr2=lin_addr; + cpu.exception.which=14; + cpu.exception.error=(writing?0x02:0x00) | ((cpu.cpl==0)?0x00:0x04); + return false; + } + + if (cpu.cpl!=3) return true; + +// if (((entry.block.us==0) || (table.block.us==0)) || (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { + if (((entry.block.us==0) && (table.block.us==0)) || (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { + LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); + paging.cr2=lin_addr; + cpu.exception.which=14; + cpu.exception.error=0x05 | (writing?0x02:0x00); + return false; + } + return true; + } else { + Bitu phys_page; + if (lin_page0;pages--) { paging.tlb.read[lin_page]=0; paging.tlb.write[lin_page]=0; - paging.tlb.handler[lin_page]=&init_page_handler; + paging.tlb.readhandler[lin_page]=&init_page_handler; + paging.tlb.writehandler[lin_page]=&init_page_handler; + lin_page++; } } @@ -353,7 +405,8 @@ void PAGING_MapPage(Bitu lin_page,Bitu phys_page) { paging.firstmb[lin_page]=phys_page; paging.tlb.read[lin_page]=0; paging.tlb.write[lin_page]=0; - paging.tlb.handler[lin_page]=&init_page_handler; + paging.tlb.readhandler[lin_page]=&init_page_handler; + paging.tlb.writehandler[lin_page]=&init_page_handler; } else { PAGING_LinkPage(lin_page,phys_page); } @@ -377,7 +430,28 @@ void PAGING_LinkPage(Bitu lin_page,Bitu phys_page) { else paging.tlb.write[lin_page]=0; paging.links.entries[paging.links.used++]=lin_page; - paging.tlb.handler[lin_page]=handler; + paging.tlb.readhandler[lin_page]=handler; + paging.tlb.writehandler[lin_page]=handler; +} + +void PAGING_LinkPage_ReadOnly(Bitu lin_page,Bitu phys_page) { + PageHandler * handler=MEM_GetPageHandler(phys_page); + Bitu lin_base=lin_page << 12; + if (lin_page>=TLB_SIZE || phys_page>=TLB_SIZE) + E_Exit("Illegal page"); + + if (paging.links.used>=PAGING_LINKS) { + LOG(LOG_PAGING,LOG_NORMAL)("Not enough paging links, resetting cache"); + PAGING_ClearTLB(); + } + + paging.tlb.phys_page[lin_page]=phys_page; + if (handler->flags & PFLAG_READABLE) paging.tlb.read[lin_page]=handler->GetHostReadPt(phys_page)-lin_base; + else paging.tlb.read[lin_page]=0; + paging.tlb.write[lin_page]=0; + + paging.links.entries[paging.links.used++]=lin_page; + paging.tlb.readhandler[lin_page]=handler; } #else @@ -386,7 +460,8 @@ static INLINE void InitTLBInt(tlb_entry *bank) { for (Bitu i=0;iread=0; entry->write=0; - entry->handler=&init_page_handler; + entry->readhandler=&init_page_handler; + entry->writehandler=&init_page_handler; } paging.links.used=0; } @@ -418,7 +494,8 @@ void PAGING_UnlinkPages(Bitu lin_page,Bitu pages) { for (;pages>0;pages--) { entry->read=0; entry->write=0; - entry->handler=&init_page_handler; + entry->readhandler=&init_page_handler; + entry->writehandler=&init_page_handler; } } @@ -427,7 +504,8 @@ void PAGING_MapPage(Bitu lin_page,Bitu phys_page) { paging.firstmb[lin_page]=phys_page; paging.tlbh[lin_page].read=0; paging.tlbh[lin_page].write=0; - paging.tlbh[lin_page].handler=&init_page_handler; + paging.tlbh[lin_page].readhandler=&init_page_handler; + paging.tlbh[lin_page].writehandler=&init_page_handler; } else { PAGING_LinkPage(lin_page,phys_page); } @@ -452,7 +530,29 @@ void PAGING_LinkPage(Bitu lin_page,Bitu phys_page) { else entry->write=0; paging.links.entries[paging.links.used++]=lin_page; - entry->handler=handler; + entry->readhandler=handler; + entry->writehandler=handler; +} + +void PAGING_LinkPage_ReadOnly(Bitu lin_page,Bitu phys_page) { + PageHandler * handler=MEM_GetPageHandler(phys_page); + Bitu lin_base=lin_page << 12; + if (lin_page>=(TLB_SIZE*(TLB_BANKS+1)) || phys_page>=(TLB_SIZE*(TLB_BANKS+1))) + E_Exit("Illegal page"); + + if (paging.links.used>=PAGING_LINKS) { + LOG(LOG_PAGING,LOG_NORMAL)("Not enough paging links, resetting cache"); + PAGING_ClearTLB(); + } + + tlb_entry *entry = get_tlb_entry(lin_base); + entry->phys_page=phys_page; + if (handler->flags & PFLAG_READABLE) entry->read=handler->GetHostReadPt(phys_page)-lin_base; + else entry->read=0; + entry->write=0; + + paging.links.entries[paging.links.used++]=lin_page; + entry->readhandler=handler; } #endif diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 7e0ec1b5..5ffb2b4c 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.89 2007-10-05 17:45:53 c2woody Exp $ */ +/* $Id: debug.cpp,v 1.90 2007-11-24 17:26:48 c2woody Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -674,7 +674,7 @@ static void DrawData(void) { else mvwprintw (dbg.win_data,1+y,0,"%04X:%08X ",dataSeg,add); for (int x=0; x<16; x++) { address = GetAddress(dataSeg,add); - if (!(get_tlb_handler(address)->flags & PFLAG_INIT)) { + if (!(get_tlb_readhandler(address)->flags & PFLAG_INIT)) { ch = mem_readb(address); } else ch = 0; mvwprintw (dbg.win_data,1+y,14+3*x,"%02X",ch); @@ -1344,7 +1344,7 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) pos++; }; Bit32u address = GetAddress(seg,adr); - if (!(get_tlb_handler(address)->flags & PFLAG_INIT)) { + if (!(get_tlb_readhandler(address)->flags & PFLAG_INIT)) { static char outmask[] = "%s:[%04X]=%02X"; if (cpu.pmode) outmask[6] = '8'; From ee3ead7b2701575b430efffb75c94b271381cf27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 26 Nov 2007 00:00:58 +0000 Subject: [PATCH 2963/4131] raise privilege level for cpu-internal supervisor level memory accesses Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3051 --- include/cpu.h | 15 +++++---------- src/cpu/cpu.cpp | 33 +++++++++++++++++++++++++++++---- src/cpu/paging.cpp | 38 +++++++++++++++++++++++--------------- 3 files changed, 57 insertions(+), 29 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index fd868341..9f0639fc 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -150,6 +150,7 @@ void CPU_SetFlags(Bitu word,Bitu mask); #define EXCEPTION_NP 11 #define EXCEPTION_SS 12 #define EXCEPTION_GP 13 +#define EXCEPTION_PF 14 #define CR0_PROTECTION 0x00000001 #define CR0_MONITORPROCESSOR 0x00000002 @@ -303,16 +304,9 @@ class Descriptor public: Descriptor() { saved.fill[0]=saved.fill[1]=0; } - void Load(PhysPt address) { - Bit32u* data = (Bit32u*)&saved; - *data = mem_readd(address); - *(data+1) = mem_readd(address+4); - } - void Save(PhysPt address) { - Bit32u* data = (Bit32u*)&saved; - mem_writed(address,*data); - mem_writed(address+4,*(data+1)); - } + 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; } @@ -433,6 +427,7 @@ public: struct CPUBlock { Bitu cpl; /* Current Privilege */ + Bitu mpl; Bitu cr0; bool pmode; /* Is Protected mode enabled */ GDTDescriptorTable gdt; diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 311e1d58..d1a71535 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.103 2007-08-09 19:52:32 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.104 2007-11-26 00:00:58 c2woody Exp $ */ #include #include @@ -110,6 +110,22 @@ void CPU_Core_Dynrec_Cache_Close(void); #endif +void Descriptor::Load(PhysPt address) { + cpu.mpl=0; + Bit32u* data = (Bit32u*)&saved; + *data = mem_readd(address); + *(data+1) = mem_readd(address+4); + cpu.mpl=3; +} +void Descriptor:: Save(PhysPt address) { + cpu.mpl=0; + Bit32u* data = (Bit32u*)&saved; + mem_writed(address,*data); + mem_writed(address+4,*(data+1)); + cpu.mpl=03; +} + + void CPU_Push16(Bitu value) { Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-2)&cpu.stack.mask); mem_writew(SegPhys(ss) + (new_esp & cpu.stack.mask) ,value); @@ -210,12 +226,16 @@ public: return valid; } Bitu Get_back(void) { - return mem_readw(base); + cpu.mpl=0; + Bit16u backlink=mem_readw(base); + cpu.mpl=3; + return backlink; } void SaveSelector(void) { cpu.gdt.SetDescriptor(selector,desc); } void Get_SSx_ESPx(Bitu level,Bitu & _ss,Bitu & _esp) { + cpu.mpl=0; if (is386) { PhysPt where=base+offsetof(TSS_32,esp0)+level*8; _esp=mem_readd(where); @@ -225,6 +245,7 @@ public: _esp=mem_readw(where); _ss=mem_readw(where+2); } + cpu.mpl=3; } bool SetSelector(Bitu new_sel) { valid=false; @@ -433,6 +454,7 @@ doconforming: bool CPU_IO_Exception(Bitu port,Bitu size) { if (cpu.pmode && ((GETFLAG_IOPL>(16-size)) << (port&7); if (map & mask) goto doexception; + cpu.mpl=3; } return false; doexception: + cpu.mpl=3; LOG(LOG_CPU,LOG_NORMAL)("IO Exception port %X",port); return CPU_PrepareException(EXCEPTION_GP,0); } @@ -497,8 +521,8 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { return; } } - Descriptor gate; + Descriptor gate; if (!cpu.idt.GetDescriptor(num<<3,gate)) { // zone66 CPU_Exception(EXCEPTION_GP,num*8+2+(type&CPU_INT_SOFTWARE)?0:1); @@ -980,8 +1004,8 @@ void CPU_CALL(bool use32,Bitu selector,Bitu offset,Bitu oldeip) { CPU_CHECK_COND((selector & 0xfffc)==0, "CALL:CS selector zero", EXCEPTION_GP,0) - Descriptor call; Bitu rpl=selector & 3; + Descriptor call; CPU_CHECK_COND(!cpu.gdt.GetDescriptor(selector,call), "CALL:CS beyond limits", EXCEPTION_GP,selector & 0xfffc) @@ -1089,6 +1113,7 @@ call_code: Bitu o_ss = SegValue(ss); PhysPt o_stack = SegPhys(ss)+(reg_esp & cpu.stack.mask); + // catch pagefaults if (call.saved.gate.paramcount&31) { if (call.Type()==DESC_386_CALL_GATE) { diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 4dc63074..ab11e3ab 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.cpp,v 1.29 2007-11-24 17:26:48 c2woody Exp $ */ +/* $Id: paging.cpp,v 1.30 2007-11-26 00:00:58 c2woody Exp $ */ #include #include @@ -102,6 +102,7 @@ struct PF_Entry { Bitu cs; Bitu eip; Bitu page_addr; + Bitu mpl; }; #define PF_QUEUESIZE 16 @@ -122,8 +123,10 @@ static Bits PageFaultCore(void) { PF_Entry * entry=&pf_queue.entries[pf_queue.used-1]; X86PageEntry pentry; pentry.load=phys_readd(entry->page_addr); - if (pentry.block.p && entry->cs == SegValue(cs) && entry->eip==reg_eip) + if (pentry.block.p && entry->cs == SegValue(cs) && entry->eip==reg_eip) { + cpu.cpl=entry->mpl; return -1; + } return 0; } #if C_DEBUG @@ -147,8 +150,9 @@ void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu faultcode) { entry->cs=SegValue(cs); entry->eip=reg_eip; entry->page_addr=page_addr; + entry->mpl=cpu.mpl; //Caused by a write by default? - CPU_Exception(14,faultcode); + CPU_Exception(EXCEPTION_PF,faultcode); #if C_DEBUG // DEBUG_EnableDebugger(); #endif @@ -237,7 +241,8 @@ public: table.load=phys_readd(table_addr); if (!table.block.p) { LOG(LOG_PAGING,LOG_NORMAL)("NP Table"); - PAGING_PageFault(lin_addr,table_addr,(writing?0x02:0x00) | ((cpu.cpl==0)?0x00:0x04)); + PAGING_PageFault(lin_addr,table_addr, + (writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04)); table.load=phys_readd(table_addr); if (!table.block.p) E_Exit("Pagefault didn't correct table"); @@ -247,7 +252,8 @@ public: entry.load=phys_readd(entry_addr); if (!entry.block.p) { // LOG(LOG_PAGING,LOG_NORMAL)("NP Page"); - PAGING_PageFault(lin_addr,entry_addr,(writing?0x02:0x00) | ((cpu.cpl==0)?0x00:0x04)); + PAGING_PageFault(lin_addr,entry_addr, + (writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04)); entry.load=phys_readd(entry_addr); if (!entry.block.p) E_Exit("Pagefault didn't correct page"); @@ -259,15 +265,16 @@ public: Bitu priv_check=0; // if ((entry.block.us==0) || (table.block.us==0)) { if ((entry.block.us==0) && (table.block.us==0)) { - if (cpu.cpl==3) priv_check=2; + if ((cpu.cpl&cpu.mpl)==3) priv_check=2; else priv_check=1; } if ((entry.block.wr==0) || (table.block.wr==0)) { priv_check=1; - if (writing && (cpu.cpl==3)) priv_check=2; + if (writing && ((cpu.cpl&cpu.mpl)==3)) priv_check=2; } if (priv_check==2) { - LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); + LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x", + cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); PAGING_PageFault(lin_addr,entry_addr,0x05 | (writing?0x02:0x00)); } @@ -307,8 +314,8 @@ public: table.load=phys_readd(table_addr); if (!table.block.p) { paging.cr2=lin_addr; - cpu.exception.which=14; - cpu.exception.error=(writing?0x02:0x00) | ((cpu.cpl==0)?0x00:0x04); + cpu.exception.which=EXCEPTION_PF; + cpu.exception.error=(writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04); return false; } X86PageEntry entry; @@ -316,18 +323,19 @@ public: entry.load=phys_readd(entry_addr); if (!entry.block.p) { paging.cr2=lin_addr; - cpu.exception.which=14; - cpu.exception.error=(writing?0x02:0x00) | ((cpu.cpl==0)?0x00:0x04); + cpu.exception.which=EXCEPTION_PF; + cpu.exception.error=(writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04); return false; } - if (cpu.cpl!=3) return true; + if ((cpu.cpl&cpu.mpl)!=3) return true; // if (((entry.block.us==0) || (table.block.us==0)) || (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { if (((entry.block.us==0) && (table.block.us==0)) || (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { - LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); + LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x", + cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); paging.cr2=lin_addr; - cpu.exception.which=14; + cpu.exception.which=EXCEPTION_PF; cpu.exception.error=0x05 | (writing?0x02:0x00); return false; } From 2b61d6eaf56c99fd62e18e6cd35e8637b72b6de5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 28 Nov 2007 23:06:54 +0000 Subject: [PATCH 2964/4131] move state commit point of pmode/v86 iret further back Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3052 --- src/cpu/cpu.cpp | 124 ++++++++++++++++++++++++++++++------------------ 1 file changed, 78 insertions(+), 46 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index d1a71535..254d15b0 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.104 2007-11-26 00:00:58 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.105 2007-11-28 23:06:54 c2woody Exp $ */ #include #include @@ -711,15 +711,29 @@ void CPU_IRET(bool use32,Bitu oldeip) { return; } else { if (use32) { - reg_eip=CPU_Pop32(); - SegSet16(cs,CPU_Pop32()); + Bit32u new_eip=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask)); + Bit32u tempesp=(reg_esp&cpu.stack.notmask)|((reg_esp+4)&cpu.stack.mask); + Bit32u new_cs=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask)); + tempesp=(tempesp&cpu.stack.notmask)|((tempesp+4)&cpu.stack.mask); + Bit32u new_flags=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask)); + reg_esp=(tempesp&cpu.stack.notmask)|((tempesp+4)&cpu.stack.mask); + + reg_eip=new_eip; + SegSet16(cs,(Bit16u)(new_cs&0xffff)); /* IOPL can not be modified in v86 mode by IRET */ - CPU_SetFlags(CPU_Pop32(),FMASK_NORMAL|FLAG_NT); + CPU_SetFlags(new_flags,FMASK_NORMAL|FLAG_NT); } else { - reg_eip=CPU_Pop16(); - SegSet16(cs,CPU_Pop16()); + Bit16u new_eip=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); + Bit32u tempesp=(reg_esp&cpu.stack.notmask)|((reg_esp+2)&cpu.stack.mask); + Bit16u new_cs=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask)); + tempesp=(tempesp&cpu.stack.notmask)|((tempesp+2)&cpu.stack.mask); + Bit16u new_flags=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask)); + reg_esp=(tempesp&cpu.stack.notmask)|((tempesp+2)&cpu.stack.mask); + + reg_eip=(Bit32u)new_eip; + SegSet16(cs,new_cs); /* IOPL can not be modified in v86 mode by IRET */ - CPU_SetFlags(CPU_Pop16(),FMASK_NORMAL|FLAG_NT); + CPU_SetFlags(new_flags,FMASK_NORMAL|FLAG_NT); } cpu.code.big=false; DestroyConditionFlags(); @@ -738,12 +752,18 @@ void CPU_IRET(bool use32,Bitu oldeip) { return; } Bitu n_cs_sel,n_eip,n_flags; + Bit32u tempesp; if (use32) { - // commit point - n_eip=CPU_Pop32(); - n_cs_sel=CPU_Pop32() & 0xffff; - n_flags=CPU_Pop32(); + n_eip=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask)); + tempesp=(reg_esp&cpu.stack.notmask)|((reg_esp+4)&cpu.stack.mask); + n_cs_sel=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask)) & 0xffff; + tempesp=(tempesp&cpu.stack.notmask)|((tempesp+4)&cpu.stack.mask); + n_flags=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask)); + tempesp=(tempesp&cpu.stack.notmask)|((tempesp+4)&cpu.stack.mask); + if ((n_flags & FLAG_VM) && (cpu.cpl==0)) { + // commit point + reg_esp=tempesp; reg_eip=n_eip & 0xffff; Bitu n_ss,n_esp,n_es,n_ds,n_fs,n_gs; n_esp=CPU_Pop32(); @@ -770,9 +790,14 @@ void CPU_IRET(bool use32,Bitu oldeip) { } if (n_flags & FLAG_VM) E_Exit("IRET from pmode to v86 with CPL!=0"); } else { - n_eip=CPU_Pop16(); - n_cs_sel=CPU_Pop16(); - n_flags=(reg_flags & 0xffff0000) | CPU_Pop16(); + n_eip=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); + tempesp=(reg_esp&cpu.stack.notmask)|((reg_esp+2)&cpu.stack.mask); + n_cs_sel=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask)); + tempesp=(tempesp&cpu.stack.notmask)|((tempesp+2)&cpu.stack.mask); + n_flags=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask)); + n_flags|=(reg_flags & 0xffff0000); + tempesp=(tempesp&cpu.stack.notmask)|((tempesp+2)&cpu.stack.mask); + if (n_flags & FLAG_VM) E_Exit("VM Flag in 16-bit iret"); } CPU_CHECK_COND((n_cs_sel & 0xfffc)==0, @@ -809,6 +834,9 @@ void CPU_IRET(bool use32,Bitu oldeip) { if (n_cs_rpl==cpu.cpl) { /* Return to same level */ + + // commit point + reg_esp=tempesp; Segs.phys[cs]=n_cs_desc.GetBase(); cpu.code.big=n_cs_desc.Big()>0; Segs.val[cs]=n_cs_sel; @@ -823,11 +851,13 @@ void CPU_IRET(bool use32,Bitu oldeip) { /* Return to outer level */ Bitu n_ss,n_esp; if (use32) { - n_esp=CPU_Pop32(); - n_ss=CPU_Pop32() & 0xffff; + n_esp=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask)); + tempesp=(tempesp&cpu.stack.notmask)|((tempesp+4)&cpu.stack.mask); + n_ss=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask)) & 0xffff; } else { - n_esp=CPU_Pop16(); - n_ss=CPU_Pop16(); + n_esp=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask)); + tempesp=(tempesp&cpu.stack.notmask)|((tempesp+2)&cpu.stack.mask); + n_ss=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask)); } CPU_CHECK_COND((n_ss & 0xfffc)==0, "IRET:Outer level:SS selector zero", @@ -855,6 +885,8 @@ void CPU_IRET(bool use32,Bitu oldeip) { "IRET:Outer level:Stack segment not present", EXCEPTION_NP,n_ss & 0xfffc) + // commit point + Segs.phys[cs]=n_cs_desc.GetBase(); cpu.code.big=n_cs_desc.Big()>0; Segs.val[cs]=n_cs_sel; @@ -883,34 +915,34 @@ void CPU_IRET(bool use32,Bitu oldeip) { // borland extender, zrdx Descriptor desc; - cpu.gdt.GetDescriptor(SegValue(es),desc); - switch (desc.Type()) { - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(es,0); break; - default: break; } - cpu.gdt.GetDescriptor(SegValue(ds),desc); - switch (desc.Type()) { - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(ds,0); break; - default: break; } - cpu.gdt.GetDescriptor(SegValue(fs),desc); - switch (desc.Type()) { - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(fs,0); break; - default: break; } - cpu.gdt.GetDescriptor(SegValue(gs),desc); - switch (desc.Type()) { - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(gs,0); break; - default: break; } + if (cpu.gdt.GetDescriptor(SegValue(es),desc)) + switch (desc.Type()) { + case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(es,0); break; + default: break; } + if (cpu.gdt.GetDescriptor(SegValue(ds),desc)) + switch (desc.Type()) { + case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(ds,0); break; + default: break; } + if (cpu.gdt.GetDescriptor(SegValue(fs),desc)) + switch (desc.Type()) { + case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(fs,0); break; + default: break; } + if (cpu.gdt.GetDescriptor(SegValue(gs),desc)) + switch (desc.Type()) { + case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(gs,0); break; + default: break; } LOG(LOG_CPU,LOG_NORMAL)("IRET:Outer level:%X:%X big %d",n_cs_sel,n_eip,cpu.code.big); } From 7ae0f48fb5290c10e0161cdad2830bf22267f727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 29 Nov 2007 21:01:46 +0000 Subject: [PATCH 2965/4131] save/restore the modified pl var Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3053 --- src/cpu/paging.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index ab11e3ab..ddce5992 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.cpp,v 1.30 2007-11-26 00:00:58 c2woody Exp $ */ +/* $Id: paging.cpp,v 1.31 2007-11-29 21:01:46 c2woody Exp $ */ #include #include @@ -124,7 +124,7 @@ static Bits PageFaultCore(void) { X86PageEntry pentry; pentry.load=phys_readd(entry->page_addr); if (pentry.block.p && entry->cs == SegValue(cs) && entry->eip==reg_eip) { - cpu.cpl=entry->mpl; + cpu.mpl=entry->mpl; return -1; } return 0; @@ -151,7 +151,8 @@ void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu faultcode) { entry->eip=reg_eip; entry->page_addr=page_addr; entry->mpl=cpu.mpl; - //Caused by a write by default? + cpu.mpl=3; + CPU_Exception(EXCEPTION_PF,faultcode); #if C_DEBUG // DEBUG_EnableDebugger(); From abbf10093fccecf71afa4ccb371fab084c4bc238 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 6 Dec 2007 17:44:19 +0000 Subject: [PATCH 2966/4131] small bugfix by hal. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3054 --- include/serialport.h | 4 ++-- src/dos/dos.cpp | 5 +++-- src/hardware/serialport/serialport.cpp | 15 ++++++++------- src/ints/bios.cpp | 5 ++--- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/include/serialport.h b/include/serialport.h index bc55b0cd..7ed273d8 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.h,v 1.14 2007-01-13 08:35:49 qbix79 Exp $ */ +/* $Id: serialport.h,v 1.15 2007-12-06 17:44:19 qbix79 Exp $ */ #ifndef DOSBOX_SERIALPORT_H #define DOSBOX_SERIALPORT_H @@ -167,7 +167,7 @@ public: void Init_Registers(); bool Putchar(Bit8u data, bool wait_dtr, bool wait_rts, Bitu timeout); - bool Getchar(Bit8u* data, bool wait_dsr, Bitu timeout); + bool Getchar(Bit8u* data, Bit8u* lsr, bool wait_dsr, Bitu timeout); private: diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 807c2b94..726c4037 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.106 2007-11-18 10:30:12 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.107 2007-12-06 17:44:19 qbix79 Exp $ */ #include #include @@ -83,9 +83,10 @@ static Bitu DOS_21Handler(void) { { Bit16u port = real_readw(0x40,0); if(port!=0 && serialports[0]) { + Bit8u status; // RTS/DTR on IO_WriteB(port+4,0x3); - serialports[0]->Getchar(®_al,true, 0xFFFFFFFF); + serialports[0]->Getchar(®_al, &status, true, 0xFFFFFFFF); } } break; diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index e535ed0f..25ea520c 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.cpp,v 1.7 2007-02-22 08:41:16 qbix79 Exp $ */ +/* $Id: serialport.cpp,v 1.8 2007-12-06 17:44:19 qbix79 Exp $ */ #include #include @@ -44,7 +44,8 @@ bool device_COM::Read(Bit8u * data,Bit16u * size) { sclass->Write_MCR(0x03); for (Bit16u i=0; i<*size; i++) { - if(!(sclass->Getchar(&data[i],true,1000))) { + Bit8u status; + if(!(sclass->Getchar(&data[i],&status,true,1000))) { *size=i; return true; } @@ -1082,7 +1083,7 @@ CSerial::~CSerial(void) { for(Bitu i = 0; i <= SERIAL_BASE_EVENT_COUNT; i++) removeEvent(i); }; -bool CSerial::Getchar(Bit8u* data, bool wait_dsr, Bitu timeout) { +bool CSerial::Getchar(Bit8u* data, Bit8u* lsr, bool wait_dsr, Bitu timeout) { double starttime=PIC_FullIndex(); // wait for it to become empty @@ -1093,19 +1094,19 @@ bool CSerial::Getchar(Bit8u* data, bool wait_dsr, Bitu timeout) { if(!(starttime>PIC_FullIndex()-timeout)) { #if SERIAL_DEBUG if(dbg_aux) - fprintf(debugfp,"%12.3f API read timeout: MSR 0x%x\r\n", PIC_FullIndex(),Read_MSR()); + fprintf(debugfp,"%12.3f Getchar status timeout: MSR 0x%x\r\n", PIC_FullIndex(),Read_MSR()); #endif return false; } } // wait for a byte to arrive - while((!(Read_LSR()&0x1))&&(starttime>PIC_FullIndex()-timeout)) + while((!((*lsr=Read_LSR())&0x1))&&(starttime>PIC_FullIndex()-timeout)) CALLBACK_Idle(); if(!(starttime>PIC_FullIndex()-timeout)) { #if SERIAL_DEBUG if(dbg_aux) - fprintf(debugfp,"%12.3f API read timeout: MSR 0x%x\r\n", PIC_FullIndex(),Read_MSR()); + fprintf(debugfp,"%12.3f Getchar data timeout: MSR 0x%x\r\n", PIC_FullIndex(),Read_MSR()); #endif return false; } @@ -1146,7 +1147,7 @@ bool CSerial::Putchar(Bit8u data, bool wait_dsr, bool wait_cts, Bitu timeout) { if(!(starttime>PIC_FullIndex()-timeout)) { #if SERIAL_DEBUG if(dbg_aux) - fprintf(debugfp,"%12.3f API write timeout: MSR 0x%x\r\n", + fprintf(debugfp,"%12.3f Putchar timeout: MSR 0x%x\r\n", PIC_FullIndex(),Read_MSR()); #endif return false; diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index d1c9467e..48797316 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.69 2007-09-20 16:42:43 c2woody Exp $ */ +/* $Id: bios.cpp,v 1.70 2007-12-06 17:44:18 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -431,7 +431,6 @@ static Bitu INT14_Handler(void) // get result reg_ah=IO_ReadB(port+5); if(timeout) reg_ah |= 0x80; - reg_al=IO_ReadB(port+6); } CALLBACK_SCF(false); } @@ -445,7 +444,7 @@ static Bitu INT14_Handler(void) // switch modem lines on IO_WriteB(port+4,0x3); // wait for something - timeout = !serialports[reg_dx]->Getchar(&buffer,true, + timeout = !serialports[reg_dx]->Getchar(&buffer,®_ah,true, mem_readb(BIOS_COM1_TIMEOUT+reg_dx)*1000); // RTS off From 26722f8d4ebd31da008383c83003fccc0d71ee46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 7 Dec 2007 20:49:19 +0000 Subject: [PATCH 2967/4131] better segment clearing for iret/retf (outer level returns) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3055 --- src/cpu/cpu.cpp | 107 ++++++++++++++++++++++-------------------------- 1 file changed, 48 insertions(+), 59 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 254d15b0..b7441482 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.105 2007-11-28 23:06:54 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.106 2007-12-07 20:49:19 c2woody Exp $ */ #include #include @@ -217,6 +217,50 @@ bool CPU_PUSHF(Bitu use32) { return false; } +void CPU_CheckSegments(void) { + bool needs_invalidation=false; + Descriptor desc; + if (!cpu.gdt.GetDescriptor(SegValue(es),desc)) needs_invalidation=true; + else switch (desc.Type()) { + case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl>desc.DPL()) needs_invalidation=true; break; + default: break; } + if (needs_invalidation) CPU_SetSegGeneral(es,0); + + needs_invalidation=false; + if (!cpu.gdt.GetDescriptor(SegValue(ds),desc)) needs_invalidation=true; + else switch (desc.Type()) { + case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl>desc.DPL()) needs_invalidation=true; break; + default: break; } + if (needs_invalidation) CPU_SetSegGeneral(ds,0); + + needs_invalidation=false; + if (!cpu.gdt.GetDescriptor(SegValue(fs),desc)) needs_invalidation=true; + else switch (desc.Type()) { + case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl>desc.DPL()) needs_invalidation=true; break; + default: break; } + if (needs_invalidation) CPU_SetSegGeneral(fs,0); + + needs_invalidation=false; + if (!cpu.gdt.GetDescriptor(SegValue(gs),desc)) needs_invalidation=true; + else switch (desc.Type()) { + case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: + case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl>desc.DPL()) needs_invalidation=true; break; + default: break; } + if (needs_invalidation) CPU_SetSegGeneral(gs,0); +} + + class TaskStateSegment { public: TaskStateSegment() { @@ -914,35 +958,7 @@ void CPU_IRET(bool use32,Bitu oldeip) { } // borland extender, zrdx - Descriptor desc; - if (cpu.gdt.GetDescriptor(SegValue(es),desc)) - switch (desc.Type()) { - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(es,0); break; - default: break; } - if (cpu.gdt.GetDescriptor(SegValue(ds),desc)) - switch (desc.Type()) { - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(ds,0); break; - default: break; } - if (cpu.gdt.GetDescriptor(SegValue(fs),desc)) - switch (desc.Type()) { - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(fs,0); break; - default: break; } - if (cpu.gdt.GetDescriptor(SegValue(gs),desc)) - switch (desc.Type()) { - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(gs,0); break; - default: break; } + CPU_CheckSegments(); LOG(LOG_CPU,LOG_NORMAL)("IRET:Outer level:%X:%X big %d",n_cs_sel,n_eip,cpu.code.big); } @@ -1410,35 +1426,7 @@ RET_same_level: reg_sp=(n_esp & 0xffff)+bytes; } - Descriptor desc; - cpu.gdt.GetDescriptor(SegValue(es),desc); - switch (desc.Type()) { - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(es,0); break; - default: break; } - cpu.gdt.GetDescriptor(SegValue(ds),desc); - switch (desc.Type()) { - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(ds,0); break; - default: break; } - cpu.gdt.GetDescriptor(SegValue(fs),desc); - switch (desc.Type()) { - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(fs,0); break; - default: break; } - cpu.gdt.GetDescriptor(SegValue(gs),desc); - switch (desc.Type()) { - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(gs,0); break; - default: break; } + CPU_CheckSegments(); // LOG(LOG_MISC,LOG_ERROR)("RET - Higher level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL()); return; @@ -2220,6 +2208,7 @@ public: } CPU_CycleAutoAdjust=false; } + CPU_CycleUp=section->Get_int("cycleup"); CPU_CycleDown=section->Get_int("cycledown"); const char * core=section->Get_string("core"); From 57da409fe7d7a6c7e3aa452dc206bd1baedee1ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 8 Dec 2007 10:24:41 +0000 Subject: [PATCH 2968/4131] certain segment loading parameters are invalid (normal core); add hlt entry in 32bit addressing mode (full core) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3056 --- src/cpu/core_full/optable.h | 2 +- src/cpu/core_normal/prefix_0f.h | 12 +++++++++--- src/cpu/core_normal/prefix_66.h | 8 ++++++-- src/cpu/core_normal/prefix_66_0f.h | 12 +++++++++--- src/cpu/core_normal/prefix_none.h | 8 ++++++-- 5 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 1d21d4b5..93c51057 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -528,7 +528,7 @@ static OpCode OpCodeTable[1024]={ /* 0x2f0 - 0x2f7 */ {D_LOCK ,0 ,0 ,0 },{D_ICEBP ,0 ,0 ,0 }, {L_PREREPNE ,0 ,0 ,0 },{L_PREREP ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{D_CMC ,0 ,0 ,0 }, +{D_HLT ,0 ,0 ,0 },{D_CMC ,0 ,0 ,0 }, {L_MODRM ,8 ,0 ,M_GRP },{L_MODRM ,0xa ,0 ,M_GRP }, /* 0x2f8 - 0x2ff */ {D_CLC ,0 ,0 ,0 },{D_STC ,0 ,0 ,0 }, diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 0f229830..16397144 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -344,7 +344,9 @@ break; CASE_0F_W(0xb2) /* LSS Ew */ { - GetRMrw;GetEAa; + GetRMrw; + if (rm >= 0xc0) goto illegal_opcode; + GetEAa; if (CPU_SetSegGeneral(ss,LoadMw(eaa+2))) RUNEXCEPTION(); *rmrw=LoadMw(eaa); break; @@ -367,14 +369,18 @@ } CASE_0F_W(0xb4) /* LFS Ew */ { - GetRMrw;GetEAa; + GetRMrw; + if (rm >= 0xc0) goto illegal_opcode; + GetEAa; if (CPU_SetSegGeneral(fs,LoadMw(eaa+2))) RUNEXCEPTION(); *rmrw=LoadMw(eaa); break; } CASE_0F_W(0xb5) /* LGS Ew */ { - GetRMrw;GetEAa; + GetRMrw; + if (rm >= 0xc0) goto illegal_opcode; + GetEAa; if (CPU_SetSegGeneral(gs,LoadMw(eaa+2))) RUNEXCEPTION(); *rmrw=LoadMw(eaa); break; diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index f2aef294..473248e1 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -462,14 +462,18 @@ continue; CASE_D(0xc4) /* LES */ { - GetRMrd;GetEAa; + GetRMrd; + if (rm >= 0xc0) goto illegal_opcode; + GetEAa; if (CPU_SetSegGeneral(es,LoadMw(eaa+4))) RUNEXCEPTION(); *rmrd=LoadMd(eaa); break; } CASE_D(0xc5) /* LDS */ { - GetRMrd;GetEAa; + GetRMrd; + if (rm >= 0xc0) goto illegal_opcode; + GetEAa; if (CPU_SetSegGeneral(ds,LoadMw(eaa+4))) RUNEXCEPTION(); *rmrd=LoadMd(eaa); break; diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 8c00c268..6c5318cd 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -237,7 +237,9 @@ } CASE_0F_D(0xb2) /* LSS Ed */ { - GetRMrd;GetEAa; + GetRMrd; + if (rm >= 0xc0) goto illegal_opcode; + GetEAa; if (CPU_SetSegGeneral(ss,LoadMw(eaa+4))) RUNEXCEPTION(); *rmrd=LoadMd(eaa); break; @@ -260,14 +262,18 @@ } CASE_0F_D(0xb4) /* LFS Ed */ { - GetRMrd;GetEAa; + GetRMrd; + if (rm >= 0xc0) goto illegal_opcode; + GetEAa; if (CPU_SetSegGeneral(fs,LoadMw(eaa+4))) RUNEXCEPTION(); *rmrd=LoadMd(eaa); break; } CASE_0F_D(0xb5) /* LGS Ed */ { - GetRMrd;GetEAa; + GetRMrd; + if (rm >= 0xc0) goto illegal_opcode; + GetEAa; if (CPU_SetSegGeneral(gs,LoadMw(eaa+4))) RUNEXCEPTION(); *rmrd=LoadMd(eaa); break; diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 9622294f..deeeba3c 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -687,14 +687,18 @@ continue; CASE_W(0xc4) /* LES */ { - GetRMrw;GetEAa; + GetRMrw; + if (rm >= 0xc0) goto illegal_opcode; + GetEAa; if (CPU_SetSegGeneral(es,LoadMw(eaa+2))) RUNEXCEPTION(); *rmrw=LoadMw(eaa); break; } CASE_W(0xc5) /* LDS */ { - GetRMrw;GetEAa; + GetRMrw; + if (rm >= 0xc0) goto illegal_opcode; + GetEAa; if (CPU_SetSegGeneral(ds,LoadMw(eaa+2))) RUNEXCEPTION(); *rmrw=LoadMw(eaa); break; From 60419734aaea140df2ddd9e9b2c96d7a55e48c12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 8 Dec 2007 15:43:30 +0000 Subject: [PATCH 2969/4131] allow more than one seg override prefix, certain segment loading parameters are invalid (recompiling cores) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3057 --- src/cpu/core_dyn_x86/decoder.h | 32 ++++++++++++++++++++------- src/cpu/core_dynrec/decoder.h | 27 ++++++++++++++++++---- src/cpu/core_dynrec/decoder_opcodes.h | 3 +-- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 6bc6c109..8ef2330a 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1589,8 +1589,7 @@ static void dyn_load_seg(SegNames seg,DynReg * src) { } static void dyn_load_seg_off_ea(SegNames seg) { - dyn_get_modrm(); - if (GCC_UNLIKELY(decode.modrm.mod<3)) { + if (decode.modrm.mod<3) { dyn_fill_ea(); gen_lea(DREG(TMPB),DREG(EA),0,0,decode.big_op ? 4:2); dyn_read_word(DREG(TMPB),DREG(TMPB),false); @@ -1666,7 +1665,7 @@ static void dyn_leave(void) { } static void dyn_segprefix(SegNames seg) { - if (GCC_UNLIKELY((Bitu)(decode.segprefix))) IllegalOption("dyn_segprefix"); +// if (GCC_UNLIKELY((Bitu)(decode.segprefix))) IllegalOption("dyn_segprefix"); decode.segprefix=&DynRegs[G_ES+seg]; } @@ -1988,8 +1987,16 @@ restart_prefix: /* Imul Ev,Gv */ case 0xaf:dyn_imul_gvev(0);break; /* LFS,LGS */ - case 0xb4:dyn_load_seg_off_ea(fs);break; - case 0xb5:dyn_load_seg_off_ea(gs);break; + case 0xb4: + dyn_get_modrm(); + if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode; + dyn_load_seg_off_ea(fs); + break; + case 0xb5: + dyn_get_modrm(); + if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode; + dyn_load_seg_off_ea(gs); + break; /* MOVZX Gv,Eb/Ew */ case 0xb6:dyn_mov_ev_gb(false);break; case 0xb7:dyn_mov_ev_gw(false);break; @@ -2240,9 +2247,18 @@ restart_prefix: //RET near Iw / Ret case 0xc2:dyn_ret_near(decode_fetchw());goto finish_block; case 0xc3:dyn_ret_near(0);goto finish_block; - //LES/LDS - case 0xc4:dyn_load_seg_off_ea(es);break; - case 0xc5:dyn_load_seg_off_ea(ds);break; + //LES + case 0xc4: + dyn_get_modrm(); + if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode; + dyn_load_seg_off_ea(es); + break; + //LDS + case 0xc5: + dyn_get_modrm(); + if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode; + dyn_load_seg_off_ea(ds); + break; // MOV Eb/Ev,Ib/Iv case 0xc6:dyn_mov_ebib();break; case 0xc7:dyn_mov_eviv();break; diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h index 143e50a1..76603912 100644 --- a/src/cpu/core_dynrec/decoder.h +++ b/src/cpu/core_dynrec/decoder.h @@ -218,8 +218,18 @@ restart_prefix: case 0xaf:dyn_imul_gvev(0);break; - case 0xb4:dyn_load_seg_off_ea(DRC_SEG_FS);break; - case 0xb5:dyn_load_seg_off_ea(DRC_SEG_GS);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; @@ -413,8 +423,17 @@ restart_prefix: case 0xc2:dyn_ret_near(decode_fetchw());goto finish_block; case 0xc3:dyn_ret_near(0);goto finish_block; - case 0xc4:dyn_load_seg_off_ea(DRC_SEG_ES);break; - case 0xc5:dyn_load_seg_off_ea(DRC_SEG_DS);break; + // 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; diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index 1771f989..cbf0625e 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -453,7 +453,7 @@ static void dyn_pop_ev(void) { static void dyn_segprefix(Bit8u seg) { - if (GCC_UNLIKELY(decode.seg_prefix_used)) IllegalOptionDynrec("dyn_segprefix"); +// if (GCC_UNLIKELY(decode.seg_prefix_used)) IllegalOptionDynrec("dyn_segprefix"); decode.seg_prefix=seg; decode.seg_prefix_used=true; } @@ -472,7 +472,6 @@ static void dyn_segprefix(Bit8u seg) { } static void dyn_load_seg_off_ea(Bit8u seg) { - dyn_get_modrm(); if (decode.modrm.mod<3) { dyn_fill_ea(FC_ADDR); gen_protect_addr_reg(); From f87fc498091658aaf609c4b37f5d2ad1f58fbf45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 9 Dec 2007 17:02:55 +0000 Subject: [PATCH 2970/4131] add scanline-precise changeability of some vga features (hal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3058 --- include/vga.h | 3 + src/hardware/pic.cpp | 4 +- src/hardware/vga.cpp | 4 + src/hardware/vga_crtc.cpp | 4 +- src/hardware/vga_dac.cpp | 10 ++ src/hardware/vga_draw.cpp | 240 +++++++++++++++++++++++++++++++++++--- 6 files changed, 244 insertions(+), 21 deletions(-) diff --git a/include/vga.h b/include/vga.h index 6e080aae..582f9b7b 100644 --- a/include/vga.h +++ b/include/vga.h @@ -129,6 +129,7 @@ typedef struct { double vdend, vtotal; double hdend, htotal; double parts; + double virtline; } delay; double aspect_ratio; bool double_scan; @@ -318,6 +319,7 @@ typedef struct { Bitu first_changed; Bit8u combine[16]; RGBEntry rgb[0x100]; + Bit16u xlat16[256]; } VGA_Dac; typedef struct { @@ -354,6 +356,7 @@ typedef struct { typedef struct { VGAModes mode; /* The mode the vga system is in */ VGAModes lastmode; + Bits screenflip; Bit8u misc_output; VGA_Draw draw; VGA_Config config; diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index f44037b1..6c00de53 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.41 2007-06-12 20:22:08 c2woody Exp $ */ +/* $Id: pic.cpp,v 1.42 2007-12-09 17:02:55 c2woody Exp $ */ #include @@ -28,7 +28,7 @@ #include "timer.h" #include "setup.h" -#define PIC_QUEUESIZE 128 +#define PIC_QUEUESIZE 512 struct IRQ_Block { bool masked; diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 1ef5192b..dd6cdb83 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -18,6 +18,7 @@ #include "dosbox.h" +//#include "setup.h" #include "video.h" #include "pic.h" #include "vga.h" @@ -148,6 +149,9 @@ void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3) { } void VGA_Init(Section* sec) { +// Section_prop * section=static_cast(sec); +// vga.screenflip = section->Get_int("screenflip"); + vga.screenflip = 0; vga.draw.resizing=false; vga.mode=M_ERROR; //For first init VGA_SetupMemory(); diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 58f81b80..c2e3e1b0 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -138,7 +138,9 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { case 0x09: /* Maximum Scan Line Register */ if (IS_VGA_ARCH) vga.config.line_compare=(vga.config.line_compare & 0x5ff)|(val&0x40)<<3; - if ((vga.crtc.maximum_scan_line ^ val) & 0xbf) { + + // don't call resize on doublescan change (magic.exe by European Technology) + if ((vga.crtc.maximum_scan_line ^ val) & ((svgaCard==SVGA_None)?0x3f:0xbf)) { crtc(maximum_scan_line)=val; VGA_StartResize(); } else crtc(maximum_scan_line)=val; diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index d568eec0..80dc7196 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -52,6 +52,9 @@ enum {DAC_READ,DAC_WRITE}; static INLINE void VGA_DAC_UpdateColor( Bitu index ) { Bitu maskIndex = index & vga.dac.pel_mask; + vga.dac.xlat16[index] = ((vga.dac.rgb[maskIndex].blue>>1)&0x1f) | + (((vga.dac.rgb[maskIndex].green)&0x3f)<<5)| + (((vga.dac.rgb[maskIndex].red>>1)&0x1f) << 11); RENDER_SetPal( index, vga.dac.rgb[maskIndex].red << 2, vga.dac.rgb[maskIndex].green << 2, @@ -126,6 +129,10 @@ static void write_p3c9(Bitu port,Bitu val,Bitu iolen) { /* Check for attributes and DAC entry link */ for (Bitu i=0;i<16;i++) { if (vga.dac.combine[i]==vga.dac.write_index) { + vga.dac.xlat16[i] = ( + (vga.dac.rgb[vga.dac.write_index].blue>>1)&0x1f) | + (((vga.dac.rgb[vga.dac.write_index].green)&0x3f)<<5)| + (((vga.dac.rgb[vga.dac.write_index].red>>1)&0x1f) << 11); RENDER_SetPal(i, vga.dac.rgb[vga.dac.write_index].red << 2, vga.dac.rgb[vga.dac.write_index].green << 2, @@ -176,6 +183,9 @@ void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal) { case M_LIN8: break; default: + vga.dac.xlat16[attr] = ((vga.dac.rgb[pal].blue>>1)&0x1f) | + (((vga.dac.rgb[pal].green)&0x3f)<<5)| + (((vga.dac.rgb[pal].red>>1)&0x1f) << 11); RENDER_SetPal(attr, vga.dac.rgb[pal].red << 2, vga.dac.rgb[pal].green << 2, diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 842ec49a..251cedfb 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.87 2007-10-14 13:12:19 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.88 2007-12-09 17:02:55 c2woody Exp $ */ #include #include @@ -178,6 +178,23 @@ static Bit8u * VGA_Draw_Linear_Line(Bitu vidstart, Bitu line) { return ret; } +static Bit8u * VGA_Draw_Xlat16_Linear_Line(Bitu vidstart, Bitu line) { + Bit8u *ret = &vga.draw.linear_base[ vidstart & vga.draw.linear_mask ]; + Bit16u* temps = (Bit16u*) TempLine; + for(Bitu i = 0; i < vga.draw.line_length; i++) { + temps[i]=vga.dac.xlat16[ret[i]]; + } + return TempLine; + /* +#if !defined(C_UNALIGNED_MEMORY) + if (GCC_UNLIKELY( ((Bitu)ret) & (sizeof(Bitu)-1)) ) { + memcpy( TempLine, ret, vga.draw.line_length ); + return TempLine; + } +#endif + return ret;*/ +} + //Test version, might as well keep it static Bit8u * VGA_Draw_Chain_Line(Bitu vidstart, Bitu line) { Bitu i = 0; @@ -409,6 +426,44 @@ skip_cursor: return TempLine; } +static Bit8u * VGA_TEXT_Xlat16_Draw_Line(Bitu vidstart, Bitu line) { + Bits font_addr; + Bit16u * draw=(Bit16u *)TempLine; + const Bit8u *vidmem = &vga.tandy.draw_base[vidstart]; + for (Bitu cx=0;cx> 3)&1][chr*32+line]; + Bit32u mask1=TXT_Font_Table[font>>4] & FontMask[col >> 7]; + Bit32u mask2=TXT_Font_Table[font&0xf] & FontMask[col >> 7]; + Bit32u fg=TXT_FG_Table[col&0xf]; + Bit32u bg=TXT_BG_Table[col>>4]; + + mask1=fg&mask1 | bg&~mask1; + mask2=fg&mask2 | bg&~mask2; + + for(int i = 0; i < 4; i++) { + *draw++ = vga.dac.xlat16[(mask1>>8*i)&0xff]; + } + for(int i = 0; i < 4; i++) { + *draw++ = vga.dac.xlat16[(mask2>>8*i)&0xff]; + } + } + if (!vga.draw.cursor.enabled || !(vga.draw.cursor.count&0x8)) goto skip_cursor; + font_addr = (vga.draw.cursor.address-vidstart) >> 1; + if (font_addr>=0 && font_addr<(Bits)vga.draw.blocks) { + if (linevga.draw.cursor.eline) goto skip_cursor; + draw=(Bit16u *)&TempLine[font_addr*16]; + Bit8u att=(Bit8u)(TXT_FG_Table[vga.tandy.draw_base[vga.draw.cursor.address+1]&0xf]&0xff); + for(int i = 0; i < 8; i++) { + *draw++ = vga.dac.xlat16[att]; + } + } +skip_cursor: + return TempLine; +} + static Bit8u * VGA_TEXT_Draw_Line_9(Bitu vidstart, Bitu line) { Bits font_addr; Bit8u * draw=(Bit8u *)TempLine; @@ -447,7 +502,7 @@ static Bit8u * VGA_TEXT_Draw_Line_9(Bitu vidstart, Bitu line) { *draw++=(font&0x02)?fg:bg; Bit8u last=(font&0x01)?fg:bg; *draw++=last; - *draw++=((chr<0xc0) || (chr>0xdf)) ? bg : last; + *draw++=((vga.attr.mode_control&0x04) && ((chr<0xc0) || (chr>0xdf))) ? bg : last; if (pel_pan) { if (underline && ((col&0x07) == 0x01)) font=0xff; else font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<=vga.draw.split_line)) pel_pan=0; + const Bit8u *vidmem = &vga.tandy.draw_base[vidstart]; + Bit8u chr=vidmem[0]; + Bit8u col=vidmem[1]; + Bit8u font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<>4]&0xff); + Bitu draw_blocks=vga.draw.blocks; + draw_blocks++; + for (Bitu cx=1;cx>(8-pel_pan); + else font|=vga.draw.font_tables[(col >> 3)&1][chr*32+line]>>(8-pel_pan); + fg=col&0xf; + bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff); + } else { + chr=vidmem[(cx-1)*2]; + col=vidmem[(cx-1)*2+1]; + if (underline && ((col&0x07) == 0x01)) font=0xff; + else font=vga.draw.font_tables[(col >> 3)&1][chr*32+line]; + fg=col&0xf; + bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff); + } + if (FontMask[col>>7]==0) font=0; + Bit8u mask=0x80; + for(int i = 0; i < 8; i++) { + *draw++= vga.dac.xlat16[font&mask?fg:bg]; + mask>>=1; + } + *draw++=(((vga.attr.mode_control&0x04) && ((chr<0xc0) || (chr>0xdf))) && + !(underline && ((col&0x07) == 0x01))) ? + (vga.dac.xlat16[bg]) : draw[-1]; + if (pel_pan) { + if (underline && ((col&0x07) == 0x01)) font=0xff; + else font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<> 1; + if (font_addr>=0 && font_addr<(Bits)vga.draw.blocks) { + if (linevga.draw.cursor.eline) goto skip_cursor; + draw=(Bit16u*)&TempLine[font_addr*18]; + Bit8u fg=vga.tandy.draw_base[vga.draw.cursor.address+1]&0xf; + for(int i = 0; i < 8; i++) { + *draw++ = vga.dac.xlat16[fg]; + } + //if(underline && ((col&0x07) == 0x01)) + // *draw = vga.dac.xlat16[fg]; + } +skip_cursor: + return TempLine; +} + static void VGA_VerticalDisplayEnd(Bitu val) { // vga.config.retrace=true; vga.config.real_start=vga.config.display_start & ((2*1024*1024)-1); @@ -494,6 +611,40 @@ static INLINE void VGA_ChangesEnd(void ) { #endif +static void VGA_DrawSingleLine(Bitu blah) { + if(vga.attr.enabled || (!(vga.mode==M_VGA || vga.mode==M_EGA))) { + Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line ); + // Magic Circle last part + if((vga.crtc.maximum_scan_line & 0x80)&& !vga.draw.doubleheight) + RENDER_DrawLine(data); + RENDER_DrawLine(data); + } else { + // else draw overscan color line + // TODO: black line should be good enough for now + // (DoWhackaDo) + memset(TempLine, 0, sizeof(TempLine)); + if((vga.crtc.maximum_scan_line & 0x80)&& !vga.draw.doubleheight) + RENDER_DrawLine(TempLine); + RENDER_DrawLine(TempLine); + } + + vga.draw.address_line++; + if (vga.draw.address_line>=vga.draw.address_line_total) { + vga.draw.address_line=0; + vga.draw.address+=vga.draw.address_add; + } + vga.draw.lines_done++; + if (vga.draw.split_line==vga.draw.lines_done) { + vga.draw.address=0; + if(!(vga.attr.mode_control&0x20)) + vga.draw.address += vga.config.pel_panning; + vga.draw.address_line=0; + } + if ((vga.draw.lines_done < vga.draw.lines_total) && (!vga.draw.resizing)) { + PIC_AddEvent(VGA_DrawSingleLine,(float)vga.draw.delay.virtline); + } else RENDER_EndUpdate(); +} + static void VGA_DrawPart(Bitu lines) { while (lines--) { Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line ); @@ -568,29 +719,61 @@ static void INLINE VGA_ChangesStart( void ) { static void VGA_VerticalTimer(Bitu val) { + + /* + // Panic plasma appears more stable with this variant + vga.draw.delay.framestart += vga.draw.delay.vtotal; + double error = PIC_FullIndex()-vga.draw.delay.framestart; + //vga.draw.delay.framestart = PIC_FullIndex(); + //error = vga.draw.delay.framestart - error - vga.draw.delay.vtotal; + //if (abs(error) > 0.001 ) LOG_MSG("vgaerror: %f",error); + + //PIC_RemoveEvents(VGA_VerticalDisplayEnd); + PIC_AddEvent( VGA_VerticalTimer, (float)vga.draw.delay.vtotal - error); + double flip_offset = vga.screenflip/1000.0 + vga.draw.delay.vrstart; + if(flip_offset > vga.draw.delay.vtotal) { + VGA_VerticalDisplayEnd(0); + } else PIC_AddEvent( VGA_VerticalDisplayEnd, + (float)(flip_offset - error)); +*/ double error = vga.draw.delay.framestart; vga.draw.delay.framestart = PIC_FullIndex(); error = vga.draw.delay.framestart - error - vga.draw.delay.vtotal; // if (abs(error) > 0.001 ) // LOG_MSG("vgaerror: %f",error); PIC_AddEvent( VGA_VerticalTimer, (float)vga.draw.delay.vtotal ); - PIC_AddEvent( VGA_VerticalDisplayEnd, (float)vga.draw.delay.vrstart ); - if ( GCC_UNLIKELY( vga.draw.parts_left )) { - LOG(LOG_VGAMISC,LOG_NORMAL)( "Parts left: %d", vga.draw.parts_left ); - PIC_RemoveEvents( &VGA_DrawPart ); - RENDER_EndUpdate(); - vga.draw.parts_left = 0; + //PIC_AddEvent( VGA_VerticalDisplayEnd, (float)vga.draw.delay.vrstart ); + double flip_offset = vga.screenflip/1000.0 + vga.draw.delay.vrstart; + if(flip_offset > vga.draw.delay.vtotal) { + VGA_VerticalDisplayEnd(0); + } else PIC_AddEvent( VGA_VerticalDisplayEnd,(float)flip_offset); + + if ( GCC_UNLIKELY( vga.draw.parts_left)) { + if (!IS_VGA_ARCH || (svgaCard!=SVGA_None)) { + LOG(LOG_VGAMISC,LOG_NORMAL)( "Parts left: %d", vga.draw.parts_left ); + PIC_RemoveEvents( &VGA_DrawPart ); + RENDER_EndUpdate(); + vga.draw.parts_left = 0; + } } //Check if we can actually render, else skip the rest if (!RENDER_StartUpdate()) return; + if ( GCC_UNLIKELY( vga.draw.lines_done < vga.draw.lines_total)) { + if (IS_VGA_ARCH && (svgaCard==SVGA_None)) { + while(vga.draw.lines_done < vga.draw.lines_total) + VGA_DrawSingleLine(0); + PIC_RemoveEvents(VGA_DrawSingleLine); + } + } //TODO Maybe check for an active frame on parts_left and clear that first? vga.draw.parts_left = vga.draw.parts_total; vga.draw.lines_done = 0; // vga.draw.address=vga.config.display_start; - vga.draw.address = vga.config.real_start; vga.draw.address_line = vga.config.hlines_skip; vga.draw.split_line = (vga.config.line_compare/vga.draw.lines_scaled); + if (vga.draw.split_line==0) vga.draw.address = 0; + else vga.draw.address = vga.config.real_start; // go figure... if (machine==MCH_EGA) vga.draw.split_line*=2; // if (machine==MCH_EGA) vga.draw.split_line = ((((vga.config.line_compare&0x5ff)+1)*2-1)/vga.draw.lines_scaled); @@ -642,15 +825,17 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.address *= 2; break; } - //VGA_DrawPart( vga.draw.parts_lines ); - PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts,vga.draw.parts_lines); -// PIC_AddEvent(VGA_DrawPart,(float)(vga.draw.delay.parts/2),vga.draw.parts_lines); //Else tearline in Tyrian and second reality if (GCC_UNLIKELY(machine==MCH_EGA)) { if (!(vga.crtc.vertical_retrace_end&0x20)) { PIC_ActivateIRQ(2); vga.draw.vret_triggered=true; } } + if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) PIC_AddEvent(VGA_DrawSingleLine,(float)vga.draw.delay.htotal); + else PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts,vga.draw.parts_lines); + //VGA_DrawPart( vga.draw.parts_lines ); + //PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts,vga.draw.parts_lines); + //PIC_AddEvent(VGA_DrawPart,(float)(vga.draw.delay.parts/2),vga.draw.parts_lines); //Else tearline in Tyrian and second reality } void VGA_CheckScanLength(void) { @@ -919,7 +1104,9 @@ void VGA_SetupDrawing(Bitu val) { //Check to prevent useless black areas if (hbstart 0; vga.draw.blocks = width; width<<=3; - VGA_DrawLine=VGA_Draw_Linear_Line; + if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) { + bpp=16; + VGA_DrawLine = VGA_Draw_Xlat16_Linear_Line; + } else VGA_DrawLine=VGA_Draw_Linear_Line; + vga.draw.linear_base = vga.mem.linear + VGA_CACHE_OFFSET; vga.draw.linear_mask = 512 * 1024 - 1; break; @@ -1000,12 +1194,17 @@ void VGA_SetupDrawing(Bitu val) { aspect_ratio=1.0; vga.draw.blocks=width; doublewidth=(vga.seq.clocking_mode & 0x8) > 0; - if ((IS_VGA_ARCH) && (svgaCard==SVGA_None) && (vga.attr.mode_control&0x04)) { + if ((IS_VGA_ARCH) && (svgaCard==SVGA_None) && (vga.seq.clocking_mode&0x01)) { width*=9; /* 9 bit wide text font */ - VGA_DrawLine=VGA_TEXT_Draw_Line_9; + VGA_DrawLine=VGA_TEXT_Xlat16_Draw_Line_9; + bpp=16; +// VGA_DrawLine=VGA_TEXT_Draw_Line_9; } else { width<<=3; /* 8 bit wide text font */ - VGA_DrawLine=VGA_TEXT_Draw_Line; + if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) { + VGA_DrawLine=VGA_TEXT_Xlat16_Draw_Line; + bpp=16; + } else VGA_DrawLine=VGA_TEXT_Draw_Line; } break; case M_HERC_GFX: @@ -1101,6 +1300,7 @@ void VGA_SetupDrawing(Bitu val) { PIC_RemoveEvents(VGA_VerticalTimer); PIC_RemoveEvents(VGA_VerticalDisplayEnd); PIC_RemoveEvents(VGA_DrawPart); + PIC_RemoveEvents(VGA_DrawSingleLine); vga.draw.width = width; vga.draw.height = height; vga.draw.doublewidth = doublewidth; @@ -1114,6 +1314,9 @@ void VGA_SetupDrawing(Bitu val) { doublewidth ? "double":"normal",doubleheight ? "double":"normal",aspect_ratio); #endif RENDER_SetSize(width,height,bpp,fps,aspect_ratio,doublewidth,doubleheight); + if(doubleheight) vga.draw.delay.virtline = vga.draw.delay.htotal * 2.0; + // On doubleheight modes we need twice the time to pass to the next scanline + else vga.draw.delay.virtline = vga.draw.delay.htotal; vga.draw.delay.framestart = PIC_FullIndex(); PIC_AddEvent( VGA_VerticalTimer , (float)vga.draw.delay.vtotal ); } @@ -1121,4 +1324,5 @@ void VGA_SetupDrawing(Bitu val) { void VGA_KillDrawing(void) { PIC_RemoveEvents(VGA_DrawPart); + PIC_RemoveEvents(VGA_DrawSingleLine); } From 0dba278956bba7ad53d8b1b14565901d82b09cff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 10 Dec 2007 22:11:13 +0000 Subject: [PATCH 2971/4131] fix some bugs+enhance the s3/xga emulation (hal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3059 --- include/paging.h | 4 +- include/vga.h | 7 +- src/hardware/memory.cpp | 9 +- src/hardware/vga.cpp | 42 ++- src/hardware/vga_draw.cpp | 111 +++--- src/hardware/vga_memory.cpp | 75 +--- src/hardware/vga_misc.cpp | 4 +- src/hardware/vga_s3.cpp | 74 ++-- src/hardware/vga_xga.cpp | 687 ++++++++++++++++++++++-------------- src/ints/int10_modes.cpp | 130 +++++-- src/ints/int10_vesa.cpp | 69 ++-- 11 files changed, 728 insertions(+), 484 deletions(-) diff --git a/include/paging.h b/include/paging.h index b80a2571..f35c3fcc 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.29 2007-11-24 17:26:48 c2woody Exp $ */ +/* $Id: paging.h,v 1.30 2007-12-10 22:11:13 c2woody Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H @@ -94,7 +94,7 @@ void PAGING_UnlinkPages(Bitu lin_page,Bitu pages); void PAGING_MapPage(Bitu lin_page,Bitu phys_page); bool PAGING_MakePhysPage(Bitu & page); -void MEM_SetLFB( Bitu page, Bitu pages, PageHandler *handler); +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); diff --git a/include/vga.h b/include/vga.h index 582f9b7b..1d8faf84 100644 --- a/include/vga.h +++ b/include/vga.h @@ -178,12 +178,17 @@ typedef struct { Bit8u reg_lock2; Bit8u reg_31; Bit8u reg_35; + 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_58; + 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; diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 99eb482e..afe051d2 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: memory.cpp,v 1.52 2007-09-29 13:23:59 c2woody Exp $ */ +/* $Id: memory.cpp,v 1.53 2007-12-10 22:11:13 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -48,6 +48,7 @@ static struct MemoryBlock { Bitu end_page; Bitu pages; PageHandler *handler; + PageHandler *mmiohandler; } lfb; struct { bool enabled; @@ -122,8 +123,9 @@ static IllegalPageHandler illegal_page_handler; static RAMPageHandler ram_page_handler; static ROMPageHandler rom_page_handler; -void MEM_SetLFB(Bitu page, Bitu pages, PageHandler *handler) { +void MEM_SetLFB(Bitu page, Bitu pages, PageHandler *handler, PageHandler *mmiohandler) { memory.lfb.handler=handler; + memory.lfb.mmiohandler=mmiohandler; memory.lfb.start_page=page; memory.lfb.end_page=page+pages; memory.lfb.pages=pages; @@ -135,6 +137,9 @@ PageHandler * MEM_GetPageHandler(Bitu phys_page) { return memory.phandlers[phys_page]; } else if ((phys_page>=memory.lfb.start_page) && (phys_page=memory.lfb.start_page+0x01000000/4096) && + (phys_page> 4) { - case 1:VGA_SetMode(M_LIN8);break; - case 3:VGA_SetMode(M_LIN15);break; - case 5:VGA_SetMode(M_LIN16);break; - case 13:VGA_SetMode(M_LIN32);break; + switch (vga.s3.misc_control_2 >> 4) { + case 0: + if (vga.attr.mode_control & 1) { // graphics mode + if (IS_VGA_ARCH && (vga.gfx.mode & 0x40)) { + // access above 256k? + if (vga.s3.reg_31 & 0x8) VGA_SetMode(M_LIN8); + else VGA_SetMode(M_VGA); + } + else if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4); + else if ((vga.gfx.miscellaneous & 0x0c)==0x0c) VGA_SetMode(M_CGA2); + else { + // access above 256k? + if (vga.s3.reg_31 & 0x8) VGA_SetMode(M_LIN4); + else VGA_SetMode(M_EGA); + } + } else { + VGA_SetMode(M_TEXT); } - /* Test for graphics or alphanumeric mode */ - } else if (vga.attr.mode_control & 1) { - if (IS_VGA_ARCH && (vga.gfx.mode & 0x40)) VGA_SetMode(M_VGA); - else if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4); - else if ((vga.gfx.miscellaneous & 0x0c)==0x0c) VGA_SetMode(M_CGA2); - else { - if (vga.s3.reg_31 & 0x8) - VGA_SetMode(M_LIN4); - else - VGA_SetMode(M_EGA); - } - } else { - VGA_SetMode(M_TEXT); + break; + case 1:VGA_SetMode(M_LIN8);break; + case 3:VGA_SetMode(M_LIN15);break; + case 5:VGA_SetMode(M_LIN16);break; + case 13:VGA_SetMode(M_LIN32);break; } } diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 251cedfb..c78c0625 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.88 2007-12-09 17:02:55 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.89 2007-12-10 22:11:13 c2woody Exp $ */ #include #include @@ -207,7 +207,7 @@ static Bit8u * VGA_Draw_Chain_Line(Bitu vidstart, Bitu line) { static Bit8u * VGA_Draw_VGA_Line_HWMouse( Bitu vidstart, Bitu line) { if(vga.s3.hgc.curmode & 0x1) { - Bitu lineat = vidstart / vga.draw.width; + Bitu lineat = (vidstart-(vga.config.real_start<<2)) / vga.draw.width; if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) { return &vga.mem.linear[ vidstart ]; } else { @@ -267,7 +267,7 @@ static Bit8u * VGA_Draw_VGA_Line_HWMouse( Bitu vidstart, Bitu line) { static Bit8u * VGA_Draw_LIN16_Line_HWMouse(Bitu vidstart, Bitu line) { if(vga.s3.hgc.curmode & 0x1) { - Bitu lineat = (vidstart >> 1) / vga.draw.width; + Bitu lineat = ((vidstart-(vga.config.real_start<<2)) >> 1) / vga.draw.width; if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) { return &vga.mem.linear[ vidstart ]; } else { @@ -330,7 +330,7 @@ static Bit8u * VGA_Draw_LIN16_Line_HWMouse(Bitu vidstart, Bitu line) { static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart, Bitu line) { if(vga.s3.hgc.curmode & 0x1) { - Bitu lineat = (vidstart >> 2) / vga.draw.width; + Bitu lineat = ((vidstart-(vga.config.real_start<<2)) >> 2) / vga.draw.width; if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) { return &vga.mem.linear[ vidstart ]; } else { @@ -379,7 +379,7 @@ static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart, Bitu line) { TempLine[xat] = ~TempLine[xat]; TempLine[xat+1] = ~TempLine[xat+1]; TempLine[xat+2] = ~TempLine[xat+2]; - TempLine[xat+2] = ~TempLine[xat+3]; + TempLine[xat+3] = ~TempLine[xat+3]; break; } xat+=4; @@ -586,7 +586,7 @@ skip_cursor: static void VGA_VerticalDisplayEnd(Bitu val) { // vga.config.retrace=true; - vga.config.real_start=vga.config.display_start & ((2*1024*1024)-1); + vga.config.real_start=vga.config.display_start & ((VGA_MEMORY)-1); } static void VGA_HorizontalTimer(void) { @@ -909,53 +909,60 @@ void VGA_SetupDrawing(Bitu val) { Bitu htotal, hdend, hbstart, hbend, hrstart, hrend; Bitu vtotal, vdend, vbstart, vbend, vrstart, vrend; if (IS_EGAVGA_ARCH) { - htotal = 2 + vga.crtc.horizontal_total; - if (IS_VGA_ARCH) htotal += 3; - hdend = 1 + vga.crtc.horizontal_display_end; - hbstart = vga.crtc.start_horizontal_blanking; + htotal = vga.crtc.horizontal_total; + hdend = vga.crtc.horizontal_display_end; hbend = vga.crtc.end_horizontal_blanking&0x1F; - if (IS_VGA_ARCH) hbend |= (vga.crtc.end_horizontal_retrace&0x80)>>2; - hbend = hbstart + ((hbend - hbstart) & 0x3F); + hbstart = vga.crtc.start_horizontal_blanking; hrstart = vga.crtc.start_horizontal_retrace; - hrend = vga.crtc.end_horizontal_retrace & 0x1f; - hrend = (hrend - hrstart) & 0x1f; - if ( !hrend ) - hrend = hrstart + 0x1f + 1; - else - hrend = hrstart + hrend; - vtotal= 2 + vga.crtc.vertical_total | ((vga.crtc.overflow & 1) << 8); - vdend = 1 + vga.crtc.vertical_display_end | ((vga.crtc.overflow & 2)<<7); + vtotal= vga.crtc.vertical_total | ((vga.crtc.overflow & 1) << 8); + vdend = vga.crtc.vertical_display_end | ((vga.crtc.overflow & 2)<<7); + vbstart = vga.crtc.start_vertical_blanking | ((vga.crtc.overflow & 0x08) << 5); vrstart = vga.crtc.vertical_retrace_start + ((vga.crtc.overflow & 0x04) << 6); + if (IS_VGA_ARCH) { // additional bits only present on vga cards + htotal |= (vga.s3.ex_hor_overflow & 0x1) << 8; + htotal += 3; + hdend |= (vga.s3.ex_hor_overflow & 0x2) << 7; + hbend |= (vga.crtc.end_horizontal_retrace&0x80) >> 2; + hbstart |= (vga.s3.ex_hor_overflow & 0x4) << 6; + hrstart |= (vga.s3.ex_hor_overflow & 0x10) << 4; + vtotal |= (vga.crtc.overflow & 0x20) << 4; - vdend |= ((vga.crtc.overflow & 0x40) << 3) | - ((vga.s3.ex_ver_overflow & 0x2) << 9); + vtotal |= (vga.s3.ex_ver_overflow & 0x1) << 10; + vdend |= (vga.crtc.overflow & 0x40) << 3; + vdend |= (vga.s3.ex_ver_overflow & 0x2) << 9; + vbstart |= (vga.crtc.maximum_scan_line & 0x20) << 4; + vbstart |= (vga.s3.ex_ver_overflow & 0x4) << 8; vrstart |= ((vga.crtc.overflow & 0x80) << 2); - } - - vrend = vga.crtc.vertical_retrace_end & 0xF; - vrend = ( vrend - vrstart)&0xF; - if ( !vrend) - vrend = vrstart + 0xf + 1; - else - vrend = vrstart + vrend; - - vbstart = vga.crtc.start_vertical_blanking | ((vga.crtc.overflow & 0x08) << 5); - if (IS_VGA_ARCH) { - vbstart |= ((vga.crtc.maximum_scan_line & 0x20) << 4); + vrstart |= (vga.s3.ex_ver_overflow & 0x10) << 6; vbend = vga.crtc.end_vertical_blanking & 0x3f; } else { vbend = vga.crtc.end_vertical_blanking & 0xf; } - vbend = (vbend - vbstart) & 0x3f; - if ( !vbend) - vbend = vbstart + 0x3f + 1; - else - vbend = vbstart + vbend; - + htotal += 2; + vtotal += 2; + hdend += 1; + vdend += 1; + hbend = hbstart + ((hbend - hbstart) & 0x3F); + hrend = vga.crtc.end_horizontal_retrace & 0x1f; + hrend = (hrend - hrstart) & 0x1f; + + if ( !hrend ) hrend = hrstart + 0x1f + 1; + else hrend = hrstart + hrend; + + vrend = vga.crtc.vertical_retrace_end & 0xF; + vrend = ( vrend - vrstart)&0xF; + + if ( !vrend) vrend = vrstart + 0xf + 1; + else vrend = vrstart + vrend; + + vbend = (vbend - vbstart) & 0x3f; + if ( !vbend) vbend = vbstart + 0x3f + 1; + else vbend = vbstart + vbend; + switch (svgaCard) { case SVGA_S3Trio: clock = SVGA_S3_GetClock(); @@ -1141,14 +1148,22 @@ void VGA_SetupDrawing(Bitu val) { } else VGA_DrawLine = VGA_Draw_Linear_Line; break; case M_LIN8: - case M_LIN15: - case M_LIN16: - case M_LIN32: - width<<=3; - if (vga.crtc.mode_control & 0x8) { - doublewidth = true; - width >>= 1; + if (vga.crtc.mode_control & 0x8) + width >>=1; + else if(!(vga.s3.reg_3a&0x10)) { + doublewidth=true; + width >>=1; } + // fall-through + case M_LIN32: + width<<=1; + // fall-through + case M_LIN15: + case M_LIN16: + // 15/16 bpp modes double the horizontal values + width<<=2; + if (vga.crtc.mode_control & 0x8) + doublewidth = true; /* Use HW mouse cursor drawer if enabled */ VGA_ActivateHardwareCursor(); break; @@ -1194,7 +1209,7 @@ void VGA_SetupDrawing(Bitu val) { aspect_ratio=1.0; vga.draw.blocks=width; doublewidth=(vga.seq.clocking_mode & 0x8) > 0; - if ((IS_VGA_ARCH) && (svgaCard==SVGA_None) && (vga.seq.clocking_mode&0x01)) { + if ((IS_VGA_ARCH) && (svgaCard==SVGA_None) && !(vga.seq.clocking_mode&0x01)) { width*=9; /* 9 bit wide text font */ VGA_DrawLine=VGA_TEXT_Xlat16_Draw_Line_9; bpp=16; diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 71905f75..00f9fe98 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_memory.cpp,v 1.44 2007-10-20 16:01:40 c2woody Exp $ */ +/* $Id: vga_memory.cpp,v 1.45 2007-12-10 22:11:13 c2woody Exp $ */ #include #include @@ -574,81 +574,39 @@ public: } }; +extern void XGA_Write(Bitu port, Bitu val, Bitu len); +extern Bitu XGA_Read(Bitu port, Bitu len); + class VGA_MMIO_Handler : public PageHandler { public: - Bit16u regmem[16384]; VGA_MMIO_Handler() { flags=PFLAG_NOCODE; - //memset(®mem[0], 0, sizeof(regmem)); } void writeb(PhysPt addr,Bitu val) { Bitu port = PAGING_GetPhysicalAddress(addr) & 0xffff; - if(port >= 0x82E8) IO_WriteB(port, val); - if(port <= 0x4000) { - if(port == 0x0000) { - IO_WriteB(0xe2e0, val); - } else { - IO_WriteB(0xe2e8, val); - } - } - //LOG_MSG("MMIO: Write byte to %x with %x", addr, val); + XGA_Write(port, val, 1); } void writew(PhysPt addr,Bitu val) { Bitu port = PAGING_GetPhysicalAddress(addr) & 0xffff; - if(port >= 0x82E8) IO_WriteW(port, val); - if(port == 0x8118) IO_WriteW(0x9ae8, val); - if(port <= 0x4000) { - if(port == 0x0000) { - IO_WriteW(0xe2e0, val); - } else { - IO_WriteW(0xe2e8, val); - } - } - //LOG_MSG("MMIO: Write word to %x with %x", addr, val); + XGA_Write(port, val, 2); } void writed(PhysPt addr,Bitu val) { Bitu port = PAGING_GetPhysicalAddress(addr) & 0xffff; - if(port >= 0x82E8) IO_WriteD(port, val); - if(port == 0x8100) { - IO_WriteW(0x86e8, (val >> 16)); - IO_WriteW(0x82e8, (val & 0xffff)); - } - if(port == 0x8148) { - IO_WriteW(0x96e8, (val >> 16)); - IO_WriteW(0xbee8, (val & 0xffff)); - } - if(port <= 0x4000) { - if(port == 0x0000) { - IO_WriteW(0xe2e0, (val & 0xffff)); - IO_WriteW(0xe2e8, (val >> 16)); - } else { - IO_WriteW(0xe2e8, (val & 0xffff)); - IO_WriteW(0xe2e8, (val >> 16)); - } - } - - //LOG_MSG("MMIO: Write dword to %x with %x", addr, val); + XGA_Write(port, val, 4); } Bitu readb(PhysPt addr) { Bitu port = PAGING_GetPhysicalAddress(addr) & 0xffff; - if(port >= 0x82E8) return IO_ReadB(port); - //LOG_MSG("MMIO: Read byte from %x", addr); - return 0x00; + return XGA_Read(port, 1); } Bitu readw(PhysPt addr) { Bitu port = PAGING_GetPhysicalAddress(addr) & 0xffff; - if(port >= 0x82E8) return IO_ReadW(port); - //LOG_MSG("MMIO: Read word from %x", addr); - return 0x00; + return XGA_Read(port, 2); } Bitu readd(PhysPt addr) { Bitu port = PAGING_GetPhysicalAddress(addr) & 0xffff; - if(port >= 0x82E8) return IO_ReadD(port); - //LOG_MSG("MMIO: Read dword from %x", addr); - return 0x00; + return XGA_Read(port, 4); } - }; class VGA_TANDY_PageHandler : public PageHandler { @@ -845,7 +803,7 @@ void VGA_SetupHandlers(void) { MEM_ResetPageHandler( VGA_PAGE_B0, 8 ); break; } - if(((vga.s3.ext_mem_ctrl & 0x10) != 0x00) /*&& (vga.mode == M_LIN8)*/) + if(vga.s3.ext_mem_ctrl & 0x10) MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio); range_done: PAGING_ClearTLB(); @@ -859,18 +817,9 @@ void VGA_StartUpdateLFB(void) { #else vga.lfb.handler = &vgaph.lfbchanges; #endif - MEM_SetLFB(vga.s3.la_window << 4 ,VGA_MEMORY/4096, vga.lfb.handler ); + MEM_SetLFB(vga.s3.la_window << 4 ,VGA_MEMORY/4096, vga.lfb.handler, &vgaph.mmio); } -void VGA_MapMMIO(void) { - MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio); -} - -void VGA_UnmapMMIO(void) { - //MEM_SetPageHandler(VGA_PAGE_A0, &ram_page_handler); -} - - void VGA_SetupMemory() { // allocate 16byte-aligned memory vga.mem.linear = new Bit8u[VGA_MEMORY+16]; diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index d3638c37..f20bbdcb 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_misc.cpp,v 1.35 2007-10-13 16:34:06 c2woody Exp $ */ +/* $Id: vga_misc.cpp,v 1.36 2007-12-10 22:11:13 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -30,7 +30,7 @@ Bitu vga_read_p3d4(Bitu port,Bitu iolen); void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen); Bitu vga_read_p3d5(Bitu port,Bitu iolen); -static Bitu vga_read_p3da(Bitu port,Bitu iolen) { +Bitu vga_read_p3da(Bitu port,Bitu iolen) { vga.internal.attrindex=false; vga.tandy.pcjr_flipflop=false; Bit8u retval=0; diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index a48ab1c4..5c718456 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_s3.cpp,v 1.8 2007-06-28 16:02:27 c2woody Exp $ */ +/* $Id: vga_s3.cpp,v 1.9 2007-12-10 22:11:13 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -70,9 +70,15 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { case 0x39: /* CR39 Register Lock 2 */ vga.s3.reg_lock2=val; break; + case 0x3a: + vga.s3.reg_3a = val; + break; case 0x40: /* CR40 System Config */ vga.s3.reg_40 = val; break; + case 0x41: /* CR41 BIOS flags */ + vga.s3.reg_41 = val; + break; case 0x43: /* CR43 Extended Mode */ vga.s3.reg_43=val & ~0x4; if (((val & 0x4) ^ (vga.config.scan_len >> 6)) & 0x4) { @@ -114,17 +120,22 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { vga.s3.hgc.bstackpos++; break; case 0x4c: /* HGC start address high byte*/ - vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | ((val & 0xff) << 8); + vga.s3.hgc.startaddr &=0xff; + vga.s3.hgc.startaddr |= ((val & 0xf) << 8); break; case 0x4d: /* HGC start address low byte*/ - vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | (val & 0xff); + vga.s3.hgc.startaddr &=0xff00; + vga.s3.hgc.startaddr |= (val & 0xff); break; case 0x4e: /* HGC pattern start X */ vga.s3.hgc.posx = val; break; - case 0x4f: /* HGC pattern start X */ + case 0x4f: /* HGC pattern start Y */ vga.s3.hgc.posy = val; break; + case 0x50: // Extended System Control 1 + vga.s3.reg_50 = val; + break; case 0x51: /* Extended System Control 2 */ vga.s3.reg_51=val & 0xc0; //Only store bits 6,7 //TODO Display start @@ -161,17 +172,17 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { 7 (not 864/964) Enable EPROM Write. If set enables flash memory write control to the BIOS ROM address */ + case 0x52: // Extended System Control 1 + vga.s3.reg_52 = val; + break; case 0x53: - if((val & 0x10) != (vga.s3.ext_mem_ctrl & 0x10)) { - /* Map or unmap MMIO */ - if ((val & 0x10) != 0) { - //LOG_MSG("VGA: Mapping Memory Mapped I/O to 0xA0000"); -// VGA_MapMMIO(); - } else { -// VGA_UnmapMMIO(); - } + // Map or unmap MMIO + // bit 4 = MMIO at A0000 + // bit 3 = MMIO at LFB + 16M (should be fine if its always enabled for now) + if(vga.s3.ext_mem_ctrl!=val) { + vga.s3.ext_mem_ctrl = val; + VGA_SetupHandlers(); } - vga.s3.ext_mem_ctrl = val; break; case 0x55: /* Extended Video DAC Control */ vga.s3.reg_55=val; @@ -302,6 +313,9 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { vga.s3.svga_bank.b.bank=val & 0x3f; VGA_SetupHandlers(); break; + case 0x6b: // BIOS scratchpad: LFB adress + vga.s3.reg_6b=(Bit8u)val; + break; default: LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:S3:CRTC:Write to illegal index %2X", reg ); break; @@ -317,38 +331,56 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { return 0x11; //Trio 64 id case 0x2f: /* Revision */ - return 0x00; + return 0x44; case 0x30: /* CR30 Chip ID/REV register */ - return 0xe0; //Trio+ dual byte - // Trio32/64 has 0xe0. extended + return 0xe1; //Trio+ dual byte + //return 0xc0; // 864 + case 0x31: /* CR31 Memory Configuration */ //TODO mix in bits from baseaddress; return vga.s3.reg_31; case 0x35: /* CR35 CRT Register Lock */ return vga.s3.reg_35|(vga.s3.svga_bank.b.bank & 0xf); case 0x36: /* CR36 Reset State Read 1 */ - //return 0x8f; - return 0x8e; /* PCI version */ + return 0x92; /* PCI version */ //2 Mb PCI and some bios settings case 0x37: /* Reset state read 2 */ return 0x2b; case 0x38: /* CR38 Register Lock 1 */ return vga.s3.reg_lock1; case 0x39: /* CR39 Register Lock 2 */ - return vga.s3.reg_lock2; + return vga.s3.reg_lock2; + case 0x3a: + return vga.s3.reg_3a; case 0x40: /* CR40 system config */ return vga.s3.reg_40; + case 0x41: /* CR40 system config */ + return vga.s3.reg_41; + case 0x42: // not interlaced + return 0x0d; case 0x43: /* CR43 Extended Mode */ return vga.s3.reg_43|((vga.config.scan_len>>6)&0x4); case 0x45: /* Hardware cursor mode */ vga.s3.hgc.bstackpos = 0; vga.s3.hgc.fstackpos = 0; - return vga.s3.hgc.curmode; + return vga.s3.hgc.curmode|0xa0; + case 0x46: + return vga.s3.hgc.originx>>8; + case 0x47: /* HGC orgX */ + return vga.s3.hgc.originx&0xff; + case 0x48: + return vga.s3.hgc.originy>>8; + case 0x49: /* HGC orgY */ + return vga.s3.hgc.originy&0xff; + case 0x50: // CR50 Extended System Control 1 + return vga.s3.reg_50; case 0x51: /* Extended System Control 2 */ return ((vga.config.display_start >> 16) & 3 ) | ((vga.s3.svga_bank.b.bank & 0x30) >> 2) | ((vga.config.scan_len & 0x300) >> 4) | vga.s3.reg_51; + case 0x52: // CR52 Extended BIOS flags 1 + return vga.s3.reg_52; case 0x53: return vga.s3.ext_mem_ctrl; case 0x55: /* Extended Video DAC Control */ @@ -369,6 +401,8 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { return (Bit8u)((vga.config.display_start & 0x1f0000)>>16); case 0x6a: /* Extended System Control 4 */ return (Bit8u)(vga.s3.svga_bank.b.bank & 0x3f); + case 0x6b: // BIOS scatchpad: LFB address + return vga.s3.reg_6b; default: return 0x00; } diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index e8557970..4054be5f 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -16,12 +16,16 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: vga_xga.cpp,v 1.10 2007-12-10 22:11:13 c2woody Exp $ */ + #include #include "dosbox.h" #include "inout.h" #include "vga.h" #include #include +#include "callback.h" +#include "cpu.h" // for 0x3da delay #define XGA_SCREEN_WIDTH vga.draw.width @@ -63,6 +67,7 @@ struct XGAStatus { Bit16u x1, y1, x2, y2, sizex, sizey; Bit32u data; /* transient data passed by multiple calls */ Bitu datasize; + Bitu buswidth; } waitcmd; } xga; @@ -71,25 +76,25 @@ void XGA_Write_Multifunc(Bitu val, Bitu len) { Bitu regselect = val >> 12; Bitu dataval = val & 0xfff; switch(regselect) { - case 0: + case 0: // minor axis pixel count xga.MIPcount = dataval; break; - case 1: + case 1: // top scissors xga.scissors.y1 = dataval; break; - case 2: + case 2: // left xga.scissors.x1 = dataval; break; - case 3: + case 3: // bottom xga.scissors.y2 = dataval; break; - case 4: + case 4: // right xga.scissors.x2 = dataval; break; - case 0xa: + case 0xa: // data manip control xga.pix_cntl = dataval; break; - case 0xd: + case 0xd: // misc 2 xga.control2 = dataval; break; case 0xe: @@ -104,8 +109,7 @@ void XGA_Write_Multifunc(Bitu val, Bitu len) { } } -Bitu XGA_Read_Multifunc() -{ +Bitu XGA_Read_Multifunc() { switch(xga.read_sel++) { case 0: return xga.MIPcount; case 1: return xga.scissors.y1; @@ -124,7 +128,6 @@ Bitu XGA_Read_Multifunc() void XGA_DrawPoint(Bitu x, Bitu y, Bitu c) { - if(!(xga.curcommand & 0x1)) return; if(!(xga.curcommand & 0x10)) return; @@ -139,18 +142,24 @@ void XGA_DrawPoint(Bitu x, Bitu y, Bitu c) { during windows dragging. */ switch(vga.mode) { case M_LIN8: vga.mem.linear[memaddr] = c; break; - case M_LIN15: ((Bit16u*)(vga.mem.linear))[memaddr] = c&0x7fff; break; - case M_LIN16: ((Bit16u*)(vga.mem.linear))[memaddr] = c; break; - case M_LIN32: ((Bit32u*)(vga.mem.linear))[memaddr] = c&0x00ffffff; break; + case M_LIN15: ((Bit16u*)(vga.mem.linear))[memaddr] = (Bit16u)(c&0x7fff); break; + case M_LIN16: ((Bit16u*)(vga.mem.linear))[memaddr] = (Bit16u)(c&0xffff); break; + case M_LIN32: ((Bit32u*)(vga.mem.linear))[memaddr] = c; } } Bitu XGA_GetPoint(Bitu x, Bitu y) { Bit32u memaddr = (y * XGA_SCREEN_WIDTH) + x; + + if(VGA_MEMORY < memaddr) { + //LOG_MSG("getpoint mem over: x%d y%d",x,y); + return 0; + } switch(vga.mode) { case M_LIN8: return vga.mem.linear[memaddr]; - case M_LIN15: case M_LIN16: return ((Bit16u*)(vga.mem.linear))[memaddr]; + case M_LIN15: + case M_LIN16: return ((Bit16u*)(vga.mem.linear))[memaddr]; case M_LIN32: return ((Bit32u*)(vga.mem.linear))[memaddr]; } return 0; @@ -213,7 +222,6 @@ Bitu XGA_GetMixResult(Bitu mixmode, Bitu srcval, Bitu dstdata) { break; } return destval; - } void XGA_DrawLineVector(Bitu val) { @@ -268,8 +276,6 @@ void XGA_DrawLineVector(Bitu val) { break; } - //for(yat=y1;yat<=y2;yat++) { - // for(xat=x1;xat<=x2;xat++) { for (i=0;i<=dx;i++) { Bitu mixmode = (xga.pix_cntl >> 6) & 0x3; switch (mixmode) { @@ -284,7 +290,7 @@ void XGA_DrawLineVector(Bitu val) { break; case 0x02: /* Src is pixel data from PIX_TRANS register */ //srcval = tmpval; - LOG_MSG("XGA: DrawRect: Wants data from PIX_TRANS register"); + //LOG_MSG("XGA: DrawRect: Wants data from PIX_TRANS register"); break; case 0x03: /* Src is bitmap data */ LOG_MSG("XGA: DrawRect: Wants data from srcdata"); @@ -310,9 +316,6 @@ void XGA_DrawLineVector(Bitu val) { xga.curx = xat-1; xga.cury = yat; - // } - //} - } void XGA_DrawLineBresenham(Bitu val) { @@ -326,12 +329,19 @@ void XGA_DrawLineBresenham(Bitu val) { #define SWAP(a,b) tmpswap = a; a = b; b = tmpswap; - Bits dx, sx, dy, sy, e, dmajor, dminor; + Bits dx, sx, dy, sy, e, dmajor, dminor,destxtmp; // Probably a lot easier way to do this, but this works. - dminor = (Bits)((Bit16s)xga.desty) >> 1; - dmajor = -((Bits)((Bit16s)xga.destx) - (dminor << 1)) >> 1; + dminor = (Bits)((Bit16s)xga.desty); + if(xga.desty&0x2000) dminor |= 0xffffe000; + dminor >>= 1; + + destxtmp=(Bits)((Bit16s)xga.destx); + if(xga.destx&0x2000) destxtmp |= 0xffffe000; + + + dmajor = -(destxtmp - (dminor << 1)) >> 1; dx = dmajor; if((val >> 5) & 0x1) { @@ -346,6 +356,7 @@ void XGA_DrawLineBresenham(Bitu val) { sy = -1; } e = (Bits)((Bit16s)xga.ErrTerm); + if(xga.ErrTerm&0x2000) e |= 0xffffe000; xat = xga.curx; yat = xga.cury; @@ -357,10 +368,8 @@ void XGA_DrawLineBresenham(Bitu val) { steep = true; } - //LOG_MSG("XGA: Bresenham: ASC %d, LPDSC %d, sx %d, sy %d, err %d, steep %d, length %d, dmajor %d, dminor %d", dx, dy, sx, sy, e, steep, xga.MAPcount, dmajor, dminor); + //LOG_MSG("XGA: Bresenham: ASC %d, LPDSC %d, sx %d, sy %d, err %d, steep %d, length %d, dmajor %d, dminor %d, xstart %d, ystart %d", dx, dy, sx, sy, e, steep, xga.MAPcount, dmajor, dminor,xat,yat); - //for(yat=y1;yat<=y2;yat++) { - // for(xat=x1;xat<=x2;xat++) { for (i=0;i<=xga.MAPcount;i++) { Bitu mixmode = (xga.pix_cntl >> 6) & 0x3; switch (mixmode) { @@ -405,7 +414,7 @@ void XGA_DrawLineBresenham(Bitu val) { LOG_MSG("XGA: DrawLine: Needs mixmode %x", mixmode); break; } - while (e >= 0) { + while (e > 0) { yat += sy; e -= (dx << 1); } @@ -476,7 +485,7 @@ void XGA_DrawRectangle(Bitu val) { default: LOG_MSG("XGA: DrawRect: Needs mixmode %x", mixmode); break; - } + } srcx += dx; } srcy += dy; @@ -490,192 +499,206 @@ void XGA_DrawRectangle(Bitu val) { bool XGA_CheckX(void) { bool newline = false; if(!xga.waitcmd.newline) { - if(xga.waitcmd.curx > xga.waitcmd.x2) { + + if((xga.waitcmd.curx<2048) && xga.waitcmd.curx > (xga.waitcmd.x2)) { xga.waitcmd.curx = xga.waitcmd.x1; xga.waitcmd.cury++; + xga.waitcmd.cury&=0x0fff; newline = true; xga.waitcmd.newline = true; - if(xga.waitcmd.cury > xga.waitcmd.y2) xga.waitcmd.wait = false; - } + if((xga.waitcmd.cury<2048)&&(xga.waitcmd.cury > xga.waitcmd.y2)) + xga.waitcmd.wait = false; + } else if(xga.waitcmd.curx>=2048) { + Bit16u realx = 4096-xga.waitcmd.curx; + if(xga.waitcmd.x2>2047) { // x end is negative too + Bit16u realxend=4096-xga.waitcmd.x2; + if(realx==realxend) { + xga.waitcmd.curx = xga.waitcmd.x1; + xga.waitcmd.cury++; + xga.waitcmd.cury&=0x0fff; + newline = true; + xga.waitcmd.newline = true; + if((xga.waitcmd.cury<2048)&&(xga.waitcmd.cury > xga.waitcmd.y2)) + xga.waitcmd.wait = false; + } + } else { // else overlapping + if(realx==xga.waitcmd.x2) { + xga.waitcmd.curx = xga.waitcmd.x1; + xga.waitcmd.cury++; + xga.waitcmd.cury&=0x0fff; + newline = true; + xga.waitcmd.newline = true; + if((xga.waitcmd.cury<2048)&&(xga.waitcmd.cury > xga.waitcmd.y2)) + xga.waitcmd.wait = false; + } + } + } } else { xga.waitcmd.newline = false; } return newline; } +void XGA_DrawWaitSub(Bitu mixmode, Bitu srcval) { + Bitu destval; + Bitu dstdata; + dstdata = XGA_GetPoint(xga.waitcmd.curx, xga.waitcmd.cury); + destval = XGA_GetMixResult(mixmode, srcval, dstdata); + //LOG_MSG("XGA: DrawPattern: Mixmode: %x srcval: %x", mixmode, srcval); + + XGA_DrawPoint(xga.waitcmd.curx, xga.waitcmd.cury, destval); + xga.waitcmd.curx++; + xga.waitcmd.curx&=0x0fff; + XGA_CheckX(); +} void XGA_DrawWait(Bitu val, Bitu len) { if(!xga.waitcmd.wait) return; - - //if(!(xga.curcommand & 0x2)) return; - Bitu mixmode = (xga.pix_cntl >> 6) & 0x3; Bitu srcval; - Bitu destval; - Bitu dstdata; - //Bitu tmpval; - Bits bitneed; - switch(xga.waitcmd.cmd) { case 2: /* Rectangle */ switch(mixmode) { case 0x00: /* FOREMIX always used */ mixmode = xga.foremix; - Bitu t; - for(t=0;t> 5) & 0x03) { - case 0x00: /* Src is background color */ - srcval = xga.backcolor; - break; - case 0x01: /* Src is foreground color */ - srcval = xga.forecolor; - break; - case 0x02: /* Src is pixel data from PIX_TRANS register */ - /* This register is 16 bit. In theory, it is possible to access it as 8-bit - or 32-bit but all calls from Win3 drivers are 16-bit. 8-bit color modes - would work regardless of the access size (although something else in this - function may break), other color modes may require more complex code to - collect transient data or break incoming data in chunks. */ - if(vga.mode == M_LIN8) - srcval = (val >> (8 * t)) & 0xff; - else if(vga.mode == M_LIN32) { /* May need transient data */ - if(xga.waitcmd.datasize == 0) { - xga.waitcmd.data = val; - xga.waitcmd.datasize = 2; - return; - } else { - srcval = (val<<16)|xga.waitcmd.data; - xga.waitcmd.data = 0; - xga.waitcmd.datasize = 0; - t = len; /* All data used */ - } + +/* switch((mixmode >> 5) & 0x03) { + case 0x00: // Src is background color + srcval = xga.backcolor; + break; + case 0x01: // Src is foreground color + srcval = xga.forecolor; + break; + case 0x02: // Src is pixel data from PIX_TRANS register +*/ + if(((mixmode >> 5) & 0x03) != 0x2) { + // those cases don't seem to occur + LOG_MSG("XGA: unsupported drawwait operation"); + break; + } + switch(xga.waitcmd.buswidth) { + case M_LIN8: // 8 bit + XGA_DrawWaitSub(mixmode, val); + break; + case 0x20 | M_LIN8: // 16 bit + XGA_DrawWaitSub(mixmode, val); + if(!xga.waitcmd.newline) + XGA_DrawWaitSub(mixmode, val>>8); + break; + case 0x40 | M_LIN8: // 32 bit + for(int i = 0; i < 4; i++) + XGA_DrawWaitSub(mixmode, (val>>(8*i))&0xff); + break; + case (0x20 | M_LIN32): + if(len!=4) { // Win 3.11 864 'hack?' + if(xga.waitcmd.datasize == 0) { + // set it up to wait for the next word + xga.waitcmd.data = val; + xga.waitcmd.datasize = 2; + return; + } else { + srcval = (val<<16)|xga.waitcmd.data; + xga.waitcmd.data = 0; + xga.waitcmd.datasize = 0; + XGA_DrawWaitSub(mixmode, srcval); } - else { - srcval = val; - t = len; /* All data used */ - } - //LOG_MSG("XGA: DrawBlitWait: Wants data from PIX_TRANS register"); - break; - case 0x03: /* Src is bitmap data */ - LOG_MSG("XGA: DrawBlitWait: Wants data from srcdata"); - //srcval = srcdata; - break; - default: - LOG_MSG("XGA: DrawBlitWait: Shouldn't be able to get here!"); - break; - } - - - - dstdata = XGA_GetPoint(xga.waitcmd.curx, xga.waitcmd.cury); - - destval = XGA_GetMixResult(mixmode, srcval, dstdata); - - //LOG_MSG("XGA: DrawPattern: Mixmode: %x srcval: %x", mixmode, srcval); - - XGA_DrawPoint(xga.waitcmd.curx++, xga.waitcmd.cury, destval); - - XGA_CheckX(); - if(xga.waitcmd.newline) break; - } + break; + } // fall-through + case 0x40 | M_LIN32: // 32 bit + XGA_DrawWaitSub(mixmode, val); + break; + case 0x20 | M_LIN15: // 16 bit + case 0x20 | M_LIN16: // 16 bit + XGA_DrawWaitSub(mixmode, val); + break; + case 0x40 | M_LIN15: // 32 bit + case 0x40 | M_LIN16: // 32 bit + XGA_DrawWaitSub(mixmode, val&0xffff); + if(!xga.waitcmd.newline) + XGA_DrawWaitSub(mixmode, val>>16); + break; + default: + // Let's hope they never show up ;) + LOG_MSG("XGA: unsupported bpp / datawidth combination %x", + xga.waitcmd.buswidth); + break; + }; break; - case 0x02: /* Data from PIX_TRANS selects the mix */ - Bitu bitcount; - int i; - switch(len) { - case 1: - bitcount = 8; - break; - case 2: - bitcount = 16; - val = ((val & 0xff) << 8) | ((val >> 8) & 0xff); - break; - case 4: - bitcount = 32; - break; - } - - - bitneed = ((Bits)xga.waitcmd.x2 - (Bits)xga.waitcmd.curx) ; - //xga.waitcmd.curx = xga.waitcmd.x1; - xga.waitcmd.newline = false; - - - i = bitcount -1 ; - //bitneed = i; - - for(;bitneed>=0;--bitneed) { - //for(;i>=0;--i) { - Bitu bitval = (val >> i) & 0x1; - //Bitu bitval = (val >> bitneed) & 0x1; - - //XGA_DrawPoint8(xga.waitcmd.curx, xga.waitcmd.cury, i); - Bitu mixmode = 0x67; - - if(bitval) { - mixmode = xga.foremix; - } else { - mixmode = xga.backmix; - } - - switch((mixmode >> 5) & 0x03) { - case 0x00: /* Src is background color */ - srcval = xga.backcolor; - break; - case 0x01: /* Src is foreground color */ - srcval = xga.forecolor; - break; - case 0x02: /* Src is pixel data from PIX_TRANS register */ - LOG_MSG("XGA: DrawBlitWait: Wants data from PIX_TRANS register"); - break; - case 0x03: /* Src is bitmap data */ - LOG_MSG("XGA: DrawBlitWait: Wants data from srcdata"); - //srcval = srcdata; - break; - default: - LOG_MSG("XGA: DrawBlitWait: Shouldn't be able to get here!"); - break; - } - - Bitu dstdata = XGA_GetPoint(xga.waitcmd.curx, xga.waitcmd.cury); - - destval = XGA_GetMixResult(mixmode, srcval, dstdata); - - XGA_DrawPoint(xga.waitcmd.curx, xga.waitcmd.cury, destval); - - --i; - if(i < 0) break; - //--bitneed; - //if(bitneed < 0) break; - - xga.waitcmd.curx++; - XGA_CheckX(); - if(xga.waitcmd.newline) break; - } - //xga.waitcmd.cury++; - - if(xga.waitcmd.cury > xga.waitcmd.y2) xga.waitcmd.wait = false; + case 0x02: // Data from PIX_TRANS selects the mix + Bitu chunksize; + Bitu chunks; + switch(xga.waitcmd.buswidth&0x60) { + case 0x0: + chunksize=8; + chunks=1; + break; + case 0x20: // 16 bit + chunksize=16; + if(len==4) chunks=2; + else chunks = 1; + break; + case 0x40: // 32 bit + chunksize=16; + if(len==4) chunks=2; + else chunks = 1; + break; + case 0x60: // undocumented guess (but works) + chunksize=8; + chunks=4; + break; + } + + for(Bitu k = 0; k < chunks; k++) { // chunks counter + xga.waitcmd.newline = false; + for(Bitu n = 0; n < chunksize; n++) { // pixels + Bitu mixmode; + + // This formula can rule the world ;) + Bitu mask = 1 << ((((n&0xF8)+(8-(n&0x7)))-1)+chunksize*k); + if(val&mask) mixmode = xga.foremix; + else mixmode = xga.backmix; + + switch((mixmode >> 5) & 0x03) { + case 0x00: // Src is background color + srcval = xga.backcolor; + break; + case 0x01: // Src is foreground color + srcval = xga.forecolor; + break; + default: + LOG_MSG("XGA: DrawBlitWait: Unsupported src %x", + (mixmode >> 5) & 0x03); + srcval=0; + break; + } + XGA_DrawWaitSub(mixmode, srcval); + + if((xga.waitcmd.cury<2048) && + (xga.waitcmd.cury >= xga.waitcmd.y2)) { + xga.waitcmd.wait = false; + k=1000; // no more chunks + break; + } + // next chunk goes to next line + if(xga.waitcmd.newline) break; + } // pixels loop + } // chunks loop break; + default: LOG_MSG("XGA: DrawBlitWait: Unhandled mixmode: %d", mixmode); break; - } + } // switch mixmode break; default: LOG_MSG("XGA: Unhandled draw command %x", xga.waitcmd.cmd); break; } - } void XGA_BlitRect(Bitu val) { Bit32u xat, yat; -// Bit32u xmass, xmod, xdist, memrec; - //Bit8u *srcptr; - //Bit8u *destptr; - //Bit8u *destline; - //Bit8u *srcline; Bitu srcdata; Bitu dstdata; @@ -683,28 +706,18 @@ void XGA_BlitRect(Bitu val) { Bitu destval; Bits srcx, srcy, tarx, tary, dx, dy; - //bool incx = false; - //bool incy = false; dx = -1; dy = -1; - //if(((val >> 5) & 0x01) != 0) incx = true; - //if(((val >> 7) & 0x01) != 0) incy = true; - if(((val >> 5) & 0x01) != 0) dx = 1; if(((val >> 7) & 0x01) != 0) dy = 1; - //Bit32u srcaddr = (xga.cury * (Bit32u)XGA_SCREEN_WIDTH) + xga.curx; - //Bit32u destaddr = (xga.desty * (Bit32u)XGA_SCREEN_WIDTH) + xga.destx; srcx = xga.curx; srcy = xga.cury; tarx = xga.destx; tary = xga.desty; - //srcptr = &vga.mem.linear[srcaddr]; - //destptr = &vga.mem.linear[destaddr]; - Bitu mixselect = (xga.pix_cntl >> 6) & 0x3; Bitu mixmode = 0x67; /* Source is bitmap data, mix mode is src */ switch(mixselect) { @@ -718,7 +731,7 @@ void XGA_BlitRect(Bitu val) { //LOG_MSG("XGA: Srcdata: %x, Forecolor %x, Backcolor %x, Foremix: %x Backmix: %x", srcdata, xga.forecolor, xga.backcolor, xga.foremix, xga.backmix); break; default: - LOG_MSG("XGA: DrawPattern: Unknown mix select register"); + LOG_MSG("XGA: BlitRect: Unknown mix select register"); break; } @@ -733,17 +746,17 @@ void XGA_BlitRect(Bitu val) { dstdata = XGA_GetPoint(tarx, tary); if(mixselect == 0x3) { - if(srcdata == xga.forecolor) { - mixmode = xga.foremix; + if(srcdata == xga.forecolor) { + mixmode = xga.foremix; + } else { + if(srcdata == xga.backcolor) { + mixmode = xga.backmix; } else { - if(srcdata == xga.backcolor) { - mixmode = xga.backmix; - } else { - /* Best guess otherwise */ - mixmode = 0x67; /* Source is bitmap data, mix mode is src */ + /* Best guess otherwise */ + mixmode = 0x67; /* Source is bitmap data, mix mode is src */ + } + } } - } - } switch((mixmode >> 5) & 0x03) { case 0x00: /* Src is background color */ @@ -761,13 +774,11 @@ void XGA_BlitRect(Bitu val) { default: LOG_MSG("XGA: DrawPattern: Shouldn't be able to get here!"); break; - } + } destval = XGA_GetMixResult(mixmode, srcval, dstdata); - //LOG_MSG("XGA: DrawPattern: Mixmode: %x Mixselect: %x", mixmode, mixselect); - //*smallptr++ = destval; XGA_DrawPoint(tarx, tary, destval); srcx += dx; @@ -776,7 +787,6 @@ void XGA_BlitRect(Bitu val) { srcy += dy; tary += dy; } - } void XGA_DrawPattern(Bitu val) { @@ -799,17 +809,17 @@ void XGA_DrawPattern(Bitu val) { tary = xga.desty; - Bitu mixselect = (xga.pix_cntl >> 6) & 0x3; - Bitu mixmode = 0x67; /* Source is bitmap data, mix mode is src */ - switch(mixselect) { - case 0x00: /* Foreground mix is always used */ - mixmode = xga.foremix; - break; - case 0x02: /* CPU Data determines mix used */ - LOG_MSG("XGA: DrawPattern: Mixselect data from PIX_TRANS register"); - break; - case 0x03: /* Video memory determines mix */ - //LOG_MSG("XGA: Srcdata: %x, Forecolor %x, Backcolor %x, Foremix: %x Backmix: %x", srcdata, xga.forecolor, xga.backcolor, xga.foremix, xga.backmix); + Bitu mixselect = (xga.pix_cntl >> 6) & 0x3; + Bitu mixmode = 0x67; /* Source is bitmap data, mix mode is src */ + switch(mixselect) { + case 0x00: /* Foreground mix is always used */ + mixmode = xga.foremix; + break; + case 0x02: /* CPU Data determines mix used */ + LOG_MSG("XGA: DrawPattern: Mixselect data from PIX_TRANS register"); + break; + case 0x03: /* Video memory determines mix */ + //LOG_MSG("XGA: Pixctl: %x, Srcdata: %x, Forecolor %x, Backcolor %x, Foremix: %x Backmix: %x",xga.pix_cntl, srcdata, xga.forecolor, xga.backcolor, xga.foremix, xga.backmix); break; default: LOG_MSG("XGA: DrawPattern: Unknown mix select register"); @@ -821,20 +831,16 @@ void XGA_DrawPattern(Bitu val) { for(xat=0;xat<=xga.MAPcount;xat++) { srcdata = XGA_GetPoint(srcx + (tarx & 0x7), srcy + (tary & 0x7)); + //LOG_MSG("patternpoint (%3d/%3d)v%x",srcx + (tarx & 0x7), srcy + (tary & 0x7),srcdata); dstdata = XGA_GetPoint(tarx, tary); if(mixselect == 0x3) { - if(srcdata == xga.forecolor) { - mixmode = xga.foremix; - } else { - if(srcdata == xga.backcolor) { - mixmode = xga.backmix; - } else { - /* Best guess otherwise */ - mixmode = 0x67; /* Source is bitmap data, mix mode is src */ - } - } + // TODO lots of guessing here but best results this way + /*if(srcdata == xga.forecolor)*/ mixmode = xga.foremix; + // else + if(srcdata == xga.backcolor || srcdata == 0) + mixmode = xga.backmix; } switch((mixmode >> 5) & 0x03) { @@ -862,16 +868,14 @@ void XGA_DrawPattern(Bitu val) { tarx += dx; } tary += dy; - } - } void XGA_DrawCmd(Bitu val, Bitu len) { Bit16u cmd; cmd = val >> 13; #if XGA_SHOW_COMMAND_TRACE == 1 - LOG_MSG("XGA: Draw command %x", cmd); + //LOG_MSG("XGA: Draw command %x", cmd); #endif xga.curcommand = val; switch(cmd) { @@ -895,10 +899,12 @@ void XGA_DrawCmd(Bitu val, Bitu len) { case 2: /* Rectangle fill */ if((val & 0x100) == 0) { xga.waitcmd.wait = false; - XGA_DrawRectangle(val); #if XGA_SHOW_COMMAND_TRACE == 1 - LOG_MSG("XGA: Draw immediate rect"); + LOG_MSG("XGA: Draw immediate rect: xy(%3d/%3d), len(%3d/%3d)", + xga.curx,xga.cury,xga.MAPcount,xga.MIPcount); #endif + XGA_DrawRectangle(val); + } else { xga.waitcmd.newline = true; @@ -907,44 +913,50 @@ void XGA_DrawCmd(Bitu val, Bitu len) { xga.waitcmd.cury = xga.cury; xga.waitcmd.x1 = xga.curx; xga.waitcmd.y1 = xga.cury; - xga.waitcmd.x2 = xga.curx + xga.MAPcount; - xga.waitcmd.y2 = xga.cury + xga.MIPcount + 1; + xga.waitcmd.x2 = (Bit16u)((xga.curx + xga.MAPcount)&0x0fff); + xga.waitcmd.y2 = (Bit16u)((xga.cury + xga.MIPcount + 1)&0x0fff); xga.waitcmd.sizex = xga.MAPcount; xga.waitcmd.sizey = xga.MIPcount + 1; xga.waitcmd.cmd = 2; - + xga.waitcmd.buswidth = vga.mode | ((val&0x600) >> 4); xga.waitcmd.data = 0; xga.waitcmd.datasize = 0; #if XGA_SHOW_COMMAND_TRACE == 1 - LOG_MSG("XGA: Draw wait rect, width %d, heigth %d", xga.MAPcount, xga.MIPcount+1); + LOG_MSG("XGA: Draw wait rect, w/h(%3d/%3d), x/y1(%3d/%3d), x/y2(%3d/%3d), %4x", + xga.MAPcount+1, xga.MIPcount+1,xga.curx,xga.cury, + (xga.curx + xga.MAPcount)&0x0fff, + (xga.cury + xga.MIPcount + 1)&0x0fff,val&0xffff); #endif + } break; case 6: /* BitBLT */ - XGA_BlitRect(val); #if XGA_SHOW_COMMAND_TRACE == 1 LOG_MSG("XGA: Blit Rect"); #endif + XGA_BlitRect(val); break; case 7: /* Pattern fill */ - XGA_DrawPattern(val); #if XGA_SHOW_COMMAND_TRACE == 1 - LOG_MSG("XGA: Pattern fill"); + LOG_MSG("XGA: Pattern fill: src(%3d/%3d), dest(%3d/%3d), fill(%3d/%3d)", + xga.curx,xga.cury,xga.destx,xga.desty,xga.MAPcount,xga.MIPcount); #endif + XGA_DrawPattern(val); break; default: LOG_MSG("XGA: Unhandled draw command %x", cmd); break; - } } -void XGA_SetDualReg(Bit32u& reg, Bitu val) -{ +void XGA_SetDualReg(Bit32u& reg, Bitu val) { switch(vga.mode) { - case M_LIN8: reg = val&0x000000ff; break; - case M_LIN15: case M_LIN16: reg = val&0x0000ffff; break; + case M_LIN8: + reg = (Bit8u)(val&0xff); break; + case M_LIN15: + case M_LIN16: + reg = (Bit16u)(val&0xffff); break; case M_LIN32: { if(xga.control1 & 0x200) reg = val; @@ -958,11 +970,12 @@ void XGA_SetDualReg(Bit32u& reg, Bitu val) } } -Bitu XGA_GetDualReg(Bit32u reg) -{ +Bitu XGA_GetDualReg(Bit32u reg) { switch(vga.mode) { - case M_LIN8: return reg&0x000000ff; - case M_LIN15: case M_LIN16: return reg&0x0000ffff; + case M_LIN8: + return (Bit8u)(reg&0xff); + case M_LIN15: case M_LIN16: + return (Bit16u)(reg&0xffff); case M_LIN32: { if(xga.control1 & 0x200) return reg; @@ -976,15 +989,111 @@ Bitu XGA_GetDualReg(Bit32u reg) return 0; } +extern Bitu vga_read_p3da(Bitu port,Bitu iolen); + +extern void vga_write_p3d4(Bitu port,Bitu val,Bitu iolen); +extern Bitu vga_read_p3d4(Bitu port,Bitu iolen); + +extern void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen); +extern Bitu vga_read_p3d5(Bitu port,Bitu iolen); + void XGA_Write(Bitu port, Bitu val, Bitu len) { + //LOG_MSG("XGA: Write to port %x, val %8x, len %x", port,val, len); + switch(port) { + case 0x8100:// drawing control: row (low word), column (high word) + // "CUR_X" and "CUR_Y" (see PORT 82E8h,PORT 86E8h) + xga.cury = val & 0x0fff; + if(len==4) xga.curx = (val>>16)&0x0fff; + break; + case 0x8102: + xga.curx = val& 0x0fff; + break; + + case 0x8108:// DWORD drawing control: destination Y and axial step + // constant (low word), destination X and axial step + // constant (high word) (see PORT 8AE8h,PORT 8EE8h) + xga.desty = val&0x3FFF; + if(len==4) xga.destx = (val>>16)&0x3fff; + break; + case 0x810a: + xga.destx = val&0x3fff; + break; + case 0x8110: // WORD error term (see PORT 92E8h) + xga.ErrTerm = val&0x3FFF; + break; + + case 0x8120: // packed MMIO: DWORD background color (see PORT A2E8h) + //if(len==4) xga.backcolor = val; + //else + XGA_SetDualReg(xga.backcolor, val); + break; + case 0x8124: // packed MMIO: DWORD foreground color (see PORT A6E8h) + //if(len==4) xga.forecolor = val; // TODO + //else + XGA_SetDualReg(xga.forecolor, val); + break; + case 0x8128: // DWORD write mask (see PORT AAE8h) + //if(len==4) xga.writemask = val; + //else + XGA_SetDualReg(xga.writemask, val); + break; + case 0x812C: // DWORD read mask (see PORT AEE8h) + //if(len==4) xga.readmask = val; + //else + XGA_SetDualReg(xga.readmask, val); + break; + case 0x8134: // packed MMIO: DWORD background mix (low word) and + // foreground mix (high word) (see PORT B6E8h,PORT BAE8h) + xga.backmix = val&0xFFFF; + if(len==4) xga.foremix = (val>>16); + break; + case 0x8136: + xga.foremix = val; + break; + case 0x8138:// DWORD top scissors (low word) and left scissors (high + // word) (see PORT BEE8h,#P1047) + xga.scissors.y1=val&0x0fff; + if(len==4) xga.scissors.x1 = (val>>16)&0x0fff; + break; + case 0x813a: + xga.scissors.x1 = val&0x0fff; + break; + case 0x813C:// DWORD bottom scissors (low word) and right scissors + // (high word) (see PORT BEE8h,#P1047) + xga.scissors.y2=val&0x0fff; + if(len==4) xga.scissors.x2 = (val>>16)&0x0fff; + break; + case 0x813e: + xga.scissors.x2 = val&0x0fff; + break; + + case 0x8140:// DWORD data manipulation control (low word) and + // miscellaneous 2 (high word) (see PORT BEE8h,#P1047) + xga.pix_cntl=val&0xFFFF; + if(len==4) xga.control2=(val>>16)&0x0fff; + break; + case 0x8144:// DWORD miscellaneous (low word) and read register select + // (high word)(see PORT BEE8h,#P1047) + xga.control1=val&0xffff; + if(len==4)xga.read_sel=(val>>16)&0x7; + break; + case 0x8148:// DWORD minor axis pixel count (low word) and major axis + // pixel count (high word) (see PORT BEE8h,#P1047,PORT 96E8h) + xga.MIPcount = val&0x0fff; + if(len==4) xga.MAPcount = (val>>16)&0x0fff; + break; + case 0x814a: + xga.MAPcount = val&0x0fff; + break; case 0x92e8: - xga.ErrTerm = val; + xga.ErrTerm = val&0x3FFF; break; case 0x96e8: - xga.MAPcount = val; + xga.MAPcount = val&0x0fff; break; case 0x9ae8: + case 0x8118: // Trio64V+ packed MMIO XGA_DrawCmd(val, len); break; case 0xa2e8: @@ -1000,16 +1109,19 @@ void XGA_Write(Bitu port, Bitu val, Bitu len) { XGA_SetDualReg(xga.readmask, val); break; case 0x82e8: - xga.cury = val; + xga.cury = val&0x0fff; break; case 0x86e8: - xga.curx = val; + xga.curx = val&0x0fff; break; case 0x8ae8: - xga.desty = val; + xga.desty = val&0x3fff; break; case 0x8ee8: - xga.destx = val; + xga.destx = val&0x3fff; + break; + case 0xb2e8: + LOG_MSG("COLOR_CMP not implemented"); break; case 0xb6e8: xga.backmix = val; @@ -1020,38 +1132,63 @@ void XGA_Write(Bitu port, Bitu val, Bitu len) { case 0xbee8: XGA_Write_Multifunc(val, len); break; - case 0x0e2e0: - if(!xga.waitcmd.newline) { - xga.waitcmd.curx = xga.waitcmd.x1; - xga.waitcmd.cury++; - xga.waitcmd.newline = true; - } - - XGA_DrawWait(val, len); - if(xga.waitcmd.cury > xga.waitcmd.y2) xga.waitcmd.wait = false; - break; case 0xe2e8: xga.waitcmd.newline = false; XGA_DrawWait(val, len); break; + case 0x83d4: + if(len==1) vga_write_p3d4(0,val,1); + else if(len==2) { + vga_write_p3d4(0,val&0xff,1); + vga_write_p3d5(0,val>>8,1); + } + else E_Exit("unimplemented XGA MMIO"); + break; + case 0x83d5: + if(len==1) vga_write_p3d5(0,val,1); + else E_Exit("unimplemented XGA MMIO"); + break; default: - LOG_MSG("XGA: Wrote to port %x with %x, len %x", port, val, len); + if(port <= 0x4000) { + //LOG_MSG("XGA: Wrote to port %4x with %08x, len %x", port, val, len); + xga.waitcmd.newline = false; + XGA_DrawWait(val, len); + + } + else LOG_MSG("XGA: Wrote to port %x with %x, len %x", port, val, len); break; } - } Bitu XGA_Read(Bitu port, Bitu len) { - //LOG_MSG("XGA: Read from port %x, len %x", port, len); switch(port) { + case 0x8118: case 0x9ae8: - return 0x0; - case 0x9ae9: - if(xga.waitcmd.wait) { - return 0x4; - } else { - return 0x0; + return 0x400; // nothing busy + break; + case 0x81ec: // S3 video data processor + return 0x00007000; + break; + case 0x83da: + { + Bits delaycyc = CPU_CycleMax/5000; + if(GCC_UNLIKELY(CPU_Cycles < 3*delaycyc)) delaycyc = 0; + CPU_Cycles -= delaycyc; + CPU_IODelayRemoved += delaycyc; + return vga_read_p3da(0,0); + break; } + case 0x83d4: + if(len==1) return vga_read_p3d4(0,0); + else E_Exit("unimplemented XGA MMIO"); + break; + case 0x83d5: + if(len==1) return vga_read_p3d5(0,0); + else E_Exit("unimplemented XGA MMIO"); + break; + case 0x9ae9: + if(xga.waitcmd.wait) return 0x4; + else return 0x0; case 0xbee8: return XGA_Read_Multifunc(); case 0xa2e8: @@ -1067,9 +1204,10 @@ Bitu XGA_Read(Bitu port, Bitu len) { return XGA_GetDualReg(xga.readmask); break; default: - LOG_MSG("XGA: Read from port %x, len %x", port, len); - return 0x0; + //LOG_MSG("XGA: Read from port %x, len %x", port, len); + break; } + return 0xffffffff; } void VGA_SetupXGA(void) { @@ -1077,6 +1215,11 @@ void VGA_SetupXGA(void) { memset(&xga, 0, sizeof(XGAStatus)); + xga.scissors.y1 = 0; + xga.scissors.x1 = 0; + xga.scissors.y2 = 0xFFF; + xga.scissors.x2 = 0xFFF; + IO_RegisterWriteHandler(0x42e8,&XGA_Write,IO_MB | IO_MW | IO_MD); IO_RegisterReadHandler(0x42e8,&XGA_Read,IO_MB | IO_MW | IO_MD); diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index da24595a..f008954b 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.70 2007-11-05 18:42:56 qbix79 Exp $ */ +/* $Id: int10_modes.cpp,v 1.71 2007-12-10 22:11:13 c2woody Exp $ */ #include @@ -57,51 +57,69 @@ VideoModeBlock ModeList_VGA[]={ { 0x054 ,M_TEXT ,1056,688, 132,43, 8, 16, 1 ,0xB8000 ,0x4000, 192, 800, 132,688, 0 }, { 0x055 ,M_TEXT ,1056,400, 132,25, 8, 16, 1 ,0xB8000 ,0x2000, 192, 449, 132,400, 0 }, +/* Alias of mode 102 */ { 0x06A ,M_LIN4 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, /* Follow vesa 1.2 for first 0x20 */ { 0x100 ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, { 0x101 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, -{ 0x102 ,M_LIN4 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, -{ 0x103 ,M_LIN8 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, -{ 0x104 ,M_LIN4 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,150 ,800 ,128,768 ,0 }, -{ 0x105 ,M_LIN8 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,150 ,800 ,128,768 ,0 }, +{ 0x102 ,M_LIN4 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,132 ,628 ,100,600 ,0 }, +{ 0x103 ,M_LIN8 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,132 ,628 ,100,600 ,0 }, +{ 0x104 ,M_LIN4 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,168 ,806 ,128,768 ,0 }, +{ 0x105 ,M_LIN8 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,168 ,806 ,128,768 ,0 }, +{ 0x106 ,M_LIN4 ,1280,1024,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,212 ,1066,160,1024,0 }, +{ 0x107 ,M_LIN8 ,1280,1024,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,212 ,1066,160,1024,0 }, { 0x10D ,M_LIN15 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, { 0x10E ,M_LIN16 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, -{ 0x10F ,M_LIN32 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, -{ 0x110 ,M_LIN15 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, -{ 0x111 ,M_LIN16 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, +{ 0x10F ,M_LIN32 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,50 ,449 ,40 ,400 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x110 ,M_LIN15 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,200 ,525 ,160,480 ,0 }, +{ 0x111 ,M_LIN16 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,200 ,525 ,160,480 ,0 }, { 0x112 ,M_LIN32 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, -{ 0x113 ,M_LIN15 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, -{ 0x114 ,M_LIN16 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, -{ 0x115 ,M_LIN32 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, - -{ 0x116 ,M_LIN15 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,150 ,800 ,128,768 ,0 }, -{ 0x117 ,M_LIN16 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,150 ,800 ,128,768 ,0 }, -{ 0x118 ,M_LIN32 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,150 ,800 ,128,768 ,0 }, +{ 0x113 ,M_LIN15 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,264 ,628 ,200,600 ,0 }, +{ 0x114 ,M_LIN16 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,264 ,628 ,200,600 ,0 }, +{ 0x115 ,M_LIN32 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,132 ,628 ,100,600 ,0 }, +{ 0x116 ,M_LIN15 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,336 ,806 ,256,768 ,0 }, +{ 0x117 ,M_LIN16 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,336 ,806 ,256,768 ,0 }, +{ 0x118 ,M_LIN32 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,168 ,806 ,128,768 ,0 }, +/* those should be interlaced but ok */ +//{ 0x119 ,M_LIN15 ,1280,1024,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,424 ,1066,320,1024,0 }, +//{ 0x11A ,M_LIN16 ,1280,1024,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,424 ,1066,320,1024,0 }, { 0x150 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, { 0x151 ,M_LIN8 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, { 0x152 ,M_LIN8 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE }, { 0x153 ,M_LIN8 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE }, -{ 0x160 ,M_LIN15 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, -{ 0x161 ,M_LIN15 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE }, -{ 0x162 ,M_LIN15 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE }, -{ 0x165 ,M_LIN15 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, +{ 0x160 ,M_LIN15 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 , 80 ,480 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x161 ,M_LIN15 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 , 80 ,400 , _VGA_PIXEL_DOUBLE }, +{ 0x162 ,M_LIN15 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 , 80 ,480 , _VGA_PIXEL_DOUBLE }, +{ 0x165 ,M_LIN15 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,200 ,449 ,160 ,400 ,0 }, -{ 0x170 ,M_LIN16 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, -{ 0x171 ,M_LIN16 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE }, -{ 0x172 ,M_LIN16 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE }, -{ 0x175 ,M_LIN16 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, +{ 0x170 ,M_LIN16 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 , 80 ,480 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x171 ,M_LIN16 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 , 80 ,400 , _VGA_PIXEL_DOUBLE }, +{ 0x172 ,M_LIN16 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 , 80 ,480 , _VGA_PIXEL_DOUBLE }, +{ 0x175 ,M_LIN16 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,200 ,449 ,160 ,400 ,0 }, -{ 0x190 ,M_LIN32 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, -{ 0x191 ,M_LIN32 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE }, -{ 0x192 ,M_LIN32 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , _VGA_PIXEL_DOUBLE }, -{ 0x195 ,M_LIN32 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, +{ 0x190 ,M_LIN32 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000, 50 ,525 ,40 ,480 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, +{ 0x191 ,M_LIN32 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000, 50 ,449 ,40 ,400 , _VGA_PIXEL_DOUBLE }, +{ 0x192 ,M_LIN32 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000, 50 ,525 ,40 ,480 , _VGA_PIXEL_DOUBLE }, +/* S3 specific modes */ +{ 0x207 ,M_LIN8 ,1152,864,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,182 ,948 ,144,864 ,0 }, +{ 0x209 ,M_LIN15 ,1152,864,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,364 ,948 ,288,864 ,0 }, +{ 0x20A ,M_LIN16 ,1152,864,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,364 ,948 ,288,864 ,0 }, +//{ 0x20B ,M_LIN32 ,1152,864,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,182 ,948 ,144,864 ,0 }, +{ 0x213 ,M_LIN32 ,640 ,400,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, + +/* Some custom modes */ +//{ 0x220 ,M_LIN32 ,1280,1024,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,212 ,1066,160,1024,0 }, +// A nice 16:9 mode +{ 0x222 ,M_LIN8 ,848 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,132 ,525 ,106 ,480 ,0 }, +{ 0x223 ,M_LIN15 ,848 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,264 ,525 ,212 ,480 ,0 }, +{ 0x224 ,M_LIN16 ,848 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,264 ,525 ,212 ,480 ,0 }, +{ 0x225 ,M_LIN32 ,848 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,132 ,525 ,106 ,480 ,0 }, {0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, }; @@ -515,6 +533,9 @@ bool INT10_SetVideoMode(Bitu mode) { if (mono_mode) crtc_base=0x3b4; else crtc_base=0x3d4; + // Disable MMIO here so we can read / write memory + if (IS_VGA_ARCH) IO_Write(crtc_base,0x53);IO_Write(crtc_base+1,0x0); + /* Setup MISC Output Register */ Bit8u misc_output=0x2 | (mono_mode ? 0x0 : 0x1); @@ -804,9 +825,7 @@ bool INT10_SetVideoMode(Bitu mode) { /* Setup Pixel format */ switch (CurMode->type) { case M_LIN8: - /* This should be 0x0 according to the specs but makes it easier to detect - compared to normal vga modes now */ - misc_control_2=0x10; + misc_control_2=0x00; break; case M_LIN15: misc_control_2=0x30; @@ -939,7 +958,9 @@ att_text16: break; case M_VGA: case M_LIN8: + case M_LIN15: case M_LIN16: + case M_LIN32: for (i=0;i<16;i++) att_data[i]=i; att_data[0x10]=0x41; //Color Graphics 8-bit break; @@ -993,7 +1014,9 @@ dac_text16: break; case M_VGA: case M_LIN8: + case M_LIN15: case M_LIN16: + case M_LIN32: for (i=0;i<256;i++) { IO_Write(0x3c9,vga_palette[i][0]); IO_Write(0x3c9,vga_palette[i][1]); @@ -1056,10 +1079,51 @@ dac_text16: IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 24)); IO_Write(crtc_base,0x5a); IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 16)); + IO_Write(crtc_base,0x6b); // BIOS scratchpad + IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 24)); + /* Setup some remaining S3 registers */ - Bitu reg_31; + IO_Write(crtc_base,0x41); // BIOS scratchpad + IO_Write(crtc_base+1,0x88); + IO_Write(crtc_base,0x52); // extended BIOS scratchpad + IO_Write(crtc_base+1,0x80); + + // Accellerator setup + Bitu reg_50=0; switch (CurMode->type) { - case M_LIN4: + case M_LIN15: + case M_LIN16: reg_50|=0x10; break; + case M_LIN32: reg_50|=0x30; break; + } + switch(CurMode->swidth) + { + case 640: reg_50|=0x40; break; + case 800: reg_50|=0x80; break; + case 1024: break; + case 1152: reg_50|=0x01; break; + case 1280: reg_50|=0xc1; break; + } + IO_WriteB(crtc_base,0x50); IO_WriteB(crtc_base+1,reg_50); + + Bitu reg_31, reg_3a; + switch (CurMode->type) { + case M_LIN15: + case M_LIN16: + case M_LIN32: + reg_3a=0x15; + break; + case M_LIN8: + // S3VBE20 does it this way. The other double pixel bit does not + // seem to have an effect on the Trio64. + if(CurMode->special&_VGA_PIXEL_DOUBLE) reg_3a=0x5; + else reg_3a=0x15; + break; + default: + reg_3a=5; + }; + + switch (CurMode->type) { + case M_LIN4: // <- Theres a discrepance with real hardware on this case M_LIN8: case M_LIN15: case M_LIN16: @@ -1070,9 +1134,9 @@ dac_text16: reg_31 = 0; break; } + IO_Write(crtc_base,0x3a);IO_Write(crtc_base+1,reg_3a); IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,reg_31); //Enable banked memory and 256k+ access IO_Write(crtc_base,0x58);IO_Write(crtc_base+1,0x3); //Enable 8 mb of linear addressing - IO_Write(crtc_base,0x53);IO_Write(crtc_base+1,0x0); //Disable MMIO IO_Write(crtc_base,0x38);IO_Write(crtc_base+1,0x48); //Register lock 1 IO_Write(crtc_base,0x39);IO_Write(crtc_base+1,0xa5); //Register lock 2 diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index b66a0d2b..0aaf6c06 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.29 2007-09-24 20:50:40 c2woody Exp $ */ +/* $Id: int10_vesa.cpp,v 1.30 2007-12-10 22:11:13 c2woody Exp $ */ #include #include @@ -115,7 +115,7 @@ Bit8u VESA_GetSVGAInformation(Bit16u seg,Bit16u off) { } mem_writed(buffer+0x0a,0x0); //Capabilities and flags mem_writed(buffer+0x0e,int10.rom.vesa_modes); //VESA Mode list - mem_writew(buffer+0x12,32); //32 64kb blocks for 2 mb memory + mem_writew(buffer+0x12,Bit16u(VGA_MEMORY/(64*1024))); // memory size in 64kb blocks return 0x00; } @@ -124,6 +124,7 @@ Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off) { memset(&minfo,0,sizeof(minfo)); PhysPt buf=PhysMake(seg,off); Bitu pageSize; + Bit8u modeAttributes; Bitu i=0; mode&=0x3fff; // vbe2 compatible, ignore lfb and keep screen content bits @@ -138,27 +139,33 @@ foundit: case M_LIN4: pageSize = mblock->sheight * mblock->swidth/2; pageSize = (pageSize | 15) & ~ 15; - var_write(&minfo.NumberOfImagePages,(512*1024 / pageSize)-1); var_write(&minfo.BytesPerScanLine,mblock->swidth/8); var_write(&minfo.NumberOfPlanes,0x4); var_write(&minfo.BitsPerPixel,4); var_write(&minfo.MemoryModel,3); //ega planar mode - var_write(&minfo.ModeAttributes,0x1b); //Color, graphics, no linear buffer + modeAttributes = 0x1b; // Color, graphics, no linear buffer + + if(pageSize > 512*1024) { // this limitation is not on the real card + var_write(&minfo.ModeAttributes, modeAttributes & ~0x1); + var_write(&minfo.NumberOfImagePages,0); + } else { + var_write(&minfo.ModeAttributes, modeAttributes); + Bitu pages = (512*1024 / pageSize)-1; + var_write(&minfo.NumberOfImagePages,pages); + } break; case M_LIN8: pageSize = mblock->sheight * mblock->swidth; pageSize = (pageSize | 15) & ~ 15; - var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); var_write(&minfo.BytesPerScanLine,mblock->swidth); var_write(&minfo.NumberOfPlanes,0x1); var_write(&minfo.BitsPerPixel,8); var_write(&minfo.MemoryModel,4); //packed pixel - var_write(&minfo.ModeAttributes,0x9b); //Color, graphics, linear buffer + modeAttributes = 0x9b; // Color, graphics, linear buffer break; case M_LIN15: pageSize = mblock->sheight * mblock->swidth*2; pageSize = (pageSize | 15) & ~ 15; - var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); var_write(&minfo.BytesPerScanLine,mblock->swidth*2); var_write(&minfo.NumberOfPlanes,0x1); var_write(&minfo.BitsPerPixel,15); @@ -171,12 +178,11 @@ foundit: var_write(&minfo.BlueMaskPos,0); var_write(&minfo.ReservedMaskSize,0x01); var_write(&minfo.ReservedMaskPos,0x0f); - var_write(&minfo.ModeAttributes,0x9b); //Color, graphics, linear buffer + modeAttributes = 0x9b; // Color, graphics, linear buffer break; case M_LIN16: pageSize = mblock->sheight * mblock->swidth*2; pageSize = (pageSize | 15) & ~ 15; - var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); var_write(&minfo.BytesPerScanLine,mblock->swidth*2); var_write(&minfo.NumberOfPlanes,0x1); var_write(&minfo.BitsPerPixel,16); @@ -187,12 +193,11 @@ foundit: var_write(&minfo.GreenMaskPos,5); var_write(&minfo.BlueMaskSize,5); var_write(&minfo.BlueMaskPos,0); - var_write(&minfo.ModeAttributes,0x9b); //Color, graphics, linear buffer + modeAttributes = 0x9b; // Color, graphics, linear buffer break; case M_LIN32: pageSize = mblock->sheight * mblock->swidth*4; pageSize = (pageSize | 15) & ~ 15; - var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); var_write(&minfo.BytesPerScanLine,mblock->swidth*4); var_write(&minfo.NumberOfPlanes,0x1); var_write(&minfo.BitsPerPixel,32); @@ -205,22 +210,33 @@ foundit: var_write(&minfo.BlueMaskPos,0x0); var_write(&minfo.ReservedMaskSize,0x8); var_write(&minfo.ReservedMaskPos,0x18); - var_write(&minfo.ModeAttributes,0x9b); //Color, graphics, linear buffer + modeAttributes = 0x9b; // Color, graphics, linear buffer break; /* case M_TEXT: pageSize = mblock->sheight/8 * mblock->swidth*2/8; pageSize = (pageSize | 15) & ~ 15; - var_write(&minfo.NumberOfImagePages,(2*1024*1024 / pageSize)-1); var_write(&minfo.BytesPerScanLine,mblock->swidth*2/8); var_write(&minfo.NumberOfPlanes,0x4); var_write(&minfo.BitsPerPixel,4); var_write(&minfo.MemoryModel,0); //Text - var_write(&minfo.ModeAttributes,0x0f); //Color, text, bios output + modeAttributes = 0x0f; //Color, text, bios output break; */ default: return 0x1; } - var_write(&minfo.WinAAttributes,0x7); //Exists/readable/writable + var_write(&minfo.WinAAttributes,0x7); // Exists/readable/writable + + if(mblock->type != M_LIN4) + if(pageSize > VGA_MEMORY) { + // Mode not supported by current hardware configuration + var_write(&minfo.ModeAttributes, modeAttributes & ~0x1); + var_write(&minfo.NumberOfImagePages,0); + } else { + var_write(&minfo.ModeAttributes, modeAttributes); + Bitu pages = (VGA_MEMORY / pageSize)-1; + var_write(&minfo.NumberOfImagePages,pages); + } + if (mblock->type==M_TEXT) { var_write(&minfo.WinGranularity,32); var_write(&minfo.WinSize,32); @@ -333,15 +349,17 @@ Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u val, Bit16u & bytes,Bit16u & pixe } switch (subcall) { case 0x00: /* Set in pixels */ - vga.config.scan_len = (val * bpp); + if(CurMode->type==M_LIN4) vga.config.scan_len=val/2; + else vga.config.scan_len = (val * bpp); break; case 0x02: /* Set in bytes */ - vga.config.scan_len = val; + if(CurMode->type==M_LIN4) vga.config.scan_len = val*4; + else vga.config.scan_len = val; break; case 0x03: /* Get maximum */ bytes=0x400*4; pixels=bytes/bpp; - lines = 2*1024*1024 / bytes; + lines = VGA_MEMORY / bytes; return 0x00; case 0x01: /* Get lengths */ break; @@ -354,9 +372,16 @@ Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u val, Bit16u & bytes,Bit16u & pixe vga.config.scan_len += 8; vga.config.scan_len /= 8; } - pixels=(vga.config.scan_len*8)/bpp; - bytes=vga.config.scan_len*8; - lines = 2*1024*1024 / bytes; + if(CurMode->type==M_LIN4) { + pixels=(vga.config.scan_len*16)/bpp; + bytes=vga.config.scan_len*2; + lines = Bit16u(VGA_MEMORY /( bytes*4)); + } + else { + pixels=(vga.config.scan_len*8)/bpp; + bytes=vga.config.scan_len*8; + lines = Bit16u(VGA_MEMORY / bytes); + } VGA_StartResize(); return 0x0; } @@ -366,7 +391,7 @@ Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y) { Bitu start; switch (CurMode->type) { case M_LIN4: - start=vga.config.scan_len*8*y+x; + start=vga.config.scan_len*16*y+x; vga.config.display_start=start/8; IO_Read(0x3da); IO_Write(0x3c0,0x13+32); From 7473dabb3daa20f9c33925d7ba6528f49bad571e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 11 Dec 2007 21:25:14 +0000 Subject: [PATCH 2972/4131] add program to load external graphics bioses Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3060 --- src/dos/dos_programs.cpp | 61 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 900b225c..08083c97 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.79 2007-11-01 12:15:34 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.80 2007-12-11 21:25:14 c2woody Exp $ */ #include "dosbox.h" #include @@ -756,12 +756,66 @@ public: } }; - static void BOOT_ProgramStart(Program * * make) { *make=new BOOT; } +#if C_DEBUG +class LDGFXROM : public Program { +public: + void Run(void) { + if (!(cmd->FindCommand(1, temp_line))) return; + + Bit8u drive; + char fullname[DOS_PATHLENGTH]; + + localDrive* ldp=0; + if (!DOS_MakeName((char *)temp_line.c_str(),fullname,&drive)) return; + + try { + ldp=dynamic_cast(Drives[drive]); + if(!ldp) return; + + FILE *tmpfile = ldp->GetSystemFilePtr(fullname, "rb"); + if(tmpfile == NULL) { + LOG_MSG("BIOS file not accessible."); + return; + } + fseek(tmpfile, 0L, SEEK_END); + if (ftell(tmpfile)>0x10000) { + LOG_MSG("BIOS file too large."); + return; + } + fseek(tmpfile, 0L, SEEK_SET); + + PhysPt rom_base=PhysMake(0xc000,0); + + Bit8u vga_buffer[0x10000]; + Bitu data_written=0; + Bitu data_read=fread(vga_buffer, 1, 0x10000, tmpfile); + for (Bitu ct=0; ct Date: Wed, 12 Dec 2007 13:37:38 +0000 Subject: [PATCH 2973/4131] Sync mouse on fullscreen startup. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3061 --- src/gui/sdlmain.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 83df14fe..9d15234b 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.136 2007-11-06 20:08:34 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.137 2007-12-12 13:37:38 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1037,6 +1037,10 @@ static void GUI_StartUp(Section * sec) { sdl.mouse.autolock=false; sdl.mouse.sensitivity=section->Get_int("sensitivity"); const char * output=section->Get_string("output"); + + /* Setup Mouse correctly if fullscreen */ + if(sdl.desktop.fullscreen) GFX_CaptureMouse(); + if (!strcasecmp(output,"surface")) { sdl.desktop.want_type=SCREEN_SURFACE; #if (HAVE_DDRAW_H) && defined(WIN32) From a1b4e1c778627a689991316d8c7b1018aae2a0fd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 12 Dec 2007 19:18:39 +0000 Subject: [PATCH 2974/4131] Add (modified) version of patch 1490638: Coremidi support by Peter McCombs Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3062 --- configure.in | 2 +- src/gui/midi.cpp | 1 + src/gui/midi_coremidi.h | 105 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 src/gui/midi_coremidi.h diff --git a/configure.in b/configure.in index b453220f..0b1ba0f9 100644 --- a/configure.in +++ b/configure.in @@ -404,7 +404,7 @@ case "$target" in dnl to do more to distinguish them. dnl For now I am lazy and do not add proper detection code. AC_DEFINE(MACOSX, 1, [Compiling on Mac OS X]) - LIBS="$LIBS -framework AudioUnit" + LIBS="$LIBS -framework CoreMidi -framework AudioUnit" AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).]) ;; *-*-linux*) diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 22407130..85a6a8fe 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -80,6 +80,7 @@ MidiHandler Midi_none; #if defined(MACOSX) #include "midi_coreaudio.h" +#include "midi_coremidi.h" #elif defined (WIN32) diff --git a/src/gui/midi_coremidi.h b/src/gui/midi_coremidi.h new file mode 100644 index 00000000..4f44fe2b --- /dev/null +++ b/src/gui/midi_coremidi.h @@ -0,0 +1,105 @@ +/* + * 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 + +class MidiHandler_coremidi : public MidiHandler { +private: + MIDIPortRef m_port; + MIDIClientRef m_client; + MIDIEndpointRef m_endpoint; + MIDIPacket* m_pCurPacket; +public: + MidiHandler_coremidi() {m_pCurPacket = 0;} + char * GetName(void) { return "coremidi"; } + bool Open(const char * conf) { + + // Get the MIDIEndPoint + m_endpoint = 0; + OSStatus result; + Bitu numDests = MIDIGetNumberOfDestinations(); + Bitu destId = 0; + if(conf && conf[0]) destId = atoi(conf); + if (destId < numDests) + { + m_endpoint = MIDIGetDestination(destId); + } + + // Create a MIDI client and port + MIDIClientCreate(CFSTR("MyClient"), 0, 0, &m_client); + + if (!m_client) + { + LOG_MSG("MIDI:coremidi: No client created."); + return false; + } + + MIDIOutputPortCreate(m_client, CFSTR("MyOutPort"), &m_port); + + if (!m_port) + { + LOG_MSG("MIDI:coremidi: No port created."); + return false; + } + + + return true; + } + + void Close(void) { + // Dispose the port + MIDIPortDispose(m_port); + + // Dispose the client + MIDIClientDispose(m_client); + + // Dispose the endpoint + MIDIEndpointDispose(m_endpoint); + } + + void PlayMsg(Bit8u * msg) { + // Acquire a MIDIPacketList + Byte packetBuf[128]; + MIDIPacketList *packetList = (MIDIPacketList *)packetBuf; + m_pCurPacket = MIDIPacketListInit(packetList); + + // Determine the length of msg + Bitu len=MIDI_evt_len[*msg]; + + // Add msg to the MIDIPacketList + MIDIPacketListAdd(packetList, (ByteCount)sizeof(packetBuf), m_pCurPacket, (MIDITimeStamp)0, len, msg); + + // Send the MIDIPacketList + MIDISend(m_port,m_endpoint,packetList); + } + + void PlaySysex(Bit8u * sysex, Bitu len) { + // Acquire a MIDIPacketList + Byte packetBuf[SYSEX_SIZE*4]; + Bitu pos=0; + MIDIPacketList *packetList = (MIDIPacketList *)packetBuf; + m_pCurPacket = MIDIPacketListInit(packetList); + + // Add msg to the MIDIPacketList + MIDIPacketListAdd(packetList, (ByteCount)sizeof(packetBuf), m_pCurPacket, (MIDITimeStamp)0, len, sysex); + + // Send the MIDIPacketList + MIDISend(m_port,m_endpoint,packetList); + } +}; + +MidiHandler_coremidi Midi_coremidi; + From debad77a6c0f58ed293f9a94843cfc01b09bedb0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 13 Dec 2007 12:38:13 +0000 Subject: [PATCH 2975/4131] mention it here as well Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3063 --- src/dosbox.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 5be71d77..1291e113 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.123 2007-09-24 20:50:40 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.124 2007-12-13 12:38:13 qbix79 Exp $ */ #include #include @@ -383,7 +383,7 @@ void DOSBOX_Init(void) { MSG_Add("MIDI_CONFIGFILE_HELP", "mpu401 -- Type of MPU-401 to emulate: none, uart or intelligent.\n" "device -- Device that will receive the MIDI data from MPU-401.\n" - " This can be default,alsa,oss,win32,coreaudio,none.\n" + " This can be default,alsa,oss,win32,coreaudio,coremidi,none.\n" "config -- Special configuration options for the device. In Windows put\n" " the id of the device you want to use. See README for details.\n" ); From 8e932280a10a2df8c695f09a0b548a20c75bdd44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 15 Dec 2007 16:28:32 +0000 Subject: [PATCH 2976/4131] some debugger fixes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3064 --- src/debug/debug.cpp | 105 +++++++++++++++++++++---------------- src/debug/debug_disasm.cpp | 2 +- 2 files changed, 61 insertions(+), 46 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 5ffb2b4c..b11f2550 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.90 2007-11-24 17:26:48 c2woody Exp $ */ +/* $Id: debug.cpp,v 1.91 2007-12-15 16:28:32 c2woody Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -448,7 +448,8 @@ bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off) Bitu address; if (bp->GetType()==BKPNT_MEMORY_LINEAR) address = bp->GetOffset(); else address = GetAddress(bp->GetSegment(),bp->GetOffset()); - Bit8u value = mem_readb(address); + Bit8u value=0; + if (mem_readb_checked(address,&value)) return false; if (bp->GetValue() != value) { // Yup, memory value changed DEBUG_ShowMsg("DEBUG: Memory breakpoint %s: %04X:%04X - %02X -> %02X\n",(bp->GetType()==BKPNT_MEMORY_PROT)?"(Prot)":"",bp->GetSegment(),bp->GetOffset(),bp->GetValue(),value); @@ -674,9 +675,7 @@ static void DrawData(void) { else mvwprintw (dbg.win_data,1+y,0,"%04X:%08X ",dataSeg,add); for (int x=0; x<16; x++) { address = GetAddress(dataSeg,add); - if (!(get_tlb_readhandler(address)->flags & PFLAG_INIT)) { - ch = mem_readb(address); - } else ch = 0; + if (mem_readb_checked(address,&ch)) ch=0; mvwprintw (dbg.win_data,1+y,14+3*x,"%02X",ch); if (ch<32 || !isprint(*reinterpret_cast(&ch))) ch='.'; mvwprintw (dbg.win_data,1+y,63+x,"%c",ch); @@ -759,8 +758,7 @@ static void DrawRegisters(void) { wrefresh(dbg.win_reg); }; -static void DrawCode(void) -{ +static void DrawCode(void) { bool saveSel; Bit32u disEIP = codeViewData.useEIP; PhysPt start = GetAddress(codeViewData.useCS,codeViewData.useEIP); @@ -796,7 +794,11 @@ static void DrawCode(void) mvwprintw(dbg.win_code,i,0,"%04X:%04X ",codeViewData.useCS,disEIP); if (drawsize>10) { toolarge = true; drawsize = 9; }; - for (c=0;c %04Xxxx flags [uw] %x:%x::%x:%x",i,entry.block.base,entry.block.us,table.block.us,entry.block.wr,table.block.wr); + sprintf(out1,"page %05Xxxx -> %04Xxxx flags [uw] %x:%x::%x:%x [d=%x|a=%x]", + i,entry.block.base,entry.block.us,table.block.us, + entry.block.wr,table.block.wr,entry.block.d,entry.block.a); LOG(LOG_MISC,LOG_ERROR)(out1); } } @@ -1764,8 +1766,7 @@ void LogPages(char* selname) } }; -static void LogCPUInfo(void) -{ +static void LogCPUInfo(void) { char out1[512]; sprintf(out1,"cr0:%08X cr2:%08X cr3:%08X cpl=%x",cpu.cr0,paging.cr2,paging.cr3,cpu.cpl); LOG(LOG_MISC,LOG_ERROR)(out1); @@ -1778,13 +1779,15 @@ static void LogCPUInfo(void) Bitu sel=CPU_STR(); Descriptor desc; - cpu.gdt.GetDescriptor(sel,desc); - sprintf(out1,"TR selector=%04X, base=%08X limit=%08X*%X",sel,desc.GetBase(),desc.GetLimit(),desc.saved.seg.g?0x4000:1); - LOG(LOG_MISC,LOG_ERROR)(out1); + if (cpu.gdt.GetDescriptor(sel,desc)) { + sprintf(out1,"TR selector=%04X, base=%08X limit=%08X*%X",sel,desc.GetBase(),desc.GetLimit(),desc.saved.seg.g?0x4000:1); + LOG(LOG_MISC,LOG_ERROR)(out1); + } sel=CPU_SLDT(); - cpu.gdt.GetDescriptor(sel,desc); - sprintf(out1,"LDT selector=%04X, base=%08X limit=%08X*%X",sel,desc.GetBase(),desc.GetLimit(),desc.saved.seg.g?0x4000:1); - LOG(LOG_MISC,LOG_ERROR)(out1); + if (cpu.gdt.GetDescriptor(sel,desc)) { + sprintf(out1,"LDT selector=%04X, base=%08X limit=%08X*%X",sel,desc.GetBase(),desc.GetLimit(),desc.saved.seg.g?0x4000:1); + LOG(LOG_MISC,LOG_ERROR)(out1); + } }; #if C_HEAVY_DEBUG @@ -1813,7 +1816,9 @@ static void LogInstruction(Bit16u segValue, Bit32u eipValue, ofstream& out) { } else if (cpuLogType == 2) { char ibytes[200]=""; char tmpc[200]; for (Bitu i=0; i0) { - sprintf(buffer,"%04X:%04X ",seg,ofs1); for (Bit16u x=0; x<16; x++) { - sprintf (temp,"%02X ",mem_readb(GetAddress(seg,ofs1+x))); - strcat (buffer,temp); + Bit8u value; + if (mem_readb_checked(GetAddress(seg,ofs1+x),&value)) sprintf(temp,"?? ",value); + else sprintf(temp,"%02X ",value); + strcat(buffer,temp); }; ofs1+=16; num-=16; @@ -2080,7 +2085,8 @@ static void SaveMemoryBin(Bitu seg, Bitu ofs1, Bit32u num) { } for(Bitu x = 0; x < num;x++) { - Bit8u val = mem_readb(GetAddress(seg,ofs1+x)); + Bit8u val; + if (mem_readb_checked(GetAddress(seg,ofs1+x),&val)) val=0; fwrite(&val,1,1,f); }; @@ -2088,8 +2094,7 @@ static void SaveMemoryBin(Bitu seg, Bitu ofs1, Bit32u num) { DEBUG_ShowMsg("DEBUG: Memory dump binary success.\n"); }; -static void OutputVecTable(char* filename) -{ +static void OutputVecTable(char* filename) { FILE* f = fopen(filename, "wt"); if (!f) { @@ -2105,8 +2110,9 @@ static void OutputVecTable(char* filename) } #define DEBUG_VAR_BUF_LEN 16 -static void DrawVariables(void) -{ +static void DrawVariables(void) { + if (CDebugVar::varList.size()==0) return; + std::list::iterator i; CDebugVar *dv; char buffer[DEBUG_VAR_BUF_LEN]; @@ -2121,8 +2127,11 @@ static void DrawVariables(void) dv = static_cast(*i); - Bit16u value = mem_readw(dv->GetAdr()); - snprintf(buffer,DEBUG_VAR_BUF_LEN, "0x%04x", value); + Bit16u value; + if (mem_readw_checked(dv->GetAdr(),&value)) + snprintf(buffer,DEBUG_VAR_BUF_LEN, "??????", value); + else + snprintf(buffer,DEBUG_VAR_BUF_LEN, "0x%04x", value); int y = idx / 3; int x = (idx % 3) * 26; @@ -2276,8 +2285,14 @@ bool DEBUG_HeavyIsBreakpoint(void) { } // LogInstruction if (logHeavy) DEBUG_HeavyLogInstruction(); - if(zeroProtect && mem_readd(SegPhys(cs) + reg_eip) == 0) zero_count++; else zero_count = 0; - if(zeroProtect && GCC_UNLIKELY(zero_count == 10)) E_Exit("running zeroed code"); + if (zeroProtect) { + Bit32u value=0; + if (!mem_readd_checked(SegPhys(cs)+reg_eip,&value)) { + if (value == 0) zero_count++; + else zero_count = 0; + } + if (GCC_UNLIKELY(zero_count == 10)) E_Exit("running zeroed code"); + } if (skipFirstInstruction) { skipFirstInstruction = false; diff --git a/src/debug/debug_disasm.cpp b/src/debug/debug_disasm.cpp index 3ccbded5..c9cd7335 100644 --- a/src/debug/debug_disasm.cpp +++ b/src/debug/debug_disasm.cpp @@ -878,7 +878,7 @@ static void percent(char type, char subtype) vofs |= (UINT32)getbyte() << 8; vofs |= (UINT32)getbyte() << 16; vofs |= (UINT32)getbyte() << 24; - name = addr_to_hex(vofs+instruction_offset+INSTRUCTION_SIZE,1); + name = addr_to_hex(vofs+instruction_offset+INSTRUCTION_SIZE,(addrsize == 32)?0:1); break; } if (vofs<0) From b9a73a548c710f420abc505561be43caee9b24a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 19 Dec 2007 21:12:22 +0000 Subject: [PATCH 2977/4131] fix some custom hicolor s3 modes' width settings (hal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3065 --- src/hardware/vga_draw.cpp | 16 ++++++++++------ src/ints/int10_modes.cpp | 7 +++++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index c78c0625..07106670 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.89 2007-12-10 22:11:13 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.90 2007-12-19 21:12:22 c2woody Exp $ */ #include #include @@ -1156,14 +1156,18 @@ void VGA_SetupDrawing(Bitu val) { } // fall-through case M_LIN32: - width<<=1; - // fall-through - case M_LIN15: + width<<=3; + if (vga.crtc.mode_control & 0x8) + doublewidth = true; + /* Use HW mouse cursor drawer if enabled */ + VGA_ActivateHardwareCursor(); + break; + case M_LIN15: case M_LIN16: // 15/16 bpp modes double the horizontal values width<<=2; - if (vga.crtc.mode_control & 0x8) - doublewidth = true; + if ((vga.crtc.mode_control & 0x8) || (vga.s3.pll.cmd & 0x10)) + doublewidth = true; /* Use HW mouse cursor drawer if enabled */ VGA_ActivateHardwareCursor(); break; diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index f008954b..09649a7d 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.71 2007-12-10 22:11:13 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.72 2007-12-19 21:12:22 c2woody Exp $ */ #include @@ -1088,6 +1088,9 @@ dac_text16: IO_Write(crtc_base,0x52); // extended BIOS scratchpad IO_Write(crtc_base+1,0x80); + IO_Write(0x3c4,0x15); + IO_Write(0x3c5,0x03); + // Accellerator setup Bitu reg_50=0; switch (CurMode->type) { @@ -1131,7 +1134,7 @@ dac_text16: reg_31 = 9; break; default: - reg_31 = 0; + reg_31 = 5; break; } IO_Write(crtc_base,0x3a);IO_Write(crtc_base+1,reg_3a); From 4577f5ed590947783ce57353a99c3f5cc66e8f7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 23 Dec 2007 16:00:53 +0000 Subject: [PATCH 2978/4131] resize screen on sequencer font size changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3066 --- src/hardware/vga_attr.cpp | 18 ++++++++++-------- src/hardware/vga_seq.cpp | 9 +++++++-- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index adbf4b45..95c3c810 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_attr.cpp,v 1.26 2007-10-13 16:34:06 c2woody Exp $ */ +/* $Id: vga_attr.cpp,v 1.27 2007-12-23 16:00:53 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -84,13 +84,15 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) { if ((attr(mode_control) ^ val) & 0x08) { VGA_SetBlinking(val & 0x8); } - /* - Special hacks for games programming registers themselves, - Doesn't work if they program EGA16 themselves, - but haven't encountered that yet - */ - attr(mode_control)=val; - VGA_DetermineMode(); + if ((attr(mode_control) ^ val) & 0x04) { + attr(mode_control)=val; + VGA_DetermineMode(); + if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) VGA_StartResize(); + } else { + attr(mode_control)=val; + VGA_DetermineMode(); + } + /* 0 Graphics mode if set, Alphanumeric mode else. 1 Monochrome mode if set, color mode else. diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 85207ee7..8e979ede 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: vga_seq.cpp,v 1.21 2007-12-23 16:00:53 c2woody Exp $ */ + #include "dosbox.h" #include "inout.h" #include "vga.h" @@ -38,10 +40,13 @@ void write_p3c5(Bitu port,Bitu val,Bitu iolen) { break; case 1: /* Clocking Mode */ if (val!=seq(clocking_mode)) { - seq(clocking_mode)=val; // don't resize if only the screen off bit was changed - if ((val&(~0x20))!=(seq(clocking_mode)&(~0x20))) + if ((val&(~0x20))!=(seq(clocking_mode)&(~0x20))) { + seq(clocking_mode)=val; VGA_StartResize(); + } else { + seq(clocking_mode)=val; + } } /* TODO Figure this out :) 0 If set character clocks are 8 dots wide, else 9. From a472b4777b8da0412c83810712f36bffec1980a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 27 Dec 2007 10:57:51 +0000 Subject: [PATCH 2979/4131] small vga fixes (vasyl) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3067 --- src/hardware/vga_s3.cpp | 4 ++-- src/ints/int10_modes.cpp | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index 5c718456..9bf965ed 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_s3.cpp,v 1.9 2007-12-10 22:11:13 c2woody Exp $ */ +/* $Id: vga_s3.cpp,v 1.10 2007-12-27 10:57:51 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -240,7 +240,7 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { } break; case 0x5D: /* Extended Horizontal Overflow */ - if ((val & vga.s3.ex_hor_overflow) ^ 3) { + if ((val ^ vga.s3.ex_hor_overflow) & 3) { vga.s3.ex_hor_overflow=val; VGA_StartResize(); } else vga.s3.ex_hor_overflow=val; diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 09649a7d..c64f2714 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.72 2007-12-19 21:12:22 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.73 2007-12-27 10:57:51 c2woody Exp $ */ #include @@ -971,6 +971,7 @@ att_text16: IO_Write(0x3c0,i); IO_Write(0x3c0,att_data[i]); } + vga.config.pel_panning = 0; IO_Write(0x3c0,0x20); IO_Write(0x3c0,0x00); //Disable palette access IO_Write(0x3c6,0xff); //Reset Pelmask /* Setup the DAC */ @@ -1036,6 +1037,7 @@ dac_text16: IO_Write(0x3c0,i); IO_Write(0x3c0,att_data[i]); } + vga.config.pel_panning = 0; IO_Write(0x3c0,0x20); //Disable palette access } /* Setup some special stuff for different modes */ From 1cf6ec64cce891ed7884080779c50ab24e5c4714 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 27 Dec 2007 13:22:02 +0000 Subject: [PATCH 2980/4131] Forgot to mention it here Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3068 --- src/gui/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index d397a92e..2e608415 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -7,5 +7,5 @@ libgui_a_SOURCES = sdlmain.cpp sdl_mapper.cpp dosbox_logo.h \ render_templates_sai.h render_templates_hq.h \ render_templates_hq2x.h render_templates_hq3x.h \ midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h midi_alsa.h \ - sdl_gui.cpp + midi_coremidi.h sdl_gui.cpp From f119b07834b36abccd11d8140d78d3843635f824 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 27 Dec 2007 15:38:00 +0000 Subject: [PATCH 2981/4131] Fix several buffer overflows (ludwig Nussel). Fix double fcloses Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3069 --- src/dos/dos_programs.cpp | 44 ++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 08083c97..e9c90a1a 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.80 2007-12-11 21:25:14 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.81 2007-12-27 15:38:00 qbix79 Exp $ */ #include "dosbox.h" #include @@ -596,7 +596,7 @@ public: strcat(cmdlist," "); strcat(cmdlist,buf); ct+=1+clen+3; - if (ct>0x1000) break; + if (ct>sizeof(cmdlist)) break; clen=rombuf[ct]; } if (ct>6) { @@ -610,7 +610,7 @@ public: diskSwap[dct]=NULL; } } - fclose(usefile_1); + //fclose(usefile_1); //delete diskSwap closes the file return; } else { while (clen!=0) { @@ -627,7 +627,7 @@ public: } ct+=3; - if (ct>0x1000) break; + if (ct>sizeof(cmdlist)) break; clen=rombuf[ct]; } if (cfound_at<=0) { @@ -642,7 +642,7 @@ public: diskSwap[dct]=NULL; } } - fclose(usefile_1); + //fclose(usefile_1); //Delete diskSwap closes the file return; } } @@ -673,7 +673,7 @@ public: /* read cartridge data into buffer */ fseek(usefile_2, 0x200L, SEEK_SET); fread(rombuf, 1, rombytesize_2-0x200, usefile_2); - fclose(usefile_2); + //fclose(usefile_2); //usefile_2 is in diskSwap structure which should be deleted to close the file /* write cartridge data into ROM */ for(i=0;i0) { /* run cartridge setup */ SegSet16(ds,dos.psp()); SegSet16(es,dos.psp()); CALLBACK_RunRealFar(romseg,cfound_at); - } else { - for(Bitu dct=0;dctFindCommand(commandNr++,temp_line); - strncat(args,temp_line.c_str(),256); - strncat(args," ",256); + if(sizeof(args)-strlen(args)-1 < temp_line.length()+1) + break; + strcat(args,temp_line.c_str()); + strcat(args," "); } while (ok); // Use shell to start program DOS_Shell shell; From 962df668ffcb6833bb6738e7d26200fce6c392c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 29 Dec 2007 20:22:22 +0000 Subject: [PATCH 2982/4131] use dedicated page handler for pages which prohibit write access for user-level (enables fast reading); some code cleanup and small fixes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3070 --- src/cpu/paging.cpp | 317 +++++++++++++++++++++++++++++++++------------ 1 file changed, 236 insertions(+), 81 deletions(-) diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index ddce5992..57ce9e9a 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.cpp,v 1.31 2007-11-29 21:01:46 c2woody Exp $ */ +/* $Id: paging.cpp,v 1.32 2007-12-29 20:22:22 c2woody Exp $ */ #include #include @@ -33,9 +33,12 @@ #define LINK_TOTAL (64*1024) -PagingBlock paging; +#define USERWRITE_PROHIBITED ((cpu.cpl&cpu.mpl)==3) +#define USERACCESS_PROHIBITED(u1,u2) (((u1)==0) && ((u2)==0)) +PagingBlock paging; + Bitu PageHandler::readb(PhysPt addr) { E_Exit("No byte handler for read from %d",addr); @@ -164,36 +167,105 @@ void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu faultcode) { cpudecoder=old_cpudecoder; // LOG_MSG("SS:%04x SP:%08X",SegValue(ss),reg_esp); } - + +static INLINE void InitPageUpdateLink(Bitu relink,PhysPt addr) { + if (relink==0) return; + if (paging.links.used) { + if (paging.links.entries[paging.links.used-1]==(addr>>12)) { + paging.links.used--; + PAGING_UnlinkPages(addr>>12,1); + } + } + if (relink>1) PAGING_LinkPage_ReadOnly(addr>>12,relink); +} + +static INLINE void InitPageCheckPresence(PhysPt lin_addr,bool writing,X86PageEntry& table,X86PageEntry& entry) { + Bitu lin_page=lin_addr >> 12; + Bitu d_index=lin_page >> 10; + Bitu t_index=lin_page & 0x3ff; + Bitu table_addr=(paging.base.page<<12)+d_index*4; + table.load=phys_readd(table_addr); + if (!table.block.p) { + LOG(LOG_PAGING,LOG_NORMAL)("NP Table"); + PAGING_PageFault(lin_addr,table_addr, + (writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04)); + table.load=phys_readd(table_addr); + if (GCC_UNLIKELY(!table.block.p)) + E_Exit("Pagefault didn't correct table"); + } + Bitu entry_addr=(table.block.base<<12)+t_index*4; + entry.load=phys_readd(entry_addr); + if (!entry.block.p) { +// LOG(LOG_PAGING,LOG_NORMAL)("NP Page"); + PAGING_PageFault(lin_addr,entry_addr, + (writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04)); + entry.load=phys_readd(entry_addr); + if (GCC_UNLIKELY(!entry.block.p)) + E_Exit("Pagefault didn't correct page"); + } +} + +static INLINE bool InitPageCheckPresence_CheckOnly(PhysPt lin_addr,bool writing,X86PageEntry& table,X86PageEntry& entry) { + Bitu lin_page=lin_addr >> 12; + Bitu d_index=lin_page >> 10; + Bitu t_index=lin_page & 0x3ff; + Bitu table_addr=(paging.base.page<<12)+d_index*4; + table.load=phys_readd(table_addr); + if (!table.block.p) { + paging.cr2=lin_addr; + cpu.exception.which=EXCEPTION_PF; + cpu.exception.error=(writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04); + return false; + } + Bitu entry_addr=(table.block.base<<12)+t_index*4; + entry.load=phys_readd(entry_addr); + if (!entry.block.p) { + paging.cr2=lin_addr; + cpu.exception.which=EXCEPTION_PF; + cpu.exception.error=(writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04); + return false; + } + return true; +} + + class InitPageHandler : public PageHandler { public: - InitPageHandler() {flags=PFLAG_INIT|PFLAG_NOCODE;} + InitPageHandler() { + flags=PFLAG_INIT|PFLAG_NOCODE; + } Bitu readb(PhysPt addr) { - InitPage(addr,false); - return mem_readb(addr); + Bitu needs_reset=InitPage(addr,false); + Bit8u val=mem_readb(addr); + InitPageUpdateLink(needs_reset,addr); + return val; } Bitu readw(PhysPt addr) { - InitPage(addr,false); - return mem_readw(addr); + Bitu needs_reset=InitPage(addr,false); + Bit16u val=mem_readw(addr); + InitPageUpdateLink(needs_reset,addr); + return val; } Bitu readd(PhysPt addr) { - InitPage(addr,false); - return mem_readd(addr); + Bitu needs_reset=InitPage(addr,false); + Bit32u val=mem_readd(addr); + InitPageUpdateLink(needs_reset,addr); + return val; } void writeb(PhysPt addr,Bitu val) { - bool needs_reset=InitPage(addr,true); + Bitu needs_reset=InitPage(addr,true); mem_writeb(addr,val); - if (GCC_UNLIKELY(needs_reset)) PAGING_UnlinkPages(addr>>12,1); + InitPageUpdateLink(needs_reset,addr); } void writew(PhysPt addr,Bitu val) { - bool needs_reset=InitPage(addr,true); + Bitu needs_reset=InitPage(addr,true); mem_writew(addr,val); - if (GCC_UNLIKELY(needs_reset)) PAGING_UnlinkPages(addr>>12,1); + InitPageUpdateLink(needs_reset,addr); } void writed(PhysPt addr,Bitu val) { - bool needs_reset=InitPage(addr,true); + Bitu needs_reset=InitPage(addr,true); mem_writed(addr,val); - if (GCC_UNLIKELY(needs_reset)) PAGING_UnlinkPages(addr>>12,1); + InitPageUpdateLink(needs_reset,addr); } bool readb_checked(PhysPt addr, Bit8u * val) { if (InitPageCheckOnly(addr,false)) { @@ -231,69 +303,57 @@ public: return false; } else return true; } - bool InitPage(Bitu lin_addr,bool writing) { + Bitu InitPage(Bitu lin_addr,bool writing) { Bitu lin_page=lin_addr >> 12; Bitu phys_page; if (paging.enabled) { - Bitu d_index=lin_page >> 10; - Bitu t_index=lin_page & 0x3ff; - Bitu table_addr=(paging.base.page<<12)+d_index*4; X86PageEntry table; - table.load=phys_readd(table_addr); - if (!table.block.p) { - LOG(LOG_PAGING,LOG_NORMAL)("NP Table"); - PAGING_PageFault(lin_addr,table_addr, - (writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04)); - table.load=phys_readd(table_addr); - if (!table.block.p) - E_Exit("Pagefault didn't correct table"); - } X86PageEntry entry; - Bitu entry_addr=(table.block.base<<12)+t_index*4; - entry.load=phys_readd(entry_addr); - if (!entry.block.p) { -// LOG(LOG_PAGING,LOG_NORMAL)("NP Page"); - PAGING_PageFault(lin_addr,entry_addr, - (writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04)); - entry.load=phys_readd(entry_addr); - if (!entry.block.p) - E_Exit("Pagefault didn't correct page"); - } + InitPageCheckPresence(lin_addr,writing,table,entry); // 0: no action - // 1: can (but currently does not) fail a privilege check - // 2: fails a privilege check + // 1: can (but currently does not) fail a user-level access privilege check + // 2: can (but currently does not) fail a write privilege check + // 3: fails a privilege check Bitu priv_check=0; -// if ((entry.block.us==0) || (table.block.us==0)) { - if ((entry.block.us==0) && (table.block.us==0)) { - if ((cpu.cpl&cpu.mpl)==3) priv_check=2; + if (USERACCESS_PROHIBITED(entry.block.us,table.block.us)) { + if ((cpu.cpl&cpu.mpl)==3) priv_check=3; else priv_check=1; } if ((entry.block.wr==0) || (table.block.wr==0)) { - priv_check=1; - if (writing && ((cpu.cpl&cpu.mpl)==3)) priv_check=2; + if (priv_check==0) priv_check=2; + if (writing && USERWRITE_PROHIBITED) priv_check=3; } - if (priv_check==2) { + if (priv_check==3) { LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x", cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); - PAGING_PageFault(lin_addr,entry_addr,0x05 | (writing?0x02:0x00)); + PAGING_PageFault(lin_addr,(table.block.base<<12)+(lin_page & 0x3ff)*4,0x05 | (writing?0x02:0x00)); + priv_check=0; } if (!table.block.a) { table.block.a=1; //Set access - phys_writed(table_addr,table.load); + phys_writed((paging.base.page<<12)+(lin_page >> 10)*4,table.load); } if ((!entry.block.a) || (!entry.block.d)) { entry.block.a=1; //Set access if (writing) entry.block.d=1; //Set dirty - phys_writed(entry_addr,entry.load); + phys_writed((table.block.base<<12)+(lin_page & 0x3ff)*4,entry.load); } phys_page=entry.block.base; if (priv_check==0) PAGING_LinkPage(lin_page,phys_page); else { - if (writing) { + if (priv_check==1) { PAGING_LinkPage(lin_page,phys_page); - return true; + return 1; + } else if (writing) { + PageHandler * handler=MEM_GetPageHandler(phys_page); + PAGING_LinkPage(lin_page,phys_page); + if (!(handler->flags & PFLAG_READABLE)) return 1; + if (!(handler->flags & PFLAG_WRITEABLE)) return 1; + if (get_tlb_read(lin_addr)!=get_tlb_write(lin_addr)) return 1; + if (phys_page>1) return phys_page; + else return 1; } else { PAGING_LinkPage_ReadOnly(lin_page,phys_page); } @@ -303,36 +363,19 @@ public: else phys_page=lin_page; PAGING_LinkPage(lin_page,phys_page); } - return false; + return 0; } bool InitPageCheckOnly(Bitu lin_addr,bool writing) { Bitu lin_page=lin_addr >> 12; if (paging.enabled) { - Bitu d_index=lin_page >> 10; - Bitu t_index=lin_page & 0x3ff; - Bitu table_addr=(paging.base.page<<12)+d_index*4; X86PageEntry table; - table.load=phys_readd(table_addr); - if (!table.block.p) { - paging.cr2=lin_addr; - cpu.exception.which=EXCEPTION_PF; - cpu.exception.error=(writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04); - return false; - } X86PageEntry entry; - Bitu entry_addr=(table.block.base<<12)+t_index*4; - entry.load=phys_readd(entry_addr); - if (!entry.block.p) { - paging.cr2=lin_addr; - cpu.exception.which=EXCEPTION_PF; - cpu.exception.error=(writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04); - return false; - } + if (!InitPageCheckPresence_CheckOnly(lin_addr,writing,table,entry)) return false; - if ((cpu.cpl&cpu.mpl)!=3) return true; + if (!USERWRITE_PROHIBITED) return true; -// if (((entry.block.us==0) || (table.block.us==0)) || (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { - if (((entry.block.us==0) && (table.block.us==0)) || (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { + if (USERACCESS_PROHIBITED(entry.block.us,table.block.us) || + (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x", cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); paging.cr2=lin_addr; @@ -340,17 +383,126 @@ public: cpu.exception.error=0x05 | (writing?0x02:0x00); return false; } - return true; } else { Bitu phys_page; if (lin_page1) tlb_addr=get_tlb_read(addr); + else tlb_addr=get_tlb_write(addr); + host_writeb(tlb_addr+addr,(Bit8u)(val&0xff)); + return false; + } + return true; + } + bool writew_checked(PhysPt addr,Bitu val) { + Bitu writecode=InitPageCheckOnly(addr,(Bit16u)(val&0xffff)); + if (writecode) { + HostPt tlb_addr; + if (writecode>1) tlb_addr=get_tlb_read(addr); + else tlb_addr=get_tlb_write(addr); + host_writew(tlb_addr+addr,(Bit16u)(val&0xffff)); + return false; + } + return true; + } + bool writed_checked(PhysPt addr,Bitu val) { + Bitu writecode=InitPageCheckOnly(addr,(Bit32u)val); + if (writecode) { + HostPt tlb_addr; + if (writecode>1) tlb_addr=get_tlb_read(addr); + else tlb_addr=get_tlb_write(addr); + host_writed(tlb_addr+addr,(Bit32u)val); + return false; + } + return true; + } + void InitPage(Bitu lin_addr,Bitu val) { + Bitu lin_page=lin_addr >> 12; + Bitu phys_page; + if (paging.enabled) { + if (!USERWRITE_PROHIBITED) return; + + X86PageEntry table; + X86PageEntry entry; + InitPageCheckPresence(lin_addr,true,table,entry); + + LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x", + cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); + PAGING_PageFault(lin_addr,(table.block.base<<12)+(lin_page & 0x3ff)*4,0x07); + + if (!table.block.a) { + table.block.a=1; //Set access + phys_writed((paging.base.page<<12)+(lin_page >> 10)*4,table.load); + } + if ((!entry.block.a) || (!entry.block.d)) { + entry.block.a=1; //Set access + entry.block.d=1; //Set dirty + phys_writed((table.block.base<<12)+(lin_page & 0x3ff)*4,entry.load); + } + phys_page=entry.block.base; + PAGING_LinkPage(lin_page,phys_page); + } else { + if (lin_page> 12; + if (paging.enabled) { + if (!USERWRITE_PROHIBITED) return 2; + + X86PageEntry table; + X86PageEntry entry; + if (!InitPageCheckPresence_CheckOnly(lin_addr,true,table,entry)) return 0; + + if (USERACCESS_PROHIBITED(entry.block.us,table.block.us) || (((entry.block.wr==0) || (table.block.wr==0)))) { + LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x", + cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); + paging.cr2=lin_addr; + cpu.exception.which=EXCEPTION_PF; + cpu.exception.error=0x07; + return 0; + } + PAGING_LinkPage(lin_page,entry.block.base); + } else { + Bitu phys_page; + if (lin_page> 10; @@ -362,14 +514,15 @@ bool PAGING_MakePhysPage(Bitu & page) { entry.load=phys_readd((table.block.base<<12)+t_index*4); if (!entry.block.p) return false; page=entry.block.base; - } else { - if (pagereadhandler=handler; + entry->writehandler=&init_page_handler_userro; } #endif From 1a6921ddb6833089c0927e5fa862d05855bf69e1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 30 Dec 2007 08:21:35 +0000 Subject: [PATCH 2983/4131] MSCDEX sets word on stack to ADAD if it DADA on entry. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3071 --- src/dos/dos_mscdex.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index dde2aba6..2fa767d3 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.50 2007-07-20 18:22:28 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.51 2007-12-30 08:21:35 qbix79 Exp $ */ #include #include @@ -1077,6 +1077,11 @@ static Bitu MSCDEX_Interrupt_Handler(void) { static bool MSCDEX_Handler(void) { if(reg_ah == 0x11) { if(reg_al == 0x00) { + PhysPt check = PhysMake(SegValue(ss),reg_sp); + if(mem_readw(check+6) == 0xDADA) { + //MSCDEX sets word on stack to ADAD if it DADA on entry. + mem_writew(check+6,0xADAD); + } reg_al = 0xff; return true; } else { From bfe2db4163593a805360ad53167a693e4bdbc201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 5 Jan 2008 21:05:06 +0000 Subject: [PATCH 2984/4131] force page initialization for code recompilation Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3072 --- include/paging.h | 5 ++- src/cpu/core_dyn_x86/decoder.h | 13 +++++- src/cpu/core_dynrec/decoder_basic.h | 15 +++++-- src/cpu/paging.cpp | 64 ++++++++++++++++++++++++++++- 4 files changed, 88 insertions(+), 9 deletions(-) diff --git a/include/paging.h b/include/paging.h index f35c3fcc..d9935b14 100644 --- a/include/paging.h +++ b/include/paging.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.30 2007-12-10 22:11:13 c2woody Exp $ */ +/* $Id: paging.h,v 1.31 2008-01-05 21:04:43 c2woody Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H @@ -93,6 +93,7 @@ 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); diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 8ef2330a..4f23c0ad 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -60,8 +60,17 @@ static bool MakeCodePage(Bitu lin_addr,CodePageHandler * &cph) { return false; } if (handler->flags & PFLAG_NOCODE) { - LOG_MSG("DYNX86:Can't run code in this page"); - cph=0; return false; + if (PAGING_ForcePageInit(lin_addr)) { + handler=get_tlb_readhandler(lin_addr); + if (handler->flags & PFLAG_HASCODE) { + cph=( CodePageHandler *)handler; + return false; + } + } + if (handler->flags & PFLAG_NOCODE) { + LOG_MSG("DYNX86:Can't run code in this page!"); + cph=0; return false; + } } Bitu lin_page=lin_addr >> 12; Bitu phys_page=lin_page; diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index 1f25c474..c3d95773 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -139,9 +139,18 @@ static bool MakeCodePage(Bitu lin_addr,CodePageHandlerDynRec * &cph) { return false; } if (handler->flags & PFLAG_NOCODE) { - LOG_MSG("DYNREC:Can't run code in this page"); - cph=0; - return false; + if (PAGING_ForcePageInit(lin_addr)) { + handler=get_tlb_readhandler(lin_addr); + if (handler->flags & PFLAG_HASCODE) { + cph=(CodePageHandlerDynRec *)handler; + return false; + } + } + if (handler->flags & PFLAG_NOCODE) { + LOG_MSG("DYNREC:Can't run code in this page"); + cph=0; + return false; + } } Bitu lin_page=lin_addr>>12; Bitu phys_page=lin_page; diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 57ce9e9a..fc7bfa85 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.cpp,v 1.32 2007-12-29 20:22:22 c2woody Exp $ */ +/* $Id: paging.cpp,v 1.33 2008-01-05 21:05:06 c2woody Exp $ */ #include #include @@ -391,6 +391,30 @@ public: } return true; } + void InitPageForced(Bitu lin_addr) { + Bitu lin_page=lin_addr >> 12; + Bitu phys_page; + if (paging.enabled) { + X86PageEntry table; + X86PageEntry entry; + InitPageCheckPresence(lin_addr,false,table,entry); + + if (!table.block.a) { + table.block.a=1; //Set access + phys_writed((paging.base.page<<12)+(lin_page >> 10)*4,table.load); + } + if (!entry.block.a) { + entry.block.a=1; //Set access + phys_writed((table.block.base<<12)+(lin_page & 0x3ff)*4,entry.load); + } + phys_page=entry.block.base; + // maybe use read-only page here if possible + } else { + if (lin_page> 12; + Bitu phys_page; + if (paging.enabled) { + X86PageEntry table; + X86PageEntry entry; + InitPageCheckPresence(lin_addr,true,table,entry); + + if (!table.block.a) { + table.block.a=1; //Set access + phys_writed((paging.base.page<<12)+(lin_page >> 10)*4,table.load); + } + if (!entry.block.a) { + entry.block.a=1; //Set access + phys_writed((table.block.base<<12)+(lin_page & 0x3ff)*4,entry.load); + } + phys_page=entry.block.base; + } else { + if (lin_page>12,1); + init_page_handler_userro.InitPageForced(lin_addr); + return true; + } + return false; +} + #if defined(USE_FULL_TLB) void PAGING_InitTLB(void) { for (Bitu i=0;i Date: Sun, 6 Jan 2008 16:45:42 +0000 Subject: [PATCH 2985/4131] use better/slower fpu emulation on x86 for the normal core Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3073 --- src/fpu/fpu_instructions_x86.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index f83586ca..a5fdca04 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -16,10 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions_x86.h,v 1.5 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: fpu_instructions_x86.h,v 1.6 2008-01-06 16:45:42 c2woody Exp $ */ -#define WEAK_EXCEPTIONS +// #define WEAK_EXCEPTIONS #if defined (_MSC_VER) From 2c95419294893f94e3f7468a4ce29d0c04b0b8c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 7 Jan 2008 22:29:37 +0000 Subject: [PATCH 2986/4131] report irq2 as active when irq's on the second pic are active (pic cascading), thanks Srecko Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3074 --- src/hardware/pic.cpp | 98 ++++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 48 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 6c00de53..a0295faa 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.42 2007-12-09 17:02:55 c2woody Exp $ */ +/* $Id: pic.cpp,v 1.43 2008-01-07 22:29:37 c2woody Exp $ */ #include @@ -41,8 +41,6 @@ struct PIC_Controller { Bitu icw_words; Bitu icw_index; Bitu masked; - Bitu active; - Bitu inservice; bool special; bool auto_eoi; @@ -54,6 +52,7 @@ struct PIC_Controller { Bitu PIC_Ticks=0; Bitu PIC_IRQCheck; +Bitu PIC_IRQOnSecondPicActive; Bitu PIC_IRQActive; @@ -63,7 +62,7 @@ static bool PIC_Special_Mode = false; //Saves one compare in the pic_run_irqloop struct PICEntry { float index; Bitu value; - PIC_EventHandler event; + PIC_EventHandler pic_event; PICEntry * next; }; @@ -71,7 +70,7 @@ static struct { PICEntry entries[PIC_QUEUESIZE]; PICEntry * free_entry; PICEntry * next_entry; -} pic; +} pic_queue; static void write_command(Bitu port,Bitu val,Bitu iolen) { PIC_Controller * pic=&pics[port==0x20 ? 0 : 1]; @@ -209,6 +208,7 @@ static void write_data(Bitu port,Bitu val,Bitu iolen) { break; default: LOG(LOG_PIC,LOG_NORMAL)("ICW HUH? %X",val); + break; } } @@ -227,6 +227,7 @@ static Bitu read_command(Bitu port,Bitu iolen) { if (irqs[i].active) ret|=b; b <<= 1; } + if (irq_base==0 && (PIC_IRQCheck&0xff00)) ret |=4; } return ret; } @@ -250,6 +251,7 @@ void PIC_ActivateIRQ(Bitu irq) { } } else if (irq < 16) { irqs[irq].active = true; + PIC_IRQOnSecondPicActive|=(1 << irq); if (!irqs[irq].masked && !irqs[2].masked) { PIC_IRQCheck|=(1 << irq); } @@ -260,6 +262,7 @@ void PIC_DeActivateIRQ(Bitu irq) { if (irq<16) { irqs[irq].active=false; PIC_IRQCheck&=~(1 << irq); + PIC_IRQOnSecondPicActive&=~(1 << irq); } } static inline bool PIC_startIRQ(Bitu i) { @@ -267,6 +270,7 @@ static inline bool PIC_startIRQ(Bitu i) { if( i > 7 && irqs[2].masked) return false; irqs[i].active = false; PIC_IRQCheck&= ~(1 << i); + PIC_IRQOnSecondPicActive&= ~(1 << i); CPU_HW_Interrupt(irqs[i].vector); Bitu pic=(i&8)>>3; if (!pics[pic].auto_eoi) { //irq 0-7 => pic 0 else pic 1 @@ -350,12 +354,12 @@ void PIC_SetIRQMask(Bitu irq, bool masked) { } static void AddEntry(PICEntry * entry) { - PICEntry * find_entry=pic.next_entry; + PICEntry * find_entry=pic_queue.next_entry; if (!find_entry) { entry->next=0; - pic.next_entry=entry; + pic_queue.next_entry=entry; } else if (find_entry->index>entry->index) { - pic.next_entry=entry; + pic_queue.next_entry=entry; entry->next=find_entry; } else while (find_entry) { if (find_entry->next) { @@ -373,7 +377,7 @@ static void AddEntry(PICEntry * entry) { break; } } - Bits cycles=PIC_MakeCycles(pic.next_entry->index-PIC_TickIndex()); + Bits cycles=PIC_MakeCycles(pic_queue.next_entry->index-PIC_TickIndex()); if (cyclesindex=delay+PIC_TickIndex(); - entry->event=handler; + entry->pic_event=handler; entry->value=val; - pic.free_entry=pic.free_entry->next; + pic_queue.free_entry=pic_queue.free_entry->next; AddEntry(entry); } void PIC_RemoveSpecificEvents(PIC_EventHandler handler, Bitu val) { - PICEntry * entry=pic.next_entry; + PICEntry * entry=pic_queue.next_entry; PICEntry * prev_entry; prev_entry = 0; while (entry) { - if ((entry->event == handler) && (entry->value == val)) { + if ((entry->pic_event == handler) && (entry->value == val)) { if (prev_entry) { prev_entry->next=entry->next; - entry->next=pic.free_entry; - pic.free_entry=entry; + entry->next=pic_queue.free_entry; + pic_queue.free_entry=entry; entry=prev_entry->next; continue; } else { - pic.next_entry=entry->next; - entry->next=pic.free_entry; - pic.free_entry=entry; - entry=pic.next_entry; + pic_queue.next_entry=entry->next; + entry->next=pic_queue.free_entry; + pic_queue.free_entry=entry; + entry=pic_queue.next_entry; continue; } } @@ -419,22 +423,22 @@ void PIC_RemoveSpecificEvents(PIC_EventHandler handler, Bitu val) { } void PIC_RemoveEvents(PIC_EventHandler handler) { - PICEntry * entry=pic.next_entry; + PICEntry * entry=pic_queue.next_entry; PICEntry * prev_entry; prev_entry=0; while (entry) { - if (entry->event==handler) { + if (entry->pic_event==handler) { if (prev_entry) { prev_entry->next=entry->next; - entry->next=pic.free_entry; - pic.free_entry=entry; + entry->next=pic_queue.free_entry; + pic_queue.free_entry=entry; entry=prev_entry->next; continue; } else { - pic.next_entry=entry->next; - entry->next=pic.free_entry; - pic.free_entry=entry; - entry=pic.next_entry; + pic_queue.next_entry=entry->next; + entry->next=pic_queue.free_entry; + pic_queue.free_entry=entry; + entry=pic_queue.next_entry; continue; } } @@ -453,17 +457,17 @@ bool PIC_RunQueue(void) { } /* Check the queue for an entry */ Bits index_nd=PIC_TickIndexND(); - while (pic.next_entry && (pic.next_entry->index*CPU_CycleMax<=index_nd)) { - PICEntry * entry=pic.next_entry; - pic.next_entry=entry->next; - (entry->event)(entry->value); + while (pic_queue.next_entry && (pic_queue.next_entry->index*CPU_CycleMax<=index_nd)) { + PICEntry * entry=pic_queue.next_entry; + pic_queue.next_entry=entry->next; + (entry->pic_event)(entry->value); /* Put the entry in the free list */ - entry->next=pic.free_entry; - pic.free_entry=entry; + entry->next=pic_queue.free_entry; + pic_queue.free_entry=entry; } /* Check when to set the new cycle end */ - if (pic.next_entry) { - Bits cycles=(Bits)(pic.next_entry->index*CPU_CycleMax-index_nd); + if (pic_queue.next_entry) { + Bits cycles=(Bits)(pic_queue.next_entry->index*CPU_CycleMax-index_nd); if (!cycles) cycles=1; if (cycleshandler==handler) { - *where=ticker->next; + *tick_where=ticker->next; delete ticker; return; } - where=&ticker->next; + tick_where=&ticker->next; ticker=ticker->next; } } @@ -512,7 +516,7 @@ void TIMER_AddTick(void) { CPU_Cycles=0; PIC_Ticks++; /* Go through the list of scheduled events and lower their index with 1000 */ - PICEntry * entry=pic.next_entry; + PICEntry * entry=pic_queue.next_entry; while (entry) { if (entry->index>=1) entry->index-=1; else entry->index=0; @@ -541,8 +545,6 @@ public: Bitu i; for (i=0;i<2;i++) { pics[i].masked=0xff; - pics[i].active=0; - pics[i].inservice=0; pics[i].auto_eoi=false; pics[i].rotate_on_auto_eoi=false; pics[i].request_issr=false; @@ -579,11 +581,11 @@ public: WriteHandler[3].Install(0xa1,write_data,IO_MB); /* Initialize the pic queue */ for (i=0;i Date: Wed, 9 Jan 2008 20:34:51 +0000 Subject: [PATCH 2987/4131] additional svga chipset emulation (tseng, paradise) and small fixes for s3, vasyl Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3075 --- include/dosbox.h | 8 +- include/vga.h | 88 ++-- src/dosbox.cpp | 19 +- src/hardware/Makefile.am | 2 +- src/hardware/vga.cpp | 35 +- src/hardware/vga_attr.cpp | 10 +- src/hardware/vga_crtc.cpp | 21 +- src/hardware/vga_draw.cpp | 43 +- src/hardware/vga_gfx.cpp | 19 +- src/hardware/vga_memory.cpp | 66 ++- src/hardware/vga_paradise.cpp | 223 ++++++++++ src/hardware/vga_s3.cpp | 56 ++- src/hardware/vga_seq.cpp | 21 +- src/hardware/vga_tseng.cpp | 785 ++++++++++++++++++++++++++++++++++ src/ints/int10.cpp | 6 +- src/ints/int10_modes.cpp | 330 +++++++++----- visualc_net/dosbox.vcproj | 6 + 17 files changed, 1512 insertions(+), 226 deletions(-) create mode 100644 src/hardware/vga_paradise.cpp create mode 100644 src/hardware/vga_tseng.cpp diff --git a/include/dosbox.h b/include/dosbox.h index 19bde530..4f80bc87 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * 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 $ */ + #ifndef DOSBOX_DOSBOX_H #define DOSBOX_DOSBOX_H @@ -51,7 +53,9 @@ enum MachineType { enum SVGACards { SVGA_None, SVGA_S3Trio, - SVGA_TsengET4K + SVGA_TsengET4K, + SVGA_TsengET3K, + SVGA_ParadisePVGA1A }; extern SVGACards svgaCard; diff --git a/include/vga.h b/include/vga.h index 1d8faf84..a497b33a 100644 --- a/include/vga.h +++ b/include/vga.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: vga.h,v 1.37 2008-01-09 20:34:21 c2woody Exp $ */ + #ifndef DOSBOX_VGA_H #define DOSBOX_VGA_H @@ -157,23 +159,7 @@ typedef struct { Bit8u mc[64][64]; } VGA_HWCURSOR; -typedef union { - Bit32u fullbank; -#ifndef WORDS_BIGENDIAN - struct { - Bit16u lowerbank; - Bit16u bank; - } b; -#else - struct { - Bit16u bank; - Bit16u lowerbank; - } b; -#endif -} VGA_S3_BANK; - typedef struct { - VGA_S3_BANK svga_bank; Bit8u reg_lock1; Bit8u reg_lock2; Bit8u reg_31; @@ -330,6 +316,11 @@ typedef struct { 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 { @@ -423,15 +414,64 @@ void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3); void VGA_ActivateHardwareCursor(void); void VGA_KillDrawing(void); -/* S3 Functions */ -Bitu SVGA_S3_GetClock(void); -void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen); -Bitu SVGA_S3_ReadCRTC(Bitu reg,Bitu iolen); -void SVGA_S3_WriteSEQ(Bitu reg,Bitu val,Bitu iolen); -Bitu SVGA_S3_ReadSEQ(Bitu reg,Bitu iolen); - 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); + extern Bit32u ExpandTable[256]; extern Bit32u FillTable[16]; extern Bit32u CGA_2_Table[16]; diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 1291e113..3c5cd29c 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.124 2007-12-13 12:38:13 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.125 2008-01-09 20:34:21 c2woody Exp $ */ #include #include @@ -269,13 +269,22 @@ static void DOSBOX_RealInit(Section * sec) { (strcasecmp(mtype,"svga")==0) || (strcasecmp(mtype,"svga_s3")==0)) { machine=MCH_VGA; svgaCard=SVGA_S3Trio; -/* } else if ((strcasecmp(mtype,"vga_et4000")==0) || (strcasecmp(mtype,"svga_et4000")==0)) { + } else if ((strcasecmp(mtype,"vga_et4000")==0) || (strcasecmp(mtype,"svga_et4000")==0)) { machine=MCH_VGA; - svgaCard=SVGA_TsengET4K; */ + svgaCard=SVGA_TsengET4K; + } else if ((strcasecmp(mtype,"vga_et3000")==0) || (strcasecmp(mtype,"svga_et3000")==0)) { + machine=MCH_VGA; + svgaCard=SVGA_TsengET3K; + } else if ((strcasecmp(mtype,"vga_pvga1a")==0) || (strcasecmp(mtype,"svga_pvga1a")==0) || + (strcasecmp(mtype,"svga_paradise")==0)) { + machine=MCH_VGA; + svgaCard=SVGA_ParadisePVGA1A; } else if (strcasecmp(mtype,"vgaonly")==0) { machine=MCH_VGA; svgaCard=SVGA_None; - } else LOG_MSG("DOSBOX:Unknown machine type %s",mtype); + } else { + LOG_MSG("DOSBOX:Unknown machine type %s",mtype); + } } diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index c733621c..7a9f7bf6 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -9,7 +9,7 @@ noinst_LIBRARIES = libhardware.a libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler.cpp joystick.cpp keyboard.cpp \ memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp vga_other.cpp \ - vga_memory.cpp vga_misc.cpp vga_seq.cpp vga_xga.cpp vga_s3.cpp \ + vga_memory.cpp vga_misc.cpp vga_seq.cpp vga_xga.cpp vga_s3.cpp vga_tseng.cpp vga_paradise.cpp \ cmos.cpp disney.cpp gus.cpp mpu401.cpp ipx.cpp ipxserver.cpp diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index b60cece0..5a52b026 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga.cpp,v 1.31 2007-12-10 22:11:13 c2woody Exp $ */ +/* $Id: vga.cpp,v 1.32 2008-01-09 20:34:51 c2woody Exp $ */ #include "dosbox.h" //#include "setup.h" @@ -24,7 +24,10 @@ #include "pic.h" #include "vga.h" +#include + VGA_Type vga; +SVGA_Driver svga; Bit32u CGA_2_Table[16]; Bit32u CGA_4_Table[256]; @@ -48,6 +51,10 @@ void VGA_SetMode(VGAModes mode) { } void VGA_DetermineMode(void) { + if (svga.determine_mode) { + svga.determine_mode(); + return; + } /* Test for VGA output active or direct color modes */ switch (vga.s3.misc_control_2 >> 4) { case 0: @@ -84,6 +91,10 @@ void VGA_StartResize(void) { } void VGA_SetClock(Bitu which,Bitu target) { + if (svga.set_clock) { + svga.set_clock(which, target); + return; + } struct{ Bitu n,m; Bits err; @@ -158,6 +169,7 @@ void VGA_Init(Section* sec) { vga.screenflip = 0; vga.draw.resizing=false; vga.mode=M_ERROR; //For first init + SVGA_Setup_Driver(); VGA_SetupMemory(); VGA_SetupMisc(); VGA_SetupDAC(); @@ -220,3 +232,22 @@ void VGA_Init(Section* sec) { } } } + +void SVGA_Setup_Driver(void) { + memset(&svga, 0, sizeof(SVGA_Driver)); + + switch(svgaCard) { + case SVGA_S3Trio: + SVGA_Setup_S3Trio(); + break; + case SVGA_TsengET4K: + SVGA_Setup_TsengET4K(); + break; + case SVGA_TsengET3K: + SVGA_Setup_TsengET3K(); + break; + case SVGA_ParadisePVGA1A: + SVGA_Setup_ParadisePVGA1A(); + break; + } +} diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 95c3c810..622d39a5 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_attr.cpp,v 1.27 2007-12-23 16:00:53 c2woody Exp $ */ +/* $Id: vga_attr.cpp,v 1.28 2008-01-09 20:34:51 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -177,6 +177,10 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) { */ break; default: + if (svga.write_p3c0) { + svga.write_p3c0(attr(index), val, iolen); + break; + } LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:ATTR:Write to unkown Index %2X",attr(index)); break; } @@ -203,6 +207,8 @@ Bitu read_p3c1(Bitu port,Bitu iolen) { case 0x14: /* Color Select Register */ return attr(color_select); default: + if (svga.read_p3c1) + return svga.read_p3c1(attr(index), iolen); LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:ATTR:Read from unkown Index %2X",attr(index)); } return 0; diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index c2e3e1b0..c35c2fe0 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: vga_crtc.cpp,v 1.30 2008-01-09 20:34:51 c2woody Exp $ */ + #include #include "dosbox.h" #include "inout.h" @@ -330,12 +332,10 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { */ break; default: - switch (svgaCard) { - case SVGA_S3Trio: - SVGA_S3_WriteCRTC( crtc(index), val, iolen); - break; - default: - break; + if (svga.write_p3d5) { + svga.write_p3d5(crtc(index), val, iolen); + } else { + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:Write to unknown index %X",crtc(index)); } break; } @@ -395,10 +395,9 @@ Bitu vga_read_p3d5(Bitu port,Bitu iolen) { case 0x18: /* Line Compare Register */ return crtc(line_compare); default: - switch (svgaCard) { - case SVGA_S3Trio: - return SVGA_S3_ReadCRTC( crtc(index), iolen ); - default: + if (svga.read_p3d5) { + return svga.read_p3d5(crtc(index), iolen); + } else { LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:Read from unknown index %X",crtc(index)); return 0x0; } diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 07106670..ed9b5de1 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.90 2007-12-19 21:12:22 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.91 2008-01-09 20:34:51 c2woody Exp $ */ #include #include @@ -206,7 +206,11 @@ static Bit8u * VGA_Draw_Chain_Line(Bitu vidstart, Bitu line) { } static Bit8u * VGA_Draw_VGA_Line_HWMouse( Bitu vidstart, Bitu line) { - if(vga.s3.hgc.curmode & 0x1) { + bool hwcursor_active=false; + if (svga.hardware_cursor_active) { + if (svga.hardware_cursor_active()) hwcursor_active=true; + } + if (hwcursor_active) { Bitu lineat = (vidstart-(vga.config.real_start<<2)) / vga.draw.width; if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) { return &vga.mem.linear[ vidstart ]; @@ -266,7 +270,11 @@ static Bit8u * VGA_Draw_VGA_Line_HWMouse( Bitu vidstart, Bitu line) { } static Bit8u * VGA_Draw_LIN16_Line_HWMouse(Bitu vidstart, Bitu line) { - if(vga.s3.hgc.curmode & 0x1) { + bool hwcursor_active=false; + if (svga.hardware_cursor_active) { + if (svga.hardware_cursor_active()) hwcursor_active=true; + } + if (hwcursor_active) { Bitu lineat = ((vidstart-(vga.config.real_start<<2)) >> 1) / vga.draw.width; if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) { return &vga.mem.linear[ vidstart ]; @@ -329,7 +337,11 @@ static Bit8u * VGA_Draw_LIN16_Line_HWMouse(Bitu vidstart, Bitu line) { } static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart, Bitu line) { - if(vga.s3.hgc.curmode & 0x1) { + bool hwcursor_active=false; + if (svga.hardware_cursor_active) { + if (svga.hardware_cursor_active()) hwcursor_active=true; + } + if (hwcursor_active) { Bitu lineat = ((vidstart-(vga.config.real_start<<2)) >> 2) / vga.draw.width; if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) { return &vga.mem.linear[ vidstart ]; @@ -881,7 +893,11 @@ void VGA_CheckScanLength(void) { } void VGA_ActivateHardwareCursor(void) { - if(vga.s3.hgc.curmode & 0x1) { + bool hwcursor_active=false; + if (svga.hardware_cursor_active) { + if (svga.hardware_cursor_active()) hwcursor_active=true; + } + if (hwcursor_active) { switch(vga.mode) { case M_LIN32: VGA_DrawLine=VGA_Draw_LIN32_Line_HWMouse; @@ -963,11 +979,9 @@ void VGA_SetupDrawing(Bitu val) { if ( !vbend) vbend = vbstart + 0x3f + 1; else vbend = vbstart + vbend; - switch (svgaCard) { - case SVGA_S3Trio: - clock = SVGA_S3_GetClock(); - break; - default: + if (svga.get_clock) { + clock = svga.get_clock(); + } else { switch ((vga.misc_output >> 2) & 3) { case 0: clock = 25175000; @@ -976,7 +990,6 @@ void VGA_SetupDrawing(Bitu val) { clock = 28322000; break; } - break; } /* Check for 8 for 9 character clock mode */ @@ -986,8 +999,6 @@ void VGA_SetupDrawing(Bitu val) { htotal*=2; } vga.draw.address_line_total=(vga.crtc.maximum_scan_line&0xf)+1; - /* Check for dual transfer whatever thing,master clock/2 */ - if (vga.s3.pll.cmd & 0x10) clock/=2; if (IS_VGA_ARCH) vga.draw.double_scan=(vga.crtc.maximum_scan_line&0x80)>0; else vga.draw.double_scan=(vtotal==262); @@ -1150,7 +1161,7 @@ void VGA_SetupDrawing(Bitu val) { case M_LIN8: if (vga.crtc.mode_control & 0x8) width >>=1; - else if(!(vga.s3.reg_3a&0x10)) { + else if(svgaCard == SVGA_S3Trio && !(vga.s3.reg_3a&0x10)) { doublewidth=true; width >>=1; } @@ -1166,7 +1177,7 @@ void VGA_SetupDrawing(Bitu val) { case M_LIN16: // 15/16 bpp modes double the horizontal values width<<=2; - if ((vga.crtc.mode_control & 0x8) || (vga.s3.pll.cmd & 0x10)) + if ((vga.crtc.mode_control & 0x8) || (svgaCard == SVGA_S3Trio && (vga.s3.pll.cmd & 0x10))) doublewidth = true; /* Use HW mouse cursor drawer if enabled */ VGA_ActivateHardwareCursor(); diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index 81d61f56..53055266 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: vga_gfx.cpp,v 1.18 2008-01-09 20:34:51 c2woody Exp $ */ + #include "dosbox.h" #include "inout.h" #include "vga.h" @@ -174,14 +176,16 @@ static void write_p3cf(Bitu port,Bitu val,Bitu iolen) { display memory. */ break; - case 9: /* Unknown */ - /* Crystal Dreams seems to like to write tothis register very weird */ - if (!index9warned) { + default: + if (svga.write_p3cf) { + svga.write_p3cf(gfx(index), val, iolen); + break; + } + if (gfx(index) == 9 && !index9warned) { LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:3CF:Write %2X to illegal index 9",val); index9warned=true; + break; } - break; - default: LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:3CF:Write %2X to illegal index %2X",val,gfx(index)); break; } @@ -208,7 +212,10 @@ static Bitu read_p3cf(Bitu port,Bitu iolen) { case 8: /* Bit Mask Register */ return gfx(bit_mask); default: + if (svga.read_p3cf) + return svga.read_p3cf(gfx(index), iolen); LOG(LOG_VGAMISC,LOG_NORMAL)("Reading from illegal index %2X in port %4X",static_cast(gfx(index)),port); + break; } return 0; /* Compiler happy */ } diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 00f9fe98..fd9ab374 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_memory.cpp,v 1.45 2007-12-10 22:11:13 c2woody Exp $ */ +/* $Id: vga_memory.cpp,v 1.46 2008-01-09 20:34:51 c2woody Exp $ */ #include #include @@ -132,16 +132,19 @@ public: public: Bitu readb(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.svga.bank_read_full; return readHandler(addr); } Bitu readw(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.svga.bank_read_full; return (readHandler(addr+0) << 0) | (readHandler(addr+1) << 8); } Bitu readd(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.svga.bank_read_full; return (readHandler(addr+0) << 0) | (readHandler(addr+1) << 8) | @@ -187,17 +190,20 @@ public: } void writeb(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.svga.bank_write_full; MEM_CHANGED( addr << 3); writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.svga.bank_write_full; MEM_CHANGED( addr << 3); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.svga.bank_write_full; MEM_CHANGED( addr << 3); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); @@ -206,16 +212,19 @@ public: } Bitu readb(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.svga.bank_read_full; return readHandler(addr); } Bitu readw(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.svga.bank_read_full; return (readHandler(addr+0) << 0) | (readHandler(addr+1) << 8); } Bitu readd(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.svga.bank_read_full; return (readHandler(addr+0) << 0) | (readHandler(addr+1) << 8) | @@ -263,17 +272,20 @@ public: } void writeb(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.svga.bank_write_full; MEM_CHANGED( addr << 3); writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.svga.bank_write_full; MEM_CHANGED( addr << 3); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.svga.bank_write_full; MEM_CHANGED( addr << 3); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); @@ -307,10 +319,12 @@ public: } Bitu readb(PhysPt addr ) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.svga.bank_read_full; return readHandler( addr ); } Bitu readw(PhysPt addr ) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.svga.bank_read_full; if (GCC_UNLIKELY(addr & 1)) return (readHandler( addr+0 ) << 0 ) | @@ -320,6 +334,7 @@ public: } Bitu readd(PhysPt addr ) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.svga.bank_read_full; if (GCC_UNLIKELY(addr & 3)) return (readHandler( addr+0 ) << 0 ) | @@ -331,12 +346,14 @@ public: } void writeb(PhysPt addr, Bitu val ) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.svga.bank_write_full; MEM_CHANGED( addr ); writeHandler( addr, val ); writeCache( addr, val ); } void writew(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.svga.bank_write_full; MEM_CHANGED( addr ); // MEM_CHANGED( addr + 1); if (GCC_UNLIKELY(addr & 1)) { @@ -349,6 +366,7 @@ public: } void writed(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr += vga.svga.bank_write_full; MEM_CHANGED( addr ); // MEM_CHANGED( addr + 3); if (GCC_UNLIKELY(addr & 3)) { @@ -381,20 +399,20 @@ public: } void writeb(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - addr += vga.s3.svga_bank.fullbank; + addr += vga.svga.bank_write_full; MEM_CHANGED( addr << 2 ); writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - addr += vga.s3.svga_bank.fullbank; + addr += vga.svga.bank_write_full; MEM_CHANGED( addr << 2); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - addr += vga.s3.svga_bank.fullbank; + addr += vga.svga.bank_write_full; MEM_CHANGED( addr << 2); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); @@ -427,11 +445,11 @@ public: } HostPt GetHostReadPt(Bitu phys_page) { phys_page-=vgapages.base; - return &vga.mem.linear[vga.s3.svga_bank.fullbank+phys_page*4096]; + return &vga.mem.linear[vga.svga.bank_read_full+phys_page*4096]; } HostPt GetHostWritePt(Bitu phys_page) { phys_page-=vgapages.base; - return &vga.mem.linear[vga.s3.svga_bank.fullbank+phys_page*4096]; + return &vga.mem.linear[vga.svga.bank_write_full+phys_page*4096]; } }; @@ -442,34 +460,34 @@ public: } Bitu readb(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - addr += vga.s3.svga_bank.fullbank; + addr += vga.svga.bank_read_full; return hostRead( &vga.mem.linear[addr] ); } Bitu readw(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - addr += vga.s3.svga_bank.fullbank; + addr += vga.svga.bank_read_full; return hostRead( &vga.mem.linear[addr] ); } Bitu readd(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - addr += vga.s3.svga_bank.fullbank; + addr += vga.svga.bank_read_full; return hostRead( &vga.mem.linear[addr] ); } void writeb(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - addr += vga.s3.svga_bank.fullbank; + addr += vga.svga.bank_write_full; MEM_CHANGED( addr ); hostWrite( &vga.mem.linear[addr], val ); } void writew(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - addr += vga.s3.svga_bank.fullbank; + addr += vga.svga.bank_write_full; MEM_CHANGED( addr ); hostWrite( &vga.mem.linear[addr], val ); } void writed(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; - addr += vga.s3.svga_bank.fullbank; + addr += vga.svga.bank_write_full; MEM_CHANGED( addr ); hostWrite( &vga.mem.linear[addr], val ); } @@ -481,20 +499,20 @@ public: flags=PFLAG_NOCODE; } void writeb(PhysPt addr,Bitu val) { - addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr = vga.svga.bank_write_full + (PAGING_GetPhysicalAddress(addr) & 0xffff); addr &= (128*1024-1); MEM_CHANGED( addr << 3 ); writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { - addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr = vga.svga.bank_write_full + (PAGING_GetPhysicalAddress(addr) & 0xffff); addr &= (128*1024-1); MEM_CHANGED( addr << 3 ); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { - addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr = vga.svga.bank_write_full + (PAGING_GetPhysicalAddress(addr) & 0xffff); addr &= (128*1024-1); MEM_CHANGED( addr << 3 ); writeHandler(addr+0,(Bit8u)(val >> 0)); @@ -503,19 +521,19 @@ public: writeHandler(addr+3,(Bit8u)(val >> 24)); } Bitu readb(PhysPt addr) { - addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr = vga.svga.bank_read_full + (PAGING_GetPhysicalAddress(addr) & 0xffff); addr &= (128*1024-1); return readHandler(addr); } Bitu readw(PhysPt addr) { - addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr = vga.svga.bank_read_full + (PAGING_GetPhysicalAddress(addr) & 0xffff); addr &= (128*1024-1); return (readHandler(addr+0) << 0) | (readHandler(addr+1) << 8); } Bitu readd(PhysPt addr) { - addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff); + addr = vga.svga.bank_read_full + (PAGING_GetPhysicalAddress(addr) & 0xffff); addr &= (128*1024-1); return (readHandler(addr+0) << 0) | @@ -687,6 +705,9 @@ void VGA_ChangedBank(void) { } void VGA_SetupHandlers(void) { + vga.svga.bank_read_full = vga.svga.bank_read*vga.svga.bank_size; + vga.svga.bank_write_full = vga.svga.bank_write*vga.svga.bank_size; + PageHandler *newHandler; switch (machine) { case MCH_CGA: @@ -803,7 +824,7 @@ void VGA_SetupHandlers(void) { MEM_ResetPageHandler( VGA_PAGE_B0, 8 ); break; } - if(vga.s3.ext_mem_ctrl & 0x10) + if(svgaCard == SVGA_S3Trio && (vga.s3.ext_mem_ctrl & 0x10)) MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio); range_done: PAGING_ClearTLB(); @@ -828,7 +849,10 @@ void VGA_SetupMemory() { #ifdef VGA_KEEP_CHANGES memset( &vga.changes, 0, sizeof( vga.changes )); #endif - vga.s3.svga_bank.fullbank=0; + vga.svga.bank_read = vga.svga.bank_write = 0; + vga.svga.bank_read_full = vga.svga.bank_write_full = 0; + vga.svga.bank_size = 0x10000; /* most common bank size is 64K */ + if (machine==MCH_PCJR) { /* PCJr does not have dedicated graphics memory but uses conventional memory below 128k */ diff --git a/src/hardware/vga_paradise.cpp b/src/hardware/vga_paradise.cpp new file mode 100644 index 00000000..8a10c76e --- /dev/null +++ b/src/hardware/vga_paradise.cpp @@ -0,0 +1,223 @@ +/* + * 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: vga_paradise.cpp,v 1.1 2008-01-09 20:34:51 c2woody Exp $ */ + +#include "dosbox.h" +#include "setup.h" +#include "vga.h" +#include "inout.h" +#include "mem.h" + +typedef struct { + Bitu PR0A; + Bitu PR0B; + Bitu PR1; + Bitu PR2; + Bitu PR3; + Bitu PR4; + Bitu PR5; + + inline bool locked() { return (PR5&7)!=5; } + + Bitu clockFreq[4]; + Bitu biosMode; +} SVGA_PVGA1A_DATA; + +static SVGA_PVGA1A_DATA pvga1a = { 0, 0, 0, 0, 0, 0, 0 }; + + +static void bank_setup_pvga1a() { +// Note: There is some inconsistency in available documentation. Most sources tell that PVGA1A used +// only 7 bits of bank index (VGADOC and Ferraro agree on that) but also point that there are +// implementations with 1M of RAM which is simply not possible with 7-bit banks. This implementation +// assumes that the eighth bit was actually wired and could be used. This does not conflict with +// anything and actually works in WHATVGA just fine. + if (pvga1a.PR1 & 0x08) { + // TODO: Dual bank function is not supported yet + // TODO: Requirements are not compatible with vga_memory implementation. + } else { + // Single bank config is straightforward + vga.svga.bank_read = vga.svga.bank_write = pvga1a.PR0A; + vga.svga.bank_size = 4*1024; + VGA_SetupHandlers(); + } +} + +void write_p3cf_pvga1a(Bitu reg,Bitu val,Bitu iolen) { + if (pvga1a.locked() && reg >= 0x09 && reg <= 0x0e) + return; + + switch (reg) { + case 0x09: + // Bank A, 4K granularity, not using bit 7 + // Maps to A800h-AFFFh if PR1 bit 3 set and 64k config B000h-BFFFh if 128k config. A000h-AFFFh otherwise. + pvga1a.PR0A = val; + bank_setup_pvga1a(); + break; + case 0x0a: + // Bank B, 4K granularity, not using bit 7 + // Maps to A000h-A7FFh if PR1 bit 3 set and 64k config, A000h-AFFFh if 128k + pvga1a.PR0B = val; + bank_setup_pvga1a(); + break; + case 0x0b: + // Memory size. We only allow to mess with bit 3 here (enable bank B) - this may break some detection schemes + pvga1a.PR1 = (pvga1a.PR1 & ~0x08) | (val & 0x08); + bank_setup_pvga1a(); + break; + case 0x0c: + // Video configuration + // TODO: Figure out if there is anything worth implementing here. + pvga1a.PR2 = val; + break; + case 0x0d: + // CRT control. Bits 3-4 contain bits 16-17 of CRT start. + // TODO: Implement bit 2 (CRT address doubling - this mechanism is present in other chipsets as well, + // but not implemented in DosBox core) + pvga1a.PR3 = val; + vga.config.display_start = (vga.config.display_start & 0xffff) | ((val & 0x18)<<13); + vga.config.cursor_start = (vga.config.cursor_start & 0xffff) | ((val & 0x18)<<13); + break; + case 0x0e: + // Video control + // TODO: Figure out if there is anything worth implementing here. + pvga1a.PR4 = val; + break; + case 0x0f: + // Enable extended registers + pvga1a.PR5 = val; + break; + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:GFX:PVGA1A:Write to illegal index %2X", reg); + break; + } +} + +Bitu read_p3cf_pvga1a(Bitu reg,Bitu iolen) { + if (pvga1a.locked() && reg >= 0x09 && reg <= 0x0e) + return 0x0; + + switch (reg) { + case 0x09: + return pvga1a.PR0A; + case 0x0a: + return pvga1a.PR0B; + case 0x0b: + return pvga1a.PR1; + case 0x0c: + return pvga1a.PR2; + case 0x0d: + return pvga1a.PR3; + case 0x0e: + return pvga1a.PR4; + case 0x0f: + return pvga1a.PR5; + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:GFX:PVGA1A:Read from illegal index %2X", reg); + break; + } + + return 0x0; +} + +void FinishSetMode_PVGA1A(Bitu /*crtc_base*/, VGA_ModeExtraData* modeData) { + pvga1a.biosMode = modeData->modeNo; + +// Reset to single bank and set it to 0. May need to unlock first (DPaint locks on exit) + IO_Write(0x3ce, 0x0f); + Bitu oldlock = IO_Read(0x3cf); + IO_Write(0x3cf, 0x05); + IO_Write(0x3ce, 0x09); + IO_Write(0x3cf, 0x00); + IO_Write(0x3ce, 0x0a); + IO_Write(0x3cf, 0x00); + IO_Write(0x3ce, 0x0b); + Bit8u val = IO_Read(0x3cf); + IO_Write(0x3cf, val & ~0x08); + IO_Write(0x3ce, 0x0c); + IO_Write(0x3cf, 0x00); + IO_Write(0x3ce, 0x0d); + IO_Write(0x3cf, 0x00); + IO_Write(0x3ce, 0x0e); + IO_Write(0x3cf, 0x00); + IO_Write(0x3ce, 0x0f); + IO_Write(0x3cf, oldlock); + + if (svga.determine_mode) + svga.determine_mode(); + + if (vga.mode != M_VGA) + vga.config.compatible_chain4 = false; // in process of verification + else + vga.config.compatible_chain4 = true; + + VGA_SetupHandlers(); +} + +void DetermineMode_PVGA1A() { + // Close replica from the base implementation. It will stay here + // until I figure a way to either distinguish M_VGA and M_LIN8 or + // merge them. + if (vga.attr.mode_control & 1) { + if (vga.gfx.mode & 0x40) VGA_SetMode((pvga1a.biosMode<=0x13)?M_VGA:M_LIN8); + else if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4); + else if ((vga.gfx.miscellaneous & 0x0c)==0x0c) VGA_SetMode(M_CGA2); + else VGA_SetMode((pvga1a.biosMode<=0x13)?M_EGA:M_LIN4); + } else { + VGA_SetMode(M_TEXT); + } +} + +void SetClock_PVGA1A(Bitu which,Bitu target) { + if (which < 4) { + pvga1a.clockFreq[which]=1000*target; + VGA_StartResize(); + } +} + +Bitu GetClock_PVGA1A() { + return pvga1a.clockFreq[(vga.misc_output >> 2) & 3]; +} + +void SVGA_Setup_ParadisePVGA1A(void) { + svga.write_p3cf = &write_p3cf_pvga1a; + svga.read_p3cf = &read_p3cf_pvga1a; + + svga.set_video_mode = &FinishSetMode_PVGA1A; + svga.determine_mode = &DetermineMode_PVGA1A; + svga.set_clock = &SetClock_PVGA1A; + svga.get_clock = &GetClock_PVGA1A; + + VGA_SetClock(0,CLK_25); + VGA_SetClock(1,CLK_28); + VGA_SetClock(2,32400); // could not find documentation + VGA_SetClock(3,35900); + + // Set memory size at 512K (standard for PVGA1A) + pvga1a.PR1 = 2<<6; + + // Paradise ROM signature + PhysPt rom_base=PhysMake(0xc000,0); + phys_writeb(rom_base+0x007d,'V'); + phys_writeb(rom_base+0x007e,'G'); + phys_writeb(rom_base+0x007f,'A'); + phys_writeb(rom_base+0x0080,'='); + + IO_Write(0x3cf, 0x05); // Enable! +} diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index 9bf965ed..2f5484e6 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_s3.cpp,v 1.10 2007-12-27 10:57:51 c2woody Exp $ */ +/* $Id: vga_s3.cpp,v 1.11 2008-01-09 20:34:51 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -28,6 +28,7 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { //TODO Base address vga.s3.reg_31 = val; vga.config.compatible_chain4 = !(val&0x08); + vga.config.display_start = (vga.config.display_start&~0x30000)|((val&0x30)<<12); VGA_DetermineMode(); VGA_SetupHandlers(); break; @@ -48,9 +49,10 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { case 0x35: /* CR35 CRT Register Lock */ if (vga.s3.reg_lock1 != 0x48) return; //Needed for uvconfig detection vga.s3.reg_35=val & 0xf0; - if ((vga.s3.svga_bank.b.bank & 0xf) ^ (val & 0xf)) { - vga.s3.svga_bank.b.bank&=0xf0; - vga.s3.svga_bank.b.bank|=val & 0xf; + if ((vga.svga.bank_read & 0xf) ^ (val & 0xf)) { + vga.svga.bank_read&=0xf0; + vga.svga.bank_read|=val & 0xf; + vga.svga.bank_write = vga.svga.bank_read; VGA_SetupHandlers(); } break; @@ -138,12 +140,12 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { break; case 0x51: /* Extended System Control 2 */ vga.s3.reg_51=val & 0xc0; //Only store bits 6,7 - //TODO Display start - vga.config.display_start&=0xFCFFFF; - vga.config.display_start|=(val & 3) << 16; - if ((vga.s3.svga_bank.b.bank&0xcf) ^ ((val&0xc)<<2)) { - vga.s3.svga_bank.b.bank&=0xcf; - vga.s3.svga_bank.b.bank|=(val&0xc)<<2; + vga.config.display_start&=0xF3FFFF; + vga.config.display_start|=(val & 3) << 18; + if ((vga.svga.bank_read&0x30) ^ ((val&0xc)<<2)) { + vga.svga.bank_read&=0xcf; + vga.svga.bank_read|=(val&0xc)<<2; + vga.svga.bank_write = vga.svga.bank_read; VGA_SetupHandlers(); } if (((val & 0x30) ^ (vga.config.scan_len >> 4)) & 0x30) { @@ -310,7 +312,8 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { } break; case 0x6a: /* Extended System Control 4 */ - vga.s3.svga_bank.b.bank=val & 0x3f; + vga.svga.bank_read=val & 0x3f; + vga.svga.bank_write = vga.svga.bank_read; VGA_SetupHandlers(); break; case 0x6b: // BIOS scratchpad: LFB adress @@ -340,7 +343,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { //TODO mix in bits from baseaddress; return vga.s3.reg_31; case 0x35: /* CR35 CRT Register Lock */ - return vga.s3.reg_35|(vga.s3.svga_bank.b.bank & 0xf); + return vga.s3.reg_35|(vga.svga.bank_read & 0xf); case 0x36: /* CR36 Reset State Read 1 */ return 0x92; /* PCI version */ //2 Mb PCI and some bios settings @@ -349,7 +352,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { case 0x38: /* CR38 Register Lock 1 */ return vga.s3.reg_lock1; case 0x39: /* CR39 Register Lock 2 */ - return vga.s3.reg_lock2; + return vga.s3.reg_lock2; case 0x3a: return vga.s3.reg_3a; case 0x40: /* CR40 system config */ @@ -376,7 +379,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { return vga.s3.reg_50; case 0x51: /* Extended System Control 2 */ return ((vga.config.display_start >> 16) & 3 ) | - ((vga.s3.svga_bank.b.bank & 0x30) >> 2) | + ((vga.svga.bank_read & 0x30) >> 2) | ((vga.config.scan_len & 0x300) >> 4) | vga.s3.reg_51; case 0x52: // CR52 Extended BIOS flags 1 @@ -400,7 +403,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { case 0x69: /* Extended System Control 3 */ return (Bit8u)((vga.config.display_start & 0x1f0000)>>16); case 0x6a: /* Extended System Control 4 */ - return (Bit8u)(vga.s3.svga_bank.b.bank & 0x3f); + return (Bit8u)(vga.svga.bank_read & 0x3f); case 0x6b: // BIOS scatchpad: LFB address return vga.s3.reg_6b; default: @@ -471,6 +474,27 @@ Bitu SVGA_S3_GetClock(void) { clock = 28322000; else clock=1000*S3_CLOCK(vga.s3.clk[clock].m,vga.s3.clk[clock].n,vga.s3.clk[clock].r); + /* Check for dual transfer, master clock/2 */ + if (vga.s3.pll.cmd & 0x10) clock/=2; return clock; } +bool SVGA_S3_HWCursorActive(void) { + return (vga.s3.hgc.curmode & 0x1) != 0; +} + +void SVGA_Setup_S3Trio(void) { + svga.write_p3d5 = &SVGA_S3_WriteCRTC; + svga.read_p3d5 = &SVGA_S3_ReadCRTC; + svga.write_p3c5 = &SVGA_S3_WriteSEQ; + svga.read_p3c5 = &SVGA_S3_ReadSEQ; + svga.write_p3c0 = 0; /* no S3-specific functionality */ + svga.read_p3c1 = 0; /* no S3-specific functionality */ + + svga.set_video_mode = 0; /* implemented in core */ + svga.determine_mode = 0; /* implemented in core */ + svga.set_clock = 0; /* implemented in core */ + svga.get_clock = &SVGA_S3_GetClock; + svga.hardware_cursor_active = &SVGA_S3_HWCursorActive; + svga.accepts_mode = 0; /* don't filter modes */ +} diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 8e979ede..130025c4 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_seq.cpp,v 1.21 2007-12-23 16:00:53 c2woody Exp $ */ +/* $Id: vga_seq.cpp,v 1.22 2008-01-09 20:34:51 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -109,13 +109,12 @@ void write_p3c5(Bitu port,Bitu val,Bitu iolen) { } break; default: - switch (svgaCard) { - case SVGA_S3Trio: - SVGA_S3_WriteSEQ( seq(index), val, iolen ); - break; - default: + if (svga.write_p3c5) { + svga.write_p3c5(seq(index), val, iolen); + } else { LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:Write to illegal index %2X",seq(index)); } + break; } } @@ -137,11 +136,11 @@ Bitu read_p3c5(Bitu port,Bitu iolen) { break; case 4: /* Memory Mode */ return seq(memory_mode); + break; default: - switch (svgaCard) { - case SVGA_S3Trio: - return SVGA_S3_ReadSEQ( seq(index), iolen ); - } + if (svga.read_p3c5) + return svga.read_p3c5(seq(index), iolen); + break; } return 0; } diff --git a/src/hardware/vga_tseng.cpp b/src/hardware/vga_tseng.cpp new file mode 100644 index 00000000..3dadc70f --- /dev/null +++ b/src/hardware/vga_tseng.cpp @@ -0,0 +1,785 @@ +/* + * 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: vga_tseng.cpp,v 1.1 2008-01-09 20:34:51 c2woody Exp $ */ + +#include "dosbox.h" +#include "setup.h" +#include "vga.h" +#include "inout.h" +#include "mem.h" + +// Tseng ET4K data +typedef struct { + Bit8u extensionsEnabled; + +// Stored exact values of some registers. Documentation only specifies some bits but hardware checks may +// expect other bits to be preserved. + Bitu store_3d4_31; + Bitu store_3d4_32; + Bitu store_3d4_33; + Bitu store_3d4_34; + Bitu store_3d4_35; + Bitu store_3d4_36; + Bitu store_3d4_37; + Bitu store_3d4_3f; + + Bitu store_3c0_16; + Bitu store_3c0_17; + + Bitu store_3c4_06; + Bitu store_3c4_07; + + Bitu clockFreq[16]; + Bitu biosMode; +} SVGA_ET4K_DATA; + +static SVGA_ET4K_DATA et4k = { 1, 0, /* the rest are 0s */ }; + +#define STORE_ET4K(port, index) \ + case 0x##index: \ + et4k.store_##port##_##index = val; \ + break; + +#define RESTORE_ET4K(port, index) \ + case 0x##index: \ + return et4k.store_##port##_##index; + +// Tseng ET4K implementation +void write_p3d5_et4k(Bitu reg,Bitu val,Bitu iolen) { + if(!et4k.extensionsEnabled && reg!=0x33) + return; + + switch(reg) { + /* + 3d4h index 31h (R/W): General Purpose + bit 0-3 Scratch pad + 6-7 Clock Select bits 3-4. Bits 0-1 are in 3C2h/3CCh bits 2-3. + */ + STORE_ET4K(3d4, 31); + + // 3d4h index 32h - RAS/CAS Configuration (R/W) + // No effect on emulation. Should not be written by software. + STORE_ET4K(3d4, 32); + + case 0x33: + // 3d4 index 33h (R/W): Extended start Address + // 0-1 Display Start Address bits 16-17 + // 2-3 Cursor start address bits 16-17 + // Used by standard Tseng ID scheme + et4k.store_3d4_33 = val; + vga.config.display_start = (vga.config.display_start & 0xffff) | ((val & 0x03)<<16); + vga.config.cursor_start = (vga.config.cursor_start & 0xffff) | ((val & 0x0c)<<14); + break; + + /* + 3d4h index 34h (R/W): 6845 Compatibility Control Register + bit 0 Enable CS0 (alternate clock timing) + 1 Clock Select bit 2. Bits 0-1 in 3C2h bits 2-3, bits 3-4 are in 3d4h + index 31h bits 6-7 + 2 Tristate ET4000 bus and color outputs if set + 3 Video Subsystem Enable Register at 46E8h if set, at 3C3h if clear. + 4 Enable Translation ROM for reading CRTC and MISCOUT if set + 5 Enable Translation ROM for writing CRTC and MISCOUT if set + 6 Enable double scan in AT&T compatibility mode if set + 7 Enable 6845 compatibility if set + */ + // TODO: Bit 6 may have effect on emulation + STORE_ET4K(3d4, 34); + + case 0x35: + /* + 3d4h index 35h (R/W): Overflow High + bit 0 Vertical Blank Start Bit 10 (3d4h index 15h). + 1 Vertical Total Bit 10 (3d4h index 6). + 2 Vertical Display End Bit 10 (3d4h index 12h). + 3 Vertical Sync Start Bit 10 (3d4h index 10h). + 4 Line Compare Bit 10 (3d4h index 18h). + 5 Gen-Lock Enabled if set (External sync) + 6 (4000) Read/Modify/Write Enabled if set. Currently not implemented. + 7 Vertical interlace if set. The Vertical timing registers are + programmed as if the mode was non-interlaced!! + */ + et4k.store_3d4_35 = val; + vga.config.line_compare = (vga.config.line_compare & 0x3ff) | ((val&0x10)<<6); + // Abusing s3 ex_ver_overflow field. This is to be cleaned up later. + { + Bit8u s3val = + ((val & 0x01) << 2) | // vbstart + ((val & 0x02) >> 1) | // vtotal + ((val & 0x04) >> 1) | // vdispend + ((val & 0x08) << 1) | // vsyncstart (?) + ((val & 0x10) << 2); // linecomp + if ((s3val ^ vga.s3.ex_ver_overflow) & 0x3) { + vga.s3.ex_ver_overflow=s3val; + VGA_StartResize(); + } else vga.s3.ex_ver_overflow=s3val; + } + break; + + // 3d4h index 36h - Video System Configuration 1 (R/W) + // VGADOC provides a lot of info on this register, Ferraro has significantly less detail. + // This is unlikely to be used by any games. Bit 4 switches chipset into linear mode - + // that may be useful in some cases if there is any software actually using it. + // TODO (not near future): support linear addressing + STORE_ET4K(3d4, 36); + + // 3d4h index 37 - Video System Configuration 2 (R/W) + // Bits 0,1, and 3 provides information about memory size: + // 0-1 Bus width (1: 8 bit, 2: 16 bit, 3: 32 bit) + // 3 Size of RAM chips (0: 64Kx, 1: 256Kx) + // Other bits have no effect on emulation. + case 0x37: + if (val != et4k.store_3d4_37) { + et4k.store_3d4_37 = val; + VGA_SetupHandlers(); + } + break; + + case 0x3f: + /* + 3d4h index 3Fh (R/W): + bit 0 Bit 8 of the Horizontal Total (3d4h index 0) + 2 Bit 8 of the Horizontal Blank Start (3d4h index 3) + 4 Bit 8 of the Horizontal Retrace Start (3d4h index 4) + 7 Bit 8 of the CRTC offset register (3d4h index 13h). + */ + // The only unimplemented one is bit 7 + et4k.store_3d4_3f = val; + // Abusing s3 ex_hor_overflow field which very similar. This is + // to be cleaned up later + if ((val ^ vga.s3.ex_hor_overflow) & 3) { + vga.s3.ex_hor_overflow=(val&0x15); + VGA_StartResize(); + } else vga.s3.ex_hor_overflow=(val&0x15); + break; + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:ET4K:Write to illegal index %2X", reg); + break; + } +} + +Bitu read_p3d5_et4k(Bitu reg,Bitu iolen) { + if (!et4k.extensionsEnabled && reg!=0x33) + return 0x0; + switch(reg) { + RESTORE_ET4K(3d4, 31); + RESTORE_ET4K(3d4, 32); + RESTORE_ET4K(3d4, 33); + RESTORE_ET4K(3d4, 34); + RESTORE_ET4K(3d4, 35); + RESTORE_ET4K(3d4, 36); + RESTORE_ET4K(3d4, 37); + RESTORE_ET4K(3d4, 3f); + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:ET4K:Read from illegal index %2X", reg); + break; + } + return 0x0; +} + +void write_p3c5_et4k(Bitu reg,Bitu val,Bitu iolen) { + switch(reg) { + /* + 3C4h index 6 (R/W): TS State Control + bit 1-2 Font Width Select in dots/character + If 3C4h index 4 bit 0 clear: + 0: 9 dots, 1: 10 dots, 2: 12 dots, 3: 6 dots + If 3C4h index 5 bit 0 set: + 0: 8 dots, 1: 11 dots, 2: 7 dots, 3: 16 dots + Only valid if 3d4h index 34h bit 3 set. + */ + // TODO: Figure out if this has any practical use + STORE_ET4K(3c4, 06); + // 3C4h index 7 (R/W): TS Auxiliary Mode + // Unlikely to be used by games (things like ROM enable/disable and emulation of VGA vs EGA) + STORE_ET4K(3c4, 07); + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:ET4K:Write to illegal index %2X", reg); + break; + } +} + +Bitu read_p3c5_et4k(Bitu reg,Bitu iolen) { + switch(reg) { + RESTORE_ET4K(3c4, 06); + RESTORE_ET4K(3c4, 07); + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:ET4K:Read from illegal index %2X", reg); + break; + } + return 0x0; +} + +/* +3CDh (R/W): Segment Select +bit 0-3 64k Write bank number (0..15) + 4-7 64k Read bank number (0..15) +*/ +void write_p3cd_et4k(Bitu port,Bitu val,Bitu iolen) { + vga.svga.bank_write = val & 0x0f; + vga.svga.bank_read = (val>>4) & 0x0f; + VGA_SetupHandlers(); +} + +Bitu read_p3cd_et4k(Bitu port,Bitu iolen) { + return (vga.svga.bank_read<<4)|vga.svga.bank_write; +} + +void write_p3c0_et4k(Bitu reg,Bitu val,Bitu iolen) { + switch(reg) { + // 3c0 index 16h: ATC Miscellaneous + // VGADOC provides a lot of information, Ferarro documents only two bits + // and even those incompletely. The register is used as part of identification + // scheme. + // Unlikely to be used by any games but double timing may be useful. + // TODO: Figure out if this has any practical use + STORE_ET4K(3c0, 16); + /* + 3C0h index 17h (R/W): Miscellaneous 1 + bit 7 If set protects the internal palette ram and redefines the attribute + bits as follows: + Monochrome: + bit 0-2 Select font 0-7 + 3 If set selects blinking + 4 If set selects underline + 5 If set prevents the character from being displayed + 6 If set displays the character at half intensity + 7 If set selects reverse video + Color: + bit 0-1 Selects font 0-3 + 2 Foreground Blue + 3 Foreground Green + 4 Foreground Red + 5 Background Blue + 6 Background Green + 7 Background Red + */ + // TODO: Figure out if this has any practical use + STORE_ET4K(3c0, 17); + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:ATTR:ET4K:Write to illegal index %2X", reg); + break; + } +} + +Bitu read_p3c1_et4k(Bitu reg,Bitu iolen) { + switch(reg) { + RESTORE_ET4K(3c0, 16); + RESTORE_ET4K(3c0, 17); + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:ATTR:ET4K:Read from illegal index %2X", reg); + break; + } + return 0x0; +} + +/* +These ports are used but have little if any effect on emulation: + 3BFh (R/W): Hercules Compatibility Mode + 3CBh (R/W): PEL Address/Data Wd + 3CEh index 0Dh (R/W): Microsequencer Mode + 3CEh index 0Eh (R/W): Microsequencer Reset + 3d8h (R/W): Display Mode Control + 3DEh (W); AT&T Mode Control Register +*/ + +static Bitu get_clock_index_et4k() { + // Ignoring bit 4, using "only" 16 frequencies. Looks like most implementations had only that + return ((vga.misc_output>>2)&3) | ((et4k.store_3d4_34<<1)&4) | ((et4k.store_3d4_31>>3)&8); +} + +static void set_clock_index_et4k(Bitu index) { + // Shortwiring register reads/writes for simplicity + IO_Write(0x3c2, (vga.misc_output&~0x0c)|((index&3)<<2)); + et4k.store_3d4_34 = (et4k.store_3d4_34&~0x02)|((index&4)>>1); + et4k.store_3d4_31 = (et4k.store_3d4_31&~0xc0)|((index&8)<<3); // (index&0x18) if 32 clock frequencies are to be supported +} + +void FinishSetMode_ET4K(Bitu crtc_base, VGA_ModeExtraData* modeData) { + et4k.biosMode = modeData->modeNo; + + IO_Write(0x3cd, 0x00); // both banks to 0 + + // Reinterpret hor_overflow. Curiously, three bits out of four are + // in the same places. Input has hdispend (not supported), output + // has CRTC offset (also not supported) + Bit8u et4k_hor_overflow = + (modeData->hor_overflow & 0x01) | + (modeData->hor_overflow & 0x04) | + (modeData->hor_overflow & 0x10); + IO_Write(crtc_base,0x3f);IO_Write(crtc_base+1,et4k_hor_overflow); + + // Reinterpret ver_overflow + Bit8u et4k_ver_overflow = + ((modeData->ver_overflow & 0x01) << 1) | // vtotal10 + ((modeData->ver_overflow & 0x02) << 1) | // vdispend10 + ((modeData->ver_overflow & 0x04) >> 2) | // vbstart10 + ((modeData->ver_overflow & 0x10) >> 1) | // vretrace10 (tseng has vsync start?) + ((modeData->ver_overflow & 0x40) >> 2); // line_compare + IO_Write(crtc_base,0x35);IO_Write(crtc_base+1,et4k_ver_overflow); + + // Clear remaining ext CRTC registers + IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,0); + IO_Write(crtc_base,0x32);IO_Write(crtc_base+1,0); + IO_Write(crtc_base,0x33);IO_Write(crtc_base+1,0); + IO_Write(crtc_base,0x34);IO_Write(crtc_base+1,0); + IO_Write(crtc_base,0x36);IO_Write(crtc_base+1,0); + IO_Write(crtc_base,0x37);IO_Write(crtc_base+1,0x0f); // 1M video ram (0x0e for 512K, 0x0d for 256K) + // Clear ext SEQ + IO_Write(0x3c4,0x06);IO_Write(0x3c5,0); + IO_Write(0x3c4,0x07);IO_Write(0x3c5,0); + // Clear ext ATTR + IO_Write(0x3c0,0x16);IO_Write(0x3c0,0); + IO_Write(0x3c0,0x17);IO_Write(0x3c0,0); + + // Select SVGA clock to get close to 60Hz (not particularly clean implementation) + if (modeData->modeNo > 0x13) { + Bitu target = modeData->vtotal*8*modeData->htotal*60; + Bitu best = 1; + Bits dist = 100000000; + for (Bitu i=0; i<16; i++) { + if (abs(target-et4k.clockFreq[i]) < dist) { + best = i; + dist = abs(target-et4k.clockFreq[i]); + } + } + set_clock_index_et4k(best); + } + + if(svga.determine_mode) + svga.determine_mode(); + + // Verified (on real hardware and in a few games): Tseng ET4000 used chain4 implementation + // different from standard VGA. It was also not limited to 64K in regular mode 13h. + vga.config.compatible_chain4 = false; + + VGA_SetupHandlers(); +} + +void DetermineMode_ET4K() { + // Close replica from the base implementation. It will stay here + // until I figure a way to either distinguish M_VGA and M_LIN8 or + // merge them. + if (vga.attr.mode_control & 1) { + if (vga.gfx.mode & 0x40) VGA_SetMode((et4k.biosMode<=0x13)?M_VGA:M_LIN8); // Ugly... + else if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4); + else if ((vga.gfx.miscellaneous & 0x0c)==0x0c) VGA_SetMode(M_CGA2); + else VGA_SetMode((et4k.biosMode<=0x13)?M_EGA:M_LIN4); + } else { + VGA_SetMode(M_TEXT); + } +} + +void SetClock_ET4K(Bitu which,Bitu target) { + et4k.clockFreq[which]=1000*target; + VGA_StartResize(); +} + +Bitu GetClock_ET4K() { + return et4k.clockFreq[get_clock_index_et4k()]; +} + +bool AcceptsMode_ET4K(Bitu mode) { + return mode != 0x3d; +} + +void SVGA_Setup_TsengET4K(void) { + svga.write_p3d5 = &write_p3d5_et4k; + svga.read_p3d5 = &read_p3d5_et4k; + svga.write_p3c5 = &write_p3c5_et4k; + svga.read_p3c5 = &read_p3c5_et4k; + svga.write_p3c0 = &write_p3c0_et4k; + svga.read_p3c1 = &read_p3c1_et4k; + + svga.set_video_mode = &FinishSetMode_ET4K; + svga.determine_mode = &DetermineMode_ET4K; + svga.set_clock = &SetClock_ET4K; + svga.get_clock = &GetClock_ET4K; + svga.accepts_mode = &AcceptsMode_ET4K; + + // From the depths of X86Config, probably inexact + VGA_SetClock(0,CLK_25); + VGA_SetClock(1,CLK_28); + VGA_SetClock(2,32400); + VGA_SetClock(3,35900); + VGA_SetClock(4,39900); + VGA_SetClock(5,44700); + VGA_SetClock(6,31400); + VGA_SetClock(7,37500); + VGA_SetClock(8,50000); + VGA_SetClock(9,56500); + VGA_SetClock(10,64900); + VGA_SetClock(11,71900); + VGA_SetClock(12,79900); + VGA_SetClock(13,89600); + VGA_SetClock(14,62800); + VGA_SetClock(15,74800); + + IO_RegisterReadHandler(0x3cd,read_p3cd_et4k,IO_MB); + IO_RegisterWriteHandler(0x3cd,write_p3cd_et4k,IO_MB); + + // Tseng ROM signature + PhysPt rom_base=PhysMake(0xc000,0); + phys_writeb(rom_base+0x0075,' '); + phys_writeb(rom_base+0x0076,'T'); + phys_writeb(rom_base+0x0077,'s'); + phys_writeb(rom_base+0x0078,'e'); + phys_writeb(rom_base+0x0079,'n'); + phys_writeb(rom_base+0x007a,'g'); + phys_writeb(rom_base+0x007b,' '); +} + + +// Tseng ET3K implementation +typedef struct { +// Stored exact values of some registers. Documentation only specifies some bits but hardware checks may +// expect other bits to be preserved. + Bitu store_3d4_1b; + Bitu store_3d4_1c; + Bitu store_3d4_1d; + Bitu store_3d4_1e; + Bitu store_3d4_1f; + Bitu store_3d4_20; + Bitu store_3d4_21; + Bitu store_3d4_23; // note that 22 is missing + Bitu store_3d4_24; + Bitu store_3d4_25; + + Bitu store_3c0_16; + Bitu store_3c0_17; + + Bitu store_3c4_06; + Bitu store_3c4_07; + + Bitu clockFreq[8]; + Bitu biosMode; +} SVGA_ET3K_DATA; + +static SVGA_ET3K_DATA et3k = { 0 /* and the rest are 0s as well */ }; + +#define STORE_ET3K(port, index) \ + case 0x##index: \ + et3k.store_##port##_##index = val; \ + break; + +#define RESTORE_ET3K(port, index) \ + case 0x##index: \ + return et3k.store_##port##_##index; + + +void write_p3d5_et3k(Bitu reg,Bitu val,Bitu iolen) { + switch(reg) { + // 3d4 index 1bh-21h: Hardware zoom control registers + // I am not sure if there was a piece of software that used these. + // Not implemented and will probably stay this way. + STORE_ET3K(3d4, 1b); + STORE_ET3K(3d4, 1c); + STORE_ET3K(3d4, 1d); + STORE_ET3K(3d4, 1e); + STORE_ET3K(3d4, 1f); + STORE_ET3K(3d4, 20); + STORE_ET3K(3d4, 21); + + case 0x23: + /* + 3d4h index 23h (R/W): Extended start ET3000 + bit 0 Cursor start address bit 16 + 1 Display start address bit 16 + 2 Zoom start address bit 16 + 7 If set memory address 8 is output on the MBSL pin (allowing access to + 1MB), if clear the blanking signal is output. + */ + // Only bits 1 and 2 are supported. Bit 2 is related to hardware zoom, bit 7 is too obscure to be useful + et3k.store_3d4_23 = val; + vga.config.display_start = (vga.config.display_start & 0xffff) | ((val & 0x02)<<15); + vga.config.cursor_start = (vga.config.cursor_start & 0xffff) | ((val & 0x01)<<16); + break; + + + /* + 3d4h index 24h (R/W): Compatibility Control + bit 0 Enable Clock Translate if set + 1 Clock Select bit 2. Bits 0-1 are in 3C2h/3CCh. + 2 Enable tri-state for all output pins if set + 3 Enable input A8 of 1MB DRAMs from the INTL output if set + 4 Reserved + 5 Enable external ROM CRTC translation if set + 6 Enable Double Scan and Underline Attribute if set + 7 Enable 6845 compatibility if set. + */ + // TODO: Some of these may be worth implementing. + STORE_ET3K(3d4, 24); + + + case 0x25: + /* + 3d4h index 25h (R/W): Overflow High + bit 0 Vertical Blank Start bit 10 + 1 Vertical Total Start bit 10 + 2 Vertical Display End bit 10 + 3 Vertical Sync Start bit 10 + 4 Line Compare bit 10 + 5-6 Reserved + 7 Vertical Interlace if set + */ + et3k.store_3d4_25 = val; + vga.config.line_compare = (vga.config.line_compare & 0x3ff) | ((val&0x10)<<6); + // Abusing s3 ex_ver_overflow field. This is to be cleaned up later. + { + Bit8u s3val = + ((val & 0x01) << 2) | // vbstart + ((val & 0x02) >> 1) | // vtotal + ((val & 0x04) >> 1) | // vdispend + ((val & 0x08) << 1) | // vsyncstart (?) + ((val & 0x10) << 2); // linecomp + if ((s3val ^ vga.s3.ex_ver_overflow) & 0x3) { + vga.s3.ex_ver_overflow=s3val; + VGA_StartResize(); + } else vga.s3.ex_ver_overflow=s3val; + } + break; + + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:ET3K:Write to illegal index %2X", reg); + break; + } +} + +Bitu read_p3d5_et3k(Bitu reg,Bitu iolen) { + switch(reg) { + RESTORE_ET3K(3d4, 1b); + RESTORE_ET3K(3d4, 1c); + RESTORE_ET3K(3d4, 1d); + RESTORE_ET3K(3d4, 1e); + RESTORE_ET3K(3d4, 1f); + RESTORE_ET3K(3d4, 20); + RESTORE_ET3K(3d4, 21); + RESTORE_ET3K(3d4, 23); + RESTORE_ET3K(3d4, 24); + RESTORE_ET3K(3d4, 25); + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:ET3K:Read from illegal index %2X", reg); + break; + } + return 0x0; +} + +void write_p3c5_et3k(Bitu reg,Bitu val,Bitu iolen) { + switch(reg) { + // Both registers deal mostly with hardware zoom which is not implemented. Other bits + // seem to be useless for emulation with the exception of index 7 bit 4 (font select) + STORE_ET3K(3c4, 06); + STORE_ET3K(3c4, 07); + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:ET3K:Write to illegal index %2X", reg); + break; + } +} + +Bitu read_p3c5_et3k(Bitu reg,Bitu iolen) { + switch(reg) { + RESTORE_ET3K(3c4, 06); + RESTORE_ET3K(3c4, 07); + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:ET3K:Read from illegal index %2X", reg); + break; + } + return 0x0; +} + +/* +3CDh (R/W): Segment Select +bit 0-2 64k Write bank number + 3-5 64k Read bank number + 6-7 Segment Configuration. + 0 128K segments + 1 64K segments + 2 1M linear memory +NOTES: 1M linear memory is not supported +*/ +void write_p3cd_et3k(Bitu port,Bitu val,Bitu iolen) { + vga.svga.bank_write = val & 0x07; + vga.svga.bank_read = (val>>3) & 0x07; + vga.svga.bank_size = (val&0x40)?64*1024:128*1024; + VGA_SetupHandlers(); +} + +Bitu read_p3cd_et3k(Bitu port,Bitu iolen) { + return (vga.svga.bank_read<<3)|vga.svga.bank_write|((vga.svga.bank_size==128*1024)?0:0x40); +} + +void write_p3c0_et3k(Bitu reg,Bitu val,Bitu iolen) { +// See ET4K notes. + switch(reg) { + STORE_ET3K(3c0, 16); + STORE_ET3K(3c0, 17); + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:ATTR:ET3K:Write to illegal index %2X", reg); + break; + } +} + +Bitu read_p3c1_et3k(Bitu reg,Bitu iolen) { + switch(reg) { + RESTORE_ET3K(3c0, 16); + RESTORE_ET3K(3c0, 17); + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:ATTR:ET3K:Read from illegal index %2X", reg); + break; + } + return 0x0; +} + +/* +These ports are used but have little if any effect on emulation: + 3B8h (W): Display Mode Control Register + 3BFh (R/W): Hercules Compatibility Mode + 3CBh (R/W): PEL Address/Data Wd + 3CEh index 0Dh (R/W): Microsequencer Mode + 3CEh index 0Eh (R/W): Microsequencer Reset + 3d8h (R/W): Display Mode Control + 3D9h (W): Color Select Register + 3dAh (W): Feature Control Register + 3DEh (W); AT&T Mode Control Register +*/ + +static Bitu get_clock_index_et3k() { + return ((vga.misc_output>>2)&3) | ((et3k.store_3d4_24<<1)&4); +} + +static void set_clock_index_et3k(Bitu index) { + // Shortwiring register reads/writes for simplicity + IO_Write(0x3c2, (vga.misc_output&~0x0c)|((index&3)<<2)); + et3k.store_3d4_24 = (et3k.store_3d4_24&~0x02)|((index&4)>>1); +} + +void FinishSetMode_ET3K(Bitu crtc_base, VGA_ModeExtraData* modeData) { + et3k.biosMode = modeData->modeNo; + + IO_Write(0x3cd, 0x40); // both banks to 0, 64K bank size + + // Tseng ET3K does not have horizontal overflow bits + // Reinterpret ver_overflow + Bit8u et4k_ver_overflow = + ((modeData->ver_overflow & 0x01) << 1) | // vtotal10 + ((modeData->ver_overflow & 0x02) << 1) | // vdispend10 + ((modeData->ver_overflow & 0x04) >> 2) | // vbstart10 + ((modeData->ver_overflow & 0x10) >> 1) | // vretrace10 (tseng has vsync start?) + ((modeData->ver_overflow & 0x40) >> 2); // line_compare + IO_Write(crtc_base,0x25);IO_Write(crtc_base+1,et4k_ver_overflow); + + // Clear remaining ext CRTC registers + for (Bitu i=0x16; i<=0x21; i++) + IO_Write(crtc_base,i);IO_Write(crtc_base+1,0); + IO_Write(crtc_base,0x23);IO_Write(crtc_base+1,0); + IO_Write(crtc_base,0x24);IO_Write(crtc_base+1,0); + // Clear ext SEQ + IO_Write(0x3c4,0x06);IO_Write(0x3c5,0); + IO_Write(0x3c4,0x07);IO_Write(0x3c5,0x40); // 0 in this register breaks WHATVGA + // Clear ext ATTR + IO_Write(0x3c0,0x16);IO_Write(0x3c0,0); + IO_Write(0x3c0,0x17);IO_Write(0x3c0,0); + + // Select SVGA clock to get close to 60Hz (not particularly clean implementation) + if (modeData->modeNo > 0x13) { + Bitu target = modeData->vtotal*8*modeData->htotal*60; + Bitu best = 1; + Bits dist = 100000000; + for (Bitu i=0; i<8; i++) { + if (abs(target-et3k.clockFreq[i]) < dist) { + best = i; + dist = abs(target-et3k.clockFreq[i]); + } + } + set_clock_index_et3k(best); + } + + if (svga.determine_mode) + svga.determine_mode(); + + // Verified on functioning (at last!) hardware: Tseng ET3000 is the same as ET4000 when + // it comes to chain4 architecture + vga.config.compatible_chain4 = false; + + VGA_SetupHandlers(); +} + +void DetermineMode_ET3K() { + // Close replica from the base implementation. It will stay here + // until I figure a way to either distinguish M_VGA and M_LIN8 or + // merge them. + if (vga.attr.mode_control & 1) { + if (vga.gfx.mode & 0x40) VGA_SetMode((et3k.biosMode<=0x13)?M_VGA:M_LIN8); // Ugly... + else if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4); + else if ((vga.gfx.miscellaneous & 0x0c)==0x0c) VGA_SetMode(M_CGA2); + else VGA_SetMode((et3k.biosMode<=0x13)?M_EGA:M_LIN4); + } else { + VGA_SetMode(M_TEXT); + } +} + +void SetClock_ET3K(Bitu which,Bitu target) { + et3k.clockFreq[which]=1000*target; + VGA_StartResize(); +} + +Bitu GetClock_ET3K() { + return et3k.clockFreq[get_clock_index_et3k()]; +} + +bool AcceptsMode_ET3K(Bitu mode) { + return mode <= 0x37 && mode != 0x2f; +} + +void SVGA_Setup_TsengET3K(void) { + svga.write_p3d5 = &write_p3d5_et3k; + svga.read_p3d5 = &read_p3d5_et3k; + svga.write_p3c5 = &write_p3c5_et3k; + svga.read_p3c5 = &read_p3c5_et3k; + svga.write_p3c0 = &write_p3c0_et3k; + svga.read_p3c1 = &read_p3c1_et3k; + + svga.set_video_mode = &FinishSetMode_ET3K; + svga.determine_mode = &DetermineMode_ET3K; + svga.set_clock = &SetClock_ET3K; + svga.get_clock = &GetClock_ET3K; + svga.accepts_mode = &AcceptsMode_ET3K; + + VGA_SetClock(0,CLK_25); + VGA_SetClock(1,CLK_28); + VGA_SetClock(2,32400); + VGA_SetClock(3,35900); + VGA_SetClock(4,39900); + VGA_SetClock(5,44700); + VGA_SetClock(6,31400); + VGA_SetClock(7,37500); + + IO_RegisterReadHandler(0x3cd,read_p3cd_et3k,IO_MB); + IO_RegisterWriteHandler(0x3cd,write_p3cd_et3k,IO_MB); + + // Tseng ROM signature + PhysPt rom_base=PhysMake(0xc000,0); + phys_writeb(rom_base+0x0075,' '); + phys_writeb(rom_base+0x0076,'T'); + phys_writeb(rom_base+0x0077,'s'); + phys_writeb(rom_base+0x0078,'e'); + phys_writeb(rom_base+0x0079,'n'); + phys_writeb(rom_base+0x007a,'g'); + phys_writeb(rom_base+0x007b,' '); +} diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 96af9e9b..3effb153 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: int10.cpp,v 1.48 2008-01-09 20:34:51 c2woody Exp $ */ + #include "dosbox.h" #include "mem.h" #include "callback.h" @@ -480,7 +482,7 @@ graphics_chars: } break; case 0x4f: /* VESA Calls */ - if ((!IS_VGA_ARCH) || (svgaCard==SVGA_None)) break; + if ((!IS_VGA_ARCH) || (svgaCard!=SVGA_S3Trio)) break; switch (reg_al) { case 0x00: /* Get SVGA Information */ reg_al=0x4f; diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index c64f2714..a3b3cb92 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.73 2007-12-27 10:57:51 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.74 2008-01-09 20:34:51 c2woody Exp $ */ #include @@ -124,6 +124,79 @@ VideoModeBlock ModeList_VGA[]={ {0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, }; +VideoModeBlock ModeList_VGA_Tseng[]={ +/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */ +{ 0x000 ,M_TEXT ,360 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, +{ 0x001 ,M_TEXT ,360 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, +{ 0x002 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x003 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x007 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, + +{ 0x00D ,M_EGA ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, +{ 0x00E ,M_EGA ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE }, +{ 0x00F ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 },/*was EGA_2*/ +{ 0x010 ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, +{ 0x011 ,M_EGA ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 },/*was EGA_2 */ +{ 0x012 ,M_EGA ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, +{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x2000 ,100 ,449 ,80 ,400 ,0 }, + +{ 0x018 ,M_TEXT ,1056 ,688, 132,44, 8, 8, 1 ,0xB0000 ,0x4000, 192, 800, 132, 704, 0 }, +{ 0x019 ,M_TEXT ,1056 ,400, 132,25, 8, 16,1 ,0xB0000 ,0x2000, 192, 449, 132, 400, 0 }, +{ 0x01A ,M_TEXT ,1056 ,400, 132,28, 8, 16,1 ,0xB0000 ,0x2000, 192, 449, 132, 448, 0 }, +{ 0x022 ,M_TEXT ,1056 ,688, 132,44, 8, 8, 1 ,0xB8000 ,0x4000, 192, 800, 132, 704, 0 }, +{ 0x023 ,M_TEXT ,1056 ,400, 132,25, 8, 16,1 ,0xB8000 ,0x2000, 192, 449, 132, 400, 0 }, +{ 0x024 ,M_TEXT ,1056 ,400, 132,28, 8, 16,1 ,0xB8000 ,0x2000, 192, 449, 132, 448, 0 }, +{ 0x025 ,M_LIN4 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 , 0 }, +{ 0x029 ,M_LIN4 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0xA000, 128 ,663 ,100,600 , 0 }, +{ 0x02D ,M_LIN8 ,640 ,350 ,80 ,21 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,350 , 0 }, +{ 0x02E ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , 0 }, +{ 0x02F ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , 0 },/* ET4000 only */ +{ 0x030 ,M_LIN8 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 , 0 }, +{ 0x036 ,M_LIN4 ,960 , 720,120,45 ,8 ,16 ,1 ,0xA0000 ,0xA000, 120 ,800 ,120,720 , 0 },/* STB only */ +{ 0x037 ,M_LIN4 ,1024, 768,128,48 ,8 ,16 ,1 ,0xA0000 ,0xA000, 128 ,800 ,128,768 , 0 }, +{ 0x038 ,M_LIN8 ,1024 ,768,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,800 ,128,768 , 0 },/* ET4000 only */ +{ 0x03D ,M_LIN4 ,1280,1024,160,64 ,8 ,16 ,1 ,0xA0000 ,0xA000, 160 ,1152,160,1024, 0 },/* newer ET4000 */ +{ 0x03E ,M_LIN4 ,1280, 960,160,60 ,8 ,16 ,1 ,0xA0000 ,0xA000, 160 ,1024,160,960 , 0 },/* Definicon only */ +{ 0x06A ,M_LIN4 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0xA000, 128 ,663 ,100,600 , 0 },/* newer ET4000 */ + +{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, +}; + +VideoModeBlock ModeList_VGA_Paradise[]={ +/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */ +{ 0x000 ,M_TEXT ,360 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, +{ 0x001 ,M_TEXT ,360 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, +{ 0x002 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x003 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x007 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, + +{ 0x00D ,M_EGA ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, +{ 0x00E ,M_EGA ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE }, +{ 0x00F ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 },/*was EGA_2*/ +{ 0x010 ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, +{ 0x011 ,M_EGA ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 },/*was EGA_2 */ +{ 0x012 ,M_EGA ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, +{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x2000 ,100 ,449 ,80 ,400 ,0 }, + +{ 0x054 ,M_TEXT ,1056 ,688, 132,43, 8, 9, 1, 0xB0000, 0x4000, 192, 720, 132,688, 0 }, +{ 0x055 ,M_TEXT ,1056 ,400, 132,25, 8, 16,1, 0xB0000, 0x2000, 192, 449, 132,400, 0 }, +{ 0x056 ,M_TEXT ,1056 ,688, 132,43, 8, 9, 1, 0xB0000, 0x4000, 192, 720, 132,688, 0 }, +{ 0x057 ,M_TEXT ,1056 ,400, 132,25, 8, 16,1, 0xB0000, 0x2000, 192, 449, 132,400, 0 }, +{ 0x058 ,M_LIN4 ,800 , 600, 100,37, 8, 16,1, 0xA0000, 0xA000, 128 ,663 ,100,600, 0 }, +{ 0x05D ,M_LIN4 ,1024, 768, 128,48 ,8, 16,1, 0xA0000, 0x10000,128 ,800 ,128,768 ,0 }, // documented only on C00 upwards +{ 0x05E ,M_LIN8 ,640 , 400, 80 ,25, 8, 16,1, 0xA0000, 0x10000,100 ,449 ,80 ,400, 0 }, +{ 0x05F ,M_LIN8 ,640 , 480, 80 ,30, 8, 16,1, 0xA0000, 0x10000,100 ,525 ,80 ,480, 0 }, + +{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, +}; + + VideoModeBlock ModeList_EGA[]={ /* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */ { 0x000 ,M_TEXT ,320 ,350 ,40 ,25 ,8 ,14 ,8 ,0xB8000 ,0x0800 ,50 ,366 ,40 ,350 ,_EGA_HALF_CLOCK }, @@ -510,9 +583,29 @@ bool INT10_SetVideoMode(Bitu mode) { Bit8u modeset_ctl,video_ctl,vga_switches; if (IS_VGA_ARCH) { - if (!SetCurMode(ModeList_VGA,mode)){ - LOG(LOG_INT10,LOG_ERROR)("VGA:Trying to set illegal mode %X",mode); - return false; + if (svga.accepts_mode) { + if (!svga.accepts_mode(mode)) return false; + } + + switch(svgaCard) { + case SVGA_TsengET4K: + case SVGA_TsengET3K: + if (!SetCurMode(ModeList_VGA_Tseng,mode)){ + LOG(LOG_INT10,LOG_ERROR)("VGA:Trying to set illegal mode %X",mode); + return false; + } + break; + case SVGA_ParadisePVGA1A: + if (!SetCurMode(ModeList_VGA_Paradise,mode)){ + LOG(LOG_INT10,LOG_ERROR)("VGA:Trying to set illegal mode %X",mode); + return false; + } + break; + default: + if (!SetCurMode(ModeList_VGA,mode)){ + LOG(LOG_INT10,LOG_ERROR)("VGA:Trying to set illegal mode %X",mode); + return false; + } } } else { if (!SetCurMode(ModeList_EGA,mode)){ @@ -534,7 +627,7 @@ bool INT10_SetVideoMode(Bitu mode) { else crtc_base=0x3d4; // Disable MMIO here so we can read / write memory - if (IS_VGA_ARCH) IO_Write(crtc_base,0x53);IO_Write(crtc_base+1,0x0); + if (IS_VGA_ARCH && svgaCard == SVGA_S3Trio) IO_Write(crtc_base,0x53);IO_Write(crtc_base+1,0x0); /* Setup MISC Output Register */ Bit8u misc_output=0x2 | (mono_mode ? 0x0 : 0x1); @@ -744,10 +837,14 @@ bool INT10_SetVideoMode(Bitu mode) { /* OverFlow */ IO_Write(crtc_base,0x07);IO_Write(crtc_base+1,overflow); - /* Extended Horizontal Overflow */ - IO_Write(crtc_base,0x5d);IO_Write(crtc_base+1,hor_overflow); - /* Extended Vertical Overflow */ - IO_Write(crtc_base,0x5e);IO_Write(crtc_base+1,ver_overflow); + + if (svgaCard == SVGA_S3Trio) { + /* Extended Horizontal Overflow */ + IO_Write(crtc_base,0x5d);IO_Write(crtc_base+1,hor_overflow); + /* Extended Vertical Overflow */ + IO_Write(crtc_base,0x5e);IO_Write(crtc_base+1,ver_overflow); + } + /* Offset Register */ Bitu offset; switch (CurMode->type) { @@ -766,15 +863,18 @@ bool INT10_SetVideoMode(Bitu mode) { } IO_Write(crtc_base,0x13); IO_Write(crtc_base + 1,offset & 0xff); - /* Extended System Control 2 Register */ - /* This register actually has more bits but only use the extended offset ones */ - IO_Write(crtc_base,0x51); - IO_Write(crtc_base + 1,(offset & 0x300) >> 4); - /* Clear remaining bits of the display start */ - IO_Write(crtc_base,0x69); - IO_Write(crtc_base + 1,0); - /* Extended Vertical Overflow */ - IO_Write(crtc_base,0x5e);IO_Write(crtc_base+1,ver_overflow); + + if (svgaCard == SVGA_S3Trio) { + /* Extended System Control 2 Register */ + /* This register actually has more bits but only use the extended offset ones */ + IO_Write(crtc_base,0x51); + IO_Write(crtc_base + 1,(offset & 0x300) >> 4); + /* Clear remaining bits of the display start */ + IO_Write(crtc_base,0x69); + IO_Write(crtc_base + 1,0); + /* Extended Vertical Overflow */ + IO_Write(crtc_base,0x5e);IO_Write(crtc_base+1,ver_overflow); + } /* Mode Control */ Bit8u mode_control=0; @@ -815,32 +915,36 @@ bool INT10_SetVideoMode(Bitu mode) { /* Renable write protection */ IO_Write(crtc_base,0x11); IO_Write(crtc_base+1,IO_Read(crtc_base+1)|0x80); - /* Setup the correct clock */ - if (CurMode->mode>=0x100) { - misc_output|=0xef; //Select clock 3 - Bitu clock=CurMode->vtotal*8*CurMode->htotal*70; - VGA_SetClock(3,clock/1000); + + if (svgaCard == SVGA_S3Trio) { + /* Setup the correct clock */ + if (CurMode->mode>=0x100) { + misc_output|=0xef; //Select clock 3 + Bitu clock=CurMode->vtotal*8*CurMode->htotal*70; + VGA_SetClock(3,clock/1000); + } + Bit8u misc_control_2; + /* Setup Pixel format */ + switch (CurMode->type) { + case M_LIN8: + misc_control_2=0x00; + break; + case M_LIN15: + misc_control_2=0x30; + break; + case M_LIN16: + misc_control_2=0x50; + break; + case M_LIN32: + misc_control_2=0xd0; + break; + default: + misc_control_2=0x0; + break; + } + IO_WriteB(crtc_base,0x67);IO_WriteB(crtc_base+1,misc_control_2); } - Bit8u misc_control_2; - /* Setup Pixel format */ - switch (CurMode->type) { - case M_LIN8: - misc_control_2=0x00; - break; - case M_LIN15: - misc_control_2=0x30; - break; - case M_LIN16: - misc_control_2=0x50; - break; - case M_LIN32: - misc_control_2=0xd0; - break; - default: - misc_control_2=0x0; - break; - } - IO_WriteB(crtc_base,0x67);IO_WriteB(crtc_base+1,misc_control_2); + /* Write Misc Output */ IO_Write(0x3c2,misc_output); /* Program Graphics controller */ @@ -1073,78 +1177,90 @@ dac_text16: } // disabled, has to be set in bios.cpp exclusively // real_writeb(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE,feature); - /* Setup the CPU Window */ - IO_Write(crtc_base,0x6a); - IO_Write(crtc_base+1,0); - /* Setup the linear frame buffer */ - IO_Write(crtc_base,0x59); - IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 24)); - IO_Write(crtc_base,0x5a); - IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 16)); - IO_Write(crtc_base,0x6b); // BIOS scratchpad - IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 24)); - - /* Setup some remaining S3 registers */ - IO_Write(crtc_base,0x41); // BIOS scratchpad - IO_Write(crtc_base+1,0x88); - IO_Write(crtc_base,0x52); // extended BIOS scratchpad - IO_Write(crtc_base+1,0x80); - IO_Write(0x3c4,0x15); - IO_Write(0x3c5,0x03); + if (svgaCard == SVGA_S3Trio) { + /* Setup the CPU Window */ + IO_Write(crtc_base,0x6a); + IO_Write(crtc_base+1,0); + /* Setup the linear frame buffer */ + IO_Write(crtc_base,0x59); + IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 24)); + IO_Write(crtc_base,0x5a); + IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 16)); + IO_Write(crtc_base,0x6b); // BIOS scratchpad + IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 24)); + + /* Setup some remaining S3 registers */ + IO_Write(crtc_base,0x41); // BIOS scratchpad + IO_Write(crtc_base+1,0x88); + IO_Write(crtc_base,0x52); // extended BIOS scratchpad + IO_Write(crtc_base+1,0x80); - // Accellerator setup - Bitu reg_50=0; - switch (CurMode->type) { - case M_LIN15: - case M_LIN16: reg_50|=0x10; break; - case M_LIN32: reg_50|=0x30; break; - } - switch(CurMode->swidth) - { - case 640: reg_50|=0x40; break; - case 800: reg_50|=0x80; break; - case 1024: break; - case 1152: reg_50|=0x01; break; - case 1280: reg_50|=0xc1; break; - } - IO_WriteB(crtc_base,0x50); IO_WriteB(crtc_base+1,reg_50); + IO_Write(0x3c4,0x15); + IO_Write(0x3c5,0x03); - Bitu reg_31, reg_3a; - switch (CurMode->type) { + // Accellerator setup + Bitu reg_50=0; + switch (CurMode->type) { + case M_LIN15: + case M_LIN16: reg_50|=0x10; break; + case M_LIN32: reg_50|=0x30; break; + } + switch(CurMode->swidth) { + case 640: reg_50|=0x40; break; + case 800: reg_50|=0x80; break; + case 1024: break; + case 1152: reg_50|=0x01; break; + case 1280: reg_50|=0xc1; break; + } + IO_WriteB(crtc_base,0x50); IO_WriteB(crtc_base+1,reg_50); + + Bitu reg_31, reg_3a; + switch (CurMode->type) { + case M_LIN15: + case M_LIN16: + case M_LIN32: + reg_3a=0x15; + break; + case M_LIN8: + // S3VBE20 does it this way. The other double pixel bit does not + // seem to have an effect on the Trio64. + if(CurMode->special&_VGA_PIXEL_DOUBLE) reg_3a=0x5; + else reg_3a=0x15; + break; + default: + reg_3a=5; + break; + }; + + switch (CurMode->type) { + case M_LIN4: // <- Theres a discrepance with real hardware on this + case M_LIN8: case M_LIN15: case M_LIN16: case M_LIN32: - reg_3a=0x15; - break; - case M_LIN8: - // S3VBE20 does it this way. The other double pixel bit does not - // seem to have an effect on the Trio64. - if(CurMode->special&_VGA_PIXEL_DOUBLE) reg_3a=0x5; - else reg_3a=0x15; + reg_31 = 9; break; default: - reg_3a=5; - }; - - switch (CurMode->type) { - case M_LIN4: // <- Theres a discrepance with real hardware on this - case M_LIN8: - case M_LIN15: - case M_LIN16: - case M_LIN32: - reg_31 = 9; - break; - default: - reg_31 = 5; - break; - } - IO_Write(crtc_base,0x3a);IO_Write(crtc_base+1,reg_3a); - IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,reg_31); //Enable banked memory and 256k+ access - IO_Write(crtc_base,0x58);IO_Write(crtc_base+1,0x3); //Enable 8 mb of linear addressing + reg_31 = 5; + break; + } + IO_Write(crtc_base,0x3a);IO_Write(crtc_base+1,reg_3a); + IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,reg_31); //Enable banked memory and 256k+ access + IO_Write(crtc_base,0x58);IO_Write(crtc_base+1,0x3); //Enable 8 mb of linear addressing - IO_Write(crtc_base,0x38);IO_Write(crtc_base+1,0x48); //Register lock 1 - IO_Write(crtc_base,0x39);IO_Write(crtc_base+1,0xa5); //Register lock 2 + IO_Write(crtc_base,0x38);IO_Write(crtc_base+1,0x48); //Register lock 1 + IO_Write(crtc_base,0x39);IO_Write(crtc_base+1,0xa5); //Register lock 2 + } else if (svga.set_video_mode) { + VGA_ModeExtraData modeData; + modeData.ver_overflow = ver_overflow; + modeData.hor_overflow = hor_overflow; + modeData.offset = offset; + modeData.modeNo = CurMode->mode; + modeData.htotal = CurMode->htotal; + modeData.vtotal = CurMode->vtotal; + svga.set_video_mode(crtc_base, &modeData); + } FinishSetMode(clearmem); /* Load text mode font */ diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index a98b5210..f2257ce0 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -513,12 +513,18 @@ + + + + From 056302a6a59895dc2e61406b965bcbae6d76d1fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 10 Jan 2008 20:36:03 +0000 Subject: [PATCH 2988/4131] xga fix for win3x paint (hal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3076 --- src/hardware/vga_xga.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index 4054be5f..d92d6413 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_xga.cpp,v 1.10 2007-12-10 22:11:13 c2woody Exp $ */ +/* $Id: vga_xga.cpp,v 1.11 2008-01-10 20:36:03 c2woody Exp $ */ #include #include "dosbox.h" @@ -581,9 +581,10 @@ void XGA_DrawWait(Bitu val, Bitu len) { XGA_DrawWaitSub(mixmode, val); break; case 0x20 | M_LIN8: // 16 bit - XGA_DrawWaitSub(mixmode, val); - if(!xga.waitcmd.newline) - XGA_DrawWaitSub(mixmode, val>>8); + for(Bitu i = 0; i < len; i++) { + XGA_DrawWaitSub(mixmode, (val>>(8*i))&0xff); + if(xga.waitcmd.newline) break; + } break; case 0x40 | M_LIN8: // 32 bit for(int i = 0; i < 4; i++) From 50917251f442780277105699e298e3247fa87a11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 12 Jan 2008 17:37:48 +0000 Subject: [PATCH 2989/4131] add variable-size graphics memory, enable some more vga memory wrapping (vasyl) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3077 --- include/vga.h | 18 +++-- src/hardware/vga.cpp | 7 +- src/hardware/vga_draw.cpp | 30 +++++--- src/hardware/vga_memory.cpp | 124 +++++++++++++++++++++++++++------- src/hardware/vga_paradise.cpp | 31 +++++++-- src/hardware/vga_s3.cpp | 38 +++++++++-- src/hardware/vga_tseng.cpp | 25 +++++-- src/hardware/vga_xga.cpp | 4 +- src/ints/int10_modes.cpp | 52 +++++++++++++- src/ints/int10_vesa.cpp | 32 +++++---- 10 files changed, 285 insertions(+), 76 deletions(-) diff --git a/include/vga.h b/include/vga.h index a497b33a..9cf7d2df 100644 --- a/include/vga.h +++ b/include/vga.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga.h,v 1.37 2008-01-09 20:34:21 c2woody Exp $ */ +/* $Id: vga.h,v 1.38 2008-01-12 17:36:48 c2woody Exp $ */ #ifndef DOSBOX_VGA_H #define DOSBOX_VGA_H @@ -31,9 +31,6 @@ #define VGA_MEMORY (2*1024*1024) #define VGA_CHANGE_SHIFT 9 -//Offset inside VGA_MEMORY that will be used for certain types of caching -#define VGA_CACHE_OFFSET (512*1024) - class PageHandler; @@ -164,6 +161,7 @@ typedef struct { 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 @@ -330,11 +328,12 @@ typedef union { typedef struct { Bit8u* linear; + Bit8u* linear_orgptr; } VGA_Memory; typedef struct { //Add a few more just to be safe - Bit8u map[(VGA_MEMORY >> VGA_CHANGE_SHIFT) + 32]; + Bit8u* map; /* allocated dynamically: [(VGA_MEMORY >> VGA_CHANGE_SHIFT) + 32] */ Bit8u checkMask, frame, writeMask; bool active; Bit32u clearMask; @@ -370,6 +369,10 @@ typedef struct { 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 @@ -394,7 +397,7 @@ void VGA_ATTR_SetPalette(Bit8u index,Bit8u val); /* The VGA Subfunction startups */ void VGA_SetupAttr(void); -void VGA_SetupMemory(void); +void VGA_SetupMemory(Section* sec); void VGA_SetupDAC(void); void VGA_SetupCRTC(void); void VGA_SetupMisc(void); @@ -472,6 +475,9 @@ 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]; diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 5a52b026..060ab750 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga.cpp,v 1.32 2008-01-09 20:34:51 c2woody Exp $ */ +/* $Id: vga.cpp,v 1.33 2008-01-12 17:37:48 c2woody Exp $ */ #include "dosbox.h" //#include "setup.h" @@ -170,7 +170,7 @@ void VGA_Init(Section* sec) { vga.draw.resizing=false; vga.mode=M_ERROR; //For first init SVGA_Setup_Driver(); - VGA_SetupMemory(); + VGA_SetupMemory(sec); VGA_SetupMisc(); VGA_SetupDAC(); VGA_SetupGFX(); @@ -249,5 +249,8 @@ void SVGA_Setup_Driver(void) { case SVGA_ParadisePVGA1A: SVGA_Setup_ParadisePVGA1A(); break; + default: + vga.vmemsize = vga.vmemwrap = 256*1024; + break; } } diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index ed9b5de1..28640222 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.91 2008-01-09 20:34:51 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.92 2008-01-12 17:37:48 c2woody Exp $ */ #include #include @@ -150,7 +150,10 @@ static Bit8u * VGA_Draw_Changes_Line(Bitu vidstart, Bitu line) { Bitu end = ((vidstart + vga.draw.line_length ) >> VGA_CHANGE_SHIFT); for (; start <= end;start++) { if ( map[start] & checkMask ) { - Bit8u *ret = &vga.draw.linear_base[ vidstart & vga.draw.linear_mask ]; + Bitu offset = vidstart & vga.draw.linear_mask; + if(vga.draw.linear_mask-offset < vga.draw.line_length) + memcpy(vga.draw.linear_base+vga.draw.linear_mask+1, vga.draw.linear_base, vga.draw.line_length); + Bit8u *ret = &vga.draw.linear_base[ offset ]; #if !defined(C_UNALIGNED_MEMORY) if (GCC_UNLIKELY( ((Bitu)ret) & (sizeof(Bitu)-1)) ) { memcpy( TempLine, ret, vga.draw.line_length ); @@ -168,7 +171,12 @@ static Bit8u * VGA_Draw_Changes_Line(Bitu vidstart, Bitu line) { #endif static Bit8u * VGA_Draw_Linear_Line(Bitu vidstart, Bitu line) { - Bit8u *ret = &vga.draw.linear_base[ vidstart & vga.draw.linear_mask ]; +// There is guaranteed extra memory past the wrap boundary. So, instead of using temporary +// storage just copy appropriate chunk from the beginning to the wrap boundary when needed. + Bitu offset = vidstart & vga.draw.linear_mask; + if (vga.draw.linear_mask-offset < vga.draw.line_length) + memcpy(vga.draw.linear_base+vga.draw.linear_mask+1, vga.draw.linear_base, vga.draw.line_length); + Bit8u *ret = &vga.draw.linear_base[ offset ]; #if !defined(C_UNALIGNED_MEMORY) if (GCC_UNLIKELY( ((Bitu)ret) & (sizeof(Bitu)-1)) ) { memcpy( TempLine, ret, vga.draw.line_length ); @@ -598,7 +606,7 @@ skip_cursor: static void VGA_VerticalDisplayEnd(Bitu val) { // vga.config.retrace=true; - vga.config.real_start=vga.config.display_start & ((VGA_MEMORY)-1); + vga.config.real_start=vga.config.display_start & (vga.vmemwrap-1); } static void VGA_HorizontalTimer(void) { @@ -800,11 +808,11 @@ static void VGA_VerticalTimer(Bitu val) { break; case M_VGA: if(vga.config.compatible_chain4 && (vga.crtc.underline_location & 0x40)) { - vga.draw.linear_base = vga.mem.linear + VGA_CACHE_OFFSET; + vga.draw.linear_base = vga.fastmem; vga.draw.linear_mask = 0xffff; } else { vga.draw.linear_base = vga.mem.linear; - vga.draw.linear_mask = VGA_MEMORY - 1; + vga.draw.linear_mask = vga.vmemwrap - 1; } case M_LIN8: case M_LIN15: @@ -1148,7 +1156,7 @@ void VGA_SetupDrawing(Bitu val) { break; } vga.draw.linear_base = vga.mem.linear; - vga.draw.linear_mask = VGA_MEMORY - 1; + vga.draw.linear_mask = vga.vmemwrap - 1; switch (vga.mode) { case M_VGA: doublewidth=true; @@ -1187,8 +1195,8 @@ void VGA_SetupDrawing(Bitu val) { vga.draw.blocks = width; width<<=3; VGA_DrawLine=VGA_Draw_Linear_Line; - vga.draw.linear_base = vga.mem.linear + VGA_CACHE_OFFSET; - vga.draw.linear_mask = 1024 * 1024 - 1; + vga.draw.linear_base = vga.fastmem; + vga.draw.linear_mask = (vga.vmemwrap<<1) - 1; break; case M_EGA: doublewidth=(vga.seq.clocking_mode & 0x8) > 0; @@ -1199,8 +1207,8 @@ void VGA_SetupDrawing(Bitu val) { VGA_DrawLine = VGA_Draw_Xlat16_Linear_Line; } else VGA_DrawLine=VGA_Draw_Linear_Line; - vga.draw.linear_base = vga.mem.linear + VGA_CACHE_OFFSET; - vga.draw.linear_mask = 512 * 1024 - 1; + vga.draw.linear_base = vga.fastmem; + vga.draw.linear_mask = (vga.vmemwrap<<1) - 1; break; case M_CGA16: doubleheight=true; diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index fd9ab374..9193fd7d 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_memory.cpp,v 1.46 2008-01-09 20:34:51 c2woody Exp $ */ +/* $Id: vga_memory.cpp,v 1.47 2008-01-12 17:37:48 c2woody Exp $ */ #include #include @@ -26,6 +26,27 @@ #include "paging.h" #include "pic.h" #include "inout.h" +#include "setup.h" + + +/* #ifndef C_VGARAM_CHECKED +#define C_VGARAM_CHECKED 1 +#endif */ + +#if C_VGARAM_CHECKED +// Checked linear offset +#define CHECKED(v) ((v)&(vga.vmemwrap-1)) +// Checked planar offset (latched access) +#define CHECKED2(v) ((v)&((vga.vmemwrap>>2)-1)) +// Checked planar offset (latched access) +#else +#define CHECKED(v) (v) +#define CHECKED2(v) (v) +#endif + +#define CHECKED3(v) ((v)&(vga.vmemwrap-1)) +#define CHECKED4(v) ((v)&((vga.vmemwrap>>2)-1)) + #ifdef VGA_KEEP_CHANGES #define MEM_CHANGED( _MEM ) vga.changes.map[ (_MEM) >> VGA_CHANGE_SHIFT ] |= vga.changes.writeMask; @@ -133,11 +154,13 @@ public: Bitu readb(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_read_full; + addr = CHECKED2(addr); return readHandler(addr); } Bitu readw(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_read_full; + addr = CHECKED2(addr); return (readHandler(addr+0) << 0) | (readHandler(addr+1) << 8); @@ -145,6 +168,7 @@ public: Bitu readd(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_read_full; + addr = CHECKED2(addr); return (readHandler(addr+0) << 0) | (readHandler(addr+1) << 8) | @@ -166,7 +190,7 @@ public: start >>= 2; pixels.d=((Bit32u*)vga.mem.linear)[start]; - Bit8u * write_pixels=&vga.mem.linear[VGA_CACHE_OFFSET+(start<<3)]; + Bit8u * write_pixels=&vga.fastmem[start<<3]; Bit32u colors0_3, colors4_7; VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f; @@ -191,12 +215,14 @@ public: void writeb(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_write_full; + addr = CHECKED(addr); MEM_CHANGED( addr << 3); writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_write_full; + addr = CHECKED(addr); MEM_CHANGED( addr << 3); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); @@ -204,6 +230,7 @@ public: void writed(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_write_full; + addr = CHECKED(addr); MEM_CHANGED( addr << 3); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); @@ -213,11 +240,13 @@ public: Bitu readb(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_read_full; + addr = CHECKED(addr); return readHandler(addr); } Bitu readw(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_read_full; + addr = CHECKED(addr); return (readHandler(addr+0) << 0) | (readHandler(addr+1) << 8); @@ -225,6 +254,7 @@ public: Bitu readd(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_read_full; + addr = CHECKED(addr); return (readHandler(addr+0) << 0) | (readHandler(addr+1) << 8) | @@ -244,7 +274,7 @@ public: pixels.d&=vga.config.full_not_map_mask; pixels.d|=(data & vga.config.full_map_mask); ((Bit32u*)vga.mem.linear)[start]=pixels.d; - Bit8u * write_pixels=&vga.mem.linear[VGA_CACHE_OFFSET+(start<<3)]; + Bit8u * write_pixels=&vga.fastmem[start<<3]; Bit32u colors0_3, colors4_7; VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f; @@ -261,10 +291,6 @@ public: Expand16Table[2][temp.b[2]] | Expand16Table[3][temp.b[3]]; *(Bit32u *)(write_pixels+4)=colors4_7; - if (wrapping && GCC_UNLIKELY( start < 512)) { - *(Bit32u *)(write_pixels+512*1024)=colors0_3; - *(Bit32u *)(write_pixels+512*1024+4)=colors4_7; - } } public: VGA_UnchainedEGA_Handler() { @@ -273,12 +299,14 @@ public: void writeb(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_write_full; + addr = CHECKED2(addr); MEM_CHANGED( addr << 3); writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_write_full; + addr = CHECKED2(addr); MEM_CHANGED( addr << 3); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); @@ -286,6 +314,7 @@ public: void writed(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_write_full; + addr = CHECKED2(addr); MEM_CHANGED( addr << 3); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); @@ -306,10 +335,10 @@ public: } template static INLINE void writeCache(PhysPt addr, Bitu val) { - hostWrite( &vga.mem.linear[VGA_CACHE_OFFSET+addr], val ); + hostWrite( &vga.fastmem[addr], val ); if (GCC_UNLIKELY(addr < 320)) { // And replicate the first line - hostWrite( &vga.mem.linear[VGA_CACHE_OFFSET+addr+64*1024], val ); + hostWrite( &vga.fastmem[addr+64*1024], val ); } } template @@ -320,11 +349,13 @@ public: Bitu readb(PhysPt addr ) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_read_full; + addr = CHECKED(addr); return readHandler( addr ); } Bitu readw(PhysPt addr ) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_read_full; + addr = CHECKED(addr); if (GCC_UNLIKELY(addr & 1)) return (readHandler( addr+0 ) << 0 ) | @@ -335,6 +366,7 @@ public: Bitu readd(PhysPt addr ) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_read_full; + addr = CHECKED(addr); if (GCC_UNLIKELY(addr & 3)) return (readHandler( addr+0 ) << 0 ) | @@ -347,6 +379,7 @@ public: void writeb(PhysPt addr, Bitu val ) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_write_full; + addr = CHECKED(addr); MEM_CHANGED( addr ); writeHandler( addr, val ); writeCache( addr, val ); @@ -354,6 +387,7 @@ public: void writew(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_write_full; + addr = CHECKED(addr); MEM_CHANGED( addr ); // MEM_CHANGED( addr + 1); if (GCC_UNLIKELY(addr & 1)) { @@ -367,6 +401,7 @@ public: void writed(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_write_full; + addr = CHECKED(addr); MEM_CHANGED( addr ); // MEM_CHANGED( addr + 3); if (GCC_UNLIKELY(addr & 3)) { @@ -391,7 +426,7 @@ public: pixels.d|=(data & vga.config.full_map_mask); ((Bit32u*)vga.mem.linear)[addr]=pixels.d; if(vga.config.compatible_chain4) - ((Bit32u*)vga.mem.linear)[addr+64*1024]=pixels.d; + ((Bit32u*)vga.mem.linear)[CHECKED2(addr+64*1024)]=pixels.d; } public: VGA_UnchainedVGA_Handler() { @@ -400,12 +435,14 @@ public: void writeb(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_write_full; + addr = CHECKED2(addr); MEM_CHANGED( addr << 2 ); writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_write_full; + addr = CHECKED2(addr); MEM_CHANGED( addr << 2); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); @@ -413,6 +450,7 @@ public: void writed(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_write_full; + addr = CHECKED2(addr); MEM_CHANGED( addr << 2); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); @@ -445,11 +483,11 @@ public: } HostPt GetHostReadPt(Bitu phys_page) { phys_page-=vgapages.base; - return &vga.mem.linear[vga.svga.bank_read_full+phys_page*4096]; + return &vga.mem.linear[CHECKED3(vga.svga.bank_read_full+phys_page*4096)]; } HostPt GetHostWritePt(Bitu phys_page) { phys_page-=vgapages.base; - return &vga.mem.linear[vga.svga.bank_write_full+phys_page*4096]; + return &vga.mem.linear[CHECKED3(vga.svga.bank_write_full+phys_page*4096)]; } }; @@ -461,33 +499,39 @@ public: Bitu readb(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_read_full; + addr = CHECKED(addr); return hostRead( &vga.mem.linear[addr] ); } Bitu readw(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_read_full; + addr = CHECKED(addr); return hostRead( &vga.mem.linear[addr] ); } Bitu readd(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_read_full; + addr = CHECKED(addr); return hostRead( &vga.mem.linear[addr] ); } void writeb(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_write_full; + addr = CHECKED(addr); MEM_CHANGED( addr ); hostWrite( &vga.mem.linear[addr], val ); } void writew(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_write_full; + addr = CHECKED(addr); MEM_CHANGED( addr ); hostWrite( &vga.mem.linear[addr], val ); } void writed(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) & 0xffff; addr += vga.svga.bank_write_full; + addr = CHECKED(addr); MEM_CHANGED( addr ); hostWrite( &vga.mem.linear[addr], val ); } @@ -500,20 +544,20 @@ public: } void writeb(PhysPt addr,Bitu val) { addr = vga.svga.bank_write_full + (PAGING_GetPhysicalAddress(addr) & 0xffff); - addr &= (128*1024-1); + addr = CHECKED4(addr); MEM_CHANGED( addr << 3 ); writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { addr = vga.svga.bank_write_full + (PAGING_GetPhysicalAddress(addr) & 0xffff); - addr &= (128*1024-1); + addr = CHECKED4(addr); MEM_CHANGED( addr << 3 ); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { addr = vga.svga.bank_write_full + (PAGING_GetPhysicalAddress(addr) & 0xffff); - addr &= (128*1024-1); + addr = CHECKED4(addr); MEM_CHANGED( addr << 3 ); writeHandler(addr+0,(Bit8u)(val >> 0)); writeHandler(addr+1,(Bit8u)(val >> 8)); @@ -522,19 +566,19 @@ public: } Bitu readb(PhysPt addr) { addr = vga.svga.bank_read_full + (PAGING_GetPhysicalAddress(addr) & 0xffff); - addr &= (128*1024-1); + addr = CHECKED4(addr); return readHandler(addr); } Bitu readw(PhysPt addr) { addr = vga.svga.bank_read_full + (PAGING_GetPhysicalAddress(addr) & 0xffff); - addr &= (128*1024-1); + addr = CHECKED4(addr); return (readHandler(addr+0) << 0) | (readHandler(addr+1) << 8); } Bitu readd(PhysPt addr) { addr = vga.svga.bank_read_full + (PAGING_GetPhysicalAddress(addr) & 0xffff); - addr &= (128*1024-1); + addr = CHECKED4(addr); return (readHandler(addr+0) << 0) | (readHandler(addr+1) << 8) | @@ -551,28 +595,34 @@ public: } Bitu readb(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + addr = CHECKED(addr); return hostRead( &vga.mem.linear[addr] ); } Bitu readw(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + addr = CHECKED(addr); return hostRead( &vga.mem.linear[addr] ); } Bitu readd(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + addr = CHECKED(addr); return hostRead( &vga.mem.linear[addr] ); } void writeb(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + addr = CHECKED(addr); hostWrite( &vga.mem.linear[addr], val ); MEM_CHANGED( addr ); } void writew(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + addr = CHECKED(addr); hostWrite( &vga.mem.linear[addr], val ); MEM_CHANGED( addr ); } void writed(PhysPt addr,Bitu val) { addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr; + addr = CHECKED(addr); hostWrite( &vga.mem.linear[addr], val ); MEM_CHANGED( addr ); } @@ -585,7 +635,7 @@ public: } HostPt GetHostReadPt( Bitu phys_page ) { phys_page -= vga.lfb.page; - return &vga.mem.linear[phys_page * 4096]; + return &vga.mem.linear[CHECKED3(phys_page * 4096)]; } HostPt GetHostWritePt( Bitu phys_page ) { return GetHostReadPt( phys_page ); @@ -838,21 +888,45 @@ void VGA_StartUpdateLFB(void) { #else vga.lfb.handler = &vgaph.lfbchanges; #endif - MEM_SetLFB(vga.s3.la_window << 4 ,VGA_MEMORY/4096, vga.lfb.handler, &vgaph.mmio); + MEM_SetLFB(vga.s3.la_window << 4 ,vga.vmemsize/4096, vga.lfb.handler, &vgaph.mmio); } -void VGA_SetupMemory() { - // allocate 16byte-aligned memory - vga.mem.linear = new Bit8u[VGA_MEMORY+16]; - vga.mem.linear=(Bit8u*)(((Bitu)vga.mem.linear + 16-1) & ~(16-1)); - memset( vga.mem.linear, 0, VGA_MEMORY ); +static void VGA_Memory_ShutDown(Section * sec) { + delete[] vga.mem.linear_orgptr; + delete[] vga.fastmem_orgptr; +#ifdef VGA_KEEP_CHANGES + delete[] vga.changes.map; +#endif +} + +void VGA_SetupMemory(Section* sec) { + vga.svga.bank_read = vga.svga.bank_write = 0; + vga.svga.bank_read_full = vga.svga.bank_write_full = 0; + + // We reserve extra 2K for one scan line + vga.mem.linear_orgptr = new Bit8u[vga.vmemsize+2048+16]; + vga.mem.linear=(Bit8u*)(((Bitu)vga.mem.linear_orgptr + 16-1) & ~(16-1)); + memset(vga.mem.linear,0,vga.vmemsize); + + vga.fastmem_orgptr = new Bit8u[(vga.vmemsize<<1)+4096+16]; + vga.fastmem=(Bit8u*)(((Bitu)vga.fastmem_orgptr + 16-1) & ~(16-1)); + + // In most cases these values stay the same. Assumptions: vmemwrap is power of 2, + // vmemwrap <= vmemsize, fastmem implicitly has mem wrap twice as big + vga.vmemwrap = vga.vmemsize; + #ifdef VGA_KEEP_CHANGES memset( &vga.changes, 0, sizeof( vga.changes )); + int changesMapSize = (vga.vmemsize >> VGA_CHANGE_SHIFT) + 32; + vga.changes.map = new Bit8u[changesMapSize]; + memset(vga.changes.map, 0, changesMapSize); #endif vga.svga.bank_read = vga.svga.bank_write = 0; vga.svga.bank_read_full = vga.svga.bank_write_full = 0; vga.svga.bank_size = 0x10000; /* most common bank size is 64K */ + sec->AddDestroyFunction(&VGA_Memory_ShutDown); + if (machine==MCH_PCJR) { /* PCJr does not have dedicated graphics memory but uses conventional memory below 128k */ diff --git a/src/hardware/vga_paradise.cpp b/src/hardware/vga_paradise.cpp index 8a10c76e..6ce124f3 100644 --- a/src/hardware/vga_paradise.cpp +++ b/src/hardware/vga_paradise.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_paradise.cpp,v 1.1 2008-01-09 20:34:51 c2woody Exp $ */ +/* $Id: vga_paradise.cpp,v 1.2 2008-01-12 17:37:48 c2woody Exp $ */ #include "dosbox.h" #include "setup.h" @@ -162,10 +162,13 @@ void FinishSetMode_PVGA1A(Bitu /*crtc_base*/, VGA_ModeExtraData* modeData) { if (svga.determine_mode) svga.determine_mode(); - if (vga.mode != M_VGA) - vga.config.compatible_chain4 = false; // in process of verification - else + if(vga.mode != M_VGA) { + vga.config.compatible_chain4 = false; + vga.vmemwrap = vga.vmemsize; + } else { vga.config.compatible_chain4 = true; + vga.vmemwrap = 256*1024; + } VGA_SetupHandlers(); } @@ -195,6 +198,10 @@ Bitu GetClock_PVGA1A() { return pvga1a.clockFreq[(vga.misc_output >> 2) & 3]; } +bool AcceptsMode_PVGA1A(Bitu mode) { + return VideoModeMemSize(mode) < vga.vmemsize; +} + void SVGA_Setup_ParadisePVGA1A(void) { svga.write_p3cf = &write_p3cf_pvga1a; svga.read_p3cf = &read_p3cf_pvga1a; @@ -203,14 +210,26 @@ void SVGA_Setup_ParadisePVGA1A(void) { svga.determine_mode = &DetermineMode_PVGA1A; svga.set_clock = &SetClock_PVGA1A; svga.get_clock = &GetClock_PVGA1A; + svga.accepts_mode = &AcceptsMode_PVGA1A; VGA_SetClock(0,CLK_25); VGA_SetClock(1,CLK_28); VGA_SetClock(2,32400); // could not find documentation VGA_SetClock(3,35900); - // Set memory size at 512K (standard for PVGA1A) - pvga1a.PR1 = 2<<6; + // Adjust memory, default to 512K + if (vga.vmemsize == 0) + vga.vmemsize = 512*1024; + + if (vga.vmemsize < 512*1024) { + vga.vmemsize = 256*1024; + pvga1a.PR1 = 1<<6; + } else if (vga.vmemsize > 512*1024) { + vga.vmemsize = 1024*1024; + pvga1a.PR1 = 3<<6; + } else { + pvga1a.PR1 = 2<<6; + } // Paradise ROM signature PhysPt rom_base=PhysMake(0xc000,0); diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index 2f5484e6..a927ced5 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_s3.cpp,v 1.11 2008-01-09 20:34:51 c2woody Exp $ */ +/* $Id: vga_s3.cpp,v 1.12 2008-01-12 17:37:48 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -28,6 +28,8 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { //TODO Base address vga.s3.reg_31 = val; vga.config.compatible_chain4 = !(val&0x08); + if (vga.config.compatible_chain4) vga.vmemwrap = 256*1024; + else vga.vmemwrap = vga.vmemsize; vga.config.display_start = (vga.config.display_start&~0x30000)|((val&0x30)<<12); VGA_DetermineMode(); VGA_SetupHandlers(); @@ -312,7 +314,7 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { } break; case 0x6a: /* Extended System Control 4 */ - vga.svga.bank_read=val & 0x3f; + vga.svga.bank_read=val & 0x7f; vga.svga.bank_write = vga.svga.bank_read; VGA_SetupHandlers(); break; @@ -345,8 +347,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { case 0x35: /* CR35 CRT Register Lock */ return vga.s3.reg_35|(vga.svga.bank_read & 0xf); case 0x36: /* CR36 Reset State Read 1 */ - return 0x92; /* PCI version */ - //2 Mb PCI and some bios settings + return vga.s3.reg_36; case 0x37: /* Reset state read 2 */ return 0x2b; case 0x38: /* CR38 Register Lock 1 */ @@ -403,7 +404,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { case 0x69: /* Extended System Control 3 */ return (Bit8u)((vga.config.display_start & 0x1f0000)>>16); case 0x6a: /* Extended System Control 4 */ - return (Bit8u)(vga.svga.bank_read & 0x3f); + return (Bit8u)(vga.svga.bank_read & 0x7f); case 0x6b: // BIOS scatchpad: LFB address return vga.s3.reg_6b; default: @@ -483,6 +484,10 @@ bool SVGA_S3_HWCursorActive(void) { return (vga.s3.hgc.curmode & 0x1) != 0; } +bool SVGA_S3_AcceptsMode(Bitu mode) { + return VideoModeMemSize(mode) < vga.vmemsize; +} + void SVGA_Setup_S3Trio(void) { svga.write_p3d5 = &SVGA_S3_WriteCRTC; svga.read_p3d5 = &SVGA_S3_ReadCRTC; @@ -496,5 +501,26 @@ void SVGA_Setup_S3Trio(void) { svga.set_clock = 0; /* implemented in core */ svga.get_clock = &SVGA_S3_GetClock; svga.hardware_cursor_active = &SVGA_S3_HWCursorActive; - svga.accepts_mode = 0; /* don't filter modes */ + svga.accepts_mode = &SVGA_S3_AcceptsMode; + + if (vga.vmemsize == 0) + vga.vmemsize = VGA_MEMORY; // the most common S3 configuration + + // Set CRTC 36 to specify amount of VRAM and PCI + if (vga.vmemsize < 1024*1024) { + vga.vmemsize = 512*1024; + vga.s3.reg_36 = 0xf2; + } else if (vga.vmemsize < 2048*1024) { + vga.vmemsize = 1024*1024; + vga.s3.reg_36 = 0xd2; + } else if (vga.vmemsize < 3072*1024) { + vga.vmemsize = 2048*1024; + vga.s3.reg_36 = 0x92; + } else if (vga.vmemsize < 4096*1024) { + vga.vmemsize = 3072*1024; + vga.s3.reg_36 = 0x52; + } else { // Trio64 supported only up to 4M + vga.vmemsize = 4096*1024; + vga.s3.reg_36 = 0x12; + } } diff --git a/src/hardware/vga_tseng.cpp b/src/hardware/vga_tseng.cpp index 3dadc70f..3e86ee51 100644 --- a/src/hardware/vga_tseng.cpp +++ b/src/hardware/vga_tseng.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_tseng.cpp,v 1.1 2008-01-09 20:34:51 c2woody Exp $ */ +/* $Id: vga_tseng.cpp,v 1.2 2008-01-12 17:37:48 c2woody Exp $ */ #include "dosbox.h" #include "setup.h" @@ -147,6 +147,7 @@ void write_p3d5_et4k(Bitu reg,Bitu val,Bitu iolen) { case 0x37: if (val != et4k.store_3d4_37) { et4k.store_3d4_37 = val; + vga.vmemwrap = ((64*1024)<<((val&8)>>2))<<((val&3)-1); VGA_SetupHandlers(); } break; @@ -340,7 +341,7 @@ void FinishSetMode_ET4K(Bitu crtc_base, VGA_ModeExtraData* modeData) { IO_Write(crtc_base,0x33);IO_Write(crtc_base+1,0); IO_Write(crtc_base,0x34);IO_Write(crtc_base+1,0); IO_Write(crtc_base,0x36);IO_Write(crtc_base+1,0); - IO_Write(crtc_base,0x37);IO_Write(crtc_base+1,0x0f); // 1M video ram (0x0e for 512K, 0x0d for 256K) + IO_Write(crtc_base,0x37);IO_Write(crtc_base+1,0x0c|(vga.vmemsize==1024*1024?3:vga.vmemsize==512*1024?2:1)); // Clear ext SEQ IO_Write(0x3c4,0x06);IO_Write(0x3c5,0); IO_Write(0x3c4,0x07);IO_Write(0x3c5,0); @@ -368,6 +369,7 @@ void FinishSetMode_ET4K(Bitu crtc_base, VGA_ModeExtraData* modeData) { // Verified (on real hardware and in a few games): Tseng ET4000 used chain4 implementation // different from standard VGA. It was also not limited to 64K in regular mode 13h. vga.config.compatible_chain4 = false; + vga.vmemwrap = vga.vmemsize; VGA_SetupHandlers(); } @@ -396,7 +398,8 @@ Bitu GetClock_ET4K() { } bool AcceptsMode_ET4K(Bitu mode) { - return mode != 0x3d; + return VideoModeMemSize(mode) < vga.vmemsize; +// return mode != 0x3d; } void SVGA_Setup_TsengET4K(void) { @@ -434,6 +437,17 @@ void SVGA_Setup_TsengET4K(void) { IO_RegisterReadHandler(0x3cd,read_p3cd_et4k,IO_MB); IO_RegisterWriteHandler(0x3cd,write_p3cd_et4k,IO_MB); + // Default to 1M of VRAM + if (vga.vmemsize == 0) + vga.vmemsize = 1024*1024; + + if (vga.vmemsize < 512*1024) + vga.vmemsize = 256*1024; + else if (vga.vmemsize < 1024*1024) + vga.vmemsize = 512*1024; + else + vga.vmemsize = 1024*1024; + // Tseng ROM signature PhysPt rom_base=PhysMake(0xc000,0); phys_writeb(rom_base+0x0075,' '); @@ -716,6 +730,7 @@ void FinishSetMode_ET3K(Bitu crtc_base, VGA_ModeExtraData* modeData) { // Verified on functioning (at last!) hardware: Tseng ET3000 is the same as ET4000 when // it comes to chain4 architecture vga.config.compatible_chain4 = false; + vga.vmemwrap = vga.vmemsize; VGA_SetupHandlers(); } @@ -744,7 +759,7 @@ Bitu GetClock_ET3K() { } bool AcceptsMode_ET3K(Bitu mode) { - return mode <= 0x37 && mode != 0x2f; + return mode <= 0x37 && mode != 0x2f && VideoModeMemSize(mode) < vga.vmemsize; } void SVGA_Setup_TsengET3K(void) { @@ -773,6 +788,8 @@ void SVGA_Setup_TsengET3K(void) { IO_RegisterReadHandler(0x3cd,read_p3cd_et3k,IO_MB); IO_RegisterWriteHandler(0x3cd,write_p3cd_et3k,IO_MB); + vga.vmemsize = 512*1024; // Cannot figure how this was supposed to work on the real card + // Tseng ROM signature PhysPt rom_base=PhysMake(0xc000,0); phys_writeb(rom_base+0x0075,' '); diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index d92d6413..1b11b7e0 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_xga.cpp,v 1.11 2008-01-10 20:36:03 c2woody Exp $ */ +/* $Id: vga_xga.cpp,v 1.12 2008-01-12 17:37:48 c2woody Exp $ */ #include #include "dosbox.h" @@ -152,7 +152,7 @@ void XGA_DrawPoint(Bitu x, Bitu y, Bitu c) { Bitu XGA_GetPoint(Bitu x, Bitu y) { Bit32u memaddr = (y * XGA_SCREEN_WIDTH) + x; - if(VGA_MEMORY < memaddr) { + if(vga.vmemsize < memaddr) { //LOG_MSG("getpoint mem over: x%d y%d",x,y); return 0; } diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index a3b3cb92..41210be8 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.74 2008-01-09 20:34:51 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.75 2008-01-12 17:37:48 c2woody Exp $ */ #include @@ -368,7 +368,8 @@ static void FinishSetMode(bool clearmem) { case M_LIN16: case M_LIN32: /* Hack we just acess the memory directly */ - memset(vga.mem.linear,0,VGA_MEMORY); + memset(vga.mem.linear,0,vga.vmemsize); + memset(vga.fastmem, 0, vga.vmemsize<<1); } } /* Setup the BIOS */ @@ -1270,3 +1271,50 @@ dac_text16: } return true; } + +Bitu VideoModeMemSize(Bitu mode) { + if (!IS_VGA_ARCH) + return 0; + + VideoModeBlock* modelist = NULL; + + switch (svgaCard) { + case SVGA_TsengET4K: + case SVGA_TsengET3K: + modelist = ModeList_VGA_Tseng; + break; + case SVGA_ParadisePVGA1A: + modelist = ModeList_VGA_Paradise; + break; + default: + modelist = ModeList_VGA; + break; + } + + VideoModeBlock* vmodeBlock = NULL; + Bitu i=0; + while (modelist[i].mode!=0xffff) { + if (modelist[i].mode==mode) { + vmodeBlock = &modelist[i]; + break; + } + i++; + } + if (!vmodeBlock) + return 0; + + switch(vmodeBlock->type) { + case M_LIN4: + return vmodeBlock->swidth*vmodeBlock->sheight/2; + case M_LIN8: + return vmodeBlock->swidth*vmodeBlock->sheight; + case M_LIN15: case M_LIN16: + return vmodeBlock->swidth*vmodeBlock->sheight*2; + case M_LIN32: + return vmodeBlock->swidth*vmodeBlock->sheight*4; + case M_TEXT: + return vmodeBlock->twidth*vmodeBlock->theight*2; + } + // Return 0 for all other types, those always fit in memory + return 0; +} diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 0aaf6c06..08d035ce 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.30 2007-12-10 22:11:13 c2woody Exp $ */ +/* $Id: int10_vesa.cpp,v 1.31 2008-01-12 17:37:48 c2woody Exp $ */ #include #include @@ -115,7 +115,7 @@ Bit8u VESA_GetSVGAInformation(Bit16u seg,Bit16u off) { } mem_writed(buffer+0x0a,0x0); //Capabilities and flags mem_writed(buffer+0x0e,int10.rom.vesa_modes); //VESA Mode list - mem_writew(buffer+0x12,Bit16u(VGA_MEMORY/(64*1024))); // memory size in 64kb blocks + mem_writew(buffer+0x12,(Bit16u)(vga.vmemsize/(64*1024))); // memory size in 64kb blocks return 0x00; } @@ -129,6 +129,9 @@ Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off) { mode&=0x3fff; // vbe2 compatible, ignore lfb and keep screen content bits if (mode<0x100) return 0x01; + if (svga.accepts_mode) { + if (!svga.accepts_mode(mode)) return 0x01; + } while (ModeList_VGA[i].mode!=0xffff) { if (mode==ModeList_VGA[i].mode) goto foundit; else i++; } @@ -145,12 +148,12 @@ foundit: var_write(&minfo.MemoryModel,3); //ega planar mode modeAttributes = 0x1b; // Color, graphics, no linear buffer - if(pageSize > 512*1024) { // this limitation is not on the real card + if(pageSize > vga.vmemsize/4) { // this limitation is not on the real card var_write(&minfo.ModeAttributes, modeAttributes & ~0x1); var_write(&minfo.NumberOfImagePages,0); } else { var_write(&minfo.ModeAttributes, modeAttributes); - Bitu pages = (512*1024 / pageSize)-1; + Bitu pages = ((vga.vmemsize/4) / pageSize)-1; var_write(&minfo.NumberOfImagePages,pages); } break; @@ -227,13 +230,13 @@ foundit: var_write(&minfo.WinAAttributes,0x7); // Exists/readable/writable if(mblock->type != M_LIN4) - if(pageSize > VGA_MEMORY) { + if(pageSize > vga.vmemsize) { // Mode not supported by current hardware configuration var_write(&minfo.ModeAttributes, modeAttributes & ~0x1); var_write(&minfo.NumberOfImagePages,0); } else { var_write(&minfo.ModeAttributes, modeAttributes); - Bitu pages = (VGA_MEMORY / pageSize)-1; + Bitu pages = (vga.vmemsize / pageSize)-1; var_write(&minfo.NumberOfImagePages,pages); } @@ -274,7 +277,7 @@ Bit8u VESA_GetSVGAMode(Bit16u & mode) { Bit8u VESA_SetCPUWindow(Bit8u window,Bit8u address) { if (window) return 0x1; - if ((address<32)) { + if (((Bit32u)(address)*64*1024type==M_LIN4) { pixels=(vga.config.scan_len*16)/bpp; bytes=vga.config.scan_len*2; - lines = Bit16u(VGA_MEMORY /( bytes*4)); + lines = (Bit16u)(vga.vmemsize /( bytes*4)); } else { pixels=(vga.config.scan_len*8)/bpp; bytes=vga.config.scan_len*8; - lines = Bit16u(VGA_MEMORY / bytes); + lines = (Bit16u)(vga.vmemsize / bytes); } VGA_StartResize(); return 0x0; @@ -465,7 +468,12 @@ void INT10_SetupVESA(void) { int10.rom.vesa_modes=RealMake(0xc000,int10.rom.used); //TODO Maybe add normal vga modes too, but only seems to complicate things while (ModeList_VGA[i].mode!=0xffff) { - if (ModeList_VGA[i].mode>=0x100){ + bool canuse_mode=false; + if (!svga.accepts_mode) canuse_mode=true; + else { + if (svga.accepts_mode(ModeList_VGA[i].mode)) canuse_mode=true; + } + if (ModeList_VGA[i].mode>=0x100 && canuse_mode) { phys_writew(PhysMake(0xc000,int10.rom.used),ModeList_VGA[i].mode); int10.rom.used+=2; } From bd88bcea69549a245e85451633710fae505a24a4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 13 Jan 2008 11:28:41 +0000 Subject: [PATCH 2990/4131] Add low- and uppercase for std::string. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3078 --- include/support.h | 9 +++++---- src/misc/support.cpp | 18 +++++++++++++++++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/include/support.h b/include/support.h index 2b7e66ea..5933de19 100644 --- a/include/support.h +++ b/include/support.h @@ -16,10 +16,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: support.h,v 1.16 2008-01-13 11:28:41 qbix79 Exp $ */ + #ifndef DOSBOX_SUPPORT_H #define DOSBOX_SUPPORT_H #include +#include #include #ifndef DOSBOX_DOSBOX_H #include "dosbox.h" @@ -28,10 +31,6 @@ #if defined (_MSC_VER) /* MS Visual C++ */ #define strcasecmp(a,b) stricmp(a,b) #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 #define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) @@ -63,5 +62,7 @@ INLINE char * lowcase(char * str) { return str; } +void upcase(std::string &str); +void lowcase(std::string &str); #endif diff --git a/src/misc/support.cpp b/src/misc/support.cpp index f51ad77b..070235e6 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.33 2007-10-31 11:45:14 qbix79 Exp $ */ +/* $Id: support.cpp,v 1.34 2008-01-13 11:28:41 qbix79 Exp $ */ #include #include @@ -25,11 +25,27 @@ #include #include #include +#include +#include +#include + #include "dosbox.h" #include "debug.h" #include "support.h" #include "video.h" + +void upcase(std::string &str) { + int (*tf)(int) = std::toupper; + std::transform(str.begin(), str.end(), str.begin(), tf); +} + +void lowcase(std::string &str) { + int (*tf)(int) = std::tolower; + std::transform(str.begin(), str.end(), str.begin(), tf); +} + + /* Ripped some source from freedos for this one. From 4cb280c42a325e19a54531055cd14d7b3a4ce7b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 15 Jan 2008 17:46:25 +0000 Subject: [PATCH 2991/4131] vesa pmode set window ignores the window parameter (complies with univbe) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3079 --- src/ints/int10_vesa.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 08d035ce..09a60234 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.31 2008-01-12 17:37:48 c2woody Exp $ */ +/* $Id: int10_vesa.cpp,v 1.32 2008-01-15 17:46:25 c2woody Exp $ */ #include #include @@ -445,7 +445,7 @@ static Bitu VESA_SetWindow(void) { } static Bitu VESA_PMSetWindow(void) { - VESA_SetCPUWindow(reg_bl,(Bit8u)reg_dx); + VESA_SetCPUWindow(0,(Bit8u)reg_dx); return 0; } static Bitu VESA_PMSetPalette(void) { From ae447b6477355ef792f26d4b3dd77111cabbbb64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 16 Jan 2008 20:17:15 +0000 Subject: [PATCH 2992/4131] prevent auto cycle adjusting to lower the cycles too much on heavy background load Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3080 --- include/cpu.h | 10 ++++++++++ src/cpu/cpu.cpp | 33 +++++++++++++++++++++++++++++---- src/dosbox.cpp | 43 +++++++++++++++++++++++++++++-------------- src/gui/sdlmain.cpp | 8 ++++++-- 4 files changed, 74 insertions(+), 20 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 9f0639fc..06d03589 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: cpu.h,v 1.52 2008-01-16 20:16:31 c2woody Exp $ */ + #ifndef DOSBOX_CPU_H #define DOSBOX_CPU_H @@ -36,6 +38,8 @@ #define CPU_AUTODETERMINE_SHIFT 0x02 #define CPU_AUTODETERMINE_MASK 0x03 +#define CPU_CYCLES_LOWER_LIMIT 100 + /* CPU Cycle Timing */ extern Bit32s CPU_Cycles; extern Bit32s CPU_CycleLeft; @@ -45,6 +49,7 @@ extern Bit32s CPU_CyclePercUsed; extern Bit32s CPU_CycleLimit; extern Bit64s CPU_IODelayRemoved; extern bool CPU_CycleAutoAdjust; +extern bool CPU_SkipCycleAutoAdjust; extern Bitu CPU_AutoDetermineMode; /* Some common Defines */ @@ -61,6 +66,11 @@ Bits CPU_Core_Dyn_X86_Trap_Run(void); Bits CPU_Core_Dynrec_Run(void); Bits CPU_Core_Dynrec_Trap_Run(void); +void CPU_Enable_SkipAutoAdjust(void); +void CPU_Disable_SkipAutoAdjust(void); +void CPU_Reset_AutoAdjust(void); + + //CPU Stuff extern Bit16u parity_lookup[256]; diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index b7441482..cb452b91 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.106 2007-12-07 20:49:19 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.107 2008-01-16 20:17:15 c2woody Exp $ */ #include #include @@ -57,8 +57,9 @@ Bit32s CPU_CycleUp = 0; Bit32s CPU_CycleDown = 0; Bit64s CPU_IODelayRemoved = 0; CPU_Decoder * cpudecoder; -bool CPU_CycleAutoAdjust; -Bitu CPU_AutoDetermineMode; +bool CPU_CycleAutoAdjust = false; +bool CPU_SkipCycleAutoAdjust = false; +Bitu CPU_AutoDetermineMode = 0; void CPU_Core_Full_Init(void); void CPU_Core_Normal_Init(void); @@ -2074,6 +2075,29 @@ static void CPU_CycleDecrease(bool pressed) { } } +void CPU_Enable_SkipAutoAdjust(void) { + if (CPU_CycleAutoAdjust) { + CPU_CycleMax /= 2; + if (CPU_CycleMax < CPU_CYCLES_LOWER_LIMIT) + CPU_CycleMax = CPU_CYCLES_LOWER_LIMIT; + } + CPU_SkipCycleAutoAdjust=true; +} + +void CPU_Disable_SkipAutoAdjust(void) { + CPU_SkipCycleAutoAdjust=false; +} + + +extern Bit32s ticksDone; +extern Bit32u ticksScheduled; + +void CPU_Reset_AutoAdjust(void) { + CPU_IODelayRemoved = 0; + ticksDone = 0; + ticksScheduled = 0; +} + class CPU: public Module_base { private: static bool inited; @@ -2138,6 +2162,7 @@ public: CPU_AutoDetermineMode=CPU_AUTODETERMINE_NONE; CPU_CycleLeft=0;//needed ? CPU_Cycles=0; + CPU_SkipCycleAutoAdjust=false; std::string str; CommandLine cmd(0,section->Get_string("cycles")); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 3c5cd29c..7a8b3698 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.125 2008-01-09 20:34:21 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.126 2008-01-16 20:16:31 c2woody Exp $ */ #include #include @@ -117,8 +117,8 @@ bool SDLNetInited; static Bit32u ticksRemain; static Bit32u ticksLast; static Bit32u ticksAdded; -static Bit32s ticksDone; -static Bit32u ticksScheduled; +Bit32s ticksDone; +Bit32u ticksScheduled; bool ticksLocked; static Bitu Normal_Loop(void) { @@ -162,15 +162,17 @@ increaseticks: ticksRemain = 20; } ticksAdded = ticksRemain; - if (CPU_CycleAutoAdjust) { - if(ticksScheduled >= 250 || ticksDone >= 250 || (ticksAdded > 15 && ticksScheduled >= 5) ) { + if (CPU_CycleAutoAdjust && !CPU_SkipCycleAutoAdjust) { + if (ticksScheduled >= 250 || ticksDone >= 250 || (ticksAdded > 15 && ticksScheduled >= 5) ) { /* ratio we are aiming for is around 90% usage*/ Bits ratio = (ticksScheduled * (CPU_CyclePercUsed*90*1024/100/100)) / ticksDone; Bit32s new_cmax = CPU_CycleMax; Bit64s cproc = (Bit64s)CPU_CycleMax * (Bit64s)ticksScheduled; - if(cproc > 0) { + if (cproc > 0) { + /* ignore the cycles added due to the io delay code in order + to have smoother auto cycle adjustments */ double ratioremoved = (double) CPU_IODelayRemoved / (double) cproc; - if(ratioremoved < 1.0) { + if (ratioremoved < 1.0) { ratio = (Bits)((double)ratio * (1 - ratioremoved)); if (ratio <= 1024) new_cmax = (CPU_CycleMax * ratio) / 1024; @@ -179,19 +181,32 @@ increaseticks: } } - // maybe care about not going negative - if (new_cmax > 0) - CPU_CycleMax = new_cmax; - if (CPU_CycleLimit > 0) { - if (CPU_CycleMax>CPU_CycleLimit) CPU_CycleMax = CPU_CycleLimit; + if (new_cmax10) { + /* ratios below 12% along with a large time since the last update + has taken place are most likely caused by heavy load through a + different application, the cycles adjusting is skipped as well */ + if ((ratio>120) || (ticksDone<700)) { + CPU_CycleMax = new_cmax; + if (CPU_CycleLimit > 0) { + if (CPU_CycleMax>CPU_CycleLimit) CPU_CycleMax = CPU_CycleLimit; + } + } } CPU_IODelayRemoved = 0; ticksDone = 0; ticksScheduled = 0; } else if (ticksAdded > 15) { + /* ticksAdded > 15 but ticksScheduled < 5, lower the cycles + but do not reset the scheduled/done ticks to take them into + account during the next auto cycle adjustment */ CPU_CycleMax /= 3; - if (CPU_CycleMax < 100) - CPU_CycleMax = 100; + if (CPU_CycleMax < CPU_CYCLES_LOWER_LIMIT) + CPU_CycleMax = CPU_CYCLES_LOWER_LIMIT; } } } else { diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 9d15234b..64c5ddaa 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.137 2007-12-12 13:37:38 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.138 2008-01-16 20:17:15 c2woody Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -45,6 +45,7 @@ #include "mapper.h" #include "vga.h" #include "keyboard.h" +#include "cpu.h" //#define DISABLE_JOYSTICK @@ -309,6 +310,7 @@ void GFX_ResetScreen(void) { if (sdl.draw.callback) (sdl.draw.callback)( GFX_CallBackReset ); GFX_Start(); + CPU_Reset_AutoAdjust(); } static int int_log2 (int val) { @@ -1198,6 +1200,7 @@ void GFX_Events() { if (sdl.desktop.fullscreen && !sdl.mouse.locked) GFX_CaptureMouse(); SetPriority(sdl.priority.focus); + CPU_Disable_SkipAutoAdjust(); } else { if (sdl.mouse.locked) { #ifdef WIN32 @@ -1211,6 +1214,7 @@ void GFX_Events() { } SetPriority(sdl.priority.nofocus); MAPPER_LosingFocus(); + CPU_Enable_SkipAutoAdjust(); } } From 41a5d9d3d6fcdf3b846dacbd59c12697ce1876e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 17 Jan 2008 18:53:18 +0000 Subject: [PATCH 2993/4131] prioritize first language code when scanning for a layout Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3081 --- src/dos/dos_keyboard_layout.cpp | 103 +++++++++++++++++++------------- 1 file changed, 62 insertions(+), 41 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 85b5b4fa..47cf8f72 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: dos_keyboard_layout.cpp,v 1.11 2008-01-17 18:53:18 c2woody Exp $ */ + #include "dosbox.h" #include "bios.h" #include "setup.h" @@ -140,7 +142,7 @@ void keyboard_layout::read_keyboard_file(Bit32s specific_layout) { this->read_keyboard_file(current_keyboard_file_name, specific_layout, dos.loaded_codepage); } -static Bit32u read_kcl_file(const char* kcl_file_name, const char* layout_id) { +static Bit32u read_kcl_file(const char* kcl_file_name, const char* layout_id, bool first_id_only) { FILE* tempfile = OpenDosboxFile(kcl_file_name); if (tempfile==0) return 0; @@ -163,7 +165,7 @@ static Bit32u read_kcl_file(const char* kcl_file_name, const char* layout_id) { Bit8u data_len=rbuf[2]; - char lng_codes[256]; + char lng_codes[258]; // get all language codes for this layout for (Bitu i=0; i Date: Sat, 19 Jan 2008 11:02:29 +0000 Subject: [PATCH 2994/4131] Move commandline to programs.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3082 --- include/programs.h | 35 +++++++++++++++++++++++++++++++++-- include/setup.h | 36 ++++++++++++------------------------ src/dos/dos_programs.cpp | 3 ++- src/shell/shell_cmds.cpp | 3 ++- 4 files changed, 49 insertions(+), 28 deletions(-) diff --git a/include/programs.h b/include/programs.h index 868a436d..3cee7b4d 100644 --- a/include/programs.h +++ b/include/programs.h @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: programs.h,v 1.15 2008-01-19 11:02:29 qbix79 Exp $ */ + #ifndef DOSBOX_PROGRAMS_H #define DOSBOX_PROGRAMS_H @@ -25,10 +27,39 @@ #ifndef DOSBOX_DOS_INC_H #include "dos_inc.h" #endif -#ifndef DOSBOX_SETUP_H -#include "setup.h" + +#ifndef CH_LIST +#define CH_LIST +#include #endif +#ifndef CH_STRING +#define CH_STRING +#include +#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); +private: + typedef std::list::iterator cmd_it; + std::list cmds; + std::string file_name; + bool FindEntry(char const * const name,cmd_it & it,bool neednext=false); +}; class Program { public: diff --git a/include/setup.h b/include/setup.h index ad50ddfc..5c406e04 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.28 2007-10-21 08:43:24 qbix79 Exp $ */ +/* $Id: setup.h,v 1.29 2008-01-19 11:02:29 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -28,31 +28,19 @@ #ifndef DOSBOX_CROSS_H #include "cross.h" #endif -#include +#ifndef DOSBOX_PROGRAMS_H +#include "programs.h" +#endif + +#ifndef CH_LIST +#define CH_LIST #include +#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); -private: - typedef std::list::iterator cmd_it; - std::list cmds; - std::string file_name; - bool FindEntry(char const * const name,cmd_it & it,bool neednext=false); -}; +#ifndef CH_STRING +#define CH_STRING +#include +#endif union Value{ int _hex; diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index e9c90a1a..60c6cd33 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.81 2007-12-27 15:38:00 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.82 2008-01-19 11:02:29 qbix79 Exp $ */ #include "dosbox.h" #include @@ -34,6 +34,7 @@ #include "dos_system.h" #include "dos_inc.h" #include "bios.h" +#include "setup.h" #if defined HAVE_SYS_TYPES_H && defined HAVE_PWD_H #include diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 3c1a3f48..4b3a1307 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.79 2007-10-16 07:29:22 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.80 2008-01-19 11:02:29 qbix79 Exp $ */ #include "dosbox.h" #include "shell.h" @@ -24,6 +24,7 @@ #include "regs.h" #include "../dos/drives.h" #include "support.h" +#include "setup.h" #include #include #include From f82d47239e35cb59ee9a3d33c6d2f113e0e105ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 20 Jan 2008 09:21:49 +0000 Subject: [PATCH 2995/4131] use bios scanlength/page size fields instead of mode fixed values for put/get pixel functions (fixes aldo2) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3083 --- src/ints/int10_put_pixel.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index b6445ead..d854bdf7 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: int10_put_pixel.cpp,v 1.19 2008-01-20 09:21:49 c2woody Exp $ */ + #include "dosbox.h" #include "mem.h" #include "inout.h" @@ -102,7 +104,12 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { if (color & 0x80) { IO_Write(0x3ce,0x3);IO_Write(0x3cf,0x18); } //Perhaps also set mode 1 /* Calculate where the pixel is in video memory */ - PhysPt off=0xa0000+CurMode->plength*page+((y*CurMode->swidth+x)>>3); + if (CurMode->plength!=real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)) + E_Exit("PutPixel_EGA_p: %x!=%x",CurMode->plength,real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)); + if (CurMode->swidth!=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8) + E_Exit("PutPixel_EGA_w: %x!=%x",CurMode->swidth,real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); + PhysPt off=0xa0000+real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)*page+ + ((y*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8+x)>>3); /* Bitmask and set/reset should do the rest */ mem_readb(off); mem_writeb(off,0xff); @@ -118,7 +125,9 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { mem_writeb(PhysMake(0xa000,y*320+x),color); break; case M_LIN8: { - PhysPt off=S3_LFB_BASE+y*CurMode->swidth+x; + if (CurMode->swidth!=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8) + E_Exit("PutPixel_VGA_w: %x!=%x",CurMode->swidth,real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); + PhysPt off=S3_LFB_BASE+y*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8+x; mem_writeb(off,color); break; } @@ -149,7 +158,12 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { case M_EGA: { /* Calculate where the pixel is in video memory */ - PhysPt off=0xa0000+CurMode->plength*page+((y*CurMode->swidth+x)>>3); + if (CurMode->plength!=real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)) + E_Exit("GetPixel_EGA_p: %x!=%x",CurMode->plength,real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)); + if (CurMode->swidth!=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8) + E_Exit("GetPixel_EGA_w: %x!=%x",CurMode->swidth,real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); + PhysPt off=0xa0000+real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)*page+ + ((y*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8+x)>>3); Bitu shift=7-(x & 7); /* Set the read map */ *color=0; @@ -167,7 +181,9 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { *color=mem_readb(PhysMake(0xa000,320*y+x)); break; case M_LIN8: { - PhysPt off=S3_LFB_BASE+y*CurMode->swidth+x; + if (CurMode->swidth!=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8) + E_Exit("GetPixel_VGA_w: %x!=%x",CurMode->swidth,real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); + PhysPt off=S3_LFB_BASE+y*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8+x; *color = mem_readb(off); break; } From cd53ce7d2449923584d001d47a7b3b03fb1333cb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 21 Jan 2008 21:20:01 +0000 Subject: [PATCH 2996/4131] add setup.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3084 --- src/debug/debug.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index b11f2550..de403a7e 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.91 2007-12-15 16:28:32 c2woody Exp $ */ +/* $Id: debug.cpp,v 1.92 2008-01-21 21:20:01 qbix79 Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -48,6 +48,7 @@ using namespace std; #include "debug_inc.h" #include "../cpu/lazyflags.h" #include "keyboard.h" +#include "setup.h" #ifdef WIN32 void WIN32_Console(); From 93d6a604934a05c7345bd9979b62994734933f0c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 21 Jan 2008 21:22:58 +0000 Subject: [PATCH 2997/4131] Add setup.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3085 --- src/dos/cdrom_image.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 4d378f80..b47714e6 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.18 2007-10-14 17:31:52 c2woody Exp $ */ +/* $Id: cdrom_image.cpp,v 1.19 2008-01-21 21:22:58 qbix79 Exp $ */ #include #include @@ -30,6 +30,7 @@ #include "cdrom.h" #include "drives.h" #include "support.h" +#include "setup.h" #if !defined(WIN32) #include From c920ed5e8c9455eb48952c602774585967ea1b68 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 21 Jan 2008 21:25:17 +0000 Subject: [PATCH 2998/4131] More mscdex quirks. Label is not upcased. Fixes daggerfall cdrom detection. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3086 --- src/dos/drives.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index aacb0e26..7cd1cb93 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.cpp,v 1.12 2007-11-01 12:15:34 qbix79 Exp $ */ +/* $Id: drives.cpp,v 1.13 2008-01-21 21:25:17 qbix79 Exp $ */ #include "dosbox.h" #include "dos_system.h" @@ -88,7 +88,9 @@ void Set_Label(char const * const input, char * const output, bool cdrom) { if (input[vnamePos]==0) break; if (!point && (input[vnamePos]=='.')) { togo=4; point=true; } - output[labelPos] = toupper(input[vnamePos]); + //another mscdex quirk. Label is not always uppercase. (Daggerfall) + output[labelPos] = (cdrom?input[vnamePos]:toupper(input[vnamePos])); + labelPos++; vnamePos++; togo--; if ((togo==0) && !point) { From 6532a8bc74e6f8be08ca685ad0b2214cf4183752 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 21 Jan 2008 21:26:49 +0000 Subject: [PATCH 2999/4131] Don't close totally empty fcbs. Very basic check. Fixes Oubliette. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3087 --- include/dos_inc.h | 3 ++- src/dos/dos_classes.cpp | 8 +++++++- src/dos/dos_files.cpp | 3 ++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 152afd0a..4f46a970 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.72 2007-11-18 10:30:11 c2woody Exp $ */ +/* $Id: dos_inc.h,v 1.73 2008-01-21 21:26:49 qbix79 Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -502,6 +502,7 @@ public: bool Extended(void); void GetAttr(Bit8u & attr); void SetAttr(Bit8u attr); + bool Valid(void); private: bool extended; PhysPt real_pt; diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index fa648bc2..81364b6e 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.53 2007-11-07 22:08:03 c2woody Exp $ */ +/* $Id: dos_classes.cpp,v 1.54 2008-01-21 21:26:49 qbix79 Exp $ */ #include #include @@ -472,6 +472,12 @@ void DOS_FCB::FileOpen(Bit8u _fhandle) { sSave(sFCB,date,Files[temp]->date); } +bool DOS_FCB::Valid() { + //Very simple check for Oubliette + if(sGet(sFCB,filename[0]) == 0 && sGet(sFCB,file_handle) == 0) return false; + return true; +} + void DOS_FCB::FileClose(Bit8u & _fhandle) { _fhandle=sGet(sFCB,file_handle); sSave(sFCB,file_handle,0xff); diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 0c37e33e..6c921731 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.93 2007-10-20 19:13:59 c2woody Exp $ */ +/* $Id: dos_files.cpp,v 1.94 2008-01-21 21:26:49 qbix79 Exp $ */ #include #include @@ -851,6 +851,7 @@ bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { bool DOS_FCBClose(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); + if(!fcb.Valid()) return false; Bit8u fhandle; fcb.FileClose(fhandle); DOS_CloseFile(fhandle); From e0c08be26f06a65ca27af594865635debe16fd37 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 26 Jan 2008 15:50:19 +0000 Subject: [PATCH 3000/4131] Part of the configurating changes. Value is a class now. Some cleanups and support functions to make this transition smooth. It compiles and works, but it's not finished yet. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3088 --- include/setup.h | 114 ++++++++++++++++++++++++++++------- src/gui/sdl_gui.cpp | 12 ++-- src/misc/setup.cpp | 144 +++++++++++++++++++++++++++++++++++++------- 3 files changed, 219 insertions(+), 51 deletions(-) diff --git a/include/setup.h b/include/setup.h index 5c406e04..cc27f4df 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.29 2008-01-19 11:02:29 qbix79 Exp $ */ +/* $Id: setup.h,v 1.30 2008-01-26 15:50:19 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -37,74 +37,142 @@ #include #endif +#ifndef CH_VECTOR +#define CH_VECTOR +#include +#endif + #ifndef CH_STRING #define CH_STRING #include #endif -union Value{ +class Hex { +private: + int _hex; +public: + Hex(int in):_hex(in) { }; + Hex():_hex(0) { }; + bool operator==(Hex const& other) {return _hex == other._hex;} +}; + +class Value { +public: //for the time being. Added a n to _hex to keep compilable during the work + Hex _hexn; int _hex; bool _bool; int _int; std::string* _string; - float _float; + double _double; +public: + class WrongType { }; // Conversion error class + enum { V_NONE, V_HEX, V_BOOL, V_INT, V_STRING, V_DOUBLE} type; + + /* Constructors */ + Value() :type(V_NONE) { }; + Value(Hex in) :type(V_HEX), _hexn(in) { }; + Value(int in) :type(V_INT), _int(in) { }; + Value(bool in) :type(V_BOOL), _bool(in) { }; + Value(double in) :type(V_DOUBLE), _double(in) { }; + Value(std::string const& in) :type(V_STRING), _string(new std::string(in)) { }; + Value(char const * const in) :type(V_STRING), _string(new std::string(in)) { }; + Value(Value const& in) {plaincopy(in);} + ~Value() { destroy();}; + + /* 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 () throw(WrongType); + operator Hex () throw(WrongType); + operator int () throw(WrongType); + operator double () throw(WrongType); + operator char const* () throw(WrongType); + +private: + void destroy(); + Value& copy(Value const& in) throw(WrongType); + void plaincopy(Value const& in); + }; class Property { public: + struct Changable { enum Value {Always, WhenIdle,OnlyAtStart};}; Property(char const * const _propname):propname(_propname) { } virtual void SetValue(char* input)=0; virtual void GetValuestring(char* str) const=0; Value GetValue() const { return value;} virtual ~Property(){ } std::string propname; + //CheckValue returns true (and sets value to in) 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) {if(forced || CheckValue(in,false)) value = in; else value = default_value;} +protected: Value value; + std::vector suggested_values; + typedef std::vector::iterator iter; + Value default_value; + /*const*/ Changable::Value change; }; class Prop_int:public Property { public: Prop_int(char const * const _propname, int _value):Property(_propname) { - value._int=_value; + default_value = value = _value; + min = max = -1; } + void SetMinMax(Value const& min,Value const& max) {this->min = min; this->max=max;} void SetValue(char* input); - void GetValuestring(char* str) const; + void GetValuestring(char* str) const; ~Prop_int(){ } + virtual bool CheckValue(Value const& in, bool warn); +private: + Value min,max; }; -class Prop_float:public Property { +class Prop_double:public Property { public: - Prop_float(char const * const _propname, float _value):Property(_propname){ - value._float=_value; + Prop_double(char const * const _propname, float _value):Property(_propname){ + default_value = value = _value; } void SetValue(char* input); void GetValuestring(char* str) const; - ~Prop_float(){ } + ~Prop_double(){ } }; class Prop_bool:public Property { public: Prop_bool(char const * const _propname, bool _value):Property(_propname) { - value._bool=_value; + default_value = value = _value; } void SetValue(char* input); - void GetValuestring(char* str) const; + void GetValuestring(char* str) const; ~Prop_bool(){ } }; class Prop_string:public Property{ public: Prop_string(char const * const _propname, char const * const _value):Property(_propname) { - value._string=new std::string(_value); - } - ~Prop_string(){ - delete value._string; + default_value = value = _value; } void SetValue(char* input); - void GetValuestring(char* str) const; + void GetValuestring(char* str) const; + ~Prop_string(){ } + }; class Prop_hex:public Property { public: Prop_hex(char const * const _propname, int _value):Property(_propname) { - value._hex=_value; + default_value = value._hex = _value; } void SetValue(char* input); ~Prop_hex(){ } @@ -150,18 +218,18 @@ private: typedef std::list::const_iterator const_it; public: Section_prop(char const * const _sectionname):Section(_sectionname){} - void Add_int(char const * const _propname, int _value=0); - void Add_string(char const * const _propname, char const * const _value=NULL); - void Add_bool(char const * const _propname, bool _value=false); - void Add_hex(char const * const _propname, int _value=0); - void Add_float(char const * const _propname, float _value=0.0); + Prop_int& Add_int(char const * const _propname, int _value=0); + Prop_string& Add_string(char const * const _propname, char const * const _value=NULL); + Prop_bool& Add_bool(char const * const _propname, bool _value=false); + Prop_hex& Add_hex(char const * const _propname, int _value=0); + void Add_double(char const * const _propname, double _value=0.0); Property* Get_prop(int index); int Get_int(char const * const _propname) const; const char* Get_string(char const * const _propname) const; bool Get_bool(char const * const _propname) const; int Get_hex(char const * const _propname) const; - float Get_float(char const * const _propname) const; + double Get_double(char const * const _propname) const; void HandleInputline(char *gegevens); void PrintData(FILE* outfile) const; virtual char const * GetPropValue(char const * const _property) const; diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index 59b40233..6a1a900c 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_gui.cpp,v 1.3 2007-11-06 20:25:36 qbix79 Exp $ */ +/* $Id: sdl_gui.cpp,v 1.4 2008-01-26 15:50:19 qbix79 Exp $ */ #include "SDL.h" #include "../libs/gui_tk/gui_tk.h" @@ -317,13 +317,13 @@ public: PropertyEditor(parent, x, y, section, prop) { new GUI::Label(this, 0, 5, prop->propname); input = new GUI::Input(this, 130, 0, 50); - input->setText(stringify(prop->GetValue()._float)); + input->setText(stringify((double)prop->GetValue())); } bool prepare(std::string &buffer) { - float val; + double val; convert(input->getText(), val, false); - if (val == prop->GetValue()._float) return false; + if (val == (double)prop->GetValue()) return false; buffer.append(stringify(val)); return true; } @@ -403,7 +403,7 @@ public: while ((prop = section->Get_prop(i))) { Prop_bool *pbool = dynamic_cast(prop); Prop_int *pint = dynamic_cast(prop); - Prop_float *pfloat = dynamic_cast(prop); + Prop_double *pdouble = dynamic_cast(prop); Prop_hex *phex = dynamic_cast(prop); Prop_string *pstring = dynamic_cast(prop); @@ -411,7 +411,7 @@ public: if (pbool) p = new PropertyEditorBool(this, 5+250*(i/6), 40+(i%6)*30, section, prop); else if (phex) p = new PropertyEditorHex(this, 5+250*(i/6), 40+(i%6)*30, section, prop); else if (pint) p = new PropertyEditorInt(this, 5+250*(i/6), 40+(i%6)*30, section, prop); - else if (pfloat) p = new PropertyEditorFloat(this, 5+250*(i/6), 40+(i%6)*30, section, prop); + else if (pdouble) p = new PropertyEditorFloat(this, 5+250*(i/6), 40+(i%6)*30, section, prop); else if (pstring) p = new PropertyEditorString(this, 5+250*(i/6), 40+(i%6)*30, section, prop); else { i++; continue; } b->addActionHandler(p); diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 842cbdfc..9506bd7e 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.41 2007-10-21 08:43:24 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.42 2008-01-26 15:50:19 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -30,19 +30,115 @@ using namespace std; -void Prop_float::SetValue(char* input){ +void Value::destroy() { + if (type == V_STRING) delete _string; +} + +Value& Value::copy(Value const& in) throw(WrongType) { + if (this != &in) { //Selfassigment! + if(type != V_NONE && type != in.type) throw WrongType(); + destroy(); + plaincopy(in); + } + return *this; +} + +void Value::plaincopy(Value const& in) { + type = in.type; + _int = in._int; + _double = in._double; + _bool = in._bool; + _hex = in._hex; + if(type == V_STRING) _string = new string(*in._string); +} + +Value::operator bool () throw(WrongType) { + if(type != V_BOOL) throw WrongType(); + return _bool; +} + +Value::operator Hex () throw(WrongType) { + if(type != V_HEX) throw WrongType(); + return _hexn; +} + +Value::operator int () throw(WrongType) { + if(type != V_INT) throw WrongType(); + return _int; +} + +Value::operator double () throw(WrongType) { + if(type != V_DOUBLE) throw WrongType(); + return _double; +} + +Value::operator char const* () throw(WrongType) { + if(type != V_STRING) throw WrongType(); + return _string->c_str(); +} + +bool Value::operator==(Value const& other) { + if(this == &other) return true; + if(type != other.type) return false; + switch(type){ + case V_BOOL: + if(_bool == other._bool) return true; + break; + case V_INT: + if(_int == other._int) return true; + break; + case V_HEX: + if(_hexn == other._hexn) return true; + break; + case V_DOUBLE: + if(_double == other._double) return true; + break; + case V_STRING: + if((*_string) == (*other._string)) return true; + break; + default: + E_Exit("comparing stuff that doesn't make sense"); + break; + } + return false; +} + +bool Property::CheckValue(Value const& in, bool warn){ + if(suggested_values.empty()) return false; + for(iter it = suggested_values.begin();it != suggested_values.end();it++) { + if ( (*it) == in) { //Match! + return true; + } + } + if(warn) LOG_MSG("Value not in suggested values"); + return false; +} + +bool Prop_int::CheckValue(Value const& in, bool warn) { + if(Property::CheckValue(in,warn)) return true; + //No >= and <= in Value type and == is ambigious + int mi = min; + int ma = max; + int va = static_cast(Value(in)); + if(mi == -1 && ma == -1) return true; + if (va >= mi && va <= ma) return true; + if(warn) LOG_MSG("Value not included in range"); + return false; +} + +void Prop_double::SetValue(char* input){ input=trim(input); - value._float= static_cast(atof(input)); + value = static_cast(atof(input)); } void Prop_int::SetValue(char* input){ input=trim(input); - value._int= atoi(input); + value = atoi(input); } void Prop_string::SetValue(char* input){ input=trim(input); - value._string->assign(input); + value=input; } void Prop_bool::SetValue(char* input){ @@ -71,42 +167,46 @@ void Prop_bool::GetValuestring(char* str) const{ sprintf(str,"%s",value._bool?"true":"false"); } -void Prop_float::GetValuestring(char* str) const { - sprintf(str,"%1.2f",value._float); +void Prop_double::GetValuestring(char* str) const { + sprintf(str,"%1.2f",value._double); } void Prop_hex::GetValuestring(char* str) const { sprintf(str,"%X",value._hex); } -void Section_prop::Add_float(char const * const _propname, float _value) { - Property* test=new Prop_float(_propname,_value); +void Section_prop::Add_double(char const * const _propname, double _value) { + Property* test=new Prop_double(_propname,_value); properties.push_back(test); } -void Section_prop::Add_int(const char* _propname, int _value) { - Property* test=new Prop_int(_propname,_value); +Prop_int& Section_prop::Add_int(const char* _propname, int _value) { + Prop_int* test=new Prop_int(_propname,_value); properties.push_back(test); + return *test; } -void Section_prop::Add_string(char const * const _propname, char const * const _value) { - Property* test=new Prop_string(_propname,_value); +Prop_string& Section_prop::Add_string(char const * const _propname, char const * const _value) { + Prop_string* test=new Prop_string(_propname,_value); properties.push_back(test); + return *test; } -void Section_prop::Add_bool(char const * const _propname, bool _value) { - Property* test=new Prop_bool(_propname,_value); +Prop_bool& Section_prop::Add_bool(char const * const _propname, bool _value) { + Prop_bool* test=new Prop_bool(_propname,_value); properties.push_back(test); + return *test; } -void Section_prop::Add_hex(const char* _propname, int _value) { - Property* test=new Prop_hex(_propname,_value); +Prop_hex& Section_prop::Add_hex(const char* _propname, int _value) { + Prop_hex* test=new Prop_hex(_propname,_value); properties.push_back(test); + return *test; } int Section_prop::Get_int(char const * const _propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ - return ((*tel)->GetValue())._int; + return ((*tel)->GetValue()); } } return 0; @@ -115,15 +215,15 @@ int Section_prop::Get_int(char const * const _propname) const { bool Section_prop::Get_bool(char const * const _propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ - return ((*tel)->GetValue())._bool; + return ((*tel)->GetValue()); } } return false; } -float Section_prop::Get_float(char const * const _propname) const { +double Section_prop::Get_double(char const * const _propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ - return ((*tel)->GetValue())._float; + return ((*tel)->GetValue()); } } return false; @@ -139,7 +239,7 @@ Property* Section_prop::Get_prop(int index){ const char* Section_prop::Get_string(char const * const _propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ - return ((*tel)->GetValue())._string->c_str(); + return ((*tel)->GetValue()); } } return ""; From 8a10bb8f0dc704eefc511a102b63b1b1d12c55bb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 27 Jan 2008 18:31:01 +0000 Subject: [PATCH 3001/4131] Fix creating of a copy of Value in GetValue. Fixes crashes with freeing the returned string. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3089 --- include/setup.h | 18 ++++++++++-------- src/misc/setup.cpp | 12 ++++++------ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/include/setup.h b/include/setup.h index cc27f4df..1024d547 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.30 2008-01-26 15:50:19 qbix79 Exp $ */ +/* $Id: setup.h,v 1.31 2008-01-27 18:31:01 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -47,6 +47,8 @@ #include #endif +#pragma warning(disable: 4290) + class Hex { private: int _hex; @@ -89,11 +91,11 @@ public: Value& operator= (Value const& in) throw(WrongType) { return copy(Value(in));} bool operator== (Value const & other); - operator bool () throw(WrongType); - operator Hex () throw(WrongType); - operator int () throw(WrongType); - operator double () throw(WrongType); - operator char const* () throw(WrongType); + 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); private: void destroy(); @@ -108,7 +110,7 @@ public: Property(char const * const _propname):propname(_propname) { } virtual void SetValue(char* input)=0; virtual void GetValuestring(char* str) const=0; - Value GetValue() const { return value;} + Value const& GetValue() const { return value;} virtual ~Property(){ } std::string propname; //CheckValue returns true (and sets value to in) if value is in suggested_values; @@ -141,7 +143,7 @@ private: }; class Prop_double:public Property { public: - Prop_double(char const * const _propname, float _value):Property(_propname){ + Prop_double(char const * const _propname, double _value):Property(_propname){ default_value = value = _value; } void SetValue(char* input); diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 9506bd7e..a2937720 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.42 2008-01-26 15:50:19 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.43 2008-01-27 18:31:01 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -52,27 +52,27 @@ void Value::plaincopy(Value const& in) { if(type == V_STRING) _string = new string(*in._string); } -Value::operator bool () throw(WrongType) { +Value::operator bool () const throw(WrongType) { if(type != V_BOOL) throw WrongType(); return _bool; } -Value::operator Hex () throw(WrongType) { +Value::operator Hex () const throw(WrongType) { if(type != V_HEX) throw WrongType(); return _hexn; } -Value::operator int () throw(WrongType) { +Value::operator int () const throw(WrongType) { if(type != V_INT) throw WrongType(); return _int; } -Value::operator double () throw(WrongType) { +Value::operator double () const throw(WrongType) { if(type != V_DOUBLE) throw WrongType(); return _double; } -Value::operator char const* () throw(WrongType) { +Value::operator char const* () const throw(WrongType) { if(type != V_STRING) throw WrongType(); return _string->c_str(); } From 827bb022174b9c7bee7ef7cd2727c134a8f25623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 2 Feb 2008 20:47:24 +0000 Subject: [PATCH 3002/4131] always stick to correct vga memory wrapping Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3090 --- src/hardware/vga_memory.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 9193fd7d..2e77e6f7 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_memory.cpp,v 1.47 2008-01-12 17:37:48 c2woody Exp $ */ +/* $Id: vga_memory.cpp,v 1.48 2008-02-02 20:47:24 c2woody Exp $ */ #include #include @@ -29,16 +29,15 @@ #include "setup.h" -/* #ifndef C_VGARAM_CHECKED +#ifndef C_VGARAM_CHECKED #define C_VGARAM_CHECKED 1 -#endif */ +#endif #if C_VGARAM_CHECKED // Checked linear offset #define CHECKED(v) ((v)&(vga.vmemwrap-1)) // Checked planar offset (latched access) #define CHECKED2(v) ((v)&((vga.vmemwrap>>2)-1)) -// Checked planar offset (latched access) #else #define CHECKED(v) (v) #define CHECKED2(v) (v) @@ -425,8 +424,8 @@ public: pixels.d&=vga.config.full_not_map_mask; pixels.d|=(data & vga.config.full_map_mask); ((Bit32u*)vga.mem.linear)[addr]=pixels.d; - if(vga.config.compatible_chain4) - ((Bit32u*)vga.mem.linear)[CHECKED2(addr+64*1024)]=pixels.d; +// if(vga.config.compatible_chain4) +// ((Bit32u*)vga.mem.linear)[CHECKED2(addr+64*1024)]=pixels.d; } public: VGA_UnchainedVGA_Handler() { From 02579c09f2f2995f7ff84c4ece950fc1ef4b8f5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 3 Feb 2008 12:19:35 +0000 Subject: [PATCH 3003/4131] save vesa modes' upper 24-30 bits for later get vesa mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3091 --- src/ints/int10.h | 5 ++++- src/ints/int10_modes.cpp | 3 ++- src/ints/int10_vesa.cpp | 10 +++++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/ints/int10.h b/src/ints/int10.h index 0d5db7df..5fb65dc4 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: int10.h,v 1.33 2008-02-03 12:19:35 c2woody Exp $ */ + #include "vga.h" #define S3_LFB_BASE 0xC0000000 @@ -135,6 +137,7 @@ typedef struct { Bit16u pmode_interface_palette; Bitu used; } rom; + Bitu vesa_setmode; } Int10Data; extern Int10Data int10; diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 41210be8..f8f2b86d 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.75 2008-01-12 17:37:48 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.76 2008-02-03 12:19:35 c2woody Exp $ */ #include @@ -579,6 +579,7 @@ bool INT10_SetVideoMode(Bitu mode) { clearmem=false; mode-=0x80; } + int10.vesa_setmode=0xffff; LOG(LOG_INT10,LOG_NORMAL)("Set Video Mode %X",mode); if (!IS_EGAVGA_ARCH) return INT10_SetVideoMode_OTHER(mode,clearmem); Bit8u modeset_ctl,video_ctl,vga_switches; diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 09a60234..b622ff29 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.32 2008-01-15 17:46:25 c2woody Exp $ */ +/* $Id: int10_vesa.cpp,v 1.33 2008-02-03 12:19:35 c2woody Exp $ */ #include #include @@ -266,12 +266,16 @@ foundit: Bit8u VESA_SetSVGAMode(Bit16u mode) { - if (INT10_SetVideoMode(mode)) return 0x00; + if (INT10_SetVideoMode(mode)) { + int10.vesa_setmode=mode&0x7fff; + return 0x00; + } return 0x01; }; Bit8u VESA_GetSVGAMode(Bit16u & mode) { - mode=(Bit16u)(CurMode->mode); + if (int10.vesa_setmode!=0xffff) mode=int10.vesa_setmode; + else mode=(Bit16u)(CurMode->mode); return 0x00; } From 09622a48afab19dd5d9320ed0fbfed9322b907cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 3 Feb 2008 20:43:14 +0000 Subject: [PATCH 3004/4131] optionally turn off vesa linear framebuffer for some buggy games Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3092 --- src/dosbox.cpp | 8 +++++++- src/ints/int10.h | 3 ++- src/ints/int10_modes.cpp | 3 ++- src/ints/int10_vesa.cpp | 16 ++++++++++------ 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 7a8b3698..9e09b4df 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.126 2008-01-16 20:16:31 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.127 2008-02-03 20:43:13 c2woody Exp $ */ #include #include @@ -39,6 +39,7 @@ #include "programs.h" #include "support.h" #include "mapper.h" +#include "ints/int10.h" Config * control; MachineType machine; @@ -271,6 +272,7 @@ static void DOSBOX_RealInit(Section * sec) { MAPPER_AddHandler(DOSBOX_UnlockSpeed, MK_f12, MMOD2,"speedlock","Speedlock"); svgaCard=SVGA_None; machine=MCH_VGA; + int10.vesa_nolfb=false; std::string cmd_machine; const char * mtype; if (control->cmdline->FindString("-machine",cmd_machine,true)) mtype=cmd_machine.c_str(); @@ -284,6 +286,10 @@ static void DOSBOX_RealInit(Section * sec) { (strcasecmp(mtype,"svga")==0) || (strcasecmp(mtype,"svga_s3")==0)) { machine=MCH_VGA; svgaCard=SVGA_S3Trio; + } else if (strcasecmp(mtype,"vesa_nolfb")==0) { + machine=MCH_VGA; + svgaCard=SVGA_S3Trio; + int10.vesa_nolfb=true; } else if ((strcasecmp(mtype,"vga_et4000")==0) || (strcasecmp(mtype,"svga_et4000")==0)) { machine=MCH_VGA; svgaCard=SVGA_TsengET4K; diff --git a/src/ints/int10.h b/src/ints/int10.h index 5fb65dc4..9f9f4c2f 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.h,v 1.33 2008-02-03 12:19:35 c2woody Exp $ */ +/* $Id: int10.h,v 1.34 2008-02-03 20:43:14 c2woody Exp $ */ #include "vga.h" @@ -138,6 +138,7 @@ typedef struct { Bitu used; } rom; Bitu vesa_setmode; + bool vesa_nolfb; } Int10Data; extern Int10Data int10; diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index f8f2b86d..949ccb86 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.76 2008-02-03 12:19:35 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.77 2008-02-03 20:43:14 c2woody Exp $ */ #include @@ -572,6 +572,7 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { bool INT10_SetVideoMode(Bitu mode) { bool clearmem=true;Bitu i; if (mode>=0x100) { + if ((mode & 0x4000) && int10.vesa_nolfb) return false; if (mode & 0x8000) clearmem=false; mode&=0xfff; } diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index b622ff29..144ccad0 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.33 2008-02-03 12:19:35 c2woody Exp $ */ +/* $Id: int10_vesa.cpp,v 1.34 2008-02-03 20:43:14 c2woody Exp $ */ #include #include @@ -164,7 +164,8 @@ foundit: var_write(&minfo.NumberOfPlanes,0x1); var_write(&minfo.BitsPerPixel,8); var_write(&minfo.MemoryModel,4); //packed pixel - modeAttributes = 0x9b; // Color, graphics, linear buffer + modeAttributes = 0x1b; // Color, graphics + if (!int10.vesa_nolfb) modeAttributes |= 0x80; // linear framebuffer break; case M_LIN15: pageSize = mblock->sheight * mblock->swidth*2; @@ -181,7 +182,8 @@ foundit: var_write(&minfo.BlueMaskPos,0); var_write(&minfo.ReservedMaskSize,0x01); var_write(&minfo.ReservedMaskPos,0x0f); - modeAttributes = 0x9b; // Color, graphics, linear buffer + modeAttributes = 0x1b; // Color, graphics + if (!int10.vesa_nolfb) modeAttributes |= 0x80; // linear framebuffer break; case M_LIN16: pageSize = mblock->sheight * mblock->swidth*2; @@ -196,7 +198,8 @@ foundit: var_write(&minfo.GreenMaskPos,5); var_write(&minfo.BlueMaskSize,5); var_write(&minfo.BlueMaskPos,0); - modeAttributes = 0x9b; // Color, graphics, linear buffer + modeAttributes = 0x1b; // Color, graphics + if (!int10.vesa_nolfb) modeAttributes |= 0x80; // linear framebuffer break; case M_LIN32: pageSize = mblock->sheight * mblock->swidth*4; @@ -213,7 +216,8 @@ foundit: var_write(&minfo.BlueMaskPos,0x0); var_write(&minfo.ReservedMaskSize,0x8); var_write(&minfo.ReservedMaskPos,0x18); - modeAttributes = 0x9b; // Color, graphics, linear buffer + modeAttributes = 0x1b; // Color, graphics + if (!int10.vesa_nolfb) modeAttributes |= 0x80; // linear framebuffer break; /* case M_TEXT: pageSize = mblock->sheight/8 * mblock->swidth*2/8; @@ -258,7 +262,7 @@ foundit: var_write(&minfo.Reserved_page,0x1); var_write(&minfo.XCharSize,mblock->cwidth); var_write(&minfo.YCharSize,mblock->cheight); - var_write(&minfo.PhysBasePtr,S3_LFB_BASE); + if (!int10.vesa_nolfb) var_write(&minfo.PhysBasePtr,S3_LFB_BASE); MEM_BlockWrite(buf,&minfo,sizeof(MODE_INFO)); return 0x00; From cb40dff18bcacef2d935fff25ed1f31f93fd79b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 5 Feb 2008 17:58:14 +0000 Subject: [PATCH 3005/4131] keep some lower limit for allocated vga memory Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3093 --- src/hardware/vga_memory.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 2e77e6f7..81b007fd 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_memory.cpp,v 1.48 2008-02-02 20:47:24 c2woody Exp $ */ +/* $Id: vga_memory.cpp,v 1.49 2008-02-05 17:58:14 c2woody Exp $ */ #include #include @@ -902,10 +902,14 @@ void VGA_SetupMemory(Section* sec) { vga.svga.bank_read = vga.svga.bank_write = 0; vga.svga.bank_read_full = vga.svga.bank_write_full = 0; + Bit32u vga_allocsize=vga.vmemsize; + // Keep lower limit at 512k + if (vga_allocsize<512*1024) vga_allocsize=512*1024; // We reserve extra 2K for one scan line - vga.mem.linear_orgptr = new Bit8u[vga.vmemsize+2048+16]; + vga_allocsize+=2048+16; + vga.mem.linear_orgptr = new Bit8u[vga_allocsize]; vga.mem.linear=(Bit8u*)(((Bitu)vga.mem.linear_orgptr + 16-1) & ~(16-1)); - memset(vga.mem.linear,0,vga.vmemsize); + memset(vga.mem.linear,0,vga_allocsize); vga.fastmem_orgptr = new Bit8u[(vga.vmemsize<<1)+4096+16]; vga.fastmem=(Bit8u*)(((Bitu)vga.fastmem_orgptr + 16-1) & ~(16-1)); From 8ee3853d179ec3faad23e9f481deff98248f44c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 6 Feb 2008 18:23:34 +0000 Subject: [PATCH 3006/4131] delay small vertical display end changes a bit to avoid immediate screen resizing Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3094 --- include/vga.h | 4 ++-- src/hardware/vga.cpp | 8 ++++---- src/hardware/vga_crtc.cpp | 11 ++++++++--- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/include/vga.h b/include/vga.h index 9cf7d2df..ba39f2b2 100644 --- a/include/vga.h +++ b/include/vga.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga.h,v 1.38 2008-01-12 17:36:48 c2woody Exp $ */ +/* $Id: vga.h,v 1.39 2008-02-06 18:22:27 c2woody Exp $ */ #ifndef DOSBOX_VGA_H #define DOSBOX_VGA_H @@ -385,7 +385,7 @@ typedef struct { void VGA_SetMode(VGAModes mode); void VGA_DetermineMode(void); void VGA_SetupHandlers(void); -void VGA_StartResize(void); +void VGA_StartResize(Bitu delay=50); void VGA_SetupDrawing(Bitu val); void VGA_CheckScanLength(void); void VGA_ChangedBank(void); diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 060ab750..2d95fd74 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga.cpp,v 1.33 2008-01-12 17:37:48 c2woody Exp $ */ +/* $Id: vga.cpp,v 1.34 2008-02-06 18:23:34 c2woody Exp $ */ #include "dosbox.h" //#include "setup.h" @@ -82,11 +82,11 @@ void VGA_DetermineMode(void) { } } -void VGA_StartResize(void) { +void VGA_StartResize(Bitu delay /*=50*/) { if (!vga.draw.resizing) { vga.draw.resizing=true; - /* Start a resize after 50 ms */ - PIC_AddEvent(VGA_SetupDrawing,50); + /* Start a resize after delay (default 50 ms) */ + PIC_AddEvent(VGA_SetupDrawing,(float)delay); } } diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index c35c2fe0..cc941e12 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_crtc.cpp,v 1.30 2008-01-09 20:34:51 c2woody Exp $ */ +/* $Id: vga_crtc.cpp,v 1.31 2008-02-06 18:23:34 c2woody Exp $ */ #include #include "dosbox.h" @@ -226,11 +226,16 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { case 0x12: /* Vertical Display End Register */ if (val!=crtc(vertical_display_end)) { if (abs((Bits)val-(Bits)crtc(vertical_display_end))<3) { + // delay small vde changes a bit to avoid screen resizing + // if they are reverted in a short timeframe PIC_RemoveEvents(VGA_SetupDrawing); vga.draw.resizing=false; + crtc(vertical_display_end)=val; + VGA_StartResize(150); + } else { + crtc(vertical_display_end)=val; + VGA_StartResize(); } - crtc(vertical_display_end)=val; - VGA_StartResize(); } /* 0-7 Lower 8 bits of Vertical Display End. The display ends when the line From 6bb6bdc967808b0a110fa17fbdf2bc4c55cce854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 6 Feb 2008 21:56:32 +0000 Subject: [PATCH 3007/4131] use private dos data area for mscdex functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3095 --- src/dos/dos_mscdex.cpp | 117 +++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 63 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 2fa767d3..aac4c803 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.51 2007-12-30 08:21:35 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.52 2008-02-06 21:56:32 c2woody Exp $ */ #include #include @@ -138,6 +138,7 @@ public: private: PhysPt GetDefaultBuffer (void); + PhysPt GetTempBuffer (void); Bit16u numDrives; @@ -161,8 +162,7 @@ public: Bit16u rootDriverHeaderSeg; }; -CMscdex::CMscdex(void) -{ +CMscdex::CMscdex(void) { numDrives = 0; rootDriverHeaderSeg = 0; defaultBufSeg = 0; @@ -171,12 +171,12 @@ CMscdex::CMscdex(void) for (Bit32u i=0; i=numDrives) return false; Bit16u drive = dinfo[subUnit].drive; - Bit16u error,seg,size = 128; + Bit16u error; bool success = false; - if (DOS_AllocateMemory(&seg,&size)) { - PhysPt ptoc = PhysMake(seg,0); - success = ReadVTOC(drive,0x00,ptoc,error); - if (success) { - MEM_StrCopy(ptoc+40,data,31); - data[31] = 0; - rtrim(data); - }; - DOS_FreeMemory(seg); - } else { LOG(LOG_MISC,LOG_ERROR)("MSCDEX buffer allocation failed."); }; + PhysPt ptoc = GetTempBuffer(); + success = ReadVTOC(drive,0x00,ptoc,error); + if (success) { + MEM_StrCopy(ptoc+40,data,31); + data[31] = 0; + rtrim(data); + }; + return success; }; -bool CMscdex::GetCopyrightName(Bit16u drive, PhysPt data) -{ - Bit16u error,seg,size = 128; +bool CMscdex::GetCopyrightName(Bit16u drive, PhysPt data) { + Bit16u error; bool success = false; - if (DOS_AllocateMemory(&seg,&size)) { - PhysPt ptoc = PhysMake(seg,0); - success = ReadVTOC(drive,0x00,ptoc,error); - if (success) { - MEM_BlockCopy(data,ptoc+702,37); - mem_writeb(data+37,0); - }; - DOS_FreeMemory(seg); - } else { LOG(LOG_MISC,LOG_ERROR)("MSCDEX buffer allocation failed."); }; + PhysPt ptoc = GetTempBuffer(); + success = ReadVTOC(drive,0x00,ptoc,error); + if (success) { + MEM_BlockCopy(data,ptoc+702,37); + mem_writeb(data+37,0); + }; return success; }; -bool CMscdex::GetAbstractName(Bit16u drive, PhysPt data) -{ - Bit16u error,seg,size = 128; +bool CMscdex::GetAbstractName(Bit16u drive, PhysPt data) { + Bit16u error; bool success = false; - if (DOS_AllocateMemory(&seg,&size)) { - PhysPt ptoc = PhysMake(seg,0); - success = ReadVTOC(drive,0x00,ptoc,error); - if (success) { - MEM_BlockCopy(data,ptoc+739,37); - mem_writeb(data+37,0); - }; - DOS_FreeMemory(seg); - } else { LOG(LOG_MISC,LOG_ERROR)("MSCDEX buffer allocation failed."); }; + PhysPt ptoc = GetTempBuffer(); + success = ReadVTOC(drive,0x00,ptoc,error); + if (success) { + MEM_BlockCopy(data,ptoc+739,37); + mem_writeb(data+37,0); + }; return success; }; -bool CMscdex::GetDocumentationName(Bit16u drive, PhysPt data) -{ - Bit16u error,seg,size = 128; +bool CMscdex::GetDocumentationName(Bit16u drive, PhysPt data) { + Bit16u error; bool success = false; - if (DOS_AllocateMemory(&seg,&size)) { - PhysPt ptoc = PhysMake(seg,0); - success = ReadVTOC(drive,0x00,ptoc,error); - if (success) { - MEM_BlockCopy(data,ptoc+776,37); - mem_writeb(data+37,0); - }; - DOS_FreeMemory(seg); - } else { LOG(LOG_MISC,LOG_ERROR)("MSCDEX buffer allocation failed."); }; + PhysPt ptoc = GetTempBuffer(); + success = ReadVTOC(drive,0x00,ptoc,error); + if (success) { + MEM_BlockCopy(data,ptoc+776,37); + mem_writeb(data+37,0); + }; return success; }; From b7a86b482d08dc52b6f635fd2415ccaf27b4fb75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 8 Feb 2008 21:25:57 +0000 Subject: [PATCH 3008/4131] remove 4bpp vesa mode page size limit (hal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3096 --- src/ints/int10_vesa.cpp | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 144ccad0..5be682b4 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.34 2008-02-03 20:43:14 c2woody Exp $ */ +/* $Id: int10_vesa.cpp,v 1.35 2008-02-08 21:25:57 c2woody Exp $ */ #include #include @@ -147,15 +147,6 @@ foundit: var_write(&minfo.BitsPerPixel,4); var_write(&minfo.MemoryModel,3); //ega planar mode modeAttributes = 0x1b; // Color, graphics, no linear buffer - - if(pageSize > vga.vmemsize/4) { // this limitation is not on the real card - var_write(&minfo.ModeAttributes, modeAttributes & ~0x1); - var_write(&minfo.NumberOfImagePages,0); - } else { - var_write(&minfo.ModeAttributes, modeAttributes); - Bitu pages = ((vga.vmemsize/4) / pageSize)-1; - var_write(&minfo.NumberOfImagePages,pages); - } break; case M_LIN8: pageSize = mblock->sheight * mblock->swidth; @@ -233,16 +224,15 @@ foundit: } var_write(&minfo.WinAAttributes,0x7); // Exists/readable/writable - if(mblock->type != M_LIN4) - if(pageSize > vga.vmemsize) { - // Mode not supported by current hardware configuration - var_write(&minfo.ModeAttributes, modeAttributes & ~0x1); - var_write(&minfo.NumberOfImagePages,0); - } else { - var_write(&minfo.ModeAttributes, modeAttributes); - Bitu pages = (vga.vmemsize / pageSize)-1; - var_write(&minfo.NumberOfImagePages,pages); - } + if(pageSize > vga.vmemsize) { + // Mode not supported by current hardware configuration + var_write(&minfo.ModeAttributes, modeAttributes & ~0x1); + var_write(&minfo.NumberOfImagePages,0); + } else { + var_write(&minfo.ModeAttributes, modeAttributes); + Bitu pages = (vga.vmemsize / pageSize)-1; + var_write(&minfo.NumberOfImagePages,pages); + } if (mblock->type==M_TEXT) { var_write(&minfo.WinGranularity,32); From 0a8945c885e5e7417ea97b7d006cff1873040234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 9 Feb 2008 12:44:16 +0000 Subject: [PATCH 3009/4131] fix attr plane resetting for bios font loading (jal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3097 --- src/ints/int10_memory.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 701e2ccd..6582339a 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_memory.cpp,v 1.24 2007-10-08 20:22:13 c2woody Exp $ */ +/* $Id: int10_memory.cpp,v 1.25 2008-02-09 12:44:16 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -47,17 +47,16 @@ static Bit16u map_offset[8]={ }; void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu height) { - PhysPt where=PhysMake(0xa000,map_offset[map & 0x7]+offset*32); + PhysPt ftwhere=PhysMake(0xa000,map_offset[map & 0x7]+offset*32); IO_Write(0x3c4,0x2);IO_Write(0x3c5,0x4); //Enable plane 2 IO_Write(0x3ce,0x6);Bitu old_6=IO_Read(0x3cf); IO_Write(0x3cf,0x0); //Disable odd/even and a0000 adressing for (Bitu i=0;i Date: Sun, 10 Feb 2008 11:14:03 +0000 Subject: [PATCH 3010/4131] Partial rewrite of the configsystem part 2. Should be usuable. Missing parts are cosmetic. (based on Moe his stuff). I hope everything works in visual C. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3098 --- include/setup.h | 159 ++++++++----- src/cpu/cpu.cpp | 21 +- src/dosbox.cpp | 491 +++++++++++++++++++++++---------------- src/gui/render.cpp | 70 +++--- src/gui/sdl_gui.cpp | 22 +- src/gui/sdlmain.cpp | 166 ++++++------- src/misc/messages.cpp | 5 +- src/misc/programs.cpp | 10 +- src/misc/setup.cpp | 397 +++++++++++++++++++++---------- src/shell/shell_cmds.cpp | 6 +- 10 files changed, 811 insertions(+), 536 deletions(-) diff --git a/include/setup.h b/include/setup.h index 1024d547..fa7bdec0 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,13 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.31 2008-01-27 18:31:01 qbix79 Exp $ */ +/* $Id: setup.h,v 1.32 2008-02-10 11:14:02 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H #ifdef _MSC_VER #pragma warning ( disable : 4786 ) +#pragma warning ( disable : 4290 ) #endif #ifndef DOSBOX_CROSS_H @@ -47,7 +48,6 @@ #include #endif -#pragma warning(disable: 4290) class Hex { private: @@ -56,30 +56,39 @@ 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 { -public: //for the time being. Added a n to _hex to keep compilable during the work - Hex _hexn; - int _hex; +/* + * 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 { V_NONE, V_HEX, V_BOOL, V_INT, V_STRING, V_DOUBLE} type; + enum Etype { V_NONE, V_HEX, V_BOOL, V_INT, V_STRING, V_DOUBLE,V_CURRENT} type; /* Constructors */ - Value() :type(V_NONE) { }; - Value(Hex in) :type(V_HEX), _hexn(in) { }; + Value() :type(V_NONE),_string(0) { }; + Value(Hex in) :type(V_HEX), _hex(in) { }; Value(int in) :type(V_INT), _int(in) { }; Value(bool in) :type(V_BOOL), _bool(in) { }; Value(double in) :type(V_DOUBLE), _double(in) { }; Value(std::string const& in) :type(V_STRING), _string(new std::string(in)) { }; Value(char const * const in) :type(V_STRING), _string(new std::string(in)) { }; - Value(Value const& in) {plaincopy(in);} + Value(Value const& in):_string(0) {plaincopy(in);} ~Value() { destroy();}; + Value(std::string const& in,Etype _t) :type(V_NONE),_string(0){SetValue(in,_t);} /* Assigment operators */ Value& operator= (Hex in) throw(WrongType) { return copy(Value(in));} @@ -96,91 +105,108 @@ public: 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(); + void destroy() throw(); Value& copy(Value const& in) throw(WrongType); - void plaincopy(Value const& in); - + 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 Changable { enum Value {Always, WhenIdle,OnlyAtStart};}; - Property(char const * const _propname):propname(_propname) { } - virtual void SetValue(char* input)=0; - virtual void GetValuestring(char* str) const=0; + 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;} - virtual ~Property(){ } - std::string propname; - //CheckValue returns true (and sets value to in) if value is in suggested_values; + //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) {if(forced || CheckValue(in,false)) value = in; else value = default_value;} + void SetVal(Value const& in, bool forced,bool warn=true) {if(forced || CheckValue(in,warn)) value = in; else value = default_value;} + virtual ~Property(){ } protected: Value value; std::vector suggested_values; typedef std::vector::iterator iter; Value default_value; - /*const*/ Changable::Value change; + const Changeable::Value change; }; class Prop_int:public Property { public: - Prop_int(char const * const _propname, int _value):Property(_propname) { + 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(char* input); - void GetValuestring(char* str) const; + 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(char const * const _propname, double _value):Property(_propname){ + Prop_double(std::string const & _propname, Changeable::Value when, double _value) + :Property(_propname,when){ default_value = value = _value; } - void SetValue(char* input); - void GetValuestring(char* str) const; + void SetValue(std::string const& input); ~Prop_double(){ } }; class Prop_bool:public Property { public: - Prop_bool(char const * const _propname, bool _value):Property(_propname) { + Prop_bool(std::string const& _propname, Changeable::Value when, bool _value) + :Property(_propname,when) { default_value = value = _value; } - void SetValue(char* input); - void GetValuestring(char* str) const; + void SetValue(std::string const& in); ~Prop_bool(){ } }; class Prop_string:public Property{ public: - Prop_string(char const * const _propname, char const * const _value):Property(_propname) { + Prop_string(std::string const& _propname, Changeable::Value when, char const * const _value) + :Property(_propname,when) { default_value = value = _value; } - void SetValue(char* input); - void GetValuestring(char* str) const; + void SetValue(std::string const& in); ~Prop_string(){ } - }; + class Prop_hex:public Property { public: - Prop_hex(char const * const _propname, int _value):Property(_propname) { - default_value = value._hex = _value; + Prop_hex(std::string const& _propname, Changeable::Value when, Hex _value) + :Property(_propname,when) { + default_value = value = _value; } - void SetValue(char* input); + void SetValue(std::string const& in); ~Prop_hex(){ } - void GetValuestring(char* str) const; }; +#define NO_SUCH_PROPERTY "PROP_NOT_EXIST" class Section { private: typedef void (*SectionFunction)(Section*); @@ -198,7 +224,7 @@ private: std::list destroyfunctions; std::string sectionname; public: - Section(char const * const _sectionname):sectionname(_sectionname) { } + Section(std::string const& _sectionname):sectionname(_sectionname) { } void AddInitFunction(SectionFunction func,bool canchange=false); void AddDestroyFunction(SectionFunction func,bool canchange=false); @@ -206,46 +232,61 @@ public: void ExecuteDestroy(bool destroyall=true); const char* GetName() const {return sectionname.c_str();} - virtual char const * GetPropValue(char const * const _property) const =0; - virtual void HandleInputline(char * _line)=0; + 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 Section_prop:public Section { private: std::list properties; typedef std::list::iterator it; typedef std::list::const_iterator const_it; + public: - Section_prop(char const * const _sectionname):Section(_sectionname){} - Prop_int& Add_int(char const * const _propname, int _value=0); - Prop_string& Add_string(char const * const _propname, char const * const _value=NULL); - Prop_bool& Add_bool(char const * const _propname, bool _value=false); - Prop_hex& Add_hex(char const * const _propname, int _value=0); - void Add_double(char const * const _propname, double _value=0.0); + 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_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); P + Prop_multival *Add_multi(std::string const& _propname, Property::Changeable::Value when,std::string const& sep); Property* Get_prop(int index); - int Get_int(char const * const _propname) const; - const char* Get_string(char const * const _propname) const; - bool Get_bool(char const * const _propname) const; - int Get_hex(char const * const _propname) const; - double Get_double(char const * const _propname) const; - void HandleInputline(char *gegevens); + 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_multival* Get_multival(std::string const& _propname) const; + void HandleInputline(std::string const& gegevens); void PrintData(FILE* outfile) const; - virtual char const * GetPropValue(char const * const _property) 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{ + Section_prop* section; + std::string seperator; +public: + Prop_multival(std::string const& _propname, Changeable::Value when,std::string const& sep):Property(_propname,when), section(new Section_prop("")),seperator(sep) { + value = ""; + } + Section_prop *GetSection() { return section; } + const Section_prop *GetSection() const { return section; } + void SetValue(std::string const& input); +}; //value bevat totalle string. setvalue zet elk van de sub properties en checked die. + class Section_line: public Section{ public: - Section_line(char const * const _sectionname):Section(_sectionname){} + Section_line(std::string const& _sectionname):Section(_sectionname){} ~Section_line(){ExecuteDestroy(true);} - void HandleInputline(char* gegevens); + void HandleInputline(std::string const& gegevens); void PrintData(FILE* outfile) const; - virtual const char* GetPropValue(char const * const _property) const; + virtual std::string GetPropValue(std::string const& _property) const; std::string data; }; @@ -267,7 +308,7 @@ public: Section_prop * AddSection_prop(char const * const _name,void (*_initfunction)(Section*),bool canchange=false); Section* GetSection(int index); - Section* GetSection(char const* const _sectionname) const; + Section* GetSection(std::string const&_sectionname) const; Section* GetSectionFromProperty(char const * const prop) const; void SetStartUp(void (*_function)(void)); diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index cb452b91..e0ff121a 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.107 2008-01-16 20:17:15 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.108 2008-02-10 11:14:03 qbix79 Exp $ */ #include #include @@ -2164,16 +2164,16 @@ public: CPU_Cycles=0; CPU_SkipCycleAutoAdjust=false; - std::string str; - CommandLine cmd(0,section->Get_string("cycles")); - cmd.FindCommand(1,str); - - if (str=="max") { + Prop_multival* p = section->Get_multival("cycles"); + std::string type = p->GetSection()->Get_string("type"); + std::string str ; + CommandLine cmd(0,p->GetSection()->Get_string("parameters")); + if (type=="max") { CPU_CycleMax=0; CPU_CyclePercUsed=100; CPU_CycleAutoAdjust=true; CPU_CycleLimit=-1; - for (Bitu cmdnum=2; cmdnum<=cmd.GetCount(); cmdnum++) { + for (Bitu cmdnum=1; cmdnum<=cmd.GetCount(); cmdnum++) { if (cmd.FindCommand(cmdnum,str)) { if (str.find('%')==str.length()-1) { str.erase(str.find('%')); @@ -2193,12 +2193,12 @@ public: } } } else { - if (str=="auto") { + if (type=="auto") { CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CYCLES; CPU_CycleMax=3000; CPU_OldCycleMax=3000; CPU_CyclePercUsed=100; - for (Bitu cmdnum=2; cmdnum<=cmd.GetCount(); cmdnum++) { + for (Bitu cmdnum=0; cmdnum<=cmd.GetCount(); cmdnum++) { if (cmd.FindCommand(cmdnum,str)) { if (str.find('%')==str.length()-1) { str.erase(str.find('%')); @@ -2225,7 +2225,8 @@ public: } } } - } else { + } else if(type =="fixed") { + cmd.FindCommand(1,str); int rmdval=0; std::istringstream stream(str); stream >> rmdval; diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 9e09b4df..957ba59d 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.127 2008-02-03 20:43:13 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.128 2008-02-10 11:14:03 qbix79 Exp $ */ #include #include @@ -270,57 +270,66 @@ static void DOSBOX_RealInit(Section * sec) { "# They are used to (briefly) document the effect of each option.\n"); MAPPER_AddHandler(DOSBOX_UnlockSpeed, MK_f12, MMOD2,"speedlock","Speedlock"); - svgaCard=SVGA_None; - machine=MCH_VGA; - int10.vesa_nolfb=false; std::string cmd_machine; - const char * mtype; - if (control->cmdline->FindString("-machine",cmd_machine,true)) mtype=cmd_machine.c_str(); - else mtype=section->Get_string("machine"); - if (strcasecmp(mtype,"cga")==0) machine=MCH_CGA; - else if (strcasecmp(mtype,"tandy")==0) machine=MCH_TANDY; - else if (strcasecmp(mtype,"pcjr")==0) machine=MCH_PCJR; - else if (strcasecmp(mtype,"hercules")==0) machine=MCH_HERC; - else if (strcasecmp(mtype,"ega")==0) machine=MCH_EGA; - else if ((strcasecmp(mtype,"vga")==0) || (strcasecmp(mtype,"vga_s3")==0) || - (strcasecmp(mtype,"svga")==0) || (strcasecmp(mtype,"svga_s3")==0)) { - machine=MCH_VGA; - svgaCard=SVGA_S3Trio; - } else if (strcasecmp(mtype,"vesa_nolfb")==0) { - machine=MCH_VGA; - svgaCard=SVGA_S3Trio; - int10.vesa_nolfb=true; - } else if ((strcasecmp(mtype,"vga_et4000")==0) || (strcasecmp(mtype,"svga_et4000")==0)) { - machine=MCH_VGA; - svgaCard=SVGA_TsengET4K; - } else if ((strcasecmp(mtype,"vga_et3000")==0) || (strcasecmp(mtype,"svga_et3000")==0)) { - machine=MCH_VGA; - svgaCard=SVGA_TsengET3K; - } else if ((strcasecmp(mtype,"vga_pvga1a")==0) || (strcasecmp(mtype,"svga_pvga1a")==0) || - (strcasecmp(mtype,"svga_paradise")==0)) { - machine=MCH_VGA; - svgaCard=SVGA_ParadisePVGA1A; - } else if (strcasecmp(mtype,"vgaonly")==0) { - machine=MCH_VGA; - svgaCard=SVGA_None; - } else { - LOG_MSG("DOSBOX:Unknown machine type %s",mtype); + if (control->cmdline->FindString("-machine",cmd_machine,true)){ + //update value in config (else no matching against suggested values + section->HandleInputline(std::string("machine=") + cmd_machine); } + + std::string mtype(section->Get_string("machine")); + svgaCard = SVGA_S3Trio; + machine = MCH_VGA; + int10.vesa_nolfb = false; + if (mtype == "cga") { machine = MCH_CGA; } + else if (mtype == "tandy") { machine = MCH_TANDY; } + else if (mtype == "pcjr") { machine = MCH_PCJR; } + else if (mtype == "hercules") { machine = MCH_HERC; } + else if (mtype == "ega") { machine = MCH_EGA; } + else if (mtype == "vga") { svgaCard = SVGA_S3Trio; } + else if (mtype == "vga_s3") { svgaCard = SVGA_S3Trio; } + else if (mtype == "vesa_nolfb") { svgaCard = SVGA_S3Trio; int10.vesa_nolfb = true;} + else if (mtype == "vga_et4000") { svgaCard = SVGA_TsengET4K; } + else if (mtype == "vga_et3000") { svgaCard = SVGA_TsengET3K; } + else if (mtype == "vga_pvga1a") { svgaCard = SVGA_ParadisePVGA1A; } + else if (mtype == "vga_paradise") { svgaCard = SVGA_ParadisePVGA1A; } + else if (mtype == "vgaonly") { svgaCard = SVGA_None; } + else E_Exit("DOSBOX:Unknown machine type %s",mtype.c_str()); } void DOSBOX_Init(void) { Section_prop * secprop; Section_line * secline; + Prop_int* Pint; + Prop_hex* Phex; + Prop_string* Pstring; + Prop_bool* Pbool; + Prop_multival* Pmulti; SDLNetInited = false; + // Some frequently used option sets + const char *rates[] = { "22050", "44100", "48000", "32000", "16000", "11025", "8000", 0 }; + const char *ios[] = { "220", "240", "260", "280", "2a0", "2c0", "2e0", "300", 0 }; + const char *irqs[] = { "3", "5", "7", "9", "10", "11", "12", 0 }; + const char *dmas[] = { "0", "1", "3", "5", "6", "7", 0 }; + + /* Setup all the different modules making up DOSBox */ - + const char* machines[] = { + "hercules", "cga"," tandy", "pcjr", "ega", "vga", + "vgaonly", "vga_s3", "vga_et3000", "vga_et4000", + "vga_pvga1a", "vga_paradise", "vesa_nolfb", 0 }; secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit); - secprop->Add_string("language",""); - secprop->Add_string("machine","vga"); - secprop->Add_string("captures","capture"); + Pstring = secprop->Add_string("language",Property::Changeable::Always,""); + Pstring->Set_help("Select another language file."); + + Pstring = secprop->Add_string("machine",Property::Changeable::OnlyAtStart,"vga"); + Pstring->Set_values(machines); + Pstring->Set_help("The type of machine tries to emulate."); + + Pstring = secprop->Add_string("captures",Property::Changeable::Always,"capture"); + Pstring->Set_help("Directory where things like wave, midi, screenshot get captured."); #if C_DEBUG LOG_StartUp(); @@ -330,58 +339,75 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&PAGING_Init);//done secprop->AddInitFunction(&MEM_Init);//done secprop->AddInitFunction(&HARDWARE_Init);//done - secprop->Add_int("memsize",16); + Pint = secprop->Add_int("memsize", Property::Changeable::WhenIdle,16); + Pint->SetMinMax(1,63); + Pint->Set_help("Amount of memory DOSBox has in megabytes."); secprop->AddInitFunction(&CALLBACK_Init); secprop->AddInitFunction(&PIC_Init);//done secprop->AddInitFunction(&PROGRAMS_Init); secprop->AddInitFunction(&TIMER_Init);//done secprop->AddInitFunction(&CMOS_Init);//done - - MSG_Add("DOSBOX_CONFIGFILE_HELP", - "language -- Select another language file.\n" - "memsize -- Amount of memory DOSBox has in megabytes.\n" - "machine -- The type of machine tries to emulate:hercules,cga,tandy,pcjr,vga.\n" - "captures -- Directory where things like wave,midi,screenshot get captured.\n" - ); secprop=control->AddSection_prop("render",&RENDER_Init,true); - secprop->Add_int("frameskip",0); - secprop->Add_bool("aspect",false); - secprop->Add_string("scaler","normal2x"); - MSG_Add("RENDER_CONFIGFILE_HELP", - "frameskip -- How many frames DOSBox skips before drawing one.\n" - "aspect -- Do aspect correction, if your output method doesn't support scaling this can slow things down!.\n" - "scaler -- Scaler used to enlarge/enhance low resolution modes.\n" - " Supported are none,normal2x,normal3x,advmame2x,advmame3x,hq2x,hq3x,\n" - " 2xsai,super2xsai,supereagle,advinterp2x,advinterp3x,\n" - " tv2x,tv3x,rgb2x,rgb3x,scan2x,scan3x.\n" - " If forced is appended (like scaler=hq2x forced), the scaler will be used\n" - " even if the result might not be desired.\n" - ); + Pint = secprop->Add_int("frameskip",Property::Changeable::Always,0); + Pint->SetMinMax(0,10); + Pint->Set_help("How many frames DOSBox skips before drawing one."); + + Pbool = secprop->Add_bool("aspect",Property::Changeable::Always,false); + Pbool->Set_help("Do aspect correction, if your output method doesn't support scaling this can slow things down!."); + + Pmulti = secprop->Add_multi("scaler",Property::Changeable::Always," "); + Pmulti->Set_help("Scaler used to enlarge/enhance low resolution modes. If 'forced' is appended,the scaler will be used even if the result might not be desired."); + Pstring = Pmulti->GetSection()->Add_string("type",Property::Changeable::Always,"normal2x"); + + const char *scalers[] = { + "none", "normal2x", "normal3x", +#if RENDER_USE_ADVANCED_SCALERS>2 + "advmame2x", "advmame3x", "advinterp2x", "advinterp3x", "hq2x", "hq3x", "2xsai", "super2xsai", "supereagle", +#endif +#if RENDER_USE_ADVANCED_SCALERS>0 + "tv2x", "tv3x", "rgb2x", "rgb3x", "scan2x", "scan3x", +#endif + 0 }; + Pstring->Set_values(scalers); + + const char* force[] = { "", "forced", 0 }; + Pstring = Pmulti->GetSection()->Add_string("force",Property::Changeable::Always,""); + Pstring->Set_values(force); secprop=control->AddSection_prop("cpu",&CPU_Init,true);//done + const char* cores[] = { "auto", #if (C_DYNAMIC_X86) || (C_DYNREC) - secprop->Add_string("core","auto"); -#else - secprop->Add_string("core","normal"); + "dynamic", #endif - secprop->Add_string("cycles","auto"); - secprop->Add_int("cycleup",500); - secprop->Add_int("cycledown",20); - MSG_Add("CPU_CONFIGFILE_HELP", - "core -- CPU Core used in emulation: normal,simple" -#if (C_DYNAMIC_X86) || (C_DYNREC) - ",dynamic,auto.\n" - " auto switches from normal to dynamic if appropriate" -#endif - ".\n" - "cycles -- Amount of instructions DOSBox tries to emulate each millisecond.\n" - " Setting this value too high results in sound dropouts and lags.\n" - " You can also let DOSBox guess the correct value by setting it to max.\n" - " The default setting (auto) switches to max if appropriate.\n" - "cycleup -- Amount of cycles to increase/decrease with keycombo.\n" - "cycledown Setting it lower than 100 will be a percentage.\n" - ); + "normal", "simple",0 }; + Pstring = secprop->Add_string("core",Property::Changeable::WhenIdle,"auto"); + Pstring->Set_values(cores); + Pstring->Set_help("CPU Core used in emulation. auto will switch to dynamic if available and appropriate."); + + Pmulti = secprop->Add_multi("cycles",Property::Changeable::Always," "); + Pmulti->Set_help( + "Amount of instructions DOSBox tries to emulate each millisecond. Setting this value too high results in sound dropouts and lags. Cycles can be set in 3 ways:" + " 'auto' tries to guess what a game needs.\n" + " It usually works, but can fail for certain games.\n" + " 'fixed #number' will set a fixed amount of cycles. This is what you usually need if 'auto' fails.\n" + " (Example: fixed 4000)\n" + " 'max' will allocate as much cycles as your computer is able to handle\n"); + + const char* cyclest[] = { "auto","fixed","max" }; + Pstring = Pmulti->GetSection()->Add_string("type",Property::Changeable::Always,"auto"); + Pstring->Set_values(cyclest); + + Pstring = Pmulti->GetSection()->Add_string("parameters",Property::Changeable::Always,""); + + Pint = secprop->Add_int("cycleup",Property::Changeable::Always,500); + Pint->SetMinMax(1,1000000); + Pint->Set_help("Amount of cycles to increase/decrease with keycombo."); + + Pint = secprop->Add_int("cycledown",Property::Changeable::Always,20); + Pint->SetMinMax(1,1000000); + Pint->Set_help("Setting it lower than 100 will be a percentage."); + #if C_FPU secprop->AddInitFunction(&FPU_Init); #endif @@ -390,168 +416,229 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&KEYBOARD_Init); secprop=control->AddSection_prop("mixer",&MIXER_Init); - secprop->Add_bool("nosound",false); - secprop->Add_int("rate",22050); - secprop->Add_int("blocksize",2048); - secprop->Add_int("prebuffer",10); + Pbool = secprop->Add_bool("nosound",Property::Changeable::OnlyAtStart,false); + Pbool->Set_help("Enable silent mode, sound is still emulated though."); - MSG_Add("MIXER_CONFIGFILE_HELP", - "nosound -- Enable silent mode, sound is still emulated though.\n" - "rate -- Mixer sample rate, setting any devices higher than this will\n" - " probably lower their sound quality.\n" - "blocksize -- Mixer block size, larger blocks might help sound stuttering\n" - " but sound will also be more lagged.\n" - "prebuffer -- How many milliseconds of data to keep on top of the blocksize.\n" - ); + Pint = secprop->Add_int("rate",Property::Changeable::OnlyAtStart,22050); + Pint->Set_values(rates); + Pint->Set_help("Mixer sample rate, setting any devices higher than this will probably lower their sound quality."); + + const char *blocksizes[] = { + "2048", "4096", "8192", "1024", "512", "256", 0}; + Pint = secprop->Add_int("blocksize",Property::Changeable::OnlyAtStart,2048); + Pint->Set_values(blocksizes); + Pint->Set_help("Mixer block size, larger blocks might help sound stuttering but sound will also be more lagged."); + + Pint = secprop->Add_int("prebuffer",Property::Changeable::OnlyAtStart,10); + Pint->SetMinMax(0,100); + Pint->Set_help("How many milliseconds of data to keep on top of the blocksize."); secprop=control->AddSection_prop("midi",&MIDI_Init,true);//done secprop->AddInitFunction(&MPU401_Init,true);//done - secprop->Add_string("mpu401","intelligent"); - secprop->Add_string("device","default"); - secprop->Add_string("config",""); - MSG_Add("MIDI_CONFIGFILE_HELP", - "mpu401 -- Type of MPU-401 to emulate: none, uart or intelligent.\n" - "device -- Device that will receive the MIDI data from MPU-401.\n" - " This can be default,alsa,oss,win32,coreaudio,coremidi,none.\n" - "config -- Special configuration options for the device. In Windows put\n" - " the id of the device you want to use. See README for details.\n" - ); + const char* mputypes[] = { "intelligent", "uart", "none",0}; + // FIXME: add some way to offer the actually available choices. + const char *devices[] = { "default", "win32", "alsa", "oss", "coreaudio", "coremidi","none", 0}; + Pstring = secprop->Add_string("mpu401",Property::Changeable::WhenIdle,"intelligent"); + Pstring->Set_values(mputypes); + Pstring->Set_help("Type of MPU-401 to emulate."); + + Pstring = secprop->Add_string("device",Property::Changeable::WhenIdle,"default"); + Pstring->Set_values(devices); + Pstring->Set_help("Device that will receive the MIDI data from MPU-401."); + + Pstring = secprop->Add_string("config",Property::Changeable::WhenIdle,""); + Pstring->Set_help("Special configuration options for the device driver. This is usually the id of the device you want to use. See README for details."); #if C_DEBUG secprop=control->AddSection_prop("debug",&DEBUG_Init); #endif secprop=control->AddSection_prop("sblaster",&SBLASTER_Init,true);//done - secprop->Add_string("sbtype","sb16"); - secprop->Add_hex("sbbase",0x220); - secprop->Add_int("irq",7); - secprop->Add_int("dma",1); - secprop->Add_int("hdma",5); - secprop->Add_bool("mixer",true); - secprop->Add_string("oplmode","auto"); - secprop->Add_int("oplrate",22050); + + const char* sbtypes[] = { "sb1", "sb2", "sbpro1", "sbpro2", "sb16", "none", 0 }; + Pstring = secprop->Add_string("sbtype",Property::Changeable::WhenIdle,"sb16"); + Pstring->Set_values(sbtypes); + Pstring->Set_help("Type of sblaster to emulate."); + + Phex = secprop->Add_hex("sbbase",Property::Changeable::WhenIdle,0x220); + Phex->Set_values(ios); + Phex->Set_help("The IO address of the soundblaster."); + + Pint = secprop->Add_int("irq",Property::Changeable::WhenIdle,7); + Pint->Set_values(irqs); + Pint->Set_help("The IRQ number of the soundblaster."); + + Pint = secprop->Add_int("dma",Property::Changeable::WhenIdle,1); + Pint->Set_values(dmas); + Pint->Set_help("The DMA number of the soundblaster."); + + Pint = secprop->Add_int("hdma",Property::Changeable::WhenIdle,5); + Pint->Set_values(dmas); + Pint->Set_help("The High DMA number of the soundblaster."); + + Pbool = secprop->Add_bool("mixer",Property::Changeable::WhenIdle,true); + Pbool->Set_help("Allow the soundblaster mixer to modify the DOSBox mixer."); + + const char* opltypes[]={ "auto", "cms", "opl2", "dualopl2", "opl3", "none", 0}; + Pstring = secprop->Add_string("oplmode",Property::Changeable::WhenIdle,"auto"); + Pstring->Set_values(opltypes); + Pstring->Set_help("Type of OPL emulation. On 'auto' the mode is determined by sblaster type. All OPL modes are Adlib-compatible, except for 'cms'."); + + Pint = secprop->Add_int("oplrate",Property::Changeable::WhenIdle,22050); + Pint->Set_values(rates); + Pint->Set_help("Sample rate of OPL music emulation."); - MSG_Add("SBLASTER_CONFIGFILE_HELP", - "sbtype -- Type of sblaster to emulate:none,sb1,sb2,sbpro1,sbpro2,sb16.\n" - "sbbase,irq,dma,hdma -- The IO/IRQ/DMA/High DMA address of the soundblaster.\n" - "mixer -- Allow the soundblaster mixer to modify the DOSBox mixer.\n" - "oplmode -- Type of OPL emulation: auto,cms,opl2,dualopl2,opl3.\n" - " On auto the mode is determined by sblaster type.\n" - " All OPL modes are 'Adlib', except for CMS.\n" - "oplrate -- Sample rate of OPL music emulation.\n" - ); secprop=control->AddSection_prop("gus",&GUS_Init,true); //done - secprop->Add_bool("gus",true); - secprop->Add_int("gusrate",22050); - secprop->Add_hex("gusbase",0x240); - secprop->Add_int("irq1",5); - secprop->Add_int("irq2",5); - secprop->Add_int("dma1",3); - secprop->Add_int("dma2",3); - secprop->Add_string("ultradir","C:\\ULTRASND"); + Pbool = secprop->Add_bool("gus",Property::Changeable::WhenIdle,true); + Pbool->Set_help("Enable the Gravis Ultrasound emulation."); - MSG_Add("GUS_CONFIGFILE_HELP", - "gus -- Enable the Gravis Ultrasound emulation.\n" - "gusbase,irq1,irq2,dma1,dma2 -- The IO/IRQ/DMA addresses of the \n" - " Gravis Ultrasound. (Same IRQ's and DMA's are OK.)\n" - "gusrate -- Sample rate of Ultrasound emulation.\n" - "ultradir -- Path to Ultrasound directory. In this directory\n" - " there should be a MIDI directory that contains\n" - " the patch files for GUS playback. Patch sets used\n" - " with Timidity should work fine.\n" - ); + Pint = secprop->Add_int("gusrate",Property::Changeable::WhenIdle,22050); + Pint->Set_values(rates); + Pint->Set_help("Sample rate of Ultrasound emulation."); + + Phex = secprop->Add_hex("gusbase",Property::Changeable::WhenIdle,0x240); + Phex->Set_values(ios); + Phex->Set_help("The IO addresses of the Gravis Ultrasound."); + + Pint = secprop->Add_int("irq1",Property::Changeable::WhenIdle,5); + Pint->Set_values(irqs); + Pint->Set_help("The first IRQ number of the Gravis Ultrasound. (Same IRQs are OK.)"); + + Pint = secprop->Add_int("irq2",Property::Changeable::WhenIdle,5); + Pint->Set_values(irqs); + Pint->Set_help("The second IRQ number of the Gravis Ultrasound. (Same IRQs are OK.)"); + + Pint = secprop->Add_int("dma1",Property::Changeable::WhenIdle,3); + Pint->Set_values(dmas); + Pint->Set_help("The first DMA addresses of the Gravis Ultrasound. (Same DMAs are OK.)"); + + Pint = secprop->Add_int("dma2",Property::Changeable::WhenIdle,3); + Pint->Set_values(dmas); + Pint->Set_help("The second DMA addresses of the Gravis Ultrasound. (Same DMAs are OK.)"); + + Pstring = secprop->Add_string("ultradir",Property::Changeable::WhenIdle,"C:\\ULTRASND"); + Pstring->Set_help( + "Path to Ultrasound directory. In this directory\n" + "there should be a MIDI directory that contains\n" + "the patch files for GUS playback. Patch sets used\n" + "with Timidity should work fine."); + + secprop = control->AddSection_prop("speaker",&PCSPEAKER_Init,true);//done + Pbool = secprop->Add_bool("pcspeaker",Property::Changeable::WhenIdle,true); + Pbool->Set_help("Enable PC-Speaker emulation."); + + Pint = secprop->Add_int("pcrate",Property::Changeable::WhenIdle,22050); + Pint->Set_values(rates); + Pint->Set_help("Sample rate of the PC-Speaker sound generation."); - secprop=control->AddSection_prop("speaker",&PCSPEAKER_Init,true);//done - secprop->Add_bool("pcspeaker",true); - secprop->Add_int("pcrate",22050); secprop->AddInitFunction(&TANDYSOUND_Init,true);//done - secprop->Add_string("tandy","auto"); - secprop->Add_int("tandyrate",22050); - secprop->AddInitFunction(&DISNEY_Init,true);//done - secprop->Add_bool("disney",true); + const char* tandys[] = { "auto", "on", "off", 0}; + Pstring = secprop->Add_string("tandy",Property::Changeable::WhenIdle,"auto"); + Pstring->Set_values(tandys); + Pstring->Set_help("Enable Tandy Sound System emulation. For 'auto', emulation is present only if machine is set to 'tandy'."); + + Pint = secprop->Add_int("tandyrate",Property::Changeable::WhenIdle,22050); + Pint->Set_values(rates); + Pint->Set_help("Sample rate of the Tandy 3-Voice generation."); - MSG_Add("SPEAKER_CONFIGFILE_HELP", - "pcspeaker -- Enable PC-Speaker emulation.\n" - "pcrate -- Sample rate of the PC-Speaker sound generation.\n" - "tandy -- Enable Tandy Sound System emulation (off,on,auto).\n" - " For auto Tandysound emulation is present only if machine is set to tandy.\n" - "tandyrate -- Sample rate of the Tandy 3-Voice generation.\n" - "disney -- Enable Disney Sound Source emulation. Covox Voice Master and Speech Thing compatible.\n" - ); + secprop->AddInitFunction(&DISNEY_Init,true);//done + + Pbool = secprop->Add_bool("disney",Property::Changeable::WhenIdle,true); + Pbool->Set_help("Enable Disney Sound Source emulation. (Covox Voice Master and Speech Thing compatible)."); secprop=control->AddSection_prop("joystick",&BIOS_Init,false);//done - MSG_Add("JOYSTICK_CONFIGFILE_HELP", - "joysticktype -- Type of joystick to emulate: auto (default), none,\n" - " 2axis (supports two joysticks,\n" - " 4axis (supports one joystick, first joystick used),\n" - " 4axis_2 (supports one joystick, second joystick used),\n" - " fcs (Thrustmaster), ch (CH Flightstick).\n" - " none disables joystick emulation.\n" - " auto chooses emulation depending on real joystick(s).\n" - "timed -- enable timed intervals for axis. (false is old style behaviour).\n" - "autofire -- continuously fires as long as you keep the button pressed.\n" - "swap34 -- swap the 3rd and the 4th axis. can be useful for certain joysticks.\n" - "buttonwrap -- enable button wrapping at the number of emulated buttons.\n" - ); - secprop->AddInitFunction(&INT10_Init); secprop->AddInitFunction(&MOUSE_Init); //Must be after int10 as it uses CurMode secprop->AddInitFunction(&JOYSTICK_Init); - secprop->Add_string("joysticktype","auto"); - secprop->Add_bool("timed",true); - secprop->Add_bool("autofire",false); - secprop->Add_bool("swap34",false); - secprop->Add_bool("buttonwrap",true); + const char* joytypes[] = { "auto", "2axis", "4axis", "4axis_2", "fcs", "ch", "none",0}; + Pstring = secprop->Add_string("joysticktype",Property::Changeable::WhenIdle,"auto"); + Pstring->Set_values(joytypes); + Pstring->Set_help( + "Type of joystick to emulate: auto (default), none,\n" + "2axis (supports two joysticks),\n" + "4axis (supports one joystick, first joystick used),\n" + "4axis_2 (supports one joystick, second joystick used),\n" + "fcs (Thrustmaster), ch (CH Flightstick).\n" + "none disables joystick emulation.\n" + "auto chooses emulation depending on real joystick(s)."); + + Pbool = secprop->Add_bool("timed",Property::Changeable::WhenIdle,true); + Pbool->Set_help("enable timed intervals for axis. (false is old style behaviour)."); + + Pbool = secprop->Add_bool("autofire",Property::Changeable::WhenIdle,false); + Pbool->Set_help("continuously fires as long as you keep the button pressed."); + + Pbool = secprop->Add_bool("swap34",Property::Changeable::WhenIdle,false); + Pbool->Set_help("swap the 3rd and the 4th axis. can be useful for certain joysticks."); + + Pbool = secprop->Add_bool("buttonwrap",Property::Changeable::WhenIdle,true); + Pbool->Set_help("enable button wrapping at the number of emulated buttons."); - // had to rename these to serial due to conflicts in config secprop=control->AddSection_prop("serial",&SERIAL_Init,true); - secprop->Add_string("serial1","dummy"); - secprop->Add_string("serial2","dummy"); - secprop->Add_string("serial3","disabled"); - secprop->Add_string("serial4","disabled"); - MSG_Add("SERIAL_CONFIGFILE_HELP", - "serial1-4 -- set type of device connected to com port.\n" - " Can be disabled, dummy, modem, nullmodem, directserial.\n" - " Additional parameters must be in the same line in the form of\n" - " parameter:value. Parameter for all types is irq.\n" - " for directserial: realport (required), rxdelay (optional).\n" - " for modem: listenport (optional).\n" - " for nullmodem: server, rxdelay, txdelay, telnet, usedtr,\n" - " transparent, port, inhsocket (all optional).\n" - " Example: serial1=modem listenport:5000\n" - ); + const char* serials[] = { "dummy", "disabled", "modem", "nullmodem", +#if defined(WIN32) || defined(OS2) + "directserial realport:COM1", "directserial realport:COM2", +#else + "directserial realport:ttyS0", "directserial realport:ttyS1", +#endif + 0}; + + Pstring = secprop->Add_string("serial1",Property::Changeable::WhenIdle,"dummy"); + Pstring->Set_values(serials); + Pstring->Set_help( + "set type of device connected to com port.\n" + "Can be disabled, dummy, modem, nullmodem, directserial.\n" + "Additional parameters must be in the same line in the form of\n" + "parameter:value. Parameter for all types is irq.\n" + "for directserial: realport (required), rxdelay (optional).\n" + "for modem: listenport (optional).\n" + "for nullmodem: server, rxdelay, txdelay, telnet, usedtr,\n" + " transparent, port, inhsocket (all optional).\n" + "Example: serial1=modem listenport:5000"); + + Pstring = secprop->Add_string("serial2",Property::Changeable::WhenIdle,"dummy"); + Pstring->Set_values(serials); + Pstring->Set_help("see serial1"); + + Pstring = secprop->Add_string("serial3",Property::Changeable::WhenIdle,"disabled"); + Pstring->Set_values(serials); + Pstring->Set_help("see serial1"); + + Pstring = secprop->Add_string("serial4",Property::Changeable::WhenIdle,"disabled"); + Pstring->Set_values(serials); + Pstring->Set_help("see serial1"); /* All the DOS Related stuff, which will eventually start up in the shell */ - //TODO Maybe combine most of the dos stuff in one section like ems,xms secprop=control->AddSection_prop("dos",&DOS_Init,false);//done secprop->AddInitFunction(&XMS_Init,true);//done - secprop->Add_bool("xms",true); + Pbool = secprop->Add_bool("xms",Property::Changeable::WhenIdle,true); + Pbool->Set_help("Enable XMS support."); + secprop->AddInitFunction(&EMS_Init,true);//done - secprop->Add_bool("ems",true); - secprop->Add_bool("umb",true); + Pbool = secprop->Add_bool("ems",Property::Changeable::WhenIdle,true); + Pbool->Set_help("Enable EMS support."); + + Pbool = secprop->Add_bool("umb",Property::Changeable::WhenIdle,true); + Pbool->Set_help("Enable UMB support."); + secprop->AddInitFunction(&DOS_KeyboardLayout_Init,true); - secprop->Add_string("keyboardlayout", "none"); - MSG_Add("DOS_CONFIGFILE_HELP", - "xms -- Enable XMS support.\n" - "ems -- Enable EMS support.\n" - "umb -- Enable UMB support.\n" - "keyboardlayout -- Language code of the keyboard layout (or none).\n" - ); + Pstring = secprop->Add_string("keyboardlayout",Property::Changeable::WhenIdle, "none"); + Pstring->Set_help("Language code of the keyboard layout (or none)."); + // Mscdex secprop->AddInitFunction(&MSCDEX_Init); secprop->AddInitFunction(&DRIVES_Init); secprop->AddInitFunction(&CDROM_Image_Init); #if C_IPX secprop=control->AddSection_prop("ipx",&IPX_Init,true); - secprop->Add_bool("ipx", false); - MSG_Add("IPX_CONFIGFILE_HELP", - "ipx -- Enable ipx over UDP/IP emulation.\n" - ); + Pbool = secprop->Add_bool("ipx",Property::Changeable::WhenIdle, false); + Pbool->Set_help("Enable ipx over UDP/IP emulation."); #endif // secprop->AddInitFunction(&CREDITS_Init); + //TODO ? secline=control->AddSection_line("autoexec",&AUTOEXEC_Init); MSG_Add("AUTOEXEC_CONFIGFILE_HELP", "Lines in this section will be run at startup.\n" diff --git a/src/gui/render.cpp b/src/gui/render.cpp index a3de853d..698a8376 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.55 2007-08-11 12:19:00 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.56 2008-02-10 11:14:03 qbix79 Exp $ */ #include #include @@ -571,53 +571,43 @@ void RENDER_Init(Section * sec) { render.aspect=section->Get_bool("aspect"); render.frameskip.max=section->Get_int("frameskip"); render.frameskip.count=0; - const char * scaler; std::string cline; - std::string scaler_str; + std::string scaler; + //Check for commandline paramters and parse them through the configclass so they get checked against allowed values if (control->cmdline->FindString("-scaler",cline,false)) { - scaler=cline.c_str(); - render.scale.forced=false; + section->HandleInputline(std::string("scaler=") + cline); } else if (control->cmdline->FindString("-forcescaler",cline,false)) { - scaler=cline.c_str(); - render.scale.forced=true; - } else { - CommandLine cmd(0,section->Get_string("scaler")); - cmd.FindCommand(1,scaler_str); - scaler=scaler_str.c_str(); - render.scale.forced=false; - if (cmd.GetCount()>1) { - std::string str; - if (cmd.FindCommand(2,str)) { - if (str=="forced") render.scale.forced=true; - } - } + section->HandleInputline(std::string("scaler=") + cline + " forced"); } - if (!strcasecmp(scaler,"none")) { render.scale.op = scalerOpNormal;render.scale.size = 1; } - else if (!strcasecmp(scaler,"normal2x")) { render.scale.op = scalerOpNormal;render.scale.size = 2; } - else if (!strcasecmp(scaler,"normal3x")) { render.scale.op = scalerOpNormal;render.scale.size = 3; } + + Prop_multival* prop = section->Get_multival("scaler"); + scaler = prop->GetSection()->Get_string("type"); + std::string f = prop->GetSection()->Get_string("force"); + render.scale.forced = false; + if(f == "forced") render.scale.forced = true; + + if (scaler == "none") { render.scale.op = scalerOpNormal;render.scale.size = 1; } + else if (scaler == "normal2x") { render.scale.op = scalerOpNormal;render.scale.size = 2; } + else if (scaler == "normal3x") { render.scale.op = scalerOpNormal;render.scale.size = 3; } #if RENDER_USE_ADVANCED_SCALERS>2 - else if (!strcasecmp(scaler,"advmame2x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 2; } - else if (!strcasecmp(scaler,"advmame3x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 3; } - else if (!strcasecmp(scaler,"advinterp2x")) { render.scale.op = scalerOpAdvInterp;render.scale.size = 2; } - else if (!strcasecmp(scaler,"advinterp3x")) { render.scale.op = scalerOpAdvInterp;render.scale.size = 3; } - else if (!strcasecmp(scaler,"hq2x")) { render.scale.op = scalerOpHQ;render.scale.size = 2; } - else if (!strcasecmp(scaler,"hq3x")) { render.scale.op = scalerOpHQ;render.scale.size = 3; } - else if (!strcasecmp(scaler,"2xsai")) { render.scale.op = scalerOpSaI;render.scale.size = 2; } - else if (!strcasecmp(scaler,"super2xsai")) { render.scale.op = scalerOpSuperSaI;render.scale.size = 2; } - else if (!strcasecmp(scaler,"supereagle")) { render.scale.op = scalerOpSuperEagle;render.scale.size = 2; } + else if (scaler == "advmame2x") { render.scale.op = scalerOpAdvMame;render.scale.size = 2; } + else if (scaler == "advmame3x") { render.scale.op = scalerOpAdvMame;render.scale.size = 3; } + else if (scaler == "advinterp2x") { render.scale.op = scalerOpAdvInterp;render.scale.size = 2; } + else if (scaler == "advinterp3x") { render.scale.op = scalerOpAdvInterp;render.scale.size = 3; } + else if (scaler == "hq2x") { render.scale.op = scalerOpHQ;render.scale.size = 2; } + else if (scaler == "hq3x") { render.scale.op = scalerOpHQ;render.scale.size = 3; } + else if (scaler == "2xsai") { render.scale.op = scalerOpSaI;render.scale.size = 2; } + else if (scaler == "super2xsai") { render.scale.op = scalerOpSuperSaI;render.scale.size = 2; } + else if (scaler == "supereagle") { render.scale.op = scalerOpSuperEagle;render.scale.size = 2; } #endif #if RENDER_USE_ADVANCED_SCALERS>0 - else if (!strcasecmp(scaler,"tv2x")) { render.scale.op = scalerOpTV;render.scale.size = 2; } - else if (!strcasecmp(scaler,"tv3x")) { render.scale.op = scalerOpTV;render.scale.size = 3; } - else if (!strcasecmp(scaler,"rgb2x")){ render.scale.op = scalerOpRGB;render.scale.size = 2; } - else if (!strcasecmp(scaler,"rgb3x")){ render.scale.op = scalerOpRGB;render.scale.size = 3; } - else if (!strcasecmp(scaler,"scan2x")){ render.scale.op = scalerOpScan;render.scale.size = 2; } - else if (!strcasecmp(scaler,"scan3x")){ render.scale.op = scalerOpScan;render.scale.size = 3; } + else if (scaler == "tv2x") { render.scale.op = scalerOpTV;render.scale.size = 2; } + else if (scaler == "tv3x") { render.scale.op = scalerOpTV;render.scale.size = 3; } + else if (scaler == "rgb2x"){ render.scale.op = scalerOpRGB;render.scale.size = 2; } + else if (scaler == "rgb3x"){ render.scale.op = scalerOpRGB;render.scale.size = 3; } + else if (scaler == "scan2x"){ render.scale.op = scalerOpScan;render.scale.size = 2; } + else if (scaler == "scan3x"){ render.scale.op = scalerOpScan;render.scale.size = 3; } #endif - else { - render.scale.op = scalerOpNormal;render.scale.size = 1; - LOG_MSG("Illegal scaler type %s,falling back to normal.",scaler); - } //If something changed that needs a ReInit // Only ReInit when there is a src.bpp (fixes crashes on startup and directly changing the scaler without a screen specified yet) diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index 6a1a900c..4197ff59 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_gui.cpp,v 1.4 2008-01-26 15:50:19 qbix79 Exp $ */ +/* $Id: sdl_gui.cpp,v 1.5 2008-02-10 11:14:03 qbix79 Exp $ */ #include "SDL.h" #include "../libs/gui_tk/gui_tk.h" @@ -281,11 +281,11 @@ public: PropertyEditorBool(Window *parent, int x, int y, Section_prop *section, Property *prop) : PropertyEditor(parent, x, y, section, prop) { input = new GUI::Checkbox(this, 0, 3, prop->propname.c_str()); - input->setChecked(prop->GetValue()._bool); + input->setChecked(static_cast(prop->GetValue())); } bool prepare(std::string &buffer) { - if (input->isChecked() == prop->GetValue()._bool) return false; + if (input->isChecked() == static_cast(prop->GetValue())) return false; buffer.append(input->isChecked()?"true":"false"); return true; } @@ -299,11 +299,13 @@ public: PropertyEditor(parent, x, y, section, prop) { new GUI::Label(this, 0, 5, prop->propname); input = new GUI::Input(this, 130, 0, 110); - input->setText(prop->GetValue()._string); + std::string temps = prop->GetValue().ToString(); + input->setText(stringify(temps)); } bool prepare(std::string &buffer) { - if (input->getText() == GUI::String(prop->GetValue()._string)) return false; + std::string temps = prop->GetValue().ToString(); + if (input->getText() == GUI::String(temps)) return false; buffer.append(static_cast(input->getText())); return true; } @@ -337,13 +339,14 @@ public: PropertyEditor(parent, x, y, section, prop) { new GUI::Label(this, 0, 5, prop->propname); input = new GUI::Input(this, 130, 0, 50); - input->setText(stringify(prop->GetValue()._hex, std::hex)); + std::string temps = prop->GetValue().ToString(); + input->setText(temps.c_str()); } bool prepare(std::string &buffer) { int val; convert(input->getText(), val, false, std::hex); - if (val == prop->GetValue()._hex) return false; + if ((Hex)val == prop->GetValue()) return false; buffer.append(stringify(val, std::hex)); return true; } @@ -357,13 +360,14 @@ public: PropertyEditor(parent, x, y, section, prop) { new GUI::Label(this, 0, 5, prop->propname); input = new GUI::Input(this, 130, 0, 50); - input->setText(stringify(prop->GetValue()._int)); + //Maybe use ToString() of Value + input->setText(stringify(static_cast(prop->GetValue()))); } bool prepare(std::string &buffer) { int val; convert(input->getText(), val, false); - if (val == prop->GetValue()._int) return false; + if (val == static_cast(prop->GetValue())) return false; buffer.append(stringify(val)); return true; } diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 64c5ddaa..3a1486ae 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.138 2008-01-16 20:17:15 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.139 2008-02-10 11:14:03 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -938,48 +938,29 @@ static void GUI_StartUp(Section * sec) { sdl.desktop.fullscreen=section->Get_bool("fullscreen"); sdl.wait_on_error=section->Get_bool("waitonerror"); - const char * priority=section->Get_string("priority"); - if (priority && priority[0]) { - Bitu next; - if (!strncasecmp(priority,"lowest",6)) { - sdl.priority.focus=PRIORITY_LEVEL_LOWEST;next=6; - } else if (!strncasecmp(priority,"lower",5)) { - sdl.priority.focus=PRIORITY_LEVEL_LOWER;next=5; - } else if (!strncasecmp(priority,"normal",6)) { - sdl.priority.focus=PRIORITY_LEVEL_NORMAL;next=6; - } else if (!strncasecmp(priority,"higher",6)) { - sdl.priority.focus=PRIORITY_LEVEL_HIGHER;next=6; - } else if (!strncasecmp(priority,"highest",7)) { - sdl.priority.focus=PRIORITY_LEVEL_HIGHEST;next=7; - } else { - next=0;sdl.priority.focus=PRIORITY_LEVEL_HIGHER; - } - priority=&priority[next]; - if (next && priority[0]==',' && priority[1]) { - priority++; - if (!strncasecmp(priority,"lowest",6)) { - sdl.priority.nofocus=PRIORITY_LEVEL_LOWEST; - } else if (!strncasecmp(priority,"lower",5)) { - sdl.priority.nofocus=PRIORITY_LEVEL_LOWER; - } else if (!strncasecmp(priority,"normal",6)) { - sdl.priority.nofocus=PRIORITY_LEVEL_NORMAL; - } else if (!strncasecmp(priority,"higher",6)) { - sdl.priority.nofocus=PRIORITY_LEVEL_HIGHER; - } else if (!strncasecmp(priority,"highest",7)) { - sdl.priority.nofocus=PRIORITY_LEVEL_HIGHEST; - } else if (!strncasecmp(priority,"pause",5)) { - /* we only check for pause here, because it makes no sense - * for DOSBox to be paused while it has focus - */ - sdl.priority.nofocus=PRIORITY_LEVEL_PAUSE; - } else { - sdl.priority.nofocus=PRIORITY_LEVEL_NORMAL; - } - } else sdl.priority.nofocus=sdl.priority.focus; - } else { - sdl.priority.focus=PRIORITY_LEVEL_HIGHER; - sdl.priority.nofocus=PRIORITY_LEVEL_NORMAL; + + Prop_multival* p=section->Get_multival("priority"); + std::string focus = p->GetSection()->Get_string("active"); + std::string notfocus = p->GetSection()->Get_string("inactive"); + + if (focus == "lowest") { sdl.priority.focus = PRIORITY_LEVEL_LOWEST; } + else if (focus == "lower") { sdl.priority.focus = PRIORITY_LEVEL_LOWER; } + else if (focus == "normal") { sdl.priority.focus = PRIORITY_LEVEL_NORMAL; } + else if (focus == "higher") { sdl.priority.focus = PRIORITY_LEVEL_HIGHER; } + else if (focus == "highest") { sdl.priority.focus = PRIORITY_LEVEL_HIGHEST; } + + if (notfocus == "lowest") { sdl.priority.nofocus=PRIORITY_LEVEL_LOWEST; } + else if (notfocus == "lower") { sdl.priority.nofocus=PRIORITY_LEVEL_LOWER; } + else if (notfocus == "normal") { sdl.priority.nofocus=PRIORITY_LEVEL_NORMAL; } + else if (notfocus == "higher") { sdl.priority.nofocus=PRIORITY_LEVEL_HIGHER; } + else if (notfocus == "highest") { sdl.priority.nofocus=PRIORITY_LEVEL_HIGHEST; } + else if (notfocus == "pause") { + /* we only check for pause here, because it makes no sense + * for DOSBox to be paused while it has focus + */ + sdl.priority.nofocus=PRIORITY_LEVEL_PAUSE; } + SetPriority(sdl.priority.focus); //Assume focus on startup sdl.mouse.locked=false; mouselocked=false; //Global for mapper @@ -1038,30 +1019,30 @@ static void GUI_StartUp(Section * sec) { if (!sdl.mouse.autoenable) SDL_ShowCursor(SDL_DISABLE); sdl.mouse.autolock=false; sdl.mouse.sensitivity=section->Get_int("sensitivity"); - const char * output=section->Get_string("output"); + std::string output=section->Get_string("output"); /* Setup Mouse correctly if fullscreen */ if(sdl.desktop.fullscreen) GFX_CaptureMouse(); - if (!strcasecmp(output,"surface")) { + if (output == "surface") { sdl.desktop.want_type=SCREEN_SURFACE; #if (HAVE_DDRAW_H) && defined(WIN32) - } else if (!strcasecmp(output,"ddraw")) { + } else if (output == "ddraw") { sdl.desktop.want_type=SCREEN_SURFACE_DDRAW; #endif - } else if (!strcasecmp(output,"overlay")) { + } else if (output == "overlay") { sdl.desktop.want_type=SCREEN_OVERLAY; #if C_OPENGL - } else if (!strcasecmp(output,"opengl")) { + } else if (output == "opengl") { sdl.desktop.want_type=SCREEN_OPENGL; sdl.opengl.bilinear=true; - } else if (!strcasecmp(output,"openglnb")) { + } else if (output == "openglnb") { sdl.desktop.want_type=SCREEN_OPENGL; sdl.opengl.bilinear=false; #endif } else { - LOG_MSG("SDL:Unsupported output device %s, switching back to surface",output); - sdl.desktop.want_type=SCREEN_SURFACE; + LOG_MSG("SDL:Unsupported output device %s, switching back to surface",output.c_str()); + sdl.desktop.want_type=SCREEN_SURFACE;//SHOULDN'T BE POSSIBLE anymore } sdl.overlay=0; @@ -1233,10 +1214,10 @@ void GFX_Events() { GFX_SetTitle(-1,-1,true); KEYBOARD_ClrBuffer(); - SDL_Delay(500); - while (SDL_PollEvent(&ev)) { +// SDL_Delay(500); +// while (SDL_PollEvent(&ev)) { // flush event queue. - } +// } while (paused) { // WaitEvent waits for an event rather than polling, so CPU usage drops to zero @@ -1433,39 +1414,62 @@ int main(int argc, char* argv[]) { sdl.num_joysticks=SDL_NumJoysticks(); Section_prop * sdl_sec=control->AddSection_prop("sdl",&GUI_StartUp); sdl_sec->AddInitFunction(&MAPPER_StartUp); - sdl_sec->Add_bool("fullscreen",false); - sdl_sec->Add_bool("fulldouble",false); - sdl_sec->Add_string("fullresolution","original"); - sdl_sec->Add_string("windowresolution","original"); - sdl_sec->Add_string("output","surface"); - sdl_sec->Add_bool("autolock",true); - sdl_sec->Add_int("sensitivity",100); - sdl_sec->Add_bool("waitonerror",true); - sdl_sec->Add_string("priority","higher,normal"); - sdl_sec->Add_string("mapperfile","mapper.txt"); - sdl_sec->Add_bool("usescancodes",true); + Prop_bool* Pbool; + Prop_string* Pstring; + Prop_int* Pint; + Prop_multival* Pmulti; + Pbool = sdl_sec->Add_bool("fullscreen",Property::Changeable::Always,false); + Pbool->Set_help("Start dosbox directly in fullscreen."); - MSG_Add("SDL_CONFIGFILE_HELP", - "fullscreen -- Start dosbox directly in fullscreen.\n" - "fulldouble -- Use double buffering in fullscreen.\n" - "fullresolution -- What resolution to use for fullscreen: original or fixed size (e.g. 1024x768).\n" - "windowresolution -- Scale the window to this size IF the output device supports hardware scaling.\n" - "output -- What to use for output: surface,overlay" + Pbool = sdl_sec->Add_bool("fulldouble",Property::Changeable::Always,false); + Pbool->Set_help("Use double buffering in fullscreen."); + + Pstring = sdl_sec->Add_string("fullresolution",Property::Changeable::Always,"original"); + Pstring->Set_help("What resolution to use for fullscreen: original or fixed size (e.g. 1024x768)."); + + Pstring = sdl_sec->Add_string("windowresolution",Property::Changeable::Always,"original"); + Pstring->Set_help("Scale the window to this size IF the output device supports hardware scaling."); + + const char* outputs[] = { + "surface", "overlay", #if C_OPENGL - ",opengl,openglnb" + "opengl", "openglnb", #endif #if (HAVE_DDRAW_H) && defined(WIN32) - ",ddraw" + "ddraw", #endif - ".\n" - "autolock -- Mouse will automatically lock, if you click on the screen.\n" - "sensitiviy -- Mouse sensitivity.\n" - "waitonerror -- Wait before closing the console if dosbox has an error.\n" - "priority -- Priority levels for dosbox: lowest,lower,normal,higher,highest,pause (when not focussed).\n" - " Second entry behind the comma is for when dosbox is not focused/minimized.\n" - "mapperfile -- File used to load/save the key/event mappings from.\n" - "usescancodes -- Avoid usage of symkeys, might not work on all operating systems.\n" - ); + 0 }; + Pstring = sdl_sec->Add_string("output",Property::Changeable::Always,"surface"); + Pstring->Set_help("What video system to use for output."); + Pstring->Set_values(outputs); + + Pbool = sdl_sec->Add_bool("autolock",Property::Changeable::Always,true); + Pbool->Set_help("Mouse will automatically lock, if you click on the screen."); + + Pint = sdl_sec->Add_int("sensitivity",Property::Changeable::Always,100); + Pint->SetMinMax(1,1000); + Pint->Set_help("Mouse sensitivity."); + + Pbool = sdl_sec->Add_bool("waitonerror",Property::Changeable::Always, true); + Pbool->Set_help("Wait before closing the console if dosbox has an error."); + + Pmulti = sdl_sec->Add_multi("priority", Property::Changeable::Always, ","); + Pmulti->Set_help("priority -- Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized. (pause is only valid for the second entry)"); + + const char* actt[] = { "lowest", "lower", "normal", "higher", "highest", "pause", 0}; + Pstring = Pmulti->GetSection()->Add_string("active",Property::Changeable::Always,"higher"); + Pstring->Set_values(actt); + + const char* inactt[] = { "lowest", "lower", "normal", "higher", "highest", "pause", 0}; + Pstring = Pmulti->GetSection()->Add_string("inactive",Property::Changeable::Always,"normal"); + Pstring->Set_values(inactt); + + Pstring = sdl_sec->Add_string("mapperfile",Property::Changeable::Always,"mapper.txt"); + Pstring->Set_help("File used to load/save the key/event mappings from."); + + Pbool = sdl_sec->Add_bool("usescancodes",Property::Changeable::Always,true); + Pbool->Set_help("Avoid usage of symkeys, might not work on all operating systems."); + /* Init all the dosbox subsystems */ DOSBOX_Init(); std::string config_file; diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 4d15dc47..259b99ba 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: messages.cpp,v 1.19 2007-01-08 19:45:41 qbix79 Exp $ */ +/* $Id: messages.cpp,v 1.20 2008-02-10 11:14:03 qbix79 Exp $ */ #include #include @@ -47,10 +47,11 @@ void MSG_Add(const char * _name, const char* _val) { /* Find the message */ for(itmb tel=Lang.begin();tel!=Lang.end();tel++) { if((*tel).name==_name) { + LOG_MSG("double entry for %s",_name); return; } } - /* Even if the message doesn't exist add it */ + /* if the message doesn't exist add it */ Lang.push_back(MessageBlock(_name,_val)); } diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 4fd87fbf..79d28b3e 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.29 2007-11-04 19:14:32 c2woody Exp $ */ +/* $Id: programs.cpp,v 1.30 2008-02-10 11:14:03 qbix79 Exp $ */ #include #include @@ -249,13 +249,13 @@ void CONFIG::Run(void) { WriteOut(MSG_Get("PROGRAM_CONFIG_SECTION_ERROR"),temp_line.c_str()); return; } - char const* val = sec->GetPropValue(prop.c_str()); - if(!val) { + std::string val = sec->GetPropValue(prop.c_str()); + if(val != NO_SUCH_PROPERTY) { WriteOut(MSG_Get("PROGRAM_CONFIG_NO_PROPERTY"),prop.c_str(),temp_line.c_str()); return; } - WriteOut("%s",val); - first_shell->SetEnv("CONFIG",val); + WriteOut("%s",val.c_str()); + first_shell->SetEnv("CONFIG",val.c_str()); return; } diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index a2937720..3752ab37 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,21 +16,22 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.43 2008-01-27 18:31:01 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.44 2008-02-10 11:14:03 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" #include "setup.h" +#include "support.h" #include #include +#include #include #include #include -#include "support.h" using namespace std; -void Value::destroy() { +void Value::destroy() throw(){ if (type == V_STRING) delete _string; } @@ -43,7 +44,7 @@ Value& Value::copy(Value const& in) throw(WrongType) { return *this; } -void Value::plaincopy(Value const& in) { +void Value::plaincopy(Value const& in) throw(){ type = in.type; _int = in._int; _double = in._double; @@ -59,7 +60,7 @@ Value::operator bool () const throw(WrongType) { Value::operator Hex () const throw(WrongType) { if(type != V_HEX) throw WrongType(); - return _hexn; + return _hex; } Value::operator int () const throw(WrongType) { @@ -88,7 +89,7 @@ bool Value::operator==(Value const& other) { if(_int == other._int) return true; break; case V_HEX: - if(_hexn == other._hexn) return true; + if(_hex == other._hex) return true; break; case V_DOUBLE: if(_double == other._double) return true; @@ -102,108 +103,245 @@ bool Value::operator==(Value const& other) { } return false; } +void Value::SetValue(string const& in,Etype _type) throw(WrongType) { + /* Throw exception if the current type isn't the wanted type + * Unless the wanted type is current. + */ + if(_type == V_CURRENT && type == V_NONE) throw WrongType(); + if(_type != V_CURRENT) { + if(type != V_NONE && type != _type) throw WrongType(); + type = _type; + } + switch(type){ + case V_HEX: + set_hex(in); + break; + case V_INT: + set_int(in); + break; + case V_BOOL: + set_bool(in); + break; + case V_STRING: + set_string(in); + break; + case V_DOUBLE: + set_double(in); + break; + + case V_NONE: + case V_CURRENT: + default: + /* Shouldn't happen!/Unhandled */ + throw WrongType(); + break; + } +} + +void Value::set_hex(std::string const& in) { + istringstream input(in); + input.flags(ios::hex); + int result = 0; + input >> result; + _hex = result; +} + +void Value::set_int(string const &in) { + istringstream input(in); + int result = 0; + input >> result; + _int = result; +} +void Value::set_double(string const &in) { + istringstream input(in); + double result = 0; + input >> result; + _double = result; +} + +void Value::set_bool(string const &in) { + istringstream input(in); + string result; + input >> result; + _bool = true; + lowcase(result); + /* valid false entries: 0 ,d*, f*, off everything else gets true */ + if( !result.size() ) return; + if(result[0] == '0' || result[0] == 'd' || result[0] == 'f' || result == "off") + _bool = false; +} + +void Value::set_string(string const & in) { + if(!_string) _string = new string(); + _string->assign(in); +} + +string Value::ToString() const { + ostringstream oss; + switch(type) { + case V_HEX: + oss.flags(ios::hex); + oss << _hex; + break; + case V_INT: + oss << _int; + break; + case V_BOOL: + oss << boolalpha << _bool; + break; + case V_STRING: + oss << *_string; + break; + case V_DOUBLE: + oss.precision(2); + oss << fixed << _double; + break; + case V_NONE: + case V_CURRENT: + default: + E_Exit("ToString messed up ?"); + break; + } + return oss.str(); +} bool Property::CheckValue(Value const& in, bool warn){ - if(suggested_values.empty()) return false; + if(suggested_values.empty()) return true; for(iter it = suggested_values.begin();it != suggested_values.end();it++) { if ( (*it) == in) { //Match! return true; } } - if(warn) LOG_MSG("Value not in suggested values"); + if(warn) LOG_MSG("\"%s\" is not a valid value for variable: %s.\nIt might now be reset it to default value: %s",in.ToString().c_str(),propname.c_str(),default_value.ToString().c_str()); return false; } +void Property::Set_help(string const& in) { + string result = string("CONFIG_") + propname; + upcase(result); + MSG_Add(result.c_str(),in.c_str()); +} + +char const* Property::Get_help() { + string result = string("CONFIG_") + propname; + upcase(result); + return MSG_Get(result.c_str()); +} + + bool Prop_int::CheckValue(Value const& in, bool warn) { - if(Property::CheckValue(in,warn)) return true; + if(suggested_values.empty() && Property::CheckValue(in,warn)) return true; //No >= and <= in Value type and == is ambigious int mi = min; int ma = max; int va = static_cast(Value(in)); if(mi == -1 && ma == -1) return true; if (va >= mi && va <= ma) return true; - if(warn) LOG_MSG("Value not included in range"); + if(warn) LOG_MSG("%s lies outside the range %s-%s for variable: %s.\nIt might now be reset to the default value: %s",in.ToString().c_str(),min.ToString().c_str(),max.ToString().c_str(),propname.c_str(),default_value.ToString().c_str()); return false; } -void Prop_double::SetValue(char* input){ - input=trim(input); - value = static_cast(atof(input)); +void Prop_double::SetValue(std::string const& input){ + Value val(input,Value::V_DOUBLE); + SetVal(val,false,true); } -void Prop_int::SetValue(char* input){ - input=trim(input); - value = atoi(input); +//void Property::SetValue(char* input){ +// value.SetValue(input, Value::V_CURRENT); +//} +void Prop_int::SetValue(std::string const& input){; + Value val(input,Value::V_INT); + SetVal(val,false,true); } -void Prop_string::SetValue(char* input){ - input=trim(input); - value=input; +void Prop_string::SetValue(std::string const& input){ + Value val(input,Value::V_STRING); + SetVal(val,false,true); } -void Prop_bool::SetValue(char* input){ - input=lowcase(trim(input)); - /* valid false entries: 0 ,d*, of* ,f* everything else gets true */ - if((input[0]=='0') || (input[0]=='d') || ( (input[0]=='o') && (input[1]=='f')) || (input[0]=='f')){ - value._bool=false; - }else{ - value._bool=true; +void Prop_bool::SetValue(std::string const& input){ + value.SetValue(input,Value::V_BOOL); +} + +void Prop_hex::SetValue(std::string const& input){ + Value val(input,Value::V_HEX); + SetVal(val,false,true); +} + +//TODO checkvalue stuff +void Prop_multival::SetValue(std::string const& input) { + Value val(input,Value::V_STRING); + SetVal(val,false,true); + + std::string local(input); + int i = 0; + Property *p = section->Get_prop(0); + //No properties in this section. do nothing + if(!p) return; + string::size_type loc = string::npos; + while( (p = section->Get_prop(i++)) ) { + //trim leading seperators + loc = local.find_first_not_of(seperator); + if(loc != string::npos) local.erase(0,loc); + loc = local.find_first_of(seperator); + string in = "";//default value + if(loc != string::npos) { //seperator found + in = local.substr(0,loc); + local.erase(0,loc+1); + } else if(local.size()) { //last argument + in = local; + local = ""; + } + p->SetValue(in); } } -void Prop_hex::SetValue(char* input){ - input=trim(input); - if(!sscanf(input,"%X",&(value._hex))) value._hex=0; -} - -void Prop_int::GetValuestring(char* str) const{ - sprintf(str,"%d",value._int); -} - -void Prop_string::GetValuestring(char* str) const{ - sprintf(str,"%s",value._string->c_str()); -} - -void Prop_bool::GetValuestring(char* str) const{ - sprintf(str,"%s",value._bool?"true":"false"); -} - -void Prop_double::GetValuestring(char* str) const { - sprintf(str,"%1.2f",value._double); -} - -void Prop_hex::GetValuestring(char* str) const { - sprintf(str,"%X",value._hex); -} +/* void Section_prop::Add_double(char const * const _propname, double _value) { Property* test=new Prop_double(_propname,_value); properties.push_back(test); +}*/ + +void Property::Set_values(const char * const *in) { + Value::Etype type = default_value.type; + int i = 0; + while (in[i]) { + Value val(in[i],type); + suggested_values.push_back(val); + i++; + } +} + +Prop_int* Section_prop::Add_int(string const& _propname, Property::Changeable::Value when, int _value) { + Prop_int* test=new Prop_int(_propname,when,_value); + properties.push_back(test); + return test; +} + +Prop_string* Section_prop::Add_string(string const& _propname, Property::Changeable::Value when, char const * const _value) { + Prop_string* test=new Prop_string(_propname,when,_value); + properties.push_back(test); + return test; +} + +Prop_bool* Section_prop::Add_bool(string const& _propname, Property::Changeable::Value when, bool _value) { + Prop_bool* test=new Prop_bool(_propname,when,_value); + properties.push_back(test); + return test; +} +Prop_hex* Section_prop::Add_hex(string const& _propname, Property::Changeable::Value when, Hex _value) { + Prop_hex* test=new Prop_hex(_propname,when,_value); + properties.push_back(test); + return test; +} +Prop_multival* Section_prop::Add_multi(std::string const& _propname, Property::Changeable::Value when,std::string const& sep) { + Prop_multival* test = new Prop_multival(_propname,when,sep); + properties.push_back(test); + return test; } -Prop_int& Section_prop::Add_int(const char* _propname, int _value) { - Prop_int* test=new Prop_int(_propname,_value); - properties.push_back(test); - return *test; -} - -Prop_string& Section_prop::Add_string(char const * const _propname, char const * const _value) { - Prop_string* test=new Prop_string(_propname,_value); - properties.push_back(test); - return *test; -} - -Prop_bool& Section_prop::Add_bool(char const * const _propname, bool _value) { - Prop_bool* test=new Prop_bool(_propname,_value); - properties.push_back(test); - return *test; -} -Prop_hex& Section_prop::Add_hex(const char* _propname, int _value) { - Prop_hex* test=new Prop_hex(_propname,_value); - properties.push_back(test); - return *test; -} -int Section_prop::Get_int(char const * const _propname) const { +int Section_prop::Get_int(string const&_propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ return ((*tel)->GetValue()); @@ -212,7 +350,7 @@ int Section_prop::Get_int(char const * const _propname) const { return 0; } -bool Section_prop::Get_bool(char const * const _propname) const { +bool Section_prop::Get_bool(string const& _propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ return ((*tel)->GetValue()); @@ -220,13 +358,22 @@ bool Section_prop::Get_bool(char const * const _propname) const { } return false; } -double Section_prop::Get_double(char const * const _propname) const { +double Section_prop::Get_double(string const& _propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ return ((*tel)->GetValue()); } } - return false; + return 0.0; +} +Prop_multival* Section_prop::Get_multival(string const& _propname) const { + for(const_it tel=properties.begin();tel!=properties.end();tel++){ + if((*tel)->propname==_propname){ + Prop_multival* val = dynamic_cast((*tel)); + if(val) return val; else return NULL; + } + } + return NULL; } Property* Section_prop::Get_prop(int index){ @@ -236,7 +383,7 @@ Property* Section_prop::Get_prop(int index){ return NULL; } -const char* Section_prop::Get_string(char const * const _propname) const { +const char* Section_prop::Get_string(string const& _propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ return ((*tel)->GetValue()); @@ -244,50 +391,57 @@ const char* Section_prop::Get_string(char const * const _propname) const { } return ""; } -int Section_prop::Get_hex(char const * const _propname) const { +Hex Section_prop::Get_hex(string const& _propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ - return ((*tel)->GetValue())._hex; + return ((*tel)->GetValue()); } } return 0; } -void Section_prop::HandleInputline(char *gegevens){ - char * rest=strrchr(gegevens,'='); - if(!rest) return; - *rest = 0; - gegevens=trim(gegevens); +void trim(string& in) { + string::size_type loc = in.find_first_not_of(' '); + if(loc != string::npos) in.erase(0,loc); + loc = in.find_last_not_of(' '); + if(loc != string::npos) in.erase(loc+1); +} + +//TODO double c_str +void Section_prop::HandleInputline(string const& gegevens){ + string str1 = gegevens; + string::size_type loc = str1.find('='); + if(loc == string::npos) return; + string name = str1.substr(0,loc); + string val = str1.substr(loc + 1); + /* trim the results incase there were spaces somewhere */ + trim(name);trim(val); for(it tel=properties.begin();tel!=properties.end();tel++){ - if(!strcasecmp((*tel)->propname.c_str(),gegevens)){ - (*tel)->SetValue(rest+1); + if(!strcasecmp((*tel)->propname.c_str(),name.c_str())){ + (*tel)->SetValue(val); return; } } } - void Section_prop::PrintData(FILE* outfile) const { - char temp[1000]; /* Should be enough for the properties */ /* Now print out the individual section entries */ for(const_it tel=properties.begin();tel!=properties.end();tel++){ - (*tel)->GetValuestring(temp); - fprintf(outfile,"%s=%s\n",(*tel)->propname.c_str(),temp); + fprintf(outfile,"%s=%s\n",(*tel)->propname.c_str(),(*tel)->GetValue().ToString().c_str()); } } -static char buffer[1024]; -char const * Section_prop::GetPropValue(char const * const _property) const{ +//TODO geen noodzaak voor 2 keer c_str +string Section_prop::GetPropValue(string const& _property) const{ for(const_it tel=properties.begin();tel!=properties.end();tel++){ - if(!strcasecmp((*tel)->propname.c_str(),_property)){ - (*tel)->GetValuestring(buffer); - return buffer; + if(!strcasecmp((*tel)->propname.c_str(),_property.c_str())){ + return (*tel)->GetValue().ToString(); } } - return NULL; + return NO_SUCH_PROPERTY; } -void Section_line::HandleInputline(char* line){ +void Section_line::HandleInputline(string const& line){ data+=line; data+="\n"; } @@ -296,8 +450,8 @@ void Section_line::PrintData(FILE* outfile) const { fprintf(outfile,"%s",data.c_str()); } -char const* Section_line::GetPropValue(char const * const /* _property*/) const { - return NULL; +string Section_line::GetPropValue(string const& /* _property*/) const { + return NO_SUCH_PROPERTY; } void Config::PrintConfig(char const * const configfilename) const { @@ -403,17 +557,17 @@ Section* Config::GetSection(int index){ } return NULL; } - -Section* Config::GetSection(char const * const _sectionname) const{ +//c_str() 2x +Section* Config::GetSection(string const& _sectionname) const{ for (const_it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ - if (!strcasecmp((*tel)->GetName(),_sectionname)) return (*tel); + if (!strcasecmp((*tel)->GetName(),_sectionname.c_str())) return (*tel); } return NULL; } Section* Config::GetSectionFromProperty(char const * const prop) const{ for (const_it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ - if ((*tel)->GetPropValue(prop)) return (*tel); + if ((*tel)->GetPropValue(prop) != NO_SUCH_PROPERTY) return (*tel); } return NULL; } @@ -425,27 +579,17 @@ bool Config::ParseConfigFile(char const * const configfilename){ const char * settings_type = first_configfile?"primary":"additional"; first_configfile = false; LOG_MSG("CONFIG:Loading %s settings from config file %s", settings_type,configfilename); - char gegevens[1024]; + string gegevens; Section* currentsection = NULL; Section* testsec = NULL; while (in) { - in.getline(gegevens,1024); - char* temp; - char* s; - int len; - s = gegevens; + getline(in,gegevens); - /* strip trailing whitespace */ - for (len = strlen(s); len > 0 && isspace(s[len - 1]); len--) { - /* nothing */ - } - s[len] = 0; + /* strip leading/trailing whitespace */ + trim(gegevens); + if(!gegevens.size()) continue; - /* strip leading whitespace */ - while (isspace(s[0])) { - s++; - } - switch(s[0]){ + switch(gegevens[0]){ case '%': case '\0': case '#': @@ -454,16 +598,19 @@ bool Config::ParseConfigFile(char const * const configfilename){ continue; break; case '[': - temp = strrchr(s,']'); - *temp=0; - testsec = GetSection(&s[1]); + { + string::size_type loc = gegevens.find(']'); + if(loc == string::npos) continue; + gegevens.erase(loc); + testsec = GetSection(gegevens.substr(1)); if(testsec != NULL ) currentsection = testsec; testsec = NULL; + } break; default: - try{ - if(currentsection) currentsection->HandleInputline(s); - }catch(const char* message){ + try { + if(currentsection) currentsection->HandleInputline(gegevens); + } catch(const char* message) { message=0; //EXIT with message } diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 4b3a1307..6dba9d7a 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.80 2008-01-19 11:02:29 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.81 2008-02-10 11:14:03 qbix79 Exp $ */ #include "dosbox.h" #include "shell.h" @@ -74,8 +74,8 @@ bool DOS_Shell::CheckConfig(char* cmd_in,char*line) { Section* test = control->GetSectionFromProperty(cmd_in); if(!test) return false; if(line && !line[0]) { - char const* val = test->GetPropValue(cmd_in); - if(val) WriteOut("%s\n",val); + std::string val = test->GetPropValue(cmd_in); + if(val != NO_SUCH_PROPERTY) WriteOut("%s\n",val.c_str()); return true; } char newcom[1024]; newcom[0] = 0; strcpy(newcom,"z:\\config "); From b437d79d8d470818f1f3edf440b198a2d707778e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 10 Feb 2008 14:31:00 +0000 Subject: [PATCH 3011/4131] Fix crash due to missing 0 at end of list Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3099 --- src/dosbox.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 957ba59d..76170a09 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.128 2008-02-10 11:14:03 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.129 2008-02-10 14:31:00 qbix79 Exp $ */ #include #include @@ -394,7 +394,7 @@ void DOSBOX_Init(void) { " (Example: fixed 4000)\n" " 'max' will allocate as much cycles as your computer is able to handle\n"); - const char* cyclest[] = { "auto","fixed","max" }; + const char* cyclest[] = { "auto","fixed","max",0 }; Pstring = Pmulti->GetSection()->Add_string("type",Property::Changeable::Always,"auto"); Pstring->Set_values(cyclest); From ff3634a5d91e683a3a68394e0b7ca2fb73c03038 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 10 Feb 2008 18:55:23 +0000 Subject: [PATCH 3012/4131] Add "hack" to display the initial values of the prop_multival entries. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3100 --- src/dosbox.cpp | 4 +++- src/gui/sdlmain.cpp | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 76170a09..1c702a44 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.129 2008-02-10 14:31:00 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.130 2008-02-10 18:55:23 qbix79 Exp $ */ #include #include @@ -357,6 +357,7 @@ void DOSBOX_Init(void) { Pbool->Set_help("Do aspect correction, if your output method doesn't support scaling this can slow things down!."); Pmulti = secprop->Add_multi("scaler",Property::Changeable::Always," "); + Pmulti->SetValue("normal2x"); Pmulti->Set_help("Scaler used to enlarge/enhance low resolution modes. If 'forced' is appended,the scaler will be used even if the result might not be desired."); Pstring = Pmulti->GetSection()->Add_string("type",Property::Changeable::Always,"normal2x"); @@ -396,6 +397,7 @@ void DOSBOX_Init(void) { const char* cyclest[] = { "auto","fixed","max",0 }; Pstring = Pmulti->GetSection()->Add_string("type",Property::Changeable::Always,"auto"); + Pmulti->SetValue("auto"); Pstring->Set_values(cyclest); Pstring = Pmulti->GetSection()->Add_string("parameters",Property::Changeable::Always,""); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 3a1486ae..1a39209e 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.139 2008-02-10 11:14:03 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.140 2008-02-10 18:55:23 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1454,6 +1454,7 @@ int main(int argc, char* argv[]) { Pbool->Set_help("Wait before closing the console if dosbox has an error."); Pmulti = sdl_sec->Add_multi("priority", Property::Changeable::Always, ","); + Pmulti->SetValue("higher,normal"); Pmulti->Set_help("priority -- Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized. (pause is only valid for the second entry)"); const char* actt[] = { "lowest", "lower", "normal", "higher", "highest", "pause", 0}; From 8ca07ff1f074a43b99844c8e9ff6f408ae7ed6e7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 13 Feb 2008 14:06:22 +0000 Subject: [PATCH 3013/4131] Make core_audio default again and add some extra headers. Mac OS X 10.5.x users please test if it still works. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3101 --- src/gui/midi.cpp | 2 +- src/gui/midi_coreaudio.h | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 85a6a8fe..ede2088d 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -79,8 +79,8 @@ MidiHandler Midi_none; #if defined(MACOSX) -#include "midi_coreaudio.h" #include "midi_coremidi.h" +#include "midi_coreaudio.h" #elif defined (WIN32) diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index 923f1615..758972a6 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -18,6 +18,13 @@ #include +//We seem to using very old interface. This keeps it compiling. Maybe +//somebody will come up with something better oneday. +#ifdef MAC_OS_X_VERSION_10_5 +#include +#include +#endif + class MidiHandler_coreaudio : public MidiHandler { private: AudioUnit m_musicDevice; From 5bb96c2dba70641faeed51c5b077c75ae29be776 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 16 Feb 2008 20:47:41 +0000 Subject: [PATCH 3014/4131] don't need writemode when reading the file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3102 --- src/gui/sdl_mapper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 061f2889..2015bee5 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.47 2007-11-07 17:41:32 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.48 2008-02-16 20:47:41 qbix79 Exp $ */ #include #include @@ -2102,7 +2102,7 @@ static void MAPPER_SaveBinds(void) { } static bool MAPPER_LoadBinds(void) { - FILE * loadfile=fopen(mapper.filename,"rb+"); + FILE * loadfile=fopen(mapper.filename,"rb"); if (!loadfile) return false; char linein[512]; while (fgets(linein,512,loadfile)) { From 482d2ab34927aefb0f15fec5fa730e748e1015fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 18 Feb 2008 17:45:55 +0000 Subject: [PATCH 3015/4131] correct error code when dos create file is called with directory bit set (fixes some pkunzip oddity) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3103 --- src/dos/dos_files.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 6c921731..dfef87f0 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.94 2008-01-21 21:26:49 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.95 2008-02-18 17:45:55 c2woody Exp $ */ #include #include @@ -426,6 +426,11 @@ bool DOS_CreateFile(char const * name,Bit16u attributes,Bit16u * entry) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); return false; } + /* Don't allow directories to be created */ + if (attributes&0x10) { + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; + } bool foundit=Drives[drive]->FileCreate(&Files[handle],fullname,attributes); if (foundit) { Files[handle]->SetDrive(drive); From cd2718f011ecb9c520c08caa6cd46d0a73019d55 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 18 Feb 2008 19:48:22 +0000 Subject: [PATCH 3016/4131] Fix (a part of) marriage. ;) (don't zero al on unknown calls) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3104 --- src/ints/int10.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 3effb153..ffa93e67 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.cpp,v 1.48 2008-01-09 20:34:51 c2woody Exp $ */ +/* $Id: int10.cpp,v 1.49 2008-02-18 19:48:22 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -643,8 +643,8 @@ graphics_chars: warned_ff=true; break; default: - LOG(LOG_INT10,LOG_ERROR)("Function %2X not supported",reg_ah); - reg_al=0x00; //Successfull + LOG(LOG_INT10,LOG_ERROR)("Function %4X not supported",reg_ax); +// reg_al=0x00; //Successfull, breaks marriage break; }; return CBRET_NONE; From e8aac54d8081bdba89f9ba2ccc67aa18a5463856 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 18 Feb 2008 20:25:21 +0000 Subject: [PATCH 3017/4131] Add case insensitive support for string type options. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3105 --- src/misc/setup.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 3752ab37..11cb5e79 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.44 2008-02-10 11:14:03 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.45 2008-02-18 20:25:21 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -255,7 +255,12 @@ void Prop_int::SetValue(std::string const& input){; } void Prop_string::SetValue(std::string const& input){ - Value val(input,Value::V_STRING); + //Special version for lowcase stuff + std::string temp(input); + //suggested values always case insensitive. + //If there are none then it can be paths and such which are case sensitive + if(!suggested_values.empty()) lowcase(temp); + Value val(temp,Value::V_STRING); SetVal(val,false,true); } From 615dab6a1fb70432c52eb53afdf6b1722a1c5441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 19 Feb 2008 17:45:33 +0000 Subject: [PATCH 3018/4131] eat up some cycles for cdrom sector transfers (gets some cdrom speed checks to work better) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3106 --- src/dos/dos_mscdex.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index aac4c803..570ed64a 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.52 2008-02-06 21:56:32 c2woody Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.53 2008-02-19 17:45:33 c2woody Exp $ */ #include #include @@ -27,6 +27,7 @@ #include "setup.h" #include "support.h" #include "bios.h" +#include "cpu.h" #include "cdrom.h" @@ -628,27 +629,25 @@ bool CMscdex::GetUPC(Bit8u subUnit, Bit8u& attr, char* upc) return dinfo[subUnit].lastResult = cdrom[subUnit]->GetUPC(attr,&upc[0]); }; -bool CMscdex::ReadSectors(Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data) -{ +bool CMscdex::ReadSectors(Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data) { if (subUnit>=numDrives) return false; + if ((4*num*2048+5) < CPU_Cycles) CPU_Cycles -= 4*num*2048; + else CPU_Cycles = 5; dinfo[subUnit].lastResult = cdrom[subUnit]->ReadSectors(data,raw,sector,num); return dinfo[subUnit].lastResult; }; -bool CMscdex::ReadSectorsMSF(Bit8u subUnit, bool raw, Bit32u start, Bit16u num, PhysPt data) -{ +bool CMscdex::ReadSectorsMSF(Bit8u subUnit, bool raw, Bit32u start, Bit16u num, PhysPt data) { if (subUnit>=numDrives) return false; Bit8u min = (Bit8u)(start>>16) & 0xFF; Bit8u sec = (Bit8u)(start>> 8) & 0xFF; Bit8u fr = (Bit8u)(start>> 0) & 0xFF; Bit32u sector = min*60*75+sec*75+fr - 150; - // TODO: Check, if num has to be converted too ?! return ReadSectors(subUnit,raw,sector,num,data); }; -bool CMscdex::ReadSectors(Bit16u drive, Bit32u sector, Bit16u num, PhysPt data) // Called from INT 2F -{ +bool CMscdex::ReadSectors(Bit16u drive, Bit32u sector, Bit16u num, PhysPt data) { return ReadSectors(GetSubUnit(drive),false,sector,num,data); }; From cb1b1fcbced827da5861ae5ae2f086d80678909f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 21 Feb 2008 19:25:34 +0000 Subject: [PATCH 3019/4131] release special alt-state when starting the gui (fixes tab-completion bug) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3107 --- include/video.h | 5 ++++- src/gui/sdl_gui.cpp | 6 +++--- src/gui/sdlmain.cpp | 23 ++++++++++++++++------- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/include/video.h b/include/video.h index 40656bc0..980f5410 100644 --- a/include/video.h +++ b/include/video.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: video.h,v 1.24 2008-02-21 19:25:04 c2woody Exp $ */ + #ifndef DOSBOX_VIDEO_H #define DOSBOX_VIDEO_H @@ -66,6 +68,7 @@ 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); diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index 4197ff59..b54375e3 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_gui.cpp,v 1.5 2008-02-10 11:14:03 qbix79 Exp $ */ +/* $Id: sdl_gui.cpp,v 1.6 2008-02-21 19:25:34 c2woody Exp $ */ #include "SDL.h" #include "../libs/gui_tk/gui_tk.h" @@ -95,7 +95,7 @@ static GUI::ScreenSDL *UI_Startup(GUI::ScreenSDL *screen) { if(!screen) { //Coming from DOSBox. Clean up the keyboard buffer. KEYBOARD_ClrBuffer();//Clear buffer } - MAPPER_LosingFocus();//Release any keys pressed (buffer gets filled again). (could be in above if, but clearing the mapper input when exiting the mapper is sensible as well + GFX_LosingFocus();//Release any keys pressed (buffer gets filled again). (could be in above if, but clearing the mapper input when exiting the mapper is sensible as well SDL_Delay(500); // Comparable to the code of intro.com, but not the same! (the code of intro.com is called from within a com file) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 1a39209e..2514653b 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.140 2008-02-10 18:55:23 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.141 2008-02-21 19:25:34 c2woody Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -211,6 +211,9 @@ struct SDL_Block { #if defined (WIN32) bool using_windib; #endif + // state of alt-keys for certain special handlings + Bit8u laltstate; + Bit8u raltstate; }; static SDL_Block sdl; @@ -1159,8 +1162,11 @@ static void HandleMouseButton(SDL_MouseButtonEvent * button) { } } -static Bit8u laltstate = SDL_KEYUP; -static Bit8u raltstate = SDL_KEYUP; +void GFX_LosingFocus(void) { + sdl.laltstate=SDL_KEYUP; + sdl.raltstate=SDL_KEYUP; + MAPPER_LosingFocus(); +} void GFX_Events() { SDL_Event event; @@ -1194,7 +1200,7 @@ void GFX_Events() { GFX_CaptureMouse(); } SetPriority(sdl.priority.nofocus); - MAPPER_LosingFocus(); + GFX_LosingFocus(); CPU_Enable_SkipAutoAdjust(); } } @@ -1266,10 +1272,10 @@ void GFX_Events() { case SDL_KEYDOWN: case SDL_KEYUP: // ignore event alt+tab - if (event.key.keysym.sym==SDLK_LALT) laltstate = event.key.type; - if (event.key.keysym.sym==SDLK_RALT) raltstate = event.key.type; + if (event.key.keysym.sym==SDLK_LALT) sdl.laltstate = event.key.type; + if (event.key.keysym.sym==SDLK_RALT) sdl.raltstate = event.key.type; if (((event.key.keysym.sym==SDLK_TAB)) && - ((laltstate==SDL_KEYDOWN) || (raltstate==SDL_KEYDOWN))) break; + ((sdl.laltstate==SDL_KEYDOWN) || (sdl.raltstate==SDL_KEYDOWN))) break; #endif default: void MAPPER_CheckEvent(SDL_Event * event); @@ -1382,6 +1388,9 @@ int main(int argc, char* argv[]) { if( SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0 ) LOG_MSG("Failed to init joystick support"); #endif + sdl.laltstate = SDL_KEYUP; + sdl.raltstate = SDL_KEYUP; + #if defined (WIN32) #if SDL_VERSION_ATLEAST(1, 2, 10) sdl.using_windib=true; From 2a10734876dc68e0159a6f1e4510bc3f2f50dc63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 22 Feb 2008 18:18:03 +0000 Subject: [PATCH 3020/4131] fix get filename from entry Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3108 --- src/dos/drive_fat.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index ce411649..58f3059e 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * Copyright (C) 2002-20078 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.23 2007-11-03 17:20:29 c2woody Exp $ */ +/* $Id: drive_fat.cpp,v 1.24 2008-02-22 18:18:03 c2woody Exp $ */ #include #include @@ -394,6 +394,7 @@ bool fatDrive::getEntryName(char *fullname, char *entname) { //LOG_MSG("Testing for filename %s", fullname); findDir = strtok(dirtoken,"\\"); + if (findDir==NULL) return false; findFile = findDir; while(findDir != NULL) { findFile = findDir; From 864b737029ba5fab5f0df9d9271566c40945c571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 24 Feb 2008 17:38:03 +0000 Subject: [PATCH 3021/4131] fat fs: preserve error code for create file calls on success Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3109 --- src/dos/drive_fat.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 58f3059e..5eab57af 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-20078 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.24 2008-02-22 18:18:03 c2woody Exp $ */ +/* $Id: drive_fat.cpp,v 1.25 2008-02-24 17:38:03 c2woody Exp $ */ #include #include @@ -394,7 +394,9 @@ bool fatDrive::getEntryName(char *fullname, char *entname) { //LOG_MSG("Testing for filename %s", fullname); findDir = strtok(dirtoken,"\\"); - if (findDir==NULL) return false; + if (findDir==NULL) { + return true; // root always exists + } findFile = findDir; while(findDir != NULL) { findFile = findDir; @@ -765,6 +767,8 @@ bool fatDrive::FileCreate(DOS_File **file, char *name, Bit16u attributes) { char dirName[DOS_NAMELENGTH_ASCII]; char pathName[11]; + Bitu save_errorcode=dos.errorcode; + /* Check if file already exists */ if(getFileDirEntry(name, &fileEntry, &dirClust, &subEntry)) { /* Truncate file */ @@ -794,6 +798,8 @@ bool fatDrive::FileCreate(DOS_File **file, char *name, Bit16u attributes) { /* Maybe modTime and date should be used ? (crt matches findnext) */ ((fatFile *)(*file))->time = fileEntry.crtTime; ((fatFile *)(*file))->date = fileEntry.crtDate; + + dos.errorcode=save_errorcode; return true; } From 0665eeb12d88eaba2c951045c39176510eb078fd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 Feb 2008 06:21:09 +0000 Subject: [PATCH 3022/4131] Fix double adition of last line of autoexec.bat stuff Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3110 --- src/misc/setup.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 11cb5e79..8fa818b1 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.45 2008-02-18 20:25:21 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.46 2008-02-25 06:21:09 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -587,8 +587,7 @@ bool Config::ParseConfigFile(char const * const configfilename){ string gegevens; Section* currentsection = NULL; Section* testsec = NULL; - while (in) { - getline(in,gegevens); + while (getline(in,gegevens)) { /* strip leading/trailing whitespace */ trim(gegevens); From eb14c103fe9b50a5da02001c83598bcff41ae931 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 26 Feb 2008 08:55:29 +0000 Subject: [PATCH 3023/4131] GCC 4.3 header. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3111 --- src/hardware/vga_tseng.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_tseng.cpp b/src/hardware/vga_tseng.cpp index 3e86ee51..b328ea92 100644 --- a/src/hardware/vga_tseng.cpp +++ b/src/hardware/vga_tseng.cpp @@ -16,14 +16,15 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_tseng.cpp,v 1.2 2008-01-12 17:37:48 c2woody Exp $ */ +/* $Id: vga_tseng.cpp,v 1.3 2008-02-26 08:55:29 qbix79 Exp $ */ + #include "dosbox.h" #include "setup.h" #include "vga.h" #include "inout.h" #include "mem.h" - +#include // Tseng ET4K data typedef struct { Bit8u extensionsEnabled; From e5bd92e4721ca062c18971d44808fc3070ed4fd3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 2 Mar 2008 08:53:34 +0000 Subject: [PATCH 3024/4131] Keep it compiling. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3112 --- src/debug/debug_gui.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index fff27f17..7331bdf0 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug_gui.cpp,v 1.32 2007-05-09 14:35:51 c2woody Exp $ */ +/* $Id: debug_gui.cpp,v 1.33 2008-03-02 08:53:34 qbix79 Exp $ */ #include "dosbox.h" @@ -243,12 +243,12 @@ void LOG_StartUp(void) { /* Register the log section */ Section_prop * sect=control->AddSection_prop("log",LOG_Init); - sect->Add_string("logfile",""); + sect->Add_string("logfile",Property::Changeable::Always,""); char buf[1024]; for (Bitu i=1;iAdd_bool(buf,true); + sect->Add_bool(buf,Property::Changeable::Always,true); } MSG_Add("LOG_CONFIGFILE_HELP","Logging related options for the debugger.\n"); } From f2c40b9407543c190dabf510d5a9db7557e00c67 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 2 Mar 2008 08:55:04 +0000 Subject: [PATCH 3025/4131] Add way to easy timer 4 check to counter_output. But seems to work. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3113 --- src/hardware/timer.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index ffc6b1c1..22f0bd90 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.45 2007-11-18 17:09:15 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.46 2008-03-02 08:55:04 qbix79 Exp $ */ #include #include "dosbox.h" @@ -91,6 +91,11 @@ static bool counter_output(Bitu counter) { if (p->new_mode) return true; index=fmod(index,(double)p->delay); return index*2delay; + case 4: + //Only low on terminal count + // if(fmod(index,(double)p->delay) == 0) return false; //Maybe take one rate tick in consideration + //Easiest solution is to report always high (Space marines uses this mode) + return true; default: LOG(LOG_PIT,LOG_ERROR)("Illegal Mode %d for reading output",p->mode); return true; From 3f2e4fbd83cba4556b00735cd2dc2934ec781a36 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 2 Mar 2008 11:13:47 +0000 Subject: [PATCH 3026/4131] Allow longer commandlines in MOUNT and IMGMOUNT. Fix crash reported by MiniMax (mount -u 0). Fix bug reported by Tearex ("config -get" broken). Add some protection that makes it harder to mount a directory from within an executable. Add some protection to make mounting from command /c much harder. Add a securemode commandline switch to config and dosbox that should make it impossible to mount a location when this isn't wanted by the user. (Addresses concerns of CVE-2007-6328) Update documentation to reflect this. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3114 --- README | 15 +++++++++- docs/dosbox.1 | 20 +++++++++++++- include/programs.h | 3 +- include/setup.h | 7 +++-- include/shell.h | 7 +++-- src/dos/dos_programs.cpp | 60 ++++++++++++++++++++++++++++------------ src/misc/programs.cpp | 36 ++++++++++++++++++++++-- src/shell/shell.cpp | 37 ++++++++++++++++++------- src/shell/shell_misc.cpp | 9 ++++-- 9 files changed, 156 insertions(+), 38 deletions(-) diff --git a/README b/README index 6a5637fb..d1ee926c 100644 --- a/README +++ b/README @@ -273,7 +273,8 @@ description: dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] [-lang languagefile] [-machine machinetype] [-noconsole] - [-startmapper] [-noautoexec] [-scaler scaler | -forcescaler scaler] + [-startmapper] [-noautoexec] [-securemode] + [-scaler scaler | -forcescaler scaler] dosbox -version @@ -318,6 +319,11 @@ dosbox -version -noautoexec Skips the [autoexec] section of the loaded configuration file. + -securemode + Same as -noautoexec, but adds config.com -securemode at the + bottom of AUTOEXEC.BAT (which in turn disables any changes to how + the drives are mounted inside DOSBox) + -scaler scaler Uses the scaler specified by "scaler". See the DOSBox configuration file for the available scalers. @@ -469,6 +475,7 @@ MEM CONFIG -writeconf localfile CONFIG -writelang localfile +CONFIG -securemode CONFIG -set "section property=value" CONFIG -get "section property" @@ -491,6 +498,12 @@ CONFIG -get "section property" The language file controls all visible output of the internal commands and the internal DOS. + -securemode + Switches DOSBox to a more secure mode. In this mode the 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 DOSBox.) + -set "section property=value" CONFIG will attempt to set the property to new value. At this moment CONFIG can not report whether the command succeeded or not. diff --git a/docs/dosbox.1 b/docs/dosbox.1 index cefa7018..c895bbbe 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -8,6 +8,7 @@ dosbox \- an x86/DOS emulator with sound/graphics .B [\-fullscreen] .B [\-startmapper] .B [\-noautoexec] +.B [\-securemode] .BI "[\-scaler " scaler ] .BI "[\-forcescaler " scaler ] .BI "[\-conf " configfile ] @@ -41,6 +42,13 @@ A summary of options is included below. .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 @@ -67,7 +75,7 @@ wish to execute on startup. Multiple .IR langfile . .TP .B \-exit -.BR dosbox " will close itself when the DOS program specified by " file "ends." +.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." @@ -153,9 +161,19 @@ 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," diff --git a/include/programs.h b/include/programs.h index 3cee7b4d..750b37b7 100644 --- a/include/programs.h +++ b/include/programs.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.h,v 1.15 2008-01-19 11:02:29 qbix79 Exp $ */ +/* $Id: programs.h,v 1.16 2008-03-02 11:13:46 qbix79 Exp $ */ #ifndef DOSBOX_PROGRAMS_H #define DOSBOX_PROGRAMS_H @@ -77,6 +77,7 @@ public: Bitu GetEnvCount(void); bool SetEnv(const char * entry,const char * new_string); void WriteOut(const char * format,...); /* Write to standard output */ + void ChangeToLongCmd(); }; diff --git a/include/setup.h b/include/setup.h index fa7bdec0..7e7131f4 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.32 2008-02-10 11:14:02 qbix79 Exp $ */ +/* $Id: setup.h,v 1.33 2008-03-02 11:13:46 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -300,8 +300,9 @@ private: typedef std::list::const_iterator const_it; typedef std::list::const_reverse_iterator const_reverse_it; void (* _start_function)(void); + bool secure_mode; //Sandbox mode public: - Config(CommandLine * cmd):cmdline(cmd){} + Config(CommandLine * cmd):cmdline(cmd),secure_mode(false){} ~Config(); Section_line * AddSection_line(char const * const _name,void (*_initfunction)(Section*)); @@ -318,6 +319,8 @@ public: void 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 }; class Module_base { diff --git a/include/shell.h b/include/shell.h index 32032f9d..0080e949 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.22 2007-10-28 10:58:49 qbix79 Exp $ */ +/* $Id: shell.h,v 1.23 2008-03-02 11:13:46 qbix79 Exp $ */ #ifndef DOSBOX_SHELL_H #define DOSBOX_SHELL_H @@ -39,8 +39,11 @@ 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; +/* command_slashc indicates that the next commands are being run from command /c. Remove parameters for internal .COM files */ +extern bool command_slashc; + +class DOS_Shell; class BatchFile { public: diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 60c6cd33..3d9056c9 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.82 2008-01-19 11:02:29 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.83 2008-03-02 11:13:46 qbix79 Exp $ */ #include "dosbox.h" #include @@ -72,6 +72,7 @@ static void ResolveHomedir(std::string & temp_line) { } } + class MOUNT : public Program { public: void Run(void) @@ -80,11 +81,32 @@ public: std::string label; std::string umount; + //Hack To allow long commandlines + ChangeToLongCmd(); + /* Parse the command line */ + /* if the command line is empty show current mounts */ + if (!cmd->GetCount()) { + WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_1")); + for (int d=0;dGetInfo()); + } + } + return; + } + + /* In secure mode don't allow people to change mount points. + * Neither mount nor unmount */ + if(control->SecureMode()) { + WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW")); + return; + } + /* Check for unmounting */ if (cmd->FindString("-u",umount,false)) { umount[0] = toupper(umount[0]); int i_drive = umount[0]-'A'; - if(i_drive < DOS_DRIVES && Drives[i_drive]) { + if(i_drive < DOS_DRIVES && i_drive >= 0 && Drives[i_drive]) { switch (DriveManager::UnmountDrive(i_drive)) { case 0: Drives[i_drive] = 0; @@ -115,18 +137,6 @@ public: return; } - /* Parse the command line */ - /* if the command line is empty show current mounts */ - if (!cmd->GetCount()) { - WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_1")); - for (int d=0;dGetInfo()); - } - } - return; - } - std::string type="dir"; cmd->FindString("-t",type,true); bool iscdrom = (type =="cdrom"); //Used for mscdex bug cdrom label name emulation @@ -492,6 +502,15 @@ private: public: void Run(void) { + //Hack To allow long commandlines + ChangeToLongCmd(); + /* In secure mode don't allow people to boot stuff. + * They might try to corrupt the data on it */ + if(control->SecureMode()) { + WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW")); + return; + } + FILE *usefile_1=NULL; FILE *usefile_2=NULL; Bitu i; @@ -946,8 +965,15 @@ static void INTRO_ProgramStart(Program * * make) { class IMGMOUNT : public Program { public: - void Run(void) - { + void Run(void) { + //Hack To allow long commandlines + ChangeToLongCmd(); + /* In secure mode don't allow people to change imgmount points. + * Neither mount nor unmount */ + if(control->SecureMode()) { + WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW")); + return; + } DOS_Drive * newdrive; imageDisk * newImage; Bit32u imagesize; @@ -959,7 +985,7 @@ public: if (cmd->FindString("-u",umount,false)) { umount[0] = toupper(umount[0]); int i_drive = umount[0]-'A'; - if (i_drive < DOS_DRIVES && Drives[i_drive]) { + if (i_drive < DOS_DRIVES && i_drive >= 0 && Drives[i_drive]) { switch (DriveManager::UnmountDrive(i_drive)) { case 0: Drives[i_drive] = 0; diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 79d28b3e..451a2e24 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.30 2008-02-10 11:14:03 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.31 2008-03-02 11:13:46 qbix79 Exp $ */ #include #include @@ -106,6 +106,18 @@ Program::Program() { cmd = new CommandLine(filename,tail.buffer); } +extern std::string full_arguments; + +void Program::ChangeToLongCmd() { + CommandLine* temp = 0; + //If command_slashc => then don't pass any parameters to the internal .COM files + if(command_slashc) temp = new CommandLine(cmd->GetFileName(),""); + else temp = new CommandLine(cmd->GetFileName(),full_arguments.c_str()); + delete cmd; + cmd = temp; + full_arguments.assign(""); //Clear so it gets even more save +} + void Program::WriteOut(const char * format,...) { char buf[2048]; va_list msg; @@ -207,6 +219,11 @@ void CONFIG::Run(void) { FILE * f; if (cmd->FindString("-writeconf",temp_line,true) || cmd->FindString("-wc",temp_line,true)) { + /* In secure mode don't allow a new configfile to be created */ + if(control->SecureMode()) { + WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW")); + return; + } f=fopen(temp_line.c_str(),"wb+"); if (!f) { WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str()); @@ -218,6 +235,12 @@ void CONFIG::Run(void) { } if (cmd->FindString("-writelang",temp_line,true) ||cmd->FindString("-wl",temp_line,true)) { + /* In secure mode don't allow a new languagefile to be created + * Who knows which kind of file we would overwriting. */ + if(control->SecureMode()) { + WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW")); + return; + } f=fopen(temp_line.c_str(),"wb+"); if (!f) { WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str()); @@ -228,6 +251,13 @@ void CONFIG::Run(void) { return; } + /* Code for switching to secure mode */ + if(cmd->FindExist("-securemode",true)) { + control->SwitchToSecureMode(); + WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_ON")); + return; + } + /* Code for getting the current configuration. * * Official format: config -get "section property" * * As a bonus it will set %CONFIG% to this value as well */ @@ -250,7 +280,7 @@ void CONFIG::Run(void) { return; } std::string val = sec->GetPropValue(prop.c_str()); - if(val != NO_SUCH_PROPERTY) { + if(val == NO_SUCH_PROPERTY) { WriteOut(MSG_Get("PROGRAM_CONFIG_NO_PROPERTY"),prop.c_str(),temp_line.c_str()); return; } @@ -338,6 +368,8 @@ void PROGRAMS_Init(Section* /*sec*/) { MSG_Add("PROGRAM_CONFIG_FILE_ERROR","Can't open file %s\n"); MSG_Add("PROGRAM_CONFIG_USAGE","Config tool:\nUse -writeconf filename to write the current config.\nUse -writelang filename to write the current language strings.\n"); + MSG_Add("PROGRAM_CONFIG_SECURE_ON","Switched to secure mode.\n"); + MSG_Add("PROGRAM_CONFIG_SECURE_DISALLOW","This operation is not permitted in secure mode.\n"); MSG_Add("PROGRAM_CONFIG_SECTION_ERROR","Section %s doesn't exist.\n"); MSG_Add("PROGRAM_CONFIG_PROPERTY_ERROR","No such section or property.\n"); MSG_Add("PROGRAM_CONFIG_NO_PROPERTY","There is no property %s in section %s.\n"); diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 3b0ece22..2e6276b5 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.88 2007-08-17 17:58:46 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.89 2008-03-02 11:13:47 qbix79 Exp $ */ #include #include @@ -28,6 +28,7 @@ #include "callback.h" #include "support.h" + Bitu call_shellstop; /* Larger scope so shell_del autoexec can use it to * remove things from the environment */ @@ -278,16 +279,22 @@ void DOS_Shell::RunInternal(void) return; } +bool command_slashc = false; void DOS_Shell::Run(void) { char input_line[CMD_MAXLINE] = {0}; std::string line; if (cmd->FindStringRemain("/C",line)) { + //command_slashc indicates that the following commands are run with command /c. Forbid parameters to mount. + //command_allready_set prevents against command /c "command /c command" + bool command_allready_set = command_slashc; + command_slashc = true; strcpy(input_line,line.c_str()); DOS_Shell temp; temp.echo = echo; temp.ParseLine(input_line); //for *.exe *.com |*.bat creates the bf needed by runinternal; temp.RunInternal(); // exits when no bf is found. + if(!command_allready_set) command_slashc = false; return; } /* Start a normal shell and check for a first command init */ @@ -333,7 +340,7 @@ void DOS_Shell::SyntaxError(void) { class AUTOEXEC:public Module_base { private: - AutoexecObject autoexec[16]; + AutoexecObject autoexec[17]; AutoexecObject autoexec_echo; public: AUTOEXEC(Section* configuration):Module_base(configuration) { @@ -341,9 +348,12 @@ public: std::string line; Section_line * section=static_cast(configuration); - /* add stuff from the configfile unless -noautexec is specified. */ - char * extra=const_cast(section->data.c_str()); - if (extra && !control->cmdline->FindExist("-noautoexec",true)) { + /* Check -securemode switch to disable mount/imgmount/boot after running autoexec.bat */ + bool secure = control->cmdline->FindExist("-securemode",true); + + /* add stuff from the configfile unless -noautexec or -securemode is specified. */ + char * extra = const_cast(section->data.c_str()); + if (extra && !secure && !control->cmdline->FindExist("-noautoexec",true)) { /* detect if "echo off" is the first line */ bool echo_off = !strncasecmp(extra,"echo off",8); if (!echo_off) echo_off = !strncasecmp(extra,"@echo off",9); @@ -372,7 +382,10 @@ public: /* Check for first command being a directory or file */ char buffer[CROSS_LEN]; char cross_filesplit[2] = {CROSS_FILESPLIT , 0}; - if (control->cmdline->FindCommand(1,line)) { + /* Combining -securemode and no parameter leaves you with a lovely Z:\. */ + if ( !control->cmdline->FindCommand(1,line) ) { + if ( secure ) autoexec[12].Install("z:\\config.com -securemode"); + } else { struct stat test; strcpy(buffer,line.c_str()); if (stat(buffer,&test)){ @@ -384,6 +397,7 @@ public: if (test.st_mode & S_IFDIR) { autoexec[12].Install(std::string("MOUNT C \"") + buffer + "\""); autoexec[13].Install("C:"); + if(secure) autoexec[14].Install("z:\\config.com -securemode"); } else { char* name = strrchr(buffer,CROSS_FILESPLIT); if (!name) { //Only a filename @@ -401,16 +415,19 @@ public: autoexec[13].Install("C:"); upcase(name); if(strstr(name,".BAT") != 0) { + if(secure) autoexec[14].Install("z:\\config.com -securemode"); /* BATch files are called else exit will not work */ - autoexec[14].Install(std::string("CALL ") + name); + autoexec[15].Install(std::string("CALL ") + name); } else if((strstr(name,".IMG") != 0) || (strstr(name,".IMA") !=0)) { + //No secure mode here as boot is destructive and enabling securemode disables boot /* Boot image files */ - autoexec[14].Install(std::string("BOOT ") + name); + autoexec[15].Install(std::string("BOOT ") + name); } else { - autoexec[14].Install(name); + if(secure) autoexec[14].Install("z:\\config.com -securemode"); + autoexec[15].Install(name); } - if(addexit) autoexec[15].Install("exit"); + if(addexit) autoexec[16].Install("exit"); } } nomount: diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 4a023f3f..f2dc58b3 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.51 2007-08-22 11:21:28 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.52 2008-03-02 11:13:47 qbix79 Exp $ */ #include #include @@ -354,6 +354,7 @@ void DOS_Shell::InputCommand(char * line) { if (l_completion.size()) l_completion.clear(); } +std::string full_arguments = ""; bool DOS_Shell::Execute(char * name,char * args) { /* return true => don't check for hardware changes in do_command * return false => check for hardware changes in do_command */ @@ -438,7 +439,7 @@ bool DOS_Shell::Execute(char * name,char * args) { if(strcasecmp(extension, ".com") !=0) { if(strcasecmp(extension, ".exe") !=0) return false; - } + } /* Run the .exe or .com file from the shell */ /* Allocate some stack space for tables in physical memory */ reg_sp-=0x200; @@ -448,6 +449,10 @@ bool DOS_Shell::Execute(char * name,char * args) { //Add a filename RealPt file_name=RealMakeSeg(ss,reg_sp+0x20); MEM_BlockWrite(Real2Phys(file_name),fullname,strlen(fullname)+1); + + /* HACK: Store full commandline for mount and imgmount */ + full_arguments.assign(line); + /* Fill the command line */ CommandTail cmdtail; cmdtail.count = 0; From afb28f903908b85cfef996690cdc6920323f3dcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 2 Mar 2008 19:45:41 +0000 Subject: [PATCH 3027/4131] fix some oddities with get/set file attribute calls (fixes almost nothing!) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3115 --- src/dos/dos.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 726c4037..e3134a5b 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.107 2007-12-06 17:44:19 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.108 2008-03-02 19:45:41 c2woody Exp $ */ #include #include @@ -582,17 +582,22 @@ static Bitu DOS_21Handler(void) { MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); switch (reg_al) { case 0x00: /* Get */ - if (DOS_GetFileAttr(name1,®_cx)) { - reg_ax=reg_cx; /* Undocumented */ - CALLBACK_SCF(false); - } else { - CALLBACK_SCF(true); - reg_ax=dos.errorcode; - } - break; + { + Bit16u attr_val=reg_cx; + if (DOS_GetFileAttr(name1,&attr_val)) { + reg_cx=attr_val; + reg_ax=attr_val; /* Undocumented */ + CALLBACK_SCF(false); + } else { + CALLBACK_SCF(true); + reg_ax=dos.errorcode; + } + break; + }; case 0x01: /* Set */ LOG(LOG_MISC,LOG_ERROR)("DOS:Set File Attributes for %s not supported",name1); if (DOS_SetFileAttr(name1,reg_cx)) { + reg_ax=0x202; /* ax destroyed */ CALLBACK_SCF(false); } else { CALLBACK_SCF(true); From 39efc20d3e70c0cbae2d1f630cb4cea8f7def7f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 8 Mar 2008 12:29:59 +0000 Subject: [PATCH 3028/4131] pel panning+line compare handled different in textmodes, fixes diamond cave (thanks to hal for spotting this) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3116 --- src/hardware/vga_draw.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 28640222..dbfb1ba6 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.92 2008-01-12 17:37:48 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.93 2008-03-08 12:29:59 c2woody Exp $ */ #include #include @@ -656,8 +656,10 @@ static void VGA_DrawSingleLine(Bitu blah) { vga.draw.lines_done++; if (vga.draw.split_line==vga.draw.lines_done) { vga.draw.address=0; - if(!(vga.attr.mode_control&0x20)) - vga.draw.address += vga.config.pel_panning; + if (!(vga.attr.mode_control&0x20)) { + // pel panning enabled + if (!(vga.mode==M_TEXT)) vga.draw.address = vga.config.pel_panning; + } vga.draw.address_line=0; } if ((vga.draw.lines_done < vga.draw.lines_total) && (!vga.draw.resizing)) { @@ -680,8 +682,10 @@ static void VGA_DrawPart(Bitu lines) { VGA_ChangesEnd( ); #endif vga.draw.address=0; - if(!(vga.attr.mode_control&0x20)) - vga.draw.address += vga.config.pel_panning; + if (!(vga.attr.mode_control&0x20)) { + // pel panning enabled + if (!(vga.mode==M_TEXT)) vga.draw.address = vga.config.pel_panning; + } vga.draw.address_line=0; #ifdef VGA_KEEP_CHANGES vga.changes.start = vga.draw.address >> VGA_CHANGE_SHIFT; From cf48084ceaf5428034df733fb8388f03b93c2090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 8 Mar 2008 22:05:05 +0000 Subject: [PATCH 3029/4131] correct mouse maximal y-value for non-standard font heights in text mode (fixes mouse in lba2 installer) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3117 --- include/mouse.h | 18 +++++++++++------- src/ints/mouse.cpp | 11 ++++++++--- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/include/mouse.h b/include/mouse.h index f0467fe1..ccc38a05 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -16,16 +16,20 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.h,v 1.13 2007-01-08 19:45:37 qbix79 Exp $ */ - -#ifndef DOSBOX_MOUSE_H -#define DOSBOX_MOUSE_H - +/* $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_HideCursor(void); -bool Mouse_SetPS2State(bool use); -void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs); +bool Mouse_SetPS2State(bool use); + +void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs); + void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate); void Mouse_CursorSet(float x,float y); diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 5b1fe4ba..664663b2 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.71 2007-11-05 21:46:26 c2woody Exp $ */ +/* $Id: mouse.cpp,v 1.72 2008-03-08 22:05:05 c2woody Exp $ */ #include #include @@ -537,7 +537,12 @@ void Mouse_NewVideoMode(void) { case 0x00: case 0x01: case 0x02: - case 0x03: + case 0x03: { + Bitu rows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS); + if ((rows==0) || (rows>250)) rows=25-1; + mouse.max_y=8*(rows+1)-1; + break; + } case 0x04: case 0x05: case 0x06: From cd688843612aef41a8b03be5d0099e158fdee307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 9 Mar 2008 20:32:23 +0000 Subject: [PATCH 3030/4131] make rom out of ems pageframe segment when BOOTing a disk Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3118 --- src/dos/dos_programs.cpp | 6 ++++-- src/hardware/memory.cpp | 11 +++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 3d9056c9..bc38707c 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.83 2008-03-02 11:13:46 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.84 2008-03-09 20:32:22 c2woody Exp $ */ #include "dosbox.h" #include @@ -746,6 +746,8 @@ public: } } else { disable_umb_ems_xms(); + void RemoveEMSPageFrame(void); + RemoveEMSPageFrame(); WriteOut(MSG_Get("PROGRAM_BOOT_BOOT"), drive); for(i=0;i<512;i++) real_writeb(0, 0x7c00 + i, bootarea.rawdata[i]); diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index afe051d2..efdbe02f 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: memory.cpp,v 1.53 2007-12-10 22:11:13 c2woody Exp $ */ +/* $Id: memory.cpp,v 1.54 2008-03-09 20:32:23 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -519,6 +519,13 @@ static Bitu read_p92(Bitu port,Bitu iolen) { return memory.a20.controlport | (memory.a20.enabled ? 0x02 : 0); } +void RemoveEMSPageFrame(void) { + /* Setup rom at 0xe0000-0xf0000 */ + for (Bitu ct=0xe0;ct<0xf0;ct++) { + memory.phandlers[ct] = &rom_page_handler; + } +} + void PreparePCJRCartRom(void) { /* Setup rom at 0xd0000-0xe0000 */ for (Bitu ct=0xd0;ct<0xe0;ct++) { From 94d7c8db7d6d6d71caf391d777e273d550fbb176 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 10 Mar 2008 13:43:37 +0000 Subject: [PATCH 3031/4131] don't parse above 9 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3119 --- src/shell/shell_batch.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 84893f7b..d16e748a 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.26 2007-10-28 10:58:50 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.27 2008-03-10 13:43:37 qbix79 Exp $ */ #include #include @@ -86,14 +86,14 @@ emptyline: cmd_write+=strlen(file_name); continue; } - size_t len=strspn(cmd_read,"123456789"); - if (len) { /* Handle %1 %2 .. %9 */ - memcpy(env_name,cmd_read,len); - env_name[len]=0;cmd_read+=len; - len=atoi(env_name); - if (cmd->GetCount() '0' && next <= '9') { + /* Handle %1 %2 .. %9 */ + cmd_read++; //Progress reader + next -= '0'; + if (cmd->GetCount()FindCommand(len,word)) continue; + if (!cmd->FindCommand(next,word)) continue; strcpy(cmd_write,word.c_str()); cmd_write+=strlen(word.c_str()); continue; From 766edb294fadf45f78529267e237aacf80870da8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 11 Mar 2008 18:16:34 +0000 Subject: [PATCH 3032/4131] raise default freesize of directory mounts a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3120 --- src/dos/dos_programs.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index bc38707c..c1097760 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.84 2008-03-09 20:32:22 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.85 2008-03-11 18:16:34 c2woody Exp $ */ #include "dosbox.h" #include @@ -148,9 +148,9 @@ public: str_size="512,1,2880,2880";/* All space free */ mediaid=0xF0; /* Floppy 1.44 media */ } else if (type=="dir") { - // 512*127*16513==~1GB total size - // 512*127*1700==~100MB total free size - str_size="512,127,16513,1700"; + // 512*127*16383==~1GB total size + // 512*127*4031==~250MB total free size + str_size="512,127,16383,4031"; mediaid=0xF8; /* Hard Disk */ } else if (type=="cdrom") { str_size="2048,1,65535,0"; From 7ebc99e37a9c0c1e3cc4d495fb39a51de307dae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 11 Mar 2008 21:30:09 +0000 Subject: [PATCH 3033/4131] small readme corrections Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3121 --- README | 325 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 179 insertions(+), 146 deletions(-) diff --git a/README b/README index d1ee926c..71cb23e6 100644 --- a/README +++ b/README @@ -40,7 +40,7 @@ INDEX: Type INTRO in DOSBox for a quick tour. It is essential that you get familiar with the idea of mounting, -DOSBox does not automatically make any drive (or parts of it) +DOSBox does not automatically make any drive (or a part of it) accessible to the emulation. See the FAQ entry "I've got a Z instead of a C at the prompt" as well as the description of the MOUNT command (section 4). @@ -65,6 +65,7 @@ Q: The keyboard lags. Q: The cursor always moves into one direction! Q: The game/application can't find its CD-ROM. Q: The game/application runs much too slow! +Q: The game/application does not run at all/crashes! Q: Can DOSBox harm my computer? Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. Q: What sound hardware does DOSBox presently emulate? @@ -142,7 +143,7 @@ A: You're using too much CPU power to keep DOSBox running at the current speed. You can lower the cycles, skip frames, reduce the sampling rate of the respective sound device (see the DOSBox configuration file) or the mixer device. You can also increase the prebuffer in the configfile. - If you are using cycles=max or =auto, then make sure that there no + If you are using cycles=max or =auto, then make sure that there is no background processes interfering! (especially if they access the harddisk) @@ -151,11 +152,13 @@ A: This is a known problem. It only occurs if your keyboard layout isn't US. Some possible fixes: 1. Switch the keyboard layout of your operating system. 2. Use / instead. - 3. Open dosbox.conf and change usescancodes=false to usescancodes=true. - 4. Add the commands you want to execute to the "configfile". - 5. Change the DOS keyboard layout (see Section 7 Keyboard Layout). + 3. Open the DOSBox configuration file and change usescancodes=false + to usescancodes=true. + 4. Add the commands you want to execute to the [autoexec]-section + of the DOSBox configuration file. + 5. Change the DOS keyboard layout (see Section 7: Keyboard Layout). 6. Use ALT-58 for : and ALT-92 for \. - 7. for \ try the keys around "enter". For ":" try shift and the keys + 7. For \ try the keys around "enter". For ":" try shift and the keys between "enter" and "l" (US keyboard layout). 8. Try keyb.com from FreeDOS (http://projects.freedos.net/keyb/). Look for keyb2.0 pre4 as older and newer versions are known to @@ -171,23 +174,23 @@ A: Lower the priority setting in the DOSBox configuration file Q: The cursor always moves into one direction! A: See if it still happens if you disable the joystick emulation, set joysticktype=none in the [joystick] section of your DOSBox - configuration file. Maybe also try unplugging any joystick. + configuration file. Maybe also try unplugging any joystick/gamepad. If you want to use the joystick in the game, try setting timed=false and be sure to calibrate the joystick (both in your OS as well as - in the game or the game's setup). + in the game or the game's setup program). Q: The game/application can't find its CD-ROM. A: Be sure to mount the CD-ROM with -t cdrom switch, this will enable the - MSCDEX interface required by DOS games to interface with CD-ROMs. - Also try adding the correct label (-label LABEL). To enable lower-level - CD-ROM support, add the following switch to mount: -usecd #, where # is - the number of your CD-ROM drive reported by mount -cd. Under Windows you - can specify -ioctl, -aspi or -noioctl. Look at the description elsewhere - in this document for their meaning. + MSCDEX interface required by DOS games to interface with CD-ROM's. + Also try adding the correct label (-label LABEL) to the mount command. + To enable lower-level CD-ROM support, add the following switch to mount: + -usecd #, where # is the number of your CD-ROM drive reported by mount -cd. + Under Windows you can specify -ioctl, -aspi or -noioctl. Look at the + description of the mount command in Section 4 for their meaning. Try creating a CD-ROM image (preferably CUE/BIN pair) and use the - DOSBox-internal IMGMOUNT tool to mount the image. This enables very - good low-level CD-ROM support on any operating system. + DOSBox-internal IMGMOUNT tool to mount the image (the CUE sheet). + This enables very good low-level CD-ROM support on any operating system. Q: The game/application runs much too slow! @@ -195,6 +198,10 @@ A: Look at the section "How to run resource-demanding games" for more information. +Q: The game/application does not run at all/crashes! +A: Look at Section 10: Troubleshooting + + Q: Can DOSBox harm my computer? A: DOSBox can not harm your computer more than any other resource demanding program. Increasing the cycles does not overclock your real CPU. @@ -206,6 +213,7 @@ Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. A: This is possible! Just create a config file: config -writeconf configfile. Start your favourite editor and look through the settings. To start DOSBox with your new settings: dosbox -conf configfile + See the description of the config command in Section 4 for more details. Q: What sound hardware does DOSBox presently emulate? @@ -252,12 +260,12 @@ Q: Great README, but I still don't get it. A: A look at "The Newbie's pictorial guide to DOSBox" located at http://vogons.zetafleet.com/viewforum.php?f=39 might help you. Also try the wiki of DOSBox: - http://dosbox.sourceforge.net/wiki/ + http://www.dosbox.com/wiki/ For more questions read the remainder of this README and/or check the site/forum: -http://dosbox.sourceforge.net +http://www.dosbox.com @@ -267,7 +275,7 @@ http://dosbox.sourceforge.net An overview of the command line options you can give to DOSBox. Windows Users must open cmd.exe or command.com or edit the shortcut to -DOSBox.exe for this. +dosbox.exe for this. The options are valid for all operating systems unless noted in the option description: @@ -288,7 +296,7 @@ dosbox -version -c command Runs the specified command before running "name". Multiple commands - can be specified. Each command should start with "-c", though. + can be specified. Each command should start with "-c" though. A command can be: an Internal Program, a DOS command or an executable on a mounted drive. @@ -298,15 +306,16 @@ dosbox -version -conf configfile Start DOSBox with the options specified in "configfile". Multiple -conf options may be present. - See Chapter 10 for more details. + See Section 11 for more details. -lang languagefile Start DOSBox using the language specified in "languagefile". -machine machinetype Setup DOSBox to emulate a specific type of machine. Valid choices are: - hercules, cga, pcjr, tandy, vga (default). The machinetype affects - both the videocard and the available soundcards. + hercules, cga, pcjr, tandy, vga (default) as well as the svga chipsets + listed in the help of the DOSBox configuration file. The machinetype + affects both the videocard and the available soundcards. -noconsole (Windows Only) Start DOSBox without showing the console window. Output will @@ -322,7 +331,7 @@ dosbox -version -securemode Same as -noautoexec, but adds config.com -securemode at the bottom of AUTOEXEC.BAT (which in turn disables any changes to how - the drives are mounted inside DOSBox) + the drives are mounted inside DOSBox). -scaler scaler Uses the scaler specified by "scaler". See the DOSBox configuration @@ -338,14 +347,14 @@ dosbox -version Note: If a name/command/configfile/languagefile contains a space, put the whole name/command/configfile/languagefile between quotes ("command or file name"). If you need to use quotes within quotes - (most likely with -c and mount). + (most likely with -c and mount): Windows and OS/2 users can use single quotes inside the double quotes. Other people should be able to use escaped double quotes inside the double quotes. - win -c "mount c 'c:\program files\'" - linux -c "mount c \"/tmp/name with space\"" + Windows: -c "mount c 'c:\program files\'" + Linux: -c "mount c \"/tmp/name with space\"" -For example: +For example (Windows): dosbox c:\atlantis\atlantis.exe -c "MOUNT D C:\SAVES" This mounts c:\atlantis as c:\ and runs atlantis.exe. @@ -376,7 +385,7 @@ MOUNT -u "Emulated Drive letter" "Emulated Drive letter" The driveletter inside DOSBox (eg. C). - "Real Drive letter (usually for CD-ROMs in Windows) or Directory" + "Real Drive letter (usually for CD-ROM's in Windows) or Directory" The local directory you want accessible inside DOSBox. -t type @@ -399,11 +408,11 @@ MOUNT -u "Emulated Drive letter" -label drivelabel 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 CD-ROM. If you don't specify a label and no + systems if the CD-ROM label isn't read correctly (useful when a + program can't find its CD-ROM). If you don't specify a label and no lowlevel support is selected (that is omitting the -usecd # and/or - -aspi parameters or specifying -noioctl): - For win32: label is extracted from "Real Drive". + -aspi parameters, or specifying -noioctl): + For Windows: label is extracted from "Real Drive". For Linux: label is set to NO_LABEL. If you do specify a label, this label will be kept as long as the drive @@ -435,7 +444,7 @@ MOUNT -u "Emulated Drive letter" Basically MOUNT allows you to connect real hardware to DOSBox's emulated PC. So MOUNT C C:\GAMES tells DOSBox to use your C:\GAMES directory as drive C: - in DOSBox. It also allows you to change the drive's letter identification + in DOSBox. It also allows you to change the drive letter identification for programs that demand specific drive letters. For example: Touche: Adventures of The Fifth Musketeer must be run on your C: @@ -445,34 +454,44 @@ MOUNT -u "Emulated Drive letter" MOUNT C D:\OLDGAMES will allow you to run Touche from the D drive. Mounting your entire C drive with MOUNT C C:\ is NOT recommended! The same - is true for mounting the root of any other drive, except for CD-ROMs (due to + is true for mounting the root of any other drive, except for CD-ROM's (due to their read-only nature). Otherwise if you or DOSBox make a mistake you may - loose all your files. + lose all your files. It is recommended to put all your applications/games into a subdirectory and mount that. General MOUNT Examples: - 1. To mount c:\DirX as a floppy : - mount a c:\DirX -t floppy - 2. To mount system CD-ROM drive E as CD-ROM drive D in DOSBox: - mount d e:\ -t cdrom - 3. To mount system CD-ROM drive at mountpoint /media/cdrom as CD-ROM drive D - in DOSBox: - mount d /media/cdrom -t cdrom -usecd 0 - 4. To mount a drive with ~870 mb free diskspace (simple version): - mount c d:\ -freesize 870 - 5. To mount a drive with ~870 mb free diskspace (experts only, full control): - mount c d:\ -size 512,127,16513,13500 - 6. To mount /home/user/dirY as drive C in DOSBox: - mount c /home/user/dirY - 7. To mount the directory where DOSBox was started as D in DOSBox: - mount d . + 1. To mount c:\DirX as a floppy : + mount a c:\DirX -t floppy + 2. To mount system CD-ROM drive E as CD-ROM drive D in DOSBox: + mount d e:\ -t cdrom + 3. To mount system CD-ROM drive at mountpoint /media/cdrom as CD-ROM drive D + in DOSBox: + mount d /media/cdrom -t cdrom -usecd 0 + 4. To mount a drive with ~870 mb free diskspace (simple version): + mount c d:\ -freesize 870 + 5. To mount a drive with ~870 mb free diskspace (experts only, full control): + mount c d:\ -size 512,127,16513,13500 + 6. To mount /home/user/dirY as drive C in DOSBox: + mount c /home/user/dirY + 7. To mount the directory where DOSBox was started as D in DOSBox: + mount d . + (note the . which represents the directory where DOSBox was started) MEM Program to display the amount of free memory. +VER +VER set major_version [minor_version] + Display the current DOSBox version and reported DOS version + (parameterless usage). + Change the reported DOS version with the "set" parameter, + for example: "VER set 6 22" to have DOSBox report DOS 6.22 + as version number. + + CONFIG -writeconf localfile CONFIG -writelang localfile CONFIG -securemode @@ -482,7 +501,7 @@ CONFIG -get "section property" CONFIG can be used to change or query various settings of DOSBox during runtime. It can save the current settings and language strings to disk. Information about all possible sections and properties can - be found in section 11 (The Config File). + be found in Section 11 (The Config File). -writeconf localfile Write the current configuration settings to file. "localfile" is @@ -490,7 +509,7 @@ CONFIG -get "section property" The configuration file controls various settings of DOSBox: the amount of emulated memory, the emulated soundcards and many more things. It allows access to AUTOEXEC.BAT as well. - See section 11 (The Config File) for more information. + See Section 11 (The Config File) for more information. -writelang localfile Write the current language settings to file. "localfile" is @@ -502,10 +521,10 @@ CONFIG -get "section property" Switches DOSBox to a more secure mode. In this mode the 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 DOSBox.) + (Warning: you can only undo this mode by restarting DOSBox.) -set "section property=value" - CONFIG will attempt to set the property to new value. At this moment + CONFIG will attempt to set the property to new value. Currently CONFIG can not report whether the command succeeded or not. -get "section property" @@ -517,20 +536,20 @@ CONFIG -get "section property" own preferences for each game. Examples: - 1. To create a configfile in your current directory: - config -writeconf dosbox.conf - 2. To set the cpu cycles to 10000: - config -set "cpu cycles=10000" - 3. To turn ems memory emulation off: - config -set "dos ems=off" - 4. To check which cpu core is being used. - config -get "cpu core" + 1. To create a configfile in your current directory: + config -writeconf dosbox.conf + 2. To set the cpu cycles to 10000: + config -set "cpu cycles=10000" + 3. To turn ems memory emulation off: + config -set "dos ems=off" + 4. To check which cpu core is being used. + config -get "cpu core" LOADFIX [-size] [program] [program-parameters] LOADFIX -f - Program to reduce the amount of memory available. Useful for old programs - which don't expect much memory to be free. + Program to reduce the amount of available conventional memory. + Useful for old programs which don't expect much memory to be free. -size number of kilobytes to "eat up", default = 64kb @@ -538,14 +557,14 @@ LOADFIX -f -f frees all previously allocated memory -Examples: - 1. To start mm2.exe and allocate 64kb memory - (mm2 will have 64 kb less available) : - loadfix mm2 - 2. To start mm2.exe and allocate 32kb memory : - loadfix -32 mm2 - 3. To free previous allocated memory : - loadfix -f + Examples: + 1. To start mm2.exe and allocate 64kb memory + (mm2 will have 64 kb less available) : + loadfix mm2 + 2. To start mm2.exe and allocate 32kb memory : + loadfix -32 mm2 + 3. To free previous allocated memory : + loadfix -f RESCAN @@ -564,7 +583,7 @@ MIXER left:right The volume levels in percentages. If you put a D in front it will be - in decibel (example mixer gus d-10). + in decibel (Example: mixer gus d-10). /NOSHOW Prevents DOSBox from showing the result if you set one @@ -582,20 +601,31 @@ IMGMOUNT IMGMOUNT DRIVE [imagefile] -t [image_type] -fs [image_format] -size [sectorsbytesize, sectorsperhead, heads, cylinders] + IMGMOUNT DRIVE [imagefile1, .. ,imagefileN] -t iso -fs iso imagefile - Location of the image files to mount in DOSBox. The location can + Location of the image file to mount in DOSBox. The location can be on a mounted drive inside DOSBox, or on your real disk. It is possible to mount CD-ROM images (ISOs or CUE/BIN) as well, if you - need CD swapping capabilities specify all images in succession. - The CDs can be swapped with CTRL-F4 at any time. + need CD swapping capabilities specify all images in succession + (see the next entry). + CUE/BIN pairs are the preferred CD-ROM image type as they can + store audio tracks compared to ISOs (which are data-only). For + the CUE/BIN mounting always specify the CUE sheet. + + imagefile1, .. ,imagefileN + Location of the image files to mount in DOSBox. Specifying a number + of image files is only allowed for CD-ROM images. The CD's can be + swapped with CTRL-F4 at any time. This is required for games which + use multiple CD-ROM's and require the CD to be switched during the + gameplay at some point. -t The following are valid image types: - floppy: Specifies a floppy image or images. DOSBox will automatically - identify the disk geometry ( 360K, 1.2MB, 720K, 1.44MB, etc). - iso: Specifies a CD-ROM iso image. The geometry is automatic and - set for this size. This can be an iso or a cue/bin. + floppy: Specifies a floppy image. DOSBox will automatically identify + the disk geometry (360K, 1.2MB, 720K, 1.44MB, etc). + iso: Specifies a CD-ROM iso image. The geometry is automatic and + set for this size. This can be an iso or a cue/bin pair. hdd: Specifies a harddrive image. The proper CHS geometry must be set for this to work. @@ -607,18 +637,18 @@ IMGMOUNT available from inside DOSBox. none: DOSBox will make no attempt to read the file system on the disk. This is useful if you need to format it or if you want to boot - the disk using the BOOT command. When using the "none" + the disk using the BOOT command. When using the "none" filesystem, you must specify the drive number (2 or 3, where 2 = master, 3 = slave) rather than a drive letter. For example, to mount a 70MB image as the slave drive device, - you would type: + you would type (without the quotes): "imgmount 3 d:\test.img -size 512,63,16,142 -fs none" - (without the quotes) Compare this with a mount to read the - drive in DOSBox, which would read as: + Compare this with a mount to be able to access the drive + within DOSBox, which would read as: "imgmount e: d:\test.img -size 512,63,16,142" -size - The Cylinders, Heads and Sectors specification of the drive. + The Cylinders, Heads and Sectors of the drive. Required to mount hard drive images. An example how to mount CD-ROM images: @@ -647,7 +677,7 @@ BOOT [-l driveletter] This parameter allows you to specify the drive to boot from. - The default is the A drive, the floppy drive. You can also boot + The default is the A drive, the floppy drive. You can also boot a hard drive image mounted as master by specifying "-l C" without the quotes, or the drive as slave by specifying "-l D" @@ -667,12 +697,12 @@ IPX With regard to actually setting up a network, one system needs to be the server. To set this up, type "IPXNET STARTSERVER" (without the quotes) - in a DOSBox session. The server DOSBox session will - automatically add itself to the virtual IPX network. For every - additional computer that should be part of the virtual IPX network, - you'll need to type "IPXNET CONNECT ". - For example, if your server is at bob.dosbox.com, - you would type "IPXNET CONNECT bob.dosbox.com" on every non-server system. + in a DOSBox session. The server DOSBox session will automatically add + itself to the virtual IPX network. For every additional computer that + should be part of the virtual IPX network, you'll need to type + "IPXNET CONNECT ". + For example, if your server is at bob.dosbox.com, you would type + "IPXNET CONNECT bob.dosbox.com" on every non-server system. To play games that need Netbios a file named NETBIOS.EXE from Novell is needed. Establish the IPX connection as explained above, then run @@ -762,17 +792,17 @@ KEYB [languagecode [codepage [codepagefile]]] Examples: - 1) To load the german keyboard layout (automatically uses codepage 858): - keyb gr - 2) To load the russian keyboard layout with codepage 866: - keyb ru 866 - In order to type russian characters press ALT+RIGHT-SHIFT. - 3) To load the french keyboard layout with codepage 850 (where the - codepage is defined in EGACPI.DAT): - keyb fr 850 EGACPI.DAT - 4) To load codepage 858 (without a keyboard layout): - keyb none 858 - This can be used to change the codepage for the freedos keyb2 utility. + 1. To load the german keyboard layout (automatically uses codepage 858): + keyb gr + 2. To load the russian keyboard layout with codepage 866: + keyb ru 866 + In order to type russian characters press ALT+RIGHT-SHIFT. + 3. To load the french keyboard layout with codepage 850 (where the + codepage is defined in EGACPI.DAT): + keyb fr 850 EGACPI.DAT + 4. To load codepage 858 (without a keyboard layout): + keyb none 858 + This can be used to change the codepage for the FreeDOS keyb2 utility. @@ -801,19 +831,20 @@ CTRL-F11 Slow down emulation (Decrease DOSBox Cycles). CTRL-F12 Speed up emulation (Increase DOSBox Cycles). ALT-F12 Unlock speed (turbo button). -These are the default keybindings. They can be changed in the keymapper. +(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.) + + +These are the default keybindings. They can be changed in the keymapper +(see Section 6: Mapper). Saved/recorded files can be found in current_directory/capture -(can be changed in the configfile). +(this can be changed in the DOSBox configuration file). The directory has to exist prior to starting DOSBox, otherwise nothing gets saved/recorded ! -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. - - ========== 6. Mapper: @@ -823,10 +854,10 @@ When you start the DOSBox mapper (either with CTRL-F1 or -startmapper as a command line argument to the DOSBox executable) you are presented with a virtual keyboard and a virtual joystick. -These virtual devices correspond to the keys DOSBox will report to the -DOS applications. If you click on a key with your mouse, you can see in -the lower left corner with which event it is associated (EVENT) and to -what events it is currently bound. +These virtual devices correspond to the keys and events DOSBox will +report to the DOS applications. If you click on a button with your mouse, +you can see in the lower left corner with which event it is associated +(EVENT) and to what events it is currently bound. Event: EVENT BIND: BIND @@ -878,32 +909,32 @@ Examples about remapping the joystick: You have a joystick attached, it is working fine under DOSBox and you want to play some keyboard-only game with the joystick (it is assumed that the game is controlled by the arrows on the keyboard): - 1) Start the mapper, then click on one of the arrows in the middle + 1. Start the mapper, then click on one of the arrows in the middle of the left part of the screen (right above the Mod1/Mod2 buttons). EVENT should be key_left. Now click on Add and move your joystick in the respective direction, this should add an event to the BIND. - 2) Repeat the above for the missing three directions, additionally + 2. Repeat the above for the missing three directions, additionally the buttons of the joystick can be remapped as well (fire/jump). - 3) Click on Save, then on Exit and test it with some game. + 3. Click on Save, then on Exit and test it with some game. You want to swap the y-axis of the joystick because some flightsim uses the up/down joystick movement in a way you don't like, and it is not configurable in the game itself: - 1) Start the mapper and click on Y- in the upper joystick field (this + 1. Start the mapper and click on Y- in the upper joystick field (this is for the first joystick if you have two joysticks attached) or the lower joystick field (second joystick or, if you have only one joystick attached, the second axes cross). EVENT should be jaxis_0_1- (or jaxis_1_1-). - 2) Click on Del to remove the current binding, then click Add and move + 2. Click on Del to remove the current binding, then click Add and move your joystick downwards. A new bind should be created. - 3) Repeat this for Y+, save the layout and finally test it with some game. + 3. Repeat this for Y+, save the layout and finally test it with some game. If you change the default mapping, you can save your changes by clicking on -"Save". DOSBox will save the mapping to a location specified in the configfile -(mapperfile=mapper.txt). At startup, DOSBox will load your mapperfile, if it -is present in the configfile. +"Save". DOSBox will save the mapping to a location specified in the configuration +file (the mapperfile= entry). At startup, DOSBox will load your mapperfile, +if it is present in the DOSBox configuration file. @@ -912,39 +943,40 @@ is present in the configfile. =================== To switch to a different keyboard layout, either the entry "keyboardlayout" -in the [dos] section in dosbox.conf can be used, or the internal DOSBox -program keyb.com. Both accept DOS conforming language codes (see below), but -only by using keyb.com a custom codepage can be specified. +in the [dos] section of the DOSBox configuration file can be used, or the +internal DOSBox program keyb.com. Both accept DOS conforming language codes +(see below), but only by using keyb.com a custom codepage can be specified. Layout switching DOSBox supports a number of keyboard layouts and codepages by default, in this case just the layout identifier needs to be specified (like - keyboardlayout=sv in the DOSBox config file, or using "keyb sv" at - the DOSBox command prompt). + keyboardlayout=sv in the DOSBox configuration file, or using "keyb sv" + at the DOSBox command prompt). Some keyboard layouts (for example layout GK codepage 869 and layout RU codepage 808) have support for dual layouts that can be activated by pressing LEFT-ALT+RIGHT-SHIFT and deactivated by LEFT-ALT+LEFT-SHIFT. Supported external files - The freedos .kl files are supported (freedos keyb2 keyboard layoutfiles) as - well as the freedos keyboard.sys/keybrd2.sys/keybrd3.sys libraries which + The FreeDOS .kl files are supported (FreeDOS keyb2 keyboard layoutfiles) as + well as the FreeDOS keyboard.sys/keybrd2.sys/keybrd3.sys libraries which consist of all available .kl files. See http://projects.freedos.net/keyb/ for precompiled keyboard layouts if - the DOSBox-integrated layouts don't work for some reason, or updated or + the DOSBox-integrated layouts don't work for some reason, or if updated or new layouts become available. - Both .CPI (MSDOS/compatible codepage files) and .CPX (freedos UPX-compressed - codepage files) can be used. Some codepages are compiled into DOSBox, so it - is mostly not needed to care about external codepage files. If you need - a different (or custom) codepage file, copy it into the directory of the - DOSBox configuration file so it is accessible for DOSBox. + Both .CPI (MS-DOS and compatible codepage files) and .CPX (FreeDOS + UPX-compressed codepage files) can be used. Some codepages are compiled + into DOSBox, so it is mostly not needed to care about external codepage + files. If you need a different (or custom) codepage file, copy it into + the directory of the DOSBox configuration file so it is accessible for + DOSBox. Additional layouts can be added by copying the corresponding .kl file into - the directory of dosbox.conf and using the first part of the filename as - language code. + the directory of the DOSBox configuration file and using the first part of + the filename as language code. Example: For the file UZ.KL (keyboard layout for Uzbekistan) specify - "keyboardlayout=uz" in dosbox.conf. + "keyboardlayout=uz" in the DOSBox configuration file. The integration of keyboard layout packages (like keybrd2.sys) works similar. @@ -1023,7 +1055,7 @@ CPU Cycles in the DOSBox configuration file specify for example cycles=30000. When running some DOS application you can raise the cycles with CTRL-F12 even more, but you will be limited by the power of your actual CPU. You can see - how much free time your true CPU has by looking at the Task Manager in + how much free time your real CPU has by looking at the Task Manager in Windows 2000/XP and the System Monitor in Windows 95/98/ME. Once 100% of your real CPU time is used there is no further way to speed up DOSBox unless you reduce the load generated by the non-CPU parts of DOSBox. @@ -1047,7 +1079,7 @@ Graphics emulation Sound emulation You can also try to disable the sound through the setup utility of the game to reduce load on your CPU further. Setting nosound=true does NOT disable - the emulation of sound devices, just the sound output will be disabled. + the emulation of sound devices, just the output of sound will be disabled. Also try to close every program but DOSBox to reserve as much resources as possible for DOSBox. @@ -1116,14 +1148,15 @@ You can edit the generated configfile to customize DOSBox. The file is divided into several sections (the names have [] around it). Some sections have options you can set. # and % indicate comment-lines. -The generated configfile contains the current settings. You can alter them and -start DOSBox with the -conf switch to load the file and use these settings. +The DOSBox configuration file contains the current settings. You can +alter them and start DOSBox with the -conf switch to load the file and +use these settings. DOSBox will first parse the settings in ~/.dosboxrc (Linux), ~\dosbox.conf (Win32) or "~/Library/Preferences/DOSBox Preferences" (MACOSX). Afterwards DOSBox will parse all configfiles specified with the -conf switch. If no configfile is specified with the -conf switch, DOSBox will -look in the current directory for dosbox.conf. +look in the current directory for the DOSBox configuration file. @@ -1160,5 +1193,5 @@ See the THANKS file. ============ See the site: -http://dosbox.sourceforge.net +http://www.dosbox.com for an email address (The Crew-page). From b0fed179bc7f8d7294325e9af09118c92a275165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 12 Mar 2008 17:45:39 +0000 Subject: [PATCH 3034/4131] fix tsr return code handling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3122 --- src/dos/dos.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index e3134a5b..44f9bf52 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.108 2008-03-02 19:45:41 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.109 2008-03-12 17:45:39 c2woody Exp $ */ #include #include @@ -386,7 +386,6 @@ static Bitu DOS_21Handler(void) { // Important: This service does not set the carry flag! DOS_ResizeMemory(dos.psp(),®_dx); DOS_Terminate(true,reg_al); - dos.return_code=reg_al; //Officially a field in the SDA dos.return_mode=RETURN_TSR; break; case 0x1f: /* Get drive parameter block for default drive */ From 09142bde170c06a040c87b5f0c8db53ea8adc4d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 13 Mar 2008 19:53:23 +0000 Subject: [PATCH 3035/4131] weaken some debugging checks Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3123 --- src/ints/int10_char.cpp | 8 ++++---- src/ints/int10_put_pixel.cpp | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index b244b278..728fd04d 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.52 2007-09-24 20:50:40 c2woody Exp $ */ +/* $Id: int10_char.cpp,v 1.53 2008-03-13 19:53:23 c2woody Exp $ */ /* Character displaying moving functions */ @@ -273,7 +273,7 @@ filling: void INT10_SetActivePage(Bit8u page) { Bit16u mem_address; - if (page>7) E_Exit("INT10_SetActivePage page %d",page); + if (page>7) LOG(LOG_INT10,LOG_ERROR)("INT10_SetActivePage page %d",page); mem_address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); /* Write the new page start */ real_writew(BIOSMEM_SEG,BIOSMEM_CURRENT_START,mem_address); @@ -348,7 +348,7 @@ dowrite: void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page) { Bit16u address; - if (page>7) E_Exit("INT10_SetCursorPos page %d"); + if (page>7) LOG(LOG_INT10,LOG_ERROR)("INT10_SetCursorPos page %d"); // Bios cursor pos real_writeb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2,col); real_writeb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2+1,row); diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index d854bdf7..d0c87c0e 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_put_pixel.cpp,v 1.19 2008-01-20 09:21:49 c2woody Exp $ */ +/* $Id: int10_put_pixel.cpp,v 1.20 2008-03-13 19:53:23 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -105,9 +105,9 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { //Perhaps also set mode 1 /* Calculate where the pixel is in video memory */ if (CurMode->plength!=real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)) - E_Exit("PutPixel_EGA_p: %x!=%x",CurMode->plength,real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)); + LOG(LOG_INT10,LOG_ERROR)("PutPixel_EGA_p: %x!=%x",CurMode->plength,real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)); if (CurMode->swidth!=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8) - E_Exit("PutPixel_EGA_w: %x!=%x",CurMode->swidth,real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); + LOG(LOG_INT10,LOG_ERROR)("PutPixel_EGA_w: %x!=%x",CurMode->swidth,real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); PhysPt off=0xa0000+real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)*page+ ((y*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8+x)>>3); /* Bitmask and set/reset should do the rest */ @@ -126,7 +126,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { break; case M_LIN8: { if (CurMode->swidth!=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8) - E_Exit("PutPixel_VGA_w: %x!=%x",CurMode->swidth,real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); + LOG(LOG_INT10,LOG_ERROR)("PutPixel_VGA_w: %x!=%x",CurMode->swidth,real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); PhysPt off=S3_LFB_BASE+y*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8+x; mem_writeb(off,color); break; @@ -159,9 +159,9 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { { /* Calculate where the pixel is in video memory */ if (CurMode->plength!=real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)) - E_Exit("GetPixel_EGA_p: %x!=%x",CurMode->plength,real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)); + LOG(LOG_INT10,LOG_ERROR)("GetPixel_EGA_p: %x!=%x",CurMode->plength,real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)); if (CurMode->swidth!=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8) - E_Exit("GetPixel_EGA_w: %x!=%x",CurMode->swidth,real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); + LOG(LOG_INT10,LOG_ERROR)("GetPixel_EGA_w: %x!=%x",CurMode->swidth,real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); PhysPt off=0xa0000+real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)*page+ ((y*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8+x)>>3); Bitu shift=7-(x & 7); @@ -182,7 +182,7 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { break; case M_LIN8: { if (CurMode->swidth!=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8) - E_Exit("GetPixel_VGA_w: %x!=%x",CurMode->swidth,real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); + LOG(LOG_INT10,LOG_ERROR)("GetPixel_VGA_w: %x!=%x",CurMode->swidth,real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); PhysPt off=S3_LFB_BASE+y*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8+x; *color = mem_readb(off); break; From 27991bc01b020fd7109de7996297cf64cac80f34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 14 Mar 2008 18:16:34 +0000 Subject: [PATCH 3036/4131] add dummy alternate font table indexer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3124 --- src/ints/int10.cpp | 12 +++++++++++- src/ints/int10.h | 4 +++- src/ints/int10_memory.cpp | 5 ++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index ffa93e67..3e053d62 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.cpp,v 1.49 2008-02-18 19:48:22 qbix79 Exp $ */ +/* $Id: int10.cpp,v 1.50 2008-03-14 18:16:34 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -282,11 +282,21 @@ graphics_chars: SegSet16(es,RealSeg(int10.rom.font_8_second)); reg_bp=RealOff(int10.rom.font_8_second); break; + case 0x05: /* alpha alternate 9x14 */ + if (!IS_VGA_ARCH) break; + SegSet16(es,RealSeg(int10.rom.font_14_alternate)); + reg_bp=RealOff(int10.rom.font_14_alternate); + break; case 0x06: /* font 8x16 */ if (!IS_VGA_ARCH) break; SegSet16(es,RealSeg(int10.rom.font_16)); reg_bp=RealOff(int10.rom.font_16); break; + case 0x07: /* alpha alternate 9x16 */ + if (!IS_VGA_ARCH) break; + SegSet16(es,RealSeg(int10.rom.font_16_alternate)); + reg_bp=RealOff(int10.rom.font_16_alternate); + break; default: LOG(LOG_INT10,LOG_ERROR)("Function 11:30 Request for font %2X",reg_bh); break; diff --git a/src/ints/int10.h b/src/ints/int10.h index 9f9f4c2f..07204037 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.h,v 1.34 2008-02-03 20:43:14 c2woody Exp $ */ +/* $Id: int10.h,v 1.35 2008-03-14 18:16:34 c2woody Exp $ */ #include "vga.h" @@ -123,6 +123,8 @@ typedef struct { RealPt font_8_second; RealPt font_14; RealPt font_16; + RealPt font_14_alternate; + RealPt font_16_alternate; RealPt static_state; RealPt video_save_pointers; RealPt video_parameter_table; diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 6582339a..7cc5234c 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_memory.cpp,v 1.25 2008-02-09 12:44:16 c2woody Exp $ */ +/* $Id: int10_memory.cpp,v 1.26 2008-03-14 18:16:34 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -117,6 +117,9 @@ void INT10_SetupRomMemory(void) { phys_writeb(PhysMake(0xf000,0xfa6e)+i,int10_font_08[i]); } RealSetVec(0x1F,int10.rom.font_8_second); + int10.rom.font_14_alternate=RealMake(0xC000,int10.rom.used); + int10.rom.font_16_alternate=RealMake(0xC000,int10.rom.used); + phys_writeb(rom_base+int10.rom.used++,0x00); // end of table (empty) if (IS_EGAVGA_ARCH) { int10.rom.video_parameter_table=RealMake(0xC000,int10.rom.used); From 2ee19ba49de8eb2bd3e23fdcf20784e24d02cf89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 14 Mar 2008 22:00:59 +0000 Subject: [PATCH 3037/4131] add s3-id rom string Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3125 --- src/hardware/vga_s3.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index a927ced5..daed7547 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -16,11 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_s3.cpp,v 1.12 2008-01-12 17:37:48 c2woody Exp $ */ +/* $Id: vga_s3.cpp,v 1.13 2008-03-14 22:00:59 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" #include "vga.h" +#include "mem.h" void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { switch (reg) { @@ -523,4 +524,16 @@ void SVGA_Setup_S3Trio(void) { vga.vmemsize = 4096*1024; vga.s3.reg_36 = 0x12; } + + // S3 ROM signature + PhysPt rom_base=PhysMake(0xc000,0); + phys_writeb(rom_base+0x003f,'S'); + phys_writeb(rom_base+0x0040,'3'); + phys_writeb(rom_base+0x0041,' '); + phys_writeb(rom_base+0x0042,'8'); + phys_writeb(rom_base+0x0043,'6'); + phys_writeb(rom_base+0x0044,'C'); + phys_writeb(rom_base+0x0045,'7'); + phys_writeb(rom_base+0x0046,'6'); + phys_writeb(rom_base+0x0047,'5'); } From 861c9d8ee7068e701752ce59d41bbd1908d4ad73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 16 Mar 2008 18:53:33 +0000 Subject: [PATCH 3038/4131] fix memory wrapping for special 128k window (hal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3126 --- src/hardware/vga_memory.cpp | 67 +++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 81b007fd..c0f7da4c 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_memory.cpp,v 1.49 2008-02-05 17:58:14 c2woody Exp $ */ +/* $Id: vga_memory.cpp,v 1.50 2008-03-16 18:53:33 c2woody Exp $ */ #include #include @@ -151,13 +151,13 @@ public: } public: Bitu readb(PhysPt addr) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_read_full; addr = CHECKED2(addr); return readHandler(addr); } Bitu readw(PhysPt addr) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_read_full; addr = CHECKED2(addr); return @@ -165,7 +165,7 @@ public: (readHandler(addr+1) << 8); } Bitu readd(PhysPt addr) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_read_full; addr = CHECKED2(addr); return @@ -212,14 +212,14 @@ public: flags=PFLAG_NOCODE; } void writeb(PhysPt addr,Bitu val) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_write_full; addr = CHECKED(addr); MEM_CHANGED( addr << 3); writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_write_full; addr = CHECKED(addr); MEM_CHANGED( addr << 3); @@ -227,7 +227,7 @@ public: writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_write_full; addr = CHECKED(addr); MEM_CHANGED( addr << 3); @@ -237,13 +237,13 @@ public: writeHandler(addr+3,(Bit8u)(val >> 24)); } Bitu readb(PhysPt addr) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_read_full; addr = CHECKED(addr); return readHandler(addr); } Bitu readw(PhysPt addr) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_read_full; addr = CHECKED(addr); return @@ -251,7 +251,7 @@ public: (readHandler(addr+1) << 8); } Bitu readd(PhysPt addr) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_read_full; addr = CHECKED(addr); return @@ -296,14 +296,14 @@ public: flags=PFLAG_NOCODE; } void writeb(PhysPt addr,Bitu val) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_write_full; addr = CHECKED2(addr); MEM_CHANGED( addr << 3); writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_write_full; addr = CHECKED2(addr); MEM_CHANGED( addr << 3); @@ -311,7 +311,7 @@ public: writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_write_full; addr = CHECKED2(addr); MEM_CHANGED( addr << 3); @@ -346,13 +346,13 @@ public: hostWrite( &vga.mem.linear[((addr&~3)<<2)+(addr&3)], val ); } Bitu readb(PhysPt addr ) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_read_full; addr = CHECKED(addr); return readHandler( addr ); } Bitu readw(PhysPt addr ) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_read_full; addr = CHECKED(addr); if (GCC_UNLIKELY(addr & 1)) @@ -363,7 +363,7 @@ public: return readHandler( addr ); } Bitu readd(PhysPt addr ) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_read_full; addr = CHECKED(addr); if (GCC_UNLIKELY(addr & 3)) @@ -376,7 +376,7 @@ public: return readHandler( addr ); } void writeb(PhysPt addr, Bitu val ) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_write_full; addr = CHECKED(addr); MEM_CHANGED( addr ); @@ -384,7 +384,7 @@ public: writeCache( addr, val ); } void writew(PhysPt addr,Bitu val) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_write_full; addr = CHECKED(addr); MEM_CHANGED( addr ); @@ -398,7 +398,7 @@ public: writeCache( addr, val ); } void writed(PhysPt addr,Bitu val) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_write_full; addr = CHECKED(addr); MEM_CHANGED( addr ); @@ -432,14 +432,14 @@ public: flags=PFLAG_NOCODE; } void writeb(PhysPt addr,Bitu val) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_write_full; addr = CHECKED2(addr); MEM_CHANGED( addr << 2 ); writeHandler(addr+0,(Bit8u)(val >> 0)); } void writew(PhysPt addr,Bitu val) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_write_full; addr = CHECKED2(addr); MEM_CHANGED( addr << 2); @@ -447,7 +447,7 @@ public: writeHandler(addr+1,(Bit8u)(val >> 8)); } void writed(PhysPt addr,Bitu val) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_write_full; addr = CHECKED2(addr); MEM_CHANGED( addr << 2); @@ -496,39 +496,39 @@ public: flags=PFLAG_NOCODE; } Bitu readb(PhysPt addr) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_read_full; addr = CHECKED(addr); return hostRead( &vga.mem.linear[addr] ); } Bitu readw(PhysPt addr) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_read_full; addr = CHECKED(addr); return hostRead( &vga.mem.linear[addr] ); } Bitu readd(PhysPt addr) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_read_full; addr = CHECKED(addr); return hostRead( &vga.mem.linear[addr] ); } void writeb(PhysPt addr,Bitu val) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_write_full; addr = CHECKED(addr); MEM_CHANGED( addr ); hostWrite( &vga.mem.linear[addr], val ); } void writew(PhysPt addr,Bitu val) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_write_full; addr = CHECKED(addr); MEM_CHANGED( addr ); hostWrite( &vga.mem.linear[addr], val ); } void writed(PhysPt addr,Bitu val) { - addr = PAGING_GetPhysicalAddress(addr) & 0xffff; + addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_write_full; addr = CHECKED(addr); MEM_CHANGED( addr ); @@ -849,7 +849,16 @@ void VGA_SetupHandlers(void) { switch ((vga.gfx.miscellaneous >> 2) & 3) { case 0: vgapages.base = VGA_PAGE_A0; - vgapages.mask = 0x1ffff; + switch (svgaCard) { + case SVGA_TsengET3K: + case SVGA_TsengET4K: + vgapages.mask = 0xffff; + break; + case SVGA_S3Trio: + default: + vgapages.mask = 0x1ffff; + break; + } MEM_SetPageHandler(VGA_PAGE_A0, 32, newHandler ); break; case 1: From 3e5dae287754d5fae7e6f9d84c59cc2e5de50217 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 18 Mar 2008 20:51:26 +0000 Subject: [PATCH 3039/4131] rename vga_X to svga_X. kick vga. make svga_s3 default. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3127 --- src/dosbox.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 1c702a44..b06ebfa2 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.130 2008-02-10 18:55:23 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.131 2008-03-18 20:51:26 qbix79 Exp $ */ #include #include @@ -285,13 +285,13 @@ static void DOSBOX_RealInit(Section * sec) { else if (mtype == "pcjr") { machine = MCH_PCJR; } else if (mtype == "hercules") { machine = MCH_HERC; } else if (mtype == "ega") { machine = MCH_EGA; } - else if (mtype == "vga") { svgaCard = SVGA_S3Trio; } - else if (mtype == "vga_s3") { svgaCard = SVGA_S3Trio; } +// else if (mtype == "vga") { svgaCard = SVGA_S3Trio; } + else if (mtype == "svga_s3") { svgaCard = SVGA_S3Trio; } else if (mtype == "vesa_nolfb") { svgaCard = SVGA_S3Trio; int10.vesa_nolfb = true;} - else if (mtype == "vga_et4000") { svgaCard = SVGA_TsengET4K; } - else if (mtype == "vga_et3000") { svgaCard = SVGA_TsengET3K; } - else if (mtype == "vga_pvga1a") { svgaCard = SVGA_ParadisePVGA1A; } - else if (mtype == "vga_paradise") { svgaCard = SVGA_ParadisePVGA1A; } + else if (mtype == "svga_et4000") { svgaCard = SVGA_TsengET4K; } + else if (mtype == "svga_et3000") { svgaCard = SVGA_TsengET3K; } +// else if (mtype == "vga_pvga1a") { svgaCard = SVGA_ParadisePVGA1A; } + else if (mtype == "svga_paradise") { svgaCard = SVGA_ParadisePVGA1A; } else if (mtype == "vgaonly") { svgaCard = SVGA_None; } else E_Exit("DOSBOX:Unknown machine type %s",mtype.c_str()); } @@ -317,14 +317,14 @@ void DOSBOX_Init(void) { /* Setup all the different modules making up DOSBox */ const char* machines[] = { - "hercules", "cga"," tandy", "pcjr", "ega", "vga", - "vgaonly", "vga_s3", "vga_et3000", "vga_et4000", - "vga_pvga1a", "vga_paradise", "vesa_nolfb", 0 }; + "hercules", "cga"," tandy", "pcjr", "ega", + "vgaonly", "svga_s3", "svga_et3000", "svga_et4000", + "svga_paradise", "vesa_nolfb", 0 }; secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit); Pstring = secprop->Add_string("language",Property::Changeable::Always,""); Pstring->Set_help("Select another language file."); - Pstring = secprop->Add_string("machine",Property::Changeable::OnlyAtStart,"vga"); + Pstring = secprop->Add_string("machine",Property::Changeable::OnlyAtStart,"svga_s3"); Pstring->Set_values(machines); Pstring->Set_help("The type of machine tries to emulate."); From d7294c63148615742032984acad656980ba8e560 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 19 Mar 2008 08:41:45 +0000 Subject: [PATCH 3040/4131] rename LOG_DMA to LOG_DMACONTROL to remove nameclash with soundblaster dma. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3128 --- include/logging.h | 2 +- src/debug/debug_gui.cpp | 4 ++-- src/hardware/dma.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/logging.h b/include/logging.h index dc04e960..37a5afa3 100644 --- a/include/logging.h +++ b/include/logging.h @@ -3,7 +3,7 @@ enum LOG_TYPES { LOG_ALL, LOG_VGA, LOG_VGAGFX,LOG_VGAMISC,LOG_INT10, - LOG_SB,LOG_DMA, + 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, diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 7331bdf0..cc5ed1e3 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug_gui.cpp,v 1.33 2008-03-02 08:53:34 qbix79 Exp $ */ +/* $Id: debug_gui.cpp,v 1.34 2008-03-19 08:41:45 qbix79 Exp $ */ #include "dosbox.h" @@ -218,7 +218,7 @@ void LOG_StartUp(void) { loggrp[LOG_VGAMISC].front="VGAMISC"; loggrp[LOG_INT10].front="INT10"; loggrp[LOG_SB].front="SBLASTER"; - loggrp[LOG_DMA].front="DMA"; + loggrp[LOG_DMACONTROL].front="DMA_CONTROL"; loggrp[LOG_FPU].front="FPU"; loggrp[LOG_CPU].front="CPU"; diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 68de882d..5a367fd9 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -235,7 +235,7 @@ Bitu DmaController::ReadControllerReg(Bitu reg,Bitu len) { } return ret; default: - LOG(LOG_DMA,LOG_NORMAL)("Trying to read undefined DMA port %x",reg); + LOG(LOG_DMACONTROL,LOG_NORMAL)("Trying to read undefined DMA port %x",reg); break; } return 0xffffffff; From d530a9a416c542332db996cc6238985ebd9701c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 19 Mar 2008 17:55:58 +0000 Subject: [PATCH 3041/4131] fix some dos ioctl functions when called for cdrom block devices Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3129 --- src/dos/dos_ioctl.cpp | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 38ecf1e9..a921a0f1 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.29 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.30 2008-03-19 17:55:58 c2woody Exp $ */ #include #include "dosbox.h" @@ -27,7 +27,8 @@ bool DOS_IOCTL(void) { Bitu handle=0;Bit8u drive=0; - if (reg_al<8) { /* call 0-7 use a file handle */ + /* calls 0-7,10,12,16 use a file handle */ + if ((reg_al<8) || (reg_al==0x0a) || (reg_al==0x0c) || (reg_al==0x10)) { handle=RealHandle(reg_bx); if (handle>=DOS_FILES) { DOS_SetError(DOSERR_INVALID_HANDLE); @@ -69,7 +70,7 @@ bool DOS_IOCTL(void) { return true; } } - DOS_SetError(0x0001); // invalid function + DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); return false; case 0x03: /* Write to Device Control Channel */ if (Files[handle]->GetInformation() & 0xc000) { @@ -81,7 +82,7 @@ bool DOS_IOCTL(void) { return true; } } - DOS_SetError(0x0001); // invalid function + DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); return false; case 0x06: /* Get Input Status */ if (Files[handle]->GetInformation() & 0x8000) { //Check for device @@ -106,9 +107,12 @@ bool DOS_IOCTL(void) { return true; case 0x08: /* Check if block device removable */ /* cdrom drives and drive a&b are removable */ - if (drive < 2 || Drives[drive]->isRemovable()) - reg_ax=0; - else reg_ax=1; + if (drive < 2) reg_ax=0; + else if (!Drives[drive]->isRemovable()) reg_ax=1; + else { + DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); + return false; + } return true; case 0x09: /* Check if block device remote */ reg_dx=0; @@ -118,6 +122,10 @@ bool DOS_IOCTL(void) { return true; case 0x0D: /* Generic block device request */ { + if (Drives[drive]->isRemovable()) { + DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); + return false; + } PhysPt ptr = SegPhys(ds)+reg_dx; switch (reg_cl) { case 0x60: /* Get Device parameters */ @@ -158,15 +166,21 @@ bool DOS_IOCTL(void) { break; default : LOG(LOG_IOCTL,LOG_ERROR)("DOS:IOCTL Call 0D:%2X Drive %2X unhandled",reg_cl,drive); + DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); return false; } return true; } - case 0xE: /* Get Logical Drive Map */ + case 0x0E: /* Get Logical Drive Map */ + if (Drives[drive]->isRemovable()) { + DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); + return false; + } reg_al = 0; /* Only 1 logical drive assigned */ return true; default: LOG(LOG_DOSMISC,LOG_ERROR)("DOS:IOCTL Call %2X unhandled",reg_al); + DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); return false; }; return false; From f209b02e6b8797e5653bf5e7a92c68e24ce47751 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 19 Mar 2008 20:35:18 +0000 Subject: [PATCH 3042/4131] Add some modified version of some uncommited part of moe his patch. which add helptexts in the configfile. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3130 --- include/setup.h | 9 ++++-- src/dosbox.cpp | 14 ++++++--- src/gui/sdlmain.cpp | 4 +-- src/misc/setup.cpp | 76 ++++++++++++++++++++++++++++++++++++++------- 4 files changed, 81 insertions(+), 22 deletions(-) diff --git a/include/setup.h b/include/setup.h index 7e7131f4..34625028 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.33 2008-03-02 11:13:46 qbix79 Exp $ */ +/* $Id: setup.h,v 1.34 2008-03-19 20:35:16 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -136,7 +136,9 @@ public: 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 ~Property(){ } + virtual const std::vector& GetValues() const; + protected: Value value; std::vector suggested_values; @@ -278,7 +280,8 @@ public: Section_prop *GetSection() { return section; } const Section_prop *GetSection() const { return section; } void SetValue(std::string const& input); -}; //value bevat totalle string. setvalue zet elk van de sub properties en checked die. + virtual const std::vector& GetValues() const; +}; //value bevat totale string. setvalue zet elk van de sub properties en checked die. class Section_line: public Section{ public: diff --git a/src/dosbox.cpp b/src/dosbox.cpp index b06ebfa2..892bfe90 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.131 2008-03-18 20:51:26 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.132 2008-03-19 20:35:17 qbix79 Exp $ */ #include #include @@ -40,6 +40,7 @@ #include "support.h" #include "mapper.h" #include "ints/int10.h" +#include "render.h" Config * control; MachineType machine; @@ -268,6 +269,7 @@ static void DOSBOX_RealInit(Section * sec) { "# This is the configurationfile for DOSBox %s.\n" "# Lines starting with a # are commentlines.\n" "# They are used to (briefly) document the effect of each option.\n"); + MSG_Add("CONFIG_SUGGESTED_VALUES", "Possible values"); MAPPER_AddHandler(DOSBOX_UnlockSpeed, MK_f12, MMOD2,"speedlock","Speedlock"); std::string cmd_machine; @@ -313,6 +315,8 @@ void DOSBOX_Init(void) { const char *ios[] = { "220", "240", "260", "280", "2a0", "2c0", "2e0", "300", 0 }; const char *irqs[] = { "3", "5", "7", "9", "10", "11", "12", 0 }; const char *dmas[] = { "0", "1", "3", "5", "6", "7", 0 }; + const char *irqssb[] = { "7", "5", "3", "9", "10", "11", "12", 0 }; + const char *dmassb[] = { "1", "5", "0", "3", "6", "7", 0 }; /* Setup all the different modules making up DOSBox */ @@ -388,7 +392,7 @@ void DOSBOX_Init(void) { Pmulti = secprop->Add_multi("cycles",Property::Changeable::Always," "); Pmulti->Set_help( - "Amount of instructions DOSBox tries to emulate each millisecond. Setting this value too high results in sound dropouts and lags. Cycles can be set in 3 ways:" + "Amount of instructions DOSBox tries to emulate each millisecond. Setting this value too high results in sound dropouts and lags. Cycles can be set in 3 ways:\n" " 'auto' tries to guess what a game needs.\n" " It usually works, but can fail for certain games.\n" " 'fixed #number' will set a fixed amount of cycles. This is what you usually need if 'auto' fails.\n" @@ -468,15 +472,15 @@ void DOSBOX_Init(void) { Phex->Set_help("The IO address of the soundblaster."); Pint = secprop->Add_int("irq",Property::Changeable::WhenIdle,7); - Pint->Set_values(irqs); + Pint->Set_values(irqssb); Pint->Set_help("The IRQ number of the soundblaster."); Pint = secprop->Add_int("dma",Property::Changeable::WhenIdle,1); - Pint->Set_values(dmas); + Pint->Set_values(dmassb); Pint->Set_help("The DMA number of the soundblaster."); Pint = secprop->Add_int("hdma",Property::Changeable::WhenIdle,5); - Pint->Set_values(dmas); + Pint->Set_values(dmassb); Pint->Set_help("The High DMA number of the soundblaster."); Pbool = secprop->Add_bool("mixer",Property::Changeable::WhenIdle,true); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 2514653b..9225d544 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.141 2008-02-21 19:25:34 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.142 2008-03-19 20:35:17 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1464,7 +1464,7 @@ int main(int argc, char* argv[]) { Pmulti = sdl_sec->Add_multi("priority", Property::Changeable::Always, ","); Pmulti->SetValue("higher,normal"); - Pmulti->Set_help("priority -- Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized. (pause is only valid for the second entry)"); + Pmulti->Set_help("Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized. (pause is only valid for the second entry)"); const char* actt[] = { "lowest", "lower", "normal", "higher", "highest", "pause", 0}; Pstring = Pmulti->GetSection()->Add_string("active",Property::Changeable::Always,"higher"); diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 8fa818b1..72c53193 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.46 2008-02-25 06:21:09 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.47 2008-03-19 20:35:18 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -300,6 +300,22 @@ void Prop_multival::SetValue(std::string const& input) { p->SetValue(in); } } +const std::vector& Property::GetValues() const { + return suggested_values; +} + const std::vector& Prop_multival::GetValues() const +{ + Property *p = section->Get_prop(0); + //No properties in this section. do nothing + if(!p) return suggested_values; + int i =0; + string::size_type loc = string::npos; + while( (p = section->Get_prop(i++)) ) { + std::vector v = p->GetValues(); + if(!v.empty()) return p->GetValues(); + } + return suggested_values; +} /* void Section_prop::Add_double(char const * const _propname, double _value) { @@ -469,22 +485,58 @@ void Config::PrintConfig(char const * const configfilename) const { fprintf(outfile,"\n"); for (const_it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ /* Print out the Section header */ + Section_prop *sec = dynamic_cast(*tel); strcpy(temp,(*tel)->GetName()); lowcase(temp); fprintf(outfile,"[%s]\n",temp); - upcase(temp); - strcat(temp,"_CONFIGFILE_HELP"); - const char * helpstr=MSG_Get(temp); - char * helpwrite=helpline; - while (*helpstr) { - *helpwrite++=*helpstr; - if (*helpstr == '\n') { - *helpwrite=0; - fprintf(outfile,"# %s",helpline); - helpwrite=helpline; + + if (sec) { + Property *p; + size_t i = 0, maxwidth = 0; + while ((p = sec->Get_prop(i++))) { + size_t w = strlen(p->propname.c_str()); + if (w > maxwidth) maxwidth = w; + } + i=0; + char prefix[80]; + snprintf(prefix,80, "\n# %*s ", maxwidth, ""); + while ((p = sec->Get_prop(i++))) { + std::string help = p->Get_help(); + std::string::size_type pos = std::string::npos; + while ((pos = help.find("\n", pos+1)) != std::string::npos) { + help.replace(pos, 1, prefix); + } + + fprintf(outfile, "# %*s: %s", maxwidth, p->propname.c_str(), help.c_str()); + + std::vector values = p->GetValues(); + if (!values.empty()) { + fprintf(outfile, "%s%s:", prefix, MSG_Get("CONFIG_SUGGESTED_VALUES")); + std::vector::iterator it = values.begin(); + while (it != values.end()) { + if (it != values.begin()) fputs(",", outfile); + fprintf(outfile, " %s", (*it).ToString().c_str()); + ++it; + } + } + fprintf(outfile, "\n"); + } + } else { + upcase(temp); + strcat(temp,"_CONFIGFILE_HELP"); + const char * helpstr=MSG_Get(temp); + char * helpwrite=helpline; + while (*helpstr) { + *helpwrite++=*helpstr; + if (*helpstr == '\n') { + *helpwrite=0; + fprintf(outfile,"# %s",helpline); + helpwrite=helpline; + } + helpstr++; } - helpstr++; } + fprintf(outfile,"\n"); (*tel)->PrintData(outfile); fprintf(outfile,"\n"); /* Always an empty line between sections */ From 434cc5408b79e3d6989e60be48a8c259ebf888a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 20 Mar 2008 00:13:41 +0000 Subject: [PATCH 3043/4131] early checking for v86 mode protection violation of special fullcore opcodes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3131 --- src/cpu/core_full/load.h | 3 +++ src/cpu/core_full/op.h | 3 --- src/cpu/core_full/optable.h | 6 +++--- src/cpu/core_full/support.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index ec63d572..a0c1ca47 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -6,6 +6,9 @@ switch (inst.code.load) { case L_POPdRM: inst_op1_d = Pop_32(); goto case_L_MODRM; + case L_MODRM_NVM: + if ((reg_flags & FLAG_VM) || !cpu.pmode) goto illegalopcode; + goto case_L_MODRM; case_L_MODRM: case L_MODRM: inst.rm=Fetchb(); diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index ed407a3a..67ae2c9a 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -459,7 +459,6 @@ switch (inst.code.op) { break; case O_LAR: { - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode; Bitu ar=inst_op2_d; CPU_LAR(inst_op1_w,ar); inst_op1_d=(Bit32u)ar; @@ -467,7 +466,6 @@ switch (inst.code.op) { break; case O_LSL: { - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode; Bitu limit=inst_op2_d; CPU_LSL(inst_op1_w,limit); inst_op1_d=(Bit32u)limit; @@ -475,7 +473,6 @@ switch (inst.code.op) { break; case O_ARPL: { - if ((reg_flags & FLAG_VM) || !cpu.pmode) goto illegalopcode; Bitu new_sel=inst_op1_d; CPU_ARPL(new_sel,inst_op2_d); inst_op1_d=(Bit32u)new_sel; diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 93c51057..fcdb1508 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -69,7 +69,7 @@ static OpCode OpCodeTable[1024]={ /* 0x60 - 0x67 */ {D_PUSHAw ,0 ,0 ,0 },{D_POPAw ,0 ,0 ,0 }, -{L_MODRM ,O_BOUNDw ,0 ,M_Gw },{L_MODRM ,O_ARPL ,S_Ew ,M_EwGw }, +{L_MODRM ,O_BOUNDw ,0 ,M_Gw },{L_MODRM_NVM ,O_ARPL ,S_Ew ,M_EwGw }, {L_PRESEG ,0 ,0 ,fs },{L_PRESEG ,0 ,0 ,gs }, {L_PREOP ,0 ,0 ,0 },{L_PREADD ,0 ,0 ,0 }, /* 0x68 - 0x6f */ @@ -183,7 +183,7 @@ static OpCode OpCodeTable[1024]={ /* 0x100 - 0x107 */ {L_MODRM ,O_GRP6w ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7w ,S_Ew ,M_Ew }, -{L_MODRM ,O_LAR ,S_Gw ,M_EwGw },{L_MODRM ,O_LSL ,S_Gw ,M_EwGw }, +{L_MODRM_NVM ,O_LAR ,S_Gw ,M_EwGw },{L_MODRM_NVM ,O_LSL ,S_Gw ,M_EwGw }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {D_CLTS ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x108 - 0x10f */ @@ -539,7 +539,7 @@ static OpCode OpCodeTable[1024]={ /* 0x300 - 0x307 */ {L_MODRM ,O_GRP6d ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7d ,S_Ew ,M_Ew }, -{L_MODRM ,O_LAR ,S_Gd ,M_EdGd },{L_MODRM ,O_LSL ,S_Gd ,M_EdGd }, +{L_MODRM_NVM ,O_LAR ,S_Gd ,M_EdGd },{L_MODRM_NVM ,O_LSL ,S_Gd ,M_EdGd }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {D_CLTS ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x308 - 0x30f */ diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index f7f54b00..cde08ebc 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -2,7 +2,7 @@ enum { L_N=0, L_SKIP, /* Grouped ones using MOD/RM */ - L_MODRM,L_POPwRM,L_POPdRM, + L_MODRM,L_MODRM_NVM,L_POPwRM,L_POPdRM, L_Ib,L_Iw,L_Id, L_Ibx,L_Iwx,L_Idx, //Sign extend From 89893d77bbd0ef9b0bc8e92178972c850c96b8aa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 21 Mar 2008 04:36:20 +0000 Subject: [PATCH 3044/4131] Fix padding. Thanks eL-PuSHeR Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3132 --- src/dosbox.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 892bfe90..9f316017 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.132 2008-03-19 20:35:17 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.133 2008-03-21 04:36:20 qbix79 Exp $ */ #include #include @@ -321,7 +321,7 @@ void DOSBOX_Init(void) { /* Setup all the different modules making up DOSBox */ const char* machines[] = { - "hercules", "cga"," tandy", "pcjr", "ega", + "hercules", "cga", "tandy", "pcjr", "ega", "vgaonly", "svga_s3", "svga_et3000", "svga_et4000", "svga_paradise", "vesa_nolfb", 0 }; secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit); From cd2e2fd3066d518ccc1428981d52c3014926e46f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 29 Mar 2008 16:47:09 +0000 Subject: [PATCH 3045/4131] move xms callback location to have offset!=0 (buggy xms check in Legend of Kyrandia setup) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3133 --- src/ints/xms.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 473df0f3..e19b6d33 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.51 2007-10-19 12:15:40 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.52 2008-03-29 16:47:09 c2woody Exp $ */ #include #include @@ -270,7 +270,6 @@ INLINE void SET_RESULT(Bitu res,bool touch_bl_on_succes=true) { Bitu XMS_Handler(void) { // LOG(LOG_MISC,LOG_ERROR)("XMS: CALL %02X",reg_ah); switch (reg_ah) { - case XMS_GET_VERSION: /* 00 */ reg_ax=XMS_VERSION; reg_bx=XMS_DRIVER_VERSION; @@ -426,7 +425,7 @@ public: DOS_AddMultiplexHandler(multiplex_xms); /* place hookable callback in writable memory area */ - xms_callback=RealMake(DOS_GetMemory(0x1),0); + xms_callback=RealMake(DOS_GetMemory(0x1)-1,0x10); callbackhandler.Install(&XMS_Handler,CB_HOOKABLE,Real2Phys(xms_callback),"XMS Handler"); // pseudocode for CB_HOOKABLE: // jump near skip From 549100192361812e0adfccdf898141040abb8338 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 30 Mar 2008 18:02:23 +0000 Subject: [PATCH 3046/4131] Add zooming stuff from hal. Add some fixes by wd and hal to prevent crashing related not enough lines calculated with screenresizes (vgaonly). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3134 --- include/vga.h | 3 +-- src/hardware/vga_crtc.cpp | 20 ++++++++++++----- src/hardware/vga_dac.cpp | 5 ++++- src/hardware/vga_draw.cpp | 45 ++++++++++++++++++++++----------------- 4 files changed, 45 insertions(+), 28 deletions(-) diff --git a/include/vga.h b/include/vga.h index ba39f2b2..7a849bf5 100644 --- a/include/vga.h +++ b/include/vga.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga.h,v 1.39 2008-02-06 18:22:27 c2woody Exp $ */ +/* $Id: vga.h,v 1.40 2008-03-30 18:02:23 qbix79 Exp $ */ #ifndef DOSBOX_VGA_H #define DOSBOX_VGA_H @@ -128,7 +128,6 @@ typedef struct { double vdend, vtotal; double hdend, htotal; double parts; - double virtline; } delay; double aspect_ratio; bool double_scan; diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index cc941e12..70fce996 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_crtc.cpp,v 1.31 2008-02-06 18:23:34 c2woody Exp $ */ +/* $Id: vga_crtc.cpp,v 1.32 2008-03-30 18:02:23 qbix79 Exp $ */ #include #include "dosbox.h" @@ -141,11 +141,21 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { if (IS_VGA_ARCH) vga.config.line_compare=(vga.config.line_compare & 0x5ff)|(val&0x40)<<3; - // don't call resize on doublescan change (magic.exe by European Technology) - if ((vga.crtc.maximum_scan_line ^ val) & ((svgaCard==SVGA_None)?0x3f:0xbf)) { + if(IS_VGA_ARCH && (svgaCard==SVGA_None) && (vga.mode==M_EGA || vga.mode==M_VGA)) { + // in vgaonly mode we take special care of line repeats (excluding CGA modes) + if ((vga.crtc.maximum_scan_line ^ val) & 0x20) { + crtc(maximum_scan_line)=val; + VGA_StartResize(); + } crtc(maximum_scan_line)=val; - VGA_StartResize(); - } else crtc(maximum_scan_line)=val; + vga.draw.address_line_total = (val &0x1F) + 1; + if(val&0x80) vga.draw.address_line_total*=2; + } else { + if ((vga.crtc.maximum_scan_line ^ val) & 0xbf) { + crtc(maximum_scan_line)=val; + VGA_StartResize(); + } + } /* 0-4 Number of scan lines in a character row -1. In graphics modes this is the number of times (-1) the line is displayed before passing on to diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index 80dc7196..2dd7f52a 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -179,9 +179,12 @@ void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal) { /* Check if this is a new color */ vga.dac.combine[attr]=pal; switch (vga.mode) { - case M_VGA: case M_LIN8: break; + case M_VGA: + // used by copper demo; almost no video card seems to suport it + if(!IS_VGA_ARCH || (svgaCard!=SVGA_None)) break; + default: vga.dac.xlat16[attr] = ((vga.dac.rgb[pal].blue>>1)&0x1f) | (((vga.dac.rgb[pal].green)&0x3f)<<5)| diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index dbfb1ba6..033c5ad7 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.93 2008-03-08 12:29:59 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.94 2008-03-30 18:02:23 qbix79 Exp $ */ #include #include @@ -634,17 +634,12 @@ static INLINE void VGA_ChangesEnd(void ) { static void VGA_DrawSingleLine(Bitu blah) { if(vga.attr.enabled || (!(vga.mode==M_VGA || vga.mode==M_EGA))) { Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line ); - // Magic Circle last part - if((vga.crtc.maximum_scan_line & 0x80)&& !vga.draw.doubleheight) - RENDER_DrawLine(data); RENDER_DrawLine(data); } else { // else draw overscan color line // TODO: black line should be good enough for now // (DoWhackaDo) memset(TempLine, 0, sizeof(TempLine)); - if((vga.crtc.maximum_scan_line & 0x80)&& !vga.draw.doubleheight) - RENDER_DrawLine(TempLine); RENDER_DrawLine(TempLine); } @@ -662,8 +657,8 @@ static void VGA_DrawSingleLine(Bitu blah) { } vga.draw.address_line=0; } - if ((vga.draw.lines_done < vga.draw.lines_total) && (!vga.draw.resizing)) { - PIC_AddEvent(VGA_DrawSingleLine,(float)vga.draw.delay.virtline); + if (vga.draw.lines_done < vga.draw.lines_total) { + PIC_AddEvent(VGA_DrawSingleLine,(float)vga.draw.delay.htotal); } else RENDER_EndUpdate(); } @@ -855,7 +850,7 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.vret_triggered=true; } } - if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) PIC_AddEvent(VGA_DrawSingleLine,(float)vga.draw.delay.htotal); + if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) PIC_AddEvent(VGA_DrawSingleLine,(float)(vga.draw.delay.htotal/4.0)); else PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts,vga.draw.parts_lines); //VGA_DrawPart( vga.draw.parts_lines ); //PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts,vga.draw.parts_lines); @@ -1010,9 +1005,17 @@ void VGA_SetupDrawing(Bitu val) { if (vga.seq.clocking_mode & 0x8) { htotal*=2; } - vga.draw.address_line_total=(vga.crtc.maximum_scan_line&0xf)+1; - - if (IS_VGA_ARCH) vga.draw.double_scan=(vga.crtc.maximum_scan_line&0x80)>0; + vga.draw.address_line_total=(vga.crtc.maximum_scan_line&0x1f)+1; + if(IS_VGA_ARCH && (svgaCard==SVGA_None) && (vga.mode==M_EGA || vga.mode==M_VGA)) { + // vgaonly; can't use with CGA because these use address_line for their + // own purposes. + // Set the low resolution modes to have as many lines as are scanned - + // Quite a few demos change the max_scanline register at display time + // to get SFX: Majic12 show, Magic circle, Copper, GBU, Party91 + if( vga.crtc.maximum_scan_line&0x80) vga.draw.address_line_total*=2; + vga.draw.double_scan=false; + } + else if (IS_VGA_ARCH) vga.draw.double_scan=(vga.crtc.maximum_scan_line&0x80)>0; else vga.draw.double_scan=(vtotal==262); } else { htotal = vga.other.htotal + 1; @@ -1313,11 +1316,15 @@ void VGA_SetupDrawing(Bitu val) { if (IS_VGA_ARCH) height/=2; doubleheight=true; } - //Only check for extra double height in vga modes - if (!doubleheight && (vga.mode Date: Sun, 30 Mar 2008 19:59:42 +0000 Subject: [PATCH 3047/4131] revert some linecompare hack, fix vga drawing start for zero-linecompare values (fixes Event Horizon game glitches) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3135 --- src/hardware/vga_draw.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 033c5ad7..7df2c39b 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.94 2008-03-30 18:02:23 qbix79 Exp $ */ +/* $Id: vga_draw.cpp,v 1.95 2008-03-30 19:59:42 c2woody Exp $ */ #include #include @@ -671,8 +671,8 @@ static void VGA_DrawPart(Bitu lines) { vga.draw.address_line=0; vga.draw.address+=vga.draw.address_add; } -// vga.draw.lines_done++; - if (vga.draw.split_line==vga.draw.lines_done++) { + vga.draw.lines_done++; + if (vga.draw.split_line==vga.draw.lines_done) { #ifdef VGA_KEEP_CHANGES VGA_ChangesEnd( ); #endif @@ -801,6 +801,8 @@ static void VGA_VerticalTimer(Bitu val) { case M_LIN4: vga.draw.address *= 8; vga.draw.address += vga.config.pel_panning; + if ((vga.draw.split_line==0) && (vga.attr.mode_control&0x20)) + vga.draw.address = 0; #ifdef VGA_KEEP_CHANGES VGA_ChangesStart(); #endif @@ -819,6 +821,8 @@ static void VGA_VerticalTimer(Bitu val) { case M_LIN32: vga.draw.address *= 4; vga.draw.address += vga.config.pel_panning; + if ((vga.draw.split_line==0) && (vga.attr.mode_control&0x20)) + vga.draw.address = 0; #ifdef VGA_KEEP_CHANGES VGA_ChangesStart(); #endif @@ -1318,8 +1322,8 @@ void VGA_SetupDrawing(Bitu val) { } if(!(IS_VGA_ARCH && (svgaCard==SVGA_None) && (vga.mode==M_EGA || vga.mode==M_VGA))) { - // what is this hack needed for? //Only check for extra double height in vga modes + //(line multiplying by address_line_total) if (!doubleheight && (vga.mode Date: Mon, 31 Mar 2008 14:43:34 +0000 Subject: [PATCH 3048/4131] some vga bioses scramble the high part of ax for int10/ah=1a (fixes Gizmos&Gadgets graphics card detection) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3136 --- src/ints/int10.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 3e053d62..2261354e 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.cpp,v 1.50 2008-03-14 18:16:34 c2woody Exp $ */ +/* $Id: int10.cpp,v 1.51 2008-03-31 14:43:34 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -426,7 +426,7 @@ graphics_chars: else reg_bx=dccentry; } else reg_bx=0xffff; } else reg_bx=0xffff; - reg_al=0x1A; + reg_ax=0x1A; // high part destroyed or zeroed depending on BIOS } else if (reg_al==1) { // set dcc Bit8u newidx=0xff; // walk the tables... @@ -450,7 +450,7 @@ graphics_chars: } real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,newidx); - reg_al=0x1A; + reg_ax=0x1A; // high part destroyed or zeroed depending on BIOS } break; case 0x1B: /* functionality State Information */ From 650536481f1970b636dd0ccf9b3eb256cc2c4489 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 31 Mar 2008 19:09:51 +0000 Subject: [PATCH 3049/4131] Remove implementation depended behavior.(fixes black lines with gcc 3.4 on vgaonly) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3137 --- src/hardware/vga_draw.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 7df2c39b..8cdd2d89 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.95 2008-03-30 19:59:42 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.96 2008-03-31 19:09:51 qbix79 Exp $ */ #include #include @@ -575,13 +575,15 @@ static Bit8u * VGA_TEXT_Xlat16_Draw_Line_9(Bitu vidstart, Bitu line) { } if (FontMask[col>>7]==0) font=0; Bit8u mask=0x80; - for(int i = 0; i < 8; i++) { - *draw++= vga.dac.xlat16[font&mask?fg:bg]; + for (int i = 0; i < 7; i++) { + *draw++=vga.dac.xlat16[font&mask?fg:bg]; mask>>=1; } + Bit16u lastval=vga.dac.xlat16[font&mask?fg:bg]; + *draw++=lastval; *draw++=(((vga.attr.mode_control&0x04) && ((chr<0xc0) || (chr>0xdf))) && !(underline && ((col&0x07) == 0x01))) ? - (vga.dac.xlat16[bg]) : draw[-1]; + (vga.dac.xlat16[bg]) : lastval; if (pel_pan) { if (underline && ((col&0x07) == 0x01)) font=0xff; else font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])< Date: Tue, 1 Apr 2008 19:58:34 +0000 Subject: [PATCH 3050/4131] add vga horizontal address byte skipping Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3138 --- include/vga.h | 3 +- src/hardware/vga_draw.cpp | 137 +++++++++++++++++++++----------------- 2 files changed, 79 insertions(+), 61 deletions(-) diff --git a/include/vga.h b/include/vga.h index 7a849bf5..91ff973b 100644 --- a/include/vga.h +++ b/include/vga.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga.h,v 1.40 2008-03-30 18:02:23 qbix79 Exp $ */ +/* $Id: vga.h,v 1.41 2008-04-01 19:58:17 c2woody Exp $ */ #ifndef DOSBOX_VGA_H #define DOSBOX_VGA_H @@ -119,6 +119,7 @@ typedef struct { Bitu parts_total; Bitu parts_lines; Bitu parts_left; + Bitu byte_panning_shift; struct { double framestart; double vrstart, vrend; // V-retrace diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 8cdd2d89..16494d4c 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.96 2008-03-31 19:09:51 qbix79 Exp $ */ +/* $Id: vga_draw.cpp,v 1.97 2008-04-01 19:58:34 c2woody Exp $ */ #include #include @@ -248,21 +248,21 @@ static Bit8u * VGA_Draw_VGA_Line_HWMouse( Bitu vidstart, Bitu line) { mappoint = (((bitsA >> z) & 0x1) << 1) | ((bitsB >> z) & 0x1); if(mapat >= vga.s3.hgc.posx) { switch(mappoint) { - case 0: - TempLine[xat] = vga.s3.hgc.backstack[0]; - break; - case 1: - TempLine[xat] = vga.s3.hgc.forestack[0]; - break; - case 2: - //Transparent - break; - case 3: - // Invert screen data - TempLine[xat] = ~TempLine[xat]; - break; - } - xat++; + case 0: + TempLine[xat] = vga.s3.hgc.backstack[0]; + break; + case 1: + TempLine[xat] = vga.s3.hgc.forestack[0]; + break; + case 2: + //Transparent + break; + case 3: + // Invert screen data + TempLine[xat] = ~TempLine[xat]; + break; + } + xat++; } mapat++; --z; @@ -312,24 +312,24 @@ static Bit8u * VGA_Draw_LIN16_Line_HWMouse(Bitu vidstart, Bitu line) { mappoint = (((bitsA >> z) & 0x1) << 1) | ((bitsB >> z) & 0x1); if(mapat >= vga.s3.hgc.posx) { switch(mappoint) { - case 0: - TempLine[xat] = vga.s3.hgc.backstack[0]; - TempLine[xat+1] = vga.s3.hgc.backstack[1]; - break; - case 1: - TempLine[xat] = vga.s3.hgc.forestack[0]; - TempLine[xat+1] = vga.s3.hgc.forestack[1]; - break; - case 2: - //Transparent - break; - case 3: - // Invert screen data - TempLine[xat] = ~TempLine[xat]; - TempLine[xat+1] = ~TempLine[xat+1]; - break; - } - xat+=2; + case 0: + TempLine[xat] = vga.s3.hgc.backstack[0]; + TempLine[xat+1] = vga.s3.hgc.backstack[1]; + break; + case 1: + TempLine[xat] = vga.s3.hgc.forestack[0]; + TempLine[xat+1] = vga.s3.hgc.forestack[1]; + break; + case 2: + //Transparent + break; + case 3: + // Invert screen data + TempLine[xat] = ~TempLine[xat]; + TempLine[xat+1] = ~TempLine[xat+1]; + break; + } + xat+=2; } mapat++; --z; @@ -379,30 +379,30 @@ static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart, Bitu line) { mappoint = (((bitsA >> z) & 0x1) << 1) | ((bitsB >> z) & 0x1); if(mapat >= vga.s3.hgc.posx) { switch(mappoint) { - case 0: - TempLine[xat] = vga.s3.hgc.backstack[0]; - TempLine[xat+1] = vga.s3.hgc.backstack[1]; - TempLine[xat+2] = vga.s3.hgc.backstack[2]; - TempLine[xat+3] = 255; - break; - case 1: - TempLine[xat] = vga.s3.hgc.forestack[0]; - TempLine[xat+1] = vga.s3.hgc.forestack[1]; - TempLine[xat+2] = vga.s3.hgc.forestack[2]; - TempLine[xat+3] = 255; - break; - case 2: - //Transparent - break; - case 3: - // Invert screen data - TempLine[xat] = ~TempLine[xat]; - TempLine[xat+1] = ~TempLine[xat+1]; - TempLine[xat+2] = ~TempLine[xat+2]; - TempLine[xat+3] = ~TempLine[xat+3]; - break; - } - xat+=4; + case 0: + TempLine[xat] = vga.s3.hgc.backstack[0]; + TempLine[xat+1] = vga.s3.hgc.backstack[1]; + TempLine[xat+2] = vga.s3.hgc.backstack[2]; + TempLine[xat+3] = 255; + break; + case 1: + TempLine[xat] = vga.s3.hgc.forestack[0]; + TempLine[xat+1] = vga.s3.hgc.forestack[1]; + TempLine[xat+2] = vga.s3.hgc.forestack[2]; + TempLine[xat+3] = 255; + break; + case 2: + //Transparent + break; + case 3: + // Invert screen data + TempLine[xat] = ~TempLine[xat]; + TempLine[xat+1] = ~TempLine[xat+1]; + TempLine[xat+2] = ~TempLine[xat+2]; + TempLine[xat+3] = ~TempLine[xat+3]; + break; + } + xat+=4; } mapat++; --z; @@ -655,7 +655,12 @@ static void VGA_DrawSingleLine(Bitu blah) { vga.draw.address=0; if (!(vga.attr.mode_control&0x20)) { // pel panning enabled - if (!(vga.mode==M_TEXT)) vga.draw.address = vga.config.pel_panning; + if (!(vga.mode==M_TEXT)) { + vga.draw.address = vga.config.pel_panning + + vga.draw.byte_panning_shift*vga.config.bytes_skip; + } else { + vga.draw.address = vga.draw.byte_panning_shift*vga.config.bytes_skip; + } } vga.draw.address_line=0; } @@ -681,7 +686,12 @@ static void VGA_DrawPart(Bitu lines) { vga.draw.address=0; if (!(vga.attr.mode_control&0x20)) { // pel panning enabled - if (!(vga.mode==M_TEXT)) vga.draw.address = vga.config.pel_panning; + if (!(vga.mode==M_TEXT)) { + vga.draw.address = vga.config.pel_panning + + vga.draw.byte_panning_shift*vga.config.bytes_skip; + } else { + vga.draw.address = vga.draw.byte_panning_shift*vga.config.bytes_skip; + } } vga.draw.address_line=0; #ifdef VGA_KEEP_CHANGES @@ -795,16 +805,19 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.split_line = (vga.config.line_compare/vga.draw.lines_scaled); if (vga.draw.split_line==0) vga.draw.address = 0; else vga.draw.address = vga.config.real_start; + vga.draw.byte_panning_shift = 0; // go figure... if (machine==MCH_EGA) vga.draw.split_line*=2; // if (machine==MCH_EGA) vga.draw.split_line = ((((vga.config.line_compare&0x5ff)+1)*2-1)/vga.draw.lines_scaled); switch (vga.mode) { case M_EGA: case M_LIN4: + vga.draw.address += vga.config.bytes_skip; vga.draw.address *= 8; vga.draw.address += vga.config.pel_panning; if ((vga.draw.split_line==0) && (vga.attr.mode_control&0x20)) vga.draw.address = 0; + vga.draw.byte_panning_shift = 8; #ifdef VGA_KEEP_CHANGES VGA_ChangesStart(); #endif @@ -821,10 +834,12 @@ static void VGA_VerticalTimer(Bitu val) { case M_LIN15: case M_LIN16: case M_LIN32: + vga.draw.address += vga.config.bytes_skip; vga.draw.address *= 4; vga.draw.address += vga.config.pel_panning; if ((vga.draw.split_line==0) && (vga.attr.mode_control&0x20)) vga.draw.address = 0; + vga.draw.byte_panning_shift = 4; #ifdef VGA_KEEP_CHANGES VGA_ChangesStart(); #endif @@ -832,6 +847,8 @@ static void VGA_VerticalTimer(Bitu val) { case M_TEXT: if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) vga.draw.address = vga.config.real_start * 2; else vga.draw.address = vga.config.display_start * 2; + vga.draw.address += vga.config.bytes_skip*2; + vga.draw.byte_panning_shift = 2; case M_TANDY_TEXT: case M_HERC_TEXT: vga.draw.cursor.address=vga.config.cursor_start*2; From e43272326e11e3977b1e0de2ccfcc155cde76255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 3 Apr 2008 18:28:19 +0000 Subject: [PATCH 3051/4131] fix undocumented error handling of dos freesize check for non-present floppy drives Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3139 --- src/dos/dos.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 44f9bf52..700ba82c 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.109 2008-03-12 17:45:39 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.110 2008-04-03 18:28:19 c2woody Exp $ */ #include #include @@ -435,13 +435,22 @@ static Bitu DOS_21Handler(void) { { Bit16u bytes,clusters,free; Bit8u sectors; - if(DOS_GetFreeDiskSpace(reg_dl,&bytes,§ors,&clusters,&free)) { + if (DOS_GetFreeDiskSpace(reg_dl,&bytes,§ors,&clusters,&free)) { reg_ax=sectors; reg_bx=free; reg_cx=bytes; reg_dx=clusters; } else { - reg_ax=0xffff; + Bit8u drive=reg_dl; + if (drive==0) drive=DOS_GetDefaultDrive(); + else drive--; + if (drive<2) { + // floppy oddity, non-present drives don't fail with the + // invalid drive error + CALLBACK_SCF(true); + } else { + reg_ax=0xffff; // invalid drive specified + } } } break; From 865b429d85e009c29a6629a5153fb74504a78e2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 7 Apr 2008 19:11:48 +0000 Subject: [PATCH 3052/4131] revert "fix", update comment (int24 abortable hook not feasible here) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3140 --- src/dos/dos.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 700ba82c..e32f9292 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.110 2008-04-03 18:28:19 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.111 2008-04-07 19:11:48 c2woody Exp $ */ #include #include @@ -445,12 +445,11 @@ static Bitu DOS_21Handler(void) { if (drive==0) drive=DOS_GetDefaultDrive(); else drive--; if (drive<2) { - // floppy oddity, non-present drives don't fail with the - // invalid drive error - CALLBACK_SCF(true); - } else { - reg_ax=0xffff; // invalid drive specified + // floppy drive, non-present drivesdisks issue floppy check through int24 + // (critical error handler); needed for Mixed up Mother Goose (hook) +// CALLBACK_RunRealInt(0x24); } + reg_ax=0xffff; // invalid drive specified } } break; From e421cd96d2a29b40397154c862256b904e0c4230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 12 Apr 2008 20:32:19 +0000 Subject: [PATCH 3053/4131] ega always resets vga pel pan/byte skip on line compare (hal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3141 --- src/hardware/vga_draw.cpp | 126 +++++++++++++++----------------------- 1 file changed, 48 insertions(+), 78 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 16494d4c..9b506cd4 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.97 2008-04-01 19:58:34 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.98 2008-04-12 20:32:19 c2woody Exp $ */ #include #include @@ -633,6 +633,19 @@ static INLINE void VGA_ChangesEnd(void ) { #endif +static void VGA_ProcessSplit() { + // On the EGA the address is always reset to 0. + if ((vga.attr.mode_control&0x20) || (machine==MCH_EGA)) { + vga.draw.address=0; + } else { + // In text mode only the characters are shifted by panning, not the address; + // this is done in the text line draw function. + vga.draw.address = vga.draw.byte_panning_shift*vga.config.bytes_skip; + if (!(vga.mode==M_TEXT)) vga.draw.address += vga.config.pel_panning; + } + vga.draw.address_line=0; +} + static void VGA_DrawSingleLine(Bitu blah) { if(vga.attr.enabled || (!(vga.mode==M_VGA || vga.mode==M_EGA))) { Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line ); @@ -651,19 +664,7 @@ static void VGA_DrawSingleLine(Bitu blah) { vga.draw.address+=vga.draw.address_add; } vga.draw.lines_done++; - if (vga.draw.split_line==vga.draw.lines_done) { - vga.draw.address=0; - if (!(vga.attr.mode_control&0x20)) { - // pel panning enabled - if (!(vga.mode==M_TEXT)) { - vga.draw.address = vga.config.pel_panning + - vga.draw.byte_panning_shift*vga.config.bytes_skip; - } else { - vga.draw.address = vga.draw.byte_panning_shift*vga.config.bytes_skip; - } - } - vga.draw.address_line=0; - } + if (vga.draw.split_line==vga.draw.lines_done) VGA_ProcessSplit(); if (vga.draw.lines_done < vga.draw.lines_total) { PIC_AddEvent(VGA_DrawSingleLine,(float)vga.draw.delay.htotal); } else RENDER_EndUpdate(); @@ -683,17 +684,7 @@ static void VGA_DrawPart(Bitu lines) { #ifdef VGA_KEEP_CHANGES VGA_ChangesEnd( ); #endif - vga.draw.address=0; - if (!(vga.attr.mode_control&0x20)) { - // pel panning enabled - if (!(vga.mode==M_TEXT)) { - vga.draw.address = vga.config.pel_panning + - vga.draw.byte_panning_shift*vga.config.bytes_skip; - } else { - vga.draw.address = vga.draw.byte_panning_shift*vga.config.bytes_skip; - } - } - vga.draw.address_line=0; + VGA_ProcessSplit(); #ifdef VGA_KEEP_CHANGES vga.changes.start = vga.draw.address >> VGA_CHANGE_SHIFT; #endif @@ -750,28 +741,9 @@ static void INLINE VGA_ChangesStart( void ) { static void VGA_VerticalTimer(Bitu val) { - - /* - // Panic plasma appears more stable with this variant - vga.draw.delay.framestart += vga.draw.delay.vtotal; - double error = PIC_FullIndex()-vga.draw.delay.framestart; - //vga.draw.delay.framestart = PIC_FullIndex(); - //error = vga.draw.delay.framestart - error - vga.draw.delay.vtotal; - //if (abs(error) > 0.001 ) LOG_MSG("vgaerror: %f",error); - - //PIC_RemoveEvents(VGA_VerticalDisplayEnd); - PIC_AddEvent( VGA_VerticalTimer, (float)vga.draw.delay.vtotal - error); - double flip_offset = vga.screenflip/1000.0 + vga.draw.delay.vrstart; - if(flip_offset > vga.draw.delay.vtotal) { - VGA_VerticalDisplayEnd(0); - } else PIC_AddEvent( VGA_VerticalDisplayEnd, - (float)(flip_offset - error)); -*/ double error = vga.draw.delay.framestart; vga.draw.delay.framestart = PIC_FullIndex(); error = vga.draw.delay.framestart - error - vga.draw.delay.vtotal; -// if (abs(error) > 0.001 ) -// LOG_MSG("vgaerror: %f",error); PIC_AddEvent( VGA_VerticalTimer, (float)vga.draw.delay.vtotal ); //PIC_AddEvent( VGA_VerticalDisplayEnd, (float)vga.draw.delay.vrstart ); double flip_offset = vga.screenflip/1000.0 + vga.draw.delay.vrstart; @@ -800,26 +772,26 @@ static void VGA_VerticalTimer(Bitu val) { //TODO Maybe check for an active frame on parts_left and clear that first? vga.draw.parts_left = vga.draw.parts_total; vga.draw.lines_done = 0; -// vga.draw.address=vga.config.display_start; vga.draw.address_line = vga.config.hlines_skip; - vga.draw.split_line = (vga.config.line_compare/vga.draw.lines_scaled); - if (vga.draw.split_line==0) vga.draw.address = 0; - else vga.draw.address = vga.config.real_start; + if (IS_EGAVGA_ARCH) vga.draw.split_line = (vga.config.line_compare/vga.draw.lines_scaled); + else vga.draw.split_line = 0x10000; // don't care + vga.draw.address = vga.config.real_start; vga.draw.byte_panning_shift = 0; // go figure... if (machine==MCH_EGA) vga.draw.split_line*=2; // if (machine==MCH_EGA) vga.draw.split_line = ((((vga.config.line_compare&0x5ff)+1)*2-1)/vga.draw.lines_scaled); +#ifdef VGA_KEEP_CHANGES + bool startaddr_changed=false; +#endif switch (vga.mode) { case M_EGA: case M_LIN4: - vga.draw.address += vga.config.bytes_skip; - vga.draw.address *= 8; - vga.draw.address += vga.config.pel_panning; - if ((vga.draw.split_line==0) && (vga.attr.mode_control&0x20)) - vga.draw.address = 0; vga.draw.byte_panning_shift = 8; + vga.draw.address += vga.config.bytes_skip; + vga.draw.address *= vga.draw.byte_panning_shift; + vga.draw.address += vga.config.pel_panning; #ifdef VGA_KEEP_CHANGES - VGA_ChangesStart(); + startaddr_changed=true; #endif break; case M_VGA: @@ -834,21 +806,20 @@ static void VGA_VerticalTimer(Bitu val) { case M_LIN15: case M_LIN16: case M_LIN32: - vga.draw.address += vga.config.bytes_skip; - vga.draw.address *= 4; - vga.draw.address += vga.config.pel_panning; - if ((vga.draw.split_line==0) && (vga.attr.mode_control&0x20)) - vga.draw.address = 0; vga.draw.byte_panning_shift = 4; + vga.draw.address += vga.config.bytes_skip; + vga.draw.address *= vga.draw.byte_panning_shift; + vga.draw.address += vga.config.pel_panning; #ifdef VGA_KEEP_CHANGES - VGA_ChangesStart(); + startaddr_changed=true; #endif break; case M_TEXT: + if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) vga.draw.byte_panning_shift = 2; + else vga.draw.byte_panning_shift = 0; if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) vga.draw.address = vga.config.real_start * 2; else vga.draw.address = vga.config.display_start * 2; - vga.draw.address += vga.config.bytes_skip*2; - vga.draw.byte_panning_shift = 2; + vga.draw.address += vga.config.bytes_skip*vga.draw.byte_panning_shift; case M_TANDY_TEXT: case M_HERC_TEXT: vga.draw.cursor.address=vga.config.cursor_start*2; @@ -867,6 +838,10 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.address *= 2; break; } + if (GCC_UNLIKELY(vga.draw.split_line==0)) VGA_ProcessSplit(); +#ifdef VGA_KEEP_CHANGES + if (startaddr_changed) VGA_ChangesStart(); +#endif if (GCC_UNLIKELY(machine==MCH_EGA)) { if (!(vga.crtc.vertical_retrace_end&0x20)) { PIC_ActivateIRQ(2); @@ -1099,22 +1074,17 @@ void VGA_SetupDrawing(Bitu val) { // Display end vga.draw.delay.vdend = vdend * vga.draw.delay.htotal; - /* - // just curious - LOG_MSG("H total %d, V Total %d",htotal,vtotal); - LOG_MSG("H D End %d, V D End %d",hdend,vdend); - LOG_MSG("vrstart: %d, vrend: %d\n",vrstart,vrend); - LOG_MSG("htotal: %2.6f, vtotal: %2.6f,\n"\ - "hblkstart: %2.6f, hblkend: %2.6f,\n"\ - "vblkstart: %2.6f, vblkend: %2.6f,\n"\ - "vrstart: %2.6f, vrend: %2.6f,\n"\ - "vdispend: %2.6f", - vga.draw.delay.htotal, vga.draw.delay.vtotal, - vga.draw.delay.hblkstart, vga.draw.delay.hblkend, - vga.draw.delay.vblkstart, vga.draw.delay.vblkend, - vga.draw.delay.vrstart, vga.draw.delay.vrend, - vga.draw.delay.vdend); - */ +#if C_DEBUG + LOG(LOG_VGA,LOG_NORMAL)("h total %2.5f (%3.2fkHz) blank(%02.5f/%02.5f) retrace(%02.5f/%02.5f)", + vga.draw.delay.htotal,(1.0/vga.draw.delay.htotal), + vga.draw.delay.hblkstart,vga.draw.delay.hblkend, + vga.draw.delay.hrstart,vga.draw.delay.hrend); + LOG(LOG_VGA,LOG_NORMAL)("v total %2.5f (%3.2fHz) blank(%02.5f/%02.5f) retrace(%02.5f/%02.5f)", + vga.draw.delay.vtotal,(1000.0/vga.draw.delay.vtotal), + vga.draw.delay.vblkstart,vga.draw.delay.vblkend, + vga.draw.delay.vrstart,vga.draw.delay.vrend); +#endif + vga.draw.parts_total=VGA_PARTS; /* 6 Horizontal Sync Polarity. Negative if set From 533b4bf35966795905f9bb91188c1076e2010ef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 13 Apr 2008 19:50:47 +0000 Subject: [PATCH 3054/4131] correct ega machine graphics clock values (hal); better handling of aspect correction for ega machine with certain modes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3142 --- src/hardware/vga_draw.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 9b506cd4..3c80c76e 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.98 2008-04-12 20:32:19 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.99 2008-04-13 19:50:47 c2woody Exp $ */ #include #include @@ -989,10 +989,10 @@ void VGA_SetupDrawing(Bitu val) { } else { switch ((vga.misc_output >> 2) & 3) { case 0: - clock = 25175000; + clock = (machine==MCH_EGA) ? 14318180 : 25175000; break; case 1: - clock = 28322000; + clock = (machine==MCH_EGA) ? 16257000 : 28322000; break; } } @@ -1097,25 +1097,26 @@ void VGA_SetupDrawing(Bitu val) { //Base pixel width around 100 clocks horizontal //For 9 pixel text modes this should be changed, but we don't support that anyway :) //Seems regular vga only listens to the 9 char pixel mode with character mode enabled - double pwidth = 100.0 / htotal; + double pwidth = (machine==MCH_EGA) ? (114.0 / htotal) : (100.0 / htotal); //Base pixel height around vertical totals of modes that have 100 clocks horizontal //Different sync values gives different scaling of the whole vertical range //VGA monitor just seems to thighten or widen the whole vertical range double pheight; + double target_total = (machine==MCH_EGA) ? 262.0 : 449.0; Bitu sync = vga.misc_output >> 6; switch ( sync ) { case 0: // This is not defined in vga specs, // Kiet, seems to be slightly less than 350 on my monitor //340 line mode, filled with 449 total - pheight = (480.0 / 340.0) * ( 449.0 / vtotal ); + pheight = (480.0 / 340.0) * ( target_total / vtotal ); break; case 1: //400 line mode, filled with 449 total - pheight = (480.0 / 400.0) * ( 449.0 / vtotal ); + pheight = (480.0 / 400.0) * ( target_total / vtotal ); break; case 2: //350 line mode, filled with 449 total //This mode seems to get regular 640x400 timing and goes for a loong retrace //Depends on the monitor to stretch the screen - pheight = (480.0 / 350.0) * ( 449.0 / vtotal ); + pheight = (480.0 / 350.0) * ( target_total / vtotal ); break; case 3: //480 line mode, filled with 525 total pheight = (480.0 / 480.0) * ( 525.0 / vtotal ); From b5db3bf635edb00c43ff14a7853044cb5d0fffb5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 16 Apr 2008 18:37:08 +0000 Subject: [PATCH 3055/4131] Add patch [ 1934824 ] Mac OS X CoreAudio driver update. Update configure.in to give an error if there is no curses and debugmode is specified.(was a warning which people sometimes missed) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3143 --- configure.in | 6 +- src/gui/midi_coreaudio.h | 126 +++++++++++++++++++++------------------ src/gui/midi_coremidi.h | 2 +- 3 files changed, 72 insertions(+), 62 deletions(-) diff --git a/configure.in b/configure.in index 0b1ba0f9..a2660ead 100644 --- a/configure.in +++ b/configure.in @@ -168,7 +168,7 @@ AC_ARG_ENABLE(debug,AC_HELP_STRING([--enable-debug],[Enable debug mode]),[ AC_DEFINE(C_HEAVY_DEBUG,1) fi else - AC_MSG_WARN([Can't find curses, debug mode disabled]) + AC_MSG_ERROR([Can't find curses, which is required for debug mode]) fi ],) @@ -399,12 +399,12 @@ case "$target" in fi ;; *-*-darwin*) - dnl We have a problem here: both MacOS X and Darwin report + 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" + 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*) diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index 758972a6..cb23ea52 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -16,80 +16,90 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include +#include -//We seem to using very old interface. This keeps it compiling. Maybe -//somebody will come up with something better oneday. -#ifdef MAC_OS_X_VERSION_10_5 -#include -#include -#endif +// A macro to simplify error handling a bit. +#define RequireNoErr(error) \ +do { \ + err = error; \ + if (err != noErr) \ + goto bail; \ +} while (false) class MidiHandler_coreaudio : public MidiHandler { private: - AudioUnit m_musicDevice; - AudioUnit m_outputUnit; + AUGraph m_auGraph; + AudioUnit m_synth; public: - MidiHandler_coreaudio() : m_musicDevice(0), m_outputUnit(0) {} + MidiHandler_coreaudio() : m_auGraph(0), m_synth(0) {} const char * GetName(void) { return "coreaudio"; } bool Open(const char * conf) { - int err; - AudioUnitConnection auconnect; - ComponentDescription compdesc; - Component compid; - - if (m_outputUnit) + OSStatus err = 0; + + if (m_auGraph) return false; - - // Open the Music Device - compdesc.componentType = kAudioUnitComponentType; - compdesc.componentSubType = kAudioUnitSubType_MusicDevice; - compdesc.componentManufacturer = kAudioUnitID_DLSSynth; - compdesc.componentFlags = 0; - compdesc.componentFlagsMask = 0; - compid = FindNextComponent(NULL, &compdesc); - m_musicDevice = (AudioUnit) OpenComponent(compid); - - // open the output unit - m_outputUnit = (AudioUnit) OpenDefaultComponent(kAudioUnitComponentType, kAudioUnitSubType_Output); - - // connect the units - auconnect.sourceAudioUnit = m_musicDevice; - auconnect.sourceOutputNumber = 0; - auconnect.destInputNumber = 0; - err = - AudioUnitSetProperty(m_outputUnit, kAudioUnitProperty_MakeConnection, kAudioUnitScope_Input, 0, - (void *)&auconnect, sizeof(AudioUnitConnection)); - - // initialize the units - AudioUnitInitialize(m_musicDevice); - AudioUnitInitialize(m_outputUnit); - - // start the output - AudioOutputUnitStart(m_outputUnit); - + + // Open the Music Device. + RequireNoErr(NewAUGraph(&m_auGraph)); + + AUNode outputNode, synthNode; + ComponentDescription desc; + + // The default output device + desc.componentType = kAudioUnitType_Output; + desc.componentSubType = kAudioUnitSubType_DefaultOutput; + desc.componentManufacturer = kAudioUnitManufacturer_Apple; + desc.componentFlags = 0; + desc.componentFlagsMask = 0; + RequireNoErr(AUGraphNewNode(m_auGraph, &desc, 0, NULL, &outputNode)); + + // The built-in default (softsynth) music device + desc.componentType = kAudioUnitType_MusicDevice; + desc.componentSubType = kAudioUnitSubType_DLSSynth; + desc.componentManufacturer = kAudioUnitManufacturer_Apple; + RequireNoErr(AUGraphNewNode(m_auGraph, &desc, 0, NULL, &synthNode)); + + // Connect the softsynth to the default output + RequireNoErr(AUGraphConnectNodeInput(m_auGraph, synthNode, 0, outputNode, 0)); + + // Open and initialize the whole graph + RequireNoErr(AUGraphOpen(m_auGraph)); + RequireNoErr(AUGraphInitialize(m_auGraph)); + + // Get the music device from the graph. + RequireNoErr(AUGraphGetNodeInfo(m_auGraph, synthNode, NULL, NULL, NULL, &m_synth)); + + // Finally: Start the graph! + RequireNoErr(AUGraphStart(m_auGraph)); + return true; + + bail: + if (m_auGraph) { + AUGraphStop(m_auGraph); + DisposeAUGraph(m_auGraph); + m_auGraph = 0; + } + return false; } - + void Close(void) { - if (m_outputUnit) { - AudioOutputUnitStop(m_outputUnit); - CloseComponent(m_outputUnit); - m_outputUnit = 0; - } - if (m_musicDevice) { - CloseComponent(m_musicDevice); - m_musicDevice = 0; + if (m_auGraph) { + AUGraphStop(m_auGraph); + DisposeAUGraph(m_auGraph); + m_auGraph = 0; } } - + void PlayMsg(Bit8u * msg) { - MusicDeviceMIDIEvent(m_musicDevice,msg[0],msg[1],msg[2],0); - } - + MusicDeviceMIDIEvent(m_synth, msg[0], msg[1], msg[2], 0); + } + void PlaySysex(Bit8u * sysex, Bitu len) { - MusicDeviceSysEx(m_musicDevice, sysex, len); + MusicDeviceSysEx(m_synth, sysex, len); } }; +#undef RequireNoErr + MidiHandler_coreaudio Midi_coreaudio; diff --git a/src/gui/midi_coremidi.h b/src/gui/midi_coremidi.h index 4f44fe2b..460b44fd 100644 --- a/src/gui/midi_coremidi.h +++ b/src/gui/midi_coremidi.h @@ -24,7 +24,7 @@ private: MIDIPacket* m_pCurPacket; public: MidiHandler_coremidi() {m_pCurPacket = 0;} - char * GetName(void) { return "coremidi"; } + const char * GetName(void) { return "coremidi"; } bool Open(const char * conf) { // Get the MIDIEndPoint From c7b676198f210a5f09c13fc50ddcebbe6ae950e8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 16 Apr 2008 19:31:05 +0000 Subject: [PATCH 3056/4131] Add DOS_ATTR_DEVICE Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3144 --- include/dos_system.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 30c047a0..97933ff7 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.41 2007-11-01 12:15:34 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.42 2008-04-16 19:31:05 qbix79 Exp $ */ #ifndef DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H @@ -48,7 +48,8 @@ enum { DOS_ATTR_SYSTEM= 0x04, DOS_ATTR_VOLUME= 0x08, DOS_ATTR_DIRECTORY= 0x10, - DOS_ATTR_ARCHIVE= 0x20 + DOS_ATTR_ARCHIVE= 0x20, + DOS_ATTR_DEVICE= 0x40 }; struct FileStat_Block { From a02f75204accd610bc6b21b304b9b8c05499fa97 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 19 Apr 2008 09:25:48 +0000 Subject: [PATCH 3057/4131] gcc4.3 is a bit more strict Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3145 --- src/dos/cdrom_image.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index b47714e6..229f9bd5 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -16,14 +16,15 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.19 2008-01-21 21:22:58 qbix79 Exp $ */ +/* $Id: cdrom_image.cpp,v 1.20 2008-04-19 09:25:48 qbix79 Exp $ */ #include #include #include #include #include -#include +#include +#include //GCC 2.95 #include #include #include From fb9bded44e70b6043fb953efb438dfbc1e71776e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 21 Apr 2008 19:55:02 +0000 Subject: [PATCH 3058/4131] add cga crtc mirror-registers (fixes Prohibition); thanks to jmk Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3146 --- src/hardware/vga_other.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 1c723d93..73639261 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_other.cpp,v 1.21 2007-02-01 16:24:03 c2woody Exp $ */ +/* $Id: vga_other.cpp,v 1.22 2008-04-21 19:55:02 c2woody Exp $ */ #include #include @@ -509,7 +509,16 @@ void VGA_SetupOther(void) { IO_RegisterWriteHandler(0x3da,write_pcjr,IO_MB); IO_RegisterWriteHandler(0x3df,write_pcjr,IO_MB); } - if (machine==MCH_CGA || machine==MCH_HERC || IS_TANDY_ARCH) { + if (machine==MCH_CGA) { + Bitu base=0x3d0; + for (Bitu port_ct=0; port_ct<4; port_ct++) { + IO_RegisterWriteHandler(base+port_ct*2,write_crtc_index_other,IO_MB); + IO_RegisterWriteHandler(base+port_ct*2+1,write_crtc_data_other,IO_MB); + IO_RegisterReadHandler(base+port_ct*2,read_crtc_index_other,IO_MB); + IO_RegisterReadHandler(base+port_ct*2+1,read_crtc_data_other,IO_MB); + } + } + if (machine==MCH_HERC || IS_TANDY_ARCH) { Bitu base=machine==MCH_HERC ? 0x3b4 : 0x3d4; IO_RegisterWriteHandler(base,write_crtc_index_other,IO_MB); IO_RegisterWriteHandler(base+1,write_crtc_data_other,IO_MB); From f7ef67af0fa7daad22fbbb43da127a04416ca7a8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 29 Apr 2008 08:21:43 +0000 Subject: [PATCH 3059/4131] Check for ncurses as well Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3147 --- configure.in | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/configure.in b/configure.in index a2660ead..a773aa0c 100644 --- a/configure.in +++ b/configure.in @@ -151,6 +151,7 @@ AH_TEMPLATE(C_HEAVY_DEBUG,[Define to 1 to enable heavy debugging, also have to e 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 @@ -161,6 +162,12 @@ AC_ARG_ENABLE(debug,AC_HELP_STRING([--enable-debug],[Enable debug mode]),[ 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) From e4ab181b7b514c4dabd4275da70510cfc2204455 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 29 Apr 2008 08:22:26 +0000 Subject: [PATCH 3060/4131] Make auto a valid choice when there is no dynamic core. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3148 --- src/cpu/cpu.cpp | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index e0ff121a..3e43a601 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.108 2008-02-10 11:14:03 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.109 2008-04-29 08:22:26 qbix79 Exp $ */ #include #include @@ -2237,42 +2237,39 @@ public: CPU_CycleUp=section->Get_int("cycleup"); CPU_CycleDown=section->Get_int("cycledown"); - const char * core=section->Get_string("core"); + std::string core(section->Get_string("core")); cpudecoder=&CPU_Core_Normal_Run; - if (!strcasecmp(core,"normal")) { + if (core == "normal") { cpudecoder=&CPU_Core_Normal_Run; - } else if (!strcasecmp(core,"simple")) { + } else if (core =="simple") { cpudecoder=&CPU_Core_Simple_Run; - } else if (!strcasecmp(core,"full")) { + } else if (core == "full") { cpudecoder=&CPU_Core_Full_Run; - } + } else if (core == "auto") { + cpudecoder=&CPU_Core_Normal_Run; #if (C_DYNAMIC_X86) - else if (!strcasecmp(core,"dynamic")) { + CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CORE; + } + else if (core == "dynamic") { cpudecoder=&CPU_Core_Dyn_X86_Run; CPU_Core_Dyn_X86_SetFPUMode(true); - } else if (!strcasecmp(core,"dynamic_nodhfpu")) { + } else if (core == "dynamic_nodhfpu") { cpudecoder=&CPU_Core_Dyn_X86_Run; CPU_Core_Dyn_X86_SetFPUMode(false); - } else if (!strcasecmp(core,"auto")) { - cpudecoder=&CPU_Core_Normal_Run; - CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CORE; - } #elif (C_DYNREC) - else if (!strcasecmp(core,"dynamic")) { - cpudecoder=&CPU_Core_Dynrec_Run; - } else if (!strcasecmp(core,"auto")) { - cpudecoder=&CPU_Core_Normal_Run; CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CORE; - } -#endif - else { - LOG_MSG("CPU:Unknown core type %s, switching back to normal.",core); } + else if (core == "dynamic") { + cpudecoder=&CPU_Core_Dynrec_Run; + } +#else + } +#endif #if (C_DYNAMIC_X86) - CPU_Core_Dyn_X86_Cache_Init(!strcasecmp(core,"dynamic") || !strcasecmp(core,"dynamic_nodhfpu")); + CPU_Core_Dyn_X86_Cache_Init((core == "dynamic") || (core == "dynamic_nodhfpu")); #elif (C_DYNREC) - CPU_Core_Dynrec_Cache_Init(!strcasecmp(core,"dynamic")); + CPU_Core_Dynrec_Cache_Init( core == "dynamic" ); #endif if(CPU_CycleMax <= 0) CPU_CycleMax = 3000; From fb13f8dcbcd8a49eb1805d38346ea2d2f5e38687 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 29 Apr 2008 08:23:16 +0000 Subject: [PATCH 3061/4131] Add multiremain class. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3149 --- include/setup.h | 16 ++++++++++++-- src/misc/setup.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/include/setup.h b/include/setup.h index 34625028..a94c2592 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.34 2008-03-19 20:35:16 qbix79 Exp $ */ +/* $Id: setup.h,v 1.35 2008-04-29 08:23:16 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -241,6 +241,7 @@ public: }; class Prop_multival; +class Prop_multival_remain; class Section_prop:public Section { private: std::list properties; @@ -255,6 +256,7 @@ public: 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); P 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; @@ -263,6 +265,7 @@ public: Hex Get_hex(std::string const& _propname) const; double Get_double(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; @@ -271,6 +274,7 @@ public: }; class Prop_multival:public Property{ +protected: Section_prop* section; std::string seperator; public: @@ -279,10 +283,18 @@ public: } Section_prop *GetSection() { return section; } const Section_prop *GetSection() const { return section; } - void SetValue(std::string const& input); + virtual void SetValue(std::string const& input); virtual const std::vector& GetValues() const; }; //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){} diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 72c53193..d71bfcb0 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.47 2008-03-19 20:35:18 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.48 2008-04-29 08:23:16 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -273,6 +273,40 @@ void Prop_hex::SetValue(std::string const& input){ SetVal(val,false,true); } +//TODO checkvalue stuff +void Prop_multival_remain::SetValue(std::string const& input) { + Value val(input,Value::V_STRING); + SetVal(val,false,true); + + std::string local(input); + int i = 0,number_of_properties = 0; + Property *p = section->Get_prop(0); + //No properties in this section. do nothing + if(!p) return; + + while( (section->Get_prop(number_of_properties)) ) + number_of_properties++; + + string::size_type loc = string::npos; + while( (p = section->Get_prop(i++)) ) { + //trim leading seperators + loc = local.find_first_not_of(seperator); + if(loc != string::npos) local.erase(0,loc); + loc = local.find_first_of(seperator); + string in = "";//default value + /* when i == number_of_properties add the total line. (makes more then + * one string argument possible for parameters of cpu) */ + if(loc != string::npos && i < number_of_properties) { //seperator found + in = local.substr(0,loc); + local.erase(0,loc+1); + } else if(local.size()) { //last argument or last property + in = local; + local = ""; + } + p->SetValue(in); + } +} + //TODO checkvalue stuff void Prop_multival::SetValue(std::string const& input) { Value val(input,Value::V_STRING); @@ -300,6 +334,7 @@ void Prop_multival::SetValue(std::string const& input) { p->SetValue(in); } } + const std::vector& Property::GetValues() const { return suggested_values; } @@ -360,7 +395,11 @@ Prop_multival* Section_prop::Add_multi(std::string const& _propname, Property::C properties.push_back(test); return test; } - +Prop_multival_remain* Section_prop::Add_multiremain(std::string const& _propname, Property::Changeable::Value when,std::string const& sep) { + Prop_multival_remain* test = new Prop_multival_remain(_propname,when,sep); + properties.push_back(test); + return test; +} int Section_prop::Get_int(string const&_propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ @@ -397,6 +436,15 @@ Prop_multival* Section_prop::Get_multival(string const& _propname) const { return NULL; } +Prop_multival_remain* Section_prop::Get_multivalremain(string const& _propname) const { + for(const_it tel=properties.begin();tel!=properties.end();tel++){ + if((*tel)->propname==_propname){ + Prop_multival_remain* val = dynamic_cast((*tel)); + if(val) return val; else return NULL; + } + } + return NULL; +} Property* Section_prop::Get_prop(int index){ for(it tel=properties.begin();tel!=properties.end();tel++){ if(!index--) return (*tel); From 327f9acedb82c1a0b91febc49eb1fe88e3444074 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 29 Apr 2008 08:24:16 +0000 Subject: [PATCH 3062/4131] Convert both cycles and serial port to new multiremain class. TODO src/hardware/serialport.cpp to parse new classes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3150 --- src/dosbox.cpp | 56 +++++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 9f316017..a5308d58 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.133 2008-03-21 04:36:20 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.134 2008-04-29 08:24:16 qbix79 Exp $ */ #include #include @@ -307,6 +307,7 @@ void DOSBOX_Init(void) { Prop_string* Pstring; Prop_bool* Pbool; Prop_multival* Pmulti; + Prop_multival_remain* Pmulti_remain; SDLNetInited = false; @@ -390,8 +391,8 @@ void DOSBOX_Init(void) { Pstring->Set_values(cores); Pstring->Set_help("CPU Core used in emulation. auto will switch to dynamic if available and appropriate."); - Pmulti = secprop->Add_multi("cycles",Property::Changeable::Always," "); - Pmulti->Set_help( + Pmulti_remain = secprop->Add_multiremain("cycles",Property::Changeable::Always," "); + Pmulti_remain->Set_help( "Amount of instructions DOSBox tries to emulate each millisecond. Setting this value too high results in sound dropouts and lags. Cycles can be set in 3 ways:\n" " 'auto' tries to guess what a game needs.\n" " It usually works, but can fail for certain games.\n" @@ -400,11 +401,11 @@ void DOSBOX_Init(void) { " 'max' will allocate as much cycles as your computer is able to handle\n"); const char* cyclest[] = { "auto","fixed","max",0 }; - Pstring = Pmulti->GetSection()->Add_string("type",Property::Changeable::Always,"auto"); - Pmulti->SetValue("auto"); + Pstring = Pmulti_remain->GetSection()->Add_string("type",Property::Changeable::Always,"auto"); + Pmulti_remain->SetValue("auto"); Pstring->Set_values(cyclest); - Pstring = Pmulti->GetSection()->Add_string("parameters",Property::Changeable::Always,""); + Pstring = Pmulti_remain->GetSection()->Add_string("parameters",Property::Changeable::Always,""); Pint = secprop->Add_int("cycleup",Property::Changeable::Always,500); Pint->SetMinMax(1,1000000); @@ -584,37 +585,46 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("serial",&SERIAL_Init,true); const char* serials[] = { "dummy", "disabled", "modem", "nullmodem", -#if defined(WIN32) || defined(OS2) - "directserial realport:COM1", "directserial realport:COM2", -#else - "directserial realport:ttyS0", "directserial realport:ttyS1", -#endif - 0}; - - Pstring = secprop->Add_string("serial1",Property::Changeable::WhenIdle,"dummy"); + "directserial",0 }; + + Pmulti_remain = secprop->Add_multiremain("serial1",Property::Changeable::WhenIdle," "); + Pstring = Pmulti_remain->GetSection()->Add_string("type",Property::Changeable::WhenIdle,"dummy"); + Pmulti_remain->SetValue("dummy"); Pstring->Set_values(serials); - Pstring->Set_help( + Pstring = Pmulti_remain->GetSection()->Add_string("parameters",Property::Changeable::WhenIdle,""); + Pmulti_remain->Set_help( "set type of device connected to com port.\n" "Can be disabled, dummy, modem, nullmodem, directserial.\n" "Additional parameters must be in the same line in the form of\n" "parameter:value. Parameter for all types is irq.\n" "for directserial: realport (required), rxdelay (optional).\n" + " (realport:COM1 realport:ttyS0).\n" "for modem: listenport (optional).\n" "for nullmodem: server, rxdelay, txdelay, telnet, usedtr,\n" " transparent, port, inhsocket (all optional).\n" "Example: serial1=modem listenport:5000"); - - Pstring = secprop->Add_string("serial2",Property::Changeable::WhenIdle,"dummy"); - Pstring->Set_values(serials); - Pstring->Set_help("see serial1"); - Pstring = secprop->Add_string("serial3",Property::Changeable::WhenIdle,"disabled"); + Pmulti_remain = secprop->Add_multiremain("serial2",Property::Changeable::WhenIdle," "); + Pstring = Pmulti_remain->GetSection()->Add_string("type",Property::Changeable::WhenIdle,"dummy"); + Pmulti_remain->SetValue("dummy"); Pstring->Set_values(serials); - Pstring->Set_help("see serial1"); + Pstring = Pmulti_remain->GetSection()->Add_string("parameters",Property::Changeable::WhenIdle,""); + Pmulti_remain->Set_help("see serial1"); - Pstring = secprop->Add_string("serial4",Property::Changeable::WhenIdle,"disabled"); + Pmulti_remain = secprop->Add_multiremain("serial3",Property::Changeable::WhenIdle," "); + Pstring = Pmulti_remain->GetSection()->Add_string("type",Property::Changeable::WhenIdle,"disabled"); + Pmulti_remain->SetValue("disabled"); Pstring->Set_values(serials); - Pstring->Set_help("see serial1"); + Pstring = Pmulti_remain->GetSection()->Add_string("parameters",Property::Changeable::WhenIdle,""); + Pmulti_remain->Set_help("see serial1"); + + Pmulti_remain = secprop->Add_multiremain("serial4",Property::Changeable::WhenIdle," "); + Pstring = Pmulti_remain->GetSection()->Add_string("type",Property::Changeable::WhenIdle,"disabled"); + Pmulti_remain->SetValue("disabled"); + Pstring->Set_values(serials); + Pstring = Pmulti_remain->GetSection()->Add_string("parameters",Property::Changeable::WhenIdle,""); + Pmulti_remain->Set_help("see serial1"); + /* All the DOS Related stuff, which will eventually start up in the shell */ secprop=control->AddSection_prop("dos",&DOS_Init,false);//done From e05da8b3d6bd6d721bb80ad57d8abbf62dccd5a0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 30 Apr 2008 18:26:17 +0000 Subject: [PATCH 3063/4131] FindFirst can find devices now as well. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3151 --- src/dos/dos_files.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index dfef87f0..8dbf5e83 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.95 2008-02-18 17:45:55 c2woody Exp $ */ +/* $Id: dos_files.cpp,v 1.96 2008-04-30 18:26:17 qbix79 Exp $ */ #include #include @@ -266,6 +266,9 @@ bool DOS_FindFirst(char * search,Bit16u attr,bool fcb_findfirst) { return false; } if (!DOS_MakeName(search,fullsearch,&drive)) return false; + //Check for devices. FindDevice checks for leading subdir as well + bool device = (DOS_FindDevice(search) != DOS_DEVICES); + /* Split the search in dir and pattern */ char * find_last; find_last=strrchr(fullsearch,'\\'); @@ -277,12 +280,18 @@ bool DOS_FindFirst(char * search,Bit16u attr,bool fcb_findfirst) { strcpy(pattern,find_last+1); strcpy(dir,fullsearch); } -//check for devices. first part of filename before the dot -//can be the name of a device. like con.1 -//if(findDevice(pattern) blah blah -// but leading subdirs must exist.... -// + dta.SetupSearch(drive,(Bit8u)attr,pattern); + + if(device) { + find_last = strrchr(pattern,'.'); + if(find_last) *find_last = 0; + //TODO use current date and time + dta.SetResult(pattern,0,0,0,DOS_ATTR_DEVICE); + LOG(LOG_DOSMISC,LOG_WARN)("finding device %s",pattern); + return true; + } + if (Drives[drive]->FindFirst(dir,dta,fcb_findfirst)) return true; return false; From 3a57da9aed039377b4bdd361a5e7f36a01d153cd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 5 May 2008 13:29:04 +0000 Subject: [PATCH 3064/4131] Fix bug 1957787 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3152 --- src/cpu/cpu.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 3e43a601..2fa38733 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.109 2008-04-29 08:22:26 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.110 2008-05-05 13:29:04 qbix79 Exp $ */ #include #include @@ -2261,10 +2261,10 @@ public: } else if (core == "dynamic") { cpudecoder=&CPU_Core_Dynrec_Run; - } #else - } + #endif + } #if (C_DYNAMIC_X86) CPU_Core_Dyn_X86_Cache_Init((core == "dynamic") || (core == "dynamic_nodhfpu")); From caa9317946e7553ee18c956aaafc6884fd8c4562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 10 May 2008 17:33:28 +0000 Subject: [PATCH 3065/4131] add possibility to emulate older vesa version to work around some buggy games (fixes Supreme Warrior) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3153 --- src/dosbox.cpp | 8 +++++--- src/ints/int10.cpp | 6 +++++- src/ints/int10.h | 3 ++- src/ints/int10_modes.cpp | 17 ++++++++++------- src/ints/int10_vesa.cpp | 16 ++++++++++------ 5 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index a5308d58..e3374a08 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.134 2008-04-29 08:24:16 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.135 2008-05-10 17:33:27 c2woody Exp $ */ #include #include @@ -279,9 +279,10 @@ static void DOSBOX_RealInit(Section * sec) { } std::string mtype(section->Get_string("machine")); - svgaCard = SVGA_S3Trio; + svgaCard = SVGA_None; machine = MCH_VGA; int10.vesa_nolfb = false; + int10.vesa_oldvbe = false; if (mtype == "cga") { machine = MCH_CGA; } else if (mtype == "tandy") { machine = MCH_TANDY; } else if (mtype == "pcjr") { machine = MCH_PCJR; } @@ -290,6 +291,7 @@ static void DOSBOX_RealInit(Section * sec) { // else if (mtype == "vga") { svgaCard = SVGA_S3Trio; } else if (mtype == "svga_s3") { svgaCard = SVGA_S3Trio; } else if (mtype == "vesa_nolfb") { svgaCard = SVGA_S3Trio; int10.vesa_nolfb = true;} + else if (mtype == "vesa_oldvbe") { svgaCard = SVGA_S3Trio; int10.vesa_oldvbe = true;} else if (mtype == "svga_et4000") { svgaCard = SVGA_TsengET4K; } else if (mtype == "svga_et3000") { svgaCard = SVGA_TsengET3K; } // else if (mtype == "vga_pvga1a") { svgaCard = SVGA_ParadisePVGA1A; } @@ -324,7 +326,7 @@ void DOSBOX_Init(void) { const char* machines[] = { "hercules", "cga", "tandy", "pcjr", "ega", "vgaonly", "svga_s3", "svga_et3000", "svga_et4000", - "svga_paradise", "vesa_nolfb", 0 }; + "svga_paradise", "vesa_nolfb", "vesa_oldvbe", 0 }; secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit); Pstring = secprop->Add_string("language",Property::Changeable::Always,""); Pstring->Set_help("Select another language file."); diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 2261354e..1e6895ce 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.cpp,v 1.51 2008-03-31 14:43:34 c2woody Exp $ */ +/* $Id: int10.cpp,v 1.52 2008-05-10 17:33:28 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -587,6 +587,10 @@ graphics_chars: } break; case 0x0a: /* Get Pmode Interface */ + if (int10.vesa_oldvbe) { + reg_ax=0x014f; + break; + } switch (reg_bl) { case 0x00: reg_edi=RealOff(int10.rom.pmode_interface); diff --git a/src/ints/int10.h b/src/ints/int10.h index 07204037..4e5250bc 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.h,v 1.35 2008-03-14 18:16:34 c2woody Exp $ */ +/* $Id: int10.h,v 1.36 2008-05-10 17:33:28 c2woody Exp $ */ #include "vga.h" @@ -141,6 +141,7 @@ typedef struct { } rom; Bitu vesa_setmode; bool vesa_nolfb; + bool vesa_oldvbe; } Int10Data; extern Int10Data int10; diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 949ccb86..418d344b 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.77 2008-02-03 20:43:14 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.78 2008-05-10 17:33:28 c2woody Exp $ */ #include @@ -330,14 +330,17 @@ VideoModeBlock * CurMode; static bool SetCurMode(VideoModeBlock modeblock[],Bitu mode) { Bitu i=0; - while ( modeblock[i].mode!=0xffff) { - if ( modeblock[i].mode==mode) goto foundmode; - i++; + while (modeblock[i].mode!=0xffff) { + if (modeblock[i].mode!=mode) i++; + else { + if ((!int10.vesa_oldvbe) || (ModeList_VGA[i].mode<0x120)) { + CurMode=&modeblock[i]; + return true; + } + return false; + } } return false; -foundmode: - CurMode=&modeblock[i]; - return true; } diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 5be682b4..6f90ffd7 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.35 2008-02-08 21:25:57 c2woody Exp $ */ +/* $Id: int10_vesa.cpp,v 1.36 2008-05-10 17:33:28 c2woody Exp $ */ #include #include @@ -91,15 +91,16 @@ Bit8u VESA_GetSVGAInformation(Bit16u seg,Bit16u off) { Bitu i; bool vbe2=false;Bit16u vbe2_pos=256+off; Bitu id=mem_readd(buffer); - if ((id==0x56424532)||(id==0x32454256)) vbe2=true; + if (((id==0x56424532)||(id==0x32454256)) && (!int10.vesa_oldvbe)) vbe2=true; if (vbe2) { for (i=0;i<0x200;i++) mem_writeb(buffer+i,0); } else { for (i=0;i<0x100;i++) mem_writeb(buffer+i,0); } /* Fill common data */ - MEM_BlockWrite(buffer,(void *)"VESA",4); //Identification - mem_writew(buffer+0x04,0x200); //Vesa version 0x200 + MEM_BlockWrite(buffer,(void *)"VESA",4); //Identification + if (!int10.vesa_oldvbe) mem_writew(buffer+0x04,0x200); //Vesa version 2.0 + else mem_writew(buffer+0x04,0x102); //Vesa version 1.2 if (vbe2) { mem_writed(buffer+0x06,RealMake(seg,vbe2_pos)); for (i=0;i=0x120)) return 0x01; VideoModeBlock * mblock=&ModeList_VGA[i]; switch (mblock->type) { case M_LIN4: @@ -472,8 +474,10 @@ void INT10_SetupVESA(void) { if (svga.accepts_mode(ModeList_VGA[i].mode)) canuse_mode=true; } if (ModeList_VGA[i].mode>=0x100 && canuse_mode) { - phys_writew(PhysMake(0xc000,int10.rom.used),ModeList_VGA[i].mode); - int10.rom.used+=2; + if ((!int10.vesa_oldvbe) || (ModeList_VGA[i].mode<0x120)) { + phys_writew(PhysMake(0xc000,int10.rom.used),ModeList_VGA[i].mode); + int10.rom.used+=2; + } } i++; } From 581a6c232281a67525b7ae43ff0e3af09eff7879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 15 May 2008 20:12:37 +0000 Subject: [PATCH 3066/4131] don't screw up gfx regs when using mouse on non-vga machine modes (workaround) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3154 --- src/ints/mouse.cpp | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 664663b2..6f8ded52 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.72 2008-03-08 22:05:05 c2woody Exp $ */ +/* $Id: mouse.cpp,v 1.73 2008-05-15 20:12:37 c2woody Exp $ */ #include #include @@ -256,28 +256,36 @@ void DrawCursorText() { static Bit8u gfxReg3CE[9]; static Bit8u index3C4,gfxReg3C5; void SaveVgaRegisters() { - for (int i=0; i<9; i++) { - IO_Write (0x3CE,i); - gfxReg3CE[i] = IO_Read(0x3CF); - } - /* Setup some default values in GFX regs that should work */ - IO_Write(0x3CE,3); IO_Write(0x3Cf,0); //disable rotate and operation - IO_Write(0x3CE,5); IO_Write(0x3Cf,gfxReg3CE[5]&0xf0); //Force read/write mode 0 + if (IS_VGA_ARCH) { + for (int i=0; i<9; i++) { + IO_Write (0x3CE,i); + gfxReg3CE[i] = IO_Read(0x3CF); + } + /* Setup some default values in GFX regs that should work */ + IO_Write(0x3CE,3); IO_Write(0x3Cf,0); //disable rotate and operation + IO_Write(0x3CE,5); IO_Write(0x3Cf,gfxReg3CE[5]&0xf0); //Force read/write mode 0 - //Set Map to all planes. Celtic Tales - index3C4 = IO_Read(0x3c4); IO_Write(0x3C4,2); - gfxReg3C5 = IO_Read(0x3C5); IO_Write(0x3C5,0xF); + //Set Map to all planes. Celtic Tales + index3C4 = IO_Read(0x3c4); IO_Write(0x3C4,2); + gfxReg3C5 = IO_Read(0x3C5); IO_Write(0x3C5,0xF); + } else if (machine==MCH_EGA) { + //Set Map to all planes. + IO_Write(0x3C4,2); + IO_Write(0x3C5,0xF); + } } void RestoreVgaRegisters() { - for (int i=0; i<9; i++) { - IO_Write(0x3CE,i); - IO_Write(0x3CF,gfxReg3CE[i]); - } + if (IS_VGA_ARCH) { + for (int i=0; i<9; i++) { + IO_Write(0x3CE,i); + IO_Write(0x3CF,gfxReg3CE[i]); + } - IO_Write(0x3C4,2); - IO_Write(0x3C5,gfxReg3C5); - IO_Write(0x3C4,index3C4); + IO_Write(0x3C4,2); + IO_Write(0x3C5,gfxReg3C5); + IO_Write(0x3C4,index3C4); + } } void ClipCursorArea(Bit16s& x1, Bit16s& x2, Bit16s& y1, Bit16s& y2, From e3aba20b3c5d756628bd4770356a58c8a38de30a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 18 May 2008 13:11:14 +0000 Subject: [PATCH 3067/4131] better separation of cpu type specific features; make cpu type selectable Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3155 --- include/cpu.h | 16 +++++-- src/cpu/core_dyn_x86/decoder.h | 68 +++++++++++++++++++++++++- src/cpu/core_dyn_x86/risc_x86.h | 16 ++++++- src/cpu/core_full/load.h | 2 +- src/cpu/core_full/op.h | 14 ++++++ src/cpu/core_full/optable.h | 2 +- src/cpu/core_full/support.h | 2 +- src/cpu/core_normal/prefix_0f.h | 28 ++++++++++- src/cpu/core_normal/prefix_66_0f.h | 31 +++++++++++- src/cpu/cpu.cpp | 77 +++++++++++++++++++++++++----- src/cpu/paging.cpp | 55 ++++++++++++++++++--- src/dosbox.cpp | 8 +++- 12 files changed, 288 insertions(+), 31 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 06d03589..5544f93f 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.h,v 1.52 2008-01-16 20:16:31 c2woody Exp $ */ +/* $Id: cpu.h,v 1.53 2008-05-18 13:10:42 c2woody Exp $ */ #ifndef DOSBOX_CPU_H #define DOSBOX_CPU_H @@ -40,6 +40,14 @@ #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; @@ -52,6 +60,8 @@ extern bool CPU_CycleAutoAdjust; extern bool CPU_SkipCycleAutoAdjust; extern Bitu CPU_AutoDetermineMode; +extern Bitu CPU_ArchitectureType; + /* Some common Defines */ /* A CPU Handler */ typedef Bits (CPU_Decoder)(void); @@ -146,7 +156,7 @@ void CPU_Exception(Bitu which,Bitu error=0); bool CPU_SetSegGeneral(SegNames seg,Bitu value); bool CPU_PopSeg(SegNames seg,bool use32); -void CPU_CPUID(void); +bool CPU_CPUID(void); Bitu CPU_Pop16(void); Bitu CPU_Pop32(void); void CPU_Push16(Bitu value); diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 4f23c0ad..56ebfb52 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: decoder.h,v 1.55 2008-05-18 13:11:14 c2woody Exp $ */ + #define X86_DYNFPU_DH_ENABLED #define X86_INLINED_MEMACCESS @@ -1329,6 +1331,68 @@ static void dyn_mov_ev_gw(bool sign) { } } +static void dyn_cmpxchg_evgv(void) { + dyn_get_modrm(); + DynReg * rm_reg=&DynRegs[decode.modrm.reg]; + gen_protectflags(); + if (decode.modrm.mod<3) { + gen_releasereg(DREG(EAX)); + gen_releasereg(DREG(TMPB)); + gen_releasereg(rm_reg); + + dyn_fill_ea(); + dyn_read_word(DREG(EA),DREG(TMPB),decode.big_op); + gen_dop_word(DOP_CMP,decode.big_op,DREG(EAX),DREG(TMPB)); + Bit8u * branch=gen_create_branch(BR_NZ); + + // eax==mem -> mem:=rm_reg + dyn_write_word_release(DREG(EA),rm_reg,decode.big_op); + gen_setzeroflag(); + gen_releasereg(DREG(EAX)); + gen_releasereg(DREG(TMPB)); + gen_releasereg(rm_reg); + + Bit8u * jump=gen_create_jump(); + + gen_fill_branch(branch); + // eax!=mem -> eax:=mem + dyn_write_word_release(DREG(EA),DREG(TMPB),decode.big_op); // cmpxchg always issues write + gen_dop_word(DOP_MOV,decode.big_op,DREG(EAX),DREG(TMPB)); + gen_clearzeroflag(); + gen_releasereg(DREG(EAX)); + gen_releasereg(DREG(TMPB)); + gen_releasereg(rm_reg); + + gen_fill_jump(jump); + } else { + gen_releasereg(DREG(EAX)); + gen_releasereg(&DynRegs[decode.modrm.rm]); + gen_releasereg(rm_reg); + + gen_dop_word(DOP_CMP,decode.big_op,DREG(EAX),&DynRegs[decode.modrm.rm]); + Bit8u * branch=gen_create_branch(BR_NZ); + + // eax==rm -> rm:=rm_reg + gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],rm_reg); + gen_setzeroflag(); + gen_releasereg(DREG(EAX)); + gen_releasereg(&DynRegs[decode.modrm.rm]); + gen_releasereg(rm_reg); + + Bit8u * jump=gen_create_jump(); + + gen_fill_branch(branch); + // eax!=rm -> eax:=rm + gen_dop_word(DOP_MOV,decode.big_op,DREG(EAX),&DynRegs[decode.modrm.rm]); + gen_clearzeroflag(); + gen_releasereg(DREG(EAX)); + gen_releasereg(&DynRegs[decode.modrm.rm]); + gen_releasereg(rm_reg); + + gen_fill_jump(jump); + } +} + static void dyn_dshift_ev_gv(bool left,bool immediate) { dyn_get_modrm(); DynReg * rm_reg=&DynRegs[decode.modrm.reg]; @@ -1995,6 +2059,8 @@ restart_prefix: case 0xad:dyn_dshift_ev_gv(false,false);break; /* Imul Ev,Gv */ case 0xaf:dyn_imul_gvev(0);break; + /* CMPXCHG */ + case 0xb1:dyn_cmpxchg_evgv();break; /* LFS,LGS */ case 0xb4: dyn_get_modrm(); diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 709cf6b6..b091c384 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: risc_x86.h,v 1.30 2008-05-18 13:11:14 c2woody Exp $ */ + static void gen_init(void); /* End of needed */ @@ -268,6 +270,18 @@ static void gen_needcarry(void) { } } +static void gen_setzeroflag(void) { + if (x86gen.flagsactive) IllegalOption("gen_setzeroflag"); + cache_addw(0x0c83); //OR DWORD [ESP],0x40 + cache_addw(0x4024); +} + +static void gen_clearzeroflag(void) { + if (x86gen.flagsactive) IllegalOption("gen_clearzeroflag"); + cache_addw(0x2483); //AND DWORD [ESP],~0x40 + cache_addw(0xbf24); +} + static bool skip_flags=false; static void set_skipflags(bool state) { diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index a0c1ca47..a5e7adeb 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -468,7 +468,7 @@ l_M_Ed: AAS(); goto nextopcode; case D_CPUID: - CPU_CPUID(); + if (!CPU_CPUID()) goto illegalopcode; goto nextopcode; case D_HLT: if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 67ae2c9a..bfcb90d1 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -585,8 +585,22 @@ switch (inst.code.op) { inst_op1_d&=~(1 << (inst_op2_d & 31)); break; case O_BSWAP: + if (CPU_ArchitectureType=0xc0) << 3) | inst.code.save) { diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index fcdb1508..39907e0e 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -661,7 +661,7 @@ static OpCode OpCodeTable[1024]={ {0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdxGdx }, /* 0x3b0 - 0x3b7 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{L_MODRM ,O_CMPXCHG ,S_Ed ,M_Ed }, {L_MODRM ,O_SEGSS ,S_SEGGd,M_Efd },{L_MODRM ,O_BTRd ,S_Ed ,M_EdGdt }, {L_MODRM ,O_SEGFS ,S_SEGGd,M_Efd },{L_MODRM ,O_SEGGS ,S_SEGGd,M_Efd }, {L_MODRM ,0 ,S_Gd ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ew }, diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index cde08ebc..32b92620 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -94,7 +94,7 @@ enum { O_BTd,O_BTSd,O_BTRd,O_BTCd, O_BSFw,O_BSRw,O_BSFd,O_BSRd, - O_BSWAP, + O_BSWAP,O_CMPXCHG, O_FPU, diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 16397144..388c15c2 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -142,6 +142,11 @@ if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); cpu.cr0&=(~CR0_TASKSWITCH); break; + CASE_0F_B(0x08) /* INVD */ + CASE_0F_B(0x09) /* WBINVD */ + if (CPU_ArchitectureType>32); + reg_eax=(Bit32u)(tsc&0xffffffff); + } + break; CASE_0F_W(0x80) /* JO */ JumpCond16_w(TFLG_O);break; CASE_0F_W(0x81) /* JNO */ @@ -291,7 +304,8 @@ if (CPU_PopSeg(fs,false)) RUNEXCEPTION(); break; CASE_0F_B(0xa2) /* CPUID */ - CPU_CPUID();break; + if (!CPU_CPUID()) goto illegal_opcode; + break; CASE_0F_W(0xa3) /* BT Ew,Gw */ { FillFlags();GetRMrw; @@ -503,6 +517,7 @@ } CASE_0F_B(0xc0) /* XADD Gb,Eb */ { + if (CPU_ArchitectureType= 0xc0 ) {GetEArb;*rmrb=*earb;*earb+=oldrmrb;} else {GetEAa;*rmrb=LoadMb(eaa);SaveMb(eaa,LoadMb(eaa)+oldrmrb);} @@ -510,25 +525,34 @@ } CASE_0F_W(0xc1) /* XADD Gw,Ew */ { + if (CPU_ArchitectureType= 0xc0 ) {GetEArw;*rmrw=*earw;*earw+=oldrmrw;} else {GetEAa;*rmrw=LoadMw(eaa);SaveMw(eaa,LoadMw(eaa)+oldrmrw);} break; } CASE_0F_B(0xc8) /* BSWAP EAX */ + if (CPU_ArchitectureType= 0xc0) { + GetEArd; + if (*eard==reg_eax) { + *eard=*rmrd; + SETFLAGBIT(ZF,1); + } else { + reg_eax=*eard; + SETFLAGBIT(ZF,0); + } + } else { + GetEAa; + Bit32u val=LoadMd(eaa); + if (val==reg_eax) { + SaveMd(eaa,*rmrd); + SETFLAGBIT(ZF,1); + } else { + SaveMd(eaa,val); + reg_eax=val; + SETFLAGBIT(ZF,0); + } + } + break; + } CASE_0F_D(0xb2) /* LSS Ed */ { GetRMrd; @@ -405,6 +433,7 @@ } CASE_0F_D(0xc1) /* XADD Gd,Ed */ { + if (CPU_ArchitectureType= 0xc0 ) {GetEArd;*rmrd=*eard;*eard+=oldrmrd;} else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,LoadMd(eaa)+oldrmrd);} diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 2fa38733..e5c8991a 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.110 2008-05-05 13:29:04 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.111 2008-05-18 13:11:14 c2woody Exp $ */ #include #include @@ -61,6 +61,10 @@ bool CPU_CycleAutoAdjust = false; bool CPU_SkipCycleAutoAdjust = false; Bitu CPU_AutoDetermineMode = 0; +Bitu CPU_ArchitectureType = CPU_ARCHTYPE_MIXED; + +Bitu CPU_flag_id_toggle=0; + void CPU_Core_Full_Init(void); void CPU_Core_Normal_Init(void); void CPU_Core_Simple_Init(void); @@ -161,8 +165,10 @@ PhysPt SelBase(Bitu sel) { } } + void CPU_SetFlags(Bitu word,Bitu mask) { - reg_flags=(reg_flags & ~mask)|(word & mask)|2|FLAG_ID; + mask|=CPU_flag_id_toggle; // ID-flag can be toggled on cpuid-supporting CPUs + reg_flags=(reg_flags & ~mask)|(word & mask)|2; cpu.direction=1-((reg_flags & FLAG_DF) >> 9); } @@ -1569,6 +1575,9 @@ bool CPU_WRITE_CRX(Bitu cr,Bitu value) { /* Check if privileged to access control registers */ if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); if ((cr==1) || (cr>4)) return CPU_PrepareException(EXCEPTION_UD,0); + if (CPU_ArchitectureType=CPU_ARCHTYPE_PENTIUMSLOW) return cpu.cr0; + else if (CPU_ArchitectureType>=CPU_ARCHTYPE_486OLDSLOW) return (cpu.cr0 & 0xe005003f); + else return (cpu.cr0 | 0x7ffffff0); case 2: return paging.cr2; case 3: @@ -1613,7 +1624,11 @@ bool CPU_WRITE_DRX(Bitu dr,Bitu value) { break; case 5: case 7: - cpu.drx[7]=(value|0x400) & 0xffff2fff; + if (CPU_ArchitectureTypeGet_int("cycleup"); CPU_CycleDown=section->Get_int("cycledown"); - std::string core(section->Get_string("core")); + std::string core(section->Get_string("core")); cpudecoder=&CPU_Core_Normal_Run; if (core == "normal") { cpudecoder=&CPU_Core_Normal_Run; @@ -2271,7 +2306,25 @@ public: #elif (C_DYNREC) CPU_Core_Dynrec_Cache_Init( core == "dynamic" ); #endif - + + CPU_ArchitectureType = CPU_ARCHTYPE_MIXED; + std::string cputype(section->Get_string("cputype")); + if (cputype == "auto") { + CPU_ArchitectureType = CPU_ARCHTYPE_MIXED; + } else if (cputype == "386") { + CPU_ArchitectureType = CPU_ARCHTYPE_386FAST; + } else if (cputype == "386_slow") { + CPU_ArchitectureType = CPU_ARCHTYPE_386SLOW; + } else if (cputype == "486_slow") { + CPU_ArchitectureType = CPU_ARCHTYPE_486NEWSLOW; + } else if (cputype == "pentium_slow") { + CPU_ArchitectureType = CPU_ARCHTYPE_PENTIUMSLOW; + } + + if (CPU_ArchitectureType>=CPU_ARCHTYPE_486NEWSLOW) CPU_flag_id_toggle=FLAG_ID; + else CPU_flag_id_toggle=0; + + if(CPU_CycleMax <= 0) CPU_CycleMax = 3000; if(CPU_CycleUp <= 0) CPU_CycleUp = 500; if(CPU_CycleDown <= 0) CPU_CycleDown = 20; diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index fc7bfa85..7bbc97a6 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.cpp,v 1.33 2008-01-05 21:05:06 c2woody Exp $ */ +/* $Id: paging.cpp,v 1.34 2008-05-18 13:11:14 c2woody Exp $ */ #include #include @@ -34,7 +34,6 @@ #define LINK_TOTAL (64*1024) #define USERWRITE_PROHIBITED ((cpu.cpl&cpu.mpl)==3) -#define USERACCESS_PROHIBITED(u1,u2) (((u1)==0) && ((u2)==0)) PagingBlock paging; @@ -228,6 +227,20 @@ static INLINE bool InitPageCheckPresence_CheckOnly(PhysPt lin_addr,bool writing, return true; } +static INLINE bool InitPage_CheckUseraccess(Bitu u1,Bitu u2) { + switch (CPU_ArchitectureType) { + case CPU_ARCHTYPE_MIXED: + case CPU_ARCHTYPE_386SLOW: + case CPU_ARCHTYPE_386FAST: + default: + return ((u1)==0) && ((u2)==0); + case CPU_ARCHTYPE_486OLDSLOW: + case CPU_ARCHTYPE_486NEWSLOW: + case CPU_ARCHTYPE_PENTIUMSLOW: + return ((u1)==0) || ((u2)==0); + } +} + class InitPageHandler : public PageHandler { public: @@ -316,12 +329,40 @@ public: // 2: can (but currently does not) fail a write privilege check // 3: fails a privilege check Bitu priv_check=0; - if (USERACCESS_PROHIBITED(entry.block.us,table.block.us)) { + if (InitPage_CheckUseraccess(entry.block.us,table.block.us)) { if ((cpu.cpl&cpu.mpl)==3) priv_check=3; - else priv_check=1; + else { + switch (CPU_ArchitectureType) { + case CPU_ARCHTYPE_MIXED: + case CPU_ARCHTYPE_386FAST: + default: +// priv_check=0; // default + break; + case CPU_ARCHTYPE_386SLOW: + case CPU_ARCHTYPE_486OLDSLOW: + case CPU_ARCHTYPE_486NEWSLOW: + case CPU_ARCHTYPE_PENTIUMSLOW: + priv_check=1; + break; + } + } } if ((entry.block.wr==0) || (table.block.wr==0)) { - if (priv_check==0) priv_check=2; + if (priv_check==0) { + switch (CPU_ArchitectureType) { + case CPU_ARCHTYPE_MIXED: + case CPU_ARCHTYPE_386FAST: + default: +// priv_check=0; // default + break; + case CPU_ARCHTYPE_386SLOW: + case CPU_ARCHTYPE_486OLDSLOW: + case CPU_ARCHTYPE_486NEWSLOW: + case CPU_ARCHTYPE_PENTIUMSLOW: + priv_check=2; + break; + } + } if (writing && USERWRITE_PROHIBITED) priv_check=3; } if (priv_check==3) { @@ -374,7 +415,7 @@ public: if (!USERWRITE_PROHIBITED) return true; - if (USERACCESS_PROHIBITED(entry.block.us,table.block.us) || + if (InitPage_CheckUseraccess(entry.block.us,table.block.us) || (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x", cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); @@ -507,7 +548,7 @@ public: X86PageEntry entry; if (!InitPageCheckPresence_CheckOnly(lin_addr,true,table,entry)) return 0; - if (USERACCESS_PROHIBITED(entry.block.us,table.block.us) || (((entry.block.wr==0) || (table.block.wr==0)))) { + if (InitPage_CheckUseraccess(entry.block.us,table.block.us) || (((entry.block.wr==0) || (table.block.wr==0)))) { LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x", cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); paging.cr2=lin_addr; diff --git a/src/dosbox.cpp b/src/dosbox.cpp index e3374a08..81975831 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.135 2008-05-10 17:33:27 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.136 2008-05-18 13:10:42 c2woody Exp $ */ #include #include @@ -393,6 +393,12 @@ void DOSBOX_Init(void) { Pstring->Set_values(cores); Pstring->Set_help("CPU Core used in emulation. auto will switch to dynamic if available and appropriate."); + const char* cputype_values[] = { "auto", "386", "386_slow", "486_slow", "pentium_slow", 0}; + Pstring = secprop->Add_string("cputype",Property::Changeable::Always,"auto"); + Pstring->Set_values(cputype_values); + Pstring->Set_help("CPU Type used in emulation. auto is the fastest choice."); + + Pmulti_remain = secprop->Add_multiremain("cycles",Property::Changeable::Always," "); Pmulti_remain->Set_help( "Amount of instructions DOSBox tries to emulate each millisecond. Setting this value too high results in sound dropouts and lags. Cycles can be set in 3 ways:\n" From 8f9e2c379c6e53860d8a8d717d1889e719180e0d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 21 May 2008 08:50:59 +0000 Subject: [PATCH 3068/4131] Silence a few warnings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3156 --- src/debug/debug.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index de403a7e..b512b842 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.92 2008-01-21 21:20:01 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.93 2008-05-21 08:50:59 qbix79 Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -173,6 +173,7 @@ Bit32u GetAddress(Bit16u seg, Bit32u offset) return (seg<<4)+offset; } +static char empty_sel[] = { ' ',' ',0 }; bool GetDescriptorInfo(char* selname, char* out1, char* out2) { @@ -187,7 +188,7 @@ bool GetDescriptorInfo(char* selname, char* out1, char* out2) else if (strstr(selname,"ss") || strstr(selname,"SS")) sel = SegValue(ss); else { sel = GetHexValue(selname,selname); - if (*selname==0) selname=" "; + if (*selname==0) selname=empty_sel; } if (cpu.gdt.GetDescriptor(sel,desc)) { switch (desc.Type()) { @@ -808,7 +809,8 @@ static void DrawCode(void) { line20[20 - drawsize*2] = ' '; } else waddstr(dbg.win_code,line20); - char* res = ""; + char empty_res[] = { 0 }; + char* res = empty_res; if (showExtend) res = AnalyzeInstruction(dline, saveSel); // Spacepad it up to 28 characters size_t dline_len = strlen(dline); From 1a042c5abb291cf1e08fe3454c0df14a9c2a46f7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 21 May 2008 08:51:22 +0000 Subject: [PATCH 3069/4131] Add language strings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3157 --- src/debug/debug_gui.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index cc5ed1e3..ca1e23af 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug_gui.cpp,v 1.34 2008-03-19 08:41:45 qbix79 Exp $ */ +/* $Id: debug_gui.cpp,v 1.35 2008-05-21 08:51:22 qbix79 Exp $ */ #include "dosbox.h" @@ -243,12 +243,14 @@ void LOG_StartUp(void) { /* Register the log section */ Section_prop * sect=control->AddSection_prop("log",LOG_Init); - sect->Add_string("logfile",Property::Changeable::Always,""); + Prop_string* Pstring = sect->Add_string("logfile",Property::Changeable::Always,""); + Pstring->Set_help("file where the log messages will be saved to"); char buf[1024]; for (Bitu i=1;iAdd_bool(buf,Property::Changeable::Always,true); + Prop_bool* Pbool = sect->Add_bool(buf,Property::Changeable::Always,true); + Pbool->Set_help("Enable/Disable logging of this type."); } MSG_Add("LOG_CONFIGFILE_HELP","Logging related options for the debugger.\n"); } From 24bb7de36cb63309c6c7025922d3d7a6c80f8fe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 21 May 2008 21:29:32 +0000 Subject: [PATCH 3070/4131] add prefetch queue emulation Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3158 --- include/cpu.h | 6 +- src/cpu/Makefile.am | 2 +- src/cpu/core_prefetch.cpp | 315 ++++++++++++++++++++++++++++++++++++++ src/cpu/cpu.cpp | 28 +++- src/dosbox.cpp | 4 +- visualc_net/dosbox.vcproj | 3 + 6 files changed, 353 insertions(+), 5 deletions(-) create mode 100644 src/cpu/core_prefetch.cpp diff --git a/include/cpu.h b/include/cpu.h index 5544f93f..23f1aa5e 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.h,v 1.53 2008-05-18 13:10:42 c2woody Exp $ */ +/* $Id: cpu.h,v 1.54 2008-05-21 21:29:15 c2woody Exp $ */ #ifndef DOSBOX_CPU_H #define DOSBOX_CPU_H @@ -62,6 +62,8 @@ extern Bitu CPU_AutoDetermineMode; extern Bitu CPU_ArchitectureType; +extern Bitu CPU_PrefetchQueueSize; + /* Some common Defines */ /* A CPU Handler */ typedef Bits (CPU_Decoder)(void); @@ -75,6 +77,8 @@ 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); diff --git a/src/cpu/Makefile.am b/src/cpu/Makefile.am index 0d6c542f..5c63a9a4 100644 --- a/src/cpu/Makefile.am +++ b/src/cpu/Makefile.am @@ -3,5 +3,5 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libcpu.a libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h core_full.cpp instructions.h \ - paging.cpp lazyflags.h core_normal.cpp core_simple.cpp \ + paging.cpp lazyflags.h core_normal.cpp core_simple.cpp core_prefetch.cpp \ core_dyn_x86.cpp core_dynrec.cpp diff --git a/src/cpu/core_prefetch.cpp b/src/cpu/core_prefetch.cpp new file mode 100644 index 00000000..ebbd3f02 --- /dev/null +++ b/src/cpu/core_prefetch.cpp @@ -0,0 +1,315 @@ +/* + * 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_prefetch.cpp,v 1.1 2008-05-21 21:29:32 c2woody Exp $ */ + +#include + +#include "dosbox.h" +#include "mem.h" +#include "cpu.h" +#include "lazyflags.h" +#include "inout.h" +#include "callback.h" +#include "pic.h" +#include "fpu.h" +#include "paging.h" + +#if C_DEBUG +#include "debug.h" +#endif + +#if (!C_CORE_INLINE) +#define LoadMb(off) mem_readb(off) +#define LoadMw(off) mem_readw(off) +#define LoadMd(off) mem_readd(off) +#define SaveMb(off,val) mem_writeb(off,val) +#define SaveMw(off,val) mem_writew(off,val) +#define SaveMd(off,val) mem_writed(off,val) +#else +#include "paging.h" +#define LoadMb(off) mem_readb_inline(off) +#define LoadMw(off) mem_readw_inline(off) +#define LoadMd(off) mem_readd_inline(off) +#define SaveMb(off,val) mem_writeb_inline(off,val) +#define SaveMw(off,val) mem_writew_inline(off,val) +#define SaveMd(off,val) mem_writed_inline(off,val) +#endif + +extern Bitu cycle_count; + +#if C_FPU +#define CPU_FPU 1 //Enable FPU escape instructions +#endif + +#define CPU_PIC_CHECK 1 +#define CPU_TRAP_CHECK 1 + +#define OPCODE_NONE 0x000 +#define OPCODE_0F 0x100 +#define OPCODE_SIZE 0x200 + +#define PREFIX_ADDR 0x1 +#define PREFIX_REP 0x2 + +#define TEST_PREFIX_ADDR (core.prefixes & PREFIX_ADDR) +#define TEST_PREFIX_REP (core.prefixes & PREFIX_REP) + +#define DO_PREFIX_SEG(_SEG) \ + BaseDS=SegBase(_SEG); \ + BaseSS=SegBase(_SEG); \ + core.base_val_ds=_SEG; \ + goto restart_opcode; + +#define DO_PREFIX_ADDR() \ + core.prefixes=(core.prefixes & ~PREFIX_ADDR) | \ + (cpu.code.big ^ PREFIX_ADDR); \ + core.ea_table=&EATable[(core.prefixes&1) * 256]; \ + goto restart_opcode; + +#define DO_PREFIX_REP(_ZERO) \ + core.prefixes|=PREFIX_REP; \ + core.rep_zero=_ZERO; \ + goto restart_opcode; + +typedef PhysPt (*GetEAHandler)(void); + +static const Bit32u AddrMaskTable[2]={0x0000ffff,0xffffffff}; + +static struct { + Bitu opcode_index; + PhysPt cseip; + PhysPt base_ds,base_ss; + SegNames base_val_ds; + bool rep_zero; + Bitu prefixes; + GetEAHandler * ea_table; +} core; + +#define GETIP (core.cseip-SegBase(cs)) +#define SAVEIP reg_eip=GETIP; +#define LOADIP core.cseip=(SegBase(cs)+reg_eip); + +#define SegBase(c) SegPhys(c) +#define BaseDS core.base_ds +#define BaseSS core.base_ss + + +#define MAX_PQ_SIZE 32 +static Bit8u prefetch_buffer[MAX_PQ_SIZE]; +static bool pq_valid=false; +static Bitu pq_start; + +static INLINE Bit8u Fetchb() { + Bit8u temp; + if (pq_valid && (core.cseip>=pq_start) && (core.cseip=pq_start+CPU_PrefetchQueueSize-4) && + (core.cseip+1=pq_start) && (core.cseip+2=pq_start+CPU_PrefetchQueueSize-4) && + (core.cseip+2=pq_start) && (core.cseip+4=pq_start+CPU_PrefetchQueueSize-4) && + (core.cseip+40) { + if (invalidate_pq) { + pq_valid=false; + invalidate_pq=false; + } + LOADIP; + core.opcode_index=cpu.code.big*0x200; + core.prefixes=cpu.code.big; + core.ea_table=&EATable[cpu.code.big*256]; + BaseDS=SegBase(ds); + BaseSS=SegBase(ss); + core.base_val_ds=ds; +#if C_DEBUG +#if C_HEAVY_DEBUG + if (DEBUG_HeavyIsBreakpoint()) { + FillFlags(); + return debugCallback; + }; +#endif + cycle_count++; +#endif +restart_opcode: + Bit8u next_opcode=Fetchb(); + invalidate_pq=false; + if (core.opcode_index&OPCODE_0F) invalidate_pq=true; + else switch (next_opcode) { + 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: // jcc + case 0x9a: // call + case 0xc2: case 0xc3: // retn + case 0xc8: // enter + case 0xc9: // leave + case 0xca: case 0xcb: // retf + case 0xcc: // int3 + case 0xcd: // int + case 0xce: // into + case 0xcf: // iret + case 0xe0: // loopnz + case 0xe1: // loopz + case 0xe2: // loop + case 0xe3: // jcxz + case 0xe8: // call + case 0xe9: case 0xea: case 0xeb: // jmp + case 0xff: + invalidate_pq=true; + break; + default: + break; + } + switch (core.opcode_index+next_opcode) { + #include "core_normal/prefix_none.h" + #include "core_normal/prefix_0f.h" + #include "core_normal/prefix_66.h" + #include "core_normal/prefix_66_0f.h" + default: + illegal_opcode: +#if C_DEBUG + { + Bitu len=(GETIP-reg_eip); + LOADIP; + if (len>16) len=16; + char tempcode[16*2+1];char * writecode=tempcode; + for (;len>0;len--) { + sprintf(writecode,"%X",mem_readb(core.cseip++)); + writecode+=2; + } + LOG(LOG_CPU,LOG_NORMAL)("Illegal/Unhandled opcode %s",tempcode); + } +#endif + CPU_Exception(6,0); + invalidate_pq=true; + continue; + } + SAVEIP; + } + FillFlags(); + return CBRET_NONE; +decode_end: + SAVEIP; + FillFlags(); + return CBRET_NONE; +} + +Bits CPU_Core_Prefetch_Trap_Run(void) { + Bits oldCycles = CPU_Cycles; + CPU_Cycles = 1; + cpu.trap_skip = false; + + Bits ret=CPU_Core_Prefetch_Run(); + if (!cpu.trap_skip) CPU_HW_Interrupt(1); + CPU_Cycles = oldCycles-1; + cpudecoder = &CPU_Core_Prefetch_Run; + + return ret; +} + + + +void CPU_Core_Prefetch_Init(void) { + +} + diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index e5c8991a..0ed6800f 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.111 2008-05-18 13:11:14 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.112 2008-05-21 21:29:32 c2woody Exp $ */ #include #include @@ -65,6 +65,8 @@ Bitu CPU_ArchitectureType = CPU_ARCHTYPE_MIXED; Bitu CPU_flag_id_toggle=0; +Bitu CPU_PrefetchQueueSize=0; + void CPU_Core_Full_Init(void); void CPU_Core_Normal_Init(void); void CPU_Core_Simple_Init(void); @@ -2313,10 +2315,34 @@ public: CPU_ArchitectureType = CPU_ARCHTYPE_MIXED; } else if (cputype == "386") { CPU_ArchitectureType = CPU_ARCHTYPE_386FAST; + } else if (cputype == "386_prefetch") { + CPU_ArchitectureType = CPU_ARCHTYPE_386FAST; + if (core == "normal") { + cpudecoder=&CPU_Core_Prefetch_Run; + CPU_PrefetchQueueSize = 16; + } else if (core == "auto") { + cpudecoder=&CPU_Core_Prefetch_Run; + CPU_PrefetchQueueSize = 16; + CPU_AutoDetermineMode&=(~CPU_AUTODETERMINE_CORE); + } else { + E_Exit("prefetch queue emulation requires the normal core setting."); + } } else if (cputype == "386_slow") { CPU_ArchitectureType = CPU_ARCHTYPE_386SLOW; } else if (cputype == "486_slow") { CPU_ArchitectureType = CPU_ARCHTYPE_486NEWSLOW; + } else if (cputype == "486_prefetch") { + CPU_ArchitectureType = CPU_ARCHTYPE_486NEWSLOW; + if (core == "normal") { + cpudecoder=&CPU_Core_Prefetch_Run; + CPU_PrefetchQueueSize = 32; + } else if (core == "auto") { + cpudecoder=&CPU_Core_Prefetch_Run; + CPU_PrefetchQueueSize = 32; + CPU_AutoDetermineMode&=(~CPU_AUTODETERMINE_CORE); + } else { + E_Exit("prefetch queue emulation requires the normal core setting."); + } } else if (cputype == "pentium_slow") { CPU_ArchitectureType = CPU_ARCHTYPE_PENTIUMSLOW; } diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 81975831..57a68c6f 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.136 2008-05-18 13:10:42 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.137 2008-05-21 21:29:16 c2woody Exp $ */ #include #include @@ -393,7 +393,7 @@ void DOSBOX_Init(void) { Pstring->Set_values(cores); Pstring->Set_help("CPU Core used in emulation. auto will switch to dynamic if available and appropriate."); - const char* cputype_values[] = { "auto", "386", "386_slow", "486_slow", "pentium_slow", 0}; + const char* cputype_values[] = { "auto", "386", "386_slow", "486_slow", "pentium_slow", "386_prefetch", 0}; Pstring = secprop->Add_string("cputype",Property::Changeable::Always,"auto"); Pstring->Set_values(cputype_values); Pstring->Set_help("CPU Type used in emulation. auto is the fastest choice."); diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index f2257ce0..0e7a1f22 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -179,6 +179,9 @@ + + From 7df629843371ba55202eebfe2b3a5c23cba5c1e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 22 May 2008 16:45:57 +0000 Subject: [PATCH 3071/4131] use device attribute fields for ioctl remote check function (Future Shock svga upgrade); thanks to ripa Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3159 --- src/dos/dos_ioctl.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index a921a0f1..14dd3d88 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.30 2008-03-19 17:55:58 c2woody Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.31 2008-05-22 16:45:57 c2woody Exp $ */ #include #include "dosbox.h" @@ -115,10 +115,15 @@ bool DOS_IOCTL(void) { } return true; case 0x09: /* Check if block device remote */ - reg_dx=0; - if (Drives[drive]->isRemote()) reg_dx|=(1 << 12); - //TODO Set bit 9 on drives that don't support direct I/O - reg_al=0; + if (Drives[drive]->isRemote()) { + reg_dx=0x1000; // device is remote + // undocumented bits always clear + } else { + reg_dx=0x0800; // Open/Close supported + // undocumented bits from device attribute word + // TODO Set bit 9 on drives that don't support direct I/O + } + reg_ax=0x300; return true; case 0x0D: /* Generic block device request */ { From 65e9118e27b564818e686dc2753428dd9de72251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 24 May 2008 18:50:39 +0000 Subject: [PATCH 3072/4131] fix iso-name parsing for special long file names Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3160 --- src/dos/drive_iso.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 4acc006d..6d088a16 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.22 2007-11-01 12:15:34 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.23 2008-05-24 18:50:39 c2woody Exp $ */ #include #include @@ -501,11 +501,11 @@ int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) if (de->fileIdentLength == 1 && de->ident[0] == 0) strcpy((char*)de->ident, "."); else if (de->fileIdentLength == 1 && de->ident[0] == 1) strcpy((char*)de->ident, ".."); else { - if (de->fileIdentLength > 31) return -1; + if (de->fileIdentLength > 200) return -1; de->ident[de->fileIdentLength] = 0; } } else { - if (de->fileIdentLength > 37) return -1; + if (de->fileIdentLength > 200) return -1; de->ident[de->fileIdentLength] = 0; // remove any file version identifiers as there are some cdroms that don't have them strreplace((char*)de->ident, ';', 0); @@ -513,6 +513,13 @@ int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) int tmp = strlen((char*)de->ident); if (tmp > 0 && de->ident[tmp - 1] == '.') de->ident[tmp - 1] = 0; } + const char* dotpos = strchr((char*)de->ident, '.'); + if (dotpos!=NULL) { + if (dotpos-(char*)de->ident>8) { + strcpy((char*)(&de->ident[8]),dotpos); + } + } + if (strlen((char*)de->ident)>12) de->ident[12]=0; return de->length; } From dbb69e15a084c5f246b90c71fc9f86f4b8458223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 25 May 2008 17:24:59 +0000 Subject: [PATCH 3073/4131] fix Fable cdrom installer (odd harddrive check) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3161 --- src/dos/dos_ioctl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 14dd3d88..04c808a9 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.31 2008-05-22 16:45:57 c2woody Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.32 2008-05-25 17:24:59 c2woody Exp $ */ #include #include "dosbox.h" @@ -119,7 +119,7 @@ bool DOS_IOCTL(void) { reg_dx=0x1000; // device is remote // undocumented bits always clear } else { - reg_dx=0x0800; // Open/Close supported + reg_dx=0x0802; // Open/Close supported; 32bit access supported (any use? fixes Fable installer) // undocumented bits from device attribute word // TODO Set bit 9 on drives that don't support direct I/O } From d0dbfbaad200d0eead639b04832a4e18749449e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 26 May 2008 19:13:42 +0000 Subject: [PATCH 3074/4131] reject joysticks with bad specs Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3162 --- src/gui/sdl_mapper.cpp | 50 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 2015bee5..f654277a 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.48 2008-02-16 20:47:41 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.49 2008-05-26 19:13:42 c2woody Exp $ */ #include #include @@ -2153,12 +2153,50 @@ static void InitializeJoysticks(void) { if (joytype != JOY_NONE) { mapper.sticks.num=SDL_NumJoysticks(); if (joytype==JOY_AUTO) { + // try to figure out what joystick type to select + // depending on the number of physically attached joysticks if (mapper.sticks.num>1) { - joytype=JOY_2AXIS; - LOG_MSG("Two or more joysticks reported, initializing with 2axis"); + // more than one joystick present; if all are acceptable use 2axis + // to allow emulation of two joysticks + bool first_usable=false; + SDL_Joystick* tmp_stick1=SDL_JoystickOpen(0); + if (tmp_stick1) { + if ((SDL_JoystickNumAxes(tmp_stick1)>1) || (SDL_JoystickNumButtons(tmp_stick1)>0)) { + first_usable=true; + } + SDL_JoystickClose(tmp_stick1); + } + bool second_usable=false; + SDL_Joystick* tmp_stick2=SDL_JoystickOpen(1); + if (tmp_stick2) { + if ((SDL_JoystickNumAxes(tmp_stick2)>1) || (SDL_JoystickNumButtons(tmp_stick2)>0)) { + second_usable=true; + } + SDL_JoystickClose(tmp_stick2); + } + // choose joystick type now that we know which physical joysticks are usable + if (first_usable) { + if (second_usable) { + joytype=JOY_2AXIS; + LOG_MSG("Two or more joysticks reported, initializing with 2axis"); + } else { + joytype=JOY_4AXIS; + LOG_MSG("One joystick reported, initializing with 4axis"); + } + } else if (second_usable) { + joytype=JOY_4AXIS_2; + LOG_MSG("One joystick reported, initializing with 4axis_2"); + } } else if (mapper.sticks.num) { - joytype=JOY_4AXIS; - LOG_MSG("One joystick reported, initializing with 4axis"); + // one joystick present; if it is acceptable use 4axis + joytype=JOY_NONE; + SDL_Joystick* tmp_stick1=SDL_JoystickOpen(0); + if (tmp_stick1) { + if ((SDL_JoystickNumAxes(tmp_stick1)>0) || (SDL_JoystickNumButtons(tmp_stick1)>0)) { + joytype=JOY_4AXIS; + LOG_MSG("One joystick reported, initializing with 4axis"); + } + } } else { joytype=JOY_NONE; } From a82bd865f03ec1467e57809106b63d01c46e3fdb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 28 May 2008 09:14:06 +0000 Subject: [PATCH 3075/4131] workaround for debian/ubuntu sdl changes. force mouse release on more events. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3163 --- src/gui/sdlmain.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 9225d544..ab4f18f1 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.142 2008-03-19 20:35:17 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.143 2008-05-28 09:14:06 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -732,7 +732,7 @@ void GFX_EndUpdate( const Bit16u *changedLines ) { rect->h = changedLines[index]; #if 0 if (rect->h + rect->y > sdl.surface->h) { - LOG_MSG("WTF"); + LOG_MSG("WTF %d + %d >%d",rect->h,rect->y,sdl.surface->h); } #endif y += changedLines[index]; @@ -1374,10 +1374,11 @@ int main(int argc, char* argv[]) { /* Display Welcometext in the console */ LOG_MSG("DOSBox version %s",VERSION); - LOG_MSG("Copyright 2002-2007 DOSBox Team, published under GNU GPL."); + LOG_MSG("Copyright 2002-2008 DOSBox Team, published under GNU GPL."); LOG_MSG("---"); /* Init SDL */ + putenv(const_cast("SDL_DISABLE_LOCK_KEYS=1")); //Workaround debian/ubuntu fixes for SDL. if ( SDL_Init( SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM |SDL_INIT_NOPARACHUTE ) < 0 ) E_Exit("Can't init SDL %s",SDL_GetError()); @@ -1537,8 +1538,15 @@ int main(int argc, char* argv[]) { ;//nothing pressed killswitch } catch(...){ + //Force visible mouse to end user. Somehow this sometimes doesn't happen + SDL_WM_GrabInput(SDL_GRAB_OFF); + SDL_ShowCursor(SDL_ENABLE); throw;//dunno what happened. rethrow for sdl to catch } + //Force visible mouse to end user. Somehow this sometimes doesn't happen + SDL_WM_GrabInput(SDL_GRAB_OFF); + SDL_ShowCursor(SDL_ENABLE); + SDL_Quit();//Let's hope sdl will quit as well when it catches an exception return 0; }; From 8293b1fab6b01632ce11ddcb14a3a7b3705308c4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 28 May 2008 09:53:31 +0000 Subject: [PATCH 3076/4131] Correct dosbox internal startup time. Give correct errorcode for 5c (Beta1) Do some input checking and give errorcode for 68 (Beta1 fixed) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3164 --- include/dos_inc.h | 3 ++- src/dos/dos.cpp | 21 ++++++++++++++++----- src/dos/dos_files.cpp | 15 ++++++++++++++- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 4f46a970..d113d392 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.73 2008-01-21 21:26:49 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.74 2008-05-28 09:53:31 qbix79 Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -110,6 +110,7 @@ bool DOS_ReadFile(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_CloseFile(Bit16u handle); +bool DOS_FlushFile(Bit16u handle); bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry); bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry); bool DOS_GetFileDate(Bit16u entry, Bit16u* otime, Bit16u* odate); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index e32f9292..82b5d312 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.111 2008-04-07 19:11:48 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.112 2008-05-28 09:53:31 qbix79 Exp $ */ #include #include @@ -849,6 +849,11 @@ static Bitu DOS_21Handler(void) { } break; } + case 0x5c: /* FLOCK File region locking */ + DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); + reg_ax = dos.errorcode; + CALLBACK_SCF(true); + break; case 0x5d: /* Network Functions */ if(reg_al == 0x06) { SegSet16(ds,DOS_SDA_SEG); @@ -977,6 +982,14 @@ static Bitu DOS_21Handler(void) { CALLBACK_SCF(false); break; }; + case 0x68: /* FFLUSH Commit file */ + if(DOS_FlushFile(reg_bl)) { + CALLBACK_SCF(false); + } else { + reg_ax = dos.errorcode; + CALLBACK_SCF(true); + } + break; case 0x69: /* Get/Set disk serial number */ { switch(reg_al) { @@ -1000,14 +1013,13 @@ static Bitu DOS_21Handler(void) { CALLBACK_SCF(true); } break; + case 0x71: /* Unknown probably 4dos detection */ reg_ax=0x7100; CALLBACK_SCF(true); LOG(LOG_DOSMISC,LOG_NORMAL)("DOS:Windows long file name support call %2X",reg_al); break; - case 0x68: /* FFLUSH Commit file */ - CALLBACK_SCF(false); //mirek case 0xE0: case 0x18: /* NULL Function for CP/M compatibility or Extended rename FCB */ case 0x1d: /* NULL Function for CP/M compatibility or Extended rename FCB */ @@ -1016,7 +1028,6 @@ static Bitu DOS_21Handler(void) { case 0x6b: /* NULL Function */ case 0x61: /* UNUSED */ case 0xEF: /* Used in Ancient Art Of War CGA */ - case 0x5c: /* FLOCK File region locking */ case 0x5e: /* More Network Functions */ default: LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Unhandled call %02X al=%02X. Set al to default of 0",reg_ah,reg_al); @@ -1116,7 +1127,7 @@ public: dos.date.day=(Bit8u)loctime->tm_mday; dos.date.month=(Bit8u)loctime->tm_mon+1; dos.date.year=(Bit16u)loctime->tm_year+1900; - Bit32u ticks=(Bit32u)((loctime->tm_hour*3600+loctime->tm_min*60+loctime->tm_sec)*18.2); + Bit32u ticks=(Bit32u)((loctime->tm_hour*3600+loctime->tm_min*60+loctime->tm_sec)*(float)PIT_TICK_RATE/65536.0); mem_writed(BIOS_TIMER,ticks); } ~DOS(){ diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 8dbf5e83..cba56eb6 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.96 2008-04-30 18:26:17 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.97 2008-05-28 09:53:31 qbix79 Exp $ */ #include #include @@ -391,6 +391,19 @@ bool DOS_CloseFile(Bit16u entry) { } return true; } +bool DOS_FlushFile(Bit16u entry) { + Bit32u handle=RealHandle(entry); + if (handle>=DOS_FILES) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; + if (!Files[handle] || !Files[handle]->IsOpen()) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; + LOG(LOG_DOSMISC,LOG_NORMAL)("FFlush used."); + return true; +} static bool PathExists(char const * const name) { const char* leading = strrchr(name,'\\'); From d86947397098504ce3e2386ad217a6cd6ad98ba8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 28 May 2008 20:43:13 +0000 Subject: [PATCH 3077/4131] Fix panning for supaplex, wish demo and majic show demo. (Beta1 thank h-a-l-9000) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3165 --- include/vga.h | 3 ++- src/hardware/vga_draw.cpp | 39 ++++++++++++++++++++------------------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/include/vga.h b/include/vga.h index 91ff973b..c66faeed 100644 --- a/include/vga.h +++ b/include/vga.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga.h,v 1.41 2008-04-01 19:58:17 c2woody Exp $ */ +/* $Id: vga.h,v 1.42 2008-05-28 20:43:13 qbix79 Exp $ */ #ifndef DOSBOX_VGA_H #define DOSBOX_VGA_H @@ -106,6 +106,7 @@ typedef struct { Bitu height; Bitu blocks; Bitu address; + Bitu panning; Bit8u *linear_base; Bitu linear_mask; Bitu address_add; diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 3c80c76e..fd0ed78b 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.99 2008-04-13 19:50:47 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.100 2008-05-28 20:43:13 qbix79 Exp $ */ #include #include @@ -488,7 +488,7 @@ static Bit8u * VGA_TEXT_Draw_Line_9(Bitu vidstart, Bitu line) { Bits font_addr; Bit8u * draw=(Bit8u *)TempLine; bool underline=(vga.crtc.underline_location&0x1f)==line; - Bit8u pel_pan=vga.config.pel_panning; + Bit8u pel_pan=vga.draw.panning; if ((vga.attr.mode_control&0x20) && (vga.draw.lines_done>=vga.draw.split_line)) pel_pan=0; const Bit8u *vidmem = &vga.tandy.draw_base[vidstart]; Bit8u chr=vidmem[0]; @@ -546,7 +546,7 @@ static Bit8u * VGA_TEXT_Xlat16_Draw_Line_9(Bitu vidstart, Bitu line) { Bits font_addr; Bit16u * draw=(Bit16u *)TempLine; bool underline=(vga.crtc.underline_location&0x1f)==line; - Bit8u pel_pan=vga.config.pel_panning; + Bit8u pel_pan=vga.draw.panning; if ((vga.attr.mode_control&0x20) && (vga.draw.lines_done>=vga.draw.split_line)) pel_pan=0; const Bit8u *vidmem = &vga.tandy.draw_base[vidstart]; Bit8u chr=vidmem[0]; @@ -606,15 +606,6 @@ skip_cursor: return TempLine; } -static void VGA_VerticalDisplayEnd(Bitu val) { -// vga.config.retrace=true; - vga.config.real_start=vga.config.display_start & (vga.vmemwrap-1); -} - -static void VGA_HorizontalTimer(void) { - -} - #ifdef VGA_KEEP_CHANGES static INLINE void VGA_ChangesEnd(void ) { if ( vga.changes.active ) { @@ -641,7 +632,7 @@ static void VGA_ProcessSplit() { // In text mode only the characters are shifted by panning, not the address; // this is done in the text line draw function. vga.draw.address = vga.draw.byte_panning_shift*vga.config.bytes_skip; - if (!(vga.mode==M_TEXT)) vga.draw.address += vga.config.pel_panning; + if (!(vga.mode==M_TEXT)) vga.draw.address += vga.draw.panning; } vga.draw.address_line=0; } @@ -739,6 +730,13 @@ static void INLINE VGA_ChangesStart( void ) { } #endif +static void VGA_DisplayStartLatch(Bitu val) { + vga.config.real_start=vga.config.display_start & (vga.vmemwrap-1); +} + +static void VGA_PanningLatch(Bitu val) { + vga.draw.panning = vga.config.pel_panning; +} static void VGA_VerticalTimer(Bitu val) { double error = vga.draw.delay.framestart; @@ -748,8 +746,9 @@ static void VGA_VerticalTimer(Bitu val) { //PIC_AddEvent( VGA_VerticalDisplayEnd, (float)vga.draw.delay.vrstart ); double flip_offset = vga.screenflip/1000.0 + vga.draw.delay.vrstart; if(flip_offset > vga.draw.delay.vtotal) { - VGA_VerticalDisplayEnd(0); - } else PIC_AddEvent( VGA_VerticalDisplayEnd,(float)flip_offset); + VGA_DisplayStartLatch(0); + } else PIC_AddEvent( VGA_DisplayStartLatch,(float)flip_offset); + PIC_AddEvent(VGA_PanningLatch,(float)vga.draw.delay.vrend); if ( GCC_UNLIKELY( vga.draw.parts_left)) { if (!IS_VGA_ARCH || (svgaCard!=SVGA_None)) { @@ -789,7 +788,7 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.byte_panning_shift = 8; vga.draw.address += vga.config.bytes_skip; vga.draw.address *= vga.draw.byte_panning_shift; - vga.draw.address += vga.config.pel_panning; + vga.draw.address += vga.draw.panning; #ifdef VGA_KEEP_CHANGES startaddr_changed=true; #endif @@ -809,7 +808,7 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.byte_panning_shift = 4; vga.draw.address += vga.config.bytes_skip; vga.draw.address *= vga.draw.byte_panning_shift; - vga.draw.address += vga.config.pel_panning; + vga.draw.address += vga.draw.panning; #ifdef VGA_KEEP_CHANGES startaddr_changed=true; #endif @@ -922,7 +921,8 @@ void VGA_ActivateHardwareCursor(void) { void VGA_SetupDrawing(Bitu val) { if (vga.mode==M_ERROR) { PIC_RemoveEvents(VGA_VerticalTimer); - PIC_RemoveEvents(VGA_VerticalDisplayEnd); + PIC_RemoveEvents(VGA_PanningLatch); + PIC_RemoveEvents(VGA_DisplayStartLatch); return; } /* Calculate the FPS for this screen */ @@ -1341,7 +1341,8 @@ void VGA_SetupDrawing(Bitu val) { (vga.mode != vga.lastmode)) { vga.lastmode = vga.mode; PIC_RemoveEvents(VGA_VerticalTimer); - PIC_RemoveEvents(VGA_VerticalDisplayEnd); + PIC_RemoveEvents(VGA_PanningLatch); + PIC_RemoveEvents(VGA_DisplayStartLatch); PIC_RemoveEvents(VGA_DrawPart); PIC_RemoveEvents(VGA_DrawSingleLine); vga.draw.width = width; From 44aca76921c7cece1b5ac1be12c0d4f75fda4988 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 30 May 2008 12:42:38 +0000 Subject: [PATCH 3078/4131] make cycles reset to correct default value. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3166 --- include/setup.h | 7 +++++-- src/misc/setup.cpp | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/include/setup.h b/include/setup.h index a94c2592..a6ce9546 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.35 2008-04-29 08:23:16 qbix79 Exp $ */ +/* $Id: setup.h,v 1.36 2008-05-30 12:42:37 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -130,6 +130,7 @@ public: 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. @@ -138,6 +139,7 @@ public: 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& GetValues() const; + Value::Etype Get_type(){return default_value.type;} protected: Value value; @@ -277,9 +279,10 @@ 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) { - value = ""; + default_value = value = ""; } Section_prop *GetSection() { return section; } const Section_prop *GetSection() const { return section; } diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index d71bfcb0..4e34fc52 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.48 2008-04-29 08:23:16 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.49 2008-05-30 12:42:38 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -273,6 +273,23 @@ void Prop_hex::SetValue(std::string const& input){ SetVal(val,false,true); } +void Prop_multival::make_default_value(){ + Bitu i = 1; + Property *p = section->Get_prop(0); + if(!p) return; + + std::string result = p->Get_Default_Value().ToString(); + while( (p = section->Get_prop(i++)) ) { + std::string props = p->Get_Default_Value().ToString(); + if(props == "") continue; + result += seperator; result += props; + } + Value val(result,Value::V_STRING); + SetVal(val,false,true); +} + + + //TODO checkvalue stuff void Prop_multival_remain::SetValue(std::string const& input) { Value val(input,Value::V_STRING); @@ -303,6 +320,12 @@ void Prop_multival_remain::SetValue(std::string const& input) { in = local; local = ""; } + //Test Value. If it fails set default + Value valtest (in,p->Get_type()); + if(!p->CheckValue(valtest,true)) { + make_default_value(); + return; + } p->SetValue(in); } } @@ -324,21 +347,28 @@ void Prop_multival::SetValue(std::string const& input) { if(loc != string::npos) local.erase(0,loc); loc = local.find_first_of(seperator); string in = "";//default value - if(loc != string::npos) { //seperator found + if(loc != string::npos) { //seperator found in = local.substr(0,loc); local.erase(0,loc+1); } else if(local.size()) { //last argument in = local; local = ""; } + //Test Value. If it fails set default + Value valtest (in,p->Get_type()); + if(!p->CheckValue(valtest,true)) { + make_default_value(); + return; + } p->SetValue(in); + } } const std::vector& Property::GetValues() const { return suggested_values; } - const std::vector& Prop_multival::GetValues() const +const std::vector& Prop_multival::GetValues() const { Property *p = section->Get_prop(0); //No properties in this section. do nothing From c1722ea76085ac28dd9fa22d0efd3297766c9f22 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 2 Jun 2008 17:26:59 +0000 Subject: [PATCH 3079/4131] Commit patch [ 1982117 ] Some minor bugs in the debugger, by etillite Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3167 --- src/debug/debug.cpp | 37 ++++++++++++++++++++----------------- src/debug/debug_gui.cpp | 29 +++++++++++++++++------------ 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index b512b842..9a4e8b08 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.93 2008-05-21 08:50:59 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.94 2008-06-02 17:26:59 qbix79 Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -56,8 +56,8 @@ void WIN32_Console(); #include #include static struct termios consolesettings; -int old_cursor_state; #endif +int old_cursor_state; // Forwards static void DrawCode(void); @@ -595,18 +595,17 @@ void CBreakpoint::ShowList(void) CBreakpoint* bp = (*i); if (bp->GetType()==BKPNT_PHYSICAL) { DEBUG_ShowMsg("%02X. BP %04X:%04X\n",nr,bp->GetSegment(),bp->GetOffset()); - nr++; } else if (bp->GetType()==BKPNT_INTERRUPT) { if (bp->GetValue()==BPINT_ALL) DEBUG_ShowMsg("%02X. BPINT %02X\n",nr,bp->GetIntNr()); else DEBUG_ShowMsg("%02X. BPINT %02X AH=%02X\n",nr,bp->GetIntNr(),bp->GetValue()); - nr++; } else if (bp->GetType()==BKPNT_MEMORY) { DEBUG_ShowMsg("%02X. BPMEM %04X:%04X (%02X)\n",nr,bp->GetSegment(),bp->GetOffset(),bp->GetValue()); - nr++; } else if (bp->GetType()==BKPNT_MEMORY_PROT) { DEBUG_ShowMsg("%02X. BPPM %04X:%08X (%02X)\n",nr,bp->GetSegment(),bp->GetOffset(),bp->GetValue()); - nr++; + } else if (bp->GetType()==BKPNT_MEMORY_LINEAR ) { + DEBUG_ShowMsg("%02X. BPLM %08X (%02X)\n",nr,bp->GetOffset(),bp->GetValue()); }; + nr++; } }; @@ -803,7 +802,7 @@ static void DrawCode(void) { } if (toolarge) { waddstr(dbg.win_code,".."); drawsize++; }; // Spacepad up to 20 characters - if(drawsize && (drawsize < 10)) { + if(drawsize && (drawsize < 11)) { line20[20 - drawsize*2] = 0; waddstr(dbg.win_code,line20); line20[20 - drawsize*2] = ' '; @@ -1016,12 +1015,12 @@ bool ParseCommand(char* str) { }; name[12] = 0; if(!name[0]) return false; - DEBUG_ShowMsg("DEBUG: Variable list load (%s) : %s.\n",name,(CDebugVar::SaveVars(name)?"ok":"failure")); + DEBUG_ShowMsg("DEBUG: Variable list load (%s) : %s.\n",name,(CDebugVar::LoadVars(name)?"ok":"failure")); return true; }; if (command == "SR") { // Set register value - DEBUG_ShowMsg("DEBUG: Set Register success.\n",(ChangeRegister(found)?"success":"failure")); + DEBUG_ShowMsg("DEBUG: Set Register %s.\n",(ChangeRegister(found)?"success":"failure")); return true; }; @@ -1109,7 +1108,7 @@ bool ParseCommand(char* str) { DEBUG_ShowMsg("DEBUG: Breakpoints deleted.\n"); } else { // delete single breakpoint - CBreakpoint::DeleteByIndex(bpNr); + DEBUG_ShowMsg("DEBUG: Breakpoint deletion %s.\n",(CBreakpoint::DeleteByIndex(bpNr)?"success":"failure")); } return true; }; @@ -1256,9 +1255,10 @@ bool ParseCommand(char* str) { DEBUG_ShowMsg("F9 - Set/Remove breakpoint.\n"); DEBUG_ShowMsg("F10/F11 - Step over / trace into instruction.\n"); DEBUG_ShowMsg("ALT + D/E/S/X/B - Set data view to DS:SI/ES:DI/SS:SP/DS:DX/ES:BX.\n"); - DEBUG_ShowMsg("Escape - clear input line."); + DEBUG_ShowMsg("Escape - Clear input line."); DEBUG_ShowMsg("Up/Down - Move code view cursor.\n"); DEBUG_ShowMsg("Page Up/Down - Scroll data view.\n"); + DEBUG_ShowMsg("Home/End - Scroll log messages.\n"); DEBUG_ShowMsg("BP [segment]:[offset] - Set breakpoint.\n"); DEBUG_ShowMsg("BPINT [intNr] * - Set interrupt breakpoint.\n"); DEBUG_ShowMsg("BPINT [intNr] [ah] - Set interrupt breakpoint with ah.\n"); @@ -1274,7 +1274,7 @@ bool ParseCommand(char* str) { #if C_HEAVY_DEBUG DEBUG_ShowMsg("LOG [num] - Write cpu log file.\n"); DEBUG_ShowMsg("LOGS/LOGL [num] - Write short/long cpu log file.\n"); - DEBUG_ShowMsg("HEAVYLOG - Enable/Disable automatic cpu when dosbox exits.\n"); + DEBUG_ShowMsg("HEAVYLOG - Enable/Disable automatic cpu log when dosbox exits.\n"); DEBUG_ShowMsg("ZEROPROTECT - Enable/Disable zero code execution detecion.\n"); #endif DEBUG_ShowMsg("SR [reg] [value] - Set register value.\n"); @@ -1464,12 +1464,15 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) { } break; } if (jmp) { + pos = strchr(instu,'$'); + if (pos) { pos = strchr(instu,'+'); if (pos) { strcpy(result,"(down)"); } else { strcpy(result,"(up)"); } + } } else { sprintf(result,"(no jmp)"); } @@ -1836,13 +1839,13 @@ static void LogInstruction(Bit16u segValue, Bit32u eipValue, ofstream& out) { << " DS:" << setw(4) << SegValue(ds)<< " ES:" << setw(4) << SegValue(es); if(cpuLogType == 0) { - out << " SS:" << setw(4) << SegValue(ss) << " C" << get_CF() << " Z" << get_ZF() - << " S" << get_SF() << " O" << get_OF() << " I" << GETFLAGBOOL(IF); + out << " SS:" << setw(4) << SegValue(ss) << " C" << (get_CF()>0) << " Z" << (get_ZF()>0) + << " S" << (get_SF()>0) << " O" << (get_OF()>0) << " I" << GETFLAGBOOL(IF); } else { out << " FS:" << setw(4) << SegValue(fs) << " GS:" << setw(4) << SegValue(gs) << " SS:" << setw(4) << SegValue(ss) - << " CF:" << get_CF() << " ZF:" << get_ZF() << " SF:" << get_SF() - << " OF:" << get_OF() << " AF:" << get_AF() << " PF:" << get_PF() + << " CF:" << (get_CF()>0) << " ZF:" << (get_ZF()>0) << " SF:" << (get_SF()>0) + << " OF:" << (get_OF()>0) << " AF:" << (get_AF()>0) << " PF:" << (get_PF()>0) << " IF:" << GETFLAGBOOL(IF); } if(cpuLogType == 2) { @@ -1950,8 +1953,8 @@ static void DEBUG_ShutDown(Section * sec) { CBreakpoint::DeleteAll(); CDebugVar::DeleteAll(); - #ifndef WIN32 curs_set(old_cursor_state); + #ifndef WIN32 tcsetattr(0, TCSANOW,&consolesettings); // printf("\e[0m\e[2J"); //Seems to destroy scrolling printf("\ec"); diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index ca1e23af..1964632f 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug_gui.cpp,v 1.35 2008-05-21 08:51:22 qbix79 Exp $ */ +/* $Id: debug_gui.cpp,v 1.36 2008-06-02 17:26:59 qbix79 Exp $ */ #include "dosbox.h" @@ -69,7 +69,7 @@ void DEBUG_ShowMsg(char const* format,...) { if (logBuffPos!=logBuff.end()) { logBuffPos=logBuff.end(); DEBUG_RefreshPage(0); - mvwprintw(dbg.win_out,dbg.win_out->_maxy-1, 0, ""); +// mvwprintw(dbg.win_out,dbg.win_out->_maxy-1, 0, ""); } logBuff.push_back(buf); if (logBuff.size() > MAX_LOG_BUFFER) @@ -85,15 +85,19 @@ void DEBUG_RefreshPage(char scroll) { else if (scroll==1 && logBuffPos!=logBuff.end()) logBuffPos++; list::iterator i = logBuffPos; - int rem_lines = dbg.win_out->_maxy; + int maxy, maxx; getmaxyx(dbg.win_out,maxy,maxx); + int rem_lines = maxy; wclear(dbg.win_out); while (rem_lines > 0 && i!=logBuff.begin()) { - rem_lines -= (int) ((*--i).size() / dbg.win_out->_maxx) + 1; + --i; + for (string::size_type posf=0, posl; (posl=(*i).find('\n',posf)) != string::npos ;posf=posl+1) + rem_lines -= (int) ((posl-posf) / maxx) + 1; // len=(posl+1)-posf-1 /* Const cast is needed for pdcurses which has no const char in mvwprintw (bug maybe) */ mvwprintw(dbg.win_out,rem_lines-1, 0, const_cast((*i).c_str())); } + mvwprintw(dbg.win_out,maxy-1, 0, ""); wrefresh(dbg.win_out); } @@ -159,22 +163,23 @@ static void DrawBars(void) { static void MakeSubWindows(void) { /* The Std output win should go in bottem */ /* Make all the subwindows */ + int win_main_maxy, win_main_maxx; getmaxyx(dbg.win_main,win_main_maxy,win_main_maxx); int outy=1; /* The Register window */ - dbg.win_reg=subwin(dbg.win_main,4,dbg.win_main->_maxx,outy,0); + dbg.win_reg=subwin(dbg.win_main,4,win_main_maxx,outy,0); outy+=5; /* The Data Window */ - dbg.win_data=subwin(dbg.win_main,10,dbg.win_main->_maxx,outy,0); + dbg.win_data=subwin(dbg.win_main,10,win_main_maxx,outy,0); outy+=11; /* The Code Window */ - dbg.win_code=subwin(dbg.win_main,11,dbg.win_main->_maxx,outy,0); + dbg.win_code=subwin(dbg.win_main,11,win_main_maxx,outy,0); outy+=12; /* The Variable Window */ - dbg.win_var=subwin(dbg.win_main,4,dbg.win_main->_maxx,outy,0); + dbg.win_var=subwin(dbg.win_main,4,win_main_maxx,outy,0); outy+=5; /* The Output Window */ - dbg.win_out=subwin(dbg.win_main,dbg.win_main->_maxy-outy-1,dbg.win_main->_maxx,outy,0); - dbg.input_y=dbg.win_main->_maxy-1; + dbg.win_out=subwin(dbg.win_main,win_main_maxy-outy-1,win_main_maxx,outy,0); + dbg.input_y=win_main_maxy-1; scrollok(dbg.win_out,TRUE); DrawBars(); Draw_RegisterLayout(); @@ -266,10 +271,10 @@ void DBGUI_StartUp(void) { nodelay(dbg.win_main,true); keypad(dbg.win_main,true); #ifndef WIN32 - resizeterm(50,81); + resizeterm(50,80); touchwin(dbg.win_main); - old_cursor_state = curs_set(0); #endif + old_cursor_state = curs_set(0); start_color(); cycle_count=0; MakePairs(); From b5c65f12a01d7fd56013ba67d26787a75cc6742f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 3 Jun 2008 18:35:32 +0000 Subject: [PATCH 3080/4131] better vga irq2 emulation/misc vga reg vret signalling (hal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3168 --- src/hardware/vga_crtc.cpp | 7 ++++++- src/hardware/vga_draw.cpp | 21 ++++++++++++++------- src/hardware/vga_misc.cpp | 34 +++++++++++++++++++++++----------- 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 70fce996..5b6c40d0 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_crtc.cpp,v 1.32 2008-03-30 18:02:23 qbix79 Exp $ */ +/* $Id: vga_crtc.cpp,v 1.33 2008-06-03 18:35:32 c2woody Exp $ */ #include #include "dosbox.h" @@ -220,6 +220,11 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { break; case 0x11: /* Vertical Retrace End Register */ crtc(vertical_retrace_end)=val; + + if (IS_EGAVGA_ARCH && !(val & 0x10)) { + vga.draw.vret_triggered=false; + if (GCC_UNLIKELY(machine==MCH_EGA)) PIC_DeActivateIRQ(9); + } if (IS_VGA_ARCH) crtc(read_only)=(val & 128)>0; else crtc(read_only)=false; /* diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index fd0ed78b..c745e2ce 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.100 2008-05-28 20:43:13 qbix79 Exp $ */ +/* $Id: vga_draw.cpp,v 1.101 2008-06-03 18:35:32 c2woody Exp $ */ #include #include @@ -730,6 +730,13 @@ static void INLINE VGA_ChangesStart( void ) { } #endif +static void VGA_VertInterrupt(Bitu val) { + if ((!vga.draw.vret_triggered) && ((vga.crtc.vertical_retrace_end&0x30)==0x10)) { + vga.draw.vret_triggered=true; + if (GCC_UNLIKELY(machine==MCH_EGA)) PIC_ActivateIRQ(9); + } +} + static void VGA_DisplayStartLatch(Bitu val) { vga.config.real_start=vga.config.display_start & (vga.vmemwrap-1); } @@ -750,6 +757,11 @@ static void VGA_VerticalTimer(Bitu val) { } else PIC_AddEvent( VGA_DisplayStartLatch,(float)flip_offset); PIC_AddEvent(VGA_PanningLatch,(float)vga.draw.delay.vrend); + // EGA: 82c435 datasheet: interrupt happens at display end + // VGA: checked with scope + // add a little amount of time to make sure the last drawpart has already fired + if (IS_EGAVGA_ARCH) PIC_AddEvent(VGA_VertInterrupt,(float)(vga.draw.delay.vdend + 0.005)); + if ( GCC_UNLIKELY( vga.draw.parts_left)) { if (!IS_VGA_ARCH || (svgaCard!=SVGA_None)) { LOG(LOG_VGAMISC,LOG_NORMAL)( "Parts left: %d", vga.draw.parts_left ); @@ -841,12 +853,7 @@ static void VGA_VerticalTimer(Bitu val) { #ifdef VGA_KEEP_CHANGES if (startaddr_changed) VGA_ChangesStart(); #endif - if (GCC_UNLIKELY(machine==MCH_EGA)) { - if (!(vga.crtc.vertical_retrace_end&0x20)) { - PIC_ActivateIRQ(2); - vga.draw.vret_triggered=true; - } - } + if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) PIC_AddEvent(VGA_DrawSingleLine,(float)(vga.draw.delay.htotal/4.0)); else PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts,vga.draw.parts_lines); //VGA_DrawPart( vga.draw.parts_lines ); diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index f20bbdcb..6e301705 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_misc.cpp,v 1.36 2007-12-10 22:11:13 c2woody Exp $ */ +/* $Id: vga_misc.cpp,v 1.37 2008-06-03 18:35:32 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -135,16 +135,28 @@ static Bitu read_p3c8(Bitu port,Bitu iolen) { } static Bitu read_p3c2(Bitu port,Bitu iolen) { - if (GCC_UNLIKELY(machine==MCH_EGA)) { - Bitu retcode=0x60; - retcode |= (vga.draw.vret_triggered ? 0x80 : 0x00); - vga.draw.vret_triggered=false; - // ega colour monitor - if ((((vga.misc_output>>2)&3)==0) || (((vga.misc_output>>2)&3)==3)) retcode|=0x10; - return retcode; - } else { - return 0x70; + Bit8u retval=0; + + if (machine==MCH_EGA) retval = 0x0F; + else if (IS_VGA_ARCH) retval = 0x60; + if ((machine==MCH_VGA) || (((vga.misc_output>>2)&3)==0) || (((vga.misc_output>>2)&3)==3)) { + retval |= 0x10; } + + if (vga.draw.vret_triggered) retval |= 0x80; + return retval; + /* + 0-3 0xF on EGA, 0x0 on VGA + 4 Status of the switch selected by the Miscellaneous Output + Register 3C2h bit 2-3. Switch high if set. + (apparently always 1 on VGA) + 5 (EGA) Pin 19 of the Feature Connector (FEAT0) is high if set + 6 (EGA) Pin 17 of the Feature Connector (FEAT1) is high if set + (default differs by card, ET4000 sets them both) + 7 If set IRQ 2 has happened due to Vertical Retrace. + Should be cleared by IRQ 2 interrupt routine by clearing port 3d4h + index 11h bit 4. + */ } void VGA_SetupMisc(void) { From 868ebc0ea020570154dd0b37a8da946dac9a0205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 8 Jun 2008 18:27:25 +0000 Subject: [PATCH 3081/4131] adjust line split position (fixes Supaplex) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3169 --- src/hardware/vga_draw.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index c745e2ce..9528ef46 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.101 2008-06-03 18:35:32 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.102 2008-06-08 18:27:25 c2woody Exp $ */ #include #include @@ -784,8 +784,12 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.parts_left = vga.draw.parts_total; vga.draw.lines_done = 0; vga.draw.address_line = vga.config.hlines_skip; - if (IS_EGAVGA_ARCH) vga.draw.split_line = (vga.config.line_compare/vga.draw.lines_scaled); - else vga.draw.split_line = 0x10000; // don't care + if (IS_EGAVGA_ARCH) { + vga.draw.split_line = (Bitu)((vga.config.line_compare+1)/vga.draw.lines_scaled); + if ((svgaCard==SVGA_S3Trio) && (vga.config.line_compare==0)) vga.draw.split_line=0; + } else { + vga.draw.split_line = 0x10000; // don't care + } vga.draw.address = vga.config.real_start; vga.draw.byte_panning_shift = 0; // go figure... From 95760d70df276737e45a8e4ff872f204c7edbf3d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 13 Jun 2008 08:55:04 +0000 Subject: [PATCH 3082/4131] Add destructor for multival. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3170 --- include/setup.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/setup.h b/include/setup.h index a6ce9546..a8fbffda 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.36 2008-05-30 12:42:37 qbix79 Exp $ */ +/* $Id: setup.h,v 1.37 2008-06-13 08:55:04 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -256,7 +256,7 @@ public: Prop_string* Add_string(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); P +// 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); @@ -288,6 +288,7 @@ public: const Section_prop *GetSection() const { return section; } virtual void SetValue(std::string const& input); virtual const std::vector& 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{ From 7ec342c9a9fe6d4ca3a4cc8e3202ac083cba2521 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 14 Jun 2008 19:31:04 +0000 Subject: [PATCH 3083/4131] Some warning improvements. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3171 --- src/ints/int10_char.cpp | 4 ++-- src/ints/int10_put_pixel.cpp | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 728fd04d..64d7b8be 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.53 2008-03-13 19:53:23 c2woody Exp $ */ +/* $Id: int10_char.cpp,v 1.54 2008-06-14 19:31:04 qbix79 Exp $ */ /* Character displaying moving functions */ @@ -475,7 +475,7 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt if(GCC_UNLIKELY(!useattr)) { //Set attribute(color) to a sensible value static bool warned_use = false; if(GCC_UNLIKELY(!warned_use)){ - LOG(LOG_INT10,LOG_ERROR)("writechar used without attribute in non-textmode"); + LOG(LOG_INT10,LOG_ERROR)("writechar used without attribute in non-textmode %c %X",chr,chr); warned_use = true; } switch(CurMode->type) { diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index d0c87c0e..9770c4c7 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_put_pixel.cpp,v 1.20 2008-03-13 19:53:23 c2woody Exp $ */ +/* $Id: int10_put_pixel.cpp,v 1.21 2008-06-14 19:31:04 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -25,7 +25,9 @@ static Bit8u cga_masks[4]={0x3f,0xcf,0xf3,0xfc}; static Bit8u cga_masks2[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}; + void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { + static bool putpixelwarned = false; switch (CurMode->type) { case M_CGA4: @@ -132,7 +134,10 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { break; } default: - LOG(LOG_INT10,LOG_ERROR)("PutPixel unhandled mode type %d",CurMode->type); + if(GCC_UNLIKELY(!putpixelwarned)) { + putpixelwarned = true; + LOG(LOG_INT10,LOG_ERROR)("PutPixel unhandled mode type %d",CurMode->type); + } break; } } From faa11dfa3d8ab79d8f2aec0019d22f25a8fc1320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 16 Jun 2008 20:01:25 +0000 Subject: [PATCH 3084/4131] some strange people are offended by chdir hints that are not always fully correct in all imaginable situations; removed Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3172 --- src/shell/shell_cmds.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 6dba9d7a..0673eb91 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.81 2008-02-10 11:14:03 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.82 2008-06-16 20:01:25 c2woody Exp $ */ #include "dosbox.h" #include "shell.h" @@ -281,11 +281,13 @@ void DOS_Shell::CMD_CHDIR(char * args) { *dot = 0; if(strlen(temp) > 6) temp[6] = 0; strcat(temp,"~1"); - WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_2"),temp); +// WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_2"),temp); + WriteOut(MSG_Get("SHELL_CMD_CHDIR_ERROR"),args); } else if(strlen(temp) >8) { temp[6] = 0; strcat(temp,"~1"); - WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_2"),temp); +// WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_2"),temp); + WriteOut(MSG_Get("SHELL_CMD_CHDIR_ERROR"),args); } else { Bit8u drive=DOS_GetDefaultDrive()+'A'; if (drive=='Z') { From e688408c1032192d6a487c8c0cbda45531b55d5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 29 Jun 2008 08:00:32 +0000 Subject: [PATCH 3085/4131] fix adlib key scale levels Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3173 --- src/hardware/fmopl.c | 55 +++++++++++++++++++++++------------------- src/hardware/ymf262.c | 56 +++++++++++++++++++++++-------------------- 2 files changed, 60 insertions(+), 51 deletions(-) diff --git a/src/hardware/fmopl.c b/src/hardware/fmopl.c index 9e1500a6..d29a370e 100644 --- a/src/hardware/fmopl.c +++ b/src/hardware/fmopl.c @@ -333,48 +333,54 @@ static const int slot_array[32]= static const UINT32 ksl_tab[8*16]= { /* OCT 0 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), /* OCT 1 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.750), SC(1.125), SC(1.500), - SC(1.875), SC(2.250), SC(2.625), SC(3.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.750), SC(1.125), SC(1.500), + SC(1.875), SC(2.250), SC(2.625), SC(3.000), /* OCT 2 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(1.125), SC(1.875), SC(2.625), - SC(3.000), SC(3.750), SC(4.125), SC(4.500), - SC(4.875), SC(5.250), SC(5.625), SC(6.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(1.125), SC(1.875), SC(2.625), + SC(3.000), SC(3.750), SC(4.125), SC(4.500), + SC(4.875), SC(5.250), SC(5.625), SC(6.000), /* OCT 3 */ - SC(0.000), SC(0.000), SC(0.000), SC(1.875), - SC(3.000), SC(4.125), SC(4.875), SC(5.625), - SC(6.000), SC(6.750), SC(7.125), SC(7.500), - SC(7.875), SC(8.250), SC(8.625), SC(9.000), + SC(0.000), SC(0.000), SC(0.000), SC(1.875), + SC(3.000), SC(4.125), SC(4.875), SC(5.625), + SC(6.000), SC(6.750), SC(7.125), SC(7.500), + SC(7.875), SC(8.250), SC(8.625), SC(9.000), /* OCT 4 */ - SC(0.000), SC(0.000), SC(3.000), SC(4.875), - SC(6.000), SC(7.125), SC(7.875), SC(8.625), - SC(9.000), SC(9.750),SC(10.125),SC(10.500), + SC(0.000), SC(0.000), SC(3.000), SC(4.875), + SC(6.000), SC(7.125), SC(7.875), SC(8.625), + SC(9.000), SC(9.750),SC(10.125),SC(10.500), SC(10.875),SC(11.250),SC(11.625),SC(12.000), /* OCT 5 */ - SC(0.000), SC(3.000), SC(6.000), SC(7.875), - SC(9.000),SC(10.125),SC(10.875),SC(11.625), + SC(0.000), SC(3.000), SC(6.000), SC(7.875), + SC(9.000),SC(10.125),SC(10.875),SC(11.625), SC(12.000),SC(12.750),SC(13.125),SC(13.500), SC(13.875),SC(14.250),SC(14.625),SC(15.000), /* OCT 6 */ - SC(0.000), SC(6.000), SC(9.000),SC(10.875), + SC(0.000), SC(6.000), SC(9.000),SC(10.875), SC(12.000),SC(13.125),SC(13.875),SC(14.625), SC(15.000),SC(15.750),SC(16.125),SC(16.500), SC(16.875),SC(17.250),SC(17.625),SC(18.000), /* OCT 7 */ - SC(0.000), SC(9.000),SC(12.000),SC(13.875), + SC(0.000), SC(9.000),SC(12.000),SC(13.875), SC(15.000),SC(16.125),SC(16.875),SC(17.625), SC(18.000),SC(18.750),SC(19.125),SC(19.500), SC(19.875),SC(20.250),SC(20.625),SC(21.000) }; #undef SC +/* key scale level lookup */ +static const INT32 ksl_level[4]= +{ + 31,1,2,0 +}; + /* sustain level table (3dB per step) */ /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ #define SC(db) (UINT32) ( db * (2.0/ENV_STEP) ) @@ -1394,9 +1400,8 @@ INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v) { OPL_CH *CH = &OPL->P_CH[slot/2]; OPL_SLOT *SLOT = &CH->SLOT[slot&1]; - int ksl = v>>6; /* 0 / 1.5 / 3.0 / 6.0 dB/OCT */ - SLOT->ksl = ksl ? 3-ksl : 31; + SLOT->ksl = ksl_level[(v>>6)&3]; /* 0 / 3.0 / 1.5 / 6.0 dB/OCT */ SLOT->TL = (v&0x3f)<<(ENV_BITS-1-7); /* 7 bits TL (bit 6 = always 0) */ SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); diff --git a/src/hardware/ymf262.c b/src/hardware/ymf262.c index 6e044fc6..2d9bec26 100644 --- a/src/hardware/ymf262.c +++ b/src/hardware/ymf262.c @@ -284,48 +284,54 @@ static const int slot_array[32]= static const UINT32 ksl_tab[8*16]= { /* OCT 0 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), /* OCT 1 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.750), SC(1.125), SC(1.500), - SC(1.875), SC(2.250), SC(2.625), SC(3.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.750), SC(1.125), SC(1.500), + SC(1.875), SC(2.250), SC(2.625), SC(3.000), /* OCT 2 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(1.125), SC(1.875), SC(2.625), - SC(3.000), SC(3.750), SC(4.125), SC(4.500), - SC(4.875), SC(5.250), SC(5.625), SC(6.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(1.125), SC(1.875), SC(2.625), + SC(3.000), SC(3.750), SC(4.125), SC(4.500), + SC(4.875), SC(5.250), SC(5.625), SC(6.000), /* OCT 3 */ - SC(0.000), SC(0.000), SC(0.000), SC(1.875), - SC(3.000), SC(4.125), SC(4.875), SC(5.625), - SC(6.000), SC(6.750), SC(7.125), SC(7.500), - SC(7.875), SC(8.250), SC(8.625), SC(9.000), + SC(0.000), SC(0.000), SC(0.000), SC(1.875), + SC(3.000), SC(4.125), SC(4.875), SC(5.625), + SC(6.000), SC(6.750), SC(7.125), SC(7.500), + SC(7.875), SC(8.250), SC(8.625), SC(9.000), /* OCT 4 */ - SC(0.000), SC(0.000), SC(3.000), SC(4.875), - SC(6.000), SC(7.125), SC(7.875), SC(8.625), - SC(9.000), SC(9.750),SC(10.125),SC(10.500), + SC(0.000), SC(0.000), SC(3.000), SC(4.875), + SC(6.000), SC(7.125), SC(7.875), SC(8.625), + SC(9.000), SC(9.750),SC(10.125),SC(10.500), SC(10.875),SC(11.250),SC(11.625),SC(12.000), /* OCT 5 */ - SC(0.000), SC(3.000), SC(6.000), SC(7.875), - SC(9.000),SC(10.125),SC(10.875),SC(11.625), + SC(0.000), SC(3.000), SC(6.000), SC(7.875), + SC(9.000),SC(10.125),SC(10.875),SC(11.625), SC(12.000),SC(12.750),SC(13.125),SC(13.500), SC(13.875),SC(14.250),SC(14.625),SC(15.000), /* OCT 6 */ - SC(0.000), SC(6.000), SC(9.000),SC(10.875), + SC(0.000), SC(6.000), SC(9.000),SC(10.875), SC(12.000),SC(13.125),SC(13.875),SC(14.625), SC(15.000),SC(15.750),SC(16.125),SC(16.500), SC(16.875),SC(17.250),SC(17.625),SC(18.000), /* OCT 7 */ - SC(0.000), SC(9.000),SC(12.000),SC(13.875), + SC(0.000), SC(9.000),SC(12.000),SC(13.875), SC(15.000),SC(16.125),SC(16.875),SC(17.625), SC(18.000),SC(18.750),SC(19.125),SC(19.500), SC(19.875),SC(20.250),SC(20.625),SC(21.000) }; #undef SC +/* key scale level lookup */ +static const INT32 ksl_level[4]= +{ + 31,1,2,0 +}; + /* sustain level table (3dB per step) */ /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ #define SC(db) (UINT32) ( db * (2.0/ENV_STEP) ) @@ -1494,9 +1500,7 @@ INLINE void set_ksl_tl(OPL3 *chip,int slot,int v) OPL3_CH *CH = &chip->P_CH[slot/2]; OPL3_SLOT *SLOT = &CH->SLOT[slot&1]; - int ksl = v>>6; /* 0 / 1.5 / 3.0 / 6.0 dB/OCT */ - - SLOT->ksl = ksl ? 3-ksl : 31; + SLOT->ksl = ksl_level[(v>>6)&3]; /* 0 / 3.0 / 1.5 / 6.0 dB/OCT */ SLOT->TL = (v&0x3f)<<(ENV_BITS-1-7); /* 7 bits TL (bit 6 = always 0) */ if (chip->OPL3_mode & 1) From d204f38ea5904a4e549fdc9d0b5802ea5d734ccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 30 Jun 2008 20:32:37 +0000 Subject: [PATCH 3086/4131] support non-standard additional keyboard layouts Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3174 --- src/dos/dos_keyboard_layout.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 47cf8f72..e8487b76 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_keyboard_layout.cpp,v 1.11 2008-01-17 18:53:18 c2woody Exp $ */ +/* $Id: dos_keyboard_layout.cpp,v 1.12 2008-06-30 20:32:37 c2woody Exp $ */ #include "dosbox.h" #include "bios.h" @@ -209,6 +209,7 @@ static Bit32u read_kcl_data(Bit8u * kcl_data, Bit32u kcl_data_size, const char* char lng_codes[258]; // get all language codes for this layout for (Bitu i=0; i Date: Fri, 4 Jul 2008 19:15:53 +0000 Subject: [PATCH 3087/4131] fix opl3 4op connection mode selection Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3175 --- src/hardware/ymf262.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/ymf262.c b/src/hardware/ymf262.c index 2d9bec26..1c297432 100644 --- a/src/hardware/ymf262.c +++ b/src/hardware/ymf262.c @@ -2103,7 +2103,7 @@ static void OPL3WriteReg(OPL3 *chip, int r, int v) case 9: case 10: case 11: if (CH->extended) { - UINT8 conn = (CH->SLOT[SLOT1].CON<<1) || ((CH+3)->SLOT[SLOT1].CON<<0); + UINT8 conn = (CH->SLOT[SLOT1].CON<<1) | ((CH+3)->SLOT[SLOT1].CON<<0); switch(conn) { case 0: @@ -2155,7 +2155,7 @@ static void OPL3WriteReg(OPL3 *chip, int r, int v) case 12: case 13: case 14: if ((CH-3)->extended) { - UINT8 conn = ((CH-3)->SLOT[SLOT1].CON<<1) || (CH->SLOT[SLOT1].CON<<0); + UINT8 conn = ((CH-3)->SLOT[SLOT1].CON<<1) | (CH->SLOT[SLOT1].CON<<0); switch(conn) { case 0: From c8b4ac03a8b6440c5403033428e0938094c6567b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 5 Jul 2008 08:54:59 +0000 Subject: [PATCH 3088/4131] disable 0xff escaping for transparent nullmodem mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3176 --- src/hardware/serialport/nullmodem.cpp | 29 +++++++++++++++------------ 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/hardware/serialport/nullmodem.cpp b/src/hardware/serialport/nullmodem.cpp index f0853c17..2c017460 100644 --- a/src/hardware/serialport/nullmodem.cpp +++ b/src/hardware/serialport/nullmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: nullmodem.cpp,v 1.4 2008-07-05 08:54:59 c2woody Exp $ */ + #include "dosbox.h" #if C_MODEM @@ -139,13 +141,13 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) { if(cmd->FindStringBegin("server:",tmpstring,false)) { // we are a client const char* hostnamechar=tmpstring.c_str(); - Bitu hostlen=strlen(hostnamechar)+1; + size_t hostlen=strlen(hostnamechar)+1; if(hostlen>sizeof(hostnamebuffer)) { hostlen=sizeof(hostnamebuffer); hostnamebuffer[sizeof(hostnamebuffer)-1]=0; } memcpy(hostnamebuffer,hostnamechar,hostlen); - clientport=temptcpport; + clientport=(Bit16u)temptcpport; if(dtrrespect) { // we connect as soon as DTR is switched on setEvent(SERIAL_NULLMODEM_DTR_EVENT, 50); @@ -176,9 +178,10 @@ CNullModem::~CNullModem () { if(serversocket) delete serversocket; if(clientsocket) delete clientsocket; // remove events - for(Bitu i = SERIAL_BASE_EVENT_COUNT+1; - i <= SERIAL_NULLMODEM_EVENT_COUNT; i++) + for(Bit16u i = SERIAL_BASE_EVENT_COUNT+1; + i <= SERIAL_NULLMODEM_EVENT_COUNT; i++) { removeEvent(i); + } } void CNullModem::WriteChar(Bit8u data) { @@ -194,7 +197,7 @@ void CNullModem::WriteChar(Bit8u data) { Bits CNullModem::readChar() { Bits rxchar = clientsocket->GetcharNonBlock(); - if(telnet && rxchar>=0) return TelnetEmulation(rxchar); + if(telnet && rxchar>=0) return TelnetEmulation((Bit8u)rxchar); else if(rxchar==0xff && !transparent) {// escape char // get the next char Bits rxchar = clientsocket->GetcharNonBlock(); @@ -300,7 +303,8 @@ void CNullModem::handleUpperEvent(Bit16u type) { case SERIAL_SERVER_POLLING_EVENT: { // As long as nothing is connected to out server poll the // connection. - if((clientsocket=serversocket->Accept())) { + clientsocket=serversocket->Accept(); + if(clientsocket) { Bit8u peeripbuf[16]; clientsocket->GetRemoteAddressString(peeripbuf); LOG_MSG("Serial%d: A client (%s) has connected.",idnumber+1,peeripbuf); @@ -338,7 +342,7 @@ void CNullModem::handleUpperEvent(Bit16u type) { /* updatePortConfig is called when emulated app changes the serial port **/ /* parameters baudrate, stopbits, number of databits, parity. **/ /*****************************************************************************/ -void CNullModem::updatePortConfig (Bit16u divider, Bit8u lcr) { +void CNullModem::updatePortConfig (Bit16u /*divider*/, Bit8u /*lcr*/) { } @@ -351,13 +355,12 @@ void CNullModem::transmitByte (Bit8u val, bool first) { // transmit it later in THR_Event if(first) { setEvent(SERIAL_THR_EVENT, bytetime/8); - } - else { + } else { //if(clientsocket) clientsocket->Putchar(val); setEvent(SERIAL_TX_EVENT, bytetime); } - /*****************************/ - if(val==0xff) WriteChar(0xff); + // disable 0xff escaping when transparent mode is enabled + if (!transparent && (val==0xff)) WriteChar(0xff); WriteChar(val); } @@ -471,7 +474,7 @@ Bits CNullModem::TelnetEmulation(Bit8u data) { /* setBreak(val) switches break on or off **/ /*****************************************************************************/ -void CNullModem::setBreak (bool value) { +void CNullModem::setBreak (bool /*value*/) { CNullModem::setRTSDTR(getRTS(), getDTR()); } From bc593183b6f66ce8fd33beffbebfbc220ca9e1fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 13 Jul 2008 09:51:04 +0000 Subject: [PATCH 3089/4131] fix opl additional time counter status bit setting for the second timer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3177 --- src/hardware/fmopl.c | 4 +++- src/hardware/ymf262.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hardware/fmopl.c b/src/hardware/fmopl.c index d29a370e..2d7ff38e 100644 --- a/src/hardware/fmopl.c +++ b/src/hardware/fmopl.c @@ -1922,6 +1922,7 @@ static unsigned char OPLRead(FM_OPL *OPL,int a) #endif if (OPL->st[0]) { + /* Timer A */ if (OPL->TC[0]) OPL->TC[0]--; else { OPL->TC[0]=OPL->T[0]*20; @@ -1929,10 +1930,11 @@ static unsigned char OPLRead(FM_OPL *OPL,int a) } } if (OPL->st[1]) { + /* Timer B */ if (OPL->TC[1]) OPL->TC[1]--; else { OPL->TC[1]=OPL->T[1]*20; - OPL_STATUS_SET(OPL,0x40); + OPL_STATUS_SET(OPL,0x20); } } return OPL->status & (OPL->statusmask|0x80); diff --git a/src/hardware/ymf262.c b/src/hardware/ymf262.c index 1c297432..992d832b 100644 --- a/src/hardware/ymf262.c +++ b/src/hardware/ymf262.c @@ -2446,6 +2446,7 @@ static unsigned char OPL3Read(OPL3 *chip,int a) if( a==0 ) { if (chip->st[0]) { + /* Timer A */ if (chip->TC[0]) chip->TC[0]--; else { chip->TC[0]=chip->T[0]*20; @@ -2453,10 +2454,11 @@ static unsigned char OPL3Read(OPL3 *chip,int a) } } if (chip->st[1]) { + /* Timer B */ if (chip->TC[1]) chip->TC[1]--; else { chip->TC[1]=chip->T[1]*20; - OPL3_STATUS_SET(chip,0x40); + OPL3_STATUS_SET(chip,0x20); } } return chip->status; From 1ff3aed302c5ad1c555a20e9830c8e28ad749aa0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2008 19:07:04 +0000 Subject: [PATCH 3090/4131] New DRO Capturing Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3178 --- src/hardware/adlib.cpp | 430 ++++++++++++++++++++++++++--------------- 1 file changed, 273 insertions(+), 157 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 113039b4..0c5db85a 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -37,6 +37,255 @@ #define logerror + +#ifdef _MSC_VER +#pragma pack (1) +#endif + +#define HW_OPL2 0 +#define HW_DUALOPL2 1 +#define HW_OPL3 2 + +struct RawHeader { + Bit8u id[8]; /* 0x00, "DBRAWOPL" */ + Bit16u versionHigh; /* 0x08, size of the data following the m */ + Bit16u versionLow; /* 0x0a, size of the data following the m */ + Bit32u commands; /* 0x0c, Bit32u amount of command/data pairs */ + Bit32u milliseconds; /* 0x10, Bit32u Total milliseconds of data in this chunk */ + Bit8u hardware; /* 0x14, Bit8u Hardware Type 0=opl2,1=dual-opl2,2=opl3 */ + Bit8u format; /* 0x15, Bit8u Format 0=cmd/data interleaved, 1 maybe all cdms, followed by all data */ + Bit8u compression; /* 0x16, Bit8u Compression Type, 0 = No Compression */ + Bit8u delay256; /* 0x17, Bit8u Delay 1-256 msec command */ + Bit8u delayShift8; /* 0x18, Bit8u (delay + 1)*256 */ + Bit8u conversionTableSize; /* 0x191, Bit8u Raw Conversion Table size */ +} GCC_ATTRIBUTE(packed); +#ifdef _MSC_VER +#pragma pack() +#endif +/* + The Raw Tables is < 128 and is used to convert raw commands into a full register index + When the high bit of a raw command is set it indicates the cmd/data pair is to be sent to the 2nd port + After the conversion table the raw data follows immediatly till the end of the chunk +*/ + +typedef Bit8u RawCache[2][256]; + + +//Table to map the opl register to one <127 for dro saving +class RawCapture { + //127 entries to go from raw data to registers + Bit8u ToReg[127]; + //How many entries in the ToPort are used + Bit8u RawUsed; + //256 entries to go from port index to raw data + Bit8u ToRaw[256]; + Bit8u delay256; + Bit8u delayShift8; + RawHeader header; + + FILE* handle; //File used for writing + Bit32u startTicks; //Start used to check total raw length on end + Bit32u lastTicks; //Last ticks when last last cmd was added + Bit8u buf[1024]; //16 added for delay commands and what not + Bit32u bufUsed; + Bit8u cmd[2]; //Last cmd's sent to either ports + bool doneOpl3; + bool doneDualOpl2; + + RawCache* cache; + + void MakeEntry( Bit8u reg, Bit8u& raw ) { + ToReg[ raw ] = reg; + ToRaw[ reg ] = raw; + raw++; + } + void MakeTables( void ) { + Bit8u index = 0; + memset( ToReg, 0xff, sizeof ( ToReg ) ); + memset( ToRaw, 0xff, sizeof ( ToRaw ) ); + //Select the entries that are valid and the index is the mapping to the index entry + MakeEntry( 0x01, index ); //0x01: Waveform select + MakeEntry( 0x04, index ); //104: Four-Operator Enable + MakeEntry( 0x05, index ); //105: OPL3 Mode Enable + MakeEntry( 0x08, index ); //08: CSW / NOTE-SEL + MakeEntry( 0xbd, index ); //BD: Tremolo Depth / Vibrato Depth / Percussion Mode / BD/SD/TT/CY/HH On + //Add the 32 byte range that hold the 18 operators + for ( int i = 0 ; i < 24; i++ ) { + if ( (i & 7) < 6 ) { + MakeEntry(0x20 + i, index ); //20-35: Tremolo / Vibrato / Sustain / KSR / Frequency Multiplication Facto + MakeEntry(0x40 + i, index ); //40-55: Key Scale Level / Output Level + MakeEntry(0x60 + i, index ); //60-75: Attack Rate / Decay Rate + MakeEntry(0x80 + i, index ); //80-95: Sustain Level / Release Rate + MakeEntry(0xe0 + i, index ); //E0-F5: Waveform Select + } + } + //Add the 9 byte range that hold the 9 channels + for ( int i = 0 ; i < 9; i++ ) { + MakeEntry(0xa0 + i, index ); //A0-A8: Frequency Number + MakeEntry(0xb0 + i, index ); //B0-B8: Key On / Block Number / F-Number(hi bits) + MakeEntry(0xc0 + i, index ); //C0-C8: FeedBack Modulation Factor / Synthesis Type + } + //Store the amount of bytes the table contains + RawUsed = index; +// assert( RawUsed <= 127 ); + delay256 = RawUsed; + delayShift8 = RawUsed+1; + } + + void ClearBuf( void ) { + fwrite( buf, 1, bufUsed, handle ); + header.commands += bufUsed / 2; + bufUsed = 0; + } + void AddBuf( Bit8u raw, Bit8u val ) { + buf[bufUsed++] = raw; + buf[bufUsed++] = val; + if ( bufUsed >= sizeof( buf ) ) { + ClearBuf(); + } + } + void AddWrite( Bit8u index, Bit8u reg, Bit8u val ) { + /* + Do some special checks if we're doing opl3 or dualopl2 commands + Although you could pretty much just stick to always doing opl3 on the player side + */ + if ( index ) { + //opl3 enabling will always override dual opl + if ( header.hardware != HW_OPL3 && reg == 4 && val && (*cache)[1][5] ) { + header.hardware = HW_OPL3; + } + if ( header.hardware == HW_OPL2 && reg >= 0xb0 && reg <=0xb8 && val ) { + header.hardware = HW_DUALOPL2; + } + } + Bit8u raw = ToRaw[reg]; + if ( raw == 0xff ) + return; + if ( index ) + raw |= 128; + AddBuf( raw, val ); + } + void WriteCache( void ) { + Bitu i, val; + /* Check the registers to add */ + for (i=0;i<256;i++) { + //Skip the note on entries + if (i>=0xb0 && i<=0xb8) + continue; + val = (*cache)[0][i]; + if (val) { + AddWrite( 0, i, val ); + } + val = (*cache)[1][i]; + if (val) { + AddWrite( 1, i, val ); + } + } + } + void InitHeader( void ) { + memset( &header, 0, sizeof( header ) ); + memcpy( header.id, "DBRAWOPL", 8 ); + header.versionLow = 0; + header.versionHigh = 2; + header.delay256 = delay256; + header.delayShift8 = delayShift8; + header.conversionTableSize = RawUsed; + } + void CloseFile( void ) { + if ( handle ) { + ClearBuf(); + /* Endianize the header and write it to beginning of the file */ + var_write( &header.versionHigh, header.versionHigh ); + var_write( &header.versionLow, header.versionLow ); + var_write( &header.commands, header.commands ); + var_write( &header.milliseconds, header.milliseconds ); + fseek( handle, 0, SEEK_SET ); + fwrite( &header, 1, sizeof( header ), handle ); + fclose( handle ); + handle = 0; + } + } +public: + bool DoWrite( Bit8u index, Bit8u reg, Bit8u val ) { + //Check the raw index for this register if we actually have to save it + if ( handle ) { + /* + Check if we actually care for this to be logged, else just ignore it + */ + Bit8u raw = ToRaw[reg]; + if ( raw == 0xff ) { + return true; + } + /* Check if this command will not just replace the same value + in a reg that doesn't do anything with it + */ + if ( (*cache)[index][reg] == val ) + return true; + /* Check how much time has passed */ + Bitu passed = PIC_Ticks - lastTicks; + lastTicks = PIC_Ticks; + header.milliseconds += passed; + + //if ( passed > 0 ) LOG_MSG( "Delay %d", passed ) ; + + // If we passed more than 30 seconds since the last command, we'll restart the the capture + if ( passed > 30000 ) { + CloseFile(); + goto skipWrite; + } + while (passed > 0) { + if (passed < 257) { //1-256 millisecond delay + AddBuf( delay256, passed - 1 ); + passed = 0; + } else { + Bitu shift = (passed >> 8); + passed -= shift << 8; + AddBuf( delayShift8, shift - 1 ); + } + } + AddWrite( index, reg, val ); + return true; + } +skipWrite: + //Not yet capturing to a file here + //Check for commands that would start capturing, if it's not one of them return + if ( !( + //note on in any channel + ( reg>=0xb0 && reg<=0xb8 && (val&0x020) ) || + //Percussion mode enabled and a note on in any percussion instrument + ( reg == 0xbd && ( (val&0x3f) > 0x20 ) ) + )) { + return true; + } + handle = OpenCaptureFile("Raw Opl",".dro"); + if (!handle) + return false; + InitHeader(); + //Prepare space at start of the file for the header + fwrite( &header, 1, sizeof(header), handle ); + /* write the Raw To Reg table */ + fwrite( &ToReg, 1, RawUsed, handle ); + /* Write the cache of last commands */ + WriteCache( ); + /* Write the command that triggered this */ + AddWrite( index, reg, val ); + //Init the timing information for the next commands + lastTicks = PIC_Ticks; + startTicks = PIC_Ticks; + return true; + } + RawCapture( RawCache* _cache ) { + cache = _cache; + handle = 0; + bufUsed = 0; + MakeTables(); + } + ~RawCapture() { + CloseFile(); + } + +}; + #ifdef _MSC_VER /* Disable recurring warnings */ # pragma warning ( disable : 4018 ) @@ -87,22 +336,11 @@ static struct { bool active; OPL_Mode mode; MixerChannel * chan; - Bit32u last_used; - Bit16s mixbuf[2][128]; - struct { - FILE * handle; - bool capturing; - Bit32u start; - Bit32u last; - Bit8u index; - Bit8u buffer[RAW_SIZE+8]; - Bit8u regs[2][256]; - Bit32u used; - Bit32u done; - Bit8u cmd[2]; - bool opl3; - bool dualopl2; - } raw; + Bit32u last_used; //Ticks when adlib was last used to turn of mixing after a few second + Bit16s mixbuf[2][128]; //Mix buffer to mix dual opl2 into final stream + Bit8u cmd[2]; //Last cmd written to either index + RawCache cache; + RawCapture* raw; } opl; static void OPL_CallBack(Bitu len) { @@ -146,7 +384,6 @@ static Bitu OPL_Read(Bitu port,Bitu iolen) { return 0xff; } -static void OPL_RawAdd(Bitu index,Bitu val); void OPL_Write(Bitu port,Bitu val,Bitu iolen) { opl.last_used=PIC_Ticks; if (!opl.active) { @@ -154,12 +391,16 @@ void OPL_Write(Bitu port,Bitu val,Bitu iolen) { opl.chan->Enable(true); } port&=3; - if (port&1) { - Bitu index=port>>1; - opl.raw.regs[index][opl.raw.cmd[index]]=val; - if (opl.raw.capturing) OPL_RawAdd(index,val); - } else opl.raw.cmd[port>>1]=val; - if (!port) adlib_commandreg=val; + Bitu index = port>>1; + if ( port&1 ) { + Bit8u cmd = opl.cmd[index]; + if ( opl.raw ) + opl.raw->DoWrite( index, cmd, val ); + //Write to the cache after, so the raw can check for unchanged values + opl.cache[index][cmd]=val; + } else { + opl.cmd[ index ] = val; + } switch (opl.mode) { case OPL_opl2: OPL2::YM3812Write(0,port,val); @@ -168,149 +409,22 @@ void OPL_Write(Bitu port,Bitu val,Bitu iolen) { THEOPL3::YMF262Write(0,port,val); break; case OPL_dualopl2: - OPL2::YM3812Write(port>>1,port,val); + OPL2::YM3812Write( index,port,val); break; } } -static Bit8u dro_header[]={ - 'D','B','R','A', /* 0x00, Bit32u ID */ - 'W','O','P','L', /* 0x04, Bit32u ID */ - 0x0,0x00, /* 0x08, Bit16u version low */ - 0x1,0x00, /* 0x09, Bit16u version high */ - 0x0,0x0,0x0,0x0, /* 0x0c, Bit32u total milliseconds */ - 0x0,0x0,0x0,0x0, /* 0x10, Bit32u total data */ - 0x0,0x0,0x0,0x0 /* 0x14, Bit32u Type 0=opl2,1=opl3,2=dual-opl2 */ -}; -/* Commands - 0x00 Bit8u, millisecond delay+1 - 0x02 none, Use the low index/data pair - 0x03 none, Use the high index/data pair - 0x10 Bit16u, millisecond delay+1 - 0xxx Bit8u, send command and data to current index/data pair -*/ - -static void OPL_RawEmptyBuffer(void) { - fwrite(opl.raw.buffer,1,opl.raw.used,opl.raw.handle); - opl.raw.done+=opl.raw.used; - opl.raw.used=0; -} - -#define ADDBUF(_VAL_) opl.raw.buffer[opl.raw.used++]=_VAL_; -static void OPL_RawAdd(Bitu index,Bitu val) { - Bit8u cmd=opl.raw.cmd[index]; - /* check for cmd's we use for special meaning - These only control timers or are unused - */ - if (cmd == 2 || cmd == 3 || cmd == 0x10) return; - if (cmd == 4 && !index) return; - /* Check if we have yet to start */ - if (!opl.raw.handle) { - if (cmd<0xb0 || cmd>0xb8) return; - if (!(val&0x20)) return; - Bitu i; - opl.raw.last=PIC_Ticks; - opl.raw.start=PIC_Ticks; - opl.raw.handle=OpenCaptureFile("Raw Opl",".dro"); - if (!opl.raw.handle) { - opl.raw.capturing=false; - return; - } - memset(opl.raw.buffer,0,sizeof(opl.raw.buffer)); - fwrite(dro_header,1,sizeof(dro_header),opl.raw.handle); - /* Check the registers to add */ - for (i=0;i<256;i++) { - if (!opl.raw.regs[0][i]) continue; - if (i>=0xb0 && i<=0xb8) continue; - ADDBUF((Bit8u)i); - ADDBUF(opl.raw.regs[0][i]); - } - bool donesecond=false; - /* Check if we already have an opl3 enable bit logged */ - if (opl.raw.regs[1][5] & 1) - opl.raw.opl3 = true; - for (i=0;i<256;i++) { - if (!opl.raw.regs[1][i]) continue; - if (i>=0xb0 && i<=0xb8) continue; - if (!donesecond) { - /* Or already have dual opl2 */ - opl.raw.dualopl2 = true; - donesecond=true; - ADDBUF(0x3); - } - ADDBUF((Bit8u)i); - ADDBUF(opl.raw.regs[1][i]); - } - if (donesecond) ADDBUF(0x2); - } - /* Check if we enable opl3 or access dual opl2 mode */ - if (cmd == 5 && index && (val & 1)) { - opl.raw.opl3 = true; - } - if (index && val && cmd>=0xb0 && cmd<=0xb8) { - opl.raw.dualopl2 = true; - } - /* Check how much time has passed, Allow an extra 5 milliseconds? */ - if (PIC_Ticks>(opl.raw.last+5)) { - Bitu passed=PIC_Ticks-opl.raw.last; - opl.raw.last=PIC_Ticks; - while (passed) { - passed-=1; - if (passed<256) { - ADDBUF(0x00); //8bit delay - ADDBUF((Bit8u)passed); //8bit delay - passed=0; - } else if (passed<0x10000) { - ADDBUF(0x01); //16bit delay - ADDBUF((Bit8u)(passed & 0xff)); //lo-byte - ADDBUF((Bit8u)(passed >> 8)); //hi-byte - passed=0; - } else { - ADDBUF(0x01); //16bit delay - ADDBUF(0xff); //lo-byte - ADDBUF(0xff); //hi-byte - passed-=0xffff; - } - } - } - /* Check if we're still sending to the correct index */ - if (opl.raw.index != index) { - opl.raw.index=index; - ADDBUF(opl.raw.index ? 0x3 : 0x2); - } - ADDBUF(cmd); - ADDBUF(val); - if (opl.raw.used>=RAW_SIZE) OPL_RawEmptyBuffer(); -} - static void OPL_SaveRawEvent(bool pressed) { if (!pressed) return; /* Check for previously opened wave file */ - if (opl.raw.handle) { - OPL_RawEmptyBuffer(); - /* Fill in the header with useful information */ - host_writed(&dro_header[0x0c],opl.raw.last-opl.raw.start); - host_writed(&dro_header[0x10],opl.raw.done); - if (opl.raw.opl3 && opl.raw.dualopl2) host_writed(&dro_header[0x14],0x1); - else if (opl.raw.dualopl2) host_writed(&dro_header[0x14],0x2); - else host_writed(&dro_header[0x14],0x0); - fseek(opl.raw.handle,0,0); - fwrite(dro_header,1,sizeof(dro_header),opl.raw.handle); - fclose(opl.raw.handle); - opl.raw.handle=0; - } - if (opl.raw.capturing) { - opl.raw.capturing=false; - LOG_MSG("Stopping Raw OPL capturing."); + if ( opl.raw ) { + delete opl.raw; + opl.raw = 0; + LOG_MSG("Stopped Raw OPL capturing."); } else { LOG_MSG("Preparing to capture Raw OPL, will start with first note played."); - opl.raw.capturing=true; - opl.raw.index=0; - opl.raw.used=0; - opl.raw.done=0; - opl.raw.start=0; - opl.raw.last=0; + opl.raw = new RawCapture( &opl.cache ); } } @@ -345,6 +459,7 @@ public: WriteHandler[2].Install(base+8,OPL_Write,IO_MB,2); ReadHandler[2].Install(base+8,OPL_Read,IO_MB,2); + opl.raw = 0; opl.active=false; opl.last_used=0; opl.mode=oplmode; @@ -353,7 +468,8 @@ public: MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL"); } ~OPL() { - if (opl.raw.handle) OPL_SaveRawEvent(true); + if (opl.raw) + delete opl.raw; OPL2::YM3812Shutdown(); THEOPL3::YMF262Shutdown(); } From 92dade7e5b115811fd2832dc2b5e6583079aee88 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 14 Jul 2008 19:30:29 +0000 Subject: [PATCH 3091/4131] Show a few more digits. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3179 --- src/hardware/timer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 22f0bd90..999a39d0 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.46 2008-03-02 08:55:04 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.47 2008-07-14 19:30:29 qbix79 Exp $ */ #include #include "dosbox.h" @@ -220,7 +220,7 @@ static void write_latch(Bitu port,Bitu val,Bitu /*iolen*/) { if(p->mode==0) PIC_RemoveEvents(PIT0_Event); // DoWhackaDo demo PIC_AddEvent(PIT0_Event,p->delay); } else LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer set without new control word"); - LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.2f Hz mode %d",1000.0/p->delay,p->mode); + LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.4f Hz mode %d",1000.0/p->delay,p->mode); break; case 0x02: /* Timer hooked to PC-Speaker */ // LOG(LOG_PIT,"PIT 2 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode); From d04432186474fd29f8c3ac3a846bc9592ce20882 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 14 Jul 2008 19:39:10 +0000 Subject: [PATCH 3092/4131] Add disney changes from h-a-l-9000 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3180 --- src/hardware/disney.cpp | 292 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 266 insertions(+), 26 deletions(-) diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 896faa5b..7e8a19a3 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: disney.cpp,v 1.16 2008-07-14 19:39:10 qbix79 Exp $ */ + #include #include "dosbox.h" #include "inout.h" @@ -25,33 +27,209 @@ #define DISNEY_BASE 0x0378 -#define DISNEY_SIZE 32 +#define DISNEY_SIZE 128 + +typedef struct _dac_channel { + Bit8u buffer[DISNEY_SIZE]; // data buffer + Bitu used; // current data buffer level + double speedcheck_sum; + double speedcheck_last; + bool speedcheck_failed; + bool speedcheck_init; +} dac_channel; static struct { + // parallel port stuff Bit8u data; Bit8u status; Bit8u control; - Bit8u buffer[DISNEY_SIZE]; - Bitu used;Bitu last_used; + // the D/A channels + dac_channel da[2]; + + Bitu last_used; + MixerObject * mo; MixerChannel * chan; + bool stereo; + // which channel do we use for mono output? + // and the channel used for stereo + dac_channel* leader; + + Bitu state; + Bitu interface_det; } disney; -static void disney_write(Bitu port,Bitu val,Bitu iolen) { - if (!disney.last_used) { - disney.chan->Enable(true); +#define DS_IDLE 0 +#define DS_RUNNING 1 +#define DS_FINISH 2 +#define DS_ANALYZING 3 + +static void DISNEY_CallBack(Bitu len); + +static void DISNEY_disable(Bitu) { + if(disney.mo) { + disney.chan->AddSilence(); + disney.chan->Enable(false); + delete disney.mo; } + disney.interface_det = 0; + disney.leader = 0; + disney.last_used = 0; + disney.mo = 0; + disney.state = DS_IDLE; + disney.interface_det = 0; +} + +static void DISNEY_enable(Bitu freq) { + if(freq < 500 || freq > 100000) { + // try again.. + disney.state = DS_IDLE; + return; + } else { +#if 0 + if(disney.stereo) LOG(LOG_MISC,LOG_NORMAL)("disney enable %d Hz, stereo",freq); + else LOG(LOG_MISC,LOG_NORMAL)("disney enable %d Hz, mono",freq); +#endif + disney.mo = new MixerObject(); + disney.chan=disney.mo->Install(&DISNEY_CallBack,freq,"DISNEY"); + disney.chan->Enable(true); + disney.state = DS_RUNNING; + } +} + +static void DISNEY_analyze(Bitu channel){ + switch(disney.state) { + case DS_RUNNING: // should not get here + break; + case DS_IDLE: + // initialize channel data + for(int i = 0; i < 2; i++) { + disney.da[i].used = 0; + disney.da[i].speedcheck_sum = 0; + disney.da[i].speedcheck_failed = false; + disney.da[i].speedcheck_init = false; + } + disney.da[channel].speedcheck_last = PIC_FullIndex(); + disney.da[channel].speedcheck_init = true; + + disney.state = DS_ANALYZING; + break; + + case DS_FINISH: + { + // detect stereo: if we have about the same data amount in both channels + Bits st_diff = disney.da[0].used - disney.da[1].used; + + // find leader channel (the one with higher rate) [this good for the stereo case?] + if(disney.da[0].used > disney.da[1].used) { + //disney.monochannel=0; + disney.leader = &disney.da[0]; + } else { + //disney.monochannel=1; + disney.leader = &disney.da[1]; + } + + if((st_diff < 5) && (st_diff > -5)) disney.stereo = true; + else disney.stereo = false; + + // calculate rate for both channels + Bitu ch_speed[2]; + + for(Bitu i = 0; i < 2; i++) { + ch_speed[i] = (Bitu)(1.0/((disney.da[i].speedcheck_sum/1000.0) / + (float)(((float)disney.da[i].used)-1.0))); // -1.75 + } + + // choose the larger value + DISNEY_enable(ch_speed[0] > ch_speed[1]? + ch_speed[0]:ch_speed[1]); // TODO + break; + } + case DS_ANALYZING: + { + double current = PIC_FullIndex(); + dac_channel* cch = &disney.da[channel]; + + if(!cch->speedcheck_init) { + cch->speedcheck_init = true; + cch->speedcheck_last = current; + break; + } + cch->speedcheck_sum += current - cch->speedcheck_last; + //LOG_MSG("t=%f",current - cch->speedcheck_last); + + // sanity checks (printer...) + if((current - cch-> speedcheck_last) < 0.01 || + (current - cch-> speedcheck_last) > 2) + cch->speedcheck_failed = true; + + // if both are failed we are back at start + if(disney.da[0].speedcheck_failed && disney.da[1].speedcheck_failed) { + disney.state=DS_IDLE; + break; + } + + cch->speedcheck_last = current; + + // analyze finish condition + if(disney.da[0].used > 30 || disney.da[1].used > 30) + disney.state = DS_FINISH; + break; + } + } +} + +static void disney_write(Bitu port,Bitu val,Bitu iolen) { + //LOG_MSG("write disney time %f addr%x val %x",PIC_FullIndex(),port,val); disney.last_used=PIC_Ticks; switch (port-DISNEY_BASE) { case 0: /* Data Port */ + { disney.data=val; - if (disney.used 5) + DISNEY_analyze(0); + } + if(disney.interface_det > 5) { + if(disney.da[0].used < DISNEY_SIZE) { + disney.da[0].buffer[disney.da[0].used] = disney.data; + disney.da[0].used++; + } //else LOG_MSG("disney overflow 0"); + + } break; + } case 1: /* Status Port */ LOG(LOG_MISC,LOG_NORMAL)("DISNEY:Status write %x",val); break; case 2: /* Control Port */ + if((disney.control & 0x2) && !(val & 0x2)) { + if(disney.state != DS_RUNNING) { + disney.interface_det = 0; + DISNEY_analyze(1); + } + + // stereo channel latch + if(disney.da[1].used < DISNEY_SIZE) { + disney.da[1].buffer[disney.da[1].used] = disney.data; + disney.da[1].used++; + } //else LOG_MSG("disney overflow 1"); + } + + if((disney.control & 0x1) && !(val & 0x1)) { + if(disney.state != DS_RUNNING) { + disney.interface_det = 0; + DISNEY_analyze(0); + } + // stereo channel latch + if(disney.da[0].used < DISNEY_SIZE) { + disney.da[0].buffer[disney.da[0].used] = disney.data; + disney.da[0].used++; + } //else LOG_MSG("disney overflow 0"); + } + // LOG_WARN("DISNEY:Control write %x",val); if (val&0x10) LOG(LOG_MISC,LOG_ERROR)("DISNEY:Parallel IRQ Enabled"); disney.control=val; @@ -67,7 +245,9 @@ static Bitu disney_read(Bitu port,Bitu iolen) { break; case 1: /* Status Port */ // LOG(LOG_MISC,"DISNEY:Read from status port %X",disney.status); - if (disney.used>=16) return 0x40; + if (disney.leader && disney.leader->used >= 16) return 0x40; + /* Stereo-on-1 and (or) New-Stereo DACs present */ + if(!(disney.data&0x80)) return 0xc4; else return 0x0; break; case 2: /* Control Port */ @@ -78,21 +258,79 @@ static Bitu disney_read(Bitu port,Bitu iolen) { return 0xff; } +static void DISNEY_PlayStereo(Bitu len, Bit8u* l, Bit8u* r) { + static Bit8u stereodata[DISNEY_SIZE*2]; + for(Bitu i = 0; i < len; i++) { + stereodata[i*2] = l[i]; + stereodata[i*2+1] = r[i]; + } + disney.chan->AddSamples_s8(len,stereodata); +} static void DISNEY_CallBack(Bitu len) { if (!len) return; - if (disney.used>len) { - disney.chan->AddSamples_m8(len,disney.buffer); - memmove(disney.buffer,&disney.buffer[len],disney.used-len); - disney.used-=len; - } else { - disney.chan->AddSamples_m8(disney.used,disney.buffer); - disney.chan->AddSilence(); - disney.used=0; + + // get the smaller used + Bitu real_used; + if(disney.stereo) { + real_used = disney.da[0].used; + if(disney.da[1].used < real_used) real_used = disney.da[1].used; + } else + real_used = disney.leader->used; + + if (real_used >= len) { // enough data for now + if(disney.stereo) DISNEY_PlayStereo(len, disney.da[0].buffer, disney.da[1].buffer); + else disney.chan->AddSamples_m8(len,disney.leader->buffer); + + // put the rest back to start + for(int i = 0; i < 2; i++) { + // TODO for mono only one + memmove(disney.da[i].buffer,&disney.da[i].buffer[len],DISNEY_SIZE/*real_used*/-len); + disney.da[i].used -= len; + } + // TODO: len > DISNEY + } else { // not enough data + if(disney.stereo) { + Bit8u gapfiller0 = 128; + Bit8u gapfiller1 = 128; + if(real_used) { + gapfiller0 = disney.da[0].buffer[real_used-1]; + gapfiller1 = disney.da[1].buffer[real_used-1]; + }; + + memset(disney.da[0].buffer+real_used, + gapfiller0,len-real_used); + memset(disney.da[1].buffer+real_used, + gapfiller1,len-real_used); + + DISNEY_PlayStereo(len, disney.da[0].buffer, disney.da[1].buffer); + len -= real_used; + + } else { // mono + Bit8u gapfiller = 128; //Keep the middle + if(real_used) { + // fix for some stupid game; it outputs 0 at the end of the stream + // causing a click. So if we have at least two bytes availible in the + // buffer and the last one is a 0 then ignore that. + if(disney.leader->buffer[real_used-1]==0) + real_used--; + } + // do it this way because AddSilence sounds like a gnawing mouse + if(real_used) + gapfiller = disney.leader->buffer[real_used-1]; + //LOG_MSG("gapfiller %x, fill len %d, realused %d",gapfiller,len-real_used,real_used); + memset(disney.leader->buffer+real_used, gapfiller, len-real_used); + disney.chan->AddSamples_m8(len, disney.leader->buffer); + } + disney.da[0].used =0; + disney.da[1].used =0; + + //LOG_MSG("disney underflow %d",len - real_used); } - if (disney.last_used+5000Enable(false); + if (disney.last_used+100(configuration); @@ -109,14 +347,16 @@ public: WriteHandler.Install(DISNEY_BASE,disney_write,IO_MB,3); ReadHandler.Install(DISNEY_BASE,disney_read,IO_MB,3); - disney.chan=MixerChan.Install(&DISNEY_CallBack,7000,"DISNEY"); - disney.status=0x84; disney.control=0; - disney.used=0; disney.last_used=0; + + disney.mo=0; + DISNEY_disable(0); + } + ~DISNEY(){ + DISNEY_disable(0); } - ~DISNEY(){ } }; static DISNEY* test; From 4dbecf269cc24bd0419a216d6ede0d8c92cc4cc3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 14 Jul 2008 20:06:19 +0000 Subject: [PATCH 3093/4131] Update directserial to new configclass. Thanks h-a-l-9000 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3181 --- .../serialport/directserial_win32.cpp | 4 +- src/hardware/serialport/serialport.cpp | 55 +++++++------------ 2 files changed, 23 insertions(+), 36 deletions(-) diff --git a/src/hardware/serialport/directserial_win32.cpp b/src/hardware/serialport/directserial_win32.cpp index 5b88721d..7b4d9c83 100644 --- a/src/hardware/serialport/directserial_win32.cpp +++ b/src/hardware/serialport/directserial_win32.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_win32.cpp,v 1.5 2007-01-13 08:35:49 qbix79 Exp $ */ +/* $Id: directserial_win32.cpp,v 1.6 2008-07-14 20:06:19 qbix79 Exp $ */ #include "dosbox.h" @@ -39,7 +39,7 @@ CDirectSerial::CDirectSerial (Bitu id, CommandLine* cmd) :CSerial (id, cmd) { InstallationSuccessful = false; - + hCom = INVALID_HANDLE_VALUE; // else destructor may close an invalid handle rx_retry = 0; rx_retry_max = 0; diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index 25ea520c..a35c4d03 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.cpp,v 1.8 2007-12-06 17:44:19 qbix79 Exp $ */ +/* $Id: serialport.cpp,v 1.9 2008-07-14 20:06:19 qbix79 Exp $ */ #include #include @@ -1166,68 +1166,55 @@ bool CSerial::Putchar(Bit8u data, bool wait_dsr, bool wait_cts, Bitu timeout) { class SERIALPORTS:public Module_base { public: SERIALPORTS (Section * configuration):Module_base (configuration) { - Bit16u biosParameter[4] = { 0, 0, 0, 0 }; Section_prop *section = static_cast (configuration); - const char *configstrings[4] = { - section->Get_string ("serial1"), - section->Get_string ("serial2"), - section->Get_string ("serial3"), - section->Get_string ("serial4") - }; - // iterate through all 4 com ports - for (Bitu i = 0; i < 4; i++) { - biosParameter[i] = serial_baseaddr[i]; - - CommandLine* cmd; - std::string str; - cmd=new CommandLine(0,configstrings[i]); - cmd->FindCommand(1,str); + char s_property[] = "serialx"; + for(Bitu i = 0; i < 4; i++) { + // get the configuration property + s_property[6] = '1' + i; + Prop_multival* p = section->Get_multival(s_property); + std::string type = p->GetSection()->Get_string("type"); + CommandLine cmd(0,p->GetSection()->Get_string("parameters")); - if(!str.compare("dummy")) { - serialports[i] = new CSerialDummy (i, cmd); + // detect the type + if (type=="dummy") { + serialports[i] = new CSerialDummy (i, &cmd); } #ifdef DIRECTSERIAL_AVAILIBLE - else if(!str.compare("directserial")) { - serialports[i] = new CDirectSerial (i, cmd); + else if (type=="directserial") { + serialports[i] = new CDirectSerial (i, &cmd); if (!serialports[i]->InstallationSuccessful) { // serial port name was wrong or already in use delete serialports[i]; serialports[i] = NULL; - biosParameter[i] = 0; } } #endif - #if C_MODEM - else if(!str.compare("modem")) { - serialports[i] = new CSerialModem (i, cmd); + else if(type=="modem") { + serialports[i] = new CSerialModem (i, &cmd); if (!serialports[i]->InstallationSuccessful) { delete serialports[i]; serialports[i] = NULL; - biosParameter[i] = 0; } } - else if(!str.compare("nullmodem")) { - serialports[i] = new CNullModem (i, cmd); + else if(type=="nullmodem") { + serialports[i] = new CNullModem (i, &cmd); if (!serialports[i]->InstallationSuccessful) { delete serialports[i]; serialports[i] = NULL; - biosParameter[i] = 0; } } #endif - else if(!str.compare("disabled")) { + else if(type=="disabled") { serialports[i] = NULL; - biosParameter[i] = 0; } else { - LOG_MSG ("Invalid type for COM%d.", i + 1); serialports[i] = NULL; - biosParameter[i] = 0; + LOG_MSG("Invalid type for serial%d",i+1); } - delete cmd; - } // for + if(serialports[i]) biosParameter[i] = serial_baseaddr[i]; + } // for 1-4 BIOS_SetComPorts (biosParameter); } From 3f010a728c006c2d049b77e4c5acb0300e5b980a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 19 Jul 2008 13:28:03 +0000 Subject: [PATCH 3094/4131] Add syncing to real clock to interrupt 8 (disabled by default. DOSBOX_CLOCKSYNC) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3182 --- src/ints/bios.cpp | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 48797316..de42895d 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.70 2007-12-06 17:44:18 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.71 2008-07-19 13:28:03 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -320,10 +320,38 @@ static Bitu INT11_Handler(void) { reg_ax=mem_readw(BIOS_CONFIGURATION); return CBRET_NONE; } - +/* + * Define the following define to 1 if you want dosbox to check + * the system time every 5 seconds and adjust 1/2 a second to sync them. + */ +#ifndef DOSBOX_CLOCKSYNC +#define DOSBOX_CLOCKSYNC 0 +#endif static Bitu INT8_Handler(void) { /* Increase the bios tick counter */ - mem_writed(BIOS_TIMER,mem_readd(BIOS_TIMER)+1); + Bit32u value = mem_readd(BIOS_TIMER) + 1; +#if DOSBOX_CLOCKSYNC + static bool check = false; + if((value %50)==0) { + if(((value %100)==0) && check) { + check = false; + time_t curtime;struct tm *loctime; + curtime = time (NULL);loctime = localtime (&curtime); + Bit32u ticksnu = (Bit32u)((loctime->tm_hour*3600+loctime->tm_min*60+loctime->tm_sec)*(float)PIT_TICK_RATE/65536.0); + Bit32s bios = value;Bit32s tn = ticksnu; + Bit32s diff = tn - bios; + if(diff>0) { + if(diff < 18) { diff = 0; } else diff = 9; + } else { + if(diff > -18) { diff = 0; } else diff = -9; + } + + value += diff; + } else if((value%100)==50) check = true; + } +#endif + mem_writed(BIOS_TIMER,value); + /* decrease floppy motor timer */ Bit8u val = mem_readb(BIOS_DISK_MOTOR_TIMEOUT); if (val) mem_writeb(BIOS_DISK_MOTOR_TIMEOUT,val-1); @@ -331,6 +359,7 @@ static Bitu INT8_Handler(void) { mem_writeb(BIOS_DRIVE_RUNNING,mem_readb(BIOS_DRIVE_RUNNING) & 0xF0); return CBRET_NONE; }; +#undef DOSBOX_CLOCKSYNC static Bitu INT1C_Handler(void) { return CBRET_NONE; From ec45bd0fad92afbe06c0ecf5780bee617e9253d6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 26 Jul 2008 14:49:38 +0000 Subject: [PATCH 3095/4131] Add pingpatch from h-a-l-9000. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3183 --- src/hardware/ipx.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index bbc6aecd..4d4e800b 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.cpp,v 1.14 2007-11-01 12:11:40 qbix79 Exp $ */ +/* $Id: ipx.cpp,v 1.15 2008-07-26 14:49:38 qbix79 Exp $ */ #include "dosbox.h" @@ -1038,7 +1038,7 @@ public: WriteOut("IPX Tunneling Client not connected.\n"); return; } - + TIMER_DelTickHandler(&IPX_ClientLoop); WriteOut("Sending broadcast ping:\n\n"); pingSend(); ticks = GetTicks(); @@ -1048,6 +1048,7 @@ public: WriteOut("Response from %d.%d.%d.%d, port %d time=%dms\n", CONVIP(pingHead.src.addr.byIP.host), SDLNet_Read16(&pingHead.src.addr.byIP.port), GetTicks() - ticks); } } + TIMER_AddTickHandler(&IPX_ClientLoop); return; } } From e7d66020eada47ec1eaf1e8897ceba37ecd5756f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 26 Jul 2008 19:06:26 +0000 Subject: [PATCH 3096/4131] Add non-parsing WriteOut. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3184 --- include/programs.h | 3 ++- src/misc/programs.cpp | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/include/programs.h b/include/programs.h index 750b37b7..a6f7e172 100644 --- a/include/programs.h +++ b/include/programs.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.h,v 1.16 2008-03-02 11:13:46 qbix79 Exp $ */ +/* $Id: programs.h,v 1.17 2008-07-26 19:06:26 qbix79 Exp $ */ #ifndef DOSBOX_PROGRAMS_H #define DOSBOX_PROGRAMS_H @@ -77,6 +77,7 @@ public: Bitu GetEnvCount(void); bool SetEnv(const char * entry,const char * new_string); void WriteOut(const char * format,...); /* Write to standard output */ + void WriteOut_NoParsing(const char * format); /* Write to standard output, no parsing */ void ChangeToLongCmd(); }; diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 451a2e24..ada79052 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.31 2008-03-02 11:13:46 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.32 2008-07-26 19:06:26 qbix79 Exp $ */ #include #include @@ -126,10 +126,15 @@ void Program::WriteOut(const char * format,...) { vsnprintf(buf,2047,format,msg); va_end(msg); - Bit16u size=strlen(buf); + Bit16u size = strlen(buf); DOS_WriteFile(STDOUT,(Bit8u *)buf,&size); } +void Program::WriteOut_NoParsing(const char * format) { + Bit16u size = strlen(format); + DOS_WriteFile(STDOUT,(Bit8u *)format,&size); +} + bool Program::GetEnvStr(const char * entry,std::string & result) { /* Walk through the internal environment and see for a match */ From 87941d08833eea369012533cbc600131069c26dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 27 Jul 2008 19:52:12 +0000 Subject: [PATCH 3097/4131] merge opl3-output into two channels only Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3185 --- src/hardware/ymf262.c | 156 ++++++++++++++---------------------------- 1 file changed, 53 insertions(+), 103 deletions(-) diff --git a/src/hardware/ymf262.c b/src/hardware/ymf262.c index 992d832b..5fa9ba69 100644 --- a/src/hardware/ymf262.c +++ b/src/hardware/ymf262.c @@ -215,8 +215,7 @@ unsigned char reserved[512-272];//speedup:pump up the struct size to power of 2 typedef struct { OPL3_CH P_CH[18]; /* OPL3 chips have 18 channels */ - UINT32 pan[18*4]; /* channels output masks (0xffffffff = enable); 4 masks per one channel */ - UINT32 pan_ctrl_value[18]; /* output control values 1 per one channel (1 value contains 4 masks) */ + UINT32 pan[18*2]; /* channels output multiplier; 2 per channel */ UINT32 eg_cnt; /* global envelope generator counter */ UINT32 eg_timer; /* global envelope generator counter works at frequency = chipclock/288 (288=8*36) */ @@ -2069,27 +2068,23 @@ static void OPL3WriteReg(OPL3 *chip, int r, int v) if( chip->OPL3_mode & 1 ) { - int base = ((r&0xf) + ch_offset) * 4; + int base = ((r&0xf) + ch_offset) * 2; /* OPL3 mode */ - chip->pan[ base ] = (v & 0x10) ? ~0 : 0; /* ch.A */ - chip->pan[ base +1 ] = (v & 0x20) ? ~0 : 0; /* ch.B */ - chip->pan[ base +2 ] = (v & 0x40) ? ~0 : 0; /* ch.C */ - chip->pan[ base +3 ] = (v & 0x80) ? ~0 : 0; /* ch.D */ + chip->pan[ base ] = (v & 0x10) ? 1 : 0; /* ch.A */ + chip->pan[ base +1 ] = (v & 0x20) ? 1 : 0; /* ch.B */ + if (v & 0x40) chip->pan[ base ] += 1; /* ch.C->ch.A */ + if (v & 0x80) chip->pan[ base +1 ] += 1; /* ch.D->ch.B */ } else { - int base = ((r&0xf) + ch_offset) * 4; + int base = ((r&0xf) + ch_offset) * 2; /* OPL2 mode - always enabled */ - chip->pan[ base ] = ~0; /* ch.A */ - chip->pan[ base +1 ] = ~0; /* ch.B */ - chip->pan[ base +2 ] = ~0; /* ch.C */ - chip->pan[ base +3 ] = ~0; /* ch.D */ + chip->pan[ base ] = 1; /* ch.A */ + chip->pan[ base +1 ] = 1; /* ch.B */ } - chip->pan_ctrl_value[ (r&0xf) + ch_offset ] = v; /* store control value for OPL3/OPL2 mode switching on the fly */ - CH->SLOT[SLOT1].FB = (v>>1)&7 ? ((v>>1)&7) + 7 : 0; CH->SLOT[SLOT1].CON = v&1; @@ -2590,8 +2585,6 @@ void YMF262UpdateOne(int which, INT16 *buffer, int length) #if 0 OPL3SAMPLE *ch_a = buffers[0]; OPL3SAMPLE *ch_b = buffers[1]; - OPL3SAMPLE *ch_c = buffers[2]; - OPL3SAMPLE *ch_d = buffers[3]; #endif int i; @@ -2605,7 +2598,7 @@ void YMF262UpdateOne(int which, INT16 *buffer, int length) } for( i=0; i < length ; i++ ) { - int a,b,c,d; + int a,b; advance_lfo(chip); @@ -2615,8 +2608,7 @@ void YMF262UpdateOne(int which, INT16 *buffer, int length) //profiler_mark(PROFILER_USER1); -#if 1 - /* register set #1 */ + /* register set #1 */ chan_calc(&chip->P_CH[0]); /* extended 4op ch#0 part 1 or 2op ch#0 */ if (chip->P_CH[0].extended) chan_calc_ext(&chip->P_CH[3]); /* extended 4op ch#0 part 2 */ @@ -2649,7 +2641,7 @@ void YMF262UpdateOne(int which, INT16 *buffer, int length) chan_calc_rhythm(&chip->P_CH[0], (chip->noise_rng>>0)&1 ); } - /* register set #2 */ + /* register set #2 */ chan_calc(&chip->P_CH[ 9]); if (chip->P_CH[9].extended) chan_calc_ext(&chip->P_CH[12]); @@ -2675,103 +2667,63 @@ void YMF262UpdateOne(int which, INT16 *buffer, int length) chan_calc(&chip->P_CH[15]); chan_calc(&chip->P_CH[16]); chan_calc(&chip->P_CH[17]); -#endif + //profiler_mark(PROFILER_END); //profiler_mark(PROFILER_USER2); /* accumulator register set #1 */ - a = chanout[0] & chip->pan[0]; - b = chanout[0] & chip->pan[1]; - c = chanout[0] & chip->pan[2]; - d = chanout[0] & chip->pan[3]; -#if 1 - a += chanout[1] & chip->pan[4]; - b += chanout[1] & chip->pan[5]; - c += chanout[1] & chip->pan[6]; - d += chanout[1] & chip->pan[7]; - a += chanout[2] & chip->pan[8]; - b += chanout[2] & chip->pan[9]; - c += chanout[2] & chip->pan[10]; - d += chanout[2] & chip->pan[11]; + a = chanout[0] * chip->pan[0]; + b = chanout[0] * chip->pan[1]; - a += chanout[3] & chip->pan[12]; - b += chanout[3] & chip->pan[13]; - c += chanout[3] & chip->pan[14]; - d += chanout[3] & chip->pan[15]; - a += chanout[4] & chip->pan[16]; - b += chanout[4] & chip->pan[17]; - c += chanout[4] & chip->pan[18]; - d += chanout[4] & chip->pan[19]; - a += chanout[5] & chip->pan[20]; - b += chanout[5] & chip->pan[21]; - c += chanout[5] & chip->pan[22]; - d += chanout[5] & chip->pan[23]; + a += chanout[1] * chip->pan[2]; + b += chanout[1] * chip->pan[3]; + a += chanout[2] * chip->pan[4]; + b += chanout[2] * chip->pan[5]; - a += chanout[6] & chip->pan[24]; - b += chanout[6] & chip->pan[25]; - c += chanout[6] & chip->pan[26]; - d += chanout[6] & chip->pan[27]; - a += chanout[7] & chip->pan[28]; - b += chanout[7] & chip->pan[29]; - c += chanout[7] & chip->pan[30]; - d += chanout[7] & chip->pan[31]; - a += chanout[8] & chip->pan[32]; - b += chanout[8] & chip->pan[33]; - c += chanout[8] & chip->pan[34]; - d += chanout[8] & chip->pan[35]; + a += chanout[3] * chip->pan[6]; + b += chanout[3] * chip->pan[7]; + a += chanout[4] * chip->pan[8]; + b += chanout[4] * chip->pan[9]; + a += chanout[5] * chip->pan[10]; + b += chanout[5] * chip->pan[11]; + + a += chanout[6] * chip->pan[12]; + b += chanout[6] * chip->pan[13]; + a += chanout[7] * chip->pan[14]; + b += chanout[7] * chip->pan[15]; + a += chanout[8] * chip->pan[16]; + b += chanout[8] * chip->pan[17]; /* accumulator register set #2 */ - a += chanout[9] & chip->pan[36]; - b += chanout[9] & chip->pan[37]; - c += chanout[9] & chip->pan[38]; - d += chanout[9] & chip->pan[39]; - a += chanout[10] & chip->pan[40]; - b += chanout[10] & chip->pan[41]; - c += chanout[10] & chip->pan[42]; - d += chanout[10] & chip->pan[43]; - a += chanout[11] & chip->pan[44]; - b += chanout[11] & chip->pan[45]; - c += chanout[11] & chip->pan[46]; - d += chanout[11] & chip->pan[47]; + a += chanout[9] * chip->pan[18]; + b += chanout[9] * chip->pan[19]; + a += chanout[10] * chip->pan[20]; + b += chanout[10] * chip->pan[21]; + a += chanout[11] * chip->pan[22]; + b += chanout[11] * chip->pan[23]; - a += chanout[12] & chip->pan[48]; - b += chanout[12] & chip->pan[49]; - c += chanout[12] & chip->pan[50]; - d += chanout[12] & chip->pan[51]; - a += chanout[13] & chip->pan[52]; - b += chanout[13] & chip->pan[53]; - c += chanout[13] & chip->pan[54]; - d += chanout[13] & chip->pan[55]; - a += chanout[14] & chip->pan[56]; - b += chanout[14] & chip->pan[57]; - c += chanout[14] & chip->pan[58]; - d += chanout[14] & chip->pan[59]; + a += chanout[12] * chip->pan[24]; + b += chanout[12] * chip->pan[25]; + a += chanout[13] * chip->pan[26]; + b += chanout[13] * chip->pan[27]; + a += chanout[14] * chip->pan[28]; + b += chanout[14] * chip->pan[29]; + + a += chanout[15] * chip->pan[30]; + b += chanout[15] * chip->pan[31]; + a += chanout[16] * chip->pan[32]; + b += chanout[16] * chip->pan[33]; + a += chanout[17] * chip->pan[34]; + b += chanout[17] * chip->pan[35]; - a += chanout[15] & chip->pan[60]; - b += chanout[15] & chip->pan[61]; - c += chanout[15] & chip->pan[62]; - d += chanout[15] & chip->pan[63]; - a += chanout[16] & chip->pan[64]; - b += chanout[16] & chip->pan[65]; - c += chanout[16] & chip->pan[66]; - d += chanout[16] & chip->pan[67]; - a += chanout[17] & chip->pan[68]; - b += chanout[17] & chip->pan[69]; - c += chanout[17] & chip->pan[70]; - d += chanout[17] & chip->pan[71]; -#endif a >>= FINAL_SH; b >>= FINAL_SH; - c >>= FINAL_SH; - d >>= FINAL_SH; /* limit check */ - a = limit( a+c , MAXOUT, MINOUT ); - b = limit( b+d , MAXOUT, MINOUT ); -// c = limit( c , MAXOUT, MINOUT ); -// d = limit( d , MAXOUT, MINOUT ); + a = limit( a , MAXOUT, MINOUT ); + b = limit( b , MAXOUT, MINOUT ); #ifdef SAVE_SAMPLE if (which==0) @@ -2786,8 +2738,6 @@ void YMF262UpdateOne(int which, INT16 *buffer, int length) #if 0 ch_a[i] = a; ch_b[i] = b; - ch_c[i] = c; - ch_d[i] = d; #endif //profiler_mark(PROFILER_END); From 6d1979bb9d3c9805eda86603d08a21849c5224d6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 27 Jul 2008 20:12:28 +0000 Subject: [PATCH 3098/4131] Make max 50% in autoexec.bat possible. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3186 --- src/shell/shell.cpp | 12 ++++++------ src/shell/shell_batch.cpp | 6 ++++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 2e6276b5..1e7c6a25 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.89 2008-03-02 11:13:47 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.90 2008-07-27 20:12:28 qbix79 Exp $ */ #include #include @@ -270,8 +270,8 @@ void DOS_Shell::RunInternal(void) if (echo) { if (input_line[0] != '@') { ShowPrompt(); - WriteOut(input_line); - WriteOut("\n"); + WriteOut_NoParsing(input_line); + WriteOut_NoParsing("\n"); }; }; ParseLine(input_line); @@ -318,8 +318,8 @@ void DOS_Shell::Run(void) { if (echo) { if (input_line[0]!='@') { ShowPrompt(); - WriteOut(input_line); - WriteOut("\n"); + WriteOut_NoParsing(input_line); + WriteOut_NoParsing("\n"); }; }; ParseLine(input_line); @@ -329,7 +329,7 @@ void DOS_Shell::Run(void) { if (echo) ShowPrompt(); InputCommand(input_line); ParseLine(input_line); - if (echo && !bf) WriteOut("\n"); + if (echo && !bf) WriteOut_NoParsing("\n"); } } while (!exit); } diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index d16e748a..a8b9ce4c 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.27 2008-03-10 13:43:37 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.28 2008-07-27 20:12:28 qbix79 Exp $ */ #include #include @@ -100,7 +100,9 @@ emptyline: } else { /* Not a command line number has to be an environment */ char * first=strchr(cmd_read,'%'); - if (!first) continue; *first++=0; + /* No env afterall.Somewhat of a hack though as %% and % aren't handled consistent in dosbox. Maybe echo needs to parse % and %% as well. */ + if (!first) {*cmd_write++ = '%';continue;} + *first++ = 0; std::string env; if (shell->GetEnvStr(cmd_read,env)) { const char * equals=strchr(env.c_str(),'='); From becde6b64cb119647e30a86b5e54704e66d32e51 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 28 Jul 2008 19:46:39 +0000 Subject: [PATCH 3099/4131] Some const correctness. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3187 --- src/debug/debug_disasm.cpp | 86 +++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/src/debug/debug_disasm.cpp b/src/debug/debug_disasm.cpp index c9cd7335..66a9820d 100644 --- a/src/debug/debug_disasm.cpp +++ b/src/debug/debug_disasm.cpp @@ -176,9 +176,9 @@ static int addr32bit=0; /* watch out for aad && aam with odd operands */ -static char *(*opmap1)[256]; +static char const* (*opmap1)[256]; -static char *op386map1[256] = { +static char const * op386map1[256] = { /* 0 */ "add %Eb,%Gb", "add %Ev,%Gv", "add %Gb,%Eb", "add %Gv,%Ev", "add al,%Ib", "add %eax,%Iv", "push es", "pop es", @@ -266,7 +266,7 @@ static char *op386map1[256] = { "cld", "std", "%g3", "%g4" }; -static char *second[] = { +static char const *second[] = { /* 0 */ "%g5", "%g6", "lar %Gv,%Ew", "lsl %Gv,%Ew", 0, "[loadall]", "clts", "[loadall]", @@ -333,7 +333,7 @@ static char *second[] = { 0, 0, 0, 0, 0, 0, 0, 0, }; -static char *groups[][8] = { /* group 0 is group 3 for %Ev set */ +static char const *groups[][8] = { /* group 0 is group 3 for %Ev set */ /* 0 */ { "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" }, @@ -362,45 +362,45 @@ static char *groups[][8] = { /* group 0 is group 3 for %Ev set */ /* zero here means invalid. If first entry starts with '*', use st(i) */ /* no assumed %EFs here. Indexed by RM(modrm()) */ -static char *f0[] = { 0, 0, 0, 0, 0, 0, 0, 0}; -static char *fop_8[] = { "*fld st,%GF" }; -static char *fop_9[] = { "*fxch st,%GF" }; -static char *fop_10[] = { "fnop", 0, 0, 0, 0, 0, 0, 0 }; -static char *fop_11[] = { "*fst st,%GF" }; -static char *fop_12[] = { "fchs", "fabs", 0, 0, "ftst", "fxam", 0, 0 }; -static char *fop_13[] = { "fld1", "fldl2t", "fldl2e", "fldpi", +static char const *f0[] = { 0, 0, 0, 0, 0, 0, 0, 0}; +static char const *fop_8[] = { "*fld st,%GF" }; +static char const *fop_9[] = { "*fxch st,%GF" }; +static char const *fop_10[] = { "fnop", 0, 0, 0, 0, 0, 0, 0 }; +static char const *fop_11[] = { "*fst st,%GF" }; +static char const *fop_12[] = { "fchs", "fabs", 0, 0, "ftst", "fxam", 0, 0 }; +static char const *fop_13[] = { "fld1", "fldl2t", "fldl2e", "fldpi", "fldlg2", "fldln2", "fldz", 0 }; -static char *fop_14[] = { "f2xm1", "fyl2x", "fptan", "fpatan", +static char const *fop_14[] = { "f2xm1", "fyl2x", "fptan", "fpatan", "fxtract", "fprem1", "fdecstp", "fincstp" }; -static char *fop_15[] = { "fprem", "fyl2xp1", "fsqrt", "fsincos", +static char const *fop_15[] = { "fprem", "fyl2xp1", "fsqrt", "fsincos", "frndint", "fscale", "fsin", "fcos" }; -static char *fop_21[] = { 0, "fucompp", 0, 0, 0, 0, 0, 0 }; -static char *fop_28[] = { "[fneni]", "[fndis]", "fclex", "finit", "[fnsetpm]", "[frstpm]", 0, 0 }; -static char *fop_32[] = { "*fadd %GF,st" }; -static char *fop_33[] = { "*fmul %GF,st" }; -static char *fop_34[] = { "*fcom %GF,st" }; -static char *fop_35[] = { "*fcomp %GF,st" }; -static char *fop_36[] = { "*fsubr %GF,st" }; -static char *fop_37[] = { "*fsub %GF,st" }; -static char *fop_38[] = { "*fdivr %GF,st" }; -static char *fop_39[] = { "*fdiv %GF,st" }; -static char *fop_40[] = { "*ffree %GF" }; -static char *fop_41[] = { "*fxch %GF" }; -static char *fop_42[] = { "*fst %GF" }; -static char *fop_43[] = { "*fstp %GF" }; -static char *fop_44[] = { "*fucom %GF" }; -static char *fop_45[] = { "*fucomp %GF" }; -static char *fop_48[] = { "*faddp %GF,st" }; -static char *fop_49[] = { "*fmulp %GF,st" }; -static char *fop_50[] = { "*fcomp %GF,st" }; -static char *fop_51[] = { 0, "fcompp", 0, 0, 0, 0, 0, 0 }; -static char *fop_52[] = { "*fsubrp %GF,st" }; -static char *fop_53[] = { "*fsubp %GF,st" }; -static char *fop_54[] = { "*fdivrp %GF,st" }; -static char *fop_55[] = { "*fdivp %GF,st" }; -static char *fop_60[] = { "fstsw ax", 0, 0, 0, 0, 0, 0, 0 }; +static char const *fop_21[] = { 0, "fucompp", 0, 0, 0, 0, 0, 0 }; +static char const *fop_28[] = { "[fneni]", "[fndis]", "fclex", "finit", "[fnsetpm]", "[frstpm]", 0, 0 }; +static char const *fop_32[] = { "*fadd %GF,st" }; +static char const *fop_33[] = { "*fmul %GF,st" }; +static char const *fop_34[] = { "*fcom %GF,st" }; +static char const *fop_35[] = { "*fcomp %GF,st" }; +static char const *fop_36[] = { "*fsubr %GF,st" }; +static char const *fop_37[] = { "*fsub %GF,st" }; +static char const *fop_38[] = { "*fdivr %GF,st" }; +static char const *fop_39[] = { "*fdiv %GF,st" }; +static char const *fop_40[] = { "*ffree %GF" }; +static char const *fop_41[] = { "*fxch %GF" }; +static char const *fop_42[] = { "*fst %GF" }; +static char const *fop_43[] = { "*fstp %GF" }; +static char const *fop_44[] = { "*fucom %GF" }; +static char const *fop_45[] = { "*fucomp %GF" }; +static char const *fop_48[] = { "*faddp %GF,st" }; +static char const *fop_49[] = { "*fmulp %GF,st" }; +static char const *fop_50[] = { "*fcomp %GF,st" }; +static char const *fop_51[] = { 0, "fcompp", 0, 0, 0, 0, 0, 0 }; +static char const *fop_52[] = { "*fsubrp %GF,st" }; +static char const *fop_53[] = { "*fsubp %GF,st" }; +static char const *fop_54[] = { "*fdivrp %GF,st" }; +static char const *fop_55[] = { "*fdivp %GF,st" }; +static char const *fop_60[] = { "fstsw ax", 0, 0, 0, 0, 0, 0, 0 }; -static char **fspecial[] = { /* 0=use st(i), 1=undefined 0 in fop_* means undefined */ +static char const **fspecial[] = { /* 0=use st(i), 1=undefined 0 in fop_* means undefined */ 0, 0, 0, 0, 0, 0, 0, 0, fop_8, fop_9, fop_10, fop_11, fop_12, fop_13, fop_14, fop_15, f0, f0, f0, f0, f0, fop_21, f0, f0, @@ -411,7 +411,7 @@ static char **fspecial[] = { /* 0=use st(i), 1=undefined 0 in fop_* means undefi f0, f0, f0, f0, fop_60, f0, f0, f0, }; -static char *floatops[] = { /* assumed " %EF" at end of each. mod != 3 only */ +static const char *floatops[] = { /* assumed " %EF" at end of each. mod != 3 only */ /*00*/ "fadd", "fmul", "fcom", "fcomp", "fsub", "fsubr", "fdiv", "fdivr", /*08*/ "fld", 0, "fst", "fstp", @@ -482,7 +482,7 @@ static int sib(void) /*------------------------------------------------------------------------*/ -static void uprintf(char *s, ...) +static void uprintf(char const *s, ...) { va_list arg_ptr; va_start (arg_ptr, s); @@ -674,7 +674,7 @@ static void reg_name(int regnum, char size) /*------------------------------------------------------------------------*/ -static void ua_str(char *str); +static void ua_str(char const *str); static void do_sib(int m) { @@ -1035,7 +1035,7 @@ static void percent(char type, char subtype) } -static void ua_str(char *str) +static void ua_str(char const *str) { char c; From b1ed4cc84c40e681468b17b52fb2bd3f7e0d5c63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 1 Aug 2008 19:52:02 +0000 Subject: [PATCH 3100/4131] write dcc code into dynamic function state area, not the dcc index Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3188 --- src/ints/int10_misc.cpp | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 7b31e24b..8f0a1821 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: int10_misc.cpp,v 1.19 2008-08-01 19:52:02 c2woody Exp $ */ + #include "dosbox.h" #include "mem.h" #include "inout.h" @@ -88,8 +90,24 @@ void INT10_GetFuncStateInformation(PhysPt save) { } /* Zero out rest of block */ for (i=0x25;i<0x40;i++) mem_writeb(save+i,0); - /* DCC Index */ - mem_writeb(save+0x25,real_readb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX)); + /* DCC */ +// mem_writeb(save+0x25,real_readb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX)); + Bit8u dccode = 0x00; + RealPt vsavept=real_readd(BIOSMEM_SEG,BIOSMEM_VS_POINTER); + RealPt svstable=real_readd(RealSeg(vsavept),RealOff(vsavept)+0x10); + if (svstable) { + RealPt dcctable=real_readd(RealSeg(svstable),RealOff(svstable)+0x02); + Bit8u entries=real_readb(RealSeg(dcctable),RealOff(dcctable)+0x00); + Bit8u idx=real_readb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX); + // check if index within range + if (idx>8)&0xff); + else dccode=(Bit8u)(dccentry&0xff); + } + } + mem_writeb(save+0x25,dccode); + Bit16u col_count=0; switch (CurMode->type) { case M_TEXT: From 6eae7e5586c803f7322acd1429f550ffd000e773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 3 Aug 2008 13:37:49 +0000 Subject: [PATCH 3101/4131] fix some s3 crtc register return values, use trio64 as ID (re-enables lfb detection for univbe) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3189 --- src/hardware/vga_s3.cpp | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index daed7547..2153e2ac 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_s3.cpp,v 1.13 2008-03-14 22:00:59 c2woody Exp $ */ +/* $Id: vga_s3.cpp,v 1.14 2008-08-03 13:37:49 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -330,18 +330,18 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { switch (reg) { - case 0x2d: /* Extended Chip ID. */ + case 0x24: /* attribute controller index (read only) */ + case 0x26: + return (vga.attr.enabled?0x20:0x00) | (vga.attr.index&0x1f); + case 0x2d: /* Extended Chip ID (high byte of PCI device ID) */ return 0x88; - // Always 88h ? - case 0x2e: /* New Chip ID */ - return 0x11; - //Trio 64 id + case 0x2e: /* New Chip ID (low byte of PCI device ID) */ + return 0x11; // Trio64 case 0x2f: /* Revision */ - return 0x44; + return 0x00; // Trio64 (exact value?) +// return 0x44; // Trio64 V+ case 0x30: /* CR30 Chip ID/REV register */ - return 0xe1; //Trio+ dual byte - //return 0xc0; // 864 - + return 0xe1; // Trio+ dual byte case 0x31: /* CR31 Memory Configuration */ //TODO mix in bits from baseaddress; return vga.s3.reg_31; @@ -350,7 +350,8 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { case 0x36: /* CR36 Reset State Read 1 */ return vga.s3.reg_36; case 0x37: /* Reset state read 2 */ - return 0x2b; + return 0x2f; +// return 0x2b; case 0x38: /* CR38 Register Lock 1 */ return vga.s3.reg_lock1; case 0x39: /* CR39 Register Lock 2 */ @@ -510,19 +511,19 @@ void SVGA_Setup_S3Trio(void) { // Set CRTC 36 to specify amount of VRAM and PCI if (vga.vmemsize < 1024*1024) { vga.vmemsize = 512*1024; - vga.s3.reg_36 = 0xf2; + vga.s3.reg_36 = 0xf9; // less than 1mb, video BIOS access enabled, VLB } else if (vga.vmemsize < 2048*1024) { vga.vmemsize = 1024*1024; - vga.s3.reg_36 = 0xd2; + vga.s3.reg_36 = 0xd9; // 1mb, video BIOS access enabled, VLB } else if (vga.vmemsize < 3072*1024) { vga.vmemsize = 2048*1024; - vga.s3.reg_36 = 0x92; + vga.s3.reg_36 = 0x99; // 2mb, video BIOS access enabled, VLB } else if (vga.vmemsize < 4096*1024) { vga.vmemsize = 3072*1024; - vga.s3.reg_36 = 0x52; + vga.s3.reg_36 = 0x59; // 3mb, video BIOS access enabled, VLB } else { // Trio64 supported only up to 4M vga.vmemsize = 4096*1024; - vga.s3.reg_36 = 0x12; + vga.s3.reg_36 = 0x19; // 4mb, video BIOS access enabled, VLB } // S3 ROM signature From 01e8571eceb09c2aaefd01c0c4d41868b5823713 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 3 Aug 2008 15:52:06 +0000 Subject: [PATCH 3102/4131] Make the mouse struct a bit smaller. ignore mouse.page in text mode, always use current page. Fixes CV RENUM. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3190 --- src/ints/mouse.cpp | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 6f8ded52..08df6103 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.73 2008-05-15 20:12:37 c2woody Exp $ */ +/* $Id: mouse.cpp,v 1.74 2008-08-03 15:52:06 qbix79 Exp $ */ #include #include @@ -44,8 +44,8 @@ static Bit16s oldmouseX, oldmouseY; void WriteMouseIntVector(void); struct button_event { - Bit16u type; - Bit16u buttons; + Bit8u type; + Bit8u buttons; }; #define QUEUE_SIZE 32 @@ -79,7 +79,7 @@ static Bit16u userdefScreenMask[CURSORY]; static Bit16u userdefCursorMask[CURSORY]; static struct { - Bit16u buttons; + Bit8u buttons; Bit16u times_pressed[MOUSE_BUTTONS]; Bit16u times_released[MOUSE_BUTTONS]; Bit16u last_released_x[MOUSE_BUTTONS]; @@ -92,7 +92,7 @@ static struct { float mickey_x,mickey_y; float x,y; button_event event_queue[QUEUE_SIZE]; - Bit32u events; + Bit8u events;//Increase if QUEUE_SIZE >255 (currently 32) Bit16u sub_seg,sub_ofs; Bit16u sub_mask; @@ -196,7 +196,7 @@ Bitu PS2_Handler(void) { #define MOUSE_MIDDLE_PRESSED 32 #define MOUSE_MIDDLE_RELEASED 64 -INLINE void Mouse_AddEvent(Bit16u type) { +INLINE void Mouse_AddEvent(Bit8u type) { if (mouse.events0) { /* Skip duplicate events */ @@ -225,7 +225,7 @@ void RestoreCursorBackgroundText() { if (mouse.hidden || mouse.inhibit_draw) return; if (mouse.background) { - WriteChar(mouse.backposx,mouse.backposy,0,mouse.backData[0],mouse.backData[1],true); + WriteChar(mouse.backposx,mouse.backposy,real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE),mouse.backData[0],mouse.backData[1],true); mouse.background = false; } }; @@ -239,14 +239,17 @@ void DrawCursorText() { mouse.backposx = POS_X>>3; mouse.backposy = POS_Y>>3; + //use current page (CV program) + Bit8u page = real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); Bit16u result; - ReadCharAttr(mouse.backposx,mouse.backposy,0,&result); + + ReadCharAttr(mouse.backposx,mouse.backposy,page,&result); mouse.backData[0] = (Bit8u)(result & 0xFF); mouse.backData[1] = (Bit8u)(result>>8); mouse.background = true; // Write Cursor result = (result & mouse.textAndMask) ^ mouse.textXorMask; - WriteChar(mouse.backposx,mouse.backposy,0,(Bit8u)(result&0xFF),(Bit8u)(result>>8),true); + WriteChar(mouse.backposx,mouse.backposy,page,(Bit8u)(result&0xFF),(Bit8u)(result>>8),true); }; // *************************************************************************** @@ -343,7 +346,14 @@ void RestoreCursorBackground() { void DrawCursor() { if (mouse.hidden || mouse.inhibit_draw) return; -// Check video page + // In Textmode ? + if (CurMode->type==M_TEXT) { + DrawCursorText(); + return; + } + + // Check video page. Seems to be ignored for text mode. + // hence the text mode handled above this if (real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE)!=mouse.page) return; // Check if cursor in update region /* if ((POS_X >= mouse.updateRegion_x[0]) && (POS_X <= mouse.updateRegion_x[1]) && @@ -359,11 +369,6 @@ void DrawCursor() { // Get Clipping ranges - // In Textmode ? - if (CurMode->type==M_TEXT) { - DrawCursorText(); - return; - } mouse.clipx = CurMode->swidth-1; /* Get from bios ? */ mouse.clipy = CurMode->sheight-1; From 3d40069e4a6ad4b263a944a98dff32f860b6a010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 4 Aug 2008 17:48:36 +0000 Subject: [PATCH 3103/4131] tweak s3 crtc reg36 (hal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3191 --- src/hardware/vga_s3.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index 2153e2ac..a549407c 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_s3.cpp,v 1.14 2008-08-03 13:37:49 c2woody Exp $ */ +/* $Id: vga_s3.cpp,v 1.15 2008-08-04 17:48:36 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -350,8 +350,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { case 0x36: /* CR36 Reset State Read 1 */ return vga.s3.reg_36; case 0x37: /* Reset state read 2 */ - return 0x2f; -// return 0x2b; + return 0x2b; case 0x38: /* CR38 Register Lock 1 */ return vga.s3.reg_lock1; case 0x39: /* CR39 Register Lock 2 */ @@ -511,19 +510,19 @@ void SVGA_Setup_S3Trio(void) { // Set CRTC 36 to specify amount of VRAM and PCI if (vga.vmemsize < 1024*1024) { vga.vmemsize = 512*1024; - vga.s3.reg_36 = 0xf9; // less than 1mb, video BIOS access enabled, VLB + vga.s3.reg_36 = 0xfa; // less than 1mb fast page mode } else if (vga.vmemsize < 2048*1024) { vga.vmemsize = 1024*1024; - vga.s3.reg_36 = 0xd9; // 1mb, video BIOS access enabled, VLB + vga.s3.reg_36 = 0xda; // 1mb fast page mode } else if (vga.vmemsize < 3072*1024) { vga.vmemsize = 2048*1024; - vga.s3.reg_36 = 0x99; // 2mb, video BIOS access enabled, VLB + vga.s3.reg_36 = 0x9a; // 2mb fast page mode } else if (vga.vmemsize < 4096*1024) { vga.vmemsize = 3072*1024; - vga.s3.reg_36 = 0x59; // 3mb, video BIOS access enabled, VLB + vga.s3.reg_36 = 0x5a; // 3mb fast page mode } else { // Trio64 supported only up to 4M vga.vmemsize = 4096*1024; - vga.s3.reg_36 = 0x19; // 4mb, video BIOS access enabled, VLB + vga.s3.reg_36 = 0x1a; // 4mb fast page mode } // S3 ROM signature @@ -536,5 +535,5 @@ void SVGA_Setup_S3Trio(void) { phys_writeb(rom_base+0x0044,'C'); phys_writeb(rom_base+0x0045,'7'); phys_writeb(rom_base+0x0046,'6'); - phys_writeb(rom_base+0x0047,'5'); + phys_writeb(rom_base+0x0047,'4'); } From c78a9f6c03ebc7d65ef4818357fdea956e2d264e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 6 Aug 2008 18:34:21 +0000 Subject: [PATCH 3104/4131] fix/work around some gcc Wall warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3192 --- include/dos_system.h | 6 +- include/setup.h | 20 +++---- src/cpu/core_dyn_x86/risc_x86.h | 4 +- src/cpu/cpu.cpp | 24 ++++++-- src/dos/cdrom_aspi_win32.cpp | 16 ++++-- src/dos/dos_files.cpp | 15 ++--- src/dos/dos_keyboard_layout.cpp | 55 ++++++++++--------- src/dos/dos_misc.cpp | 7 +-- src/dos/dos_mscdex.cpp | 6 +- src/dos/dos_programs.cpp | 18 +++--- src/dos/dos_tables.cpp | 6 +- src/dos/drive_cache.cpp | 7 +-- src/dos/drive_fat.cpp | 29 +++++----- src/gui/midi_win32.h | 8 +-- src/gui/render.cpp | 8 ++- src/gui/sdl_gui.cpp | 12 ++-- src/gui/sdlmain.cpp | 17 +++++- src/hardware/adlib.cpp | 10 +++- src/hardware/hardware.cpp | 12 ++-- src/hardware/sblaster.cpp | 11 +++- .../serialport/directserial_win32.cpp | 13 ++--- src/hardware/serialport/serialport.cpp | 8 +-- src/hardware/vga.cpp | 4 +- src/hardware/vga_draw.cpp | 26 ++++++--- src/hardware/vga_memory.cpp | 5 +- src/hardware/vga_other.cpp | 6 +- src/hardware/vga_paradise.cpp | 4 +- src/hardware/vga_tseng.cpp | 7 ++- src/hardware/vga_xga.cpp | 4 +- src/ints/bios.cpp | 8 +-- src/ints/ems.cpp | 6 +- src/ints/int10_modes.cpp | 18 +++--- src/ints/int10_put_pixel.cpp | 24 ++++---- src/ints/int10_video_state.cpp | 12 ++-- src/ints/int10_vptable.cpp | 28 +++++----- src/libs/gui_tk/gui_tk.cpp | 8 +-- src/libs/gui_tk/gui_tk.h | 4 +- src/misc/setup.cpp | 5 +- src/misc/support.cpp | 6 +- src/platform/visualc/dirent.c | 6 +- src/shell/shell_batch.cpp | 6 +- 41 files changed, 280 insertions(+), 219 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 97933ff7..9269a416 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.42 2008-04-16 19:31:05 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.43 2008-08-06 18:31:10 c2woody Exp $ */ #ifndef DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H @@ -130,7 +130,7 @@ public: DOS_Drive_Cache (const char* path); ~DOS_Drive_Cache (void); - typedef enum TDirSort { NOSORT, ALPHABETICAL, DIRALPHABETICAL, ALPHABETICALREV, DIRALPHABETICALREV }; + enum TDirSort { NOSORT, ALPHABETICAL, DIRALPHABETICAL, ALPHABETICALREV, DIRALPHABETICALREV }; void SetBaseDir (const char* path); void SetDirSort (TDirSort sort) { sortDirType = sort; }; diff --git a/include/setup.h b/include/setup.h index a8fbffda..8e9d4a8a 100644 --- a/include/setup.h +++ b/include/setup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.37 2008-06-13 08:55:04 qbix79 Exp $ */ +/* $Id: setup.h,v 1.38 2008-08-06 18:31:10 c2woody Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -79,16 +79,16 @@ public: enum Etype { V_NONE, V_HEX, V_BOOL, V_INT, V_STRING, V_DOUBLE,V_CURRENT} type; /* Constructors */ - Value() :type(V_NONE),_string(0) { }; - Value(Hex in) :type(V_HEX), _hex(in) { }; - Value(int in) :type(V_INT), _int(in) { }; - Value(bool in) :type(V_BOOL), _bool(in) { }; - Value(double in) :type(V_DOUBLE), _double(in) { }; - Value(std::string const& in) :type(V_STRING), _string(new std::string(in)) { }; - Value(char const * const in) :type(V_STRING), _string(new std::string(in)) { }; + 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) :type(V_NONE),_string(0){SetValue(in,_t);} + 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));} diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index b091c384..76bf4395 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_x86.h,v 1.30 2008-05-18 13:11:14 c2woody Exp $ */ +/* $Id: risc_x86.h,v 1.31 2008-08-06 18:31:26 c2woody Exp $ */ static void gen_init(void); @@ -752,8 +752,10 @@ static void gen_call_function(void * func,char const* ops,...) { if (ops) { va_list params; va_start(params,ops); +#if defined (MACOSX) Bitu stack_used=0; bool free_flags=false; +#endif Bits pindex=0; while (*ops) { if (*ops=='%') { diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 0ed6800f..3c45e182 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.112 2008-05-21 21:29:32 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.113 2008-08-06 18:31:26 c2woody Exp $ */ #include #include @@ -379,6 +379,14 @@ bool CPU_SwitchTask(Bitu new_tss_selector,TSwitchType tstype,Bitu old_eip) { new_ldt=mem_readw(new_tss.base+offsetof(TSS_32,ldt)); } else { E_Exit("286 task switch"); + new_cr3=0; + new_eip=0; + new_eflags=0; + new_eax=0; new_ecx=0; new_edx=0; new_ebx=0; + new_esp=0; new_ebp=0; new_edi=0; new_esi=0; + + new_es=0; new_cs=0; new_ss=0; new_ds=0; new_fs=0; new_gs=0; + new_ldt=0; } /* Check if we need to clear busy bit of old TASK */ @@ -498,7 +506,9 @@ doconforming: CPU_SetSegGeneral(ds,new_ds); CPU_SetSegGeneral(fs,new_fs); CPU_SetSegGeneral(gs,new_gs); - if (!cpu_tss.SetSelector(new_tss_selector)) LOG(LOG_CPU,LOG_NORMAL)("TaskSwitch: set tss selector %X failed",new_tss_selector); + if (!cpu_tss.SetSelector(new_tss_selector)) { + LOG(LOG_CPU,LOG_NORMAL)("TaskSwitch: set tss selector %X failed",new_tss_selector); + } // cpu_tss.desc.SetBusy(true); // cpu_tss.SaveSelector(); // LOG_MSG("Task CPL %X CS:%X IP:%X SS:%X SP:%X eflags %x",cpu.cpl,SegValue(cs),reg_eip,SegValue(ss),reg_esp,reg_flags); @@ -717,8 +727,9 @@ do_interrupt: cpu.code.big=cs_desc.Big()>0; reg_eip=gate_off; - if (!(gate.Type()&1)) + if (!(gate.Type()&1)) { SETFLAGBIT(IF,false); + } SETFLAGBIT(TF,false); SETFLAGBIT(NT,false); SETFLAGBIT(VM,false); @@ -799,7 +810,9 @@ void CPU_IRET(bool use32,Bitu oldeip) { CPU_CHECK_COND(!cpu_tss.IsValid(), "TASK Iret without valid TSS", EXCEPTION_TS,cpu_tss.selector & 0xfffc) - if (!cpu_tss.desc.IsBusy()) LOG(LOG_CPU,LOG_ERROR)("TASK Iret:TSS not busy"); + if (!cpu_tss.desc.IsBusy()) { + LOG(LOG_CPU,LOG_ERROR)("TASK Iret:TSS not busy"); + } Bitu back_link=cpu_tss.Get_back(); CPU_SwitchTask(back_link,TSwitch_IRET,oldeip); return; @@ -1129,7 +1142,6 @@ call_code: CPU_CHECK_COND(n_cs_dpl>cpu.cpl, "CALL:Gate:CS DPL>CPL", EXCEPTION_GP,n_cs_sel & 0xfffc) - Bitu n_cs_rpl = n_cs_sel & 3; Bitu n_eip = call.GetOffset(); switch (n_cs_desc.Type()) { case DESC_CODE_N_NC_A:case DESC_CODE_N_NC_NA: @@ -2140,8 +2152,8 @@ public: Change_Config(configuration); return; } +// Section_prop * section=static_cast(configuration); inited=true; - Section_prop * section=static_cast(configuration); reg_eax=0; reg_ebx=0; reg_ecx=0; diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index 1da3ba23..4f389461 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_aspi_win32.cpp,v 1.18 2007-06-12 20:22:07 c2woody Exp $ */ +/* $Id: cdrom_aspi_win32.cpp,v 1.19 2008-08-06 18:32:34 c2woody Exp $ */ #if defined (WIN32) @@ -158,19 +158,23 @@ bool CDROM_Interface_Aspi::ScanRegistryFindKey(HKEY& hKeyBase) // Open Key... newKeyResult = RegOpenKeyEx (hKeyBase,subKey,0,KEY_READ,&hNewKey); if (newKeyResult==ERROR_SUCCESS) { - if (GetRegistryValue(hNewKey,"CurrentDriveLetterAssignment",buffer,256)) { + static const char drive_letter_assignment[] = "CurrentDriveLetterAssignment"; + if (GetRegistryValue(hNewKey,(char*)&drive_letter_assignment,buffer,256)) { LOG(LOG_MISC,LOG_NORMAL)("SCSI: Drive Letter found: %s",buffer); // aha, something suspicious... if (buffer[0]==letter) { char hardwareID[256]; // found it... lets see if we can get the scsi values - bool v1 = GetRegistryValue(hNewKey,"SCSILUN",buffer,256); + static const char SCSI_LUN[] = "SCSILUN"; + bool v1 = GetRegistryValue(hNewKey,(char*)SCSI_LUN,buffer,256); LOG(LOG_MISC,LOG_NORMAL)("SCSI: SCSILUN found: %s",buffer); lun = buffer[0]-'0'; - bool v2 = GetRegistryValue(hNewKey,"SCSITargetID",buffer,256); + static const char SCSI_TargetID[] = "SCSITargetID"; + bool v2 = GetRegistryValue(hNewKey,(char*)SCSI_TargetID,buffer,256); LOG(LOG_MISC,LOG_NORMAL)("SCSI: SCSITargetID found: %s",buffer); target = buffer[0]-'0'; - bool v3 = GetRegistryValue(hNewKey,"HardwareID",hardwareID,256); + static const char Hardware_ID[] = "HardwareID"; + bool v3 = GetRegistryValue(hNewKey,(char*)Hardware_ID,hardwareID,256); RegCloseKey(hNewKey); if (v1 && v2 && v3) { haId = GetHostAdapter(hardwareID); diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index cba56eb6..f5651495 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.97 2008-05-28 09:53:31 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.98 2008-08-06 18:32:34 c2woody Exp $ */ #include #include @@ -123,7 +123,7 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { continue; } - Bit32s iDown, cDots; + Bit32s iDown; bool dots = true; Bit32s templen=(Bit32s)strlen(tempdir); for(iDown=0;(iDown < templen) && dots;iDown++) @@ -131,13 +131,10 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { dots = false; // only dots? - cDots = templen - 1; - if(dots && (cDots > 0)) - { - for(iDown=(Bit32s)strlen(fullname)-1;iDown>=0;iDown--) - { - if(fullname[iDown]=='\\' || iDown==0) - { + if (dots && (templen > 1)) { + Bit32s cDots = templen - 1; + for(iDown=(Bit32s)strlen(fullname)-1;iDown>=0;iDown--) { + if(fullname[iDown]=='\\' || iDown==0) { lastdir = iDown; cDots--; if(cDots==0) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index e8487b76..8a03862f 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_keyboard_layout.cpp,v 1.12 2008-06-30 20:32:37 c2woody Exp $ */ +/* $Id: dos_keyboard_layout.cpp,v 1.13 2008-08-06 18:32:34 c2woody Exp $ */ #include "dosbox.h" #include "bios.h" @@ -249,38 +249,39 @@ Bitu keyboard_layout::read_keyboard_file(const char* keyboard_file_name, Bit32s Bit32u start_pos=5; char nbuf[512]; + read_buf_size = 0; sprintf(nbuf, "%s.kl", keyboard_file_name); FILE* tempfile = OpenDosboxFile(nbuf); if (tempfile==NULL) { // try keyboard layout libraries next - if (start_pos=read_kcl_file("keyboard.sys",keyboard_file_name,true)) { + if ((start_pos=read_kcl_file("keyboard.sys",keyboard_file_name,true))) { tempfile = OpenDosboxFile("keyboard.sys"); - } else if (start_pos=read_kcl_file("keybrd2.sys",keyboard_file_name,true)) { + } else if ((start_pos=read_kcl_file("keybrd2.sys",keyboard_file_name,true))) { tempfile = OpenDosboxFile("keybrd2.sys"); - } else if (start_pos=read_kcl_file("keybrd3.sys",keyboard_file_name,true)) { + } else if ((start_pos=read_kcl_file("keybrd3.sys",keyboard_file_name,true))) { tempfile = OpenDosboxFile("keybrd3.sys"); - } else if (start_pos=read_kcl_file("keyboard.sys",keyboard_file_name,false)) { + } else if ((start_pos=read_kcl_file("keyboard.sys",keyboard_file_name,false))) { tempfile = OpenDosboxFile("keyboard.sys"); - } else if (start_pos=read_kcl_file("keybrd2.sys",keyboard_file_name,false)) { + } else if ((start_pos=read_kcl_file("keybrd2.sys",keyboard_file_name,false))) { tempfile = OpenDosboxFile("keybrd2.sys"); - } else if (start_pos=read_kcl_file("keybrd3.sys",keyboard_file_name,false)) { + } else if ((start_pos=read_kcl_file("keybrd3.sys",keyboard_file_name,false))) { tempfile = OpenDosboxFile("keybrd3.sys"); - } else if (start_pos=read_kcl_data(layout_keyboardsys,33196,keyboard_file_name,true)) { + } else if ((start_pos=read_kcl_data(layout_keyboardsys,33196,keyboard_file_name,true))) { read_buf_size=0; for (Bitu ct=start_pos+2; ct<33196; ct++) read_buf[read_buf_size++]=layout_keyboardsys[ct]; - } else if (start_pos=read_kcl_data(layout_keybrd2sys,25431,keyboard_file_name,true)) { + } else if ((start_pos=read_kcl_data(layout_keybrd2sys,25431,keyboard_file_name,true))) { read_buf_size=0; for (Bitu ct=start_pos+2; ct<25431; ct++) read_buf[read_buf_size++]=layout_keybrd2sys[ct]; - } else if (start_pos=read_kcl_data(layout_keybrd3sys,27122,keyboard_file_name,true)) { + } else if ((start_pos=read_kcl_data(layout_keybrd3sys,27122,keyboard_file_name,true))) { read_buf_size=0; for (Bitu ct=start_pos+2; ct<27122; ct++) read_buf[read_buf_size++]=layout_keybrd3sys[ct]; - } else if (start_pos=read_kcl_data(layout_keyboardsys,33196,keyboard_file_name,false)) { + } else if ((start_pos=read_kcl_data(layout_keyboardsys,33196,keyboard_file_name,false))) { read_buf_size=0; for (Bitu ct=start_pos+2; ct<33196; ct++) read_buf[read_buf_size++]=layout_keyboardsys[ct]; - } else if (start_pos=read_kcl_data(layout_keybrd2sys,25431,keyboard_file_name,false)) { + } else if ((start_pos=read_kcl_data(layout_keybrd2sys,25431,keyboard_file_name,false))) { read_buf_size=0; for (Bitu ct=start_pos+2; ct<25431; ct++) read_buf[read_buf_size++]=layout_keybrd2sys[ct]; - } else if (start_pos=read_kcl_data(layout_keybrd3sys,27122,keyboard_file_name,false)) { + } else if ((start_pos=read_kcl_data(layout_keybrd3sys,27122,keyboard_file_name,false))) { read_buf_size=0; for (Bitu ct=start_pos+2; ct<27122; ct++) read_buf[read_buf_size++]=layout_keybrd3sys[ct]; } else { @@ -598,34 +599,34 @@ Bit16u keyboard_layout::extract_codepage(const char* keyboard_file_name) { FILE* tempfile = OpenDosboxFile(nbuf); if (tempfile==NULL) { // try keyboard layout libraries next - if (start_pos=read_kcl_file("keyboard.sys",keyboard_file_name,true)) { + if ((start_pos=read_kcl_file("keyboard.sys",keyboard_file_name,true))) { tempfile = OpenDosboxFile("keyboard.sys"); - } else if (start_pos=read_kcl_file("keybrd2.sys",keyboard_file_name,true)) { + } else if ((start_pos=read_kcl_file("keybrd2.sys",keyboard_file_name,true))) { tempfile = OpenDosboxFile("keybrd2.sys"); - } else if (start_pos=read_kcl_file("keybrd3.sys",keyboard_file_name,true)) { + } else if ((start_pos=read_kcl_file("keybrd3.sys",keyboard_file_name,true))) { tempfile = OpenDosboxFile("keybrd3.sys"); - } else if (start_pos=read_kcl_file("keyboard.sys",keyboard_file_name,false)) { + } else if ((start_pos=read_kcl_file("keyboard.sys",keyboard_file_name,false))) { tempfile = OpenDosboxFile("keyboard.sys"); - } else if (start_pos=read_kcl_file("keybrd2.sys",keyboard_file_name,false)) { + } else if ((start_pos=read_kcl_file("keybrd2.sys",keyboard_file_name,false))) { tempfile = OpenDosboxFile("keybrd2.sys"); - } else if (start_pos=read_kcl_file("keybrd3.sys",keyboard_file_name,false)) { + } else if ((start_pos=read_kcl_file("keybrd3.sys",keyboard_file_name,false))) { tempfile = OpenDosboxFile("keybrd3.sys"); - } else if (start_pos=read_kcl_data(layout_keyboardsys,33196,keyboard_file_name,true)) { + } else if ((start_pos=read_kcl_data(layout_keyboardsys,33196,keyboard_file_name,true))) { read_buf_size=0; for (Bitu ct=start_pos+2; ct<33196; ct++) read_buf[read_buf_size++]=layout_keyboardsys[ct]; - } else if (start_pos=read_kcl_data(layout_keybrd2sys,25431,keyboard_file_name,true)) { + } else if ((start_pos=read_kcl_data(layout_keybrd2sys,25431,keyboard_file_name,true))) { read_buf_size=0; for (Bitu ct=start_pos+2; ct<25431; ct++) read_buf[read_buf_size++]=layout_keybrd2sys[ct]; - } else if (start_pos=read_kcl_data(layout_keybrd3sys,27122,keyboard_file_name,true)) { + } else if ((start_pos=read_kcl_data(layout_keybrd3sys,27122,keyboard_file_name,true))) { read_buf_size=0; for (Bitu ct=start_pos+2; ct<27122; ct++) read_buf[read_buf_size++]=layout_keybrd3sys[ct]; - } else if (start_pos=read_kcl_data(layout_keyboardsys,33196,keyboard_file_name,false)) { + } else if ((start_pos=read_kcl_data(layout_keyboardsys,33196,keyboard_file_name,false))) { read_buf_size=0; for (Bitu ct=start_pos+2; ct<33196; ct++) read_buf[read_buf_size++]=layout_keyboardsys[ct]; - } else if (start_pos=read_kcl_data(layout_keybrd2sys,25431,keyboard_file_name,false)) { + } else if ((start_pos=read_kcl_data(layout_keybrd2sys,25431,keyboard_file_name,false))) { read_buf_size=0; for (Bitu ct=start_pos+2; ct<25431; ct++) read_buf[read_buf_size++]=layout_keybrd2sys[ct]; - } else if (start_pos=read_kcl_data(layout_keybrd3sys,27122,keyboard_file_name,false)) { + } else if ((start_pos=read_kcl_data(layout_keybrd3sys,27122,keyboard_file_name,false))) { read_buf_size=0; for (Bitu ct=start_pos+2; ct<27122; ct++) read_buf[read_buf_size++]=layout_keybrd3sys[ct]; } else { @@ -992,11 +993,11 @@ void keyboard_layout::switch_foreign_layout() { static keyboard_layout* loaded_layout=NULL; // CTRL-ALT-F2 switches between foreign and US-layout using this function -static void switch_keyboard_layout(bool pressed) { +/* static void switch_keyboard_layout(bool pressed) { if (!pressed) return; if (loaded_layout) loaded_layout->switch_foreign_layout(); -} +} */ // called by int9-handler bool DOS_LayoutKey(Bitu key, Bit8u flags1, Bit8u flags2, Bit8u flags3) { diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index ddf68a22..e695f7f8 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_misc.cpp,v 1.18 2007-11-07 22:08:03 c2woody Exp $ */ +/* $Id: dos_misc.cpp,v 1.19 2008-08-06 18:32:34 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" @@ -116,8 +116,7 @@ static bool DOS_MultiplexFunctions(void) { size_t nlen=strlen(filename); size_t extlen=strlen(dotpos); Bits nmelen=(Bits)nlen-(Bits)extlen; - nmelen--; - if (nmelen<0) return true; + if (nmelen<1) return true; nlen-=(extlen+1); if (nlen>8) nlen=8; diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 570ed64a..46e9384e 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.53 2008-02-19 17:45:33 c2woody Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.54 2008-08-06 18:32:34 c2woody Exp $ */ #include #include @@ -247,7 +247,7 @@ int CMscdex::RemoveDrive(Bit16u _drive) int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) { subUnit = 0; - if (GetNumDrives()+1>=MSCDEX_MAX_DRIVES) return 4; + if ((Bitu)GetNumDrives()+1>=MSCDEX_MAX_DRIVES) return 4; if (GetNumDrives()) { // Error check, driveletter have to be in a row if (dinfo[0].drive-1!=_drive && dinfo[numDrives-1].drive+1!=_drive) @@ -902,7 +902,7 @@ static Bit16u MSCDEX_IOCTL_Input(PhysPt buffer,Bit8u drive_unit) { break; case 0x0A : /* Get Audio Disk info */ Bit8u tr1,tr2; TMSF leadOut; - mscdex->GetCDInfo(drive_unit,tr1,tr2,leadOut); + if (!mscdex->GetCDInfo(drive_unit,tr1,tr2,leadOut)) return 0x05; mem_writeb(buffer+1,tr1); mem_writeb(buffer+2,tr2); mem_writeb(buffer+3,leadOut.fr); diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index c1097760..5478a55f 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.85 2008-03-11 18:16:34 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.86 2008-08-06 18:32:34 c2woody Exp $ */ #include "dosbox.h" #include @@ -976,8 +976,8 @@ public: WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW")); return; } - DOS_Drive * newdrive; - imageDisk * newImage; + DOS_Drive * newdrive = NULL; + imageDisk * newImage = NULL; Bit32u imagesize; char drive; std::string label; @@ -1050,27 +1050,27 @@ public: if(fstype=="fat" || fstype=="iso") { // get the drive letter if (!cmd->FindCommand(1,temp_line) || (temp_line.size() > 2) || ((temp_line.size()>1) && (temp_line[1]!=':'))) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_DRIVE")); + WriteOut_NoParsing(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_DRIVE")); return; } drive=toupper(temp_line[0]); if (!isalpha(drive)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_DRIVE")); + WriteOut_NoParsing(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_DRIVE")); return; } } else if (fstype=="none") { cmd->FindCommand(1,temp_line); if ((temp_line.size() > 1) || (!isdigit(temp_line[0]))) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY2")); + WriteOut_NoParsing(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY2")); return; } drive=temp_line[0]; - if((drive-'0')>3) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY2")); + if ((drive<'0') || (drive>3+'0')) { + WriteOut_NoParsing(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY2")); return; } } else { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FORMAT_UNSUPPORTED")); + WriteOut_NoParsing(MSG_Get("PROGRAM_IMGMOUNT_FORMAT_UNSUPPORTED")); return; } diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 4cf0a35f..1f852661 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.29 2007-07-20 18:53:52 qbix79 Exp $ */ +/* $Id: dos_tables.cpp,v 1.30 2008-08-06 18:32:34 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -43,7 +43,7 @@ static Bitu call_casemap; static Bit16u dos_memseg=DOS_PRIVATE_SEGMENT; Bit16u DOS_GetMemory(Bit16u pages) { - if (pages+dos_memseg>=DOS_PRIVATE_SEGMENT_END) { + if ((Bitu)pages+(Bitu)dos_memseg>=DOS_PRIVATE_SEGMENT_END) { E_Exit("DOS:Not enough memory for internal tables"); } Bit16u page=dos_memseg; diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index d2d6fc5b..3fe88e2e 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -1,6 +1,5 @@ - /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -17,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.52 2007-11-02 07:50:27 qbix79 Exp $ */ +/* $Id: drive_cache.cpp,v 1.53 2008-08-06 18:32:34 c2woody Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -193,7 +192,7 @@ char* DOS_Drive_Cache::GetExpandName(const char* path) strcat(work,dir); } - if(work && *work) { + if (*work) { size_t len = strlen(work); #if defined (WIN32) if((work[len-1] == CROSS_FILESPLIT ) && (len >= 2) && (work[len-2] != ':')) { diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 5eab57af..0b68d083 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.25 2008-02-24 17:38:03 c2woody Exp $ */ +/* $Id: drive_fat.cpp,v 1.26 2008-08-06 18:32:34 c2woody Exp $ */ #include #include @@ -866,25 +866,22 @@ bool fatDrive::FindFirst(char *_dir, DOS_DTA &dta,bool /*fcb_findfirst*/) { return FindNextInternal(cwdDirCluster, dta, &dummyClust); } -char* removeTrailingSpaces(char* str) -{ - char* end = str + strlen(str); - while(*--end == ' ' && end > str); - *++end = '\0'; - return str; +char* removeTrailingSpaces(char* str) { + char* end = str + strlen(str); + while((*--end == ' ') && (end > str)) {}; + *++end = '\0'; + return str; } -char* removeLeadingSpaces(char* str) -{ - size_t len = strlen(str); - size_t pos = strspn(str," "); - memmove(str,str + pos,len - pos + 1); - return str; +char* removeLeadingSpaces(char* str) { + size_t len = strlen(str); + size_t pos = strspn(str," "); + memmove(str,str + pos,len - pos + 1); + return str; } -char* trimString(char* str) -{ - return removeTrailingSpaces(removeLeadingSpaces(str)); +char* trimString(char* str) { + return removeTrailingSpaces(removeLeadingSpaces(str)); } bool fatDrive::FindNextInternal(Bit32u dirClustNumber, DOS_DTA &dta, direntry *foundEntry) { diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index e4042a49..ec788d6d 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_win32.h,v 1.14 2007-06-14 08:23:46 qbix79 Exp $ */ +/* $Id: midi_win32.h,v 1.15 2008-08-06 18:32:34 c2woody Exp $ */ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN @@ -33,12 +33,12 @@ private: HANDLE m_event; bool isOpen; public: - MidiHandler_win32() : isOpen(false),MidiHandler() {}; + MidiHandler_win32() : MidiHandler(),isOpen(false) {}; const char * GetName(void) { return "win32";}; bool Open(const char * conf) { if (isOpen) return false; m_event = CreateEvent (NULL, true, true, NULL); - MMRESULT res; + MMRESULT res = MMSYSERR_NOERROR; if(conf && *conf) { std::string strconf(conf); std::istringstream configmidi(strconf); diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 698a8376..7b0f9cfd 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.56 2008-02-10 11:14:03 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.57 2008-08-06 18:32:34 c2woody Exp $ */ #include #include @@ -282,7 +282,7 @@ static void RENDER_Reset( void ) { gfx_scalew = 1; gfx_scaleh = 1; } - if (dblh && dblw || (render.scale.forced && !dblh && !dblw)) { + if ((dblh && dblw) || (render.scale.forced && !dblh && !dblw)) { /* Initialize always working defaults */ if (render.scale.size == 2) simpleBlock = &ScaleNormal2x; @@ -343,6 +343,8 @@ static void RENDER_Reset( void ) { else if (render.scale.size == 3) simpleBlock = &ScaleScan3x; break; + default: + break; } #endif } else if (dblw) { diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index b54375e3..938b5a08 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_gui.cpp,v 1.6 2008-02-21 19:25:34 c2woody Exp $ */ +/* $Id: sdl_gui.cpp,v 1.7 2008-08-06 18:32:34 c2woody Exp $ */ #include "SDL.h" #include "../libs/gui_tk/gui_tk.h" @@ -52,10 +52,10 @@ void UI_Init(void) { GUI::Font::addFont("default",new GUI::BitmapFont(int10_font_14,14,10)); } -static void getPixel(Bitu x, Bitu y, int &r, int &g, int &b, int shift) +static void getPixel(Bits x, Bits y, int &r, int &g, int &b, int shift) { - if (x >= render.src.width) x = render.src.width-1; - if (y >= render.src.height) x = render.src.height-1; + if (x >= (Bits)render.src.width) x = (Bits)render.src.width-1; + if (y >= (Bits)render.src.height) x = (Bits)render.src.height-1; if (x < 0) x = 0; if (y < 0) y = 0; @@ -159,7 +159,7 @@ static GUI::ScreenSDL *UI_Startup(GUI::ScreenSDL *screen) { SDL_BlitSurface(background, NULL, sdlscreen, NULL); SDL_BlitSurface(screenshot, NULL, sdlscreen, NULL); SDL_UpdateRect(sdlscreen, 0, 0, 0, 0); - while (SDL_PollEvent(&event)); + while (SDL_PollEvent(&event)) {}; SDL_Delay(40); } @@ -187,7 +187,7 @@ static void UI_Shutdown(GUI::ScreenSDL *screen) { SDL_BlitSurface(background, NULL, sdlscreen, NULL); SDL_BlitSurface(screenshot, NULL, sdlscreen, NULL); SDL_UpdateRect(sdlscreen, 0, 0, 0, 0); - while (SDL_PollEvent(&event)); + while (SDL_PollEvent(&event)) {}; SDL_Delay(40); } diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index ab4f18f1..34c28517 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.143 2008-05-28 09:14:06 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.144 2008-08-06 18:32:34 c2woody Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -260,7 +260,9 @@ check_surface: else if (flags & GFX_LOVE_16) testbpp=16; else if (flags & GFX_LOVE_32) testbpp=32; else testbpp=0; +#if (HAVE_DDRAW_H) && defined(WIN32) check_gotbpp: +#endif if (sdl.desktop.fullscreen) gotbpp=SDL_VideoModeOK(640,480,testbpp,SDL_FULLSCREEN|SDL_HWSURFACE|SDL_HWPALETTE); else gotbpp=sdl.desktop.bpp; /* If we can't get our favorite mode check for another working one */ @@ -303,6 +305,9 @@ check_gotbpp: flags&=~(GFX_CAN_8|GFX_CAN_15|GFX_CAN_16); break; #endif + default: + goto check_surface; + break; } return flags; } @@ -611,6 +616,9 @@ dosurface: break; }//OPENGL #endif //C_OPENGL + default: + goto dosurface; + break; }//CASE if (retFlags) GFX_Start(); @@ -698,13 +706,17 @@ bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) { sdl.updating=true; return true; #endif + default: + break; } return false; } void GFX_EndUpdate( const Bit16u *changedLines ) { +#if (HAVE_DDRAW_H) && defined(WIN32) int ret; +#endif if (!sdl.updating) return; sdl.updating=false; @@ -800,7 +812,8 @@ void GFX_EndUpdate( const Bit16u *changedLines ) { } break; #endif - + default: + break; } } diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 0c5db85a..02031a6b 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: adlib.cpp,v 1.31 2008-08-06 18:32:35 c2woody Exp $ */ + #include #include #include @@ -364,6 +366,8 @@ static void OPL_CallBack(Bitu len) { } opl.chan->AddSamples_s16(len,(Bit16s*)MixTemp); break; + default: + break; } if ((PIC_Ticks-opl.last_used)>30000) { opl.chan->Enable(false); @@ -380,6 +384,8 @@ static Bitu OPL_Read(Bitu port,Bitu iolen) { return OPL2::YM3812Read(addr>>1,addr); case OPL_opl3: return THEOPL3::YMF262Read(0,addr); + default: + break; } return 0xff; } @@ -411,6 +417,8 @@ void OPL_Write(Bitu port,Bitu val,Bitu iolen) { case OPL_dualopl2: OPL2::YM3812Write( index,port,val); break; + default: + break; } } diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 01f187de..8e7d7921 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: hardware.cpp,v 1.18 2007-01-08 19:45:40 qbix79 Exp $ */ +/* $Id: hardware.cpp,v 1.19 2008-08-06 18:32:35 c2woody Exp $ */ #include #include @@ -147,10 +147,10 @@ static void CAPTURE_AddAviChunk(const char * tag, Bit32u size, void * data, Bit3 } #endif +#if (C_SSHOT) static void CAPTURE_VideoEvent(bool pressed) { if (!pressed) return; -#if (C_SSHOT) if (CaptureState & CAPTURE_VIDEO) { /* Close the video */ CaptureState &= ~CAPTURE_VIDEO; @@ -283,12 +283,12 @@ static void CAPTURE_VideoEvent(bool pressed) { } else { CaptureState |= CAPTURE_VIDEO; } -#endif } +#endif void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags, float fps, Bit8u * data, Bit8u * pal) { - Bitu i; #if (C_SSHOT) + Bitu i; Bit8u doubleRow[SCALER_MAXWIDTH*4]; Bitu countWidth = width; @@ -543,11 +543,13 @@ skip_video: } +#if (C_SSHOT) static void CAPTURE_ScreenShotEvent(bool pressed) { if (!pressed) return; CaptureState |= CAPTURE_IMAGE; } +#endif /* WAV capturing */ diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 112433ac..077d6e48 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.67 2007-09-20 16:42:43 c2woody Exp $ */ +/* $Id: sblaster.cpp,v 1.68 2008-08-06 18:32:35 c2woody Exp $ */ #include #include @@ -226,6 +226,8 @@ static INLINE void SB_RaiseIRQ(SB_IRQS type) { case SB_IRQ_16: sb.irq.pending_16bit=true; break; + default: + break; } } @@ -470,6 +472,7 @@ static void GenerateDMASound(Bitu size) { } } +/* old version... static void GenerateDACSound(Bitu len) { if (!sb.dac.used) { sb.mode=MODE_NONE; @@ -485,6 +488,7 @@ static void GenerateDACSound(Bitu len) { sb.dac.used=0; sb.chan->AddSamples_m16(len,(Bit16s *)MixTemp); } +*/ static void DMA_Silent_Event(Bitu val) { if (sb.dma.leftGet_int("dma"); sb.hw.dma16=section->Get_int("hdma"); sb.mixer.enabled=section->Get_bool("mixer"); - Bitu oplrate=section->Get_int("oplrate"); sb.mixer.stereo=false; OPL_Mode opl_mode = OPL_none; Find_Type_And_Opl(section,sb.type,opl_mode); diff --git a/src/hardware/serialport/directserial_win32.cpp b/src/hardware/serialport/directserial_win32.cpp index 7b4d9c83..dc9de4b4 100644 --- a/src/hardware/serialport/directserial_win32.cpp +++ b/src/hardware/serialport/directserial_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_win32.cpp,v 1.6 2008-07-14 20:06:19 qbix79 Exp $ */ +/* $Id: directserial_win32.cpp,v 1.7 2008-08-06 18:33:30 c2woody Exp $ */ #include "dosbox.h" @@ -96,7 +96,7 @@ CDirectSerial::CDirectSerial (Bitu id, CommandLine* cmd) if (!fSuccess) { // Handle the error. - LOG_MSG ("GetCommState failed with error %d.\n", GetLastError ()); + LOG_MSG ("GetCommState failed with error %d.\n", (int)GetLastError ()); hCom = INVALID_HANDLE_VALUE; return; } @@ -125,7 +125,7 @@ CDirectSerial::CDirectSerial (Bitu id, CommandLine* cmd) if (!fSuccess) { // Handle the error. - LOG_MSG ("SetCommState failed with error %d.\n", GetLastError ()); + LOG_MSG ("SetCommState failed with error %d.\n", (int)GetLastError ()); hCom = INVALID_HANDLE_VALUE; return; } @@ -157,7 +157,6 @@ void CDirectSerial::handleUpperEvent(Bit16u type) { switch(type) { case SERIAL_POLLING_EVENT: { DWORD dwRead = 0; - DWORD errors = 0; Bit8u chRead = 0; setEvent(SERIAL_POLLING_EVENT, 1); @@ -329,12 +328,12 @@ void CDirectSerial::updatePortConfig (Bit16u divider, Bit8u lcr) { #endif LOG_MSG ("Serial%d: Desired serial mode not supported (%d,%d,%d,%d", - dcb.BaudRate,dcb.ByteSize,dcb.Parity,dcb.StopBits, COMNUMBER); + (Bit32u)dcb.BaudRate,(Bit32u)dcb.ByteSize, + (Bit32u)dcb.Parity,(Bit32u)dcb.StopBits, COMNUMBER); } } void CDirectSerial::updateMSR () { - Bit8u newmsr = 0; DWORD dptr = 0; if (!GetCommModemStatus (hCom, &dptr)) { diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index a35c4d03..1b1651d7 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.cpp,v 1.9 2008-07-14 20:06:19 qbix79 Exp $ */ +/* $Id: serialport.cpp,v 1.10 2008-08-06 18:33:30 c2woody Exp $ */ + #include #include @@ -939,8 +940,7 @@ void CSerial::Init_Registers () { Bit32u initbps = 9600; Bit8u bytesize = 8; - char parity = 'N'; - Bit8u stopbits = 1; + char parity = 'N'; Bit8u lcrresult = 0; Bit16u baudresult = 0; diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 2d95fd74..c1fab73c 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga.cpp,v 1.34 2008-02-06 18:23:34 c2woody Exp $ */ +/* $Id: vga.cpp,v 1.35 2008-08-06 18:32:35 c2woody Exp $ */ #include "dosbox.h" //#include "setup.h" @@ -100,6 +100,8 @@ void VGA_SetClock(Bitu which,Bitu target) { Bits err; } best; best.err=target; + best.m=1; + best.n=1; Bitu n,r; Bits m; diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 9528ef46..4f91ea17 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.102 2008-06-08 18:27:25 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.103 2008-08-06 18:32:35 c2woody Exp $ */ #include #include @@ -204,14 +204,14 @@ static Bit8u * VGA_Draw_Xlat16_Linear_Line(Bitu vidstart, Bitu line) { } //Test version, might as well keep it -static Bit8u * VGA_Draw_Chain_Line(Bitu vidstart, Bitu line) { +/* static Bit8u * VGA_Draw_Chain_Line(Bitu vidstart, Bitu line) { Bitu i = 0; for ( i = 0; i < vga.draw.width;i++ ) { Bitu addr = vidstart + i; TempLine[i] = vga.mem.linear[((addr&~3)<<2)+(addr&3)]; } return TempLine; -} +} */ static Bit8u * VGA_Draw_VGA_Line_HWMouse( Bitu vidstart, Bitu line) { bool hwcursor_active=false; @@ -430,8 +430,8 @@ static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart, Bitu line) { Bit32u mask2=TXT_Font_Table[font&0xf] & FontMask[col >> 7]; Bit32u fg=TXT_FG_Table[col&0xf]; Bit32u bg=TXT_BG_Table[col>>4]; - *draw++=fg&mask1 | bg&~mask1; - *draw++=fg&mask2 | bg&~mask2; + *draw++=(fg&mask1) | (bg&~mask1); + *draw++=(fg&mask2) | (bg&~mask2); } if (!vga.draw.cursor.enabled || !(vga.draw.cursor.count&0x8)) goto skip_cursor; font_addr = (vga.draw.cursor.address-vidstart) >> 1; @@ -459,8 +459,8 @@ static Bit8u * VGA_TEXT_Xlat16_Draw_Line(Bitu vidstart, Bitu line) { Bit32u fg=TXT_FG_Table[col&0xf]; Bit32u bg=TXT_BG_Table[col>>4]; - mask1=fg&mask1 | bg&~mask1; - mask2=fg&mask2 | bg&~mask2; + mask1=(fg&mask1) | (bg&~mask1); + mask2=(fg&mask2) | (bg&~mask2); for(int i = 0; i < 4; i++) { *draw++ = vga.dac.xlat16[(mask1>>8*i)&0xff]; @@ -484,6 +484,7 @@ skip_cursor: return TempLine; } +/* static Bit8u * VGA_TEXT_Draw_Line_9(Bitu vidstart, Bitu line) { Bits font_addr; Bit8u * draw=(Bit8u *)TempLine; @@ -541,6 +542,7 @@ static Bit8u * VGA_TEXT_Draw_Line_9(Bitu vidstart, Bitu line) { skip_cursor: return TempLine; } +*/ static Bit8u * VGA_TEXT_Xlat16_Draw_Line_9(Bitu vidstart, Bitu line) { Bits font_addr; @@ -852,6 +854,8 @@ static void VGA_VerticalTimer(Bitu val) { case M_TANDY2:case M_TANDY4:case M_TANDY16: vga.draw.address *= 2; break; + default: + break; } if (GCC_UNLIKELY(vga.draw.split_line==0)) VGA_ProcessSplit(); #ifdef VGA_KEEP_CHANGES @@ -904,6 +908,9 @@ void VGA_CheckScanLength(void) { case M_HERC_GFX: vga.draw.address_add=vga.draw.blocks; break; + default: + vga.draw.address_add=vga.draw.blocks*8; + break; } } @@ -1003,6 +1010,7 @@ void VGA_SetupDrawing(Bitu val) { clock = (machine==MCH_EGA) ? 14318180 : 25175000; break; case 1: + default: clock = (machine==MCH_EGA) ? 16257000 : 28322000; break; } @@ -1055,6 +1063,9 @@ void VGA_SetupDrawing(Bitu val) { if (vga.herc.mode_control & 0x2) clock=14318180/16; else clock=14318180/8; break; + default: + clock = 14318180; + break; } } #if C_DEBUG @@ -1130,6 +1141,7 @@ void VGA_SetupDrawing(Bitu val) { pheight = (480.0 / 350.0) * ( target_total / vtotal ); break; case 3: //480 line mode, filled with 525 total + default: pheight = (480.0 / 480.0) * ( 525.0 / vtotal ); break; } diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index c0f7da4c..45f8b0eb 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_memory.cpp,v 1.50 2008-03-16 18:53:33 c2woody Exp $ */ +/* $Id: vga_memory.cpp,v 1.51 2008-08-06 18:32:35 c2woody Exp $ */ #include #include @@ -182,7 +182,7 @@ public: return vga.mem.linear[addr]; } void writeHandler(PhysPt start, Bit8u val) { - Bit32u data=ModeOperation(val); + ModeOperation(val); /* Update video memory and the pixel buffer */ VGA_Latch pixels; vga.mem.linear[start] = val; @@ -802,6 +802,7 @@ void VGA_SetupHandlers(void) { /* This should be vga only */ switch (vga.mode) { case M_ERROR: + default: return; case M_LIN4: newHandler = &vgaph.lin4; diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 73639261..64c1d8ac 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_other.cpp,v 1.22 2008-04-21 19:55:02 c2woody Exp $ */ +/* $Id: vga_other.cpp,v 1.23 2008-08-06 18:32:35 c2woody Exp $ */ #include #include @@ -456,10 +456,10 @@ static void write_hercules(Bitu port,Bitu val,Bitu iolen) { } } -static Bitu read_hercules(Bitu port,Bitu iolen) { +/* static Bitu read_hercules(Bitu port,Bitu iolen) { LOG_MSG("read from Herc port %x",port); return 0; -} +} */ void VGA_SetupOther(void) { diff --git a/src/hardware/vga_paradise.cpp b/src/hardware/vga_paradise.cpp index 6ce124f3..d84ccc36 100644 --- a/src/hardware/vga_paradise.cpp +++ b/src/hardware/vga_paradise.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_paradise.cpp,v 1.2 2008-01-12 17:37:48 c2woody Exp $ */ +/* $Id: vga_paradise.cpp,v 1.3 2008-08-06 18:32:35 c2woody Exp $ */ #include "dosbox.h" #include "setup.h" @@ -39,7 +39,7 @@ typedef struct { Bitu biosMode; } SVGA_PVGA1A_DATA; -static SVGA_PVGA1A_DATA pvga1a = { 0, 0, 0, 0, 0, 0, 0 }; +static SVGA_PVGA1A_DATA pvga1a = { 0,0, 0,0,0,0,0, {0,0,0,0}, 0 }; static void bank_setup_pvga1a() { diff --git a/src/hardware/vga_tseng.cpp b/src/hardware/vga_tseng.cpp index b328ea92..678b6261 100644 --- a/src/hardware/vga_tseng.cpp +++ b/src/hardware/vga_tseng.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_tseng.cpp,v 1.3 2008-02-26 08:55:29 qbix79 Exp $ */ +/* $Id: vga_tseng.cpp,v 1.4 2008-08-06 18:32:35 c2woody Exp $ */ #include "dosbox.h" @@ -50,7 +50,8 @@ typedef struct { Bitu biosMode; } SVGA_ET4K_DATA; -static SVGA_ET4K_DATA et4k = { 1, 0, /* the rest are 0s */ }; +static SVGA_ET4K_DATA et4k = { 1,0,0,0,0,0,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 STORE_ET4K(port, index) \ case 0x##index: \ @@ -486,7 +487,7 @@ typedef struct { Bitu biosMode; } SVGA_ET3K_DATA; -static SVGA_ET3K_DATA et3k = { 0 /* and the rest are 0s as well */ }; +static SVGA_ET3K_DATA et3k = { 0,0,0,0,0,0,0,0,0,0, 0,0, 0,0, {0,0,0,0,0,0,0,0}, 0 }; #define STORE_ET3K(port, index) \ case 0x##index: \ diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index 1b11b7e0..9c10497e 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_xga.cpp,v 1.12 2008-01-12 17:37:48 c2woody Exp $ */ +/* $Id: vga_xga.cpp,v 1.13 2008-08-06 18:32:35 c2woody Exp $ */ #include #include "dosbox.h" @@ -774,6 +774,7 @@ void XGA_BlitRect(Bitu val) { break; default: LOG_MSG("XGA: DrawPattern: Shouldn't be able to get here!"); + srcval = 0; break; } @@ -859,6 +860,7 @@ void XGA_DrawPattern(Bitu val) { break; default: LOG_MSG("XGA: DrawPattern: Shouldn't be able to get here!"); + srcval = 0; break; } diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index de42895d..00daf8e0 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.71 2008-07-19 13:28:03 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.72 2008-08-06 18:32:35 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -624,8 +624,8 @@ static Bitu INT15_Handler(void) { MEM_A20_Enable(true); Bitu bytes = reg_cx * 2; PhysPt data = SegPhys(es)+reg_si; - PhysPt source = mem_readd(data+0x12) & 0x00FFFFFF + (mem_readb(data+0x16)<<24); - PhysPt dest = mem_readd(data+0x1A) & 0x00FFFFFF + (mem_readb(data+0x1E)<<24); + PhysPt source = (mem_readd(data+0x12) & 0x00FFFFFF) + (mem_readb(data+0x16)<<24); + PhysPt dest = (mem_readd(data+0x1A) & 0x00FFFFFF) + (mem_readb(data+0x1E)<<24); MEM_BlockCopy(dest,source,bytes); reg_ax = 0x00; MEM_A20_Enable(enabled); diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 3ea702ce..06e3a2a9 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.56 2007-11-01 12:11:40 qbix79 Exp $ */ +/* $Id: ems.cpp,v 1.57 2008-08-06 18:32:35 c2woody Exp $ */ #include #include @@ -1029,7 +1029,7 @@ static Bitu V86_Monitor() { Bitu which=(rm_val >> 3) & 7; if ((rm_val<0xc0) || (rm_val>=0xe8)) E_Exit("Invalid opcode 0x0f 0x22 %x caused a protection fault!",rm_val); - Bit32u crx; + Bit32u crx=0; switch (rm_val&7) { case 0: crx=reg_eax; break; case 1: crx=reg_ecx; break; diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 418d344b..db139849 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.78 2008-05-10 17:33:28 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.79 2008-08-06 18:32:35 c2woody Exp $ */ #include @@ -248,14 +248,14 @@ static Bit8u text_palette[64][3]= static Bit8u mtext_palette[64][3]= { - 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, - 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, - 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, - 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, - 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, - 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, - 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, - 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f + {0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00}, + {0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a}, + {0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a}, + {0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f}, + {0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00}, + {0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a}, + {0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a}, + {0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f} }; static Bit8u ega_palette[64][3]= diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 9770c4c7..7d77412d 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_put_pixel.cpp,v 1.21 2008-06-14 19:31:04 qbix79 Exp $ */ +/* $Id: int10_put_pixel.cpp,v 1.22 2008-08-06 18:32:35 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -41,7 +41,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { color&=3; old^=color << (2*(3-(x&3))); } else { - old=old&cga_masks[x&3]|((color&3) << (2*(3-(x&3)))); + old=(old&cga_masks[x&3])|((color&3) << (2*(3-(x&3)))); } real_writeb(0xb800,off,old); } else { @@ -53,7 +53,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { old^=(color&1) << (7-(x&7)); old^=((color&2)>>1) << ((7-(x&7))+8); } else { - old=old&(~(0x101<<(7-(x&7)))) | ((color&1) << (7-(x&7))) | (((color&2)>>1) << ((7-(x&7))+8)); + old=(old&(~(0x101<<(7-(x&7))))) | ((color&1) << (7-(x&7))) | (((color&2)>>1) << ((7-(x&7))+8)); } real_writew(0xb800,off,old); } @@ -68,7 +68,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { color&=1; old^=color << ((7-(x&7))); } else { - old=old&cga_masks2[x&7]|((color&1) << ((7-(x&7)))); + old=(old&cga_masks2[x&7])|((color&1) << ((7-(x&7)))); } real_writeb(0xb800,off,old); } @@ -106,9 +106,9 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { if (color & 0x80) { IO_Write(0x3ce,0x3);IO_Write(0x3cf,0x18); } //Perhaps also set mode 1 /* Calculate where the pixel is in video memory */ - if (CurMode->plength!=real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)) + if (CurMode->plength!=(Bitu)real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)) LOG(LOG_INT10,LOG_ERROR)("PutPixel_EGA_p: %x!=%x",CurMode->plength,real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)); - if (CurMode->swidth!=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8) + if (CurMode->swidth!=(Bitu)real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8) LOG(LOG_INT10,LOG_ERROR)("PutPixel_EGA_w: %x!=%x",CurMode->swidth,real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); PhysPt off=0xa0000+real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)*page+ ((y*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8+x)>>3); @@ -127,7 +127,7 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { mem_writeb(PhysMake(0xa000,y*320+x),color); break; case M_LIN8: { - if (CurMode->swidth!=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8) + if (CurMode->swidth!=(Bitu)real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8) LOG(LOG_INT10,LOG_ERROR)("PutPixel_VGA_w: %x!=%x",CurMode->swidth,real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); PhysPt off=S3_LFB_BASE+y*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8+x; mem_writeb(off,color); @@ -149,7 +149,7 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { Bit16u off=(y>>1)*80+(x>>2); if (y&1) off+=8*1024; Bit8u val=real_readb(0xb800,off); - *color=(val>>(((3-x&3))*2)) & 3 ; + *color=(val>>(((3-(x&3)))*2)) & 3 ; } break; case M_CGA2: @@ -157,15 +157,15 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { Bit16u off=(y>>1)*80+(x>>3); if (y&1) off+=8*1024; Bit8u val=real_readb(0xb800,off); - *color=(val>>(((7-x&7)))) & 1 ; + *color=(val>>(((7-(x&7))))) & 1 ; } break; case M_EGA: { /* Calculate where the pixel is in video memory */ - if (CurMode->plength!=real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)) + if (CurMode->plength!=(Bitu)real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)) LOG(LOG_INT10,LOG_ERROR)("GetPixel_EGA_p: %x!=%x",CurMode->plength,real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)); - if (CurMode->swidth!=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8) + if (CurMode->swidth!=(Bitu)real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8) LOG(LOG_INT10,LOG_ERROR)("GetPixel_EGA_w: %x!=%x",CurMode->swidth,real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); PhysPt off=0xa0000+real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)*page+ ((y*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8+x)>>3); @@ -186,7 +186,7 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { *color=mem_readb(PhysMake(0xa000,320*y+x)); break; case M_LIN8: { - if (CurMode->swidth!=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8) + if (CurMode->swidth!=(Bitu)real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8) LOG(LOG_INT10,LOG_ERROR)("GetPixel_VGA_w: %x!=%x",CurMode->swidth,real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); PhysPt off=S3_LFB_BASE+y*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8+x; *color = mem_readb(off); diff --git a/src/ints/int10_video_state.cpp b/src/ints/int10_video_state.cpp index 0d83a902..50d55950 100644 --- a/src/ints/int10_video_state.cpp +++ b/src/ints/int10_video_state.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: */ +/* $Id: int10_video_state.cpp,v 1.2 2008-08-06 18:32:35 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -178,7 +178,8 @@ bool INT10_VideoState_Save(Bitu state,RealPt buffer) { Bit16u crt_reg=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); IO_WriteB(0x3c4,0x08); - Bitu seq_8=IO_ReadB(0x3c5); +// Bitu seq_8=IO_ReadB(0x3c5); + IO_ReadB(0x3c5); // real_writeb(base_seg,base_dest+0x00,IO_ReadB(0x3c5)); IO_WriteB(0x3c5,0x06); // unlock s3-specific registers @@ -332,7 +333,8 @@ bool INT10_VideoState_Restore(Bitu state,RealPt buffer) { Bitu seq_idx=IO_ReadB(0x3c4); IO_WriteB(0x3c4,0x08); - Bitu seq_8=IO_ReadB(0x3c5); +// Bitu seq_8=IO_ReadB(0x3c5); + IO_ReadB(0x3c5); // real_writeb(base_seg,base_dest+0x00,IO_ReadB(0x3c5)); IO_WriteB(0x3c5,0x06); // unlock s3-specific registers @@ -342,7 +344,7 @@ bool INT10_VideoState_Restore(Bitu state,RealPt buffer) { } IO_WriteB(0x3c4,seq_idx); - Bitu crtc_idx=IO_ReadB(0x3d4); +// Bitu crtc_idx=IO_ReadB(0x3d4); // unlock s3-specific registers IO_WriteW(crt_reg,0x4838); diff --git a/src/ints/int10_vptable.cpp b/src/ints/int10_vptable.cpp index ad6d0692..8b6d9ab0 100644 --- a/src/ints/int10_vptable.cpp +++ b/src/ints/int10_vptable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vptable.cpp,v 1.1 2007-10-08 20:22:13 c2woody Exp $ */ +/* $Id: int10_vptable.cpp,v 1.2 2008-08-06 18:32:35 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -489,7 +489,7 @@ void INT10_GenerateVideoParameterTable(void) { } LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // sequencer registers",seq_regs[0],seq_regs[1],seq_regs[2],seq_regs[3]); LOG_MSG(" 0x%02x, // misc output registers",IO_ReadB(0x3cc)); - Bitu crtc_regs[4]; + Bitu crtc_regs[0x19]; Bit16u crt_addr=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); for (ct=0; ct<0x19; ct++) { IO_WriteB(crt_addr,ct); @@ -504,7 +504,7 @@ void INT10_GenerateVideoParameterTable(void) { LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 16-24", crtc_regs[0x10],crtc_regs[0x11],crtc_regs[0x12],crtc_regs[0x13], crtc_regs[0x14],crtc_regs[0x15],crtc_regs[0x16],crtc_regs[0x17],crtc_regs[0x18]); - Bitu attr_regs[4]; + Bitu attr_regs[0x14]; for (ct=0; ct<0x14; ct++) { IO_ReadB(crt_addr+6); IO_WriteB(0x3c0,ct); @@ -518,7 +518,7 @@ void INT10_GenerateVideoParameterTable(void) { attr_regs[0x0c],attr_regs[0x0d],attr_regs[0x0e],attr_regs[0x0f]); LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 16-19", attr_regs[0x10],attr_regs[0x11],attr_regs[0x12],attr_regs[0x13]); - Bitu gfx_regs[4]; + Bitu gfx_regs[9]; for (ct=0; ct<0x09; ct++) { IO_WriteB(0x3ce,ct); gfx_regs[ct]=IO_ReadB(0x3cf); @@ -547,7 +547,7 @@ void INT10_GenerateVideoParameterTable(void) { } LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // sequencer registers",seq_regs[0],seq_regs[1],seq_regs[2],seq_regs[3]); LOG_MSG(" 0x%02x, // misc output registers",IO_ReadB(0x3cc)); - Bitu crtc_regs[4]; + Bitu crtc_regs[0x19]; Bit16u crt_addr=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); for (ct=0; ct<0x19; ct++) { IO_WriteB(crt_addr,ct); @@ -562,7 +562,7 @@ void INT10_GenerateVideoParameterTable(void) { LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 16-24", crtc_regs[0x10],crtc_regs[0x11],crtc_regs[0x12],crtc_regs[0x13], crtc_regs[0x14],crtc_regs[0x15],crtc_regs[0x16],crtc_regs[0x17],crtc_regs[0x18]); - Bitu attr_regs[4]; + Bitu attr_regs[0x14]; for (ct=0; ct<0x14; ct++) { IO_ReadB(crt_addr+6); IO_WriteB(0x3c0,ct); @@ -576,7 +576,7 @@ void INT10_GenerateVideoParameterTable(void) { attr_regs[0x0c],attr_regs[0x0d],attr_regs[0x0e],attr_regs[0x0f]); LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 16-19", attr_regs[0x10],attr_regs[0x11],attr_regs[0x12],attr_regs[0x13]); - Bitu gfx_regs[4]; + Bitu gfx_regs[9]; for (ct=0; ct<0x09; ct++) { IO_WriteB(0x3ce,ct); gfx_regs[ct]=IO_ReadB(0x3cf); @@ -604,7 +604,7 @@ void INT10_GenerateVideoParameterTable(void) { } LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // sequencer registers",seq_regs[0],seq_regs[1],seq_regs[2],seq_regs[3]); LOG_MSG(" 0x%02x, // misc output registers",IO_ReadB(0x3cc)); - Bitu crtc_regs[4]; + Bitu crtc_regs[0x19]; Bit16u crt_addr=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); for (ct=0; ct<0x19; ct++) { IO_WriteB(crt_addr,ct); @@ -619,7 +619,7 @@ void INT10_GenerateVideoParameterTable(void) { LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 16-24", crtc_regs[0x10],crtc_regs[0x11],crtc_regs[0x12],crtc_regs[0x13], crtc_regs[0x14],crtc_regs[0x15],crtc_regs[0x16],crtc_regs[0x17],crtc_regs[0x18]); - Bitu attr_regs[4]; + Bitu attr_regs[0x14]; for (ct=0; ct<0x14; ct++) { IO_ReadB(crt_addr+6); IO_WriteB(0x3c0,ct); @@ -633,7 +633,7 @@ void INT10_GenerateVideoParameterTable(void) { attr_regs[0x0c],attr_regs[0x0d],attr_regs[0x0e],attr_regs[0x0f]); LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 16-19", attr_regs[0x10],attr_regs[0x11],attr_regs[0x12],attr_regs[0x13]); - Bitu gfx_regs[4]; + Bitu gfx_regs[9]; for (ct=0; ct<0x09; ct++) { IO_WriteB(0x3ce,ct); gfx_regs[ct]=IO_ReadB(0x3cf); @@ -659,7 +659,7 @@ void INT10_GenerateVideoParameterTable(void) { } LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // sequencer registers",seq_regs[0],seq_regs[1],seq_regs[2],seq_regs[3]); LOG_MSG(" 0x%02x, // misc output registers",IO_ReadB(0x3cc)); - Bitu crtc_regs[4]; + Bitu crtc_regs[0x19]; Bit16u crt_addr=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); for (ct=0; ct<0x19; ct++) { IO_WriteB(crt_addr,ct); @@ -674,7 +674,7 @@ void INT10_GenerateVideoParameterTable(void) { LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, // crtc registers 16-24", crtc_regs[0x10],crtc_regs[0x11],crtc_regs[0x12],crtc_regs[0x13], crtc_regs[0x14],crtc_regs[0x15],crtc_regs[0x16],crtc_regs[0x17],crtc_regs[0x18]); - Bitu attr_regs[4]; + Bitu attr_regs[0x14]; for (ct=0; ct<0x14; ct++) { IO_ReadB(crt_addr+6); IO_WriteB(0x3c0,ct); @@ -688,7 +688,7 @@ void INT10_GenerateVideoParameterTable(void) { attr_regs[0x0c],attr_regs[0x0d],attr_regs[0x0e],attr_regs[0x0f]); LOG_MSG(" 0x%02x, 0x%02x, 0x%02x, 0x%02x, // attr registers 16-19", attr_regs[0x10],attr_regs[0x11],attr_regs[0x12],attr_regs[0x13]); - Bitu gfx_regs[4]; + Bitu gfx_regs[9]; for (ct=0; ct<0x09; ct++) { IO_WriteB(0x3ce,ct); gfx_regs[ct]=IO_ReadB(0x3cf); diff --git a/src/libs/gui_tk/gui_tk.cpp b/src/libs/gui_tk/gui_tk.cpp index d90524e4..6e97d07a 100644 --- a/src/libs/gui_tk/gui_tk.cpp +++ b/src/libs/gui_tk/gui_tk.cpp @@ -19,7 +19,7 @@ /* TODO: - make menu a bufferedwindow with shadow */ -/* $Id: gui_tk.cpp,v 1.2 2007-10-28 17:05:28 c2woody Exp $ */ +/* $Id: gui_tk.cpp,v 1.3 2008-08-06 18:33:47 c2woody Exp $ */ /** \file * \brief Implementation file for gui_tk. @@ -146,7 +146,7 @@ void Drawable::drawText(const String& text, bool interpret, Size start, Size len switch (param) { case 0: setColor(Color::Black); break; case 1: setColor(color | 0x00808080); break; - case 30: setColor(Color::Black|bright & intensity); break; + case 30: setColor((Color::Black|bright) & intensity); break; case 31: setColor(Color::Red & intensity); break; case 32: setColor(Color::Green & intensity); break; case 33: setColor(Color::Yellow & intensity); break; @@ -426,7 +426,7 @@ void BitmapFont::drawChar(Drawable *d, const Char c) const { ptr = char_position[c]; bit = 0; } else { - move(character_step*c); + move(character_step*((int)c)); } int rs = row_step; @@ -1380,7 +1380,7 @@ void ScreenRGB32le::paint(Drawable &d) const test(d); } -static const MouseButton SDL_to_GUI(const int button) +static MouseButton SDL_to_GUI(const int button) { switch (button) { case SDL_BUTTON_LEFT: return GUI::Left; diff --git a/src/libs/gui_tk/gui_tk.h b/src/libs/gui_tk/gui_tk.h index e852d6e7..06d5aba9 100644 --- a/src/libs/gui_tk/gui_tk.h +++ b/src/libs/gui_tk/gui_tk.h @@ -102,7 +102,7 @@ * along with this program. If not, see */ -/* $Id: gui_tk.h,v 1.2 2007-11-06 20:26:27 qbix79 Exp $ */ +/* $Id: gui_tk.h,v 1.3 2008-08-06 18:33:47 c2woody Exp $ */ #ifndef GUI__TOOLKIT_H #define GUI__TOOLKIT_H @@ -1988,7 +1988,7 @@ public: if (selected >= 0 && !menus[selected]->isVisible()) oldselected = -1; if (selected >= 0) menus[selected]->setVisible(false); if (x < 0 || x >= lastx) return true; - for (selected = menus.size()-1; menus[selected]->getX() > x; selected--); + for (selected = menus.size()-1; menus[selected]->getX() > x; selected--) {}; if (oldselected == selected) selected = -1; else menus[selected]->setVisible(true); return true; diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 4e34fc52..fc9021dc 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.49 2008-05-30 12:42:38 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.50 2008-08-06 18:32:35 c2woody Exp $ */ #include "dosbox.h" #include "cross.h" @@ -374,7 +374,6 @@ const std::vector& Prop_multival::GetValues() const //No properties in this section. do nothing if(!p) return suggested_values; int i =0; - string::size_type loc = string::npos; while( (p = section->Get_prop(i++)) ) { std::vector v = p->GetValues(); if(!v.empty()) return p->GetValues(); diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 070235e6..7851cbe7 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.34 2008-01-13 11:28:41 qbix79 Exp $ */ +/* $Id: support.cpp,v 1.35 2008-08-06 18:32:35 c2woody Exp $ */ #include #include @@ -71,7 +71,7 @@ char *ltrim(char *str) { char *rtrim(char *str) { char *p; p = strchr(str, '\0'); - while (--p >= str && isspace(*reinterpret_cast(p))); + while (--p >= str && isspace(*reinterpret_cast(p))) {}; p[1] = '\0'; return str; } diff --git a/src/platform/visualc/dirent.c b/src/platform/visualc/dirent.c index d2e25c2a..1131da7e 100644 --- a/src/platform/visualc/dirent.c +++ b/src/platform/visualc/dirent.c @@ -9,6 +9,8 @@ #include "dirent.h" #include "io.h" +#define safe_strncpy_dirent(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) + #ifdef WIN32 /** open the current directory and return a structure @@ -23,7 +25,7 @@ DIR * opendir(const char *dirname) { size_t len; /* Stash the directory name */ - strcpy(dir.pathName,dirname); + safe_strncpy_dirent(dir.pathName,dirname,260); len = strlen(dirname); if ((len>0) && (dirname[len-1]=='\\')) strcat(dir.pathName,"*.*"); @@ -80,7 +82,7 @@ struct dirent * readdir(DIR *dirp) { /* we have a valid FIND_FILE_DATA, copy the filename */ memset(&d,'\0', sizeof(struct dirent)); - strcpy(d.d_name,dirp->findFileData.cFileName); + safe_strncpy_dirent(d.d_name,dirp->findFileData.cFileName,260); d.d_namlen = (char)strlen(d.d_name); return &d; diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index a8b9ce4c..3f908b01 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.28 2008-07-27 20:12:28 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.29 2008-08-06 18:32:35 c2woody Exp $ */ #include #include @@ -91,7 +91,7 @@ emptyline: /* Handle %1 %2 .. %9 */ cmd_read++; //Progress reader next -= '0'; - if (cmd->GetCount()GetCount()<(unsigned int)next) continue; std::string word; if (!cmd->FindCommand(next,word)) continue; strcpy(cmd_write,word.c_str()); From b374d8c93f795c676f1e8879f8d291dbac516f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 8 Aug 2008 21:57:00 +0000 Subject: [PATCH 3105/4131] some s3/xga fixes (hal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3193 --- include/vga.h | 16 +++++++++- src/hardware/vga_s3.cpp | 24 ++++++++++++++- src/hardware/vga_xga.cpp | 64 ++++++++++++++++++---------------------- src/ints/int10_modes.cpp | 20 +++++++------ 4 files changed, 77 insertions(+), 47 deletions(-) diff --git a/include/vga.h b/include/vga.h index c66faeed..7815586b 100644 --- a/include/vga.h +++ b/include/vga.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga.h,v 1.42 2008-05-28 20:43:13 qbix79 Exp $ */ +/* $Id: vga.h,v 1.43 2008-08-08 21:56:36 c2woody Exp $ */ #ifndef DOSBOX_VGA_H #define DOSBOX_VGA_H @@ -55,6 +55,18 @@ enum VGAModes { #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; @@ -179,6 +191,8 @@ typedef struct { Bit16u la_window; Bit8u misc_control_2; Bit8u ext_mem_ctrl; + Bitu xga_screen_width; + VGAModes xga_color_mode; struct { Bit8u r; Bit8u n; diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index a549407c..d1b6e2c5 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_s3.cpp,v 1.15 2008-08-04 17:48:36 c2woody Exp $ */ +/* $Id: vga_s3.cpp,v 1.16 2008-08-08 21:57:00 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -140,6 +140,19 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { break; case 0x50: // Extended System Control 1 vga.s3.reg_50 = val; + switch (val & S3_XGA_CMASK) { + case S3_XGA_32BPP: vga.s3.xga_color_mode = M_LIN32; break; + case S3_XGA_16BPP: vga.s3.xga_color_mode = M_LIN16; break; + case S3_XGA_8BPP: vga.s3.xga_color_mode = M_LIN8; break; + } + switch (val & S3_XGA_WMASK) { + case S3_XGA_1024: vga.s3.xga_screen_width = 1024; break; + case S3_XGA_1152: vga.s3.xga_screen_width = 1152; break; + case S3_XGA_640: vga.s3.xga_screen_width = 640; break; + case S3_XGA_800: vga.s3.xga_screen_width = 800; break; + case S3_XGA_1280: vga.s3.xga_screen_width = 1280; break; + default: vga.s3.xga_screen_width = 1024; break; + } break; case 0x51: /* Extended System Control 2 */ vga.s3.reg_51=val & 0xc0; //Only store bits 6,7 @@ -297,6 +310,11 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { /* 0 VCLK PHS. VCLK Phase With Respect to DCLK. If clear VLKC is inverted DCLK, if set VCLK = DCLK. + 2-3 (Trio64V+) streams mode + 00 disable Streams Processor + 01 overlay secondary stream on VGA-mode background + 10 reserved + 11 full Streams Processor operation 4-7 Pixel format. 0 Mode 0: 8bit (1 pixel/VCLK) 1 Mode 8: 8bit (2 pixels/VCLK) @@ -377,6 +395,10 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { return vga.s3.hgc.originy>>8; case 0x49: /* HGC orgY */ return vga.s3.hgc.originy&0xff; + case 0x4A: /* HGC foreground stack */ + return vga.s3.hgc.forestack[vga.s3.hgc.fstackpos]; + case 0x4B: /* HGC background stack */ + return vga.s3.hgc.backstack[vga.s3.hgc.bstackpos]; case 0x50: // CR50 Extended System Control 1 return vga.s3.reg_50; case 0x51: /* Extended System Control 2 */ diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index 9c10497e..2e796c5c 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_xga.cpp,v 1.13 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: vga_xga.cpp,v 1.14 2008-08-08 21:57:00 c2woody Exp $ */ #include #include "dosbox.h" @@ -27,7 +27,8 @@ #include "callback.h" #include "cpu.h" // for 0x3da delay -#define XGA_SCREEN_WIDTH vga.draw.width +#define XGA_SCREEN_WIDTH vga.s3.xga_screen_width +#define XGA_COLOR_MODE vga.s3.xga_color_mode #define XGA_SHOW_COMMAND_TRACE 0 @@ -140,7 +141,7 @@ void XGA_DrawPoint(Bitu x, Bitu y, Bitu c) { /* Need to zero out all unused bits in modes that have any (15-bit or "32"-bit -- the last one is actually 24-bit. Without this step there may be some graphics corruption (mainly, during windows dragging. */ - switch(vga.mode) { + switch(XGA_COLOR_MODE) { case M_LIN8: vga.mem.linear[memaddr] = c; break; case M_LIN15: ((Bit16u*)(vga.mem.linear))[memaddr] = (Bit16u)(c&0x7fff); break; case M_LIN16: ((Bit16u*)(vga.mem.linear))[memaddr] = (Bit16u)(c&0xffff); break; @@ -156,7 +157,7 @@ Bitu XGA_GetPoint(Bitu x, Bitu y) { //LOG_MSG("getpoint mem over: x%d y%d",x,y); return 0; } - switch(vga.mode) { + switch(XGA_COLOR_MODE) { case M_LIN8: return vga.mem.linear[memaddr]; case M_LIN15: case M_LIN16: return ((Bit16u*)(vga.mem.linear))[memaddr]; @@ -954,40 +955,35 @@ void XGA_DrawCmd(Bitu val, Bitu len) { } void XGA_SetDualReg(Bit32u& reg, Bitu val) { - switch(vga.mode) { + switch(XGA_COLOR_MODE) { case M_LIN8: reg = (Bit8u)(val&0xff); break; case M_LIN15: case M_LIN16: reg = (Bit16u)(val&0xffff); break; - case M_LIN32: { - if(xga.control1 & 0x200) - reg = val; - else if(xga.control1 & 0x10) - reg = (reg&0x0000ffff)|(val<<16); - else - reg = (reg&0xffff0000)|(val&0x0000ffff); - xga.control1 ^= 0x10; - } + case M_LIN32: + if (xga.control1 & 0x200) + reg = val; + else if (xga.control1 & 0x10) + reg = (reg&0x0000ffff)|(val<<16); + else + reg = (reg&0xffff0000)|(val&0x0000ffff); + xga.control1 ^= 0x10; break; } } Bitu XGA_GetDualReg(Bit32u reg) { - switch(vga.mode) { + switch(XGA_COLOR_MODE) { case M_LIN8: return (Bit8u)(reg&0xff); case M_LIN15: case M_LIN16: return (Bit16u)(reg&0xffff); - case M_LIN32: { - if(xga.control1 & 0x200) - return reg; - xga.control1 ^= 0x10; - if(xga.control1 & 0x10) - return reg&0x0000ffff; - else - return reg>>16; - } + case M_LIN32: + if (xga.control1 & 0x200) return reg; + xga.control1 ^= 0x10; + if (xga.control1 & 0x10) return reg&0x0000ffff; + else return reg>>16; } return 0; } @@ -1027,24 +1023,20 @@ void XGA_Write(Bitu port, Bitu val, Bitu len) { break; case 0x8120: // packed MMIO: DWORD background color (see PORT A2E8h) - //if(len==4) xga.backcolor = val; - //else - XGA_SetDualReg(xga.backcolor, val); + if (len==4) xga.backcolor = val; + else XGA_SetDualReg(xga.backcolor, val); break; case 0x8124: // packed MMIO: DWORD foreground color (see PORT A6E8h) - //if(len==4) xga.forecolor = val; // TODO - //else - XGA_SetDualReg(xga.forecolor, val); + if (len==4) xga.forecolor = val; // TODO + else XGA_SetDualReg(xga.forecolor, val); break; case 0x8128: // DWORD write mask (see PORT AAE8h) - //if(len==4) xga.writemask = val; - //else - XGA_SetDualReg(xga.writemask, val); + if (len==4) xga.writemask = val; + else XGA_SetDualReg(xga.writemask, val); break; case 0x812C: // DWORD read mask (see PORT AEE8h) - //if(len==4) xga.readmask = val; - //else - XGA_SetDualReg(xga.readmask, val); + if (len==4) xga.readmask = val; + else XGA_SetDualReg(xga.readmask, val); break; case 0x8134: // packed MMIO: DWORD background mix (low word) and // foreground mix (high word) (see PORT B6E8h,PORT BAE8h) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index db139849..0f5d7830 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.79 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.80 2008-08-08 21:57:00 c2woody Exp $ */ #include @@ -1206,18 +1206,20 @@ dac_text16: IO_Write(0x3c5,0x03); // Accellerator setup - Bitu reg_50=0; + Bitu reg_50=S3_XGA_8BPP; switch (CurMode->type) { case M_LIN15: - case M_LIN16: reg_50|=0x10; break; - case M_LIN32: reg_50|=0x30; break; + case M_LIN16: reg_50|=S3_XGA_16BPP; break; + case M_LIN32: reg_50|=S3_XGA_32BPP; break; + default: break; } switch(CurMode->swidth) { - case 640: reg_50|=0x40; break; - case 800: reg_50|=0x80; break; - case 1024: break; - case 1152: reg_50|=0x01; break; - case 1280: reg_50|=0xc1; break; + case 640: reg_50|=S3_XGA_640; break; + case 800: reg_50|=S3_XGA_800; break; + case 1024: reg_50|=S3_XGA_1024; break; + case 1152: reg_50|=S3_XGA_1152; break; + case 1280: reg_50|=S3_XGA_1280; break; + default: break; } IO_WriteB(crtc_base,0x50); IO_WriteB(crtc_base+1,reg_50); From 34cc1838d08554ee256689bb4fe9683fd5e083c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 9 Aug 2008 15:37:15 +0000 Subject: [PATCH 3106/4131] fix graphics rom checksum position Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3194 --- src/ints/int10_memory.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 7cc5234c..97e8a20b 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_memory.cpp,v 1.26 2008-03-14 18:16:34 c2woody Exp $ */ +/* $Id: int10_memory.cpp,v 1.27 2008-08-09 15:37:15 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -75,7 +75,6 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu } -static Bitu checksumlocation = 0; //Same type as int10.rom.used void INT10_SetupRomMemory(void) { /* This should fill up certain structures inside the Video Bios Rom Area */ PhysPt rom_base=PhysMake(0xc000,0); @@ -185,10 +184,6 @@ void INT10_SetupRomMemory(void) { if (IS_TANDY_ARCH) { RealSetVec(0x44,int10.rom.font_8_first); } - if (IS_EGAVGA_ARCH) { //EGA/VGA. Just to be safe - //Reserve checksum location - checksumlocation = int10.rom.used++; - } } void INT10_ReloadRomFonts(void) { @@ -218,10 +213,11 @@ void INT10_SetupRomMemoryChecksum(void) { /* Sum of all bytes in rom module 256 should be 0 */ Bit8u sum = 0; PhysPt rom_base = PhysMake(0xc000,0); - for (Bitu i = 0;i < 32 * 1024;i++) //32 KB romsize - sum += phys_readb(rom_base + i); //OVERFLOW IS OKAY + Bitu last_rombyte = 32*1024 - 1; //32 KB romsize + for (Bitu i = 0;i < last_rombyte;i++) + sum += phys_readb(rom_base + i); //OVERFLOW IS OKAY sum = 256 - sum; - phys_writeb(rom_base + checksumlocation,sum); + phys_writeb(rom_base + last_rombyte,sum); } } From 6a721243e7d79f3597a541cb7de8e7bde3f79659 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 9 Aug 2008 19:42:26 +0000 Subject: [PATCH 3107/4131] Some more warning fixes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3195 --- src/libs/gui_tk/gui_tk.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/gui_tk/gui_tk.h b/src/libs/gui_tk/gui_tk.h index 06d5aba9..fd18a21f 100644 --- a/src/libs/gui_tk/gui_tk.h +++ b/src/libs/gui_tk/gui_tk.h @@ -102,7 +102,7 @@ * along with this program. If not, see */ -/* $Id: gui_tk.h,v 1.3 2008-08-06 18:33:47 c2woody Exp $ */ +/* $Id: gui_tk.h,v 1.4 2008-08-09 19:42:26 qbix79 Exp $ */ #ifndef GUI__TOOLKIT_H #define GUI__TOOLKIT_H @@ -1726,8 +1726,8 @@ public: virtual void move(int x, int y) { relx = x; rely = y; Window::move(x+realparent->getScreenX(),y+realparent->getScreenY()); } - virtual int getX() { return x-realparent->getScreenX(); } - virtual int getY() { return y-realparent->getScreenY(); } + virtual int getX() const { return x-realparent->getScreenX(); } + virtual int getY() const { return y-realparent->getScreenY(); } virtual void setVisible(bool v) { if (v) raise(); Window::setVisible(v); } virtual void windowMoved(Window *src, int x, int y) { move(relx,rely); } From cd0394d69248564a421b02902b3c072c8b5693b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 10 Aug 2008 18:33:30 +0000 Subject: [PATCH 3108/4131] change VER to display the sub-version in an easier readable form (6.2->6.02, 6.20->6.20) to avoid confusion Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3196 --- src/shell/shell.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 1e7c6a25..2ec452a1 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.90 2008-07-27 20:12:28 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.91 2008-08-10 18:33:30 c2woody Exp $ */ #include #include @@ -560,7 +560,7 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_ATTRIB_HELP","Does nothing. Provided for compatibility.\n"); MSG_Add("SHELL_CMD_PATH_HELP","Provided for compatibility.\n"); MSG_Add("SHELL_CMD_VER_HELP","View and set the reported DOS version.\n"); - MSG_Add("SHELL_CMD_VER_VER","DOSBox version %s. Reported DOS version %d.%d.\n"); + MSG_Add("SHELL_CMD_VER_VER","DOSBox version %s. Reported DOS version %d.%02d.\n"); /* Regular startup */ call_shellstop=CALLBACK_Allocate(); From b1519ba4c11b285859919a1e17719c5014caa69c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Aug 2008 07:47:04 +0000 Subject: [PATCH 3109/4131] Make more creative labels possible (:======label======) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3197 --- src/shell/shell_batch.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 3f908b01..8cb566a2 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.29 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: shell_batch.cpp,v 1.30 2008-08-11 07:47:04 qbix79 Exp $ */ #include #include @@ -139,11 +139,21 @@ again: *cmd_write++=c; } } while (c!='\n' && n); - *cmd_write++=0; + *cmd_write++ = 0; char *nospace = trim(cmd_buffer); if (nospace[0] == ':') { - char* nonospace = trim(nospace+1); - if (strcasecmp(nonospace,where)==0) return true; + nospace++; //Skip : + //Strip spaces and = from it. + while(*nospace && (isspace(*reinterpret_cast(nospace)) || (*nospace == '='))) + nospace++; + + //label is until space/=/eol + char* const beginlabel = nospace; + while(*nospace && !isspace(*reinterpret_cast(nospace)) && (*nospace != '=')) + nospace++; + + *nospace = 0; + if (strcasecmp(beginlabel,where)==0) return true; } if (!n) { delete this; From a84fcb5f7c07fdf94ae28b6d2c3ebd46c5a7b0fa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Aug 2008 12:50:26 +0000 Subject: [PATCH 3110/4131] Fix logging message. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3198 --- src/ints/int10_char.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 64d7b8be..1c35dec3 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.54 2008-06-14 19:31:04 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.55 2008-08-11 12:50:26 qbix79 Exp $ */ /* Character displaying moving functions */ @@ -348,7 +348,7 @@ dowrite: void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page) { Bit16u address; - if (page>7) LOG(LOG_INT10,LOG_ERROR)("INT10_SetCursorPos page %d"); + if (page>7) LOG(LOG_INT10,LOG_ERROR)("INT10_SetCursorPos page %d",page); // Bios cursor pos real_writeb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2,col); real_writeb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2+1,row); From baade2ff3f699ce40f90496929421e46e2317f0d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Aug 2008 12:51:11 +0000 Subject: [PATCH 3111/4131] signed vs unsigned Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3199 --- src/dos/cdrom_ioctl_linux.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/cdrom_ioctl_linux.cpp b/src/dos/cdrom_ioctl_linux.cpp index 368f9312..9c202bd5 100644 --- a/src/dos/cdrom_ioctl_linux.cpp +++ b/src/dos/cdrom_ioctl_linux.cpp @@ -57,7 +57,7 @@ bool CDROM_Interface_Ioctl::ReadSectors(PhysPt buffer, bool raw, unsigned long s int cdrom_fd = open(device_name, O_RDONLY | O_NONBLOCK); if (cdrom_fd <= 0) return false; - Bitu buflen = raw ? num * CD_FRAMESIZE_RAW : num * CD_FRAMESIZE; + Bits buflen = raw ? num * CD_FRAMESIZE_RAW : num * CD_FRAMESIZE; Bit8u* buf = new Bit8u[buflen]; int ret; From 0c788c8d3a5b23198ac15dc423430d535e578ae4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Aug 2008 12:52:36 +0000 Subject: [PATCH 3112/4131] Remove unused variable Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3200 --- src/shell/shell.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 2ec452a1..1122e462 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.91 2008-08-10 18:33:30 c2woody Exp $ */ +/* $Id: shell.cpp,v 1.92 2008-08-11 12:52:36 qbix79 Exp $ */ #include #include @@ -264,7 +264,6 @@ void DOS_Shell::ParseLine(char * line) { void DOS_Shell::RunInternal(void) { char input_line[CMD_MAXLINE] = {0}; - std::string line; while(bf && bf->ReadLine(input_line)) { if (echo) { From 8fe4a7e67fcc017add21e1fdb5e6d88e0778da4f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Aug 2008 12:54:57 +0000 Subject: [PATCH 3113/4131] Refactoring. Rewrite IF to not simply delete all =. Makes stuff like if errorlevel === 0 if not errorlevel 1 set A=1 correctly possible. Linefeed stuff(beta1) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3201 --- include/shell.h | 28 +------- src/shell/shell_cmds.cpp | 137 +++++++++++++++++++++++++-------------- 2 files changed, 91 insertions(+), 74 deletions(-) diff --git a/include/shell.h b/include/shell.h index 0080e949..e4f8f27b 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.23 2008-03-02 11:13:46 qbix79 Exp $ */ +/* $Id: shell.h,v 1.24 2008-08-11 12:54:57 qbix79 Exp $ */ #ifndef DOSBOX_SHELL_H #define DOSBOX_SHELL_H @@ -127,32 +127,6 @@ struct SHELL_Cmd { const char * help; /* String with command help */ }; -static inline void StripSpaces(char*&args) { - while(args && *args && isspace(*reinterpret_cast(args))) - args++; -} - -static inline char* ExpandDot(char*args, char* buffer) { - if(*args=='.') - { - if(*(args+1)==0) - { - strcpy(buffer,"*.*"); - return buffer; - } - if( (*(args+1)!='.') && (*(args+1)!='\\') ) - { - buffer[0]='*'; - buffer[1]=0; - strcat(buffer,args); - return buffer; - } else - strcpy (buffer, args); - } - else strcpy(buffer,args); - return buffer; -} - /* 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 */ diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 0673eb91..eabb056c 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.82 2008-06-16 20:01:25 c2woody Exp $ */ +/* $Id: shell_cmds.cpp,v 1.83 2008-08-11 12:54:57 qbix79 Exp $ */ #include "dosbox.h" #include "shell.h" @@ -67,8 +67,38 @@ static SHELL_Cmd cmd_list[]={ {0,0,0,0} }; +/* support functions */ static char empty_char = 0; static char* empty_string = &empty_char; +static void StripSpaces(char*&args) { + while(args && *args && isspace(*reinterpret_cast(args))) + args++; +} + +static void StripSpaces(char*&args,char also) { + while(args && *args && (isspace(*reinterpret_cast(args)) || (*args == also))) + args++; +} + +static char* ExpandDot(char*args, char* buffer) { + if(*args == '.') { + if(*(args+1) == 0){ + strcpy(buffer,"*.*"); + return buffer; + } + if( (*(args+1) != '.') && (*(args+1) != '\\') ) { + buffer[0] = '*'; + buffer[1] = 0; + strcat(buffer,args); + return buffer; + } else + strcpy (buffer, args); + } + else strcpy(buffer,args); + return buffer; +} + + bool DOS_Shell::CheckConfig(char* cmd_in,char*line) { Section* test = control->GetSectionFromProperty(cmd_in); @@ -139,7 +169,7 @@ void DOS_Shell::CMD_CLS(char * args) { HELP("CLS"); reg_ax=0x0003; CALLBACK_RunRealInt(0x10); -}; +} void DOS_Shell::CMD_DELETE(char * args) { HELP("DELETE"); @@ -251,14 +281,18 @@ void DOS_Shell::CMD_ECHO(char * args){ return; } args++;//skip first character. either a slash or dot or space - WriteOut("%s\n",args); -}; + size_t len = strlen(args); //TODO check input of else ook nodig is. + if(len && args[len - 1] == '\r') { + LOG(LOG_MISC,LOG_WARN)("Hu ? carriage return allready present. Is this possible?"); + WriteOut("%s\n",args); + } else WriteOut("%s\r\n",args); +} void DOS_Shell::CMD_EXIT(char * args) { HELP("EXIT"); exit = true; -}; +} void DOS_Shell::CMD_CHDIR(char * args) { HELP("CHDIR"); @@ -297,7 +331,7 @@ void DOS_Shell::CMD_CHDIR(char * args) { } } } -}; +} void DOS_Shell::CMD_MKDIR(char * args) { HELP("MKDIR"); @@ -310,7 +344,7 @@ void DOS_Shell::CMD_MKDIR(char * args) { if (!DOS_MakeDir(args)) { WriteOut(MSG_Get("SHELL_CMD_MKDIR_ERROR"),args); } -}; +} void DOS_Shell::CMD_RMDIR(char * args) { HELP("RMDIR"); @@ -323,7 +357,7 @@ void DOS_Shell::CMD_RMDIR(char * args) { if (!DOS_RemoveDir(args)) { WriteOut(MSG_Get("SHELL_CMD_RMDIR_ERROR"),args); } -}; +} static void FormatNumber(Bitu num,char * buf) { Bitu numm,numk,numb,numg; @@ -490,6 +524,7 @@ void DOS_Shell::CMD_DIR(char * args) { WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_FREE"),dir_count,numformat); dos.dta(save_dta); } + struct copysource { std::string filename; bool concat; @@ -708,29 +743,41 @@ void DOS_Shell::CMD_IF(char * args) { HELP("IF"); StripSpaces(args); bool has_not=false; - char * comp=strchr(args,'='); - if (comp) { - if (comp[1] == '=') { - *comp++ = ' '; - *comp++ = ' '; - } else if(strncasecmp(args,"ERRORLEVEL",10) == 0) { - /* this is in general a syntax error except for errorlevel */ - *comp++ = ' '; - while(*comp++ == ' ') - ; /*nothing */ - } else if(strncasecmp(args," set ",5) !=0) { - /* if cond set a=b is allowed as well */ - SyntaxError(); + char* word; + + if (strncasecmp(args,"NOT ",4) ==0) { + args += 4; //skip text + //skip more spaces + StripSpaces(args); + has_not = true; + } + + if(strncasecmp(args,"ERRORLEVEL",10) == 0) { + args += 10; //skip text + //Strip spaces and == + StripSpaces(args,'='); + word = StripWord(args); + if(!isdigit(*word)) { + WriteOut(MSG_Get("SHELL_CMD_IF_ERRORLEVEL_MISSING_NUMBER")); return; } - }; - char * word=StripWord(args); - if (strcasecmp(word,"NOT")==0) { - word=StripWord(args); - has_not=true; + + Bit8u n = 0; + do n = n * 10 + (*word - '0'); + while (isdigit(*++word)); + if(*word && !isspace(*word)) { + WriteOut(MSG_Get("SHELL_CMD_IF_ERRORLEVEL_INVALID_NUMBER")); + return; + } + /* Read the error code from DOS */ + if ((dos.return_code>=n) ==(!has_not)) DoCommand(args); + return; } - if (strcasecmp(word,"EXIST")==0) { - word=StripWord(args); + + if(strncasecmp(args,"EXIST ",6) == 0) { + args += 6; //Skip text + StripSpaces(args); + word = StripWord(args); if (!*word) { WriteOut(MSG_Get("SHELL_CMD_IF_EXIST_MISSING_FILENAME")); return; @@ -745,28 +792,24 @@ void DOS_Shell::CMD_IF(char * args) { } return; } - if (strcasecmp(word,"ERRORLEVEL")==0) { - word=StripWord(args); - if(!isdigit(*word)) { - WriteOut(MSG_Get("SHELL_CMD_IF_ERRORLEVEL_MISSING_NUMBER")); - return; - } - Bit8u n=0; - do n = n * 10 + (*word - '0'); - while (isdigit(*++word)); - if(*word && !isspace(*word)) { - WriteOut(MSG_Get("SHELL_CMD_IF_ERRORLEVEL_INVALID_NUMBER")); - return; - } - /* Read the error code from DOS */ - if ((dos.return_code>=n) ==(!has_not)) DoCommand(args); + /* Normal if string compare */ + word = args; + // Word is until space or = + while(*args && !isspace(*reinterpret_cast(args)) && (*args != '=')) + args++; + char* end_word1 = args; + StripSpaces(args); + //Check for 2 == + if(strlen(args)<2 || args[0] != '=' || args[1] != '=') { + SyntaxError(); return; } - /* Normal if string compare */ - if (!*args) { SyntaxError();return;}; - char * word2=StripWord(args); - if ((strcmp(word,word2)==0)==(!has_not)) DoCommand(args); + args += 2; + StripSpaces(args); + char* woord2 = StripWord(args); + *end_word1 = 0; + if ((strcmp(word,woord2)==0)==(!has_not)) DoCommand(args); } void DOS_Shell::CMD_GOTO(char * args) { From cdbd12696e9a36dbad37686c19a597ab843a31dc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Aug 2008 13:09:44 +0000 Subject: [PATCH 3114/4131] Map PRN to LPT1. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3202 --- src/dos/dos_devices.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 64322323..0a2bfab4 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_devices.cpp,v 1.19 2007-09-27 19:34:43 qbix79 Exp $ */ +/* $Id: dos_devices.cpp,v 1.20 2008-08-11 13:09:44 qbix79 Exp $ */ #include #include "dosbox.h" @@ -125,6 +125,7 @@ Bit8u DOS_FindDevice(char const * name) { // STDAUX is alias for COM1 // A bit of a hack, but no application will probably use stdaux to determine wether a directory exists if (strcasecmp(name, "STDAUX") == 0) name = "COM1"; + if (strcasecmp(name, "PRN") == 0) name = "LPT1"; char temp[CROSS_LEN];//TODO if(!name || !(*name)) return DOS_DEVICES; From c4ab50a955ccf23ffde7fe5d897faa2aa9a8fc46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 11 Aug 2008 17:51:06 +0000 Subject: [PATCH 3115/4131] xga mmio dword fix (hal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3203 --- src/hardware/vga_xga.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index 2e796c5c..9645c0f5 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_xga.cpp,v 1.14 2008-08-08 21:57:00 c2woody Exp $ */ +/* $Id: vga_xga.cpp,v 1.15 2008-08-11 17:51:06 c2woody Exp $ */ #include #include "dosbox.h" @@ -1023,20 +1023,16 @@ void XGA_Write(Bitu port, Bitu val, Bitu len) { break; case 0x8120: // packed MMIO: DWORD background color (see PORT A2E8h) - if (len==4) xga.backcolor = val; - else XGA_SetDualReg(xga.backcolor, val); + xga.backcolor = val; break; case 0x8124: // packed MMIO: DWORD foreground color (see PORT A6E8h) - if (len==4) xga.forecolor = val; // TODO - else XGA_SetDualReg(xga.forecolor, val); + xga.forecolor = val; break; case 0x8128: // DWORD write mask (see PORT AAE8h) - if (len==4) xga.writemask = val; - else XGA_SetDualReg(xga.writemask, val); + xga.writemask = val; break; case 0x812C: // DWORD read mask (see PORT AEE8h) - if (len==4) xga.readmask = val; - else XGA_SetDualReg(xga.readmask, val); + xga.readmask = val; break; case 0x8134: // packed MMIO: DWORD background mix (low word) and // foreground mix (high word) (see PORT B6E8h,PORT BAE8h) From 7bce57da3e80fd415c4436309961255d8d590311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 12 Aug 2008 18:13:51 +0000 Subject: [PATCH 3116/4131] add version information/description to installer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3204 --- scripts/dosbox-installer.nsi | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index fd026290..206d4768 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -1,8 +1,20 @@ !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 "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer" +Name "${APP_NAME}" ; The file to write OutFile "DOSBox${VER_MAYOR}.${VER_MINOR}-win32-installer.exe" @@ -25,10 +37,13 @@ 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 @@ -71,6 +86,14 @@ 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 From 6640a3e6f0274f31ac2042ffcf47607d0b303eef Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 19 Aug 2008 13:59:24 +0000 Subject: [PATCH 3117/4131] Fix ROR byte flag calculations. (thank you h-a-l-9000 for your help in determing which instruction was broken) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3205 --- src/cpu/core_dynrec/operators.h | 2 +- src/cpu/instructions.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_dynrec/operators.h b/src/cpu/core_dynrec/operators.h index 65b3dbfb..be667dcd 100644 --- a/src/cpu/core_dynrec/operators.h +++ b/src/cpu/core_dynrec/operators.h @@ -754,7 +754,7 @@ static Bit8u DRC_CALL_CONV dynrec_rol_byte_simple(Bit8u op1,Bit8u op2) { static Bit8u DRC_CALL_CONV dynrec_ror_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_ror_byte(Bit8u op1,Bit8u op2) { if (!(op2&0x7)) { - if (op2&0x10) { + if (op2&0x18) { FillFlagsNoCFOF(); SETFLAGBIT(CF,op1>>7); SETFLAGBIT(OF,(op1>>7) ^ ((op1>>6) & 1)); diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 45b2c795..1a69ffb4 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -277,7 +277,7 @@ #define RORB(op1,op2,load,save) \ if (!(op2&0x7)) { \ - if (op2&0x10) { \ + if (op2&0x18) { \ FillFlagsNoCFOF(); \ SETFLAGBIT(CF,op1>>7); \ SETFLAGBIT(OF,(op1>>7) ^ ((op1>>6) & 1)); \ From 021c76f6d9417f9e20a2699db1f8210e6ca53e65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 20 Aug 2008 14:13:21 +0000 Subject: [PATCH 3118/4131] add arm4 dynamic recompiler backend (M-HT) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3206 --- src/cpu/core_dynrec.cpp | 7 +- src/cpu/core_dynrec/Makefile.am | 4 +- src/cpu/core_dynrec/decoder_basic.h | 5 +- src/cpu/core_dynrec/risc_armv4le-common.h | 97 +++ src/cpu/core_dynrec/risc_armv4le-o3.h | 858 ++++++++++++++++++++ src/cpu/core_dynrec/risc_armv4le-s3.h | 694 ++++++++++++++++ src/cpu/core_dynrec/risc_armv4le-thumb.h | 934 ++++++++++++++++++++++ src/cpu/core_dynrec/risc_armv4le.h | 29 + src/cpu/core_dynrec/risc_mipsel32.h | 16 +- src/cpu/core_dynrec/risc_x64.h | 6 +- src/cpu/core_dynrec/risc_x86.h | 6 +- 11 files changed, 2649 insertions(+), 7 deletions(-) create mode 100644 src/cpu/core_dynrec/risc_armv4le-common.h create mode 100644 src/cpu/core_dynrec/risc_armv4le-o3.h create mode 100644 src/cpu/core_dynrec/risc_armv4le-s3.h create mode 100644 src/cpu/core_dynrec/risc_armv4le-thumb.h create mode 100644 src/cpu/core_dynrec/risc_armv4le.h diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index cca2c66e..787bc908 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: core_dynrec.cpp,v 1.9 2007-11-24 17:26:48 c2woody Exp $ */ +/* $Id: core_dynrec.cpp,v 1.10 2008-08-20 14:13:21 c2woody Exp $ */ #include "dosbox.h" @@ -138,6 +138,7 @@ static struct { #define X86 0x01 #define X86_64 0x02 #define MIPSEL 0x03 +#define ARMV4LE 0x04 #if C_TARGETCPU == X86_64 #include "core_dynrec/risc_x64.h" @@ -145,6 +146,8 @@ static struct { #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" diff --git a/src/cpu/core_dynrec/Makefile.am b/src/cpu/core_dynrec/Makefile.am index 50c57a7a..ca58ca90 100644 --- a/src/cpu/core_dynrec/Makefile.am +++ b/src/cpu/core_dynrec/Makefile.am @@ -1,2 +1,4 @@ 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 \ No newline at end of file + 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 diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index c3d95773..4b4f7321 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: decoder_basic.h,v 1.11 2008-08-20 14:13:21 c2woody Exp $ */ + /* This file provides some definitions and basic level functions @@ -554,6 +556,7 @@ static void dyn_closeblock(void) { //Shouldn't create empty block normally but let's do it like this dyn_fill_blocks(); cache_closeblock(); + cache_block_closing(decode.block->cache.start,decode.block->cache.size); } diff --git a/src/cpu/core_dynrec/risc_armv4le-common.h b/src/cpu/core_dynrec/risc_armv4le-common.h new file mode 100644 index 00000000..599f65ac --- /dev/null +++ b/src/cpu/core_dynrec/risc_armv4le-common.h @@ -0,0 +1,97 @@ +/* + * 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: risc_armv4le-common.h,v 1.1 2008-08-20 14:13:21 c2woody Exp $ */ + + +/* ARMv4 (little endian) backend by M-HT (common data/functions) */ + + +// some configuring defines that specify the capabilities of this architecture +// or aspects of the recompiling + +// protect FC_ADDR over function calls if necessaray +// #define DRC_PROTECT_ADDR_REG + +// try to use non-flags generating functions if possible +#define DRC_FLAGS_INVALIDATION +// try to replace _simple functions by code +#define DRC_FLAGS_INVALIDATION_DCODE + +// type with the same size as a pointer +#define DRC_PTR_SIZE_IM Bit32u + +// calling convention modifier +#define DRC_CALL_CONV /* nothing */ +#define DRC_FC /* nothing */ + +// register mapping +typedef Bit8u HostReg; + +// "lo" registers +#define HOST_r0 0 +#define HOST_r1 1 +#define HOST_r2 2 +#define HOST_r3 3 +#define HOST_r4 4 +#define HOST_r5 5 +#define HOST_r6 6 +#define HOST_r7 7 +// "hi" registers +#define HOST_r8 8 +#define HOST_r9 9 +#define HOST_r10 10 +#define HOST_r11 11 +#define HOST_r12 12 +#define HOST_r13 13 +#define HOST_r14 14 +#define HOST_r15 15 + +// register aliases +// "lo" registers +#define HOST_a1 HOST_r0 +#define HOST_a2 HOST_r1 +#define HOST_a3 HOST_r2 +#define HOST_a4 HOST_r3 +#define HOST_v1 HOST_r4 +#define HOST_v2 HOST_r5 +#define HOST_v3 HOST_r6 +#define HOST_v4 HOST_r7 +// "hi" registers +#define HOST_v5 HOST_r8 +#define HOST_v6 HOST_r9 +#define HOST_v7 HOST_r10 +#define HOST_v8 HOST_r11 +#define HOST_ip HOST_r12 +#define HOST_sp HOST_r13 +#define HOST_lr HOST_r14 +#define HOST_pc HOST_r15 + + +static void cache_block_closing(Bit8u* block_start,Bitu block_size) { +// GP2X BEGIN + //flush cache + register unsigned long _beg __asm ("a1") = (unsigned long)(block_start); // block start + register unsigned long _end __asm ("a2") = (unsigned long)(block_start+block_size); // block end + register unsigned long _flg __asm ("a3") = 0; + __asm __volatile ("swi 0x9f0002 @ sys_cacheflush" + : // no outputs + : // no inputs + : "a1"); +// GP2X END +} diff --git a/src/cpu/core_dynrec/risc_armv4le-o3.h b/src/cpu/core_dynrec/risc_armv4le-o3.h new file mode 100644 index 00000000..d639d297 --- /dev/null +++ b/src/cpu/core_dynrec/risc_armv4le-o3.h @@ -0,0 +1,858 @@ +/* + * 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: risc_armv4le-o3.h,v 1.1 2008-08-20 14:13:21 c2woody Exp $ */ + + +/* ARMv4 (little endian) backend by M-HT (size-tweaked arm version) */ + + +// temporary registers +#define temp1 HOST_ip +#define temp2 HOST_v5 +#define temp3 HOST_v4 + +// register that holds function return values +#define FC_RETOP HOST_v3 + +// register used for address calculations, +#define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG + +// register that holds the first parameter +#define FC_OP1 HOST_a1 + +// register that holds the second parameter +#define FC_OP2 HOST_a2 + +// register that holds byte-accessible temporary values +#define FC_TMP_BA1 HOST_a1 + +// register that holds byte-accessible temporary values +#define FC_TMP_BA2 HOST_a2 + +// temporary register for LEA +#define TEMP_REG_DRC HOST_v2 + +// helper macro +#define ROTATE_SCALE(x) ( (x)?(32 - x):(0) ) + +// move a full register from reg_src to reg_dst +static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { + if(reg_src == reg_dst) return; + cache_addd(0xe1a00000 + (reg_dst << 12) + reg_src); // mov reg_dst, reg_src +} + +// helper function +static Bits get_imm_gen_len(Bit32u imm) { + Bits ret; + if (imm == 0) { + return 1; + } else { + ret = 0; + while (imm) { + while ((imm & 3) == 0) { + imm>>=2; + } + ret++; + imm>>=8; + } + return ret; + } +} + +// helper function +static Bits get_method_imm_gen_len(Bit32u imm, Bits preffer00, Bits *num) { + Bits num00, num15, numadd, numsub, numret, ret; + num00 = get_imm_gen_len(imm); + num15 = get_imm_gen_len(~imm); + numadd = get_imm_gen_len(imm - ((Bit32u)cache.pos+8)); + numsub = get_imm_gen_len(((Bit32u)cache.pos+8) - imm); + if (numsub < numadd && numsub < num00 && numsub < num15) { + ret = 0; + numret = numsub; + } else if (numadd < num00 && numadd < num15) { + ret = 1; + numret = numadd; + } else if (num00 < num15 || (num00 == num15 && preffer00)) { + ret = 2; + numret = num00; + } else { + ret = 3; + numret = num15; + } + if (num != NULL) *num = numret; + return ret; +} + +// move a 32bit constant value into dest_reg +static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { + Bits first, method, scale; + Bit32u imm2, dist; + if (imm == 0) { + cache_addd(0xe3a00000 + (dest_reg << 12)); // mov dest_reg, #0 + } else if (imm == 0xffffffff) { + cache_addd(0xe3e00000 + (dest_reg << 12)); // mvn dest_reg, #0 + } else { + method = get_method_imm_gen_len(imm, 1, NULL); + + scale = 0; + first = 1; + if (method == 0) { + dist = ((Bit32u)cache.pos+8) - imm; + while (dist) { + while ((dist & 3) == 0) { + dist>>=2; + scale+=2; + } + if (first) { + cache_addd(0xe2400000 + (dest_reg << 12) + (HOST_pc << 16) + (ROTATE_SCALE(scale) << 7) + (dist & 0xff)); // sub dest_reg, pc, #((dist & 0xff) << scale) + first = 0; + } else { + cache_addd(0xe2400000 + (dest_reg << 12) + (dest_reg << 16) + (ROTATE_SCALE(scale) << 7) + (dist & 0xff)); // sub dest_reg, dest_reg, #((dist & 0xff) << scale) + } + dist>>=8; + scale+=8; + } + } else if (method == 1) { + dist = imm - ((Bit32u)cache.pos+8); + if (dist == 0) { + cache_addd(0xe1a00000 + (dest_reg << 12) + HOST_pc); // mov dest_reg, pc + } else { + while (dist) { + while ((dist & 3) == 0) { + dist>>=2; + scale+=2; + } + if (first) { + cache_addd(0xe2800000 + (dest_reg << 12) + (HOST_pc << 16) + (ROTATE_SCALE(scale) << 7) + (dist & 0xff)); // add dest_reg, pc, #((dist & 0xff) << scale) + first = 0; + } else { + cache_addd(0xe2800000 + (dest_reg << 12) + (dest_reg << 16) + (ROTATE_SCALE(scale) << 7) + (dist & 0xff)); // add dest_reg, dest_reg, #((dist & 0xff) << scale) + } + dist>>=8; + scale+=8; + } + } + } else if (method == 2) { + while (imm) { + while ((imm & 3) == 0) { + imm>>=2; + scale+=2; + } + if (first) { + cache_addd(0xe3a00000 + (dest_reg << 12) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // mov dest_reg, #((imm & 0xff) << scale) + first = 0; + } else { + cache_addd(0xe3800000 + (dest_reg << 12) + (dest_reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // orr dest_reg, dest_reg, #((imm & 0xff) << scale) + } + imm>>=8; + scale+=8; + } + } else { + imm2 = ~imm; + while (imm2) { + while ((imm2 & 3) == 0) { + imm2>>=2; + scale+=2; + } + if (first) { + cache_addd(0xe3e00000 + (dest_reg << 12) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // mvn dest_reg, #((imm2 & 0xff) << scale) + first = 0; + } else { + cache_addd(0xe3c00000 + (dest_reg << 12) + (dest_reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // bic dest_reg, dest_reg, #((imm2 & 0xff) << scale) + } + imm2>>=8; + scale+=8; + } + } + } +} + +// helper function for gen_mov_word_to_reg +static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,HostReg data_reg) { + // alignment.... + if (dword) { + if ((Bit32u)data & 3) { + if ( ((Bit32u)data & 3) == 2 ) { + cache_addd(0xe1d000b0 + (dest_reg << 12) + (data_reg << 16)); // ldrh dest_reg, [data_reg] + cache_addd(0xe1d000b2 + (temp2 << 12) + (data_reg << 16)); // ldrh temp2, [data_reg, #2] + cache_addd(0xe1800800 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #16 + } else { + cache_addd(0xe5d00000 + (dest_reg << 12) + (data_reg << 16)); // ldrb dest_reg, [data_reg] + cache_addd(0xe1d000b1 + (temp2 << 12) + (data_reg << 16)); // ldrh temp2, [data_reg, #1] + cache_addd(0xe1800400 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #8 + cache_addd(0xe5d00003 + (temp2 << 12) + (data_reg << 16)); // ldrb temp2, [data_reg, #3] + cache_addd(0xe1800c00 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #24 + } + } else { + cache_addd(0xe5900000 + (dest_reg << 12) + (data_reg << 16)); // ldr dest_reg, [data_reg] + } + } else { + if ((Bit32u)data & 1) { + cache_addd(0xe5d00000 + (dest_reg << 12) + (data_reg << 16)); // ldrb dest_reg, [data_reg] + cache_addd(0xe5d00001 + (temp2 << 12) + (data_reg << 16)); // ldrb temp2, [data_reg, #1] + cache_addd(0xe1800400 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #8 + } else { + cache_addd(0xe1d000b0 + (dest_reg << 12) + (data_reg << 16)); // ldrh dest_reg, [data_reg] + } + } +} + +// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { + gen_mov_dword_to_reg_imm(temp1, (Bit32u)data); + gen_mov_word_to_reg_helper(dest_reg, data, dword, temp1); +} + +// move a 16bit constant value into dest_reg +// the upper 16bit of the destination register may be destroyed +static void gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { + Bits first, scale; + Bit32u imm2; + if (imm == 0) { + cache_addd(0xe3a00000 + (dest_reg << 12)); // mov dest_reg, #0 + } else { + scale = 0; + first = 1; + imm2 = (Bit32u)imm; + while (imm2) { + while ((imm2 & 3) == 0) { + imm2>>=2; + scale+=2; + } + if (first) { + cache_addd(0xe3a00000 + (dest_reg << 12) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // mov dest_reg, #((imm2 & 0xff) << scale) + first = 0; + } else { + cache_addd(0xe3800000 + (dest_reg << 12) + (dest_reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // orr dest_reg, dest_reg, #((imm2 & 0xff) << scale) + } + imm2>>=8; + scale+=8; + } + } +} + +// helper function for gen_mov_word_from_reg +static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, HostReg data_reg) { + // alignment.... + if (dword) { + if ((Bit32u)dest & 3) { + if ( ((Bit32u)dest & 3) == 2 ) { + cache_addd(0xe1c000b0 + (src_reg << 12) + (data_reg << 16)); // strh src_reg, [data_reg] + cache_addd(0xe1a00820 + (temp2 << 12) + (src_reg)); // mov temp2, src_reg, lsr #16 + cache_addd(0xe1c000b2 + (temp2 << 12) + (data_reg << 16)); // strh temp2, [data_reg, #2] + } else { + cache_addd(0xe5c00000 + (src_reg << 12) + (data_reg << 16)); // strb src_reg, [data_reg] + cache_addd(0xe1a00420 + (temp2 << 12) + (src_reg)); // mov temp2, src_reg, lsr #8 + cache_addd(0xe1c000b1 + (temp2 << 12) + (data_reg << 16)); // strh temp2, [data_reg, #1] + cache_addd(0xe1a00820 + (temp2 << 12) + (temp2)); // mov temp2, temp2, lsr #16 + cache_addd(0xe5c00003 + (temp2 << 12) + (data_reg << 16)); // strb temp2, [data_reg, #3] + } + } else { + cache_addd(0xe5800000 + (src_reg << 12) + (data_reg << 16)); // str src_reg, [data_reg] + } + } else { + if ((Bit32u)dest & 1) { + cache_addd(0xe5c00000 + (src_reg << 12) + (data_reg << 16)); // strb src_reg, [data_reg] + cache_addd(0xe1a00420 + (temp2 << 12) + (src_reg)); // mov temp2, src_reg, lsr #8 + cache_addd(0xe5c00001 + (temp2 << 12) + (data_reg << 16)); // strb temp2, [data_reg, #1] + } else { + cache_addd(0xe1c000b0 + (src_reg << 12) + (data_reg << 16)); // strh src_reg, [data_reg] + } + } +} + +// move 32bit (dword==true) or 16bit (dword==false) of a register into memory +static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { + gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); + gen_mov_word_from_reg_helper(src_reg, dest, dword, temp1); +} + +// move an 8bit value from memory into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { + gen_mov_dword_to_reg_imm(temp1, (Bit32u)data); + cache_addd(0xe5d00000 + (dest_reg << 12) + (temp1 << 16)); // ldrb dest_reg, [temp1] +} + +// move an 8bit value from memory into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { + gen_mov_byte_to_reg_low(dest_reg, data); +} + +// move an 8bit constant value into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { + cache_addd(0xe3a00000 + (dest_reg << 12) + (imm)); // mov dest_reg, #(imm) +} + +// move an 8bit constant value into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { + gen_mov_byte_to_reg_low_imm(dest_reg, imm); +} + +// move the lowest 8bit of a register into memory +static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { + gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); + cache_addd(0xe5c00000 + (src_reg << 12) + (temp1 << 16)); // strb src_reg, [temp1] +} + + + +// convert an 8bit word to a 32bit dword +// the register is zero-extended (sign==false) or sign-extended (sign==true) +static void gen_extend_byte(bool sign,HostReg reg) { + if (sign) { + cache_addd(0xe1a00c00 + (reg << 12) + (reg)); // mov reg, reg, lsl #24 + cache_addd(0xe1a00c40 + (reg << 12) + (reg)); // mov reg, reg, asr #24 + } else { + cache_addd(0xe20000ff + (reg << 12) + (reg << 16)); // and reg, reg, #0xff + } +} + +// convert a 16bit word to a 32bit dword +// the register is zero-extended (sign==false) or sign-extended (sign==true) +static void gen_extend_word(bool sign,HostReg reg) { + if (sign) { + cache_addd(0xe1a00800 + (reg << 12) + (reg)); // mov reg, reg, lsl #16 + cache_addd(0xe1a00840 + (reg << 12) + (reg)); // mov reg, reg, asr #16 + } else { + cache_addd(0xe1a00800 + (reg << 12) + (reg)); // mov reg, reg, lsl #16 + cache_addd(0xe1a00820 + (reg << 12) + (reg)); // mov reg, reg, lsr #16 + } +} + +// add a 32bit value from memory to a full register +static void gen_add(HostReg reg,void* op) { + gen_mov_word_to_reg(temp3, op, 1); + cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp3)); // add reg, reg, temp3 +} + +// add a 32bit constant value to a full register +static void gen_add_imm(HostReg reg,Bit32u imm) { + Bits method1, method2, num1, num2, scale, sub; + if(!imm) return; + if (imm == 1) { + cache_addd(0xe2800001 + (reg << 12) + (reg << 16)); // add reg, reg, #1 + } else if (imm == 0xffffffff) { + cache_addd(0xe2400001 + (reg << 12) + (reg << 16)); // sub reg, reg, #1 + } else { + method1 = get_method_imm_gen_len(imm, 1, &num1); + method2 = get_method_imm_gen_len(-((Bit32s)imm), 1, &num2); + if (num2 < num1) { + method1 = method2; + imm = (Bit32u)(-((Bit32s)imm)); + sub = 1; + } else sub = 0; + + if (method1 != 2) { + gen_mov_dword_to_reg_imm(temp3, imm); + if (sub) { + cache_addd(0xe0400000 + (reg << 12) + (reg << 16) + (temp3)); // sub reg, reg, temp3 + } else { + cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp3)); // add reg, reg, temp3 + } + } else { + scale = 0; + while (imm) { + while ((imm & 3) == 0) { + imm>>=2; + scale+=2; + } + if (sub) { + cache_addd(0xe2400000 + (reg << 12) + (reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // sub reg, reg, #((imm & 0xff) << scale) + } else { + cache_addd(0xe2800000 + (reg << 12) + (reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // add reg, reg, #((imm & 0xff) << scale) + } + imm>>=8; + scale+=8; + } + } + } +} + +// and a 32bit constant value with a full register +static void gen_and_imm(HostReg reg,Bit32u imm) { + Bits method, scale; + Bit32u imm2; + imm2 = ~imm; + if(!imm2) return; + if (!imm) { + cache_addd(0xe3a00000 + (reg << 12)); // mov reg, #0 + } else { + method = get_method_imm_gen_len(imm, 0, NULL); + if (method != 3) { + gen_mov_dword_to_reg_imm(temp3, imm); + cache_addd(0xe0000000 + (reg << 12) + (reg << 16) + (temp3)); // and reg, reg, temp3 + } else { + scale = 0; + while (imm2) { + while ((imm2 & 3) == 0) { + imm2>>=2; + scale+=2; + } + cache_addd(0xe3c00000 + (reg << 12) + (reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // bic reg, reg, #((imm2 & 0xff) << scale) + imm2>>=8; + scale+=8; + } + } + } +} + + +// move a 32bit constant value into memory +static void gen_mov_direct_dword(void* dest,Bit32u imm) { + gen_mov_dword_to_reg_imm(temp3, imm); + gen_mov_word_from_reg(temp3, dest, 1); +} + +// move an address into memory +static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { + gen_mov_direct_dword(dest,(Bit32u)imm); +} + +// add an 8bit constant value to a dword memory value +static void gen_add_direct_byte(void* dest,Bit8s imm) { + if(!imm) return; + gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); + gen_mov_word_to_reg_helper(temp3, dest, 1, temp1); + if (imm >= 0) { + cache_addd(0xe2800000 + (temp3 << 12) + (temp3 << 16) + ((Bit32s)imm)); // add temp3, temp3, #(imm) + } else { + cache_addd(0xe2400000 + (temp3 << 12) + (temp3 << 16) + (-((Bit32s)imm))); // sub temp3, temp3, #(-imm) + } + gen_mov_word_from_reg_helper(temp3, dest, 1, temp1); +} + +// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value +static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { + if(!imm) return; + if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { + gen_add_direct_byte(dest,(Bit8s)imm); + return; + } + gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); + gen_mov_word_to_reg_helper(temp3, dest, dword, temp1); + // maybe use function gen_add_imm + if (dword) { + gen_mov_dword_to_reg_imm(temp2, imm); + } else { + gen_mov_word_to_reg_imm(temp2, (Bit16u)imm); + } + cache_addd(0xe0800000 + (temp3 << 12) + (temp3 << 16) + (temp2)); // add temp3, temp3, temp2 + gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); +} + +// subtract an 8bit constant value from a dword memory value +static void gen_sub_direct_byte(void* dest,Bit8s imm) { + if(!imm) return; + gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); + gen_mov_word_to_reg_helper(temp3, dest, 1, temp1); + if (imm >= 0) { + cache_addd(0xe2400000 + (temp3 << 12) + (temp3 << 16) + ((Bit32s)imm)); // sub temp3, temp3, #(imm) + } else { + cache_addd(0xe2800000 + (temp3 << 12) + (temp3 << 16) + (-((Bit32s)imm))); // add temp3, temp3, #(-imm) + } + gen_mov_word_from_reg_helper(temp3, dest, 1, temp1); +} + +// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value +static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { + if(!imm) return; + if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { + gen_sub_direct_byte(dest,(Bit8s)imm); + return; + } + gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); + gen_mov_word_to_reg_helper(temp3, dest, dword, temp1); + // maybe use function gen_add_imm/gen_sub_imm + if (dword) { + gen_mov_dword_to_reg_imm(temp2, imm); + } else { + gen_mov_word_to_reg_imm(temp2, (Bit16u)imm); + } + cache_addd(0xe0400000 + (temp3 << 12) + (temp3 << 16) + (temp2)); // sub temp3, temp3, temp2 + gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); +} + +// effective address calculation, destination is dest_reg +// scale_reg is scaled by scale (scale_reg*(2^scale)) and +// added to dest_reg, then the immediate value is added +static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { + cache_addd(0xe0800000 + (dest_reg << 12) + (dest_reg << 16) + (scale_reg) + (scale << 7)); // add dest_reg, dest_reg, scale_reg, lsl #(scale) + gen_add_imm(dest_reg, imm); +} + +// effective address calculation, destination is dest_reg +// dest_reg is scaled by scale (dest_reg*(2^scale)), +// then the immediate value is added +static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { + if (scale) { + cache_addd(0xe1a00000 + (dest_reg << 12) + (dest_reg) + (scale << 7)); // mov dest_reg, dest_reg, lsl #(scale) + } + gen_add_imm(dest_reg, imm); +} + +// generate a call to a parameterless function +static void INLINE gen_call_function_raw(void * func) { + cache_addd(0xe5900004 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #4] + cache_addd(0xe2800004 + (HOST_lr << 12) + (HOST_pc << 16)); // add lr, pc, #4 + cache_addd(0xe12fff10 + (temp1)); // bx temp1 + cache_addd((Bit32u)func); // .int func + cache_addd(0xe1a00000 + (FC_RETOP << 12) + HOST_a1); // mov FC_RETOP, a1 +} + +// generate a call to a function with paramcount parameters +// note: the parameters are loaded in the architecture specific way +// using the gen_load_param_ functions below +static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { + Bit32u proc_addr = (Bit32u)cache.pos; + gen_call_function_raw(func); + return proc_addr; +} + +#if (1) +// max of 4 parameters in a1-a4 + +// load an immediate value as param'th function parameter +static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { + gen_mov_dword_to_reg_imm(param, imm); +} + +// load an address as param'th function parameter +static void INLINE gen_load_param_addr(Bitu addr,Bitu param) { + gen_mov_dword_to_reg_imm(param, addr); +} + +// load a host-register as param'th function parameter +static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { + gen_mov_regs(param, reg); +} + +// load a value from memory as param'th function parameter +static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { + gen_mov_word_to_reg(param, (void *)mem, 1); +} +#else + other arm abis +#endif + +// jump to an address pointed at by ptr, offset is in imm +static void gen_jmp_ptr(void * ptr,Bits imm=0) { + Bits num1, num2, scale, sub; + Bitu imm2; + gen_mov_word_to_reg(temp3, ptr, 1); + + if (imm) { + num1 = get_imm_gen_len(imm); + num2 = get_imm_gen_len(-imm); + + if (num2 < num1) { + imm = -imm; + sub = 1; + } else sub = 0; + + scale = 0; + imm2 = (Bitu)imm; + while (imm2) { + while ((imm2 & 3) == 0) { + imm2>>=2; + scale+=2; + } + if (sub) { + cache_addd(0xe2400000 + (temp3 << 12) + (temp3 << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // sub temp3, temp3, #((imm2 & 0xff) << scale) + } else { + cache_addd(0xe2800000 + (temp3 << 12) + (temp3 << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // add temp3, temp3, #((imm2 & 0xff) << scale) + } + imm2>>=8; + scale+=8; + } + } + +#if (1) +// (*ptr) should be word aligned + if ((imm & 0x03) == 0) { + cache_addd(0xe5900000 + (temp1 << 12) + (temp3 << 16)); // ldr temp1, [temp3] + } else +#endif + { + cache_addd(0xe5d00000 + (temp1 << 12) + (temp3 << 16)); // ldrb temp1, [temp3] + cache_addd(0xe5d00001 + (temp2 << 12) + (temp3 << 16)); // ldrb temp2, [temp3, #1] + cache_addd(0xe1800400 + (temp1 << 12) + (temp1 << 16) + (temp2)); // orr temp1, temp1, temp2, lsl #8 + cache_addd(0xe5d00002 + (temp2 << 12) + (temp3 << 16)); // ldrb temp2, [temp3, #2] + cache_addd(0xe1800800 + (temp1 << 12) + (temp1 << 16) + (temp2)); // orr temp1, temp1, temp2, lsl #16 + cache_addd(0xe5d00003 + (temp2 << 12) + (temp3 << 16)); // ldrb temp2, [temp3, #3] + cache_addd(0xe1800c00 + (temp1 << 12) + (temp1 << 16) + (temp2)); // orr temp1, temp1, temp2, lsl #24 + } + + cache_addd(0xe12fff10 + (temp1)); // bx temp1 +} + +// short conditional jump (+-127 bytes) if register is zero +// the destination is set by gen_fill_branch() later +static Bit32u INLINE gen_create_branch_on_zero(HostReg reg,bool dword) { + if (dword) { + cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 + } else { + cache_addd(0xe1b00800 + (temp1 << 12) + (reg)); // movs temp1, reg, lsl #16 + } + cache_addd(0x0a000000); // beq j + return ((Bit32u)cache.pos-4); +} + +// short conditional jump (+-127 bytes) if register is nonzero +// the destination is set by gen_fill_branch() later +static Bit32u INLINE gen_create_branch_on_nonzero(HostReg reg,bool dword) { + if (dword) { + cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 + } else { + cache_addd(0xe1b00800 + (temp1 << 12) + (reg)); // movs temp1, reg, lsl #16 + } + cache_addd(0x1a000000); // bne j + return ((Bit32u)cache.pos-4); +} + +// calculate relative offset and fill it into the location pointed to by data +static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) { +#if C_DEBUG + Bits len=(Bit32u)cache.pos-(data+8); + if (len<0) len=-len; + if (len>0x02000000) LOG_MSG("Big jump %d",len); +#endif + *(Bit32u*)data=( (*(Bit32u*)data) & 0xff000000 ) | ( ( ((Bit32u)cache.pos - (data+8)) >> 2 ) & 0x00ffffff ); +} + +// conditional jump if register is nonzero +// for isdword==true the 32bit of the register are tested +// for isdword==false the lowest 8bit of the register are tested +static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { + if (isdword) { + cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 + } else { + cache_addd(0xe31000ff + (reg << 16)); // tst reg, #0xff + } + cache_addd(0x0a000002); // beq nobranch + cache_addd(0xe5900000 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #0] + cache_addd(0xe12fff10 + (temp1)); // bx temp1 + cache_addd(0); // fill j + // nobranch: + return ((Bit32u)cache.pos-4); +} + +// compare 32bit-register against zero and jump if value less/equal than zero +static Bit32u INLINE gen_create_branch_long_leqzero(HostReg reg) { + cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 + cache_addd(0xca000002); // bgt nobranch + cache_addd(0xe5900000 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #0] + cache_addd(0xe12fff10 + (temp1)); // bx temp1 + cache_addd(0); // fill j + // nobranch: + return ((Bit32u)cache.pos-4); +} + +// calculate long relative offset and fill it into the location pointed to by data +static void INLINE gen_fill_branch_long(Bit32u data) { + // this is an absolute branch + *(Bit32u*)data=(Bit32u)cache.pos; +} + +static void gen_run_code(void) { + cache_addd(0xe92d4000); // stmfd sp!, {lr} + cache_addd(0xe92d01f0); // stmfd sp!, {v1-v5} + cache_addd(0xe28fe004); // add lr, pc, #4 + cache_addd(0xe92d4000); // stmfd sp!, {lr} + cache_addd(0xe12fff10); // bx r0 + cache_addd(0xe8bd01f0); // ldmfd sp!, {v1-v5} + + cache_addd(0xe8bd4000); // ldmfd sp!, {lr} + cache_addd(0xe12fff1e); // bx lr +} + +// return from a function +static void gen_return_function(void) { + cache_addd(0xe1a00000 + (HOST_a1 << 12) + FC_RETOP); // mov a1, FC_RETOP + cache_addd(0xe8bd4000); // ldmfd sp!, {lr} + cache_addd(0xe12fff1e); // bx lr +} + +#ifdef DRC_FLAGS_INVALIDATION + +// called when a call to a function can be replaced by a +// call to a simpler function +static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { +#ifdef DRC_FLAGS_INVALIDATION_DCODE + // try to avoid function calls but rather directly fill in code + switch (flags_type) { + case t_ADDb: + case t_ADDw: + case t_ADDd: + *(Bit32u*)pos=0xe0800000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // add FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_ORb: + case t_ORw: + case t_ORd: + *(Bit32u*)pos=0xe1800000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // orr FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_ANDb: + case t_ANDw: + case t_ANDd: + *(Bit32u*)pos=0xe0000000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // and FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_SUBb: + case t_SUBw: + case t_SUBd: + *(Bit32u*)pos=0xe0400000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // sub FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_XORb: + case t_XORw: + case t_XORd: + *(Bit32u*)pos=0xe0200000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // eor FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_CMPb: + case t_CMPw: + case t_CMPd: + case t_TESTb: + case t_TESTw: + case t_TESTd: + *(Bit32u*)pos=0xea000000 + (3); // b (pc+3*4) + break; + case t_INCb: + case t_INCw: + case t_INCd: + *(Bit32u*)pos=0xe2800000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (1); // add FC_RETOP, a1, #1 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_DECb: + case t_DECw: + case t_DECd: + *(Bit32u*)pos=0xe2400000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (1); // sub FC_RETOP, a1, #1 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_SHLb: + case t_SHLw: + case t_SHLd: + *(Bit32u*)pos=0xe1a00010 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, lsl a2 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_SHRb: + *(Bit32u*)pos=0xe2000000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (0xff); // and FC_RETOP, a1, #0xff + *(Bit32u*)(pos+4)=0xe1a00030 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, lsr a2 + *(Bit32u*)(pos+8)=0xe1a00000; // nop + *(Bit32u*)(pos+12)=0xe1a00000; // nop + *(Bit32u*)(pos+16)=0xe1a00000; // nop + break; + case t_SHRw: + *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+4)=0xe1a00020 + (FC_RETOP << 12) + (FC_RETOP) + (16 << 7); // mov FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+8)=0xe1a00030 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, lsr a2 + *(Bit32u*)(pos+12)=0xe1a00000; // nop + *(Bit32u*)(pos+16)=0xe1a00000; // nop + break; + case t_SHRd: + *(Bit32u*)pos=0xe1a00030 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, lsr a2 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_SARb: + *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (24 << 7); // mov FC_RETOP, a1, lsl #24 + *(Bit32u*)(pos+4)=0xe1a00040 + (FC_RETOP << 12) + (FC_RETOP) + (24 << 7); // mov FC_RETOP, FC_RETOP, asr #24 + *(Bit32u*)(pos+8)=0xe1a00050 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, asr a2 + *(Bit32u*)(pos+12)=0xe1a00000; // nop + *(Bit32u*)(pos+16)=0xe1a00000; // nop + break; + case t_SARw: + *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+4)=0xe1a00040 + (FC_RETOP << 12) + (FC_RETOP) + (16 << 7); // mov FC_RETOP, FC_RETOP, asr #16 + *(Bit32u*)(pos+8)=0xe1a00050 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, asr a2 + *(Bit32u*)(pos+12)=0xe1a00000; // nop + *(Bit32u*)(pos+16)=0xe1a00000; // nop + break; + case t_SARd: + *(Bit32u*)pos=0xe1a00050 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, asr a2 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_RORb: + *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (24 << 7); // mov FC_RETOP, a1, lsl #24 + *(Bit32u*)(pos+4)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (8 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 + *(Bit32u*)(pos+8)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+12)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2 + *(Bit32u*)(pos+16)=0xe1a00000; // nop + break; + case t_RORw: + *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+4)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+8)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2 + *(Bit32u*)(pos+12)=0xe1a00000; // nop + *(Bit32u*)(pos+16)=0xe1a00000; // nop + break; + case t_RORd: + *(Bit32u*)pos=0xe1a00070 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, ror a2 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_ROLb: + *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (24 << 7); // mov FC_RETOP, a1, lsl #24 + *(Bit32u*)(pos+4)=0xe2600000 + (HOST_a2 << 12) + (HOST_a2 << 16) + (32); // rsb a2, a2, #32 + *(Bit32u*)(pos+8)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (8 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 + *(Bit32u*)(pos+12)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+16)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2 + break; + case t_ROLw: + *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+4)=0xe2600000 + (HOST_a2 << 12) + (HOST_a2 << 16) + (32); // rsb a2, a2, #32 + *(Bit32u*)(pos+8)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+12)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2 + *(Bit32u*)(pos+16)=0xe1a00000; // nop + break; + case t_ROLd: + *(Bit32u*)pos=0xe2600000 + (HOST_a2 << 12) + (HOST_a2 << 16) + (32); // rsb a2, a2, #32 + *(Bit32u*)(pos+4)=0xe1a00070 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, ror a2 + *(Bit32u*)(pos+8)=0xe1a00000; // nop + *(Bit32u*)(pos+12)=0xe1a00000; // nop + *(Bit32u*)(pos+16)=0xe1a00000; // nop + break; + case t_NEGb: + case t_NEGw: + case t_NEGd: + *(Bit32u*)pos=0xe2600000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (0); // rsb FC_RETOP, a1, #0 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + default: + *(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func + break; + + } +#else + *(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func +#endif +} +#endif diff --git a/src/cpu/core_dynrec/risc_armv4le-s3.h b/src/cpu/core_dynrec/risc_armv4le-s3.h new file mode 100644 index 00000000..6388538d --- /dev/null +++ b/src/cpu/core_dynrec/risc_armv4le-s3.h @@ -0,0 +1,694 @@ +/* + * 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: risc_armv4le-s3.h,v 1.1 2008-08-20 14:13:21 c2woody Exp $ */ + + +/* ARMv4 (little endian) backend by M-HT (speed-tweaked arm version) */ + + +// temporary registers +#define temp1 HOST_ip +#define temp2 HOST_v5 +#define temp3 HOST_v4 + +// register that holds function return values +#define FC_RETOP HOST_v3 + +// register used for address calculations, +#define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG + +// register that holds the first parameter +#define FC_OP1 HOST_a1 + +// register that holds the second parameter +#define FC_OP2 HOST_a2 + +// register that holds byte-accessible temporary values +#define FC_TMP_BA1 HOST_a1 + +// register that holds byte-accessible temporary values +#define FC_TMP_BA2 HOST_a2 + +// temporary register for LEA +#define TEMP_REG_DRC HOST_v2 + +// helper macro +#define ROTATE_SCALE(x) ( (x)?(32 - x):(0) ) + +// move a full register from reg_src to reg_dst +static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { + if(reg_src == reg_dst) return; + cache_addd(0xe1a00000 + (reg_dst << 12) + reg_src); // mov reg_dst, reg_src +} + +// move a 32bit constant value into dest_reg +static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { + Bits first, scale; + if (imm == 0) { + cache_addd(0xe3a00000 + (dest_reg << 12)); // mov dest_reg, #0 + } else { + scale = 0; + first = 1; + while (imm) { + while ((imm & 3) == 0) { + imm>>=2; + scale+=2; + } + if (first) { + cache_addd(0xe3a00000 + (dest_reg << 12) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // mov dest_reg, #((imm & 0xff) << scale) + first = 0; + } else { + cache_addd(0xe3800000 + (dest_reg << 12) + (dest_reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // orr dest_reg, dest_reg, #((imm & 0xff) << scale) + } + imm>>=8; + scale+=8; + } + } +} + +// helper function for gen_mov_word_to_reg +static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,HostReg data_reg) { + // alignment.... + if (dword) { + if ((Bit32u)data & 3) { + if ( ((Bit32u)data & 3) == 2 ) { + cache_addd(0xe1d000b0 + (dest_reg << 12) + (data_reg << 16)); // ldrh dest_reg, [data_reg] + cache_addd(0xe1d000b2 + (temp2 << 12) + (data_reg << 16)); // ldrh temp2, [data_reg, #2] + cache_addd(0xe1800800 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #16 + } else { + cache_addd(0xe5d00000 + (dest_reg << 12) + (data_reg << 16)); // ldrb dest_reg, [data_reg] + cache_addd(0xe1d000b1 + (temp2 << 12) + (data_reg << 16)); // ldrh temp2, [data_reg, #1] + cache_addd(0xe1800400 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #8 + cache_addd(0xe5d00003 + (temp2 << 12) + (data_reg << 16)); // ldrb temp2, [data_reg, #3] + cache_addd(0xe1800c00 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #24 + } + } else { + cache_addd(0xe5900000 + (dest_reg << 12) + (data_reg << 16)); // ldr dest_reg, [data_reg] + } + } else { + if ((Bit32u)data & 1) { + cache_addd(0xe5d00000 + (dest_reg << 12) + (data_reg << 16)); // ldrb dest_reg, [data_reg] + cache_addd(0xe5d00001 + (temp2 << 12) + (data_reg << 16)); // ldrb temp2, [data_reg, #1] + cache_addd(0xe1800400 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #8 + } else { + cache_addd(0xe1d000b0 + (dest_reg << 12) + (data_reg << 16)); // ldrh dest_reg, [data_reg] + } + } +} + +// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { + gen_mov_dword_to_reg_imm(temp1, (Bit32u)data); + gen_mov_word_to_reg_helper(dest_reg, data, dword, temp1); +} + +// move a 16bit constant value into dest_reg +// the upper 16bit of the destination register may be destroyed +static void INLINE gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { + gen_mov_dword_to_reg_imm(dest_reg, (Bit32u)imm); +} + +// helper function for gen_mov_word_from_reg +static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, HostReg data_reg) { + // alignment.... + if (dword) { + if ((Bit32u)dest & 3) { + if ( ((Bit32u)dest & 3) == 2 ) { + cache_addd(0xe1c000b0 + (src_reg << 12) + (data_reg << 16)); // strh src_reg, [data_reg] + cache_addd(0xe1a00820 + (temp2 << 12) + (src_reg)); // mov temp2, src_reg, lsr #16 + cache_addd(0xe1c000b2 + (temp2 << 12) + (data_reg << 16)); // strh temp2, [data_reg, #2] + } else { + cache_addd(0xe5c00000 + (src_reg << 12) + (data_reg << 16)); // strb src_reg, [data_reg] + cache_addd(0xe1a00420 + (temp2 << 12) + (src_reg)); // mov temp2, src_reg, lsr #8 + cache_addd(0xe1c000b1 + (temp2 << 12) + (data_reg << 16)); // strh temp2, [data_reg, #1] + cache_addd(0xe1a00820 + (temp2 << 12) + (temp2)); // mov temp2, temp2, lsr #16 + cache_addd(0xe5c00003 + (temp2 << 12) + (data_reg << 16)); // strb temp2, [data_reg, #3] + } + } else { + cache_addd(0xe5800000 + (src_reg << 12) + (data_reg << 16)); // str src_reg, [data_reg] + } + } else { + if ((Bit32u)dest & 1) { + cache_addd(0xe5c00000 + (src_reg << 12) + (data_reg << 16)); // strb src_reg, [data_reg] + cache_addd(0xe1a00420 + (temp2 << 12) + (src_reg)); // mov temp2, src_reg, lsr #8 + cache_addd(0xe5c00001 + (temp2 << 12) + (data_reg << 16)); // strb temp2, [data_reg, #1] + } else { + cache_addd(0xe1c000b0 + (src_reg << 12) + (data_reg << 16)); // strh src_reg, [data_reg] + } + } +} + +// move 32bit (dword==true) or 16bit (dword==false) of a register into memory +static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { + gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); + gen_mov_word_from_reg_helper(src_reg, dest, dword, temp1); +} + +// move an 8bit value from memory into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { + gen_mov_dword_to_reg_imm(temp1, (Bit32u)data); + cache_addd(0xe5d00000 + (dest_reg << 12) + (temp1 << 16)); // ldrb dest_reg, [temp1] +} + +// move an 8bit value from memory into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { + gen_mov_byte_to_reg_low(dest_reg, data); +} + +// move an 8bit constant value into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { + cache_addd(0xe3a00000 + (dest_reg << 12) + (imm)); // mov dest_reg, #(imm) +} + +// move an 8bit constant value into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { + gen_mov_byte_to_reg_low_imm(dest_reg, imm); +} + +// move the lowest 8bit of a register into memory +static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { + gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); + cache_addd(0xe5c00000 + (src_reg << 12) + (temp1 << 16)); // strb src_reg, [temp1] +} + + + +// convert an 8bit word to a 32bit dword +// the register is zero-extended (sign==false) or sign-extended (sign==true) +static void gen_extend_byte(bool sign,HostReg reg) { + if (sign) { + cache_addd(0xe1a00c00 + (reg << 12) + (reg)); // mov reg, reg, lsl #24 + cache_addd(0xe1a00c40 + (reg << 12) + (reg)); // mov reg, reg, asr #24 + } else { + cache_addd(0xe20000ff + (reg << 12) + (reg << 16)); // and reg, reg, #0xff + } +} + +// convert a 16bit word to a 32bit dword +// the register is zero-extended (sign==false) or sign-extended (sign==true) +static void gen_extend_word(bool sign,HostReg reg) { + if (sign) { + cache_addd(0xe1a00800 + (reg << 12) + (reg)); // mov reg, reg, lsl #16 + cache_addd(0xe1a00840 + (reg << 12) + (reg)); // mov reg, reg, asr #16 + } else { + cache_addd(0xe1a00800 + (reg << 12) + (reg)); // mov reg, reg, lsl #16 + cache_addd(0xe1a00820 + (reg << 12) + (reg)); // mov reg, reg, lsr #16 + } +} + +// add a 32bit value from memory to a full register +static void gen_add(HostReg reg,void* op) { + gen_mov_word_to_reg(temp3, op, 1); + cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp3)); // add reg, reg, temp3 +} + +// add a 32bit constant value to a full register +static void gen_add_imm(HostReg reg,Bit32u imm) { + Bits scale; + if(!imm) return; + if (imm == 0xffffffff) { + cache_addd(0xe2400001 + (reg << 12) + (reg << 16)); // sub reg, reg, #1 + } else { + scale = 0; + while (imm) { + while ((imm & 3) == 0) { + imm>>=2; + scale+=2; + } + cache_addd(0xe2800000 + (reg << 12) + (reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // add reg, reg, #((imm & 0xff) << scale) + imm>>=8; + scale+=8; + } + } +} + +// and a 32bit constant value with a full register +static void gen_and_imm(HostReg reg,Bit32u imm) { + Bits scale; + Bit32u imm2; + imm2 = ~imm; + if(!imm2) return; + if (!imm) { + cache_addd(0xe3a00000 + (reg << 12)); // mov reg, #0 + } else { + scale = 0; + while (imm2) { + while ((imm2 & 3) == 0) { + imm2>>=2; + scale+=2; + } + cache_addd(0xe3c00000 + (reg << 12) + (reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // bic reg, reg, #((imm2 & 0xff) << scale) + imm2>>=8; + scale+=8; + } + } +} + + +// move a 32bit constant value into memory +static void gen_mov_direct_dword(void* dest,Bit32u imm) { + gen_mov_dword_to_reg_imm(temp3, imm); + gen_mov_word_from_reg(temp3, dest, 1); +} + +// move an address into memory +static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { + gen_mov_direct_dword(dest,(Bit32u)imm); +} + +// add an 8bit constant value to a dword memory value +static void gen_add_direct_byte(void* dest,Bit8s imm) { + if(!imm) return; + gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); + gen_mov_word_to_reg_helper(temp3, dest, 1, temp1); + if (imm >= 0) { + cache_addd(0xe2800000 + (temp3 << 12) + (temp3 << 16) + ((Bit32s)imm)); // add temp3, temp3, #(imm) + } else { + cache_addd(0xe2400000 + (temp3 << 12) + (temp3 << 16) + (-((Bit32s)imm))); // sub temp3, temp3, #(-imm) + } + gen_mov_word_from_reg_helper(temp3, dest, 1, temp1); +} + +// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value +static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { + if(!imm) return; + if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { + gen_add_direct_byte(dest,(Bit8s)imm); + return; + } + gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); + gen_mov_word_to_reg_helper(temp3, dest, dword, temp1); + // maybe use function gen_add_imm + if (dword) { + gen_mov_dword_to_reg_imm(temp2, imm); + } else { + gen_mov_word_to_reg_imm(temp2, (Bit16u)imm); + } + cache_addd(0xe0800000 + (temp3 << 12) + (temp3 << 16) + (temp2)); // add temp3, temp3, temp2 + gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); +} + +// subtract an 8bit constant value from a dword memory value +static void gen_sub_direct_byte(void* dest,Bit8s imm) { + if(!imm) return; + gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); + gen_mov_word_to_reg_helper(temp3, dest, 1, temp1); + if (imm >= 0) { + cache_addd(0xe2400000 + (temp3 << 12) + (temp3 << 16) + ((Bit32s)imm)); // sub temp3, temp3, #(imm) + } else { + cache_addd(0xe2800000 + (temp3 << 12) + (temp3 << 16) + (-((Bit32s)imm))); // add temp3, temp3, #(-imm) + } + gen_mov_word_from_reg_helper(temp3, dest, 1, temp1); +} + +// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value +static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { + if(!imm) return; + if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { + gen_sub_direct_byte(dest,(Bit8s)imm); + return; + } + gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); + gen_mov_word_to_reg_helper(temp3, dest, dword, temp1); + // maybe use function gen_add_imm/gen_sub_imm + if (dword) { + gen_mov_dword_to_reg_imm(temp2, imm); + } else { + gen_mov_word_to_reg_imm(temp2, (Bit16u)imm); + } + cache_addd(0xe0400000 + (temp3 << 12) + (temp3 << 16) + (temp2)); // sub temp3, temp3, temp2 + gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); +} + +// effective address calculation, destination is dest_reg +// scale_reg is scaled by scale (scale_reg*(2^scale)) and +// added to dest_reg, then the immediate value is added +static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { + cache_addd(0xe0800000 + (dest_reg << 12) + (dest_reg << 16) + (scale_reg) + (scale << 7)); // add dest_reg, dest_reg, scale_reg, lsl #(scale) + gen_add_imm(dest_reg, imm); +} + +// effective address calculation, destination is dest_reg +// dest_reg is scaled by scale (dest_reg*(2^scale)), +// then the immediate value is added +static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { + if (scale) { + cache_addd(0xe1a00000 + (dest_reg << 12) + (dest_reg) + (scale << 7)); // mov dest_reg, dest_reg, lsl #(scale) + } + gen_add_imm(dest_reg, imm); +} + +// generate a call to a parameterless function +static void INLINE gen_call_function_raw(void * func) { + cache_addd(0xe5900004 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #4] + cache_addd(0xe2800004 + (HOST_lr << 12) + (HOST_pc << 16)); // add lr, pc, #4 + cache_addd(0xe12fff10 + (temp1)); // bx temp1 + cache_addd((Bit32u)func); // .int func + cache_addd(0xe1a00000 + (FC_RETOP << 12) + HOST_a1); // mov FC_RETOP, a1 +} + +// generate a call to a function with paramcount parameters +// note: the parameters are loaded in the architecture specific way +// using the gen_load_param_ functions below +static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { + Bit32u proc_addr = (Bit32u)cache.pos; + gen_call_function_raw(func); + return proc_addr; +} + +#if (1) +// max of 4 parameters in a1-a4 + +// load an immediate value as param'th function parameter +static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { + gen_mov_dword_to_reg_imm(param, imm); +} + +// load an address as param'th function parameter +static void INLINE gen_load_param_addr(Bitu addr,Bitu param) { + gen_mov_dword_to_reg_imm(param, addr); +} + +// load a host-register as param'th function parameter +static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { + gen_mov_regs(param, reg); +} + +// load a value from memory as param'th function parameter +static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { + gen_mov_word_to_reg(param, (void *)mem, 1); +} +#else + other arm abis +#endif + +// jump to an address pointed at by ptr, offset is in imm +static void gen_jmp_ptr(void * ptr,Bits imm=0) { + Bits scale; + Bitu imm2; + gen_mov_word_to_reg(temp3, ptr, 1); + + if (imm) { + scale = 0; + imm2 = (Bitu)imm; + while (imm2) { + while ((imm2 & 3) == 0) { + imm2>>=2; + scale+=2; + } + cache_addd(0xe2800000 + (temp3 << 12) + (temp3 << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // add temp3, temp3, #((imm2 & 0xff) << scale) + imm2>>=8; + scale+=8; + } + } + +#if (1) +// (*ptr) should be word aligned + if ((imm & 0x03) == 0) { + cache_addd(0xe5900000 + (temp1 << 12) + (temp3 << 16)); // ldr temp1, [temp3] + } else +#endif + { + cache_addd(0xe5d00000 + (temp1 << 12) + (temp3 << 16)); // ldrb temp1, [temp3] + cache_addd(0xe5d00001 + (temp2 << 12) + (temp3 << 16)); // ldrb temp2, [temp3, #1] + cache_addd(0xe1800400 + (temp1 << 12) + (temp1 << 16) + (temp2)); // orr temp1, temp1, temp2, lsl #8 + cache_addd(0xe5d00002 + (temp2 << 12) + (temp3 << 16)); // ldrb temp2, [temp3, #2] + cache_addd(0xe1800800 + (temp1 << 12) + (temp1 << 16) + (temp2)); // orr temp1, temp1, temp2, lsl #16 + cache_addd(0xe5d00003 + (temp2 << 12) + (temp3 << 16)); // ldrb temp2, [temp3, #3] + cache_addd(0xe1800c00 + (temp1 << 12) + (temp1 << 16) + (temp2)); // orr temp1, temp1, temp2, lsl #24 + } + + cache_addd(0xe12fff10 + (temp1)); // bx temp1 +} + +// short conditional jump (+-127 bytes) if register is zero +// the destination is set by gen_fill_branch() later +static Bit32u INLINE gen_create_branch_on_zero(HostReg reg,bool dword) { + if (dword) { + cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 + } else { + cache_addd(0xe1b00800 + (temp1 << 12) + (reg)); // movs temp1, reg, lsl #16 + } + cache_addd(0x0a000000); // beq j + return ((Bit32u)cache.pos-4); +} + +// short conditional jump (+-127 bytes) if register is nonzero +// the destination is set by gen_fill_branch() later +static Bit32u INLINE gen_create_branch_on_nonzero(HostReg reg,bool dword) { + if (dword) { + cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 + } else { + cache_addd(0xe1b00800 + (temp1 << 12) + (reg)); // movs temp1, reg, lsl #16 + } + cache_addd(0x1a000000); // bne j + return ((Bit32u)cache.pos-4); +} + +// calculate relative offset and fill it into the location pointed to by data +static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) { +#if C_DEBUG + Bits len=(Bit32u)cache.pos-(data+8); + if (len<0) len=-len; + if (len>0x02000000) LOG_MSG("Big jump %d",len); +#endif + *(Bit32u*)data=( (*(Bit32u*)data) & 0xff000000 ) | ( ( ((Bit32u)cache.pos - (data+8)) >> 2 ) & 0x00ffffff ); +} + +// conditional jump if register is nonzero +// for isdword==true the 32bit of the register are tested +// for isdword==false the lowest 8bit of the register are tested +static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { + if (isdword) { + cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 + } else { + cache_addd(0xe31000ff + (reg << 16)); // tst reg, #0xff + } + cache_addd(0x0a000002); // beq nobranch + cache_addd(0xe5900000 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #0] + cache_addd(0xe12fff10 + (temp1)); // bx temp1 + cache_addd(0); // fill j + // nobranch: + return ((Bit32u)cache.pos-4); +} + +// compare 32bit-register against zero and jump if value less/equal than zero +static Bit32u INLINE gen_create_branch_long_leqzero(HostReg reg) { + cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 + cache_addd(0xca000002); // bgt nobranch + cache_addd(0xe5900000 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #0] + cache_addd(0xe12fff10 + (temp1)); // bx temp1 + cache_addd(0); // fill j + // nobranch: + return ((Bit32u)cache.pos-4); +} + +// calculate long relative offset and fill it into the location pointed to by data +static void INLINE gen_fill_branch_long(Bit32u data) { + // this is an absolute branch + *(Bit32u*)data=(Bit32u)cache.pos; +} + +static void gen_run_code(void) { + cache_addd(0xe92d4000); // stmfd sp!, {lr} + cache_addd(0xe92d01f0); // stmfd sp!, {v1-v5} + cache_addd(0xe28fe004); // add lr, pc, #4 + cache_addd(0xe92d4000); // stmfd sp!, {lr} + cache_addd(0xe12fff10); // bx r0 + cache_addd(0xe8bd01f0); // ldmfd sp!, {v1-v5} + + cache_addd(0xe8bd4000); // ldmfd sp!, {lr} + cache_addd(0xe12fff1e); // bx lr +} + +// return from a function +static void gen_return_function(void) { + cache_addd(0xe1a00000 + (HOST_a1 << 12) + FC_RETOP); // mov a1, FC_RETOP + cache_addd(0xe8bd4000); // ldmfd sp!, {lr} + cache_addd(0xe12fff1e); // bx lr +} + +#ifdef DRC_FLAGS_INVALIDATION + +// called when a call to a function can be replaced by a +// call to a simpler function +static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { +#ifdef DRC_FLAGS_INVALIDATION_DCODE + // try to avoid function calls but rather directly fill in code + switch (flags_type) { + case t_ADDb: + case t_ADDw: + case t_ADDd: + *(Bit32u*)pos=0xe0800000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // add FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_ORb: + case t_ORw: + case t_ORd: + *(Bit32u*)pos=0xe1800000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // orr FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_ANDb: + case t_ANDw: + case t_ANDd: + *(Bit32u*)pos=0xe0000000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // and FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_SUBb: + case t_SUBw: + case t_SUBd: + *(Bit32u*)pos=0xe0400000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // sub FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_XORb: + case t_XORw: + case t_XORd: + *(Bit32u*)pos=0xe0200000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // eor FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_CMPb: + case t_CMPw: + case t_CMPd: + case t_TESTb: + case t_TESTw: + case t_TESTd: + *(Bit32u*)pos=0xea000000 + (3); // b (pc+3*4) + break; + case t_INCb: + case t_INCw: + case t_INCd: + *(Bit32u*)pos=0xe2800000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (1); // add FC_RETOP, a1, #1 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_DECb: + case t_DECw: + case t_DECd: + *(Bit32u*)pos=0xe2400000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (1); // sub FC_RETOP, a1, #1 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_SHLb: + case t_SHLw: + case t_SHLd: + *(Bit32u*)pos=0xe1a00010 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, lsl a2 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_SHRb: + *(Bit32u*)pos=0xe2000000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (0xff); // and FC_RETOP, a1, #0xff + *(Bit32u*)(pos+4)=0xe1a00030 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, lsr a2 + *(Bit32u*)(pos+8)=0xe1a00000; // nop + *(Bit32u*)(pos+12)=0xe1a00000; // nop + *(Bit32u*)(pos+16)=0xe1a00000; // nop + break; + case t_SHRw: + *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+4)=0xe1a00020 + (FC_RETOP << 12) + (FC_RETOP) + (16 << 7); // mov FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+8)=0xe1a00030 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, lsr a2 + *(Bit32u*)(pos+12)=0xe1a00000; // nop + *(Bit32u*)(pos+16)=0xe1a00000; // nop + break; + case t_SHRd: + *(Bit32u*)pos=0xe1a00030 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, lsr a2 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_SARb: + *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (24 << 7); // mov FC_RETOP, a1, lsl #24 + *(Bit32u*)(pos+4)=0xe1a00040 + (FC_RETOP << 12) + (FC_RETOP) + (24 << 7); // mov FC_RETOP, FC_RETOP, asr #24 + *(Bit32u*)(pos+8)=0xe1a00050 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, asr a2 + *(Bit32u*)(pos+12)=0xe1a00000; // nop + *(Bit32u*)(pos+16)=0xe1a00000; // nop + break; + case t_SARw: + *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+4)=0xe1a00040 + (FC_RETOP << 12) + (FC_RETOP) + (16 << 7); // mov FC_RETOP, FC_RETOP, asr #16 + *(Bit32u*)(pos+8)=0xe1a00050 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, asr a2 + *(Bit32u*)(pos+12)=0xe1a00000; // nop + *(Bit32u*)(pos+16)=0xe1a00000; // nop + break; + case t_SARd: + *(Bit32u*)pos=0xe1a00050 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, asr a2 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_RORb: + *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (24 << 7); // mov FC_RETOP, a1, lsl #24 + *(Bit32u*)(pos+4)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (8 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 + *(Bit32u*)(pos+8)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+12)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2 + *(Bit32u*)(pos+16)=0xe1a00000; // nop + break; + case t_RORw: + *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+4)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+8)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2 + *(Bit32u*)(pos+12)=0xe1a00000; // nop + *(Bit32u*)(pos+16)=0xe1a00000; // nop + break; + case t_RORd: + *(Bit32u*)pos=0xe1a00070 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, ror a2 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + case t_ROLb: + *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (24 << 7); // mov FC_RETOP, a1, lsl #24 + *(Bit32u*)(pos+4)=0xe2600000 + (HOST_a2 << 12) + (HOST_a2 << 16) + (32); // rsb a2, a2, #32 + *(Bit32u*)(pos+8)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (8 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 + *(Bit32u*)(pos+12)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+16)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2 + break; + case t_ROLw: + *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+4)=0xe2600000 + (HOST_a2 << 12) + (HOST_a2 << 16) + (32); // rsb a2, a2, #32 + *(Bit32u*)(pos+8)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+12)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2 + *(Bit32u*)(pos+16)=0xe1a00000; // nop + break; + case t_ROLd: + *(Bit32u*)pos=0xe2600000 + (HOST_a2 << 12) + (HOST_a2 << 16) + (32); // rsb a2, a2, #32 + *(Bit32u*)(pos+4)=0xe1a00070 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, ror a2 + *(Bit32u*)(pos+8)=0xe1a00000; // nop + *(Bit32u*)(pos+12)=0xe1a00000; // nop + *(Bit32u*)(pos+16)=0xe1a00000; // nop + break; + case t_NEGb: + case t_NEGw: + case t_NEGd: + *(Bit32u*)pos=0xe2600000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (0); // rsb FC_RETOP, a1, #0 + *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + break; + default: + *(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func + break; + + } +#else + *(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func +#endif +} +#endif diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb.h b/src/cpu/core_dynrec/risc_armv4le-thumb.h new file mode 100644 index 00000000..1820fa39 --- /dev/null +++ b/src/cpu/core_dynrec/risc_armv4le-thumb.h @@ -0,0 +1,934 @@ +/* + * 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: risc_armv4le-thumb.h,v 1.1 2008-08-20 14:13:21 c2woody Exp $ */ + + +/* ARMv4 (little endian) backend by M-HT */ + + +// temporary "lo" registers +#define templo1 HOST_v3 +#define templo2 HOST_v4 + +// temporary "lo" register - value must be preserved when using it +#define templosav HOST_a3 + +// temporary "hi" register +#define temphi1 HOST_ip + +// register that holds function return values +#define FC_RETOP HOST_v2 + +// register used for address calculations, +#define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG + +// register that holds the first parameter +#define FC_OP1 HOST_a1 + +// register that holds the second parameter +#define FC_OP2 HOST_a2 + +// register that holds byte-accessible temporary values +#define FC_TMP_BA1 HOST_a1 + +// register that holds byte-accessible temporary values +#define FC_TMP_BA2 HOST_a2 + +// temporary register for LEA +#define TEMP_REG_DRC HOST_a4 + +// move a full register from reg_src to reg_dst +static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { + if(reg_src == reg_dst) return; + cache_addw(0x1c00 + reg_dst + (reg_src << 3)); // mov reg_dst, reg_src +} + +// move a 32bit constant value into dest_reg +static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { + if ((imm & 0xffffff00) == 0) { + cache_addw(0x2000 + (dest_reg << 8) + (Bit8u)(imm & 0xff)); // mov dest_reg, #(imm) + } else if ((imm & 0xffff00ff) == 0) { + cache_addw(0x2000 + (dest_reg << 8) + (Bit8u)(imm >> 8)); // mov dest_reg, #(imm >> 8) + cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (8 << 6)); // lsl dest_reg, dest_reg, #8 + } else if ((imm & 0xff00ffff) == 0) { + cache_addw(0x2000 + (dest_reg << 8) + (imm >> 16)); // mov dest_reg, #(imm >> 16) + cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (16 << 6)); // lsl dest_reg, dest_reg, #16 + } else if ((imm & 0x00ffffff) == 0) { + cache_addw(0x2000 + (dest_reg << 8) + (imm >> 24)); // mov dest_reg, #(imm >> 24) + cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (24 << 6)); // lsl dest_reg, dest_reg, #24 + } else { + Bit32u diff; + + diff = imm - ((Bit32u)cache.pos+4); + + if ((diff < 1024) && ((imm & 0x03) == 0)) { + if (((Bit32u)cache.pos & 0x03) == 0) { + cache_addw(0xa000 + (dest_reg << 8) + (Bit8u)(diff >> 2)); // add dest_reg, pc, #(dist >> 2) + } else { + cache_addw(0x46c0); // nop + // is the result of (diff-2)>>2 correct for diff<2 ??? + cache_addw(0xa000 + (dest_reg << 8) + (Bit8u)((diff - 2) >> 2)); // add dest_reg, pc, #((dist - 2) >> 2) + } + } else { + if (((Bit32u)cache.pos & 0x03) == 0) { + cache_addw(0x4800 + (dest_reg << 8)); // ldr dest_reg, [pc, #0] + cache_addw(0xe000 + (2 >> 1)); // b next_code (pc+2) + cache_addd(imm); // .int imm + // next_code: + } else { + cache_addw(0x4800 + (dest_reg << 8) + (4 >> 2)); // ldr dest_reg, [pc, #4] + cache_addw(0xe000 + (4 >> 1)); // b next_code (pc+4) + cache_addw(0x46c0); // nop + cache_addd(imm); // .int imm + // next_code: + } + } + } +} + +// helper function for gen_mov_word_to_reg +static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,HostReg data_reg) { + // alignment.... + if (dword) { + if ((Bit32u)data & 3) { + if ( ((Bit32u)data & 3) == 2 ) { + cache_addw(0x8800 + dest_reg + (data_reg << 3)); // ldrh dest_reg, [data_reg] + cache_addw(0x8800 + templo1 + (data_reg << 3) + (2 << 5)); // ldrh templo1, [data_reg, #2] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (16 << 6)); // lsl templo1, templo1, #16 + cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + } else { + cache_addw(0x7800 + dest_reg + (data_reg << 3)); // ldrb dest_reg, [data_reg] + cache_addw(0x1c00 + templo1 + (data_reg << 3) + (1 << 6)); // add templo1, data_reg, #1 + cache_addw(0x8800 + templo1 + (templo1 << 3)); // ldrh templo1, [templo1] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (8 << 6)); // lsl templo1, templo1, #8 + cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + cache_addw(0x7800 + templo1 + (data_reg << 3) + (3 << 6)); // ldrb templo1, [data_reg, #3] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (24 << 6)); // lsl templo1, templo1, #24 + cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + } + } else { + cache_addw(0x6800 + dest_reg + (data_reg << 3)); // ldr dest_reg, [data_reg] + } + } else { + if ((Bit32u)data & 1) { + cache_addw(0x7800 + dest_reg + (data_reg << 3)); // ldrb dest_reg, [data_reg] + cache_addw(0x7800 + templo1 + (data_reg << 3) + (1 << 6)); // ldrb templo1, [data_reg, #1] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (8 << 6)); // lsl templo1, templo1, #8 + cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + } else { + cache_addw(0x8800 + dest_reg + (data_reg << 3)); // ldrh dest_reg, [data_reg] + } + } +} + +// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { + gen_mov_dword_to_reg_imm(templo2, (Bit32u)data); + gen_mov_word_to_reg_helper(dest_reg, data, dword, templo2); +} + +// move a 16bit constant value into dest_reg +// the upper 16bit of the destination register may be destroyed +static void INLINE gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { + gen_mov_dword_to_reg_imm(dest_reg, (Bit32u)imm); +} + +// helper function for gen_mov_word_from_reg +static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, HostReg data_reg) { + // alignment.... + if (dword) { + if ((Bit32u)dest & 3) { + if ( ((Bit32u)dest & 3) == 2 ) { + cache_addw(0x8000 + src_reg + (data_reg << 3)); // strh src_reg, [data_reg] + cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg + cache_addw(0x0800 + templo1 + (templo1 << 3) + (16 << 6)); // lsr templo1, templo1, #16 + cache_addw(0x8000 + templo1 + (data_reg << 3) + (2 << 5)); // strh templo1, [data_reg, #2] + } else { + cache_addw(0x7000 + src_reg + (data_reg << 3)); // strb src_reg, [data_reg] + cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg + cache_addw(0x0800 + templo1 + (templo1 << 3) + (8 << 6)); // lsr templo1, templo1, #8 + cache_addw(0x7000 + templo1 + (data_reg << 3) + (1 << 6)); // strb templo1, [data_reg, #1] + cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg + cache_addw(0x0800 + templo1 + (templo1 << 3) + (16 << 6)); // lsr templo1, templo1, #16 + cache_addw(0x7000 + templo1 + (data_reg << 3) + (2 << 6)); // strb templo1, [data_reg, #2] + cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg + cache_addw(0x0800 + templo1 + (templo1 << 3) + (24 << 6)); // lsr templo1, templo1, #24 + cache_addw(0x7000 + templo1 + (data_reg << 3) + (3 << 6)); // strb templo1, [data_reg, #3] + } + } else { + cache_addw(0x6000 + src_reg + (data_reg << 3)); // str src_reg, [data_reg] + } + } else { + if ((Bit32u)dest & 1) { + cache_addw(0x7000 + src_reg + (data_reg << 3)); // strb src_reg, [data_reg] + cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg + cache_addw(0x0800 + templo1 + (templo1 << 3) + (8 << 6)); // lsr templo1, templo1, #8 + cache_addw(0x7000 + templo1 + (data_reg << 3) + (1 << 6)); // strb templo1, [data_reg, #1] + } else { + cache_addw(0x8000 + src_reg + (data_reg << 3)); // strh src_reg, [data_reg] + } + } +} + +// move 32bit (dword==true) or 16bit (dword==false) of a register into memory +static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_from_reg_helper(src_reg, dest, dword, templo2); +} + +// move an 8bit value from memory into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { + gen_mov_dword_to_reg_imm(templo1, (Bit32u)data); + cache_addw(0x7800 + dest_reg + (templo1 << 3)); // ldrb dest_reg, [templo1] +} + +// move an 8bit value from memory into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { + gen_mov_byte_to_reg_low(dest_reg, data); +} + +// move an 8bit constant value into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { + cache_addw(0x2000 + (dest_reg << 8) + imm); // mov dest_reg, #(imm) +} + +// move an 8bit constant value into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { + gen_mov_byte_to_reg_low_imm(dest_reg, imm); +} + +// move the lowest 8bit of a register into memory +static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { + gen_mov_dword_to_reg_imm(templo1, (Bit32u)dest); + cache_addw(0x7000 + src_reg + (templo1 << 3)); // strb src_reg, [templo1] +} + + + +// convert an 8bit word to a 32bit dword +// the register is zero-extended (sign==false) or sign-extended (sign==true) +static void gen_extend_byte(bool sign,HostReg reg) { + cache_addw(0x0000 + reg + (reg << 3) + (24 << 6)); // lsl reg, reg, #24 + + if (sign) { + cache_addw(0x1000 + reg + (reg << 3) + (24 << 6)); // asr reg, reg, #24 + } else { + cache_addw(0x0800 + reg + (reg << 3) + (24 << 6)); // lsr reg, reg, #24 + } +} + +// convert a 16bit word to a 32bit dword +// the register is zero-extended (sign==false) or sign-extended (sign==true) +static void gen_extend_word(bool sign,HostReg reg) { + cache_addw(0x0000 + reg + (reg << 3) + (16 << 6)); // lsl reg, reg, #16 + + if (sign) { + cache_addw(0x1000 + reg + (reg << 3) + (16 << 6)); // asr reg, reg, #16 + } else { + cache_addw(0x0800 + reg + (reg << 3) + (16 << 6)); // lsr reg, reg, #16 + } +} + +// add a 32bit value from memory to a full register +static void gen_add(HostReg reg,void* op) { + cache_addw(0x4680 + (temphi1 - HOST_r8) + (reg << 3)); // mov temphi1, reg + gen_mov_word_to_reg(reg, op, 1); + cache_addw(0x4440 + (reg) + ((temphi1 - HOST_r8) << 3)); // add reg, temphi1 +} + +// add a 32bit constant value to a full register +static void gen_add_imm(HostReg reg,Bit32u imm) { + if(!imm) return; + gen_mov_dword_to_reg_imm(templo1, imm); + cache_addw(0x1800 + reg + (reg << 3) + (templo1 << 6)); // add reg, reg, templo1 +} + +// and a 32bit constant value with a full register +static void gen_and_imm(HostReg reg,Bit32u imm) { + if(imm == 0xffffffff) return; + gen_mov_dword_to_reg_imm(templo1, imm); + cache_addw(0x4000 + reg + (templo1<< 3)); // and reg, templo1 +} + + +// move a 32bit constant value into memory +static void gen_mov_direct_dword(void* dest,Bit32u imm) { + cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + gen_mov_dword_to_reg_imm(templosav, imm); + gen_mov_word_from_reg(templosav, dest, 1); + cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 +} + +// move an address into memory +static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { + gen_mov_direct_dword(dest,(Bit32u)imm); +} + +// add an 8bit constant value to a dword memory value +static void gen_add_direct_byte(void* dest,Bit8s imm) { + if(!imm) return; + cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_to_reg_helper(templosav, dest, 1, templo2); + if (imm >= 0) { + cache_addw(0x3000 + (templosav << 8) + ((Bit32s)imm)); // add templosav, #(imm) + } else { + cache_addw(0x3800 + (templosav << 8) + (-((Bit32s)imm))); // sub templosav, #(-imm) + } + gen_mov_word_from_reg_helper(templosav, dest, 1, templo2); + cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 +} + +// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value +static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { + if(!imm) return; + if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { + gen_add_direct_byte(dest,(Bit8s)imm); + return; + } + cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_to_reg_helper(templosav, dest, dword, templo2); + if (dword) { + gen_mov_dword_to_reg_imm(templo1, imm); + } else { + gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); + } + cache_addw(0x1800 + templosav + (templosav << 3) + (templo1 << 6)); // add templosav, templosav, templo1 + gen_mov_word_from_reg_helper(templosav, dest, dword, templo2); + cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 +} + +// subtract an 8bit constant value from a dword memory value +static void gen_sub_direct_byte(void* dest,Bit8s imm) { + if(!imm) return; + cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_to_reg_helper(templosav, dest, 1, templo2); + if (imm >= 0) { + cache_addw(0x3800 + (templosav << 8) + ((Bit32s)imm)); // sub templosav, #(imm) + } else { + cache_addw(0x3000 + (templosav << 8) + (-((Bit32s)imm))); // add templosav, #(-imm) + } + gen_mov_word_from_reg_helper(templosav, dest, 1, templo2); + cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 +} + +// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value +static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { + if(!imm) return; + if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { + gen_sub_direct_byte(dest,(Bit8s)imm); + return; + } + cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_to_reg_helper(templosav, dest, dword, templo2); + if (dword) { + gen_mov_dword_to_reg_imm(templo1, imm); + } else { + gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); + } + cache_addw(0x1a00 + templosav + (templosav << 3) + (templo1 << 6)); // sub templosav, templosav, templo1 + gen_mov_word_from_reg_helper(templosav, dest, dword, templo2); + cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 +} + +// effective address calculation, destination is dest_reg +// scale_reg is scaled by scale (scale_reg*(2^scale)) and +// added to dest_reg, then the immediate value is added +static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { + if (scale) { + cache_addw(0x0000 + templo1 + (scale_reg << 3) + (scale << 6)); // lsl templo1, scale_reg, #(scale) + cache_addw(0x1800 + dest_reg + (dest_reg << 3) + (templo1 << 6)); // add dest_reg, dest_reg, templo1 + } else { + cache_addw(0x1800 + dest_reg + (dest_reg << 3) + (scale_reg << 6)); // add dest_reg, dest_reg, scale_reg + } + gen_add_imm(dest_reg, imm); +} + +// effective address calculation, destination is dest_reg +// dest_reg is scaled by scale (dest_reg*(2^scale)), +// then the immediate value is added +static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { + if (scale) { + cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (scale << 6)); // lsl dest_reg, dest_reg, #(scale) + } + gen_add_imm(dest_reg, imm); +} + +// generate a call to a parameterless function +static void INLINE gen_call_function_raw(void * func) { + if (((Bit32u)cache.pos & 0x03) == 0) { + cache_addw(0x4800 + (templo1 << 8) + (4 >> 2)); // ldr templo1, [pc, #4] + cache_addw(0xa000 + (templo2 << 8) + (8 >> 2)); // adr templo2, after_call (add templo2, pc, #8) + cache_addw(0x4680 + (HOST_lr - HOST_r8) + (templo2 << 3)); // mov lr, templo2 + cache_addw(0x4700 + (templo1 << 3)); // bx templo1 --- switch to arm state + } else { + cache_addw(0x4800 + (templo1 << 8) + (8 >> 2)); // ldr templo1, [pc, #8] + cache_addw(0xa000 + (templo2 << 8) + (8 >> 2)); // adr templo2, after_call (add templo2, pc, #8) + cache_addw(0x4680 + (HOST_lr - HOST_r8) + (templo2 << 3)); // mov lr, templo2 + cache_addw(0x4700 + (templo1 << 3)); // bx templo1 --- switch to arm state + cache_addw(0x46c0); // nop + } + cache_addd((Bit32u)func); // .int func + // after_call: + + // switch from arm to thumb state + cache_addd(0xe2800000 + (templo1 << 12) + (HOST_pc << 16) + (1)); // add templo1, pc, #1 + cache_addd(0xe12fff10 + (templo1)); // bx templo1 + + // thumb state from now on + cache_addw(0x1c00 + FC_RETOP + (HOST_a1 << 3)); // mov FC_RETOP, a1 +} + +// generate a call to a function with paramcount parameters +// note: the parameters are loaded in the architecture specific way +// using the gen_load_param_ functions below +static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { + Bit32u proc_addr = (Bit32u)cache.pos; + gen_call_function_raw(func); + return proc_addr; + // if proc_addr is on word boundary ((proc_addr & 0x03) == 0) + // then length of generated code is 22 bytes + // otherwise length of generated code is 24 bytes +} + +#if (1) +// max of 4 parameters in a1-a4 + +// load an immediate value as param'th function parameter +static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { + gen_mov_dword_to_reg_imm(param, imm); +} + +// load an address as param'th function parameter +static void INLINE gen_load_param_addr(Bitu addr,Bitu param) { + gen_mov_dword_to_reg_imm(param, addr); +} + +// load a host-register as param'th function parameter +static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { + gen_mov_regs(param, reg); +} + +// load a value from memory as param'th function parameter +static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { + gen_mov_word_to_reg(param, (void *)mem, 1); +} +#else + other arm abis +#endif + +// jump to an address pointed at by ptr, offset is in imm +static void gen_jmp_ptr(void * ptr,Bits imm=0) { + cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + gen_mov_word_to_reg(templosav, ptr, 1); + + if (imm) { + gen_mov_dword_to_reg_imm(templo2, imm); + cache_addw(0x1800 + templosav + (templosav << 3) + (templo2 << 6)); // add templosav, templosav, templo2 + } + +#if (1) +// (*ptr) should be word aligned + if ((imm & 0x03) == 0) { + cache_addw(0x6800 + templo2 + (templosav << 3)); // ldr templo2, [templosav] + } else +#endif + { + cache_addw(0x7800 + templo2 + (templosav << 3)); // ldrb templo2, [templosav] + cache_addw(0x7800 + templo1 + (templosav << 3) + (1 << 6)); // ldrb templo1, [templosav, #1] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (8 << 6)); // lsl templo1, templo1, #8 + cache_addw(0x4300 + templo2 + (templo1 << 3)); // orr templo2, templo1 + cache_addw(0x7800 + templo1 + (templosav << 3) + (2 << 6)); // ldrb templo1, [templosav, #2] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (16 << 6)); // lsl templo1, templo1, #16 + cache_addw(0x4300 + templo2 + (templo1 << 3)); // orr templo2, templo1 + cache_addw(0x7800 + templo1 + (templosav << 3) + (3 << 6)); // ldrb templo1, [templosav, #3] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (24 << 6)); // lsl templo1, templo1, #24 + cache_addw(0x4300 + templo2 + (templo1 << 3)); // orr templo2, templo1 + } + + // increase jmp address to keep thumb state + cache_addw(0x1c00 + templo2 + (templo2 << 3) + (1 << 6)); // add templo2, templo2, #1 + + cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + + cache_addw(0x4700 + (templo2 << 3)); // bx templo2 +} + +// short conditional jump (+-127 bytes) if register is zero +// the destination is set by gen_fill_branch() later +static Bit32u INLINE gen_create_branch_on_zero(HostReg reg,bool dword) { + if (dword) { + cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + } else { + cache_addw(0x0000 + templo1 + (reg << 3) + (16 << 6)); // lsl templo1, reg, #16 + } + cache_addw(0xd000); // beq j + return ((Bit32u)cache.pos-2); +} + +// short conditional jump (+-127 bytes) if register is nonzero +// the destination is set by gen_fill_branch() later +static Bit32u INLINE gen_create_branch_on_nonzero(HostReg reg,bool dword) { + if (dword) { + cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + } else { + cache_addw(0x0000 + templo1 + (reg << 3) + (16 << 6)); // lsl templo1, reg, #16 + } + cache_addw(0xd100); // bne j + return ((Bit32u)cache.pos-2); +} + +// calculate relative offset and fill it into the location pointed to by data +static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) { +#if C_DEBUG + Bits len=(Bit32u)cache.pos-(data+4); + if (len<0) len=-len; + if (len>252) LOG_MSG("Big jump %d",len); +#endif + *(Bit8u*)data=(Bit8u)( ((Bit32u)cache.pos-(data+4)) >> 1 ); +} + +// conditional jump if register is nonzero +// for isdword==true the 32bit of the register are tested +// for isdword==false the lowest 8bit of the register are tested +static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { + if (isdword) { + cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + } else { + cache_addw(0x0000 + templo2 + (reg << 3) + (24 << 6)); // lsl templo2, reg, #24 + } + if (((Bit32u)cache.pos & 0x03) == 0) { + cache_addw(0xd000 + (8 >> 1)); // beq nobranch (pc+8) + cache_addw(0x4800 + (templo1 << 8) + (4 >> 2)); // ldr templo1, [pc, #4] + cache_addw(0x4700 + (templo1 << 3)); // bx templo1 + cache_addw(0x46c0); // nop + } else { + cache_addw(0xd000 + (6 >> 1)); // beq nobranch (pc+6) + cache_addw(0x4800 + (templo1 << 8)); // ldr templo1, [pc, #0] + cache_addw(0x4700 + (templo1 << 3)); // bx templo1 + } + cache_addd(0); // fill j + // nobranch: + return ((Bit32u)cache.pos-4); +} + +// compare 32bit-register against zero and jump if value less/equal than zero +static Bit32u INLINE gen_create_branch_long_leqzero(HostReg reg) { + cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + if (((Bit32u)cache.pos & 0x03) == 0) { + cache_addw(0xdc00 + (8 >> 1)); // bgt nobranch (pc+8) + cache_addw(0x4800 + (templo1 << 8) + (4 >> 2)); // ldr templo1, [pc, #4] + cache_addw(0x4700 + (templo1 << 3)); // bx templo1 + cache_addw(0x46c0); // nop + } else { + cache_addw(0xdc00 + (6 >> 1)); // bgt nobranch (pc+6) + cache_addw(0x4800 + (templo1 << 8)); // ldr templo1, [pc, #0] + cache_addw(0x4700 + (templo1 << 3)); // bx templo1 + } + cache_addd(0); // fill j + // nobranch: + return ((Bit32u)cache.pos-4); +} + +// calculate long relative offset and fill it into the location pointed to by data +static void INLINE gen_fill_branch_long(Bit32u data) { + // this is an absolute branch + *(Bit32u*)data=((Bit32u)cache.pos) + 1; // add 1 to keep processor in thumb state +} + +static void gen_run_code(void) { + // switch from arm to thumb state + cache_addd(0xe2800000 + (HOST_r3 << 12) + (HOST_pc << 16) + (1)); // add r3, pc, #1 + cache_addd(0xe12fff10 + (HOST_r3)); // bx r3 + + // thumb state from now on + cache_addw(0xb500); // push {lr} + cache_addw(0xb4f0); // push {v1-v4} + + cache_addw(0xa302); // add r3, pc, #8 + cache_addw(0x3001); // add r0, #1 + cache_addw(0x3301); // add r3, #1 + cache_addw(0xb408); // push {r3} + cache_addw(0x4700); // bx r0 + cache_addw(0x46c0); // nop + + cache_addw(0xbcf0); // pop {v1-v4} + + cache_addw(0xbc08); // pop {r3} + cache_addw(0x4718); // bx r3 +} + +// return from a function +static void gen_return_function(void) { + cache_addw(0x1c00 + HOST_a1 + (FC_RETOP << 3)); // mov a1, FC_RETOP + cache_addw(0xbc08); // pop {r3} + cache_addw(0x4718); // bx r3 +} + +#ifdef DRC_FLAGS_INVALIDATION + +// called when a call to a function can be replaced by a +// call to a simpler function +static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { +#ifdef DRC_FLAGS_INVALIDATION_DCODE + if (((Bit32u)pos & 0x03) == 0) + { + // try to avoid function calls but rather directly fill in code + switch (flags_type) { + case t_ADDb: + case t_ADDw: + case t_ADDd: + *(Bit16u*)pos=0x1800 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // add FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=0xe000 + (16 >> 1); // b after_call (pc+16) + break; + case t_ORb: + case t_ORw: + case t_ORd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4300 + FC_RETOP + (HOST_a2 << 3); // orr FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (14 >> 1); // b after_call (pc+14) + break; + case t_ANDb: + case t_ANDw: + case t_ANDd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4000 + FC_RETOP + (HOST_a2 << 3); // and FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (14 >> 1); // b after_call (pc+14) + break; + case t_SUBb: + case t_SUBw: + case t_SUBd: + *(Bit16u*)pos=0x1a00 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // sub FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=0xe000 + (16 >> 1); // b after_call (pc+16) + break; + case t_XORb: + case t_XORw: + case t_XORd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4040 + FC_RETOP + (HOST_a2 << 3); // eor FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (14 >> 1); // b after_call (pc+14) + break; + case t_CMPb: + case t_CMPw: + case t_CMPd: + case t_TESTb: + case t_TESTw: + case t_TESTd: + *(Bit16u*)pos=0xe000 + (18 >> 1); // b after_call (pc+18) + break; + case t_INCb: + case t_INCw: + case t_INCd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // add FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=0xe000 + (16 >> 1); // b after_call (pc+16) + break; + case t_DECb: + case t_DECw: + case t_DECd: + *(Bit16u*)pos=0x1e00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // sub FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=0xe000 + (16 >> 1); // b after_call (pc+16) + break; + case t_SHLb: + case t_SHLw: + case t_SHLd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4080 + FC_RETOP + (HOST_a2 << 3); // lsl FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (14 >> 1); // b after_call (pc+14) + break; + case t_SHRb: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // lsr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (12 >> 1); // b after_call (pc+12) + break; + case t_SHRw: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // lsr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (12 >> 1); // b after_call (pc+12) + break; + case t_SHRd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (14 >> 1); // b after_call (pc+14) + break; + case t_SARb: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // asr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (12 >> 1); // b after_call (pc+12) + break; + case t_SARw: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // asr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (12 >> 1); // b after_call (pc+12) + break; + case t_SARd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (14 >> 1); // b after_call (pc+14) + break; + case t_RORb: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+4)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP + *(Bit16u*)(pos+6)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + *(Bit16u*)(pos+12)=0xe000 + (6 >> 1); // b after_call (pc+6) + break; + case t_RORw: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+4)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+6)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + *(Bit16u*)(pos+8)=0xe000 + (10 >> 1); // b after_call (pc+10) + break; + case t_RORd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (14 >> 1); // b after_call (pc+14) + break; + case t_ROLb: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 + *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 + *(Bit16u*)(pos+8)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP + *(Bit16u*)(pos+10)=0x46c0; // nop + *(Bit16u*)(pos+12)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+14)=0x46c0; // nop + *(Bit16u*)(pos+16)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+18)=0x46c0; // nop + *(Bit16u*)(pos+20)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + break; + case t_ROLw: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 + *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 + *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+12)=0xe000 + (6 >> 1); // b after_call (pc+6) + break; + case t_ROLd: + *(Bit16u*)pos=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 + *(Bit16u*)(pos+2)=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+4)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 + *(Bit16u*)(pos+6)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+8)=0xe000 + (10 >> 1); // b after_call (pc+10) + break; + case t_NEGb: + case t_NEGw: + case t_NEGd: + *(Bit16u*)pos=0x4240 + FC_RETOP + (HOST_a1 << 3); // neg FC_RETOP, a1 + *(Bit16u*)(pos+2)=0xe000 + (16 >> 1); // b after_call (pc+16) + break; + default: + *(Bit32u*)(pos+8)=(Bit32u)fct_ptr; // simple_func + break; + } + } + else + { + // try to avoid function calls but rather directly fill in code + switch (flags_type) { + case t_ADDb: + case t_ADDw: + case t_ADDd: + *(Bit16u*)pos=0x1800 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // add FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=0xe000 + (18 >> 1); // b after_call (pc+18) + break; + case t_ORb: + case t_ORw: + case t_ORd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4300 + FC_RETOP + (HOST_a2 << 3); // orr FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (16 >> 1); // b after_call (pc+16) + break; + case t_ANDb: + case t_ANDw: + case t_ANDd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4000 + FC_RETOP + (HOST_a2 << 3); // and FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (16 >> 1); // b after_call (pc+16) + break; + case t_SUBb: + case t_SUBw: + case t_SUBd: + *(Bit16u*)pos=0x1a00 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // sub FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=0xe000 + (18 >> 1); // b after_call (pc+18) + break; + case t_XORb: + case t_XORw: + case t_XORd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4040 + FC_RETOP + (HOST_a2 << 3); // eor FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (16 >> 1); // b after_call (pc+16) + break; + case t_CMPb: + case t_CMPw: + case t_CMPd: + case t_TESTb: + case t_TESTw: + case t_TESTd: + *(Bit16u*)pos=0xe000 + (20 >> 1); // b after_call (pc+20) + break; + case t_INCb: + case t_INCw: + case t_INCd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // add FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=0xe000 + (18 >> 1); // b after_call (pc+18) + break; + case t_DECb: + case t_DECw: + case t_DECd: + *(Bit16u*)pos=0x1e00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // sub FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=0xe000 + (18 >> 1); // b after_call (pc+18) + break; + case t_SHLb: + case t_SHLw: + case t_SHLd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4080 + FC_RETOP + (HOST_a2 << 3); // lsl FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (16 >> 1); // b after_call (pc+16) + break; + case t_SHRb: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // lsr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (14 >> 1); // b after_call (pc+14) + break; + case t_SHRw: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // lsr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (14 >> 1); // b after_call (pc+14) + break; + case t_SHRd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (16 >> 1); // b after_call (pc+16) + break; + case t_SARb: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // asr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (14 >> 1); // b after_call (pc+14) + break; + case t_SARw: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // asr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (14 >> 1); // b after_call (pc+14) + break; + case t_SARd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (16 >> 1); // b after_call (pc+16) + break; + case t_RORb: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+4)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP + *(Bit16u*)(pos+6)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + *(Bit16u*)(pos+12)=0xe000 + (8 >> 1); // b after_call (pc+8) + break; + case t_RORw: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+4)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+6)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + *(Bit16u*)(pos+8)=0xe000 + (12 >> 1); // b after_call (pc+12) + break; + case t_RORd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (16 >> 1); // b after_call (pc+16) + break; + case t_ROLb: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 + *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 + *(Bit16u*)(pos+8)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP + *(Bit16u*)(pos+10)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+12)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+14)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+16)=0xe000 + (4 >> 1); // b after_call (pc+4) + break; + case t_ROLw: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 + *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 + *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+12)=0xe000 + (8 >> 1); // b after_call (pc+8) + break; + case t_ROLd: + *(Bit16u*)pos=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 + *(Bit16u*)(pos+2)=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+4)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 + *(Bit16u*)(pos+6)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+8)=0xe000 + (12 >> 1); // b after_call (pc+12) + break; + case t_NEGb: + case t_NEGw: + case t_NEGd: + *(Bit16u*)pos=0x4240 + FC_RETOP + (HOST_a1 << 3); // neg FC_RETOP, a1 + *(Bit16u*)(pos+2)=0xe000 + (18 >> 1); // b after_call (pc+18) + break; + default: + *(Bit32u*)(pos+10)=(Bit32u)fct_ptr; // simple_func + break; + } + + } +#else + if (((Bit32u)pos & 0x03) == 0) + { + *(Bit32u*)(pos+8)=(Bit32u)fct_ptr; // simple_func + } + else + { + *(Bit32u*)(pos+10)=(Bit32u)fct_ptr; // simple_func + } +#endif +} +#endif diff --git a/src/cpu/core_dynrec/risc_armv4le.h b/src/cpu/core_dynrec/risc_armv4le.h new file mode 100644 index 00000000..d7e6f6a0 --- /dev/null +++ b/src/cpu/core_dynrec/risc_armv4le.h @@ -0,0 +1,29 @@ +/* + * 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: risc_armv4le.h,v 1.1 2008-08-20 14:13:21 c2woody Exp $ */ + + +/* ARMv4 (little endian) backend (switcher) by M-HT */ + +#include "risc_armv4le-common.h" + +// choose your destiny: +#include "risc_armv4le-s3.h" +//#include "risc_armv4le-o3.h" +//#include "risc_armv4le-thumb.h" diff --git a/src/cpu/core_dynrec/risc_mipsel32.h b/src/cpu/core_dynrec/risc_mipsel32.h index a6718feb..451081b6 100644 --- a/src/cpu/core_dynrec/risc_mipsel32.h +++ b/src/cpu/core_dynrec/risc_mipsel32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: risc_mipsel32.h,v 1.2 2008-08-20 14:13:21 c2woody Exp $ */ + /* MIPS32 (little endian) backend by crazyc */ @@ -630,3 +632,15 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { #endif } #endif + +static void cache_block_closing(Bit8u* block_start,Bitu block_size) { +#ifdef PSP +// writeback dcache and invalidate icache + Bit32u inval_start = ((Bit32u)block_start) & ~63; + Bit32u inval_end = (((Bit32u)block_start) + block_size + 64) & ~63; + for (;inval_start < inval_end; inval_start+=64) { + __builtin_allegrex_cache(0x1a, inval_start); + __builtin_allegrex_cache(0x08, inval_start); + } +#endif +} diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index 1464ed61..59ef05cc 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: risc_x64.h,v 1.10 2008-08-20 14:13:21 c2woody Exp $ */ + // some configuring defines that specify the capabilities of this architecture // or aspects of the recompiling @@ -671,3 +673,5 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { #endif } #endif + +static void cache_block_closing(Bit8u* block_start,Bitu block_size) { } diff --git a/src/cpu/core_dynrec/risc_x86.h b/src/cpu/core_dynrec/risc_x86.h index 88fe4361..5e7992a4 100644 --- a/src/cpu/core_dynrec/risc_x86.h +++ b/src/cpu/core_dynrec/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: risc_x86.h,v 1.7 2008-08-20 14:13:21 c2woody Exp $ */ + // some configuring defines that specify the capabilities of this architecture // or aspects of the recompiling @@ -505,3 +507,5 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { #endif } #endif + +static void cache_block_closing(Bit8u* block_start,Bitu block_size) { } From 23bc78dd1bc079a4d4c38483b3f34dd15a1f112e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 21 Aug 2008 09:10:31 +0000 Subject: [PATCH 3119/4131] fix get/set xga pixel constraints Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3207 --- src/hardware/vga_xga.cpp | 44 ++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index 9645c0f5..5ced5bb7 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_xga.cpp,v 1.15 2008-08-11 17:51:06 c2woody Exp $ */ +/* $Id: vga_xga.cpp,v 1.16 2008-08-21 09:10:31 c2woody Exp $ */ #include #include "dosbox.h" @@ -142,10 +142,24 @@ void XGA_DrawPoint(Bitu x, Bitu y, Bitu c) { one is actually 24-bit. Without this step there may be some graphics corruption (mainly, during windows dragging. */ switch(XGA_COLOR_MODE) { - case M_LIN8: vga.mem.linear[memaddr] = c; break; - case M_LIN15: ((Bit16u*)(vga.mem.linear))[memaddr] = (Bit16u)(c&0x7fff); break; - case M_LIN16: ((Bit16u*)(vga.mem.linear))[memaddr] = (Bit16u)(c&0xffff); break; - case M_LIN32: ((Bit32u*)(vga.mem.linear))[memaddr] = c; + case M_LIN8: + if (GCC_UNLIKELY(memaddr >= vga.vmemsize)) break; + vga.mem.linear[memaddr] = c; + break; + case M_LIN15: + if (GCC_UNLIKELY(memaddr*2 >= vga.vmemsize)) break; + ((Bit16u*)(vga.mem.linear))[memaddr] = (Bit16u)(c&0x7fff); + break; + case M_LIN16: + if (GCC_UNLIKELY(memaddr*2 >= vga.vmemsize)) break; + ((Bit16u*)(vga.mem.linear))[memaddr] = (Bit16u)(c&0xffff); + break; + case M_LIN32: + if (GCC_UNLIKELY(memaddr*4 >= vga.vmemsize)) break; + ((Bit32u*)(vga.mem.linear))[memaddr] = c; + break; + default: + break; } } @@ -153,15 +167,19 @@ void XGA_DrawPoint(Bitu x, Bitu y, Bitu c) { Bitu XGA_GetPoint(Bitu x, Bitu y) { Bit32u memaddr = (y * XGA_SCREEN_WIDTH) + x; - if(vga.vmemsize < memaddr) { - //LOG_MSG("getpoint mem over: x%d y%d",x,y); - return 0; - } switch(XGA_COLOR_MODE) { - case M_LIN8: return vga.mem.linear[memaddr]; + case M_LIN8: + if (GCC_UNLIKELY(memaddr >= vga.vmemsize)) break; + return vga.mem.linear[memaddr]; case M_LIN15: - case M_LIN16: return ((Bit16u*)(vga.mem.linear))[memaddr]; - case M_LIN32: return ((Bit32u*)(vga.mem.linear))[memaddr]; + case M_LIN16: + if (GCC_UNLIKELY(memaddr*2 >= vga.vmemsize)) break; + return ((Bit16u*)(vga.mem.linear))[memaddr]; + case M_LIN32: + if (GCC_UNLIKELY(memaddr*4 >= vga.vmemsize)) break; + return ((Bit32u*)(vga.mem.linear))[memaddr]; + default: + break; } return 0; } @@ -997,7 +1015,7 @@ extern void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen); extern Bitu vga_read_p3d5(Bitu port,Bitu iolen); void XGA_Write(Bitu port, Bitu val, Bitu len) { - //LOG_MSG("XGA: Write to port %x, val %8x, len %x", port,val, len); +// LOG_MSG("XGA: Write to port %x, val %8x, len %x", port,val, len); switch(port) { case 0x8100:// drawing control: row (low word), column (high word) From 6bc0cb78a105bc872dd89e79efad832d31b33d4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 23 Aug 2008 16:36:21 +0000 Subject: [PATCH 3120/4131] add INVLPG to recompiler (Cavewars) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3208 --- src/cpu/core_dynrec/decoder_opcodes.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index cbf0625e..9fbd88c8 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -977,6 +977,11 @@ static bool dyn_grp7(void) { dyn_return(BR_Normal); dyn_closeblock(); return true; + case 0x07: // INVLPG +// if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); + if (cpu.pmode && cpu.cpl) IllegalOptionDynrec("invlpg nonpriviledged"); + gen_call_function_raw((void*)PAGING_ClearTLB); + break; default: IllegalOptionDynrec("dyn_grp7_1"); } } else { From e08ea925b7f3e4ca6f2298805584bb90953aea01 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 24 Aug 2008 16:43:06 +0000 Subject: [PATCH 3121/4131] pedantic warnings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3209 --- include/cpu.h | 6 +++--- include/logging.h | 4 ++-- include/mapper.h | 2 +- include/mem.h | 24 ++++++++++++------------ include/mixer.h | 2 +- include/regs.h | 2 +- include/vga.h | 4 ++-- include/video.h | 4 ++-- 8 files changed, 24 insertions(+), 24 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 23f1aa5e..4a2d14aa 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.h,v 1.54 2008-05-21 21:29:15 c2woody Exp $ */ +/* $Id: cpu.h,v 1.55 2008-08-24 16:43:06 qbix79 Exp $ */ #ifndef DOSBOX_CPU_H #define DOSBOX_CPU_H @@ -481,12 +481,12 @@ extern CPUBlock cpu; INLINE void CPU_SetFlagsd(Bitu word) { Bitu mask=cpu.cpl ? FMASK_NORMAL : FMASK_ALL; CPU_SetFlags(word,mask); -}; +} INLINE void CPU_SetFlagsw(Bitu word) { Bitu mask=(cpu.cpl ? FMASK_NORMAL : FMASK_ALL) & 0xffff; CPU_SetFlags(word,mask); -}; +} #endif diff --git a/include/logging.h b/include/logging.h index 37a5afa3..fa349718 100644 --- a/include/logging.h +++ b/include/logging.h @@ -9,13 +9,13 @@ enum LOG_TYPES { LOG_PIT,LOG_KEYBOARD,LOG_PIC, LOG_MOUSE,LOG_BIOS,LOG_GUI,LOG_MISC, LOG_IO, - LOG_MAX, + LOG_MAX }; enum LOG_SEVERITIES { LOG_NORMAL, LOG_WARN, - LOG_ERROR, + LOG_ERROR }; #if C_DEBUG diff --git a/include/mapper.h b/include/mapper.h index c9b51f1f..aea28945 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -21,7 +21,7 @@ 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, + MK_return,MK_kpminus,MK_scrolllock,MK_printscreen,MK_pause }; diff --git a/include/mem.h b/include/mem.h index 436dc384..f9128dad 100644 --- a/include/mem.h +++ b/include/mem.h @@ -61,47 +61,47 @@ MemHandle MEM_NextHandleAt(MemHandle handle,Bitu where); INLINE Bit8u host_readb(HostPt off) { return off[0]; -}; +} INLINE Bit16u host_readw(HostPt off) { return off[0] | (off[1] << 8); -}; +} INLINE Bit32u host_readd(HostPt off) { return off[0] | (off[1] << 8) | (off[2] << 16) | (off[3] << 24); -}; +} INLINE void host_writeb(HostPt off,Bit8u val) { off[0]=val; -}; +} INLINE void host_writew(HostPt off,Bit16u val) { off[0]=(Bit8u)(val); off[1]=(Bit8u)(val >> 8); -}; +} 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 INLINE Bit8u host_readb(HostPt off) { return *(Bit8u *)off; -}; +} INLINE Bit16u host_readw(HostPt off) { return *(Bit16u *)off; -}; +} INLINE Bit32u host_readd(HostPt off) { return *(Bit32u *)off; -}; +} INLINE void host_writeb(HostPt off,Bit8u val) { *(Bit8u *)(off)=val; -}; +} INLINE void host_writew(HostPt off,Bit16u val) { *(Bit16u *)(off)=val; -}; +} INLINE void host_writed(HostPt off,Bit32u val) { *(Bit32u *)(off)=val; -}; +} #endif diff --git a/include/mixer.h b/include/mixer.h index 70162024..af0ebbc0 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -33,7 +33,7 @@ enum BlahModes { enum MixerModes { M_8M,M_8S, - M_16M,M_16S, + M_16M,M_16S }; #define MIXER_BUFSIZE (16*1024) diff --git a/include/regs.h b/include/regs.h index 0f5a0c41..8f8445f4 100644 --- a/include/regs.h +++ b/include/regs.h @@ -118,7 +118,7 @@ enum { enum { REGI_AL, REGI_CL, REGI_DL, REGI_BL, - REGI_AH, REGI_CH, REGI_DH, REGI_BH, + REGI_AH, REGI_CH, REGI_DH, REGI_BH }; diff --git a/include/vga.h b/include/vga.h index 7815586b..c995dfe0 100644 --- a/include/vga.h +++ b/include/vga.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga.h,v 1.43 2008-08-08 21:56:36 c2woody Exp $ */ +/* $Id: vga.h,v 1.44 2008-08-24 16:43:06 qbix79 Exp $ */ #ifndef DOSBOX_VGA_H #define DOSBOX_VGA_H @@ -41,7 +41,7 @@ enum VGAModes { M_TEXT, M_HERC_GFX, M_HERC_TEXT, M_CGA16, M_TANDY2, M_TANDY4, M_TANDY16, M_TANDY_TEXT, - M_ERROR, + M_ERROR }; diff --git a/include/video.h b/include/video.h index 980f5410..de4bbace 100644 --- a/include/video.h +++ b/include/video.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: video.h,v 1.24 2008-02-21 19:25:04 c2woody Exp $ */ +/* $Id: video.h,v 1.25 2008-08-24 16:43:06 qbix79 Exp $ */ #ifndef DOSBOX_VIDEO_H #define DOSBOX_VIDEO_H @@ -26,7 +26,7 @@ typedef enum { GFX_CallBackReset, GFX_CallBackStop, - GFX_CallBackRedraw, + GFX_CallBackRedraw } GFX_CallBackFunctions_t; typedef void (*GFX_CallBack_t)( GFX_CallBackFunctions_t function ); From 3fc520528db1446cded7a7ca8ab93c76b5654906 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 24 Aug 2008 16:48:23 +0000 Subject: [PATCH 3122/4131] More pedantic. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3210 --- src/shell/shell_batch.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 8cb566a2..5ef909b7 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.30 2008-08-11 07:47:04 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.31 2008-08-24 16:48:23 qbix79 Exp $ */ #include #include @@ -33,7 +33,7 @@ BatchFile::BatchFile(DOS_Shell * host,char const * const name, char const * cons //TODO Come up with something better E_Exit("SHELL:Can't open BatchFile"); } -}; +} BatchFile::~BatchFile() { delete cmd; @@ -161,7 +161,8 @@ again: } goto again; return false; -}; +} + void BatchFile::Shift(void) { cmd->Shift(1); } From cbdb5b97fe2071e1818650368d2d145b7e15c5b8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 27 Aug 2008 16:21:30 +0000 Subject: [PATCH 3123/4131] Change logging message to always display things in twofault. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3211 --- src/cpu/core_normal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index d5495b9e..dfab4979 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -169,7 +169,7 @@ restart_opcode: if (len>16) len=16; char tempcode[16*2+1];char * writecode=tempcode; for (;len>0;len--) { - sprintf(writecode,"%X",mem_readb(core.cseip++)); + sprintf(writecode,"%02X",mem_readb(core.cseip++)); writecode+=2; } LOG(LOG_CPU,LOG_NORMAL)("Illegal/Unhandled opcode %s",tempcode); From ba077a4d76d9c5b514c5b5d8efff0a0ebbcb2b43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 28 Aug 2008 17:37:23 +0000 Subject: [PATCH 3124/4131] add/fix some undocumented sb16 dsp commands (asp/csp programming) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3212 --- src/hardware/sblaster.cpp | 139 ++++++++++++++++++++++++++++++++++---- 1 file changed, 125 insertions(+), 14 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 077d6e48..a7aac8cc 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.68 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: sblaster.cpp,v 1.69 2008-08-28 17:37:23 c2woody Exp $ */ #include #include @@ -160,9 +160,32 @@ static SB_INFO sb; static char const * const copyright_string="COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; -static Bit8u DSP_cmd_len[256] = { -// 0,0,0,0, 1,2,0,0, 0,0,0,0, 0,0,2,1, // 0x00 for SB16. but breaks sbpro - 0,0,0,0, 0,2,0,0, 0,0,0,0, 0,0,2,1, // 0x00 +// number of bytes in input for commands (sb/sbpro) +static Bit8u DSP_cmd_len_sb[256] = { + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00 + 1,0,0,0, 2,0,2,2, 0,0,0,0, 0,0,0,0, // 0x10 + 0,0,0,0, 2,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 + 0,0,0,0, 0,0,0,0, 1,0,0,0, 0,0,0,0, // 0x30 + + 1,2,2,0, 0,0,0,0, 2,0,0,0, 0,0,0,0, // 0x40 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x50 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x60 + 0,0,0,0, 2,2,2,2, 0,0,0,0, 0,0,0,0, // 0x70 + + 2,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x80 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x90 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0xa0 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0xb0 + + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0xc0 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0xd0 + 1,0,1,0, 1,0,0,0, 0,0,0,0, 0,0,0,0, // 0xe0 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 // 0xf0 +}; + +// number of bytes in input for commands (sb16) +static Bit8u DSP_cmd_len_sb16[256] = { + 0,0,0,0, 1,2,0,0, 1,0,0,0, 0,0,2,1, // 0x00 1,0,0,0, 2,0,2,2, 0,0,0,0, 0,0,0,0, // 0x10 0,0,0,0, 2,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 0,0,0,0, 0,0,0,0, 1,0,0,0, 0,0,0,0, // 0x30 @@ -180,9 +203,12 @@ static Bit8u DSP_cmd_len[256] = { 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xc0 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0xd0 1,0,1,0, 1,0,0,0, 0,0,0,0, 0,0,0,0, // 0xe0 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 // 0xf0 + 0,0,0,0, 0,0,0,0, 0,1,0,0, 0,0,0,0 // 0xf0 }; +static Bit8u ASP_regs[256]; +static bool ASP_init_in_progress = false; + static int E2_incr_table[4][9] = { { 0x01, -0x02, -0x04, 0x08, -0x10, 0x20, 0x40, -0x80, -106 }, { -0x01, 0x02, -0x04, 0x08, 0x10, -0x20, 0x40, -0x80, 165 }, @@ -708,9 +734,56 @@ Bitu DEBUG_EnableDebugger(void); static void DSP_DoCommand(void) { // LOG_MSG("DSP Command %X",sb.dsp.cmd); switch (sb.dsp.cmd) { - case 0x04: /* DSP Status SB 2.0/pro version. NOT SB16. */ - DSP_FlushData(); - DSP_AddData(0xff); //Everthing enabled + case 0x04: + if (sb.type == SBT_16) { + /* SB16 ASP set mode register */ + if ((sb.dsp.in.data[0]&0xf1)==0xf1) ASP_init_in_progress=true; + else ASP_init_in_progress=false; + LOG(LOG_SB,LOG_NORMAL)("DSP Unhandled SB16ASP command %X (set mode register to %X)",sb.dsp.cmd,sb.dsp.in.data[0]); + } else { + /* DSP Status SB 2.0/pro version. NOT SB16. */ + DSP_FlushData(); + if (sb.type == SBT_2) DSP_AddData(0x88); + else if ((sb.type == SBT_PRO1) || (sb.type == SBT_PRO2)) DSP_AddData(0x7b); + else DSP_AddData(0xff); //Everything enabled + } + break; + case 0x05: /* SB16 ASP set codec parameter */ + LOG(LOG_SB,LOG_NORMAL)("DSP Unhandled SB16ASP command %X (set codec parameter)",sb.dsp.cmd); + break; + case 0x08: /* SB16 ASP get version */ + LOG(LOG_SB,LOG_NORMAL)("DSP Unhandled SB16ASP command %X sub %X",sb.dsp.cmd,sb.dsp.in.data[0]); + if (sb.type == SBT_16) { + switch (sb.dsp.in.data[0]) { + case 0x03: + DSP_AddData(0x18); // version ID (??) + break; + default: + LOG(LOG_SB,LOG_NORMAL)("DSP Unhandled SB16ASP command %X sub %X",sb.dsp.cmd,sb.dsp.in.data[0]); + break; + } + } else { + LOG(LOG_SB,LOG_NORMAL)("DSP Unhandled SB16ASP command %X sub %X",sb.dsp.cmd,sb.dsp.in.data[0]); + } + break; + case 0x0e: /* SB16 ASP set register */ + if (sb.type == SBT_16) { +// LOG(LOG_SB,LOG_NORMAL)("SB16 ASP set register %X := %X",sb.dsp.in.data[0],sb.dsp.in.data[1]); + ASP_regs[sb.dsp.in.data[0]] = sb.dsp.in.data[1]; + } else { + LOG(LOG_SB,LOG_NORMAL)("DSP Unhandled SB16ASP command %X (set register)",sb.dsp.cmd); + } + break; + case 0x0f: /* SB16 ASP get register */ + if (sb.type == SBT_16) { + if ((ASP_init_in_progress) && (sb.dsp.in.data[0]==0x83)) { + ASP_regs[0x83] = ~ASP_regs[0x83]; + } +// LOG(LOG_SB,LOG_NORMAL)("SB16 ASP get register %X == %X",sb.dsp.in.data[0],ASP_regs[sb.dsp.in.data[0]]); + DSP_AddData(ASP_regs[sb.dsp.in.data[0]]); + } else { + LOG(LOG_SB,LOG_NORMAL)("DSP Unhandled SB16ASP command %X (get register)",sb.dsp.cmd); + } break; case 0x10: /* Direct DAC */ DSP_ChangeMode(MODE_DAC); @@ -893,11 +966,45 @@ static void DSP_DoCommand(void) { case 0xa0: case 0xa8: /* Documented only for DSP 3.x */ LOG(LOG_SB,LOG_ERROR)("DSP:Unimplemented input command %2X",sb.dsp.cmd); break; - case 0x0f: /* SB16 ASP get register */ - DSP_AddData(0xff); //Fall through - case 0x0e: /* SB16 ASP Command ? */ - case 0x05: /* SB16 ASP set register */ - LOG(LOG_SB,LOG_NORMAL)("DSP Unhandled SB16ASP command %X",sb.dsp.cmd); + case 0xf9: /* SB16 ASP ??? */ + if (sb.type == SBT_16) { + LOG(LOG_SB,LOG_NORMAL)("SB16 ASP unknown function %x",sb.dsp.in.data[0]); + // just feed it what it expects + switch (sb.dsp.in.data[0]) { + case 0x0b: + DSP_AddData(0x00); + break; + case 0x0e: + DSP_AddData(0xff); + break; + case 0x0f: + DSP_AddData(0x07); + break; + case 0x23: + DSP_AddData(0x00); + break; + case 0x24: + DSP_AddData(0x00); + break; + case 0x2b: + DSP_AddData(0x00); + break; + case 0x2c: + DSP_AddData(0x00); + break; + case 0x2d: + DSP_AddData(0x00); + break; + case 0x37: + DSP_AddData(0x38); + break; + default: + DSP_AddData(0x00); + break; + } + } else { + LOG(LOG_SB,LOG_NORMAL)("SB16 ASP unknown function %X",sb.dsp.cmd); + } break; default: LOG(LOG_SB,LOG_ERROR)("DSP:Unhandled (undocumented) command %2X",sb.dsp.cmd); @@ -912,7 +1019,8 @@ static void DSP_DoWrite(Bit8u val) { switch (sb.dsp.cmd) { case DSP_NO_COMMAND: sb.dsp.cmd=val; - sb.dsp.cmd_len=DSP_cmd_len[val]; + if (sb.type == SBT_16) sb.dsp.cmd_len=DSP_cmd_len_sb16[val]; + else sb.dsp.cmd_len=DSP_cmd_len_sb[val]; sb.dsp.in.pos=0; if (!sb.dsp.cmd_len) DSP_DoCommand(); break; @@ -1382,6 +1490,9 @@ public: ReadHandler[i].Install(sb.hw.base+i,read_sb,IO_MB); WriteHandler[i].Install(sb.hw.base+i,write_sb,IO_MB); } + for (i=0;i<256;i++) ASP_regs[i] = 0; + ASP_regs[5] = 0x01; + ASP_regs[9] = 0xf8; DSP_Reset(); CTMIXER_Reset(); // The documentation does not specify if SB gets initialized with the speaker enabled From e0efbfbd4ce041d554d396ca2642ba1a248c2930 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 29 Aug 2008 19:27:04 +0000 Subject: [PATCH 3125/4131] fix offset of sda to be correctly placed relative to the sysvars table (codeview checks) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3213 --- include/dos_inc.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index d113d392..9ea928f2 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.74 2008-05-28 09:53:31 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.75 2008-08-29 19:27:04 c2woody Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -77,13 +77,15 @@ enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; #define DOS_DEVICES 10 -#define DOS_INFOBLOCK_SEG 0x80 -#define DOS_CDS_SEG 0xa8 -#define DOS_CONSTRING_SEG 0xb8 -#define DOS_CONDRV_SEG 0xbc -#define DOS_SDA_SEG 0xca +// 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_MEM_START 0x11a //First Segment that DOS can use +#define DOS_CDS_SEG 0x108 +#define DOS_MEM_START 0x118 //First Segment that DOS can use #define DOS_PRIVATE_SEGMENT 0xc800 #define DOS_PRIVATE_SEGMENT_END 0xd000 From acce294193eba7e28fd8f46c1eb83b5c450440db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 31 Aug 2008 10:14:31 +0000 Subject: [PATCH 3126/4131] ability to automatically select host-matching keyboard layout Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3214 --- src/dos/dos_keyboard_layout.cpp | 156 ++++++++++++++++++++++++++++++-- 1 file changed, 150 insertions(+), 6 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 8a03862f..74a92bf4 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_keyboard_layout.cpp,v 1.13 2008-08-06 18:32:34 c2woody Exp $ */ +/* $Id: dos_keyboard_layout.cpp,v 1.14 2008-08-31 10:14:31 c2woody Exp $ */ #include "dosbox.h" #include "bios.h" @@ -32,6 +32,10 @@ #include "dos_codepages.h" #include "dos_keyboard_layout_data.h" +#if defined (WIN32) +#include +#endif + static FILE* OpenDosboxFile(const char* name) { Bit8u drive; @@ -1046,12 +1050,152 @@ public: loaded_layout=new keyboard_layout(); const char * layoutname=section->Get_string("keyboardlayout"); - // try to find a good codepage for the requested layout - Bitu req_codepage=loaded_layout->extract_codepage(layoutname); - loaded_layout->read_codepage_file("auto", req_codepage); - if (loaded_layout->read_keyboard_file(layoutname, dos.loaded_codepage)) - LOG_MSG("Error loading keyboard layout %s",layoutname); + Bits wants_dos_codepage = -1; + if (!strncmp(layoutname,"auto",4)) { +#if defined (WIN32) + DWORD cur_kb_layout = MAKELCID(LOWORD(GetKeyboardLayout(0)),SORT_DEFAULT); + // try to match emulated keyboard layout with host-keyboardlayout + // codepage 437 (standard) is preferred + switch (cur_kb_layout) { + case 1026: + layoutname = "bg241"; + break; + case 1029: + layoutname = "cz243"; + break; + case 1030: + layoutname = "dk"; + break; + case 1031: + layoutname = "gr"; + wants_dos_codepage = 437; + break; + case 1032: + layoutname = "gk"; + break; + case 1034: + layoutname = "sp"; + wants_dos_codepage = 437; + break; + case 1035: + layoutname = "su"; + wants_dos_codepage = 437; + break; + case 1036: + layoutname = "fr"; + wants_dos_codepage = 437; + break; + case 1038: + layoutname = "hu"; + break; + case 1039: + layoutname = "is161"; + break; + case 1040: + layoutname = "it"; + wants_dos_codepage = 437; + break; + case 1043: + layoutname = "nl"; + wants_dos_codepage = 437; + break; + case 1044: + layoutname = "no"; + break; + case 1045: + layoutname = "pl214"; + break; + case 1046: + layoutname = "br"; + wants_dos_codepage = 437; + break; + case 1048: + layoutname = "ro446"; + break; + case 1049: + layoutname = "ru"; + wants_dos_codepage = 437; + break; + case 1050: + layoutname = "hr"; + break; + case 1051: + layoutname = "sk"; + break; + case 1052: + layoutname = "sq448"; + break; + case 1053: + layoutname = "sv"; + wants_dos_codepage = 437; + break; + case 1055: + layoutname = "tr"; + break; + case 1058: + layoutname = "ur"; + wants_dos_codepage = 437; + break; + case 1059: + layoutname = "bl"; + break; + case 1060: + layoutname = "si"; + break; + case 1061: + layoutname = "et"; + break; +/* case 1062: + layoutname = "lv"; + break; */ + case 1063: + layoutname = "lt221"; + break; +/* case 1064: + layoutname = "tj"; + break; + case 1066: + layoutname = "vi"; + break; + case 1067: + layoutname = "hy"; + break; */ + case 2055: + layoutname = "sg"; + wants_dos_codepage = 437; + break; + case 2070: + layoutname = "po"; + break; + case 4108: + layoutname = "sf"; + wants_dos_codepage = 437; + break; + default: + break; + } +#endif + } + + bool extract_codepage = true; + if (wants_dos_codepage>0) { + if ((loaded_layout->read_codepage_file("auto", (Bitu)wants_dos_codepage)) == KEYB_NOERROR) { + // preselected codepage was successfully loaded + extract_codepage = false; + } + } + if (extract_codepage) { + // try to find a good codepage for the requested layout + Bitu req_codepage = loaded_layout->extract_codepage(layoutname); + loaded_layout->read_codepage_file("auto", req_codepage); + } + + if (loaded_layout->read_keyboard_file(layoutname, dos.loaded_codepage)) { + if (strncmp(layoutname,"auto",4)) { + LOG_MSG("Error loading keyboard layout %s",layoutname); + } + } } ~DOS_KeyboardLayout(){ From dce428ac54ea9e0f04efe7bdeb0dee6e38c95dc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 2 Sep 2008 20:44:41 +0000 Subject: [PATCH 3127/4131] armv4le backend update (M-HT), adds distance data pool for thumb emitter Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3215 --- src/cpu/core_dynrec/decoder_basic.h | 3 +- src/cpu/core_dynrec/risc_armv4le-o3.h | 10 +- src/cpu/core_dynrec/risc_armv4le-s3.h | 10 +- src/cpu/core_dynrec/risc_armv4le-thumb-iw.h | 1135 ++++++++++++++++++ src/cpu/core_dynrec/risc_armv4le-thumb-niw.h | 1132 +++++++++++++++++ src/cpu/core_dynrec/risc_armv4le-thumb.h | 4 +- src/cpu/core_dynrec/risc_armv4le.h | 8 +- src/cpu/core_dynrec/risc_mipsel32.h | 4 +- src/cpu/core_dynrec/risc_x64.h | 4 +- src/cpu/core_dynrec/risc_x86.h | 4 +- 10 files changed, 2298 insertions(+), 16 deletions(-) create mode 100644 src/cpu/core_dynrec/risc_armv4le-thumb-iw.h create mode 100644 src/cpu/core_dynrec/risc_armv4le-thumb-niw.h diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index 4b4f7321..d568da4d 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: decoder_basic.h,v 1.11 2008-08-20 14:13:21 c2woody Exp $ */ +/* $Id: decoder_basic.h,v 1.12 2008-09-02 20:44:41 c2woody Exp $ */ /* @@ -555,6 +555,7 @@ static void dyn_fill_blocks(void) { static void dyn_closeblock(void) { //Shouldn't create empty block normally but let's do it like this dyn_fill_blocks(); + cache_block_before_close(); cache_closeblock(); cache_block_closing(decode.block->cache.start,decode.block->cache.size); } diff --git a/src/cpu/core_dynrec/risc_armv4le-o3.h b/src/cpu/core_dynrec/risc_armv4le-o3.h index d639d297..b4c1c181 100644 --- a/src/cpu/core_dynrec/risc_armv4le-o3.h +++ b/src/cpu/core_dynrec/risc_armv4le-o3.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-o3.h,v 1.1 2008-08-20 14:13:21 c2woody Exp $ */ +/* $Id: risc_armv4le-o3.h,v 1.2 2008-09-02 20:44:41 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (size-tweaked arm version) */ @@ -616,7 +616,7 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { // short conditional jump (+-127 bytes) if register is zero // the destination is set by gen_fill_branch() later -static Bit32u INLINE gen_create_branch_on_zero(HostReg reg,bool dword) { +static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { if (dword) { cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 } else { @@ -628,7 +628,7 @@ static Bit32u INLINE gen_create_branch_on_zero(HostReg reg,bool dword) { // short conditional jump (+-127 bytes) if register is nonzero // the destination is set by gen_fill_branch() later -static Bit32u INLINE gen_create_branch_on_nonzero(HostReg reg,bool dword) { +static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { if (dword) { cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 } else { @@ -666,7 +666,7 @@ static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { } // compare 32bit-register against zero and jump if value less/equal than zero -static Bit32u INLINE gen_create_branch_long_leqzero(HostReg reg) { +static Bit32u gen_create_branch_long_leqzero(HostReg reg) { cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 cache_addd(0xca000002); // bgt nobranch cache_addd(0xe5900000 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #0] @@ -856,3 +856,5 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { #endif } #endif + +static void cache_block_before_close(void) { } diff --git a/src/cpu/core_dynrec/risc_armv4le-s3.h b/src/cpu/core_dynrec/risc_armv4le-s3.h index 6388538d..8a07b71b 100644 --- a/src/cpu/core_dynrec/risc_armv4le-s3.h +++ b/src/cpu/core_dynrec/risc_armv4le-s3.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-s3.h,v 1.1 2008-08-20 14:13:21 c2woody Exp $ */ +/* $Id: risc_armv4le-s3.h,v 1.2 2008-09-02 20:44:41 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (speed-tweaked arm version) */ @@ -452,7 +452,7 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { // short conditional jump (+-127 bytes) if register is zero // the destination is set by gen_fill_branch() later -static Bit32u INLINE gen_create_branch_on_zero(HostReg reg,bool dword) { +static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { if (dword) { cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 } else { @@ -464,7 +464,7 @@ static Bit32u INLINE gen_create_branch_on_zero(HostReg reg,bool dword) { // short conditional jump (+-127 bytes) if register is nonzero // the destination is set by gen_fill_branch() later -static Bit32u INLINE gen_create_branch_on_nonzero(HostReg reg,bool dword) { +static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { if (dword) { cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 } else { @@ -502,7 +502,7 @@ static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { } // compare 32bit-register against zero and jump if value less/equal than zero -static Bit32u INLINE gen_create_branch_long_leqzero(HostReg reg) { +static Bit32u gen_create_branch_long_leqzero(HostReg reg) { cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 cache_addd(0xca000002); // bgt nobranch cache_addd(0xe5900000 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #0] @@ -692,3 +692,5 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { #endif } #endif + +static void cache_block_before_close(void) { } diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h new file mode 100644 index 00000000..a00db4ce --- /dev/null +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h @@ -0,0 +1,1135 @@ +/* + * 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: risc_armv4le-thumb-iw.h,v 1.1 2008-09-02 20:44:41 c2woody Exp $ */ + + +/* ARMv4 (little endian) backend by M-HT (thumb version, requires -mthumb-interwork switch when compiling dosbox) */ + + +// temporary "lo" registers +#define templo1 HOST_v3 +#define templo2 HOST_v4 + +// temporary "lo" register - value must be preserved when using it +#define templosav HOST_a3 + +// temporary "hi" register +#define temphi1 HOST_ip + +// register that holds function return values +#define FC_RETOP HOST_v2 + +// register used for address calculations, +#define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG + +// register that holds the first parameter +#define FC_OP1 HOST_a1 + +// register that holds the second parameter +#define FC_OP2 HOST_a2 + +// register that holds byte-accessible temporary values +#define FC_TMP_BA1 HOST_a1 + +// register that holds byte-accessible temporary values +#define FC_TMP_BA2 HOST_a2 + +// temporary register for LEA +#define TEMP_REG_DRC HOST_a4 + + +// data pool defines +#define CACHE_DATA_JUMP (2) +#define CACHE_DATA_ALIGN (32) +#define CACHE_DATA_MIN (32) +#define CACHE_DATA_MAX (288) + +// data pool variables +static Bit8u * cache_datapos = NULL; // position of data pool in the cache block +static Bit32u cache_datasize = 0; // total size of data pool +static Bit32u cache_dataindex = 0; // used size of data pool = index of free data item (in bytes) in data pool + + +static void INLINE gen_create_branch_short(void * func); + +// function to check distance to data pool +// if too close, then generate jump after data pool +static void cache_checkinstr(Bit32u size) { + if (cache_datasize == 0) { + if (cache_datapos != NULL) { + if (cache.pos + size + CACHE_DATA_JUMP >= cache_datapos) { + cache_datapos = NULL; + } + } + return; + } + + if (cache.pos + size + CACHE_DATA_JUMP <= cache_datapos) return; + + { + register Bit8u * newcachepos; + + newcachepos = cache_datapos + cache_datasize; + gen_create_branch_short(newcachepos); + cache.pos = newcachepos; + } + + if (cache.pos + CACHE_DATA_MAX + CACHE_DATA_ALIGN >= cache.block.active->cache.start + cache.block.active->cache.size && + cache.pos + CACHE_DATA_MIN + CACHE_DATA_ALIGN + (CACHE_DATA_ALIGN - CACHE_ALIGN) < cache.block.active->cache.start + cache.block.active->cache.size) + { + cache_datapos = (Bit8u *) (((Bitu)cache.block.active->cache.start + cache.block.active->cache.size - CACHE_DATA_ALIGN) & ~(CACHE_DATA_ALIGN - 1)); + } else { + register Bit32u cachemodsize; + + cachemodsize = (cache.pos - cache.block.active->cache.start) & (CACHE_MAXSIZE - 1); + + if (cachemodsize + CACHE_DATA_MAX + CACHE_DATA_ALIGN <= CACHE_MAXSIZE || + cachemodsize + CACHE_DATA_MIN + CACHE_DATA_ALIGN + (CACHE_DATA_ALIGN - CACHE_ALIGN) > CACHE_MAXSIZE) + { + cache_datapos = (Bit8u *) (((Bitu)cache.pos + CACHE_DATA_MAX) & ~(CACHE_DATA_ALIGN - 1)); + } else { + cache_datapos = (Bit8u *) (((Bitu)cache.pos + (CACHE_MAXSIZE - CACHE_DATA_ALIGN) - cachemodsize) & ~(CACHE_DATA_ALIGN - 1)); + } + } + + cache_datasize = 0; + cache_dataindex = 0; +} + +// function to reserve item in data pool +// returns address of item +static Bit8u * cache_reservedata(void) { + // if data pool not yet initialized, then initialize data pool + if (GCC_UNLIKELY(cache_datapos == NULL)) { + if (cache.pos + CACHE_DATA_MIN + CACHE_DATA_ALIGN < cache.block.active->cache.start + CACHE_DATA_MAX) { + cache_datapos = (Bit8u *) (((Bitu)cache.block.active->cache.start + CACHE_DATA_MAX) & ~(CACHE_DATA_ALIGN - 1)); + } + } + + // if data pool not yet used, then set data pool + if (cache_datasize == 0) { + // set data pool address is too close (or behind) cache.pos then set new data pool size + if (cache.pos + CACHE_DATA_MIN + CACHE_DATA_JUMP /*+ CACHE_DATA_ALIGN*/ > cache_datapos) { + if (cache.pos + CACHE_DATA_MAX + CACHE_DATA_ALIGN >= cache.block.active->cache.start + cache.block.active->cache.size && + cache.pos + CACHE_DATA_MIN + CACHE_DATA_ALIGN + (CACHE_DATA_ALIGN - CACHE_ALIGN) < cache.block.active->cache.start + cache.block.active->cache.size) + { + cache_datapos = (Bit8u *) (((Bitu)cache.block.active->cache.start + cache.block.active->cache.size - CACHE_DATA_ALIGN) & ~(CACHE_DATA_ALIGN - 1)); + } else { + register Bit32u cachemodsize; + + cachemodsize = (cache.pos - cache.block.active->cache.start) & (CACHE_MAXSIZE - 1); + + if (cachemodsize + CACHE_DATA_MAX + CACHE_DATA_ALIGN <= CACHE_MAXSIZE || + cachemodsize + CACHE_DATA_MIN + CACHE_DATA_ALIGN + (CACHE_DATA_ALIGN - CACHE_ALIGN) > CACHE_MAXSIZE) + { + cache_datapos = (Bit8u *) (((Bitu)cache.pos + CACHE_DATA_MAX) & ~(CACHE_DATA_ALIGN - 1)); + } else { + cache_datapos = (Bit8u *) (((Bitu)cache.pos + (CACHE_MAXSIZE - CACHE_DATA_ALIGN) - cachemodsize) & ~(CACHE_DATA_ALIGN - 1)); + } + } + } + // set initial data pool size + cache_datasize = CACHE_DATA_ALIGN; + } + + // if data pool is full, then enlarge data pool + if (cache_dataindex == cache_datasize) { + cache_datasize += CACHE_DATA_ALIGN; + } + + cache_dataindex += 4; + return (cache_datapos + (cache_dataindex - 4)); +} + +static void cache_block_before_close(void) { + // if data pool in use, then resize cache block to include the data pool + if (cache_datasize != 0) + { + cache.pos = cache_datapos + cache_dataindex; + } + + // clear the values before next use + cache_datapos = NULL; + cache_datasize = 0; + cache_dataindex = 0; +} + + +// move a full register from reg_src to reg_dst +static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { + if(reg_src == reg_dst) return; + cache_checkinstr(2); + cache_addw(0x1c00 + reg_dst + (reg_src << 3)); // mov reg_dst, reg_src +} + +// move a 32bit constant value into dest_reg +static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { + if ((imm & 0xffffff00) == 0) { + cache_checkinstr(2); + cache_addw(0x2000 + (dest_reg << 8) + imm); // mov dest_reg, #(imm) + } else if ((imm & 0xffff00ff) == 0) { + cache_checkinstr(4); + cache_addw(0x2000 + (dest_reg << 8) + (imm >> 8)); // mov dest_reg, #(imm >> 8) + cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (8 << 6)); // lsl dest_reg, dest_reg, #8 + } else if ((imm & 0xff00ffff) == 0) { + cache_checkinstr(4); + cache_addw(0x2000 + (dest_reg << 8) + (imm >> 16)); // mov dest_reg, #(imm >> 16) + cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (16 << 6)); // lsl dest_reg, dest_reg, #16 + } else if ((imm & 0x00ffffff) == 0) { + cache_checkinstr(4); + cache_addw(0x2000 + (dest_reg << 8) + (imm >> 24)); // mov dest_reg, #(imm >> 24) + cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (24 << 6)); // lsl dest_reg, dest_reg, #24 + } else { + Bit32u diff; + + cache_checkinstr(4); + + diff = imm - ((Bit32u)cache.pos+4); + + if ((diff < 1024) && ((imm & 0x03) == 0)) { + if (((Bit32u)cache.pos & 0x03) == 0) { + cache_addw(0xa000 + (dest_reg << 8) + (diff >> 2)); // add dest_reg, pc, #(diff >> 2) + } else { + cache_addw(0x46c0); // nop + cache_addw(0xa000 + (dest_reg << 8) + ((diff - 2) >> 2)); // add dest_reg, pc, #((diff - 2) >> 2) + } + } else { + Bit8u *datapos; + + datapos = cache_reservedata(); + *(Bit32u*)datapos=imm; + + if (((Bit32u)cache.pos & 0x03) == 0) { + cache_addw(0x4800 + (dest_reg << 8) + ((datapos - (cache.pos + 4)) >> 2)); // ldr dest_reg, [pc, datapos] + } else { + cache_addw(0x4800 + (dest_reg << 8) + ((datapos - (cache.pos + 2)) >> 2)); // ldr dest_reg, [pc, datapos] + } + } + } +} + +// helper function for gen_mov_word_to_reg +static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,HostReg data_reg) { + // alignment.... + if (dword) { + if ((Bit32u)data & 3) { + if ( ((Bit32u)data & 3) == 2 ) { + cache_checkinstr(8); + cache_addw(0x8800 + dest_reg + (data_reg << 3)); // ldrh dest_reg, [data_reg] + cache_addw(0x8800 + templo1 + (data_reg << 3) + (2 << 5)); // ldrh templo1, [data_reg, #2] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (16 << 6)); // lsl templo1, templo1, #16 + cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + } else { + cache_checkinstr(16); + cache_addw(0x7800 + dest_reg + (data_reg << 3)); // ldrb dest_reg, [data_reg] + cache_addw(0x1c00 + templo1 + (data_reg << 3) + (1 << 6)); // add templo1, data_reg, #1 + cache_addw(0x8800 + templo1 + (templo1 << 3)); // ldrh templo1, [templo1] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (8 << 6)); // lsl templo1, templo1, #8 + cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + cache_addw(0x7800 + templo1 + (data_reg << 3) + (3 << 6)); // ldrb templo1, [data_reg, #3] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (24 << 6)); // lsl templo1, templo1, #24 + cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + } + } else { + cache_checkinstr(2); + cache_addw(0x6800 + dest_reg + (data_reg << 3)); // ldr dest_reg, [data_reg] + } + } else { + if ((Bit32u)data & 1) { + cache_checkinstr(8); + cache_addw(0x7800 + dest_reg + (data_reg << 3)); // ldrb dest_reg, [data_reg] + cache_addw(0x7800 + templo1 + (data_reg << 3) + (1 << 6)); // ldrb templo1, [data_reg, #1] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (8 << 6)); // lsl templo1, templo1, #8 + cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + } else { + cache_checkinstr(2); + cache_addw(0x8800 + dest_reg + (data_reg << 3)); // ldrh dest_reg, [data_reg] + } + } +} + +// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { + gen_mov_dword_to_reg_imm(templo2, (Bit32u)data); + gen_mov_word_to_reg_helper(dest_reg, data, dword, templo2); +} + +// move a 16bit constant value into dest_reg +// the upper 16bit of the destination register may be destroyed +static void INLINE gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { + gen_mov_dword_to_reg_imm(dest_reg, (Bit32u)imm); +} + +// helper function for gen_mov_word_from_reg +static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, HostReg data_reg) { + // alignment.... + if (dword) { + if ((Bit32u)dest & 3) { + if ( ((Bit32u)dest & 3) == 2 ) { + cache_checkinstr(8); + cache_addw(0x8000 + src_reg + (data_reg << 3)); // strh src_reg, [data_reg] + cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg + cache_addw(0x0800 + templo1 + (templo1 << 3) + (16 << 6)); // lsr templo1, templo1, #16 + cache_addw(0x8000 + templo1 + (data_reg << 3) + (2 << 5)); // strh templo1, [data_reg, #2] + } else { + cache_checkinstr(20); + cache_addw(0x7000 + src_reg + (data_reg << 3)); // strb src_reg, [data_reg] + cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg + cache_addw(0x0800 + templo1 + (templo1 << 3) + (8 << 6)); // lsr templo1, templo1, #8 + cache_addw(0x7000 + templo1 + (data_reg << 3) + (1 << 6)); // strb templo1, [data_reg, #1] + cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg + cache_addw(0x0800 + templo1 + (templo1 << 3) + (16 << 6)); // lsr templo1, templo1, #16 + cache_addw(0x7000 + templo1 + (data_reg << 3) + (2 << 6)); // strb templo1, [data_reg, #2] + cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg + cache_addw(0x0800 + templo1 + (templo1 << 3) + (24 << 6)); // lsr templo1, templo1, #24 + cache_addw(0x7000 + templo1 + (data_reg << 3) + (3 << 6)); // strb templo1, [data_reg, #3] + } + } else { + cache_checkinstr(2); + cache_addw(0x6000 + src_reg + (data_reg << 3)); // str src_reg, [data_reg] + } + } else { + if ((Bit32u)dest & 1) { + cache_checkinstr(8); + cache_addw(0x7000 + src_reg + (data_reg << 3)); // strb src_reg, [data_reg] + cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg + cache_addw(0x0800 + templo1 + (templo1 << 3) + (8 << 6)); // lsr templo1, templo1, #8 + cache_addw(0x7000 + templo1 + (data_reg << 3) + (1 << 6)); // strb templo1, [data_reg, #1] + } else { + cache_checkinstr(2); + cache_addw(0x8000 + src_reg + (data_reg << 3)); // strh src_reg, [data_reg] + } + } +} + +// move 32bit (dword==true) or 16bit (dword==false) of a register into memory +static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_from_reg_helper(src_reg, dest, dword, templo2); +} + +// move an 8bit value from memory into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { + gen_mov_dword_to_reg_imm(templo1, (Bit32u)data); + cache_checkinstr(2); + cache_addw(0x7800 + dest_reg + (templo1 << 3)); // ldrb dest_reg, [templo1] +} + +// move an 8bit value from memory into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { + gen_mov_byte_to_reg_low(dest_reg, data); +} + +// move an 8bit constant value into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { + cache_checkinstr(2); + cache_addw(0x2000 + (dest_reg << 8) + imm); // mov dest_reg, #(imm) +} + +// move an 8bit constant value into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { + gen_mov_byte_to_reg_low_imm(dest_reg, imm); +} + +// move the lowest 8bit of a register into memory +static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { + gen_mov_dword_to_reg_imm(templo1, (Bit32u)dest); + cache_checkinstr(2); + cache_addw(0x7000 + src_reg + (templo1 << 3)); // strb src_reg, [templo1] +} + + + +// convert an 8bit word to a 32bit dword +// the register is zero-extended (sign==false) or sign-extended (sign==true) +static void gen_extend_byte(bool sign,HostReg reg) { + cache_checkinstr(4); + cache_addw(0x0000 + reg + (reg << 3) + (24 << 6)); // lsl reg, reg, #24 + + if (sign) { + cache_addw(0x1000 + reg + (reg << 3) + (24 << 6)); // asr reg, reg, #24 + } else { + cache_addw(0x0800 + reg + (reg << 3) + (24 << 6)); // lsr reg, reg, #24 + } +} + +// convert a 16bit word to a 32bit dword +// the register is zero-extended (sign==false) or sign-extended (sign==true) +static void gen_extend_word(bool sign,HostReg reg) { + cache_checkinstr(4); + cache_addw(0x0000 + reg + (reg << 3) + (16 << 6)); // lsl reg, reg, #16 + + if (sign) { + cache_addw(0x1000 + reg + (reg << 3) + (16 << 6)); // asr reg, reg, #16 + } else { + cache_addw(0x0800 + reg + (reg << 3) + (16 << 6)); // lsr reg, reg, #16 + } +} + +// add a 32bit value from memory to a full register +static void gen_add(HostReg reg,void* op) { + cache_checkinstr(2); + cache_addw(0x4680 + (temphi1 - HOST_r8) + (reg << 3)); // mov temphi1, reg + gen_mov_word_to_reg(reg, op, 1); + cache_checkinstr(2); + cache_addw(0x4440 + (reg) + ((temphi1 - HOST_r8) << 3)); // add reg, temphi1 +} + +// add a 32bit constant value to a full register +static void gen_add_imm(HostReg reg,Bit32u imm) { + if(!imm) return; + gen_mov_dword_to_reg_imm(templo1, imm); + cache_checkinstr(2); + cache_addw(0x1800 + reg + (reg << 3) + (templo1 << 6)); // add reg, reg, templo1 +} + +// and a 32bit constant value with a full register +static void gen_and_imm(HostReg reg,Bit32u imm) { + if(imm == 0xffffffff) return; + gen_mov_dword_to_reg_imm(templo1, imm); + cache_checkinstr(2); + cache_addw(0x4000 + reg + (templo1<< 3)); // and reg, templo1 +} + + +// move a 32bit constant value into memory +static void gen_mov_direct_dword(void* dest,Bit32u imm) { + cache_checkinstr(2); + cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + gen_mov_dword_to_reg_imm(templosav, imm); + gen_mov_word_from_reg(templosav, dest, 1); + cache_checkinstr(2); + cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 +} + +// move an address into memory +static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { + gen_mov_direct_dword(dest,(Bit32u)imm); +} + +// add an 8bit constant value to a dword memory value +static void gen_add_direct_byte(void* dest,Bit8s imm) { + if(!imm) return; + cache_checkinstr(2); + cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_to_reg_helper(templosav, dest, 1, templo2); + cache_checkinstr(2); + if (imm >= 0) { + cache_addw(0x3000 + (templosav << 8) + ((Bit32s)imm)); // add templosav, #(imm) + } else { + cache_addw(0x3800 + (templosav << 8) + (-((Bit32s)imm))); // sub templosav, #(-imm) + } + gen_mov_word_from_reg_helper(templosav, dest, 1, templo2); + cache_checkinstr(2); + cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 +} + +// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value +static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { + if(!imm) return; + if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { + gen_add_direct_byte(dest,(Bit8s)imm); + return; + } + cache_checkinstr(2); + cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_to_reg_helper(templosav, dest, dword, templo2); + if (dword) { + gen_mov_dword_to_reg_imm(templo1, imm); + } else { + gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); + } + cache_checkinstr(2); + cache_addw(0x1800 + templosav + (templosav << 3) + (templo1 << 6)); // add templosav, templosav, templo1 + gen_mov_word_from_reg_helper(templosav, dest, dword, templo2); + cache_checkinstr(2); + cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 +} + +// subtract an 8bit constant value from a dword memory value +static void gen_sub_direct_byte(void* dest,Bit8s imm) { + if(!imm) return; + cache_checkinstr(2); + cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_to_reg_helper(templosav, dest, 1, templo2); + cache_checkinstr(2); + if (imm >= 0) { + cache_addw(0x3800 + (templosav << 8) + ((Bit32s)imm)); // sub templosav, #(imm) + } else { + cache_addw(0x3000 + (templosav << 8) + (-((Bit32s)imm))); // add templosav, #(-imm) + } + gen_mov_word_from_reg_helper(templosav, dest, 1, templo2); + cache_checkinstr(2); + cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 +} + +// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value +static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { + if(!imm) return; + if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { + gen_sub_direct_byte(dest,(Bit8s)imm); + return; + } + cache_checkinstr(2); + cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_to_reg_helper(templosav, dest, dword, templo2); + if (dword) { + gen_mov_dword_to_reg_imm(templo1, imm); + } else { + gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); + } + cache_checkinstr(2); + cache_addw(0x1a00 + templosav + (templosav << 3) + (templo1 << 6)); // sub templosav, templosav, templo1 + gen_mov_word_from_reg_helper(templosav, dest, dword, templo2); + cache_checkinstr(2); + cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 +} + +// effective address calculation, destination is dest_reg +// scale_reg is scaled by scale (scale_reg*(2^scale)) and +// added to dest_reg, then the immediate value is added +static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { + if (scale) { + cache_checkinstr(4); + cache_addw(0x0000 + templo1 + (scale_reg << 3) + (scale << 6)); // lsl templo1, scale_reg, #(scale) + cache_addw(0x1800 + dest_reg + (dest_reg << 3) + (templo1 << 6)); // add dest_reg, dest_reg, templo1 + } else { + cache_checkinstr(2); + cache_addw(0x1800 + dest_reg + (dest_reg << 3) + (scale_reg << 6)); // add dest_reg, dest_reg, scale_reg + } + gen_add_imm(dest_reg, imm); +} + +// effective address calculation, destination is dest_reg +// dest_reg is scaled by scale (dest_reg*(2^scale)), +// then the immediate value is added +static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { + if (scale) { + cache_checkinstr(2); + cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (scale << 6)); // lsl dest_reg, dest_reg, #(scale) + } + gen_add_imm(dest_reg, imm); +} + +// helper function for gen_call_function_raw and gen_call_function_setup +static void gen_call_function_helper(void * func) { + Bit8u *datapos; + + datapos = cache_reservedata(); + *(Bit32u*)datapos=(Bit32u)func; + + if (((Bit32u)cache.pos & 0x03) == 0) { + cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 4)) >> 2)); // ldr templo1, [pc, datapos] + cache_addw(0xa000 + (templo2 << 8) + (8 >> 2)); // adr templo2, after_call (add templo2, pc, #8) + cache_addw(0x3000 + (templo2 << 8) + (1)); // add templo2, #1 + cache_addw(0x4680 + (HOST_lr - HOST_r8) + (templo2 << 3)); // mov lr, templo2 + cache_addw(0x4700 + (templo1 << 3)); // bx templo1 --- switch to arm state + cache_addw(0x46c0); // nop + } else { + cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 2)) >> 2)); // ldr templo1, [pc, datapos] + cache_addw(0xa000 + (templo2 << 8) + (4 >> 2)); // adr templo2, after_call (add templo2, pc, #4) + cache_addw(0x3000 + (templo2 << 8) + (1)); // add templo2, #1 + cache_addw(0x4680 + (HOST_lr - HOST_r8) + (templo2 << 3)); // mov lr, templo2 + cache_addw(0x4700 + (templo1 << 3)); // bx templo1 --- switch to arm state + } + // after_call: + + // thumb state from now on + cache_addw(0x1c00 + FC_RETOP + (HOST_a1 << 3)); // mov FC_RETOP, a1 +} + +// generate a call to a parameterless function +static void INLINE gen_call_function_raw(void * func) { + cache_checkinstr(14); + gen_call_function_helper(func); +} + +// generate a call to a function with paramcount parameters +// note: the parameters are loaded in the architecture specific way +// using the gen_load_param_ functions below +static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { + cache_checkinstr(14); + Bit32u proc_addr = (Bit32u)cache.pos; + gen_call_function_helper(func); + return proc_addr; + // if proc_addr is on word boundary ((proc_addr & 0x03) == 0) + // then length of generated code is 14 bytes + // otherwise length of generated code is 12 bytes +} + +#if (1) +// max of 4 parameters in a1-a4 + +// load an immediate value as param'th function parameter +static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { + gen_mov_dword_to_reg_imm(param, imm); +} + +// load an address as param'th function parameter +static void INLINE gen_load_param_addr(Bitu addr,Bitu param) { + gen_mov_dword_to_reg_imm(param, addr); +} + +// load a host-register as param'th function parameter +static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { + gen_mov_regs(param, reg); +} + +// load a value from memory as param'th function parameter +static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { + gen_mov_word_to_reg(param, (void *)mem, 1); +} +#else + other arm abis +#endif + +// jump to an address pointed at by ptr, offset is in imm +static void gen_jmp_ptr(void * ptr,Bits imm=0) { + cache_checkinstr(2); + cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + gen_mov_word_to_reg(templosav, ptr, 1); + + if (imm) { + gen_mov_dword_to_reg_imm(templo2, imm); + cache_checkinstr(2); + cache_addw(0x1800 + templosav + (templosav << 3) + (templo2 << 6)); // add templosav, templosav, templo2 + } + +#if (1) +// (*ptr) should be word aligned + if ((imm & 0x03) == 0) { + cache_checkinstr(8); + cache_addw(0x6800 + templo2 + (templosav << 3)); // ldr templo2, [templosav] + } else +#endif + { + cache_checkinstr(26); + cache_addw(0x7800 + templo2 + (templosav << 3)); // ldrb templo2, [templosav] + cache_addw(0x7800 + templo1 + (templosav << 3) + (1 << 6)); // ldrb templo1, [templosav, #1] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (8 << 6)); // lsl templo1, templo1, #8 + cache_addw(0x4300 + templo2 + (templo1 << 3)); // orr templo2, templo1 + cache_addw(0x7800 + templo1 + (templosav << 3) + (2 << 6)); // ldrb templo1, [templosav, #2] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (16 << 6)); // lsl templo1, templo1, #16 + cache_addw(0x4300 + templo2 + (templo1 << 3)); // orr templo2, templo1 + cache_addw(0x7800 + templo1 + (templosav << 3) + (3 << 6)); // ldrb templo1, [templosav, #3] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (24 << 6)); // lsl templo1, templo1, #24 + cache_addw(0x4300 + templo2 + (templo1 << 3)); // orr templo2, templo1 + } + + // increase jmp address to keep thumb state + cache_addw(0x1c00 + templo2 + (templo2 << 3) + (1 << 6)); // add templo2, templo2, #1 + + cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + + cache_addw(0x4700 + (templo2 << 3)); // bx templo2 +} + +// short conditional jump (+-127 bytes) if register is zero +// the destination is set by gen_fill_branch() later +static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { + cache_checkinstr(4); + if (dword) { + cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + } else { + cache_addw(0x0000 + templo1 + (reg << 3) + (16 << 6)); // lsl templo1, reg, #16 + } + cache_addw(0xd000); // beq j + return ((Bit32u)cache.pos-2); +} + +// short conditional jump (+-127 bytes) if register is nonzero +// the destination is set by gen_fill_branch() later +static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { + cache_checkinstr(4); + if (dword) { + cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + } else { + cache_addw(0x0000 + templo1 + (reg << 3) + (16 << 6)); // lsl templo1, reg, #16 + } + cache_addw(0xd100); // bne j + return ((Bit32u)cache.pos-2); +} + +// calculate relative offset and fill it into the location pointed to by data +static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) { +#if C_DEBUG + Bits len=(Bit32u)cache.pos-(data+4); + if (len<0) len=-len; + if (len>252) LOG_MSG("Big jump %d",len); +#endif + *(Bit8u*)data=(Bit8u)( ((Bit32u)cache.pos-(data+4)) >> 1 ); +} + + +// conditional jump if register is nonzero +// for isdword==true the 32bit of the register are tested +// for isdword==false the lowest 8bit of the register are tested +static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { + Bit8u *datapos; + + cache_checkinstr(8); + datapos = cache_reservedata(); + + if (isdword) { + cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + } else { + cache_addw(0x0000 + templo2 + (reg << 3) + (24 << 6)); // lsl templo2, reg, #24 + } + cache_addw(0xd000 + (2 >> 1)); // beq nobranch (pc+2) + if (((Bit32u)cache.pos & 0x03) == 0) { + cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 4)) >> 2)); // ldr templo1, [pc, datapos] + } else { + cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 2)) >> 2)); // ldr templo1, [pc, datapos] + } + cache_addw(0x4700 + (templo1 << 3)); // bx templo1 + // nobranch: + return ((Bit32u)datapos); +} + +// compare 32bit-register against zero and jump if value less/equal than zero +static Bit32u gen_create_branch_long_leqzero(HostReg reg) { + Bit8u *datapos; + + cache_checkinstr(8); + datapos = cache_reservedata(); + + cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + cache_addw(0xdc00 + (2 >> 1)); // bgt nobranch (pc+2) + if (((Bit32u)cache.pos & 0x03) == 0) { + cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 4)) >> 2)); // ldr templo1, [pc, datapos] + } else { + cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 2)) >> 2)); // ldr templo1, [pc, datapos] + } + cache_addw(0x4700 + (templo1 << 3)); // bx templo1 + // nobranch: + return ((Bit32u)datapos); +} + +// calculate long relative offset and fill it into the location pointed to by data +static void INLINE gen_fill_branch_long(Bit32u data) { + // this is an absolute branch + *(Bit32u*)data=((Bit32u)cache.pos) + 1; // add 1 to keep processor in thumb state +} + +static void gen_run_code(void) { + // switch from arm to thumb state + cache_addd(0xe2800000 + (HOST_r3 << 12) + (HOST_pc << 16) + (1)); // add r3, pc, #1 + cache_addd(0xe12fff10 + (HOST_r3)); // bx r3 + + // thumb state from now on + cache_addw(0xb500); // push {lr} + cache_addw(0xb4f0); // push {v1-v4} + + cache_addw(0xa302); // add r3, pc, #8 + cache_addw(0x3001); // add r0, #1 + cache_addw(0x3301); // add r3, #1 + cache_addw(0xb408); // push {r3} + cache_addw(0x4700); // bx r0 + cache_addw(0x46c0); // nop + + cache_addw(0xbcf0); // pop {v1-v4} + + cache_addw(0xbc08); // pop {r3} + cache_addw(0x4718); // bx r3 +} + +// return from a function +static void gen_return_function(void) { + cache_checkinstr(6); + cache_addw(0x1c00 + HOST_a1 + (FC_RETOP << 3)); // mov a1, FC_RETOP + cache_addw(0xbc08); // pop {r3} + cache_addw(0x4718); // bx r3 +} + + +// short unconditional jump (over data pool) +// must emit at most CACHE_DATA_JUMP bytes +static void INLINE gen_create_branch_short(void * func) { + cache_addw(0xe000 + (((Bit32u)func - ((Bit32u)cache.pos + 4)) >> 1) ); // b func +} + + +#ifdef DRC_FLAGS_INVALIDATION + +// called when a call to a function can be replaced by a +// call to a simpler function +static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { + if ((*(Bit16u*)pos & 0xf000) == 0xe000) { + if ((*(Bit16u*)pos & 0x0fff) >= ((CACHE_DATA_ALIGN / 2) - 1) && + (*(Bit16u*)pos & 0x0fff) < 0x0800) + { + pos = (Bit8u *) ( ( ( (Bit32u)(*(Bit16u*)pos & 0x0fff) ) << 1 ) + ((Bit32u)pos + 4) ); + } + } + +#ifdef DRC_FLAGS_INVALIDATION_DCODE + if (((Bit32u)pos & 0x03) == 0) + { + // try to avoid function calls but rather directly fill in code + switch (flags_type) { + case t_ADDb: + case t_ADDw: + case t_ADDd: + *(Bit16u*)pos=0x1800 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // add FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=0xe000 + (8 >> 1); // b after_call (pc+8) + break; + case t_ORb: + case t_ORw: + case t_ORd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4300 + FC_RETOP + (HOST_a2 << 3); // orr FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (6 >> 1); // b after_call (pc+6) + break; + case t_ANDb: + case t_ANDw: + case t_ANDd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4000 + FC_RETOP + (HOST_a2 << 3); // and FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (6 >> 1); // b after_call (pc+6) + break; + case t_SUBb: + case t_SUBw: + case t_SUBd: + *(Bit16u*)pos=0x1a00 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // sub FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=0xe000 + (8 >> 1); // b after_call (pc+8) + break; + case t_XORb: + case t_XORw: + case t_XORd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4040 + FC_RETOP + (HOST_a2 << 3); // eor FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (6 >> 1); // b after_call (pc+6) + break; + case t_CMPb: + case t_CMPw: + case t_CMPd: + case t_TESTb: + case t_TESTw: + case t_TESTd: + *(Bit16u*)pos=0xe000 + (10 >> 1); // b after_call (pc+10) + break; + case t_INCb: + case t_INCw: + case t_INCd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // add FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=0xe000 + (8 >> 1); // b after_call (pc+8) + break; + case t_DECb: + case t_DECw: + case t_DECd: + *(Bit16u*)pos=0x1e00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // sub FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=0xe000 + (8 >> 1); // b after_call (pc+8) + break; + case t_SHLb: + case t_SHLw: + case t_SHLd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4080 + FC_RETOP + (HOST_a2 << 3); // lsl FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (6 >> 1); // b after_call (pc+6) + break; + case t_SHRb: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // lsr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (4 >> 1); // b after_call (pc+4) + break; + case t_SHRw: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // lsr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (4 >> 1); // b after_call (pc+4) + break; + case t_SHRd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (6 >> 1); // b after_call (pc+6) + break; + case t_SARb: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // asr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (4 >> 1); // b after_call (pc+4) + break; + case t_SARw: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // asr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (4 >> 1); // b after_call (pc+4) + break; + case t_SARd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (6 >> 1); // b after_call (pc+6) + break; + case t_RORb: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+4)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP + *(Bit16u*)(pos+6)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=0x46c0; // nop + *(Bit16u*)(pos+12)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + break; + case t_RORw: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=0x46c0; // nop + *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+6)=0x46c0; // nop + *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=0x46c0; // nop + *(Bit16u*)(pos+12)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + break; + case t_RORd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (6 >> 1); // b after_call (pc+6) + break; + /*case t_ROLb: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 + *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 + *(Bit16u*)(pos+8)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP + *(Bit16u*)(pos+10)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+12)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+14)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + break;*/ + case t_ROLw: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 + *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 + *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=0x46c0; // nop + *(Bit16u*)(pos+12)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + break; + case t_ROLd: + *(Bit16u*)pos=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 + *(Bit16u*)(pos+2)=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+4)=0x46c0; // nop + *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 + *(Bit16u*)(pos+8)=0x46c0; // nop + *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+12)=0x46c0; // nop + break; + case t_NEGb: + case t_NEGw: + case t_NEGd: + *(Bit16u*)pos=0x4240 + FC_RETOP + (HOST_a1 << 3); // neg FC_RETOP, a1 + *(Bit16u*)(pos+2)=0xe000 + (8 >> 1); // b after_call (pc+8) + break; + default: + *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 4) ) = (Bit32u)fct_ptr; // simple_func + break; + } + } + else + { + // try to avoid function calls but rather directly fill in code + switch (flags_type) { + case t_ADDb: + case t_ADDw: + case t_ADDd: + *(Bit16u*)pos=0x1800 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // add FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=0xe000 + (6 >> 1); // b after_call (pc+6) + break; + case t_ORb: + case t_ORw: + case t_ORd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4300 + FC_RETOP + (HOST_a2 << 3); // orr FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (4 >> 1); // b after_call (pc+4) + break; + case t_ANDb: + case t_ANDw: + case t_ANDd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4000 + FC_RETOP + (HOST_a2 << 3); // and FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (4 >> 1); // b after_call (pc+4) + break; + case t_SUBb: + case t_SUBw: + case t_SUBd: + *(Bit16u*)pos=0x1a00 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // sub FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=0xe000 + (6 >> 1); // b after_call (pc+6) + break; + case t_XORb: + case t_XORw: + case t_XORd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4040 + FC_RETOP + (HOST_a2 << 3); // eor FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (4 >> 1); // b after_call (pc+4) + break; + case t_CMPb: + case t_CMPw: + case t_CMPd: + case t_TESTb: + case t_TESTw: + case t_TESTd: + *(Bit16u*)pos=0xe000 + (8 >> 1); // b after_call (pc+8) + break; + case t_INCb: + case t_INCw: + case t_INCd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // add FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=0xe000 + (6 >> 1); // b after_call (pc+6) + break; + case t_DECb: + case t_DECw: + case t_DECd: + *(Bit16u*)pos=0x1e00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // sub FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=0xe000 + (6 >> 1); // b after_call (pc+6) + break; + case t_SHLb: + case t_SHLw: + case t_SHLd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4080 + FC_RETOP + (HOST_a2 << 3); // lsl FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (4 >> 1); // b after_call (pc+4) + break; + case t_SHRb: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=0x46c0; // nop + *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // lsr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+6)=0x46c0; // nop + *(Bit16u*)(pos+8)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+10)=0x46c0; // nop + break; + case t_SHRw: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=0x46c0; // nop + *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // lsr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+6)=0x46c0; // nop + *(Bit16u*)(pos+8)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+10)=0x46c0; // nop + break; + case t_SHRd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (4 >> 1); // b after_call (pc+4) + break; + case t_SARb: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=0x46c0; // nop + *(Bit16u*)(pos+4)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // asr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+6)=0x46c0; // nop + *(Bit16u*)(pos+8)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 + *(Bit16u*)(pos+10)=0x46c0; // nop + break; + case t_SARw: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=0x46c0; // nop + *(Bit16u*)(pos+4)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // asr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+6)=0x46c0; // nop + *(Bit16u*)(pos+8)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 + *(Bit16u*)(pos+10)=0x46c0; // nop + break; + case t_SARd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (4 >> 1); // b after_call (pc+4) + break; + case t_RORb: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+4)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP + *(Bit16u*)(pos+6)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + break; + case t_RORw: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+4)=0x46c0; // nop + *(Bit16u*)(pos+6)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+8)=0x46c0; // nop + *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + break; + case t_RORd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (4 >> 1); // b after_call (pc+4) + break; + /*case t_ROLb: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 + *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 + *(Bit16u*)(pos+8)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP + *(Bit16u*)(pos+10)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+12)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+14)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + break;*/ + case t_ROLw: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 + *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 + *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + break; + case t_ROLd: + *(Bit16u*)pos=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 + *(Bit16u*)(pos+2)=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+4)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 + *(Bit16u*)(pos+6)=0x46c0; // nop + *(Bit16u*)(pos+8)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+10)=0x46c0; // nop + break; + case t_NEGb: + case t_NEGw: + case t_NEGd: + *(Bit16u*)pos=0x4240 + FC_RETOP + (HOST_a1 << 3); // neg FC_RETOP, a1 + *(Bit16u*)(pos+2)=0xe000 + (6 >> 1); // b after_call (pc+6) + break; + default: + *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 2) ) = (Bit32u)fct_ptr; // simple_func + break; + } + + } +#else + if (((Bit32u)pos & 0x03) == 0) + { + *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 4) ) = (Bit32u)fct_ptr; // simple_func + } + else + { + *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 2) ) = (Bit32u)fct_ptr; // simple_func + } +#endif +} +#endif diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h new file mode 100644 index 00000000..81a01bce --- /dev/null +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h @@ -0,0 +1,1132 @@ +/* + * 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: risc_armv4le-thumb-niw.h,v 1.1 2008-09-02 20:44:41 c2woody Exp $ */ + + +/* ARMv4 (little endian) backend by M-HT (thumb version) */ + + +// temporary "lo" registers +#define templo1 HOST_v3 +#define templo2 HOST_v4 + +// temporary "lo" register - value must be preserved when using it +#define templosav HOST_a3 + +// temporary "hi" register +#define temphi1 HOST_ip + +// register that holds function return values +#define FC_RETOP HOST_v2 + +// register used for address calculations, +#define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG + +// register that holds the first parameter +#define FC_OP1 HOST_a1 + +// register that holds the second parameter +#define FC_OP2 HOST_a2 + +// register that holds byte-accessible temporary values +#define FC_TMP_BA1 HOST_a1 + +// register that holds byte-accessible temporary values +#define FC_TMP_BA2 HOST_a2 + +// temporary register for LEA +#define TEMP_REG_DRC HOST_a4 + + +// data pool defines +#define CACHE_DATA_JUMP (2) +#define CACHE_DATA_ALIGN (32) +#define CACHE_DATA_MIN (32) +#define CACHE_DATA_MAX (288) + +// data pool variables +static Bit8u * cache_datapos = NULL; // position of data pool in the cache block +static Bit32u cache_datasize = 0; // total size of data pool +static Bit32u cache_dataindex = 0; // used size of data pool = index of free data item (in bytes) in data pool + + +static void INLINE gen_create_branch_short(void * func); + +// function to check distance to data pool +// if too close, then generate jump after data pool +static void cache_checkinstr(Bit32u size) { + if (cache_datasize == 0) { + if (cache_datapos != NULL) { + if (cache.pos + size + CACHE_DATA_JUMP >= cache_datapos) { + cache_datapos = NULL; + } + } + return; + } + + if (cache.pos + size + CACHE_DATA_JUMP <= cache_datapos) return; + + { + register Bit8u * newcachepos; + + newcachepos = cache_datapos + cache_datasize; + gen_create_branch_short(newcachepos); + cache.pos = newcachepos; + } + + if (cache.pos + CACHE_DATA_MAX + CACHE_DATA_ALIGN >= cache.block.active->cache.start + cache.block.active->cache.size && + cache.pos + CACHE_DATA_MIN + CACHE_DATA_ALIGN + (CACHE_DATA_ALIGN - CACHE_ALIGN) < cache.block.active->cache.start + cache.block.active->cache.size) + { + cache_datapos = (Bit8u *) (((Bitu)cache.block.active->cache.start + cache.block.active->cache.size - CACHE_DATA_ALIGN) & ~(CACHE_DATA_ALIGN - 1)); + } else { + register Bit32u cachemodsize; + + cachemodsize = (cache.pos - cache.block.active->cache.start) & (CACHE_MAXSIZE - 1); + + if (cachemodsize + CACHE_DATA_MAX + CACHE_DATA_ALIGN <= CACHE_MAXSIZE || + cachemodsize + CACHE_DATA_MIN + CACHE_DATA_ALIGN + (CACHE_DATA_ALIGN - CACHE_ALIGN) > CACHE_MAXSIZE) + { + cache_datapos = (Bit8u *) (((Bitu)cache.pos + CACHE_DATA_MAX) & ~(CACHE_DATA_ALIGN - 1)); + } else { + cache_datapos = (Bit8u *) (((Bitu)cache.pos + (CACHE_MAXSIZE - CACHE_DATA_ALIGN) - cachemodsize) & ~(CACHE_DATA_ALIGN - 1)); + } + } + + cache_datasize = 0; + cache_dataindex = 0; +} + +// function to reserve item in data pool +// returns address of item +static Bit8u * cache_reservedata(void) { + // if data pool not yet initialized, then initialize data pool + if (GCC_UNLIKELY(cache_datapos == NULL)) { + if (cache.pos + CACHE_DATA_MIN + CACHE_DATA_ALIGN < cache.block.active->cache.start + CACHE_DATA_MAX) { + cache_datapos = (Bit8u *) (((Bitu)cache.block.active->cache.start + CACHE_DATA_MAX) & ~(CACHE_DATA_ALIGN - 1)); + } + } + + // if data pool not yet used, then set data pool + if (cache_datasize == 0) { + // set data pool address is too close (or behind) cache.pos then set new data pool size + if (cache.pos + CACHE_DATA_MIN + CACHE_DATA_JUMP /*+ CACHE_DATA_ALIGN*/ > cache_datapos) { + if (cache.pos + CACHE_DATA_MAX + CACHE_DATA_ALIGN >= cache.block.active->cache.start + cache.block.active->cache.size && + cache.pos + CACHE_DATA_MIN + CACHE_DATA_ALIGN + (CACHE_DATA_ALIGN - CACHE_ALIGN) < cache.block.active->cache.start + cache.block.active->cache.size) + { + cache_datapos = (Bit8u *) (((Bitu)cache.block.active->cache.start + cache.block.active->cache.size - CACHE_DATA_ALIGN) & ~(CACHE_DATA_ALIGN - 1)); + } else { + register Bit32u cachemodsize; + + cachemodsize = (cache.pos - cache.block.active->cache.start) & (CACHE_MAXSIZE - 1); + + if (cachemodsize + CACHE_DATA_MAX + CACHE_DATA_ALIGN <= CACHE_MAXSIZE || + cachemodsize + CACHE_DATA_MIN + CACHE_DATA_ALIGN + (CACHE_DATA_ALIGN - CACHE_ALIGN) > CACHE_MAXSIZE) + { + cache_datapos = (Bit8u *) (((Bitu)cache.pos + CACHE_DATA_MAX) & ~(CACHE_DATA_ALIGN - 1)); + } else { + cache_datapos = (Bit8u *) (((Bitu)cache.pos + (CACHE_MAXSIZE - CACHE_DATA_ALIGN) - cachemodsize) & ~(CACHE_DATA_ALIGN - 1)); + } + } + } + // set initial data pool size + cache_datasize = CACHE_DATA_ALIGN; + } + + // if data pool is full, then enlarge data pool + if (cache_dataindex == cache_datasize) { + cache_datasize += CACHE_DATA_ALIGN; + } + + cache_dataindex += 4; + return (cache_datapos + (cache_dataindex - 4)); +} + +static void cache_block_before_close(void) { + // if data pool in use, then resize cache block to include the data pool + if (cache_datasize != 0) + { + cache.pos = cache_datapos + cache_dataindex; + } + + // clear the values before next use + cache_datapos = NULL; + cache_datasize = 0; + cache_dataindex = 0; +} + + +// move a full register from reg_src to reg_dst +static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { + if(reg_src == reg_dst) return; + cache_checkinstr(2); + cache_addw(0x1c00 + reg_dst + (reg_src << 3)); // mov reg_dst, reg_src +} + +// move a 32bit constant value into dest_reg +static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { + if ((imm & 0xffffff00) == 0) { + cache_checkinstr(2); + cache_addw(0x2000 + (dest_reg << 8) + imm); // mov dest_reg, #(imm) + } else if ((imm & 0xffff00ff) == 0) { + cache_checkinstr(4); + cache_addw(0x2000 + (dest_reg << 8) + (imm >> 8)); // mov dest_reg, #(imm >> 8) + cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (8 << 6)); // lsl dest_reg, dest_reg, #8 + } else if ((imm & 0xff00ffff) == 0) { + cache_checkinstr(4); + cache_addw(0x2000 + (dest_reg << 8) + (imm >> 16)); // mov dest_reg, #(imm >> 16) + cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (16 << 6)); // lsl dest_reg, dest_reg, #16 + } else if ((imm & 0x00ffffff) == 0) { + cache_checkinstr(4); + cache_addw(0x2000 + (dest_reg << 8) + (imm >> 24)); // mov dest_reg, #(imm >> 24) + cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (24 << 6)); // lsl dest_reg, dest_reg, #24 + } else { + Bit32u diff; + + cache_checkinstr(4); + + diff = imm - ((Bit32u)cache.pos+4); + + if ((diff < 1024) && ((imm & 0x03) == 0)) { + if (((Bit32u)cache.pos & 0x03) == 0) { + cache_addw(0xa000 + (dest_reg << 8) + (diff >> 2)); // add dest_reg, pc, #(diff >> 2) + } else { + cache_addw(0x46c0); // nop + cache_addw(0xa000 + (dest_reg << 8) + ((diff - 2) >> 2)); // add dest_reg, pc, #((diff - 2) >> 2) + } + } else { + Bit8u *datapos; + + datapos = cache_reservedata(); + *(Bit32u*)datapos=imm; + + if (((Bit32u)cache.pos & 0x03) == 0) { + cache_addw(0x4800 + (dest_reg << 8) + ((datapos - (cache.pos + 4)) >> 2)); // ldr dest_reg, [pc, datapos] + } else { + cache_addw(0x4800 + (dest_reg << 8) + ((datapos - (cache.pos + 2)) >> 2)); // ldr dest_reg, [pc, datapos] + } + } + } +} + +// helper function for gen_mov_word_to_reg +static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,HostReg data_reg) { + // alignment.... + if (dword) { + if ((Bit32u)data & 3) { + if ( ((Bit32u)data & 3) == 2 ) { + cache_checkinstr(8); + cache_addw(0x8800 + dest_reg + (data_reg << 3)); // ldrh dest_reg, [data_reg] + cache_addw(0x8800 + templo1 + (data_reg << 3) + (2 << 5)); // ldrh templo1, [data_reg, #2] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (16 << 6)); // lsl templo1, templo1, #16 + cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + } else { + cache_checkinstr(16); + cache_addw(0x7800 + dest_reg + (data_reg << 3)); // ldrb dest_reg, [data_reg] + cache_addw(0x1c00 + templo1 + (data_reg << 3) + (1 << 6)); // add templo1, data_reg, #1 + cache_addw(0x8800 + templo1 + (templo1 << 3)); // ldrh templo1, [templo1] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (8 << 6)); // lsl templo1, templo1, #8 + cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + cache_addw(0x7800 + templo1 + (data_reg << 3) + (3 << 6)); // ldrb templo1, [data_reg, #3] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (24 << 6)); // lsl templo1, templo1, #24 + cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + } + } else { + cache_checkinstr(2); + cache_addw(0x6800 + dest_reg + (data_reg << 3)); // ldr dest_reg, [data_reg] + } + } else { + if ((Bit32u)data & 1) { + cache_checkinstr(8); + cache_addw(0x7800 + dest_reg + (data_reg << 3)); // ldrb dest_reg, [data_reg] + cache_addw(0x7800 + templo1 + (data_reg << 3) + (1 << 6)); // ldrb templo1, [data_reg, #1] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (8 << 6)); // lsl templo1, templo1, #8 + cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + } else { + cache_checkinstr(2); + cache_addw(0x8800 + dest_reg + (data_reg << 3)); // ldrh dest_reg, [data_reg] + } + } +} + +// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { + gen_mov_dword_to_reg_imm(templo2, (Bit32u)data); + gen_mov_word_to_reg_helper(dest_reg, data, dword, templo2); +} + +// move a 16bit constant value into dest_reg +// the upper 16bit of the destination register may be destroyed +static void INLINE gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { + gen_mov_dword_to_reg_imm(dest_reg, (Bit32u)imm); +} + +// helper function for gen_mov_word_from_reg +static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, HostReg data_reg) { + // alignment.... + if (dword) { + if ((Bit32u)dest & 3) { + if ( ((Bit32u)dest & 3) == 2 ) { + cache_checkinstr(8); + cache_addw(0x8000 + src_reg + (data_reg << 3)); // strh src_reg, [data_reg] + cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg + cache_addw(0x0800 + templo1 + (templo1 << 3) + (16 << 6)); // lsr templo1, templo1, #16 + cache_addw(0x8000 + templo1 + (data_reg << 3) + (2 << 5)); // strh templo1, [data_reg, #2] + } else { + cache_checkinstr(20); + cache_addw(0x7000 + src_reg + (data_reg << 3)); // strb src_reg, [data_reg] + cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg + cache_addw(0x0800 + templo1 + (templo1 << 3) + (8 << 6)); // lsr templo1, templo1, #8 + cache_addw(0x7000 + templo1 + (data_reg << 3) + (1 << 6)); // strb templo1, [data_reg, #1] + cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg + cache_addw(0x0800 + templo1 + (templo1 << 3) + (16 << 6)); // lsr templo1, templo1, #16 + cache_addw(0x7000 + templo1 + (data_reg << 3) + (2 << 6)); // strb templo1, [data_reg, #2] + cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg + cache_addw(0x0800 + templo1 + (templo1 << 3) + (24 << 6)); // lsr templo1, templo1, #24 + cache_addw(0x7000 + templo1 + (data_reg << 3) + (3 << 6)); // strb templo1, [data_reg, #3] + } + } else { + cache_checkinstr(2); + cache_addw(0x6000 + src_reg + (data_reg << 3)); // str src_reg, [data_reg] + } + } else { + if ((Bit32u)dest & 1) { + cache_checkinstr(8); + cache_addw(0x7000 + src_reg + (data_reg << 3)); // strb src_reg, [data_reg] + cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg + cache_addw(0x0800 + templo1 + (templo1 << 3) + (8 << 6)); // lsr templo1, templo1, #8 + cache_addw(0x7000 + templo1 + (data_reg << 3) + (1 << 6)); // strb templo1, [data_reg, #1] + } else { + cache_checkinstr(2); + cache_addw(0x8000 + src_reg + (data_reg << 3)); // strh src_reg, [data_reg] + } + } +} + +// move 32bit (dword==true) or 16bit (dword==false) of a register into memory +static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_from_reg_helper(src_reg, dest, dword, templo2); +} + +// move an 8bit value from memory into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { + gen_mov_dword_to_reg_imm(templo1, (Bit32u)data); + cache_checkinstr(2); + cache_addw(0x7800 + dest_reg + (templo1 << 3)); // ldrb dest_reg, [templo1] +} + +// move an 8bit value from memory into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { + gen_mov_byte_to_reg_low(dest_reg, data); +} + +// move an 8bit constant value into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { + cache_checkinstr(2); + cache_addw(0x2000 + (dest_reg << 8) + imm); // mov dest_reg, #(imm) +} + +// move an 8bit constant value into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { + gen_mov_byte_to_reg_low_imm(dest_reg, imm); +} + +// move the lowest 8bit of a register into memory +static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { + gen_mov_dword_to_reg_imm(templo1, (Bit32u)dest); + cache_checkinstr(2); + cache_addw(0x7000 + src_reg + (templo1 << 3)); // strb src_reg, [templo1] +} + + + +// convert an 8bit word to a 32bit dword +// the register is zero-extended (sign==false) or sign-extended (sign==true) +static void gen_extend_byte(bool sign,HostReg reg) { + cache_checkinstr(4); + cache_addw(0x0000 + reg + (reg << 3) + (24 << 6)); // lsl reg, reg, #24 + + if (sign) { + cache_addw(0x1000 + reg + (reg << 3) + (24 << 6)); // asr reg, reg, #24 + } else { + cache_addw(0x0800 + reg + (reg << 3) + (24 << 6)); // lsr reg, reg, #24 + } +} + +// convert a 16bit word to a 32bit dword +// the register is zero-extended (sign==false) or sign-extended (sign==true) +static void gen_extend_word(bool sign,HostReg reg) { + cache_checkinstr(4); + cache_addw(0x0000 + reg + (reg << 3) + (16 << 6)); // lsl reg, reg, #16 + + if (sign) { + cache_addw(0x1000 + reg + (reg << 3) + (16 << 6)); // asr reg, reg, #16 + } else { + cache_addw(0x0800 + reg + (reg << 3) + (16 << 6)); // lsr reg, reg, #16 + } +} + +// add a 32bit value from memory to a full register +static void gen_add(HostReg reg,void* op) { + cache_checkinstr(2); + cache_addw(0x4680 + (temphi1 - HOST_r8) + (reg << 3)); // mov temphi1, reg + gen_mov_word_to_reg(reg, op, 1); + cache_checkinstr(2); + cache_addw(0x4440 + (reg) + ((temphi1 - HOST_r8) << 3)); // add reg, temphi1 +} + +// add a 32bit constant value to a full register +static void gen_add_imm(HostReg reg,Bit32u imm) { + if(!imm) return; + gen_mov_dword_to_reg_imm(templo1, imm); + cache_checkinstr(2); + cache_addw(0x1800 + reg + (reg << 3) + (templo1 << 6)); // add reg, reg, templo1 +} + +// and a 32bit constant value with a full register +static void gen_and_imm(HostReg reg,Bit32u imm) { + if(imm == 0xffffffff) return; + gen_mov_dword_to_reg_imm(templo1, imm); + cache_checkinstr(2); + cache_addw(0x4000 + reg + (templo1<< 3)); // and reg, templo1 +} + + +// move a 32bit constant value into memory +static void gen_mov_direct_dword(void* dest,Bit32u imm) { + cache_checkinstr(2); + cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + gen_mov_dword_to_reg_imm(templosav, imm); + gen_mov_word_from_reg(templosav, dest, 1); + cache_checkinstr(2); + cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 +} + +// move an address into memory +static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { + gen_mov_direct_dword(dest,(Bit32u)imm); +} + +// add an 8bit constant value to a dword memory value +static void gen_add_direct_byte(void* dest,Bit8s imm) { + if(!imm) return; + cache_checkinstr(2); + cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_to_reg_helper(templosav, dest, 1, templo2); + cache_checkinstr(2); + if (imm >= 0) { + cache_addw(0x3000 + (templosav << 8) + ((Bit32s)imm)); // add templosav, #(imm) + } else { + cache_addw(0x3800 + (templosav << 8) + (-((Bit32s)imm))); // sub templosav, #(-imm) + } + gen_mov_word_from_reg_helper(templosav, dest, 1, templo2); + cache_checkinstr(2); + cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 +} + +// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value +static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { + if(!imm) return; + if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { + gen_add_direct_byte(dest,(Bit8s)imm); + return; + } + cache_checkinstr(2); + cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_to_reg_helper(templosav, dest, dword, templo2); + if (dword) { + gen_mov_dword_to_reg_imm(templo1, imm); + } else { + gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); + } + cache_checkinstr(2); + cache_addw(0x1800 + templosav + (templosav << 3) + (templo1 << 6)); // add templosav, templosav, templo1 + gen_mov_word_from_reg_helper(templosav, dest, dword, templo2); + cache_checkinstr(2); + cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 +} + +// subtract an 8bit constant value from a dword memory value +static void gen_sub_direct_byte(void* dest,Bit8s imm) { + if(!imm) return; + cache_checkinstr(2); + cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_to_reg_helper(templosav, dest, 1, templo2); + cache_checkinstr(2); + if (imm >= 0) { + cache_addw(0x3800 + (templosav << 8) + ((Bit32s)imm)); // sub templosav, #(imm) + } else { + cache_addw(0x3000 + (templosav << 8) + (-((Bit32s)imm))); // add templosav, #(-imm) + } + gen_mov_word_from_reg_helper(templosav, dest, 1, templo2); + cache_checkinstr(2); + cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 +} + +// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value +static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { + if(!imm) return; + if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { + gen_sub_direct_byte(dest,(Bit8s)imm); + return; + } + cache_checkinstr(2); + cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_to_reg_helper(templosav, dest, dword, templo2); + if (dword) { + gen_mov_dword_to_reg_imm(templo1, imm); + } else { + gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); + } + cache_checkinstr(2); + cache_addw(0x1a00 + templosav + (templosav << 3) + (templo1 << 6)); // sub templosav, templosav, templo1 + gen_mov_word_from_reg_helper(templosav, dest, dword, templo2); + cache_checkinstr(2); + cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 +} + +// effective address calculation, destination is dest_reg +// scale_reg is scaled by scale (scale_reg*(2^scale)) and +// added to dest_reg, then the immediate value is added +static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { + if (scale) { + cache_checkinstr(4); + cache_addw(0x0000 + templo1 + (scale_reg << 3) + (scale << 6)); // lsl templo1, scale_reg, #(scale) + cache_addw(0x1800 + dest_reg + (dest_reg << 3) + (templo1 << 6)); // add dest_reg, dest_reg, templo1 + } else { + cache_checkinstr(2); + cache_addw(0x1800 + dest_reg + (dest_reg << 3) + (scale_reg << 6)); // add dest_reg, dest_reg, scale_reg + } + gen_add_imm(dest_reg, imm); +} + +// effective address calculation, destination is dest_reg +// dest_reg is scaled by scale (dest_reg*(2^scale)), +// then the immediate value is added +static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { + if (scale) { + cache_checkinstr(2); + cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (scale << 6)); // lsl dest_reg, dest_reg, #(scale) + } + gen_add_imm(dest_reg, imm); +} + +// helper function for gen_call_function_raw and gen_call_function_setup +static void gen_call_function_helper(void * func) { + Bit8u *datapos; + + datapos = cache_reservedata(); + *(Bit32u*)datapos=(Bit32u)func; + + if (((Bit32u)cache.pos & 0x03) == 0) { + cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 4)) >> 2)); // ldr templo1, [pc, datapos] + cache_addw(0xa000 + (templo2 << 8) + (4 >> 2)); // adr templo2, after_call (add templo2, pc, #4) + cache_addw(0x4680 + (HOST_lr - HOST_r8) + (templo2 << 3)); // mov lr, templo2 + cache_addw(0x4700 + (templo1 << 3)); // bx templo1 --- switch to arm state + } else { + cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 2)) >> 2)); // ldr templo1, [pc, datapos] + cache_addw(0xa000 + (templo2 << 8) + (4 >> 2)); // adr templo2, after_call (add templo2, pc, #4) + cache_addw(0x4680 + (HOST_lr - HOST_r8) + (templo2 << 3)); // mov lr, templo2 + cache_addw(0x4700 + (templo1 << 3)); // bx templo1 --- switch to arm state + cache_addw(0x46c0); // nop + } + // after_call: + + // switch from arm to thumb state + cache_addd(0xe2800000 + (templo1 << 12) + (HOST_pc << 16) + (1)); // add templo1, pc, #1 + cache_addd(0xe12fff10 + (templo1)); // bx templo1 + + // thumb state from now on + cache_addw(0x1c00 + FC_RETOP + (HOST_a1 << 3)); // mov FC_RETOP, a1 +} + +// generate a call to a parameterless function +static void INLINE gen_call_function_raw(void * func) { + cache_checkinstr(20); + gen_call_function_helper(func); +} + +// generate a call to a function with paramcount parameters +// note: the parameters are loaded in the architecture specific way +// using the gen_load_param_ functions below +static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { + cache_checkinstr(20); + Bit32u proc_addr = (Bit32u)cache.pos; + gen_call_function_helper(func); + return proc_addr; + // if proc_addr is on word boundary ((proc_addr & 0x03) == 0) + // then length of generated code is 18 bytes + // otherwise length of generated code is 20 bytes +} + +#if (1) +// max of 4 parameters in a1-a4 + +// load an immediate value as param'th function parameter +static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { + gen_mov_dword_to_reg_imm(param, imm); +} + +// load an address as param'th function parameter +static void INLINE gen_load_param_addr(Bitu addr,Bitu param) { + gen_mov_dword_to_reg_imm(param, addr); +} + +// load a host-register as param'th function parameter +static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { + gen_mov_regs(param, reg); +} + +// load a value from memory as param'th function parameter +static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { + gen_mov_word_to_reg(param, (void *)mem, 1); +} +#else + other arm abis +#endif + +// jump to an address pointed at by ptr, offset is in imm +static void gen_jmp_ptr(void * ptr,Bits imm=0) { + cache_checkinstr(2); + cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + gen_mov_word_to_reg(templosav, ptr, 1); + + if (imm) { + gen_mov_dword_to_reg_imm(templo2, imm); + cache_checkinstr(2); + cache_addw(0x1800 + templosav + (templosav << 3) + (templo2 << 6)); // add templosav, templosav, templo2 + } + +#if (1) +// (*ptr) should be word aligned + if ((imm & 0x03) == 0) { + cache_checkinstr(8); + cache_addw(0x6800 + templo2 + (templosav << 3)); // ldr templo2, [templosav] + } else +#endif + { + cache_checkinstr(26); + cache_addw(0x7800 + templo2 + (templosav << 3)); // ldrb templo2, [templosav] + cache_addw(0x7800 + templo1 + (templosav << 3) + (1 << 6)); // ldrb templo1, [templosav, #1] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (8 << 6)); // lsl templo1, templo1, #8 + cache_addw(0x4300 + templo2 + (templo1 << 3)); // orr templo2, templo1 + cache_addw(0x7800 + templo1 + (templosav << 3) + (2 << 6)); // ldrb templo1, [templosav, #2] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (16 << 6)); // lsl templo1, templo1, #16 + cache_addw(0x4300 + templo2 + (templo1 << 3)); // orr templo2, templo1 + cache_addw(0x7800 + templo1 + (templosav << 3) + (3 << 6)); // ldrb templo1, [templosav, #3] + cache_addw(0x0000 + templo1 + (templo1 << 3) + (24 << 6)); // lsl templo1, templo1, #24 + cache_addw(0x4300 + templo2 + (templo1 << 3)); // orr templo2, templo1 + } + + // increase jmp address to keep thumb state + cache_addw(0x1c00 + templo2 + (templo2 << 3) + (1 << 6)); // add templo2, templo2, #1 + + cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + + cache_addw(0x4700 + (templo2 << 3)); // bx templo2 +} + +// short conditional jump (+-127 bytes) if register is zero +// the destination is set by gen_fill_branch() later +static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { + cache_checkinstr(4); + if (dword) { + cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + } else { + cache_addw(0x0000 + templo1 + (reg << 3) + (16 << 6)); // lsl templo1, reg, #16 + } + cache_addw(0xd000); // beq j + return ((Bit32u)cache.pos-2); +} + +// short conditional jump (+-127 bytes) if register is nonzero +// the destination is set by gen_fill_branch() later +static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { + cache_checkinstr(4); + if (dword) { + cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + } else { + cache_addw(0x0000 + templo1 + (reg << 3) + (16 << 6)); // lsl templo1, reg, #16 + } + cache_addw(0xd100); // bne j + return ((Bit32u)cache.pos-2); +} + +// calculate relative offset and fill it into the location pointed to by data +static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) { +#if C_DEBUG + Bits len=(Bit32u)cache.pos-(data+4); + if (len<0) len=-len; + if (len>252) LOG_MSG("Big jump %d",len); +#endif + *(Bit8u*)data=(Bit8u)( ((Bit32u)cache.pos-(data+4)) >> 1 ); +} + + +// conditional jump if register is nonzero +// for isdword==true the 32bit of the register are tested +// for isdword==false the lowest 8bit of the register are tested +static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { + Bit8u *datapos; + + cache_checkinstr(8); + datapos = cache_reservedata(); + + if (isdword) { + cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + } else { + cache_addw(0x0000 + templo2 + (reg << 3) + (24 << 6)); // lsl templo2, reg, #24 + } + cache_addw(0xd000 + (2 >> 1)); // beq nobranch (pc+2) + if (((Bit32u)cache.pos & 0x03) == 0) { + cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 4)) >> 2)); // ldr templo1, [pc, datapos] + } else { + cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 2)) >> 2)); // ldr templo1, [pc, datapos] + } + cache_addw(0x4700 + (templo1 << 3)); // bx templo1 + // nobranch: + return ((Bit32u)datapos); +} + +// compare 32bit-register against zero and jump if value less/equal than zero +static Bit32u gen_create_branch_long_leqzero(HostReg reg) { + Bit8u *datapos; + + cache_checkinstr(8); + datapos = cache_reservedata(); + + cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + cache_addw(0xdc00 + (2 >> 1)); // bgt nobranch (pc+2) + if (((Bit32u)cache.pos & 0x03) == 0) { + cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 4)) >> 2)); // ldr templo1, [pc, datapos] + } else { + cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 2)) >> 2)); // ldr templo1, [pc, datapos] + } + cache_addw(0x4700 + (templo1 << 3)); // bx templo1 + // nobranch: + return ((Bit32u)datapos); +} + +// calculate long relative offset and fill it into the location pointed to by data +static void INLINE gen_fill_branch_long(Bit32u data) { + // this is an absolute branch + *(Bit32u*)data=((Bit32u)cache.pos) + 1; // add 1 to keep processor in thumb state +} + +static void gen_run_code(void) { + // switch from arm to thumb state + cache_addd(0xe2800000 + (HOST_r3 << 12) + (HOST_pc << 16) + (1)); // add r3, pc, #1 + cache_addd(0xe12fff10 + (HOST_r3)); // bx r3 + + // thumb state from now on + cache_addw(0xb500); // push {lr} + cache_addw(0xb4f0); // push {v1-v4} + + cache_addw(0xa302); // add r3, pc, #8 + cache_addw(0x3001); // add r0, #1 + cache_addw(0x3301); // add r3, #1 + cache_addw(0xb408); // push {r3} + cache_addw(0x4700); // bx r0 + cache_addw(0x46c0); // nop + + cache_addw(0xbcf0); // pop {v1-v4} + + cache_addw(0xbc08); // pop {r3} + cache_addw(0x4718); // bx r3 +} + +// return from a function +static void gen_return_function(void) { + cache_checkinstr(6); + cache_addw(0x1c00 + HOST_a1 + (FC_RETOP << 3)); // mov a1, FC_RETOP + cache_addw(0xbc08); // pop {r3} + cache_addw(0x4718); // bx r3 +} + + +// short unconditional jump (over data pool) +// must emit at most CACHE_DATA_JUMP bytes +static void INLINE gen_create_branch_short(void * func) { + cache_addw(0xe000 + (((Bit32u)func - ((Bit32u)cache.pos + 4)) >> 1) ); // b func +} + + +#ifdef DRC_FLAGS_INVALIDATION + +// called when a call to a function can be replaced by a +// call to a simpler function +static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { + if ((*(Bit16u*)pos & 0xf000) == 0xe000) { + if ((*(Bit16u*)pos & 0x0fff) >= ((CACHE_DATA_ALIGN / 2) - 1) && + (*(Bit16u*)pos & 0x0fff) < 0x0800) + { + pos = (Bit8u *) ( ( ( (Bit32u)(*(Bit16u*)pos & 0x0fff) ) << 1 ) + ((Bit32u)pos + 4) ); + } + } + +#ifdef DRC_FLAGS_INVALIDATION_DCODE + if (((Bit32u)pos & 0x03) == 0) + { + // try to avoid function calls but rather directly fill in code + switch (flags_type) { + case t_ADDb: + case t_ADDw: + case t_ADDd: + *(Bit16u*)pos=0x1800 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // add FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=0xe000 + (12 >> 1); // b after_call (pc+12) + break; + case t_ORb: + case t_ORw: + case t_ORd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4300 + FC_RETOP + (HOST_a2 << 3); // orr FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (10 >> 1); // b after_call (pc+10) + break; + case t_ANDb: + case t_ANDw: + case t_ANDd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4000 + FC_RETOP + (HOST_a2 << 3); // and FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (10 >> 1); // b after_call (pc+10) + break; + case t_SUBb: + case t_SUBw: + case t_SUBd: + *(Bit16u*)pos=0x1a00 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // sub FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=0xe000 + (12 >> 1); // b after_call (pc+12) + break; + case t_XORb: + case t_XORw: + case t_XORd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4040 + FC_RETOP + (HOST_a2 << 3); // eor FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (10 >> 1); // b after_call (pc+10) + break; + case t_CMPb: + case t_CMPw: + case t_CMPd: + case t_TESTb: + case t_TESTw: + case t_TESTd: + *(Bit16u*)pos=0xe000 + (14 >> 1); // b after_call (pc+14) + break; + case t_INCb: + case t_INCw: + case t_INCd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // add FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=0xe000 + (12 >> 1); // b after_call (pc+12) + break; + case t_DECb: + case t_DECw: + case t_DECd: + *(Bit16u*)pos=0x1e00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // sub FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=0xe000 + (12 >> 1); // b after_call (pc+12) + break; + case t_SHLb: + case t_SHLw: + case t_SHLd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4080 + FC_RETOP + (HOST_a2 << 3); // lsl FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (10 >> 1); // b after_call (pc+10) + break; + case t_SHRb: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // lsr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (8 >> 1); // b after_call (pc+8) + break; + case t_SHRw: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // lsr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (8 >> 1); // b after_call (pc+8) + break; + case t_SHRd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (10 >> 1); // b after_call (pc+10) + break; + case t_SARb: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // asr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (8 >> 1); // b after_call (pc+8) + break; + case t_SARw: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // asr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (8 >> 1); // b after_call (pc+8) + break; + case t_SARd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (10 >> 1); // b after_call (pc+10) + break; + case t_RORb: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+4)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP + *(Bit16u*)(pos+6)=0x46c0; // nop + *(Bit16u*)(pos+8)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+10)=0x46c0; // nop + *(Bit16u*)(pos+12)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+14)=0x46c0; // nop + *(Bit16u*)(pos+16)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + break; + case t_RORw: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+4)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+6)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + *(Bit16u*)(pos+8)=0xe000 + (6 >> 1); // b after_call (pc+6) + break; + case t_RORd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (10 >> 1); // b after_call (pc+10) + break; + case t_ROLb: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 + *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 + *(Bit16u*)(pos+8)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP + *(Bit16u*)(pos+10)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+12)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+14)=0x46c0; // nop + *(Bit16u*)(pos+16)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + break; + case t_ROLw: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 + *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 + *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=0x46c0; // nop + *(Bit16u*)(pos+12)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+14)=0x46c0; // nop + *(Bit16u*)(pos+16)=0x46c0; // nop + break; + case t_ROLd: + *(Bit16u*)pos=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 + *(Bit16u*)(pos+2)=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+4)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 + *(Bit16u*)(pos+6)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+8)=0xe000 + (6 >> 1); // b after_call (pc+6) + break; + case t_NEGb: + case t_NEGw: + case t_NEGd: + *(Bit16u*)pos=0x4240 + FC_RETOP + (HOST_a1 << 3); // neg FC_RETOP, a1 + *(Bit16u*)(pos+2)=0xe000 + (12 >> 1); // b after_call (pc+12) + break; + default: + *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 4) ) = (Bit32u)fct_ptr; // simple_func + break; + } + } + else + { + // try to avoid function calls but rather directly fill in code + switch (flags_type) { + case t_ADDb: + case t_ADDw: + case t_ADDd: + *(Bit16u*)pos=0x1800 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // add FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=0xe000 + (14 >> 1); // b after_call (pc+14) + break; + case t_ORb: + case t_ORw: + case t_ORd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4300 + FC_RETOP + (HOST_a2 << 3); // orr FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (12 >> 1); // b after_call (pc+12) + break; + case t_ANDb: + case t_ANDw: + case t_ANDd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4000 + FC_RETOP + (HOST_a2 << 3); // and FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (12 >> 1); // b after_call (pc+12) + break; + case t_SUBb: + case t_SUBw: + case t_SUBd: + *(Bit16u*)pos=0x1a00 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // sub FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=0xe000 + (14 >> 1); // b after_call (pc+14) + break; + case t_XORb: + case t_XORw: + case t_XORd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4040 + FC_RETOP + (HOST_a2 << 3); // eor FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (12 >> 1); // b after_call (pc+12) + break; + case t_CMPb: + case t_CMPw: + case t_CMPd: + case t_TESTb: + case t_TESTw: + case t_TESTd: + *(Bit16u*)pos=0xe000 + (16 >> 1); // b after_call (pc+16) + break; + case t_INCb: + case t_INCw: + case t_INCd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // add FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=0xe000 + (14 >> 1); // b after_call (pc+14) + break; + case t_DECb: + case t_DECw: + case t_DECd: + *(Bit16u*)pos=0x1e00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // sub FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=0xe000 + (14 >> 1); // b after_call (pc+14) + break; + case t_SHLb: + case t_SHLw: + case t_SHLd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4080 + FC_RETOP + (HOST_a2 << 3); // lsl FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (12 >> 1); // b after_call (pc+12) + break; + case t_SHRb: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // lsr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (10 >> 1); // b after_call (pc+10) + break; + case t_SHRw: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // lsr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (10 >> 1); // b after_call (pc+10) + break; + case t_SHRd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (12 >> 1); // b after_call (pc+12) + break; + case t_SARb: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // asr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (10 >> 1); // b after_call (pc+10) + break; + case t_SARw: + *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // asr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=0xe000 + (10 >> 1); // b after_call (pc+10) + break; + case t_SARd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (12 >> 1); // b after_call (pc+12) + break; + case t_RORb: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+4)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP + *(Bit16u*)(pos+6)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + *(Bit16u*)(pos+12)=0xe000 + (4 >> 1); // b after_call (pc+4) + break; + case t_RORw: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+4)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+6)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + *(Bit16u*)(pos+8)=0xe000 + (8 >> 1); // b after_call (pc+8) + break; + case t_RORd: + *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + *(Bit16u*)(pos+4)=0xe000 + (12 >> 1); // b after_call (pc+12) + break; + case t_ROLb: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 + *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 + *(Bit16u*)(pos+8)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP + *(Bit16u*)(pos+10)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+12)=0x46c0; // nop + *(Bit16u*)(pos+14)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+16)=0x46c0; // nop + *(Bit16u*)(pos+18)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + break; + case t_ROLw: + *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 + *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 + *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+12)=0xe000 + (4 >> 1); // b after_call (pc+4) + break; + case t_ROLd: + *(Bit16u*)pos=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 + *(Bit16u*)(pos+2)=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 + *(Bit16u*)(pos+4)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 + *(Bit16u*)(pos+6)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+8)=0xe000 + (8 >> 1); // b after_call (pc+8) + break; + case t_NEGb: + case t_NEGw: + case t_NEGd: + *(Bit16u*)pos=0x4240 + FC_RETOP + (HOST_a1 << 3); // neg FC_RETOP, a1 + *(Bit16u*)(pos+2)=0xe000 + (14 >> 1); // b after_call (pc+14) + break; + default: + *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 2) ) = (Bit32u)fct_ptr; // simple_func + break; + } + + } +#else + if (((Bit32u)pos & 0x03) == 0) + { + *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 4) ) = (Bit32u)fct_ptr; // simple_func + } + else + { + *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 2) ) = (Bit32u)fct_ptr; // simple_func + } +#endif +} +#endif diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb.h b/src/cpu/core_dynrec/risc_armv4le-thumb.h index 1820fa39..4d9222e2 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-thumb.h,v 1.1 2008-08-20 14:13:21 c2woody Exp $ */ +/* $Id: risc_armv4le-thumb.h,v 1.2 2008-09-02 20:44:41 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT */ @@ -932,3 +932,5 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { #endif } #endif + +static void cache_block_before_close(void) { } diff --git a/src/cpu/core_dynrec/risc_armv4le.h b/src/cpu/core_dynrec/risc_armv4le.h index d7e6f6a0..e5437d34 100644 --- a/src/cpu/core_dynrec/risc_armv4le.h +++ b/src/cpu/core_dynrec/risc_armv4le.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le.h,v 1.1 2008-08-20 14:13:21 c2woody Exp $ */ +/* $Id: risc_armv4le.h,v 1.2 2008-09-02 20:44:41 c2woody Exp $ */ /* ARMv4 (little endian) backend (switcher) by M-HT */ @@ -24,6 +24,8 @@ #include "risc_armv4le-common.h" // choose your destiny: -#include "risc_armv4le-s3.h" -//#include "risc_armv4le-o3.h" +#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" diff --git a/src/cpu/core_dynrec/risc_mipsel32.h b/src/cpu/core_dynrec/risc_mipsel32.h index 451081b6..eb0c124c 100644 --- a/src/cpu/core_dynrec/risc_mipsel32.h +++ b/src/cpu/core_dynrec/risc_mipsel32.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_mipsel32.h,v 1.2 2008-08-20 14:13:21 c2woody Exp $ */ +/* $Id: risc_mipsel32.h,v 1.3 2008-09-02 20:44:41 c2woody Exp $ */ /* MIPS32 (little endian) backend by crazyc */ @@ -644,3 +644,5 @@ static void cache_block_closing(Bit8u* block_start,Bitu block_size) { } #endif } + +static void cache_block_before_close(void) { } diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index 59ef05cc..1b34ada5 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_x64.h,v 1.10 2008-08-20 14:13:21 c2woody Exp $ */ +/* $Id: risc_x64.h,v 1.11 2008-09-02 20:44:41 c2woody Exp $ */ // some configuring defines that specify the capabilities of this architecture @@ -675,3 +675,5 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { #endif static void cache_block_closing(Bit8u* block_start,Bitu block_size) { } + +static void cache_block_before_close(void) { } diff --git a/src/cpu/core_dynrec/risc_x86.h b/src/cpu/core_dynrec/risc_x86.h index 5e7992a4..c1247874 100644 --- a/src/cpu/core_dynrec/risc_x86.h +++ b/src/cpu/core_dynrec/risc_x86.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_x86.h,v 1.7 2008-08-20 14:13:21 c2woody Exp $ */ +/* $Id: risc_x86.h,v 1.8 2008-09-02 20:44:41 c2woody Exp $ */ // some configuring defines that specify the capabilities of this architecture @@ -509,3 +509,5 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { #endif static void cache_block_closing(Bit8u* block_start,Bitu block_size) { } + +static void cache_block_before_close(void) { } From a94ef4eddc78de38a8817e2c909bc8bde077a120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 6 Sep 2008 14:47:15 +0000 Subject: [PATCH 3128/4131] move first shell's psp/environment into low dos memory, uses complete MCBs for them (gold aztecs doesn't like it otherwise) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3216 --- include/dos_inc.h | 5 +++-- src/shell/shell.cpp | 20 +++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 9ea928f2..f3c6b833 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.75 2008-08-29 19:27:04 c2woody Exp $ */ +/* $Id: dos_inc.h,v 1.76 2008-09-06 14:47:02 c2woody Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -85,7 +85,8 @@ enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; #define DOS_SDA_SEG 0xb2 // dos swappable area #define DOS_SDA_OFS 0 #define DOS_CDS_SEG 0x108 -#define DOS_MEM_START 0x118 //First Segment that DOS can use +#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 diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 1122e462..d7032b92 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.92 2008-08-11 12:52:36 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.93 2008-09-06 14:47:15 c2woody Exp $ */ #include #include @@ -572,8 +572,8 @@ void SHELL_Init() { PROGRAMS_MakeFile("COMMAND.COM",SHELL_ProgramStart); /* Now call up the shell for the first time */ - Bit16u psp_seg=DOS_GetMemory(16+3)+1; - Bit16u env_seg=DOS_GetMemory(1+(4096/16))+1; + Bit16u psp_seg=DOS_FIRST_SHELL; + Bit16u env_seg=DOS_FIRST_SHELL+19; //DOS_GetMemory(1+(4096/16))+1; Bit16u stack_seg=DOS_GetMemory(2048/16); SegSet16(ss,stack_seg); reg_sp=2046; @@ -586,11 +586,17 @@ void SHELL_Init() { /* Set up int 23 to "int 20" in the psp. Fixes what.exe */ real_writed(0,0x23*4,((Bit32u)psp_seg<<16)); - /* Setup MCB and the environment */ + /* Setup MCBs */ + DOS_MCB pspmcb((Bit16u)(psp_seg-1)); + pspmcb.SetPSPSeg(psp_seg); // MCB of the command shell psp + pspmcb.SetSize(0x10+2); + pspmcb.SetType(0x4d); DOS_MCB envmcb((Bit16u)(env_seg-1)); - envmcb.SetPSPSeg(psp_seg); - envmcb.SetSize(4096/16); + envmcb.SetPSPSeg(psp_seg); // MCB of the command shell environment + envmcb.SetSize(0x28); + envmcb.SetType(0x4d); + /* Setup environment */ PhysPt env_write=PhysMake(env_seg,0); MEM_BlockWrite(env_write,path_string,strlen(path_string)+1); env_write+=strlen(path_string)+1; @@ -626,8 +632,8 @@ void SHELL_Init() { tail.count=strlen(init_line); strcpy(tail.buffer,init_line); MEM_BlockWrite(PhysMake(psp_seg,128),&tail,128); + /* Setup internal DOS Variables */ - dos.dta(RealMake(psp_seg,0x80)); dos.psp(psp_seg); From c994a9a25e1af4ba4270aaf5b8cbb4ce93ac840d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 7 Sep 2008 10:55:16 +0000 Subject: [PATCH 3129/4131] fix some msvc64bit warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3217 --- src/dos/cdrom_aspi_win32.cpp | 8 ++++---- src/dos/cdrom_image.cpp | 12 ++++++------ src/dos/dos.cpp | 8 ++++---- src/dos/dos_classes.cpp | 17 ++++++----------- src/dos/dos_execute.cpp | 6 +++--- src/dos/dos_files.cpp | 12 +++++++----- src/dos/dos_ioctl.cpp | 5 +++-- src/dos/dos_misc.cpp | 30 +++++++++++++++++------------- src/dos/dos_mscdex.cpp | 10 +++++----- src/dos/dos_programs.cpp | 6 +++--- src/dos/drive_iso.cpp | 14 +++++++++----- src/dos/drive_local.cpp | 8 ++++---- src/dos/drives.cpp | 10 ++++++---- src/gui/render_simple.h | 6 ++++-- src/ints/ems.cpp | 6 +++--- src/ints/int10_vesa.cpp | 4 ++-- src/libs/gui_tk/gui_tk.cpp | 8 ++++---- src/libs/gui_tk/gui_tk.h | 26 +++++++++++++++----------- src/misc/programs.cpp | 22 +++++++++++----------- src/misc/setup.cpp | 4 ++-- src/shell/shell.cpp | 18 +++++++++--------- src/shell/shell_cmds.cpp | 11 +++++++---- src/shell/shell_misc.cpp | 22 +++++++++++----------- 23 files changed, 145 insertions(+), 128 deletions(-) diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index 4f389461..47bac693 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_aspi_win32.cpp,v 1.19 2008-08-06 18:32:34 c2woody Exp $ */ +/* $Id: cdrom_aspi_win32.cpp,v 1.20 2008-09-07 10:55:14 c2woody Exp $ */ #if defined (WIN32) @@ -224,9 +224,9 @@ bool CDROM_Interface_Aspi::GetVendor(BYTE HA_num, BYTE SCSI_Id, BYTE SCSI_Lun, c return false; } else { safe_strncpy(szBuffer,szBuffer+8,26); - int len = strlen(szBuffer); - for (int i=0; i #include @@ -65,7 +65,7 @@ bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count) int CDROM_Interface_Image::BinaryFile::getLength() { file->seekg(0, ios::end); - int length = file->tellg(); + int length = (int)file->tellg(); if (file->fail()) return -1; return length; } @@ -170,7 +170,7 @@ bool CDROM_Interface_Image::SetDevice(char* path, int forceCD) // print error message on dosbox console char buf[MAX_LINE_LENGTH]; snprintf(buf, MAX_LINE_LENGTH, "Could not load image file: %s\n", path); - Bit16u size = strlen(buf); + Bit16u size = (Bit16u)strlen(buf); DOS_WriteFile(STDOUT, (Bit8u*)buf, &size); return false; } @@ -185,7 +185,7 @@ bool CDROM_Interface_Image::GetUPC(unsigned char& attr, char* upc) bool CDROM_Interface_Image::GetAudioTracks(int& stTrack, int& end, TMSF& leadOut) { stTrack = 1; - end = tracks.size() - 1; + end = (int)(tracks.size() - 1); FRAMES_TO_MSF(tracks[tracks.size() - 1].start + 150, &leadOut.min, &leadOut.sec, &leadOut.fr); return true; } @@ -639,7 +639,7 @@ bool CDROM_Interface_Image::GetCueFrame(int &frames, istream &in) bool CDROM_Interface_Image::GetCueString(string &str, istream &in) { - int pos = in.tellg(); + int pos = (int)in.tellg(); in >> str; if (str[0] == '\"') { if (str[str.size() - 1] == '\"') { diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 82b5d312..d5260132 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.112 2008-05-28 09:53:31 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.113 2008-09-07 10:55:14 c2woody Exp $ */ #include #include @@ -645,7 +645,7 @@ static Bitu DOS_21Handler(void) { break; case 0x47: /* CWD Get current directory */ if (DOS_GetCurrentDir(reg_dl,name1)) { - MEM_BlockWrite(SegPhys(ds)+reg_si,name1,strlen(name1)+1); + MEM_BlockWrite(SegPhys(ds)+reg_si,name1,(Bitu)(strlen(name1)+1)); reg_ax=0x0100; CALLBACK_SCF(false); } else { @@ -821,7 +821,7 @@ static Bitu DOS_21Handler(void) { MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_CreateTempFile(name1,&handle)) { reg_ax=handle; - MEM_BlockWrite(SegPhys(ds)+reg_dx,name1,strlen(name1)+1); + MEM_BlockWrite(SegPhys(ds)+reg_dx,name1,(Bitu)(strlen(name1)+1)); CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; @@ -870,7 +870,7 @@ static Bitu DOS_21Handler(void) { case 0x60: /* Canonicalize filename or path */ MEM_StrCopy(SegPhys(ds)+reg_si,name1,DOSNAMEBUF); if (DOS_Canonicalize(name1,name2)) { - MEM_BlockWrite(SegPhys(es)+reg_di,name2,strlen(name2)+1); + MEM_BlockWrite(SegPhys(es)+reg_di,name2,(Bitu)(strlen(name2)+1)); CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 81364b6e..85e829e5 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.54 2008-01-21 21:26:49 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.55 2008-09-07 10:55:14 c2woody Exp $ */ #include #include @@ -25,12 +25,6 @@ #include "dos_inc.h" #include "support.h" -/* - Work in progress, making classes for handling certain internal memory structures in dos - This should make it somewhat easier for porting to other endian machines and make - dos work a bit easier. -*/ - void DOS_ParamBlock::Clear(void) { memset(&exec,0,sizeof(exec)); @@ -345,12 +339,13 @@ void DOS_DTA::SetupSearch(Bit8u _sdrive,Bit8u _sattr,char * pattern) { char * find_ext; find_ext=strchr(pattern,'.'); if (find_ext) { - Bitu size=find_ext-pattern;if (size>8) size=8; + Bitu size=(Bitu)(find_ext-pattern); + if (size>8) size=8; MEM_BlockWrite(pt+offsetof(sDTA,sname),pattern,size); find_ext++; - MEM_BlockWrite(pt+offsetof(sDTA,sext),find_ext,(strlen(find_ext)>3) ? 3 : strlen(find_ext)); + MEM_BlockWrite(pt+offsetof(sDTA,sext),find_ext,(strlen(find_ext)>3) ? 3 : (Bitu)strlen(find_ext)); } else { - MEM_BlockWrite(pt+offsetof(sDTA,sname),pattern,(strlen(pattern) > 8) ? 8 : strlen(pattern)); + MEM_BlockWrite(pt+offsetof(sDTA,sname),pattern,(strlen(pattern) > 8) ? 8 : (Bitu)strlen(pattern)); } } diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index ee646230..62f5f455 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.63 2007-11-18 10:30:12 c2woody Exp $ */ +/* $Id: dos_execute.cpp,v 1.64 2008-09-07 10:55:14 c2woody Exp $ */ #include #include @@ -201,7 +201,7 @@ static bool MakeEnv(char * name,Bit16u * segment) { envwrite+=2; char namebuf[DOS_PATHLENGTH]; if (DOS_Canonicalize(name,namebuf)) { - MEM_BlockWrite(envwrite,namebuf,strlen(namebuf)+1); + MEM_BlockWrite(envwrite,namebuf,(Bitu)(strlen(namebuf)+1)); return true; } else return false; } diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index f5651495..9abfb119 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.98 2008-08-06 18:32:34 c2woody Exp $ */ +/* $Id: dos_files.cpp,v 1.99 2008-09-07 10:55:14 c2woody Exp $ */ #include #include @@ -153,7 +153,7 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { } - lastdir=strlen(fullname); + lastdir=(Bit32u)strlen(fullname); if (lastdir!=0) strcat(fullname,"\\"); char * ext=strchr(tempdir,'.'); @@ -814,9 +814,11 @@ static void DTAExtendName(char * const name,char * const filename,char * const e *find=0; } else ext[0]=0; strcpy(filename,name); - Bitu i; - for (i=strlen(name);i<8;i++) filename[i]=' ';filename[8]=0; - for (i=strlen(ext);i<3;i++) ext[i]=' ';ext[3]=0; + size_t i; + for (i=strlen(name);i<8;i++) filename[i]=' '; + filename[8]=0; + for (i=strlen(ext);i<3;i++) ext[i]=' '; + ext[3]=0; } static void SaveFindResult(DOS_FCB & find_fcb) { diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 04c808a9..5b402383 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.32 2008-05-25 17:24:59 c2woody Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.33 2008-09-07 10:55:14 c2woody Exp $ */ #include #include "dosbox.h" @@ -152,7 +152,8 @@ bool DOS_IOCTL(void) { char const* find_ext=strchr(bufin,'.'); if (find_ext) { - Bitu size=find_ext-bufin;if (size>8) size=8; + Bitu size=(Bitu)(find_ext-bufin); + if (size>8) size=8; memcpy(buffer,bufin,size); find_ext++; memcpy(buffer+size,find_ext,(strlen(find_ext)>3) ? 3 : strlen(find_ext)); diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index e695f7f8..f203c720 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_misc.cpp,v 1.19 2008-08-06 18:32:34 c2woody Exp $ */ +/* $Id: dos_misc.cpp,v 1.20 2008-09-07 10:55:14 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" @@ -120,22 +120,26 @@ static bool DOS_MultiplexFunctions(void) { nlen-=(extlen+1); if (nlen>8) nlen=8; - for (Bitu i=0; i3) extlen=3; - for (Bitu i=0; i8) nlen=8; - for (Bitu i=0; i #include @@ -666,10 +666,10 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph upcase(searchName); char* searchPos = searchName; - //strip of tailing . (XCOM APOCALIPSE) - int searchlen = strlen(searchName); - if(searchlen > 1 && strcmp(searchName,"..")) - if(searchName[searchlen-1] =='.') searchName[searchlen-1] = 0; + //strip of tailing . (XCOM APOCALYPSE) + size_t searchlen = strlen(searchName); + if (searchlen > 1 && strcmp(searchName,"..")) + if (searchName[searchlen-1] =='.') searchName[searchlen-1] = 0; //LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Get DirEntry : Find : %s",searchName); // read vtoc diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 5478a55f..2e1d4f44 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.86 2008-08-06 18:32:34 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.87 2008-09-07 10:55:14 c2woody Exp $ */ #include "dosbox.h" #include @@ -678,7 +678,7 @@ public: FILE *tfile = getFSFile("system.rom", &sz1, &sz2, true); if (tfile!=NULL) { fseek(tfile, 0x3000L, SEEK_SET); - Bit32u drd=fread(rombuf, 1, 0xb000, tfile); + Bit32u drd=(Bit32u)fread(rombuf, 1, 0xb000, tfile); if (drd==0xb000) { for(i=0;i<0xb000;i++) phys_writeb(0xf3000+i,rombuf[i]); } @@ -1075,7 +1075,7 @@ public: } // find all file parameters, assuming that all option parameters have been removed - while(cmd->FindCommand(paths.size() + 2, temp_line) && temp_line.size()) { + while(cmd->FindCommand((unsigned int)(paths.size() + 2), temp_line) && temp_line.size()) { struct stat test; if (stat(temp_line.c_str(),&test)) { diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 6d088a16..d7ae555a 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.23 2008-05-24 18:50:39 c2woody Exp $ */ +/* $Id: drive_iso.cpp,v 1.24 2008-09-07 10:55:14 c2woody Exp $ */ #include #include @@ -510,8 +510,10 @@ int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) // remove any file version identifiers as there are some cdroms that don't have them strreplace((char*)de->ident, ';', 0); // if file has no extension remove the trailing dot - int tmp = strlen((char*)de->ident); - if (tmp > 0 && de->ident[tmp - 1] == '.') de->ident[tmp - 1] = 0; + size_t tmp = strlen((char*)de->ident); + if (tmp > 0) { + if (de->ident[tmp - 1] == '.') de->ident[tmp - 1] = 0; + } } const char* dotpos = strchr((char*)de->ident, '.'); if (dotpos!=NULL) { @@ -554,8 +556,10 @@ bool isoDrive :: lookup(isoDirEntry *de, const char *path) if (IS_DIR(de->fileFlags)) { // remove the trailing dot if present - int nameLength = strlen(name); - if (nameLength > 0 && name[nameLength - 1] == '.') name[nameLength - 1] = 0; + size_t nameLength = strlen(name); + if (nameLength > 0) { + if (name[nameLength - 1] == '.') name[nameLength - 1] = 0; + } // look for the current path element int dirIterator = GetDirIterator(de); diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 117de89d..74eae3a7 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.76 2007-11-01 12:15:34 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.77 2008-09-07 10:55:14 c2woody Exp $ */ #include #include @@ -443,7 +443,7 @@ localDrive::localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors bool localFile::Read(Bit8u * data,Bit16u * size) { if (last_action==WRITE) fseek(fhandle,ftell(fhandle),SEEK_SET); last_action=READ; - *size=fread(data,1,*size,fhandle); + *size=(Bit16u)fread(data,1,*size,fhandle); /* Fake harddrive motion. Inspector Gadget with soundblaster compatible */ /* Same for Igor */ /* hardrive motion => unmask irq 2. Only do it when it's masked as unmasking is realitively heavy to emulate */ @@ -460,7 +460,7 @@ bool localFile::Write(Bit8u * data,Bit16u * size) { } else { - *size=fwrite(data,1,*size,fhandle); + *size=(Bit16u)fwrite(data,1,*size,fhandle); return true; } } diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index 7cd1cb93..c33ad5a7 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.cpp,v 1.13 2008-01-21 21:25:17 qbix79 Exp $ */ +/* $Id: drives.cpp,v 1.14 2008-09-07 10:55:14 c2woody Exp $ */ #include "dosbox.h" #include "dos_system.h" @@ -40,7 +40,8 @@ bool WildFileCmp(const char * file, const char * wild) find_ext=strrchr(file,'.'); if (find_ext) { - Bitu size=find_ext-file;if (size>8) size=8; + Bitu size=(Bitu)(find_ext-file); + if (size>8) size=8; memcpy(file_name,file,size); find_ext++; memcpy(file_ext,find_ext,(strlen(find_ext)>3) ? 3 : strlen(find_ext)); @@ -50,7 +51,8 @@ bool WildFileCmp(const char * file, const char * wild) upcase(file_name);upcase(file_ext); find_ext=strrchr(wild,'.'); if (find_ext) { - Bitu size=find_ext-wild;if (size>8) size=8; + Bitu size=(Bitu)(find_ext-wild); + if (size>8) size=8; memcpy(wild_name,wild,size); find_ext++; memcpy(wild_ext,find_ext,(strlen(find_ext)>3) ? 3 : strlen(find_ext)); diff --git a/src/gui/render_simple.h b/src/gui/render_simple.h index 84b50333..94bddd17 100644 --- a/src/gui/render_simple.h +++ b/src/gui/render_simple.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: render_simple.h,v 1.6 2008-09-07 10:55:15 c2woody Exp $ */ + #if defined (SCALERLINEAR) static void conc4d(SCALERNAME,SBPP,DBPP,L)(const void *s) { #else @@ -91,7 +93,7 @@ static void conc4d(SCALERNAME,SBPP,DBPP,R)(const void *s) { } #if defined(SCALERLINEAR) #if (SCALERHEIGHT > 1) - Bitu copyLen = (Bit8u*)line1 - (Bit8u*)WC[0]; + Bitu copyLen = (Bitu)((Bit8u*)line1 - (Bit8u*)WC[0]); BituMove(((Bit8u*)line0)-copyLen+render.scale.outPitch ,WC[0], copyLen ); #endif #if (SCALERHEIGHT > 2) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 06e3a2a9..440eaf77 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.57 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.58 2008-09-07 10:55:15 c2woody Exp $ */ #include #include @@ -437,7 +437,7 @@ static Bit8u EMM_PartialPageMapping(void) { return EMM_RestoreMappingTable(); break; case 0x02: /* Get Partial Page Map Array Size */ - reg_al=2+reg_bx*(2+sizeof(EMM_Mapping)); + reg_al=(Bit8u)(2+reg_bx*(2+sizeof(EMM_Mapping))); break; default: LOG(LOG_MISC,LOG_ERROR)("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al); @@ -1237,7 +1237,7 @@ public: /* Add a little hack so it appears that there is an actual ems device installed */ char const* emsname="EMMXXXX0"; if(!emsnameseg) emsnameseg=DOS_GetMemory(2); //We have 32 bytes - MEM_BlockWrite(PhysMake(emsnameseg,0xa),emsname,strlen(emsname)+1); + MEM_BlockWrite(PhysMake(emsnameseg,0xa),emsname,(Bitu)(strlen(emsname)+1)); /* Copy the callback piece into the beginning, and set the interrupt vector to it*/ char buf[16]; diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 6f90ffd7..d4cca91d 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.36 2008-05-10 17:33:28 c2woody Exp $ */ +/* $Id: int10_vesa.cpp,v 1.37 2008-09-07 10:55:15 c2woody Exp $ */ #include #include @@ -484,7 +484,7 @@ void INT10_SetupVESA(void) { phys_writew(PhysMake(0xc000,int10.rom.used),0xffff); int10.rom.used+=2; int10.rom.oemstring=RealMake(0xc000,int10.rom.used); - Bitu len=strlen(string_oem)+1; + Bitu len=(Bitu)(strlen(string_oem)+1); for (i=0;i text.size()-start) len = text.size()-start; + if (len > text.size()-start) len = (Size)(text.size()-start); len += start; Size wordstart = start; @@ -859,7 +859,7 @@ bool Input::keyDown(const Key &key) start_sel = end_sel = pos; } else { start_sel = 0; - pos = end_sel = text.size(); + pos = end_sel = (Size)text.size(); } break; case 24: @@ -905,7 +905,7 @@ bool Input::keyDown(const Key &key) case Key::End: if (multi) { while (pos < text.size() && f->toSpecial(text[pos]) != Font::LF) pos++; - } else pos = text.size(); + } else pos = (Size)text.size(); break; case Key::Backspace: if (!key.shift && start_sel != end_sel) clearSelection(); diff --git a/src/libs/gui_tk/gui_tk.h b/src/libs/gui_tk/gui_tk.h index fd18a21f..3d5f0e2d 100644 --- a/src/libs/gui_tk/gui_tk.h +++ b/src/libs/gui_tk/gui_tk.h @@ -102,7 +102,7 @@ * along with this program. If not, see */ -/* $Id: gui_tk.h,v 1.4 2008-08-09 19:42:26 qbix79 Exp $ */ +/* $Id: gui_tk.h,v 1.5 2008-09-07 10:55:15 c2woody Exp $ */ #ifndef GUI__TOOLKIT_H #define GUI__TOOLKIT_H @@ -435,7 +435,7 @@ template void NativeString::getString(String &dest, const S } template STR* NativeString::getNative(const String &src) { - Size strlen = src.size(); + Size strlen = (Size)src.size(); STR* dest = new STR[strlen+1]; dest[strlen] = 0; for (; strlen > 0; strlen--) dest[strlen-1] = src[strlen-1]; @@ -447,12 +447,12 @@ template <> class NativeString { protected: friend class String; static void getString(String &dest, const std::string *src) { - Size strlen = src->length(); + Size strlen = (Size)src->length(); dest.resize(strlen); for (Size i = 0; i< strlen; i++) dest[i] = (*src)[i]; } static std::string* getNative(const String &src) { - Size strlen = src.size(); + Size strlen = (Size)src.size(); std::string* dest = new std::string(); for (Size i = 0; i < strlen; i++) dest->append(1,src[i]); src.addNative(new String::NativeObject(dest)); @@ -466,12 +466,12 @@ template <> class NativeString { protected: friend class String; static void getString(String &dest, const std::string &src) { - Size strlen = src.length(); + Size strlen = (Size)src.length(); dest.resize(strlen); for (Size i = 0; i< strlen; i++) dest[i] = src[i]; } static std::string& getNative(const String &src) { - Size strlen = src.size(); + Size strlen = (Size)src.size(); std::string* dest = new std::string(); for (Size i = 0; i < strlen; i++) dest->append(1,src[i]); src.addNative(new String::NativeObject(dest)); @@ -1133,7 +1133,11 @@ protected: /// Draw \p len characters to a drawable at the current position, starting at string position \p start. /** This can be used to provide kerning. */ - virtual void drawString(Drawable *d, const String &s, Size start, Size len) const { if (len > s.size()-start) len = s.size()-start; len += start; while (start < len) drawChar(d,s[start++]); } + virtual void drawString(Drawable *d, const String &s, Size start, Size len) const { + if (len > s.size()-start) len = (Size)(s.size()-start); + len += start; + while (start < len) drawChar(d,s[start++]); + } public: /// Return a font with the given name (case-sensitive). @@ -1173,7 +1177,7 @@ public: /** Can be used to provide kerning. */ virtual int getWidth(const String &s, Size start = 0, Size len = (Size)-1) const { int width = 0; - if (start+len > s.size()) len = s.size()-start; + if (start+len > s.size()) len = (Size)(s.size()-start); while (len--) width += getWidth(s[start++]); return width; } @@ -1506,7 +1510,7 @@ public: String c = getClipboard(); clearSelection(); text.insert(text.begin()+pos,c.begin(),c.end()); - start_sel = end_sel = pos += c.size(); + start_sel = end_sel = pos += (Size)c.size(); } /// get character position corresponding to coordinates @@ -1852,7 +1856,7 @@ public: else if (key.special == Key::Escape) { setVisible(false); return true; } else return true; if (items[selected].size() == 0 && items.size() > 1) return keyDown(key); - if (selected < 0) selected = items.size()-1; + if (selected < 0) selected = (int)(items.size()-1); if (selected >= (int)items.size()) selected = 0; return true; } @@ -1988,7 +1992,7 @@ public: if (selected >= 0 && !menus[selected]->isVisible()) oldselected = -1; if (selected >= 0) menus[selected]->setVisible(false); if (x < 0 || x >= lastx) return true; - for (selected = menus.size()-1; menus[selected]->getX() > x; selected--) {}; + for (selected = (int)(menus.size()-1); menus[selected]->getX() > x; selected--) {}; if (oldselected == selected) selected = -1; else menus[selected]->setVisible(true); return true; diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index ada79052..59d08d88 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.32 2008-07-26 19:06:26 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.33 2008-09-07 10:55:15 c2woody Exp $ */ #include #include @@ -126,12 +126,12 @@ void Program::WriteOut(const char * format,...) { vsnprintf(buf,2047,format,msg); va_end(msg); - Bit16u size = strlen(buf); + Bit16u size = (Bit16u)strlen(buf); DOS_WriteFile(STDOUT,(Bit8u *)buf,&size); } void Program::WriteOut_NoParsing(const char * format) { - Bit16u size = strlen(format); + Bit16u size = (Bit16u)strlen(format); DOS_WriteFile(STDOUT,(Bit8u *)format,&size); } @@ -145,7 +145,7 @@ bool Program::GetEnvStr(const char * entry,std::string & result) { do { MEM_StrCopy(env_read,env_string,1024); if (!env_string[0]) return false; - env_read+=strlen(env_string)+1; + env_read += (PhysPt)(strlen(env_string)+1); char* equal = strchr(env_string,'='); if (!equal) continue; /* replace the = with \0 to get the length */ @@ -167,7 +167,7 @@ bool Program::GetEnvNum(Bitu num,std::string & result) { MEM_StrCopy(env_read,env_string,1024); if (!env_string[0]) break; if (!num) { result=env_string;return true;} - env_read+=strlen(env_string)+1; + env_read += (PhysPt)(strlen(env_string)+1); num--; } while (1); return false; @@ -191,12 +191,12 @@ bool Program::SetEnv(const char * entry,const char * new_string) { do { MEM_StrCopy(env_read,env_string,1024); if (!env_string[0]) break; - env_read+=strlen(env_string)+1; + env_read += (PhysPt)(strlen(env_string)+1); if (!strchr(env_string,'=')) continue; /* Remove corrupt entry? */ if ((strncasecmp(entry,env_string,strlen(entry))==0) && env_string[strlen(entry)]=='=') continue; - MEM_BlockWrite(env_write,env_string,strlen(env_string)+1); - env_write+=strlen(env_string)+1; + MEM_BlockWrite(env_write,env_string,(Bitu)(strlen(env_string)+1)); + env_write += (PhysPt)(strlen(env_string)+1); } while (1); /* TODO Maybe save the program name sometime. not really needed though */ /* Save the new entry */ @@ -205,8 +205,8 @@ bool Program::SetEnv(const char * entry,const char * new_string) { for (std::string::iterator it = bigentry.begin(); it != bigentry.end(); ++it) *it = toupper(*it); sprintf(env_string,"%s=%s",bigentry.c_str(),new_string); // sprintf(env_string,"%s=%s",entry,new_string); //oldcode - MEM_BlockWrite(env_write,env_string,strlen(env_string)+1); - env_write+=strlen(env_string)+1; + MEM_BlockWrite(env_write,env_string,(Bitu)(strlen(env_string)+1)); + env_write += (PhysPt)(strlen(env_string)+1); } /* Clear out the final piece of the environment */ mem_writed(env_write,0); diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index fc9021dc..0347a3c6 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.50 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: setup.cpp,v 1.51 2008-09-07 10:55:15 c2woody Exp $ */ #include "dosbox.h" #include "cross.h" @@ -872,7 +872,7 @@ bool CommandLine::GetStringRemain(std::string & value) { unsigned int CommandLine::GetCount(void) { - return cmds.size(); + return (unsigned int)cmds.size(); } CommandLine::CommandLine(int argc,char const * const argv[]) { diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index d7032b92..744c9952 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.93 2008-09-06 14:47:15 c2woody Exp $ */ +/* $Id: shell.cpp,v 1.94 2008-09-07 10:55:16 c2woody Exp $ */ #include #include @@ -99,7 +99,7 @@ void AutoexecObject::CreateAutoexec(void) { } sprintf((autoexec_data+auto_len),"%s\r\n",(*it).c_str()); } - if(first_shell) VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,strlen(autoexec_data)); + if(first_shell) VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,(Bit32u)strlen(autoexec_data)); } AutoexecObject::~AutoexecObject(){ @@ -430,7 +430,7 @@ public: } } nomount: - VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,strlen(autoexec_data)); + VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,(Bit32u)strlen(autoexec_data)); } }; @@ -598,14 +598,14 @@ void SHELL_Init() { /* Setup environment */ PhysPt env_write=PhysMake(env_seg,0); - MEM_BlockWrite(env_write,path_string,strlen(path_string)+1); - env_write+=strlen(path_string)+1; - MEM_BlockWrite(env_write,comspec_string,strlen(comspec_string)+1); - env_write+=strlen(comspec_string)+1; + MEM_BlockWrite(env_write,path_string,(Bitu)(strlen(path_string)+1)); + env_write += (PhysPt)(strlen(path_string)+1); + MEM_BlockWrite(env_write,comspec_string,(Bitu)(strlen(comspec_string)+1)); + env_write += (PhysPt)(strlen(comspec_string)+1); mem_writeb(env_write++,0); mem_writew(env_write,1); env_write+=2; - MEM_BlockWrite(env_write,full_name,strlen(full_name)+1); + MEM_BlockWrite(env_write,full_name,(Bitu)(strlen(full_name)+1)); DOS_PSP psp(psp_seg); psp.MakeNew(0); @@ -629,7 +629,7 @@ void SHELL_Init() { psp.SetEnvironment(env_seg); /* Set the command line for the shell start up */ CommandTail tail; - tail.count=strlen(init_line); + tail.count=(Bit8u)strlen(init_line); strcpy(tail.buffer,init_line); MEM_BlockWrite(PhysMake(psp_seg,128),&tail,128); diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index eabb056c..6842b258 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.83 2008-08-11 12:54:57 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.84 2008-09-07 10:55:16 c2woody Exp $ */ #include "dosbox.h" #include "shell.h" @@ -413,7 +413,7 @@ void DOS_Shell::CMD_DIR(char * args) { char buffer[CROSS_LEN]; args = trim(args); - Bit32u argLen = strlen(args); + size_t argLen = strlen(args); if (argLen == 0) { strcpy(args,"*.*"); //no arguments. } else { @@ -481,7 +481,10 @@ void DOS_Shell::CMD_DIR(char * args) { if (attr & DOS_ATTR_DIRECTORY) { if (optW) { WriteOut("[%s]",name); - for (Bitu i=14-strlen(name);i>0;i--) WriteOut(" "); + size_t namelen = strlen(name); + if ((namelen>=0) && (namelen<=14)) { + for (Bitu i=14-(Bitu)namelen;i>0;i--) WriteOut(" "); + } } else { WriteOut("%-8s %-3s %-16s %02d-%02d-%04d %2d:%02d\n",name,ext,"

",day,month,year,hour,minute); } @@ -1003,7 +1006,7 @@ void DOS_Shell::CMD_CHOICE(char * args){ } while (!c || !(ptr = strchr(rem,(optS?c:toupper(c))))); c = optS?c:toupper(c); DOS_WriteFile (STDOUT,&c, &n); - dos.return_code = ptr-rem+1; + dos.return_code = (Bit8u)(ptr-rem+1); } void DOS_Shell::CMD_ATTRIB(char *args){ diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index f2dc58b3..224f0956 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.52 2008-03-02 11:13:47 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.53 2008-09-07 10:55:16 c2woody Exp $ */ #include #include @@ -78,7 +78,7 @@ void DOS_Shell::InputCommand(char * line) { line[str_index ++] = c; DOS_WriteFile(STDOUT,&c,&n); } - str_len = str_index = it_history->length(); + str_len = str_index = (Bitu)it_history->length(); size = CMD_MAXLINE - str_index - 2; line[str_len] = 0; } @@ -124,7 +124,7 @@ void DOS_Shell::InputCommand(char * line) { outc(8); outc(' '); outc(8); } strcpy(line, it_history->c_str()); - len = it_history->length(); + len = (Bit16u)it_history->length(); str_len = str_index = len; size = CMD_MAXLINE - str_index - 2; DOS_WriteFile(STDOUT, (Bit8u *)line, &len); @@ -153,7 +153,7 @@ void DOS_Shell::InputCommand(char * line) { outc(8); outc(' '); outc(8); } strcpy(line, it_history->c_str()); - len = it_history->length(); + len = (Bit16u)it_history->length(); str_len = str_index = len; size = CMD_MAXLINE - str_index - 2; DOS_WriteFile(STDOUT, (Bit8u *)line, &len); @@ -224,15 +224,15 @@ void DOS_Shell::InputCommand(char * line) { if (p_completion_start) { p_completion_start ++; - completion_index = str_len - strlen(p_completion_start); + completion_index = (Bit16u)(str_len - strlen(p_completion_start)); } else { p_completion_start = line; completion_index = 0; } char *path; - if ((path = strrchr(line+completion_index,'\\'))) completion_index = path-line+1; - if ((path = strrchr(line+completion_index,'/'))) completion_index = path-line+1; + if ((path = strrchr(line+completion_index,'\\'))) completion_index = (Bit16u)(path-line+1); + if ((path = strrchr(line+completion_index,'/'))) completion_index = (Bit16u)(path-line+1); // build the completion list char mask[DOS_PATHLENGTH]; @@ -295,7 +295,7 @@ void DOS_Shell::InputCommand(char * line) { } strcpy(&line[completion_index], it_completion->c_str()); - len = it_completion->length(); + len = (Bit16u)it_completion->length(); str_len = str_index = completion_index + len; size = CMD_MAXLINE - str_index - 2; DOS_WriteFile(STDOUT, (Bit8u *)it_completion->c_str(), &len); @@ -448,7 +448,7 @@ bool DOS_Shell::Execute(char * name,char * args) { block.Clear(); //Add a filename RealPt file_name=RealMakeSeg(ss,reg_sp+0x20); - MEM_BlockWrite(Real2Phys(file_name),fullname,strlen(fullname)+1); + MEM_BlockWrite(Real2Phys(file_name),fullname,(Bitu)(strlen(fullname)+1)); /* HACK: Store full commandline for mount and imgmount */ full_arguments.assign(line); @@ -458,7 +458,7 @@ bool DOS_Shell::Execute(char * name,char * args) { cmdtail.count = 0; memset(&cmdtail.buffer,0,126); //Else some part of the string is unitialized (valgrind) if (strlen(line)>126) line[126]=0; - cmdtail.count=strlen(line); + cmdtail.count=(Bit8u)strlen(line); memcpy(cmdtail.buffer,line,strlen(line)); cmdtail.buffer[strlen(line)]=0xd; /* Copy command line in stack block too */ From 74b5d82ccf626c5ca0f238f1d4f9345fd55f31fe Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Sep 2008 16:20:04 +0000 Subject: [PATCH 3130/4131] fix numlock/capslock status on focus loss. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3218 --- src/gui/sdl_mapper.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index f654277a..f677d267 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.49 2008-05-26 19:13:42 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.50 2008-09-10 16:20:04 qbix79 Exp $ */ #include #include @@ -2259,7 +2259,8 @@ void MAPPER_UpdateJoysticks(void) { void MAPPER_LosingFocus(void) { for (CEventVector_it evit=events.begin();evit!=events.end();evit++) { - (*evit)->DeActivateAll(); + if(*evit != caps_lock_event && *evit != num_lock_event) + (*evit)->DeActivateAll(); } } From 5f12dea7677bdf088b6075985d9f7585ce946f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 13 Sep 2008 20:04:28 +0000 Subject: [PATCH 3131/4131] reset dma request line on soundblaster reset (thanks to hal), fixes 3d bomber Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3219 --- include/dma.h | 13 +++++++++++-- src/hardware/dma.cpp | 8 ++++++-- src/hardware/sblaster.cpp | 4 +++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/include/dma.h b/include/dma.h index 74080d6d..84cca2b0 100644 --- a/include/dma.h +++ b/include/dma.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dma.h,v 1.17 2007-01-08 19:45:37 qbix79 Exp $ */ +/* $Id: dma.h,v 1.18 2008-09-13 20:04:28 c2woody Exp $ */ #ifndef DOSBOX_DMA_H #define DOSBOX_DMA_H @@ -46,6 +46,7 @@ public: Bit8u trantype; bool masked; bool tcount; + bool request; DMA_CallBack callback; DmaChannel(Bit8u num, bool dma16); @@ -59,6 +60,8 @@ public: void Register_Callback(DMA_CallBack _cb) { callback = _cb; SetMask(masked); + if (callback) Raise_Request(); + else Clear_Request(); } void ReachedTC(void) { tcount=true; @@ -68,6 +71,12 @@ public: 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); }; diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 5a367fd9..ee17c59c 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: dma.cpp,v 1.39 2008-09-13 20:04:28 c2woody Exp $ */ + #include #include "dosbox.h" #include "mem.h" @@ -231,7 +233,8 @@ Bitu DmaController::ReadControllerReg(Bitu reg,Bitu len) { chan=GetChannel(i); if (chan->tcount) ret|=1 << i; chan->tcount=false; - if (chan->callback) ret|=1 << (i+4); +// if (chan->callback) ret|=1 << (i+4); + if (chan->request) ret|=1 << (4+i); } return ret; default: @@ -256,6 +259,7 @@ DmaChannel::DmaChannel(Bit8u num, bool dma16) { increment = true; autoinit = false; tcount = false; + request = false; } Bitu DmaChannel::Read(Bitu want, Bit8u * buffer) { diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index a7aac8cc..5bc3e801 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.69 2008-08-28 17:37:23 c2woody Exp $ */ +/* $Id: sblaster.cpp,v 1.70 2008-09-13 20:04:28 c2woody Exp $ */ #include #include @@ -680,6 +680,7 @@ static void DSP_Reset(void) { sb.dma.autoinit=false; sb.dma.mode=DSP_DMA_NONE; sb.dma.remain_size=0; + if (sb.dma.chan) sb.dma.chan->Clear_Request(); sb.freq=22050; sb.time_constant=45; sb.dac.used=0; @@ -1482,6 +1483,7 @@ public: if (sb.type==SBT_NONE) return; sb.chan=MixerChan.Install(&SBLASTER_CallBack,22050,"SB"); sb.dsp.state=DSP_S_NORMAL; + sb.dma.chan=NULL; for (i=4;i<=0xf;i++) { if (i==8 || i==9) continue; From 298034bec7ad2a1999d97185c76e9d62d71ae1f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 19 Sep 2008 16:48:03 +0000 Subject: [PATCH 3132/4131] ability to cache register/segment register pointer in host register for the recompiler (M-HT, implemented for arm backends) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3220 --- src/cpu/core_dynrec.cpp | 4 +- src/cpu/core_dynrec/Makefile.am | 4 +- src/cpu/core_dynrec/decoder.h | 10 +- src/cpu/core_dynrec/decoder_basic.h | 226 +++++++++++--- src/cpu/core_dynrec/decoder_opcodes.h | 291 ++++++++++--------- src/cpu/core_dynrec/dyn_fpu.h | 4 +- src/cpu/core_dynrec/risc_armv4le-common.h | 11 +- src/cpu/core_dynrec/risc_armv4le-o3.h | 128 +++++++- src/cpu/core_dynrec/risc_armv4le-s3.h | 129 +++++++- src/cpu/core_dynrec/risc_armv4le-thumb-iw.h | 164 ++++++++++- src/cpu/core_dynrec/risc_armv4le-thumb-niw.h | 164 ++++++++++- src/cpu/core_dynrec/risc_armv4le-thumb.h | 158 +++++++++- src/cpu/core_dynrec/risc_mipsel32.h | 104 ++++++- 13 files changed, 1179 insertions(+), 218 deletions(-) diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index 787bc908..14730d6e 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: core_dynrec.cpp,v 1.10 2008-08-20 14:13:21 c2woody Exp $ */ +/* $Id: core_dynrec.cpp,v 1.11 2008-09-19 16:48:02 c2woody Exp $ */ #include "dosbox.h" @@ -92,7 +92,7 @@ // access to a general register -#define DRCD_REG(reg) (&cpu_regs.regs[reg].dword) +#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 diff --git a/src/cpu/core_dynrec/Makefile.am b/src/cpu/core_dynrec/Makefile.am index ca58ca90..05edb3cf 100644 --- a/src/cpu/core_dynrec/Makefile.am +++ b/src/cpu/core_dynrec/Makefile.am @@ -1,4 +1,6 @@ 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-s3.h risc_armv4le-o3.h risc_armv4le-thumb.h \ + risc_armv4le-thumb-iw.h risc_armv4le-thumb-niw.h \ + decoder_macros.h diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h index 76603912..1e32843a 100644 --- a/src/cpu/core_dynrec/decoder.h +++ b/src/cpu/core_dynrec/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * 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" @@ -324,11 +326,7 @@ restart_prefix: case 0x8c:dyn_mov_ev_seg();break; // load effective address - case 0x8d: - dyn_get_modrm(); - dyn_fill_ea(FC_ADDR,false); - gen_mov_word_from_reg(FC_ADDR,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); - break; + 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; diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index d568da4d..541cb70a 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: decoder_basic.h,v 1.12 2008-09-02 20:44:41 c2woody Exp $ */ +/* $Id: decoder_basic.h,v 1.13 2008-09-19 16:48:02 c2woody Exp $ */ /* @@ -352,6 +352,89 @@ static void INLINE dyn_get_modrm(void) { } +#ifdef DRC_USE_SEGS_ADDR + +#define MOV_SEG_VAL_TO_HOST_REG(host_reg, seg_index) gen_mov_seg16_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_SEG_VAL(seg_index)) - (DRC_PTR_SIZE_IM)(&Segs)) + +#define MOV_SEG_PHYS_TO_HOST_REG(host_reg, seg_index) gen_mov_seg32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_SEG_PHYS(seg_index)) - (DRC_PTR_SIZE_IM)(&Segs)) +#define ADD_SEG_PHYS_TO_HOST_REG(host_reg, seg_index) gen_add_seg32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_SEG_PHYS(seg_index)) - (DRC_PTR_SIZE_IM)(&Segs)) + +#else + +#define MOV_SEG_VAL_TO_HOST_REG(host_reg, seg_index) gen_mov_word_to_reg(host_reg,DRCD_SEG_VAL(seg_index),false) + +#define MOV_SEG_PHYS_TO_HOST_REG(host_reg, seg_index) gen_mov_word_to_reg(host_reg,DRCD_SEG_PHYS(seg_index),true) +#define ADD_SEG_PHYS_TO_HOST_REG(host_reg, seg_index) gen_add(host_reg,DRCD_SEG_PHYS(seg_index)) + +#endif + + +#ifdef DRC_USE_REGS_ADDR + +#define MOV_REG_VAL_TO_HOST_REG(host_reg, reg_index) gen_mov_regval32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_VAL(reg_index)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) +#define ADD_REG_VAL_TO_HOST_REG(host_reg, reg_index) gen_add_regval32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_VAL(reg_index)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) + +#define MOV_REG_WORD16_TO_HOST_REG(host_reg, reg_index) gen_mov_regval16_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,false)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) +#define MOV_REG_WORD32_TO_HOST_REG(host_reg, reg_index) gen_mov_regval32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,true)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) +#define MOV_REG_WORD_TO_HOST_REG(host_reg, reg_index, dword) gen_mov_regword_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,dword)) - (DRC_PTR_SIZE_IM)(&cpu_regs), dword) + +#define MOV_REG_WORD16_FROM_HOST_REG(host_reg, reg_index) gen_mov_regval16_from_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,false)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) +#define MOV_REG_WORD32_FROM_HOST_REG(host_reg, reg_index) gen_mov_regval32_from_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,true)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) +#define MOV_REG_WORD_FROM_HOST_REG(host_reg, reg_index, dword) gen_mov_regword_from_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,dword)) - (DRC_PTR_SIZE_IM)(&cpu_regs), dword) + +#define MOV_REG_BYTE_TO_HOST_REG_LOW(host_reg, reg_index, high_byte) gen_mov_regbyte_to_reg_low(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_BYTE(reg_index,high_byte)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) +#define MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(host_reg, reg_index, high_byte) gen_mov_regbyte_to_reg_low_canuseword(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_BYTE(reg_index,high_byte)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) +#define MOV_REG_BYTE_FROM_HOST_REG_LOW(host_reg, reg_index, high_byte) gen_mov_regbyte_from_reg_low(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_BYTE(reg_index,high_byte)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) + +#else + +#define MOV_REG_VAL_TO_HOST_REG(host_reg, reg_index) gen_mov_word_to_reg(host_reg,DRCD_REG_VAL(reg_index),true) +#define ADD_REG_VAL_TO_HOST_REG(host_reg, reg_index) gen_add(host_reg,DRCD_REG_VAL(reg_index)) + +#define MOV_REG_WORD16_TO_HOST_REG(host_reg, reg_index) gen_mov_word_to_reg(host_reg,DRCD_REG_WORD(reg_index,false),false) +#define MOV_REG_WORD32_TO_HOST_REG(host_reg, reg_index) gen_mov_word_to_reg(host_reg,DRCD_REG_WORD(reg_index,true),true) +#define MOV_REG_WORD_TO_HOST_REG(host_reg, reg_index, dword) gen_mov_word_to_reg(host_reg,DRCD_REG_WORD(reg_index,dword),dword) + +#define MOV_REG_WORD16_FROM_HOST_REG(host_reg, reg_index) gen_mov_word_from_reg(host_reg,DRCD_REG_WORD(reg_index,false),false) +#define MOV_REG_WORD32_FROM_HOST_REG(host_reg, reg_index) gen_mov_word_from_reg(host_reg,DRCD_REG_WORD(reg_index,true),true) +#define MOV_REG_WORD_FROM_HOST_REG(host_reg, reg_index, dword) gen_mov_word_from_reg(host_reg,DRCD_REG_WORD(reg_index,dword),dword) + +#define MOV_REG_BYTE_TO_HOST_REG_LOW(host_reg, reg_index, high_byte) gen_mov_byte_to_reg_low(host_reg,DRCD_REG_BYTE(reg_index,high_byte)) +#define MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(host_reg, reg_index, high_byte) gen_mov_byte_to_reg_low_canuseword(host_reg,DRCD_REG_BYTE(reg_index,high_byte)) +#define MOV_REG_BYTE_FROM_HOST_REG_LOW(host_reg, reg_index, high_byte) gen_mov_byte_from_reg_low(host_reg,DRCD_REG_BYTE(reg_index,high_byte)) + +#endif + + +#define DYN_LEA_MEM_MEM(ea_reg, op1, op2, scale, imm) dyn_lea_mem_mem(ea_reg,op1,op2,scale,imm) + +#if defined(DRC_USE_REGS_ADDR) && defined(DRC_USE_SEGS_ADDR) + +#define DYN_LEA_SEG_PHYS_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_segphys_regval(ea_reg,op1_index,op2_index,scale,imm) +#define DYN_LEA_REG_VAL_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_regval_regval(ea_reg,op1_index,op2_index,scale,imm) +#define DYN_LEA_MEM_REG_VAL(ea_reg, op1, op2_index, scale, imm) dyn_lea_mem_regval(ea_reg,op1,op2_index,scale,imm) + +#elif defined(DRC_USE_REGS_ADDR) + +#define DYN_LEA_SEG_PHYS_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_mem_regval(ea_reg,DRCD_SEG_PHYS(op1_index),op2_index,scale,imm) +#define DYN_LEA_REG_VAL_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_regval_regval(ea_reg,op1_index,op2_index,scale,imm) +#define DYN_LEA_MEM_REG_VAL(ea_reg, op1, op2_index, scale, imm) dyn_lea_mem_regval(ea_reg,op1,op2_index,scale,imm) + +#elif defined(DRC_USE_SEGS_ADDR) + +#define DYN_LEA_SEG_PHYS_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_segphys_mem(ea_reg,op1_index,DRCD_REG_VAL(op2_index),scale,imm) +#define DYN_LEA_REG_VAL_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,DRCD_REG_VAL(op1_index),DRCD_REG_VAL(op2_index),scale,imm) +#define DYN_LEA_MEM_REG_VAL(ea_reg, op1, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,op1,DRCD_REG_VAL(op2_index),scale,imm) + +#else + +#define DYN_LEA_SEG_PHYS_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,DRCD_SEG_PHYS(op1_index),DRCD_REG_VAL(op2_index),scale,imm) +#define DYN_LEA_REG_VAL_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,DRCD_REG_VAL(op1_index),DRCD_REG_VAL(op2_index),scale,imm) +#define DYN_LEA_MEM_REG_VAL(ea_reg, op1, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,op1,DRCD_REG_VAL(op2_index),scale,imm) + +#endif + + // adjust CPU_Cycles value static void dyn_reduce_cycles(void) { @@ -689,7 +772,7 @@ static void dyn_write_word(HostReg reg_addr,HostReg reg_val,bool dword) { // effective address calculation helper, op2 has to be present! // loads op1 into ea_reg and adds the scaled op2 and the immediate to it -static void dyn_lea(HostReg ea_reg,void* op1,void* op2,Bitu scale,Bits imm) { +static void dyn_lea_mem_mem(HostReg ea_reg,void* op1,void* op2,Bitu scale,Bits imm) { if (scale || imm) { if (op1!=NULL) { gen_mov_word_to_reg(ea_reg,op1,true); @@ -706,6 +789,79 @@ static void dyn_lea(HostReg ea_reg,void* op1,void* op2,Bitu scale,Bits imm) { } } +#ifdef DRC_USE_REGS_ADDR +// effective address calculation helper +// loads op1 into ea_reg and adds the scaled op2 and the immediate to it +// op1 is cpu_regs[op1_index], op2 is cpu_regs[op2_index] +static void dyn_lea_regval_regval(HostReg ea_reg,Bitu op1_index,Bitu op2_index,Bitu scale,Bits imm) { + if (scale || imm) { + MOV_REG_VAL_TO_HOST_REG(ea_reg,op1_index); + MOV_REG_VAL_TO_HOST_REG(TEMP_REG_DRC,op2_index); + + gen_lea(ea_reg,TEMP_REG_DRC,scale,imm); + } else { + MOV_REG_VAL_TO_HOST_REG(ea_reg,op2_index); + ADD_REG_VAL_TO_HOST_REG(ea_reg,op1_index); + } +} + +// effective address calculation helper +// loads op1 into ea_reg and adds the scaled op2 and the immediate to it +// op2 is cpu_regs[op2_index] +static void dyn_lea_mem_regval(HostReg ea_reg,void* op1,Bitu op2_index,Bitu scale,Bits imm) { + if (scale || imm) { + if (op1!=NULL) { + gen_mov_word_to_reg(ea_reg,op1,true); + MOV_REG_VAL_TO_HOST_REG(TEMP_REG_DRC,op2_index); + + gen_lea(ea_reg,TEMP_REG_DRC,scale,imm); + } else { + MOV_REG_VAL_TO_HOST_REG(ea_reg,op2_index); + gen_lea(ea_reg,scale,imm); + } + } else { + MOV_REG_VAL_TO_HOST_REG(ea_reg,op2_index); + if (op1!=NULL) gen_add(ea_reg,op1); + } +} +#endif + +#ifdef DRC_USE_SEGS_ADDR +#ifdef DRC_USE_REGS_ADDR +// effective address calculation helper +// loads op1 into ea_reg and adds the scaled op2 and the immediate to it +// op1 is Segs[op1_index], op2 is cpu_regs[op2_index] +static void dyn_lea_segphys_regval(HostReg ea_reg,Bitu op1_index,Bitu op2_index,Bitu scale,Bits imm) { + if (scale || imm) { + MOV_SEG_PHYS_TO_HOST_REG(ea_reg,op1_index); + MOV_REG_VAL_TO_HOST_REG(TEMP_REG_DRC,op2_index); + + gen_lea(ea_reg,TEMP_REG_DRC,scale,imm); + } else { + MOV_REG_VAL_TO_HOST_REG(ea_reg,op2_index); + ADD_SEG_PHYS_TO_HOST_REG(ea_reg,op1_index); + } +} + +#else + +// effective address calculation helper, op2 has to be present! +// loads op1 into ea_reg and adds the scaled op2 and the immediate to it +// op1 is Segs[op1_index] +static void dyn_lea_segphys_mem(HostReg ea_reg,Bitu op1_index,void* op2,Bitu scale,Bits imm) { + if (scale || imm) { + MOV_SEG_PHYS_TO_HOST_REG(ea_reg,op1_index); + gen_mov_word_to_reg(TEMP_REG_DRC,op2,true); + + gen_lea(ea_reg,TEMP_REG_DRC,scale,imm); + } else { + gen_mov_word_to_reg(ea_reg,op2,true); + ADD_SEG_PHYS_TO_HOST_REG(ea_reg,op1_index); + } +} +#endif +#endif + // calculate the effective address and store it in ea_reg static void dyn_fill_ea(HostReg ea_reg,bool addseg=true) { Bit8u seg_base=DRC_SEG_DS; @@ -718,25 +874,25 @@ static void dyn_fill_ea(HostReg ea_reg,bool addseg=true) { } switch (decode.modrm.rm) { case 0:// BX+SI - dyn_lea(ea_reg,DRCD_REG(DRC_REG_EBX),DRCD_REG(DRC_REG_ESI),0,imm); + DYN_LEA_REG_VAL_REG_VAL(ea_reg,DRC_REG_EBX,DRC_REG_ESI,0,imm); break; case 1:// BX+DI - dyn_lea(ea_reg,DRCD_REG(DRC_REG_EBX),DRCD_REG(DRC_REG_EDI),0,imm); + DYN_LEA_REG_VAL_REG_VAL(ea_reg,DRC_REG_EBX,DRC_REG_EDI,0,imm); break; case 2:// BP+SI - dyn_lea(ea_reg,DRCD_REG(DRC_REG_EBP),DRCD_REG(DRC_REG_ESI),0,imm); + DYN_LEA_REG_VAL_REG_VAL(ea_reg,DRC_REG_EBP,DRC_REG_ESI,0,imm); seg_base=DRC_SEG_SS; break; case 3:// BP+DI - dyn_lea(ea_reg,DRCD_REG(DRC_REG_EBP),DRCD_REG(DRC_REG_EDI),0,imm); + DYN_LEA_REG_VAL_REG_VAL(ea_reg,DRC_REG_EBP,DRC_REG_EDI,0,imm); seg_base=DRC_SEG_SS; break; case 4:// SI - gen_mov_word_to_reg(ea_reg,DRCD_REG(DRC_REG_ESI),true); + MOV_REG_VAL_TO_HOST_REG(ea_reg,DRC_REG_ESI); if (imm) gen_add_imm(ea_reg,(Bit32u)imm); break; case 5:// DI - gen_mov_word_to_reg(ea_reg,DRCD_REG(DRC_REG_EDI),true); + MOV_REG_VAL_TO_HOST_REG(ea_reg,DRC_REG_EDI); if (imm) gen_add_imm(ea_reg,(Bit32u)imm); break; case 6:// imm/BP @@ -745,13 +901,13 @@ static void dyn_fill_ea(HostReg ea_reg,bool addseg=true) { gen_mov_dword_to_reg_imm(ea_reg,(Bit32u)imm); goto skip_extend_word; } else { - gen_mov_word_to_reg(ea_reg,DRCD_REG(DRC_REG_EBP),true); + MOV_REG_VAL_TO_HOST_REG(ea_reg,DRC_REG_EBP); gen_add_imm(ea_reg,(Bit32u)imm); seg_base=DRC_SEG_SS; } break; case 7: // BX - gen_mov_word_to_reg(ea_reg,DRCD_REG(DRC_REG_EBX),true); + MOV_REG_VAL_TO_HOST_REG(ea_reg,DRC_REG_EBX); if (imm) gen_add_imm(ea_reg,(Bit32u)imm); break; } @@ -760,7 +916,7 @@ static void dyn_fill_ea(HostReg ea_reg,bool addseg=true) { skip_extend_word: if (addseg) { // add the physical segment value if requested - gen_add(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); + ADD_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); } } else { Bits imm=0; @@ -804,14 +960,14 @@ skip_extend_word: if (!scaled_reg_used) { gen_mov_word_to_reg(ea_reg,(void*)val,true); } else { - dyn_lea(ea_reg,NULL,DRCD_REG(scaled_reg),scale,0); + DYN_LEA_MEM_REG_VAL(ea_reg,NULL,scaled_reg,scale,0); gen_add(ea_reg,(void*)val); } } else { if (!scaled_reg_used) { - gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); + MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); } else { - dyn_lea(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),DRCD_REG(scaled_reg),scale,0); + DYN_LEA_SEG_PHYS_REG_VAL(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base),scaled_reg,scale,0); } gen_add(ea_reg,(void*)val); } @@ -824,14 +980,14 @@ skip_extend_word: if (!scaled_reg_used) { gen_mov_dword_to_reg_imm(ea_reg,(Bit32u)imm); } else { - dyn_lea(ea_reg,NULL,DRCD_REG(scaled_reg),scale,imm); + DYN_LEA_MEM_REG_VAL(ea_reg,NULL,scaled_reg,scale,imm); } } else { if (!scaled_reg_used) { - gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); + MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); if (imm) gen_add_imm(ea_reg,(Bit32u)imm); } else { - dyn_lea(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),DRCD_REG(scaled_reg),scale,imm); + DYN_LEA_SEG_PHYS_REG_VAL(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base),scaled_reg,scale,imm); } } @@ -853,19 +1009,19 @@ skip_extend_word: // succeeded, use the pointer to avoid code invalidation if (!addseg) { if (!scaled_reg_used) { - gen_mov_word_to_reg(ea_reg,DRCD_REG(base_reg),true); + MOV_REG_VAL_TO_HOST_REG(ea_reg,base_reg); gen_add(ea_reg,(void*)val); } else { - dyn_lea(ea_reg,DRCD_REG(base_reg),DRCD_REG(scaled_reg),scale,0); + DYN_LEA_REG_VAL_REG_VAL(ea_reg,base_reg,scaled_reg,scale,0); gen_add(ea_reg,(void*)val); } } else { if (!scaled_reg_used) { - gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); + MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); } else { - dyn_lea(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),DRCD_REG(scaled_reg),scale,0); + DYN_LEA_SEG_PHYS_REG_VAL(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base),scaled_reg,scale,0); } - gen_add(ea_reg,DRCD_REG(base_reg)); + ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg); gen_add(ea_reg,(void*)val); } return; @@ -878,19 +1034,19 @@ skip_extend_word: if (!addseg) { if (!scaled_reg_used) { - gen_mov_word_to_reg(ea_reg,DRCD_REG(base_reg),true); + MOV_REG_VAL_TO_HOST_REG(ea_reg,base_reg); gen_add_imm(ea_reg,(Bit32u)imm); } else { - dyn_lea(ea_reg,DRCD_REG(base_reg),DRCD_REG(scaled_reg),scale,imm); + DYN_LEA_REG_VAL_REG_VAL(ea_reg,base_reg,scaled_reg,scale,imm); } } else { if (!scaled_reg_used) { - gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); - gen_add(ea_reg,DRCD_REG(base_reg)); + MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); + ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg); if (imm) gen_add_imm(ea_reg,(Bit32u)imm); } else { - dyn_lea(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),DRCD_REG(scaled_reg),scale,imm); - gen_add(ea_reg,DRCD_REG(base_reg)); + DYN_LEA_SEG_PHYS_REG_VAL(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base),scaled_reg,scale,imm); + ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg); } } @@ -907,7 +1063,7 @@ skip_extend_word: if (!addseg) { gen_mov_dword_to_reg_imm(ea_reg,(Bit32u)imm); } else { - gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); + MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); if (imm) gen_add_imm(ea_reg,(Bit32u)imm); } @@ -930,11 +1086,11 @@ skip_extend_word: if (decode_fetchd_imm(val)) { // succeeded, use the pointer to avoid code invalidation if (!addseg) { - gen_mov_word_to_reg(ea_reg,DRCD_REG(base_reg),true); + MOV_REG_VAL_TO_HOST_REG(ea_reg,base_reg); gen_add(ea_reg,(void*)val); } else { - gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); - gen_add(ea_reg,DRCD_REG(base_reg)); + MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); + ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg); gen_add(ea_reg,(void*)val); } return; @@ -946,11 +1102,11 @@ skip_extend_word: } if (!addseg) { - gen_mov_word_to_reg(ea_reg,DRCD_REG(base_reg),true); + MOV_REG_VAL_TO_HOST_REG(ea_reg,base_reg); if (imm) gen_add_imm(ea_reg,(Bit32u)imm); } else { - gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); - gen_add(ea_reg,DRCD_REG(base_reg)); + MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); + ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg); if (imm) gen_add_imm(ea_reg,(Bit32u)imm); } } diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index 9fbd88c8..030cf30e 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -34,7 +34,7 @@ static void dyn_dop_ebgb(DualOps op) { dyn_fill_ea(FC_ADDR); gen_protect_addr_reg(); dyn_read_byte_canuseword(FC_ADDR,FC_OP1); - gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); dyn_dop_byte_gencall(op); if ((op!=DOP_CMP) && (op!=DOP_TEST)) { @@ -42,10 +42,10 @@ static void dyn_dop_ebgb(DualOps op) { dyn_write_byte(FC_ADDR,FC_RETOP); } } else { - gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); - gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); dyn_dop_byte_gencall(op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } } @@ -53,11 +53,11 @@ static void dyn_dop_ebgb_mov(void) { dyn_get_modrm(); if (decode.modrm.mod<3) { dyn_fill_ea(FC_ADDR); - gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); dyn_write_byte(FC_ADDR,FC_TMP_BA1); } else { - gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); - gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } } @@ -69,7 +69,7 @@ static void dyn_dop_ebib_mov(void) { dyn_write_byte(FC_ADDR,FC_TMP_BA1); } else { gen_mov_byte_to_reg_low_imm(FC_TMP_BA1,decode_fetchb()); - gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } } @@ -79,16 +79,16 @@ static void dyn_dop_ebgb_xchg(void) { dyn_fill_ea(FC_ADDR); gen_protect_addr_reg(); dyn_read_byte(FC_ADDR,FC_TMP_BA1); - gen_mov_byte_to_reg_low(FC_TMP_BA2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA2,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); - gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); gen_restore_addr_reg(); dyn_write_byte(FC_ADDR,FC_TMP_BA2); } else { - gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); - gen_mov_byte_to_reg_low(FC_TMP_BA2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); - gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); - gen_mov_byte_from_reg_low(FC_TMP_BA2,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); + MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA2,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA2,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } } @@ -97,14 +97,14 @@ static void dyn_dop_gbeb(DualOps op) { if (decode.modrm.mod<3) { dyn_fill_ea(FC_ADDR); dyn_read_byte_canuseword(FC_ADDR,FC_OP2); - gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); dyn_dop_byte_gencall(op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); } else { - gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); - gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); dyn_dop_byte_gencall(op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); } } @@ -113,10 +113,10 @@ static void dyn_dop_gbeb_mov(void) { if (decode.modrm.mod<3) { dyn_fill_ea(FC_ADDR); dyn_read_byte(FC_ADDR,FC_TMP_BA1); - gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); } else { - gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); - gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); } } @@ -126,17 +126,17 @@ static void dyn_dop_evgv(DualOps op) { dyn_fill_ea(FC_ADDR); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); gen_protect_addr_reg(); - gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); dyn_dop_word_gencall(op,decode.big_op); if ((op!=DOP_CMP) && (op!=DOP_TEST)) { gen_restore_addr_reg(); dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); } } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); - gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); dyn_dop_word_gencall(op,decode.big_op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op); } } @@ -144,11 +144,11 @@ static void dyn_dop_evgv_mov(void) { dyn_get_modrm(); if (decode.modrm.mod<3) { dyn_fill_ea(FC_ADDR); - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); dyn_write_word(FC_ADDR,FC_OP1,decode.big_op); } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); } } @@ -162,7 +162,7 @@ static void dyn_dop_eviv_mov(void) { } else { if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP1,decode_fetchd()); else gen_mov_word_to_reg_imm(FC_OP1,decode_fetchw()); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); } } @@ -172,26 +172,26 @@ static void dyn_dop_evgv_xchg(void) { dyn_fill_ea(FC_ADDR); gen_protect_addr_reg(); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); - gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); gen_protect_reg(FC_OP1); gen_restore_addr_reg(); dyn_write_word(FC_ADDR,FC_OP2,decode.big_op); gen_restore_reg(FC_OP1); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); - gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); - gen_mov_word_from_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP2,decode.modrm.rm,decode.big_op); } } static void dyn_xchg_ax(Bit8u reg) { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); - gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); - gen_mov_word_from_reg(FC_OP2,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_EAX,decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP2,reg,decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,reg,decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP2,DRC_REG_EAX,decode.big_op); } static void dyn_dop_gvev(DualOps op) { @@ -200,17 +200,17 @@ static void dyn_dop_gvev(DualOps op) { dyn_fill_ea(FC_ADDR); gen_protect_addr_reg(); dyn_read_word(FC_ADDR,FC_OP2,decode.big_op); - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); dyn_dop_word_gencall(op,decode.big_op); if ((op!=DOP_CMP) && (op!=DOP_TEST)) { gen_restore_addr_reg(); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.reg,decode.big_op); } } else { - gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.rm,decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); dyn_dop_word_gencall(op,decode.big_op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.reg,decode.big_op); } } @@ -219,22 +219,22 @@ static void dyn_dop_gvev_mov(void) { if (decode.modrm.mod<3) { dyn_fill_ea(FC_ADDR); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); } } static void dyn_dop_byte_imm(DualOps op,Bit8u reg,Bit8u idx) { - gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(reg,idx)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,reg,idx); gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,decode_fetchb()); dyn_dop_byte_gencall(op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(reg,idx)); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,reg,idx); } static void dyn_dop_byte_imm_mem(DualOps op,Bit8u reg,Bit8u idx) { - gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(reg,idx)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,reg,idx); Bitu val; if (decode_fetchb_imm(val)) { gen_mov_byte_to_reg_low_canuseword(FC_OP2,(void*)val); @@ -242,7 +242,7 @@ static void dyn_dop_byte_imm_mem(DualOps op,Bit8u reg,Bit8u idx) { gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,(Bit8u)val); } dyn_dop_byte_gencall(op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(reg,idx)); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,reg,idx); } static void dyn_prep_word_imm(Bit8u reg) { @@ -263,23 +263,23 @@ static void dyn_prep_word_imm(Bit8u reg) { } static void dyn_dop_word_imm(DualOps op,Bit8u reg) { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,reg,decode.big_op); dyn_prep_word_imm(reg); dyn_dop_word_gencall(op,decode.big_op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,reg,decode.big_op); } static void dyn_dop_word_imm_old(DualOps op,Bit8u reg,Bitu imm) { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,reg,decode.big_op); if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)imm); else gen_mov_word_to_reg_imm(FC_OP2,(Bit16u)imm); dyn_dop_word_gencall(op,decode.big_op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,reg,decode.big_op); } static void dyn_mov_byte_imm(Bit8u reg,Bit8u idx,Bit8u imm) { gen_mov_byte_to_reg_low_imm(FC_TMP_BA1,imm); - gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(reg,idx)); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,reg,idx); } static void dyn_mov_word_imm(Bit8u reg) { @@ -287,45 +287,45 @@ static void dyn_mov_word_imm(Bit8u reg) { if (decode.big_op) { if (decode_fetchd_imm(val)) { gen_mov_word_to_reg(FC_OP1,(void*)val,true); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(reg,true),true); + MOV_REG_WORD32_FROM_HOST_REG(FC_OP1,reg); return; } } else { if (decode_fetchw_imm(val)) { gen_mov_word_to_reg(FC_OP1,(void*)val,false); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(reg,false),false); + MOV_REG_WORD16_FROM_HOST_REG(FC_OP1,reg); return; } } if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP1,(Bit32u)val); else gen_mov_word_to_reg_imm(FC_OP1,(Bit16u)val); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,reg,decode.big_op); } static void dyn_sop_word(SingleOps op,Bit8u reg) { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,reg,decode.big_op); dyn_sop_word_gencall(op,decode.big_op); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,reg,decode.big_op); } static void dyn_mov_byte_al_direct(Bitu imm) { - gen_mov_word_to_reg(FC_ADDR,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS),true); + MOV_SEG_PHYS_TO_HOST_REG(FC_ADDR,(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS)); gen_add_imm(FC_ADDR,imm); dyn_read_byte(FC_ADDR,FC_TMP_BA1); - gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(DRC_REG_EAX,0)); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,DRC_REG_EAX,0); } static void dyn_mov_byte_ax_direct(Bitu imm) { - gen_mov_word_to_reg(FC_ADDR,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS),true); + MOV_SEG_PHYS_TO_HOST_REG(FC_ADDR,(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS)); gen_add_imm(FC_ADDR,imm); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,DRC_REG_EAX,decode.big_op); } static void dyn_mov_byte_direct_al() { - gen_mov_word_to_reg(FC_ADDR,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS),true); + MOV_SEG_PHYS_TO_HOST_REG(FC_ADDR,(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS)); if (decode.big_addr) { Bitu val; if (decode_fetchd_imm(val)) { @@ -336,14 +336,14 @@ static void dyn_mov_byte_direct_al() { } else { gen_add_imm(FC_ADDR,decode_fetchw()); } - gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(DRC_REG_EAX,0)); + MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,DRC_REG_EAX,0); dyn_write_byte(FC_ADDR,FC_TMP_BA1); } static void dyn_mov_byte_direct_ax(Bitu imm) { - gen_mov_word_to_reg(FC_ADDR,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS),true); + MOV_SEG_PHYS_TO_HOST_REG(FC_ADDR,(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS)); gen_add_imm(FC_ADDR,imm); - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_EAX,decode.big_op); dyn_write_word(FC_ADDR,FC_OP1,decode.big_op); } @@ -354,11 +354,11 @@ static void dyn_movx_ev_gb(bool sign) { dyn_fill_ea(FC_ADDR); dyn_read_byte(FC_ADDR,FC_TMP_BA1); gen_extend_byte(sign,FC_TMP_BA1); - gen_mov_word_from_reg(FC_TMP_BA1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_TMP_BA1,decode.modrm.reg,decode.big_op); } else { - gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); gen_extend_byte(sign,FC_TMP_BA1); - gen_mov_word_from_reg(FC_TMP_BA1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_TMP_BA1,decode.modrm.reg,decode.big_op); } } @@ -368,30 +368,37 @@ static void dyn_movx_ev_gw(bool sign) { dyn_fill_ea(FC_ADDR); dyn_read_word(FC_ADDR,FC_OP1,false); gen_extend_word(sign,FC_OP1); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,false),false); + MOV_REG_WORD16_TO_HOST_REG(FC_OP1,decode.modrm.rm); gen_extend_word(sign,FC_OP1); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); } } static void dyn_mov_ev_seg(void) { dyn_get_modrm(); - gen_mov_word_to_reg(FC_OP1,DRCD_SEG_VAL(decode.modrm.reg),false); + MOV_SEG_VAL_TO_HOST_REG(FC_OP1,decode.modrm.reg); if (decode.modrm.mod<3) { dyn_fill_ea(FC_ADDR); dyn_write_word(FC_ADDR,FC_OP1,false); } else { if (decode.big_op) gen_extend_word(false,FC_OP1); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); } } +static void dyn_lea(void) { + dyn_get_modrm(); + dyn_fill_ea(FC_ADDR,false); + MOV_REG_WORD_FROM_HOST_REG(FC_ADDR,decode.modrm.reg,decode.big_op); +} + + static void dyn_push_seg(Bit8u seg) { - gen_mov_word_to_reg(FC_OP1,DRCD_SEG_VAL(seg),false); + MOV_SEG_VAL_TO_HOST_REG(FC_OP1,seg); if (decode.big_op) { gen_extend_word(false,FC_OP1); gen_call_function_raw((void*)&dynrec_push_dword); @@ -406,7 +413,7 @@ static void dyn_pop_seg(Bit8u seg) { } static void dyn_push_reg(Bit8u reg) { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,reg,decode.big_op); if (decode.big_op) gen_call_function_raw((void*)&dynrec_push_dword); else gen_call_function_raw((void*)&dynrec_push_word); } @@ -414,7 +421,7 @@ static void dyn_push_reg(Bit8u reg) { static void dyn_pop_reg(Bit8u reg) { if (decode.big_op) gen_call_function_raw((void*)&dynrec_pop_dword); else gen_call_function_raw((void*)&dynrec_pop_word); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,reg,decode.big_op); } static void dyn_push_byte_imm(Bit8s imm) { @@ -447,7 +454,7 @@ static void dyn_pop_ev(void) { } else { if (decode.big_op) gen_call_function_raw((void*)&dynrec_pop_dword); else gen_call_function_raw((void*)&dynrec_pop_word); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op); } } @@ -465,7 +472,7 @@ static void dyn_segprefix(Bit8u seg) { dyn_fill_ea(FC_ADDR); dyn_read_word(FC_ADDR,FC_RETOP,false); } else { - gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); + MOV_REG_WORD16_TO_HOST_REG(FC_RETOP,decode.modrm.rm); } gen_call_function_IR((void *)&CPU_SetSegGeneral,decode.modrm.reg,FC_RETOP); dyn_check_exception(FC_RETOP); @@ -486,7 +493,7 @@ static void dyn_load_seg_off_ea(Bit8u seg) { dyn_check_exception(FC_RETOP); gen_restore_reg(FC_OP1); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); } else { IllegalOptionDynrec("dyn_load_seg_off_ea"); } @@ -500,12 +507,12 @@ static void dyn_imul_gvev(Bitu immsize) { dyn_fill_ea(FC_ADDR); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); } switch (immsize) { case 0: - gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); break; case 1: if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit8s)decode_fetchb()); @@ -524,7 +531,7 @@ static void dyn_imul_gvev(Bitu immsize) { if (decode.big_op) gen_call_function_raw((void*)dynrec_dimul_dword); else gen_call_function_raw((void*)dynrec_dimul_word); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.reg,decode.big_op); } static void dyn_dshift_ev_gv(bool left,bool immediate) { @@ -534,11 +541,11 @@ static void dyn_dshift_ev_gv(bool left,bool immediate) { gen_protect_addr_reg(); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); } - gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); if (immediate) gen_mov_byte_to_reg_low_imm(FC_RETOP,decode_fetchb()); - else gen_mov_byte_to_reg_low(FC_RETOP,DRCD_REG_BYTE(DRC_REG_ECX,0)); + else MOV_REG_BYTE_TO_HOST_REG_LOW(FC_RETOP,DRC_REG_ECX,0); if (decode.big_op) dyn_dpshift_dword_gencall(left); else dyn_dpshift_word_gencall(left); @@ -546,7 +553,7 @@ static void dyn_dshift_ev_gv(bool left,bool immediate) { gen_restore_addr_reg(); dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); } else { - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op); } } @@ -610,7 +617,7 @@ static void dyn_grp2_eb(grp2_types type) { gen_protect_addr_reg(); dyn_read_byte_canuseword(FC_ADDR,FC_OP1); } else { - gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } switch (type) { case grp2_1: @@ -626,7 +633,7 @@ static void dyn_grp2_eb(grp2_types type) { } break; case grp2_cl: - gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(DRC_REG_ECX,0)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,DRC_REG_ECX,0); gen_and_imm(FC_OP2,0x1f); dyn_shift_byte_gencall((ShiftOps)decode.modrm.reg); break; @@ -635,7 +642,7 @@ static void dyn_grp2_eb(grp2_types type) { gen_restore_addr_reg(); dyn_write_byte(FC_ADDR,FC_RETOP); } else { - gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } } @@ -646,7 +653,7 @@ static void dyn_grp2_ev(grp2_types type) { gen_protect_addr_reg(); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); } switch (type) { case grp2_1: @@ -669,7 +676,7 @@ static void dyn_grp2_ev(grp2_types type) { } break; case grp2_cl: - gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(DRC_REG_ECX,0)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,DRC_REG_ECX,0); gen_and_imm(FC_OP2,0x1f); dyn_shift_word_gencall((ShiftOps)decode.modrm.reg,decode.big_op); break; @@ -678,7 +685,7 @@ static void dyn_grp2_ev(grp2_types type) { gen_restore_addr_reg(); dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); } else { - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op); } } @@ -690,7 +697,7 @@ static void dyn_grp3_eb(void) { if ((decode.modrm.reg==2) || (decode.modrm.reg==3)) gen_protect_addr_reg(); dyn_read_byte_canuseword(FC_ADDR,FC_OP1); } else { - gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } switch (decode.modrm.reg) { case 0x0: // test eb,ib @@ -723,7 +730,7 @@ static void dyn_grp3_eb(void) { gen_restore_addr_reg(); dyn_write_byte(FC_ADDR,FC_RETOP); } else { - gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } } @@ -734,7 +741,7 @@ static void dyn_grp3_ev(void) { if ((decode.modrm.reg==2) || (decode.modrm.reg==3)) gen_protect_addr_reg(); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); } switch (decode.modrm.reg) { case 0x0: // test ev,iv @@ -772,7 +779,7 @@ static void dyn_grp3_ev(void) { gen_restore_addr_reg(); dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); } else { - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op); } } @@ -790,9 +797,9 @@ static bool dyn_grp4_eb(void) { gen_restore_addr_reg(); dyn_write_byte(FC_ADDR,FC_RETOP); } else { - gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); dyn_sop_byte_gencall(decode.modrm.reg==0 ? SOP_INC : SOP_DEC); - gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } break; case 0x7: //CALBACK Iw @@ -816,7 +823,7 @@ static bool dyn_grp4_ev(void) { if ((decode.modrm.reg<2) || (decode.modrm.reg==3) || (decode.modrm.reg==5)) gen_protect_addr_reg(); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); } switch (decode.modrm.reg) { case 0x0://INC Ev @@ -826,7 +833,7 @@ static bool dyn_grp4_ev(void) { gen_restore_addr_reg(); dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); } else { - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op); } break; case 0x2: // CALL Ev @@ -879,7 +886,7 @@ static bool dyn_grp6(void) { dyn_fill_ea(FC_ADDR); dyn_write_word(FC_ADDR,FC_RETOP,false); } else { - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); + MOV_REG_WORD16_FROM_HOST_REG(FC_RETOP,decode.modrm.rm); } break; case 0x02: // LLDT @@ -890,7 +897,7 @@ static bool dyn_grp6(void) { dyn_fill_ea(FC_ADDR); dyn_read_word(FC_ADDR,FC_RETOP,false); } else { - gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); + MOV_REG_WORD16_TO_HOST_REG(FC_RETOP,decode.modrm.rm); } gen_extend_word(false,FC_RETOP); switch (decode.modrm.reg) { @@ -988,10 +995,10 @@ static bool dyn_grp7(void) { switch (decode.modrm.reg) { case 0x04: // SMSW gen_call_function_raw((void*)CPU_SMSW); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); + MOV_REG_WORD16_FROM_HOST_REG(FC_RETOP,decode.modrm.rm); break; case 0x06: // LMSW - gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); + MOV_REG_WORD16_TO_HOST_REG(FC_RETOP,decode.modrm.rm); gen_call_function_R((void*)CPU_LMSW,FC_RETOP); dyn_check_exception(FC_RETOP); dyn_set_eip_end(); @@ -1013,14 +1020,14 @@ static void dyn_larlsl(bool is_lar) { dyn_fill_ea(FC_ADDR); dyn_read_word(FC_ADDR,FC_RETOP,false); } else { - gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); + MOV_REG_WORD16_TO_HOST_REG(FC_RETOP,decode.modrm.rm); } gen_extend_word(false,FC_RETOP); if (is_lar) gen_call_function((void*)CPU_LAR,"%R%A",FC_RETOP,(DRC_PTR_SIZE_IM)&core_dynrec.readdata); else gen_call_function((void*)CPU_LSL,"%R%A",FC_RETOP,(DRC_PTR_SIZE_IM)&core_dynrec.readdata); DRC_PTR_SIZE_IM brnz=gen_create_branch_on_nonzero(FC_RETOP,true); gen_mov_word_to_reg(FC_OP2,&core_dynrec.readdata,true); - gen_mov_word_from_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); gen_fill_branch(brnz); } */ @@ -1031,12 +1038,12 @@ static void dyn_mov_from_crx(void) { gen_call_function_IA((void*)CPU_READ_CRX,decode.modrm.reg,(DRC_PTR_SIZE_IM)&core_dynrec.readdata); dyn_check_exception(FC_RETOP); gen_mov_word_to_reg(FC_OP2,&core_dynrec.readdata,true); - gen_mov_word_from_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.rm,true),true); + MOV_REG_WORD32_FROM_HOST_REG(FC_OP2,decode.modrm.rm); } static void dyn_mov_to_crx(void) { dyn_get_modrm(); - gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,true),true); + MOV_REG_WORD32_TO_HOST_REG(FC_RETOP,decode.modrm.rm); gen_call_function_IR((void*)CPU_WRITE_CRX,decode.modrm.reg,FC_RETOP); dyn_check_exception(FC_RETOP); dyn_set_eip_end(); @@ -1048,29 +1055,29 @@ static void dyn_mov_to_crx(void) { static void dyn_cbw(void) { if (decode.big_op) { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,false),false); + MOV_REG_WORD16_TO_HOST_REG(FC_OP1,DRC_REG_EAX); gen_call_function_raw((void *)&dynrec_cwde); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EAX,true),true); + MOV_REG_WORD32_FROM_HOST_REG(FC_RETOP,DRC_REG_EAX); } else { - gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(DRC_REG_EAX,0)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,DRC_REG_EAX,0); gen_call_function_raw((void *)&dynrec_cbw); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EAX,false),false); + MOV_REG_WORD16_FROM_HOST_REG(FC_RETOP,DRC_REG_EAX); } } static void dyn_cwd(void) { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_EAX,decode.big_op); if (decode.big_op) { gen_call_function_raw((void *)&dynrec_cdq); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EDX,true),true); + MOV_REG_WORD32_FROM_HOST_REG(FC_RETOP,DRC_REG_EDX); } else { gen_call_function_raw((void *)&dynrec_cwd); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EDX,false),false); + MOV_REG_WORD16_FROM_HOST_REG(FC_RETOP,DRC_REG_EDX); } } static void dyn_sahf(void) { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,false),false); + MOV_REG_WORD16_TO_HOST_REG(FC_OP1,DRC_REG_EAX); gen_call_function_raw((void *)&dynrec_sahf); InvalidateFlags(); } @@ -1111,7 +1118,7 @@ static void dyn_set_byte_on_condition(BranchTypes btype) { dyn_fill_ea(FC_ADDR); dyn_write_byte(FC_ADDR,FC_RETOP); } else { - gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } } */ @@ -1136,13 +1143,13 @@ static void dyn_loop(LoopTypes type) { case LOOP_E: case LOOP_NE: case LOOP_NONE: - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr); gen_add_imm(FC_OP1,(Bit32u)(-1)); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr); branch2=gen_create_branch_on_zero(FC_OP1,decode.big_addr); break; case LOOP_JCXZ: - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr); branch2=gen_create_branch_on_nonzero(FC_OP1,decode.big_addr); break; } @@ -1150,9 +1157,9 @@ static void dyn_loop(LoopTypes type) { gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlockDynRec,cache.start)); if (branch1) { gen_fill_branch(branch1); - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr); gen_add_imm(FC_OP1,(Bit32u)(-1)); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr); } // Branch taken gen_fill_branch(branch2); @@ -1242,7 +1249,7 @@ static void dyn_interrupt(Bit8u num) { static void dyn_string(StringOps op) { - if (decode.rep) gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + if (decode.rep) MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr); else gen_mov_dword_to_reg_imm(FC_OP1,1); gen_mov_word_to_reg(FC_OP2,&cpu.direction,true); Bit8u di_base_addr=decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS; @@ -1287,7 +1294,7 @@ static void dyn_string(StringOps op) { break; default: IllegalOptionDynrec("dyn_string"); } - if (decode.rep) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + if (decode.rep) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,DRC_REG_ECX,decode.big_addr); if (op> 2)); // ldr r3, [pc, #(&Segs)] + // adr: 18 + cache_addw(0x4800 + (HOST_r2 << 8) + ((68 - (18 + 2)) >> 2)); // ldr r2, [pc, #(&cpu_regs)] + cache_addw(0x4680 + (FC_SEGS_ADDR - HOST_r8) + (HOST_r3 << 3)); // mov FC_SEGS_ADDR, r3 + cache_addw(0x4680 + (FC_REGS_ADDR - HOST_r8) + (HOST_r2 << 3)); // mov FC_REGS_ADDR, r2 + + // align 4 cache_addw(0xa302); // add r3, pc, #8 cache_addw(0x3001); // add r0, #1 @@ -760,10 +781,24 @@ static void gen_run_code(void) { cache_addw(0x4700); // bx r0 cache_addw(0x46c0); // nop - cache_addw(0xbcf0); // pop {v1-v4} + // align 4 + cache_addw(0xbcfc); // pop {r2,r3,v1-v4} + cache_addw(0x4680 + (FC_SEGS_ADDR - HOST_r8) + (HOST_r3 << 3)); // mov FC_SEGS_ADDR, r3 + cache_addw(0x4680 + (FC_REGS_ADDR - HOST_r8) + (HOST_r2 << 3)); // mov FC_REGS_ADDR, r2 cache_addw(0xbc08); // pop {r3} cache_addw(0x4718); // bx r3 + // fill up to 64 bytes + cache_addw(0x46c0); // nop + cache_addd(0x46c046c0); // nop, nop + cache_addd(0x46c046c0); // nop, nop + cache_addd(0x46c046c0); // nop, nop + cache_addd(0x46c046c0); // nop, nop + + // adr: 64 + cache_addd((Bit32u)&Segs); // address of "Segs" + // adr: 68 + cache_addd((Bit32u)&cpu_regs); // address of "cpu_regs" } // return from a function @@ -1133,3 +1168,122 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { #endif } #endif + +#ifdef DRC_USE_SEGS_ADDR + +// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR + cache_addw(0x8800 + dest_reg + (templo1 << 3) + (index << 5)); // ldrh dest_reg, [templo1, #index] +} + +// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) +static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR + cache_addw(0x6800 + dest_reg + (templo1 << 3) + (index << 4)); // ldr dest_reg, [templo1, #index] +} + +// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) +static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { + cache_checkinstr(6); + cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR + cache_addw(0x6800 + templo2 + (templo1 << 3) + (index << 4)); // ldr templo2, [templo1, #index] + cache_addw(0x1800 + reg + (reg << 3) + (templo2 << 6)); // add reg, reg, templo2 +} + +#endif + +#ifdef DRC_USE_REGS_ADDR + +// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x8800 + dest_reg + (templo2 << 3) + (index << 5)); // ldrh dest_reg, [templo2, #index] +} + +// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x6800 + dest_reg + (templo2 << 3) + (index << 4)); // ldr dest_reg, [templo2, #index] +} + +// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + if (dword) { + cache_addw(0x6800 + dest_reg + (templo2 << 3) + (index << 4)); // ldr dest_reg, [templo2, #index] + } else { + cache_addw(0x8800 + dest_reg + (templo2 << 3) + (index << 5)); // ldrh dest_reg, [templo2, #index] + } +} + +// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x7800 + dest_reg + (templo2 << 3) + (index << 6)); // ldrb dest_reg, [templo2, #index] +} + +// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x7800 + dest_reg + (templo2 << 3) + (index << 6)); // ldrb dest_reg, [templo2, #index] +} + + +// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { + cache_checkinstr(6); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x6800 + templo1 + (templo2 << 3) + (index << 4)); // ldr templo1, [templo2, #index] + cache_addw(0x1800 + reg + (reg << 3) + (templo1 << 6)); // add reg, reg, templo1 +} + + +// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) +static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw(0x8000 + src_reg + (templo1 << 3) + (index << 5)); // strh src_reg, [templo1, #index] +} + +// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw(0x6000 + src_reg + (templo1 << 3) + (index << 4)); // str src_reg, [templo1, #index] +} + +// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) +static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + if (dword) { + cache_addw(0x6000 + src_reg + (templo1 << 3) + (index << 4)); // str src_reg, [templo1, #index] + } else { + cache_addw(0x8000 + src_reg + (templo1 << 3) + (index << 5)); // strh src_reg, [templo1, #index] + } +} + +// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR +static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw(0x7000 + src_reg + (templo1 << 3) + (index << 6)); // strb src_reg, [templo1, #index] +} +#endif diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h index 81a01bce..e994c731 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h @@ -16,10 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-thumb-niw.h,v 1.1 2008-09-02 20:44:41 c2woody Exp $ */ +/* $Id: risc_armv4le-thumb-niw.h,v 1.2 2008-09-19 16:48:02 c2woody Exp $ */ -/* ARMv4 (little endian) backend by M-HT (thumb version) */ +/* ARMv4 (little endian) backend by M-HT (thumb version with data pool) */ // temporary "lo" registers @@ -53,6 +53,16 @@ // temporary register for LEA #define TEMP_REG_DRC HOST_a4 +#ifdef DRC_USE_REGS_ADDR +// used to hold the address of "cpu_regs" - preferably filled in function gen_run_code +#define FC_REGS_ADDR HOST_v7 +#endif + +#ifdef DRC_USE_SEGS_ADDR +// used to hold the address of "Segs" - preferably filled in function gen_run_code +#define FC_SEGS_ADDR HOST_v8 +#endif + // data pool defines #define CACHE_DATA_JUMP (2) @@ -65,7 +75,7 @@ static Bit8u * cache_datapos = NULL; // position of data pool in the cache block static Bit32u cache_datasize = 0; // total size of data pool static Bit32u cache_dataindex = 0; // used size of data pool = index of free data item (in bytes) in data pool - +// forwarded function static void INLINE gen_create_branch_short(void * func); // function to check distance to data pool @@ -753,7 +763,18 @@ static void gen_run_code(void) { // thumb state from now on cache_addw(0xb500); // push {lr} - cache_addw(0xb4f0); // push {v1-v4} + cache_addw(0x4640 + HOST_r3 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov r3, FC_SEGS_ADDR + cache_addw(0x4640 + HOST_r2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov r2, FC_REGS_ADDR + cache_addw(0xb4fc); // push {r2,r3,v1-v4} + + // adr: 16 + cache_addw(0x4800 + (HOST_r3 << 8) + ((64 - (16 + 4)) >> 2)); // ldr r3, [pc, #(&Segs)] + // adr: 18 + cache_addw(0x4800 + (HOST_r2 << 8) + ((68 - (18 + 2)) >> 2)); // ldr r2, [pc, #(&cpu_regs)] + cache_addw(0x4680 + (FC_SEGS_ADDR - HOST_r8) + (HOST_r3 << 3)); // mov FC_SEGS_ADDR, r3 + cache_addw(0x4680 + (FC_REGS_ADDR - HOST_r8) + (HOST_r2 << 3)); // mov FC_REGS_ADDR, r2 + + // align 4 cache_addw(0xa302); // add r3, pc, #8 cache_addw(0x3001); // add r0, #1 @@ -762,10 +783,24 @@ static void gen_run_code(void) { cache_addw(0x4700); // bx r0 cache_addw(0x46c0); // nop - cache_addw(0xbcf0); // pop {v1-v4} + // align 4 + cache_addw(0xbcfc); // pop {r2,r3,v1-v4} + cache_addw(0x4680 + (FC_SEGS_ADDR - HOST_r8) + (HOST_r3 << 3)); // mov FC_SEGS_ADDR, r3 + cache_addw(0x4680 + (FC_REGS_ADDR - HOST_r8) + (HOST_r2 << 3)); // mov FC_REGS_ADDR, r2 cache_addw(0xbc08); // pop {r3} cache_addw(0x4718); // bx r3 + // fill up to 64 bytes + cache_addw(0x46c0); // nop + cache_addd(0x46c046c0); // nop, nop + cache_addd(0x46c046c0); // nop, nop + cache_addd(0x46c046c0); // nop, nop + cache_addd(0x46c046c0); // nop, nop + + // adr: 64 + cache_addd((Bit32u)&Segs); // address of "Segs" + // adr: 68 + cache_addd((Bit32u)&cpu_regs); // address of "cpu_regs" } // return from a function @@ -1130,3 +1165,122 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { #endif } #endif + +#ifdef DRC_USE_SEGS_ADDR + +// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR + cache_addw(0x8800 + dest_reg + (templo1 << 3) + (index << 5)); // ldrh dest_reg, [templo1, #index] +} + +// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) +static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR + cache_addw(0x6800 + dest_reg + (templo1 << 3) + (index << 4)); // ldr dest_reg, [templo1, #index] +} + +// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) +static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { + cache_checkinstr(6); + cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR + cache_addw(0x6800 + templo2 + (templo1 << 3) + (index << 4)); // ldr templo2, [templo1, #index] + cache_addw(0x1800 + reg + (reg << 3) + (templo2 << 6)); // add reg, reg, templo2 +} + +#endif + +#ifdef DRC_USE_REGS_ADDR + +// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x8800 + dest_reg + (templo2 << 3) + (index << 5)); // ldrh dest_reg, [templo2, #index] +} + +// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x6800 + dest_reg + (templo2 << 3) + (index << 4)); // ldr dest_reg, [templo2, #index] +} + +// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + if (dword) { + cache_addw(0x6800 + dest_reg + (templo2 << 3) + (index << 4)); // ldr dest_reg, [templo2, #index] + } else { + cache_addw(0x8800 + dest_reg + (templo2 << 3) + (index << 5)); // ldrh dest_reg, [templo2, #index] + } +} + +// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x7800 + dest_reg + (templo2 << 3) + (index << 6)); // ldrb dest_reg, [templo2, #index] +} + +// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x7800 + dest_reg + (templo2 << 3) + (index << 6)); // ldrb dest_reg, [templo2, #index] +} + + +// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { + cache_checkinstr(6); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x6800 + templo1 + (templo2 << 3) + (index << 4)); // ldr templo1, [templo2, #index] + cache_addw(0x1800 + reg + (reg << 3) + (templo1 << 6)); // add reg, reg, templo1 +} + + +// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) +static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw(0x8000 + src_reg + (templo1 << 3) + (index << 5)); // strh src_reg, [templo1, #index] +} + +// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw(0x6000 + src_reg + (templo1 << 3) + (index << 4)); // str src_reg, [templo1, #index] +} + +// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) +static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + if (dword) { + cache_addw(0x6000 + src_reg + (templo1 << 3) + (index << 4)); // str src_reg, [templo1, #index] + } else { + cache_addw(0x8000 + src_reg + (templo1 << 3) + (index << 5)); // strh src_reg, [templo1, #index] + } +} + +// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR +static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw(0x7000 + src_reg + (templo1 << 3) + (index << 6)); // strb src_reg, [templo1, #index] +} +#endif diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb.h b/src/cpu/core_dynrec/risc_armv4le-thumb.h index 4d9222e2..5501bc0a 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb.h @@ -16,10 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-thumb.h,v 1.2 2008-09-02 20:44:41 c2woody Exp $ */ +/* $Id: risc_armv4le-thumb.h,v 1.3 2008-09-19 16:48:03 c2woody Exp $ */ -/* ARMv4 (little endian) backend by M-HT */ +/* ARMv4 (little endian) backend by M-HT (thumb version) */ // temporary "lo" registers @@ -53,6 +53,16 @@ // temporary register for LEA #define TEMP_REG_DRC HOST_a4 +#ifdef DRC_USE_REGS_ADDR +// used to hold the address of "cpu_regs" - preferably filled in function gen_run_code +#define FC_REGS_ADDR HOST_v7 +#endif + +#ifdef DRC_USE_SEGS_ADDR +// used to hold the address of "Segs" - preferably filled in function gen_run_code +#define FC_SEGS_ADDR HOST_v8 +#endif + // move a full register from reg_src to reg_dst static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { if(reg_src == reg_dst) return; @@ -82,7 +92,6 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { cache_addw(0xa000 + (dest_reg << 8) + (Bit8u)(diff >> 2)); // add dest_reg, pc, #(dist >> 2) } else { cache_addw(0x46c0); // nop - // is the result of (diff-2)>>2 correct for diff<2 ??? cache_addw(0xa000 + (dest_reg << 8) + (Bit8u)((diff - 2) >> 2)); // add dest_reg, pc, #((dist - 2) >> 2) } } else { @@ -488,7 +497,7 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { // short conditional jump (+-127 bytes) if register is zero // the destination is set by gen_fill_branch() later -static Bit32u INLINE gen_create_branch_on_zero(HostReg reg,bool dword) { +static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { if (dword) { cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 } else { @@ -500,7 +509,7 @@ static Bit32u INLINE gen_create_branch_on_zero(HostReg reg,bool dword) { // short conditional jump (+-127 bytes) if register is nonzero // the destination is set by gen_fill_branch() later -static Bit32u INLINE gen_create_branch_on_nonzero(HostReg reg,bool dword) { +static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { if (dword) { cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 } else { @@ -545,7 +554,7 @@ static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { } // compare 32bit-register against zero and jump if value less/equal than zero -static Bit32u INLINE gen_create_branch_long_leqzero(HostReg reg) { +static Bit32u gen_create_branch_long_leqzero(HostReg reg) { cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 if (((Bit32u)cache.pos & 0x03) == 0) { cache_addw(0xdc00 + (8 >> 1)); // bgt nobranch (pc+8) @@ -575,7 +584,18 @@ static void gen_run_code(void) { // thumb state from now on cache_addw(0xb500); // push {lr} - cache_addw(0xb4f0); // push {v1-v4} + cache_addw(0x4640 + HOST_r3 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov r3, FC_SEGS_ADDR + cache_addw(0x4640 + HOST_r2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov r2, FC_REGS_ADDR + cache_addw(0xb4fc); // push {r2,r3,v1-v4} + + // adr: 16 + cache_addw(0x4800 + (HOST_r3 << 8) + ((64 - (16 + 4)) >> 2)); // ldr r3, [pc, #(&Segs)] + // adr: 18 + cache_addw(0x4800 + (HOST_r2 << 8) + ((68 - (18 + 2)) >> 2)); // ldr r2, [pc, #(&cpu_regs)] + cache_addw(0x4680 + (FC_SEGS_ADDR - HOST_r8) + (HOST_r3 << 3)); // mov FC_SEGS_ADDR, r3 + cache_addw(0x4680 + (FC_REGS_ADDR - HOST_r8) + (HOST_r2 << 3)); // mov FC_REGS_ADDR, r2 + + // align 4 cache_addw(0xa302); // add r3, pc, #8 cache_addw(0x3001); // add r0, #1 @@ -584,10 +604,24 @@ static void gen_run_code(void) { cache_addw(0x4700); // bx r0 cache_addw(0x46c0); // nop - cache_addw(0xbcf0); // pop {v1-v4} + // align 4 + cache_addw(0xbcfc); // pop {r2,r3,v1-v4} + cache_addw(0x4680 + (FC_SEGS_ADDR - HOST_r8) + (HOST_r3 << 3)); // mov FC_SEGS_ADDR, r3 + cache_addw(0x4680 + (FC_REGS_ADDR - HOST_r8) + (HOST_r2 << 3)); // mov FC_REGS_ADDR, r2 cache_addw(0xbc08); // pop {r3} cache_addw(0x4718); // bx r3 + // fill up to 64 bytes + cache_addw(0x46c0); // nop + cache_addd(0x46c046c0); // nop, nop + cache_addd(0x46c046c0); // nop, nop + cache_addd(0x46c046c0); // nop, nop + cache_addd(0x46c046c0); // nop, nop + + // adr: 64 + cache_addd((Bit32u)&Segs); // address of "Segs" + // adr: 68 + cache_addd((Bit32u)&cpu_regs); // address of "cpu_regs" } // return from a function @@ -934,3 +968,111 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { #endif static void cache_block_before_close(void) { } + + +#ifdef DRC_USE_SEGS_ADDR + +// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { + cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR + cache_addw(0x8800 + dest_reg + (templo1 << 3) + (index << 5)); // ldrh dest_reg, [templo1, #index] +} + +// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) +static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { + cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR + cache_addw(0x6800 + dest_reg + (templo1 << 3) + (index << 4)); // ldr dest_reg, [templo1, #index] +} + +// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) +static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { + cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR + cache_addw(0x6800 + templo2 + (templo1 << 3) + (index << 4)); // ldr templo2, [templo1, #index] + cache_addw(0x1800 + reg + (reg << 3) + (templo2 << 6)); // add reg, reg, templo2 +} + +#endif + +#ifdef DRC_USE_REGS_ADDR + +// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x8800 + dest_reg + (templo2 << 3) + (index << 5)); // ldrh dest_reg, [templo2, #index] +} + +// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x6800 + dest_reg + (templo2 << 3) + (index << 4)); // ldr dest_reg, [templo2, #index] +} + +// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + if (dword) { + cache_addw(0x6800 + dest_reg + (templo2 << 3) + (index << 4)); // ldr dest_reg, [templo2, #index] + } else { + cache_addw(0x8800 + dest_reg + (templo2 << 3) + (index << 5)); // ldrh dest_reg, [templo2, #index] + } +} + +// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x7800 + dest_reg + (templo2 << 3) + (index << 6)); // ldrb dest_reg, [templo2, #index] +} + +// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x7800 + dest_reg + (templo2 << 3) + (index << 6)); // ldrb dest_reg, [templo2, #index] +} + + +// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x6800 + templo1 + (templo2 << 3) + (index << 4)); // ldr templo1, [templo2, #index] + cache_addw(0x1800 + reg + (reg << 3) + (templo1 << 6)); // add reg, reg, templo1 +} + + +// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) +static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw(0x8000 + src_reg + (templo1 << 3) + (index << 5)); // strh src_reg, [templo1, #index] +} + +// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw(0x6000 + src_reg + (templo1 << 3) + (index << 4)); // str src_reg, [templo1, #index] +} + +// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) +static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + if (dword) { + cache_addw(0x6000 + src_reg + (templo1 << 3) + (index << 4)); // str src_reg, [templo1, #index] + } else { + cache_addw(0x8000 + src_reg + (templo1 << 3) + (index << 5)); // strh src_reg, [templo1, #index] + } +} + +// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR +static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw(0x7000 + src_reg + (templo1 << 3) + (index << 6)); // strb src_reg, [templo1, #index] +} + +#endif diff --git a/src/cpu/core_dynrec/risc_mipsel32.h b/src/cpu/core_dynrec/risc_mipsel32.h index eb0c124c..bcd92653 100644 --- a/src/cpu/core_dynrec/risc_mipsel32.h +++ b/src/cpu/core_dynrec/risc_mipsel32.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_mipsel32.h,v 1.3 2008-09-02 20:44:41 c2woody Exp $ */ +/* $Id: risc_mipsel32.h,v 1.4 2008-09-19 16:48:03 c2woody Exp $ */ /* MIPS32 (little endian) backend by crazyc */ @@ -38,7 +38,12 @@ // calling convention modifier #define DRC_CALL_CONV /* nothing */ -#define DRC_FC /* nothing */ +#define DRC_FC /* nothing */ + +// use FC_REGS_ADDR to hold the address of "cpu_regs" and to access it using FC_REGS_ADDR +//#define DRC_USE_REGS_ADDR +// use FC_SEGS_ADDR to hold the address of "Segs" and to access it using FC_SEGS_ADDR +//#define DRC_USE_SEGS_ADDR // register mapping typedef Bit8u HostReg; @@ -78,6 +83,16 @@ typedef Bit8u HostReg; // temporary register for LEA #define TEMP_REG_DRC HOST_t7 +#ifdef DRC_USE_REGS_ADDR +// used to hold the address of "cpu_regs" - preferably filled in function gen_run_code +#define FC_REGS_ADDR HOST_??? +#endif + +#ifdef DRC_USE_SEGS_ADDR +// used to hold the address of "Segs" - preferably filled in function gen_run_code +#define FC_SEGS_ADDR HOST_??? +#endif + // save some state to improve code gen static bool temp1_valid = false; static Bit32u temp1_value; @@ -646,3 +661,88 @@ static void cache_block_closing(Bit8u* block_start,Bitu block_size) { } static void cache_block_before_close(void) { } + + +#ifdef DRC_USE_SEGS_ADDR + +// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { +// stub +} + +// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) +static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { +// stub +} + +// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) +static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { +// stub +} + +#endif + +#ifdef DRC_USE_REGS_ADDR + +// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { +// stub +} + +// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { +// stub +} + +// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { +// stub +} + +// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { +// stub +} + +// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { +// stub +} + + +// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { +// stub +} + + +// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) +static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { +// stub +} + +// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { +// stub +} + +// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) +static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { +// stub +} + +// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR +static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { +// stub +} + +#endif From 353b1c9011b652c4a567993cfd1894443822e584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 19 Sep 2008 20:18:21 +0000 Subject: [PATCH 3133/4131] keep it compiling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3221 --- src/cpu/core_dynrec/Makefile.am | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cpu/core_dynrec/Makefile.am b/src/cpu/core_dynrec/Makefile.am index 05edb3cf..2bc15bbc 100644 --- a/src/cpu/core_dynrec/Makefile.am +++ b/src/cpu/core_dynrec/Makefile.am @@ -2,5 +2,4 @@ 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 \ - decoder_macros.h + risc_armv4le-thumb-iw.h risc_armv4le-thumb-niw.h From 4214b133a0254332eb3f1b8deb7f1ac00e15af50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 20 Sep 2008 14:51:53 +0000 Subject: [PATCH 3134/4131] fix shell file create attribute setting for output redirection (thanks to skatz for noticing) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3222 --- src/dos/dos_files.cpp | 18 ++++++++-------- src/shell/shell.cpp | 48 +++++++++++++++++++++---------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 9abfb119..9e9c6e19 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.99 2008-09-07 10:55:14 c2woody Exp $ */ +/* $Id: dos_files.cpp,v 1.100 2008-09-20 14:51:52 c2woody Exp $ */ #include #include @@ -421,7 +421,7 @@ bool DOS_CreateFile(char const * name,Bit16u attributes,Bit16u * entry) { // Creation of a device is the same as opening it // Tc201 installer if (DOS_FindDevice(name) != DOS_DEVICES) - return DOS_OpenFile(name, 0, entry); + return DOS_OpenFile(name, OPEN_READ, entry); LOG(LOG_FILES,LOG_NORMAL)("file create attributes %X file %s",attributes,name); char fullname[DOS_PATHLENGTH];Bit8u drive; @@ -446,7 +446,7 @@ bool DOS_CreateFile(char const * name,Bit16u attributes,Bit16u * entry) { return false; } /* Don't allow directories to be created */ - if (attributes&0x10) { + if (attributes&DOS_ATTR_DIRECTORY) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } @@ -529,13 +529,13 @@ bool DOS_OpenFileExtended(char const * name, Bit16u flags, Bit16u createAttr, Bi // FIXME: Not yet supported : Bit 13 of flags (int 0x24 on critical error { Bit16u result = 0; - if (DOS_OpenFile(name, (Bit8u)flags, entry)) { + if (DOS_OpenFile(name, (Bit8u)(flags&0xff), entry)) { // File already exists switch (action & 0x0f) { case 0x00 : return false; // failed case 0x01 : result = 1; break; // file open (already done) case 0x02 : DOS_CloseFile(*entry); // replace - if (!DOS_CreateFile(name, flags, entry)) return false; + if (!DOS_CreateFile(name, createAttr, entry)) return false; result = 3; break; default : E_Exit("DOS: OpenFileExtended: Unknown action."); @@ -544,7 +544,7 @@ bool DOS_OpenFileExtended(char const * name, Bit16u flags, Bit16u createAttr, Bi // File doesnt exist if ((action & 0xf0)==0) return false; // Create File - if (!DOS_CreateFile(name, flags, entry)) return false; + if (!DOS_CreateFile(name, createAttr, entry)) return false; result = 2; }; *status = result; @@ -840,7 +840,7 @@ bool DOS_FCBCreate(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); char shortname[DOS_FCBNAME];Bit16u handle; fcb.GetName(shortname); - if (!DOS_CreateFile(shortname,2,&handle)) return false; + if (!DOS_CreateFile(shortname,DOS_ATTR_ARCHIVE,&handle)) return false; fcb.FileOpen((Bit8u)handle); return true; } @@ -870,7 +870,7 @@ bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { } } - if (!DOS_OpenFile(shortname,2,&handle)) return false; + if (!DOS_OpenFile(shortname,OPEN_READWRITE,&handle)) return false; fcb.FileOpen((Bit8u)handle); return true; } @@ -1017,7 +1017,7 @@ bool DOS_FCBGetFileSize(Bit16u seg,Bit16u offset) { char shortname[DOS_PATHLENGTH];Bit16u entry;Bit8u handle;Bit16u rec_size; DOS_FCB fcb(seg,offset); fcb.GetName(shortname); - if (!DOS_OpenFile(shortname,0,&entry)) return false; + if (!DOS_OpenFile(shortname,OPEN_READ,&entry)) return false; handle = RealHandle(entry); Bit32u size = 0; Files[handle]->Seek(&size,DOS_SEEK_END); diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 744c9952..8a8fb976 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.94 2008-09-07 10:55:16 c2woody Exp $ */ +/* $Id: shell.cpp,v 1.95 2008-09-20 14:51:53 c2woody Exp $ */ #include #include @@ -212,34 +212,34 @@ void DOS_Shell::ParseLine(char * line) { num = GetRedirection(line,&in, &out,&append); if (num>1) LOG_MSG("SHELL:Multiple command on 1 line not supported"); if (in || out) { - normalstdin = (psp->GetFileHandle(0) != 0xff); - normalstdout = (psp->GetFileHandle(1) != 0xff); + normalstdin = (psp->GetFileHandle(0) != 0xff); + normalstdout = (psp->GetFileHandle(1) != 0xff); } if (in) { - if(DOS_OpenFile(in,0,&dummy)) { //Test if file exists + if(DOS_OpenFile(in,OPEN_READ,&dummy)) { //Test if file exists DOS_CloseFile(dummy); LOG_MSG("SHELL:Redirect input from %s",in); - if(normalstdin) DOS_CloseFile(0); //Close stdin - DOS_OpenFile(in,0,&dummy); //Open new stdin + if(normalstdin) DOS_CloseFile(0); //Close stdin + DOS_OpenFile(in,OPEN_READ,&dummy); //Open new stdin } } if (out){ LOG_MSG("SHELL:Redirect output to %s",out); if(normalstdout) DOS_CloseFile(1); - if(!normalstdin && !in) DOS_OpenFile("con",2,&dummy); + if(!normalstdin && !in) DOS_OpenFile("con",OPEN_READWRITE,&dummy); bool status = true; /* Create if not exist. Open if exist. Both in read/write mode */ if(append) { - if( (status = DOS_OpenFile(out,2,&dummy)) ) { + if( (status = DOS_OpenFile(out,OPEN_READWRITE,&dummy)) ) { DOS_SeekFile(1,&bigdummy,DOS_SEEK_END); } else { - status = DOS_CreateFile(out,2,&dummy); //Create if not exists. + status = DOS_CreateFile(out,DOS_ATTR_ARCHIVE,&dummy); //Create if not exists. } + } else { + status = DOS_OpenFileExtended(out,OPEN_READWRITE,DOS_ATTR_ARCHIVE,0x12,&dummy,&dummy2); } - else - status = DOS_OpenFileExtended(out,2,2,0x12,&dummy,&dummy2); - if(!status && normalstdout) DOS_OpenFile("con",2,&dummy); //Read only file, open con again + if(!status && normalstdout) DOS_OpenFile("con",OPEN_READWRITE,&dummy); //Read only file, open con again if(!normalstdin && !in) DOS_CloseFile(0); } /* Run the actual command */ @@ -247,13 +247,13 @@ void DOS_Shell::ParseLine(char * line) { /* Restore handles */ if(in) { DOS_CloseFile(0); - if(normalstdin) DOS_OpenFile("con",2,&dummy); + if(normalstdin) DOS_OpenFile("con",OPEN_READWRITE,&dummy); free(in); } if(out) { DOS_CloseFile(1); - if(!normalstdin) DOS_OpenFile("con",2,&dummy); - if(normalstdout) DOS_OpenFile("con",2,&dummy); + if(!normalstdin) DOS_OpenFile("con",OPEN_READWRITE,&dummy); + if(normalstdout) DOS_OpenFile("con",OPEN_READWRITE,&dummy); if(!normalstdin) DOS_CloseFile(0); free(out); } @@ -321,8 +321,8 @@ void DOS_Shell::Run(void) { WriteOut_NoParsing("\n"); }; }; - ParseLine(input_line); - if (echo) WriteOut("\n"); + ParseLine(input_line); + if (echo) WriteOut("\n"); } } else { if (echo) ShowPrompt(); @@ -616,13 +616,13 @@ void SHELL_Init() { * In order to achieve this: First open 2 files. Close the first and * duplicate the second (so the entries get 01) */ Bit16u dummy=0; - DOS_OpenFile("CON",2,&dummy);/* STDIN */ - DOS_OpenFile("CON",2,&dummy);/* STDOUT */ - DOS_CloseFile(0); /* Close STDIN */ - DOS_ForceDuplicateEntry(1,0);/* "new" STDIN */ - DOS_ForceDuplicateEntry(1,2);/* STDERR */ - DOS_OpenFile("CON",2,&dummy);/* STDAUX */ - DOS_OpenFile("CON",2,&dummy);/* STDPRN */ + DOS_OpenFile("CON",OPEN_READWRITE,&dummy); /* STDIN */ + DOS_OpenFile("CON",OPEN_READWRITE,&dummy); /* STDOUT */ + DOS_CloseFile(0); /* Close STDIN */ + DOS_ForceDuplicateEntry(1,0); /* "new" STDIN */ + DOS_ForceDuplicateEntry(1,2); /* STDERR */ + DOS_OpenFile("CON",OPEN_READWRITE,&dummy); /* STDAUX */ + DOS_OpenFile("CON",OPEN_READWRITE,&dummy); /* STDPRN */ psp.SetParent(psp_seg); /* Set the environment */ From 2468984293b8ae84313a2b7325665cf5dff49643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 21 Sep 2008 19:42:47 +0000 Subject: [PATCH 3135/4131] rework error code handling for special extended-open dos call Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3223 --- src/dos/dos_files.cpp | 59 ++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 9e9c6e19..b3518f39 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.100 2008-09-20 14:51:52 c2woody Exp $ */ +/* $Id: dos_files.cpp,v 1.101 2008-09-21 19:42:47 c2woody Exp $ */ #include #include @@ -525,31 +525,56 @@ bool DOS_OpenFile(char const * name,Bit8u flags,Bit16u * entry) { } } -bool DOS_OpenFileExtended(char const * name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status) -// FIXME: Not yet supported : Bit 13 of flags (int 0x24 on critical error -{ +bool DOS_OpenFileExtended(char const * name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status) { +// FIXME: Not yet supported : Bit 13 of flags (int 0x24 on critical error) Bit16u result = 0; + if (action==0) { + // always fail setting + DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); + return false; + } else { + if (((action & 0x0f)>2) || ((action & 0xf0)>0x10)) { + // invalid action parameter + DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); + return false; + } + } if (DOS_OpenFile(name, (Bit8u)(flags&0xff), entry)) { // File already exists switch (action & 0x0f) { - case 0x00 : return false; // failed - case 0x01 : result = 1; break; // file open (already done) - case 0x02 : DOS_CloseFile(*entry); // replace - if (!DOS_CreateFile(name, createAttr, entry)) return false; - result = 3; - break; - default : E_Exit("DOS: OpenFileExtended: Unknown action."); - }; + case 0x00: // failed + DOS_SetError(DOSERR_FILE_ALREADY_EXISTS); + return false; + case 0x01: // file open (already done) + result = 1; + break; + case 0x02: // replace + DOS_CloseFile(*entry); + if (!DOS_CreateFile(name, createAttr, entry)) return false; + result = 3; + break; + default: + DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); + E_Exit("DOS: OpenFileExtended: Unknown action."); + break; + } } else { - // File doesnt exist - if ((action & 0xf0)==0) return false; + // File doesn't exist + if ((action & 0xf0)==0) { + // uses error code from failed open + return false; + } // Create File - if (!DOS_CreateFile(name, createAttr, entry)) return false; + if (!DOS_CreateFile(name, createAttr, entry)) { + // uses error code from failed create + return false; + } result = 2; - }; + } + // success *status = result; return true; -}; +} bool DOS_UnlinkFile(char const * const name) { char fullname[DOS_PATHLENGTH];Bit8u drive; From bb9fc62ba8d4469e2c4bd11c260086ef8596c357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 23 Sep 2008 17:13:18 +0000 Subject: [PATCH 3136/4131] some warning fixes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3224 --- src/dos/drive_cache.cpp | 43 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 3fe88e2e..c0ee732d 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.53 2008-08-06 18:32:34 c2woody Exp $ */ +/* $Id: drive_cache.cpp,v 1.54 2008-09-23 17:13:18 c2woody Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -254,14 +254,15 @@ void DOS_Drive_Cache::DeleteEntry(const char* path, bool ignoreLastDir) } }; -void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) -{ +void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) { char expand[CROSS_LEN] = { 0 }; CFileInfo* dir; if (ignoreLastDir) { char tmp[CROSS_LEN] = { 0 }; - Bit32s len = strrchr(path,CROSS_FILESPLIT) - path; + Bit32s len=0; + const char* pos = strrchr(path,CROSS_FILESPLIT); + if (pos) len = (Bit32s)(pos - path); if (len>0) { safe_strncpy(tmp,path,len+1); } else { @@ -282,7 +283,7 @@ void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) dir->fileList.clear(); dir->longNameList.clear(); save_dir = 0; -}; +} bool DOS_Drive_Cache::IsCachedIn(CFileInfo* curDir) { @@ -297,7 +298,7 @@ bool DOS_Drive_Cache::GetShortName(const char* fullname, char* shortname) CFileInfo* curDir = FindDirInfo(fullname,expand); Bits low = 0; - Bits high = curDir->longNameList.size()-1; + Bits high = (Bits)(curDir->longNameList.size()-1); Bits mid, res; while (low<=high) { @@ -349,7 +350,7 @@ Bit16u DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name) { Bits foundNr = 0; Bits low = 0; - Bits high = curDir->longNameList.size()-1; + Bits high = (Bits)(curDir->longNameList.size()-1); Bits mid, res; while (low<=high) { @@ -373,7 +374,7 @@ Bit16u DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name) bool DOS_Drive_Cache::RemoveTrailingDot(char* shortname) // remove trailing '.' if no extension is available (Linux compatibility) { - Bitu len = strlen(shortname); + size_t len = strlen(shortname); if (len && (shortname[len-1]=='.')) { if (len==1) return false; if ((len==2) && (shortname[0]=='.')) return false; @@ -389,7 +390,7 @@ Bits DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) RemoveTrailingDot(shortName); // Search long name and return array number of element Bits low = 0; - Bits high = curDir->fileList.size()-1; + Bits high = (Bits)(curDir->fileList.size()-1); Bits mid,res; while (low<=high) { mid = (low+high)/2; @@ -420,7 +421,6 @@ bool DOS_Drive_Cache::RemoveSpaces(char* str) void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) { Bits len = 0; - Bits lenExt = 0; bool createShort = false; char tmpNameBuffer[CROSS_LEN]; @@ -435,19 +435,17 @@ void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) // Get Length of filename char* pos = strchr(tmpName,'.'); if (pos) { - // Get Length of extension - lenExt = strlen(pos)-1; // ignore preceding '.' if extension is longer than "3" - if (lenExt>3) { + if (strlen(pos)>4) { while (*tmpName=='.') tmpName++; createShort = true; - }; + } pos = strchr(tmpName,'.'); - if (pos) len = (Bit16u)(pos - tmpName); - else len = strlen(tmpName); - - } else - len = strlen(tmpName); + if (pos) len = (Bits)(pos - tmpName); + else len = (Bits)strlen(tmpName); + } else { + len = (Bits)strlen(tmpName); + } // Should shortname version be created ? createShort = createShort || (len>8); @@ -463,9 +461,10 @@ void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) info->shortNr = CreateShortNameID(curDir,tmpName); sprintf(buffer,"%d",info->shortNr); // Copy first letters - Bit16u tocopy = 0; - if (len+strlen(buffer)+1>8) tocopy = 8 - strlen(buffer) - 1; - else tocopy = len; + Bits tocopy = 0; + size_t buflen = strlen(buffer); + if (len+buflen+1>8) tocopy = (Bits)(8 - buflen - 1); + else tocopy = len; safe_strncpy(info->shortname,tmpName,tocopy+1); // Copy number strcat(info->shortname,"~"); From 30d2c50b9f73266f08a5b04b543efb46583edca7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 26 Sep 2008 17:21:17 +0000 Subject: [PATCH 3137/4131] Give warning on c:/" as well. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3225 --- src/dos/dos_programs.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 2e1d4f44..7c6963f1 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.87 2008-09-07 10:55:14 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.88 2008-09-26 17:21:17 qbix79 Exp $ */ #include "dosbox.h" #include @@ -288,7 +288,9 @@ public: } else { /* Give a warning when mount c:\ or the / */ #if defined (WIN32) || defined(OS2) - if( (temp_line == "c:\\") || (temp_line == "C:\\")) WriteOut(MSG_Get("PROGRAM_MOUNT_WARNING_WIN")); + if( (temp_line == "c:\\") || (temp_line == "C:\\") || + (temp_line == "c:/") || (temp_line == "C:/") ) + WriteOut(MSG_Get("PROGRAM_MOUNT_WARNING_WIN")); #else if(temp_line == "/") WriteOut(MSG_Get("PROGRAM_MOUNT_WARNING_OTHER")); #endif From e3c5fe0708dfa6f9ff31ec6bff122aa73595f32a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 29 Sep 2008 17:50:18 +0000 Subject: [PATCH 3138/4131] avoid (rare) possibility of a crash when corrupted cdrom images are loaded Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3226 --- src/dos/cdrom_image.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 90dfb8e8..ce2a2689 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.21 2008-09-07 10:55:14 c2woody Exp $ */ +/* $Id: cdrom_image.cpp,v 1.22 2008-09-29 17:50:18 c2woody Exp $ */ #include #include @@ -200,8 +200,9 @@ bool CDROM_Interface_Image::GetAudioTrackInfo(int track, TMSF& start, unsigned c bool CDROM_Interface_Image::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) { - track = GetTrack(player.currFrame); - if (track < 1) return false; + int cur_track = GetTrack(player.currFrame); + if (cur_track < 1) return false; + track = (unsigned char)cur_track; attr = tracks[track - 1].attr; index = 1; FRAMES_TO_MSF(player.currFrame + 150, &absPos.min, &absPos.sec, &absPos.fr); From 2314183f15d5b18636fbc7fa57b59b3f9f18cf03 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 5 Oct 2008 14:44:52 +0000 Subject: [PATCH 3139/4131] Some warnings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3227 --- src/dos/cdrom_image.cpp | 4 +-- src/dos/dev_con.h | 4 +-- src/dos/dos_execute.cpp | 6 ++-- src/dos/dos_files.cpp | 17 +++++----- src/dos/dos_memory.cpp | 2 +- src/dos/dos_misc.cpp | 9 +++--- src/dos/drive_local.cpp | 65 ++++++++++++++++---------------------- src/dos/drive_virtual.cpp | 8 ++--- src/hardware/joystick.cpp | 18 ++++------- src/hardware/mixer.cpp | 4 +-- src/hardware/vga_attr.cpp | 4 +-- src/ints/ems.cpp | 12 +++---- src/ints/int10.cpp | 6 ++-- src/ints/int10_vptable.cpp | 4 ++- src/ints/xms.cpp | 28 ++++++++-------- src/misc/programs.cpp | 6 ++-- 16 files changed, 93 insertions(+), 104 deletions(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index ce2a2689..3b5983d7 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.22 2008-09-29 17:50:18 c2woody Exp $ */ +/* $Id: cdrom_image.cpp,v 1.23 2008-10-05 14:44:52 qbix79 Exp $ */ #include #include @@ -131,7 +131,7 @@ int CDROM_Interface_Image::AudioFile::getLength() int CDROM_Interface_Image::refCount = 0; CDROM_Interface_Image* CDROM_Interface_Image::images[26]; CDROM_Interface_Image::imagePlayer CDROM_Interface_Image::player = { - NULL, NULL, NULL, 0, 0, 0, 0, 0, false, false }; + NULL, NULL, NULL, {0}, 0, 0, 0, false, false }; CDROM_Interface_Image::CDROM_Interface_Image(Bit8u subUnit) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 3b55ac67..89cd8795 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.33 2007-09-20 16:42:43 c2woody Exp $ */ +/* $Id: dev_con.h,v 1.34 2008-10-05 14:44:52 qbix79 Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" @@ -392,7 +392,7 @@ Bit16u device_CON::GetInformation(void) { if (head>=end) head=start; mem_writew(BIOS_KEYBOARD_BUFFER_HEAD,head); return 0x80D3; /* No Key Available */ -}; +} device_CON::device_CON() { SetName("CON"); diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 62f5f455..021aceec 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.64 2008-09-07 10:55:14 c2woody Exp $ */ +/* $Id: dos_execute.cpp,v 1.65 2008-10-05 14:44:52 qbix79 Exp $ */ #include #include @@ -215,7 +215,7 @@ bool DOS_NewPSP(Bit16u segment, Bit16u size) { // copy command line as well (Kings Quest AGI -cga switch) psp.SetCommandTail(RealMake(parent_psp_seg,0x80)); return true; -}; +} bool DOS_ChildPSP(Bit16u segment, Bit16u size) { DOS_PSP psp(segment); @@ -225,7 +225,7 @@ bool DOS_ChildPSP(Bit16u segment, Bit16u size) { psp.SetEnvironment(psp_parent.GetEnvironment()); psp.SetSize(size); return true; -}; +} static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { /* Fix the PSP for psp and environment MCB's */ diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index b3518f39..f8e52a32 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.101 2008-09-21 19:42:47 c2woody Exp $ */ +/* $Id: dos_files.cpp,v 1.102 2008-10-05 14:44:52 qbix79 Exp $ */ #include #include @@ -329,7 +329,7 @@ bool DOS_ReadFile(Bit16u entry,Bit8u * data,Bit16u * amount) { bool ret=Files[handle]->Read(data,&toread); *amount=toread; return ret; -}; +} bool DOS_WriteFile(Bit16u entry,Bit8u * data,Bit16u * amount) { Bit32u handle=RealHandle(entry); @@ -352,7 +352,7 @@ bool DOS_WriteFile(Bit16u entry,Bit8u * data,Bit16u * amount) { bool ret=Files[handle]->Write(data,&towrite); *amount=towrite; return ret; -}; +} bool DOS_SeekFile(Bit16u entry,Bit32u * pos,Bit32u type) { Bit32u handle=RealHandle(entry); @@ -365,7 +365,7 @@ bool DOS_SeekFile(Bit16u entry,Bit32u * pos,Bit32u type) { return false; }; return Files[handle]->Seek(pos,type); -}; +} bool DOS_CloseFile(Bit16u entry) { Bit32u handle=RealHandle(entry); @@ -388,6 +388,7 @@ bool DOS_CloseFile(Bit16u entry) { } return true; } + bool DOS_FlushFile(Bit16u entry) { Bit32u handle=RealHandle(entry); if (handle>=DOS_FILES) { @@ -660,7 +661,7 @@ bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry) { Files[handle]->AddRef(); psp.SetFileHandle(*newentry,handle); return true; -}; +} bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry) { if(entry == newentry) { @@ -684,7 +685,7 @@ bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry) { Files[orig]->AddRef(); psp.SetFileHandle(newentry,orig); return true; -}; +} @@ -1116,7 +1117,7 @@ bool DOS_SetDrive(Bit8u drive) { } else { return false; } -}; +} bool DOS_GetFileDate(Bit16u entry, Bit16u* otime, Bit16u* odate) { Bit32u handle=RealHandle(entry); @@ -1135,7 +1136,7 @@ bool DOS_GetFileDate(Bit16u entry, Bit16u* otime, Bit16u* odate) { *otime = Files[handle]->time; *odate = Files[handle]->date; return true; -}; +} void DOS_SetupFiles (void) { /* Setup the File Handles */ diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 9785e879..3f337dba 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -386,7 +386,7 @@ bool DOS_LinkUMBsToMemChain(Bit16u linkstate) { static Bitu DOS_default_handler(void) { LOG(LOG_CPU,LOG_ERROR)("DOS rerouted Interrupt Called %X",lastint); return CBRET_NONE; -}; +} static CALLBACK_HandlerObject callbackhandler; void DOS_SetupMemory(void) { diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index f203c720..6d4079b7 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_misc.cpp,v 1.20 2008-09-07 10:55:14 c2woody Exp $ */ +/* $Id: dos_misc.cpp,v 1.21 2008-10-05 14:44:52 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" @@ -50,13 +50,12 @@ static Bitu INT2F_Handler(void) { LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Multiplex Unhandled call %4X",reg_ax); return CBRET_NONE; -}; +} static Bitu INT2A_Handler(void) { - return CBRET_NONE; -}; +} static bool DOS_MultiplexFunctions(void) { switch (reg_ax) { @@ -214,4 +213,4 @@ void DOS_SetupMisc(void) { call_int2a=CALLBACK_Allocate(); CALLBACK_Setup(call_int2a,&INT2A_Handler,CB_IRET,"DOS Int 2a"); RealSetVec(0x2A,CALLBACK_RealPointer(call_int2a)); -}; +} diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 74eae3a7..91bd08b5 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.77 2008-09-07 10:55:14 c2woody Exp $ */ +/* $Id: drive_local.cpp,v 1.78 2008-10-05 14:44:52 qbix79 Exp $ */ #include #include @@ -76,7 +76,7 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) { *file=new localFile(name,hand); return true; -}; +} bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { const char* type; @@ -113,7 +113,7 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { (*file)->flags=flags; //for the inheritance flag and maybe check for others. // (*file)->SetFileName(newname); return true; -}; +} FILE * localDrive::GetSystemFilePtr(char const * const name, char const * const type) { @@ -304,7 +304,7 @@ bool localDrive::GetFileAttr(char * name,Bit16u * attr) { } *attr=0; return false; -}; +} bool localDrive::MakeDir(char * dir) { char newdir[CROSS_LEN]; @@ -364,7 +364,7 @@ bool localDrive::Rename(char * oldname,char * newname) { if (temp==0) dirCache.CacheOut(newnew); return (temp==0); -}; +} bool localDrive::AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters) { /* Always report 100 mb free should be enough */ @@ -374,7 +374,7 @@ bool localDrive::AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster, *_total_clusters=allocation.total_clusters; *_free_clusters=allocation.free_clusters; return true; -}; +} bool localDrive::FileExists(const char* name) { char newname[CROSS_LEN]; @@ -450,7 +450,7 @@ bool localFile::Read(Bit8u * data,Bit16u * size) { Bit8u mask = IO_Read(0x21); if(mask & 0x4 ) IO_Write(0x21,mask&0xfb); return true; -}; +} bool localFile::Write(Bit8u * data,Bit16u * size) { if (last_action==READ) fseek(fhandle,ftell(fhandle),SEEK_SET); @@ -464,6 +464,7 @@ bool localFile::Write(Bit8u * data,Bit16u * size) { return true; } } + bool localFile::Seek(Bit32u * pos,Bit32u type) { int seektype; switch (type) { @@ -556,8 +557,7 @@ bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name); cdromDrive::cdromDrive(const char driveLetter, const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid, int& error) - :localDrive(startdir,_bytes_sector,_sectors_cluster,_total_clusters,_free_clusters,_mediaid) -{ + :localDrive(startdir,_bytes_sector,_sectors_cluster,_total_clusters,_free_clusters,_mediaid) { // Init mscdex error = MSCDEX_AddDrive(driveLetter,startdir,subUnit); strcpy(info, "CDRom "); @@ -566,10 +566,9 @@ cdromDrive::cdromDrive(const char driveLetter, const char * startdir,Bit16u _byt // Get Volume Label char name[32]; if (MSCDEX_GetVolumeName(subUnit,name)) dirCache.SetLabel(name,true,true); -}; +} -bool cdromDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) -{ +bool cdromDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { if ((flags&3)==OPEN_READWRITE) { flags &= ~OPEN_READWRITE; } else if ((flags&3)==OPEN_WRITE) { @@ -579,47 +578,40 @@ bool cdromDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) bool retcode = localDrive::FileOpen(file,name,flags); if(retcode) (dynamic_cast(*file))->FlagReadOnlyMedium(); return retcode; -}; +} -bool cdromDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) -{ +bool cdromDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; -}; +} -bool cdromDrive::FileUnlink(char * name) -{ +bool cdromDrive::FileUnlink(char * name) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; -}; +} -bool cdromDrive::RemoveDir(char * dir) -{ +bool cdromDrive::RemoveDir(char * dir) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; -}; +} -bool cdromDrive::MakeDir(char * dir) -{ +bool cdromDrive::MakeDir(char * dir) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; -}; +} -bool cdromDrive::Rename(char * oldname,char * newname) -{ +bool cdromDrive::Rename(char * oldname,char * newname) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; -}; +} -bool cdromDrive::GetFileAttr(char * name,Bit16u * attr) -{ +bool cdromDrive::GetFileAttr(char * name,Bit16u * attr) { bool result = localDrive::GetFileAttr(name,attr); if (result) *attr |= DOS_ATTR_READ_ONLY; return result; -}; +} -bool cdromDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) -{ +bool cdromDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) { // If media has changed, reInit drivecache. if (MSCDEX_HasMediaChanged(subUnit)) { dirCache.EmptyCache(); @@ -628,10 +620,9 @@ bool cdromDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) if (MSCDEX_GetVolumeName(subUnit,name)) dirCache.SetLabel(name,true,true); } return localDrive::FindFirst(_dir,dta); -}; +} -void cdromDrive::SetDir(const char* path) -{ +void cdromDrive::SetDir(const char* path) { // If media has changed, reInit drivecache. if (MSCDEX_HasMediaChanged(subUnit)) { dirCache.EmptyCache(); @@ -640,7 +631,7 @@ void cdromDrive::SetDir(const char* path) if (MSCDEX_GetVolumeName(subUnit,name)) dirCache.SetLabel(name,true,true); } localDrive::SetDir(path); -}; +} bool cdromDrive::isRemote(void) { return true; diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 628201d1..17ee00a9 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -98,12 +98,12 @@ bool Virtual_File::Read(Bit8u * data,Bit16u * size) { } file_pos+=*size; return true; -}; +} bool Virtual_File::Write(Bit8u * data,Bit16u * size){ /* Not really writeable */ return false; -}; +} bool Virtual_File::Seek(Bit32u * new_pos,Bit32u type){ switch (type) { @@ -122,11 +122,11 @@ bool Virtual_File::Seek(Bit32u * new_pos,Bit32u type){ } *new_pos=file_pos; return true; -}; +} bool Virtual_File::Close(){ return true; -}; +} Bit16u Virtual_File::GetInformation(void) { diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index f8fc6341..550ecca4 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: joystick.cpp,v 1.19 2007-08-12 10:23:36 c2woody Exp $ */ +/* $Id: joystick.cpp,v 1.20 2008-10-05 14:44:52 qbix79 Exp $ */ #include #include "dosbox.h" @@ -164,29 +164,25 @@ void JOYSTICK_Move_Y(Bitu which,float y) { } } -bool JOYSTICK_IsEnabled(Bitu which) -{ +bool JOYSTICK_IsEnabled(Bitu which) { if (which<2) return stick[which].enabled; return false; -}; +} -bool JOYSTICK_GetButton(Bitu which, Bitu num) -{ +bool JOYSTICK_GetButton(Bitu which, Bitu num) { if ((which<2) && (num<2)) return stick[which].button[num]; return false; } -float JOYSTICK_GetMove_X(Bitu which) -{ +float JOYSTICK_GetMove_X(Bitu which) { if (which<2) return stick[which].xpos; return 0.0f; } -float JOYSTICK_GetMove_Y(Bitu which) -{ +float JOYSTICK_GetMove_Y(Bitu which) { if (which<2) return stick[which].ypos; return 0.0f; -}; +} class JOYSTICK:public Module_base{ private: diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 7991c1bb..ce42db4c 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.47 2007-08-12 19:16:01 c2woody Exp $ */ +/* $Id: mixer.cpp,v 1.48 2008-10-05 14:44:52 qbix79 Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -265,7 +265,7 @@ void MixerChannel::AddStretched(Bitu len,Bit16s * data) { mixer.work[mixpos][1]+=sample*volmul[1]; mixpos++; } -}; +} void MixerChannel::AddSamples_m8(Bitu len,Bit8u * data) { AddSamples(len,data); diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 622d39a5..fd7df3c2 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_attr.cpp,v 1.28 2008-01-09 20:34:51 c2woody Exp $ */ +/* $Id: vga_attr.cpp,v 1.29 2008-10-05 14:44:52 qbix79 Exp $ */ #include "dosbox.h" #include "inout.h" @@ -212,7 +212,7 @@ Bitu read_p3c1(Bitu port,Bitu iolen) { LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:ATTR:Read from unkown Index %2X",attr(index)); } return 0; -}; +} void VGA_SetupAttr(void) { diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 440eaf77..7a54ffb2 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.58 2008-09-07 10:55:15 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.59 2008-10-05 14:44:52 qbix79 Exp $ */ #include #include @@ -527,9 +527,9 @@ static Bit8u MemoryRegion(void) { } LoadMoveRegion(SegPhys(ds)+reg_si,region); /* Parse the region for information */ - PhysPt src_mem,dest_mem; - MemHandle src_handle,dest_handle; - Bitu src_off,dest_off;Bitu src_remain,dest_remain; + PhysPt src_mem = 0,dest_mem = 0; + MemHandle src_handle = 0,dest_handle = 0; + Bitu src_off = 0,dest_off = 0 ;Bitu src_remain = 0,dest_remain = 0; if (!region.src_type) { src_mem=region.src_page_seg*16+region.src_offset; } else { @@ -1009,7 +1009,7 @@ static Bitu V86_Monitor() { Bitu rm_val=mem_readb((v86_cs<<4)+v86_ip+2); Bitu which=(rm_val >> 3) & 7; if ((rm_val<0xc0) || (rm_val>=0xe8)) - E_Exit("Invalid opcode 0x0f 0x20 %x caused a protection fault!",rm_val); + E_Exit("Invalid opcode 0x0f 0x20 %x caused a protection fault!",static_cast(rm_val)); Bit32u crx=CPU_GET_CRX(which); switch (rm_val&7) { case 0: reg_eax=crx; break; @@ -1028,7 +1028,7 @@ static Bitu V86_Monitor() { Bitu rm_val=mem_readb((v86_cs<<4)+v86_ip+2); Bitu which=(rm_val >> 3) & 7; if ((rm_val<0xc0) || (rm_val>=0xe8)) - E_Exit("Invalid opcode 0x0f 0x22 %x caused a protection fault!",rm_val); + E_Exit("Invalid opcode 0x0f 0x22 %x caused a protection fault!",static_cast(rm_val)); Bit32u crx=0; switch (rm_val&7) { case 0: crx=reg_eax; break; diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 1e6895ce..9a5cbff0 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.cpp,v 1.52 2008-05-10 17:33:28 c2woody Exp $ */ +/* $Id: int10.cpp,v 1.53 2008-10-05 14:44:52 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -684,7 +684,7 @@ static void INT10_InitVGA(void) { /* More than 64k */ IO_Write(0x3c4,0x04); IO_Write(0x3c5,0x02); -}; +} static void SetupTandyBios(void) { static Bit8u TandyConfig[130]= { @@ -720,4 +720,4 @@ void INT10_Init(Section* sec) { INT10_SetupVESA(); INT10_SetupRomMemoryChecksum();//SetupVesa modifies the rom as well. INT10_SetVideoMode(machine==MCH_HERC ? 0x7 : 0x3); -}; +} diff --git a/src/ints/int10_vptable.cpp b/src/ints/int10_vptable.cpp index 8b6d9ab0..acd383d6 100644 --- a/src/ints/int10_vptable.cpp +++ b/src/ints/int10_vptable.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vptable.cpp,v 1.2 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: int10_vptable.cpp,v 1.3 2008-10-05 14:44:52 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -461,6 +461,7 @@ Bitu INT10_SetupVideoParameterTable(PhysPt basepos) { } } +#if 0 void INT10_GenerateVideoParameterTable(void) { if (!IS_VGA_ARCH) E_Exit("Be sure that all graphics registers are readable!"); Bitu i; @@ -701,3 +702,4 @@ void INT10_GenerateVideoParameterTable(void) { INT10_SetVideoMode(3); E_Exit("done!"); } +#endif diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index e19b6d33..e6d91b86 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.52 2008-03-29 16:47:09 c2woody Exp $ */ +/* $Id: xms.cpp,v 1.53 2008-10-05 14:44:52 qbix79 Exp $ */ #include #include @@ -103,18 +103,16 @@ struct XMS_MemMove{ #endif -Bitu XMS_EnableA20(bool enable) -{ +Bitu XMS_EnableA20(bool enable) { Bit8u val = IO_Read (0x92); if (enable) IO_Write(0x92,val | 2); else IO_Write(0x92,val & ~2); return 0; -}; +} -Bitu XMS_GetEnabledA20(void) -{ +Bitu XMS_GetEnabledA20(void) { return (IO_Read(0x92)&2)>0; -}; +} static RealPt xms_callback; static bool umb_available; @@ -131,7 +129,7 @@ Bitu XMS_QueryFreeMemory(Bit16u& largestFree, Bit16u& totalFree) { largestFree=(Bit16u)(MEM_FreeLargest()*4); if (!totalFree) return XMS_OUT_OF_SPACE; return 0; -}; +} Bitu XMS_AllocateMemory(Bitu size, Bit16u& handle) { // size = kb /* Find free handle */ @@ -154,7 +152,7 @@ Bitu XMS_AllocateMemory(Bitu size, Bit16u& handle) { // size = kb xms_handles[index].size=size; handle=index; return 0; -}; +} Bitu XMS_FreeMemory(Bitu handle) { if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; @@ -163,7 +161,7 @@ Bitu XMS_FreeMemory(Bitu handle) { xms_handles[handle].size=0; xms_handles[handle].free=true; return 0; -}; +} Bitu XMS_MoveMemory(PhysPt bpt) { /* Read the block with mem_read's */ @@ -215,7 +213,7 @@ Bitu XMS_LockMemory(Bitu handle, Bit32u& address) { if (xms_handles[handle].locked<255) xms_handles[handle].locked++; address = xms_handles[handle].mem*4096; return 0; -}; +} Bitu XMS_UnlockMemory(Bitu handle) { if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; @@ -224,7 +222,7 @@ Bitu XMS_UnlockMemory(Bitu handle) { return 0; } return XMS_BLOCK_NOT_LOCKED; -}; +} Bitu XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFree, Bit16u& size) { if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; @@ -236,7 +234,7 @@ Bitu XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFree, Bit } size=(Bit16u)(xms_handles[handle].size); return 0; -}; +} Bitu XMS_ResizeMemory(Bitu handle, Bitu newSize) { if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; @@ -261,7 +259,8 @@ static bool multiplex_xms(void) { } return false; -}; +} + INLINE void SET_RESULT(Bitu res,bool touch_bl_on_succes=true) { if(touch_bl_on_succes || res) reg_bl = (Bit8u)res; reg_ax = (res==0); @@ -412,6 +411,7 @@ Bitu XMS_Handler(void) { // LOG(LOG_MISC,LOG_ERROR)("XMS: CALL Result: %02X",reg_bl); return CBRET_NONE; } + class XMS: public Module_base { private: CALLBACK_HandlerObject callbackhandler; diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 59d08d88..0395406e 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.33 2008-09-07 10:55:15 c2woody Exp $ */ +/* $Id: programs.cpp,v 1.34 2008-10-05 14:44:52 qbix79 Exp $ */ #include #include @@ -58,7 +58,7 @@ void PROGRAMS_MakeFile(char const * const name,PROGRAMS_Main * main) { comdata[CB_POS+1]=(Bit8u)((call_program>>8)&0xff); /* Copy save the pointer in the vector and save it's index */ - if (internal_progs.size()>255) E_Exit("PROGRAMS_MakeFile program size too large (%d)",internal_progs.size()); + if (internal_progs.size()>255) E_Exit("PROGRAMS_MakeFile program size too large (%d)",static_cast(internal_progs.size())); Bit8u index = (Bit8u)internal_progs.size(); internal_progs.push_back(main); @@ -158,7 +158,7 @@ bool Program::GetEnvStr(const char * entry,std::string & result) { return true; } while (1); return false; -}; +} bool Program::GetEnvNum(Bitu num,std::string & result) { char env_string[1024+1]; From fa4aadc31dd5b6a9a8a8d15a2bc5fde8a52c00a0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 5 Oct 2008 14:50:31 +0000 Subject: [PATCH 3140/4131] add debug thing to default header Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3228 --- include/debug.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/debug.h b/include/debug.h index 88cc2541..318b418d 100644 --- a/include/debug.h +++ b/include/debug.h @@ -24,6 +24,7 @@ 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 debugCallback; From 02cafbb3f0335e0fc8a673b97588c452d2fbf997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 9 Oct 2008 20:37:08 +0000 Subject: [PATCH 3141/4131] adjust cycles for short-running string loops (thanks to ripsaw for pointing this out); fixes some gunship2000 flaws Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3229 --- src/cpu/core_full/string.h | 1 + src/cpu/core_normal/string.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index 0af58c1b..5da65b10 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -31,6 +31,7 @@ LoadIP(); } else { /* Won't interrupt scas and cmps instruction since they can interrupt themselves */ + if (inst.code.op Date: Tue, 21 Oct 2008 06:14:51 +0000 Subject: [PATCH 3142/4131] Add fixcakewalk.diff from Srecko. 19820 on vogons. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3230 --- src/hardware/mpu401.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 43c48661..140f7c37 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.26 2007-02-03 14:11:38 qbix79 Exp $ */ +/* $Id: mpu401.cpp,v 1.27 2008-10-21 06:14:51 qbix79 Exp $ */ #include #include "dosbox.h" @@ -496,11 +496,17 @@ static void UpdateTrack(Bit8u chan) { mpu.playbuf[chan].counter=0xf0; mpu.state.req_mask|=(1< Date: Mon, 27 Oct 2008 11:02:41 +0000 Subject: [PATCH 3143/4131] sone general warnings to not arbitrarily raise the memory size option Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3231 --- src/dosbox.cpp | 9 +++++++-- src/hardware/memory.cpp | 7 ++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 57a68c6f..2e8b926b 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.137 2008-05-21 21:29:16 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.138 2008-10-27 11:02:41 c2woody Exp $ */ #include #include @@ -68,6 +68,7 @@ void FPU_Init(Section*); #endif void DMA_Init(Section*); + void MIXER_Init(Section*); void MIDI_Init(Section*); void HARDWARE_Init(Section*); @@ -348,7 +349,11 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&HARDWARE_Init);//done Pint = secprop->Add_int("memsize", Property::Changeable::WhenIdle,16); Pint->SetMinMax(1,63); - Pint->Set_help("Amount of memory DOSBox has in megabytes."); + Pint->Set_help( + "Amount of memory DOSBox has in megabytes.\n" + " This value is best left at its default to avoid problems with some games,\n" + " though few games might require a higher value.\n" + " There is generally no speed advantage when raising this value."); secprop->AddInitFunction(&CALLBACK_Init); secprop->AddInitFunction(&PIC_Init);//done secprop->AddInitFunction(&PROGRAMS_Init); diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index efdbe02f..5d362af5 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: memory.cpp,v 1.54 2008-03-09 20:32:23 c2woody Exp $ */ +/* $Id: memory.cpp,v 1.55 2008-10-27 11:02:41 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -28,6 +28,7 @@ #include #define PAGES_IN_BLOCK ((1024*1024)/MEM_PAGE_SIZE) +#define SAFE_MEMORY 32 #define MAX_MEMORY 64 #define MAX_PAGE_ENTRIES (MAX_MEMORY*1024*1024/4096) #define LFB_PAGES 512 @@ -553,6 +554,10 @@ public: LOG_MSG("Maximum memory size is %d MB",MAX_MEMORY - 1); memsize = MAX_MEMORY-1; } + if (memsize > SAFE_MEMORY-1) { + LOG_MSG("Memory sizes above %d MB are NOT recommended.",SAFE_MEMORY - 1); + LOG_MSG("Stick with the default values unless you are absolutely certain."); + } MemBase = new Bit8u[memsize*1024*1024]; if (!MemBase) E_Exit("Can't allocate main memory of %d MB",memsize); /* Clear the memory, as new doesn't always give zeroed memory From c96d1f063e7ed835a1ba32563d02490af2ae30a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 30 Oct 2008 22:34:17 +0000 Subject: [PATCH 3144/4131] allow more submappings for the keyboard layouts (skatz, used for e.g. ukrainian layout) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3232 --- src/dos/dos_keyboard_layout.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 74a92bf4..436bb907 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_keyboard_layout.cpp,v 1.14 2008-08-31 10:14:31 c2woody Exp $ */ +/* $Id: dos_keyboard_layout.cpp,v 1.15 2008-10-30 22:34:17 c2woody Exp $ */ #include "dosbox.h" #include "bios.h" @@ -542,7 +542,7 @@ bool keyboard_layout::map_key(Bitu key, Bit16u layouted_key, bool is_command, bo diacritics_character=key_command; if (diacritics_character-200>=diacritics_entries) diacritics_character=0; return true; - } else if ((key_command>=120) && (key_command<129)) { + } else if ((key_command>=120) && (key_command<140)) { // switch layout command this->read_keyboard_file(key_command-119); return true; From 1bcab407aeba865d694d127e9a5b0cc0de70ba22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 6 Nov 2008 19:31:21 +0000 Subject: [PATCH 3145/4131] fix cdrom ioctl raw sector reading; add mci cd audio functionality to cdrom ioctl interface; add direct audio extraction functionality to cdrom ioctl interface Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3233 --- src/dos/cdrom.h | 51 +++- src/dos/cdrom_ioctl_win32.cpp | 463 ++++++++++++++++++++++++++++------ src/dos/dos_mscdex.cpp | 22 +- src/dos/dos_programs.cpp | 34 ++- 4 files changed, 478 insertions(+), 92 deletions(-) diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index 39268232..241839be 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -23,7 +23,7 @@ #define RAW_SECTOR_SIZE 2352 #define COOKED_SECTOR_SIZE 2048 -enum { CDROM_USE_SDL, CDROM_USE_ASPI, CDROM_USE_IOCTL }; +enum { CDROM_USE_SDL, CDROM_USE_ASPI, CDROM_USE_IOCTL_DIO, CDROM_USE_IOCTL_DX, CDROM_USE_IOCTL_MCI }; typedef struct SMSF { unsigned char min; @@ -265,7 +265,10 @@ private: class CDROM_Interface_Ioctl : public CDROM_Interface { public: - CDROM_Interface_Ioctl (void); + enum cdioctl_cdatype { CDIOCTL_CDA_DIO, CDIOCTL_CDA_MCI, CDIOCTL_CDA_DX }; + cdioctl_cdatype cdioctl_cda_selected; + + CDROM_Interface_Ioctl (cdioctl_cdatype ioctl_cda); virtual ~CDROM_Interface_Ioctl(void); bool SetDevice (char* path, int forceCD); @@ -282,6 +285,7 @@ public: bool PauseAudio (bool resume); bool StopAudio (void); + bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector); bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); bool LoadUnloadMedia (bool unload); @@ -291,10 +295,51 @@ private: bool Open (void); void Close (void); - + char pathname[32]; HANDLE hIOCTL; TMSF oldLeadOut; + + + /* track start/length data */ + bool track_start_valid; + int track_start_first,track_start_last; + int track_start[128]; + + bool GetAudioTracksAll (void); + + + /* mci audio cd interface */ + bool use_mciplay; + int mci_devid; + + bool mci_CDioctl (UINT msg, DWORD flags, void *arg); + bool mci_CDOpen (char drive); + bool mci_CDClose (void); + bool mci_CDPlay (int start, int length); + bool mci_CDPause (void); + bool mci_CDResume (void); + bool mci_CDStop (void); + int mci_CDStatus (void); + bool mci_CDPosition (int *position); + + + /* digital audio extraction cd interface */ + static void dx_CDAudioCallBack(Bitu len); + + bool use_dxplay; + static struct dxPlayer { + CDROM_Interface_Ioctl *cd; + MixerChannel *channel; + SDL_mutex *mutex; + Bit8u buffer[8192]; + int bufLen; + int currFrame; + int targetFrame; + bool isPlaying; + bool isPaused; + } player; + }; #endif /* WIN 32 */ diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index 7afdc965..299f9585 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_ioctl_win32.cpp,v 1.14 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: cdrom_ioctl_win32.cpp,v 1.15 2008-11-06 19:31:21 c2woody Exp $ */ #if defined (WIN32) @@ -34,35 +34,173 @@ #include "ddk/ntddcdrm.h" // Ioctl stuff #endif +#include + #include "cdrom.h" -CDROM_Interface_Ioctl::CDROM_Interface_Ioctl() -{ +// for a more sophisticated implementation of the mci cdda functionality +// see the SDL sources, which the mci_ functions are based on + +/* General ioctl() CD-ROM command function */ +bool CDROM_Interface_Ioctl::mci_CDioctl(UINT msg, DWORD flags, void *arg) { + MCIERROR mci_error = mciSendCommand(mci_devid, msg, flags, (DWORD_PTR)arg); + if (mci_error!=MMSYSERR_NOERROR) { + char error[256]; + mciGetErrorString(mci_error, error, 256); + LOG_MSG("mciSendCommand() error: %s", error); + return true; + } + return false; +} + +bool CDROM_Interface_Ioctl::mci_CDOpen(char drive) { + MCI_OPEN_PARMS mci_open; + MCI_SET_PARMS mci_set; + char device[3]; + DWORD flags; + + /* Open the requested device */ + mci_open.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_CD_AUDIO; + device[0] = drive; + device[1] = ':'; + device[2] = '\0'; + mci_open.lpstrElementName = device; + flags = (MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID|MCI_OPEN_SHAREABLE|MCI_OPEN_ELEMENT); + if (mci_CDioctl(MCI_OPEN, flags, &mci_open)) { + flags &= ~MCI_OPEN_SHAREABLE; + if (mci_CDioctl(MCI_OPEN, flags, &mci_open)) { + return true; + } + } + mci_devid = mci_open.wDeviceID; + + /* Set the minute-second-frame time format */ + mci_set.dwTimeFormat = MCI_FORMAT_MSF; + mci_CDioctl(MCI_SET, MCI_SET_TIME_FORMAT, &mci_set); + + return false; +} + +bool CDROM_Interface_Ioctl::mci_CDClose(void) { + return mci_CDioctl(MCI_CLOSE, MCI_WAIT, NULL); +} + +bool CDROM_Interface_Ioctl::mci_CDPlay(int start, int length) { + DWORD flags = MCI_FROM | MCI_TO | MCI_NOTIFY; + MCI_PLAY_PARMS mci_play; + mci_play.dwCallback = 0; + + int m, s, f; + FRAMES_TO_MSF(start, &m, &s, &f); + mci_play.dwFrom = MCI_MAKE_MSF(m, s, f); + + FRAMES_TO_MSF(start+length, &m, &s, &f); + mci_play.dwTo = MCI_MAKE_MSF(m, s, f); + + return mci_CDioctl(MCI_PLAY, flags, &mci_play); +} + +bool CDROM_Interface_Ioctl::mci_CDPause(void) { + return mci_CDioctl(MCI_PAUSE, MCI_WAIT, NULL); +} + +bool CDROM_Interface_Ioctl::mci_CDResume(void) { + return mci_CDioctl(MCI_RESUME, MCI_WAIT, NULL); +} + +bool CDROM_Interface_Ioctl::mci_CDStop(void) { + return mci_CDioctl(MCI_STOP, MCI_WAIT, NULL); +} + +int CDROM_Interface_Ioctl::mci_CDStatus(void) { + int status; + MCI_STATUS_PARMS mci_status; + + DWORD flags = MCI_STATUS_ITEM | MCI_WAIT; + mci_status.dwItem = MCI_STATUS_MODE; + if (mci_CDioctl(MCI_STATUS, flags, &mci_status)) { + status = -1; + } else { + switch (mci_status.dwReturn) { + case MCI_MODE_NOT_READY: + case MCI_MODE_OPEN: + status = 0; + break; + case MCI_MODE_STOP: + status = 1; + break; + case MCI_MODE_PLAY: + status = 2; + break; + case MCI_MODE_PAUSE: + status = 3; + break; + default: + status = -1; + break; + } + } + + return status; +} + +bool CDROM_Interface_Ioctl::mci_CDPosition(int *position) { + *position = 0; + + DWORD flags = MCI_STATUS_ITEM | MCI_WAIT; + + MCI_STATUS_PARMS mci_status; + mci_status.dwItem = MCI_STATUS_MODE; + if (mci_CDioctl(MCI_STATUS, flags, &mci_status)) return true; + switch (mci_status.dwReturn) { + case MCI_MODE_NOT_READY: + case MCI_MODE_OPEN: + case MCI_MODE_STOP: + return true; // not ready/undefined status + case MCI_MODE_PLAY: + case MCI_MODE_PAUSE: + mci_status.dwItem = MCI_STATUS_POSITION; + if (!mci_CDioctl(MCI_STATUS, flags, &mci_status)) { + *position = MSF_TO_FRAMES( + MCI_MSF_MINUTE(mci_status.dwReturn), + MCI_MSF_SECOND(mci_status.dwReturn), + MCI_MSF_FRAME(mci_status.dwReturn)); + } + return false; // no error, position read + default: + break; + } + return false; +} + + +CDROM_Interface_Ioctl::dxPlayer CDROM_Interface_Ioctl::player = { + NULL, NULL, NULL, 0, 0, 0, 0, 0, false, false }; + +CDROM_Interface_Ioctl::CDROM_Interface_Ioctl(cdioctl_cdatype ioctl_cda) { pathname[0] = 0; hIOCTL = INVALID_HANDLE_VALUE; memset(&oldLeadOut,0,sizeof(oldLeadOut)); -}; + cdioctl_cda_selected = ioctl_cda; +} -CDROM_Interface_Ioctl::~CDROM_Interface_Ioctl() -{ +CDROM_Interface_Ioctl::~CDROM_Interface_Ioctl() { StopAudio(); + if (use_mciplay) mci_CDStop(); Close(); -}; + if (use_mciplay) mci_CDClose(); +} -bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc) -{ +bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc) { // FIXME : To Do return true; } -bool CDROM_Interface_Ioctl::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut) -{ -// Open(); +bool CDROM_Interface_Ioctl::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut) { CDROM_TOC toc; DWORD byteCount; BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), &byteCount,NULL); -// Close(); if (!bStat) return false; stTrack = toc.FirstTrack; @@ -70,17 +208,30 @@ bool CDROM_Interface_Ioctl::GetAudioTracks(int& stTrack, int& endTrack, TMSF& le leadOut.min = toc.TrackData[endTrack].Address[1]; leadOut.sec = toc.TrackData[endTrack].Address[2]; leadOut.fr = toc.TrackData[endTrack].Address[3]; - return true; -}; -bool CDROM_Interface_Ioctl::GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr) -{ -// Open(); + if ((use_mciplay || use_dxplay) && (!track_start_valid)) { + Bits track_num = 0; + // get track start address of all tracks + for (Bits i=toc.FirstTrack; i<=toc.LastTrack+1; i++) { + if (((toc.TrackData[i].Control&1)==0) || (i==toc.LastTrack+1)) { + track_start[track_num] = MSF_TO_FRAMES(toc.TrackData[track_num].Address[1],toc.TrackData[track_num].Address[2],toc.TrackData[track_num].Address[3])-150; + track_start[track_num] += 150; + track_num++; + } + } + track_start_first = 0; + track_start_last = track_num-1; + track_start_valid = true; + } + + return true; +} + +bool CDROM_Interface_Ioctl::GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr) { CDROM_TOC toc; DWORD byteCount; BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), &byteCount,NULL); -// Close(); if (!bStat) return false; attr = (toc.TrackData[track-1].Control << 4) & 0xEF; @@ -88,11 +239,52 @@ bool CDROM_Interface_Ioctl::GetAudioTrackInfo(int track, TMSF& start, unsigned c start.sec = toc.TrackData[track-1].Address[2]; start.fr = toc.TrackData[track-1].Address[3]; return true; -}; +} -bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) -{ -// Open(); +bool CDROM_Interface_Ioctl::GetAudioTracksAll(void) { + if (track_start_valid) return true; + + CDROM_TOC toc; + DWORD byteCount; + BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, + &toc, sizeof(toc), &byteCount,NULL); + if (!bStat) return false; + + Bits track_num = 0; + // get track start address of all tracks + for (Bits i=toc.FirstTrack; i<=toc.LastTrack+1; i++) { + if (((toc.TrackData[i].Control&1)==0) || (i==toc.LastTrack+1)) { + track_start[track_num] = MSF_TO_FRAMES(toc.TrackData[track_num].Address[1],toc.TrackData[track_num].Address[2],toc.TrackData[track_num].Address[3])-150; + track_start[track_num] += 150; + track_num++; + } + } + track_start_first = 0; + track_start_last = track_num-1; + track_start_valid = true; + return true; +} + +bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) { + if (use_dxplay) { + track = 1; + FRAMES_TO_MSF(player.currFrame + 150, &absPos.min, &absPos.sec, &absPos.fr); + FRAMES_TO_MSF(player.currFrame + 150, &relPos.min, &relPos.sec, &relPos.fr); + + if (GetAudioTracksAll()) { + // get track number from current frame + for (int i=track_start_first; i<=track_start_last; i++) { + if ((player.currFrame + 150=track_start[i])) { + // track found, calculate relative position + track = i; + FRAMES_TO_MSF(player.currFrame + 150-track_start[i],&relPos.min,&relPos.sec,&relPos.fr); + break; + } + } + } + + return true; + } CDROM_SUB_Q_DATA_FORMAT insub; SUB_Q_CHANNEL_DATA sub; @@ -102,7 +294,6 @@ bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& trac BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), &byteCount,NULL); -// Close(); if (!bStat) return false; attr = (sub.CurrentPosition.Control << 4) & 0xEF; @@ -114,13 +305,40 @@ bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& trac absPos.min = sub.CurrentPosition.AbsoluteAddress[1]; absPos.sec = sub.CurrentPosition.AbsoluteAddress[2]; absPos.fr = sub.CurrentPosition.AbsoluteAddress[3]; - - return true; -}; -bool CDROM_Interface_Ioctl::GetAudioStatus(bool& playing, bool& pause) -{ -// Open(); + if (use_mciplay) { + int cur_pos; + if (!mci_CDPosition(&cur_pos)) { + // absolute position read, try to calculate the track-relative position + if (GetAudioTracksAll()) { + for (int i=track_start_first; i<=track_start_last; i++) { + if ((cur_pos=track_start[i])) { + // track found, calculate relative position + FRAMES_TO_MSF(cur_pos-track_start[i],&relPos.min,&relPos.sec,&relPos.fr); + break; + } + } + } + FRAMES_TO_MSF(cur_pos,&absPos.min,&absPos.sec,&absPos.fr); + } + } + + return true; +} + +bool CDROM_Interface_Ioctl::GetAudioStatus(bool& playing, bool& pause) { + if (use_mciplay) { + int status = mci_CDStatus(); + if (status<0) return false; + playing = (status==2); + pause = (status==3); + return true; + } + if (use_dxplay) { + playing = player.isPlaying; + pause = player.isPaused; + return true; + } CDROM_SUB_Q_DATA_FORMAT insub; SUB_Q_CHANNEL_DATA sub; @@ -130,17 +348,15 @@ bool CDROM_Interface_Ioctl::GetAudioStatus(bool& playing, bool& pause) BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), &byteCount,NULL); -// Close(); if (!bStat) return false; playing = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_IN_PROGRESS); pause = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_PAUSED); return true; -}; +} -bool CDROM_Interface_Ioctl::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) -{ +bool CDROM_Interface_Ioctl::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) { // Seems not possible to get this values using ioctl... int track1,track2; TMSF leadOut; @@ -149,20 +365,41 @@ bool CDROM_Interface_Ioctl::GetMediaTrayStatus(bool& mediaPresent, bool& mediaCh trayOpen = !mediaPresent; mediaChanged = (oldLeadOut.min!=leadOut.min) || (oldLeadOut.sec!=leadOut.sec) || (oldLeadOut.fr!=leadOut.fr); if (mediaChanged) { - // Open new media - Close(); Open(); - }; + Close(); + if (use_mciplay) mci_CDClose(); + // Open new medium + Open(); + + // check this (what to do if cd is ejected): + use_mciplay = false; + if (!mci_CDOpen(pathname[4])) use_mciplay = true; + track_start_valid = false; + } // Save old values oldLeadOut.min = leadOut.min; oldLeadOut.sec = leadOut.sec; oldLeadOut.fr = leadOut.fr; // always success return true; -}; +} + +bool CDROM_Interface_Ioctl::PlayAudioSector (unsigned long start,unsigned long len) { + if (use_mciplay) { + if (!mci_CDPlay(start+150, len)) return true; + if (!mci_CDPlay(start+150, len-1)) return true; + return false; + } + if (use_dxplay) { + SDL_mutexP(player.mutex); + player.cd = this; + player.currFrame = start; + player.targetFrame = start + len; + player.isPlaying = true; + player.isPaused = false; + SDL_mutexV(player.mutex); + return true; + } -bool CDROM_Interface_Ioctl::PlayAudioSector (unsigned long start,unsigned long len) -{ -// Open(); CDROM_PLAY_AUDIO_MSF audio; DWORD byteCount; // Start @@ -178,53 +415,90 @@ bool CDROM_Interface_Ioctl::PlayAudioSector (unsigned long start,unsigned long l BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PLAY_AUDIO_MSF, &audio, sizeof(audio), NULL, 0, &byteCount,NULL); -// Close(); return bStat>0; -}; +} + +bool CDROM_Interface_Ioctl::PauseAudio(bool resume) { + if (use_mciplay) { + if (resume) { + if (!mci_CDResume()) return true; + } else { + if (!mci_CDPause()) return true; + } + return false; + } + if (use_dxplay) { + player.isPaused = !resume; + return true; + } -bool CDROM_Interface_Ioctl::PauseAudio(bool resume) -{ -// Open(); BOOL bStat; DWORD byteCount; if (resume) bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RESUME_AUDIO, NULL, 0, NULL, 0, &byteCount,NULL); else bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PAUSE_AUDIO, NULL, 0, NULL, 0, &byteCount,NULL); -// Close(); return bStat>0; -}; +} + +bool CDROM_Interface_Ioctl::StopAudio(void) { + if (use_mciplay) { + if (!mci_CDStop()) return true; + return false; + } + if (use_dxplay) { + player.isPlaying = false; + player.isPaused = false; + return true; + } -bool CDROM_Interface_Ioctl::StopAudio(void) -{ -// Open(); BOOL bStat; DWORD byteCount; bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_STOP_AUDIO, NULL, 0, NULL, 0, &byteCount,NULL); -// Close(); return bStat>0; -}; +} -bool CDROM_Interface_Ioctl::LoadUnloadMedia(bool unload) -{ -// Open(); +bool CDROM_Interface_Ioctl::LoadUnloadMedia(bool unload) { BOOL bStat; DWORD byteCount; if (unload) bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &byteCount,NULL); else bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, &byteCount,NULL); -// Close(); + track_start_valid = false; return bStat>0; -}; +} -bool CDROM_Interface_Ioctl::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) -{ +bool CDROM_Interface_Ioctl::ReadSector(Bit8u *buffer, bool raw, unsigned long sector) { BOOL bStat; DWORD byteCount = 0; -// Open(); + Bitu buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; + + if (!raw) { + // Cooked + int success = 0; + DWORD newPos = SetFilePointer(hIOCTL, sector*COOKED_SECTOR_SIZE, 0, FILE_BEGIN); + if (newPos != 0xFFFFFFFF) success = ReadFile(hIOCTL, buffer, buflen, &byteCount, NULL); + bStat = (success!=0); + } else { + // Raw + RAW_READ_INFO in; + in.DiskOffset.LowPart = sector*COOKED_SECTOR_SIZE; + in.DiskOffset.HighPart = 0; + in.SectorCount = 1; + in.TrackMode = CDDA; + bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RAW_READ, &in, sizeof(in), + buffer, buflen, &byteCount,NULL); + } + + return (byteCount==buflen) && (bStat>0); +} + +bool CDROM_Interface_Ioctl::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) { + BOOL bStat; + DWORD byteCount = 0; Bitu buflen = raw ? num*RAW_SECTOR_SIZE : num*COOKED_SECTOR_SIZE; Bit8u* bufdata = new Bit8u[buflen]; @@ -238,14 +512,13 @@ bool CDROM_Interface_Ioctl::ReadSectors(PhysPt buffer, bool raw, unsigned long s } else { // Raw RAW_READ_INFO in; - in.DiskOffset.LowPart = sector; + in.DiskOffset.LowPart = sector*COOKED_SECTOR_SIZE; in.DiskOffset.HighPart = 0; in.SectorCount = num; in.TrackMode = CDDA; bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RAW_READ, &in, sizeof(in), bufdata, buflen, &byteCount,NULL); } -// Close(); MEM_BlockWrite(buffer,bufdata,buflen); delete[] bufdata; @@ -253,23 +526,68 @@ bool CDROM_Interface_Ioctl::ReadSectors(PhysPt buffer, bool raw, unsigned long s return (byteCount==buflen) && (bStat>0); } -bool CDROM_Interface_Ioctl::SetDevice(char* path, int forceCD) -{ +void CDROM_Interface_Ioctl::dx_CDAudioCallBack(Bitu len) { + len *= 4; // 16 bit, stereo + if (!len) return; + if (!player.isPlaying || player.isPaused) { + player.channel->AddSilence(); + return; + } + SDL_mutexP(player.mutex); + while (player.bufLen < (Bits)len) { + bool success; + if (player.targetFrame > player.currFrame) + success = player.cd->ReadSector(&player.buffer[player.bufLen], true, player.currFrame); + else success = false; + + if (success) { + player.currFrame++; + player.bufLen += RAW_SECTOR_SIZE; + } else { + memset(&player.buffer[player.bufLen], 0, len - player.bufLen); + player.bufLen = len; + player.isPlaying = false; + } + } + SDL_mutexV(player.mutex); + player.channel->AddSamples_s16(len/4,(Bit16s *)player.buffer); + memmove(player.buffer, &player.buffer[len], player.bufLen - len); + player.bufLen -= len; +} + +bool CDROM_Interface_Ioctl::SetDevice(char* path, int forceCD) { + mci_devid = 0; + use_mciplay = false; + use_dxplay = false; + track_start_valid = false; if (GetDriveType(path)==DRIVE_CDROM) { char letter [3] = { 0, ':', 0 }; letter[0] = path[0]; strcpy(pathname,"\\\\.\\"); strcat(pathname,letter); if (Open()) { -// Close(); + if (cdioctl_cda_selected == CDIOCTL_CDA_MCI) { + // check if MCI-interface can be used for cd audio + if (!mci_CDOpen(path[0])) use_mciplay = true; + } + if (!use_mciplay) { + if (cdioctl_cda_selected == CDIOCTL_CDA_DX) { + // use direct sector access for cd audio routines + player.mutex = SDL_CreateMutex(); + if (!player.channel) { + player.channel = MIXER_AddChannel(&dx_CDAudioCallBack, 44100, "CDAUDIO"); + } + player.channel->Enable(true); + use_dxplay = true; + } + } return true; }; } return false; } -bool CDROM_Interface_Ioctl::Open(void) -{ +bool CDROM_Interface_Ioctl::Open(void) { hIOCTL = CreateFile(pathname, // drive to open GENERIC_READ, // read access FILE_SHARE_READ | // share mode @@ -279,11 +597,10 @@ bool CDROM_Interface_Ioctl::Open(void) 0, // file attributes NULL); // do not copy file attributes return (hIOCTL!=INVALID_HANDLE_VALUE); -}; +} -void CDROM_Interface_Ioctl::Close(void) -{ +void CDROM_Interface_Ioctl::Close(void) { CloseHandle(hIOCTL); -}; +} #endif diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index cc185918..55e942ed 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.55 2008-09-07 10:55:14 c2woody Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.56 2008-11-06 19:31:21 c2woody Exp $ */ #include #include @@ -173,10 +173,6 @@ CMscdex::CMscdex(void) { }; CMscdex::~CMscdex(void) { -/* if (defaultBufSeg!=0) { - DOS_FreeMemory(defaultBufSeg); // can't free that - defaultBufSeg = 0; - } */ defaultBufSeg = 0; for (Bit16u i=0; i4)) { // only WIN NT/200/XP - if (useCdromInterface==CDROM_USE_IOCTL) { - cdrom[numDrives] = new CDROM_Interface_Ioctl(); + if (useCdromInterface==CDROM_USE_IOCTL_DIO) { + cdrom[numDrives] = new CDROM_Interface_Ioctl(CDROM_Interface_Ioctl::CDIOCTL_CDA_DIO); LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface."); break; } + if (useCdromInterface==CDROM_USE_IOCTL_DX) { + cdrom[numDrives] = new CDROM_Interface_Ioctl(CDROM_Interface_Ioctl::CDIOCTL_CDA_DX); + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface (digital audio extraction)."); + break; + } + if (useCdromInterface==CDROM_USE_IOCTL_MCI) { + cdrom[numDrives] = new CDROM_Interface_Ioctl(CDROM_Interface_Ioctl::CDIOCTL_CDA_MCI); + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface (media control interface)."); + break; + } } if (useCdromInterface==CDROM_USE_ASPI) { - // all Wins - ASPI + // all Wins - ASPI cdrom[numDrives] = new CDROM_Interface_Aspi(); LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: ASPI Interface."); break; diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 7c6963f1..60710464 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.88 2008-09-26 17:21:17 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.89 2008-11-06 19:31:21 c2woody Exp $ */ #include "dosbox.h" #include @@ -263,12 +263,32 @@ public: int error; if (cmd->FindExist("-aspi",false)) { MSCDEX_SetCDInterface(CDROM_USE_ASPI, num); - } else if (cmd->FindExist("-ioctl",false)) { - MSCDEX_SetCDInterface(CDROM_USE_IOCTL, num); + } else if (cmd->FindExist("-ioctl_dio",false)) { + MSCDEX_SetCDInterface(CDROM_USE_IOCTL_DIO, num); + } else if (cmd->FindExist("-ioctl_dx",false)) { + MSCDEX_SetCDInterface(CDROM_USE_IOCTL_DX, num); +#if defined (WIN32) + } else if (cmd->FindExist("-ioctl_mci",false)) { + MSCDEX_SetCDInterface(CDROM_USE_IOCTL_MCI, num); +#endif } else if (cmd->FindExist("-noioctl",false)) { MSCDEX_SetCDInterface(CDROM_USE_SDL, num); } else { - MSCDEX_SetCDInterface(CDROM_USE_IOCTL, num); +#if defined (WIN32) +/* // Check OS + OSVERSIONINFO osi; + osi.dwOSVersionInfoSize = sizeof(osi); + GetVersionEx(&osi); + if ((osi.dwPlatformId==VER_PLATFORM_WIN32_NT) && (osi.dwMajorVersion>5)) { + // Vista/above + MSCDEX_SetCDInterface(CDROM_USE_IOCTL_DX, num); + } else { + MSCDEX_SetCDInterface(CDROM_USE_IOCTL_DIO, num); + } */ + MSCDEX_SetCDInterface(CDROM_USE_IOCTL_DX, num); +#else + MSCDEX_SetCDInterface(CDROM_USE_IOCTL_DIO, num); +#endif } newdrive = new cdromDrive(drive,temp_line.c_str(),sizes[0],bit8size,sizes[2],0,mediaid,error); // Check Mscdex, if it worked out... @@ -515,19 +535,17 @@ public: FILE *usefile_1=NULL; FILE *usefile_2=NULL; - Bitu i; + Bitu i=0; Bit32u floppysize; Bit32u rombytesize_1=0; Bit32u rombytesize_2=0; - Bit8u drive; + Bit8u drive = 'A'; std::string cart_cmd=""; if(!cmd->GetCount()) { printError(); return; } - i=0; - drive = 'A'; while(iGetCount()) { if(cmd->FindCommand(i+1, temp_line)) { if((temp_line == "-l") || (temp_line == "-L")) { From e2a1305dce34a7f27081d1997c8c7422ea61ce77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 8 Nov 2008 12:56:50 +0000 Subject: [PATCH 3146/4131] some typo; fix mode0xa number of reported columns (thanks etillite, see sf bug #2209440) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3234 --- src/ints/int10_modes.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 0f5d7830..5e1484c7 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.80 2008-08-08 21:57:00 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.81 2008-11-08 12:56:50 c2woody Exp $ */ #include @@ -227,7 +227,7 @@ VideoModeBlock ModeList_OTHER[]={ { 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,56 ,127 ,40 ,100 ,0 }, { 0x008 ,M_TANDY16,160 ,200 ,20 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,56 ,127 ,40 ,100 ,0 }, { 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,113 ,63 ,80 ,50 ,0 }, -{ 0x00A ,M_CGA4 ,640 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,113 ,63 ,80 ,50 ,0 }, +{ 0x00A ,M_CGA4 ,640 ,200 ,80 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,113 ,63 ,80 ,50 ,0 }, {0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, }; @@ -632,8 +632,11 @@ bool INT10_SetVideoMode(Bitu mode) { if (mono_mode) crtc_base=0x3b4; else crtc_base=0x3d4; - // Disable MMIO here so we can read / write memory - if (IS_VGA_ARCH && svgaCard == SVGA_S3Trio) IO_Write(crtc_base,0x53);IO_Write(crtc_base+1,0x0); + if (IS_VGA_ARCH && (svgaCard == SVGA_S3Trio)) { + // Disable MMIO here so we can read / write memory + IO_Write(crtc_base,0x53); + IO_Write(crtc_base+1,0x0); + } /* Setup MISC Output Register */ Bit8u misc_output=0x2 | (mono_mode ? 0x0 : 0x1); From 163dce9a452d5aa18c6e25d36611ac766d054d34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 9 Nov 2008 10:38:21 +0000 Subject: [PATCH 3147/4131] fix a few windib alternative key scancodes (thanks etillite, see sf bug #2209440) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3235 --- src/gui/sdl_mapper.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index f677d267..88aa0a9d 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.50 2008-09-10 16:20:04 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.51 2008-11-09 10:38:21 c2woody Exp $ */ #include #include @@ -422,7 +422,10 @@ Bitu GetKeyCode(SDL_keysym keysym) { #if defined (WIN32) switch (key) { case 0x1c: // ENTER + case 0x1d: // CONTROL case 0x35: // SLASH + case 0x37: // PRINTSCREEN + case 0x38: // ALT case 0x45: // PAUSE case 0x47: // HOME case 0x48: // cursor UP From 0aa906a05c512258f0fcc7dec9c794637238b8f7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 9 Nov 2008 11:22:03 +0000 Subject: [PATCH 3148/4131] Fix telengard. Always use attr in non-textmode. Change cga4 to use 0x3 instead of 0x1. Might not be needed as attribute is always used.... Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3236 --- src/ints/int10_char.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 1c35dec3..6789be59 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.55 2008-08-11 12:50:26 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.56 2008-11-09 11:22:03 qbix79 Exp $ */ /* Character displaying moving functions */ @@ -480,6 +480,8 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt } switch(CurMode->type) { case M_CGA4: + attr = 0x3; + break; case M_CGA2: attr = 0x1; break; @@ -521,6 +523,7 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) { if (CurMode->type!=M_TEXT) { + showattr=true; //Use attr in graphics mode always switch (machine) { case EGAVGA_ARCH_CASE: page%=CurMode->ptotal; From 5b559c39054f44305effe05279727481ca5b5fcf Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 10 Nov 2008 15:29:38 +0000 Subject: [PATCH 3149/4131] Cakewalk (ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3237 --- src/hardware/mpu401.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 140f7c37..bf83177f 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.27 2008-10-21 06:14:51 qbix79 Exp $ */ +/* $Id: mpu401.cpp,v 1.28 2008-11-10 15:29:38 qbix79 Exp $ */ #include #include "dosbox.h" @@ -502,6 +502,7 @@ static void UpdateTrack(Bit8u chan) { static void UpdateConductor(void) { if (mpu.condbuf.value[0]==0xfc) { + mpu.condbuf.value[0]=0; mpu.state.conductor=false; mpu.state.req_mask&=~(1<<9); if (mpu.state.amask==0) mpu.state.req_mask|=(1<<12); From 5de6a707505bdc100a3ef627bb765aefc51074b2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 10 Nov 2008 15:30:25 +0000 Subject: [PATCH 3150/4131] Prioritize realtime messages.(Srecko) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3238 --- src/gui/midi.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index ede2088d..78228426 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -103,6 +103,7 @@ static struct { Bitu cmd_len; Bitu cmd_pos; Bit8u cmd_buf[8]; + Bit8u rt_buf[8]; struct { Bit8u buf[SYSEX_SIZE]; Bitu used; @@ -112,6 +113,12 @@ static struct { } midi; void MIDI_RawOutByte(Bit8u data) { + /* Test for a realtime MIDI message */ + if (data>=0xf8) { + midi.rt_buf[0]=data; + midi.handler->PlayMsg(midi.rt_buf); + return; + } /* Test for a active sysex tranfer */ if (midi.status==0xf0) { if (!(data&0x80)) { From 5822f7af76d5e74e8b8b368d46b9310002004bb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 22 Nov 2008 14:24:11 +0000 Subject: [PATCH 3151/4131] display loaded language code when using keyb without parameter Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3239 --- src/dos/dos_keyboard_layout.cpp | 21 ++++++++++++++++++++- src/dos/dos_programs.cpp | 13 ++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 436bb907..f71b6e83 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_keyboard_layout.cpp,v 1.15 2008-10-30 22:34:17 c2woody Exp $ */ +/* $Id: dos_keyboard_layout.cpp,v 1.16 2008-11-22 14:24:11 c2woody Exp $ */ #include "dosbox.h" #include "bios.h" @@ -81,6 +81,7 @@ public: Bitu switch_keyboard_layout(const char* new_layout, keyboard_layout* &created_layout); void switch_foreign_layout(); + const char* get_layout_name(); private: @@ -993,6 +994,16 @@ void keyboard_layout::switch_foreign_layout() { else LOG(LOG_BIOS,LOG_NORMAL)("Switched to US layout"); } +const char* keyboard_layout::get_layout_name() { + // get layout name (language ID or NULL if default layout) + if (use_foreign_layout) { + if (strcmp(current_keyboard_file_name,"none") != 0) { + return (const char*)¤t_keyboard_file_name; + } + } + return NULL; +} + static keyboard_layout* loaded_layout=NULL; @@ -1041,6 +1052,14 @@ Bitu DOS_SwitchKeyboardLayout(const char* new_layout) { } else return 0xff; } +// get currently loaded layout name (NULL if no layout is loaded) +const char* DOS_GetLoadedLayout(void) { + if (loaded_layout) { + return loaded_layout->get_layout_name(); + } + return NULL; +} + class DOS_KeyboardLayout: public Module_base { public: diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 60710464..eee5c927 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.89 2008-11-06 19:31:21 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.90 2008-11-22 14:24:11 c2woody Exp $ */ #include "dosbox.h" #include @@ -1292,6 +1292,7 @@ void IMGMOUNT_ProgramStart(Program * * make) { Bitu DOS_SwitchKeyboardLayout(const char* new_layout); Bitu DOS_LoadKeyboardLayout(const char * layoutname, Bit32s codepage, const char * codepagefile); +const char* DOS_GetLoadedLayout(void); class KEYB : public Program { public: @@ -1344,8 +1345,13 @@ void KEYB::Run(void) { } } } else { - /* no parameter in the command line, just output codepage info */ - WriteOut(MSG_Get("PROGRAM_KEYB_INFO"),dos.loaded_codepage); + /* no parameter in the command line, just output codepage info and possibly loaded layout ID */ + const char* layout_name = DOS_GetLoadedLayout(); + if (layout_name==NULL) { + WriteOut(MSG_Get("PROGRAM_KEYB_INFO"),dos.loaded_codepage); + } else { + WriteOut(MSG_Get("PROGRAM_KEYB_INFO_LAYOUT"),dos.loaded_codepage,layout_name); + } } }; @@ -1532,6 +1538,7 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_IMGMOUNT_MULTIPLE_NON_CUEISO_FILES", "Using multiple files is only supported for cue/iso images.\n"); MSG_Add("PROGRAM_KEYB_INFO","Codepage %i has been loaded\n"); + MSG_Add("PROGRAM_KEYB_INFO_LAYOUT","Codepage %i has been loaded for layout %s\n"); MSG_Add("PROGRAM_KEYB_SHOWHELP", "\033[32;1mKEYB\033[0m [keyboard layout ID[ codepage number[ codepage file]]]\n\n" "Some examples:\n" From 0204b90e8676803e1e37b2485b6b4339c899e819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 23 Nov 2008 09:25:29 +0000 Subject: [PATCH 3152/4131] update cdrom related sections of the readme Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3240 --- README | 102 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 64 insertions(+), 38 deletions(-) diff --git a/README b/README index 71cb23e6..1be74ef5 100644 --- a/README +++ b/README @@ -57,13 +57,13 @@ Q: I've got a Z instead of a C at the prompt. Q: Do I always have to type these commands? Automation? Q: How do I change to fullscreen? Q: My CD-ROM doesn't work. +Q: The game/application can't find its CD-ROM. Q: The mouse doesn't work. Q: There is no sound. Q: The sound stutters or sounds stretched/weird. Q: I can't type \ or : in DOSBox. Q: The keyboard lags. Q: The cursor always moves into one direction! -Q: The game/application can't find its CD-ROM. Q: The game/application runs much too slow! Q: The game/application does not run at all/crashes! Q: Can DOSBox harm my computer? @@ -103,18 +103,43 @@ Q: My CD-ROM doesn't work. A: To mount your CD-ROM in DOSBox you have to specify some additional options when mounting the CD-ROM. To enable CD-ROM support (includes MSCDEX): - - mount d f:\ -t cdrom - To enable low-level CD-ROM-support (uses ioctl if possible): - - mount d f:\ -t cdrom -usecd 0 - To enable low-level SDL-support: - - mount d f:\ -t cdrom -usecd 0 -noioctl - To enable low-level aspi-support (win98 with aspi-layer installed): - - mount d f:\ -t cdrom -usecd 0 -aspi + - mount d f:\ -t cdrom (windows) + - mount d /media/cdrom -t cdrom (linux) + + In some cases you might want to use a different CD-ROM interface, + for example if CD audio does not work: + To enable SDL-support (does not include low-level CD access!): + - mount d f:\ -t cdrom -usecd 0 -noioctl + To enable ioctl access using digital audio extraction for CD audio + (windows-only, useful for Vista): + - mount d f:\ -t cdrom -ioctl_dx + To enable ioctl access using MCI for CD audio (windows-only): + - mount d f:\ -t cdrom -ioctl_mci + To force ioctl-only access (windows-only): + - mount d f:\ -t cdrom -ioctl_dio + To enable low-level aspi-support (win98 with aspi-layer installed): + - mount d f:\ -t cdrom -aspi In the commands: - d driveletter you will get in DOSBox - f:\ location of CD-ROM on your PC. - - 0 The number of the CD-ROM drive, reported by mount -cd - See also the question: The game/application can't find its CD-ROM. + - 0 The number of the CD-ROM drive, reported by "mount -cd" + (note that this value is only needed when using SDL + for CD audio, otherwise it is ignored) + See also the next question: The game/application can't find its CD-ROM. + + +Q: The game/application can't find its CD-ROM. +A: Be sure to mount the CD-ROM with -t cdrom switch, this will enable the + MSCDEX interface required by DOS games to interface with CD-ROMs. + Also try adding the correct label (-label LABEL) to the mount command, + where LABEL is the CD-label (volume ID) of the CD-ROM. + Under Windows you can specify -ioctl, -aspi or -noioctl. Look at the + description of the mount command in Section 4 for their meaning and the + additional audio-CD related options -ioctl_dx, ioctl_mci, ioctl_dio. + + Try creating a CD-ROM image (preferably CUE/BIN pair) and use the + DOSBox-internal IMGMOUNT tool to mount the image (the CUE sheet). + This enables very good low-level CD-ROM support on any operating system. Q: The mouse doesn't work. @@ -160,9 +185,6 @@ A: This is a known problem. It only occurs if your keyboard layout isn't US. 6. Use ALT-58 for : and ALT-92 for \. 7. For \ try the keys around "enter". For ":" try shift and the keys between "enter" and "l" (US keyboard layout). - 8. Try keyb.com from FreeDOS (http://projects.freedos.net/keyb/). - Look for keyb2.0 pre4 as older and newer versions are known to - have a bug in the loader routines. Q: The keyboard lags. @@ -178,19 +200,6 @@ A: See if it still happens if you disable the joystick emulation, If you want to use the joystick in the game, try setting timed=false and be sure to calibrate the joystick (both in your OS as well as in the game or the game's setup program). - - -Q: The game/application can't find its CD-ROM. -A: Be sure to mount the CD-ROM with -t cdrom switch, this will enable the - MSCDEX interface required by DOS games to interface with CD-ROM's. - Also try adding the correct label (-label LABEL) to the mount command. - To enable lower-level CD-ROM support, add the following switch to mount: - -usecd #, where # is the number of your CD-ROM drive reported by mount -cd. - Under Windows you can specify -ioctl, -aspi or -noioctl. Look at the - description of the mount command in Section 4 for their meaning. - Try creating a CD-ROM image (preferably CUE/BIN pair) and use the - DOSBox-internal IMGMOUNT tool to mount the image (the CUE sheet). - This enables very good low-level CD-ROM support on any operating system. Q: The game/application runs much too slow! @@ -236,7 +245,7 @@ A: DOSBox emulates several legacy sound devices: - Adlib Borrowed from MAME, this emulation is almost perfect and includes the Adlib's ability to almost play digitized sound. - - SoundBlaster 16/ SoundBlaster Pro I & II /SoundBlaster I & II + - SoundBlaster 16 / SoundBlaster Pro I & II / SoundBlaster I & II By default DOSBox provides Soundblaster 16 level 16-bit stereo sound. You can select a different SoundBlaster version in the configfile of DOSBox (See Internal Commands: CONFIG). @@ -385,7 +394,7 @@ MOUNT -u "Emulated Drive letter" "Emulated Drive letter" The driveletter inside DOSBox (eg. C). - "Real Drive letter (usually for CD-ROM's in Windows) or Directory" + "Real Drive letter (usually for CD-ROMs in Windows) or Directory" The local directory you want accessible inside DOSBox. -t type @@ -422,19 +431,29 @@ MOUNT -u "Emulated Drive letter" Forces use of the aspi layer. Only valid if mounting a CD-ROM under Windows systems with an ASPI-Layer. - -ioctl + -ioctl (automatic selection of the CD audio interface) + -ioctl_dx (digital audio extraction used for CD audio) + -ioctl_dio (ioctl calls used for CD audio) + -ioctl_mci (MCI used for CD audio) Forces use of ioctl commands. Only valid if mounting a CD-ROM under a Windows OS which support them (Win2000/XP/NT). + The various choices only differ in the way CD audio is handled, + preferrably -ioctl_dio is used (lowest workload), but this might not + work on all systems so -ioctl_dx (or -ioctl_mci) can be used. - -noioctl + -noioctl Forces use of the SDL CD-ROM layer. Valid on all systems. -usecd number - Forces use of SDL CD-ROM support for drive number. - Number can be found by -cd. Valid on all systems. + Valid on all systems, under windows the -noioctl switch has to be + present to make use of the -usecd switch. + Enables to select the drive that should be used by SDL. Use this if + the wrong or no CD-ROM drive is mounted while using the SDL CD-ROM + interface. "number" can be found by "MOUNT -cd". -cd - Displays all detected CD-ROM drives and their numbers. Use with -usecd. + Displays all CD-ROM drives detected by SDL, and their numbers. + See the information at the -usecd entry above. -u Removes the mount. Doesn't work for Z:\. @@ -454,7 +473,7 @@ MOUNT -u "Emulated Drive letter" MOUNT C D:\OLDGAMES will allow you to run Touche from the D drive. Mounting your entire C drive with MOUNT C C:\ is NOT recommended! The same - is true for mounting the root of any other drive, except for CD-ROM's (due to + is true for mounting the root of any other drive, except for CD-ROMs (due to their read-only nature). Otherwise if you or DOSBox make a mistake you may lose all your files. It is recommended to put all your applications/games into a subdirectory @@ -579,7 +598,9 @@ MIXER mixer channel left:right [/NOSHOW] [/LISTMIDI] channel - Can be one of the following: MASTER, DISNEY, SPKR, GUS, SB, FM. + Can be one of the following: MASTER, DISNEY, SPKR, GUS, SB, FM [, CDAUDIO]. + CDAUDIO is only available if a CD-ROM interface with volume control is + enabled (CD image, ioctl_dx). left:right The volume levels in percentages. If you put a D in front it will be @@ -617,7 +638,7 @@ IMGMOUNT Location of the image files to mount in DOSBox. Specifying a number of image files is only allowed for CD-ROM images. The CD's can be swapped with CTRL-F4 at any time. This is required for games which - use multiple CD-ROM's and require the CD to be switched during the + use multiple CD-ROMs and require the CD to be switched during the gameplay at some point. -t @@ -803,6 +824,8 @@ KEYB [languagecode [codepage [codepagefile]]] 4. To load codepage 858 (without a keyboard layout): keyb none 858 This can be used to change the codepage for the FreeDOS keyb2 utility. + 5. To display the current codepage and, if loaded, the keyboard layout: + keyb @@ -819,9 +842,9 @@ ALT-PAUSE Pause emulation. CTRL-F1 Start the keymapper. CTRL-F4 Change between mounted disk-images. Update directory cache for all drives! CTRL-ALT-F5 Start/Stop creating a movie of the screen. (avi video capturing) -CTRL-F5 Save a screenshot. (png) +CTRL-F5 Save a screenshot. (PNG format) CTRL-F6 Start/Stop recording sound output to a wave file. -CTRL-ALT-F7 Start/Stop recording of OPL commands. +CTRL-ALT-F7 Start/Stop recording of OPL commands. (DRO format) CTRL-ALT-F8 Start/Stop the recording of raw MIDI commands. CTRL-F7 Decrease frameskip. CTRL-F8 Increase frameskip. @@ -947,6 +970,9 @@ in the [dos] section of the DOSBox configuration file can be used, or the internal DOSBox program keyb.com. Both accept DOS conforming language codes (see below), but only by using keyb.com a custom codepage can be specified. +The default keyboardlayout=auto currently works under windows only, the +layout is chosen according to the OS layout. + Layout switching DOSBox supports a number of keyboard layouts and codepages by default, in this case just the layout identifier needs to be specified (like From 4652da4af5886cd6ea5e61e418158707b768b907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 27 Nov 2008 18:57:45 +0000 Subject: [PATCH 3153/4131] add ems OS-dedicated handle functionality (fixes battle chess 4000 screen bug, thanks to ripsaw for debugging this), fix some ems error numbers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3241 --- src/ints/ems.cpp | 63 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 7a54ffb2..5f581f21 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.59 2008-10-05 14:44:52 qbix79 Exp $ */ +/* $Id: ems.cpp,v 1.60 2008-11-27 18:57:45 c2woody Exp $ */ #include #include @@ -57,12 +57,14 @@ #define EMM_INVALID_HANDLE 0x83 #define EMM_FUNC_NOSUP 0x84 #define EMM_OUT_OF_HANDLES 0x85 +#define EMM_SAVEMAP_ERROR 0x86 #define EMM_OUT_OF_PHYS 0x87 #define EMM_OUT_OF_LOG 0x88 #define EMM_ZERO_PAGES 0x89 #define EMM_LOG_OUT_RANGE 0x8a #define EMM_ILL_PHYS 0x8b #define EMM_PAGE_MAP_SAVED 0x8d +#define EMM_NO_SAVED_PAGE_MAP 0x8e #define EMM_INVALID_SUB 0x8f #define EMM_FEAT_NOSUP 0x91 #define EMM_MOVE_OVLAP 0x92 @@ -210,9 +212,11 @@ static bool INLINE ValidHandle(Bit16u handle) { return true; } -static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & dhandle) { +static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & dhandle,bool can_allocate_zpages) { /* Check for 0 page allocation */ - if (!pages) return EMM_ZERO_PAGES; + if (!pages) { + if (!can_allocate_zpages) return EMM_ZERO_PAGES; + } /* Check for enough free pages */ if ((MEM_FreeTotal()/ 4) < pages) { return EMM_OUT_OF_LOG;} Bit16u handle = 1; @@ -229,6 +233,21 @@ static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & dhandle) { return EMM_NO_ERROR; } +static Bit8u EMM_AllocateSystemHandle(Bit16u pages) { + /* Check for enough free pages */ + if ((MEM_FreeTotal()/ 4) < pages) { return EMM_OUT_OF_LOG;} + Bit16u handle = 0; // emm system handle (reserved for OS usage) + /* Release memory if already allocated */ + if (emm_handles[handle].pages != NULL_HANDLE) { + MEM_ReleasePages(emm_handles[handle].mem); + } + MemHandle mem = MEM_AllocatePages(pages*4,false); + if (!mem) E_Exit("EMS:System handle memory allocation failure"); + emm_handles[handle].pages = pages; + emm_handles[handle].mem = mem; + return EMM_NO_ERROR; +} + static Bit8u EMM_ReallocatePages(Bit16u handle,Bit16u & pages) { /* Check for valid handle */ if (!ValidHandle(handle)) return EMM_INVALID_HANDLE; @@ -328,10 +347,16 @@ static Bit8u EMM_MapSegment(Bitu segment,Bit16u handle,Bit16u log_page) { static Bit8u EMM_ReleaseMemory(Bit16u handle) { /* Check for valid handle */ if (!ValidHandle(handle)) return EMM_INVALID_HANDLE; + // should check for saved_page_map flag here, returning an error if it's true + // as apps are required to restore the pagemap beforehand; to be checked MEM_ReleasePages(emm_handles[handle].mem); /* Reset handle */ emm_handles[handle].mem=0; - emm_handles[handle].pages=NULL_HANDLE; + if (handle==0) { + emm_handles[handle].pages=0; // OS handle is NEVER deallocated + } else { + emm_handles[handle].pages=NULL_HANDLE; + } emm_handles[handle].saved_page_map=false; memset(&emm_handles[handle].name,0,8); return EMM_NO_ERROR; @@ -372,7 +397,7 @@ static Bit8u EMM_RestorePageMap(Bit16u handle) { if (handle!=0) return EMM_INVALID_HANDLE; } /* Check for previous save */ - if (!emm_handles[handle].saved_page_map) return EMM_INVALID_HANDLE; + if (!emm_handles[handle].saved_page_map) return EMM_NO_SAVED_PAGE_MAP; /* Restore the mappings */ emm_handles[handle].saved_page_map=false; for (Bitu i=0;i Date: Thu, 4 Dec 2008 21:09:32 +0000 Subject: [PATCH 3154/4131] fake page dirtying in some cases for memory reads if later writes can not be caught Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3242 --- src/cpu/paging.cpp | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 7bbc97a6..55806aa3 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.cpp,v 1.34 2008-05-18 13:11:14 c2woody Exp $ */ +/* $Id: paging.cpp,v 1.35 2008-12-04 21:09:32 c2woody Exp $ */ #include #include @@ -58,7 +58,7 @@ Bitu PageHandler::readd(PhysPt addr) { void PageHandler::writeb(PhysPt addr,Bitu /*val*/) { E_Exit("No byte handler for write to %d",addr); -}; +} void PageHandler::writew(PhysPt addr,Bitu val) { writeb(addr+0,(Bit8u) (val >> 0)); @@ -69,7 +69,7 @@ void PageHandler::writed(PhysPt addr,Bitu val) { writeb(addr+1,(Bit8u) (val >> 8)); writeb(addr+2,(Bit8u) (val >> 16)); writeb(addr+3,(Bit8u) (val >> 24)); -}; +} HostPt PageHandler::GetHostReadPt(Bitu /*phys_page*/) { return 0; @@ -227,6 +227,7 @@ static INLINE bool InitPageCheckPresence_CheckOnly(PhysPt lin_addr,bool writing, return true; } +// check if a user-level memory access would trigger a privilege page fault static INLINE bool InitPage_CheckUseraccess(Bitu u1,Bitu u2) { switch (CPU_ArchitectureType) { case CPU_ARCHTYPE_MIXED: @@ -348,6 +349,7 @@ public: } } if ((entry.block.wr==0) || (table.block.wr==0)) { + // page is write-protected for user mode if (priv_check==0) { switch (CPU_ArchitectureType) { case CPU_ARCHTYPE_MIXED: @@ -363,6 +365,7 @@ public: break; } } + // check if actually failing the write-protected check if (writing && USERWRITE_PROHIBITED) priv_check=3; } if (priv_check==3) { @@ -373,17 +376,28 @@ public: } if (!table.block.a) { - table.block.a=1; //Set access + table.block.a=1; // set page table accessed phys_writed((paging.base.page<<12)+(lin_page >> 10)*4,table.load); } if ((!entry.block.a) || (!entry.block.d)) { - entry.block.a=1; //Set access - if (writing) entry.block.d=1; //Set dirty + entry.block.a=1; // set page accessed + + // page is dirty if we're writing to it, or if we're reading but the + // page will be fully linked so we can't track later writes + if (writing || (priv_check==0)) entry.block.d=1; // mark page as dirty + phys_writed((table.block.base<<12)+(lin_page & 0x3ff)*4,entry.load); } + phys_page=entry.block.base; - if (priv_check==0) PAGING_LinkPage(lin_page,phys_page); - else { + + // now see how the page should be linked best, if we need to catch privilege + // checks later on it should be linked as read-only page + if (priv_check==0) { + // if reading we could link the page as read-only to later cacth writes, + // will slow down pretty much but allows catching all dirty events + PAGING_LinkPage(lin_page,phys_page); + } else { if (priv_check==1) { PAGING_LinkPage(lin_page,phys_page); return 1; @@ -754,12 +768,13 @@ void PAGING_ClearTLB(void) { } void PAGING_UnlinkPages(Bitu lin_page,Bitu pages) { - tlb_entry *entry = get_tlb_entry(lin_page<<12); for (;pages>0;pages--) { + tlb_entry *entry = get_tlb_entry(lin_page<<12); entry->read=0; entry->write=0; entry->readhandler=&init_page_handler; entry->writehandler=&init_page_handler; + lin_page++; } } From 53b9323bd7c8afc75c73f5fb8bc191354eef7883 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 11 Dec 2008 09:16:31 +0000 Subject: [PATCH 3155/4131] Slightly improve stability with some lot's of fileloading game, while being picky on the sound irq timing. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3243 --- src/dos/dos.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index d5260132..01c7d90c 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.113 2008-09-07 10:55:14 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.114 2008-12-11 09:16:31 qbix79 Exp $ */ #include #include @@ -46,7 +46,13 @@ void DOS_SetError(Bit16u code) { #ifdef DATA_TRANSFERS_TAKE_CYCLES #include "cpu.h" static inline void modify_cycles(Bits value) { - if((4*value+5) < CPU_Cycles) CPU_Cycles -= 4*value; else CPU_Cycles = 5; + if((4*value+5) < CPU_Cycles) { + CPU_Cycles -= 4*value; + CPU_IODelayRemoved += 4*value; + } else { + CPU_IODelayRemoved += CPU_Cycles/*-5*/; //don't want to mess with negative + CPU_Cycles = 5; + } } #else static inline void modify_cycles(Bits /* value */) { From 975a2d424791d1961422016042bfb88160480ff3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 11 Dec 2008 20:45:43 +0000 Subject: [PATCH 3156/4131] Improve find_device so it supports weird input c:NUL and C:/hi. Makes DOSBox even more compatible with turbo 2.01 installer. (no nul file left on linux anymore) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3244 --- src/dos/dos_devices.cpp | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 0a2bfab4..9466a664 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_devices.cpp,v 1.20 2008-08-11 13:09:44 qbix79 Exp $ */ +/* $Id: dos_devices.cpp,v 1.21 2008-12-11 20:45:43 qbix79 Exp $ */ #include #include "dosbox.h" @@ -122,31 +122,32 @@ DOS_File & DOS_File::operator= (const DOS_File & orig) { Bit8u DOS_FindDevice(char const * name) { /* should only check for the names before the dot and spacepadded */ - // STDAUX is alias for COM1 - // A bit of a hack, but no application will probably use stdaux to determine wether a directory exists - if (strcasecmp(name, "STDAUX") == 0) name = "COM1"; - if (strcasecmp(name, "PRN") == 0) name = "LPT1"; + char fullname[DOS_PATHLENGTH];Bit8u drive; +// if(!name || !(*name)) return DOS_DEVICES; //important, but makename does it + if (!DOS_MakeName(name,fullname,&drive)) return DOS_DEVICES; - char temp[CROSS_LEN];//TODO - if(!name || !(*name)) return DOS_DEVICES; - strcpy(temp,name); - - char* name_start = strrchr(temp,'\\'); - if(name_start) { - //Directory found in front of the filename. Check it's path - *name_start++ = 0; - Bit8u drive;char fulldir[DOS_PATHLENGTH]; - if (!DOS_MakeName(temp,fulldir,&drive)) return DOS_DEVICES; - if(!Drives[drive]->TestDir(fulldir)) return DOS_DEVICES; - } else name_start = temp; - - char* dot = strrchr(name_start,'.'); + char* name_part = strrchr(fullname,'\\'); + if(name_part) { + *name_part++ = 0; + //Check validity of leading directory. + if(!Drives[drive]->TestDir(fullname)) return DOS_DEVICES; + } else name_part = fullname; + + char* dot = strrchr(name_part,'.'); if(dot) *dot = 0; //no ext checking + static char com[5] = { 'C','O','M','1',0 }; + static char lpt[5] = { 'L','P','T','1',0 }; + // AUX is alias for COM1 and PRN for LPT1 + // A bit of a hack. (but less then before). + // no need for casecmp as makename returns uppercase + if (strcmp(name_part, "AUX") == 0) name_part = com; + if (strcmp(name_part, "PRN") == 0) name_part = lpt; + /* loop through devices */ for(Bit8u index = 0;index < DOS_DEVICES;index++) { if (Devices[index]) { - if (WildFileCmp(name_start,Devices[index]->name)) return index; + if (WildFileCmp(name_part,Devices[index]->name)) return index; } } return DOS_DEVICES; From 2553d6230afe48ccce12f10a7f5eef034c3380d8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 15 Dec 2008 16:20:07 +0000 Subject: [PATCH 3157/4131] Only support SDL 1.2.x Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3245 --- configure.in | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/configure.in b/configure.in index a773aa0c..26ac8272 100644 --- a/configure.in +++ b/configure.in @@ -36,6 +36,16 @@ AM_PATH_SDL($SDL_VERSION, LIBS="$LIBS $SDL_LIBS" CPPFLAGS="$CPPFLAGS $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([AC_LANG_PROGRAM([[#include "SDL.h"]],[[ +#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 typedefs, structures, and compiler characteristics. From 32d6ebc48af4e6e2d9a8715a6f7080a2a4830c3a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 15 Dec 2008 16:23:34 +0000 Subject: [PATCH 3158/4131] add some beautification quote Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3246 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 26ac8272..6ca9c561 100644 --- a/configure.in +++ b/configure.in @@ -40,7 +40,7 @@ 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([AC_LANG_PROGRAM([[#include "SDL.h"]],[[ #if SDL_MINOR_VERSION != 2 -#error "Only SDL 1.2 supported +#error "Only SDL 1.2 supported" #endif ]])],AC_MSG_RESULT([yes]),[ AC_MSG_RESULT([no]) From 4e63ba6dd8e96d53597c2d26f9cfbc94c7f31dfa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 18 Dec 2008 07:54:28 +0000 Subject: [PATCH 3159/4131] Hopefully fix configure test on windows Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3247 --- configure.in | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 6ca9c561..3ac3a61a 100644 --- a/configure.in +++ b/configure.in @@ -38,11 +38,15 @@ CPPFLAGS="$CPPFLAGS $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([AC_LANG_PROGRAM([[#include "SDL.h"]],[[ +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([yes]),[ AC_MSG_RESULT([no]) AC_MSG_ERROR([Only libSDL 1.2.X supported])]) From c8f8013bb889a3825e3740d46a85aef5724844a6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 19 Dec 2008 15:20:35 +0000 Subject: [PATCH 3160/4131] Improve handling when one dosbox is closed.(fixed by hal reported by ariel) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3248 --- src/hardware/serialport/nullmodem.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/serialport/nullmodem.cpp b/src/hardware/serialport/nullmodem.cpp index 2c017460..c11186d6 100644 --- a/src/hardware/serialport/nullmodem.cpp +++ b/src/hardware/serialport/nullmodem.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: nullmodem.cpp,v 1.4 2008-07-05 08:54:59 c2woody Exp $ */ +/* $Id: nullmodem.cpp,v 1.5 2008-12-19 15:20:35 qbix79 Exp $ */ #include "dosbox.h" @@ -233,7 +233,7 @@ void CNullModem::Disconnect() { LOG_MSG("Serial%d: Disconnected.",idnumber+1); delete clientsocket; clientsocket=0; - setDTR(false); + setDSR(false); setCTS(false); if(serverport) { serversocket = new TCPServerSocket(serverport); From bfca020e7459c55e4a0705b413db17e369d4f0e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 28 Dec 2008 20:22:12 +0000 Subject: [PATCH 3161/4131] enhance s3 hardware cursor routines (hal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3249 --- src/hardware/vga_draw.cpp | 331 +++++++++++++++----------------------- src/hardware/vga_s3.cpp | 11 +- 2 files changed, 137 insertions(+), 205 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 4f91ea17..01ea8db6 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.103 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.104 2008-12-28 20:22:12 c2woody Exp $ */ #include #include @@ -170,7 +170,7 @@ static Bit8u * VGA_Draw_Changes_Line(Bitu vidstart, Bitu line) { #endif -static Bit8u * VGA_Draw_Linear_Line(Bitu vidstart, Bitu line) { +static Bit8u * VGA_Draw_Linear_Line(Bitu vidstart, Bitu /*line*/) { // There is guaranteed extra memory past the wrap boundary. So, instead of using temporary // storage just copy appropriate chunk from the beginning to the wrap boundary when needed. Bitu offset = vidstart & vga.draw.linear_mask; @@ -186,7 +186,7 @@ static Bit8u * VGA_Draw_Linear_Line(Bitu vidstart, Bitu line) { return ret; } -static Bit8u * VGA_Draw_Xlat16_Linear_Line(Bitu vidstart, Bitu line) { +static Bit8u * VGA_Draw_Xlat16_Linear_Line(Bitu vidstart, Bitu /*line*/) { Bit8u *ret = &vga.draw.linear_base[ vidstart & vga.draw.linear_mask ]; Bit16u* temps = (Bit16u*) TempLine; for(Bitu i = 0; i < vga.draw.line_length; i++) { @@ -213,207 +213,134 @@ static Bit8u * VGA_Draw_Xlat16_Linear_Line(Bitu vidstart, Bitu line) { return TempLine; } */ -static Bit8u * VGA_Draw_VGA_Line_HWMouse( Bitu vidstart, Bitu line) { - bool hwcursor_active=false; - if (svga.hardware_cursor_active) { - if (svga.hardware_cursor_active()) hwcursor_active=true; - } - if (hwcursor_active) { - Bitu lineat = (vidstart-(vga.config.real_start<<2)) / vga.draw.width; - if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) { - return &vga.mem.linear[ vidstart ]; - } else { - memcpy(TempLine, &vga.mem.linear[ vidstart ], vga.draw.width); - /* Draw mouse cursor */ - Bits moff = ((Bits)lineat - (Bits)vga.s3.hgc.originy) + (Bits)vga.s3.hgc.posy; - if(moff>63) return &vga.mem.linear[ vidstart ]; - if(moff<0) moff+=64; - Bitu xat = vga.s3.hgc.originx; - Bitu m, mapat; - Bits r, z; - mapat = 0; +static Bit8u * VGA_Draw_VGA_Line_HWMouse( Bitu vidstart, Bitu /*line*/) { + if (!svga.hardware_cursor_active || !svga.hardware_cursor_active()) + // HW Mouse not enabled, use the tried and true call + return &vga.mem.linear[vidstart]; - Bitu mouseaddr = (Bit32u)vga.s3.hgc.startaddr * (Bit32u)1024; - mouseaddr+=(moff * 16); - - Bit16u bitsA, bitsB; - Bit8u mappoint; - for(m=0;m<4;m++) { - bitsA = *(Bit16u *)&vga.mem.linear[mouseaddr]; - mouseaddr+=2; - bitsB = *(Bit16u *)&vga.mem.linear[mouseaddr]; - mouseaddr+=2; - z = 7; - for(r=15;r>=0;--r) { - mappoint = (((bitsA >> z) & 0x1) << 1) | ((bitsB >> z) & 0x1); - if(mapat >= vga.s3.hgc.posx) { - switch(mappoint) { - case 0: - TempLine[xat] = vga.s3.hgc.backstack[0]; - break; - case 1: - TempLine[xat] = vga.s3.hgc.forestack[0]; - break; - case 2: - //Transparent - break; - case 3: - // Invert screen data - TempLine[xat] = ~TempLine[xat]; - break; - } - xat++; - } - mapat++; - --z; - if(z<0) z=15; - } - } - return TempLine; - } - } else { - /* HW Mouse not enabled, use the tried and true call */ + Bitu lineat = (vidstart-(vga.config.real_start<<2)) / vga.draw.width; + if ((vga.s3.hgc.posx >= vga.draw.width) || + (lineat < vga.s3.hgc.originy) || + (lineat > (vga.s3.hgc.originy + (63U-vga.s3.hgc.posy))) ) { + // the mouse cursor *pattern* is not on this line return &vga.mem.linear[ vidstart ]; + } else { + // Draw mouse cursor: cursor is a 64x64 pattern which is shifted (inside the + // 64x64 mouse cursor space) to the right by posx pixels and up by posy pixels. + // This is used when the mouse cursor partially leaves the screen. + // It is arranged as bitmap of 16bits of bitA followed by 16bits of bitB, each + // AB bits corresponding to a cursor pixel. The whole map is 8kB in size. + memcpy(TempLine, &vga.mem.linear[ vidstart ], vga.draw.width); + // the index of the bit inside the cursor bitmap we start at: + Bitu sourceStartBit = ((lineat - vga.s3.hgc.originy) + vga.s3.hgc.posy)*64 + vga.s3.hgc.posx; + // convert to video memory addr and bit index + // start adjusted to the pattern structure (thus shift address by 2 instead of 3) + // Need to get rid of the third bit, so "/8 *2" becomes ">> 2 & ~1" + Bitu cursorMemStart = ((sourceStartBit >> 2)& ~1) + (((Bit32u)vga.s3.hgc.startaddr) << 10); + Bitu cursorStartBit = sourceStartBit & 0x7; + // stay at the right position in the pattern + if (cursorMemStart & 0x2) cursorMemStart--; + Bitu cursorMemEnd = cursorMemStart + ((64-vga.s3.hgc.posx) >> 2); + Bit8u* xat = &TempLine[vga.s3.hgc.originx]; // mouse data start pos. in scanline + for (Bitu m = cursorMemStart; m < cursorMemEnd; (m&1)?(m+=3):m++) { + // for each byte of cursor data + Bit8u bitsA = vga.mem.linear[m]; + Bit8u bitsB = vga.mem.linear[m+2]; + for (Bit8u bit=(0x80 >> cursorStartBit); bit != 0; bit >>= 1) { + // for each bit + cursorStartBit=0; // only the first byte has some bits cut off + if (bitsA&bit) { + if (bitsB&bit) *xat ^= 0xFF; // Invert screen data + //else Transparent + } else if (bitsB&bit) { + *xat = vga.s3.hgc.forestack[0]; // foreground color + } else { + *xat = vga.s3.hgc.backstack[0]; + } + xat++; + } + } + return TempLine; } } -static Bit8u * VGA_Draw_LIN16_Line_HWMouse(Bitu vidstart, Bitu line) { - bool hwcursor_active=false; - if (svga.hardware_cursor_active) { - if (svga.hardware_cursor_active()) hwcursor_active=true; - } - if (hwcursor_active) { - Bitu lineat = ((vidstart-(vga.config.real_start<<2)) >> 1) / vga.draw.width; - if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) { - return &vga.mem.linear[ vidstart ]; - } else { - memcpy(TempLine, &vga.mem.linear[ vidstart ], 2*vga.draw.width); - /* Draw mouse cursor */ - Bits moff = ((Bits)lineat - (Bits)vga.s3.hgc.originy) + (Bits)vga.s3.hgc.posy; - if(moff>63) return &vga.mem.linear[ vidstart ]; - if(moff<0) moff+=64; - Bitu xat = 2*vga.s3.hgc.originx; - Bitu m, mapat; - Bits r, z; - mapat = 0; +static Bit8u * VGA_Draw_LIN16_Line_HWMouse(Bitu vidstart, Bitu /*line*/) { + if (!svga.hardware_cursor_active || !svga.hardware_cursor_active()) + return &vga.mem.linear[vidstart]; - Bitu mouseaddr = (Bit32u)vga.s3.hgc.startaddr * (Bit32u)1024; - mouseaddr+=(moff * 16); - - Bit16u bitsA, bitsB; - Bit8u mappoint; - for(m=0;m<4;m++) { - bitsA = *(Bit16u *)&vga.mem.linear[mouseaddr]; - mouseaddr+=2; - bitsB = *(Bit16u *)&vga.mem.linear[mouseaddr]; - mouseaddr+=2; - z = 7; - for(r=15;r>=0;--r) { - mappoint = (((bitsA >> z) & 0x1) << 1) | ((bitsB >> z) & 0x1); - if(mapat >= vga.s3.hgc.posx) { - switch(mappoint) { - case 0: - TempLine[xat] = vga.s3.hgc.backstack[0]; - TempLine[xat+1] = vga.s3.hgc.backstack[1]; - break; - case 1: - TempLine[xat] = vga.s3.hgc.forestack[0]; - TempLine[xat+1] = vga.s3.hgc.forestack[1]; - break; - case 2: - //Transparent - break; - case 3: - // Invert screen data - TempLine[xat] = ~TempLine[xat]; - TempLine[xat+1] = ~TempLine[xat+1]; - break; - } - xat+=2; - } - mapat++; - --z; - if(z<0) z=15; - } - } - return TempLine; - } + Bitu lineat = ((vidstart-(vga.config.real_start<<2)) >> 1) / vga.draw.width; + if ((vga.s3.hgc.posx >= vga.draw.width) || + (lineat < vga.s3.hgc.originy) || + (lineat > (vga.s3.hgc.originy + (63U-vga.s3.hgc.posy))) ) { + return &vga.mem.linear[vidstart]; } else { - /* HW Mouse not enabled, use the tried and true call */ - return &vga.mem.linear[ vidstart ]; + memcpy(TempLine, &vga.mem.linear[ vidstart ], vga.draw.width*2); + Bitu sourceStartBit = ((lineat - vga.s3.hgc.originy) + vga.s3.hgc.posy)*64 + vga.s3.hgc.posx; + Bitu cursorMemStart = ((sourceStartBit >> 2)& ~1) + (((Bit32u)vga.s3.hgc.startaddr) << 10); + Bitu cursorStartBit = sourceStartBit & 0x7; + if (cursorMemStart & 0x2) cursorMemStart--; + Bitu cursorMemEnd = cursorMemStart + ((64-vga.s3.hgc.posx) >> 2); + Bit16u* xat = &((Bit16u*)TempLine)[vga.s3.hgc.originx]; + for (Bitu m = cursorMemStart; m < cursorMemEnd; (m&1)?(m+=3):m++) { + // for each byte of cursor data + Bit8u bitsA = vga.mem.linear[m]; + Bit8u bitsB = vga.mem.linear[m+2]; + for (Bit8u bit=(0x80 >> cursorStartBit); bit != 0; bit >>= 1) { + // for each bit + cursorStartBit=0; + if (bitsA&bit) { + // byte order doesn't matter here as all bits get flipped + if (bitsB&bit) *xat ^= ~0U; + //else Transparent + } else if (bitsB&bit) { + // Source as well as destination are Bit8u arrays, + // so this should work out endian-wise? + *xat = *(Bit16u*)vga.s3.hgc.forestack; + } else { + *xat = *(Bit16u*)vga.s3.hgc.backstack; + } + xat++; + } + } + return TempLine; } } -static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart, Bitu line) { - bool hwcursor_active=false; - if (svga.hardware_cursor_active) { - if (svga.hardware_cursor_active()) hwcursor_active=true; - } - if (hwcursor_active) { - Bitu lineat = ((vidstart-(vga.config.real_start<<2)) >> 2) / vga.draw.width; - if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) { - return &vga.mem.linear[ vidstart ]; - } else { - memcpy(TempLine, &vga.mem.linear[ vidstart ], 4*vga.draw.width); - /* Draw mouse cursor */ - Bits moff = ((Bits)lineat - (Bits)vga.s3.hgc.originy) + (Bits)vga.s3.hgc.posy; - if(moff>63) return &vga.mem.linear[ vidstart ]; - if(moff<0) moff+=64; - Bitu xat = 4*vga.s3.hgc.originx; - Bitu m, mapat; - Bits r, z; - mapat = 0; +static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart, Bitu /*line*/) { + if (!svga.hardware_cursor_active || !svga.hardware_cursor_active()) + return &vga.mem.linear[vidstart]; - Bitu mouseaddr = (Bit32u)vga.s3.hgc.startaddr * (Bit32u)1024; - mouseaddr+=(moff * 16); - - Bit16u bitsA, bitsB; - Bit8u mappoint; - for(m=0;m<4;m++) { - bitsA = *(Bit16u *)&vga.mem.linear[mouseaddr]; - mouseaddr+=2; - bitsB = *(Bit16u *)&vga.mem.linear[mouseaddr]; - mouseaddr+=2; - z = 7; - for(r=15;r>=0;--r) { - mappoint = (((bitsA >> z) & 0x1) << 1) | ((bitsB >> z) & 0x1); - if(mapat >= vga.s3.hgc.posx) { - switch(mappoint) { - case 0: - TempLine[xat] = vga.s3.hgc.backstack[0]; - TempLine[xat+1] = vga.s3.hgc.backstack[1]; - TempLine[xat+2] = vga.s3.hgc.backstack[2]; - TempLine[xat+3] = 255; - break; - case 1: - TempLine[xat] = vga.s3.hgc.forestack[0]; - TempLine[xat+1] = vga.s3.hgc.forestack[1]; - TempLine[xat+2] = vga.s3.hgc.forestack[2]; - TempLine[xat+3] = 255; - break; - case 2: - //Transparent - break; - case 3: - // Invert screen data - TempLine[xat] = ~TempLine[xat]; - TempLine[xat+1] = ~TempLine[xat+1]; - TempLine[xat+2] = ~TempLine[xat+2]; - TempLine[xat+3] = ~TempLine[xat+3]; - break; - } - xat+=4; - } - mapat++; - --z; - if(z<0) z=15; - } - } - return TempLine; - } - } else { - /* HW Mouse not enabled, use the tried and true call */ + Bitu lineat = ((vidstart-(vga.config.real_start<<2)) >> 2) / vga.draw.width; + if ((vga.s3.hgc.posx >= vga.draw.width) || + (lineat < vga.s3.hgc.originy) || + (lineat > (vga.s3.hgc.originy + (63U-vga.s3.hgc.posy))) ) { return &vga.mem.linear[ vidstart ]; + } else { + memcpy(TempLine, &vga.mem.linear[ vidstart ], vga.draw.width*4); + Bitu sourceStartBit = ((lineat - vga.s3.hgc.originy) + vga.s3.hgc.posy)*64 + vga.s3.hgc.posx; + Bitu cursorMemStart = ((sourceStartBit >> 2)& ~1) + (((Bit32u)vga.s3.hgc.startaddr) << 10); + Bitu cursorStartBit = sourceStartBit & 0x7; + if (cursorMemStart & 0x2) cursorMemStart--; + Bitu cursorMemEnd = cursorMemStart + ((64-vga.s3.hgc.posx) >> 2); + Bit32u* xat = &((Bit32u*)TempLine)[vga.s3.hgc.originx]; + for (Bitu m = cursorMemStart; m < cursorMemEnd; (m&1)?(m+=3):m++) { + // for each byte of cursor data + Bit8u bitsA = vga.mem.linear[m]; + Bit8u bitsB = vga.mem.linear[m+2]; + for (Bit8u bit=(0x80 >> cursorStartBit); bit != 0; bit >>= 1) { // for each bit + cursorStartBit=0; + if (bitsA&bit) { + if (bitsB&bit) *xat ^= ~0U; + //else Transparent + } else if (bitsB&bit) { + *xat = *(Bit32u*)vga.s3.hgc.forestack; + } else { + *xat = *(Bit32u*)vga.s3.hgc.backstack; + } + xat++; + } + } + return TempLine; } } @@ -488,8 +415,8 @@ skip_cursor: static Bit8u * VGA_TEXT_Draw_Line_9(Bitu vidstart, Bitu line) { Bits font_addr; Bit8u * draw=(Bit8u *)TempLine; - bool underline=(vga.crtc.underline_location&0x1f)==line; - Bit8u pel_pan=vga.draw.panning; + bool underline=(Bitu)(vga.crtc.underline_location&0x1f)==line; + Bit8u pel_pan=(Bit8u)vga.draw.panning; if ((vga.attr.mode_control&0x20) && (vga.draw.lines_done>=vga.draw.split_line)) pel_pan=0; const Bit8u *vidmem = &vga.tandy.draw_base[vidstart]; Bit8u chr=vidmem[0]; @@ -547,8 +474,8 @@ skip_cursor: static Bit8u * VGA_TEXT_Xlat16_Draw_Line_9(Bitu vidstart, Bitu line) { Bits font_addr; Bit16u * draw=(Bit16u *)TempLine; - bool underline=(vga.crtc.underline_location&0x1f)==line; - Bit8u pel_pan=vga.draw.panning; + bool underline=(Bitu)(vga.crtc.underline_location&0x1f)==line; + Bit8u pel_pan=(Bit8u)vga.draw.panning; if ((vga.attr.mode_control&0x20) && (vga.draw.lines_done>=vga.draw.split_line)) pel_pan=0; const Bit8u *vidmem = &vga.tandy.draw_base[vidstart]; Bit8u chr=vidmem[0]; @@ -639,7 +566,7 @@ static void VGA_ProcessSplit() { vga.draw.address_line=0; } -static void VGA_DrawSingleLine(Bitu blah) { +static void VGA_DrawSingleLine(Bitu /*blah*/) { if(vga.attr.enabled || (!(vga.mode==M_VGA || vga.mode==M_EGA))) { Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line ); RENDER_DrawLine(data); @@ -732,22 +659,22 @@ static void INLINE VGA_ChangesStart( void ) { } #endif -static void VGA_VertInterrupt(Bitu val) { +static void VGA_VertInterrupt(Bitu /*val*/) { if ((!vga.draw.vret_triggered) && ((vga.crtc.vertical_retrace_end&0x30)==0x10)) { vga.draw.vret_triggered=true; if (GCC_UNLIKELY(machine==MCH_EGA)) PIC_ActivateIRQ(9); } } -static void VGA_DisplayStartLatch(Bitu val) { +static void VGA_DisplayStartLatch(Bitu /*val*/) { vga.config.real_start=vga.config.display_start & (vga.vmemwrap-1); } -static void VGA_PanningLatch(Bitu val) { +static void VGA_PanningLatch(Bitu /*val*/) { vga.draw.panning = vga.config.pel_panning; } -static void VGA_VerticalTimer(Bitu val) { +static void VGA_VerticalTimer(Bitu /*val*/) { double error = vga.draw.delay.framestart; vga.draw.delay.framestart = PIC_FullIndex(); error = vga.draw.delay.framestart - error - vga.draw.delay.vtotal; @@ -936,7 +863,7 @@ void VGA_ActivateHardwareCursor(void) { } } -void VGA_SetupDrawing(Bitu val) { +void VGA_SetupDrawing(Bitu /*val*/) { if (vga.mode==M_ERROR) { PIC_RemoveEvents(VGA_VerticalTimer); PIC_RemoveEvents(VGA_PanningLatch); diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index d1b6e2c5..2f6c283c 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_s3.cpp,v 1.16 2008-08-08 21:57:00 c2woody Exp $ */ +/* $Id: vga_s3.cpp,v 1.17 2008-12-28 20:22:12 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -127,16 +127,21 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { case 0x4c: /* HGC start address high byte*/ vga.s3.hgc.startaddr &=0xff; vga.s3.hgc.startaddr |= ((val & 0xf) << 8); + if ((((Bitu)vga.s3.hgc.startaddr)<<10)+((64*64*2)/8) > vga.vmemsize) { + vga.s3.hgc.startaddr &= 0xff; // put it back to some sane area; + // if read back of this address is ever implemented this needs to change + LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:S3:CRTC: HGC pattern address beyond video memory" ); + } break; case 0x4d: /* HGC start address low byte*/ vga.s3.hgc.startaddr &=0xff00; vga.s3.hgc.startaddr |= (val & 0xff); break; case 0x4e: /* HGC pattern start X */ - vga.s3.hgc.posx = val; + vga.s3.hgc.posx = val & 0x3f; // bits 0-5 break; case 0x4f: /* HGC pattern start Y */ - vga.s3.hgc.posy = val; + vga.s3.hgc.posy = val & 0x3f; // bits 0-5 break; case 0x50: // Extended System Control 1 vga.s3.reg_50 = val; From 615f21836ad612125139ff10079d17e8b6b1fbf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 29 Dec 2008 14:41:05 +0000 Subject: [PATCH 3162/4131] fix mode7 vga attribute register mapping (hal/ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3250 --- src/ints/int10_modes.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 5e1484c7..181c3a70 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.81 2008-11-08 12:56:50 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.82 2008-12-29 14:41:05 c2woody Exp $ */ #include @@ -1042,11 +1042,20 @@ bool INT10_SetVideoMode(Bitu mode) { } real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x30); att_text16: - for (i=0;i<8;i++) { - att_data[i]=i; - att_data[i+8]=i+0x38; + if (CurMode->mode==7) { + att_data[0]=0x00; + att_data[8]=0x10; + for (i=1; i<8; i++) { + att_data[i]=0x08; + att_data[i+8]=0x18; + } + } else { + for (i=0;i<8;i++) { + att_data[i]=i; + att_data[i+8]=i+0x38; + } + if (IS_VGA_ARCH) att_data[0x06]=0x14; //Odd Color 6 yellow/brown. } - if (IS_VGA_ARCH) att_data[0x06]=0x14; //Odd Color 6 yellow/brown. break; case M_CGA2: att_data[0x10]=0x01; //Color Graphics From 4c781ee42911b19821ec1045cdfdfc1adaa8da87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 31 Dec 2008 16:33:46 +0000 Subject: [PATCH 3163/4131] add evdev-kbd compatible scancode remapping (disabled atm) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3251 --- src/gui/sdl_mapper.cpp | 59 ++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 88aa0a9d..9d4b1a61 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.51 2008-11-09 10:38:21 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.52 2008-12-31 16:33:46 c2woody Exp $ */ #include #include @@ -1617,7 +1617,7 @@ static struct { static void change_action_text(const char* text,Bit8u col) { - bind_but.action->Change(text); + bind_but.action->Change(text,""); bind_but.action->SetColor(col); } @@ -2216,7 +2216,7 @@ static void CreateBindGroups(void) { if (mapper.sticks.num) SDL_JoystickEventState(SDL_DISABLE); #else // enable joystick event handling - if (numsticks) SDL_JoystickEventState(SDL_ENABLE); + if (mapper.sticks.num) SDL_JoystickEventState(SDL_ENABLE); else return; #endif Bit8u joyno=0; @@ -2378,22 +2378,43 @@ void MAPPER_StartUp(Section * sec) { sdlkey_map[0x40]=SDLK_KP5; sdlkey_map[0x41]=SDLK_KP6; #elif !defined (WIN32) /* => Linux */ - sdlkey_map[0x5a]=SDLK_UP; - sdlkey_map[0x60]=SDLK_DOWN; - sdlkey_map[0x5c]=SDLK_LEFT; - sdlkey_map[0x5e]=SDLK_RIGHT; - sdlkey_map[0x59]=SDLK_HOME; - sdlkey_map[0x5f]=SDLK_END; - sdlkey_map[0x5b]=SDLK_PAGEUP; - sdlkey_map[0x61]=SDLK_PAGEDOWN; - sdlkey_map[0x62]=SDLK_INSERT; - sdlkey_map[0x63]=SDLK_DELETE; - sdlkey_map[0x68]=SDLK_KP_DIVIDE; - sdlkey_map[0x64]=SDLK_KP_ENTER; - sdlkey_map[0x65]=SDLK_RCTRL; - sdlkey_map[0x66]=SDLK_PAUSE; - sdlkey_map[0x67]=SDLK_PRINT; - sdlkey_map[0x69]=SDLK_RALT; + bool evdev_input = false; + + if (evdev_input) { + sdlkey_map[0x67]=SDLK_UP; + sdlkey_map[0x6c]=SDLK_DOWN; + sdlkey_map[0x69]=SDLK_LEFT; + sdlkey_map[0x6a]=SDLK_RIGHT; + sdlkey_map[0x66]=SDLK_HOME; + sdlkey_map[0x6b]=SDLK_END; + sdlkey_map[0x68]=SDLK_PAGEUP; + sdlkey_map[0x6d]=SDLK_PAGEDOWN; + sdlkey_map[0x6e]=SDLK_INSERT; + sdlkey_map[0x6f]=SDLK_DELETE; + sdlkey_map[0x62]=SDLK_KP_DIVIDE; + sdlkey_map[0x60]=SDLK_KP_ENTER; + sdlkey_map[0x61]=SDLK_RCTRL; + sdlkey_map[0x77]=SDLK_PAUSE; + sdlkey_map[0x63]=SDLK_PRINT; + sdlkey_map[0x64]=SDLK_RALT; + } else { + sdlkey_map[0x5a]=SDLK_UP; + sdlkey_map[0x60]=SDLK_DOWN; + sdlkey_map[0x5c]=SDLK_LEFT; + sdlkey_map[0x5e]=SDLK_RIGHT; + sdlkey_map[0x59]=SDLK_HOME; + sdlkey_map[0x5f]=SDLK_END; + sdlkey_map[0x5b]=SDLK_PAGEUP; + sdlkey_map[0x61]=SDLK_PAGEDOWN; + sdlkey_map[0x62]=SDLK_INSERT; + sdlkey_map[0x63]=SDLK_DELETE; + sdlkey_map[0x68]=SDLK_KP_DIVIDE; + sdlkey_map[0x64]=SDLK_KP_ENTER; + sdlkey_map[0x65]=SDLK_RCTRL; + sdlkey_map[0x66]=SDLK_PAUSE; + sdlkey_map[0x67]=SDLK_PRINT; + sdlkey_map[0x69]=SDLK_RALT; + } #else sdlkey_map[0xc8]=SDLK_UP; sdlkey_map[0xd0]=SDLK_DOWN; From 87c8c10eb6115ebbc0389ea13ca1f17a4292a9d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 1 Jan 2009 22:36:03 +0000 Subject: [PATCH 3164/4131] switch to old style volume for opl2mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3252 --- src/hardware/ymf262.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/ymf262.c b/src/hardware/ymf262.c index 5fa9ba69..25b5c3f0 100644 --- a/src/hardware/ymf262.c +++ b/src/hardware/ymf262.c @@ -2081,8 +2081,8 @@ static void OPL3WriteReg(OPL3 *chip, int r, int v) int base = ((r&0xf) + ch_offset) * 2; /* OPL2 mode - always enabled */ - chip->pan[ base ] = 1; /* ch.A */ - chip->pan[ base +1 ] = 1; /* ch.B */ + chip->pan[ base ] = 2; /* ch.A */ + chip->pan[ base +1 ] = 2; /* ch.B */ } CH->SLOT[SLOT1].FB = (v>>1)&7 ? ((v>>1)&7) + 7 : 0; From c680a2b46ca25755e0a645d6bd7f8ca2358f3eea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 2 Jan 2009 19:30:53 +0000 Subject: [PATCH 3165/4131] add alternative mono-palette for mode7 (hal, thanks to ripsaw for reporting this) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3253 --- src/ints/int10_modes.cpp | 51 ++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 181c3a70..f86abf2f 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.82 2008-12-29 14:41:05 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.83 2009-01-02 19:30:53 c2woody Exp $ */ #include @@ -247,6 +247,18 @@ static Bit8u text_palette[64][3]= }; static Bit8u mtext_palette[64][3]= +{ + {0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00}, + {0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a}, + {0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00}, + {0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f}, + {0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00}, + {0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a}, + {0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00}, + {0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f},{0x3f,0x3f,0x3f} +}; + +static Bit8u mtext_s3_palette[64][3]= { {0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00}, {0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a},{0x2a,0x2a,0x2a}, @@ -1100,12 +1112,20 @@ att_text16: IO_Write(0x3c8,0); switch (CurMode->type) { case M_EGA: - if (CurMode->mode>0xf) goto dac_text16; - else if (CurMode->mode==0xf) goto dac_mtext16; - for (i=0;i<64;i++) { - IO_Write(0x3c9,ega_palette[i][0]); - IO_Write(0x3c9,ega_palette[i][1]); - IO_Write(0x3c9,ega_palette[i][2]); + if (CurMode->mode>0xf) { + goto dac_text16; + } else if (CurMode->mode==0xf) { + for (i=0;i<64;i++) { + IO_Write(0x3c9,mtext_s3_palette[i][0]); + IO_Write(0x3c9,mtext_s3_palette[i][1]); + IO_Write(0x3c9,mtext_s3_palette[i][2]); + } + } else { + for (i=0;i<64;i++) { + IO_Write(0x3c9,ega_palette[i][0]); + IO_Write(0x3c9,ega_palette[i][1]); + IO_Write(0x3c9,ega_palette[i][2]); + } } break; case M_CGA2: @@ -1119,11 +1139,18 @@ att_text16: break; case M_TEXT: if (CurMode->mode==7) { -dac_mtext16: - for (i=0;i<64;i++) { - IO_Write(0x3c9,mtext_palette[i][0]); - IO_Write(0x3c9,mtext_palette[i][1]); - IO_Write(0x3c9,mtext_palette[i][2]); + if ((IS_VGA_ARCH) && (svgaCard == SVGA_S3Trio)) { + for (i=0;i<64;i++) { + IO_Write(0x3c9,mtext_s3_palette[i][0]); + IO_Write(0x3c9,mtext_s3_palette[i][1]); + IO_Write(0x3c9,mtext_s3_palette[i][2]); + } + } else { + for (i=0;i<64;i++) { + IO_Write(0x3c9,mtext_palette[i][0]); + IO_Write(0x3c9,mtext_palette[i][1]); + IO_Write(0x3c9,mtext_palette[i][2]); + } } break; } //FALLTHROUGH!!!! From 0e07688f1a1bd4ddcb90d19fd1dac09fecbacf34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 7 Jan 2009 22:39:18 +0000 Subject: [PATCH 3166/4131] don't accidentally switch to different ioctl/cdda player interface when media status changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3254 --- src/dos/cdrom_ioctl_win32.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index 299f9585..0f60cfb8 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_ioctl_win32.cpp,v 1.15 2008-11-06 19:31:21 c2woody Exp $ */ +/* $Id: cdrom_ioctl_win32.cpp,v 1.16 2009-01-07 22:39:18 c2woody Exp $ */ #if defined (WIN32) @@ -370,9 +370,11 @@ bool CDROM_Interface_Ioctl::GetMediaTrayStatus(bool& mediaPresent, bool& mediaCh // Open new medium Open(); - // check this (what to do if cd is ejected): - use_mciplay = false; - if (!mci_CDOpen(pathname[4])) use_mciplay = true; + if (cdioctl_cda_selected == CDIOCTL_CDA_MCI) { + // check this (what to do if cd is ejected): + use_mciplay = false; + if (!mci_CDOpen(pathname[4])) use_mciplay = true; + } track_start_valid = false; } // Save old values From a5e74da117e3b1787afb117dd4cd68c237a20051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 9 Jan 2009 23:10:44 +0000 Subject: [PATCH 3167/4131] suppress key activation when forwarding numlock/capslock state during startup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3255 --- src/gui/sdl_mapper.cpp | 46 +++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 9d4b1a61..43b9a998 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.52 2008-12-31 16:33:46 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.53 2009-01-09 23:10:44 c2woody Exp $ */ #include #include @@ -106,8 +106,8 @@ public: void AddBind(CBind * bind); virtual ~CEvent() {} virtual void Active(bool yesno)=0; - virtual void Activate(bool ev_trigger)=0; - virtual void DeActivate(bool ev_trigger)=0; + virtual void ActivateEvent(bool ev_trigger,bool skip_action)=0; + virtual void DeActivateEvent(bool ev_trigger)=0; void DeActivateAll(void); void SetValue(Bits value){ current_value=value; @@ -131,20 +131,20 @@ public: virtual bool IsTrigger(void) { return true; } - void Activate(bool ev_trigger) { + void ActivateEvent(bool ev_trigger,bool skip_action) { if (current_value>25000) { /* value exceeds boundary, trigger event if not active */ - if (!activity) Active(true); + if (!activity && !skip_action) Active(true); if (activity<32767) activity++; } else { if (activity>0) { /* untrigger event if it is fully inactive */ - DeActivate(ev_trigger); + DeActivateEvent(ev_trigger); activity=0; } } } - void DeActivate(bool /*ev_trigger*/) { + void DeActivateEvent(bool /*ev_trigger*/) { activity--; if (!activity) Active(false); } @@ -157,17 +157,17 @@ public: virtual bool IsTrigger(void) { return false; } - void Activate(bool ev_trigger) { + void ActivateEvent(bool ev_trigger,bool skip_action) { if (ev_trigger) { activity++; - Active(true); + if (!skip_action) Active(true); } else { /* test if no trigger-activity is present, this cares especially about activity of the opposite-direction joystick axis for example */ if (!GetActivityCount()) Active(true); } } - void DeActivate(bool ev_trigger) { + void DeActivateEvent(bool ev_trigger) { if (ev_trigger) { if (activity>0) activity--; if (activity==0) { @@ -214,27 +214,27 @@ public: if (!strcasecmp(word,"hold")) flags|=BFLG_Hold; } } - void Activate(Bits _value,bool ev_trigger) { + void ActivateBind(Bits _value,bool ev_trigger,bool skip_action=false) { if (event->IsTrigger()) { /* use value-boundary for on/off events */ if (_value>25000) { event->SetValue(_value); if (active) return; - event->Activate(ev_trigger); + event->ActivateEvent(ev_trigger,skip_action); active=true; } else { if (active) { - event->DeActivate(ev_trigger); + event->DeActivateEvent(ev_trigger); active=false; } } } else { /* store value for possible later use in the activated event */ event->SetValue(_value); - event->Activate(ev_trigger); + event->ActivateEvent(ev_trigger,false); } } - void DeActivate(bool ev_trigger) { + void DeActivateBind(bool ev_trigger) { if (event->IsTrigger()) { if (!active) return; active=false; @@ -248,11 +248,11 @@ public: holding=false; } } - event->DeActivate(ev_trigger); + event->DeActivateEvent(ev_trigger); } else { /* store value for possible later use in the activated event */ event->SetValue(0); - event->DeActivate(ev_trigger); + event->DeActivateEvent(ev_trigger); } } virtual void ConfigName(char * buf)=0; @@ -272,7 +272,7 @@ void CEvent::AddBind(CBind * bind) { } void CEvent::DeActivateAll(void) { for (CBindList_it bit=bindlist.begin();bit!=bindlist.end();bit++) { - (*bit)->DeActivate(true); + (*bit)->DeActivateBind(true); } } @@ -1247,14 +1247,14 @@ void CBindGroup::ActivateBindList(CBindList * list,Bits value,bool ev_trigger) { } for (it=list->begin();it!=list->end();it++) { /*BUG:CRASH if keymapper key is removed*/ - if (validmod==(*it)->mods) (*it)->Activate(value,ev_trigger); + if (validmod==(*it)->mods) (*it)->ActivateBind(value,ev_trigger); } } void CBindGroup::DeactivateBindList(CBindList * list,bool ev_trigger) { CBindList_it it; for (it=list->begin();it!=list->end();it++) { - (*it)->DeActivate(ev_trigger); + (*it)->DeActivateBind(ev_trigger); } } @@ -2324,12 +2324,12 @@ void MAPPER_Init(void) { if (!MAPPER_LoadBinds()) CreateDefaultBinds(); if (SDL_GetModState()&KMOD_CAPS) { for (CBindList_it bit=caps_lock_event->bindlist.begin();bit!=caps_lock_event->bindlist.end();bit++) { - (*bit)->Activate(32767,true); + (*bit)->ActivateBind(32767,true,true); } } if (SDL_GetModState()&KMOD_NUM) { for (CBindList_it bit=num_lock_event->bindlist.begin();bit!=num_lock_event->bindlist.end();bit++) { - (*bit)->Activate(32767,true); + (*bit)->ActivateBind(32767,true,true); } } } From a9f0ec5b10f8aa3df84492be49b0762cef0b869b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 11 Jan 2009 18:22:59 +0000 Subject: [PATCH 3168/4131] hercules updates by hal (herc mode/status reg, herc textmode drawing), fixes blockout Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3256 --- src/hardware/vga_draw.cpp | 69 ++++++++++++++++++++++++++++++++---- src/hardware/vga_misc.cpp | 56 ++++++++++++++++------------- src/hardware/vga_other.cpp | 72 +++++++++++++++++++++++++------------- src/ints/int10_modes.cpp | 29 ++++++++------- src/shell/shell.cpp | 14 ++++---- src/shell/shell_cmds.cpp | 8 +++-- 6 files changed, 166 insertions(+), 82 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 01ea8db6..5fc6957c 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.104 2008-12-28 20:22:12 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.105 2009-01-11 18:22:59 c2woody Exp $ */ #include #include @@ -373,6 +373,55 @@ skip_cursor: return TempLine; } +static Bit8u * VGA_TEXT_Herc_Draw_Line(Bitu vidstart, Bitu line) { + Bits font_addr; + Bit32u * draw=(Bit32u *)TempLine; + const Bit8u *vidmem = &vga.tandy.draw_base[vidstart]; + + for (Bitu cx=0;cx> 7]; + else { + Bitu font=vga.draw.font_tables[0][chr*32+line]; + mask1=TXT_Font_Table[font>>4] & FontMask[attrib >> 7]; // blinking + mask2=TXT_Font_Table[font&0xf] & FontMask[attrib >> 7]; + } + *draw++=(fg&mask1) | (bg&~mask1); + *draw++=(fg&mask2) | (bg&~mask2); + } + } + if (!vga.draw.cursor.enabled || !(vga.draw.cursor.count&0x8)) goto skip_cursor; + font_addr = (vga.draw.cursor.address-vidstart) >> 1; + if (font_addr>=0 && font_addr<(Bits)vga.draw.blocks) { + if (linevga.draw.cursor.eline) goto skip_cursor; + draw=(Bit32u *)&TempLine[font_addr*8]; + Bit32u att=TXT_FG_Table[vga.tandy.draw_base[vga.draw.cursor.address+1]&0xf]; + *draw++=att;*draw++=att; + } +skip_cursor: + return TempLine; +} + static Bit8u * VGA_TEXT_Xlat16_Draw_Line(Bitu vidstart, Bitu line) { Bits font_addr; Bit16u * draw=(Bit16u *)TempLine; @@ -987,8 +1036,8 @@ void VGA_SetupDrawing(Bitu /*val*/) { clock=((vga.tandy.mode_control & 1) ? 14318180 : (14318180/2))/8; break; case MCH_HERC: - if (vga.herc.mode_control & 0x2) clock=14318180/16; - else clock=14318180/8; + if (vga.herc.mode_control & 0x2) clock=16000000/16; + else clock=16000000/8; break; default: clock = 14318180; @@ -1245,16 +1294,22 @@ void VGA_SetupDrawing(Bitu /*val*/) { break; case M_TANDY_TEXT: doublewidth=(vga.tandy.mode_control & 0x1)==0; - case M_HERC_TEXT: aspect_ratio=1; - doubleheight=(vga.mode!=M_HERC_TEXT); + doubleheight=true; vga.draw.blocks=width; width<<=3; VGA_DrawLine=VGA_TEXT_Draw_Line; break; + case M_HERC_TEXT: + aspect_ratio=1; + vga.draw.blocks=width; + width<<=3; + VGA_DrawLine=VGA_TEXT_Herc_Draw_Line; + break; default: LOG(LOG_VGA,LOG_ERROR)("Unhandled VGA mode %d while checking for resolution",vga.mode); - }; + break; + } VGA_CheckScanLength(); if (vga.draw.double_scan) { if (IS_VGA_ARCH) height/=2; diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 6e301705..4e68727d 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_misc.cpp,v 1.37 2008-06-03 18:35:32 c2woody Exp $ */ +/* $Id: vga_misc.cpp,v 1.38 2009-01-11 18:22:59 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -39,40 +39,46 @@ Bitu vga_read_p3da(Bitu port,Bitu iolen) { vga.internal.attrindex=false; vga.tandy.pcjr_flipflop=false; - switch (machine) { - case MCH_HERC: - { - // 3BAh (R): Status Register - // bit 0 Horizontal sync - // 3 Video signal - // 7 Vertical sync - if(timeInFrame >= vga.draw.delay.vrstart && - timeInFrame <= vga.draw.delay.vrend) - retval |= 0x80; - double timeInLine=fmod(timeInFrame,vga.draw.delay.htotal); - if(timeInLine >= vga.draw.delay.hrstart && - timeInLine <= vga.draw.delay.hrend) - retval |= 1; - retval |= 0x10; //Hercules ident - break; - } - default: + if (machine!=MCH_HERC) { // 3DAh (R): Status Register // bit 0 Horizontal or Vertical blanking // 3 Vertical sync - if(timeInFrame >= vga.draw.delay.vrstart && + if (timeInFrame >= vga.draw.delay.vrstart && timeInFrame <= vga.draw.delay.vrend) retval |= 8; - if(timeInFrame >= vga.draw.delay.vdend) + if (timeInFrame >= vga.draw.delay.vdend) { retval |= 1; - else { + } else { double timeInLine=fmod(timeInFrame,vga.draw.delay.htotal); - if(timeInLine >= (vga.draw.delay.hblkstart) && - timeInLine <= vga.draw.delay.hblkend){ + if (timeInLine >= vga.draw.delay.hblkstart && + timeInLine <= vga.draw.delay.hblkend) { retval |= 1; } } + } else { + // 3BAh (R): Status Register + // bit 0 Horizontal sync + // 1 Light pen status (only some cards) + // 3 Video signal + // 4-6 000: Hercules + // 001: Hercules Plus + // 101: Hercules InColor + // 111: Unknown clone + // 7 Vertical sync inverted + + retval=0x72; // Hercules ident; from a working card (Winbond W86855AF) + // Another known working card has 0x76 ("KeysoGood", full-length) + if (timeInFrame < vga.draw.delay.vrstart || + timeInFrame > vga.draw.delay.vrend) retval |= 0x80; + + double timeInLine=fmod(timeInFrame,vga.draw.delay.htotal); + if (timeInLine >= vga.draw.delay.hrstart && + timeInLine <= vga.draw.delay.hrend) retval |= 0x1; + + // 688 Attack sub checks bit 3 - as a workaround have the bit enabled + // if no sync active (corresponds to a completely white screen) + if ((retval&0x81)==0x80) retval |= 0x8; } return retval; } diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 64c1d8ac..800827b0 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_other.cpp,v 1.23 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: vga_other.cpp,v 1.24 2009-01-11 18:22:59 c2woody Exp $ */ #include #include @@ -432,26 +432,40 @@ static void write_pcjr(Bitu port,Bitu val,Bitu iolen) { static void write_hercules(Bitu port,Bitu val,Bitu iolen) { switch (port) { - case 0x3b8: - if (vga.herc.enable_bits & 1 ) { - vga.herc.mode_control&=~0x2; - vga.herc.mode_control|=(val&0x2); - if (val & 0x2) { - VGA_SetMode(M_HERC_GFX); - } else { + case 0x3b8: { + // the protected bits can always be cleared but only be set if the + // protection bits are set + if (vga.herc.mode_control&0x2) { + // already set + if (!(val&0x2)) { + vga.herc.mode_control &= ~0x2; VGA_SetMode(M_HERC_TEXT); } + } else { + // not set, can only set if protection bit is set + if ((val & 0x2) && (vga.herc.enable_bits & 0x1)) { + vga.herc.mode_control |= 0x2; + VGA_SetMode(M_HERC_GFX); + } } - if ((vga.herc.enable_bits & 0x2) && ((vga.herc.mode_control ^ val)&0x80)) { - vga.herc.mode_control^=0x80; + if (vga.herc.mode_control&0x80) { + if (!(val&0x80)) { + vga.herc.mode_control &= ~0x80; + vga.tandy.draw_base = &vga.mem.linear[0]; + } + } else { + if ((val & 0x80) && (vga.herc.enable_bits & 0x2)) { + vga.herc.mode_control |= 0x80; + vga.tandy.draw_base = &vga.mem.linear[32*1024]; + } } - vga.tandy.draw_base = &vga.mem.linear[(vga.herc.mode_control & 0x80 ) ? 32*1024 : 0]; + vga.draw.blinking = (val&0x20)!=0; + vga.herc.mode_control &= 0x82; + vga.herc.mode_control |= val & ~0x82; break; - case 0x3bf: - if ( vga.herc.enable_bits ^ val) { - vga.herc.enable_bits=val; - VGA_SetupHandlers(); } + case 0x3bf: + vga.herc.enable_bits=val; break; } } @@ -488,12 +502,6 @@ void VGA_SetupOther(void) { MAPPER_AddHandler(IncreaseHue,MK_f11,MMOD2,"inchue","Inc Hue"); MAPPER_AddHandler(DecreaseHue,MK_f11,0,"dechue","Dec Hue"); } - if (machine==MCH_HERC) { - vga.herc.enable_bits=0; - vga.herc.mode_control=0x8; - IO_RegisterWriteHandler(0x3b8,write_hercules,IO_MB); - IO_RegisterWriteHandler(0x3bf,write_hercules,IO_MB); - } if (machine==MCH_TANDY) { write_tandy( 0x3df, 0x0, 0 ); IO_RegisterWriteHandler(0x3d8,write_tandy,IO_MB); @@ -509,6 +517,22 @@ void VGA_SetupOther(void) { IO_RegisterWriteHandler(0x3da,write_pcjr,IO_MB); IO_RegisterWriteHandler(0x3df,write_pcjr,IO_MB); } + if (machine==MCH_HERC) { + Bitu base=0x3b0; + for (Bitu i = 0; i < 4; i++) { + // The registers are repeated as the address is not decoded properly; + // The official ports are 3b4, 3b5 + IO_RegisterWriteHandler(base+i*2,write_crtc_index_other,IO_MB); + IO_RegisterWriteHandler(base+i*2+1,write_crtc_data_other,IO_MB); + IO_RegisterReadHandler(base+i*2,read_crtc_index_other,IO_MB); + IO_RegisterReadHandler(base+i*2+1,read_crtc_data_other,IO_MB); + } + vga.herc.enable_bits=0; + vga.herc.mode_control=0xa; // first mode written will be text mode + vga.crtc.underline_location = 13; + IO_RegisterWriteHandler(0x3b8,write_hercules,IO_MB); + IO_RegisterWriteHandler(0x3bf,write_hercules,IO_MB); + } if (machine==MCH_CGA) { Bitu base=0x3d0; for (Bitu port_ct=0; port_ct<4; port_ct++) { @@ -518,8 +542,8 @@ void VGA_SetupOther(void) { IO_RegisterReadHandler(base+port_ct*2+1,read_crtc_data_other,IO_MB); } } - if (machine==MCH_HERC || IS_TANDY_ARCH) { - Bitu base=machine==MCH_HERC ? 0x3b4 : 0x3d4; + if (IS_TANDY_ARCH) { + Bitu base=0x3d4; IO_RegisterWriteHandler(base,write_crtc_index_other,IO_MB); IO_RegisterWriteHandler(base+1,write_crtc_data_other,IO_MB); IO_RegisterReadHandler(base,read_crtc_index_other,IO_MB); diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index f86abf2f..9c32e424 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.83 2009-01-02 19:30:53 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.84 2009-01-11 18:22:59 c2woody Exp $ */ #include @@ -368,13 +368,11 @@ static void FinishSetMode(bool clearmem) { real_writew( 0xb800,i*2,0x0000); } break; - case M_TEXT: - if (CurMode->mode==7) for (i=0;i<16*1024;i++) { - real_writew(0xb000,i*2,0x0120); - } else for (i=0;i<16*1024;i++) { - real_writew(0xb800,i*2,0x0720); - } + case M_TEXT: { + Bit16u seg = (CurMode->mode==7)?0xb000:0xb800; + for (i=0;i<16*1024;i++) real_writew(seg,i*2,0x0720); break; + } case M_EGA: case M_VGA: case M_LIN8: @@ -436,8 +434,7 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { case MCH_HERC: if (mode!=7) { //Just the text memory, most games seem to use any random mode to clear the screen - for (i=0;i<16*1024;i++) - real_writew(0xb000,i*2,0x0120); + for (i=0;i<16*1024;i++) real_writew(0xb000,i*2,0x0720); return false; } CurMode=&Hercules_Mode; @@ -504,12 +501,14 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { Bit8u mode_control,color_select; switch (machine) { case MCH_HERC: - IO_WriteB(0x3bf,0x3); //Enable changing all bits - IO_WriteB(0x3b8,0x8); //TEXT mode and non-blinking characters - IO_WriteB(0x3bf,0x0); + IO_WriteB(0x3b8,0x28); // TEXT mode and blinking characters + VGA_DAC_CombineColor(0,0); - for ( i = 1; i < 15;i++) - VGA_DAC_CombineColor(i,0xf); + VGA_DAC_CombineColor(8,0); + for ( i = 1; i < 8;i++) { + VGA_DAC_CombineColor(i,0x7); + VGA_DAC_CombineColor(i+8,0xf); + } break; case MCH_CGA: mode_control=mode_control_list[CurMode->mode]; diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 8a8fb976..395fdcac 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.95 2008-09-20 14:51:53 c2woody Exp $ */ +/* $Id: shell.cpp,v 1.96 2009-01-11 18:22:59 c2woody Exp $ */ #include #include @@ -297,14 +297,12 @@ void DOS_Shell::Run(void) { return; } /* Start a normal shell and check for a first command init */ - if(machine != MCH_HERC) { //Hide it for hercules as that looks too weird - WriteOut(MSG_Get("SHELL_STARTUP_BEGIN"),VERSION); + WriteOut(MSG_Get("SHELL_STARTUP_BEGIN"),VERSION); #if C_DEBUG - WriteOut(MSG_Get("SHELL_STARTUP_DEBUG")); + WriteOut(MSG_Get("SHELL_STARTUP_DEBUG")); #endif - if(machine == MCH_CGA) WriteOut(MSG_Get("SHELL_STARTUP_CGA")); - WriteOut(MSG_Get("SHELL_STARTUP_END")); - } + if (machine == MCH_CGA) WriteOut(MSG_Get("SHELL_STARTUP_CGA")); + WriteOut(MSG_Get("SHELL_STARTUP_END")); if (cmd->FindString("/INIT",line,true)) { strcpy(input_line,line.c_str()); diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 6842b258..1c659c38 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.84 2008-09-07 10:55:16 c2woody Exp $ */ +/* $Id: shell_cmds.cpp,v 1.85 2009-01-11 18:22:59 c2woody Exp $ */ #include "dosbox.h" #include "shell.h" @@ -167,7 +167,9 @@ void DOS_Shell::DoCommand(char * line) { void DOS_Shell::CMD_CLS(char * args) { HELP("CLS"); - reg_ax=0x0003; + // 3 is not good for hercules as it 'forgets' to reset the cursor position + if (machine==MCH_HERC) reg_ax=0x0007; + else reg_ax=0x0003; CALLBACK_RunRealInt(0x10); } From 9690d8d53f08339642a568020684266b40a655fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 13 Jan 2009 17:32:09 +0000 Subject: [PATCH 3169/4131] prevent overflows during cycles estimation Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3257 --- src/dosbox.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 2e8b926b..9c58c741 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.138 2008-10-27 11:02:41 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.139 2009-01-13 17:32:09 c2woody Exp $ */ #include #include @@ -168,7 +168,7 @@ increaseticks: if (CPU_CycleAutoAdjust && !CPU_SkipCycleAutoAdjust) { if (ticksScheduled >= 250 || ticksDone >= 250 || (ticksAdded > 15 && ticksScheduled >= 5) ) { /* ratio we are aiming for is around 90% usage*/ - Bits ratio = (ticksScheduled * (CPU_CyclePercUsed*90*1024/100/100)) / ticksDone; + Bit32s ratio = (ticksScheduled * (CPU_CyclePercUsed*90*1024/100/100)) / ticksDone; Bit32s new_cmax = CPU_CycleMax; Bit64s cproc = (Bit64s)CPU_CycleMax * (Bit64s)ticksScheduled; if (cproc > 0) { @@ -176,11 +176,12 @@ increaseticks: to have smoother auto cycle adjustments */ double ratioremoved = (double) CPU_IODelayRemoved / (double) cproc; if (ratioremoved < 1.0) { - ratio = (Bits)((double)ratio * (1 - ratioremoved)); + Bit64s cmax_scaled = (Bit64s)CPU_CycleMax * (Bit64s)ratio; + ratio = (Bit32s)((double)ratio * (1 - ratioremoved)); if (ratio <= 1024) - new_cmax = (CPU_CycleMax * ratio) / 1024; + new_cmax = (Bit32s)(cmax_scaled / (Bit64s)1024); else - new_cmax = 1 + (CPU_CycleMax >> 1) + (CPU_CycleMax * ratio) / 2048; + new_cmax = (Bit32s)(1 + (CPU_CycleMax >> 1) + cmax_scaled / (Bit64s)2048); } } From 6b65170fbdc76a059ec5a427c2cd5f5fac56fd7c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 13 Jan 2009 19:02:43 +0000 Subject: [PATCH 3170/4131] don't compress memory on free. (beta 2) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3258 --- src/dos/dos_memory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 3f337dba..1e55725b 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -298,7 +298,7 @@ bool DOS_FreeMemory(Bit16u segment) { return false; } mcb.SetPSPSeg(MCB_FREE); - DOS_CompressMemory(); +// DOS_CompressMemory(); return true; } From 4e8f79fd9e14cce803309ea2baf6b568108d4f46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 14 Jan 2009 20:50:23 +0000 Subject: [PATCH 3171/4131] reduce GUS parameters, disable gravis ultrasound by default (for testing) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3259 --- src/dosbox.cpp | 33 +++++++++++++-------------------- src/hardware/gus.cpp | 42 +++++++++++++++++++++++++----------------- 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 9c58c741..9601f0fc 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.139 2009-01-13 17:32:09 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.140 2009-01-14 20:50:22 c2woody Exp $ */ #include #include @@ -318,10 +318,11 @@ void DOSBOX_Init(void) { // Some frequently used option sets const char *rates[] = { "22050", "44100", "48000", "32000", "16000", "11025", "8000", 0 }; const char *ios[] = { "220", "240", "260", "280", "2a0", "2c0", "2e0", "300", 0 }; - const char *irqs[] = { "3", "5", "7", "9", "10", "11", "12", 0 }; - const char *dmas[] = { "0", "1", "3", "5", "6", "7", 0 }; const char *irqssb[] = { "7", "5", "3", "9", "10", "11", "12", 0 }; const char *dmassb[] = { "1", "5", "0", "3", "6", "7", 0 }; + const char *iosgus[] = { "240", "220", "260", "280", "2a0", "2c0", "2e0", "300", 0 }; + const char *irqsgus[] = { "5", "3", "7", "9", "10", "11", "12", 0 }; + const char *dmasgus[] = { "3", "0", "1", "5", "6", "7", 0 }; /* Setup all the different modules making up DOSBox */ @@ -512,7 +513,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("gus",&GUS_Init,true); //done - Pbool = secprop->Add_bool("gus",Property::Changeable::WhenIdle,true); + Pbool = secprop->Add_bool("gus",Property::Changeable::WhenIdle,false); Pbool->Set_help("Enable the Gravis Ultrasound emulation."); Pint = secprop->Add_int("gusrate",Property::Changeable::WhenIdle,22050); @@ -520,24 +521,16 @@ void DOSBOX_Init(void) { Pint->Set_help("Sample rate of Ultrasound emulation."); Phex = secprop->Add_hex("gusbase",Property::Changeable::WhenIdle,0x240); - Phex->Set_values(ios); - Phex->Set_help("The IO addresses of the Gravis Ultrasound."); + Phex->Set_values(iosgus); + Phex->Set_help("The IO base address of the Gravis Ultrasound."); - Pint = secprop->Add_int("irq1",Property::Changeable::WhenIdle,5); - Pint->Set_values(irqs); - Pint->Set_help("The first IRQ number of the Gravis Ultrasound. (Same IRQs are OK.)"); + Pint = secprop->Add_int("gusirq",Property::Changeable::WhenIdle,5); + Pint->Set_values(irqsgus); + Pint->Set_help("The IRQ number of the Gravis Ultrasound."); - Pint = secprop->Add_int("irq2",Property::Changeable::WhenIdle,5); - Pint->Set_values(irqs); - Pint->Set_help("The second IRQ number of the Gravis Ultrasound. (Same IRQs are OK.)"); - - Pint = secprop->Add_int("dma1",Property::Changeable::WhenIdle,3); - Pint->Set_values(dmas); - Pint->Set_help("The first DMA addresses of the Gravis Ultrasound. (Same DMAs are OK.)"); - - Pint = secprop->Add_int("dma2",Property::Changeable::WhenIdle,3); - Pint->Set_values(dmas); - Pint->Set_help("The second DMA addresses of the Gravis Ultrasound. (Same DMAs are OK.)"); + Pint = secprop->Add_int("gusdma",Property::Changeable::WhenIdle,3); + Pint->Set_values(dmasgus); + Pint->Set_help("The DMA channel of the Gravis Ultrasound."); Pstring = secprop->Add_string("ultradir",Property::Changeable::WhenIdle,"C:\\ULTRASND"); Pstring->Set_help( diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index c952d14a..9542d1b4 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: gus.cpp,v 1.33 2009-01-14 20:50:23 c2woody Exp $ */ + #include #include #include @@ -85,11 +87,11 @@ struct GFGus { } timers[2]; Bit32u rate; Bitu portbase; - Bitu dma1; - Bitu dma2; + Bit8u dma1; + Bit8u dma2; - Bitu irq1; - Bitu irq2; + Bit8u irq1; + Bit8u irq2; char ultradir[512]; bool irqenabled; @@ -376,7 +378,7 @@ static void CheckVoiceIrq(void) { if (myGUS.RampIRQ) myGUS.IRQStatus|=0x40; if (myGUS.WaveIRQ) myGUS.IRQStatus|=0x20; GUS_CheckIRQ(); - while (1) { + for (;;) { Bit32u check=(1 << myGUS.IRQChan); if (totalmask & check) return; myGUS.IRQChan++; @@ -801,10 +803,15 @@ public: myGUS.rate=section->Get_int("gusrate"); myGUS.portbase = section->Get_hex("gusbase") - 0x200; - myGUS.dma1 = section->Get_int("dma1"); - myGUS.dma2 = section->Get_int("dma2"); - myGUS.irq1 = section->Get_int("irq1"); - myGUS.irq2 = section->Get_int("irq2"); + int dma_val = section->Get_int("gusdma"); + if ((dma_val<0) || (dma_val>255)) dma_val = 3; // sensible default + int irq_val = section->Get_int("gusirq"); + if ((irq_val<0) || (irq_val>255)) irq_val = 5; // sensible default + myGUS.dma1 = (Bit8u)dma_val; + myGUS.dma2 = (Bit8u)dma_val; + myGUS.irq1 = (Bit8u)irq_val; + myGUS.irq2 = (Bit8u)irq_val; + strcpy(&myGUS.ultradir[0], section->Get_string("ultradir")); // We'll leave the MIDI interface to the MPU-401 @@ -842,9 +849,8 @@ public: MakeTables(); - int i; - for(i=0;i<32;i++) { - guschan[i] = new GUSChannels(i); + for (Bit8u chan_ct=0; chan_ct<32; chan_ct++) { + guschan[chan_ct] = new GUSChannels(chan_ct); } // Register the Mixer CallBack gus_chan=MixerChan.Install(GUS_CallBack,GUS_RATE,"GUS"); @@ -852,12 +858,14 @@ public: GUSReset(); myGUS.gRegData=0x0; int portat = 0x200+GUS_BASE; + // ULTRASND=Port,DMA1,DMA2,IRQ1,IRQ2 - // Create autoexec.bat lines + // [GUS port], [GUS DMA (recording)], [GUS DMA (playback)], [GUS IRQ (playback)], [GUS IRQ (MIDI)] ostringstream temp; temp << "SET ULTRASND=" << hex << setw(3) << portat << "," - << dec << myGUS.dma1 << "," << myGUS.dma2 << "," - << myGUS.irq1 << "," << myGUS.irq2 << ends; + << dec << (Bitu)myGUS.dma1 << "," << (Bitu)myGUS.dma2 << "," + << (Bitu)myGUS.irq1 << "," << (Bitu)myGUS.irq2 << ends; + // Create autoexec.bat lines autoexecline[0].Install(temp.str()); autoexecline[1].Install(std::string("SET ULTRADIR=")+ myGUS.ultradir); } @@ -883,7 +891,7 @@ public: static GUS* test; -void GUS_ShutDown(Section* sec) { +void GUS_ShutDown(Section* /*sec*/) { delete test; } From f47d48ba0715014b15d342a0dee85a36f10b4d76 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 14 Jan 2009 22:16:00 +0000 Subject: [PATCH 3172/4131] Start stuff with an REFT instead of IRET. Fixes CyberRace.(Beta 2) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3260 --- include/callback.h | 5 +++-- src/cpu/callback.cpp | 14 +++++++++++++- src/dos/dos.cpp | 11 ++++++++--- src/dos/dos_execute.cpp | 15 +++++++++------ 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/include/callback.h b/include/callback.h index 1bfc3526..faaa8bc0 100644 --- a/include/callback.h +++ b/include/callback.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.h,v 1.21 2007-06-12 20:22:07 c2woody Exp $ */ +/* $Id: callback.h,v 1.22 2009-01-14 22:16:00 qbix79 Exp $ */ #ifndef DOSBOX_CALLBACK_H #define DOSBOX_CALLBACK_H @@ -30,7 +30,8 @@ extern CallBack_Handler CallBack_Handlers[]; enum { CB_RETN,CB_RETF,CB_RETF8,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1, 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_INT29,CB_INT16,CB_HOOKABLE,CB_TDE_IRET,CB_IPXESR,CB_IPXESR_RET, + CB_INT21 }; #define CB_MAX 128 #define CB_SIZE 32 diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index ea1e167f..2f1b7f9c 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.37 2007-06-03 16:46:33 c2woody Exp $ */ +/* $Id: callback.cpp,v 1.38 2009-01-14 22:16:00 qbix79 Exp $ */ #include #include @@ -403,6 +403,18 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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: E_Exit("CALLBACK:Setup:Illegal type %d",type); } diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 01c7d90c..e9ae9c3b 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.114 2008-12-11 09:16:31 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.115 2009-01-14 22:16:00 qbix79 Exp $ */ #include #include @@ -1041,7 +1041,7 @@ static Bitu DOS_21Handler(void) { break; }; return CBRET_NONE; -}; +} static Bitu DOS_20Handler(void) { @@ -1091,8 +1091,13 @@ public: callback[0].Install(DOS_20Handler,CB_IRET,"DOS Int 20"); callback[0].Set_RealVec(0x20); - callback[1].Install(DOS_21Handler,CB_IRET_STI,"DOS Int 21"); + callback[1].Install(DOS_21Handler,CB_INT21,"DOS Int 21"); callback[1].Set_RealVec(0x21); + //Pseudo code for int 21 + // sti + // callback + // iret + // retf <- int 21 4c jumps here to mimic a retf Cyber callback[2].Install(DOS_25Handler,CB_RETF,"DOS Int 25"); callback[2].Set_RealVec(0x25); diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 021aceec..a6058a83 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.65 2008-10-05 14:44:52 qbix79 Exp $ */ +/* $Id: dos_execute.cpp,v 1.66 2009-01-14 22:16:00 qbix79 Exp $ */ #include #include @@ -457,13 +457,16 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { /* Set the stack for new program */ SegSet16(ss,RealSeg(sssp));reg_sp=RealOff(sssp); /* Add some flags and CS:IP on the stack for the IRET */ - reg_sp-=6; + reg_sp-=4; mem_writew(SegPhys(ss)+reg_sp+0,RealOff(csip)); mem_writew(SegPhys(ss)+reg_sp+2,RealSeg(csip)); - /* DOS starts programs with a RETF, so our IRET - should not modify critical flags (IOPL in v86 mode); - interrupt flag is set explicitly, test flags cleared */ - mem_writew(SegPhys(ss)+reg_sp+4,(reg_flags&(~FMASK_TEST))|FLAG_IF); + /* Old info, we now jump to a RETF: + * DOS starts programs with a RETF, so our IRET + * should not modify critical flags (IOPL in v86 mode); + * interrupt flag is set explicitly, test flags cleared */ + reg_flags=(reg_flags&(~FMASK_TEST))|FLAG_IF; + //Jump to retf so that we only need to store cs:ip on the stack + reg_ip++; /* Setup the rest of the registers */ reg_ax=reg_bx=0;reg_cx=0xff; reg_dx=pspseg; From b81691c53c2e6259b3cef59812cb4fd3656f65b2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 14 Jan 2009 22:24:39 +0000 Subject: [PATCH 3173/4131] Softmodem changes related to the dail command. (Beta 2) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3261 --- src/hardware/serialport/softmodem.cpp | 97 ++++++++++++++------------- 1 file changed, 49 insertions(+), 48 deletions(-) diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index d5aad515..bcd45952 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.cpp,v 1.9 2007-11-01 12:11:40 qbix79 Exp $ */ +/* $Id: softmodem.cpp,v 1.10 2009-01-14 22:24:39 qbix79 Exp $ */ #include "dosbox.h" @@ -329,60 +329,61 @@ void CSerialModem::DoCommand() { SendRes(ResOK); return; } - - /* Check for dial command */ - if(strncmp(cmdbuf,"ATD3",3)==0) { - char * foundstr=&cmdbuf[3]; - if (*foundstr=='T' || *foundstr=='P') foundstr++; - /* Small protection against empty line */ - if (!foundstr[0]) { - SendRes(ResERROR); - return; - } - char* helper; - // scan for and remove spaces; weird bug: with leading spaces in the string, - // SDLNet_ResolveHost will return no error but not work anyway (win) - while(foundstr[0]==' ') foundstr++; - helper=foundstr; - helper+=strlen(foundstr); - while(helper[0]==' ') { - helper[0]=0; - helper--; - } - if (strlen(foundstr) >= 12) { - // Check if supplied parameter only consists of digits - bool isNum = true; - for (Bitu i=0; i '9') - isNum = false; - if (isNum) { - // Parameter is a number with at least 12 digits => this cannot be a valid IP/name - // Transform by adding dots - char buffer[128]; - Bitu j = 0; - for (Bitu i=0; i12) - buffer[j++] = ':'; - } - buffer[j] = 0; - foundstr = buffer; - } - } - Dial(foundstr); - return; - } char * scanbuf; scanbuf=&cmdbuf[2]; char chr; Bitu num; while (chr=*scanbuf++) { switch (chr) { + case 'D': // Dial + { + char * foundstr=&scanbuf[0]; + if (*foundstr=='T' || *foundstr=='P') foundstr++; + // Small protection against empty line and long string + if ((!foundstr[0]) || (strlen(foundstr)>100)) { + SendRes(ResERROR); + return; + } + char* helper; + // scan for and remove spaces; weird bug: with leading spaces in the string, + // SDLNet_ResolveHost will return no error but not work anyway (win) + while(foundstr[0]==' ') foundstr++; + helper=foundstr; + helper+=strlen(foundstr); + while(helper[0]==' ') { + helper[0]=0; + helper--; + } + if (strlen(foundstr) >= 12) { + // Check if supplied parameter only consists of digits + bool isNum = true; + for (Bitu i=0; i '9') + isNum = false; + if (isNum) { + // Parameter is a number with at least 12 digits => this cannot + // be a valid IP/name + // Transform by adding dots + char buffer[128]; + Bitu j = 0; + for (Bitu i=0; i12) + buffer[j++] = ':'; + } + buffer[j] = 0; + foundstr = buffer; + } + } + Dial(foundstr); + return; + } case 'I': //Some strings about firmware switch (num=ScanNumber(scanbuf)) { case 3:SendLine("DosBox Emulated Modem Firmware V1.00");break; From a5bbd753a1d9cb44bd65153e07678664727dbbe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 17 Jan 2009 21:31:21 +0000 Subject: [PATCH 3174/4131] update displayed copyright year Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3262 --- src/dosbox.rc | 4 ++-- src/gui/sdlmain.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dosbox.rc b/src/dosbox.rc index a77e6dd1..66c79a45 100644 --- a/src/dosbox.rc +++ b/src/dosbox.rc @@ -19,12 +19,12 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "Comments", "© 2002-2007 DOSBox Team, published under GNU GPL" + VALUE "Comments", "© 2002-2009 DOSBox Team, published under GNU GPL" VALUE "CompanyName", "DOSBox Team" VALUE "FileDescription", "DOSBox DOS Emulator" VALUE "FileVersion", "0, 72, 0, 0" VALUE "InternalName", "DOSBox" - VALUE "LegalCopyright", "Copyright © 2002-2007 DOSBox Team" + VALUE "LegalCopyright", "Copyright © 2002-2009 DOSBox Team" VALUE "OriginalFilename", "dosbox.exe" VALUE "ProductName", "DOSBox DOS Emulator" VALUE "ProductVersion", "0, 72, 0, 0" diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 34c28517..1ddc5874 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.144 2008-08-06 18:32:34 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.145 2009-01-17 21:31:21 c2woody Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1387,7 +1387,7 @@ int main(int argc, char* argv[]) { /* Display Welcometext in the console */ LOG_MSG("DOSBox version %s",VERSION); - LOG_MSG("Copyright 2002-2008 DOSBox Team, published under GNU GPL."); + LOG_MSG("Copyright 2002-2009 DOSBox Team, published under GNU GPL."); LOG_MSG("---"); /* Init SDL */ From a6d6dce331ab7ba8d40929bf77edc06d9f287be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 18 Jan 2009 13:57:45 +0000 Subject: [PATCH 3175/4131] have irq6 use a different default handler to work around a bug in a game (thanks to ripsaw, should fix design your own railroad) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3263 --- src/cpu/callback.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 2f1b7f9c..cda77a75 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.38 2009-01-14 22:16:00 qbix79 Exp $ */ +/* $Id: callback.cpp,v 1.39 2009-01-18 13:57:45 c2woody Exp $ */ #include #include @@ -34,7 +34,7 @@ CallBack_Handler CallBack_Handlers[CB_MAX]; char* CallBack_Description[CB_MAX]; -static Bitu call_stop,call_idle,call_default; +static Bitu call_stop,call_idle,call_default,call_default2; Bitu call_priv_io; static Bitu illegal_handler(void) { @@ -77,11 +77,11 @@ void CALLBACK_Idle(void) { static Bitu default_handler(void) { LOG(LOG_CPU,LOG_ERROR)("Illegal Unhandled Interrupt Called %X",lastint); return CBRET_NONE; -}; +} static Bitu stop_handler(void) { return CBRET_STOP; -}; +} @@ -112,13 +112,13 @@ void CALLBACK_SZF(bool val) { Bit16u tempf=mem_readw(SegPhys(ss)+reg_sp+4) & 0xFFBF; Bit16u newZF=(val==true) << 6; mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newZF)); -}; +} void CALLBACK_SCF(bool val) { Bit16u tempf=mem_readw(SegPhys(ss)+reg_sp+4) & 0xFFFE; Bit16u newCF=(val==true); mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newCF)); -}; +} void CALLBACK_SetDescription(Bitu nr, const char* descr) { if (descr) { @@ -126,12 +126,12 @@ void CALLBACK_SetDescription(Bitu nr, const char* descr) { 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) { if (callback>=CB_MAX) @@ -524,9 +524,11 @@ void CALLBACK_Init(Section* sec) { phys_writeb(CALLBACK_PhysPointer(call_idle)+13,0x38); 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(); CALLBACK_Setup(call_default,&default_handler,CB_IRET,"default"); + call_default2=CALLBACK_Allocate(); + 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++) { @@ -544,10 +546,11 @@ void CALLBACK_Init(Section* sec) { } // setup a few interrupt handlers that point to bios IRETs by default - real_writed(0,0x66*4,CALLBACK_RealPointer(call_default)); //war2d + 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,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(); From 8033d5b7e0f1f4ce264a390a247b6d2e5a706571 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 19 Jan 2009 19:55:03 +0000 Subject: [PATCH 3176/4131] Close and reopen batch for each executed line. Makes it possible to rewrite it and to call it itself infinitely. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3264 --- include/shell.h | 3 ++- src/shell/shell_batch.cpp | 46 ++++++++++++++++++++++++++++++++------- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/include/shell.h b/include/shell.h index e4f8f27b..689ad1d2 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.24 2008-08-11 12:54:57 qbix79 Exp $ */ +/* $Id: shell.h,v 1.25 2009-01-19 19:55:03 qbix79 Exp $ */ #ifndef DOSBOX_SHELL_H #define DOSBOX_SHELL_H @@ -53,6 +53,7 @@ public: bool Goto(char * where); void Shift(void); Bit16u file_handle; + Bit32u location; bool echo; DOS_Shell * shell; BatchFile * prev; diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 5ef909b7..b5757684 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.31 2008-08-24 16:48:23 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.32 2009-01-19 19:55:03 qbix79 Exp $ */ #include #include @@ -25,24 +25,35 @@ #include "support.h" BatchFile::BatchFile(DOS_Shell * host,char const * const name, char const * const cmd_line) { + location = 0; prev=host->bf; echo=host->echo; shell=host; - cmd=new CommandLine(name,cmd_line); - if (!DOS_OpenFile(name,128,&file_handle)) { + char totalname[DOS_PATHLENGTH+4]; + DOS_Canonicalize(name,totalname); // Get fullname including drive specificiation + cmd = new CommandLine(totalname,cmd_line); + + //Test if file is openable + if (!DOS_OpenFile(totalname,128,&file_handle)) { //TODO Come up with something better - E_Exit("SHELL:Can't open BatchFile"); + E_Exit("SHELL:Can't open BatchFile %s",totalname); } + DOS_CloseFile(file_handle); } BatchFile::~BatchFile() { delete cmd; - DOS_CloseFile(file_handle); shell->bf=prev; shell->echo=echo; } bool BatchFile::ReadLine(char * line) { + //Open the batchfile and seek to stored postion + if (!DOS_OpenFile(cmd->GetFileName(),128,&file_handle)) { + E_Exit("SHELL:ReadLine Can't open BatchFile %s",cmd->GetFileName()); + } + DOS_SeekFile(file_handle,&(this->location),DOS_SEEK_SET); + Bit8u c=0;Bit16u n=1; char temp[CMD_MAXLINE]; emptyline: @@ -61,12 +72,15 @@ emptyline: } while (c!='\n' && n); *cmd_write=0; if (!n && cmd_write==temp) { + //Close file and delete bat file + DOS_CloseFile(file_handle); delete this; return false; } if (!strlen(temp)) goto emptyline; if (temp[0]==':') goto emptyline; -/* Now parse the line read from the bat file for % stuff */ + + /* Now parse the line read from the bat file for % stuff */ cmd_write=line; char * cmd_read=temp; char env_name[256];char * env_write; @@ -118,14 +132,22 @@ emptyline: } } *cmd_write=0; + //Store current location and close bat file + this->location = 0; + DOS_SeekFile(file_handle,&(this->location),DOS_SEEK_CUR); + DOS_CloseFile(file_handle); return true; } bool BatchFile::Goto(char * where) { + //Open bat file and search for the where string + if (!DOS_OpenFile(cmd->GetFileName(),128,&file_handle)) { + E_Exit("SHELL:Goto Can't open BatchFile %s",cmd->GetFileName()); + } + Bit32u pos=0; char cmd_buffer[CMD_MAXLINE]; char * cmd_write; - DOS_SeekFile(file_handle,&pos,DOS_SEEK_SET); /* Scan till we have a match or return false */ Bit8u c;Bit16u n; @@ -153,9 +175,17 @@ again: nospace++; *nospace = 0; - if (strcasecmp(beginlabel,where)==0) return true; + if (strcasecmp(beginlabel,where)==0) { + //Found it! Store location and continue + this->location = 0; + DOS_SeekFile(file_handle,&(this->location),DOS_SEEK_CUR); + DOS_CloseFile(file_handle); + return true; + } + } if (!n) { + DOS_CloseFile(file_handle); delete this; return false; } From 7bc763807e7c79c0f04d1875b2f02cf306f4af1c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 19 Jan 2009 20:24:18 +0000 Subject: [PATCH 3177/4131] Generate an error for files/directories with double extentions. Fixes some application that depends on this behavior in order to distinguish between arguments Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3265 --- src/dos/dos_files.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index f8e52a32..362a7194 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.102 2008-10-05 14:44:52 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.103 2009-01-19 20:24:18 qbix79 Exp $ */ #include #include @@ -53,7 +53,6 @@ void DOS_SetDefaultDrive(Bit8u drive) { } bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { - if(!name || *name == 0 || *name == ' ') { /* Both \0 and space are seperators and * empty filenames report file not found */ @@ -106,7 +105,7 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { else fullname[0]=0; Bit32u lastdir=0;Bit32u t=0; while (fullname[t]!=0) { - if ((fullname[t]=='\\') && (fullname[t+1]!=0))lastdir=t; + if ((fullname[t]=='\\') && (fullname[t+1]!=0)) lastdir=t; t++; }; r=0;w=0; @@ -144,7 +143,7 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { fullname[lastdir]=0; t=0;lastdir=0; while (fullname[t]!=0) { - if ((fullname[t]=='\\') && (fullname[t+1]!=0))lastdir=t; + if ((fullname[t]=='\\') && (fullname[t+1]!=0)) lastdir=t; t++; } tempdir[0]=0; @@ -158,6 +157,18 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { if (lastdir!=0) strcat(fullname,"\\"); char * ext=strchr(tempdir,'.'); if (ext) { + if(strchr(ext+1,'.')) { + //another dot in the extension =>file not found + //Or path not found depending on wether + //we are still in dir check stage or file stage + LOG_MSG("stop = %d",stop); + if(stop) + DOS_SetError(DOSERR_FILE_NOT_FOUND); + else + DOS_SetError(DOSERR_PATH_NOT_FOUND); + return false; + } + ext[4] = 0; if((strlen(tempdir) - strlen(ext)) > 8) memmove(tempdir + 8, ext, 5); } else tempdir[8]=0; From 5ba2b294e74093f3bf97533ec5ab7b03612013ee Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 19 Jan 2009 20:26:12 +0000 Subject: [PATCH 3178/4131] Remove LOG_MSG Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3266 --- src/dos/dos_files.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 362a7194..ddf42e0c 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.103 2009-01-19 20:24:18 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.104 2009-01-19 20:26:12 qbix79 Exp $ */ #include #include @@ -161,7 +161,6 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { //another dot in the extension =>file not found //Or path not found depending on wether //we are still in dir check stage or file stage - LOG_MSG("stop = %d",stop); if(stop) DOS_SetError(DOSERR_FILE_NOT_FOUND); else From 9f649f01b4dae094f442c36539cb7334075c5cfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 20 Jan 2009 20:01:04 +0000 Subject: [PATCH 3179/4131] better use the ratio after it is updated... Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3267 --- src/dosbox.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 9601f0fc..c75fb8a8 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.140 2009-01-14 20:50:22 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.141 2009-01-20 20:01:04 c2woody Exp $ */ #include #include @@ -176,8 +176,8 @@ increaseticks: to have smoother auto cycle adjustments */ double ratioremoved = (double) CPU_IODelayRemoved / (double) cproc; if (ratioremoved < 1.0) { - Bit64s cmax_scaled = (Bit64s)CPU_CycleMax * (Bit64s)ratio; ratio = (Bit32s)((double)ratio * (1 - ratioremoved)); + Bit64s cmax_scaled = (Bit64s)CPU_CycleMax * (Bit64s)ratio; if (ratio <= 1024) new_cmax = (Bit32s)(cmax_scaled / (Bit64s)1024); else From 8bba45ae042c1003bc3eeaf61f2949c926b361f7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 21 Jan 2009 21:50:23 +0000 Subject: [PATCH 3180/4131] Add reboot handler and some more bios strings. (h-a-l-9000, Beta2) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3268 --- src/ints/bios.cpp | 55 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 00daf8e0..5f423f5b 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.72 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: bios.cpp,v 1.73 2009-01-21 21:50:23 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -358,17 +358,17 @@ static Bitu INT8_Handler(void) { /* and running drive */ mem_writeb(BIOS_DRIVE_RUNNING,mem_readb(BIOS_DRIVE_RUNNING) & 0xF0); return CBRET_NONE; -}; +} #undef DOSBOX_CLOCKSYNC static Bitu INT1C_Handler(void) { return CBRET_NONE; -}; +} static Bitu INT12_Handler(void) { reg_ax=mem_readw(BIOS_MEMORY_SIZE); return CBRET_NONE; -}; +} static Bitu INT17_Handler(void) { LOG(LOG_BIOS,LOG_NORMAL)("INT17:Function %X",reg_ah); @@ -741,6 +741,24 @@ static Bitu INT15_Handler(void) { return CBRET_NONE; } +static Bitu Reboot_Handler(void) { + // switch to text mode, notify user (let's hope INT10 still works) + const char* const text = "\n\n Reboot requested, quitting now."; + reg_ax = 0; + CALLBACK_RunRealInt(0x10); + reg_ah = 0xe; + reg_bx = 0; + for(Bitu i = 0; i < strlen(text);i++) { + reg_al = text[i]; + CALLBACK_RunRealInt(0x10); + } + LOG_MSG(text); + double start = PIC_FullIndex(); + while((PIC_FullIndex()-start)<3000) CALLBACK_Idle(); + throw 1; + return CBRET_NONE; +} + void BIOS_ZeroExtendedSize(bool in) { if(in) other_memsystems++; else other_memsystems--; @@ -759,7 +777,7 @@ void BIOS_SetupDisks(void); class BIOS:public Module_base{ private: - CALLBACK_HandlerObject callback[10]; + CALLBACK_HandlerObject callback[11]; public: BIOS(Section* configuration):Module_base(configuration){ /* tandy DAC can be requested in tandy_sound.cpp by initializing this field */ @@ -815,7 +833,7 @@ public: BIOS_SetupKeyboard(); /* INT 17 Printer Routines */ - callback[5].Install(&INT17_Handler,CB_IRET,"Int 17 Printer"); + callback[5].Install(&INT17_Handler,CB_IRET_STI,"Int 17 Printer"); callback[5].Set_RealVec(0x17); /* INT 1A TIME and some other functions */ @@ -834,6 +852,16 @@ public: callback[9].Install(NULL,CB_IRQ9,"irq 9 bios"); callback[9].Set_RealVec(0x71); + /* Reboot */ + callback[10].Install(&Reboot_Handler,CB_IRET,"reboot"); + callback[10].Set_RealVec(0x18); + RealPt rptr = callback[10].Get_RealPointer(); + RealSetVec(0x19,rptr); + // set system BIOS entry point too + phys_writeb(0xFFFF0,0xEA); // FARJMP + phys_writew(0xFFFF1,RealOff(rptr)); // offset + phys_writew(0xFFFF3,RealSeg(rptr)); // segment + /* Irq 2 */ RealPt irq2pt=RealMake(0xf000,0xff55); /* Ghost busters 2 mt32 mode */ Bitu call_irq2=CALLBACK_Allocate(); @@ -850,6 +878,21 @@ public: else if (machine==MCH_PCJR) phys_writeb(0xffffe,0xfd); /* PCJr model */ else phys_writeb(0xffffe,0xfc); /* PC */ + // System BIOS identification + const char* const b_type = + "IBM COMPATIBLE 486 BIOS COPYRIGHT The DOSBox Team."; + for(Bitu i = 0; i < strlen(b_type); i++) phys_writeb(0xfe00e + i,b_type[i]); + + // System BIOS version + const char* const b_vers = + "DOSBox FakeBIOS v1.0"; + for(Bitu i = 0; i < strlen(b_vers); i++) phys_writeb(0xfe061+i,b_vers[i]); + + // write system BIOS date + const char* const b_date = "01/01/92"; + for(Bitu i = 0; i < strlen(b_date); i++) phys_writeb(0xffff5+i,b_date[i]); + phys_writeb(0xfffff,0x55); // signature + if (use_tandyDAC) { /* tandy DAC sound requested, see if soundblaster device is available */ if (Tandy_InitializeSB()) { From 5c0ae73150df1420ccffae4731e91f7498a440d7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Jan 2009 13:14:33 +0000 Subject: [PATCH 3181/4131] Add experimental evdev detection. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3269 --- src/gui/sdl_mapper.cpp | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 43b9a998..9d9aaac9 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.53 2009-01-09 23:10:44 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.54 2009-01-22 13:14:33 qbix79 Exp $ */ #include #include @@ -2333,7 +2333,11 @@ void MAPPER_Init(void) { } } } - +//Somehow including them at the top conflicts with something in setup.h +#ifdef LINUX +#include "SDL_syswm.h" +#include +#endif void MAPPER_StartUp(Section * sec) { Section_prop * section=static_cast(sec); mapper.sticks.num=0; @@ -2350,7 +2354,7 @@ void MAPPER_StartUp(Section * sec) { virtual_joysticks[0].axis_pos[i]=0; } - usescancodes=false; + usescancodes = false; if (section->Get_bool("usescancodes")) { usescancodes=true; @@ -2377,9 +2381,27 @@ void MAPPER_StartUp(Section * sec) { sdlkey_map[0x5E]=SDLK_RALT; sdlkey_map[0x40]=SDLK_KP5; sdlkey_map[0x41]=SDLK_KP6; -#elif !defined (WIN32) /* => Linux */ +#elif !defined (WIN32) /* => Linux & BSDs */ bool evdev_input = false; - +#ifdef LINUX + SDL_SysWMinfo info; + SDL_VERSION(&info.version); + if (SDL_GetWMInfo(&info)) { + XkbDescPtr desc = NULL; + if((desc = XkbGetMap(info.info.x11.display,XkbAllComponentsMask,XkbUseCoreKbd))) { + if(XkbGetNames(info.info.x11.display,XkbAllNamesMask,desc) == 0) { + const char* keycodes = XGetAtomName(info.info.x11.display, desc->names->keycodes); +// const char* geom = XGetAtomName(info.info.x11.display, desc->names->geometry); + if(keycodes) { + LOG(LOG_MISC,LOG_NORMAL)("keyboard type %s",keycodes); + if (strncmp(keycodes,"evdev",6) == 0) evdev_input = true; + } + XkbFreeNames(desc,XkbAllNamesMask,True); + } + XkbFreeClientMap(desc,0,True); + } + } +#endif if (evdev_input) { sdlkey_map[0x67]=SDLK_UP; sdlkey_map[0x6c]=SDLK_DOWN; From a81b9ffa5c810c60388767ea6392848e27abb99a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Jan 2009 21:44:14 +0000 Subject: [PATCH 3182/4131] counting is hard Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3270 --- src/gui/sdl_mapper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 9d9aaac9..a6b5f7bd 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.54 2009-01-22 13:14:33 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.55 2009-01-22 21:44:14 qbix79 Exp $ */ #include #include @@ -2394,7 +2394,7 @@ void MAPPER_StartUp(Section * sec) { // const char* geom = XGetAtomName(info.info.x11.display, desc->names->geometry); if(keycodes) { LOG(LOG_MISC,LOG_NORMAL)("keyboard type %s",keycodes); - if (strncmp(keycodes,"evdev",6) == 0) evdev_input = true; + if (strncmp(keycodes,"evdev",5) == 0) evdev_input = true; } XkbFreeNames(desc,XkbAllNamesMask,True); } From 0589064b991068ed14fa187513feab2720df46de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 23 Jan 2009 19:27:54 +0000 Subject: [PATCH 3183/4131] use layout name for auto kb layout detection, enable it by default; add secondary hungarian layout check (see sf patch #2528951 by etillite) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3271 --- src/dos/dos_keyboard_layout.cpp | 31 +++++++++++++++++++++++++++---- src/dosbox.cpp | 4 ++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index f71b6e83..36c4378a 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_keyboard_layout.cpp,v 1.16 2008-11-22 14:24:11 c2woody Exp $ */ +/* $Id: dos_keyboard_layout.cpp,v 1.17 2009-01-23 19:27:53 c2woody Exp $ */ #include "dosbox.h" #include "bios.h" @@ -1073,7 +1073,29 @@ public: Bits wants_dos_codepage = -1; if (!strncmp(layoutname,"auto",4)) { #if defined (WIN32) - DWORD cur_kb_layout = MAKELCID(LOWORD(GetKeyboardLayout(0)),SORT_DEFAULT); + WORD cur_kb_layout = LOWORD(GetKeyboardLayout(0)); + WORD cur_kb_subID = 0; + char layoutID_string[KL_NAMELENGTH]; + if (GetKeyboardLayoutName(layoutID_string)) { + if (strlen(layoutID_string) == 8) { + int cur_kb_layout_by_name = ((layoutID_string[4]-'0')<<12) + + ((layoutID_string[5]-'0')<<8) + + ((layoutID_string[6]-'0')<<4) + + ((layoutID_string[7]-'0')); + int subID = ((layoutID_string[0]-'0')<<12) + + ((layoutID_string[1]-'0')<<8) + + ((layoutID_string[2]-'0')<<4) + + ((layoutID_string[3]-'0')); + if ((cur_kb_layout_by_name>0) && (cur_kb_layout_by_name<65536)) { + // use layout ID extracted from the layout string + cur_kb_layout = (WORD)cur_kb_layout_by_name; + } + if ((subID>=0) && (subID<100)) { + // use sublanguage ID extracted from the layout string + cur_kb_subID = (WORD)subID; + } + } + } // try to match emulated keyboard layout with host-keyboardlayout // codepage 437 (standard) is preferred switch (cur_kb_layout) { @@ -1106,7 +1128,8 @@ public: wants_dos_codepage = 437; break; case 1038: - layoutname = "hu"; + if (cur_kb_subID==1) layoutname = "hu"; + else layoutname = "hu208"; break; case 1039: layoutname = "is161"; diff --git a/src/dosbox.cpp b/src/dosbox.cpp index c75fb8a8..90fdc3c4 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.141 2009-01-20 20:01:04 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.142 2009-01-23 19:27:54 c2woody Exp $ */ #include #include @@ -647,7 +647,7 @@ void DOSBOX_Init(void) { Pbool->Set_help("Enable UMB support."); secprop->AddInitFunction(&DOS_KeyboardLayout_Init,true); - Pstring = secprop->Add_string("keyboardlayout",Property::Changeable::WhenIdle, "none"); + Pstring = secprop->Add_string("keyboardlayout",Property::Changeable::WhenIdle, "auto"); Pstring->Set_help("Language code of the keyboard layout (or none)."); // Mscdex From d25f38427628cc481d99db2b64d5005a82dc0d47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 24 Jan 2009 16:22:55 +0000 Subject: [PATCH 3184/4131] don't append randomized extension for create temporary file dos call (thanks to hal for reporting, fixes warcraft2) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3272 --- src/dos/dos_files.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index ddf42e0c..0f4da6a3 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.104 2009-01-19 20:26:12 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.105 2009-01-24 16:22:55 c2woody Exp $ */ #include #include @@ -609,7 +609,7 @@ bool DOS_GetFileAttr(char const * const name,Bit16u * attr) { } } -bool DOS_SetFileAttr(char const * const name,Bit16u attr) +bool DOS_SetFileAttr(char const * const name,Bit16u /*attr*/) // this function does not change the file attributs // it just does some tests if file is available // returns false when using on cdrom (stonekeep) @@ -716,11 +716,7 @@ bool DOS_CreateTempFile(char * const name,Bit16u * entry) { for (i=0;i<8;i++) { tempname[i]=(rand()%26)+'A'; } - tempname[8]='.'; - for (i=9;i<12;i++) { - tempname[i]=(rand()%26)+'A'; - } - tempname[12]=0; + tempname[8]=0; } while ((!DOS_CreateFile(name,0,entry)) && (dos.errorcode==DOSERR_FILE_ALREADY_EXISTS)); if (dos.errorcode) return false; return true; @@ -781,7 +777,7 @@ Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u * fcb_name.part.drive[0]=0; hasdrive=true; if (isalpha(string[0]) && Drives[toupper(string[0])-'A']) { - fcb_name.part.drive[0]=toupper(string[0])-'A'+1; + fcb_name.part.drive[0]=(char)(toupper(string[0])-'A'+1); } else ret=0xff; string+=2; } @@ -809,7 +805,7 @@ Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u * if (!finished) { if (string[0]=='*') {fill='?';fcb_name.part.name[index]='?';if (!ret) ret=1;finished=true;} else if (string[0]=='?') {fcb_name.part.name[index]='?';if (!ret) ret=1;} - else if (isvalid(string[0])) {fcb_name.part.name[index]=toupper(string[0]);} + else if (isvalid(string[0])) {fcb_name.part.name[index]=(char)(toupper(string[0]));} else { finished=true;continue; } string++; } else { @@ -826,7 +822,7 @@ checkext: if (!finished) { if (string[0]=='*') {fill='?';fcb_name.part.ext[index]='?';finished=true;} else if (string[0]=='?') {fcb_name.part.ext[index]='?';if (!ret) ret=1;} - else if (isvalid(string[0])) {fcb_name.part.ext[index]=toupper(string[0]);} + else if (isvalid(string[0])) {fcb_name.part.ext[index]=(char)(toupper(string[0]));} else { finished=true;continue; } string++; } else { @@ -1015,7 +1011,7 @@ Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { if (restore) fcb.GetRecord(old_block,old_rec);//store this for after the read. // Read records for (int i=0; i Date: Sun, 25 Jan 2009 12:00:52 +0000 Subject: [PATCH 3185/4131] hercules updates from hal (fixes jet) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3273 --- src/hardware/vga_misc.cpp | 59 ++++++++++---------------------------- src/hardware/vga_other.cpp | 31 +++++++++++++++++++- src/ints/int10.cpp | 14 ++++----- src/ints/int10_modes.cpp | 18 ++++-------- src/shell/shell_cmds.cpp | 12 ++++---- 5 files changed, 63 insertions(+), 71 deletions(-) diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 4e68727d..4773f936 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_misc.cpp,v 1.38 2009-01-11 18:22:59 c2woody Exp $ */ +/* $Id: vga_misc.cpp,v 1.39 2009-01-25 12:00:49 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -31,54 +31,27 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen); Bitu vga_read_p3d5(Bitu port,Bitu iolen); Bitu vga_read_p3da(Bitu port,Bitu iolen) { - vga.internal.attrindex=false; - vga.tandy.pcjr_flipflop=false; Bit8u retval=0; double timeInFrame = PIC_FullIndex()-vga.draw.delay.framestart; - vga.internal.attrindex=false; - vga.tandy.pcjr_flipflop=false; + vga.internal.attrindex=false; + vga.tandy.pcjr_flipflop=false; - if (machine!=MCH_HERC) { - // 3DAh (R): Status Register - // bit 0 Horizontal or Vertical blanking - // 3 Vertical sync + // 3DAh (R): Status Register + // bit 0 Horizontal or Vertical blanking + // 3 Vertical sync - if (timeInFrame >= vga.draw.delay.vrstart && - timeInFrame <= vga.draw.delay.vrend) - retval |= 8; - if (timeInFrame >= vga.draw.delay.vdend) { - retval |= 1; - } else { - double timeInLine=fmod(timeInFrame,vga.draw.delay.htotal); - if (timeInLine >= vga.draw.delay.hblkstart && - timeInLine <= vga.draw.delay.hblkend) { - retval |= 1; - } - } + if (timeInFrame >= vga.draw.delay.vrstart && + timeInFrame <= vga.draw.delay.vrend) + retval |= 8; + if (timeInFrame >= vga.draw.delay.vdend) { + retval |= 1; } else { - // 3BAh (R): Status Register - // bit 0 Horizontal sync - // 1 Light pen status (only some cards) - // 3 Video signal - // 4-6 000: Hercules - // 001: Hercules Plus - // 101: Hercules InColor - // 111: Unknown clone - // 7 Vertical sync inverted - - retval=0x72; // Hercules ident; from a working card (Winbond W86855AF) - // Another known working card has 0x76 ("KeysoGood", full-length) - if (timeInFrame < vga.draw.delay.vrstart || - timeInFrame > vga.draw.delay.vrend) retval |= 0x80; - double timeInLine=fmod(timeInFrame,vga.draw.delay.htotal); - if (timeInLine >= vga.draw.delay.hrstart && - timeInLine <= vga.draw.delay.hrend) retval |= 0x1; - - // 688 Attack sub checks bit 3 - as a workaround have the bit enabled - // if no sync active (corresponds to a completely white screen) - if ((retval&0x81)==0x80) retval |= 0x8; + if (timeInLine >= vga.draw.delay.hblkstart && + timeInLine <= vga.draw.delay.hblkend) { + retval |= 1; + } } return retval; } @@ -178,7 +151,5 @@ void VGA_SetupMisc(void) { } } else if (machine==MCH_CGA || IS_TANDY_ARCH) { IO_RegisterReadHandler(0x3da,vga_read_p3da,IO_MB); - } else if (machine==MCH_HERC) { - IO_RegisterReadHandler(0x3ba,vga_read_p3da,IO_MB); } } diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 800827b0..5b666bf4 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_other.cpp,v 1.24 2009-01-11 18:22:59 c2woody Exp $ */ +/* $Id: vga_other.cpp,v 1.25 2009-01-25 12:00:51 c2woody Exp $ */ #include #include @@ -24,6 +24,7 @@ #include "inout.h" #include "vga.h" #include "mem.h" +#include "pic.h" #include "render.h" #include "mapper.h" @@ -475,6 +476,33 @@ static void write_hercules(Bitu port,Bitu val,Bitu iolen) { return 0; } */ +Bitu read_herc_status(Bitu port,Bitu iolen) { + // 3BAh (R): Status Register + // bit 0 Horizontal sync + // 1 Light pen status (only some cards) + // 3 Video signal + // 4-6 000: Hercules + // 001: Hercules Plus + // 101: Hercules InColor + // 111: Unknown clone + // 7 Vertical sync inverted + + double timeInFrame = PIC_FullIndex()-vga.draw.delay.framestart; + Bit8u retval=0x72; // Hercules ident; from a working card (Winbond W86855AF) + // Another known working card has 0x76 ("KeysoGood", full-length) + if (timeInFrame < vga.draw.delay.vrstart || + timeInFrame > vga.draw.delay.vrend) retval |= 0x80; + + double timeInLine=fmod(timeInFrame,vga.draw.delay.htotal); + if (timeInLine >= vga.draw.delay.hrstart && + timeInLine <= vga.draw.delay.hrend) retval |= 0x1; + + // 688 Attack sub checks bit 3 - as a workaround have the bit enabled + // if no sync active (corresponds to a completely white screen) + if ((retval&0x81)==0x80) retval |= 0x8; + return retval; +} + void VGA_SetupOther(void) { Bitu i; @@ -532,6 +560,7 @@ void VGA_SetupOther(void) { vga.crtc.underline_location = 13; IO_RegisterWriteHandler(0x3b8,write_hercules,IO_MB); IO_RegisterWriteHandler(0x3bf,write_hercules,IO_MB); + IO_RegisterReadHandler(0x3ba,read_herc_status,IO_MB); } if (machine==MCH_CGA) { Bitu base=0x3d0; diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 9a5cbff0..0f51dcf6 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.cpp,v 1.53 2008-10-05 14:44:52 qbix79 Exp $ */ +/* $Id: int10.cpp,v 1.54 2009-01-25 12:00:52 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -442,7 +442,7 @@ graphics_chars: for (ct=0; ct @@ -432,11 +432,6 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { } break; case MCH_HERC: - if (mode!=7) { - //Just the text memory, most games seem to use any random mode to clear the screen - for (i=0;i<16*1024;i++) real_writew(0xb000,i*2,0x0720); - return false; - } CurMode=&Hercules_Mode; break; } @@ -504,11 +499,9 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { IO_WriteB(0x3b8,0x28); // TEXT mode and blinking characters VGA_DAC_CombineColor(0,0); - VGA_DAC_CombineColor(8,0); - for ( i = 1; i < 8;i++) { - VGA_DAC_CombineColor(i,0x7); - VGA_DAC_CombineColor(i+8,0xf); - } + VGA_DAC_CombineColor(1,7); + + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x29); // attribute controls blinking break; case MCH_CGA: mode_control=mode_control_list[CurMode->mode]; @@ -1210,7 +1203,8 @@ dac_text16: case 0:real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x2c);break; case 1:real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x28);break; case 2:real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x2d);break; - case 3:real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x29);break; + case 3: + case 7:real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x29);break; } break; case M_LIN4: diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 1c659c38..8034e170 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.85 2009-01-11 18:22:59 c2woody Exp $ */ +/* $Id: shell_cmds.cpp,v 1.86 2009-01-25 12:00:52 c2woody Exp $ */ #include "dosbox.h" #include "shell.h" @@ -167,9 +167,7 @@ void DOS_Shell::DoCommand(char * line) { void DOS_Shell::CMD_CLS(char * args) { HELP("CLS"); - // 3 is not good for hercules as it 'forgets' to reset the cursor position - if (machine==MCH_HERC) reg_ax=0x0007; - else reg_ax=0x0003; + reg_ax=0x0003; CALLBACK_RunRealInt(0x10); } @@ -907,7 +905,7 @@ void DOS_Shell::CMD_SUBST (char * args) { command.FindCommand(1,arg); if( (arg.size()>1) && arg[1] !=':') throw(0); - temp_str[0]=toupper(args[0]); + temp_str[0]=(char)toupper(args[0]); if(Drives[temp_str[0]-'A'] ) throw 0; //targetdrive in use strcat(mountstring,temp_str); strcat(mountstring," "); @@ -981,7 +979,7 @@ void DOS_Shell::CMD_CHOICE(char * args){ if (!rem || !*rem) rem = defchoice; /* No choices specified use YN */ ptr = rem; Bit8u c; - if(!optS) while ((c = *ptr)) *ptr++ = toupper(c); /* When in no case-sensitive mode. make everything upcase */ + if(!optS) while ((c = *ptr)) *ptr++ = (char)toupper(c); /* When in no case-sensitive mode. make everything upcase */ if(args && *args ) { StripSpaces(args); size_t argslen = strlen(args); @@ -1006,7 +1004,7 @@ void DOS_Shell::CMD_CHOICE(char * args){ do { DOS_ReadFile (STDIN,&c,&n); } while (!c || !(ptr = strchr(rem,(optS?c:toupper(c))))); - c = optS?c:toupper(c); + c = optS?c:(Bit8u)toupper(c); DOS_WriteFile (STDOUT,&c, &n); dos.return_code = (Bit8u)(ptr-rem+1); } From 6945f3e81fa73e352bbc0f14cb64d6df8e41b147 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 26 Jan 2009 20:15:58 +0000 Subject: [PATCH 3186/4131] Enable directserial for BSD. (talked it over with the FreeBSD maintainer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3274 --- configure.in | 3 ++- src/hardware/serialport/directserial_posix.cpp | 4 ++-- src/hardware/serialport/directserial_posix.h | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/configure.in b/configure.in index 3ac3a61a..3cf4bc49 100644 --- a/configure.in +++ b/configure.in @@ -438,7 +438,8 @@ case "$target" in 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 - dnl AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).]) + 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]) diff --git a/src/hardware/serialport/directserial_posix.cpp b/src/hardware/serialport/directserial_posix.cpp index 5b6c9db4..a13aec94 100644 --- a/src/hardware/serialport/directserial_posix.cpp +++ b/src/hardware/serialport/directserial_posix.cpp @@ -16,14 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_posix.cpp,v 1.2 2007-08-26 17:19:46 qbix79 Exp $ */ +/* $Id: directserial_posix.cpp,v 1.3 2009-01-26 20:15:58 qbix79 Exp $ */ #include "dosbox.h" #if C_DIRECTSERIAL // Posix version -#if defined (LINUX) || defined (MACOSX) +#if defined (LINUX) || defined (MACOSX) || defined (BSD) #include "serialport.h" #include "directserial_posix.h" diff --git a/src/hardware/serialport/directserial_posix.h b/src/hardware/serialport/directserial_posix.h index 93c7d6a3..00bb0077 100644 --- a/src/hardware/serialport/directserial_posix.h +++ b/src/hardware/serialport/directserial_posix.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_posix.h,v 1.2 2007-08-26 17:19:46 qbix79 Exp $ */ +/* $Id: directserial_posix.h,v 1.3 2009-01-26 20:15:58 qbix79 Exp $ */ // include guard #ifndef DOSBOX_DIRECTSERIAL_POSIX_H @@ -25,7 +25,7 @@ #include "dosbox.h" #if C_DIRECTSERIAL -#if defined (LINUX) || defined (MACOSX) +#if defined (LINUX) || defined (MACOSX) || defined (BSD) From 5a228425fd27f7108391aa9e7fb5b56eb3650b57 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 26 Jan 2009 20:23:44 +0000 Subject: [PATCH 3187/4131] patch to latch bytepanning at display start. Fixes some graphic distortion with commanche. (Danke h-a-l-9000) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3275 --- include/vga.h | 3 ++- src/hardware/vga_draw.cpp | 11 ++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/include/vga.h b/include/vga.h index c995dfe0..de5b8292 100644 --- a/include/vga.h +++ b/include/vga.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga.h,v 1.44 2008-08-24 16:43:06 qbix79 Exp $ */ +/* $Id: vga.h,v 1.45 2009-01-26 20:23:44 qbix79 Exp $ */ #ifndef DOSBOX_VGA_H #define DOSBOX_VGA_H @@ -119,6 +119,7 @@ typedef struct { Bitu blocks; Bitu address; Bitu panning; + Bitu bytes_skip; Bit8u *linear_base; Bitu linear_mask; Bitu address_add; diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 5fc6957c..3d5624bd 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.105 2009-01-11 18:22:59 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.106 2009-01-26 20:23:44 qbix79 Exp $ */ #include #include @@ -609,7 +609,7 @@ static void VGA_ProcessSplit() { } else { // In text mode only the characters are shifted by panning, not the address; // this is done in the text line draw function. - vga.draw.address = vga.draw.byte_panning_shift*vga.config.bytes_skip; + vga.draw.address = vga.draw.byte_panning_shift*vga.draw.bytes_skip; if (!(vga.mode==M_TEXT)) vga.draw.address += vga.draw.panning; } vga.draw.address_line=0; @@ -717,6 +717,7 @@ static void VGA_VertInterrupt(Bitu /*val*/) { static void VGA_DisplayStartLatch(Bitu /*val*/) { vga.config.real_start=vga.config.display_start & (vga.vmemwrap-1); + vga.draw.bytes_skip = vga.config.bytes_skip; } static void VGA_PanningLatch(Bitu /*val*/) { @@ -780,7 +781,7 @@ static void VGA_VerticalTimer(Bitu /*val*/) { case M_EGA: case M_LIN4: vga.draw.byte_panning_shift = 8; - vga.draw.address += vga.config.bytes_skip; + vga.draw.address += vga.draw.bytes_skip; vga.draw.address *= vga.draw.byte_panning_shift; vga.draw.address += vga.draw.panning; #ifdef VGA_KEEP_CHANGES @@ -800,7 +801,7 @@ static void VGA_VerticalTimer(Bitu /*val*/) { case M_LIN16: case M_LIN32: vga.draw.byte_panning_shift = 4; - vga.draw.address += vga.config.bytes_skip; + vga.draw.address += vga.draw.bytes_skip; vga.draw.address *= vga.draw.byte_panning_shift; vga.draw.address += vga.draw.panning; #ifdef VGA_KEEP_CHANGES @@ -812,7 +813,7 @@ static void VGA_VerticalTimer(Bitu /*val*/) { else vga.draw.byte_panning_shift = 0; if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) vga.draw.address = vga.config.real_start * 2; else vga.draw.address = vga.config.display_start * 2; - vga.draw.address += vga.config.bytes_skip*vga.draw.byte_panning_shift; + vga.draw.address += vga.draw.bytes_skip*vga.draw.byte_panning_shift; case M_TANDY_TEXT: case M_HERC_TEXT: vga.draw.cursor.address=vga.config.cursor_start*2; From 0b3d75997e2dcd6297ea3150b31ce0c2a956fd34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 29 Jan 2009 23:17:59 +0000 Subject: [PATCH 3188/4131] fix layout extraction Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3276 --- src/dos/dos_keyboard_layout.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 36c4378a..90d55d84 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_keyboard_layout.cpp,v 1.17 2009-01-23 19:27:53 c2woody Exp $ */ +/* $Id: dos_keyboard_layout.cpp,v 1.18 2009-01-29 23:17:59 c2woody Exp $ */ #include "dosbox.h" #include "bios.h" @@ -1078,14 +1078,9 @@ public: char layoutID_string[KL_NAMELENGTH]; if (GetKeyboardLayoutName(layoutID_string)) { if (strlen(layoutID_string) == 8) { - int cur_kb_layout_by_name = ((layoutID_string[4]-'0')<<12) + - ((layoutID_string[5]-'0')<<8) + - ((layoutID_string[6]-'0')<<4) + - ((layoutID_string[7]-'0')); - int subID = ((layoutID_string[0]-'0')<<12) + - ((layoutID_string[1]-'0')<<8) + - ((layoutID_string[2]-'0')<<4) + - ((layoutID_string[3]-'0')); + int cur_kb_layout_by_name = ConvHexWord((char*)&layoutID_string[4]); + layoutID_string[4] = 0; + int subID = ConvHexWord((char*)&layoutID_string[0]); if ((cur_kb_layout_by_name>0) && (cur_kb_layout_by_name<65536)) { // use layout ID extracted from the layout string cur_kb_layout = (WORD)cur_kb_layout_by_name; @@ -1112,6 +1107,9 @@ public: layoutname = "gr"; wants_dos_codepage = 437; break; + case 1033: + // US + return; case 1032: layoutname = "gk"; break; From d584afc0ef118640d01eddc8377982c499afd5cd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 11:07:11 +0000 Subject: [PATCH 3189/4131] Rename mixer => sbmixer. Add Wari hack (beta2) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3277 --- src/dosbox.cpp | 4 ++-- src/hardware/sblaster.cpp | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 90fdc3c4..2faf54ca 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.142 2009-01-23 19:27:54 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.143 2009-02-01 11:07:11 qbix79 Exp $ */ #include #include @@ -499,7 +499,7 @@ void DOSBOX_Init(void) { Pint->Set_values(dmassb); Pint->Set_help("The High DMA number of the soundblaster."); - Pbool = secprop->Add_bool("mixer",Property::Changeable::WhenIdle,true); + Pbool = secprop->Add_bool("sbmixer",Property::Changeable::WhenIdle,true); Pbool->Set_help("Allow the soundblaster mixer to modify the DOSBox mixer."); const char* opltypes[]={ "auto", "cms", "opl2", "dualopl2", "opl3", "none", 0}; diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 5bc3e801..dd72b40f 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.70 2008-09-13 20:04:28 c2woody Exp $ */ +/* $Id: sblaster.cpp,v 1.71 2009-02-01 11:07:11 qbix79 Exp $ */ #include #include @@ -163,7 +163,8 @@ static char const * const copyright_string="COPYRIGHT (C) CREATIVE TECHNOLOGY LT // number of bytes in input for commands (sb/sbpro) static Bit8u DSP_cmd_len_sb[256] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00 - 1,0,0,0, 2,0,2,2, 0,0,0,0, 0,0,0,0, // 0x10 +// 1,0,0,0, 2,0,2,2, 0,0,0,0, 0,0,0,0, // 0x10 + 1,0,0,0, 2,2,2,2, 0,0,0,0, 0,0,0,0, // 0x10 Wari hack 0,0,0,0, 2,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 0,0,0,0, 0,0,0,0, 1,0,0,0, 0,0,0,0, // 0x30 @@ -186,7 +187,8 @@ static Bit8u DSP_cmd_len_sb[256] = { // number of bytes in input for commands (sb16) static Bit8u DSP_cmd_len_sb16[256] = { 0,0,0,0, 1,2,0,0, 1,0,0,0, 0,0,2,1, // 0x00 - 1,0,0,0, 2,0,2,2, 0,0,0,0, 0,0,0,0, // 0x10 +// 1,0,0,0, 2,0,2,2, 0,0,0,0, 0,0,0,0, // 0x10 + 1,0,0,0, 2,2,2,2, 0,0,0,0, 0,0,0,0, // 0x10 Wari hack 0,0,0,0, 2,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 0,0,0,0, 0,0,0,0, 1,0,0,0, 0,0,0,0, // 0x30 @@ -800,6 +802,7 @@ static void DSP_DoCommand(void) { GetDMAChannel(sb.hw.dma8)->Register_Callback(DSP_ADC_CallBack); break; case 0x14: /* Singe Cycle 8-Bit DMA DAC */ + case 0x15: /* Wari hack. Waru uses this one instead of 0x14, but some weird stuff going on there anyway */ case 0x91: /* Singe Cycle 8-Bit DMA High speed DAC */ /* Note: 0x91 is documented only for DSP ver.2.x and 3.x, not 4.x */ DSP_PrepareDMA_Old(DSP_DMA_8,false,false); @@ -1460,7 +1463,7 @@ public: sb.hw.irq=section->Get_int("irq"); sb.hw.dma8=section->Get_int("dma"); sb.hw.dma16=section->Get_int("hdma"); - sb.mixer.enabled=section->Get_bool("mixer"); + sb.mixer.enabled=section->Get_bool("sbmixer"); sb.mixer.stereo=false; OPL_Mode opl_mode = OPL_none; Find_Type_And_Opl(section,sb.type,opl_mode); From 9b8cd3721fba7097911987952108ce748864cdf5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 14:06:36 +0000 Subject: [PATCH 3190/4131] Quick and dirty fix for IF. Needs revisiting later. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3278 --- src/shell/shell_cmds.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 8034e170..c3eaa5c3 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.86 2009-01-25 12:00:52 c2woody Exp $ */ +/* $Id: shell_cmds.cpp,v 1.87 2009-02-01 14:06:36 qbix79 Exp $ */ #include "dosbox.h" #include "shell.h" @@ -24,7 +24,7 @@ #include "regs.h" #include "../dos/drives.h" #include "support.h" -#include "setup.h" +#include "control.h" #include #include #include @@ -748,11 +748,11 @@ void DOS_Shell::CMD_IF(char * args) { bool has_not=false; char* word; - if (strncasecmp(args,"NOT ",4) ==0) { + while(strncasecmp(args,"NOT ",4) ==0) { args += 4; //skip text //skip more spaces StripSpaces(args); - has_not = true; + has_not = !has_not; } if(strncasecmp(args,"ERRORLEVEL",10) == 0) { @@ -810,7 +810,11 @@ void DOS_Shell::CMD_IF(char * args) { } args += 2; StripSpaces(args); - char* woord2 = StripWord(args); + char* woord2 = args; + // Word is until space or = + while(*args && !isspace(*reinterpret_cast(args)) && (*args != '=')) + args++; + *args++=0; *end_word1 = 0; if ((strcmp(word,woord2)==0)==(!has_not)) DoCommand(args); } From bb4141a03a46c5a1246e3cdc19ea47a36c308ed1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 14:07:05 +0000 Subject: [PATCH 3191/4131] headers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3279 --- src/shell/shell.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 395fdcac..efd621f5 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,14 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.96 2009-01-11 18:22:59 c2woody Exp $ */ +/* $Id: shell.cpp,v 1.97 2009-02-01 14:07:05 qbix79 Exp $ */ #include #include #include #include "dosbox.h" #include "regs.h" -#include "setup.h" +#include "control.h" #include "shell.h" #include "callback.h" #include "support.h" From c11d55a223814ee0568cea586f30cf30383bc567 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 14:11:45 +0000 Subject: [PATCH 3192/4131] Reorder headers a bit. Add control.h and bios_disk.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3280 --- include/Makefile.am | 2 + include/bios.h | 61 +------------------------------ include/bios_disk.h | 85 +++++++++++++++++++++++++++++++++++++++++++ include/control.h | 87 ++++++++++++++++++++++++++++++++++++++++++++ include/cross.h | 15 +++++++- include/serialport.h | 9 +++-- include/setup.h | 54 +++++++-------------------- 7 files changed, 209 insertions(+), 104 deletions(-) create mode 100644 include/bios_disk.h create mode 100644 include/control.h diff --git a/include/Makefile.am b/include/Makefile.am index ce2c03c0..b37389c8 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,8 +1,10 @@ noinst_HEADERS = \ bios.h \ +bios_disk.h \ callback.h \ cpu.h \ cross.h \ +control.h \ debug.h \ dma.h \ dos_inc.h \ diff --git a/include/bios.h b/include/bios.h index 66b09ba4..0245cdaf 100644 --- a/include/bios.h +++ b/include/bios.h @@ -105,66 +105,9 @@ #define MAX_SCAN_CODE 0x58 /* The Section handling Bios Disk Access */ -#define BIOS_MAX_DISK 10 +//#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[]; - -#include -#ifndef DOSBOX_MEM_H -#include "mem.h" -#endif -#ifndef DOSBOX_DOS_INC_H -#include "dos_inc.h" -#endif - -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); +//#define MAX_SWAPPABLE_DISKS 20 void BIOS_ZeroExtendedSize(bool in); void char_out(Bit8u chr,Bit32u att,Bit8u page); diff --git a/include/bios_disk.h b/include/bios_disk.h new file mode 100644 index 00000000..7f5d97cc --- /dev/null +++ b/include/bios_disk.h @@ -0,0 +1,85 @@ +/* + * 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 +#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 diff --git a/include/control.h b/include/control.h new file mode 100644 index 00000000..5076fbb8 --- /dev/null +++ b/include/control.h @@ -0,0 +1,87 @@ +/* + * 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 +#endif + +#ifndef CH_VECTOR +#define CH_VECTOR +#include +#endif + +#ifndef CH_STRING +#define CH_STRING +#include +#endif + + + + +class Config{ +public: + CommandLine * cmdline; +private: + std::list sectionlist; + typedef std::list::iterator it; + typedef std::list::reverse_iterator reverse_it; + typedef std::list::const_iterator const_it; + typedef std::list::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 diff --git a/include/cross.h b/include/cross.h index 5b0ae608..d92379e4 100644 --- a/include/cross.h +++ b/include/cross.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.h,v 1.18 2007-01-08 19:45:37 qbix79 Exp $ */ +/* $Id: cross.h,v 1.19 2009-02-01 14:11:45 qbix79 Exp $ */ #ifndef DOSBOX_CROSS_H #define DOSBOX_CROSS_H @@ -28,6 +28,7 @@ #include #include #include +#include #if defined (_MSC_VER) /* MS Visual C++ */ #include @@ -66,4 +67,14 @@ 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); +}; + + #endif diff --git a/include/serialport.h b/include/serialport.h index 7ed273d8..f1016031 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.h,v 1.15 2007-12-06 17:44:19 qbix79 Exp $ */ +/* $Id: serialport.h,v 1.16 2009-02-01 14:11:45 qbix79 Exp $ */ #ifndef DOSBOX_SERIALPORT_H #define DOSBOX_SERIALPORT_H @@ -35,9 +35,12 @@ #ifndef DOSBOX_TIMER_H #include "timer.h" #endif - +#ifndef DOSBOX_DOS_INC_H #include "dos_inc.h" -#include "setup.h" +#endif +#ifndef DOSBOX_PROGRAMS_H +#include "programs.h" +#endif #if SERIAL_DEBUG #include "hardware.h" diff --git a/include/setup.h b/include/setup.h index 8e9d4a8a..1a048d60 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.38 2008-08-06 18:31:10 c2woody Exp $ */ +/* $Id: setup.h,v 1.39 2009-02-01 14:11:45 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -26,12 +26,6 @@ #pragma warning ( disable : 4290 ) #endif -#ifndef DOSBOX_CROSS_H -#include "cross.h" -#endif -#ifndef DOSBOX_PROGRAMS_H -#include "programs.h" -#endif #ifndef CH_LIST #define CH_LIST @@ -199,6 +193,17 @@ public: void SetValue(std::string const& in); ~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: @@ -254,6 +259,7 @@ 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); @@ -266,6 +272,7 @@ public: 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); @@ -309,39 +316,6 @@ public: std::string data; }; -class Config{ -public: - CommandLine * cmdline; -private: - std::list sectionlist; - typedef std::list::iterator it; - typedef std::list::reverse_iterator reverse_it; - typedef std::list::const_iterator const_it; - typedef std::list::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(); - void 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 -}; - class Module_base { /* Base for all hardware and software "devices" */ protected: From 21408ee979661279105b14a7c60ed52ce58a59bf Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 14:14:51 +0000 Subject: [PATCH 3193/4131] Add new files. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3281 --- visualc_net/dosbox.vcproj | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 0e7a1f22..28b0d83c 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -731,6 +731,9 @@ + + @@ -780,9 +783,15 @@ + + + + From 77362e66f24e1ca97098f90f3e7594f0aa909362 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 14:16:52 +0000 Subject: [PATCH 3194/4131] Added cross.cpp, which has functions for the configuration file locations. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3282 --- src/misc/Makefile.am | 2 +- src/misc/cross.cpp | 105 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 src/misc/cross.cpp diff --git a/src/misc/Makefile.am b/src/misc/Makefile.am index 2cea9df3..968151af 100644 --- a/src/misc/Makefile.am +++ b/src/misc/Makefile.am @@ -1,4 +1,4 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libmisc.a -libmisc_a_SOURCES = programs.cpp messages.cpp support.cpp setup.cpp +libmisc_a_SOURCES = cross.cpp messages.cpp programs.cpp setup.cpp support.cpp diff --git a/src/misc/cross.cpp b/src/misc/cross.cpp new file mode 100644 index 00000000..d444c993 --- /dev/null +++ b/src/misc/cross.cpp @@ -0,0 +1,105 @@ +/* + * 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: cross.cpp,v 1.1 2009-02-01 14:16:52 qbix79 Exp $ */ + +#include "dosbox.h" +#include "cross.h" +#include + +#ifdef WIN32 +#define _WIN32_IE 0x0400 +#include +#endif + +#if defined HAVE_SYS_TYPES_H && defined HAVE_PWD_H +#include +#include +#endif + + +void Cross::GetPlatformConfigDir(std::string& in) { +#ifdef WIN32 + char result[MAX_PATH] = { 0 }; + SHGetSpecialFolderPath(NULL,result,CSIDL_LOCAL_APPDATA,0); + in = result; + in += "\\DOSBox"; +#elif defined(MACOSX) + in = "/Library/Preferences"; + ResolveHomedir(in); +#else + in = "~/.dosbox"; + ResolveHomedir(in); +#endif + in += CROSS_FILESPLIT; +} + +void Cross::GetPlatformConfigName(std::string& in) { +#ifdef WIN32 +#define DEFAULT_CONFIG_FILE "dosbox-" VERSION ".conf" +#elif defined(MACOSX) +#define DEFAULT_CONFIG_FILE "DOSBox " VERSION " Preferences" +#else /*linux freebsd*/ +#define DEFAULT_CONFIG_FILE "dosbox-" VERSION ".conf" +#endif + in = DEFAULT_CONFIG_FILE; +} + +void Cross::CreatePlatformConfigDir(std::string& in) { +#ifdef WIN32 + char result[MAX_PATH] = { 0 }; + SHGetSpecialFolderPath(NULL,result,CSIDL_LOCAL_APPDATA,1); //1 at end is create + in = result; + in += "\\DOSBox"; + mkdir(in.c_str()); +#elif defined(MACOSX) + in = "~/Library/Preferences/"; + ResolveHomedir(in); + //Don't create it. Assume it exists +#else + in = "~/.dosbox"; + ResolveHomedir(in); + mkdir(in.c_str(),0700); +#endif + in += CROSS_FILESPLIT; +} + +void Cross::ResolveHomedir(std::string & temp_line) { + if(!temp_line.size() || temp_line[0] != '~') return; //No ~ + + if(temp_line.size() == 1 || temp_line[1] == CROSS_FILESPLIT) { //The ~ and ~/ variant + char * home = getenv("HOME"); + if(home) temp_line.replace(0,1,std::string(home)); +#if defined HAVE_SYS_TYPES_H && defined HAVE_PWD_H + } else { // The ~username variant + std::string::size_type namelen = temp_line.find(CROSS_FILESPLIT); + if(namelen == std::string::npos) namelen = temp_line.size(); + std::string username = temp_line.substr(1,namelen - 1); + struct passwd* pass = getpwnam(username.c_str()); + if(pass) temp_line.replace(0,namelen,pass->pw_dir); //namelen -1 +1(for the ~) +#endif // USERNAME lookup code + } +} + +void Cross::CreateDir(std::string const& in) { +#ifdef WIN32 + mkdir(in.c_str()); +#else + mkdir(in.c_str(),0700); +#endif +} From 4a26ec8d4c789e255b0704c5e6294271ac6c0c95 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 14:18:12 +0000 Subject: [PATCH 3195/4131] headers, languagefile location new system. Fix console message which is unneeded. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3283 --- src/misc/messages.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 259b99ba..301174c0 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: messages.cpp,v 1.20 2008-02-10 11:14:03 qbix79 Exp $ */ +/* $Id: messages.cpp,v 1.21 2009-02-01 14:18:12 qbix79 Exp $ */ #include #include @@ -25,6 +25,7 @@ #include "cross.h" #include "support.h" #include "setup.h" +#include "control.h" #include #include using namespace std; @@ -47,7 +48,7 @@ void MSG_Add(const char * _name, const char* _val) { /* Find the message */ for(itmb tel=Lang.begin();tel!=Lang.end();tel++) { if((*tel).name==_name) { - LOG_MSG("double entry for %s",_name); +// LOG_MSG("double entry for %s",_name); //Message file might be loaded before default text messages return; } } @@ -133,5 +134,8 @@ void MSG_Init(Section_prop * section) { std::string file_name; if (control->cmdline->FindString("-lang",file_name,true)) { LoadMessageFile(file_name.c_str()); - } else LoadMessageFile(section->Get_string("language")); + } else { + Prop_path* pathprop = section->Get_path("language"); + if(pathprop) LoadMessageFile(pathprop->realpath.c_str()); + } } From 9ec3c20d7dd8d8049576b8480c8420d350e43528 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 14:19:20 +0000 Subject: [PATCH 3196/4131] Headers, Add Prop_path which is capable of resolving paths relatively and absolutely. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3284 --- src/misc/programs.cpp | 4 ++-- src/misc/setup.cpp | 56 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 0395406e..3176e911 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.34 2008-10-05 14:44:52 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.35 2009-02-01 14:19:20 qbix79 Exp $ */ #include #include @@ -29,7 +29,7 @@ #include "regs.h" #include "support.h" #include "cross.h" -#include "setup.h" +#include "control.h" #include "shell.h" Bitu call_program; diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 0347a3c6..09b7b392 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,11 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.51 2008-09-07 10:55:15 c2woody Exp $ */ +/* $Id: setup.cpp,v 1.52 2009-02-01 14:19:20 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" #include "setup.h" +#include "control.h" #include "support.h" #include #include @@ -30,7 +31,7 @@ #include using namespace std; - +static std::string current_config_dir; // Set by parseconfigfile so Prop_path can use it to construct the realpath void Value::destroy() throw(){ if (type == V_STRING) delete _string; } @@ -263,6 +264,25 @@ void Prop_string::SetValue(std::string const& input){ Value val(temp,Value::V_STRING); SetVal(val,false,true); } + +void Prop_path::SetValue(std::string const& input){ + //Special version to merge realpath with it + + Value val(input,Value::V_STRING); + SetVal(val,false,true); + + std::string workcopy(input); + Cross::ResolveHomedir(workcopy); //Parse ~ and friends + //Prepend config directory in it exists. Check for absolute paths later + if( current_config_dir.empty()) realpath = workcopy; + else realpath = current_config_dir + CROSS_FILESPLIT + workcopy; + //Absolute paths +#if defined (WIN32) || defined(OS2) + if( workcopy.size() > 2 && workcopy[1] == ':' ) realpath = workcopy; +#else + if( workcopy.size() > 1 && workcopy[0] == '/' ) realpath = workcopy; +#endif +} void Prop_bool::SetValue(std::string const& input){ value.SetValue(input,Value::V_BOOL); @@ -409,6 +429,12 @@ Prop_string* Section_prop::Add_string(string const& _propname, Property::Changea return test; } +Prop_path* Section_prop::Add_path(string const& _propname, Property::Changeable::Value when, char const * const _value) { + Prop_path* test=new Prop_path(_propname,when,_value); + properties.push_back(test); + return test; +} + Prop_bool* Section_prop::Add_bool(string const& _propname, Property::Changeable::Value when, bool _value) { Prop_bool* test=new Prop_bool(_propname,when,_value); properties.push_back(test); @@ -455,6 +481,17 @@ double Section_prop::Get_double(string const& _propname) const { } return 0.0; } + +Prop_path* Section_prop::Get_path(string const& _propname) const { + for(const_it tel=properties.begin();tel!=properties.end();tel++){ + if((*tel)->propname==_propname){ + Prop_path* val = dynamic_cast((*tel)); + if(val) return val; else return NULL; + } + } + return NULL; +} + Prop_multival* Section_prop::Get_multival(string const& _propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ @@ -552,10 +589,10 @@ string Section_line::GetPropValue(string const& /* _property*/) const { return NO_SUCH_PROPERTY; } -void Config::PrintConfig(char const * const configfilename) const { +bool Config::PrintConfig(char const * const configfilename) const { char temp[50];char helpline[256]; FILE* outfile=fopen(configfilename,"w+t"); - if(outfile==NULL) return; + if(outfile==NULL) return false; /* Print start of configfile and add an return to improve readibility. */ fprintf(outfile,MSG_Get("CONFIGFILE_INTRO"),VERSION); @@ -619,6 +656,7 @@ void Config::PrintConfig(char const * const configfilename) const { fprintf(outfile,"\n"); /* Always an empty line between sections */ } fclose(outfile); + return true; } @@ -651,6 +689,7 @@ void Config::Init() { (*tel)->ExecuteInit(); } } + void Section::AddInitFunction(SectionFunction func,bool canchange) { initfunctions.push_back(Function_wrapper(func,canchange)); } @@ -706,6 +745,7 @@ Section* Config::GetSectionFromProperty(char const * const prop) const{ return NULL; } + bool Config::ParseConfigFile(char const * const configfilename){ static bool first_configfile = true; ifstream in(configfilename); @@ -713,6 +753,13 @@ bool Config::ParseConfigFile(char const * const configfilename){ const char * settings_type = first_configfile?"primary":"additional"; first_configfile = false; LOG_MSG("CONFIG:Loading %s settings from config file %s", settings_type,configfilename); + + //Get directory from configfilename, used with relative paths. + current_config_dir=configfilename; + std::string::size_type pos = current_config_dir.rfind(CROSS_FILESPLIT); + if(pos == std::string::npos) pos = 0; //No directory then erase string + current_config_dir.erase(pos); + string gegevens; Section* currentsection = NULL; Section* testsec = NULL; @@ -750,6 +797,7 @@ bool Config::ParseConfigFile(char const * const configfilename){ break; } } + current_config_dir.clear();//So internal changes don't use the path information return true; } From 7a8c67326753385f3e658c0d41589da2a3787d27 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 14:21:19 +0000 Subject: [PATCH 3197/4131] Create directory if doesn't exist. Use Prop_path. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3285 --- src/hardware/hardware.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 8e7d7921..d2d74566 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: hardware.cpp,v 1.19 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: hardware.cpp,v 1.20 2009-02-01 14:21:19 qbix79 Exp $ */ #include #include @@ -30,13 +30,14 @@ #include "mapper.h" #include "pic.h" #include "render.h" +#include "cross.h" #if (C_SSHOT) #include #include "../libs/zmbv/zmbv.cpp" #endif -static char * capturedir; +static std::string capturedir; extern const char* RunningProgram; Bitu CaptureState; @@ -87,10 +88,16 @@ FILE * OpenCaptureFile(const char * type,const char * ext) { char file_start[16]; DIR * dir;struct dirent * dir_ent; /* Find a filename to open */ - dir=opendir(capturedir); + dir=opendir(capturedir.c_str()); if (!dir) { - LOG_MSG("Can't open dir %s for capturing %s",capturedir,type); - return 0; + //Try creating it first + Cross::CreateDir(capturedir); + dir=opendir(capturedir.c_str()); + if(!dir) { + + LOG_MSG("Can't open dir %s for capturing %s",capturedir.c_str(),type); + return 0; + } } strcpy(file_start,RunningProgram); lowcase(file_start); @@ -106,7 +113,7 @@ FILE * OpenCaptureFile(const char * type,const char * ext) { if (num>=last) last=num+1; } closedir(dir); - sprintf(file_name,"%s%c%s%03d%s",capturedir,CROSS_FILESPLIT,file_start,last,ext); + sprintf(file_name,"%s%c%s%03d%s",capturedir.c_str(),CROSS_FILESPLIT,file_start,last,ext); /* Open the actual file */ FILE * handle=fopen(file_name,"wb"); if (handle) { @@ -719,7 +726,8 @@ class HARDWARE:public Module_base{ public: HARDWARE(Section* configuration):Module_base(configuration){ Section_prop * section = static_cast(configuration); - capturedir = (char *)section->Get_string("captures"); + Prop_path* proppath= section->Get_path("captures"); + capturedir = proppath->realpath; CaptureState = 0; MAPPER_AddHandler(CAPTURE_WaveEvent,MK_f6,MMOD1,"recwave","Rec Wave"); MAPPER_AddHandler(CAPTURE_MidiEvent,MK_f8,MMOD1|MMOD2,"caprawmidi","Cap MIDI"); From 177cbf42b6b03388773d84bfea25b3ea71984635 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 14:22:22 +0000 Subject: [PATCH 3198/4131] Rename midi elements. Move configfile message to Init function so they are available as soon as possible. Make language and capture use Prop_path. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3286 --- src/dosbox.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 2faf54ca..c4bff49e 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.143 2009-02-01 11:07:11 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.144 2009-02-01 14:22:22 qbix79 Exp $ */ #include #include @@ -35,6 +35,7 @@ #include "timer.h" #include "dos_inc.h" #include "setup.h" +#include "control.h" #include "cross.h" #include "programs.h" #include "support.h" @@ -267,11 +268,6 @@ static void DOSBOX_RealInit(Section * sec) { ticksLocked = false; DOSBOX_SetLoop(&Normal_Loop); MSG_Init(section); - MSG_Add("CONFIGFILE_INTRO", - "# This is the configurationfile for DOSBox %s.\n" - "# Lines starting with a # are commentlines.\n" - "# They are used to (briefly) document the effect of each option.\n"); - MSG_Add("CONFIG_SUGGESTED_VALUES", "Possible values"); MAPPER_AddHandler(DOSBOX_UnlockSpeed, MK_f12, MMOD2,"speedlock","Speedlock"); std::string cmd_machine; @@ -331,14 +327,14 @@ void DOSBOX_Init(void) { "vgaonly", "svga_s3", "svga_et3000", "svga_et4000", "svga_paradise", "vesa_nolfb", "vesa_oldvbe", 0 }; secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit); - Pstring = secprop->Add_string("language",Property::Changeable::Always,""); + Pstring = secprop->Add_path("language",Property::Changeable::Always,""); Pstring->Set_help("Select another language file."); Pstring = secprop->Add_string("machine",Property::Changeable::OnlyAtStart,"svga_s3"); Pstring->Set_values(machines); Pstring->Set_help("The type of machine tries to emulate."); - Pstring = secprop->Add_string("captures",Property::Changeable::Always,"capture"); + Pstring = secprop->Add_path("captures",Property::Changeable::Always,"capture"); Pstring->Set_help("Directory where things like wave, midi, screenshot get captured."); #if C_DEBUG @@ -465,11 +461,11 @@ void DOSBOX_Init(void) { Pstring->Set_values(mputypes); Pstring->Set_help("Type of MPU-401 to emulate."); - Pstring = secprop->Add_string("device",Property::Changeable::WhenIdle,"default"); + Pstring = secprop->Add_string("mididevice",Property::Changeable::WhenIdle,"default"); Pstring->Set_values(devices); Pstring->Set_help("Device that will receive the MIDI data from MPU-401."); - Pstring = secprop->Add_string("config",Property::Changeable::WhenIdle,""); + Pstring = secprop->Add_string("midiconfig",Property::Changeable::WhenIdle,""); Pstring->Set_help("Special configuration options for the device driver. This is usually the id of the device you want to use. See README for details."); #if C_DEBUG @@ -666,5 +662,11 @@ void DOSBOX_Init(void) { MSG_Add("AUTOEXEC_CONFIGFILE_HELP", "Lines in this section will be run at startup.\n" ); + MSG_Add("CONFIGFILE_INTRO", + "# This is the configurationfile for DOSBox %s.\n" + "# Lines starting with a # are commentlines.\n" + "# They are used to (briefly) document the effect of each option.\n"); + MSG_Add("CONFIG_SUGGESTED_VALUES", "Possible values"); + control->SetStartUp(&SHELL_Init); } From bc90f8429a23c88df09f9b4b2a1dbd45aa0f47d6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 14:22:41 +0000 Subject: [PATCH 3199/4131] Rename midi elements. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3287 --- src/gui/midi.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 78228426..46493970 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -162,8 +162,8 @@ class MIDI:public Module_base{ public: MIDI(Section* configuration):Module_base(configuration){ Section_prop * section=static_cast(configuration); - const char * dev=section->Get_string("device"); - const char * conf=section->Get_string("config"); + const char * dev=section->Get_string("mididevice"); + const char * conf=section->Get_string("midiconfig"); /* If device = "default" go for first handler that works */ MidiHandler * handler; // MAPPER_AddHandler(MIDI_SaveRawEvent,MK_f8,MMOD1|MMOD2,"caprawmidi","Cap MIDI"); From 4b1a5010f2c0d361f14d80877b9bbf994d50475e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 14:24:12 +0000 Subject: [PATCH 3200/4131] Split of sdl configuration part into seperate function. Add hopefully vista compatible configuration layout. Add -printconf and -editconf Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3288 --- src/gui/sdlmain.cpp | 228 +++++++++++++++++++++++++++++--------------- 1 file changed, 149 insertions(+), 79 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 1ddc5874..af05f48a 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.145 2009-01-17 21:31:21 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.146 2009-02-01 14:24:12 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -46,6 +46,8 @@ #include "vga.h" #include "keyboard.h" #include "cpu.h" +#include "cross.h" +#include "control.h" //#define DISABLE_JOYSTICK @@ -1326,15 +1328,121 @@ void GFX_ShowMsg(char const* format,...) { strcat(buf,"\n"); va_end(msg); if(!no_stdout) printf("%s",buf); //Else buf is parsed again. -}; +} + + +void Config_Add_SDL() { + Section_prop * sdl_sec=control->AddSection_prop("sdl",&GUI_StartUp); + sdl_sec->AddInitFunction(&MAPPER_StartUp); + Prop_bool* Pbool; + Prop_string* Pstring; + Prop_int* Pint; + Prop_multival* Pmulti; + + Pbool = sdl_sec->Add_bool("fullscreen",Property::Changeable::Always,false); + Pbool->Set_help("Start dosbox directly in fullscreen."); + + Pbool = sdl_sec->Add_bool("fulldouble",Property::Changeable::Always,false); + Pbool->Set_help("Use double buffering in fullscreen."); + + Pstring = sdl_sec->Add_string("fullresolution",Property::Changeable::Always,"original"); + Pstring->Set_help("What resolution to use for fullscreen: original or fixed size (e.g. 1024x768)."); + + Pstring = sdl_sec->Add_string("windowresolution",Property::Changeable::Always,"original"); + Pstring->Set_help("Scale the window to this size IF the output device supports hardware scaling."); + + const char* outputs[] = { + "surface", "overlay", +#if C_OPENGL + "opengl", "openglnb", +#endif +#if (HAVE_DDRAW_H) && defined(WIN32) + "ddraw", +#endif + 0 }; + Pstring = sdl_sec->Add_string("output",Property::Changeable::Always,"surface"); + Pstring->Set_help("What video system to use for output."); + Pstring->Set_values(outputs); + + Pbool = sdl_sec->Add_bool("autolock",Property::Changeable::Always,true); + Pbool->Set_help("Mouse will automatically lock, if you click on the screen."); + + Pint = sdl_sec->Add_int("sensitivity",Property::Changeable::Always,100); + Pint->SetMinMax(1,1000); + Pint->Set_help("Mouse sensitivity."); + + Pbool = sdl_sec->Add_bool("waitonerror",Property::Changeable::Always, true); + Pbool->Set_help("Wait before closing the console if dosbox has an error."); + + Pmulti = sdl_sec->Add_multi("priority", Property::Changeable::Always, ","); + Pmulti->SetValue("higher,normal"); + Pmulti->Set_help("Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized. (pause is only valid for the second entry)"); + + const char* actt[] = { "lowest", "lower", "normal", "higher", "highest", "pause", 0}; + Pstring = Pmulti->GetSection()->Add_string("active",Property::Changeable::Always,"higher"); + Pstring->Set_values(actt); + + const char* inactt[] = { "lowest", "lower", "normal", "higher", "highest", "pause", 0}; + Pstring = Pmulti->GetSection()->Add_string("inactive",Property::Changeable::Always,"normal"); + Pstring->Set_values(inactt); + + Pstring = sdl_sec->Add_string("mapperfile",Property::Changeable::Always,"mapper.txt"); + Pstring->Set_help("File used to load/save the key/event mappings from."); + + Pbool = sdl_sec->Add_bool("usescancodes",Property::Changeable::Always,true); + Pbool->Set_help("Avoid usage of symkeys, might not work on all operating systems."); +} + +static void launcheditor(std::string const& edit) { + std::string path,file; + Cross::CreatePlatformConfigDir(path); + Cross::GetPlatformConfigName(file); + path += file; + FILE* f = fopen(path.c_str(),"r"); + if(!f && !control->PrintConfig(path.c_str())) { + printf("tried creating %s. but failed.\n",path.c_str()); + exit(1); + } + if(f) fclose(f); + if(edit.empty()) { + printf("no editor specified.\n"); + exit(1); + } + + execlp(edit.c_str(),edit.c_str(),path.c_str(),(char*) 0); + //if you get here the launching failed! + printf("can't find editor %s\n",edit.c_str()); + exit(1); +} + +static void printconfiglocation() { + std::string path,file; + Cross::CreatePlatformConfigDir(path); + Cross::GetPlatformConfigName(file); + path += file; + FILE* f = fopen(path.c_str(),"r"); + if(!f && !control->PrintConfig(path.c_str())) { + printf("tried creating %s. but failed",path.c_str()); + exit(1); + } + if(f) fclose(f); + printf("%s\n",path.c_str()); + exit(0); +} + extern void UI_Init(void); - int main(int argc, char* argv[]) { try { CommandLine com_line(argc,argv); Config myconf(&com_line); control=&myconf; + /* Init the configuration system and add default values */ + Config_Add_SDL(); + DOSBOX_Init(); + + std::string editor; + if(control->cmdline->FindString("-editconf",editor,true)) launcheditor(editor); /* Can't disable the console with debugger enabled */ #if defined(WIN32) && !(C_DEBUG) @@ -1367,6 +1475,7 @@ int main(int argc, char* argv[]) { printf("please read the COPYING file thoroughly before doing so.\n\n"); return 0; } + if(control->cmdline->FindExist("-printconf")) printconfiglocation(); #if C_DEBUG DEBUG_SetupConsole(); @@ -1434,84 +1543,43 @@ int main(int argc, char* argv[]) { if (strcmp(sdl_drv_name,"windib")==0) LOG_MSG("SDL_Init: Starting up with SDL windib video driver.\n Try to update your video card and directx drivers!"); } #endif - sdl.num_joysticks=SDL_NumJoysticks(); - Section_prop * sdl_sec=control->AddSection_prop("sdl",&GUI_StartUp); - sdl_sec->AddInitFunction(&MAPPER_StartUp); - Prop_bool* Pbool; - Prop_string* Pstring; - Prop_int* Pint; - Prop_multival* Pmulti; - Pbool = sdl_sec->Add_bool("fullscreen",Property::Changeable::Always,false); - Pbool->Set_help("Start dosbox directly in fullscreen."); + sdl.num_joysticks=SDL_NumJoysticks(); - Pbool = sdl_sec->Add_bool("fulldouble",Property::Changeable::Always,false); - Pbool->Set_help("Use double buffering in fullscreen."); - - Pstring = sdl_sec->Add_string("fullresolution",Property::Changeable::Always,"original"); - Pstring->Set_help("What resolution to use for fullscreen: original or fixed size (e.g. 1024x768)."); - - Pstring = sdl_sec->Add_string("windowresolution",Property::Changeable::Always,"original"); - Pstring->Set_help("Scale the window to this size IF the output device supports hardware scaling."); - - const char* outputs[] = { - "surface", "overlay", -#if C_OPENGL - "opengl", "openglnb", -#endif -#if (HAVE_DDRAW_H) && defined(WIN32) - "ddraw", -#endif - 0 }; - Pstring = sdl_sec->Add_string("output",Property::Changeable::Always,"surface"); - Pstring->Set_help("What video system to use for output."); - Pstring->Set_values(outputs); - - Pbool = sdl_sec->Add_bool("autolock",Property::Changeable::Always,true); - Pbool->Set_help("Mouse will automatically lock, if you click on the screen."); - - Pint = sdl_sec->Add_int("sensitivity",Property::Changeable::Always,100); - Pint->SetMinMax(1,1000); - Pint->Set_help("Mouse sensitivity."); - - Pbool = sdl_sec->Add_bool("waitonerror",Property::Changeable::Always, true); - Pbool->Set_help("Wait before closing the console if dosbox has an error."); - - Pmulti = sdl_sec->Add_multi("priority", Property::Changeable::Always, ","); - Pmulti->SetValue("higher,normal"); - Pmulti->Set_help("Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized. (pause is only valid for the second entry)"); - - const char* actt[] = { "lowest", "lower", "normal", "higher", "highest", "pause", 0}; - Pstring = Pmulti->GetSection()->Add_string("active",Property::Changeable::Always,"higher"); - Pstring->Set_values(actt); - - const char* inactt[] = { "lowest", "lower", "normal", "higher", "highest", "pause", 0}; - Pstring = Pmulti->GetSection()->Add_string("inactive",Property::Changeable::Always,"normal"); - Pstring->Set_values(inactt); - - Pstring = sdl_sec->Add_string("mapperfile",Property::Changeable::Always,"mapper.txt"); - Pstring->Set_help("File used to load/save the key/event mappings from."); - - Pbool = sdl_sec->Add_bool("usescancodes",Property::Changeable::Always,true); - Pbool->Set_help("Avoid usage of symkeys, might not work on all operating systems."); - - /* Init all the dosbox subsystems */ - DOSBOX_Init(); - std::string config_file; - bool parsed_anyconfigfile = false; - // First parse the configfile in the $HOME directory - if ((getenv("HOME") != NULL)) { - config_file = (std::string)getenv("HOME") + - (std::string)DEFAULT_CONFIG_FILE; - if (control->ParseConfigFile(config_file.c_str())) parsed_anyconfigfile = true; - } - // Add extra settings from dosbox.conf in the local directory if there is no configfile specified at the commandline - if (!control->cmdline->FindString("-conf",config_file,true)) config_file="dosbox.conf"; + /* Parse configuration files */ + std::string config_file,config_path; + bool parsed_anyconfigfile = false; + //First Parse -conf switches + while(control->cmdline->FindString("-conf",config_file,true)) if (control->ParseConfigFile(config_file.c_str())) parsed_anyconfigfile = true; - // Add extra settings from additional configfiles at the commandline - while(control->cmdline->FindString("-conf",config_file,true)) - if (control->ParseConfigFile(config_file.c_str())) parsed_anyconfigfile = true; - // Give a message if no configfile whatsoever was found. - if(!parsed_anyconfigfile) LOG_MSG("CONFIG: Using default settings. Create a configfile to change them"); + + //if none found => parse localdir conf + config_file = "dosbox.conf"; + if (!parsed_anyconfigfile && control->ParseConfigFile(config_file.c_str())) parsed_anyconfigfile = true; + + //if none found => parse userlevel conf + if(!parsed_anyconfigfile) { + config_file.clear(); + Cross::GetPlatformConfigDir(config_path); + Cross::GetPlatformConfigName(config_file); + config_path += config_file; + if(control->ParseConfigFile(config_path.c_str())) parsed_anyconfigfile = true; + } + + if(!parsed_anyconfigfile) { + //Try to create the userlevel configfile. + config_file.clear(); + Cross::CreatePlatformConfigDir(config_path); + Cross::GetPlatformConfigName(config_file); + config_path += config_file; + if(control->PrintConfig(config_path.c_str())) { + LOG_MSG("CONFIG: Generating default configuration.\nWriting it to %s",config_path.c_str()); + //Load them as well. Makes relative paths much easier + control->ParseConfigFile(config_path.c_str()); + } else { + LOG_MSG("CONFIG: Using default settings. Create a configfile to change them"); + } + } + #if (ENVIRON_LINKED) control->ParseEnv(environ); @@ -1521,6 +1589,8 @@ int main(int argc, char* argv[]) { /* Init all the sections */ control->Init(); /* Some extra SDL Functions */ + Section_prop * sdl_sec=static_cast(control->GetSection("sdl")); + if (control->cmdline->FindExist("-fullscreen") || sdl_sec->Get_bool("fullscreen")) { if(!sdl.desktop.fullscreen) { //only switch if not allready in fullscreen GFX_SwitchFullScreen(); From c90ebb3028745cb39c313fe56d8c91efb9069b24 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 14:24:38 +0000 Subject: [PATCH 3201/4131] Header updates. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3289 --- src/cpu/cpu.cpp | 3 ++- src/dos/dos_keyboard_layout.cpp | 3 ++- src/dos/dos_mscdex.cpp | 4 ++-- src/dos/dos_programs.cpp | 32 +++++---------------------- src/dos/drives.h | 4 ++-- src/gui/render.cpp | 3 ++- src/gui/sdl_gui.cpp | 3 ++- src/hardware/cmos.cpp | 4 +++- src/hardware/serialport/nullmodem.cpp | 4 ++-- src/ints/bios_keyboard.cpp | 1 + src/ints/mouse.cpp | 4 ++-- src/ints/xms.cpp | 4 ++-- 12 files changed, 27 insertions(+), 42 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 3c45e182..d26a8843 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.113 2008-08-06 18:31:26 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.114 2009-02-01 14:24:36 qbix79 Exp $ */ #include #include @@ -26,6 +26,7 @@ #include "debug.h" #include "mapper.h" #include "setup.h" +#include "programs.h" #include "paging.h" #include "lazyflags.h" #include "support.h" diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 90d55d84..704f80ac 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -16,10 +16,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_keyboard_layout.cpp,v 1.18 2009-01-29 23:17:59 c2woody Exp $ */ +/* $Id: dos_keyboard_layout.cpp,v 1.19 2009-02-01 14:24:36 qbix79 Exp $ */ #include "dosbox.h" #include "bios.h" +#include "bios_disk.h" #include "setup.h" #include "support.h" #include "../ints/int10.h" diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 55e942ed..ac2046ce 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.56 2008-11-06 19:31:21 c2woody Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.57 2009-02-01 14:24:36 qbix79 Exp $ */ #include #include @@ -26,7 +26,7 @@ #include "dos_inc.h" #include "setup.h" #include "support.h" -#include "bios.h" +#include "bios_disk.h" #include "cpu.h" #include "cdrom.h" diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index eee5c927..c8795282 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.90 2008-11-22 14:24:11 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.91 2009-02-01 14:24:36 qbix79 Exp $ */ #include "dosbox.h" #include @@ -35,11 +35,7 @@ #include "dos_inc.h" #include "bios.h" #include "setup.h" - -#if defined HAVE_SYS_TYPES_H && defined HAVE_PWD_H -#include -#include -#endif +#include "control.h" #if defined(OS2) @@ -54,24 +50,6 @@ Bitu DEBUG_EnableDebugger(void); void MSCDEX_SetCDInterface(int intNr, int forceCD); -//Helper function for mount and imgmount to correctly find the path -static void ResolveHomedir(std::string & temp_line) { - if(!temp_line.size() || temp_line[0] != '~') return; //No ~ - - if(temp_line.size() == 1 || temp_line[1] == CROSS_FILESPLIT) { //The ~ and ~/ variant - char * home = getenv("HOME"); - if(home) temp_line.replace(0,1,std::string(home)); -#if defined HAVE_SYS_TYPES_H && defined HAVE_PWD_H - } else { // The ~username variant - std::string::size_type namelen = temp_line.find(CROSS_FILESPLIT); - if(namelen == std::string::npos) namelen = temp_line.size(); - std::string username = temp_line.substr(1,namelen - 1); - struct passwd* pass = getpwnam(username.c_str()); - if(pass) temp_line.replace(0,namelen,pass->pw_dir); //namelen -1 +1(for the ~) -#endif // USERNAME lookup code - } -} - class MOUNT : public Program { public: @@ -227,7 +205,7 @@ public: #else if (stat(temp_line.c_str(),&test)) { failed = true; - ResolveHomedir(temp_line); + Cross::ResolveHomedir(temp_line); //Try again after resolving ~ if(!stat(temp_line.c_str(),&test)) failed = false; } @@ -480,7 +458,7 @@ private: if(tmpfile) return tmpfile; //File not found on mounted filesystem. Try regular filesystem std::string filename_s(filename); - ResolveHomedir(filename_s); + Cross::ResolveHomedir(filename_s); tmpfile = fopen(filename_s.c_str(),"rb+"); if(!tmpfile) { if( (tmpfile = fopen(filename_s.c_str(),"rb")) ) { @@ -1101,7 +1079,7 @@ public: if (stat(temp_line.c_str(),&test)) { //See if it works if the ~ are written out std::string homedir(temp_line); - ResolveHomedir(homedir); + Cross::ResolveHomedir(homedir); if(!stat(homedir.c_str(),&test)) { temp_line = homedir; } else { diff --git a/src/dos/drives.h b/src/dos/drives.h index c6febda2..a657a0c4 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.39 2007-11-01 12:15:34 qbix79 Exp $ */ +/* $Id: drives.h,v 1.40 2009-02-01 14:24:36 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ @@ -25,7 +25,7 @@ #include #include "dos_system.h" #include "shell.h" /* for DOS_Shell */ -#include "bios.h" /* for fatDrive */ +#include "bios_disk.h" /* for fatDrive */ bool WildFileCmp(const char * file, const char * wild); void Set_Label(char const * const input, char * const output, bool cdrom); diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 7b0f9cfd..8e7311a5 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.57 2008-08-06 18:32:34 c2woody Exp $ */ +/* $Id: render.cpp,v 1.58 2009-02-01 14:24:36 qbix79 Exp $ */ #include #include @@ -27,6 +27,7 @@ #include "video.h" #include "render.h" #include "setup.h" +#include "control.h" #include "mapper.h" #include "cross.h" #include "hardware.h" diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index 938b5a08..6c6a96e3 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_gui.cpp,v 1.7 2008-08-06 18:32:34 c2woody Exp $ */ +/* $Id: sdl_gui.cpp,v 1.8 2009-02-01 14:24:36 qbix79 Exp $ */ #include "SDL.h" #include "../libs/gui_tk/gui_tk.h" @@ -27,6 +27,7 @@ #include "render.h" #include "mapper.h" #include "setup.h" +#include "control.h" #include "shell.h" #include diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index f5ff406e..25e0ba2d 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: cmos.cpp,v 1.25 2009-02-01 14:24:37 qbix79 Exp $ */ + #include #include "dosbox.h" @@ -23,7 +25,7 @@ #include "pic.h" #include "inout.h" #include "mem.h" -#include "bios.h" +#include "bios_disk.h" #include "setup.h" static struct { diff --git a/src/hardware/serialport/nullmodem.cpp b/src/hardware/serialport/nullmodem.cpp index c11186d6..f343ace7 100644 --- a/src/hardware/serialport/nullmodem.cpp +++ b/src/hardware/serialport/nullmodem.cpp @@ -16,13 +16,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: nullmodem.cpp,v 1.5 2008-12-19 15:20:35 qbix79 Exp $ */ +/* $Id: nullmodem.cpp,v 1.6 2009-02-01 14:24:37 qbix79 Exp $ */ #include "dosbox.h" #if C_MODEM -#include "setup.h" // CommandLine +#include "control.h" #include "serialport.h" #include "nullmodem.h" diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 46d70585..9a4a89af 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -23,6 +23,7 @@ #include "keyboard.h" #include "regs.h" #include "inout.h" +#include "dos_inc.h" /* SDL by default treats numlock and scrolllock different from all other keys. * Some linux distros disable this bad behaviour. (for example debian) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 08df6103..65cfe06c 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.74 2008-08-03 15:52:06 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.75 2009-02-01 14:24:38 qbix79 Exp $ */ #include #include @@ -32,7 +32,7 @@ #include "inout.h" #include "int10.h" #include "bios.h" - +#include "dos_inc.h" static Bitu call_int33,call_int74,int74_ret_callback,call_mouse_bd; static Bit16u ps2cbseg,ps2cbofs; diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index e6d91b86..8aafcf83 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.53 2008-10-05 14:44:52 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.54 2009-02-01 14:24:38 qbix79 Exp $ */ #include #include @@ -24,7 +24,7 @@ #include "callback.h" #include "mem.h" #include "regs.h" -#include "dos_system.h" +#include "dos_inc.h" #include "setup.h" #include "inout.h" #include "xms.h" From 9d16fb980e00dcbc40ce6d3d24f6d9aeb84c9805 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 15:52:25 +0000 Subject: [PATCH 3202/4131] empty input is empty realpath. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3290 --- src/misc/setup.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 09b7b392..cf6c252c 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.52 2009-02-01 14:19:20 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.53 2009-02-01 15:52:25 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -271,6 +271,10 @@ void Prop_path::SetValue(std::string const& input){ Value val(input,Value::V_STRING); SetVal(val,false,true); + if(input.empty()) { + realpath = ""; + return; + } std::string workcopy(input); Cross::ResolveHomedir(workcopy); //Parse ~ and friends //Prepend config directory in it exists. Check for absolute paths later From 1ea1b9cae5f6747dbae559b19414e29ee156fe69 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 15:52:53 +0000 Subject: [PATCH 3203/4131] no dir no glory. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3291 --- src/hardware/hardware.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index d2d74566..135e6e5e 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: hardware.cpp,v 1.20 2009-02-01 14:21:19 qbix79 Exp $ */ +/* $Id: hardware.cpp,v 1.21 2009-02-01 15:52:53 qbix79 Exp $ */ #include #include @@ -83,6 +83,11 @@ static struct { } capture; FILE * OpenCaptureFile(const char * type,const char * ext) { + if(capturedir.empty()) { + LOG_MSG("Please specify a capture directory"); + return 0; + } + Bitu last=0; char file_name[CROSS_LEN]; char file_start[16]; From 0c075b29fd84c7a9c20b552214ac8715404c825d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 16:05:28 +0000 Subject: [PATCH 3204/4131] Renable mapper. Make it Prop_path Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3292 --- src/gui/sdl_mapper.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index a6b5f7bd..8a787ea2 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.55 2009-01-22 21:44:14 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.56 2009-02-01 16:05:28 qbix79 Exp $ */ #include #include @@ -1234,7 +1234,7 @@ static struct CMapper { Bitu num_groups,num; CStickBindGroup * stick[MAXSTICKS]; } sticks; - const char * filename; + std::string filename; } mapper; void CBindGroup::ActivateBindList(CBindList * list,Bits value,bool ev_trigger) { @@ -2083,9 +2083,9 @@ void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char const } static void MAPPER_SaveBinds(void) { - FILE * savefile=fopen(mapper.filename,"wb+"); + FILE * savefile=fopen(mapper.filename.c_str(),"wb+"); if (!savefile) { - LOG_MSG("Can't open %s for saving the mappings",mapper.filename); + LOG_MSG("Can't open %s for saving the mappings",mapper.filename.c_str()); return; } char buf[128]; @@ -2105,14 +2105,14 @@ static void MAPPER_SaveBinds(void) { } static bool MAPPER_LoadBinds(void) { - FILE * loadfile=fopen(mapper.filename,"rb"); + FILE * loadfile=fopen(mapper.filename.c_str(),"rb"); if (!loadfile) return false; char linein[512]; while (fgets(linein,512,loadfile)) { CreateStringBind(linein); } fclose(loadfile); - LOG_MSG("MAPPER: Loading mapper settings from %s", mapper.filename); + LOG_MSG("MAPPER: Loading mapper settings from %s", mapper.filename.c_str()); return true; } @@ -2464,6 +2464,8 @@ void MAPPER_StartUp(Section * sec) { } } - mapper.filename=section->Get_string("mapperfile"); + Prop_path* pp = section->Get_path("mapperfile"); + mapper.filename = pp->realpath; + MAPPER_AddHandler(&MAPPER_Run,MK_f1,MMOD1,"mapper","Mapper"); } From 0c570b7b7976bc57588fae58534eb0a8eb7f49b9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 16:06:26 +0000 Subject: [PATCH 3205/4131] Disable menu, reintroduce pausedosbox. reintroduce -startmapper and keybindings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3293 --- src/gui/sdl_gui.cpp | 4 +++- src/gui/sdlmain.cpp | 44 ++++++++++++++++++++++++++++++++------ src/libs/gui_tk/gui_tk.cpp | 4 +++- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index 6c6a96e3..4ad029fc 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -16,8 +16,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_gui.cpp,v 1.8 2009-02-01 14:24:36 qbix79 Exp $ */ +/* $Id: sdl_gui.cpp,v 1.9 2009-02-01 16:06:26 qbix79 Exp $ */ +#if 0 #include "SDL.h" #include "../libs/gui_tk/gui_tk.h" @@ -628,3 +629,4 @@ void UI_Run(bool pressed) { UI_Shutdown(screen); delete screen; } +#endif \ No newline at end of file diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index af05f48a..847f3b45 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.146 2009-02-01 14:24:12 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.147 2009-02-01 16:06:26 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -244,6 +244,35 @@ void GFX_SetTitle(Bit32s cycles,Bits frameskip,bool paused){ SDL_WM_SetCaption(title,VERSION); } +static void PauseDOSBox(bool pressed) { + if (!pressed) + return; + GFX_SetTitle(-1,-1,true); + bool paused = true; + KEYBOARD_ClrBuffer(); + SDL_Delay(500); + SDL_Event event; + while (SDL_PollEvent(&event)) { + // flush event queue. + } + + while (paused) { + SDL_WaitEvent(&event); // since we're not polling, cpu usage drops to 0. + switch (event.type) { + + case SDL_QUIT: throw(0); break; + case SDL_KEYDOWN: // Must use Pause/Break Key to resume. + case SDL_KEYUP: + if(event.key.keysym.sym==SDLK_PAUSE) { + + paused=false; + GFX_SetTitle(-1,-1,false); + break; + } + } + } +} + #if defined (WIN32) bool GFX_SDLUsingWinDIB(void) { return sdl.using_windib; @@ -936,7 +965,7 @@ static unsigned char logo[32*32*4]= { #include "dosbox_logo.h" }; -extern void UI_Run(bool); +//extern void UI_Run(bool); static void GUI_StartUp(Section * sec) { sec->AddDestroyFunction(&GUI_ShutDown); Section_prop * section=static_cast(sec); @@ -1111,7 +1140,7 @@ static void GUI_StartUp(Section * sec) { #if C_DEBUG /* Pause binds with activate-debugger */ #else - MAPPER_AddHandler(&UI_Run, MK_pause, MMOD2, "ui", "UI"); + MAPPER_AddHandler(&PauseDOSBox, MK_pause, MMOD2, "pause", "Pause"); #endif /* Get Keyboard state of numlock and capslock */ SDLMod keystate = SDL_GetModState(); @@ -1386,7 +1415,7 @@ void Config_Add_SDL() { Pstring = Pmulti->GetSection()->Add_string("inactive",Property::Changeable::Always,"normal"); Pstring->Set_values(inactt); - Pstring = sdl_sec->Add_string("mapperfile",Property::Changeable::Always,"mapper.txt"); + Pstring = sdl_sec->Add_path("mapperfile",Property::Changeable::Always,"mapper.txt"); Pstring->Set_help("File used to load/save the key/event mappings from."); Pbool = sdl_sec->Add_bool("usescancodes",Property::Changeable::Always,true); @@ -1431,7 +1460,7 @@ static void printconfiglocation() { } -extern void UI_Init(void); +//extern void UI_Init(void); int main(int argc, char* argv[]) { try { CommandLine com_line(argc,argv); @@ -1584,8 +1613,8 @@ int main(int argc, char* argv[]) { #if (ENVIRON_LINKED) control->ParseEnv(environ); #endif - UI_Init(); - if (control->cmdline->FindExist("-startui")) UI_Run(false); +// UI_Init(); +// if (control->cmdline->FindExist("-startui")) UI_Run(false); /* Init all the sections */ control->Init(); /* Some extra SDL Functions */ @@ -1599,6 +1628,7 @@ int main(int argc, char* argv[]) { /* Init the keyMapper */ MAPPER_Init(); + if (control->cmdline->FindExist("-startmapper")) MAPPER_Run(true); /* Start up main machine */ control->StartUp(); /* Shutdown everything */ diff --git a/src/libs/gui_tk/gui_tk.cpp b/src/libs/gui_tk/gui_tk.cpp index f6320c41..0ba88eb6 100644 --- a/src/libs/gui_tk/gui_tk.cpp +++ b/src/libs/gui_tk/gui_tk.cpp @@ -1,3 +1,4 @@ +#if 0 /* * gui_tk - framework-agnostic GUI toolkit * Copyright (C) 2005-2007 Jörg Walter @@ -19,7 +20,7 @@ /* TODO: - make menu a bufferedwindow with shadow */ -/* $Id: gui_tk.cpp,v 1.4 2008-09-07 10:55:15 c2woody Exp $ */ +/* $Id: gui_tk.cpp,v 1.5 2009-02-01 16:06:26 qbix79 Exp $ */ /** \file * \brief Implementation file for gui_tk. @@ -1703,3 +1704,4 @@ int main(int argc, char *argv[]) } #endif +#endif \ No newline at end of file From 4141de4aee4b65af69cd6e5fe64aadadac86ab89 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 16:32:33 +0000 Subject: [PATCH 3206/4131] Add header for win32. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3294 --- src/gui/sdlmain.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 847f3b45..6e49c917 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.147 2009-02-01 16:06:26 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.148 2009-02-01 16:32:33 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -30,6 +30,7 @@ #include #ifdef WIN32 #include +#include #endif #include "SDL.h" From 934bb53bd76ff030f1e6623c3466c48110493762 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 19:28:58 +0000 Subject: [PATCH 3207/4131] Fix compilation in debug mode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3295 --- src/debug/debug_gui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 1964632f..03921116 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -16,12 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug_gui.cpp,v 1.36 2008-06-02 17:26:59 qbix79 Exp $ */ +/* $Id: debug_gui.cpp,v 1.37 2009-02-01 19:28:58 qbix79 Exp $ */ #include "dosbox.h" #if C_DEBUG -#include "setup.h" +#include "control.h" #include #include #include From 7dc248bec901bd1d179f06cc70b30a0bf2f449d8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 20:25:38 +0000 Subject: [PATCH 3208/4131] Mini optimalisation. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3296 --- src/debug/debug.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 9a4e8b08..e235ecab 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.94 2008-06-02 17:26:59 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.95 2009-02-01 20:25:38 qbix79 Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -2117,7 +2117,7 @@ static void OutputVecTable(char* filename) { #define DEBUG_VAR_BUF_LEN 16 static void DrawVariables(void) { - if (CDebugVar::varList.size()==0) return; + if (CDebugVar::varList.empty()) return; std::list::iterator i; CDebugVar *dv; From a6363423b8e1d66765eb398691bddbe2f3e18415 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 1 Feb 2009 21:22:51 +0000 Subject: [PATCH 3209/4131] reenable hints for CHDIR. Thanks woody Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3297 --- src/shell/shell_cmds.cpp | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index c3eaa5c3..b2a60542 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.87 2009-02-01 14:06:36 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.88 2009-02-01 21:22:51 qbix79 Exp $ */ #include "dosbox.h" #include "shell.h" @@ -306,22 +306,27 @@ void DOS_Shell::CMD_CHDIR(char * args) { WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT"),toupper(*reinterpret_cast(&args[0]))); } else if (!DOS_ChangeDir(args)) { /* Changedir failed. Check if the filename is longer then 8 and/or contains spaces */ - char temp[DOS_PATHLENGTH]; - safe_strncpy(temp,args,DOS_PATHLENGTH); - char* dot = strrchr(temp,'.'); - if(dot) *dot = 0; - dot = strrchr(temp,' '); - if(dot) { /* Contains spaces */ - *dot = 0; - if(strlen(temp) > 6) temp[6] = 0; - strcat(temp,"~1"); -// WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_2"),temp); - WriteOut(MSG_Get("SHELL_CMD_CHDIR_ERROR"),args); - } else if(strlen(temp) >8) { - temp[6] = 0; - strcat(temp,"~1"); -// WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_2"),temp); - WriteOut(MSG_Get("SHELL_CMD_CHDIR_ERROR"),args); + + std::string temps(args),slashpart; + std::string::size_type separator = temps.find_first_of("\\/"); + if(!separator) { + slashpart = temps.substr(0,1); + temps.erase(0,1); + } + separator = temps.find_first_of("\\/"); + if(separator != std::string::npos) temps.erase(separator); + separator = temps.rfind('.'); + if(separator != std::string::npos) temps.erase(separator); + separator = temps.find(' '); + if(separator != std::string::npos) {/* Contains spaces */ + temps.erase(separator); + if(temps.size() >6) temps.erase(6); + temps += "~1"; + WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_2"),temps.insert(0,slashpart).c_str()); + } else if (temps.size()>8) { + temps.erase(6); + temps += "~1"; + WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_2"),temps.insert(0,slashpart).c_str()); } else { Bit8u drive=DOS_GetDefaultDrive()+'A'; if (drive=='Z') { From d25daebcb9364efeb4a7c2440ccea35c39752069 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 3 Feb 2009 08:27:47 +0000 Subject: [PATCH 3210/4131] include stdlib for getennv. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3298 --- src/misc/cross.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/misc/cross.cpp b/src/misc/cross.cpp index d444c993..06c009a7 100644 --- a/src/misc/cross.cpp +++ b/src/misc/cross.cpp @@ -16,11 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.cpp,v 1.1 2009-02-01 14:16:52 qbix79 Exp $ */ +/* $Id: cross.cpp,v 1.2 2009-02-03 08:27:47 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" #include +#include #ifdef WIN32 #define _WIN32_IE 0x0400 From 9b70d00853f0073b9b1b045330c76afcf7b28217 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 3 Feb 2009 19:20:30 +0000 Subject: [PATCH 3211/4131] New adlib interface allowing for different emulation backends Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3299 --- src/dosbox.cpp | 11 +- src/hardware/adlib.cpp | 541 ++++++++++++++++++++++++++++------------- src/hardware/adlib.h | 121 +++++++++ 3 files changed, 496 insertions(+), 177 deletions(-) create mode 100644 src/hardware/adlib.h diff --git a/src/dosbox.cpp b/src/dosbox.cpp index c4bff49e..2a007b51 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.144 2009-02-01 14:22:22 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.145 2009-02-03 19:20:30 harekiet Exp $ */ #include #include @@ -498,11 +498,16 @@ void DOSBOX_Init(void) { Pbool = secprop->Add_bool("sbmixer",Property::Changeable::WhenIdle,true); Pbool->Set_help("Allow the soundblaster mixer to modify the DOSBox mixer."); - const char* opltypes[]={ "auto", "cms", "opl2", "dualopl2", "opl3", "none", 0}; + const char* oplmodes[]={ "auto", "cms", "opl2", "dualopl2", "opl3", "none", 0}; Pstring = secprop->Add_string("oplmode",Property::Changeable::WhenIdle,"auto"); - Pstring->Set_values(opltypes); + Pstring->Set_values(oplmodes); Pstring->Set_help("Type of OPL emulation. On 'auto' the mode is determined by sblaster type. All OPL modes are Adlib-compatible, except for 'cms'."); + const char* oplemus[]={ "auto", 0}; + Pstring = secprop->Add_string("oplemu",Property::Changeable::WhenIdle,"auto"); + Pstring->Set_values(oplemus); + Pstring->Set_help("Provider for the OPL emulation. On 'auto' dosbox will use the best emulation."); + Pint = secprop->Add_int("oplrate",Property::Changeable::WhenIdle,22050); Pint->Set_values(rates); Pint->Set_help("Sample rate of OPL music emulation."); diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 02031a6b..bd58b7e9 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: adlib.cpp,v 1.31 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: adlib.cpp,v 1.32 2009-02-03 19:20:30 harekiet Exp $ */ #include #include @@ -31,15 +31,117 @@ #include "hardware.h" #include "setup.h" #include "mapper.h" +#include "adlib.h" #include "mem.h" /* Thanks to vdmsound for nice simple way to implement this */ +#ifdef _MSC_VER + /* Disable recurring warnings */ +# pragma warning ( disable : 4018 ) +# pragma warning ( disable : 4244 ) +#endif + + #define logerror +struct __MALLOCPTR { + void* m_ptr; + + __MALLOCPTR(void) : m_ptr(NULL) { } + __MALLOCPTR(void* src) : m_ptr(src) { } + void* operator=(void* rhs) { return (m_ptr = rhs); } + operator int*() const { return (int*)m_ptr; } + operator int**() const { return (int**)m_ptr; } + operator char*() const { return (char*)m_ptr; } +}; + +namespace OPL2 { + #define OPL2_INTERNAL_FREQ 3600000 // The OPL2 operates at 3.6MHz + #define HAS_YM3812 1 + #include "fmopl.c" + + struct Handler : public Adlib::Handler { + virtual void WriteReg( Bit32u reg, Bit8u val ) { + OPLWriteReg( OPL_YM3812[ 0 ], reg, val ); + } + virtual Bit32u WriteAddr( Bit32u port, Bit8u val ) { + OPL_YM3812[ 0 ]->address = val; + return val; + } + + virtual void Generate( MixerChannel* chan, Bitu samples ) { + Bit16s buf[1024]; + while( samples > 0 ) { + Bitu todo = samples > 1024 ? 1024 : samples; + samples -= todo; + YM3812UpdateOne( 0, buf, todo ); + chan->AddSamples_m16( todo, buf ); + } + } + virtual void Init( Bitu rate ) { + if ( YM3812Init( 1, OPL2_INTERNAL_FREQ, rate )) { + E_Exit("Can't create OPL2 Emulator"); + }; + } + ~Handler() { + YM3812Shutdown(); + } + }; +} +#undef OSD_CPU_H +#undef TL_TAB_LEN + +namespace OPL3 { + #define OPL3_INTERNAL_FREQ 14400000 // The OPL3 operates at 14.4MHz + #define HAS_YMF262 1 + #include "ymf262.c" + + struct Handler : public Adlib::Handler { + virtual void WriteReg( Bit32u reg, Bit8u val ) { + OPL3WriteReg( YMF262[0], reg, val ); + } + virtual Bit32u WriteAddr( Bit32u port, Bit8u val ) { + OPL3Write( YMF262[0], port, val ); + return YMF262[0]->address; + } + virtual void Generate( MixerChannel* chan, Bitu samples ) { + Bit16s buf[2][1024]; + while( samples > 0 ) { + Bitu todo = samples > 1024 ? 1024 : samples; + samples -= todo; + YMF262UpdateOne( 0, buf[0], todo ); + chan->AddSamples_s16( todo, buf[0] ); + } + } + virtual void Init( Bitu rate ) { + if ( YMF262Init( 1, OPL3_INTERNAL_FREQ, rate )) { + E_Exit("Can't create OPL3 Emulator"); + }; + } + ~Handler() { + YMF262Shutdown(); + } + }; +} + + +#define RAW_SIZE 1024 + + +/* + Main Adlib implementation + +*/ + +namespace Adlib { + + +/* Raw DRO capture stuff */ + #ifdef _MSC_VER #pragma pack (1) #endif @@ -70,11 +172,8 @@ struct RawHeader { After the conversion table the raw data follows immediatly till the end of the chunk */ -typedef Bit8u RawCache[2][256]; - - //Table to map the opl register to one <127 for dro saving -class RawCapture { +class Capture { //127 entries to go from raw data to registers Bit8u ToReg[127]; //How many entries in the ToPort are used @@ -94,7 +193,7 @@ class RawCapture { bool doneOpl3; bool doneDualOpl2; - RawCache* cache; + RegisterCache* cache; void MakeEntry( Bit8u reg, Bit8u& raw ) { ToReg[ raw ] = reg; @@ -146,24 +245,25 @@ class RawCapture { ClearBuf(); } } - void AddWrite( Bit8u index, Bit8u reg, Bit8u val ) { + void AddWrite( Bit32u regFull, Bit8u val ) { + Bit8u regMask = regFull & 0xff; /* Do some special checks if we're doing opl3 or dualopl2 commands Although you could pretty much just stick to always doing opl3 on the player side */ - if ( index ) { - //opl3 enabling will always override dual opl - if ( header.hardware != HW_OPL3 && reg == 4 && val && (*cache)[1][5] ) { - header.hardware = HW_OPL3; - } - if ( header.hardware == HW_OPL2 && reg >= 0xb0 && reg <=0xb8 && val ) { - header.hardware = HW_DUALOPL2; - } + //Enabling opl3 4op modes will make us go into opl3 mode + if ( header.hardware != HW_OPL3 && regFull == 0x104 && val && (*cache)[0x105] ) { + header.hardware = HW_OPL3; + } + //Writing a keyon to a 2nd address enables dual opl2 otherwise + //Maybe also check for rhythm + if ( header.hardware == HW_OPL2 && regFull >= 0x1b0 && regFull <=0x1b8 && val ) { + header.hardware = HW_DUALOPL2; } - Bit8u raw = ToRaw[reg]; + Bit8u raw = ToRaw[ regMask ]; if ( raw == 0xff ) return; - if ( index ) + if ( regFull & 0x100 ) raw |= 128; AddBuf( raw, val ); } @@ -174,13 +274,13 @@ class RawCapture { //Skip the note on entries if (i>=0xb0 && i<=0xb8) continue; - val = (*cache)[0][i]; + val = (*cache)[ i ]; if (val) { - AddWrite( 0, i, val ); + AddWrite( i, val ); } - val = (*cache)[1][i]; + val = (*cache)[ 0x100 + i ]; if (val) { - AddWrite( 1, i, val ); + AddWrite( 0x100 + i, val ); } } } @@ -208,20 +308,21 @@ class RawCapture { } } public: - bool DoWrite( Bit8u index, Bit8u reg, Bit8u val ) { + bool DoWrite( Bit32u regFull, Bit8u val ) { + Bit8u regMask = regFull & 0xff; //Check the raw index for this register if we actually have to save it if ( handle ) { /* Check if we actually care for this to be logged, else just ignore it */ - Bit8u raw = ToRaw[reg]; + Bit8u raw = ToRaw[ regMask ]; if ( raw == 0xff ) { return true; } /* Check if this command will not just replace the same value in a reg that doesn't do anything with it */ - if ( (*cache)[index][reg] == val ) + if ( (*cache)[ regFull ] == val ) return true; /* Check how much time has passed */ Bitu passed = PIC_Ticks - lastTicks; @@ -245,7 +346,7 @@ public: AddBuf( delayShift8, shift - 1 ); } } - AddWrite( index, reg, val ); + AddWrite( regFull, val ); return true; } skipWrite: @@ -253,9 +354,9 @@ skipWrite: //Check for commands that would start capturing, if it's not one of them return if ( !( //note on in any channel - ( reg>=0xb0 && reg<=0xb8 && (val&0x020) ) || + ( regMask>=0xb0 && regMask<=0xb8 && (val&0x020) ) || //Percussion mode enabled and a note on in any percussion instrument - ( reg == 0xbd && ( (val&0x3f) > 0x20 ) ) + ( regMask == 0xbd && ( (val&0x3f) > 0x20 ) ) )) { return true; } @@ -270,169 +371,252 @@ skipWrite: /* Write the cache of last commands */ WriteCache( ); /* Write the command that triggered this */ - AddWrite( index, reg, val ); + AddWrite( regFull, val ); //Init the timing information for the next commands lastTicks = PIC_Ticks; startTicks = PIC_Ticks; return true; } - RawCapture( RawCache* _cache ) { + Capture( RegisterCache* _cache ) { cache = _cache; handle = 0; bufUsed = 0; MakeTables(); } - ~RawCapture() { + ~Capture() { CloseFile(); } }; -#ifdef _MSC_VER - /* Disable recurring warnings */ -# pragma warning ( disable : 4018 ) -# pragma warning ( disable : 4244 ) -#endif +/* +Chip +*/ -struct __MALLOCPTR { - void* m_ptr; - - __MALLOCPTR(void) : m_ptr(NULL) { } - __MALLOCPTR(void* src) : m_ptr(src) { } - void* operator=(void* rhs) { return (m_ptr = rhs); } - operator int*() const { return (int*)m_ptr; } - operator int**() const { return (int**)m_ptr; } - operator char*() const { return (char*)m_ptr; } -}; - -namespace OPL2 { - #define HAS_YM3812 1 - #include "fmopl.c" - void TimerOver(Bitu val){ - YM3812TimerOver(val>>8,val & 0xff); - } - void TimerHandler(int channel,double interval_Sec) { - if (interval_Sec==0.0) return; - PIC_AddEvent(TimerOver,1000.0f*interval_Sec,channel); +bool Chip::Write( Bit32u reg, Bit8u val ) { + switch ( reg ) { + case 0x02: + timer[0].counter = val; + return true; + case 0x03: + timer[1].counter = val; + return true; + case 0x04: + double time; + time = PIC_FullIndex(); + if ( val & 0x80 ) { + timer[0].Reset( time ); + timer[1].Reset( time ); + } else { + timer[0].Update( time ); + timer[1].Update( time ); + if ( val & 0x1 ) { + timer[0].Start( time, 80 ); + } else { + timer[0].Stop( ); + } + timer[0].masked = (val & 0x40) > 0; + if ( val & 0x2 ) { + timer[1].Start( time, 320 ); + } else { + timer[1].Stop( ); + } + timer[1].masked = (val & 0x20) > 0; + } + return true; } + return false; } -#undef OSD_CPU_H -#undef TL_TAB_LEN -namespace THEOPL3 { - #define HAS_YMF262 1 - #include "ymf262.c" - void TimerOver(Bitu val){ - YMF262TimerOver(val>>8,val & 0xff); + + +Bit8u Chip::Read( ) { + double time( PIC_FullIndex() ); + timer[0].Update( time ); + timer[1].Update( time ); + Bit8u ret = 0; + //Overflow won't be set if a channel is masked + if ( timer[0].overflow ) { + ret |= 0x40; + ret |= 0x80; } - void TimerHandler(int channel,double interval_Sec) { - if (interval_Sec==0.0) return; - PIC_AddEvent(TimerOver,1000.0f*interval_Sec,channel); + if ( timer[1].overflow ) { + ret |= 0x20; + ret |= 0x80; + } + return ret; + +} + +void Module::CacheWrite( Bit32u reg, Bit8u val ) { + //capturing? + if ( capture ) { + capture->DoWrite( reg, val ); + } + //Store it into the cache + cache[ reg ] = val; +} + +void Module::DualWrite( Bit8u index, Bit8u reg, Bit8u val ) { + //Make sure you don't use opl3 features + //Don't allow write to disable opl3 + if ( reg == 5 ) { + return; + } + //Only allow 4 waveforms + if ( reg >= 0xE0 ) { + val &= 3; + } + //Write to the timer? + if ( chip[index].Write( reg, val ) ) + return; + //Enabling panning + if ( reg >= 0xc0 && reg <0xc8 ) { + val &= 7; + val |= index ? 0xA0 : 0x50; + } + Bit32u fullReg = reg + index ? 0x100 : 0; + handler->WriteReg( fullReg, val ); + CacheWrite( fullReg, val ); +} + + +void Module::PortWrite( Bitu port, Bitu val, Bitu iolen ) { + //Keep track of last write time + lastUsed = PIC_Ticks; + //Maybe only enable with a keyon? + if ( !chan->enabled ) { + chan->Enable(true); + } + if ( port&1 ) { + switch ( mode ) { + case MODE_OPL2: + case MODE_OPL3: + if ( !chip[0].Write( reg.normal, val ) ) { + handler->WriteReg( reg.normal, val ); + CacheWrite( reg.normal, val ); + } + break; + case MODE_DUALOPL2: + //Not a 0x??8 port, then write to a specific port + if ( !(port & 0x8) ) { + Bit8u index = ( port & 2 ) >> 1; + DualWrite( index, reg.dual[index], val ); + } else { + //Write to both ports + DualWrite( 0, reg.dual[0], val ); + DualWrite( 1, reg.dual[1], val ); + } + break; + } + } else { + //Ask the handler to write the address + //Make sure to clip them in the right range + switch ( mode ) { + case MODE_OPL2: + reg.normal = handler->WriteAddr( port, val ) & 0xff; + break; + case MODE_OPL3: + reg.normal = handler->WriteAddr( port, val ) & 0x1ff; + break; + case MODE_DUALOPL2: + //Not a 0x?88 port, when write to a specific side + if ( !(port & 0x8) ) { + Bit8u index = ( port & 2 ) >> 1; + reg.dual[index] = val & 0xff; + } else { + reg.dual[0] = val & 0xff; + reg.dual[1] = val & 0xff; + } + break; + } } } -#define OPL2_INTERNAL_FREQ 3600000 // The OPL2 operates at 3.6MHz -#define OPL3_INTERNAL_FREQ 14400000 // The OPL3 operates at 14.4MHz -#define RAW_SIZE 1024 -static struct { - bool active; - OPL_Mode mode; - MixerChannel * chan; - Bit32u last_used; //Ticks when adlib was last used to turn of mixing after a few second - Bit16s mixbuf[2][128]; //Mix buffer to mix dual opl2 into final stream - Bit8u cmd[2]; //Last cmd written to either index - RawCache cache; - RawCapture* raw; -} opl; +Bitu Module::PortRead( Bitu port, Bitu iolen ) { + switch ( mode ) { + case MODE_OPL2: + //We allocated 4 ports, so just return -1 for the higher ones + if ( !(port & 3 ) ) { + //Make sure the low bits are 6 on opl2 + return chip[0].Read() | 0x6; + } else { + return 0xff; + } + case MODE_OPL3: + //We allocated 4 ports, so just return -1 for the higher ones + if ( !(port & 3 ) ) { + return chip[0].Read(); + } else { + return 0xff; + } + case MODE_DUALOPL2: + //Only return for the lower ports + if ( port & 1 ) { + return 0xff; + } + //Make sure the low bits are 6 on opl2 + return chip[ (port >> 1) & 1].Read() | 0x6; + } + return 0; +} + + +void Module::Init( Mode m ) { + mode = m; + switch ( mode ) { + case MODE_OPL3: + case MODE_OPL2: + break; + case MODE_DUALOPL2: + //Setup opl3 mode in the hander + handler->WriteReg( 0x105, 1 ); + //Also set it up in the cache so the capturing will start opl3 + CacheWrite( 0x105, 1 ); + break; + } +} + +Module::Module() { + reg.dual[0] = 0; + reg.dual[1] = 0; + reg.normal = 0; +} + + +}; //Adlib Namespace + + +static Adlib::Module module; + static void OPL_CallBack(Bitu len) { - /* Check for size to update and check for 1 ms updates to the opl registers */ - Bitu i; - switch(opl.mode) { - case OPL_opl2: - OPL2::YM3812UpdateOne(0,(OPL2::INT16 *)MixTemp,len); - opl.chan->AddSamples_m16(len,(Bit16s*)MixTemp); - break; - case OPL_opl3: - THEOPL3::YMF262UpdateOne(0,(OPL2::INT16 *)MixTemp,len); - opl.chan->AddSamples_s16(len,(Bit16s*)MixTemp); - break; - case OPL_dualopl2: - OPL2::YM3812UpdateOne(0,(OPL2::INT16 *)opl.mixbuf[0],len); - OPL2::YM3812UpdateOne(1,(OPL2::INT16 *)opl.mixbuf[1],len); - for (i=0;iAddSamples_s16(len,(Bit16s*)MixTemp); - break; - default: - break; - } - if ((PIC_Ticks-opl.last_used)>30000) { - opl.chan->Enable(false); - opl.active=false; + module.handler->Generate( module.chan, len ); + //Disable the sound generation after 30 seconds of silence + if ((PIC_Ticks-module.lastUsed) > 30000) { + module.chan->Enable(false); } } static Bitu OPL_Read(Bitu port,Bitu iolen) { - Bitu addr=port & 3; - switch (opl.mode) { - case OPL_opl2: - return OPL2::YM3812Read(0,addr); - case OPL_dualopl2: - return OPL2::YM3812Read(addr>>1,addr); - case OPL_opl3: - return THEOPL3::YMF262Read(0,addr); - default: - break; - } - return 0xff; + return module.PortRead( port, iolen ); } void OPL_Write(Bitu port,Bitu val,Bitu iolen) { - opl.last_used=PIC_Ticks; - if (!opl.active) { - opl.active=true; - opl.chan->Enable(true); - } - port&=3; - Bitu index = port>>1; - if ( port&1 ) { - Bit8u cmd = opl.cmd[index]; - if ( opl.raw ) - opl.raw->DoWrite( index, cmd, val ); - //Write to the cache after, so the raw can check for unchanged values - opl.cache[index][cmd]=val; - } else { - opl.cmd[ index ] = val; - } - switch (opl.mode) { - case OPL_opl2: - OPL2::YM3812Write(0,port,val); - break; - case OPL_opl3: - THEOPL3::YMF262Write(0,port,val); - break; - case OPL_dualopl2: - OPL2::YM3812Write( index,port,val); - break; - default: - break; - } + module.PortWrite( port, val, iolen ); } static void OPL_SaveRawEvent(bool pressed) { if (!pressed) return; /* Check for previously opened wave file */ - if ( opl.raw ) { - delete opl.raw; - opl.raw = 0; + if ( module.capture ) { + delete module.capture; + module.capture = 0; LOG_MSG("Stopped Raw OPL capturing."); } else { LOG_MSG("Preparing to capture Raw OPL, will start with first note played."); - opl.raw = new RawCapture( &opl.cache ); + module.capture = new Adlib::Capture( &module.cache ); } } @@ -448,38 +632,47 @@ public: Section_prop * section=static_cast(configuration); Bitu base = section->Get_hex("sbbase"); Bitu rate = section->Get_int("oplrate"); - if (OPL2::YM3812Init(2,OPL2_INTERNAL_FREQ,rate)) { - E_Exit("Can't create OPL2 Emulator"); - }; - OPL2::YM3812SetTimerHandler(0,OPL2::TimerHandler,0); - OPL2::YM3812SetTimerHandler(1,OPL2::TimerHandler,256); - if (THEOPL3::YMF262Init(1,OPL3_INTERNAL_FREQ,rate)) { - E_Exit("Can't create OPL3 Emulator"); - }; - THEOPL3::YMF262SetTimerHandler(0,THEOPL3::TimerHandler,0); - WriteHandler[0].Install(0x388,OPL_Write,IO_MB,4); - ReadHandler[0].Install(0x388,OPL_Read,IO_MB,4); - if (oplmode>=OPL_dualopl2) { - WriteHandler[1].Install(base,OPL_Write,IO_MB,4); - ReadHandler[1].Install(base,OPL_Read,IO_MB,4); + std::string oplemu( section->Get_string( "oplemu" ) ); + + module.chan = MixerChan.Install(OPL_CallBack,rate,"FM"); + if ( 1 || oplemu == "auto") { + if ( oplmode == OPL_opl2 ) { + module.handler = new OPL2::Handler(); + } else { + module.handler = new OPL3::Handler(); + } } - + module.handler->Init( rate ); + Bit8u portRange = 4; //opl2 will set this to 2 + switch ( oplmode ) { + case OPL_opl2: + portRange = 2; + module.Init( Adlib::MODE_OPL2 ); + break; + case OPL_dualopl2: + module.Init( Adlib::MODE_DUALOPL2 ); + break; + case OPL_opl3: + module.Init( Adlib::MODE_OPL3 ); + break; + } + //0x388 range + WriteHandler[0].Install(0x388,OPL_Write,IO_MB, portRange ); + ReadHandler[0].Install(0x388,OPL_Read,IO_MB, portRange - 1 ); + //0x220 range + WriteHandler[1].Install(base,OPL_Write,IO_MB, portRange ); + ReadHandler[1].Install(base,OPL_Read,IO_MB, portRange - 1 ); + //0x228 range WriteHandler[2].Install(base+8,OPL_Write,IO_MB,2); - ReadHandler[2].Install(base+8,OPL_Read,IO_MB,2); + ReadHandler[2].Install(base+8,OPL_Read,IO_MB,1); - opl.raw = 0; - opl.active=false; - opl.last_used=0; - opl.mode=oplmode; - memset(&opl.raw,0,sizeof(opl.raw)); - opl.chan=MixerChan.Install(OPL_CallBack,rate,"FM"); MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL"); } ~OPL() { - if (opl.raw) - delete opl.raw; + if ( module.capture ) + delete module.capture; OPL2::YM3812Shutdown(); - THEOPL3::YMF262Shutdown(); + OPL3::YMF262Shutdown(); } }; diff --git a/src/hardware/adlib.h b/src/hardware/adlib.h new file mode 100644 index 00000000..b8a0af95 --- /dev/null +++ b/src/hardware/adlib.h @@ -0,0 +1,121 @@ +#ifndef DOSBOX_ADLIB_H +#define DOSBOX_ADLIB_H + +#include "dosbox.h" +#include "mixer.h" +#include "pic.h" + +namespace Adlib { + +struct Timer { + double start; + double delay; + bool enabled, overflow, masked; + Bit8u counter; + Timer() { + masked = false; + overflow = false; + enabled = false; + counter = 0; + delay = 0; + } + //Call update before making any further changes + void Update( double time ) { + if ( !enabled || !delay ) + return; + double deltaStart = time - start; + //Only set the overflow flag when not masked + if ( deltaStart >= 0 && !masked ) { + overflow = 1; + } + } + //On a reset make sure the start is in sync with the next cycle + void Reset(const double& time ) { + overflow = false; + if ( !delay || !enabled ) + return; + double delta = (time - start); + double rem = fmod( delta, delay ); + double next = delay - rem; + start = time + next; + } + void Stop( ) { + enabled = false; + } + void Start( const double& time, Bits scale ) { + //Don't enable again + if ( enabled ) { + return; + } + enabled = true; + delay = 0.001 * (256 - counter ) * scale; + start = time + delay; + } + +}; + +struct Chip { + //Last selected register + Timer timer[2]; + //Check for it being a write to the timer + bool Write( Bit32u addr, Bit8u val ); + //Read the current timer state, will use current double + Bit8u Read( ); +}; + +//The type of handler this is +typedef enum { + MODE_OPL2, + MODE_DUALOPL2, + MODE_OPL3, +} Mode; + +class Handler { +public: + //Write an address to a chip, returns the address the chip sets + virtual Bit32u WriteAddr( Bit32u port, Bit8u val ) = 0; + //Write to a specific register in the chip + virtual void WriteReg( Bit32u addr, Bit8u val ) = 0; + //Generate a certain amount of samples + virtual void Generate( MixerChannel* chan, Bitu samples ) = 0; + //Initialize at a specific sample rate and mode + virtual void Init( Bitu rate ) = 0; +}; + +//The cache for 2 chips or an opl3 +typedef Bit8u RegisterCache[512]; + +//Internal class used for dro capturing +class Capture; + +class Module { + //Mode we're running in + Mode mode; + //Last selected address in the chip for the different modes + union { + Bit32u normal; + Bit8u dual[2]; + } reg; + void CacheWrite( Bit32u reg, Bit8u val ); + void DualWrite( Bit8u index, Bit8u reg, Bit8u val ); +public: + MixerChannel* chan; + Bit32u lastUsed; //Ticks when adlib was last used to turn of mixing after a few second + + Handler* handler; //Handler that will generate the sound + RegisterCache cache; + Capture* capture; + Chip chip[2]; + + //Handle port writes + void PortWrite( Bitu port, Bitu val, Bitu iolen ); + Bitu PortRead( Bitu port, Bitu iolen ); + void Init( Mode m ); + + Module(); +}; + + +}; //Adlib namespace + +#endif From 384ca22a2bf4977030fbfc42b3b801cb81925829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 4 Feb 2009 21:47:57 +0000 Subject: [PATCH 3212/4131] update zmbv codec stats Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3300 --- src/libs/zmbv/zmbv_vfw.cpp | 4 ++-- src/libs/zmbv/zmbv_vfw.rc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/zmbv/zmbv_vfw.cpp b/src/libs/zmbv/zmbv_vfw.cpp index a20c8444..9ae25b37 100644 --- a/src/libs/zmbv/zmbv_vfw.cpp +++ b/src/libs/zmbv/zmbv_vfw.cpp @@ -96,10 +96,10 @@ static BOOL CALLBACK AboutDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPA EndDialog(hwndDlg, 0); break; case IDC_HOMEPAGE: - ShellExecute(NULL, NULL, "http://dosbox.sf.net", NULL, NULL, SW_SHOW); + ShellExecute(NULL, NULL, "http://www.dosbox.com", NULL, NULL, SW_SHOW); break; case IDC_EMAIL: - ShellExecute(NULL, NULL, "mailto:db.crew@gmail.com", NULL, NULL, SW_SHOW); + ShellExecute(NULL, NULL, "mailto:dosbox.crew@gmail.com", NULL, NULL, SW_SHOW); break; } } diff --git a/src/libs/zmbv/zmbv_vfw.rc b/src/libs/zmbv/zmbv_vfw.rc index 6678d1a5..41d82294 100644 --- a/src/libs/zmbv/zmbv_vfw.rc +++ b/src/libs/zmbv/zmbv_vfw.rc @@ -59,7 +59,7 @@ CAPTION "DOSBox Video Codec v0.1" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN DEFPUSHBUTTON "OK",IDOK,131,34,29,14 - CTEXT "Zipped Motion Block Video v 0.1\nCopyright 2005, DOSBox Team", + CTEXT "Zipped Motion Block Video v 0.1\nCopyright 2009, DOSBox Team", IDC_STATIC,7,7,153,25,SS_NOPREFIX PUSHBUTTON "Email author",IDC_EMAIL,7,34,50,14 PUSHBUTTON "Visit home page",IDC_HOMEPAGE,59,34,58,14 From e2d1fc598f554120982b540d0ff602087734e954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 11 Feb 2009 22:16:05 +0000 Subject: [PATCH 3213/4131] prevent stuck keys when exiting the mapper, due to the mapper event preceding the addkey one (thanks to etillite, see sf bug #2581983 and posted patch) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3301 --- src/gui/sdl_gui.cpp | 8 ++++---- src/gui/sdl_mapper.cpp | 10 ++++------ src/gui/sdlmain.cpp | 20 ++++++++++---------- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index 4ad029fc..775c7637 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_gui.cpp,v 1.9 2009-02-01 16:06:26 qbix79 Exp $ */ +/* $Id: sdl_gui.cpp,v 1.10 2009-02-11 22:16:05 c2woody Exp $ */ #if 0 #include "SDL.h" @@ -561,7 +561,7 @@ public: running = false; } else if (arg == "Keyboard") { UI_Shutdown(dynamic_cast(getScreen())); - MAPPER_Run(true); + MAPPER_Run(false); UI_Startup(dynamic_cast(getScreen())); } else if (sname == "autoexec") { Section_line *section = static_cast(control->GetSection((const char *)sname)); @@ -629,4 +629,4 @@ void UI_Run(bool pressed) { UI_Shutdown(screen); delete screen; } -#endif \ No newline at end of file +#endif diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 8a787ea2..949487b1 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.56 2009-02-01 16:05:28 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.57 2009-02-11 22:16:05 c2woody Exp $ */ #include #include @@ -2268,12 +2268,10 @@ void MAPPER_LosingFocus(void) { } void MAPPER_Run(bool pressed) { - if (!pressed) + if (pressed) return; - /* Deactive all running binds */ - for (CEventVector_it evit=events.begin();evit!=events.end();evit++) { - (*evit)->DeActivateAll(); - } + KEYBOARD_ClrBuffer(); //Clear buffer + GFX_LosingFocus(); //Release any keys pressed (buffer gets filled again). int cursor = SDL_ShowCursor(SDL_QUERY); SDL_ShowCursor(SDL_ENABLE); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 6e49c917..951cc7dc 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.148 2009-02-01 16:32:33 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.149 2009-02-11 22:16:05 c2woody Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -897,7 +897,7 @@ void GFX_Start() { sdl.active=true; } -static void GUI_ShutDown(Section * sec) { +static void GUI_ShutDown(Section * /*sec*/) { GFX_Stop(); if (sdl.draw.callback) (sdl.draw.callback)( GFX_CallBackStop ); if (sdl.mouse.locked) GFX_CaptureMouse(); @@ -1026,8 +1026,8 @@ static void GUI_StartUp(Section * sec) { char* height = const_cast(strchr(fullresolution,'x')); if(height && * height) { *height = 0; - sdl.desktop.full.height = atoi(height+1); - sdl.desktop.full.width = atoi(res); + sdl.desktop.full.height = (Bit16u)atoi(height+1); + sdl.desktop.full.width = (Bit16u)atoi(res); } } } @@ -1043,22 +1043,22 @@ static void GUI_StartUp(Section * sec) { char* height = const_cast(strchr(windowresolution,'x')); if(height && *height) { *height = 0; - sdl.desktop.window.height = atoi(height+1); - sdl.desktop.window.width = atoi(res); + sdl.desktop.window.height = (Bit16u)atoi(height+1); + sdl.desktop.window.width = (Bit16u)atoi(res); } } } sdl.desktop.doublebuf=section->Get_bool("fulldouble"); if (!sdl.desktop.full.width) { #ifdef WIN32 - sdl.desktop.full.width=GetSystemMetrics(SM_CXSCREEN); + sdl.desktop.full.width=(Bit16u)GetSystemMetrics(SM_CXSCREEN); #else sdl.desktop.full.width=1024; #endif } if (!sdl.desktop.full.height) { #ifdef WIN32 - sdl.desktop.full.height=GetSystemMetrics(SM_CYSCREEN); + sdl.desktop.full.height=(Bit16u)GetSystemMetrics(SM_CYSCREEN); #else sdl.desktop.full.height=768; #endif @@ -1629,7 +1629,7 @@ int main(int argc, char* argv[]) { /* Init the keyMapper */ MAPPER_Init(); - if (control->cmdline->FindExist("-startmapper")) MAPPER_Run(true); + if (control->cmdline->FindExist("-startmapper")) MAPPER_Run(false); /* Start up main machine */ control->StartUp(); /* Shutdown everything */ From 9d45ed91b51aedb70375f3d7b952b9b741cd374b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 12 Feb 2009 21:38:23 +0000 Subject: [PATCH 3214/4131] update zmbv installer (installs under vista64 as 32bit wow6432 codec) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3302 --- src/libs/zmbv/zmbv.inf | 66 +++++++++++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/src/libs/zmbv/zmbv.inf b/src/libs/zmbv/zmbv.inf index 736f51db..a98ea016 100644 --- a/src/libs/zmbv/zmbv.inf +++ b/src/libs/zmbv/zmbv.inf @@ -1,5 +1,8 @@ -[version] -signature="$CHICAGO$" +[Version] +Signature="$CHICAGO$" +Provider=%ZMBV_PUBLISHER% +Class=MEDIA + [DefaultInstall] CopyFiles=ZMBV.Files.Inf,ZMBV.Files.Dll @@ -8,7 +11,12 @@ UpdateInis=ZMBV.INIs [DefaultInstall.ntx86] CopyFiles=ZMBV.Files.Inf,ZMBV.Files.Dll -AddReg=ZMBV.RegNT +AddReg=ZMBV.RegNTx86 +UpdateInis=ZMBV.INIs + +[DefaultInstall.ntamd64] +CopyFiles=ZMBV.Files.Inf,ZMBV.Files.Dll.NTamd64 +AddReg=ZMBV.RegNTamd64 UpdateInis=ZMBV.INIs [DefaultUnInstall] @@ -18,7 +26,12 @@ UpdateInis=ZMBV.INIs.Del [DefaultUnInstall.ntx86] DelFiles=ZMBV.Files.Dll,ZMBV.Files.Inf,ZMBV.Files.Ini -DelReg=ZMBV.RegNT +DelReg=ZMBV.RegNTx86 +UpdateInis=ZMBV.INIs.Del + +[DefaultUnInstall.ntamd64] +DelFiles=ZMBV.Files.Dll.NTamd64,ZMBV.Files.Inf,ZMBV.Files.Ini +DelReg=ZMBV.RegNTamd64 UpdateInis=ZMBV.INIs.Del [SourceDisksNames] @@ -30,6 +43,7 @@ ZMBV.INF=1 [DestinationDirs] ZMBV.Files.Inf=17 ZMBV.Files.Dll=11 +ZMBV.Files.Dll.NTamd64=10,SysWOW64 ZMBV.Files.Ini=25 [ZMBV.Files.Inf] @@ -38,28 +52,54 @@ zmbv.inf [ZMBV.Files.Dll] zmbv.dll +[ZMBV.Files.Dll.NTamd64] +zmbv.dll + [ZMBV.Files.Ini] zmbv.ini [ZMBV.Reg9x] -HKLM,SYSTEM\CurrentControlSet\Control\MediaResources\icm\VIDC.ZMBV,Description,,"Zip Motion Block Video [ZMBV]" +HKLM,SYSTEM\CurrentControlSet\Control\MediaResources\icm\VIDC.ZMBV,Description,,"%ZMBV_DISPLAY_NAME%" HKLM,SYSTEM\CurrentControlSet\Control\MediaResources\icm\VIDC.ZMBV,Driver,,"zmbv.dll" -HKLM,SYSTEM\CurrentControlSet\Control\MediaResources\icm\VIDC.ZMBV,FriendlyName,,"Zip Motion Block Video [ZMBV]" +HKLM,SYSTEM\CurrentControlSet\Control\MediaResources\icm\VIDC.ZMBV,FriendlyName,,"%ZMBV_DISPLAY_NAME%" HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV -HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,DisplayName,,"Zip Motion Block Video codec (Remove Only)" +HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,DisplayName,,"%ZMBV_UNINST_DISPLAY_NAME%" HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,UninstallString,,"rundll.exe setupx.dll,InstallHinfSection DefaultUninstall 132 %17%\ZMBV.INF" -[ZMBV.RegNT] -HKLM,SOFTWARE\Microsoft\Windows NT\CurrentVersion\drivers.desc,zmbv.dll,,"Zip Motion Block Video [ZMBV]" -HKLM,SOFTWARE\Microsoft\Windows NT\CurrentVersion\drivers32,VIDC.ZMBV,,zmbv.dll +[ZMBV.RegNTx86] +HKLM,SOFTWARE\Microsoft\Windows NT\CurrentVersion\drivers.desc,zmbv.dll,,"%ZMBV_DISPLAY_NAME%" +HKLM,SOFTWARE\Microsoft\Windows NT\CurrentVersion\drivers32,vidc.zmbv,,zmbv.dll -HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV -HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,DisplayName,,"Zip Motion Block Video codec (Remove Only)" -HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,UninstallString,,"rundll32.exe setupapi,InstallHinfSection DefaultUninstall 132 %17%\ZMBV.INF" +HKLM,SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV +HKLM,SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,DisplayName,,"%ZMBV_UNINST_DISPLAY_NAME%" +HKLM,SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,Publisher,,"%ZMBV_PUBLISHER%" +HKLM,SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,URLInfoAbout,,"%ZMBV_URL_HOMEPAGE%" +HKLM,SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,NoRepair,0x10001,01,00,00,00 +HKLM,SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,NoModify,0x10001,01,00,00,00 +HKLM,SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,UninstallString,,"rundll32.exe setupapi,InstallHinfSection DefaultUninstall 132 %17%\ZMBV.INF" + +[ZMBV.RegNTamd64] +HKLM,SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\drivers.desc,zmbv.dll,,"%ZMBV_DISPLAY_NAME%" +HKLM,SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\drivers32,vidc.zmbv,,zmbv.dll + +HKLM,SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV +HKLM,SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,DisplayName,,"%ZMBV_UNINST_DISPLAY_NAME%" +HKLM,SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,Publisher,,"%ZMBV_PUBLISHER%" +HKLM,SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,URLInfoAbout,,"%ZMBV_URL_HOMEPAGE%" +HKLM,SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,NoRepair,0x10001,01,00,00,00 +HKLM,SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,NoModify,0x10001,01,00,00,00 +HKLM,SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ZMBV,UninstallString,,"rundll32.exe setupapi.dll,InstallHinfSection DefaultUninstall 132 %17%\ZMBV.INF" [ZMBV.INIs] system.ini, drivers32,, "VIDC.ZMBV=zmbv.dll" [ZMBV.INIs.Del] system.ini, drivers32, "VIDC.ZMBV=zmbv.dll" + +[Strings] +ZMBV_PUBLISHER = "DOSBox Team" +ZMBV_DISPLAY_NAME = "Zip Motion Block Video [ZMBV]" +ZMBV_UNINST_DISPLAY_NAME = "Zip Motion Block Video codec (Remove Only)" +ZMBV_URL_HOMEPAGE = "http://www.dosbox.com/" +CODEC_INSTALLATION_FINISHED = "Zip Motion Block Video codec installation is complete." From e639014e95898a69bba8da154e3da6901b6fae09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 15 Feb 2009 10:45:01 +0000 Subject: [PATCH 3215/4131] fix batch/shell IF handling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3303 --- src/shell/shell_cmds.cpp | 56 +++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index b2a60542..94cebf73 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.88 2009-02-01 21:22:51 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.89 2009-02-15 10:45:01 c2woody Exp $ */ #include "dosbox.h" #include "shell.h" @@ -266,7 +266,7 @@ void DOS_Shell::CMD_ECHO(char * args){ if (!*args) { if (echo) { WriteOut(MSG_Get("SHELL_CMD_ECHO_ON"));} else { WriteOut(MSG_Get("SHELL_CMD_ECHO_OFF"));} - return; + return; } char buffer[512]; char* pbuffer = buffer; @@ -749,14 +749,14 @@ void DOS_Shell::CMD_SET(char * args) { void DOS_Shell::CMD_IF(char * args) { HELP("IF"); - StripSpaces(args); + StripSpaces(args,'='); bool has_not=false; - char* word; - while(strncasecmp(args,"NOT ",4) ==0) { - args += 4; //skip text + while (strncasecmp(args,"NOT",3) == 0) { + if (!isspace(*reinterpret_cast(&args[3])) && (args[3] != '=')) break; + args += 3; //skip text //skip more spaces - StripSpaces(args); + StripSpaces(args,'='); has_not = !has_not; } @@ -764,7 +764,7 @@ void DOS_Shell::CMD_IF(char * args) { args += 10; //skip text //Strip spaces and == StripSpaces(args,'='); - word = StripWord(args); + char* word = StripWord(args); if(!isdigit(*word)) { WriteOut(MSG_Get("SHELL_CMD_IF_ERRORLEVEL_MISSING_NUMBER")); return; @@ -785,11 +785,11 @@ void DOS_Shell::CMD_IF(char * args) { if(strncasecmp(args,"EXIST ",6) == 0) { args += 6; //Skip text StripSpaces(args); - word = StripWord(args); + char* word = StripWord(args); if (!*word) { WriteOut(MSG_Get("SHELL_CMD_IF_EXIST_MISSING_FILENAME")); return; - }; + } { /* DOS_FindFirst uses dta so set it to our internal dta */ RealPt save_dta=dos.dta(); @@ -802,26 +802,36 @@ void DOS_Shell::CMD_IF(char * args) { } /* Normal if string compare */ - word = args; - // Word is until space or = - while(*args && !isspace(*reinterpret_cast(args)) && (*args != '=')) + + char* word1 = args; + // first word is until space or = + while (*args && !isspace(*reinterpret_cast(args)) && (*args != '=')) args++; char* end_word1 = args; - StripSpaces(args); - //Check for 2 == - if(strlen(args)<2 || args[0] != '=' || args[1] != '=') { + + // scan for = + while (*args && (*args != '=')) + args++; + // check for == + if ((*args==0) || (args[1] != '=')) { SyntaxError(); return; } args += 2; - StripSpaces(args); - char* woord2 = args; - // Word is until space or = - while(*args && !isspace(*reinterpret_cast(args)) && (*args != '=')) + StripSpaces(args,'='); + + char* word2 = args; + // second word is until space or = + while (*args && !isspace(*reinterpret_cast(args)) && (*args != '=')) args++; - *args++=0; - *end_word1 = 0; - if ((strcmp(word,woord2)==0)==(!has_not)) DoCommand(args); + + if (*args) { + *end_word1 = 0; // mark end of first word + *args++ = 0; // mark end of second word + StripSpaces(args,'='); + + if ((strcmp(word1,word2)==0)==(!has_not)) DoCommand(args); + } } void DOS_Shell::CMD_GOTO(char * args) { From 5d7701ef6764336b9fa28bde1779c783e0f79238 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 15 Feb 2009 20:01:08 +0000 Subject: [PATCH 3216/4131] Add cycles=number support. Based on patch of h-a-l-9000, but slightly better. Beautify the configfile a bit.(Beta2) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3304 --- include/setup.h | 3 ++- src/cpu/cpu.cpp | 7 ++++++- src/dosbox.cpp | 4 ++-- src/misc/setup.cpp | 25 ++++++++++++++++++++++--- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/include/setup.h b/include/setup.h index 1a048d60..ab392b84 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.39 2009-02-01 14:11:45 qbix79 Exp $ */ +/* $Id: setup.h,v 1.40 2009-02-15 20:01:08 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -191,6 +191,7 @@ public: 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{ diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index d26a8843..871d06ea 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.114 2009-02-01 14:24:36 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.115 2009-02-15 20:01:08 qbix79 Exp $ */ #include #include @@ -2281,6 +2281,11 @@ public: std::istringstream stream(str); stream >> rmdval; CPU_CycleMax=(Bit32s)rmdval; + } else { + std::istringstream stream(type); + int rmdval=0; + stream >> rmdval; + if(rmdval) CPU_CycleMax=(Bit32s)rmdval; } CPU_CycleAutoAdjust=false; } diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 2a007b51..d872a426 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.145 2009-02-03 19:20:30 harekiet Exp $ */ +/* $Id: dosbox.cpp,v 1.146 2009-02-15 20:01:08 qbix79 Exp $ */ #include #include @@ -411,7 +411,7 @@ void DOSBOX_Init(void) { " (Example: fixed 4000)\n" " 'max' will allocate as much cycles as your computer is able to handle\n"); - const char* cyclest[] = { "auto","fixed","max",0 }; + const char* cyclest[] = { "auto","fixed","max","%u",0 }; Pstring = Pmulti_remain->GetSection()->Add_string("type",Property::Changeable::Always,"auto"); Pmulti_remain->SetValue("auto"); Pstring->Set_values(cyclest); diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index cf6c252c..2fb54478 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.53 2009-02-01 15:52:25 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.54 2009-02-15 20:01:08 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -264,6 +264,22 @@ void Prop_string::SetValue(std::string const& input){ Value val(temp,Value::V_STRING); SetVal(val,false,true); } +bool Prop_string::CheckValue(Value const& in, bool warn){ + if(suggested_values.empty()) return true; + for(iter it = suggested_values.begin();it != suggested_values.end();it++) { + if ( (*it) == in) { //Match! + return true; + } + if((*it).ToString() == "%u") { + Bitu value; + if(sscanf(in.ToString().c_str(),"%u",&value) == 1) { + return true; + } + } + } + if(warn) LOG_MSG("\"%s\" is not a valid value for variable: %s.\nIt might now be reset it to default value: %s",in.ToString().c_str(),propname.c_str(),default_value.ToString().c_str()); + return false; +} void Prop_path::SetValue(std::string const& input){ //Special version to merge realpath with it @@ -632,10 +648,13 @@ bool Config::PrintConfig(char const * const configfilename) const { fprintf(outfile, "%s%s:", prefix, MSG_Get("CONFIG_SUGGESTED_VALUES")); std::vector::iterator it = values.begin(); while (it != values.end()) { - if (it != values.begin()) fputs(",", outfile); - fprintf(outfile, " %s", (*it).ToString().c_str()); + if((*it).ToString() != "%u") { //Hack hack hack. else we need to modify GetValues, but that one is const... + if (it != values.begin()) fputs(",", outfile); + fprintf(outfile, " %s", (*it).ToString().c_str()); + } ++it; } + fprintf(outfile,"."); } fprintf(outfile, "\n"); } From 54606df9ddd7c6c1af02b7fe7000a0b736d91543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 16 Feb 2009 20:33:11 +0000 Subject: [PATCH 3217/4131] mouse min/max setting is signed, fixes Magic Maze (thanks to ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3305 --- src/ints/mouse.cpp | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 65cfe06c..247c0e6b 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.75 2009-02-01 14:24:38 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.76 2009-02-16 20:33:11 c2woody Exp $ */ #include #include @@ -37,7 +37,7 @@ static Bitu call_int33,call_int74,int74_ret_callback,call_mouse_bd; static Bit16u ps2cbseg,ps2cbofs; static bool useps2callback,ps2callbackinit; -static Bit16u call_ps2; +static Bitu call_ps2; static RealPt ps2_callback; static Bit16s oldmouseX, oldmouseY; // forward @@ -88,7 +88,7 @@ static struct { Bit16u last_pressed_y[MOUSE_BUTTONS]; Bit16u hidden; float add_x,add_y; - Bit16u min_x,max_x,min_y,max_y; + Bit16s min_x,max_x,min_y,max_y; float mickey_x,mickey_y; float x,y; button_event event_queue[QUEUE_SIZE]; @@ -260,7 +260,7 @@ static Bit8u gfxReg3CE[9]; static Bit8u index3C4,gfxReg3C5; void SaveVgaRegisters() { if (IS_VGA_ARCH) { - for (int i=0; i<9; i++) { + for (Bit8u i=0; i<9; i++) { IO_Write (0x3CE,i); gfxReg3CE[i] = IO_Read(0x3CF); } @@ -280,7 +280,7 @@ void SaveVgaRegisters() { void RestoreVgaRegisters() { if (IS_VGA_ARCH) { - for (int i=0; i<9; i++) { + for (Bit8u i=0; i<9; i++) { IO_Write(0x3CE,i); IO_Write(0x3CF,gfxReg3CE[i]); } @@ -370,8 +370,8 @@ void DrawCursor() { // Get Clipping ranges - mouse.clipx = CurMode->swidth-1; /* Get from bios ? */ - mouse.clipy = CurMode->sheight-1; + mouse.clipx = (Bit16s)((Bits)CurMode->swidth-1); /* Get from bios ? */ + mouse.clipy = (Bit16s)((Bits)CurMode->sheight-1); /* might be vidmode == 0x13?2:1 */ Bit16s xratio = 640; @@ -445,7 +445,7 @@ void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate) { if (CurMode->type == M_TEXT) { mouse.x = x*CurMode->swidth; mouse.y = y*CurMode->sheight * 8 / CurMode->cheight; - } else if (mouse.max_x < 2048 || mouse.max_y < 2048 || mouse.max_x != mouse.max_y) { + } else if (abs(mouse.max_x) < 2048 || abs(mouse.max_y) < 2048 || mouse.max_x != mouse.max_y) { mouse.x = x*mouse.max_x; mouse.y = y*mouse.max_y; } else { // Games faking relative movement through absolute coordinates. Quite surprising that this actually works.. @@ -659,13 +659,13 @@ static Bitu INT33_Handler(void) { /* If position isn't different from current position * don't change it then. (as position is rounded so numbers get * lost when the rounded number is set) (arena/simulation Wolf) */ - if(reg_cx >= mouse.max_x) mouse.x = static_cast(mouse.max_x); - else if (mouse.min_x >= reg_cx) mouse.x = static_cast(mouse.min_x); - else if (reg_cx != POS_X) mouse.x = static_cast(reg_cx); + if ((Bit16s)reg_cx >= mouse.max_x) mouse.x = static_cast(mouse.max_x); + else if (mouse.min_x >= (Bit16s)reg_cx) mouse.x = static_cast(mouse.min_x); + else if ((Bit16s)reg_cx != POS_X) mouse.x = static_cast(reg_cx); - if(reg_dx >= mouse.max_y) mouse.y = static_cast(mouse.max_y); - else if (mouse.min_y >= reg_dx) mouse.y = static_cast(mouse.min_y); - else if (reg_dx != POS_Y) mouse.y = static_cast(reg_dx); + if ((Bit16s)reg_dx >= mouse.max_y) mouse.y = static_cast(mouse.max_y); + else if (mouse.min_y >= (Bit16s)reg_dx) mouse.y = static_cast(mouse.min_y); + else if ((Bit16s)reg_dx != POS_Y) mouse.y = static_cast(reg_dx); DrawCursor(); break; case 0x05: /* Return Button Press Data */ @@ -696,7 +696,7 @@ static Bitu INT33_Handler(void) { { //lemmings set 1-640 and wants that. iron seeds set 0-640 but doesn't like 640 //Iron seed works if newvideo mode with mode 13 sets 0-639 //Larry 6 actually wants newvideo mode with mode 13 to set it to 0-319 - Bits max,min; + Bit16s max,min; if ((Bit16s)reg_cx<(Bit16s)reg_dx) { min=(Bit16s)reg_cx;max=(Bit16s)reg_dx;} else { min=(Bit16s)reg_dx;max=(Bit16s)reg_cx;} mouse.min_x=min; @@ -713,7 +713,7 @@ static Bitu INT33_Handler(void) { { // not sure what to take instead of the CurMode (see case 0x07 as well) // especially the cases where sheight= 400 and we set it with the mouse_reset to 200 //disabled it at the moment. Seems to break syndicate who want 400 in mode 13 - Bits max,min; + Bit16s max,min; if ((Bit16s)reg_cx<(Bit16s)reg_dx) { min=(Bit16s)reg_cx;max=(Bit16s)reg_dx;} else { min=(Bit16s)reg_dx;max=(Bit16s)reg_cx;} mouse.min_y=min; @@ -865,11 +865,12 @@ static Bitu INT33_Handler(void) { break; case 0x26: /* Get Maximum virtual coordinates */ reg_bx=(mouse.enabled ? 0x0000 : 0xffff); - reg_cx=mouse.max_x; - reg_dx=mouse.max_y; + reg_cx=(Bit16u)mouse.max_x; + reg_dx=(Bit16u)mouse.max_y; break; default: LOG(LOG_MOUSE,LOG_ERROR)("Mouse Function %04X not implemented!",reg_ax); + break; } return CBRET_NONE; } @@ -970,7 +971,7 @@ Bitu MOUSE_UserInt_CB_Handler(void) { return CBRET_NONE; } -void MOUSE_Init(Section* sec) { +void MOUSE_Init(Section* /*sec*/) { // Callback for mouse interrupt 0x33 call_int33=CALLBACK_Allocate(); // RealPt i33loc=RealMake(CB_SEG+1,(call_int33*CB_SIZE)-0x10); From 30cadccb6ef1e00d1076642e31ae32a2e22bab00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 19 Feb 2009 10:52:53 +0000 Subject: [PATCH 3218/4131] can't people just remove a simple call themselves and not opening hundreds of reports for dev sources before it's finished? Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3306 --- src/ints/mouse.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 247c0e6b..5142143b 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.76 2009-02-16 20:33:11 c2woody Exp $ */ +/* $Id: mouse.cpp,v 1.77 2009-02-19 10:52:53 c2woody Exp $ */ #include #include @@ -445,9 +445,14 @@ void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate) { if (CurMode->type == M_TEXT) { mouse.x = x*CurMode->swidth; mouse.y = y*CurMode->sheight * 8 / CurMode->cheight; - } else if (abs(mouse.max_x) < 2048 || abs(mouse.max_y) < 2048 || mouse.max_x != mouse.max_y) { - mouse.x = x*mouse.max_x; - mouse.y = y*mouse.max_y; + } else if ((mouse.max_x < 2048) || (mouse.max_y < 2048) || (mouse.max_x != mouse.max_y)) { + if ((mouse.max_x > 0) && (mouse.max_y > 0)) { + mouse.x = x*mouse.max_x; + mouse.y = y*mouse.max_y; + } else { + mouse.x += xrel; + mouse.y += yrel; + } } else { // Games faking relative movement through absolute coordinates. Quite surprising that this actually works.. mouse.x += xrel; mouse.y += yrel; From 97257734079d8ba644bad173860f29f10b3f2a48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 20 Feb 2009 14:19:47 +0000 Subject: [PATCH 3219/4131] keep drive cache lists sorted on insert to avoid full sort calls Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3307 --- include/dos_system.h | 8 +-- src/dos/drive_cache.cpp | 137 ++++++++++++++++++++++++++-------------- 2 files changed, 94 insertions(+), 51 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 9269a416..ead2cc50 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.43 2008-08-06 18:31:10 c2woody Exp $ */ +/* $Id: dos_system.h,v 1.44 2009-02-20 14:19:43 c2woody Exp $ */ #ifndef DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H @@ -179,9 +179,9 @@ private: bool RemoveTrailingDot (char* shortname); Bits GetLongName (CFileInfo* info, char* shortname); void CreateShortName (CFileInfo* dir, CFileInfo* info); - Bit16u CreateShortNameID (CFileInfo* dir, const char* name); + Bitu CreateShortNameID (CFileInfo* dir, const char* name); int CompareShortname (const char* compareName, const char* shortName); - bool SetResult (CFileInfo* dir, char * &result, Bit16u entryNr); + bool SetResult (CFileInfo* dir, char * &result, Bitu entryNr); bool IsCachedIn (CFileInfo* dir); CFileInfo* FindDirInfo (const char* path, char* expandedPath); bool RemoveSpaces (char* str); diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index c0ee732d..e1adb529 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.54 2008-09-23 17:13:18 c2woody Exp $ */ +/* $Id: drive_cache.cpp,v 1.55 2009-02-20 14:19:47 c2woody Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -205,8 +205,7 @@ char* DOS_Drive_Cache::GetExpandName(const char* path) return work; }; -void DOS_Drive_Cache::AddEntry(const char* path, bool checkExists) -{ +void DOS_Drive_Cache::AddEntry(const char* path, bool checkExists) { // Get Last part... char file [CROSS_LEN]; char expand [CROSS_LEN]; @@ -216,12 +215,13 @@ void DOS_Drive_Cache::AddEntry(const char* path, bool checkExists) if (pos) { strcpy(file,pos+1); - // Check if file already exists, then dont add new entry... - if (checkExists && (GetLongName(dir,file)>=0)) return; + // Check if file already exists, then don't add new entry... + if (checkExists) { + if (GetLongName(dir,file)>=0) return; + } CreateEntry(dir,file); - // Sort Lists - filelist has to be alphabetically sorted - std::sort(dir->fileList.begin(), dir->fileList.end(), SortByName); + Bits index = GetLongName(dir,file); if (index>=0) { Bit32u i; @@ -229,13 +229,13 @@ void DOS_Drive_Cache::AddEntry(const char* path, bool checkExists) if (dir) for (i=0; inextEntry)) dirSearch[i]->nextEntry++; - } - }; + } + } // LOG_DEBUG("DIR: Added Entry %s",path); } else { // LOG_DEBUG("DIR: Error: Failed to add %s",path); - }; -}; + } +} void DOS_Drive_Cache::DeleteEntry(const char* path, bool ignoreLastDir) { @@ -291,14 +291,16 @@ bool DOS_Drive_Cache::IsCachedIn(CFileInfo* curDir) }; -bool DOS_Drive_Cache::GetShortName(const char* fullname, char* shortname) -{ +bool DOS_Drive_Cache::GetShortName(const char* fullname, char* shortname) { // Get Dir Info char expand[CROSS_LEN] = {0}; CFileInfo* curDir = FindDirInfo(fullname,expand); + std::vector::size_type filelist_size = curDir->longNameList.size(); + if (GCC_UNLIKELY(filelist_size<=0)) return false; + Bits low = 0; - Bits high = (Bits)(curDir->longNameList.size()-1); + Bits high = (Bits)(filelist_size-1); Bits mid, res; while (low<=high) { @@ -346,11 +348,13 @@ int DOS_Drive_Cache::CompareShortname(const char* compareName, const char* short return strcmp(compareName,shortName); }; -Bit16u DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name) -{ - Bits foundNr = 0; +Bitu DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name) { + std::vector::size_type filelist_size = curDir->longNameList.size(); + if (GCC_UNLIKELY(filelist_size<=0)) return 0; + + Bitu foundNr = 0; Bits low = 0; - Bits high = (Bits)(curDir->longNameList.size()-1); + Bits high = (Bits)(filelist_size-1); Bits mid, res; while (low<=high) { @@ -361,7 +365,7 @@ Bit16u DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name) if (res<0) high = mid-1; else { // any more same x chars in next entries ? - do { + do { foundNr = curDir->longNameList[mid]->shortNr; mid++; } while((Bitu)midlongNameList.size() && (CompareShortname(name,curDir->longNameList[mid]->shortname)==0)); @@ -386,11 +390,14 @@ bool DOS_Drive_Cache::RemoveTrailingDot(char* shortname) Bits DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) { + std::vector::size_type filelist_size = curDir->fileList.size(); + if (GCC_UNLIKELY(filelist_size<=0)) return -1; + // Remove dot, if no extension... RemoveTrailingDot(shortName); // Search long name and return array number of element Bits low = 0; - Bits high = (Bits)(curDir->fileList.size()-1); + Bits high = (Bits)(filelist_size-1); Bits mid,res; while (low<=high) { mid = (low+high)/2; @@ -418,8 +425,7 @@ bool DOS_Drive_Cache::RemoveSpaces(char* str) return (curpos!=chkpos); }; -void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) -{ +void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) { Bits len = 0; bool createShort = false; @@ -476,18 +482,38 @@ void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) // add extension strncat(info->shortname,pos,4); info->shortname[DOS_NAMELENGTH] = 0; - }; - // Put it in longname list... - curDir->longNameList.push_back(info); - std::sort(curDir->longNameList.begin(), curDir->longNameList.end(), SortByName); + } + + // keep list sorted for CreateShortNameID to work correctly + if (curDir->longNameList.size()>0) { + if (!(strcmp(info->shortname,curDir->longNameList.back()->shortname)<0)) { + // append at end of list + curDir->longNameList.push_back(info); + } else { + // look for position where to insert this element + bool found=false; + std::vector::iterator it; + for (it=curDir->longNameList.begin(); it!=curDir->longNameList.end(); ++it) { + if (strcmp(info->shortname,(*it)->shortname)<0) { + found = true; + break; + } + } + // Put it in longname list... + if (found) curDir->longNameList.insert(it,info); + else curDir->longNameList.push_back(info); + } + } else { + // empty file list, append + curDir->longNameList.push_back(info); + } } else { strcpy(info->shortname,tmpName); } RemoveTrailingDot(info->shortname); -}; +} -DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* expandedPath) -{ +DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* expandedPath) { // statics static char split[2] = { CROSS_FILESPLIT,0 }; @@ -601,8 +627,7 @@ bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, const char* expand, Bit16u& id) return false; }; -void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name) -{ +void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name) { struct stat status; CFileInfo* info = new CFileInfo; strcpy(info->orgname ,name); @@ -615,9 +640,32 @@ void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name) else info->isDir = false; // Check for long filenames... CreateShortName(dir, info); - // Put file in lists - dir->fileList.push_back(info); -}; + + bool found = false; + + // keep list sorted (so GetLongName works correctly, used by CreateShortName in this routine) + if (dir->fileList.size()>0) { + if (!(strcmp(info->shortname,dir->fileList.back()->shortname)<0)) { + // append at end of list + dir->fileList.push_back(info); + } else { + // look for position where to insert this element + std::vector::iterator it; + for (it=dir->fileList.begin(); it!=dir->fileList.end(); ++it) { + if (strcmp(info->shortname,(*it)->shortname)<0) { + found = true; + break; + } + } + // Put file in lists + if (found) dir->fileList.insert(it,info); + else dir->fileList.push_back(info); + } + } else { + // empty file list, append + dir->fileList.push_back(info); + } +} bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) { @@ -635,9 +683,6 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) struct dirent* tmpres; while ((tmpres = readdir(dirp))!=NULL) { CreateEntry(dirSearch[id],tmpres->d_name); - // Sort Lists - filelist has to be alphabetically sorted, even in between (for finding double file names) - // hmpf.. bit slow probably... - std::sort(dirSearch[id]->fileList.begin(), dirSearch[id]->fileList.end(), SortByName); } // close dir closedir(dirp); @@ -656,7 +701,7 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) return false; }; -bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bit16u entryNr) +bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bitu entryNr) { static char res[CROSS_LEN] = { 0 }; @@ -671,8 +716,7 @@ bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bit16u entryNr) }; // FindFirst / FindNext -bool DOS_Drive_Cache::FindFirst(char* path, Bitu& id) -{ +bool DOS_Drive_Cache::FindFirst(char* path, Bitu& id) { Bit16u dirID; Bitu dirFindFirstID = this->nextFreeFindFirst; @@ -688,7 +732,7 @@ bool DOS_Drive_Cache::FindFirst(char* path, Bitu& id) dirFindFirstID = 0; this->nextFreeFindFirst = 1; //the next free one after this search for(Bitu n=0; nfileList.size(); i++) { CreateEntry(dirFindFirst[dirFindFirstID],dirSearch[dirID]->fileList[i]->orgname); - // Sort Lists - filelist has to be alphabetically sorted, even in between (for finding double file names) - std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByName); - }; + } // Now re-sort the fileList accordingly to output switch (sortDirType) { - case ALPHABETICAL : std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByName); break; + case ALPHABETICAL : break; +// case ALPHABETICAL : std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByName); break; case DIRALPHABETICAL : std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByDirName); break; case ALPHABETICALREV : std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByNameRev); break; case DIRALPHABETICALREV : std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByDirNameRev); break; case NOSORT : break; - }; + } // LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst : %s (ID:%02X)",path,dirFindFirstID); id = dirFindFirstID; From ad13c63c3263987bda8dab6a4dff1db835ded423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 24 Feb 2009 17:56:55 +0000 Subject: [PATCH 3220/4131] avoid using stat calls if possible (reusing cached data if needed) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3308 --- include/dos_system.h | 20 ++++++++++---------- src/dos/drive_cache.cpp | 22 +++++++++++++++------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index ead2cc50..04dd50ec 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.44 2009-02-20 14:19:43 c2woody Exp $ */ +/* $Id: dos_system.h,v 1.45 2009-02-24 17:56:55 c2woody Exp $ */ #ifndef DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H @@ -105,12 +105,12 @@ public: open=true; return *this; } - DOS_Device():DOS_File(),devnum(0){}; + 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 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;} @@ -118,7 +118,7 @@ private: Bitu devnum; }; -/* The following variable can be lowered to free up some memory. +/* 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 @@ -140,7 +140,7 @@ public: 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); @@ -153,7 +153,7 @@ public: char* GetLabel (void) { return label; }; class CFileInfo { - public: + public: CFileInfo(void) { orgname[0] = shortname[0] = 0; nextEntry = shortNr = 0; @@ -186,7 +186,7 @@ private: 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); + void CreateEntry (CFileInfo* dir, const char* name, Bitu query_directory); Bit16u GetFreeID (CFileInfo* dir); void Clear (void); @@ -241,7 +241,7 @@ public: virtual char const * GetLabel(){return dirCache.GetLabel();}; DOS_Drive_Cache dirCache; - + // disk cycling functionality (request resources) virtual void Activate(void) {}; }; @@ -251,8 +251,8 @@ enum { DOS_SEEK_SET=0,DOS_SEEK_CUR=1,DOS_SEEK_END=2}; /* - A multiplex handler should read the registers to check what function is being called - If the handler returns false dos will stop checking other handlers + A multiplex handler should read the registers to check what function is being called + If the handler returns false dos will stop checking other handlers */ typedef bool (MultiplexHandler)(void); diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index e1adb529..b2177b93 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.55 2009-02-20 14:19:47 c2woody Exp $ */ +/* $Id: drive_cache.cpp,v 1.56 2009-02-24 17:56:55 c2woody Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -220,7 +220,7 @@ void DOS_Drive_Cache::AddEntry(const char* path, bool checkExists) { if (GetLongName(dir,file)>=0) return; } - CreateEntry(dir,file); + CreateEntry(dir,file,0); Bits index = GetLongName(dir,file); if (index>=0) { @@ -627,7 +627,7 @@ bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, const char* expand, Bit16u& id) return false; }; -void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name) { +void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name, Bitu is_directory) { struct stat status; CFileInfo* info = new CFileInfo; strcpy(info->orgname ,name); @@ -636,8 +636,13 @@ void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name) { char buffer[CROSS_LEN]; strcpy(buffer,dirPath); strcat(buffer,info->orgname); - if (stat(buffer,&status)==0) info->isDir = (S_ISDIR(status.st_mode)>0); - else info->isDir = false; + switch (is_directory) { + case 0: info->isDir = false; break; + case 1: info->isDir = true; break; + case 2: + if (stat(buffer,&status)==0) info->isDir = (S_ISDIR(status.st_mode)>0); + else info->isDir = false; + } // Check for long filenames... CreateShortName(dir, info); @@ -682,7 +687,9 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) // Read complete directory struct dirent* tmpres; while ((tmpres = readdir(dirp))!=NULL) { - CreateEntry(dirSearch[id],tmpres->d_name); + // is_dir from readdir?? + CreateEntry(dirSearch[id],tmpres->d_name,2); +// CreateEntry(dirSearch[id],tmpres->d_name,(tmpres->d_type==DT_DIR)?1:0); } // close dir closedir(dirp); @@ -743,7 +750,8 @@ bool DOS_Drive_Cache::FindFirst(char* path, Bitu& id) { // Copy entries to use with FindNext for (Bitu i=0; ifileList.size(); i++) { - CreateEntry(dirFindFirst[dirFindFirstID],dirSearch[dirID]->fileList[i]->orgname); + CreateEntry(dirFindFirst[dirFindFirstID],dirSearch[dirID]->fileList[i]->orgname, + dirSearch[dirID]->fileList[i]->isDir?1:0); } // Now re-sort the fileList accordingly to output switch (sortDirType) { From 6934389b52ab0b6664a94a27d526ba1f16b0cd16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 25 Feb 2009 19:58:11 +0000 Subject: [PATCH 3221/4131] update displayed year entries Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3309 --- src/gui/sdl_gui.cpp | 6 +-- src/gui/sdlmain.cpp | 106 ++++++++++++++++++++++---------------------- 2 files changed, 56 insertions(+), 56 deletions(-) diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index 775c7637..1cba06d9 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_gui.cpp,v 1.10 2009-02-11 22:16:05 c2woody Exp $ */ +/* $Id: sdl_gui.cpp,v 1.11 2009-02-25 19:58:11 c2woody Exp $ */ #if 0 #include "SDL.h" @@ -39,7 +39,7 @@ #include extern Bit8u int10_font_14[256 * 14]; -extern Program * first_shell; +extern Program * first_shell; extern void MSG_Write(const char *); extern void GFX_SetTitle(Bit32s cycles, Bits frameskip, bool paused); @@ -570,7 +570,7 @@ public: Section_prop *section = static_cast(sec); new SectionEditor(getScreen(), 50, 30, section); } else if (arg == "About") { - new GUI::MessageBox(getScreen(), 200, 150, 280, "About DOSBox", "\nDOSBox 0.72\nAn emulator for old DOS Games\n\nCopyright 2002-2007\nThe DOSBox Team"); + new GUI::MessageBox(getScreen(), 200, 150, 280, "About DOSBox", "\nDOSBox 0.72\nAn emulator for old DOS Games\n\nCopyright 2002-2009\nThe DOSBox Team"); } else if (arg == "Introduction") { new GUI::MessageBox(getScreen(), 20, 50, 600, "Introduction", MSG_Get("PROGRAM_INTRO")); } else if (arg == "Getting Started") { diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 951cc7dc..68965219 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.149 2009-02-11 22:16:05 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.150 2009-02-25 19:58:11 c2woody Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -74,7 +74,7 @@ typedef void (APIENTRY * PFNWGLFREEMEMORYNVPROC) (void *pointer); PFNWGLALLOCATEMEMORYNVPROC db_glAllocateMemoryNV = NULL; PFNWGLFREEMEMORYNVPROC db_glFreeMemoryNV = NULL; -#else +#else #endif @@ -130,7 +130,7 @@ struct private_hwdata { #include #endif -enum SCREEN_TYPES { +enum SCREEN_TYPES { SCREEN_SURFACE, SCREEN_SURFACE_DDRAW, SCREEN_OVERLAY, @@ -256,16 +256,16 @@ static void PauseDOSBox(bool pressed) { while (SDL_PollEvent(&event)) { // flush event queue. } - + while (paused) { SDL_WaitEvent(&event); // since we're not polling, cpu usage drops to 0. switch (event.type) { - + case SDL_QUIT: throw(0); break; case SDL_KEYDOWN: // Must use Pause/Break Key to resume. case SDL_KEYUP: if(event.key.keysym.sym==SDLK_PAUSE) { - + paused=false; GFX_SetTitle(-1,-1,false); break; @@ -384,7 +384,7 @@ static SDL_Surface * GFX_SetupSurfaceScaled(Bit32u sdl_flags, Bit32u bpp) { sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex*ratio_h); sdl.clip.h=(Bit16u)fixedHeight; } - if (sdl.desktop.fullscreen) + if (sdl.desktop.fullscreen) sdl.surface = SDL_SetVideoMode(fixedWidth,fixedHeight,bpp,sdl_flags); else sdl.surface = SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags); @@ -406,7 +406,7 @@ static SDL_Surface * GFX_SetupSurfaceScaled(Bit32u sdl_flags, Bit32u bpp) { } Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_CallBack_t callback) { - if (sdl.updating) + if (sdl.updating) GFX_EndUpdate( 0 ); sdl.draw.width=width; @@ -417,7 +417,7 @@ Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,G Bitu bpp=0; Bitu retFlags = 0; - + if (sdl.blit.surface) { SDL_FreeSurface(sdl.blit.surface); sdl.blit.surface=0; @@ -437,13 +437,13 @@ dosurface: sdl.clip.x=(Sint16)((sdl.desktop.full.width-width)/2); sdl.clip.y=(Sint16)((sdl.desktop.full.height-height)/2); sdl.surface=SDL_SetVideoMode(sdl.desktop.full.width,sdl.desktop.full.height,bpp, - SDL_FULLSCREEN | ((flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE) | + SDL_FULLSCREEN | ((flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE) | (sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0) | SDL_HWPALETTE); if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",sdl.desktop.full.width,sdl.desktop.full.height,bpp,SDL_GetError()); } else { sdl.clip.x=0;sdl.clip.y=0; sdl.surface=SDL_SetVideoMode(width,height,bpp, - SDL_FULLSCREEN | ((flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE) | + SDL_FULLSCREEN | ((flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE) | (sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0)|SDL_HWPALETTE); if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",width,height,bpp,SDL_GetError()); @@ -467,7 +467,7 @@ dosurface: sdl.surface = SDL_SetVideoMode(width,height,bpp,SDL_HWSURFACE); } #endif - if (sdl.surface == NULL) + if (sdl.surface == NULL) E_Exit("Could not set windowed video mode %ix%i-%i: %s",width,height,bpp,SDL_GetError()); } if (sdl.surface) { @@ -585,7 +585,7 @@ dosurface: glPixelDataRangeNV(GL_WRITE_PIXEL_DATA_RANGE_NV,width*height*4,sdl.opengl.framebuf); glEnableClientState(GL_WRITE_PIXEL_DATA_RANGE_NV); } else { -#else +#else { #endif sdl.opengl.framebuf=malloc(width*height*4); //32 bit color @@ -613,7 +613,7 @@ dosurface: glClear(GL_COLOR_BUFFER_BIT); SDL_GL_SwapBuffers(); glClear(GL_COLOR_BUFFER_BIT); - glShadeModel (GL_FLAT); + glShadeModel (GL_FLAT); glDisable (GL_DEPTH_TEST); glDisable (GL_LIGHTING); glDisable(GL_CULL_FACE); @@ -652,7 +652,7 @@ dosurface: goto dosurface; break; }//CASE - if (retFlags) + if (retFlags) GFX_Start(); if (!sdl.mouse.autoenable) SDL_ShowCursor(sdl.mouse.autolock?SDL_DISABLE:SDL_ENABLE); return retFlags; @@ -695,7 +695,7 @@ static void SwitchFullScreen(bool pressed) { bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) { - if (!sdl.active || sdl.updating) + if (!sdl.active || sdl.updating) return false; switch (sdl.desktop.type) { case SCREEN_SURFACE: @@ -749,7 +749,7 @@ void GFX_EndUpdate( const Bit16u *changedLines ) { #if (HAVE_DDRAW_H) && defined(WIN32) int ret; #endif - if (!sdl.updating) + if (!sdl.updating) return; sdl.updating=false; switch (sdl.desktop.type) { @@ -816,7 +816,7 @@ void GFX_EndUpdate( const Bit16u *changedLines ) { #if defined(NVIDIA_PixelDataRange) if (sdl.opengl.pixel_data_range) { glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, sdl.draw.width, sdl.draw.height, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, sdl.opengl.framebuf); glCallList(sdl.opengl.displaylist); @@ -832,7 +832,7 @@ void GFX_EndUpdate( const Bit16u *changedLines ) { } else { Bit8u *pixels = (Bit8u *)sdl.opengl.framebuf + y * sdl.opengl.pitch; Bitu height = changedLines[index]; - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, y, + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, y, sdl.draw.width, height, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, pixels ); y += height; @@ -888,7 +888,7 @@ Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue) { } void GFX_Stop() { - if (sdl.updating) + if (sdl.updating) GFX_EndUpdate( 0 ); sdl.active=false; } @@ -913,10 +913,10 @@ static void KillSwitch(bool pressed) { static void SetPriority(PRIORITY_LEVELS level) { #if C_SET_PRIORITY -// Do nothing if priorties are not the same and not root, else the highest +// Do nothing if priorties are not the same and not root, else the highest // priority can not be set as users can only lower priority (not restore it) - if((sdl.priority.focus != sdl.priority.nofocus ) && + if((sdl.priority.focus != sdl.priority.nofocus ) && (getuid()!=0) ) return; #endif @@ -986,22 +986,22 @@ static void GUI_StartUp(Section * sec) { sdl.desktop.fullscreen=section->Get_bool("fullscreen"); sdl.wait_on_error=section->Get_bool("waitonerror"); - + Prop_multival* p=section->Get_multival("priority"); std::string focus = p->GetSection()->Get_string("active"); std::string notfocus = p->GetSection()->Get_string("inactive"); - if (focus == "lowest") { sdl.priority.focus = PRIORITY_LEVEL_LOWEST; } - else if (focus == "lower") { sdl.priority.focus = PRIORITY_LEVEL_LOWER; } - else if (focus == "normal") { sdl.priority.focus = PRIORITY_LEVEL_NORMAL; } - else if (focus == "higher") { sdl.priority.focus = PRIORITY_LEVEL_HIGHER; } - else if (focus == "highest") { sdl.priority.focus = PRIORITY_LEVEL_HIGHEST; } + if (focus == "lowest") { sdl.priority.focus = PRIORITY_LEVEL_LOWEST; } + else if (focus == "lower") { sdl.priority.focus = PRIORITY_LEVEL_LOWER; } + else if (focus == "normal") { sdl.priority.focus = PRIORITY_LEVEL_NORMAL; } + else if (focus == "higher") { sdl.priority.focus = PRIORITY_LEVEL_HIGHER; } + else if (focus == "highest") { sdl.priority.focus = PRIORITY_LEVEL_HIGHEST; } - if (notfocus == "lowest") { sdl.priority.nofocus=PRIORITY_LEVEL_LOWEST; } - else if (notfocus == "lower") { sdl.priority.nofocus=PRIORITY_LEVEL_LOWER; } - else if (notfocus == "normal") { sdl.priority.nofocus=PRIORITY_LEVEL_NORMAL; } - else if (notfocus == "higher") { sdl.priority.nofocus=PRIORITY_LEVEL_HIGHER; } - else if (notfocus == "highest") { sdl.priority.nofocus=PRIORITY_LEVEL_HIGHEST; } + if (notfocus == "lowest") { sdl.priority.nofocus=PRIORITY_LEVEL_LOWEST; } + else if (notfocus == "lower") { sdl.priority.nofocus=PRIORITY_LEVEL_LOWER; } + else if (notfocus == "normal") { sdl.priority.nofocus=PRIORITY_LEVEL_NORMAL; } + else if (notfocus == "higher") { sdl.priority.nofocus=PRIORITY_LEVEL_HIGHER; } + else if (notfocus == "highest") { sdl.priority.nofocus=PRIORITY_LEVEL_HIGHEST; } else if (notfocus == "pause") { /* we only check for pause here, because it makes no sense * for DOSBox to be paused while it has focus @@ -1052,14 +1052,14 @@ static void GUI_StartUp(Section * sec) { if (!sdl.desktop.full.width) { #ifdef WIN32 sdl.desktop.full.width=(Bit16u)GetSystemMetrics(SM_CXSCREEN); -#else +#else sdl.desktop.full.width=1024; #endif } if (!sdl.desktop.full.height) { #ifdef WIN32 sdl.desktop.full.height=(Bit16u)GetSystemMetrics(SM_CYSCREEN); -#else +#else sdl.desktop.full.height=768; #endif } @@ -1068,7 +1068,7 @@ static void GUI_StartUp(Section * sec) { sdl.mouse.autolock=false; sdl.mouse.sensitivity=section->Get_int("sensitivity"); std::string output=section->Get_string("output"); - + /* Setup Mouse correctly if fullscreen */ if(sdl.desktop.fullscreen) GFX_CaptureMouse(); @@ -1117,14 +1117,14 @@ static void GUI_StartUp(Section * sec) { #if defined(NVIDIA_PixelDataRange) sdl.opengl.pixel_data_range=(strstr(gl_ext,"GL_NV_pixel_data_range") >0 ) && glPixelDataRangeNV && db_glAllocateMemoryNV && db_glFreeMemoryNV; - sdl.opengl.pixel_data_range = 0; + sdl.opengl.pixel_data_range = 0; #endif } else { sdl.opengl.packed_pixel=sdl.opengl.paletted_texture=false; } } } /* OPENGL is requested end */ - + #endif //OPENGL /* Initialize screen for first time */ sdl.surface=SDL_SetVideoMode(640,400,0,0); @@ -1159,7 +1159,7 @@ void Mouse_AutoLock(bool enable) { } static void HandleMouseMotion(SDL_MouseMotionEvent * motion) { - if (sdl.mouse.locked || !sdl.mouse.autoenable) + if (sdl.mouse.locked || !sdl.mouse.autoenable) Mouse_CursorMoved((float)motion->xrel*sdl.mouse.sensitivity/100.0f, (float)motion->yrel*sdl.mouse.sensitivity/100.0f, (float)(motion->x-sdl.clip.x)/(sdl.clip.w-1)*sdl.mouse.sensitivity/100.0f, @@ -1275,7 +1275,7 @@ void GFX_Events() { SDL_WaitEvent(&ev); switch (ev.type) { - case SDL_QUIT: throw(0); break; // a bit redundant at linux at least as the active events gets before the quit event. + case SDL_QUIT: throw(0); break; // a bit redundant at linux at least as the active events gets before the quit event. case SDL_ACTIVEEVENT: // wait until we get window focus back if (ev.active.state & (SDL_APPINPUTFOCUS | SDL_APPACTIVE)) { // We've got focus back, so unpause and break out of the loop @@ -1382,7 +1382,7 @@ void Config_Add_SDL() { Pstring->Set_help("Scale the window to this size IF the output device supports hardware scaling."); const char* outputs[] = { - "surface", "overlay", + "surface", "overlay", #if C_OPENGL "opengl", "openglnb", #endif @@ -1438,13 +1438,13 @@ static void launcheditor(std::string const& edit) { printf("no editor specified.\n"); exit(1); } - + execlp(edit.c_str(),edit.c_str(),path.c_str(),(char*) 0); //if you get here the launching failed! printf("can't find editor %s\n",edit.c_str()); exit(1); } - + static void printconfiglocation() { std::string path,file; Cross::CreatePlatformConfigDir(path); @@ -1459,7 +1459,7 @@ static void printconfiglocation() { printf("%s\n",path.c_str()); exit(0); } - + //extern void UI_Init(void); int main(int argc, char* argv[]) { @@ -1496,9 +1496,9 @@ int main(int argc, char* argv[]) { SetConsoleTitle("DOSBox Status Window"); } #endif //defined(WIN32) && !(C_DEBUG) - if (control->cmdline->FindExist("-version") || + if (control->cmdline->FindExist("-version") || control->cmdline->FindExist("--version") ) { - printf("\nDOSBox version %s, copyright 2002-2007 DOSBox Team.\n\n",VERSION); + printf("\nDOSBox version %s, copyright 2002-2009 DOSBox Team.\n\n",VERSION); printf("DOSBox is written by the DOSBox Team (See AUTHORS file))\n"); printf("DOSBox comes with ABSOLUTELY NO WARRANTY. This is free software,\n"); printf("and you are welcome to redistribute it under certain conditions;\n"); @@ -1609,8 +1609,8 @@ int main(int argc, char* argv[]) { LOG_MSG("CONFIG: Using default settings. Create a configfile to change them"); } } - - + + #if (ENVIRON_LINKED) control->ParseEnv(environ); #endif @@ -1620,7 +1620,7 @@ int main(int argc, char* argv[]) { control->Init(); /* Some extra SDL Functions */ Section_prop * sdl_sec=static_cast(control->GetSection("sdl")); - + if (control->cmdline->FindExist("-fullscreen") || sdl_sec->Get_bool("fullscreen")) { if(!sdl.desktop.fullscreen) { //only switch if not allready in fullscreen GFX_SwitchFullScreen(); @@ -1644,23 +1644,23 @@ int main(int argc, char* argv[]) { fgetc(stdin); #elif defined(WIN32) Sleep(5000); -#endif +#endif } } - catch (int){ + catch (int){ ;//nothing pressed killswitch } catch(...){ //Force visible mouse to end user. Somehow this sometimes doesn't happen SDL_WM_GrabInput(SDL_GRAB_OFF); SDL_ShowCursor(SDL_ENABLE); - throw;//dunno what happened. rethrow for sdl to catch + throw;//dunno what happened. rethrow for sdl to catch } //Force visible mouse to end user. Somehow this sometimes doesn't happen SDL_WM_GrabInput(SDL_GRAB_OFF); SDL_ShowCursor(SDL_ENABLE); - + SDL_Quit();//Let's hope sdl will quit as well when it catches an exception return 0; }; From e08513aece479d25544ccb27715b110f5658e1b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 28 Feb 2009 11:34:10 +0000 Subject: [PATCH 3222/4131] fix file shortener ID of the drive cache (under rare conditions, bug recently introduced); use better/faster method to copy the drive cache contents for findfirst, directly related to the shortname bug found+analyzed by Alexander Katz (sf patch #2194354) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3310 --- include/dos_system.h | 3 ++- src/dos/drive_cache.cpp | 42 +++++++++++++++++++++++------------------ 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 04dd50ec..8ee17459 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.45 2009-02-24 17:56:55 c2woody Exp $ */ +/* $Id: dos_system.h,v 1.46 2009-02-28 11:34:04 c2woody Exp $ */ #ifndef DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H @@ -187,6 +187,7 @@ private: bool RemoveSpaces (char* str); bool OpenDir (CFileInfo* dir, const char* path, Bit16u& id); void CreateEntry (CFileInfo* dir, const char* name, Bitu query_directory); + void CopyEntry (CFileInfo* dir, CFileInfo* from); Bit16u GetFreeID (CFileInfo* dir); void Clear (void); diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index b2177b93..96921ebd 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.56 2009-02-24 17:56:55 c2woody Exp $ */ +/* $Id: drive_cache.cpp,v 1.57 2009-02-28 11:34:10 c2woody Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -350,7 +350,7 @@ int DOS_Drive_Cache::CompareShortname(const char* compareName, const char* short Bitu DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name) { std::vector::size_type filelist_size = curDir->longNameList.size(); - if (GCC_UNLIKELY(filelist_size<=0)) return 0; + if (GCC_UNLIKELY(filelist_size<=0)) return 1; // shortener IDs start with 1 Bitu foundNr = 0; Bits low = 0; @@ -672,8 +672,18 @@ void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name, Bitu is_dire } } -bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) -{ +void DOS_Drive_Cache::CopyEntry(CFileInfo* dir, CFileInfo* from) { + CFileInfo* info = new CFileInfo; + // just copy things into new fileinfo + strcpy(info->orgname, from->orgname); + strcpy(info->shortname, from->shortname); + info->shortNr = from->shortNr; + info->isDir = from->isDir; + + dir->fileList.push_back(info); +} + +bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) { // shouldnt happen... if (id>MAX_OPENDIRS) return false; @@ -687,12 +697,11 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) // Read complete directory struct dirent* tmpres; while ((tmpres = readdir(dirp))!=NULL) { - // is_dir from readdir?? CreateEntry(dirSearch[id],tmpres->d_name,2); -// CreateEntry(dirSearch[id],tmpres->d_name,(tmpres->d_type==DT_DIR)?1:0); } // close dir closedir(dirp); + // Info /* if (!dirp) { LOG_DEBUG("DIR: Error Caching in %s",dirPath); @@ -701,15 +710,14 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) char buffer[128]; sprintf(buffer,"DIR: Caching in %s (%d Files)",dirPath,dirSearch[srchNr]->fileList.size()); LOG_DEBUG(buffer); - };*/ - }; + }*/ + } if (SetResult(dirSearch[id], result, dirSearch[id]->nextEntry)) return true; free[id] = true; return false; -}; +} -bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bitu entryNr) -{ +bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bitu entryNr) { static char res[CROSS_LEN] = { 0 }; result = res; @@ -720,7 +728,7 @@ bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bitu entryNr) // Set to next Entry dir->nextEntry = entryNr+1; return true; -}; +} // FindFirst / FindNext bool DOS_Drive_Cache::FindFirst(char* path, Bitu& id) { @@ -750,8 +758,7 @@ bool DOS_Drive_Cache::FindFirst(char* path, Bitu& id) { // Copy entries to use with FindNext for (Bitu i=0; ifileList.size(); i++) { - CreateEntry(dirFindFirst[dirFindFirstID],dirSearch[dirID]->fileList[i]->orgname, - dirSearch[dirID]->fileList[i]->isDir?1:0); + CopyEntry(dirFindFirst[dirFindFirstID],dirSearch[dirID]->fileList[i]); } // Now re-sort the fileList accordingly to output switch (sortDirType) { @@ -766,10 +773,9 @@ bool DOS_Drive_Cache::FindFirst(char* path, Bitu& id) { // LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst : %s (ID:%02X)",path,dirFindFirstID); id = dirFindFirstID; return true; -}; +} -bool DOS_Drive_Cache::FindNext(Bitu id, char* &result) -{ +bool DOS_Drive_Cache::FindNext(Bitu id, char* &result) { // out of range ? if ((id>=MAX_OPENDIRS) || !dirFindFirst[id]) { LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst/Next failure : ID out of range: %04X",id); @@ -781,4 +787,4 @@ bool DOS_Drive_Cache::FindNext(Bitu id, char* &result) return false; } return true; -}; +} From d289485bdfc2b50af261a955db38d5123e547023 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 28 Feb 2009 14:28:10 +0000 Subject: [PATCH 3223/4131] Forgot a ~ Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3311 --- src/misc/cross.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/misc/cross.cpp b/src/misc/cross.cpp index 06c009a7..316e60d3 100644 --- a/src/misc/cross.cpp +++ b/src/misc/cross.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.cpp,v 1.2 2009-02-03 08:27:47 qbix79 Exp $ */ +/* $Id: cross.cpp,v 1.3 2009-02-28 14:28:10 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -41,7 +41,7 @@ void Cross::GetPlatformConfigDir(std::string& in) { in = result; in += "\\DOSBox"; #elif defined(MACOSX) - in = "/Library/Preferences"; + in = "~/Library/Preferences"; ResolveHomedir(in); #else in = "~/.dosbox"; From 614cec47ff98033b59f70e34b208b9cf3b86e100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 1 Mar 2009 15:40:30 +0000 Subject: [PATCH 3224/4131] mscdex check sets some register that isn't mentioned in references (thanks to ripsaw, fixes part of judge dredd) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3312 --- src/dos/dos_mscdex.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index ac2046ce..3dd8c7a1 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.57 2009-02-01 14:24:36 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.58 2009-03-01 15:40:30 c2woody Exp $ */ #include #include @@ -1097,6 +1097,7 @@ static bool MSCDEX_Handler(void) { case 0x1500: /* Install check */ reg_bx = mscdex->GetNumDrives(); if (reg_bx>0) reg_cx = mscdex->GetFirstDrive(); + reg_al = 0xff; return true; case 0x1501: /* Get cdrom driver info */ mscdex->GetDriverInfo(data); From 8fa4a2d43a3180bbae71b1d7e20de2c3690dea9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 3 Mar 2009 18:30:41 +0000 Subject: [PATCH 3225/4131] clear direction flag when entering ps2 irq routine (needed when irq happens if direction flag is set and the user subroutine assumes DF to be clear), thanks to ripsaw for figuring this out Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3313 --- src/cpu/callback.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index cda77a75..fd88711f 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.39 2009-01-18 13:57:45 c2woody Exp $ */ +/* $Id: callback.cpp,v 1.40 2009-03-03 18:30:41 c2woody Exp $ */ #include #include @@ -268,11 +268,12 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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)0xfb); // sti - 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 - return 0x09; + 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 From 904307ce5b2e639feede4cb10440d210ce4c91d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 4 Mar 2009 19:34:42 +0000 Subject: [PATCH 3226/4131] add custom fast filesearch routines Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3314 --- include/cross.h | 30 +++++++++++- src/ints/mouse.cpp | 8 ++-- src/misc/cross.cpp | 111 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 141 insertions(+), 8 deletions(-) diff --git a/include/cross.h b/include/cross.h index d92379e4..60473b8e 100644 --- a/include/cross.h +++ b/include/cross.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.h,v 1.19 2009-02-01 14:11:45 qbix79 Exp $ */ +/* $Id: cross.h,v 1.20 2009-03-04 19:34:42 c2woody Exp $ */ #ifndef DOSBOX_CROSS_H #define DOSBOX_CROSS_H @@ -77,4 +77,30 @@ public: }; +#if defined (WIN32) + +#if defined (WIN32) /* Win 32 */ +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from +#include +#endif + +typedef struct dir_struct { + HANDLE handle; + char base_path[MAX_PATH+4]; + WIN32_FIND_DATA search_data; +} dir_information; + +#else + +#include + +typedef DIR dir_information; + +#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 diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 5142143b..2be96182 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.77 2009-02-19 10:52:53 c2woody Exp $ */ +/* $Id: mouse.cpp,v 1.78 2009-03-04 19:34:42 c2woody Exp $ */ #include #include @@ -188,7 +188,7 @@ Bitu PS2_Handler(void) { #define X_MICKEY 8 #define Y_MICKEY 8 -#define MOUSE_MOVED 1 +#define MOUSE_HAS_MOVED 1 #define MOUSE_LEFT_PRESSED 2 #define MOUSE_LEFT_RELEASED 4 #define MOUSE_RIGHT_PRESSED 8 @@ -200,7 +200,7 @@ INLINE void Mouse_AddEvent(Bit8u type) { if (mouse.events0) { /* Skip duplicate events */ - if ((type==MOUSE_MOVED) && (mouse.buttons==0)) return; + if ((type==MOUSE_HAS_MOVED) && (mouse.buttons==0)) return; /* Always put the newest element in the front as that the events are * handled backwards (prevents doubleclicks while moving) */ @@ -467,7 +467,7 @@ void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate) { if (mouse.y > mouse.max_y) mouse.y = mouse.max_y; if (mouse.y < mouse.min_y) mouse.y = mouse.min_y; } - Mouse_AddEvent(MOUSE_MOVED); + Mouse_AddEvent(MOUSE_HAS_MOVED); DrawCursor(); } diff --git a/src/misc/cross.cpp b/src/misc/cross.cpp index 316e60d3..d45e5b19 100644 --- a/src/misc/cross.cpp +++ b/src/misc/cross.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,15 +16,18 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.cpp,v 1.3 2009-02-28 14:28:10 qbix79 Exp $ */ +/* $Id: cross.cpp,v 1.4 2009-03-04 19:34:42 c2woody Exp $ */ #include "dosbox.h" #include "cross.h" +#include "support.h" #include #include #ifdef WIN32 +#ifndef _WIN32_IE #define _WIN32_IE 0x0400 +#endif #include #endif @@ -104,3 +107,107 @@ void Cross::CreateDir(std::string const& in) { mkdir(in.c_str(),0700); #endif } + +#if defined (WIN32) + +dir_information* open_directory(const char* dirname) { + if (dirname == NULL) return NULL; + + size_t len = strlen(dirname); + if (len == 0) return NULL; + + static dir_information dir; + + safe_strncpy(dir.base_path,dirname,MAX_PATH); + + if (dirname[len-1]=='\\') strcat(dir.base_path,"*.*"); + else strcat(dir.base_path,"\\*.*"); + + dir.handle = INVALID_HANDLE_VALUE; + + return (access(dirname,0) ? NULL : &dir); +} + +bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory) { + dirp->handle = FindFirstFile(dirp->base_path, &dirp->search_data); + if (INVALID_HANDLE_VALUE == dirp->handle) { + return false; + } + + safe_strncpy(entry_name,dirp->search_data.cFileName,(MAX_PATHsearch_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) is_directory = true; + else is_directory = false; + + return true; +} + +bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) { + int result = FindNextFile(dirp->handle, &dirp->search_data); + if (result==0) return false; + + safe_strncpy(entry_name,dirp->search_data.cFileName,(MAX_PATHsearch_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) is_directory = true; + else is_directory = false; + + return true; +} + +void close_directory(dir_information* dirp) { + if (dirp->handle != INVALID_HANDLE_VALUE) { + FindClose(dirp->handle); + dirp->handle = INVALID_HANDLE_VALUE; + } +} + +#else + +#include "dirent.h" +//#include "stdio.h" + +typedef DIR dir_information; + +dir_information* open_directory(const char* dirname) { + return opendir(dirname); +} + +bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory) { + struct dirent* dentry = readdir(dirp); + if (dentry==NULL) { + return false; + } + +// safe_strncpy(entry_name,dentry->d_name,(FILENAME_MAXd_name,CROSS_LEN); + + // probably use d_type here instead of a full stat() + struct stat status; + if (stat(entry_name,&status)==0) is_directory = (S_ISDIR(status.st_mode)>0); + else is_directory = false; + + return true; +} + +bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) { + struct dirent* dentry = readdir(dirp); + if (dentry==NULL) { + return false; + } + +// safe_strncpy(entry_name,dentry->d_name,(FILENAME_MAXd_name,CROSS_LEN); + + // probably use d_type here instead of a full stat() + struct stat status; + if (stat(entry_name,&status)==0) is_directory = (S_ISDIR(status.st_mode)>0); + else is_directory = false; + + return true; +} + +void close_directory(dir_information* dirp) { + closedir(dirp); +} + +#endif From 2fd9c8f349168f06f92dfde40c6501b3ff52435f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 4 Mar 2009 21:08:22 +0000 Subject: [PATCH 3227/4131] use fast filesearch routines for directory cache Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3315 --- include/dos_system.h | 4 ++-- src/dos/drive_cache.cpp | 50 +++++++++++++++++++---------------------- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 8ee17459..e530cded 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.46 2009-02-28 11:34:04 c2woody Exp $ */ +/* $Id: dos_system.h,v 1.47 2009-03-04 21:08:22 c2woody Exp $ */ #ifndef DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H @@ -186,7 +186,7 @@ private: 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, Bitu query_directory); + void CreateEntry (CFileInfo* dir, const char* name, bool query_directory); void CopyEntry (CFileInfo* dir, CFileInfo* from); Bit16u GetFreeID (CFileInfo* dir); void Clear (void); diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 96921ebd..a34e2bca 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -16,12 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.57 2009-02-28 11:34:10 c2woody Exp $ */ +/* $Id: drive_cache.cpp,v 1.58 2009-03-04 21:08:22 c2woody Exp $ */ #include "drives.h" #include "dos_inc.h" -#include "dirent.h" #include "support.h" +#include "cross.h" // STL stuff #include @@ -220,7 +220,7 @@ void DOS_Drive_Cache::AddEntry(const char* path, bool checkExists) { if (GetLongName(dir,file)>=0) return; } - CreateEntry(dir,file,0); + CreateEntry(dir,file,false); Bits index = GetLongName(dir,file); if (index>=0) { @@ -615,10 +615,10 @@ bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, const char* expand, Bit16u& id) // open dir if (dirSearch[id]) { // open dir - DIR* dirp = opendir(expandcopy); + dir_information* dirp = open_directory(expandcopy); if (dirp) { // Reset it.. - closedir(dirp); + close_directory(dirp); strcpy(dirPath,expandcopy); free[id] = false; return true; @@ -627,22 +627,12 @@ bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, const char* expand, Bit16u& id) return false; }; -void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name, Bitu is_directory) { - struct stat status; +void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name, bool is_directory) { CFileInfo* info = new CFileInfo; - strcpy(info->orgname ,name); + strcpy(info->orgname, name); info->shortNr = 0; - // Read and copy file stats - char buffer[CROSS_LEN]; - strcpy(buffer,dirPath); - strcat(buffer,info->orgname); - switch (is_directory) { - case 0: info->isDir = false; break; - case 1: info->isDir = true; break; - case 2: - if (stat(buffer,&status)==0) info->isDir = (S_ISDIR(status.st_mode)>0); - else info->isDir = false; - } + info->isDir = is_directory; + // Check for long filenames... CreateShortName(dir, info); @@ -689,18 +679,23 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) { if (!IsCachedIn(dirSearch[id])) { // Try to open directory - DIR* dirp = opendir(dirPath); + dir_information* dirp = open_directory(dirPath); if (!dirp) { free[id] = true; return false; } // Read complete directory - struct dirent* tmpres; - while ((tmpres = readdir(dirp))!=NULL) { - CreateEntry(dirSearch[id],tmpres->d_name,2); + char dir_name[CROSS_LEN]; + bool is_directory; + if (read_directory_first(dirp, dir_name, is_directory)) { + CreateEntry(dirSearch[id], dir_name, is_directory); + while (read_directory_next(dirp, dir_name, is_directory)) { + CreateEntry(dirSearch[id], dir_name, is_directory); + } } + // close dir - closedir(dirp); + close_directory(dirp); // Info /* if (!dirp) { @@ -710,14 +705,15 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) { char buffer[128]; sprintf(buffer,"DIR: Caching in %s (%d Files)",dirPath,dirSearch[srchNr]->fileList.size()); LOG_DEBUG(buffer); - }*/ - } + };*/ + }; if (SetResult(dirSearch[id], result, dirSearch[id]->nextEntry)) return true; free[id] = true; return false; } -bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bitu entryNr) { +bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bitu entryNr) +{ static char res[CROSS_LEN] = { 0 }; result = res; From 48edfe540907e9b29e4e1425d014bed0e8aa0919 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 11 Mar 2009 20:18:37 +0000 Subject: [PATCH 3228/4131] Add Get_arglength, make trim(string a bit more flexible with whitespace so that configfiles from windows can be used on linux without converting Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3316 --- include/programs.h | 4 +++- src/misc/setup.cpp | 13 ++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/include/programs.h b/include/programs.h index a6f7e172..b86987a0 100644 --- a/include/programs.h +++ b/include/programs.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.h,v 1.17 2008-07-26 19:06:26 qbix79 Exp $ */ +/* $Id: programs.h,v 1.18 2009-03-11 20:18:37 qbix79 Exp $ */ #ifndef DOSBOX_PROGRAMS_H #define DOSBOX_PROGRAMS_H @@ -54,6 +54,8 @@ public: bool GetStringRemain(std::string & value); unsigned int GetCount(void); void Shift(unsigned int amount=1); + Bit16u Get_arglength(); + private: typedef std::list::iterator cmd_it; std::list cmds; diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 2fb54478..1cbbea0e 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.54 2009-02-15 20:01:08 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.55 2009-03-11 20:18:37 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -556,9 +556,9 @@ Hex Section_prop::Get_hex(string const& _propname) const { } void trim(string& in) { - string::size_type loc = in.find_first_not_of(' '); + string::size_type loc = in.find_first_not_of(" \r\t\f\n"); if(loc != string::npos) in.erase(0,loc); - loc = in.find_last_not_of(' '); + loc = in.find_last_not_of(" \r\t\f\n"); if(loc != string::npos) in.erase(loc+1); } @@ -956,6 +956,13 @@ CommandLine::CommandLine(int argc,char const * const argv[]) { i++; } } +Bit16u CommandLine::Get_arglength() { + if(cmds.empty()) return 0; + Bit16u i=1; + for(cmd_it it=cmds.begin();it != cmds.end();it++) + i+=(*it).size() + 1; + return --i; +} CommandLine::CommandLine(char const * const name,char const * const cmdline) { From 88d134b3a9d466b7381e9f019aceec620fefd487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 14 Mar 2009 16:10:00 +0000 Subject: [PATCH 3229/4131] implement temp file creation function when used without a path (see sf bug #2665465) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3317 --- src/dos/dos.cpp | 8 ++++---- src/dos/dos_files.cpp | 12 +++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index e9ae9c3b..cd3ff0eb 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.115 2009-01-14 22:16:00 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.116 2009-03-14 16:10:00 c2woody Exp $ */ #include #include @@ -67,8 +67,8 @@ static Bitu DOS_21Handler(void) { psp.SetStack(RealMake(SegValue(ss),reg_sp-18)); } - char name1[DOSNAMEBUF+1]; - char name2[DOSNAMEBUF+1]; + char name1[DOSNAMEBUF+2+DOS_NAMELENGTH_ASCII]; + char name2[DOSNAMEBUF+2+DOS_NAMELENGTH_ASCII]; switch (reg_ah) { case 0x01: /* Read character from STDIN, with echo */ { diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 0f4da6a3..4d80ab59 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.105 2009-01-24 16:22:55 c2woody Exp $ */ +/* $Id: dos_files.cpp,v 1.106 2009-03-14 16:10:00 c2woody Exp $ */ #include #include @@ -698,19 +698,21 @@ bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry) { } - bool DOS_CreateTempFile(char * const name,Bit16u * entry) { - /* First add random crap to the end of the name and try to open */ size_t namelen=strlen(name); char * tempname=name+namelen; - if (namelen==0) E_Exit("DOS:Invalid call to CreateTempFile"); - else { + if (namelen==0) { + // temp file created in root directory + tempname[0]='\\'; + tempname++; + } else { if ((name[namelen-1]!='\\') && (name[namelen-1]!='/')) { tempname[0]='\\'; tempname++; } } dos.errorcode=0; + /* add random crap to the end of the name and try to open */ do { Bit32u i; for (i=0;i<8;i++) { From 9b8d6f45eb07dfb71b9c12c126b23c7378b4613a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 14 Mar 2009 18:02:34 +0000 Subject: [PATCH 3230/4131] Linux fastdir support. Fix problems without fastdir support (closes: 2671401) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3318 --- configure.in | 10 +++++++++ include/cross.h | 16 ++++++++------- src/misc/cross.cpp | 51 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 58 insertions(+), 19 deletions(-) diff --git a/configure.in b/configure.in index 3cf4bc49..1d9f13a9 100644 --- a/configure.in +++ b/configure.in @@ -110,6 +110,16 @@ 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 +#include +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 if test x$target = xi386-pc-os2-emx ; then AC_MSG_CHECKING(for powf in libm); diff --git a/include/cross.h b/include/cross.h index 60473b8e..6a558e6f 100644 --- a/include/cross.h +++ b/include/cross.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.h,v 1.20 2009-03-04 19:34:42 c2woody Exp $ */ +/* $Id: cross.h,v 1.21 2009-03-14 18:02:34 qbix79 Exp $ */ #ifndef DOSBOX_CROSS_H #define DOSBOX_CROSS_H @@ -79,22 +79,24 @@ public: #if defined (WIN32) -#if defined (WIN32) /* Win 32 */ #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from #include -#endif typedef struct dir_struct { - HANDLE handle; - char base_path[MAX_PATH+4]; - WIN32_FIND_DATA search_data; + HANDLE handle; + char base_path[MAX_PATH+4]; + WIN32_FIND_DATA search_data; } dir_information; #else +//#include //Included above #include -typedef DIR dir_information; +typedef struct dir_struct { + DIR* dir; + char base_path[CROSS_LEN]; +} dir_information; #endif diff --git a/src/misc/cross.cpp b/src/misc/cross.cpp index d45e5b19..74ad66bc 100644 --- a/src/misc/cross.cpp +++ b/src/misc/cross.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.cpp,v 1.4 2009-03-04 19:34:42 c2woody Exp $ */ +/* $Id: cross.cpp,v 1.5 2009-03-14 18:02:34 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -163,17 +163,15 @@ void close_directory(dir_information* dirp) { #else -#include "dirent.h" -//#include "stdio.h" - -typedef DIR dir_information; - dir_information* open_directory(const char* dirname) { - return opendir(dirname); + static dir_information dir; + dir.dir=opendir(dirname); + safe_strncpy(dir.base_path,dirname,CROSS_LEN); + return dir.dir?&dir:NULL; } bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory) { - struct dirent* dentry = readdir(dirp); + struct dirent* dentry = readdir(dirp->dir); if (dentry==NULL) { return false; } @@ -181,16 +179,30 @@ bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_dire // safe_strncpy(entry_name,dentry->d_name,(FILENAME_MAXd_name,CROSS_LEN); +#ifdef DIRENT_HAS_D_TYPE + if(dentry->d_type == DT_DIR) { + is_directory = true; + return true; + } else if(dentry->d_type == DT_REG) { + is_directory = false; + return true; + } +#endif + // probably use d_type here instead of a full stat() + static char buffer[2*CROSS_LEN] = { 0 }; + buffer[0] = 0; + strcpy(buffer,dirp->base_path); + strcat(buffer,entry_name); struct stat status; - if (stat(entry_name,&status)==0) is_directory = (S_ISDIR(status.st_mode)>0); + if (stat(buffer,&status)==0) is_directory = (S_ISDIR(status.st_mode)>0); else is_directory = false; return true; } bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) { - struct dirent* dentry = readdir(dirp); + struct dirent* dentry = readdir(dirp->dir); if (dentry==NULL) { return false; } @@ -198,16 +210,31 @@ bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_direc // safe_strncpy(entry_name,dentry->d_name,(FILENAME_MAXd_name,CROSS_LEN); +#ifdef DIRENT_HAS_D_TYPE + if(dentry->d_type == DT_DIR) { + is_directory = true; + return true; + } else if(dentry->d_type == DT_REG) { + is_directory = false; + return true; + } +#endif + // probably use d_type here instead of a full stat() + static char buffer[2*CROSS_LEN] = { 0 }; + buffer[0] = 0; + strcpy(buffer,dirp->base_path); + strcat(buffer,entry_name); struct stat status; - if (stat(entry_name,&status)==0) is_directory = (S_ISDIR(status.st_mode)>0); + + if (stat(buffer,&status)==0) is_directory = (S_ISDIR(status.st_mode)>0); else is_directory = false; return true; } void close_directory(dir_information* dirp) { - closedir(dirp); + closedir(dirp->dir); } #endif From b8fa29c72afe61b52f20fe9316e8b6f965782d70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 15 Mar 2009 11:28:35 +0000 Subject: [PATCH 3231/4131] remove obsolete define about vga memory size Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3319 --- include/vga.h | 5 ++--- src/hardware/vga_s3.cpp | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/include/vga.h b/include/vga.h index de5b8292..bd3ae94c 100644 --- a/include/vga.h +++ b/include/vga.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga.h,v 1.45 2009-01-26 20:23:44 qbix79 Exp $ */ +/* $Id: vga.h,v 1.46 2009-03-15 11:28:34 c2woody Exp $ */ #ifndef DOSBOX_VGA_H #define DOSBOX_VGA_H @@ -28,7 +28,6 @@ //Don't enable keeping changes and mapping lfb probably... #define VGA_LFB_MAPPED //#define VGA_KEEP_CHANGES -#define VGA_MEMORY (2*1024*1024) #define VGA_CHANGE_SHIFT 9 class PageHandler; diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index 2f6c283c..0be0982a 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_s3.cpp,v 1.17 2008-12-28 20:22:12 c2woody Exp $ */ +/* $Id: vga_s3.cpp,v 1.18 2009-03-15 11:28:35 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -532,7 +532,7 @@ void SVGA_Setup_S3Trio(void) { svga.accepts_mode = &SVGA_S3_AcceptsMode; if (vga.vmemsize == 0) - vga.vmemsize = VGA_MEMORY; // the most common S3 configuration + vga.vmemsize = 2*1024*1024; // the most common S3 configuration // Set CRTC 36 to specify amount of VRAM and PCI if (vga.vmemsize < 1024*1024) { From 65396d5313fb23c3b5864ea281e2cdc7a73dfeb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 15 Mar 2009 18:54:46 +0000 Subject: [PATCH 3232/4131] update porting docs Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3320 --- docs/PORTING | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/docs/PORTING b/docs/PORTING index b2d0b8a1..f95c62d1 100644 --- a/docs/PORTING +++ b/docs/PORTING @@ -2,13 +2,10 @@ Some notes about porting DOSBox to systems with certain restrictions, like handheld devices. If memory is a constraint: - - in paging.h reduce the size of the TLB: - #define TLB_SIZE (64*1024) - the 64 gives access to the first 256mb of linear memory - drawback: some protected mode games won't work then + - 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 - TODO: limit vmemory access to the size of the TLB, - otherwise games which use >256mb vaddresses will crash badly - in render.h lower the scaler integration: #define RENDER_USE_ADVANCED_SCALERS 1 or @@ -22,18 +19,17 @@ If memory is a constraint: ~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 whith large directory trees + 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 - - in vga.h reduce the size of the emulated graphics memory: - #define VGA_MEMORY (1*1024*1024) + - 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 - [EDIT: many modes won't work due to pixel caches] - gain: reduces memory requirements about 1mb - TODO: get this to actually work; - remove the respective svga modes, adapt some svga registers + 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 From 44fd168a61ad9bb9046933d4dfa675a589bbed8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 16 Mar 2009 18:10:08 +0000 Subject: [PATCH 3233/4131] adjust debug checking for int/call functions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3321 --- src/cpu/cpu.cpp | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 871d06ea..fdfa4c48 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.115 2009-02-15 20:01:08 qbix79 Exp $ */ +/* $Id: cpu.cpp,v 1.116 2009-03-16 18:10:08 c2woody Exp $ */ #include #include @@ -599,14 +599,15 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { return; } - CPU_CHECK_COND(!gate.saved.seg.p, - "INT:Gate segment not present", - EXCEPTION_NP,num*8+2+(type&CPU_INT_SOFTWARE)?0:1) switch (gate.Type()) { case DESC_286_INT_GATE: case DESC_386_INT_GATE: case DESC_286_TRAP_GATE: case DESC_386_TRAP_GATE: { + CPU_CHECK_COND(!gate.saved.seg.p, + "INT:Gate segment not present", + EXCEPTION_NP,num*8+2+(type&CPU_INT_SOFTWARE)?0:1) + Descriptor cs_desc; Bitu gate_sel=gate.GetSelector(); Bitu gate_off=gate.GetOffset(); @@ -738,6 +739,10 @@ do_interrupt: return; } case DESC_TASK_GATE: + CPU_CHECK_COND(!gate.saved.seg.p, + "INT:Gate segment not present", + EXCEPTION_NP,num*8+2+(type&CPU_INT_SOFTWARE)?0:1) + CPU_SwitchTask(gate.GetSelector(),TSwitch_CALL_INT,oldeip); if (type & CPU_INT_HAS_ERROR) { //TODO Be sure about this, seems somewhat unclear @@ -1143,15 +1148,17 @@ call_code: CPU_CHECK_COND(n_cs_dpl>cpu.cpl, "CALL:Gate:CS DPL>CPL", EXCEPTION_GP,n_cs_sel & 0xfffc) + + CPU_CHECK_COND(!n_cs_desc.saved.seg.p, + "CALL:Gate:CS not present", + EXCEPTION_NP,n_cs_sel & 0xfffc) + Bitu n_eip = call.GetOffset(); switch (n_cs_desc.Type()) { case DESC_CODE_N_NC_A:case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A:case DESC_CODE_R_NC_NA: /* Check if we goto inner priviledge */ if (n_cs_dpl < cpu.cpl) { - CPU_CHECK_COND(!n_cs_desc.saved.seg.p, - "CALL:Gate:CS not present", - EXCEPTION_NP,n_cs_sel & 0xfffc) /* Get new SS:ESP out of TSS */ Bitu n_ss_sel,n_esp; Descriptor n_ss_desc; @@ -1267,10 +1274,15 @@ call_code: case DESC_386_TSS_A: CPU_CHECK_COND(call.DPL() Date: Mon, 16 Mar 2009 18:33:59 +0000 Subject: [PATCH 3234/4131] Add 32bit signed type for mixing Change the mixer template to use a class type Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3322 --- include/mixer.h | 23 +++++++------ src/hardware/mixer.cpp | 77 ++++++++++++++++++++++-------------------- 2 files changed, 53 insertions(+), 47 deletions(-) diff --git a/include/mixer.h b/include/mixer.h index af0ebbc0..b8e75926 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -50,16 +50,19 @@ public: void SetFreq(Bitu _freq); void Mix(Bitu _needed); void AddSilence(void); //Fill up until needed - template - void AddSamples(Bitu len,void * data); - void AddSamples_m8(Bitu len,Bit8u * data); - void AddSamples_s8(Bitu len,Bit8u * data); - void AddSamples_m8s(Bitu len,Bit8s * data); - void AddSamples_s8s(Bitu len,Bit8s * data); - void AddSamples_m16(Bitu len,Bit16s * data); - void AddSamples_s16(Bitu len,Bit16s * data); - void AddSamples_m16u(Bitu len,Bit16u * data); - void AddSamples_s16u(Bitu len,Bit16u * data); + template + 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 AddStretched(Bitu len,Bit16s * data); //Strech block up into needed data void FillUp(void); void Enable(bool _yesno); diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index ce42db4c..84d1a977 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.48 2008-10-05 14:44:52 qbix79 Exp $ */ +/* $Id: mixer.cpp,v 1.49 2009-03-16 18:33:59 harekiet Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -174,13 +174,9 @@ void MixerChannel::AddSilence(void) { } } -template -INLINE void MixerChannel::AddSamples(Bitu len,void * data) { +template +INLINE void MixerChannel::AddSamples(Bitu len, const Type* data) { Bits diff[2]; - Bit8u * data8=(Bit8u*)data; - Bit8s * data8s=(Bit8s*)data; - Bit16s * data16=(Bit16s*)data; - Bit16u * data16u=(Bit16u*)data; Bitu mixpos=mixer.pos+done; freq_index&=MIXER_REMAIN; Bitu pos=0;Bitu new_pos; @@ -194,36 +190,37 @@ INLINE void MixerChannel::AddSamples(Bitu len,void * data) { pos=new_pos; thestart: if (pos>=len) return; - if (_8bits) { + if ( sizeof( Type) == 1) { if (!signeddata) { if (stereo) { - diff[0]=(((Bit8s)(data8[pos*2+0] ^ 0x80)) << 8)-last[0]; - diff[1]=(((Bit8s)(data8[pos*2+1] ^ 0x80)) << 8)-last[1]; + diff[0]=(((Bit8s)(data[pos*2+0] ^ 0x80)) << 8)-last[0]; + diff[1]=(((Bit8s)(data[pos*2+1] ^ 0x80)) << 8)-last[1]; } else { - diff[0]=(((Bit8s)(data8[pos] ^ 0x80)) << 8)-last[0]; + diff[0]=(((Bit8s)(data[pos] ^ 0x80)) << 8)-last[0]; } } else { if (stereo) { - diff[0]=(data8s[pos*2+0] << 8)-last[0]; - diff[1]=(data8s[pos*2+1] << 8)-last[1]; + diff[0]=(data[pos*2+0] << 8)-last[0]; + diff[1]=(data[pos*2+1] << 8)-last[1]; } else { - diff[0]=(data8s[pos] << 8)-last[0]; + diff[0]=(data[pos] << 8)-last[0]; } } - } else { + //16bit and 32bit both contain 16bit data internally + } else { if (signeddata) { if (stereo) { - diff[0]=data16[pos*2+0]-last[0]; - diff[1]=data16[pos*2+1]-last[1]; + diff[0]=data[pos*2+0]-last[0]; + diff[1]=data[pos*2+1]-last[1]; } else { - diff[0]=data16[pos]-last[0]; + diff[0]=data[pos]-last[0]; } } else { if (stereo) { - diff[0]=(Bits)data16u[pos*2+0]-32768-last[0]; - diff[1]=(Bits)data16u[pos*2+1]-32768-last[1]; + diff[0]=(Bits)data[pos*2+0]-32768-last[0]; + diff[1]=(Bits)data[pos*2+1]-32768-last[1]; } else { - diff[0]=(Bits)data16u[pos]-32768-last[0]; + diff[0]=(Bits)data[pos]-32768-last[0]; } } } @@ -267,29 +264,35 @@ void MixerChannel::AddStretched(Bitu len,Bit16s * data) { } } -void MixerChannel::AddSamples_m8(Bitu len,Bit8u * data) { - AddSamples(len,data); +void MixerChannel::AddSamples_m8(Bitu len, const Bit8u * data) { + AddSamples(len,data); } -void MixerChannel::AddSamples_s8(Bitu len,Bit8u * data) { - AddSamples(len,data); +void MixerChannel::AddSamples_s8(Bitu len,const Bit8u * data) { + AddSamples(len,data); } -void MixerChannel::AddSamples_m8s(Bitu len,Bit8s * data) { - AddSamples(len,data); +void MixerChannel::AddSamples_m8s(Bitu len,const Bit8s * data) { + AddSamples(len,data); } -void MixerChannel::AddSamples_s8s(Bitu len,Bit8s * data) { - AddSamples(len,data); +void MixerChannel::AddSamples_s8s(Bitu len,const Bit8s * data) { + AddSamples(len,data); } -void MixerChannel::AddSamples_m16(Bitu len,Bit16s * data) { - AddSamples(len,data); +void MixerChannel::AddSamples_m16(Bitu len,const Bit16s * data) { + AddSamples(len,data); } -void MixerChannel::AddSamples_s16(Bitu len,Bit16s * data) { - AddSamples(len,data); +void MixerChannel::AddSamples_s16(Bitu len,const Bit16s * data) { + AddSamples(len,data); } -void MixerChannel::AddSamples_m16u(Bitu len,Bit16u * data) { - AddSamples(len,data); +void MixerChannel::AddSamples_m16u(Bitu len,const Bit16u * data) { + AddSamples(len,data); } -void MixerChannel::AddSamples_s16u(Bitu len,Bit16u * data) { - AddSamples(len,data); +void MixerChannel::AddSamples_s16u(Bitu len,const Bit16u * data) { + AddSamples(len,data); +} +void MixerChannel::AddSamples_m32(Bitu len,const Bit32s * data) { + AddSamples(len,data); +} +void MixerChannel::AddSamples_s32(Bitu len,const Bit32s * data) { + AddSamples(len,data); } void MixerChannel::FillUp(void) { From 8288b0cd344204f06f193370bbf6a7160118e1c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 18 Mar 2009 18:08:16 +0000 Subject: [PATCH 3235/4131] fix linecompare update in certain cases (thanks to ripsaw for pointing this out, fixes inner worlds regression) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3323 --- src/hardware/vga_crtc.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 5b6c40d0..561185d3 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_crtc.cpp,v 1.33 2008-06-03 18:35:32 c2woody Exp $ */ +/* $Id: vga_crtc.cpp,v 1.34 2009-03-18 18:08:16 c2woody Exp $ */ #include #include "dosbox.h" @@ -141,19 +141,22 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { if (IS_VGA_ARCH) vga.config.line_compare=(vga.config.line_compare & 0x5ff)|(val&0x40)<<3; - if(IS_VGA_ARCH && (svgaCard==SVGA_None) && (vga.mode==M_EGA || vga.mode==M_VGA)) { + if (IS_VGA_ARCH && (svgaCard==SVGA_None) && (vga.mode==M_EGA || vga.mode==M_VGA)) { // in vgaonly mode we take special care of line repeats (excluding CGA modes) if ((vga.crtc.maximum_scan_line ^ val) & 0x20) { crtc(maximum_scan_line)=val; VGA_StartResize(); + } else { + crtc(maximum_scan_line)=val; } - crtc(maximum_scan_line)=val; vga.draw.address_line_total = (val &0x1F) + 1; - if(val&0x80) vga.draw.address_line_total*=2; + if (val&0x80) vga.draw.address_line_total*=2; } else { if ((vga.crtc.maximum_scan_line ^ val) & 0xbf) { crtc(maximum_scan_line)=val; VGA_StartResize(); + } else { + crtc(maximum_scan_line)=val; } } /* From ce5ef7a25449a1d0910d70fc8ce8136c2eadfb21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 19 Mar 2009 20:45:42 +0000 Subject: [PATCH 3236/4131] fix 16bit mixer handling on bigendian machines (sb16 hdma, cdda for cd images), also see sf patches #1284246 and #1989569 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3324 --- include/mixer.h | 12 ++++- src/dos/cdrom_image.cpp | 8 +++- src/hardware/mixer.cpp | 94 ++++++++++++++++++++++++++++++--------- src/hardware/sblaster.cpp | 14 +++++- 4 files changed, 102 insertions(+), 26 deletions(-) diff --git a/include/mixer.h b/include/mixer.h index b8e75926..a614f524 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: mixer.h,v 1.17 2009-03-19 20:45:42 c2woody Exp $ */ + #ifndef DOSBOX_MIXER_H #define DOSBOX_MIXER_H @@ -50,7 +52,7 @@ public: void SetFreq(Bitu _freq); void Mix(Bitu _needed); void AddSilence(void); //Fill up until needed - template + template void AddSamples(Bitu len, const Type* data); void AddSamples_m8(Bitu len, const Bit8u * data); void AddSamples_s8(Bitu len, const Bit8u * data); @@ -62,6 +64,12 @@ public: 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); diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 3b5983d7..32bb39a1 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.23 2008-10-05 14:44:52 qbix79 Exp $ */ +/* $Id: cdrom_image.cpp,v 1.24 2009-03-19 20:45:42 c2woody Exp $ */ #include #include @@ -327,7 +327,11 @@ void CDROM_Interface_Image::CDAudioCallBack(Bitu len) } } SDL_mutexV(player.mutex); +#if defined(WORDS_BIGENDIAN) + player.channel->AddSamples_s16_nonnative(len/4,(Bit16s *)player.buffer); +#else player.channel->AddSamples_s16(len/4,(Bit16s *)player.buffer); +#endif memmove(player.buffer, &player.buffer[len], player.bufLen - len); player.bufLen -= len; } diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 84d1a977..fc8a4d98 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.49 2009-03-16 18:33:59 harekiet Exp $ */ +/* $Id: mixer.cpp,v 1.50 2009-03-19 20:45:42 c2woody Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -174,7 +174,7 @@ void MixerChannel::AddSilence(void) { } } -template +template INLINE void MixerChannel::AddSamples(Bitu len, const Type* data) { Bits diff[2]; Bitu mixpos=mixer.pos+done; @@ -182,7 +182,7 @@ INLINE void MixerChannel::AddSamples(Bitu len, const Type* data) { Bitu pos=0;Bitu new_pos; goto thestart; - while (1) { + for (;;) { new_pos=freq_index >> MIXER_SHIFT; if (pos(len,data); + AddSamples(len,data); } void MixerChannel::AddSamples_s8(Bitu len,const Bit8u * data) { - AddSamples(len,data); + AddSamples(len,data); } void MixerChannel::AddSamples_m8s(Bitu len,const Bit8s * data) { - AddSamples(len,data); + AddSamples(len,data); } void MixerChannel::AddSamples_s8s(Bitu len,const Bit8s * data) { - AddSamples(len,data); + AddSamples(len,data); } void MixerChannel::AddSamples_m16(Bitu len,const Bit16s * data) { - AddSamples(len,data); + AddSamples(len,data); } void MixerChannel::AddSamples_s16(Bitu len,const Bit16s * data) { - AddSamples(len,data); + AddSamples(len,data); } void MixerChannel::AddSamples_m16u(Bitu len,const Bit16u * data) { - AddSamples(len,data); + AddSamples(len,data); } void MixerChannel::AddSamples_s16u(Bitu len,const Bit16u * data) { - AddSamples(len,data); + AddSamples(len,data); } void MixerChannel::AddSamples_m32(Bitu len,const Bit32s * data) { - AddSamples(len,data); + AddSamples(len,data); } void MixerChannel::AddSamples_s32(Bitu len,const Bit32s * data) { - AddSamples(len,data); + AddSamples(len,data); +} +void MixerChannel::AddSamples_m16_nonnative(Bitu len,const Bit16s * data) { + AddSamples(len,data); +} +void MixerChannel::AddSamples_s16_nonnative(Bitu len,const Bit16s * data) { + AddSamples(len,data); +} +void MixerChannel::AddSamples_m16u_nonnative(Bitu len,const Bit16u * data) { + AddSamples(len,data); +} +void MixerChannel::AddSamples_s16u_nonnative(Bitu len,const Bit16u * data) { + AddSamples(len,data); +} +void MixerChannel::AddSamples_m32_nonnative(Bitu len,const Bit32s * data) { + AddSamples(len,data); +} +void MixerChannel::AddSamples_s32_nonnative(Bitu len,const Bit32s * data) { + AddSamples(len,data); } void MixerChannel::FillUp(void) { diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index dd72b40f..2df1273d 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.71 2009-02-01 11:07:11 qbix79 Exp $ */ +/* $Id: sblaster.cpp,v 1.72 2009-03-19 20:45:42 c2woody Exp $ */ #include #include @@ -461,8 +461,13 @@ static void GenerateDMASound(Bitu size) { read=sb.dma.chan->Read(size,(Bit8u *)&sb.dma.buf.b16[sb.dma.remain_size]) >> (sb.dma.mode==DSP_DMA_16_ALIASED ? 1:0); Bitu total=read+sb.dma.remain_size; +#if defined(WORDS_BIGENDIAN) + if (sb.dma.sign) sb.chan->AddSamples_s16_nonnative(total>>1,sb.dma.buf.b16); + else sb.chan->AddSamples_s16u_nonnative(total>>1,(Bit16u *)sb.dma.buf.b16); +#else if (sb.dma.sign) sb.chan->AddSamples_s16(total>>1,sb.dma.buf.b16); else sb.chan->AddSamples_s16u(total>>1,(Bit16u *)sb.dma.buf.b16); +#endif if (total&1) { sb.dma.remain_size=1; sb.dma.buf.b16[0]=sb.dma.buf.b16[total-1]; @@ -470,8 +475,13 @@ static void GenerateDMASound(Bitu size) { } else { read=sb.dma.chan->Read(size,(Bit8u *)sb.dma.buf.b16) >> (sb.dma.mode==DSP_DMA_16_ALIASED ? 1:0); +#if defined(WORDS_BIGENDIAN) + if (sb.dma.sign) sb.chan->AddSamples_m16_nonnative(read,sb.dma.buf.b16); + else sb.chan->AddSamples_m16u_nonnative(read,(Bit16u *)sb.dma.buf.b16); +#else if (sb.dma.sign) sb.chan->AddSamples_m16(read,sb.dma.buf.b16); else sb.chan->AddSamples_m16u(read,(Bit16u *)sb.dma.buf.b16); +#endif } //restore buffer length value to byte size in aliased mode if (sb.dma.mode==DSP_DMA_16_ALIASED) read=read<<1; From 981fd5e269b5a7957ceea7e57fcb67592422077c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 22 Mar 2009 21:04:41 +0000 Subject: [PATCH 3237/4131] fix memory clearing after allocating vga emulation memory when non-paragraph aligned memory has been returned Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3325 --- src/hardware/vga_memory.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 45f8b0eb..605593a1 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_memory.cpp,v 1.51 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: vga_memory.cpp,v 1.52 2009-03-22 21:04:41 c2woody Exp $ */ #include #include @@ -717,11 +717,11 @@ public: VGA_Empty_Handler() { flags=PFLAG_NOCODE; } - Bitu readb(PhysPt addr) { + Bitu readb(PhysPt /*addr*/) { // LOG(LOG_VGA, LOG_NORMAL ) ( "Read from empty memory space at %x", addr ); return 0xff; } - void writeb(PhysPt addr,Bitu val) { + void writeb(PhysPt /*addr*/,Bitu /*val*/) { // LOG(LOG_VGA, LOG_NORMAL ) ( "Write %x to empty memory space at %x", val, addr ); } }; @@ -900,7 +900,7 @@ void VGA_StartUpdateLFB(void) { MEM_SetLFB(vga.s3.la_window << 4 ,vga.vmemsize/4096, vga.lfb.handler, &vgaph.mmio); } -static void VGA_Memory_ShutDown(Section * sec) { +static void VGA_Memory_ShutDown(Section * /*sec*/) { delete[] vga.mem.linear_orgptr; delete[] vga.fastmem_orgptr; #ifdef VGA_KEEP_CHANGES @@ -916,8 +916,8 @@ void VGA_SetupMemory(Section* sec) { // Keep lower limit at 512k if (vga_allocsize<512*1024) vga_allocsize=512*1024; // We reserve extra 2K for one scan line - vga_allocsize+=2048+16; - vga.mem.linear_orgptr = new Bit8u[vga_allocsize]; + vga_allocsize+=2048; + vga.mem.linear_orgptr = new Bit8u[vga_allocsize+16]; vga.mem.linear=(Bit8u*)(((Bitu)vga.mem.linear_orgptr + 16-1) & ~(16-1)); memset(vga.mem.linear,0,vga_allocsize); From d8266a6a417bdef04407d42aaf93045e021fc554 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 23 Mar 2009 10:55:36 +0000 Subject: [PATCH 3238/4131] revise switchToLongcmd a bit. allow execution of mount/imgmount from menus and such.(beta3) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3326 --- include/shell.h | 5 +---- src/misc/programs.cpp | 24 +++++++++++++++++------- src/shell/shell.cpp | 9 +-------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/include/shell.h b/include/shell.h index 689ad1d2..e5dc80a1 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.25 2009-01-19 19:55:03 qbix79 Exp $ */ +/* $Id: shell.h,v 1.26 2009-03-23 10:55:35 qbix79 Exp $ */ #ifndef DOSBOX_SHELL_H #define DOSBOX_SHELL_H @@ -40,9 +40,6 @@ extern Bitu call_shellstop; * by "external" programs. (config) */ extern Program * first_shell; -/* command_slashc indicates that the next commands are being run from command /c. Remove parameters for internal .COM files */ -extern bool command_slashc; - class DOS_Shell; class BatchFile { diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 3176e911..58736618 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.35 2009-02-01 14:19:20 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.36 2009-03-23 10:55:36 qbix79 Exp $ */ #include #include @@ -109,12 +109,22 @@ Program::Program() { extern std::string full_arguments; void Program::ChangeToLongCmd() { - CommandLine* temp = 0; - //If command_slashc => then don't pass any parameters to the internal .COM files - if(command_slashc) temp = new CommandLine(cmd->GetFileName(),""); - else temp = new CommandLine(cmd->GetFileName(),full_arguments.c_str()); - delete cmd; - cmd = temp; + /* + * Get arguments directly from the shell instead of the psp. + * this is done in securemode: (as then the arguments to mount and friends + * can only be given on the shell ( so no int 21 4b) + * Securemode part is disabled as each of the internal command has already + * protection for it. (and it breaks games like cdman) + * it is also done for long arguments to as it is convient (as the total commandline can be longer then 127 characters. + * imgmount with lot's of parameters + * Length of arguments can be ~120. but switch when above 100 to be sure + */ + + if(/*control->SecureMode() ||*/ cmd->Get_arglength() > 100) { + CommandLine* temp = new CommandLine(cmd->GetFileName(),full_arguments.c_str()); + delete cmd; + cmd = temp; + } full_arguments.assign(""); //Clear so it gets even more save } diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index efd621f5..ae9d40a3 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.97 2009-02-01 14:07:05 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.98 2009-03-23 10:55:36 qbix79 Exp $ */ #include #include @@ -278,22 +278,15 @@ void DOS_Shell::RunInternal(void) return; } -bool command_slashc = false; - void DOS_Shell::Run(void) { char input_line[CMD_MAXLINE] = {0}; std::string line; if (cmd->FindStringRemain("/C",line)) { - //command_slashc indicates that the following commands are run with command /c. Forbid parameters to mount. - //command_allready_set prevents against command /c "command /c command" - bool command_allready_set = command_slashc; - command_slashc = true; strcpy(input_line,line.c_str()); DOS_Shell temp; temp.echo = echo; temp.ParseLine(input_line); //for *.exe *.com |*.bat creates the bf needed by runinternal; temp.RunInternal(); // exits when no bf is found. - if(!command_allready_set) command_slashc = false; return; } /* Start a normal shell and check for a first command init */ From cb09b0a3ac7ec88e1a3500662b0f267d9a978a4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 23 Mar 2009 21:58:05 +0000 Subject: [PATCH 3239/4131] fix fcb write function with odd behaviour for zero-block writing Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3327 --- src/dos/dos_files.cpp | 45 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 4d80ab59..45903976 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.106 2009-03-14 16:10:00 c2woody Exp $ */ +/* $Id: dos_files.cpp,v 1.107 2009-03-23 21:58:05 c2woody Exp $ */ #include #include @@ -961,8 +961,7 @@ Bit8u DOS_FCBRead(Bit16u seg,Bit16u offset,Bit16u recno) { return FCB_READ_PARTIAL; } -Bit8u DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u recno) -{ +Bit8u DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u recno) { DOS_FCB fcb(seg,offset); Bit8u fhandle,cur_rec;Bit16u cur_block,rec_size; fcb.GetSeqData(fhandle,rec_size); @@ -992,6 +991,34 @@ Bit8u DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u recno) return FCB_SUCCESS; } +Bit8u DOS_FCBIncreaseSize(Bit16u seg,Bit16u offset) { + DOS_FCB fcb(seg,offset); + Bit8u fhandle,cur_rec;Bit16u cur_block,rec_size; + fcb.GetSeqData(fhandle,rec_size); + fcb.GetRecord(cur_block,cur_rec); + Bit32u pos=((cur_block*128)+cur_rec)*rec_size; + if (!DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET)) return FCB_ERR_WRITE; + Bit16u towrite=0; + if (!DOS_WriteFile(fhandle,dos_copybuf,&towrite)) return FCB_ERR_WRITE; + Bit32u size;Bit16u date,time; + fcb.GetSizeDateTime(size,date,time); + if (pos+towrite>size) size=pos+towrite; + //time doesn't keep track of endofday + date = DOS_PackDate(dos.date.year,dos.date.month,dos.date.day); + Bit32u ticks = mem_readd(BIOS_TIMER); + Bit32u seconds = (ticks*10)/182; + Bit16u hour = (Bit16u)(seconds/3600); + Bit16u min = (Bit16u)((seconds % 3600)/60); + Bit16u sec = (Bit16u)(seconds % 60); + time = DOS_PackTime(hour,min,sec); + Bit8u temp=RealHandle(fhandle); + Files[temp]->time=time; + Files[temp]->date=date; + fcb.SetSizeDateTime(size,date,time); + fcb.SetRecord(cur_block,cur_rec); + return FCB_SUCCESS; +} + Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { /* if restore is true :random read else random blok read. * random read updates old block and old record to reflect the random data @@ -1034,10 +1061,14 @@ Bit8u DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { fcb.GetRandom(random); fcb.SetRecord((Bit16u)(random / 128),(Bit8u)(random & 127)); if (restore) fcb.GetRecord(old_block,old_rec); - /* Write records */ - for (int i=0; i0) { + /* Write records */ + for (int i=0; i Date: Tue, 24 Mar 2009 17:07:30 +0000 Subject: [PATCH 3240/4131] add some rarely used ioctl subfunctions, improve error checking a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3328 --- src/dos/dos_ioctl.cpp | 51 ++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 5b402383..342b113e 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.33 2008-09-07 10:55:14 c2woody Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.34 2009-03-24 17:07:30 c2woody Exp $ */ #include #include "dosbox.h" @@ -27,8 +27,8 @@ bool DOS_IOCTL(void) { Bitu handle=0;Bit8u drive=0; - /* calls 0-7,10,12,16 use a file handle */ - if ((reg_al<8) || (reg_al==0x0a) || (reg_al==0x0c) || (reg_al==0x10)) { + /* calls 0-4,6,7,10,12,16 use a file handle */ + if ((reg_al<4) || (reg_al==0x06) || (reg_al==0x07) || (reg_al==0x0a) || (reg_al==0x0c) || (reg_al==0x10)) { handle=RealHandle(reg_bx); if (handle>=DOS_FILES) { DOS_SetError(DOSERR_INVALID_HANDLE); @@ -38,12 +38,18 @@ bool DOS_IOCTL(void) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; } - } else { /* the others use a diskdrive */ - drive=reg_bl;if (!drive) drive=dos.current_drive;else drive--; - if( !(( drive < DOS_DRIVES ) && Drives[drive]) ) { - DOS_SetError(DOSERR_INVALID_DRIVE); - return false; + } else if (reg_al<0x12) { /* those use a diskdrive except 0x0b */ + if (reg_al!=0x0b) { + drive=reg_bl;if (!drive) drive=dos.current_drive;else drive--; + if( !(( drive < DOS_DRIVES ) && Drives[drive]) ) { + DOS_SetError(DOSERR_INVALID_DRIVE); + return false; + } } + } else { + LOG(LOG_DOSMISC,LOG_ERROR)("DOS:IOCTL Call %2X unhandled",reg_al); + DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); + return false; } switch(reg_al) { case 0x00: /* Get Device Information */ @@ -60,6 +66,19 @@ bool DOS_IOCTL(void) { } reg_ax=reg_dx; //Destroyed officially return true; + case 0x01: /* Set Device Information */ + if (reg_dh != 0) { + DOS_SetError(DOSERR_DATA_INVALID); + return false; + } else { + if (Files[handle]->GetInformation() & 0x8000) { //Check for device + reg_al=(Bit8u)(Files[handle]->GetInformation() & 0xff); + } else { + DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); + return false; + } + } + return true; case 0x02: /* Read from Device Control Channel */ if (Files[handle]->GetInformation() & 0xc000) { /* is character device with IOCTL support */ @@ -125,6 +144,12 @@ bool DOS_IOCTL(void) { } reg_ax=0x300; return true; + case 0x0B: /* Set sharing retry count */ + if (reg_dx==0) { + DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); + return false; + } + return true; case 0x0D: /* Generic block device request */ { if (Drives[drive]->isRemovable()) { @@ -187,10 +212,10 @@ bool DOS_IOCTL(void) { default: LOG(LOG_DOSMISC,LOG_ERROR)("DOS:IOCTL Call %2X unhandled",reg_al); DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); - return false; - }; + break; + } return false; -}; +} bool DOS_GetSTDINStatus(void) { @@ -198,4 +223,4 @@ bool DOS_GetSTDINStatus(void) { if (handle==0xFF) return false; if (Files[handle] && (Files[handle]->GetInformation() & 64)) return false; return true; -}; +} From efe69a5b43a3d2e32e9f91fe7d1a79d63bd7f036 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 25 Mar 2009 21:12:23 +0000 Subject: [PATCH 3241/4131] add part of etillite's layout patch (sf patch #2528951) which adds extended layout support for kcl files; disable/change some untested layouts in the automatic detection Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3329 --- src/dos/dos_keyboard_layout.cpp | 40 +++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 704f80ac..af61708a 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_keyboard_layout.cpp,v 1.19 2009-02-01 14:24:36 qbix79 Exp $ */ +/* $Id: dos_keyboard_layout.cpp,v 1.20 2009-03-25 21:12:23 c2woody Exp $ */ #include "dosbox.h" #include "bios.h" @@ -172,8 +172,11 @@ static Bit32u read_kcl_file(const char* kcl_file_name, const char* layout_id, bo Bit8u data_len=rbuf[2]; char lng_codes[258]; + fseek(tempfile, -2, SEEK_CUR); // get all language codes for this layout for (Bitu i=0; i Date: Thu, 26 Mar 2009 21:38:35 +0000 Subject: [PATCH 3242/4131] update some FAQ entries, minor readme additions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3330 --- README | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/README b/README index 1be74ef5..b9f269e1 100644 --- a/README +++ b/README @@ -161,6 +161,9 @@ A: Be sure that the sound is correctly configured in the game. This might be If you still don't get any sound set the core to normal and use some lower fixed cycles value (like cycles=2000). Also assure that your host operating sound does provide sound. + In certain cases it might be useful to use a different emulated sound device + like a soundblaster pro (sbtype=sbpro1 in the DOSBox configuration file) or + the gravis ultrasound (gus=true). Q: The sound stutters or sounds stretched/weird. @@ -173,24 +176,27 @@ A: You're using too much CPU power to keep DOSBox running at the current speed. Q: I can't type \ or : in DOSBox. -A: This is a known problem. It only occurs if your keyboard layout isn't US. +A: This can happen in various cases, like your host keyboard layout does not + have a matching DOS layout representation (or it was not correctly detected), + or the key mapping is wrong. Some possible fixes: - 1. Switch the keyboard layout of your operating system. - 2. Use / instead. - 3. Open the DOSBox configuration file and change usescancodes=false - to usescancodes=true. - 4. Add the commands you want to execute to the [autoexec]-section + 1. Use / instead, or ALT-58 for : and ALT-92 for \. + 2. Change the DOS keyboard layout (see Section 7: Keyboard Layout). + 3. Add the commands you want to execute to the [autoexec]-section of the DOSBox configuration file. - 5. Change the DOS keyboard layout (see Section 7: Keyboard Layout). - 6. Use ALT-58 for : and ALT-92 for \. - 7. For \ try the keys around "enter". For ":" try shift and the keys - between "enter" and "l" (US keyboard layout). + 4. Open the DOSBox configuration file and change the usescancodes entry. + 5. Switch the keyboard layout of your operating system. + + Note that if the host layout can not be identified, or keyboardlayout is set + to none in the DOSBox configuration file, the standard US layout is used. + In this configuration try the keys around "enter" for the key \ (backslash), + and for the key : (colon) use shift and the keys between "enter" and "l". Q: The keyboard lags. -A: Lower the priority setting in the DOSBox configuration file - like set "priority=normal,normal". You might also want to - try lowering the cycles. +A: Lower the priority setting in the DOSBox configuration file, for example + set "priority=normal,normal". You might also want to try lowering the cycles + (use a fixed cycle count to start with, like cycles=10000). Q: The cursor always moves into one direction! @@ -292,6 +298,7 @@ dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] [-lang languagefile] [-machine machinetype] [-noconsole] [-startmapper] [-noautoexec] [-securemode] [-scaler scaler | -forcescaler scaler] + [-version] dosbox -version @@ -322,9 +329,13 @@ dosbox -version -machine machinetype Setup DOSBox to emulate a specific type of machine. Valid choices are: - hercules, cga, pcjr, tandy, vga (default) as well as the svga chipsets - listed in the help of the DOSBox configuration file. The machinetype - affects both the videocard and the available soundcards. + hercules, cga, pcjr, tandy, svga_s3 (default) as well as the additional + svga chipsets listed in the help of the DOSBox configuration file. + svga_s3 enables vesa emulation as well. + For some special vga effects the machinetype vgaonly can be used, + note that this disables svga capabilites and might be (considerably) + slower due to the much higher emulation precision. + The machinetype affects both the videocard and the available soundcards. -noconsole (Windows Only) Start DOSBox without showing the console window. Output will @@ -838,7 +849,7 @@ For more information use the /? command line switch with the programs. ================ ALT-ENTER Switch to full screen and back. -ALT-PAUSE Pause emulation. +ALT-PAUSE Pause emulation (hit ALT-PAUSE again to continue). CTRL-F1 Start the keymapper. CTRL-F4 Change between mounted disk-images. Update directory cache for all drives! CTRL-ALT-F5 Start/Stop creating a movie of the screen. (avi video capturing) From 6fee7ccb03a15ee7f0917010de05085a99fa3ca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 27 Mar 2009 18:10:35 +0000 Subject: [PATCH 3243/4131] immediately check for irq line activation when popf enables the interrupt flag (fixes star quest 1, thanks to ripsaw for finding this) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3331 --- src/cpu/core_dyn_x86/decoder.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 56ebfb52..16b7e129 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: decoder.h,v 1.55 2008-05-18 13:11:14 c2woody Exp $ */ +/* $Id: decoder.h,v 1.56 2009-03-27 18:10:35 c2woody Exp $ */ #define X86_DYNFPU_DH_ENABLED #define X86_INLINED_MEMACCESS @@ -2258,6 +2258,7 @@ restart_prefix: dyn_check_bool_exception(DREG(TMPB)); dyn_flags_host_to_gen(); gen_releasereg(DREG(TMPB)); + dyn_check_irqrequest(); break; /* MOV AL,direct addresses */ case 0xa0: From b2b0fa448d0d5ea4778fefa13a528f9dee695395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 28 Mar 2009 12:20:52 +0000 Subject: [PATCH 3244/4131] update pit counter in mode2 on the next timer event rather than immediately (thanks to hal for this one, fixes worms1 cutscenes) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3332 --- src/hardware/timer.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 999a39d0..4987ffc7 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.47 2008-07-14 19:30:29 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.48 2009-03-28 12:20:52 c2woody Exp $ */ #include #include "dosbox.h" @@ -55,6 +55,7 @@ struct PIT_Block { bool new_mode; bool counterstatus_set; bool counting; + bool update_count; }; static PIT_Block pit[3]; @@ -69,6 +70,12 @@ static void PIT0_Event(Bitu /*val*/) { PIC_ActivateIRQ(0); if (pit[0].mode != 0) { pit[0].start += pit[0].delay; + + if (GCC_UNLIKELY(pit[0].update_count)) { + pit[0].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[0].cntr)); + pit[0].update_count=false; + } + double error = pit[0].start - PIC_FullIndex(); PIC_AddEvent(PIT0_Event,(float)(pit[0].delay + error)); } @@ -212,8 +219,17 @@ static void write_latch(Bitu port,Bitu val,Bitu /*iolen*/) { if (p->bcd == false) p->cntr = 0x10000; else p->cntr=9999; } else p->cntr = p->write_latch; + + if ((!p->new_mode) && (p->mode == 2) && (counter == 0)) { + // In mode 2 writing another value has no direct effect on the count + // until the old one has run out. This might apply to other modes too. + // This is not fixed for PIT2 yet!! + p->update_count=true; + return; + } p->start=PIC_FullIndex(); p->delay=(1000.0f/((float)PIT_TICK_RATE/(float)p->cntr)); + switch (counter) { case 0x00: /* Timer hooked to IRQ 0 */ if (p->new_mode || p->mode == 0 ) { @@ -297,6 +313,7 @@ static void write_p43(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { pit[latch].counterstatus_set=false; latched_timerstatus_locked=false; } + pit[latch].update_count = false; pit[latch].counting = false; pit[latch].read_state = (val >> 4) & 0x03; pit[latch].write_state = (val >> 4) & 0x03; @@ -404,6 +421,7 @@ public: pit[0].bcd = false; pit[0].go_read_latch = true; pit[0].counterstatus_set = false; + pit[0].update_count = false; pit[1].bcd = false; pit[1].write_state = 1; From d3045e71a6f5b27a56ef21e86fc5f57118f04b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 29 Mar 2009 09:34:18 +0000 Subject: [PATCH 3245/4131] use ioctl audio playing routines when possible, otherwise audio extraction (vista and the likes) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3333 --- src/dos/dos_programs.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index c8795282..06697d7c 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.91 2009-02-01 14:24:36 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.92 2009-03-29 09:34:18 c2woody Exp $ */ #include "dosbox.h" #include @@ -253,7 +253,7 @@ public: MSCDEX_SetCDInterface(CDROM_USE_SDL, num); } else { #if defined (WIN32) -/* // Check OS + // Check OS OSVERSIONINFO osi; osi.dwOSVersionInfoSize = sizeof(osi); GetVersionEx(&osi); @@ -262,8 +262,7 @@ public: MSCDEX_SetCDInterface(CDROM_USE_IOCTL_DX, num); } else { MSCDEX_SetCDInterface(CDROM_USE_IOCTL_DIO, num); - } */ - MSCDEX_SetCDInterface(CDROM_USE_IOCTL_DX, num); + } #else MSCDEX_SetCDInterface(CDROM_USE_IOCTL_DIO, num); #endif From d8c2179a83ea971cc34ef6ff3df2b514ed1ae20c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 29 Mar 2009 17:32:20 +0000 Subject: [PATCH 3246/4131] Fix some warning and compilation on VS2003. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3334 --- src/cpu/core_dyn_x86/decoder.h | 12 ++++++------ src/cpu/core_dyn_x86/string.h | 2 +- src/cpu/core_dynrec/decoder_basic.h | 18 +++++++++--------- src/cpu/core_full/support.h | 10 +++++----- src/cpu/core_normal/string.h | 2 +- src/cpu/core_normal/table_ea.h | 2 +- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 16b7e129..0d91df16 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: decoder.h,v 1.56 2009-03-27 18:10:35 c2woody Exp $ */ +/* $Id: decoder.h,v 1.57 2009-03-29 17:32:20 qbix79 Exp $ */ #define X86_DYNFPU_DH_ENABLED #define X86_INLINED_MEMACCESS @@ -277,7 +277,7 @@ static INLINE void dyn_set_eip_last(void) { } -enum save_info_type {exception, cycle_check, normal, fpu_restore}; +enum save_info_type {db_exception, cycle_check, normal, fpu_restore}; static struct { @@ -309,7 +309,7 @@ static void dyn_check_bool_exception(DynReg * check) { save_info[used_save_info].cycles=decode.cycles; save_info[used_save_info].eip_change=decode.op_start-decode.code_start; if (!cpu.code.big) save_info[used_save_info].eip_change&=0xffff; - save_info[used_save_info].type=exception; + save_info[used_save_info].type=db_exception; used_save_info++; } @@ -321,7 +321,7 @@ static void dyn_check_bool_exception_al(void) { save_info[used_save_info].cycles=decode.cycles; save_info[used_save_info].eip_change=decode.op_start-decode.code_start; if (!cpu.code.big) save_info[used_save_info].eip_change&=0xffff; - save_info[used_save_info].type=exception; + save_info[used_save_info].type=db_exception; used_save_info++; } @@ -348,7 +348,7 @@ static void dyn_check_bool_exception_ne(void) { save_info[used_save_info].cycles=decode.cycles; save_info[used_save_info].eip_change=decode.op_start-decode.code_start; if (!cpu.code.big) save_info[used_save_info].eip_change&=0xffff; - save_info[used_save_info].type=exception; + save_info[used_save_info].type=db_exception; used_save_info++; } @@ -356,7 +356,7 @@ static void dyn_fill_blocks(void) { for (Bitu sct=0; sct> 3) &7] << (sib >> 6); return base; -}; +} static PhysPt EA_32_00_n(void) { return BaseDS+reg_eax; } static PhysPt EA_32_01_n(void) { return BaseDS+reg_ecx; } From 03f524f5a3f54c7b3327f385afbfb112bc81e7c8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 31 Mar 2009 18:15:10 +0000 Subject: [PATCH 3247/4131] Fix adlib timer overflow to be reset when timer is masked Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3335 --- src/hardware/adlib.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index bd58b7e9..8576be18 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: adlib.cpp,v 1.32 2009-02-03 19:20:30 harekiet Exp $ */ +/* $Id: adlib.cpp,v 1.33 2009-03-31 18:15:10 harekiet Exp $ */ #include #include @@ -416,12 +416,17 @@ bool Chip::Write( Bit32u reg, Bit8u val ) { timer[0].Stop( ); } timer[0].masked = (val & 0x40) > 0; + if ( timer[0].masked ) + timer[0].overflow = false; if ( val & 0x2 ) { timer[1].Start( time, 320 ); } else { timer[1].Stop( ); } timer[1].masked = (val & 0x20) > 0; + if ( timer[1].masked ) + timer[1].overflow = false; + } return true; } @@ -474,7 +479,7 @@ void Module::DualWrite( Bit8u index, Bit8u reg, Bit8u val ) { val &= 7; val |= index ? 0xA0 : 0x50; } - Bit32u fullReg = reg + index ? 0x100 : 0; + Bit32u fullReg = reg + (index ? 0x100 : 0); handler->WriteReg( fullReg, val ); CacheWrite( fullReg, val ); } From b7d4ecdb4968988b666e2aee2a12901bf54290da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 1 Apr 2009 18:30:41 +0000 Subject: [PATCH 3248/4131] display auto-loaded dos keyboard layout information in console window Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3336 --- src/dos/dos_keyboard_layout.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index af61708a..1d828870 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_keyboard_layout.cpp,v 1.20 2009-03-25 21:12:23 c2woody Exp $ */ +/* $Id: dos_keyboard_layout.cpp,v 1.21 2009-04-01 18:30:41 c2woody Exp $ */ #include "dosbox.h" #include "bios.h" @@ -83,6 +83,7 @@ public: Bitu switch_keyboard_layout(const char* new_layout, keyboard_layout* &created_layout); void switch_foreign_layout(); const char* get_layout_name(); + const char* main_language_code(); private: @@ -1017,6 +1018,13 @@ const char* keyboard_layout::get_layout_name() { return NULL; } +const char* keyboard_layout::main_language_code() { + if (language_codes) { + return language_codes[0]; + } + return NULL; +} + static keyboard_layout* loaded_layout=NULL; @@ -1244,10 +1252,18 @@ public: loaded_layout->read_codepage_file("auto", req_codepage); } +/* if (strncmp(layoutname,"auto",4) && strncmp(layoutname,"none",4)) { + LOG_MSG("Loading DOS keyboard layout %s ...",layoutname); + } */ if (loaded_layout->read_keyboard_file(layoutname, dos.loaded_codepage)) { if (strncmp(layoutname,"auto",4)) { LOG_MSG("Error loading keyboard layout %s",layoutname); } + } else { + const char* lcode = loaded_layout->main_language_code(); + if (lcode) { + LOG_MSG("DOS keyboard layout loaded with main language code %s for layout %s",lcode,layoutname); + } } } From 0080ef7e6aaf838a5773879962a545056b9568fc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 2 Apr 2009 19:08:26 +0000 Subject: [PATCH 3249/4131] warning fixes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3337 --- src/shell/shell_batch.cpp | 5 ++--- src/shell/shell_cmds.cpp | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index b5757684..969b5efd 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.32 2009-01-19 19:55:03 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.33 2009-04-02 19:08:26 qbix79 Exp $ */ #include #include @@ -145,7 +145,6 @@ bool BatchFile::Goto(char * where) { E_Exit("SHELL:Goto Can't open BatchFile %s",cmd->GetFileName()); } - Bit32u pos=0; char cmd_buffer[CMD_MAXLINE]; char * cmd_write; @@ -180,7 +179,7 @@ again: this->location = 0; DOS_SeekFile(file_handle,&(this->location),DOS_SEEK_CUR); DOS_CloseFile(file_handle); - return true; + return true; } } diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 94cebf73..6f27f541 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.89 2009-02-15 10:45:01 c2woody Exp $ */ +/* $Id: shell_cmds.cpp,v 1.90 2009-04-02 19:08:26 qbix79 Exp $ */ #include "dosbox.h" #include "shell.h" @@ -487,8 +487,8 @@ void DOS_Shell::CMD_DIR(char * args) { if (optW) { WriteOut("[%s]",name); size_t namelen = strlen(name); - if ((namelen>=0) && (namelen<=14)) { - for (Bitu i=14-(Bitu)namelen;i>0;i--) WriteOut(" "); + if (namelen <= 14) { + for (size_t i=14-namelen;i>0;i--) WriteOut(" "); } } else { WriteOut("%-8s %-3s %-16s %02d-%02d-%04d %2d:%02d\n",name,ext,"",day,month,year,hour,minute); From fd2bfad813340081ff4930785888743fa0a26686 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 2 Apr 2009 19:10:44 +0000 Subject: [PATCH 3250/4131] very simple, but effective way to disable the internal mouse driver, so you can load external ones. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3338 --- src/debug/debug.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index e235ecab..d136e535 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.95 2009-02-01 20:25:38 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.96 2009-04-02 19:10:44 qbix79 Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -1867,8 +1867,14 @@ public: void Run(void) { + if(cmd->FindExist("/NOMOUSE",false)) { + real_writed(0,0x33<<2,0); + return; + } + char filename[128]; char args[256]; + cmd->FindCommand(1,temp_line); safe_strncpy(filename,temp_line.c_str(),128); // Read commandline From d20566a44ee91991758c571b6e48c782d280aa08 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 6 Apr 2009 11:23:21 +0000 Subject: [PATCH 3251/4131] Make make dist happy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3339 --- src/hardware/Makefile.am | 2 +- src/hardware/adlib.h | 24 ++++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index 7a9f7bf6..2967ab71 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -2,7 +2,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include SUBDIRS = serialport -EXTRA_DIST = fmopl.c fmopl.h ymf262.h ymf262.c +EXTRA_DIST = fmopl.c fmopl.h ymf262.h ymf262.c adlib.h noinst_LIBRARIES = libhardware.a diff --git a/src/hardware/adlib.h b/src/hardware/adlib.h index b8a0af95..dd029250 100644 --- a/src/hardware/adlib.h +++ b/src/hardware/adlib.h @@ -1,3 +1,23 @@ +/* + * 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: adlib.h,v 1.2 2009-04-06 11:23:21 qbix79 Exp $ */ + #ifndef DOSBOX_ADLIB_H #define DOSBOX_ADLIB_H @@ -67,7 +87,7 @@ struct Chip { typedef enum { MODE_OPL2, MODE_DUALOPL2, - MODE_OPL3, + MODE_OPL3 } Mode; class Handler { @@ -116,6 +136,6 @@ public: }; -}; //Adlib namespace +} //Adlib namespace #endif From 1c92388bfd795cb915f477b78a9fdafca88ed575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 10 Apr 2009 09:53:04 +0000 Subject: [PATCH 3252/4131] use sensible counter latch value for initialization of timer2 (fixes startrek sf academy demo) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3340 --- src/hardware/timer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 4987ffc7..f94e43c2 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.48 2009-03-28 12:20:52 c2woody Exp $ */ +/* $Id: timer.cpp,v 1.49 2009-04-10 09:53:04 c2woody Exp $ */ #include #include "dosbox.h" @@ -432,7 +432,7 @@ public: pit[1].write_state = 3; pit[1].counterstatus_set = false; - pit[2].read_latch=0; /* MadTv1 */ + pit[2].read_latch=1320; /* MadTv1 */ pit[2].write_state = 3; /* Chuck Yeager */ pit[2].read_state = 3; pit[2].mode=3; From f95d934328e87aee0d62882f13d88d0bf1eb1ea0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 11 Apr 2009 07:58:39 +0000 Subject: [PATCH 3253/4131] minor stuff Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3341 --- src/ints/int10.cpp | 6 +++--- src/ints/int10.h | 6 +++--- src/ints/int10_misc.cpp | 6 +++--- src/ints/int10_vesa.cpp | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 0f51dcf6..1e25c925 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.cpp,v 1.54 2009-01-25 12:00:52 c2woody Exp $ */ +/* $Id: int10.cpp,v 1.55 2009-04-11 07:58:39 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -635,10 +635,10 @@ graphics_chars: INT10_EGA_RIL_WriteRegister(reg_bl, reg_bh, reg_dx); break; case 0xf2: - INT10_EGA_RIL_ReadRegisterRange(reg_bl, reg_ch, reg_cl, reg_dx, SegPhys(es)+reg_bx); + INT10_EGA_RIL_ReadRegisterRange(reg_ch, reg_cl, reg_dx, SegPhys(es)+reg_bx); break; case 0xf3: - INT10_EGA_RIL_WriteRegisterRange(reg_bl, reg_ch, reg_cl, reg_dx, SegPhys(es)+reg_bx); + INT10_EGA_RIL_WriteRegisterRange(reg_ch, reg_cl, reg_dx, SegPhys(es)+reg_bx); break; case 0xf4: INT10_EGA_RIL_ReadRegisterSet(reg_cx, SegPhys(es)+reg_bx); diff --git a/src/ints/int10.h b/src/ints/int10.h index 4e5250bc..6eae71e3 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.h,v 1.36 2008-05-10 17:33:28 c2woody Exp $ */ +/* $Id: int10.h,v 1.37 2009-04-11 07:58:39 qbix79 Exp $ */ #include "vga.h" @@ -219,8 +219,8 @@ void INT10_SetupVESA(void); RealPt INT10_EGA_RIL_GetVersionPt(void); void INT10_EGA_RIL_ReadRegister(Bit8u & bl, Bit16u dx); void INT10_EGA_RIL_WriteRegister(Bit8u & bl, Bit8u bh, Bit16u dx); -void INT10_EGA_RIL_ReadRegisterRange(Bit8u & bl, Bit8u ch, Bit8u cl, Bit16u dx, PhysPt dst); -void INT10_EGA_RIL_WriteRegisterRange(Bit8u & bl, Bit8u ch, Bit8u cl, Bit16u dx, PhysPt dst); +void INT10_EGA_RIL_ReadRegisterRange(Bit8u ch, Bit8u cl, Bit16u dx, PhysPt dst); +void INT10_EGA_RIL_WriteRegisterRange(Bit8u ch, Bit8u cl, Bit16u dx, PhysPt dst); void INT10_EGA_RIL_ReadRegisterSet(Bit16u cx, PhysPt tbl); void INT10_EGA_RIL_WriteRegisterSet(Bit16u cx, PhysPt tbl); diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 8f0a1821..c983f395 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_misc.cpp,v 1.19 2008-08-01 19:52:02 c2woody Exp $ */ +/* $Id: int10_misc.cpp,v 1.20 2009-04-11 07:58:39 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -228,7 +228,7 @@ void INT10_EGA_RIL_WriteRegister(Bit8u & bl, Bit8u bh, Bit16u dx) { } } -void INT10_EGA_RIL_ReadRegisterRange(Bit8u & bl, Bit8u ch, Bit8u cl, Bit16u dx, PhysPt dst) { +void INT10_EGA_RIL_ReadRegisterRange(Bit8u ch, Bit8u cl, Bit16u dx, PhysPt dst) { Bitu port = 0; Bitu regs = 0; EGA_RIL(dx,port,regs); @@ -247,7 +247,7 @@ void INT10_EGA_RIL_ReadRegisterRange(Bit8u & bl, Bit8u ch, Bit8u cl, Bit16u dx, } } -void INT10_EGA_RIL_WriteRegisterRange(Bit8u & bl, Bit8u ch, Bit8u cl, Bit16u dx, PhysPt src) { +void INT10_EGA_RIL_WriteRegisterRange(Bit8u ch, Bit8u cl, Bit16u dx, PhysPt src) { Bitu port = 0; Bitu regs = 0; EGA_RIL(dx,port,regs); diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index d4cca91d..c718a2fb 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.37 2008-09-07 10:55:15 c2woody Exp $ */ +/* $Id: int10_vesa.cpp,v 1.38 2009-04-11 07:58:39 qbix79 Exp $ */ #include #include @@ -267,7 +267,7 @@ Bit8u VESA_SetSVGAMode(Bit16u mode) { return 0x00; } return 0x01; -}; +} Bit8u VESA_GetSVGAMode(Bit16u & mode) { if (int10.vesa_setmode!=0xffff) mode=int10.vesa_setmode; From 4f379fc870778af914647385ffd922ee120bb131 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 11 Apr 2009 08:02:23 +0000 Subject: [PATCH 3254/4131] even more small stuff Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3342 --- src/hardware/cmos.cpp | 4 ++-- src/hardware/gus.cpp | 4 ++-- src/hardware/iohandler.cpp | 16 +++++++++------- src/hardware/serialport/serialport.cpp | 8 ++++---- src/hardware/serialport/softmodem.h | 4 ++-- src/hardware/vga_dac.cpp | 2 +- src/hardware/vga_draw.cpp | 4 ++-- src/hardware/vga_seq.cpp | 12 ++++++------ 8 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 25e0ba2d..798e216a 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cmos.cpp,v 1.25 2009-02-01 14:24:37 qbix79 Exp $ */ +/* $Id: cmos.cpp,v 1.26 2009-04-11 08:02:23 qbix79 Exp $ */ #include @@ -280,7 +280,7 @@ static Bitu cmos_readreg(Bitu port,Bitu iolen) { void CMOS_SetRegister(Bitu regNr, Bit8u val) { cmos.regs[regNr] = val; -}; +} class CMOS:public Module_base{ diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 9542d1b4..934a54f6 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: gus.cpp,v 1.33 2009-01-14 20:50:23 c2woody Exp $ */ +/* $Id: gus.cpp,v 1.34 2009-04-11 08:02:23 qbix79 Exp $ */ #include #include @@ -454,7 +454,7 @@ static void GUS_TimerEvent(Bitu val) { } if (myGUS.timers[val].running) PIC_AddEvent(GUS_TimerEvent,myGUS.timers[val].delay,val); -}; +} static void ExecuteGlobRegister(void) { diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 4de2561a..0d05b873 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: iohandler.cpp,v 1.28 2007-06-12 20:22:08 c2woody Exp $ */ +/* $Id: iohandler.cpp,v 1.29 2009-04-11 08:02:23 qbix79 Exp $ */ #include #include "dosbox.h" @@ -32,6 +32,7 @@ IO_ReadHandler * io_readhandlers[3][IO_MAX]; static Bitu IO_ReadBlocked(Bitu /*port*/,Bitu /*iolen*/) { return ~0; } + static void IO_WriteBlocked(Bitu /*port*/,Bitu /*val*/,Bitu /*iolen*/) { } @@ -78,6 +79,7 @@ void IO_RegisterReadHandler(Bitu port,IO_ReadHandler * handler,Bitu mask,Bitu ra port++; } } + void IO_RegisterWriteHandler(Bitu port,IO_WriteHandler * handler,Bitu mask,Bitu range) { while (range--) { if (mask&IO_MB) io_writehandlers[0][port]=handler; @@ -241,7 +243,7 @@ void IO_WriteB(Bitu port,Bitu val) { IO_USEC_write_delay(); io_writehandlers[0][port](port,val,1); } -}; +} void IO_WriteW(Bitu port,Bitu val) { if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,2)))) { @@ -276,7 +278,7 @@ void IO_WriteW(Bitu port,Bitu val) { IO_USEC_write_delay(); io_writehandlers[1][port](port,val,2); } -}; +} void IO_WriteD(Bitu port,Bitu val) { if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,4)))) { @@ -308,7 +310,7 @@ void IO_WriteD(Bitu port,Bitu val) { cpudecoder=old_cpudecoder; } else io_writehandlers[2][port](port,val,4); -}; +} Bitu IO_ReadB(Bitu port) { if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,1)))) { @@ -343,7 +345,7 @@ Bitu IO_ReadB(Bitu port) { IO_USEC_read_delay(); return io_readhandlers[0][port](port,1); } -}; +} Bitu IO_ReadW(Bitu port) { if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,2)))) { @@ -378,7 +380,7 @@ Bitu IO_ReadW(Bitu port) { IO_USEC_read_delay(); return io_readhandlers[1][port](port,2); } -}; +} Bitu IO_ReadD(Bitu port) { if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,4)))) { @@ -410,7 +412,7 @@ Bitu IO_ReadD(Bitu port) { return retval; } else return io_readhandlers[2][port](port,4); -}; +} class IO :public Module_base { public: diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index 1b1651d7..1a5d6234 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.cpp,v 1.10 2008-08-06 18:33:30 c2woody Exp $ */ +/* $Id: serialport.cpp,v 1.11 2009-04-11 08:02:23 qbix79 Exp $ */ #include #include @@ -82,7 +82,7 @@ bool device_COM::Close() { Bit16u device_COM::GetInformation(void) { return 0x80A0; -}; +} device_COM::device_COM(class CSerial* sc) { sclass = sc; @@ -1068,7 +1068,7 @@ CSerial::CSerial(Bitu id, CommandLine* cmd) { if(debugfp) fprintf(debugfp,"COM%d: BASE %3x, IRQ %d\r\n\r\n", COMNUMBER,base,irq); #endif -}; +} bool CSerial::getBituSubstring(const char* name,Bitu* data, CommandLine* cmd) { std::string tmpstring; @@ -1082,7 +1082,7 @@ CSerial::~CSerial(void) { DOS_DelDevice(mydosdevice); for(Bitu i = 0; i <= SERIAL_BASE_EVENT_COUNT; i++) removeEvent(i); -}; +} bool CSerial::Getchar(Bit8u* data, Bit8u* lsr, bool wait_dsr, Bitu timeout) { double starttime=PIC_FullIndex(); diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index 2c128f82..8a856a56 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.h,v 1.8 2007-07-19 18:58:39 c2woody Exp $ */ +/* $Id: softmodem.h,v 1.9 2009-04-11 08:02:23 qbix79 Exp $ */ #ifndef DOSBOX_SERIALMODEM_H #define DOSBOX_SERIALMODEM_H @@ -45,7 +45,7 @@ enum ResTypes { ResNONE, ResOK,ResERROR, ResCONNECT,ResRING, - ResBUSY,ResNODIALTONE,ResNOCARRIER, + ResBUSY,ResNODIALTONE,ResNOCARRIER }; #define TEL_CLIENT 0 diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index 2dd7f52a..ab971f56 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -240,4 +240,4 @@ void VGA_SetupDAC(void) { if ((i&8)>0) vga.dac.rgb[i].blue+=0x15; } } -}; +} diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 3d5624bd..502f3b64 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.106 2009-01-26 20:23:44 qbix79 Exp $ */ +/* $Id: vga_draw.cpp,v 1.107 2009-04-11 08:02:23 qbix79 Exp $ */ #include #include @@ -1368,7 +1368,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { PIC_AddEvent( VGA_VerticalTimer , (float)vga.draw.delay.vtotal ); vga.draw.lines_done = 0; } -}; +} void VGA_KillDrawing(void) { PIC_RemoveEvents(VGA_DrawPart); diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 130025c4..5af68a2d 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_seq.cpp,v 1.22 2008-01-09 20:34:51 c2woody Exp $ */ +/* $Id: vga_seq.cpp,v 1.23 2009-04-11 08:02:23 qbix79 Exp $ */ #include "dosbox.h" #include "inout.h" @@ -24,15 +24,15 @@ #define seq(blah) vga.seq.blah -Bitu read_p3c4(Bitu port,Bitu iolen) { +Bitu read_p3c4(Bitu /*port*/,Bitu /*iolen*/) { return seq(index); } -void write_p3c4(Bitu port,Bitu val,Bitu iolen) { +void write_p3c4(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { seq(index)=val; -}; +} -void write_p3c5(Bitu port,Bitu val,Bitu iolen) { +void write_p3c5(Bitu /*port*/,Bitu val,Bitu iolen) { // LOG_MSG("SEQ WRITE reg %X val %X",seq(index),val); switch(seq(index)) { case 0: /* Reset */ @@ -119,7 +119,7 @@ void write_p3c5(Bitu port,Bitu val,Bitu iolen) { } -Bitu read_p3c5(Bitu port,Bitu iolen) { +Bitu read_p3c5(Bitu /*port*/,Bitu iolen) { // LOG_MSG("VGA:SEQ:Read from index %2X",seq(index)); switch(seq(index)) { case 0: /* Reset */ From ff5542b76009d06a50751e3c06b5a4f7cefd7c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 11 Apr 2009 19:49:52 +0000 Subject: [PATCH 3255/4131] fix debugger memory dumping function Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3343 --- src/debug/debug.cpp | 57 ++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index d136e535..fadaa8f4 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.96 2009-04-02 19:10:44 qbix79 Exp $ */ +/* $Id: debug.cpp,v 1.97 2009-04-11 19:49:52 c2woody Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -77,17 +77,17 @@ Bit32u GetHexValue(char* str, char*& hex); class DebugPageHandler : public PageHandler { public: - Bitu readb(PhysPt addr) { + Bitu readb(PhysPt /*addr*/) { } - Bitu readw(PhysPt addr) { + Bitu readw(PhysPt /*addr*/) { } - Bitu readd(PhysPt addr) { + Bitu readd(PhysPt /*addr*/) { } - void writeb(PhysPt addr,Bitu val) { + void writeb(PhysPt /*addr*/,Bitu /*val*/) { } - void writew(PhysPt addr,Bitu val) { + void writew(PhysPt /*addr*/,Bitu /*val*/) { } - void writed(PhysPt addr,Bitu val) { + void writed(PhysPt /*addr*/,Bitu /*val*/) { } @@ -1938,8 +1938,7 @@ static void DEBUG_ProgramStart(Program * * make) { // INIT -void DEBUG_SetupConsole(void) -{ +void DEBUG_SetupConsole(void) { #ifdef WIN32 WIN32_Console(); #else @@ -1953,10 +1952,9 @@ void DEBUG_SetupConsole(void) input_count=0; /* Start the Debug Gui */ DBGUI_StartUp(); -}; +} -static void DEBUG_ShutDown(Section * sec) -{ +static void DEBUG_ShutDown(Section * /*sec*/) { CBreakpoint::DeleteAll(); CDebugVar::DeleteAll(); curs_set(old_cursor_state); @@ -1966,7 +1964,7 @@ static void DEBUG_ShutDown(Section * sec) printf("\ec"); fflush(NULL); #endif -}; +} Bitu debugCallback; @@ -2020,9 +2018,10 @@ bool CDebugVar::SaveVars(char* name) { FILE* f = fopen(name,"wb+"); if (!f) return false; + if (varList.size()>65535) return false; // write number of vars - Bit16u num = varList.size(); + Bit16u num = (Bit16u)varList.size(); fwrite(&num,1,sizeof(num),f); std::list::iterator i; @@ -2072,22 +2071,32 @@ static void SaveMemory(Bitu seg, Bitu ofs1, Bit32u num) { char buffer[128]; char temp[16]; - while(num>0) { + while (num>16) { sprintf(buffer,"%04X:%04X ",seg,ofs1); for (Bit16u x=0; x<16; x++) { Bit8u value; if (mem_readb_checked(GetAddress(seg,ofs1+x),&value)) sprintf(temp,"?? ",value); else sprintf(temp,"%02X ",value); strcat(buffer,temp); - }; + } ofs1+=16; num-=16; fprintf(f,"%s\n",buffer); - }; + } + if (num>0) { + sprintf(buffer,"%04X:%04X ",seg,ofs1); + for (Bit16u x=0; x Date: Thu, 16 Apr 2009 12:11:45 +0000 Subject: [PATCH 3256/4131] Several changes that speed limit the amount of mouse events. Keeping tracking of mode and UIR now (no action though). Fixes to Get buttonpress/release.(Tunnels of Armageddon). Reset less stuff on videomode changes (Stonekeep). Thanks for you help wd and ripsaw (beta3). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3344 --- src/ints/mouse.cpp | 77 +++++++++++++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 22 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 2be96182..e54384bb 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.78 2009-03-04 19:34:42 c2woody Exp $ */ +/* $Id: mouse.cpp,v 1.79 2009-04-16 12:11:45 qbix79 Exp $ */ #include #include @@ -123,6 +123,9 @@ static struct { Bit8u page; bool enabled; bool inhibit_draw; + bool timer_in_progress; + bool in_UIR; + Bit8u mode; } mouse; bool Mouse_SetPS2State(bool use) { @@ -195,12 +198,22 @@ Bitu PS2_Handler(void) { #define MOUSE_RIGHT_RELEASED 16 #define MOUSE_MIDDLE_PRESSED 32 #define MOUSE_MIDDLE_RELEASED 64 +#define MOUSE_DELAY 5.0 + +void MOUSE_Limit_Events(Bitu /*val*/) { + mouse.timer_in_progress = false; + if (mouse.events) { + mouse.timer_in_progress = true; + PIC_AddEvent(MOUSE_Limit_Events,MOUSE_DELAY); + PIC_ActivateIRQ(MOUSE_IRQ); + } +} INLINE void Mouse_AddEvent(Bit8u type) { if (mouse.events0) { /* Skip duplicate events */ - if ((type==MOUSE_HAS_MOVED) && (mouse.buttons==0)) return; + if (type==MOUSE_HAS_MOVED) return; /* Always put the newest element in the front as that the events are * handled backwards (prevents doubleclicks while moving) */ @@ -211,7 +224,11 @@ INLINE void Mouse_AddEvent(Bit8u type) { mouse.event_queue[0].buttons=mouse.buttons; mouse.events++; } - PIC_ActivateIRQ(MOUSE_IRQ); + if (!mouse.timer_in_progress) { + mouse.timer_in_progress = true; + PIC_AddEvent(MOUSE_Limit_Events,MOUSE_DELAY); + PIC_ActivateIRQ(MOUSE_IRQ); + } } // *************************************************************************** @@ -228,7 +245,7 @@ void RestoreCursorBackgroundText() { WriteChar(mouse.backposx,mouse.backposy,real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE),mouse.backData[0],mouse.backData[1],true); mouse.background = false; } -}; +} void DrawCursorText() { // Restore Background @@ -250,7 +267,7 @@ void DrawCursorText() { // Write Cursor result = (result & mouse.textAndMask) ^ mouse.textXorMask; WriteChar(mouse.backposx,mouse.backposy,page,(Bit8u)(result&0xFF),(Bit8u)(result>>8),true); -}; +} // *************************************************************************** // Mouse cursor - graphic mode @@ -313,7 +330,7 @@ void ClipCursorArea(Bit16s& x1, Bit16s& x2, Bit16s& y1, Bit16s& y2, addx2 = x2 - mouse.clipx; x2 = mouse.clipx; }; -}; +} void RestoreCursorBackground() { if (mouse.hidden || mouse.inhibit_draw) return; @@ -342,7 +359,7 @@ void RestoreCursorBackground() { mouse.background = false; }; RestoreVgaRegisters(); -}; +} void DrawCursor() { if (mouse.hidden || mouse.inhibit_draw) return; @@ -524,7 +541,8 @@ static void Mouse_SetMickeyPixelRate(Bit16s px, Bit16s py){ mouse.pixelPerMickey_x = X_MICKEY/(float)px; mouse.pixelPerMickey_y = Y_MICKEY/(float)py; } -}; +} + static void Mouse_SetSensitivity(Bit16u px, Bit16u py, Bit16u dspeed){ if(px>100) px=100; if(py>100) py=100; @@ -539,18 +557,19 @@ static void Mouse_SetSensitivity(Bit16u px, Bit16u py, Bit16u dspeed){ mouse.senv_x=(static_cast(px)*px)/3600.0f +1.0f/3.0f; mouse.senv_y=(static_cast(py)*py)/3600.0f +1.0f/3.0f; } -}; +} static void Mouse_ResetHardware(void){ PIC_SetIRQMask(MOUSE_IRQ,false); -}; +} //Does way to much. Many things should be moved to mouse reset one day void Mouse_NewVideoMode(void) { mouse.inhibit_draw=false; /* Get the correct resolution from the current video mode */ - Bitu mode=mem_readb(BIOS_VIDEO_MODE); + Bit8u mode=mem_readb(BIOS_VIDEO_MODE); + if(mode == mouse.mode) {LOG(LOG_MOUSE,LOG_NORMAL)("New video is the same as the old"); /*return;*/} switch (mode) { case 0x00: case 0x01: @@ -586,16 +605,15 @@ void Mouse_NewVideoMode(void) { mouse.inhibit_draw=true; return; } + mouse.mode = mode; mouse.hidden = 1; mouse.max_x = 639; mouse.min_x = 0; mouse.min_y = 0; - // Dont set max coordinates here. it is done by SetResolution! - mouse.x = static_cast((mouse.max_x + 1)/ 2); - mouse.y = static_cast((mouse.max_y + 1)/ 2); + mouse.events = 0; - mouse.mickey_x = 0; - mouse.mickey_y = 0; + mouse.timer_in_progress = false; + PIC_RemoveEvents(MOUSE_Limit_Events); mouse.hotx = 0; mouse.hoty = 0; @@ -617,6 +635,8 @@ void Mouse_NewVideoMode(void) { oldmouseX = static_cast(mouse.x); oldmouseY = static_cast(mouse.y); + + } //Much too empty, Mouse_NewVideoMode contains stuff that should be in here @@ -629,7 +649,14 @@ static void Mouse_Reset(void) { Mouse_NewVideoMode(); Mouse_SetMickeyPixelRate(8,16); - mouse.sub_mask=0; + mouse.mickey_x = 0; + mouse.mickey_y = 0; + + // Dont set max coordinates here. it is done by SetResolution! + mouse.x = static_cast((mouse.max_x + 1)/ 2); + mouse.y = static_cast((mouse.max_y + 1)/ 2); + mouse.sub_mask = 0; + mouse.in_UIR = false; } static Bitu INT33_Handler(void) { @@ -677,8 +704,7 @@ static Bitu INT33_Handler(void) { { Bit16u but=reg_bx; reg_ax=mouse.buttons; - reg_bx++; - if (but>=MOUSE_BUTTONS) break; + if (but>=MOUSE_BUTTONS) but = MOUSE_BUTTONS - 1; reg_cx=mouse.last_pressed_x[but]; reg_dx=mouse.last_pressed_y[but]; reg_bx=mouse.times_pressed[but]; @@ -689,8 +715,7 @@ static Bitu INT33_Handler(void) { { Bit16u but=reg_bx; reg_ax=mouse.buttons; - reg_bx++; - if (but>=MOUSE_BUTTONS) break; + if (but>=MOUSE_BUTTONS) but = MOUSE_BUTTONS - 1; reg_cx=mouse.last_released_x[but]; reg_dx=mouse.last_released_y[but]; reg_bx=mouse.times_released[but]; @@ -954,6 +979,8 @@ static Bitu INT74_Handler(void) { CPU_Push16(RealOff(CALLBACK_RealPointer(int74_ret_callback))); SegSet16(cs, mouse.sub_seg); reg_ip = mouse.sub_ofs; + if(mouse.in_UIR) LOG(LOG_MOUSE,LOG_ERROR)("Already in UIR!"); + mouse.in_UIR = true; } else if (useps2callback) { CPU_Push16(RealSeg(CALLBACK_RealPointer(int74_ret_callback))); CPU_Push16(RealOff(CALLBACK_RealPointer(int74_ret_callback))); @@ -970,8 +997,12 @@ static Bitu INT74_Handler(void) { } Bitu MOUSE_UserInt_CB_Handler(void) { + mouse.in_UIR = false; if (mouse.events) { - PIC_ActivateIRQ(MOUSE_IRQ); + if (!mouse.timer_in_progress) { + mouse.timer_in_progress = true; + PIC_AddEvent(MOUSE_Limit_Events,MOUSE_DELAY); + } } return CBRET_NONE; } @@ -1033,6 +1064,8 @@ void MOUSE_Init(Section* /*sec*/) { memset(&mouse,0,sizeof(mouse)); mouse.hidden = 1; //Hide mouse on startup + mouse.timer_in_progress = false; + mouse.mode = 0xFF; //Non existing mode mouse.sub_mask=0; mouse.sub_seg=0x6362; // magic value From 92c5771c4d38c8192401964d7ea471ddb7be51ce Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 16 Apr 2009 12:16:52 +0000 Subject: [PATCH 3257/4131] Prepare system to mode current drive to sda. Check for problems with rename.(fixes linux rename). Small warning fixes + style changes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3345 --- src/dos/dos.cpp | 5 ++-- src/dos/dos_classes.cpp | 62 +++++++++++++++++------------------------ src/dos/dos_files.cpp | 37 ++++++++++++++++++++---- src/dos/dos_ioctl.cpp | 4 +-- 4 files changed, 62 insertions(+), 46 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index cd3ff0eb..fd5ebbe1 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.116 2009-03-14 16:10:00 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.117 2009-04-16 12:16:52 qbix79 Exp $ */ #include #include @@ -397,7 +397,7 @@ static Bitu DOS_21Handler(void) { case 0x1f: /* Get drive parameter block for default drive */ case 0x32: /* Get drive parameter block for specific drive */ { /* Officially a dpb should be returned as well. The disk detection part is implemented */ - Bitu drive=reg_dl;if(!drive || reg_ah==0x1f) drive=dos.current_drive;else drive--; + Bitu drive=reg_dl;if(!drive || reg_ah==0x1f) drive = DOS_GetDefaultDrive();else drive--; if(Drives[drive]) { reg_al = 0x00; SegSet16(ds,dos.tables.dpb); @@ -1126,6 +1126,7 @@ public: DOS_SetupMemory(); /* Setup first MCB */ DOS_SetupPrograms(); DOS_SetupMisc(); /* Some additional dos interrupts */ + DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetDrive(25); /* Else the next call gives a warning. */ DOS_SetDefaultDrive(25); dos.version.major=5; diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 85e829e5..70b6c14b 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.55 2008-09-07 10:55:14 c2woody Exp $ */ +/* $Id: dos_classes.cpp,v 1.56 2009-04-16 12:16:52 qbix79 Exp $ */ #include #include @@ -210,41 +210,36 @@ void DOS_PSP::MakeNew(Bit16u mem_size) { if (rootpsp==0) rootpsp = seg; } -Bit8u DOS_PSP::GetFileHandle(Bit16u index) -{ +Bit8u DOS_PSP::GetFileHandle(Bit16u index) { if (index>=sGet(sPSP,max_files)) return 0xff; PhysPt files=Real2Phys(sGet(sPSP,file_table)); return mem_readb(files+index); -}; +} -void DOS_PSP::SetFileHandle(Bit16u index, Bit8u handle) -{ +void DOS_PSP::SetFileHandle(Bit16u index, Bit8u handle) { if (indexGetFileHandle(i); @@ -266,53 +261,46 @@ void DOS_PSP::CopyFileTable(DOS_PSP* srcpsp,bool createchildpsp) SetFileHandle(i,handle); } } -}; +} -void DOS_PSP::CloseFiles(void) -{ +void DOS_PSP::CloseFiles(void) { for (Bit16u i=0;i20) { // Allocate needed paragraphs fileNum+=2; // Add a few more files for safety @@ -327,7 +315,7 @@ bool DOS_PSP::SetNumFiles(Bit16u fileNum) sSave(sPSP,max_files,fileNum); }; return true; -}; +} void DOS_DTA::SetupSearch(Bit8u _sdrive,Bit8u _sattr,char * pattern) { @@ -480,7 +468,7 @@ void DOS_FCB::FileClose(Bit8u & _fhandle) { Bit8u DOS_FCB::GetDrive(void) { Bit8u drive=sGet(sFCB,drive); - if (!drive) return dos.current_drive; + if (!drive) return DOS_GetDefaultDrive(); else return drive-1; } diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 45903976..363bb1bf 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.107 2009-03-23 21:58:05 c2woody Exp $ */ +/* $Id: dos_files.cpp,v 1.108 2009-04-16 12:16:52 qbix79 Exp $ */ #include #include @@ -45,11 +45,15 @@ DOS_File * Files[DOS_FILES]; DOS_Drive * Drives[DOS_DRIVES]; Bit8u DOS_GetDefaultDrive(void) { +// return DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).GetDrive(); + Bit8u d = DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).GetDrive(); + if( d != dos.current_drive ) LOG(LOG_DOSMISC,LOG_ERROR)("SDA drive %d not the same as dos.current_drive %d",d,dos.current_drive); return dos.current_drive; } void DOS_SetDefaultDrive(Bit8u drive) { - if (drive<=DOS_DRIVES && ((drive<2) || Drives[drive])) dos.current_drive = drive; +// if (drive<=DOS_DRIVES && ((drive<2) || Drives[drive])) DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetDrive(drive); + if (drive<=DOS_DRIVES && ((drive<2) || Drives[drive])) {dos.current_drive = drive; DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetDrive(drive);} } bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { @@ -63,7 +67,7 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { char tempdir[DOS_PATHLENGTH]; char upname[DOS_PATHLENGTH]; Bitu r,w; - *drive=dos.current_drive; + *drive = DOS_GetDefaultDrive(); /* First get the drive */ if (name_int[1]==':') { *drive=(name_int[0] | 0x20)-'a'; @@ -256,8 +260,31 @@ bool DOS_Rename(char const * const oldname,char const * const newname) { Bit8u drivenew;char fullnew[DOS_PATHLENGTH]; if (!DOS_MakeName(oldname,fullold,&driveold)) return false; if (!DOS_MakeName(newname,fullnew,&drivenew)) return false; - //TODO Test for different drives maybe + /* No tricks with devices */ + if ( (DOS_FindDevice(oldname) != DOS_DEVICES) || + (DOS_FindDevice(newname) != DOS_DEVICES) ) { + DOS_SetError(DOSERR_FILE_NOT_FOUND); + return false; + } + /* Must be on the same drive */ + if(driveold != drivenew) { + DOS_SetError(DOSERR_NOT_SAME_DEVICE); + return false; + } + /*Test if target exists => no access */ + if(Drives[drivenew]->FileExists(fullnew)) { + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; + } + /* Source must exist, check for path ? */ + if(!Drives[driveold]->FileExists(fullold)) { + DOS_SetError(DOSERR_FILE_NOT_FOUND); + return false; + } + if (Drives[drivenew]->Rename(fullold,fullnew)) return true; + /* If it still fails. which error should we give ? PATH NOT FOUND or EACCESS */ + LOG(LOG_FILES,LOG_NORMAL)("Rename fails on %c from %s to %s, no proper errorcode returned.",driveold+'A',oldname,newname); DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } @@ -1139,7 +1166,7 @@ bool DOS_FileExists(char const * const name) { } bool DOS_GetAllocationInfo(Bit8u drive,Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters) { - if (!drive) drive=dos.current_drive; + if (!drive) drive = DOS_GetDefaultDrive(); else drive--; if (drive >= DOS_DRIVES || !Drives[drive]) return false; Bit16u _free_clusters; diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 342b113e..57c53777 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.34 2009-03-24 17:07:30 c2woody Exp $ */ +/* $Id: dos_ioctl.cpp,v 1.35 2009-04-16 12:16:52 qbix79 Exp $ */ #include #include "dosbox.h" @@ -40,7 +40,7 @@ bool DOS_IOCTL(void) { } } else if (reg_al<0x12) { /* those use a diskdrive except 0x0b */ if (reg_al!=0x0b) { - drive=reg_bl;if (!drive) drive=dos.current_drive;else drive--; + drive=reg_bl;if (!drive) drive = DOS_GetDefaultDrive();else drive--; if( !(( drive < DOS_DRIVES ) && Drives[drive]) ) { DOS_SetError(DOSERR_INVALID_DRIVE); return false; From c3af6d242067347c1ed0c16ff4ea24ff05f8b933 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 16 Apr 2009 12:28:30 +0000 Subject: [PATCH 3258/4131] Warnings and style. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3346 --- src/dos/cdrom.cpp | 88 ++++++++++++----------------- src/dos/dos_mscdex.cpp | 98 ++++++++++++++++---------------- src/dos/dos_programs.cpp | 8 +-- src/dos/drive_cache.cpp | 118 ++++++++++++++++----------------------- 4 files changed, 135 insertions(+), 177 deletions(-) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 3e13ac39..488f858f 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -30,22 +30,19 @@ #include "support.h" #include "cdrom.h" -CDROM_Interface_SDL::CDROM_Interface_SDL(void) -{ +CDROM_Interface_SDL::CDROM_Interface_SDL(void) { driveID = 0; oldLeadOut = 0; cd = 0; -}; +} -CDROM_Interface_SDL::~CDROM_Interface_SDL(void) -{ +CDROM_Interface_SDL::~CDROM_Interface_SDL(void) { StopAudio(); SDL_CDClose(cd); cd = 0; -}; +} -bool CDROM_Interface_SDL::SetDevice (char* path, int forceCD) -{ +bool CDROM_Interface_SDL::SetDevice(char* path, int forceCD) { char buffer[512]; strcpy(buffer,path); upcase(buffer); @@ -69,10 +66,9 @@ bool CDROM_Interface_SDL::SetDevice (char* path, int forceCD) }; }; return false; -}; +} -bool CDROM_Interface_SDL::GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) -{ +bool CDROM_Interface_SDL::GetAudioTracks(int& stTrack, int& end, TMSF& leadOut) { if (CD_INDRIVE(SDL_CDStatus(cd))) { stTrack = 1; @@ -80,19 +76,17 @@ bool CDROM_Interface_SDL::GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) FRAMES_TO_MSF(cd->track[cd->numtracks].offset,&leadOut.min,&leadOut.sec,&leadOut.fr); } return CD_INDRIVE(SDL_CDStatus(cd)); -}; +} -bool CDROM_Interface_SDL::GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr) -{ +bool CDROM_Interface_SDL::GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr) { if (CD_INDRIVE(SDL_CDStatus(cd))) { FRAMES_TO_MSF(cd->track[track-1].offset,&start.min,&start.sec,&start.fr); attr = cd->track[track-1].type<<4;//sdl uses 0 for audio and 4 for data. instead of 0x00 and 0x40 } return CD_INDRIVE(SDL_CDStatus(cd)); -}; +} -bool CDROM_Interface_SDL::GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) -{ +bool CDROM_Interface_SDL::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) { if (CD_INDRIVE(SDL_CDStatus(cd))) { track = cd->cur_track; index = cd->cur_track; @@ -101,19 +95,17 @@ bool CDROM_Interface_SDL::GetAudioSub (unsigned char& attr, unsigned char& track FRAMES_TO_MSF(cd->cur_frame+cd->track[track].offset,&absPos.min,&absPos.sec,&absPos.fr); } return CD_INDRIVE(SDL_CDStatus(cd)); -}; +} -bool CDROM_Interface_SDL::GetAudioStatus (bool& playing, bool& pause) -{ +bool CDROM_Interface_SDL::GetAudioStatus(bool& playing, bool& pause){ if (CD_INDRIVE(SDL_CDStatus(cd))) { playing = (cd->status==CD_PLAYING); pause = (cd->status==CD_PAUSED); } return CD_INDRIVE(SDL_CDStatus(cd)); -}; +} -bool CDROM_Interface_SDL::GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) -{ +bool CDROM_Interface_SDL::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) { SDL_CDStatus(cd); mediaPresent = (cd->status!=CD_TRAYEMPTY) && (cd->status!=CD_ERROR); mediaChanged = (oldLeadOut!=cd->track[cd->numtracks].offset); @@ -121,45 +113,40 @@ bool CDROM_Interface_SDL::GetMediaTrayStatus (bool& mediaPresent, bool& mediaCha oldLeadOut = cd->track[cd->numtracks].offset; if (mediaChanged) SDL_CDStatus(cd); return true; -}; +} -bool CDROM_Interface_SDL::PlayAudioSector (unsigned long start,unsigned long len) -{ +bool CDROM_Interface_SDL::PlayAudioSector(unsigned long start,unsigned long len) { // Has to be there, otherwise wrong cd status report (dunno why, sdl bug ?) SDL_CDClose(cd); cd = SDL_CDOpen(driveID); bool success = (SDL_CDPlay(cd,start+150,len)==0); return success; -}; +} -bool CDROM_Interface_SDL::PauseAudio (bool resume) -{ +bool CDROM_Interface_SDL::PauseAudio(bool resume) { bool success; if (resume) success = (SDL_CDResume(cd)==0); else success = (SDL_CDPause (cd)==0); return success; -}; +} -bool CDROM_Interface_SDL::StopAudio (void) -{ +bool CDROM_Interface_SDL::StopAudio(void) { // Has to be there, otherwise wrong cd status report (dunno why, sdl bug ?) SDL_CDClose(cd); cd = SDL_CDOpen(driveID); bool success = (SDL_CDStop(cd)==0); return success; -}; +} -bool CDROM_Interface_SDL::LoadUnloadMedia(bool unload) -{ +bool CDROM_Interface_SDL::LoadUnloadMedia(bool unload) { bool success = (SDL_CDEject(cd)==0); return success; -}; +} -int CDROM_GetMountType(char* path, int forceCD) +int CDROM_GetMountType(char* path, int forceCD) { // 0 - physical CDROM // 1 - Iso file // 2 - subdirectory -{ // 1. Smells like a real cdrom // if ((strlen(path)<=3) && (path[2]=='\\') && (strchr(path,'\\')==strrchr(path,'\\')) && (GetDriveType(path)==DRIVE_CDROM)) return 0; @@ -187,31 +174,28 @@ int CDROM_GetMountType(char* path, int forceCD) struct stat file_stat; if ((stat(path, &file_stat) == 0) && S_ISREG(file_stat.st_mode)) return 1; return 2; -}; +} // ****************************************************** // Fake CDROM // ****************************************************** -bool CDROM_Interface_Fake :: GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) -{ +bool CDROM_Interface_Fake :: GetAudioTracks(int& stTrack, int& end, TMSF& leadOut) { stTrack = end = 1; leadOut.min = 60; leadOut.sec = leadOut.fr = 0; return true; -}; +} -bool CDROM_Interface_Fake :: GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr) -{ +bool CDROM_Interface_Fake :: GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr) { if (track>1) return false; start.min = start.fr = 0; start.sec = 2; attr = 0x60; // data / permitted return true; -}; +} -bool CDROM_Interface_Fake :: GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) -{ +bool CDROM_Interface_Fake :: GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos){ attr = 0; track = index = 1; relPos.min = relPos.fr = 0; relPos.sec = 2; @@ -219,18 +203,16 @@ bool CDROM_Interface_Fake :: GetAudioSub (unsigned char& attr, unsigned char& tr return true; } -bool CDROM_Interface_Fake :: GetAudioStatus (bool& playing, bool& pause) -{ +bool CDROM_Interface_Fake :: GetAudioStatus(bool& playing, bool& pause) { playing = pause = false; return true; } -bool CDROM_Interface_Fake :: GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) -{ +bool CDROM_Interface_Fake :: GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) { mediaPresent = true; mediaChanged = false; - trayOpen = false; + trayOpen = false; return true; -}; +} diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 3dd8c7a1..e8908b1c 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.58 2009-03-01 15:40:30 c2woody Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.59 2009-04-16 12:28:30 qbix79 Exp $ */ #include #include @@ -54,8 +54,7 @@ int forceCD = -1; static Bitu MSCDEX_Strategy_Handler(void); static Bitu MSCDEX_Interrupt_Handler(void); -class DOS_DeviceHeader:public MemStruct -{ +class DOS_DeviceHeader:public MemStruct { public: DOS_DeviceHeader(PhysPt ptr) { pt = ptr; }; @@ -88,8 +87,7 @@ public: #endif }; -class CMscdex -{ +class CMscdex { public: CMscdex (void); ~CMscdex (void); @@ -170,7 +168,7 @@ CMscdex::CMscdex(void) { memset(dinfo,0,sizeof(dinfo)); for (Bit32u i=0; i> 0) & 0xFF; Bit32u sector = min*60*75+sec*75+fr - 150; return dinfo[subUnit].lastResult = PlayAudioSector(subUnit,sector,length); -}; +} bool CMscdex::GetSubChannelData(Bit8u subUnit, Bit8u& attr, Bit8u& track, Bit8u &index, TMSF& rel, TMSF& abs) { @@ -494,7 +492,7 @@ bool CMscdex::GetSubChannelData(Bit8u subUnit, Bit8u& attr, Bit8u& track, Bit8u memset(&abs,0,sizeof(abs)); }; return dinfo[subUnit].lastResult; -}; +} bool CMscdex::GetAudioStatus(Bit8u subUnit, bool& playing, bool& pause, TMSF& start, TMSF& end) { @@ -519,7 +517,7 @@ bool CMscdex::GetAudioStatus(Bit8u subUnit, bool& playing, bool& pause, TMSF& st }; return dinfo[subUnit].lastResult; -}; +} bool CMscdex::StopAudio(Bit8u subUnit) { @@ -541,13 +539,13 @@ bool CMscdex::StopAudio(Bit8u subUnit) dinfo[subUnit].audioPlay = false; }; return dinfo[subUnit].lastResult; -}; +} bool CMscdex::ResumeAudio(Bit8u subUnit) { if (subUnit>=numDrives) return false; return dinfo[subUnit].lastResult = PlayAudioSector(subUnit,dinfo[subUnit].audioStart,dinfo[subUnit].audioEnd); -}; +} Bit32u CMscdex::GetVolumeSize(Bit8u subUnit) { @@ -557,7 +555,7 @@ Bit32u CMscdex::GetVolumeSize(Bit8u subUnit) dinfo[subUnit].lastResult = GetCDInfo(subUnit,tr1,tr2,leadOut); if (dinfo[subUnit].lastResult) return (leadOut.min*60*75)+(leadOut.sec*75)+leadOut.fr; return 0; -}; +} bool CMscdex::ReadVTOC(Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error) { @@ -574,7 +572,7 @@ bool CMscdex::ReadVTOC(Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error) Bit8u type = mem_readb(data); error = (type == 1) ? 1 : (type == 0xFF) ? 0xFF : 0; return true; -}; +} bool CMscdex::GetVolumeName(Bit8u subUnit, char* data) { if (subUnit>=numDrives) return false; @@ -591,7 +589,7 @@ bool CMscdex::GetVolumeName(Bit8u subUnit, char* data) { }; return success; -}; +} bool CMscdex::GetCopyrightName(Bit16u drive, PhysPt data) { Bit16u error; @@ -603,7 +601,7 @@ bool CMscdex::GetCopyrightName(Bit16u drive, PhysPt data) { mem_writeb(data+37,0); }; return success; -}; +} bool CMscdex::GetAbstractName(Bit16u drive, PhysPt data) { Bit16u error; @@ -615,7 +613,7 @@ bool CMscdex::GetAbstractName(Bit16u drive, PhysPt data) { mem_writeb(data+37,0); }; return success; -}; +} bool CMscdex::GetDocumentationName(Bit16u drive, PhysPt data) { Bit16u error; @@ -627,13 +625,13 @@ bool CMscdex::GetDocumentationName(Bit16u drive, PhysPt data) { mem_writeb(data+37,0); }; return success; -}; +} bool CMscdex::GetUPC(Bit8u subUnit, Bit8u& attr, char* upc) { if (subUnit>=numDrives) return false; return dinfo[subUnit].lastResult = cdrom[subUnit]->GetUPC(attr,&upc[0]); -}; +} bool CMscdex::ReadSectors(Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data) { if (subUnit>=numDrives) return false; @@ -641,7 +639,7 @@ bool CMscdex::ReadSectors(Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, Ph else CPU_Cycles = 5; dinfo[subUnit].lastResult = cdrom[subUnit]->ReadSectors(data,raw,sector,num); return dinfo[subUnit].lastResult; -}; +} bool CMscdex::ReadSectorsMSF(Bit8u subUnit, bool raw, Bit32u start, Bit16u num, PhysPt data) { if (subUnit>=numDrives) return false; @@ -650,12 +648,12 @@ bool CMscdex::ReadSectorsMSF(Bit8u subUnit, bool raw, Bit32u start, Bit16u num, Bit8u fr = (Bit8u)(start>> 0) & 0xFF; Bit32u sector = min*60*75+sec*75+fr - 150; return ReadSectors(subUnit,raw,sector,num,data); -}; +} // Called from INT 2F bool CMscdex::ReadSectors(Bit16u drive, Bit32u sector, Bit16u num, PhysPt data) { return ReadSectors(GetSubUnit(drive),false,sector,num,data); -}; +} bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, PhysPt buffer, Bit16u& error) { @@ -766,7 +764,7 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph }; error = 2; // file not found return false; // not found -}; +} bool CMscdex::GetCurrentPos(Bit8u subUnit, TMSF& pos) { @@ -776,14 +774,14 @@ bool CMscdex::GetCurrentPos(Bit8u subUnit, TMSF& pos) dinfo[subUnit].lastResult = GetSubChannelData(subUnit, attr, track, index, rel, pos); if (!dinfo[subUnit].lastResult) memset(&pos,0,sizeof(pos)); return dinfo[subUnit].lastResult; -}; +} bool CMscdex::GetMediaStatus(Bit8u subUnit, bool& media, bool& changed, bool& trayOpen) { if (subUnit>=numDrives) return false; dinfo[subUnit].lastResult = cdrom[subUnit]->GetMediaTrayStatus(media,changed,trayOpen); return dinfo[subUnit].lastResult; -}; +} Bit32u CMscdex::GetDeviceStatus(Bit8u subUnit) { @@ -798,7 +796,7 @@ Bit32u CMscdex::GetDeviceStatus(Bit8u subUnit) (1<<9) | // Red book & HSG ((!media) << 11); // Drive is empty ? return status; -}; +} bool CMscdex::GetMediaStatus(Bit8u subUnit, Bit8u& status) { @@ -809,14 +807,14 @@ bool CMscdex::GetMediaStatus(Bit8u subUnit, Bit8u& status) return result; */ status = getSwapRequest() ? 0xFF : 0x01; return true; -}; +} bool CMscdex::LoadUnloadMedia(Bit8u subUnit, bool unload) { if (subUnit>=numDrives) return false; dinfo[subUnit].lastResult = cdrom[subUnit]->LoadUnloadMedia(unload); return dinfo[subUnit].lastResult; -}; +} bool CMscdex::SendDriverRequest(Bit16u drive, PhysPt data) { @@ -828,7 +826,7 @@ bool CMscdex::SendDriverRequest(Bit16u drive, PhysPt data) MSCDEX_Strategy_Handler(); MSCDEX_Interrupt_Handler(); return true; -}; +} Bit16u CMscdex::GetStatusWord(Bit8u subUnit,Bit16u status) { @@ -850,14 +848,14 @@ Bit16u CMscdex::GetStatusWord(Bit8u subUnit,Bit16u status) } dinfo[subUnit].lastResult = true; return status; -}; +} void CMscdex::InitNewMedia(Bit8u subUnit) { if (subUnitInitNewMedia(); } -}; +} static CMscdex* mscdex = 0; static PhysPt curReqheaderPtr = 0; @@ -1177,7 +1175,7 @@ static bool MSCDEX_Handler(void) { }; LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unknwon call : %04X",reg_ax); return true; -}; +} class device_MSCDEX : public DOS_Device { public: @@ -1216,28 +1214,28 @@ int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit) { int result = mscdex->AddDrive(driveLetter-'A',(char*)physicalPath,subUnit); return result; -}; +} int MSCDEX_RemoveDrive(char driveLetter) { if(!mscdex) return 0; return mscdex->RemoveDrive(driveLetter-'A'); -}; +} bool MSCDEX_HasDrive(char driveLetter) { return mscdex->HasDrive(driveLetter-'A'); -}; +} void MSCDEX_ReplaceDrive(CDROM_Interface* cdrom, Bit8u subUnit) { mscdex->ReplaceDrive(cdrom, subUnit); -}; +} bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name) { return mscdex->GetVolumeName(subUnit,name); -}; +} bool MSCDEX_HasMediaChanged(Bit8u subUnit) { @@ -1261,20 +1259,20 @@ bool MSCDEX_HasMediaChanged(Bit8u subUnit) leadOut[subUnit].fr = 0; } return true; -}; +} void MSCDEX_SetCDInterface(int intNr, int numCD) { useCdromInterface = intNr; forceCD = numCD; -}; +} void MSCDEX_ShutDown(Section* sec) { delete mscdex; mscdex = 0; curReqheaderPtr = 0; -}; +} void MSCDEX_Init(Section* sec) { @@ -1288,4 +1286,4 @@ void MSCDEX_Init(Section* sec) DOS_AddMultiplexHandler(MSCDEX_Handler); /* Create MSCDEX */ mscdex = new CMscdex; -}; +} diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 06697d7c..150b70f7 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.92 2009-03-29 09:34:18 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.93 2009-04-16 12:28:30 qbix79 Exp $ */ #include "dosbox.h" #include @@ -889,7 +889,7 @@ void LOADFIX::Run(void) } else { WriteOut(MSG_Get("PROGRAM_LOADFIX_ERROR"),kb); } -}; +} static void LOADFIX_ProgramStart(Program * * make) { *make=new LOADFIX; @@ -910,7 +910,7 @@ void RESCAN::Run(void) Drives[drive]->EmptyCache(); WriteOut(MSG_Get("PROGRAM_RESCAN_SUCCESS")); } -}; +} static void RESCAN_ProgramStart(Program * * make) { *make=new RESCAN; @@ -1330,7 +1330,7 @@ void KEYB::Run(void) { WriteOut(MSG_Get("PROGRAM_KEYB_INFO_LAYOUT"),dos.loaded_codepage,layout_name); } } -}; +} static void KEYB_ProgramStart(Program * * make) { *make=new KEYB; diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index a34e2bca..75f2a2b2 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.58 2009-03-04 21:08:22 c2woody Exp $ */ +/* $Id: drive_cache.cpp,v 1.59 2009-04-16 12:28:30 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" @@ -41,32 +41,27 @@ int fileInfoCounter = 0; -bool SortByName(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b) -{ +bool SortByName(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b) { return strcmp(a->shortname,b->shortname)<0; -}; +} -bool SortByNameRev(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b) -{ +bool SortByNameRev(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b) { return strcmp(a->shortname,b->shortname)>0; -}; +} -bool SortByDirName(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b) -{ +bool SortByDirName(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b) { // Directories first... if (a->isDir!=b->isDir) return (a->isDir>b->isDir); return strcmp(a->shortname,b->shortname)<0; -}; +} -bool SortByDirNameRev(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b) -{ +bool SortByDirNameRev(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b) { // Directories first... if (a->isDir!=b->isDir) return (a->isDir>b->isDir); return strcmp(a->shortname,b->shortname)>0; -}; +} -DOS_Drive_Cache::DOS_Drive_Cache(void) -{ +DOS_Drive_Cache::DOS_Drive_Cache(void) { dirBase = new CFileInfo; save_dir = 0; srchNr = 0; @@ -75,10 +70,9 @@ DOS_Drive_Cache::DOS_Drive_Cache(void) for (Bit32u i=0; iupdatelabel = allowupdate; Set_Label(vname,label,cdrom); LOG(LOG_DOSMISC,LOG_NORMAL)("DIRCACHE: Set volume label to %s",label); -}; +} -Bit16u DOS_Drive_Cache::GetFreeID(CFileInfo* dir) -{ +Bit16u DOS_Drive_Cache::GetFreeID(CFileInfo* dir) { for (Bit16u i=0; inextEntry>0)) dirSearch[srchNr]->nextEntry--; @@ -252,7 +237,7 @@ void DOS_Drive_Cache::DeleteEntry(const char* path, bool ignoreLastDir) dirSearch[i]->nextEntry--; } } -}; +} void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) { char expand[CROSS_LEN] = { 0 }; @@ -285,10 +270,9 @@ void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) { save_dir = 0; } -bool DOS_Drive_Cache::IsCachedIn(CFileInfo* curDir) -{ +bool DOS_Drive_Cache::IsCachedIn(CFileInfo* curDir) { return (curDir->fileList.size()>0); -}; +} bool DOS_Drive_Cache::GetShortName(const char* fullname, char* shortname) { @@ -314,10 +298,9 @@ bool DOS_Drive_Cache::GetShortName(const char* fullname, char* shortname) { }; } return false; -}; +} -int DOS_Drive_Cache::CompareShortname(const char* compareName, const char* shortName) -{ +int DOS_Drive_Cache::CompareShortname(const char* compareName, const char* shortName) { char const* cpos = strchr(shortName,'~'); if (cpos) { /* the following code is replaced as it's not safe when char* is 64 bits */ @@ -346,7 +329,7 @@ int DOS_Drive_Cache::CompareShortname(const char* compareName, const char* short return strncmp(compareName,shortName,compareCount1); } return strcmp(compareName,shortName); -}; +} Bitu DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name) { std::vector::size_type filelist_size = curDir->longNameList.size(); @@ -373,11 +356,10 @@ Bitu DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name) { }; } return foundNr+1; -}; +} -bool DOS_Drive_Cache::RemoveTrailingDot(char* shortname) +bool DOS_Drive_Cache::RemoveTrailingDot(char* shortname) { // remove trailing '.' if no extension is available (Linux compatibility) -{ size_t len = strlen(shortname); if (len && (shortname[len-1]=='.')) { if (len==1) return false; @@ -386,10 +368,9 @@ bool DOS_Drive_Cache::RemoveTrailingDot(char* shortname) return true; } return false; -}; +} -Bits DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) -{ +Bits DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) { std::vector::size_type filelist_size = curDir->fileList.size(); if (GCC_UNLIKELY(filelist_size<=0)) return -1; @@ -411,11 +392,10 @@ Bits DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) } // not available return -1; -}; +} -bool DOS_Drive_Cache::RemoveSpaces(char* str) +bool DOS_Drive_Cache::RemoveSpaces(char* str) { // Removes all spaces -{ char* curpos = str; char* chkpos = str; while (*chkpos!=0) { @@ -423,7 +403,7 @@ bool DOS_Drive_Cache::RemoveSpaces(char* str) } *curpos = 0; return (curpos!=chkpos); -}; +} void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) { Bits len = 0; @@ -590,10 +570,9 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* save_dir = curDir; return curDir; -}; +} -bool DOS_Drive_Cache::OpenDir(const char* path, Bit16u& id) -{ +bool DOS_Drive_Cache::OpenDir(const char* path, Bit16u& id) { char expand[CROSS_LEN] = {0}; CFileInfo* dir = FindDirInfo(path,expand); if (OpenDir(dir,expand,id)) { @@ -601,10 +580,9 @@ bool DOS_Drive_Cache::OpenDir(const char* path, Bit16u& id) return true; } return false; -}; +} -bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, const char* expand, Bit16u& id) -{ +bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, const char* expand, Bit16u& id) { id = GetFreeID(dir); dirSearch[id] = dir; char expandcopy [CROSS_LEN]; @@ -625,7 +603,7 @@ bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, const char* expand, Bit16u& id) } }; return false; -}; +} void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name, bool is_directory) { CFileInfo* info = new CFileInfo; From 415a6641c01e0db1474cb43c9eec404accf12d76 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 17 Apr 2009 11:33:51 +0000 Subject: [PATCH 3259/4131] Fix non-debug mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3347 --- include/logging.h | 2 +- src/dos/dos_files.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/logging.h b/include/logging.h index fa349718..ae3daae9 100644 --- a/include/logging.h +++ b/include/logging.h @@ -53,7 +53,7 @@ struct LOG 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 diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 363bb1bf..2dccf4c7 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.108 2009-04-16 12:16:52 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.109 2009-04-17 11:33:51 qbix79 Exp $ */ #include #include @@ -284,7 +284,7 @@ bool DOS_Rename(char const * const oldname,char const * const newname) { if (Drives[drivenew]->Rename(fullold,fullnew)) return true; /* If it still fails. which error should we give ? PATH NOT FOUND or EACCESS */ - LOG(LOG_FILES,LOG_NORMAL)("Rename fails on %c from %s to %s, no proper errorcode returned.",driveold+'A',oldname,newname); + LOG(LOG_FILES,LOG_NORMAL)("Rename fails for %s to %s, no proper errorcode returned.",oldname,newname); DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } From 1b6028a8be78b3a79e4909eff64f7f57770350e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 17 Apr 2009 17:24:47 +0000 Subject: [PATCH 3260/4131] add alternative opl2/opl3 emulator; fix opl clock rate Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3348 --- src/dosbox.cpp | 6 +- src/hardware/Makefile.am | 2 +- src/hardware/adlib.cpp | 79 ++- src/hardware/opl.cpp | 1452 ++++++++++++++++++++++++++++++++++++++ src/hardware/opl.h | 194 +++++ 5 files changed, 1722 insertions(+), 11 deletions(-) create mode 100644 src/hardware/opl.cpp create mode 100644 src/hardware/opl.h diff --git a/src/dosbox.cpp b/src/dosbox.cpp index d872a426..e8d63d8b 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.146 2009-02-15 20:01:08 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.147 2009-04-17 17:24:47 c2woody Exp $ */ #include #include @@ -503,10 +503,10 @@ void DOSBOX_Init(void) { Pstring->Set_values(oplmodes); Pstring->Set_help("Type of OPL emulation. On 'auto' the mode is determined by sblaster type. All OPL modes are Adlib-compatible, except for 'cms'."); - const char* oplemus[]={ "auto", 0}; + const char* oplemus[]={ "default", "old", 0}; Pstring = secprop->Add_string("oplemu",Property::Changeable::WhenIdle,"auto"); Pstring->Set_values(oplemus); - Pstring->Set_help("Provider for the OPL emulation. On 'auto' dosbox will use the best emulation."); + Pstring->Set_help("Provider for the OPL emulation."); Pint = secprop->Add_int("oplrate",Property::Changeable::WhenIdle,22050); Pint->Set_values(rates); diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index 2967ab71..1f602e11 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -2,7 +2,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include SUBDIRS = serialport -EXTRA_DIST = fmopl.c fmopl.h ymf262.h ymf262.c adlib.h +EXTRA_DIST = opl.cpp opl.h fmopl.c fmopl.h ymf262.h ymf262.c adlib.h noinst_LIBRARIES = libhardware.a diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 8576be18..4e699f33 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: adlib.cpp,v 1.33 2009-03-31 18:15:10 harekiet Exp $ */ +/* $Id: adlib.cpp,v 1.34 2009-04-17 17:24:47 c2woody Exp $ */ #include #include @@ -59,8 +59,67 @@ struct __MALLOCPTR { operator char*() const { return (char*)m_ptr; } }; + namespace OPL2 { - #define OPL2_INTERNAL_FREQ 3600000 // The OPL2 operates at 3.6MHz + #include "opl.cpp" + + struct Handler : public Adlib::Handler { + virtual void WriteReg( Bit32u reg, Bit8u val ) { + adlib_write(reg,val); + } + virtual Bit32u WriteAddr( Bit32u port, Bit8u val ) { + return val; + } + + virtual void Generate( MixerChannel* chan, Bitu samples ) { + Bit16s buf[1024]; + while( samples > 0 ) { + Bitu todo = samples > 1024 ? 1024 : samples; + samples -= todo; + adlib_getsample(buf, todo); + chan->AddSamples_m16( todo, buf ); + } + } + virtual void Init( Bitu rate ) { + adlib_init(rate); + } + ~Handler() { + } + }; +} + +namespace OPL3 { + #define OPLTYPE_IS_OPL3 + #include "opl.cpp" + + struct Handler : public Adlib::Handler { + virtual void WriteReg( Bit32u reg, Bit8u val ) { + adlib_write(reg,val); + } + virtual Bit32u WriteAddr( Bit32u port, Bit8u val ) { + adlib_write_index(port, val); + return index; + } + virtual void Generate( MixerChannel* chan, Bitu samples ) { + Bit16s buf[1024*2]; + while( samples > 0 ) { + Bitu todo = samples > 1024 ? 1024 : samples; + samples -= todo; + adlib_getsample(buf, todo); + chan->AddSamples_s16( todo, buf ); + } + } + virtual void Init( Bitu rate ) { + adlib_init(rate); + } + ~Handler() { + } + }; +} + + +namespace old_OPL2 { + #define OPL2_INTERNAL_FREQ 3579545 // The OPL2 operates at ~3.6MHz #define HAS_YM3812 1 #include "fmopl.c" @@ -95,8 +154,8 @@ namespace OPL2 { #undef OSD_CPU_H #undef TL_TAB_LEN -namespace OPL3 { - #define OPL3_INTERNAL_FREQ 14400000 // The OPL3 operates at 14.4MHz +namespace old_OPL3 { + #define OPL3_INTERNAL_FREQ 14318180 // The OPL3 operates at ~14.3MHz #define HAS_YMF262 1 #include "ymf262.c" @@ -640,7 +699,13 @@ public: std::string oplemu( section->Get_string( "oplemu" ) ); module.chan = MixerChan.Install(OPL_CallBack,rate,"FM"); - if ( 1 || oplemu == "auto") { + if (oplemu == "old") { + if ( oplmode == OPL_opl2 ) { + module.handler = new old_OPL2::Handler(); + } else { + module.handler = new old_OPL3::Handler(); + } + } else { if ( oplmode == OPL_opl2 ) { module.handler = new OPL2::Handler(); } else { @@ -676,8 +741,8 @@ public: ~OPL() { if ( module.capture ) delete module.capture; - OPL2::YM3812Shutdown(); - OPL3::YMF262Shutdown(); + old_OPL2::YM3812Shutdown(); + old_OPL3::YMF262Shutdown(); } }; diff --git a/src/hardware/opl.cpp b/src/hardware/opl.cpp new file mode 100644 index 00000000..94095f04 --- /dev/null +++ b/src/hardware/opl.cpp @@ -0,0 +1,1452 @@ +/* + * Copyright (C) 2002-2009 The DOSBox Team + * OPL2/OPL3 emulation library + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +/* + * Originally based on ADLIBEMU.C, an AdLib/OPL2 emulation library by Ken Silverman + * Copyright (C) 1998-2001 Ken Silverman + * Ken Silverman's official web site: "http://www.advsys.net/ken" + */ + + +#include +#include +#include "dosbox.h" +#include "opl.h" + + +static fltype recipsamp; // inverse of sampling rate +static Bit16s wavtable[WAVEPREC*3]; // wave form table + +// vibrato/tremolo tables +static Bit32s vib_table[VIBTAB_SIZE]; +static Bit32s trem_table[TREMTAB_SIZE*2]; + +static Bit32s vibval_const[BLOCKBUF_SIZE]; +static Bit32s tremval_const[BLOCKBUF_SIZE]; + +// vibrato value tables (used per-operator) +static Bit32s vibval_var1[BLOCKBUF_SIZE]; +static Bit32s vibval_var2[BLOCKBUF_SIZE]; +static Bit32s vibval_var3[BLOCKBUF_SIZE]; +static Bit32s vibval_var4[BLOCKBUF_SIZE]; + +// vibrato/trmolo value table pointers +static Bit32s *vibval1, *vibval2, *vibval3, *vibval4; +static Bit32s *tremval1, *tremval2, *tremval3, *tremval4; + + +// key scale level lookup table +static const fltype kslmul[4] = { + 0.0, 0.5, 0.25, 1.0 // -> 0, 3, 1.5, 6 dB/oct +}; + +// frequency multiplicator lookup table +static const fltype frqmul_tab[16] = { + 0.5,1,2,3,4,5,6,7,8,9,10,10,12,12,15,15 +}; +// calculated frequency multiplication values (depend on sampling rate) +static float frqmul[16]; + +// key scale levels +static Bit8u kslev[8][16]; + +// map a channel number to the register offset of the modulator (=register base) +static const Bit8u modulatorbase[9] = { + 0,1,2, + 8,9,10, + 16,17,18 +}; + +// map a register base to a modulator operator number or operator number +#if defined(OPLTYPE_IS_OPL3) +static const Bit8u regbase2modop[44] = { + 0,1,2,0,1,2,0,0,3,4,5,3,4,5,0,0,6,7,8,6,7,8, // first set + 18,19,20,18,19,20,0,0,21,22,23,21,22,23,0,0,24,25,26,24,25,26 // second set +}; +static const Bit8u regbase2op[44] = { + 0,1,2,9,10,11,0,0,3,4,5,12,13,14,0,0,6,7,8,15,16,17, // first set + 18,19,20,27,28,29,0,0,21,22,23,30,31,32,0,0,24,25,26,33,34,35 // second set +}; +#else +static const Bit8u regbase2modop[22] = { + 0,1,2,0,1,2,0,0,3,4,5,3,4,5,0,0,6,7,8,6,7,8 +}; +static const Bit8u regbase2op[22] = { + 0,1,2,9,10,11,0,0,3,4,5,12,13,14,0,0,6,7,8,15,16,17 +}; +#endif + + +// start of the waveform +static Bit32u waveform[8] = { + WAVEPREC, + WAVEPREC>>1, + WAVEPREC, + (WAVEPREC*3)>>2, + 0, + 0, + (WAVEPREC*5)>>2, + WAVEPREC<<1 +}; + +// length of the waveform as mask +static Bit32u wavemask[8] = { + WAVEPREC-1, + WAVEPREC-1, + (WAVEPREC>>1)-1, + (WAVEPREC>>1)-1, + WAVEPREC-1, + ((WAVEPREC*3)>>2)-1, + WAVEPREC>>1, + WAVEPREC-1 +}; + +// where the first entry resides +static Bit32u wavestart[8] = { + 0, + WAVEPREC>>1, + 0, + WAVEPREC>>2, + 0, + 0, + 0, + WAVEPREC>>3 +}; + +// envelope generator function constants +static fltype attackconst[4] = {1/2.82624,1/2.25280,1/1.88416,1/1.59744}; +static fltype decrelconst[4] = {1/39.28064,1/31.41608,1/26.17344,1/22.44608}; + + +void operator_advance(op_type* op_pt, Bit32s vib) { + op_pt->wfpos = op_pt->tcount; // waveform position + + // advance waveform time + op_pt->tcount += op_pt->tinc; + op_pt->tcount += (Bit32s)(op_pt->tinc)*vib/FIXEDPT; + + op_pt->generator_pos += generator_add; +} + +void operator_advance_drums(op_type* op_pt1, Bit32s vib1, op_type* op_pt2, Bit32s vib2, op_type* op_pt3, Bit32s vib3) { + Bit32u c1 = op_pt1->tcount/FIXEDPT; + Bit32u c3 = op_pt3->tcount/FIXEDPT; + Bit32u phasebit = (((c1 & 0x88) ^ ((c1<<5) & 0x80)) | ((c3 ^ (c3<<2)) & 0x20)) ? 0x02 : 0x00; + + Bit32u noisebit = rand()&1; + + Bit32u snare_phase_bit = (((Bitu)((op_pt1->tcount/FIXEDPT) / 0x100))&1); + + //Hihat + Bit32u inttm = (phasebit<<8) | (0x34<<(phasebit ^ (noisebit<<1))); + op_pt1->wfpos = inttm*FIXEDPT; // waveform position + // advance waveform time + op_pt1->tcount += op_pt1->tinc; + op_pt1->tcount += (Bit32s)(op_pt1->tinc)*vib1/FIXEDPT; + op_pt1->generator_pos += generator_add; + + //Snare + inttm = ((1+snare_phase_bit) ^ noisebit)<<8; + op_pt2->wfpos = inttm*FIXEDPT; // waveform position + // advance waveform time + op_pt2->tcount += op_pt2->tinc; + op_pt2->tcount += (Bit32s)(op_pt2->tinc)*vib2/FIXEDPT; + op_pt2->generator_pos += generator_add; + + //Cymbal + inttm = (1+phasebit)<<8; + op_pt3->wfpos = inttm*FIXEDPT; // waveform position + // advance waveform time + op_pt3->tcount += op_pt3->tinc; + op_pt3->tcount += (Bit32s)(op_pt3->tinc)*vib3/FIXEDPT; + op_pt3->generator_pos += generator_add; +} + + +// output level is sustained, mode changes only when operator is turned off (->release) +// or when the keep-sustained bit is turned off (->sustain_nokeep) +void operator_output(op_type* op_pt, Bit32s modulator, Bit32s trem) { + if (op_pt->op_state != OF_TYPE_OFF) { + op_pt->lastcval = op_pt->cval; + Bit32u i = (Bit32u)((op_pt->wfpos+modulator)/FIXEDPT); + + // wform: -16384 to 16383 (0x4000) + // trem : 32768 to 65535 (0x10000) + // step_amp: 0.0 to 1.0 + // vol : 1/2^14 to 1/2^29 (/0x4000; /1../0x8000) + + op_pt->cval = (Bit32s)(op_pt->step_amp*op_pt->vol*op_pt->cur_wform[i&op_pt->cur_wmask]*trem/16.0); + } +} + + +// no action, operator is off +void operator_off(op_type* /*op_pt*/) { +} + +// output level is sustained, mode changes only when operator is turned off (->release) +// or when the keep-sustained bit is turned off (->sustain_nokeep) +void operator_sustain(op_type* op_pt) { + Bit32u num_steps_add = op_pt->generator_pos/FIXEDPT; // number of (standardized) samples + for (Bit32u ct=0; ctcur_env_step++; + } + op_pt->generator_pos -= num_steps_add*FIXEDPT; +} + +// operator in release mode, if output level reaches zero the operator is turned off +void operator_release(op_type* op_pt) { + // ??? boundary? + if (op_pt->amp > 0.00000001) { + // release phase + op_pt->amp *= op_pt->releasemul; + } + + Bit32u num_steps_add = op_pt->generator_pos/FIXEDPT; // number of (standardized) samples + for (Bit32u ct=0; ctcur_env_step++; // sample counter + if ((op_pt->cur_env_step & op_pt->env_step_r)==0) { + if (op_pt->amp <= 0.00000001) { + // release phase finished, turn off this operator + op_pt->amp = 0.0; + if (op_pt->op_state == OF_TYPE_REL) { + op_pt->op_state = OF_TYPE_OFF; + } + } + op_pt->step_amp = op_pt->amp; + } + } + op_pt->generator_pos -= num_steps_add*FIXEDPT; +} + +// operator in decay mode, if sustain level is reached the output level is either +// kept (sustain level keep enabled) or the operator is switched into release mode +void operator_decay(op_type* op_pt) { + if (op_pt->amp > op_pt->sustain_level) { + // decay phase + op_pt->amp *= op_pt->decaymul; + } + + Bit32u num_steps_add = op_pt->generator_pos/FIXEDPT; // number of (standardized) samples + for (Bit32u ct=0; ctcur_env_step++; + if ((op_pt->cur_env_step & op_pt->env_step_d)==0) { + if (op_pt->amp <= op_pt->sustain_level) { + // decay phase finished, sustain level reached + if (op_pt->sus_keep) { + // keep sustain level (until turned off) + op_pt->op_state = OF_TYPE_SUS; + op_pt->amp = op_pt->sustain_level; + } else { + // next: release phase + op_pt->op_state = OF_TYPE_SUS_NOKEEP; + } + } + op_pt->step_amp = op_pt->amp; + } + } + op_pt->generator_pos -= num_steps_add*FIXEDPT; +} + +// operator in attack mode, if full output level is reached, +// the operator is switched into decay mode +void operator_attack(op_type* op_pt) { + op_pt->amp = ((op_pt->a3*op_pt->amp + op_pt->a2)*op_pt->amp + op_pt->a1)*op_pt->amp + op_pt->a0; + + Bit32u num_steps_add = op_pt->generator_pos/FIXEDPT; // number of (standardized) samples + for (Bit32u ct=0; ctcur_env_step++; // next sample + if ((op_pt->cur_env_step & op_pt->env_step_a)==0) { // check if next step already reached + if (op_pt->amp > 1.0) { + // attack phase finished, next: decay + op_pt->op_state = OF_TYPE_DEC; + op_pt->amp = 1.0; + op_pt->step_amp = 1.0; + } + op_pt->step_skip_pos <<= 1; + if (op_pt->step_skip_pos==0) op_pt->step_skip_pos = 1; + if (op_pt->step_skip_pos & op_pt->env_step_skip_a) { // check if required to skip next step + op_pt->step_amp = op_pt->amp; + } + } + } + op_pt->generator_pos -= num_steps_add*FIXEDPT; +} + + +typedef void (*optype_fptr)(op_type*); + +optype_fptr opfuncs[6] = { + operator_attack, + operator_decay, + operator_release, + operator_sustain, // sustain phase (keeping level) + operator_release, // sustain_nokeep phase (release-style) + operator_off +}; + +void change_attackrate(Bitu regbase, op_type* op_pt) { + Bits attackrate = adlibreg[ARC_ATTR_DECR+regbase]>>4; + if (attackrate) { + fltype f = (fltype)(pow(FL2,(fltype)attackrate+(op_pt->toff>>2)-1)*attackconst[op_pt->toff&3]*recipsamp); + // attack rate coefficients + op_pt->a0 = (fltype)(0.0377*f); + op_pt->a1 = (fltype)(10.73*f+1); + op_pt->a2 = (fltype)(-17.57*f); + op_pt->a3 = (fltype)(7.42*f); + + Bits step_skip = attackrate*4 + op_pt->toff; + Bits steps = step_skip >> 2; + op_pt->env_step_a = (1<<(steps<=12?12-steps:0))-1; + + Bits step_num = (step_skip<=48)?(4-(step_skip&3)):0; + static Bit8u step_skip_mask[5] = {0xff, 0xfe, 0xee, 0xba, 0xaa}; + op_pt->env_step_skip_a = step_skip_mask[step_num]; + +#if defined(OPLTYPE_IS_OPL3) + if (step_skip>=60) { +#else + if (step_skip>=62) { +#endif + op_pt->a0 = (fltype)(2.0); // something that triggers an immediate transition to amp:=1.0 + op_pt->a1 = (fltype)(0.0); + op_pt->a2 = (fltype)(0.0); + op_pt->a3 = (fltype)(0.0); + } + } else { + // attack disabled + op_pt->a0 = 0.0; + op_pt->a1 = 1.0; + op_pt->a2 = 0.0; + op_pt->a3 = 0.0; + op_pt->env_step_a = 0; + op_pt->env_step_skip_a = 0; + } +} + +void change_decayrate(Bitu regbase, op_type* op_pt) { + Bits decayrate = adlibreg[ARC_ATTR_DECR+regbase]&15; + // decaymul should be 1.0 when decayrate==0 + if (decayrate) { + fltype f = (fltype)(-7.4493*decrelconst[op_pt->toff&3]*recipsamp); + op_pt->decaymul = (fltype)(pow(FL2,f*pow(FL2,(fltype)(decayrate+(op_pt->toff>>2))))); + Bits steps = (decayrate*4 + op_pt->toff) >> 2; + op_pt->env_step_d = (1<<(steps<=12?12-steps:0))-1; + } else { + op_pt->decaymul = 1.0; + op_pt->env_step_d = 0; + } +} + +void change_releaserate(Bitu regbase, op_type* op_pt) { + Bits releaserate = adlibreg[ARC_SUSL_RELR+regbase]&15; + // releasemul should be 1.0 when releaserate==0 + if (releaserate) { + fltype f = (fltype)(-7.4493*decrelconst[op_pt->toff&3]*recipsamp); + op_pt->releasemul = (fltype)(pow(FL2,f*pow(FL2,(fltype)(releaserate+(op_pt->toff>>2))))); + Bits steps = (releaserate*4 + op_pt->toff) >> 2; + op_pt->env_step_r = (1<<(steps<=12?12-steps:0))-1; + } else { + op_pt->releasemul = 1.0; + op_pt->env_step_r = 0; + } +} + +void change_sustainlevel(Bitu regbase, op_type* op_pt) { + Bits sustainlevel = adlibreg[ARC_SUSL_RELR+regbase]>>4; + // sustainlevel should be 0.0 when sustainlevel==15 (max) + if (sustainlevel<15) { + op_pt->sustain_level = (fltype)(pow(FL2,(fltype)sustainlevel * (-FL05))); + } else { + op_pt->sustain_level = 0.0; + } +} + +void change_waveform(Bitu regbase, op_type* op_pt) { +#if defined(OPLTYPE_IS_OPL3) + if (regbase>=ARC_SECONDSET) regbase -= (ARC_SECONDSET-22); // second set starts at 22 +#endif + // waveform selection + op_pt->cur_wmask = wavemask[wave_sel[regbase]]; + op_pt->cur_wform = &wavtable[waveform[wave_sel[regbase]]]; + // (might need to be adapted to waveform type here...) +} + +void change_keepsustain(Bitu regbase, op_type* op_pt) { + op_pt->sus_keep = (adlibreg[ARC_TVS_KSR_MUL+regbase]&0x20)>0; + if (op_pt->op_state==OF_TYPE_SUS) { + if (!op_pt->sus_keep) op_pt->op_state = OF_TYPE_SUS_NOKEEP; + } else if (op_pt->op_state==OF_TYPE_SUS_NOKEEP) { + if (op_pt->sus_keep) op_pt->op_state = OF_TYPE_SUS; + } +} + +// enable/disable vibrato/tremolo LFO effects +void change_vibrato(Bitu regbase, op_type* op_pt) { + op_pt->vibrato = (adlibreg[ARC_TVS_KSR_MUL+regbase]&0x40)!=0; + op_pt->tremolo = (adlibreg[ARC_TVS_KSR_MUL+regbase]&0x80)!=0; +} + +// change amount of self-feedback +void change_feedback(Bitu chanbase, op_type* op_pt) { + Bits feedback = adlibreg[ARC_FEEDBACK+chanbase]&14; + if (feedback) op_pt->mfbi = (Bit32s)(pow(FL2,(fltype)((feedback>>1)+8))); + else op_pt->mfbi = 0; +} + +void change_frequency(Bitu chanbase, Bitu regbase, op_type* op_pt) { + // frequency + Bit32u frn = ((((Bit32u)adlibreg[ARC_KON_BNUM+chanbase])&3)<<8) + (Bit32u)adlibreg[ARC_FREQ_NUM+chanbase]; + // block number/octave + Bit32u oct = ((((Bit32u)adlibreg[ARC_KON_BNUM+chanbase])>>2)&7); + op_pt->freq_high = (Bit32s)((frn>>7)&7); + + // keysplit + Bit32u note_sel = (adlibreg[8]>>6)&1; + op_pt->toff = ((frn>>9)&(note_sel^1)) | ((frn>>8)¬e_sel); + op_pt->toff += (oct<<1); + + // envelope scaling (KSR) + if (!(adlibreg[ARC_TVS_KSR_MUL+regbase]&0x10)) op_pt->toff >>= 2; + + // 20+a0+b0: + op_pt->tinc = (Bit32u)((((fltype)(frn<>6]*kslev[oct][frn>>6]); + op_pt->vol = (fltype)(pow(FL2,(fltype)(vol_in * -0.125 - 14))); + + // operator frequency changed, care about features that depend on it + change_attackrate(regbase,op_pt); + change_decayrate(regbase,op_pt); + change_releaserate(regbase,op_pt); +} + +void enable_operator(Bitu regbase, op_type* op_pt, Bit32u act_type) { + // check if this is really an off-on transition + if (op_pt->act_state == OP_ACT_OFF) { + Bits wselbase = regbase; + if (wselbase>=ARC_SECONDSET) wselbase -= (ARC_SECONDSET-22); // second set starts at 22 + + op_pt->tcount = wavestart[wave_sel[wselbase]]*FIXEDPT; + + // start with attack mode + op_pt->op_state = OF_TYPE_ATT; + op_pt->act_state |= act_type; + } +} + +void disable_operator(op_type* op_pt, Bit32u act_type) { + // check if this is really an on-off transition + if (op_pt->act_state != OP_ACT_OFF) { + op_pt->act_state &= (~act_type); + if (op_pt->act_state == OP_ACT_OFF) { + if (op_pt->op_state != OF_TYPE_OFF) op_pt->op_state = OF_TYPE_REL; + } + } +} + +void adlib_init(Bit32u samplerate) { + Bits i, j, oct; + + int_samplerate = samplerate; + + generator_add = (Bit32u)(INTFREQU*FIXEDPT/int_samplerate); + + + memset((void *)adlibreg,0,sizeof(adlibreg)); + memset((void *)op,0,sizeof(op_type)*MAXOPERATORS); + memset((void *)wave_sel,0,sizeof(wave_sel)); + + for (i=0;i=0;i--) { + frqmul[i] = (fltype)(frqmul_tab[i]*INTFREQU/(fltype)WAVEPREC*(fltype)FIXEDPT*recipsamp); + } + + status = 0; + index = 0; + + + // create vibrato table + vib_table[0] = 8; + vib_table[1] = 4; + vib_table[2] = 0; + vib_table[3] = -4; + for (i=4; i -0.5/6 to 0) + for (i=14; i<41; i++) trem_table_int[i] = -i+14; // downwards (26 to 0 -> 0 to -1/6) + for (i=41; i<53; i++) trem_table_int[i] = i-40-26; // upwards (1 to 12 -> -1/6 to -0.5/6) + + for (i=0; i>1);i++) { + wavtable[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<1) )*PI*2/WAVEPREC)); + wavtable[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<1)+1)*PI*2/WAVEPREC)); + wavtable[i] = wavtable[(i<<1) +WAVEPREC]; + // table to be verified, alternative: (zero-less) +/* wavtable[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)(((i*2+1)<<1)-1)*PI/WAVEPREC)); + wavtable[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)(((i*2+1)<<1) )*PI/WAVEPREC)); + wavtable[i] = wavtable[(i<<1)-1+WAVEPREC]; */ + } + for (i=0;i<(WAVEPREC>>3);i++) { + wavtable[i+(WAVEPREC<<1)] = wavtable[i+(WAVEPREC>>3)]-16384; + wavtable[i+((WAVEPREC*17)>>3)] = wavtable[i+(WAVEPREC>>2)]+16384; + } + + // key scale level table verified ([table in book]*8/3) + kslev[7][0] = 0; kslev[7][1] = 24; kslev[7][2] = 32; kslev[7][3] = 37; + kslev[7][4] = 40; kslev[7][5] = 43; kslev[7][6] = 45; kslev[7][7] = 47; + kslev[7][8] = 48; + for (i=9;i<16;i++) kslev[7][i] = (Bit8u)(i+41); + for (j=6;j>=0;j--) { + for (i=0;i<16;i++) { + oct = (Bits)kslev[j+1][i]-8; + if (oct < 0) oct = 0; + kslev[j][i] = (Bit8u)oct; + } + } + } + +} + + + +void adlib_write(Bitu idx, Bit8u val) { + Bit32u second_set = idx&0x100; + Bit8u old_val = adlibreg[idx]; + adlibreg[idx] = val; + + switch (idx&0xf0) { + case ARC_CONTROL: + // here we check for the second set registers, too: + switch (idx) { + case 0x02: // timer1 counter + case 0x03: // timer2 counter + break; + case 0x04: + // IRQ reset, timer mask/start + if (val&0x80) { + // clear IRQ bits in status register + status &= ~0x60; + } else { + status = 0; + } + break; +#if defined(OPLTYPE_IS_OPL3) + case 0x04|ARC_SECONDSET: + // 4op enable/disable switches for each possible channel + op[0].is_4op = (val&1)>0; + op[3].is_4op_attached = op[0].is_4op; + op[1].is_4op = (val&2)>0; + op[4].is_4op_attached = op[1].is_4op; + op[2].is_4op = (val&4)>0; + op[5].is_4op_attached = op[2].is_4op; + op[18].is_4op = (val&8)>0; + op[21].is_4op_attached = op[18].is_4op; + op[19].is_4op = (val&16)>0; + op[22].is_4op_attached = op[19].is_4op; + op[20].is_4op = (val&32)>0; + op[23].is_4op_attached = op[20].is_4op; + break; + case 0x05|ARC_SECONDSET: + break; +#endif + case 0x08: + // CSW, note select + break; + default: + break; + } + break; + case ARC_TVS_KSR_MUL: + case ARC_TVS_KSR_MUL+0x10: { + // tremolo/vibrato/sustain keeping enabled; key scale rate; frequency multiplication + int num = idx&7; + Bitu base = (idx-ARC_TVS_KSR_MUL)&0xff; + if ((num<6) && (base<22)) { + Bitu modop = regbase2modop[second_set?(base+22):base]; + Bitu regbase = base+second_set; + Bitu chanbase = second_set?(modop-18+ARC_SECONDSET):modop; + + // change tremolo/vibrato and sustain keeping of this operator + op_type* op_ptr = &op[modop+((num<3) ? 0 : 9)]; + change_keepsustain(regbase,op_ptr); + change_vibrato(regbase,op_ptr); + + // change frequency calculations of this operator as + // key scale rate and frequency multiplicator can be changed +#if defined(OPLTYPE_IS_OPL3) + if ((adlibreg[0x105]&1) && (op[modop].is_4op_attached)) { + // operator uses frequency of channel + change_frequency(chanbase-3,regbase,op_ptr); + } else { + change_frequency(chanbase,regbase,op_ptr); + } +#else + change_frequency(chanbase,base,op_ptr); +#endif + } + } + break; + case ARC_KSL_OUTLEV: + case ARC_KSL_OUTLEV+0x10: { + // key scale level; output rate + int num = idx&7; + Bitu base = (idx-ARC_KSL_OUTLEV)&0xff; + if ((num<6) && (base<22)) { + Bitu modop = regbase2modop[second_set?(base+22):base]; + Bitu chanbase = second_set?(modop-18+ARC_SECONDSET):modop; + + // change frequency calculations of this operator as + // key scale level and output rate can be changed + op_type* op_ptr = &op[modop+((num<3) ? 0 : 9)]; +#if defined(OPLTYPE_IS_OPL3) + Bitu regbase = base+second_set; + if ((adlibreg[0x105]&1) && (op[modop].is_4op_attached)) { + // operator uses frequency of channel + change_frequency(chanbase-3,regbase,op_ptr); + } else { + change_frequency(chanbase,regbase,op_ptr); + } +#else + change_frequency(chanbase,base,op_ptr); +#endif + } + } + break; + case ARC_ATTR_DECR: + case ARC_ATTR_DECR+0x10: { + // attack/decay rates + int num = idx&7; + Bitu base = (idx-ARC_ATTR_DECR)&0xff; + if ((num<6) && (base<22)) { + Bitu regbase = base+second_set; + + // change attack rate and decay rate of this operator + op_type* op_ptr = &op[regbase2op[second_set?(base+22):base]]; + change_attackrate(regbase,op_ptr); + change_decayrate(regbase,op_ptr); + } + } + break; + case ARC_SUSL_RELR: + case ARC_SUSL_RELR+0x10: { + // sustain level; release rate + int num = idx&7; + Bitu base = (idx-ARC_SUSL_RELR)&0xff; + if ((num<6) && (base<22)) { + Bitu regbase = base+second_set; + + // change sustain level and release rate of this operator + op_type* op_ptr = &op[regbase2op[second_set?(base+22):base]]; + change_releaserate(regbase,op_ptr); + change_sustainlevel(regbase,op_ptr); + } + } + break; + case ARC_FREQ_NUM: { + // 0xa0-0xa8 low8 frequency + Bitu base = (idx-ARC_FREQ_NUM)&0xff; + if (base<9) { + Bits opbase = second_set?(base+18):base; +#if defined(OPLTYPE_IS_OPL3) + if ((adlibreg[0x105]&1) && op[opbase].is_4op_attached) break; +#endif + // regbase of modulator: + Bits modbase = modulatorbase[base]+second_set; + + Bitu chanbase = base+second_set; + + change_frequency(chanbase,modbase,&op[opbase]); + change_frequency(chanbase,modbase+3,&op[opbase+9]); +#if defined(OPLTYPE_IS_OPL3) + // for 4op channels all four operators are modified to the frequency of the channel + if ((adlibreg[0x105]&1) && op[second_set?(base+18):base].is_4op) { + change_frequency(chanbase,modbase+8,&op[opbase+3]); + change_frequency(chanbase,modbase+3+8,&op[opbase+3+9]); + } +#endif + } + } + break; + case ARC_KON_BNUM: { + if (idx == ARC_PERC_MODE) { +#if defined(OPLTYPE_IS_OPL3) + if (second_set) return; +#endif + + if ((val&0x30) == 0x30) { // BassDrum active + enable_operator(16,&op[6],OP_ACT_PERC); + change_frequency(6,16,&op[6]); + enable_operator(16+3,&op[6+9],OP_ACT_PERC); + change_frequency(6,16+3,&op[6+9]); + } else { + disable_operator(&op[6],OP_ACT_PERC); + disable_operator(&op[6+9],OP_ACT_PERC); + } + if ((val&0x28) == 0x28) { // Snare active + enable_operator(17+3,&op[16],OP_ACT_PERC); + change_frequency(7,17+3,&op[16]); + } else { + disable_operator(&op[16],OP_ACT_PERC); + } + if ((val&0x24) == 0x24) { // TomTom active + enable_operator(18,&op[8],OP_ACT_PERC); + change_frequency(8,18,&op[8]); + } else { + disable_operator(&op[8],OP_ACT_PERC); + } + if ((val&0x22) == 0x22) { // Cymbal active + enable_operator(18+3,&op[8+9],OP_ACT_PERC); + change_frequency(8,18+3,&op[8+9]); + } else { + disable_operator(&op[8+9],OP_ACT_PERC); + } + if ((val&0x21) == 0x21) { // Hihat active + enable_operator(17,&op[7],OP_ACT_PERC); + change_frequency(7,17,&op[7]); + } else { + disable_operator(&op[7],OP_ACT_PERC); + } + + break; + } + // regular 0xb0-0xb8 + Bitu base = (idx-ARC_KON_BNUM)&0xff; + if (base<9) { + Bits opbase = second_set?(base+18):base; +#if defined(OPLTYPE_IS_OPL3) + if ((adlibreg[0x105]&1) && op[opbase].is_4op_attached) break; +#endif + // regbase of modulator: + Bits modbase = modulatorbase[base]+second_set; + + if (val&32) { + // operator switched on + enable_operator(modbase,&op[opbase],OP_ACT_NORMAL); // modulator (if 2op) + enable_operator(modbase+3,&op[opbase+9],OP_ACT_NORMAL); // carrier (if 2op) +#if defined(OPLTYPE_IS_OPL3) + // for 4op channels all four operators are switched on + if ((adlibreg[0x105]&1) && op[opbase].is_4op) { + // turn on chan+3 operators as well + enable_operator(modbase+8,&op[opbase+3],OP_ACT_NORMAL); + enable_operator(modbase+3+8,&op[opbase+3+9],OP_ACT_NORMAL); + } +#endif + } else { + // operator switched off + disable_operator(&op[opbase],OP_ACT_NORMAL); + disable_operator(&op[opbase+9],OP_ACT_NORMAL); +#if defined(OPLTYPE_IS_OPL3) + // for 4op channels all four operators are switched off + if ((adlibreg[0x105]&1) && op[opbase].is_4op) { + // turn off chan+3 operators as well + disable_operator(&op[opbase+3],OP_ACT_NORMAL); + disable_operator(&op[opbase+3+9],OP_ACT_NORMAL); + } +#endif + } + + Bitu chanbase = base+second_set; + + // change frequency calculations of modulator and carrier (2op) as + // the frequency of the channel has changed + change_frequency(chanbase,modbase,&op[opbase]); + change_frequency(chanbase,modbase+3,&op[opbase+9]); +#if defined(OPLTYPE_IS_OPL3) + // for 4op channels all four operators are modified to the frequency of the channel + if ((adlibreg[0x105]&1) && op[second_set?(base+18):base].is_4op) { + // change frequency calculations of chan+3 operators as well + change_frequency(chanbase,modbase+8,&op[opbase+3]); + change_frequency(chanbase,modbase+3+8,&op[opbase+3+9]); + } +#endif + } + } + break; + case ARC_FEEDBACK: { + // 0xc0-0xc8 feedback/modulation type (AM/FM) + Bitu base = (idx-ARC_FEEDBACK)&0xff; + if (base<9) { + Bits opbase = second_set?(base+18):base; + Bitu chanbase = base+second_set; + change_feedback(chanbase,&op[opbase]); +#if defined(OPLTYPE_IS_OPL3) + // OPL3 panning + op[opbase].left_pan = ((val&0x10)>>4)+((val&0x40)>>6); + op[opbase].right_pan = ((val&0x20)>>5)+((val&0x80)>>7); +#endif + } + } + break; + case ARC_WAVE_SEL: + case ARC_WAVE_SEL+0x10: { + int num = idx&7; + Bitu base = (idx-ARC_WAVE_SEL)&0xff; + if ((num<6) && (base<22)) { +#if defined(OPLTYPE_IS_OPL3) + Bits wselbase = second_set?(base+22):base; // for easier mapping onto wave_sel[] + // change waveform + if (adlibreg[0x105]&1) wave_sel[wselbase] = val&7; // opl3 mode enabled, all waveforms accessible + else wave_sel[wselbase] = val&3; + op_type* op_ptr = &op[regbase2modop[wselbase]+((num<3) ? 0 : 9)]; + change_waveform(wselbase,op_ptr); +#else + if (adlibreg[0x01]&0x20) { + // wave selection enabled, change waveform + wave_sel[base] = val&3; + op_type* op_ptr = &op[regbase2modop[base]+((num<3) ? 0 : 9)]; + change_waveform(base,op_ptr); + } +#endif + } + } + break; + default: + break; + } +} + + +Bitu adlib_reg_read(Bitu port) { +#if defined(OPLTYPE_IS_OPL3) + // opl3-detection routines require ret&6 to be zero + if ((port&1)==0) { + return status; + } + return 0x00; +#else + // opl2-detection routines require ret&6 to be 6 + if ((port&1)==0) { + return status|6; + } + return 0xff; +#endif +} + +void adlib_write_index(Bitu port, Bit8u val) { + index = val; +#if defined(OPLTYPE_IS_OPL3) + if ((port&3)!=0) { + // possibly second set + if (((adlibreg[0x105]&1)!=0) || (index==5)) index |= ARC_SECONDSET; + } +#endif +} + +static void INLINE clipit16(Bit32s ival, Bit16s* outval) { + if (ival<32768) { + if (ival>-32769) { + *outval=(Bit16s)ival; + } else { + *outval = -32768; + } + } else { + *outval = 32767; + } +} + + + +// be careful with this +// uses cptr and chanval, outputs into outbufl(/outbufr) +// for opl3 check if opl3-mode is enabled (which uses stereo panning) +#undef CHANVAL_OUT +#if defined(OPLTYPE_IS_OPL3) +#define CHANVAL_OUT \ + if (adlibreg[0x105]&1) { \ + outbufl[i] += chanval*cptr[0].left_pan; \ + outbufr[i] += chanval*cptr[0].right_pan; \ + } else { \ + outbufl[i] += chanval*2; \ + } +#else +#define CHANVAL_OUT \ + outbufl[i] += chanval; +#endif + +void adlib_getsample(Bit16s* sndptr, Bits numsamples) { + Bits i, endsamples; + op_type* cptr; + + Bit32s outbufl[BLOCKBUF_SIZE]; +#if defined(OPLTYPE_IS_OPL3) + // second output buffer (right channel for opl3 stereo) + Bit32s outbufr[BLOCKBUF_SIZE]; +#endif + + // vibrato/tremolo lookup tables (global, to possibly be used by all operators) + Bit32s vib_lut[BLOCKBUF_SIZE]; + Bit32s trem_lut[BLOCKBUF_SIZE]; + + Bits samples_to_process = numsamples; + + for (Bits cursmp=0; cursmpBLOCKBUF_SIZE) endsamples = BLOCKBUF_SIZE; + + memset((void*)&outbufl,0,endsamples*sizeof(Bit32s)); +#if defined(OPLTYPE_IS_OPL3) + // clear second output buffer (opl3 stereo) + if (adlibreg[0x105]&1) memset((void*)&outbufr,0,endsamples*sizeof(Bit32s)); +#endif + + // calculate vibrato/tremolo lookup tables + Bit32s vib_tshift = ((adlibreg[ARC_PERC_MODE]&0x40)==0) ? 1 : 0; // 14cents/7cents switching + for (i=0;i=VIBTAB_SIZE) vibtab_pos-=VIBTAB_SIZE*FIXEDPT_LFO; + vib_lut[i] = vib_table[vibtab_pos/FIXEDPT_LFO]>>vib_tshift; // 14cents (14/100 of a semitone) or 7cents + + // cycle through tremolo table + tremtab_pos += tremtab_add; + if (tremtab_pos/FIXEDPT_LFO>=TREMTAB_SIZE) tremtab_pos-=TREMTAB_SIZE*FIXEDPT_LFO; + if (adlibreg[ARC_PERC_MODE]&0x80) trem_lut[i] = trem_table[tremtab_pos/FIXEDPT_LFO]; + else trem_lut[i] = trem_table[TREMTAB_SIZE+tremtab_pos/FIXEDPT_LFO]; + } + + if (adlibreg[ARC_PERC_MODE]&0x20) { + //BassDrum + cptr = &op[6]; + if (adlibreg[ARC_FEEDBACK+6]&1) { + // additive synthesis + if (cptr[9].op_state != OF_TYPE_OFF) { + if (cptr[9].vibrato) { + vibval1 = vibval_var1; + for (i=0;i=0; cur_ch--) { + // skip drum/percussion operators + if ((adlibreg[ARC_PERC_MODE]&0x20) && (cur_ch >= 6) && (cur_ch < 9)) continue; + + Bitu k = cur_ch; +#if defined(OPLTYPE_IS_OPL3) + if (cur_ch < 9) { + cptr = &op[cur_ch]; + } else { + cptr = &op[cur_ch+9]; // second set is operator18-operator35 + k += (-9+256); // second set uses registers 0x100 onwards + } + // check if this operator is part of a 4-op + if ((adlibreg[0x105]&1) && cptr->is_4op_attached) continue; +#else + cptr = &op[cur_ch]; +#endif + + // check for FM/AM + if (adlibreg[ARC_FEEDBACK+k]&1) { +#if defined(OPLTYPE_IS_OPL3) + if ((adlibreg[0x105]&1) && cptr->is_4op) { + if (adlibreg[ARC_FEEDBACK+k+3]&1) { + // AM-AM-style synthesis (op1[fb] + (op2 * op3) + op4) + if (cptr[0].op_state != OF_TYPE_OFF) { + if (cptr[0].vibrato) { + vibval1 = vibval_var1; + for (i=0;iis_4op) { + if (adlibreg[ARC_FEEDBACK+k+3]&1) { + // FM-AM-style synthesis ((op1[fb] * op2) + (op3 * op4)) + if ((cptr[0].op_state != OF_TYPE_OFF) || (cptr[9].op_state != OF_TYPE_OFF)) { + if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) { + vibval1 = vibval_var1; + for (i=0;i +typedef uintptr_t Bitu; +typedef intptr_t Bits; +typedef uint32_t Bit32u; +typedef int32_t Bit32s; +typedef uint16_t Bit16u; +typedef int16_t Bit16s; +typedef uint8_t Bit8u; +typedef int8_t Bit8s; +*/ + +#undef NUM_CHANNELS +#if defined(OPLTYPE_IS_OPL3) +#define NUM_CHANNELS 18 +#else +#define NUM_CHANNELS 9 +#endif + +#define MAXOPERATORS (NUM_CHANNELS*2) + + +#define FL05 ((fltype)0.5) +#define FL2 ((fltype)2.0) +#define PI ((fltype)3.1415926535897932384626433832795) + + +#define FIXEDPT 0x10000 // fixed-point calculations using 16+16 +#define FIXEDPT_LFO 0x1000000 // fixed-point calculations using 8+24 + +#define WAVEPREC 1024 // waveform precision (10 bits) + +#define INTFREQU ((fltype)(14318180.0 / 288.0)) // clocking of the chip + + +#define OF_TYPE_ATT 0 +#define OF_TYPE_DEC 1 +#define OF_TYPE_REL 2 +#define OF_TYPE_SUS 3 +#define OF_TYPE_SUS_NOKEEP 4 +#define OF_TYPE_OFF 5 + +#define ARC_CONTROL 0x00 +#define ARC_TVS_KSR_MUL 0x20 +#define ARC_KSL_OUTLEV 0x40 +#define ARC_ATTR_DECR 0x60 +#define ARC_SUSL_RELR 0x80 +#define ARC_FREQ_NUM 0xa0 +#define ARC_KON_BNUM 0xb0 +#define ARC_PERC_MODE 0xbd +#define ARC_FEEDBACK 0xc0 +#define ARC_WAVE_SEL 0xe0 + +#define ARC_SECONDSET 0x100 // second operator set for OPL3 + + +#define OP_ACT_OFF 0x00 +#define OP_ACT_NORMAL 0x01 // regular channel activated (bitmasked) +#define OP_ACT_PERC 0x02 // percussion channel activated (bitmasked) + +#define BLOCKBUF_SIZE 512 + + +// vibrato constants +#define VIBTAB_SIZE 8 +#define VIBFAC 70/50000 // no braces, integer mul/div + +// tremolo constants and table +#define TREMTAB_SIZE 53 +#define TREM_FREQ ((fltype)(3.7)) // tremolo at 3.7hz + + +/* operator struct definition + For OPL2 all 9 channels consist of two operators each, carrier and modulator. + Channel x has operators x as modulator and operators (9+x) as carrier. + For OPL3 all 18 channels consist either of two operators (2op mode) or four + operators (4op mode) which is determined through register4 of the second + adlib register set. + Only the channels 0,1,2 (first set) and 9,10,11 (second set) can act as + 4op channels. The two additional operators for a channel y come from the + 2op channel y+3 so the operatorss y, (9+y), y+3, (9+y)+3 make up a 4op + channel. +*/ +typedef struct operator_struct { + Bit32s cval, lastcval; // current output/last output (used for feedback) + Bit32u tcount, wfpos, tinc; // time (position in waveform) and time increment + fltype amp, step_amp; // and amplification (envelope) + fltype vol; // volume + fltype sustain_level; // sustain level + Bit32s mfbi; // feedback amount + fltype a0, a1, a2, a3; // attack rate function coefficients + fltype decaymul, releasemul; // decay/release rate functions + Bit32u op_state; // current state of operator (attack/decay/sustain/release/off) + Bit32u toff; + Bit32s freq_high; // highest three bits of the frequency, used for vibrato calculations + Bit16s* cur_wform; // start of selected waveform + Bit32u cur_wmask; // mask for selected waveform + Bit32u act_state; // activity state (regular, percussion) + bool sus_keep; // keep sustain level when decay finished + bool vibrato,tremolo; // vibrato/tremolo enable bits + + // variables used to provide non-continuous envelopes + Bit32u generator_pos; // for non-standard sample rates we need to determine how many samples have passed + Bits cur_env_step; // current (standardized) sample position + Bits env_step_a,env_step_d,env_step_r; // number of std samples of one step (for attack/decay/release mode) + Bit8u step_skip_pos; // position of 8-cyclic step skipping (always 2^x to check against mask) + Bits env_step_skip_a; // bitmask that determines if a step is skipped (respective bit is zero then) + +#if defined(OPLTYPE_IS_OPL3) + bool is_4op,is_4op_attached; // base of a 4op channel/part of a 4op channel + Bit32s left_pan,right_pan; // opl3 stereo panning amount +#endif +} op_type; + +// per-chip variables +Bitu chip_num; +op_type op[MAXOPERATORS]; + +Bits int_samplerate; + +Bit8u status; +Bit32u index; +#if defined(OPLTYPE_IS_OPL3) +Bit8u adlibreg[512]; // adlib register set (including second set) +Bit8u wave_sel[44]; // waveform selection +#else +Bit8u adlibreg[256]; // adlib register set +Bit8u wave_sel[22]; // waveform selection +#endif + + +// vibrato/tremolo increment/counter +Bit32u vibtab_pos; +Bit32u vibtab_add; +Bit32u tremtab_pos; +Bit32u tremtab_add; + + +// enable an operator +void enable_operator(Bitu regbase, op_type* op_pt); + +// functions to change parameters of an operator +void change_frequency(Bitu chanbase, Bitu regbase, op_type* op_pt); + +void change_attackrate(Bitu regbase, op_type* op_pt); +void change_decayrate(Bitu regbase, op_type* op_pt); +void change_releaserate(Bitu regbase, op_type* op_pt); +void change_sustainlevel(Bitu regbase, op_type* op_pt); +void change_waveform(Bitu regbase, op_type* op_pt); +void change_keepsustain(Bitu regbase, op_type* op_pt); +void change_vibrato(Bitu regbase, op_type* op_pt); +void change_feedback(Bitu chanbase, op_type* op_pt); + +// general functions +void adlib_init(Bit32u samplerate); +void adlib_write(Bitu idx, Bit8u val); +void adlib_getsample(Bit16s* sndptr, Bits numsamples); + +Bitu adlib_reg_read(Bitu port); +void adlib_write_index(Bitu port, Bit8u val); + +static Bit32u generator_add; // should be a chip parameter From d54f7a4edf65c3504a97c229a85cd704915e3041 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 22 Apr 2009 12:28:51 +0000 Subject: [PATCH 3261/4131] change E_Exit to LOG + cleanup. Allows people do weird things. (deleting the bat file while running the bat file) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3349 --- src/shell/shell_batch.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 969b5efd..f3c3c42f 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.33 2009-04-02 19:08:26 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.34 2009-04-22 12:28:51 qbix79 Exp $ */ #include #include @@ -50,7 +50,9 @@ BatchFile::~BatchFile() { bool BatchFile::ReadLine(char * line) { //Open the batchfile and seek to stored postion if (!DOS_OpenFile(cmd->GetFileName(),128,&file_handle)) { - E_Exit("SHELL:ReadLine Can't open BatchFile %s",cmd->GetFileName()); + LOG(LOG_MISC,LOG_ERROR)("ReadLine Can't open BatchFile %s",cmd->GetFileName()); + delete this; + return false; } DOS_SeekFile(file_handle,&(this->location),DOS_SEEK_SET); @@ -142,7 +144,9 @@ emptyline: bool BatchFile::Goto(char * where) { //Open bat file and search for the where string if (!DOS_OpenFile(cmd->GetFileName(),128,&file_handle)) { - E_Exit("SHELL:Goto Can't open BatchFile %s",cmd->GetFileName()); + LOG(LOG_MISC,LOG_ERROR)("SHELL:Goto Can't open BatchFile %s",cmd->GetFileName()); + delete this; + return false; } char cmd_buffer[CMD_MAXLINE]; From b35f4027ccf8b2c16218178336746148231a37e5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 25 Apr 2009 06:59:54 +0000 Subject: [PATCH 3262/4131] Fix some warnings in pedantic mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3350 --- src/fpu/fpu_instructions.h | 4 ++-- src/gui/sdl_mapper.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index e0971d31..cc51a568 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.31 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.32 2009-04-25 06:59:54 qbix79 Exp $ */ static void FPU_FINIT(void) { @@ -321,7 +321,7 @@ static void FPU_FDIVR(Bitu st, Bitu other){ fpu.regs[st].d= fpu.regs[other].d/fpu.regs[st].d; // flags and such :) return; -}; +} static void FPU_FMUL(Bitu st, Bitu other){ fpu.regs[st].d*=fpu.regs[other].d; diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 949487b1..896790db 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.57 2009-02-11 22:16:05 c2woody Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.58 2009-04-25 06:59:54 qbix79 Exp $ */ #include #include @@ -53,7 +53,7 @@ enum BB_Types { enum BC_Types { BC_Mod1,BC_Mod2,BC_Mod3, - BC_Hold, + BC_Hold }; #define BMOD_Mod1 0x0001 From 150dd1443363cfe22e4240061f53643f714b9faa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 25 Apr 2009 07:02:28 +0000 Subject: [PATCH 3263/4131] Fix some warnings in pedantic mode. (another one). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3351 --- src/hardware/sblaster.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 2df1273d..05620830 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.72 2009-03-19 20:45:42 c2woody Exp $ */ +/* $Id: sblaster.cpp,v 1.73 2009-04-25 07:02:28 qbix79 Exp $ */ #include #include @@ -78,11 +78,11 @@ enum DSP_MODES { enum DMA_MODES { DSP_DMA_NONE, DSP_DMA_2,DSP_DMA_3,DSP_DMA_4,DSP_DMA_8, - DSP_DMA_16,DSP_DMA_16_ALIASED, + DSP_DMA_16,DSP_DMA_16_ALIASED }; enum { - PLAY_MONO,PLAY_STEREO, + PLAY_MONO,PLAY_STEREO }; struct SB_INFO { From dff27bb2c45f9f8876d5e8575d2e42bc81ff8caf Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 25 Apr 2009 09:55:50 +0000 Subject: [PATCH 3264/4131] Add the integer dosbox opl Combine all the adlib stuff in 1 module Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3352 --- src/hardware/adlib.cpp | 214 +++--- src/hardware/adlib.h | 19 +- src/hardware/dbopl.cpp | 1467 ++++++++++++++++++++++++++++++++++++++++ src/hardware/dbopl.h | 250 +++++++ 4 files changed, 1860 insertions(+), 90 deletions(-) create mode 100644 src/hardware/dbopl.cpp create mode 100644 src/hardware/dbopl.h diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 4e699f33..1943a50a 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: adlib.cpp,v 1.34 2009-04-17 17:24:47 c2woody Exp $ */ +/* $Id: adlib.cpp,v 1.35 2009-04-25 09:55:50 harekiet Exp $ */ #include #include @@ -24,15 +24,12 @@ #include #include -#include "dosbox.h" -#include "inout.h" -#include "mixer.h" -#include "pic.h" -#include "hardware.h" +#include "adlib.h" + #include "setup.h" #include "mapper.h" -#include "adlib.h" #include "mem.h" +#include "dbopl.h" /* Thanks to vdmsound for nice simple way to implement this @@ -188,6 +185,7 @@ namespace old_OPL3 { } + #define RAW_SIZE 1024 @@ -548,8 +546,8 @@ void Module::PortWrite( Bitu port, Bitu val, Bitu iolen ) { //Keep track of last write time lastUsed = PIC_Ticks; //Maybe only enable with a keyon? - if ( !chan->enabled ) { - chan->Enable(true); + if ( !mixerChan->enabled ) { + mixerChan->Enable(true); } if ( port&1 ) { switch ( mode ) { @@ -641,121 +639,165 @@ void Module::Init( Mode m ) { } } -Module::Module() { - reg.dual[0] = 0; - reg.dual[1] = 0; - reg.normal = 0; -} +}; //namespace -}; //Adlib Namespace - - -static Adlib::Module module; +static Adlib::Module* module = 0; static void OPL_CallBack(Bitu len) { - module.handler->Generate( module.chan, len ); + module->handler->Generate( module->mixerChan, len ); //Disable the sound generation after 30 seconds of silence - if ((PIC_Ticks-module.lastUsed) > 30000) { - module.chan->Enable(false); + if ((PIC_Ticks - module->lastUsed) > 30000) { + module->mixerChan->Enable(false); } } static Bitu OPL_Read(Bitu port,Bitu iolen) { - return module.PortRead( port, iolen ); + return module->PortRead( port, iolen ); } void OPL_Write(Bitu port,Bitu val,Bitu iolen) { - module.PortWrite( port, val, iolen ); + module->PortWrite( port, val, iolen ); } +/* + Save the current state of the operators as instruments in an reality adlib tracker file +*/ +static void SaveRad() { + char b[16 * 1024]; + int w = 0; + + FILE* handle = OpenCaptureFile("RAD Capture",".rad"); + if ( !handle ) + return; + //Header + fwrite( "RAD by REALiTY!!", 1, 16, handle ); + b[w++] = 0x10; //version + b[w++] = 0x06; //default speed and no description + //Write 18 instuments for all operators in the cache + for ( int i = 0; i < 18; i++ ) { + Bit8u* set = module->cache + ( i / 9 ) * 256; + Bitu offset = ((i % 9) / 3) * 8 + (i % 3); + Bit8u* base = set + offset; + b[w++] = 1 + i; //instrument number + b[w++] = base[0x23]; + b[w++] = base[0x20]; + b[w++] = base[0x43]; + b[w++] = base[0x40]; + b[w++] = base[0x63]; + b[w++] = base[0x60]; + b[w++] = base[0x83]; + b[w++] = base[0x80]; + b[w++] = set[0xc0 + (i % 9)]; + b[w++] = base[0xe3]; + b[w++] = base[0xe0]; + } + b[w++] = 0; //instrument 0, no more instruments following + b[w++] = 1; //1 pattern following + //Zero out the remaing part of the file a bit to make rad happy + for ( int i = 0; i < 64; i++ ) { + b[w++] = 0; + } + fwrite( b, 1, w, handle ); + fclose( handle ); +}; + + static void OPL_SaveRawEvent(bool pressed) { if (!pressed) return; +// SaveRad();return; /* Check for previously opened wave file */ - if ( module.capture ) { - delete module.capture; - module.capture = 0; + if ( module->capture ) { + delete module->capture; + module->capture = 0; LOG_MSG("Stopped Raw OPL capturing."); } else { LOG_MSG("Preparing to capture Raw OPL, will start with first note played."); - module.capture = new Adlib::Capture( &module.cache ); + module->capture = new Adlib::Capture( &module->cache ); } } -class OPL: public Module_base { -private: - IO_ReadHandleObject ReadHandler[3]; - IO_WriteHandleObject WriteHandler[3]; - MixerObject MixerChan; -public: - static OPL_Mode oplmode; +namespace Adlib { - OPL(Section* configuration):Module_base(configuration) { - Section_prop * section=static_cast(configuration); - Bitu base = section->Get_hex("sbbase"); - Bitu rate = section->Get_int("oplrate"); - std::string oplemu( section->Get_string( "oplemu" ) ); +Module::Module( Section* configuration ) : Module_base(configuration) { + reg.dual[0] = 0; + reg.dual[1] = 0; + reg.normal = 0; + handler = 0; + capture = 0; - module.chan = MixerChan.Install(OPL_CallBack,rate,"FM"); - if (oplemu == "old") { - if ( oplmode == OPL_opl2 ) { - module.handler = new old_OPL2::Handler(); - } else { - module.handler = new old_OPL3::Handler(); - } + Section_prop * section=static_cast(configuration); + Bitu base = section->Get_hex("sbbase"); + Bitu rate = section->Get_int("oplrate"); + std::string oplemu( section->Get_string( "oplemu" ) ); + + mixerChan = mixerObject.Install(OPL_CallBack,rate,"FM"); + if (oplemu == "old") { + if ( oplmode == OPL_opl2 ) { + handler = new old_OPL2::Handler(); } else { - if ( oplmode == OPL_opl2 ) { - module.handler = new OPL2::Handler(); - } else { - module.handler = new OPL3::Handler(); - } + handler = new old_OPL3::Handler(); } - module.handler->Init( rate ); - Bit8u portRange = 4; //opl2 will set this to 2 - switch ( oplmode ) { - case OPL_opl2: - portRange = 2; - module.Init( Adlib::MODE_OPL2 ); - break; - case OPL_dualopl2: - module.Init( Adlib::MODE_DUALOPL2 ); - break; - case OPL_opl3: - module.Init( Adlib::MODE_OPL3 ); - break; + } else if (oplemu == "fast") { + handler = new DBOPL::Handler(); + } else { + if ( oplmode == OPL_opl2 ) { + handler = new OPL2::Handler(); + } else { + handler = new OPL3::Handler(); } - //0x388 range - WriteHandler[0].Install(0x388,OPL_Write,IO_MB, portRange ); - ReadHandler[0].Install(0x388,OPL_Read,IO_MB, portRange - 1 ); - //0x220 range - WriteHandler[1].Install(base,OPL_Write,IO_MB, portRange ); - ReadHandler[1].Install(base,OPL_Read,IO_MB, portRange - 1 ); - //0x228 range - WriteHandler[2].Install(base+8,OPL_Write,IO_MB,2); - ReadHandler[2].Install(base+8,OPL_Read,IO_MB,1); - - MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL"); } - ~OPL() { - if ( module.capture ) - delete module.capture; - old_OPL2::YM3812Shutdown(); - old_OPL3::YMF262Shutdown(); + handler->Init( rate ); + Bit8u portRange = 4; //opl2 will set this to 2 + switch ( oplmode ) { + case OPL_opl2: + portRange = 2; + Init( Adlib::MODE_OPL2 ); + break; + case OPL_dualopl2: + Init( Adlib::MODE_DUALOPL2 ); + break; + case OPL_opl3: + Init( Adlib::MODE_OPL3 ); + break; } -}; + //0x388 range + WriteHandler[0].Install(0x388,OPL_Write,IO_MB, portRange ); + ReadHandler[0].Install(0x388,OPL_Read,IO_MB, portRange - 1 ); + //0x220 range + WriteHandler[1].Install(base,OPL_Write,IO_MB, portRange ); + ReadHandler[1].Install(base,OPL_Read,IO_MB, portRange - 1 ); + //0x228 range + WriteHandler[2].Install(base+8,OPL_Write,IO_MB,2); + ReadHandler[2].Install(base+8,OPL_Read,IO_MB,1); -static OPL* test; + MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL"); +} + +Module::~Module() { + if ( capture ) { + delete capture; + } + if ( handler ) { + delete handler; + } +} //Initialize static members -OPL_Mode OPL::oplmode=OPL_none; +OPL_Mode Module::oplmode=OPL_none; + +}; //Adlib Namespace + void OPL_Init(Section* sec,OPL_Mode oplmode) { - OPL::oplmode = oplmode; - test = new OPL(sec); + Adlib::Module::oplmode = oplmode; + module = new Adlib::Module( sec ); } void OPL_ShutDown(Section* sec){ - delete test; + delete module; + module = 0; + } diff --git a/src/hardware/adlib.h b/src/hardware/adlib.h index dd029250..07ae23c9 100644 --- a/src/hardware/adlib.h +++ b/src/hardware/adlib.h @@ -16,14 +16,19 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: adlib.h,v 1.2 2009-04-06 11:23:21 qbix79 Exp $ */ +/* $Id: adlib.h,v 1.3 2009-04-25 09:55:50 harekiet Exp $ */ #ifndef DOSBOX_ADLIB_H #define DOSBOX_ADLIB_H #include "dosbox.h" #include "mixer.h" +#include "inout.h" +#include "mixer.h" +#include "setup.h" #include "pic.h" +#include "hardware.h" + namespace Adlib { @@ -108,7 +113,11 @@ typedef Bit8u RegisterCache[512]; //Internal class used for dro capturing class Capture; -class Module { +class Module: public Module_base { + IO_ReadHandleObject ReadHandler[3]; + IO_WriteHandleObject WriteHandler[3]; + MixerObject mixerObject; + //Mode we're running in Mode mode; //Last selected address in the chip for the different modes @@ -119,7 +128,8 @@ class Module { void CacheWrite( Bit32u reg, Bit8u val ); void DualWrite( Bit8u index, Bit8u reg, Bit8u val ); public: - MixerChannel* chan; + static OPL_Mode oplmode; + MixerChannel* mixerChan; Bit32u lastUsed; //Ticks when adlib was last used to turn of mixing after a few second Handler* handler; //Handler that will generate the sound @@ -132,7 +142,8 @@ public: Bitu PortRead( Bitu port, Bitu iolen ); void Init( Mode m ); - Module(); + Module( Section* configuration); + ~Module(); }; diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp new file mode 100644 index 00000000..1d12af12 --- /dev/null +++ b/src/hardware/dbopl.cpp @@ -0,0 +1,1467 @@ +/* + * 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. + */ + +/* + DOSBox implementation of a combined Yamaha YMF262 and Yamaha YM3812 emulator. + Enabling the opl3 bit will switch the emulator to stereo opl3 output instead of regular mono opl2 + Except for the table generation it's all integer math + Can choose different types of generators, using muls and bigger tables, try different ones for slower platforms + The generation was based on the MAME implementation but tried to have it use less memory and be faster in general + MAME uses much bigger envelope tables and this will be the biggest cause of it sounding different at times + + //TODO Don't delay first operator 1 sample in opl3 mode + //TODO Maybe not use class method pointers but a regular function pointers with operator as first parameter + //TODO Fix panning for the rhytm channels, would any opl3 player use it and actually really change it though? + //TODO don't use variables in work structure for tremolo and vibrato but give the variables as parameters to GetSample + //TODO Since the vibrato takes 1024 samples it's easier to run the emulator in same vibrato chunks, vibrato would be costfree + + //DUNNO Keyon in 4op, switch to 2op without keyoff. +*/ + + +#include +#include +#include +#include "dosbox.h" +#include "dbopl.h" + + +#ifndef PI +#define PI 3.14159265358979323846 +#endif + +namespace DBOPL { + +#define MAX_SAMPLES 256 +#define OPLRATE 50000 + +//Only need 4 valid bits at the top for vibrato +#define VIBRATO_SH ( 32 - 4 ) +//Need 6 bits of accuracy +#define TREMOLO_SH ( 32 - 6 ) +#define TREMOLO_TABLE 52 + +//Wave bits available in the top of the 32bit range +//Original adlib uses 10.10, we use 12.20 +//Have to keep some bits in the top to allow for freqmul 0.5 +#define WAVE_BITS 12 +#define WAVE_SH ( 32 - WAVE_BITS ) +#define WAVE_MASK ( ( 1 << WAVE_SH ) - 1 ) + +//Maximum amount of attenuation bits +//Envelope goes to 511, 9 bits +//Final envelope should get shifted up 3 bits, we already do that for some generation modes +#if (DBOPL_WAVE == WAVE_TABLEMUL ) +//Uses the value directly +#define ENV_BITS ( 9 ) +#else +//Add 3 bits here for more accuracy and would have to be shifted up either way +#define ENV_BITS ( 12 ) +#endif +//Limits of the envelope with those bits and when the envelope goes silent +#define ENV_MIN 0 +#define ENV_EXTRA ( ENV_BITS - 9 ) +#define ENV_MAX ( 511 << ENV_EXTRA ) +#define ENV_LIMIT ( ( 12 * 256) >> ( 3 - ENV_EXTRA ) ) +#define ENV_SILENT( _X_ ) ( (_X_) >= ENV_LIMIT ) + +//Attack/decay/release rate counter shift +#define RATE_SH 24 +#define RATE_MASK ( ( 1 << RATE_SH ) - 1 ) +//Has to fit within 16bit lookuptable +#define MUL_SH 16 + +//Check some ranges +#if ENV_EXTRA > 3 +#error Too many envelope bits +#endif + + +//How much to substract from the base value for the final attenuation +static const Bit8u KslCreateTable[16] = { + //0 will always be be lower than 7 * 8 + 64, 32, 24, 19, + 16, 12, 11, 10, + 8, 6, 5, 4, + 3, 2, 1, 0, +}; + +#define M(_X_) ((Bit8u)( (_X_) * 2)) +static const Bit8u FreqCreateTable[16] = { + M(0.5), M(1 ), M(2 ), M(3 ), M(4 ), M(5 ), M(6 ), M(7 ), + M(8 ), M(9 ), M(10), M(10), M(12), M(12), M(15), M(15) +}; +#undef M + +//We're not including the highest attack rate, that gets a special value +static const Bit8u AttackSamplesTable[13] = { + 69, 55, 46, 40, + 35, 29, 23, 20, + 19, 15, 11, 10, + 9 +}; +//On a real opl these values take 8 samples to reach and are based upon larger tables +static const Bit8u EnvelopeIncreaseTable[13] = { + 4, 5, 6, 7, + 8, 10, 12, 14, + 16, 20, 24, 28, + 32, +}; + +#if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG ) +static Bit16u ExpTable[ 256 ]; +#endif + +#if ( DBOPL_WAVE == WAVE_HANDLER ) +//PI table used by WAVEHANDLER +static Bit16u SinTable[ 512 ]; +#endif + +#if ( DBOPL_WAVE > WAVE_HANDLER ) +//Layout of the waveform table in 512 entry intervals +//With overlapping waves we reduce the table to half it's size + +// | |//\\|____|WAV7|//__|/\ |____|/\/\| +// |\\//| | |WAV7| | \/| | | +// |06 |0126|17 |7 |3 |4 |4 5 |5 | + +//6 is just 0 shifted and masked + +static Bit16s WaveTable[ 8 * 512 ]; +//Distance into WaveTable the wave starts +static const Bit16u WaveBaseTable[8] = { + 0x000, 0x200, 0x200, 0x800, + 0xa00, 0xc00, 0x100, 0x400, + +}; +//Mask the counter with this +static const Bit16u WaveMaskTable[8] = { + 1023, 1023, 511, 511, + 1023, 1023, 512, 1023, +}; + +//Where to start the counter on at keyon +static const Bit16u WaveStartTable[8] = { + 512, 0, 0, 0, + 0, 512, 512, 256, +}; +#endif + +#if ( DBOPL_WAVE == WAVE_TABLEMUL ) +static Bit16u MulTable[ 384 ]; +#endif + +static Bit8u KslTable[ 8 * 16 ]; +static Bit8u TremoloTable[ TREMOLO_TABLE ]; +//Start of a channel behind the chip struct start +static Bit16u ChanOffsetTable[32]; +//Start of an operator behind the chip struct start +static Bit16u OpOffsetTable[64]; + +//The lower bits are the shift of the operator vibrato value +//The highest bit is right shifted to generate -1 or 0 for negation +//So taking the highest input value of 7 this gives 3, 7, 3, 0, -3, -7, -3, 0 +static const Bit8s VibratoTable[ 8 ] = { + 1 - 0x00, 0 - 0x00, 1 - 0x00, 30 - 0x00, + 1 - 0x80, 0 - 0x80, 1 - 0x80, 30 - 0x80 +}; + +//Shift strength for the ksl value determined by ksl strength +static const Bit8u KslShiftTable[4] = { + 31,1,2,0 +}; + +//Generate a table index and table shift value using input value from a selected rate +static void EnvelopeSelect( Bit8u val, Bit8u& index, Bit8u& shift ) { + if ( val < 13 * 4 ) { //Rate 0 - 12 + shift = 12 - ( val >> 2 ); + index = val & 3; + } else if ( val < 15 * 4 ) { //rate 13 - 14 + shift = 0; + index = val - 12 * 4; + } else { //rate 15 and up + shift = 0; + index = 12; + } +} + +#if ( DBOPL_WAVE == WAVE_HANDLER ) +/* + Generate the different waveforms out of the sine/exponetial table using handlers +*/ +static inline Bits MakeVolume( Bitu wave, Bitu volume ) { + Bitu total = wave + volume; + Bitu index = total & 0xff; + Bitu sig = ExpTable[ index ]; + Bitu exp = total >> 8; +#if 0 + //Check if we overflow the 31 shift limit + if ( exp >= 32 ) { + LOG_MSG( "WTF %d %d", total, exp ); + } +#endif + return (sig >> exp); +}; + +static Bits FASTCALL WaveForm0( Bitu i, Bitu volume ) { + Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 + Bitu wave = SinTable[i & 511]; + return (MakeVolume( wave, volume ) ^ neg) - neg; +} +static Bits FASTCALL WaveForm1( Bitu i, Bitu volume ) { + Bit32u wave = SinTable[i & 511]; + wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 ); + return MakeVolume( wave, volume ); +} +static Bits FASTCALL WaveForm2( Bitu i, Bitu volume ) { + Bitu wave = SinTable[i & 511]; + return MakeVolume( wave, volume ); +} +static Bits FASTCALL WaveForm3( Bitu i, Bitu volume ) { + Bitu wave = SinTable[i & 255]; + wave |= ( ( (i ^ 256 ) & 256) - 1) >> ( 32 - 12 ); + return MakeVolume( wave, volume ); +} +static Bits FASTCALL WaveForm4( Bitu i, Bitu volume ) { + //Twice as fast + i <<= 1; + Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 + Bitu wave = SinTable[i & 511]; + wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 ); + return (MakeVolume( wave, volume ) ^ neg) - neg; +} +static Bits FASTCALL WaveForm5( Bitu i, Bitu volume ) { + //Twice as fast + i <<= 1; + Bitu wave = SinTable[i & 511]; + wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 ); + return MakeVolume( wave, volume ); +} +static Bits FASTCALL WaveForm6( Bitu i, Bitu volume ) { + Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 + return (MakeVolume( 0, volume ) ^ neg) - neg; +} +static Bits FASTCALL WaveForm7( Bitu i, Bitu volume ) { + //Negative is reversed here + Bits neg = (( i >> 9) & 1) - 1; + Bitu wave = (i << 3); + //When negative the volume also runs backwards + wave = ((wave ^ neg) - neg) & 4095; + return (MakeVolume( wave, volume ) ^ neg) - neg; +} + +static const WaveHandler WaveHandlerTable[8] = { + WaveForm0, WaveForm1, WaveForm2, WaveForm3, + WaveForm4, WaveForm5, WaveForm6, WaveForm7 +}; + +#endif + +//Structto hold the data everything well yeh works with +static struct { + Bitu samples; + Bits vibrato; + Bits tremolo; + inline void SetVibrato( Bit8s vib ) { + vibrato = vib; + vibrato &= ~0x80; + } + Bit32s output[MAX_SAMPLES * 2]; + //Could intermix the vib/trem table for slightly better cache hits + Bit8s vibTable[MAX_SAMPLES]; + Bit8s tremTable[MAX_SAMPLES]; +} Work; + +/* + Operator +*/ + +//We zero out when rate == 0 +inline void Operator::UpdateAttack( const Chip* chip ) { + Bit8u rate = reg60 >> 4; + if ( rate ) { + Bit8u val = (rate << 2) + ksr; + attackAdd = chip->attackRates[ val ]; + rateZero &= ~(1 << ATTACK); + } else { + attackAdd = 0; + rateZero |= (1 << ATTACK); + } +} +inline void Operator::UpdateDecay( const Chip* chip ) { + Bit8u rate = reg60 & 0xf; + if ( rate ) { + Bit8u val = (rate << 2) + ksr; + decayAdd = chip->linearRates[ val ]; + rateZero &= ~(1 << DECAY); + } else { + decayAdd = 0; + rateZero |= (1 << DECAY); + } +} +inline void Operator::UpdateRelease( const Chip* chip ) { + Bit8u rate = reg80 & 0xf; + if ( rate ) { + Bit8u val = (rate << 2) + ksr; + releaseAdd = chip->linearRates[ val ]; + rateZero &= ~(1 << RELEASE); + if ( !(reg20 & MASK_SUSTAIN ) ) { + rateZero &= ~( 1 << SUSTAIN ); + } + } else { + rateZero |= (1 << RELEASE); + releaseAdd = 0; + if ( !(reg20 & MASK_SUSTAIN ) ) { + rateZero |= ( 1 << SUSTAIN ); + } + } +} + +inline void Operator::UpdateAttenuation( ) { + Bit8u kslBase = (chanData >> SHIFT_KSLBASE) & 0xff; + Bit32u tl = reg40 & 0x3f; + Bit8u kslShift = KslShiftTable[ reg40 >> 6 ]; + //Make sure the attenuation goes to the right bits + totalLevel = tl << ( ENV_BITS - 7 ); //Total level goes 2 bits below max + totalLevel += ( kslBase << ENV_EXTRA ) >> kslShift; +} + +void Operator::UpdateFrequency( ) { + Bit32u freq = chanData & (( 1 << 10 ) - 1); + Bit32u block = (chanData >> 10) & 0xff; + + waveAdd = (freq << block) * freqMul; + if ( reg20 & MASK_VIBRATO ) { + vibStrength = (Bit8u)(freq >> 7); + vibrato = ( vibStrength << block ) * freqMul; + } else { + vibStrength = 0; + vibrato = 0; + } +} + +void Operator::UpdateRates( const Chip* chip ) { + //Mame seems to reverse this where enabling ksr actually lowers + //the rate, but pdf manuals says otherwise? + Bit8u newKsr = (chanData >> SHIFT_KEYCODE) & 0xff; + if ( !( reg20 & MASK_KSR ) ) { + newKsr >>= 2; + } + if ( ksr == newKsr ) + return; + ksr = newKsr; + UpdateAttack( chip ); + UpdateDecay( chip ); + UpdateRelease( chip ); +} + +INLINE Bit32s Operator::RateForward( Bit32u add ) { + rateIndex += add; + Bit32s ret = rateIndex >> RATE_SH; + rateIndex = rateIndex & RATE_MASK; + return ret; +} + +template< Operator::State yes> +Bits Operator::TemplateVolume( ) { + Bit32s vol = activeLevel; + Bit32s change; + switch ( yes ) { + case OFF: + return ENV_MAX; + case ATTACK: + change = RateForward( attackAdd ); + if ( !change ) + return vol; + vol += ( (~vol) * change ) >> 3; + if ( vol < ENV_MIN ) { + activeLevel = ENV_MIN; + rateIndex = 0; + SetState( DECAY ); + return ENV_MIN; + } + break; + case DECAY: + vol += RateForward( decayAdd ); + if ( vol >= sustainLevel ) { + //Check if we didn't overshoot max attenuation, then just go off + if ( vol >= ENV_MAX ) { + activeLevel = ENV_MAX; + SetState( OFF ); + return ENV_MAX; + } + //Continue as sustain + rateIndex = 0; + SetState( SUSTAIN ); + } + break; + case SUSTAIN: + if ( reg20 & MASK_SUSTAIN ) { + return vol; + } + //In sustain phase, but not sustaining, do regular release + case RELEASE: + vol += RateForward( releaseAdd );; + if ( vol >= ENV_MAX ) { + activeLevel = ENV_MAX; + SetState( OFF ); + return ENV_MAX; + } + break; + } + activeLevel = vol; + return vol; +} + +static const VolumeHandler VolumeHandlerTable[5] = { + &Operator::TemplateVolume< Operator::OFF >, + &Operator::TemplateVolume< Operator::RELEASE >, + &Operator::TemplateVolume< Operator::SUSTAIN >, + &Operator::TemplateVolume< Operator::DECAY >, + &Operator::TemplateVolume< Operator::ATTACK > +}; + +INLINE Bitu Operator::ForwardVolume() { + return totalLevel + (this->*volHandler)() +#if defined ( DBOPL_TREMOLO ) + + (Work.tremolo & tremoloMask) +#endif + ; +} + + +INLINE Bitu Operator::ForwardWave() { +#if defined ( DBOPL_VIBRATO ) + if ( vibStrength >> (Bit8u)(Work.vibrato) ) { + Bit32s add = vibrato >> (Bit8u)(Work.vibrato); + //Sign extend over the shift value + Bit32s neg = Work.vibrato >> 16; + //Negate the add with -1 or 0 + add = ( add ^ neg ) - neg; + waveIndex += add + waveAdd; + return waveIndex >> WAVE_SH; + } +#endif + waveIndex += waveAdd; + return waveIndex >> WAVE_SH; +} + + +void Operator::Write20( const Chip* chip, Bit8u val ) { + Bit8u change = (reg20 ^ val ); + if ( !change ) + return; + reg20 = val; + //Shift the tremolo bit over the entire register, saved a branch, YES! + tremoloMask = (Bit8s)(val) >> 7; + tremoloMask &= ~(( 1 << ENV_EXTRA ) -1); + //Update specific features based on changes + if ( change & MASK_KSR ) { + UpdateRates( chip ); + } + //With sustain enable the volume doesn't change + if ( reg20 & MASK_SUSTAIN || ( !releaseAdd ) ) { + rateZero |= ( 1 << SUSTAIN ); + } else { + rateZero &= ~( 1 << SUSTAIN ); + } + //Frequency multiplier or vibrato changed + if ( change & (0xf | MASK_VIBRATO) ) { + freqMul = chip->freqMul[ val & 0xf ]; + UpdateFrequency(); + } +} + +void Operator::Write40( const Chip* chip, Bit8u val ) { + if (!(reg40 ^ val )) + return; + reg40 = val; + UpdateAttenuation( ); +} + +void Operator::Write60( const Chip* chip, Bit8u val ) { + Bit8u change = reg60 ^ val; + reg60 = val; + if ( change & 0x0f ) { + UpdateDecay( chip ); + } + if ( change & 0xf0 ) { + UpdateAttack( chip ); + } +} + +void Operator::Write80( const Chip* chip, Bit8u val ) { + Bit8u change = (reg80 ^ val ); + if ( !change ) + return; + reg80 = val; + Bit8u sustain = val >> 4; + //Turn 0xf into 0x1f + sustain |= ( sustain + 1) & 0x10; + sustainLevel = sustain << ( ENV_BITS - 5 ); + if ( change & 0x0f ) { + UpdateRelease( chip ); + } +} + +void Operator::WriteE0( const Chip* chip, Bit8u val ) { + if ( !(regE0 ^ val) ) + return; + //in opl3 mode you can always selet 7 waveforms regardless of waveformselect + Bit8u waveForm = val & ( ( 0x3 & chip->waveFormMask ) | (0x7 & chip->opl3Active ) ); + regE0 = val; +#if ( DBOPL_WAVE == WAVE_HANDLER ) + waveHandler = WaveHandlerTable[ waveForm ]; +#else + waveBase = WaveTable + WaveBaseTable[ waveForm ]; + waveStart = WaveStartTable[ waveForm ] << WAVE_SH; + waveMask = WaveMaskTable[ waveForm ]; +#endif +} + +INLINE void Operator::SetState( Bit8u s ) { + state = s; + volHandler = VolumeHandlerTable[ s ]; +} + +INLINE bool Operator::Silent() const { + if ( !ENV_SILENT( totalLevel + activeLevel ) ) + return false; + if ( !(rateZero & ( 1 << state ) ) ) + return false; + return true; +}; + +void Operator::KeyOn( Bit8u mask ) { + if ( !keyOn ) { + //Restart the frequency generator +#if ( DBOPL_WAVE > WAVE_HANDLER ) + waveIndex = waveStart; +#else + waveIndex = 0; +#endif + rateIndex = 0; + SetState( ATTACK ); + } + keyOn |= mask; +} + +void Operator::KeyOff( Bit8u mask ) { + keyOn &= ~mask; + if ( !keyOn ) { + if ( state != OFF ) { + SetState( RELEASE ); + } + } +} + +INLINE Bits Operator::GetWave( Bitu index, Bitu vol ) { +#if ( DBOPL_WAVE == WAVE_HANDLER ) + return waveHandler( index, vol << ( 3 - ENV_EXTRA ) ); +#elif ( DBOPL_WAVE == WAVE_TABLEMUL ) + return (waveBase[ index & waveMask ] * MulTable[ vol >> ENV_EXTRA ]) >> MUL_SH; +#elif ( DBOPL_WAVE == WAVE_TABLELOG ) + Bit32s wave = waveBase[ index & waveMask ]; + Bit32u total = ( wave & 0x7fff ) + vol; + Bit32s sig = ExpTable[ total & 0xff ]; + Bit32u exp = total >> 8; + Bit32s neg = wave >> 16; + return ((sig ^ neg) - neg) >> exp; +#else +#error "No valid wave routine" +#endif +} + +Bits INLINE Operator::GetSample( Bits modulation ) { + Bitu vol = ForwardVolume(); + if ( ENV_SILENT( vol ) ) { + //Simply forward the wave + waveIndex += waveAdd; + return 0; + } else { + Bitu index = ForwardWave(); + index += modulation; + return GetWave( index, vol ); + } +} + +Operator::Operator() { + freqMul = 0; + waveIndex = 0; + waveAdd = 0; + keyOn = 0; + ksr = 0; + chanData = 0; + SetState( OFF ); + rateZero = (1 << OFF); + + sustainLevel = ENV_MAX; + activeLevel = ENV_MAX; + totalLevel = ENV_MAX; +} + +/* + Channel +*/ + +Channel::Channel() { + //Frequency init + chanData = 0; + regC0 = 0; + maskLeft = -1; + maskRight = -1; + feedback = 31; + fourMask = 0; + synthHandler = &Channel::BlockTemplate< sm2FM >; +}; + +void Channel::SetChanData( const Chip* chip, Bit32u data ) { + Bit32u change = chanData ^ data; + chanData = data; + Op( 0 )->chanData = data; + Op( 1 )->chanData = data; + //Since a frequency update triggered this, always update frequency + Op( 0 )->UpdateFrequency(); + Op( 1 )->UpdateFrequency(); + if ( change & ( 0xff << SHIFT_KSLBASE ) ) { + Op( 0 )->UpdateAttenuation(); + Op( 1 )->UpdateAttenuation(); + } + if ( change & ( 0xff << SHIFT_KEYCODE ) ) { + Op( 0 )->UpdateRates( chip ); + Op( 1 )->UpdateRates( chip ); + } +} + +void Channel::UpdateFrequency( const Chip* chip, Bit8u fourOp ) { + //Extrace the frequency bits + Bit32u data = chanData & 0xffff; + Bit32u kslBase = KslTable[ data >> 6 ]; + Bit32u keyCode = ( data & 0x1c00) >> 9; + if ( chip->reg08 & 0x40 ) { + keyCode |= ( data & 0x100)>>8; /* notesel == 1 */ + } else { + keyCode |= ( data & 0x200)>>9; /* notesel == 0 */ + } + //Add the keycode and ksl into the highest bits of chanData + data |= (keyCode << SHIFT_KEYCODE) | ( kslBase << SHIFT_KSLBASE ); + ( this + 0 )->SetChanData( chip, data ); + if ( fourOp & 0x3f ) { + ( this + 1 )->SetChanData( chip, data ); + } +} + +void Channel::WriteA0( const Chip* chip, Bit8u val ) { + Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask; + //Don't handle writes to silent fourop channels + if ( fourOp > 0x80 ) + return; + Bit32u change = (chanData ^ val ) & 0xff; + if ( change ) { + chanData ^= change; + UpdateFrequency( chip, fourOp ); + } +} + +void Channel::WriteB0( const Chip* chip, Bit8u val ) { + Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask; + //Don't handle writes to silent fourop channels + if ( fourOp > 0x80 ) + return; + Bitu change = (chanData ^ ( val << 8 ) ) & 0x1f00; + if ( change ) { + chanData ^= change; + UpdateFrequency( chip, fourOp ); + } + //Check for a change in the keyon/off state + if ( !(( val ^ regB0) & 0x20)) + return; + regB0 = val; + if ( val & 0x20 ) { + Op(0)->KeyOn( 0x1 ); + Op(1)->KeyOn( 0x1 ); + if ( fourOp & 0x3f ) { + ( this + 1 )->Op(0)->KeyOn( 1 ); + ( this + 1 )->Op(1)->KeyOn( 1 ); + } + } else { + Op(0)->KeyOff( 0x1 ); + Op(1)->KeyOff( 0x1 ); + if ( fourOp & 0x3f ) { + ( this + 1 )->Op(0)->KeyOff( 1 ); + ( this + 1 )->Op(1)->KeyOff( 1 ); + } + } +} + +void Channel::WriteC0( const Chip* chip, Bit8u val ) { + Bit8u change = val ^ regC0; + if ( !change ) + return; + regC0 = val; + feedback = ( val >> 1 ) & 7; + if ( feedback ) { + //We shift the input to the right 10 bit wave index value + feedback = 9 - feedback; + } else { + feedback = 31; + } + //Select the new synth mode + if ( chip->opl3Active ) { + //4-op mode enabled for this channel + if ( (chip->reg104 & fourMask) & 0x3f ) { + Channel* chan0, *chan1; + //Check if it's the 2nd channel in a 4-op + if ( !(fourMask & 0x80 ) ) { + chan0 = this; + chan1 = this + 1; + } else { + chan0 = this - 1; + chan1 = this; + } + + Bit8u synth = ( (chan0->regC0 & 1) << 0 )| (( chan1->regC0 & 1) << 1 ); + switch ( synth ) { + case 0: + chan0->synthHandler = &Channel::BlockTemplate< sm3FMFM >; + break; + case 1: + chan0->synthHandler = &Channel::BlockTemplate< sm3AMFM >; + break; + case 2: + chan0->synthHandler = &Channel::BlockTemplate< sm3FMAM >; + break; + case 3: + chan0->synthHandler = &Channel::BlockTemplate< sm3AMAM >; + break; + } + //Disable updating rhytm channels + } else if ((fourMask & 0x40) && ( chip->regBD & 0x20) ) { + + //Regular dual op, am or fm + } else if ( val & 1 ) { + synthHandler = &Channel::BlockTemplate< sm3AM >; + } else { + synthHandler = &Channel::BlockTemplate< sm3FM >; + } + maskLeft = ( val & 0x10 ) ? -1 : 0; + maskRight = ( val & 0x20 ) ? -1 : 0; + //opl2 active + } else { + //Disable updating rhytm channels + if ( (fourMask & 0x40) && ( chip->regBD & 0x20 ) ) { + + //Regular dual op, am or fm + } else if ( val & 1 ) { + synthHandler = &Channel::BlockTemplate< sm2AM >; + } else { + synthHandler = &Channel::BlockTemplate< sm2FM >; + } + } +} + +void Channel::ResetC0( const Chip* chip ) { + Bit8u val = regC0; + regC0 ^= 0xff; + WriteC0( chip, val ); +}; + +template< bool opl3Mode> +void Channel::GenerateRhytm( Bit32s* output ) { + Channel* chan = this; + + //BassDrum + Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback; + old[0] = old[1]; + old[1] = Op(0)->GetSample( mod ); + + //When bassdrum is in AM mode first operator is ignoed + if ( chan->regC0 & 1 ) { + mod = 0; + } else { + mod = old[0]; + } + Bit32s sample = Op(1)->GetSample( mod ); + + Operator* op2 = ( this + 1 )->Op(0); + Operator* op4 = ( this + 2 )->Op(0); + + //Precalculate stuff used by other oupts + Bit32u noiseBit = rand() & 0x2; + Bit32u c2 = op2->ForwardWave(); + //(bit 7 ^ bit 2) | bit 3 -> combined in bit 1 + Bit32u phaseBit = ( (c2 >> 6) ^ ( c2 >> 1 ) ) | ( c2 >> 2 ); + Bit32u c4 = op4->ForwardWave(); + //bit 5 ^ bit 3 to bit 1 + Bit32u gateBit = ( c4 >> 4 ) ^ ( c4 >> 3 ); + phaseBit = (phaseBit | gateBit) & 0x2; + + //Hi-Hat + Bit32u hhVol = op2->ForwardVolume(); + if ( !ENV_SILENT( hhVol ) ) { + /* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */ + /* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */ + Bit32u hhIndex = ( phaseBit << 8 ) | ( 0xd0 >> ( phaseBit ^ noiseBit ) ); + sample += op2->GetWave( hhIndex, hhVol ); + } + //Snare Drum + Operator* op3 = ( this + 1 )->Op(1); + Bit32u sdVol = op3->ForwardVolume(); + if ( !ENV_SILENT( sdVol ) ) { + Bit32u sdBits = 0x100 + (c2 & 0x100); + Bit32u sdIndex = sdBits ^ ( noiseBit << 7 ); + sample += op3->GetWave( sdIndex, sdVol ); + } + //Tom-tom + sample += op4->GetSample( 0 ); + //Top-Cymbal + Operator* op5 = ( this + 2 )->Op(1); + Bit32u tcVol = op5->ForwardVolume(); + if ( !ENV_SILENT( tcVol ) ) { + Bit32u tcIndex = (1 + phaseBit) << 8; + sample += op5->GetWave( tcIndex, tcVol ); + } + sample <<= 1; + if ( opl3Mode ) { + output[0] += sample; + output[1] += sample; + } else { + output[0] += sample; + } +} + +template +Channel* Channel::BlockTemplate( ) { + switch( mode ) { + case sm2AM: + case sm3AM: + if ( Op(0)->Silent() && Op(1)->Silent() ) { + old[0] = old[1] = 0; + return (this + 1); + } + break; + case sm2FM: + case sm3FM: + if ( Op(1)->Silent() ) { + old[0] = old[1] = 0; + return (this + 1); + } + break; + case sm3FMFM: + if ( Op(3)->Silent() ) { + old[0] = old[1] = 0; + return (this + 2); + } + break; + case sm3AMFM: + if ( Op(0)->Silent() && Op(3)->Silent() ) { + old[0] = old[1] = 0; + return (this + 2); + } + break; + case sm3FMAM: + if ( Op(1)->Silent() && Op(3)->Silent() ) { + old[0] = old[1] = 0; + return (this + 2); + } + break; + case sm3AMAM: + if ( Op(0)->Silent() && Op(2)->Silent() && Op(3)->Silent() ) { + old[0] = old[1] = 0; + return (this + 2); + } + break; + } + for ( Bitu i = 0; i < Work.samples; i++ ) { + Work.vibrato = Work.vibTable[i]; + Work.tremolo = Work.tremTable[i]; + + //Early out for rhytm handlers + if ( mode == sm2Rhytm ) { + GenerateRhytm( Work.output + i ); + continue; //Prevent some unitialized value bitching + } else if ( mode == sm3Rhytm ) { + GenerateRhytm( Work.output + i * 2 ); + continue; //Prevent some unitialized value bitching + } + + //Do unsigned shift so we can shift out all bits but still stay in 10 bit range otherwise + Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback; + old[0] = old[1]; + old[1] = Op(0)->GetSample( mod ); + Bit32s sample; + Bit32s out0 = old[0]; + if ( mode == sm2AM || mode == sm3AM ) { + sample = out0 + Op(1)->GetSample( 0 ); + } else if ( mode == sm2FM || mode == sm3FM ) { + sample = Op(1)->GetSample( out0 ); + } else if ( mode == sm3FMFM ) { + Bits next = Op(1)->GetSample( out0 ); + next = Op(2)->GetSample( next ); + sample = Op(3)->GetSample( next ); + } else if ( mode == sm3AMFM ) { + sample = out0; + Bits next = Op(1)->GetSample( 0 ); + next = Op(2)->GetSample( next ); + sample += Op(3)->GetSample( next ); + } else if ( mode == sm3FMAM ) { + sample = Op(1)->GetSample( out0 ); + Bits next = Op(2)->GetSample( 0 ); + sample += Op(3)->GetSample( next ); + } else if ( mode == sm3AMAM ) { + sample = out0; + Bits next = Op(1)->GetSample( 0 ); + sample += Op(2)->GetSample( next ); + sample += Op(3)->GetSample( 0 ); + } + switch( mode ) { + case sm2AM: + case sm2FM: + Work.output[ i ] += sample; + break; + case sm3AM: + case sm3FM: + case sm3FMFM: + case sm3AMFM: + case sm3FMAM: + case sm3AMAM: + Work.output[ i * 2 + 0 ] += sample & maskLeft; + Work.output[ i * 2 + 1 ] += sample & maskRight; + break; + } + } + switch( mode ) { + case sm2AM: + case sm2FM: + case sm3AM: + case sm3FM: + return ( this + 1 ); + case sm3FMFM: + case sm3AMFM: + case sm3FMAM: + case sm3AMAM: + return( this + 2 ); + case sm2Rhytm: + case sm3Rhytm: + return( this + 3 ); + } + return 0; +} + +/* + Chip +*/ + +Chip::Chip() { + reg104 = 0; + opl3Active = 0; +} + + +Bit8u Chip::ForwardTremolo( ) { + tremoloCounter += tremoloAdd; + if ( tremoloCounter >= (TREMOLO_TABLE << TREMOLO_SH) ) { + tremoloCounter -= TREMOLO_TABLE << TREMOLO_SH; + } + Bitu index = tremoloCounter >> TREMOLO_SH; + return TremoloTable[ index ] >> tremoloShift; +} + +Bit8s Chip::ForwardVibrato( ) { + vibratoCounter += vibratoAdd; + Bitu index = vibratoCounter >> VIBRATO_SH; + //Vibrato shift, basically makes the shift greater reducing the actual final value + return VibratoTable[index & 7] + vibratoShift; +} + +void Chip::WriteBD( Bit8u val ) { + Bit8u change = regBD ^ val; + if ( !change ) + return; + regBD = val; + //TODO could do this with shift and xor? + vibratoShift = (val & 0x40) ? 0x00 : 0x01; + tremoloShift = (val & 0x80) ? 0x00 : 0x02; + if ( val & 0x20 ) { + //Drum was just enabled, make sure channel 6 has the right synth + if ( change & 0x20 ) { + if ( opl3Active ) { + chan[6].synthHandler = &Channel::BlockTemplate< sm3Rhytm >; + } else { + chan[6].synthHandler = &Channel::BlockTemplate< sm2Rhytm >; + } + } + //Bass Drum + if ( val & 0x10 ) { + chan[6].op[0].KeyOn( 0x2 ); + chan[6].op[1].KeyOn( 0x2 ); + } else { + chan[6].op[0].KeyOff( 0x2 ); + chan[6].op[1].KeyOff( 0x2 ); + } + //Hi-Hat + if ( val & 0x1 ) { + chan[7].op[0].KeyOn( 0x2 ); + } else { + chan[7].op[0].KeyOff( 0x2 ); + } + //Snare + if ( val & 0x8 ) { + chan[7].op[1].KeyOn( 0x2 ); + } else { + chan[7].op[1].KeyOff( 0x2 ); + } + //Tom-Tom + if ( val & 0x4 ) { + chan[8].op[0].KeyOn( 0x2 ); + } else { + chan[8].op[0].KeyOff( 0x2 ); + } + //Top Cymbal + if ( val & 0x2 ) { + chan[8].op[1].KeyOn( 0x2 ); + } else { + chan[8].op[1].KeyOff( 0x2 ); + } + //Toggle keyoffs when we turn off the rhytm + } else if ( change & 0x20 ) { + //Trigger a reset to setup the original synth handler + chan[6].ResetC0( this ); + chan[6].op[0].KeyOff( 0x2 ); + chan[6].op[1].KeyOff( 0x2 ); + chan[7].op[0].KeyOff( 0x2 ); + chan[7].op[1].KeyOff( 0x2 ); + chan[8].op[0].KeyOff( 0x2 ); + chan[8].op[1].KeyOff( 0x2 ); + } +} + + +#define REGOP( _FUNC_ ) \ + index = ( ( reg >> 3) & 0x20 ) | ( reg & 0x1f ); \ + if ( OpOffsetTable[ index ] ) { \ + Operator* regOp = (Operator*)( ((char *)this ) + OpOffsetTable[ index ] ); \ + regOp->_FUNC_( this, val ); \ + } + +#define REGCHAN( _FUNC_ ) \ + index = ( ( reg >> 4) & 0x10 ) | ( reg & 0xf ); \ + if ( ChanOffsetTable[ index ] ) { \ + Channel* regChan = (Channel*)( ((char *)this ) + ChanOffsetTable[ index ] ); \ + regChan->_FUNC_( this, val ); \ + } + +void Chip::WriteReg( Bit32u reg, Bit8u val ) { + Bitu index; + switch ( (reg & 0xf0) >> 4 ) { + case 0x00 >> 4: + if ( reg == 0x01 ) { + waveFormMask = ( val & 0x20 ) ? 0x7 : 0x0; + } else if ( reg == 0x104 ) { + //Only detect changes in lowest 6 bits + if ( !((reg104 ^ val) & 0x3f) ) + return; + //Always keep the highest bit enabled, for checking > 0x80 + reg104 = 0x80 | ( val & 0x3f ); + } else if ( reg == 0x105 ) { + //MAME says the real opl3 doesn't reset anything on opl3 disable/enable till the next write in another register + if ( !((opl3Active ^ val) & 1 ) ) + return; + opl3Active = ( val & 1 ) ? 0xff : 0; + //Update the 0xc0 register for all channels to signal the switch to mono/stereo handlers + for ( int i = 0; i < 18;i++ ) { + chan[i].ResetC0( this ); + } + } else if ( reg == 0x08 ) { + reg08 = val; + } + case 0x10 >> 4: + break; + case 0x20 >> 4: + case 0x30 >> 4: + REGOP( Write20 ); + break; + case 0x40 >> 4: + case 0x50 >> 4: + REGOP( Write40 ); + break; + case 0x60 >> 4: + case 0x70 >> 4: + REGOP( Write60 ); + break; + case 0x80 >> 4: + case 0x90 >> 4: + REGOP( Write80 ); + break; + case 0xa0 >> 4: + REGCHAN( WriteA0 ); + break; + case 0xb0 >> 4: + if ( reg == 0xbd ) { + WriteBD( val ); + } else { + REGCHAN( WriteB0 ); + } + break; + case 0xc0 >> 4: + REGCHAN( WriteC0 ); + case 0xd0 >> 4: + break; + case 0xe0 >> 4: + case 0xf0 >> 4: + REGOP( WriteE0 ); + break; + } +} + + +Bit32u Chip::WriteAddr( Bit32u port, Bit8u val ) { + switch ( port & 3 ) { + case 0: + return val; + case 2: + if ( opl3Active || (val == 0x05) ) + return 0x100 | val; + else + return val; + } + return 0; +} + +void Chip::GenerateBlock2( Bitu samples ) { + Work.samples = samples; + for ( Bitu i = 0; i < Work.samples; i++ ) { + Work.vibTable[i] = ForwardVibrato(); + Work.tremTable[i] = ForwardTremolo(); + Work.output[i] = 0; + } + int count = 0; + for( Channel* ch = chan; ch < chan + 9; ) { + count++; + ch = (ch->*(ch->synthHandler))(); + } +} + +void Chip::GenerateBlock3( Bitu samples ) { + Work.samples = samples; + for ( Bitu i = 0; i < Work.samples; i++ ) { + Work.vibTable[i] = ForwardVibrato(); + Work.tremTable[i] = ForwardTremolo(); + Work.output[i*2 + 0] = 0; + Work.output[i*2 + 1] = 0; + } + int count = 0; + for( Channel* ch = chan; ch < chan + 18; ) { + count++; + ch = (ch->*(ch->synthHandler))(); + } +} + +void Chip::Setup( Bit32u rate ) { + //Vibrato forwards every 1024 samples + vibratoAdd = (Bit32u)((double)rate * (double)( 1 << (VIBRATO_SH - 10) ) / OPLRATE); + vibratoCounter = 0; + //tremolo forwards every 64 samples + //We use a 52 entry table, real is 210, so repeat each sample an extra 4 times + tremoloAdd = (Bit32u)((double)rate * (double)( 1 << (TREMOLO_SH - 6 - 2) ) / OPLRATE); + tremoloCounter = 0; + //10 bits of frequency counter + //With higher octave this gets shifted up + //-1 since the freqCreateTable = *2 + double scale = ((double)OPLRATE * (double)( 1 << ( WAVE_SH - 10 - 1))) / rate; + for ( int i = 0; i < 16; i++ ) { + //Use rounding with 0.5 + freqMul[i] = (Bit32u)( 0.5 + scale * FreqCreateTable[ i ] ); + } + + scale = (double)OPLRATE / rate; + //-3 since the real envelope takes 8 steps to reach the single value we supply + for ( Bit8u i = 0; i < 76; i++ ) { + Bit8u index, shift; + EnvelopeSelect( i, index, shift ); + linearRates[i] = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH + ENV_EXTRA - shift - 3 ))); + } + //Generate the best matching attack rate + for ( Bit8u i = 0; i < 62; i++ ) { + Bit8u index, shift; + EnvelopeSelect( i, index, shift ); + //Original amount of samples the attack would take + Bit32s original = (Bit32u)( (AttackSamplesTable[ index ] << shift) / scale); + + Bit32s guessAdd = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH - shift - 3 ))); + Bit32s bestAdd; + Bit32u bestDiff = 1 << 30; + for( Bit32u passes = 0; passes < 16; passes ++ ) { + Bit32s volume = ENV_MAX; + Bit32s samples = 0; + Bit32u count = 0; + while ( volume > 0 && samples < original * 2 ) { + count += guessAdd; + Bit32s change = count >> RATE_SH; + count &= RATE_MASK; + if ( change ) { + volume += ( ~volume * change ) >> 3; + } + samples++; + + } + Bit32s diff = original - samples; + Bit32u lDiff = labs( diff ); + //Init last on first pass + if ( lDiff < bestDiff ) { + bestDiff = lDiff; + bestAdd = guessAdd; + if ( !bestDiff ) + break; + } + //Below our target + if ( diff < 0 ) { + //Better than the last time + Bit32s mul = ((original - diff) << 12) / original; + guessAdd = ((guessAdd * mul) >> 12); + guessAdd++; + } else if ( diff > 0 ) { + Bit32s mul = ((original - diff) << 12) / original; + guessAdd = (guessAdd * mul) >> 12; + guessAdd--; + } + } + attackRates[i] = bestAdd; + } + for ( Bit8u i = 62; i < 76; i++ ) { + //This should provide instant volume maximizing + attackRates[i] = 8 << RATE_SH; + } + //Setup the channels with the correct four op flags + //Channels are accessed through a table so they appear linear here + chan[ 0].fourMask = 0x00 | ( 1 << 0 ); + chan[ 1].fourMask = 0x80 | ( 1 << 0 ); + chan[ 2].fourMask = 0x00 | ( 1 << 1 ); + chan[ 3].fourMask = 0x80 | ( 1 << 1 ); + chan[ 4].fourMask = 0x00 | ( 1 << 2 ); + chan[ 5].fourMask = 0x80 | ( 1 << 2 ); + + chan[ 9].fourMask = 0x00 | ( 1 << 3 ); + chan[10].fourMask = 0x80 | ( 1 << 3 ); + chan[11].fourMask = 0x00 | ( 1 << 4 ); + chan[12].fourMask = 0x80 | ( 1 << 4 ); + chan[13].fourMask = 0x00 | ( 1 << 5 ); + chan[14].fourMask = 0x80 | ( 1 << 5 ); + + //mark the rhythm channels + chan[ 6].fourMask = 0x40; + chan[ 7].fourMask = 0x40; + chan[ 8].fourMask = 0x40; + + //Clear Everything in opl3 mode + WriteReg( 0x105, 0x1 ); + for ( int i = 0; i < 512; i++ ) { + if ( i == 0x105 ) + continue; + WriteReg( i, 0xff ); + WriteReg( i, 0x0 ); + } + WriteReg( 0x105, 0x0 ); + //Clear everything in opl2 mode + for ( int i = 0; i < 255; i++ ) { + WriteReg( i, 0xff ); + WriteReg( i, 0x0 ); + } +} + +static bool doneTables = false; +void InitTables( void ) { + if ( doneTables ) + return; + doneTables = true; +#if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG ) + //Exponential volume table, same as the real adlib + for ( int i = 0; i < 256; i++ ) { + //Save them in reverse + ExpTable[i] = (int)( 0.5 + ( pow(2, ( 255 - i) * ( 1.0 /256 ) )-1) * 1024 ); + ExpTable[i] += 1024; //or remove the -1 oh well :) + //Preshift to the left once so the final volume can shift to the right + ExpTable[i] *= 2; + } +#endif +#if ( DBOPL_WAVE == WAVE_HANDLER ) + //Add 0.5 for the trunc rounding of the integer cast + //Do a PI sinetable instead of the original 0.5 PI + for ( int i = 0; i < 512; i++ ) { + SinTable[i] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 ); + } +#endif +#if ( DBOPL_WAVE == WAVE_TABLEMUL ) + //Multiplication based tables + for ( int i = 0; i < 384; i++ ) { + int s = i * 8; + //TODO maybe keep some of the precision errors of the original table? + double val = ( 0.5 + ( pow(2, -1 + ( 255 - s) * ( 1.0 /256 ) )) * ( 1 << MUL_SH )); + MulTable[i] = (Bit16u)(val); + } + + //Sine Wave Base + for ( int i = 0; i < 512; i++ ) { + WaveTable[ 0x0200 + i ] = (Bit16s)(sin( (i + 0.5) * (PI / 512.0) ) * 4084); + WaveTable[ 0x0000 + i ] = -WaveTable[ 0x200 + i ]; + } + //Exponential wave + for ( int i = 0; i < 256; i++ ) { + WaveTable[ 0x700 + i ] = (Bit16s)( 0.5 + ( pow(2, -1 + ( 255 - i * 8) * ( 1.0 /256 ) ) ) * 4085 ); + WaveTable[ 0x6ff - i ] = -WaveTable[ 0x700 + i ]; + } +#endif +#if ( DBOPL_WAVE == WAVE_TABLELOG ) + //Sine Wave Base + for ( int i = 0; i < 512; i++ ) { + WaveTable[ 0x0200 + i ] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 ); + WaveTable[ 0x0000 + i ] = ((Bit16s)0x8000) | WaveTable[ 0x200 + i]; + } + //Exponential wave + for ( int i = 0; i < 256; i++ ) { + WaveTable[ 0x700 + i ] = i * 8; + WaveTable[ 0x6ff - i ] = ((Bit16s)0x8000) | i * 8; + } +#endif + + // | |//\\|____|WAV7|//__|/\ |____|/\/\| + // |\\//| | |WAV7| | \/| | | + // |06 |0126|27 |7 |3 |4 |4 5 |5 | + +#if (( DBOPL_WAVE == WAVE_TABLELOG ) || ( DBOPL_WAVE == WAVE_TABLEMUL )) + for ( int i = 0; i < 256; i++ ) { + //Fill silence gaps + WaveTable[ 0x400 + i ] = WaveTable[0]; + WaveTable[ 0x500 + i ] = WaveTable[0]; + WaveTable[ 0x900 + i ] = WaveTable[0]; + WaveTable[ 0xc00 + i ] = WaveTable[0]; + WaveTable[ 0xd00 + i ] = WaveTable[0]; + //Replicate sines in other pieces + WaveTable[ 0x800 + i ] = WaveTable[ 0x200 + i ]; + //double speed sines + WaveTable[ 0xa00 + i ] = WaveTable[ 0x200 + i * 2 ]; + WaveTable[ 0xb00 + i ] = WaveTable[ 0x000 + i * 2 ]; + WaveTable[ 0xe00 + i ] = WaveTable[ 0x200 + i * 2 ]; + WaveTable[ 0xf00 + i ] = WaveTable[ 0x200 + i * 2 ]; + } +#endif + + //Create the ksl table + for ( int oct = 0; oct < 8; oct++ ) { + int base = oct * 8; + for ( int i = 0; i < 16; i++ ) { + int val = base - KslCreateTable[i]; + if ( val < 0 ) + val = 0; + //*4 for the final range to match attenuation range + KslTable[ oct * 16 + i ] = val * 4; + } + } + //Create the Tremolo table, just increase and decrease a triangle wave + for ( Bit8u i = 0; i < TREMOLO_TABLE / 2; i++ ) { + Bit8u val = i << ENV_EXTRA; + TremoloTable[i] = val; + TremoloTable[TREMOLO_TABLE - 1 - i] = val; + } + //Create a table with offsets of the channels from the start of the chip + DBOPL::Chip* chip = 0; + for ( Bitu i = 0; i < 32; i++ ) { + Bitu index = i & 0xf; + if ( index >= 9 ) { + ChanOffsetTable[i] = 0; + continue; + } + //Make sure the four op channels follow eachother + if ( index < 6 ) { + index = (index % 3) * 2 + ( index / 3 ); + } + //Add back the bits for highest ones + if ( i >= 16 ) + index += 9; + Bitu blah = reinterpret_cast( &(chip->chan[ index ]) ); + ChanOffsetTable[i] = blah; + } + //Same for operators + for ( Bitu i = 0; i < 64; i++ ) { + if ( i % 8 >= 6 || ( (i / 8) % 4 == 3 ) ) { + OpOffsetTable[i] = 0; + continue; + } + Bitu chNum = (i / 8) * 3 + (i % 8) % 3; + //Make sure we use 16 and up for the 2nd range to match the chanoffset gap + if ( chNum >= 12 ) + chNum += 16 - 12; + Bitu opNum = ( i % 8 ) / 3; + DBOPL::Channel* chan = 0; + Bitu blah = reinterpret_cast( &(chan->op[opNum]) ); + OpOffsetTable[i] = ChanOffsetTable[ chNum ] + blah; + } +#if 0 + //Stupid checks if table's are correct + for ( Bitu i = 0; i < 18; i++ ) { + Bit32u find = (Bit16u)( &(chip->chan[ i ]) ); + for ( Bitu c = 0; c < 32; c++ ) { + if ( ChanOffsetTable[c] == find ) { + find = 0; + break; + } + } + if ( find ) { + find = find; + } + } + for ( Bitu i = 0; i < 36; i++ ) { + Bit32u find = (Bit16u)( &(chip->chan[ i / 2 ].op[i % 2]) ); + for ( Bitu c = 0; c < 64; c++ ) { + if ( OpOffsetTable[c] == find ) { + find = 0; + break; + } + } + if ( find ) { + find = find; + } + } +#endif +} + +Bit32u Handler::WriteAddr( Bit32u port, Bit8u val ) { + return chip.WriteAddr( port, val ); + +} +void Handler::WriteReg( Bit32u addr, Bit8u val ) { + chip.WriteReg( addr, val ); +} + +void Handler::Generate( MixerChannel* chan, Bitu samples ) { + if ( !chip.opl3Active ) { + chip.GenerateBlock2( samples ); + chan->AddSamples_m32( samples, Work.output ); + } else { + chip.GenerateBlock3( samples ); + chan->AddSamples_s32( samples, Work.output ); + } +} + +void Handler::Init( Bitu rate ) { + InitTables(); + chip.Setup( rate ); +} + + +}; //Namespace Kiet diff --git a/src/hardware/dbopl.h b/src/hardware/dbopl.h new file mode 100644 index 00000000..2d08bf7b --- /dev/null +++ b/src/hardware/dbopl.h @@ -0,0 +1,250 @@ +/* + * 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. + */ + +#include "adlib.h" +#include "dosbox.h" + +//Use 8 handlers based on a small logatirmic wavetabe and an exponential table for volume +#define WAVE_HANDLER 10 +//Use a logarithmic wavetable with an exponential table for volume +#define WAVE_TABLELOG 11 +//Use a linear wavetable with a multiply table for volume +#define WAVE_TABLEMUL 12 + +//Select the type of wave generator routine +#define DBOPL_WAVE WAVE_HANDLER +//Enable vibrato in the output +#define DBOPL_VIBRATO +//Enable tremolo in the output +#define DBOPL_TREMOLO + +namespace DBOPL { + +struct Chip; +struct Operator; +struct Channel; + +#if (DBOPL_WAVE == WAVE_HANDLER) +typedef Bits ( FASTCALL *WaveHandler) ( Bitu i, Bitu volume ); +#endif + +typedef Bits ( DBOPL::Operator::*VolumeHandler) ( ); +typedef Channel* ( DBOPL::Channel::*SynthHandler) ( ); + +//Different synth modes that can generate blocks of data +typedef enum { + smNone, + sm2AM, + sm2FM, + sm2Rhytm, + sm3AM, + sm3FM, + sm3FMFM, + sm3AMFM, + sm3FMAM, + sm3AMAM, + sm3Rhytm, +} SynthMode; + +//Shifts for the values contained in chandata variable +enum { + SHIFT_KSLBASE = 16, + SHIFT_KEYCODE = 24, +}; + +struct Operator { +public: + //Masks for operator 20 values + enum { + MASK_KSR = 0x10, + MASK_SUSTAIN = 0x20, + MASK_VIBRATO = 0x40, + MASK_TREMOLO = 0x80, + }; + + typedef enum { + OFF, + RELEASE, + SUSTAIN, + DECAY, + ATTACK, + } State; + + VolumeHandler volHandler; + +#if (DBOPL_WAVE == WAVE_HANDLER) + WaveHandler waveHandler; //Routine that generate a wave +#else + Bit16s* waveBase; + Bit32u waveMask; + Bit32u waveStart; +#endif + Bit32u waveIndex; //WAVE_BITS shifted counter of the frequency index + Bit32u waveAdd; + + Bit32u chanData; //Frequency/octave and derived data coming from whatever channel controls this + Bit32u freqMul; //Scale channel frequency with this, TODO maybe remove? + Bit32u vibrato; //Scaled up vibrato strength + Bit32s sustainLevel; //When stopping at sustain level stop here + Bit32s totalLevel; //totalLeve is added to every generated volume + Bit32s activeLevel; //The currently active volume + + Bit32u attackAdd; //Timers for the different states of the envelope + Bit32u decayAdd; + Bit32u releaseAdd; + Bit32u rateIndex; //Current position of the evenlope + + Bit8u rateZero; //Bits for the different states of the envelope having no changes + Bit8u keyOn; //Bitmask of different values that can generate keyon + //Registers, also used to check for changes + Bit8u reg20, reg40, reg60, reg80, regE0; + //Active part of the envelope we're in + Bit8u state; + //0xff when tremolo is enabled + Bit8u tremoloMask; + //Strength of the vibrato + Bit8u vibStrength; + //Keep track of the calculated KSR so we can check for changes + Bit8u ksr; + +private: + void SetState( Bit8u s ); + void UpdateAttack( const Chip* chip ); + void UpdateRelease( const Chip* chip ); + void UpdateDecay( const Chip* chip ); +public: + //is the operator silent? + void UpdateAttenuation(); + void UpdateRates( const Chip* chip ); + void UpdateFrequency( ); + + void Write20( const Chip* chip, Bit8u val ); + void Write40( const Chip* chip, Bit8u val ); + void Write60( const Chip* chip, Bit8u val ); + void Write80( const Chip* chip, Bit8u val ); + void WriteE0( const Chip* chip, Bit8u val ); + + bool Silent() const; + void KeyOn( Bit8u mask); + void KeyOff( Bit8u mask); + + template< State state> + Bits TemplateVolume( ); + + Bit32s RateForward( Bit32u add ); + Bitu ForwardWave(); + Bitu ForwardVolume(); + + Bits GetSample( Bits modulation ); + Bits GetWave( Bitu index, Bitu vol ); +public: + Operator(); +}; + +struct Channel { + Operator op[2]; + inline Operator* Op( Bitu index ) { + return &( ( this + (index >> 1) )->op[ index & 1 ]); + } + SynthHandler synthHandler; + Bit32u chanData; //Frequency/octave and derived values + Bit32s old[2]; //Old data for feedback + + Bit8u feedback; //Feedback shift + Bit8u regB0; //Register values to check for changes + Bit8u regC0; + //This should correspond with reg104, bit 6 indicates a rhytm channel, bit 7 indicates a silent channel + Bit8u fourMask; + Bit8s maskLeft; //Sign extended values for both channel's panning + Bit8s maskRight; + + //Forward the channel data to the operators of the channel + void SetChanData( const Chip* chip, Bit32u data ); + //Change in the chandata, check for new values and if we have to forward to operators + void UpdateFrequency( const Chip* chip, Bit8u fourOp ); + void WriteA0( const Chip* chip, Bit8u val ); + void WriteB0( const Chip* chip, Bit8u val ); + void WriteC0( const Chip* chip, Bit8u val ); + void ResetC0( const Chip* chip ); + + //call this for the first channel + template< bool opl3Mode > + void GenerateRhytm( Bit32s* output ); + + //Generate blocks of data in specific modes + template + Channel* BlockTemplate( ); + void BlockRhytm( ); + Channel(); +}; + +struct Chip { + //This is used as the base counter for vibrato and tremolo + Bit32u tremoloCounter; + Bit32u tremoloAdd; + Bit32u vibratoCounter; + Bit32u vibratoAdd; + + //Frequency scales for the different multiplications + Bit32u freqMul[16]; + //Rates for decay and release for rate of this chip + Bit32u linearRates[76]; + //Best match attack rates for the rate of this chip + Bit32u attackRates[76]; + + //18 channels with 2 operators each + Channel chan[18]; + + Bit8u reg104; + Bit8u reg08; + Bit8u reg04; + Bit8u regBD; + Bit8u vibratoShift; + Bit8u tremoloShift; + //Mask for allowed wave forms + Bit8u waveFormMask; + //0 or -1 when enabled + Bit8s opl3Active; + + Bit8u ForwardTremolo(); + Bit8s ForwardVibrato(); + + void WriteBD( Bit8u val ); + void WriteReg(Bit32u reg, Bit8u val ); + + Bit32u WriteAddr( Bit32u port, Bit8u val ); + + void GenerateBlock2( Bitu samples ); + void GenerateBlock3( Bitu samples ); + + void Generate( Bit32u samples ); + void Setup( Bit32u r ); + + Chip(); +}; + +struct Handler : public Adlib::Handler { + DBOPL::Chip chip; + virtual Bit32u WriteAddr( Bit32u port, Bit8u val ); + virtual void WriteReg( Bit32u addr, Bit8u val ); + virtual void Generate( MixerChannel* chan, Bitu samples ); + virtual void Init( Bitu rate ); +}; + + +}; //Namespace \ No newline at end of file From 6ba856c857a0ce222a45f9115719426fa91f5054 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 25 Apr 2009 13:59:42 +0000 Subject: [PATCH 3265/4131] add dbopl.* to the makefile Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3353 --- src/hardware/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index 1f602e11..51851435 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -2,7 +2,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include SUBDIRS = serialport -EXTRA_DIST = opl.cpp opl.h fmopl.c fmopl.h ymf262.h ymf262.c adlib.h +EXTRA_DIST = opl.cpp opl.h fmopl.c fmopl.h ymf262.h ymf262.c adlib.h dbopl.h noinst_LIBRARIES = libhardware.a @@ -10,6 +10,6 @@ libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp vga_other.cpp \ vga_memory.cpp vga_misc.cpp vga_seq.cpp vga_xga.cpp vga_s3.cpp vga_tseng.cpp vga_paradise.cpp \ - cmos.cpp disney.cpp gus.cpp mpu401.cpp ipx.cpp ipxserver.cpp + cmos.cpp disney.cpp gus.cpp mpu401.cpp ipx.cpp ipxserver.cpp dbopl.cpp From 5f6236ee356d71ae7903b2f0eb6ffd9b05d0437c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 25 Apr 2009 15:57:07 +0000 Subject: [PATCH 3266/4131] Try to open 128:0 Timidity port as well. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3354 --- src/gui/midi_alsa.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index f9aae8a2..1e64b1ab 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_alsa.h,v 1.17 2007-08-08 08:04:53 qbix79 Exp $ */ +/* $Id: midi_alsa.h,v 1.18 2009-04-25 15:57:07 qbix79 Exp $ */ #define ALSA_PCM_OLD_HW_PARAMS_API #define ALSA_PCM_OLD_SW_PARAMS_API @@ -125,7 +125,7 @@ public: bool Open(const char * conf) { char var[10]; unsigned int caps; - bool defaultport = true; //try 17:0 as well. Seems to be default nowadays + bool defaultport = true; //try 17:0 and 128:0 as well. Seems to be default nowadays // try to use port specified in config file if (conf && conf[0]) { @@ -168,10 +168,13 @@ public: if (snd_seq_connect_to(seq_handle, my_port, seq_client, seq_port) < 0) { if (defaultport) { //if port "65:0" (default) try "17:0" as well seq_client = 17; seq_port = 0; //Update reported values - if(snd_seq_connect_to(seq_handle,my_port,seq_client,seq_port) < 0) { - snd_seq_close(seq_handle); - LOG_MSG("ALSA:Can't subscribe to MIDI port (65:0) nor (17:0)"); - return false; + if(snd_seq_connect_to(seq_handle,my_port,seq_client,seq_port) < 0) { //Try 128:0 Timidity port as well + seq_client = 128; seq_port = 0; //Update reported values + if(snd_seq_connect_to(seq_handle,my_port,seq_client,seq_port) < 0) { + snd_seq_close(seq_handle); + LOG_MSG("ALSA:Can't subscribe to MIDI port (65:0) nor (17:0) nor (128:0)"); + return false; + } } } else { snd_seq_close(seq_handle); From 88caf1dc713ae1d62f2a632f816e514e73a24232 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 25 Apr 2009 16:25:03 +0000 Subject: [PATCH 3267/4131] Add compiler testing for always_inline attribute Add compiler testing for fastcall attribute Add the FASTCALL define to visual c Remove some overkill inline routines Make sure that all the inline routines in headers are static Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3355 --- acinclude.m4 | 13 ++++++- configure.in | 19 ++++++++++ include/callback.h | 8 ++-- include/cpu.h | 12 +++--- include/dos_inc.h | 20 +++++----- include/fpu.h | 16 ++++---- include/inout.h | 6 +-- include/mem.h | 70 +++++++++++++++++------------------ include/mixer.h | 4 +- include/paging.h | 52 +++++++++++++------------- include/pic.h | 8 ++-- include/regs.h | 8 ++-- include/support.h | 14 ++----- src/hardware/dbopl.cpp | 16 ++++---- src/hardware/dbopl.h | 4 +- src/hardware/mixer.cpp | 6 +-- src/ints/int10.h | 6 +-- src/ints/int10_char.cpp | 28 +++++++------- src/misc/support.cpp | 13 ++++++- src/platform/visualc/config.h | 6 +-- 20 files changed, 182 insertions(+), 147 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 2b5d94a1..cab7e791 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -323,7 +323,18 @@ AH_TOP([ */ ]) -AH_BOTTOM([#define INLINE inline]) +AH_BOTTOM([#if C_ATTRIBUTE_ALWAYS_INLINE +#define 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)) diff --git a/configure.in b/configure.in index 1d9f13a9..7ed482af 100644 --- a/configure.in +++ b/configure.in @@ -142,6 +142,25 @@ 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++) diff --git a/include/callback.h b/include/callback.h index faaa8bc0..1c438ec7 100644 --- a/include/callback.h +++ b/include/callback.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.h,v 1.22 2009-01-14 22:16:00 qbix79 Exp $ */ +/* $Id: callback.h,v 1.23 2009-04-25 16:25:03 harekiet Exp $ */ #ifndef DOSBOX_CALLBACK_H #define DOSBOX_CALLBACK_H @@ -43,14 +43,14 @@ enum { extern Bit8u lastint; -INLINE RealPt CALLBACK_RealPointer(Bitu callback) { +static INLINE RealPt CALLBACK_RealPointer(Bitu callback) { return RealMake(CB_SEG,(Bit16u)(callback*CB_SIZE)); } -INLINE PhysPt CALLBACK_PhysPointer(Bitu callback) { +static INLINE PhysPt CALLBACK_PhysPointer(Bitu callback) { return PhysMake(CB_SEG,(Bit16u)(callback*CB_SIZE)); } -INLINE PhysPt CALLBACK_GetBase(void) { +static INLINE PhysPt CALLBACK_GetBase(void) { return CB_SEG << 4; } diff --git a/include/cpu.h b/include/cpu.h index 4a2d14aa..643fc182 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.h,v 1.55 2008-08-24 16:43:06 qbix79 Exp $ */ +/* $Id: cpu.h,v 1.56 2009-04-25 16:25:03 harekiet Exp $ */ #ifndef DOSBOX_CPU_H #define DOSBOX_CPU_H @@ -144,13 +144,13 @@ void CPU_ENTER(bool use32,Bitu bytes,Bitu level); #define CPU_INT_NOIOPLCHECK 0x8 void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip); -INLINE void CPU_HW_Interrupt(Bitu num) { +static INLINE void CPU_HW_Interrupt(Bitu num) { CPU_Interrupt(num,0,reg_eip); } -INLINE void CPU_SW_Interrupt(Bitu num,Bitu oldeip) { +static INLINE void CPU_SW_Interrupt(Bitu num,Bitu oldeip) { CPU_Interrupt(num,CPU_INT_SOFTWARE,oldeip); } -INLINE void CPU_SW_Interrupt_NoIOPLCheck(Bitu num,Bitu oldeip) { +static INLINE void CPU_SW_Interrupt_NoIOPLCheck(Bitu num,Bitu oldeip) { CPU_Interrupt(num,CPU_INT_SOFTWARE|CPU_INT_NOIOPLCHECK,oldeip); } @@ -478,12 +478,12 @@ struct CPUBlock { extern CPUBlock cpu; -INLINE void CPU_SetFlagsd(Bitu word) { +static INLINE void CPU_SetFlagsd(Bitu word) { Bitu mask=cpu.cpl ? FMASK_NORMAL : FMASK_ALL; CPU_SetFlags(word,mask); } -INLINE void CPU_SetFlagsw(Bitu word) { +static INLINE void CPU_SetFlagsw(Bitu word) { Bitu mask=(cpu.cpl ? FMASK_NORMAL : FMASK_ALL) & 0xffff; CPU_SetFlags(word,mask); } diff --git a/include/dos_inc.h b/include/dos_inc.h index f3c6b833..e1d037a4 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.76 2008-09-06 14:47:02 c2woody Exp $ */ +/* $Id: dos_inc.h,v 1.77 2009-04-25 16:25:03 harekiet Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -208,18 +208,18 @@ enum { }; -INLINE Bit16u long2para(Bit32u size) { +static INLINE Bit16u long2para(Bit32u size) { if (size>0xFFFF0) return 0xffff; if (size&0xf) return (Bit16u)((size>>4)+1); else return (Bit16u)(size>>4); } -INLINE Bit16u DOS_PackTime(Bit16u hour,Bit16u min,Bit16u sec) { +static INLINE Bit16u DOS_PackTime(Bit16u hour,Bit16u min,Bit16u sec) { return (hour&0x1f)<<11 | (min&0x3f) << 5 | ((sec/2)&0x1f); } -INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) { +static INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) { return ((year-1980)&0x7f)<<9 | (mon&0x3f) << 5 | (day&0x1f); } @@ -254,7 +254,7 @@ INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) { class MemStruct { public: - INLINE Bitu GetIt(Bitu size,PhysPt addr) { + Bitu GetIt(Bitu size,PhysPt addr) { switch (size) { case 1:return mem_readb(pt+addr); case 2:return mem_readw(pt+addr); @@ -262,16 +262,16 @@ public: } return 0; } - INLINE void SaveIt(Bitu size,PhysPt addr,Bitu val) { + void SaveIt(Bitu size,PhysPt addr,Bitu val) { switch (size) { case 1:mem_writeb(pt+addr,(Bit8u)val);break; case 2:mem_writew(pt+addr,(Bit16u)val);break; case 4:mem_writed(pt+addr,(Bit32u)val);break; } } - INLINE void SetPt(Bit16u seg) { pt=PhysMake(seg,0);} - INLINE void SetPt(Bit16u seg,Bit16u off) { pt=PhysMake(seg,off);} - INLINE void SetPt(RealPt addr) { pt=Real2Phys(addr);} + void SetPt(Bit16u seg) { pt=PhysMake(seg,0);} + void SetPt(Bit16u seg,Bit16u off) { pt=PhysMake(seg,off);} + void SetPt(RealPt addr) { pt=Real2Phys(addr);} protected: PhysPt pt; }; @@ -635,7 +635,7 @@ struct DOS_Block { extern DOS_Block dos; -INLINE Bit8u RealHandle(Bit16u handle) { +static Bit8u RealHandle(Bit16u handle) { DOS_PSP psp(dos.psp()); return psp.GetFileHandle(handle); } diff --git a/include/fpu.h b/include/fpu.h index 2c071801..92dd3aab 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -108,44 +108,44 @@ extern FPU_rec fpu; Bit16u FPU_GetTag(void); void FPU_FLDCW(PhysPt addr); -INLINE void FPU_SetTag(Bit16u tag){ +static INLINE void FPU_SetTag(Bit16u tag){ for(Bitu i=0;i<8;i++) fpu.tags[i] = static_cast((tag >>(2*i))&3); } -INLINE void FPU_SetCW(Bitu word){ +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); } -INLINE Bitu FPU_GET_TOP(void) { +static INLINE Bitu FPU_GET_TOP(void) { return (fpu.sw & 0x3800)>>11; } -INLINE void FPU_SET_TOP(Bitu val){ +static INLINE void FPU_SET_TOP(Bitu val){ fpu.sw &= ~0x3800; fpu.sw |= (val&7)<<11; } -INLINE void FPU_SET_C0(Bitu C){ +static INLINE void FPU_SET_C0(Bitu C){ fpu.sw &= ~0x0100; if(C) fpu.sw |= 0x0100; } -INLINE void FPU_SET_C1(Bitu C){ +static INLINE void FPU_SET_C1(Bitu C){ fpu.sw &= ~0x0200; if(C) fpu.sw |= 0x0200; } -INLINE void FPU_SET_C2(Bitu C){ +static INLINE void FPU_SET_C2(Bitu C){ fpu.sw &= ~0x0400; if(C) fpu.sw |= 0x0400; } -INLINE void FPU_SET_C3(Bitu C){ +static INLINE void FPU_SET_C3(Bitu C){ fpu.sw &= ~0x4000; if(C) fpu.sw |= 0x4000; } diff --git a/include/inout.h b/include/inout.h index 06987c51..9e3c0329 100644 --- a/include/inout.h +++ b/include/inout.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: inout.h,v 1.11 2007-06-12 20:22:07 c2woody Exp $ */ +/* $Id: inout.h,v 1.12 2009-04-25 16:25:03 harekiet Exp $ */ #ifndef DOSBOX_INOUT_H #define DOSBOX_INOUT_H @@ -68,10 +68,10 @@ public: ~IO_WriteHandleObject(); }; -INLINE void IO_Write(Bitu port,Bit8u val) { +static INLINE void IO_Write(Bitu port,Bit8u val) { IO_WriteB(port,val); } -INLINE Bit8u IO_Read(Bitu port){ +static INLINE Bit8u IO_Read(Bitu port){ return (Bit8u)IO_ReadB(port); } diff --git a/include/mem.h b/include/mem.h index f9128dad..7a2cfb99 100644 --- a/include/mem.h +++ b/include/mem.h @@ -59,23 +59,23 @@ MemHandle MEM_NextHandleAt(MemHandle handle,Bitu where); #if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) -INLINE Bit8u host_readb(HostPt off) { +static 4/25/2009INLINE Bit8u host_readb(HostPt off) { return off[0]; } -INLINE Bit16u host_readw(HostPt off) { +static INLINE Bit16u host_readw(HostPt off) { return off[0] | (off[1] << 8); } -INLINE Bit32u host_readd(HostPt off) { +static INLINE Bit32u host_readd(HostPt off) { return off[0] | (off[1] << 8) | (off[2] << 16) | (off[3] << 24); } -INLINE void host_writeb(HostPt off,Bit8u val) { +static INLINE void host_writeb(HostPt off,Bit8u val) { off[0]=val; } -INLINE void host_writew(HostPt off,Bit16u val) { +static INLINE void host_writew(HostPt off,Bit16u val) { off[0]=(Bit8u)(val); off[1]=(Bit8u)(val >> 8); } -INLINE void host_writed(HostPt off,Bit32u val) { +static INLINE void host_writed(HostPt off,Bit32u val) { off[0]=(Bit8u)(val); off[1]=(Bit8u)(val >> 8); off[2]=(Bit8u)(val >> 16); @@ -84,37 +84,37 @@ INLINE void host_writed(HostPt off,Bit32u val) { #else -INLINE Bit8u host_readb(HostPt off) { +static INLINE Bit8u host_readb(HostPt off) { return *(Bit8u *)off; } -INLINE Bit16u host_readw(HostPt off) { +static INLINE Bit16u host_readw(HostPt off) { return *(Bit16u *)off; } -INLINE Bit32u host_readd(HostPt off) { +static INLINE Bit32u host_readd(HostPt off) { return *(Bit32u *)off; } -INLINE void host_writeb(HostPt off,Bit8u val) { +static INLINE void host_writeb(HostPt off,Bit8u val) { *(Bit8u *)(off)=val; } -INLINE void host_writew(HostPt off,Bit16u val) { +static INLINE void host_writew(HostPt off,Bit16u val) { *(Bit16u *)(off)=val; } -INLINE void host_writed(HostPt off,Bit32u val) { +static INLINE void host_writed(HostPt off,Bit32u val) { *(Bit32u *)(off)=val; } #endif -INLINE void var_write(Bit8u * var, Bit8u val) { +static INLINE void var_write(Bit8u * var, Bit8u val) { host_writeb((HostPt)var, val); } -INLINE void var_write(Bit16u * var, Bit16u val) { +static INLINE void var_write(Bit16u * var, Bit16u val) { host_writew((HostPt)var, val); } -INLINE void var_write(Bit32u * var, Bit32u val) { +static INLINE void var_write(Bit32u * var, Bit32u val) { host_writed((HostPt)var, val); } @@ -128,23 +128,23 @@ void mem_writeb(PhysPt pt,Bit8u val); void mem_writew(PhysPt pt,Bit16u val); void mem_writed(PhysPt pt,Bit32u val); -INLINE void phys_writeb(PhysPt addr,Bit8u val) { +static INLINE void phys_writeb(PhysPt addr,Bit8u val) { host_writeb(MemBase+addr,val); } -INLINE void phys_writew(PhysPt addr,Bit16u val){ +static INLINE void phys_writew(PhysPt addr,Bit16u val){ host_writew(MemBase+addr,val); } -INLINE void phys_writed(PhysPt addr,Bit32u val){ +static INLINE void phys_writed(PhysPt addr,Bit32u val){ host_writed(MemBase+addr,val); } -INLINE Bit8u phys_readb(PhysPt addr) { +static INLINE Bit8u phys_readb(PhysPt addr) { return host_readb(MemBase+addr); } -INLINE Bit16u phys_readw(PhysPt addr){ +static INLINE Bit16u phys_readw(PhysPt addr){ return host_readw(MemBase+addr); } -INLINE Bit32u phys_readd(PhysPt addr){ +static INLINE Bit32u phys_readd(PhysPt addr){ return host_readd(MemBase+addr); } @@ -161,57 +161,57 @@ void mem_strcpy(PhysPt dest,PhysPt src); /* The folowing functions are all shortcuts to the above functions using physical addressing */ -INLINE Bit8u real_readb(Bit16u seg,Bit16u off) { +static INLINE Bit8u real_readb(Bit16u seg,Bit16u off) { return mem_readb((seg<<4)+off); } -INLINE Bit16u real_readw(Bit16u seg,Bit16u off) { +static INLINE Bit16u real_readw(Bit16u seg,Bit16u off) { return mem_readw((seg<<4)+off); } -INLINE Bit32u real_readd(Bit16u seg,Bit16u off) { +static INLINE Bit32u real_readd(Bit16u seg,Bit16u off) { return mem_readd((seg<<4)+off); } -INLINE void real_writeb(Bit16u seg,Bit16u off,Bit8u val) { +static INLINE void real_writeb(Bit16u seg,Bit16u off,Bit8u val) { mem_writeb(((seg<<4)+off),val); } -INLINE void real_writew(Bit16u seg,Bit16u off,Bit16u val) { +static INLINE void real_writew(Bit16u seg,Bit16u off,Bit16u val) { mem_writew(((seg<<4)+off),val); } -INLINE void real_writed(Bit16u seg,Bit16u off,Bit32u val) { +static INLINE void real_writed(Bit16u seg,Bit16u off,Bit32u val) { mem_writed(((seg<<4)+off),val); } -INLINE Bit16u RealSeg(RealPt pt) { +static INLINE Bit16u RealSeg(RealPt pt) { return (Bit16u)(pt>>16); } -INLINE Bit16u RealOff(RealPt pt) { +static INLINE Bit16u RealOff(RealPt pt) { return (Bit16u)(pt&0xffff); } -INLINE PhysPt Real2Phys(RealPt pt) { +static INLINE PhysPt Real2Phys(RealPt pt) { return (RealSeg(pt)<<4) +RealOff(pt); } -INLINE PhysPt PhysMake(Bit16u seg,Bit16u off) { +static INLINE PhysPt PhysMake(Bit16u seg,Bit16u off) { return (seg<<4)+off; } -INLINE RealPt RealMake(Bit16u seg,Bit16u off) { +static INLINE RealPt RealMake(Bit16u seg,Bit16u off) { return (seg<<16)+off; } -INLINE void RealSetVec(Bit8u vec,RealPt pt) { +static INLINE void RealSetVec(Bit8u vec,RealPt pt) { mem_writed(vec<<2,pt); } -INLINE void RealSetVec(Bit8u vec,RealPt pt,RealPt &old) { +static INLINE void RealSetVec(Bit8u vec,RealPt pt,RealPt &old) { old = mem_readd(vec<<2); mem_writed(vec<<2,pt); } -INLINE RealPt RealGetVec(Bit8u vec) { +static INLINE RealPt RealGetVec(Bit8u vec) { return mem_readd(vec<<2); } diff --git a/include/mixer.h b/include/mixer.h index a614f524..d8585a35 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.h,v 1.17 2009-03-19 20:45:42 c2woody Exp $ */ +/* $Id: mixer.h,v 1.18 2009-04-25 16:25:03 harekiet Exp $ */ #ifndef DOSBOX_MIXER_H #define DOSBOX_MIXER_H @@ -52,8 +52,10 @@ public: void SetFreq(Bitu _freq); void Mix(Bitu _needed); void AddSilence(void); //Fill up until needed + template 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); diff --git a/include/paging.h b/include/paging.h index d9935b14..1b09a109 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.31 2008-01-05 21:04:43 c2woody Exp $ */ +/* $Id: paging.h,v 1.32 2009-04-25 16:25:03 harekiet Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H @@ -197,25 +197,25 @@ bool mem_unalignedwrited_checked(PhysPt address,Bit32u val); #if defined(USE_FULL_TLB) -INLINE HostPt get_tlb_read(PhysPt address) { +static INLINE HostPt get_tlb_read(PhysPt address) { return paging.tlb.read[address>>12]; } -INLINE HostPt get_tlb_write(PhysPt address) { +static INLINE HostPt get_tlb_write(PhysPt address) { return paging.tlb.write[address>>12]; } -INLINE PageHandler* get_tlb_readhandler(PhysPt address) { +static INLINE PageHandler* get_tlb_readhandler(PhysPt address) { return paging.tlb.readhandler[address>>12]; } -INLINE PageHandler* get_tlb_writehandler(PhysPt address) { +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 */ -INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { +static INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { return (paging.tlb.phys_page[linePage>>12]<<12); } -INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { +static INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { return (paging.tlb.phys_page[linAddr>>12]<<12)|(linAddr&0xfff); } @@ -223,7 +223,7 @@ INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { void PAGING_InitTLBBank(tlb_entry **bank); -INLINE tlb_entry *get_tlb_entry(PhysPt address) { +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; @@ -234,26 +234,26 @@ INLINE tlb_entry *get_tlb_entry(PhysPt address) { return &paging.tlbh[index]; } -INLINE HostPt get_tlb_read(PhysPt address) { +static INLINE HostPt get_tlb_read(PhysPt address) { return get_tlb_entry(address)->read; } -INLINE HostPt get_tlb_write(PhysPt address) { +static INLINE HostPt get_tlb_write(PhysPt address) { return get_tlb_entry(address)->write; } -INLINE PageHandler* get_tlb_readhandler(PhysPt address) { +static INLINE PageHandler* get_tlb_readhandler(PhysPt address) { return get_tlb_entry(address)->readhandler; } -INLINE PageHandler* get_tlb_writehandler(PhysPt address) { +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 */ -INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { +static INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { tlb_entry *entry = get_tlb_entry(linePage); return (entry->phys_page<<12); } -INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { +static INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { tlb_entry *entry = get_tlb_entry(linAddr); return (entry->phys_page<<12)|(linAddr&0xfff); } @@ -261,13 +261,13 @@ INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { /* Special inlined memory reading/writing */ -INLINE Bit8u mem_readb_inline(PhysPt address) { +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); } -INLINE Bit16u mem_readw_inline(PhysPt 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); @@ -275,7 +275,7 @@ INLINE Bit16u mem_readw_inline(PhysPt address) { } else return mem_unalignedreadw(address); } -INLINE Bit32u mem_readd_inline(PhysPt 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); @@ -283,13 +283,13 @@ INLINE Bit32u mem_readd_inline(PhysPt address) { } else return mem_unalignedreadd(address); } -INLINE void mem_writeb_inline(PhysPt address,Bit8u val) { +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); } -INLINE void mem_writew_inline(PhysPt address,Bit16u 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); @@ -297,7 +297,7 @@ INLINE void mem_writew_inline(PhysPt address,Bit16u val) { } else mem_unalignedwritew(address,val); } -INLINE void mem_writed_inline(PhysPt address,Bit32u 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); @@ -306,7 +306,7 @@ INLINE void mem_writed_inline(PhysPt address,Bit32u val) { } -INLINE bool mem_readb_checked(PhysPt address, Bit8u * 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); @@ -314,7 +314,7 @@ INLINE bool mem_readb_checked(PhysPt address, Bit8u * val) { } else return (get_tlb_readhandler(address))->readb_checked(address, val); } -INLINE bool mem_readw_checked(PhysPt address, Bit16u * 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) { @@ -324,7 +324,7 @@ INLINE bool mem_readw_checked(PhysPt address, Bit16u * val) { } else return mem_unalignedreadw_checked(address, val); } -INLINE bool mem_readd_checked(PhysPt address, Bit32u * 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) { @@ -334,7 +334,7 @@ INLINE bool mem_readd_checked(PhysPt address, Bit32u * val) { } else return mem_unalignedreadd_checked(address, val); } -INLINE bool mem_writeb_checked(PhysPt address,Bit8u 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); @@ -342,7 +342,7 @@ INLINE bool mem_writeb_checked(PhysPt address,Bit8u val) { } else return (get_tlb_writehandler(address))->writeb_checked(address,val); } -INLINE bool mem_writew_checked(PhysPt address,Bit16u 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) { @@ -352,7 +352,7 @@ INLINE bool mem_writew_checked(PhysPt address,Bit16u val) { } else return mem_unalignedwritew_checked(address,val); } -INLINE bool mem_writed_checked(PhysPt address,Bit32u 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) { diff --git a/include/pic.h b/include/pic.h index 420a1fe5..9d68e6b0 100644 --- a/include/pic.h +++ b/include/pic.h @@ -36,19 +36,19 @@ extern Bitu PIC_IRQCheck; extern Bitu PIC_IRQActive; extern Bitu PIC_Ticks; -INLINE float PIC_TickIndex(void) { +static INLINE float PIC_TickIndex(void) { return (CPU_CycleMax-CPU_CycleLeft-CPU_Cycles)/(float)CPU_CycleMax; } -INLINE Bits PIC_TickIndexND(void) { +static INLINE Bits PIC_TickIndexND(void) { return CPU_CycleMax-CPU_CycleLeft-CPU_Cycles; } -INLINE Bits PIC_MakeCycles(double amount) { +static INLINE Bits PIC_MakeCycles(double amount) { return (Bits)(CPU_CycleMax*amount); } -INLINE double PIC_FullIndex(void) { +static INLINE double PIC_FullIndex(void) { return PIC_Ticks+(double)PIC_TickIndex(); } diff --git a/include/regs.h b/include/regs.h index 8f8445f4..59d7a761 100644 --- a/include/regs.h +++ b/include/regs.h @@ -93,20 +93,20 @@ struct CPU_Regs { extern Segments Segs; extern CPU_Regs cpu_regs; -INLINE PhysPt SegPhys(SegNames index) { +static INLINE PhysPt SegPhys(SegNames index) { return Segs.phys[index]; } -INLINE Bit16u SegValue(SegNames index) { +static INLINE Bit16u SegValue(SegNames index) { return (Bit16u)Segs.val[index]; } -INLINE RealPt RealMakeSeg(SegNames index,Bit16u off) { +static INLINE RealPt RealMakeSeg(SegNames index,Bit16u off) { return RealMake(SegValue(index),off); } -INLINE void SegSet16(Bitu index,Bit16u val) { +static INLINE void SegSet16(Bitu index,Bit16u val) { Segs.val[index]=val; Segs.phys[index]=val << 4; } diff --git a/include/support.h b/include/support.h index 5933de19..3c10a386 100644 --- a/include/support.h +++ b/include/support.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.h,v 1.16 2008-01-13 11:28:41 qbix79 Exp $ */ +/* $Id: support.h,v 1.17 2009-04-25 16:25:03 harekiet Exp $ */ #ifndef DOSBOX_SUPPORT_H #define DOSBOX_SUPPORT_H @@ -43,6 +43,8 @@ void strreplace(char * str,char o,char n); char *ltrim(char *str); char *rtrim(char *str); char *trim(char * str); +char * upcase(char * str); +char * lowcase(char * str); bool ScanCMDBool(char * cmd,char const * const check); char * ScanCMDRemain(char * cmd); @@ -52,16 +54,6 @@ bool IsHexWord(char * word); Bits ConvDecWord(char * word); Bits ConvHexWord(char * word); -INLINE char * upcase(char * str) { - for (char* idx = str; *idx ; idx++) *idx = toupper(*reinterpret_cast(idx)); - return str; -} - -INLINE char * lowcase(char * str) { - for(char* idx = str; *idx ; idx++) *idx = tolower(*reinterpret_cast(idx)); - return str; -} - void upcase(std::string &str); void lowcase(std::string &str); diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index 1d12af12..be8830cd 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -218,26 +218,26 @@ static inline Bits MakeVolume( Bitu wave, Bitu volume ) { return (sig >> exp); }; -static Bits FASTCALL WaveForm0( Bitu i, Bitu volume ) { +static Bits DB_FASTCALL WaveForm0( Bitu i, Bitu volume ) { Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 Bitu wave = SinTable[i & 511]; return (MakeVolume( wave, volume ) ^ neg) - neg; } -static Bits FASTCALL WaveForm1( Bitu i, Bitu volume ) { +static Bits DB_FASTCALL WaveForm1( Bitu i, Bitu volume ) { Bit32u wave = SinTable[i & 511]; wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 ); return MakeVolume( wave, volume ); } -static Bits FASTCALL WaveForm2( Bitu i, Bitu volume ) { +static Bits DB_FASTCALL WaveForm2( Bitu i, Bitu volume ) { Bitu wave = SinTable[i & 511]; return MakeVolume( wave, volume ); } -static Bits FASTCALL WaveForm3( Bitu i, Bitu volume ) { +static Bits DB_FASTCALL WaveForm3( Bitu i, Bitu volume ) { Bitu wave = SinTable[i & 255]; wave |= ( ( (i ^ 256 ) & 256) - 1) >> ( 32 - 12 ); return MakeVolume( wave, volume ); } -static Bits FASTCALL WaveForm4( Bitu i, Bitu volume ) { +static Bits DB_FASTCALL WaveForm4( Bitu i, Bitu volume ) { //Twice as fast i <<= 1; Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 @@ -245,18 +245,18 @@ static Bits FASTCALL WaveForm4( Bitu i, Bitu volume ) { wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 ); return (MakeVolume( wave, volume ) ^ neg) - neg; } -static Bits FASTCALL WaveForm5( Bitu i, Bitu volume ) { +static Bits DB_FASTCALL WaveForm5( Bitu i, Bitu volume ) { //Twice as fast i <<= 1; Bitu wave = SinTable[i & 511]; wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 ); return MakeVolume( wave, volume ); } -static Bits FASTCALL WaveForm6( Bitu i, Bitu volume ) { +static Bits DB_FASTCALL WaveForm6( Bitu i, Bitu volume ) { Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 return (MakeVolume( 0, volume ) ^ neg) - neg; } -static Bits FASTCALL WaveForm7( Bitu i, Bitu volume ) { +static Bits DB_FASTCALL WaveForm7( Bitu i, Bitu volume ) { //Negative is reversed here Bits neg = (( i >> 9) & 1) - 1; Bitu wave = (i << 3); diff --git a/src/hardware/dbopl.h b/src/hardware/dbopl.h index 2d08bf7b..f42a330d 100644 --- a/src/hardware/dbopl.h +++ b/src/hardware/dbopl.h @@ -40,7 +40,7 @@ struct Operator; struct Channel; #if (DBOPL_WAVE == WAVE_HANDLER) -typedef Bits ( FASTCALL *WaveHandler) ( Bitu i, Bitu volume ); +typedef Bits ( DB_FASTCALL *WaveHandler) ( Bitu i, Bitu volume ); #endif typedef Bits ( DBOPL::Operator::*VolumeHandler) ( ); @@ -247,4 +247,4 @@ struct Handler : public Adlib::Handler { }; -}; //Namespace \ No newline at end of file +}; //Namespace diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index fc8a4d98..3c8cb9f8 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.50 2009-03-19 20:45:42 c2woody Exp $ */ +/* $Id: mixer.cpp,v 1.51 2009-04-25 16:25:03 harekiet Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -55,7 +55,7 @@ #define MIXER_REMAIN ((1< MIN_AUDIO) return SAMP; @@ -175,7 +175,7 @@ void MixerChannel::AddSilence(void) { } template -INLINE void MixerChannel::AddSamples(Bitu len, const Type* data) { +inline void MixerChannel::AddSamples(Bitu len, const Type* data) { Bits diff[2]; Bitu mixpos=mixer.pos+done; freq_index&=MIXER_REMAIN; diff --git a/src/ints/int10.h b/src/ints/int10.h index 6eae71e3..9f84ed03 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.h,v 1.37 2009-04-11 07:58:39 qbix79 Exp $ */ +/* $Id: int10.h,v 1.38 2009-04-25 16:25:03 harekiet Exp $ */ #include "vga.h" @@ -146,11 +146,11 @@ typedef struct { extern Int10Data int10; -INLINE Bit8u CURSOR_POS_COL(Bit8u page) { +static Bit8u CURSOR_POS_COL(Bit8u page) { return real_readb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2); } -INLINE Bit8u CURSOR_POS_ROW(Bit8u page) { +static Bit8u CURSOR_POS_ROW(Bit8u page) { return real_readb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2+1); } diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 6789be59..c4c201e2 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.56 2008-11-09 11:22:03 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.57 2009-04-25 16:25:03 harekiet Exp $ */ /* Character displaying moving functions */ @@ -26,7 +26,7 @@ #include "inout.h" #include "int10.h" -static INLINE void CGA2_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { +static void CGA2_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); PhysPt dest=base+((CurMode->twidth*rnew)*(cheight/2)+cleft); PhysPt src=base+((CurMode->twidth*rold)*(cheight/2)+cleft); @@ -39,7 +39,7 @@ static INLINE void CGA2_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,P } } -static INLINE void CGA4_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { +static void CGA4_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); PhysPt dest=base+((CurMode->twidth*rnew)*(cheight/2)+cleft)*2; PhysPt src=base+((CurMode->twidth*rold)*(cheight/2)+cleft)*2; @@ -51,7 +51,7 @@ static INLINE void CGA4_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,P } } -static INLINE void TANDY16_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { +static void TANDY16_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); PhysPt dest=base+((CurMode->twidth*rnew)*(cheight/4)+cleft)*4; PhysPt src=base+((CurMode->twidth*rold)*(cheight/4)+cleft)*4; @@ -65,7 +65,7 @@ static INLINE void TANDY16_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rne } } -static INLINE void EGA16_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { +static void EGA16_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { PhysPt src,dest;Bitu copy; Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); dest=base+(CurMode->twidth*rnew)*cheight+cleft; @@ -85,7 +85,7 @@ static INLINE void EGA16_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew, IO_Write(0x3ce,5);IO_Write(0x3cf,0); /* Normal transfer mode */ } -static INLINE void VGA_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { +static void VGA_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { PhysPt src,dest;Bitu copy; Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); dest=base+8*((CurMode->twidth*rnew)*cheight+cleft); @@ -99,14 +99,14 @@ static INLINE void VGA_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,Ph } } -static INLINE void TEXT_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { +static void TEXT_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { PhysPt src,dest; src=base+(rold*CurMode->twidth+cleft)*2; dest=base+(rnew*CurMode->twidth+cleft)*2; MEM_BlockCopy(dest,src,(cright-cleft)*2); } -static INLINE void CGA2_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { +static void CGA2_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); PhysPt dest=base+((CurMode->twidth*row)*(cheight/2)+cleft); Bitu copy=(cright-cleft); @@ -122,7 +122,7 @@ static INLINE void CGA2_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,B } -static INLINE void CGA4_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { +static void CGA4_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); PhysPt dest=base+((CurMode->twidth*row)*(cheight/2)+cleft)*2; Bitu copy=(cright-cleft)*2;Bitu nextline=CurMode->twidth*2; @@ -136,7 +136,7 @@ static INLINE void CGA4_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,B } } -static INLINE void TANDY16_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { +static void TANDY16_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); PhysPt dest=base+((CurMode->twidth*row)*(cheight/4)+cleft)*4; Bitu copy=(cright-cleft)*4;Bitu nextline=CurMode->twidth*4; @@ -152,7 +152,7 @@ static INLINE void TANDY16_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt bas } } -static INLINE void EGA16_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { +static void EGA16_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { /* Set Bitmask / Color / Full Set Reset */ IO_Write(0x3ce,0x8);IO_Write(0x3cf,0xff); IO_Write(0x3ce,0x0);IO_Write(0x3cf,attr); @@ -169,7 +169,7 @@ static INLINE void EGA16_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base, IO_Write(0x3cf,0); } -static INLINE void VGA_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { +static void VGA_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { /* Write some bytes */ Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); PhysPt dest=base+8*((CurMode->twidth*row)*cheight+cleft); @@ -181,7 +181,7 @@ static INLINE void VGA_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bi } } -static INLINE void TEXT_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { +static void TEXT_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u attr) { /* Do some filing */ PhysPt dest; dest=base+(row*CurMode->twidth+cleft)*2; @@ -549,7 +549,7 @@ void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) } } -static INLINE void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr,Bit8u page) { +static void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr,Bit8u page) { BIOS_NCOLS;BIOS_NROWS; Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 7851cbe7..18552eab 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.35 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: support.cpp,v 1.36 2009-04-25 16:25:03 harekiet Exp $ */ #include #include @@ -80,6 +80,17 @@ char *trim(char *str) { return ltrim(rtrim(str)); } +char * upcase(char * str) { + for (char* idx = str; *idx ; idx++) *idx = toupper(*reinterpret_cast(idx)); + return str; +} + +char * lowcase(char * str) { + for(char* idx = str; *idx ; idx++) *idx = tolower(*reinterpret_cast(idx)); + return str; +} + + bool ScanCMDBool(char * cmd,char const * const check) { char * scan=cmd;size_t c_len=strlen(check); diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 630e8b5f..75e9c0cf 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -1,8 +1,5 @@ -#define INLINE __forceinline - #define VERSION "0.72" - /* Define to 1 to enable internal debugger, requires libcurses */ #define C_DEBUG 0 @@ -58,6 +55,9 @@ #define GCC_ATTRIBUTE(x) /* attribute not supported */ #define GCC_UNLIKELY(x) (x) +#define INLINE __forceinline +#define DB_FASTCALL __fastcall + #if defined(_MSC_VER) && (_MSC_VER >= 1400) #pragma warning(disable : 4996) #endif From caeec288c2ae872d55990bd9c37b23b9294415fd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 26 Apr 2009 10:33:53 +0000 Subject: [PATCH 3268/4131] Add a virtual desctuctor so opl handlers free correctly Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3356 --- src/hardware/adlib.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hardware/adlib.h b/src/hardware/adlib.h index 07ae23c9..baa3b586 100644 --- a/src/hardware/adlib.h +++ b/src/hardware/adlib.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: adlib.h,v 1.3 2009-04-25 09:55:50 harekiet Exp $ */ +/* $Id: adlib.h,v 1.4 2009-04-26 10:33:53 harekiet Exp $ */ #ifndef DOSBOX_ADLIB_H #define DOSBOX_ADLIB_H @@ -105,6 +105,8 @@ public: virtual void Generate( MixerChannel* chan, Bitu samples ) = 0; //Initialize at a specific sample rate and mode virtual void Init( Bitu rate ) = 0; + virtual ~Handler() { + } }; //The cache for 2 chips or an opl3 From 423fe84280b7394d8ee83b6070a73b26d7b0918c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 26 Apr 2009 10:36:16 +0000 Subject: [PATCH 3269/4131] Always use the volume table Replace the ultradir char buf with a std::string Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3357 --- src/hardware/gus.cpp | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 934a54f6..325f47e1 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: gus.cpp,v 1.34 2009-04-11 08:02:23 qbix79 Exp $ */ +/* $Id: gus.cpp,v 1.35 2009-04-26 10:36:16 harekiet Exp $ */ #include #include @@ -43,8 +43,6 @@ using namespace std; #define RAMP_FRACT (10) #define RAMP_FRACT_MASK ((1 << RAMP_FRACT)-1) -#define USEVOLTABLE 1 - #define GUS_BASE myGUS.portbase #define GUS_RATE myGUS.rate #define LOG_GUS 0 @@ -54,10 +52,8 @@ static MixerChannel * gus_chan; static Bit8u irqtable[8] = { 0, 2, 5, 3, 7, 11, 12, 15 }; static Bit8u dmatable[8] = { 0, 1, 3, 5, 6, 7, 0, 0 }; static Bit8u GUSRam[1024*1024]; // 1024K of GUS Ram -static Bit32s AutoAmp=512; -#if USEVOLTABLE +static Bit32s AutoAmp = 512; static Bit16u vol16bit[4096]; -#endif static Bit32u pantable[16]; class GUSChannels; @@ -93,7 +89,7 @@ struct GFGus { Bit8u irq1; Bit8u irq2; - char ultradir[512]; + std::string ultradir; bool irqenabled; bool ChangeIRQDMA; // IRQ status register values @@ -272,12 +268,8 @@ public: templeft&=~(templeft >> 31); Bit32s tempright=RampVol - PanRight; tempright&=~(tempright >> 31); -#if USEVOLTABLE VolLeft=vol16bit[templeft >> RAMP_FRACT]; VolRight=vol16bit[tempright >> RAMP_FRACT]; -#else - -#endif } INLINE void RampUpdate(void) { /* Check if ramping enabled */ @@ -772,13 +764,11 @@ static void GUS_CallBack(Bitu len) { // Generate logarithmic to linear volume conversion tables static void MakeTables(void) { int i; -#if USEVOLTABLE double out = (double)(1 << 13); for (i=4095;i>=0;i--) { vol16bit[i]=(Bit16s)out; out/=1.002709201; /* 0.0235 dB Steps */ } -#endif pantable[0]=0; for (i=1;i<16;i++) { pantable[i]=(Bit32u)(-128.0*(log((double)i/15.0)/log(2.0))*(double)(1 << RAMP_FRACT)); @@ -812,7 +802,7 @@ public: myGUS.irq1 = (Bit8u)irq_val; myGUS.irq2 = (Bit8u)irq_val; - strcpy(&myGUS.ultradir[0], section->Get_string("ultradir")); + myGUS.ultradir = section->Get_string("ultradir"); // We'll leave the MIDI interface to the MPU-401 // Ditto for the Joystick From 4ebdd5114a8024e57e33fba2104e6fbf59f05fba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 26 Apr 2009 15:37:04 +0000 Subject: [PATCH 3270/4131] add dbopl to vs project file; fix internal opl rate of dbopl; change opl provider selection and default Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3358 --- src/dosbox.cpp | 17 +++++++++-------- src/hardware/adlib.cpp | 8 +++++--- src/hardware/dbopl.cpp | 8 ++++---- visualc_net/dosbox.vcproj | 3 +++ 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index e8d63d8b..19661808 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.147 2009-04-17 17:24:47 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.148 2009-04-26 15:37:04 c2woody Exp $ */ #include #include @@ -312,7 +312,8 @@ void DOSBOX_Init(void) { SDLNetInited = false; // Some frequently used option sets - const char *rates[] = { "22050", "44100", "48000", "32000", "16000", "11025", "8000", 0 }; + const char *rates[] = { "22050", "44100", "48000", "32000", "16000", "11025", "8000", "49716", 0 }; + const char *oplrates[] = { "22050", "49716", "44100", "48000", "32000", "16000", "11025", "8000", 0 }; const char *ios[] = { "220", "240", "260", "280", "2a0", "2c0", "2e0", "300", 0 }; const char *irqssb[] = { "7", "5", "3", "9", "10", "11", "12", 0 }; const char *dmassb[] = { "1", "5", "0", "3", "6", "7", 0 }; @@ -439,7 +440,7 @@ void DOSBOX_Init(void) { Pint = secprop->Add_int("rate",Property::Changeable::OnlyAtStart,22050); Pint->Set_values(rates); - Pint->Set_help("Mixer sample rate, setting any devices higher than this will probably lower their sound quality."); + Pint->Set_help("Mixer sample rate, setting any device's rate higher than this will probably lower their sound quality."); const char *blocksizes[] = { "2048", "4096", "8192", "1024", "512", "256", 0}; @@ -503,14 +504,14 @@ void DOSBOX_Init(void) { Pstring->Set_values(oplmodes); Pstring->Set_help("Type of OPL emulation. On 'auto' the mode is determined by sblaster type. All OPL modes are Adlib-compatible, except for 'cms'."); - const char* oplemus[]={ "default", "old", 0}; - Pstring = secprop->Add_string("oplemu",Property::Changeable::WhenIdle,"auto"); + const char* oplemus[]={ "default", "compat", "fast", "old", 0}; + Pstring = secprop->Add_string("oplemu",Property::Changeable::WhenIdle,"default"); Pstring->Set_values(oplemus); - Pstring->Set_help("Provider for the OPL emulation."); + Pstring->Set_help("Provider for the OPL emulation. compat or old might provide better quality (see oplrate as well)."); Pint = secprop->Add_int("oplrate",Property::Changeable::WhenIdle,22050); - Pint->Set_values(rates); - Pint->Set_help("Sample rate of OPL music emulation."); + Pint->Set_values(oplrates); + Pint->Set_help("Sample rate of OPL music emulation. Use 49716 for highest quality (set the mixer rate accordingly)."); secprop=control->AddSection_prop("gus",&GUS_Init,true); //done diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 1943a50a..1a614214 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: adlib.cpp,v 1.35 2009-04-25 09:55:50 harekiet Exp $ */ +/* $Id: adlib.cpp,v 1.36 2009-04-26 15:37:04 c2woody Exp $ */ #include #include @@ -742,12 +742,14 @@ Module::Module( Section* configuration ) : Module_base(configuration) { } } else if (oplemu == "fast") { handler = new DBOPL::Handler(); - } else { + } else if (oplemu == "compat") { if ( oplmode == OPL_opl2 ) { handler = new OPL2::Handler(); } else { handler = new OPL3::Handler(); } + } else { + handler = new DBOPL::Handler(); } handler->Init( rate ); Bit8u portRange = 4; //opl2 will set this to 2 diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index be8830cd..3c6b32cb 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -48,7 +48,7 @@ namespace DBOPL { #define MAX_SAMPLES 256 -#define OPLRATE 50000 +#define OPLRATE ((double)(14318180.0 / 288.0)) //Only need 4 valid bits at the top for vibrato #define VIBRATO_SH ( 32 - 4 ) @@ -1183,13 +1183,13 @@ void Chip::Setup( Bit32u rate ) { //10 bits of frequency counter //With higher octave this gets shifted up //-1 since the freqCreateTable = *2 - double scale = ((double)OPLRATE * (double)( 1 << ( WAVE_SH - 10 - 1))) / rate; + double scale = (OPLRATE * (double)( 1 << ( WAVE_SH - 10 - 1))) / rate; for ( int i = 0; i < 16; i++ ) { //Use rounding with 0.5 freqMul[i] = (Bit32u)( 0.5 + scale * FreqCreateTable[ i ] ); } - scale = (double)OPLRATE / rate; + scale = OPLRATE / rate; //-3 since the real envelope takes 8 steps to reach the single value we supply for ( Bit8u i = 0; i < 76; i++ ) { Bit8u index, shift; @@ -1464,4 +1464,4 @@ void Handler::Init( Bitu rate ) { } -}; //Namespace Kiet +}; //Namespace DBOPL diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 28b0d83c..f6403e06 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -538,6 +538,9 @@ + + From 8516e5d4bf2887112dad891ed6af2d32b54dc379 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 Apr 2009 18:24:36 +0000 Subject: [PATCH 3271/4131] Remove dirent.h dependency. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3359 --- src/dos/cdrom.cpp | 7 ++++--- src/dos/drive_local.cpp | 8 ++++---- src/gui/render.cpp | 5 ++--- src/hardware/adlib.cpp | 4 +--- src/hardware/hardware.cpp | 25 +++++++++++++------------ src/hardware/mixer.cpp | 3 +-- 6 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 488f858f..8e3ec414 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: cdrom.cpp,v 1.27 2009-04-26 18:24:36 qbix79 Exp $ */ // ****************************************************** // SDL CDROM @@ -24,7 +25,7 @@ #include #include #include -#include + #include "dosbox.h" #include "SDL.h" #include "support.h" @@ -172,7 +173,7 @@ int CDROM_GetMountType(char* path, int forceCD) { // Detect ISO struct stat file_stat; - if ((stat(path, &file_stat) == 0) && S_ISREG(file_stat.st_mode)) return 1; + if ((stat(path, &file_stat) == 0) && (file_stat.st_mode & S_IFREG)) return 1; return 2; } diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 91bd08b5..bd171413 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,14 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.78 2008-10-05 14:44:52 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.79 2009-04-26 18:24:36 qbix79 Exp $ */ #include #include #include #include #include -#include + #include "dosbox.h" #include "dos_inc.h" #include "drives.h" @@ -264,7 +264,7 @@ again: goto again;//No symlinks and such } - if(S_ISDIR(stat_block.st_mode)) find_attr=DOS_ATTR_DIRECTORY; + if(stat_block.st_mode & S_IFDIR) find_attr=DOS_ATTR_DIRECTORY; else find_attr=DOS_ATTR_ARCHIVE; if (~srch_attr & find_attr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM)) goto again; diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 8e7311a5..cdd9cbfd 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,10 +16,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.58 2009-02-01 14:24:36 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.59 2009-04-26 18:24:36 qbix79 Exp $ */ #include -#include #include #include diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 1a614214..8ab83109 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -16,14 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: adlib.cpp,v 1.36 2009-04-26 15:37:04 c2woody Exp $ */ +/* $Id: adlib.cpp,v 1.37 2009-04-26 18:24:36 qbix79 Exp $ */ #include #include #include #include -#include - #include "adlib.h" #include "setup.h" diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 135e6e5e..44671ab7 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,9 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: hardware.cpp,v 1.21 2009-02-01 15:52:53 qbix79 Exp $ */ +/* $Id: hardware.cpp,v 1.22 2009-04-26 18:24:36 qbix79 Exp $ */ -#include #include #include #include @@ -89,15 +88,14 @@ FILE * OpenCaptureFile(const char * type,const char * ext) { } Bitu last=0; - char file_name[CROSS_LEN]; char file_start[16]; - DIR * dir;struct dirent * dir_ent; + dir_information * dir; /* Find a filename to open */ - dir=opendir(capturedir.c_str()); + dir = open_directory(capturedir.c_str()); if (!dir) { //Try creating it first Cross::CreateDir(capturedir); - dir=opendir(capturedir.c_str()); + dir=open_directory(capturedir.c_str()); if(!dir) { LOG_MSG("Can't open dir %s for capturing %s",capturedir.c_str(),type); @@ -107,17 +105,20 @@ FILE * OpenCaptureFile(const char * type,const char * ext) { strcpy(file_start,RunningProgram); lowcase(file_start); strcat(file_start,"_"); - while ((dir_ent=readdir(dir))) { - char tempname[CROSS_LEN]; - strcpy(tempname,dir_ent->d_name); + bool is_directory; + char tempname[CROSS_LEN]; + bool testRead = read_directory_first(dir, tempname, is_directory ); + for ( ; testRead; testRead = read_directory_next(dir, tempname, is_directory) ) { char * test=strstr(tempname,ext); - if (!test || strlen(test)!=strlen(ext)) continue; + if (!test || strlen(test)!=strlen(ext)) + continue; *test=0; if (strncasecmp(tempname,file_start,strlen(file_start))!=0) continue; Bitu num=atoi(&tempname[strlen(file_start)]); if (num>=last) last=num+1; } - closedir(dir); + close_directory( dir ); + char file_name[CROSS_LEN]; sprintf(file_name,"%s%c%s%03d%s",capturedir.c_str(),CROSS_FILESPLIT,file_start,last,ext); /* Open the actual file */ FILE * handle=fopen(file_name,"wb"); diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 3c8cb9f8..81955e60 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.51 2009-04-25 16:25:03 harekiet Exp $ */ +/* $Id: mixer.cpp,v 1.52 2009-04-26 18:24:36 qbix79 Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -25,7 +25,6 @@ #include #include -#include #include #if defined (WIN32) From ce176a2a7b15a95ca6d11c5bfb4546e4973038ff Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 Apr 2009 18:26:10 +0000 Subject: [PATCH 3272/4131] Prepare for testing at a future date. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3360 --- src/hardware/cmos.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 798e216a..ef5646d4 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cmos.cpp,v 1.26 2009-04-11 08:02:23 qbix79 Exp $ */ +/* $Id: cmos.cpp,v 1.27 2009-04-26 18:26:10 qbix79 Exp $ */ #include @@ -65,6 +65,8 @@ static void cmos_checktimer(void) { if (!cmos.timer.div || !cmos.timer.enabled) return; LOG(LOG_PIT,LOG_NORMAL)("RTC Timer at %.2f hz",1000.0/cmos.timer.delay); PIC_AddEvent(cmos_timerevent,cmos.timer.delay); +// PIC_AddEvent(cmos_timerevent,(double)cmos.timer.delay-fmod(PIC_FullIndex(),(double)cmos.timer.delay)); //Should be more like a real pc. Check +// status reg A reading with this (and with other delays actually) } void cmos_selreg(Bitu port,Bitu val,Bitu iolen) { From b663901319a9aac50ebdec22bc91c4c6ac116c10 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 26 Apr 2009 19:12:12 +0000 Subject: [PATCH 3273/4131] Fix windres failing when building from another directory Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3361 --- src/Makefile.am | 14 +++++++------- src/{dosbox.rc => winres.rc} | 0 2 files changed, 7 insertions(+), 7 deletions(-) rename src/{dosbox.rc => winres.rc} (100%) diff --git a/src/Makefile.am b/src/Makefile.am index 2c45ed72..08c0b853 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,16 +5,16 @@ SUBDIRS = cpu debug dos fpu gui hardware libs ints misc shell platform bin_PROGRAMS = dosbox if HAVE_WINDRES -ico_stuff = dosbox_ico.o +ico_stuff = winres.rc endif +.rc.o: + $(WINDRES) -o $@ $< -dosbox_SOURCES = dosbox.cpp +dosbox_SOURCES = dosbox.cpp $(icostuff) 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\ - $(ico_stuff) + ints/libints.a misc/libmisc.a shell/libshell.a hardware/serialport/libserial.a libs/gui_tk/libgui_tk.a + +EXTRA_DIST = winres.rc dosbox.ico -EXTRA_DIST = dosbox.rc dosbox.ico -dosbox_ico.o: dosbox.rc dosbox.ico - $(WINDRES) dosbox.rc dosbox_ico.o diff --git a/src/dosbox.rc b/src/winres.rc similarity index 100% rename from src/dosbox.rc rename to src/winres.rc From 3ac8b9963b18b095af1458ce85fb5f6ed22595c8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 26 Apr 2009 19:12:39 +0000 Subject: [PATCH 3274/4131] Fix __always__inline attribute Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3362 --- acinclude.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index cab7e791..2abdc3f8 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -324,7 +324,7 @@ AH_TOP([ ]) AH_BOTTOM([#if C_ATTRIBUTE_ALWAYS_INLINE -#define INLINE __attribute__((always_inline)) +#define INLINE inline __attribute__((always_inline)) #else #define INLINE inline #endif]) From 4263c9a9df8b712ab2c4e7a7abf454bbc8e2eb2b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 26 Apr 2009 19:13:32 +0000 Subject: [PATCH 3275/4131] Fix renaming of directories not detecting existence directory Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3363 --- src/dos/dos_files.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 2dccf4c7..425ca921 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.109 2009-04-17 11:33:51 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.110 2009-04-26 19:13:32 harekiet Exp $ */ #include #include @@ -272,12 +272,13 @@ bool DOS_Rename(char const * const oldname,char const * const newname) { return false; } /*Test if target exists => no access */ - if(Drives[drivenew]->FileExists(fullnew)) { + Bit16u attr; + if(Drives[drivenew]->GetFileAttr(fullnew,&attr)) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } /* Source must exist, check for path ? */ - if(!Drives[driveold]->FileExists(fullold)) { + if (!Drives[driveold]->GetFileAttr( fullold, &attr ) ) { DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } From 75da889c3edb66224bebc921d293c4ef85d6a6b1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 26 Apr 2009 19:14:50 +0000 Subject: [PATCH 3276/4131] Fix rounding errors with aspect correction Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3364 --- src/gui/render.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index cdd9cbfd..c25e6cac 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.59 2009-04-26 18:24:36 qbix79 Exp $ */ +/* $Id: render.cpp,v 1.60 2009-04-26 19:14:50 harekiet Exp $ */ #include #include @@ -519,6 +519,12 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool if (!width || !height || width > SCALER_MAXWIDTH || height > SCALER_MAXHEIGHT) { return; } + if ( ratio > 1 ) { + double target = height * ratio + 0.1; + ratio = target / height; + } else { + //This would alter the width of the screen, we don't care about rounding errors here + } render.src.width=width; render.src.height=height; render.src.bpp=bpp; From d261fb01fd2c6cb14805cdb2a6622d8e41c3ac46 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 Apr 2009 20:13:22 +0000 Subject: [PATCH 3277/4131] Make visual C++ 2003 happy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3365 --- src/hardware/dbopl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index 3c6b32cb..d0786565 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -1293,7 +1293,7 @@ void InitTables( void ) { //Exponential volume table, same as the real adlib for ( int i = 0; i < 256; i++ ) { //Save them in reverse - ExpTable[i] = (int)( 0.5 + ( pow(2, ( 255 - i) * ( 1.0 /256 ) )-1) * 1024 ); + ExpTable[i] = (int)( 0.5 + ( pow(2.0, ( 255 - i) * ( 1.0 /256 ) )-1) * 1024 ); ExpTable[i] += 1024; //or remove the -1 oh well :) //Preshift to the left once so the final volume can shift to the right ExpTable[i] *= 2; From 076a8e78b8128ce96eda7607957fcc3d0f3cb6e0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Apr 2009 09:17:03 +0000 Subject: [PATCH 3278/4131] Fix compilation under gcc 4.4 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3366 --- src/gui/midi_alsa.h | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 1e64b1ab..afc0b985 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,13 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_alsa.h,v 1.18 2009-04-25 15:57:07 qbix79 Exp $ */ +/* $Id: midi_alsa.h,v 1.19 2009-04-27 09:17:03 qbix79 Exp $ */ #define ALSA_PCM_OLD_HW_PARAMS_API #define ALSA_PCM_OLD_SW_PARAMS_API #include #include - +#include +#include #define ADDR_DELIM ".:" #if ((SND_LIB_MINOR >= 6) && (SND_LIB_MAJOR == 0)) || (SND_LIB_MAJOR >= 1) @@ -50,22 +51,24 @@ private: snd_seq_flush_output(seq_handle); } - int parse_addr(const char *arg, int *client, int *port) { - char *p; + bool parse_addr(const char *arg, int *client, int *port) { + std::string in(arg); + if(in.empty()) return false; - if (isdigit(*arg)) { - if ((p = strpbrk(arg, ADDR_DELIM)) == NULL) - return -1; - *client = atoi(arg); - *port = atoi(p + 1); - } else { - if (*arg == 's' || *arg == 'S') { - *client = SND_SEQ_ADDRESS_SUBSCRIBERS; - *port = 0; - } else - return -1; + if(in[0] == 's' || in[0] == 'S') { + *client = SND_SEQ_ADDRESS_SUBSCRIBERS; + *port = 0; + return true; } - return 0; + + if(in.find_first_of(ADDR_DELIM) == std::string::npos) return false; + std::istringstream inp(in); + int val1, val2; char c; + if(!(inp >> val1)) return false; + if(!(inp >> c )) return false; + if(!(inp >> val2)) return false; + *client = val1; *port = val2; + return true; } public: MidiHandler_alsa() : MidiHandler() {}; @@ -130,14 +133,14 @@ public: // try to use port specified in config file if (conf && conf[0]) { safe_strncpy(var, conf, 10); - if (parse_addr(var, &seq_client, &seq_port) < 0) { + if (!parse_addr(var, &seq_client, &seq_port)) { LOG_MSG("ALSA:Invalid alsa port %s", var); return false; } defaultport = false; } // default port if none specified - else if (parse_addr("65:0", &seq_client, &seq_port) < 0) { + else if (!parse_addr("65:0", &seq_client, &seq_port)) { LOG_MSG("ALSA:Invalid alsa port 65:0"); return false; } From 72d1ef211a6f1cbcc550a07ac2cb3182699ffd02 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Apr 2009 10:56:00 +0000 Subject: [PATCH 3279/4131] Keep it compiling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3367 --- visualc_net/dosbox.vcproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index f6403e06..5ec48865 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -159,7 +159,7 @@ RelativePath="..\src\dosbox.cpp"> + RelativePath="..\src\windres.rc"> Date: Mon, 27 Apr 2009 11:47:21 +0000 Subject: [PATCH 3280/4131] adding highly-efficient compression to almost-unused code that resembles something similar Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3368 --- visualc_net/dosbox.vcproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 5ec48865..445bb4da 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -159,7 +159,7 @@ RelativePath="..\src\dosbox.cpp"> + RelativePath="..\src\winres.rc"> Date: Mon, 27 Apr 2009 17:11:26 +0000 Subject: [PATCH 3281/4131] Fix crash Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3369 --- src/hardware/gus.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 325f47e1..34ecc28a 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: gus.cpp,v 1.35 2009-04-26 10:36:16 harekiet Exp $ */ +/* $Id: gus.cpp,v 1.36 2009-04-27 17:11:26 qbix79 Exp $ */ #include #include @@ -89,7 +89,6 @@ struct GFGus { Bit8u irq1; Bit8u irq2; - std::string ultradir; bool irqenabled; bool ChangeIRQDMA; // IRQ status register values @@ -802,8 +801,6 @@ public: myGUS.irq1 = (Bit8u)irq_val; myGUS.irq2 = (Bit8u)irq_val; - myGUS.ultradir = section->Get_string("ultradir"); - // We'll leave the MIDI interface to the MPU-401 // Ditto for the Joystick // GF1 Synthesizer @@ -857,7 +854,7 @@ public: << (Bitu)myGUS.irq1 << "," << (Bitu)myGUS.irq2 << ends; // Create autoexec.bat lines autoexecline[0].Install(temp.str()); - autoexecline[1].Install(std::string("SET ULTRADIR=")+ myGUS.ultradir); + autoexecline[1].Install(std::string("SET ULTRADIR=") + section->Get_string("ultradir")); } From 903a10ef9d4ed462b7c4a9bf2791447911bfe511 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Apr 2009 17:33:12 +0000 Subject: [PATCH 3282/4131] disable timidity port by default. timiditys default configuration on Ubuntu gives a high load when used with dosbox in idle mode ( -B2,8 ) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3370 --- src/gui/midi_alsa.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index afc0b985..36f7e967 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_alsa.h,v 1.19 2009-04-27 09:17:03 qbix79 Exp $ */ +/* $Id: midi_alsa.h,v 1.20 2009-04-27 17:33:12 qbix79 Exp $ */ #define ALSA_PCM_OLD_HW_PARAMS_API #define ALSA_PCM_OLD_SW_PARAMS_API @@ -128,7 +128,7 @@ public: bool Open(const char * conf) { char var[10]; unsigned int caps; - bool defaultport = true; //try 17:0 and 128:0 as well. Seems to be default nowadays + bool defaultport = true; //try 17:0. Seems to be default nowadays // try to use port specified in config file if (conf && conf[0]) { @@ -172,12 +172,12 @@ public: if (defaultport) { //if port "65:0" (default) try "17:0" as well seq_client = 17; seq_port = 0; //Update reported values if(snd_seq_connect_to(seq_handle,my_port,seq_client,seq_port) < 0) { //Try 128:0 Timidity port as well - seq_client = 128; seq_port = 0; //Update reported values - if(snd_seq_connect_to(seq_handle,my_port,seq_client,seq_port) < 0) { +// seq_client = 128; seq_port = 0; //Update reported values +// if(snd_seq_connect_to(seq_handle,my_port,seq_client,seq_port) < 0) { snd_seq_close(seq_handle); - LOG_MSG("ALSA:Can't subscribe to MIDI port (65:0) nor (17:0) nor (128:0)"); + LOG_MSG("ALSA:Can't subscribe to MIDI port (65:0) nor (17:0)"); return false; - } +// } } } else { snd_seq_close(seq_handle); From f5da809617feb86f2a558227431520ca6d3ddc29 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 27 Apr 2009 18:26:20 +0000 Subject: [PATCH 3283/4131] Default to use the multiplication table Don't use extra envelope bits for exponential wave routines Use the stereo percussion handler when opl3 is enabled Init some more variables in the constructors Shift the volume up once to make opl sound a bit louder Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3371 --- src/hardware/dbopl.cpp | 59 +++++++++++++++++++++++++++--------------- src/hardware/dbopl.h | 13 ++++------ 2 files changed, 43 insertions(+), 29 deletions(-) diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index d0786565..c077d939 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -26,7 +26,7 @@ //TODO Don't delay first operator 1 sample in opl3 mode //TODO Maybe not use class method pointers but a regular function pointers with operator as first parameter - //TODO Fix panning for the rhytm channels, would any opl3 player use it and actually really change it though? + //TODO Fix panning for the Percussion channels, would any opl3 player use it and actually really change it though? //TODO don't use variables in work structure for tremolo and vibrato but give the variables as parameters to GetSample //TODO Since the vibrato takes 1024 samples it's easier to run the emulator in same vibrato chunks, vibrato would be costfree @@ -49,6 +49,8 @@ namespace DBOPL { #define MAX_SAMPLES 256 #define OPLRATE ((double)(14318180.0 / 288.0)) +//Shift the final volume up at the end +#define POST_VOLSHIFT (1) //Only need 4 valid bits at the top for vibrato #define VIBRATO_SH ( 32 - 4 ) @@ -65,13 +67,12 @@ namespace DBOPL { //Maximum amount of attenuation bits //Envelope goes to 511, 9 bits -//Final envelope should get shifted up 3 bits, we already do that for some generation modes #if (DBOPL_WAVE == WAVE_TABLEMUL ) //Uses the value directly #define ENV_BITS ( 9 ) #else //Add 3 bits here for more accuracy and would have to be shifted up either way -#define ENV_BITS ( 12 ) +#define ENV_BITS ( 9 ) #endif //Limits of the envelope with those bits and when the envelope goes silent #define ENV_MIN 0 @@ -577,7 +578,7 @@ INLINE Bits Operator::GetWave( Bitu index, Bitu vol ) { return (waveBase[ index & waveMask ] * MulTable[ vol >> ENV_EXTRA ]) >> MUL_SH; #elif ( DBOPL_WAVE == WAVE_TABLELOG ) Bit32s wave = waveBase[ index & waveMask ]; - Bit32u total = ( wave & 0x7fff ) + vol; + Bit32u total = ( wave & 0x7fff ) + vol << ( 3 - ENV_EXTRA ); Bit32s sig = ExpTable[ total & 0xff ]; Bit32u exp = total >> 8; Bit32s neg = wave >> 16; @@ -601,15 +602,19 @@ Bits INLINE Operator::GetSample( Bits modulation ) { } Operator::Operator() { + chanData = 0; freqMul = 0; waveIndex = 0; waveAdd = 0; keyOn = 0; ksr = 0; - chanData = 0; + reg20 = 0; + reg40 = 0; + reg60 = 0; + reg80 = 0; + regE0 = 0; SetState( OFF ); rateZero = (1 << OFF); - sustainLevel = ENV_MAX; activeLevel = ENV_MAX; totalLevel = ENV_MAX; @@ -620,8 +625,9 @@ Operator::Operator() { */ Channel::Channel() { - //Frequency init + old[0] = old[1] = 0; chanData = 0; + regB0 = 0; regC0 = 0; maskLeft = -1; maskRight = -1; @@ -750,7 +756,7 @@ void Channel::WriteC0( const Chip* chip, Bit8u val ) { chan0->synthHandler = &Channel::BlockTemplate< sm3AMAM >; break; } - //Disable updating rhytm channels + //Disable updating percussion channels } else if ((fourMask & 0x40) && ( chip->regBD & 0x20) ) { //Regular dual op, am or fm @@ -763,7 +769,7 @@ void Channel::WriteC0( const Chip* chip, Bit8u val ) { maskRight = ( val & 0x20 ) ? -1 : 0; //opl2 active } else { - //Disable updating rhytm channels + //Disable updating percussion channels if ( (fourMask & 0x40) && ( chip->regBD & 0x20 ) ) { //Regular dual op, am or fm @@ -782,7 +788,7 @@ void Channel::ResetC0( const Chip* chip ) { }; template< bool opl3Mode> -void Channel::GenerateRhytm( Bit32s* output ) { +void Channel::GeneratePercussion( Bit32s* output ) { Channel* chan = this; //BassDrum @@ -891,12 +897,12 @@ Channel* Channel::BlockTemplate( ) { Work.vibrato = Work.vibTable[i]; Work.tremolo = Work.tremTable[i]; - //Early out for rhytm handlers - if ( mode == sm2Rhytm ) { - GenerateRhytm( Work.output + i ); + //Early out for percussion handlers + if ( mode == sm2Percussion ) { + GeneratePercussion( Work.output + i ); continue; //Prevent some unitialized value bitching - } else if ( mode == sm3Rhytm ) { - GenerateRhytm( Work.output + i * 2 ); + } else if ( mode == sm3Percussion ) { + GeneratePercussion( Work.output + i * 2 ); continue; //Prevent some unitialized value bitching } @@ -956,8 +962,8 @@ Channel* Channel::BlockTemplate( ) { case sm3FMAM: case sm3AMAM: return( this + 2 ); - case sm2Rhytm: - case sm3Rhytm: + case sm2Percussion: + case sm3Percussion: return( this + 3 ); } return 0; @@ -968,6 +974,9 @@ Channel* Channel::BlockTemplate( ) { */ Chip::Chip() { + reg08 = 0; + reg04 = 0; + regBD = 0; reg104 = 0; opl3Active = 0; } @@ -1001,9 +1010,9 @@ void Chip::WriteBD( Bit8u val ) { //Drum was just enabled, make sure channel 6 has the right synth if ( change & 0x20 ) { if ( opl3Active ) { - chan[6].synthHandler = &Channel::BlockTemplate< sm3Rhytm >; + chan[6].synthHandler = &Channel::BlockTemplate< sm3Percussion >; } else { - chan[6].synthHandler = &Channel::BlockTemplate< sm2Rhytm >; + chan[6].synthHandler = &Channel::BlockTemplate< sm2Percussion >; } } //Bass Drum @@ -1038,7 +1047,7 @@ void Chip::WriteBD( Bit8u val ) { } else { chan[8].op[1].KeyOff( 0x2 ); } - //Toggle keyoffs when we turn off the rhytm + //Toggle keyoffs when we turn off the percussion } else if ( change & 0x20 ) { //Trigger a reset to setup the original synth handler chan[6].ResetC0( this ); @@ -1155,6 +1164,9 @@ void Chip::GenerateBlock2( Bitu samples ) { count++; ch = (ch->*(ch->synthHandler))(); } + for ( Bitu i = 0; i < Work.samples; i++ ) { + Work.output[i] <<= POST_VOLSHIFT; + } } void Chip::GenerateBlock3( Bitu samples ) { @@ -1170,6 +1182,11 @@ void Chip::GenerateBlock3( Bitu samples ) { count++; ch = (ch->*(ch->synthHandler))(); } + for ( Bitu i = 0; i < Work.samples; i++ ) { + Work.output[i*2 + 0] <<= POST_VOLSHIFT; + Work.output[i*2 + 1] <<= POST_VOLSHIFT; + } + } void Chip::Setup( Bit32u rate ) { @@ -1263,7 +1280,7 @@ void Chip::Setup( Bit32u rate ) { chan[13].fourMask = 0x00 | ( 1 << 5 ); chan[14].fourMask = 0x80 | ( 1 << 5 ); - //mark the rhythm channels + //mark the percussion channels chan[ 6].fourMask = 0x40; chan[ 7].fourMask = 0x40; chan[ 8].fourMask = 0x40; diff --git a/src/hardware/dbopl.h b/src/hardware/dbopl.h index f42a330d..9232404f 100644 --- a/src/hardware/dbopl.h +++ b/src/hardware/dbopl.h @@ -27,7 +27,7 @@ #define WAVE_TABLEMUL 12 //Select the type of wave generator routine -#define DBOPL_WAVE WAVE_HANDLER +#define DBOPL_WAVE WAVE_TABLEMUL //Enable vibrato in the output #define DBOPL_VIBRATO //Enable tremolo in the output @@ -51,14 +51,14 @@ typedef enum { smNone, sm2AM, sm2FM, - sm2Rhytm, + sm2Percussion, sm3AM, sm3FM, sm3FMFM, sm3AMFM, sm3FMAM, sm3AMAM, - sm3Rhytm, + sm3Percussion, } SynthMode; //Shifts for the values contained in chandata variable @@ -121,14 +121,12 @@ public: Bit8u vibStrength; //Keep track of the calculated KSR so we can check for changes Bit8u ksr; - private: void SetState( Bit8u s ); void UpdateAttack( const Chip* chip ); void UpdateRelease( const Chip* chip ); void UpdateDecay( const Chip* chip ); public: - //is the operator silent? void UpdateAttenuation(); void UpdateRates( const Chip* chip ); void UpdateFrequency( ); @@ -168,7 +166,7 @@ struct Channel { Bit8u feedback; //Feedback shift Bit8u regB0; //Register values to check for changes Bit8u regC0; - //This should correspond with reg104, bit 6 indicates a rhytm channel, bit 7 indicates a silent channel + //This should correspond with reg104, bit 6 indicates a Percussion channel, bit 7 indicates a silent channel Bit8u fourMask; Bit8s maskLeft; //Sign extended values for both channel's panning Bit8s maskRight; @@ -184,12 +182,11 @@ struct Channel { //call this for the first channel template< bool opl3Mode > - void GenerateRhytm( Bit32s* output ); + void GeneratePercussion( Bit32s* output ); //Generate blocks of data in specific modes template Channel* BlockTemplate( ); - void BlockRhytm( ); Channel(); }; From d8b0d241bdd4925d05e3cf1c6028ac5d22cff5c3 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 27 Apr 2009 21:17:58 +0000 Subject: [PATCH 3284/4131] Remove the volume hack again, never listen to woody Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3372 --- src/hardware/dbopl.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index c077d939..02106d86 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -49,8 +49,6 @@ namespace DBOPL { #define MAX_SAMPLES 256 #define OPLRATE ((double)(14318180.0 / 288.0)) -//Shift the final volume up at the end -#define POST_VOLSHIFT (1) //Only need 4 valid bits at the top for vibrato #define VIBRATO_SH ( 32 - 4 ) @@ -1164,9 +1162,6 @@ void Chip::GenerateBlock2( Bitu samples ) { count++; ch = (ch->*(ch->synthHandler))(); } - for ( Bitu i = 0; i < Work.samples; i++ ) { - Work.output[i] <<= POST_VOLSHIFT; - } } void Chip::GenerateBlock3( Bitu samples ) { @@ -1182,11 +1177,6 @@ void Chip::GenerateBlock3( Bitu samples ) { count++; ch = (ch->*(ch->synthHandler))(); } - for ( Bitu i = 0; i < Work.samples; i++ ) { - Work.output[i*2 + 0] <<= POST_VOLSHIFT; - Work.output[i*2 + 1] <<= POST_VOLSHIFT; - } - } void Chip::Setup( Bit32u rate ) { From ad40f8db6797e4bfe6d3b594c4f78cfd7b2cd94b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Apr 2009 07:02:51 +0000 Subject: [PATCH 3285/4131] Fix typo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3373 --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 08c0b853..184469e0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,7 +11,7 @@ endif .rc.o: $(WINDRES) -o $@ $< -dosbox_SOURCES = dosbox.cpp $(icostuff) +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 \ ints/libints.a misc/libmisc.a shell/libshell.a hardware/serialport/libserial.a libs/gui_tk/libgui_tk.a From cfd261d31949edfb3b8b3386089787a93da3123a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Apr 2009 13:27:27 +0000 Subject: [PATCH 3286/4131] Fix warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3374 --- src/hardware/opl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/opl.cpp b/src/hardware/opl.cpp index 94095f04..27d0ae44 100644 --- a/src/hardware/opl.cpp +++ b/src/hardware/opl.cpp @@ -521,7 +521,7 @@ void adlib_init(Bit32u samplerate) { for (i=4; i(VIBTAB_SIZE*FIXEDPT_LFO/8192*INTFREQU/int_samplerate); vibtab_pos = 0; for (i=0; i Date: Tue, 28 Apr 2009 18:47:04 +0000 Subject: [PATCH 3287/4131] warning fixes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3375 --- src/dos/dos_misc.cpp | 14 +++++++------- src/hardware/dbopl.cpp | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index 6d4079b7..3ef6a1ae 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_misc.cpp,v 1.21 2008-10-05 14:44:52 qbix79 Exp $ */ +/* $Id: dos_misc.cpp,v 1.22 2009-04-28 18:47:04 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" @@ -88,12 +88,12 @@ static bool DOS_MultiplexFunctions(void) { } else { Bit8u drive=Files[reg_bx]->GetDrive(); - mem_writew(sftptr+sftofs+0x02,Files[reg_bx]->flags&3); // file open mode - mem_writeb(sftptr+sftofs+0x04,(Bit8u)(Files[reg_bx]->attr)); // file attribute - mem_writew(sftptr+sftofs+0x05,0x40|drive); // device info word - mem_writed(sftptr+sftofs+0x07,RealMake(dos.tables.dpb,drive)); // dpb of the drive - mem_writew(sftptr+sftofs+0x0d,Files[reg_bx]->time); // packed file time - mem_writew(sftptr+sftofs+0x0f,Files[reg_bx]->date); // packed file date + mem_writew(sftptr+sftofs+0x02,(Bit16u)(Files[reg_bx]->flags&3)); // file open mode + mem_writeb(sftptr+sftofs+0x04,(Bit8u)(Files[reg_bx]->attr)); // file attribute + mem_writew(sftptr+sftofs+0x05,0x40|drive); // device info word + mem_writed(sftptr+sftofs+0x07,RealMake(dos.tables.dpb,drive)); // dpb of the drive + mem_writew(sftptr+sftofs+0x0d,Files[reg_bx]->time); // packed file time + mem_writew(sftptr+sftofs+0x0f,Files[reg_bx]->date); // packed file date Bit32u curpos=0; Files[reg_bx]->Seek(&curpos,DOS_SEEK_CUR); Bit32u endpos=0; diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index 02106d86..99e45c90 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -332,7 +332,7 @@ inline void Operator::UpdateRelease( const Chip* chip ) { } inline void Operator::UpdateAttenuation( ) { - Bit8u kslBase = (chanData >> SHIFT_KSLBASE) & 0xff; + Bit8u kslBase = (Bit8u)((chanData >> SHIFT_KSLBASE) & 0xff); Bit32u tl = reg40 & 0x3f; Bit8u kslShift = KslShiftTable[ reg40 >> 6 ]; //Make sure the attenuation goes to the right bits @@ -357,7 +357,7 @@ void Operator::UpdateFrequency( ) { void Operator::UpdateRates( const Chip* chip ) { //Mame seems to reverse this where enabling ksr actually lowers //the rate, but pdf manuals says otherwise? - Bit8u newKsr = (chanData >> SHIFT_KEYCODE) & 0xff; + Bit8u newKsr = (Bit8u)((chanData >> SHIFT_KEYCODE) & 0xff); if ( !( reg20 & MASK_KSR ) ) { newKsr >>= 2; } From 1975a129cceb70de5ffc479a1166d93e2202ca3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 28 Apr 2009 21:45:43 +0000 Subject: [PATCH 3288/4131] ignore adlib 0xc0 high bits (seemingly unused on real cards), reduce volume Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3376 --- src/hardware/adlib.h | 3 +-- src/hardware/opl.cpp | 10 +++++----- src/hardware/ymf262.c | 6 ++---- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/hardware/adlib.h b/src/hardware/adlib.h index baa3b586..f82953df 100644 --- a/src/hardware/adlib.h +++ b/src/hardware/adlib.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: adlib.h,v 1.4 2009-04-26 10:33:53 harekiet Exp $ */ +/* $Id: adlib.h,v 1.5 2009-04-28 21:45:43 c2woody Exp $ */ #ifndef DOSBOX_ADLIB_H #define DOSBOX_ADLIB_H @@ -24,7 +24,6 @@ #include "dosbox.h" #include "mixer.h" #include "inout.h" -#include "mixer.h" #include "setup.h" #include "pic.h" #include "hardware.h" diff --git a/src/hardware/opl.cpp b/src/hardware/opl.cpp index 27d0ae44..2d8d6b1d 100644 --- a/src/hardware/opl.cpp +++ b/src/hardware/opl.cpp @@ -499,8 +499,8 @@ void adlib_init(Bit32u samplerate) { #if defined(OPLTYPE_IS_OPL3) op[i].is_4op = false; op[i].is_4op_attached = false; - op[i].left_pan = 2; - op[i].right_pan = 2; + op[i].left_pan = 1; + op[i].right_pan = 1; #endif } @@ -848,8 +848,8 @@ void adlib_write(Bitu idx, Bit8u val) { change_feedback(chanbase,&op[opbase]); #if defined(OPLTYPE_IS_OPL3) // OPL3 panning - op[opbase].left_pan = ((val&0x10)>>4)+((val&0x40)>>6); - op[opbase].right_pan = ((val&0x20)>>5)+((val&0x80)>>7); + op[opbase].left_pan = ((val&0x10)>>4); + op[opbase].right_pan = ((val&0x20)>>5); #endif } } @@ -933,7 +933,7 @@ static void INLINE clipit16(Bit32s ival, Bit16s* outval) { outbufl[i] += chanval*cptr[0].left_pan; \ outbufr[i] += chanval*cptr[0].right_pan; \ } else { \ - outbufl[i] += chanval*2; \ + outbufl[i] += chanval; \ } #else #define CHANVAL_OUT \ diff --git a/src/hardware/ymf262.c b/src/hardware/ymf262.c index 25b5c3f0..fe630135 100644 --- a/src/hardware/ymf262.c +++ b/src/hardware/ymf262.c @@ -2073,16 +2073,14 @@ static void OPL3WriteReg(OPL3 *chip, int r, int v) /* OPL3 mode */ chip->pan[ base ] = (v & 0x10) ? 1 : 0; /* ch.A */ chip->pan[ base +1 ] = (v & 0x20) ? 1 : 0; /* ch.B */ - if (v & 0x40) chip->pan[ base ] += 1; /* ch.C->ch.A */ - if (v & 0x80) chip->pan[ base +1 ] += 1; /* ch.D->ch.B */ } else { int base = ((r&0xf) + ch_offset) * 2; /* OPL2 mode - always enabled */ - chip->pan[ base ] = 2; /* ch.A */ - chip->pan[ base +1 ] = 2; /* ch.B */ + chip->pan[ base ] = 1; /* ch.A */ + chip->pan[ base +1 ] = 1; /* ch.B */ } CH->SLOT[SLOT1].FB = (v>>1)&7 ? ((v>>1)&7) + 7 : 0; From f6def87e3434607d3a7a9600d8a2601d96156398 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 28 Apr 2009 21:48:24 +0000 Subject: [PATCH 3289/4131] Include an extra scale factor in the mixer volume to be set by a device Set the adlib device scale at 2.0 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3377 --- include/mixer.h | 4 +++- src/hardware/adlib.cpp | 3 ++- src/hardware/mixer.cpp | 26 +++++++++----------------- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/include/mixer.h b/include/mixer.h index d8585a35..a31b5493 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.h,v 1.18 2009-04-25 16:25:03 harekiet Exp $ */ +/* $Id: mixer.h,v 1.19 2009-04-28 21:48:24 harekiet Exp $ */ #ifndef DOSBOX_MIXER_H #define DOSBOX_MIXER_H @@ -48,6 +48,7 @@ extern Bit8u MixTemp[MIXER_BUFSIZE]; class MixerChannel { public: void SetVolume(float _left,float _right); + void SetScale( float f ); void UpdateVolume(void); void SetFreq(Bitu _freq); void Mix(Bitu _needed); @@ -78,6 +79,7 @@ public: void Enable(bool _yesno); MIXER_Handler handler; float volmain[2]; + float scale; Bit32s volmul[2]; Bitu freq_add,freq_index; Bitu done,needed; diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 8ab83109..d2e3bf94 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: adlib.cpp,v 1.37 2009-04-26 18:24:36 qbix79 Exp $ */ +/* $Id: adlib.cpp,v 1.38 2009-04-28 21:48:24 harekiet Exp $ */ #include #include @@ -732,6 +732,7 @@ Module::Module( Section* configuration ) : Module_base(configuration) { std::string oplemu( section->Get_string( "oplemu" ) ); mixerChan = mixerObject.Install(OPL_CallBack,rate,"FM"); + mixerChan->SetScale( 2.0 ); if (oplemu == "old") { if ( oplmode == OPL_opl2 ) { handler = new old_OPL2::Handler(); diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 81955e60..6999ba7d 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.52 2009-04-26 18:24:36 qbix79 Exp $ */ +/* $Id: mixer.cpp,v 1.53 2009-04-28 21:48:24 harekiet Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -62,20 +62,6 @@ static INLINE Bit16s MIXER_CLIP(Bits SAMP) { } else return MAX_AUDIO; } -struct MIXER_Channel { - double vol_main[2]; - Bits vol_mul[2]; - Bit8u mode; - Bitu freq; - char * name; - MIXER_MixHandler handler; - Bitu sample_add; - Bitu sample_left; - Bitu remain; - bool playing; - MIXER_Channel * next; -}; - static struct { Bit32s work[MIXER_BUFSIZE][2]; Bitu pos,done; @@ -92,6 +78,7 @@ Bit8u MixTemp[MIXER_BUFSIZE]; MixerChannel * MIXER_AddChannel(MIXER_Handler handler,Bitu freq,const char * name) { MixerChannel * chan=new MixerChannel(); + chan->scale = 1.0; chan->handler=handler; chan->name=name; chan->SetFreq(freq); @@ -126,8 +113,8 @@ void MIXER_DelChannel(MixerChannel* delchan) { } void MixerChannel::UpdateVolume(void) { - volmul[0]=(Bits)((1 << MIXER_VOLSHIFT)*volmain[0]*mixer.mastervol[0]); - volmul[1]=(Bits)((1 << MIXER_VOLSHIFT)*volmain[1]*mixer.mastervol[1]); + volmul[0]=(Bits)((1 << MIXER_VOLSHIFT)*scale*volmain[0]*mixer.mastervol[0]); + volmul[1]=(Bits)((1 << MIXER_VOLSHIFT)*scale*volmain[1]*mixer.mastervol[1]); } void MixerChannel::SetVolume(float _left,float _right) { @@ -136,6 +123,11 @@ void MixerChannel::SetVolume(float _left,float _right) { UpdateVolume(); } +void MixerChannel::SetScale( float f ) { + scale = f; + UpdateVolume(); +} + void MixerChannel::Enable(bool _yesno) { if (_yesno==enabled) return; enabled=_yesno; From c4d033cc79e820c05ca323d67b7c161a64275297 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 30 Apr 2009 12:36:55 +0000 Subject: [PATCH 3290/4131] Fix accidential mix up Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3378 --- include/mem.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mem.h b/include/mem.h index 7a2cfb99..c42f6ac1 100644 --- a/include/mem.h +++ b/include/mem.h @@ -59,7 +59,7 @@ MemHandle MEM_NextHandleAt(MemHandle handle,Bitu where); #if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) -static 4/25/2009INLINE Bit8u host_readb(HostPt off) { +static INLINE Bit8u host_readb(HostPt off) { return off[0]; } static INLINE Bit16u host_readw(HostPt off) { From 5762e97c82cdbe2392d5100d48f31b8bf2dd36d6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 12 May 2009 12:37:29 +0000 Subject: [PATCH 3291/4131] Several configure improvements. powf possibly being a define. a X header detection for some ports who don't have it nor need the functionality. Renamed CoreMidi to CoreMIDI so it works on case-sensitive filesystems. (thanks Jonathan) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3379 --- configure.in | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/configure.in b/configure.in index 7ed482af..e02f5832 100644 --- a/configure.in +++ b/configure.in @@ -121,17 +121,14 @@ d_test.d_type = 0; dnl Check for powf -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 ]],[[ +AC_MSG_CHECKING(for powf in libm); +LIBS_BACKUP=$LIBS; +LIBS="$LIBS -lm"; +AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]],[[ 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 +]])], [AC_MSG_RESULT(yes)], [AC_DEFINE([DB_HAVE_NO_POWF],[1],[libm doesn't include powf])]) +LIBS=$LIBS_BACKUP + dnl Checks for libraries. @@ -377,6 +374,18 @@ else AC_MSG_WARN([Can't find SDL_net, internal modem and ipx disabled]) fi +AH_TEMPLATE(C_X11_XKB,[define to 1 if you have XKBlib.h and X11 lib]) +AC_CHECK_LIB(X11, main, have_x11_lib=yes, have_x11_lib=no, ) +AC_CHECK_HEADER(X11/XKBlib.h, have_x11_h=yes, have_x11_h=no, ) +AC_MSG_CHECKING(for XKBlib support) +if test x$have_x11_lib = xyes -a x$have_x11_h = xyes ; then + LIBS="$LIBS -lX11" + AC_DEFINE(C_X11_XKB,1) + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +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 , ) @@ -454,7 +463,7 @@ case "$target" in 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" + 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*) From db4387542f288dc79ae7347474186ff45bc2e22e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 14 May 2009 17:04:37 +0000 Subject: [PATCH 3292/4131] Fix disney stuff that wants a fixed rate. (RC1, thanks hal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3380 --- src/hardware/disney.cpp | 43 +++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 7e8a19a3..89b3ce59 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: disney.cpp,v 1.16 2008-07-14 19:39:10 qbix79 Exp $ */ +/* $Id: disney.cpp,v 1.17 2009-05-14 17:04:37 qbix79 Exp $ */ #include #include "dosbox.h" @@ -56,6 +56,7 @@ static struct { Bitu state; Bitu interface_det; + Bitu interface_det_ext; } disney; #define DS_IDLE 0 @@ -71,12 +72,13 @@ static void DISNEY_disable(Bitu) { disney.chan->Enable(false); delete disney.mo; } - disney.interface_det = 0; disney.leader = 0; disney.last_used = 0; disney.mo = 0; disney.state = DS_IDLE; disney.interface_det = 0; + disney.interface_det_ext = 0; + disney.stereo = false; } static void DISNEY_enable(Bitu freq) { @@ -197,7 +199,6 @@ static void disney_write(Bitu port,Bitu val,Bitu iolen) { disney.da[0].buffer[disney.da[0].used] = disney.data; disney.da[0].used++; } //else LOG_MSG("disney overflow 0"); - } break; } @@ -208,6 +209,7 @@ static void disney_write(Bitu port,Bitu val,Bitu iolen) { if((disney.control & 0x2) && !(val & 0x2)) { if(disney.state != DS_RUNNING) { disney.interface_det = 0; + disney.interface_det_ext = 0; DISNEY_analyze(1); } @@ -221,6 +223,7 @@ static void disney_write(Bitu port,Bitu val,Bitu iolen) { if((disney.control & 0x1) && !(val & 0x1)) { if(disney.state != DS_RUNNING) { disney.interface_det = 0; + disney.interface_det_ext = 0; DISNEY_analyze(0); } // stereo channel latch @@ -230,6 +233,24 @@ static void disney_write(Bitu port,Bitu val,Bitu iolen) { } //else LOG_MSG("disney overflow 0"); } + if((disney.control & 0x8) && !(val & 0x8)) { + // emulate a device with 16-byte sound FIFO + if(disney.state != DS_RUNNING) { + disney.interface_det_ext++; + disney.interface_det = 0; + if(disney.interface_det_ext > 5) { + disney.leader = &disney.da[0]; + DISNEY_enable(7000); + } + } + if(disney.interface_det_ext > 5) { + if(disney.da[0].used < DISNEY_SIZE) { + disney.da[0].buffer[disney.da[0].used] = disney.data; + disney.da[0].used++; + } + } + } + // LOG_WARN("DISNEY:Control write %x",val); if (val&0x10) LOG(LOG_MISC,LOG_ERROR)("DISNEY:Parallel IRQ Enabled"); disney.control=val; @@ -238,6 +259,7 @@ static void disney_write(Bitu port,Bitu val,Bitu iolen) { } static Bitu disney_read(Bitu port,Bitu iolen) { + Bitu retval; switch (port-DISNEY_BASE) { case 0: /* Data Port */ // LOG(LOG_MISC,LOG_NORMAL)("DISNEY:Read from data port"); @@ -245,10 +267,15 @@ static Bitu disney_read(Bitu port,Bitu iolen) { break; case 1: /* Status Port */ // LOG(LOG_MISC,"DISNEY:Read from status port %X",disney.status); - if (disney.leader && disney.leader->used >= 16) return 0x40; - /* Stereo-on-1 and (or) New-Stereo DACs present */ - if(!(disney.data&0x80)) return 0xc4; - else return 0x0; + retval = 0x07;//0x40; // Stereo-on-1 and (or) New-Stereo DACs present + if(disney.interface_det_ext > 5) { + if (disney.leader && disney.leader->used >= 16){ + retval |= 0x40; // ack + retval &= ~0x4; // interrupt + } + } + if(!(disney.data&0x80)) retval |= 0x80; // pin 9 is wired to pin 11 + return retval; break; case 2: /* Control Port */ LOG(LOG_MISC,LOG_NORMAL)("DISNEY:Read from control port"); From a14636aea054514c1fbae8d004d46b639cbf23e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 14 May 2009 17:05:58 +0000 Subject: [PATCH 3293/4131] handle zero-pages ems allocation requests correctly (fixes VBDOS) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3381 --- src/ints/ems.cpp | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 5f581f21..51b74d4f 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.60 2008-11-27 18:57:45 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.61 2009-05-14 17:05:58 c2woody Exp $ */ #include #include @@ -79,16 +79,16 @@ public: SetName("EMMXXXX0"); GEMMIS_seg=0; } - bool Read(Bit8u * data,Bit16u * size) { return false;} - bool Write(Bit8u * data,Bit16u * size){ + bool Read(Bit8u * /*data*/,Bit16u * /*size*/) { return false;} + bool Write(Bit8u * /*data*/,Bit16u * /*size*/){ LOG(LOG_IOCTL,LOG_NORMAL)("EMS:Write to device"); return false; } - bool Seek(Bit32u * pos,Bit32u type){return false;} + bool Seek(Bit32u * /*pos*/,Bit32u /*type*/){return false;} bool Close(){return false;} Bit16u GetInformation(void){return 0xc080;} bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode); - bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return true;} + bool WriteToControlChannel(PhysPt /*bufptr*/,Bit16u /*size*/,Bit16u * /*retcode*/){return true;} private: Bit8u cache; }; @@ -126,7 +126,7 @@ bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retco mem_writeb(GEMMIS_addr+0x0a+frnr,0x03); // frame type: EMS frame in 64k page mem_writeb(GEMMIS_addr+0x0b+frnr,0xff); // owner: NONE mem_writew(GEMMIS_addr+0x0c+frnr,0x7fff); // no logical page number - mem_writeb(GEMMIS_addr+0x0e + frnr,frct); // physical EMS page number + mem_writeb(GEMMIS_addr+0x0e+frnr,(Bit8u)(frct&0xff)); // physical EMS page number mem_writeb(GEMMIS_addr+0x0f+frnr,0x00); // EMS frame } /* build non-EMS ROM frames (0xf000-0x10000) */ @@ -224,8 +224,11 @@ static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & dhandle,bool can_allocate_ while (emm_handles[handle].pages != NULL_HANDLE) { if (++handle >= EMM_MAX_HANDLES) {return EMM_OUT_OF_HANDLES;} } - MemHandle mem = MEM_AllocatePages(pages*4,false); - if (!mem) E_Exit("EMS:Memory allocation failure"); + MemHandle mem = 0; + if (pages) { + mem = MEM_AllocatePages(pages*4,false); + if (!mem) E_Exit("EMS:Memory allocation failure"); + } emm_handles[handle].pages = pages; emm_handles[handle].mem = mem; /* Change handle only if there is no error. */ @@ -251,8 +254,14 @@ static Bit8u EMM_AllocateSystemHandle(Bit16u pages) { static Bit8u EMM_ReallocatePages(Bit16u handle,Bit16u & pages) { /* Check for valid handle */ if (!ValidHandle(handle)) return EMM_INVALID_HANDLE; - /* Check for enough pages */ - if (!MEM_ReAllocatePages(emm_handles[handle].mem,pages*4,false)) return EMM_OUT_OF_LOG; + if (emm_handles[handle].pages != 0) { + /* Check for enough pages */ + if (!MEM_ReAllocatePages(emm_handles[handle].mem,pages*4,false)) return EMM_OUT_OF_LOG; + } else { + MemHandle mem = MEM_AllocatePages(pages*4,false); + if (!mem) E_Exit("EMS:Memory allocation failure during reallocation"); + emm_handles[handle].mem = mem; + } /* Update size */ emm_handles[handle].pages=pages; return EMM_NO_ERROR; @@ -347,9 +356,14 @@ static Bit8u EMM_MapSegment(Bitu segment,Bit16u handle,Bit16u log_page) { static Bit8u EMM_ReleaseMemory(Bit16u handle) { /* Check for valid handle */ if (!ValidHandle(handle)) return EMM_INVALID_HANDLE; + // should check for saved_page_map flag here, returning an error if it's true // as apps are required to restore the pagemap beforehand; to be checked - MEM_ReleasePages(emm_handles[handle].mem); +// if (emm_handles[handle].saved_page_map) return EMM_SAVEMAP_ERROR; + + if (emm_handles[handle].pages != 0) { + MEM_ReleasePages(emm_handles[handle].mem); + } /* Reset handle */ emm_handles[handle].mem=0; if (handle==0) { @@ -1370,7 +1384,7 @@ public: static EMS* test; -void EMS_ShutDown(Section* sec) { +void EMS_ShutDown(Section* /*sec*/) { delete test; } From 445eeda8f77e8e44cbb6deffbdb08a61704709cd Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 14 May 2009 17:39:36 +0000 Subject: [PATCH 3294/4131] Fix dual speed in percussion mode Use noise calculation like in MAME Run the generator in same tremolo/vibrato blocks for more speed Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3382 --- src/hardware/dbopl.cpp | 297 ++++++++++++++++++++++++----------------- src/hardware/dbopl.h | 54 +++++--- 2 files changed, 207 insertions(+), 144 deletions(-) diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index 99e45c90..6845b076 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -27,8 +27,7 @@ //TODO Don't delay first operator 1 sample in opl3 mode //TODO Maybe not use class method pointers but a regular function pointers with operator as first parameter //TODO Fix panning for the Percussion channels, would any opl3 player use it and actually really change it though? - //TODO don't use variables in work structure for tremolo and vibrato but give the variables as parameters to GetSample - //TODO Since the vibrato takes 1024 samples it's easier to run the emulator in same vibrato chunks, vibrato would be costfree + //TODO Check if having the same accuracy in all frequency multipliers sounds better or not //DUNNO Keyon in 4op, switch to 2op without keyoff. */ @@ -47,22 +46,31 @@ namespace DBOPL { -#define MAX_SAMPLES 256 #define OPLRATE ((double)(14318180.0 / 288.0)) - -//Only need 4 valid bits at the top for vibrato -#define VIBRATO_SH ( 32 - 4 ) -//Need 6 bits of accuracy -#define TREMOLO_SH ( 32 - 6 ) #define TREMOLO_TABLE 52 +//Try to use most precision for frequencies +//Else try to keep different waves in synch +//#define WAVE_PRECISION 1 +#ifndef WAVE_PRECISION //Wave bits available in the top of the 32bit range -//Original adlib uses 10.10, we use 12.20 -//Have to keep some bits in the top to allow for freqmul 0.5 -#define WAVE_BITS 12 +//Original adlib uses 10.10, we use 10.22 +#define WAVE_BITS 10 +#else +//Need some extra bits at the top to have room for octaves and frequency multiplier +//We support to 8 times lower rate +//128 * 15 * 8 = 15350, 2^13.9, so need 14 bits +#define WAVE_BITS 14 +#endif #define WAVE_SH ( 32 - WAVE_BITS ) #define WAVE_MASK ( ( 1 << WAVE_SH ) - 1 ) +//Use the same accuracy as the waves +#define LFO_SH ( WAVE_SH - 10 ) +//LFO is controlled by our tremolo 256 sample limit +#define LFO_MAX ( 256 << ( LFO_SH ) ) + + //Maximum amount of attenuation bits //Envelope goes to 511, 9 bits #if (DBOPL_WAVE == WAVE_TABLEMUL ) @@ -271,21 +279,6 @@ static const WaveHandler WaveHandlerTable[8] = { #endif -//Structto hold the data everything well yeh works with -static struct { - Bitu samples; - Bits vibrato; - Bits tremolo; - inline void SetVibrato( Bit8s vib ) { - vibrato = vib; - vibrato &= ~0x80; - } - Bit32s output[MAX_SAMPLES * 2]; - //Could intermix the vib/trem table for slightly better cache hits - Bit8s vibTable[MAX_SAMPLES]; - Bit8s tremTable[MAX_SAMPLES]; -} Work; - /* Operator */ @@ -343,11 +336,20 @@ inline void Operator::UpdateAttenuation( ) { void Operator::UpdateFrequency( ) { Bit32u freq = chanData & (( 1 << 10 ) - 1); Bit32u block = (chanData >> 10) & 0xff; - - waveAdd = (freq << block) * freqMul; +#ifdef WAVE_PRECISION + block = 7 - block; + waveAdd = ( freq * freqMul ) >> block; +#else + waveAdd = ( freq << block ) * freqMul; +#endif if ( reg20 & MASK_VIBRATO ) { vibStrength = (Bit8u)(freq >> 7); + +#ifdef WAVE_PRECISION + vibrato = ( vibStrength * freqMul ) >> block; +#else vibrato = ( vibStrength << block ) * freqMul; +#endif } else { vibStrength = 0; vibrato = 0; @@ -378,7 +380,7 @@ INLINE Bit32s Operator::RateForward( Bit32u add ) { template< Operator::State yes> Bits Operator::TemplateVolume( ) { - Bit32s vol = activeLevel; + Bit32s vol = volume; Bit32s change; switch ( yes ) { case OFF: @@ -389,7 +391,7 @@ Bits Operator::TemplateVolume( ) { return vol; vol += ( (~vol) * change ) >> 3; if ( vol < ENV_MIN ) { - activeLevel = ENV_MIN; + volume = ENV_MIN; rateIndex = 0; SetState( DECAY ); return ENV_MIN; @@ -400,7 +402,7 @@ Bits Operator::TemplateVolume( ) { if ( vol >= sustainLevel ) { //Check if we didn't overshoot max attenuation, then just go off if ( vol >= ENV_MAX ) { - activeLevel = ENV_MAX; + volume = ENV_MAX; SetState( OFF ); return ENV_MAX; } @@ -417,13 +419,13 @@ Bits Operator::TemplateVolume( ) { case RELEASE: vol += RateForward( releaseAdd );; if ( vol >= ENV_MAX ) { - activeLevel = ENV_MAX; + volume = ENV_MAX; SetState( OFF ); return ENV_MAX; } break; } - activeLevel = vol; + volume = vol; return vol; } @@ -436,31 +438,15 @@ static const VolumeHandler VolumeHandlerTable[5] = { }; INLINE Bitu Operator::ForwardVolume() { - return totalLevel + (this->*volHandler)() -#if defined ( DBOPL_TREMOLO ) - + (Work.tremolo & tremoloMask) -#endif - ; + return currentLevel + (this->*volHandler)(); } INLINE Bitu Operator::ForwardWave() { -#if defined ( DBOPL_VIBRATO ) - if ( vibStrength >> (Bit8u)(Work.vibrato) ) { - Bit32s add = vibrato >> (Bit8u)(Work.vibrato); - //Sign extend over the shift value - Bit32s neg = Work.vibrato >> 16; - //Negate the add with -1 or 0 - add = ( add ^ neg ) - neg; - waveIndex += add + waveAdd; - return waveIndex >> WAVE_SH; - } -#endif - waveIndex += waveAdd; + waveIndex += waveCurrent; return waveIndex >> WAVE_SH; } - void Operator::Write20( const Chip* chip, Bit8u val ) { Bit8u change = (reg20 ^ val ); if ( !change ) @@ -539,12 +525,25 @@ INLINE void Operator::SetState( Bit8u s ) { } INLINE bool Operator::Silent() const { - if ( !ENV_SILENT( totalLevel + activeLevel ) ) + if ( !ENV_SILENT( totalLevel + volume ) ) return false; if ( !(rateZero & ( 1 << state ) ) ) return false; return true; -}; +} + +INLINE void Operator::Prepare( const Chip* chip ) { + currentLevel = totalLevel + (chip->tremoloValue & tremoloMask); + waveCurrent = waveAdd; + if ( vibStrength >> chip->vibratoShift ) { + Bit32s add = vibrato >> chip->vibratoShift; + //Sign extend over the shift value + Bit32s neg = chip->vibratoSign; + //Negate the add with -1 or 0 + add = ( add ^ neg ) - neg; + waveCurrent += add; + } +} void Operator::KeyOn( Bit8u mask ) { if ( !keyOn ) { @@ -590,7 +589,7 @@ Bits INLINE Operator::GetSample( Bits modulation ) { Bitu vol = ForwardVolume(); if ( ENV_SILENT( vol ) ) { //Simply forward the wave - waveIndex += waveAdd; + waveIndex += waveCurrent; return 0; } else { Bitu index = ForwardWave(); @@ -604,6 +603,7 @@ Operator::Operator() { freqMul = 0; waveIndex = 0; waveAdd = 0; + waveCurrent = 0; keyOn = 0; ksr = 0; reg20 = 0; @@ -614,8 +614,9 @@ Operator::Operator() { SetState( OFF ); rateZero = (1 << OFF); sustainLevel = ENV_MAX; - activeLevel = ENV_MAX; + currentLevel = ENV_MAX; totalLevel = ENV_MAX; + volume = ENV_MAX; } /* @@ -786,7 +787,7 @@ void Channel::ResetC0( const Chip* chip ) { }; template< bool opl3Mode> -void Channel::GeneratePercussion( Bit32s* output ) { +INLINE void Channel::GeneratePercussion( Chip* chip, Bit32s* output ) { Channel* chan = this; //BassDrum @@ -805,8 +806,8 @@ void Channel::GeneratePercussion( Bit32s* output ) { Operator* op2 = ( this + 1 )->Op(0); Operator* op4 = ( this + 2 )->Op(0); - //Precalculate stuff used by other oupts - Bit32u noiseBit = rand() & 0x2; + //Precalculate stuff used by other outputs + Bit32u noiseBit = (chip->ForwardNoise() & 0x1) << 1; Bit32u c2 = op2->ForwardWave(); //(bit 7 ^ bit 2) | bit 3 -> combined in bit 1 Bit32u phaseBit = ( (c2 >> 6) ^ ( c2 >> 1 ) ) | ( c2 >> 2 ); @@ -832,7 +833,10 @@ void Channel::GeneratePercussion( Bit32s* output ) { sample += op3->GetWave( sdIndex, sdVol ); } //Tom-tom - sample += op4->GetSample( 0 ); + Bit32u ttVol = op4->ForwardVolume(); + if ( !ENV_SILENT( ttVol ) ) { + sample += op4->GetWave( c4, ttVol ); + } //Top-Cymbal Operator* op5 = ( this + 2 )->Op(1); Bit32u tcVol = op5->ForwardVolume(); @@ -850,7 +854,7 @@ void Channel::GeneratePercussion( Bit32s* output ) { } template -Channel* Channel::BlockTemplate( ) { +Channel* Channel::BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ) { switch( mode ) { case sm2AM: case sm3AM: @@ -891,16 +895,24 @@ Channel* Channel::BlockTemplate( ) { } break; } - for ( Bitu i = 0; i < Work.samples; i++ ) { - Work.vibrato = Work.vibTable[i]; - Work.tremolo = Work.tremTable[i]; - + //Init the operators with the the current vibrato and tremolo values + Op( 0 )->Prepare( chip ); + Op( 1 )->Prepare( chip ); + if ( mode > sm4Start ) { + Op( 2 )->Prepare( chip ); + Op( 3 )->Prepare( chip ); + } + if ( mode > sm6Start ) { + Op( 4 )->Prepare( chip ); + Op( 5 )->Prepare( chip ); + } + for ( Bitu i = 0; i < samples; i++ ) { //Early out for percussion handlers if ( mode == sm2Percussion ) { - GeneratePercussion( Work.output + i ); + GeneratePercussion( chip, output + i ); continue; //Prevent some unitialized value bitching } else if ( mode == sm3Percussion ) { - GeneratePercussion( Work.output + i * 2 ); + GeneratePercussion( chip, output + i * 2 ); continue; //Prevent some unitialized value bitching } @@ -936,7 +948,7 @@ Channel* Channel::BlockTemplate( ) { switch( mode ) { case sm2AM: case sm2FM: - Work.output[ i ] += sample; + output[ i ] += sample; break; case sm3AM: case sm3FM: @@ -944,8 +956,8 @@ Channel* Channel::BlockTemplate( ) { case sm3AMFM: case sm3FMAM: case sm3AMAM: - Work.output[ i * 2 + 0 ] += sample & maskLeft; - Work.output[ i * 2 + 1 ] += sample & maskRight; + output[ i * 2 + 0 ] += sample & maskLeft; + output[ i * 2 + 1 ] += sample & maskRight; break; } } @@ -979,31 +991,53 @@ Chip::Chip() { opl3Active = 0; } - -Bit8u Chip::ForwardTremolo( ) { - tremoloCounter += tremoloAdd; - if ( tremoloCounter >= (TREMOLO_TABLE << TREMOLO_SH) ) { - tremoloCounter -= TREMOLO_TABLE << TREMOLO_SH; +INLINE Bit32u Chip::ForwardNoise() { + noiseCounter += noiseAdd; + Bitu count = noiseCounter >> LFO_SH; + noiseCounter &= WAVE_MASK; + for ( ; count > 0; --count ) { + //Noise calculation from mame + noiseValue ^= ( 0x800302 ) & ( 0 - (noiseValue & 1 ) ); + noiseValue >>= 1; } - Bitu index = tremoloCounter >> TREMOLO_SH; - return TremoloTable[ index ] >> tremoloShift; + return noiseValue; } -Bit8s Chip::ForwardVibrato( ) { - vibratoCounter += vibratoAdd; - Bitu index = vibratoCounter >> VIBRATO_SH; - //Vibrato shift, basically makes the shift greater reducing the actual final value - return VibratoTable[index & 7] + vibratoShift; +INLINE Bit32u Chip::ForwardLFO( Bit32u samples ) { + //Current vibrato value, runs 4x slower than tremolo + vibratoSign = ( VibratoTable[ vibratoIndex >> 2] ) >> 7; + vibratoShift = ( VibratoTable[ vibratoIndex >> 2] & 7) + vibratoStrength; + tremoloValue = TremoloTable[ tremoloIndex ] >> tremoloStrength; + + //Check hom many samples there can be done before the value changes + Bit32u todo = LFO_MAX - lfoCounter; + Bit32u count = (todo + lfoAdd - 1) / lfoAdd; + if ( count > samples ) { + count = samples; + lfoCounter += count * lfoAdd; + } else { + lfoCounter += count * lfoAdd; + lfoCounter &= (LFO_MAX - 1); + //Maximum of 7 vibrato value * 4 + vibratoIndex = ( vibratoIndex + 1 ) & 31; + //Clip tremolo to the the table size + if ( tremoloIndex + 1 < TREMOLO_TABLE ) + ++tremoloIndex; + else + tremoloIndex = 0; + } + return count; } + void Chip::WriteBD( Bit8u val ) { Bit8u change = regBD ^ val; if ( !change ) return; regBD = val; //TODO could do this with shift and xor? - vibratoShift = (val & 0x40) ? 0x00 : 0x01; - tremoloShift = (val & 0x80) ? 0x00 : 0x02; + vibratoStrength = (val & 0x40) ? 0x00 : 0x01; + tremoloStrength = (val & 0x80) ? 0x00 : 0x02; if ( val & 0x20 ) { //Drum was just enabled, make sure channel 6 has the right synth if ( change & 0x20 ) { @@ -1150,53 +1184,69 @@ Bit32u Chip::WriteAddr( Bit32u port, Bit8u val ) { return 0; } -void Chip::GenerateBlock2( Bitu samples ) { - Work.samples = samples; - for ( Bitu i = 0; i < Work.samples; i++ ) { - Work.vibTable[i] = ForwardVibrato(); - Work.tremTable[i] = ForwardTremolo(); - Work.output[i] = 0; - } - int count = 0; - for( Channel* ch = chan; ch < chan + 9; ) { - count++; - ch = (ch->*(ch->synthHandler))(); +void Chip::GenerateBlock2( Bitu total, Bit32s* output ) { + while ( total > 0 ) { + Bit32u samples = ForwardLFO( total ); + for ( Bitu i = 0; i < samples; i++ ) { + output[i] = 0; + } + int count = 0; + for( Channel* ch = chan; ch < chan + 9; ) { + count++; + ch = (ch->*(ch->synthHandler))( this, samples, output ); + } + total -= samples; + output += samples; } } -void Chip::GenerateBlock3( Bitu samples ) { - Work.samples = samples; - for ( Bitu i = 0; i < Work.samples; i++ ) { - Work.vibTable[i] = ForwardVibrato(); - Work.tremTable[i] = ForwardTremolo(); - Work.output[i*2 + 0] = 0; - Work.output[i*2 + 1] = 0; - } - int count = 0; - for( Channel* ch = chan; ch < chan + 18; ) { - count++; - ch = (ch->*(ch->synthHandler))(); +void Chip::GenerateBlock3( Bitu total, Bit32s* output ) { + while ( total > 0 ) { + Bit32u samples = ForwardLFO( total ); + for ( Bitu i = 0; i < samples; i++ ) { + output[i * 2 + 0 ] = 0; + output[i * 2 + 1 ] = 0; + } + int count = 0; + for( Channel* ch = chan; ch < chan + 18; ) { + count++; + ch = (ch->*(ch->synthHandler))( this, samples, output ); + } + total -= samples; + output += samples * 2; } } void Chip::Setup( Bit32u rate ) { - //Vibrato forwards every 1024 samples - vibratoAdd = (Bit32u)((double)rate * (double)( 1 << (VIBRATO_SH - 10) ) / OPLRATE); - vibratoCounter = 0; - //tremolo forwards every 64 samples - //We use a 52 entry table, real is 210, so repeat each sample an extra 4 times - tremoloAdd = (Bit32u)((double)rate * (double)( 1 << (TREMOLO_SH - 6 - 2) ) / OPLRATE); - tremoloCounter = 0; - //10 bits of frequency counter + double original = OPLRATE; +// double original = rate; + double scale = original / (double)rate; + + //Noise counter is run at the same precision as general waves + noiseAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) ); + noiseCounter = 0; + noiseValue = 1; //Make sure it triggers the noise xor the first time + //The low frequency oscillation counter + //Every time his overflows vibrato and tremoloindex are increased + lfoAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) ); + lfoCounter = 0; + vibratoIndex = 0; + tremoloIndex = 0; + //With higher octave this gets shifted up //-1 since the freqCreateTable = *2 - double scale = (OPLRATE * (double)( 1 << ( WAVE_SH - 10 - 1))) / rate; +#ifdef WAVE_PRECISION + double freqScale = ( 1 << 7 ) * scale * ( 1 << ( WAVE_SH - 1 - 10)); for ( int i = 0; i < 16; i++ ) { - //Use rounding with 0.5 - freqMul[i] = (Bit32u)( 0.5 + scale * FreqCreateTable[ i ] ); + freqMul[i] = (Bit32u)( 0.5 + freqScale * FreqCreateTable[ i ] ); } +#else + Bit32u freqScale = (Bit32u)( 0.5 + scale * ( 1 << ( WAVE_SH - 1 - 10))); + for ( int i = 0; i < 16; i++ ) { + freqMul[i] = freqScale * FreqCreateTable[ i ]; + } +#endif - scale = OPLRATE / rate; //-3 since the real envelope takes 8 steps to reach the single value we supply for ( Bit8u i = 0; i < 76; i++ ) { Bit8u index, shift; @@ -1456,12 +1506,15 @@ void Handler::WriteReg( Bit32u addr, Bit8u val ) { } void Handler::Generate( MixerChannel* chan, Bitu samples ) { + Bit32s buffer[ 512 * 2 ]; + if ( samples > 512 ) + samples = 512; if ( !chip.opl3Active ) { - chip.GenerateBlock2( samples ); - chan->AddSamples_m32( samples, Work.output ); + chip.GenerateBlock2( samples, buffer ); + chan->AddSamples_m32( samples, buffer ); } else { - chip.GenerateBlock3( samples ); - chan->AddSamples_s32( samples, Work.output ); + chip.GenerateBlock3( samples, buffer ); + chan->AddSamples_s32( samples, buffer ); } } diff --git a/src/hardware/dbopl.h b/src/hardware/dbopl.h index 9232404f..c0e5367a 100644 --- a/src/hardware/dbopl.h +++ b/src/hardware/dbopl.h @@ -28,10 +28,6 @@ //Select the type of wave generator routine #define DBOPL_WAVE WAVE_TABLEMUL -//Enable vibrato in the output -#define DBOPL_VIBRATO -//Enable tremolo in the output -#define DBOPL_TREMOLO namespace DBOPL { @@ -44,20 +40,21 @@ typedef Bits ( DB_FASTCALL *WaveHandler) ( Bitu i, Bitu volume ); #endif typedef Bits ( DBOPL::Operator::*VolumeHandler) ( ); -typedef Channel* ( DBOPL::Channel::*SynthHandler) ( ); +typedef Channel* ( DBOPL::Channel::*SynthHandler) ( Chip* chip, Bit32u samples, Bit32s* output ); //Different synth modes that can generate blocks of data typedef enum { - smNone, sm2AM, sm2FM, - sm2Percussion, sm3AM, sm3FM, + sm4Start, sm3FMFM, sm3AMFM, sm3FMAM, sm3AMAM, + sm6Start, + sm2Percussion, sm3Percussion, } SynthMode; @@ -95,14 +92,16 @@ public: Bit32u waveStart; #endif Bit32u waveIndex; //WAVE_BITS shifted counter of the frequency index - Bit32u waveAdd; + Bit32u waveAdd; //The base frequency without vibrato + Bit32u waveCurrent; //waveAdd + vibratao Bit32u chanData; //Frequency/octave and derived data coming from whatever channel controls this Bit32u freqMul; //Scale channel frequency with this, TODO maybe remove? Bit32u vibrato; //Scaled up vibrato strength Bit32s sustainLevel; //When stopping at sustain level stop here - Bit32s totalLevel; //totalLeve is added to every generated volume - Bit32s activeLevel; //The currently active volume + Bit32s totalLevel; //totalLevel is added to every generated volume + Bit32u currentLevel; //totalLevel + tremolo + Bit32s volume; //The currently active volume Bit32u attackAdd; //Timers for the different states of the envelope Bit32u decayAdd; @@ -129,7 +128,7 @@ private: public: void UpdateAttenuation(); void UpdateRates( const Chip* chip ); - void UpdateFrequency( ); + void UpdateFrequency( ); void Write20( const Chip* chip, Bit8u val ); void Write40( const Chip* chip, Bit8u val ); @@ -138,6 +137,8 @@ public: void WriteE0( const Chip* chip, Bit8u val ); bool Silent() const; + void Prepare( const Chip* chip ); + void KeyOn( Bit8u mask); void KeyOff( Bit8u mask); @@ -182,20 +183,23 @@ struct Channel { //call this for the first channel template< bool opl3Mode > - void GeneratePercussion( Bit32s* output ); + void GeneratePercussion( Chip* chip, Bit32s* output ); //Generate blocks of data in specific modes template - Channel* BlockTemplate( ); + Channel* BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ); Channel(); }; struct Chip { //This is used as the base counter for vibrato and tremolo - Bit32u tremoloCounter; - Bit32u tremoloAdd; - Bit32u vibratoCounter; - Bit32u vibratoAdd; + Bit32u lfoCounter; + Bit32u lfoAdd; + + + Bit32u noiseCounter; + Bit32u noiseAdd; + Bit32u noiseValue; //Frequency scales for the different multiplications Bit32u freqMul[16]; @@ -211,23 +215,29 @@ struct Chip { Bit8u reg08; Bit8u reg04; Bit8u regBD; + Bit8u vibratoIndex; + Bit8u tremoloIndex; + Bit8s vibratoSign; Bit8u vibratoShift; - Bit8u tremoloShift; + Bit8u tremoloValue; + Bit8u vibratoStrength; + Bit8u tremoloStrength; //Mask for allowed wave forms Bit8u waveFormMask; //0 or -1 when enabled Bit8s opl3Active; - Bit8u ForwardTremolo(); - Bit8s ForwardVibrato(); + //Return the maximum amount of samples before and LFO change + Bit32u ForwardLFO( Bit32u samples ); + Bit32u ForwardNoise(); void WriteBD( Bit8u val ); void WriteReg(Bit32u reg, Bit8u val ); Bit32u WriteAddr( Bit32u port, Bit8u val ); - void GenerateBlock2( Bitu samples ); - void GenerateBlock3( Bitu samples ); + void GenerateBlock2( Bitu samples, Bit32s* output ); + void GenerateBlock3( Bitu samples, Bit32s* output ); void Generate( Bit32u samples ); void Setup( Bit32u r ); From fb2a129ca602bbe45c2d07682deb2b868363ed54 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 14 May 2009 17:51:47 +0000 Subject: [PATCH 3295/4131] fix some nice compilation error. Blame woody ;) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3383 --- src/ints/ems.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 51b74d4f..8a00705e 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.61 2009-05-14 17:05:58 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.62 2009-05-14 17:51:47 qbix79 Exp $ */ #include #include @@ -126,7 +126,7 @@ bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retco mem_writeb(GEMMIS_addr+0x0a+frnr,0x03); // frame type: EMS frame in 64k page mem_writeb(GEMMIS_addr+0x0b+frnr,0xff); // owner: NONE mem_writew(GEMMIS_addr+0x0c+frnr,0x7fff); // no logical page number - mem_writeb(GEMMIS_addr+0x0e+frnr,(Bit8u)(frct&0xff)); // physical EMS page number + mem_writeb(GEMMIS_addr+0x0e + frnr,(Bit8u)(frct&0xff)); // physical EMS page number mem_writeb(GEMMIS_addr+0x0f+frnr,0x00); // EMS frame } /* build non-EMS ROM frames (0xf000-0x10000) */ From 1ecf32e26780588bd3318ad68cb84c160ba32235 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 14 May 2009 18:01:25 +0000 Subject: [PATCH 3296/4131] Make it possible to compile with Xlib headers. Pray nobody does that who has evdev installed Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3384 --- src/gui/sdl_mapper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 896790db..d8f3c4cb 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.58 2009-04-25 06:59:54 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.59 2009-05-14 18:01:25 qbix79 Exp $ */ #include #include @@ -2332,7 +2332,7 @@ void MAPPER_Init(void) { } } //Somehow including them at the top conflicts with something in setup.h -#ifdef LINUX +#ifdef C_X11_XKB #include "SDL_syswm.h" #include #endif @@ -2381,7 +2381,7 @@ void MAPPER_StartUp(Section * sec) { sdlkey_map[0x41]=SDLK_KP6; #elif !defined (WIN32) /* => Linux & BSDs */ bool evdev_input = false; -#ifdef LINUX +#ifdef C_X11_XKB SDL_SysWMinfo info; SDL_VERSION(&info.version); if (SDL_GetWMInfo(&info)) { From 02bfff0d5ffedc1cecac10e6a4b0e8d27e82aeae Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 14 May 2009 18:28:04 +0000 Subject: [PATCH 3297/4131] Fix dual opl2 handling and put a low limit on sample rate Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3385 --- src/hardware/adlib.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index d2e3bf94..8e8280c1 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: adlib.cpp,v 1.38 2009-04-28 21:48:24 harekiet Exp $ */ +/* $Id: adlib.cpp,v 1.39 2009-05-14 18:28:04 harekiet Exp $ */ #include #include @@ -530,8 +530,8 @@ void Module::DualWrite( Bit8u index, Bit8u reg, Bit8u val ) { if ( chip[index].Write( reg, val ) ) return; //Enabling panning - if ( reg >= 0xc0 && reg <0xc8 ) { - val &= 7; + if ( reg >= 0xc0 && reg <=0xc8 ) { + val &= 0x0f; val |= index ? 0xA0 : 0x50; } Bit32u fullReg = reg + (index ? 0x100 : 0); @@ -729,6 +729,9 @@ Module::Module( Section* configuration ) : Module_base(configuration) { Section_prop * section=static_cast(configuration); Bitu base = section->Get_hex("sbbase"); Bitu rate = section->Get_int("oplrate"); + //Make sure we can't select lower than 8000 to prevent fixed point issues + if ( rate < 8000 ) + rate = 8000; std::string oplemu( section->Get_string( "oplemu" ) ); mixerChan = mixerObject.Install(OPL_CallBack,rate,"FM"); From 7f67bfd3ee1713c6ac52e7ba7626693fb9dcc968 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 14 May 2009 18:44:54 +0000 Subject: [PATCH 3298/4131] ASCII advertising. ;) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3386 --- src/shell/shell.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index ae9d40a3..5dd268b9 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.98 2009-03-23 10:55:36 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.99 2009-05-14 18:44:54 qbix79 Exp $ */ #include #include @@ -498,7 +498,7 @@ void SHELL_Init() { ); MSG_Add("SHELL_STARTUP_END", "\xBA \033[32mHAVE FUN!\033[37m \xBA\n" - "\xBA \033[32mThe DOSBox Team\033[37m \xBA\n" + "\xBA \033[32mThe DOSBox Team \033[33mhttp://www.dosbox.com\033[37m \xBA\n" "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC\033[0m\n" From 144240717ddaac25c5a1072aae17831ce6dc6671 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 14 May 2009 18:51:53 +0000 Subject: [PATCH 3299/4131] Don't turn mixer channel off is current volume is not 0. Slowly decrease volume if idle for a while. Fixes (most of) the clicks of secret agent. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3387 --- src/hardware/pcspeaker.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 1e063e7e..15b5887b 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /* $Id: pcspeaker.cpp,v 1.24 2007-07-15 16:36:27 c2woody Exp $ */ + /* $Id: pcspeaker.cpp,v 1.25 2009-05-14 18:51:53 qbix79 Exp $ */ #include #include "dosbox.h" @@ -305,15 +305,21 @@ static void PCSPEAKER_CallBack(Bitu len) { if(spkr.chan) spkr.chan->AddSamples_m16(len,(Bit16s*)MixTemp); //Turn off speaker after 10 seconds of idle or one second idle when in off mode + bool turnoff = false; Bitu test_ticks = PIC_Ticks; - if ((spkr.last_ticks+10000)Enable(false); + if ((spkr.last_ticks + 10000) < test_ticks) turnoff = true; + if((spkr.mode == SPKR_OFF) && ((spkr.last_ticks + 1000) < test_ticks)) turnoff = true; + + if(turnoff){ + if(spkr.volwant == 0) { + spkr.last_ticks = 0; + if(spkr.chan) spkr.chan->Enable(false); + } else { + if(spkr.volwant > 0) spkr.volwant--; else spkr.volwant++; + + } } - if((spkr.mode == SPKR_OFF) && ((spkr.last_ticks+1000) Enable(false); - } + } class PCSPEAKER:public Module_base { private: From 1056f050355ca07bbc78c36e1c2ac96c3c9856eb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 14 May 2009 18:56:09 +0000 Subject: [PATCH 3300/4131] Nice start of the Changelog for 0.73 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3388 --- ChangeLog | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/ChangeLog b/ChangeLog index aec4a64b..d0263a17 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,53 @@ +0.73 + - Add EGA emulation. + - Add vgaonly machine mode. Supports more of the exotic tricks like + changing the palette during screen updates. 9x16 fonts etc. + - Fix problems with the split lines + - Improve vesa emulation. + - Improve video BIOS emulation to behave more like a real bios. + - Fixes to paging system + - various fixes and improvements for the recompiling core. + - Add some mscdex quirks when dealing with files that are exactly 8.3 long + - Small fixes to batch file handling. + - Small fixes to the XMS memory handling. + - various fixes for aligned memory on hosts that want it. + - Various improvements to the mouse. + - Fixes and small speed ups to the debugger. + - Fix and improve lot's of compilation problems. (curses detection, + GCC 3.4 and GCC 4.X fixes) + - Added some basic auto keyboard layout handling (windows only currently) + - Add basic support for evdev keyboard driver. + - Various fixes to the timer. (improve mode 2 timer changes, + implement mode 1, improve gate2 handling) + - Add audio extraction and mci reading. Should enable CDROM audio for Vista. + - Improve the directory cache speed a lot! + - Various fixes to the create temporary file call. + - Don't keep batchfiles open during execution. Allows rewriting of the + active batchfile (menu programs use this trick sometimes) + - Fix problems with filenames with 2 extensions. + - Fixes to hercules emulation. + - Fix flag handling for ROR + - Make the batchfile handling in regard to IF more flexible + - Fixes to scrolling (panning) + - Add prefetch queue emulation. + - Make the emulated cpu type selectable. This is mainly the + identification commands and the way paging works. + - Added special machine modes for the following svga cards: + - S3 + - Paradise + - Tseng + - Improve support for EMS when booting a different OS. + - Improve cdrom speed detection by games. + - Improve stability of cycle guessing code, when there is background + activity. + - Fix various mscdex and cdrom detection schemes. + - Added Coremidi support on Mac OS X. + - Improve support for DOS devices when used to detect the existance + of directories in various ways. + - Add IRQ 2 emulation on VRET (ega only) + - Added video parameter table and video state functionality. + - Increase default freespace to 250 MB. + 0.72 - Fixed unitialized variable in joystick. (Fixes crashes on Vista and Mac OS X) From 7696f4706cf8f7e0685f8fe00c342fa32acf4f9d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 15 May 2009 18:16:33 +0000 Subject: [PATCH 3301/4131] Add some hopeful helpful text when startserver fails. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3389 --- src/hardware/ipx.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index 4d4e800b..f5c16af4 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.cpp,v 1.15 2008-07-26 14:49:38 qbix79 Exp $ */ +/* $Id: ipx.cpp,v 1.16 2009-05-15 18:16:33 qbix79 Exp $ */ #include "dosbox.h" @@ -951,7 +951,8 @@ public: isIpxServer = true; ConnectToServer("localhost"); } else { - WriteOut("IPX Tunneling Server failed to start\n"); + WriteOut("IPX Tunneling Server failed to start.\n"); + if(udpPort < 1024) WriteOut("Try a port number above 1024. See IPXNET HELP CONNECT on how to specify a port.\n"); } } else { WriteOut("IPX Tunneling Server already started\n"); From 05da192ef7747b33887fbb256cf41ccc805987cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 15 May 2009 21:07:13 +0000 Subject: [PATCH 3302/4131] small cleanup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3390 --- src/hardware/adlib.cpp | 4 ++-- src/hardware/opl.cpp | 43 +++++++++++++++++++++++++----------------- src/hardware/opl.h | 11 +++++++++-- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 8e8280c1..41e826c0 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: adlib.cpp,v 1.39 2009-05-14 18:28:04 harekiet Exp $ */ +/* $Id: adlib.cpp,v 1.40 2009-05-15 21:07:13 c2woody Exp $ */ #include #include @@ -93,7 +93,7 @@ namespace OPL3 { } virtual Bit32u WriteAddr( Bit32u port, Bit8u val ) { adlib_write_index(port, val); - return index; + return opl_index; } virtual void Generate( MixerChannel* chan, Bitu samples ) { Bit16s buf[1024*2]; diff --git a/src/hardware/opl.cpp b/src/hardware/opl.cpp index 2d8d6b1d..b179a037 100644 --- a/src/hardware/opl.cpp +++ b/src/hardware/opl.cpp @@ -26,7 +26,7 @@ #include -#include +#include // rand() #include "dosbox.h" #include "opl.h" @@ -44,8 +44,8 @@ static Bit32s tremval_const[BLOCKBUF_SIZE]; // vibrato value tables (used per-operator) static Bit32s vibval_var1[BLOCKBUF_SIZE]; static Bit32s vibval_var2[BLOCKBUF_SIZE]; -static Bit32s vibval_var3[BLOCKBUF_SIZE]; -static Bit32s vibval_var4[BLOCKBUF_SIZE]; +//static Bit32s vibval_var3[BLOCKBUF_SIZE]; +//static Bit32s vibval_var4[BLOCKBUF_SIZE]; // vibrato/trmolo value table pointers static Bit32s *vibval1, *vibval2, *vibval3, *vibval4; @@ -131,8 +131,18 @@ static Bit32u wavestart[8] = { }; // envelope generator function constants -static fltype attackconst[4] = {1/2.82624,1/2.25280,1/1.88416,1/1.59744}; -static fltype decrelconst[4] = {1/39.28064,1/31.41608,1/26.17344,1/22.44608}; +static fltype attackconst[4] = { + (fltype)(1/2.82624), + (fltype)(1/2.25280), + (fltype)(1/1.88416), + (fltype)(1/1.59744) +}; +static fltype decrelconst[4] = { + (fltype)(1/39.28064), + (fltype)(1/31.41608), + (fltype)(1/26.17344), + (fltype)(1/22.44608) +}; void operator_advance(op_type* op_pt, Bit32s vib) { @@ -280,9 +290,9 @@ void operator_attack(op_type* op_pt) { op_pt->amp = 1.0; op_pt->step_amp = 1.0; } - op_pt->step_skip_pos <<= 1; - if (op_pt->step_skip_pos==0) op_pt->step_skip_pos = 1; - if (op_pt->step_skip_pos & op_pt->env_step_skip_a) { // check if required to skip next step + op_pt->step_skip_pos_a <<= 1; + if (op_pt->step_skip_pos_a==0) op_pt->step_skip_pos_a = 1; + if (op_pt->step_skip_pos_a & op_pt->env_step_skip_a) { // check if required to skip next step op_pt->step_amp = op_pt->amp; } } @@ -493,7 +503,7 @@ void adlib_init(Bit32u samplerate) { op[i].env_step_a = 0; op[i].env_step_d = 0; op[i].env_step_r = 0; - op[i].step_skip_pos = 0; + op[i].step_skip_pos_a = 0; op[i].env_step_skip_a = 0; #if defined(OPLTYPE_IS_OPL3) @@ -510,7 +520,7 @@ void adlib_init(Bit32u samplerate) { } status = 0; - index = 0; + opl_index = 0; // create vibrato table @@ -558,9 +568,9 @@ void adlib_init(Bit32u samplerate) { wavtable[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<1) )*PI*2/WAVEPREC)); wavtable[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<1)+1)*PI*2/WAVEPREC)); wavtable[i] = wavtable[(i<<1) +WAVEPREC]; - // table to be verified, alternative: (zero-less) -/* wavtable[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)(((i*2+1)<<1)-1)*PI/WAVEPREC)); - wavtable[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)(((i*2+1)<<1) )*PI/WAVEPREC)); + // alternative: (zero-less) +/* wavtable[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<2)+1)*PI/WAVEPREC)); + wavtable[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<2)+3)*PI/WAVEPREC)); wavtable[i] = wavtable[(i<<1)-1+WAVEPREC]; */ } for (i=0;i<(WAVEPREC>>3);i++) { @@ -588,7 +598,6 @@ void adlib_init(Bit32u samplerate) { void adlib_write(Bitu idx, Bit8u val) { Bit32u second_set = idx&0x100; - Bit8u old_val = adlibreg[idx]; adlibreg[idx] = val; switch (idx&0xf0) { @@ -900,16 +909,16 @@ Bitu adlib_reg_read(Bitu port) { } void adlib_write_index(Bitu port, Bit8u val) { - index = val; + opl_index = val; #if defined(OPLTYPE_IS_OPL3) if ((port&3)!=0) { // possibly second set - if (((adlibreg[0x105]&1)!=0) || (index==5)) index |= ARC_SECONDSET; + if (((adlibreg[0x105]&1)!=0) || (opl_index==5)) opl_index |= ARC_SECONDSET; } #endif } -static void INLINE clipit16(Bit32s ival, Bit16s* outval) { +static void OPL_INLINE clipit16(Bit32s ival, Bit16s* outval) { if (ival<32768) { if (ival>-32769) { *outval=(Bit16s)ival; diff --git a/src/hardware/opl.h b/src/hardware/opl.h index 317dee24..eafb527c 100644 --- a/src/hardware/opl.h +++ b/src/hardware/opl.h @@ -42,6 +42,13 @@ typedef uint8_t Bit8u; typedef int8_t Bit8s; */ + +/* + define attribution that inlines/forces inlining of a function (optional) +*/ +#define OPL_INLINE INLINE + + #undef NUM_CHANNELS #if defined(OPLTYPE_IS_OPL3) #define NUM_CHANNELS 18 @@ -135,7 +142,7 @@ typedef struct operator_struct { Bit32u generator_pos; // for non-standard sample rates we need to determine how many samples have passed Bits cur_env_step; // current (standardized) sample position Bits env_step_a,env_step_d,env_step_r; // number of std samples of one step (for attack/decay/release mode) - Bit8u step_skip_pos; // position of 8-cyclic step skipping (always 2^x to check against mask) + Bit8u step_skip_pos_a; // position of 8-cyclic step skipping (always 2^x to check against mask) Bits env_step_skip_a; // bitmask that determines if a step is skipped (respective bit is zero then) #if defined(OPLTYPE_IS_OPL3) @@ -151,7 +158,7 @@ op_type op[MAXOPERATORS]; Bits int_samplerate; Bit8u status; -Bit32u index; +Bit32u opl_index; #if defined(OPLTYPE_IS_OPL3) Bit8u adlibreg[512]; // adlib register set (including second set) Bit8u wave_sel[44]; // waveform selection From 1d71454869dee4cc8c109489ac75a078cae4f27a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 16 May 2009 06:40:13 +0000 Subject: [PATCH 3303/4131] Properly convert the 6 bit of vga to the 8bit output Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3391 --- src/hardware/vga_dac.cpp | 42 ++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index ab971f56..a228521c 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -50,16 +50,19 @@ Note: Each read or write of this register will cycle through first the enum {DAC_READ,DAC_WRITE}; -static INLINE void VGA_DAC_UpdateColor( Bitu index ) { +static void VGA_DAC_SendColor( Bitu index, Bitu src ) { + const Bit8u red = vga.dac.rgb[src].red; + const Bit8u green = vga.dac.rgb[src].green; + const Bit8u blue = vga.dac.rgb[src].blue; + //Set entry in 16bit output lookup table + vga.dac.xlat16[index] = ((blue>>1)&0x1f) | (((green)&0x3f)<<5) | (((red>>1)&0x1f) << 11); + + RENDER_SetPal( index, (red << 2) | ( red >> 4 ), (green << 2) | ( green >> 4 ), (blue << 2) | ( blue >> 4 ) ); +} + +static void VGA_DAC_UpdateColor( Bitu index ) { Bitu maskIndex = index & vga.dac.pel_mask; - vga.dac.xlat16[index] = ((vga.dac.rgb[maskIndex].blue>>1)&0x1f) | - (((vga.dac.rgb[maskIndex].green)&0x3f)<<5)| - (((vga.dac.rgb[maskIndex].red>>1)&0x1f) << 11); - RENDER_SetPal( index, - vga.dac.rgb[maskIndex].red << 2, - vga.dac.rgb[maskIndex].green << 2, - vga.dac.rgb[maskIndex].blue << 2 - ); + VGA_DAC_SendColor( index, maskIndex ); } static void write_p3c6(Bitu port,Bitu val,Bitu iolen) { @@ -129,14 +132,7 @@ static void write_p3c9(Bitu port,Bitu val,Bitu iolen) { /* Check for attributes and DAC entry link */ for (Bitu i=0;i<16;i++) { if (vga.dac.combine[i]==vga.dac.write_index) { - vga.dac.xlat16[i] = ( - (vga.dac.rgb[vga.dac.write_index].blue>>1)&0x1f) | - (((vga.dac.rgb[vga.dac.write_index].green)&0x3f)<<5)| - (((vga.dac.rgb[vga.dac.write_index].red>>1)&0x1f) << 11); - RENDER_SetPal(i, - vga.dac.rgb[vga.dac.write_index].red << 2, - vga.dac.rgb[vga.dac.write_index].green << 2, - vga.dac.rgb[vga.dac.write_index].blue << 2); + VGA_DAC_SendColor( i, vga.dac.write_index ); } } } @@ -184,16 +180,8 @@ void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal) { case M_VGA: // used by copper demo; almost no video card seems to suport it if(!IS_VGA_ARCH || (svgaCard!=SVGA_None)) break; - default: - vga.dac.xlat16[attr] = ((vga.dac.rgb[pal].blue>>1)&0x1f) | - (((vga.dac.rgb[pal].green)&0x3f)<<5)| - (((vga.dac.rgb[pal].red>>1)&0x1f) << 11); - RENDER_SetPal(attr, - vga.dac.rgb[pal].red << 2, - vga.dac.rgb[pal].green << 2, - vga.dac.rgb[pal].blue << 2 - ); + VGA_DAC_SendColor( attr, pal ); } } @@ -204,7 +192,7 @@ void VGA_DAC_SetEntry(Bitu entry,Bit8u red,Bit8u green,Bit8u blue) { vga.dac.rgb[entry].blue=blue; for (Bitu i=0;i<16;i++) if (vga.dac.combine[i]==entry) - RENDER_SetPal(i,red << 2,green << 2,blue << 2); + VGA_DAC_SendColor( i, i ); } void VGA_SetupDAC(void) { From 64aaada31a0efadd7c919f4ad08e9d762be73cd1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 16 May 2009 08:29:05 +0000 Subject: [PATCH 3304/4131] Don't install handlers for 0x220-0x223 when using opl2 so we can have both opl2 and cms. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3392 --- src/hardware/adlib.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 41e826c0..0500b95a 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: adlib.cpp,v 1.40 2009-05-15 21:07:13 c2woody Exp $ */ +/* $Id: adlib.cpp,v 1.41 2009-05-16 08:29:05 harekiet Exp $ */ #include #include @@ -754,10 +754,10 @@ Module::Module( Section* configuration ) : Module_base(configuration) { handler = new DBOPL::Handler(); } handler->Init( rate ); - Bit8u portRange = 4; //opl2 will set this to 2 + bool single = false; switch ( oplmode ) { case OPL_opl2: - portRange = 2; + single = true; Init( Adlib::MODE_OPL2 ); break; case OPL_dualopl2: @@ -768,14 +768,16 @@ Module::Module( Section* configuration ) : Module_base(configuration) { break; } //0x388 range - WriteHandler[0].Install(0x388,OPL_Write,IO_MB, portRange ); - ReadHandler[0].Install(0x388,OPL_Read,IO_MB, portRange - 1 ); + WriteHandler[0].Install(0x388,OPL_Write,IO_MB, 4 ); + ReadHandler[0].Install(0x388,OPL_Read,IO_MB, 4 ); //0x220 range - WriteHandler[1].Install(base,OPL_Write,IO_MB, portRange ); - ReadHandler[1].Install(base,OPL_Read,IO_MB, portRange - 1 ); + if ( !single ) { + WriteHandler[1].Install(base,OPL_Write,IO_MB, 4 ); + ReadHandler[1].Install(base,OPL_Read,IO_MB, 4 ); + } //0x228 range - WriteHandler[2].Install(base+8,OPL_Write,IO_MB,2); - ReadHandler[2].Install(base+8,OPL_Read,IO_MB,1); + WriteHandler[2].Install(base+8,OPL_Write,IO_MB, 2); + ReadHandler[2].Install(base+8,OPL_Read,IO_MB, 1); MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL"); } From 79de511c0ee02e315cda6cb72d761649f9f5ccd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 16 May 2009 21:52:47 +0000 Subject: [PATCH 3305/4131] update recompiler arm backend (M-HT) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3393 --- THANKS | 5 +- src/cpu/core_dynrec/risc_armv4le-common.h | 18 +- src/cpu/core_dynrec/risc_armv4le-o3.h | 495 +++++++----- src/cpu/core_dynrec/risc_armv4le-s3.h | 462 ++++++----- src/cpu/core_dynrec/risc_armv4le-thumb-iw.h | 805 +++++++++++-------- src/cpu/core_dynrec/risc_armv4le-thumb-niw.h | 791 ++++++++++-------- src/cpu/core_dynrec/risc_armv4le-thumb.h | 801 ++++++++++-------- 7 files changed, 1925 insertions(+), 1452 deletions(-) diff --git a/THANKS b/THANKS index 7698f021..42ed2d72 100644 --- a/THANKS +++ b/THANKS @@ -3,7 +3,8 @@ We would like to thank: Vlad R. of the vdmsound project for excellent sound blaster info. Tatsuyuki Satoh of the Mame Team for making an excellent FM emulator. -Jarek Burczynski for the new OPL emulator. +Jarek Burczynski for the new OPL3 emulator. +Ken Silverman for his work on an OPL2 emulator. The Bochs and DOSemu projects which I used for information. Freedos for ideas in making my shell. @@ -15,7 +16,7 @@ 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. +crazyc, gulikoza, M-HT for their work on the dynrec core. Jantien for the version management. Shawn, Johannes and Marcus for creating the MAC OS X version. diff --git a/src/cpu/core_dynrec/risc_armv4le-common.h b/src/cpu/core_dynrec/risc_armv4le-common.h index d150c14c..9478a4ea 100644 --- a/src/cpu/core_dynrec/risc_armv4le-common.h +++ b/src/cpu/core_dynrec/risc_armv4le-common.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-common.h,v 1.2 2008-09-19 16:48:02 c2woody Exp $ */ +/* $Id: risc_armv4le-common.h,v 1.3 2009-05-16 21:52:47 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (common data/functions) */ @@ -89,8 +89,19 @@ typedef Bit8u HostReg; static void cache_block_closing(Bit8u* block_start,Bitu block_size) { +#if (__ARM_EABI__) + //flush cache - eabi + register unsigned long _beg __asm ("a1") = (unsigned long)(block_start); // block start + register unsigned long _end __asm ("a2") = (unsigned long)(block_start+block_size); // block end + register unsigned long _flg __asm ("a3") = 0; + register unsigned long _par __asm ("r7") = 0xf0002; // sys_cacheflush + __asm __volatile ("swi 0x0" + : // no outputs + : "r" (_beg), "r" (_end), "r" (_flg), "r" (_par) + ); +#else // GP2X BEGIN - //flush cache + //flush cache - old abi register unsigned long _beg __asm ("a1") = (unsigned long)(block_start); // block start register unsigned long _end __asm ("a2") = (unsigned long)(block_start+block_size); // block end register unsigned long _flg __asm ("a3") = 0; @@ -99,4 +110,5 @@ static void cache_block_closing(Bit8u* block_start,Bitu block_size) { : "r" (_beg), "r" (_end), "r" (_flg) ); // GP2X END +#endif } diff --git a/src/cpu/core_dynrec/risc_armv4le-o3.h b/src/cpu/core_dynrec/risc_armv4le-o3.h index 625c14c7..4b6916b8 100644 --- a/src/cpu/core_dynrec/risc_armv4le-o3.h +++ b/src/cpu/core_dynrec/risc_armv4le-o3.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-o3.h,v 1.3 2008-09-19 16:48:02 c2woody Exp $ */ +/* $Id: risc_armv4le-o3.h,v 1.4 2009-05-16 21:52:47 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (size-tweaked arm version) */ @@ -58,13 +58,102 @@ #define FC_SEGS_ADDR HOST_v8 #endif + // helper macro #define ROTATE_SCALE(x) ( (x)?(32 - x):(0) ) + +// instruction encodings + +// move +// mov dst, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define MOV_IMM(dst, imm, rimm) (0xe3a00000 + ((dst) << 12) + (imm) + ((rimm) << 7) ) +// mov dst, src, lsl #imm +#define MOV_REG_LSL_IMM(dst, src, imm) (0xe1a00000 + ((dst) << 12) + (src) + ((imm) << 7) ) +// movs dst, src, lsl #imm +#define MOVS_REG_LSL_IMM(dst, src, imm) (0xe1b00000 + ((dst) << 12) + (src) + ((imm) << 7) ) +// mov dst, src, lsr #imm +#define MOV_REG_LSR_IMM(dst, src, imm) (0xe1a00020 + ((dst) << 12) + (src) + ((imm) << 7) ) +// mov dst, src, asr #imm +#define MOV_REG_ASR_IMM(dst, src, imm) (0xe1a00040 + ((dst) << 12) + (src) + ((imm) << 7) ) +// mov dst, src, lsl rreg +#define MOV_REG_LSL_REG(dst, src, rreg) (0xe1a00010 + ((dst) << 12) + (src) + ((rreg) << 8) ) +// mov dst, src, lsr rreg +#define MOV_REG_LSR_REG(dst, src, rreg) (0xe1a00030 + ((dst) << 12) + (src) + ((rreg) << 8) ) +// mov dst, src, asr rreg +#define MOV_REG_ASR_REG(dst, src, rreg) (0xe1a00050 + ((dst) << 12) + (src) + ((rreg) << 8) ) +// mov dst, src, ror rreg +#define MOV_REG_ROR_REG(dst, src, rreg) (0xe1a00070 + ((dst) << 12) + (src) + ((rreg) << 8) ) +// mvn dst, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define MVN_IMM(dst, imm, rimm) (0xe3e00000 + ((dst) << 12) + (imm) + ((rimm) << 7) ) + +// arithmetic +// add dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define ADD_IMM(dst, src, imm, rimm) (0xe2800000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) +// add dst, src1, src2, lsl #imm +#define ADD_REG_LSL_IMM(dst, src1, src2, imm) (0xe0800000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) +// sub dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define SUB_IMM(dst, src, imm, rimm) (0xe2400000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) +// sub dst, src1, src2, lsl #imm +#define SUB_REG_LSL_IMM(dst, src1, src2, imm) (0xe0400000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) +// rsb dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define RSB_IMM(dst, src, imm, rimm) (0xe2600000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) +// cmp src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define CMP_IMM(src, imm, rimm) (0xe3500000 + ((src) << 16) + (imm) + ((rimm) << 7) ) +// nop +#define NOP MOV_REG_LSL_IMM(HOST_r0, HOST_r0, 0) + +// logical +// tst src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define TST_IMM(src, imm, rimm) (0xe3100000 + ((src) << 16) + (imm) + ((rimm) << 7) ) +// and dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define AND_IMM(dst, src, imm, rimm) (0xe2000000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) +// and dst, src1, src2, lsl #imm +#define AND_REG_LSL_IMM(dst, src1, src2, imm) (0xe0000000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) +// orr dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define ORR_IMM(dst, src, imm, rimm) (0xe3800000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) +// orr dst, src1, src2, lsl #imm +#define ORR_REG_LSL_IMM(dst, src1, src2, imm) (0xe1800000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) +// orr dst, src1, src2, lsr #imm +#define ORR_REG_LSR_IMM(dst, src1, src2, imm) (0xe1800020 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) +// eor dst, src1, src2, lsl #imm +#define EOR_REG_LSL_IMM(dst, src1, src2, imm) (0xe0200000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) +// bic dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define BIC_IMM(dst, src, imm, rimm) (0xe3c00000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) + +// load +// ldr reg, [addr, #imm] @ 0 <= imm < 4096 +#define LDR_IMM(reg, addr, imm) (0xe5900000 + ((reg) << 12) + ((addr) << 16) + (imm) ) +// ldrh reg, [addr, #imm] @ 0 <= imm < 256 +#define LDRH_IMM(reg, addr, imm) (0xe1d000b0 + ((reg) << 12) + ((addr) << 16) + (((imm) & 0xf0) << 4) + ((imm) & 0x0f) ) +// ldrb reg, [addr, #imm] @ 0 <= imm < 4096 +#define LDRB_IMM(reg, addr, imm) (0xe5d00000 + ((reg) << 12) + ((addr) << 16) + (imm) ) + +// store +// str reg, [addr, #imm] @ 0 <= imm < 4096 +#define STR_IMM(reg, addr, imm) (0xe5800000 + ((reg) << 12) + ((addr) << 16) + (imm) ) +// strh reg, [addr, #imm] @ 0 <= imm < 256 +#define STRH_IMM(reg, addr, imm) (0xe1c000b0 + ((reg) << 12) + ((addr) << 16) + (((imm) & 0xf0) << 4) + ((imm) & 0x0f) ) +// strb reg, [addr, #imm] @ 0 <= imm < 4096 +#define STRB_IMM(reg, addr, imm) (0xe5c00000 + ((reg) << 12) + ((addr) << 16) + (imm) ) + +// branch +// beq pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 +#define BEQ_FWD(imm) (0x0a000000 + ((imm) >> 2) ) +// bne pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 +#define BNE_FWD(imm) (0x1a000000 + ((imm) >> 2) ) +// bgt pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 +#define BGT_FWD(imm) (0xca000000 + ((imm) >> 2) ) +// b pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 +#define B_FWD(imm) (0xea000000 + ((imm) >> 2) ) +// bx reg +#define BX(reg) (0xe12fff10 + (reg) ) + + // move a full register from reg_src to reg_dst static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { if(reg_src == reg_dst) return; - cache_addd(0xe1a00000 + (reg_dst << 12) + reg_src); // mov reg_dst, reg_src + cache_addd( MOV_REG_LSL_IMM(reg_dst, reg_src, 0) ); // mov reg_dst, reg_src } // helper function @@ -114,9 +203,9 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { Bits first, method, scale; Bit32u imm2, dist; if (imm == 0) { - cache_addd(0xe3a00000 + (dest_reg << 12)); // mov dest_reg, #0 + cache_addd( MOV_IMM(dest_reg, 0, 0) ); // mov dest_reg, #0 } else if (imm == 0xffffffff) { - cache_addd(0xe3e00000 + (dest_reg << 12)); // mvn dest_reg, #0 + cache_addd( MVN_IMM(dest_reg, 0, 0) ); // mvn dest_reg, #0 } else { method = get_method_imm_gen_len(imm, 1, NULL); @@ -130,10 +219,10 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { scale+=2; } if (first) { - cache_addd(0xe2400000 + (dest_reg << 12) + (HOST_pc << 16) + (ROTATE_SCALE(scale) << 7) + (dist & 0xff)); // sub dest_reg, pc, #((dist & 0xff) << scale) + cache_addd( SUB_IMM(dest_reg, HOST_pc, dist & 0xff, ROTATE_SCALE(scale)) ); // sub dest_reg, pc, #((dist & 0xff) << scale) first = 0; } else { - cache_addd(0xe2400000 + (dest_reg << 12) + (dest_reg << 16) + (ROTATE_SCALE(scale) << 7) + (dist & 0xff)); // sub dest_reg, dest_reg, #((dist & 0xff) << scale) + cache_addd( SUB_IMM(dest_reg, dest_reg, dist & 0xff, ROTATE_SCALE(scale)) ); // sub dest_reg, dest_reg, #((dist & 0xff) << scale) } dist>>=8; scale+=8; @@ -141,7 +230,7 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { } else if (method == 1) { dist = imm - ((Bit32u)cache.pos+8); if (dist == 0) { - cache_addd(0xe1a00000 + (dest_reg << 12) + HOST_pc); // mov dest_reg, pc + cache_addd( MOV_REG_LSL_IMM(dest_reg, HOST_pc, 0) ); // mov dest_reg, pc } else { while (dist) { while ((dist & 3) == 0) { @@ -149,10 +238,10 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { scale+=2; } if (first) { - cache_addd(0xe2800000 + (dest_reg << 12) + (HOST_pc << 16) + (ROTATE_SCALE(scale) << 7) + (dist & 0xff)); // add dest_reg, pc, #((dist & 0xff) << scale) + cache_addd( ADD_IMM(dest_reg, HOST_pc, dist & 0xff, ROTATE_SCALE(scale)) ); // add dest_reg, pc, #((dist & 0xff) << scale) first = 0; } else { - cache_addd(0xe2800000 + (dest_reg << 12) + (dest_reg << 16) + (ROTATE_SCALE(scale) << 7) + (dist & 0xff)); // add dest_reg, dest_reg, #((dist & 0xff) << scale) + cache_addd( ADD_IMM(dest_reg, dest_reg, dist & 0xff, ROTATE_SCALE(scale)) ); // add dest_reg, dest_reg, #((dist & 0xff) << scale) } dist>>=8; scale+=8; @@ -165,10 +254,10 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { scale+=2; } if (first) { - cache_addd(0xe3a00000 + (dest_reg << 12) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // mov dest_reg, #((imm & 0xff) << scale) + cache_addd( MOV_IMM(dest_reg, imm & 0xff, ROTATE_SCALE(scale)) ); // mov dest_reg, #((imm & 0xff) << scale) first = 0; } else { - cache_addd(0xe3800000 + (dest_reg << 12) + (dest_reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // orr dest_reg, dest_reg, #((imm & 0xff) << scale) + cache_addd( ORR_IMM(dest_reg, dest_reg, imm & 0xff, ROTATE_SCALE(scale)) ); // orr dest_reg, dest_reg, #((imm & 0xff) << scale) } imm>>=8; scale+=8; @@ -181,10 +270,10 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { scale+=2; } if (first) { - cache_addd(0xe3e00000 + (dest_reg << 12) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // mvn dest_reg, #((imm2 & 0xff) << scale) + cache_addd( MVN_IMM(dest_reg, imm2 & 0xff, ROTATE_SCALE(scale)) ); // mvn dest_reg, #((imm2 & 0xff) << scale) first = 0; } else { - cache_addd(0xe3c00000 + (dest_reg << 12) + (dest_reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // bic dest_reg, dest_reg, #((imm2 & 0xff) << scale) + cache_addd( BIC_IMM(dest_reg, dest_reg, imm2 & 0xff, ROTATE_SCALE(scale)) ); // bic dest_reg, dest_reg, #((imm2 & 0xff) << scale) } imm2>>=8; scale+=8; @@ -199,26 +288,26 @@ static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,Ho if (dword) { if ((Bit32u)data & 3) { if ( ((Bit32u)data & 3) == 2 ) { - cache_addd(0xe1d000b0 + (dest_reg << 12) + (data_reg << 16)); // ldrh dest_reg, [data_reg] - cache_addd(0xe1d000b2 + (temp2 << 12) + (data_reg << 16)); // ldrh temp2, [data_reg, #2] - cache_addd(0xe1800800 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #16 + cache_addd( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] + cache_addd( LDRH_IMM(temp2, data_reg, 2) ); // ldrh temp2, [data_reg, #2] + cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 16) ); // orr dest_reg, dest_reg, temp2, lsl #16 } else { - cache_addd(0xe5d00000 + (dest_reg << 12) + (data_reg << 16)); // ldrb dest_reg, [data_reg] - cache_addd(0xe1d000b1 + (temp2 << 12) + (data_reg << 16)); // ldrh temp2, [data_reg, #1] - cache_addd(0xe1800400 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #8 - cache_addd(0xe5d00003 + (temp2 << 12) + (data_reg << 16)); // ldrb temp2, [data_reg, #3] - cache_addd(0xe1800c00 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #24 + cache_addd( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] + cache_addd( LDRH_IMM(temp2, data_reg, 1) ); // ldrh temp2, [data_reg, #1] + cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 8) ); // orr dest_reg, dest_reg, temp2, lsl #8 + cache_addd( LDRB_IMM(temp2, data_reg, 3) ); // ldrb temp2, [data_reg, #3] + cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 24) ); // orr dest_reg, dest_reg, temp2, lsl #24 } } else { - cache_addd(0xe5900000 + (dest_reg << 12) + (data_reg << 16)); // ldr dest_reg, [data_reg] + cache_addd( LDR_IMM(dest_reg, data_reg, 0) ); // ldr dest_reg, [data_reg] } } else { if ((Bit32u)data & 1) { - cache_addd(0xe5d00000 + (dest_reg << 12) + (data_reg << 16)); // ldrb dest_reg, [data_reg] - cache_addd(0xe5d00001 + (temp2 << 12) + (data_reg << 16)); // ldrb temp2, [data_reg, #1] - cache_addd(0xe1800400 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #8 + cache_addd( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] + cache_addd( LDRB_IMM(temp2, data_reg, 1) ); // ldrb temp2, [data_reg, #1] + cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 8) ); // orr dest_reg, dest_reg, temp2, lsl #8 } else { - cache_addd(0xe1d000b0 + (dest_reg << 12) + (data_reg << 16)); // ldrh dest_reg, [data_reg] + cache_addd( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] } } } @@ -236,7 +325,7 @@ static void gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { Bits first, scale; Bit32u imm2; if (imm == 0) { - cache_addd(0xe3a00000 + (dest_reg << 12)); // mov dest_reg, #0 + cache_addd( MOV_IMM(dest_reg, 0, 0) ); // mov dest_reg, #0 } else { scale = 0; first = 1; @@ -247,10 +336,10 @@ static void gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { scale+=2; } if (first) { - cache_addd(0xe3a00000 + (dest_reg << 12) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // mov dest_reg, #((imm2 & 0xff) << scale) + cache_addd( MOV_IMM(dest_reg, imm2 & 0xff, ROTATE_SCALE(scale)) ); // mov dest_reg, #((imm2 & 0xff) << scale) first = 0; } else { - cache_addd(0xe3800000 + (dest_reg << 12) + (dest_reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // orr dest_reg, dest_reg, #((imm2 & 0xff) << scale) + cache_addd( ORR_IMM(dest_reg, dest_reg, imm2 & 0xff, ROTATE_SCALE(scale)) ); // orr dest_reg, dest_reg, #((imm2 & 0xff) << scale) } imm2>>=8; scale+=8; @@ -264,26 +353,26 @@ static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, if (dword) { if ((Bit32u)dest & 3) { if ( ((Bit32u)dest & 3) == 2 ) { - cache_addd(0xe1c000b0 + (src_reg << 12) + (data_reg << 16)); // strh src_reg, [data_reg] - cache_addd(0xe1a00820 + (temp2 << 12) + (src_reg)); // mov temp2, src_reg, lsr #16 - cache_addd(0xe1c000b2 + (temp2 << 12) + (data_reg << 16)); // strh temp2, [data_reg, #2] + cache_addd( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] + cache_addd( MOV_REG_LSR_IMM(temp2, src_reg, 16) ); // mov temp2, src_reg, lsr #16 + cache_addd( STRH_IMM(temp2, data_reg, 2) ); // strh temp2, [data_reg, #2] } else { - cache_addd(0xe5c00000 + (src_reg << 12) + (data_reg << 16)); // strb src_reg, [data_reg] - cache_addd(0xe1a00420 + (temp2 << 12) + (src_reg)); // mov temp2, src_reg, lsr #8 - cache_addd(0xe1c000b1 + (temp2 << 12) + (data_reg << 16)); // strh temp2, [data_reg, #1] - cache_addd(0xe1a00820 + (temp2 << 12) + (temp2)); // mov temp2, temp2, lsr #16 - cache_addd(0xe5c00003 + (temp2 << 12) + (data_reg << 16)); // strb temp2, [data_reg, #3] + cache_addd( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] + cache_addd( MOV_REG_LSR_IMM(temp2, src_reg, 8) ); // mov temp2, src_reg, lsr #8 + cache_addd( STRH_IMM(temp2, data_reg, 1) ); // strh temp2, [data_reg, #1] + cache_addd( MOV_REG_LSR_IMM(temp2, temp2, 16) ); // mov temp2, temp2, lsr #16 + cache_addd( STRB_IMM(temp2, data_reg, 3) ); // strb temp2, [data_reg, #3] } } else { - cache_addd(0xe5800000 + (src_reg << 12) + (data_reg << 16)); // str src_reg, [data_reg] + cache_addd( STR_IMM(src_reg, data_reg, 0) ); // str src_reg, [data_reg] } } else { if ((Bit32u)dest & 1) { - cache_addd(0xe5c00000 + (src_reg << 12) + (data_reg << 16)); // strb src_reg, [data_reg] - cache_addd(0xe1a00420 + (temp2 << 12) + (src_reg)); // mov temp2, src_reg, lsr #8 - cache_addd(0xe5c00001 + (temp2 << 12) + (data_reg << 16)); // strb temp2, [data_reg, #1] + cache_addd( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] + cache_addd( MOV_REG_LSR_IMM(temp2, src_reg, 8) ); // mov temp2, src_reg, lsr #8 + cache_addd( STRB_IMM(temp2, data_reg, 1) ); // strb temp2, [data_reg, #1] } else { - cache_addd(0xe1c000b0 + (src_reg << 12) + (data_reg << 16)); // strh src_reg, [data_reg] + cache_addd( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] } } } @@ -300,7 +389,7 @@ static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { // registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { gen_mov_dword_to_reg_imm(temp1, (Bit32u)data); - cache_addd(0xe5d00000 + (dest_reg << 12) + (temp1 << 16)); // ldrb dest_reg, [temp1] + cache_addd( LDRB_IMM(dest_reg, temp1, 0) ); // ldrb dest_reg, [temp1] } // move an 8bit value from memory into dest_reg @@ -316,7 +405,7 @@ static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* dat // this function does not use FC_OP1/FC_OP2 as dest_reg as these // registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { - cache_addd(0xe3a00000 + (dest_reg << 12) + (imm)); // mov dest_reg, #(imm) + cache_addd( MOV_IMM(dest_reg, imm, 0) ); // mov dest_reg, #(imm) } // move an 8bit constant value into dest_reg @@ -330,7 +419,7 @@ static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u // move the lowest 8bit of a register into memory static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - cache_addd(0xe5c00000 + (src_reg << 12) + (temp1 << 16)); // strb src_reg, [temp1] + cache_addd( STRB_IMM(src_reg, temp1, 0) ); // strb src_reg, [temp1] } @@ -339,10 +428,10 @@ static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { // the register is zero-extended (sign==false) or sign-extended (sign==true) static void gen_extend_byte(bool sign,HostReg reg) { if (sign) { - cache_addd(0xe1a00c00 + (reg << 12) + (reg)); // mov reg, reg, lsl #24 - cache_addd(0xe1a00c40 + (reg << 12) + (reg)); // mov reg, reg, asr #24 + cache_addd( MOV_REG_LSL_IMM(reg, reg, 24) ); // mov reg, reg, lsl #24 + cache_addd( MOV_REG_ASR_IMM(reg, reg, 24) ); // mov reg, reg, asr #24 } else { - cache_addd(0xe20000ff + (reg << 12) + (reg << 16)); // and reg, reg, #0xff + cache_addd( AND_IMM(reg, reg, 0xff, 0) ); // and reg, reg, #0xff } } @@ -350,18 +439,18 @@ static void gen_extend_byte(bool sign,HostReg reg) { // the register is zero-extended (sign==false) or sign-extended (sign==true) static void gen_extend_word(bool sign,HostReg reg) { if (sign) { - cache_addd(0xe1a00800 + (reg << 12) + (reg)); // mov reg, reg, lsl #16 - cache_addd(0xe1a00840 + (reg << 12) + (reg)); // mov reg, reg, asr #16 + cache_addd( MOV_REG_LSL_IMM(reg, reg, 16) ); // mov reg, reg, lsl #16 + cache_addd( MOV_REG_ASR_IMM(reg, reg, 16) ); // mov reg, reg, asr #16 } else { - cache_addd(0xe1a00800 + (reg << 12) + (reg)); // mov reg, reg, lsl #16 - cache_addd(0xe1a00820 + (reg << 12) + (reg)); // mov reg, reg, lsr #16 + cache_addd( MOV_REG_LSL_IMM(reg, reg, 16) ); // mov reg, reg, lsl #16 + cache_addd( MOV_REG_LSR_IMM(reg, reg, 16) ); // mov reg, reg, lsr #16 } } // add a 32bit value from memory to a full register static void gen_add(HostReg reg,void* op) { gen_mov_word_to_reg(temp3, op, 1); - cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp3)); // add reg, reg, temp3 + cache_addd( ADD_REG_LSL_IMM(reg, reg, temp3, 0) ); // add reg, reg, temp3 } // add a 32bit constant value to a full register @@ -369,9 +458,9 @@ static void gen_add_imm(HostReg reg,Bit32u imm) { Bits method1, method2, num1, num2, scale, sub; if(!imm) return; if (imm == 1) { - cache_addd(0xe2800001 + (reg << 12) + (reg << 16)); // add reg, reg, #1 + cache_addd( ADD_IMM(reg, reg, 1, 0) ); // add reg, reg, #1 } else if (imm == 0xffffffff) { - cache_addd(0xe2400001 + (reg << 12) + (reg << 16)); // sub reg, reg, #1 + cache_addd( SUB_IMM(reg, reg, 1, 0) ); // sub reg, reg, #1 } else { method1 = get_method_imm_gen_len(imm, 1, &num1); method2 = get_method_imm_gen_len(-((Bit32s)imm), 1, &num2); @@ -384,9 +473,9 @@ static void gen_add_imm(HostReg reg,Bit32u imm) { if (method1 != 2) { gen_mov_dword_to_reg_imm(temp3, imm); if (sub) { - cache_addd(0xe0400000 + (reg << 12) + (reg << 16) + (temp3)); // sub reg, reg, temp3 + cache_addd( SUB_REG_LSL_IMM(reg, reg, temp3, 0) ); // sub reg, reg, temp3 } else { - cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp3)); // add reg, reg, temp3 + cache_addd( ADD_REG_LSL_IMM(reg, reg, temp3, 0) ); // add reg, reg, temp3 } } else { scale = 0; @@ -396,9 +485,9 @@ static void gen_add_imm(HostReg reg,Bit32u imm) { scale+=2; } if (sub) { - cache_addd(0xe2400000 + (reg << 12) + (reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // sub reg, reg, #((imm & 0xff) << scale) + cache_addd( SUB_IMM(reg, reg, imm & 0xff, ROTATE_SCALE(scale)) ); // sub reg, reg, #((imm & 0xff) << scale) } else { - cache_addd(0xe2800000 + (reg << 12) + (reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // add reg, reg, #((imm & 0xff) << scale) + cache_addd( ADD_IMM(reg, reg, imm & 0xff, ROTATE_SCALE(scale)) ); // add reg, reg, #((imm & 0xff) << scale) } imm>>=8; scale+=8; @@ -414,12 +503,12 @@ static void gen_and_imm(HostReg reg,Bit32u imm) { imm2 = ~imm; if(!imm2) return; if (!imm) { - cache_addd(0xe3a00000 + (reg << 12)); // mov reg, #0 + cache_addd( MOV_IMM(reg, 0, 0) ); // mov reg, #0 } else { method = get_method_imm_gen_len(imm, 0, NULL); if (method != 3) { gen_mov_dword_to_reg_imm(temp3, imm); - cache_addd(0xe0000000 + (reg << 12) + (reg << 16) + (temp3)); // and reg, reg, temp3 + cache_addd( AND_REG_LSL_IMM(reg, reg, temp3, 0) ); // and reg, reg, temp3 } else { scale = 0; while (imm2) { @@ -427,7 +516,7 @@ static void gen_and_imm(HostReg reg,Bit32u imm) { imm2>>=2; scale+=2; } - cache_addd(0xe3c00000 + (reg << 12) + (reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // bic reg, reg, #((imm2 & 0xff) << scale) + cache_addd( BIC_IMM(reg, reg, imm2 & 0xff, ROTATE_SCALE(scale)) ); // bic reg, reg, #((imm2 & 0xff) << scale) imm2>>=8; scale+=8; } @@ -453,9 +542,9 @@ static void gen_add_direct_byte(void* dest,Bit8s imm) { gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); gen_mov_word_to_reg_helper(temp3, dest, 1, temp1); if (imm >= 0) { - cache_addd(0xe2800000 + (temp3 << 12) + (temp3 << 16) + ((Bit32s)imm)); // add temp3, temp3, #(imm) + cache_addd( ADD_IMM(temp3, temp3, (Bit32s)imm, 0) ); // add temp3, temp3, #(imm) } else { - cache_addd(0xe2400000 + (temp3 << 12) + (temp3 << 16) + (-((Bit32s)imm))); // sub temp3, temp3, #(-imm) + cache_addd( SUB_IMM(temp3, temp3, -((Bit32s)imm), 0) ); // sub temp3, temp3, #(-imm) } gen_mov_word_from_reg_helper(temp3, dest, 1, temp1); } @@ -475,7 +564,7 @@ static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { } else { gen_mov_word_to_reg_imm(temp2, (Bit16u)imm); } - cache_addd(0xe0800000 + (temp3 << 12) + (temp3 << 16) + (temp2)); // add temp3, temp3, temp2 + cache_addd( ADD_REG_LSL_IMM(temp3, temp3, temp2, 0) ); // add temp3, temp3, temp2 gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); } @@ -485,9 +574,9 @@ static void gen_sub_direct_byte(void* dest,Bit8s imm) { gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); gen_mov_word_to_reg_helper(temp3, dest, 1, temp1); if (imm >= 0) { - cache_addd(0xe2400000 + (temp3 << 12) + (temp3 << 16) + ((Bit32s)imm)); // sub temp3, temp3, #(imm) + cache_addd( SUB_IMM(temp3, temp3, (Bit32s)imm, 0) ); // sub temp3, temp3, #(imm) } else { - cache_addd(0xe2800000 + (temp3 << 12) + (temp3 << 16) + (-((Bit32s)imm))); // add temp3, temp3, #(-imm) + cache_addd( ADD_IMM(temp3, temp3, -((Bit32s)imm), 0) ); // add temp3, temp3, #(-imm) } gen_mov_word_from_reg_helper(temp3, dest, 1, temp1); } @@ -507,7 +596,7 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { } else { gen_mov_word_to_reg_imm(temp2, (Bit16u)imm); } - cache_addd(0xe0400000 + (temp3 << 12) + (temp3 << 16) + (temp2)); // sub temp3, temp3, temp2 + cache_addd( SUB_REG_LSL_IMM(temp3, temp3, temp2, 0) ); // sub temp3, temp3, temp2 gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); } @@ -515,7 +604,7 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { // scale_reg is scaled by scale (scale_reg*(2^scale)) and // added to dest_reg, then the immediate value is added static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { - cache_addd(0xe0800000 + (dest_reg << 12) + (dest_reg << 16) + (scale_reg) + (scale << 7)); // add dest_reg, dest_reg, scale_reg, lsl #(scale) + cache_addd( ADD_REG_LSL_IMM(dest_reg, dest_reg, scale_reg, scale) ); // add dest_reg, dest_reg, scale_reg, lsl #(scale) gen_add_imm(dest_reg, imm); } @@ -524,18 +613,18 @@ static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits im // then the immediate value is added static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { if (scale) { - cache_addd(0xe1a00000 + (dest_reg << 12) + (dest_reg) + (scale << 7)); // mov dest_reg, dest_reg, lsl #(scale) + cache_addd( MOV_REG_LSL_IMM(dest_reg, dest_reg, scale) ); // mov dest_reg, dest_reg, lsl #(scale) } gen_add_imm(dest_reg, imm); } // generate a call to a parameterless function static void INLINE gen_call_function_raw(void * func) { - cache_addd(0xe5900004 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #4] - cache_addd(0xe2800004 + (HOST_lr << 12) + (HOST_pc << 16)); // add lr, pc, #4 - cache_addd(0xe12fff10 + (temp1)); // bx temp1 + cache_addd( LDR_IMM(temp1, HOST_pc, 4) ); // ldr temp1, [pc, #4] + cache_addd( ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 + cache_addd( BX(temp1) ); // bx temp1 cache_addd((Bit32u)func); // .int func - cache_addd(0xe1a00000 + (FC_RETOP << 12) + HOST_a1); // mov FC_RETOP, a1 + cache_addd( MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 0) ); // mov FC_RETOP, a1 } // generate a call to a function with paramcount parameters @@ -596,9 +685,9 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { scale+=2; } if (sub) { - cache_addd(0xe2400000 + (temp3 << 12) + (temp3 << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // sub temp3, temp3, #((imm2 & 0xff) << scale) + cache_addd( SUB_IMM(temp3, temp3, imm2 & 0xff, ROTATE_SCALE(scale)) ); // sub temp3, temp3, #((imm2 & 0xff) << scale) } else { - cache_addd(0xe2800000 + (temp3 << 12) + (temp3 << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // add temp3, temp3, #((imm2 & 0xff) << scale) + cache_addd( ADD_IMM(temp3, temp3, imm2 & 0xff, ROTATE_SCALE(scale)) ); // add temp3, temp3, #((imm2 & 0xff) << scale) } imm2>>=8; scale+=8; @@ -608,31 +697,31 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { #if (1) // (*ptr) should be word aligned if ((imm & 0x03) == 0) { - cache_addd(0xe5900000 + (temp1 << 12) + (temp3 << 16)); // ldr temp1, [temp3] + cache_addd( LDR_IMM(temp1, temp3, 0) ); // ldr temp1, [temp3] } else #endif { - cache_addd(0xe5d00000 + (temp1 << 12) + (temp3 << 16)); // ldrb temp1, [temp3] - cache_addd(0xe5d00001 + (temp2 << 12) + (temp3 << 16)); // ldrb temp2, [temp3, #1] - cache_addd(0xe1800400 + (temp1 << 12) + (temp1 << 16) + (temp2)); // orr temp1, temp1, temp2, lsl #8 - cache_addd(0xe5d00002 + (temp2 << 12) + (temp3 << 16)); // ldrb temp2, [temp3, #2] - cache_addd(0xe1800800 + (temp1 << 12) + (temp1 << 16) + (temp2)); // orr temp1, temp1, temp2, lsl #16 - cache_addd(0xe5d00003 + (temp2 << 12) + (temp3 << 16)); // ldrb temp2, [temp3, #3] - cache_addd(0xe1800c00 + (temp1 << 12) + (temp1 << 16) + (temp2)); // orr temp1, temp1, temp2, lsl #24 + cache_addd( LDRB_IMM(temp1, temp3, 0) ); // ldrb temp1, [temp3] + cache_addd( LDRB_IMM(temp2, temp3, 1) ); // ldrb temp2, [temp3, #1] + cache_addd( ORR_REG_LSL_IMM(temp1, temp1, temp2, 8) ); // orr temp1, temp1, temp2, lsl #8 + cache_addd( LDRB_IMM(temp2, temp3, 2) ); // ldrb temp2, [temp3, #2] + cache_addd( ORR_REG_LSL_IMM(temp1, temp1, temp2, 16) ); // orr temp1, temp1, temp2, lsl #16 + cache_addd( LDRB_IMM(temp2, temp3, 3) ); // ldrb temp2, [temp3, #3] + cache_addd( ORR_REG_LSL_IMM(temp1, temp1, temp2, 24) ); // orr temp1, temp1, temp2, lsl #24 } - cache_addd(0xe12fff10 + (temp1)); // bx temp1 + cache_addd( BX(temp1) ); // bx temp1 } // short conditional jump (+-127 bytes) if register is zero // the destination is set by gen_fill_branch() later static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { if (dword) { - cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 + cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 } else { - cache_addd(0xe1b00800 + (temp1 << 12) + (reg)); // movs temp1, reg, lsl #16 + cache_addd( MOVS_REG_LSL_IMM(temp1, reg, 16) ); // movs temp1, reg, lsl #16 } - cache_addd(0x0a000000); // beq j + cache_addd( BEQ_FWD(0) ); // beq j return ((Bit32u)cache.pos-4); } @@ -640,11 +729,11 @@ static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { // the destination is set by gen_fill_branch() later static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { if (dword) { - cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 + cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 } else { - cache_addd(0xe1b00800 + (temp1 << 12) + (reg)); // movs temp1, reg, lsl #16 + cache_addd( MOVS_REG_LSL_IMM(temp1, reg, 16) ); // movs temp1, reg, lsl #16 } - cache_addd(0x1a000000); // bne j + cache_addd( BNE_FWD(0) ); // bne j return ((Bit32u)cache.pos-4); } @@ -663,13 +752,13 @@ static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) { // for isdword==false the lowest 8bit of the register are tested static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { if (isdword) { - cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 + cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 } else { - cache_addd(0xe31000ff + (reg << 16)); // tst reg, #0xff + cache_addd( TST_IMM(reg, 0xff, 0) ); // tst reg, #0xff } - cache_addd(0x0a000002); // beq nobranch - cache_addd(0xe5900000 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #0] - cache_addd(0xe12fff10 + (temp1)); // bx temp1 + cache_addd( BEQ_FWD(8) ); // beq nobranch (pc +8) + cache_addd( LDR_IMM(temp1, HOST_pc, 0) ); // ldr temp1, [pc, #0] + cache_addd( BX(temp1) ); // bx temp1 cache_addd(0); // fill j // nobranch: return ((Bit32u)cache.pos-4); @@ -677,10 +766,10 @@ static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { // compare 32bit-register against zero and jump if value less/equal than zero static Bit32u gen_create_branch_long_leqzero(HostReg reg) { - cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 - cache_addd(0xca000002); // bgt nobranch - cache_addd(0xe5900000 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #0] - cache_addd(0xe12fff10 + (temp1)); // bx temp1 + cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 + cache_addd( BGT_FWD(8) ); // bgt nobranch (pc+8) + cache_addd( LDR_IMM(temp1, HOST_pc, 0) ); // ldr temp1, [pc, #0] + cache_addd( BX(temp1) ); // bx temp1 cache_addd(0); // fill j // nobranch: return ((Bit32u)cache.pos-4); @@ -697,23 +786,26 @@ static void gen_run_code(void) { cache_addd(0xe92d0df0); // stmfd sp!, {v1-v5,v7,v8} // adr: 8 - cache_addd(0xe5900000 + (FC_SEGS_ADDR << 12) + (HOST_pc << 16) + (64 - (8 + 8))); // ldr FC_SEGS_ADDR, [pc, #(&Segs)] + cache_addd( LDR_IMM(FC_SEGS_ADDR, HOST_pc, 64 - (8 + 8)) ); // ldr FC_SEGS_ADDR, [pc, #(&Segs)] // adr: 12 - cache_addd(0xe5900000 + (FC_REGS_ADDR << 12) + (HOST_pc << 16) + (68 - (12 + 8))); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)] - cache_addd(0xe28fe004); // add lr, pc, #4 + cache_addd( LDR_IMM(FC_REGS_ADDR, HOST_pc, 68 - (12 + 8)) ); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)] + + cache_addd( ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 cache_addd(0xe92d4000); // stmfd sp!, {lr} - cache_addd(0xe12fff10); // bx r0 + cache_addd( BX(HOST_r0) ); // bx r0 + cache_addd(0xe8bd0df0); // ldmfd sp!, {v1-v5,v7,v8} cache_addd(0xe8bd4000); // ldmfd sp!, {lr} - cache_addd(0xe12fff1e); // bx lr + cache_addd( BX(HOST_lr) ); // bx lr + // fill up to 64 bytes - cache_addd(0xe1a00000); // nop - cache_addd(0xe1a00000); // nop - cache_addd(0xe1a00000); // nop - cache_addd(0xe1a00000); // nop - cache_addd(0xe1a00000); // nop - cache_addd(0xe1a00000); // nop + cache_addd( NOP ); // nop + cache_addd( NOP ); // nop + cache_addd( NOP ); // nop + cache_addd( NOP ); // nop + cache_addd( NOP ); // nop + cache_addd( NOP ); // nop // adr: 64 cache_addd((Bit32u)&Segs); // address of "Segs" @@ -723,9 +815,9 @@ static void gen_run_code(void) { // return from a function static void gen_return_function(void) { - cache_addd(0xe1a00000 + (HOST_a1 << 12) + FC_RETOP); // mov a1, FC_RETOP + cache_addd( MOV_REG_LSL_IMM(HOST_a1, FC_RETOP, 0) ); // mov a1, FC_RETOP cache_addd(0xe8bd4000); // ldmfd sp!, {lr} - cache_addd(0xe12fff1e); // bx lr + cache_addd( BX(HOST_lr) ); // bx lr } #ifdef DRC_FLAGS_INVALIDATION @@ -739,32 +831,32 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: - *(Bit32u*)pos=0xe0800000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // add FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=ADD_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // add FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_ORb: case t_ORw: case t_ORd: - *(Bit32u*)pos=0xe1800000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // orr FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=ORR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // orr FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_ANDb: case t_ANDw: case t_ANDd: - *(Bit32u*)pos=0xe0000000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // and FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=AND_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // and FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_SUBb: case t_SUBw: case t_SUBd: - *(Bit32u*)pos=0xe0400000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // sub FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=SUB_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // sub FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_XORb: case t_XORw: case t_XORd: - *(Bit32u*)pos=0xe0200000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // eor FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=EOR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // eor FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_CMPb: case t_CMPw: @@ -772,106 +864,106 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit32u*)pos=0xea000000 + (3); // b (pc+3*4) + *(Bit32u*)pos=B_FWD(12); // b (pc+3*4) break; case t_INCb: case t_INCw: case t_INCd: - *(Bit32u*)pos=0xe2800000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (1); // add FC_RETOP, a1, #1 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=ADD_IMM(FC_RETOP, HOST_a1, 1, 0); // add FC_RETOP, a1, #1 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_DECb: case t_DECw: case t_DECd: - *(Bit32u*)pos=0xe2400000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (1); // sub FC_RETOP, a1, #1 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=SUB_IMM(FC_RETOP, HOST_a1, 1, 0); // sub FC_RETOP, a1, #1 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_SHLb: case t_SHLw: case t_SHLd: - *(Bit32u*)pos=0xe1a00010 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, lsl a2 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=MOV_REG_LSL_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsl a2 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_SHRb: - *(Bit32u*)pos=0xe2000000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (0xff); // and FC_RETOP, a1, #0xff - *(Bit32u*)(pos+4)=0xe1a00030 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, lsr a2 - *(Bit32u*)(pos+8)=0xe1a00000; // nop - *(Bit32u*)(pos+12)=0xe1a00000; // nop - *(Bit32u*)(pos+16)=0xe1a00000; // nop + *(Bit32u*)pos=AND_IMM(FC_RETOP, HOST_a1, 0xff, 0); // and FC_RETOP, a1, #0xff + *(Bit32u*)(pos+4)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2 + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop break; case t_SHRw: - *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=0xe1a00020 + (FC_RETOP << 12) + (FC_RETOP) + (16 << 7); // mov FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+8)=0xe1a00030 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, lsr a2 - *(Bit32u*)(pos+12)=0xe1a00000; // nop - *(Bit32u*)(pos+16)=0xe1a00000; // nop + *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+4)=MOV_REG_LSR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+8)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop break; case t_SHRd: - *(Bit32u*)pos=0xe1a00030 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, lsr a2 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=MOV_REG_LSR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsr a2 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_SARb: - *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (24 << 7); // mov FC_RETOP, a1, lsl #24 - *(Bit32u*)(pos+4)=0xe1a00040 + (FC_RETOP << 12) + (FC_RETOP) + (24 << 7); // mov FC_RETOP, FC_RETOP, asr #24 - *(Bit32u*)(pos+8)=0xe1a00050 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, asr a2 - *(Bit32u*)(pos+12)=0xe1a00000; // nop - *(Bit32u*)(pos+16)=0xe1a00000; // nop + *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 + *(Bit32u*)(pos+4)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 24); // mov FC_RETOP, FC_RETOP, asr #24 + *(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop break; case t_SARw: - *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=0xe1a00040 + (FC_RETOP << 12) + (FC_RETOP) + (16 << 7); // mov FC_RETOP, FC_RETOP, asr #16 - *(Bit32u*)(pos+8)=0xe1a00050 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, asr a2 - *(Bit32u*)(pos+12)=0xe1a00000; // nop - *(Bit32u*)(pos+16)=0xe1a00000; // nop + *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+4)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, asr #16 + *(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop break; case t_SARd: - *(Bit32u*)pos=0xe1a00050 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, asr a2 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=MOV_REG_ASR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, asr a2 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_RORb: - *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (24 << 7); // mov FC_RETOP, a1, lsl #24 - *(Bit32u*)(pos+4)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (8 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 - *(Bit32u*)(pos+8)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+12)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2 - *(Bit32u*)(pos+16)=0xe1a00000; // nop + *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 + *(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 8); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 + *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 + *(Bit32u*)(pos+16)=NOP; // nop break; case t_RORw: - *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+8)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2 - *(Bit32u*)(pos+12)=0xe1a00000; // nop - *(Bit32u*)(pos+16)=0xe1a00000; // nop + *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop break; case t_RORd: - *(Bit32u*)pos=0xe1a00070 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, ror a2 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_ROLb: - *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (24 << 7); // mov FC_RETOP, a1, lsl #24 - *(Bit32u*)(pos+4)=0xe2600000 + (HOST_a2 << 12) + (HOST_a2 << 16) + (32); // rsb a2, a2, #32 - *(Bit32u*)(pos+8)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (8 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 - *(Bit32u*)(pos+12)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+16)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2 + *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 + *(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 + *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 8); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 + *(Bit32u*)(pos+12)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+16)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 break; case t_ROLw: - *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=0xe2600000 + (HOST_a2 << 12) + (HOST_a2 << 16) + (32); // rsb a2, a2, #32 - *(Bit32u*)(pos+8)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+12)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2 - *(Bit32u*)(pos+16)=0xe1a00000; // nop + *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 + *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 + *(Bit32u*)(pos+16)=NOP; // nop break; case t_ROLd: - *(Bit32u*)pos=0xe2600000 + (HOST_a2 << 12) + (HOST_a2 << 16) + (32); // rsb a2, a2, #32 - *(Bit32u*)(pos+4)=0xe1a00070 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, ror a2 - *(Bit32u*)(pos+8)=0xe1a00000; // nop - *(Bit32u*)(pos+12)=0xe1a00000; // nop - *(Bit32u*)(pos+16)=0xe1a00000; // nop + *(Bit32u*)pos=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 + *(Bit32u*)(pos+4)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop break; case t_NEGb: case t_NEGw: case t_NEGd: - *(Bit32u*)pos=0xe2600000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (0); // rsb FC_RETOP, a1, #0 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=RSB_IMM(FC_RETOP, HOST_a1, 0, 0); // rsb FC_RETOP, a1, #0 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; default: *(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func @@ -886,24 +978,23 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { static void cache_block_before_close(void) { } - #ifdef DRC_USE_SEGS_ADDR // mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { - cache_addd(0xe1d000b0 + (dest_reg << 12) + (FC_SEGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // ldrh dest_reg, [FC_SEGS_ADDR, #index] + cache_addd( LDRH_IMM(dest_reg, FC_SEGS_ADDR, index) ); // ldrh dest_reg, [FC_SEGS_ADDR, #index] } // mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { - cache_addd(0xe5900000 + (dest_reg << 12) + (FC_SEGS_ADDR << 16) + (index)); // ldr dest_reg, [FC_SEGS_ADDR, #index] + cache_addd( LDR_IMM(dest_reg, FC_SEGS_ADDR, index) ); // ldr dest_reg, [FC_SEGS_ADDR, #index] } // add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { - cache_addd(0xe5900000 + (temp1 << 12) + (FC_SEGS_ADDR << 16) + (index)); // ldr temp1, [FC_SEGS_ADDR, #index] - cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp1)); // add reg, reg, temp1 + cache_addd( LDR_IMM(temp1, FC_SEGS_ADDR, index) ); // ldr temp1, [FC_SEGS_ADDR, #index] + cache_addd( ADD_REG_LSL_IMM(reg, reg, temp1, 0) ); // add reg, reg, temp1 } #endif @@ -913,21 +1004,21 @@ static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { // mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { - cache_addd(0xe1d000b0 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // ldrh dest_reg, [FC_REGS_ADDR, #index] + cache_addd( LDRH_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrh dest_reg, [FC_REGS_ADDR, #index] } // mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { - cache_addd(0xe5900000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldr dest_reg, [FC_REGS_ADDR, #index] + cache_addd( LDR_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldr dest_reg, [FC_REGS_ADDR, #index] } // move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { if (dword) { - cache_addd(0xe5900000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldr dest_reg, [FC_REGS_ADDR, #index] + cache_addd( LDR_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldr dest_reg, [FC_REGS_ADDR, #index] } else { - cache_addd(0xe1d000b0 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // ldrh dest_reg, [FC_REGS_ADDR, #index] + cache_addd( LDRH_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrh dest_reg, [FC_REGS_ADDR, #index] } } @@ -936,7 +1027,7 @@ static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { // this function does not use FC_OP1/FC_OP2 as dest_reg as these // registers might not be directly byte-accessible on some architectures static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { - cache_addd(0xe5d00000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldrb dest_reg, [FC_REGS_ADDR, #index] + cache_addd( LDRB_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrb dest_reg, [FC_REGS_ADDR, #index] } // move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR @@ -944,39 +1035,39 @@ static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { // this function can use FC_OP1/FC_OP2 as dest_reg which are // not directly byte-accessible on some architectures static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { - cache_addd(0xe5d00000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldrb dest_reg, [FC_REGS_ADDR, #index] + cache_addd( LDRB_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrb dest_reg, [FC_REGS_ADDR, #index] } // add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { - cache_addd(0xe5900000 + (temp2 << 12) + (FC_REGS_ADDR << 16) + (index)); // ldr temp2, [FC_REGS_ADDR, #index] - cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp2)); // add reg, reg, temp2 + cache_addd( LDR_IMM(temp2, FC_REGS_ADDR, index) ); // ldr temp2, [FC_REGS_ADDR, #index] + cache_addd( ADD_REG_LSL_IMM(reg, reg, temp2, 0) ); // add reg, reg, temp2 } // move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { - cache_addd(0xe1c000b0 + (src_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // strh src_reg, [FC_REGS_ADDR, #index] + cache_addd( STRH_IMM(src_reg, FC_REGS_ADDR, index) ); // strh src_reg, [FC_REGS_ADDR, #index] } // move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { - cache_addd(0xe5800000 + (src_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // str src_reg, [FC_REGS_ADDR, #index] + cache_addd( STR_IMM(src_reg, FC_REGS_ADDR, index) ); // str src_reg, [FC_REGS_ADDR, #index] } // move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { if (dword) { - cache_addd(0xe5800000 + (src_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // str src_reg, [FC_REGS_ADDR, #index] + cache_addd( STR_IMM(src_reg, FC_REGS_ADDR, index) ); // str src_reg, [FC_REGS_ADDR, #index] } else { - cache_addd(0xe1c000b0 + (src_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // strh src_reg, [FC_REGS_ADDR, #index] + cache_addd( STRH_IMM(src_reg, FC_REGS_ADDR, index) ); // strh src_reg, [FC_REGS_ADDR, #index] } } // move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { - cache_addd(0xe5c00000 + (src_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // strb src_reg, [FC_REGS_ADDR, #index] + cache_addd( STRB_IMM(src_reg, FC_REGS_ADDR, index) ); // strb src_reg, [FC_REGS_ADDR, #index] } #endif diff --git a/src/cpu/core_dynrec/risc_armv4le-s3.h b/src/cpu/core_dynrec/risc_armv4le-s3.h index f824c2d1..c2b7d582 100644 --- a/src/cpu/core_dynrec/risc_armv4le-s3.h +++ b/src/cpu/core_dynrec/risc_armv4le-s3.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-s3.h,v 1.3 2008-09-19 16:48:02 c2woody Exp $ */ +/* $Id: risc_armv4le-s3.h,v 1.4 2009-05-16 21:52:47 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (speed-tweaked arm version) */ @@ -58,20 +58,109 @@ #define FC_SEGS_ADDR HOST_v8 #endif + // helper macro #define ROTATE_SCALE(x) ( (x)?(32 - x):(0) ) + +// instruction encodings + +// move +// mov dst, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define MOV_IMM(dst, imm, rimm) (0xe3a00000 + ((dst) << 12) + (imm) + ((rimm) << 7) ) +// mov dst, src, lsl #imm +#define MOV_REG_LSL_IMM(dst, src, imm) (0xe1a00000 + ((dst) << 12) + (src) + ((imm) << 7) ) +// movs dst, src, lsl #imm +#define MOVS_REG_LSL_IMM(dst, src, imm) (0xe1b00000 + ((dst) << 12) + (src) + ((imm) << 7) ) +// mov dst, src, lsr #imm +#define MOV_REG_LSR_IMM(dst, src, imm) (0xe1a00020 + ((dst) << 12) + (src) + ((imm) << 7) ) +// mov dst, src, asr #imm +#define MOV_REG_ASR_IMM(dst, src, imm) (0xe1a00040 + ((dst) << 12) + (src) + ((imm) << 7) ) +// mov dst, src, lsl rreg +#define MOV_REG_LSL_REG(dst, src, rreg) (0xe1a00010 + ((dst) << 12) + (src) + ((rreg) << 8) ) +// mov dst, src, lsr rreg +#define MOV_REG_LSR_REG(dst, src, rreg) (0xe1a00030 + ((dst) << 12) + (src) + ((rreg) << 8) ) +// mov dst, src, asr rreg +#define MOV_REG_ASR_REG(dst, src, rreg) (0xe1a00050 + ((dst) << 12) + (src) + ((rreg) << 8) ) +// mov dst, src, ror rreg +#define MOV_REG_ROR_REG(dst, src, rreg) (0xe1a00070 + ((dst) << 12) + (src) + ((rreg) << 8) ) +// mvn dst, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define MVN_IMM(dst, imm, rimm) (0xe3e00000 + ((dst) << 12) + (imm) + ((rimm) << 7) ) + +// arithmetic +// add dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define ADD_IMM(dst, src, imm, rimm) (0xe2800000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) +// add dst, src1, src2, lsl #imm +#define ADD_REG_LSL_IMM(dst, src1, src2, imm) (0xe0800000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) +// sub dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define SUB_IMM(dst, src, imm, rimm) (0xe2400000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) +// sub dst, src1, src2, lsl #imm +#define SUB_REG_LSL_IMM(dst, src1, src2, imm) (0xe0400000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) +// rsb dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define RSB_IMM(dst, src, imm, rimm) (0xe2600000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) +// cmp src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define CMP_IMM(src, imm, rimm) (0xe3500000 + ((src) << 16) + (imm) + ((rimm) << 7) ) +// nop +#define NOP MOV_REG_LSL_IMM(HOST_r0, HOST_r0, 0) + +// logical +// tst src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define TST_IMM(src, imm, rimm) (0xe3100000 + ((src) << 16) + (imm) + ((rimm) << 7) ) +// and dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define AND_IMM(dst, src, imm, rimm) (0xe2000000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) +// and dst, src1, src2, lsl #imm +#define AND_REG_LSL_IMM(dst, src1, src2, imm) (0xe0000000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) +// orr dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define ORR_IMM(dst, src, imm, rimm) (0xe3800000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) +// orr dst, src1, src2, lsl #imm +#define ORR_REG_LSL_IMM(dst, src1, src2, imm) (0xe1800000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) +// orr dst, src1, src2, lsr #imm +#define ORR_REG_LSR_IMM(dst, src1, src2, imm) (0xe1800020 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) +// eor dst, src1, src2, lsl #imm +#define EOR_REG_LSL_IMM(dst, src1, src2, imm) (0xe0200000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) +// bic dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define BIC_IMM(dst, src, imm, rimm) (0xe3c00000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) + +// load +// ldr reg, [addr, #imm] @ 0 <= imm < 4096 +#define LDR_IMM(reg, addr, imm) (0xe5900000 + ((reg) << 12) + ((addr) << 16) + (imm) ) +// ldrh reg, [addr, #imm] @ 0 <= imm < 256 +#define LDRH_IMM(reg, addr, imm) (0xe1d000b0 + ((reg) << 12) + ((addr) << 16) + (((imm) & 0xf0) << 4) + ((imm) & 0x0f) ) +// ldrb reg, [addr, #imm] @ 0 <= imm < 4096 +#define LDRB_IMM(reg, addr, imm) (0xe5d00000 + ((reg) << 12) + ((addr) << 16) + (imm) ) + +// store +// str reg, [addr, #imm] @ 0 <= imm < 4096 +#define STR_IMM(reg, addr, imm) (0xe5800000 + ((reg) << 12) + ((addr) << 16) + (imm) ) +// strh reg, [addr, #imm] @ 0 <= imm < 256 +#define STRH_IMM(reg, addr, imm) (0xe1c000b0 + ((reg) << 12) + ((addr) << 16) + (((imm) & 0xf0) << 4) + ((imm) & 0x0f) ) +// strb reg, [addr, #imm] @ 0 <= imm < 4096 +#define STRB_IMM(reg, addr, imm) (0xe5c00000 + ((reg) << 12) + ((addr) << 16) + (imm) ) + +// branch +// beq pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 +#define BEQ_FWD(imm) (0x0a000000 + ((imm) >> 2) ) +// bne pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 +#define BNE_FWD(imm) (0x1a000000 + ((imm) >> 2) ) +// bgt pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 +#define BGT_FWD(imm) (0xca000000 + ((imm) >> 2) ) +// b pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 +#define B_FWD(imm) (0xea000000 + ((imm) >> 2) ) +// bx reg +#define BX(reg) (0xe12fff10 + (reg) ) + + // move a full register from reg_src to reg_dst static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { if(reg_src == reg_dst) return; - cache_addd(0xe1a00000 + (reg_dst << 12) + reg_src); // mov reg_dst, reg_src + cache_addd( MOV_REG_LSL_IMM(reg_dst, reg_src, 0) ); // mov reg_dst, reg_src } // move a 32bit constant value into dest_reg static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { Bits first, scale; if (imm == 0) { - cache_addd(0xe3a00000 + (dest_reg << 12)); // mov dest_reg, #0 + cache_addd( MOV_IMM(dest_reg, 0, 0) ); // mov dest_reg, #0 } else { scale = 0; first = 1; @@ -81,10 +170,10 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { scale+=2; } if (first) { - cache_addd(0xe3a00000 + (dest_reg << 12) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // mov dest_reg, #((imm & 0xff) << scale) + cache_addd( MOV_IMM(dest_reg, imm & 0xff, ROTATE_SCALE(scale)) ); // mov dest_reg, #((imm & 0xff) << scale) first = 0; } else { - cache_addd(0xe3800000 + (dest_reg << 12) + (dest_reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // orr dest_reg, dest_reg, #((imm & 0xff) << scale) + cache_addd( ORR_IMM(dest_reg, dest_reg, imm & 0xff, ROTATE_SCALE(scale)) ); // orr dest_reg, dest_reg, #((imm & 0xff) << scale) } imm>>=8; scale+=8; @@ -98,26 +187,26 @@ static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,Ho if (dword) { if ((Bit32u)data & 3) { if ( ((Bit32u)data & 3) == 2 ) { - cache_addd(0xe1d000b0 + (dest_reg << 12) + (data_reg << 16)); // ldrh dest_reg, [data_reg] - cache_addd(0xe1d000b2 + (temp2 << 12) + (data_reg << 16)); // ldrh temp2, [data_reg, #2] - cache_addd(0xe1800800 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #16 + cache_addd( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] + cache_addd( LDRH_IMM(temp2, data_reg, 2) ); // ldrh temp2, [data_reg, #2] + cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 16) ); // orr dest_reg, dest_reg, temp2, lsl #16 } else { - cache_addd(0xe5d00000 + (dest_reg << 12) + (data_reg << 16)); // ldrb dest_reg, [data_reg] - cache_addd(0xe1d000b1 + (temp2 << 12) + (data_reg << 16)); // ldrh temp2, [data_reg, #1] - cache_addd(0xe1800400 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #8 - cache_addd(0xe5d00003 + (temp2 << 12) + (data_reg << 16)); // ldrb temp2, [data_reg, #3] - cache_addd(0xe1800c00 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #24 + cache_addd( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] + cache_addd( LDRH_IMM(temp2, data_reg, 1) ); // ldrh temp2, [data_reg, #1] + cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 8) ); // orr dest_reg, dest_reg, temp2, lsl #8 + cache_addd( LDRB_IMM(temp2, data_reg, 3) ); // ldrb temp2, [data_reg, #3] + cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 24) ); // orr dest_reg, dest_reg, temp2, lsl #24 } } else { - cache_addd(0xe5900000 + (dest_reg << 12) + (data_reg << 16)); // ldr dest_reg, [data_reg] + cache_addd( LDR_IMM(dest_reg, data_reg, 0) ); // ldr dest_reg, [data_reg] } } else { if ((Bit32u)data & 1) { - cache_addd(0xe5d00000 + (dest_reg << 12) + (data_reg << 16)); // ldrb dest_reg, [data_reg] - cache_addd(0xe5d00001 + (temp2 << 12) + (data_reg << 16)); // ldrb temp2, [data_reg, #1] - cache_addd(0xe1800400 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #8 + cache_addd( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] + cache_addd( LDRB_IMM(temp2, data_reg, 1) ); // ldrb temp2, [data_reg, #1] + cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 8) ); // orr dest_reg, dest_reg, temp2, lsl #8 } else { - cache_addd(0xe1d000b0 + (dest_reg << 12) + (data_reg << 16)); // ldrh dest_reg, [data_reg] + cache_addd( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] } } } @@ -141,26 +230,26 @@ static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, if (dword) { if ((Bit32u)dest & 3) { if ( ((Bit32u)dest & 3) == 2 ) { - cache_addd(0xe1c000b0 + (src_reg << 12) + (data_reg << 16)); // strh src_reg, [data_reg] - cache_addd(0xe1a00820 + (temp2 << 12) + (src_reg)); // mov temp2, src_reg, lsr #16 - cache_addd(0xe1c000b2 + (temp2 << 12) + (data_reg << 16)); // strh temp2, [data_reg, #2] + cache_addd( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] + cache_addd( MOV_REG_LSR_IMM(temp2, src_reg, 16) ); // mov temp2, src_reg, lsr #16 + cache_addd( STRH_IMM(temp2, data_reg, 2) ); // strh temp2, [data_reg, #2] } else { - cache_addd(0xe5c00000 + (src_reg << 12) + (data_reg << 16)); // strb src_reg, [data_reg] - cache_addd(0xe1a00420 + (temp2 << 12) + (src_reg)); // mov temp2, src_reg, lsr #8 - cache_addd(0xe1c000b1 + (temp2 << 12) + (data_reg << 16)); // strh temp2, [data_reg, #1] - cache_addd(0xe1a00820 + (temp2 << 12) + (temp2)); // mov temp2, temp2, lsr #16 - cache_addd(0xe5c00003 + (temp2 << 12) + (data_reg << 16)); // strb temp2, [data_reg, #3] + cache_addd( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] + cache_addd( MOV_REG_LSR_IMM(temp2, src_reg, 8) ); // mov temp2, src_reg, lsr #8 + cache_addd( STRH_IMM(temp2, data_reg, 1) ); // strh temp2, [data_reg, #1] + cache_addd( MOV_REG_LSR_IMM(temp2, temp2, 16) ); // mov temp2, temp2, lsr #16 + cache_addd( STRB_IMM(temp2, data_reg, 3) ); // strb temp2, [data_reg, #3] } } else { - cache_addd(0xe5800000 + (src_reg << 12) + (data_reg << 16)); // str src_reg, [data_reg] + cache_addd( STR_IMM(src_reg, data_reg, 0) ); // str src_reg, [data_reg] } } else { if ((Bit32u)dest & 1) { - cache_addd(0xe5c00000 + (src_reg << 12) + (data_reg << 16)); // strb src_reg, [data_reg] - cache_addd(0xe1a00420 + (temp2 << 12) + (src_reg)); // mov temp2, src_reg, lsr #8 - cache_addd(0xe5c00001 + (temp2 << 12) + (data_reg << 16)); // strb temp2, [data_reg, #1] + cache_addd( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] + cache_addd( MOV_REG_LSR_IMM(temp2, src_reg, 8) ); // mov temp2, src_reg, lsr #8 + cache_addd( STRB_IMM(temp2, data_reg, 1) ); // strb temp2, [data_reg, #1] } else { - cache_addd(0xe1c000b0 + (src_reg << 12) + (data_reg << 16)); // strh src_reg, [data_reg] + cache_addd( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] } } } @@ -177,7 +266,7 @@ static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { // registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { gen_mov_dword_to_reg_imm(temp1, (Bit32u)data); - cache_addd(0xe5d00000 + (dest_reg << 12) + (temp1 << 16)); // ldrb dest_reg, [temp1] + cache_addd( LDRB_IMM(dest_reg, temp1, 0) ); // ldrb dest_reg, [temp1] } // move an 8bit value from memory into dest_reg @@ -193,7 +282,7 @@ static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* dat // this function does not use FC_OP1/FC_OP2 as dest_reg as these // registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { - cache_addd(0xe3a00000 + (dest_reg << 12) + (imm)); // mov dest_reg, #(imm) + cache_addd( MOV_IMM(dest_reg, imm, 0) ); // mov dest_reg, #(imm) } // move an 8bit constant value into dest_reg @@ -207,7 +296,7 @@ static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u // move the lowest 8bit of a register into memory static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - cache_addd(0xe5c00000 + (src_reg << 12) + (temp1 << 16)); // strb src_reg, [temp1] + cache_addd( STRB_IMM(src_reg, temp1, 0) ); // strb src_reg, [temp1] } @@ -216,10 +305,10 @@ static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { // the register is zero-extended (sign==false) or sign-extended (sign==true) static void gen_extend_byte(bool sign,HostReg reg) { if (sign) { - cache_addd(0xe1a00c00 + (reg << 12) + (reg)); // mov reg, reg, lsl #24 - cache_addd(0xe1a00c40 + (reg << 12) + (reg)); // mov reg, reg, asr #24 + cache_addd( MOV_REG_LSL_IMM(reg, reg, 24) ); // mov reg, reg, lsl #24 + cache_addd( MOV_REG_ASR_IMM(reg, reg, 24) ); // mov reg, reg, asr #24 } else { - cache_addd(0xe20000ff + (reg << 12) + (reg << 16)); // and reg, reg, #0xff + cache_addd( AND_IMM(reg, reg, 0xff, 0) ); // and reg, reg, #0xff } } @@ -227,18 +316,18 @@ static void gen_extend_byte(bool sign,HostReg reg) { // the register is zero-extended (sign==false) or sign-extended (sign==true) static void gen_extend_word(bool sign,HostReg reg) { if (sign) { - cache_addd(0xe1a00800 + (reg << 12) + (reg)); // mov reg, reg, lsl #16 - cache_addd(0xe1a00840 + (reg << 12) + (reg)); // mov reg, reg, asr #16 + cache_addd( MOV_REG_LSL_IMM(reg, reg, 16) ); // mov reg, reg, lsl #16 + cache_addd( MOV_REG_ASR_IMM(reg, reg, 16) ); // mov reg, reg, asr #16 } else { - cache_addd(0xe1a00800 + (reg << 12) + (reg)); // mov reg, reg, lsl #16 - cache_addd(0xe1a00820 + (reg << 12) + (reg)); // mov reg, reg, lsr #16 + cache_addd( MOV_REG_LSL_IMM(reg, reg, 16) ); // mov reg, reg, lsl #16 + cache_addd( MOV_REG_LSR_IMM(reg, reg, 16) ); // mov reg, reg, lsr #16 } } // add a 32bit value from memory to a full register static void gen_add(HostReg reg,void* op) { gen_mov_word_to_reg(temp3, op, 1); - cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp3)); // add reg, reg, temp3 + cache_addd( ADD_REG_LSL_IMM(reg, reg, temp3, 0) ); // add reg, reg, temp3 } // add a 32bit constant value to a full register @@ -246,7 +335,7 @@ static void gen_add_imm(HostReg reg,Bit32u imm) { Bits scale; if(!imm) return; if (imm == 0xffffffff) { - cache_addd(0xe2400001 + (reg << 12) + (reg << 16)); // sub reg, reg, #1 + cache_addd( SUB_IMM(reg, reg, 1, 0) ); // sub reg, reg, #1 } else { scale = 0; while (imm) { @@ -254,7 +343,7 @@ static void gen_add_imm(HostReg reg,Bit32u imm) { imm>>=2; scale+=2; } - cache_addd(0xe2800000 + (reg << 12) + (reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // add reg, reg, #((imm & 0xff) << scale) + cache_addd( ADD_IMM(reg, reg, imm & 0xff, ROTATE_SCALE(scale)) ); // add reg, reg, #((imm & 0xff) << scale) imm>>=8; scale+=8; } @@ -268,7 +357,7 @@ static void gen_and_imm(HostReg reg,Bit32u imm) { imm2 = ~imm; if(!imm2) return; if (!imm) { - cache_addd(0xe3a00000 + (reg << 12)); // mov reg, #0 + cache_addd( MOV_IMM(reg, 0, 0) ); // mov reg, #0 } else { scale = 0; while (imm2) { @@ -276,7 +365,7 @@ static void gen_and_imm(HostReg reg,Bit32u imm) { imm2>>=2; scale+=2; } - cache_addd(0xe3c00000 + (reg << 12) + (reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // bic reg, reg, #((imm2 & 0xff) << scale) + cache_addd( BIC_IMM(reg, reg, imm2 & 0xff, ROTATE_SCALE(scale)) ); // bic reg, reg, #((imm2 & 0xff) << scale) imm2>>=8; scale+=8; } @@ -301,9 +390,9 @@ static void gen_add_direct_byte(void* dest,Bit8s imm) { gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); gen_mov_word_to_reg_helper(temp3, dest, 1, temp1); if (imm >= 0) { - cache_addd(0xe2800000 + (temp3 << 12) + (temp3 << 16) + ((Bit32s)imm)); // add temp3, temp3, #(imm) + cache_addd( ADD_IMM(temp3, temp3, (Bit32s)imm, 0) ); // add temp3, temp3, #(imm) } else { - cache_addd(0xe2400000 + (temp3 << 12) + (temp3 << 16) + (-((Bit32s)imm))); // sub temp3, temp3, #(-imm) + cache_addd( SUB_IMM(temp3, temp3, -((Bit32s)imm), 0) ); // sub temp3, temp3, #(-imm) } gen_mov_word_from_reg_helper(temp3, dest, 1, temp1); } @@ -323,7 +412,7 @@ static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { } else { gen_mov_word_to_reg_imm(temp2, (Bit16u)imm); } - cache_addd(0xe0800000 + (temp3 << 12) + (temp3 << 16) + (temp2)); // add temp3, temp3, temp2 + cache_addd( ADD_REG_LSL_IMM(temp3, temp3, temp2, 0) ); // add temp3, temp3, temp2 gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); } @@ -333,9 +422,9 @@ static void gen_sub_direct_byte(void* dest,Bit8s imm) { gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); gen_mov_word_to_reg_helper(temp3, dest, 1, temp1); if (imm >= 0) { - cache_addd(0xe2400000 + (temp3 << 12) + (temp3 << 16) + ((Bit32s)imm)); // sub temp3, temp3, #(imm) + cache_addd( SUB_IMM(temp3, temp3, (Bit32s)imm, 0) ); // sub temp3, temp3, #(imm) } else { - cache_addd(0xe2800000 + (temp3 << 12) + (temp3 << 16) + (-((Bit32s)imm))); // add temp3, temp3, #(-imm) + cache_addd( ADD_IMM(temp3, temp3, -((Bit32s)imm), 0) ); // add temp3, temp3, #(-imm) } gen_mov_word_from_reg_helper(temp3, dest, 1, temp1); } @@ -355,7 +444,7 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { } else { gen_mov_word_to_reg_imm(temp2, (Bit16u)imm); } - cache_addd(0xe0400000 + (temp3 << 12) + (temp3 << 16) + (temp2)); // sub temp3, temp3, temp2 + cache_addd( SUB_REG_LSL_IMM(temp3, temp3, temp2, 0) ); // sub temp3, temp3, temp2 gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); } @@ -363,7 +452,7 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { // scale_reg is scaled by scale (scale_reg*(2^scale)) and // added to dest_reg, then the immediate value is added static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { - cache_addd(0xe0800000 + (dest_reg << 12) + (dest_reg << 16) + (scale_reg) + (scale << 7)); // add dest_reg, dest_reg, scale_reg, lsl #(scale) + cache_addd( ADD_REG_LSL_IMM(dest_reg, dest_reg, scale_reg, scale) ); // add dest_reg, dest_reg, scale_reg, lsl #(scale) gen_add_imm(dest_reg, imm); } @@ -372,18 +461,18 @@ static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits im // then the immediate value is added static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { if (scale) { - cache_addd(0xe1a00000 + (dest_reg << 12) + (dest_reg) + (scale << 7)); // mov dest_reg, dest_reg, lsl #(scale) + cache_addd( MOV_REG_LSL_IMM(dest_reg, dest_reg, scale) ); // mov dest_reg, dest_reg, lsl #(scale) } gen_add_imm(dest_reg, imm); } // generate a call to a parameterless function static void INLINE gen_call_function_raw(void * func) { - cache_addd(0xe5900004 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #4] - cache_addd(0xe2800004 + (HOST_lr << 12) + (HOST_pc << 16)); // add lr, pc, #4 - cache_addd(0xe12fff10 + (temp1)); // bx temp1 + cache_addd( LDR_IMM(temp1, HOST_pc, 4) ); // ldr temp1, [pc, #4] + cache_addd( ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 + cache_addd( BX(temp1) ); // bx temp1 cache_addd((Bit32u)func); // .int func - cache_addd(0xe1a00000 + (FC_RETOP << 12) + HOST_a1); // mov FC_RETOP, a1 + cache_addd( MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 0) ); // mov FC_RETOP, a1 } // generate a call to a function with paramcount parameters @@ -435,7 +524,7 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { imm2>>=2; scale+=2; } - cache_addd(0xe2800000 + (temp3 << 12) + (temp3 << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // add temp3, temp3, #((imm2 & 0xff) << scale) + cache_addd( ADD_IMM(temp3, temp3, imm2 & 0xff, ROTATE_SCALE(scale)) ); // add temp3, temp3, #((imm2 & 0xff) << scale) imm2>>=8; scale+=8; } @@ -444,31 +533,31 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { #if (1) // (*ptr) should be word aligned if ((imm & 0x03) == 0) { - cache_addd(0xe5900000 + (temp1 << 12) + (temp3 << 16)); // ldr temp1, [temp3] + cache_addd( LDR_IMM(temp1, temp3, 0) ); // ldr temp1, [temp3] } else #endif { - cache_addd(0xe5d00000 + (temp1 << 12) + (temp3 << 16)); // ldrb temp1, [temp3] - cache_addd(0xe5d00001 + (temp2 << 12) + (temp3 << 16)); // ldrb temp2, [temp3, #1] - cache_addd(0xe1800400 + (temp1 << 12) + (temp1 << 16) + (temp2)); // orr temp1, temp1, temp2, lsl #8 - cache_addd(0xe5d00002 + (temp2 << 12) + (temp3 << 16)); // ldrb temp2, [temp3, #2] - cache_addd(0xe1800800 + (temp1 << 12) + (temp1 << 16) + (temp2)); // orr temp1, temp1, temp2, lsl #16 - cache_addd(0xe5d00003 + (temp2 << 12) + (temp3 << 16)); // ldrb temp2, [temp3, #3] - cache_addd(0xe1800c00 + (temp1 << 12) + (temp1 << 16) + (temp2)); // orr temp1, temp1, temp2, lsl #24 + cache_addd( LDRB_IMM(temp1, temp3, 0) ); // ldrb temp1, [temp3] + cache_addd( LDRB_IMM(temp2, temp3, 1) ); // ldrb temp2, [temp3, #1] + cache_addd( ORR_REG_LSL_IMM(temp1, temp1, temp2, 8) ); // orr temp1, temp1, temp2, lsl #8 + cache_addd( LDRB_IMM(temp2, temp3, 2) ); // ldrb temp2, [temp3, #2] + cache_addd( ORR_REG_LSL_IMM(temp1, temp1, temp2, 16) ); // orr temp1, temp1, temp2, lsl #16 + cache_addd( LDRB_IMM(temp2, temp3, 3) ); // ldrb temp2, [temp3, #3] + cache_addd( ORR_REG_LSL_IMM(temp1, temp1, temp2, 24) ); // orr temp1, temp1, temp2, lsl #24 } - cache_addd(0xe12fff10 + (temp1)); // bx temp1 + cache_addd( BX(temp1) ); // bx temp1 } // short conditional jump (+-127 bytes) if register is zero // the destination is set by gen_fill_branch() later static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { if (dword) { - cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 + cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 } else { - cache_addd(0xe1b00800 + (temp1 << 12) + (reg)); // movs temp1, reg, lsl #16 + cache_addd( MOVS_REG_LSL_IMM(temp1, reg, 16) ); // movs temp1, reg, lsl #16 } - cache_addd(0x0a000000); // beq j + cache_addd( BEQ_FWD(0) ); // beq j return ((Bit32u)cache.pos-4); } @@ -476,11 +565,11 @@ static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { // the destination is set by gen_fill_branch() later static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { if (dword) { - cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 + cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 } else { - cache_addd(0xe1b00800 + (temp1 << 12) + (reg)); // movs temp1, reg, lsl #16 + cache_addd( MOVS_REG_LSL_IMM(temp1, reg, 16) ); // movs temp1, reg, lsl #16 } - cache_addd(0x1a000000); // bne j + cache_addd( BNE_FWD(0) ); // bne j return ((Bit32u)cache.pos-4); } @@ -499,13 +588,13 @@ static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) { // for isdword==false the lowest 8bit of the register are tested static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { if (isdword) { - cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 + cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 } else { - cache_addd(0xe31000ff + (reg << 16)); // tst reg, #0xff + cache_addd( TST_IMM(reg, 0xff, 0) ); // tst reg, #0xff } - cache_addd(0x0a000002); // beq nobranch - cache_addd(0xe5900000 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #0] - cache_addd(0xe12fff10 + (temp1)); // bx temp1 + cache_addd( BEQ_FWD(8) ); // beq nobranch (pc +8) + cache_addd( LDR_IMM(temp1, HOST_pc, 0) ); // ldr temp1, [pc, #0] + cache_addd( BX(temp1) ); // bx temp1 cache_addd(0); // fill j // nobranch: return ((Bit32u)cache.pos-4); @@ -513,10 +602,10 @@ static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { // compare 32bit-register against zero and jump if value less/equal than zero static Bit32u gen_create_branch_long_leqzero(HostReg reg) { - cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0 - cache_addd(0xca000002); // bgt nobranch - cache_addd(0xe5900000 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #0] - cache_addd(0xe12fff10 + (temp1)); // bx temp1 + cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 + cache_addd( BGT_FWD(8) ); // bgt nobranch (pc+8) + cache_addd( LDR_IMM(temp1, HOST_pc, 0) ); // ldr temp1, [pc, #0] + cache_addd( BX(temp1) ); // bx temp1 cache_addd(0); // fill j // nobranch: return ((Bit32u)cache.pos-4); @@ -533,22 +622,26 @@ static void gen_run_code(void) { cache_addd(0xe92d0df0); // stmfd sp!, {v1-v5,v7,v8} // adr: 8 - cache_addd(0xe5900000 + (FC_SEGS_ADDR << 12) + (HOST_pc << 16) + (64 - (8 + 8))); // ldr FC_SEGS_ADDR, [pc, #(&Segs)] + cache_addd( LDR_IMM(FC_SEGS_ADDR, HOST_pc, 64 - (8 + 8)) ); // ldr FC_SEGS_ADDR, [pc, #(&Segs)] // adr: 12 - cache_addd(0xe5900000 + (FC_REGS_ADDR << 12) + (HOST_pc << 16) + (68 - (12 + 8))); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)] - cache_addd(0xe28fe004); // add lr, pc, #4 + cache_addd( LDR_IMM(FC_REGS_ADDR, HOST_pc, 68 - (12 + 8)) ); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)] + + cache_addd( ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 cache_addd(0xe92d4000); // stmfd sp!, {lr} - cache_addd(0xe12fff10); // bx r0 + cache_addd( BX(HOST_r0) ); // bx r0 + cache_addd(0xe8bd0df0); // ldmfd sp!, {v1-v5,v7,v8} + cache_addd(0xe8bd4000); // ldmfd sp!, {lr} - cache_addd(0xe12fff1e); // bx lr + cache_addd( BX(HOST_lr) ); // bx lr + // fill up to 64 bytes - cache_addd(0xe1a00000); // nop - cache_addd(0xe1a00000); // nop - cache_addd(0xe1a00000); // nop - cache_addd(0xe1a00000); // nop - cache_addd(0xe1a00000); // nop - cache_addd(0xe1a00000); // nop + cache_addd( NOP ); // nop + cache_addd( NOP ); // nop + cache_addd( NOP ); // nop + cache_addd( NOP ); // nop + cache_addd( NOP ); // nop + cache_addd( NOP ); // nop // adr: 64 cache_addd((Bit32u)&Segs); // address of "Segs" @@ -558,9 +651,9 @@ static void gen_run_code(void) { // return from a function static void gen_return_function(void) { - cache_addd(0xe1a00000 + (HOST_a1 << 12) + FC_RETOP); // mov a1, FC_RETOP + cache_addd( MOV_REG_LSL_IMM(HOST_a1, FC_RETOP, 0) ); // mov a1, FC_RETOP cache_addd(0xe8bd4000); // ldmfd sp!, {lr} - cache_addd(0xe12fff1e); // bx lr + cache_addd( BX(HOST_lr) ); // bx lr } #ifdef DRC_FLAGS_INVALIDATION @@ -574,32 +667,32 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: - *(Bit32u*)pos=0xe0800000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // add FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=ADD_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // add FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_ORb: case t_ORw: case t_ORd: - *(Bit32u*)pos=0xe1800000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // orr FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=ORR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // orr FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_ANDb: case t_ANDw: case t_ANDd: - *(Bit32u*)pos=0xe0000000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // and FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=AND_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // and FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_SUBb: case t_SUBw: case t_SUBd: - *(Bit32u*)pos=0xe0400000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // sub FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=SUB_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // sub FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_XORb: case t_XORw: case t_XORd: - *(Bit32u*)pos=0xe0200000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // eor FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=EOR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // eor FC_RETOP, a1, a2 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_CMPb: case t_CMPw: @@ -607,106 +700,106 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit32u*)pos=0xea000000 + (3); // b (pc+3*4) + *(Bit32u*)pos=B_FWD(12); // b (pc+3*4) break; case t_INCb: case t_INCw: case t_INCd: - *(Bit32u*)pos=0xe2800000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (1); // add FC_RETOP, a1, #1 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=ADD_IMM(FC_RETOP, HOST_a1, 1, 0); // add FC_RETOP, a1, #1 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_DECb: case t_DECw: case t_DECd: - *(Bit32u*)pos=0xe2400000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (1); // sub FC_RETOP, a1, #1 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=SUB_IMM(FC_RETOP, HOST_a1, 1, 0); // sub FC_RETOP, a1, #1 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_SHLb: case t_SHLw: case t_SHLd: - *(Bit32u*)pos=0xe1a00010 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, lsl a2 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=MOV_REG_LSL_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsl a2 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_SHRb: - *(Bit32u*)pos=0xe2000000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (0xff); // and FC_RETOP, a1, #0xff - *(Bit32u*)(pos+4)=0xe1a00030 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, lsr a2 - *(Bit32u*)(pos+8)=0xe1a00000; // nop - *(Bit32u*)(pos+12)=0xe1a00000; // nop - *(Bit32u*)(pos+16)=0xe1a00000; // nop + *(Bit32u*)pos=AND_IMM(FC_RETOP, HOST_a1, 0xff, 0); // and FC_RETOP, a1, #0xff + *(Bit32u*)(pos+4)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2 + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop break; case t_SHRw: - *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=0xe1a00020 + (FC_RETOP << 12) + (FC_RETOP) + (16 << 7); // mov FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+8)=0xe1a00030 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, lsr a2 - *(Bit32u*)(pos+12)=0xe1a00000; // nop - *(Bit32u*)(pos+16)=0xe1a00000; // nop + *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+4)=MOV_REG_LSR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+8)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop break; case t_SHRd: - *(Bit32u*)pos=0xe1a00030 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, lsr a2 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=MOV_REG_LSR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsr a2 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_SARb: - *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (24 << 7); // mov FC_RETOP, a1, lsl #24 - *(Bit32u*)(pos+4)=0xe1a00040 + (FC_RETOP << 12) + (FC_RETOP) + (24 << 7); // mov FC_RETOP, FC_RETOP, asr #24 - *(Bit32u*)(pos+8)=0xe1a00050 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, asr a2 - *(Bit32u*)(pos+12)=0xe1a00000; // nop - *(Bit32u*)(pos+16)=0xe1a00000; // nop + *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 + *(Bit32u*)(pos+4)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 24); // mov FC_RETOP, FC_RETOP, asr #24 + *(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop break; case t_SARw: - *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=0xe1a00040 + (FC_RETOP << 12) + (FC_RETOP) + (16 << 7); // mov FC_RETOP, FC_RETOP, asr #16 - *(Bit32u*)(pos+8)=0xe1a00050 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, asr a2 - *(Bit32u*)(pos+12)=0xe1a00000; // nop - *(Bit32u*)(pos+16)=0xe1a00000; // nop + *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+4)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, asr #16 + *(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop break; case t_SARd: - *(Bit32u*)pos=0xe1a00050 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, asr a2 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=MOV_REG_ASR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, asr a2 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_RORb: - *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (24 << 7); // mov FC_RETOP, a1, lsl #24 - *(Bit32u*)(pos+4)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (8 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 - *(Bit32u*)(pos+8)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+12)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2 - *(Bit32u*)(pos+16)=0xe1a00000; // nop + *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 + *(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 8); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 + *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 + *(Bit32u*)(pos+16)=NOP; // nop break; case t_RORw: - *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+8)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2 - *(Bit32u*)(pos+12)=0xe1a00000; // nop - *(Bit32u*)(pos+16)=0xe1a00000; // nop + *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop break; case t_RORd: - *(Bit32u*)pos=0xe1a00070 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, ror a2 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; case t_ROLb: - *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (24 << 7); // mov FC_RETOP, a1, lsl #24 - *(Bit32u*)(pos+4)=0xe2600000 + (HOST_a2 << 12) + (HOST_a2 << 16) + (32); // rsb a2, a2, #32 - *(Bit32u*)(pos+8)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (8 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 - *(Bit32u*)(pos+12)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+16)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2 + *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 + *(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 + *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 8); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 + *(Bit32u*)(pos+12)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+16)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 break; case t_ROLw: - *(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=0xe2600000 + (HOST_a2 << 12) + (HOST_a2 << 16) + (32); // rsb a2, a2, #32 - *(Bit32u*)(pos+8)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+12)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2 - *(Bit32u*)(pos+16)=0xe1a00000; // nop + *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 + *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 + *(Bit32u*)(pos+16)=NOP; // nop break; case t_ROLd: - *(Bit32u*)pos=0xe2600000 + (HOST_a2 << 12) + (HOST_a2 << 16) + (32); // rsb a2, a2, #32 - *(Bit32u*)(pos+4)=0xe1a00070 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, ror a2 - *(Bit32u*)(pos+8)=0xe1a00000; // nop - *(Bit32u*)(pos+12)=0xe1a00000; // nop - *(Bit32u*)(pos+16)=0xe1a00000; // nop + *(Bit32u*)pos=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 + *(Bit32u*)(pos+4)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop break; case t_NEGb: case t_NEGw: case t_NEGd: - *(Bit32u*)pos=0xe2600000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (0); // rsb FC_RETOP, a1, #0 - *(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4) + *(Bit32u*)pos=RSB_IMM(FC_RETOP, HOST_a1, 0, 0); // rsb FC_RETOP, a1, #0 + *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) break; default: *(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func @@ -721,24 +814,23 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { static void cache_block_before_close(void) { } - #ifdef DRC_USE_SEGS_ADDR // mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { - cache_addd(0xe1d000b0 + (dest_reg << 12) + (FC_SEGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // ldrh dest_reg, [FC_SEGS_ADDR, #index] + cache_addd( LDRH_IMM(dest_reg, FC_SEGS_ADDR, index) ); // ldrh dest_reg, [FC_SEGS_ADDR, #index] } // mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { - cache_addd(0xe5900000 + (dest_reg << 12) + (FC_SEGS_ADDR << 16) + (index)); // ldr dest_reg, [FC_SEGS_ADDR, #index] + cache_addd( LDR_IMM(dest_reg, FC_SEGS_ADDR, index) ); // ldr dest_reg, [FC_SEGS_ADDR, #index] } // add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { - cache_addd(0xe5900000 + (temp1 << 12) + (FC_SEGS_ADDR << 16) + (index)); // ldr temp1, [FC_SEGS_ADDR, #index] - cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp1)); // add reg, reg, temp1 + cache_addd( LDR_IMM(temp1, FC_SEGS_ADDR, index) ); // ldr temp1, [FC_SEGS_ADDR, #index] + cache_addd( ADD_REG_LSL_IMM(reg, reg, temp1, 0) ); // add reg, reg, temp1 } #endif @@ -748,21 +840,21 @@ static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { // mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { - cache_addd(0xe1d000b0 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // ldrh dest_reg, [FC_REGS_ADDR, #index] + cache_addd( LDRH_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrh dest_reg, [FC_REGS_ADDR, #index] } // mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { - cache_addd(0xe5900000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldr dest_reg, [FC_REGS_ADDR, #index] + cache_addd( LDR_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldr dest_reg, [FC_REGS_ADDR, #index] } // move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { if (dword) { - cache_addd(0xe5900000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldr dest_reg, [FC_REGS_ADDR, #index] + cache_addd( LDR_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldr dest_reg, [FC_REGS_ADDR, #index] } else { - cache_addd(0xe1d000b0 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // ldrh dest_reg, [FC_REGS_ADDR, #index] + cache_addd( LDRH_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrh dest_reg, [FC_REGS_ADDR, #index] } } @@ -771,7 +863,7 @@ static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { // this function does not use FC_OP1/FC_OP2 as dest_reg as these // registers might not be directly byte-accessible on some architectures static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { - cache_addd(0xe5d00000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldrb dest_reg, [FC_REGS_ADDR, #index] + cache_addd( LDRB_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrb dest_reg, [FC_REGS_ADDR, #index] } // move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR @@ -779,39 +871,39 @@ static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { // this function can use FC_OP1/FC_OP2 as dest_reg which are // not directly byte-accessible on some architectures static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { - cache_addd(0xe5d00000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldrb dest_reg, [FC_REGS_ADDR, #index] + cache_addd( LDRB_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrb dest_reg, [FC_REGS_ADDR, #index] } // add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { - cache_addd(0xe5900000 + (temp2 << 12) + (FC_REGS_ADDR << 16) + (index)); // ldr temp2, [FC_REGS_ADDR, #index] - cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp2)); // add reg, reg, temp2 + cache_addd( LDR_IMM(temp2, FC_REGS_ADDR, index) ); // ldr temp2, [FC_REGS_ADDR, #index] + cache_addd( ADD_REG_LSL_IMM(reg, reg, temp2, 0) ); // add reg, reg, temp2 } // move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { - cache_addd(0xe1c000b0 + (src_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // strh src_reg, [FC_REGS_ADDR, #index] + cache_addd( STRH_IMM(src_reg, FC_REGS_ADDR, index) ); // strh src_reg, [FC_REGS_ADDR, #index] } // move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { - cache_addd(0xe5800000 + (src_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // str src_reg, [FC_REGS_ADDR, #index] + cache_addd( STR_IMM(src_reg, FC_REGS_ADDR, index) ); // str src_reg, [FC_REGS_ADDR, #index] } // move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { if (dword) { - cache_addd(0xe5800000 + (src_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // str src_reg, [FC_REGS_ADDR, #index] + cache_addd( STR_IMM(src_reg, FC_REGS_ADDR, index) ); // str src_reg, [FC_REGS_ADDR, #index] } else { - cache_addd(0xe1c000b0 + (src_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // strh src_reg, [FC_REGS_ADDR, #index] + cache_addd( STRH_IMM(src_reg, FC_REGS_ADDR, index) ); // strh src_reg, [FC_REGS_ADDR, #index] } } // move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { - cache_addd(0xe5c00000 + (src_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // strb src_reg, [FC_REGS_ADDR, #index] + cache_addd( STRB_IMM(src_reg, FC_REGS_ADDR, index) ); // strb src_reg, [FC_REGS_ADDR, #index] } #endif diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h index 8aefc92c..e4e0fe12 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-thumb-iw.h,v 1.2 2008-09-19 16:48:02 c2woody Exp $ */ +/* $Id: risc_armv4le-thumb-iw.h,v 1.3 2009-05-16 21:52:47 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (thumb version with data pool, requires -mthumb-interwork switch when compiling dosbox) */ @@ -64,6 +64,97 @@ #endif +// instruction encodings + +// move +// mov dst, #imm @ 0 <= imm <= 255 +#define MOV_IMM(dst, imm) (0x2000 + ((dst) << 8) + (imm) ) +// mov dst, src +#define MOV_REG(dst, src) ADD_IMM3(dst, src, 0) +// mov dst, src +#define MOV_LO_HI(dst, src) (0x4640 + (dst) + (((src) - HOST_r8) << 3) ) +// mov dst, src +#define MOV_HI_LO(dst, src) (0x4680 + ((dst) - HOST_r8) + ((src) << 3) ) + +// arithmetic +// add dst, src, #imm @ 0 <= imm <= 7 +#define ADD_IMM3(dst, src, imm) (0x1c00 + (dst) + ((src) << 3) + ((imm) << 6) ) +// add dst, #imm @ 0 <= imm <= 255 +#define ADD_IMM8(dst, imm) (0x3000 + ((dst) << 8) + (imm) ) +// add dst, src1, src2 +#define ADD_REG(dst, src1, src2) (0x1800 + (dst) + ((src1) << 3) + ((src2) << 6) ) +// add dst, src +#define ADD_LO_HI(dst, src) (0x4440 + (dst) + (((src) - HOST_r8) << 3) ) +// add dst, pc, #imm @ 0 <= imm < 1024 & imm mod 4 = 0 +#define ADD_LO_PC_IMM(dst, imm) (0xa000 + ((dst) << 8) + ((imm) >> 2) ) +// sub dst, src1, src2 +#define SUB_REG(dst, src1, src2) (0x1a00 + (dst) + ((src1) << 3) + ((src2) << 6) ) +// sub dst, src, #imm @ 0 <= imm <= 7 +#define SUB_IMM3(dst, src, imm) (0x1e00 + (dst) + ((src) << 3) + ((imm) << 6) ) +// sub dst, #imm @ 0 <= imm <= 255 +#define SUB_IMM8(dst, imm) (0x3800 + ((dst) << 8) + (imm) ) +// neg dst, src +#define NEG(dst, src) (0x4240 + (dst) + ((src) << 3) ) +// cmp dst, #imm @ 0 <= imm <= 255 +#define CMP_IMM(dst, imm) (0x2800 + ((dst) << 8) + (imm) ) +// nop +#define NOP (0x46c0) + +// logical +// and dst, src +#define AND(dst, src) (0x4000 + (dst) + ((src) << 3) ) +// eor dst, src +#define EOR(dst, src) (0x4040 + (dst) + ((src) << 3) ) +// orr dst, src +#define ORR(dst, src) (0x4300 + (dst) + ((src) << 3) ) + +// shift/rotate +// lsl dst, src, #imm +#define LSL_IMM(dst, src, imm) (0x0000 + (dst) + ((src) << 3) + ((imm) << 6) ) +// lsl dst, reg +#define LSL_REG(dst, reg) (0x4080 + (dst) + ((reg) << 3) ) +// lsr dst, src, #imm +#define LSR_IMM(dst, src, imm) (0x0800 + (dst) + ((src) << 3) + ((imm) << 6) ) +// lsr dst, reg +#define LSR_REG(dst, reg) (0x40c0 + (dst) + ((reg) << 3) ) +// asr dst, src, #imm +#define ASR_IMM(dst, src, imm) (0x1000 + (dst) + ((src) << 3) + ((imm) << 6) ) +// asr dst, reg +#define ASR_REG(dst, reg) (0x4100 + (dst) + ((reg) << 3) ) +// ror dst, reg +#define ROR_REG(dst, reg) (0x41c0 + (dst) + ((reg) << 3) ) + +// load +// ldr reg, [addr, #imm] @ 0 <= imm < 128 & imm mod 4 = 0 +#define LDR_IMM(reg, addr, imm) (0x6800 + (reg) + ((addr) << 3) + ((imm) << 4) ) +// ldrh reg, [addr, #imm] @ 0 <= imm < 64 & imm mod 2 = 0 +#define LDRH_IMM(reg, addr, imm) (0x8800 + (reg) + ((addr) << 3) + ((imm) << 5) ) +// ldrb reg, [addr, #imm] @ 0 <= imm < 32 +#define LDRB_IMM(reg, addr, imm) (0x7800 + (reg) + ((addr) << 3) + ((imm) << 6) ) +// ldr reg, [pc, #imm] @ 0 <= imm < 1024 & imm mod 4 = 0 +#define LDR_PC_IMM(reg, imm) (0x4800 + ((reg) << 8) + ((imm) >> 2) ) + +// store +// str reg, [addr, #imm] @ 0 <= imm < 128 & imm mod 4 = 0 +#define STR_IMM(reg, addr, imm) (0x6000 + (reg) + ((addr) << 3) + ((imm) << 4) ) +// strh reg, [addr, #imm] @ 0 <= imm < 64 & imm mod 2 = 0 +#define STRH_IMM(reg, addr, imm) (0x8000 + (reg) + ((addr) << 3) + ((imm) << 5) ) +// strb reg, [addr, #imm] @ 0 <= imm < 32 +#define STRB_IMM(reg, addr, imm) (0x7000 + (reg) + ((addr) << 3) + ((imm) << 6) ) + +// branch +// beq pc+imm @ 0 <= imm < 256 & imm mod 2 = 0 +#define BEQ_FWD(imm) (0xd000 + ((imm) >> 1) ) +// bne pc+imm @ 0 <= imm < 256 & imm mod 2 = 0 +#define BNE_FWD(imm) (0xd100 + ((imm) >> 1) ) +// bgt pc+imm @ 0 <= imm < 256 & imm mod 2 = 0 +#define BGT_FWD(imm) (0xdc00 + ((imm) >> 1) ) +// b pc+imm @ 0 <= imm < 2048 & imm mod 2 = 0 +#define B_FWD(imm) (0xe000 + ((imm) >> 1) ) +// bx reg +#define BX(reg) (0x4700 + ((reg) << 3) ) + + // data pool defines #define CACHE_DATA_JUMP (2) #define CACHE_DATA_ALIGN (32) @@ -75,6 +166,7 @@ static Bit8u * cache_datapos = NULL; // position of data pool in the cache block static Bit32u cache_datasize = 0; // total size of data pool static Bit32u cache_dataindex = 0; // used size of data pool = index of free data item (in bytes) in data pool + // forwarded function static void INLINE gen_create_branch_short(void * func); @@ -185,26 +277,26 @@ static void cache_block_before_close(void) { static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { if(reg_src == reg_dst) return; cache_checkinstr(2); - cache_addw(0x1c00 + reg_dst + (reg_src << 3)); // mov reg_dst, reg_src + cache_addw( MOV_REG(reg_dst, reg_src) ); // mov reg_dst, reg_src } // move a 32bit constant value into dest_reg static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { if ((imm & 0xffffff00) == 0) { cache_checkinstr(2); - cache_addw(0x2000 + (dest_reg << 8) + imm); // mov dest_reg, #(imm) + cache_addw( MOV_IMM(dest_reg, imm) ); // mov dest_reg, #(imm) } else if ((imm & 0xffff00ff) == 0) { cache_checkinstr(4); - cache_addw(0x2000 + (dest_reg << 8) + (imm >> 8)); // mov dest_reg, #(imm >> 8) - cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (8 << 6)); // lsl dest_reg, dest_reg, #8 + cache_addw( MOV_IMM(dest_reg, imm >> 8) ); // mov dest_reg, #(imm >> 8) + cache_addw( LSL_IMM(dest_reg, dest_reg, 8) ); // lsl dest_reg, dest_reg, #8 } else if ((imm & 0xff00ffff) == 0) { cache_checkinstr(4); - cache_addw(0x2000 + (dest_reg << 8) + (imm >> 16)); // mov dest_reg, #(imm >> 16) - cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (16 << 6)); // lsl dest_reg, dest_reg, #16 + cache_addw( MOV_IMM(dest_reg, imm >> 16) ); // mov dest_reg, #(imm >> 16) + cache_addw( LSL_IMM(dest_reg, dest_reg, 16) ); // lsl dest_reg, dest_reg, #16 } else if ((imm & 0x00ffffff) == 0) { cache_checkinstr(4); - cache_addw(0x2000 + (dest_reg << 8) + (imm >> 24)); // mov dest_reg, #(imm >> 24) - cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (24 << 6)); // lsl dest_reg, dest_reg, #24 + cache_addw( MOV_IMM(dest_reg, imm >> 24) ); // mov dest_reg, #(imm >> 24) + cache_addw( LSL_IMM(dest_reg, dest_reg, 24) ); // lsl dest_reg, dest_reg, #24 } else { Bit32u diff; @@ -214,10 +306,10 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { if ((diff < 1024) && ((imm & 0x03) == 0)) { if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw(0xa000 + (dest_reg << 8) + (diff >> 2)); // add dest_reg, pc, #(diff >> 2) + cache_addw( ADD_LO_PC_IMM(dest_reg, diff >> 2) ); // add dest_reg, pc, #(diff >> 2) } else { - cache_addw(0x46c0); // nop - cache_addw(0xa000 + (dest_reg << 8) + ((diff - 2) >> 2)); // add dest_reg, pc, #((diff - 2) >> 2) + cache_addw( NOP ); // nop + cache_addw( ADD_LO_PC_IMM(dest_reg, (diff - 2) >> 2) ); // add dest_reg, pc, #((diff - 2) >> 2) } } else { Bit8u *datapos; @@ -226,9 +318,9 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { *(Bit32u*)datapos=imm; if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw(0x4800 + (dest_reg << 8) + ((datapos - (cache.pos + 4)) >> 2)); // ldr dest_reg, [pc, datapos] + cache_addw( LDR_PC_IMM(dest_reg, datapos - (cache.pos + 4)) ); // ldr dest_reg, [pc, datapos] } else { - cache_addw(0x4800 + (dest_reg << 8) + ((datapos - (cache.pos + 2)) >> 2)); // ldr dest_reg, [pc, datapos] + cache_addw( LDR_PC_IMM(dest_reg, datapos - (cache.pos + 2)) ); // ldr dest_reg, [pc, datapos] } } } @@ -241,35 +333,35 @@ static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,Ho if ((Bit32u)data & 3) { if ( ((Bit32u)data & 3) == 2 ) { cache_checkinstr(8); - cache_addw(0x8800 + dest_reg + (data_reg << 3)); // ldrh dest_reg, [data_reg] - cache_addw(0x8800 + templo1 + (data_reg << 3) + (2 << 5)); // ldrh templo1, [data_reg, #2] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (16 << 6)); // lsl templo1, templo1, #16 - cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + cache_addw( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] + cache_addw( LDRH_IMM(templo1, data_reg, 2) ); // ldrh templo1, [data_reg, #2] + cache_addw( LSL_IMM(templo1, templo1, 16) ); // lsl templo1, templo1, #16 + cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 } else { cache_checkinstr(16); - cache_addw(0x7800 + dest_reg + (data_reg << 3)); // ldrb dest_reg, [data_reg] - cache_addw(0x1c00 + templo1 + (data_reg << 3) + (1 << 6)); // add templo1, data_reg, #1 - cache_addw(0x8800 + templo1 + (templo1 << 3)); // ldrh templo1, [templo1] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (8 << 6)); // lsl templo1, templo1, #8 - cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 - cache_addw(0x7800 + templo1 + (data_reg << 3) + (3 << 6)); // ldrb templo1, [data_reg, #3] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (24 << 6)); // lsl templo1, templo1, #24 - cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + cache_addw( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] + cache_addw( ADD_IMM3(templo1, data_reg, 1) ); // add templo1, data_reg, #1 + cache_addw( LDRH_IMM(templo1, templo1, 0) ); // ldrh templo1, [templo1] + cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 + cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 + cache_addw( LDRB_IMM(templo1, data_reg, 3) ); // ldrb templo1, [data_reg, #3] + cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 + cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 } } else { cache_checkinstr(2); - cache_addw(0x6800 + dest_reg + (data_reg << 3)); // ldr dest_reg, [data_reg] + cache_addw( LDR_IMM(dest_reg, data_reg, 0) ); // ldr dest_reg, [data_reg] } } else { if ((Bit32u)data & 1) { cache_checkinstr(8); - cache_addw(0x7800 + dest_reg + (data_reg << 3)); // ldrb dest_reg, [data_reg] - cache_addw(0x7800 + templo1 + (data_reg << 3) + (1 << 6)); // ldrb templo1, [data_reg, #1] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (8 << 6)); // lsl templo1, templo1, #8 - cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + cache_addw( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] + cache_addw( LDRB_IMM(templo1, data_reg, 1) ); // ldrb templo1, [data_reg, #1] + cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 + cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 } else { cache_checkinstr(2); - cache_addw(0x8800 + dest_reg + (data_reg << 3)); // ldrh dest_reg, [data_reg] + cache_addw( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] } } } @@ -294,37 +386,37 @@ static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, if ((Bit32u)dest & 3) { if ( ((Bit32u)dest & 3) == 2 ) { cache_checkinstr(8); - cache_addw(0x8000 + src_reg + (data_reg << 3)); // strh src_reg, [data_reg] - cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg - cache_addw(0x0800 + templo1 + (templo1 << 3) + (16 << 6)); // lsr templo1, templo1, #16 - cache_addw(0x8000 + templo1 + (data_reg << 3) + (2 << 5)); // strh templo1, [data_reg, #2] + cache_addw( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] + cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg + cache_addw( LSR_IMM(templo1, templo1, 16) ); // lsr templo1, templo1, #16 + cache_addw( STRH_IMM(templo1, data_reg, 2) ); // strh templo1, [data_reg, #2] } else { cache_checkinstr(20); - cache_addw(0x7000 + src_reg + (data_reg << 3)); // strb src_reg, [data_reg] - cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg - cache_addw(0x0800 + templo1 + (templo1 << 3) + (8 << 6)); // lsr templo1, templo1, #8 - cache_addw(0x7000 + templo1 + (data_reg << 3) + (1 << 6)); // strb templo1, [data_reg, #1] - cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg - cache_addw(0x0800 + templo1 + (templo1 << 3) + (16 << 6)); // lsr templo1, templo1, #16 - cache_addw(0x7000 + templo1 + (data_reg << 3) + (2 << 6)); // strb templo1, [data_reg, #2] - cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg - cache_addw(0x0800 + templo1 + (templo1 << 3) + (24 << 6)); // lsr templo1, templo1, #24 - cache_addw(0x7000 + templo1 + (data_reg << 3) + (3 << 6)); // strb templo1, [data_reg, #3] + cache_addw( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] + cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg + cache_addw( LSR_IMM(templo1, templo1, 8) ); // lsr templo1, templo1, #8 + cache_addw( STRB_IMM(templo1, data_reg, 1) ); // strb templo1, [data_reg, #1] + cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg + cache_addw( LSR_IMM(templo1, templo1, 16) ); // lsr templo1, templo1, #16 + cache_addw( STRB_IMM(templo1, data_reg, 2) ); // strb templo1, [data_reg, #2] + cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg + cache_addw( LSR_IMM(templo1, templo1, 24) ); // lsr templo1, templo1, #24 + cache_addw( STRB_IMM(templo1, data_reg, 3) ); // strb templo1, [data_reg, #3] } } else { cache_checkinstr(2); - cache_addw(0x6000 + src_reg + (data_reg << 3)); // str src_reg, [data_reg] + cache_addw( STR_IMM(src_reg, data_reg, 0) ); // str src_reg, [data_reg] } } else { if ((Bit32u)dest & 1) { cache_checkinstr(8); - cache_addw(0x7000 + src_reg + (data_reg << 3)); // strb src_reg, [data_reg] - cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg - cache_addw(0x0800 + templo1 + (templo1 << 3) + (8 << 6)); // lsr templo1, templo1, #8 - cache_addw(0x7000 + templo1 + (data_reg << 3) + (1 << 6)); // strb templo1, [data_reg, #1] + cache_addw( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] + cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg + cache_addw( LSR_IMM(templo1, templo1, 8) ); // lsr templo1, templo1, #8 + cache_addw( STRB_IMM(templo1, data_reg, 1) ); // strb templo1, [data_reg, #1] } else { cache_checkinstr(2); - cache_addw(0x8000 + src_reg + (data_reg << 3)); // strh src_reg, [data_reg] + cache_addw( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] } } } @@ -342,7 +434,7 @@ static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { gen_mov_dword_to_reg_imm(templo1, (Bit32u)data); cache_checkinstr(2); - cache_addw(0x7800 + dest_reg + (templo1 << 3)); // ldrb dest_reg, [templo1] + cache_addw( LDRB_IMM(dest_reg, templo1, 0) ); // ldrb dest_reg, [templo1] } // move an 8bit value from memory into dest_reg @@ -359,7 +451,7 @@ static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* dat // registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { cache_checkinstr(2); - cache_addw(0x2000 + (dest_reg << 8) + imm); // mov dest_reg, #(imm) + cache_addw( MOV_IMM(dest_reg, imm) ); // mov dest_reg, #(imm) } // move an 8bit constant value into dest_reg @@ -374,7 +466,7 @@ static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { gen_mov_dword_to_reg_imm(templo1, (Bit32u)dest); cache_checkinstr(2); - cache_addw(0x7000 + src_reg + (templo1 << 3)); // strb src_reg, [templo1] + cache_addw( STRB_IMM(src_reg, templo1, 0) ); // strb src_reg, [templo1] } @@ -383,12 +475,12 @@ static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { // the register is zero-extended (sign==false) or sign-extended (sign==true) static void gen_extend_byte(bool sign,HostReg reg) { cache_checkinstr(4); - cache_addw(0x0000 + reg + (reg << 3) + (24 << 6)); // lsl reg, reg, #24 + cache_addw( LSL_IMM(reg, reg, 24) ); // lsl reg, reg, #24 if (sign) { - cache_addw(0x1000 + reg + (reg << 3) + (24 << 6)); // asr reg, reg, #24 + cache_addw( ASR_IMM(reg, reg, 24) ); // asr reg, reg, #24 } else { - cache_addw(0x0800 + reg + (reg << 3) + (24 << 6)); // lsr reg, reg, #24 + cache_addw( LSR_IMM(reg, reg, 24) ); // lsr reg, reg, #24 } } @@ -396,22 +488,22 @@ static void gen_extend_byte(bool sign,HostReg reg) { // the register is zero-extended (sign==false) or sign-extended (sign==true) static void gen_extend_word(bool sign,HostReg reg) { cache_checkinstr(4); - cache_addw(0x0000 + reg + (reg << 3) + (16 << 6)); // lsl reg, reg, #16 + cache_addw( LSL_IMM(reg, reg, 16) ); // lsl reg, reg, #16 if (sign) { - cache_addw(0x1000 + reg + (reg << 3) + (16 << 6)); // asr reg, reg, #16 + cache_addw( ASR_IMM(reg, reg, 16) ); // asr reg, reg, #16 } else { - cache_addw(0x0800 + reg + (reg << 3) + (16 << 6)); // lsr reg, reg, #16 + cache_addw( LSR_IMM(reg, reg, 16) ); // lsr reg, reg, #16 } } // add a 32bit value from memory to a full register static void gen_add(HostReg reg,void* op) { cache_checkinstr(2); - cache_addw(0x4680 + (temphi1 - HOST_r8) + (reg << 3)); // mov temphi1, reg + cache_addw( MOV_HI_LO(temphi1, reg) ); // mov temphi1, reg gen_mov_word_to_reg(reg, op, 1); cache_checkinstr(2); - cache_addw(0x4440 + (reg) + ((temphi1 - HOST_r8) << 3)); // add reg, temphi1 + cache_addw( ADD_LO_HI(reg, temphi1) ); // add reg, temphi1 } // add a 32bit constant value to a full register @@ -419,7 +511,7 @@ static void gen_add_imm(HostReg reg,Bit32u imm) { if(!imm) return; gen_mov_dword_to_reg_imm(templo1, imm); cache_checkinstr(2); - cache_addw(0x1800 + reg + (reg << 3) + (templo1 << 6)); // add reg, reg, templo1 + cache_addw( ADD_REG(reg, reg, templo1) ); // add reg, reg, templo1 } // and a 32bit constant value with a full register @@ -427,18 +519,18 @@ static void gen_and_imm(HostReg reg,Bit32u imm) { if(imm == 0xffffffff) return; gen_mov_dword_to_reg_imm(templo1, imm); cache_checkinstr(2); - cache_addw(0x4000 + reg + (templo1<< 3)); // and reg, templo1 + cache_addw( AND(reg, templo1) ); // and reg, templo1 } // move a 32bit constant value into memory static void gen_mov_direct_dword(void* dest,Bit32u imm) { cache_checkinstr(2); - cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templosav, imm); gen_mov_word_from_reg(templosav, dest, 1); cache_checkinstr(2); - cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 } // move an address into memory @@ -450,18 +542,18 @@ static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { static void gen_add_direct_byte(void* dest,Bit8s imm) { if(!imm) return; cache_checkinstr(2); - cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); gen_mov_word_to_reg_helper(templosav, dest, 1, templo2); cache_checkinstr(2); if (imm >= 0) { - cache_addw(0x3000 + (templosav << 8) + ((Bit32s)imm)); // add templosav, #(imm) + cache_addw( ADD_IMM8(templosav, (Bit32s)imm) ); // add templosav, #(imm) } else { - cache_addw(0x3800 + (templosav << 8) + (-((Bit32s)imm))); // sub templosav, #(-imm) + cache_addw( SUB_IMM8(templosav, -((Bit32s)imm)) ); // sub templosav, #(-imm) } gen_mov_word_from_reg_helper(templosav, dest, 1, templo2); cache_checkinstr(2); - cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 } // add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value @@ -472,7 +564,7 @@ static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { return; } cache_checkinstr(2); - cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); gen_mov_word_to_reg_helper(templosav, dest, dword, templo2); if (dword) { @@ -481,28 +573,28 @@ static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); } cache_checkinstr(2); - cache_addw(0x1800 + templosav + (templosav << 3) + (templo1 << 6)); // add templosav, templosav, templo1 + cache_addw( ADD_REG(templosav, templosav, templo1) ); // add templosav, templosav, templo1 gen_mov_word_from_reg_helper(templosav, dest, dword, templo2); cache_checkinstr(2); - cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 } // subtract an 8bit constant value from a dword memory value static void gen_sub_direct_byte(void* dest,Bit8s imm) { if(!imm) return; cache_checkinstr(2); - cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); gen_mov_word_to_reg_helper(templosav, dest, 1, templo2); cache_checkinstr(2); if (imm >= 0) { - cache_addw(0x3800 + (templosav << 8) + ((Bit32s)imm)); // sub templosav, #(imm) + cache_addw( SUB_IMM8(templosav, (Bit32s)imm) ); // sub templosav, #(imm) } else { - cache_addw(0x3000 + (templosav << 8) + (-((Bit32s)imm))); // add templosav, #(-imm) + cache_addw( ADD_IMM8(templosav, -((Bit32s)imm)) ); // add templosav, #(-imm) } gen_mov_word_from_reg_helper(templosav, dest, 1, templo2); cache_checkinstr(2); - cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 } // subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value @@ -513,7 +605,7 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { return; } cache_checkinstr(2); - cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); gen_mov_word_to_reg_helper(templosav, dest, dword, templo2); if (dword) { @@ -522,10 +614,10 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); } cache_checkinstr(2); - cache_addw(0x1a00 + templosav + (templosav << 3) + (templo1 << 6)); // sub templosav, templosav, templo1 + cache_addw( SUB_REG(templosav, templosav, templo1) ); // sub templosav, templosav, templo1 gen_mov_word_from_reg_helper(templosav, dest, dword, templo2); cache_checkinstr(2); - cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 } // effective address calculation, destination is dest_reg @@ -534,11 +626,11 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { if (scale) { cache_checkinstr(4); - cache_addw(0x0000 + templo1 + (scale_reg << 3) + (scale << 6)); // lsl templo1, scale_reg, #(scale) - cache_addw(0x1800 + dest_reg + (dest_reg << 3) + (templo1 << 6)); // add dest_reg, dest_reg, templo1 + cache_addw( LSL_IMM(templo1, scale_reg, scale) ); // lsl templo1, scale_reg, #(scale) + cache_addw( ADD_REG(dest_reg, dest_reg, templo1) ); // add dest_reg, dest_reg, templo1 } else { cache_checkinstr(2); - cache_addw(0x1800 + dest_reg + (dest_reg << 3) + (scale_reg << 6)); // add dest_reg, dest_reg, scale_reg + cache_addw( ADD_REG(dest_reg, dest_reg, scale_reg) ); // add dest_reg, dest_reg, scale_reg } gen_add_imm(dest_reg, imm); } @@ -549,7 +641,7 @@ static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits im static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { if (scale) { cache_checkinstr(2); - cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (scale << 6)); // lsl dest_reg, dest_reg, #(scale) + cache_addw( LSL_IMM(dest_reg, dest_reg, scale) ); // lsl dest_reg, dest_reg, #(scale) } gen_add_imm(dest_reg, imm); } @@ -562,23 +654,23 @@ static void gen_call_function_helper(void * func) { *(Bit32u*)datapos=(Bit32u)func; if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 4)) >> 2)); // ldr templo1, [pc, datapos] - cache_addw(0xa000 + (templo2 << 8) + (8 >> 2)); // adr templo2, after_call (add templo2, pc, #8) - cache_addw(0x3000 + (templo2 << 8) + (1)); // add templo2, #1 - cache_addw(0x4680 + (HOST_lr - HOST_r8) + (templo2 << 3)); // mov lr, templo2 - cache_addw(0x4700 + (templo1 << 3)); // bx templo1 --- switch to arm state - cache_addw(0x46c0); // nop + cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 4)) ); // ldr templo1, [pc, datapos] + cache_addw( ADD_LO_PC_IMM(templo2, 8) ); // adr templo2, after_call (add templo2, pc, #8) + cache_addw( ADD_IMM8(templo2, 1) ); // add templo2, #1 + cache_addw( MOV_HI_LO(HOST_lr, templo2) ); // mov lr, templo2 + cache_addw( BX(templo1) ); // bx templo1 --- switch to arm state + cache_addw( NOP ); // nop } else { - cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 2)) >> 2)); // ldr templo1, [pc, datapos] - cache_addw(0xa000 + (templo2 << 8) + (4 >> 2)); // adr templo2, after_call (add templo2, pc, #4) - cache_addw(0x3000 + (templo2 << 8) + (1)); // add templo2, #1 - cache_addw(0x4680 + (HOST_lr - HOST_r8) + (templo2 << 3)); // mov lr, templo2 - cache_addw(0x4700 + (templo1 << 3)); // bx templo1 --- switch to arm state + cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 2)) ); // ldr templo1, [pc, datapos] + cache_addw( ADD_LO_PC_IMM(templo2, 4) ); // adr templo2, after_call (add templo2, pc, #4) + cache_addw( ADD_IMM8(templo2, 1) ); // add templo2, #1 + cache_addw( MOV_HI_LO(HOST_lr, templo2) ); // mov lr, templo2 + cache_addw( BX(templo1) ); // bx templo1 --- switch to arm state } // after_call: // thumb state from now on - cache_addw(0x1c00 + FC_RETOP + (HOST_a1 << 3)); // mov FC_RETOP, a1 + cache_addw( MOV_REG(FC_RETOP, HOST_a1) ); // mov FC_RETOP, a1 } // generate a call to a parameterless function @@ -629,42 +721,42 @@ static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { // jump to an address pointed at by ptr, offset is in imm static void gen_jmp_ptr(void * ptr,Bits imm=0) { cache_checkinstr(2); - cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_word_to_reg(templosav, ptr, 1); if (imm) { gen_mov_dword_to_reg_imm(templo2, imm); cache_checkinstr(2); - cache_addw(0x1800 + templosav + (templosav << 3) + (templo2 << 6)); // add templosav, templosav, templo2 + cache_addw( ADD_REG(templosav, templosav, templo2) ); // add templosav, templosav, templo2 } #if (1) // (*ptr) should be word aligned if ((imm & 0x03) == 0) { cache_checkinstr(8); - cache_addw(0x6800 + templo2 + (templosav << 3)); // ldr templo2, [templosav] + cache_addw( LDR_IMM(templo2, templosav, 0) ); // ldr templo2, [templosav] } else #endif { cache_checkinstr(26); - cache_addw(0x7800 + templo2 + (templosav << 3)); // ldrb templo2, [templosav] - cache_addw(0x7800 + templo1 + (templosav << 3) + (1 << 6)); // ldrb templo1, [templosav, #1] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (8 << 6)); // lsl templo1, templo1, #8 - cache_addw(0x4300 + templo2 + (templo1 << 3)); // orr templo2, templo1 - cache_addw(0x7800 + templo1 + (templosav << 3) + (2 << 6)); // ldrb templo1, [templosav, #2] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (16 << 6)); // lsl templo1, templo1, #16 - cache_addw(0x4300 + templo2 + (templo1 << 3)); // orr templo2, templo1 - cache_addw(0x7800 + templo1 + (templosav << 3) + (3 << 6)); // ldrb templo1, [templosav, #3] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (24 << 6)); // lsl templo1, templo1, #24 - cache_addw(0x4300 + templo2 + (templo1 << 3)); // orr templo2, templo1 + cache_addw( LDRB_IMM(templo2, templosav, 0) ); // ldrb templo2, [templosav] + cache_addw( LDRB_IMM(templo1, templosav, 1) ); // ldrb templo1, [templosav, #1] + cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 + cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 + cache_addw( LDRB_IMM(templo1, templosav, 2) ); // ldrb templo1, [templosav, #2] + cache_addw( LSL_IMM(templo1, templo1, 16) ); // lsl templo1, templo1, #16 + cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 + cache_addw( LDRB_IMM(templo1, templosav, 3) ); // ldrb templo1, [templosav, #3] + cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 + cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 } // increase jmp address to keep thumb state - cache_addw(0x1c00 + templo2 + (templo2 << 3) + (1 << 6)); // add templo2, templo2, #1 + cache_addw( ADD_IMM3(templo2, templo2, 1) ); // add templo2, templo2, #1 - cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 - cache_addw(0x4700 + (templo2 << 3)); // bx templo2 + cache_addw( BX(templo2) ); // bx templo2 } // short conditional jump (+-127 bytes) if register is zero @@ -672,11 +764,11 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { cache_checkinstr(4); if (dword) { - cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 } else { - cache_addw(0x0000 + templo1 + (reg << 3) + (16 << 6)); // lsl templo1, reg, #16 + cache_addw( LSL_IMM(templo1, reg, 16) ); // lsl templo1, reg, #16 } - cache_addw(0xd000); // beq j + cache_addw( BEQ_FWD(0) ); // beq j return ((Bit32u)cache.pos-2); } @@ -685,11 +777,11 @@ static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { cache_checkinstr(4); if (dword) { - cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 } else { - cache_addw(0x0000 + templo1 + (reg << 3) + (16 << 6)); // lsl templo1, reg, #16 + cache_addw( LSL_IMM(templo1, reg, 16) ); // lsl templo1, reg, #16 } - cache_addw(0xd100); // bne j + cache_addw( BNE_FWD(0) ); // bne j return ((Bit32u)cache.pos-2); } @@ -714,17 +806,17 @@ static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { datapos = cache_reservedata(); if (isdword) { - cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 } else { - cache_addw(0x0000 + templo2 + (reg << 3) + (24 << 6)); // lsl templo2, reg, #24 + cache_addw( LSL_IMM(templo2, reg, 24) ); // lsl templo2, reg, #24 } - cache_addw(0xd000 + (2 >> 1)); // beq nobranch (pc+2) + cache_addw( BEQ_FWD(2) ); // beq nobranch (pc+2) if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 4)) >> 2)); // ldr templo1, [pc, datapos] + cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 4)) ); // ldr templo1, [pc, datapos] } else { - cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 2)) >> 2)); // ldr templo1, [pc, datapos] + cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 2)) ); // ldr templo1, [pc, datapos] } - cache_addw(0x4700 + (templo1 << 3)); // bx templo1 + cache_addw( BX(templo1) ); // bx templo1 // nobranch: return ((Bit32u)datapos); } @@ -736,14 +828,14 @@ static Bit32u gen_create_branch_long_leqzero(HostReg reg) { cache_checkinstr(8); datapos = cache_reservedata(); - cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 - cache_addw(0xdc00 + (2 >> 1)); // bgt nobranch (pc+2) + cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 + cache_addw( BGT_FWD(2) ); // bgt nobranch (pc+2) if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 4)) >> 2)); // ldr templo1, [pc, datapos] + cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 4)) ); // ldr templo1, [pc, datapos] } else { - cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 2)) >> 2)); // ldr templo1, [pc, datapos] + cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 2)) ); // ldr templo1, [pc, datapos] } - cache_addw(0x4700 + (templo1 << 3)); // bx templo1 + cache_addw( BX(templo1) ); // bx templo1 // nobranch: return ((Bit32u)datapos); } @@ -761,39 +853,39 @@ static void gen_run_code(void) { // thumb state from now on cache_addw(0xb500); // push {lr} - cache_addw(0x4640 + HOST_r3 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov r3, FC_SEGS_ADDR - cache_addw(0x4640 + HOST_r2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov r2, FC_REGS_ADDR + cache_addw( MOV_LO_HI(HOST_r3, FC_SEGS_ADDR) ); // mov r3, FC_SEGS_ADDR + cache_addw( MOV_LO_HI(HOST_r2, FC_REGS_ADDR) ); // mov r2, FC_REGS_ADDR cache_addw(0xb4fc); // push {r2,r3,v1-v4} // adr: 16 - cache_addw(0x4800 + (HOST_r3 << 8) + ((64 - (16 + 4)) >> 2)); // ldr r3, [pc, #(&Segs)] + cache_addw( LDR_PC_IMM(HOST_r3, 64 - (16 + 4)) ); // ldr r3, [pc, #(&Segs)] // adr: 18 - cache_addw(0x4800 + (HOST_r2 << 8) + ((68 - (18 + 2)) >> 2)); // ldr r2, [pc, #(&cpu_regs)] - cache_addw(0x4680 + (FC_SEGS_ADDR - HOST_r8) + (HOST_r3 << 3)); // mov FC_SEGS_ADDR, r3 - cache_addw(0x4680 + (FC_REGS_ADDR - HOST_r8) + (HOST_r2 << 3)); // mov FC_REGS_ADDR, r2 + cache_addw( LDR_PC_IMM(HOST_r2, 68 - (18 + 2)) ); // ldr r2, [pc, #(&cpu_regs)] + cache_addw( MOV_HI_LO(FC_SEGS_ADDR, HOST_r3) ); // mov FC_SEGS_ADDR, r3 + cache_addw( MOV_HI_LO(FC_REGS_ADDR, HOST_r2) ); // mov FC_REGS_ADDR, r2 // align 4 - - cache_addw(0xa302); // add r3, pc, #8 - cache_addw(0x3001); // add r0, #1 - cache_addw(0x3301); // add r3, #1 + cache_addw( ADD_LO_PC_IMM(HOST_r3, 8) ); // add r3, pc, #8 + cache_addw( ADD_IMM8(HOST_r0, 1) ); // add r0, #1 + cache_addw( ADD_IMM8(HOST_r3, 1) ); // add r3, #1 cache_addw(0xb408); // push {r3} - cache_addw(0x4700); // bx r0 - cache_addw(0x46c0); // nop + cache_addw( BX(HOST_r0) ); // bx r0 + cache_addw( NOP ); // nop // align 4 cache_addw(0xbcfc); // pop {r2,r3,v1-v4} - cache_addw(0x4680 + (FC_SEGS_ADDR - HOST_r8) + (HOST_r3 << 3)); // mov FC_SEGS_ADDR, r3 - cache_addw(0x4680 + (FC_REGS_ADDR - HOST_r8) + (HOST_r2 << 3)); // mov FC_REGS_ADDR, r2 + cache_addw( MOV_HI_LO(FC_SEGS_ADDR, HOST_r3) ); // mov FC_SEGS_ADDR, r3 + cache_addw( MOV_HI_LO(FC_REGS_ADDR, HOST_r2) ); // mov FC_REGS_ADDR, r2 cache_addw(0xbc08); // pop {r3} - cache_addw(0x4718); // bx r3 + cache_addw( BX(HOST_r3) ); // bx r3 + // fill up to 64 bytes - cache_addw(0x46c0); // nop - cache_addd(0x46c046c0); // nop, nop - cache_addd(0x46c046c0); // nop, nop - cache_addd(0x46c046c0); // nop, nop - cache_addd(0x46c046c0); // nop, nop + cache_addw( NOP ); // nop + cache_addd( NOP | (NOP << 16) ); // nop, nop + cache_addd( NOP | (NOP << 16) ); // nop, nop + cache_addd( NOP | (NOP << 16) ); // nop, nop + cache_addd( NOP | (NOP << 16) ); // nop, nop // adr: 64 cache_addd((Bit32u)&Segs); // address of "Segs" @@ -804,16 +896,16 @@ static void gen_run_code(void) { // return from a function static void gen_return_function(void) { cache_checkinstr(6); - cache_addw(0x1c00 + HOST_a1 + (FC_RETOP << 3)); // mov a1, FC_RETOP + cache_addw( MOV_REG(HOST_a1, FC_RETOP) ); // mov a1, FC_RETOP cache_addw(0xbc08); // pop {r3} - cache_addw(0x4718); // bx r3 + cache_addw( BX(HOST_r3) ); // bx r3 } // short unconditional jump (over data pool) // must emit at most CACHE_DATA_JUMP bytes static void INLINE gen_create_branch_short(void * func) { - cache_addw(0xe000 + (((Bit32u)func - ((Bit32u)cache.pos + 4)) >> 1) ); // b func + cache_addw( B_FWD((Bit32u)func - ((Bit32u)cache.pos + 4)) ); // b func } @@ -838,35 +930,35 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: - *(Bit16u*)pos=0x1800 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // add FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=0xe000 + (8 >> 1); // b after_call (pc+8) + *(Bit16u*)pos=ADD_REG(FC_RETOP, HOST_a1, HOST_a2); // add FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(8); // b after_call (pc+8) break; case t_ORb: case t_ORw: case t_ORd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4300 + FC_RETOP + (HOST_a2 << 3); // orr FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (6 >> 1); // b after_call (pc+6) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=ORR(FC_RETOP, HOST_a2); // orr FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6) break; case t_ANDb: case t_ANDw: case t_ANDd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4000 + FC_RETOP + (HOST_a2 << 3); // and FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (6 >> 1); // b after_call (pc+6) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=AND(FC_RETOP, HOST_a2); // and FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6) break; case t_SUBb: case t_SUBw: case t_SUBd: - *(Bit16u*)pos=0x1a00 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // sub FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=0xe000 + (8 >> 1); // b after_call (pc+8) + *(Bit16u*)pos=SUB_REG(FC_RETOP, HOST_a1, HOST_a2); // sub FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(8); // b after_call (pc+8) break; case t_XORb: case t_XORw: case t_XORd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4040 + FC_RETOP + (HOST_a2 << 3); // eor FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (6 >> 1); // b after_call (pc+6) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=EOR(FC_RETOP, HOST_a2); // eor FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6) break; case t_CMPb: case t_CMPw: @@ -874,117 +966,117 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit16u*)pos=0xe000 + (10 >> 1); // b after_call (pc+10) + *(Bit16u*)pos=B_FWD(10); // b after_call (pc+10) break; case t_INCb: case t_INCw: case t_INCd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // add FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=0xe000 + (8 >> 1); // b after_call (pc+8) + *(Bit16u*)pos=ADD_IMM3(FC_RETOP, HOST_a1, 1); // add FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(8); // b after_call (pc+8) break; case t_DECb: case t_DECw: case t_DECd: - *(Bit16u*)pos=0x1e00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // sub FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=0xe000 + (8 >> 1); // b after_call (pc+8) + *(Bit16u*)pos=SUB_IMM3(FC_RETOP, HOST_a1, 1); // sub FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(8); // b after_call (pc+8) break; case t_SHLb: case t_SHLw: case t_SHLd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4080 + FC_RETOP + (HOST_a2 << 3); // lsl FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (6 >> 1); // b after_call (pc+6) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=LSL_REG(FC_RETOP, HOST_a2); // lsl FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6) break; case t_SHRb: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // lsr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (4 >> 1); // b after_call (pc+4) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 24); // lsr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(4); // b after_call (pc+4) break; case t_SHRw: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // lsr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (4 >> 1); // b after_call (pc+4) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 16); // lsr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(4); // b after_call (pc+4) break; case t_SHRd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (6 >> 1); // b after_call (pc+6) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6) break; case t_SARb: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // asr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (4 >> 1); // b after_call (pc+4) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 24); // asr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(4); // b after_call (pc+4) break; case t_SARw: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // asr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (4 >> 1); // b after_call (pc+4) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 16); // asr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(4); // b after_call (pc+4) break; case t_SARd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (6 >> 1); // b after_call (pc+6) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6) break; case t_RORb: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+4)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP - *(Bit16u*)(pos+6)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=0x46c0; // nop - *(Bit16u*)(pos+12)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+4)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP + *(Bit16u*)(pos+6)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=NOP; // nop + *(Bit16u*)(pos+12)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 break; case t_RORw: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=0x46c0; // nop - *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+6)=0x46c0; // nop - *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=0x46c0; // nop - *(Bit16u*)(pos+12)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=NOP; // nop + *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+6)=NOP; // nop + *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=NOP; // nop + *(Bit16u*)(pos+12)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 break; case t_RORd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (6 >> 1); // b after_call (pc+6) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6) break; /*case t_ROLb: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 - *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 - *(Bit16u*)(pos+8)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP - *(Bit16u*)(pos+10)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+12)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+14)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 + *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)(pos+8)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP + *(Bit16u*)(pos+10)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+12)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+14)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 break;*/ case t_ROLw: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 - *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 - *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=0x46c0; // nop - *(Bit16u*)(pos+12)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 + *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=NOP; // nop + *(Bit16u*)(pos+12)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 break; case t_ROLd: - *(Bit16u*)pos=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 - *(Bit16u*)(pos+2)=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+4)=0x46c0; // nop - *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 - *(Bit16u*)(pos+8)=0x46c0; // nop - *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+12)=0x46c0; // nop + *(Bit16u*)pos=NEG(templo1, HOST_a2); // neg templo1, a2 + *(Bit16u*)(pos+2)=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+4)=NOP; // nop + *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)(pos+8)=NOP; // nop + *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+12)=NOP; // nop break; case t_NEGb: case t_NEGw: case t_NEGd: - *(Bit16u*)pos=0x4240 + FC_RETOP + (HOST_a1 << 3); // neg FC_RETOP, a1 - *(Bit16u*)(pos+2)=0xe000 + (8 >> 1); // b after_call (pc+8) + *(Bit16u*)pos=NEG(FC_RETOP, HOST_a1); // neg FC_RETOP, a1 + *(Bit16u*)(pos+2)=B_FWD(8); // b after_call (pc+8) break; default: *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 4) ) = (Bit32u)fct_ptr; // simple_func @@ -998,35 +1090,35 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: - *(Bit16u*)pos=0x1800 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // add FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=0xe000 + (6 >> 1); // b after_call (pc+6) + *(Bit16u*)pos=ADD_REG(FC_RETOP, HOST_a1, HOST_a2); // add FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) break; case t_ORb: case t_ORw: case t_ORd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4300 + FC_RETOP + (HOST_a2 << 3); // orr FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (4 >> 1); // b after_call (pc+4) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=ORR(FC_RETOP, HOST_a2); // orr FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4) break; case t_ANDb: case t_ANDw: case t_ANDd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4000 + FC_RETOP + (HOST_a2 << 3); // and FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (4 >> 1); // b after_call (pc+4) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=AND(FC_RETOP, HOST_a2); // and FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4) break; case t_SUBb: case t_SUBw: case t_SUBd: - *(Bit16u*)pos=0x1a00 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // sub FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=0xe000 + (6 >> 1); // b after_call (pc+6) + *(Bit16u*)pos=SUB_REG(FC_RETOP, HOST_a1, HOST_a2); // sub FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) break; case t_XORb: case t_XORw: case t_XORd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4040 + FC_RETOP + (HOST_a2 << 3); // eor FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (4 >> 1); // b after_call (pc+4) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=EOR(FC_RETOP, HOST_a2); // eor FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4) break; case t_CMPb: case t_CMPw: @@ -1034,121 +1126,121 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit16u*)pos=0xe000 + (8 >> 1); // b after_call (pc+8) + *(Bit16u*)pos=B_FWD(8); // b after_call (pc+8) break; case t_INCb: case t_INCw: case t_INCd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // add FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=0xe000 + (6 >> 1); // b after_call (pc+6) + *(Bit16u*)pos=ADD_IMM3(FC_RETOP, HOST_a1, 1); // add FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) break; case t_DECb: case t_DECw: case t_DECd: - *(Bit16u*)pos=0x1e00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // sub FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=0xe000 + (6 >> 1); // b after_call (pc+6) + *(Bit16u*)pos=SUB_IMM3(FC_RETOP, HOST_a1, 1); // sub FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) break; case t_SHLb: case t_SHLw: case t_SHLd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4080 + FC_RETOP + (HOST_a2 << 3); // lsl FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (4 >> 1); // b after_call (pc+4) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=LSL_REG(FC_RETOP, HOST_a2); // lsl FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4) break; case t_SHRb: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=0x46c0; // nop - *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // lsr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+6)=0x46c0; // nop - *(Bit16u*)(pos+8)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+10)=0x46c0; // nop + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=NOP; // nop + *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, FC_RETOP, 24); // lsr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+6)=NOP; // nop + *(Bit16u*)(pos+8)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+10)=NOP; // nop break; case t_SHRw: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=0x46c0; // nop - *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // lsr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+6)=0x46c0; // nop - *(Bit16u*)(pos+8)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+10)=0x46c0; // nop + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=NOP; // nop + *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, FC_RETOP, 16); // lsr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+6)=NOP; // nop + *(Bit16u*)(pos+8)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+10)=NOP; // nop break; case t_SHRd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (4 >> 1); // b after_call (pc+4) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4) break; case t_SARb: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=0x46c0; // nop - *(Bit16u*)(pos+4)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // asr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+6)=0x46c0; // nop - *(Bit16u*)(pos+8)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 - *(Bit16u*)(pos+10)=0x46c0; // nop + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=NOP; // nop + *(Bit16u*)(pos+4)=ASR_IMM(FC_RETOP, FC_RETOP, 24); // asr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+6)=NOP; // nop + *(Bit16u*)(pos+8)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 + *(Bit16u*)(pos+10)=NOP; // nop break; case t_SARw: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=0x46c0; // nop - *(Bit16u*)(pos+4)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // asr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+6)=0x46c0; // nop - *(Bit16u*)(pos+8)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 - *(Bit16u*)(pos+10)=0x46c0; // nop + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=NOP; // nop + *(Bit16u*)(pos+4)=ASR_IMM(FC_RETOP, FC_RETOP, 16); // asr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+6)=NOP; // nop + *(Bit16u*)(pos+8)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 + *(Bit16u*)(pos+10)=NOP; // nop break; case t_SARd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (4 >> 1); // b after_call (pc+4) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4) break; case t_RORb: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+4)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP - *(Bit16u*)(pos+6)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+4)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP + *(Bit16u*)(pos+6)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 break; case t_RORw: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+4)=0x46c0; // nop - *(Bit16u*)(pos+6)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+8)=0x46c0; // nop - *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+4)=NOP; // nop + *(Bit16u*)(pos+6)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+8)=NOP; // nop + *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 break; case t_RORd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (4 >> 1); // b after_call (pc+4) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4) break; /*case t_ROLb: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 - *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 - *(Bit16u*)(pos+8)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP - *(Bit16u*)(pos+10)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+12)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+14)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 + *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)(pos+8)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP + *(Bit16u*)(pos+10)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+12)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+14)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 break;*/ case t_ROLw: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 - *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 - *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 + *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 break; case t_ROLd: - *(Bit16u*)pos=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 - *(Bit16u*)(pos+2)=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+4)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 - *(Bit16u*)(pos+6)=0x46c0; // nop - *(Bit16u*)(pos+8)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+10)=0x46c0; // nop + *(Bit16u*)pos=NEG(templo1, HOST_a2); // neg templo1, a2 + *(Bit16u*)(pos+2)=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+4)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)(pos+6)=NOP; // nop + *(Bit16u*)(pos+8)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+10)=NOP; // nop break; case t_NEGb: case t_NEGw: case t_NEGd: - *(Bit16u*)pos=0x4240 + FC_RETOP + (HOST_a1 << 3); // neg FC_RETOP, a1 - *(Bit16u*)(pos+2)=0xe000 + (6 >> 1); // b after_call (pc+6) + *(Bit16u*)pos=NEG(FC_RETOP, HOST_a1); // neg FC_RETOP, a1 + *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) break; default: *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 2) ) = (Bit32u)fct_ptr; // simple_func @@ -1175,23 +1267,23 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { cache_checkinstr(4); - cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR - cache_addw(0x8800 + dest_reg + (templo1 << 3) + (index << 5)); // ldrh dest_reg, [templo1, #index] + cache_addw( MOV_LO_HI(templo1, FC_SEGS_ADDR) ); // mov templo1, FC_SEGS_ADDR + cache_addw( LDRH_IMM(dest_reg, templo1, index) ); // ldrh dest_reg, [templo1, #index] } // mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { cache_checkinstr(4); - cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR - cache_addw(0x6800 + dest_reg + (templo1 << 3) + (index << 4)); // ldr dest_reg, [templo1, #index] + cache_addw( MOV_LO_HI(templo1, FC_SEGS_ADDR) ); // mov templo1, FC_SEGS_ADDR + cache_addw( LDR_IMM(dest_reg, templo1, index) ); // ldr dest_reg, [templo1, #index] } // add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { cache_checkinstr(6); - cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR - cache_addw(0x6800 + templo2 + (templo1 << 3) + (index << 4)); // ldr templo2, [templo1, #index] - cache_addw(0x1800 + reg + (reg << 3) + (templo2 << 6)); // add reg, reg, templo2 + cache_addw( MOV_LO_HI(templo1, FC_SEGS_ADDR) ); // mov templo1, FC_SEGS_ADDR + cache_addw( LDR_IMM(templo2, templo1, index) ); // ldr templo2, [templo1, #index] + cache_addw( ADD_REG(reg, reg, templo2) ); // add reg, reg, templo2 } #endif @@ -1202,26 +1294,26 @@ static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { cache_checkinstr(4); - cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR - cache_addw(0x8800 + dest_reg + (templo2 << 3) + (index << 5)); // ldrh dest_reg, [templo2, #index] + cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR + cache_addw( LDRH_IMM(dest_reg, templo2, index) ); // ldrh dest_reg, [templo2, #index] } // mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { cache_checkinstr(4); - cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR - cache_addw(0x6800 + dest_reg + (templo2 << 3) + (index << 4)); // ldr dest_reg, [templo2, #index] + cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR + cache_addw( LDR_IMM(dest_reg, templo2, index) ); // ldr dest_reg, [templo2, #index] } // move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { cache_checkinstr(4); - cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR if (dword) { - cache_addw(0x6800 + dest_reg + (templo2 << 3) + (index << 4)); // ldr dest_reg, [templo2, #index] + cache_addw( LDR_IMM(dest_reg, templo2, index) ); // ldr dest_reg, [templo2, #index] } else { - cache_addw(0x8800 + dest_reg + (templo2 << 3) + (index << 5)); // ldrh dest_reg, [templo2, #index] + cache_addw( LDRH_IMM(dest_reg, templo2, index) ); // ldrh dest_reg, [templo2, #index] } } @@ -1231,8 +1323,8 @@ static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { // registers might not be directly byte-accessible on some architectures static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { cache_checkinstr(4); - cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR - cache_addw(0x7800 + dest_reg + (templo2 << 3) + (index << 6)); // ldrb dest_reg, [templo2, #index] + cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR + cache_addw( LDRB_IMM(dest_reg, templo2, index) ); // ldrb dest_reg, [templo2, #index] } // move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR @@ -1241,49 +1333,50 @@ static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { // not directly byte-accessible on some architectures static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { cache_checkinstr(4); - cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR - cache_addw(0x7800 + dest_reg + (templo2 << 3) + (index << 6)); // ldrb dest_reg, [templo2, #index] + cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR + cache_addw( LDRB_IMM(dest_reg, templo2, index) ); // ldrb dest_reg, [templo2, #index] } // add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { cache_checkinstr(6); - cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR - cache_addw(0x6800 + templo1 + (templo2 << 3) + (index << 4)); // ldr templo1, [templo2, #index] - cache_addw(0x1800 + reg + (reg << 3) + (templo1 << 6)); // add reg, reg, templo1 + cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR + cache_addw( LDR_IMM(templo1, templo2, index) ); // ldr templo1, [templo2, #index] + cache_addw( ADD_REG(reg, reg, templo1) ); // add reg, reg, templo1 } // move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { cache_checkinstr(4); - cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR - cache_addw(0x8000 + src_reg + (templo1 << 3) + (index << 5)); // strh src_reg, [templo1, #index] + cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR + cache_addw( STRH_IMM(src_reg, templo1, index) ); // strh src_reg, [templo1, #index] } // move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { cache_checkinstr(4); - cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR - cache_addw(0x6000 + src_reg + (templo1 << 3) + (index << 4)); // str src_reg, [templo1, #index] + cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR + cache_addw( STR_IMM(src_reg, templo1, index) ); // str src_reg, [templo1, #index] } // move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { cache_checkinstr(4); - cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR if (dword) { - cache_addw(0x6000 + src_reg + (templo1 << 3) + (index << 4)); // str src_reg, [templo1, #index] + cache_addw( STR_IMM(src_reg, templo1, index) ); // str src_reg, [templo1, #index] } else { - cache_addw(0x8000 + src_reg + (templo1 << 3) + (index << 5)); // strh src_reg, [templo1, #index] + cache_addw( STRH_IMM(src_reg, templo1, index) ); // strh src_reg, [templo1, #index] } } // move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { cache_checkinstr(4); - cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR - cache_addw(0x7000 + src_reg + (templo1 << 3) + (index << 6)); // strb src_reg, [templo1, #index] + cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR + cache_addw( STRB_IMM(src_reg, templo1, index) ); // strb src_reg, [templo1, #index] } + #endif diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h index e994c731..d8618f12 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-thumb-niw.h,v 1.2 2008-09-19 16:48:02 c2woody Exp $ */ +/* $Id: risc_armv4le-thumb-niw.h,v 1.3 2009-05-16 21:52:47 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (thumb version with data pool) */ @@ -64,6 +64,97 @@ #endif +// instruction encodings + +// move +// mov dst, #imm @ 0 <= imm <= 255 +#define MOV_IMM(dst, imm) (0x2000 + ((dst) << 8) + (imm) ) +// mov dst, src +#define MOV_REG(dst, src) ADD_IMM3(dst, src, 0) +// mov dst, src +#define MOV_LO_HI(dst, src) (0x4640 + (dst) + (((src) - HOST_r8) << 3) ) +// mov dst, src +#define MOV_HI_LO(dst, src) (0x4680 + ((dst) - HOST_r8) + ((src) << 3) ) + +// arithmetic +// add dst, src, #imm @ 0 <= imm <= 7 +#define ADD_IMM3(dst, src, imm) (0x1c00 + (dst) + ((src) << 3) + ((imm) << 6) ) +// add dst, #imm @ 0 <= imm <= 255 +#define ADD_IMM8(dst, imm) (0x3000 + ((dst) << 8) + (imm) ) +// add dst, src1, src2 +#define ADD_REG(dst, src1, src2) (0x1800 + (dst) + ((src1) << 3) + ((src2) << 6) ) +// add dst, src +#define ADD_LO_HI(dst, src) (0x4440 + (dst) + (((src) - HOST_r8) << 3) ) +// add dst, pc, #imm @ 0 <= imm < 1024 & imm mod 4 = 0 +#define ADD_LO_PC_IMM(dst, imm) (0xa000 + ((dst) << 8) + ((imm) >> 2) ) +// sub dst, src1, src2 +#define SUB_REG(dst, src1, src2) (0x1a00 + (dst) + ((src1) << 3) + ((src2) << 6) ) +// sub dst, src, #imm @ 0 <= imm <= 7 +#define SUB_IMM3(dst, src, imm) (0x1e00 + (dst) + ((src) << 3) + ((imm) << 6) ) +// sub dst, #imm @ 0 <= imm <= 255 +#define SUB_IMM8(dst, imm) (0x3800 + ((dst) << 8) + (imm) ) +// neg dst, src +#define NEG(dst, src) (0x4240 + (dst) + ((src) << 3) ) +// cmp dst, #imm @ 0 <= imm <= 255 +#define CMP_IMM(dst, imm) (0x2800 + ((dst) << 8) + (imm) ) +// nop +#define NOP (0x46c0) + +// logical +// and dst, src +#define AND(dst, src) (0x4000 + (dst) + ((src) << 3) ) +// eor dst, src +#define EOR(dst, src) (0x4040 + (dst) + ((src) << 3) ) +// orr dst, src +#define ORR(dst, src) (0x4300 + (dst) + ((src) << 3) ) + +// shift/rotate +// lsl dst, src, #imm +#define LSL_IMM(dst, src, imm) (0x0000 + (dst) + ((src) << 3) + ((imm) << 6) ) +// lsl dst, reg +#define LSL_REG(dst, reg) (0x4080 + (dst) + ((reg) << 3) ) +// lsr dst, src, #imm +#define LSR_IMM(dst, src, imm) (0x0800 + (dst) + ((src) << 3) + ((imm) << 6) ) +// lsr dst, reg +#define LSR_REG(dst, reg) (0x40c0 + (dst) + ((reg) << 3) ) +// asr dst, src, #imm +#define ASR_IMM(dst, src, imm) (0x1000 + (dst) + ((src) << 3) + ((imm) << 6) ) +// asr dst, reg +#define ASR_REG(dst, reg) (0x4100 + (dst) + ((reg) << 3) ) +// ror dst, reg +#define ROR_REG(dst, reg) (0x41c0 + (dst) + ((reg) << 3) ) + +// load +// ldr reg, [addr, #imm] @ 0 <= imm < 128 & imm mod 4 = 0 +#define LDR_IMM(reg, addr, imm) (0x6800 + (reg) + ((addr) << 3) + ((imm) << 4) ) +// ldrh reg, [addr, #imm] @ 0 <= imm < 64 & imm mod 2 = 0 +#define LDRH_IMM(reg, addr, imm) (0x8800 + (reg) + ((addr) << 3) + ((imm) << 5) ) +// ldrb reg, [addr, #imm] @ 0 <= imm < 32 +#define LDRB_IMM(reg, addr, imm) (0x7800 + (reg) + ((addr) << 3) + ((imm) << 6) ) +// ldr reg, [pc, #imm] @ 0 <= imm < 1024 & imm mod 4 = 0 +#define LDR_PC_IMM(reg, imm) (0x4800 + ((reg) << 8) + ((imm) >> 2) ) + +// store +// str reg, [addr, #imm] @ 0 <= imm < 128 & imm mod 4 = 0 +#define STR_IMM(reg, addr, imm) (0x6000 + (reg) + ((addr) << 3) + ((imm) << 4) ) +// strh reg, [addr, #imm] @ 0 <= imm < 64 & imm mod 2 = 0 +#define STRH_IMM(reg, addr, imm) (0x8000 + (reg) + ((addr) << 3) + ((imm) << 5) ) +// strb reg, [addr, #imm] @ 0 <= imm < 32 +#define STRB_IMM(reg, addr, imm) (0x7000 + (reg) + ((addr) << 3) + ((imm) << 6) ) + +// branch +// beq pc+imm @ 0 <= imm < 256 & imm mod 2 = 0 +#define BEQ_FWD(imm) (0xd000 + ((imm) >> 1) ) +// bne pc+imm @ 0 <= imm < 256 & imm mod 2 = 0 +#define BNE_FWD(imm) (0xd100 + ((imm) >> 1) ) +// bgt pc+imm @ 0 <= imm < 256 & imm mod 2 = 0 +#define BGT_FWD(imm) (0xdc00 + ((imm) >> 1) ) +// b pc+imm @ 0 <= imm < 2048 & imm mod 2 = 0 +#define B_FWD(imm) (0xe000 + ((imm) >> 1) ) +// bx reg +#define BX(reg) (0x4700 + ((reg) << 3) ) + + // data pool defines #define CACHE_DATA_JUMP (2) #define CACHE_DATA_ALIGN (32) @@ -75,6 +166,7 @@ static Bit8u * cache_datapos = NULL; // position of data pool in the cache block static Bit32u cache_datasize = 0; // total size of data pool static Bit32u cache_dataindex = 0; // used size of data pool = index of free data item (in bytes) in data pool + // forwarded function static void INLINE gen_create_branch_short(void * func); @@ -185,26 +277,26 @@ static void cache_block_before_close(void) { static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { if(reg_src == reg_dst) return; cache_checkinstr(2); - cache_addw(0x1c00 + reg_dst + (reg_src << 3)); // mov reg_dst, reg_src + cache_addw( MOV_REG(reg_dst, reg_src) ); // mov reg_dst, reg_src } // move a 32bit constant value into dest_reg static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { if ((imm & 0xffffff00) == 0) { cache_checkinstr(2); - cache_addw(0x2000 + (dest_reg << 8) + imm); // mov dest_reg, #(imm) + cache_addw( MOV_IMM(dest_reg, imm) ); // mov dest_reg, #(imm) } else if ((imm & 0xffff00ff) == 0) { cache_checkinstr(4); - cache_addw(0x2000 + (dest_reg << 8) + (imm >> 8)); // mov dest_reg, #(imm >> 8) - cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (8 << 6)); // lsl dest_reg, dest_reg, #8 + cache_addw( MOV_IMM(dest_reg, imm >> 8) ); // mov dest_reg, #(imm >> 8) + cache_addw( LSL_IMM(dest_reg, dest_reg, 8) ); // lsl dest_reg, dest_reg, #8 } else if ((imm & 0xff00ffff) == 0) { cache_checkinstr(4); - cache_addw(0x2000 + (dest_reg << 8) + (imm >> 16)); // mov dest_reg, #(imm >> 16) - cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (16 << 6)); // lsl dest_reg, dest_reg, #16 + cache_addw( MOV_IMM(dest_reg, imm >> 16) ); // mov dest_reg, #(imm >> 16) + cache_addw( LSL_IMM(dest_reg, dest_reg, 16) ); // lsl dest_reg, dest_reg, #16 } else if ((imm & 0x00ffffff) == 0) { cache_checkinstr(4); - cache_addw(0x2000 + (dest_reg << 8) + (imm >> 24)); // mov dest_reg, #(imm >> 24) - cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (24 << 6)); // lsl dest_reg, dest_reg, #24 + cache_addw( MOV_IMM(dest_reg, imm >> 24) ); // mov dest_reg, #(imm >> 24) + cache_addw( LSL_IMM(dest_reg, dest_reg, 24) ); // lsl dest_reg, dest_reg, #24 } else { Bit32u diff; @@ -214,10 +306,10 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { if ((diff < 1024) && ((imm & 0x03) == 0)) { if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw(0xa000 + (dest_reg << 8) + (diff >> 2)); // add dest_reg, pc, #(diff >> 2) + cache_addw( ADD_LO_PC_IMM(dest_reg, diff >> 2) ); // add dest_reg, pc, #(diff >> 2) } else { - cache_addw(0x46c0); // nop - cache_addw(0xa000 + (dest_reg << 8) + ((diff - 2) >> 2)); // add dest_reg, pc, #((diff - 2) >> 2) + cache_addw( NOP ); // nop + cache_addw( ADD_LO_PC_IMM(dest_reg, (diff - 2) >> 2) ); // add dest_reg, pc, #((diff - 2) >> 2) } } else { Bit8u *datapos; @@ -226,9 +318,9 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { *(Bit32u*)datapos=imm; if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw(0x4800 + (dest_reg << 8) + ((datapos - (cache.pos + 4)) >> 2)); // ldr dest_reg, [pc, datapos] + cache_addw( LDR_PC_IMM(dest_reg, datapos - (cache.pos + 4)) ); // ldr dest_reg, [pc, datapos] } else { - cache_addw(0x4800 + (dest_reg << 8) + ((datapos - (cache.pos + 2)) >> 2)); // ldr dest_reg, [pc, datapos] + cache_addw( LDR_PC_IMM(dest_reg, datapos - (cache.pos + 2)) ); // ldr dest_reg, [pc, datapos] } } } @@ -241,35 +333,35 @@ static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,Ho if ((Bit32u)data & 3) { if ( ((Bit32u)data & 3) == 2 ) { cache_checkinstr(8); - cache_addw(0x8800 + dest_reg + (data_reg << 3)); // ldrh dest_reg, [data_reg] - cache_addw(0x8800 + templo1 + (data_reg << 3) + (2 << 5)); // ldrh templo1, [data_reg, #2] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (16 << 6)); // lsl templo1, templo1, #16 - cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + cache_addw( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] + cache_addw( LDRH_IMM(templo1, data_reg, 2) ); // ldrh templo1, [data_reg, #2] + cache_addw( LSL_IMM(templo1, templo1, 16) ); // lsl templo1, templo1, #16 + cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 } else { cache_checkinstr(16); - cache_addw(0x7800 + dest_reg + (data_reg << 3)); // ldrb dest_reg, [data_reg] - cache_addw(0x1c00 + templo1 + (data_reg << 3) + (1 << 6)); // add templo1, data_reg, #1 - cache_addw(0x8800 + templo1 + (templo1 << 3)); // ldrh templo1, [templo1] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (8 << 6)); // lsl templo1, templo1, #8 - cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 - cache_addw(0x7800 + templo1 + (data_reg << 3) + (3 << 6)); // ldrb templo1, [data_reg, #3] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (24 << 6)); // lsl templo1, templo1, #24 - cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + cache_addw( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] + cache_addw( ADD_IMM3(templo1, data_reg, 1) ); // add templo1, data_reg, #1 + cache_addw( LDRH_IMM(templo1, templo1, 0) ); // ldrh templo1, [templo1] + cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 + cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 + cache_addw( LDRB_IMM(templo1, data_reg, 3) ); // ldrb templo1, [data_reg, #3] + cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 + cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 } } else { cache_checkinstr(2); - cache_addw(0x6800 + dest_reg + (data_reg << 3)); // ldr dest_reg, [data_reg] + cache_addw( LDR_IMM(dest_reg, data_reg, 0) ); // ldr dest_reg, [data_reg] } } else { if ((Bit32u)data & 1) { cache_checkinstr(8); - cache_addw(0x7800 + dest_reg + (data_reg << 3)); // ldrb dest_reg, [data_reg] - cache_addw(0x7800 + templo1 + (data_reg << 3) + (1 << 6)); // ldrb templo1, [data_reg, #1] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (8 << 6)); // lsl templo1, templo1, #8 - cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + cache_addw( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] + cache_addw( LDRB_IMM(templo1, data_reg, 1) ); // ldrb templo1, [data_reg, #1] + cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 + cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 } else { cache_checkinstr(2); - cache_addw(0x8800 + dest_reg + (data_reg << 3)); // ldrh dest_reg, [data_reg] + cache_addw( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] } } } @@ -294,37 +386,37 @@ static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, if ((Bit32u)dest & 3) { if ( ((Bit32u)dest & 3) == 2 ) { cache_checkinstr(8); - cache_addw(0x8000 + src_reg + (data_reg << 3)); // strh src_reg, [data_reg] - cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg - cache_addw(0x0800 + templo1 + (templo1 << 3) + (16 << 6)); // lsr templo1, templo1, #16 - cache_addw(0x8000 + templo1 + (data_reg << 3) + (2 << 5)); // strh templo1, [data_reg, #2] + cache_addw( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] + cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg + cache_addw( LSR_IMM(templo1, templo1, 16) ); // lsr templo1, templo1, #16 + cache_addw( STRH_IMM(templo1, data_reg, 2) ); // strh templo1, [data_reg, #2] } else { cache_checkinstr(20); - cache_addw(0x7000 + src_reg + (data_reg << 3)); // strb src_reg, [data_reg] - cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg - cache_addw(0x0800 + templo1 + (templo1 << 3) + (8 << 6)); // lsr templo1, templo1, #8 - cache_addw(0x7000 + templo1 + (data_reg << 3) + (1 << 6)); // strb templo1, [data_reg, #1] - cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg - cache_addw(0x0800 + templo1 + (templo1 << 3) + (16 << 6)); // lsr templo1, templo1, #16 - cache_addw(0x7000 + templo1 + (data_reg << 3) + (2 << 6)); // strb templo1, [data_reg, #2] - cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg - cache_addw(0x0800 + templo1 + (templo1 << 3) + (24 << 6)); // lsr templo1, templo1, #24 - cache_addw(0x7000 + templo1 + (data_reg << 3) + (3 << 6)); // strb templo1, [data_reg, #3] + cache_addw( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] + cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg + cache_addw( LSR_IMM(templo1, templo1, 8) ); // lsr templo1, templo1, #8 + cache_addw( STRB_IMM(templo1, data_reg, 1) ); // strb templo1, [data_reg, #1] + cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg + cache_addw( LSR_IMM(templo1, templo1, 16) ); // lsr templo1, templo1, #16 + cache_addw( STRB_IMM(templo1, data_reg, 2) ); // strb templo1, [data_reg, #2] + cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg + cache_addw( LSR_IMM(templo1, templo1, 24) ); // lsr templo1, templo1, #24 + cache_addw( STRB_IMM(templo1, data_reg, 3) ); // strb templo1, [data_reg, #3] } } else { cache_checkinstr(2); - cache_addw(0x6000 + src_reg + (data_reg << 3)); // str src_reg, [data_reg] + cache_addw( STR_IMM(src_reg, data_reg, 0) ); // str src_reg, [data_reg] } } else { if ((Bit32u)dest & 1) { cache_checkinstr(8); - cache_addw(0x7000 + src_reg + (data_reg << 3)); // strb src_reg, [data_reg] - cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg - cache_addw(0x0800 + templo1 + (templo1 << 3) + (8 << 6)); // lsr templo1, templo1, #8 - cache_addw(0x7000 + templo1 + (data_reg << 3) + (1 << 6)); // strb templo1, [data_reg, #1] + cache_addw( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] + cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg + cache_addw( LSR_IMM(templo1, templo1, 8) ); // lsr templo1, templo1, #8 + cache_addw( STRB_IMM(templo1, data_reg, 1) ); // strb templo1, [data_reg, #1] } else { cache_checkinstr(2); - cache_addw(0x8000 + src_reg + (data_reg << 3)); // strh src_reg, [data_reg] + cache_addw( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] } } } @@ -342,7 +434,7 @@ static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { gen_mov_dword_to_reg_imm(templo1, (Bit32u)data); cache_checkinstr(2); - cache_addw(0x7800 + dest_reg + (templo1 << 3)); // ldrb dest_reg, [templo1] + cache_addw( LDRB_IMM(dest_reg, templo1, 0) ); // ldrb dest_reg, [templo1] } // move an 8bit value from memory into dest_reg @@ -359,7 +451,7 @@ static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* dat // registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { cache_checkinstr(2); - cache_addw(0x2000 + (dest_reg << 8) + imm); // mov dest_reg, #(imm) + cache_addw( MOV_IMM(dest_reg, imm) ); // mov dest_reg, #(imm) } // move an 8bit constant value into dest_reg @@ -374,7 +466,7 @@ static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { gen_mov_dword_to_reg_imm(templo1, (Bit32u)dest); cache_checkinstr(2); - cache_addw(0x7000 + src_reg + (templo1 << 3)); // strb src_reg, [templo1] + cache_addw( STRB_IMM(src_reg, templo1, 0) ); // strb src_reg, [templo1] } @@ -383,12 +475,12 @@ static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { // the register is zero-extended (sign==false) or sign-extended (sign==true) static void gen_extend_byte(bool sign,HostReg reg) { cache_checkinstr(4); - cache_addw(0x0000 + reg + (reg << 3) + (24 << 6)); // lsl reg, reg, #24 + cache_addw( LSL_IMM(reg, reg, 24) ); // lsl reg, reg, #24 if (sign) { - cache_addw(0x1000 + reg + (reg << 3) + (24 << 6)); // asr reg, reg, #24 + cache_addw( ASR_IMM(reg, reg, 24) ); // asr reg, reg, #24 } else { - cache_addw(0x0800 + reg + (reg << 3) + (24 << 6)); // lsr reg, reg, #24 + cache_addw( LSR_IMM(reg, reg, 24) ); // lsr reg, reg, #24 } } @@ -396,22 +488,22 @@ static void gen_extend_byte(bool sign,HostReg reg) { // the register is zero-extended (sign==false) or sign-extended (sign==true) static void gen_extend_word(bool sign,HostReg reg) { cache_checkinstr(4); - cache_addw(0x0000 + reg + (reg << 3) + (16 << 6)); // lsl reg, reg, #16 + cache_addw( LSL_IMM(reg, reg, 16) ); // lsl reg, reg, #16 if (sign) { - cache_addw(0x1000 + reg + (reg << 3) + (16 << 6)); // asr reg, reg, #16 + cache_addw( ASR_IMM(reg, reg, 16) ); // asr reg, reg, #16 } else { - cache_addw(0x0800 + reg + (reg << 3) + (16 << 6)); // lsr reg, reg, #16 + cache_addw( LSR_IMM(reg, reg, 16) ); // lsr reg, reg, #16 } } // add a 32bit value from memory to a full register static void gen_add(HostReg reg,void* op) { cache_checkinstr(2); - cache_addw(0x4680 + (temphi1 - HOST_r8) + (reg << 3)); // mov temphi1, reg + cache_addw( MOV_HI_LO(temphi1, reg) ); // mov temphi1, reg gen_mov_word_to_reg(reg, op, 1); cache_checkinstr(2); - cache_addw(0x4440 + (reg) + ((temphi1 - HOST_r8) << 3)); // add reg, temphi1 + cache_addw( ADD_LO_HI(reg, temphi1) ); // add reg, temphi1 } // add a 32bit constant value to a full register @@ -419,7 +511,7 @@ static void gen_add_imm(HostReg reg,Bit32u imm) { if(!imm) return; gen_mov_dword_to_reg_imm(templo1, imm); cache_checkinstr(2); - cache_addw(0x1800 + reg + (reg << 3) + (templo1 << 6)); // add reg, reg, templo1 + cache_addw( ADD_REG(reg, reg, templo1) ); // add reg, reg, templo1 } // and a 32bit constant value with a full register @@ -427,18 +519,18 @@ static void gen_and_imm(HostReg reg,Bit32u imm) { if(imm == 0xffffffff) return; gen_mov_dword_to_reg_imm(templo1, imm); cache_checkinstr(2); - cache_addw(0x4000 + reg + (templo1<< 3)); // and reg, templo1 + cache_addw( AND(reg, templo1) ); // and reg, templo1 } // move a 32bit constant value into memory static void gen_mov_direct_dword(void* dest,Bit32u imm) { cache_checkinstr(2); - cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templosav, imm); gen_mov_word_from_reg(templosav, dest, 1); cache_checkinstr(2); - cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 } // move an address into memory @@ -450,18 +542,18 @@ static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { static void gen_add_direct_byte(void* dest,Bit8s imm) { if(!imm) return; cache_checkinstr(2); - cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); gen_mov_word_to_reg_helper(templosav, dest, 1, templo2); cache_checkinstr(2); if (imm >= 0) { - cache_addw(0x3000 + (templosav << 8) + ((Bit32s)imm)); // add templosav, #(imm) + cache_addw( ADD_IMM8(templosav, (Bit32s)imm) ); // add templosav, #(imm) } else { - cache_addw(0x3800 + (templosav << 8) + (-((Bit32s)imm))); // sub templosav, #(-imm) + cache_addw( SUB_IMM8(templosav, -((Bit32s)imm)) ); // sub templosav, #(-imm) } gen_mov_word_from_reg_helper(templosav, dest, 1, templo2); cache_checkinstr(2); - cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 } // add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value @@ -472,7 +564,7 @@ static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { return; } cache_checkinstr(2); - cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); gen_mov_word_to_reg_helper(templosav, dest, dword, templo2); if (dword) { @@ -481,28 +573,28 @@ static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); } cache_checkinstr(2); - cache_addw(0x1800 + templosav + (templosav << 3) + (templo1 << 6)); // add templosav, templosav, templo1 + cache_addw( ADD_REG(templosav, templosav, templo1) ); // add templosav, templosav, templo1 gen_mov_word_from_reg_helper(templosav, dest, dword, templo2); cache_checkinstr(2); - cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 } // subtract an 8bit constant value from a dword memory value static void gen_sub_direct_byte(void* dest,Bit8s imm) { if(!imm) return; cache_checkinstr(2); - cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); gen_mov_word_to_reg_helper(templosav, dest, 1, templo2); cache_checkinstr(2); if (imm >= 0) { - cache_addw(0x3800 + (templosav << 8) + ((Bit32s)imm)); // sub templosav, #(imm) + cache_addw( SUB_IMM8(templosav, (Bit32s)imm) ); // sub templosav, #(imm) } else { - cache_addw(0x3000 + (templosav << 8) + (-((Bit32s)imm))); // add templosav, #(-imm) + cache_addw( ADD_IMM8(templosav, -((Bit32s)imm)) ); // add templosav, #(-imm) } gen_mov_word_from_reg_helper(templosav, dest, 1, templo2); cache_checkinstr(2); - cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 } // subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value @@ -513,7 +605,7 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { return; } cache_checkinstr(2); - cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); gen_mov_word_to_reg_helper(templosav, dest, dword, templo2); if (dword) { @@ -522,10 +614,10 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); } cache_checkinstr(2); - cache_addw(0x1a00 + templosav + (templosav << 3) + (templo1 << 6)); // sub templosav, templosav, templo1 + cache_addw( SUB_REG(templosav, templosav, templo1) ); // sub templosav, templosav, templo1 gen_mov_word_from_reg_helper(templosav, dest, dword, templo2); cache_checkinstr(2); - cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 } // effective address calculation, destination is dest_reg @@ -534,11 +626,11 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { if (scale) { cache_checkinstr(4); - cache_addw(0x0000 + templo1 + (scale_reg << 3) + (scale << 6)); // lsl templo1, scale_reg, #(scale) - cache_addw(0x1800 + dest_reg + (dest_reg << 3) + (templo1 << 6)); // add dest_reg, dest_reg, templo1 + cache_addw( LSL_IMM(templo1, scale_reg, scale) ); // lsl templo1, scale_reg, #(scale) + cache_addw( ADD_REG(dest_reg, dest_reg, templo1) ); // add dest_reg, dest_reg, templo1 } else { cache_checkinstr(2); - cache_addw(0x1800 + dest_reg + (dest_reg << 3) + (scale_reg << 6)); // add dest_reg, dest_reg, scale_reg + cache_addw( ADD_REG(dest_reg, dest_reg, scale_reg) ); // add dest_reg, dest_reg, scale_reg } gen_add_imm(dest_reg, imm); } @@ -549,7 +641,7 @@ static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits im static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { if (scale) { cache_checkinstr(2); - cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (scale << 6)); // lsl dest_reg, dest_reg, #(scale) + cache_addw( LSL_IMM(dest_reg, dest_reg, scale) ); // lsl dest_reg, dest_reg, #(scale) } gen_add_imm(dest_reg, imm); } @@ -562,16 +654,16 @@ static void gen_call_function_helper(void * func) { *(Bit32u*)datapos=(Bit32u)func; if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 4)) >> 2)); // ldr templo1, [pc, datapos] - cache_addw(0xa000 + (templo2 << 8) + (4 >> 2)); // adr templo2, after_call (add templo2, pc, #4) - cache_addw(0x4680 + (HOST_lr - HOST_r8) + (templo2 << 3)); // mov lr, templo2 - cache_addw(0x4700 + (templo1 << 3)); // bx templo1 --- switch to arm state + cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 4)) ); // ldr templo1, [pc, datapos] + cache_addw( ADD_LO_PC_IMM(templo2, 4) ); // adr templo2, after_call (add templo2, pc, #4) + cache_addw( MOV_HI_LO(HOST_lr, templo2) ); // mov lr, templo2 + cache_addw( BX(templo1) ); // bx templo1 --- switch to arm state } else { - cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 2)) >> 2)); // ldr templo1, [pc, datapos] - cache_addw(0xa000 + (templo2 << 8) + (4 >> 2)); // adr templo2, after_call (add templo2, pc, #4) - cache_addw(0x4680 + (HOST_lr - HOST_r8) + (templo2 << 3)); // mov lr, templo2 - cache_addw(0x4700 + (templo1 << 3)); // bx templo1 --- switch to arm state - cache_addw(0x46c0); // nop + cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 2)) ); // ldr templo1, [pc, datapos] + cache_addw( ADD_LO_PC_IMM(templo2, 4) ); // adr templo2, after_call (add templo2, pc, #4) + cache_addw( MOV_HI_LO(HOST_lr, templo2) ); // mov lr, templo2 + cache_addw( BX(templo1) ); // bx templo1 --- switch to arm state + cache_addw( NOP ); // nop } // after_call: @@ -580,7 +672,7 @@ static void gen_call_function_helper(void * func) { cache_addd(0xe12fff10 + (templo1)); // bx templo1 // thumb state from now on - cache_addw(0x1c00 + FC_RETOP + (HOST_a1 << 3)); // mov FC_RETOP, a1 + cache_addw( MOV_REG(FC_RETOP, HOST_a1) ); // mov FC_RETOP, a1 } // generate a call to a parameterless function @@ -631,42 +723,42 @@ static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { // jump to an address pointed at by ptr, offset is in imm static void gen_jmp_ptr(void * ptr,Bits imm=0) { cache_checkinstr(2); - cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_word_to_reg(templosav, ptr, 1); if (imm) { gen_mov_dword_to_reg_imm(templo2, imm); cache_checkinstr(2); - cache_addw(0x1800 + templosav + (templosav << 3) + (templo2 << 6)); // add templosav, templosav, templo2 + cache_addw( ADD_REG(templosav, templosav, templo2) ); // add templosav, templosav, templo2 } #if (1) // (*ptr) should be word aligned if ((imm & 0x03) == 0) { cache_checkinstr(8); - cache_addw(0x6800 + templo2 + (templosav << 3)); // ldr templo2, [templosav] + cache_addw( LDR_IMM(templo2, templosav, 0) ); // ldr templo2, [templosav] } else #endif { cache_checkinstr(26); - cache_addw(0x7800 + templo2 + (templosav << 3)); // ldrb templo2, [templosav] - cache_addw(0x7800 + templo1 + (templosav << 3) + (1 << 6)); // ldrb templo1, [templosav, #1] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (8 << 6)); // lsl templo1, templo1, #8 - cache_addw(0x4300 + templo2 + (templo1 << 3)); // orr templo2, templo1 - cache_addw(0x7800 + templo1 + (templosav << 3) + (2 << 6)); // ldrb templo1, [templosav, #2] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (16 << 6)); // lsl templo1, templo1, #16 - cache_addw(0x4300 + templo2 + (templo1 << 3)); // orr templo2, templo1 - cache_addw(0x7800 + templo1 + (templosav << 3) + (3 << 6)); // ldrb templo1, [templosav, #3] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (24 << 6)); // lsl templo1, templo1, #24 - cache_addw(0x4300 + templo2 + (templo1 << 3)); // orr templo2, templo1 + cache_addw( LDRB_IMM(templo2, templosav, 0) ); // ldrb templo2, [templosav] + cache_addw( LDRB_IMM(templo1, templosav, 1) ); // ldrb templo1, [templosav, #1] + cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 + cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 + cache_addw( LDRB_IMM(templo1, templosav, 2) ); // ldrb templo1, [templosav, #2] + cache_addw( LSL_IMM(templo1, templo1, 16) ); // lsl templo1, templo1, #16 + cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 + cache_addw( LDRB_IMM(templo1, templosav, 3) ); // ldrb templo1, [templosav, #3] + cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 + cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 } // increase jmp address to keep thumb state - cache_addw(0x1c00 + templo2 + (templo2 << 3) + (1 << 6)); // add templo2, templo2, #1 + cache_addw( ADD_IMM3(templo2, templo2, 1) ); // add templo2, templo2, #1 - cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 - cache_addw(0x4700 + (templo2 << 3)); // bx templo2 + cache_addw( BX(templo2) ); // bx templo2 } // short conditional jump (+-127 bytes) if register is zero @@ -674,11 +766,11 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { cache_checkinstr(4); if (dword) { - cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 } else { - cache_addw(0x0000 + templo1 + (reg << 3) + (16 << 6)); // lsl templo1, reg, #16 + cache_addw( LSL_IMM(templo1, reg, 16) ); // lsl templo1, reg, #16 } - cache_addw(0xd000); // beq j + cache_addw( BEQ_FWD(0) ); // beq j return ((Bit32u)cache.pos-2); } @@ -687,11 +779,11 @@ static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { cache_checkinstr(4); if (dword) { - cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 } else { - cache_addw(0x0000 + templo1 + (reg << 3) + (16 << 6)); // lsl templo1, reg, #16 + cache_addw( LSL_IMM(templo1, reg, 16) ); // lsl templo1, reg, #16 } - cache_addw(0xd100); // bne j + cache_addw( BNE_FWD(0) ); // bne j return ((Bit32u)cache.pos-2); } @@ -716,17 +808,17 @@ static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { datapos = cache_reservedata(); if (isdword) { - cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 } else { - cache_addw(0x0000 + templo2 + (reg << 3) + (24 << 6)); // lsl templo2, reg, #24 + cache_addw( LSL_IMM(templo2, reg, 24) ); // lsl templo2, reg, #24 } - cache_addw(0xd000 + (2 >> 1)); // beq nobranch (pc+2) + cache_addw( BEQ_FWD(2) ); // beq nobranch (pc+2) if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 4)) >> 2)); // ldr templo1, [pc, datapos] + cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 4)) ); // ldr templo1, [pc, datapos] } else { - cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 2)) >> 2)); // ldr templo1, [pc, datapos] + cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 2)) ); // ldr templo1, [pc, datapos] } - cache_addw(0x4700 + (templo1 << 3)); // bx templo1 + cache_addw( BX(templo1) ); // bx templo1 // nobranch: return ((Bit32u)datapos); } @@ -738,14 +830,14 @@ static Bit32u gen_create_branch_long_leqzero(HostReg reg) { cache_checkinstr(8); datapos = cache_reservedata(); - cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 - cache_addw(0xdc00 + (2 >> 1)); // bgt nobranch (pc+2) + cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 + cache_addw( BGT_FWD(2) ); // bgt nobranch (pc+2) if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 4)) >> 2)); // ldr templo1, [pc, datapos] + cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 4)) ); // ldr templo1, [pc, datapos] } else { - cache_addw(0x4800 + (templo1 << 8) + ((datapos - (cache.pos + 2)) >> 2)); // ldr templo1, [pc, datapos] + cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 2)) ); // ldr templo1, [pc, datapos] } - cache_addw(0x4700 + (templo1 << 3)); // bx templo1 + cache_addw( BX(templo1) ); // bx templo1 // nobranch: return ((Bit32u)datapos); } @@ -763,39 +855,39 @@ static void gen_run_code(void) { // thumb state from now on cache_addw(0xb500); // push {lr} - cache_addw(0x4640 + HOST_r3 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov r3, FC_SEGS_ADDR - cache_addw(0x4640 + HOST_r2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov r2, FC_REGS_ADDR + cache_addw( MOV_LO_HI(HOST_r3, FC_SEGS_ADDR) ); // mov r3, FC_SEGS_ADDR + cache_addw( MOV_LO_HI(HOST_r2, FC_REGS_ADDR) ); // mov r2, FC_REGS_ADDR cache_addw(0xb4fc); // push {r2,r3,v1-v4} // adr: 16 - cache_addw(0x4800 + (HOST_r3 << 8) + ((64 - (16 + 4)) >> 2)); // ldr r3, [pc, #(&Segs)] + cache_addw( LDR_PC_IMM(HOST_r3, 64 - (16 + 4)) ); // ldr r3, [pc, #(&Segs)] // adr: 18 - cache_addw(0x4800 + (HOST_r2 << 8) + ((68 - (18 + 2)) >> 2)); // ldr r2, [pc, #(&cpu_regs)] - cache_addw(0x4680 + (FC_SEGS_ADDR - HOST_r8) + (HOST_r3 << 3)); // mov FC_SEGS_ADDR, r3 - cache_addw(0x4680 + (FC_REGS_ADDR - HOST_r8) + (HOST_r2 << 3)); // mov FC_REGS_ADDR, r2 + cache_addw( LDR_PC_IMM(HOST_r2, 68 - (18 + 2)) ); // ldr r2, [pc, #(&cpu_regs)] + cache_addw( MOV_HI_LO(FC_SEGS_ADDR, HOST_r3) ); // mov FC_SEGS_ADDR, r3 + cache_addw( MOV_HI_LO(FC_REGS_ADDR, HOST_r2) ); // mov FC_REGS_ADDR, r2 // align 4 - - cache_addw(0xa302); // add r3, pc, #8 - cache_addw(0x3001); // add r0, #1 - cache_addw(0x3301); // add r3, #1 + cache_addw( ADD_LO_PC_IMM(HOST_r3, 8) ); // add r3, pc, #8 + cache_addw( ADD_IMM8(HOST_r0, 1) ); // add r0, #1 + cache_addw( ADD_IMM8(HOST_r3, 1) ); // add r3, #1 cache_addw(0xb408); // push {r3} - cache_addw(0x4700); // bx r0 - cache_addw(0x46c0); // nop + cache_addw( BX(HOST_r0) ); // bx r0 + cache_addw( NOP ); // nop // align 4 cache_addw(0xbcfc); // pop {r2,r3,v1-v4} - cache_addw(0x4680 + (FC_SEGS_ADDR - HOST_r8) + (HOST_r3 << 3)); // mov FC_SEGS_ADDR, r3 - cache_addw(0x4680 + (FC_REGS_ADDR - HOST_r8) + (HOST_r2 << 3)); // mov FC_REGS_ADDR, r2 + cache_addw( MOV_HI_LO(FC_SEGS_ADDR, HOST_r3) ); // mov FC_SEGS_ADDR, r3 + cache_addw( MOV_HI_LO(FC_REGS_ADDR, HOST_r2) ); // mov FC_REGS_ADDR, r2 cache_addw(0xbc08); // pop {r3} - cache_addw(0x4718); // bx r3 + cache_addw( BX(HOST_r3) ); // bx r3 + // fill up to 64 bytes - cache_addw(0x46c0); // nop - cache_addd(0x46c046c0); // nop, nop - cache_addd(0x46c046c0); // nop, nop - cache_addd(0x46c046c0); // nop, nop - cache_addd(0x46c046c0); // nop, nop + cache_addw( NOP ); // nop + cache_addd( NOP | (NOP << 16) ); // nop, nop + cache_addd( NOP | (NOP << 16) ); // nop, nop + cache_addd( NOP | (NOP << 16) ); // nop, nop + cache_addd( NOP | (NOP << 16) ); // nop, nop // adr: 64 cache_addd((Bit32u)&Segs); // address of "Segs" @@ -806,16 +898,16 @@ static void gen_run_code(void) { // return from a function static void gen_return_function(void) { cache_checkinstr(6); - cache_addw(0x1c00 + HOST_a1 + (FC_RETOP << 3)); // mov a1, FC_RETOP + cache_addw( MOV_REG(HOST_a1, FC_RETOP) ); // mov a1, FC_RETOP cache_addw(0xbc08); // pop {r3} - cache_addw(0x4718); // bx r3 + cache_addw( BX(HOST_r3) ); // bx r3 } // short unconditional jump (over data pool) // must emit at most CACHE_DATA_JUMP bytes static void INLINE gen_create_branch_short(void * func) { - cache_addw(0xe000 + (((Bit32u)func - ((Bit32u)cache.pos + 4)) >> 1) ); // b func + cache_addw( B_FWD((Bit32u)func - ((Bit32u)cache.pos + 4)) ); // b func } @@ -840,35 +932,35 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: - *(Bit16u*)pos=0x1800 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // add FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=0xe000 + (12 >> 1); // b after_call (pc+12) + *(Bit16u*)pos=ADD_REG(FC_RETOP, HOST_a1, HOST_a2); // add FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) break; case t_ORb: case t_ORw: case t_ORd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4300 + FC_RETOP + (HOST_a2 << 3); // orr FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (10 >> 1); // b after_call (pc+10) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=ORR(FC_RETOP, HOST_a2); // orr FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10) break; case t_ANDb: case t_ANDw: case t_ANDd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4000 + FC_RETOP + (HOST_a2 << 3); // and FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (10 >> 1); // b after_call (pc+10) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=AND(FC_RETOP, HOST_a2); // and FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10) break; case t_SUBb: case t_SUBw: case t_SUBd: - *(Bit16u*)pos=0x1a00 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // sub FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=0xe000 + (12 >> 1); // b after_call (pc+12) + *(Bit16u*)pos=SUB_REG(FC_RETOP, HOST_a1, HOST_a2); // sub FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) break; case t_XORb: case t_XORw: case t_XORd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4040 + FC_RETOP + (HOST_a2 << 3); // eor FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (10 >> 1); // b after_call (pc+10) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=EOR(FC_RETOP, HOST_a2); // eor FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10) break; case t_CMPb: case t_CMPw: @@ -876,118 +968,118 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit16u*)pos=0xe000 + (14 >> 1); // b after_call (pc+14) + *(Bit16u*)pos=B_FWD(14); // b after_call (pc+14) break; case t_INCb: case t_INCw: case t_INCd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // add FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=0xe000 + (12 >> 1); // b after_call (pc+12) + *(Bit16u*)pos=ADD_IMM3(FC_RETOP, HOST_a1, 1); // add FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) break; case t_DECb: case t_DECw: case t_DECd: - *(Bit16u*)pos=0x1e00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // sub FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=0xe000 + (12 >> 1); // b after_call (pc+12) + *(Bit16u*)pos=SUB_IMM3(FC_RETOP, HOST_a1, 1); // sub FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) break; case t_SHLb: case t_SHLw: case t_SHLd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4080 + FC_RETOP + (HOST_a2 << 3); // lsl FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (10 >> 1); // b after_call (pc+10) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=LSL_REG(FC_RETOP, HOST_a2); // lsl FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10) break; case t_SHRb: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // lsr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (8 >> 1); // b after_call (pc+8) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 24); // lsr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8) break; case t_SHRw: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // lsr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (8 >> 1); // b after_call (pc+8) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 16); // lsr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8) break; case t_SHRd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (10 >> 1); // b after_call (pc+10) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10) break; case t_SARb: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // asr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (8 >> 1); // b after_call (pc+8) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 24); // asr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8) break; case t_SARw: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // asr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (8 >> 1); // b after_call (pc+8) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 16); // asr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8) break; case t_SARd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (10 >> 1); // b after_call (pc+10) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10) break; case t_RORb: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+4)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP - *(Bit16u*)(pos+6)=0x46c0; // nop - *(Bit16u*)(pos+8)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+10)=0x46c0; // nop - *(Bit16u*)(pos+12)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+14)=0x46c0; // nop - *(Bit16u*)(pos+16)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+4)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP + *(Bit16u*)(pos+6)=NOP; // nop + *(Bit16u*)(pos+8)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+10)=NOP; // nop + *(Bit16u*)(pos+12)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+14)=NOP; // nop + *(Bit16u*)(pos+16)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 break; case t_RORw: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+4)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+6)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 - *(Bit16u*)(pos+8)=0xe000 + (6 >> 1); // b after_call (pc+6) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+4)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 + *(Bit16u*)(pos+8)=B_FWD(6); // b after_call (pc+6) break; case t_RORd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (10 >> 1); // b after_call (pc+10) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10) break; case t_ROLb: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 - *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 - *(Bit16u*)(pos+8)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP - *(Bit16u*)(pos+10)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+12)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+14)=0x46c0; // nop - *(Bit16u*)(pos+16)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 + *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)(pos+8)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP + *(Bit16u*)(pos+10)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+12)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+14)=NOP; // nop + *(Bit16u*)(pos+16)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 break; case t_ROLw: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 - *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 - *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=0x46c0; // nop - *(Bit16u*)(pos+12)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+14)=0x46c0; // nop - *(Bit16u*)(pos+16)=0x46c0; // nop + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 + *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=NOP; // nop + *(Bit16u*)(pos+12)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+14)=NOP; // nop + *(Bit16u*)(pos+16)=NOP; // nop break; case t_ROLd: - *(Bit16u*)pos=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 - *(Bit16u*)(pos+2)=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+4)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 - *(Bit16u*)(pos+6)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+8)=0xe000 + (6 >> 1); // b after_call (pc+6) + *(Bit16u*)pos=NEG(templo1, HOST_a2); // neg templo1, a2 + *(Bit16u*)(pos+2)=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+4)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+8)=B_FWD(6); // b after_call (pc+6) break; case t_NEGb: case t_NEGw: case t_NEGd: - *(Bit16u*)pos=0x4240 + FC_RETOP + (HOST_a1 << 3); // neg FC_RETOP, a1 - *(Bit16u*)(pos+2)=0xe000 + (12 >> 1); // b after_call (pc+12) + *(Bit16u*)pos=NEG(FC_RETOP, HOST_a1); // neg FC_RETOP, a1 + *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) break; default: *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 4) ) = (Bit32u)fct_ptr; // simple_func @@ -1001,35 +1093,35 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: - *(Bit16u*)pos=0x1800 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // add FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=0xe000 + (14 >> 1); // b after_call (pc+14) + *(Bit16u*)pos=ADD_REG(FC_RETOP, HOST_a1, HOST_a2); // add FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) break; case t_ORb: case t_ORw: case t_ORd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4300 + FC_RETOP + (HOST_a2 << 3); // orr FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (12 >> 1); // b after_call (pc+12) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=ORR(FC_RETOP, HOST_a2); // orr FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12) break; case t_ANDb: case t_ANDw: case t_ANDd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4000 + FC_RETOP + (HOST_a2 << 3); // and FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (12 >> 1); // b after_call (pc+12) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=AND(FC_RETOP, HOST_a2); // and FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12) break; case t_SUBb: case t_SUBw: case t_SUBd: - *(Bit16u*)pos=0x1a00 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // sub FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=0xe000 + (14 >> 1); // b after_call (pc+14) + *(Bit16u*)pos=SUB_REG(FC_RETOP, HOST_a1, HOST_a2); // sub FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) break; case t_XORb: case t_XORw: case t_XORd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4040 + FC_RETOP + (HOST_a2 << 3); // eor FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (12 >> 1); // b after_call (pc+12) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=EOR(FC_RETOP, HOST_a2); // eor FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12) break; case t_CMPb: case t_CMPw: @@ -1037,115 +1129,115 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit16u*)pos=0xe000 + (16 >> 1); // b after_call (pc+16) + *(Bit16u*)pos=B_FWD(16); // b after_call (pc+16) break; case t_INCb: case t_INCw: case t_INCd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // add FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=0xe000 + (14 >> 1); // b after_call (pc+14) + *(Bit16u*)pos=ADD_IMM3(FC_RETOP, HOST_a1, 1); // add FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) break; case t_DECb: case t_DECw: case t_DECd: - *(Bit16u*)pos=0x1e00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // sub FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=0xe000 + (14 >> 1); // b after_call (pc+14) + *(Bit16u*)pos=SUB_IMM3(FC_RETOP, HOST_a1, 1); // sub FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) break; case t_SHLb: case t_SHLw: case t_SHLd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4080 + FC_RETOP + (HOST_a2 << 3); // lsl FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (12 >> 1); // b after_call (pc+12) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=LSL_REG(FC_RETOP, HOST_a2); // lsl FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12) break; case t_SHRb: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // lsr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (10 >> 1); // b after_call (pc+10) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 24); // lsr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10) break; case t_SHRw: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // lsr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (10 >> 1); // b after_call (pc+10) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 16); // lsr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10) break; case t_SHRd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (12 >> 1); // b after_call (pc+12) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12) break; case t_SARb: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // asr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (10 >> 1); // b after_call (pc+10) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 24); // asr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10) break; case t_SARw: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // asr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (10 >> 1); // b after_call (pc+10) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 16); // asr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10) break; case t_SARd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (12 >> 1); // b after_call (pc+12) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12) break; case t_RORb: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+4)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP - *(Bit16u*)(pos+6)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 - *(Bit16u*)(pos+12)=0xe000 + (4 >> 1); // b after_call (pc+4) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+4)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP + *(Bit16u*)(pos+6)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 + *(Bit16u*)(pos+12)=B_FWD(4); // b after_call (pc+4) break; case t_RORw: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+4)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+6)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 - *(Bit16u*)(pos+8)=0xe000 + (8 >> 1); // b after_call (pc+8) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+4)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 + *(Bit16u*)(pos+8)=B_FWD(8); // b after_call (pc+8) break; case t_RORd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (12 >> 1); // b after_call (pc+12) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12) break; case t_ROLb: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 - *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 - *(Bit16u*)(pos+8)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP - *(Bit16u*)(pos+10)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+12)=0x46c0; // nop - *(Bit16u*)(pos+14)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+16)=0x46c0; // nop - *(Bit16u*)(pos+18)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 + *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)(pos+8)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP + *(Bit16u*)(pos+10)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+12)=NOP; // nop + *(Bit16u*)(pos+14)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+16)=NOP; // nop + *(Bit16u*)(pos+18)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 break; case t_ROLw: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 - *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 - *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+12)=0xe000 + (4 >> 1); // b after_call (pc+4) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 + *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+12)=B_FWD(4); // b after_call (pc+4) break; case t_ROLd: - *(Bit16u*)pos=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 - *(Bit16u*)(pos+2)=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+4)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 - *(Bit16u*)(pos+6)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+8)=0xe000 + (8 >> 1); // b after_call (pc+8) + *(Bit16u*)pos=NEG(templo1, HOST_a2); // neg templo1, a2 + *(Bit16u*)(pos+2)=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+4)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+8)=B_FWD(8); // b after_call (pc+8) break; case t_NEGb: case t_NEGw: case t_NEGd: - *(Bit16u*)pos=0x4240 + FC_RETOP + (HOST_a1 << 3); // neg FC_RETOP, a1 - *(Bit16u*)(pos+2)=0xe000 + (14 >> 1); // b after_call (pc+14) + *(Bit16u*)pos=NEG(FC_RETOP, HOST_a1); // neg FC_RETOP, a1 + *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) break; default: *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 2) ) = (Bit32u)fct_ptr; // simple_func @@ -1172,23 +1264,23 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { cache_checkinstr(4); - cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR - cache_addw(0x8800 + dest_reg + (templo1 << 3) + (index << 5)); // ldrh dest_reg, [templo1, #index] + cache_addw( MOV_LO_HI(templo1, FC_SEGS_ADDR) ); // mov templo1, FC_SEGS_ADDR + cache_addw( LDRH_IMM(dest_reg, templo1, index) ); // ldrh dest_reg, [templo1, #index] } // mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { cache_checkinstr(4); - cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR - cache_addw(0x6800 + dest_reg + (templo1 << 3) + (index << 4)); // ldr dest_reg, [templo1, #index] + cache_addw( MOV_LO_HI(templo1, FC_SEGS_ADDR) ); // mov templo1, FC_SEGS_ADDR + cache_addw( LDR_IMM(dest_reg, templo1, index) ); // ldr dest_reg, [templo1, #index] } // add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { cache_checkinstr(6); - cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR - cache_addw(0x6800 + templo2 + (templo1 << 3) + (index << 4)); // ldr templo2, [templo1, #index] - cache_addw(0x1800 + reg + (reg << 3) + (templo2 << 6)); // add reg, reg, templo2 + cache_addw( MOV_LO_HI(templo1, FC_SEGS_ADDR) ); // mov templo1, FC_SEGS_ADDR + cache_addw( LDR_IMM(templo2, templo1, index) ); // ldr templo2, [templo1, #index] + cache_addw( ADD_REG(reg, reg, templo2) ); // add reg, reg, templo2 } #endif @@ -1199,26 +1291,26 @@ static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { cache_checkinstr(4); - cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR - cache_addw(0x8800 + dest_reg + (templo2 << 3) + (index << 5)); // ldrh dest_reg, [templo2, #index] + cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR + cache_addw( LDRH_IMM(dest_reg, templo2, index) ); // ldrh dest_reg, [templo2, #index] } // mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { cache_checkinstr(4); - cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR - cache_addw(0x6800 + dest_reg + (templo2 << 3) + (index << 4)); // ldr dest_reg, [templo2, #index] + cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR + cache_addw( LDR_IMM(dest_reg, templo2, index) ); // ldr dest_reg, [templo2, #index] } // move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { cache_checkinstr(4); - cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR if (dword) { - cache_addw(0x6800 + dest_reg + (templo2 << 3) + (index << 4)); // ldr dest_reg, [templo2, #index] + cache_addw( LDR_IMM(dest_reg, templo2, index) ); // ldr dest_reg, [templo2, #index] } else { - cache_addw(0x8800 + dest_reg + (templo2 << 3) + (index << 5)); // ldrh dest_reg, [templo2, #index] + cache_addw( LDRH_IMM(dest_reg, templo2, index) ); // ldrh dest_reg, [templo2, #index] } } @@ -1228,8 +1320,8 @@ static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { // registers might not be directly byte-accessible on some architectures static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { cache_checkinstr(4); - cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR - cache_addw(0x7800 + dest_reg + (templo2 << 3) + (index << 6)); // ldrb dest_reg, [templo2, #index] + cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR + cache_addw( LDRB_IMM(dest_reg, templo2, index) ); // ldrb dest_reg, [templo2, #index] } // move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR @@ -1238,49 +1330,50 @@ static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { // not directly byte-accessible on some architectures static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { cache_checkinstr(4); - cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR - cache_addw(0x7800 + dest_reg + (templo2 << 3) + (index << 6)); // ldrb dest_reg, [templo2, #index] + cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR + cache_addw( LDRB_IMM(dest_reg, templo2, index) ); // ldrb dest_reg, [templo2, #index] } // add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { cache_checkinstr(6); - cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR - cache_addw(0x6800 + templo1 + (templo2 << 3) + (index << 4)); // ldr templo1, [templo2, #index] - cache_addw(0x1800 + reg + (reg << 3) + (templo1 << 6)); // add reg, reg, templo1 + cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR + cache_addw( LDR_IMM(templo1, templo2, index) ); // ldr templo1, [templo2, #index] + cache_addw( ADD_REG(reg, reg, templo1) ); // add reg, reg, templo1 } // move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { cache_checkinstr(4); - cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR - cache_addw(0x8000 + src_reg + (templo1 << 3) + (index << 5)); // strh src_reg, [templo1, #index] + cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR + cache_addw( STRH_IMM(src_reg, templo1, index) ); // strh src_reg, [templo1, #index] } // move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { cache_checkinstr(4); - cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR - cache_addw(0x6000 + src_reg + (templo1 << 3) + (index << 4)); // str src_reg, [templo1, #index] + cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR + cache_addw( STR_IMM(src_reg, templo1, index) ); // str src_reg, [templo1, #index] } // move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { cache_checkinstr(4); - cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR if (dword) { - cache_addw(0x6000 + src_reg + (templo1 << 3) + (index << 4)); // str src_reg, [templo1, #index] + cache_addw( STR_IMM(src_reg, templo1, index) ); // str src_reg, [templo1, #index] } else { - cache_addw(0x8000 + src_reg + (templo1 << 3) + (index << 5)); // strh src_reg, [templo1, #index] + cache_addw( STRH_IMM(src_reg, templo1, index) ); // strh src_reg, [templo1, #index] } } // move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { cache_checkinstr(4); - cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR - cache_addw(0x7000 + src_reg + (templo1 << 3) + (index << 6)); // strb src_reg, [templo1, #index] + cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR + cache_addw( STRB_IMM(src_reg, templo1, index) ); // strb src_reg, [templo1, #index] } + #endif diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb.h b/src/cpu/core_dynrec/risc_armv4le-thumb.h index 5501bc0a..58620574 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-thumb.h,v 1.3 2008-09-19 16:48:03 c2woody Exp $ */ +/* $Id: risc_armv4le-thumb.h,v 1.4 2009-05-16 21:52:47 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (thumb version) */ @@ -63,25 +63,117 @@ #define FC_SEGS_ADDR HOST_v8 #endif + +// instruction encodings + +// move +// mov dst, #imm @ 0 <= imm <= 255 +#define MOV_IMM(dst, imm) (0x2000 + ((dst) << 8) + (imm) ) +// mov dst, src +#define MOV_REG(dst, src) ADD_IMM3(dst, src, 0) +// mov dst, src +#define MOV_LO_HI(dst, src) (0x4640 + (dst) + (((src) - HOST_r8) << 3) ) +// mov dst, src +#define MOV_HI_LO(dst, src) (0x4680 + ((dst) - HOST_r8) + ((src) << 3) ) + +// arithmetic +// add dst, src, #imm @ 0 <= imm <= 7 +#define ADD_IMM3(dst, src, imm) (0x1c00 + (dst) + ((src) << 3) + ((imm) << 6) ) +// add dst, #imm @ 0 <= imm <= 255 +#define ADD_IMM8(dst, imm) (0x3000 + ((dst) << 8) + (imm) ) +// add dst, src1, src2 +#define ADD_REG(dst, src1, src2) (0x1800 + (dst) + ((src1) << 3) + ((src2) << 6) ) +// add dst, src +#define ADD_LO_HI(dst, src) (0x4440 + (dst) + (((src) - HOST_r8) << 3) ) +// add dst, pc, #imm @ 0 <= imm < 1024 & imm mod 4 = 0 +#define ADD_LO_PC_IMM(dst, imm) (0xa000 + ((dst) << 8) + ((imm) >> 2) ) +// sub dst, src1, src2 +#define SUB_REG(dst, src1, src2) (0x1a00 + (dst) + ((src1) << 3) + ((src2) << 6) ) +// sub dst, src, #imm @ 0 <= imm <= 7 +#define SUB_IMM3(dst, src, imm) (0x1e00 + (dst) + ((src) << 3) + ((imm) << 6) ) +// sub dst, #imm @ 0 <= imm <= 255 +#define SUB_IMM8(dst, imm) (0x3800 + ((dst) << 8) + (imm) ) +// neg dst, src +#define NEG(dst, src) (0x4240 + (dst) + ((src) << 3) ) +// cmp dst, #imm @ 0 <= imm <= 255 +#define CMP_IMM(dst, imm) (0x2800 + ((dst) << 8) + (imm) ) +// nop +#define NOP (0x46c0) + +// logical +// and dst, src +#define AND(dst, src) (0x4000 + (dst) + ((src) << 3) ) +// eor dst, src +#define EOR(dst, src) (0x4040 + (dst) + ((src) << 3) ) +// orr dst, src +#define ORR(dst, src) (0x4300 + (dst) + ((src) << 3) ) + +// shift/rotate +// lsl dst, src, #imm +#define LSL_IMM(dst, src, imm) (0x0000 + (dst) + ((src) << 3) + ((imm) << 6) ) +// lsl dst, reg +#define LSL_REG(dst, reg) (0x4080 + (dst) + ((reg) << 3) ) +// lsr dst, src, #imm +#define LSR_IMM(dst, src, imm) (0x0800 + (dst) + ((src) << 3) + ((imm) << 6) ) +// lsr dst, reg +#define LSR_REG(dst, reg) (0x40c0 + (dst) + ((reg) << 3) ) +// asr dst, src, #imm +#define ASR_IMM(dst, src, imm) (0x1000 + (dst) + ((src) << 3) + ((imm) << 6) ) +// asr dst, reg +#define ASR_REG(dst, reg) (0x4100 + (dst) + ((reg) << 3) ) +// ror dst, reg +#define ROR_REG(dst, reg) (0x41c0 + (dst) + ((reg) << 3) ) + +// load +// ldr reg, [addr, #imm] @ 0 <= imm < 128 & imm mod 4 = 0 +#define LDR_IMM(reg, addr, imm) (0x6800 + (reg) + ((addr) << 3) + ((imm) << 4) ) +// ldrh reg, [addr, #imm] @ 0 <= imm < 64 & imm mod 2 = 0 +#define LDRH_IMM(reg, addr, imm) (0x8800 + (reg) + ((addr) << 3) + ((imm) << 5) ) +// ldrb reg, [addr, #imm] @ 0 <= imm < 32 +#define LDRB_IMM(reg, addr, imm) (0x7800 + (reg) + ((addr) << 3) + ((imm) << 6) ) +// ldr reg, [pc, #imm] @ 0 <= imm < 1024 & imm mod 4 = 0 +#define LDR_PC_IMM(reg, imm) (0x4800 + ((reg) << 8) + ((imm) >> 2) ) + +// store +// str reg, [addr, #imm] @ 0 <= imm < 128 & imm mod 4 = 0 +#define STR_IMM(reg, addr, imm) (0x6000 + (reg) + ((addr) << 3) + ((imm) << 4) ) +// strh reg, [addr, #imm] @ 0 <= imm < 64 & imm mod 2 = 0 +#define STRH_IMM(reg, addr, imm) (0x8000 + (reg) + ((addr) << 3) + ((imm) << 5) ) +// strb reg, [addr, #imm] @ 0 <= imm < 32 +#define STRB_IMM(reg, addr, imm) (0x7000 + (reg) + ((addr) << 3) + ((imm) << 6) ) + +// branch +// beq pc+imm @ 0 <= imm < 256 & imm mod 2 = 0 +#define BEQ_FWD(imm) (0xd000 + ((imm) >> 1) ) +// bne pc+imm @ 0 <= imm < 256 & imm mod 2 = 0 +#define BNE_FWD(imm) (0xd100 + ((imm) >> 1) ) +// bgt pc+imm @ 0 <= imm < 256 & imm mod 2 = 0 +#define BGT_FWD(imm) (0xdc00 + ((imm) >> 1) ) +// b pc+imm @ 0 <= imm < 2048 & imm mod 2 = 0 +#define B_FWD(imm) (0xe000 + ((imm) >> 1) ) +// bx reg +#define BX(reg) (0x4700 + ((reg) << 3) ) + + // move a full register from reg_src to reg_dst static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { if(reg_src == reg_dst) return; - cache_addw(0x1c00 + reg_dst + (reg_src << 3)); // mov reg_dst, reg_src + cache_addw( MOV_REG(reg_dst, reg_src) ); // mov reg_dst, reg_src } // move a 32bit constant value into dest_reg static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { if ((imm & 0xffffff00) == 0) { - cache_addw(0x2000 + (dest_reg << 8) + (Bit8u)(imm & 0xff)); // mov dest_reg, #(imm) + cache_addw( MOV_IMM(dest_reg, imm) ); // mov dest_reg, #(imm) } else if ((imm & 0xffff00ff) == 0) { - cache_addw(0x2000 + (dest_reg << 8) + (Bit8u)(imm >> 8)); // mov dest_reg, #(imm >> 8) - cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (8 << 6)); // lsl dest_reg, dest_reg, #8 + cache_addw( MOV_IMM(dest_reg, imm >> 8) ); // mov dest_reg, #(imm >> 8) + cache_addw( LSL_IMM(dest_reg, dest_reg, 8) ); // lsl dest_reg, dest_reg, #8 } else if ((imm & 0xff00ffff) == 0) { - cache_addw(0x2000 + (dest_reg << 8) + (imm >> 16)); // mov dest_reg, #(imm >> 16) - cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (16 << 6)); // lsl dest_reg, dest_reg, #16 + cache_addw( MOV_IMM(dest_reg, imm >> 16) ); // mov dest_reg, #(imm >> 16) + cache_addw( LSL_IMM(dest_reg, dest_reg, 16) ); // lsl dest_reg, dest_reg, #16 } else if ((imm & 0x00ffffff) == 0) { - cache_addw(0x2000 + (dest_reg << 8) + (imm >> 24)); // mov dest_reg, #(imm >> 24) - cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (24 << 6)); // lsl dest_reg, dest_reg, #24 + cache_addw( MOV_IMM(dest_reg, imm >> 24) ); // mov dest_reg, #(imm >> 24) + cache_addw( LSL_IMM(dest_reg, dest_reg, 24) ); // lsl dest_reg, dest_reg, #24 } else { Bit32u diff; @@ -89,21 +181,21 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { if ((diff < 1024) && ((imm & 0x03) == 0)) { if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw(0xa000 + (dest_reg << 8) + (Bit8u)(diff >> 2)); // add dest_reg, pc, #(dist >> 2) + cache_addw( ADD_LO_PC_IMM(dest_reg, diff) ); // add dest_reg, pc, #(diff >> 2) } else { - cache_addw(0x46c0); // nop - cache_addw(0xa000 + (dest_reg << 8) + (Bit8u)((diff - 2) >> 2)); // add dest_reg, pc, #((dist - 2) >> 2) + cache_addw( NOP ); // nop + cache_addw( ADD_LO_PC_IMM(dest_reg, diff - 2) ); // add dest_reg, pc, #((diff - 2) >> 2) } } else { if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw(0x4800 + (dest_reg << 8)); // ldr dest_reg, [pc, #0] - cache_addw(0xe000 + (2 >> 1)); // b next_code (pc+2) + cache_addw( LDR_PC_IMM(dest_reg, 0) ); // ldr dest_reg, [pc, #0] + cache_addw( B_FWD(2) ); // b next_code (pc+2) cache_addd(imm); // .int imm // next_code: } else { - cache_addw(0x4800 + (dest_reg << 8) + (4 >> 2)); // ldr dest_reg, [pc, #4] - cache_addw(0xe000 + (4 >> 1)); // b next_code (pc+4) - cache_addw(0x46c0); // nop + cache_addw( LDR_PC_IMM(dest_reg, 4) ); // ldr dest_reg, [pc, #4] + cache_addw( B_FWD(4) ); // b next_code (pc+4) + cache_addw( NOP ); // nop cache_addd(imm); // .int imm // next_code: } @@ -117,31 +209,31 @@ static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,Ho if (dword) { if ((Bit32u)data & 3) { if ( ((Bit32u)data & 3) == 2 ) { - cache_addw(0x8800 + dest_reg + (data_reg << 3)); // ldrh dest_reg, [data_reg] - cache_addw(0x8800 + templo1 + (data_reg << 3) + (2 << 5)); // ldrh templo1, [data_reg, #2] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (16 << 6)); // lsl templo1, templo1, #16 - cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + cache_addw( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] + cache_addw( LDRH_IMM(templo1, data_reg, 2) ); // ldrh templo1, [data_reg, #2] + cache_addw( LSL_IMM(templo1, templo1, 16) ); // lsl templo1, templo1, #16 + cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 } else { - cache_addw(0x7800 + dest_reg + (data_reg << 3)); // ldrb dest_reg, [data_reg] - cache_addw(0x1c00 + templo1 + (data_reg << 3) + (1 << 6)); // add templo1, data_reg, #1 - cache_addw(0x8800 + templo1 + (templo1 << 3)); // ldrh templo1, [templo1] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (8 << 6)); // lsl templo1, templo1, #8 - cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 - cache_addw(0x7800 + templo1 + (data_reg << 3) + (3 << 6)); // ldrb templo1, [data_reg, #3] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (24 << 6)); // lsl templo1, templo1, #24 - cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + cache_addw( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] + cache_addw( ADD_IMM3(templo1, data_reg, 1) ); // add templo1, data_reg, #1 + cache_addw( LDRH_IMM(templo1, templo1, 0) ); // ldrh templo1, [templo1] + cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 + cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 + cache_addw( LDRB_IMM(templo1, data_reg, 3) ); // ldrb templo1, [data_reg, #3] + cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 + cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 } } else { - cache_addw(0x6800 + dest_reg + (data_reg << 3)); // ldr dest_reg, [data_reg] + cache_addw( LDR_IMM(dest_reg, data_reg, 0) ); // ldr dest_reg, [data_reg] } } else { if ((Bit32u)data & 1) { - cache_addw(0x7800 + dest_reg + (data_reg << 3)); // ldrb dest_reg, [data_reg] - cache_addw(0x7800 + templo1 + (data_reg << 3) + (1 << 6)); // ldrb templo1, [data_reg, #1] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (8 << 6)); // lsl templo1, templo1, #8 - cache_addw(0x4300 + dest_reg + (templo1 << 3)); // orr dest_reg, templo1 + cache_addw( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] + cache_addw( LDRB_IMM(templo1, data_reg, 1) ); // ldrb templo1, [data_reg, #1] + cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 + cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 } else { - cache_addw(0x8800 + dest_reg + (data_reg << 3)); // ldrh dest_reg, [data_reg] + cache_addw( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] } } } @@ -165,33 +257,33 @@ static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, if (dword) { if ((Bit32u)dest & 3) { if ( ((Bit32u)dest & 3) == 2 ) { - cache_addw(0x8000 + src_reg + (data_reg << 3)); // strh src_reg, [data_reg] - cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg - cache_addw(0x0800 + templo1 + (templo1 << 3) + (16 << 6)); // lsr templo1, templo1, #16 - cache_addw(0x8000 + templo1 + (data_reg << 3) + (2 << 5)); // strh templo1, [data_reg, #2] + cache_addw( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] + cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg + cache_addw( LSR_IMM(templo1, templo1, 16) ); // lsr templo1, templo1, #16 + cache_addw( STRH_IMM(templo1, data_reg, 2) ); // strh templo1, [data_reg, #2] } else { - cache_addw(0x7000 + src_reg + (data_reg << 3)); // strb src_reg, [data_reg] - cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg - cache_addw(0x0800 + templo1 + (templo1 << 3) + (8 << 6)); // lsr templo1, templo1, #8 - cache_addw(0x7000 + templo1 + (data_reg << 3) + (1 << 6)); // strb templo1, [data_reg, #1] - cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg - cache_addw(0x0800 + templo1 + (templo1 << 3) + (16 << 6)); // lsr templo1, templo1, #16 - cache_addw(0x7000 + templo1 + (data_reg << 3) + (2 << 6)); // strb templo1, [data_reg, #2] - cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg - cache_addw(0x0800 + templo1 + (templo1 << 3) + (24 << 6)); // lsr templo1, templo1, #24 - cache_addw(0x7000 + templo1 + (data_reg << 3) + (3 << 6)); // strb templo1, [data_reg, #3] + cache_addw( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] + cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg + cache_addw( LSR_IMM(templo1, templo1, 8) ); // lsr templo1, templo1, #8 + cache_addw( STRB_IMM(templo1, data_reg, 1) ); // strb templo1, [data_reg, #1] + cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg + cache_addw( LSR_IMM(templo1, templo1, 16) ); // lsr templo1, templo1, #16 + cache_addw( STRB_IMM(templo1, data_reg, 2) ); // strb templo1, [data_reg, #2] + cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg + cache_addw( LSR_IMM(templo1, templo1, 24) ); // lsr templo1, templo1, #24 + cache_addw( STRB_IMM(templo1, data_reg, 3) ); // strb templo1, [data_reg, #3] } } else { - cache_addw(0x6000 + src_reg + (data_reg << 3)); // str src_reg, [data_reg] + cache_addw( STR_IMM(src_reg, data_reg, 0) ); // str src_reg, [data_reg] } } else { if ((Bit32u)dest & 1) { - cache_addw(0x7000 + src_reg + (data_reg << 3)); // strb src_reg, [data_reg] - cache_addw(0x1c00 + templo1 + (src_reg << 3)); // mov templo1, src_reg - cache_addw(0x0800 + templo1 + (templo1 << 3) + (8 << 6)); // lsr templo1, templo1, #8 - cache_addw(0x7000 + templo1 + (data_reg << 3) + (1 << 6)); // strb templo1, [data_reg, #1] + cache_addw( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] + cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg + cache_addw( LSR_IMM(templo1, templo1, 8) ); // lsr templo1, templo1, #8 + cache_addw( STRB_IMM(templo1, data_reg, 1) ); // strb templo1, [data_reg, #1] } else { - cache_addw(0x8000 + src_reg + (data_reg << 3)); // strh src_reg, [data_reg] + cache_addw( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] } } } @@ -208,7 +300,7 @@ static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { // registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { gen_mov_dword_to_reg_imm(templo1, (Bit32u)data); - cache_addw(0x7800 + dest_reg + (templo1 << 3)); // ldrb dest_reg, [templo1] + cache_addw( LDRB_IMM(dest_reg, templo1, 0) ); // ldrb dest_reg, [templo1] } // move an 8bit value from memory into dest_reg @@ -224,7 +316,7 @@ static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* dat // this function does not use FC_OP1/FC_OP2 as dest_reg as these // registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { - cache_addw(0x2000 + (dest_reg << 8) + imm); // mov dest_reg, #(imm) + cache_addw( MOV_IMM(dest_reg, imm) ); // mov dest_reg, #(imm) } // move an 8bit constant value into dest_reg @@ -238,7 +330,7 @@ static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u // move the lowest 8bit of a register into memory static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { gen_mov_dword_to_reg_imm(templo1, (Bit32u)dest); - cache_addw(0x7000 + src_reg + (templo1 << 3)); // strb src_reg, [templo1] + cache_addw( STRB_IMM(src_reg, templo1, 0) ); // strb src_reg, [templo1] } @@ -246,55 +338,55 @@ static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { // convert an 8bit word to a 32bit dword // the register is zero-extended (sign==false) or sign-extended (sign==true) static void gen_extend_byte(bool sign,HostReg reg) { - cache_addw(0x0000 + reg + (reg << 3) + (24 << 6)); // lsl reg, reg, #24 + cache_addw( LSL_IMM(reg, reg, 24) ); // lsl reg, reg, #24 if (sign) { - cache_addw(0x1000 + reg + (reg << 3) + (24 << 6)); // asr reg, reg, #24 + cache_addw( ASR_IMM(reg, reg, 24) ); // asr reg, reg, #24 } else { - cache_addw(0x0800 + reg + (reg << 3) + (24 << 6)); // lsr reg, reg, #24 + cache_addw( LSR_IMM(reg, reg, 24) ); // lsr reg, reg, #24 } } // convert a 16bit word to a 32bit dword // the register is zero-extended (sign==false) or sign-extended (sign==true) static void gen_extend_word(bool sign,HostReg reg) { - cache_addw(0x0000 + reg + (reg << 3) + (16 << 6)); // lsl reg, reg, #16 + cache_addw( LSL_IMM(reg, reg, 16) ); // lsl reg, reg, #16 if (sign) { - cache_addw(0x1000 + reg + (reg << 3) + (16 << 6)); // asr reg, reg, #16 + cache_addw( ASR_IMM(reg, reg, 16) ); // asr reg, reg, #16 } else { - cache_addw(0x0800 + reg + (reg << 3) + (16 << 6)); // lsr reg, reg, #16 + cache_addw( LSR_IMM(reg, reg, 16) ); // lsr reg, reg, #16 } } // add a 32bit value from memory to a full register static void gen_add(HostReg reg,void* op) { - cache_addw(0x4680 + (temphi1 - HOST_r8) + (reg << 3)); // mov temphi1, reg + cache_addw( MOV_HI_LO(temphi1, reg) ); // mov temphi1, reg gen_mov_word_to_reg(reg, op, 1); - cache_addw(0x4440 + (reg) + ((temphi1 - HOST_r8) << 3)); // add reg, temphi1 + cache_addw( ADD_LO_HI(reg, temphi1) ); // add reg, temphi1 } // add a 32bit constant value to a full register static void gen_add_imm(HostReg reg,Bit32u imm) { if(!imm) return; gen_mov_dword_to_reg_imm(templo1, imm); - cache_addw(0x1800 + reg + (reg << 3) + (templo1 << 6)); // add reg, reg, templo1 + cache_addw( ADD_REG(reg, reg, templo1) ); // add reg, reg, templo1 } // and a 32bit constant value with a full register static void gen_and_imm(HostReg reg,Bit32u imm) { if(imm == 0xffffffff) return; gen_mov_dword_to_reg_imm(templo1, imm); - cache_addw(0x4000 + reg + (templo1<< 3)); // and reg, templo1 + cache_addw( AND(reg, templo1) ); // and reg, templo1 } // move a 32bit constant value into memory static void gen_mov_direct_dword(void* dest,Bit32u imm) { - cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templosav, imm); gen_mov_word_from_reg(templosav, dest, 1); - cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 } // move an address into memory @@ -305,16 +397,16 @@ static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { // add an 8bit constant value to a dword memory value static void gen_add_direct_byte(void* dest,Bit8s imm) { if(!imm) return; - cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); gen_mov_word_to_reg_helper(templosav, dest, 1, templo2); if (imm >= 0) { - cache_addw(0x3000 + (templosav << 8) + ((Bit32s)imm)); // add templosav, #(imm) + cache_addw( ADD_IMM8(templosav, (Bit32s)imm) ); // add templosav, #(imm) } else { - cache_addw(0x3800 + (templosav << 8) + (-((Bit32s)imm))); // sub templosav, #(-imm) + cache_addw( SUB_IMM8(templosav, -((Bit32s)imm)) ); // sub templosav, #(-imm) } gen_mov_word_from_reg_helper(templosav, dest, 1, templo2); - cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 } // add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value @@ -324,7 +416,7 @@ static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { gen_add_direct_byte(dest,(Bit8s)imm); return; } - cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); gen_mov_word_to_reg_helper(templosav, dest, dword, templo2); if (dword) { @@ -332,24 +424,24 @@ static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { } else { gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); } - cache_addw(0x1800 + templosav + (templosav << 3) + (templo1 << 6)); // add templosav, templosav, templo1 + cache_addw( ADD_REG(templosav, templosav, templo1) ); // add templosav, templosav, templo1 gen_mov_word_from_reg_helper(templosav, dest, dword, templo2); - cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 } // subtract an 8bit constant value from a dword memory value static void gen_sub_direct_byte(void* dest,Bit8s imm) { if(!imm) return; - cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); gen_mov_word_to_reg_helper(templosav, dest, 1, templo2); if (imm >= 0) { - cache_addw(0x3800 + (templosav << 8) + ((Bit32s)imm)); // sub templosav, #(imm) + cache_addw( SUB_IMM8(templosav, (Bit32s)imm) ); // sub templosav, #(imm) } else { - cache_addw(0x3000 + (templosav << 8) + (-((Bit32s)imm))); // add templosav, #(-imm) + cache_addw( ADD_IMM8(templosav, -((Bit32s)imm)) ); // add templosav, #(-imm) } gen_mov_word_from_reg_helper(templosav, dest, 1, templo2); - cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 } // subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value @@ -359,7 +451,7 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { gen_sub_direct_byte(dest,(Bit8s)imm); return; } - cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); gen_mov_word_to_reg_helper(templosav, dest, dword, templo2); if (dword) { @@ -367,9 +459,9 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { } else { gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); } - cache_addw(0x1a00 + templosav + (templosav << 3) + (templo1 << 6)); // sub templosav, templosav, templo1 + cache_addw( SUB_REG(templosav, templosav, templo1) ); // sub templosav, templosav, templo1 gen_mov_word_from_reg_helper(templosav, dest, dword, templo2); - cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 } // effective address calculation, destination is dest_reg @@ -377,10 +469,10 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { // added to dest_reg, then the immediate value is added static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { if (scale) { - cache_addw(0x0000 + templo1 + (scale_reg << 3) + (scale << 6)); // lsl templo1, scale_reg, #(scale) - cache_addw(0x1800 + dest_reg + (dest_reg << 3) + (templo1 << 6)); // add dest_reg, dest_reg, templo1 + cache_addw( LSL_IMM(templo1, scale_reg, scale) ); // lsl templo1, scale_reg, #(scale) + cache_addw( ADD_REG(dest_reg, dest_reg, templo1) ); // add dest_reg, dest_reg, templo1 } else { - cache_addw(0x1800 + dest_reg + (dest_reg << 3) + (scale_reg << 6)); // add dest_reg, dest_reg, scale_reg + cache_addw( ADD_REG(dest_reg, dest_reg, scale_reg) ); // add dest_reg, dest_reg, scale_reg } gen_add_imm(dest_reg, imm); } @@ -390,7 +482,7 @@ static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits im // then the immediate value is added static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { if (scale) { - cache_addw(0x0000 + dest_reg + (dest_reg << 3) + (scale << 6)); // lsl dest_reg, dest_reg, #(scale) + cache_addw( LSL_IMM(dest_reg, dest_reg, scale) ); // lsl dest_reg, dest_reg, #(scale) } gen_add_imm(dest_reg, imm); } @@ -398,16 +490,16 @@ static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { // generate a call to a parameterless function static void INLINE gen_call_function_raw(void * func) { if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw(0x4800 + (templo1 << 8) + (4 >> 2)); // ldr templo1, [pc, #4] - cache_addw(0xa000 + (templo2 << 8) + (8 >> 2)); // adr templo2, after_call (add templo2, pc, #8) - cache_addw(0x4680 + (HOST_lr - HOST_r8) + (templo2 << 3)); // mov lr, templo2 - cache_addw(0x4700 + (templo1 << 3)); // bx templo1 --- switch to arm state + cache_addw( LDR_PC_IMM(templo1, 4) ); // ldr templo1, [pc, #4] + cache_addw( ADD_LO_PC_IMM(templo2, 8) ); // adr templo2, after_call (add templo2, pc, #8) + cache_addw( MOV_HI_LO(HOST_lr, templo2) ); // mov lr, templo2 + cache_addw( BX(templo1) ); // bx templo1 --- switch to arm state } else { - cache_addw(0x4800 + (templo1 << 8) + (8 >> 2)); // ldr templo1, [pc, #8] - cache_addw(0xa000 + (templo2 << 8) + (8 >> 2)); // adr templo2, after_call (add templo2, pc, #8) - cache_addw(0x4680 + (HOST_lr - HOST_r8) + (templo2 << 3)); // mov lr, templo2 - cache_addw(0x4700 + (templo1 << 3)); // bx templo1 --- switch to arm state - cache_addw(0x46c0); // nop + cache_addw( LDR_PC_IMM(templo1, 8) ); // ldr templo1, [pc, #8] + cache_addw( ADD_LO_PC_IMM(templo2, 8) ); // adr templo2, after_call (add templo2, pc, #8) + cache_addw( MOV_HI_LO(HOST_lr, templo2) ); // mov lr, templo2 + cache_addw( BX(templo1) ); // bx templo1 --- switch to arm state + cache_addw( NOP ); // nop } cache_addd((Bit32u)func); // .int func // after_call: @@ -417,7 +509,7 @@ static void INLINE gen_call_function_raw(void * func) { cache_addd(0xe12fff10 + (templo1)); // bx templo1 // thumb state from now on - cache_addw(0x1c00 + FC_RETOP + (HOST_a1 << 3)); // mov FC_RETOP, a1 + cache_addw( MOV_REG(FC_RETOP, HOST_a1) ); // mov FC_RETOP, a1 } // generate a call to a function with paramcount parameters @@ -460,50 +552,50 @@ static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { // jump to an address pointed at by ptr, offset is in imm static void gen_jmp_ptr(void * ptr,Bits imm=0) { - cache_addw(0x4680 + (temphi1 - HOST_r8) + (templosav << 3)); // mov temphi1, templosav + cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_word_to_reg(templosav, ptr, 1); if (imm) { gen_mov_dword_to_reg_imm(templo2, imm); - cache_addw(0x1800 + templosav + (templosav << 3) + (templo2 << 6)); // add templosav, templosav, templo2 + cache_addw( ADD_REG(templosav, templosav, templo2) ); // add templosav, templosav, templo2 } #if (1) // (*ptr) should be word aligned if ((imm & 0x03) == 0) { - cache_addw(0x6800 + templo2 + (templosav << 3)); // ldr templo2, [templosav] + cache_addw( LDR_IMM(templo2, templosav, 0) ); // ldr templo2, [templosav] } else #endif { - cache_addw(0x7800 + templo2 + (templosav << 3)); // ldrb templo2, [templosav] - cache_addw(0x7800 + templo1 + (templosav << 3) + (1 << 6)); // ldrb templo1, [templosav, #1] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (8 << 6)); // lsl templo1, templo1, #8 - cache_addw(0x4300 + templo2 + (templo1 << 3)); // orr templo2, templo1 - cache_addw(0x7800 + templo1 + (templosav << 3) + (2 << 6)); // ldrb templo1, [templosav, #2] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (16 << 6)); // lsl templo1, templo1, #16 - cache_addw(0x4300 + templo2 + (templo1 << 3)); // orr templo2, templo1 - cache_addw(0x7800 + templo1 + (templosav << 3) + (3 << 6)); // ldrb templo1, [templosav, #3] - cache_addw(0x0000 + templo1 + (templo1 << 3) + (24 << 6)); // lsl templo1, templo1, #24 - cache_addw(0x4300 + templo2 + (templo1 << 3)); // orr templo2, templo1 + cache_addw( LDRB_IMM(templo2, templosav, 0) ); // ldrb templo2, [templosav] + cache_addw( LDRB_IMM(templo1, templosav, 1) ); // ldrb templo1, [templosav, #1] + cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 + cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 + cache_addw( LDRB_IMM(templo1, templosav, 2) ); // ldrb templo1, [templosav, #2] + cache_addw( LSL_IMM(templo1, templo1, 16) ); // lsl templo1, templo1, #16 + cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 + cache_addw( LDRB_IMM(templo1, templosav, 3) ); // ldrb templo1, [templosav, #3] + cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 + cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 } // increase jmp address to keep thumb state - cache_addw(0x1c00 + templo2 + (templo2 << 3) + (1 << 6)); // add templo2, templo2, #1 + cache_addw( ADD_IMM3(templo2, templo2, 1) ); // add templo2, templo2, #1 - cache_addw(0x4640 + templosav + ((temphi1 - HOST_r8) << 3)); // mov templosav, temphi1 + cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 - cache_addw(0x4700 + (templo2 << 3)); // bx templo2 + cache_addw( BX(templo2) ); // bx templo2 } // short conditional jump (+-127 bytes) if register is zero // the destination is set by gen_fill_branch() later static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { if (dword) { - cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 } else { - cache_addw(0x0000 + templo1 + (reg << 3) + (16 << 6)); // lsl templo1, reg, #16 + cache_addw( LSL_IMM(templo1, reg, 16) ); // lsl templo1, reg, #16 } - cache_addw(0xd000); // beq j + cache_addw( BEQ_FWD(0) ); // beq j return ((Bit32u)cache.pos-2); } @@ -511,11 +603,11 @@ static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { // the destination is set by gen_fill_branch() later static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { if (dword) { - cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 } else { - cache_addw(0x0000 + templo1 + (reg << 3) + (16 << 6)); // lsl templo1, reg, #16 + cache_addw( LSL_IMM(templo1, reg, 16) ); // lsl templo1, reg, #16 } - cache_addw(0xd100); // bne j + cache_addw( BNE_FWD(0) ); // bne j return ((Bit32u)cache.pos-2); } @@ -534,19 +626,19 @@ static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) { // for isdword==false the lowest 8bit of the register are tested static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { if (isdword) { - cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 } else { - cache_addw(0x0000 + templo2 + (reg << 3) + (24 << 6)); // lsl templo2, reg, #24 + cache_addw( LSL_IMM(templo2, reg, 24) ); // lsl templo2, reg, #24 } if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw(0xd000 + (8 >> 1)); // beq nobranch (pc+8) - cache_addw(0x4800 + (templo1 << 8) + (4 >> 2)); // ldr templo1, [pc, #4] - cache_addw(0x4700 + (templo1 << 3)); // bx templo1 - cache_addw(0x46c0); // nop + cache_addw( BEQ_FWD(8) ); // beq nobranch (pc+8) + cache_addw( LDR_PC_IMM(templo1, 4) ); // ldr templo1, [pc, #4] + cache_addw( BX(templo1) ); // bx templo1 + cache_addw( NOP ); // nop } else { - cache_addw(0xd000 + (6 >> 1)); // beq nobranch (pc+6) - cache_addw(0x4800 + (templo1 << 8)); // ldr templo1, [pc, #0] - cache_addw(0x4700 + (templo1 << 3)); // bx templo1 + cache_addw( BEQ_FWD(6) ); // beq nobranch (pc+6) + cache_addw( LDR_PC_IMM(templo1, 0) ); // ldr templo1, [pc, #0] + cache_addw( BX(templo1) ); // bx templo1 } cache_addd(0); // fill j // nobranch: @@ -555,16 +647,16 @@ static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { // compare 32bit-register against zero and jump if value less/equal than zero static Bit32u gen_create_branch_long_leqzero(HostReg reg) { - cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 + cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw(0xdc00 + (8 >> 1)); // bgt nobranch (pc+8) - cache_addw(0x4800 + (templo1 << 8) + (4 >> 2)); // ldr templo1, [pc, #4] - cache_addw(0x4700 + (templo1 << 3)); // bx templo1 - cache_addw(0x46c0); // nop + cache_addw( BGT_FWD(8) ); // bgt nobranch (pc+8) + cache_addw( LDR_PC_IMM(templo1, 4) ); // ldr templo1, [pc, #4] + cache_addw( BX(templo1) ); // bx templo1 + cache_addw( NOP ); // nop } else { - cache_addw(0xdc00 + (6 >> 1)); // bgt nobranch (pc+6) - cache_addw(0x4800 + (templo1 << 8)); // ldr templo1, [pc, #0] - cache_addw(0x4700 + (templo1 << 3)); // bx templo1 + cache_addw( BGT_FWD(6) ); // bgt nobranch (pc+6) + cache_addw( LDR_PC_IMM(templo1, 0) ); // ldr templo1, [pc, #0] + cache_addw( BX(templo1) ); // bx templo1 } cache_addd(0); // fill j // nobranch: @@ -584,39 +676,39 @@ static void gen_run_code(void) { // thumb state from now on cache_addw(0xb500); // push {lr} - cache_addw(0x4640 + HOST_r3 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov r3, FC_SEGS_ADDR - cache_addw(0x4640 + HOST_r2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov r2, FC_REGS_ADDR + cache_addw( MOV_LO_HI(HOST_r3, FC_SEGS_ADDR) ); // mov r3, FC_SEGS_ADDR + cache_addw( MOV_LO_HI(HOST_r2, FC_REGS_ADDR) ); // mov r2, FC_REGS_ADDR cache_addw(0xb4fc); // push {r2,r3,v1-v4} // adr: 16 - cache_addw(0x4800 + (HOST_r3 << 8) + ((64 - (16 + 4)) >> 2)); // ldr r3, [pc, #(&Segs)] + cache_addw( LDR_PC_IMM(HOST_r3, 64 - (16 + 4)) ); // ldr r3, [pc, #(&Segs)] // adr: 18 - cache_addw(0x4800 + (HOST_r2 << 8) + ((68 - (18 + 2)) >> 2)); // ldr r2, [pc, #(&cpu_regs)] - cache_addw(0x4680 + (FC_SEGS_ADDR - HOST_r8) + (HOST_r3 << 3)); // mov FC_SEGS_ADDR, r3 - cache_addw(0x4680 + (FC_REGS_ADDR - HOST_r8) + (HOST_r2 << 3)); // mov FC_REGS_ADDR, r2 + cache_addw( LDR_PC_IMM(HOST_r2, 68 - (18 + 2)) ); // ldr r2, [pc, #(&cpu_regs)] + cache_addw( MOV_HI_LO(FC_SEGS_ADDR, HOST_r3) ); // mov FC_SEGS_ADDR, r3 + cache_addw( MOV_HI_LO(FC_REGS_ADDR, HOST_r2) ); // mov FC_REGS_ADDR, r2 // align 4 - - cache_addw(0xa302); // add r3, pc, #8 - cache_addw(0x3001); // add r0, #1 - cache_addw(0x3301); // add r3, #1 + cache_addw( ADD_LO_PC_IMM(HOST_r3, 8) ); // add r3, pc, #8 + cache_addw( ADD_IMM8(HOST_r0, 1) ); // add r0, #1 + cache_addw( ADD_IMM8(HOST_r3, 1) ); // add r3, #1 cache_addw(0xb408); // push {r3} - cache_addw(0x4700); // bx r0 - cache_addw(0x46c0); // nop + cache_addw( BX(HOST_r0) ); // bx r0 + cache_addw( NOP ); // nop // align 4 cache_addw(0xbcfc); // pop {r2,r3,v1-v4} - cache_addw(0x4680 + (FC_SEGS_ADDR - HOST_r8) + (HOST_r3 << 3)); // mov FC_SEGS_ADDR, r3 - cache_addw(0x4680 + (FC_REGS_ADDR - HOST_r8) + (HOST_r2 << 3)); // mov FC_REGS_ADDR, r2 + cache_addw( MOV_HI_LO(FC_SEGS_ADDR, HOST_r3) ); // mov FC_SEGS_ADDR, r3 + cache_addw( MOV_HI_LO(FC_REGS_ADDR, HOST_r2) ); // mov FC_REGS_ADDR, r2 cache_addw(0xbc08); // pop {r3} - cache_addw(0x4718); // bx r3 + cache_addw( BX(HOST_r3) ); // bx r3 + // fill up to 64 bytes - cache_addw(0x46c0); // nop - cache_addd(0x46c046c0); // nop, nop - cache_addd(0x46c046c0); // nop, nop - cache_addd(0x46c046c0); // nop, nop - cache_addd(0x46c046c0); // nop, nop + cache_addw( NOP ); // nop + cache_addd( NOP | (NOP << 16) ); // nop, nop + cache_addd( NOP | (NOP << 16) ); // nop, nop + cache_addd( NOP | (NOP << 16) ); // nop, nop + cache_addd( NOP | (NOP << 16) ); // nop, nop // adr: 64 cache_addd((Bit32u)&Segs); // address of "Segs" @@ -626,9 +718,9 @@ static void gen_run_code(void) { // return from a function static void gen_return_function(void) { - cache_addw(0x1c00 + HOST_a1 + (FC_RETOP << 3)); // mov a1, FC_RETOP + cache_addw( MOV_REG(HOST_a1, FC_RETOP) ); // mov a1, FC_RETOP cache_addw(0xbc08); // pop {r3} - cache_addw(0x4718); // bx r3 + cache_addw( BX(HOST_r3) ); // bx r3 } #ifdef DRC_FLAGS_INVALIDATION @@ -644,35 +736,35 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: - *(Bit16u*)pos=0x1800 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // add FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=0xe000 + (16 >> 1); // b after_call (pc+16) + *(Bit16u*)pos=ADD_REG(FC_RETOP, HOST_a1, HOST_a2); // add FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) break; case t_ORb: case t_ORw: case t_ORd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4300 + FC_RETOP + (HOST_a2 << 3); // orr FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (14 >> 1); // b after_call (pc+14) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=ORR(FC_RETOP, HOST_a2); // orr FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14) break; case t_ANDb: case t_ANDw: case t_ANDd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4000 + FC_RETOP + (HOST_a2 << 3); // and FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (14 >> 1); // b after_call (pc+14) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=AND(FC_RETOP, HOST_a2); // and FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14) break; case t_SUBb: case t_SUBw: case t_SUBd: - *(Bit16u*)pos=0x1a00 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // sub FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=0xe000 + (16 >> 1); // b after_call (pc+16) + *(Bit16u*)pos=SUB_REG(FC_RETOP, HOST_a1, HOST_a2); // sub FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) break; case t_XORb: case t_XORw: case t_XORd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4040 + FC_RETOP + (HOST_a2 << 3); // eor FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (14 >> 1); // b after_call (pc+14) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=EOR(FC_RETOP, HOST_a2); // eor FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14) break; case t_CMPb: case t_CMPw: @@ -680,116 +772,116 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit16u*)pos=0xe000 + (18 >> 1); // b after_call (pc+18) + *(Bit16u*)pos=B_FWD(18); // b after_call (pc+18) break; case t_INCb: case t_INCw: case t_INCd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // add FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=0xe000 + (16 >> 1); // b after_call (pc+16) + *(Bit16u*)pos=ADD_IMM3(FC_RETOP, HOST_a1, 1); // add FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) break; case t_DECb: case t_DECw: case t_DECd: - *(Bit16u*)pos=0x1e00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // sub FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=0xe000 + (16 >> 1); // b after_call (pc+16) + *(Bit16u*)pos=SUB_IMM3(FC_RETOP, HOST_a1, 1); // sub FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) break; case t_SHLb: case t_SHLw: case t_SHLd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4080 + FC_RETOP + (HOST_a2 << 3); // lsl FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (14 >> 1); // b after_call (pc+14) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=LSL_REG(FC_RETOP, HOST_a2); // lsl FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14) break; case t_SHRb: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // lsr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (12 >> 1); // b after_call (pc+12) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 24); // lsr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12) break; case t_SHRw: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // lsr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (12 >> 1); // b after_call (pc+12) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 16); // lsr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12) break; case t_SHRd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (14 >> 1); // b after_call (pc+14) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14) break; case t_SARb: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // asr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (12 >> 1); // b after_call (pc+12) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 24); // asr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12) break; case t_SARw: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // asr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (12 >> 1); // b after_call (pc+12) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 16); // asr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12) break; case t_SARd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (14 >> 1); // b after_call (pc+14) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14) break; case t_RORb: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+4)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP - *(Bit16u*)(pos+6)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 - *(Bit16u*)(pos+12)=0xe000 + (6 >> 1); // b after_call (pc+6) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+4)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP + *(Bit16u*)(pos+6)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 + *(Bit16u*)(pos+12)=B_FWD(6); // b after_call (pc+6) break; case t_RORw: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+4)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+6)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 - *(Bit16u*)(pos+8)=0xe000 + (10 >> 1); // b after_call (pc+10) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+4)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 + *(Bit16u*)(pos+8)=B_FWD(10); // b after_call (pc+10) break; case t_RORd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (14 >> 1); // b after_call (pc+14) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14) break; case t_ROLb: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 - *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 - *(Bit16u*)(pos+8)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP - *(Bit16u*)(pos+10)=0x46c0; // nop - *(Bit16u*)(pos+12)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+14)=0x46c0; // nop - *(Bit16u*)(pos+16)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+18)=0x46c0; // nop - *(Bit16u*)(pos+20)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 + *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)(pos+8)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP + *(Bit16u*)(pos+10)=NOP; // nop + *(Bit16u*)(pos+12)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+14)=NOP; // nop + *(Bit16u*)(pos+16)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+18)=NOP; // nop + *(Bit16u*)(pos+20)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 break; case t_ROLw: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 - *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 - *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+12)=0xe000 + (6 >> 1); // b after_call (pc+6) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 + *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+12)=B_FWD(6); // b after_call (pc+6) break; case t_ROLd: - *(Bit16u*)pos=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 - *(Bit16u*)(pos+2)=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+4)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 - *(Bit16u*)(pos+6)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+8)=0xe000 + (10 >> 1); // b after_call (pc+10) + *(Bit16u*)pos=NEG(templo1, HOST_a2); // neg templo1, a2 + *(Bit16u*)(pos+2)=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+4)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+8)=B_FWD(10); // b after_call (pc+10) break; case t_NEGb: case t_NEGw: case t_NEGd: - *(Bit16u*)pos=0x4240 + FC_RETOP + (HOST_a1 << 3); // neg FC_RETOP, a1 - *(Bit16u*)(pos+2)=0xe000 + (16 >> 1); // b after_call (pc+16) + *(Bit16u*)pos=NEG(FC_RETOP, HOST_a1); // neg FC_RETOP, a1 + *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) break; default: *(Bit32u*)(pos+8)=(Bit32u)fct_ptr; // simple_func @@ -803,35 +895,35 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: - *(Bit16u*)pos=0x1800 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // add FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=0xe000 + (18 >> 1); // b after_call (pc+18) + *(Bit16u*)pos=ADD_REG(FC_RETOP, HOST_a1, HOST_a2); // add FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(18); // b after_call (pc+18) break; case t_ORb: case t_ORw: case t_ORd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4300 + FC_RETOP + (HOST_a2 << 3); // orr FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (16 >> 1); // b after_call (pc+16) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=ORR(FC_RETOP, HOST_a2); // orr FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16) break; case t_ANDb: case t_ANDw: case t_ANDd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4000 + FC_RETOP + (HOST_a2 << 3); // and FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (16 >> 1); // b after_call (pc+16) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=AND(FC_RETOP, HOST_a2); // and FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16) break; case t_SUBb: case t_SUBw: case t_SUBd: - *(Bit16u*)pos=0x1a00 + FC_RETOP + (HOST_a1 << 3) + (HOST_a2 << 6); // sub FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=0xe000 + (18 >> 1); // b after_call (pc+18) + *(Bit16u*)pos=SUB_REG(FC_RETOP, HOST_a1, HOST_a2); // sub FC_RETOP, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(18); // b after_call (pc+18) break; case t_XORb: case t_XORw: case t_XORd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4040 + FC_RETOP + (HOST_a2 << 3); // eor FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (16 >> 1); // b after_call (pc+16) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=EOR(FC_RETOP, HOST_a2); // eor FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16) break; case t_CMPb: case t_CMPw: @@ -839,114 +931,114 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit16u*)pos=0xe000 + (20 >> 1); // b after_call (pc+20) + *(Bit16u*)pos=B_FWD(20); // b after_call (pc+20) break; case t_INCb: case t_INCw: case t_INCd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // add FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=0xe000 + (18 >> 1); // b after_call (pc+18) + *(Bit16u*)pos=ADD_IMM3(FC_RETOP, HOST_a1, 1); // add FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(18); // b after_call (pc+18) break; case t_DECb: case t_DECw: case t_DECd: - *(Bit16u*)pos=0x1e00 + FC_RETOP + (HOST_a1 << 3) + (1 << 6); // sub FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=0xe000 + (18 >> 1); // b after_call (pc+18) + *(Bit16u*)pos=SUB_IMM3(FC_RETOP, HOST_a1, 1); // sub FC_RETOP, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(18); // b after_call (pc+18) break; case t_SHLb: case t_SHLw: case t_SHLd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4080 + FC_RETOP + (HOST_a2 << 3); // lsl FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (16 >> 1); // b after_call (pc+16) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=LSL_REG(FC_RETOP, HOST_a2); // lsl FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16) break; case t_SHRb: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // lsr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (14 >> 1); // b after_call (pc+14) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 24); // lsr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(14); // b after_call (pc+14) break; case t_SHRw: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // lsr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (14 >> 1); // b after_call (pc+14) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 16); // lsr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(14); // b after_call (pc+14) break; case t_SHRd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x40c0 + FC_RETOP + (HOST_a2 << 3); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (16 >> 1); // b after_call (pc+16) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16) break; case t_SARb: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (24 << 6); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (24 << 6); // asr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (14 >> 1); // b after_call (pc+14) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 + *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 24); // asr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(14); // b after_call (pc+14) break; case t_SARw: - *(Bit16u*)pos=0x0000 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=0x1000 + FC_RETOP + (FC_RETOP << 3) + (16 << 6); // asr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=0xe000 + (14 >> 1); // b after_call (pc+14) + *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 16); // asr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 + *(Bit16u*)(pos+6)=B_FWD(14); // b after_call (pc+14) break; case t_SARd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x4100 + FC_RETOP + (HOST_a2 << 3); // asr FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (16 >> 1); // b after_call (pc+16) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16) break; case t_RORb: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+4)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP - *(Bit16u*)(pos+6)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 - *(Bit16u*)(pos+12)=0xe000 + (8 >> 1); // b after_call (pc+8) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+4)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP + *(Bit16u*)(pos+6)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 + *(Bit16u*)(pos+12)=B_FWD(8); // b after_call (pc+8) break; case t_RORw: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+4)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+6)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 - *(Bit16u*)(pos+8)=0xe000 + (12 >> 1); // b after_call (pc+12) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+4)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 + *(Bit16u*)(pos+8)=B_FWD(12); // b after_call (pc+12) break; case t_RORd: - *(Bit16u*)pos=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=0x41c0 + FC_RETOP + (HOST_a2 << 3); // ror FC_RETOP, a2 - *(Bit16u*)(pos+4)=0xe000 + (16 >> 1); // b after_call (pc+16) + *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+2)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 + *(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16) break; case t_ROLb: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (24 << 6); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 - *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (8 << 6); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 - *(Bit16u*)(pos+8)=0x4300 + HOST_a1 + (FC_RETOP << 3); // orr a1, FC_RETOP - *(Bit16u*)(pos+10)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+12)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+14)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+16)=0xe000 + (4 >> 1); // b after_call (pc+4) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 + *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 + *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)(pos+8)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP + *(Bit16u*)(pos+10)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+12)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+14)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+16)=B_FWD(4); // b after_call (pc+4) break; case t_ROLw: - *(Bit16u*)pos=0x0000 + HOST_a1 + (HOST_a1 << 3) + (16 << 6); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 - *(Bit16u*)(pos+4)=0x0800 + FC_RETOP + (HOST_a1 << 3) + (16 << 6); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+6)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 - *(Bit16u*)(pos+8)=0x4300 + FC_RETOP + (HOST_a1 << 3); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+12)=0xe000 + (8 >> 1); // b after_call (pc+8) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 + *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+12)=B_FWD(8); // b after_call (pc+8) break; case t_ROLd: - *(Bit16u*)pos=0x4240 + templo1 + (HOST_a2 << 3); // neg templo1, a2 - *(Bit16u*)(pos+2)=0x1c00 + FC_RETOP + (HOST_a1 << 3); // mov FC_RETOP, a1 - *(Bit16u*)(pos+4)=0x3000 + (templo1 << 8) + (32); // add templo1, #32 - *(Bit16u*)(pos+6)=0x41c0 + FC_RETOP + (templo1 << 3); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+8)=0xe000 + (12 >> 1); // b after_call (pc+12) + *(Bit16u*)pos=NEG(templo1, HOST_a2); // neg templo1, a2 + *(Bit16u*)(pos+2)=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 + *(Bit16u*)(pos+4)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+8)=B_FWD(12); // b after_call (pc+12) break; case t_NEGb: case t_NEGw: case t_NEGd: - *(Bit16u*)pos=0x4240 + FC_RETOP + (HOST_a1 << 3); // neg FC_RETOP, a1 - *(Bit16u*)(pos+2)=0xe000 + (18 >> 1); // b after_call (pc+18) + *(Bit16u*)pos=NEG(FC_RETOP, HOST_a1); // neg FC_RETOP, a1 + *(Bit16u*)(pos+2)=B_FWD(18); // b after_call (pc+18) break; default: *(Bit32u*)(pos+10)=(Bit32u)fct_ptr; // simple_func @@ -969,27 +1061,26 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { static void cache_block_before_close(void) { } - #ifdef DRC_USE_SEGS_ADDR // mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { - cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR - cache_addw(0x8800 + dest_reg + (templo1 << 3) + (index << 5)); // ldrh dest_reg, [templo1, #index] + cache_addw( MOV_LO_HI(templo1, FC_SEGS_ADDR) ); // mov templo1, FC_SEGS_ADDR + cache_addw( LDRH_IMM(dest_reg, templo1, index) ); // ldrh dest_reg, [templo1, #index] } // mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { - cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR - cache_addw(0x6800 + dest_reg + (templo1 << 3) + (index << 4)); // ldr dest_reg, [templo1, #index] + cache_addw( MOV_LO_HI(templo1, FC_SEGS_ADDR) ); // mov templo1, FC_SEGS_ADDR + cache_addw( LDR_IMM(dest_reg, templo1, index) ); // ldr dest_reg, [templo1, #index] } // add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { - cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR - cache_addw(0x6800 + templo2 + (templo1 << 3) + (index << 4)); // ldr templo2, [templo1, #index] - cache_addw(0x1800 + reg + (reg << 3) + (templo2 << 6)); // add reg, reg, templo2 + cache_addw( MOV_LO_HI(templo1, FC_SEGS_ADDR) ); // mov templo1, FC_SEGS_ADDR + cache_addw( LDR_IMM(templo2, templo1, index) ); // ldr templo2, [templo1, #index] + cache_addw( ADD_REG(reg, reg, templo2) ); // add reg, reg, templo2 } #endif @@ -999,24 +1090,24 @@ static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { // mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { - cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR - cache_addw(0x8800 + dest_reg + (templo2 << 3) + (index << 5)); // ldrh dest_reg, [templo2, #index] + cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR + cache_addw( LDRH_IMM(dest_reg, templo2, index) ); // ldrh dest_reg, [templo2, #index] } // mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { - cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR - cache_addw(0x6800 + dest_reg + (templo2 << 3) + (index << 4)); // ldr dest_reg, [templo2, #index] + cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR + cache_addw( LDR_IMM(dest_reg, templo2, index) ); // ldr dest_reg, [templo2, #index] } // move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { - cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR if (dword) { - cache_addw(0x6800 + dest_reg + (templo2 << 3) + (index << 4)); // ldr dest_reg, [templo2, #index] + cache_addw( LDR_IMM(dest_reg, templo2, index) ); // ldr dest_reg, [templo2, #index] } else { - cache_addw(0x8800 + dest_reg + (templo2 << 3) + (index << 5)); // ldrh dest_reg, [templo2, #index] + cache_addw( LDRH_IMM(dest_reg, templo2, index) ); // ldrh dest_reg, [templo2, #index] } } @@ -1025,8 +1116,8 @@ static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { // this function does not use FC_OP1/FC_OP2 as dest_reg as these // registers might not be directly byte-accessible on some architectures static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { - cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR - cache_addw(0x7800 + dest_reg + (templo2 << 3) + (index << 6)); // ldrb dest_reg, [templo2, #index] + cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR + cache_addw( LDRB_IMM(dest_reg, templo2, index) ); // ldrb dest_reg, [templo2, #index] } // move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR @@ -1034,45 +1125,45 @@ static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { // this function can use FC_OP1/FC_OP2 as dest_reg which are // not directly byte-accessible on some architectures static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { - cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR - cache_addw(0x7800 + dest_reg + (templo2 << 3) + (index << 6)); // ldrb dest_reg, [templo2, #index] + cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR + cache_addw( LDRB_IMM(dest_reg, templo2, index) ); // ldrb dest_reg, [templo2, #index] } // add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { - cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR - cache_addw(0x6800 + templo1 + (templo2 << 3) + (index << 4)); // ldr templo1, [templo2, #index] - cache_addw(0x1800 + reg + (reg << 3) + (templo1 << 6)); // add reg, reg, templo1 + cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR + cache_addw( LDR_IMM(templo1, templo2, index) ); // ldr templo1, [templo2, #index] + cache_addw( ADD_REG(reg, reg, templo1) ); // add reg, reg, templo1 } // move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { - cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR - cache_addw(0x8000 + src_reg + (templo1 << 3) + (index << 5)); // strh src_reg, [templo1, #index] + cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR + cache_addw( STRH_IMM(src_reg, templo1, index) ); // strh src_reg, [templo1, #index] } // move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { - cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR - cache_addw(0x6000 + src_reg + (templo1 << 3) + (index << 4)); // str src_reg, [templo1, #index] + cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR + cache_addw( STR_IMM(src_reg, templo1, index) ); // str src_reg, [templo1, #index] } // move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { - cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR if (dword) { - cache_addw(0x6000 + src_reg + (templo1 << 3) + (index << 4)); // str src_reg, [templo1, #index] + cache_addw( STR_IMM(src_reg, templo1, index) ); // str src_reg, [templo1, #index] } else { - cache_addw(0x8000 + src_reg + (templo1 << 3) + (index << 5)); // strh src_reg, [templo1, #index] + cache_addw( STRH_IMM(src_reg, templo1, index) ); // strh src_reg, [templo1, #index] } } // move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { - cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR - cache_addw(0x7000 + src_reg + (templo1 << 3) + (index << 6)); // strb src_reg, [templo1, #index] + cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR + cache_addw( STRB_IMM(src_reg, templo1, index) ); // strb src_reg, [templo1, #index] } #endif From 229c30dd4fb94888bd80654f5c8753352253acd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 17 May 2009 15:28:05 +0000 Subject: [PATCH 3306/4131] min/max safety Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3394 --- src/debug/debug_win32.cpp | 6 +++++- src/libs/gui_tk/gui_tk.h | 8 ++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/debug/debug_win32.cpp b/src/debug/debug_win32.cpp index 01a229cc..b33c9004 100644 --- a/src/debug/debug_win32.cpp +++ b/src/debug/debug_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -22,6 +22,10 @@ #include #include +#ifndef min +#define min(a,b) ((a)<(b)?(a):(b)) +#endif + /* Have to remember where i ripped this code sometime ago. diff --git a/src/libs/gui_tk/gui_tk.h b/src/libs/gui_tk/gui_tk.h index 3d5f0e2d..ebc90c53 100644 --- a/src/libs/gui_tk/gui_tk.h +++ b/src/libs/gui_tk/gui_tk.h @@ -102,13 +102,13 @@ * along with this program. If not, see */ -/* $Id: gui_tk.h,v 1.5 2008-09-07 10:55:15 c2woody Exp $ */ +/* $Id: gui_tk.h,v 1.6 2009-05-17 15:28:05 c2woody Exp $ */ #ifndef GUI__TOOLKIT_H #define GUI__TOOLKIT_H -#define imin(x,y) (xy?x:y) +#define imin(x,y) ((x)<(y)?(x):(y)) +#define imax(x,y) ((x)>(y)?(x):(y)) #define isign(x) (((x)<0?-1:1)) /** \file @@ -1263,7 +1263,7 @@ public: const SpecialChar *special = NULL); virtual ~BitmapFont(); - + /// Retrieve total height of font in pixels. virtual int getHeight() const { return height; }; From 9d2afb00afab2af1c12cfbaef0e98d1ea10dc115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 17 May 2009 20:02:51 +0000 Subject: [PATCH 3307/4131] update changelog Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3395 --- ChangeLog | 80 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index d0263a17..2310a4f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,41 +1,52 @@ 0.73 + - Add two new opl2+opl3 emulators. (better speed, different implementation + approach) + - Improved DRO recording/better file structure. - Add EGA emulation. - - Add vgaonly machine mode. Supports more of the exotic tricks like - changing the palette during screen updates. 9x16 fonts etc. - - Fix problems with the split lines - - Improve vesa emulation. - - Improve video BIOS emulation to behave more like a real bios. - - Fixes to paging system - - various fixes and improvements for the recompiling core. - - Add some mscdex quirks when dealing with files that are exactly 8.3 long - - Small fixes to batch file handling. - - Small fixes to the XMS memory handling. - - various fixes for aligned memory on hosts that want it. - - Various improvements to the mouse. - - Fixes and small speed ups to the debugger. - - Fix and improve lot's of compilation problems. (curses detection, - GCC 3.4 and GCC 4.X fixes) - - Added some basic auto keyboard layout handling (windows only currently) - - Add basic support for evdev keyboard driver. - - Various fixes to the timer. (improve mode 2 timer changes, - implement mode 1, improve gate2 handling) - - Add audio extraction and mci reading. Should enable CDROM audio for Vista. - - Improve the directory cache speed a lot! - - Various fixes to the create temporary file call. - - Don't keep batchfiles open during execution. Allows rewriting of the - active batchfile (menu programs use this trick sometimes) - - Fix problems with filenames with 2 extensions. - - Fixes to hercules emulation. - - Fix flag handling for ROR - - Make the batchfile handling in regard to IF more flexible - - Fixes to scrolling (panning) - - Add prefetch queue emulation. - - Make the emulated cpu type selectable. This is mainly the - identification commands and the way paging works. + - Add special vga machine mode. Supports more of the exotic tricks like + changing the palette during screen updates, 9x16 fonts etc. - Added special machine modes for the following svga cards: - S3 - Paradise - Tseng + - Fix problems with the vga split line feature. + - Improve vesa emulation. + - Add optional selection of old vesa mode for games that don't work + with certain vesa features. + - Improve video BIOS emulation to behave more like a real bios. + - Fixes for emulated 4bpp graphics modes. + - Fixes to paging system. + - Various fixes and improvements for the recompiling core. + - Add arm backend for the recompiling core. + - Add some mscdex quirks when dealing with files that are exactly 8.3 long. + - Small fixes to batch file handling. + - Small fixes to the XMS memory handling. + - Various fixes for aligned memory on hosts that want it. + - Various improvements to the mouse. + - Fixes and small speed ups to the debugger. + - Fix and improve lot's of compilation problems. (curses detection, + GCC 3.4 and GCC 4.X fixes) + - Added some basic auto keyboard layout handling. (windows only currently) + - Add basic support for evdev keyboard driver. + - Various fixes to the timer. (improve mode 2 timer changes, + implement mode 1, improve gate2 handling) + - Add audio extraction and mci audio support. Should enable CDROM audio + for Vista and adds volume control. + - Improve the directory cache speed a lot, especially with mounting slow + media like network paths. + - Various fixes to the create temporary file call. + - Don't keep batchfiles open during execution. Allows rewriting of the + active batchfile. (menu programs use this trick sometimes) + - Fix problems with filenames with 2 extensions. + - Add some more lowlevel dos tables. + - Fixes to hercules emulation. + - Fix flag handling for special case of ROR. + - Make the batchfile handling in regard to IF more flexible. + - Fixes to scrolling/panning feature. + - Add prefetch queue emulation. + - Make the emulated cpu type selectable. This is mainly the + identification commands and the way paging works. + - Some special EMS functionality added. (OS handles, zero-page handling) - Improve support for EMS when booting a different OS. - Improve cdrom speed detection by games. - Improve stability of cycle guessing code, when there is background @@ -44,9 +55,12 @@ - Added Coremidi support on Mac OS X. - Improve support for DOS devices when used to detect the existance of directories in various ways. - - Add IRQ 2 emulation on VRET (ega only) + - Add IRQ 2 emulation on VRET. (ega only) - Added video parameter table and video state functionality. - Increase default freespace to 250 MB. + - Some fixes to the fat filesystem handling for disk images. + - Some soundblaster fixes and command additions. + - Fix mixer 16bit direct transfers on bigendian hosts. 0.72 - Fixed unitialized variable in joystick. (Fixes crashes on Vista and From 5d8736e78f84a1c29fc2d876c6cf77b929954c7c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 20 May 2009 18:05:12 +0000 Subject: [PATCH 3308/4131] remove dirent stuff for win32 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3396 --- src/platform/visualc/Makefile.am | 2 +- src/platform/visualc/dirent.c | 97 -------------------------------- src/platform/visualc/dirent.h | 58 ------------------- visualc_net/dosbox.vcproj | 6 -- 4 files changed, 1 insertion(+), 162 deletions(-) delete mode 100644 src/platform/visualc/dirent.c delete mode 100644 src/platform/visualc/dirent.h diff --git a/src/platform/visualc/Makefile.am b/src/platform/visualc/Makefile.am index 1c4a8708..35f20390 100644 --- a/src/platform/visualc/Makefile.am +++ b/src/platform/visualc/Makefile.am @@ -1 +1 @@ -EXTRA_DIST = dirent.c dirent.h unistd.h config.h ntddscsi.h ntddcdrm.h +EXTRA_DIST = unistd.h config.h ntddscsi.h ntddcdrm.h diff --git a/src/platform/visualc/dirent.c b/src/platform/visualc/dirent.c deleted file mode 100644 index 1131da7e..00000000 --- a/src/platform/visualc/dirent.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Implementation of the standard functions in direct.h - * - * opendir(), readdir(), closedir() and rewinddir(). - * - * 06/17/2000 by Mike Haaland - */ - -#include "dirent.h" -#include "io.h" - -#define safe_strncpy_dirent(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) - -#ifdef WIN32 - -/** open the current directory and return a structure - * to be used in subsequent readdir() and closedir() - * calls. - * - * returns NULL if one error. - */ -DIR * opendir(const char *dirname) { - - static DIR dir; - size_t len; - - /* Stash the directory name */ - safe_strncpy_dirent(dir.pathName,dirname,260); - - len = strlen(dirname); - if ((len>0) && (dirname[len-1]=='\\')) strcat(dir.pathName,"*.*"); - else strcat(dir.pathName,"\\*.*"); - - /* set the handle to invalid and set the firstTime flag */ - dir.handle = INVALID_HANDLE_VALUE; - dir.firstTime = TRUE; - - /* Change the current directory to the one requested */ - return (access(dirname,0) ? NULL : &dir); -} - -/** Close the current directory - return 0 if success */ -int closedir(DIR *dirp) { - /* reset ourselves to the first file in the directory - * - * We just close the current handle and reset for the - * next readdir call - */ - int result = 1; - - if (dirp->handle != INVALID_HANDLE_VALUE) - { - result = FindClose(dirp->handle); - dirp->handle = INVALID_HANDLE_VALUE; - } - - return (result == 0) ? 1 : 0; -} - -/** get the next entry in the directory */ -struct dirent * readdir(DIR *dirp) { - static struct dirent d; - - if (TRUE == dirp->firstTime) - { - /** Get the first entry in the directory */ - dirp->handle = FindFirstFile(dirp->pathName, &dirp->findFileData); - dirp->firstTime = FALSE; - if (INVALID_HANDLE_VALUE == dirp->handle) - { - return NULL; - } - } - else - { - int result = FindNextFile(dirp->handle, &dirp->findFileData); - if (0 == result ) - { - return NULL; - } - } - /* we have a valid FIND_FILE_DATA, copy the filename */ - memset(&d,'\0', sizeof(struct dirent)); - - safe_strncpy_dirent(d.d_name,dirp->findFileData.cFileName,260); - d.d_namlen = (char)strlen(d.d_name); - - return &d; -} - -/** reopen the current directory */ -void rewinddir(DIR *dirp) { - closedir(dirp); - dirp->firstTime = TRUE; -} - -#endif diff --git a/src/platform/visualc/dirent.h b/src/platform/visualc/dirent.h deleted file mode 100644 index c37dbb60..00000000 --- a/src/platform/visualc/dirent.h +++ /dev/null @@ -1,58 +0,0 @@ - - -/* - * Defines and structures used to implement the - * functionality standard in direct.h for: - * - * opendir(), readdir(), closedir() and rewinddir(). - * - * 06/17/2000 by Mike Haaland - */ -#ifndef _DIRENT_H_ -#define _DIRENT_H_ - -#ifdef _MSC_VER - - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - -#if !defined(__GNUC__) -/* Convienience macros used with stat structures */ -#define S_ISDIR(x) (x & _S_IFDIR) -#define S_ISREG(x) (x & _S_IFREG) -#endif - - -/* Structure to keep track of the current directory status */ -typedef struct my_dir { - HANDLE handle; - WIN32_FIND_DATA findFileData; - BOOLEAN firstTime; - char pathName[MAX_PATH]; -} DIR; - -/* Standard directory name entry returned by readdir() */ -struct dirent { - char d_namlen; - char d_name[MAX_PATH]; -}; - -/* function prototypes */ -int closedir(DIR *dirp); -DIR * opendir(const char *dirname); -struct dirent * readdir(DIR *dirp); -void rewinddir(DIR *dirp); - -#ifdef __cplusplus -} -#endif - -#endif -#endif - diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 445bb4da..43a487d1 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -756,12 +756,6 @@ - - - - From acada1af49908c764022e28b69d6ab0daeefaec2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 20 May 2009 18:07:06 +0000 Subject: [PATCH 3309/4131] Prevent against div by zero. Make it possible to recover from ratio increases. Try to prevent large increases that are caused by timing resolution problems Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3397 --- src/dosbox.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 19661808..aa293cc1 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.148 2009-04-26 15:37:04 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.149 2009-05-20 18:07:06 qbix79 Exp $ */ #include #include @@ -168,6 +168,7 @@ increaseticks: ticksAdded = ticksRemain; if (CPU_CycleAutoAdjust && !CPU_SkipCycleAutoAdjust) { if (ticksScheduled >= 250 || ticksDone >= 250 || (ticksAdded > 15 && ticksScheduled >= 5) ) { + if(ticksDone < 1) ticksDone = 1; // Protect against div by zero /* ratio we are aiming for is around 90% usage*/ Bit32s ratio = (ticksScheduled * (CPU_CyclePercUsed*90*1024/100/100)) / ticksDone; Bit32s new_cmax = CPU_CycleMax; @@ -178,6 +179,10 @@ increaseticks: double ratioremoved = (double) CPU_IODelayRemoved / (double) cproc; if (ratioremoved < 1.0) { ratio = (Bit32s)((double)ratio * (1 - ratioremoved)); + /* Don't allow very high ratio which can cause us to lock as we don't scale down + * for very low ratios. High ratio might result because of timing resolution */ + if (ticksScheduled >= 250 && ticksDone < 10 && ratio > 20480) + ratio = 20480; Bit64s cmax_scaled = (Bit64s)CPU_CycleMax * (Bit64s)ratio; if (ratio <= 1024) new_cmax = (Bit32s)(cmax_scaled / (Bit64s)1024); From 97845ad1dc5d6115b14ff3f4ea23b45c2bcb3331 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 20 May 2009 18:08:59 +0000 Subject: [PATCH 3310/4131] Initial part of new configuration system. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3398 --- scripts/dosbox-installer.nsi | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index 206d4768..8c4b9ff8 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -2,10 +2,10 @@ !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 COPYRIGHT "Copyright © 2002-2009 DOSBox Team" !define DESCRIPTION "DOSBox Installer" -VIProductVersion "${VER_MAYOR}.${VER_MINOR}.0.0" +VIProductVersion "${VER_MAYOR}.73.0.0" VIAddVersionKey "ProductName" "${APP_NAME}" VIAddVersionKey "CompanyName" "${COMP_NAME}" VIAddVersionKey "FileDescription" "${DESCRIPTION}" @@ -32,10 +32,13 @@ LicenseText "DOSBox v${VER_MAYOR}.${VER_MINOR} License" "Next >" ; Else vista enables compatibility mode RequestExecutionLevel admin +; Shortcuts in all users ComponentText "Select components for DOSBox" ; The stuff to install Section "!Core files" Core +SetShellVarContext all + ; Set output path to the installation directory. ClearErrors SetOutPath $INSTDIR @@ -44,7 +47,6 @@ Section "!Core files" Core ; Put file there - CreateDirectory "$INSTDIR\capture" CreateDirectory "$INSTDIR\zmbv" File /oname=README.txt README File /oname=COPYING.txt COPYING @@ -53,7 +55,6 @@ Section "!Core files" Core 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 @@ -62,12 +63,14 @@ Section "!Core files" Core CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}" CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video" + CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration" 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}\DOSBox.lnk" "$INSTDIR\DOSBox.exe" "" "$INSTDIR\DOSBox.exe" 0 + CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox (noconsole).lnk" "$INSTDIR\DOSBox.exe" "-noconsole" "$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}\Configuration\Edit Configuration.lnk" "$INSTDIR\DOSBox.exe" "-editconf notepad.exe" + CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration\Reset Configuration.lnk" "$INSTDIR\DOSBox.exe" "-eraseconf" + CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Capture folder.lnk" "$INSTDIR\DOSBox.exe" "-opencaptures explorer.exe" 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" @@ -97,8 +100,9 @@ end_section: SectionEnd ; end the section Section "Desktop Shortcut" SecDesktop +SetShellVarContext all -CreateShortCut "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk" "$INSTDIR\DOSBox.exe" "-conf $\"$INSTDIR\dosbox.conf$\"" "$INSTDIR\DOSBox.exe" 0 +CreateShortCut "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk" "$INSTDIR\DOSBox.exe" "" "$INSTDIR\DOSBox.exe" 0 SectionEnd ; end the section @@ -106,6 +110,10 @@ CreateShortCut "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk" "$INSTDIR\DOSBox. UninstallText "This will uninstall DOSBox v${VER_MAYOR}.${VER_MINOR}. Hit next to continue." Section "Uninstall" + +; Shortcuts in all users +SetShellVarContext all + Delete "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk" ; remove registry keys ; remove files @@ -116,7 +124,6 @@ Section "Uninstall" 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 @@ -134,14 +141,15 @@ Section "Uninstall" 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}\Configuration\Edit Configuration.lnk" + Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration\Reset Configuration.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}\Configuration" RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video" RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}" SectionEnd From 0e589b8b89b1dd8f3a4a883982af5df978028825 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 20 May 2009 18:26:35 +0000 Subject: [PATCH 3311/4131] Add splash and various new configuration file functionality Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3399 --- src/gui/dosbox_splash.h | 1028 +++++++++++++++++++++++++++++++++++++++ src/gui/sdlmain.cpp | 204 +++++++- 2 files changed, 1227 insertions(+), 5 deletions(-) create mode 100644 src/gui/dosbox_splash.h diff --git a/src/gui/dosbox_splash.h b/src/gui/dosbox_splash.h new file mode 100644 index 00000000..8ae776f2 --- /dev/null +++ b/src/gui/dosbox_splash.h @@ -0,0 +1,1028 @@ +/* GIMP RGB C-Source image dump 1-byte-run-length-encoded (t.c) */ + +#define GIMP_IMAGE_RUN_LENGTH_DECODE(image_buf, rle_data, size, bpp) do \ +{ unsigned int __bpp; unsigned char *__ip; const unsigned char *__il, *__rd; \ + __bpp = (bpp); __ip = (image_buf); __il = __ip + (size) * __bpp; \ + __rd = (rle_data); if (__bpp > 3) { /* RGBA */ \ + while (__ip < __il) { unsigned int __l = *(__rd++); \ + if (__l & 128) { __l = __l - 128; \ + do { memcpy (__ip, __rd, 4); __ip += 4; } while (--__l); __rd += 4; \ + } else { __l *= 4; memcpy (__ip, __rd, __l); \ + __ip += __l; __rd += __l; } } \ + } else { /* RGB */ \ + while (__ip < __il) { unsigned int __l = *(__rd++); \ + if (__l & 128) { __l = __l - 128; \ + do { memcpy (__ip, __rd, 3); __ip += 3; } while (--__l); __rd += 3; \ + } else { __l *= 3; memcpy (__ip, __rd, __l); \ + __ip += __l; __rd += __l; } } \ + } } while (0) +static const struct { + unsigned int width; + unsigned int height; + unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */ + unsigned char rle_pixel_data[24875 + 1]; +} gimp_image = { + 640, 400, 3, + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\245\272" + "=\0\3\275D\11\261J\27\260;\2\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\376\272=\0\14\300M\24\317\201[\341\274\251\360\355\352\241~m\37\37\37,\"" + "\34B'\30]+\23y1\15\2205\10\2469\4\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\365\272=\0\3\303Y%\324\222r\344\305\266\204\362\362\362\1\241~m\207\37" + "\37\37\6$\40\36?&\31Y*\23q/\17\2104\12\2378\5\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\354\272=\0\3\310j<\330\235\200\353\334\323\207\362\362\362" + "\1\241~m\216\37\37\37\6:%\32S)\25h-\20\2002\14\2347\6\267=\1\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\341\272=\0\4\275D\11\313uK\335\256\227\355" + "\342\337\212\362\362\362\1\241~m\224\37\37\37\6""3#\33I)\27b,\22|1\14\227" + "6\7\260;\2\377\272=\0\377\272=\0\377\272=\0\377\272=\0\330\272=\0\4\300M" + "\24\317\201[\341\274\251\360\355\352\215\362\362\362\1\241~m\232\37\37\37" + "\6+!\35B'\30]+\23y1\15\2205\10\2469\4\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\317\272=\0\3\301T\37\324\222r\344\305\266\221\362\362\362\1\241~" + "m\240\37\37\37\6$\40\36?&\31Y*\23q/\17\2104\12\2378\5\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\306\272=\0\3\310j<\330\235\200\353\334\323\224" + "\362\362\362\1\241~m\247\37\37\37\6:%\32S)\25h-\20\2002\14\2347\6\267=\1" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\273\272=\0\4\275D\11\313uK\335" + "\256\227\355\342\337\227\362\362\362\1\241~m\255\37\37\37\6""1\"\33I)\27" + "b,\22|1\14\2276\7\255;\3\377\272=\0\377\272=\0\377\272=\0\377\272=\0\262" + "\272=\0\4\300M\24\317\201[\341\274\251\360\355\352\232\362\362\362\1\241" + "~m\263\37\37\37\6+!\35B'\30]+\23y1\15\2175\11\2469\4\377\272=\0\377\272=" + "\0\377\272=\0\377\272=\0\251\272=\0\3\301T\37\324\222r\344\305\266\236\362" + "\362\362\1\241~m\271\37\37\37\6$\40\36?&\31Y*\23o/\17\2104\12\2378\5\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\240\272=\0\3\310j<\330\235\200\352" + "\331\320\241\362\362\362\1\241~m\212\37\37\37\5\240\240\240\252\252\252\212" + "\212\212gggGGG\261\37\37\37\6:%\32Q)\25h-\20\2002\14\2347\6\267=\1\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\225\272=\0\4\275D\11\313uK\335\256\227" + "\355\342\337\244\362\362\362\1\241~m\212\37\37\37\1\300\300\300\205\362\362" + "\362\6\317\317\317\257\257\257\214\214\214lllIII!!!\260\37\37\37\6""1\"\33" + "I)\27b,\22|1\14\2276\7\255;\3\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\214\272=\0\4\300M\24\317\201[\341\274\251\360\355\352\247\362\362\362\1" + "\241~m\212\37\37\37\1\271\271\271\213\362\362\362\6\324\324\324\261\261\261" + "\221\221\221qqqIII&&&\260\37\37\37\6+!\35B'\30]+\23y1\15\2175\11\2469\4\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\206\272=\0\1\350\322\310\252\362" + "\362\362\1\241~m\212\37\37\37\1\264\264\264\221\362\362\362\5\327\327\327" + "\261\261\261\205\205\205[[[&&&\261\37\37\37\6$\40\36?&\31X*\24o/\17\2104" + "\12\2378\5\377\272=\0\377\272=\0\377\272=\0\377\272=\0\1\350\322\310\252" + "\362\362\362\1\241~m\212\37\37\37\1\264\264\264\225\362\362\362\3\353\353" + "\353\261\261\261ggg\266\37\37\37\6:%\32Q)\25h-\20\2002\14\2347\6\265<\1\377" + "\272=\0\377\272=\0\377\272=\0\370\272=\0\1\350\322\310\252\362\362\362\1" + "\241~m\212\37\37\37\1\264\264\264\230\362\362\362\3\322\322\322sss$$$\271" + "\37\37\37\6""1\"\33I)\27b,\22|1\14\2276\7\255;\3\377\272=\0\377\272=\0\377" + "\272=\0\362\272=\0\1\350\322\310\252\362\362\362\1\241~m\212\37\37\37\1\264" + "\264\264\232\362\362\362\2\334\334\334xxx\276\37\37\37\6+!\35B'\30]+\23w" + "0\15\2175\11\2469\4\377\272=\0\377\272=\0\377\272=\0\354\272=\0\1\350\322" + "\310\252\362\362\362\1\241~m\212\37\37\37\1\264\264\264\234\362\362\362\2" + "\266\266\266000\302\37\37\37\6$\40\36?&\31X*\24o/\17\2104\12\2378\5\377\272" + "=\0\377\272=\0\377\272=\0\346\272=\0\1\350\322\310\252\362\362\362\1\240" + "\200n\212\37\37\37\1\264\264\264\235\362\362\362\2\334\334\334QQQ\227\37" + "\37\37\3VVVsss\200\200\200\202\236\236\236\202sss\1SSS\251\37\37\37\6:%\32" + "Q)\25h-\20~2\14\2347\6\265<\1\377\272=\0\377\272=\0\377\272=\0\337\272=\0" + "\1\350\322\310\252\362\362\362\1\234~n\212\37\37\37\1\264\264\264\236\362" + "\362\362\2\360\360\360vvv\223\37\37\37\3GGG\243\243\243\341\341\341\210\362" + "\362\362\4\350\350\350\264\264\264}}}...\253\37\37\37\6""1\"\33I)\27`,\22" + "|1\14\2276\7\255;\3\377\272=\0\377\272=\0\377\272=\0\331\272=\0\1\350\322" + "\310\252\362\362\362\1\234~n\212\37\37\37\1\264\264\264\240\362\362\362\1" + "qqq\220\37\37\37\3+++\231\231\231\360\360\360\215\362\362\362\3\350\350\350" + "\217\217\217...\257\37\37\37\3+!\35@%\30\253:\3\377\272=\0\377\272=\0\377" + "\272=\0\326\272=\0\1\350\322\310\252\362\362\362\1\234~n\212\37\37\37\1\254" + "\254\254\240\362\362\362\2\360\360\360[[[\216\37\37\37\2???\331\331\331\221" + "\362\362\362\2\350\350\350sss\260\37\37\37\1\2378\5\377\272=\0\377\272=\0" + "\377\272=\0\326\272=\0\1\350\322\310\252\362\362\362\1\234~n\212\37\37\37" + "\1\250\250\250\241\362\362\362\2\346\346\346:::\214\37\37\37\2===\341\341" + "\341\224\362\362\362\2\240\240\240&&&\256\37\37\37\1\2378\5\377\272=\0\377" + "\272=\0\377\272=\0\326\272=\0\1\350\322\310\252\362\362\362\1\234~n\212\37" + "\37\37\1\250\250\250\242\362\362\362\1\300\300\300\213\37\37\37\2$$$\317" + "\317\317\226\362\362\362\2\305\305\305+++\255\37\37\37\1\2378\5\377\272=" + "\0\377\272=\0\377\272=\0\326\272=\0\1\350\322\310\252\362\362\362\1\234~" + "n\212\37\37\37\1\250\250\250\212\362\362\362\3\322\322\322\310\310\310\350" + "\350\350\226\362\362\362\1vvv\212\37\37\37\1\217\217\217\230\362\362\362" + "\2\261\261\261!!!\224\37\37\37\1:::\227\37\37\37\1\2378\5\377\272=\0\377" + "\272=\0\377\272=\0\326\272=\0\1\350\322\310\252\362\362\362\1\234~n\212\37" + "\37\37\1\250\250\250\212\362\362\362\1\217\217\217\202\37\37\37\7+++IIIl" + "ll\205\205\205\236\236\236\305\305\305\343\343\343\217\362\362\362\2\336" + "\336\336)))\210\37\37\37\2:::\355\355\355\231\362\362\362\1\221\221\221\217" + "\37\37\37\4===\207\207\207\303\303\303\360\360\360\204\362\362\362\4\317" + "\317\317\252\252\252xxxBBB\221\37\37\37\1\2378\5\377\272=\0\377\272=\0\377" + "\272=\0\326\272=\0\1\350\322\310\252\362\362\362\1\234~n\212\37\37\37\1\250" + "\250\250\212\362\362\362\1\217\217\217\211\37\37\37\3:::iii\264\264\264\215" + "\362\362\362\1\202\202\202\210\37\37\37\1\231\231\231\233\362\362\362\1X" + "XX\214\37\37\37\2???\273\273\273\214\362\362\362\3\315\315\315}}}...\216" + "\37\37\37\1\2469\4\377\272=\0\377\272=\0\377\272=\0\326\272=\0\1\350\322" + "\310\252\362\362\362\1\234~n\212\37\37\37\1\250\250\250\212\362\362\362\1" + "\217\217\217\214\37\37\37\2""555\250\250\250\213\362\362\362\2\336\336\336" + "$$$\206\37\37\37\2&&&\350\350\350\233\362\362\362\2\312\312\312!!!\212\37" + "\37\37\2\200\200\200\355\355\355\217\362\362\362\3\346\346\346\202\202\202" + "!!!\214\37\37\37\1\250:\4\377\272=\0\377\272=\0\377\272=\0\326\272=\0\1\350" + "\322\310\252\362\362\362\1\234~n\212\37\37\37\1\250\250\250\212\362\362\362" + "\1\217\217\217\216\37\37\37\2```\353\353\353\212\362\362\362\1eee\206\37" + "\37\37\1ggg\235\362\362\362\1lll\211\37\37\37\1\214\214\214\223\362\362\362" + "\2\303\303\303888\213\37\37\37\1\250:\4\377\272=\0\377\272=\0\377\272=\0" + "\326\272=\0\1\350\322\310\252\362\362\362\1\234~n\212\37\37\37\1\250\250" + "\250\212\362\362\362\1\217\217\217\217\37\37\37\2VVV\355\355\355\211\362" + "\362\362\1\264\264\264\206\37\37\37\1\245\245\245\235\362\362\362\2\327\327" + "\327!!!\207\37\37\37\1\202\202\202\225\362\362\362\2\343\343\343:::\212\37" + "\37\37\1\250:\4\377\272=\0\377\272=\0\377\272=\0\326\272=\0\1\350\322\310" + "\252\362\362\362\1\234~n\212\37\37\37\1\236\236\236\212\362\362\362\1\217" + "\217\217\220\37\37\37\1\205\205\205\211\362\362\362\2\353\353\353)))\205" + "\37\37\37\1\327\327\327\215\362\362\362\3\322\322\322\310\310\310\315\315" + "\315\216\362\362\362\1XXX\206\37\37\37\2DDD\355\355\355\225\362\362\362\2" + "\353\353\353&&&\212\37\37\37\1\250:\4\377\272=\0\377\272=\0\377\272=\0\326" + "\272=\0\1\350\322\310\252\362\362\362\1\234~n\212\37\37\37\1\233\233\233" + "\212\362\362\362\1\217\217\217\220\37\37\37\2$$$\322\322\322\211\362\362" + "\362\1```\204\37\37\37\1...\213\362\362\362\3\327\327\327eee!!!\203\37\37" + "\37\4)))[[[\236\236\236\355\355\355\212\362\362\362\1\250\250\250\206\37" + "\37\37\1\310\310\310\226\362\362\362\1\266\266\266\213\37\37\37\1\250:\4" + "\377\272=\0\377\272=\0\377\272=\0\326\272=\0\1\350\322\310\252\362\362\362" + "\1\234~n\212\37\37\37\1\233\233\233\212\362\362\362\1\217\217\217\221\37" + "\37\37\1}}}\211\362\362\362\1\224\224\224\204\37\37\37\1SSS\212\362\362\362" + "\2\322\322\322333\210\37\37\37\2""888\271\271\271\211\362\362\362\2\343\343" + "\343!!!\204\37\37\37\1SSS\227\362\362\362\1\202\202\202\213\37\37\37\1\250" + ":\4\377\272=\0\377\272=\0\377\272=\0\326\272=\0\1\350\322\310\252\362\362" + "\362\1\234~n\212\37\37\37\1\233\233\233\212\362\362\362\1\217\217\217\221" + "\37\37\37\1""000\211\362\362\362\1\303\303\303\204\37\37\37\1qqq\212\362" + "\362\362\1QQQ\212\37\37\37\2$$$\264\264\264\211\362\362\362\1LLL\204\37\37" + "\37\1\257\257\257\227\362\362\362\1GGG\213\37\37\37\1\250:\4\377\272=\0\377" + "\272=\0\377\272=\0\326\272=\0\1\350\322\310\252\362\362\362\1\234~n\212\37" + "\37\37\1\233\233\233\212\362\362\362\1\217\217\217\222\37\37\37\1\324\324" + "\324\210\362\362\362\1\350\350\350\204\37\37\37\1\205\205\205\211\362\362" + "\362\1\266\266\266\214\37\37\37\2""555\346\346\346\210\362\362\362\1{{{\203" + "\37\37\37\2...\360\360\360\226\362\362\362\2\343\343\343!!!\213\37\37\37" + "\1\260;\2\377\272=\0\377\272=\0\377\272=\0\326\272=\0\1\350\322\310\252\362" + "\362\362\1\234~n\212\37\37\37\1\233\233\233\212\362\362\362\1\217\217\217" + "\222\37\37\37\1\254\254\254\211\362\362\362\1""888\203\37\37\37\1\226\226" + "\226\211\362\362\362\1vvv\215\37\37\37\1\205\205\205\210\362\362\362\1\245" + "\245\245\203\37\37\37\1```\213\362\362\362\6\341\341\341\271\271\271\236" + "\236\236\252\252\252\310\310\310\360\360\360\206\362\362\362\1\252\252\252" + "\214\37\37\37\1\262<\2\377\272=\0\377\272=\0\377\272=\0\326\272=\0\1\350" + "\322\310\252\362\362\362\1\234~n\212\37\37\37\1\233\233\233\212\362\362\362" + "\1\217\217\217\222\37\37\37\1\221\221\221\211\362\362\362\1QQQ\203\37\37" + "\37\1\236\236\236\211\362\362\362\1BBB\215\37\37\37\1""888\210\362\362\362" + "\1\303\303\303\203\37\37\37\1\212\212\212\211\362\362\362\2\341\341\341i" + "ii\206\37\37\37\3VVV\233\233\233\346\346\346\203\362\362\362\1vvv\214\37" + "\37\37\1\262<\2\377\272=\0\377\272=\0\377\272=\0\326\272=\0\1\350\322\310" + "\252\362\362\362\1\234~n\212\37\37\37\1\233\233\233\212\362\362\362\1\217" + "\217\217\222\37\37\37\1\205\205\205\211\362\362\362\1eee\203\37\37\37\1\250" + "\250\250\210\362\362\362\2\355\355\355!!!\216\37\37\37\1\322\322\322\207" + "\362\362\362\1\336\336\336\203\37\37\37\1\250\250\250\210\362\362\362\2\341" + "\341\341000\211\37\37\37\5...\233\233\233\360\360\360\362\362\362:::\214" + "\37\37\37\1\262<\2\377\272=\0\377\272=\0\377\272=\0\326\272=\0\1\350\322" + "\310\252\362\362\362\1\234~n\212\37\37\37\1\233\233\233\212\362\362\362\1" + "\217\217\217\222\37\37\37\1xxx\211\362\362\362\1vvv\203\37\37\37\1\250\250" + "\250\210\362\362\362\1\327\327\327\217\37\37\37\1\254\254\254\207\362\362" + "\362\1\360\360\360\203\37\37\37\1\273\273\273\210\362\362\362\1iii\214\37" + "\37\37\2???\233\233\233\215\37\37\37\1\262<\2\377\272=\0\377\272=\0\377\272" + "=\0\326\272=\0\1\350\322\310\252\362\362\362\1\234~n\212\37\37\37\1\221\221" + "\221\212\362\362\362\1\226\226\226\222\37\37\37\1vvv\211\362\362\362\1\202" + "\202\202\203\37\37\37\1\250\250\250\210\362\362\362\1\305\305\305\217\37" + "\37\37\1\212\212\212\210\362\362\362\1+++\202\37\37\37\1\300\300\300\207" + "\362\362\362\2\346\346\346!!!\233\37\37\37\1\262<\2\377\272=\0\377\272=\0" + "\377\272=\0\326\272=\0\1\350\322\310\252\362\362\362\1\234~n\212\37\37\37" + "\1\217\217\217\212\362\362\362\1\233\233\233\222\37\37\37\1vvv\211\362\362" + "\362\1\202\202\202\203\37\37\37\1\250\250\250\210\362\362\362\1\266\266\266" + "\217\37\37\37\1vvv\210\362\362\362\1""555\202\37\37\37\1\300\300\300\207" + "\362\362\362\1\310\310\310\234\37\37\37\1\262<\2\377\272=\0\377\272=\0\377" + "\272=\0\326\272=\0\1\350\322\310\252\362\362\362\1\234~n\212\37\37\37\1\217" + "\217\217\212\362\362\362\1\233\233\233\222\37\37\37\1vvv\211\362\362\362" + "\1\212\212\212\203\37\37\37\1\250\250\250\210\362\362\362\1\264\264\264\217" + "\37\37\37\1ggg\210\362\362\362\1""888\202\37\37\37\1\266\266\266\207\362" + "\362\362\1\305\305\305\234\37\37\37\1\262<\2\377\272=\0\377\272=\0\377\272" + "=\0\326\272=\0\1\350\322\310\252\362\362\362\1\234~n\212\37\37\37\1\217\217" + "\217\212\362\362\362\1\233\233\233\222\37\37\37\1vvv\211\362\362\362\1\202" + "\202\202\203\37\37\37\1\250\250\250\210\362\362\362\1\250\250\250\217\37" + "\37\37\1]]]\210\362\362\362\1""888\202\37\37\37\1\250\250\250\207\362\362" + "\362\2\346\346\346!!!\233\37\37\37\1\267=\1\377\272=\0\377\272=\0\377\272" + "=\0\326\272=\0\1\350\322\310\252\362\362\362\1\234~n\212\37\37\37\1\217\217" + "\217\212\362\362\362\1\233\233\233\222\37\37\37\1vvv\211\362\362\362\1\202" + "\202\202\203\37\37\37\1\257\257\257\210\362\362\362\1\250\250\250\217\37" + "\37\37\1]]]\210\362\362\362\1""888\202\37\37\37\1\217\217\217\210\362\362" + "\362\1]]]\233\37\37\37\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350" + "\322\310\252\362\362\362\1\234~n\212\37\37\37\1\217\217\217\212\362\362\362" + "\1\233\233\233\222\37\37\37\1vvv\211\362\362\362\1\202\202\202\203\37\37" + "\37\1\264\264\264\210\362\362\362\1\250\250\250\217\37\37\37\1]]]\210\362" + "\362\362\1""888\202\37\37\37\1iii\210\362\362\362\2\310\310\310!!!\232\37" + "\37\37\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362" + "\362\362\1\234~n\212\37\37\37\1\217\217\217\212\362\362\362\1\233\233\233" + "\222\37\37\37\1vvv\211\362\362\362\1\202\202\202\203\37\37\37\1\264\264\264" + "\210\362\362\362\1\250\250\250\217\37\37\37\1]]]\210\362\362\362\1""000\202" + "\37\37\37\1BBB\211\362\362\362\1\221\221\221\232\37\37\37\377\272=\0\377" + "\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\234~n\212\37" + "\37\37\1\217\217\217\212\362\362\362\1\233\233\233\222\37\37\37\1vvv\211" + "\362\362\362\1\202\202\202\203\37\37\37\1\264\264\264\210\362\362\362\1\250" + "\250\250\217\37\37\37\1]]]\210\362\362\362\1+++\203\37\37\37\1\331\331\331" + "\211\362\362\362\1xxx\231\37\37\37\377\272=\0\377\272=\0\377\272=\0\327\272" + "=\0\1\350\322\310\252\362\362\362\1\234~n\212\37\37\37\1\217\217\217\212" + "\362\362\362\1\233\233\233\222\37\37\37\1vvv\211\362\362\362\1\202\202\202" + "\203\37\37\37\1\264\264\264\210\362\362\362\1\250\250\250\217\37\37\37\1" + "]]]\210\362\362\362\1+++\203\37\37\37\1\212\212\212\212\362\362\362\1\212" + "\212\212\230\37\37\37\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322" + "\310\252\362\362\362\1\234~n\212\37\37\37\1\205\205\205\212\362\362\362\1" + "\233\233\233\222\37\37\37\1vvv\211\362\362\362\1\202\202\202\203\37\37\37" + "\1\264\264\264\210\362\362\362\1\250\250\250\217\37\37\37\1]]]\210\362\362" + "\362\1+++\203\37\37\37\2""555\360\360\360\212\362\362\362\2\264\264\264." + "..\226\37\37\37\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310" + "\252\362\362\362\1\234~n\212\37\37\37\1\202\202\202\212\362\362\362\1\233" + "\233\233\222\37\37\37\1vvv\211\362\362\362\1\202\202\202\203\37\37\37\1\264" + "\264\264\210\362\362\362\1\243\243\243\217\37\37\37\1ggg\210\362\362\362" + "\1+++\204\37\37\37\1\252\252\252\213\362\362\362\2\331\331\331NNN\225\37" + "\37\37\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362" + "\362\362\1\234~n\212\37\37\37\1\202\202\202\212\362\362\362\1\233\233\233" + "\222\37\37\37\1vvv\211\362\362\362\1\202\202\202\203\37\37\37\1\264\264\264" + "\210\362\362\362\1\233\233\233\217\37\37\37\1iii\210\362\362\362\1!!!\204" + "\37\37\37\2""555\350\350\350\213\362\362\362\2\355\355\355\202\202\202\223" + "\37\37\37\1$\40\36\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322" + "\310\252\362\362\362\1\234~n\212\37\37\37\1\202\202\202\212\362\362\362\1" + "\233\233\233\222\37\37\37\1vvv\211\362\362\362\1\202\202\202\203\37\37\37" + "\1\264\264\264\210\362\362\362\1\233\233\233\217\37\37\37\1iii\210\362\362" + "\362\206\37\37\37\1{{{\215\362\362\362\2\264\264\264...\221\37\37\37\1)!" + "\35\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362" + "\362\1\234~n\212\37\37\37\1\202\202\202\212\362\362\362\1\233\233\233\222" + "\37\37\37\1vvv\211\362\362\362\1\202\202\202\203\37\37\37\1\264\264\264\210" + "\362\362\362\1\233\233\233\217\37\37\37\1iii\210\362\362\362\207\37\37\37" + "\1\254\254\254\215\362\362\362\2\331\331\331NNN\220\37\37\37\1)!\35\377\272" + "=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\234" + "~n\212\37\37\37\1\202\202\202\212\362\362\362\1\233\233\233\222\37\37\37" + "\1vvv\211\362\362\362\1\202\202\202\203\37\37\37\1\264\264\264\210\362\362" + "\362\1\233\233\233\217\37\37\37\1iii\210\362\362\362\207\37\37\37\2&&&\305" + "\305\305\215\362\362\362\2\355\355\355nnn\217\37\37\37\1)!\35\377\272=\0" + "\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\234~n\212" + "\37\37\37\1\202\202\202\212\362\362\362\1\245\245\245\222\37\37\37\1vvv\211" + "\362\362\362\1\202\202\202\203\37\37\37\1\264\264\264\210\362\362\362\1\233" + "\233\233\217\37\37\37\1iii\210\362\362\362\210\37\37\37\2+++\276\276\276" + "\216\362\362\362\1\207\207\207\216\37\37\37\1)!\35\377\272=\0\377\272=\0" + "\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\234~n\212\37\37\37" + "\1\202\202\202\212\362\362\362\1\250\250\250\222\37\37\37\1vvv\211\362\362" + "\362\1\202\202\202\203\37\37\37\1\264\264\264\210\362\362\362\1\233\233\233" + "\217\37\37\37\1qqq\207\362\362\362\1\350\350\350\211\37\37\37\2&&&\254\254" + "\254\216\362\362\362\2\243\243\243!!!\214\37\37\37\1)!\35\377\272=\0\377" + "\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\234~n\212\37" + "\37\37\1\202\202\202\212\362\362\362\1\250\250\250\222\37\37\37\1vvv\211" + "\362\362\362\1\202\202\202\203\37\37\37\1\264\264\264\210\362\362\362\1\233" + "\233\233\217\37\37\37\1vvv\207\362\362\362\1\346\346\346\213\37\37\37\2v" + "vv\353\353\353\215\362\362\362\2\266\266\266&&&\213\37\37\37\1)!\35\377\272" + "=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\234" + "~n\212\37\37\37\1vvv\212\362\362\362\1\250\250\250\222\37\37\37\1vvv\211" + "\362\362\362\1\202\202\202\203\37\37\37\1\264\264\264\210\362\362\362\1\233" + "\233\233\217\37\37\37\1vvv\207\362\362\362\1\346\346\346\214\37\37\37\2B" + "BB\317\317\317\215\362\362\362\2\261\261\261!!!\212\37\37\37\1)!\35\377\272" + "=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\234" + "~n\212\37\37\37\1vvv\212\362\362\362\1\250\250\250\222\37\37\37\1vvv\211" + "\362\362\362\1\202\202\202\203\37\37\37\1\264\264\264\210\362\362\362\1\233" + "\233\233\217\37\37\37\1vvv\207\362\362\362\1\346\346\346\215\37\37\37\2&" + "&&\231\231\231\215\362\362\362\1\233\233\233\212\37\37\37\1,\"\34\377\272" + "=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\227" + "|o\212\37\37\37\1vvv\212\362\362\362\1\250\250\250\222\37\37\37\1vvv\211" + "\362\362\362\1xxx\203\37\37\37\1\276\276\276\210\362\362\362\1\233\233\233" + "\217\37\37\37\1vvv\207\362\362\362\1\346\346\346\217\37\37\37\2[[[\334\334" + "\334\214\362\362\362\1lll\211\37\37\37\1""1\"\33\377\272=\0\377\272=\0\377" + "\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\226}p\212\37\37\37\1v" + "vv\212\362\362\362\1\250\250\250\222\37\37\37\1vvv\211\362\362\362\1vvv\203" + "\37\37\37\1\300\300\300\210\362\362\362\1\217\217\217\217\37\37\37\1vvv\207" + "\362\362\362\1\331\331\331\220\37\37\37\2+++\250\250\250\213\362\362\362" + "\2\346\346\346:::\210\37\37\37\1""1\"\33\377\272=\0\377\272=\0\377\272=\0" + "\327\272=\0\1\350\322\310\252\362\362\362\1\226}p\212\37\37\37\1vvv\212\362" + "\362\362\1\250\250\250\222\37\37\37\1vvv\211\362\362\362\1vvv\203\37\37\37" + "\1\300\300\300\210\362\362\362\1\217\217\217\217\37\37\37\1}}}\207\362\362" + "\362\1\331\331\331\222\37\37\37\2[[[\343\343\343\212\362\362\362\1\264\264" + "\264\210\37\37\37\1""1\"\33\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1" + "\350\322\310\252\362\362\362\1\226}p\212\37\37\37\1vvv\212\362\362\362\1" + "\250\250\250\222\37\37\37\1vvv\211\362\362\362\1vvv\203\37\37\37\1\300\300" + "\300\210\362\362\362\1\217\217\217\217\37\37\37\1\202\202\202\207\362\362" + "\362\1\331\331\331\223\37\37\37\2""888\312\312\312\212\362\362\362\1SSS\207" + "\37\37\37\1""1\"\33\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322" + "\310\252\362\362\362\1\226}p\212\37\37\37\1vvv\212\362\362\362\1\250\250" + "\250\222\37\37\37\1vvv\211\362\362\362\1vvv\203\37\37\37\1\300\300\300\210" + "\362\362\362\1\217\217\217\217\37\37\37\1\202\202\202\207\362\362\362\1\331" + "\331\331\224\37\37\37\2&&&\273\273\273\211\362\362\362\1\300\300\300\207" + "\37\37\37\1""1\"\33\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322" + "\310\252\362\362\362\1\226}p\212\37\37\37\1vvv\212\362\362\362\1\250\250" + "\250\222\37\37\37\1vvv\211\362\362\362\1vvv\203\37\37\37\1\300\300\300\210" + "\362\362\362\1\217\217\217\217\37\37\37\1\202\202\202\207\362\362\362\1\331" + "\331\331\225\37\37\37\2&&&\266\266\266\211\362\362\362\1GGG\206\37\37\37" + "\1""1\"\33\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252" + "\362\362\362\1\226}p\212\37\37\37\1vvv\212\362\362\362\1\250\250\250\222" + "\37\37\37\1vvv\211\362\362\362\1vvv\203\37\37\37\1\300\300\300\210\362\362" + "\362\1\217\217\217\217\37\37\37\1\202\202\202\207\362\362\362\1\315\315\315" + "\226\37\37\37\2+++\322\322\322\210\362\362\362\1\224\224\224\206\37\37\37" + "\1""1\"\33\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252" + "\362\362\362\1\226}p\212\37\37\37\1iii\212\362\362\362\1\250\250\250\222" + "\37\37\37\1vvv\211\362\362\362\1vvv\203\37\37\37\1\300\300\300\210\362\362" + "\362\1\217\217\217\217\37\37\37\1\202\202\202\207\362\362\362\1\315\315\315" + "\227\37\37\37\2BBB\355\355\355\207\362\362\362\2\334\334\334!!!\205\37\37" + "\37\1""3#\33\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252" + "\362\362\362\1\226}p\212\37\37\37\1iii\212\362\362\362\1\250\250\250\222" + "\37\37\37\1vvv\211\362\362\362\1vvv\203\37\37\37\1\300\300\300\210\362\362" + "\362\1\217\217\217\217\37\37\37\1\207\207\207\207\362\362\362\1\315\315\315" + "\230\37\37\37\1\231\231\231\210\362\362\362\1DDD\205\37\37\37\1:%\32\377" + "\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1" + "\226}p\212\37\37\37\1iii\212\362\362\362\1\250\250\250\222\37\37\37\1vvv" + "\211\362\362\362\1vvv\203\37\37\37\1\300\300\300\210\362\362\362\1\217\217" + "\217\217\37\37\37\1\217\217\217\207\362\362\362\1\315\315\315\230\37\37\37" + "\2""555\353\353\353\207\362\362\362\1vvv\205\37\37\37\1:%\32\377\272=\0\377" + "\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\226}p\212\37" + "\37\37\1iii\212\362\362\362\1\261\261\261\222\37\37\37\1vvv\211\362\362\362" + "\1vvv\203\37\37\37\1\300\300\300\210\362\362\362\1\217\217\217\217\37\37" + "\37\1\217\217\217\207\362\362\362\1\312\312\312\231\37\37\37\1\252\252\252" + "\207\362\362\362\1\233\233\233\205\37\37\37\1:%\32\377\272=\0\377\272=\0" + "\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\226}p\212\37\37\37" + "\1iii\212\362\362\362\1\264\264\264\222\37\37\37\1vvv\211\362\362\362\1s" + "ss\203\37\37\37\1\300\300\300\210\362\362\362\1\217\217\217\217\37\37\37" + "\1\217\217\217\207\362\362\362\1\300\300\300\231\37\37\37\1lll\207\362\362" + "\362\1\271\271\271\205\37\37\37\1:%\32\377\272=\0\377\272=\0\377\272=\0\327" + "\272=\0\1\350\322\310\252\362\362\362\1\226}p\212\37\37\37\1iii\212\362\362" + "\362\1\264\264\264\222\37\37\37\1{{{\211\362\362\362\1iii\203\37\37\37\1" + "\300\300\300\210\362\362\362\1\221\221\221\217\37\37\37\1\221\221\221\207" + "\362\362\362\1\300\300\300\231\37\37\37\1===\207\362\362\362\1\312\312\312" + "\205\37\37\37\1:%\32\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322" + "\310\252\362\362\362\1\230\177r\212\37\37\37\1iii\212\362\362\362\1\264\264" + "\264\222\37\37\37\1\207\207\207\211\362\362\362\1bbb\203\37\37\37\1\300\300" + "\300\210\362\362\362\1\236\236\236\217\37\37\37\1\240\240\240\207\362\362" + "\362\1\300\300\300\231\37\37\37\2!!!\355\355\355\206\362\362\362\1\331\331" + "\331\205\37\37\37\1:%\32\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350" + "\322\310\252\362\362\362\1\237\210}\212\37\37\37\1iii\212\362\362\362\1\264" + "\264\264\222\37\37\37\1\245\245\245\211\362\362\362\1VVV\203\37\37\37\1\266" + "\266\266\210\362\362\362\1\266\266\266\217\37\37\37\1\271\271\271\207\362" + "\362\362\1\276\276\276\204\37\37\37\7???XXXsss\236\236\236\266\266\266\317" + "\317\317888\217\37\37\37\1\341\341\341\206\362\362\362\1\334\334\334\205" + "\37\37\37\1:%\32\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310" + "\252\362\362\362\1\237\210}\212\37\37\37\1iii\212\362\362\362\1\264\264\264" + "\222\37\37\37\1\322\322\322\211\362\362\362\1===\203\37\37\37\1\261\261\261" + "\210\362\362\362\1\336\336\336\217\37\37\37\1\343\343\343\207\362\362\362" + "\4\264\264\264\37\37\37lll\317\317\317\207\362\362\362\1SSS\217\37\37\37" + "\1\331\331\331\206\362\362\362\1\331\331\331\205\37\37\37\1=$\31\377\272" + "=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\237" + "\210}\212\37\37\37\1]]]\212\362\362\362\1\264\264\264\221\37\37\37\1GGG\211" + "\362\362\362\2\360\360\360$$$\203\37\37\37\1\233\233\233\211\362\362\362" + "\1III\215\37\37\37\1GGG\210\362\362\362\3\250\250\250\37\37\37sss\210\362" + "\362\362\1xxx\217\37\37\37\1\346\346\346\206\362\362\362\1\322\322\322\205" + "\37\37\37\1D&\30\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310" + "\252\362\362\362\1\237\210}\212\37\37\37\1]]]\212\362\362\362\1\264\264\264" + "\221\37\37\37\1\257\257\257\211\362\362\362\1\322\322\322\204\37\37\37\1" + "\200\200\200\211\362\362\362\1\226\226\226\215\37\37\37\1\224\224\224\210" + "\362\362\362\3\231\231\231\37\37\37```\210\362\362\362\1\264\264\264\216" + "\37\37\37\1""333\207\362\362\362\1\305\305\305\205\37\37\37\1D&\30\377\272" + "=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\237" + "\210}\212\37\37\37\1]]]\212\362\362\362\1\264\264\264\220\37\37\37\1vvv\212" + "\362\362\362\1\250\250\250\204\37\37\37\1eee\211\362\362\362\2\350\350\350" + "555\213\37\37\37\2""555\350\350\350\210\362\362\362\3}}}\37\37\37BBB\210" + "\362\362\362\2\355\355\355333\215\37\37\37\1nnn\207\362\362\362\1\254\254" + "\254\205\37\37\37\1D&\30\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350" + "\322\310\252\362\362\362\1\237\210}\212\37\37\37\1]]]\212\362\362\362\1\264" + "\264\264\216\37\37\37\2)))\214\214\214\213\362\362\362\1vvv\204\37\37\37" + "\1""555\212\362\362\362\2\273\273\273$$$\212\37\37\37\1\257\257\257\211\362" + "\362\362\4```\37\37\37!!!\350\350\350\210\362\362\362\1\224\224\224\215\37" + "\37\37\1\305\305\305\207\362\362\362\1\217\217\217\205\37\37\37\1D&\30\377" + "\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1" + "\237\210}\212\37\37\37\1]]]\212\362\362\362\1\300\300\300\204III\1+++\205" + "\37\37\37\5:::III```\226\226\226\343\343\343\214\362\362\362\1""888\205\37" + "\37\37\1\331\331\331\212\362\362\362\2\261\261\261+++\207\37\37\37\2$$$\233" + "\233\233\212\362\362\362\1""333\202\37\37\37\1\264\264\264\210\362\362\362" + "\2\360\360\360NNN\213\37\37\37\1qqq\210\362\362\362\1iii\205\37\37\37\1D" + "&\30\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362" + "\362\1\237\210}\212\37\37\37\1]]]\245\362\362\362\1\303\303\303\206\37\37" + "\37\1\233\233\233\213\362\362\362\3\334\334\334}}}000\203\37\37\37\3&&&g" + "gg\315\315\315\212\362\362\362\1\327\327\327\203\37\37\37\1vvv\211\362\362" + "\362\2\341\341\341GGG\211\37\37\37\2[[[\353\353\353\210\362\362\362\1""8" + "88\205\37\37\37\1D&\30\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350" + "\322\310\252\362\362\362\1\237\210}\212\37\37\37\1]]]\245\362\362\362\1l" + "ll\206\37\37\37\1QQQ\216\362\362\362\3\350\350\350\310\310\310\327\327\327" + "\215\362\362\362\1\221\221\221\203\37\37\37\2""333\360\360\360\211\362\362" + "\362\3\350\350\350{{{$$$\205\37\37\37\3+++\221\221\221\360\360\360\210\362" + "\362\362\1\322\322\322\206\37\37\37\1D&\30\377\272=\0\377\272=\0\377\272" + "=\0\327\272=\0\1\350\322\310\252\362\362\362\1\237\210}\212\37\37\37\1]]" + "]\244\362\362\362\2\324\324\324$$$\207\37\37\37\1\317\317\317\235\362\362" + "\362\1LLL\204\37\37\37\1\261\261\261\213\362\362\362\7\346\346\346\250\250" + "\250\212\212\212vvv\236\236\236\261\261\261\350\350\350\212\362\362\362\1" + "\202\202\202\206\37\37\37\1D&\30\377\272=\0\377\272=\0\377\272=\0\327\272" + "=\0\1\350\322\310\252\362\362\362\1\237\210}\212\37\37\37\1[[[\244\362\362" + "\362\1iii\210\37\37\37\1lll\234\362\362\362\1\303\303\303\205\37\37\37\1" + "LLL\233\362\362\362\2\360\360\360555\206\37\37\37\1N(\26\377\272=\0\377\272" + "=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\237\210}\212\37" + "\37\37\1QQQ\243\362\362\362\1\252\252\252\211\37\37\37\2!!!\312\312\312\233" + "\362\362\362\1]]]\206\37\37\37\1\245\245\245\232\362\362\362\1\254\254\254" + "\207\37\37\37\1N(\26\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322" + "\310\252\362\362\362\1\237\210}\212\37\37\37\1QQQ\242\362\362\362\2\317\317" + "\317+++\212\37\37\37\2GGG\355\355\355\231\362\362\362\1\271\271\271\207\37" + "\37\37\2...\341\341\341\230\362\362\362\2\350\350\350555\207\37\37\37\1N" + "(\26\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362" + "\362\1\237\210}\212\37\37\37\1QQQ\241\362\362\362\2\317\317\317555\214\37" + "\37\37\1sss\230\362\362\362\2\331\331\331000\210\37\37\37\1bbb\230\362\362" + "\362\1\202\202\202\210\37\37\37\1N(\26\377\272=\0\377\272=\0\377\272=\0\327" + "\272=\0\1\350\322\310\252\362\362\362\1\237\210}\212\37\37\37\1QQQ\240\362" + "\362\362\2\240\240\240&&&\216\37\37\37\1\212\212\212\226\362\362\362\2\353" + "\353\353DDD\212\37\37\37\1xxx\226\362\362\362\2\273\273\273$$$\210\37\37" + "\37\1N(\26\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252" + "\362\362\362\1\237\210}\212\37\37\37\1QQQ\236\362\362\362\2\334\334\334b" + "bb\221\37\37\37\2sss\353\353\353\223\362\362\362\2\350\350\350XXX\214\37" + "\37\37\1}}}\224\362\362\362\2\305\305\305+++\211\37\37\37\1N(\26\377\272" + "=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\237" + "\210}\212\37\37\37\1QQQ\234\362\362\362\2\273\273\273bbb\224\37\37\37\2G" + "GG\324\324\324\221\362\362\362\2\315\315\315BBB\216\37\37\37\2bbb\341\341" + "\341\221\362\362\362\2\254\254\254)))\212\37\37\37\1N(\26\377\272=\0\377" + "\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\237\210}\212" + "\37\37\37\1GGG\202\310\310\310\1\343\343\343\223\362\362\362\6\341\341\341" + "\310\310\310\273\273\273\217\217\217bbb333\227\37\37\37\3&&&sss\327\327\327" + "\215\362\362\362\3\327\327\327xxx$$$\220\37\37\37\2""000\250\250\250\216" + "\362\362\362\2\331\331\331ggg\214\37\37\37\1N(\26\377\272=\0\377\272=\0\377" + "\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\237\210}\301\37\37\37" + "\3bbb\236\236\236\327\327\327\207\362\362\362\4\334\334\334\252\252\252g" + "gg!!!\224\37\37\37\3DDD\233\233\233\336\336\336\210\362\362\362\4\346\346" + "\346\250\250\250```$$$\215\37\37\37\1V*\24\377\272=\0\377\272=\0\377\272" + "=\0\327\272=\0\1\350\322\310\252\362\362\362\1\237\210}\304\37\37\37\7""8" + "88III[[[sssbbbIII===\233\37\37\37\5BBBLLLsss\202\202\202\224\224\224\202" + "sss\2III$$$\220\37\37\37\1V*\24\377\272=\0\377\272=\0\377\272=\0\327\272" + "=\0\1\350\322\310\252\362\362\362\1\237\210}\377\37\37\37\1V*\24\377\272" + "=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\237" + "\210}\377\37\37\37\1V*\24\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350" + "\322\310\252\362\362\362\1\237\210}\377\37\37\37\1V*\24\377\272=\0\377\272" + "=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\237\210}\377\37" + "\37\37\1V*\24\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252" + "\362\362\362\1\237\210}\377\37\37\37\1V*\24\377\272=\0\377\272=\0\377\272" + "=\0\327\272=\0\1\350\322\310\252\362\362\362\1\237\210}\377\37\37\37\1V*" + "\24\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362" + "\362\1\235\207}\377\37\37\37\1]+\23\377\272=\0\377\272=\0\377\272=\0\327" + "\272=\0\1\350\322\310\252\362\362\362\1\233\211\177\377\37\37\37\1`,\22\377" + "\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1" + "\233\211\177\377\37\37\37\1`,\22\377\272=\0\377\272=\0\377\272=\0\327\272" + "=\0\1\350\322\310\252\362\362\362\1\233\211\177\302\37\37\37\4!!![[[sss\207" + "\207\207\203\236\236\236\3\212\212\212sssSSS\252\37\37\37\1BBB\202III\1$" + "$$\205\37\37\37\1`,\22\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350" + "\322\310\252\362\362\362\1\233\211\177\277\37\37\37\4$$$iii\254\254\254\346" + "\346\346\211\362\362\362\3\336\336\336\233\233\233III\212\37\37\37\1nnn\202" + "\236\236\236\1\221\221\221\230\37\37\37\1sss\202\362\362\362\2\324\324\324" + "!!!\205\37\37\37\1`,\22\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350" + "\322\310\252\362\362\362\1\233\211\177\227\37\37\37\1...\211III\1)))\234" + "\37\37\37\2qqq\334\334\334\217\362\362\362\2\231\231\231+++\210\37\37\37" + "\1sss\203\362\362\362\1XXX\226\37\37\37\2!!!\317\317\317\202\362\362\362" + "\1vvv\206\37\37\37\1`,\22\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350" + "\322\310\252\362\362\362\1\233\211\177\212\37\37\37\1""333\202\310\310\310" + "\1\324\324\324\225\362\362\362\3\303\303\303\214\214\214XXX\226\37\37\37" + "\2""333\273\273\273\222\362\362\362\2\336\336\336GGG\207\37\37\37\2$$$\336" + "\336\336\202\362\362\362\1\266\266\266\226\37\37\37\1```\202\362\362\362" + "\2\341\341\341&&&\206\37\37\37\1`,\22\377\272=\0\377\272=\0\377\272=\0\327" + "\272=\0\1\350\322\310\252\362\362\362\1\233\211\177\212\37\37\37\1""888\233" + "\362\362\362\3\322\322\322nnn!!!\222\37\37\37\2BBB\331\331\331\207\362\362" + "\362\2\322\322\322\305\305\305\203\236\236\236\2\300\300\300\331\331\331" + "\206\362\362\362\2\341\341\341DDD\207\37\37\37\1\205\205\205\203\362\362" + "\362\1GGG\225\37\37\37\1\276\276\276\202\362\362\362\1\214\214\214\207\37" + "\37\37\1`,\22\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252" + "\362\362\362\1\233\211\177\212\37\37\37\1""888\235\362\362\362\2\327\327" + "\327VVV\220\37\37\37\2===\336\336\336\205\362\362\362\3\310\310\310\200\200" + "\200888\207\37\37\37\3===\202\202\202\334\334\334\204\362\362\362\2\341\341" + "\341:::\206\37\37\37\2+++\350\350\350\202\362\362\362\1\250\250\250\224\37" + "\37\37\1NNN\202\362\362\362\2\353\353\353333\207\37\37\37\1e-\21\377\272" + "=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\233" + "\211\177\212\37\37\37\1""888\237\362\362\362\1\202\202\202\216\37\37\37\2" + "&&&\317\317\317\204\362\362\362\2\336\336\336lll\214\37\37\37\2&&&\214\214" + "\214\204\362\362\362\1\276\276\276\207\37\37\37\1\226\226\226\202\362\362" + "\362\2\360\360\360888\223\37\37\37\1\252\252\252\202\362\362\362\1\236\236" + "\236\210\37\37\37\1h-\20\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350" + "\322\310\252\362\362\362\1\233\211\177\212\37\37\37\1""888\240\362\362\362" + "\1\231\231\231\215\37\37\37\1\233\233\233\204\362\362\362\2\300\300\300+" + "++\217\37\37\37\2qqq\360\360\360\203\362\362\362\1iii\206\37\37\37\2""88" + "8\360\360\360\202\362\362\362\1\231\231\231\222\37\37\37\2===\360\360\360" + "\202\362\362\362\1BBB\210\37\37\37\1h-\20\377\272=\0\377\272=\0\377\272=" + "\0\327\272=\0\1\350\322\310\252\362\362\362\1\233\211\177\212\37\37\37\1" + """555\241\362\362\362\1}}}\213\37\37\37\2GGG\360\360\360\203\362\362\362" + "\2\271\271\271&&&\221\37\37\37\1sss\203\362\362\362\2\324\324\324!!!\206" + "\37\37\37\1\250\250\250\202\362\362\362\2\350\350\350000\221\37\37\37\1\231" + "\231\231\202\362\362\362\1\266\266\266\211\37\37\37\1h-\20\377\272=\0\377" + "\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\233\211\177" + "\212\37\37\37\1+++\241\362\362\362\2\360\360\360NNN\212\37\37\37\1\266\266" + "\266\203\362\362\362\2\327\327\327)))\223\37\37\37\1\266\266\266\203\362" + "\362\362\1]]]\206\37\37\37\1GGG\203\362\362\362\1\207\207\207\220\37\37\37" + "\2""000\353\353\353\202\362\362\362\1SSS\211\37\37\37\1h-\20\377\272=\0\377" + "\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\233\211\177" + "\212\37\37\37\1+++\242\362\362\362\1\276\276\276\211\37\37\37\1GGG\203\362" + "\362\362\2\360\360\360SSS\224\37\37\37\2""555\355\355\355\202\362\362\362" + "\1\250\250\250\207\37\37\37\1\273\273\273\202\362\362\362\2\341\341\341&" + "&&\217\37\37\37\1\205\205\205\202\362\362\362\1\312\312\312\212\37\37\37" + "\1h-\20\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362" + "\362\362\1\233\211\177\212\37\37\37\1+++\243\362\362\362\1XXX\210\37\37\37" + "\1\224\224\224\203\362\362\362\1\240\240\240\226\37\37\37\1\243\243\243\202" + "\362\362\362\2\346\346\346!!!\206\37\37\37\1[[[\203\362\362\362\1vvv\216" + "\37\37\37\2&&&\341\341\341\202\362\362\362\1lll\212\37\37\37\1h-\20\377\272" + "=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\233" + "\211\177\212\37\37\37\1+++\243\362\362\362\1\300\300\300\207\37\37\37\2!" + "!!\336\336\336\202\362\362\362\2\360\360\360===\226\37\37\37\1SSS\203\362" + "\362\362\1LLL\207\37\37\37\1\315\315\315\202\362\362\362\2\324\324\324!!" + "!\215\37\37\37\1sss\202\362\362\362\2\331\331\331!!!\212\37\37\37\1h-\20" + "\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362" + "\1\233\211\177\212\37\37\37\1+++\244\362\362\362\1???\206\37\37\37\1DDD\203" + "\362\362\362\1\273\273\273\227\37\37\37\2!!!\346\346\346\202\362\362\362" + "\1{{{\207\37\37\37\1lll\203\362\362\362\1ggg\214\37\37\37\2!!!\322\322\322" + "\202\362\362\362\1\200\200\200\213\37\37\37\1m.\17\377\272=\0\377\272=\0" + "\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\233\211\177\212\37" + "\37\37\1+++\214\362\362\362\1\331\331\331\206\310\310\310\1\355\355\355\220" + "\362\362\362\1\202\202\202\206\37\37\37\1\200\200\200\203\362\362\362\1{" + "{{\230\37\37\37\1\271\271\271\202\362\362\362\1\236\236\236\207\37\37\37" + "\2$$$\331\331\331\202\362\362\362\1\310\310\310\214\37\37\37\1```\202\362" + "\362\362\2\350\350\350+++\213\37\37\37\1q/\17\377\272=\0\377\272=\0\377\272" + "=\0\327\272=\0\1\350\322\310\252\362\362\362\1\233\211\177\212\37\37\37\1" + "+++\212\362\362\362\1\331\331\331\211\37\37\37\3$$$```\276\276\276\215\362" + "\362\362\1\261\261\261\206\37\37\37\1\250\250\250\203\362\362\362\1DDD\230" + "\37\37\37\1\221\221\221\202\362\362\362\1\273\273\273\210\37\37\37\1\200" + "\200\200\203\362\362\362\1VVV\213\37\37\37\1\303\303\303\202\362\362\362" + "\1\224\224\224\214\37\37\37\1q/\17\377\272=\0\377\272=\0\377\272=\0\327\272" + "=\0\1\350\322\310\252\362\362\362\1\233\211\177\212\37\37\37\1+++\212\362" + "\362\362\1\331\331\331\214\37\37\37\1xxx\214\362\362\362\1\336\336\336\206" + "\37\37\37\1\315\315\315\202\362\362\362\2\353\353\353!!!\230\37\37\37\1{" + "{{\202\362\362\362\1\317\317\317\210\37\37\37\2)))\346\346\346\202\362\362" + "\362\1\266\266\266\212\37\37\37\1NNN\202\362\362\362\2\360\360\360888\214" + "\37\37\37\1q/\17\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310" + "\252\362\362\362\1\233\211\177\212\37\37\37\1)))\212\362\362\362\1\331\331" + "\331\215\37\37\37\1\224\224\224\214\362\362\362\1)))\205\37\37\37\1\353\353" + "\353\202\362\362\362\1\312\312\312\231\37\37\37\1ggg\202\362\362\362\1\341" + "\341\341\211\37\37\37\1\221\221\221\203\362\362\362\1DDD\211\37\37\37\1\257" + "\257\257\202\362\362\362\1\252\252\252\215\37\37\37\1q/\17\377\272=\0\377" + "\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\233\211\177" + "\213\37\37\37\212\362\362\362\1\331\331\331\215\37\37\37\2+++\350\350\350" + "\213\362\362\362\1???\204\37\37\37\1+++\203\362\362\362\1\264\264\264\231" + "\37\37\37\1]]]\202\362\362\362\1\346\346\346\211\37\37\37\2""333\355\355" + "\355\202\362\362\362\1\245\245\245\210\37\37\37\2===\360\360\360\202\362" + "\362\362\1III\215\37\37\37\1q/\17\377\272=\0\377\272=\0\377\272=\0\327\272" + "=\0\1\350\322\310\252\362\362\362\1\233\211\177\213\37\37\37\212\362\362" + "\362\1\331\331\331\216\37\37\37\1\233\233\233\213\362\362\362\1III\204\37" + "\37\37\1???\203\362\362\362\1\243\243\243\231\37\37\37\1]]]\202\362\362\362" + "\1\350\350\350\212\37\37\37\1\243\243\243\202\362\362\362\2\360\360\3608" + "88\207\37\37\37\1\233\233\233\202\362\362\362\1\276\276\276\216\37\37\37" + "\1q/\17\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362" + "\362\362\1\233\211\177\213\37\37\37\212\362\362\362\1\331\331\331\216\37" + "\37\37\1nnn\213\362\362\362\1QQQ\204\37\37\37\1GGG\203\362\362\362\1\233" + "\233\233\231\37\37\37\1]]]\202\362\362\362\1\346\346\346\212\37\37\37\1B" + "BB\203\362\362\362\1\226\226\226\206\37\37\37\2""000\353\353\353\202\362" + "\362\362\1```\216\37\37\37\1q/\17\377\272=\0\377\272=\0\377\272=\0\327\272" + "=\0\1\350\322\310\252\362\362\362\1\233\211\177\213\37\37\37\212\362\362" + "\362\1\331\331\331\216\37\37\37\1VVV\213\362\362\362\1LLL\204\37\37\37\1" + "QQQ\203\362\362\362\1\233\233\233\231\37\37\37\1]]]\202\362\362\362\1\346" + "\346\346\213\37\37\37\1\266\266\266\202\362\362\362\2\350\350\350...\205" + "\37\37\37\1\212\212\212\202\362\362\362\2\322\322\322!!!\216\37\37\37\1v" + "0\16\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362" + "\362\1\233\211\177\213\37\37\37\212\362\362\362\1\331\331\331\216\37\37\37" + "\1III\213\362\362\362\1BBB\204\37\37\37\1QQQ\203\362\362\362\1\221\221\221" + "\231\37\37\37\1]]]\202\362\362\362\1\346\346\346\213\37\37\37\1SSS\203\362" + "\362\362\1\205\205\205\204\37\37\37\2&&&\341\341\341\202\362\362\362\1ss" + "s\217\37\37\37\1{1\15\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322" + "\310\252\362\362\362\1\233\211\177\213\37\37\37\212\362\362\362\1\331\331" + "\331\216\37\37\37\1DDD\213\362\362\362\1""888\204\37\37\37\1QQQ\203\362\362" + "\362\1\217\217\217\231\37\37\37\1ggg\202\362\362\362\1\346\346\346\214\37" + "\37\37\1\310\310\310\202\362\362\362\2\336\336\336&&&\203\37\37\37\1vvv\202" + "\362\362\362\2\341\341\341&&&\217\37\37\37\1{1\15\377\272=\0\377\272=\0\377" + "\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\233\211\177\213\37\37" + "\37\212\362\362\362\1\331\331\331\216\37\37\37\1III\212\362\362\362\2\360" + "\360\360$$$\204\37\37\37\1QQQ\203\362\362\362\1\217\217\217\231\37\37\37" + "\1iii\202\362\362\362\1\346\346\346\214\37\37\37\1ggg\203\362\362\362\1s" + "ss\202\37\37\37\2!!!\324\324\324\202\362\362\362\1\214\214\214\220\37\37" + "\37\1{1\15\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252" + "\362\362\362\1\233\211\177\213\37\37\37\212\362\362\362\1\331\331\331\216" + "\37\37\37\1]]]\212\362\362\362\1\327\327\327\205\37\37\37\1QQQ\203\362\362" + "\362\1\217\217\217\231\37\37\37\1iii\202\362\362\362\1\331\331\331\214\37" + "\37\37\2!!!\327\327\327\202\362\362\362\4\324\324\324!!!\37\37\37bbb\202" + "\362\362\362\2\353\353\353000\220\37\37\37\1{1\15\377\272=\0\377\272=\0\377" + "\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\233\211\177\213\37\37" + "\37\1\360\360\360\211\362\362\362\1\346\346\346\216\37\37\37\1}}}\212\362" + "\362\362\1\252\252\252\205\37\37\37\1[[[\203\362\362\362\1\217\217\217\231" + "\37\37\37\1iii\202\362\362\362\1\331\331\331\215\37\37\37\1xxx\203\362\362" + "\362\3eee\37\37\37\303\303\303\202\362\362\362\1\236\236\236\221\37\37\37" + "\1{1\15\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362" + "\362\362\1\233\211\177\213\37\37\37\1\346\346\346\211\362\362\362\1\346\346" + "\346\216\37\37\37\1\261\261\261\212\362\362\362\1vvv\205\37\37\37\1]]]\203" + "\362\362\362\1\217\217\217\231\37\37\37\1iii\202\362\362\362\1\331\331\331" + "\215\37\37\37\2)))\341\341\341\202\362\362\362\2\305\305\305QQQ\203\362\362" + "\362\1BBB\221\37\37\37\1{1\15\377\272=\0\377\272=\0\377\272=\0\327\272=\0" + "\1\350\322\310\252\362\362\362\1\233\211\177\213\37\37\37\1\346\346\346\211" + "\362\362\362\1\346\346\346\215\37\37\37\2""333\353\353\353\211\362\362\362" + "\2\360\360\360555\205\37\37\37\1]]]\203\362\362\362\1\217\217\217\231\37" + "\37\37\1nnn\202\362\362\362\1\331\331\331\216\37\37\37\1\214\214\214\203" + "\362\362\362\1\324\324\324\202\362\362\362\1\261\261\261\222\37\37\37\1{" + "1\15\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362" + "\362\1\233\211\177\213\37\37\37\1\346\346\346\211\362\362\362\1\346\346\346" + "\215\37\37\37\1\217\217\217\212\362\362\362\1\271\271\271\206\37\37\37\1" + "]]]\203\362\362\362\1\217\217\217\231\37\37\37\1vvv\202\362\362\362\1\331" + "\331\331\216\37\37\37\2""000\353\353\353\205\362\362\362\1SSS\222\37\37\37" + "\1~2\14\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362" + "\362\362\1\233\211\177\213\37\37\37\1\346\346\346\211\362\362\362\1\346\346" + "\346\214\37\37\37\2XXX\360\360\360\212\362\362\362\1VVV\206\37\37\37\1]]" + "]\203\362\362\362\1\217\217\217\231\37\37\37\1vvv\202\362\362\362\1\317\317" + "\317\217\37\37\37\1\236\236\236\204\362\362\362\1\312\312\312\223\37\37\37" + "\1\2033\13\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252" + "\362\362\362\1\233\211\177\213\37\37\37\1\346\346\346\211\362\362\362\1\346" + "\346\346\213\37\37\37\2```\346\346\346\212\362\362\362\1\271\271\271\207" + "\37\37\37\1]]]\203\362\362\362\1\217\217\217\231\37\37\37\1vvv\202\362\362" + "\362\1\315\315\315\217\37\37\37\2===\360\360\360\203\362\362\362\1iii\223" + "\37\37\37\1\2033\13\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322" + "\310\252\362\362\362\1\233\211\177\213\37\37\37\1\346\346\346\211\362\362" + "\362\1\346\346\346\211\37\37\37\2III\252\252\252\213\362\362\362\2\346\346" + "\346:::\207\37\37\37\1]]]\203\362\362\362\1\217\217\217\231\37\37\37\1vv" + "v\202\362\362\362\1\315\315\315\220\37\37\37\1\276\276\276\203\362\362\362" + "\1:::\223\37\37\37\1\2033\13\377\272=\0\377\272=\0\377\272=\0\327\272=\0" + "\1\350\322\310\252\362\362\362\1\233\211\177\213\37\37\37\1\346\346\346\211" + "\362\362\362\1\346\346\346\203\37\37\37\6&&&IIIggg\217\217\217\264\264\264" + "\334\334\334\215\362\362\362\1iii\210\37\37\37\1]]]\203\362\362\362\1\217" + "\217\217\231\37\37\37\1vvv\202\362\362\362\1\315\315\315\217\37\37\37\2""0" + "00\350\350\350\203\362\362\362\1\233\233\233\223\37\37\37\1\2033\13\377\272" + "=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\233" + "\211\177\213\37\37\37\1\346\346\346\211\362\362\362\3\360\360\360\310\310" + "\310\341\341\341\223\362\362\362\1}}}\211\37\37\37\1]]]\203\362\362\362\1" + "\207\207\207\231\37\37\37\1\202\202\202\202\362\362\362\1\315\315\315\217" + "\37\37\37\1\212\212\212\204\362\362\362\2\353\353\353333\222\37\37\37\1\203" + "3\13\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362" + "\362\1\233\211\177\213\37\37\37\1\346\346\346\236\362\362\362\1\226\226\226" + "\212\37\37\37\1]]]\203\362\362\362\1\202\202\202\231\37\37\37\1\202\202\202" + "\202\362\362\362\1\305\305\305\216\37\37\37\2)))\343\343\343\205\362\362" + "\362\1\217\217\217\222\37\37\37\1\2033\13\377\272=\0\377\272=\0\377\272=" + "\0\327\272=\0\1\350\322\310\252\362\362\362\1\233\211\177\213\37\37\37\1" + "\331\331\331\236\362\362\362\3\353\353\353\221\221\221)))\210\37\37\37\1" + "]]]\203\362\362\362\1\202\202\202\231\37\37\37\1\202\202\202\202\362\362" + "\362\1\300\300\300\216\37\37\37\1}}}\203\362\362\362\1\346\346\346\202\362" + "\362\362\2\350\350\350+++\221\37\37\37\1\2033\13\377\272=\0\377\272=\0\377" + "\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\233\211\177\213\37\37" + "\37\1\331\331\331\240\362\362\362\2\322\322\322BBB\207\37\37\37\1]]]\203" + "\362\362\362\1\202\202\202\231\37\37\37\1\202\202\202\202\362\362\362\1\300" + "\300\300\215\37\37\37\2$$$\334\334\334\202\362\362\362\2\266\266\266}}}\203" + "\362\362\362\1\207\207\207\221\37\37\37\1\2053\13\377\272=\0\377\272=\0\377" + "\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\225\206\177\213\37\37" + "\37\1\331\331\331\241\362\362\362\2\346\346\346LLL\206\37\37\37\1]]]\203" + "\362\362\362\1\202\202\202\231\37\37\37\1\202\202\202\202\362\362\362\1\300" + "\300\300\215\37\37\37\1qqq\203\362\362\362\3SSS)))\341\341\341\202\362\362" + "\362\2\341\341\341)))\220\37\37\37\1\2155\11\377\272=\0\377\272=\0\377\272" + "=\0\327\272=\0\1\350\322\310\252\362\362\362\1\225\206\177\213\37\37\37\1" + "\331\331\331\242\362\362\362\2\346\346\346BBB\205\37\37\37\1]]]\203\362\362" + "\362\1\202\202\202\231\37\37\37\1\214\214\214\202\362\362\362\1\300\300\300" + "\214\37\37\37\2!!!\322\322\322\202\362\362\362\1\303\303\303\202\37\37\37" + "\1\207\207\207\203\362\362\362\1}}}\220\37\37\37\1\2155\11\377\272=\0\377" + "\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\225\206\177" + "\213\37\37\37\1\331\331\331\243\362\362\362\2\317\317\317$$$\204\37\37\37" + "\1]]]\203\362\362\362\1\202\202\202\231\37\37\37\1\217\217\217\202\362\362" + "\362\1\273\273\273\214\37\37\37\1eee\203\362\362\362\1bbb\202\37\37\37\2" + "+++\346\346\346\202\362\362\362\2\334\334\334$$$\217\37\37\37\1\2155\11\377" + "\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1" + "\225\206\177\213\37\37\37\1\331\331\331\244\362\362\362\1\217\217\217\204" + "\37\37\37\1eee\203\362\362\362\1\202\202\202\231\37\37\37\1\217\217\217\202" + "\362\362\362\1\264\264\264\214\37\37\37\1\310\310\310\202\362\362\362\2\317" + "\317\317!!!\203\37\37\37\1\212\212\212\203\362\362\362\1sss\217\37\37\37" + "\1\2155\11\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252" + "\362\362\362\1\225\206\177\213\37\37\37\1\331\331\331\244\362\362\362\2\350" + "\350\350000\203\37\37\37\1iii\203\362\362\362\1\202\202\202\231\37\37\37" + "\1\217\217\217\202\362\362\362\1\264\264\264\213\37\37\37\1XXX\203\362\362" + "\362\1nnn\204\37\37\37\2...\350\350\350\202\362\362\362\2\324\324\324!!!" + "\216\37\37\37\1\2155\11\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350" + "\322\310\252\362\362\362\1\225\206\177\213\37\37\37\1\331\331\331\245\362" + "\362\362\1\221\221\221\203\37\37\37\1iii\203\362\362\362\1\202\202\202\231" + "\37\37\37\1\217\217\217\202\362\362\362\1\264\264\264\213\37\37\37\1\273" + "\273\273\202\362\362\362\2\331\331\331$$$\205\37\37\37\1\224\224\224\203" + "\362\362\362\1iii\216\37\37\37\1\2155\11\377\272=\0\377\272=\0\377\272=\0" + "\327\272=\0\1\350\322\310\252\362\362\362\1\225\206\177\213\37\37\37\1\331" + "\331\331\221\362\362\362\1\353\353\353\202\310\310\310\1\324\324\324\220" + "\362\362\362\2\341\341\341!!!\202\37\37\37\1iii\203\362\362\362\1\202\202" + "\202\231\37\37\37\1\224\224\224\202\362\362\362\1\264\264\264\212\37\37\37" + "\1LLL\203\362\362\362\1{{{\206\37\37\37\2""333\353\353\353\202\362\362\362" + "\1\315\315\315\216\37\37\37\1\2155\11\377\272=\0\377\272=\0\377\272=\0\327" + "\272=\0\1\350\322\310\252\362\362\362\1\225\206\177\213\37\37\37\1\315\315" + "\315\211\362\362\362\7\355\355\355\236\236\236\224\224\224sssbbbIII000\206" + "\37\37\37\3LLL\207\207\207\341\341\341\215\362\362\362\1QQQ\202\37\37\37" + "\1iii\203\362\362\362\1\202\202\202\231\37\37\37\1\233\233\233\202\362\362" + "\362\1\261\261\261\212\37\37\37\1\257\257\257\202\362\362\362\2\341\341\341" + ")))\207\37\37\37\1\226\226\226\203\362\362\362\1```\215\37\37\37\1\2175\11" + "\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362" + "\1\225\206\177\213\37\37\37\1\315\315\315\211\362\362\362\1\353\353\353\216" + "\37\37\37\2+++\254\254\254\214\362\362\362\1\214\214\214\202\37\37\37\1i" + "ii\203\362\362\362\1}}}\231\37\37\37\1\233\233\233\202\362\362\362\1\250" + "\250\250\211\37\37\37\1BBB\203\362\362\362\1\207\207\207\210\37\37\37\2""5" + "55\355\355\355\202\362\362\362\1\305\305\305\215\37\37\37\1\2276\7\377\272" + "=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\225" + "\206\177\213\37\37\37\1\315\315\315\212\362\362\362\220\37\37\37\1\250\250" + "\250\213\362\362\362\1\264\264\264\202\37\37\37\1iii\203\362\362\362\1vv" + "v\231\37\37\37\1\233\233\233\202\362\362\362\1\250\250\250\211\37\37\37\1" + "\245\245\245\202\362\362\362\2\350\350\350000\211\37\37\37\1\240\240\240" + "\203\362\362\362\1VVV\214\37\37\37\1\2276\7\377\272=\0\377\272=\0\377\272" + "=\0\327\272=\0\1\350\322\310\252\362\362\362\1\225\206\177\213\37\37\37\1" + "\315\315\315\212\362\362\362\220\37\37\37\2)))\343\343\343\212\362\362\362" + "\1\336\336\336\202\37\37\37\1iii\203\362\362\362\1vvv\231\37\37\37\1\233" + "\233\233\202\362\362\362\1\250\250\250\210\37\37\37\2""888\360\360\360\202" + "\362\362\362\1\226\226\226\212\37\37\37\2:::\360\360\360\202\362\362\362" + "\1\273\273\273\214\37\37\37\1\2276\7\377\272=\0\377\272=\0\377\272=\0\327" + "\272=\0\1\350\322\310\252\362\362\362\1\225\206\177\213\37\37\37\1\315\315" + "\315\212\362\362\362\221\37\37\37\1\207\207\207\213\362\362\362\3+++\37\37" + "\37iii\203\362\362\362\1vvv\231\37\37\37\1\233\233\233\202\362\362\362\1" + "\250\250\250\210\37\37\37\1\231\231\231\202\362\362\362\2\355\355\355888" + "\213\37\37\37\1\243\243\243\203\362\362\362\1LLL\213\37\37\37\1\2276\7\377" + "\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1" + "\225\206\177\213\37\37\37\1\315\315\315\212\362\362\362\221\37\37\37\1DD" + "D\213\362\362\362\3???\37\37\37iii\203\362\362\362\1vvv\231\37\37\37\1\250" + "\250\250\202\362\362\362\1\240\240\240\207\37\37\37\2""000\353\353\353\202" + "\362\362\362\1\243\243\243\214\37\37\37\2???\360\360\360\202\362\362\362" + "\1\257\257\257\213\37\37\37\1\2276\7\377\272=\0\377\272=\0\377\272=\0\327" + "\272=\0\1\350\322\310\252\362\362\362\1\225\206\177\213\37\37\37\1\315\315" + "\315\212\362\362\362\221\37\37\37\2!!!\346\346\346\212\362\362\362\3NNN\37" + "\37\37iii\203\362\362\362\1vvv\231\37\37\37\1\254\254\254\202\362\362\362" + "\1\226\226\226\207\37\37\37\1\214\214\214\202\362\362\362\2\360\360\360B" + "BB\215\37\37\37\1\252\252\252\203\362\362\362\1BBB\212\37\37\37\1\2276\7" + "\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362" + "\1\225\206\177\213\37\37\37\1\315\315\315\212\362\362\362\222\37\37\37\1" + "\310\310\310\212\362\362\362\3QQQ\37\37\37iii\203\362\362\362\1vvv\231\37" + "\37\37\1\271\271\271\202\362\362\362\1\214\214\214\206\37\37\37\2)))\346" + "\346\346\202\362\362\362\1\257\257\257\216\37\37\37\1DDD\203\362\362\362" + "\1\250\250\250\212\37\37\37\1\2276\7\377\272=\0\377\272=\0\377\272=\0\327" + "\272=\0\1\350\322\310\252\362\362\362\1\225\206\177\213\37\37\37\1\315\315" + "\315\212\362\362\362\222\37\37\37\1\273\273\273\212\362\362\362\3QQQ\37\37" + "\37iii\203\362\362\362\1vvv\231\37\37\37\1\317\317\317\202\362\362\362\1" + "sss\206\37\37\37\1\200\200\200\203\362\362\362\1LLL\217\37\37\37\1\257\257" + "\257\202\362\362\362\2\360\360\360:::\211\37\37\37\1\2276\7\377\272=\0\377" + "\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\225\206\177" + "\213\37\37\37\1\300\300\300\212\362\362\362\222\37\37\37\1\271\271\271\212" + "\362\362\362\3GGG\37\37\37iii\203\362\362\362\1vvv\230\37\37\37\2!!!\350" + "\350\350\202\362\362\362\1XXX\205\37\37\37\2$$$\336\336\336\202\362\362\362" + "\1\276\276\276\220\37\37\37\1III\203\362\362\362\1\236\236\236\211\37\37" + "\37\1\2378\5\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252" + "\362\362\362\1\225\206\177\213\37\37\37\1\300\300\300\212\362\362\362\222" + "\37\37\37\1\300\300\300\212\362\362\362\3""888\37\37\37iii\203\362\362\362" + "\1\200\200\200\230\37\37\37\1DDD\203\362\362\362\1""333\205\37\37\37\1ss" + "s\203\362\362\362\1[[[\221\37\37\37\1\266\266\266\202\362\362\362\2\355\355" + "\355555\210\37\37\37\1\2378\5\377\272=\0\377\272=\0\377\272=\0\327\272=\0" + "\1\350\322\310\252\362\362\362\1\225\206\177\213\37\37\37\1\300\300\300\212" + "\362\362\362\222\37\37\37\1\324\324\324\211\362\362\362\4\360\360\360$$$" + "\37\37\37```\203\362\362\362\1\217\217\217\230\37\37\37\1vvv\202\362\362" + "\362\1\327\327\327\205\37\37\37\2!!!\324\324\324\202\362\362\362\1\312\312" + "\312\222\37\37\37\1QQQ\203\362\362\362\1\224\224\224\210\37\37\37\1\2378" + "\5\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362" + "\362\1\225\206\177\213\37\37\37\1\300\300\300\212\362\362\362\221\37\37\37" + "\2!!!\355\355\355\211\362\362\362\1\327\327\327\202\37\37\37\1QQQ\203\362" + "\362\362\1\250\250\250\230\37\37\37\1\271\271\271\202\362\362\362\1\250\250" + "\250\205\37\37\37\1ggg\203\362\362\362\1ggg\223\37\37\37\1\273\273\273\202" + "\362\362\362\2\350\350\350...\207\37\37\37\1\2378\5\377\272=\0\377\272=\0" + "\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\225\206\177\213\37" + "\37\37\1\300\300\300\212\362\362\362\221\37\37\37\1GGG\212\362\362\362\1" + "\264\264\264\202\37\37\37\1:::\203\362\362\362\1\327\327\327\227\37\37\37" + "\1GGG\203\362\362\362\1```\205\37\37\37\1\312\312\312\202\362\362\362\2\324" + "\324\324!!!\223\37\37\37\1VVV\203\362\362\362\1\212\212\212\207\37\37\37" + "\1\2378\5\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362" + "\362\362\1\225\206\177\213\37\37\37\1\300\300\300\212\362\362\362\1!!!\220" + "\37\37\37\1\202\202\202\212\362\362\362\1\205\205\205\202\37\37\37\2!!!\346" + "\346\346\203\362\362\362\1""555\226\37\37\37\1\245\245\245\202\362\362\362" + "\2\336\336\336&&&\204\37\37\37\1[[[\203\362\362\362\1sss\225\37\37\37\1\303" + "\303\303\202\362\362\362\2\343\343\343)))\206\37\37\37\1\2378\5\377\272=" + "\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\225\206" + "\177\213\37\37\37\1\300\300\300\212\362\362\362\1+++\220\37\37\37\1\317\317" + "\317\212\362\362\362\1QQQ\203\37\37\37\1\264\264\264\203\362\362\362\1ss" + "s\225\37\37\37\2GGG\355\355\355\202\362\362\362\1\202\202\202\205\37\37\37" + "\1\276\276\276\202\362\362\362\2\336\336\336$$$\225\37\37\37\1]]]\203\362" + "\362\362\1\200\200\200\206\37\37\37\1\2378\5\377\272=\0\377\272=\0\377\272" + "=\0\327\272=\0\1\350\322\310\252\362\362\362\1\225\206\177\213\37\37\37\1" + "\300\300\300\212\362\362\362\1+++\217\37\37\37\1iii\212\362\362\362\2\343" + "\343\343!!!\203\37\37\37\1\202\202\202\203\362\362\362\2\324\324\324!!!\223" + "\37\37\37\2&&&\317\317\317\202\362\362\362\2\346\346\346+++\204\37\37\37" + "\1NNN\203\362\362\362\1\200\200\200\227\37\37\37\4\310\310\310\362\362\362" + "\310\310\310\212\212\212\206\37\37\37\1\2378\5\377\272=\0\377\272=\0\377" + "\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\225\206\177\213\37\37" + "\37\1\300\300\300\212\362\362\362\1+++\216\37\37\37\2""555\336\336\336\212" + "\362\362\362\1\240\240\240\204\37\37\37\1QQQ\204\362\362\362\1ggg\222\37" + "\37\37\2!!!\245\245\245\203\362\362\362\1\214\214\214\205\37\37\37\1\261" + "\261\261\202\362\362\362\2\346\346\346+++\227\37\37\37\1""555\211\37\37\37" + "\1\250:\4\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362" + "\362\362\1\225\206\177\213\37\37\37\1\264\264\264\212\362\362\362\1+++\215" + "\37\37\37\2""888\317\317\317\213\362\362\362\1LLL\205\37\37\37\1\322\322" + "\322\203\362\362\362\2\346\346\346:::\220\37\37\37\2$$$\252\252\252\203\362" + "\362\362\2\322\322\322$$$\204\37\37\37\1DDD\203\362\362\362\1\217\217\217" + "\242\37\37\37\1\250:\4\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350" + "\322\310\252\362\362\362\1\225\206\177\213\37\37\37\1\264\264\264\212\362" + "\362\362\1+++\214\37\37\37\2sss\350\350\350\213\362\362\362\1\300\300\300" + "\206\37\37\37\1sss\204\362\362\362\2\312\312\312333\216\37\37\37\2===\276" + "\276\276\203\362\362\362\2\353\353\353DDD\205\37\37\37\1\250\250\250\202" + "\362\362\362\2\353\353\353333\242\37\37\37\1\250:\4\377\272=\0\377\272=\0" + "\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362\1\225\206\177\213\37" + "\37\37\1\264\264\264\212\362\362\362\1+++\211\37\37\37\3""888\200\200\200" + "\327\327\327\215\362\362\362\1NNN\206\37\37\37\2!!!\322\322\322\204\362\362" + "\362\2\331\331\331QQQ\213\37\37\37\3...\212\212\212\353\353\353\203\362\362" + "\362\2\360\360\360```\205\37\37\37\2:::\360\360\360\202\362\362\362\1\233" + "\233\233\243\37\37\37\1\250:\4\377\272=\0\377\272=\0\377\272=\0\327\272=" + "\0\1\350\322\310\252\362\362\362\1\225\206\177\213\37\37\37\1\264\264\264" + "\212\362\362\362\1+++\204\37\37\37\5+++NNNsss\243\243\243\327\327\327\217" + "\362\362\362\1\257\257\257\210\37\37\37\2LLL\355\355\355\205\362\362\362" + "\3\266\266\266]]]!!!\205\37\37\37\4""000bbb\245\245\245\355\355\355\204\362" + "\362\362\2\355\355\355eee\206\37\37\37\5\233\233\233\362\362\362\353\353" + "\353\310\310\310:::\243\37\37\37\1\250:\4\377\272=\0\377\272=\0\377\272=" + "\0\327\272=\0\1\350\322\310\252\362\362\362\1\225\206\177\213\37\37\37\1" + "\264\264\264\212\362\362\362\5vvv\205\205\205\240\240\240\310\310\310\343" + "\343\343\223\362\362\362\2\353\353\353===\211\37\37\37\1iii\207\362\362\362" + "\1\360\360\360\202\310\310\310\3\264\264\264\310\310\310\324\324\324\207" + "\362\362\362\2\334\334\334SSS\207\37\37\37\2VVV:::\246\37\37\37\1\250:\4" + "\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362\362" + "\1\225\206\177\213\37\37\37\1\264\264\264\242\362\362\362\1xxx\213\37\37" + "\37\2```\350\350\350\221\362\362\362\2\231\231\231)))\260\37\37\37\1\250" + ":\4\377\272=\0\377\272=\0\377\272=\0\327\272=\0\1\350\322\310\252\362\362" + "\362\1\225\206\177\213\37\37\37\1\264\264\264\241\362\362\362\1\250\250\250" + "\215\37\37\37\2BBB\303\303\303\215\362\362\362\3\360\360\360\252\252\252" + "III\260\37\37\37\3$\40\36?&\31\255;\3\377\272=\0\377\272=\0\377\272=\0\327" + "\272=\0\1\350\322\310\252\362\362\362\1\225\206\177\213\37\37\37\1\264\264" + "\264\240\362\362\362\2\257\257\257!!!\217\37\37\37\3SSS\264\264\264\350\350" + "\350\207\362\362\362\4\360\360\360\276\276\276\212\212\212333\254\37\37\37" + "\6$\40\36?&\31Y*\23t0\16\2155\11\2469\4\377\272=\0\377\272=\0\377\272=\0" + "\332\272=\0\1\350\322\310\252\362\362\362\1\225\206\177\213\37\37\37\1\264" + "\264\264\237\362\362\362\2\221\221\221!!!\223\37\37\37\1NNN\202sss\5{{{s" + "ssiiiIII$$$\251\37\37\37\6!\40\37?&\31Y*\23q/\17\2134\11\2449\4\377\272=" + "\0\377\272=\0\377\272=\0\340\272=\0\1\344\304\264\252\362\362\362\1\225\206" + "\177\213\37\37\37\1\250\250\250\235\362\362\362\2\353\353\353lll\301\37\37" + "\37\5?&\31X*\24q/\17\2124\12\2439\5\377\272=\0\377\272=\0\377\272=\0\347" + "\272=\0\2\312pD\342\277\256\250\362\362\362\1\225\206\177\213\37\37\37\1" + "\250\250\250\234\362\362\362\2\305\305\305GGG\274\37\37\37\5?&\31V*\24o/" + "\17\2124\12\2418\5\377\272=\0\377\272=\0\377\272=\0\357\272=\0\3\302W\"\332" + "\244\212\357\350\345\245\362\362\362\1\225\206\177\213\37\37\37\1\250\250" + "\250\232\362\362\362\2\317\317\317nnn\270\37\37\37\5=$\31V*\24m.\17\2104" + "\12\2418\5\377\272=\0\377\272=\0\377\272=\0\367\272=\0\3\275F\13\321\211" + "e\351\325\313\243\362\362\362\1\225\206\177\213\37\37\37\1\250\250\250\227" + "\362\362\362\3\346\346\346\250\250\250XXX\264\37\37\37\5:%\32T)\24m.\17\205" + "3\13\2378\5\377\272=\0\377\272=\0\377\272=\0\377\272=\0\3\272=\0\310m@\340" + "\271\246\241\362\362\362\1\225\206\177\213\37\37\37\1\250\250\250\223\362" + "\362\362\5\322\322\322\257\257\257\200\200\200SSS!!!\260\37\37\37\5:%\32" + "S)\25l.\20\2053\13\2368\6\377\272=\0\377\272=\0\377\272=\0\377\272=\0\211" + "\272=\0\3\302S\34\330\240\204\356\345\342\236\362\362\362\1\225\206\177\213" + "\37\37\37\1\250\250\250\215\362\362\362\6\327\327\327\264\264\264\221\221" + "\221nnnIII!!!\257\37\37\37\5:%\32S)\25j.\20\2033\13\2368\6\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\221\272=\0\3\275D\11\320\204^\347\320\305\234" + "\362\362\362\1\225\207\177\213\37\37\37\1\250\250\250\207\362\362\362\6\334" + "\334\334\271\271\271\226\226\226sssIII&&&\257\37\37\37\5""8$\32Q)\25j.\20" + "\2012\13\2347\6\377\272=\0\377\272=\0\377\272=\0\377\272=\0\232\272=\0\3" + "\307h9\337\264\237\361\357\357\231\362\362\362\1\221\207\201\213\37\37\37" + "\10\250\250\250\362\362\362\341\341\341\276\276\276\233\233\233sssNNN+++" + "\257\37\37\37\6""5$\33N(\26h-\20\2012\13\2347\6\270=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\241\272=\0\3\277N\27\327\233}\355\342\337\227\362" + "\362\362\1\221\207\201\213\37\37\37\2:::000\257\37\37\37\6""5$\33N(\26g-" + "\21\2002\14\2347\6\270=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\251" + "\272=\0\3\274B\6\316\177X\346\315\300\225\362\362\362\1\221\207\201\266\37" + "\37\37\6""3#\33N(\26g-\21~2\14\2347\6\267=\1\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\262\272=\0\3\307d3\336\261\232\361\356\355\222\362\362\362" + "\1\221\207\201\260\37\37\37\6""1\"\33L(\26e-\21~2\14\2347\6\265<\1\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\272\272=\0\3\300M\24\325\225u\355\342" + "\333\220\362\362\362\1\221\207\201\252\37\37\37\6""1\"\33I)\27b,\22|1\14" + "\2347\6\265<\1\377\272=\0\377\272=\0\377\272=\0\377\272=\0\302\272=\0\3\273" + "@\3\316~V\346\315\300\216\362\362\362\1\221\207\201\244\37\37\37\6""0\"\34" + "I)\27b,\22|1\14\2317\7\263<\1\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\313\272=\0\3\307d3\336\261\232\361\356\355\213\362\362\362\1\221\207\201" + "\236\37\37\37\6.#\34G'\27b,\22|1\14\2317\7\262<\2\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\323\272=\0\3\300M\24\325\225u\355\342\333\211\362\362" + "\362\1\221\207\201\230\37\37\37\6.#\34E&\27`,\22|1\14\2276\7\262<\2\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\333\272=\0\3\273@\3\315{S\345\310\271" + "\207\362\362\362\1\225\213\205\222\37\37\37\6,\"\34E&\27]+\23|1\14\2276\7" + "\260;\2\377\272=\0\377\272=\0\377\272=\0\377\272=\0\344\272=\0\3\306`.\334" + "\254\224\360\355\352\204\362\362\362\1\234\221\214\214\37\37\37\6+!\35D&" + "\30]+\23|1\14\2246\10\255;\3\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\354\272=\0\3\277J\21\324\221p\353\336\327\202\362\362\362\1\234\221\214" + "\206\37\37\37\6+!\35B'\30]+\23{1\15\2246\10\253:\3\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\365\272=\0\11\314xN\344\304\264\234\221\214)!\35B" + "'\30]+\23y1\15\2225\10\253:\3\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\375\272=\0\1\262A\12\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377" + "\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0" + "\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272" + "=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\377\272=\0\346" + "\272=\0", +}; + diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 68965219..b842c027 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.150 2009-02-25 19:58:11 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.151 2009-05-20 18:26:35 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -33,6 +33,7 @@ #include #endif +#include "cross.h" #include "SDL.h" #include "dosbox.h" @@ -148,6 +149,7 @@ enum PRIORITY_LEVELS { struct SDL_Block { + bool inited; bool active; //If this isn't set don't draw bool updating; struct { @@ -962,9 +964,30 @@ static void SetPriority(PRIORITY_LEVELS level) { } } +extern Bit8u int10_font_14[256 * 14]; +static void OutputString(Bitu x,Bitu y,const char * text,Bit32u color,Bit32u color2,SDL_Surface * output_surface) { + Bit32u * draw=(Bit32u*)(((Bit8u *)output_surface->pixels)+((y)*output_surface->pitch))+x; + while (*text) { + Bit8u * font=&int10_font_14[(*text)*14]; + Bitu i,j; + Bit32u * draw_line=draw; + for (i=0;i<14;i++) { + Bit8u map=*font++; + for (j=0;j<8;j++) { + if (map & 0x80) *((Bit32u*)(draw_line+j))=color; else *((Bit32u*)(draw_line+j))=color2; + map<<=1; + } + draw_line+=output_surface->pitch/4; + } + text++; + draw+=8; + } +} + static unsigned char logo[32*32*4]= { #include "dosbox_logo.h" }; +#include "dosbox_splash.h" //extern void UI_Run(bool); static void GUI_StartUp(Section * sec) { @@ -1134,7 +1157,89 @@ static void GUI_StartUp(Section * sec) { LOG_MSG("SDL:You are running in 24 bpp mode, this will slow down things!"); } GFX_Stop(); -/* Get some Event handlers */ + SDL_WM_SetCaption("DOSBox",VERSION); + +/* The endian part is intentionally disabled as somehow it produces correct results without according to rhoenie*/ +//#if SDL_BYTEORDER == SDL_BIG_ENDIAN +// Bit32u rmask = 0xff000000; +// Bit32u gmask = 0x00ff0000; +// Bit32u bmask = 0x0000ff00; +//#else + Bit32u rmask = 0x000000ff; + Bit32u gmask = 0x0000ff00; + Bit32u bmask = 0x00ff0000; +//#endif + +/* Please leave the Splash screen stuff in working order in DOSBox. We spend a lot of time making DOSBox. */ + SDL_Surface* splash_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, 640, 400, 32, rmask, gmask, bmask, 0); + if (splash_surf) { + SDL_FillRect(splash_surf, NULL, SDL_MapRGB(splash_surf->format, 0, 0, 0)); + + Bit8u* tmpbufp = new Bit8u[640*400*3]; + GIMP_IMAGE_RUN_LENGTH_DECODE(tmpbufp,gimp_image.rle_pixel_data,640*400,3); + for (Bitu y=0; y<400; y++) { + + Bit8u* tmpbuf = tmpbufp + y*640*3; +/* Bit8u * draw=((Bit8u *)splash_surf->pixels)+((399-y)*splash_surf->pitch); + for (Bitu x=0; x<640; x++) { + *draw++ = tmpbuf[x*3+2]; + *draw++ = tmpbuf[x*3+1]; + *draw++ = tmpbuf[x*3+0]; + *draw++ = 0xff; + } */ + Bit32u * draw=(Bit32u*)(((Bit8u *)splash_surf->pixels)+((y)*splash_surf->pitch)); + for (Bitu x=0; x<640; x++) { +//#if SDL_BYTEORDER == SDL_BIG_ENDIAN +// *draw++ = tmpbuf[x*3+2]+tmpbuf[x*3+1]*0x100+tmpbuf[x*3+0]*0x10000+0x00000000; +//#else + *draw++ = tmpbuf[x*3+0]+tmpbuf[x*3+1]*0x100+tmpbuf[x*3+2]*0x10000+0x00000000; +//#endif + } + } + + bool exit_splash = false; + + static Bitu max_splash_loop = 600; + static Bitu splash_fade = 100; + static bool use_fadeout = true; + + for(Bit32u ct = 0,startticks = GetTicks();ct < max_splash_loop;ct = GetTicks()-startticks) { + SDL_Event evt; + while (SDL_PollEvent(&evt)) { + if (evt.type == SDL_QUIT) { + exit_splash = true; + break; + } + } + if (exit_splash) break; + + if (ct<1) { + SDL_FillRect(sdl.surface, NULL, SDL_MapRGB(sdl.surface->format, 0, 0, 0)); + SDL_SetAlpha(splash_surf, SDL_SRCALPHA,255); + SDL_BlitSurface(splash_surf, NULL, sdl.surface, NULL); + SDL_Flip(sdl.surface); + } else if (ct>=max_splash_loop-splash_fade) { + if (use_fadeout) { + SDL_FillRect(sdl.surface, NULL, SDL_MapRGB(sdl.surface->format, 0, 0, 0)); + SDL_SetAlpha(splash_surf, SDL_SRCALPHA, (max_splash_loop-1-ct)*255/(splash_fade-1)); + SDL_BlitSurface(splash_surf, NULL, sdl.surface, NULL); + SDL_Flip(sdl.surface); + } + } + +// SDL_Delay(1); + } + + if (use_fadeout) { + SDL_FillRect(sdl.surface, NULL, SDL_MapRGB(sdl.surface->format, 0, 0, 0)); + SDL_Flip(sdl.surface); + } + SDL_FreeSurface(splash_surf); + delete [] tmpbufp; + + } + + /* Get some Event handlers */ MAPPER_AddHandler(KillSwitch,MK_f9,MMOD1,"shutdown","ShutDown"); MAPPER_AddHandler(CaptureMouse,MK_f10,MMOD1,"capmouse","Cap Mouse"); MAPPER_AddHandler(SwitchFullScreen,MK_return,MMOD2,"fullscr","Fullscreen"); @@ -1423,6 +1528,48 @@ void Config_Add_SDL() { Pbool->Set_help("Avoid usage of symkeys, might not work on all operating systems."); } +static void show_warning(char const * const message) { + bool textonly = true; +#ifdef WIN32 + textonly = false; + if ( !sdl.inited && SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE) < 0 ) textonly = true; + sdl.inited = true; +#endif + printf(message); + if(textonly) return; + if(!sdl.surface) sdl.surface = SDL_SetVideoMode(640,400,0,0); + if(!sdl.surface) return; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + Bit32u rmask = 0xff000000; + Bit32u gmask = 0x00ff0000; + Bit32u bmask = 0x0000ff00; +#else + Bit32u rmask = 0x000000ff; + Bit32u gmask = 0x0000ff00; + Bit32u bmask = 0x00ff0000; +#endif + SDL_Surface* splash_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, 640, 400, 32, rmask, gmask, bmask, 0); + if (!splash_surf) return; + + int x = 120,y = 20; + std::string m(message),m2; + std::string::size_type a,b,c,d; + + while(m.size()) { //Max 50 characters. break on space before or on a newline + c = m.find('\n'); + d = m.rfind(' ',50); + if(c>d) a=b=d; else a=b=c; + if( a != std::string::npos) b++; + m2 = m.substr(0,a); m.erase(0,b); + OutputString(x,y,m2.c_str(),0xffffffff,0,splash_surf); + y += 20; + } + + SDL_BlitSurface(splash_surf, NULL, sdl.surface, NULL); + SDL_Flip(sdl.surface); + SDL_Delay(10000); +} + static void launcheditor(std::string const& edit) { std::string path,file; Cross::CreatePlatformConfigDir(path); @@ -1434,16 +1581,42 @@ static void launcheditor(std::string const& edit) { exit(1); } if(f) fclose(f); - if(edit.empty()) { +/* if(edit.empty()) { printf("no editor specified.\n"); exit(1); - } + }*/ execlp(edit.c_str(),edit.c_str(),path.c_str(),(char*) 0); //if you get here the launching failed! printf("can't find editor %s\n",edit.c_str()); exit(1); } +static void launchcaptures(std::string const& edit) { + std::string path,file; + Section* t = control->GetSection("dosbox"); + if(t) file = t->GetPropValue("captures"); + if(!t || file == NO_SUCH_PROPERTY) { + printf("Config system messed up.\n"); + exit(1); + } + Cross::CreatePlatformConfigDir(path); + path += file; + Cross::CreateDir(path); + struct stat cstat; + if(stat(path.c_str(),&cstat) || (cstat.st_mode & S_IFDIR) == 0) { + printf("%s doesn't exists or isn't a directory.\n",path.c_str()); + exit(1); + } +/* if(edit.empty()) { + printf("no editor specified.\n"); + exit(1); + }*/ + + execlp(edit.c_str(),edit.c_str(),path.c_str(),(char*) 0); + //if you get here the launching failed! + printf("can't find filemanager %s\n",edit.c_str()); + exit(1); +} static void printconfiglocation() { std::string path,file; @@ -1460,6 +1633,24 @@ static void printconfiglocation() { exit(0); } +static void eraseconfigfile() { + FILE* f = fopen("dosbox.conf","r"); + if(f) { + fclose(f); + show_warning("Warning: dosbox.conf exists in current working directory.\nThis will override the configuration file at runtime.\n"); + } + std::string path,file; + Cross::GetPlatformConfigDir(path); + Cross::GetPlatformConfigName(file); + path += file; + f = fopen(path.c_str(),"r"); + if(!f) exit(0); + fclose(f); + unlink(path.c_str()); + exit(0); +} + + //extern void UI_Init(void); int main(int argc, char* argv[]) { @@ -1473,6 +1664,8 @@ int main(int argc, char* argv[]) { std::string editor; if(control->cmdline->FindString("-editconf",editor,true)) launcheditor(editor); + if(control->cmdline->FindString("-opencaptures",editor,true)) launchcaptures(editor); + if(control->cmdline->FindExist("-eraseconf")) eraseconfigfile(); /* Can't disable the console with debugger enabled */ #if defined(WIN32) && !(C_DEBUG) @@ -1534,6 +1727,7 @@ int main(int argc, char* argv[]) { if ( SDL_Init( SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM |SDL_INIT_NOPARACHUTE ) < 0 ) E_Exit("Can't init SDL %s",SDL_GetError()); + sdl.inited = true; #ifndef DISABLE_JOYSTICK //Initialise Joystick seperately. This way we can warn when it fails instead @@ -1663,7 +1857,7 @@ int main(int argc, char* argv[]) { SDL_Quit();//Let's hope sdl will quit as well when it catches an exception return 0; -}; +} void GFX_GetSize(int &width, int &height, bool &fullscreen) { width = sdl.draw.width; From b01982bf3d9a06e770ae03280bb6d7c138cdca4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 22 May 2009 20:56:35 +0000 Subject: [PATCH 3312/4131] cleanup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3400 --- src/gui/sdlmain.cpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index b842c027..7a771c6c 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.151 2009-05-20 18:26:35 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.152 2009-05-22 20:56:35 c2woody Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1180,13 +1180,6 @@ static void GUI_StartUp(Section * sec) { for (Bitu y=0; y<400; y++) { Bit8u* tmpbuf = tmpbufp + y*640*3; -/* Bit8u * draw=((Bit8u *)splash_surf->pixels)+((399-y)*splash_surf->pitch); - for (Bitu x=0; x<640; x++) { - *draw++ = tmpbuf[x*3+2]; - *draw++ = tmpbuf[x*3+1]; - *draw++ = tmpbuf[x*3+0]; - *draw++ = 0xff; - } */ Bit32u * draw=(Bit32u*)(((Bit8u *)splash_surf->pixels)+((y)*splash_surf->pitch)); for (Bitu x=0; x<640; x++) { //#if SDL_BYTEORDER == SDL_BIG_ENDIAN @@ -1203,7 +1196,7 @@ static void GUI_StartUp(Section * sec) { static Bitu splash_fade = 100; static bool use_fadeout = true; - for(Bit32u ct = 0,startticks = GetTicks();ct < max_splash_loop;ct = GetTicks()-startticks) { + for (Bit32u ct = 0,startticks = GetTicks();ct < max_splash_loop;ct = GetTicks()-startticks) { SDL_Event evt; while (SDL_PollEvent(&evt)) { if (evt.type == SDL_QUIT) { @@ -1221,13 +1214,12 @@ static void GUI_StartUp(Section * sec) { } else if (ct>=max_splash_loop-splash_fade) { if (use_fadeout) { SDL_FillRect(sdl.surface, NULL, SDL_MapRGB(sdl.surface->format, 0, 0, 0)); - SDL_SetAlpha(splash_surf, SDL_SRCALPHA, (max_splash_loop-1-ct)*255/(splash_fade-1)); + SDL_SetAlpha(splash_surf, SDL_SRCALPHA, (Bit8u)((max_splash_loop-1-ct)*255/(splash_fade-1))); SDL_BlitSurface(splash_surf, NULL, sdl.surface, NULL); SDL_Flip(sdl.surface); } } -// SDL_Delay(1); } if (use_fadeout) { From d74770521b3b27492913acca600541458c527f68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 24 May 2009 19:49:44 +0000 Subject: [PATCH 3313/4131] some hint when starting to port from msvc-based sources Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3401 --- docs/PORTING | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/PORTING b/docs/PORTING index f95c62d1..4a47607e 100644 --- a/docs/PORTING +++ b/docs/PORTING @@ -1,6 +1,12 @@ Some notes about porting DOSBox to systems with certain restrictions, like handheld devices. +General: + - depending on where you start off with the port, assure that the + config.h entries are correct/exhausting, like GCC_ATTRIBUTE is + required (struct packing) but is undefined if you base the port + on msvc sources which have a special config.h + 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 From 540fd839d803b94d231301d870bf689b333746da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 25 May 2009 14:26:50 +0000 Subject: [PATCH 3314/4131] cleanup and small additions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3402 --- INSTALL | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/INSTALL b/INSTALL index 6be2b895..cc48f8e2 100644 --- a/INSTALL +++ b/INSTALL @@ -7,6 +7,8 @@ SDL (src/platform/sdl-win32.diff). If you want the patched sourcetree send us an email. (see README) Licensed under LGPL + Note that only version 1.2 and its subversions (1.2.8, 1.2.13 etc.) + are currently supported. Curses (optional) If you want to enable the debugger you need a curses library. @@ -53,7 +55,7 @@ If you are building from the cvs run ./autogen.sh first before doing the followi In step 1 you could add the following switches: --enable-debug enables the internal debugger. --enable-debug=heavy enables even more - debug options. Dosbox should then be run from a xterm and when the sdl- + 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 @@ -66,7 +68,7 @@ In step 1 you could add the following switches: --disable-fpu-x86 disables the assembly fpu core. Although relatively new the x86 fpu - core has more accuracy then the regular fpu core. + core has more accuracy then the regular fpu core. --disable-dynamic-x86 disables the dynamic x86 specific cpu core. Although it might be @@ -78,11 +80,15 @@ In step 1 you could add the following switches: --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. + 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-dynamic-x86 --disable-dynrec) + +--disable-opengl + disables OpenGL-support (output mode that can be selected in the + DOSBox configuration file). --disable-unaligned-memory disables unaligned memory access. @@ -94,4 +100,5 @@ src/ints/bios_keyboard.cpp and go to line 30 and read there how to fix it. Build instructions for VC++6 -Don't use VC++ 6:it creates faulty code in core_normal.cpp +Don't use VC++ 6: it creates faulty code in core_normal.cpp +Later Visual Studio versions work fine (vs2003/.net, vs2005, vs2008) From d46122e0f0ae2891c382689c3a2d28e442ff1c5b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 May 2009 15:58:31 +0000 Subject: [PATCH 3315/4131] Updates Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3403 --- README | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/README b/README index b9f269e1..2fbaf8fb 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -DOSBox v0.72 +DOSBox v0.73 ===== @@ -70,6 +70,7 @@ Q: Can DOSBox harm my computer? Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. Q: What sound hardware does DOSBox presently emulate? Q: DOSBox crashes on startup and I'm running arts. +Q: My Build game(Duke3D/Blood/Shadow Warrior) has problems. Q: Great README, but I still don't get it. @@ -249,8 +250,8 @@ A: DOSBox emulates several legacy sound devices: be sure the soundblaster is not disabled in the DOSBox configuration file. The Tandy DAC is only emulated at the BIOS level. - Adlib - Borrowed from MAME, this emulation is almost perfect and includes the - Adlib's ability to almost play digitized sound. + This emulation is almost perfect and includes the Adlib's ability to + almost play digitized sound. - SoundBlaster 16 / SoundBlaster Pro I & II / SoundBlaster I & II By default DOSBox provides Soundblaster 16 level 16-bit stereo sound. You can select a different SoundBlaster version in the configfile of @@ -271,6 +272,13 @@ A: This isn't really a DOSBox problem, but the solution is to set the environment variable SDL_AUDIODRIVER to alsa or oss. +Q: My Build game(Duke3D/Blood/Shadow Warrior) has problems. +A: First of all, try to find a port of the game. Those will offer a + better experience. To fix the graphics problem that occurs in + DOSBox on higher resolutions. Open the configuration file of + DOSBox and search for machine=svga_s3. Change svga_s3 to vesa_nolfb + + Q: Great README, but I still don't get it. A: A look at "The Newbie's pictorial guide to DOSBox" located at http://vogons.zetafleet.com/viewforum.php?f=39 might help you. @@ -301,6 +309,10 @@ dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] [-version] dosbox -version +dosbox -editconf program +dosbox -opencaptures program +dosbox -printconf +dosbox -eraseconf name If "name" is a directory it will mount that as the C: drive. @@ -364,6 +376,19 @@ dosbox -version -version output version information and exit. Useful for frontends. + -editconf program + calls program with as first parameter the configuration file. + + -opencaptures + calls program with as first paramter the location of the captures + folder. + + -printconf + prints the location of the default configuration file. + + -eraseconf + removes the default configuration file + Note: If a name/command/configfile/languagefile contains a space, put the whole name/command/configfile/languagefile between quotes ("command or file name"). If you need to use quotes within quotes @@ -1189,11 +1214,13 @@ The DOSBox configuration file contains the current settings. You can alter them and start DOSBox with the -conf switch to load the file and use these settings. -DOSBox will first parse the settings in ~/.dosboxrc (Linux), -~\dosbox.conf (Win32) or "~/Library/Preferences/DOSBox Preferences" -(MACOSX). Afterwards DOSBox will parse all configfiles specified with the --conf switch. If no configfile is specified with the -conf switch, DOSBox will -look in the current directory for the DOSBox configuration file. +DOSBox will parse configuration files that are specified with -conf. If +none were specified it will try to load "dosbox.conf" from the local +directory. If there is none, DOSBox will load the user configuration +file. This file will be created if it doesn't exist. The file can be +found in ~/.dosbox (Linux) or "~/Library/Preferences" (MAC OS X). +Windows users should use the shortcuts in the startmenu to find it. + From 7509c4dbc4f4056d168db84350f371d0091aa0fe Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 May 2009 16:07:17 +0000 Subject: [PATCH 3316/4131] Typo + new functionality description Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3404 --- README | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README b/README index 2fbaf8fb..1244e73b 100644 --- a/README +++ b/README @@ -378,9 +378,11 @@ dosbox -eraseconf -editconf program calls program with as first parameter the configuration file. + You can specify this command more than once. In this case it will + move to second program if the first one fails to start. -opencaptures - calls program with as first paramter the location of the captures + calls program with as first paramater the location of the captures folder. -printconf From f427a52f113ca0e4ea0ed96ad683e68106e9eefa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 May 2009 16:29:36 +0000 Subject: [PATCH 3317/4131] Add the functionality. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3405 --- src/gui/sdlmain.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 7a771c6c..4ce3d12a 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.152 2009-05-22 20:56:35 c2woody Exp $ */ +/* $Id: sdlmain.cpp,v 1.153 2009-05-25 16:29:36 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1446,7 +1446,6 @@ static BOOL WINAPI ConsoleEventHandler(DWORD event) { /* static variable to show wether there is not a valid stdout. * Fixes some bugs when -noconsole is used in a read only directory */ static bool no_stdout = false; - void GFX_ShowMsg(char const* format,...) { char buf[512]; va_list msg; @@ -1562,7 +1561,7 @@ static void show_warning(char const * const message) { SDL_Delay(10000); } -static void launcheditor(std::string const& edit) { +static void launcheditor() { std::string path,file; Cross::CreatePlatformConfigDir(path); Cross::GetPlatformConfigName(file); @@ -1577,10 +1576,11 @@ static void launcheditor(std::string const& edit) { printf("no editor specified.\n"); exit(1); }*/ - - execlp(edit.c_str(),edit.c_str(),path.c_str(),(char*) 0); + std::string edit; + while(control->cmdline->FindString("-editconf",edit,true)) //Loop until one succeeds + execlp(edit.c_str(),edit.c_str(),path.c_str(),(char*) 0); //if you get here the launching failed! - printf("can't find editor %s\n",edit.c_str()); + printf("can't find editor(s) specified at the command line.\n"); exit(1); } static void launchcaptures(std::string const& edit) { @@ -1615,6 +1615,7 @@ static void printconfiglocation() { Cross::CreatePlatformConfigDir(path); Cross::GetPlatformConfigName(file); path += file; + FILE* f = fopen(path.c_str(),"r"); if(!f && !control->PrintConfig(path.c_str())) { printf("tried creating %s. but failed",path.c_str()); @@ -1655,7 +1656,7 @@ int main(int argc, char* argv[]) { DOSBOX_Init(); std::string editor; - if(control->cmdline->FindString("-editconf",editor,true)) launcheditor(editor); + if(control->cmdline->FindString("-editconf",editor,false)) launcheditor(); if(control->cmdline->FindString("-opencaptures",editor,true)) launchcaptures(editor); if(control->cmdline->FindExist("-eraseconf")) eraseconfigfile(); From 14fc0aaad5d06ec558e39142ac8c076d1dd7f945 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 May 2009 16:39:47 +0000 Subject: [PATCH 3318/4131] Use the functionality. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3406 --- scripts/dosbox-installer.nsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index 8c4b9ff8..149ed253 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -68,7 +68,7 @@ SetShellVarContext all CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.lnk" "$INSTDIR\DOSBox.exe" "" "$INSTDIR\DOSBox.exe" 0 CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox (noconsole).lnk" "$INSTDIR\DOSBox.exe" "-noconsole" "$INSTDIR\DOSBox.exe" 0 CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\README.lnk" "$INSTDIR\README.txt" - CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration\Edit Configuration.lnk" "$INSTDIR\DOSBox.exe" "-editconf notepad.exe" + CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration\Edit Configuration.lnk" "$INSTDIR\DOSBox.exe" "-editconf notepad.exe -editconf $\"%SystemRoot%\system32\notepad.exe$\" -editconf $\"%WINDIR%\notepad.exe$\"" CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration\Reset Configuration.lnk" "$INSTDIR\DOSBox.exe" "-eraseconf" CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Capture folder.lnk" "$INSTDIR\DOSBox.exe" "-opencaptures explorer.exe" CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Video instructions.lnk" "$INSTDIR\zmbv\README.txt" From dee1769b1dc4ebc9935b8d24c4b70576bbc7f8e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 25 May 2009 17:52:57 +0000 Subject: [PATCH 3319/4131] consistency update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3407 --- README | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README b/README index 1244e73b..4310aed5 100644 --- a/README +++ b/README @@ -651,8 +651,8 @@ MIXER /LISTMIDI Lists the available midi devices on your PC (Windows). To select a device other than the Windows default midi-mapper, add a line - 'config=id' to the [midi] section in the configuration file, where - 'id' is the number for the device as listed by LISTMIDI. + 'midiconfig=id' to the [midi] section in the configuration file, + where 'id' is the number for the device as listed by LISTMIDI. IMGMOUNT @@ -1182,7 +1182,12 @@ Running a certain game closes DOSBox, crashes with some message or hangs: fixed cycles (for example cycles=10000) ems=false xms=false - or combinations of the above settings + or combinations of the above settings, + similar the machine settings that control the emulated chipset and + functionality: + machine=vesa_nolfb + or + machine=vgaonly - use loadfix before starting the game The game exits to the DOSBox prompt with some error message: From 305e4d9055cf736dd15718c80eabdc943ba9ddba Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 26 May 2009 17:19:15 +0000 Subject: [PATCH 3320/4131] Add some failsafes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3408 --- src/misc/cross.cpp | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/misc/cross.cpp b/src/misc/cross.cpp index 74ad66bc..ba5bd8e7 100644 --- a/src/misc/cross.cpp +++ b/src/misc/cross.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.cpp,v 1.5 2009-03-14 18:02:34 qbix79 Exp $ */ +/* $Id: cross.cpp,v 1.6 2009-05-26 17:19:15 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -36,12 +36,28 @@ #include #endif +#ifdef WIN32 +static void W32_ConfDir(std::string& in,bool create) { + int c = create?1:0; + char result[MAX_PATH] = { 0 }; + BOOL r = SHGetSpecialFolderPath(NULL,result,CSIDL_LOCAL_APPDATA,c); + if(!r || result[0] == 0) r = SHGetSpecialFolderPath(NULL,result,CSIDL_APPDATA,c); + if(!r || result[0] == 0) { + char* windir = getenv("windir"); + if(!windir) windir = "c:\\windows"; + safe_strncpy(result,windir,MAX_PATH); + char* appdata = "\\Application Data"; + size_t len = strlen(result); + if(len + strlen(appdata) < MAX_PATH) strcat(result,appdata); + if(create) mkdir(result); + } + in = result; +} +#endif void Cross::GetPlatformConfigDir(std::string& in) { #ifdef WIN32 - char result[MAX_PATH] = { 0 }; - SHGetSpecialFolderPath(NULL,result,CSIDL_LOCAL_APPDATA,0); - in = result; + W32_ConfDir(in,false); in += "\\DOSBox"; #elif defined(MACOSX) in = "~/Library/Preferences"; @@ -66,9 +82,7 @@ void Cross::GetPlatformConfigName(std::string& in) { void Cross::CreatePlatformConfigDir(std::string& in) { #ifdef WIN32 - char result[MAX_PATH] = { 0 }; - SHGetSpecialFolderPath(NULL,result,CSIDL_LOCAL_APPDATA,1); //1 at end is create - in = result; + W32_ConfDir(in,true); in += "\\DOSBox"; mkdir(in.c_str()); #elif defined(MACOSX) @@ -120,8 +134,8 @@ dir_information* open_directory(const char* dirname) { safe_strncpy(dir.base_path,dirname,MAX_PATH); - if (dirname[len-1]=='\\') strcat(dir.base_path,"*.*"); - else strcat(dir.base_path,"\\*.*"); + if (dirname[len-1] == '\\') strcat(dir.base_path,"*.*"); + else strcat(dir.base_path,"\\*.*"); dir.handle = INVALID_HANDLE_VALUE; From fb874404f722100c383672fe1a0702954d7d8b6a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 26 May 2009 17:43:39 +0000 Subject: [PATCH 3321/4131] Fix warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3409 --- src/misc/cross.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/misc/cross.cpp b/src/misc/cross.cpp index ba5bd8e7..82b78d19 100644 --- a/src/misc/cross.cpp +++ b/src/misc/cross.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.cpp,v 1.6 2009-05-26 17:19:15 qbix79 Exp $ */ +/* $Id: cross.cpp,v 1.7 2009-05-26 17:43:39 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -43,10 +43,10 @@ static void W32_ConfDir(std::string& in,bool create) { BOOL r = SHGetSpecialFolderPath(NULL,result,CSIDL_LOCAL_APPDATA,c); if(!r || result[0] == 0) r = SHGetSpecialFolderPath(NULL,result,CSIDL_APPDATA,c); if(!r || result[0] == 0) { - char* windir = getenv("windir"); + char const * windir = getenv("windir"); if(!windir) windir = "c:\\windows"; safe_strncpy(result,windir,MAX_PATH); - char* appdata = "\\Application Data"; + char const* appdata = "\\Application Data"; size_t len = strlen(result); if(len + strlen(appdata) < MAX_PATH) strcat(result,appdata); if(create) mkdir(result); From 16d14b78e19d06e0e0c15c6bc6a4c18bcc01b78f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 27 May 2009 09:15:42 +0000 Subject: [PATCH 3322/4131] Some year and version numbers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3410 --- NEWS | 64 +++++++++++++++++++ THANKS | 1 + VERSION | 2 +- acinclude.m4 | 2 +- configure.in | 2 +- include/bios.h | 2 +- include/bios_disk.h | 2 +- include/callback.h | 4 +- include/control.h | 4 +- include/cpu.h | 4 +- include/debug.h | 2 +- include/dma.h | 4 +- include/dos_inc.h | 4 +- include/dosbox.h | 4 +- include/fpu.h | 2 +- include/hardware.h | 2 +- include/inout.h | 4 +- include/ipx.h | 4 +- include/ipxserver.h | 2 +- include/joystick.h | 4 +- include/keyboard.h | 2 +- include/mapper.h | 2 +- include/mem.h | 2 +- include/mouse.h | 4 +- include/paging.h | 4 +- include/pic.h | 2 +- include/programs.h | 4 +- include/regs.h | 2 +- include/render.h | 2 +- include/serialport.h | 4 +- include/setup.h | 4 +- include/shell.h | 4 +- include/support.h | 4 +- include/timer.h | 2 +- include/video.h | 4 +- src/cpu/core_dyn_x86.cpp | 4 +- src/cpu/core_dyn_x86/dyn_fpu.h | 4 +- src/cpu/core_dyn_x86/dyn_fpu_dh.h | 4 +- src/cpu/core_dyn_x86/risc_x86.h | 4 +- src/cpu/core_dyn_x86/string.h | 2 +- src/cpu/core_dynrec.cpp | 4 +- src/cpu/core_dynrec/cache.h | 2 +- src/cpu/core_dynrec/decoder.h | 4 +- src/cpu/core_dynrec/decoder_basic.h | 4 +- src/cpu/core_dynrec/decoder_opcodes.h | 2 +- src/cpu/core_dynrec/dyn_fpu.h | 2 +- src/cpu/core_dynrec/operators.h | 2 +- src/cpu/core_dynrec/risc_armv4le.h | 4 +- src/cpu/core_dynrec/risc_mipsel32.h | 4 +- src/cpu/core_dynrec/risc_x64.h | 4 +- src/cpu/core_dynrec/risc_x86.h | 4 +- src/cpu/core_full.cpp | 2 +- src/cpu/core_normal.cpp | 2 +- src/cpu/core_normal/helpers.h | 2 +- src/cpu/core_normal/prefix_0f.h | 2 +- src/cpu/core_normal/prefix_66.h | 2 +- src/cpu/core_normal/prefix_66_0f.h | 2 +- src/cpu/core_normal/prefix_none.h | 2 +- src/cpu/core_normal/support.h | 2 +- src/cpu/core_normal/table_ea.h | 2 +- src/cpu/core_prefetch.cpp | 4 +- src/cpu/core_simple.cpp | 2 +- src/cpu/flags.cpp | 2 +- src/cpu/instructions.h | 2 +- src/cpu/lazyflags.h | 2 +- src/cpu/modrm.cpp | 2 +- src/cpu/modrm.h | 2 +- src/cpu/paging.cpp | 4 +- src/debug/debug_gui.cpp | 4 +- src/debug/debug_inc.h | 4 +- src/debug/disasm_tables.h | 2 +- src/dos/cdrom_aspi_win32.cpp | 4 +- src/dos/cdrom_ioctl_linux.cpp | 2 +- src/dos/cdrom_ioctl_os2.cpp | 4 +- src/dos/dev_con.h | 4 +- src/dos/dos_classes.cpp | 4 +- src/dos/dos_devices.cpp | 4 +- src/dos/dos_execute.cpp | 4 +- src/dos/dos_memory.cpp | 2 +- src/dos/dos_misc.cpp | 4 +- src/dos/dos_tables.cpp | 4 +- src/dos/drive_fat.cpp | 4 +- src/dos/drive_iso.cpp | 4 +- src/dos/drive_virtual.cpp | 2 +- src/dos/drives.cpp | 4 +- src/dos/drives.h | 4 +- src/fpu/fpu.cpp | 4 +- src/fpu/fpu_instructions.h | 4 +- src/fpu/fpu_instructions_x86.h | 4 +- src/gui/Makefile.am | 2 +- src/gui/dosbox_logo.h | 4 +- src/gui/midi.cpp | 2 +- src/gui/midi_coreaudio.h | 2 +- src/gui/midi_oss.h | 2 +- src/gui/midi_win32.h | 4 +- src/gui/render_loops.h | 2 +- src/gui/render_scalers.cpp | 2 +- src/gui/render_scalers.h | 2 +- src/gui/render_simple.h | 4 +- src/gui/render_templates.h | 2 +- src/gui/render_templates_hq.h | 2 +- src/gui/render_templates_hq2x.h | 2 +- src/gui/render_templates_hq3x.h | 2 +- src/gui/render_templates_sai.h | 2 +- src/hardware/cmos.cpp | 4 +- src/hardware/dma.cpp | 4 +- src/hardware/gameblaster.cpp | 2 +- src/hardware/iohandler.cpp | 4 +- src/hardware/ipx.cpp | 4 +- src/hardware/ipxserver.cpp | 4 +- src/hardware/joystick.cpp | 4 +- src/hardware/keyboard.cpp | 4 +- src/hardware/memory.cpp | 4 +- src/hardware/mpu401.cpp | 4 +- src/hardware/pcspeaker.cpp | 4 +- src/hardware/pic.cpp | 4 +- src/hardware/serialport/directserial_os2.cpp | 4 +- src/hardware/serialport/directserial_os2.h | 4 +- .../serialport/directserial_posix.cpp | 4 +- src/hardware/serialport/directserial_posix.h | 4 +- .../serialport/directserial_win32.cpp | 4 +- src/hardware/serialport/directserial_win32.h | 4 +- src/hardware/serialport/nullmodem.cpp | 4 +- src/hardware/serialport/nullmodem.h | 4 +- src/hardware/serialport/serialdummy.cpp | 4 +- src/hardware/serialport/serialdummy.h | 4 +- src/hardware/serialport/serialport.cpp | 4 +- src/hardware/serialport/softmodem.cpp | 4 +- src/hardware/serialport/softmodem.h | 4 +- src/hardware/tandy_sound.cpp | 2 +- src/hardware/vga.cpp | 4 +- src/hardware/vga_attr.cpp | 4 +- src/hardware/vga_dac.cpp | 2 +- src/hardware/vga_gfx.cpp | 4 +- src/hardware/vga_paradise.cpp | 4 +- src/hardware/vga_seq.cpp | 4 +- src/hardware/vga_tseng.cpp | 4 +- src/hardware/vga_xga.cpp | 4 +- src/ints/bios.cpp | 4 +- src/ints/bios_disk.cpp | 4 +- src/ints/bios_keyboard.cpp | 2 +- src/ints/int10.h | 4 +- src/ints/int10_char.cpp | 4 +- src/ints/int10_memory.cpp | 4 +- src/ints/int10_misc.cpp | 4 +- src/ints/int10_pal.cpp | 2 +- src/ints/int10_put_pixel.cpp | 4 +- src/ints/int10_vesa.cpp | 4 +- src/ints/int10_video_state.cpp | 4 +- src/ints/int10_vptable.cpp | 4 +- src/ints/xms.cpp | 4 +- src/ints/xms.h | 2 +- src/libs/zmbv/drvproc.cpp | 2 +- src/libs/zmbv/zmbv.cpp | 2 +- src/libs/zmbv/zmbv.h | 2 +- src/libs/zmbv/zmbv_vfw.cpp | 2 +- src/misc/messages.cpp | 4 +- src/misc/programs.cpp | 4 +- src/misc/setup.cpp | 4 +- src/misc/support.cpp | 4 +- src/platform/visualc/config.h | 2 +- src/shell/shell_batch.cpp | 4 +- src/shell/shell_misc.cpp | 4 +- src/winres.rc | 8 +-- 164 files changed, 328 insertions(+), 263 deletions(-) diff --git a/NEWS b/NEWS index d629edcd..d303e45d 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,67 @@ +0.73 + - Add two new opl2+opl3 emulators. (better speed, different implementation + approach) + - Improved DRO recording/better file structure. + - Add EGA emulation. + - Add special vga machine mode. Supports more of the exotic tricks like + changing the palette during screen updates, 9x16 fonts etc. + - Added special machine modes for the following svga cards: + - S3 + - Paradise + - Tseng + - Fix problems with the vga split line feature. + - Improve vesa emulation. + - Add optional selection of old vesa mode for games that don't work + with certain vesa features. + - Improve video BIOS emulation to behave more like a real bios. + - Fixes for emulated 4bpp graphics modes. + - Fixes to paging system. + - Various fixes and improvements for the recompiling core. + - Add arm backend for the recompiling core. + - Add some mscdex quirks when dealing with files that are exactly 8.3 long. + - Small fixes to batch file handling. + - Small fixes to the XMS memory handling. + - Various fixes for aligned memory on hosts that want it. + - Various improvements to the mouse. + - Fixes and small speed ups to the debugger. + - Fix and improve lot's of compilation problems. (curses detection, + GCC 3.4 and GCC 4.X fixes) + - Added some basic auto keyboard layout handling. (windows only currently) + - Add basic support for evdev keyboard driver. + - Various fixes to the timer. (improve mode 2 timer changes, + implement mode 1, improve gate2 handling) + - Add audio extraction and mci audio support. Should enable CDROM audio + for Vista and adds volume control. + - Improve the directory cache speed a lot, especially with mounting slow + media like network paths. + - Various fixes to the create temporary file call. + - Don't keep batchfiles open during execution. Allows rewriting of the + active batchfile. (menu programs use this trick sometimes) + - Fix problems with filenames with 2 extensions. + - Add some more lowlevel dos tables. + - Fixes to hercules emulation. + - Fix flag handling for special case of ROR. + - Make the batchfile handling in regard to IF more flexible. + - Fixes to scrolling/panning feature. + - Add prefetch queue emulation. + - Make the emulated cpu type selectable. This is mainly the + identification commands and the way paging works. + - Some special EMS functionality added. (OS handles, zero-page handling) + - Improve support for EMS when booting a different OS. + - Improve cdrom speed detection by games. + - Improve stability of cycle guessing code, when there is background + activity. + - Fix various mscdex and cdrom detection schemes. + - Added Coremidi support on Mac OS X. + - Improve support for DOS devices when used to detect the existance + of directories in various ways. + - Add IRQ 2 emulation on VRET. (ega only) + - Added video parameter table and video state functionality. + - Increase default freespace to 250 MB. + - Some fixes to the fat filesystem handling for disk images. + - Some soundblaster fixes and command additions. + - Fix mixer 16bit direct transfers on bigendian hosts. + 0.72 - Fixed unitialized variable in joystick. (Fixes crashes on Vista and Mac OS X) diff --git a/THANKS b/THANKS index 42ed2d72..811f6c87 100644 --- a/THANKS +++ b/THANKS @@ -22,6 +22,7 @@ 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. +GOG Team for the splash screen. All the people who submitted a bug. The Beta Testers. diff --git a/VERSION b/VERSION index b214dd99..6ab5ccfd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.72 +0.73 diff --git a/acinclude.m4 b/acinclude.m4 index 2abdc3f8..a118bf1f 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -305,7 +305,7 @@ AC_SUBST(ALSA_LIBS) AH_TOP([ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/configure.in b/configure.in index e02f5832..a24f9bf2 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Init. -AC_INIT(dosbox,0.72) +AC_INIT(dosbox,0.73) AC_PREREQ(2.50) AC_CONFIG_SRCDIR(README) diff --git a/include/bios.h b/include/bios.h index 0245cdaf..e3377040 100644 --- a/include/bios.h +++ b/include/bios.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/include/bios_disk.h b/include/bios_disk.h index 7f5d97cc..3a77ea5c 100644 --- a/include/bios_disk.h +++ b/include/bios_disk.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 diff --git a/include/callback.h b/include/callback.h index 1c438ec7..a14fd8ce 100644 --- a/include/callback.h +++ b/include/callback.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: callback.h,v 1.24 2009-05-27 09:15:40 qbix79 Exp $ */ #ifndef DOSBOX_CALLBACK_H #define DOSBOX_CALLBACK_H diff --git a/include/control.h b/include/control.h index 5076fbb8..427fc6d9 100644 --- a/include/control.h +++ b/include/control.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: control.h,v 1.2 2009-05-27 09:15:40 qbix79 Exp $ */ #ifndef DOSBOX_CONTROL_H #define DOSBOX_CONTROL_H diff --git a/include/cpu.h b/include/cpu.h index 643fc182..a10291b1 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: cpu.h,v 1.57 2009-05-27 09:15:40 qbix79 Exp $ */ #ifndef DOSBOX_CPU_H #define DOSBOX_CPU_H diff --git a/include/debug.h b/include/debug.h index 318b418d..89378c74 100644 --- a/include/debug.h +++ b/include/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/include/dma.h b/include/dma.h index 84cca2b0..f62446f4 100644 --- a/include/dma.h +++ b/include/dma.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: dma.h,v 1.19 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_DMA_H #define DOSBOX_DMA_H diff --git a/include/dos_inc.h b/include/dos_inc.h index e1d037a4..bb624021 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: dos_inc.h,v 1.78 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H diff --git a/include/dosbox.h b/include/dosbox.h index 4f80bc87..743de581 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: dosbox.h,v 1.32 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_DOSBOX_H #define DOSBOX_DOSBOX_H diff --git a/include/fpu.h b/include/fpu.h index 92dd3aab..b5e3b2d7 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/include/hardware.h b/include/hardware.h index 680ae50a..df2c73ce 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/include/inout.h b/include/inout.h index 9e3c0329..4943435f 100644 --- a/include/inout.h +++ b/include/inout.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: inout.h,v 1.13 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_INOUT_H #define DOSBOX_INOUT_H diff --git a/include/ipx.h b/include/ipx.h index 884b4946..f8e434dd 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: ipx.h,v 1.13 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_IPX_H #define DOSBOX_IPX_H diff --git a/include/ipxserver.h b/include/ipxserver.h index 9cb6db97..6ed39b75 100644 --- a/include/ipxserver.h +++ b/include/ipxserver.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/include/joystick.h b/include/joystick.h index 7cd44494..5d4575b7 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: joystick.h,v 1.13 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_JOYSTICK_H #define DOSBOX_JOYSTICK_H void JOYSTICK_Enable(Bitu which,bool enabled); diff --git a/include/keyboard.h b/include/keyboard.h index d56affdf..bb62cab0 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/include/mapper.h b/include/mapper.h index aea28945..17b02211 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/include/mem.h b/include/mem.h index c42f6ac1..8b24762a 100644 --- a/include/mem.h +++ b/include/mem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/include/mouse.h b/include/mouse.h index ccc38a05..218a4442 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: mouse.h,v 1.15 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_MOUSE_H diff --git a/include/paging.h b/include/paging.h index 1b09a109..f7468545 100644 --- a/include/paging.h +++ b/include/paging.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: paging.h,v 1.33 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H diff --git a/include/pic.h b/include/pic.h index 9d68e6b0..e104ec4e 100644 --- a/include/pic.h +++ b/include/pic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/include/programs.h b/include/programs.h index b86987a0..e92fdb33 100644 --- a/include/programs.h +++ b/include/programs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: programs.h,v 1.19 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_PROGRAMS_H #define DOSBOX_PROGRAMS_H diff --git a/include/regs.h b/include/regs.h index 59d7a761..2f37b1c1 100644 --- a/include/regs.h +++ b/include/regs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/include/render.h b/include/render.h index 6e85971b..ee3db590 100644 --- a/include/render.h +++ b/include/render.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/include/serialport.h b/include/serialport.h index f1016031..ca0d72b3 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: serialport.h,v 1.17 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_SERIALPORT_H #define DOSBOX_SERIALPORT_H diff --git a/include/setup.h b/include/setup.h index ab392b84..b9b68666 100644 --- a/include/setup.h +++ b/include/setup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: setup.h,v 1.41 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H diff --git a/include/shell.h b/include/shell.h index e5dc80a1..02edab16 100644 --- a/include/shell.h +++ b/include/shell.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: shell.h,v 1.27 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_SHELL_H #define DOSBOX_SHELL_H diff --git a/include/support.h b/include/support.h index 3c10a386..9b7e7022 100644 --- a/include/support.h +++ b/include/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: support.h,v 1.18 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_SUPPORT_H #define DOSBOX_SUPPORT_H diff --git a/include/timer.h b/include/timer.h index 5ba2696d..495381f5 100644 --- a/include/timer.h +++ b/include/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/include/video.h b/include/video.h index de4bbace..4b57e0e5 100644 --- a/include/video.h +++ b/include/video.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: video.h,v 1.26 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_VIDEO_H #define DOSBOX_VIDEO_H diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 5e3a6d42..dbbb72b2 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: core_dyn_x86.cpp,v 1.35 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/cpu/core_dyn_x86/dyn_fpu.h b/src/cpu/core_dyn_x86/dyn_fpu.h index 06e3efe0..1373fecf 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu.h +++ b/src/cpu/core_dyn_x86/dyn_fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: dyn_fpu.h,v 1.4 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU diff --git a/src/cpu/core_dyn_x86/dyn_fpu_dh.h b/src/cpu/core_dyn_x86/dyn_fpu_dh.h index 5a6ca5f7..d4d606f0 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu_dh.h +++ b/src/cpu/core_dyn_x86/dyn_fpu_dh.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: dyn_fpu_dh.h,v 1.6 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 76bf4395..6837d0e3 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_x86.h,v 1.31 2008-08-06 18:31:26 c2woody Exp $ */ +/* $Id: risc_x86.h,v 1.32 2009-05-27 09:15:41 qbix79 Exp $ */ static void gen_init(void); diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index 256a8af2..3b90fa16 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index 14730d6e..2819c1f9 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: core_dynrec.cpp,v 1.12 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index 78d671c5..9a38f775 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h index 1e32843a..dbd9cf50 100644 --- a/src/cpu/core_dynrec/decoder.h +++ b/src/cpu/core_dynrec/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: decoder.h,v 1.6 2009-05-27 09:15:41 qbix79 Exp $ */ #include "decoder_basic.h" diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index 4f821246..99d57272 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: decoder_basic.h,v 1.14 2009-03-29 17:32:20 qbix79 Exp $ */ +/* $Id: decoder_basic.h,v 1.15 2009-05-27 09:15:41 qbix79 Exp $ */ /* diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index 030cf30e..22a5a556 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 diff --git a/src/cpu/core_dynrec/dyn_fpu.h b/src/cpu/core_dynrec/dyn_fpu.h index a68c81a5..6d3e7091 100644 --- a/src/cpu/core_dynrec/dyn_fpu.h +++ b/src/cpu/core_dynrec/dyn_fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 diff --git a/src/cpu/core_dynrec/operators.h b/src/cpu/core_dynrec/operators.h index be667dcd..c4c89f17 100644 --- a/src/cpu/core_dynrec/operators.h +++ b/src/cpu/core_dynrec/operators.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/cpu/core_dynrec/risc_armv4le.h b/src/cpu/core_dynrec/risc_armv4le.h index e5437d34..a36af244 100644 --- a/src/cpu/core_dynrec/risc_armv4le.h +++ b/src/cpu/core_dynrec/risc_armv4le.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: risc_armv4le.h,v 1.3 2009-05-27 09:15:41 qbix79 Exp $ */ /* ARMv4 (little endian) backend (switcher) by M-HT */ diff --git a/src/cpu/core_dynrec/risc_mipsel32.h b/src/cpu/core_dynrec/risc_mipsel32.h index bcd92653..b3da84e5 100644 --- a/src/cpu/core_dynrec/risc_mipsel32.h +++ b/src/cpu/core_dynrec/risc_mipsel32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_mipsel32.h,v 1.4 2008-09-19 16:48:03 c2woody Exp $ */ +/* $Id: risc_mipsel32.h,v 1.5 2009-05-27 09:15:41 qbix79 Exp $ */ /* MIPS32 (little endian) backend by crazyc */ diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index 1b34ada5..55000960 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_x64.h,v 1.11 2008-09-02 20:44:41 c2woody Exp $ */ +/* $Id: risc_x64.h,v 1.12 2009-05-27 09:15:41 qbix79 Exp $ */ // some configuring defines that specify the capabilities of this architecture diff --git a/src/cpu/core_dynrec/risc_x86.h b/src/cpu/core_dynrec/risc_x86.h index c1247874..3f2f9dba 100644 --- a/src/cpu/core_dynrec/risc_x86.h +++ b/src/cpu/core_dynrec/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_x86.h,v 1.8 2008-09-02 20:44:41 c2woody Exp $ */ +/* $Id: risc_x86.h,v 1.9 2009-05-27 09:15:41 qbix79 Exp $ */ // some configuring defines that specify the capabilities of this architecture diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 72f8f489..b8273573 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index dfab4979..4fd1a785 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/cpu/core_normal/helpers.h b/src/cpu/core_normal/helpers.h index f0956f65..06fc3fbf 100644 --- a/src/cpu/core_normal/helpers.h +++ b/src/cpu/core_normal/helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 388c15c2..fcdcdb40 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 473248e1..3d34b705 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index fefbbee7..f2180309 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index deeeba3c..6232be23 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index 65dbfa3e..2a849451 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/cpu/core_normal/table_ea.h b/src/cpu/core_normal/table_ea.h index 9b5d1108..3f9329b9 100644 --- a/src/cpu/core_normal/table_ea.h +++ b/src/cpu/core_normal/table_ea.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/cpu/core_prefetch.cpp b/src/cpu/core_prefetch.cpp index ebbd3f02..6a08e6fe 100644 --- a/src/cpu/core_prefetch.cpp +++ b/src/cpu/core_prefetch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: core_prefetch.cpp,v 1.1 2008-05-21 21:29:32 c2woody Exp $ */ +/* $Id: core_prefetch.cpp,v 1.2 2009-05-27 09:15:41 qbix79 Exp $ */ #include diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp index cfe68d57..1930c3b8 100644 --- a/src/cpu/core_simple.cpp +++ b/src/cpu/core_simple.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index d475dfeb..889f6a4e 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 1a69ffb4..e224d42a 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index 2f088ec0..96974ec0 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/cpu/modrm.cpp b/src/cpu/modrm.cpp index 830daf0c..cd62c629 100644 --- a/src/cpu/modrm.cpp +++ b/src/cpu/modrm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/cpu/modrm.h b/src/cpu/modrm.h index 7fb3059b..d06aec67 100644 --- a/src/cpu/modrm.h +++ b/src/cpu/modrm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 55806aa3..589c489f 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.cpp,v 1.35 2008-12-04 21:09:32 c2woody Exp $ */ +/* $Id: paging.cpp,v 1.36 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 03921116..53d19361 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug_gui.cpp,v 1.37 2009-02-01 19:28:58 qbix79 Exp $ */ +/* $Id: debug_gui.cpp,v 1.38 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h index 870751c8..f17fa314 100644 --- a/src/debug/debug_inc.h +++ b/src/debug/debug_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -18,7 +18,7 @@ /* Local Debug Function */ -/* $Id: debug_inc.h,v 1.11 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: debug_inc.h,v 1.12 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include "mem.h" diff --git a/src/debug/disasm_tables.h b/src/debug/disasm_tables.h index 3ce7fb08..e86e1f86 100644 --- a/src/debug/disasm_tables.h +++ b/src/debug/disasm_tables.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index 47bac693..d333ef79 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_aspi_win32.cpp,v 1.20 2008-09-07 10:55:14 c2woody Exp $ */ +/* $Id: cdrom_aspi_win32.cpp,v 1.21 2009-05-27 09:15:41 qbix79 Exp $ */ #if defined (WIN32) diff --git a/src/dos/cdrom_ioctl_linux.cpp b/src/dos/cdrom_ioctl_linux.cpp index 9c202bd5..a4a968b7 100644 --- a/src/dos/cdrom_ioctl_linux.cpp +++ b/src/dos/cdrom_ioctl_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/dos/cdrom_ioctl_os2.cpp b/src/dos/cdrom_ioctl_os2.cpp index 4c0e27eb..30c62721 100644 --- a/src/dos/cdrom_ioctl_os2.cpp +++ b/src/dos/cdrom_ioctl_os2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_ioctl_os2.cpp,v 1.3 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: cdrom_ioctl_os2.cpp,v 1.4 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 89cd8795..4a3527ea 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.34 2008-10-05 14:44:52 qbix79 Exp $ */ +/* $Id: dev_con.h,v 1.35 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 70b6c14b..3add7df1 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.56 2009-04-16 12:16:52 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.57 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 9466a664..47811f65 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_devices.cpp,v 1.21 2008-12-11 20:45:43 qbix79 Exp $ */ +/* $Id: dos_devices.cpp,v 1.22 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index a6058a83..80436386 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.66 2009-01-14 22:16:00 qbix79 Exp $ */ +/* $Id: dos_execute.cpp,v 1.67 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 1e55725b..30de8354 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index 3ef6a1ae..b65be5a7 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_misc.cpp,v 1.22 2009-04-28 18:47:04 c2woody Exp $ */ +/* $Id: dos_misc.cpp,v 1.23 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 1f852661..c4d659f1 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.30 2008-08-06 18:32:34 c2woody Exp $ */ +/* $Id: dos_tables.cpp,v 1.31 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 0b68d083..f1d01cd9 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.26 2008-08-06 18:32:34 c2woody Exp $ */ +/* $Id: drive_fat.cpp,v 1.27 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index d7ae555a..f3f9c150 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.24 2008-09-07 10:55:14 c2woody Exp $ */ +/* $Id: drive_iso.cpp,v 1.25 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 17ee00a9..c2089a8c 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index c33ad5a7..018dd52e 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.cpp,v 1.14 2008-09-07 10:55:14 c2woody Exp $ */ +/* $Id: drives.cpp,v 1.15 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" #include "dos_system.h" diff --git a/src/dos/drives.h b/src/dos/drives.h index a657a0c4..86ce3deb 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.40 2009-02-01 14:24:36 qbix79 Exp $ */ +/* $Id: drives.h,v 1.41 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 7e39e1f3..64dfae3c 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu.cpp,v 1.29 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: fpu.cpp,v 1.30 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index cc51a568..ec2f810d 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.32 2009-04-25 06:59:54 qbix79 Exp $ */ +/* $Id: fpu_instructions.h,v 1.33 2009-05-27 09:15:41 qbix79 Exp $ */ static void FPU_FINIT(void) { diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index a5fdca04..8d5ad728 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions_x86.h,v 1.6 2008-01-06 16:45:42 c2woody Exp $ */ +/* $Id: fpu_instructions_x86.h,v 1.7 2009-05-27 09:15:41 qbix79 Exp $ */ // #define WEAK_EXCEPTIONS diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 2e608415..3fed5e68 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -7,5 +7,5 @@ libgui_a_SOURCES = sdlmain.cpp sdl_mapper.cpp dosbox_logo.h \ render_templates_sai.h render_templates_hq.h \ render_templates_hq2x.h render_templates_hq3x.h \ midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h midi_alsa.h \ - midi_coremidi.h sdl_gui.cpp + midi_coremidi.h sdl_gui.cpp dosbox_splash.h diff --git a/src/gui/dosbox_logo.h b/src/gui/dosbox_logo.h index 93f5b9d3..25f2c15e 100644 --- a/src/gui/dosbox_logo.h +++ b/src/gui/dosbox_logo.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox_logo.h,v 1.4 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: dosbox_logo.h,v 1.5 2009-05-27 09:15:41 qbix79 Exp $ */ /* DOSBox icon designed by Ido Beeri */ diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 46493970..1ddbd373 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index cb23ea52..a54b0a8b 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index b4ae3069..0010d8a3 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index ec788d6d..7efb7564 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_win32.h,v 1.15 2008-08-06 18:32:34 c2woody Exp $ */ +/* $Id: midi_win32.h,v 1.16 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN diff --git a/src/gui/render_loops.h b/src/gui/render_loops.h index a87c7fb8..49867790 100644 --- a/src/gui/render_loops.h +++ b/src/gui/render_loops.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index c20d2661..787e094a 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index ad5b5be5..8e6815d2 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/gui/render_simple.h b/src/gui/render_simple.h index 94bddd17..b873acc7 100644 --- a/src/gui/render_simple.h +++ b/src/gui/render_simple.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render_simple.h,v 1.6 2008-09-07 10:55:15 c2woody Exp $ */ +/* $Id: render_simple.h,v 1.7 2009-05-27 09:15:41 qbix79 Exp $ */ #if defined (SCALERLINEAR) static void conc4d(SCALERNAME,SBPP,DBPP,L)(const void *s) { diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index ba14a5f5..b2461ac7 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/gui/render_templates_hq.h b/src/gui/render_templates_hq.h index fd9e14bb..661604e3 100644 --- a/src/gui/render_templates_hq.h +++ b/src/gui/render_templates_hq.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/gui/render_templates_hq2x.h b/src/gui/render_templates_hq2x.h index 4937af56..764d2784 100644 --- a/src/gui/render_templates_hq2x.h +++ b/src/gui/render_templates_hq2x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/gui/render_templates_hq3x.h b/src/gui/render_templates_hq3x.h index d879de8f..6f72393d 100644 --- a/src/gui/render_templates_hq3x.h +++ b/src/gui/render_templates_hq3x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/gui/render_templates_sai.h b/src/gui/render_templates_sai.h index 4088a637..62da940e 100644 --- a/src/gui/render_templates_sai.h +++ b/src/gui/render_templates_sai.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index ef5646d4..c26e1f51 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cmos.cpp,v 1.27 2009-04-26 18:26:10 qbix79 Exp $ */ +/* $Id: cmos.cpp,v 1.28 2009-05-27 09:15:41 qbix79 Exp $ */ #include diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index ee17c59c..e611e8c3 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dma.cpp,v 1.39 2008-09-13 20:04:28 c2woody Exp $ */ +/* $Id: dma.cpp,v 1.40 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index d749e984..628d368b 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 0d05b873..328c7804 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: iohandler.cpp,v 1.29 2009-04-11 08:02:23 qbix79 Exp $ */ +/* $Id: iohandler.cpp,v 1.30 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index f5c16af4..e4129d06 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.cpp,v 1.16 2009-05-15 18:16:33 qbix79 Exp $ */ +/* $Id: ipx.cpp,v 1.17 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/ipxserver.cpp b/src/hardware/ipxserver.cpp index b4045224..9c1d3d2b 100644 --- a/src/hardware/ipxserver.cpp +++ b/src/hardware/ipxserver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipxserver.cpp,v 1.9 2007-01-08 19:45:40 qbix79 Exp $ */ +/* $Id: ipxserver.cpp,v 1.10 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index 550ecca4..b963cfe8 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: joystick.cpp,v 1.20 2008-10-05 14:44:52 qbix79 Exp $ */ +/* $Id: joystick.cpp,v 1.21 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 72511107..4b48ef1c 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.40 2007-11-18 17:09:15 qbix79 Exp $ */ +/* $Id: keyboard.cpp,v 1.41 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" #include "keyboard.h" diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 5d362af5..20b2a924 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: memory.cpp,v 1.55 2008-10-27 11:02:41 c2woody Exp $ */ +/* $Id: memory.cpp,v 1.56 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index bf83177f..a0a82146 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.28 2008-11-10 15:29:38 qbix79 Exp $ */ +/* $Id: mpu401.cpp,v 1.29 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 15b5887b..94496714 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /* $Id: pcspeaker.cpp,v 1.25 2009-05-14 18:51:53 qbix79 Exp $ */ + /* $Id: pcspeaker.cpp,v 1.26 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index a0295faa..5a1df36c 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.43 2008-01-07 22:29:37 c2woody Exp $ */ +/* $Id: pic.cpp,v 1.44 2009-05-27 09:15:41 qbix79 Exp $ */ #include diff --git a/src/hardware/serialport/directserial_os2.cpp b/src/hardware/serialport/directserial_os2.cpp index 4bf88921..e1626641 100644 --- a/src/hardware/serialport/directserial_os2.cpp +++ b/src/hardware/serialport/directserial_os2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_os2.cpp,v 1.4 2007-02-22 08:41:16 qbix79 Exp $ */ +/* $Id: directserial_os2.cpp,v 1.5 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/directserial_os2.h b/src/hardware/serialport/directserial_os2.h index 99e4d1d1..5d818b27 100644 --- a/src/hardware/serialport/directserial_os2.h +++ b/src/hardware/serialport/directserial_os2.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_os2.h,v 1.4 2007-02-22 08:41:16 qbix79 Exp $ */ +/* $Id: directserial_os2.h,v 1.5 2009-05-27 09:15:41 qbix79 Exp $ */ // include guard #ifndef DOSBOX_DIRECTSERIAL_OS2_H diff --git a/src/hardware/serialport/directserial_posix.cpp b/src/hardware/serialport/directserial_posix.cpp index a13aec94..64bd7c2b 100644 --- a/src/hardware/serialport/directserial_posix.cpp +++ b/src/hardware/serialport/directserial_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_posix.cpp,v 1.3 2009-01-26 20:15:58 qbix79 Exp $ */ +/* $Id: directserial_posix.cpp,v 1.4 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/directserial_posix.h b/src/hardware/serialport/directserial_posix.h index 00bb0077..6d9865f5 100644 --- a/src/hardware/serialport/directserial_posix.h +++ b/src/hardware/serialport/directserial_posix.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_posix.h,v 1.3 2009-01-26 20:15:58 qbix79 Exp $ */ +/* $Id: directserial_posix.h,v 1.4 2009-05-27 09:15:41 qbix79 Exp $ */ // include guard #ifndef DOSBOX_DIRECTSERIAL_POSIX_H diff --git a/src/hardware/serialport/directserial_win32.cpp b/src/hardware/serialport/directserial_win32.cpp index dc9de4b4..c3073bb4 100644 --- a/src/hardware/serialport/directserial_win32.cpp +++ b/src/hardware/serialport/directserial_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_win32.cpp,v 1.7 2008-08-06 18:33:30 c2woody Exp $ */ +/* $Id: directserial_win32.cpp,v 1.8 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/directserial_win32.h b/src/hardware/serialport/directserial_win32.h index 9b978369..a2757f1a 100644 --- a/src/hardware/serialport/directserial_win32.h +++ b/src/hardware/serialport/directserial_win32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_win32.h,v 1.5 2007-05-23 08:05:22 qbix79 Exp $ */ +/* $Id: directserial_win32.h,v 1.6 2009-05-27 09:15:41 qbix79 Exp $ */ // include guard #ifndef DOSBOX_DIRECTSERIAL_WIN32_H diff --git a/src/hardware/serialport/nullmodem.cpp b/src/hardware/serialport/nullmodem.cpp index f343ace7..c447ad29 100644 --- a/src/hardware/serialport/nullmodem.cpp +++ b/src/hardware/serialport/nullmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: nullmodem.cpp,v 1.6 2009-02-01 14:24:37 qbix79 Exp $ */ +/* $Id: nullmodem.cpp,v 1.7 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/nullmodem.h b/src/hardware/serialport/nullmodem.h index 419b3681..7869e3e6 100644 --- a/src/hardware/serialport/nullmodem.h +++ b/src/hardware/serialport/nullmodem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: nullmodem.h,v 1.2 2007-02-22 08:41:16 qbix79 Exp $ */ +/* $Id: nullmodem.h,v 1.3 2009-05-27 09:15:41 qbix79 Exp $ */ // include guard #ifndef DOSBOX_NULLMODEM_WIN32_H diff --git a/src/hardware/serialport/serialdummy.cpp b/src/hardware/serialport/serialdummy.cpp index df8c6d88..c8aa9492 100644 --- a/src/hardware/serialport/serialdummy.cpp +++ b/src/hardware/serialport/serialdummy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialdummy.cpp,v 1.4 2007-01-13 08:35:49 qbix79 Exp $ */ +/* $Id: serialdummy.cpp,v 1.5 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/serialdummy.h b/src/hardware/serialport/serialdummy.h index 95b9d412..52087b51 100644 --- a/src/hardware/serialport/serialdummy.h +++ b/src/hardware/serialport/serialdummy.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialdummy.h,v 1.4 2007-01-13 08:35:49 qbix79 Exp $ */ +/* $Id: serialdummy.h,v 1.5 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef INCLUDEGUARD_SERIALDUMMY_H #define INCLUDEGUARD_SERIALDUMMY_H diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index 1a5d6234..fab9b220 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.cpp,v 1.11 2009-04-11 08:02:23 qbix79 Exp $ */ +/* $Id: serialport.cpp,v 1.12 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index bcd45952..7651dac2 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.cpp,v 1.10 2009-01-14 22:24:39 qbix79 Exp $ */ +/* $Id: softmodem.cpp,v 1.11 2009-05-27 09:15:42 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index 8a856a56..f30d746b 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.h,v 1.9 2009-04-11 08:02:23 qbix79 Exp $ */ +/* $Id: softmodem.h,v 1.10 2009-05-27 09:15:42 qbix79 Exp $ */ #ifndef DOSBOX_SERIALMODEM_H #define DOSBOX_SERIALMODEM_H diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 0dcb4b5c..9adde3a7 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index c1fab73c..0f1377bb 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga.cpp,v 1.35 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: vga.cpp,v 1.36 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" //#include "setup.h" diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index fd7df3c2..269f962c 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_attr.cpp,v 1.29 2008-10-05 14:44:52 qbix79 Exp $ */ +/* $Id: vga_attr.cpp,v 1.30 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" #include "inout.h" diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index a228521c..74f44762 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index 53055266..9ce72a7f 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_gfx.cpp,v 1.18 2008-01-09 20:34:51 c2woody Exp $ */ +/* $Id: vga_gfx.cpp,v 1.19 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" #include "inout.h" diff --git a/src/hardware/vga_paradise.cpp b/src/hardware/vga_paradise.cpp index d84ccc36..596b267d 100644 --- a/src/hardware/vga_paradise.cpp +++ b/src/hardware/vga_paradise.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_paradise.cpp,v 1.3 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: vga_paradise.cpp,v 1.4 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" #include "setup.h" diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 5af68a2d..409b2ca8 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_seq.cpp,v 1.23 2009-04-11 08:02:23 qbix79 Exp $ */ +/* $Id: vga_seq.cpp,v 1.24 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" #include "inout.h" diff --git a/src/hardware/vga_tseng.cpp b/src/hardware/vga_tseng.cpp index 678b6261..72c4612f 100644 --- a/src/hardware/vga_tseng.cpp +++ b/src/hardware/vga_tseng.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_tseng.cpp,v 1.4 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: vga_tseng.cpp,v 1.5 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index 5ced5bb7..363b9592 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_xga.cpp,v 1.16 2008-08-21 09:10:31 c2woody Exp $ */ +/* $Id: vga_xga.cpp,v 1.17 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 5f423f5b..9874cb73 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.73 2009-01-21 21:50:23 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.74 2009-05-27 09:15:42 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index bf6f3040..18c53297 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.37 2007-07-14 16:42:38 c2woody Exp $ */ +/* $Id: bios_disk.cpp,v 1.38 2009-05-27 09:15:42 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 9a4a89af..49cda3a1 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/ints/int10.h b/src/ints/int10.h index 9f84ed03..fdf01064 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.h,v 1.38 2009-04-25 16:25:03 harekiet Exp $ */ +/* $Id: int10.h,v 1.39 2009-05-27 09:15:42 qbix79 Exp $ */ #include "vga.h" diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index c4c201e2..ee291623 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.57 2009-04-25 16:25:03 harekiet Exp $ */ +/* $Id: int10_char.cpp,v 1.58 2009-05-27 09:15:42 qbix79 Exp $ */ /* Character displaying moving functions */ diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 97e8a20b..253a6052 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_memory.cpp,v 1.27 2008-08-09 15:37:15 c2woody Exp $ */ +/* $Id: int10_memory.cpp,v 1.28 2009-05-27 09:15:42 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index c983f395..4c91dbe2 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_misc.cpp,v 1.20 2009-04-11 07:58:39 qbix79 Exp $ */ +/* $Id: int10_misc.cpp,v 1.21 2009-05-27 09:15:42 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 8003edf3..49e48260 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 7d77412d..585260c5 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_put_pixel.cpp,v 1.22 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: int10_put_pixel.cpp,v 1.23 2009-05-27 09:15:42 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index c718a2fb..605a0e49 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.38 2009-04-11 07:58:39 qbix79 Exp $ */ +/* $Id: int10_vesa.cpp,v 1.39 2009-05-27 09:15:42 qbix79 Exp $ */ #include #include diff --git a/src/ints/int10_video_state.cpp b/src/ints/int10_video_state.cpp index 50d55950..4c697f61 100644 --- a/src/ints/int10_video_state.cpp +++ b/src/ints/int10_video_state.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_video_state.cpp,v 1.2 2008-08-06 18:32:35 c2woody Exp $ */ +/* $Id: int10_video_state.cpp,v 1.3 2009-05-27 09:15:42 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/ints/int10_vptable.cpp b/src/ints/int10_vptable.cpp index acd383d6..c21baf77 100644 --- a/src/ints/int10_vptable.cpp +++ b/src/ints/int10_vptable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vptable.cpp,v 1.3 2008-10-05 14:44:52 qbix79 Exp $ */ +/* $Id: int10_vptable.cpp,v 1.4 2009-05-27 09:15:42 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 8aafcf83..a5d9f669 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.54 2009-02-01 14:24:38 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.55 2009-05-27 09:15:42 qbix79 Exp $ */ #include #include diff --git a/src/ints/xms.h b/src/ints/xms.h index 863d27c8..f41151da 100644 --- a/src/ints/xms.h +++ b/src/ints/xms.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/libs/zmbv/drvproc.cpp b/src/libs/zmbv/drvproc.cpp index 27611cb9..faace585 100644 --- a/src/libs/zmbv/drvproc.cpp +++ b/src/libs/zmbv/drvproc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/libs/zmbv/zmbv.cpp b/src/libs/zmbv/zmbv.cpp index 2eb0fcb3..cb9d761c 100644 --- a/src/libs/zmbv/zmbv.cpp +++ b/src/libs/zmbv/zmbv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/libs/zmbv/zmbv.h b/src/libs/zmbv/zmbv.h index db619405..8306b962 100644 --- a/src/libs/zmbv/zmbv.h +++ b/src/libs/zmbv/zmbv.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/libs/zmbv/zmbv_vfw.cpp b/src/libs/zmbv/zmbv_vfw.cpp index 9ae25b37..4181797f 100644 --- a/src/libs/zmbv/zmbv_vfw.cpp +++ b/src/libs/zmbv/zmbv_vfw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 301174c0..221bbd98 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: messages.cpp,v 1.21 2009-02-01 14:18:12 qbix79 Exp $ */ +/* $Id: messages.cpp,v 1.22 2009-05-27 09:15:42 qbix79 Exp $ */ #include #include diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 58736618..b67aee75 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.36 2009-03-23 10:55:36 qbix79 Exp $ */ +/* $Id: programs.cpp,v 1.37 2009-05-27 09:15:42 qbix79 Exp $ */ #include #include diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 1cbbea0e..27bee4b4 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.55 2009-03-11 20:18:37 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.56 2009-05-27 09:15:42 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 18552eab..375923a6 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.36 2009-04-25 16:25:03 harekiet Exp $ */ +/* $Id: support.cpp,v 1.37 2009-05-27 09:15:42 qbix79 Exp $ */ #include #include diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 75e9c0cf..c96651bc 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -1,4 +1,4 @@ -#define VERSION "0.72" +#define VERSION "0.73" /* Define to 1 to enable internal debugger, requires libcurses */ #define C_DEBUG 0 diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index f3c3c42f..9bf40070 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.34 2009-04-22 12:28:51 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.35 2009-05-27 09:15:42 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 224f0956..0f51905f 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.53 2008-09-07 10:55:16 c2woody Exp $ */ +/* $Id: shell_misc.cpp,v 1.54 2009-05-27 09:15:42 qbix79 Exp $ */ #include #include diff --git a/src/winres.rc b/src/winres.rc index 66c79a45..4a071afa 100644 --- a/src/winres.rc +++ b/src/winres.rc @@ -7,8 +7,8 @@ dosbox_ico ICON "dosbox.ico" // version resource VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,72,0,0 - PRODUCTVERSION 0,72,0,0 + FILEVERSION 0,73,0,0 + PRODUCTVERSION 0,73,0,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -22,12 +22,12 @@ BEGIN VALUE "Comments", "© 2002-2009 DOSBox Team, published under GNU GPL" VALUE "CompanyName", "DOSBox Team" VALUE "FileDescription", "DOSBox DOS Emulator" - VALUE "FileVersion", "0, 72, 0, 0" + VALUE "FileVersion", "0, 73, 0, 0" VALUE "InternalName", "DOSBox" VALUE "LegalCopyright", "Copyright © 2002-2009 DOSBox Team" VALUE "OriginalFilename", "dosbox.exe" VALUE "ProductName", "DOSBox DOS Emulator" - VALUE "ProductVersion", "0, 72, 0, 0" + VALUE "ProductVersion", "0, 73, 0, 0" END END BLOCK "VarFileInfo" From fb86dbe837ebb775a89df944f09c0df178309d87 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 27 May 2009 14:34:06 +0000 Subject: [PATCH 3323/4131] Some documentation updates. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3411 --- README | 4 ++-- docs/dosbox.1 | 42 +++++++++++++++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/README b/README index 4310aed5..65b2312e 100644 --- a/README +++ b/README @@ -381,7 +381,7 @@ dosbox -eraseconf You can specify this command more than once. In this case it will move to second program if the first one fails to start. - -opencaptures + -opencaptures program calls program with as first paramater the location of the captures folder. @@ -389,7 +389,7 @@ dosbox -eraseconf prints the location of the default configuration file. -eraseconf - removes the default configuration file + removes the default configuration file. Note: If a name/command/configfile/languagefile contains a space, put the whole name/command/configfile/languagefile between quotes diff --git a/docs/dosbox.1 b/docs/dosbox.1 index c895bbbe..653e57d3 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -1,5 +1,5 @@ .\" Hey, EMACS: -*- nroff -*- -.TH DOSBOX 1 "Jul 01, 2007" +.TH DOSBOX 1 "May 27, 2009" .\" Please adjust this date whenever revising the manpage. .SH NAME dosbox \- an x86/DOS emulator with sound/graphics @@ -18,7 +18,15 @@ dosbox \- an x86/DOS emulator with sound/graphics .B [\-exit] .BI "[\-machine " machinetype ] .LP -.B dosbox -version +.B dosbox \-version +.LP +.BI "dosbox \-editconf" " program" +.LP +.BI "dosbox \-opencaptures" " program" +.LP +.B dosbox \-printconf +.LP +.B dosbox \-eraseconf .SH DESCRIPTION This manual page briefly documents .BR "dosbox" ", an x86/DOS emulator." @@ -74,17 +82,31 @@ wish to execute on startup. Multiple .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." +.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)". +.RI "Valid choices are: " "hercules, cga, tandy, pcjr, ega, vgaonly, svga_s3(default), svga_et3000, svga_et4000, svga_paradise, vesa_nolfb, vesa_oldvbe". The machinetype has influence on both the videocard and the available soundcards. .TP .B \-version Output version information and exit. Useful for frontends. +.TP +.BI \-editconf " program" +.RI calls " program" " with as first parameter the configuration file." +.R You can specify this command more than once. In this case it will +.RI " move to second " program " if the first one fails to start." +.TP +.BI \-opencaptures " program" +.RI "calls " program " with as first paramater the location of the captures folder." +.TP +.B \-printconf +.R prints the location of the default configuration file. +.TP +.B \-eraseconf +.R removes the default configuration file. .SH "INTERNAL COMMANDS" .B dosbox supports most of the DOS commands found in command.com. In addition, the @@ -243,11 +265,13 @@ Keyb can change the keyboardlayout and the codepage used inside dosbox. .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 +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. +loaded automatically. If a configfile is specified at the commandline +that one will be used instead. If no configfile is specified or found +in the current directory +.RB " then dosbox will load one from " ~/.dosbox/ ". It will try to create " +one if there is none. .SH "SPECIAL KEYS" .TP 12m .IP ALT\-ENTER From f56a09814bc1b71a370dd025ac36972c48f84e2a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 27 May 2009 16:14:38 +0000 Subject: [PATCH 3324/4131] Version number update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3412 --- scripts/dosbox-installer.nsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index 149ed253..629bca5c 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -1,11 +1,11 @@ !define VER_MAYOR 0 -!define VER_MINOR 72 +!define VER_MINOR 73 !define APP_NAME "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer" !define COMP_NAME "DOSBox Team" !define COPYRIGHT "Copyright © 2002-2009 DOSBox Team" !define DESCRIPTION "DOSBox Installer" -VIProductVersion "${VER_MAYOR}.73.0.0" +VIProductVersion "${VER_MAYOR}.${VER_MINOR}.0.0" VIAddVersionKey "ProductName" "${APP_NAME}" VIAddVersionKey "CompanyName" "${COMP_NAME}" VIAddVersionKey "FileDescription" "${DESCRIPTION}" From eca7e8600f43952219b75377278f3f5e789856d8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 1 Jun 2009 10:25:51 +0000 Subject: [PATCH 3325/4131] Some mapper fixes related to interfacing with mapper overlay. Fixes missing keyups etc Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3414 --- src/gui/sdl_mapper.cpp | 7 +++++-- src/gui/sdlmain.cpp | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index d8f3c4cb..480f0e4b 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.59 2009-05-14 18:01:25 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.60 2009-06-01 10:25:51 qbix79 Exp $ */ #include #include @@ -2126,7 +2126,7 @@ void BIND_MappingEvents(void) { SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { - case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: /* Check the press */ for (CButton_it but_it = buttons.begin();but_it!=buttons.end();but_it++) { if ((*but_it)->OnTop(event.button.x,event.button.y)) { @@ -2272,7 +2272,10 @@ void MAPPER_Run(bool pressed) { return; KEYBOARD_ClrBuffer(); //Clear buffer GFX_LosingFocus(); //Release any keys pressed (buffer gets filled again). + MAPPER_RunInternal(); +} +void MAPPER_RunInternal() { int cursor = SDL_ShowCursor(SDL_QUERY); SDL_ShowCursor(SDL_ENABLE); bool mousetoggle=false; diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 4ce3d12a..555a411d 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.153 2009-05-25 16:29:36 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.154 2009-06-01 10:25:51 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1816,7 +1816,7 @@ int main(int argc, char* argv[]) { /* Init the keyMapper */ MAPPER_Init(); - if (control->cmdline->FindExist("-startmapper")) MAPPER_Run(false); + if (control->cmdline->FindExist("-startmapper")) MAPPER_RunInternal(); /* Start up main machine */ control->StartUp(); /* Shutdown everything */ From fbfe0dbf3dcea5b9d6477ba59dae66c26b6bbe92 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 1 Jun 2009 10:26:14 +0000 Subject: [PATCH 3326/4131] Some mapper fixes related to interfacing with mapper overlay. Fixes missing keyups etc. and these :) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3415 --- include/mapper.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/mapper.h b/include/mapper.h index 17b02211..bf329cb1 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -30,6 +30,7 @@ void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char const void MAPPER_Init(void); void MAPPER_StartUp(Section * sec); void MAPPER_Run(bool pressed); +void MAPPER_RunInternal(); void MAPPER_LosingFocus(void); From f5fc904ff5c4608b056d59d36094a6ed15a3820e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 6 Jun 2009 15:45:31 +0000 Subject: [PATCH 3327/4131] better sb dsp reset mechanism (hal), fixes stmik-based applications; add sb irq acknowledge logic Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3416 --- src/hardware/sblaster.cpp | 94 ++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 31 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 05620830..0516e886 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.73 2009-04-25 07:02:28 qbix79 Exp $ */ +/* $Id: sblaster.cpp,v 1.74 2009-06-06 15:45:31 c2woody Exp $ */ #include #include @@ -62,7 +62,7 @@ bool MIDI_Available(void); #define SB_SH 14 #define SB_SH_MASK ((1 << SB_SH)-1) -enum {DSP_S_RESET,DSP_S_NORMAL,DSP_S_HIGHSPEED}; +enum {DSP_S_RESET,DSP_S_RESET_WAIT,DSP_S_NORMAL,DSP_S_HIGHSPEED}; enum SB_TYPES {SBT_NONE=0,SBT_1=1,SBT_PRO1=2,SBT_2=3,SBT_PRO2=4,SBT_16=6}; enum SB_IRQS {SB_IRQ_8,SB_IRQ_16,SB_IRQ_MPU}; @@ -117,6 +117,7 @@ struct SB_INFO { Bit8u cmd_in_pos; Bit8u cmd_in[DSP_BUFSIZE]; struct { + Bit8u lastval; Bit8u data[DSP_BUFSIZE]; Bitu pos,used; } in,out; @@ -145,7 +146,7 @@ struct SB_INFO { struct { Bitu base; Bitu irq; - Bitu dma8,dma16; + Bit8u dma8,dma16; } hw; struct { Bits value; @@ -246,13 +247,22 @@ static void DSP_SetSpeaker(bool how) { static INLINE void SB_RaiseIRQ(SB_IRQS type) { LOG(LOG_SB,LOG_NORMAL)("Raising IRQ"); - PIC_ActivateIRQ(sb.hw.irq); switch (type) { case SB_IRQ_8: + if (sb.irq.pending_8bit) { + E_Exit("SB: 8bit irq pending"); + return; + } sb.irq.pending_8bit=true; + PIC_ActivateIRQ(sb.hw.irq); break; case SB_IRQ_16: + if (sb.irq.pending_16bit) { + E_Exit("SB: 16bit irq pending"); + return; + } sb.irq.pending_16bit=true; + PIC_ActivateIRQ(sb.hw.irq); break; default: break; @@ -316,7 +326,7 @@ static INLINE Bit8u decode_ADPCM_4_sample(Bit8u sample,Bit8u & reference,Bits& s Bits ref = reference + scaleMap[samp]; if (ref > 0xff) reference = 0xff; else if (ref < 0x00) reference = 0x00; - else reference = ref; + else reference = (Bit8u)(ref&0xff); scale = (scale + adjustMap[samp]) & 0xff; return reference; @@ -345,7 +355,7 @@ static INLINE Bit8u decode_ADPCM_2_sample(Bit8u sample,Bit8u & reference,Bits& s Bits ref = reference + scaleMap[samp]; if (ref > 0xff) reference = 0xff; else if (ref < 0x00) reference = 0x00; - else reference = ref; + else reference = (Bit8u)(ref&0xff); scale = (scale + adjustMap[samp]) & 0xff; return reference; @@ -377,7 +387,7 @@ INLINE Bit8u decode_ADPCM_3_sample(Bit8u sample,Bit8u & reference,Bits& scale) { Bits ref = reference + scaleMap[samp]; if (ref > 0xff) reference = 0xff; else if (ref < 0x00) reference = 0x00; - else reference = ref; + else reference = (Bit8u)(ref&0xff); scale = (scale + adjustMap[samp]) & 0xff; return reference; @@ -573,7 +583,7 @@ static void DSP_ChangeMode(DSP_MODES mode) { sb.mode=mode; } -static void DSP_RaiseIRQEvent(Bitu val) { +static void DSP_RaiseIRQEvent(Bitu /*val*/) { SB_RaiseIRQ(SB_IRQ_8); } @@ -678,13 +688,23 @@ static void DSP_AddData(Bit8u val) { } +static void DSP_FinishReset(Bitu /*val*/) { + DSP_FlushData(); + DSP_AddData(0xaa); + sb.dsp.state=DSP_S_NORMAL; +} + static void DSP_Reset(void) { LOG(LOG_SB,LOG_ERROR)("DSP:Reset"); PIC_DeActivateIRQ(sb.hw.irq); + DSP_ChangeMode(MODE_NONE); + DSP_FlushData(); sb.dsp.cmd_len=0; sb.dsp.in.pos=0; sb.dsp.write_busy=0; + PIC_RemoveEvents(DSP_FinishReset); + sb.dma.left=0; sb.dma.total=0; sb.dma.stereo=false; @@ -693,6 +713,7 @@ static void DSP_Reset(void) { sb.dma.mode=DSP_DMA_NONE; sb.dma.remain_size=0; if (sb.dma.chan) sb.dma.chan->Clear_Request(); + sb.freq=22050; sb.time_constant=45; sb.dac.used=0; @@ -706,29 +727,28 @@ static void DSP_Reset(void) { PIC_RemoveEvents(END_DMA_Event); } - static void DSP_DoReset(Bit8u val) { - if ((val&1)!=0) { + if (((val&1)!=0) && (sb.dsp.state!=DSP_S_RESET)) { //TODO Get out of highspeed mode DSP_Reset(); sb.dsp.state=DSP_S_RESET; - } else { - DSP_FlushData(); - DSP_AddData(0xaa); - sb.dsp.state=DSP_S_NORMAL; + } else if (((val&1)==0) && (sb.dsp.state==DSP_S_RESET)) { // reset off + sb.dsp.state=DSP_S_RESET_WAIT; + PIC_RemoveEvents(DSP_FinishReset); + PIC_AddEvent(DSP_FinishReset,20.0f/1000.0f,0); // 20 microseconds } } -static void DSP_E2_DMA_CallBack(DmaChannel * chan, DMAEvent event) { +static void DSP_E2_DMA_CallBack(DmaChannel * /*chan*/, DMAEvent event) { if (event==DMA_UNMASKED) { - Bit8u val=sb.e2.value; + Bit8u val=(Bit8u)(sb.e2.value&0xff); DmaChannel * chan=GetDMAChannel(sb.hw.dma8); chan->Register_Callback(0); chan->Write(1,&val); } } -static void DSP_ADC_CallBack(DmaChannel * chan, DMAEvent event) { +static void DSP_ADC_CallBack(DmaChannel * /*chan*/, DMAEvent event) { if (event!=DMA_UNMASKED) return; Bit8u val=128; DmaChannel * ch=GetDMAChannel(sb.hw.dma8); @@ -1047,14 +1067,13 @@ static void DSP_DoWrite(Bit8u val) { static Bit8u DSP_ReadData(void) { /* Static so it repeats the last value on succesive reads (JANGLE DEMO) */ - static Bit8u data = 0; if (sb.dsp.out.used) { - data=sb.dsp.out.data[sb.dsp.out.pos]; + sb.dsp.out.lastval=sb.dsp.out.data[sb.dsp.out.pos]; sb.dsp.out.pos++; if (sb.dsp.out.pos>=DSP_BUFSIZE) sb.dsp.out.pos-=DSP_BUFSIZE; sb.dsp.out.used--; } - return data; + return sb.dsp.out.lastval; } //The soundblaster manual says 2.0 Db steps but we'll go for a bit less @@ -1337,7 +1356,7 @@ static Bit8u CTMIXER_Read(void) { } -static Bitu read_sb(Bitu port,Bitu iolen) { +static Bitu read_sb(Bitu port,Bitu /*iolen*/) { switch (port-sb.hw.base) { case MIXER_INDEX: return sb.mixer.index; @@ -1360,6 +1379,7 @@ static Bitu read_sb(Bitu port,Bitu iolen) { if (sb.dsp.write_busy & 8) return 0xff; return 0x7f; case DSP_S_RESET: + case DSP_S_RESET_WAIT: return 0xff; } return 0xff; @@ -1372,19 +1392,20 @@ static Bitu read_sb(Bitu port,Bitu iolen) { return 0xff; } -static void write_sb(Bitu port,Bitu val,Bitu iolen) { +static void write_sb(Bitu port,Bitu val,Bitu /*iolen*/) { + Bit8u val8=(Bit8u)(val&0xff); switch (port-sb.hw.base) { case DSP_RESET: - DSP_DoReset(val); + DSP_DoReset(val8); break; case DSP_WRITE_DATA: - DSP_DoWrite(val); + DSP_DoWrite(val8); break; case MIXER_INDEX: - sb.mixer.index=val; + sb.mixer.index=val8; break; case MIXER_DATA: - CTMIXER_Write(val); + CTMIXER_Write(val8); break; default: LOG(LOG_SB,LOG_NORMAL)("Unhandled write to SB Port %4X",port); @@ -1392,8 +1413,8 @@ static void write_sb(Bitu port,Bitu val,Bitu iolen) { } } -static void adlib_gusforward(Bitu port,Bitu val,Bitu iolen) { - adlib_commandreg=val; +static void adlib_gusforward(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { + adlib_commandreg=(Bit8u)(val&0xff); } static void SBLASTER_CallBack(Bitu len) { @@ -1469,10 +1490,16 @@ public: SBLASTER(Section* configuration):Module_base(configuration) { Bitu i; Section_prop * section=static_cast(configuration); + sb.hw.base=section->Get_hex("sbbase"); sb.hw.irq=section->Get_int("irq"); - sb.hw.dma8=section->Get_int("dma"); - sb.hw.dma16=section->Get_int("hdma"); + Bitu dma8bit=section->Get_int("dma"); + if (dma8bit>0xff) dma8bit=0xff; + sb.hw.dma8=(Bit8u)(dma8bit&0xff); + Bitu dma16bit=section->Get_int("hdma"); + if (dma16bit>0xff) dma16bit=0xff; + sb.hw.dma16=(Bit8u)(dma16bit&0xff); + sb.mixer.enabled=section->Get_bool("sbmixer"); sb.mixer.stereo=false; OPL_Mode opl_mode = OPL_none; @@ -1493,9 +1520,12 @@ public: OPL_Init(section,opl_mode); break; } + if (sb.type==SBT_NONE) return; + sb.chan=MixerChan.Install(&SBLASTER_CallBack,22050,"SB"); sb.dsp.state=DSP_S_NORMAL; + sb.dsp.out.lastval=0xaa; sb.dma.chan=NULL; for (i=4;i<=0xf;i++) { @@ -1508,8 +1538,10 @@ public: for (i=0;i<256;i++) ASP_regs[i] = 0; ASP_regs[5] = 0x01; ASP_regs[9] = 0xf8; + DSP_Reset(); CTMIXER_Reset(); + // The documentation does not specify if SB gets initialized with the speaker enabled // or disabled. Real SBPro2 has it disabled. sb.speaker=false; @@ -1559,7 +1591,7 @@ public: static SBLASTER* test; -void SBLASTER_ShutDown(Section* sec) { +void SBLASTER_ShutDown(Section* /*sec*/) { delete test; } From 618f0867c139f78fb9e3ba78bd0f1786f6405fbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 6 Jun 2009 21:52:09 +0000 Subject: [PATCH 3328/4131] some more special handling for the emm system handle Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3417 --- src/ints/ems.cpp | 71 +++++++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 8a00705e..98879bdf 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.62 2009-05-14 17:51:47 qbix79 Exp $ */ +/* $Id: ems.cpp,v 1.63 2009-06-06 21:52:09 c2woody Exp $ */ #include #include @@ -43,8 +43,9 @@ #define EMM_VERSION 0x40 #define GEMMIS_VERSION 0x0001 // Version 1.0 -#define NULL_HANDLE 0xffff -#define NULL_PAGE 0xffff +#define EMM_SYSTEM_HANDLE 0x0000 +#define NULL_HANDLE 0xffff +#define NULL_PAGE 0xffff #define ENABLE_VCPI 1 #define ENABLE_V86_STARTUP 0 @@ -71,6 +72,25 @@ #define EMM_MOVE_OVLAPI 0x97 #define EMM_NOT_FOUND 0xa0 + +struct EMM_Mapping { + Bit16u handle; + Bit16u page; +}; + +struct EMM_Handle { + Bit16u pages; + MemHandle mem; + char name[8]; + bool saved_page_map; + EMM_Mapping page_map[EMM_MAX_PHYS]; +}; + +static EMM_Handle emm_handles[EMM_MAX_HANDLES]; +static EMM_Mapping emm_mappings[EMM_MAX_PHYS]; +static EMM_Mapping emm_segmentmappings[0x40]; + + static Bit16u GEMMIS_seg; class device_EMM : public DOS_Device { @@ -144,8 +164,13 @@ bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retco mem_writew(GEMMIS_addr+0x18d,0x0000); // system handle mem_writed(GEMMIS_addr+0x18f,0); // handle name mem_writed(GEMMIS_addr+0x193,0); // handle name - mem_writew(GEMMIS_addr+0x197,0x0010); // system handle - mem_writed(GEMMIS_addr+0x199,0x00110000); // physical address + if (emm_handles[EMM_SYSTEM_HANDLE].pages != NULL_HANDLE) { + mem_writew(GEMMIS_addr+0x197,(emm_handles[EMM_SYSTEM_HANDLE].pages+3)/4); + mem_writed(GEMMIS_addr+0x199,emm_handles[EMM_SYSTEM_HANDLE].mem<<12); // physical address + } else { + mem_writew(GEMMIS_addr+0x197,0x0001); // system handle + mem_writed(GEMMIS_addr+0x199,0x00110000); // physical address + } /* fill buffer with import structure */ mem_writed(bufptr+0x00,GEMMIS_seg<<4); @@ -163,23 +188,6 @@ bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retco return false; } -struct EMM_Mapping { - Bit16u handle; - Bit16u page; -}; - -struct EMM_Handle { - Bit16u pages; - MemHandle mem; - char name[8]; - bool saved_page_map; - EMM_Mapping page_map[EMM_MAX_PHYS]; -}; - -static EMM_Handle emm_handles[EMM_MAX_HANDLES]; -static EMM_Mapping emm_mappings[EMM_MAX_PHYS]; -static EMM_Mapping emm_segmentmappings[0x40]; - static struct { bool enabled; Bit16u ems_handle; @@ -239,7 +247,7 @@ static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & dhandle,bool can_allocate_ static Bit8u EMM_AllocateSystemHandle(Bit16u pages) { /* Check for enough free pages */ if ((MEM_FreeTotal()/ 4) < pages) { return EMM_OUT_OF_LOG;} - Bit16u handle = 0; // emm system handle (reserved for OS usage) + Bit16u handle = EMM_SYSTEM_HANDLE; // emm system handle (reserved for OS usage) /* Release memory if already allocated */ if (emm_handles[handle].pages != NULL_HANDLE) { MEM_ReleasePages(emm_handles[handle].mem); @@ -1093,11 +1101,11 @@ static Bitu V86_Monitor() { } break; case 0xe4: // IN AL,Ib - reg_al=IO_ReadB(mem_readb((v86_cs<<4)+v86_ip+1)); + reg_al=(Bit8u)(IO_ReadB(mem_readb((v86_cs<<4)+v86_ip+1))&0xff); mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+2); break; case 0xe5: // IN AX,Ib - reg_ax=IO_ReadW(mem_readb((v86_cs<<4)+v86_ip+1)); + reg_ax=(Bit16u)(IO_ReadW(mem_readb((v86_cs<<4)+v86_ip+1))&0xffff); mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+2); break; case 0xe6: // OUT Ib,AL @@ -1109,11 +1117,11 @@ static Bitu V86_Monitor() { mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+2); break; case 0xec: // IN AL,DX - reg_al=IO_ReadB(reg_dx); + reg_al=(Bit8u)(IO_ReadB(reg_dx)&0xff); mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+1); break; case 0xed: // IN AX,DX - reg_ax=IO_ReadW(reg_dx); + reg_ax=(Bit16u)(IO_ReadW(reg_dx)&0xffff); mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+1); break; case 0xee: // OUT DX,AL @@ -1304,7 +1312,8 @@ public: emm_segmentmappings[i].handle=NULL_HANDLE; } - EMM_AllocateSystemHandle(4); // allocate OS-dedicated handle (ems handle zero) + EMM_AllocateSystemHandle(4); // allocate OS-dedicated handle (ems handle zero, 16kb) + if (!ENABLE_VCPI) return; @@ -1363,6 +1372,12 @@ public: char buf[32]= { 0 }; MEM_BlockWrite(PhysMake(emsnameseg,0),buf,32); RealSetVec(0x67,old67_pointer); + + /* Release memory allocated to system handle */ + if (emm_handles[EMM_SYSTEM_HANDLE].pages != NULL_HANDLE) { + MEM_ReleasePages(emm_handles[EMM_SYSTEM_HANDLE].mem); + } + /* Clear handle and page tables */ //TODO From 4ad533c78f42bf385a05cc62e4390141a8c0ca57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 7 Jun 2009 10:18:14 +0000 Subject: [PATCH 3329/4131] use different sb detection for tandy dac initialization Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3418 --- include/hardware.h | 4 ++ src/hardware/sblaster.cpp | 16 +++++++- src/ints/bios.cpp | 80 +++++++++++++-------------------------- 3 files changed, 45 insertions(+), 55 deletions(-) diff --git a/include/hardware.h b/include/hardware.h index df2c73ce..8823aac9 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: hardware.h,v 1.16 2009-06-07 10:18:13 c2woody Exp $ */ + #ifndef DOSBOX_HARDWARE_H #define DOSBOX_HARDWARE_H @@ -38,6 +40,8 @@ void CMS_Init(Section* sec); void OPL_ShutDown(Section* sec); void CMS_ShutDown(Section* sec); +bool SB_Get_Address(Bitu& sbaddr, Bitu& sbirq, Bitu& sbdma); + extern Bit8u adlib_commandreg; FILE * OpenCaptureFile(const char * type,const char * ext); diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 0516e886..7ffaa56e 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.74 2009-06-06 15:45:31 c2woody Exp $ */ +/* $Id: sblaster.cpp,v 1.75 2009-06-07 10:18:13 c2woody Exp $ */ #include #include @@ -1417,6 +1417,19 @@ static void adlib_gusforward(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { adlib_commandreg=(Bit8u)(val&0xff); } +bool SB_Get_Address(Bitu& sbaddr, Bitu& sbirq, Bitu& sbdma) { + sbaddr=0; + sbirq =0; + sbdma =0; + if (sb.type == SBT_NONE) return false; + else { + sbaddr=sb.hw.base; + sbirq =sb.hw.irq; + sbdma = sb.hw.dma8; + return true; + } +} + static void SBLASTER_CallBack(Bitu len) { switch (sb.mode) { case MODE_NONE: @@ -1443,6 +1456,7 @@ static void SBLASTER_CallBack(Bitu len) { break; } } + class SBLASTER: public Module_base { private: /* Data */ diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 9874cb73..a0f3181b 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.74 2009-05-27 09:15:42 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.75 2009-06-07 10:18:14 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -26,6 +26,7 @@ #include "callback.h" #include "inout.h" #include "pic.h" +#include "hardware.h" #include "joystick.h" #include "mouse.h" #include "setup.h" @@ -70,48 +71,19 @@ static struct { Bit8u dma; } tandy_sb; -static bool Tandy_ProbeSBPort(Bit16u sbport) { - IO_Write(sbport+0x6,1); - IO_Write(sbport+0x6,0); - while (!(IO_Read(sbport+0xe)&0x80)) ; - if (IO_Read(sbport+0xa)==0xaa) return true; - else return false; -} - static bool Tandy_InitializeSB() { - /* see if soundblaster module available and at what port */ - if (Tandy_ProbeSBPort(0x220)) tandy_sb.port=0x220; - else if (Tandy_ProbeSBPort(0x230)) tandy_sb.port=0x230; - else if (Tandy_ProbeSBPort(0x210)) tandy_sb.port=0x210; - else if (Tandy_ProbeSBPort(0x240)) tandy_sb.port=0x240; - else if (Tandy_ProbeSBPort(0x250)) tandy_sb.port=0x250; - else if (Tandy_ProbeSBPort(0x260)) tandy_sb.port=0x260; - else { + /* see if soundblaster module available and at what port/IRQ/DMA */ + Bitu sbport, sbirq, sbdma; + if (SB_Get_Address(sbport, sbirq, sbdma)) { + tandy_sb.port=(Bit16u)(sbport&0xffff); + tandy_sb.irq =(Bit8u)(sbirq&0xff); + tandy_sb.dma =(Bit8u)(sbdma&0xff); + return true; + } else { /* no soundblaster accessible, disable Tandy DAC */ tandy_sb.port=0; return false; } - - /* try to detect IRQ setting */ - IO_Write(tandy_sb.port+0x4,0x80); - Bit8u rval=IO_Read(tandy_sb.port+0x5); - if (rval && (rval!=0xff)) { - if (rval&1) tandy_sb.irq=0x02; - else if (rval&2) tandy_sb.irq=0x05; - else if (rval&4) tandy_sb.irq=0x07; - else tandy_sb.irq=0x10; - } else tandy_sb.irq=0x07; /* assume irq=7 for older soundblaster settings */ - - /* try to detect DMA setting */ - IO_Write(tandy_sb.port+0x4,0x81); - rval=IO_Read(tandy_sb.port+0x5); - if (rval && (rval!=0xff)) { - if (rval&1) tandy_sb.dma=0x00; - else if (rval&2) tandy_sb.dma=0x01; - else tandy_sb.dma=0x03; - } else tandy_sb.dma=0x01; /* assume dma=1 for older soundblaster settings */ - - return true; } /* check if Tandy DAC is still playing */ @@ -120,7 +92,7 @@ static bool Tandy_TransferInProgress(void) { if (real_readb(0x40,0xd4)==0xff) return false; /* still in init-state */ IO_Write(0x0c,0x00); - Bit16u datalen=IO_ReadB(tandy_sb.dma*2+1); + Bit16u datalen=(Bit8u)(IO_ReadB(tandy_sb.dma*2+1)&0xff); datalen|=(IO_ReadB(tandy_sb.dma*2+1)<<8); if (datalen==0xffff) return false; /* no DMA transfer */ else if ((datalen<0x10) && (real_readb(0x40,0xd4)==0x0f) && (real_readw(0x40,0xd2)==0x1c)) { @@ -173,7 +145,7 @@ static void Tandy_SetupTransfer(PhysPt bufpt,bool isplayback) { IO_Write(tandy_sb.dma*2+1,(Bit8u)((tlength>>8)&0xff)); IO_Write(0x0a,tandy_sb.dma); /* enable DMA channel */ - Bitu delay=real_readw(0x40,0xd2)&0xfff; + Bit16u delay=(Bit16u)(real_readw(0x40,0xd2)&0xfff); /* set frequency */ IO_Write(tandy_sb.port+0xc,0x40); IO_Write(tandy_sb.port+0xc,256-delay*100/358); @@ -186,7 +158,7 @@ static void Tandy_SetupTransfer(PhysPt bufpt,bool isplayback) { if (!isplayback) { /* mark transfer as recording operation */ - real_writew(0x40,0xd2,delay|0x1000); + real_writew(0x40,0xd2,(Bit16u)(delay|0x1000)); } } @@ -439,8 +411,8 @@ static Bitu INT14_Handler(void) IO_ReadB(port+2); // get result - reg_ah=IO_ReadB(port+5); - reg_al=IO_ReadB(port+6); + reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff); + reg_al=(Bit8u)(IO_ReadB(port+6)&0xff); CALLBACK_SCF(false); } break; @@ -458,7 +430,7 @@ static Bitu INT14_Handler(void) timeout = !serialports[reg_dx]->Putchar(reg_al,true,true, mem_readb(BIOS_COM1_TIMEOUT+reg_dx)*1000); // get result - reg_ah=IO_ReadB(port+5); + reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff); if(timeout) reg_ah |= 0x80; } CALLBACK_SCF(false); @@ -479,7 +451,7 @@ static Bitu INT14_Handler(void) // RTS off IO_WriteB(port+4,0x1); // get result - reg_ah=IO_ReadB(port+5); + reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff); if(timeout) reg_ah |= 0x80; else reg_al=buffer; } @@ -488,8 +460,8 @@ static Bitu INT14_Handler(void) } case 0x03: // get status { - reg_ah=IO_ReadB(port+5); - reg_al=IO_ReadB(port+6); + reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff); + reg_al=(Bit8u)(IO_ReadB(port+6)&0xff); CALLBACK_SCF(false); } break; @@ -498,7 +470,7 @@ static Bitu INT14_Handler(void) } static Bitu INT15_Handler(void) { - static Bitu biosConfigSeg=0; + static Bit16u biosConfigSeg=0; switch (reg_ah) { case 0x06: LOG(LOG_BIOS,LOG_NORMAL)("INT15 Unkown Function 6"); @@ -767,7 +739,7 @@ void BIOS_ZeroExtendedSize(bool in) { #define RAM_REFRESH_DELAY 16.7f -static void RAMRefresh_Event(Bitu val) { +static void RAMRefresh_Event(Bitu /*val*/) { PIC_ActivateIRQ(5); PIC_AddEvent(RAMRefresh_Event,RAM_REFRESH_DELAY); } @@ -917,7 +889,7 @@ public: RealPt current_irq=RealGetVec(tandy_sb.irq+8); real_writed(0x40,0xd6,current_irq); - for (Bitu i=0; i<0x10; i++) phys_writeb(PhysMake(0xf000,0xa084+i),0x80); + for (Bit16u i=0; i<0x10; i++) phys_writeb(PhysMake(0xf000,0xa084+i),0x80); } else real_writeb(0x40,0xd4,0x00); } @@ -971,8 +943,8 @@ public: /* Setup equipment list */ // look http://www.bioscentral.com/misc/bda.htm - //Bitu config=0x4400; //1 Floppy, 2 serial and 1 parrallel - Bitu config = 0x0; + //Bit16u config=0x4400; //1 Floppy, 2 serial and 1 parallel + Bit16u config = 0x0; // set number of parallel ports // if(ppindex == 0) config |= 0x8000; // looks like 0 ports are not specified @@ -1004,7 +976,7 @@ public: // Gameport config |= 0x1000; mem_writew(BIOS_CONFIGURATION,config); - CMOS_SetRegister(0x14,config); //Should be updated on changes + CMOS_SetRegister(0x14,(Bit8u)(config&0xff)); //Should be updated on changes /* Setup extended memory size */ IO_Write(0x70,0x30); size_extended=IO_Read(0x71); @@ -1058,7 +1030,7 @@ void BIOS_SetComPorts(Bit16u baseaddr[]) { static BIOS* test; -void BIOS_Destroy(Section* sec){ +void BIOS_Destroy(Section* /*sec*/){ delete test; } From 20f226de9015b12cfff0be61f476188e5d62b0c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 7 Jun 2009 19:49:39 +0000 Subject: [PATCH 3330/4131] slight changes to the rhythm algorithms Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3419 --- src/hardware/dbopl.cpp | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index 6845b076..06500ead 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -32,6 +32,8 @@ //DUNNO Keyon in 4op, switch to 2op without keyoff. */ +/* $Id: dbopl.cpp,v 1.9 2009-06-07 19:49:39 c2woody Exp $ */ + #include #include @@ -472,7 +474,7 @@ void Operator::Write20( const Chip* chip, Bit8u val ) { } } -void Operator::Write40( const Chip* chip, Bit8u val ) { +void Operator::Write40( const Chip* /*chip*/, Bit8u val ) { if (!(reg40 ^ val )) return; reg40 = val; @@ -809,27 +811,20 @@ INLINE void Channel::GeneratePercussion( Chip* chip, Bit32s* output ) { //Precalculate stuff used by other outputs Bit32u noiseBit = (chip->ForwardNoise() & 0x1) << 1; Bit32u c2 = op2->ForwardWave(); - //(bit 7 ^ bit 2) | bit 3 -> combined in bit 1 - Bit32u phaseBit = ( (c2 >> 6) ^ ( c2 >> 1 ) ) | ( c2 >> 2 ); Bit32u c4 = op4->ForwardWave(); - //bit 5 ^ bit 3 to bit 1 - Bit32u gateBit = ( c4 >> 4 ) ^ ( c4 >> 3 ); - phaseBit = (phaseBit | gateBit) & 0x2; + Bit32u phaseBit = (((c2 & 0x88) ^ ((c2<<5) & 0x80)) | ((c4 ^ (c4<<2)) & 0x20)) ? 0x02 : 0x00; //Hi-Hat Bit32u hhVol = op2->ForwardVolume(); if ( !ENV_SILENT( hhVol ) ) { - /* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */ - /* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */ - Bit32u hhIndex = ( phaseBit << 8 ) | ( 0xd0 >> ( phaseBit ^ noiseBit ) ); + Bit32u hhIndex = (phaseBit<<8) | (0x34<<(phaseBit ^ noiseBit)); sample += op2->GetWave( hhIndex, hhVol ); } //Snare Drum Operator* op3 = ( this + 1 )->Op(1); Bit32u sdVol = op3->ForwardVolume(); if ( !ENV_SILENT( sdVol ) ) { - Bit32u sdBits = 0x100 + (c2 & 0x100); - Bit32u sdIndex = sdBits ^ ( noiseBit << 7 ); + Bit32u sdIndex = ( 0x100 + (c2 & 0x100) ) ^ ( noiseBit << 7 ); sample += op3->GetWave( sdIndex, sdVol ); } //Tom-tom @@ -1261,7 +1256,7 @@ void Chip::Setup( Bit32u rate ) { Bit32s original = (Bit32u)( (AttackSamplesTable[ index ] << shift) / scale); Bit32s guessAdd = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH - shift - 3 ))); - Bit32s bestAdd; + Bit32s bestAdd = guessAdd; Bit32u bestDiff = 1 << 30; for( Bit32u passes = 0; passes < 16; passes ++ ) { Bit32s volume = ENV_MAX; @@ -1368,7 +1363,7 @@ void InitTables( void ) { for ( int i = 0; i < 384; i++ ) { int s = i * 8; //TODO maybe keep some of the precision errors of the original table? - double val = ( 0.5 + ( pow(2, -1 + ( 255 - s) * ( 1.0 /256 ) )) * ( 1 << MUL_SH )); + double val = ( 0.5 + ( pow(2.0, -1.0 + ( 255 - s) * ( 1.0 /256 ) )) * ( 1 << MUL_SH )); MulTable[i] = (Bit16u)(val); } @@ -1379,7 +1374,7 @@ void InitTables( void ) { } //Exponential wave for ( int i = 0; i < 256; i++ ) { - WaveTable[ 0x700 + i ] = (Bit16s)( 0.5 + ( pow(2, -1 + ( 255 - i * 8) * ( 1.0 /256 ) ) ) * 4085 ); + WaveTable[ 0x700 + i ] = (Bit16s)( 0.5 + ( pow(2.0, -1.0 + ( 255 - i * 8) * ( 1.0 /256 ) ) ) * 4085 ); WaveTable[ 0x6ff - i ] = -WaveTable[ 0x700 + i ]; } #endif From a070990e1beb9de4b249b746cd0b6cdca3f6052d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 8 Jun 2009 17:20:02 +0000 Subject: [PATCH 3331/4131] in tandy mode remove unused buffer-paragraph reserved for UMB chain (ripsaw), fixes mech warrior tandy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3420 --- src/dos/dos_memory.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 30de8354..efe8a46c 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: dos_memory.cpp,v 1.44 2009-06-08 17:20:02 c2woody Exp $ */ + #include "dosbox.h" #include "mem.h" #include "dos_inc.h" @@ -45,7 +47,7 @@ static void DOS_CompressMemory(void) { void DOS_FreeProcessMemory(Bit16u pspseg) { Bit16u mcb_segment=dos.firstMCB; DOS_MCB mcb(mcb_segment); - while (true) { + for (;;) { if (mcb.GetPSPSeg()==pspseg) { mcb.SetPSPSeg(MCB_FREE); } @@ -64,7 +66,7 @@ void DOS_FreeProcessMemory(Bit16u pspseg) { Bit16u umb_start=dos_infoblock.GetStartOfUMBChain(); if (umb_start==UMB_START_SEG) { DOS_MCB umb_mcb(umb_start); - while (true) { + for (;;) { if (umb_mcb.GetPSPSeg()==pspseg) { umb_mcb.SetPSPSeg(MCB_FREE); } @@ -394,8 +396,8 @@ void DOS_SetupMemory(void) { * buggy games, which compare against the interrupt table. (probably a * broken linked list implementation) */ callbackhandler.Allocate(&DOS_default_handler,"DOS default int"); - Bitu ihseg = 0x70; - Bitu ihofs = 0x08; + Bit16u ihseg = 0x70; + Bit16u ihofs = 0x08; real_writeb(ihseg,ihofs+0x00,(Bit8u)0xFE); //GRP 4 real_writeb(ihseg,ihofs+0x01,(Bit8u)0x38); //Extra Callback instruction real_writew(ihseg,ihofs+0x02,callbackhandler.Get_callback()); //The immediate word @@ -434,12 +436,12 @@ void DOS_SetupMemory(void) { if (machine==MCH_TANDY) { /* memory up to 608k available, the rest (to 640k) is used by the tandy graphics system's variable mapping of 0xb800 */ - mcb.SetSize(0x97FE - DOS_MEM_START - mcb_sizes); + mcb.SetSize(0x97FF - DOS_MEM_START - mcb_sizes); } else if (machine==MCH_PCJR) { /* memory from 128k to 640k is available */ mcb_devicedummy.SetPt((Bit16u)0x2000); mcb_devicedummy.SetPSPSeg(MCB_FREE); - mcb_devicedummy.SetSize(0x9FFE - 0x2000); + mcb_devicedummy.SetSize(0x9FFF - 0x2000); mcb_devicedummy.SetType(0x5a); /* exclude PCJr graphics region */ @@ -453,6 +455,7 @@ void DOS_SetupMemory(void) { mcb.SetType(0x4d); } else { /* complete memory up to 640k available */ + /* last paragraph used to add UMB chain to low-memory MCB chain */ mcb.SetSize(0x9FFE - DOS_MEM_START - mcb_sizes); } From b58bbc5c36ecef9ecb4be5475b987ceb7dbd4059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 10 Jun 2009 17:44:59 +0000 Subject: [PATCH 3332/4131] doesn't like Bit8u (char) there Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3421 --- src/hardware/sblaster.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 7ffaa56e..7fdf8d48 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.75 2009-06-07 10:18:13 c2woody Exp $ */ +/* $Id: sblaster.cpp,v 1.76 2009-06-10 17:44:59 c2woody Exp $ */ #include #include @@ -1566,8 +1566,8 @@ public: // Create set blaster line ostringstream temp; temp << "SET BLASTER=A" << setw(3)<< hex << sb.hw.base - << " I" << dec << sb.hw.irq << " D"<< sb.hw.dma8; - if (sb.type==SBT_16) temp << " H" << sb.hw.dma16; + << " I" << dec << (Bitu)sb.hw.irq << " D" << (Bitu)sb.hw.dma8; + if (sb.type==SBT_16) temp << " H" << (Bitu)sb.hw.dma16; temp << " T" << static_cast(sb.type) << ends; autoexecline.Install(temp.str()); From c2eeb226ba89f399c69a61986238a686976df3ee Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 10 Jun 2009 19:54:51 +0000 Subject: [PATCH 3333/4131] Fix hi-hat and top cymbal Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3422 --- src/hardware/dbopl.cpp | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index 06500ead..0ff691f8 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -32,7 +32,7 @@ //DUNNO Keyon in 4op, switch to 2op without keyoff. */ -/* $Id: dbopl.cpp,v 1.9 2009-06-07 19:49:39 c2woody Exp $ */ +/* $Id: dbopl.cpp,v 1.10 2009-06-10 19:54:51 harekiet Exp $ */ #include @@ -805,39 +805,33 @@ INLINE void Channel::GeneratePercussion( Chip* chip, Bit32s* output ) { } Bit32s sample = Op(1)->GetSample( mod ); - Operator* op2 = ( this + 1 )->Op(0); - Operator* op4 = ( this + 2 )->Op(0); //Precalculate stuff used by other outputs - Bit32u noiseBit = (chip->ForwardNoise() & 0x1) << 1; - Bit32u c2 = op2->ForwardWave(); - Bit32u c4 = op4->ForwardWave(); - Bit32u phaseBit = (((c2 & 0x88) ^ ((c2<<5) & 0x80)) | ((c4 ^ (c4<<2)) & 0x20)) ? 0x02 : 0x00; + Bit32u noiseBit = chip->ForwardNoise() & 0x1; + Bit32u c2 = Op(2)->ForwardWave(); + Bit32u c5 = Op(5)->ForwardWave(); + Bit32u phaseBit = (((c2 & 0x88) ^ ((c2<<5) & 0x80)) | ((c5 ^ (c5<<2)) & 0x20)) ? 0x02 : 0x00; //Hi-Hat - Bit32u hhVol = op2->ForwardVolume(); + Bit32u hhVol = Op(2)->ForwardVolume(); if ( !ENV_SILENT( hhVol ) ) { - Bit32u hhIndex = (phaseBit<<8) | (0x34<<(phaseBit ^ noiseBit)); - sample += op2->GetWave( hhIndex, hhVol ); + Bit32u hhIndex = (phaseBit<<8) | (0x34 << ( phaseBit ^ (noiseBit << 1 ))); + sample += Op(2)->GetWave( hhIndex, hhVol ); } //Snare Drum - Operator* op3 = ( this + 1 )->Op(1); - Bit32u sdVol = op3->ForwardVolume(); + Bit32u sdVol = Op(3)->ForwardVolume(); if ( !ENV_SILENT( sdVol ) ) { - Bit32u sdIndex = ( 0x100 + (c2 & 0x100) ) ^ ( noiseBit << 7 ); - sample += op3->GetWave( sdIndex, sdVol ); + Bit32u sdIndex = ( 0x100 + (c2 & 0x100) ) ^ ( noiseBit << 8 ); + sample += Op(3)->GetWave( sdIndex, sdVol ); } //Tom-tom - Bit32u ttVol = op4->ForwardVolume(); - if ( !ENV_SILENT( ttVol ) ) { - sample += op4->GetWave( c4, ttVol ); - } + sample += Op(4)->GetSample( 0 ); + //Top-Cymbal - Operator* op5 = ( this + 2 )->Op(1); - Bit32u tcVol = op5->ForwardVolume(); + Bit32u tcVol = Op(5)->ForwardVolume(); if ( !ENV_SILENT( tcVol ) ) { Bit32u tcIndex = (1 + phaseBit) << 8; - sample += op5->GetWave( tcIndex, tcVol ); + sample += Op(5)->GetWave( tcIndex, tcVol ); } sample <<= 1; if ( opl3Mode ) { From 58ce4315f8dd6f00a14edfb764d6103d55982aea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 11 Jun 2009 16:05:17 +0000 Subject: [PATCH 3334/4131] move callback default segment to bios standard; use fixed default offset for irq0 as well (ripsaw, fixes tinker tales) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3423 --- include/bios.h | 6 ++++ include/callback.h | 31 +++++++++++------ src/cpu/callback.cpp | 71 ++++++++++++++++++++------------------ src/ints/bios.cpp | 17 +++++---- src/ints/bios_keyboard.cpp | 10 +++--- 5 files changed, 77 insertions(+), 58 deletions(-) diff --git a/include/bios.h b/include/bios.h index e3377040..87696b6a 100644 --- a/include/bios.h +++ b/include/bios.h @@ -101,6 +101,12 @@ #define BIOS_VIDEO_SAVEPTR 0x4a8 + +#define BIOS_DEFAULT_HANDLER_LOCATION (RealMake(0xf000,0xff53)) +#define BIOS_DEFAULT_IRQ0_LOCATION (RealMake(0xf000,0xfea5)) +#define BIOS_DEFAULT_IRQ1_LOCATION (RealMake(0xf000,0xe987)) +#define BIOS_DEFAULT_IRQ2_LOCATION (RealMake(0xf000,0xff55)) + /* maximum of scancodes handled by keyboard bios routines */ #define MAX_SCAN_CODE 0x58 diff --git a/include/callback.h b/include/callback.h index a14fd8ce..53bc39c0 100644 --- a/include/callback.h +++ b/include/callback.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.h,v 1.24 2009-05-27 09:15:40 qbix79 Exp $ */ +/* $Id: callback.h,v 1.25 2009-06-11 16:05:17 c2woody Exp $ */ #ifndef DOSBOX_CALLBACK_H #define DOSBOX_CALLBACK_H @@ -33,9 +33,10 @@ enum { CB_RETN,CB_RETF,CB_RETF8,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1, CB_INT29,CB_INT16,CB_HOOKABLE,CB_TDE_IRET,CB_IPXESR,CB_IPXESR_RET, CB_INT21 }; -#define CB_MAX 128 -#define CB_SIZE 32 -#define CB_SEG 0xF100 +#define CB_MAX 128 +#define CB_SIZE 32 +#define CB_SEG 0xF000 +#define CB_SOFFSET 0x1000 enum { CBRET_NONE=0,CBRET_STOP=1 @@ -44,14 +45,14 @@ enum { extern Bit8u lastint; static INLINE RealPt CALLBACK_RealPointer(Bitu callback) { - return RealMake(CB_SEG,(Bit16u)(callback*CB_SIZE)); + return RealMake(CB_SEG,(Bit16u)(CB_SOFFSET+callback*CB_SIZE)); } static INLINE PhysPt CALLBACK_PhysPointer(Bitu callback) { - return PhysMake(CB_SEG,(Bit16u)(callback*CB_SIZE)); + return PhysMake(CB_SEG,(Bit16u)(CB_SOFFSET+callback*CB_SIZE)); } static INLINE PhysPt CALLBACK_GetBase(void) { - return CB_SEG << 4; + return (CB_SEG << 4) + CB_SOFFSET; } Bitu CALLBACK_Allocate(); @@ -77,7 +78,7 @@ extern Bitu call_priv_io; class CALLBACK_HandlerObject{ private: bool installed; - Bit16u m_callback; + Bitu m_callback; enum {NONE,SETUP,SETUPAT} m_type; struct { RealPt old_vector; @@ -85,15 +86,23 @@ private: bool installed; } vectorhandler; public: - CALLBACK_HandlerObject():installed(false),m_type(NONE){vectorhandler.installed=false;} + 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);} + Bit16u Get_callback() { + return (Bit16u)m_callback; + } + RealPt Get_RealPointer() { + return CALLBACK_RealPointer(m_callback); + } void Set_RealVec(Bit8u vec); }; #endif diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index fd88711f..b5d88089 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: callback.cpp,v 1.41 2009-06-11 16:05:17 c2woody Exp $ */ #include #include @@ -26,7 +26,7 @@ #include "mem.h" #include "cpu.h" -/* CallBack are located at 0xF100:0 (see CB_SEG in callback.h) +/* CallBack are located at 0xF000:0x1000 (see CB_SEG and CB_SOFFSET in callback.h) And they are 16 bytes each and you can define them to behave in certain ways like a far return or and IRET */ @@ -87,8 +87,8 @@ static Bitu stop_handler(void) { void CALLBACK_RunRealFar(Bit16u seg,Bit16u off) { reg_sp-=4; - mem_writew(SegPhys(ss)+reg_sp,call_stop*CB_SIZE); - mem_writew(SegPhys(ss)+reg_sp+2,CB_SEG); + mem_writew(SegPhys(ss)+reg_sp,RealOff(CALLBACK_RealPointer(call_stop))); + mem_writew(SegPhys(ss)+reg_sp+2,RealSeg(CALLBACK_RealPointer(call_stop))); Bit32u oldeip=reg_eip; Bit16u oldcs=SegValue(cs); reg_eip=off; @@ -101,7 +101,7 @@ void CALLBACK_RunRealFar(Bit16u seg,Bit16u off) { void CALLBACK_RunRealInt(Bit8u intnum) { Bit32u oldeip=reg_eip; Bit16u oldcs=SegValue(cs); - reg_eip=(CB_MAX*CB_SIZE)+(intnum*6); + reg_eip=CB_SOFFSET+(CB_MAX*CB_SIZE)+(intnum*6); SegSet16(cs,CB_SEG); DOSBOX_RunMachine(); reg_eip=oldeip; @@ -141,7 +141,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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 + phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word physAddress+=4; } phys_writeb(physAddress+0x00,(Bit8u)0xC3); //A RETN Instruction @@ -150,7 +150,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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 + phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word physAddress+=4; } phys_writeb(physAddress+0x00,(Bit8u)0xCB); //A RETF Instruction @@ -159,7 +159,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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 + phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word physAddress+=4; } phys_writeb(physAddress+0x00,(Bit8u)0xCA); //A RETF 8 Instruction @@ -169,7 +169,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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 + phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word physAddress+=4; } phys_writeb(physAddress+0x00,(Bit8u)0xCF); //An IRET Instruction @@ -178,7 +178,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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 + phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word physAddress+=4; } phys_writeb(physAddress+0x00,(Bit8u)0x66); //An IRETD Instruction @@ -189,7 +189,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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 + phys_writew(physAddress+0x03,(Bit16u)callback); //The immediate word physAddress+=4; } phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction @@ -198,7 +198,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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 + phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word physAddress+=4; } phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax @@ -213,7 +213,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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 + phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word physAddress+=4; } phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax @@ -238,7 +238,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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 + phys_writew(physAddress+0x0c,(Bit16u)callback); //The immediate word // jump here to (skip): physAddress+=6; } @@ -252,7 +252,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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 + phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word physAddress+=4; } phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax @@ -272,13 +272,13 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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 + phys_writew(physAddress+0x08,(Bit16u)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 + phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word physAddress+=4; } phys_writeb(physAddress+0x00,(Bit8u)0xfa); // cli @@ -298,7 +298,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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 + phys_writew(physAddress+0x09,(Bit16u)callback); //The immediate word physAddress+=4; } else { phys_writew(physAddress+0x05,(Bit16u)0x0274); // je skip @@ -318,7 +318,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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 + phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word physAddress+=4; } phys_writeb(physAddress+0x00,(Bit8u)0xCF); //An IRET Instruction @@ -328,7 +328,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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 + phys_writew(physAddress+0x03,(Bit16u)callback); //The immediate word physAddress+=4; } phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction @@ -339,7 +339,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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 + phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word physAddress+=4; } phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax @@ -357,7 +357,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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 + phys_writew(physAddress+0x07,(Bit16u)callback); //The immediate word physAddress+=4; } phys_writeb(physAddress+0x05,(Bit8u)0xCB); //A RETF Instruction @@ -366,7 +366,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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 + phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word physAddress+=4; } phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax @@ -388,7 +388,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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_writew(physAddress+0x09,(Bit16u)callback); //The immediate word phys_writeb(physAddress+0x0b,(Bit8u)0xCB); //A RETF Instruction return 0x0c; case CB_IPXESR_RET: // IPX ESR return @@ -409,7 +409,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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 + phys_writew(physAddress+0x03,(Bit16u)callback); //The immediate word physAddress+=4; } phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction @@ -502,7 +502,7 @@ void CALLBACK_HandlerObject::Set_RealVec(Bit8u vec){ } else E_Exit ("double usage of vector handler"); } -void CALLBACK_Init(Section* sec) { +void CALLBACK_Init(Section* /*sec*/) { Bitu i; for (i=0;i IRET */ phys_writew(Real2Phys(RealGetVec(0x12))+0x12,0x20); //Hack for Jurresic if (machine==MCH_TANDY) phys_writeb(0xffffe,0xff) ; /* Tandy model */ diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 49cda3a1..e26c11a2 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: bios_keyboard.cpp,v 1.36 2009-06-11 16:05:17 c2woody Exp $ */ + #include "dosbox.h" #include "callback.h" #include "mem.h" @@ -382,7 +384,7 @@ static Bitu IRQ1_Handler(void) { } if(flags1 &0x08) { Bit8u token = mem_readb(BIOS_KEYBOARD_TOKEN); - token= token*10 + scan_to_scanascii[scancode].alt; + token = token*10 + (Bit8u)(scan_to_scanascii[scancode].alt&0xff); mem_writeb(BIOS_KEYBOARD_TOKEN,token); } else if (flags1 &0x04) { add_key(scan_to_scanascii[scancode].control); @@ -601,12 +603,12 @@ void BIOS_SetupKeyboard(void) { /* Allocate/setup a callback for int 0x16 and for standard IRQ 1 handler */ call_int16=CALLBACK_Allocate(); - CALLBACK_Setup(call_int16,&INT16_Handler,CB_INT16,"keyboard"); + CALLBACK_Setup(call_int16,&INT16_Handler,CB_INT16,"Keyboard"); RealSetVec(0x16,CALLBACK_RealPointer(call_int16)); call_irq1=CALLBACK_Allocate(); - CALLBACK_Setup(call_irq1,&IRQ1_Handler,CB_IRQ1,"keyboard irq"); - RealSetVec(0x9,CALLBACK_RealPointer(call_irq1)); + CALLBACK_Setup(call_irq1,&IRQ1_Handler,CB_IRQ1,Real2Phys(BIOS_DEFAULT_IRQ1_LOCATION),"IRQ 1 Keyboard"); + RealSetVec(0x09,BIOS_DEFAULT_IRQ1_LOCATION); // pseudocode for CB_IRQ1: // push ax // in al, 0x60 From c0054fe94c56370050aa9405a48693637f1c4c7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 12 Jun 2009 20:10:09 +0000 Subject: [PATCH 3335/4131] lower stack pointer when booting to avoid overwriting loader code (ripsaw, fixes last mission booter) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3424 --- src/dos/dos_programs.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 150b70f7..3a3b8be6 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.93 2009-04-16 12:28:30 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.94 2009-06-12 20:10:09 c2woody Exp $ */ #include "dosbox.h" #include @@ -238,7 +238,7 @@ public: if (type=="cdrom") { int num = -1; cmd->FindInt("-usecd",num,true); - int error; + int error = 0; if (cmd->FindExist("-aspi",false)) { MSCDEX_SetCDInterface(CDROM_USE_ASPI, num); } else if (cmd->FindExist("-ioctl_dio",false)) { @@ -758,7 +758,7 @@ public: SegSet16(es, 0); /* set up stack at a safe place */ SegSet16(ss, 0x7000); - reg_esp = 0x400; + reg_esp = 0x100; reg_esi = 0; reg_ecx = 1; reg_ebp = 0; From 416a9abf4d3fc717448161841fd0f056d13f66d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 13 Jun 2009 10:43:00 +0000 Subject: [PATCH 3336/4131] fix reading from files opened in write-only mode (should fail) and associated error handling; fixes champions of zulula Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3425 --- src/dos/drive_local.cpp | 48 +++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index bd171413..123f7d80 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.79 2009-04-26 18:24:36 qbix79 Exp $ */ +/* $Id: drive_local.cpp,v 1.80 2009-06-13 10:43:00 c2woody Exp $ */ #include #include @@ -48,7 +48,7 @@ private: }; -bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) { +bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u /*attributes*/) { //TODO Maybe care for attributes but not likely char newname[CROSS_LEN]; strcpy(newname,basedir); @@ -80,16 +80,14 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) { bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { const char* type; - switch (flags &3) { + switch (flags&0xf) { case OPEN_READ:type="rb"; break; - case OPEN_WRITE:type="rb+"; break; + case OPEN_WRITE:type="wb"; break; case OPEN_READWRITE:type="rb+"; break; default: -//TODO FIX IT - type="rb+"; -// return false; - - }; + DOS_SetError(DOSERR_ACCESS_CODE_INVALID); + return false; + } char newname[CROSS_LEN]; strcpy(newname,basedir); strcat(newname,name); @@ -99,7 +97,7 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { FILE * hand=fopen(newname,type); // Bit32u err=errno; if (!hand) { - if((flags&3) != OPEN_READ) { + if((flags&0xf) != OPEN_READ) { FILE * hmm=fopen(newname,"rb"); if (hmm) { fclose(hmm); @@ -136,7 +134,6 @@ bool localDrive::GetSystemFilename(char *sysName, char const * const dosName) { } bool localDrive::FileUnlink(char * name) { - char newname[CROSS_LEN]; strcpy(newname,basedir); strcat(newname,name); @@ -175,11 +172,9 @@ bool localDrive::FileUnlink(char * name) { dirCache.DeleteEntry(newname); return true; } - return false; } bool localDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) { - char tempDir[CROSS_LEN]; strcpy(tempDir,basedir); strcat(tempDir,_dir); @@ -193,8 +188,7 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) { if (tempDir[strlen(tempDir)-1]!=CROSS_FILESPLIT) strcat(tempDir,end); Bitu id; - if (!dirCache.FindFirst(tempDir,id)) - { + if (!dirCache.FindFirst(tempDir,id)) { DOS_SetError(DOSERR_PATH_NOT_FOUND); return false; } @@ -441,6 +435,10 @@ localDrive::localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors //TODO Maybe use fflush, but that seemed to fuck up in visual c bool localFile::Read(Bit8u * data,Bit16u * size) { + if ((this->flags & 0xf) == OPEN_WRITE) { // check if file opened in write-only mode + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; + } if (last_action==WRITE) fseek(fhandle,ftell(fhandle),SEEK_SET); last_action=READ; *size=(Bit16u)fread(data,1,*size,fhandle); @@ -453,6 +451,10 @@ bool localFile::Read(Bit8u * data,Bit16u * size) { } bool localFile::Write(Bit8u * data,Bit16u * size) { + if ((this->flags & 0xf) == OPEN_READ) { // check if file opened in read-only mode + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; + } if (last_action==READ) fseek(fhandle,ftell(fhandle),SEEK_SET); last_action=WRITE; if(*size==0){ @@ -569,9 +571,9 @@ cdromDrive::cdromDrive(const char driveLetter, const char * startdir,Bit16u _byt } bool cdromDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { - if ((flags&3)==OPEN_READWRITE) { + if ((flags&0xf)==OPEN_READWRITE) { flags &= ~OPEN_READWRITE; - } else if ((flags&3)==OPEN_WRITE) { + } else if ((flags&0xf)==OPEN_WRITE) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } @@ -580,27 +582,27 @@ bool cdromDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { return retcode; } -bool cdromDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) { +bool cdromDrive::FileCreate(DOS_File * * /*file*/,char * /*name*/,Bit16u /*attributes*/) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } -bool cdromDrive::FileUnlink(char * name) { +bool cdromDrive::FileUnlink(char * /*name*/) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } -bool cdromDrive::RemoveDir(char * dir) { +bool cdromDrive::RemoveDir(char * /*dir*/) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } -bool cdromDrive::MakeDir(char * dir) { +bool cdromDrive::MakeDir(char * /*dir*/) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } -bool cdromDrive::Rename(char * oldname,char * newname) { +bool cdromDrive::Rename(char * /*oldname*/,char * /*newname*/) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } @@ -611,7 +613,7 @@ bool cdromDrive::GetFileAttr(char * name,Bit16u * attr) { return result; } -bool cdromDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) { +bool cdromDrive::FindFirst(char * _dir,DOS_DTA & dta,bool /*fcb_findfirst*/) { // If media has changed, reInit drivecache. if (MSCDEX_HasMediaChanged(subUnit)) { dirCache.EmptyCache(); From 613816e5a42da7cfd5f7bc9c224743acbcfefdfc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 16 Jun 2009 18:19:18 +0000 Subject: [PATCH 3337/4131] Turn rtc always running trick on. fixes Loadstar: The Legend of Tully Bodine. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3426 --- src/hardware/cmos.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index c26e1f51..26a0e79f 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -16,9 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cmos.cpp,v 1.28 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: cmos.cpp,v 1.29 2009-06-16 18:19:18 qbix79 Exp $ */ #include +#include #include "dosbox.h" #include "timer.h" @@ -27,6 +28,7 @@ #include "mem.h" #include "bios_disk.h" #include "setup.h" +#include "cross.h" //fmod on certain platforms static struct { Bit8u regs[0x40]; @@ -64,8 +66,9 @@ static void cmos_checktimer(void) { cmos.timer.delay=(1000.0f/(32768.0f / (1 << (cmos.timer.div - 1)))); if (!cmos.timer.div || !cmos.timer.enabled) return; LOG(LOG_PIT,LOG_NORMAL)("RTC Timer at %.2f hz",1000.0/cmos.timer.delay); - PIC_AddEvent(cmos_timerevent,cmos.timer.delay); -// PIC_AddEvent(cmos_timerevent,(double)cmos.timer.delay-fmod(PIC_FullIndex(),(double)cmos.timer.delay)); //Should be more like a real pc. Check +// PIC_AddEvent(cmos_timerevent,cmos.timer.delay); + /* A rtc is always running */ + PIC_AddEvent(cmos_timerevent,(double)cmos.timer.delay-fmod(PIC_FullIndex(),(double)cmos.timer.delay)); //Should be more like a real pc. Check // status reg A reading with this (and with other delays actually) } From 6de523ff7b82413d7fb39e9c026a96c9ffab15f0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 16 Jun 2009 19:00:26 +0000 Subject: [PATCH 3338/4131] Add 0x31. Should improve Waterworld. Thanks ripsaw Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3427 --- src/ints/mouse.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index e54384bb..06357726 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.79 2009-04-16 12:11:45 qbix79 Exp $ */ +/* $Id: mouse.cpp,v 1.80 2009-06-16 19:00:26 qbix79 Exp $ */ #include #include @@ -898,6 +898,12 @@ static Bitu INT33_Handler(void) { reg_cx=(Bit16u)mouse.max_x; reg_dx=(Bit16u)mouse.max_y; break; + case 0x31: /* Get Current Minimum/Maximum virtual coordinates */ + reg_ax=(Bit16u)mouse.min_x; + reg_bx=(Bit16u)mouse.min_y; + reg_cx=(Bit16u)mouse.max_x; + reg_dx=(Bit16u)mouse.max_y; + break; default: LOG(LOG_MOUSE,LOG_ERROR)("Mouse Function %04X not implemented!",reg_ax); break; From 4a44f76516775925def5aee8032ba3457e189b82 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 17 Jun 2009 08:52:35 +0000 Subject: [PATCH 3339/4131] Change language handling a bit so that seperater includes the new line. Results in slightly larger language file, but it is the easiest way to fix the configuration language stuff. (inspired by bug 2799277 of hiro) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3428 --- src/misc/messages.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 221bbd98..b2ce3d9c 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: messages.cpp,v 1.22 2009-05-27 09:15:42 qbix79 Exp $ */ +/* $Id: messages.cpp,v 1.23 2009-06-17 08:52:35 qbix79 Exp $ */ #include #include @@ -99,8 +99,11 @@ static void LoadMessageFile(const char * fname) { strcpy(name,linein+1); /* End of string marker */ } else if (linein[0]=='.') { - /* Replace/Add the string to the internal langaugefile */ - MSG_Replace(name,string); + /* Replace/Add the string to the internal langaugefile */ + /* Remove last newline (marker is \n.\n) */ + size_t ll = strlen(string); + if(ll && string[ll - 1] == '\n') string[ll - 1] = 0; //Second if should not be needed, but better be safe. + MSG_Replace(name,string); } else { /* Normal string to be added */ strcat(string,linein); @@ -125,7 +128,7 @@ void MSG_Write(const char * location) { FILE* out=fopen(location,"w+t"); if(out==NULL) return;//maybe an error? for(itmb tel=Lang.begin();tel!=Lang.end();tel++){ - fprintf(out,":%s\n%s.\n",(*tel).name.c_str(),(*tel).val.c_str()); + fprintf(out,":%s\n%s\n.\n",(*tel).name.c_str(),(*tel).val.c_str()); } fclose(out); } From 08a74bd8e99b6e52ae3299f7dac4691125361e48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 18 Jun 2009 18:17:54 +0000 Subject: [PATCH 3340/4131] set sensible value for flags when creating a file (avoid false error message) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3429 --- src/dos/dos_files.cpp | 16 +++++++++------- src/dos/drive_local.cpp | 28 +++++++++++----------------- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 425ca921..3a7b5039 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.110 2009-04-26 19:13:32 harekiet Exp $ */ +/* $Id: dos_files.cpp,v 1.111 2009-06-18 18:17:54 c2woody Exp $ */ #include #include @@ -356,9 +356,8 @@ bool DOS_ReadFile(Bit16u entry,Bit8u * data,Bit16u * amount) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; -//TODO maybe another code :) /* - if (!(Files[handle]->flags & OPEN_READ)) { + if ((Files[handle]->flags & 0x0f) == OPEN_WRITE)) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; } @@ -379,9 +378,8 @@ bool DOS_WriteFile(Bit16u entry,Bit8u * data,Bit16u * amount) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; -//TODO maybe another code :) /* - if (!(Files[handle]->flags & OPEN_WRITE)) { + if ((Files[handle]->flags & 0x0f) == OPEN_READ)) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; } @@ -1059,7 +1057,9 @@ Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { */ DOS_FCB fcb(seg,offset); - Bit32u random;Bit16u old_block;Bit8u old_rec; + Bit32u random; + Bit16u old_block=0; + Bit8u old_rec=0; Bit8u error=0; /* Set the correct record from the random data */ @@ -1082,7 +1082,9 @@ Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { Bit8u DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { /* see FCB_RandomRead */ DOS_FCB fcb(seg,offset); - Bit32u random;Bit16u old_block;Bit8u old_rec; + Bit32u random; + Bit16u old_block=0; + Bit8u old_rec=0; Bit8u error=0; /* Set the correct record from the random data */ diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 123f7d80..99bd96a3 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.80 2009-06-13 10:43:00 c2woody Exp $ */ +/* $Id: drive_local.cpp,v 1.81 2009-06-18 18:17:54 c2woody Exp $ */ #include #include @@ -74,6 +74,7 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u /*attributes*/) if(!existing_file) dirCache.AddEntry(newname, true); /* Make the 16 bit device information */ *file=new localFile(name,hand); + (*file)->flags=OPEN_READWRITE; return true; } @@ -273,8 +274,8 @@ again: find_size=(Bit32u) stat_block.st_size; struct tm *time; if((time=localtime(&stat_block.st_mtime))!=0){ - find_date=DOS_PackDate(time->tm_year+1900,time->tm_mon+1,time->tm_mday); - find_time=DOS_PackTime(time->tm_hour,time->tm_min,time->tm_sec); + find_date=DOS_PackDate((Bit16u)(time->tm_year+1900),(Bit16u)(time->tm_mon+1),(Bit16u)time->tm_mday); + find_time=DOS_PackTime((Bit16u)time->tm_hour,(Bit16u)time->tm_min,(Bit16u)time->tm_sec); } else { find_time=6; find_date=4; @@ -393,8 +394,8 @@ bool localDrive::FileStat(const char* name, FileStat_Block * const stat_block) { /* Convert the stat to a FileStat */ struct tm *time; if((time=localtime(&temp_stat.st_mtime))!=0) { - stat_block->time=DOS_PackTime(time->tm_hour,time->tm_min,time->tm_sec); - stat_block->date=DOS_PackDate(time->tm_year+1900,time->tm_mon+1,time->tm_mday); + stat_block->time=DOS_PackTime((Bit16u)time->tm_hour,(Bit16u)time->tm_min,(Bit16u)time->tm_sec); + stat_block->date=DOS_PackDate((Bit16u)(time->tm_year+1900),(Bit16u)(time->tm_mon+1),(Bit16u)time->tm_mday); } else { } @@ -511,20 +512,13 @@ Bit16u localFile::GetInformation(void) { localFile::localFile(const char* _name, FILE * handle) { fhandle=handle; - struct stat temp_stat; - fstat(fileno(handle),&temp_stat); - struct tm * ltime; - if((ltime=localtime(&temp_stat.st_mtime))!=0) { - time=DOS_PackTime(ltime->tm_hour,ltime->tm_min,ltime->tm_sec); - date=DOS_PackDate(ltime->tm_year+1900,ltime->tm_mon+1,ltime->tm_mday); - } else { - time=1;date=1; - } + open=true; + UpdateDateTimeFromHost(); + attr=DOS_ATTR_ARCHIVE; last_action=NONE; read_only_medium=false; - open=true; name=0; SetName(_name); } @@ -539,8 +533,8 @@ bool localFile::UpdateDateTimeFromHost(void) { fstat(fileno(fhandle),&temp_stat); struct tm * ltime; if((ltime=localtime(&temp_stat.st_mtime))!=0) { - time=DOS_PackTime(ltime->tm_hour,ltime->tm_min,ltime->tm_sec); - date=DOS_PackDate(ltime->tm_year+1900,ltime->tm_mon+1,ltime->tm_mday); + time=DOS_PackTime((Bit16u)ltime->tm_hour,(Bit16u)ltime->tm_min,(Bit16u)ltime->tm_sec); + date=DOS_PackDate((Bit16u)(ltime->tm_year+1900),(Bit16u)(ltime->tm_mon+1),(Bit16u)ltime->tm_mday); } else { time=1;date=1; } From a4d747c681a0fbbf88f8a9374dbeebdcc2b3aa87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 19 Jun 2009 18:28:10 +0000 Subject: [PATCH 3341/4131] respect the open mode for fat/iso drives as well (file read/write error handling) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3430 --- src/dos/drive_fat.cpp | 17 ++++++-- src/dos/drive_iso.cpp | 97 +++++++++++++++---------------------------- 2 files changed, 47 insertions(+), 67 deletions(-) diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index f1d01cd9..76cf9736 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.27 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: drive_fat.cpp,v 1.28 2009-06-19 18:28:10 c2woody Exp $ */ #include #include @@ -105,6 +105,10 @@ fatFile::fatFile(const char* /*name*/, Bit32u startCluster, Bit32u fileLen, fatD } bool fatFile::Read(Bit8u * data, Bit16u *size) { + if ((this->flags & 0xf) == OPEN_WRITE) { // check if file opened in write-only mode + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; + } Bit16u sizedec, sizecount; if(seekpos >= filelength) { *size = 0; @@ -156,6 +160,11 @@ bool fatFile::Read(Bit8u * data, Bit16u *size) { bool fatFile::Write(Bit8u * data, Bit16u *size) { /* TODO: Check for read-only bit */ + if ((this->flags & 0xf) == OPEN_READ) { // check if file opened in read-only mode + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; + } + direntry tmpentry; Bit16u sizedec, sizecount; sizedec = *size; @@ -767,7 +776,7 @@ bool fatDrive::FileCreate(DOS_File **file, char *name, Bit16u attributes) { char dirName[DOS_NAMELENGTH_ASCII]; char pathName[11]; - Bitu save_errorcode=dos.errorcode; + Bit16u save_errorcode=dos.errorcode; /* Check if file already exists */ if(getFileDirEntry(name, &fileEntry, &dirClust, &subEntry)) { @@ -793,6 +802,7 @@ bool fatDrive::FileCreate(DOS_File **file, char *name, Bit16u attributes) { /* Empty file created, now lets open it */ /* TODO: check for read-only flag and requested write access */ *file = new fatFile(name, fileEntry.loFirstClust, fileEntry.entrysize, this); + (*file)->flags=OPEN_READWRITE; ((fatFile *)(*file))->dirCluster = dirClust; ((fatFile *)(*file))->dirIndex = subEntry; /* Maybe modTime and date should be used ? (crt matches findnext) */ @@ -810,12 +820,13 @@ bool fatDrive::FileExists(const char *name) { return true; } -bool fatDrive::FileOpen(DOS_File **file, char *name, Bit32u /*flags*/) { +bool fatDrive::FileOpen(DOS_File **file, char *name, Bit32u flags) { direntry fileEntry; Bit32u dirClust, subEntry; if(!getFileDirEntry(name, &fileEntry, &dirClust, &subEntry)) return false; /* TODO: check for read-only flag and requested write access */ *file = new fatFile(name, fileEntry.loFirstClust, fileEntry.entrysize, this); + (*file)->flags = flags; ((fatFile *)(*file))->dirCluster = dirClust; ((fatFile *)(*file))->dirIndex = subEntry; /* Maybe modTime and date should be used ? (crt matches findnext) */ diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index f3f9c150..c3451001 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.25 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.26 2009-06-19 18:28:10 c2woody Exp $ */ #include #include @@ -46,8 +46,7 @@ private: Bit16u info; }; -isoFile::isoFile(isoDrive *drive, const char *name, FileStat_Block *stat, Bit32u offset) -{ +isoFile::isoFile(isoDrive *drive, const char *name, FileStat_Block *stat, Bit32u offset) { this->drive = drive; time = stat->time; date = stat->date; @@ -61,8 +60,7 @@ isoFile::isoFile(isoDrive *drive, const char *name, FileStat_Block *stat, Bit32u SetName(name); } -bool isoFile::Read(Bit8u *data, Bit16u *size) -{ +bool isoFile::Read(Bit8u *data, Bit16u *size) { if (filePos + *size > fileEnd) *size = (Bit16u)(fileEnd - filePos); @@ -99,13 +97,11 @@ bool isoFile::Read(Bit8u *data, Bit16u *size) return true; } -bool isoFile::Write(Bit8u *data, Bit16u *size) -{ +bool isoFile::Write(Bit8u* /*data*/, Bit16u* /*size*/) { return false; } -bool isoFile::Seek(Bit32u *pos, Bit32u type) -{ +bool isoFile::Seek(Bit32u *pos, Bit32u type) { switch (type) { case DOS_SEEK_SET: filePos = fileBegin + *pos; @@ -126,14 +122,12 @@ bool isoFile::Seek(Bit32u *pos, Bit32u type) return true; } -bool isoFile::Close() -{ +bool isoFile::Close() { if (refCtr == 1) open = false; return true; } -Bit16u isoFile::GetInformation(void) -{ +Bit16u isoFile::GetInformation(void) { return 0x40; // read-only drive } @@ -143,8 +137,7 @@ void MSCDEX_ReplaceDrive(CDROM_Interface* cdrom, Bit8u subUnit); bool MSCDEX_HasDrive(char driveLetter); bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name); -isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &error) -{ +isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &error) { nextFreeDirIterator = 0; memset(dirIterators, 0, sizeof(dirIterators)); memset(sectorHashEntries, 0, sizeof(sectorHashEntries)); @@ -199,9 +192,8 @@ void isoDrive::Activate(void) { UpdateMscdex(driveLetter, fileName, subUnit); } -bool isoDrive::FileOpen(DOS_File **file, char *name, Bit32u flags) -{ - if (flags == OPEN_WRITE) { +bool isoDrive::FileOpen(DOS_File **file, char *name, Bit32u flags) { + if ((flags & 0x0f) == OPEN_WRITE) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } @@ -221,38 +213,32 @@ bool isoDrive::FileOpen(DOS_File **file, char *name, Bit32u flags) return success; } -bool isoDrive::FileCreate(DOS_File **file, char *name, Bit16u attributes) -{ +bool isoDrive::FileCreate(DOS_File** /*file*/, char* /*name*/, Bit16u /*attributes*/) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } -bool isoDrive::FileUnlink(char *name) -{ +bool isoDrive::FileUnlink(char* /*name*/) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } -bool isoDrive::RemoveDir(char *dir) -{ +bool isoDrive::RemoveDir(char* /*dir*/) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } -bool isoDrive::MakeDir(char *dir) -{ +bool isoDrive::MakeDir(char* /*dir*/) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } -bool isoDrive::TestDir(char *dir) -{ +bool isoDrive::TestDir(char *dir) { isoDirEntry de; return (lookup(&de, dir) && IS_DIR(de.fileFlags)); } -bool isoDrive::FindFirst(char *dir, DOS_DTA &dta, bool fcb_findfirst) -{ +bool isoDrive::FindFirst(char *dir, DOS_DTA &dta, bool fcb_findfirst) { isoDirEntry de; if (!lookup(&de, dir)) { DOS_SetError(DOSERR_PATH_NOT_FOUND); @@ -285,8 +271,7 @@ bool isoDrive::FindFirst(char *dir, DOS_DTA &dta, bool fcb_findfirst) return FindNext(dta); } -bool isoDrive::FindNext(DOS_DTA &dta) -{ +bool isoDrive::FindNext(DOS_DTA &dta) { Bit8u attr; char pattern[DOS_NAMELENGTH_ASCII]; dta.GetSearchParams(attr, pattern); @@ -324,14 +309,12 @@ bool isoDrive::FindNext(DOS_DTA &dta) return false; } -bool isoDrive::Rename(char *oldname, char *newname) -{ +bool isoDrive::Rename(char* /*oldname*/, char* /*newname*/) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } -bool isoDrive::GetFileAttr(char *name, Bit16u *attr) -{ +bool isoDrive::GetFileAttr(char *name, Bit16u *attr) { *attr = 0; isoDirEntry de; bool success = lookup(&de, name); @@ -343,8 +326,7 @@ bool isoDrive::GetFileAttr(char *name, Bit16u *attr) return success; } -bool isoDrive::AllocationInfo(Bit16u *bytes_sector, Bit8u *sectors_cluster, Bit16u *total_clusters, Bit16u *free_clusters) -{ +bool isoDrive::AllocationInfo(Bit16u *bytes_sector, Bit8u *sectors_cluster, Bit16u *total_clusters, Bit16u *free_clusters) { *bytes_sector = 2048; *sectors_cluster = 1; // cluster size for cdroms ? *total_clusters = 60000; @@ -352,14 +334,12 @@ bool isoDrive::AllocationInfo(Bit16u *bytes_sector, Bit8u *sectors_cluster, Bit1 return true; } -bool isoDrive::FileExists(const char *name) -{ +bool isoDrive::FileExists(const char *name) { isoDirEntry de; return (lookup(&de, name) && !IS_DIR(de.fileFlags)); } -bool isoDrive::FileStat(const char *name, FileStat_Block *const stat_block) -{ +bool isoDrive::FileStat(const char *name, FileStat_Block *const stat_block) { isoDirEntry de; bool success = lookup(&de, name); @@ -374,18 +354,15 @@ bool isoDrive::FileStat(const char *name, FileStat_Block *const stat_block) return success; } -Bit8u isoDrive::GetMediaByte(void) -{ +Bit8u isoDrive::GetMediaByte(void) { return mediaid; } -bool isoDrive::isRemote(void) -{ +bool isoDrive::isRemote(void) { return true; } -bool isoDrive::isRemovable(void) -{ +bool isoDrive::isRemovable(void) { return true; } @@ -397,8 +374,7 @@ Bits isoDrive::UnMount(void) { return 2; } -int isoDrive::GetDirIterator(const isoDirEntry* de) -{ +int isoDrive::GetDirIterator(const isoDirEntry* de) { int dirIterator = nextFreeDirIterator; // get start and end sector of the directory entry (pad end sector if necessary) @@ -418,8 +394,7 @@ int isoDrive::GetDirIterator(const isoDirEntry* de) return dirIterator; } -bool isoDrive::GetNextDirEntry(const int dirIteratorHandle, isoDirEntry* de) -{ +bool isoDrive::GetNextDirEntry(const int dirIteratorHandle, isoDirEntry* de) { bool result = false; Bit8u* buffer = NULL; DirIterator& dirIterator = dirIterators[dirIteratorHandle]; @@ -450,8 +425,7 @@ bool isoDrive::GetNextDirEntry(const int dirIteratorHandle, isoDirEntry* de) return result; } -void isoDrive::FreeDirIterator(const int dirIterator) -{ +void isoDrive::FreeDirIterator(const int dirIterator) { dirIterators[dirIterator].valid = false; // if this was the last aquired iterator decrement nextFreeIterator @@ -460,8 +434,7 @@ void isoDrive::FreeDirIterator(const int dirIterator) } } -bool isoDrive::ReadCachedSector(Bit8u** buffer, const Bit32u sector) -{ +bool isoDrive::ReadCachedSector(Bit8u** buffer, const Bit32u sector) { // get hash table entry int pos = sector % ISO_MAX_HASH_TABLE_SIZE; SectorHashEntry& he = sectorHashEntries[pos]; @@ -479,13 +452,11 @@ bool isoDrive::ReadCachedSector(Bit8u** buffer, const Bit32u sector) return true; } -inline bool isoDrive :: readSector(Bit8u *buffer, Bit32u sector) -{ +inline bool isoDrive :: readSector(Bit8u *buffer, Bit32u sector) { return CDROM_Interface_Image::images[subUnit]->ReadSector(buffer, false, sector); } -int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) -{ +int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) { // copy data into isoDirEntry struct, data[0] = length of DirEntry // if (data[0] > sizeof(isoDirEntry)) return -1;//check disabled as isoDirentry is currently 258 bytes large. So it always fits memcpy(de, data, data[0]);//Perharps care about a zero at the end. @@ -525,8 +496,7 @@ int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) return de->length; } -bool isoDrive :: loadImage() -{ +bool isoDrive :: loadImage() { isoPVD pvd; dataCD = false; readSector((Bit8u*)(&pvd), ISO_FIRST_VD); @@ -538,8 +508,7 @@ bool isoDrive :: loadImage() return false; } -bool isoDrive :: lookup(isoDirEntry *de, const char *path) -{ +bool isoDrive :: lookup(isoDirEntry *de, const char *path) { if (!dataCD) return false; *de = this->rootEntry; if (!strcmp(path, "")) return true; From 704221c89d47011878ea102ada955c70a812bd7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 23 Jun 2009 17:46:05 +0000 Subject: [PATCH 3342/4131] add lowlevel tandy dac implementation Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3431 --- include/hardware.h | 3 +- src/hardware/tandy_sound.cpp | 269 ++++++++++++++++++++++++++++++----- src/ints/bios.cpp | 167 +++++++++++++++++----- 3 files changed, 370 insertions(+), 69 deletions(-) diff --git a/include/hardware.h b/include/hardware.h index 8823aac9..4a440855 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: hardware.h,v 1.16 2009-06-07 10:18:13 c2woody Exp $ */ +/* $Id: hardware.h,v 1.17 2009-06-23 17:46:05 c2woody Exp $ */ #ifndef DOSBOX_HARDWARE_H #define DOSBOX_HARDWARE_H @@ -41,6 +41,7 @@ void OPL_ShutDown(Section* sec); void CMS_ShutDown(Section* sec); bool SB_Get_Address(Bitu& sbaddr, Bitu& sbirq, Bitu& sbdma); +bool TS_Get_Address(Bitu& tsaddr, Bitu& tsirq, Bitu& tsdma); extern Bit8u adlib_commandreg; FILE * OpenCaptureFile(const char * type,const char * ext); diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 9adde3a7..120ed13e 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -27,10 +27,10 @@ #include "setup.h" #include "pic.h" #include "dma.h" +#include "hardware.h" #include #include -#define DAC_CLOCK 3570000 #define MAX_OUTPUT 0x7fff #define STEP 0x10000 @@ -56,8 +56,7 @@ Hope that helps the System E stuff, more news on the PSG as and when! #define NG_PRESET 0x0f35 -struct SN76496 -{ +struct SN76496 { int SampleRate; unsigned int UpdateStep; int VolTable[16]; /* volume table */ @@ -72,18 +71,36 @@ struct SN76496 }; static struct SN76496 sn; + +#define TDAC_DMA_BUFSIZE 1024 + static struct { MixerChannel * chan; bool enabled; Bitu last_write; struct { - bool playing; - Bitu rate; + MixerChannel * chan; + bool enabled; + struct { + Bitu base; + Bit8u irq,dma; + } hw; + struct { + Bitu rate; + Bit8u buf[TDAC_DMA_BUFSIZE]; + Bit8u last_sample; + DmaChannel * chan; + bool transfer_done; + } dma; + Bit8u mode,control; + Bit16u frequency; + Bit8u amplitude; + bool irq_activated; } dac; } tandy; -static void SN76496Write(Bitu port,Bitu data,Bitu iolen) { +static void SN76496Write(Bitu /*port*/,Bitu data,Bitu /*iolen*/) { struct SN76496 *R = &sn; tandy.last_write=PIC_Ticks; @@ -160,8 +177,7 @@ static void SN76496Write(Bitu port,Bitu data,Bitu iolen) { } } -static void SN76496Update(Bitu length) -{ +static void SN76496Update(Bitu length) { if ((tandy.last_write+5000)Enable(false); @@ -250,7 +266,7 @@ static void SN76496Update(Bitu length) if (out > MAX_OUTPUT * STEP) out = MAX_OUTPUT * STEP; - *(buffer++) = out / STEP; + *(buffer++) = (Bit16s)(out / STEP); count--; } @@ -259,11 +275,9 @@ static void SN76496Update(Bitu length) -static void SN76496_set_clock(int clock) -{ +static void SN76496_set_clock(int clock) { struct SN76496 *R = &sn; - /* the base clock for the tone generators is the chip clock divided by 16; */ /* for the noise generator, it is clock / 256. */ /* Here we calculate the number of steps which happen during one sample */ @@ -274,20 +288,11 @@ static void SN76496_set_clock(int clock) } -static void TandyDACWrite(Bitu port,Bitu data,Bitu iolen) { - LOG_MSG("Write tandy dac %X val %X",port,data); - - -} - - -static void SN76496_set_gain(int gain) -{ +static void SN76496_set_gain(int gain) { struct SN76496 *R = &sn; int i; double out; - gain &= 0xff; /* increase max output basing on gain (0.2 dB per step) */ @@ -308,14 +313,185 @@ static void SN76496_set_gain(int gain) } + +bool TS_Get_Address(Bitu& tsaddr, Bitu& tsirq, Bitu& tsdma) { + tsaddr=0; + tsirq =0; + tsdma =0; + if (tandy.dac.enabled) { + tsaddr=tandy.dac.hw.base; + tsirq =tandy.dac.hw.irq; + tsdma =tandy.dac.hw.dma; + return true; + } + return false; +} + + +static void TandyDAC_DMA_CallBack(DmaChannel * /*chan*/, DMAEvent event) { + if (event == DMA_REACHED_TC) { + tandy.dac.dma.transfer_done=true; + PIC_ActivateIRQ(tandy.dac.hw.irq); + } +} + +static void TandyDACModeChanged(void) { + switch (tandy.dac.mode&3) { + case 0: + // joystick mode + break; + case 1: + break; + case 2: + // recording + break; + case 3: + // playback + tandy.dac.chan->FillUp(); + if (tandy.dac.frequency!=0) { + float freq=3579545.0f/((float)tandy.dac.frequency); + tandy.dac.chan->SetFreq((Bitu)freq); + float vol=((float)tandy.dac.amplitude)/7.0f; + tandy.dac.chan->SetVolume(vol,vol); + if ((tandy.dac.mode&0x0c)==0x0c) { + tandy.dac.dma.transfer_done=false; + tandy.dac.dma.chan=GetDMAChannel(tandy.dac.hw.dma); + if (tandy.dac.dma.chan) { + tandy.dac.dma.chan->Register_Callback(TandyDAC_DMA_CallBack); + tandy.dac.chan->Enable(true); +// LOG_MSG("Tandy DAC: playback started with freqency %f, volume %f",freq,vol); + } + } + } + break; + } +} + +static void TandyDACDMAEnabled(void) { + TandyDACModeChanged(); +} + +static void TandyDACDMADisabled(void) { +} + +static void TandyDACWrite(Bitu port,Bitu data,Bitu /*iolen*/) { + switch (port) { + case 0xc4: { + Bitu oldmode = tandy.dac.mode; + tandy.dac.mode = (Bit8u)(data&0xff); + if ((data&3)!=(oldmode&3)) { + TandyDACModeChanged(); + } + if (((data&0x0c)==0x0c) && ((oldmode&0x0c)!=0x0c)) { + TandyDACDMAEnabled(); + } else if (((data&0x0c)!=0x0c) && ((oldmode&0x0c)==0x0c)) { + TandyDACDMADisabled(); + } + } + break; + case 0xc5: + switch (tandy.dac.mode&3) { + case 0: + // joystick mode + break; + case 1: + tandy.dac.control = (Bit8u)(data&0xff); + break; + case 2: + break; + case 3: + // direct output + break; + } + break; + case 0xc6: + tandy.dac.frequency = tandy.dac.frequency & 0xf00 | (Bit8u)(data&0xff); + switch (tandy.dac.mode&3) { + case 0: + // joystick mode + break; + case 1: + case 2: + case 3: + TandyDACModeChanged(); + break; + } + break; + case 0xc7: + tandy.dac.frequency = tandy.dac.frequency & 0x00ff | (((Bit8u)(data&0xf))<<8); + tandy.dac.amplitude = (Bit8u)(data>>5); + switch (tandy.dac.mode&3) { + case 0: + // joystick mode + break; + case 1: + case 2: + case 3: + TandyDACModeChanged(); + break; + } + break; + } +} + +static Bitu TandyDACRead(Bitu port,Bitu /*iolen*/) { + switch (port) { + case 0xc4: + return (tandy.dac.mode&0x77) | (tandy.dac.irq_activated ? 0x08 : 0x00); + case 0xc6: + return (Bit8u)(tandy.dac.frequency&0xff); + case 0xc7: + return (Bit8u)(((tandy.dac.frequency>>8)&0xf) | (tandy.dac.amplitude<<5)); + } + LOG_MSG("Tandy DAC: Read from unknown %X",port); + return 0xff; +} + +static void TandyDACGenerateDMASound(Bitu length) { + if (length) { + Bitu read=tandy.dac.dma.chan->Read(length,tandy.dac.dma.buf); + tandy.dac.chan->AddSamples_m8(read,tandy.dac.dma.buf); + if (read < length) { + if (read>0) tandy.dac.dma.last_sample=tandy.dac.dma.buf[read-1]; + for (Bitu ct=read; ct < length; ct++) { + tandy.dac.chan->AddSamples_m8(1,&tandy.dac.dma.last_sample); + } + } + } +} + +static void TandyDACUpdate(Bitu length) { + if (tandy.dac.enabled && ((tandy.dac.mode&0x0c)==0x0c)) { + if (!tandy.dac.dma.transfer_done) { + Bitu len = length; + TandyDACGenerateDMASound(len); + } else { + for (Bitu ct=0; ct < length; ct++) { + tandy.dac.chan->AddSamples_m8(1,&tandy.dac.dma.last_sample); + } + } + } else { + tandy.dac.chan->AddSilence(); + } +} + + class TANDYSOUND: public Module_base { private: - IO_WriteHandleObject WriteHandler[3]; + IO_WriteHandleObject WriteHandler[4]; + IO_ReadHandleObject ReadHandler[4]; MixerObject MixerChan; + MixerObject MixerChanDAC; public: TANDYSOUND(Section* configuration):Module_base(configuration){ Section_prop * section=static_cast(configuration); + bool enable_hw_tandy_dac=true; + Bitu sbport, sbirq, sbdma; + if (SB_Get_Address(sbport, sbirq, sbdma)) { + enable_hw_tandy_dac=false; + } + real_writeb(0x40,0xd4,0x00); if (IS_TANDY_ARCH) { /* enable tandy sound if tandy=true/auto */ @@ -330,18 +506,47 @@ public: /* ports from second DMA controller conflict with tandy ports */ CloseSecondDMAController(); - WriteHandler[2].Install(0x1e0,SN76496Write,IO_MB,2); + if (enable_hw_tandy_dac) { + WriteHandler[2].Install(0x1e0,SN76496Write,IO_MB,2); + WriteHandler[3].Install(0x1e4,TandyDACWrite,IO_MB,4); +// ReadHandler[3].Install(0x1e4,TandyDACRead,IO_MB,4); + } } - - WriteHandler[0].Install(0xc0,SN76496Write,IO_MB,2); - WriteHandler[1].Install(0xc4,TandyDACWrite,IO_MB,4); - - + + Bit32u sample_rate = section->Get_int("tandyrate"); tandy.chan=MixerChan.Install(&SN76496Update,sample_rate,"TANDY"); - + + WriteHandler[0].Install(0xc0,SN76496Write,IO_MB,2); + + if (enable_hw_tandy_dac) { + // enable low-level Tandy DAC emulation + WriteHandler[1].Install(0xc4,TandyDACWrite,IO_MB,4); + ReadHandler[1].Install(0xc4,TandyDACRead,IO_MB,4); + + tandy.dac.enabled=true; + tandy.dac.chan=MixerChanDAC.Install(&TandyDACUpdate,sample_rate,"TANDYDAC"); + + tandy.dac.hw.base=0xc4; + tandy.dac.hw.irq =7; + tandy.dac.hw.dma =1; + } else { + tandy.dac.enabled=false; + tandy.dac.hw.base=0; + tandy.dac.hw.irq =0; + tandy.dac.hw.dma =0; + } + + tandy.dac.control=0; + tandy.dac.mode =0; + tandy.dac.irq_activated=false; + tandy.dac.frequency=0; + tandy.dac.amplitude=0; + tandy.dac.dma.last_sample=0; + + tandy.enabled=false; - real_writeb(0x40,0xd4,0xff); /* tandy DAC initialization value */ + real_writeb(0x40,0xd4,0xff); /* BIOS Tandy DAC initialization value */ Bitu i; struct SN76496 *R = &sn; @@ -371,7 +576,7 @@ public: static TANDYSOUND* test; -void TANDYSOUND_ShutDown(Section* sec) { +void TANDYSOUND_ShutDown(Section* /*sec*/) { delete test; } diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 0b4d90a7..fb05be2b 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.76 2009-06-11 16:05:17 c2woody Exp $ */ +/* $Id: bios.cpp,v 1.77 2009-06-23 17:46:05 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -70,6 +70,11 @@ static struct { Bit8u irq; Bit8u dma; } tandy_sb; +static struct { + Bit16u port; + Bit8u irq; + Bit8u dma; +} tandy_dac; static bool Tandy_InitializeSB() { /* see if soundblaster module available and at what port/IRQ/DMA */ @@ -86,14 +91,33 @@ static bool Tandy_InitializeSB() { } } +static bool Tandy_InitializeTS() { + /* see if Tandy DAC module available and at what port/IRQ/DMA */ + Bitu tsport, tsirq, tsdma; + if (TS_Get_Address(tsport, tsirq, tsdma)) { + tandy_dac.port=(Bit16u)(tsport&0xffff); + tandy_dac.irq =(Bit8u)(tsirq&0xff); + tandy_dac.dma =(Bit8u)(tsdma&0xff); + return true; + } else { + /* no Tandy DAC accessible */ + tandy_dac.port=0; + return false; + } +} + /* check if Tandy DAC is still playing */ static bool Tandy_TransferInProgress(void) { if (real_readw(0x40,0xd0)) return true; /* not yet done */ if (real_readb(0x40,0xd4)==0xff) return false; /* still in init-state */ + Bit8u tandy_dma = 1; + if (tandy_sb.port) tandy_dma = tandy_sb.dma; + else if (tandy_dac.port) tandy_dma = tandy_dac.dma; + IO_Write(0x0c,0x00); - Bit16u datalen=(Bit8u)(IO_ReadB(tandy_sb.dma*2+1)&0xff); - datalen|=(IO_ReadB(tandy_sb.dma*2+1)<<8); + Bit16u datalen=(Bit8u)(IO_ReadB(tandy_dma*2+1)&0xff); + datalen|=(IO_ReadB(tandy_dma*2+1)<<8); if (datalen==0xffff) return false; /* no DMA transfer */ else if ((datalen<0x10) && (real_readb(0x40,0xd4)==0x0f) && (real_readw(0x40,0xd2)==0x1c)) { /* stop already requested */ @@ -106,27 +130,44 @@ static void Tandy_SetupTransfer(PhysPt bufpt,bool isplayback) { Bitu length=real_readw(0x40,0xd0); if (length==0) return; /* nothing to do... */ - if (tandy_sb.port==0) return; + if ((tandy_sb.port==0) && (tandy_dac.port==0)) return; + + Bit8u tandy_irq = 7; + if (tandy_sb.port) tandy_irq = tandy_sb.irq; + else if (tandy_dac.port) tandy_irq = tandy_dac.irq; + Bit8u tandy_irq_vector = tandy_irq; + if (tandy_irq_vector<8) tandy_irq_vector += 8; + else tandy_irq_vector += (0x70-8); /* revector IRQ-handler if necessary */ - RealPt current_irq=RealGetVec(tandy_sb.irq+8); + RealPt current_irq=RealGetVec(tandy_irq_vector); if (current_irq!=tandy_DAC_callback[0]->Get_RealPointer()) { real_writed(0x40,0xd6,current_irq); - RealSetVec(tandy_sb.irq+8,tandy_DAC_callback[0]->Get_RealPointer()); + RealSetVec(tandy_irq_vector,tandy_DAC_callback[0]->Get_RealPointer()); } - IO_Write(tandy_sb.port+0xc,0xd0); /* stop DMA transfer */ - IO_Write(0x21,IO_Read(0x21)&(~(1<>16)&0xff); - IO_Write(tandy_sb.dma*2,(Bit8u)(bufpt&0xff)); - IO_Write(tandy_sb.dma*2,(Bit8u)((bufpt>>8)&0xff)); - switch (tandy_sb.dma) { + IO_Write(tandy_dma*2,(Bit8u)(bufpt&0xff)); + IO_Write(tandy_dma*2,(Bit8u)((bufpt>>8)&0xff)); + switch (tandy_dma) { case 0: IO_Write(0x87,bufpage); break; case 1: IO_Write(0x83,bufpage); break; case 2: IO_Write(0x81,bufpage); break; @@ -141,20 +182,31 @@ static void Tandy_SetupTransfer(PhysPt bufpt,bool isplayback) { tlength--; /* set transfer size */ - IO_Write(tandy_sb.dma*2+1,(Bit8u)(tlength&0xff)); - IO_Write(tandy_sb.dma*2+1,(Bit8u)((tlength>>8)&0xff)); - IO_Write(0x0a,tandy_sb.dma); /* enable DMA channel */ + IO_Write(tandy_dma*2+1,(Bit8u)(tlength&0xff)); + IO_Write(tandy_dma*2+1,(Bit8u)((tlength>>8)&0xff)); Bit16u delay=(Bit16u)(real_readw(0x40,0xd2)&0xfff); - /* set frequency */ - IO_Write(tandy_sb.port+0xc,0x40); - IO_Write(tandy_sb.port+0xc,256-delay*100/358); - /* set playback type to 8bit */ - if (isplayback) IO_Write(tandy_sb.port+0xc,0x14); - else IO_Write(tandy_sb.port+0xc,0x24); - /* set transfer size */ - IO_Write(tandy_sb.port+0xc,(Bit8u)(tlength&0xff)); - IO_Write(tandy_sb.port+0xc,(Bit8u)((tlength>>8)&0xff)); + Bit8u amplitude=(Bit8u)((real_readw(0x40,0xd2)>>13)&0x7); + if (tandy_sb.port) { + IO_Write(0x0a,tandy_dma); /* enable DMA channel */ + /* set frequency */ + IO_Write(tandy_sb.port+0xc,0x40); + IO_Write(tandy_sb.port+0xc,256-delay*100/358); + /* set playback type to 8bit */ + if (isplayback) IO_Write(tandy_sb.port+0xc,0x14); + else IO_Write(tandy_sb.port+0xc,0x24); + /* set transfer size */ + IO_Write(tandy_sb.port+0xc,(Bit8u)(tlength&0xff)); + IO_Write(tandy_sb.port+0xc,(Bit8u)((tlength>>8)&0xff)); + } else { + if (isplayback) IO_Write(tandy_dac.port,(IO_Read(tandy_dac.port)&0x7c) | 0x03); + else IO_Write(tandy_dac.port,(IO_Read(tandy_dac.port)&0x7c) | 0x02); + IO_Write(tandy_dac.port+2,(Bit8u)(delay&0xff)); + IO_Write(tandy_dac.port+3,(Bit8u)(((delay>>8)&0xf) | (amplitude<<5))); + if (isplayback) IO_Write(tandy_dac.port,(IO_Read(tandy_dac.port)&0x7c) | 0x1f); + else IO_Write(tandy_dac.port,(IO_Read(tandy_dac.port)&0x7c) | 0x1e); + IO_Write(0x0a,tandy_dma); /* enable DMA channel */ + } if (!isplayback) { /* mark transfer as recording operation */ @@ -163,10 +215,15 @@ static void Tandy_SetupTransfer(PhysPt bufpt,bool isplayback) { } static Bitu IRQ_TandyDAC(void) { + if (tandy_dac.port) { + IO_Read(tandy_dac.port); + } if (real_readw(0x40,0xd0)) { /* play/record next buffer */ /* acknowledge IRQ */ IO_Write(0x20,0x20); - IO_Read(tandy_sb.port+0xe); + if (tandy_sb.port) { + IO_Read(tandy_sb.port+0xe); + } /* buffer starts at the next page */ Bit8u npage=real_readb(0x40,0xd4)+1; @@ -182,11 +239,20 @@ static Bitu IRQ_TandyDAC(void) { Tandy_SetupTransfer(npage<<16,true); } } else { /* playing/recording is finished */ - RealSetVec(tandy_sb.irq+8,real_readd(0x40,0xd6)); + Bit8u tandy_irq = 7; + if (tandy_sb.port) tandy_irq = tandy_sb.irq; + else if (tandy_dac.port) tandy_irq = tandy_dac.irq; + Bit8u tandy_irq_vector = tandy_irq; + if (tandy_irq_vector<8) tandy_irq_vector += 8; + else tandy_irq_vector += (0x70-8); + + RealSetVec(tandy_irq_vector,real_readd(0x40,0xd6)); /* turn off speaker and acknowledge soundblaster IRQ */ - IO_Write(tandy_sb.port+0xc,0xd3); - IO_Read(tandy_sb.port+0xe); + if (tandy_sb.port) { + IO_Write(tandy_sb.port+0xc,0xd3); + IO_Read(tandy_sb.port+0xe); + } /* issue BIOS tandy sound device busy callout */ SegSet16(cs, RealSeg(tandy_DAC_callback[1]->Get_RealPointer())); @@ -196,10 +262,14 @@ static Bitu IRQ_TandyDAC(void) { } static void TandyDAC_Handler(Bit8u tfunction) { - if (!tandy_sb.port) return; + if ((!tandy_sb.port) && (!tandy_dac.port)) return; switch (tfunction) { case 0x81: /* Tandy sound system check */ - reg_ax=0xc4; + if (tandy_dac.port) { + reg_ax=tandy_dac.port; + } else { + reg_ax=0xc4; + } CALLBACK_SCF(Tandy_TransferInProgress()); break; case 0x82: /* Tandy sound system start recording */ @@ -228,6 +298,9 @@ static void TandyDAC_Handler(Bit8u tfunction) { CALLBACK_SCF(false); break; case 0x85: /* Tandy sound system reset */ + if (tandy_dac.port) { + IO_Write(tandy_dac.port,(Bit8u)(IO_Read(tandy_dac.port)&0xe0)); + } reg_ah=0x00; CALLBACK_SCF(false); break; @@ -864,9 +937,17 @@ public: for(Bitu i = 0; i < strlen(b_date); i++) phys_writeb(0xffff5+i,b_date[i]); phys_writeb(0xfffff,0x55); // signature + tandy_sb.port=0; + tandy_dac.port=0; if (use_tandyDAC) { /* tandy DAC sound requested, see if soundblaster device is available */ + Bitu tandy_dac_type = 0; if (Tandy_InitializeSB()) { + tandy_dac_type = 1; + } else if (Tandy_InitializeTS()) { + tandy_dac_type = 2; + } + if (tandy_dac_type) { real_writew(0x40,0xd0,0x0000); real_writew(0x40,0xd2,0x0000); real_writeb(0x40,0xd4,0xff); /* tandy DAC init value */ @@ -886,7 +967,14 @@ public: // pop ax // iret - RealPt current_irq=RealGetVec(tandy_sb.irq+8); + Bit8u tandy_irq = 7; + if (tandy_dac_type==1) tandy_irq = tandy_sb.irq; + else if (tandy_dac_type==2) tandy_irq = tandy_dac.irq; + Bit8u tandy_irq_vector = tandy_irq; + if (tandy_irq_vector<8) tandy_irq_vector += 8; + else tandy_irq_vector += (0x70-8); + + RealPt current_irq=RealGetVec(tandy_irq_vector); real_writed(0x40,0xd6,current_irq); for (Bit16u i=0; i<0x10; i++) phys_writeb(PhysMake(0xf000,0xa084+i),0x80); } else real_writeb(0x40,0xd4,0x00); @@ -995,7 +1083,14 @@ public: Bit32u orig_vector=real_readd(0x40,0xd6); if (orig_vector==tandy_DAC_callback[0]->Get_RealPointer()) { /* set IRQ vector to old value */ - RealSetVec(tandy_sb.irq+8,real_readd(0x40,0xd6)); + Bit8u tandy_irq = 7; + if (tandy_sb.port) tandy_irq = tandy_sb.irq; + else if (tandy_dac.port) tandy_irq = tandy_dac.irq; + Bit8u tandy_irq_vector = tandy_irq; + if (tandy_irq_vector<8) tandy_irq_vector += 8; + else tandy_irq_vector += (0x70-8); + + RealSetVec(tandy_irq_vector,real_readd(0x40,0xd6)); real_writed(0x40,0xd6,0x00000000); } delete tandy_DAC_callback[0]; From 31f6dccfa011d811939f371b9f568fbd74c28991 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 24 Jun 2009 17:44:52 +0000 Subject: [PATCH 3343/4131] disable vcpi if no extended memory available (as no descriptor tables can be set up) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3432 --- src/ints/ems.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 98879bdf..5f8e845b 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.63 2009-06-06 21:52:09 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.64 2009-06-24 17:44:52 c2woody Exp $ */ #include #include @@ -672,7 +672,7 @@ static Bitu INT67_Handler(void) { reg_ah=EMM_NO_ERROR; break; case 0x42: /* Get number of pages */ - reg_dx=MEM_TotalPages()/4; //Not entirely correct but okay + reg_dx=(Bit16u)(MEM_TotalPages()/4); //Not entirely correct but okay reg_bx=EMM_GetFreePages(); reg_ah=EMM_NO_ERROR; break; @@ -1175,13 +1175,16 @@ static Bitu V86_Monitor() { } static void SetupVCPI() { + vcpi.enabled=false; + + /* Allocate one EMS-page for private VCPI-data in memory beyond 1MB */ + if (EMM_AllocateMemory(1,vcpi.ems_handle,false) != EMM_NO_ERROR) return; + vcpi.enabled=true; vcpi.pic1_remapping=0x08; // master PIC base vcpi.pic2_remapping=0x70; // slave PIC base - /* Allocate one EMS-page for private VCPI-data in memory beyond 1MB */ - EMM_AllocateMemory(1,vcpi.ems_handle,false); vcpi.private_area=emm_handles[vcpi.ems_handle].mem<<12; /* GDT */ @@ -1324,6 +1327,8 @@ public: /* Initialize private data area and set up descriptor tables */ SetupVCPI(); + if (!vcpi.enabled) return; + /* Install v86-callback that handles interrupts occuring in v86 mode, including protection fault exceptions */ call_v86mon.Install(&V86_Monitor,CB_IRET,"V86 Monitor"); @@ -1381,7 +1386,7 @@ public: /* Clear handle and page tables */ //TODO - if (!ENABLE_VCPI) return; + if ((!ENABLE_VCPI) || (!vcpi.enabled)) return; /* Free private data area in expanded memory */ EMM_ReleaseMemory(vcpi.ems_handle); From 8213b3da0e26264c9aea0a7edd9a119cf35f0382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 25 Jun 2009 19:31:43 +0000 Subject: [PATCH 3344/4131] fix operator/return value aliasing in special case for arm recompiler backend (M-HT) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3433 --- src/cpu/core_dynrec/decoder_opcodes.h | 6 ++++-- src/cpu/core_dynrec/operators.h | 10 ++++++---- src/cpu/core_dynrec/risc_armv4le-o3.h | 5 ++++- src/cpu/core_dynrec/risc_armv4le-s3.h | 5 ++++- src/cpu/core_dynrec/risc_armv4le-thumb-iw.h | 5 ++++- src/cpu/core_dynrec/risc_armv4le-thumb-niw.h | 5 ++++- src/cpu/core_dynrec/risc_armv4le-thumb.h | 5 ++++- src/cpu/core_dynrec/risc_mipsel32.h | 5 ++++- src/cpu/core_dynrec/risc_x64.h | 10 ++++++---- src/cpu/core_dynrec/risc_x86.h | 12 ++++++++---- 10 files changed, 48 insertions(+), 20 deletions(-) diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index 22a5a556..25605046 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: decoder_opcodes.h,v 1.9 2009-06-25 19:31:43 c2woody Exp $ */ + /* The functions in this file are called almost exclusively by decoder.h, @@ -544,8 +546,8 @@ static void dyn_dshift_ev_gv(bool left,bool immediate) { MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); } MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); - if (immediate) gen_mov_byte_to_reg_low_imm(FC_RETOP,decode_fetchb()); - else MOV_REG_BYTE_TO_HOST_REG_LOW(FC_RETOP,DRC_REG_ECX,0); + if (immediate) gen_mov_byte_to_reg_low_imm(FC_OP3,decode_fetchb()); + else MOV_REG_BYTE_TO_HOST_REG_LOW(FC_OP3,DRC_REG_ECX,0); if (decode.big_op) dyn_dpshift_dword_gencall(left); else dyn_dpshift_word_gencall(left); diff --git a/src/cpu/core_dynrec/operators.h b/src/cpu/core_dynrec/operators.h index c4c89f17..eae97390 100644 --- a/src/cpu/core_dynrec/operators.h +++ b/src/cpu/core_dynrec/operators.h @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: operators.h,v 1.8 2009-06-25 19:31:43 c2woody Exp $ */ + static Bit8u DRC_CALL_CONV dynrec_add_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_add_byte(Bit8u op1,Bit8u op2) { @@ -1297,20 +1299,20 @@ static Bit32u DRC_CALL_CONV dynrec_dshr_dword_simple(Bit32u op1,Bit32u op2,Bit8u static void dyn_dpshift_word_gencall(bool left) { if (left) { - DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshl_word,FC_RETOP); + DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshl_word,FC_OP3); InvalidateFlagsPartially((void*)&dynrec_dshl_word_simple,proc_addr,t_DSHLw); } else { - DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshr_word,FC_RETOP); + DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshr_word,FC_OP3); InvalidateFlagsPartially((void*)&dynrec_dshr_word_simple,proc_addr,t_DSHRw); } } static void dyn_dpshift_dword_gencall(bool left) { if (left) { - DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshl_dword,FC_RETOP); + DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshl_dword,FC_OP3); InvalidateFlagsPartially((void*)&dynrec_dshl_dword_simple,proc_addr,t_DSHLd); } else { - DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshr_dword,FC_RETOP); + DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshr_dword,FC_OP3); InvalidateFlagsPartially((void*)&dynrec_dshr_dword_simple,proc_addr,t_DSHRd); } } diff --git a/src/cpu/core_dynrec/risc_armv4le-o3.h b/src/cpu/core_dynrec/risc_armv4le-o3.h index 4b6916b8..9866a7fe 100644 --- a/src/cpu/core_dynrec/risc_armv4le-o3.h +++ b/src/cpu/core_dynrec/risc_armv4le-o3.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-o3.h,v 1.4 2009-05-16 21:52:47 c2woody Exp $ */ +/* $Id: risc_armv4le-o3.h,v 1.5 2009-06-25 19:31:43 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (size-tweaked arm version) */ @@ -39,6 +39,9 @@ // register that holds the second parameter #define FC_OP2 HOST_a2 +// special register that holds the third parameter for _R3 calls (byte accessible) +#define FC_OP3 HOST_v2 + // register that holds byte-accessible temporary values #define FC_TMP_BA1 HOST_a1 diff --git a/src/cpu/core_dynrec/risc_armv4le-s3.h b/src/cpu/core_dynrec/risc_armv4le-s3.h index c2b7d582..d89ee13b 100644 --- a/src/cpu/core_dynrec/risc_armv4le-s3.h +++ b/src/cpu/core_dynrec/risc_armv4le-s3.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-s3.h,v 1.4 2009-05-16 21:52:47 c2woody Exp $ */ +/* $Id: risc_armv4le-s3.h,v 1.5 2009-06-25 19:31:43 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (speed-tweaked arm version) */ @@ -39,6 +39,9 @@ // register that holds the second parameter #define FC_OP2 HOST_a2 +// special register that holds the third parameter for _R3 calls (byte accessible) +#define FC_OP3 HOST_v2 + // register that holds byte-accessible temporary values #define FC_TMP_BA1 HOST_a1 diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h index e4e0fe12..0a2f6631 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-thumb-iw.h,v 1.3 2009-05-16 21:52:47 c2woody Exp $ */ +/* $Id: risc_armv4le-thumb-iw.h,v 1.4 2009-06-25 19:31:43 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (thumb version with data pool, requires -mthumb-interwork switch when compiling dosbox) */ @@ -44,6 +44,9 @@ // register that holds the second parameter #define FC_OP2 HOST_a2 +// special register that holds the third parameter for _R3 calls (byte accessible) +#define FC_OP3 HOST_a4 + // register that holds byte-accessible temporary values #define FC_TMP_BA1 HOST_a1 diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h index d8618f12..0c99cc3c 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-thumb-niw.h,v 1.3 2009-05-16 21:52:47 c2woody Exp $ */ +/* $Id: risc_armv4le-thumb-niw.h,v 1.4 2009-06-25 19:31:43 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (thumb version with data pool) */ @@ -44,6 +44,9 @@ // register that holds the second parameter #define FC_OP2 HOST_a2 +// special register that holds the third parameter for _R3 calls (byte accessible) +#define FC_OP3 HOST_a4 + // register that holds byte-accessible temporary values #define FC_TMP_BA1 HOST_a1 diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb.h b/src/cpu/core_dynrec/risc_armv4le-thumb.h index 58620574..37ae9c12 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-thumb.h,v 1.4 2009-05-16 21:52:47 c2woody Exp $ */ +/* $Id: risc_armv4le-thumb.h,v 1.5 2009-06-25 19:31:43 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (thumb version) */ @@ -44,6 +44,9 @@ // register that holds the second parameter #define FC_OP2 HOST_a2 +// special register that holds the third parameter for _R3 calls (byte accessible) +#define FC_OP3 HOST_a4 + // register that holds byte-accessible temporary values #define FC_TMP_BA1 HOST_a1 diff --git a/src/cpu/core_dynrec/risc_mipsel32.h b/src/cpu/core_dynrec/risc_mipsel32.h index b3da84e5..0da567a0 100644 --- a/src/cpu/core_dynrec/risc_mipsel32.h +++ b/src/cpu/core_dynrec/risc_mipsel32.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_mipsel32.h,v 1.5 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: risc_mipsel32.h,v 1.6 2009-06-25 19:31:43 c2woody Exp $ */ /* MIPS32 (little endian) backend by crazyc */ @@ -74,6 +74,9 @@ typedef Bit8u HostReg; // register that holds the second parameter #define FC_OP2 HOST_a1 +// special register that holds the third parameter for _R3 calls (byte accessible) +#define FC_OP3 HOST_??? + // register that holds byte-accessible temporary values #define FC_TMP_BA1 HOST_t5 diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index 55000960..784b46f7 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_x64.h,v 1.12 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: risc_x64.h,v 1.13 2009-06-25 19:31:43 c2woody Exp $ */ // some configuring defines that specify the capabilities of this architecture @@ -63,6 +63,9 @@ typedef Bit8u HostReg; // register that holds the second parameter #define FC_OP2 HOST_ESI +// special register that holds the third parameter for _R3 calls (byte accessible) +#define FC_OP3 HOST_EAX + // register that holds byte-accessible temporary values #define FC_TMP_BA1 HOST_ECX @@ -290,12 +293,11 @@ static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits im imm_size=4; rm_base=0x80; //Signed dword imm } - // ea_reg := ea_reg+TEMP_REG_DRC*(2^scale)+imm - // ea_reg := op1 + op2 *(2^scale)+imm + // ea_reg := ea_reg+scale_reg*(2^scale)+imm cache_addb(0x48); cache_addb(0x8d); //LEA cache_addb(0x04+(dest_reg << 3)+rm_base); //The sib indicator - cache_addb(dest_reg+(TEMP_REG_DRC<<3)+(scale<<6)); + cache_addb(dest_reg+(scale_reg<<3)+(scale<<6)); switch (imm_size) { case 0: break; diff --git a/src/cpu/core_dynrec/risc_x86.h b/src/cpu/core_dynrec/risc_x86.h index 3f2f9dba..e5aacb92 100644 --- a/src/cpu/core_dynrec/risc_x86.h +++ b/src/cpu/core_dynrec/risc_x86.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_x86.h,v 1.9 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: risc_x86.h,v 1.10 2009-06-25 19:31:43 c2woody Exp $ */ // some configuring defines that specify the capabilities of this architecture @@ -70,6 +70,9 @@ enum HostReg { // register that holds the second parameter #define FC_OP2 HOST_EDX +// special register that holds the third parameter for _R3 calls (byte accessible) +#define FC_OP3 HOST_EAX + // register that holds byte-accessible temporary values #define FC_TMP_BA1 HOST_ECX @@ -267,11 +270,10 @@ static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits im imm_size=4; rm_base=0x80; //Signed dword imm } - // ea_reg := ea_reg+TEMP_REG_DRC*(2^scale)+imm - // ea_reg := op1 + op2 *(2^scale)+imm + // ea_reg := ea_reg+scale_reg*(2^scale)+imm cache_addb(0x8d); //LEA cache_addb(0x04+(dest_reg << 3)+rm_base); //The sib indicator - cache_addb(dest_reg+(TEMP_REG_DRC<<3)+(scale<<6)); + cache_addb(dest_reg+(scale_reg<<3)+(scale<<6)); switch (imm_size) { case 0: break; @@ -425,7 +427,9 @@ static void gen_fill_branch_long(Bit32u data) { static void gen_run_code(void) { cache_addd(0x0424448b); // mov eax,[esp+4] cache_addb(0x53); // push ebx + cache_addb(0x56); // push esi cache_addw(0xd0ff); // call eax + cache_addb(0x5e); // pop esi cache_addb(0x5b); // pop ebx } From bf3652563bbd01271a0fe8ea87fa8b072ba18b7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 26 Jun 2009 16:43:30 +0000 Subject: [PATCH 3345/4131] prevent excessive inlining in prefetching core Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3434 --- src/cpu/core_prefetch.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cpu/core_prefetch.cpp b/src/cpu/core_prefetch.cpp index 6a08e6fe..0ea91f0e 100644 --- a/src/cpu/core_prefetch.cpp +++ b/src/cpu/core_prefetch.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: core_prefetch.cpp,v 1.2 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: core_prefetch.cpp,v 1.3 2009-06-26 16:43:30 c2woody Exp $ */ #include @@ -115,7 +115,7 @@ static Bit8u prefetch_buffer[MAX_PQ_SIZE]; static bool pq_valid=false; static Bitu pq_start; -static INLINE Bit8u Fetchb() { +static Bit8u Fetchb() { Bit8u temp; if (pq_valid && (core.cseip>=pq_start) && (core.cseip=pq_start) && (core.cseip+2=pq_start) && (core.cseip+416) len=16; char tempcode[16*2+1];char * writecode=tempcode; for (;len>0;len--) { - sprintf(writecode,"%X",mem_readb(core.cseip++)); + sprintf(writecode,"%02X",mem_readb(core.cseip++)); writecode+=2; } LOG(LOG_CPU,LOG_NORMAL)("Illegal/Unhandled opcode %s",tempcode); From eb9633a6e443cd766186916b3b64d91e372aa3c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 27 Jun 2009 12:51:10 +0000 Subject: [PATCH 3346/4131] optimizations for the recompiler arm backend (M-HT) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3435 --- src/cpu/core_dynrec/risc_armv4le-o3.h | 77 ++-- src/cpu/core_dynrec/risc_armv4le-s3.h | 77 ++-- src/cpu/core_dynrec/risc_armv4le-thumb-iw.h | 385 +++++++----------- src/cpu/core_dynrec/risc_armv4le-thumb-niw.h | 399 ++++++++----------- src/cpu/core_dynrec/risc_armv4le-thumb.h | 376 ++++++++--------- 5 files changed, 576 insertions(+), 738 deletions(-) diff --git a/src/cpu/core_dynrec/risc_armv4le-o3.h b/src/cpu/core_dynrec/risc_armv4le-o3.h index 9866a7fe..cbb48232 100644 --- a/src/cpu/core_dynrec/risc_armv4le-o3.h +++ b/src/cpu/core_dynrec/risc_armv4le-o3.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-o3.h,v 1.5 2009-06-25 19:31:43 c2woody Exp $ */ +/* $Id: risc_armv4le-o3.h,v 1.6 2009-06-27 12:51:10 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (size-tweaked arm version) */ @@ -24,11 +24,11 @@ // temporary registers #define temp1 HOST_ip -#define temp2 HOST_v5 +#define temp2 HOST_v3 #define temp3 HOST_v4 // register that holds function return values -#define FC_RETOP HOST_v3 +#define FC_RETOP HOST_a1 // register used for address calculations, #define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG @@ -627,7 +627,6 @@ static void INLINE gen_call_function_raw(void * func) { cache_addd( ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 cache_addd( BX(temp1) ); // bx temp1 cache_addd((Bit32u)func); // .int func - cache_addd( MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 0) ); // mov FC_RETOP, a1 } // generate a call to a function with paramcount parameters @@ -786,7 +785,7 @@ static void INLINE gen_fill_branch_long(Bit32u data) { static void gen_run_code(void) { cache_addd(0xe92d4000); // stmfd sp!, {lr} - cache_addd(0xe92d0df0); // stmfd sp!, {v1-v5,v7,v8} + cache_addd(0xe92d0cf0); // stmfd sp!, {v1-v4,v7,v8} // adr: 8 cache_addd( LDR_IMM(FC_SEGS_ADDR, HOST_pc, 64 - (8 + 8)) ); // ldr FC_SEGS_ADDR, [pc, #(&Segs)] @@ -797,7 +796,7 @@ static void gen_run_code(void) { cache_addd(0xe92d4000); // stmfd sp!, {lr} cache_addd( BX(HOST_r0) ); // bx r0 - cache_addd(0xe8bd0df0); // ldmfd sp!, {v1-v5,v7,v8} + cache_addd(0xe8bd0cf0); // ldmfd sp!, {v1-v4,v7,v8} cache_addd(0xe8bd4000); // ldmfd sp!, {lr} cache_addd( BX(HOST_lr) ); // bx lr @@ -818,7 +817,6 @@ static void gen_run_code(void) { // return from a function static void gen_return_function(void) { - cache_addd( MOV_REG_LSL_IMM(HOST_a1, FC_RETOP, 0) ); // mov a1, FC_RETOP cache_addd(0xe8bd4000); // ldmfd sp!, {lr} cache_addd( BX(HOST_lr) ); // bx lr } @@ -835,31 +833,41 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDw: case t_ADDd: *(Bit32u*)pos=ADD_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // add FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_ORb: case t_ORw: case t_ORd: *(Bit32u*)pos=ORR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // orr FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_ANDb: case t_ANDw: case t_ANDd: *(Bit32u*)pos=AND_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // and FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_SUBb: case t_SUBw: case t_SUBd: *(Bit32u*)pos=SUB_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // sub FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_XORb: case t_XORw: case t_XORd: *(Bit32u*)pos=EOR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // eor FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_CMPb: case t_CMPw: @@ -867,106 +875,105 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit32u*)pos=B_FWD(12); // b (pc+3*4) + *(Bit32u*)pos=B_FWD(8); // b (pc+2*4) break; case t_INCb: case t_INCw: case t_INCd: *(Bit32u*)pos=ADD_IMM(FC_RETOP, HOST_a1, 1, 0); // add FC_RETOP, a1, #1 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_DECb: case t_DECw: case t_DECd: *(Bit32u*)pos=SUB_IMM(FC_RETOP, HOST_a1, 1, 0); // sub FC_RETOP, a1, #1 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_SHLb: case t_SHLw: case t_SHLd: *(Bit32u*)pos=MOV_REG_LSL_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsl a2 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_SHRb: *(Bit32u*)pos=AND_IMM(FC_RETOP, HOST_a1, 0xff, 0); // and FC_RETOP, a1, #0xff *(Bit32u*)(pos+4)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2 *(Bit32u*)(pos+8)=NOP; // nop *(Bit32u*)(pos+12)=NOP; // nop - *(Bit32u*)(pos+16)=NOP; // nop break; case t_SHRw: *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 *(Bit32u*)(pos+4)=MOV_REG_LSR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, lsr #16 *(Bit32u*)(pos+8)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2 *(Bit32u*)(pos+12)=NOP; // nop - *(Bit32u*)(pos+16)=NOP; // nop break; case t_SHRd: *(Bit32u*)pos=MOV_REG_LSR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsr a2 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_SARb: *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 *(Bit32u*)(pos+4)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 24); // mov FC_RETOP, FC_RETOP, asr #24 *(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 *(Bit32u*)(pos+12)=NOP; // nop - *(Bit32u*)(pos+16)=NOP; // nop break; case t_SARw: *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 *(Bit32u*)(pos+4)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, asr #16 *(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 *(Bit32u*)(pos+12)=NOP; // nop - *(Bit32u*)(pos+16)=NOP; // nop break; case t_SARd: *(Bit32u*)pos=MOV_REG_ASR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, asr a2 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_RORb: *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 *(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 8); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 - *(Bit32u*)(pos+16)=NOP; // nop break; case t_RORw: *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 *(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 *(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 *(Bit32u*)(pos+12)=NOP; // nop - *(Bit32u*)(pos+16)=NOP; // nop break; case t_RORd: *(Bit32u*)pos=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) - break; - case t_ROLb: - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 - *(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 - *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 8); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 - *(Bit32u*)(pos+12)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+16)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_ROLw: *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 *(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 - *(Bit32u*)(pos+16)=NOP; // nop break; case t_ROLd: *(Bit32u*)pos=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 *(Bit32u*)(pos+4)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 *(Bit32u*)(pos+8)=NOP; // nop *(Bit32u*)(pos+12)=NOP; // nop - *(Bit32u*)(pos+16)=NOP; // nop break; case t_NEGb: case t_NEGw: case t_NEGd: *(Bit32u*)pos=RSB_IMM(FC_RETOP, HOST_a1, 0, 0); // rsb FC_RETOP, a1, #0 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; default: *(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func diff --git a/src/cpu/core_dynrec/risc_armv4le-s3.h b/src/cpu/core_dynrec/risc_armv4le-s3.h index d89ee13b..ae804b1f 100644 --- a/src/cpu/core_dynrec/risc_armv4le-s3.h +++ b/src/cpu/core_dynrec/risc_armv4le-s3.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-s3.h,v 1.5 2009-06-25 19:31:43 c2woody Exp $ */ +/* $Id: risc_armv4le-s3.h,v 1.6 2009-06-27 12:51:10 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (speed-tweaked arm version) */ @@ -24,11 +24,11 @@ // temporary registers #define temp1 HOST_ip -#define temp2 HOST_v5 +#define temp2 HOST_v3 #define temp3 HOST_v4 // register that holds function return values -#define FC_RETOP HOST_v3 +#define FC_RETOP HOST_a1 // register used for address calculations, #define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG @@ -475,7 +475,6 @@ static void INLINE gen_call_function_raw(void * func) { cache_addd( ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 cache_addd( BX(temp1) ); // bx temp1 cache_addd((Bit32u)func); // .int func - cache_addd( MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 0) ); // mov FC_RETOP, a1 } // generate a call to a function with paramcount parameters @@ -622,7 +621,7 @@ static void INLINE gen_fill_branch_long(Bit32u data) { static void gen_run_code(void) { cache_addd(0xe92d4000); // stmfd sp!, {lr} - cache_addd(0xe92d0df0); // stmfd sp!, {v1-v5,v7,v8} + cache_addd(0xe92d0cf0); // stmfd sp!, {v1-v4,v7,v8} // adr: 8 cache_addd( LDR_IMM(FC_SEGS_ADDR, HOST_pc, 64 - (8 + 8)) ); // ldr FC_SEGS_ADDR, [pc, #(&Segs)] @@ -633,7 +632,7 @@ static void gen_run_code(void) { cache_addd(0xe92d4000); // stmfd sp!, {lr} cache_addd( BX(HOST_r0) ); // bx r0 - cache_addd(0xe8bd0df0); // ldmfd sp!, {v1-v5,v7,v8} + cache_addd(0xe8bd0cf0); // ldmfd sp!, {v1-v4,v7,v8} cache_addd(0xe8bd4000); // ldmfd sp!, {lr} cache_addd( BX(HOST_lr) ); // bx lr @@ -654,7 +653,6 @@ static void gen_run_code(void) { // return from a function static void gen_return_function(void) { - cache_addd( MOV_REG_LSL_IMM(HOST_a1, FC_RETOP, 0) ); // mov a1, FC_RETOP cache_addd(0xe8bd4000); // ldmfd sp!, {lr} cache_addd( BX(HOST_lr) ); // bx lr } @@ -671,31 +669,41 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDw: case t_ADDd: *(Bit32u*)pos=ADD_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // add FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_ORb: case t_ORw: case t_ORd: *(Bit32u*)pos=ORR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // orr FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_ANDb: case t_ANDw: case t_ANDd: *(Bit32u*)pos=AND_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // and FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_SUBb: case t_SUBw: case t_SUBd: *(Bit32u*)pos=SUB_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // sub FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_XORb: case t_XORw: case t_XORd: *(Bit32u*)pos=EOR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // eor FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_CMPb: case t_CMPw: @@ -703,106 +711,105 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit32u*)pos=B_FWD(12); // b (pc+3*4) + *(Bit32u*)pos=B_FWD(8); // b (pc+2*4) break; case t_INCb: case t_INCw: case t_INCd: *(Bit32u*)pos=ADD_IMM(FC_RETOP, HOST_a1, 1, 0); // add FC_RETOP, a1, #1 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_DECb: case t_DECw: case t_DECd: *(Bit32u*)pos=SUB_IMM(FC_RETOP, HOST_a1, 1, 0); // sub FC_RETOP, a1, #1 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_SHLb: case t_SHLw: case t_SHLd: *(Bit32u*)pos=MOV_REG_LSL_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsl a2 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_SHRb: *(Bit32u*)pos=AND_IMM(FC_RETOP, HOST_a1, 0xff, 0); // and FC_RETOP, a1, #0xff *(Bit32u*)(pos+4)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2 *(Bit32u*)(pos+8)=NOP; // nop *(Bit32u*)(pos+12)=NOP; // nop - *(Bit32u*)(pos+16)=NOP; // nop break; case t_SHRw: *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 *(Bit32u*)(pos+4)=MOV_REG_LSR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, lsr #16 *(Bit32u*)(pos+8)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2 *(Bit32u*)(pos+12)=NOP; // nop - *(Bit32u*)(pos+16)=NOP; // nop break; case t_SHRd: *(Bit32u*)pos=MOV_REG_LSR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsr a2 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_SARb: *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 *(Bit32u*)(pos+4)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 24); // mov FC_RETOP, FC_RETOP, asr #24 *(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 *(Bit32u*)(pos+12)=NOP; // nop - *(Bit32u*)(pos+16)=NOP; // nop break; case t_SARw: *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 *(Bit32u*)(pos+4)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, asr #16 *(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 *(Bit32u*)(pos+12)=NOP; // nop - *(Bit32u*)(pos+16)=NOP; // nop break; case t_SARd: *(Bit32u*)pos=MOV_REG_ASR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, asr a2 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_RORb: *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 *(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 8); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 - *(Bit32u*)(pos+16)=NOP; // nop break; case t_RORw: *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 *(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 *(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 *(Bit32u*)(pos+12)=NOP; // nop - *(Bit32u*)(pos+16)=NOP; // nop break; case t_RORd: *(Bit32u*)pos=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) - break; - case t_ROLb: - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 - *(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 - *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 8); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 - *(Bit32u*)(pos+12)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+16)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; case t_ROLw: *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 *(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 - *(Bit32u*)(pos+16)=NOP; // nop break; case t_ROLd: *(Bit32u*)pos=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 *(Bit32u*)(pos+4)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 *(Bit32u*)(pos+8)=NOP; // nop *(Bit32u*)(pos+12)=NOP; // nop - *(Bit32u*)(pos+16)=NOP; // nop break; case t_NEGb: case t_NEGw: case t_NEGd: *(Bit32u*)pos=RSB_IMM(FC_RETOP, HOST_a1, 0, 0); // rsb FC_RETOP, a1, #0 - *(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4) + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop break; default: *(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h index 0a2f6631..57828866 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-thumb-iw.h,v 1.4 2009-06-25 19:31:43 c2woody Exp $ */ +/* $Id: risc_armv4le-thumb-iw.h,v 1.5 2009-06-27 12:51:10 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (thumb version with data pool, requires -mthumb-interwork switch when compiling dosbox) */ @@ -25,15 +25,10 @@ // temporary "lo" registers #define templo1 HOST_v3 #define templo2 HOST_v4 - -// temporary "lo" register - value must be preserved when using it -#define templosav HOST_a3 - -// temporary "hi" register -#define temphi1 HOST_ip +#define templo3 HOST_v2 // register that holds function return values -#define FC_RETOP HOST_v2 +#define FC_RETOP HOST_a1 // register used for address calculations, #define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG @@ -86,8 +81,6 @@ #define ADD_IMM8(dst, imm) (0x3000 + ((dst) << 8) + (imm) ) // add dst, src1, src2 #define ADD_REG(dst, src1, src2) (0x1800 + (dst) + ((src1) << 3) + ((src2) << 6) ) -// add dst, src -#define ADD_LO_HI(dst, src) (0x4440 + (dst) + (((src) - HOST_r8) << 3) ) // add dst, pc, #imm @ 0 <= imm < 1024 & imm mod 4 = 0 #define ADD_LO_PC_IMM(dst, imm) (0xa000 + ((dst) << 8) + ((imm) >> 2) ) // sub dst, src1, src2 @@ -502,11 +495,9 @@ static void gen_extend_word(bool sign,HostReg reg) { // add a 32bit value from memory to a full register static void gen_add(HostReg reg,void* op) { + gen_mov_word_to_reg(templo3, op, 1); cache_checkinstr(2); - cache_addw( MOV_HI_LO(temphi1, reg) ); // mov temphi1, reg - gen_mov_word_to_reg(reg, op, 1); - cache_checkinstr(2); - cache_addw( ADD_LO_HI(reg, temphi1) ); // add reg, temphi1 + cache_addw( ADD_REG(reg, reg, templo3) ); // add reg, reg, templo3 } // add a 32bit constant value to a full register @@ -528,12 +519,8 @@ static void gen_and_imm(HostReg reg,Bit32u imm) { // move a 32bit constant value into memory static void gen_mov_direct_dword(void* dest,Bit32u imm) { - cache_checkinstr(2); - cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav - gen_mov_dword_to_reg_imm(templosav, imm); - gen_mov_word_from_reg(templosav, dest, 1); - cache_checkinstr(2); - cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 + gen_mov_dword_to_reg_imm(templo3, imm); + gen_mov_word_from_reg(templo3, dest, 1); } // move an address into memory @@ -544,19 +531,15 @@ static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { // add an 8bit constant value to a dword memory value static void gen_add_direct_byte(void* dest,Bit8s imm) { if(!imm) return; - cache_checkinstr(2); - cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templosav, dest, 1, templo2); + gen_mov_word_to_reg_helper(templo3, dest, 1, templo2); cache_checkinstr(2); if (imm >= 0) { - cache_addw( ADD_IMM8(templosav, (Bit32s)imm) ); // add templosav, #(imm) + cache_addw( ADD_IMM8(templo3, (Bit32s)imm) ); // add templo3, #(imm) } else { - cache_addw( SUB_IMM8(templosav, -((Bit32s)imm)) ); // sub templosav, #(-imm) + cache_addw( SUB_IMM8(templo3, -((Bit32s)imm)) ); // sub templo3, #(-imm) } - gen_mov_word_from_reg_helper(templosav, dest, 1, templo2); - cache_checkinstr(2); - cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 + gen_mov_word_from_reg_helper(templo3, dest, 1, templo2); } // add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value @@ -566,38 +549,30 @@ static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { gen_add_direct_byte(dest,(Bit8s)imm); return; } - cache_checkinstr(2); - cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templosav, dest, dword, templo2); + gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); if (dword) { gen_mov_dword_to_reg_imm(templo1, imm); } else { gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); } cache_checkinstr(2); - cache_addw( ADD_REG(templosav, templosav, templo1) ); // add templosav, templosav, templo1 - gen_mov_word_from_reg_helper(templosav, dest, dword, templo2); - cache_checkinstr(2); - cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 + cache_addw( ADD_REG(templo3, templo3, templo1) ); // add templo3, templo3, templo1 + gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); } // subtract an 8bit constant value from a dword memory value static void gen_sub_direct_byte(void* dest,Bit8s imm) { if(!imm) return; - cache_checkinstr(2); - cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templosav, dest, 1, templo2); + gen_mov_word_to_reg_helper(templo3, dest, 1, templo2); cache_checkinstr(2); if (imm >= 0) { - cache_addw( SUB_IMM8(templosav, (Bit32s)imm) ); // sub templosav, #(imm) + cache_addw( SUB_IMM8(templo3, (Bit32s)imm) ); // sub templo3, #(imm) } else { - cache_addw( ADD_IMM8(templosav, -((Bit32s)imm)) ); // add templosav, #(-imm) + cache_addw( ADD_IMM8(templo3, -((Bit32s)imm)) ); // add templo3, #(-imm) } - gen_mov_word_from_reg_helper(templosav, dest, 1, templo2); - cache_checkinstr(2); - cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 + gen_mov_word_from_reg_helper(templo3, dest, 1, templo2); } // subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value @@ -607,20 +582,16 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { gen_sub_direct_byte(dest,(Bit8s)imm); return; } - cache_checkinstr(2); - cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templosav, dest, dword, templo2); + gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); if (dword) { gen_mov_dword_to_reg_imm(templo1, imm); } else { gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); } cache_checkinstr(2); - cache_addw( SUB_REG(templosav, templosav, templo1) ); // sub templosav, templosav, templo1 - gen_mov_word_from_reg_helper(templosav, dest, dword, templo2); - cache_checkinstr(2); - cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 + cache_addw( SUB_REG(templo3, templo3, templo1) ); // sub templo3, templo3, templo1 + gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); } // effective address calculation, destination is dest_reg @@ -673,12 +644,11 @@ static void gen_call_function_helper(void * func) { // after_call: // thumb state from now on - cache_addw( MOV_REG(FC_RETOP, HOST_a1) ); // mov FC_RETOP, a1 } // generate a call to a parameterless function static void INLINE gen_call_function_raw(void * func) { - cache_checkinstr(14); + cache_checkinstr(12); gen_call_function_helper(func); } @@ -686,13 +656,13 @@ static void INLINE gen_call_function_raw(void * func) { // note: the parameters are loaded in the architecture specific way // using the gen_load_param_ functions below static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { - cache_checkinstr(14); + cache_checkinstr(12); Bit32u proc_addr = (Bit32u)cache.pos; gen_call_function_helper(func); return proc_addr; // if proc_addr is on word boundary ((proc_addr & 0x03) == 0) - // then length of generated code is 14 bytes - // otherwise length of generated code is 12 bytes + // then length of generated code is 12 bytes + // otherwise length of generated code is 10 bytes } #if (1) @@ -723,33 +693,31 @@ static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { // jump to an address pointed at by ptr, offset is in imm static void gen_jmp_ptr(void * ptr,Bits imm=0) { - cache_checkinstr(2); - cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav - gen_mov_word_to_reg(templosav, ptr, 1); + gen_mov_word_to_reg(templo3, ptr, 1); if (imm) { gen_mov_dword_to_reg_imm(templo2, imm); cache_checkinstr(2); - cache_addw( ADD_REG(templosav, templosav, templo2) ); // add templosav, templosav, templo2 + cache_addw( ADD_REG(templo3, templo3, templo2) ); // add templo3, templo3, templo2 } #if (1) // (*ptr) should be word aligned if ((imm & 0x03) == 0) { - cache_checkinstr(8); - cache_addw( LDR_IMM(templo2, templosav, 0) ); // ldr templo2, [templosav] + cache_checkinstr(6); + cache_addw( LDR_IMM(templo2, templo3, 0) ); // ldr templo2, [templo3] } else #endif { - cache_checkinstr(26); - cache_addw( LDRB_IMM(templo2, templosav, 0) ); // ldrb templo2, [templosav] - cache_addw( LDRB_IMM(templo1, templosav, 1) ); // ldrb templo1, [templosav, #1] + cache_checkinstr(24); + cache_addw( LDRB_IMM(templo2, templo3, 0) ); // ldrb templo2, [templo3] + cache_addw( LDRB_IMM(templo1, templo3, 1) ); // ldrb templo1, [templo3, #1] cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 - cache_addw( LDRB_IMM(templo1, templosav, 2) ); // ldrb templo1, [templosav, #2] + cache_addw( LDRB_IMM(templo1, templo3, 2) ); // ldrb templo1, [templo3, #2] cache_addw( LSL_IMM(templo1, templo1, 16) ); // lsl templo1, templo1, #16 cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 - cache_addw( LDRB_IMM(templo1, templosav, 3) ); // ldrb templo1, [templosav, #3] + cache_addw( LDRB_IMM(templo1, templo3, 3) ); // ldrb templo1, [templo3, #3] cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 } @@ -757,8 +725,6 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { // increase jmp address to keep thumb state cache_addw( ADD_IMM3(templo2, templo2, 1) ); // add templo2, templo2, #1 - cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 - cache_addw( BX(templo2) ); // bx templo2 } @@ -898,8 +864,7 @@ static void gen_run_code(void) { // return from a function static void gen_return_function(void) { - cache_checkinstr(6); - cache_addw( MOV_REG(HOST_a1, FC_RETOP) ); // mov a1, FC_RETOP + cache_checkinstr(4); cache_addw(0xbc08); // pop {r3} cache_addw( BX(HOST_r3) ); // bx r3 } @@ -933,35 +898,32 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: - *(Bit16u*)pos=ADD_REG(FC_RETOP, HOST_a1, HOST_a2); // add FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(8); // b after_call (pc+8) + *(Bit16u*)pos=ADD_REG(HOST_a1, HOST_a1, HOST_a2); // add a1, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) break; case t_ORb: case t_ORw: case t_ORd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=ORR(FC_RETOP, HOST_a2); // orr FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6) + *(Bit16u*)pos=ORR(HOST_a1, HOST_a2); // orr a1, a2 + *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) break; case t_ANDb: case t_ANDw: case t_ANDd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=AND(FC_RETOP, HOST_a2); // and FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6) + *(Bit16u*)pos=AND(HOST_a1, HOST_a2); // and a1, a2 + *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) break; case t_SUBb: case t_SUBw: case t_SUBd: - *(Bit16u*)pos=SUB_REG(FC_RETOP, HOST_a1, HOST_a2); // sub FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(8); // b after_call (pc+8) + *(Bit16u*)pos=SUB_REG(HOST_a1, HOST_a1, HOST_a2); // sub a1, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) break; case t_XORb: case t_XORw: case t_XORd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=EOR(FC_RETOP, HOST_a2); // eor FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6) + *(Bit16u*)pos=EOR(HOST_a1, HOST_a2); // eor a1, a2 + *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) break; case t_CMPb: case t_CMPw: @@ -969,117 +931,107 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit16u*)pos=B_FWD(10); // b after_call (pc+10) + *(Bit16u*)pos=B_FWD(8); // b after_call (pc+8) break; case t_INCb: case t_INCw: case t_INCd: - *(Bit16u*)pos=ADD_IMM3(FC_RETOP, HOST_a1, 1); // add FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(8); // b after_call (pc+8) + *(Bit16u*)pos=ADD_IMM3(HOST_a1, HOST_a1, 1); // add a1, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) break; case t_DECb: case t_DECw: case t_DECd: - *(Bit16u*)pos=SUB_IMM3(FC_RETOP, HOST_a1, 1); // sub FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(8); // b after_call (pc+8) + *(Bit16u*)pos=SUB_IMM3(HOST_a1, HOST_a1, 1); // sub a1, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) break; case t_SHLb: case t_SHLw: case t_SHLd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=LSL_REG(FC_RETOP, HOST_a2); // lsl FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6) + *(Bit16u*)pos=LSL_REG(HOST_a1, HOST_a2); // lsl a1, a2 + *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) break; case t_SHRb: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 24); // lsr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(4); // b after_call (pc+4) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=NOP; // nop + *(Bit16u*)(pos+4)=LSR_IMM(HOST_a1, HOST_a1, 24); // lsr a1, a1, #24 + *(Bit16u*)(pos+6)=NOP; // nop + *(Bit16u*)(pos+8)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 + *(Bit16u*)(pos+10)=NOP; // nop break; case t_SHRw: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 16); // lsr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(4); // b after_call (pc+4) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=NOP; // nop + *(Bit16u*)(pos+4)=LSR_IMM(HOST_a1, HOST_a1, 16); // lsr a1, a1, #16 + *(Bit16u*)(pos+6)=NOP; // nop + *(Bit16u*)(pos+8)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 + *(Bit16u*)(pos+10)=NOP; // nop break; case t_SHRd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6) + *(Bit16u*)pos=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 + *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) break; case t_SARb: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 24); // asr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(4); // b after_call (pc+4) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=NOP; // nop + *(Bit16u*)(pos+4)=ASR_IMM(HOST_a1, HOST_a1, 24); // asr a1, a1, #24 + *(Bit16u*)(pos+6)=NOP; // nop + *(Bit16u*)(pos+8)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 + *(Bit16u*)(pos+10)=NOP; // nop break; case t_SARw: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 16); // asr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(4); // b after_call (pc+4) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=NOP; // nop + *(Bit16u*)(pos+4)=ASR_IMM(HOST_a1, HOST_a1, 16); // asr a1, a1, #16 + *(Bit16u*)(pos+6)=NOP; // nop + *(Bit16u*)(pos+8)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 + *(Bit16u*)(pos+10)=NOP; // nop break; case t_SARd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6) + *(Bit16u*)pos=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 + *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) break; case t_RORb: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+4)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP - *(Bit16u*)(pos+6)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=NOP; // nop - *(Bit16u*)(pos+12)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 + *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8 + *(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+6)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 + *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 break; case t_RORw: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=NOP; // nop - *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=NOP; // nop - *(Bit16u*)(pos+12)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 + *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 + *(Bit16u*)(pos+4)=NOP; // nop + *(Bit16u*)(pos+6)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+8)=NOP; // nop + *(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 break; case t_RORd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6) + *(Bit16u*)pos=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) break; - /*case t_ROLb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 - *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 - *(Bit16u*)(pos+8)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP - *(Bit16u*)(pos+10)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+12)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+14)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 - break;*/ case t_ROLw: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 - *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 - *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=NOP; // nop - *(Bit16u*)(pos+12)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2 + *(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 + *(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32 + *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 break; case t_ROLd: - *(Bit16u*)pos=NEG(templo1, HOST_a2); // neg templo1, a2 - *(Bit16u*)(pos+2)=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+4)=NOP; // nop - *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 - *(Bit16u*)(pos+8)=NOP; // nop - *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+12)=NOP; // nop + *(Bit16u*)pos=NEG(HOST_a2, HOST_a2); // neg a2, a2 + *(Bit16u*)(pos+2)=NOP; // nop + *(Bit16u*)(pos+4)=ADD_IMM8(HOST_a2, 32); // add a2, #32 + *(Bit16u*)(pos+6)=NOP; // nop + *(Bit16u*)(pos+8)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+10)=NOP; // nop break; case t_NEGb: case t_NEGw: case t_NEGd: - *(Bit16u*)pos=NEG(FC_RETOP, HOST_a1); // neg FC_RETOP, a1 - *(Bit16u*)(pos+2)=B_FWD(8); // b after_call (pc+8) + *(Bit16u*)pos=NEG(HOST_a1, HOST_a1); // neg a1, a1 + *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) break; default: *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 4) ) = (Bit32u)fct_ptr; // simple_func @@ -1093,35 +1045,32 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: - *(Bit16u*)pos=ADD_REG(FC_RETOP, HOST_a1, HOST_a2); // add FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) + *(Bit16u*)pos=ADD_REG(HOST_a1, HOST_a1, HOST_a2); // add a1, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) break; case t_ORb: case t_ORw: case t_ORd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=ORR(FC_RETOP, HOST_a2); // orr FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4) + *(Bit16u*)pos=ORR(HOST_a1, HOST_a2); // orr a1, a2 + *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) break; case t_ANDb: case t_ANDw: case t_ANDd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=AND(FC_RETOP, HOST_a2); // and FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4) + *(Bit16u*)pos=AND(HOST_a1, HOST_a2); // and a1, a2 + *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) break; case t_SUBb: case t_SUBw: case t_SUBd: - *(Bit16u*)pos=SUB_REG(FC_RETOP, HOST_a1, HOST_a2); // sub FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) + *(Bit16u*)pos=SUB_REG(HOST_a1, HOST_a1, HOST_a2); // sub a1, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) break; case t_XORb: case t_XORw: case t_XORd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=EOR(FC_RETOP, HOST_a2); // eor FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4) + *(Bit16u*)pos=EOR(HOST_a1, HOST_a2); // eor a1, a2 + *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) break; case t_CMPb: case t_CMPw: @@ -1129,121 +1078,85 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit16u*)pos=B_FWD(8); // b after_call (pc+8) + *(Bit16u*)pos=B_FWD(6); // b after_call (pc+6) break; case t_INCb: case t_INCw: case t_INCd: - *(Bit16u*)pos=ADD_IMM3(FC_RETOP, HOST_a1, 1); // add FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) + *(Bit16u*)pos=ADD_IMM3(HOST_a1, HOST_a1, 1); // add a1, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) break; case t_DECb: case t_DECw: case t_DECd: - *(Bit16u*)pos=SUB_IMM3(FC_RETOP, HOST_a1, 1); // sub FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) + *(Bit16u*)pos=SUB_IMM3(HOST_a1, HOST_a1, 1); // sub a1, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) break; case t_SHLb: case t_SHLw: case t_SHLd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=LSL_REG(FC_RETOP, HOST_a2); // lsl FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4) + *(Bit16u*)pos=LSL_REG(HOST_a1, HOST_a2); // lsl a1, a2 + *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) break; case t_SHRb: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 *(Bit16u*)(pos+2)=NOP; // nop - *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, FC_RETOP, 24); // lsr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=LSR_IMM(HOST_a1, HOST_a1, 24); // lsr a1, a1, #24 *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+10)=NOP; // nop + *(Bit16u*)(pos+8)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 break; case t_SHRw: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 *(Bit16u*)(pos+2)=NOP; // nop - *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, FC_RETOP, 16); // lsr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=LSR_IMM(HOST_a1, HOST_a1, 16); // lsr a1, a1, #16 *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+10)=NOP; // nop + *(Bit16u*)(pos+8)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 break; case t_SHRd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4) + *(Bit16u*)pos=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 + *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) break; case t_SARb: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 *(Bit16u*)(pos+2)=NOP; // nop - *(Bit16u*)(pos+4)=ASR_IMM(FC_RETOP, FC_RETOP, 24); // asr FC_RETOP, FC_RETOP, #24 + *(Bit16u*)(pos+4)=ASR_IMM(HOST_a1, HOST_a1, 24); // asr a1, a1, #24 *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 - *(Bit16u*)(pos+10)=NOP; // nop + *(Bit16u*)(pos+8)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 break; case t_SARw: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 *(Bit16u*)(pos+2)=NOP; // nop - *(Bit16u*)(pos+4)=ASR_IMM(FC_RETOP, FC_RETOP, 16); // asr FC_RETOP, FC_RETOP, #16 + *(Bit16u*)(pos+4)=ASR_IMM(HOST_a1, HOST_a1, 16); // asr a1, a1, #16 *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 - *(Bit16u*)(pos+10)=NOP; // nop + *(Bit16u*)(pos+8)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 break; case t_SARd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4) - break; - case t_RORb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+4)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP - *(Bit16u*)(pos+6)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 + *(Bit16u*)pos=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 + *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) break; case t_RORw: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 *(Bit16u*)(pos+4)=NOP; // nop - *(Bit16u*)(pos+6)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+8)=NOP; // nop - *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 + *(Bit16u*)(pos+6)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+8)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 break; case t_RORd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4) - break; - /*case t_ROLb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 - *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 - *(Bit16u*)(pos+8)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP - *(Bit16u*)(pos+10)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+12)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+14)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 - break;*/ - case t_ROLw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 - *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 - *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 + *(Bit16u*)pos=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) break; case t_ROLd: - *(Bit16u*)pos=NEG(templo1, HOST_a2); // neg templo1, a2 - *(Bit16u*)(pos+2)=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+4)=ADD_IMM8(templo1, 32); // add templo1, #32 + *(Bit16u*)pos=NEG(HOST_a2, HOST_a2); // neg a2, a2 + *(Bit16u*)(pos+2)=NOP; // nop + *(Bit16u*)(pos+4)=ADD_IMM8(HOST_a2, 32); // add a2, #32 *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+10)=NOP; // nop + *(Bit16u*)(pos+8)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 break; case t_NEGb: case t_NEGw: case t_NEGd: - *(Bit16u*)pos=NEG(FC_RETOP, HOST_a1); // neg FC_RETOP, a1 - *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) + *(Bit16u*)pos=NEG(HOST_a1, HOST_a1); // neg a1, a1 + *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) break; default: *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 2) ) = (Bit32u)fct_ptr; // simple_func diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h index 0c99cc3c..25056e4a 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-thumb-niw.h,v 1.4 2009-06-25 19:31:43 c2woody Exp $ */ +/* $Id: risc_armv4le-thumb-niw.h,v 1.5 2009-06-27 12:51:10 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (thumb version with data pool) */ @@ -25,15 +25,10 @@ // temporary "lo" registers #define templo1 HOST_v3 #define templo2 HOST_v4 - -// temporary "lo" register - value must be preserved when using it -#define templosav HOST_a3 - -// temporary "hi" register -#define temphi1 HOST_ip +#define templo3 HOST_v2 // register that holds function return values -#define FC_RETOP HOST_v2 +#define FC_RETOP HOST_a1 // register used for address calculations, #define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG @@ -86,8 +81,6 @@ #define ADD_IMM8(dst, imm) (0x3000 + ((dst) << 8) + (imm) ) // add dst, src1, src2 #define ADD_REG(dst, src1, src2) (0x1800 + (dst) + ((src1) << 3) + ((src2) << 6) ) -// add dst, src -#define ADD_LO_HI(dst, src) (0x4440 + (dst) + (((src) - HOST_r8) << 3) ) // add dst, pc, #imm @ 0 <= imm < 1024 & imm mod 4 = 0 #define ADD_LO_PC_IMM(dst, imm) (0xa000 + ((dst) << 8) + ((imm) >> 2) ) // sub dst, src1, src2 @@ -502,11 +495,9 @@ static void gen_extend_word(bool sign,HostReg reg) { // add a 32bit value from memory to a full register static void gen_add(HostReg reg,void* op) { + gen_mov_word_to_reg(templo3, op, 1); cache_checkinstr(2); - cache_addw( MOV_HI_LO(temphi1, reg) ); // mov temphi1, reg - gen_mov_word_to_reg(reg, op, 1); - cache_checkinstr(2); - cache_addw( ADD_LO_HI(reg, temphi1) ); // add reg, temphi1 + cache_addw( ADD_REG(reg, reg, templo3) ); // add reg, reg, templo3 } // add a 32bit constant value to a full register @@ -528,12 +519,8 @@ static void gen_and_imm(HostReg reg,Bit32u imm) { // move a 32bit constant value into memory static void gen_mov_direct_dword(void* dest,Bit32u imm) { - cache_checkinstr(2); - cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav - gen_mov_dword_to_reg_imm(templosav, imm); - gen_mov_word_from_reg(templosav, dest, 1); - cache_checkinstr(2); - cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 + gen_mov_dword_to_reg_imm(templo3, imm); + gen_mov_word_from_reg(templo3, dest, 1); } // move an address into memory @@ -544,19 +531,15 @@ static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { // add an 8bit constant value to a dword memory value static void gen_add_direct_byte(void* dest,Bit8s imm) { if(!imm) return; - cache_checkinstr(2); - cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templosav, dest, 1, templo2); + gen_mov_word_to_reg_helper(templo3, dest, 1, templo2); cache_checkinstr(2); if (imm >= 0) { - cache_addw( ADD_IMM8(templosav, (Bit32s)imm) ); // add templosav, #(imm) + cache_addw( ADD_IMM8(templo3, (Bit32s)imm) ); // add templo3, #(imm) } else { - cache_addw( SUB_IMM8(templosav, -((Bit32s)imm)) ); // sub templosav, #(-imm) + cache_addw( SUB_IMM8(templo3, -((Bit32s)imm)) ); // sub templo3, #(-imm) } - gen_mov_word_from_reg_helper(templosav, dest, 1, templo2); - cache_checkinstr(2); - cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 + gen_mov_word_from_reg_helper(templo3, dest, 1, templo2); } // add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value @@ -566,38 +549,30 @@ static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { gen_add_direct_byte(dest,(Bit8s)imm); return; } - cache_checkinstr(2); - cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templosav, dest, dword, templo2); + gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); if (dword) { gen_mov_dword_to_reg_imm(templo1, imm); } else { gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); } cache_checkinstr(2); - cache_addw( ADD_REG(templosav, templosav, templo1) ); // add templosav, templosav, templo1 - gen_mov_word_from_reg_helper(templosav, dest, dword, templo2); - cache_checkinstr(2); - cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 + cache_addw( ADD_REG(templo3, templo3, templo1) ); // add templo3, templo3, templo1 + gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); } // subtract an 8bit constant value from a dword memory value static void gen_sub_direct_byte(void* dest,Bit8s imm) { if(!imm) return; - cache_checkinstr(2); - cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templosav, dest, 1, templo2); + gen_mov_word_to_reg_helper(templo3, dest, 1, templo2); cache_checkinstr(2); if (imm >= 0) { - cache_addw( SUB_IMM8(templosav, (Bit32s)imm) ); // sub templosav, #(imm) + cache_addw( SUB_IMM8(templo3, (Bit32s)imm) ); // sub templo3, #(imm) } else { - cache_addw( ADD_IMM8(templosav, -((Bit32s)imm)) ); // add templosav, #(-imm) + cache_addw( ADD_IMM8(templo3, -((Bit32s)imm)) ); // add templo3, #(-imm) } - gen_mov_word_from_reg_helper(templosav, dest, 1, templo2); - cache_checkinstr(2); - cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 + gen_mov_word_from_reg_helper(templo3, dest, 1, templo2); } // subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value @@ -607,20 +582,16 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { gen_sub_direct_byte(dest,(Bit8s)imm); return; } - cache_checkinstr(2); - cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templosav, dest, dword, templo2); + gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); if (dword) { gen_mov_dword_to_reg_imm(templo1, imm); } else { gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); } cache_checkinstr(2); - cache_addw( SUB_REG(templosav, templosav, templo1) ); // sub templosav, templosav, templo1 - gen_mov_word_from_reg_helper(templosav, dest, dword, templo2); - cache_checkinstr(2); - cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 + cache_addw( SUB_REG(templo3, templo3, templo1) ); // sub templo3, templo3, templo1 + gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); } // effective address calculation, destination is dest_reg @@ -675,12 +646,11 @@ static void gen_call_function_helper(void * func) { cache_addd(0xe12fff10 + (templo1)); // bx templo1 // thumb state from now on - cache_addw( MOV_REG(FC_RETOP, HOST_a1) ); // mov FC_RETOP, a1 } // generate a call to a parameterless function static void INLINE gen_call_function_raw(void * func) { - cache_checkinstr(20); + cache_checkinstr(18); gen_call_function_helper(func); } @@ -688,13 +658,13 @@ static void INLINE gen_call_function_raw(void * func) { // note: the parameters are loaded in the architecture specific way // using the gen_load_param_ functions below static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { - cache_checkinstr(20); + cache_checkinstr(18); Bit32u proc_addr = (Bit32u)cache.pos; gen_call_function_helper(func); return proc_addr; // if proc_addr is on word boundary ((proc_addr & 0x03) == 0) - // then length of generated code is 18 bytes - // otherwise length of generated code is 20 bytes + // then length of generated code is 16 bytes + // otherwise length of generated code is 18 bytes } #if (1) @@ -725,33 +695,31 @@ static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { // jump to an address pointed at by ptr, offset is in imm static void gen_jmp_ptr(void * ptr,Bits imm=0) { - cache_checkinstr(2); - cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav - gen_mov_word_to_reg(templosav, ptr, 1); + gen_mov_word_to_reg(templo3, ptr, 1); if (imm) { gen_mov_dword_to_reg_imm(templo2, imm); cache_checkinstr(2); - cache_addw( ADD_REG(templosav, templosav, templo2) ); // add templosav, templosav, templo2 + cache_addw( ADD_REG(templo3, templo3, templo2) ); // add templo3, templo3, templo2 } #if (1) // (*ptr) should be word aligned if ((imm & 0x03) == 0) { - cache_checkinstr(8); - cache_addw( LDR_IMM(templo2, templosav, 0) ); // ldr templo2, [templosav] + cache_checkinstr(6); + cache_addw( LDR_IMM(templo2, templo3, 0) ); // ldr templo2, [templo3] } else #endif { - cache_checkinstr(26); - cache_addw( LDRB_IMM(templo2, templosav, 0) ); // ldrb templo2, [templosav] - cache_addw( LDRB_IMM(templo1, templosav, 1) ); // ldrb templo1, [templosav, #1] + cache_checkinstr(24); + cache_addw( LDRB_IMM(templo2, templo3, 0) ); // ldrb templo2, [templo3] + cache_addw( LDRB_IMM(templo1, templo3, 1) ); // ldrb templo1, [templo3, #1] cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 - cache_addw( LDRB_IMM(templo1, templosav, 2) ); // ldrb templo1, [templosav, #2] + cache_addw( LDRB_IMM(templo1, templo3, 2) ); // ldrb templo1, [templo3, #2] cache_addw( LSL_IMM(templo1, templo1, 16) ); // lsl templo1, templo1, #16 cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 - cache_addw( LDRB_IMM(templo1, templosav, 3) ); // ldrb templo1, [templosav, #3] + cache_addw( LDRB_IMM(templo1, templo3, 3) ); // ldrb templo1, [templo3, #3] cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 } @@ -759,8 +727,6 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { // increase jmp address to keep thumb state cache_addw( ADD_IMM3(templo2, templo2, 1) ); // add templo2, templo2, #1 - cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 - cache_addw( BX(templo2) ); // bx templo2 } @@ -900,8 +866,7 @@ static void gen_run_code(void) { // return from a function static void gen_return_function(void) { - cache_checkinstr(6); - cache_addw( MOV_REG(HOST_a1, FC_RETOP) ); // mov a1, FC_RETOP + cache_checkinstr(4); cache_addw(0xbc08); // pop {r3} cache_addw( BX(HOST_r3) ); // bx r3 } @@ -935,35 +900,32 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: - *(Bit16u*)pos=ADD_REG(FC_RETOP, HOST_a1, HOST_a2); // add FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) + *(Bit16u*)pos=ADD_REG(HOST_a1, HOST_a1, HOST_a2); // add a1, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) break; case t_ORb: case t_ORw: case t_ORd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=ORR(FC_RETOP, HOST_a2); // orr FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10) + *(Bit16u*)pos=ORR(HOST_a1, HOST_a2); // orr a1, a2 + *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) break; case t_ANDb: case t_ANDw: case t_ANDd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=AND(FC_RETOP, HOST_a2); // and FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10) + *(Bit16u*)pos=AND(HOST_a1, HOST_a2); // and a1, a2 + *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) break; case t_SUBb: case t_SUBw: case t_SUBd: - *(Bit16u*)pos=SUB_REG(FC_RETOP, HOST_a1, HOST_a2); // sub FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) + *(Bit16u*)pos=SUB_REG(HOST_a1, HOST_a1, HOST_a2); // sub a1, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) break; case t_XORb: case t_XORw: case t_XORd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=EOR(FC_RETOP, HOST_a2); // eor FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10) + *(Bit16u*)pos=EOR(HOST_a1, HOST_a2); // eor a1, a2 + *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) break; case t_CMPb: case t_CMPw: @@ -971,118 +933,110 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit16u*)pos=B_FWD(14); // b after_call (pc+14) + *(Bit16u*)pos=B_FWD(12); // b after_call (pc+12) break; case t_INCb: case t_INCw: case t_INCd: - *(Bit16u*)pos=ADD_IMM3(FC_RETOP, HOST_a1, 1); // add FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) + *(Bit16u*)pos=ADD_IMM3(HOST_a1, HOST_a1, 1); // add a1, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) break; case t_DECb: case t_DECw: case t_DECd: - *(Bit16u*)pos=SUB_IMM3(FC_RETOP, HOST_a1, 1); // sub FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) + *(Bit16u*)pos=SUB_IMM3(HOST_a1, HOST_a1, 1); // sub a1, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) break; case t_SHLb: case t_SHLw: case t_SHLd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=LSL_REG(FC_RETOP, HOST_a2); // lsl FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10) + *(Bit16u*)pos=LSL_REG(HOST_a1, HOST_a2); // lsl a1, a2 + *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) break; case t_SHRb: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 24); // lsr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 24); // lsr a1, a1, #24 + *(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 + *(Bit16u*)(pos+6)=B_FWD(6); // b after_call (pc+6) break; case t_SHRw: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 16); // lsr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 16); // lsr a1, a1, #16 + *(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 + *(Bit16u*)(pos+6)=B_FWD(6); // b after_call (pc+6) break; case t_SHRd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10) + *(Bit16u*)pos=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 + *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) break; case t_SARb: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 24); // asr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 24); // asr a1, a1, #24 + *(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 + *(Bit16u*)(pos+6)=B_FWD(6); // b after_call (pc+6) break; case t_SARw: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 16); // asr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 16); // asr a1, a1, #16 + *(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 + *(Bit16u*)(pos+6)=B_FWD(6); // b after_call (pc+6) break; case t_SARd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10) + *(Bit16u*)pos=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 + *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) break; case t_RORb: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+4)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP + *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8 + *(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1 *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+8)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 *(Bit16u*)(pos+10)=NOP; // nop - *(Bit16u*)(pos+12)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+14)=NOP; // nop - *(Bit16u*)(pos+16)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 + *(Bit16u*)(pos+12)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+14)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 break; case t_RORw: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+4)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 - *(Bit16u*)(pos+8)=B_FWD(6); // b after_call (pc+6) + *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 + *(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+6)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+8)=B_FWD(4); // b after_call (pc+4) break; case t_RORd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10) + *(Bit16u*)pos=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) break; case t_ROLb: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 - *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 - *(Bit16u*)(pos+8)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP - *(Bit16u*)(pos+10)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+12)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+14)=NOP; // nop - *(Bit16u*)(pos+16)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2 + *(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8 + *(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32 + *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+10)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 + *(Bit16u*)(pos+12)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+14)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 break; case t_ROLw: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 - *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 - *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 + *(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2 + *(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 + *(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32 + *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 *(Bit16u*)(pos+10)=NOP; // nop - *(Bit16u*)(pos+12)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+12)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 *(Bit16u*)(pos+14)=NOP; // nop - *(Bit16u*)(pos+16)=NOP; // nop break; case t_ROLd: - *(Bit16u*)pos=NEG(templo1, HOST_a2); // neg templo1, a2 - *(Bit16u*)(pos+2)=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+4)=ADD_IMM8(templo1, 32); // add templo1, #32 - *(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+8)=B_FWD(6); // b after_call (pc+6) + *(Bit16u*)pos=NEG(HOST_a2, HOST_a2); // neg a2, a2 + *(Bit16u*)(pos+2)=ADD_IMM8(HOST_a2, 32); // add a2, #32 + *(Bit16u*)(pos+4)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+6)=B_FWD(6); // b after_call (pc+6) break; case t_NEGb: case t_NEGw: case t_NEGd: - *(Bit16u*)pos=NEG(FC_RETOP, HOST_a1); // neg FC_RETOP, a1 - *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) + *(Bit16u*)pos=NEG(HOST_a1, HOST_a1); // neg a1, a1 + *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) break; default: *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 4) ) = (Bit32u)fct_ptr; // simple_func @@ -1096,35 +1050,32 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: - *(Bit16u*)pos=ADD_REG(FC_RETOP, HOST_a1, HOST_a2); // add FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) + *(Bit16u*)pos=ADD_REG(HOST_a1, HOST_a1, HOST_a2); // add a1, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) break; case t_ORb: case t_ORw: case t_ORd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=ORR(FC_RETOP, HOST_a2); // orr FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12) + *(Bit16u*)pos=ORR(HOST_a1, HOST_a2); // orr a1, a2 + *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) break; case t_ANDb: case t_ANDw: case t_ANDd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=AND(FC_RETOP, HOST_a2); // and FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12) + *(Bit16u*)pos=AND(HOST_a1, HOST_a2); // and a1, a2 + *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) break; case t_SUBb: case t_SUBw: case t_SUBd: - *(Bit16u*)pos=SUB_REG(FC_RETOP, HOST_a1, HOST_a2); // sub FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) + *(Bit16u*)pos=SUB_REG(HOST_a1, HOST_a1, HOST_a2); // sub a1, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) break; case t_XORb: case t_XORw: case t_XORd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=EOR(FC_RETOP, HOST_a2); // eor FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12) + *(Bit16u*)pos=EOR(HOST_a1, HOST_a2); // eor a1, a2 + *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) break; case t_CMPb: case t_CMPw: @@ -1132,115 +1083,113 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit16u*)pos=B_FWD(16); // b after_call (pc+16) + *(Bit16u*)pos=B_FWD(14); // b after_call (pc+14) break; case t_INCb: case t_INCw: case t_INCd: - *(Bit16u*)pos=ADD_IMM3(FC_RETOP, HOST_a1, 1); // add FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) + *(Bit16u*)pos=ADD_IMM3(HOST_a1, HOST_a1, 1); // add a1, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) break; case t_DECb: case t_DECw: case t_DECd: - *(Bit16u*)pos=SUB_IMM3(FC_RETOP, HOST_a1, 1); // sub FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) + *(Bit16u*)pos=SUB_IMM3(HOST_a1, HOST_a1, 1); // sub a1, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) break; case t_SHLb: case t_SHLw: case t_SHLd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=LSL_REG(FC_RETOP, HOST_a2); // lsl FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12) + *(Bit16u*)pos=LSL_REG(HOST_a1, HOST_a2); // lsl a1, a2 + *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) break; case t_SHRb: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 24); // lsr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 24); // lsr a1, a1, #24 + *(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 + *(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8) break; case t_SHRw: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 16); // lsr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 16); // lsr a1, a1, #16 + *(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 + *(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8) break; case t_SHRd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12) + *(Bit16u*)pos=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 + *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) break; case t_SARb: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 24); // asr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 24); // asr a1, a1, #24 + *(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 + *(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8) break; case t_SARw: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 16); // asr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 16); // asr a1, a1, #16 + *(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 + *(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8) break; case t_SARd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12) + *(Bit16u*)pos=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 + *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) break; case t_RORb: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+4)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP - *(Bit16u*)(pos+6)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 - *(Bit16u*)(pos+12)=B_FWD(4); // b after_call (pc+4) + *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8 + *(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+6)=NOP; // nop + *(Bit16u*)(pos+8)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 + *(Bit16u*)(pos+10)=NOP; // nop + *(Bit16u*)(pos+12)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+14)=NOP; // nop + *(Bit16u*)(pos+16)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 break; case t_RORw: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+4)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 - *(Bit16u*)(pos+8)=B_FWD(8); // b after_call (pc+8) + *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 + *(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+6)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+8)=B_FWD(6); // b after_call (pc+6) break; case t_RORd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12) + *(Bit16u*)pos=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) break; case t_ROLb: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 - *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 - *(Bit16u*)(pos+8)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP - *(Bit16u*)(pos+10)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+12)=NOP; // nop - *(Bit16u*)(pos+14)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+16)=NOP; // nop - *(Bit16u*)(pos+18)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2 + *(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8 + *(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32 + *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+10)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 + *(Bit16u*)(pos+12)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+14)=NOP; // nop + *(Bit16u*)(pos+16)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 break; case t_ROLw: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 - *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 - *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+12)=B_FWD(4); // b after_call (pc+4) + *(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2 + *(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 + *(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32 + *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+10)=NOP; // nop + *(Bit16u*)(pos+12)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+14)=NOP; // nop + *(Bit16u*)(pos+16)=NOP; // nop break; case t_ROLd: - *(Bit16u*)pos=NEG(templo1, HOST_a2); // neg templo1, a2 - *(Bit16u*)(pos+2)=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+4)=ADD_IMM8(templo1, 32); // add templo1, #32 - *(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+8)=B_FWD(8); // b after_call (pc+8) + *(Bit16u*)pos=NEG(HOST_a2, HOST_a2); // neg a2, a2 + *(Bit16u*)(pos+2)=ADD_IMM8(HOST_a2, 32); // add a2, #32 + *(Bit16u*)(pos+4)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8) break; case t_NEGb: case t_NEGw: case t_NEGd: - *(Bit16u*)pos=NEG(FC_RETOP, HOST_a1); // neg FC_RETOP, a1 - *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) + *(Bit16u*)pos=NEG(HOST_a1, HOST_a1); // neg a1, a1 + *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) break; default: *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 2) ) = (Bit32u)fct_ptr; // simple_func diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb.h b/src/cpu/core_dynrec/risc_armv4le-thumb.h index 37ae9c12..49a6e879 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-thumb.h,v 1.5 2009-06-25 19:31:43 c2woody Exp $ */ +/* $Id: risc_armv4le-thumb.h,v 1.6 2009-06-27 12:51:10 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (thumb version) */ @@ -25,15 +25,10 @@ // temporary "lo" registers #define templo1 HOST_v3 #define templo2 HOST_v4 - -// temporary "lo" register - value must be preserved when using it -#define templosav HOST_a3 - -// temporary "hi" register -#define temphi1 HOST_ip +#define templo3 HOST_v2 // register that holds function return values -#define FC_RETOP HOST_v2 +#define FC_RETOP HOST_a1 // register used for address calculations, #define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG @@ -86,8 +81,6 @@ #define ADD_IMM8(dst, imm) (0x3000 + ((dst) << 8) + (imm) ) // add dst, src1, src2 #define ADD_REG(dst, src1, src2) (0x1800 + (dst) + ((src1) << 3) + ((src2) << 6) ) -// add dst, src -#define ADD_LO_HI(dst, src) (0x4440 + (dst) + (((src) - HOST_r8) << 3) ) // add dst, pc, #imm @ 0 <= imm < 1024 & imm mod 4 = 0 #define ADD_LO_PC_IMM(dst, imm) (0xa000 + ((dst) << 8) + ((imm) >> 2) ) // sub dst, src1, src2 @@ -364,9 +357,8 @@ static void gen_extend_word(bool sign,HostReg reg) { // add a 32bit value from memory to a full register static void gen_add(HostReg reg,void* op) { - cache_addw( MOV_HI_LO(temphi1, reg) ); // mov temphi1, reg - gen_mov_word_to_reg(reg, op, 1); - cache_addw( ADD_LO_HI(reg, temphi1) ); // add reg, temphi1 + gen_mov_word_to_reg(templo3, op, 1); + cache_addw( ADD_REG(reg, reg, templo3) ); // add reg, reg, templo3 } // add a 32bit constant value to a full register @@ -386,10 +378,8 @@ static void gen_and_imm(HostReg reg,Bit32u imm) { // move a 32bit constant value into memory static void gen_mov_direct_dword(void* dest,Bit32u imm) { - cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav - gen_mov_dword_to_reg_imm(templosav, imm); - gen_mov_word_from_reg(templosav, dest, 1); - cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 + gen_mov_dword_to_reg_imm(templo3, imm); + gen_mov_word_from_reg(templo3, dest, 1); } // move an address into memory @@ -400,16 +390,14 @@ static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { // add an 8bit constant value to a dword memory value static void gen_add_direct_byte(void* dest,Bit8s imm) { if(!imm) return; - cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templosav, dest, 1, templo2); + gen_mov_word_to_reg_helper(templo3, dest, 1, templo2); if (imm >= 0) { - cache_addw( ADD_IMM8(templosav, (Bit32s)imm) ); // add templosav, #(imm) + cache_addw( ADD_IMM8(templo3, (Bit32s)imm) ); // add templo3, #(imm) } else { - cache_addw( SUB_IMM8(templosav, -((Bit32s)imm)) ); // sub templosav, #(-imm) + cache_addw( SUB_IMM8(templo3, -((Bit32s)imm)) ); // sub templo3, #(-imm) } - gen_mov_word_from_reg_helper(templosav, dest, 1, templo2); - cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 + gen_mov_word_from_reg_helper(templo3, dest, 1, templo2); } // add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value @@ -419,32 +407,28 @@ static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { gen_add_direct_byte(dest,(Bit8s)imm); return; } - cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templosav, dest, dword, templo2); + gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); if (dword) { gen_mov_dword_to_reg_imm(templo1, imm); } else { gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); } - cache_addw( ADD_REG(templosav, templosav, templo1) ); // add templosav, templosav, templo1 - gen_mov_word_from_reg_helper(templosav, dest, dword, templo2); - cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 + cache_addw( ADD_REG(templo3, templo3, templo1) ); // add templo3, templo3, templo1 + gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); } // subtract an 8bit constant value from a dword memory value static void gen_sub_direct_byte(void* dest,Bit8s imm) { if(!imm) return; - cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templosav, dest, 1, templo2); + gen_mov_word_to_reg_helper(templo3, dest, 1, templo2); if (imm >= 0) { - cache_addw( SUB_IMM8(templosav, (Bit32s)imm) ); // sub templosav, #(imm) + cache_addw( SUB_IMM8(templo3, (Bit32s)imm) ); // sub templo3, #(imm) } else { - cache_addw( ADD_IMM8(templosav, -((Bit32s)imm)) ); // add templosav, #(-imm) + cache_addw( ADD_IMM8(templo3, -((Bit32s)imm)) ); // add templo3, #(-imm) } - gen_mov_word_from_reg_helper(templosav, dest, 1, templo2); - cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 + gen_mov_word_from_reg_helper(templo3, dest, 1, templo2); } // subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value @@ -454,17 +438,15 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { gen_sub_direct_byte(dest,(Bit8s)imm); return; } - cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templosav, dest, dword, templo2); + gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); if (dword) { gen_mov_dword_to_reg_imm(templo1, imm); } else { gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); } - cache_addw( SUB_REG(templosav, templosav, templo1) ); // sub templosav, templosav, templo1 - gen_mov_word_from_reg_helper(templosav, dest, dword, templo2); - cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 + cache_addw( SUB_REG(templo3, templo3, templo1) ); // sub templo3, templo3, templo1 + gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); } // effective address calculation, destination is dest_reg @@ -512,7 +494,6 @@ static void INLINE gen_call_function_raw(void * func) { cache_addd(0xe12fff10 + (templo1)); // bx templo1 // thumb state from now on - cache_addw( MOV_REG(FC_RETOP, HOST_a1) ); // mov FC_RETOP, a1 } // generate a call to a function with paramcount parameters @@ -523,8 +504,8 @@ static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fa gen_call_function_raw(func); return proc_addr; // if proc_addr is on word boundary ((proc_addr & 0x03) == 0) - // then length of generated code is 22 bytes - // otherwise length of generated code is 24 bytes + // then length of generated code is 20 bytes + // otherwise length of generated code is 22 bytes } #if (1) @@ -555,29 +536,28 @@ static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { // jump to an address pointed at by ptr, offset is in imm static void gen_jmp_ptr(void * ptr,Bits imm=0) { - cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav - gen_mov_word_to_reg(templosav, ptr, 1); + gen_mov_word_to_reg(templo3, ptr, 1); if (imm) { gen_mov_dword_to_reg_imm(templo2, imm); - cache_addw( ADD_REG(templosav, templosav, templo2) ); // add templosav, templosav, templo2 + cache_addw( ADD_REG(templo3, templo3, templo2) ); // add templo3, templo3, templo2 } #if (1) // (*ptr) should be word aligned if ((imm & 0x03) == 0) { - cache_addw( LDR_IMM(templo2, templosav, 0) ); // ldr templo2, [templosav] + cache_addw( LDR_IMM(templo2, templo3, 0) ); // ldr templo2, [templo3] } else #endif { - cache_addw( LDRB_IMM(templo2, templosav, 0) ); // ldrb templo2, [templosav] - cache_addw( LDRB_IMM(templo1, templosav, 1) ); // ldrb templo1, [templosav, #1] + cache_addw( LDRB_IMM(templo2, templo3, 0) ); // ldrb templo2, [templo3] + cache_addw( LDRB_IMM(templo1, templo3, 1) ); // ldrb templo1, [templo3, #1] cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 - cache_addw( LDRB_IMM(templo1, templosav, 2) ); // ldrb templo1, [templosav, #2] + cache_addw( LDRB_IMM(templo1, templo3, 2) ); // ldrb templo1, [templo3, #2] cache_addw( LSL_IMM(templo1, templo1, 16) ); // lsl templo1, templo1, #16 cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 - cache_addw( LDRB_IMM(templo1, templosav, 3) ); // ldrb templo1, [templosav, #3] + cache_addw( LDRB_IMM(templo1, templo3, 3) ); // ldrb templo1, [templo3, #3] cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 } @@ -585,8 +565,6 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { // increase jmp address to keep thumb state cache_addw( ADD_IMM3(templo2, templo2, 1) ); // add templo2, templo2, #1 - cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1 - cache_addw( BX(templo2) ); // bx templo2 } @@ -721,7 +699,6 @@ static void gen_run_code(void) { // return from a function static void gen_return_function(void) { - cache_addw( MOV_REG(HOST_a1, FC_RETOP) ); // mov a1, FC_RETOP cache_addw(0xbc08); // pop {r3} cache_addw( BX(HOST_r3) ); // bx r3 } @@ -739,35 +716,32 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: - *(Bit16u*)pos=ADD_REG(FC_RETOP, HOST_a1, HOST_a2); // add FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) + *(Bit16u*)pos=ADD_REG(HOST_a1, HOST_a1, HOST_a2); // add a1, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) break; case t_ORb: case t_ORw: case t_ORd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=ORR(FC_RETOP, HOST_a2); // orr FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14) + *(Bit16u*)pos=ORR(HOST_a1, HOST_a2); // orr a1, a2 + *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) break; case t_ANDb: case t_ANDw: case t_ANDd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=AND(FC_RETOP, HOST_a2); // and FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14) + *(Bit16u*)pos=AND(HOST_a1, HOST_a2); // and a1, a2 + *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) break; case t_SUBb: case t_SUBw: case t_SUBd: - *(Bit16u*)pos=SUB_REG(FC_RETOP, HOST_a1, HOST_a2); // sub FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) + *(Bit16u*)pos=SUB_REG(HOST_a1, HOST_a1, HOST_a2); // sub a1, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) break; case t_XORb: case t_XORw: case t_XORd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=EOR(FC_RETOP, HOST_a2); // eor FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14) + *(Bit16u*)pos=EOR(HOST_a1, HOST_a2); // eor a1, a2 + *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) break; case t_CMPb: case t_CMPw: @@ -775,116 +749,110 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit16u*)pos=B_FWD(18); // b after_call (pc+18) + *(Bit16u*)pos=B_FWD(16); // b after_call (pc+16) break; case t_INCb: case t_INCw: case t_INCd: - *(Bit16u*)pos=ADD_IMM3(FC_RETOP, HOST_a1, 1); // add FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) + *(Bit16u*)pos=ADD_IMM3(HOST_a1, HOST_a1, 1); // add a1, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) break; case t_DECb: case t_DECw: case t_DECd: - *(Bit16u*)pos=SUB_IMM3(FC_RETOP, HOST_a1, 1); // sub FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) + *(Bit16u*)pos=SUB_IMM3(HOST_a1, HOST_a1, 1); // sub a1, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) break; case t_SHLb: case t_SHLw: case t_SHLd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=LSL_REG(FC_RETOP, HOST_a2); // lsl FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14) + *(Bit16u*)pos=LSL_REG(HOST_a1, HOST_a2); // lsl a1, a2 + *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) break; case t_SHRb: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 24); // lsr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 24); // lsr a1, a1, #24 + *(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 + *(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10) break; case t_SHRw: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 16); // lsr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 16); // lsr a1, a1, #16 + *(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 + *(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10) break; case t_SHRd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14) + *(Bit16u*)pos=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 + *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) break; case t_SARb: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 24); // asr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 24); // asr a1, a1, #24 + *(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 + *(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10) break; case t_SARw: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 16); // asr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 16); // asr a1, a1, #16 + *(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 + *(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10) break; case t_SARd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14) + *(Bit16u*)pos=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 + *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) break; case t_RORb: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+4)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP - *(Bit16u*)(pos+6)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 - *(Bit16u*)(pos+12)=B_FWD(6); // b after_call (pc+6) + *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8 + *(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+6)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 + *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+12)=B_FWD(4); // b after_call (pc+4) break; case t_RORw: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+4)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 - *(Bit16u*)(pos+8)=B_FWD(10); // b after_call (pc+10) + *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 + *(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+6)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+8)=B_FWD(8); // b after_call (pc+8) break; case t_RORd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14) + *(Bit16u*)pos=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) break; case t_ROLb: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 - *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 - *(Bit16u*)(pos+8)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP + *(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2 + *(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8 + *(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32 + *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 *(Bit16u*)(pos+10)=NOP; // nop - *(Bit16u*)(pos+12)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 + *(Bit16u*)(pos+12)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 *(Bit16u*)(pos+14)=NOP; // nop - *(Bit16u*)(pos+16)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+18)=NOP; // nop - *(Bit16u*)(pos+20)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 + *(Bit16u*)(pos+16)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+18)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 break; case t_ROLw: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 - *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 - *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+12)=B_FWD(6); // b after_call (pc+6) + *(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2 + *(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 + *(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32 + *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+12)=B_FWD(4); // b after_call (pc+4) break; case t_ROLd: - *(Bit16u*)pos=NEG(templo1, HOST_a2); // neg templo1, a2 - *(Bit16u*)(pos+2)=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+4)=ADD_IMM8(templo1, 32); // add templo1, #32 - *(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+8)=B_FWD(10); // b after_call (pc+10) + *(Bit16u*)pos=NEG(HOST_a2, HOST_a2); // neg a2, a2 + *(Bit16u*)(pos+2)=ADD_IMM8(HOST_a2, 32); // add a2, #32 + *(Bit16u*)(pos+4)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10) break; case t_NEGb: case t_NEGw: case t_NEGd: - *(Bit16u*)pos=NEG(FC_RETOP, HOST_a1); // neg FC_RETOP, a1 - *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) + *(Bit16u*)pos=NEG(HOST_a1, HOST_a1); // neg a1, a1 + *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) break; default: *(Bit32u*)(pos+8)=(Bit32u)fct_ptr; // simple_func @@ -898,35 +866,32 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: - *(Bit16u*)pos=ADD_REG(FC_RETOP, HOST_a1, HOST_a2); // add FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(18); // b after_call (pc+18) + *(Bit16u*)pos=ADD_REG(HOST_a1, HOST_a1, HOST_a2); // add a1, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) break; case t_ORb: case t_ORw: case t_ORd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=ORR(FC_RETOP, HOST_a2); // orr FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16) + *(Bit16u*)pos=ORR(HOST_a1, HOST_a2); // orr a1, a2 + *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) break; case t_ANDb: case t_ANDw: case t_ANDd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=AND(FC_RETOP, HOST_a2); // and FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16) + *(Bit16u*)pos=AND(HOST_a1, HOST_a2); // and a1, a2 + *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) break; case t_SUBb: case t_SUBw: case t_SUBd: - *(Bit16u*)pos=SUB_REG(FC_RETOP, HOST_a1, HOST_a2); // sub FC_RETOP, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(18); // b after_call (pc+18) + *(Bit16u*)pos=SUB_REG(HOST_a1, HOST_a1, HOST_a2); // sub a1, a1, a2 + *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) break; case t_XORb: case t_XORw: case t_XORd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=EOR(FC_RETOP, HOST_a2); // eor FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16) + *(Bit16u*)pos=EOR(HOST_a1, HOST_a2); // eor a1, a2 + *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) break; case t_CMPb: case t_CMPw: @@ -934,114 +899,111 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit16u*)pos=B_FWD(20); // b after_call (pc+20) + *(Bit16u*)pos=B_FWD(18); // b after_call (pc+18) break; case t_INCb: case t_INCw: case t_INCd: - *(Bit16u*)pos=ADD_IMM3(FC_RETOP, HOST_a1, 1); // add FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(18); // b after_call (pc+18) + *(Bit16u*)pos=ADD_IMM3(HOST_a1, HOST_a1, 1); // add a1, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) break; case t_DECb: case t_DECw: case t_DECd: - *(Bit16u*)pos=SUB_IMM3(FC_RETOP, HOST_a1, 1); // sub FC_RETOP, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(18); // b after_call (pc+18) + *(Bit16u*)pos=SUB_IMM3(HOST_a1, HOST_a1, 1); // sub a1, a1, #1 + *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) break; case t_SHLb: case t_SHLw: case t_SHLd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=LSL_REG(FC_RETOP, HOST_a2); // lsl FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16) + *(Bit16u*)pos=LSL_REG(HOST_a1, HOST_a2); // lsl a1, a2 + *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) break; case t_SHRb: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 24); // lsr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(14); // b after_call (pc+14) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 24); // lsr a1, a1, #24 + *(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 + *(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12) break; case t_SHRw: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 16); // lsr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(14); // b after_call (pc+14) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 16); // lsr a1, a1, #16 + *(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 + *(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12) break; case t_SHRd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16) + *(Bit16u*)pos=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 + *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) break; case t_SARb: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24 - *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 24); // asr FC_RETOP, FC_RETOP, #24 - *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(14); // b after_call (pc+14) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 + *(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 24); // asr a1, a1, #24 + *(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 + *(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12) break; case t_SARw: - *(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16 - *(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 16); // asr FC_RETOP, FC_RETOP, #16 - *(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 - *(Bit16u*)(pos+6)=B_FWD(14); // b after_call (pc+14) + *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 + *(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 16); // asr a1, a1, #16 + *(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 + *(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12) break; case t_SARd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16) + *(Bit16u*)pos=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 + *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) break; case t_RORb: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+4)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP - *(Bit16u*)(pos+6)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 - *(Bit16u*)(pos+12)=B_FWD(8); // b after_call (pc+8) + *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8 + *(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+6)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 + *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+12)=B_FWD(6); // b after_call (pc+6) break; case t_RORw: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+4)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 - *(Bit16u*)(pos+8)=B_FWD(12); // b after_call (pc+12) + *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 + *(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+6)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+8)=B_FWD(10); // b after_call (pc+10) break; case t_RORd: - *(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+2)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2 - *(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16) + *(Bit16u*)pos=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) break; case t_ROLb: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 - *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8 - *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 - *(Bit16u*)(pos+8)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP - *(Bit16u*)(pos+10)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+12)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+14)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+16)=B_FWD(4); // b after_call (pc+4) + *(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2 + *(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8 + *(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32 + *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+10)=NOP; // nop + *(Bit16u*)(pos+12)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 + *(Bit16u*)(pos+14)=NOP; // nop + *(Bit16u*)(pos+16)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+18)=NOP; // nop + *(Bit16u*)(pos+20)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 break; case t_ROLw: *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2 - *(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16 - *(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32 - *(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1 - *(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+12)=B_FWD(8); // b after_call (pc+8) + *(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2 + *(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 + *(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32 + *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 + *(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+12)=B_FWD(6); // b after_call (pc+6) break; case t_ROLd: - *(Bit16u*)pos=NEG(templo1, HOST_a2); // neg templo1, a2 - *(Bit16u*)(pos+2)=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1 - *(Bit16u*)(pos+4)=ADD_IMM8(templo1, 32); // add templo1, #32 - *(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1 - *(Bit16u*)(pos+8)=B_FWD(12); // b after_call (pc+12) + *(Bit16u*)pos=NEG(HOST_a2, HOST_a2); // neg a2, a2 + *(Bit16u*)(pos+2)=ADD_IMM8(HOST_a2, 32); // add a2, #32 + *(Bit16u*)(pos+4)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 + *(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12) break; case t_NEGb: case t_NEGw: case t_NEGd: - *(Bit16u*)pos=NEG(FC_RETOP, HOST_a1); // neg FC_RETOP, a1 - *(Bit16u*)(pos+2)=B_FWD(18); // b after_call (pc+18) + *(Bit16u*)pos=NEG(HOST_a1, HOST_a1); // neg a1, a1 + *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) break; default: *(Bit32u*)(pos+10)=(Bit32u)fct_ptr; // simple_func From 26e4b50da074f4eca1f22a6eb004980a86cd788b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 28 Jun 2009 14:56:14 +0000 Subject: [PATCH 3347/4131] vga attrib register/blanking updates (hal); cleanup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3436 --- src/hardware/vga_attr.cpp | 32 ++++++----- src/hardware/vga_draw.cpp | 4 +- src/hardware/vga_other.cpp | 89 ++++++++++++++-------------- src/ints/int10_modes.cpp | 115 +++++++++++++++++++------------------ 4 files changed, 123 insertions(+), 117 deletions(-) diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 269f962c..94e320fb 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_attr.cpp,v 1.30 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: vga_attr.cpp,v 1.31 2009-06-28 14:56:13 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -43,12 +43,14 @@ void VGA_ATTR_SetPalette(Bit8u index,Bit8u val) { VGA_DAC_CombineColor(index,val); } -Bitu read_p3c0(Bitu port,Bitu iolen) { -//Wcharts - return 0x0; +Bitu read_p3c0(Bitu /*port*/,Bitu /*iolen*/) { + // Wcharts, Win 3.11 & 95 SVGA + Bitu retval = attr(index) & 0x1f; + if (attr(enabled)) retval |= 0x20; + return retval; } -void write_p3c0(Bitu port,Bitu val,Bitu iolen) { +void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) { if (!vga.internal.attrindex) { attr(index)=val & 0x1F; vga.internal.attrindex=true; @@ -67,7 +69,7 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) { case 0x04: case 0x05: case 0x06: case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: - if (!attr(enabled)) VGA_ATTR_SetPalette(attr(index),val); + if (!attr(enabled)) VGA_ATTR_SetPalette(attr(index),(Bit8u)val); /* 0-5 Index into the 256 color DAC table. May be modified by 3C0h index 10h and 14h. @@ -77,7 +79,7 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) { if (!IS_VGA_ARCH) val&=0x1f; // not really correct, but should do it if ((attr(mode_control) ^ val) & 0x80) { attr(mode_control)^=0x80; - for (Bitu i=0;i<0x10;i++) { + for (Bit8u i=0;i<0x10;i++) { VGA_ATTR_SetPalette(i,vga.attr.palette[i]); } } @@ -85,11 +87,11 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) { VGA_SetBlinking(val & 0x8); } if ((attr(mode_control) ^ val) & 0x04) { - attr(mode_control)=val; + attr(mode_control)=(Bit8u)val; VGA_DetermineMode(); if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) VGA_StartResize(); } else { - attr(mode_control)=val; + attr(mode_control)=(Bit8u)val; VGA_DetermineMode(); } @@ -111,12 +113,12 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) { */ break; case 0x11: /* Overscan Color Register */ - attr(overscan_color)=val; + attr(overscan_color)=(Bit8u)val; /* 0-5 Color of screen border. Color is defined as in the palette registers. */ break; case 0x12: /* Color Plane Enable Register */ /* Why disable colour planes? */ - attr(color_plane_enable)=val; + attr(color_plane_enable)=(Bit8u)val; /* 0 Bit plane 0 is enabled if set. 1 Bit plane 1 is enabled if set. @@ -133,7 +135,7 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) { case M_TEXT: if ((val==0x7) && (svgaCard==SVGA_None)) vga.config.pel_panning=7; if (val>0x7) vga.config.pel_panning=0; - else vga.config.pel_panning=val+1; + else vga.config.pel_panning=(Bit8u)(val+1); break; case M_VGA: case M_LIN8: @@ -163,8 +165,8 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) { break; } if (attr(color_select) ^ val) { - attr(color_select)=val; - for (Bitu i=0;i<0x10;i++) { + attr(color_select)=(Bit8u)val; + for (Bit8u i=0;i<0x10;i++) { VGA_ATTR_SetPalette(i,vga.attr.palette[i]); } } @@ -187,7 +189,7 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) { } } -Bitu read_p3c1(Bitu port,Bitu iolen) { +Bitu read_p3c1(Bitu /*port*/,Bitu iolen) { // vga.internal.attrindex=false; switch (attr(index)) { /* Palette */ diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 502f3b64..97a3300c 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.107 2009-04-11 08:02:23 qbix79 Exp $ */ +/* $Id: vga_draw.cpp,v 1.108 2009-06-28 14:56:14 c2woody Exp $ */ #include #include @@ -616,7 +616,7 @@ static void VGA_ProcessSplit() { } static void VGA_DrawSingleLine(Bitu /*blah*/) { - if(vga.attr.enabled || (!(vga.mode==M_VGA || vga.mode==M_EGA))) { + if (vga.attr.enabled) { Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line ); RENDER_DrawLine(data); } else { diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 5b666bf4..90512878 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_other.cpp,v 1.25 2009-01-25 12:00:51 c2woody Exp $ */ +/* $Id: vga_other.cpp,v 1.26 2009-06-28 14:56:14 c2woody Exp $ */ #include #include @@ -28,57 +28,57 @@ #include "render.h" #include "mapper.h" -static void write_crtc_index_other(Bitu port,Bitu val,Bitu iolen) { - vga.other.index=val; +static void write_crtc_index_other(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { + vga.other.index=(Bit8u)val; } -static Bitu read_crtc_index_other(Bitu port,Bitu iolen) { +static Bitu read_crtc_index_other(Bitu /*port*/,Bitu /*iolen*/) { return vga.other.index; } -static void write_crtc_data_other(Bitu port,Bitu val,Bitu iolen) { +static void write_crtc_data_other(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { switch (vga.other.index) { case 0x00: //Horizontal total if (vga.other.htotal ^ val) VGA_StartResize(); - vga.other.htotal=val; + vga.other.htotal=(Bit8u)val; break; case 0x01: //Horizontal displayed chars if (vga.other.hdend ^ val) VGA_StartResize(); - vga.other.hdend=val; + vga.other.hdend=(Bit8u)val; break; case 0x02: //Horizontal sync position - vga.other.hsyncp=val; + vga.other.hsyncp=(Bit8u)val; break; case 0x03: //Horizontal and vertical sync width - vga.other.syncw=val; + vga.other.syncw=(Bit8u)val; break; case 0x04: //Vertical total if (vga.other.vtotal ^ val) VGA_StartResize(); - vga.other.vtotal=val; + vga.other.vtotal=(Bit8u)val; break; case 0x05: //Vertical display adjust if (vga.other.vadjust ^ val) VGA_StartResize(); - vga.other.vadjust=val; + vga.other.vadjust=(Bit8u)val; break; case 0x06: //Vertical rows if (vga.other.vdend ^ val) VGA_StartResize(); - vga.other.vdend=val; + vga.other.vdend=(Bit8u)val; break; case 0x07: //Vertical sync position - vga.other.vsyncp=val; + vga.other.vsyncp=(Bit8u)val; break; case 0x09: //Max scanline if (vga.other.max_scanline ^ val) VGA_StartResize(); - vga.other.max_scanline=val; + vga.other.max_scanline=(Bit8u)val; break; case 0x0A: /* Cursor Start Register */ - vga.other.cursor_start = val & 0x3f; - vga.draw.cursor.sline = val&0x1f; + vga.other.cursor_start = (Bit8u)(val & 0x3f); + vga.draw.cursor.sline = (Bit8u)(val&0x1f); vga.draw.cursor.enabled = ((val & 0x60) != 0x20); break; case 0x0B: /* Cursor End Register */ - vga.other.cursor_end = val&0x1f; - vga.draw.cursor.eline = val&0x1f; + vga.other.cursor_end = (Bit8u)(val&0x1f); + vga.draw.cursor.eline = (Bit8u)(val&0x1f); break; case 0x0C: /* Start Address High Register */ vga.config.display_start=(vga.config.display_start & 0x00FF) | (val << 8); @@ -88,23 +88,23 @@ static void write_crtc_data_other(Bitu port,Bitu val,Bitu iolen) { break; case 0x0E: /*Cursor Location High Register */ vga.config.cursor_start&=0x00ff; - vga.config.cursor_start|=val << 8; + vga.config.cursor_start|=(Bit8u)(val << 8); break; case 0x0F: /* Cursor Location Low Register */ vga.config.cursor_start&=0xff00; - vga.config.cursor_start|=val; + vga.config.cursor_start|=(Bit8u)val; break; case 0x10: /* Light Pen High */ - vga.other.lpen_high = val & 0x1f; //only 6 bits + vga.other.lpen_high = (Bit8u)(val & 0x1f); //only 6 bits break; case 0x11: /* Light Pen Low */ - vga.other.lpen_low = val; + vga.other.lpen_low = (Bit8u)val; break; default: LOG(LOG_VGAMISC,LOG_NORMAL)("MC6845:Write %X to illegal index %x",val,vga.other.index); } } -static Bitu read_crtc_data_other(Bitu port,Bitu iolen) { +static Bitu read_crtc_data_other(Bitu /*port*/,Bitu /*iolen*/) { switch (vga.other.index) { case 0x00: //Horizontal total return vga.other.htotal; @@ -143,7 +143,7 @@ static Bitu read_crtc_data_other(Bitu port,Bitu iolen) { default: LOG(LOG_VGAMISC,LOG_NORMAL)("MC6845:Read from illegal index %x",vga.other.index); } - return ~0; + return (Bitu)(~0); } static double hue_offset = 0.0; @@ -206,7 +206,7 @@ static void update_cga16_color(void) { G = Y - 0.272*I - 0.647*Q; if (G < 0.0) G = 0.0; if (G > 1.0) G = 1.0; B = Y - 1.105*I + 1.702*Q; if (B < 0.0) B = 0.0; if (B > 1.0) B = 1.0; - RENDER_SetPal(index,static_cast(R*baseR),static_cast(G*baseG),static_cast(B*baseB)); + RENDER_SetPal((Bit8u)index,static_cast(R*baseR),static_cast(G*baseG),static_cast(B*baseB)); } } } @@ -303,7 +303,7 @@ static void TandyCheckLineMask(void ) { vga.tandy.line_shift = 13; vga.tandy.addr_mask = (1 << 13) - 1; } else { - vga.tandy.addr_mask = ~0; + vga.tandy.addr_mask = (Bitu)(~0); vga.tandy.line_shift = 0; } } @@ -352,10 +352,10 @@ static void write_tandy_reg(Bit8u val) { } } -static void write_cga(Bitu port,Bitu val,Bitu iolen) { +static void write_cga(Bitu port,Bitu val,Bitu /*iolen*/) { switch (port) { case 0x3d8: - vga.tandy.mode_control=val; + vga.tandy.mode_control=(Bit8u)val; if (vga.tandy.mode_control & 0x2) { if (vga.tandy.mode_control & 0x10) { if (!(val & 0x4) && machine==MCH_CGA) { @@ -371,24 +371,24 @@ static void write_cga(Bitu port,Bitu val,Bitu iolen) { VGA_SetBlinking(val & 0x20); break; case 0x3d9: - write_color_select(val); + write_color_select((Bit8u)val); break; } } -static void write_tandy(Bitu port,Bitu val,Bitu iolen) { +static void write_tandy(Bitu port,Bitu val,Bitu /*iolen*/) { switch (port) { case 0x3d8: - vga.tandy.mode_control=val; + vga.tandy.mode_control=(Bit8u)val; TandyCheckLineMask(); VGA_SetBlinking(val & 0x20); TANDY_FindMode(); break; case 0x3d9: - write_color_select(val); + write_color_select((Bit8u)val); break; case 0x3da: - vga.tandy.reg_index=val; + vga.tandy.reg_index=(Bit8u)val; break; // case 0x3db: //Clear lightpen latch break; @@ -397,10 +397,10 @@ static void write_tandy(Bitu port,Bitu val,Bitu iolen) { // case 0x3dd: //Extended ram page address register: break; case 0x3de: - write_tandy_reg(val); + write_tandy_reg((Bit8u)val); break; case 0x3df: - vga.tandy.line_mask = val >> 6; + vga.tandy.line_mask = (Bit8u)(val >> 6); vga.tandy.draw_bank = val & ((vga.tandy.line_mask&2) ? 0x6 : 0x7); vga.tandy.mem_bank = (val >> 3) & ((vga.tandy.line_mask&2) ? 0x6 : 0x7); TandyCheckLineMask(); @@ -409,18 +409,18 @@ static void write_tandy(Bitu port,Bitu val,Bitu iolen) { } } -static void write_pcjr(Bitu port,Bitu val,Bitu iolen) { +static void write_pcjr(Bitu port,Bitu val,Bitu /*iolen*/) { switch (port) { case 0x3d9: - write_color_select(val); + write_color_select((Bit8u)val); break; case 0x3da: - if (vga.tandy.pcjr_flipflop) write_tandy_reg(val); - else vga.tandy.reg_index=val; + if (vga.tandy.pcjr_flipflop) write_tandy_reg((Bit8u)val); + else vga.tandy.reg_index=(Bit8u)val; vga.tandy.pcjr_flipflop=!vga.tandy.pcjr_flipflop; break; case 0x3df: - vga.tandy.line_mask = val >> 6; + vga.tandy.line_mask = (Bit8u)(val >> 6); vga.tandy.draw_bank = val & ((vga.tandy.line_mask&2) ? 0x6 : 0x7); vga.tandy.mem_bank = (val >> 3) & ((vga.tandy.line_mask&2) ? 0x6 : 0x7); vga.tandy.draw_base = &MemBase[vga.tandy.draw_bank * 16 * 1024]; @@ -431,7 +431,7 @@ static void write_pcjr(Bitu port,Bitu val,Bitu iolen) { } } -static void write_hercules(Bitu port,Bitu val,Bitu iolen) { +static void write_hercules(Bitu port,Bitu val,Bitu /*iolen*/) { switch (port) { case 0x3b8: { // the protected bits can always be cleared but only be set if the @@ -466,7 +466,7 @@ static void write_hercules(Bitu port,Bitu val,Bitu iolen) { break; } case 0x3bf: - vga.herc.enable_bits=val; + vga.herc.enable_bits=(Bit8u)val; break; } } @@ -476,7 +476,7 @@ static void write_hercules(Bitu port,Bitu val,Bitu iolen) { return 0; } */ -Bitu read_herc_status(Bitu port,Bitu iolen) { +Bitu read_herc_status(Bitu /*port*/,Bitu /*iolen*/) { // 3BAh (R): Status Register // bit 0 Horizontal sync // 1 Light pen status (only some cards) @@ -507,6 +507,8 @@ Bitu read_herc_status(Bitu port,Bitu iolen) { void VGA_SetupOther(void) { Bitu i; memset( &vga.tandy, 0, sizeof( vga.tandy )); + vga.attr.enabled = true; + //Initialize values common for most machines, can be overwritten vga.tandy.draw_base = vga.mem.linear; vga.tandy.mem_base = vga.mem.linear; @@ -580,4 +582,3 @@ void VGA_SetupOther(void) { } } - diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 1a71c40f..7da1a306 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.85 2009-01-25 12:00:52 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.86 2009-06-28 14:56:14 c2woody Exp $ */ #include @@ -357,20 +357,19 @@ static bool SetCurMode(VideoModeBlock modeblock[],Bitu mode) { static void FinishSetMode(bool clearmem) { - Bitu i; /* Clear video memory if needs be */ if (clearmem) { switch (CurMode->type) { case M_CGA4: case M_CGA2: case M_TANDY16: - for (i=0;i<16*1024;i++) { - real_writew( 0xb800,i*2,0x0000); + for (Bit16u ct=0;ct<16*1024;ct++) { + real_writew( 0xb800,ct*2,0x0000); } break; case M_TEXT: { Bit16u seg = (CurMode->mode==7)?0xb000:0xb800; - for (i=0;i<16*1024;i++) real_writew(seg,i*2,0x0720); + for (Bit16u ct=0;ct<16*1024;ct++) real_writew(seg,ct*2,0x0720); break; } case M_EGA: @@ -386,13 +385,13 @@ static void FinishSetMode(bool clearmem) { } } /* Setup the BIOS */ - if (CurMode->mode<128) real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,CurMode->mode); - else real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,CurMode->mode-0x98); //Looks like the s3 bios - real_writew(BIOSMEM_SEG,BIOSMEM_NB_COLS,CurMode->twidth); - real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,CurMode->plength); + if (CurMode->mode<128) real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,(Bit8u)CurMode->mode); + else real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,(Bit8u)(CurMode->mode-0x98)); //Looks like the s3 bios + real_writew(BIOSMEM_SEG,BIOSMEM_NB_COLS,(Bit16u)CurMode->twidth); + real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,(Bit16u)CurMode->plength); real_writew(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,((CurMode->mode==7 )|| (CurMode->mode==0x0f)) ? 0x3b4 : 0x3d4); - real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,CurMode->theight-1); - real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,CurMode->cheight); + real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,(Bit8u)(CurMode->theight-1)); + real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,(Bit16u)CurMode->cheight); real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem?0:0x80))); real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0x09); real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); @@ -402,11 +401,11 @@ static void FinishSetMode(bool clearmem) { real_writed(BIOSMEM_SEG,BIOSMEM_VS_POINTER,int10.rom.video_save_pointers); // Set cursor shape - if(CurMode->type==M_TEXT) { + if (CurMode->type==M_TEXT) { INT10_SetCursorShape(0x06,07); } // Set cursor pos for page 0..7 - for(i=0;i<8;i++) INT10_SetCursorPos(0,0,(Bit8u)i); + for (Bit8u ct=0;ct<8;ct++) INT10_SetCursorPos(0,0,ct); // Set active page 0 INT10_SetActivePage(0); /* Set some interrupt vectors */ @@ -420,7 +419,6 @@ static void FinishSetMode(bool clearmem) { } bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { - Bitu i; switch (machine) { case MCH_CGA: if (mode>6) return false; @@ -479,9 +477,9 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { } IO_WriteW(crtc_base,0x09 | (scanline-1) << 8); //Setup the CGA palette using VGA DAC palette - for (i=0;i<16;i++) VGA_DAC_SetEntry(i,cga_palette[i][0],cga_palette[i][1],cga_palette[i][2]); + for (Bit8u ct=0;ct<16;ct++) VGA_DAC_SetEntry(ct,cga_palette[ct][0],cga_palette[ct][1],cga_palette[ct][2]); //Setup the tandy palette - for (i=0;i<16;i++) VGA_DAC_CombineColor(i,i); + for (Bit8u ct=0;ct<16;ct++) VGA_DAC_CombineColor(ct,ct); //Setup the special registers for each machine type Bit8u mode_control_list[0xa+1]={ 0x2c,0x28,0x2d,0x29, //0-3 @@ -696,9 +694,9 @@ bool INT10_SetVideoMode(Bitu mode) { seq_data[4]|=0xc; //Graphics - odd/even - Chained break; } - for (i=0;ihtotal-5); + IO_Write(crtc_base,0x00);IO_Write(crtc_base+1,(Bit8u)(CurMode->htotal-5)); hor_overflow|=((CurMode->htotal-5) & 0x100) >> 8; /* Horizontal Display End */ - IO_Write(crtc_base,0x01);IO_Write(crtc_base+1,CurMode->hdispend-1); + IO_Write(crtc_base,0x01);IO_Write(crtc_base+1,(Bit8u)(CurMode->hdispend-1)); hor_overflow|=((CurMode->hdispend-1) & 0x100) >> 7; /* Start horizontal Blanking */ - IO_Write(crtc_base,0x02);IO_Write(crtc_base+1,CurMode->hdispend); + IO_Write(crtc_base,0x02);IO_Write(crtc_base+1,(Bit8u)CurMode->hdispend); hor_overflow|=((CurMode->hdispend) & 0x100) >> 6; /* End horizontal Blanking */ Bitu blank_end=(CurMode->htotal-2) & 0x7f; @@ -730,7 +728,7 @@ bool INT10_SetVideoMode(Bitu mode) { if ((CurMode->special & _EGA_HALF_CLOCK) && (CurMode->type!=M_CGA2)) ret_start = (CurMode->hdispend+3); else if (CurMode->type==M_TEXT) ret_start = (CurMode->hdispend+5); else ret_start = (CurMode->hdispend+4); - IO_Write(crtc_base,0x04);IO_Write(crtc_base+1,ret_start); + IO_Write(crtc_base,0x04);IO_Write(crtc_base+1,(Bit8u)ret_start); hor_overflow|=(ret_start & 0x100) >> 4; /* End Horizontal Retrace */ @@ -742,10 +740,10 @@ bool INT10_SetVideoMode(Bitu mode) { } else if (CurMode->type==M_TEXT) ret_end = (CurMode->htotal-3) & 0x1f; else ret_end = (CurMode->htotal-4) & 0x1f; - IO_Write(crtc_base,0x05);IO_Write(crtc_base+1,ret_end | (blank_end & 0x20) << 2); + IO_Write(crtc_base,0x05);IO_Write(crtc_base+1,(Bit8u)(ret_end | (blank_end & 0x20) << 2)); /* Vertical Total */ - IO_Write(crtc_base,0x06);IO_Write(crtc_base+1,(CurMode->vtotal-2)); + IO_Write(crtc_base,0x06);IO_Write(crtc_base+1,(Bit8u)(CurMode->vtotal-2)); overflow|=((CurMode->vtotal-2) & 0x100) >> 8; overflow|=((CurMode->vtotal-2) & 0x200) >> 4; ver_overflow|=((CurMode->vtotal-2) & 0x400) >> 10; @@ -770,7 +768,7 @@ bool INT10_SetVideoMode(Bitu mode) { } /* Vertical Retrace Start */ - IO_Write(crtc_base,0x10);IO_Write(crtc_base+1,vretrace); + IO_Write(crtc_base,0x10);IO_Write(crtc_base+1,(Bit8u)vretrace); overflow|=(vretrace & 0x100) >> 6; overflow|=(vretrace & 0x200) >> 2; ver_overflow|=(vretrace & 0x400) >> 6; @@ -779,7 +777,7 @@ bool INT10_SetVideoMode(Bitu mode) { IO_Write(crtc_base,0x11);IO_Write(crtc_base+1,(vretrace+2) & 0xF); /* Vertical Display End */ - IO_Write(crtc_base,0x12);IO_Write(crtc_base+1,(CurMode->vdispend-1)); + IO_Write(crtc_base,0x12);IO_Write(crtc_base+1,(Bit8u)(CurMode->vdispend-1)); overflow|=((CurMode->vdispend-1) & 0x100) >> 7; overflow|=((CurMode->vdispend-1) & 0x200) >> 3; ver_overflow|=((CurMode->vdispend-1) & 0x400) >> 9; @@ -804,13 +802,13 @@ bool INT10_SetVideoMode(Bitu mode) { } /* Vertical Blank Start */ - IO_Write(crtc_base,0x15);IO_Write(crtc_base+1,(CurMode->vdispend+vblank_trim)); + IO_Write(crtc_base,0x15);IO_Write(crtc_base+1,(Bit8u)(CurMode->vdispend+vblank_trim)); overflow|=((CurMode->vdispend+vblank_trim) & 0x100) >> 5; max_scanline|=((CurMode->vdispend+vblank_trim) & 0x200) >> 4; ver_overflow|=((CurMode->vdispend+vblank_trim) & 0x400) >> 8; /* Vertical Blank End */ - IO_Write(crtc_base,0x16);IO_Write(crtc_base+1,(CurMode->vtotal-vblank_trim-2)); + IO_Write(crtc_base,0x16);IO_Write(crtc_base+1,(Bit8u)(CurMode->vtotal-vblank_trim-2)); /* Line Compare */ Bitu line_compare=(CurMode->vtotal < 1024) ? 1023 : 2047; @@ -881,7 +879,7 @@ bool INT10_SetVideoMode(Bitu mode) { /* Extended System Control 2 Register */ /* This register actually has more bits but only use the extended offset ones */ IO_Write(crtc_base,0x51); - IO_Write(crtc_base + 1,(offset & 0x300) >> 4); + IO_Write(crtc_base + 1,(Bit8u)((offset & 0x300) >> 4)); /* Clear remaining bits of the display start */ IO_Write(crtc_base,0x69); IO_Write(crtc_base + 1,0); @@ -995,9 +993,9 @@ bool INT10_SetVideoMode(Bitu mode) { } break; } - for (i=0;itype == M_LIN4 ) goto att_text16; - for (i=0;i<8;i++) { - att_data[i]=i; - att_data[i+8]=i+0x10; + for (Bit8u ct=0;ct<8;ct++) { + att_data[ct]=ct; + att_data[ct+8]=ct+0x10; } break; } break; case M_TANDY16: att_data[0x10]=0x01; //Color Graphics - for (i=0;i<16;i++) att_data[i]=i; + for (Bit8u ct=0;ct<16;ct++) att_data[ct]=ct; break; case M_TEXT: if (machine==MCH_EGA) { @@ -1054,9 +1052,9 @@ att_text16: att_data[i+8]=0x18; } } else { - for (i=0;i<8;i++) { - att_data[i]=i; - att_data[i+8]=i+0x38; + for (Bit8u ct=0;ct<8;ct++) { + att_data[ct]=ct; + att_data[ct+8]=ct+0x38; } if (IS_VGA_ARCH) att_data[0x06]=0x14; //Odd Color 6 yellow/brown. } @@ -1078,8 +1076,8 @@ att_text16: att_data[5]=0x04; att_data[6]=0x06; att_data[7]=0x07; - for (i=0x8;i<0x10;i++) - att_data[i] = i + 0x8; + for (Bit8u ct=0x8;ct<0x10;ct++) + att_data[ct] = ct + 0x8; real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x30); break; case M_VGA: @@ -1087,15 +1085,15 @@ att_text16: case M_LIN15: case M_LIN16: case M_LIN32: - for (i=0;i<16;i++) att_data[i]=i; + for (Bit8u ct=0;ct<16;ct++) att_data[ct]=ct; att_data[0x10]=0x41; //Color Graphics 8-bit break; } IO_Read(mono_mode ? 0x3ba : 0x3da); if ((modeset_ctl & 8)==0) { - for (i=0;i> 24)); + IO_Write(crtc_base+1,(Bit8u)((S3_LFB_BASE >> 24)&0xff)); IO_Write(crtc_base,0x5a); - IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 16)); + IO_Write(crtc_base+1,(Bit8u)((S3_LFB_BASE >> 16)&0xff)); IO_Write(crtc_base,0x6b); // BIOS scratchpad - IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 24)); + IO_Write(crtc_base+1,(Bit8u)((S3_LFB_BASE >> 24)&0xff)); /* Setup some remaining S3 registers */ IO_Write(crtc_base,0x41); // BIOS scratchpad @@ -1255,7 +1253,7 @@ dac_text16: } IO_WriteB(crtc_base,0x50); IO_WriteB(crtc_base+1,reg_50); - Bitu reg_31, reg_3a; + Bit8u reg_31, reg_3a; switch (CurMode->type) { case M_LIN15: case M_LIN16: @@ -1303,6 +1301,11 @@ dac_text16: } FinishSetMode(clearmem); + + /* Set vga attrib register into defined state */ + IO_Read(mono_mode ? 0x3ba : 0x3da); + IO_Write(0x3c0,0x20); + /* Load text mode font */ if (CurMode->type==M_TEXT) { if (IS_VGA_ARCH) INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); From 6624a00d18418cb7aedd176507463526941b2f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 29 Jun 2009 18:43:33 +0000 Subject: [PATCH 3348/4131] add cga lightpen functionality (hal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3437 --- include/vga.h | 5 +++-- src/hardware/vga_draw.cpp | 3 ++- src/hardware/vga_other.cpp | 40 ++++++++++++++++++++++++++------------ 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/include/vga.h b/include/vga.h index bd3ae94c..131ee026 100644 --- a/include/vga.h +++ b/include/vga.h @@ -16,7 +16,7 @@ * 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 $ */ +/* $Id: vga.h,v 1.47 2009-06-29 18:43:33 c2woody Exp $ */ #ifndef DOSBOX_VGA_H #define DOSBOX_VGA_H @@ -222,7 +222,8 @@ typedef struct { Bit8u vsyncp; Bit8u vsyncw; Bit8u max_scanline; - Bit8u lpen_low, lpen_high; + Bit16u lightpen; + bool lightpen_triggered; Bit8u cursor_start; Bit8u cursor_end; } VGA_OTHER; diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 97a3300c..a16b3405 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.108 2009-06-28 14:56:14 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.109 2009-06-29 18:43:33 c2woody Exp $ */ #include #include @@ -1044,6 +1044,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { clock = 14318180; break; } + vga.draw.delay.hdend = hdend*1000.0/clock; //in milliseconds } #if C_DEBUG LOG(LOG_VGA,LOG_NORMAL)("h total %d end %d blank (%d/%d) retrace (%d/%d)", diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 90512878..55a93cb3 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_other.cpp,v 1.26 2009-06-28 14:56:14 c2woody Exp $ */ +/* $Id: vga_other.cpp,v 1.27 2009-06-29 18:43:33 c2woody Exp $ */ #include #include @@ -88,17 +88,19 @@ static void write_crtc_data_other(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { break; case 0x0E: /*Cursor Location High Register */ vga.config.cursor_start&=0x00ff; - vga.config.cursor_start|=(Bit8u)(val << 8); + vga.config.cursor_start|=((Bit8u)val) << 8; break; case 0x0F: /* Cursor Location Low Register */ vga.config.cursor_start&=0xff00; vga.config.cursor_start|=(Bit8u)val; break; case 0x10: /* Light Pen High */ - vga.other.lpen_high = (Bit8u)(val & 0x1f); //only 6 bits + vga.other.lightpen &= 0xff; + vga.other.lightpen |= (val & 0x3f)<<8; // only 6 bits break; case 0x11: /* Light Pen Low */ - vga.other.lpen_low = (Bit8u)val; + vga.other.lightpen &= 0xff00; + vga.other.lightpen |= (Bit8u)val; break; default: LOG(LOG_VGAMISC,LOG_NORMAL)("MC6845:Write %X to illegal index %x",val,vga.other.index); @@ -129,17 +131,17 @@ static Bitu read_crtc_data_other(Bitu /*port*/,Bitu /*iolen*/) { case 0x0B: /* Cursor End Register */ return vga.other.cursor_end; case 0x0C: /* Start Address High Register */ - return vga.config.display_start >> 8; + return (Bit8u)(vga.config.display_start >> 8); case 0x0D: /* Start Address Low Register */ - return vga.config.display_start; + return (Bit8u)(vga.config.display_start & 0xff); case 0x0E: /*Cursor Location High Register */ - return vga.config.cursor_start>>8; + return (Bit8u)(vga.config.cursor_start >> 8); case 0x0F: /* Cursor Location Low Register */ - return vga.config.cursor_start; + return (Bit8u)(vga.config.cursor_start & 0xff); case 0x10: /* Light Pen High */ - return vga.other.lpen_high; + return (Bit8u)(vga.other.lightpen >> 8); case 0x11: /* Light Pen Low */ - return vga.other.lpen_low; + return (Bit8u)(vga.other.lightpen & 0xff); default: LOG(LOG_VGAMISC,LOG_NORMAL)("MC6845:Read from illegal index %x",vga.other.index); } @@ -390,9 +392,21 @@ static void write_tandy(Bitu port,Bitu val,Bitu /*iolen*/) { case 0x3da: vga.tandy.reg_index=(Bit8u)val; break; -// case 0x3db: //Clear lightpen latch + case 0x3db: // Clear lightpen latch + vga.other.lightpen_triggered = false; break; -// case 0x3dc: //Preset lightpen latch + case 0x3dc: // Preset lightpen latch + if (!vga.other.lightpen_triggered) { + vga.other.lightpen_triggered = true; // TODO: this shows at port 3ba/3da bit 1 + + double timeInFrame = PIC_FullIndex()-vga.draw.delay.framestart; + double timeInLine = fmod(timeInFrame,vga.draw.delay.htotal); + Bitu current_scanline = (Bitu)(timeInFrame / vga.draw.delay.htotal); + + vga.other.lightpen = (Bit16u)((vga.draw.address_add/2) * (current_scanline/2)); + vga.other.lightpen += (Bit16u)((timeInLine / vga.draw.delay.hdend) * + ((float)(vga.draw.address_add/2))); + } break; // case 0x3dd: //Extended ram page address register: break; @@ -529,6 +543,8 @@ void VGA_SetupOther(void) { if (machine==MCH_CGA) { IO_RegisterWriteHandler(0x3d8,write_cga,IO_MB); IO_RegisterWriteHandler(0x3d9,write_cga,IO_MB); + IO_RegisterWriteHandler(0x3db,write_tandy,IO_MB); + IO_RegisterWriteHandler(0x3dc,write_tandy,IO_MB); MAPPER_AddHandler(IncreaseHue,MK_f11,MMOD2,"inchue","Inc Hue"); MAPPER_AddHandler(DecreaseHue,MK_f11,0,"dechue","Dec Hue"); } From 294da23d83455c950f5d3458b00ccb2f8d6a89e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 2 Jul 2009 18:56:11 +0000 Subject: [PATCH 3349/4131] raise dos mcb start to fix buggy installers (ripsaw; fixes 7th guest installer) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3438 --- include/dos_inc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index bb624021..892f63f3 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.78 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.79 2009-07-02 18:56:11 c2woody Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -86,7 +86,7 @@ enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; #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_MEM_START 0x170 //First Segment that DOS can use #define DOS_PRIVATE_SEGMENT 0xc800 #define DOS_PRIVATE_SEGMENT_END 0xd000 From bc5a4d71726fdd9b87ece2db019a2b3c87c3b5e6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 3 Jul 2009 19:36:57 +0000 Subject: [PATCH 3350/4131] fix shift. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3439 --- include/shell.h | 3 ++- src/shell/shell_batch.cpp | 11 ++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/include/shell.h b/include/shell.h index 02edab16..b6799bee 100644 --- a/include/shell.h +++ b/include/shell.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.27 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: shell.h,v 1.28 2009-07-03 19:36:57 qbix79 Exp $ */ #ifndef DOSBOX_SHELL_H #define DOSBOX_SHELL_H @@ -55,6 +55,7 @@ public: DOS_Shell * shell; BatchFile * prev; CommandLine * cmd; + std::string filename; }; class AutoexecEditor; diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 9bf40070..3d4c1668 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.35 2009-05-27 09:15:42 qbix79 Exp $ */ +/* $Id: shell_batch.cpp,v 1.36 2009-07-03 19:36:56 qbix79 Exp $ */ #include #include @@ -32,6 +32,7 @@ BatchFile::BatchFile(DOS_Shell * host,char const * const name, char const * cons char totalname[DOS_PATHLENGTH+4]; DOS_Canonicalize(name,totalname); // Get fullname including drive specificiation cmd = new CommandLine(totalname,cmd_line); + filename = totalname; //Test if file is openable if (!DOS_OpenFile(totalname,128,&file_handle)) { @@ -49,8 +50,8 @@ BatchFile::~BatchFile() { bool BatchFile::ReadLine(char * line) { //Open the batchfile and seek to stored postion - if (!DOS_OpenFile(cmd->GetFileName(),128,&file_handle)) { - LOG(LOG_MISC,LOG_ERROR)("ReadLine Can't open BatchFile %s",cmd->GetFileName()); + if (!DOS_OpenFile(filename.c_str(),128,&file_handle)) { + LOG(LOG_MISC,LOG_ERROR)("ReadLine Can't open BatchFile %s",filename.c_str()); delete this; return false; } @@ -143,8 +144,8 @@ emptyline: bool BatchFile::Goto(char * where) { //Open bat file and search for the where string - if (!DOS_OpenFile(cmd->GetFileName(),128,&file_handle)) { - LOG(LOG_MISC,LOG_ERROR)("SHELL:Goto Can't open BatchFile %s",cmd->GetFileName()); + if (!DOS_OpenFile(filename.c_str(),128,&file_handle)) { + LOG(LOG_MISC,LOG_ERROR)("SHELL:Goto Can't open BatchFile %s",filename.c_str()); delete this; return false; } From 1660096f6bbf57aed24a9524b0fd408296380a9e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 4 Jul 2009 21:23:35 +0000 Subject: [PATCH 3351/4131] Fix Allertone football manager (thanks ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3440 --- src/hardware/vga_memory.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 605593a1..c972d516 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_memory.cpp,v 1.52 2009-03-22 21:04:41 c2woody Exp $ */ +/* $Id: vga_memory.cpp,v 1.53 2009-07-04 21:23:35 qbix79 Exp $ */ #include #include @@ -114,6 +114,7 @@ INLINE static Bit32u ModeOperation(Bit8u val) { break; case 0x03: // Write Mode 3: In this mode, the data in the Set/Reset field is used as if the Enable Set/Reset field were set to 1111b. Then the host data is first rotated as per the Rotate Count field, then logical ANDed with the value of the Bit Mask field. The resulting value is used on the data obtained from the Set/Reset field in the same way that the Bit Mask field would ordinarily be used. to select which bits come from the expansion of the Set/Reset field and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory. + val=((val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate))); full=RasterOp(vga.config.full_set_reset,ExpandTable[val] & vga.config.full_bit_mask); break; default: From 934dff7731494f9e1317890bf8d71d30ea7aacea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 8 Jul 2009 20:05:41 +0000 Subject: [PATCH 3352/4131] symmetrically beautify the memory start to work around some more buggy installers/games Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3441 --- include/dos_inc.h | 4 ++-- src/shell/shell.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 892f63f3..3256e64d 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.79 2009-07-02 18:56:11 c2woody Exp $ */ +/* $Id: dos_inc.h,v 1.80 2009-07-08 20:05:41 c2woody Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -86,7 +86,7 @@ enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; #define DOS_SDA_OFS 0 #define DOS_CDS_SEG 0x108 #define DOS_FIRST_SHELL 0x118 -#define DOS_MEM_START 0x170 //First Segment that DOS can use +#define DOS_MEM_START 0x16f //First Segment that DOS can use #define DOS_PRIVATE_SEGMENT 0xc800 #define DOS_PRIVATE_SEGMENT_END 0xd000 diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 5dd268b9..3d317904 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.99 2009-05-14 18:44:54 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.100 2009-07-08 20:05:41 c2woody Exp $ */ #include #include @@ -584,7 +584,7 @@ void SHELL_Init() { pspmcb.SetType(0x4d); DOS_MCB envmcb((Bit16u)(env_seg-1)); envmcb.SetPSPSeg(psp_seg); // MCB of the command shell environment - envmcb.SetSize(0x28); + envmcb.SetSize(DOS_MEM_START-env_seg); envmcb.SetType(0x4d); /* Setup environment */ From a55cf506926c3850b52f56d351138a536fa6a14a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 9 Jul 2009 20:06:57 +0000 Subject: [PATCH 3353/4131] some fixes to the fcb parse functionality, thanks to ripsaw for finding those Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3442 --- include/dos_inc.h | 4 +-- src/dos/dos_classes.cpp | 55 ++++++++++++++++++++++------------------- src/dos/dos_files.cpp | 14 ++++++++--- 3 files changed, 41 insertions(+), 32 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 3256e64d..97deee81 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.80 2009-07-08 20:05:41 c2woody Exp $ */ +/* $Id: dos_inc.h,v 1.81 2009-07-09 20:06:56 c2woody Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -489,7 +489,7 @@ private: class DOS_FCB: public MemStruct { public: - DOS_FCB(Bit16u seg,Bit16u off); + DOS_FCB(Bit16u seg,Bit16u off,bool allow_extended=true); void Create(bool _extended); void SetName(Bit8u _drive,char * _fname,char * _ext); void SetSizeDateTime(Bit32u _size,Bit16u _date,Bit16u _time); diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 3add7df1..6057e02a 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.57 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.58 2009-07-09 20:06:57 c2woody Exp $ */ #include #include @@ -32,14 +32,14 @@ void DOS_ParamBlock::Clear(void) { } void DOS_ParamBlock::LoadData(void) { - exec.envseg=sGet(sExec,envseg); + exec.envseg=(Bit16u)sGet(sExec,envseg); exec.cmdtail=sGet(sExec,cmdtail); exec.fcb1=sGet(sExec,fcb1); exec.fcb2=sGet(sExec,fcb2); exec.initsssp=sGet(sExec,initsssp); exec.initcsip=sGet(sExec,initcsip); - overlay.loadseg=sGet(sOverlay,loadseg); - overlay.relocation=sGet(sOverlay,relocation); + overlay.loadseg=(Bit16u)sGet(sOverlay,loadseg); + overlay.relocation=(Bit16u)sGet(sOverlay,relocation); } void DOS_ParamBlock::SaveData(void) { @@ -143,7 +143,7 @@ void DOS_InfoBlock::SetDiskBufferHeadPt(Bit32u _dbheadpt) { } Bit16u DOS_InfoBlock::GetStartOfUMBChain(void) { - return sGet(sDIB,startOfUMBChain); + return (Bit16u)sGet(sDIB,startOfUMBChain); } void DOS_InfoBlock::SetStartOfUMBChain(Bit16u _umbstartseg) { @@ -151,7 +151,7 @@ void DOS_InfoBlock::SetStartOfUMBChain(Bit16u _umbstartseg) { } Bit8u DOS_InfoBlock::GetUMBChainState(void) { - return sGet(sDIB,chainingUMB); + return (Bit8u)sGet(sDIB,chainingUMB); } void DOS_InfoBlock::SetUMBChainState(Bit8u _umbchaining) { @@ -202,7 +202,7 @@ void DOS_PSP::MakeNew(Bit16u mem_size) { /* Init file pointer and max_files */ sSave(sPSP,file_table,RealMake(seg,offsetof(sPSP,files))); sSave(sPSP,max_files,20); - for (i=0;i<20;i++) SetFileHandle(i,0xff); + for (Bit16u ct=0;ct<20;ct++) SetFileHandle(ct,0xff); /* User Stack pointer */ // if (prevpsp.GetSegment()!=0) sSave(sPSP,stack,prevpsp.GetStack()); @@ -309,7 +309,7 @@ bool DOS_PSP::SetNumFiles(Bit16u fileNum) { sSave(sPSP,file_table,data); sSave(sPSP,max_files,fileNum); Bit16u i; - for (i=0; i<20; i++) SetFileHandle(i,sGet(sPSP,files[i])); + for (i=0; i<20; i++) SetFileHandle(i,(Bit8u)sGet(sPSP,files[i])); for (i=20; i #include @@ -768,11 +768,17 @@ static bool isvalid(const char in){ #define PARSE_RET_BADDRIVE 0xff Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u *change) { - char * string_begin=string;Bit8u ret=0; - DOS_FCB fcb(seg,offset); + char * string_begin=string; + Bit8u ret=0; + if (!(parser & PARSE_DFLT_DRIVE)) { + // default drive forced, this intentionally invalidates an extended FCB + mem_writeb(PhysMake(seg,offset),0); + } + DOS_FCB fcb(seg,offset,false); // always a non-extended FCB bool hasdrive,hasname,hasext,finished; hasdrive=hasname=hasext=finished=false; - Bitu index=0;Bit8u fill=' '; + Bitu index=0; + Bit8u fill=' '; /* First get the old data from the fcb */ #ifdef _MSC_VER #pragma pack (1) From 655b7caa71b641d2f4dd60643425f7dd4b4ae023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 11 Jul 2009 10:25:25 +0000 Subject: [PATCH 3354/4131] textmode address handling updated (hal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3443 --- src/hardware/vga_draw.cpp | 37 ++++++++++++++++++++++++++----------- src/hardware/vga_other.cpp | 6 ++++-- src/ints/int10.h | 4 ++-- src/ints/int10_char.cpp | 15 +++++++++++---- src/ints/int10_modes.cpp | 4 ++-- 5 files changed, 45 insertions(+), 21 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index a16b3405..8175ca25 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.109 2009-06-29 18:43:33 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.110 2009-07-11 10:25:24 c2woody Exp $ */ #include #include @@ -344,11 +344,24 @@ static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart, Bitu /*line*/) { } } +static const Bit8u* VGA_Text_Memwrap(Bitu vidstart) { + vidstart &= vga.draw.linear_mask; + Bitu line_end = 2 * vga.draw.blocks; + if (GCC_UNLIKELY((vidstart + line_end) > vga.draw.linear_mask)) { + // wrapping in this line + Bitu break_pos = (vga.draw.linear_mask - vidstart) + 1; + // need a temporary storage - TempLine/2 is ok for a bit more than 132 columns + memcpy(&TempLine[sizeof(TempLine)/2], &vga.tandy.draw_base[vidstart], break_pos); + memcpy(&TempLine[sizeof(TempLine)/2 + break_pos],&vga.tandy.draw_base[0], line_end - break_pos); + return &TempLine[sizeof(TempLine)/2]; + } else return &vga.tandy.draw_base[vidstart]; +} + static Bit32u FontMask[2]={0xffffffff,0x0}; static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart, Bitu line) { Bits font_addr; Bit32u * draw=(Bit32u *)TempLine; - const Bit8u *vidmem = &vga.tandy.draw_base[vidstart]; + const Bit8u* vidmem = VGA_Text_Memwrap(vidstart); for (Bitu cx=0;cx=vga.draw.split_line)) pel_pan=0; - const Bit8u *vidmem = &vga.tandy.draw_base[vidstart]; + const Bit8u* vidmem = VGA_Text_Memwrap(vidstart); Bit8u chr=vidmem[0]; Bit8u col=vidmem[1]; Bit8u font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<=vga.draw.split_line)) pel_pan=0; - const Bit8u *vidmem = &vga.tandy.draw_base[vidstart]; + const Bit8u* vidmem = VGA_Text_Memwrap(vidstart); Bit8u chr=vidmem[0]; Bit8u col=vidmem[1]; Bit8u font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<> 4)) ? diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 55a93cb3..bbf059ad 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_other.cpp,v 1.27 2009-06-29 18:43:33 c2woody Exp $ */ +/* $Id: vga_other.cpp,v 1.28 2009-07-11 10:25:24 c2woody Exp $ */ #include #include @@ -68,7 +68,8 @@ static void write_crtc_data_other(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { vga.other.vsyncp=(Bit8u)val; break; case 0x09: //Max scanline - if (vga.other.max_scanline ^ val) VGA_StartResize(); + val &= 0x1f; // VGADOC says bit 0-3 but the MC6845 datasheet says bit 0-4 + if (vga.other.max_scanline ^ val) VGA_StartResize(); vga.other.max_scanline=(Bit8u)val; break; case 0x0A: /* Cursor Start Register */ @@ -522,6 +523,7 @@ void VGA_SetupOther(void) { Bitu i; memset( &vga.tandy, 0, sizeof( vga.tandy )); vga.attr.enabled = true; + vga.config.bytes_skip=0; //Initialize values common for most machines, can be overwritten vga.tandy.draw_base = vga.mem.linear; diff --git a/src/ints/int10.h b/src/ints/int10.h index fdf01064..7ceee886 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.h,v 1.39 2009-05-27 09:15:42 qbix79 Exp $ */ +/* $Id: int10.h,v 1.40 2009-07-11 10:25:25 c2woody Exp $ */ #include "vga.h" @@ -95,7 +95,7 @@ #define VGAMEM_MTEXT 0xB000 #define BIOS_NCOLS Bit16u ncols=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); -#define BIOS_NROWS Bit16u nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; +#define BIOS_NROWS Bit16u nrows=(Bit16u)real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; extern Bit8u int10_font_08[256 * 8]; extern Bit8u int10_font_14[256 * 14]; diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index ee291623..9d102b4c 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.58 2009-05-27 09:15:42 qbix79 Exp $ */ +/* $Id: int10_char.cpp,v 1.59 2009-07-11 10:25:25 c2woody Exp $ */ /* Character displaying moving functions */ @@ -272,12 +272,19 @@ filling: void INT10_SetActivePage(Bit8u page) { Bit16u mem_address; - if (page>7) LOG(LOG_INT10,LOG_ERROR)("INT10_SetActivePage page %d",page); + + if (IS_EGAVGA_ARCH && (svgaCard==SVGA_S3Trio)) page &= 7; + mem_address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); /* Write the new page start */ real_writew(BIOSMEM_SEG,BIOSMEM_CURRENT_START,mem_address); - if (IS_EGAVGA_ARCH && CurMode->mode<0x8) mem_address>>=1; + if (IS_EGAVGA_ARCH) { + if (CurMode->mode<8) mem_address>>=1; + // rare alternative: if (CurMode->type==M_TEXT) mem_address>>=1; + } else { + mem_address>>=1; + } /* Write the new start address in vgahardware */ Bit16u base=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); IO_Write(base,0x0c); @@ -587,7 +594,7 @@ static void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr,Bit8u pag if(cur_row==nrows) { //Fill with black on non-text modes and with 0x7 on textmode Bit8u fill = (CurMode->type == M_TEXT)?0x7:0; - INT10_ScrollWindow(0,0,nrows-1,ncols-1,-1,fill,page); + INT10_ScrollWindow(0,0,(Bit8u)(nrows-1),ncols-1,-1,fill,page); cur_row--; } // Set the cursor for the page diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 7da1a306..e1ae1894 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.86 2009-06-28 14:56:14 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.87 2009-07-11 10:25:25 c2woody Exp $ */ #include @@ -232,7 +232,7 @@ VideoModeBlock ModeList_OTHER[]={ }; VideoModeBlock Hercules_Mode= -{ 0x007 ,M_TEXT ,640 ,400 ,80 ,25 ,8 ,14 ,4 ,0xB0000 ,0x1000 ,97 ,25 ,80 ,25 ,0 }; +{ 0x007 ,M_TEXT ,640 ,400 ,80 ,25 ,8 ,14 ,1 ,0xB0000 ,0x1000 ,97 ,25 ,80 ,25 ,0 }; static Bit8u text_palette[64][3]= { From 4ed39f7fd311101af0d091be097a3beb8ca0ca06 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 11 Jul 2009 10:39:38 +0000 Subject: [PATCH 3355/4131] Set the correct dsp version for sb 1.5 ( thanks tryton ) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3444 --- src/hardware/sblaster.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 7fdf8d48..df55a769 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.76 2009-06-10 17:44:59 c2woody Exp $ */ +/* $Id: sblaster.cpp,v 1.77 2009-07-11 10:39:38 harekiet Exp $ */ #include #include @@ -938,7 +938,7 @@ static void DSP_DoCommand(void) { DSP_FlushData(); switch (sb.type) { case SBT_1: - DSP_AddData(0x1);DSP_AddData(0x1);break; + DSP_AddData(0x1);DSP_AddData(0x05);break; case SBT_2: DSP_AddData(0x2);DSP_AddData(0x1);break; case SBT_PRO1: From 4b15cbd0a1846f1d07535e548aec970bb6ec6516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 12 Jul 2009 20:13:05 +0000 Subject: [PATCH 3356/4131] prevent write-through for recompiler code pages in rom area (pitfall2 pcjr booter) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3445 --- src/cpu/core_dyn_x86/cache.h | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index a3c43ba9..e930c0f0 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -1,3 +1,23 @@ +/* + * 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: cache.h,v 1.20 2009-07-12 20:13:05 c2woody Exp $ */ + class CacheBlock { public: void Clear(void); @@ -88,6 +108,10 @@ public: return is_current_block; } void writeb(PhysPt addr,Bitu val){ + if (GCC_UNLIKELY(old_pagehandler->flags&PFLAG_HASROM)) return; + if (GCC_UNLIKELY((old_pagehandler->flags&PFLAG_READABLE)!=PFLAG_READABLE)) { + E_Exit("wb:non-readable code page found that is no ROM page"); + } addr&=4095; if (host_readb(hostmem+addr)==(Bit8u)val) return; host_writeb(hostmem+addr,val); @@ -104,6 +128,10 @@ public: InvalidateRange(addr,addr); } void writew(PhysPt addr,Bitu val){ + if (GCC_UNLIKELY(old_pagehandler->flags&PFLAG_HASROM)) return; + if (GCC_UNLIKELY((old_pagehandler->flags&PFLAG_READABLE)!=PFLAG_READABLE)) { + E_Exit("ww:non-readable code page found that is no ROM page"); + } addr&=4095; if (host_readw(hostmem+addr)==(Bit16u)val) return; host_writew(hostmem+addr,val); @@ -120,6 +148,10 @@ public: InvalidateRange(addr,addr+1); } void writed(PhysPt addr,Bitu val){ + if (GCC_UNLIKELY(old_pagehandler->flags&PFLAG_HASROM)) return; + if (GCC_UNLIKELY((old_pagehandler->flags&PFLAG_READABLE)!=PFLAG_READABLE)) { + E_Exit("wd:non-readable code page found that is no ROM page"); + } addr&=4095; if (host_readd(hostmem+addr)==(Bit32u)val) return; host_writed(hostmem+addr,val); @@ -136,6 +168,10 @@ public: InvalidateRange(addr,addr+3); } bool writeb_checked(PhysPt addr,Bitu val) { + if (GCC_UNLIKELY(old_pagehandler->flags&PFLAG_HASROM)) return false; + if (GCC_UNLIKELY((old_pagehandler->flags&PFLAG_READABLE)!=PFLAG_READABLE)) { + E_Exit("cb:non-readable code page found that is no ROM page"); + } addr&=4095; if (host_readb(hostmem+addr)==(Bit8u)val) return false; if (!*(Bit8u*)&write_map[addr]) { @@ -158,6 +194,10 @@ public: return false; } bool writew_checked(PhysPt addr,Bitu val) { + if (GCC_UNLIKELY(old_pagehandler->flags&PFLAG_HASROM)) return false; + if (GCC_UNLIKELY((old_pagehandler->flags&PFLAG_READABLE)!=PFLAG_READABLE)) { + E_Exit("cw:non-readable code page found that is no ROM page"); + } addr&=4095; if (host_readw(hostmem+addr)==(Bit16u)val) return false; if (!*(Bit16u*)&write_map[addr]) { @@ -180,6 +220,10 @@ public: return false; } bool writed_checked(PhysPt addr,Bitu val) { + if (GCC_UNLIKELY(old_pagehandler->flags&PFLAG_HASROM)) return false; + if (GCC_UNLIKELY((old_pagehandler->flags&PFLAG_READABLE)!=PFLAG_READABLE)) { + E_Exit("cd:non-readable code page found that is no ROM page"); + } addr&=4095; if (host_readd(hostmem+addr)==(Bit32u)val) return false; if (!*(Bit32u*)&write_map[addr]) { From f06f10d3dd706b8df596daeb2e737a4693367d0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 15 Jul 2009 17:05:07 +0000 Subject: [PATCH 3357/4131] fix some umb/dos memory chaining return code (ripsaw, fixes The Legacy with umb disabled) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3446 --- src/dos/dos.cpp | 18 +++++++++++------- src/dos/dos_memory.cpp | 4 ++-- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index fd5ebbe1..5c6cf7e8 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.117 2009-04-16 12:16:52 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.118 2009-07-15 17:05:07 c2woody Exp $ */ #include #include @@ -397,8 +397,10 @@ static Bitu DOS_21Handler(void) { case 0x1f: /* Get drive parameter block for default drive */ case 0x32: /* Get drive parameter block for specific drive */ { /* Officially a dpb should be returned as well. The disk detection part is implemented */ - Bitu drive=reg_dl;if(!drive || reg_ah==0x1f) drive = DOS_GetDefaultDrive();else drive--; - if(Drives[drive]) { + Bit8u drive=reg_dl; + if (!drive || reg_ah==0x1f) drive = DOS_GetDefaultDrive(); + else drive--; + if (Drives[drive]) { reg_al = 0x00; SegSet16(ds,dos.tables.dpb); reg_bx = drive;//Faking only the first entry (that is the driveletter) @@ -813,6 +815,8 @@ static Bitu DOS_21Handler(void) { break; default: LOG(LOG_DOSMISC,LOG_ERROR)("DOS:58:Not Supported Set//Get memory allocation call %X",reg_al); + reg_ax=1; + CALLBACK_SCF(true); } break; case 0x59: /* Get Extended error information */ @@ -945,7 +949,7 @@ static Bitu DOS_21Handler(void) { { int in = reg_dl; int out = toupper(in); - reg_dl = out; + reg_dl = (Bit8u)out; } CALLBACK_SCF(false); break; @@ -960,8 +964,8 @@ static Bitu DOS_21Handler(void) { MEM_BlockRead(data,dos_copybuf,len); dos_copybuf[len] = 0; //No upcase as String(0x21) might be multiple asciz strings - for(Bitu count = 0; count < len;count++) - dos_copybuf[count] = toupper(*reinterpret_cast(dos_copybuf+count)); + for (Bitu count = 0; count < len;count++) + dos_copybuf[count] = (Bit8u)toupper(*reinterpret_cast(dos_copybuf+count)); MEM_BlockWrite(data,dos_copybuf,len); } CALLBACK_SCF(false); @@ -1149,7 +1153,7 @@ public: static DOS* test; -void DOS_ShutDown(Section* sec) { +void DOS_ShutDown(Section* /*sec*/) { delete test; } diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index efe8a46c..67533716 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_memory.cpp,v 1.44 2009-06-08 17:20:02 c2woody Exp $ */ +/* $Id: dos_memory.cpp,v 1.45 2009-07-15 17:05:07 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -347,7 +347,7 @@ bool DOS_LinkUMBsToMemChain(Bit16u linkstate) { Bit16u umb_start=dos_infoblock.GetStartOfUMBChain(); if (umb_start!=UMB_START_SEG) { if (umb_start!=0xffff) LOG(LOG_DOSMISC,LOG_ERROR)("Corrupt UMB chain: %x",umb_start); - return true; + return false; } if ((linkstate&1)==(dos_infoblock.GetUMBChainState()&1)) return true; From 3aa48444fd8c57e613ba3b809496b2677fabb886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 18 Jul 2009 18:42:55 +0000 Subject: [PATCH 3358/4131] dos open file in write-only mode uses append type open (thanks to ripsaw for pointing to this) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3447 --- src/dos/drive_local.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 99bd96a3..15dee47f 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.81 2009-06-18 18:17:54 c2woody Exp $ */ +/* $Id: drive_local.cpp,v 1.82 2009-07-18 18:42:55 c2woody Exp $ */ #include #include @@ -83,7 +83,7 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { const char* type; switch (flags&0xf) { case OPEN_READ:type="rb"; break; - case OPEN_WRITE:type="wb"; break; + case OPEN_WRITE:type="rb+"; break; case OPEN_READWRITE:type="rb+"; break; default: DOS_SetError(DOSERR_ACCESS_CODE_INVALID); From c1305f8ddac53ac3be89164083f14f17ab781952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 20 Jul 2009 17:55:52 +0000 Subject: [PATCH 3359/4131] check for pic irq events after emulated iret instruction for the recompiler Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3448 --- src/cpu/core_dyn_x86.cpp | 7 +++++-- src/cpu/core_dynrec.cpp | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index dbbb72b2..b242e7b6 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: core_dyn_x86.cpp,v 1.35 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: core_dyn_x86.cpp,v 1.36 2009-07-20 17:55:52 c2woody Exp $ */ #include "dosbox.h" @@ -306,7 +306,10 @@ run_block: return debugCallback; } #endif - if (!GETFLAG(TF)) goto restart_core; + if (!GETFLAG(TF)) { + if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; + goto restart_core; + } cpudecoder=CPU_Core_Dyn_X86_Trap_Run; if (!dyn_dh_fpu.state_used) return CBRET_NONE; DH_FPU_SAVE_REINIT diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index 2819c1f9..7aa7e7ae 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: core_dynrec.cpp,v 1.12 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: core_dynrec.cpp,v 1.13 2009-07-20 17:55:52 c2woody Exp $ */ #include "dosbox.h" @@ -233,7 +233,10 @@ run_block: #if C_HEAVY_DEBUG if (DEBUG_HeavyIsBreakpoint()) return debugCallback; #endif - if (!GETFLAG(TF)) break; + if (!GETFLAG(TF)) { + if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; + break; + } // trapflag is set, switch to the trap-aware decoder cpudecoder=CPU_Core_Dynrec_Trap_Run; return CBRET_NONE; From 76794c051ef471b13cb430d030bf5de2b3859337 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 22 Jul 2009 09:09:35 +0000 Subject: [PATCH 3360/4131] Fix compilation Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3449 --- src/cpu/core_dynrec.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index 7aa7e7ae..b4d6d697 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: core_dynrec.cpp,v 1.13 2009-07-20 17:55:52 c2woody Exp $ */ +/* $Id: core_dynrec.cpp,v 1.14 2009-07-22 09:09:35 qbix79 Exp $ */ #include "dosbox.h" @@ -51,6 +51,7 @@ #include "paging.h" #include "inout.h" #include "lazyflags.h" +#include "pic.h" #define CACHE_MAXSIZE (4096*2) #define CACHE_TOTAL (1024*1024*8) From 669ec92a594a38a878ef70e744613d2e622c9a0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 24 Jul 2009 09:56:14 +0000 Subject: [PATCH 3361/4131] add finer-grained dma wrapping capabilities Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3450 --- include/dma.h | 6 ++- src/hardware/dma.cpp | 98 ++++++++++++++++++++++++++------------------ 2 files changed, 62 insertions(+), 42 deletions(-) diff --git a/include/dma.h b/include/dma.h index f62446f4..775f9d2a 100644 --- a/include/dma.h +++ b/include/dma.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dma.h,v 1.19 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: dma.h,v 1.20 2009-07-24 09:56:14 c2woody Exp $ */ #ifndef DOSBOX_DMA_H #define DOSBOX_DMA_H @@ -35,7 +35,7 @@ class DmaChannel { public: Bit32u pagebase; Bit16u baseaddr; - Bit16u curraddr; + Bit32u curraddr; Bit16u basecnt; Bit16u currcnt; Bit8u channum; @@ -114,4 +114,6 @@ DmaChannel * GetDMAChannel(Bit8u chan); void CloseSecondDMAController(void); bool SecondDMAControllerAvailable(void); +static Bit32u dma_wrapping = 0xffff; + #endif diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index e611e8c3..c58dc039 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dma.cpp,v 1.40 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: dma.cpp,v 1.41 2009-07-24 09:56:14 c2woody Exp $ */ #include #include "dosbox.h" @@ -41,28 +41,40 @@ static void UpdateEMSMapping(void) { } /* read a block from physical memory */ -static void DMA_BlockRead(PhysPt pt,void * data,Bitu size) { +static void DMA_BlockRead(PhysPt spage,PhysPt offset,void * data,Bitu size,Bit8u dma16) { Bit8u * write=(Bit8u *) data; - for ( ; size ; size--, pt++) { - Bitu page = pt >> 12; + Bitu highpart_addr_page = spage>>12; + size <<= dma16; + offset <<= dma16; + Bit32u dma_wrap = ((0xffff<(dma_wrapping<> 12); /* care for EMS pageframe etc. */ if (page < EMM_PAGEFRAME4K) page = paging.firstmb[page]; else if (page < EMM_PAGEFRAME4K+0x10) page = ems_board_mapping[page]; else if (page < LINK_START) page = paging.firstmb[page]; - *write++=phys_readb(page*4096 + (pt & 4095)); + *write++=phys_readb(page*4096 + (offset & 4095)); } } /* write a block into physical memory */ -static void DMA_BlockWrite(PhysPt pt,void * data,Bitu size) { +static void DMA_BlockWrite(PhysPt spage,PhysPt offset,void * data,Bitu size,Bit8u dma16) { Bit8u * read=(Bit8u *) data; - for ( ; size ; size--, pt++) { - Bitu page = pt >> 12; + Bitu highpart_addr_page = spage>>12; + size <<= dma16; + offset <<= dma16; + Bit32u dma_wrap = ((0xffff<(dma_wrapping<> 12); /* care for EMS pageframe etc. */ if (page < EMM_PAGEFRAME4K) page = paging.firstmb[page]; else if (page < EMM_PAGEFRAME4K+0x10) page = ems_board_mapping[page]; else if (page < LINK_START) page = paging.firstmb[page]; - phys_writeb(page*4096 + (pt & 4095), *read++); + phys_writeb(page*4096 + (offset & 4095), *read++); } } @@ -91,7 +103,7 @@ bool SecondDMAControllerAvailable(void) { else return false; } -static void DMA_Write_Port(Bitu port,Bitu val,Bitu iolen) { +static void DMA_Write_Port(Bitu port,Bitu val,Bitu /*iolen*/) { if (port<0x10) { /* write to the first DMA controller (channels 0-3) */ DmaControllers[0]->WriteControllerReg(port,val,1); @@ -102,12 +114,12 @@ static void DMA_Write_Port(Bitu port,Bitu val,Bitu iolen) { UpdateEMSMapping(); switch (port) { /* write DMA page register */ - case 0x81:GetDMAChannel(2)->SetPage(val);break; - case 0x82:GetDMAChannel(3)->SetPage(val);break; - case 0x83:GetDMAChannel(1)->SetPage(val);break; - case 0x89:GetDMAChannel(6)->SetPage(val);break; - case 0x8a:GetDMAChannel(7)->SetPage(val);break; - case 0x8b:GetDMAChannel(5)->SetPage(val);break; + case 0x81:GetDMAChannel(2)->SetPage((Bit8u)val);break; + case 0x82:GetDMAChannel(3)->SetPage((Bit8u)val);break; + case 0x83:GetDMAChannel(1)->SetPage((Bit8u)val);break; + case 0x89:GetDMAChannel(6)->SetPage((Bit8u)val);break; + case 0x8a:GetDMAChannel(7)->SetPage((Bit8u)val);break; + case 0x8b:GetDMAChannel(5)->SetPage((Bit8u)val);break; } } } @@ -131,13 +143,13 @@ static Bitu DMA_Read_Port(Bitu port,Bitu iolen) { return 0; } -void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) { - DmaChannel * chan;Bitu i; +void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu /*len*/) { + DmaChannel * chan; switch (reg) { /* set base address of DMA transfer (1st byte low part, 2nd byte high part) */ case 0x0:case 0x2:case 0x4:case 0x6: UpdateEMSMapping(); - chan=GetChannel(reg >> 1); + chan=GetChannel((Bit8u)(reg >> 1)); flipflop=!flipflop; if (flipflop) { chan->baseaddr=(chan->baseaddr&0xff00)|val; @@ -150,7 +162,7 @@ void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) { /* set DMA transfer count (1st byte low part, 2nd byte high part) */ case 0x1:case 0x3:case 0x5:case 0x7: UpdateEMSMapping(); - chan=GetChannel(reg >> 1); + chan=GetChannel((Bit8u)(reg >> 1)); flipflop=!flipflop; if (flipflop) { chan->basecnt=(chan->basecnt&0xff00)|val; @@ -181,8 +193,8 @@ void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) { flipflop=false; break; case 0xd: /* Master Clear/Reset */ - for (i=0;i<4;i++) { - chan=GetChannel(i); + for (Bit8u ct=0;ct<4;ct++) { + chan=GetChannel(ct); chan->SetMask(true); chan->tcount=false; } @@ -190,15 +202,15 @@ void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) { break; case 0xe: /* Clear Mask register */ UpdateEMSMapping(); - for (i=0;i<4;i++) { - chan=GetChannel(i); + for (Bit8u ct=0;ct<4;ct++) { + chan=GetChannel(ct); chan->SetMask(false); } break; case 0xf: /* Multiple Mask register */ UpdateEMSMapping(); - for (i=0;i<4;i++) { - chan=GetChannel(i); + for (Bit8u ct=0;ct<4;ct++) { + chan=GetChannel(ct); chan->SetMask(val & 1); val>>=1; } @@ -206,12 +218,12 @@ void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) { } } -Bitu DmaController::ReadControllerReg(Bitu reg,Bitu len) { - DmaChannel * chan;Bitu i,ret; +Bitu DmaController::ReadControllerReg(Bitu reg,Bitu /*len*/) { + DmaChannel * chan;Bitu ret; switch (reg) { /* read base address of DMA transfer (1st byte low part, 2nd byte high part) */ case 0x0:case 0x2:case 0x4:case 0x6: - chan=GetChannel(reg >> 1); + chan=GetChannel((Bit8u)(reg >> 1)); flipflop=!flipflop; if (flipflop) { return chan->curraddr & 0xff; @@ -220,7 +232,7 @@ Bitu DmaController::ReadControllerReg(Bitu reg,Bitu len) { } /* read DMA transfer count (1st byte low part, 2nd byte high part) */ case 0x1:case 0x3:case 0x5:case 0x7: - chan=GetChannel(reg >> 1); + chan=GetChannel((Bit8u)(reg >> 1)); flipflop=!flipflop; if (flipflop) { return chan->currcnt & 0xff; @@ -229,12 +241,11 @@ Bitu DmaController::ReadControllerReg(Bitu reg,Bitu len) { } case 0x8: /* Status Register */ ret=0; - for (i=0;i<4;i++) { - chan=GetChannel(i); - if (chan->tcount) ret|=1 << i; + for (Bit8u ct=0;ct<4;ct++) { + chan=GetChannel(ct); + if (chan->tcount) ret|=1 << ct; chan->tcount=false; -// if (chan->callback) ret|=1 << (i+4); - if (chan->request) ret|=1 << (4+i); + if (chan->request) ret|=1 << (4+ct); } return ret; default: @@ -264,15 +275,16 @@ DmaChannel::DmaChannel(Bit8u num, bool dma16) { Bitu DmaChannel::Read(Bitu want, Bit8u * buffer) { Bitu done=0; + curraddr &= dma_wrapping; again: Bitu left=(currcnt+1); if (wantAddDestroyFunction(&DMA_Destroy); Bitu i; From b560a767ef75b68c58febdcb0228db47346c94f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 25 Jul 2009 16:25:43 +0000 Subject: [PATCH 3362/4131] COPY is partially directory-aware (ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3451 --- src/shell/shell_cmds.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 6f27f541..11464510 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.90 2009-04-02 19:08:26 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.91 2009-07-25 16:25:43 c2woody Exp $ */ #include "dosbox.h" #include "shell.h" @@ -570,11 +570,18 @@ void DOS_Shell::CMD_COPY(char * args) { // Concatating files go as follows: All parts except for the last bear the concat flag. // This construction allows them to be counted (only the non concat set) char* source_p = NULL; + char source_x[DOS_PATHLENGTH+CROSS_LEN]; while ( (source_p = StripWord(args)) && *source_p ) { do { char* plus = strchr(source_p,'+'); - if(plus) *plus++ = 0; - sources.push_back(copysource(source_p,(plus)?true:false)); + if (plus) *plus++ = 0; + safe_strncpy(source_x,source_p,CROSS_LEN); + if (DOS_FindFirst(source_p,0xffff & ~DOS_ATTR_VOLUME)) { + dta.GetResult(name,size,date,time,attr); + if (attr & DOS_ATTR_DIRECTORY && !strstr(source_p,"*.*")) + strcat(source_x,"\\*.*"); + } + sources.push_back(copysource(source_x,(plus)?true:false)); source_p = plus; } while(source_p && *source_p); } From e7446204580c77afefd1e8633924e4c6852f8e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 31 Jul 2009 15:36:01 +0000 Subject: [PATCH 3363/4131] add video parameter table for low-number video modes (special usage for cga/tandy/pcjr machines), thanks to hal; some cleanup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3452 --- src/ints/int10.h | 13 ++--- src/ints/int10_memory.cpp | 12 +++-- src/ints/int10_modes.cpp | 38 +++++++++++++-- src/ints/int10_vesa.cpp | 18 +++---- src/ints/int10_vptable.cpp | 98 +++++++++++++++++++++++++++++++++++++- 5 files changed, 153 insertions(+), 26 deletions(-) diff --git a/src/ints/int10.h b/src/ints/int10.h index 7ceee886..23338b31 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.h,v 1.40 2009-07-11 10:25:25 c2woody Exp $ */ +/* $Id: int10.h,v 1.41 2009-07-31 15:36:00 c2woody Exp $ */ #include "vga.h" @@ -102,7 +102,7 @@ extern Bit8u int10_font_14[256 * 14]; extern Bit8u int10_font_16[256 * 16]; struct VideoModeBlock { - Bitu mode; + Bit16u mode; VGAModes type; Bitu swidth, sheight; Bitu twidth, theight; @@ -137,9 +137,9 @@ typedef struct { Bit16u pmode_interface_start; Bit16u pmode_interface_window; Bit16u pmode_interface_palette; - Bitu used; + Bit16u used; } rom; - Bitu vesa_setmode; + Bit16u vesa_setmode; bool vesa_nolfb; bool vesa_oldvbe; } Int10Data; @@ -154,7 +154,7 @@ static Bit8u CURSOR_POS_ROW(Bit8u page) { return real_readb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2+1); } -bool INT10_SetVideoMode(Bitu mode); +bool INT10_SetVideoMode(Bit16u mode); void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit8u attr,Bit8u page); @@ -230,4 +230,5 @@ bool INT10_VideoState_Save(Bitu state,RealPt buffer); bool INT10_VideoState_Restore(Bitu state,RealPt buffer); /* Video Parameter Tables */ -Bitu INT10_SetupVideoParameterTable(PhysPt basepos); +Bit16u INT10_SetupVideoParameterTable(PhysPt basepos); +void INT10_SetupBasicVideoParameterTable(void); diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 253a6052..49e93187 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_memory.cpp,v 1.28 2009-05-27 09:15:42 qbix79 Exp $ */ +/* $Id: int10_memory.cpp,v 1.29 2009-07-31 15:36:01 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -47,7 +47,7 @@ static Bit16u map_offset[8]={ }; void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu height) { - PhysPt ftwhere=PhysMake(0xa000,map_offset[map & 0x7]+offset*32); + PhysPt ftwhere=PhysMake(0xa000,map_offset[map & 0x7]+(Bit16u)(offset*32)); IO_Write(0x3c4,0x2);IO_Write(0x3c5,0x4); //Enable plane 2 IO_Write(0x3ce,0x6);Bitu old_6=IO_Read(0x3cf); IO_Write(0x3cf,0x0); //Disable odd/even and a0000 adressing @@ -58,7 +58,7 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu } IO_Write(0x3c4,0x2);IO_Write(0x3c5,0x3); //Enable textmode planes (0,1) IO_Write(0x3ce,0x6); - if (IS_VGA_ARCH) IO_Write(0x3cf,old_6); //odd/even and b8000 adressing + if (IS_VGA_ARCH) IO_Write(0x3cf,(Bit8u)old_6); //odd/even and b8000 adressing else IO_Write(0x3cf,0x0e); /* Reload tables and registers with new values based on this height */ if (reload) { @@ -69,7 +69,7 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu //Vertical display end bios says, but should stay the same? //Rows setting in bios segment real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,(CurMode->sheight/height)-1); - real_writeb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,height); + real_writeb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,(Bit8u)height); //TODO Reprogram cursor size? } } @@ -181,6 +181,8 @@ void INT10_SetupRomMemory(void) { phys_writed(rom_base+int10.rom.used,0); int10.rom.used+=4; } + INT10_SetupBasicVideoParameterTable(); + if (IS_TANDY_ARCH) { RealSetVec(0x44,int10.rom.font_8_first); } @@ -216,7 +218,7 @@ void INT10_SetupRomMemoryChecksum(void) { Bitu last_rombyte = 32*1024 - 1; //32 KB romsize for (Bitu i = 0;i < last_rombyte;i++) sum += phys_readb(rom_base + i); //OVERFLOW IS OKAY - sum = 256 - sum; + sum = (Bit8u)((256 - (Bitu)sum)&0xff); phys_writeb(rom_base + last_rombyte,sum); } } diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index e1ae1894..e4cd027e 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.87 2009-07-11 10:25:25 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.88 2009-07-31 15:36:01 c2woody Exp $ */ #include @@ -340,7 +340,7 @@ static Bit8u vga_palette[256][3]= }; VideoModeBlock * CurMode; -static bool SetCurMode(VideoModeBlock modeblock[],Bitu mode) { +static bool SetCurMode(VideoModeBlock modeblock[],Bit16u mode) { Bitu i=0; while (modeblock[i].mode!=0xffff) { if (modeblock[i].mode!=mode) i++; @@ -418,7 +418,7 @@ static void FinishSetMode(bool clearmem) { Mouse_NewVideoMode(); } -bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { +bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) { switch (machine) { case MCH_CGA: if (mode>6) return false; @@ -569,12 +569,42 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select); break; } + + RealPt vparams = RealGetVec(0x1d); + if ((vparams != RealMake(0xf000,0xf0a4)) && (mode < 8)) { + // load crtc parameters from video params table + Bit16u crtc_block_index = 0; + if (mode < 2) crtc_block_index = 0; + else if (mode < 4) crtc_block_index = 1; + else if (mode < 7) crtc_block_index = 2; + else { + if (IS_EGAVGA_ARCH) { + if (mode == 7) crtc_block_index = 3; + } else if (machine==MCH_PCJR) { + if (mode < 9) crtc_block_index = 2; + else crtc_block_index = 3; + } + } + + // init CRTC registers + for (Bit16u i = 0; i < 16; i++) + IO_WriteW(crtc_base, i | (real_readb(RealSeg(vparams), + RealOff(vparams) + i + crtc_block_index*16) << 8)); + // mode register + IO_WriteB(crtc_base + 4, real_readb(RealSeg(vparams), + RealOff(vparams) + 4*16 + 24 + mode)); + + if (machine!=MCH_CGA) { + E_Exit("INT10 modeset: video parameter table changed"); + } + } + FinishSetMode(clearmem); return true; } -bool INT10_SetVideoMode(Bitu mode) { +bool INT10_SetVideoMode(Bit16u mode) { bool clearmem=true;Bitu i; if (mode>=0x100) { if ((mode & 0x4000) && int10.vesa_nolfb) return false; diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 605a0e49..82fc350f 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.39 2009-05-27 09:15:42 qbix79 Exp $ */ +/* $Id: int10_vesa.cpp,v 1.40 2009-07-31 15:36:01 c2woody Exp $ */ #include #include @@ -271,7 +271,7 @@ Bit8u VESA_SetSVGAMode(Bit16u mode) { Bit8u VESA_GetSVGAMode(Bit16u & mode) { if (int10.vesa_setmode!=0xffff) mode=int10.vesa_setmode; - else mode=(Bit16u)(CurMode->mode); + else mode=CurMode->mode; return 0x00; } @@ -297,7 +297,7 @@ Bit8u VESA_SetPalette(PhysPt data,Bitu index,Bitu count) { Bit8u r,g,b; if (index>255) return 0x1; if (index+count>256) return 0x1; - IO_Write(0x3c8,index); + IO_Write(0x3c8,(Bit8u)index); while (count) { b = mem_readb(data++); g = mem_readb(data++); @@ -316,7 +316,7 @@ Bit8u VESA_GetPalette(PhysPt data,Bitu index,Bitu count) { Bit8u r,g,b; if (index>255) return 0x1; if (index+count>256) return 0x1; - IO_Write(0x3c7,index); + IO_Write(0x3c7,(Bit8u)index); while (count) { r = IO_Read(0x3c9); g = IO_Read(0x3c9); @@ -428,8 +428,8 @@ Bit8u VESA_GetDisplayStart(Bit16u & x,Bit16u & y) { Bitu pan=vga.config.pel_panning; switch (CurMode->type) { case M_LIN8: - y=times; - x=rem+pan; + y=(Bit16u)times; + x=(Bit16u)(rem+pan); break; default: return 0x1; @@ -503,17 +503,17 @@ void INT10_SetupVESA(void) { int10.rom.pmode_interface_window = int10.rom.used - RealOff( int10.rom.pmode_interface ); phys_writew( Real2Phys(int10.rom.pmode_interface) + 0, int10.rom.pmode_interface_window ); callback.pmWindow=CALLBACK_Allocate(); - int10.rom.used += CALLBACK_Setup(callback.pmWindow, VESA_PMSetWindow, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Window"); + int10.rom.used += (Bit16u)CALLBACK_Setup(callback.pmWindow, VESA_PMSetWindow, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Window"); /* PM Set start call */ int10.rom.pmode_interface_start = int10.rom.used - RealOff( int10.rom.pmode_interface ); phys_writew( Real2Phys(int10.rom.pmode_interface) + 2, int10.rom.pmode_interface_start); callback.pmStart=CALLBACK_Allocate(); - int10.rom.used += CALLBACK_Setup(callback.pmStart, VESA_PMSetStart, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Start"); + int10.rom.used += (Bit16u)CALLBACK_Setup(callback.pmStart, VESA_PMSetStart, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Start"); /* PM Set Palette call */ int10.rom.pmode_interface_palette = int10.rom.used - RealOff( int10.rom.pmode_interface ); phys_writew( Real2Phys(int10.rom.pmode_interface) + 4, int10.rom.pmode_interface_palette); callback.pmPalette=CALLBACK_Allocate(); - int10.rom.used += CALLBACK_Setup(callback.pmPalette, VESA_PMSetPalette, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Palette"); + int10.rom.used += (Bit16u)CALLBACK_Setup(callback.pmPalette, VESA_PMSetPalette, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Palette"); /* Finalize the size and clear the required ports pointer */ phys_writew( Real2Phys(int10.rom.pmode_interface) + 6, 0); int10.rom.pmode_interface_size=int10.rom.used - RealOff( int10.rom.pmode_interface ); diff --git a/src/ints/int10_vptable.cpp b/src/ints/int10_vptable.cpp index c21baf77..375e8b3f 100644 --- a/src/ints/int10_vptable.cpp +++ b/src/ints/int10_vptable.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vptable.cpp,v 1.4 2009-05-27 09:15:42 qbix79 Exp $ */ +/* $Id: int10_vptable.cpp,v 1.5 2009-07-31 15:36:01 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -24,6 +24,77 @@ #include "int10.h" +const Bit8u vparams[] = { + // 40x25 mode 0 and 1 crtc registers + 0x38, 0x28, 0x2d, 0x0a, 0x1f, 0x06, 0x19, 0x1c, 0x02, 0x07, 0x06, 0x07, 0,0,0,0, + // 80x25 mode 2 and 3 crtc registers + 0x71, 0x50, 0x5a, 0x0a, 0x1f, 0x06, 0x19, 0x1c, 0x02, 0x07, 0x06, 0x07, 0,0,0,0, + // graphics modes 4, 5 and 6 + 0x38, 0x28, 0x2d, 0x0a, 0x7f, 0x06, 0x64, 0x70, 0x02, 0x01, 0x06, 0x07, 0,0,0,0, + // mode 7 MDA text + 0x61, 0x50, 0x52, 0x0f, 0x19, 0x06, 0x19, 0x19, 0x02, 0x0d, 0x0b, 0x0c, 0,0,0,0, + // buffer length words 2048, 4096, 16384, 16384 + 0x00, 0x08, 0x00, 0x10, 0x00, 0x40, 0x00, 0x40, + // columns + 40, 40, 80, 80, 40, 40, 80, 80, + // CGA mode register + 0x2c, 0x28, 0x2d, 0x29, 0x2a, 0x2e, 0x1e, 0x29 +}; + +const Bit8u vparams_pcjr[] = { + // 40x25 mode 0 and 1 crtc registers + 0x38, 0x28, 0x2c, 0x06, 0x1f, 0x06, 0x19, 0x1c, 0x02, 0x07, 0x06, 0x07, 0,0,0,0, + // 80x25 mode 2 and 3 crtc registers + 0x71, 0x50, 0x5a, 0x0c, 0x1f, 0x06, 0x19, 0x1c, 0x02, 0x07, 0x06, 0x07, 0,0,0,0, + // graphics modes 4, 5, 6, 8 + 0x38, 0x28, 0x2b, 0x06, 0x7f, 0x06, 0x64, 0x70, 0x02, 0x01, 0x26, 0x07, 0,0,0,0, + // other graphics modes + 0x71, 0x50, 0x56, 0x0c, 0x3f, 0x06, 0x32, 0x38, 0x02, 0x03, 0x26, 0x07, 0,0,0,0, + // buffer length words 2048, 4096, 16384, 16384 + 0x00, 0x08, 0x00, 0x10, 0x00, 0x40, 0x00, 0x40, + // columns + 40, 40, 80, 80, 40, 40, 80, 80, + // CGA mode register + 0x2c, 0x28, 0x2d, 0x29, 0x2a, 0x2e, 0x1e, 0x29 +}; + +const Bit8u vparams_tandy[] = { + // 40x25 mode 0 and 1 crtc registers + 0x38, 0x28, 0x2c, 0x08, 0x1f, 0x06, 0x19, 0x1c, 0x02, 0x07, 0x06, 0x07, 0,0,0,0, + // 80x25 mode 2 and 3 crtc registers + 0x71, 0x50, 0x58, 0x10, 0x1f, 0x06, 0x19, 0x1c, 0x02, 0x07, 0x06, 0x07, 0,0,0,0, + // graphics modes 4, 5 and 6 + 0x38, 0x28, 0x2c, 0x08, 0x7f, 0x06, 0x64, 0x70, 0x02, 0x01, 0x06, 0x07, 0,0,0,0, + // graphics mode 7 + 0x71, 0x50, 0x58, 0x10, 0x3f, 0x06, 0x32, 0x38, 0x02, 0x03, 0x06, 0x07, 0,0,0,0, + // buffer length words 2048, 4096, 16384, 16384 + 0x00, 0x08, 0x00, 0x10, 0x00, 0x40, 0x00, 0x40, + // columns + 40, 40, 80, 80, 40, 40, 80, 80, + // CGA mode register + 0x2c, 0x28, 0x2d, 0x29, 0x2a, 0x2e, 0x1e, 0x29 +}; + +const Bit8u vparams_tandy_td[] = { + // 40x25 mode 0 and 1 crtc registers + 0x38, 0x28, 0x2d, 0x0a, 0x1f, 0x06, 0x19, 0x1c, 0x02, 0x07, 0x06, 0x07, 0,0,0,0, + // 80x25 mode 2 and 3 crtc registers + 0x71, 0x50, 0x5a, 0x0a, 0x1f, 0x06, 0x19, 0x1c, 0x02, 0x07, 0x06, 0x07, 0,0,0,0, + // graphics modes 4, 5 and 6 + 0x38, 0x28, 0x2d, 0x0a, 0x7f, 0x06, 0x64, 0x70, 0x02, 0x01, 0x06, 0x07, 0,0,0,0, + // mode 7 MDA text + 0x61, 0x50, 0x52, 0x0f, 0x19, 0x06, 0x19, 0x19, 0x02, 0x0d, 0x0b, 0x0c, 0,0,0,0, + // ?? mode 2 and 3 crtc registers + 0x71, 0x50, 0x5a, 0x0a, 0x3f, 0x06, 0x32, 0x38, 0x02, 0x03, 0x06, 0x07, 0,0,0,0, + // buffer length words 2048, 4096, 16384, 16384 + 0x00, 0x08, 0x00, 0x10, 0x00, 0x40, 0x00, 0x40, + // columns + 40, 40, 80, 80, 40, 40, 80, 80, + // CGA mode register + 0x2c, 0x28, 0x2d, 0x29, 0x2a, 0x2e, 0x1e, 0x29 +}; + + static Bit8u video_parameter_table_vga[0x40*0x1d]={ // video parameter table for mode 0 (cga emulation) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -447,7 +518,7 @@ static Bit8u video_parameter_table_ega[0x40*0x17]={ }; -Bitu INT10_SetupVideoParameterTable(PhysPt basepos) { +Bit16u INT10_SetupVideoParameterTable(PhysPt basepos) { if (IS_VGA_ARCH) { for (Bitu i=0;i<0x40*0x1d;i++) { phys_writeb(basepos+i,video_parameter_table_vga[i]); @@ -461,6 +532,29 @@ Bitu INT10_SetupVideoParameterTable(PhysPt basepos) { } } +void INT10_SetupBasicVideoParameterTable(void) { + /* video parameter table at F000:F0A4 */ + RealSetVec(0x1d,RealMake(0xF000, 0xF0A4)); + switch (machine) { + case EGAVGA_ARCH_CASE: + case MCH_CGA: + for (Bit16u i = 0; i < sizeof(vparams); i++) { + phys_writeb(0xFF0A4+i,vparams[i]); + } + break; + case MCH_TANDY: + for (Bit16u i = 0; i < sizeof(vparams_tandy); i++) { + phys_writeb(0xFF0A4+i,vparams_tandy[i]); + } + break; + case MCH_PCJR: + for (Bit16u i = 0; i < sizeof(vparams_pcjr); i++) { + phys_writeb(0xFF0A4+i,vparams_pcjr[i]); + } + break; + } +} + #if 0 void INT10_GenerateVideoParameterTable(void) { if (!IS_VGA_ARCH) E_Exit("Be sure that all graphics registers are readable!"); From 15029fe034256df396358e70566ad7aaa228a76d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 31 Jul 2009 16:41:37 +0000 Subject: [PATCH 3364/4131] Fix input in defor. (Buggy handler, but worked in DOS) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3453 --- src/dos/dos.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 5c6cf7e8..2c5ed763 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.118 2009-07-15 17:05:07 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.119 2009-07-31 16:41:37 qbix79 Exp $ */ #include #include @@ -83,6 +83,8 @@ static Bitu DOS_21Handler(void) { { Bit8u c=reg_dl;Bit16u n=1; DOS_WriteFile(STDOUT,&c,&n); + //Not in the official specs, but happens nonetheless. (last written character) + reg_al = c;// reg_al=(c==9)?0x20:c; //Officially: tab to spaces } break; case 0x03: /* Read character from STDAUX */ @@ -115,7 +117,7 @@ static Bitu DOS_21Handler(void) { switch (reg_dl) { case 0xFF: /* Input */ { -//TODO Make this better according to standards + //TODO Make this better according to standards if (!DOS_GetSTDINStatus()) { reg_al=0; CALLBACK_SZF(true); From ff7bd7dc3c9815bdb56f54c4729317eb001dbf20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 1 Aug 2009 13:39:48 +0000 Subject: [PATCH 3365/4131] some refinements to the video parameter table handling Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3454 --- src/ints/int10_modes.cpp | 18 ++++++++++-------- src/ints/int10_vptable.cpp | 13 ++++++------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index e4cd027e..f1a424ff 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.88 2009-07-31 15:36:01 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.89 2009-08-01 13:39:48 c2woody Exp $ */ #include @@ -578,11 +578,11 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) { else if (mode < 4) crtc_block_index = 1; else if (mode < 7) crtc_block_index = 2; else { - if (IS_EGAVGA_ARCH) { - if (mode == 7) crtc_block_index = 3; - } else if (machine==MCH_PCJR) { + if (machine==MCH_PCJR) { if (mode < 9) crtc_block_index = 2; else crtc_block_index = 3; + } else { + if (mode == 7) crtc_block_index = 3; } } @@ -590,11 +590,13 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) { for (Bit16u i = 0; i < 16; i++) IO_WriteW(crtc_base, i | (real_readb(RealSeg(vparams), RealOff(vparams) + i + crtc_block_index*16) << 8)); - // mode register - IO_WriteB(crtc_base + 4, real_readb(RealSeg(vparams), - RealOff(vparams) + 4*16 + 24 + mode)); + if (machine==MCH_CGA) { + // mode register + IO_WriteB(crtc_base + 4, real_readb(RealSeg(vparams), + RealOff(vparams) + 4*16 + 24 + mode)); + } - if (machine!=MCH_CGA) { + if (machine==MCH_TANDY) { E_Exit("INT10 modeset: video parameter table changed"); } } diff --git a/src/ints/int10_vptable.cpp b/src/ints/int10_vptable.cpp index 375e8b3f..7b80fb38 100644 --- a/src/ints/int10_vptable.cpp +++ b/src/ints/int10_vptable.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vptable.cpp,v 1.5 2009-07-31 15:36:01 c2woody Exp $ */ +/* $Id: int10_vptable.cpp,v 1.6 2009-08-01 13:39:48 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -536,12 +536,6 @@ void INT10_SetupBasicVideoParameterTable(void) { /* video parameter table at F000:F0A4 */ RealSetVec(0x1d,RealMake(0xF000, 0xF0A4)); switch (machine) { - case EGAVGA_ARCH_CASE: - case MCH_CGA: - for (Bit16u i = 0; i < sizeof(vparams); i++) { - phys_writeb(0xFF0A4+i,vparams[i]); - } - break; case MCH_TANDY: for (Bit16u i = 0; i < sizeof(vparams_tandy); i++) { phys_writeb(0xFF0A4+i,vparams_tandy[i]); @@ -552,6 +546,11 @@ void INT10_SetupBasicVideoParameterTable(void) { phys_writeb(0xFF0A4+i,vparams_pcjr[i]); } break; + default: + for (Bit16u i = 0; i < sizeof(vparams); i++) { + phys_writeb(0xFF0A4+i,vparams[i]); + } + break; } } From 21612af820e3d9192017ff342aa11acab03aa2b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 2 Aug 2009 16:52:33 +0000 Subject: [PATCH 3366/4131] some big-endian fix for the recompiling core (emulated register access) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3455 --- src/cpu/core_dynrec.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index b4d6d697..df8275c0 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: core_dynrec.cpp,v 1.14 2009-07-22 09:09:35 qbix79 Exp $ */ +/* $Id: core_dynrec.cpp,v 1.15 2009-08-02 16:52:33 c2woody Exp $ */ #include "dosbox.h" @@ -100,9 +100,9 @@ #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]) +#define DRCD_REG_BYTE(reg,idx) (&cpu_regs.regs[reg].byte[idx?BH_INDEX:BL_INDEX]) // 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))) +#define DRCD_REG_WORD(reg,dwrd) ((dwrd)?((void*)(&cpu_regs.regs[reg].dword[DW_INDEX])):((void*)(&cpu_regs.regs[reg].word[W_INDEX]))) enum BlockReturn { @@ -140,6 +140,7 @@ static struct { #define X86_64 0x02 #define MIPSEL 0x03 #define ARMV4LE 0x04 +#define POWERPC 0x04 #if C_TARGETCPU == X86_64 #include "core_dynrec/risc_x64.h" @@ -149,6 +150,8 @@ static struct { #include "core_dynrec/risc_mipsel32.h" #elif C_TARGETCPU == ARMV4LE #include "core_dynrec/risc_armv4le.h" +#elif C_TARGETCPU == POWERPC +#include "core_dynrec/risc_ppc.h" #endif #include "core_dynrec/decoder.h" From b9e085dd5226cb7a10a773331f90a7e0ae11706f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 12 Aug 2009 21:16:09 +0000 Subject: [PATCH 3367/4131] narrow down low-level disk read hack (installers use it as hd-check), thanks to ripsaw; fixes Kick Off 3 regression Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3456 --- src/ints/bios_disk.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 18c53297..6fdafa6d 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.38 2009-05-27 09:15:42 qbix79 Exp $ */ +/* $Id: bios_disk.cpp,v 1.39 2009-08-12 21:16:09 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" @@ -196,7 +196,7 @@ imageDisk::imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHard active = false; hardDrive = isHardDisk; if(!isHardDisk) { - Bitu i=0; + Bit8u i=0; bool founddisk = false; while (DiskGeometryList[i].ksize!=0x0) { if ((DiskGeometryList[i].ksize==imgSizeK) || @@ -349,12 +349,15 @@ static Bitu INT13_DiskHandler(void) { CALLBACK_SCF(true); return CBRET_NONE; } - if(!any_images && (reg_dh == 0)) { // Inherit the Earth cdrom (uses it as disk test) - reg_ah = 0; - CALLBACK_SCF(false); - return CBRET_NONE; + if (!any_images) { + // Inherit the Earth cdrom (uses it as disk test) + if (((reg_dl&0x80)==0x80) && (reg_dh==0) && ((reg_cl&0x3f)==1)) { + reg_ah = 0; + CALLBACK_SCF(false); + return CBRET_NONE; + } } - if(driveInactive(drivenum)) { + if (driveInactive(drivenum)) { reg_ah = 0xff; CALLBACK_SCF(true); return CBRET_NONE; From 404af77c9b83e38142c7d1bf2b0a3e3f01e93b60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 15 Aug 2009 09:32:20 +0000 Subject: [PATCH 3368/4131] allow working-directory specifying for copy parameters (ripsaw; fixes Wrath of Earth regression) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3457 --- src/shell/shell_cmds.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 11464510..8566b0c6 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.91 2009-07-25 16:25:43 c2woody Exp $ */ +/* $Id: shell_cmds.cpp,v 1.92 2009-08-15 09:32:20 c2woody Exp $ */ #include "dosbox.h" #include "shell.h" @@ -576,10 +576,17 @@ void DOS_Shell::CMD_COPY(char * args) { char* plus = strchr(source_p,'+'); if (plus) *plus++ = 0; safe_strncpy(source_x,source_p,CROSS_LEN); - if (DOS_FindFirst(source_p,0xffff & ~DOS_ATTR_VOLUME)) { - dta.GetResult(name,size,date,time,attr); - if (attr & DOS_ATTR_DIRECTORY && !strstr(source_p,"*.*")) - strcat(source_x,"\\*.*"); + bool has_drive_spec = false; + size_t source_x_len = strlen(source_x); + if (source_x_len>0) { + if (source_x[source_x_len-1]==':') has_drive_spec = true; + } + if (!has_drive_spec) { + if (DOS_FindFirst(source_p,0xffff & ~DOS_ATTR_VOLUME)) { + dta.GetResult(name,size,date,time,attr); + if (attr & DOS_ATTR_DIRECTORY && !strstr(source_p,"*.*")) + strcat(source_x,"\\*.*"); + } } sources.push_back(copysource(source_x,(plus)?true:false)); source_p = plus; From decb3823d2973492f6ffdc32f014b9fae2c58997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 23 Aug 2009 17:24:54 +0000 Subject: [PATCH 3369/4131] int13 unconditionally enables the interrupt flag on return (ripsaw, fixes some pirates booter version); change the set/clear flag for callback return functions a bit (hal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3458 --- include/callback.h | 3 ++- src/cpu/callback.cpp | 23 ++++++++++++++++------- src/ints/bios_disk.cpp | 5 ++++- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/include/callback.h b/include/callback.h index 53bc39c0..d1240ee2 100644 --- a/include/callback.h +++ b/include/callback.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.h,v 1.25 2009-06-11 16:05:17 c2woody Exp $ */ +/* $Id: callback.h,v 1.26 2009-08-23 17:24:54 c2woody Exp $ */ #ifndef DOSBOX_CALLBACK_H #define DOSBOX_CALLBACK_H @@ -71,6 +71,7 @@ bool CALLBACK_Free(Bitu callback); void CALLBACK_SCF(bool val); void CALLBACK_SZF(bool val); +void CALLBACK_SIF(bool val); extern Bitu call_priv_io; diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index b5d88089..1d21062e 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.41 2009-06-11 16:05:17 c2woody Exp $ */ +/* $Id: callback.cpp,v 1.42 2009-08-23 17:24:54 c2woody Exp $ */ #include #include @@ -109,15 +109,24 @@ void CALLBACK_RunRealInt(Bit8u intnum) { } void CALLBACK_SZF(bool val) { - Bit16u tempf=mem_readw(SegPhys(ss)+reg_sp+4) & 0xFFBF; - Bit16u newZF=(val==true) << 6; - mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newZF)); + Bit16u tempf = mem_readw(SegPhys(ss)+reg_sp+4); + if (val) tempf |= FLAG_ZF; + else tempf &= ~FLAG_ZF; + mem_writew(SegPhys(ss)+reg_sp+4,tempf); } void CALLBACK_SCF(bool val) { - Bit16u tempf=mem_readw(SegPhys(ss)+reg_sp+4) & 0xFFFE; - Bit16u newCF=(val==true); - mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newCF)); + Bit16u tempf = mem_readw(SegPhys(ss)+reg_sp+4); + if (val) tempf |= FLAG_CF; + else tempf &= ~FLAG_CF; + mem_writew(SegPhys(ss)+reg_sp+4,tempf); +} + +void CALLBACK_SIF(bool val) { + Bit16u tempf = mem_readw(SegPhys(ss)+reg_sp+4); + if (val) tempf |= FLAG_IF; + else tempf &= ~FLAG_IF; + mem_writew(SegPhys(ss)+reg_sp+4,tempf); } void CALLBACK_SetDescription(Bitu nr, const char* descr) { diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 6fdafa6d..9b0289e4 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.39 2009-08-12 21:16:09 c2woody Exp $ */ +/* $Id: bios_disk.cpp,v 1.40 2009-08-23 17:24:54 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" @@ -309,6 +309,9 @@ static Bitu INT13_DiskHandler(void) { if(imageDiskList[i]) any_images=true; } + // unconditionally enable the interrupt flag + CALLBACK_SIF(true); + //drivenum = 0; //LOG_MSG("INT13: Function %x called on drive %x (dos drive %d)", reg_ah, reg_dl, drivenum); switch(reg_ah) { From f34415335623f75e27c7da66305ce0e2d855bba0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 31 Aug 2009 18:03:08 +0000 Subject: [PATCH 3370/4131] Array overflow. Borland c++ 4.5 installer. (thank you for the report luagnome) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3459 --- src/dos/dos_files.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index b161fc93..875a189b 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.112 2009-07-09 20:06:57 c2woody Exp $ */ +/* $Id: dos_files.cpp,v 1.113 2009-08-31 18:03:08 qbix79 Exp $ */ #include #include @@ -188,7 +188,7 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { bool DOS_GetCurrentDir(Bit8u drive,char * const buffer) { if (drive==0) drive=DOS_GetDefaultDrive(); else drive--; - if ((drive>DOS_DRIVES) || (!Drives[drive])) { + if ((drive>=DOS_DRIVES) || (!Drives[drive])) { DOS_SetError(DOSERR_INVALID_DRIVE); return false; } @@ -665,7 +665,7 @@ bool DOS_Canonicalize(char const * const name,char * const big) { bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit8u * sectors,Bit16u * clusters,Bit16u * free) { if (drive==0) drive=DOS_GetDefaultDrive(); else drive--; - if ((drive>DOS_DRIVES) || (!Drives[drive])) { + if ((drive>=DOS_DRIVES) || (!Drives[drive])) { DOS_SetError(DOSERR_INVALID_DRIVE); return false; } From 36868f0b7db77e201bc1fa7ebca5c8ea056ae249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 3 Sep 2009 16:03:01 +0000 Subject: [PATCH 3371/4131] initialize GUS register (thanks to peter ferrie for checking this out) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3460 --- src/hardware/gus.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 34ecc28a..727ad07e 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: gus.cpp,v 1.36 2009-04-27 17:11:26 qbix79 Exp $ */ +/* $Id: gus.cpp,v 1.37 2009-09-03 16:03:01 c2woody Exp $ */ #include #include @@ -338,7 +338,9 @@ static void GUSReset(void) { myGUS.timers[1].value = 0xff; myGUS.timers[0].delay = 0.080f; myGUS.timers[1].delay = 0.320f; + myGUS.ChangeIRQDMA = false; + myGUS.mixControl = 0x0b; // latches enabled by default LINEs disabled // Stop all channels int i; for(i=0;i<32;i++) { @@ -633,11 +635,11 @@ static void write_gus(Bitu port,Bitu val,Bitu iolen) { // LOG_MSG("Write gus port %x val %x",port,val); switch(port - GUS_BASE) { case 0x200: - myGUS.mixControl = val; + myGUS.mixControl = (Bit8u)val; myGUS.ChangeIRQDMA = true; return; case 0x208: - adlib_commandreg = val; + adlib_commandreg = (Bit8u)val; break; case 0x209: //TODO adlib_commandreg should be 4 for this to work else it should just latch the value @@ -684,21 +686,21 @@ static void write_gus(Bitu port,Bitu val,Bitu iolen) { curchan = guschan[myGUS.gCurChannel]; break; case 0x303: - myGUS.gRegSelect = val; + myGUS.gRegSelect = (Bit8u)val; myGUS.gRegData = 0; break; case 0x304: if (iolen==2) { - myGUS.gRegData=val; + myGUS.gRegData=(Bit16u)val; ExecuteGlobRegister(); - } else myGUS.gRegData = val; + } else myGUS.gRegData = (Bit16u)val; break; case 0x305: - myGUS.gRegData = (0x00ff & myGUS.gRegData) | val << 8; + myGUS.gRegData = (Bit16u)((0x00ff & myGUS.gRegData) | val << 8); ExecuteGlobRegister(); break; case 0x307: - if(myGUS.gDramAddr < sizeof(GUSRam)) GUSRam[myGUS.gDramAddr] = val; + if(myGUS.gDramAddr < sizeof(GUSRam)) GUSRam[myGUS.gDramAddr] = (Bit8u)val; break; default: #if LOG_GUS From 9c2a664661c37055d7c500caea4423bd5841fd9c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 5 Sep 2009 11:10:04 +0000 Subject: [PATCH 3372/4131] Small rewrite by ih8regs. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3461 --- src/hardware/mixer.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 6999ba7d..d5a29ce7 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.53 2009-04-28 21:48:24 harekiet Exp $ */ +/* $Id: mixer.cpp,v 1.54 2009-09-05 11:10:04 qbix79 Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -147,12 +147,8 @@ void MixerChannel::Mix(Bitu _needed) { needed=_needed; while (enabled && needed>done) { Bitu todo=needed-done; - todo*=freq_add; - if (todo & MIXER_REMAIN) { - todo=(todo >> MIXER_SHIFT) + 1; - } else { - todo=(todo >> MIXER_SHIFT); - } + todo *= freq_add; + todo = (todo >> MIXER_SHIFT) + ((todo & MIXER_REMAIN)!=0); handler(todo); } } From 9cab1737b87775096c55f6cd5d5c80c026cec3a5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 5 Sep 2009 11:38:15 +0000 Subject: [PATCH 3373/4131] This is more pretty accoring to the experts *cough* Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3462 --- src/gui/render_templates.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index b2461ac7..4959d457 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -349,12 +349,12 @@ static void conc3d(Cache,SBPP,DBPP) (const void * s) { line0[0]=P; \ line0[1]=P & greenMask; \ line0[2]=P & blueMask; \ - line1[0]=P & blueMask; \ - line1[1]=P; \ - line1[2]=P & redMask; \ - line2[0]=P & redMask; \ - line2[1]=P & greenMask; \ - line2[2]=P; + line1[0]=P & greenMask; \ + line1[1]=P & redMask; \ + line1[2]=P; \ + line2[0]=P; \ + line2[1]=P & blueMask; \ + line2[2]=P & redMask; #include "render_simple.h" #undef SCALERNAME #undef SCALERWIDTH From 75d7ee65e9871d3bdffd4617253f43038c9ecb37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 6 Sep 2009 19:25:34 +0000 Subject: [PATCH 3374/4131] add special int10 scanline modifying function (hal, fixes some mz700 emulator and others) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3463 --- src/dos/dos_keyboard_layout.cpp | 5 +-- src/ints/int10.cpp | 43 +++++++++++++++++++--- src/ints/int10.h | 3 +- src/ints/int10_memory.cpp | 17 ++++++++- src/ints/int10_modes.cpp | 65 ++++++++++++++++++++++++--------- 5 files changed, 104 insertions(+), 29 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 1d828870..661ca88c 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_keyboard_layout.cpp,v 1.21 2009-04-01 18:30:41 c2woody Exp $ */ +/* $Id: dos_keyboard_layout.cpp,v 1.22 2009-09-06 19:25:33 c2woody Exp $ */ #include "dosbox.h" #include "bios.h" @@ -935,8 +935,7 @@ Bitu keyboard_layout::read_codepage_file(const char* codepage_file_name, Bit32s // update font if necessary if (font_changed && (CurMode->type==M_TEXT) && (IS_EGAVGA_ARCH)) { - if (IS_VGA_ARCH) INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); - else INT10_LoadFont(Real2Phys(int10.rom.font_14),true,256,0,0,14); + INT10_ReloadFont(); } INT10_SetupRomMemoryChecksum(); diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 1e25c925..62b638ba 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.cpp,v 1.55 2009-04-11 07:58:39 qbix79 Exp $ */ +/* $Id: int10.cpp,v 1.56 2009-09-06 19:25:34 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -329,11 +329,42 @@ graphics_chars: case 0x20: /* Set alternate printscreen */ break; case 0x30: /* Select vertical resolution */ - if (!IS_VGA_ARCH) break; - LOG(LOG_INT10,LOG_ERROR)("Function 12:Call %2X not handled",reg_bl); - if (reg_al>2) reg_al=0; //invalid subfunction - else reg_al=0x12; //fake a success call - break; + { + if (!IS_VGA_ARCH) break; + LOG(LOG_INT10,LOG_WARN)("Function 12:Call %2X (select vertical resolution)",reg_bl); + if (svgaCard != SVGA_None) { + if (reg_al > 2) { + reg_al=0; // invalid subfunction + break; + } + } + Bit8u modeset_ctl = real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); + Bit8u video_switches = real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES)&0xf0; + switch(reg_al) { + case 0: // 200 + modeset_ctl &= 0xef; + modeset_ctl |= 0x80; + video_switches |= 8; // ega normal/cga emulation + break; + case 1: // 350 + modeset_ctl &= 0x6f; + video_switches |= 9; // ega enhanced + break; + case 2: // 400 + modeset_ctl &= 0x6f; + modeset_ctl |= 0x10; // use 400-line mode at next mode set + video_switches |= 9; // ega enhanced + break; + default: + modeset_ctl &= 0xef; + video_switches |= 8; // ega normal/cga emulation + break; + } + real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,modeset_ctl); + real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,video_switches); + reg_al=0x12; // success + break; + } case 0x31: /* Palette loading on modeset */ { if (!IS_VGA_ARCH) break; diff --git a/src/ints/int10.h b/src/ints/int10.h index 23338b31..4e0fd1ce 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.h,v 1.41 2009-07-31 15:36:00 c2woody Exp $ */ +/* $Id: int10.h,v 1.42 2009-09-06 19:25:34 c2woody Exp $ */ #include "vga.h" @@ -175,6 +175,7 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color); /* Font Stuff */ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu height); +void INT10_ReloadFont(void); /* Palette Group */ void INT10_SetBackgroundBorder(Bit8u val); diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 49e93187..1c0ee0ab 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_memory.cpp,v 1.29 2009-07-31 15:36:01 c2woody Exp $ */ +/* $Id: int10_memory.cpp,v 1.30 2009-09-06 19:25:34 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -74,6 +74,21 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu } } +void INT10_ReloadFont(void) { + switch(CurMode->cheight) { + case 8: + INT10_LoadFont(Real2Phys(int10.rom.font_8_first),true,256,0,0,8); + break; + case 14: + INT10_LoadFont(Real2Phys(int10.rom.font_14),true,256,0,0,14); + break; + case 16: + default: + INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); + break; + } +} + void INT10_SetupRomMemory(void) { /* This should fill up certain structures inside the Video Bios Rom Area */ diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index f1a424ff..4acd8f00 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.89 2009-08-01 13:39:48 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.90 2009-09-06 19:25:34 c2woody Exp $ */ #include @@ -124,6 +124,22 @@ VideoModeBlock ModeList_VGA[]={ {0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, }; +VideoModeBlock ModeList_VGA_Text_200lines[]={ +/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */ +{ 0x000 ,M_TEXT ,320 ,200 ,40 ,25 ,8 , 8 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x001 ,M_TEXT ,320 ,200 ,40 ,25 ,8 , 8 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x002 ,M_TEXT ,640 ,200 ,80 ,25 ,8 , 8 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE }, +{ 0x003 ,M_TEXT ,640 ,200 ,80 ,25 ,8 , 8 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE } +}; + +VideoModeBlock ModeList_VGA_Text_350lines[]={ +/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */ +{ 0x000 ,M_TEXT ,320 ,350 ,40 ,25 ,8 ,14 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,350 ,_EGA_HALF_CLOCK }, +{ 0x001 ,M_TEXT ,320 ,350 ,40 ,25 ,8 ,14 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,350 ,_EGA_HALF_CLOCK }, +{ 0x002 ,M_TEXT ,640 ,350 ,80 ,25 ,8 ,14 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,350 ,0 }, +{ 0x003 ,M_TEXT ,640 ,350 ,80 ,25 ,8 ,14 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,350 ,0 } +}; + VideoModeBlock ModeList_VGA_Tseng[]={ /* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */ { 0x000 ,M_TEXT ,360 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, @@ -394,7 +410,6 @@ static void FinishSetMode(bool clearmem) { real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,(Bit16u)CurMode->cheight); real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem?0:0x80))); real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0x09); - real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); // this is an index into the dcc table: if (IS_VGA_ARCH) real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x0b); @@ -620,7 +635,11 @@ bool INT10_SetVideoMode(Bit16u mode) { int10.vesa_setmode=0xffff; LOG(LOG_INT10,LOG_NORMAL)("Set Video Mode %X",mode); if (!IS_EGAVGA_ARCH) return INT10_SetVideoMode_OTHER(mode,clearmem); - Bit8u modeset_ctl,video_ctl,vga_switches; + + /* First read mode setup settings from bios area */ +// Bit8u video_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL); +// Bit8u vga_switches=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES); + Bit8u modeset_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); if (IS_VGA_ARCH) { if (svga.accepts_mode) { @@ -647,6 +666,18 @@ bool INT10_SetVideoMode(Bit16u mode) { return false; } } + // check for scanline backwards compatibility (VESA text modes??) + if (CurMode->type==M_TEXT) { + if ((modeset_ctl&0x90)==0x80) { // 200 lines emulation + if (CurMode->mode <= 3) { + CurMode = &ModeList_VGA_Text_200lines[CurMode->mode]; + } + } else if ((modeset_ctl&0x90)==0x00) { // 350 lines emulation + if (CurMode->mode <= 3) { + CurMode = &ModeList_VGA_Text_350lines[CurMode->mode]; + } + } + } } else { if (!SetCurMode(ModeList_EGA,mode)){ LOG(LOG_INT10,LOG_ERROR)("EGA:Trying to set illegal mode %X",mode); @@ -654,11 +685,6 @@ bool INT10_SetVideoMode(Bit16u mode) { } } - /* First read mode setup settings from bios area */ - video_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL); - vga_switches=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES); - modeset_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); - /* Setup the VGA to the correct mode */ Bit16u crtc_base; @@ -675,11 +701,14 @@ bool INT10_SetVideoMode(Bit16u mode) { /* Setup MISC Output Register */ Bit8u misc_output=0x2 | (mono_mode ? 0x0 : 0x1); + if ((CurMode->type==M_TEXT) && (CurMode->cwidth==9)) { + // 28MHz (16MHz EGA) clock for 9-pixel wide chars + misc_output|=0x4; + } + switch (CurMode->vdispend) { case 400: misc_output|=0x60; - if (CurMode->type==M_TEXT) // && (CurMode->pstart==0xB8000)) - misc_output|=0x4; break; case 480: misc_output|=0xe0; @@ -695,12 +724,13 @@ bool INT10_SetVideoMode(Bit16u mode) { /* Program Sequencer */ Bit8u seq_data[SEQ_REGS]; memset(seq_data,0,SEQ_REGS); - if (CurMode->cwidth==8) seq_data[1]|=1; //8 dot fonts by default + seq_data[1]|=0x01; //8 dot fonts by default if (CurMode->special & _EGA_HALF_CLOCK) seq_data[1]|=0x08; //Check for half clock if ((machine==MCH_EGA) && (CurMode->special & _EGA_HALF_CLOCK)) seq_data[1]|=0x02; seq_data[4]|=0x02; //More than 64kb switch (CurMode->type) { case M_TEXT: + if (CurMode->cwidth==9) seq_data[1] &= ~1; seq_data[2]|=0x3; //Enable plane 0 and 1 seq_data[4]|=0x01; //Alpanumeric if (IS_VGA_ARCH) seq_data[4]|=0x04; //odd/even enabled @@ -1067,12 +1097,12 @@ bool INT10_SetVideoMode(Bit16u mode) { for (Bit8u ct=0;ct<16;ct++) att_data[ct]=ct; break; case M_TEXT: - if (machine==MCH_EGA) { - att_data[0x13]=0x00; - att_data[0x10]=0x08; //8 Bit characters - } else { + if (CurMode->cwidth==9) { att_data[0x13]=0x08; //Pel panning on 8, although we don't have 9 dot text mode - att_data[0x10]=0x0C; //Color Text with blinking + att_data[0x10]=0x0C; //Color Text with blinking, 9 Bit characters + } else { + att_data[0x13]=0x00; + att_data[0x10]=0x08; //Color Text with blinking, 8 Bit characters } real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x30); att_text16: @@ -1340,8 +1370,7 @@ dac_text16: /* Load text mode font */ if (CurMode->type==M_TEXT) { - if (IS_VGA_ARCH) INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); - else INT10_LoadFont(Real2Phys(int10.rom.font_14),true,256,0,0,14); + INT10_ReloadFont(); } return true; } From 035a5b8a005927680a55596e97fcab37e41b8ee3 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Thu, 10 Sep 2009 17:44:57 +0000 Subject: [PATCH 3375/4131] In Hercules mode the cursor should always be monochrome. Fixes part of SF Bug 2833492. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3464 --- src/hardware/vga_draw.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 8175ca25..89f94de2 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.110 2009-07-11 10:25:24 c2woody Exp $ */ +/* $Id: vga_draw.cpp,v 1.111 2009-09-10 17:44:57 h-a-l-9000 Exp $ */ #include #include @@ -428,8 +428,16 @@ static Bit8u * VGA_TEXT_Herc_Draw_Line(Bitu vidstart, Bitu line) { if (linevga.draw.cursor.eline) goto skip_cursor; draw=(Bit32u *)&TempLine[font_addr*8]; - Bit32u att=TXT_FG_Table[vga.tandy.draw_base[vga.draw.cursor.address+1]&0xf]; - *draw++=att;*draw++=att; + Bit8u attr = vga.tandy.draw_base[vga.draw.cursor.address+1]; + Bit32u cg; + if (attr&0x8) { + cg = TXT_FG_Table[0xf]; + } else if ((attr&0x77)==0x70) { + cg = TXT_FG_Table[0x0]; + } else { + cg = TXT_FG_Table[0x7]; + } + *draw++=cg;*draw++=cg; } skip_cursor: return TempLine; From 30822d48953ca4801f77e5cdd2af4f31bcb91fa4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 16 Sep 2009 18:01:53 +0000 Subject: [PATCH 3376/4131] FFREEP. (thanks ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3465 --- src/debug/debug_disasm.cpp | 3 ++- src/fpu/fpu.cpp | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/debug/debug_disasm.cpp b/src/debug/debug_disasm.cpp index 66a9820d..5b642962 100644 --- a/src/debug/debug_disasm.cpp +++ b/src/debug/debug_disasm.cpp @@ -398,6 +398,7 @@ static char const *fop_52[] = { "*fsubrp %GF,st" }; static char const *fop_53[] = { "*fsubp %GF,st" }; static char const *fop_54[] = { "*fdivrp %GF,st" }; static char const *fop_55[] = { "*fdivp %GF,st" }; +static char const *fop_56[] = { "*ffreep %GF" }; static char const *fop_60[] = { "fstsw ax", 0, 0, 0, 0, 0, 0, 0 }; static char const **fspecial[] = { /* 0=use st(i), 1=undefined 0 in fop_* means undefined */ @@ -408,7 +409,7 @@ static char const **fspecial[] = { /* 0=use st(i), 1=undefined 0 in fop_* means fop_32, fop_33, fop_34, fop_35, fop_36, fop_37, fop_38, fop_39, fop_40, fop_41, fop_42, fop_43, fop_44, fop_45, f0, f0, fop_48, fop_49, fop_50, fop_51, fop_52, fop_53, fop_54, fop_55, - f0, f0, f0, f0, fop_60, f0, f0, f0, + fop_56, f0, f0, f0, fop_60, f0, f0, f0, }; static const char *floatops[] = { /* assumed " %EF" at end of each. mod != 3 only */ diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 64dfae3c..fade5f1e 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu.cpp,v 1.30 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: fpu.cpp,v 1.31 2009-09-16 18:01:53 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU @@ -594,6 +594,10 @@ void FPU_ESC7_Normal(Bitu rm) { Bitu group=(rm >> 3) & 7; Bitu sub=(rm & 7); switch (group){ + case 0x00: /* FFREEP STi*/ + fpu.tags[STV(sub)]=TAG_Empty; + FPU_FPOP(); + break; case 0x01: /* FXCH STi*/ FPU_FXCH(TOP,STV(sub)); break; From 2970dead37c291cfa426ef011c626d416e46b301 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Mon, 21 Sep 2009 21:04:25 +0000 Subject: [PATCH 3377/4131] Add the /B option to the DIR command Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3466 --- src/shell/shell_cmds.cpp | 91 +++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 8566b0c6..e04e018d 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.92 2009-08-15 09:32:20 c2woody Exp $ */ +/* $Id: shell_cmds.cpp,v 1.93 2009-09-21 21:04:25 h-a-l-9000 Exp $ */ #include "dosbox.h" #include "shell.h" @@ -404,6 +404,10 @@ void DOS_Shell::CMD_DIR(char * args) { bool optW=ScanCMDBool(args,"W"); ScanCMDBool(args,"S"); bool optP=ScanCMDBool(args,"P"); + if (ScanCMDBool(args,"WP") || ScanCMDBool(args,"PW")) { + optW=optP=true; + } + bool optB=ScanCMDBool(args,"B"); bool optAD=ScanCMDBool(args,"AD"); char * rem=ScanCMDRemain(args); if (rem) { @@ -450,7 +454,7 @@ void DOS_Shell::CMD_DIR(char * args) { return; } *(strrchr(path,'\\')+1)=0; - WriteOut(MSG_Get("SHELL_CMD_DIR_INTRO"),path); + if (!optB) WriteOut(MSG_Get("SHELL_CMD_DIR_INTRO"),path); /* Command uses dta so set it to our internal dta */ RealPt save_dta=dos.dta(); @@ -458,7 +462,7 @@ void DOS_Shell::CMD_DIR(char * args) { DOS_DTA dta(dos.dta()); bool ret=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME); if (!ret) { - WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); + if (!optB) WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); dos.dta(save_dta); return; } @@ -483,53 +487,62 @@ void DOS_Shell::CMD_DIR(char * args) { Bit8u minute = (Bit8u)((time >> 5) & 0x003f); /* output the file */ - if (attr & DOS_ATTR_DIRECTORY) { - if (optW) { - WriteOut("[%s]",name); - size_t namelen = strlen(name); - if (namelen <= 14) { - for (size_t i=14-namelen;i>0;i--) WriteOut(" "); - } - } else { - WriteOut("%-8s %-3s %-16s %02d-%02d-%04d %2d:%02d\n",name,ext,"",day,month,year,hour,minute); + if (optB) { + // this overrides pretty much everything + if (strcmp(".",name) && strcmp("..",name)) { + if ((attr & DOS_ATTR_DIRECTORY)||(strlen(ext)==0)) WriteOut("%s\n",name); + else WriteOut("%s.%s\n",name,ext); } - dir_count++; } else { - if (optW) { - WriteOut("%-16s",name); + if (attr & DOS_ATTR_DIRECTORY) { + if (optW) { + WriteOut("[%s]",name); + size_t namelen = strlen(name); + if (namelen <= 14) { + for (size_t i=14-namelen;i>0;i--) WriteOut(" "); + } + } else { + WriteOut("%-8s %-3s %-16s %02d-%02d-%04d %2d:%02d\n",name,ext,"",day,month,year,hour,minute); + } + dir_count++; } else { - FormatNumber(size,numformat); - WriteOut("%-8s %-3s %16s %02d-%02d-%04d %2d:%02d\n",name,ext,numformat,day,month,year,hour,minute); + if (optW) { + WriteOut("%-16s",name); + } else { + FormatNumber(size,numformat); + WriteOut("%-8s %-3s %16s %02d-%02d-%04d %2d:%02d\n",name,ext,numformat,day,month,year,hour,minute); + } + file_count++; + byte_count+=size; } - file_count++; - byte_count+=size; - } - if (optW) { - w_count++; - } - if(optP) { - if(!(++p_count%(22*w_size))) { - CMD_PAUSE(empty_string); + if (optW) { + w_count++; + } + if (optP) { + if (!(++p_count%(22*w_size))) { + CMD_PAUSE(empty_string); + } } } } while ( (ret=DOS_FindNext()) ); if (optW) { if (w_count%5) WriteOut("\n"); } - - /* Show the summary of results */ - FormatNumber(byte_count,numformat); - WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_USED"),file_count,numformat); - Bit8u drive=dta.GetSearchDrive(); - //TODO Free Space - Bitu free_space=1024*1024*100; - if (Drives[drive]) { - Bit16u bytes_sector;Bit8u sectors_cluster;Bit16u total_clusters;Bit16u free_clusters; - Drives[drive]->AllocationInfo(&bytes_sector,§ors_cluster,&total_clusters,&free_clusters); - free_space=bytes_sector*sectors_cluster*free_clusters; + if (!optB) { + /* Show the summary of results */ + FormatNumber(byte_count,numformat); + WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_USED"),file_count,numformat); + Bit8u drive=dta.GetSearchDrive(); + //TODO Free Space + Bitu free_space=1024*1024*100; + if (Drives[drive]) { + Bit16u bytes_sector;Bit8u sectors_cluster;Bit16u total_clusters;Bit16u free_clusters; + Drives[drive]->AllocationInfo(&bytes_sector,§ors_cluster,&total_clusters,&free_clusters); + free_space=bytes_sector*sectors_cluster*free_clusters; + } + FormatNumber(free_space,numformat); + WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_FREE"),dir_count,numformat); } - FormatNumber(free_space,numformat); - WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_FREE"),dir_count,numformat); dos.dta(save_dta); } From 25c7518a8c373098934693de47af6e1b61f436fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 22 Sep 2009 21:48:08 +0000 Subject: [PATCH 3378/4131] backwrap directory iterator variable for iso drive in free iterator function (thanks to rcblanke; fixes armored fist 2 installer on an iso drive) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3467 --- src/dos/drive_iso.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index c3451001..4135d734 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.26 2009-06-19 18:28:10 c2woody Exp $ */ +/* $Id: drive_iso.cpp,v 1.27 2009-09-22 21:48:08 c2woody Exp $ */ #include #include @@ -430,7 +430,11 @@ void isoDrive::FreeDirIterator(const int dirIterator) { // if this was the last aquired iterator decrement nextFreeIterator if ((dirIterator + 1) % MAX_OPENDIRS == nextFreeDirIterator) { - nextFreeDirIterator--; + if (nextFreeDirIterator>0) { + nextFreeDirIterator--; + } else { + nextFreeDirIterator = MAX_OPENDIRS-1; + } } } From d04f128aaeac931ccfddfc8beffb72d2c054f016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 23 Sep 2009 20:55:19 +0000 Subject: [PATCH 3379/4131] add undocumented ffreep fpu instruction to the recompilers (thanks to ripsaw for figuring this out; fixes Trucks) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3468 --- src/cpu/core_dyn_x86/dyn_fpu.h | 7 ++++++- src/cpu/core_dyn_x86/dyn_fpu_dh.h | 6 +++++- src/cpu/core_dynrec/dyn_fpu.h | 7 +++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_dyn_x86/dyn_fpu.h b/src/cpu/core_dyn_x86/dyn_fpu.h index 1373fecf..90e3ba09 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu.h +++ b/src/cpu/core_dyn_x86/dyn_fpu.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dyn_fpu.h,v 1.4 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: dyn_fpu.h,v 1.5 2009-09-23 20:55:19 c2woody Exp $ */ #include "dosbox.h" #if C_FPU @@ -593,6 +593,11 @@ static void dyn_fpu_esc7(){ Bitu sub=(decode.modrm.val & 7); if (decode.modrm.val >= 0xc0) { switch (group){ + case 0x00: /* FFREEP STi*/ + dyn_fpu_top(); + gen_call_function((void*)&FPU_FFREE,"%Ddr",DREG(EA)); + gen_call_function((void*)&FPU_FPOP,""); + break; case 0x01: /* FXCH STi*/ dyn_fpu_top(); gen_call_function((void*)&FPU_FXCH,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); diff --git a/src/cpu/core_dyn_x86/dyn_fpu_dh.h b/src/cpu/core_dyn_x86/dyn_fpu_dh.h index d4d606f0..cc49fe55 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu_dh.h +++ b/src/cpu/core_dyn_x86/dyn_fpu_dh.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dyn_fpu_dh.h,v 1.6 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: dyn_fpu_dh.h,v 1.7 2009-09-23 20:55:19 c2woody Exp $ */ #include "dosbox.h" #if C_FPU @@ -408,6 +408,10 @@ static void dh_fpu_esc7(){ Bitu sub=(decode.modrm.val & 7); if (decode.modrm.val >= 0xc0) { switch (group){ + case 0x00: /* FFREEP STi*/ + cache_addb(0xdf); + cache_addb(decode.modrm.val); + break; case 0x01: /* FXCH STi*/ cache_addb(0xdf); cache_addb(decode.modrm.val); diff --git a/src/cpu/core_dynrec/dyn_fpu.h b/src/cpu/core_dynrec/dyn_fpu.h index 6d3e7091..43ebff4d 100644 --- a/src/cpu/core_dynrec/dyn_fpu.h +++ b/src/cpu/core_dynrec/dyn_fpu.h @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: dyn_fpu.h,v 1.8 2009-09-23 20:55:19 c2woody Exp $ */ + #include "dosbox.h" #if C_FPU @@ -602,6 +604,11 @@ static void dyn_fpu_esc7(){ dyn_get_modrm(); if (decode.modrm.val >= 0xc0) { switch (decode.modrm.reg){ + case 0x00: /* FFREEP STi */ + dyn_fpu_top(); + gen_call_function_R((void*)&FPU_FFREE,FC_OP2); + gen_call_function_raw((void*)&FPU_FPOP); + break; case 0x01: /* FXCH STi*/ dyn_fpu_top(); gen_call_function_RR((void*)&FPU_FXCH,FC_OP1,FC_OP2); From 5ce390285d6f0b568fda09c48aa02904abac5edf Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Sep 2009 19:20:46 +0000 Subject: [PATCH 3380/4131] add some more cmpxchg stuff. Normal core. with question comment ;) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3469 --- src/cpu/core_normal/prefix_0f.h | 57 +++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index fcdcdb40..1292396f 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -356,6 +356,63 @@ CASE_0F_W(0xaf) /* IMUL Gw,Ew */ RMGwEwOp3(DIMULW,*rmrw); break; + CASE_0F_B(0xb0) /* cmpxchg Eb,Gb */ + { + if (CPU_ArchitectureType= 0xc0 ) { + GetEArb; + if (reg_al == *earb) { + *earb=*rmrb; + SETFLAGBIT(ZF,1); + } else { + reg_al = *earb; + SETFLAGBIT(ZF,0); + } + } else { + GetEAa; + Bit8u val = LoadMb(eaa); + if (reg_al == val) { + SaveMb(eaa,*rmrb); + SETFLAGBIT(ZF,1); + } else { + SaveMb(eaa,val); //NEEDED ? (val doesn't change + reg_al = val; + SETFLAGBIT(ZF,0); + } + } + break; + } + CASE_0F_W(0xb1) /* cmpxchg Ew,Gw */ + { + if (CPU_ArchitectureType= 0xc0 ) { + GetEArw; + if(reg_ax == *earw) { + *earw = *rmrw; + SETFLAGBIT(ZF,1); + } else { + reg_ax = *earw; + SETFLAGBIT(ZF,0); + } + } else { + GetEAa; + Bit16u val = LoadMw(eaa); + if(reg_ax == val) { + SaveMw(eaa,*rmrw); + SETFLAGBIT(ZF,1); + } else { + SaveMw(eaa,val); + reg_ax = val; + SETFLAGBIT(ZF,0); + } + } + break; + } + CASE_0F_W(0xb2) /* LSS Ew */ { GetRMrw; From 9de271f04a238665b448851ccf07330a2e5f5b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 25 Sep 2009 20:47:15 +0000 Subject: [PATCH 3381/4131] re: cmpxchg (comment added) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3470 --- src/cpu/core_normal/prefix_0f.h | 4 ++-- src/cpu/core_normal/prefix_66_0f.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 1292396f..ff809886 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -377,7 +377,7 @@ SaveMb(eaa,*rmrb); SETFLAGBIT(ZF,1); } else { - SaveMb(eaa,val); //NEEDED ? (val doesn't change + SaveMb(eaa,val); // cmpxchg always issues a write reg_al = val; SETFLAGBIT(ZF,0); } @@ -405,7 +405,7 @@ SaveMw(eaa,*rmrw); SETFLAGBIT(ZF,1); } else { - SaveMw(eaa,val); + SaveMw(eaa,val); // cmpxchg always issues a write reg_ax = val; SETFLAGBIT(ZF,0); } diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index f2180309..1563050b 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -256,7 +256,7 @@ SaveMd(eaa,*rmrd); SETFLAGBIT(ZF,1); } else { - SaveMd(eaa,val); + SaveMd(eaa,val); // cmpxchg always issues a write reg_eax=val; SETFLAGBIT(ZF,0); } From 599de7a67f405150965fddfb32e3b9d5ceb661f8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Sep 2009 20:51:21 +0000 Subject: [PATCH 3382/4131] Make it clear we don't support it, else we get detected as win95. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3471 --- src/dos/dos_misc.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index b65be5a7..c448ac4e 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_misc.cpp,v 1.23 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: dos_misc.cpp,v 1.24 2009-09-25 20:51:21 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" @@ -184,8 +184,7 @@ static bool DOS_MultiplexFunctions(void) { else return false; case 0x1680: /* RELEASE CURRENT VIRTUAL MACHINE TIME-SLICE */ //TODO Maybe do some idling but could screw up other systems :) - reg_al=0; - return true; + return true; //So no warning in the debugger anymore case 0x1689: /* Kernel IDLE CALL */ case 0x168f: /* Close awareness crap */ /* Removing warning */ From 8115555a4a07870f3ad29ac16863c2118e532026 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Fri, 25 Sep 2009 23:40:48 +0000 Subject: [PATCH 3383/4131] - add 16C550A FIFO support to the serial port - timing improvements for directserial - the platform specific part of directserial is now combined for less redundancy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3472 --- include/serialport.h | 138 +++- src/hardware/serialport/Makefile.am | 11 +- src/hardware/serialport/directserial.cpp | 319 +++++++ .../{directserial_win32.h => directserial.h} | 48 +- src/hardware/serialport/directserial_os2.cpp | 515 ------------ src/hardware/serialport/directserial_os2.h | 82 -- .../serialport/directserial_posix.cpp | 361 -------- src/hardware/serialport/directserial_posix.h | 69 -- .../serialport/directserial_win32.cpp | 394 --------- src/hardware/serialport/libserial.cpp | 706 ++++++++++++++++ src/hardware/serialport/libserial.h | 56 ++ src/hardware/serialport/misc_util.cpp | 21 + src/hardware/serialport/misc_util.h | 20 + src/hardware/serialport/nullmodem.cpp | 187 +++-- src/hardware/serialport/nullmodem.h | 10 +- src/hardware/serialport/serialport.cpp | 776 ++++++++++-------- src/hardware/serialport/softmodem.h | 4 +- visualc_net/dosbox.vcproj | 30 +- 18 files changed, 1834 insertions(+), 1913 deletions(-) create mode 100644 src/hardware/serialport/directserial.cpp rename src/hardware/serialport/{directserial_win32.h => directserial.h} (72%) delete mode 100644 src/hardware/serialport/directserial_os2.cpp delete mode 100644 src/hardware/serialport/directserial_os2.h delete mode 100644 src/hardware/serialport/directserial_posix.cpp delete mode 100644 src/hardware/serialport/directserial_posix.h delete mode 100644 src/hardware/serialport/directserial_win32.cpp create mode 100644 src/hardware/serialport/libserial.cpp create mode 100644 src/hardware/serialport/libserial.h diff --git a/include/serialport.h b/include/serialport.h index ca0d72b3..5879a444 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -16,16 +16,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.h,v 1.17 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: serialport.h,v 1.18 2009-09-25 23:40:48 h-a-l-9000 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 @@ -42,12 +37,91 @@ #include "programs.h" #endif +// set this to 1 for serial debugging in release mode +#define SERIAL_DBG_FORCED 0 + +#if (C_DEBUG || SERIAL_DBG_FORCED) +#define SERIAL_DEBUG 1 +#endif + #if SERIAL_DEBUG #include "hardware.h" #endif // Serial port interface +class MyFifo { +public: + MyFifo(Bitu maxsize_) { + maxsize=size=maxsize_; + pos=used=0; + data=new Bit8u[size]; + } + ~MyFifo() { + delete[] data; + } + INLINE Bitu getFree(void) { + return size-used; + } + bool isEmpty() { + return used==0; + } + bool isFull() { + return (size-used)==0; + } + + INLINE Bitu getUsage(void) { + return used; + } + void setSize(Bitu newsize) + { + size=newsize; + pos=used=0; + } + void clear(void) { + pos=used=0; + data[0]=0; + } + + bool addb(Bit8u _val) { + Bitu where=pos+used; + if (where>=size) where-=size; + if(used>=size) { + // overwrite last byte + if(where==0) where=size-1; + else where--; + data[where]=_val; + return false; + } + data[where]=_val; + used++; + return true; + } + Bit8u getb() { + if (!used) return data[pos]; + Bitu where=pos; + if (++pos>=size) pos-=size; + used--; + return data[where]; + } + Bit8u getTop() { + Bitu where=pos+used; + if (where>=size) where-=size; + if(used>=size) { + if(where==0) where=size-1; + else where--; + } + return data[where]; + } + + Bit8u probeByte() { + return data[pos]; + } +private: + Bit8u * data; + Bitu maxsize,size,pos,used; +}; + class CSerial { public: @@ -58,7 +132,7 @@ public: bool dbg_register; bool dbg_interrupt; bool dbg_aux; - + void log_ser(bool active, char const* format,...); #endif static bool getBituSubstring(const char* name,Bitu* data, CommandLine* cmd); @@ -92,8 +166,9 @@ public: #define SERIAL_RX_EVENT 4 #define SERIAL_POLLING_EVENT 5 #define SERIAL_THR_EVENT 6 +#define SERIAL_RX_TIMEOUT_EVENT 7 -#define SERIAL_BASE_EVENT_COUNT 6 +#define SERIAL_BASE_EVENT_COUNT 7 #define COMNUMBER idnumber+1 @@ -144,6 +219,7 @@ public: // If a byte comes from loopback or prepherial, put it in here. void receiveByte(Bit8u data); + void receiveByteEx(Bit8u data, Bit8u error); // If an error was received, put it here (in LSR register format) void receiveError(Bit8u errorword); @@ -177,7 +253,7 @@ private: DOS_Device* mydosdevice; - // I used this spec: http://www.exar.com/products/st16c450v420.pdf + // I used this spec: st16c450v420.pdf void ComputeInterrupts(); @@ -191,23 +267,20 @@ private: #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 TIMEOUT_PRIORITY 0x10 #define NONE_PRIORITY 0 Bit8u waiting_interrupts; // these are on, but maybe not enabled - // 16C450 (no FIFO) + // 16C550 // 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 RHR_OFFSET 0 // r Receive Holding Register, also LSB of Divisor Latch (r/w) + // Data: whole byte + #define THR_OFFSET 0 // w Transmit Holding Register + // Data: whole byte + Bit8u IER; // r/w Interrupt Enable Register, also MSB of Divisor Latch #define IER_OFFSET 1 bool irq_active; @@ -221,6 +294,7 @@ private: #define ISR_OFFSET 2 #define ISR_CLEAR_VAL 0x1 + #define ISR_FIFOTIMEOUT_VAL 0xc #define ISR_ERROR_VAL 0x6 #define ISR_RX_VAL 0x4 #define ISR_TX_VAL 0x2 @@ -292,6 +366,7 @@ private: Bitu framingErrors; Bitu parityErrors; Bitu overrunErrors; + Bitu txOverrunErrors; Bitu overrunIF0; Bitu breakErrors; @@ -329,16 +404,28 @@ private: void transmitLoopbackByte(Bit8u val, bool value); // 16C550 (FIFO) - // TODO + public: // todo remove + MyFifo* rxfifo; + private: + MyFifo* txfifo; + MyFifo* errorfifo; + Bitu errors_in_fifo; + Bitu rx_interrupt_threshold; + Bitu fifosize; + Bit8u FCR; + bool sync_guardtime; + #define FIFO_STATUS_ACTIVE 0xc0 // FIFO is active AND works ;) + #define FIFO_ERROR 0x80 + #define FCR_ACTIVATE 0x01 + #define FCR_CLEAR_RX 0x02 + #define FCR_CLEAR_TX 0x04 #define FCR_OFFSET 2 - bool fifo_warn; - //Bit8u FCR; // FIFO Control Register - + #define FIFO_FLOWCONTROL 0x20 }; extern CSerial* serialports[]; -const Bit8u serial_defaultirq[4] = { 4, 3, 4, 3 }; -const Bit16u serial_baseaddr[4] = {0x3f8,0x2f8,0x3e8,0x2e8}; +const Bit8u serial_defaultirq[] = { 4, 3, 4, 3 }; +const Bit16u serial_baseaddr[] = {0x3f8,0x2f8,0x3e8,0x2e8}; const char* const serial_comname[]={"COM1","COM2","COM3","COM4"}; // the COM devices @@ -358,4 +445,3 @@ private: }; #endif - diff --git a/src/hardware/serialport/Makefile.am b/src/hardware/serialport/Makefile.am index af7b803c..d2e72005 100644 --- a/src/hardware/serialport/Makefile.am +++ b/src/hardware/serialport/Makefile.am @@ -2,9 +2,8 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libserial.a -libserial_a_SOURCES = directserial_win32.cpp directserial_win32.h \ - serialdummy.cpp serialdummy.h serialport.cpp \ - softmodem.cpp softmodem.h misc_util.cpp misc_util.h \ - directserial_os2.h directserial_os2.cpp \ - directserial_posix.h directserial_posix.cpp \ - nullmodem.cpp nullmodem.h +libserial_a_SOURCES = directserial.cpp directserial.h \ + libserial.cpp libserial.h \ + serialdummy.cpp serialdummy.h serialport.cpp \ + softmodem.cpp softmodem.h misc_util.cpp misc_util.h \ + nullmodem.cpp nullmodem.h diff --git a/src/hardware/serialport/directserial.cpp b/src/hardware/serialport/directserial.cpp new file mode 100644 index 00000000..1e591264 --- /dev/null +++ b/src/hardware/serialport/directserial.cpp @@ -0,0 +1,319 @@ +/* + * 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: directserial.cpp,v 1.1 2009-09-25 23:40:47 h-a-l-9000 Exp $ */ + +#include "dosbox.h" + +#if C_DIRECTSERIAL + +#include "serialport.h" +#include "directserial.h" +#include "misc_util.h" +#include "pic.h" + +#include "libserial.h" + +/* This is a serial passthrough class. Its amazingly simple to */ +/* write now that the serial ports themselves were abstracted out */ + +CDirectSerial::CDirectSerial (Bitu id, CommandLine* cmd) + :CSerial (id, cmd) { + InstallationSuccessful = false; + comport = 0; + + rx_retry = 0; + rx_retry_max = 0; + + std::string tmpstring; + if(!cmd->FindStringBegin("realport:",tmpstring,false)) return; + + LOG_MSG ("Serial%d: Opening %s", COMNUMBER, tmpstring.c_str()); + if(!SERIAL_open(tmpstring.c_str(), &comport)) { + char errorbuffer[256]; + SERIAL_getErrorString(errorbuffer, sizeof(errorbuffer)); + LOG_MSG("Serial%d: Serial Port \"%s\" could not be opened.", + COMNUMBER, tmpstring.c_str()); + LOG_MSG("%s",errorbuffer); + return; + } + +#if SERIAL_DEBUG + dbgmsg_poll_block=false; + dbgmsg_rx_block=false; +#endif + + // rxdelay: How many milliseconds to wait before causing an + // overflow when the application is unresponsive. + if(getBituSubstring("rxdelay:", &rx_retry_max, cmd)) { + if(!(rx_retry_max<=10000)) { + rx_retry_max=0; + } + } + + CSerial::Init_Registers(); + InstallationSuccessful = true; + rx_state = D_RX_IDLE; + setEvent(SERIAL_POLLING_EVENT, 1); // millisecond receive tick +} + +CDirectSerial::~CDirectSerial () { + if(comport) SERIAL_close(comport); + // We do not use own events so we don't have to clear them. +} + +// CanReceive: true:UART part has room left +// doReceive: true:there was really a byte to receive +// rx_retry is incremented in polling events + +// in POLLING_EVENT: always add new polling event +// D_RX_IDLE + CanReceive + doReceive -> D_RX_WAIT , add RX_EVENT +// D_RX_IDLE + CanReceive + not doReceive -> D_RX_IDLE +// D_RX_IDLE + not CanReceive -> D_RX_BLOCKED, add RX_EVENT + +// D_RX_BLOCKED + CanReceive + doReceive -> D_RX_FASTWAIT, rem RX_EVENT +// rx_retry=0 , add RX_EVENT +// D_RX_BLOCKED + CanReceive + !doReceive -> D_RX_IDLE, rem RX_EVENT +// rx_retry=0 +// D_RX_BLOCKED + !CanReceive + doReceive + retry < max -> D_RX_BLOCKED, rx_retry++ +// D_RX_BLOCKED + !CanReceive + doReceive + retry >=max -> rx_retry=0 + +// to be continued... + +void CDirectSerial::handleUpperEvent(Bit16u type) { + switch(type) { + case SERIAL_POLLING_EVENT: { + setEvent(SERIAL_POLLING_EVENT, 1.0f); + // update Modem input line states + switch(rx_state) { + case D_RX_IDLE: + if(CanReceiveByte()) { + if(doReceive()) { + // a byte was received + rx_state=D_RX_WAIT; + setEvent(SERIAL_RX_EVENT, bytetime*0.9f); + } // else still idle + } else { +#if SERIAL_DEBUG + if(!dbgmsg_poll_block) { + log_ser(dbg_aux,"Directserial: block on polling."); + dbgmsg_poll_block=true; + } +#endif + rx_state=D_RX_BLOCKED; + // have both delays (1ms + bytetime) + setEvent(SERIAL_RX_EVENT, bytetime*0.9f); + } + break; + case D_RX_BLOCKED: + // one timeout tick + if(!CanReceiveByte()) { + rx_retry++; + if(rx_retry>=rx_retry_max) { + // it has timed out: + rx_retry=0; + removeEvent(SERIAL_RX_EVENT); + if(doReceive()) { + // read away everything + // this will set overrun errors + while(doReceive()); + rx_state=D_RX_WAIT; + setEvent(SERIAL_RX_EVENT, bytetime*0.9f); + } else { + // much trouble about nothing + rx_state=D_RX_IDLE; + } + } // else wait further + } else { + // good: we can receive again +#if SERIAL_DEBUG + dbgmsg_poll_block=false; + dbgmsg_rx_block=false; +#endif + removeEvent(SERIAL_RX_EVENT); + rx_retry=0; + if(doReceive()) { + rx_state=D_RX_FASTWAIT; + setEvent(SERIAL_RX_EVENT, bytetime*0.65f); + } else { + // much trouble about nothing + rx_state=D_RX_IDLE; + } + } + break; + + case D_RX_WAIT: + case D_RX_FASTWAIT: + break; + } + updateMSR(); + break; + } + case SERIAL_RX_EVENT: { + switch(rx_state) { + case D_RX_IDLE: + LOG_MSG("internal error in directserial"); + break; + + case D_RX_BLOCKED: // try to receive + case D_RX_WAIT: + case D_RX_FASTWAIT: + if(CanReceiveByte()) { + // just works or unblocked + rx_retry=0; // not waiting anymore + if(doReceive()) { + if(rx_state==D_RX_WAIT) setEvent(SERIAL_RX_EVENT, bytetime*0.9f); + else { + // maybe unblocked + rx_state=D_RX_FASTWAIT; + setEvent(SERIAL_RX_EVENT, bytetime*0.65f); + } + } else { + // didn't receive anything + rx_state=D_RX_IDLE; + } + } else { + // blocking now or still blocked +#if SERIAL_DEBUG + if(rx_state==D_RX_BLOCKED) { + if(!dbgmsg_rx_block) { + log_ser(dbg_aux,"Directserial: rx still blocked (retry=%d)",rx_retry); + dbgmsg_rx_block=true; + } + } + + + + + + + else log_ser(dbg_aux,"Directserial: block on continued rx (retry=%d).",rx_retry); +#endif + setEvent(SERIAL_RX_EVENT, bytetime*0.65f); + rx_state=D_RX_BLOCKED; + } + + break; + } + updateMSR(); + break; + } + case SERIAL_TX_EVENT: { + // Maybe echo cirquit works a bit better this way + if(rx_state==D_RX_IDLE && CanReceiveByte()) { + if(doReceive()) { + // a byte was received + rx_state=D_RX_WAIT; + setEvent(SERIAL_RX_EVENT, bytetime*0.9f); + } + } + ByteTransmitted(); + updateMSR(); + break; + } + case SERIAL_THR_EVENT: { + ByteTransmitting(); + setEvent(SERIAL_TX_EVENT,bytetime*1.1f); + break; + } + } +} + +bool CDirectSerial::doReceive() { + int value = SERIAL_getextchar(comport); + if(value) { + receiveByteEx((Bit8u)(value&0xff),(Bit8u)((value&0xff00)>>8)); + return true; + } + return false; +} + +// updatePortConfig is called when emulated app changes the serial port +// parameters baudrate, stopbits, number of databits, parity. +void CDirectSerial::updatePortConfig (Bit16u divider, Bit8u lcr) { + Bit8u parity = 0; + + switch ((lcr & 0x38)>>3) { + case 0x1: parity='o'; break; + case 0x3: parity='e'; break; + case 0x5: parity='m'; break; + case 0x7: parity='s'; break; + default: parity='n'; break; + } + + Bit8u bytelength = (lcr & 0x3)+5; + + // baudrate + Bitu baudrate; + if(divider==0) baudrate=115200; + else baudrate = 115200 / divider; + + // stopbits + Bit8u stopbits; + if (lcr & 0x4) { + if (bytelength == 5) stopbits = SERIAL_15STOP; + else stopbits = SERIAL_2STOP; + } else stopbits = SERIAL_1STOP; + + if(!SERIAL_setCommParameters(comport, baudrate, parity, stopbits, bytelength)) { +#if SERIAL_DEBUG + log_ser(dbg_aux,"Serial port settings not supported by host." ); +#endif + LOG_MSG ("Serial%d: Desired serial mode not supported (%d,%d,%c,%d)", + COMNUMBER, baudrate,bytelength,parity,stopbits); + } + CDirectSerial::setRTSDTR(getRTS(), getDTR()); +} + +void CDirectSerial::updateMSR () { + int new_status = SERIAL_getmodemstatus(comport); + + setCTS(new_status&SERIAL_CTS? true:false); + setDSR(new_status&SERIAL_DSR? true:false); + setRI(new_status&SERIAL_RI? true:false); + setCD(new_status&SERIAL_CD? true:false); +} + +void CDirectSerial::transmitByte (Bit8u val, bool first) { + if(!SERIAL_sendchar(comport, val)) + LOG_MSG("Serial%d: COM port error: write failed!", COMNUMBER); + if(first) setEvent(SERIAL_THR_EVENT, bytetime/8); + else setEvent(SERIAL_TX_EVENT, bytetime); +} + + +// setBreak(val) switches break on or off +void CDirectSerial::setBreak (bool value) { + SERIAL_setBREAK(comport,value); +} + +// updateModemControlLines(mcr) sets DTR and RTS. +void CDirectSerial::setRTSDTR(bool rts, bool dtr) { + SERIAL_setRTS(comport,rts); + SERIAL_setDTR(comport,dtr); +} + +void CDirectSerial::setRTS(bool val) { + SERIAL_setRTS(comport,val); +} + +void CDirectSerial::setDTR(bool val) { + SERIAL_setDTR(comport,val); +} + +#endif diff --git a/src/hardware/serialport/directserial_win32.h b/src/hardware/serialport/directserial.h similarity index 72% rename from src/hardware/serialport/directserial_win32.h rename to src/hardware/serialport/directserial.h index a2757f1a..e5efe880 100644 --- a/src/hardware/serialport/directserial_win32.h +++ b/src/hardware/serialport/directserial.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial_win32.h,v 1.6 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: directserial.h,v 1.1 2009-09-25 23:40:47 h-a-l-9000 Exp $ */ // include guard #ifndef DOSBOX_DIRECTSERIAL_WIN32_H @@ -25,33 +25,17 @@ #include "dosbox.h" #if C_DIRECTSERIAL -#ifdef WIN32 - - #define DIRECTSERIAL_AVAILIBLE #include "serialport.h" -#include //To prevent compilation problems with windows.h including winsock.h -#include + +#include "libserial.h" class CDirectSerial : public CSerial { public: - HANDLE hCom; - DCB dcb; - BOOL fSuccess; - - CDirectSerial(Bitu id, CommandLine* cmd/*const char* configstring*/); + CDirectSerial(Bitu id, CommandLine* cmd); ~CDirectSerial(); - bool receiveblock; // It's not a block of data it rather blocks - Bitu rx_retry; // counter of retries - - Bitu rx_retry_max; // how many POLL_EVENTS to wait before causing - // a overrun error. - - - void CheckErrors(); - void updatePortConfig(Bit16u divider, Bit8u lcr); void updateMSR(); void transmitByte(Bit8u val, bool first); @@ -61,9 +45,27 @@ public: void setRTS(bool val); void setDTR(bool val); void handleUpperEvent(Bit16u type); - + +private: + COMPORT comport; + + Bitu rx_state; +#define D_RX_IDLE 0 +#define D_RX_WAIT 1 +#define D_RX_BLOCKED 2 +#define D_RX_FASTWAIT 3 + + Bitu rx_retry; // counter of retries (every millisecond) + Bitu rx_retry_max; // how many POLL_EVENTS to wait before causing + // an overrun error. + bool doReceive(); + +#if SERIAL_DEBUG + bool dbgmsg_poll_block; + bool dbgmsg_rx_block; +#endif + }; -#endif // WIN32 #endif // C_DIRECTSERIAL #endif // include guard diff --git a/src/hardware/serialport/directserial_os2.cpp b/src/hardware/serialport/directserial_os2.cpp deleted file mode 100644 index e1626641..00000000 --- a/src/hardware/serialport/directserial_os2.cpp +++ /dev/null @@ -1,515 +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: directserial_os2.cpp,v 1.5 2009-05-27 09:15:41 qbix79 Exp $ */ - -#include "dosbox.h" - -#if C_DIRECTSERIAL - - -#if defined(OS2) -#include "serialport.h" -#include "directserial_os2.h" -#include "misc_util.h" -#include "pic.h" - -// OS/2 related headers -#define INCL_DOSFILEMGR -#define INCL_DOSERRORS -#define INCL_DOSDEVICES -#define INCL_DOSDEVIOCTL -#define INCL_DOSPROCESS -#include - -/* This is a serial passthrough class. Its amazingly simple to */ -/* write now that the serial ports themselves were abstracted out */ - -CDirectSerial::CDirectSerial (Bitu id, CommandLine *cmd) - : CSerial(id, cmd) { - InstallationSuccessful = false; - - - rx_retry = 0; - rx_retry_max = 0; - - std::string tmpstring; - - if (!cmd->FindStringBegin("realport:", tmpstring, false)) - { - return; - } -#if SERIAL_DEBUG - if (dbg_modemcontrol) - { - fprintf(debugfp, "%12.3f Port type directserial realport %s\r\n", PIC_FullIndex(), tmpstring.c_str()); - } -#endif - - - // rxdelay: How many milliseconds to wait before causing an - // overflow when the application is unresponsive. - if(getBituSubstring("rxdelay:", &rx_retry_max, cmd)) { - if(!(rx_retry_max<=10000)) { - rx_retry_max=0; - } - } - - const char* tmpchar=tmpstring.c_str(); - - LOG_MSG ("Serial%d: Opening %s", COMNUMBER, tmpstring.c_str()); - - ULONG ulAction = 0; - APIRET rc = DosOpen((unsigned char*)tmpstring.c_str(), &hCom, &ulAction, 0L, FILE_NORMAL, FILE_OPEN, - OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | OPEN_FLAGS_SEQUENTIAL, 0L); - if (rc != NO_ERROR) - { - LOG_MSG ("Serial%d: Serial port \"%s\" could not be opened.", COMNUMBER, tmpstring.c_str()); - if (rc == 2) { - LOG_MSG ("The specified port does not exist."); - } else if (rc == 99) { - LOG_MSG ("The specified port is already in use."); - } else { - LOG_MSG ("OS/2 error %d occurred.", rc); - } - - hCom = 0; - return; - } - - DCBINFO dcb; - ULONG ulParmLen = sizeof(DCBINFO); - rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &dcb, ulParmLen, &ulParmLen); - if ( rc != NO_ERROR) - { - LOG_MSG("GetCommState failed with error %d.\n", rc); - DosClose(hCom); - hCom = 0; - return; - } - - dcb.usWriteTimeout = 0; - dcb.usReadTimeout = 0; //65535; - dcb.fbCtlHndShake = dcb.fbFlowReplace = 0; - dcb.fbTimeout = 6; - rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0); - if ( rc != NO_ERROR) - { - LOG_MSG("SetDCBInfo failed with error %d.\n", rc); - DosClose(hCom); - hCom = 0; - return; - } - - - struct { - ULONG baud; - BYTE fraction; - } setbaud; - setbaud.baud = 9600; - setbaud.fraction = 0; - ulParmLen = sizeof(setbaud); - rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_EXTSETBAUDRATE, &setbaud, ulParmLen, &ulParmLen, 0, 0, 0); - if (rc != NO_ERROR) - { - LOG_MSG("ExtSetBaudrate failed with error %d.\n", rc); - DosClose (hCom); - hCom = 0; - return; -} - - struct { - UCHAR data; - UCHAR parity; - UCHAR stop; - } paramline; - - // byte length - paramline.data = 8; - paramline.parity = 0; - paramline.stop = 0; - ulParmLen = sizeof(paramline); - rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETLINECTRL, ¶mline, ulParmLen, &ulParmLen, 0, 0, 0); - if ( rc != NO_ERROR) - { - LOG_MSG ("SetLineCtrl failed with error %d.\n", rc); - } - - CSerial::Init_Registers(); - InstallationSuccessful = true; - receiveblock = false; - - // Clears comm errors - USHORT errors = 0; - ulParmLen = sizeof(errors); - DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMERROR, 0, 0, 0, &errors, ulParmLen, &ulParmLen); - setEvent(SERIAL_POLLING_EVENT, 1); - } - -CDirectSerial::~CDirectSerial () { - if (hCom != 0) - DosClose (hCom); -} - - - -/*****************************************************************************/ -/* updatePortConfig is called when emulated app changes the serial port **/ -/* parameters baudrate, stopbits, number of databits, parity. **/ -/*****************************************************************************/ -void CDirectSerial::updatePortConfig (Bit16u divider, Bit8u lcr) { - Bit8u parity = 0; - Bit8u bytelength = 0; - struct { - ULONG baud; - BYTE fraction; - } setbaud; - - // baud - if (divider <= 0x1) - setbaud.baud = 115200; - else if (divider <= 0x2) - setbaud.baud = 57600; - else if (divider <= 0x3) - setbaud.baud = 38400; - else if (divider <= 0x6) - setbaud.baud = 19200; - else if (divider <= 0xc) - setbaud.baud = 9600; - else if (divider <= 0x18) - setbaud.baud = 4800; - else if (divider <= 0x30) - setbaud.baud = 2400; - else if (divider <= 0x60) - setbaud.baud = 1200; - else if (divider <= 0xc0) - setbaud.baud = 600; - else if (divider <= 0x180) - setbaud.baud = 300; - else if (divider <= 0x417) - setbaud.baud = 110; - - // I read that windows can handle nonstandard baudrates: - else - setbaud.baud = 115200 / divider; - - - setbaud.fraction = 0; - ULONG ulParmLen = sizeof(setbaud); - APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_EXTSETBAUDRATE, &setbaud, ulParmLen, &ulParmLen, 0, 0, 0); - if (rc != NO_ERROR) - { - LOG_MSG("Serial%d: Desired serial mode not supported (Baud: %d, %d, Error: %d)", - COMNUMBER, setbaud.baud, divider, rc); - } - - - struct { - UCHAR data; - UCHAR parity; - UCHAR stop; - } paramline; - - // byte length - bytelength = lcr & 0x3; - bytelength += 5; - paramline.data = bytelength; - - // parity - parity = lcr & 0x38; - parity = parity >> 3; - switch (parity) { - case 0x1: - paramline.parity = 1; - break; - case 0x3: - paramline.parity = 2; - break; - case 0x5: - paramline.parity = 3; - break; - case 0x7: - paramline.parity = 4; - break; - default: - paramline.parity = 0; - break; - } - - // stopbits - if (lcr & 0x4) { - if (bytelength == 5) - paramline.stop = 1; - else - paramline.stop = 2; - } else { - paramline.stop = 0; - } - - -#ifdef SERIAL_DEBUG - LOG_MSG("_____________________________________________________"); - LOG_MSG("Serial%d, new baud rate: %d", COMNUMBER, setbaud.baud); - LOG_MSG("Serial%d: new bytelen: %d", COMNUMBER, paramline.data); - LOG_MSG("Serial%d: new parity: %d", COMNUMBER, paramline.parity); - LOG_MSG("Serial%d: new stopbits: %d", COMNUMBER, paramline.stop); -#endif - - ulParmLen = sizeof(paramline); - rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETLINECTRL, ¶mline, ulParmLen, &ulParmLen, 0, 0, 0); - if ( rc != NO_ERROR) - { -#ifdef SERIAL_DEBUG - if (dbg_modemcontrol) - { - fprintf(debugfp, "%12.3f serial mode not supported: rate=%d, LCR=%x.\r\n", PIC_FullIndex(), setbaud.baud, lcr); - } -#endif - LOG_MSG("Serial%d: Desired serial mode not supported (%d,%d,%d,%d)", - COMNUMBER, setbaud.baud, paramline.data, paramline.parity, lcr); - } - - -} - -void CDirectSerial::updateMSR () { - Bit8u newmsr = 0; - UCHAR dptr = 0; - ULONG ulParmLen = sizeof(dptr); - - APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETMODEMINPUT, 0, 0, 0, &dptr, ulParmLen, &ulParmLen); - if (rc != NO_ERROR) { - LOG_MSG ("Serial port at %x: GetModemInput failed with %d !", idnumber, dptr); - } - setCTS( (dptr & 16) != 0); - setDSR( (dptr & 32) != 0); - setRI( (dptr & 64) != 0); - setCD( (dptr & 128) != 0); -} - -void CDirectSerial::transmitByte (Bit8u val, bool first) { - ULONG bytesWritten = 0; - APIRET rc = DosWrite (hCom, &val, 1, &bytesWritten); - if (rc == NO_ERROR && bytesWritten > 0) { - //LOG_MSG("UART 0x%x: TX 0x%x", base,val); - } else { - LOG_MSG ("Serial%d: NO BYTE WRITTEN!", idnumber); - } - if (first) - { - setEvent(SERIAL_THR_EVENT, bytetime / 8); - } else { - setEvent(SERIAL_TX_EVENT, bytetime); - } -} - -/*****************************************************************************/ -/* setBreak(val) switches break on or off **/ -/*****************************************************************************/ - -void CDirectSerial::setBreak (bool value) { - USHORT error; - ULONG ulParmLen = sizeof(error); - if (value) - DosDevIOCtl (hCom, IOCTL_ASYNC, ASYNC_SETBREAKON, 0,0,0, &error, ulParmLen, &ulParmLen); - else - DosDevIOCtl (hCom, IOCTL_ASYNC, ASYNC_SETBREAKOFF, 0,0,0, &error, ulParmLen, &ulParmLen); -} - -/*****************************************************************************/ -/* updateModemControlLines(mcr) sets DTR and RTS. **/ -/*****************************************************************************/ -void CDirectSerial::setRTSDTR(bool rts, bool dtr) -{ - bool change = false; - DCBINFO dcb; - ULONG ulParmLen = sizeof(dcb); - - DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &dcb, ulParmLen, &ulParmLen); - - /*** DTR ***/ - if (dtr) { // DTR on - if (dcb.fbCtlHndShake && 3 == 0) { // DTR disabled - dcb.fbCtlHndShake |= 1; - change = true; - } - } else { - if (dcb.fbCtlHndShake && 3 == 1) { // DTR enabled - dcb.fbCtlHndShake &= ~3; - change = true; - } - } - /*** RTS ***/ - if (rts) { // RTS on - if (dcb.fbFlowReplace && 192 == 0) { //RTS disabled - dcb.fbFlowReplace |= 64; - change = true; - } - } else { - if (dcb.fbFlowReplace && 192 == 1) { // RTS enabled - dcb.fbFlowReplace &= ~192; - change = true; - } - } - if (change) - DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0); -} - -void CDirectSerial::setRTS(bool val) -{ - bool change = false; - DCBINFO dcb; - ULONG ulParmLen = sizeof(dcb); - - DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &dcb, ulParmLen, &ulParmLen); - - /*** RTS ***/ - if (val) { // RTS on - if (dcb.fbFlowReplace && 192 == 0) { //RTS disabled - dcb.fbFlowReplace |= 64; - change = true; - } - } else { - if (dcb.fbFlowReplace && 192 == 1) { // RTS enabled - dcb.fbFlowReplace &= ~192; - change = true; - } - } - if (change) - DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0); - } - -void CDirectSerial::setDTR(bool val) -{ - bool change = false; - DCBINFO dcb; - ULONG ulParmLen = sizeof(dcb); - - DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &dcb, ulParmLen, &ulParmLen); - - /*** DTR ***/ - if (val) { // DTR on - if (dcb.fbCtlHndShake && 3 == 0) { // DTR disabled - dcb.fbCtlHndShake |= 1; - change = true; - } - } else { - if (dcb.fbCtlHndShake && 3 == 1) { // DTR enabled - dcb.fbCtlHndShake &= ~3; - change = true; - } - } - if (change) - DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0); - } - - -void CDirectSerial::handleUpperEvent(Bit16u type) - { - switch(type) { - case SERIAL_POLLING_EVENT: { - ULONG dwRead = 0; - ULONG errors = 0; - Bit8u chRead = 0; - - setEvent(SERIAL_POLLING_EVENT, 1); - if(!receiveblock) { - if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )) - { - rx_retry=0; - if (DosRead (hCom, &chRead, 1, &dwRead) == NO_ERROR) { - if (dwRead) { - receiveByte (chRead); - setEvent(40, bytetime-0.03f); // receive timing - receiveblock=true; - } - } - } else rx_retry++; - } - // check for errors - CheckErrors(); - // update Modem input line states - updateMSR (); - break; - } - case 40: { - // receive time is up - ULONG dwRead = 0; - Bit8u chRead = 0; - receiveblock=false; - // check if there is something to receive - if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )) - { - rx_retry=0; - if (DosRead (hCom, &chRead, 1, &dwRead) == NO_ERROR) { - if (dwRead) { - receiveByte (chRead); - setEvent(40, bytetime-0.03f); // receive timing - receiveblock=true; - } - } - } else rx_retry++; - break; - } - case SERIAL_TX_EVENT: { - ULONG dwRead = 0; - Bit8u chRead = 0; - if(!receiveblock) { - if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )) - { - rx_retry=0; - if (DosRead (hCom, &chRead, 1, &dwRead) == NO_ERROR) { - if (dwRead) { - receiveByte (chRead); - setEvent(40, bytetime-0.03f); // receive timing - receiveblock=true; - } - } - } else rx_retry++; - } - ByteTransmitted(); - break; - } - case SERIAL_THR_EVENT: { - ByteTransmitting(); - setEvent(SERIAL_TX_EVENT,bytetime+0.03f); - break; - } - } - -} - -void CDirectSerial::CheckErrors() { - - USHORT errors = 0, event = 0; - ULONG ulParmLen = sizeof(errors); - DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMEVENT, 0, 0, 0, &event, ulParmLen, &ulParmLen); - if (event & (64 + 128) ) { // Break (Bit 6) or Frame or Parity (Bit 7) error - Bit8u errreg = 0; - if (event & 64) errreg |= LSR_RX_BREAK_MASK; - if (event & 128) { - DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMERROR, 0, 0, 0, &errors, ulParmLen, &ulParmLen); - if (errors & 8) errreg |= LSR_FRAMING_ERROR_MASK; - if (errors & 4) errreg |= LSR_PARITY_ERROR_MASK; - } - receiveError (errreg); - } -} - -#endif -#endif diff --git a/src/hardware/serialport/directserial_os2.h b/src/hardware/serialport/directserial_os2.h deleted file mode 100644 index 5d818b27..00000000 --- a/src/hardware/serialport/directserial_os2.h +++ /dev/null @@ -1,82 +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: directserial_os2.h,v 1.5 2009-05-27 09:15:41 qbix79 Exp $ */ - -// include guard -#ifndef DOSBOX_DIRECTSERIAL_OS2_H -#define DOSBOX_DIRECTSERIAL_OS2_H - -#include "dosbox.h" - -#if C_DIRECTSERIAL -#if defined(OS2) -#define DIRECTSERIAL_AVAILIBLE -#include "serialport.h" -#define INCL_DOSFILEMGR -#define INCL_DOSERRORS -#define INCL_DOSDEVICES -#define INCL_DOSDEVIOCTL -#define INCL_DOSPROCESS -#include - -class CDirectSerial : public CSerial { -public: - HFILE hCom; - BOOL fSuccess; - - CDirectSerial(Bitu id, CommandLine* cmd); - ~CDirectSerial(); - - - //Bitu lastChance; // If there is no space for new - // received data, it gets a little chance - //Bit8u ChanceChar; - - //bool CanRecv(void); - //bool CanSend(void); - - - //void RXBufferEmpty(); - bool receiveblock; - Bitu rx_retry; - Bitu rx_retry_max; - - void CheckErrors(); - - void updatePortConfig(Bit16u divider, Bit8u lcr); - void updateMSR(); - void transmitByte(Bit8u val, bool first); - void setBreak(bool value); - - void setRTSDTR(bool rts, bool dtr); - void setRTS(bool val); - void setDTR(bool val); - void handleUpperEvent(Bit16u type); - - - //void updateModemControlLines(/*Bit8u mcr*/); - //void Timer2(void); - - -}; -#endif // IFDEF - -#endif // C_DIRECTSERIAL -#endif // include guard - diff --git a/src/hardware/serialport/directserial_posix.cpp b/src/hardware/serialport/directserial_posix.cpp deleted file mode 100644 index 64bd7c2b..00000000 --- a/src/hardware/serialport/directserial_posix.cpp +++ /dev/null @@ -1,361 +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: directserial_posix.cpp,v 1.4 2009-05-27 09:15:41 qbix79 Exp $ */ - -#include "dosbox.h" - -#if C_DIRECTSERIAL - -// Posix version -#if defined (LINUX) || defined (MACOSX) || defined (BSD) - -#include "serialport.h" -#include "directserial_posix.h" -#include "pic.h" - -#include -#include -#include - -#include -#include - -/* This is a serial passthrough class. Its amazingly simple to */ -/* write now that the serial ports themselves were abstracted out */ - -CDirectSerial::CDirectSerial (Bitu id, CommandLine* cmd) - :CSerial (id, cmd) { - InstallationSuccessful = false; - - rx_retry = 0; - rx_retry_max = 0; - - std::string prefix="/dev/"; - std::string tmpstring; - if(!cmd->FindStringBegin("realport:",tmpstring,false)) return; - -#if SERIAL_DEBUG - if(dbg_modemcontrol) - fprintf(debugfp,"%12.3f Port type directserial realport %s\r\n", - PIC_FullIndex(),tmpstring.c_str()); -#endif - - prefix.append(tmpstring); - - // rxdelay: How many milliseconds to wait before causing an - // overflow when the application is unresponsive. - if(getBituSubstring("rxdelay:", &rx_retry_max, cmd)) { - if(!(rx_retry_max<=10000)) rx_retry_max=0; - } - - const char* tmpchar=prefix.c_str(); - - LOG_MSG ("Serial%d: Opening %s", COMNUMBER, tmpchar); - - fileHandle = open (tmpchar, O_RDWR | O_NOCTTY | O_NONBLOCK); - - if (fileHandle < 0) { - LOG_MSG ("Serial%d: Serial Port \"%s\" could not be opened.", - COMNUMBER, tmpchar); - if (errno == 2) { - LOG_MSG ("The specified port does not exist."); - } else if (errno == EBUSY) { - LOG_MSG ("The specified port is already in use."); - } else { - LOG_MSG ("Errno %d occurred.", errno); - } - return; - } - - int result = tcgetattr(fileHandle, &termInfo); - - - if (result==-1) { - // Handle the error. - LOG_MSG ("tcgetattr failed with error %d.\n", errno); - return; - } - - // save it here to restore in destructor - tcgetattr(fileHandle,&backup); - - // initialize the port - termInfo.c_cflag = CS8 | CREAD | CLOCAL; // noparity, 1 stopbit - termInfo.c_iflag = PARMRK | INPCK; - termInfo.c_oflag = 0; - termInfo.c_lflag = 0; - - cfsetospeed (&termInfo, B9600); - cfsetispeed (&termInfo, B9600); - - termInfo.c_cc[VMIN] = 0; - termInfo.c_cc[VTIME] = 0; - - tcflush (fileHandle, TCIFLUSH); - tcsetattr (fileHandle, TCSANOW, &termInfo); - - //initialise base class - CSerial::Init_Registers(); - InstallationSuccessful = true; - receiveblock=false; - - setEvent(SERIAL_POLLING_EVENT, 1); // millisecond tick -} - -CDirectSerial::~CDirectSerial () { - if (fileHandle >= 0) - { - tcsetattr(fileHandle, TCSANOW, &backup); - close(fileHandle); - } - // We do not use own events so we don't have to clear them. -} - -void CDirectSerial::handleUpperEvent(Bit16u type) { - - switch(type) { - case SERIAL_POLLING_EVENT: { - setEvent(SERIAL_POLLING_EVENT, 1); - if(!receiveblock) { - if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )) - { - ReadCharacter(); - } else rx_retry++; - } - // check for errors - CheckErrors(); - // update Modem input line states - updateMSR (); - break; - } - case 40: { - // receive time is up - receiveblock=false; - // check if there is something to receive - if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )) - { - ReadCharacter(); - } else rx_retry++; - break; - } - case SERIAL_TX_EVENT: { - if(!receiveblock) { - if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )) - { - ReadCharacter(); - } else rx_retry++; - } - ByteTransmitted(); - break; - } - case SERIAL_THR_EVENT: { - ByteTransmitting(); - setEvent(SERIAL_TX_EVENT,bytetime+0.03f); - break; - } - } -} - -void CDirectSerial::ReadCharacter() -{ - Bit8u chRead = 0; - int dwRead = 0; - rx_retry=0; - - dwRead=read(fileHandle,&chRead,1); - if (dwRead==1) { - if(chRead==0xff) // error escape - { - dwRead=read(fileHandle,&chRead,1); - if(chRead==0x00) // an error - { - dwRead=read(fileHandle,&chRead,1); - if(chRead==0x0)receiveError(LSR_RX_BREAK_MASK); - else receiveError(LSR_PARITY_ERROR_MASK); - } - } - receiveByte (chRead); - setEvent(40, bytetime-0.03f); // receive timing - receiveblock=true; - } -} - -void CDirectSerial::CheckErrors() { - -} - -/*****************************************************************************/ -/* updatePortConfig is called when emulated app changes the serial port **/ -/* parameters baudrate, stopbits, number of databits, parity. **/ -/*****************************************************************************/ -void CDirectSerial::updatePortConfig (Bit16u divider, Bit8u lcr) { - Bit8u parity = 0; - Bit8u bytelength = 0; - int baudrate=0; - - // baud - termInfo.c_cflag = CREAD | CLOCAL; - - if (divider == 0x1) baudrate = B115200; - else if (divider == 0x2) baudrate = B57600; - else if (divider == 0x3) baudrate = B38400; - else if (divider == 0x6) baudrate = B19200; - else if (divider == 0xc) baudrate = B9600; - else if (divider == 0x18) baudrate = B4800; - else if (divider == 0x30) baudrate = B2400; - else if (divider == 0x60) baudrate = B1200; - else if (divider == 0xc0) baudrate = B600; - else if (divider == 0x180) baudrate = B300; - else if (divider == 0x417) baudrate = B110; - - // Don't think termios supports nonstandard baudrates - else baudrate = B9600; - - // byte length - bytelength = lcr & 0x3; - bytelength += 5; - - switch (bytelength) { - case 5: - termInfo.c_cflag |= CS5; - break; - - case 6: - termInfo.c_cflag |= CS6; - break; - - case 7: - termInfo.c_cflag |= CS7; - break; - - case 8: - default: - termInfo.c_cflag |= CS8; - break; - } - - // parity - parity = lcr & 0x38; - parity >>= 3; - switch (parity) { - case 0x1: - termInfo.c_cflag |= PARODD; - termInfo.c_cflag |= PARENB; - break; - case 0x3: - termInfo.c_cflag |= PARENB; - break; - case 0x5: - -// "works on many systems" -#define CMSPAR 010000000000 - - termInfo.c_cflag |= PARODD; - termInfo.c_cflag |= PARENB; - termInfo.c_cflag |= CMSPAR; - //LOG_MSG("Serial%d: Mark parity not supported.", COMNUMBER); - break; - case 0x7: - termInfo.c_cflag |= PARENB; - termInfo.c_cflag |= CMSPAR; - //LOG_MSG("Serial%d: Space parity not supported.", COMNUMBER); - break; - default: // no parity - break; - } - - // stopbits - if (lcr & 0x4) termInfo.c_cflag |= CSTOPB; - - cfsetospeed (&termInfo, baudrate); - cfsetispeed (&termInfo, baudrate); - - int retval = tcsetattr(fileHandle, TCSANOW, &termInfo); - - if(retval==-1) - LOG_MSG ("Serial%d: Desired serial mode not supported", COMNUMBER); - -} - -void CDirectSerial::updateMSR () { - long flags = 0; - ioctl (fileHandle, TIOCMGET, &flags); - - if (flags & TIOCM_CTS) setCTS(true); - else setCTS(false); - - if (flags & TIOCM_DSR) setDSR(true); - else setDSR(false); - - if (flags & TIOCM_RI) setRI(true); - else setRI(false); - - if (flags & TIOCM_CD) setCD(true); - else setCD(false); -} - -void CDirectSerial::transmitByte (Bit8u val, bool first) { - if((LCR&LCR_BREAK_MASK) == 0) { - - int bytesWritten = write(fileHandle, &val, 1); - if (bytesWritten != 1) - LOG_MSG ("Serial%d: COM port error: write failed!", idnumber); - } - if(first) setEvent(SERIAL_THR_EVENT, bytetime/8); - else setEvent(SERIAL_TX_EVENT, bytetime); -} - -/*****************************************************************************/ -/* setBreak(val) switches break on or off **/ -/*****************************************************************************/ -void CDirectSerial::setBreak (bool value) { - if (value) ioctl (fileHandle, TIOCSBRK); - else ioctl (fileHandle, TIOCCBRK); -} - -/*****************************************************************************/ -/* updateModemControlLines(mcr) sets DTR and RTS. **/ -/*****************************************************************************/ -void CDirectSerial::setRTSDTR(bool rts, bool dtr) { - - long setflags = 0; - long clearflags = 0; - - if(rts) setflags |= TIOCM_RTS; - else clearflags |= TIOCM_RTS; - - if(dtr) setflags |= TIOCM_DTR; - else clearflags |= TIOCM_DTR; - - if(setflags) ioctl (fileHandle, TIOCMBIS, &setflags); - if(clearflags) ioctl (fileHandle, TIOCMBIC, &clearflags); -} -void CDirectSerial::setRTS(bool val) { - long flag = TIOCM_RTS; - if(val) ioctl(fileHandle, TIOCMBIS, &flag); - else ioctl(fileHandle, TIOCMBIC, &flag); -} -void CDirectSerial::setDTR(bool val) { - long flag = TIOCM_DTR; - if(val) ioctl(fileHandle, TIOCMBIS, &flag); - else ioctl(fileHandle, TIOCMBIC, &flag); -} - -#endif -#endif diff --git a/src/hardware/serialport/directserial_posix.h b/src/hardware/serialport/directserial_posix.h deleted file mode 100644 index 6d9865f5..00000000 --- a/src/hardware/serialport/directserial_posix.h +++ /dev/null @@ -1,69 +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: directserial_posix.h,v 1.4 2009-05-27 09:15:41 qbix79 Exp $ */ - -// include guard -#ifndef DOSBOX_DIRECTSERIAL_POSIX_H -#define DOSBOX_DIRECTSERIAL_POSIX_H - -#include "dosbox.h" - -#if C_DIRECTSERIAL -#if defined (LINUX) || defined (MACOSX) || defined (BSD) - - - -#define DIRECTSERIAL_AVAILIBLE -#include "serialport.h" -#include -#include - -class CDirectSerial : public CSerial { -public: - termios termInfo; - termios backup; - int fileHandle; - - CDirectSerial(Bitu id, CommandLine* cmd); - ~CDirectSerial(); - bool receiveblock; // It's not a block of data it rather blocks - - Bitu rx_retry; // counter of retries - - Bitu rx_retry_max; // how many POLL_EVENTS to wait before causing - // a overrun error. - - void ReadCharacter(); - void CheckErrors(); - - void updatePortConfig(Bit16u divider, Bit8u lcr); - void updateMSR(); - void transmitByte(Bit8u val, bool first); - void setBreak(bool value); - - void setRTSDTR(bool rts, bool dtr); - void setRTS(bool val); - void setDTR(bool val); - void handleUpperEvent(Bit16u type); - -}; - -#endif // WIN32 -#endif // C_DIRECTSERIAL -#endif // include guard diff --git a/src/hardware/serialport/directserial_win32.cpp b/src/hardware/serialport/directserial_win32.cpp deleted file mode 100644 index c3073bb4..00000000 --- a/src/hardware/serialport/directserial_win32.cpp +++ /dev/null @@ -1,394 +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: directserial_win32.cpp,v 1.8 2009-05-27 09:15:41 qbix79 Exp $ */ - -#include "dosbox.h" - -#if C_DIRECTSERIAL - -/* Windows version */ -#if defined (WIN32) - -#include "serialport.h" -#include "directserial_win32.h" -#include "misc_util.h" -#include "pic.h" - -// Win32 related headers -#include - -/* This is a serial passthrough class. Its amazingly simple to */ -/* write now that the serial ports themselves were abstracted out */ - -CDirectSerial::CDirectSerial (Bitu id, CommandLine* cmd) - :CSerial (id, cmd) { - InstallationSuccessful = false; - hCom = INVALID_HANDLE_VALUE; // else destructor may close an invalid handle - rx_retry = 0; - rx_retry_max = 0; - - // open the port in NT object space (recommended by Microsoft) - // allows the user to open COM10+ and custom port names. - std::string prefix="\\\\.\\"; - std::string tmpstring; - if(!cmd->FindStringBegin("realport:",tmpstring,false)) return; - -#if SERIAL_DEBUG - if(dbg_modemcontrol) - fprintf(debugfp,"%12.3f Port type directserial realport %s\r\n", - PIC_FullIndex(),tmpstring.c_str()); -#endif - - prefix.append(tmpstring); - - // rxdelay: How many milliseconds to wait before causing an - // overflow when the application is unresponsive. - if(getBituSubstring("rxdelay:", &rx_retry_max, cmd)) { - if(!(rx_retry_max<=10000)) { - rx_retry_max=0; - } - } - - const char* tmpchar=prefix.c_str(); - - LOG_MSG ("Serial%d: Opening %s", COMNUMBER, tmpstring.c_str()); - hCom = CreateFile (tmpchar, - GENERIC_READ | GENERIC_WRITE, 0, - // must be opened with exclusive-access - NULL, // no security attributes - OPEN_EXISTING, // must use OPEN_EXISTING - 0, // non overlapped I/O - NULL // hTemplate must be NULL for comm devices - ); - - if (hCom == INVALID_HANDLE_VALUE) { - int error = GetLastError (); - LOG_MSG ("Serial%d: Serial Port \"%s\" could not be opened.", - COMNUMBER, tmpstring.c_str()); - if (error == 2) { - LOG_MSG ("The specified port does not exist."); - } else if (error == 5) { - LOG_MSG ("The specified port is already in use."); - } else { - LOG_MSG ("Windows error %d occurred.", error); - } - return; - } - - dcb.DCBlength=sizeof(dcb); - fSuccess = GetCommState (hCom, &dcb); - - if (!fSuccess) { - // Handle the error. - LOG_MSG ("GetCommState failed with error %d.\n", (int)GetLastError ()); - hCom = INVALID_HANDLE_VALUE; - return; - } - - // initialize the port - dcb.BaudRate=CBR_9600; - dcb.fBinary=true; - dcb.fParity=true; - dcb.fOutxCtsFlow=false; - dcb.fOutxDsrFlow=false; - dcb.fDtrControl=DTR_CONTROL_DISABLE; - dcb.fDsrSensitivity=false; - - dcb.fOutX=false; - dcb.fInX=false; - dcb.fErrorChar=0; - dcb.fNull=false; - dcb.fRtsControl=RTS_CONTROL_DISABLE; - dcb.fAbortOnError=false; - - dcb.ByteSize=8; - dcb.Parity=NOPARITY; - dcb.StopBits=ONESTOPBIT; - - fSuccess = SetCommState (hCom, &dcb); - - if (!fSuccess) { - // Handle the error. - LOG_MSG ("SetCommState failed with error %d.\n", (int)GetLastError ()); - hCom = INVALID_HANDLE_VALUE; - return; - } - - // Configure timeouts to effectively use polling - COMMTIMEOUTS ct; - ct.ReadIntervalTimeout = MAXDWORD; - ct.ReadTotalTimeoutConstant = 0; - ct.ReadTotalTimeoutMultiplier = 0; - ct.WriteTotalTimeoutConstant = 0; - ct.WriteTotalTimeoutMultiplier = 0; - SetCommTimeouts (hCom, &ct); - - CSerial::Init_Registers(); - InstallationSuccessful = true; - receiveblock=false; - - ClearCommBreak (hCom); - setEvent(SERIAL_POLLING_EVENT, 1); // millisecond tick -} - -CDirectSerial::~CDirectSerial () { - if (hCom != INVALID_HANDLE_VALUE) CloseHandle (hCom); - // We do not use own events so we don't have to clear them. -} - -void CDirectSerial::handleUpperEvent(Bit16u type) { - - switch(type) { - case SERIAL_POLLING_EVENT: { - DWORD dwRead = 0; - Bit8u chRead = 0; - - setEvent(SERIAL_POLLING_EVENT, 1); - if(!receiveblock) { - if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )) - { - rx_retry=0; - if (ReadFile (hCom, &chRead, 1, &dwRead, NULL)) { - if (dwRead) { - receiveByte (chRead); - setEvent(40, bytetime-0.03f); // receive timing - receiveblock=true; - } - } - } else rx_retry++; - } - // check for errors - CheckErrors(); - // update Modem input line states - updateMSR (); - break; - } - case 40: { - // receive time is up - DWORD dwRead = 0; - Bit8u chRead = 0; - receiveblock=false; - // check if there is something to receive - if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )) - { - rx_retry=0; - if (ReadFile (hCom, &chRead, 1, &dwRead, NULL)) { - if (dwRead) { - receiveByte (chRead); - setEvent(40, bytetime-0.03f); // receive timing - receiveblock=true; - } - } - } else rx_retry++; - break; - } - case SERIAL_TX_EVENT: { - DWORD dwRead = 0; - Bit8u chRead = 0; - if(!receiveblock) { - if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )) - { - rx_retry=0; - if (ReadFile (hCom, &chRead, 1, &dwRead, NULL)) { - if (dwRead) { - receiveByte (chRead); - setEvent(40, bytetime-0.03f); // receive timing - receiveblock=true; - } - } - } else rx_retry++; - } - ByteTransmitted(); - break; - } - case SERIAL_THR_EVENT: { - ByteTransmitting(); - setEvent(SERIAL_TX_EVENT,bytetime+0.03f); - break; - } - } -} - -void CDirectSerial::CheckErrors() { - - DWORD errors=0; - // check for errors - if (ClearCommError (hCom, &errors, NULL)) - if (errors & (CE_BREAK | CE_FRAME | CE_RXPARITY)) { - Bit8u errreg = 0; - if (errors & CE_BREAK) errreg |= LSR_RX_BREAK_MASK; - if (errors & CE_FRAME) errreg |= LSR_FRAMING_ERROR_MASK; - if (errors & CE_RXPARITY) errreg |= LSR_PARITY_ERROR_MASK; - receiveError (errreg); - } -} - -/*****************************************************************************/ -/* updatePortConfig is called when emulated app changes the serial port **/ -/* parameters baudrate, stopbits, number of databits, parity. **/ -/*****************************************************************************/ -void CDirectSerial::updatePortConfig (Bit16u divider, Bit8u lcr) { - Bit8u parity = 0; - Bit8u bytelength = 0; - - // baud - if (divider == 0x1) - dcb.BaudRate = CBR_115200; - else if (divider == 0x2) - dcb.BaudRate = CBR_57600; - else if (divider == 0x3) - dcb.BaudRate = CBR_38400; - else if (divider == 0x6) - dcb.BaudRate = CBR_19200; - else if (divider == 0xc) - dcb.BaudRate = CBR_9600; - else if (divider == 0x18) - dcb.BaudRate = CBR_4800; - else if (divider == 0x30) - dcb.BaudRate = CBR_2400; - else if (divider == 0x60) - dcb.BaudRate = CBR_1200; - else if (divider == 0xc0) - dcb.BaudRate = CBR_600; - else if (divider == 0x180) - dcb.BaudRate = CBR_300; - else if (divider == 0x417) - dcb.BaudRate = CBR_110; - - // I read that windows can handle nonstandard baudrates: - else - dcb.BaudRate = 115200 / divider; - - // byte length - bytelength = lcr & 0x3; - bytelength += 5; - dcb.ByteSize = bytelength; - - // parity - parity = lcr & 0x38; - parity = parity >> 3; - switch (parity) { - case 0x1: - dcb.Parity = ODDPARITY; - break; - case 0x3: - dcb.Parity = EVENPARITY; - break; - case 0x5: - dcb.Parity = MARKPARITY; - break; - case 0x7: - dcb.Parity = SPACEPARITY; - break; - default: - dcb.Parity = NOPARITY; - break; - } - - // stopbits - if (lcr & 0x4) { - if (bytelength == 5) - dcb.StopBits = ONE5STOPBITS; - else - dcb.StopBits = TWOSTOPBITS; - } else { - dcb.StopBits = ONESTOPBIT; - } - -#ifdef SERIALPORT_DEBUGMSG - LOG_MSG ("__________________________"); - LOG_MSG ("Serial%d: new baud rate: %d", COMNUMBER, dcb.BaudRate); - LOG_MSG ("Serial%d: new bytelen: %d", COMNUMBER, dcb.ByteSize); - LOG_MSG ("Serial%d: new parity: %d", COMNUMBER, dcb.Parity); - LOG_MSG ("Serial%d: new stopbits: %d", COMNUMBER, dcb.StopBits); -#endif - - if (!SetCommState (hCom, &dcb)) { - -#if SERIAL_DEBUG - if(dbg_modemcontrol) - fprintf(debugfp,"%12.3f serial mode not supported: rate=%d,LCR=%x.\r\n", - PIC_FullIndex(),dcb.BaudRate,lcr); -#endif - - LOG_MSG ("Serial%d: Desired serial mode not supported (%d,%d,%d,%d", - (Bit32u)dcb.BaudRate,(Bit32u)dcb.ByteSize, - (Bit32u)dcb.Parity,(Bit32u)dcb.StopBits, COMNUMBER); - } -} - -void CDirectSerial::updateMSR () { - DWORD dptr = 0; - - if (!GetCommModemStatus (hCom, &dptr)) { -#ifdef SERIALPORT_DEBUGMSG -// LOG_MSG ("Serial port at %x: GetCommModemStatus failed!", base); -#endif - //return; - } - setCTS((dptr & MS_CTS_ON)!=0); - setDSR((dptr & MS_DSR_ON)!=0); - setRI ((dptr & MS_RING_ON)!=0); - setCD((dptr & MS_RLSD_ON)!=0); -} - -void CDirectSerial::transmitByte (Bit8u val, bool first) { - // mean bug: with break = 1, WriteFile will never return. - if((LCR&LCR_BREAK_MASK) == 0) { - DWORD bytesWritten = 0; - WriteFile (hCom, &val, 1, &bytesWritten, NULL); - if (bytesWritten != 1) - LOG_MSG ("Serial%d: COM port error: write failed!", idnumber); - } - if(first) setEvent(SERIAL_THR_EVENT, bytetime/8); - else setEvent(SERIAL_TX_EVENT, bytetime); -} - -/*****************************************************************************/ -/* setBreak(val) switches break on or off **/ -/*****************************************************************************/ -void CDirectSerial::setBreak (bool value) { - if (value) SetCommBreak (hCom); - else ClearCommBreak (hCom); -} - -/*****************************************************************************/ -/* updateModemControlLines(mcr) sets DTR and RTS. **/ -/*****************************************************************************/ -void CDirectSerial::setRTSDTR(bool rts, bool dtr) { - if(rts) dcb.fRtsControl = RTS_CONTROL_ENABLE; - else dcb.fRtsControl = RTS_CONTROL_DISABLE; - if(dtr) dcb.fDtrControl = DTR_CONTROL_ENABLE; - else dcb.fDtrControl = DTR_CONTROL_DISABLE; - SetCommState (hCom, &dcb); - -} -void CDirectSerial::setRTS(bool val) { - if(val) dcb.fRtsControl = RTS_CONTROL_ENABLE; - else dcb.fRtsControl = RTS_CONTROL_DISABLE; - SetCommState (hCom, &dcb); -} -void CDirectSerial::setDTR(bool val) { - if(val) dcb.fDtrControl = DTR_CONTROL_ENABLE; - else dcb.fDtrControl = DTR_CONTROL_DISABLE; - SetCommState (hCom, &dcb); -} - -#endif -#endif diff --git a/src/hardware/serialport/libserial.cpp b/src/hardware/serialport/libserial.cpp new file mode 100644 index 00000000..7ce82163 --- /dev/null +++ b/src/hardware/serialport/libserial.cpp @@ -0,0 +1,706 @@ +/* + * 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: libserial.cpp,v 1.1 2009-09-25 23:40:47 h-a-l-9000 Exp $ */ + +#include "libserial.h" + +#include "config.h" + +#ifdef WIN32 + +#include +#include + +struct _COMPORT { + HANDLE porthandle; + bool breakstatus; + DCB orig_dcb; +}; + +bool SERIAL_open(const char* portname, COMPORT* port) { + // allocate COMPORT structure + COMPORT cp = (_COMPORT*)malloc(sizeof(_COMPORT)); + if(cp == NULL) return false; + + cp->breakstatus=false; + + // open the port in NT object space (recommended by Microsoft) + // allows the user to open COM10+ and custom port names. + int len = strlen(portname); + if(len > 240) { + SetLastError(ERROR_BUFFER_OVERFLOW); + return false; + } + char extended_portname[256] = "\\\\.\\"; + memcpy(extended_portname+4,portname,len+1); + + cp->porthandle = CreateFile (extended_portname, + GENERIC_READ | GENERIC_WRITE, 0, + // must be opened with exclusive-access + NULL, // no security attributes + OPEN_EXISTING, // must use OPEN_EXISTING + 0, // non overlapped I/O + NULL // hTemplate must be NULL for comm devices + ); + + if (cp->porthandle == INVALID_HANDLE_VALUE) goto cleanup_error; + + cp->orig_dcb.DCBlength=sizeof(DCB); + + if(!GetCommState(cp->porthandle, &cp->orig_dcb)) { + goto cleanup_error; + } + + // configure the port for polling + DCB newdcb; + memcpy(&newdcb,&cp->orig_dcb,sizeof(DCB)); + + newdcb.fBinary=true; + newdcb.fParity=true; + newdcb.fOutxCtsFlow=false; + newdcb.fOutxDsrFlow=false; + newdcb.fDtrControl=DTR_CONTROL_DISABLE; + newdcb.fDsrSensitivity=false; + + newdcb.fOutX=false; + newdcb.fInX=false; + newdcb.fErrorChar=0; + newdcb.fNull=false; + newdcb.fRtsControl=RTS_CONTROL_DISABLE; + newdcb.fAbortOnError=false; + + if(!SetCommState(cp->porthandle, &newdcb)) { + goto cleanup_error; + } + + // Configure timeouts to effectively use polling + COMMTIMEOUTS ct; + ct.ReadIntervalTimeout = MAXDWORD; + ct.ReadTotalTimeoutConstant = 0; + ct.ReadTotalTimeoutMultiplier = 0; + ct.WriteTotalTimeoutConstant = 0; + ct.WriteTotalTimeoutMultiplier = 0; + if(!SetCommTimeouts(cp->porthandle, &ct)) { + goto cleanup_error; + } + if(!ClearCommBreak(cp->porthandle)) { + // Bluetooth Bluesoleil seems to not implement it + //goto cleanup_error; + } + DWORD errors; + if(!ClearCommError(cp->porthandle, &errors, NULL)) { + goto cleanup_error; + } + *port = cp; + return true; + +cleanup_error: + if (cp->porthandle != INVALID_HANDLE_VALUE) CloseHandle(cp->porthandle); + free(cp); + return false; +} + +void SERIAL_close(COMPORT port) { + // restore original DCB, close handle, free the COMPORT struct + if (port->porthandle != INVALID_HANDLE_VALUE) { + SetCommState(port->porthandle, &port->orig_dcb); + CloseHandle(port->porthandle); + } + free(port); +} + +void SERIAL_getErrorString(char* buffer, int length) { + int error = GetLastError(); + if(length < 50) return; + memset(buffer,0,length); + // get the error message text from the operating system + LPVOID sysmessagebuffer; + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &sysmessagebuffer, + 0,NULL); + + const char* err5text = "The specified port is already in use.\n"; + const char* err2text = "The specified port does not exist.\n"; + + int sysmsg_offset = 0; + + if(error == 5) { + sysmsg_offset = strlen(err5text); + memcpy(buffer,err5text,sysmsg_offset); + + } else if(error == 2) { + sysmsg_offset = strlen(err2text); + memcpy(buffer,err2text,sysmsg_offset); + } + + if((length - sysmsg_offset - strlen((const char*)sysmessagebuffer)) >= 0) + memcpy(buffer + sysmsg_offset, sysmessagebuffer, + strlen((const char*)sysmessagebuffer)); + + LocalFree(sysmessagebuffer); +} + + +void SERIAL_setDTR(COMPORT port, bool value) { + EscapeCommFunction(port->porthandle, value ? SETDTR:CLRDTR); +} + +void SERIAL_setRTS(COMPORT port, bool value) { + EscapeCommFunction(port->porthandle, value ? SETRTS:CLRRTS); +} + +void SERIAL_setBREAK(COMPORT port, bool value) { + EscapeCommFunction(port->porthandle, value ? SETBREAK:CLRBREAK); + port->breakstatus = value; +} + +int SERIAL_getmodemstatus(COMPORT port) { + DWORD retval = 0; + GetCommModemStatus (port->porthandle, &retval); + return (int)retval; +} + +bool SERIAL_sendchar(COMPORT port, char data) { + DWORD bytesWritten; + + // mean bug: with break = 1, WriteFile will never return. + if(port->breakstatus) return true; // true or false?! + + WriteFile (port->porthandle, &data, 1, &bytesWritten, NULL); + if(bytesWritten==1) return true; + else return false; +} + +// 0-7 char data, higher=flags +int SERIAL_getextchar(COMPORT port) { + DWORD errors = 0; // errors from API + DWORD dwRead = 0; // Number of chars read + char chRead; + + int retval = 0; + // receive a byte; TODO communicate faliure + if (ReadFile (port->porthandle, &chRead, 1, &dwRead, NULL)) { + if (dwRead) { + // check for errors + ClearCommError(port->porthandle, &errors, NULL); + // mask bits are identical + errors &= CE_BREAK|CE_FRAME|CE_RXPARITY|CE_OVERRUN; + retval |= (errors<<8); + retval |= (chRead & 0xff); + retval |= 0x10000; + } + } + return retval; +} + +bool SERIAL_setCommParameters(COMPORT port, + int baudrate, char parity, int stopbits, int length) { + + DCB dcb; + dcb.DCBlength=sizeof(dcb); + GetCommState(port->porthandle,&dcb); + + // parity + switch (parity) { + case 'n': dcb.Parity = NOPARITY; break; + case 'o': dcb.Parity = ODDPARITY; break; + case 'e': dcb.Parity = EVENPARITY; break; + case 'm': dcb.Parity = MARKPARITY; break; + case 's': dcb.Parity = SPACEPARITY; break; + default: + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + // stopbits + switch(stopbits) { + case SERIAL_1STOP: dcb.StopBits = ONESTOPBIT; break; + case SERIAL_2STOP: dcb.StopBits = TWOSTOPBITS; break; + case SERIAL_15STOP: dcb.StopBits = ONE5STOPBITS; break; + default: + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + // byte length + if(length > 8 || length < 5) { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + dcb.ByteSize = length; + dcb.BaudRate = baudrate; + + if (!SetCommState (port->porthandle, &dcb)) return false; + return true; +} +#endif + +#if defined (LINUX) || defined (MACOSX) + +#include // strlen +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include // sprinf + +struct _COMPORT { + int porthandle; + bool breakstatus; + termios backup; +}; + +bool SERIAL_open(const char* portname, COMPORT* port) { + int result; + // allocate COMPORT structure + COMPORT cp = (_COMPORT*)malloc(sizeof(_COMPORT)); + if(cp == NULL) return false; + + cp->breakstatus=false; + + int len = strlen(portname); + if(len > 240) { + ///////////////////////////////////SetLastError(ERROR_BUFFER_OVERFLOW); + return false; + } + char extended_portname[256] = "/dev/"; + memcpy(extended_portname+5,portname,len); + + cp->porthandle = open (extended_portname, O_RDWR | O_NOCTTY | O_NONBLOCK); + if (cp->porthandle < 0) goto cleanup_error; + + result = tcgetattr(cp->porthandle,&cp->backup); + if (result==-1) goto cleanup_error; + + // get port settings + termios termInfo; + memcpy(&termInfo,&cp->backup,sizeof(termios)); + + // initialize the port + termInfo.c_cflag = CS8 | CREAD | CLOCAL; // noparity, 1 stopbit + termInfo.c_iflag = PARMRK | INPCK; + termInfo.c_oflag = 0; + termInfo.c_lflag = 0; + termInfo.c_cc[VMIN] = 0; + termInfo.c_cc[VTIME] = 0; + + tcflush (cp->porthandle, TCIFLUSH); + tcsetattr (cp->porthandle, TCSANOW, &termInfo); + + *port = cp; + return true; + +cleanup_error: + if (cp->porthandle != 0) close(cp->porthandle); + free(cp); + return false; +} + +void SERIAL_close(COMPORT port) { + // restore original termios, close handle, free the COMPORT struct + if (port->porthandle >= 0) { + tcsetattr(port->porthandle, TCSANOW, &port->backup); + close(port->porthandle); + } + free(port); +} + +void SERIAL_getErrorString(char* buffer, int length) { + int error = errno; + if(length < 50) return; + memset(buffer,0,length); + // get the error message text from the operating system + // TODO (or not) + + const char* err5text = "The specified port is already in use.\n"; + const char* err2text = "The specified port does not exist.\n"; + + int sysmsg_offset = 0; + + if(error == EBUSY) { + sysmsg_offset = strlen(err5text); + memcpy(buffer,err5text,sysmsg_offset); + + } else if(error == 2) { + sysmsg_offset = strlen(err2text); + memcpy(buffer,err2text,sysmsg_offset); + } + + sprintf(buffer + sysmsg_offset, "System error %d.",error); + +} + +int SERIAL_getmodemstatus(COMPORT port) { + long flags = 0; + ioctl (port->porthandle, TIOCMGET, &flags); + int retval = 0; + if (flags & TIOCM_CTS) retval |= SERIAL_CTS; + if (flags & TIOCM_DSR) retval |= SERIAL_DSR; + if (flags & TIOCM_RI) retval |= SERIAL_RI; + if (flags & TIOCM_CD) retval |= SERIAL_CD; + return retval; +} + +bool SERIAL_sendchar(COMPORT port, char data) { + if(port->breakstatus) return true; // true or false?!; Does POSIX need this check? + int bytesWritten = write(port->porthandle, &data, 1); + if(bytesWritten==1) return true; + else return false; +} + +int SERIAL_getextchar(COMPORT port) { + unsigned char chRead = 0; + int dwRead = 0; + unsigned char error = 0; + int retval = 0; + + dwRead=read(port->porthandle,&chRead,1); + if (dwRead==1) { + if(chRead==0xff) // error escape + { + dwRead=read(port->porthandle,&chRead,1); + if(chRead==0x00) // an error + { + dwRead=read(port->porthandle,&chRead,1); + if(chRead==0x0) error=SERIAL_BREAK_ERR; + else error=SERIAL_FRAMING_ERR; + } + } + retval |= (error<<8); + retval |= chRead; + retval |= 0x10000; + } + return retval; +} + +bool SERIAL_setCommParameters(COMPORT port, + int baudrate, char parity, int stopbits, int length) { + + termios termInfo; + int result = tcgetattr(port->porthandle, &termInfo); + if (result==-1) return false; + termInfo.c_cflag = CREAD | CLOCAL; + + // parity + // "works on many systems" + #define CMSPAR 010000000000 + switch (parity) { + case 'n': break; + case 'o': termInfo.c_cflag |= (PARODD | PARENB); break; + case 'e': termInfo.c_cflag |= PARENB; break; + case 'm': termInfo.c_cflag |= (PARENB | CMSPAR | PARODD); break; + case 's': termInfo.c_cflag |= (PARENB | CMSPAR); break; + default: + return false; + } + // stopbits + switch(stopbits) { + case SERIAL_1STOP: break; + case SERIAL_2STOP: + case SERIAL_15STOP: termInfo.c_cflag |= CSTOPB; break; + default: + return false; + } + // byte length + if(length > 8 || length < 5) return false; + switch (length) { + case 5: termInfo.c_cflag |= CS5; break; + case 6: termInfo.c_cflag |= CS6; break; + case 7: termInfo.c_cflag |= CS7; break; + case 8: termInfo.c_cflag |= CS8; break; + } + // baudrate + int posix_baudrate=0; + switch(baudrate) { + case 115200: posix_baudrate = B115200; break; + case 57600: posix_baudrate = B57600; break; + case 38400: posix_baudrate = B38400; break; + case 19200: posix_baudrate = B19200; break; + case 9600: posix_baudrate = B9600; break; + case 4800: posix_baudrate = B4800; break; + case 2400: posix_baudrate = B2400; break; + case 1200: posix_baudrate = B1200; break; + case 600: posix_baudrate = B600; break; + case 300: posix_baudrate = B300; break; + case 110: posix_baudrate = B110; break; + default: return false; + } + cfsetospeed (&termInfo, posix_baudrate); + cfsetispeed (&termInfo, posix_baudrate); + + int retval = tcsetattr(port->porthandle, TCSANOW, &termInfo); + if(retval==-1) return false; + return true; +} + +void SERIAL_setBREAK(COMPORT port, bool value) { + ioctl(port->porthandle, value?TIOCSBRK:TIOCCBRK); +} + +void SERIAL_setDTR(COMPORT port, bool value) { + long flag = TIOCM_DTR; + ioctl(port->porthandle, value?TIOCMBIS:TIOCMBIC, &flag); +} + +void SERIAL_setRTS(COMPORT port, bool value) { + long flag = TIOCM_RTS; + ioctl(port->porthandle, value?TIOCMBIS:TIOCMBIC, &flag); +} +#endif + +#ifdef OS2 +// OS/2 related headers +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSDEVICES +#define INCL_DOSDEVIOCTL +#define INCL_DOSPROCESS +#include + +struct _COMPORT { + HFILE porthandle; + bool breakstatus; + DCBINFO backup; +}; +// TODO: THIS IS INCOMPLETE and UNTESTED. + +bool SERIAL_open(const char* portname, COMPORT* port) { + // allocate COMPORT structure + COMPORT cp = (_COMPORT*)malloc(sizeof(_COMPORT)); + if(cp == NULL) return false; + cp->porthandle=0; + cp->breakstatus=false; + + ULONG ulAction = 0; + APIRET rc = DosOpen(portname, &cp->porthandle, + &ulAction, 0L, FILE_NORMAL, FILE_OPEN, + OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | OPEN_FLAGS_SEQUENTIAL, 0L); + if (rc != NO_ERROR) { + goto cleanup_error; + } + + ULONG ulParmLen = sizeof(DCBINFO); + rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, + 0, 0, 0, &cp->orig_dcb, ulParmLen, &ulParmLen); + if ( rc != NO_ERROR) { + goto cleanup_error; + } + // configure the port for polling + DCBINFO newdcb; + memcpy(&newdcb,&cp->orig_dcb,sizeof(DCBINFO)); + + newdcb.usWriteTimeout = 0; + newdcb.usReadTimeout = 0; //65535; + newdcb.fbCtlHndShake = dcb.fbFlowReplace = 0; + newdcb.fbTimeout = 6; + + rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, + &newdcb, ulParmLen, &ulParmLen, 0, 0, 0); + if ( rc != NO_ERROR) { + goto cleanup_error; + } + + USHORT errors = 0; + ulParmLen = sizeof(errors); + rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMERROR, + 0, 0, 0, &errors, ulParmLen, &ulParmLen); + if ( rc != NO_ERROR) { + goto cleanup_error; + } + + *port = cp; + return true; + +cleanup_error: + // TODO error string - rc value + if (cp->porthandle != 0) CloseHandle(cp->porthandle); + free(cp); + return false; +} + +void SERIAL_getErrorString(char* buffer, int length) { + sprintf(buffer, "TODO: error handling is not fun"); +} +void SERIAL_close(COMPORT port) { + ULONG ulParmLen = sizeof(DCBINFO); + // restore original DCB, close handle, free the COMPORT struct + if (port->porthandle != 0) { + DosDevIOCtl(port->porthandle, IOCTL_ASYNC, ASYNC_SETDCBINFO, + &port->orig_dcb, ulParmLen, &ulParmLen, 0, 0, 0); + SetCmmState(port->porthandle, &port->orig_dcb); + DosClose (port->porthandle); + } + free(port); +} +bool SERIAL_sendchar(COMPORT port, char data) { + ULONG bytesWritten = 0; + if(port->breakstatus) return true; // does OS/2 need this? + + APIRET rc = DosWrite(port->porthandle, &data, 1, &bytesWritten); + if (rc == NO_ERROR && bytesWritten > 0) return true; + else return false; +} + +void SERIAL_setBREAK(COMPORT port, bool value) { + USHORT error; + ULONG ulParmLen = sizeof(error); + DosDevIOCtl(port->porthandle, IOCTL_ASYNC, + value? ASYNC_SETBREAKON:ASYNC_SETBREAKOFF, + 0,0,0, &error, ulParmLen, &ulParmLen); +} + +int SERIAL_getextchar(COMPORT port) { + ULONG dwRead = 0; // Number of chars read + char chRead; + + int retval = 0; + // receive a byte; TODO communicate faliure + if (DosRead(port->porthandle, &chRead, 1, &dwRead) == NO_ERROR) { + if (dwRead) { + // check for errors; will OS/2 clear the error on reading its data? + // if yes then this is in wrong order + USHORT errors = 0, event = 0; + ULONG ulParmLen = sizeof(errors); + DosDevIOCtl(port->porthandle, IOCTL_ASYNC, ASYNC_GETCOMMEVENT, + 0, 0, 0, &event, ulParmLen, &ulParmLen); + if (event & (64 + 128) ) { // Break (Bit 6) or Frame or Parity (Bit 7) error + Bit8u errreg = 0; + if (event & 64) retval |= SERIAL_BREAK_ERR; + if (event & 128) { + DosDevIOCtl(port->porthandle, IOCTL_ASYNC, ASYNC_GETCOMMERROR, + 0, 0, 0, &errors, ulParmLen, &ulParmLen); + if (errors & 8) retval |= SERIAL_FRAMING_ERR; + if (errors & 4) retval |= SERIAL_PARITY_ERR; + } + } + retval |= (chRead & 0xff); + retval |= 0x10000; + } + } + return retval; +} + + +int SERIAL_getmodemstatus(COMPORT port) { + UCHAR dptr = 0; + ULONG ulParmLen = sizeof(dptr); + DosDevIOCtl(port->porthandle, IOCTL_ASYNC, ASYNC_GETMODEMINPUT, + 0, 0, 0, &dptr, ulParmLen, &ulParmLen); + // bits are the same as return value + return (int)dptr; +} +void SERIAL_setDTR(COMPORT port, bool value) { + UCHAR masks[2]; + ULONG ulParmLen = sizeof(masks); + if(value) { + masks[0]=0x01; + masks[1]=0xFF; + } else { + masks[0]=0x00; + masks[1]=0xFE; + } + DosDevIOCtl(port->porthandle, IOCTL_ASYNC, ASYNC_SETMODEMCTRL, + 0,0,0, &masks, ulParmLen, &ulParmLen); +} + +void SERIAL_setRTS(COMPORT port, bool value) { + UCHAR masks[2]; + ULONG ulParmLen = sizeof(masks); + if(value) { + masks[0]=0x02; + masks[1]=0xFF; + } else { + masks[0]=0x00; + masks[1]=0xFD; + } + DosDevIOCtl(port->porthandle, IOCTL_ASYNC, ASYNC_SETMODEMCTRL, + 0,0,0, &masks, ulParmLen, &ulParmLen); +} + + + +bool SERIAL_setCommParameters(COMPORT port, + int baudrate, char parity, int stopbits, int length) { + // baud + struct { + ULONG baud; + BYTE fraction; + } setbaud; + + setbaud.baud = baudrate; + setbaud.fraction = 0; + ULONG ulParmLen = sizeof(setbaud); + APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_EXTSETBAUDRATE, + &setbaud, ulParmLen, &ulParmLen, 0, 0, 0); + if (rc != NO_ERROR) { + return false; + } + + struct { + UCHAR data; + UCHAR parity; + UCHAR stop; + } paramline; + + // byte length + if(length > 8 || length < 5) { + // TODO SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + paramline.data = length; + + // parity + switch (parity) { + case 'n': paramline.parity = 0; break; + case 'o': paramline.parity = 1; break; + case 'e': paramline.parity = 2; break; + case 'm': paramline.parity = 3; break; + case 's': paramline.parity = 4; break; + default: + // TODO SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + // stopbits + switch(stopbits) { + case SERIAL_1STOP: paramline.stop = 0; break; + case SERIAL_2STOP: paramline.stop = 2; break; + case SERIAL_15STOP: paramline.stop = 1; break; + default: + // TODO SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + // set it + ulParmLen = sizeof(paramline); + rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETLINECTRL, + ¶mline, ulParmLen, &ulParmLen, 0, 0, 0); + if ( rc != NO_ERROR) + return false; + return true; +} +#endif diff --git a/src/hardware/serialport/libserial.h b/src/hardware/serialport/libserial.h new file mode 100644 index 00000000..25981a49 --- /dev/null +++ b/src/hardware/serialport/libserial.h @@ -0,0 +1,56 @@ +/* + * 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: libserial.h,v 1.1 2009-09-25 23:40:47 h-a-l-9000 Exp $ */ + +typedef struct _COMPORT *COMPORT; + +bool SERIAL_open(const char* portname, COMPORT* port); +void SERIAL_close(COMPORT port); +void SERIAL_getErrorString(char* buffer, int length); + +#define SERIAL_1STOP 1 +#define SERIAL_2STOP 2 +#define SERIAL_15STOP 0 + +// parity: n, o, e, m, s + +bool SERIAL_setCommParameters(COMPORT port, + int baudrate, char parity, int stopbits, int length); + +void SERIAL_setDTR(COMPORT port, bool value); +void SERIAL_setRTS(COMPORT port, bool value); +void SERIAL_setBREAK(COMPORT port, bool value); + +#define SERIAL_CTS 0x10 +#define SERIAL_DSR 0x20 +#define SERIAL_RI 0x40 +#define SERIAL_CD 0x80 + +int SERIAL_getmodemstatus(COMPORT port); +bool SERIAL_setmodemcontrol(COMPORT port, int flags); + +bool SERIAL_sendchar(COMPORT port, char data); + +// 0-7 char data, higher=flags +#define SERIAL_BREAK_ERR 0x10 +#define SERIAL_FRAMING_ERR 0x08 +#define SERIAL_PARITY_ERR 0x04 +#define SERIAL_OVERRUN_ERR 0x02 + +int SERIAL_getextchar(COMPORT port); diff --git a/src/hardware/serialport/misc_util.cpp b/src/hardware/serialport/misc_util.cpp index 9968cd9b..6ba488d5 100644 --- a/src/hardware/serialport/misc_util.cpp +++ b/src/hardware/serialport/misc_util.cpp @@ -1,3 +1,24 @@ +/* + * 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 $ */ + + #include "config.h" #if C_MODEM diff --git a/src/hardware/serialport/misc_util.h b/src/hardware/serialport/misc_util.h index 08a36123..e4260422 100644 --- a/src/hardware/serialport/misc_util.h +++ b/src/hardware/serialport/misc_util.h @@ -1,3 +1,23 @@ +/* + * 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: misc_util.h,v 1.5 2009-09-25 23:40:47 h-a-l-9000 Exp $ */ + #ifndef SDLNETWRAPPER_H #define SDLNETWRAPPER_H diff --git a/src/hardware/serialport/nullmodem.cpp b/src/hardware/serialport/nullmodem.cpp index c447ad29..605d3826 100644 --- a/src/hardware/serialport/nullmodem.cpp +++ b/src/hardware/serialport/nullmodem.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: nullmodem.cpp,v 1.7 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: nullmodem.cpp,v 1.8 2009-09-25 23:40:47 h-a-l-9000 Exp $ */ #include "dosbox.h" @@ -36,7 +36,8 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) { clientport = 0; rx_retry = 0; - rx_retry_max = 100; + rx_retry_max = 20; + rx_state=N_RX_DISC; tx_gather = 12; @@ -51,7 +52,7 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) { // usedtr: The nullmodem will // 1) when it is client connect to the server not immediately but // as soon as a modem-aware application is started (DTR is switched on). - // 2) only transfer data when DTR is on. + // 2) only receive data when DTR is on. if(getBituSubstring("usedtr:", &bool_temp, cmd)) { if(bool_temp==1) { dtrrespect=true; @@ -105,6 +106,9 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) { clientsocket = new TCPClientSocket(sock); if(!clientsocket->isopen) { LOG_MSG("Serial%d: Connection failed.",COMNUMBER); +#if SERIAL_DEBUG + log_ser(dbg_aux,"Nullmodem: Connection failed."); +#endif delete clientsocket; clientsocket=0; return; @@ -115,6 +119,9 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) { if(!transparent) setRTSDTR(getRTS(), getDTR()); LOG_MSG("Serial%d: Connected to %s",COMNUMBER,peernamebuf); +#if SERIAL_DEBUG + log_ser(dbg_aux,"Nullmodem: Connected to %s",peernamebuf); +#endif setEvent(SERIAL_POLLING_EVENT, 1); CSerial::Init_Registers (); @@ -204,7 +211,7 @@ Bits CNullModem::readChar() { if(rxchar==0xff) return rxchar; // 0xff 0xff -> 0xff was meant rxchar&0x1? setCTS(true) : setCTS(false); rxchar&0x2? setDSR(true) : setDSR(false); - if(rxchar&0x4) receiveError(0x10); + if(rxchar&0x4) receiveByteEx(0x0,0x10); return -1; // no "payload" received } else return rxchar; } @@ -223,14 +230,16 @@ void CNullModem::ClientConnect(){ clientsocket->GetRemoteAddressString(peernamebuf); // transmit the line status if(!transparent) setRTSDTR(getRTS(), getDTR()); - + rx_state=N_RX_IDLE; LOG_MSG("Serial%d: Connected to %s",idnumber+1,peernamebuf); setEvent(SERIAL_POLLING_EVENT, 1); } void CNullModem::Disconnect() { + removeEvent(SERIAL_POLLING_EVENT); + removeEvent(SERIAL_RX_EVENT); // it was disconnected; free the socket and restart the server socket - LOG_MSG("Serial%d: Disconnected.",idnumber+1); + LOG_MSG("Serial%d: Disconnected.",COMNUMBER); delete clientsocket; clientsocket=0; setDSR(false); @@ -249,48 +258,115 @@ void CNullModem::handleUpperEvent(Bit16u type) { case SERIAL_POLLING_EVENT: { // periodically check if new data arrived, disconnect // if required. Add it back. - if(!receiveblock && clientsocket) { - if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max ) - &&(!dtrrespect | (dtrrespect&& getDTR()) )) { - rx_retry=0; - Bits rxchar = readChar(); - if(rxchar>=0) { - receiveblock=true; - setEvent(SERIAL_RX_EVENT, bytetime-0.01f); - receiveByte((Bit8u)rxchar); + setEvent(SERIAL_POLLING_EVENT, 1.0f); + // update Modem input line states + updateMSR(); + switch(rx_state) { + case N_RX_IDLE: + if(CanReceiveByte()) { + if(doReceive()) { + // a byte was received + rx_state=N_RX_WAIT; + setEvent(SERIAL_RX_EVENT, bytetime*0.9f); + } // else still idle + } else { +#if SERIAL_DEBUG + log_ser(dbg_aux,"Nullmodem: block on polling."); +#endif + rx_state=N_RX_BLOCKED; + // have both delays (1ms + bytetime) + setEvent(SERIAL_RX_EVENT, bytetime*0.9f); } - else if(rxchar==-2) Disconnect(); - else setEvent(SERIAL_POLLING_EVENT, 1); - } else { - rx_retry++; - setEvent(SERIAL_POLLING_EVENT, 1); - } - } + break; + case N_RX_BLOCKED: + // one timeout tick + if(!CanReceiveByte()) { + rx_retry++; + if(rx_retry>=rx_retry_max) { + // it has timed out: + rx_retry=0; + removeEvent(SERIAL_RX_EVENT); + if(doReceive()) { + // read away everything + while(doReceive()); + rx_state=N_RX_WAIT; + setEvent(SERIAL_RX_EVENT, bytetime*0.9f); + } else { + // much trouble about nothing + rx_state=N_RX_IDLE; +#if SERIAL_DEBUG + log_ser(dbg_aux,"Nullmodem: unblock due to no more data",rx_retry); +#endif + } + } // else wait further + } else { + // good: we can receive again + removeEvent(SERIAL_RX_EVENT); + rx_retry=0; + if(doReceive()) { + rx_state=N_RX_FASTWAIT; + setEvent(SERIAL_RX_EVENT, bytetime*0.65f); + } else { + // much trouble about nothing + rx_state=N_RX_IDLE; + } + } + break; + + case N_RX_WAIT: + case N_RX_FASTWAIT: + break; + } break; } case SERIAL_RX_EVENT: { - // receive time is up, try to receive another byte. - receiveblock=false; - - if((!(LSR&LSR_RX_DATA_READY_MASK) || rx_retry>=rx_retry_max) - &&(!dtrrespect | (dtrrespect&& getDTR()) ) - ) { - rx_retry=0; - Bits rxchar = readChar(); - if(rxchar>=0) { - receiveblock=true; - setEvent(SERIAL_RX_EVENT, bytetime-0.01f); - receiveByte((Bit8u)rxchar); - } - else if(rxchar==-2) Disconnect(); - else setEvent(SERIAL_POLLING_EVENT, 1); - } else { - setEvent(SERIAL_POLLING_EVENT, 1); - rx_retry++; + switch(rx_state) { + case N_RX_IDLE: + LOG_MSG("internal error in nullmodem"); + break; + + case N_RX_BLOCKED: // try to receive + case N_RX_WAIT: + case N_RX_FASTWAIT: + if(CanReceiveByte()) { + // just works or unblocked + if(doReceive()) { + rx_retry=0; // not waiting anymore + if(rx_state==N_RX_WAIT) setEvent(SERIAL_RX_EVENT, bytetime*0.9f); + else { + // maybe unblocked + rx_state=N_RX_FASTWAIT; + setEvent(SERIAL_RX_EVENT, bytetime*0.65f); + } + } else { + // didn't receive anything + rx_retry=0; + rx_state=N_RX_IDLE; + } + } else { + // blocking now or still blocked +#if SERIAL_DEBUG + if(rx_state==N_RX_BLOCKED) + log_ser(dbg_aux,"Nullmodem: rx still blocked (retry=%d)",rx_retry); + else log_ser(dbg_aux,"Nullmodem: block on continued rx (retry=%d).",rx_retry); +#endif + setEvent(SERIAL_RX_EVENT, bytetime*0.65f); + rx_state=N_RX_BLOCKED; + } + + break; } break; } case SERIAL_TX_EVENT: { + // Maybe echo cirquit works a bit better this way + if(rx_state==N_RX_IDLE && CanReceiveByte() && clientsocket) { + if(doReceive()) { + // a byte was received + rx_state=N_RX_WAIT; + setEvent(SERIAL_RX_EVENT, bytetime*0.9f); + } + } ByteTransmitted(); break; } @@ -301,15 +377,18 @@ void CNullModem::handleUpperEvent(Bit16u type) { break; } case SERIAL_SERVER_POLLING_EVENT: { - // As long as nothing is connected to out server poll the + // As long as nothing is connected to our server poll the // connection. clientsocket=serversocket->Accept(); if(clientsocket) { Bit8u peeripbuf[16]; clientsocket->GetRemoteAddressString(peeripbuf); - LOG_MSG("Serial%d: A client (%s) has connected.",idnumber+1,peeripbuf); - // new socket found... + LOG_MSG("Serial%d: A client (%s) has connected.",COMNUMBER,peeripbuf); +#if SERIAL_DEBUG + log_ser(dbg_aux,"Nullmodem: A client (%s) has connected.", peeripbuf); +#endif// new socket found... clientsocket->SetSendBufferSize(256); + rx_state=N_RX_IDLE; setEvent(SERIAL_POLLING_EVENT, 1); // we don't accept further connections @@ -350,15 +429,23 @@ void CNullModem::updateMSR () { } +bool CNullModem::doReceive () { + Bits rxchar = readChar(); + if(rxchar>=0) { + receiveByteEx((Bit8u)rxchar,0); + return true; + } + else if(rxchar==-2) { + Disconnect(); + } + return false; +} + void CNullModem::transmitByte (Bit8u val, bool first) { + // transmit it later in THR_Event + if(first) setEvent(SERIAL_THR_EVENT, bytetime/8); + else setEvent(SERIAL_TX_EVENT, bytetime); - // transmit it later in THR_Event - if(first) { - setEvent(SERIAL_THR_EVENT, bytetime/8); - } else { - //if(clientsocket) clientsocket->Putchar(val); - setEvent(SERIAL_TX_EVENT, bytetime); - } // disable 0xff escaping when transparent mode is enabled if (!transparent && (val==0xff)) WriteChar(0xff); diff --git a/src/hardware/serialport/nullmodem.h b/src/hardware/serialport/nullmodem.h index 7869e3e6..395af647 100644 --- a/src/hardware/serialport/nullmodem.h +++ b/src/hardware/serialport/nullmodem.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: nullmodem.h,v 1.3 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: nullmodem.h,v 1.4 2009-09-25 23:40:47 h-a-l-9000 Exp $ */ // include guard #ifndef DOSBOX_NULLMODEM_WIN32_H @@ -57,6 +57,14 @@ public: void setDTR(bool val); void handleUpperEvent(Bit16u type); + Bitu rx_state; +#define N_RX_IDLE 0 +#define N_RX_WAIT 1 +#define N_RX_BLOCKED 2 +#define N_RX_FASTWAIT 3 +#define N_RX_DISC 4 + + bool doReceive(); void ClientConnect(); void Disconnect(); Bits readChar(); diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index fab9b220..84b4b330 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.cpp,v 1.12 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: serialport.cpp,v 1.13 2009-09-25 23:40:47 h-a-l-9000 Exp $ */ #include #include @@ -30,15 +30,14 @@ #include "callback.h" // CALLBACK_Idle #include "serialport.h" -#include "directserial_win32.h" -#include "directserial_posix.h" -#include "directserial_os2.h" +#include "directserial.h" #include "serialdummy.h" #include "softmodem.h" #include "nullmodem.h" #include "cpu.h" +#define LOG_SER(x) log_ser bool device_COM::Read(Bit8u * data,Bit16u * size) { // DTR + RTS on @@ -98,97 +97,140 @@ device_COM::~device_COM() { CSerial* serialports[4] ={0,0,0,0}; static Bitu SERIAL_Read (Bitu port, Bitu iolen) { - for(Bitu i = 0; i < 4; i++) { - if(serial_baseaddr[i]==(port&0xfff8) && (serialports[i]!=0)) { - Bitu retval=0xff; - switch (port & 0x7) { - case RHR_OFFSET: - retval = serialports[i]->Read_RHR(); - break; - case IER_OFFSET: - retval = serialports[i]->Read_IER(); - break; - case ISR_OFFSET: - retval = serialports[i]->Read_ISR(); - break; - case LCR_OFFSET: - retval = serialports[i]->Read_LCR(); - break; - case MCR_OFFSET: - retval = serialports[i]->Read_MCR(); - break; - case LSR_OFFSET: - retval = serialports[i]->Read_LSR(); - break; - case MSR_OFFSET: - retval = serialports[i]->Read_MSR(); - break; - case SPR_OFFSET: - retval = serialports[i]->Read_SPR(); - break; - } + Bitu i; + Bitu retval; + Bitu index = port & 0x7; + switch(port&0xff8) { + case 0x3f8: i=0; break; + case 0x2f8: i=1; break; + case 0x3e8: i=2; break; + case 0x2e8: i=3; break; + default: return 0xff; + } + if(serialports[i]==0) return 0xff; + + switch (index) { + case RHR_OFFSET: + retval = serialports[i]->Read_RHR(); + break; + case IER_OFFSET: + retval = serialports[i]->Read_IER(); + break; + case ISR_OFFSET: + retval = serialports[i]->Read_ISR(); + break; + case LCR_OFFSET: + retval = serialports[i]->Read_LCR(); + break; + case MCR_OFFSET: + retval = serialports[i]->Read_MCR(); + break; + case LSR_OFFSET: + retval = serialports[i]->Read_LSR(); + break; + case MSR_OFFSET: + retval = serialports[i]->Read_MSR(); + break; + case SPR_OFFSET: + retval = serialports[i]->Read_SPR(); + break; + } #if SERIAL_DEBUG - const char* const dbgtext[]= - {"RHR","IER","ISR","LCR","MCR","LSR","MSR","SPR"}; - if(serialports[i]->dbg_register) - fprintf(serialports[i]->debugfp,"%12.3f read 0x%x from %s.\r\n", - PIC_FullIndex(),retval,dbgtext[port&0x7]); -#endif - - return retval; - } + const char* const dbgtext[]= + {"RHR","IER","ISR","LCR","MCR","LSR","MSR","SPR","DLL","DLM"}; + if(serialports[i]->dbg_register) { + if((index<2) && ((serialports[i]->LCR)&LCR_DIVISOR_Enable_MASK)) + index += 8; + serialports[i]->log_ser(serialports[i]->dbg_register, + "read 0x%2x from %s.",retval,dbgtext[index]); } - return 0xff; +#endif + return retval; } static void SERIAL_Write (Bitu port, Bitu val, Bitu) { + Bitu i; + Bitu index = port & 0x7; + switch(port&0xff8) { + case 0x3f8: i=0; break; + case 0x2f8: i=1; break; + case 0x3e8: i=2; break; + case 0x2e8: i=3; break; + default: return; + } + if(serialports[i]==0) return; - for(Bitu i = 0; i < 4; i++) { - if(serial_baseaddr[i]==(port&0xfff8) && serialports[i]) { - #if SERIAL_DEBUG - const char* const dbgtext[]={"THR","IER","FCR","LCR","MCR","!LSR","MSR","SPR"}; - if(serialports[i]->dbg_register) - fprintf(serialports[i]->debugfp,"%12.3f write 0x%x to %s.\r\n", - PIC_FullIndex(),val,dbgtext[port&0x7]); -#endif - - switch (port & 0x7) { - case THR_OFFSET: - serialports[i]->Write_THR (val); - return; - case IER_OFFSET: - serialports[i]->Write_IER (val); - return; - case FCR_OFFSET: - serialports[i]->Write_FCR (val); - return; - case LCR_OFFSET: - serialports[i]->Write_LCR (val); - return; - case MCR_OFFSET: - serialports[i]->Write_MCR (val); - return; - case MSR_OFFSET: - serialports[i]->Write_MSR (val); - return; - case SPR_OFFSET: - serialports[i]->Write_SPR (val); - return; - default: - serialports[i]->Write_reserved (val, port & 0x7); - } + const char* const dbgtext[]={"THR","IER","FCR", + "LCR","MCR","!LSR","MSR","SPR","DLL","DLM"}; + if(serialports[i]->dbg_register) { + Bitu debugindex=index; + if((index<2) && ((serialports[i]->LCR)&LCR_DIVISOR_Enable_MASK)) + debugindex += 8; + serialports[i]->log_ser(serialports[i]->dbg_register, + "write 0x%2x to %s.",val,dbgtext[debugindex]); } +#endif + switch (index) { + case THR_OFFSET: + serialports[i]->Write_THR (val); + return; + case IER_OFFSET: + serialports[i]->Write_IER (val); + return; + case FCR_OFFSET: + serialports[i]->Write_FCR (val); + return; + case LCR_OFFSET: + serialports[i]->Write_LCR (val); + return; + case MCR_OFFSET: + serialports[i]->Write_MCR (val); + return; + case MSR_OFFSET: + serialports[i]->Write_MSR (val); + return; + case SPR_OFFSET: + serialports[i]->Write_SPR (val); + return; + default: + serialports[i]->Write_reserved (val, port & 0x7); } } +#if SERIAL_DEBUG +void CSerial::log_ser(bool active, char const* format,...) { + if(active) { + // copied from DEBUG_SHOWMSG + char buf[512]; + buf[0]=0; + sprintf(buf,"%12.3f [% 7u] ",PIC_FullIndex(), SDL_GetTicks()); + va_list msg; + va_start(msg,format); + vsprintf(buf+strlen(buf),format,msg); + va_end(msg); + // Add newline if not present + Bitu len=strlen(buf); + if(buf[len-1]!='\n') strcat(buf,"\r\n"); + fputs(buf,debugfp); + } +} +#endif void CSerial::changeLineProperties() { // update the event wait time + float bitlen; - float bitlen = (1000.0f/115200.0f)*(float)baud_divider; + if(baud_divider==0) bitlen=(1000.0f/115200.0f); + else bitlen = (1000.0f/115200.0f)*(float)baud_divider; bytetime=bitlen*(float)(1+5+1); // startbit + minimum length + stopbit bytetime+= bitlen*(float)(LCR&0x3); // databits if(LCR&0x4) bytetime+=bitlen; // stopbit + +#if SERIAL_DEBUG + const char* const dbgtext[]={"none","odd","none","even","none","mark","none","space"}; + log_ser(dbg_serialtraffic,"New COM parameters: baudrate %5.0f, parity %s, wordlen %d, stopbits %d", + 1.0/bitlen*1000.0f,dbgtext[(LCR&0x38)>>3],(LCR&0x3)+5,((LCR&0x4)>>2)+1); +#endif updatePortConfig (baud_divider, LCR); } @@ -212,35 +254,38 @@ void CSerial::handleEvent(Bit16u type) { case SERIAL_TX_LOOPBACK_EVENT: { #if SERIAL_DEBUG - if(dbg_serialtraffic) - fprintf(debugfp,loopback_data<0x10? "%12.3f tx 0x%02x (%u) (loopback)\r\n": - "%12.3f tx 0x%02x (%c) (loopback)\r\n", - PIC_FullIndex(),loopback_data, - loopback_data); + log_ser(dbg_serialtraffic,loopback_data<0x10? + "tx 0x%02x (%u) (loopback)":"tx 0x%02x (%c) (loopback)", + loopback_data, loopback_data); #endif - receiveByte (loopback_data); ByteTransmitted (); break; } case SERIAL_THR_LOOPBACK_EVENT: { + loopback_data=txfifo->probeByte(); ByteTransmitting(); - loopback_data=THR; setEvent(SERIAL_TX_LOOPBACK_EVENT,bytetime); break; } case SERIAL_ERRMSG_EVENT: { - LOG_MSG("Serial%d: Errors occured: "\ - "Framing %d, Parity %d, Overrun %d (IF0:%d), Break %d", COMNUMBER, - framingErrors, parityErrors, overrunErrors, overrunIF0, breakErrors); + LOG_MSG("Serial%d: Errors: "\ + "Framing %d, Parity %d, Overrun RX:%d (IF0:%d), TX:%d, Break %d", + COMNUMBER, framingErrors, parityErrors, overrunErrors, + overrunIF0,txOverrunErrors, breakErrors); errormsg_pending=false; framingErrors=0; parityErrors=0; overrunErrors=0; + txOverrunErrors=0; overrunIF0=0; breakErrors=0; break; } + case SERIAL_RX_TIMEOUT_EVENT: { + rise(TIMEOUT_PRIORITY); + break; + } default: handleUpperEvent(type); } } @@ -250,20 +295,14 @@ void CSerial::handleEvent(Bit16u type) { /*****************************************************************************/ void CSerial::rise (Bit8u priority) { #if SERIAL_DEBUG - if(dbg_interrupt) - { - if(priority&TX_PRIORITY && !(waiting_interrupts&TX_PRIORITY)) - fprintf(debugfp,"%12.3f tx interrupt on.\r\n",PIC_FullIndex()); - - if(priority&RX_PRIORITY && !(waiting_interrupts&RX_PRIORITY)) - fprintf(debugfp,"%12.3f rx interrupt on.\r\n",PIC_FullIndex()); - - if(priority&MSR_PRIORITY && !(waiting_interrupts&MSR_PRIORITY)) - fprintf(debugfp,"%12.3f msr interrupt on.\r\n",PIC_FullIndex()); - - if(priority&ERROR_PRIORITY && !(waiting_interrupts&ERROR_PRIORITY)) - fprintf(debugfp,"%12.3f error interrupt on.\r\n",PIC_FullIndex()); - } + if(priority&TX_PRIORITY && !(waiting_interrupts&TX_PRIORITY)) + log_ser(dbg_interrupt,"tx interrupt on."); + if(priority&RX_PRIORITY && !(waiting_interrupts&RX_PRIORITY)) + log_ser(dbg_interrupt,"rx interrupt on."); + if(priority&MSR_PRIORITY && !(waiting_interrupts&MSR_PRIORITY)) + log_ser(dbg_interrupt,"msr interrupt on."); + if(priority&TIMEOUT_PRIORITY && !(waiting_interrupts&TIMEOUT_PRIORITY)) + log_ser(dbg_interrupt,"fifo rx timeout interrupt on."); #endif waiting_interrupts |= priority; @@ -274,23 +313,15 @@ void CSerial::rise (Bit8u priority) { void CSerial::clear (Bit8u priority) { #if SERIAL_DEBUG - if(dbg_interrupt) - { - if(priority&TX_PRIORITY && (waiting_interrupts&TX_PRIORITY)) - fprintf(debugfp,"%12.3f tx interrupt off.\r\n",PIC_FullIndex()); - - if(priority&RX_PRIORITY && (waiting_interrupts&RX_PRIORITY)) - fprintf(debugfp,"%12.3f rx interrupt off.\r\n",PIC_FullIndex()); - - if(priority&MSR_PRIORITY && (waiting_interrupts&MSR_PRIORITY)) - fprintf(debugfp,"%12.3f msr interrupt off.\r\n",PIC_FullIndex()); - - if(priority&ERROR_PRIORITY && (waiting_interrupts&ERROR_PRIORITY)) - fprintf(debugfp,"%12.3f error interrupt off.\r\n",PIC_FullIndex()); - } + if(priority&TX_PRIORITY && (waiting_interrupts&TX_PRIORITY)) + log_ser(dbg_interrupt,"tx interrupt off."); + if(priority&RX_PRIORITY && (waiting_interrupts&RX_PRIORITY)) + log_ser(dbg_interrupt,"rx interrupt off."); + if(priority&MSR_PRIORITY && (waiting_interrupts&MSR_PRIORITY)) + log_ser(dbg_interrupt,"msr interrupt off."); + if(priority&ERROR_PRIORITY && (waiting_interrupts&ERROR_PRIORITY)) + log_ser(dbg_interrupt,"error interrupt off."); #endif - - waiting_interrupts &= (~priority); ComputeInterrupts(); } @@ -299,30 +330,30 @@ void CSerial::ComputeInterrupts () { Bitu val = IER & waiting_interrupts; - if (val & ERROR_PRIORITY) ISR = ISR_ERROR_VAL; - else if (val & RX_PRIORITY) ISR = ISR_RX_VAL; - else if (val & TX_PRIORITY) ISR = ISR_TX_VAL; - else if (val & MSR_PRIORITY) ISR = ISR_MSR_VAL; + if (val & ERROR_PRIORITY) ISR = ISR_ERROR_VAL; + else if (val & TIMEOUT_PRIORITY) ISR = ISR_FIFOTIMEOUT_VAL; + else if (val & RX_PRIORITY) ISR = ISR_RX_VAL; + else if (val & TX_PRIORITY) ISR = ISR_TX_VAL; + else if (val & MSR_PRIORITY) ISR = ISR_MSR_VAL; else ISR = ISR_CLEAR_VAL; - if(val && !irq_active) { + if(val && !irq_active) + { irq_active=true; - PIC_ActivateIRQ(irq); - + if(op2) { + PIC_ActivateIRQ(irq); #if SERIAL_DEBUG - if(dbg_interrupt) - fprintf(debugfp,"%12.3f IRQ%d on.\r\n",PIC_FullIndex(),irq); + log_ser(dbg_interrupt,"IRQ%d on.",irq); #endif - } - - if(!val && irq_active) { + } + } else if((!val) && irq_active) { irq_active=false; - PIC_DeActivateIRQ(irq); - + if(op2) { + PIC_DeActivateIRQ(irq); #if SERIAL_DEBUG - if(dbg_interrupt) - fprintf(debugfp,"%12.3f IRQ%d off.\r\n",PIC_FullIndex(),irq); + log_ser(dbg_interrupt,"IRQ%d off.",irq); #endif + } } } @@ -330,108 +361,99 @@ void CSerial::ComputeInterrupts () { /* Can a byte be received? **/ /*****************************************************************************/ bool CSerial::CanReceiveByte() { - return (LSR & LSR_RX_DATA_READY_MASK) == 0; + return !rxfifo->isFull(); } /*****************************************************************************/ /* A byte was received **/ /*****************************************************************************/ -void CSerial::receiveByte (Bit8u data) { - +void CSerial::receiveByteEx (Bit8u data, Bit8u error) { + printf("%c",data); #if SERIAL_DEBUG - if(dbg_serialtraffic) - fprintf(debugfp,loopback_data<0x10? "%12.3f rx 0x%02x (%u)\r\n": - "%12.3f rx 0x%02x (%c)\r\n", - PIC_FullIndex(), data, data); + log_ser(dbg_serialtraffic,data<0x10 ? "\t\t\t\trx 0x%02x (%u)": + "\t\t\t\trx 0x%02x (%c)", data, data); #endif + if (!(rxfifo->addb(data))) { + // Overrun error ;o + error |= LSR_OVERRUN_ERROR_MASK; + } + removeEvent(SERIAL_RX_TIMEOUT_EVENT); + if(rxfifo->getUsage()==rx_interrupt_threshold) rise (RX_PRIORITY); + else setEvent(SERIAL_RX_TIMEOUT_EVENT,bytetime*4.0f); - if (LSR & LSR_RX_DATA_READY_MASK) { // Overrun error ;o + if(error) { + // A lot of UART chips generate a framing error too when receiving break + if(error&LSR_RX_BREAK_MASK) error |= LSR_FRAMING_ERROR_MASK; +#if SERIAL_DEBUG + log_ser(dbg_serialtraffic,"with error: framing=%d,overrun=%d,break=%d,parity=%d", + (error&LSR_FRAMING_ERROR_MASK)>0,(error&LSR_OVERRUN_ERROR_MASK)>0, + (error&LSR_RX_BREAK_MASK)>0,(error&LSR_PARITY_ERROR_MASK)>0); +#endif + if(FCR&FCR_ACTIVATE) { + // error and FIFO active + if(!errorfifo->isFull()) { + errors_in_fifo++; + errorfifo->addb(error); + } + else { + Bit8u toperror=errorfifo->getTop(); + if(!toperror) errors_in_fifo++; + errorfifo->addb(error|toperror); + } + if(errorfifo->probeByte()) { + // the next byte in the error fifo has an error + rise (ERROR_PRIORITY); + LSR |= error; + } + } else { + // error and FIFO inactive + rise (ERROR_PRIORITY); + LSR |= error; + }; + if(error&LSR_PARITY_ERROR_MASK) { + parityErrors++; + }; + if(error&LSR_OVERRUN_ERROR_MASK) { + overrunErrors++; + if(!GETFLAG(IF)) overrunIF0++; +#if SERIAL_DEBUG + log_ser(dbg_serialtraffic,"rx overrun (IF=%d)", GETFLAG(IF)>0); +#endif + }; + if(error&LSR_FRAMING_ERROR_MASK) { + framingErrors++; + } + if(error&LSR_RX_BREAK_MASK) { + breakErrors++; + } + // trigger status window error notification if(!errormsg_pending) { errormsg_pending=true; setEvent(SERIAL_ERRMSG_EVENT,1000); } - overrunErrors++; - Bitu iflag= GETFLAG(IF); - if(!iflag)overrunIF0++; - -#if SERIAL_DEBUG - if(dbg_serialtraffic) - fprintf(debugfp, "%12.3f rx overrun (IF=%d)\r\n", - PIC_FullIndex(), iflag); -#endif - - LSR |= LSR_OVERRUN_ERROR_MASK; - rise (ERROR_PRIORITY); } else { - RHR = data; - LSR |= LSR_RX_DATA_READY_MASK; - rise (RX_PRIORITY); + // no error + if(FCR&FCR_ACTIVATE) { + errorfifo->addb(error); + } } } -/*****************************************************************************/ -/* A line error was received **/ -/*****************************************************************************/ -void CSerial::receiveError (Bit8u errorword) { - - if(!errormsg_pending) { - errormsg_pending=true; - setEvent(SERIAL_ERRMSG_EVENT,1000); - } - if(errorword&LSR_PARITY_ERROR_MASK) { - parityErrors++; - -#if SERIAL_DEBUG - if(dbg_serialtraffic) - fprintf(debugfp, "%12.3f parity error\r\n", - PIC_FullIndex()); -#endif - - } - if(errorword&LSR_FRAMING_ERROR_MASK) { - framingErrors++; - -#if SERIAL_DEBUG - if(dbg_serialtraffic) - fprintf(debugfp, "%12.3f framing error\r\n", - PIC_FullIndex()); -#endif - - } - if(errorword&LSR_RX_BREAK_MASK) { - breakErrors++; - -#if SERIAL_DEBUG - if(dbg_serialtraffic) - fprintf(debugfp, "%12.3f break received\r\n", - PIC_FullIndex()); -#endif - - } - LSR |= errorword; - - rise (ERROR_PRIORITY); +void CSerial::receiveByte (Bit8u data) { + receiveByteEx(data,0); } /*****************************************************************************/ /* ByteTransmitting: Byte has made it from THR to TX. **/ /*****************************************************************************/ void CSerial::ByteTransmitting() { - switch(LSR&(LSR_TX_HOLDING_EMPTY_MASK|LSR_TX_EMPTY_MASK)) - { - case LSR_TX_HOLDING_EMPTY_MASK|LSR_TX_EMPTY_MASK: - // bad case there must have been one - case LSR_TX_HOLDING_EMPTY_MASK: - case LSR_TX_EMPTY_MASK: // holding full but workreg empty impossible - LOG_MSG("Internal error in serial port(1)(0x%x).",LSR); - break; - case 0: // THR is empty now. - LSR |= LSR_TX_HOLDING_EMPTY_MASK; - - // trigger interrupt - rise (TX_PRIORITY); - break; - } + if(sync_guardtime) { + //LOG_MSG("byte transmitting after guard"); + //if(txfifo->isEmpty()) LOG_MSG("Serial port: FIFO empty when it should not"); + sync_guardtime=false; + txfifo->getb(); + } //else LOG_MSG("byte transmitting"); + if(txfifo->isEmpty())rise (TX_PRIORITY); } @@ -439,39 +461,23 @@ void CSerial::ByteTransmitting() { /* ByteTransmitted: When a byte was sent, notify here. **/ /*****************************************************************************/ void CSerial::ByteTransmitted () { - switch(LSR&(LSR_TX_HOLDING_EMPTY_MASK|LSR_TX_EMPTY_MASK)) - { - case LSR_TX_HOLDING_EMPTY_MASK|LSR_TX_EMPTY_MASK: - // bad case there must have been one - case LSR_TX_EMPTY_MASK: // holding full but workreg empty impossible - LOG_MSG("Internal error in serial port(2)."); - break; - - case LSR_TX_HOLDING_EMPTY_MASK: // now both are empty - LSR |= LSR_TX_EMPTY_MASK; - break; + if(!txfifo->isEmpty()) { + // there is more data + Bit8u data = txfifo->getb(); +#if SERIAL_DEBUG + log_ser(dbg_serialtraffic,data<0x10? + "\t\t\t\t\ttx 0x%02x (%u) (from buffer)": + "\t\t\t\t\ttx 0x%02x (%c) (from buffer)",data,data); +#endif + if (loopback) setEvent(SERIAL_TX_LOOPBACK_EVENT, bytetime); + else transmitByte(data,false); + if(txfifo->isEmpty())rise (TX_PRIORITY); - case 0: // now one is empty, send the other one - LSR |= LSR_TX_HOLDING_EMPTY_MASK; - if (loopback) { - loopback_data=THR; - setEvent(SERIAL_TX_LOOPBACK_EVENT, bytetime); - } - else { - - #if SERIAL_DEBUG - if(dbg_serialtraffic) - fprintf(debugfp,THR<0x10? "%12.3f tx 0x%02x (%u) (from THR)\r\n": - "%12.3f tx 0x%02x (%c) (from THR)\r\n", - PIC_FullIndex(),THR, - THR); - #endif - - transmitByte(THR,false); - } - // It's ok here. - rise (TX_PRIORITY); - break; + } else { +#if SERIAL_DEBUG + log_ser(dbg_serialtraffic,"tx buffer empty."); +#endif + LSR |= LSR_TX_EMPTY_MASK; } } @@ -488,51 +494,43 @@ void CSerial::Write_THR (Bit8u data) { changeLineProperties(); } else { // write to THR - clear (TX_PRIORITY); + clear (TX_PRIORITY); - switch(LSR&(LSR_TX_HOLDING_EMPTY_MASK|LSR_TX_EMPTY_MASK)) - { - case 0: // both full - overflow -#if SERIAL_DEBUG - if(dbg_serialtraffic) fprintf(debugfp, "%12.3f tx overflow\r\n", - PIC_FullIndex()); -#endif - // overwrite THR - THR = data; - break; - - case LSR_TX_EMPTY_MASK: // holding full but workreg empty impossible - LOG_MSG("Internal error in serial port(3)."); - break; - - case LSR_TX_HOLDING_EMPTY_MASK: // now both are full - LSR &= (~LSR_TX_HOLDING_EMPTY_MASK); - THR = data; - break; - - case LSR_TX_HOLDING_EMPTY_MASK|LSR_TX_EMPTY_MASK: - // both are full until the first delay has passed - THR=data; - LSR &= (~LSR_TX_EMPTY_MASK); - LSR &= (~LSR_TX_HOLDING_EMPTY_MASK); - if(loopback) setEvent(SERIAL_THR_LOOPBACK_EVENT, bytetime/10); - else { + if((LSR & LSR_TX_EMPTY_MASK)) + { // we were idle before + //LOG_MSG("starting new transmit cycle"); + //if(sync_guardtime) LOG_MSG("Serial port internal error 1"); + //if(!(LSR & LSR_TX_EMPTY_MASK)) LOG_MSG("Serial port internal error 2"); + //if(txfifo->getUsage()) LOG_MSG("Serial port internal error 3"); + // need "warming up" time + sync_guardtime=true; + // block the fifo so it returns THR full (or not in case of FIFO on) + txfifo->addb(data); + // transmit shift register is busy + LSR &= (~LSR_TX_EMPTY_MASK); + if(loopback) setEvent(SERIAL_THR_LOOPBACK_EVENT, bytetime/10); + else { #if SERIAL_DEBUG - if(dbg_serialtraffic) - fprintf(debugfp,data<0x10? "%12.3f tx 0x%02x (%u)\r\n": - "%12.3f tx 0x%02x (%c)\r\n", - PIC_FullIndex(),data, - data); -#endif - - transmitByte (data,true); + log_ser(dbg_serialtraffic,data<0x10? + "\t\t\t\t\ttx 0x%02x (%u) [FIFO=%2d]": + "\t\t\t\t\ttx 0x%02x (%c) [FIFO=%2d]",data,data,txfifo->getUsage()); +#endif + transmitByte (data,true); + } + } else { + // shift register is transmitting + if(!txfifo->addb(data)) { + // TX overflow +#if SERIAL_DEBUG + log_ser(dbg_serialtraffic,"tx overflow"); +#endif + txOverrunErrors++; + if(!errormsg_pending) { + errormsg_pending=true; + setEvent(SERIAL_ERRMSG_EVENT,1000); } - - // triggered - // when holding gets empty - // rise (TX_PRIORITY); - break; + } } } } @@ -545,9 +543,26 @@ Bitu CSerial::Read_RHR () { // 0-7 received data if ((LCR & LCR_DIVISOR_Enable_MASK)) return baud_divider&0xff; else { - clear (RX_PRIORITY); - LSR &= (~LSR_RX_DATA_READY_MASK); - return RHR; + Bit8u data=rxfifo->getb(); + if(FCR&FCR_ACTIVATE) { + Bit8u error=errorfifo->getb(); + if(error) errors_in_fifo--; + // new error + if(!rxfifo->isEmpty()) { + error=errorfifo->probeByte(); + if(error) { + LSR |= error; + rise(ERROR_PRIORITY); + } + } + } + // Reading RHR resets the FIFO timeout + clear (TIMEOUT_PRIORITY); + // RX int. is cleared if the buffer holds less data than the threshold + if(rxfifo->getUsage()isEmpty()) setEvent(SERIAL_RX_TIMEOUT_EVENT,bytetime*4.0f); + return data; } } @@ -564,7 +579,7 @@ Bitu CSerial::Read_IER () { // 4-7 0 if (LCR & LCR_DIVISOR_Enable_MASK) return baud_divider>>8; - else return IER; + else return IER&0x0f; } void CSerial::Write_IER (Bit8u data) { @@ -573,11 +588,12 @@ void CSerial::Write_IER (Bit8u data) { baud_divider |= ((Bit16u)data)<<8; changeLineProperties(); } else { - - IER = data&0xF; - if ((LSR & LSR_TX_HOLDING_EMPTY_MASK) && (IER&TX_PRIORITY)) + // Retrigger TX interrupt + if (txfifo->isEmpty()&& (data&TX_PRIORITY)) waiting_interrupts |= TX_PRIORITY; + IER = data&0xF; + if((FCR&FCR_ACTIVATE)&&data&RX_PRIORITY) IER |= TIMEOUT_PRIORITY; ComputeInterrupts(); } } @@ -593,6 +609,7 @@ Bitu CSerial::Read_ISR () { // 1-3 identification // 011 LSR // 010 RXRDY + // 110 RX_TIMEOUT // 001 TXRDY // 000 MSR // 4-7 0 @@ -601,14 +618,44 @@ Bitu CSerial::Read_ISR () { Bit8u retval = ISR; // clear changes ISR!! mean.. - if(ISR==ISR_TX_VAL) clear (TX_PRIORITY); + if(ISR==ISR_TX_VAL) clear(TX_PRIORITY); + if(FCR&FCR_ACTIVATE) retval |= FIFO_STATUS_ACTIVE; + return retval; } +#define BIT_CHANGE_H(oldv,newv,bitmask) (!(oldv&bitmask) && (newv&bitmask)) +#define BIT_CHANGE_L(oldv,newv,bitmask) ((oldv&bitmask) && !(newv&bitmask)) + void CSerial::Write_FCR (Bit8u data) { - if((!fifo_warn) && (data&0x1)) { - fifo_warn=true; - LOG_MSG("Serial%d: Warning: Tried to activate FIFO.",COMNUMBER); + if(BIT_CHANGE_H(FCR,data,FCR_ACTIVATE)) { + // FIFO was switched on + errors_in_fifo=0; // should already be 0 + errorfifo->setSize(fifosize); + rxfifo->setSize(fifosize); + txfifo->setSize(fifosize); + } else if(BIT_CHANGE_L(FCR,data,FCR_ACTIVATE)) { + // FIFO was switched off + errors_in_fifo=0; + errorfifo->setSize(1); + rxfifo->setSize(1); + txfifo->setSize(1); + rx_interrupt_threshold=1; + } + FCR=data&0xCF; + if(FCR&FCR_CLEAR_RX) { + errors_in_fifo=0; + errorfifo->clear(); + rxfifo->clear(); + } + if(FCR&FCR_CLEAR_TX) txfifo->clear(); + if(FCR&FCR_ACTIVATE) { + switch(FCR>>6) { + case 0: rx_interrupt_threshold=1; break; + case 1: rx_interrupt_threshold=4; break; + case 2: rx_interrupt_threshold=8; break; + case 3: rx_interrupt_threshold=14; break; + } } } @@ -643,10 +690,8 @@ void CSerial::Write_LCR (Bit8u data) { // TODO: set loopback break event to reveiveError after } #if SERIAL_DEBUG - if(dbg_serialtraffic) - fprintf(debugfp,((LCR & LCR_BREAK_MASK)!=0)? - "%12.3f break on.\r\n": - "%12.3f break off.\r\n", PIC_FullIndex()); + log_ser(dbg_serialtraffic,((LCR & LCR_BREAK_MASK)!=0) ? + "break on.":"break off."); #endif } } @@ -675,7 +720,7 @@ Bitu CSerial::Read_MCR () { void CSerial::Write_MCR (Bit8u data) { // WARNING: At the time setRTSDTR is called rts and dsr members are still wrong. - + if(data&FIFO_FLOWCONTROL) LOG_MSG("Warning: tried to activate hardware handshake."); bool temp_dtr = data & MCR_DTR_MASK? true:false; bool temp_rts = data & MCR_RTS_MASK? true:false; bool temp_op1 = data & MCR_OP1_MASK? true:false; @@ -718,34 +763,34 @@ void CSerial::Write_MCR (Bit8u data) { // both difference #if SERIAL_DEBUG - if(dbg_modemcontrol) - { - fprintf(debugfp,temp_rts?"%12.3f RTS on.\r\n": - "%12.3f RTS off.\r\n", PIC_FullIndex()); - fprintf(debugfp,temp_dtr?"%12.3f DTR on.\r\n": - "%12.3f DTR off.\r\n", PIC_FullIndex()); - } + log_ser(dbg_modemcontrol,"RTS %x.",temp_rts); + log_ser(dbg_modemcontrol,"DTR %x.",temp_dtr); #endif setRTSDTR(temp_rts, temp_dtr); } else { // only RTS #if SERIAL_DEBUG - if(dbg_modemcontrol) - fprintf(debugfp,temp_rts?"%12.3f RTS on.\r\n":"%12.3f RTS off.\r\n", PIC_FullIndex()); + log_ser(dbg_modemcontrol,"RTS %x.",temp_rts); #endif - setRTS(temp_rts); } } else if(temp_dtr!=dtr) { // only DTR #if SERIAL_DEBUG - if(dbg_modemcontrol) - fprintf(debugfp,temp_dtr?"%12.3f DTR on.\r\n":"%12.3f DTR off.\r\n", PIC_FullIndex()); + log_ser(dbg_modemcontrol,"%DTR %x.",temp_dtr); #endif setDTR(temp_dtr); } } + // interrupt logic: if OP2 is 0, the IRQ line is tristated (pulled high) + if((!op2) && temp_op2) { + // irq has been enabled (tristate high -> irq level) + if(!irq_active) PIC_DeActivateIRQ(irq); + } else if(op2 && (!temp_op2)) { + if(!irq_active) PIC_ActivateIRQ(irq); + } + dtr=temp_dtr; rts=temp_rts; op1=temp_op1; @@ -761,7 +806,10 @@ void CSerial::Write_MCR (Bit8u data) { // - event from real serial port // - loopback Bitu CSerial::Read_LSR () { - Bitu retval = LSR; + Bitu retval = LSR & (LSR_ERROR_MASK|LSR_TX_EMPTY_MASK); + if(txfifo->isEmpty()) retval |= LSR_TX_HOLDING_EMPTY_MASK; + if(!(rxfifo->isEmpty()))retval |= LSR_RX_DATA_READY_MASK; + if(errors_in_fifo) retval |= FIFO_ERROR; LSR &= (~LSR_ERROR_MASK); // clear error bits on read clear (ERROR_PRIORITY); return retval; @@ -872,8 +920,7 @@ void CSerial::setRI (bool value) { if (value != ri) { #if SERIAL_DEBUG - if(dbg_modemcontrol) - fprintf(debugfp,value?"%12.3f RI on.\r\n":"%12.3f RI off.\r\n", PIC_FullIndex()); + log_ser(dbg_modemcontrol,"%RI %x.",value); #endif // don't change delta when in loopback mode ri=value; @@ -887,8 +934,7 @@ void CSerial::setRI (bool value) { void CSerial::setDSR (bool value) { if (value != dsr) { #if SERIAL_DEBUG - if(dbg_modemcontrol) - fprintf(debugfp,value?"%12.3f DSR on.\r\n":"%12.3f DSR off.\r\n", PIC_FullIndex()); + log_ser(dbg_modemcontrol,"DSR %x.",value); #endif // don't change delta when in loopback mode dsr=value; @@ -902,8 +948,7 @@ void CSerial::setDSR (bool value) { void CSerial::setCD (bool value) { if (value != cd) { #if SERIAL_DEBUG - if(dbg_modemcontrol) - fprintf(debugfp,value?"%12.3f CD on.\r\n":"%12.3f CD off.\r\n", PIC_FullIndex()); + log_ser(dbg_modemcontrol,"CD %x.",value); #endif // don't change delta when in loopback mode cd=value; @@ -917,8 +962,7 @@ void CSerial::setCD (bool value) { void CSerial::setCTS (bool value) { if (value != cts) { #if SERIAL_DEBUG - if(dbg_modemcontrol) - fprintf(debugfp,value?"%12.3f CTS on.\r\n":"%12.3f CTS off.\r\n", PIC_FullIndex()); + log_ser(dbg_modemcontrol,"CTS %x.",value); #endif // don't change delta when in loopback mode cts=value; @@ -945,8 +989,6 @@ void CSerial::Init_Registers () { Bit8u lcrresult = 0; Bit16u baudresult = 0; - RHR = 0; - THR = 0; IER = 0; ISR = 0x1; LCR = 0; @@ -957,6 +999,10 @@ void CSerial::Init_Registers () { op1=true; op2=true; + sync_guardtime=false; + FCR=0xff; + Write_FCR(0x00); + LSR = 0x60; d_cts = true; @@ -1023,6 +1069,12 @@ void CSerial::Init_Registers () { } CSerial::CSerial(Bitu id, CommandLine* cmd) { + idnumber=id; + Bit16u base = serial_baseaddr[id]; + + irq = serial_defaultirq[id]; + getBituSubstring("irq:",&irq, cmd); + if (irq < 2 || irq > 15) irq = serial_defaultirq[id]; #if SERIAL_DEBUG dbg_serialtraffic = cmd->FindExist("dbgtr", false); @@ -1030,44 +1082,55 @@ CSerial::CSerial(Bitu id, CommandLine* cmd) { dbg_register = cmd->FindExist("dbgreg", false); dbg_interrupt = cmd->FindExist("dbgirq", false); dbg_aux = cmd->FindExist("dbgaux", false); + + if(cmd->FindExist("dbgall", false)) { + dbg_serialtraffic= + dbg_modemcontrol= + dbg_register= + dbg_interrupt= + dbg_aux= true; + } if(dbg_serialtraffic|dbg_modemcontrol|dbg_register|dbg_interrupt|dbg_aux) debugfp=OpenCaptureFile("serlog",".serlog.txt"); else debugfp=0; + if(debugfp == 0) { + dbg_serialtraffic= + dbg_modemcontrol= + dbg_register= + dbg_interrupt= + dbg_aux= false; + } else { + std::string cleft; + cmd->GetStringRemain(cleft); + + log_ser(true,"Serial%d: BASE %3x, IRQ %d, initstring \"%s\"\r\n\r\n", + COMNUMBER,base,irq,cleft.c_str()); + } #endif + fifosize=16; + errorfifo = new MyFifo(fifosize); + rxfifo = new MyFifo(fifosize); + txfifo = new MyFifo(fifosize); - - idnumber=id; mydosdevice=new device_COM(this); DOS_AddDevice(mydosdevice); - Bit16u base = serial_baseaddr[id]; - fifo_warn=false; errormsg_pending=false; framingErrors=0; parityErrors=0; overrunErrors=0; + txOverrunErrors=0; overrunIF0=0; breakErrors=0; - // find the IRQ - irq = serial_defaultirq[id]; - getBituSubstring("irq:",&irq, cmd); - if (irq < 2 || irq > 15) irq = serial_defaultirq[id]; - - for (Bitu i = 0; i <= 7; i++) { WriteHandler[i].Install (i + base, SERIAL_Write, IO_MB); ReadHandler[i].Install (i + base, SERIAL_Read, IO_MB); } - -#if SERIAL_DEBUG - if(debugfp) fprintf(debugfp,"COM%d: BASE %3x, IRQ %d\r\n\r\n", - COMNUMBER,base,irq); -#endif } bool CSerial::getBituSubstring(const char* name,Bitu* data, CommandLine* cmd) { @@ -1082,19 +1145,16 @@ CSerial::~CSerial(void) { DOS_DelDevice(mydosdevice); for(Bitu i = 0; i <= SERIAL_BASE_EVENT_COUNT; i++) removeEvent(i); -} +}; bool CSerial::Getchar(Bit8u* data, Bit8u* lsr, bool wait_dsr, Bitu timeout) { - double starttime=PIC_FullIndex(); - // wait for it to become empty // wait for DSR on if(wait_dsr) { while((!(Read_MSR()&0x20))&&(starttime>PIC_FullIndex()-timeout)) CALLBACK_Idle(); if(!(starttime>PIC_FullIndex()-timeout)) { - #if SERIAL_DEBUG -if(dbg_aux) - fprintf(debugfp,"%12.3f Getchar status timeout: MSR 0x%x\r\n", PIC_FullIndex(),Read_MSR()); +#if SERIAL_DEBUG + log_ser(dbg_aux,"Getchar status timeout: MSR 0x%x",Read_MSR()); #endif return false; } @@ -1104,21 +1164,16 @@ if(dbg_aux) CALLBACK_Idle(); if(!(starttime>PIC_FullIndex()-timeout)) { - #if SERIAL_DEBUG -if(dbg_aux) - fprintf(debugfp,"%12.3f Getchar data timeout: MSR 0x%x\r\n", PIC_FullIndex(),Read_MSR()); +#if SERIAL_DEBUG + log_ser(dbg_aux,"Getchar data timeout: MSR 0x%x",Read_MSR()); #endif return false; } - - *data=Read_RHR(); #if SERIAL_DEBUG - if(dbg_aux) - fprintf(debugfp,"%12.3f API read success: 0x%x\r\n", PIC_FullIndex(),*data); + log_ser(dbg_aux,"Getchar read 0x%x",*data); #endif - return true; } @@ -1126,9 +1181,8 @@ if(dbg_aux) bool CSerial::Putchar(Bit8u data, bool wait_dsr, bool wait_cts, Bitu timeout) { double starttime=PIC_FullIndex(); - //Bit16u starttime= // wait for it to become empty - while(!(LSR&0x20)) { + while(!(Read_LSR()&0x20)) { CALLBACK_Idle(); } // wait for DSR+CTS on @@ -1142,13 +1196,10 @@ bool CSerial::Putchar(Bit8u data, bool wait_dsr, bool wait_cts, Bitu timeout) { } else if(wait_cts) { while(!(Read_MSR()&0x10)&&(starttime>PIC_FullIndex()-timeout)) CALLBACK_Idle(); - } if(!(starttime>PIC_FullIndex()-timeout)) { #if SERIAL_DEBUG - if(dbg_aux) - fprintf(debugfp,"%12.3f Putchar timeout: MSR 0x%x\r\n", - PIC_FullIndex(),Read_MSR()); + log_ser(dbg_aux,"Putchar timeout: MSR 0x%x",Read_MSR()); #endif return false; } @@ -1156,8 +1207,7 @@ bool CSerial::Putchar(Bit8u data, bool wait_dsr, bool wait_cts, Bitu timeout) { Write_THR(data); #if SERIAL_DEBUG - if(dbg_aux) - fprintf(debugfp,"%12.3f API write success: 0x%x\r\n", PIC_FullIndex(),data); + log_ser(dbg_aux,"Putchar 0x%x",data); #endif return true; diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index f30d746b..7cd1e792 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.h,v 1.10 2009-05-27 09:15:42 qbix79 Exp $ */ +/* $Id: softmodem.h,v 1.11 2009-09-25 23:40:47 h-a-l-9000 Exp $ */ #ifndef DOSBOX_SERIALMODEM_H #define DOSBOX_SERIALMODEM_H @@ -92,7 +92,7 @@ public: static Bits lcount=0; if (lcount<1000) { lcount++; - LOG_MSG("MODEM: FIFO Overflow! (adds len %d)",_len); + LOG_MSG("MODEM: FIFO Overflow! (adds len %u)",_len); } return; } diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 43a487d1..5a36f2ef 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -309,10 +309,10 @@ RelativePath="..\src\cpu\core_dynrec\operators.h"> + RelativePath="..\src\cpu\core_dynrec\risc_x64.h"> + RelativePath="..\src\cpu\core_dynrec\risc_x86.h"> @@ -567,28 +567,16 @@ Name="serialport" Filter=""> - - - + RelativePath="..\src\hardware\serialport\directserial.cpp"> + RelativePath="..\src\hardware\serialport\directserial.h"> + RelativePath="..\src\hardware\serialport\libserial.cpp"> - - - - + RelativePath="..\src\hardware\serialport\libserial.h"> @@ -622,6 +610,9 @@ + + @@ -649,9 +640,6 @@ - - Date: Sat, 26 Sep 2009 09:15:19 +0000 Subject: [PATCH 3384/4131] It's 2009 already Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3473 --- src/hardware/serialport/directserial.cpp | 4 ++-- src/hardware/serialport/directserial.h | 4 ++-- src/hardware/serialport/libserial.cpp | 4 ++-- src/hardware/serialport/libserial.h | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hardware/serialport/directserial.cpp b/src/hardware/serialport/directserial.cpp index 1e591264..8d8db430 100644 --- a/src/hardware/serialport/directserial.cpp +++ b/src/hardware/serialport/directserial.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial.cpp,v 1.1 2009-09-25 23:40:47 h-a-l-9000 Exp $ */ +/* $Id: directserial.cpp,v 1.2 2009-09-26 09:15:19 h-a-l-9000 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/directserial.h b/src/hardware/serialport/directserial.h index e5efe880..d8285ea4 100644 --- a/src/hardware/serialport/directserial.h +++ b/src/hardware/serialport/directserial.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial.h,v 1.1 2009-09-25 23:40:47 h-a-l-9000 Exp $ */ +/* $Id: directserial.h,v 1.2 2009-09-26 09:15:19 h-a-l-9000 Exp $ */ // include guard #ifndef DOSBOX_DIRECTSERIAL_WIN32_H diff --git a/src/hardware/serialport/libserial.cpp b/src/hardware/serialport/libserial.cpp index 7ce82163..fe8e7ecb 100644 --- a/src/hardware/serialport/libserial.cpp +++ b/src/hardware/serialport/libserial.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: libserial.cpp,v 1.1 2009-09-25 23:40:47 h-a-l-9000 Exp $ */ +/* $Id: libserial.cpp,v 1.2 2009-09-26 09:15:19 h-a-l-9000 Exp $ */ #include "libserial.h" diff --git a/src/hardware/serialport/libserial.h b/src/hardware/serialport/libserial.h index 25981a49..f3420c84 100644 --- a/src/hardware/serialport/libserial.h +++ b/src/hardware/serialport/libserial.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: libserial.h,v 1.1 2009-09-25 23:40:47 h-a-l-9000 Exp $ */ +/* $Id: libserial.h,v 1.2 2009-09-26 09:15:19 h-a-l-9000 Exp $ */ typedef struct _COMPORT *COMPORT; From a9733cefafe8f523708c65d2337861f128c6d112 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Tue, 29 Sep 2009 23:08:22 +0000 Subject: [PATCH 3385/4131] Fix crash (buffer overflow) in case of socket error Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3474 --- src/hardware/serialport/misc_util.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/serialport/misc_util.cpp b/src/hardware/serialport/misc_util.cpp index 6ba488d5..6f01d9c7 100644 --- a/src/hardware/serialport/misc_util.cpp +++ b/src/hardware/serialport/misc_util.cpp @@ -182,7 +182,7 @@ bool TCPClientSocket::GetRemoteAddressString(Bit8u* buffer) { bool TCPClientSocket::ReceiveArray(Bit8u* data, Bitu* size) { if(SDLNet_CheckSockets(listensocketset,0)) { - Bitu retval = SDLNet_TCP_Recv(mysock, data, *size); + Bits retval = SDLNet_TCP_Recv(mysock, data, *size); if(retval<1) { isopen=false; *size=0; From 42d8d2e9629ca74b3d4f0d2514b072cbad49cf67 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Thu, 1 Oct 2009 17:25:28 +0000 Subject: [PATCH 3386/4131] Remove debugging aid that accidentally slipped in Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3475 --- src/hardware/serialport/serialport.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index 84b4b330..16fe4a8d 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.cpp,v 1.13 2009-09-25 23:40:47 h-a-l-9000 Exp $ */ +/* $Id: serialport.cpp,v 1.14 2009-10-01 17:25:28 h-a-l-9000 Exp $ */ #include #include @@ -368,7 +368,6 @@ bool CSerial::CanReceiveByte() { /* A byte was received **/ /*****************************************************************************/ void CSerial::receiveByteEx (Bit8u data, Bit8u error) { - printf("%c",data); #if SERIAL_DEBUG log_ser(dbg_serialtraffic,data<0x10 ? "\t\t\t\trx 0x%02x (%u)": "\t\t\t\trx 0x%02x (%c)", data, data); From 1c410c147e9783e2bb74d812891ecefe636601e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 4 Oct 2009 14:28:07 +0000 Subject: [PATCH 3387/4131] use calling application's code segment rather than psp value for some old-style (dos 1.0) terminate functions (ripsaw, fixes fortune teller) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3476 --- include/dos_inc.h | 4 ++-- src/dos/dos.cpp | 27 ++++++++++----------------- src/dos/dos_execute.cpp | 18 ++++++++---------- 3 files changed, 20 insertions(+), 29 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 97deee81..a51085cb 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.81 2009-07-09 20:06:56 c2woody Exp $ */ +/* $Id: dos_inc.h,v 1.82 2009-10-04 14:28:06 c2woody Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -154,7 +154,7 @@ void DOS_SetupDevices(void); bool DOS_NewPSP(Bit16u pspseg,Bit16u size); bool DOS_ChildPSP(Bit16u pspseg,Bit16u size); bool DOS_Execute(char * name,PhysPt block,Bit8u flags); -bool DOS_Terminate(bool tsr,Bit8u exitcode); +void DOS_Terminate(Bit16u pspseg,bool tsr,Bit8u exitcode); /* Memory Handling Routines */ void DOS_SetupMemory(void); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 2c5ed763..ce723fac 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.119 2009-07-31 16:41:37 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.120 2009-10-04 14:28:07 c2woody Exp $ */ #include #include @@ -70,6 +70,9 @@ static Bitu DOS_21Handler(void) { char name1[DOSNAMEBUF+2+DOS_NAMELENGTH_ASCII]; char name2[DOSNAMEBUF+2+DOS_NAMELENGTH_ASCII]; switch (reg_ah) { + case 0x00: /* Terminate Program */ + DOS_Terminate(mem_readw(SegPhys(ss)+reg_sp+2),false,0); + break; case 0x01: /* Read character from STDIN, with echo */ { Bit8u c;Bit16u n=1; @@ -390,11 +393,9 @@ static Bitu DOS_21Handler(void) { reg_cx=0x0000; break; case 0x31: /* Terminate and stay resident */ - //TODO First get normal files executing // Important: This service does not set the carry flag! DOS_ResizeMemory(dos.psp(),®_dx); - DOS_Terminate(true,reg_al); - dos.return_mode=RETURN_TSR; + DOS_Terminate(dos.psp(),true,reg_al); break; case 0x1f: /* Get drive parameter block for default drive */ case 0x32: /* Get drive parameter block for specific drive */ @@ -708,18 +709,9 @@ static Bitu DOS_21Handler(void) { } break; //TODO Check for use of execution state AL=5 - case 0x00: - reg_ax=0x4c00; /* Terminate Program */ case 0x4c: /* EXIT Terminate with return code */ - { - if (DOS_Terminate(false,reg_al)) { - /* This can't ever return false normally */ - } else { - reg_ax=dos.errorcode; - CALLBACK_SCF(true); - } - break; - } + DOS_Terminate(dos.psp(),false,reg_al); + break; case 0x4d: /* Get Return code */ reg_al=dos.return_code;/* Officially read from SDA and clear when read */ reg_ah=dos.return_mode; @@ -1051,7 +1043,7 @@ static Bitu DOS_21Handler(void) { static Bitu DOS_20Handler(void) { - reg_ax=0x4c00; + reg_ah=0x00; DOS_21Handler(); return CBRET_NONE; } @@ -1059,7 +1051,8 @@ static Bitu DOS_20Handler(void) { static Bitu DOS_27Handler(void) { // Terminate & stay resident Bit16u para = (reg_dx/16)+((reg_dx % 16)>0); - if (DOS_ResizeMemory(dos.psp(),¶)) DOS_Terminate(true,0); + Bit16u psp = mem_readw(SegPhys(ss)+reg_sp+2); + if (DOS_ResizeMemory(psp,¶)) DOS_Terminate(psp,true,0); return CBRET_NONE; } diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 80436386..bf81479a 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.67 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: dos_execute.cpp,v 1.68 2009-10-04 14:28:07 c2woody Exp $ */ #include #include @@ -104,15 +104,13 @@ void DOS_UpdatePSPName(void) { GFX_SetTitle(-1,-1,false); } -bool DOS_Terminate(bool tsr,Bit8u exitcode) { +void DOS_Terminate(Bit16u pspseg,bool tsr,Bit8u exitcode) { dos.return_code=exitcode; - dos.return_mode=RETURN_EXIT; + dos.return_mode=(tsr)?RETURN_TSR:RETURN_EXIT; - Bit16u mempsp = dos.psp(); - - DOS_PSP curpsp(mempsp); - if (mempsp==curpsp.GetParent()) return true; + DOS_PSP curpsp(pspseg); + if (pspseg==curpsp.GetParent()) return; /* Free Files owned by process */ if (!tsr) curpsp.CloseFiles(); @@ -136,10 +134,10 @@ bool DOS_Terminate(bool tsr,Bit8u exitcode) { interrupts enabled, test flags cleared */ mem_writew(SegPhys(ss)+reg_sp+4,0x7202); // Free memory owned by process - if (!tsr) DOS_FreeProcessMemory(mempsp); + if (!tsr) DOS_FreeProcessMemory(pspseg); DOS_UpdatePSPName(); - if ((!(CPU_AutoDetermineMode>>CPU_AUTODETERMINE_SHIFT)) || (cpu.pmode)) return true; + if ((!(CPU_AutoDetermineMode>>CPU_AUTODETERMINE_SHIFT)) || (cpu.pmode)) return; CPU_AutoDetermineMode>>=CPU_AUTODETERMINE_SHIFT; if (CPU_AutoDetermineMode&CPU_AUTODETERMINE_CYCLES) { @@ -159,7 +157,7 @@ bool DOS_Terminate(bool tsr,Bit8u exitcode) { } #endif - return true; + return; } static bool MakeEnv(char * name,Bit16u * segment) { From b8138ed47749fd8d51559fbbd3fa2a88a1d2f17f Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 4 Oct 2009 20:57:40 +0000 Subject: [PATCH 3388/4131] - make the modem command parsing code more readable - add dummy \K modem command - improve timing when receiving data so it can go faster Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3477 --- src/hardware/serialport/softmodem.cpp | 535 +++++++++++++------------- src/hardware/serialport/softmodem.h | 5 +- 2 files changed, 279 insertions(+), 261 deletions(-) diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index 7651dac2..0dd33c25 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.cpp,v 1.11 2009-05-27 09:15:42 qbix79 Exp $ */ +/* $Id: softmodem.cpp,v 1.12 2009-10-04 20:57:40 h-a-l-9000 Exp $ */ #include "dosbox.h" @@ -77,41 +77,47 @@ CSerialModem::~CSerialModem() { } void CSerialModem::handleUpperEvent(Bit16u type) { - switch(type) - { - case SERIAL_RX_EVENT: - { - break; - } - case MODEM_TX_EVENT: - { - if(tqueue->left()) { - tqueue->addb(waiting_tx_character); - if(tqueue->left() < 2) { - CSerial::setCTS(false); - } - } else { - static Bits lcount=0; - if (lcount<1000) { - lcount++; - LOG_MSG("MODEM: TX Buffer overflow!"); - } + switch (type) { + case SERIAL_RX_EVENT: { + // check for bytes to be sent to port + if(CSerial::CanReceiveByte()) + if(rqueue->inuse() && (CSerial::getRTS()||(flowcontrol!=3))) { + Bit8u rbyte = rqueue->getb(); + //LOG_MSG("Modem: sending byte %2x back to UART3",rbyte); + CSerial::receiveByte(rbyte); + } + if(CSerial::CanReceiveByte()) setEvent(SERIAL_RX_EVENT, bytetime*0.98f); + break; + } + case MODEM_TX_EVENT: { + if (tqueue->left()) { + tqueue->addb(waiting_tx_character); + if (tqueue->left() < 2) { + CSerial::setCTS(false); + } + } else { + static Bits lcount=0; + if (lcount<1000) { + lcount++; + LOG_MSG("MODEM: TX Buffer overflow!"); } - ByteTransmitted(); - - break; } - case SERIAL_POLLING_EVENT: - { - Timer2(); - setEvent(SERIAL_POLLING_EVENT,1); - break; + ByteTransmitted(); + break; + } + case SERIAL_POLLING_EVENT: { + if (rqueue->inuse()) { + removeEvent(SERIAL_RX_EVENT); + setEvent(SERIAL_RX_EVENT, (float)0.01); } + Timer2(); + setEvent(SERIAL_POLLING_EVENT,1); + break; + } - case MODEM_RING_EVENT: - { - break; - } + case MODEM_RING_EVENT: { + break; + } } } @@ -216,6 +222,12 @@ Bitu CSerialModem::ScanNumber(char * & scan) { return ret; } +char CSerialModem::GetChar(char * & scan) { + char ch = *scan; + scan++; + return ch; +} + void CSerialModem::Reset(){ EnterIdleState(); cmdpos = 0; @@ -300,227 +312,238 @@ void CSerialModem::DoCommand() { cmdpos = 0; //Reset for next command upcase(cmdbuf); LOG_MSG("Command sent to modem: ->%s<-\n", cmdbuf); - /* Check for empty line, stops dialing and autoanswer */ - if (!cmdbuf[0]) { - reg[0]=0; // autoanswer off - return; - // } - //else { - //MIXER_Enable(mhd.chan,false); - // dialing = false; - // SendRes(ResNOCARRIER); - // goto ret_none; - // } - } - /* AT command set interpretation */ + /* Check for empty line, stops dialing and autoanswer */ + if (!cmdbuf[0]) { + reg[0]=0; // autoanswer off + return; + } + //else { + //MIXER_Enable(mhd.chan,false); + // dialing = false; + // SendRes(ResNOCARRIER); + // goto ret_none; + //} + /* AT command set interpretation */ - if ((cmdbuf[0] != 'A') || (cmdbuf[1] != 'T')) { - SendRes(ResERROR); - return; - } - - if (strstr(cmdbuf,"NET0")) { - telnetmode = false; - SendRes(ResOK); - return; - } - else if (strstr(cmdbuf,"NET1")) { - telnetmode = true; - SendRes(ResOK); - return; - } - - char * scanbuf; - scanbuf=&cmdbuf[2]; - char chr; - Bitu num; - while (chr=*scanbuf++) { - switch (chr) { - case 'D': // Dial - { - char * foundstr=&scanbuf[0]; - if (*foundstr=='T' || *foundstr=='P') foundstr++; - // Small protection against empty line and long string - if ((!foundstr[0]) || (strlen(foundstr)>100)) { - SendRes(ResERROR); - return; - } - char* helper; - // scan for and remove spaces; weird bug: with leading spaces in the string, - // SDLNet_ResolveHost will return no error but not work anyway (win) - while(foundstr[0]==' ') foundstr++; - helper=foundstr; - helper+=strlen(foundstr); - while(helper[0]==' ') { - helper[0]=0; - helper--; - } - if (strlen(foundstr) >= 12) { - // Check if supplied parameter only consists of digits - bool isNum = true; - for (Bitu i=0; i '9') - isNum = false; - if (isNum) { - // Parameter is a number with at least 12 digits => this cannot - // be a valid IP/name - // Transform by adding dots - char buffer[128]; - Bitu j = 0; - for (Bitu i=0; i12) - buffer[j++] = ':'; - } - buffer[j] = 0; - foundstr = buffer; - } - } - Dial(foundstr); - return; - } - case 'I': //Some strings about firmware - switch (num=ScanNumber(scanbuf)) { - case 3:SendLine("DosBox Emulated Modem Firmware V1.00");break; - case 4:SendLine("Modem compiled for DosBox version " VERSION);break; - };break; - case 'E': //Echo on/off - switch (num=ScanNumber(scanbuf)) { - case 0:echo = false;break; - case 1:echo = true;break; - };break; - case 'V': - switch (num=ScanNumber(scanbuf)) { - case 0:numericresponse = true;break; - case 1:numericresponse = false;break; - };break; - case 'H': //Hang up - switch (num=ScanNumber(scanbuf)) { - case 0: - if (connected) { - SendRes(ResNOCARRIER); - EnterIdleState(); - return; - } - //Else return ok - };break; - case 'O': //Return to data mode - switch (num=ScanNumber(scanbuf)) - { - case 0: - if (clientsocket) { - commandmode = false; - return; - } else { - SendRes(ResERROR); - return; - } - };break; - case 'T': //Tone Dial - case 'P': //Pulse Dial - break; - case 'M': //Monitor - case 'L': //Volume - ScanNumber(scanbuf); - break; - case 'A': //Answer call - if (waitingclientsocket) { - AcceptIncomingCall(); - } else { - SendRes(ResERROR); - return; - } - return; - case 'Z': //Reset and load profiles - { - // scan the number away, if any - ScanNumber(scanbuf); - if (clientsocket/*socket*/) SendRes(ResNOCARRIER); - Reset(); - break; - } - case ' ': //Space just skip - break; - case 'Q': // Response options - { // 0 = all on, 1 = all off, - // 2 = no ring and no connect/carrier in answermode - Bitu val = ScanNumber(scanbuf); - if(!(val>2)) { - doresponse=val; - break; - } else { - SendRes(ResERROR); - return; - } - } - case 'S': //Registers - { - Bitu index=ScanNumber(scanbuf); - if(index>=SREGS) { - SendRes(ResERROR); - return; //goto ret_none; - } - - while(scanbuf[0]==' ') scanbuf++; // skip spaces - - if(scanbuf[0]=='=') { // set register - scanbuf++; - while(scanbuf[0]==' ') scanbuf++; // skip spaces - Bitu val = ScanNumber(scanbuf); - reg[index]=val; - break; - } - else if(scanbuf[0]=='?') { // get register - SendNumber(reg[index]); - scanbuf++; - break; - } - //else LOG_MSG("print reg %d with %d",index,reg[index]); - } - break; - case '&': - { - if(scanbuf[0]!=0) { - char ch = scanbuf[0]; - scanbuf++; - switch(ch) { - case 'K': - { - Bitu val = ScanNumber(scanbuf); - if(val<5) flowcontrol=val; - else { - SendRes(ResERROR); - return; - } - break; - } - default: - { - scanbuf++; - LOG_MSG("Modem: Unhandled command: &%c%d",ch,ScanNumber(scanbuf)); - break; - } - } - } else { - SendRes(ResERROR); - return; - } - } - break; - - default: - LOG_MSG("Modem: Unhandled command: %c%d",chr,ScanNumber(scanbuf)); - } - } - + if ((cmdbuf[0] != 'A') || (cmdbuf[1] != 'T')) { + SendRes(ResERROR); + return; + } + if (strstr(cmdbuf,"NET0")) { + telnetmode = false; SendRes(ResOK); return; } + else if (strstr(cmdbuf,"NET1")) { + telnetmode = true; + SendRes(ResOK); + return; + } + + char * scanbuf = &cmdbuf[2]; + while (1) { + // LOG_MSG("loopstart ->%s<-",scanbuf); + char chr = GetChar(scanbuf); + switch (chr) { + case 'D': { // Dial + char * foundstr=&scanbuf[0]; + if (*foundstr=='T' || *foundstr=='P') foundstr++; + // Small protection against empty line and long string + if ((!foundstr[0]) || (strlen(foundstr)>100)) { + SendRes(ResERROR); + return; + } + char* helper; + // scan for and remove spaces; weird bug: with leading spaces in the string, + // SDLNet_ResolveHost will return no error but not work anyway (win) + while(foundstr[0]==' ') foundstr++; + helper=foundstr; + helper+=strlen(foundstr); + while(helper[0]==' ') { + helper[0]=0; + helper--; + } + if (strlen(foundstr) >= 12) { + // Check if supplied parameter only consists of digits + bool isNum = true; + for (Bitu i=0; i '9') isNum = false; + if (isNum) { + // Parameter is a number with at least 12 digits => this cannot + // be a valid IP/name + // Transform by adding dots + char buffer[128]; + Bitu j = 0; + for (Bitu i=0; i12) + buffer[j++] = ':'; + } + buffer[j] = 0; + foundstr = buffer; + } + } + Dial(foundstr); + return; + } + case 'I': // Some strings about firmware + switch (ScanNumber(scanbuf)) { + case 3: SendLine("DosBox Emulated Modem Firmware V1.00"); break; + case 4: SendLine("Modem compiled for DosBox version " VERSION); break; + } + break; + case 'E': // Echo on/off + switch (ScanNumber(scanbuf)) { + case 0: echo = false; break; + case 1: echo = true; break; + } + break; + case 'V': + switch (ScanNumber(scanbuf)) { + case 0: numericresponse = true; break; + case 1: numericresponse = false; break; + } + break; + case 'H': // Hang up + switch (ScanNumber(scanbuf)) { + case 0: + if (connected) { + SendRes(ResNOCARRIER); + EnterIdleState(); + return; + } + // else return ok + } + break; + case 'O': // Return to data mode + switch (ScanNumber(scanbuf)) { + case 0: + if (clientsocket) { + commandmode = false; + return; + } else { + SendRes(ResERROR); + return; + } + } + break; + case 'T': // Tone Dial + case 'P': // Pulse Dial + break; + case 'M': // Monitor + case 'L': // Volume + ScanNumber(scanbuf); + break; + case 'A': // Answer call + if (waitingclientsocket) { + AcceptIncomingCall(); + } else { + SendRes(ResERROR); + return; + } + return; + case 'Z': { // Reset and load profiles + // scan the number away, if any + ScanNumber(scanbuf); + if (clientsocket) SendRes(ResNOCARRIER); + Reset(); + break; + } + case ' ': // skip space + break; + case 'Q': { + // Response options + // 0 = all on, 1 = all off, + // 2 = no ring and no connect/carrier in answermode + Bitu val = ScanNumber(scanbuf); + if(!(val>2)) { + doresponse=val; + break; + } else { + SendRes(ResERROR); + return; + } + } + case 'S': { // Registers + Bitu index=ScanNumber(scanbuf); + if(index>=SREGS) { + SendRes(ResERROR); + return; //goto ret_none; + } + + while(scanbuf[0]==' ') scanbuf++; // skip spaces + + if(scanbuf[0]=='=') { // set register + scanbuf++; + while(scanbuf[0]==' ') scanbuf++; // skip spaces + Bitu val = ScanNumber(scanbuf); + reg[index]=val; + break; + } + else if(scanbuf[0]=='?') { // get register + SendNumber(reg[index]); + scanbuf++; + break; + } + //else LOG_MSG("print reg %d with %d",index,reg[index]); + } + break; + case '&': { // & escaped commands + char cmdchar = GetChar(scanbuf); + switch(cmdchar) { + case 'K': { + Bitu val = ScanNumber(scanbuf); + if(val<5) flowcontrol=val; + else { + SendRes(ResERROR); + return; + } + break; + } + case '\0': + // end of string + SendRes(ResERROR); + return; + default: + LOG_MSG("Modem: Unhandled command: &%c%d",cmdchar,ScanNumber(scanbuf)); + break; + } + break; + } + case '\\': { // \ escaped commands + char cmdchar = GetChar(scanbuf); + switch(cmdchar) { + case 'N': + // error correction stuff - not emulated + if (ScanNumber(scanbuf) > 5) { + SendRes(ResERROR); + return; + } + break; + case '\0': + // end of string + SendRes(ResERROR); + return; + default: + LOG_MSG("Modem: Unhandled command: \\%c%d",cmdchar, ScanNumber(scanbuf)); + break; + } + break; + } + case '\0': + SendRes(ResOK); + return; + default: + LOG_MSG("Modem: Unhandled command: %c%d",chr,ScanNumber(scanbuf)); + break; + } + } +} void CSerialModem::TelnetEmulation(Bit8u * data, Bitu size) { Bitu i; @@ -631,13 +654,6 @@ void CSerialModem::Timer2(void) { Bit8u txval; Bitu txbuffersize =0; - // check for bytes to be sent to port - if(CSerial::CanReceiveByte()) - if(rqueue->inuse() && (CSerial::getRTS()||(flowcontrol!=3))) { - Bit8u rbyte = rqueue->getb(); - //LOG_MSG("Modem: sending byte %2x back to UART3",rbyte); - CSerial::receiveByte(rbyte); - } // Check for eventual break command if (!commandmode) cmdpause++; // Handle incoming data from serial port, read as much as available @@ -684,8 +700,10 @@ void CSerialModem::Timer2(void) { if (clientsocket && sendbyte && txbuffersize) { // down here it saves a lot of network traffic - clientsocket->SendArray(tmpbuf,txbuffersize); - //TODO error testing + if(!clientsocket->SendArray(tmpbuf,txbuffersize)) { + SendRes(ResNOCARRIER); + EnterIdleState(); + } } // Handle incoming to the serial port if(!commandmode && clientsocket && rqueue->left()) { @@ -695,7 +713,6 @@ void CSerialModem::Timer2(void) { SendRes(ResNOCARRIER); EnterIdleState(); } else if(usesize) { - // LOG_MSG("rcv:%d", result); // Filter telnet commands if(telnetmode) TelnetEmulation(tmpbuf, usesize); else rqueue->adds(tmpbuf,usesize); diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index 7cd1e792..42406c37 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.h,v 1.11 2009-09-25 23:40:47 h-a-l-9000 Exp $ */ +/* $Id: softmodem.h,v 1.12 2009-10-04 20:57:40 h-a-l-9000 Exp $ */ #ifndef DOSBOX_SERIALMODEM_H #define DOSBOX_SERIALMODEM_H @@ -102,7 +102,7 @@ public: used+=_len; while (_len--) { if (where>=size) where-=size; - //LOG_MSG("+%x",*_str); + //LOG_MSG("+'%x'",*_str); data[where++]=*_str++; } } @@ -172,6 +172,7 @@ public: bool Dial(char * host); void AcceptIncomingCall(void); Bitu ScanNumber(char * & scan); + char GetChar(char * & scan); void DoCommand(); From c11bc7e1ef7eccc476107cc71e6007e3d59a4cb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 8 Oct 2009 20:01:31 +0000 Subject: [PATCH 3389/4131] recompiler speedups (M-HT) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3478 --- src/cpu/core_dyn_x86/decoder.h | 75 ++++++++++++++++++-------- src/cpu/core_dynrec/decoder.h | 8 ++- src/cpu/core_dynrec/decoder_basic.h | 82 +++++++++++++++++++---------- 3 files changed, 113 insertions(+), 52 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 0d91df16..aba48201 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: decoder.h,v 1.57 2009-03-29 17:32:20 qbix79 Exp $ */ +/* $Id: decoder.h,v 1.58 2009-10-08 20:01:31 c2woody Exp $ */ #define X86_DYNFPU_DH_ENABLED #define X86_INLINED_MEMACCESS @@ -187,13 +187,19 @@ static INLINE void decode_increase_wmapmask(Bitu size) { static bool decode_fetchb_imm(Bitu & val) { if (decode.page.index<4096) { - HostPt tlb_addr=get_tlb_read(decode.code); - if (tlb_addr) { - val=(Bitu)(tlb_addr+decode.code); - decode_increase_wmapmask(1); - decode.code++; - decode.page.index++; - return true; + if (decode.page.invmap != NULL) { + if (decode.page.invmap[decode.page.index] == 0) { + val=(Bit32u)decode_fetchb(); + return false; + } + HostPt tlb_addr=get_tlb_read(decode.code); + if (tlb_addr) { + val=(Bitu)(tlb_addr+decode.code); + decode_increase_wmapmask(1); + decode.code++; + decode.page.index++; + return true; + } } } val=(Bit32u)decode_fetchb(); @@ -201,13 +207,21 @@ static bool decode_fetchb_imm(Bitu & val) { } static bool decode_fetchw_imm(Bitu & val) { if (decode.page.index<4095) { - HostPt tlb_addr=get_tlb_read(decode.code); - if (tlb_addr) { - val=(Bitu)(tlb_addr+decode.code); - decode_increase_wmapmask(2); - decode.code+=2; - decode.page.index+=2; - return true; + if (decode.page.invmap != NULL) { + if ((decode.page.invmap[decode.page.index] == 0) && + (decode.page.invmap[decode.page.index + 1] == 0) + ) { + val=decode_fetchw(); + return false; + } + HostPt tlb_addr=get_tlb_read(decode.code); + if (tlb_addr) { + val=(Bitu)(tlb_addr+decode.code); + decode_increase_wmapmask(2); + decode.code+=2; + decode.page.index+=2; + return true; + } } } val=decode_fetchw(); @@ -215,13 +229,23 @@ static bool decode_fetchw_imm(Bitu & val) { } static bool decode_fetchd_imm(Bitu & val) { if (decode.page.index<4093) { - HostPt tlb_addr=get_tlb_read(decode.code); - if (tlb_addr) { - val=(Bitu)(tlb_addr+decode.code); - decode_increase_wmapmask(4); - decode.code+=4; - decode.page.index+=4; - return true; + if (decode.page.invmap != NULL) { + if ((decode.page.invmap[decode.page.index] == 0) && + (decode.page.invmap[decode.page.index + 1] == 0) && + (decode.page.invmap[decode.page.index + 2] == 0) && + (decode.page.invmap[decode.page.index + 3] == 0) + ) { + val=decode_fetchd(); + return false; + } + HostPt tlb_addr=get_tlb_read(decode.code); + if (tlb_addr) { + val=(Bitu)(tlb_addr+decode.code); + decode_increase_wmapmask(4); + decode.code+=4; + decode.page.index+=4; + return true; + } } } val=decode_fetchd(); @@ -2649,8 +2673,13 @@ restart_prefix: goto illegalopcode; } } - /* Normal exit because of max opcodes reached */ + // link to next block because the maximal number of opcodes has been reached dyn_set_eip_end(); + dyn_reduce_cycles(); + dyn_save_critical_regs(); + gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); + dyn_closeblock(); + goto finish_block; core_close_block: dyn_reduce_cycles(); dyn_save_critical_regs(); diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h index dbd9cf50..f2e077fc 100644 --- a/src/cpu/core_dynrec/decoder.h +++ b/src/cpu/core_dynrec/decoder.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: decoder.h,v 1.6 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: decoder.h,v 1.7 2009-10-08 20:01:31 c2woody Exp $ */ #include "decoder_basic.h" @@ -574,8 +574,12 @@ restart_prefix: goto illegalopcode; } } - // normal exit because the maximal number of opcodes has been reached + // link to next block because the maximal number of opcodes has been reached dyn_set_eip_end(); + dyn_reduce_cycles(); + gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlockDynRec,cache.start)); + dyn_closeblock(); + goto finish_block; core_close_block: dyn_reduce_cycles(); dyn_return(BR_Normal); diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index 99d57272..3a0cd4af 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: decoder_basic.h,v 1.15 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: decoder_basic.h,v 1.16 2009-10-08 20:01:31 c2woody Exp $ */ /* @@ -290,16 +290,24 @@ static bool decode_fetchb_imm(Bitu & val) { if (GCC_UNLIKELY(decode.page.index>=4096)) { decode_advancepage(); } - HostPt tlb_addr=get_tlb_read(decode.code); // see if position is directly accessible - if (tlb_addr) { - val=(Bitu)(tlb_addr+decode.code); - decode_increase_wmapmask(1); - decode.code++; - decode.page.index++; - return true; + if (decode.page.invmap != NULL) { + if (decode.page.invmap[decode.page.index] == 0) { + // position not yet modified + val=(Bit32u)decode_fetchb(); + return false; + } + + HostPt tlb_addr=get_tlb_read(decode.code); + if (tlb_addr) { + val=(Bitu)(tlb_addr+decode.code); + decode_increase_wmapmask(1); + decode.code++; + decode.page.index++; + return true; + } } - // not directly accessible, just fetch the value + // first time decoding or not directly accessible, just fetch the value val=(Bit32u)decode_fetchb(); return false; } @@ -308,17 +316,26 @@ static bool decode_fetchb_imm(Bitu & val) { // otherwise val contains the current value read from the position static bool decode_fetchw_imm(Bitu & val) { if (decode.page.index<4095) { - HostPt tlb_addr=get_tlb_read(decode.code); - // see if position is directly accessible - if (tlb_addr) { - val=(Bitu)(tlb_addr+decode.code); - decode_increase_wmapmask(2); - decode.code+=2; - decode.page.index+=2; - return true; + if (decode.page.invmap != NULL) { + if ((decode.page.invmap[decode.page.index] == 0) && + (decode.page.invmap[decode.page.index + 1] == 0)) { + // position not yet modified + val=decode_fetchw(); + return false; + } + + HostPt tlb_addr=get_tlb_read(decode.code); + // see if position is directly accessible + if (tlb_addr) { + val=(Bitu)(tlb_addr+decode.code); + decode_increase_wmapmask(2); + decode.code+=2; + decode.page.index+=2; + return true; + } } } - // not directly accessible, just fetch the value + // first time decoding or not directly accessible, just fetch the value val=decode_fetchw(); return false; } @@ -327,17 +344,28 @@ static bool decode_fetchw_imm(Bitu & val) { // otherwise val contains the current value read from the position static bool decode_fetchd_imm(Bitu & val) { if (decode.page.index<4093) { - HostPt tlb_addr=get_tlb_read(decode.code); - // see if position is directly accessible - if (tlb_addr) { - val=(Bitu)(tlb_addr+decode.code); - decode_increase_wmapmask(4); - decode.code+=4; - decode.page.index+=4; - return true; + if (decode.page.invmap != NULL) { + if ((decode.page.invmap[decode.page.index] == 0) && + (decode.page.invmap[decode.page.index + 1] == 0) && + (decode.page.invmap[decode.page.index + 2] == 0) && + (decode.page.invmap[decode.page.index + 3] == 0)) { + // position not yet modified + val=decode_fetchd(); + return false; + } + + HostPt tlb_addr=get_tlb_read(decode.code); + // see if position is directly accessible + if (tlb_addr) { + val=(Bitu)(tlb_addr+decode.code); + decode_increase_wmapmask(4); + decode.code+=4; + decode.page.index+=4; + return true; + } } } - // not directly accessible, just fetch the value + // first time decoding or not directly accessible, just fetch the value val=decode_fetchd(); return false; } From 8132bdca292483f738ea96df939b1cee2db5b670 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sat, 10 Oct 2009 13:26:46 +0000 Subject: [PATCH 3390/4131] Most of the INT14 interface rewritten for better compatibility Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3479 --- src/ints/bios.cpp | 190 +++++++++++++++++++++++++--------------------- 1 file changed, 103 insertions(+), 87 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index fb05be2b..50debeec 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.77 2009-06-23 17:46:05 c2woody Exp $ */ +/* $Id: bios.cpp,v 1.78 2009-10-10 13:26:46 h-a-l-9000 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -434,110 +434,126 @@ static Bitu INT17_Handler(void) { return CBRET_NONE; } -static Bitu INT14_Handler(void) -{ - if(reg_ah > 0x3 || reg_dx > 0x3) { // 0-3 serial port functions +static Bit8u INT14_Wait(Bit16u port, Bit8u mask, Bit8u timeout) { + double starttime = PIC_FullIndex(); + double timeout_f = timeout * 1000.0; + Bit8u retval; + while (((retval = IO_ReadB(port)) & mask) != mask) { + if (starttime < (PIC_FullIndex() - timeout_f)) { + retval |= 0x80; + break; + } + CALLBACK_Idle(); + } + return retval; +} + +static Bitu INT14_Handler(void) { + if (reg_ah > 0x3 || reg_dx > 0x3) { // 0-3 serial port functions // and no more than 4 serial ports LOG_MSG("BIOS INT14: Unhandled call AH=%2X DX=%4x",reg_ah,reg_dx); return CBRET_NONE; } Bit16u port = real_readw(0x40,reg_dx*2); // DX is always port number - if(port==0) { + Bit8u timeout = mem_readb(BIOS_COM1_TIMEOUT + reg_dx); + if (port==0) { LOG(LOG_BIOS,LOG_NORMAL)("BIOS INT14: port %d does not exist.",reg_dx); return CBRET_NONE; } - switch (reg_ah) - { - case 0x00: /* Init port */ - // Parameters: - // AL: port parameters - // Return: - // AH: line status - // AL: modem status - { - // set baud rate - Bitu baudrate = 9600; - Bit16u baudresult; - Bitu rawbaud=reg_al>>5; - - if(rawbaud==0){ baudrate=110;} - else if (rawbaud==1){ baudrate=150;} - else if (rawbaud==2){ baudrate=300;} - else if (rawbaud==3){ baudrate=600;} - else if (rawbaud==4){ baudrate=1200;} - else if (rawbaud==5){ baudrate=2400;} - else if (rawbaud==6){ baudrate=4800;} - else if (rawbaud==7){ baudrate=9600;} + switch (reg_ah) { + case 0x00: { + // Initialize port + // Parameters: Return: + // AL: port parameters AL: modem status + // AH: line status - baudresult = (Bit16u)(115200 / baudrate); + // set baud rate + Bitu baudrate = 9600; + Bit16u baudresult; + Bitu rawbaud=reg_al>>5; + + if (rawbaud==0){ baudrate=110;} + else if (rawbaud==1){ baudrate=150;} + else if (rawbaud==2){ baudrate=300;} + else if (rawbaud==3){ baudrate=600;} + else if (rawbaud==4){ baudrate=1200;} + else if (rawbaud==5){ baudrate=2400;} + else if (rawbaud==6){ baudrate=4800;} + else if (rawbaud==7){ baudrate=9600;} - IO_WriteB(port+3, 0x80); // enable divider access - IO_WriteB(port,(Bit8u)baudresult&0xff); - IO_WriteB(port+1,(Bit8u)(baudresult>>8)); + baudresult = (Bit16u)(115200 / baudrate); - // set line parameters, disable divider access - IO_WriteB(port+3, reg_al&0x1F);//LCR - - // disable interrupts - IO_WriteB(port+1, 0); - IO_ReadB(port+2); + IO_WriteB(port+3, 0x80); // enable divider access + IO_WriteB(port, (Bit8u)baudresult&0xff); + IO_WriteB(port+1, (Bit8u)(baudresult>>8)); - // get result - reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff); - reg_al=(Bit8u)(IO_ReadB(port+6)&0xff); - CALLBACK_SCF(false); - } + // set line parameters, disable divider access + IO_WriteB(port+3, reg_al&0x1F); // LCR + + // disable interrupts + IO_WriteB(port+1, 0); // IER + + // get result + reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff); + reg_al=(Bit8u)(IO_ReadB(port+6)&0xff); + CALLBACK_SCF(false); break; - case 0x01: /* Write character */ - // Parameters: - // AL: character - // Return: - // AH: line status - // AL: modem status - { - if(serialports[reg_dx]) { - bool timeout; - // switch modem lines on - IO_WriteB(port+4,0x3); - timeout = !serialports[reg_dx]->Putchar(reg_al,true,true, - mem_readb(BIOS_COM1_TIMEOUT+reg_dx)*1000); - // get result - reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff); - if(timeout) reg_ah |= 0x80; - } - CALLBACK_SCF(false); - } - break; - - case 0x02: /* Read character */ - { - if(serialports[reg_dx]) { - bool timeout; - Bit8u buffer; - // switch modem lines on - IO_WriteB(port+4,0x3); - // wait for something - timeout = !serialports[reg_dx]->Getchar(&buffer,®_ah,true, - mem_readb(BIOS_COM1_TIMEOUT+reg_dx)*1000); + } + case 0x01: { // Transmit character + // Parameters: Return: + // AL: character AL: unchanged + // AH: 0x01 AH: line status from just before the char was sent + // (0x80 | unpredicted) in case of timeout + // [undoc] (0x80 | line status) in case of tx timeout + // [undoc] (0x80 | modem status) in case of dsr/cts timeout - // RTS off - IO_WriteB(port+4,0x1); - // get result - reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff); - if(timeout) reg_ah |= 0x80; - else reg_al=buffer; + // set DTR & RTS on + IO_WriteB(port+4,0x3); + + // wait for DSR & CTS + reg_ah = INT14_Wait(port+6, 0x30, timeout); + if (!(reg_ah & 0x80)) { + // wait for TX buffer empty + reg_ah = INT14_Wait(port+5, 0x20, timeout); + if (!(reg_ah & 0x80)) { + // fianlly send the character + IO_WriteB(port,reg_al); + } + } // else timed out + CALLBACK_SCF(false); + break; + } + case 0x02: // Read character + // Parameters: Return: + // AH: 0x02 AL: received character + // [undoc] will be trashed in case of timeout + // AH: (line status & 0x1E) in case of success + // (0x80 | unpredicted) in case of timeout + // [undoc] (0x80 | line status) in case of rx timeout + // [undoc] (0x80 | modem status) in case of dsr timeout + + // set DTR on + IO_WriteB(port+4,0x1); + + // wait for DSR + reg_ah = INT14_Wait(port+6, 0x20, timeout); + if (!(reg_ah & 0x80)) { + // wait for character to arrive + reg_ah = INT14_Wait(port+5, 0x01, timeout); + if (!(reg_ah & 0x80)) { + reg_ah &= 0x1E; + reg_al = IO_ReadB(port); } - CALLBACK_SCF(false); - break; } + CALLBACK_SCF(false); + break; case 0x03: // get status - { - reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff); - reg_al=(Bit8u)(IO_ReadB(port+6)&0xff); - CALLBACK_SCF(false); - } - break; + reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff); + reg_al=(Bit8u)(IO_ReadB(port+6)&0xff); + CALLBACK_SCF(false); + break; + } return CBRET_NONE; } From 8aadb7d1657ddec9a5a105e079a84e7cacb0fc4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 11 Oct 2009 17:11:52 +0000 Subject: [PATCH 3391/4131] use emm system handle for vcpi, increase system handle pages (fixes strange mk2 bug related to continue screen); some minor ems improvements so msdos mem.exe detects ems memory Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3480 --- src/ints/ems.cpp | 60 ++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 5f8e845b..64d2593c 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.64 2009-06-24 17:44:52 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.65 2009-10-11 17:11:52 c2woody Exp $ */ #include #include @@ -40,8 +40,10 @@ #define EMM_MAX_PAGES (32 * 1024 / 16 ) #define EMM_MAX_PHYS 4 /* 4 16kb pages in pageframe */ -#define EMM_VERSION 0x40 -#define GEMMIS_VERSION 0x0001 // Version 1.0 +#define EMM_VERSION 0x40 +#define EMM_MINOR_VERSION 0x00 +//#define EMM_MINOR_VERSION 0x30 // emm386 4.48 +#define GEMMIS_VERSION 0x0001 // Version 1.0 #define EMM_SYSTEM_HANDLE 0x0000 #define NULL_HANDLE 0xffff @@ -180,8 +182,15 @@ bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retco } case 0x02: if (size!=2) return false; - mem_writeb(bufptr+0x00,EMM_VERSION>>4); // version 4.0 - mem_writew(bufptr+0x01,EMM_VERSION&0x0f); + mem_writeb(bufptr+0x00,EMM_VERSION>>4); // version 4 + mem_writeb(bufptr+0x01,EMM_MINOR_VERSION); + *retcode=2; + return true; + case 0x03: + if (EMM_MINOR_VERSION < 0x2d) return false; + if (size!=4) return false; + mem_writew(bufptr+0x00,(Bit16u)(MEM_TotalPages()*4)); // max size (kb) + mem_writew(bufptr+0x02,0x80); // min size (kb) *retcode=2; return true; } @@ -1177,8 +1186,7 @@ static Bitu V86_Monitor() { static void SetupVCPI() { vcpi.enabled=false; - /* Allocate one EMS-page for private VCPI-data in memory beyond 1MB */ - if (EMM_AllocateMemory(1,vcpi.ems_handle,false) != EMM_NO_ERROR) return; + vcpi.ems_handle=0; // use EMM system handle for VCPI data vcpi.enabled=true; @@ -1259,9 +1267,10 @@ class EMS: public Module_base { private: /* location in protected unfreeable memory where the ems name and callback are * stored 32 bytes.*/ - static Bit16u emsnameseg; + static Bit16u ems_baseseg; RealPt old4b_pointer,old67_pointer; - CALLBACK_HandlerObject call_vdma,int67,call_vcpi,call_v86mon; + CALLBACK_HandlerObject call_vdma,call_vcpi,call_v86mon; + Bitu call_int67; public: EMS(Section* configuration):Module_base(configuration){ @@ -1280,24 +1289,21 @@ public: return; } BIOS_ZeroExtendedSize(true); - int67.Install(&INT67_Handler,CB_IRET,"Int 67 ems"); - Bit16u call_int67=int67.Get_callback(); + + if (!ems_baseseg) ems_baseseg=DOS_GetMemory(2); //We have 32 bytes + + /* Add a little hack so it appears that there is an actual ems device installed */ + char const* emsname="EMMXXXX0"; + MEM_BlockWrite(PhysMake(ems_baseseg,0xa),emsname,(Bitu)(strlen(emsname)+1)); + + call_int67=CALLBACK_Allocate(); + CALLBACK_Setup(call_int67,&INT67_Handler,CB_IRET,PhysMake(ems_baseseg,4),"Int 67 ems"); + RealSetVec(0x67,RealMake(ems_baseseg,4),old67_pointer); /* Register the ems device */ //TODO MAYBE put it in the class. DOS_Device * newdev = new device_EMM(); DOS_AddDevice(newdev); - - /* Add a little hack so it appears that there is an actual ems device installed */ - char const* emsname="EMMXXXX0"; - if(!emsnameseg) emsnameseg=DOS_GetMemory(2); //We have 32 bytes - MEM_BlockWrite(PhysMake(emsnameseg,0xa),emsname,(Bitu)(strlen(emsname)+1)); - - /* Copy the callback piece into the beginning, and set the interrupt vector to it*/ - char buf[16]; - MEM_BlockRead(CALLBACK_PhysPointer(call_int67),buf,0xa); - MEM_BlockWrite(PhysMake(emsnameseg,0),buf,0xa); - RealSetVec(0x67,RealMake(emsnameseg,0),old67_pointer); /* Clear handle and page tables */ Bitu i; @@ -1315,7 +1321,7 @@ public: emm_segmentmappings[i].handle=NULL_HANDLE; } - EMM_AllocateSystemHandle(4); // allocate OS-dedicated handle (ems handle zero, 16kb) + EMM_AllocateSystemHandle(8); // allocate OS-dedicated handle (ems handle zero, 128kb) if (!ENABLE_VCPI) return; @@ -1365,6 +1371,7 @@ public: ~EMS() { Section_prop * section=static_cast(m_configuration); if (!section->Get_bool("ems")) return; + /* Undo Biosclearing */ BIOS_ZeroExtendedSize(false); @@ -1375,7 +1382,7 @@ public: /* Remove the emsname and callback hack */ char buf[32]= { 0 }; - MEM_BlockWrite(PhysMake(emsnameseg,0),buf,32); + MEM_BlockWrite(PhysMake(ems_baseseg,0),buf,32); RealSetVec(0x67,old67_pointer); /* Release memory allocated to system handle */ @@ -1388,9 +1395,6 @@ public: if ((!ENABLE_VCPI) || (!vcpi.enabled)) return; - /* Free private data area in expanded memory */ - EMM_ReleaseMemory(vcpi.ems_handle); - if (cpu.pmode && GETFLAG(VM)) { /* Switch back to real mode if in v86-mode */ CPU_SET_CRX(0, 0); @@ -1414,4 +1418,4 @@ void EMS_Init(Section* sec) { } //Initialize static members -Bit16u EMS::emsnameseg = 0; +Bit16u EMS::ems_baseseg = 0; From 2e5e70aa3101cc7874229a780cf8b7a37d08c142 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 11 Oct 2009 18:09:22 +0000 Subject: [PATCH 3392/4131] Write the header more often. (thanks kekko) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3481 --- src/hardware/hardware.cpp | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 44671ab7..378f7185 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: hardware.cpp,v 1.22 2009-04-26 18:24:36 qbix79 Exp $ */ +/* $Id: hardware.cpp,v 1.23 2009-10-11 18:09:22 qbix79 Exp $ */ #include #include @@ -161,17 +161,13 @@ static void CAPTURE_AddAviChunk(const char * tag, Bit32u size, void * data, Bit3 #endif #if (C_SSHOT) -static void CAPTURE_VideoEvent(bool pressed) { - if (!pressed) - return; - if (CaptureState & CAPTURE_VIDEO) { - /* Close the video */ - CaptureState &= ~CAPTURE_VIDEO; - LOG_MSG("Stopped capturing video."); +static void CAPTURE_VideoHeader() { Bit8u avi_header[AVI_HEADER_SIZE]; Bitu main_list; Bitu header_pos=0; + Bitu save_pos=ftell(capture.video.handle); + #define AVIOUT4(_S_) memcpy(&avi_header[header_pos],_S_,4);header_pos+=4; #define AVIOUTw(_S_) host_writew(&avi_header[header_pos], _S_);header_pos+=2; #define AVIOUTd(_S_) host_writed(&avi_header[header_pos], _S_);header_pos+=4; @@ -288,6 +284,20 @@ static void CAPTURE_VideoEvent(bool pressed) { fwrite( capture.video.index, 1, capture.video.indexused, capture.video.handle); fseek(capture.video.handle, 0, SEEK_SET); fwrite(&avi_header, 1, AVI_HEADER_SIZE, capture.video.handle); + fseek(capture.video.handle, save_pos, SEEK_SET); +} + +static void CAPTURE_VideoEvent(bool pressed) { + if (!pressed) + return; + if (CaptureState & CAPTURE_VIDEO) { + /* Close the video */ + CaptureState &= ~CAPTURE_VIDEO; + LOG_MSG("Stopped capturing video."); + + /* Adds AVI header to the file */ + CAPTURE_VideoHeader(); + fclose( capture.video.handle ); free( capture.video.index ); free( capture.video.buf ); @@ -547,6 +557,9 @@ skip_shot: capture.video.audioused = 0; } + /* Adds AVI header to the file */ + CAPTURE_VideoHeader(); + /* Everything went okay, set flag again for next frame */ CaptureState |= CAPTURE_VIDEO; } From a11709e592f79cfecbda5cbd40b7311331ea8bc8 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Mon, 12 Oct 2009 12:55:20 +0000 Subject: [PATCH 3393/4131] Use the right headers, fixes compilation on OS X (thanks Dominus) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3482 --- src/hardware/serialport/libserial.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/serialport/libserial.cpp b/src/hardware/serialport/libserial.cpp index fe8e7ecb..fd1eaff1 100644 --- a/src/hardware/serialport/libserial.cpp +++ b/src/hardware/serialport/libserial.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: libserial.cpp,v 1.2 2009-09-26 09:15:19 h-a-l-9000 Exp $ */ +/* $Id: libserial.cpp,v 1.3 2009-10-12 12:55:20 h-a-l-9000 Exp $ */ #include "libserial.h" @@ -256,8 +256,8 @@ bool SERIAL_setCommParameters(COMPORT port, #if defined (LINUX) || defined (MACOSX) -#include // strlen -#include +#include // strlen +#include #include #include From 23c833c79438cca16074c2ec83867fb9f58ec572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 15 Oct 2009 20:36:56 +0000 Subject: [PATCH 3394/4131] fix mode6/9 scrolling (ripsaw/etillite, fixes Orphee), see sf bug #2501673 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3483 --- src/ints/int10_char.cpp | 67 ++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 9d102b4c..b51e785e 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.59 2009-07-11 10:25:25 c2woody Exp $ */ +/* $Id: int10_char.cpp,v 1.60 2009-10-15 20:36:56 c2woody Exp $ */ /* Character displaying moving functions */ @@ -26,18 +26,18 @@ #include "inout.h" #include "int10.h" -static void CGA2_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { - Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); - PhysPt dest=base+((CurMode->twidth*rnew)*(cheight/2)+cleft); - PhysPt src=base+((CurMode->twidth*rold)*(cheight/2)+cleft); - Bitu copy=(cright-cleft); - Bitu nextline=CurMode->twidth; - for (Bitu i=0;itwidth*rnew)*(cheight/2)+cleft); + PhysPt src=base+((CurMode->twidth*rold)*(cheight/2)+cleft); + Bitu copy=(cright-cleft); + Bitu nextline=CurMode->twidth; + for (Bitu i=0;itwidth*rnew)*(cheight/4)+cleft)*4; PhysPt src=base+((CurMode->twidth*rold)*(cheight/4)+cleft)*4; Bitu copy=(cright-cleft)*4;Bitu nextline=CurMode->twidth*4; - for (Bitu i=0;itwidth*row)*(cheight/2)+cleft); - Bitu copy=(cright-cleft); - Bitu nextline=CurMode->twidth; - attr=(attr & 0x3) | ((attr & 0x3) << 2) | ((attr & 0x3) << 4) | ((attr & 0x3) << 6); - for (Bitu i=0;itwidth*row)*(cheight/2)+cleft); + Bitu copy=(cright-cleft); + Bitu nextline=CurMode->twidth; + attr=(attr & 0x3) | ((attr & 0x3) << 2) | ((attr & 0x3) << 4) | ((attr & 0x3) << 6); + for (Bitu i=0;itwidth*row)*(cheight/2)+cleft)*2; @@ -411,10 +410,10 @@ void ReadCharAttr(Bit16u col,Bit16u row,Bit8u page,Bit16u * result) { Bit8u bitline=mem_readb(fontdata++); Bit8u res=0; Bit8u vidline=0; - Bit16u tx=x; + Bit16u tx=(Bit16u)x; while (bitsel) { //Construct bitline in memory - INT10_GetPixel(tx,y,page,&res); + INT10_GetPixel(tx,(Bit16u)y,page,&res); if(res) vidline|=bitsel; tx++; bitsel>>=1; @@ -517,10 +516,10 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt Bit8u bitsel=128; Bit8u bitline = mem_readb(Real2Phys( fontdata )); fontdata = RealMake( RealSeg( fontdata ), RealOff( fontdata ) + 1); - Bit16u tx=x; + Bit16u tx=(Bit16u)x; while (bitsel) { - if (bitline&bitsel) INT10_PutPixel(tx,y,page,attr); - else INT10_PutPixel(tx,y,page,attr & xor_mask); + if (bitline&bitsel) INT10_PutPixel(tx,(Bit16u)y,page,attr); + else INT10_PutPixel(tx,(Bit16u)y,page,attr & xor_mask); tx++; bitsel>>=1; } @@ -594,7 +593,7 @@ static void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr,Bit8u pag if(cur_row==nrows) { //Fill with black on non-text modes and with 0x7 on textmode Bit8u fill = (CurMode->type == M_TEXT)?0x7:0; - INT10_ScrollWindow(0,0,(Bit8u)(nrows-1),ncols-1,-1,fill,page); + INT10_ScrollWindow(0,0,(Bit8u)(nrows-1),(Bit8u)(ncols-1),-1,fill,page); cur_row--; } // Set the cursor for the page From 8e761077e164cefe27359e79d8ed9dc2bb77560a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 18 Oct 2009 17:52:10 +0000 Subject: [PATCH 3395/4131] handle opcode 0xff subcode 7 as invalid instruction, fixes dif-2 and others Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3484 --- src/cpu/core_dyn_x86/decoder.h | 5 +++-- src/cpu/core_dynrec/decoder.h | 13 +++++++++++-- src/cpu/core_dynrec/decoder_opcodes.h | 15 ++++++++------- src/cpu/core_normal/prefix_66.h | 4 ++-- src/cpu/core_normal/prefix_none.h | 4 ++-- 5 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index aba48201..3a838f34 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: decoder.h,v 1.58 2009-10-08 20:01:31 c2woody Exp $ */ +/* $Id: decoder.h,v 1.59 2009-10-18 17:52:09 c2woody Exp $ */ #define X86_DYNFPU_DH_ENABLED #define X86_INLINED_MEMACCESS @@ -2665,7 +2665,8 @@ restart_prefix: dyn_push(src); break; default: - IllegalOption("opcode 0xff"); + LOG(LOG_CPU,LOG_ERROR)("CPU:GRP5:Illegal opcode 0xff"); + goto illegalopcode; }} break; default: diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h index f2e077fc..8d7846c7 100644 --- a/src/cpu/core_dynrec/decoder.h +++ b/src/cpu/core_dynrec/decoder.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: decoder.h,v 1.7 2009-10-08 20:01:31 c2woody Exp $ */ +/* $Id: decoder.h,v 1.8 2009-10-18 17:52:10 c2woody Exp $ */ #include "decoder_basic.h" @@ -566,7 +566,16 @@ restart_prefix: if (dyn_grp4_eb()) goto finish_block; break; case 0xff: - if (dyn_grp4_ev()) goto core_close_block; + switch (dyn_grp4_ev()) { + case 0: + break; + case 1: + goto core_close_block; + case 2: + goto illegalopcode; + default: + break; + } break; default: diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index 25605046..b12733b3 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: decoder_opcodes.h,v 1.9 2009-06-25 19:31:43 c2woody Exp $ */ +/* $Id: decoder_opcodes.h,v 1.10 2009-10-18 17:52:10 c2woody Exp $ */ /* @@ -818,7 +818,7 @@ static bool dyn_grp4_eb(void) { return false; } -static bool dyn_grp4_ev(void) { +static Bitu dyn_grp4_ev(void) { dyn_get_modrm(); if (decode.modrm.mod<3) { dyn_fill_ea(FC_ADDR); @@ -848,10 +848,10 @@ static bool dyn_grp4_ev(void) { gen_restore_addr_reg(); gen_mov_word_from_reg(FC_ADDR,decode.big_op?(void*)(®_eip):(void*)(®_ip),decode.big_op); - return true; + return 1; case 0x4: // JMP Ev gen_mov_word_from_reg(FC_OP1,decode.big_op?(void*)(®_eip):(void*)(®_ip),decode.big_op); - return true; + return 1; case 0x3: // CALL Ep case 0x5: // JMP Ep if (!decode.big_op) gen_extend_word(false,FC_OP1); @@ -865,15 +865,16 @@ static bool dyn_grp4_ev(void) { gen_restore_reg(FC_OP1,FC_ADDR); gen_call_function_IRRR(decode.modrm.reg == 3 ? (void*)(&CPU_CALL) : (void*)(&CPU_JMP), decode.big_op,FC_OP2,FC_ADDR,FC_RETOP); - return true; + return 1; case 0x6: // PUSH Ev if (decode.big_op) gen_call_function_raw((void*)&dynrec_push_dword); else gen_call_function_raw((void*)&dynrec_push_word); break; default: - IllegalOptionDynrec("dyn_grp4_ev"); +// IllegalOptionDynrec("dyn_grp4_ev"); + return 2; } - return false; + return 0; } diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 3d34b705..39769ce8 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -709,8 +709,8 @@ else {GetEAa;Push_32(LoadMd(eaa));} break; default: - E_Exit("CPU:66:GRP5:Illegal call %2X",which); - break; + LOG(LOG_CPU,LOG_ERROR)("CPU:66:GRP5:Illegal call %2X",which); + goto illegal_opcode; } break; } diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 6232be23..043cabdc 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -1165,8 +1165,8 @@ else {GetEAa;Push_16(LoadMw(eaa));} break; default: - E_Exit("CPU:GRP5:Illegal Call %2X",which); - break; + LOG(LOG_CPU,LOG_ERROR)("CPU:GRP5:Illegal Call %2X",which); + goto illegal_opcode; } break; } From 9ad4fb5c5b3b68a924aa78a97038b419677f0f4d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 18 Oct 2009 18:06:28 +0000 Subject: [PATCH 3396/4131] Keep it compiling. SF:2875962 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3485 --- src/gui/midi_coreaudio.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index a54b0a8b..4dc50481 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -16,7 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: midi_coreaudio.h,v 1.12 2009-10-18 18:06:28 qbix79 Exp $ */ + #include +#include // A macro to simplify error handling a bit. #define RequireNoErr(error) \ From 869328c6636a19fa62e386a2176ed1b97273d2ed Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Mon, 19 Oct 2009 16:00:22 +0000 Subject: [PATCH 3397/4131] - read the correct position in the video parameter table, fixes seven spirits of ra title screen - save the data written to the CGA control port Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3486 --- src/ints/int10_modes.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 4acd8f00..c74e9ebb 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.90 2009-09-06 19:25:34 c2woody Exp $ */ +/* $Id: int10_modes.cpp,v 1.91 2009-10-19 16:00:22 h-a-l-9000 Exp $ */ #include @@ -607,8 +607,9 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) { RealOff(vparams) + i + crtc_block_index*16) << 8)); if (machine==MCH_CGA) { // mode register - IO_WriteB(crtc_base + 4, real_readb(RealSeg(vparams), - RealOff(vparams) + 4*16 + 24 + mode)); + Bit8u mode_control = real_readb(RealSeg(vparams), RealOff(vparams) + 80 + mode); + IO_WriteB(crtc_base + 4, mode_control); + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR, mode_control); } if (machine==MCH_TANDY) { From ee5f6c5a927c0f8a7fd9e594f0dfb770add01462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 25 Oct 2009 16:22:22 +0000 Subject: [PATCH 3398/4131] behave like the real thing Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3487 --- src/hardware/sblaster.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index df55a769..a8329028 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.77 2009-07-11 10:39:38 harekiet Exp $ */ +/* $Id: sblaster.cpp,v 1.78 2009-10-25 16:22:22 c2woody Exp $ */ #include #include @@ -250,7 +250,7 @@ static INLINE void SB_RaiseIRQ(SB_IRQS type) { switch (type) { case SB_IRQ_8: if (sb.irq.pending_8bit) { - E_Exit("SB: 8bit irq pending"); +// LOG_MSG("SB: 8bit irq pending"); return; } sb.irq.pending_8bit=true; @@ -258,7 +258,7 @@ static INLINE void SB_RaiseIRQ(SB_IRQS type) { break; case SB_IRQ_16: if (sb.irq.pending_16bit) { - E_Exit("SB: 16bit irq pending"); +// LOG_MSG("SB: 16bit irq pending"); return; } sb.irq.pending_16bit=true; From b10cd0e07374e2c00b9ce78229ae39e5d35a2e31 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 28 Oct 2009 21:45:12 +0000 Subject: [PATCH 3399/4131] Add very simple and not entirely correct upcase table. Makes doswin32 happy. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3488 --- include/dos_inc.h | 3 ++- src/dos/dos.cpp | 10 ++++++++-- src/dos/dos_tables.cpp | 11 ++++++++--- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index a51085cb..c76ba885 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.82 2009-10-04 14:28:06 c2woody Exp $ */ +/* $Id: dos_inc.h,v 1.83 2009-10-28 21:45:12 qbix79 Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -627,6 +627,7 @@ struct DOS_Block { RealPt dbcs; RealPt filenamechar; RealPt collatingseq; + RealPt upcase; 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; diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index ce723fac..db640ddb 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.120 2009-10-04 14:28:07 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.121 2009-10-28 21:45:12 qbix79 Exp $ */ #include #include @@ -69,6 +69,7 @@ static Bitu DOS_21Handler(void) { char name1[DOSNAMEBUF+2+DOS_NAMELENGTH_ASCII]; char name2[DOSNAMEBUF+2+DOS_NAMELENGTH_ASCII]; + switch (reg_ah) { case 0x00: /* Terminate Program */ DOS_Terminate(mem_readw(SegPhys(ss)+reg_sp+2),false,0); @@ -924,13 +925,18 @@ static Bitu DOS_21Handler(void) { reg_cx = 5; CALLBACK_SCF(false); break; + case 0x02: // Get pointer to uppercase table + mem_writeb(data + 0x00, reg_al); + mem_writed(data + 0x01, dos.tables.upcase); + reg_cx = 5; + CALLBACK_SCF(false); + break; case 0x06: // Get pointer to collating sequence table mem_writeb(data + 0x00, reg_al); mem_writed(data + 0x01, dos.tables.collatingseq); reg_cx = 5; CALLBACK_SCF(false); break; - case 0x02: // Get pointer to uppercase table case 0x03: // Get pointer to lowercase table case 0x04: // Get pointer to filename uppercase table case 0x07: // Get pointer to double byte char set table diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index c4d659f1..a56e9e01 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.31 2009-05-27 09:15:41 qbix79 Exp $ */ +/* $Id: dos_tables.cpp,v 1.32 2009-10-28 21:45:12 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -134,10 +134,15 @@ void DOS_SetupTables(void) { mem_writeb(Real2Phys(dos.tables.filenamechar)+0x15,0x3d); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x16,0x3b); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x17,0x2c); - /* COLLATING SEQUENCE TABLE */ - dos.tables.collatingseq=RealMake(DOS_GetMemory(17),0); + /* COLLATING SEQUENCE TABLE + UPCASE TABLE*/ + // 256 bytes for col table, 128 for upcase, 4 for number of entries + dos.tables.collatingseq=RealMake(DOS_GetMemory(25),0); mem_writew(Real2Phys(dos.tables.collatingseq),0x100); for (i=0; i<256; i++) mem_writeb(Real2Phys(dos.tables.collatingseq)+i+2,i); + dos.tables.upcase=RealMake(dos.tables.collatingseq,258); + mem_writew(Real2Phys(dos.tables.upcase),0x80); + for (i=0; i<128; i++) mem_writeb(Real2Phys(dos.tables.upcase)+i+2,0x80+i); + /* Create a fake FCB SFT */ seg=DOS_GetMemory(4); From 360608e2ba7385c5aa62b864e6bd85aa17c90ead Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Mon, 2 Nov 2009 09:51:02 +0000 Subject: [PATCH 3400/4131] Re-enable directserial for BSD Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3489 --- src/hardware/serialport/libserial.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/serialport/libserial.cpp b/src/hardware/serialport/libserial.cpp index fd1eaff1..0c7ad2a4 100644 --- a/src/hardware/serialport/libserial.cpp +++ b/src/hardware/serialport/libserial.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: libserial.cpp,v 1.3 2009-10-12 12:55:20 h-a-l-9000 Exp $ */ +/* $Id: libserial.cpp,v 1.4 2009-11-02 09:51:02 h-a-l-9000 Exp $ */ #include "libserial.h" @@ -254,7 +254,7 @@ bool SERIAL_setCommParameters(COMPORT port, } #endif -#if defined (LINUX) || defined (MACOSX) +#if defined (LINUX) || defined (MACOSX) || defined (BSD) #include // strlen #include From 98efcf62b2c3fa73ef1d94341e9a1e99b0ebb0bd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 3 Nov 2009 20:17:42 +0000 Subject: [PATCH 3401/4131] Remove old opl. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3490 --- src/dosbox.cpp | 10 +- src/hardware/Makefile.am | 2 +- src/hardware/adlib.cpp | 108 +- src/hardware/fmopl.c | 2524 ----------------------------------- src/hardware/fmopl.h | 111 -- src/hardware/ymf262.c | 2746 -------------------------------------- src/hardware/ymf262.h | 53 - 7 files changed, 8 insertions(+), 5546 deletions(-) delete mode 100644 src/hardware/fmopl.c delete mode 100644 src/hardware/fmopl.h delete mode 100644 src/hardware/ymf262.c delete mode 100644 src/hardware/ymf262.h diff --git a/src/dosbox.cpp b/src/dosbox.cpp index aa293cc1..c965186c 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.149 2009-05-20 18:07:06 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.150 2009-11-03 20:17:42 qbix79 Exp $ */ #include #include @@ -130,10 +130,10 @@ static Bitu Normal_Loop(void) { while (1) { if (PIC_RunQueue()) { ret=(*cpudecoder)(); - if (ret<0) return 1; + if (GCC_UNLIKELY(ret<0)) return 1; if (ret>0) { Bitu blah=(*CallBack_Handlers[ret])(); - if (blah) return blah; + if (GCC_UNLIKELY(blah)) return blah; } #if C_DEBUG if (DEBUG_ExitLoop()) return 0; @@ -509,10 +509,10 @@ void DOSBOX_Init(void) { Pstring->Set_values(oplmodes); Pstring->Set_help("Type of OPL emulation. On 'auto' the mode is determined by sblaster type. All OPL modes are Adlib-compatible, except for 'cms'."); - const char* oplemus[]={ "default", "compat", "fast", "old", 0}; + const char* oplemus[]={ "default", "compat", "fast", 0}; Pstring = secprop->Add_string("oplemu",Property::Changeable::WhenIdle,"default"); Pstring->Set_values(oplemus); - Pstring->Set_help("Provider for the OPL emulation. compat or old might provide better quality (see oplrate as well)."); + Pstring->Set_help("Provider for the OPL emulation. compat might provide better quality (see oplrate as well)."); Pint = secprop->Add_int("oplrate",Property::Changeable::WhenIdle,22050); Pint->Set_values(oplrates); diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index 51851435..5631a06d 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -2,7 +2,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include SUBDIRS = serialport -EXTRA_DIST = opl.cpp opl.h fmopl.c fmopl.h ymf262.h ymf262.c adlib.h dbopl.h +EXTRA_DIST = opl.cpp opl.h adlib.h dbopl.h noinst_LIBRARIES = libhardware.a diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 0500b95a..c3995a37 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: adlib.cpp,v 1.41 2009-05-16 08:29:05 harekiet Exp $ */ +/* $Id: adlib.cpp,v 1.42 2009-11-03 20:17:42 qbix79 Exp $ */ #include #include @@ -29,32 +29,6 @@ #include "mem.h" #include "dbopl.h" -/* - Thanks to vdmsound for nice simple way to implement this -*/ - -#ifdef _MSC_VER - /* Disable recurring warnings */ -# pragma warning ( disable : 4018 ) -# pragma warning ( disable : 4244 ) -#endif - - -#define logerror - - -struct __MALLOCPTR { - void* m_ptr; - - __MALLOCPTR(void) : m_ptr(NULL) { } - __MALLOCPTR(void* src) : m_ptr(src) { } - void* operator=(void* rhs) { return (m_ptr = rhs); } - operator int*() const { return (int*)m_ptr; } - operator int**() const { return (int**)m_ptr; } - operator char*() const { return (char*)m_ptr; } -}; - - namespace OPL2 { #include "opl.cpp" @@ -112,78 +86,6 @@ namespace OPL3 { }; } - -namespace old_OPL2 { - #define OPL2_INTERNAL_FREQ 3579545 // The OPL2 operates at ~3.6MHz - #define HAS_YM3812 1 - #include "fmopl.c" - - struct Handler : public Adlib::Handler { - virtual void WriteReg( Bit32u reg, Bit8u val ) { - OPLWriteReg( OPL_YM3812[ 0 ], reg, val ); - } - virtual Bit32u WriteAddr( Bit32u port, Bit8u val ) { - OPL_YM3812[ 0 ]->address = val; - return val; - } - - virtual void Generate( MixerChannel* chan, Bitu samples ) { - Bit16s buf[1024]; - while( samples > 0 ) { - Bitu todo = samples > 1024 ? 1024 : samples; - samples -= todo; - YM3812UpdateOne( 0, buf, todo ); - chan->AddSamples_m16( todo, buf ); - } - } - virtual void Init( Bitu rate ) { - if ( YM3812Init( 1, OPL2_INTERNAL_FREQ, rate )) { - E_Exit("Can't create OPL2 Emulator"); - }; - } - ~Handler() { - YM3812Shutdown(); - } - }; -} -#undef OSD_CPU_H -#undef TL_TAB_LEN - -namespace old_OPL3 { - #define OPL3_INTERNAL_FREQ 14318180 // The OPL3 operates at ~14.3MHz - #define HAS_YMF262 1 - #include "ymf262.c" - - struct Handler : public Adlib::Handler { - virtual void WriteReg( Bit32u reg, Bit8u val ) { - OPL3WriteReg( YMF262[0], reg, val ); - } - virtual Bit32u WriteAddr( Bit32u port, Bit8u val ) { - OPL3Write( YMF262[0], port, val ); - return YMF262[0]->address; - } - virtual void Generate( MixerChannel* chan, Bitu samples ) { - Bit16s buf[2][1024]; - while( samples > 0 ) { - Bitu todo = samples > 1024 ? 1024 : samples; - samples -= todo; - YMF262UpdateOne( 0, buf[0], todo ); - chan->AddSamples_s16( todo, buf[0] ); - } - } - virtual void Init( Bitu rate ) { - if ( YMF262Init( 1, OPL3_INTERNAL_FREQ, rate )) { - E_Exit("Can't create OPL3 Emulator"); - }; - } - ~Handler() { - YMF262Shutdown(); - } - }; -} - - - #define RAW_SIZE 1024 @@ -736,13 +638,7 @@ Module::Module( Section* configuration ) : Module_base(configuration) { mixerChan = mixerObject.Install(OPL_CallBack,rate,"FM"); mixerChan->SetScale( 2.0 ); - if (oplemu == "old") { - if ( oplmode == OPL_opl2 ) { - handler = new old_OPL2::Handler(); - } else { - handler = new old_OPL3::Handler(); - } - } else if (oplemu == "fast") { + if (oplemu == "fast") { handler = new DBOPL::Handler(); } else if (oplemu == "compat") { if ( oplmode == OPL_opl2 ) { diff --git a/src/hardware/fmopl.c b/src/hardware/fmopl.c deleted file mode 100644 index 2d7ff38e..00000000 --- a/src/hardware/fmopl.c +++ /dev/null @@ -1,2524 +0,0 @@ -/* -** -** File: fmopl.c - software implementation of FM sound generator -** types OPL and OPL2 -** -** Copyright (C) 2002,2003 Jarek Burczynski (bujar at mame dot net) -** Copyright (C) 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmulator development -** -** Version 0.70 -** - -Revision History: - -14-06-2003 Jarek Burczynski: - - implemented all of the status register flags in Y8950 emulation - - renamed Y8950SetDeltaTMemory() parameters from _rom_ to _mem_ since - they can be either RAM or ROM - -08-10-2002 Jarek Burczynski (thanks to Dox for the YM3526 chip) - - corrected YM3526Read() to always set bit 2 and bit 1 - to HIGH state - identical to YM3812Read (verified on real YM3526) - -04-28-2002 Jarek Burczynski: - - binary exact Envelope Generator (verified on real YM3812); - compared to YM2151: the EG clock is equal to internal_clock, - rates are 2 times slower and volume resolution is one bit less - - modified interface functions (they no longer return pointer - - that's internal to the emulator now): - - new wrapper functions for OPLCreate: YM3526Init(), YM3812Init() and Y8950Init() - - corrected 'off by one' error in feedback calculations (when feedback is off) - - enabled waveform usage (credit goes to Vlad Romascanu and zazzal22) - - speeded up noise generator calculations (Nicola Salmoria) - -03-24-2002 Jarek Burczynski (thanks to Dox for the YM3812 chip) - Complete rewrite (all verified on real YM3812): - - corrected sin_tab and tl_tab data - - corrected operator output calculations - - corrected waveform_select_enable register; - simply: ignore all writes to waveform_select register when - waveform_select_enable == 0 and do not change the waveform previously selected. - - corrected KSR handling - - corrected Envelope Generator: attack shape, Sustain mode and - Percussive/Non-percussive modes handling - - Envelope Generator rates are two times slower now - - LFO amplitude (tremolo) and phase modulation (vibrato) - - rhythm sounds phase generation - - white noise generator (big thanks to Olivier Galibert for mentioning Berlekamp-Massey algorithm) - - corrected key on/off handling (the 'key' signal is ORed from three sources: FM, rhythm and CSM) - - funky details (like ignoring output of operator 1 in BD rhythm sound when connect == 1) - -12-28-2001 Acho A. Tang - - reflected Delta-T EOS status on Y8950 status port. - - fixed subscription range of attack/decay tables - - - To do: - add delay before key off in CSM mode (see CSMKeyControll) - verify volume of the FM part on the Y8950 -*/ - -#include -#include -#include - -//#include "driver.h" /* use M.A.M.E. */ -#include "fmopl.h" - -#ifndef PI -#define PI 3.14159265358979323846 -#endif - - - -/* output final shift */ -#if (OPL_SAMPLE_BITS==16) - #define FINAL_SH (0) - #define MAXOUT (+32767) - #define MINOUT (-32768) -#else - #define FINAL_SH (8) - #define MAXOUT (+127) - #define MINOUT (-128) -#endif - - -#define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */ -#define EG_SH 16 /* 16.16 fixed point (EG timing) */ -#define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */ -#define TIMER_SH 16 /* 16.16 fixed point (timers calculations) */ - -#define FREQ_MASK ((1<=0) - { - if (value < 0x0200) - return (value & ~0); - if (value < 0x0400) - return (value & ~1); - if (value < 0x0800) - return (value & ~3); - if (value < 0x1000) - return (value & ~7); - if (value < 0x2000) - return (value & ~15); - if (value < 0x4000) - return (value & ~31); - return (value & ~63); - } - /*else value < 0*/ - if (value > -0x0200) - return (~abs(value) & ~0); - if (value > -0x0400) - return (~abs(value) & ~1); - if (value > -0x0800) - return (~abs(value) & ~3); - if (value > -0x1000) - return (~abs(value) & ~7); - if (value > -0x2000) - return (~abs(value) & ~15); - if (value > -0x4000) - return (~abs(value) & ~31); - return (~abs(value) & ~63); -} - - -static FILE *sample[1]; - #if 1 /*save to MONO file */ - #define SAVE_ALL_CHANNELS \ - { signed int pom = acc_calc(lt); \ - fputc((unsigned short)pom&0xff,sample[0]); \ - fputc(((unsigned short)pom>>8)&0xff,sample[0]); \ - } - #else /*save to STEREO file */ - #define SAVE_ALL_CHANNELS \ - { signed int pom = lt; \ - fputc((unsigned short)pom&0xff,sample[0]); \ - fputc(((unsigned short)pom>>8)&0xff,sample[0]); \ - pom = rt; \ - fputc((unsigned short)pom&0xff,sample[0]); \ - fputc(((unsigned short)pom>>8)&0xff,sample[0]); \ - } - #endif -#endif - -/* #define LOG_CYM_FILE */ -#ifdef LOG_CYM_FILE - FILE * cymfile = NULL; -#endif - - - -#define OPL_TYPE_WAVESEL 0x01 /* waveform select */ -#define OPL_TYPE_ADPCM 0x02 /* DELTA-T ADPCM unit */ -#define OPL_TYPE_KEYBOARD 0x04 /* keyboard interface */ -#define OPL_TYPE_IO 0x08 /* I/O port */ - -/* ---------- Generic interface section ---------- */ -#define OPL_TYPE_YM3526 (0) -#define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL) -#define OPL_TYPE_Y8950 (OPL_TYPE_ADPCM|OPL_TYPE_KEYBOARD|OPL_TYPE_IO) - - - -typedef struct{ - UINT32 ar; /* attack rate: AR<<2 */ - UINT32 dr; /* decay rate: DR<<2 */ - UINT32 rr; /* release rate:RR<<2 */ - UINT8 KSR; /* key scale rate */ - UINT8 ksl; /* keyscale level */ - UINT8 ksr; /* key scale rate: kcode>>KSR */ - UINT8 mul; /* multiple: mul_tab[ML] */ - - /* Phase Generator */ - UINT32 Cnt; /* frequency counter */ - UINT32 Incr; /* frequency counter step */ - UINT8 FB; /* feedback shift value */ - INT32 *connect1; /* slot1 output pointer */ - INT32 op1_out[2]; /* slot1 output for feedback */ - UINT8 CON; /* connection (algorithm) type */ - - /* Envelope Generator */ - UINT8 eg_type; /* percussive/non-percussive mode */ - UINT8 state; /* phase type */ - UINT32 TL; /* total level: TL << 2 */ - INT32 TLL; /* adjusted now TL */ - INT32 volume; /* envelope counter */ - UINT32 sl; /* sustain level: sl_tab[SL] */ - UINT8 eg_sh_ar; /* (attack state) */ - UINT8 eg_sel_ar; /* (attack state) */ - UINT8 eg_sh_dr; /* (decay state) */ - UINT8 eg_sel_dr; /* (decay state) */ - UINT8 eg_sh_rr; /* (release state) */ - UINT8 eg_sel_rr; /* (release state) */ - UINT32 key; /* 0 = KEY OFF, >0 = KEY ON */ - - /* LFO */ - UINT32 AMmask; /* LFO Amplitude Modulation enable mask */ - UINT8 vib; /* LFO Phase Modulation enable flag (active high)*/ - - /* waveform select */ - unsigned int wavetable; -} OPL_SLOT; - -typedef struct{ - OPL_SLOT SLOT[2]; - /* phase generator state */ - UINT32 block_fnum; /* block+fnum */ - UINT32 fc; /* Freq. Increment base */ - UINT32 ksl_base; /* KeyScaleLevel Base step */ - UINT8 kcode; /* key code (for key scaling) */ -} OPL_CH; - -/* OPL state */ -typedef struct fm_opl_f { - /* FM channel slots */ - OPL_CH P_CH[9]; /* OPL/OPL2 chips have 9 channels*/ - - UINT32 eg_cnt; /* global envelope generator counter */ - UINT32 eg_timer; /* global envelope generator counter works at frequency = chipclock/72 */ - UINT32 eg_timer_add; /* step of eg_timer */ - UINT32 eg_timer_overflow; /* envelope generator timer overlfows every 1 sample (on real chip) */ - - UINT8 rhythm; /* Rhythm mode */ - - UINT32 fn_tab[1024]; /* fnumber->increment counter */ - - /* LFO */ - UINT8 lfo_am_depth; - UINT8 lfo_pm_depth_range; - UINT32 lfo_am_cnt; - UINT32 lfo_am_inc; - UINT32 lfo_pm_cnt; - UINT32 lfo_pm_inc; - - UINT32 noise_rng; /* 23 bit noise shift register */ - UINT32 noise_p; /* current noise 'phase' */ - UINT32 noise_f; /* current noise period */ - - UINT8 wavesel; /* waveform select enable flag */ - - int T[2]; /* timer counters */ - int TC[2]; - UINT8 st[2]; /* timer enable */ - -#if BUILD_Y8950 - /* Delta-T ADPCM unit (Y8950) */ - - YM_DELTAT *deltat; - - /* Keyboard and I/O ports interface */ - UINT8 portDirection; - UINT8 portLatch; - OPL_PORTHANDLER_R porthandler_r; - OPL_PORTHANDLER_W porthandler_w; - int port_param; - OPL_PORTHANDLER_R keyboardhandler_r; - OPL_PORTHANDLER_W keyboardhandler_w; - int keyboard_param; -#endif - - /* external event callback handlers */ - OPL_TIMERHANDLER TimerHandler; /* TIMER handler */ - int TimerParam; /* TIMER parameter */ - OPL_IRQHANDLER IRQHandler; /* IRQ handler */ - int IRQParam; /* IRQ parameter */ - OPL_UPDATEHANDLER UpdateHandler;/* stream update handler */ - int UpdateParam; /* stream update parameter */ - - UINT8 type; /* chip type */ - UINT8 address; /* address register */ - UINT8 status; /* status flag */ - UINT8 statusmask; /* status mask */ - UINT8 mode; /* Reg.08 : CSM,notesel,etc. */ - - int clock; /* master clock (Hz) */ - int rate; /* sampling rate (Hz) */ - double freqbase; /* frequency base */ - double TimerBase; /* Timer base time (==sampling time)*/ -} FM_OPL; - - - -/* mapping of register number (offset) to slot number used by the emulator */ -static const int slot_array[32]= -{ - 0, 2, 4, 1, 3, 5,-1,-1, - 6, 8,10, 7, 9,11,-1,-1, - 12,14,16,13,15,17,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1 -}; - -/* key scale level */ -/* table is 3dB/octave , DV converts this into 6dB/octave */ -/* 0.1875 is bit 0 weight of the envelope counter (volume) expressed in the 'decibel' scale */ -#define SC(x) ((UINT32)((x)/(0.1875/2.0))) -static const UINT32 ksl_tab[8*16]= -{ - /* OCT 0 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - /* OCT 1 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.750), SC(1.125), SC(1.500), - SC(1.875), SC(2.250), SC(2.625), SC(3.000), - /* OCT 2 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(1.125), SC(1.875), SC(2.625), - SC(3.000), SC(3.750), SC(4.125), SC(4.500), - SC(4.875), SC(5.250), SC(5.625), SC(6.000), - /* OCT 3 */ - SC(0.000), SC(0.000), SC(0.000), SC(1.875), - SC(3.000), SC(4.125), SC(4.875), SC(5.625), - SC(6.000), SC(6.750), SC(7.125), SC(7.500), - SC(7.875), SC(8.250), SC(8.625), SC(9.000), - /* OCT 4 */ - SC(0.000), SC(0.000), SC(3.000), SC(4.875), - SC(6.000), SC(7.125), SC(7.875), SC(8.625), - SC(9.000), SC(9.750),SC(10.125),SC(10.500), - SC(10.875),SC(11.250),SC(11.625),SC(12.000), - /* OCT 5 */ - SC(0.000), SC(3.000), SC(6.000), SC(7.875), - SC(9.000),SC(10.125),SC(10.875),SC(11.625), - SC(12.000),SC(12.750),SC(13.125),SC(13.500), - SC(13.875),SC(14.250),SC(14.625),SC(15.000), - /* OCT 6 */ - SC(0.000), SC(6.000), SC(9.000),SC(10.875), - SC(12.000),SC(13.125),SC(13.875),SC(14.625), - SC(15.000),SC(15.750),SC(16.125),SC(16.500), - SC(16.875),SC(17.250),SC(17.625),SC(18.000), - /* OCT 7 */ - SC(0.000), SC(9.000),SC(12.000),SC(13.875), - SC(15.000),SC(16.125),SC(16.875),SC(17.625), - SC(18.000),SC(18.750),SC(19.125),SC(19.500), - SC(19.875),SC(20.250),SC(20.625),SC(21.000) -}; -#undef SC - -/* key scale level lookup */ -static const INT32 ksl_level[4]= -{ - 31,1,2,0 -}; - -/* sustain level table (3dB per step) */ -/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ -#define SC(db) (UINT32) ( db * (2.0/ENV_STEP) ) -static const UINT32 sl_tab[16]={ - SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7), - SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31) -}; -#undef SC - - -#define RATE_STEPS (8) -static const unsigned char eg_inc[15*RATE_STEPS]={ - -/*cycle:0 1 2 3 4 5 6 7*/ - -/* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..12 0 (increment by 0 or 1) */ -/* 1 */ 0,1, 0,1, 1,1, 0,1, /* rates 00..12 1 */ -/* 2 */ 0,1, 1,1, 0,1, 1,1, /* rates 00..12 2 */ -/* 3 */ 0,1, 1,1, 1,1, 1,1, /* rates 00..12 3 */ - -/* 4 */ 1,1, 1,1, 1,1, 1,1, /* rate 13 0 (increment by 1) */ -/* 5 */ 1,1, 1,2, 1,1, 1,2, /* rate 13 1 */ -/* 6 */ 1,2, 1,2, 1,2, 1,2, /* rate 13 2 */ -/* 7 */ 1,2, 2,2, 1,2, 2,2, /* rate 13 3 */ - -/* 8 */ 2,2, 2,2, 2,2, 2,2, /* rate 14 0 (increment by 2) */ -/* 9 */ 2,2, 2,4, 2,2, 2,4, /* rate 14 1 */ -/*10 */ 2,4, 2,4, 2,4, 2,4, /* rate 14 2 */ -/*11 */ 2,4, 4,4, 2,4, 4,4, /* rate 14 3 */ - -/*12 */ 4,4, 4,4, 4,4, 4,4, /* rates 15 0, 15 1, 15 2, 15 3 (increment by 4) */ -/*13 */ 8,8, 8,8, 8,8, 8,8, /* rates 15 2, 15 3 for attack */ -/*14 */ 0,0, 0,0, 0,0, 0,0, /* infinity rates for attack and decay(s) */ -}; - - -#define O(a) (a*RATE_STEPS) - -/*note that there is no O(13) in this table - it's directly in the code */ -static const unsigned char eg_rate_select[16+64+16]={ /* Envelope Generator rates (16 + 64 rates + 16 RKS) */ -/* 16 infinite time rates */ -O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), -O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), - -/* rates 00-12 */ -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), - -/* rate 13 */ -O( 4),O( 5),O( 6),O( 7), - -/* rate 14 */ -O( 8),O( 9),O(10),O(11), - -/* rate 15 */ -O(12),O(12),O(12),O(12), - -/* 16 dummy rates (same as 15 3) */ -O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12), -O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12), - -}; -#undef O - -/*rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 */ -/*shift 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0 */ -/*mask 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0, 0 */ - -#define O(a) (a*1) -static const unsigned char eg_rate_shift[16+64+16]={ /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */ -/* 16 infinite time rates */ -O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), -O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), - -/* rates 00-12 */ -O(12),O(12),O(12),O(12), -O(11),O(11),O(11),O(11), -O(10),O(10),O(10),O(10), -O( 9),O( 9),O( 9),O( 9), -O( 8),O( 8),O( 8),O( 8), -O( 7),O( 7),O( 7),O( 7), -O( 6),O( 6),O( 6),O( 6), -O( 5),O( 5),O( 5),O( 5), -O( 4),O( 4),O( 4),O( 4), -O( 3),O( 3),O( 3),O( 3), -O( 2),O( 2),O( 2),O( 2), -O( 1),O( 1),O( 1),O( 1), -O( 0),O( 0),O( 0),O( 0), - -/* rate 13 */ -O( 0),O( 0),O( 0),O( 0), - -/* rate 14 */ -O( 0),O( 0),O( 0),O( 0), - -/* rate 15 */ -O( 0),O( 0),O( 0),O( 0), - -/* 16 dummy rates (same as 15 3) */ -O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), -O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), - -}; -#undef O - - -/* multiple table */ -#define SC(x) ((UINT32)((x)*2)) -static const UINT8 mul_tab[16]= { -/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,10,12,12,15,15 */ - SC(0.50), SC(1.00), SC(2.00), SC(3.00), SC(4.00), SC(5.00), SC(6.00), SC(7.00), - SC(8.00), SC(9.00),SC(10.00),SC(10.00),SC(12.00),SC(12.00),SC(15.00),SC(15.00) -}; -#undef SC - -/* TL_TAB_LEN is calculated as: -* 12 - sinus amplitude bits (Y axis) -* 2 - sinus sign bit (Y axis) -* TL_RES_LEN - sinus resolution (X axis) -*/ -#define TL_TAB_LEN (12*2*TL_RES_LEN) -static signed int tl_tab[TL_TAB_LEN]; - -#define ENV_QUIET (TL_TAB_LEN>>4) - -/* sin waveform table in 'decibel' scale */ -/* four waveforms on OPL2 type chips */ -static unsigned int sin_tab[SIN_LEN * 4]; - - -/* LFO Amplitude Modulation table (verified on real YM3812) - 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples - - Length: 210 elements. - - Each of the elements has to be repeated - exactly 64 times (on 64 consecutive samples). - The whole table takes: 64 * 210 = 13440 samples. - - When AM = 1 data is used directly - When AM = 0 data is divided by 4 before being used (loosing precision is important) -*/ - -#define LFO_AM_TAB_ELEMENTS 210 - -static const UINT8 lfo_am_table[LFO_AM_TAB_ELEMENTS] = { -0,0,0,0,0,0,0, -1,1,1,1, -2,2,2,2, -3,3,3,3, -4,4,4,4, -5,5,5,5, -6,6,6,6, -7,7,7,7, -8,8,8,8, -9,9,9,9, -10,10,10,10, -11,11,11,11, -12,12,12,12, -13,13,13,13, -14,14,14,14, -15,15,15,15, -16,16,16,16, -17,17,17,17, -18,18,18,18, -19,19,19,19, -20,20,20,20, -21,21,21,21, -22,22,22,22, -23,23,23,23, -24,24,24,24, -25,25,25,25, -26,26,26, -25,25,25,25, -24,24,24,24, -23,23,23,23, -22,22,22,22, -21,21,21,21, -20,20,20,20, -19,19,19,19, -18,18,18,18, -17,17,17,17, -16,16,16,16, -15,15,15,15, -14,14,14,14, -13,13,13,13, -12,12,12,12, -11,11,11,11, -10,10,10,10, -9,9,9,9, -8,8,8,8, -7,7,7,7, -6,6,6,6, -5,5,5,5, -4,4,4,4, -3,3,3,3, -2,2,2,2, -1,1,1,1 -}; - -/* LFO Phase Modulation table (verified on real YM3812) */ -static const INT8 lfo_pm_table[8*8*2] = { - -/* FNUM2/FNUM = 00 0xxxxxxx (0x0000) */ -0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/ -0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 00 1xxxxxxx (0x0080) */ -0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/ -1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 01 0xxxxxxx (0x0100) */ -1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/ -2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 01 1xxxxxxx (0x0180) */ -1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/ -3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 10 0xxxxxxx (0x0200) */ -2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/ -4, 2, 0,-2,-4,-2, 0, 2, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 10 1xxxxxxx (0x0280) */ -2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/ -5, 2, 0,-2,-5,-2, 0, 2, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 11 0xxxxxxx (0x0300) */ -3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/ -6, 3, 0,-3,-6,-3, 0, 3, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 11 1xxxxxxx (0x0380) */ -3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/ -7, 3, 0,-3,-7,-3, 0, 3 /*LFO PM depth = 1*/ -}; - - -/* lock level of common table */ -static int num_lock = 0; - - -static void *cur_chip = NULL; /* current chip pointer */ -static OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2; - -static signed int phase_modulation; /* phase modulation input (SLOT 2) */ -static signed int output[1]; - -#if BUILD_Y8950 -static INT32 output_deltat[4]; /* for Y8950 DELTA-T, chip is mono, that 4 here is just for safety */ -#endif - -static UINT32 LFO_AM; -static INT32 LFO_PM; - - - -INLINE int limit( int val, int max, int min ) { - if ( val > max ) - val = max; - else if ( val < min ) - val = min; - - return val; -} - - -/* status set and IRQ handling */ -INLINE void OPL_STATUS_SET(FM_OPL *OPL,int flag) -{ - /* set status flag */ - OPL->status |= flag; - if(!(OPL->status & 0x80)) - { - if(OPL->status & OPL->statusmask) - { /* IRQ on */ - OPL->status |= 0x80; - /* callback user interrupt handler (IRQ is OFF to ON) */ - if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1); - } - } -} - -/* status reset and IRQ handling */ -INLINE void OPL_STATUS_RESET(FM_OPL *OPL,int flag) -{ - /* reset status flag */ - OPL->status &=~flag; - if((OPL->status & 0x80)) - { - if (!(OPL->status & OPL->statusmask) ) - { - OPL->status &= 0x7f; - /* callback user interrupt handler (IRQ is ON to OFF) */ - if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0); - } - } -} - -/* IRQ mask set */ -INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag) -{ - OPL->statusmask = flag; - /* IRQ handling check */ - OPL_STATUS_SET(OPL,0); - OPL_STATUS_RESET(OPL,0); -} - - -/* advance LFO to next sample */ -INLINE void advance_lfo(FM_OPL *OPL) -{ - UINT8 tmp; - - /* LFO */ - OPL->lfo_am_cnt += OPL->lfo_am_inc; - if (OPL->lfo_am_cnt >= (LFO_AM_TAB_ELEMENTS<lfo_am_cnt -= (LFO_AM_TAB_ELEMENTS<lfo_am_cnt >> LFO_SH ]; - - if (OPL->lfo_am_depth) - LFO_AM = tmp; - else - LFO_AM = tmp>>2; - - OPL->lfo_pm_cnt += OPL->lfo_pm_inc; - LFO_PM = ((OPL->lfo_pm_cnt>>LFO_SH) & 7) | OPL->lfo_pm_depth_range; -} - -/* advance to next sample */ -INLINE void advance(FM_OPL *OPL) -{ - OPL_CH *CH; - OPL_SLOT *op; - int i; - - OPL->eg_timer += OPL->eg_timer_add; - - while (OPL->eg_timer >= OPL->eg_timer_overflow) - { - OPL->eg_timer -= OPL->eg_timer_overflow; - - OPL->eg_cnt++; - - for (i=0; i<9*2; i++) - { - CH = &OPL->P_CH[i/2]; - op = &CH->SLOT[i&1]; - - /* Envelope Generator */ - switch(op->state) - { - case EG_ATT: /* attack phase */ - if ( !(OPL->eg_cnt & ((1<eg_sh_ar)-1) ) ) - { - op->volume += (~op->volume * - (eg_inc[op->eg_sel_ar + ((OPL->eg_cnt>>op->eg_sh_ar)&7)]) - ) >>3; - - if (op->volume <= MIN_ATT_INDEX) - { - op->volume = MIN_ATT_INDEX; - op->state = EG_DEC; - } - - } - break; - - case EG_DEC: /* decay phase */ - if ( !(OPL->eg_cnt & ((1<eg_sh_dr)-1) ) ) - { - op->volume += eg_inc[op->eg_sel_dr + ((OPL->eg_cnt>>op->eg_sh_dr)&7)]; - - if ( op->volume >= op->sl ) - op->state = EG_SUS; - - } - break; - - case EG_SUS: /* sustain phase */ - - /* this is important behaviour: - one can change percusive/non-percussive modes on the fly and - the chip will remain in sustain phase - verified on real YM3812 */ - - if(op->eg_type) /* non-percussive mode */ - { - /* do nothing */ - } - else /* percussive mode */ - { - /* during sustain phase chip adds Release Rate (in percussive mode) */ - if ( !(OPL->eg_cnt & ((1<eg_sh_rr)-1) ) ) - { - op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt>>op->eg_sh_rr)&7)]; - - if ( op->volume >= MAX_ATT_INDEX ) - op->volume = MAX_ATT_INDEX; - } - /* else do nothing in sustain phase */ - } - break; - - case EG_REL: /* release phase */ - if ( !(OPL->eg_cnt & ((1<eg_sh_rr)-1) ) ) - { - op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt>>op->eg_sh_rr)&7)]; - - if ( op->volume >= MAX_ATT_INDEX ) - { - op->volume = MAX_ATT_INDEX; - op->state = EG_OFF; - } - - } - break; - - default: - break; - } - } - } - - for (i=0; i<9*2; i++) - { - CH = &OPL->P_CH[i/2]; - op = &CH->SLOT[i&1]; - - /* Phase Generator */ - if(op->vib) - { - UINT8 block; - unsigned int block_fnum = CH->block_fnum; - - unsigned int fnum_lfo = (block_fnum&0x0380) >> 7; - - signed int lfo_fn_table_index_offset = lfo_pm_table[LFO_PM + 16*fnum_lfo ]; - - if (lfo_fn_table_index_offset) /* LFO phase modulation active */ - { - block_fnum += lfo_fn_table_index_offset; - block = (block_fnum&0x1c00) >> 10; - op->Cnt += (OPL->fn_tab[block_fnum&0x03ff] >> (7-block)) * op->mul; - } - else /* LFO phase modulation = zero */ - { - op->Cnt += op->Incr; - } - } - else /* LFO phase modulation disabled for this operator */ - { - op->Cnt += op->Incr; - } - } - - /* The Noise Generator of the YM3812 is 23-bit shift register. - * Period is equal to 2^23-2 samples. - * Register works at sampling frequency of the chip, so output - * can change on every sample. - * - * Output of the register and input to the bit 22 is: - * bit0 XOR bit14 XOR bit15 XOR bit22 - * - * Simply use bit 22 as the noise output. - */ - - OPL->noise_p += OPL->noise_f; - i = OPL->noise_p >> FREQ_SH; /* number of events (shifts of the shift register) */ - OPL->noise_p &= FREQ_MASK; - while (i) - { - /* - UINT32 j; - j = ( (OPL->noise_rng) ^ (OPL->noise_rng>>14) ^ (OPL->noise_rng>>15) ^ (OPL->noise_rng>>22) ) & 1; - OPL->noise_rng = (j<<22) | (OPL->noise_rng>>1); - */ - - /* - Instead of doing all the logic operations above, we - use a trick here (and use bit 0 as the noise output). - The difference is only that the noise bit changes one - step ahead. This doesn't matter since we don't know - what is real state of the noise_rng after the reset. - */ - - if (OPL->noise_rng & 1) OPL->noise_rng ^= 0x800302; - OPL->noise_rng >>= 1; - - i--; - } -} - - -INLINE signed int op_calc(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab) -{ - UINT32 p; - - p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + (pm<<16))) >> FREQ_SH ) & SIN_MASK) ]; - - if (p >= TL_TAB_LEN) - return 0; - return tl_tab[p]; -} - -INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab) -{ - UINT32 p; - - p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + pm )) >> FREQ_SH ) & SIN_MASK) ]; - - if (p >= TL_TAB_LEN) - return 0; - return tl_tab[p]; -} - - -#define volume_calc(OP) ((OP)->TLL + ((UINT32)(OP)->volume) + (LFO_AM & (OP)->AMmask)) - -/* calculate output */ -INLINE void OPL_CALC_CH( OPL_CH *CH ) -{ - OPL_SLOT *SLOT; - unsigned int env; - signed int out; - - phase_modulation = 0; - - /* SLOT 1 */ - SLOT = &CH->SLOT[SLOT1]; - env = volume_calc(SLOT); - out = SLOT->op1_out[0] + SLOT->op1_out[1]; - SLOT->op1_out[0] = SLOT->op1_out[1]; - *SLOT->connect1 += SLOT->op1_out[0]; - SLOT->op1_out[1] = 0; - if( env < ENV_QUIET ) - { - if (!SLOT->FB) - out = 0; - SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB), SLOT->wavetable ); - } - - /* SLOT 2 */ - SLOT++; - env = volume_calc(SLOT); - if( env < ENV_QUIET ) - output[0] += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable); -} - -/* - operators used in the rhythm sounds generation process: - - Envelope Generator: - -channel operator register number Bass High Snare Tom Top -/ slot number TL ARDR SLRR Wave Drum Hat Drum Tom Cymbal - 6 / 0 12 50 70 90 f0 + - 6 / 1 15 53 73 93 f3 + - 7 / 0 13 51 71 91 f1 + - 7 / 1 16 54 74 94 f4 + - 8 / 0 14 52 72 92 f2 + - 8 / 1 17 55 75 95 f5 + - - Phase Generator: - -channel operator register number Bass High Snare Tom Top -/ slot number MULTIPLE Drum Hat Drum Tom Cymbal - 6 / 0 12 30 + - 6 / 1 15 33 + - 7 / 0 13 31 + + + - 7 / 1 16 34 ----- n o t u s e d ----- - 8 / 0 14 32 + - 8 / 1 17 35 + + - -channel operator register number Bass High Snare Tom Top -number number BLK/FNUM2 FNUM Drum Hat Drum Tom Cymbal - 6 12,15 B6 A6 + - - 7 13,16 B7 A7 + + + - - 8 14,17 B8 A8 + + + - -*/ - -/* calculate rhythm */ - -INLINE void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) -{ - OPL_SLOT *SLOT; - signed int out; - unsigned int env; - - - /* Bass Drum (verified on real YM3812): - - depends on the channel 6 'connect' register: - when connect = 0 it works the same as in normal (non-rhythm) mode (op1->op2->out) - when connect = 1 _only_ operator 2 is present on output (op2->out), operator 1 is ignored - - output sample always is multiplied by 2 - */ - - phase_modulation = 0; - /* SLOT 1 */ - SLOT = &CH[6].SLOT[SLOT1]; - env = volume_calc(SLOT); - - out = SLOT->op1_out[0] + SLOT->op1_out[1]; - SLOT->op1_out[0] = SLOT->op1_out[1]; - - if (!SLOT->CON) - phase_modulation = SLOT->op1_out[0]; - /* else ignore output of operator 1 */ - - SLOT->op1_out[1] = 0; - if( env < ENV_QUIET ) - { - if (!SLOT->FB) - out = 0; - SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB), SLOT->wavetable ); - } - - /* SLOT 2 */ - SLOT++; - env = volume_calc(SLOT); - if( env < ENV_QUIET ) - output[0] += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable) * 2; - - - /* Phase generation is based on: */ - /* HH (13) channel 7->slot 1 combined with channel 8->slot 2 (same combination as TOP CYMBAL but different output phases) */ - /* SD (16) channel 7->slot 1 */ - /* TOM (14) channel 8->slot 1 */ - /* TOP (17) channel 7->slot 1 combined with channel 8->slot 2 (same combination as HIGH HAT but different output phases) */ - - /* Envelope generation based on: */ - /* HH channel 7->slot1 */ - /* SD channel 7->slot2 */ - /* TOM channel 8->slot1 */ - /* TOP channel 8->slot2 */ - - - /* The following formulas can be well optimized. - I leave them in direct form for now (in case I've missed something). - */ - - /* High Hat (verified on real YM3812) */ - env = volume_calc(SLOT7_1); - if( env < ENV_QUIET ) - { - - /* high hat phase generation: - phase = d0 or 234 (based on frequency only) - phase = 34 or 2d0 (based on noise) - */ - - /* base frequency derived from operator 1 in channel 7 */ - unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1; - unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1; - unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1; - - unsigned char res1 = (bit2 ^ bit7) | bit3; - - /* when res1 = 0 phase = 0x000 | 0xd0; */ - /* when res1 = 1 phase = 0x200 | (0xd0>>2); */ - UINT32 phase = res1 ? (0x200|(0xd0>>2)) : 0xd0; - - /* enable gate based on frequency of operator 2 in channel 8 */ - unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1; - unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1; - - unsigned char res2 = (bit3e ^ bit5e); - - /* when res2 = 0 pass the phase from calculation above (res1); */ - /* when res2 = 1 phase = 0x200 | (0xd0>>2); */ - if (res2) - phase = (0x200|(0xd0>>2)); - - - /* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */ - /* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */ - if (phase&0x200) - { - if (noise) - phase = 0x200|0xd0; - } - else - /* when phase & 0x200 is clear and noise=1 then phase = 0xd0>>2 */ - /* when phase & 0x200 is clear and noise=0 then phase = 0xd0, ie no change */ - { - if (noise) - phase = 0xd0>>2; - } - - output[0] += op_calc(phase<wavetable) * 2; - } - - /* Snare Drum (verified on real YM3812) */ - env = volume_calc(SLOT7_2); - if( env < ENV_QUIET ) - { - /* base frequency derived from operator 1 in channel 7 */ - unsigned char bit8 = ((SLOT7_1->Cnt>>FREQ_SH)>>8)&1; - - /* when bit8 = 0 phase = 0x100; */ - /* when bit8 = 1 phase = 0x200; */ - UINT32 phase = bit8 ? 0x200 : 0x100; - - /* Noise bit XOR'es phase by 0x100 */ - /* when noisebit = 0 pass the phase from calculation above */ - /* when noisebit = 1 phase ^= 0x100; */ - /* in other words: phase ^= (noisebit<<8); */ - if (noise) - phase ^= 0x100; - - output[0] += op_calc(phase<wavetable) * 2; - } - - /* Tom Tom (verified on real YM3812) */ - env = volume_calc(SLOT8_1); - if( env < ENV_QUIET ) - output[0] += op_calc(SLOT8_1->Cnt, env, 0, SLOT8_1->wavetable) * 2; - - /* Top Cymbal (verified on real YM3812) */ - env = volume_calc(SLOT8_2); - if( env < ENV_QUIET ) - { - /* base frequency derived from operator 1 in channel 7 */ - unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1; - unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1; - unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1; - - unsigned char res1 = (bit2 ^ bit7) | bit3; - - /* when res1 = 0 phase = 0x000 | 0x100; */ - /* when res1 = 1 phase = 0x200 | 0x100; */ - UINT32 phase = res1 ? 0x300 : 0x100; - - /* enable gate based on frequency of operator 2 in channel 8 */ - unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1; - unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1; - - unsigned char res2 = (bit3e ^ bit5e); - /* when res2 = 0 pass the phase from calculation above (res1); */ - /* when res2 = 1 phase = 0x200 | 0x100; */ - if (res2) - phase = 0x300; - - output[0] += op_calc(phase<wavetable) * 2; - } - -} - - -/* generic table initialize */ -static int init_tables(void) -{ - signed int i,x; - signed int n; - double o,m; - - - for (x=0; x>= 4; /* 12 bits here */ - if (n&1) /* round to nearest */ - n = (n>>1)+1; - else - n = n>>1; - /* 11 bits here (rounded) */ - n <<= 1; /* 12 bits here (as in real chip) */ - tl_tab[ x*2 + 0 ] = n; - tl_tab[ x*2 + 1 ] = -tl_tab[ x*2 + 0 ]; - - for (i=1; i<12; i++) - { - tl_tab[ x*2+0 + i*2*TL_RES_LEN ] = tl_tab[ x*2+0 ]>>i; - tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = -tl_tab[ x*2+0 + i*2*TL_RES_LEN ]; - } - #if 0 - logerror("tl %04i", x*2); - for (i=0; i<12; i++) - logerror(", [%02i] %5i", i*2, tl_tab[ x*2 /*+1*/ + i*2*TL_RES_LEN ] ); - logerror("\n"); - #endif - } - /*logerror("FMOPL.C: TL_TAB_LEN = %i elements (%i bytes)\n",TL_TAB_LEN, (int)sizeof(tl_tab));*/ - - - for (i=0; i0.0) - o = 8*log(1.0/m)/log(2.0); /* convert to 'decibels' */ - else - o = 8*log(-1.0/m)/log(2.0); /* convert to 'decibels' */ - - o = o / (ENV_STEP/4); - - n = (int)(2.0*o); - if (n&1) /* round to nearest */ - n = (n>>1)+1; - else - n = n>>1; - - sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 ); - - /*logerror("FMOPL.C: sin [%4i (hex=%03x)]= %4i (tl_tab value=%5i)\n", i, i, sin_tab[i], tl_tab[sin_tab[i]] );*/ - } - - for (i=0; i>1) ]; - - /* waveform 3: _ _ _ _ */ - /* / |_/ |_/ |_/ |_*/ - /* abs(output only first quarter of the sinus waveform) */ - - if (i & (1<<(SIN_BITS-2)) ) - sin_tab[3*SIN_LEN+i] = TL_TAB_LEN; - else - sin_tab[3*SIN_LEN+i] = sin_tab[i & (SIN_MASK>>2)]; - - /*logerror("FMOPL.C: sin1[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[1*SIN_LEN+i], tl_tab[sin_tab[1*SIN_LEN+i]] ); - logerror("FMOPL.C: sin2[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[2*SIN_LEN+i], tl_tab[sin_tab[2*SIN_LEN+i]] ); - logerror("FMOPL.C: sin3[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[3*SIN_LEN+i], tl_tab[sin_tab[3*SIN_LEN+i]] );*/ - } - /*logerror("FMOPL.C: ENV_QUIET= %08x (dec*8=%i)\n", ENV_QUIET, ENV_QUIET*8 );*/ - - -#ifdef SAVE_SAMPLE - sample[0]=fopen("sampsum.pcm","wb"); -#endif - - return 1; -} - -static void OPLCloseTable( void ) -{ -#ifdef SAVE_SAMPLE - fclose(sample[0]); -#endif -} - - - -static void OPL_initalize(FM_OPL *OPL) -{ - int i; - - /* frequency base */ - OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / 72.0) / OPL->rate : 0; -#if 0 - OPL->rate = (double)OPL->clock / 72.0; - OPL->freqbase = 1.0; -#endif - - /*logerror("freqbase=%f\n", OPL->freqbase);*/ - - /* Timer base time */ - OPL->TimerBase = 1.0 / ((double)OPL->clock / 72.0 ); - - /* make fnumber -> increment counter table */ - for( i=0 ; i < 1024 ; i++ ) - { - /* opn phase increment counter = 20bit */ - OPL->fn_tab[i] = (UINT32)( (double)i * 64 * OPL->freqbase * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */ -#if 0 - logerror("FMOPL.C: fn_tab[%4i] = %08x (dec=%8i)\n", - i, OPL->fn_tab[i]>>6, OPL->fn_tab[i]>>6 ); -#endif - } - -#if 0 - for( i=0 ; i < 16 ; i++ ) - { - logerror("FMOPL.C: sl_tab[%i] = %08x\n", - i, sl_tab[i] ); - } - for( i=0 ; i < 8 ; i++ ) - { - int j; - logerror("FMOPL.C: ksl_tab[oct=%2i] =",i); - for (j=0; j<16; j++) - { - logerror("%08x ", ksl_tab[i*16+j] ); - } - logerror("\n"); - } -#endif - - - /* Amplitude modulation: 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */ - /* One entry from LFO_AM_TABLE lasts for 64 samples */ - OPL->lfo_am_inc = (UINT32)((1.0 / 64.0 ) * (1<freqbase); - - /* Vibrato: 8 output levels (triangle waveform); 1 level takes 1024 samples */ - OPL->lfo_pm_inc = (UINT32)((1.0 / 1024.0) * (1<freqbase); - - /*logerror ("OPL->lfo_am_inc = %8x ; OPL->lfo_pm_inc = %8x\n", OPL->lfo_am_inc, OPL->lfo_pm_inc);*/ - - /* Noise generator: a step takes 1 sample */ - OPL->noise_f = (UINT32)((1.0 / 1.0) * (1<freqbase); - - OPL->eg_timer_add = (UINT32)((1<freqbase); - OPL->eg_timer_overflow = ( 1 ) * (1<eg_timer_add, OPL->eg_timer_overflow);*/ - -} - -INLINE void FM_KEYON(OPL_SLOT *SLOT, UINT32 key_set) -{ - if( !SLOT->key ) - { - /* restart Phase Generator */ - SLOT->Cnt = 0; - /* phase -> Attack */ - SLOT->state = EG_ATT; - } - SLOT->key |= key_set; -} - -INLINE void FM_KEYOFF(OPL_SLOT *SLOT, UINT32 key_clr) -{ - if( SLOT->key ) - { - SLOT->key &= key_clr; - - if( !SLOT->key ) - { - /* phase -> Release */ - if (SLOT->state>EG_REL) - SLOT->state = EG_REL; - } - } -} - -/* update phase increment counter of operator (also update the EG rates if necessary) */ -INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT) -{ - int ksr; - - /* (frequency) phase increment counter */ - SLOT->Incr = CH->fc * SLOT->mul; - ksr = CH->kcode >> SLOT->KSR; - - if( SLOT->ksr != ksr ) - { - SLOT->ksr = ksr; - - /* calculate envelope generator rates */ - if ((SLOT->ar + SLOT->ksr) < 16+62) - { - SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; - SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; - } - else - { - SLOT->eg_sh_ar = 0; - SLOT->eg_sel_ar = 13*RATE_STEPS; - } - SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; - SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; - SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; - SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; - } -} - -/* set multi,am,vib,EG-TYP,KSR,mul */ -INLINE void set_mul(FM_OPL *OPL,int slot,int v) -{ - OPL_CH *CH = &OPL->P_CH[slot/2]; - OPL_SLOT *SLOT = &CH->SLOT[slot&1]; - - SLOT->mul = mul_tab[v&0x0f]; - SLOT->KSR = (v&0x10) ? 0 : 2; - SLOT->eg_type = (v&0x20); - SLOT->vib = (v&0x40); - SLOT->AMmask = (v&0x80) ? ~0 : 0; - CALC_FCSLOT(CH,SLOT); -} - -/* set ksl & tl */ -INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v) -{ - OPL_CH *CH = &OPL->P_CH[slot/2]; - OPL_SLOT *SLOT = &CH->SLOT[slot&1]; - - SLOT->ksl = ksl_level[(v>>6)&3]; /* 0 / 3.0 / 1.5 / 6.0 dB/OCT */ - SLOT->TL = (v&0x3f)<<(ENV_BITS-1-7); /* 7 bits TL (bit 6 = always 0) */ - - SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); -} - -/* set attack rate & decay rate */ -INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v) -{ - OPL_CH *CH = &OPL->P_CH[slot/2]; - OPL_SLOT *SLOT = &CH->SLOT[slot&1]; - - SLOT->ar = (v>>4) ? 16 + ((v>>4) <<2) : 0; - - if ((SLOT->ar + SLOT->ksr) < 16+62) - { - SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; - SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; - } - else - { - SLOT->eg_sh_ar = 0; - SLOT->eg_sel_ar = 13*RATE_STEPS; - } - - SLOT->dr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; - SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; - SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; -} - -/* set sustain level & release rate */ -INLINE void set_sl_rr(FM_OPL *OPL,int slot,int v) -{ - OPL_CH *CH = &OPL->P_CH[slot/2]; - OPL_SLOT *SLOT = &CH->SLOT[slot&1]; - - SLOT->sl = sl_tab[ v>>4 ]; - - SLOT->rr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; - SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; - SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; -} - - -/* write a value v to register r on OPL chip */ -static void OPLWriteReg(FM_OPL *OPL, int r, int v) -{ - OPL_CH *CH; - int slot; - int block_fnum; - - - /* adjust bus to 8 bits */ - r &= 0xff; - v &= 0xff; - -#ifdef LOG_CYM_FILE - if ((cymfile) && (r!=0) ) - { - fputc( (unsigned char)r, cymfile ); - fputc( (unsigned char)v, cymfile ); - } -#endif - - - switch(r&0xe0) - { - case 0x00: /* 00-1f:control */ - switch(r&0x1f) - { - case 0x01: /* waveform select enable */ - if(OPL->type&OPL_TYPE_WAVESEL) - { - OPL->wavesel = v&0x20; - /* do not change the waveform previously selected */ - } - break; - case 0x02: /* Timer 1 */ - OPL->T[0] = (256-v)*4; - break; - case 0x03: /* Timer 2 */ - OPL->T[1] = (256-v)*16; - break; - case 0x04: /* IRQ clear / mask and Timer enable */ - if(v&0x80) - { /* IRQ flag clear */ - OPL_STATUS_RESET(OPL,0x7f); - } - else - { /* set IRQ mask ,timer enable*/ - OPL->st[0] = v&1; - OPL->st[1] = (v>>1)&1; - - /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */ - OPL_STATUS_RESET(OPL, v & 0x78 ); - OPL_STATUSMASK_SET(OPL, (~v) & 0x78 ); - - /* timer 1 */ - if(OPL->st[0]) - { - OPL->TC[0]=OPL->T[0]*20; - double interval = (double)OPL->T[0]*OPL->TimerBase; - if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval); - } - /* timer 2 */ - if(OPL->st[1]) - { - OPL->TC[1]=OPL->T[1]*20; - double interval =(double)OPL->T[1]*OPL->TimerBase; - if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval); - } - } - break; -#if BUILD_Y8950 - case 0x06: /* Key Board OUT */ - if(OPL->type&OPL_TYPE_KEYBOARD) - { - if(OPL->keyboardhandler_w) - OPL->keyboardhandler_w(OPL->keyboard_param,v); - else - logerror("Y8950: write unmapped KEYBOARD port\n"); - } - break; - case 0x07: /* DELTA-T control 1 : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */ - if(OPL->type&OPL_TYPE_ADPCM) - YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v); - break; -#endif - case 0x08: /* MODE,DELTA-T control 2 : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */ - OPL->mode = v; -#if BUILD_Y8950 - if(OPL->type&OPL_TYPE_ADPCM) - YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v&0x0f); /* mask 4 LSBs in register 08 for DELTA-T unit */ -#endif - break; - -#if BUILD_Y8950 - case 0x09: /* START ADD */ - case 0x0a: - case 0x0b: /* STOP ADD */ - case 0x0c: - case 0x0d: /* PRESCALE */ - case 0x0e: - case 0x0f: /* ADPCM data write */ - case 0x10: /* DELTA-N */ - case 0x11: /* DELTA-N */ - case 0x12: /* ADPCM volume */ - if(OPL->type&OPL_TYPE_ADPCM) - YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v); - break; - - case 0x15: /* DAC data high 8 bits (F7,F6...F2) */ - case 0x16: /* DAC data low 2 bits (F1, F0 in bits 7,6) */ - case 0x17: /* DAC data shift (S2,S1,S0 in bits 2,1,0) */ - logerror("FMOPL.C: DAC data register written, but not implemented reg=%02x val=%02x\n",r,v); - break; - - case 0x18: /* I/O CTRL (Direction) */ - if(OPL->type&OPL_TYPE_IO) - OPL->portDirection = v&0x0f; - break; - case 0x19: /* I/O DATA */ - if(OPL->type&OPL_TYPE_IO) - { - OPL->portLatch = v; - if(OPL->porthandler_w) - OPL->porthandler_w(OPL->port_param,v&OPL->portDirection); - } - break; -#endif - default: - logerror("FMOPL.C: write to unknown register: %02x\n",r); - break; - } - break; - case 0x20: /* am ON, vib ON, ksr, eg_type, mul */ - slot = slot_array[r&0x1f]; - if(slot < 0) return; - set_mul(OPL,slot,v); - break; - case 0x40: - slot = slot_array[r&0x1f]; - if(slot < 0) return; - set_ksl_tl(OPL,slot,v); - break; - case 0x60: - slot = slot_array[r&0x1f]; - if(slot < 0) return; - set_ar_dr(OPL,slot,v); - break; - case 0x80: - slot = slot_array[r&0x1f]; - if(slot < 0) return; - set_sl_rr(OPL,slot,v); - break; - case 0xa0: - if (r == 0xbd) /* am depth, vibrato depth, r,bd,sd,tom,tc,hh */ - { - OPL->lfo_am_depth = v & 0x80; - OPL->lfo_pm_depth_range = (v&0x40) ? 8 : 0; - - OPL->rhythm = v&0x3f; - - if(OPL->rhythm&0x20) - { - /* BD key on/off */ - if(v&0x10) - { - FM_KEYON (&OPL->P_CH[6].SLOT[SLOT1], 2); - FM_KEYON (&OPL->P_CH[6].SLOT[SLOT2], 2); - } - else - { - FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1],~2); - FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2],~2); - } - /* HH key on/off */ - if(v&0x01) FM_KEYON (&OPL->P_CH[7].SLOT[SLOT1], 2); - else FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1],~2); - /* SD key on/off */ - if(v&0x08) FM_KEYON (&OPL->P_CH[7].SLOT[SLOT2], 2); - else FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2],~2); - /* TOM key on/off */ - if(v&0x04) FM_KEYON (&OPL->P_CH[8].SLOT[SLOT1], 2); - else FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1],~2); - /* TOP-CY key on/off */ - if(v&0x02) FM_KEYON (&OPL->P_CH[8].SLOT[SLOT2], 2); - else FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2],~2); - } - else - { - /* BD key off */ - FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1],~2); - FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2],~2); - /* HH key off */ - FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1],~2); - /* SD key off */ - FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2],~2); - /* TOM key off */ - FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1],~2); - /* TOP-CY off */ - FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2],~2); - } - return; - } - /* keyon,block,fnum */ - if( (r&0x0f) > 8) return; - CH = &OPL->P_CH[r&0x0f]; - if(!(r&0x10)) - { /* a0-a8 */ - block_fnum = (CH->block_fnum&0x1f00) | v; - } - else - { /* b0-b8 */ - block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff); - - if(v&0x20) - { - FM_KEYON (&CH->SLOT[SLOT1], 1); - FM_KEYON (&CH->SLOT[SLOT2], 1); - } - else - { - FM_KEYOFF(&CH->SLOT[SLOT1],~1); - FM_KEYOFF(&CH->SLOT[SLOT2],~1); - } - } - /* update */ - if(CH->block_fnum != block_fnum) - { - UINT8 block = block_fnum >> 10; - - CH->block_fnum = block_fnum; - - CH->ksl_base = ksl_tab[block_fnum>>6]; - CH->fc = OPL->fn_tab[block_fnum&0x03ff] >> (7-block); - - /* BLK 2,1,0 bits -> bits 3,2,1 of kcode */ - CH->kcode = (CH->block_fnum&0x1c00)>>9; - - /* the info below is actually opposite to what is stated in the Manuals (verifed on real YM3812) */ - /* if notesel == 0 -> lsb of kcode is bit 10 (MSB) of fnum */ - /* if notesel == 1 -> lsb of kcode is bit 9 (MSB-1) of fnum */ - if (OPL->mode&0x40) - CH->kcode |= (CH->block_fnum&0x100)>>8; /* notesel == 1 */ - else - CH->kcode |= (CH->block_fnum&0x200)>>9; /* notesel == 0 */ - - /* refresh Total Level in both SLOTs of this channel */ - CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); - CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); - - /* refresh frequency counter in both SLOTs of this channel */ - CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); - CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); - } - break; - case 0xc0: - /* FB,C */ - if( (r&0x0f) > 8) return; - CH = &OPL->P_CH[r&0x0f]; - CH->SLOT[SLOT1].FB = (v>>1)&7 ? ((v>>1)&7) + 7 : 0; - CH->SLOT[SLOT1].CON = v&1; - CH->SLOT[SLOT1].connect1 = CH->SLOT[SLOT1].CON ? &output[0] : &phase_modulation; - break; - case 0xe0: /* waveform select */ - /* simply ignore write to the waveform select register if selecting not enabled in test register */ - if(OPL->wavesel) - { - slot = slot_array[r&0x1f]; - if(slot < 0) return; - CH = &OPL->P_CH[slot/2]; - - CH->SLOT[slot&1].wavetable = (v&0x03)*SIN_LEN; - } - break; - } -} - -#ifdef LOG_CYM_FILE -static void cymfile_callback (int n) -{ - if (cymfile) - { - fputc( (unsigned char)0, cymfile ); - } -} -#endif - -/* lock/unlock for common table */ -static int OPL_LockTable(void) -{ - num_lock++; - if(num_lock>1) return 0; - - /* first time */ - - cur_chip = NULL; - /* allocate total level table (128kb space) */ - if( !init_tables() ) - { - num_lock--; - return -1; - } - -#ifdef LOG_CYM_FILE - cymfile = fopen("3812_.cym","wb"); - if (cymfile) - timer_pulse ( TIME_IN_HZ(110), 0, cymfile_callback); /*110 Hz pulse timer*/ - else - logerror("Could not create file 3812_.cym\n"); -#endif - - return 0; -} - -static void OPL_UnLockTable(void) -{ - if(num_lock) num_lock--; - if(num_lock) return; - - /* last time */ - - cur_chip = NULL; - OPLCloseTable(); - -#ifdef LOG_CYM_FILE - fclose (cymfile); - cymfile = NULL; -#endif - -} - -static void OPLResetChip(FM_OPL *OPL) -{ - int c,s; - int i; - - OPL->eg_timer = 0; - OPL->eg_cnt = 0; - - OPL->noise_rng = 1; /* noise shift register */ - OPL->mode = 0; /* normal mode */ - OPL_STATUS_RESET(OPL,0x7f); - - /* reset with register write */ - OPLWriteReg(OPL,0x01,0); /* wavesel disable */ - OPLWriteReg(OPL,0x02,0); /* Timer1 */ - OPLWriteReg(OPL,0x03,0); /* Timer2 */ - OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */ - for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0); - - /* reset operator parameters */ - for( c = 0 ; c < 9 ; c++ ) - { - OPL_CH *CH = &OPL->P_CH[c]; - for(s = 0 ; s < 2 ; s++ ) - { - /* wave table */ - CH->SLOT[s].wavetable = 0; - CH->SLOT[s].state = EG_OFF; - CH->SLOT[s].volume = MAX_ATT_INDEX; - } - } -#if BUILD_Y8950 - if(OPL->type&OPL_TYPE_ADPCM) - { - YM_DELTAT *DELTAT = OPL->deltat; - - DELTAT->freqbase = OPL->freqbase; - DELTAT->output_pointer = &output_deltat[0]; - DELTAT->portshift = 5; - DELTAT->output_range = 1<<23; - YM_DELTAT_ADPCM_Reset(DELTAT,0); - } -#endif -} - -/* Create one of virtual YM3812/YM3526/Y8950 */ -/* 'clock' is chip clock in Hz */ -/* 'rate' is sampling rate */ -static FM_OPL *OPLCreate(int type, int clock, int rate) -{ - char *ptr; - FM_OPL *OPL; - int state_size; - - if (OPL_LockTable() ==-1) return NULL; - - /* calculate OPL state size */ - state_size = sizeof(FM_OPL); - -#if BUILD_Y8950 - if (type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT); -#endif - - /* allocate memory block */ - ptr = (char *)malloc(state_size); - - if (ptr==NULL) - return NULL; - - /* clear */ - memset(ptr,0,state_size); - - OPL = (FM_OPL *)ptr; - - ptr += sizeof(FM_OPL); - -#if BUILD_Y8950 - if (type&OPL_TYPE_ADPCM) - { - OPL->deltat = (YM_DELTAT *)ptr; - } - ptr += sizeof(YM_DELTAT); -#endif - - OPL->type = type; - OPL->clock = clock; - OPL->rate = rate; - - /* init global tables */ - OPL_initalize(OPL); - - return OPL; -} - -/* Destroy one of virtual YM3812 */ -static void OPLDestroy(FM_OPL *OPL) -{ - OPL_UnLockTable(); - free(OPL); -} - -/* Optional handlers */ - -static void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset) -{ - OPL->TimerHandler = TimerHandler; - OPL->TimerParam = channelOffset; -} -static void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param) -{ - OPL->IRQHandler = IRQHandler; - OPL->IRQParam = param; -} -static void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param) -{ - OPL->UpdateHandler = UpdateHandler; - OPL->UpdateParam = param; -} - -static int OPLWrite(FM_OPL *OPL,int a,int v) -{ - if( !(a&1) ) - { /* address port */ - OPL->address = v & 0xff; - } - else - { /* data port */ - if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); - OPLWriteReg(OPL,OPL->address,v); - } - return OPL->status>>7; -} - -static unsigned char OPLRead(FM_OPL *OPL,int a) -{ - if( !(a&1) ) - { - /* status port */ - - #if BUILD_Y8950 - - if(OPL->type&OPL_TYPE_ADPCM) /* Y8950 */ - { - return (OPL->status & (OPL->statusmask|0x80)) | (OPL->deltat->PCM_BSY&1); - } - - #endif - if (OPL->st[0]) { - /* Timer A */ - if (OPL->TC[0]) OPL->TC[0]--; - else { - OPL->TC[0]=OPL->T[0]*20; - OPL_STATUS_SET(OPL,0x40); - } - } - if (OPL->st[1]) { - /* Timer B */ - if (OPL->TC[1]) OPL->TC[1]--; - else { - OPL->TC[1]=OPL->T[1]*20; - OPL_STATUS_SET(OPL,0x20); - } - } - return OPL->status & (OPL->statusmask|0x80); - } - -#if BUILD_Y8950 - /* data port */ - switch(OPL->address) - { - case 0x05: /* KeyBoard IN */ - if(OPL->type&OPL_TYPE_KEYBOARD) - { - if(OPL->keyboardhandler_r) - return OPL->keyboardhandler_r(OPL->keyboard_param); - else - logerror("Y8950: read unmapped KEYBOARD port\n"); - } - return 0; - - case 0x0f: /* ADPCM-DATA */ - if(OPL->type&OPL_TYPE_ADPCM) - { - UINT8 val; - - val = YM_DELTAT_ADPCM_Read(OPL->deltat); - /*logerror("Y8950: read ADPCM value read=%02x\n",val);*/ - return val; - } - return 0; - - case 0x19: /* I/O DATA */ - if(OPL->type&OPL_TYPE_IO) - { - if(OPL->porthandler_r) - return OPL->porthandler_r(OPL->port_param); - else - logerror("Y8950:read unmapped I/O port\n"); - } - return 0; - case 0x1a: /* PCM-DATA */ - if(OPL->type&OPL_TYPE_ADPCM) - { - logerror("Y8950 A/D convertion is accessed but not implemented !\n"); - return 0x80; /* 2's complement PCM data - result from A/D convertion */ - } - return 0; - } -#endif - - return 0xff; -} - -/* CSM Key Controll */ -INLINE void CSMKeyControll(OPL_CH *CH) -{ - FM_KEYON (&CH->SLOT[SLOT1], 4); - FM_KEYON (&CH->SLOT[SLOT2], 4); - - /* The key off should happen exactly one sample later - not implemented correctly yet */ - - FM_KEYOFF(&CH->SLOT[SLOT1], ~4); - FM_KEYOFF(&CH->SLOT[SLOT2], ~4); -} - - -static int OPLTimerOver(FM_OPL *OPL,int c) -{ - if( c ) - { /* Timer B */ - OPL_STATUS_SET(OPL,0x20); - } - else - { /* Timer A */ - OPL_STATUS_SET(OPL,0x40); - /* CSM mode key,TL controll */ - if( OPL->mode & 0x80 ) - { /* CSM mode total level latch and auto key on */ - int ch; - if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); - for(ch=0; ch<9; ch++) - CSMKeyControll( &OPL->P_CH[ch] ); - } - } - /* reload timer */ -// if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase); - return OPL->status>>7; -} - - -#define MAX_OPL_CHIPS 2 - - -#if (BUILD_YM3812) - -static FM_OPL *OPL_YM3812[MAX_OPL_CHIPS]; /* array of pointers to the YM3812's */ -static int YM3812NumChips = 0; /* number of chips */ - -int YM3812Init(int num, int clock, int rate) -{ - int i; - - if (YM3812NumChips) - return -1; /* duplicate init. */ - - YM3812NumChips = num; - - for (i = 0;i < YM3812NumChips; i++) - { - /* emulator create */ - OPL_YM3812[i] = OPLCreate(OPL_TYPE_YM3812,clock,rate); - if(OPL_YM3812[i] == NULL) - { - /* it's really bad - we run out of memeory */ - YM3812NumChips = 0; - return -1; - } - /* reset */ - YM3812ResetChip(i); - } - - return 0; -} - -void YM3812Shutdown(void) -{ - int i; - - for (i = 0;i < YM3812NumChips; i++) - { - /* emulator shutdown */ - OPLDestroy(OPL_YM3812[i]); - OPL_YM3812[i] = NULL; - } - YM3812NumChips = 0; -} -void YM3812ResetChip(int which) -{ - OPLResetChip(OPL_YM3812[which]); -} - -int YM3812Write(int which, int a, int v) -{ - return OPLWrite(OPL_YM3812[which], a, v); -} - -unsigned char YM3812Read(int which, int a) -{ - /* YM3812 always returns bit2 and bit1 in HIGH state */ - return OPLRead(OPL_YM3812[which], a) | 0x06 ; -} -int YM3812TimerOver(int which, int c) -{ - return OPLTimerOver(OPL_YM3812[which], c); -} - -void YM3812SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset) -{ - OPLSetTimerHandler(OPL_YM3812[which], TimerHandler, channelOffset); -} -void YM3812SetIRQHandler(int which,OPL_IRQHANDLER IRQHandler,int param) -{ - OPLSetIRQHandler(OPL_YM3812[which], IRQHandler, param); -} -void YM3812SetUpdateHandler(int which,OPL_UPDATEHANDLER UpdateHandler,int param) -{ - OPLSetUpdateHandler(OPL_YM3812[which], UpdateHandler, param); -} - - -/* -** Generate samples for one of the YM3812's -** -** 'which' is the virtual YM3812 number -** '*buffer' is the output buffer pointer -** 'length' is the number of samples that should be generated -*/ -void YM3812UpdateOne(int which, INT16 *buffer, int length) -{ - FM_OPL *OPL = OPL_YM3812[which]; - UINT8 rhythm = OPL->rhythm&0x20; - OPLSAMPLE *buf = buffer; - int i; - - if( (void *)OPL != cur_chip ){ - cur_chip = (void *)OPL; - /* rhythm slots */ - SLOT7_1 = &OPL->P_CH[7].SLOT[SLOT1]; - SLOT7_2 = &OPL->P_CH[7].SLOT[SLOT2]; - SLOT8_1 = &OPL->P_CH[8].SLOT[SLOT1]; - SLOT8_2 = &OPL->P_CH[8].SLOT[SLOT2]; - } - for( i=0; i < length ; i++ ) - { - int lt; - - output[0] = 0; - - advance_lfo(OPL); - - /* FM part */ - OPL_CALC_CH(&OPL->P_CH[0]); - OPL_CALC_CH(&OPL->P_CH[1]); - OPL_CALC_CH(&OPL->P_CH[2]); - OPL_CALC_CH(&OPL->P_CH[3]); - OPL_CALC_CH(&OPL->P_CH[4]); - OPL_CALC_CH(&OPL->P_CH[5]); - - if(!rhythm) - { - OPL_CALC_CH(&OPL->P_CH[6]); - OPL_CALC_CH(&OPL->P_CH[7]); - OPL_CALC_CH(&OPL->P_CH[8]); - } - else /* Rhythm part */ - { - OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>0)&1 ); - } - - lt = output[0]; - - lt >>= FINAL_SH; - - /* limit check */ - lt = limit( lt , MAXOUT, MINOUT ); - - #ifdef SAVE_SAMPLE - if (which==0) - { - SAVE_ALL_CHANNELS - } - #endif - - /* store to sound buffer */ - buf[i] = lt; - - advance(OPL); - } - -} -#endif /* BUILD_YM3812 */ - - - -#if (BUILD_YM3526) - -static FM_OPL *OPL_YM3526[MAX_OPL_CHIPS]; /* array of pointers to the YM3526's */ -static int YM3526NumChips = 0; /* number of chips */ - -int YM3526Init(int num, int clock, int rate) -{ - int i; - - if (YM3526NumChips) - return -1; /* duplicate init. */ - - YM3526NumChips = num; - - for (i = 0;i < YM3526NumChips; i++) - { - /* emulator create */ - OPL_YM3526[i] = OPLCreate(OPL_TYPE_YM3526,clock,rate); - if(OPL_YM3526[i] == NULL) - { - /* it's really bad - we run out of memeory */ - YM3526NumChips = 0; - return -1; - } - /* reset */ - YM3526ResetChip(i); - } - - return 0; -} - -void YM3526Shutdown(void) -{ - int i; - - for (i = 0;i < YM3526NumChips; i++) - { - /* emulator shutdown */ - OPLDestroy(OPL_YM3526[i]); - OPL_YM3526[i] = NULL; - } - YM3526NumChips = 0; -} -void YM3526ResetChip(int which) -{ - OPLResetChip(OPL_YM3526[which]); -} - -int YM3526Write(int which, int a, int v) -{ - return OPLWrite(OPL_YM3526[which], a, v); -} - -unsigned char YM3526Read(int which, int a) -{ - /* YM3526 always returns bit2 and bit1 in HIGH state */ - return OPLRead(OPL_YM3526[which], a) | 0x06 ; -} -int YM3526TimerOver(int which, int c) -{ - return OPLTimerOver(OPL_YM3526[which], c); -} - -void YM3526SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset) -{ - OPLSetTimerHandler(OPL_YM3526[which], TimerHandler, channelOffset); -} -void YM3526SetIRQHandler(int which,OPL_IRQHANDLER IRQHandler,int param) -{ - OPLSetIRQHandler(OPL_YM3526[which], IRQHandler, param); -} -void YM3526SetUpdateHandler(int which,OPL_UPDATEHANDLER UpdateHandler,int param) -{ - OPLSetUpdateHandler(OPL_YM3526[which], UpdateHandler, param); -} - - -/* -** Generate samples for one of the YM3526's -** -** 'which' is the virtual YM3526 number -** '*buffer' is the output buffer pointer -** 'length' is the number of samples that should be generated -*/ -void YM3526UpdateOne(int which, INT16 *buffer, int length) -{ - FM_OPL *OPL = OPL_YM3526[which]; - UINT8 rhythm = OPL->rhythm&0x20; - OPLSAMPLE *buf = buffer; - int i; - - if( (void *)OPL != cur_chip ){ - cur_chip = (void *)OPL; - /* rhythm slots */ - SLOT7_1 = &OPL->P_CH[7].SLOT[SLOT1]; - SLOT7_2 = &OPL->P_CH[7].SLOT[SLOT2]; - SLOT8_1 = &OPL->P_CH[8].SLOT[SLOT1]; - SLOT8_2 = &OPL->P_CH[8].SLOT[SLOT2]; - } - for( i=0; i < length ; i++ ) - { - int lt; - - output[0] = 0; - - advance_lfo(OPL); - - /* FM part */ - OPL_CALC_CH(&OPL->P_CH[0]); - OPL_CALC_CH(&OPL->P_CH[1]); - OPL_CALC_CH(&OPL->P_CH[2]); - OPL_CALC_CH(&OPL->P_CH[3]); - OPL_CALC_CH(&OPL->P_CH[4]); - OPL_CALC_CH(&OPL->P_CH[5]); - - if(!rhythm) - { - OPL_CALC_CH(&OPL->P_CH[6]); - OPL_CALC_CH(&OPL->P_CH[7]); - OPL_CALC_CH(&OPL->P_CH[8]); - } - else /* Rhythm part */ - { - OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>0)&1 ); - } - - lt = output[0]; - - lt >>= FINAL_SH; - - /* limit check */ - lt = limit( lt , MAXOUT, MINOUT ); - - #ifdef SAVE_SAMPLE - if (which==0) - { - SAVE_ALL_CHANNELS - } - #endif - - /* store to sound buffer */ - buf[i] = lt; - - advance(OPL); - } - -} -#endif /* BUILD_YM3526 */ - - - - -#if BUILD_Y8950 - -static FM_OPL *OPL_Y8950[MAX_OPL_CHIPS]; /* array of pointers to the Y8950's */ -static int Y8950NumChips = 0; /* number of chips */ - -static void Y8950_deltat_status_set(UINT8 which, UINT8 changebits) -{ - OPL_STATUS_SET(OPL_Y8950[which], changebits); -} -static void Y8950_deltat_status_reset(UINT8 which, UINT8 changebits) -{ - OPL_STATUS_RESET(OPL_Y8950[which], changebits); -} - -int Y8950Init(int num, int clock, int rate) -{ - int i; - - if (Y8950NumChips) - return -1; /* duplicate init. */ - - Y8950NumChips = num; - - for (i = 0;i < Y8950NumChips; i++) - { - /* emulator create */ - OPL_Y8950[i] = OPLCreate(OPL_TYPE_Y8950,clock,rate); - if(OPL_Y8950[i] == NULL) - { - /* it's really bad - we run out of memeory */ - Y8950NumChips = 0; - return -1; - } - OPL_Y8950[i]->deltat->status_set_handler = Y8950_deltat_status_set; - OPL_Y8950[i]->deltat->status_reset_handler = Y8950_deltat_status_reset; - OPL_Y8950[i]->deltat->status_change_which_chip = i; - OPL_Y8950[i]->deltat->status_change_EOS_bit = 0x10; /* status flag: set bit4 on End Of Sample */ - OPL_Y8950[i]->deltat->status_change_BRDY_bit = 0x08; /* status flag: set bit3 on BRDY (End Of: ADPCM analysis/synthesis, memory reading/writing) */ - /* reset */ - Y8950ResetChip(i); - } - - return 0; -} - -void Y8950Shutdown(void) -{ - int i; - - for (i = 0;i < Y8950NumChips; i++) - { - /* emulator shutdown */ - OPLDestroy(OPL_Y8950[i]); - OPL_Y8950[i] = NULL; - } - Y8950NumChips = 0; -} -void Y8950ResetChip(int which) -{ - OPLResetChip(OPL_Y8950[which]); -} - -int Y8950Write(int which, int a, int v) -{ - return OPLWrite(OPL_Y8950[which], a, v); -} - -unsigned char Y8950Read(int which, int a) -{ - return OPLRead(OPL_Y8950[which], a); -} -int Y8950TimerOver(int which, int c) -{ - return OPLTimerOver(OPL_Y8950[which], c); -} - -void Y8950SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset) -{ - OPLSetTimerHandler(OPL_Y8950[which], TimerHandler, channelOffset); -} -void Y8950SetIRQHandler(int which,OPL_IRQHANDLER IRQHandler,int param) -{ - OPLSetIRQHandler(OPL_Y8950[which], IRQHandler, param); -} -void Y8950SetUpdateHandler(int which,OPL_UPDATEHANDLER UpdateHandler,int param) -{ - OPLSetUpdateHandler(OPL_Y8950[which], UpdateHandler, param); -} - -void Y8950SetDeltaTMemory(int which, void * deltat_mem_ptr, int deltat_mem_size ) -{ - FM_OPL *OPL = OPL_Y8950[which]; - OPL->deltat->memory = (UINT8 *)(deltat_mem_ptr); - OPL->deltat->memory_size = deltat_mem_size; -} - -/* -** Generate samples for one of the Y8950's -** -** 'which' is the virtual Y8950 number -** '*buffer' is the output buffer pointer -** 'length' is the number of samples that should be generated -*/ -void Y8950UpdateOne(int which, INT16 *buffer, int length) -{ - int i; - FM_OPL *OPL = OPL_Y8950[which]; - UINT8 rhythm = OPL->rhythm&0x20; - YM_DELTAT *DELTAT = OPL->deltat; - OPLSAMPLE *buf = buffer; - - if( (void *)OPL != cur_chip ){ - cur_chip = (void *)OPL; - /* rhythm slots */ - SLOT7_1 = &OPL->P_CH[7].SLOT[SLOT1]; - SLOT7_2 = &OPL->P_CH[7].SLOT[SLOT2]; - SLOT8_1 = &OPL->P_CH[8].SLOT[SLOT1]; - SLOT8_2 = &OPL->P_CH[8].SLOT[SLOT2]; - - } - for( i=0; i < length ; i++ ) - { - int lt; - - output[0] = 0; - output_deltat[0] = 0; - - advance_lfo(OPL); - - /* deltaT ADPCM */ - if( DELTAT->portstate&0x80 ) - YM_DELTAT_ADPCM_CALC(DELTAT); - - /* FM part */ - OPL_CALC_CH(&OPL->P_CH[0]); - OPL_CALC_CH(&OPL->P_CH[1]); - OPL_CALC_CH(&OPL->P_CH[2]); - OPL_CALC_CH(&OPL->P_CH[3]); - OPL_CALC_CH(&OPL->P_CH[4]); - OPL_CALC_CH(&OPL->P_CH[5]); - - if(!rhythm) - { - OPL_CALC_CH(&OPL->P_CH[6]); - OPL_CALC_CH(&OPL->P_CH[7]); - OPL_CALC_CH(&OPL->P_CH[8]); - } - else /* Rhythm part */ - { - OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>0)&1 ); - } - - lt = output[0] + (output_deltat[0]>>11); - - lt >>= FINAL_SH; - - /* limit check */ - lt = limit( lt , MAXOUT, MINOUT ); - - #ifdef SAVE_SAMPLE - if (which==0) - { - SAVE_ALL_CHANNELS - } - #endif - - /* store to sound buffer */ - buf[i] = lt; - - advance(OPL); - } - -} - -void Y8950SetPortHandler(int which,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param) -{ - FM_OPL *OPL = OPL_Y8950[which]; - OPL->porthandler_w = PortHandler_w; - OPL->porthandler_r = PortHandler_r; - OPL->port_param = param; -} - -void Y8950SetKeyboardHandler(int which,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param) -{ - FM_OPL *OPL = OPL_Y8950[which]; - OPL->keyboardhandler_w = KeyboardHandler_w; - OPL->keyboardhandler_r = KeyboardHandler_r; - OPL->keyboard_param = param; -} - -#endif - diff --git a/src/hardware/fmopl.h b/src/hardware/fmopl.h deleted file mode 100644 index 5a605fce..00000000 --- a/src/hardware/fmopl.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef __FMOPL_H_ -#define __FMOPL_H_ - -/* --- select emulation chips --- */ -#define BUILD_YM3812 (HAS_YM3812) -#define BUILD_YM3526 (HAS_YM3526) -#define BUILD_Y8950 (HAS_Y8950) - -/* select output bits size of output : 8 or 16 */ -#define OPL_SAMPLE_BITS 16 - -/* compiler dependence */ -#ifndef OSD_CPU_H -#define OSD_CPU_H -typedef unsigned char UINT8; /* unsigned 8bit */ -typedef unsigned short UINT16; /* unsigned 16bit */ -typedef unsigned int UINT32; /* unsigned 32bit */ -typedef signed char INT8; /* signed 8bit */ -typedef signed short INT16; /* signed 16bit */ -typedef signed int INT32; /* signed 32bit */ -#endif - -#if (OPL_SAMPLE_BITS==16) -typedef INT16 OPLSAMPLE; -#endif -#if (OPL_SAMPLE_BITS==8) -typedef INT8 OPLSAMPLE; -#endif - - -typedef void (*OPL_TIMERHANDLER)(int channel,double interval_Sec); -typedef void (*OPL_IRQHANDLER)(int param,int irq); -typedef void (*OPL_UPDATEHANDLER)(int param,int min_interval_us); -typedef void (*OPL_PORTHANDLER_W)(int param,unsigned char data); -typedef unsigned char (*OPL_PORTHANDLER_R)(int param); - - -#if BUILD_YM3812 - -int YM3812Init(int num, int clock, int rate); -void YM3812Shutdown(void); -void YM3812ResetChip(int which); -int YM3812Write(int which, int a, int v); -unsigned char YM3812Read(int which, int a); -int YM3812TimerOver(int which, int c); -void YM3812UpdateOne(int which, INT16 *buffer, int length); - -void YM3812SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset); -void YM3812SetIRQHandler(int which, OPL_IRQHANDLER IRQHandler, int param); -void YM3812SetUpdateHandler(int which, OPL_UPDATEHANDLER UpdateHandler, int param); - -#endif - - -#if BUILD_YM3526 - -/* -** Initialize YM3526 emulator(s). -** -** 'num' is the number of virtual YM3526's to allocate -** 'clock' is the chip clock in Hz -** 'rate' is sampling rate -*/ -int YM3526Init(int num, int clock, int rate); -/* shutdown the YM3526 emulators*/ -void YM3526Shutdown(void); -void YM3526ResetChip(int which); -int YM3526Write(int which, int a, int v); -unsigned char YM3526Read(int which, int a); -int YM3526TimerOver(int which, int c); -/* -** Generate samples for one of the YM3526's -** -** 'which' is the virtual YM3526 number -** '*buffer' is the output buffer pointer -** 'length' is the number of samples that should be generated -*/ -void YM3526UpdateOne(int which, INT16 *buffer, int length); - -void YM3526SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset); -void YM3526SetIRQHandler(int which, OPL_IRQHANDLER IRQHandler, int param); -void YM3526SetUpdateHandler(int which, OPL_UPDATEHANDLER UpdateHandler, int param); - -#endif - - -#if BUILD_Y8950 - -#include "ymdeltat.h" - -/* Y8950 port handlers */ -void Y8950SetPortHandler(int which, OPL_PORTHANDLER_W PortHandler_w, OPL_PORTHANDLER_R PortHandler_r, int param); -void Y8950SetKeyboardHandler(int which, OPL_PORTHANDLER_W KeyboardHandler_w, OPL_PORTHANDLER_R KeyboardHandler_r, int param); -void Y8950SetDeltaTMemory(int which, void * deltat_mem_ptr, int deltat_mem_size ); - -int Y8950Init (int num, int clock, int rate); -void Y8950Shutdown (void); -void Y8950ResetChip (int which); -int Y8950Write (int which, int a, int v); -unsigned char Y8950Read (int which, int a); -int Y8950TimerOver (int which, int c); -void Y8950UpdateOne (int which, INT16 *buffer, int length); - -void Y8950SetTimerHandler (int which, OPL_TIMERHANDLER TimerHandler, int channelOffset); -void Y8950SetIRQHandler (int which, OPL_IRQHANDLER IRQHandler, int param); -void Y8950SetUpdateHandler (int which, OPL_UPDATEHANDLER UpdateHandler, int param); - -#endif - - -#endif diff --git a/src/hardware/ymf262.c b/src/hardware/ymf262.c deleted file mode 100644 index fe630135..00000000 --- a/src/hardware/ymf262.c +++ /dev/null @@ -1,2746 +0,0 @@ -/* -** -** File: ymf262.c - software implementation of YMF262 -** FM sound generator type OPL3 -** -** Copyright (C) 2003 Jarek Burczynski -** -** Version 0.2 -** - -Revision History: - -03-03-2003: initial release - - thanks to Olivier Galibert and Chris Hardy for YMF262 and YAC512 chips - - thanks to Stiletto for the datasheets - - - -differences between OPL2 and OPL3 not documented in Yamaha datahasheets: -- sinus table is a little different: the negative part is off by one... - -- in order to enable selection of four different waveforms on OPL2 - one must set bit 5 in register 0x01(test). - on OPL3 this bit is ignored and 4-waveform select works *always*. - (Don't confuse this with OPL3's 8-waveform select.) - -- Envelope Generator: all 15 x rates take zero time on OPL3 - (on OPL2 15 0 and 15 1 rates take some time while 15 2 and 15 3 rates - take zero time) - -- channel calculations: output of operator 1 is in perfect sync with - output of operator 2 on OPL3; on OPL and OPL2 output of operator 1 - is always delayed by one sample compared to output of operator 2 - - -differences between OPL2 and OPL3 shown in datasheets: -- YMF262 does not support CSM mode - - -*/ - -#include -#include -#include - -//#include "driver.h" /* use M.A.M.E. */ -#include "ymf262.h" - -#ifndef PI -#define PI 3.14159265358979323846 -#endif - - - -/* output final shift */ -#if (OPL3_SAMPLE_BITS==16) - #define FINAL_SH (0) - #define MAXOUT (+32767) - #define MINOUT (-32768) -#else - #define FINAL_SH (8) - #define MAXOUT (+127) - #define MINOUT (-128) -#endif - - -#define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */ -#define EG_SH 16 /* 16.16 fixed point (EG timing) */ -#define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */ -#define TIMER_SH 16 /* 16.16 fixed point (timers calculations) */ - -#define FREQ_MASK ((1<>8)&0xff,sample[0]); \ - } - #else /*save to STEREO file */ - #define SAVE_ALL_CHANNELS \ - { signed int pom = a; \ - fputc((unsigned short)pom&0xff,sample[0]); \ - fputc(((unsigned short)pom>>8)&0xff,sample[0]); \ - pom = b; \ - fputc((unsigned short)pom&0xff,sample[0]); \ - fputc(((unsigned short)pom>>8)&0xff,sample[0]); \ - } - #endif -#endif - -/*#define LOG_CYM_FILE*/ -#ifdef LOG_CYM_FILE - FILE * cymfile = NULL; -#endif - - - - - -#define OPL3_TYPE_YMF262 (0) /* 36 operators, 8 waveforms */ - - -typedef struct{ - UINT32 ar; /* attack rate: AR<<2 */ - UINT32 dr; /* decay rate: DR<<2 */ - UINT32 rr; /* release rate:RR<<2 */ - UINT8 KSR; /* key scale rate */ - UINT8 ksl; /* keyscale level */ - UINT8 ksr; /* key scale rate: kcode>>KSR */ - UINT8 mul; /* multiple: mul_tab[ML] */ - - /* Phase Generator */ - UINT32 Cnt; /* frequency counter */ - UINT32 Incr; /* frequency counter step */ - UINT8 FB; /* feedback shift value */ - INT32 *connect; /* slot output pointer */ - INT32 op1_out[2]; /* slot1 output for feedback */ - UINT8 CON; /* connection (algorithm) type */ - - /* Envelope Generator */ - UINT8 eg_type; /* percussive/non-percussive mode */ - UINT8 state; /* phase type */ - UINT32 TL; /* total level: TL << 2 */ - INT32 TLL; /* adjusted now TL */ - INT32 volume; /* envelope counter */ - UINT32 sl; /* sustain level: sl_tab[SL] */ - - UINT32 eg_m_ar; /* (attack state) */ - UINT8 eg_sh_ar; /* (attack state) */ - UINT8 eg_sel_ar; /* (attack state) */ - UINT32 eg_m_dr; /* (decay state) */ - UINT8 eg_sh_dr; /* (decay state) */ - UINT8 eg_sel_dr; /* (decay state) */ - UINT32 eg_m_rr; /* (release state) */ - UINT8 eg_sh_rr; /* (release state) */ - UINT8 eg_sel_rr; /* (release state) */ - - UINT32 key; /* 0 = KEY OFF, >0 = KEY ON */ - - /* LFO */ - UINT32 AMmask; /* LFO Amplitude Modulation enable mask */ - UINT8 vib; /* LFO Phase Modulation enable flag (active high)*/ - - /* waveform select */ - UINT8 waveform_number; - unsigned int wavetable; - -//unsigned char reserved[128-84];//speedup: pump up the struct size to power of 2 -unsigned char reserved[128-100];//speedup: pump up the struct size to power of 2 - -} OPL3_SLOT; - -typedef struct{ - OPL3_SLOT SLOT[2]; - - UINT32 block_fnum; /* block+fnum */ - UINT32 fc; /* Freq. Increment base */ - UINT32 ksl_base; /* KeyScaleLevel Base step */ - UINT8 kcode; /* key code (for key scaling) */ - - /* - there are 12 2-operator channels which can be combined in pairs - to form six 4-operator channel, they are: - 0 and 3, - 1 and 4, - 2 and 5, - 9 and 12, - 10 and 13, - 11 and 14 - */ - UINT8 extended; /* set to 1 if this channel forms up a 4op channel with another channel(only used by first of pair of channels, ie 0,1,2 and 9,10,11) */ - -unsigned char reserved[512-272];//speedup:pump up the struct size to power of 2 - -} OPL3_CH; - -/* OPL3 state */ -typedef struct { - OPL3_CH P_CH[18]; /* OPL3 chips have 18 channels */ - - UINT32 pan[18*2]; /* channels output multiplier; 2 per channel */ - - UINT32 eg_cnt; /* global envelope generator counter */ - UINT32 eg_timer; /* global envelope generator counter works at frequency = chipclock/288 (288=8*36) */ - UINT32 eg_timer_add; /* step of eg_timer */ - UINT32 eg_timer_overflow; /* envelope generator timer overlfows every 1 sample (on real chip) */ - - UINT32 fn_tab[1024]; /* fnumber->increment counter */ - - /* LFO */ - UINT8 lfo_am_depth; - UINT8 lfo_pm_depth_range; - UINT32 lfo_am_cnt; - UINT32 lfo_am_inc; - UINT32 lfo_pm_cnt; - UINT32 lfo_pm_inc; - - UINT32 noise_rng; /* 23 bit noise shift register */ - UINT32 noise_p; /* current noise 'phase' */ - UINT32 noise_f; /* current noise period */ - - UINT8 OPL3_mode; /* OPL3 extension enable flag */ - - UINT8 rhythm; /* Rhythm mode */ - - int T[2]; /* timer counters */ - int TC[2]; - UINT8 st[2]; /* timer enable */ - - UINT32 address; /* address register */ - UINT8 status; /* status flag */ - UINT8 statusmask; /* status mask */ - - UINT8 nts; /* NTS (note select) */ - - /* external event callback handlers */ - OPL3_TIMERHANDLER TimerHandler;/* TIMER handler */ - int TimerParam; /* TIMER parameter */ - OPL3_IRQHANDLER IRQHandler; /* IRQ handler */ - int IRQParam; /* IRQ parameter */ - OPL3_UPDATEHANDLER UpdateHandler;/* stream update handler */ - int UpdateParam; /* stream update parameter */ - - UINT8 type; /* chip type */ - int clock; /* master clock (Hz) */ - int rate; /* sampling rate (Hz) */ - double freqbase; /* frequency base */ - double TimerBase; /* Timer base time (==sampling time)*/ -} OPL3; - - - -/* mapping of register number (offset) to slot number used by the emulator */ -static const int slot_array[32]= -{ - 0, 2, 4, 1, 3, 5,-1,-1, - 6, 8,10, 7, 9,11,-1,-1, - 12,14,16,13,15,17,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1 -}; - -/* key scale level */ -/* table is 3dB/octave , DV converts this into 6dB/octave */ -/* 0.1875 is bit 0 weight of the envelope counter (volume) expressed in the 'decibel' scale */ -#define SC(x) ((UINT32)((x)/(0.1875/2.0))) -static const UINT32 ksl_tab[8*16]= -{ - /* OCT 0 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - /* OCT 1 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.750), SC(1.125), SC(1.500), - SC(1.875), SC(2.250), SC(2.625), SC(3.000), - /* OCT 2 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(1.125), SC(1.875), SC(2.625), - SC(3.000), SC(3.750), SC(4.125), SC(4.500), - SC(4.875), SC(5.250), SC(5.625), SC(6.000), - /* OCT 3 */ - SC(0.000), SC(0.000), SC(0.000), SC(1.875), - SC(3.000), SC(4.125), SC(4.875), SC(5.625), - SC(6.000), SC(6.750), SC(7.125), SC(7.500), - SC(7.875), SC(8.250), SC(8.625), SC(9.000), - /* OCT 4 */ - SC(0.000), SC(0.000), SC(3.000), SC(4.875), - SC(6.000), SC(7.125), SC(7.875), SC(8.625), - SC(9.000), SC(9.750),SC(10.125),SC(10.500), - SC(10.875),SC(11.250),SC(11.625),SC(12.000), - /* OCT 5 */ - SC(0.000), SC(3.000), SC(6.000), SC(7.875), - SC(9.000),SC(10.125),SC(10.875),SC(11.625), - SC(12.000),SC(12.750),SC(13.125),SC(13.500), - SC(13.875),SC(14.250),SC(14.625),SC(15.000), - /* OCT 6 */ - SC(0.000), SC(6.000), SC(9.000),SC(10.875), - SC(12.000),SC(13.125),SC(13.875),SC(14.625), - SC(15.000),SC(15.750),SC(16.125),SC(16.500), - SC(16.875),SC(17.250),SC(17.625),SC(18.000), - /* OCT 7 */ - SC(0.000), SC(9.000),SC(12.000),SC(13.875), - SC(15.000),SC(16.125),SC(16.875),SC(17.625), - SC(18.000),SC(18.750),SC(19.125),SC(19.500), - SC(19.875),SC(20.250),SC(20.625),SC(21.000) -}; -#undef SC - -/* key scale level lookup */ -static const INT32 ksl_level[4]= -{ - 31,1,2,0 -}; - -/* sustain level table (3dB per step) */ -/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ -#define SC(db) (UINT32) ( db * (2.0/ENV_STEP) ) -static const UINT32 sl_tab[16]={ - SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7), - SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31) -}; -#undef SC - - -#define RATE_STEPS (8) -static const unsigned char eg_inc[15*RATE_STEPS]={ - -/*cycle:0 1 2 3 4 5 6 7*/ - -/* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..12 0 (increment by 0 or 1) */ -/* 1 */ 0,1, 0,1, 1,1, 0,1, /* rates 00..12 1 */ -/* 2 */ 0,1, 1,1, 0,1, 1,1, /* rates 00..12 2 */ -/* 3 */ 0,1, 1,1, 1,1, 1,1, /* rates 00..12 3 */ - -/* 4 */ 1,1, 1,1, 1,1, 1,1, /* rate 13 0 (increment by 1) */ -/* 5 */ 1,1, 1,2, 1,1, 1,2, /* rate 13 1 */ -/* 6 */ 1,2, 1,2, 1,2, 1,2, /* rate 13 2 */ -/* 7 */ 1,2, 2,2, 1,2, 2,2, /* rate 13 3 */ - -/* 8 */ 2,2, 2,2, 2,2, 2,2, /* rate 14 0 (increment by 2) */ -/* 9 */ 2,2, 2,4, 2,2, 2,4, /* rate 14 1 */ -/*10 */ 2,4, 2,4, 2,4, 2,4, /* rate 14 2 */ -/*11 */ 2,4, 4,4, 2,4, 4,4, /* rate 14 3 */ - -/*12 */ 4,4, 4,4, 4,4, 4,4, /* rates 15 0, 15 1, 15 2, 15 3 for decay */ -/*13 */ 8,8, 8,8, 8,8, 8,8, /* rates 15 0, 15 1, 15 2, 15 3 for attack (zero time) */ -/*14 */ 0,0, 0,0, 0,0, 0,0, /* infinity rates for attack and decay(s) */ -}; - - -#define O(a) (a*RATE_STEPS) - -/* note that there is no O(13) in this table - it's directly in the code */ -static const unsigned char eg_rate_select[16+64+16]={ /* Envelope Generator rates (16 + 64 rates + 16 RKS) */ -/* 16 infinite time rates */ -O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), -O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), - -/* rates 00-12 */ -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), - -/* rate 13 */ -O( 4),O( 5),O( 6),O( 7), - -/* rate 14 */ -O( 8),O( 9),O(10),O(11), - -/* rate 15 */ -O(12),O(12),O(12),O(12), - -/* 16 dummy rates (same as 15 3) */ -O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12), -O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12), - -}; -#undef O - -/*rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 */ -/*shift 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0 */ -/*mask 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0, 0 */ - -#define O(a) (a*1) -static const unsigned char eg_rate_shift[16+64+16]={ /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */ -/* 16 infinite time rates */ -O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), -O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), - -/* rates 00-12 */ -O(12),O(12),O(12),O(12), -O(11),O(11),O(11),O(11), -O(10),O(10),O(10),O(10), -O( 9),O( 9),O( 9),O( 9), -O( 8),O( 8),O( 8),O( 8), -O( 7),O( 7),O( 7),O( 7), -O( 6),O( 6),O( 6),O( 6), -O( 5),O( 5),O( 5),O( 5), -O( 4),O( 4),O( 4),O( 4), -O( 3),O( 3),O( 3),O( 3), -O( 2),O( 2),O( 2),O( 2), -O( 1),O( 1),O( 1),O( 1), -O( 0),O( 0),O( 0),O( 0), - -/* rate 13 */ -O( 0),O( 0),O( 0),O( 0), - -/* rate 14 */ -O( 0),O( 0),O( 0),O( 0), - -/* rate 15 */ -O( 0),O( 0),O( 0),O( 0), - -/* 16 dummy rates (same as 15 3) */ -O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), -O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), - -}; -#undef O - - -/* multiple table */ -#define SC(x) ((UINT32)((x)*2)) -static const UINT8 mul_tab[16]= { -/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,10,12,12,15,15 */ - SC(0.50), SC(1.00), SC(2.00), SC(3.00), SC(4.00), SC(5.00), SC(6.00), SC(7.00), - SC(8.00), SC(9.00),SC(10.00),SC(10.00),SC(12.00),SC(12.00),SC(15.00),SC(15.00) -}; -#undef SC - -/* TL_TAB_LEN is calculated as: - -* (12+1)=13 - sinus amplitude bits (Y axis) -* additional 1: to compensate for calculations of negative part of waveform -* (if we don't add it then the greatest possible _negative_ value would be -2 -* and we really need -1 for waveform #7) -* 2 - sinus sign bit (Y axis) -* TL_RES_LEN - sinus resolution (X axis) -*/ -#define TL_TAB_LEN (13*2*TL_RES_LEN) -static signed int tl_tab[TL_TAB_LEN]; - -#define ENV_QUIET (TL_TAB_LEN>>4) - -/* sin waveform table in 'decibel' scale */ -/* there are eight waveforms on OPL3 chips */ -static unsigned int sin_tab[SIN_LEN * 8]; - - -/* LFO Amplitude Modulation table (verified on real YM3812) - 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples - - Length: 210 elements. - - Each of the elements has to be repeated - exactly 64 times (on 64 consecutive samples). - The whole table takes: 64 * 210 = 13440 samples. - - When AM = 1 data is used directly - When AM = 0 data is divided by 4 before being used (loosing precision is important) -*/ - -#define LFO_AM_TAB_ELEMENTS 210 - -static const UINT8 lfo_am_table[LFO_AM_TAB_ELEMENTS] = { -0,0,0,0,0,0,0, -1,1,1,1, -2,2,2,2, -3,3,3,3, -4,4,4,4, -5,5,5,5, -6,6,6,6, -7,7,7,7, -8,8,8,8, -9,9,9,9, -10,10,10,10, -11,11,11,11, -12,12,12,12, -13,13,13,13, -14,14,14,14, -15,15,15,15, -16,16,16,16, -17,17,17,17, -18,18,18,18, -19,19,19,19, -20,20,20,20, -21,21,21,21, -22,22,22,22, -23,23,23,23, -24,24,24,24, -25,25,25,25, -26,26,26, -25,25,25,25, -24,24,24,24, -23,23,23,23, -22,22,22,22, -21,21,21,21, -20,20,20,20, -19,19,19,19, -18,18,18,18, -17,17,17,17, -16,16,16,16, -15,15,15,15, -14,14,14,14, -13,13,13,13, -12,12,12,12, -11,11,11,11, -10,10,10,10, -9,9,9,9, -8,8,8,8, -7,7,7,7, -6,6,6,6, -5,5,5,5, -4,4,4,4, -3,3,3,3, -2,2,2,2, -1,1,1,1 -}; - -/* LFO Phase Modulation table (verified on real YM3812) */ -static const INT8 lfo_pm_table[8*8*2] = { - -/* FNUM2/FNUM = 00 0xxxxxxx (0x0000) */ -0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/ -0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 00 1xxxxxxx (0x0080) */ -0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/ -1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 01 0xxxxxxx (0x0100) */ -1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/ -2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 01 1xxxxxxx (0x0180) */ -1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/ -3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 10 0xxxxxxx (0x0200) */ -2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/ -4, 2, 0,-2,-4,-2, 0, 2, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 10 1xxxxxxx (0x0280) */ -2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/ -5, 2, 0,-2,-5,-2, 0, 2, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 11 0xxxxxxx (0x0300) */ -3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/ -6, 3, 0,-3,-6,-3, 0, 3, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 11 1xxxxxxx (0x0380) */ -3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/ -7, 3, 0,-3,-7,-3, 0, 3 /*LFO PM depth = 1*/ -}; - - -/* lock level of common table */ -static int num_lock = 0; - -/* work table */ -static void *cur_chip = NULL; /* current chip point */ -static OPL3_SLOT *SLOT7_1,*SLOT7_2,*SLOT8_1,*SLOT8_2; - -static signed int phase_modulation; /* phase modulation input (SLOT 2) */ -static signed int phase_modulation2; /* phase modulation input (SLOT 3 in 4 operator channels) */ -static signed int chanout[18]; /* 18 channels */ - - -static UINT32 LFO_AM; -static INT32 LFO_PM; - - - -INLINE int limit( int val, int max, int min ) { - if ( val > max ) - val = max; - else if ( val < min ) - val = min; - - return val; -} - - -/* status set and IRQ handling */ -INLINE void OPL3_STATUS_SET(OPL3 *chip,int flag) -{ - /* set status flag masking out disabled IRQs */ - chip->status |= (flag & chip->statusmask); - if(!(chip->status & 0x80)) - { - if(chip->status & 0x7f) - { /* IRQ on */ - chip->status |= 0x80; - /* callback user interrupt handler (IRQ is OFF to ON) */ - if(chip->IRQHandler) (chip->IRQHandler)(chip->IRQParam,1); - } - } -} - -/* status reset and IRQ handling */ -INLINE void OPL3_STATUS_RESET(OPL3 *chip,int flag) -{ - /* reset status flag */ - chip->status &= ~flag; - if(chip->status & 0x80) - { - if (!(chip->status & 0x7f)) - { - chip->status &= 0x7f; - /* callback user interrupt handler (IRQ is ON to OFF) */ - if(chip->IRQHandler) (chip->IRQHandler)(chip->IRQParam,0); - } - } -} - -/* IRQ mask set */ -INLINE void OPL3_STATUSMASK_SET(OPL3 *chip,int flag) -{ - chip->statusmask = flag; - /* IRQ handling check */ - OPL3_STATUS_SET(chip,0); - OPL3_STATUS_RESET(chip,0); -} - - -/* advance LFO to next sample */ -INLINE void advance_lfo(OPL3 *chip) -{ - UINT8 tmp; - - /* LFO */ - chip->lfo_am_cnt += chip->lfo_am_inc; - if (chip->lfo_am_cnt >= (LFO_AM_TAB_ELEMENTS<lfo_am_cnt -= (LFO_AM_TAB_ELEMENTS<lfo_am_cnt >> LFO_SH ]; - - if (chip->lfo_am_depth) - LFO_AM = tmp; - else - LFO_AM = tmp>>2; - - chip->lfo_pm_cnt += chip->lfo_pm_inc; - LFO_PM = ((chip->lfo_pm_cnt>>LFO_SH) & 7) | chip->lfo_pm_depth_range; -} - -/* advance to next sample */ -INLINE void advance(OPL3 *chip) -{ - OPL3_CH *CH; - OPL3_SLOT *op; - int i; - -//profiler_mark(PROFILER_USER3); - chip->eg_timer += chip->eg_timer_add; - - while (chip->eg_timer >= chip->eg_timer_overflow) - { - chip->eg_timer -= chip->eg_timer_overflow; - - chip->eg_cnt++; - - for (i=0; i<9*2*2; i++) - { - CH = &chip->P_CH[i/2]; - op = &CH->SLOT[i&1]; -#if 1 - /* Envelope Generator */ - switch(op->state) - { - case EG_ATT: /* attack phase */ -// if ( !(chip->eg_cnt & ((1<eg_sh_ar)-1) ) ) - if ( !(chip->eg_cnt & op->eg_m_ar) ) - { - op->volume += (~op->volume * - (eg_inc[op->eg_sel_ar + ((chip->eg_cnt>>op->eg_sh_ar)&7)]) - ) >>3; - - if (op->volume <= MIN_ATT_INDEX) - { - op->volume = MIN_ATT_INDEX; - op->state = EG_DEC; - } - - } - break; - - case EG_DEC: /* decay phase */ -// if ( !(chip->eg_cnt & ((1<eg_sh_dr)-1) ) ) - if ( !(chip->eg_cnt & op->eg_m_dr) ) - { - op->volume += eg_inc[op->eg_sel_dr + ((chip->eg_cnt>>op->eg_sh_dr)&7)]; - - if ( op->volume >= op->sl ) - op->state = EG_SUS; - - } - break; - - case EG_SUS: /* sustain phase */ - - /* this is important behaviour: - one can change percusive/non-percussive modes on the fly and - the chip will remain in sustain phase - verified on real YM3812 */ - - if(op->eg_type) /* non-percussive mode */ - { - /* do nothing */ - } - else /* percussive mode */ - { - /* during sustain phase chip adds Release Rate (in percussive mode) */ -// if ( !(chip->eg_cnt & ((1<eg_sh_rr)-1) ) ) - if ( !(chip->eg_cnt & op->eg_m_rr) ) - { - op->volume += eg_inc[op->eg_sel_rr + ((chip->eg_cnt>>op->eg_sh_rr)&7)]; - - if ( op->volume >= MAX_ATT_INDEX ) - op->volume = MAX_ATT_INDEX; - } - /* else do nothing in sustain phase */ - } - break; - - case EG_REL: /* release phase */ -// if ( !(chip->eg_cnt & ((1<eg_sh_rr)-1) ) ) - if ( !(chip->eg_cnt & op->eg_m_rr) ) - { - op->volume += eg_inc[op->eg_sel_rr + ((chip->eg_cnt>>op->eg_sh_rr)&7)]; - - if ( op->volume >= MAX_ATT_INDEX ) - { - op->volume = MAX_ATT_INDEX; - op->state = EG_OFF; - } - - } - break; - - default: - break; - } -#endif - } - } -//profiler_mark(PROFILER_END); - -//profiler_mark(PROFILER_USER4); - for (i=0; i<9*2*2; i++) - { - CH = &chip->P_CH[i/2]; - op = &CH->SLOT[i&1]; - - /* Phase Generator */ - if(op->vib) - { - UINT8 block; - unsigned int block_fnum = CH->block_fnum; - - unsigned int fnum_lfo = (block_fnum&0x0380) >> 7; - - signed int lfo_fn_table_index_offset = lfo_pm_table[LFO_PM + 16*fnum_lfo ]; - - if (lfo_fn_table_index_offset) /* LFO phase modulation active */ - { - block_fnum += lfo_fn_table_index_offset; - block = (block_fnum&0x1c00) >> 10; - op->Cnt += (chip->fn_tab[block_fnum&0x03ff] >> (7-block)) * op->mul; - } - else /* LFO phase modulation = zero */ - { - op->Cnt += op->Incr; - } - } - else /* LFO phase modulation disabled for this operator */ - { - op->Cnt += op->Incr; - } - } -//profiler_mark(PROFILER_END); - - /* The Noise Generator of the YM3812 is 23-bit shift register. - * Period is equal to 2^23-2 samples. - * Register works at sampling frequency of the chip, so output - * can change on every sample. - * - * Output of the register and input to the bit 22 is: - * bit0 XOR bit14 XOR bit15 XOR bit22 - * - * Simply use bit 22 as the noise output. - */ - - chip->noise_p += chip->noise_f; - i = chip->noise_p >> FREQ_SH; /* number of events (shifts of the shift register) */ - chip->noise_p &= FREQ_MASK; - while (i) - { - /* - UINT32 j; - j = ( (chip->noise_rng) ^ (chip->noise_rng>>14) ^ (chip->noise_rng>>15) ^ (chip->noise_rng>>22) ) & 1; - chip->noise_rng = (j<<22) | (chip->noise_rng>>1); - */ - - /* - Instead of doing all the logic operations above, we - use a trick here (and use bit 0 as the noise output). - The difference is only that the noise bit changes one - step ahead. This doesn't matter since we don't know - what is real state of the noise_rng after the reset. - */ - - if (chip->noise_rng & 1) chip->noise_rng ^= 0x800302; - chip->noise_rng >>= 1; - - i--; - } -} - - -INLINE signed int op_calc(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab) -{ - UINT32 p; - - p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + (pm<<16))) >> FREQ_SH ) & SIN_MASK) ]; - - if (p >= TL_TAB_LEN) - return 0; - return tl_tab[p]; -} - -INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab) -{ - UINT32 p; - - p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + pm))>>FREQ_SH) & SIN_MASK)]; - - if (p >= TL_TAB_LEN) - return 0; - return tl_tab[p]; -} - - -#define volume_calc(OP) ((OP)->TLL + ((UINT32)(OP)->volume) + (LFO_AM & (OP)->AMmask)) - -/* calculate output of a standard 2 operator channel - (or 1st part of a 4-op channel) */ -INLINE void chan_calc( OPL3_CH *CH ) -{ - OPL3_SLOT *SLOT; - unsigned int env; - signed int out; - - phase_modulation = 0; - phase_modulation2= 0; - - /* SLOT 1 */ - SLOT = &CH->SLOT[SLOT1]; - env = volume_calc(SLOT); - out = SLOT->op1_out[0] + SLOT->op1_out[1]; - SLOT->op1_out[0] = SLOT->op1_out[1]; - SLOT->op1_out[1] = 0; - if( env < ENV_QUIET ) - { - if (!SLOT->FB) - out = 0; - SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB), SLOT->wavetable ); - } - *SLOT->connect += SLOT->op1_out[1]; -//logerror("out0=%5i vol0=%4i ", SLOT->op1_out[1], env ); - - /* SLOT 2 */ - SLOT++; - env = volume_calc(SLOT); - if( env < ENV_QUIET ) - *SLOT->connect += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable); - -//logerror("out1=%5i vol1=%4i\n", op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable), env ); - -} - -/* calculate output of a 2nd part of 4-op channel */ -INLINE void chan_calc_ext( OPL3_CH *CH ) -{ - OPL3_SLOT *SLOT; - unsigned int env; - - phase_modulation = 0; - - /* SLOT 1 */ - SLOT = &CH->SLOT[SLOT1]; - env = volume_calc(SLOT); - if( env < ENV_QUIET ) - *SLOT->connect += op_calc(SLOT->Cnt, env, phase_modulation2, SLOT->wavetable ); - - /* SLOT 2 */ - SLOT++; - env = volume_calc(SLOT); - if( env < ENV_QUIET ) - *SLOT->connect += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable); - -} - -/* - operators used in the rhythm sounds generation process: - - Envelope Generator: - -channel operator register number Bass High Snare Tom Top -/ slot number TL ARDR SLRR Wave Drum Hat Drum Tom Cymbal - 6 / 0 12 50 70 90 f0 + - 6 / 1 15 53 73 93 f3 + - 7 / 0 13 51 71 91 f1 + - 7 / 1 16 54 74 94 f4 + - 8 / 0 14 52 72 92 f2 + - 8 / 1 17 55 75 95 f5 + - - Phase Generator: - -channel operator register number Bass High Snare Tom Top -/ slot number MULTIPLE Drum Hat Drum Tom Cymbal - 6 / 0 12 30 + - 6 / 1 15 33 + - 7 / 0 13 31 + + + - 7 / 1 16 34 ----- n o t u s e d ----- - 8 / 0 14 32 + - 8 / 1 17 35 + + - -channel operator register number Bass High Snare Tom Top -number number BLK/FNUM2 FNUM Drum Hat Drum Tom Cymbal - 6 12,15 B6 A6 + - - 7 13,16 B7 A7 + + + - - 8 14,17 B8 A8 + + + - -*/ - -/* calculate rhythm */ - -INLINE void chan_calc_rhythm( OPL3_CH *CH, unsigned int noise ) -{ - OPL3_SLOT *SLOT; - signed int out; - unsigned int env; - - - /* Bass Drum (verified on real YM3812): - - depends on the channel 6 'connect' register: - when connect = 0 it works the same as in normal (non-rhythm) mode (op1->op2->out) - when connect = 1 _only_ operator 2 is present on output (op2->out), operator 1 is ignored - - output sample always is multiplied by 2 - */ - - phase_modulation = 0; - - /* SLOT 1 */ - SLOT = &CH[6].SLOT[SLOT1]; - env = volume_calc(SLOT); - - out = SLOT->op1_out[0] + SLOT->op1_out[1]; - SLOT->op1_out[0] = SLOT->op1_out[1]; - - if (!SLOT->CON) - phase_modulation = SLOT->op1_out[0]; - //else ignore output of operator 1 - - SLOT->op1_out[1] = 0; - if( env < ENV_QUIET ) - { - if (!SLOT->FB) - out = 0; - SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB), SLOT->wavetable ); - } - - /* SLOT 2 */ - SLOT++; - env = volume_calc(SLOT); - if( env < ENV_QUIET ) - chanout[6] += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable) * 2; - - - /* Phase generation is based on: */ - // HH (13) channel 7->slot 1 combined with channel 8->slot 2 (same combination as TOP CYMBAL but different output phases) - // SD (16) channel 7->slot 1 - // TOM (14) channel 8->slot 1 - // TOP (17) channel 7->slot 1 combined with channel 8->slot 2 (same combination as HIGH HAT but different output phases) - - /* Envelope generation based on: */ - // HH channel 7->slot1 - // SD channel 7->slot2 - // TOM channel 8->slot1 - // TOP channel 8->slot2 - - - /* The following formulas can be well optimized. - I leave them in direct form for now (in case I've missed something). - */ - - /* High Hat (verified on real YM3812) */ - env = volume_calc(SLOT7_1); - if( env < ENV_QUIET ) - { - - /* high hat phase generation: - phase = d0 or 234 (based on frequency only) - phase = 34 or 2d0 (based on noise) - */ - - /* base frequency derived from operator 1 in channel 7 */ - unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1; - unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1; - unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1; - - unsigned char res1 = (bit2 ^ bit7) | bit3; - - /* when res1 = 0 phase = 0x000 | 0xd0; */ - /* when res1 = 1 phase = 0x200 | (0xd0>>2); */ - UINT32 phase = res1 ? (0x200|(0xd0>>2)) : 0xd0; - - /* enable gate based on frequency of operator 2 in channel 8 */ - unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1; - unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1; - - unsigned char res2 = (bit3e ^ bit5e); - - /* when res2 = 0 pass the phase from calculation above (res1); */ - /* when res2 = 1 phase = 0x200 | (0xd0>>2); */ - if (res2) - phase = (0x200|(0xd0>>2)); - - - /* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */ - /* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */ - if (phase&0x200) - { - if (noise) - phase = 0x200|0xd0; - } - else - /* when phase & 0x200 is clear and noise=1 then phase = 0xd0>>2 */ - /* when phase & 0x200 is clear and noise=0 then phase = 0xd0, ie no change */ - { - if (noise) - phase = 0xd0>>2; - } - - chanout[7] += op_calc(phase<wavetable) * 2; - } - - /* Snare Drum (verified on real YM3812) */ - env = volume_calc(SLOT7_2); - if( env < ENV_QUIET ) - { - /* base frequency derived from operator 1 in channel 7 */ - unsigned char bit8 = ((SLOT7_1->Cnt>>FREQ_SH)>>8)&1; - - /* when bit8 = 0 phase = 0x100; */ - /* when bit8 = 1 phase = 0x200; */ - UINT32 phase = bit8 ? 0x200 : 0x100; - - /* Noise bit XOR'es phase by 0x100 */ - /* when noisebit = 0 pass the phase from calculation above */ - /* when noisebit = 1 phase ^= 0x100; */ - /* in other words: phase ^= (noisebit<<8); */ - if (noise) - phase ^= 0x100; - - chanout[7] += op_calc(phase<wavetable) * 2; - } - - /* Tom Tom (verified on real YM3812) */ - env = volume_calc(SLOT8_1); - if( env < ENV_QUIET ) - chanout[8] += op_calc(SLOT8_1->Cnt, env, 0, SLOT8_1->wavetable) * 2; - - /* Top Cymbal (verified on real YM3812) */ - env = volume_calc(SLOT8_2); - if( env < ENV_QUIET ) - { - /* base frequency derived from operator 1 in channel 7 */ - unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1; - unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1; - unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1; - - unsigned char res1 = (bit2 ^ bit7) | bit3; - - /* when res1 = 0 phase = 0x000 | 0x100; */ - /* when res1 = 1 phase = 0x200 | 0x100; */ - UINT32 phase = res1 ? 0x300 : 0x100; - - /* enable gate based on frequency of operator 2 in channel 8 */ - unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1; - unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1; - - unsigned char res2 = (bit3e ^ bit5e); - /* when res2 = 0 pass the phase from calculation above (res1); */ - /* when res2 = 1 phase = 0x200 | 0x100; */ - if (res2) - phase = 0x300; - - chanout[8] += op_calc(phase<wavetable) * 2; - } - -} - - -/* generic table initialize */ -static int init_tables(void) -{ - signed int i,x; - signed int n; - double o,m; - - - for (x=0; x>= 4; /* 12 bits here */ - if (n&1) /* round to nearest */ - n = (n>>1)+1; - else - n = n>>1; - /* 11 bits here (rounded) */ - n <<= 1; /* 12 bits here (as in real chip) */ - tl_tab[ x*2 + 0 ] = n; - tl_tab[ x*2 + 1 ] = ~tl_tab[ x*2 + 0 ]; /* this *is* different from OPL2 (verified on real YMF262) */ - - for (i=1; i<13; i++) - { - tl_tab[ x*2+0 + i*2*TL_RES_LEN ] = tl_tab[ x*2+0 ]>>i; - tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = ~tl_tab[ x*2+0 + i*2*TL_RES_LEN ]; /* this *is* different from OPL2 (verified on real YMF262) */ - } - #if 0 - logerror("tl %04i", x*2); - for (i=0; i<13; i++) - logerror(", [%02i] %5i", i*2, tl_tab[ x*2 +0 + i*2*TL_RES_LEN ] ); /* positive */ - logerror("\n"); - - logerror("tl %04i", x*2); - for (i=0; i<13; i++) - logerror(", [%02i] %5i", i*2, tl_tab[ x*2 +1 + i*2*TL_RES_LEN ] ); /* negative */ - logerror("\n"); - #endif - } - - for (i=0; i0.0) - o = 8*log(1.0/m)/log(2.0); /* convert to 'decibels' */ - else - o = 8*log(-1.0/m)/log(2.0); /* convert to 'decibels' */ - - o = o / (ENV_STEP/4); - - n = (int)(2.0*o); - if (n&1) /* round to nearest */ - n = (n>>1)+1; - else - n = n>>1; - - sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 ); - - /*logerror("YMF262.C: sin [%4i (hex=%03x)]= %4i (tl_tab value=%5i)\n", i, i, sin_tab[i], tl_tab[sin_tab[i]] );*/ - } - - for (i=0; i>1) ]; - - /* waveform 3: _ _ _ _ */ - /* / |_/ |_/ |_/ |_*/ - /* abs(output only first quarter of the sinus waveform) */ - - if (i & (1<<(SIN_BITS-2)) ) - sin_tab[3*SIN_LEN+i] = TL_TAB_LEN; - else - sin_tab[3*SIN_LEN+i] = sin_tab[i & (SIN_MASK>>2)]; - - /* waveform 4: */ - /* /\ ____/\ ____*/ - /* \/ \/ */ - /* output whole sinus waveform in half the cycle(step=2) and output 0 on the other half of cycle */ - - if (i & (1<<(SIN_BITS-1)) ) - sin_tab[4*SIN_LEN+i] = TL_TAB_LEN; - else - sin_tab[4*SIN_LEN+i] = sin_tab[i*2]; - - /* waveform 5: */ - /* /\/\____/\/\____*/ - /* */ - /* output abs(whole sinus) waveform in half the cycle(step=2) and output 0 on the other half of cycle */ - - if (i & (1<<(SIN_BITS-1)) ) - sin_tab[5*SIN_LEN+i] = TL_TAB_LEN; - else - sin_tab[5*SIN_LEN+i] = sin_tab[(i*2) & (SIN_MASK>>1) ]; - - /* waveform 6: ____ ____ */ - /* */ - /* ____ ____*/ - /* output maximum in half the cycle and output minimum on the other half of cycle */ - - if (i & (1<<(SIN_BITS-1)) ) - sin_tab[6*SIN_LEN+i] = 1; /* negative */ - else - sin_tab[6*SIN_LEN+i] = 0; /* positive */ - - /* waveform 7: */ - /* |\____ |\____ */ - /* \| \|*/ - /* output sawtooth waveform */ - - if (i & (1<<(SIN_BITS-1)) ) - x = ((SIN_LEN-1)-i)*16 + 1; /* negative: from 8177 to 1 */ - else - x = i*16; /*positive: from 0 to 8176 */ - - if (x > TL_TAB_LEN) - x = TL_TAB_LEN; /* clip to the allowed range */ - - sin_tab[7*SIN_LEN+i] = x; - - //logerror("YMF262.C: sin1[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[1*SIN_LEN+i], tl_tab[sin_tab[1*SIN_LEN+i]] ); - //logerror("YMF262.C: sin2[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[2*SIN_LEN+i], tl_tab[sin_tab[2*SIN_LEN+i]] ); - //logerror("YMF262.C: sin3[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[3*SIN_LEN+i], tl_tab[sin_tab[3*SIN_LEN+i]] ); - //logerror("YMF262.C: sin4[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[4*SIN_LEN+i], tl_tab[sin_tab[4*SIN_LEN+i]] ); - //logerror("YMF262.C: sin5[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[5*SIN_LEN+i], tl_tab[sin_tab[5*SIN_LEN+i]] ); - //logerror("YMF262.C: sin6[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[6*SIN_LEN+i], tl_tab[sin_tab[6*SIN_LEN+i]] ); - //logerror("YMF262.C: sin7[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[7*SIN_LEN+i], tl_tab[sin_tab[7*SIN_LEN+i]] ); - } - /*logerror("YMF262.C: ENV_QUIET= %08x (dec*8=%i)\n", ENV_QUIET, ENV_QUIET*8 );*/ - -#ifdef SAVE_SAMPLE - sample[0]=fopen("sampsum.pcm","wb"); -#endif - - return 1; -} - -static void OPLCloseTable( void ) -{ -#ifdef SAVE_SAMPLE - fclose(sample[0]); -#endif -} - - - -static void OPL3_initalize(OPL3 *chip) -{ - int i; - - /* frequency base */ - chip->freqbase = (chip->rate) ? ((double)chip->clock / (8.0*36)) / chip->rate : 0; -#if 0 - chip->rate = (double)chip->clock / (8.0*36); - chip->freqbase = 1.0; -#endif - - /* logerror("YMF262: freqbase=%f\n", chip->freqbase); */ - - /* Timer base time */ - chip->TimerBase = 1.0 / ((double)chip->clock / (8.0*36) ); - - /* make fnumber -> increment counter table */ - for( i=0 ; i < 1024 ; i++ ) - { - /* opn phase increment counter = 20bit */ - chip->fn_tab[i] = (UINT32)( (double)i * 64 * chip->freqbase * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */ -#if 0 - logerror("YMF262.C: fn_tab[%4i] = %08x (dec=%8i)\n", - i, chip->fn_tab[i]>>6, chip->fn_tab[i]>>6 ); -#endif - } - -#if 0 - for( i=0 ; i < 16 ; i++ ) - { - logerror("YMF262.C: sl_tab[%i] = %08x\n", - i, sl_tab[i] ); - } - for( i=0 ; i < 8 ; i++ ) - { - int j; - logerror("YMF262.C: ksl_tab[oct=%2i] =",i); - for (j=0; j<16; j++) - { - logerror("%08x ", ksl_tab[i*16+j] ); - } - logerror("\n"); - } -#endif - - - /* Amplitude modulation: 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */ - /* One entry from LFO_AM_TABLE lasts for 64 samples */ - chip->lfo_am_inc = (UINT32)((1.0 / 64.0 ) * (1<freqbase); - - /* Vibrato: 8 output levels (triangle waveform); 1 level takes 1024 samples */ - chip->lfo_pm_inc = (UINT32)((1.0 / 1024.0) * (1<freqbase); - - /*logerror ("chip->lfo_am_inc = %8x ; chip->lfo_pm_inc = %8x\n", chip->lfo_am_inc, chip->lfo_pm_inc);*/ - - /* Noise generator: a step takes 1 sample */ - chip->noise_f = (UINT32)((1.0 / 1.0) * (1<freqbase); - - chip->eg_timer_add = (UINT32)((1<freqbase); - chip->eg_timer_overflow = ( 1 ) * (1<eg_timer_add, chip->eg_timer_overflow);*/ - -} - -INLINE void FM_KEYON(OPL3_SLOT *SLOT, UINT32 key_set) -{ - if( !SLOT->key ) - { - /* restart Phase Generator */ - SLOT->Cnt = 0; - /* phase -> Attack */ - SLOT->state = EG_ATT; - } - SLOT->key |= key_set; -} - -INLINE void FM_KEYOFF(OPL3_SLOT *SLOT, UINT32 key_clr) -{ - if( SLOT->key ) - { - SLOT->key &= key_clr; - - if( !SLOT->key ) - { - /* phase -> Release */ - if (SLOT->state>EG_REL) - SLOT->state = EG_REL; - } - } -} - -/* update phase increment counter of operator (also update the EG rates if necessary) */ -INLINE void CALC_FCSLOT(OPL3_CH *CH,OPL3_SLOT *SLOT) -{ - int ksr; - - /* (frequency) phase increment counter */ - SLOT->Incr = CH->fc * SLOT->mul; - ksr = CH->kcode >> SLOT->KSR; - - if( SLOT->ksr != ksr ) - { - SLOT->ksr = ksr; - - /* calculate envelope generator rates */ - if ((SLOT->ar + SLOT->ksr) < 16+60) - { - SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; - SLOT->eg_m_ar = (1<eg_sh_ar)-1; - SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; - } - else - { - SLOT->eg_sh_ar = 0; - SLOT->eg_m_ar = (1<eg_sh_ar)-1; - SLOT->eg_sel_ar = 13*RATE_STEPS; - } - SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; - SLOT->eg_m_dr = (1<eg_sh_dr)-1; - SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; - SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; - SLOT->eg_m_rr = (1<eg_sh_rr)-1; - SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; - } -} - -/* set multi,am,vib,EG-TYP,KSR,mul */ -INLINE void set_mul(OPL3 *chip,int slot,int v) -{ - OPL3_CH *CH = &chip->P_CH[slot/2]; - OPL3_SLOT *SLOT = &CH->SLOT[slot&1]; - - SLOT->mul = mul_tab[v&0x0f]; - SLOT->KSR = (v&0x10) ? 0 : 2; - SLOT->eg_type = (v&0x20); - SLOT->vib = (v&0x40); - SLOT->AMmask = (v&0x80) ? ~0 : 0; - - if (chip->OPL3_mode & 1) - { - int chan_no = slot/2; - - /* in OPL3 mode */ - //DO THIS: - //if this is one of the slots of 1st channel forming up a 4-op channel - //do normal operation - //else normal 2 operator function - //OR THIS: - //if this is one of the slots of 2nd channel forming up a 4-op channel - //update it using channel data of 1st channel of a pair - //else normal 2 operator function - switch(chan_no) - { - case 0: case 1: case 2: - case 9: case 10: case 11: - if (CH->extended) - { - /* normal */ - CALC_FCSLOT(CH,SLOT); - } - else - { - /* normal */ - CALC_FCSLOT(CH,SLOT); - } - break; - case 3: case 4: case 5: - case 12: case 13: case 14: - if ((CH-3)->extended) - { - /* update this SLOT using frequency data for 1st channel of a pair */ - CALC_FCSLOT(CH-3,SLOT); - } - else - { - /* normal */ - CALC_FCSLOT(CH,SLOT); - } - break; - default: - /* normal */ - CALC_FCSLOT(CH,SLOT); - break; - } - } - else - { - /* in OPL2 mode */ - CALC_FCSLOT(CH,SLOT); - } -} - -/* set ksl & tl */ -INLINE void set_ksl_tl(OPL3 *chip,int slot,int v) -{ - OPL3_CH *CH = &chip->P_CH[slot/2]; - OPL3_SLOT *SLOT = &CH->SLOT[slot&1]; - - SLOT->ksl = ksl_level[(v>>6)&3]; /* 0 / 3.0 / 1.5 / 6.0 dB/OCT */ - SLOT->TL = (v&0x3f)<<(ENV_BITS-1-7); /* 7 bits TL (bit 6 = always 0) */ - - if (chip->OPL3_mode & 1) - { - int chan_no = slot/2; - - /* in OPL3 mode */ - //DO THIS: - //if this is one of the slots of 1st channel forming up a 4-op channel - //do normal operation - //else normal 2 operator function - //OR THIS: - //if this is one of the slots of 2nd channel forming up a 4-op channel - //update it using channel data of 1st channel of a pair - //else normal 2 operator function - switch(chan_no) - { - case 0: case 1: case 2: - case 9: case 10: case 11: - if (CH->extended) - { - /* normal */ - SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); - } - else - { - /* normal */ - SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); - } - break; - case 3: case 4: case 5: - case 12: case 13: case 14: - if ((CH-3)->extended) - { - /* update this SLOT using frequency data for 1st channel of a pair */ - SLOT->TLL = SLOT->TL + ((CH-3)->ksl_base>>SLOT->ksl); - } - else - { - /* normal */ - SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); - } - break; - default: - /* normal */ - SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); - break; - } - } - else - { - /* in OPL2 mode */ - SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); - } - -} - -/* set attack rate & decay rate */ -INLINE void set_ar_dr(OPL3 *chip,int slot,int v) -{ - OPL3_CH *CH = &chip->P_CH[slot/2]; - OPL3_SLOT *SLOT = &CH->SLOT[slot&1]; - - SLOT->ar = (v>>4) ? 16 + ((v>>4) <<2) : 0; - - if ((SLOT->ar + SLOT->ksr) < 16+60) /* verified on real YMF262 - all 15 x rates take "zero" time */ - { - SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; - SLOT->eg_m_ar = (1<eg_sh_ar)-1; - SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; - } - else - { - SLOT->eg_sh_ar = 0; - SLOT->eg_m_ar = (1<eg_sh_ar)-1; - SLOT->eg_sel_ar = 13*RATE_STEPS; - } - - SLOT->dr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; - SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; - SLOT->eg_m_dr = (1<eg_sh_dr)-1; - SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; -} - -/* set sustain level & release rate */ -INLINE void set_sl_rr(OPL3 *chip,int slot,int v) -{ - OPL3_CH *CH = &chip->P_CH[slot/2]; - OPL3_SLOT *SLOT = &CH->SLOT[slot&1]; - - SLOT->sl = sl_tab[ v>>4 ]; - - SLOT->rr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; - SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; - SLOT->eg_m_rr = (1<eg_sh_rr)-1; - SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; -} - - -static void update_channels(OPL3 *chip, OPL3_CH *CH) -{ - /* update channel passed as a parameter and a channel at CH+=3; */ - if (CH->extended) - { /* we've just switched to combined 4 operator mode */ - - } - else - { /* we've just switched to normal 2 operator mode */ - - } - -} - -/* write a value v to register r on OPL chip */ -static void OPL3WriteReg(OPL3 *chip, int r, int v) -{ - OPL3_CH *CH; - unsigned int ch_offset = 0; - int slot; - int block_fnum; - - - -#ifdef LOG_CYM_FILE - if ((cymfile) && ((r&255)!=0) && (r!=255) ) - { - if (r>0xff) - fputc( (unsigned char)0xff, cymfile );/*mark writes to second register set*/ - - fputc( (unsigned char)r&0xff, cymfile ); - fputc( (unsigned char)v, cymfile ); - } -#endif - - if(r&0x100) - { - switch(r) - { - case 0x101: /* test register */ - return; - break; - case 0x104: /* 6 channels enable */ - { - UINT8 prev; - - CH = &chip->P_CH[0]; /* channel 0 */ - prev = CH->extended; - CH->extended = (v>>0) & 1; - if(prev != CH->extended) - update_channels(chip, CH); - CH++; /* channel 1 */ - prev = CH->extended; - CH->extended = (v>>1) & 1; - if(prev != CH->extended) - update_channels(chip, CH); - CH++; /* channel 2 */ - prev = CH->extended; - CH->extended = (v>>2) & 1; - if(prev != CH->extended) - update_channels(chip, CH); - - - CH = &chip->P_CH[9]; /* channel 9 */ - prev = CH->extended; - CH->extended = (v>>3) & 1; - if(prev != CH->extended) - update_channels(chip, CH); - CH++; /* channel 10 */ - prev = CH->extended; - CH->extended = (v>>4) & 1; - if(prev != CH->extended) - update_channels(chip, CH); - CH++; /* channel 11 */ - prev = CH->extended; - CH->extended = (v>>5) & 1; - if(prev != CH->extended) - update_channels(chip, CH); - - } - return; - break; - case 0x105: /* OPL3 extensions enable register */ - - chip->OPL3_mode = v&0x01; /* OPL3 mode when bit0=1 otherwise it is OPL2 mode */ - - /* following behaviour was tested on real YMF262, - switching OPL3/OPL2 modes on the fly: - - does not change the waveform previously selected (unless when ....) - - does not update CH.A, CH.B, CH.C and CH.D output selectors (registers c0-c8) (unless when ....) - - does not disable channels 9-17 on OPL3->OPL2 switch - - does not switch 4 operator channels back to 2 operator channels - */ - - return; - break; - - default: - if (r < 0x120) - logerror("YMF262: write to unknown register (set#2): %03x value=%02x\n",r,v); - break; - } - - ch_offset = 9; /* register page #2 starts from channel 9 (counting from 0) */ - } - - /* adjust bus to 8 bits */ - r &= 0xff; - v &= 0xff; - - - switch(r&0xe0) - { - case 0x00: /* 00-1f:control */ - switch(r&0x1f) - { - case 0x01: /* test register */ - break; - case 0x02: /* Timer 1 */ - chip->T[0] = (256-v)*4; - break; - case 0x03: /* Timer 2 */ - chip->T[1] = (256-v)*16; - break; - case 0x04: /* IRQ clear / mask and Timer enable */ - if(v&0x80) - { /* IRQ flags clear */ - OPL3_STATUS_RESET(chip,0x60); - } - else - { /* set IRQ mask ,timer enable */ - chip->st[0] = v & 1; - chip->st[1] = (v>>1) & 1; - - /* IRQRST,T1MSK,t2MSK,x,x,x,ST2,ST1 */ - OPL3_STATUS_RESET(chip, v & 0x60); - OPL3_STATUSMASK_SET(chip, (~v) & 0x60 ); - - /* timer 1 */ - if(chip->st[0]) - { - chip->TC[0]=chip->T[0]*20; - double interval = (double)chip->T[0]*chip->TimerBase; - if (chip->TimerHandler) (chip->TimerHandler)(chip->TimerParam+0,interval); - } - /* timer 2 */ - if(chip->st[1]) - { - chip->TC[1]=chip->T[1]*20; - double interval =(double)chip->T[1]*chip->TimerBase; - if (chip->TimerHandler) (chip->TimerHandler)(chip->TimerParam+1,interval); - } - } - break; - case 0x08: /* x,NTS,x,x, x,x,x,x */ - chip->nts = v; - break; - - default: - logerror("YMF262: write to unknown register: %02x value=%02x\n",r,v); - break; - } - break; - case 0x20: /* am ON, vib ON, ksr, eg_type, mul */ - slot = slot_array[r&0x1f]; - if(slot < 0) return; - set_mul(chip, slot + ch_offset*2, v); - break; - case 0x40: - slot = slot_array[r&0x1f]; - if(slot < 0) return; - set_ksl_tl(chip, slot + ch_offset*2, v); - break; - case 0x60: - slot = slot_array[r&0x1f]; - if(slot < 0) return; - set_ar_dr(chip, slot + ch_offset*2, v); - break; - case 0x80: - slot = slot_array[r&0x1f]; - if(slot < 0) return; - set_sl_rr(chip, slot + ch_offset*2, v); - break; - case 0xa0: - if (r == 0xbd) /* am depth, vibrato depth, r,bd,sd,tom,tc,hh */ - { - if (ch_offset != 0) /* 0xbd register is present in set #1 only */ - return; - - chip->lfo_am_depth = v & 0x80; - chip->lfo_pm_depth_range = (v&0x40) ? 8 : 0; - - chip->rhythm = v&0x3f; - - if(chip->rhythm&0x20) - { - /* BD key on/off */ - if(v&0x10) - { - FM_KEYON (&chip->P_CH[6].SLOT[SLOT1], 2); - FM_KEYON (&chip->P_CH[6].SLOT[SLOT2], 2); - } - else - { - FM_KEYOFF(&chip->P_CH[6].SLOT[SLOT1],~2); - FM_KEYOFF(&chip->P_CH[6].SLOT[SLOT2],~2); - } - /* HH key on/off */ - if(v&0x01) FM_KEYON (&chip->P_CH[7].SLOT[SLOT1], 2); - else FM_KEYOFF(&chip->P_CH[7].SLOT[SLOT1],~2); - /* SD key on/off */ - if(v&0x08) FM_KEYON (&chip->P_CH[7].SLOT[SLOT2], 2); - else FM_KEYOFF(&chip->P_CH[7].SLOT[SLOT2],~2); - /* TOM key on/off */ - if(v&0x04) FM_KEYON (&chip->P_CH[8].SLOT[SLOT1], 2); - else FM_KEYOFF(&chip->P_CH[8].SLOT[SLOT1],~2); - /* TOP-CY key on/off */ - if(v&0x02) FM_KEYON (&chip->P_CH[8].SLOT[SLOT2], 2); - else FM_KEYOFF(&chip->P_CH[8].SLOT[SLOT2],~2); - } - else - { - /* BD key off */ - FM_KEYOFF(&chip->P_CH[6].SLOT[SLOT1],~2); - FM_KEYOFF(&chip->P_CH[6].SLOT[SLOT2],~2); - /* HH key off */ - FM_KEYOFF(&chip->P_CH[7].SLOT[SLOT1],~2); - /* SD key off */ - FM_KEYOFF(&chip->P_CH[7].SLOT[SLOT2],~2); - /* TOM key off */ - FM_KEYOFF(&chip->P_CH[8].SLOT[SLOT1],~2); - /* TOP-CY off */ - FM_KEYOFF(&chip->P_CH[8].SLOT[SLOT2],~2); - } - return; - } - - /* keyon,block,fnum */ - if( (r&0x0f) > 8) return; - CH = &chip->P_CH[(r&0x0f) + ch_offset]; - - if(!(r&0x10)) - { /* a0-a8 */ - block_fnum = (CH->block_fnum&0x1f00) | v; - } - else - { /* b0-b8 */ - block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff); - - if (chip->OPL3_mode & 1) - { - int chan_no = (r&0x0f) + ch_offset; - - /* in OPL3 mode */ - //DO THIS: - //if this is 1st channel forming up a 4-op channel - //ALSO keyon/off slots of 2nd channel forming up 4-op channel - //else normal 2 operator function keyon/off - //OR THIS: - //if this is 2nd channel forming up 4-op channel just do nothing - //else normal 2 operator function keyon/off - switch(chan_no) - { - case 0: case 1: case 2: - case 9: case 10: case 11: - if (CH->extended) - { - //if this is 1st channel forming up a 4-op channel - //ALSO keyon/off slots of 2nd channel forming up 4-op channel - if(v&0x20) - { - FM_KEYON (&CH->SLOT[SLOT1], 1); - FM_KEYON (&CH->SLOT[SLOT2], 1); - FM_KEYON (&(CH+3)->SLOT[SLOT1], 1); - FM_KEYON (&(CH+3)->SLOT[SLOT2], 1); - } - else - { - FM_KEYOFF(&CH->SLOT[SLOT1],~1); - FM_KEYOFF(&CH->SLOT[SLOT2],~1); - FM_KEYOFF(&(CH+3)->SLOT[SLOT1],~1); - FM_KEYOFF(&(CH+3)->SLOT[SLOT2],~1); - } - } - else - { - //else normal 2 operator function keyon/off - if(v&0x20) - { - FM_KEYON (&CH->SLOT[SLOT1], 1); - FM_KEYON (&CH->SLOT[SLOT2], 1); - } - else - { - FM_KEYOFF(&CH->SLOT[SLOT1],~1); - FM_KEYOFF(&CH->SLOT[SLOT2],~1); - } - } - break; - - case 3: case 4: case 5: - case 12: case 13: case 14: - if ((CH-3)->extended) - { - //if this is 2nd channel forming up 4-op channel just do nothing - } - else - { - //else normal 2 operator function keyon/off - if(v&0x20) - { - FM_KEYON (&CH->SLOT[SLOT1], 1); - FM_KEYON (&CH->SLOT[SLOT2], 1); - } - else - { - FM_KEYOFF(&CH->SLOT[SLOT1],~1); - FM_KEYOFF(&CH->SLOT[SLOT2],~1); - } - } - break; - - default: - if(v&0x20) - { - FM_KEYON (&CH->SLOT[SLOT1], 1); - FM_KEYON (&CH->SLOT[SLOT2], 1); - } - else - { - FM_KEYOFF(&CH->SLOT[SLOT1],~1); - FM_KEYOFF(&CH->SLOT[SLOT2],~1); - } - break; - } - } - else - { - if(v&0x20) - { - FM_KEYON (&CH->SLOT[SLOT1], 1); - FM_KEYON (&CH->SLOT[SLOT2], 1); - } - else - { - FM_KEYOFF(&CH->SLOT[SLOT1],~1); - FM_KEYOFF(&CH->SLOT[SLOT2],~1); - } - } - } - /* update */ - if(CH->block_fnum != block_fnum) - { - UINT8 block = block_fnum >> 10; - - CH->block_fnum = block_fnum; - - CH->ksl_base = ksl_tab[block_fnum>>6]; - CH->fc = chip->fn_tab[block_fnum&0x03ff] >> (7-block); - - /* BLK 2,1,0 bits -> bits 3,2,1 of kcode */ - CH->kcode = (CH->block_fnum&0x1c00)>>9; - - /* the info below is actually opposite to what is stated in the Manuals (verifed on real YMF262) */ - /* if notesel == 0 -> lsb of kcode is bit 10 (MSB) of fnum */ - /* if notesel == 1 -> lsb of kcode is bit 9 (MSB-1) of fnum */ - if (chip->nts&0x40) - CH->kcode |= (CH->block_fnum&0x100)>>8; /* notesel == 1 */ - else - CH->kcode |= (CH->block_fnum&0x200)>>9; /* notesel == 0 */ - - if (chip->OPL3_mode & 1) - { - int chan_no = (r&0x0f) + ch_offset; - /* in OPL3 mode */ - //DO THIS: - //if this is 1st channel forming up a 4-op channel - //ALSO update slots of 2nd channel forming up 4-op channel - //else normal 2 operator function keyon/off - //OR THIS: - //if this is 2nd channel forming up 4-op channel just do nothing - //else normal 2 operator function keyon/off - switch(chan_no) - { - case 0: case 1: case 2: - case 9: case 10: case 11: - if (CH->extended) - { - //if this is 1st channel forming up a 4-op channel - //ALSO update slots of 2nd channel forming up 4-op channel - - /* refresh Total Level in FOUR SLOTs of this channel and channel+3 using data from THIS channel */ - CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); - CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); - (CH+3)->SLOT[SLOT1].TLL = (CH+3)->SLOT[SLOT1].TL + (CH->ksl_base>>(CH+3)->SLOT[SLOT1].ksl); - (CH+3)->SLOT[SLOT2].TLL = (CH+3)->SLOT[SLOT2].TL + (CH->ksl_base>>(CH+3)->SLOT[SLOT2].ksl); - - /* refresh frequency counter in FOUR SLOTs of this channel and channel+3 using data from THIS channel */ - CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); - CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); - CALC_FCSLOT(CH,&(CH+3)->SLOT[SLOT1]); - CALC_FCSLOT(CH,&(CH+3)->SLOT[SLOT2]); - } - else - { - //else normal 2 operator function - /* refresh Total Level in both SLOTs of this channel */ - CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); - CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); - - /* refresh frequency counter in both SLOTs of this channel */ - CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); - CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); - } - break; - - case 3: case 4: case 5: - case 12: case 13: case 14: - if ((CH-3)->extended) - { - //if this is 2nd channel forming up 4-op channel just do nothing - } - else - { - //else normal 2 operator function - /* refresh Total Level in both SLOTs of this channel */ - CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); - CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); - - /* refresh frequency counter in both SLOTs of this channel */ - CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); - CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); - } - break; - - default: - /* refresh Total Level in both SLOTs of this channel */ - CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); - CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); - - /* refresh frequency counter in both SLOTs of this channel */ - CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); - CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); - break; - } - } - else - { - /* in OPL2 mode */ - - /* refresh Total Level in both SLOTs of this channel */ - CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); - CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); - - /* refresh frequency counter in both SLOTs of this channel */ - CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); - CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); - } - } - break; - - case 0xc0: - /* CH.D, CH.C, CH.B, CH.A, FB(3bits), C */ - if( (r&0xf) > 8) return; - - CH = &chip->P_CH[(r&0xf) + ch_offset]; - - if( chip->OPL3_mode & 1 ) - { - int base = ((r&0xf) + ch_offset) * 2; - - /* OPL3 mode */ - chip->pan[ base ] = (v & 0x10) ? 1 : 0; /* ch.A */ - chip->pan[ base +1 ] = (v & 0x20) ? 1 : 0; /* ch.B */ - } - else - { - int base = ((r&0xf) + ch_offset) * 2; - - /* OPL2 mode - always enabled */ - chip->pan[ base ] = 1; /* ch.A */ - chip->pan[ base +1 ] = 1; /* ch.B */ - } - - CH->SLOT[SLOT1].FB = (v>>1)&7 ? ((v>>1)&7) + 7 : 0; - CH->SLOT[SLOT1].CON = v&1; - - if( chip->OPL3_mode & 1 ) - { - int chan_no = (r&0x0f) + ch_offset; - - switch(chan_no) - { - case 0: case 1: case 2: - case 9: case 10: case 11: - if (CH->extended) - { - UINT8 conn = (CH->SLOT[SLOT1].CON<<1) | ((CH+3)->SLOT[SLOT1].CON<<0); - switch(conn) - { - case 0: - /* 1 -> 2 -> 3 -> 4 - out */ - - CH->SLOT[SLOT1].connect = &phase_modulation; - CH->SLOT[SLOT2].connect = &phase_modulation2; - (CH+3)->SLOT[SLOT1].connect = &phase_modulation; - (CH+3)->SLOT[SLOT2].connect = &chanout[ chan_no + 3 ]; - break; - case 1: - /* 1 -> 2 -\ - 3 -> 4 -+- out */ - - CH->SLOT[SLOT1].connect = &phase_modulation; - CH->SLOT[SLOT2].connect = &chanout[ chan_no ]; - (CH+3)->SLOT[SLOT1].connect = &phase_modulation; - (CH+3)->SLOT[SLOT2].connect = &chanout[ chan_no + 3 ]; - break; - case 2: - /* 1 -----------\ - 2 -> 3 -> 4 -+- out */ - - CH->SLOT[SLOT1].connect = &chanout[ chan_no ]; - CH->SLOT[SLOT2].connect = &phase_modulation2; - (CH+3)->SLOT[SLOT1].connect = &phase_modulation; - (CH+3)->SLOT[SLOT2].connect = &chanout[ chan_no + 3 ]; - break; - case 3: - /* 1 ------\ - 2 -> 3 -+- out - 4 ------/ */ - CH->SLOT[SLOT1].connect = &chanout[ chan_no ]; - CH->SLOT[SLOT2].connect = &phase_modulation2; - (CH+3)->SLOT[SLOT1].connect = &chanout[ chan_no + 3 ]; - (CH+3)->SLOT[SLOT2].connect = &chanout[ chan_no + 3 ]; - break; - } - } - else - { - /* 2 operators mode */ - CH->SLOT[SLOT1].connect = CH->SLOT[SLOT1].CON ? &chanout[(r&0xf)+ch_offset] : &phase_modulation; - CH->SLOT[SLOT2].connect = &chanout[(r&0xf)+ch_offset]; - } - break; - - case 3: case 4: case 5: - case 12: case 13: case 14: - if ((CH-3)->extended) - { - UINT8 conn = ((CH-3)->SLOT[SLOT1].CON<<1) | (CH->SLOT[SLOT1].CON<<0); - switch(conn) - { - case 0: - /* 1 -> 2 -> 3 -> 4 - out */ - - (CH-3)->SLOT[SLOT1].connect = &phase_modulation; - (CH-3)->SLOT[SLOT2].connect = &phase_modulation2; - CH->SLOT[SLOT1].connect = &phase_modulation; - CH->SLOT[SLOT2].connect = &chanout[ chan_no ]; - break; - case 1: - /* 1 -> 2 -\ - 3 -> 4 -+- out */ - - (CH-3)->SLOT[SLOT1].connect = &phase_modulation; - (CH-3)->SLOT[SLOT2].connect = &chanout[ chan_no - 3 ]; - CH->SLOT[SLOT1].connect = &phase_modulation; - CH->SLOT[SLOT2].connect = &chanout[ chan_no ]; - break; - case 2: - /* 1 -----------\ - 2 -> 3 -> 4 -+- out */ - - (CH-3)->SLOT[SLOT1].connect = &chanout[ chan_no - 3 ]; - (CH-3)->SLOT[SLOT2].connect = &phase_modulation2; - CH->SLOT[SLOT1].connect = &phase_modulation; - CH->SLOT[SLOT2].connect = &chanout[ chan_no ]; - break; - case 3: - /* 1 ------\ - 2 -> 3 -+- out - 4 ------/ */ - (CH-3)->SLOT[SLOT1].connect = &chanout[ chan_no - 3 ]; - (CH-3)->SLOT[SLOT2].connect = &phase_modulation2; - CH->SLOT[SLOT1].connect = &chanout[ chan_no ]; - CH->SLOT[SLOT2].connect = &chanout[ chan_no ]; - break; - } - } - else - { - /* 2 operators mode */ - CH->SLOT[SLOT1].connect = CH->SLOT[SLOT1].CON ? &chanout[(r&0xf)+ch_offset] : &phase_modulation; - CH->SLOT[SLOT2].connect = &chanout[(r&0xf)+ch_offset]; - } - break; - - default: - /* 2 operators mode */ - CH->SLOT[SLOT1].connect = CH->SLOT[SLOT1].CON ? &chanout[(r&0xf)+ch_offset] : &phase_modulation; - CH->SLOT[SLOT2].connect = &chanout[(r&0xf)+ch_offset]; - break; - } - } - else - { - /* OPL2 mode - always 2 operators mode */ - CH->SLOT[SLOT1].connect = CH->SLOT[SLOT1].CON ? &chanout[(r&0xf)+ch_offset] : &phase_modulation; - CH->SLOT[SLOT2].connect = &chanout[(r&0xf)+ch_offset]; - } - break; - - case 0xe0: /* waveform select */ - slot = slot_array[r&0x1f]; - if(slot < 0) return; - - slot += ch_offset*2; - - CH = &chip->P_CH[slot/2]; - - - /* store 3-bit value written regardless of current OPL2 or OPL3 mode... (verified on real YMF262) */ - v &= 7; - CH->SLOT[slot&1].waveform_number = v; - - /* ... but select only waveforms 0-3 in OPL2 mode */ - if( !(chip->OPL3_mode & 1) ) - { - v &= 3; /* we're in OPL2 mode */ - } - CH->SLOT[slot&1].wavetable = v * SIN_LEN; - break; - } -} - -#ifdef LOG_CYM_FILE -static void cymfile_callback (int n) -{ - if (cymfile) - { - fputc( (unsigned char)0, cymfile ); - } -} -#endif - -/* lock/unlock for common table */ -static int OPL3_LockTable(void) -{ - num_lock++; - if(num_lock>1) return 0; - - /* first time */ - - cur_chip = NULL; - - if( !init_tables() ) - { - num_lock--; - return -1; - } - -#ifdef LOG_CYM_FILE - cymfile = fopen("ymf262_.cym","wb"); - if (cymfile) - timer_pulse ( TIME_IN_HZ(110), 0, cymfile_callback); /*110 Hz pulse timer*/ - else - logerror("Could not create ymf262_.cym file\n"); -#endif - - return 0; -} - -static void OPL3_UnLockTable(void) -{ - if(num_lock) num_lock--; - if(num_lock) return; - - /* last time */ - - cur_chip = NULL; - OPLCloseTable(); - -#ifdef LOG_CYM_FILE - fclose (cymfile); - cymfile = NULL; -#endif - -} - -static void OPL3ResetChip(OPL3 *chip) -{ - int c,s; - - chip->eg_timer = 0; - chip->eg_cnt = 0; - - chip->noise_rng = 1; /* noise shift register */ - chip->nts = 0; /* note split */ - OPL3_STATUS_RESET(chip,0x60); - - /* reset with register write */ - OPL3WriteReg(chip,0x01,0); /* test register */ - OPL3WriteReg(chip,0x02,0); /* Timer1 */ - OPL3WriteReg(chip,0x03,0); /* Timer2 */ - OPL3WriteReg(chip,0x04,0); /* IRQ mask clear */ - - -//FIX IT registers 101, 104 and 105 - - -//FIX IT (dont change CH.D, CH.C, CH.B and CH.A in C0-C8 registers) - for(c = 0xff ; c >= 0x20 ; c-- ) - OPL3WriteReg(chip,c,0); -//FIX IT (dont change CH.D, CH.C, CH.B and CH.A in C0-C8 registers) - for(c = 0x1ff ; c >= 0x120 ; c-- ) - OPL3WriteReg(chip,c,0); - - - - /* reset operator parameters */ - for( c = 0 ; c < 9*2 ; c++ ) - { - OPL3_CH *CH = &chip->P_CH[c]; - for(s = 0 ; s < 2 ; s++ ) - { - CH->SLOT[s].state = EG_OFF; - CH->SLOT[s].volume = MAX_ATT_INDEX; - } - } -} - -/* Create one of virtual YMF262 */ -/* 'clock' is chip clock in Hz */ -/* 'rate' is sampling rate */ -static OPL3 *OPL3Create(int type, int clock, int rate) -{ - OPL3 *chip; - - if (OPL3_LockTable() ==-1) return NULL; - - /* allocate memory block */ - chip = (OPL3 *)malloc(sizeof(OPL3)); - - if (chip==NULL) - return NULL; - - /* clear */ - memset(chip, 0, sizeof(OPL3)); - - chip->type = type; - chip->clock = clock; - chip->rate = rate; - - /* init global tables */ - OPL3_initalize(chip); - - /* reset chip */ - OPL3ResetChip(chip); - return chip; -} - -/* Destroy one of virtual YMF262 */ -static void OPL3Destroy(OPL3 *chip) -{ - OPL3_UnLockTable(); - free(chip); -} - - -/* Optional handlers */ - -static void OPL3SetTimerHandler(OPL3 *chip,OPL3_TIMERHANDLER TimerHandler,int channelOffset) -{ - chip->TimerHandler = TimerHandler; - chip->TimerParam = channelOffset; -} -static void OPL3SetIRQHandler(OPL3 *chip,OPL3_IRQHANDLER IRQHandler,int param) -{ - chip->IRQHandler = IRQHandler; - chip->IRQParam = param; -} -static void OPL3SetUpdateHandler(OPL3 *chip,OPL3_UPDATEHANDLER UpdateHandler,int param) -{ - chip->UpdateHandler = UpdateHandler; - chip->UpdateParam = param; -} - -/* YMF262 I/O interface */ -static int OPL3Write(OPL3 *chip, int a, int v) -{ - /* data bus is 8 bits */ - v &= 0xff; - - switch(a&3) - { - case 0: /* address port 0 (register set #1) */ - chip->address = v; - break; - - case 1: /* data port - ignore A1 */ - case 3: /* data port - ignore A1 */ - if(chip->UpdateHandler) chip->UpdateHandler(chip->UpdateParam,0); - OPL3WriteReg(chip,chip->address,v); - break; - - case 2: /* address port 1 (register set #2) */ - - /* verified on real YMF262: - in OPL3 mode: - address line A1 is stored during *address* write and ignored during *data* write. - - in OPL2 mode: - register set#2 writes go to register set#1 (ignoring A1) - verified on registers from set#2: 0x01, 0x04, 0x20-0xef - The only exception is register 0x05. - */ - if( chip->OPL3_mode & 1 ) - { - /* OPL3 mode */ - chip->address = v | 0x100; - } - else - { - /* in OPL2 mode the only accessible in set #2 is register 0x05 */ - if( v==5 ) - chip->address = v | 0x100; - else - chip->address = v; /* verified range: 0x01, 0x04, 0x20-0xef(set #2 becomes set #1 in opl2 mode) */ - } - break; - } - - return chip->status>>7; -} - -static unsigned char OPL3Read(OPL3 *chip,int a) -{ - if( a==0 ) - { - if (chip->st[0]) { - /* Timer A */ - if (chip->TC[0]) chip->TC[0]--; - else { - chip->TC[0]=chip->T[0]*20; - OPL3_STATUS_SET(chip,0x40); - } - } - if (chip->st[1]) { - /* Timer B */ - if (chip->TC[1]) chip->TC[1]--; - else { - chip->TC[1]=chip->T[1]*20; - OPL3_STATUS_SET(chip,0x20); - } - } - return chip->status; - } - - return 0x00; /* verified on real YMF262 */ -} - - - -static int OPL3TimerOver(OPL3 *chip,int c) -{ - if( c ) - { /* Timer B */ - OPL3_STATUS_SET(chip,0x20); - } - else - { /* Timer A */ - OPL3_STATUS_SET(chip,0x40); - } - /* reload timer */ -// if (chip->TimerHandler) (chip->TimerHandler)(chip->TimerParam+c,(double)chip->T[c]*chip->TimerBase); - return chip->status>>7; -} - - - - -#if (BUILD_YMF262) - -#define MAX_OPL3_CHIPS 2 - -static OPL3 *YMF262[MAX_OPL3_CHIPS]; /* array of pointers to the YMF262's */ -static int YMF262NumChips = 0; /* number of chips */ - -int YMF262Init(int num, int clock, int rate) -{ - int i; - - if (YMF262NumChips) - return -1; /* duplicate init. */ - - YMF262NumChips = num; - - for (i = 0;i < YMF262NumChips; i++) - { - /* emulator create */ - YMF262[i] = OPL3Create(OPL3_TYPE_YMF262,clock,rate); - if(YMF262[i] == NULL) - { - /* it's really bad - we run out of memeory */ - YMF262NumChips = 0; - return -1; - } - } - - return 0; -} - -void YMF262Shutdown(void) -{ - int i; - - for (i = 0;i < YMF262NumChips; i++) - { - /* emulator shutdown */ - OPL3Destroy(YMF262[i]); - YMF262[i] = NULL; - } - YMF262NumChips = 0; -} -void YMF262ResetChip(int which) -{ - OPL3ResetChip(YMF262[which]); -} - -int YMF262Write(int which, int a, int v) -{ - return OPL3Write(YMF262[which], a, v); -} - -unsigned char YMF262Read(int which, int a) -{ - /* Note on status register: */ - - /* YM3526(OPL) and YM3812(OPL2) return bit2 and bit1 in HIGH state */ - - /* YMF262(OPL3) always returns bit2 and bit1 in LOW state */ - /* which can be used to identify the chip */ - - /* YMF278(OPL4) returns bit2 in LOW and bit1 in HIGH state ??? info from manual - not verified */ - - return OPL3Read(YMF262[which], a); -} -int YMF262TimerOver(int which, int c) -{ - return OPL3TimerOver(YMF262[which], c); -} - -void YMF262SetTimerHandler(int which, OPL3_TIMERHANDLER TimerHandler, int channelOffset) -{ - OPL3SetTimerHandler(YMF262[which], TimerHandler, channelOffset); -} -void YMF262SetIRQHandler(int which,OPL3_IRQHANDLER IRQHandler,int param) -{ - OPL3SetIRQHandler(YMF262[which], IRQHandler, param); -} -void YMF262SetUpdateHandler(int which,OPL3_UPDATEHANDLER UpdateHandler,int param) -{ - OPL3SetUpdateHandler(YMF262[which], UpdateHandler, param); -} - - -/* -** Generate samples for one of the YMF262's -** -** 'which' is the virtual YMF262 number -** '**buffers' is table of 4 pointers to the buffers: CH.A, CH.B, CH.C and CH.D -** 'length' is the number of samples that should be generated -*/ -#if 0 -void YMF262UpdateOne(int which, INT16 **buffers, int length) -#else -void YMF262UpdateOne(int which, INT16 *buffer, int length) -#endif -{ - OPL3 *chip = YMF262[which]; - UINT8 rhythm = chip->rhythm&0x20; -#if 0 - OPL3SAMPLE *ch_a = buffers[0]; - OPL3SAMPLE *ch_b = buffers[1]; -#endif - int i; - - if( (void *)chip != cur_chip ){ - cur_chip = (void *)chip; - /* rhythm slots */ - SLOT7_1 = &chip->P_CH[7].SLOT[SLOT1]; - SLOT7_2 = &chip->P_CH[7].SLOT[SLOT2]; - SLOT8_1 = &chip->P_CH[8].SLOT[SLOT1]; - SLOT8_2 = &chip->P_CH[8].SLOT[SLOT2]; - } - for( i=0; i < length ; i++ ) - { - int a,b; - - - advance_lfo(chip); - - /* clear channel outputs */ - memset(chanout, 0, sizeof(signed int) * 18); - -//profiler_mark(PROFILER_USER1); - - /* register set #1 */ - chan_calc(&chip->P_CH[0]); /* extended 4op ch#0 part 1 or 2op ch#0 */ - if (chip->P_CH[0].extended) - chan_calc_ext(&chip->P_CH[3]); /* extended 4op ch#0 part 2 */ - else - chan_calc(&chip->P_CH[3]); /* standard 2op ch#3 */ - - - chan_calc(&chip->P_CH[1]); /* extended 4op ch#1 part 1 or 2op ch#1 */ - if (chip->P_CH[1].extended) - chan_calc_ext(&chip->P_CH[4]); /* extended 4op ch#1 part 2 */ - else - chan_calc(&chip->P_CH[4]); /* standard 2op ch#4 */ - - - chan_calc(&chip->P_CH[2]); /* extended 4op ch#2 part 1 or 2op ch#2 */ - if (chip->P_CH[2].extended) - chan_calc_ext(&chip->P_CH[5]); /* extended 4op ch#2 part 2 */ - else - chan_calc(&chip->P_CH[5]); /* standard 2op ch#5 */ - - - if(!rhythm) - { - chan_calc(&chip->P_CH[6]); - chan_calc(&chip->P_CH[7]); - chan_calc(&chip->P_CH[8]); - } - else /* Rhythm part */ - { - chan_calc_rhythm(&chip->P_CH[0], (chip->noise_rng>>0)&1 ); - } - - /* register set #2 */ - chan_calc(&chip->P_CH[ 9]); - if (chip->P_CH[9].extended) - chan_calc_ext(&chip->P_CH[12]); - else - chan_calc(&chip->P_CH[12]); - - - chan_calc(&chip->P_CH[10]); - if (chip->P_CH[10].extended) - chan_calc_ext(&chip->P_CH[13]); - else - chan_calc(&chip->P_CH[13]); - - - chan_calc(&chip->P_CH[11]); - if (chip->P_CH[11].extended) - chan_calc_ext(&chip->P_CH[14]); - else - chan_calc(&chip->P_CH[14]); - - - /* channels 15,16,17 are fixed 2-operator channels only */ - chan_calc(&chip->P_CH[15]); - chan_calc(&chip->P_CH[16]); - chan_calc(&chip->P_CH[17]); - -//profiler_mark(PROFILER_END); - - - -//profiler_mark(PROFILER_USER2); - /* accumulator register set #1 */ - a = chanout[0] * chip->pan[0]; - b = chanout[0] * chip->pan[1]; - - a += chanout[1] * chip->pan[2]; - b += chanout[1] * chip->pan[3]; - a += chanout[2] * chip->pan[4]; - b += chanout[2] * chip->pan[5]; - - a += chanout[3] * chip->pan[6]; - b += chanout[3] * chip->pan[7]; - a += chanout[4] * chip->pan[8]; - b += chanout[4] * chip->pan[9]; - a += chanout[5] * chip->pan[10]; - b += chanout[5] * chip->pan[11]; - - a += chanout[6] * chip->pan[12]; - b += chanout[6] * chip->pan[13]; - a += chanout[7] * chip->pan[14]; - b += chanout[7] * chip->pan[15]; - a += chanout[8] * chip->pan[16]; - b += chanout[8] * chip->pan[17]; - - /* accumulator register set #2 */ - a += chanout[9] * chip->pan[18]; - b += chanout[9] * chip->pan[19]; - a += chanout[10] * chip->pan[20]; - b += chanout[10] * chip->pan[21]; - a += chanout[11] * chip->pan[22]; - b += chanout[11] * chip->pan[23]; - - a += chanout[12] * chip->pan[24]; - b += chanout[12] * chip->pan[25]; - a += chanout[13] * chip->pan[26]; - b += chanout[13] * chip->pan[27]; - a += chanout[14] * chip->pan[28]; - b += chanout[14] * chip->pan[29]; - - a += chanout[15] * chip->pan[30]; - b += chanout[15] * chip->pan[31]; - a += chanout[16] * chip->pan[32]; - b += chanout[16] * chip->pan[33]; - a += chanout[17] * chip->pan[34]; - b += chanout[17] * chip->pan[35]; - - a >>= FINAL_SH; - b >>= FINAL_SH; - - /* limit check */ - a = limit( a , MAXOUT, MINOUT ); - b = limit( b , MAXOUT, MINOUT ); - - #ifdef SAVE_SAMPLE - if (which==0) - { - SAVE_ALL_CHANNELS - } - #endif - - /* store to sound buffer */ - *buffer++=(INT16)a; - *buffer++=(INT16)b; -#if 0 - ch_a[i] = a; - ch_b[i] = b; -#endif -//profiler_mark(PROFILER_END); - - advance(chip); - } - -} -#endif /* BUILD_YMF262 */ diff --git a/src/hardware/ymf262.h b/src/hardware/ymf262.h deleted file mode 100644 index 1ab2fa11..00000000 --- a/src/hardware/ymf262.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef YMF262_H -#define YMF262_H - - -#define BUILD_YMF262 (HAS_YMF262) - - -/* select number of output bits: 8 or 16 */ -#define OPL3_SAMPLE_BITS 16 - -/* compiler dependence */ -#ifndef OSD_CPU_H -#define OSD_CPU_H -typedef unsigned char UINT8; /* unsigned 8bit */ -typedef unsigned short UINT16; /* unsigned 16bit */ -typedef unsigned int UINT32; /* unsigned 32bit */ -typedef signed char INT8; /* signed 8bit */ -typedef signed short INT16; /* signed 16bit */ -typedef signed int INT32; /* signed 32bit */ -#endif - -#if (OPL3_SAMPLE_BITS==16) -typedef INT16 OPL3SAMPLE; -#endif -#if (OPL3_SAMPLE_BITS==8) -typedef INT8 OPL3SAMPLE; -#endif - - -typedef void (*OPL3_TIMERHANDLER)(int channel,double interval_Sec); -typedef void (*OPL3_IRQHANDLER)(int param,int irq); -typedef void (*OPL3_UPDATEHANDLER)(int param,int min_interval_us); - - - -#if BUILD_YMF262 - -int YMF262Init(int num, int clock, int rate); -void YMF262Shutdown(void); -void YMF262ResetChip(int which); -int YMF262Write(int which, int a, int v); -unsigned char YMF262Read(int which, int a); -int YMF262TimerOver(int which, int c); -void YMF262UpdateOne(int which, INT16 **buffers, int length); - -void YMF262SetTimerHandler(int which, OPL3_TIMERHANDLER TimerHandler, int channelOffset); -void YMF262SetIRQHandler(int which, OPL3_IRQHANDLER IRQHandler, int param); -void YMF262SetUpdateHandler(int which, OPL3_UPDATEHANDLER UpdateHandler, int param); - -#endif - - -#endif /* YMF262_H */ From f7dd5221120724560b8c2fdd943a8a35f91a20c8 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Tue, 3 Nov 2009 21:06:59 +0000 Subject: [PATCH 3402/4131] Improve handling of blanked screen parts in VGA modes. Fixes Toons, Magic Circle demo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3491 --- include/vga.h | 3 +- src/hardware/vga_draw.cpp | 69 ++++++++++++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/include/vga.h b/include/vga.h index 131ee026..8d8a3bc7 100644 --- a/include/vga.h +++ b/include/vga.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga.h,v 1.47 2009-06-29 18:43:33 c2woody Exp $ */ +/* $Id: vga.h,v 1.48 2009-11-03 21:06:59 h-a-l-9000 Exp $ */ #ifndef DOSBOX_VGA_H #define DOSBOX_VGA_H @@ -126,6 +126,7 @@ typedef struct { Bitu address_line_total; Bitu address_line; Bitu lines_total; + Bitu vblank_skip; Bitu lines_done; Bitu lines_scaled; Bitu split_line; diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 89f94de2..709f76b9 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.111 2009-09-10 17:44:57 h-a-l-9000 Exp $ */ +/* $Id: vga_draw.cpp,v 1.112 2009-11-03 21:06:59 h-a-l-9000 Exp $ */ #include #include @@ -787,6 +787,7 @@ static void VGA_VerticalTimer(Bitu /*val*/) { if (IS_EGAVGA_ARCH) { vga.draw.split_line = (Bitu)((vga.config.line_compare+1)/vga.draw.lines_scaled); if ((svgaCard==SVGA_S3Trio) && (vga.config.line_compare==0)) vga.draw.split_line=0; + vga.draw.split_line -= vga.draw.vblank_skip; } else { vga.draw.split_line = 0x10000; // don't care } @@ -861,9 +862,14 @@ static void VGA_VerticalTimer(Bitu /*val*/) { #ifdef VGA_KEEP_CHANGES if (startaddr_changed) VGA_ChangesStart(); #endif + float draw_skip = 0.0; + if (GCC_UNLIKELY(vga.draw.vblank_skip)) { + draw_skip = (float)(vga.draw.delay.htotal * vga.draw.vblank_skip); + vga.draw.address += vga.draw.address_add * (vga.draw.vblank_skip/(vga.draw.address_line_total)); + } - if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) PIC_AddEvent(VGA_DrawSingleLine,(float)(vga.draw.delay.htotal/4.0)); - else PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts,vga.draw.parts_lines); + if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) PIC_AddEvent(VGA_DrawSingleLine,(float)(vga.draw.delay.htotal/4.0 + draw_skip)); + else PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts + draw_skip,vga.draw.parts_lines); //VGA_DrawPart( vga.draw.parts_lines ); //PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts,vga.draw.parts_lines); //PIC_AddEvent(VGA_DrawPart,(float)(vga.draw.delay.parts/2),vga.draw.parts_lines); //Else tearline in Tyrian and second reality @@ -947,6 +953,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { float fps; Bitu clock; Bitu htotal, hdend, hbstart, hbend, hrstart, hrend; Bitu vtotal, vdend, vbstart, vbend, vrstart, vrend; + Bitu vblank_skip; if (IS_EGAVGA_ARCH) { htotal = vga.crtc.horizontal_total; hdend = vga.crtc.horizontal_display_end; @@ -976,14 +983,15 @@ void VGA_SetupDrawing(Bitu /*val*/) { vbstart |= (vga.s3.ex_ver_overflow & 0x4) << 8; vrstart |= ((vga.crtc.overflow & 0x80) << 2); vrstart |= (vga.s3.ex_ver_overflow & 0x10) << 6; - vbend = vga.crtc.end_vertical_blanking & 0x3f; - } else { - vbend = vga.crtc.end_vertical_blanking & 0xf; + vbend = vga.crtc.end_vertical_blanking & 0x7f; + } else { // EGA + vbend = vga.crtc.end_vertical_blanking & 0x1f; } htotal += 2; vtotal += 2; hdend += 1; vdend += 1; + vbstart += 1; hbend = hbstart + ((hbend - hbstart) & 0x3F); hrend = vga.crtc.end_horizontal_retrace & 0x1f; @@ -998,9 +1006,11 @@ void VGA_SetupDrawing(Bitu /*val*/) { if ( !vrend) vrend = vrstart + 0xf + 1; else vrend = vrstart + vrend; - vbend = (vbend - vbstart) & 0x3f; - if ( !vbend) vbend = vbstart + 0x3f + 1; + vbend = (vbend - vbstart) & 0x7f; + if ( !vbend) vbend = vbstart + 0x7f + 1; else vbend = vbstart + vbend; + + vbend++; if (svga.get_clock) { clock = svga.get_clock(); @@ -1094,6 +1104,38 @@ void VGA_SetupDrawing(Bitu /*val*/) { // Start and End of vertical retrace pulse vga.draw.delay.vrstart = vrstart * vga.draw.delay.htotal; vga.draw.delay.vrend = vrend * vga.draw.delay.htotal; + + // Vertical blanking tricks + vblank_skip = 0; + if (IS_VGA_ARCH) { // others need more investigation + if (vbend > vtotal) { + // blanking wraps to the start of the screen + vblank_skip = vbend&0x7f; + + // on blanking wrap to 0, the first line is not blanked + // this is used by the S3 BIOS and other S3 drivers in some SVGA modes + if((vbend&0x7f)==1) vblank_skip = 0; + + // it might also cut some lines off the bottom + if(vbstart < vdend) { + vdend = vbstart; + } + LOG(LOG_VGA,LOG_WARN)("Blanking wrap to line %d", vblank_skip); + } else if (vbstart==1) { + // blanking is used to cut lines at the start of the screen + vblank_skip = vbend; + LOG(LOG_VGA,LOG_WARN)("Upper %d lines of the screen blanked", vblank_skip); + } else if (vbstart < vdend) { + if(vbend < vdend) { + // the game wants a black bar somewhere on the screen + LOG(LOG_VGA,LOG_WARN)("Unsupported blanking: line %d-%d",vbstart,vbend); + } else { + // blanking is used to cut off some lines from the bottom + vdend = vbstart; + } + } + vdend -= vblank_skip; + } // Display end vga.draw.delay.vdend = vdend * vga.draw.delay.htotal; @@ -1155,9 +1197,8 @@ void VGA_SetupDrawing(Bitu /*val*/) { //Check to prevent useless black areas if (hbstart Date: Fri, 6 Nov 2009 13:43:48 +0000 Subject: [PATCH 3403/4131] Disable 8bpp love Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3492 --- src/gui/sdlmain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 555a411d..a7b681ae 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -288,6 +288,7 @@ Bitu GFX_GetBestMode(Bitu flags) { switch (sdl.desktop.want_type) { case SCREEN_SURFACE: check_surface: + flags &= ~GFX_LOVE_8; //Disable love for 8bpp modes /* Check if we can satisfy the depth it loves */ if (flags & GFX_LOVE_8) testbpp=8; else if (flags & GFX_LOVE_15) testbpp=15; From 14e46abf68072ec9349e89b588ea4ea42a4f5f98 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 6 Nov 2009 13:54:58 +0000 Subject: [PATCH 3404/4131] Add debugger patch by doshea. (slightly modified) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3493 --- src/debug/debug.cpp | 83 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index fadaa8f4..ed9b2c6e 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -64,6 +64,7 @@ static void DrawCode(void); static void DEBUG_RaiseTimerIrq(void); static void SaveMemory(Bitu seg, Bitu ofs1, Bit32u num); static void SaveMemoryBin(Bitu seg, Bitu ofs1, Bit32u num); +static void LogMCBS(void); static void LogGDT(void); static void LogLDT(void); static void LogIDT(void); @@ -145,6 +146,7 @@ struct SCodeViewData { Bit32u cursorOfs; bool inputMode; char inputStr[255]; + char prevInputStr[255]; } codeViewData; @@ -1195,6 +1197,12 @@ bool ParseCommand(char* str) { return true; }; + if (command == "DOS") { + stream >> command; + if (command == "MCBS") LogMCBS(); + return true; + } + if (command == "GDT") {LogGDT(); return true;} if (command == "LDT") {LogLDT(); return true;} @@ -1251,6 +1259,7 @@ bool ParseCommand(char* str) { if (command == "HELP" || command == "?") { DEBUG_ShowMsg("Debugger commands (enter all values in hex or as register):\n"); DEBUG_ShowMsg("--------------------------------------------------------------------------\n"); + DEBUG_ShowMsg("F3/F6 - Re-enter previous command.\n"); DEBUG_ShowMsg("F5 - Run.\n"); DEBUG_ShowMsg("F9 - Set/Remove breakpoint.\n"); DEBUG_ShowMsg("F10/F11 - Step over / trace into instruction.\n"); @@ -1270,6 +1279,7 @@ bool ParseCommand(char* str) { DEBUG_ShowMsg("BPLIST - List breakpoints.\n"); DEBUG_ShowMsg("BPDEL [bpNr] / * - Delete breakpoint nr / all.\n"); DEBUG_ShowMsg("C / D [segment]:[offset] - Set code / data view address.\n"); + DEBUG_ShowMsg("DOS MCBS - Show Memory Control Block chain.\n"); DEBUG_ShowMsg("INT [nr] / INTT [nr] - Execute / Trace into interrupt.\n"); #if C_HEAVY_DEBUG DEBUG_ShowMsg("LOG [num] - Write cpu log file.\n"); @@ -1574,7 +1584,12 @@ Bit32u DEBUG_CheckKeys(void) { case KEY_END: // End: scroll log page down DEBUG_RefreshPage(1); break; - case KEY_F(5): // Run Programm + case KEY_F(6): // Re-enter previous command (f1-f4 generate rubbish at my place) + case KEY_F(3): // Re-enter previous command + // copy prevInputStr back into inputStr + safe_strncpy(codeViewData.inputStr, codeViewData.prevInputStr, sizeof(codeViewData.inputStr)); + break; + case KEY_F(5): // Run Program debugging=false; CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); ignoreAddressOnce = SegPhys(cs)+reg_eip; @@ -1607,7 +1622,12 @@ Bit32u DEBUG_CheckKeys(void) { break; case 0x0A: //Parse typed Command codeViewData.inputMode = true; - if(ParseCommand(codeViewData.inputStr)) codeViewData.inputStr[0] = 0; + if(ParseCommand(codeViewData.inputStr)) { + // copy inputStr to prevInputStr so we can restore it if the user hits F3 + safe_strncpy(codeViewData.prevInputStr, codeViewData.inputStr, sizeof(codeViewData.prevInputStr)); + // clear input line ready for next command + codeViewData.inputStr[0] = 0; + } break; case 0x107: //backspace (linux) case 0x7f: //backspace in some terminal emulators (linux) @@ -1681,6 +1701,65 @@ static void DEBUG_RaiseTimerIrq(void) { PIC_ActivateIRQ(0); } +// Display the content of the MCB chain starting with the MCB at the specified segment. +static void LogMCBChain(Bit16u mcb_segment) { + DOS_MCB mcb(mcb_segment); + char filename[9]; // 8 characters plus a terminating NUL + const char *psp_seg_note; + PhysPt dataAddr = PhysMake(dataSeg,dataOfs);// location being viewed in the "Data Overview" + + // loop forever, breaking out of the loop once we've processed the last MCB + while (true) { + // verify that the type field is valid + if (mcb.GetType()!=0x4d && mcb.GetType()!=0x5a) { + LOG(LOG_MISC,LOG_ERROR)("MCB chain broken at %04X:0000!",mcb_segment); + return; + } + + mcb.GetFileName(filename); + + // some PSP segment values have special meanings + switch (mcb.GetPSPSeg()) { + case MCB_FREE: + psp_seg_note = "(free)"; + break; + case MCB_DOS: + psp_seg_note = "(DOS)"; + break; + default: + psp_seg_note = ""; + } + + LOG(LOG_MISC,LOG_ERROR)(" %04X %12u %04X %-7s %s",mcb_segment,mcb.GetSize() << 4,mcb.GetPSPSeg(), psp_seg_note, filename); + + // print a message if dataAddr is within this MCB's memory range + PhysPt mcbStartAddr = PhysMake(mcb_segment+1,0); + PhysPt mcbEndAddr = PhysMake(mcb_segment+1+mcb.GetSize(),0); + if (dataAddr >= mcbStartAddr && dataAddr < mcbEndAddr) { + LOG(LOG_MISC,LOG_ERROR)(" (data addr %04hX:%04X is %u bytes past this MCB)",dataSeg,dataOfs,dataAddr - mcbStartAddr); + } + + // if we've just processed the last MCB in the chain, break out of the loop + if (mcb.GetType()==0x5a) { + break; + } + // else, move to the next MCB in the chain + mcb_segment+=mcb.GetSize()+1; + mcb.SetPt(mcb_segment); + } +} + +// Display the content of all Memory Control Blocks. +static void LogMCBS(void) +{ + LOG(LOG_MISC,LOG_ERROR)("MCB Seg Size (bytes) PSP Seg (notes) Filename"); + LOG(LOG_MISC,LOG_ERROR)("Conventional memory:"); + LogMCBChain(dos.firstMCB); + + LOG(LOG_MISC,LOG_ERROR)("Upper memory:"); + LogMCBChain(dos_infoblock.GetStartOfUMBChain()); +} + static void LogGDT(void) { char out1[512]; From 6d67340c5609e9dfefdfc3f14f70c82fa120b6d5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 6 Nov 2009 14:00:13 +0000 Subject: [PATCH 3405/4131] add GCC_LIKELY Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3494 --- acinclude.m4 | 2 ++ src/platform/visualc/config.h | 1 + 2 files changed, 3 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index a118bf1f..df8d8dc7 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -344,8 +344,10 @@ AH_BOTTOM([#if C_HAS_ATTRIBUTE AH_BOTTOM([#if C_HAS_BUILTIN_EXPECT #define GCC_UNLIKELY(x) __builtin_expect((x),0) +#define GCC_LIKELY(X) __builtin_expect((x),1) #else #define GCC_UNLIKELY(x) (x) +#define GCC_LIKELY(x) (x) #endif]) AH_BOTTOM([ diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index c96651bc..d49f10a7 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -54,6 +54,7 @@ #define GCC_ATTRIBUTE(x) /* attribute not supported */ #define GCC_UNLIKELY(x) (x) +#define GCC_LIKELY(x) (x) #define INLINE __forceinline #define DB_FASTCALL __fastcall From 21f8b9d18ca44b0ea004bfda1e583f080c766f65 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 8 Nov 2009 08:52:14 +0000 Subject: [PATCH 3406/4131] Don't overwrite the interrupt table. (whooooops) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3495 --- src/dos/dos_tables.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index a56e9e01..7b9152d5 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -139,7 +139,7 @@ void DOS_SetupTables(void) { dos.tables.collatingseq=RealMake(DOS_GetMemory(25),0); mem_writew(Real2Phys(dos.tables.collatingseq),0x100); for (i=0; i<256; i++) mem_writeb(Real2Phys(dos.tables.collatingseq)+i+2,i); - dos.tables.upcase=RealMake(dos.tables.collatingseq,258); + dos.tables.upcase=dos.tables.collatingseq+258; mem_writew(Real2Phys(dos.tables.upcase),0x80); for (i=0; i<128; i++) mem_writeb(Real2Phys(dos.tables.upcase)+i+2,0x80+i); From 1a4ca448549c7616244010a521f6880ab70cbfe2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 9 Nov 2009 15:49:20 +0000 Subject: [PATCH 3407/4131] Make parser a bit more flexible, by allowing all compiled sdl_sound formats. (thanks Alex) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3496 --- src/dos/cdrom_image.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 32bb39a1..e85a5e80 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -498,8 +498,18 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) track.file = new BinaryFile(filename.c_str(), error); } #if defined(C_SDL_SOUND) + //The next if has been surpassed by the else, but leaving it in as not + //to break existing cue sheets that depend on this.(mine with OGG tracks specifying MP3 as type) else if (type == "WAVE" || type == "AIFF" || type == "MP3") { track.file = new AudioFile(filename.c_str(), error); + } else { + const Sound_DecoderInfo **i; + for (i = Sound_AvailableDecoders(); *i != NULL; i++) { + if (*(*i)->extensions == type) { + track.file = new AudioFile(filename.c_str(), error); + break; + } + } } #endif if (error) { From db0aef34cfc405395cdcd97ebb536b81241c3c7f Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Mon, 9 Nov 2009 16:33:02 +0000 Subject: [PATCH 3408/4131] Don't touch the monochrome adapter if the BIOS equipment word is set to color card - fixes Testdrive in Hercules mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3497 --- src/ints/int10_modes.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index c74e9ebb..1b2666c7 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -445,6 +445,8 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) { } break; case MCH_HERC: + // Only init the adapter if the equipment word is set to monochrome (Testdrive) + if ((real_readw(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE)&0x30)!=0x30) return false; CurMode=&Hercules_Mode; break; } From 072ddbe0832d003a7fa14a471211532ba03a0c1b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 10 Nov 2009 19:52:58 +0000 Subject: [PATCH 3409/4131] Add correct 16bit BSWAP behavior in the interpreting cores Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3498 --- src/cpu/core_full/op.h | 8 ++++++-- src/cpu/core_full/optable.h | 16 +++++++-------- src/cpu/core_full/support.h | 3 ++- src/cpu/core_normal/prefix_0f.h | 32 +++++++++++++++--------------- src/cpu/core_normal/prefix_66_0f.h | 24 ++++++++++++++++++++++ src/cpu/instructions.h | 5 ++++- 6 files changed, 60 insertions(+), 28 deletions(-) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index bfcb90d1..6c1ebc4d 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -584,9 +584,13 @@ switch (inst.code.op) { SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 31)))); inst_op1_d&=~(1 << (inst_op2_d & 31)); break; - case O_BSWAP: + case O_BSWAPw: if (CPU_ArchitectureType>24)|((op1>>8)&0xFF00)|((op1<<8)&0xFF0000)|((op1<<24)&0xFF000000); From 364257e1cc8b9290dc790b89b2f4a921887eb780 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Wed, 11 Nov 2009 18:56:45 +0000 Subject: [PATCH 3410/4131] Initially keep the serial port interrupt down. Fixes Kingdom O' Magic soundcard detection. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3499 --- src/hardware/serialport/serialport.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index 16fe4a8d..b6a310ac 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -1065,6 +1065,7 @@ void CSerial::Init_Registers () { Write_LCR (lcrresult); updateMSR(); Read_MSR(); + PIC_DeActivateIRQ(irq); } CSerial::CSerial(Bitu id, CommandLine* cmd) { From c4053d3d98dc28519e85c75baa819f8fa224211d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 11 Nov 2009 19:37:15 +0000 Subject: [PATCH 3411/4131] Return false when pausing audio when nothing is playing, fixes redneck rampage multiple track playing (ripsaw8080). Silently refuse to play datatrack. Fixes HOMM2. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3500 --- src/dos/cdrom_image.cpp | 11 ++++++++++- src/dos/cdrom_ioctl_win32.cpp | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index e85a5e80..f1dd9792 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -227,11 +227,19 @@ bool CDROM_Interface_Image::GetMediaTrayStatus(bool& mediaPresent, bool& mediaCh bool CDROM_Interface_Image::PlayAudioSector(unsigned long start,unsigned long len) { + // We might want to do some more checks. E.g valid start and length SDL_mutexP(player.mutex); player.cd = this; player.currFrame = start; player.targetFrame = start + len; - player.isPlaying = true; + int track = GetTrack(start) - 1; + if(track >= 0 && tracks[track].attr == 0x40) { + LOG(LOG_MISC,LOG_WARN)("Game tries to play the data track. Not doing this"); + player.isPlaying = false; + //Unclear wether return false should be here. + //specs say that this function returns at once and games should check the status wether the audio is actually playing + //Real drives either fail or succeed as well + } else player.isPlaying = true; player.isPaused = false; SDL_mutexV(player.mutex); return true; @@ -239,6 +247,7 @@ bool CDROM_Interface_Image::PlayAudioSector(unsigned long start,unsigned long le bool CDROM_Interface_Image::PauseAudio(bool resume) { + if (!player.isPlaying) return false; player.isPaused = !resume; return true; } diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index 0f60cfb8..60d9d3c6 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -430,6 +430,7 @@ bool CDROM_Interface_Ioctl::PauseAudio(bool resume) { return false; } if (use_dxplay) { + if (!player.isPlaying) return false; player.isPaused = !resume; return true; } From e0f2a469db11f667a0dfd03cade3f57841d90618 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 24 Nov 2009 07:16:28 +0000 Subject: [PATCH 3412/4131] Fine tune autoturn algorithm a bit. Let's hope games are smart enough to turn the keys off if they don't use the adlib anymore. (ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3501 --- src/hardware/adlib.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index c3995a37..23311778 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -549,7 +549,10 @@ static void OPL_CallBack(Bitu len) { module->handler->Generate( module->mixerChan, len ); //Disable the sound generation after 30 seconds of silence if ((PIC_Ticks - module->lastUsed) > 30000) { - module->mixerChan->Enable(false); + Bitu i; + for (i=0xb0;i<0xb9;i++) if (module->cache[i]&0x20||module->cache[i+0x100]&0x20) break; + if (i==0xb9) module->mixerChan->Enable(false); + else module->lastUsed = PIC_Ticks; } } From a165f2ae83a490dc3d3ae1354333ae815a683069 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Wed, 25 Nov 2009 19:24:49 +0000 Subject: [PATCH 3413/4131] SF bug 2854292: fix scrolling in Titan - thank you reg2s Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3502 --- src/hardware/vga_draw.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 709f76b9..6e94013b 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -801,6 +801,8 @@ static void VGA_VerticalTimer(Bitu /*val*/) { #endif switch (vga.mode) { case M_EGA: + if (!(vga.crtc.mode_control&0x1)) vga.draw.linear_mask &= ~0x10000; + else vga.draw.linear_mask |= 0x10000; case M_LIN4: vga.draw.byte_panning_shift = 8; vga.draw.address += vga.draw.bytes_skip; From 7f19fe7e3f5b90d650261b39b1e0616d6af93afa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 30 Nov 2009 08:21:38 +0000 Subject: [PATCH 3414/4131] Fix GTA installer. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3503 --- src/shell/shell.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 3d317904..dd5108eb 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -283,6 +283,8 @@ void DOS_Shell::Run(void) { std::string line; if (cmd->FindStringRemain("/C",line)) { strcpy(input_line,line.c_str()); + char* sep = strpbrk(input_line,"\r\n"); //GTA installer + if (sep) *sep = 0; DOS_Shell temp; temp.echo = echo; temp.ParseLine(input_line); //for *.exe *.com |*.bat creates the bf needed by runinternal; From b4313146e2b498d0f31cf708f8b7594bbc7ab4f1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 30 Nov 2009 08:31:17 +0000 Subject: [PATCH 3415/4131] Give an error class in some cases. Fixes Roadhog. (ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3504 --- src/dos/dos.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index db640ddb..0ff8f43e 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -816,7 +816,11 @@ static Bitu DOS_21Handler(void) { break; case 0x59: /* Get Extended error information */ reg_ax=dos.errorcode; - reg_bh=0; //Unkown error class + if (dos.errorcode==DOSERR_FILE_NOT_FOUND || dos.errorcode==DOSERR_PATH_NOT_FOUND) { + reg_bh=8; //Not Found error class (Road Hog) + } else { + reg_bh=0; //Unspecified error class + } reg_bl=1; //Retry retry retry reg_ch=0; //Unkown error locus break; From 0c2cdb1f5e0c01eaeaad22c0fe78fd37aefd82b3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 30 Nov 2009 13:10:50 +0000 Subject: [PATCH 3416/4131] Move back to the mem start of r3438. Fix Miami vice. The other buggy games were fixed otherwise Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3505 --- include/dos_inc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index c76ba885..ae02507f 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -86,7 +86,7 @@ enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; #define DOS_SDA_OFS 0 #define DOS_CDS_SEG 0x108 #define DOS_FIRST_SHELL 0x118 -#define DOS_MEM_START 0x16f //First Segment that DOS can use +#define DOS_MEM_START 0x170 //First Segment that DOS can use #define DOS_PRIVATE_SEGMENT 0xc800 #define DOS_PRIVATE_SEGMENT_END 0xd000 From 8c94075781749024c762f159668c2cb03e1fd46f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 30 Nov 2009 13:48:54 +0000 Subject: [PATCH 3417/4131] Undo 3505. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3506 --- include/dos_inc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index ae02507f..c76ba885 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -86,7 +86,7 @@ enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; #define DOS_SDA_OFS 0 #define DOS_CDS_SEG 0x108 #define DOS_FIRST_SHELL 0x118 -#define DOS_MEM_START 0x170 //First Segment that DOS can use +#define DOS_MEM_START 0x16f //First Segment that DOS can use #define DOS_PRIVATE_SEGMENT 0xc800 #define DOS_PRIVATE_SEGMENT_END 0xd000 From f56fdefb31663c47753e61f3a3accb49d700cb8e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 30 Nov 2009 14:53:00 +0000 Subject: [PATCH 3418/4131] report typed entry for %0 not the parsed entry.(System Shock reported by ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3507 --- include/shell.h | 2 +- src/shell/shell_batch.cpp | 6 +++--- src/shell/shell_misc.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/shell.h b/include/shell.h index b6799bee..7bce84df 100644 --- a/include/shell.h +++ b/include/shell.h @@ -44,7 +44,7 @@ class DOS_Shell; class BatchFile { public: - BatchFile(DOS_Shell * host,char const* const name, char const * const cmd_line); + BatchFile(DOS_Shell * host,char const* const resolved_name,char const* const entered_name, char const * const cmd_line); virtual ~BatchFile(); virtual bool ReadLine(char * line); bool Goto(char * where); diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 3d4c1668..821d188f 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -24,14 +24,14 @@ #include "shell.h" #include "support.h" -BatchFile::BatchFile(DOS_Shell * host,char const * const name, char const * const cmd_line) { +BatchFile::BatchFile(DOS_Shell * host,char const * const resolved_name,char const * const entered_name, char const * const cmd_line) { location = 0; prev=host->bf; echo=host->echo; shell=host; char totalname[DOS_PATHLENGTH+4]; - DOS_Canonicalize(name,totalname); // Get fullname including drive specificiation - cmd = new CommandLine(totalname,cmd_line); + DOS_Canonicalize(resolved_name,totalname); // Get fullname including drive specificiation + cmd = new CommandLine(entered_name,cmd_line); filename = totalname; //Test if file is openable diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 0f51905f..2b5056af 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -431,7 +431,7 @@ bool DOS_Shell::Execute(char * name,char * args) { /* delete old batch file if call is not active*/ bool temp_echo=echo; /*keep the current echostate (as delete bf might change it )*/ if(bf && !call) delete bf; - bf=new BatchFile(this,fullname,line); + bf=new BatchFile(this,fullname,name,line); echo=temp_echo; //restore it. } else From fa80b0458a63285a5d9f9841e07f5415c0ff2345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 1 Dec 2009 11:08:34 +0000 Subject: [PATCH 3419/4131] fix some warnings about float precision Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3508 --- src/hardware/cmos.cpp | 3 ++- src/hardware/opl.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 26a0e79f..35f3df88 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -68,7 +68,8 @@ static void cmos_checktimer(void) { LOG(LOG_PIT,LOG_NORMAL)("RTC Timer at %.2f hz",1000.0/cmos.timer.delay); // PIC_AddEvent(cmos_timerevent,cmos.timer.delay); /* A rtc is always running */ - PIC_AddEvent(cmos_timerevent,(double)cmos.timer.delay-fmod(PIC_FullIndex(),(double)cmos.timer.delay)); //Should be more like a real pc. Check + double remd=fmod(PIC_FullIndex(),(double)cmos.timer.delay); + PIC_AddEvent(cmos_timerevent,(float)((double)cmos.timer.delay-remd)); //Should be more like a real pc. Check // status reg A reading with this (and with other delays actually) } diff --git a/src/hardware/opl.cpp b/src/hardware/opl.cpp index b179a037..d09a79b6 100644 --- a/src/hardware/opl.cpp +++ b/src/hardware/opl.cpp @@ -62,7 +62,7 @@ static const fltype frqmul_tab[16] = { 0.5,1,2,3,4,5,6,7,8,9,10,10,12,12,15,15 }; // calculated frequency multiplication values (depend on sampling rate) -static float frqmul[16]; +static fltype frqmul[16]; // key scale levels static Bit8u kslev[8][16]; From 82ce78b0afe232c3e6459524199202ade2513548 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 1 Dec 2009 12:27:32 +0000 Subject: [PATCH 3420/4131] Fix typo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3509 --- acinclude.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index df8d8dc7..1ba54410 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -344,7 +344,7 @@ AH_BOTTOM([#if C_HAS_ATTRIBUTE AH_BOTTOM([#if C_HAS_BUILTIN_EXPECT #define GCC_UNLIKELY(x) __builtin_expect((x),0) -#define GCC_LIKELY(X) __builtin_expect((x),1) +#define GCC_LIKELY(x) __builtin_expect((x),1) #else #define GCC_UNLIKELY(x) (x) #define GCC_LIKELY(x) (x) From 189975198138adb4551fbc10e9105eb943d641f4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 1 Dec 2009 20:41:40 +0000 Subject: [PATCH 3421/4131] Playing around with LIKE Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3510 --- src/hardware/dbopl.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index 0ff691f8..b5ff85e4 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -401,9 +401,9 @@ Bits Operator::TemplateVolume( ) { break; case DECAY: vol += RateForward( decayAdd ); - if ( vol >= sustainLevel ) { + if ( GCC_UNLIKELY(vol >= sustainLevel) ) { //Check if we didn't overshoot max attenuation, then just go off - if ( vol >= ENV_MAX ) { + if ( GCC_UNLIKELY(vol >= ENV_MAX) ) { volume = ENV_MAX; SetState( OFF ); return ENV_MAX; @@ -420,7 +420,7 @@ Bits Operator::TemplateVolume( ) { //In sustain phase, but not sustaining, do regular release case RELEASE: vol += RateForward( releaseAdd );; - if ( vol >= ENV_MAX ) { + if ( GCC_UNLIKELY(vol >= ENV_MAX) ) { volume = ENV_MAX; SetState( OFF ); return ENV_MAX; @@ -1260,7 +1260,7 @@ void Chip::Setup( Bit32u rate ) { count += guessAdd; Bit32s change = count >> RATE_SH; count &= RATE_MASK; - if ( change ) { + if ( GCC_UNLIKELY(change) ) { // less than 1 % volume += ( ~volume * change ) >> 3; } samples++; @@ -1496,7 +1496,7 @@ void Handler::WriteReg( Bit32u addr, Bit8u val ) { void Handler::Generate( MixerChannel* chan, Bitu samples ) { Bit32s buffer[ 512 * 2 ]; - if ( samples > 512 ) + if ( GCC_UNLIKELY(samples > 512) ) samples = 512; if ( !chip.opl3Active ) { chip.GenerateBlock2( samples, buffer ); From d7ab4e8fd57bcf3cb4037dc9790c05a6449b3328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 2 Dec 2009 14:36:47 +0000 Subject: [PATCH 3422/4131] make it compile with vs2010 (abs overloading issue) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3511 --- src/hardware/vga_tseng.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hardware/vga_tseng.cpp b/src/hardware/vga_tseng.cpp index 72c4612f..c3cded9a 100644 --- a/src/hardware/vga_tseng.cpp +++ b/src/hardware/vga_tseng.cpp @@ -357,9 +357,10 @@ void FinishSetMode_ET4K(Bitu crtc_base, VGA_ModeExtraData* modeData) { Bitu best = 1; Bits dist = 100000000; for (Bitu i=0; i<16; i++) { - if (abs(target-et4k.clockFreq[i]) < dist) { + Bits cdiff=abs((Bits)(target-et4k.clockFreq[i])); + if (cdiff < dist) { best = i; - dist = abs(target-et4k.clockFreq[i]); + dist = cdiff; } } set_clock_index_et4k(best); @@ -718,9 +719,10 @@ void FinishSetMode_ET3K(Bitu crtc_base, VGA_ModeExtraData* modeData) { Bitu best = 1; Bits dist = 100000000; for (Bitu i=0; i<8; i++) { - if (abs(target-et3k.clockFreq[i]) < dist) { + Bits cdiff = abs((Bits)(target-et3k.clockFreq[i])); + if (cdiff < dist) { best = i; - dist = abs(target-et3k.clockFreq[i]); + dist = cdiff; } } set_clock_index_et3k(best); From 4c7f6b87f32ee892571392b6059fbd53a9382f2d Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Wed, 2 Dec 2009 21:11:03 +0000 Subject: [PATCH 3423/4131] Initialize cyclesleft variable so events can start at emulation time 0.0. Patch by Qbix Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3512 --- src/cpu/cpu.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index fdfa4c48..634558c2 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -49,7 +49,7 @@ CPUBlock cpu; Segments Segs; Bit32s CPU_Cycles = 0; -Bit32s CPU_CycleLeft = 0; +Bit32s CPU_CycleLeft = 3000; Bit32s CPU_CycleMax = 3000; Bit32s CPU_OldCycleMax = 3000; Bit32s CPU_CyclePercUsed = 100; @@ -2222,7 +2222,7 @@ public: bool Change_Config(Section* newconfig){ Section_prop * section=static_cast(newconfig); CPU_AutoDetermineMode=CPU_AUTODETERMINE_NONE; - CPU_CycleLeft=0;//needed ? + //CPU_CycleLeft=0;//needed ? CPU_Cycles=0; CPU_SkipCycleAutoAdjust=false; From fbd78617c2e220359ea1a57223ffbf900456bfd2 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Mon, 7 Dec 2009 20:00:14 +0000 Subject: [PATCH 3424/4131] Allow /p to work with /b in the DIR command - optimize /b a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3513 --- src/shell/shell_cmds.cpp | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index e04e018d..89989e0d 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -473,27 +473,26 @@ void DOS_Shell::CMD_DIR(char * args) { /* Skip non-directories if option AD is present */ if(optAD && !(attr&DOS_ATTR_DIRECTORY) ) continue; - - char * ext = empty_string; - if (!optW && (name[0] != '.')) { - ext = strrchr(name, '.'); - if (!ext) ext = empty_string; - else *ext++ = 0; - } - Bit8u day = (Bit8u)(date & 0x001f); - Bit8u month = (Bit8u)((date >> 5) & 0x000f); - Bit16u year = (Bit16u)((date >> 9) + 1980); - Bit8u hour = (Bit8u)((time >> 5 ) >> 6); - Bit8u minute = (Bit8u)((time >> 5) & 0x003f); - + /* output the file */ if (optB) { // this overrides pretty much everything if (strcmp(".",name) && strcmp("..",name)) { - if ((attr & DOS_ATTR_DIRECTORY)||(strlen(ext)==0)) WriteOut("%s\n",name); - else WriteOut("%s.%s\n",name,ext); + WriteOut("%s\n",name); } } else { + char * ext = empty_string; + if (!optW && (name[0] != '.')) { + ext = strrchr(name, '.'); + if (!ext) ext = empty_string; + else *ext++ = 0; + } + Bit8u day = (Bit8u)(date & 0x001f); + Bit8u month = (Bit8u)((date >> 5) & 0x000f); + Bit16u year = (Bit16u)((date >> 9) + 1980); + Bit8u hour = (Bit8u)((time >> 5 ) >> 6); + Bit8u minute = (Bit8u)((time >> 5) & 0x003f); + if (attr & DOS_ATTR_DIRECTORY) { if (optW) { WriteOut("[%s]",name); @@ -518,11 +517,9 @@ void DOS_Shell::CMD_DIR(char * args) { if (optW) { w_count++; } - if (optP) { - if (!(++p_count%(22*w_size))) { - CMD_PAUSE(empty_string); - } - } + } + if (optP && !(++p_count%(22*w_size))) { + CMD_PAUSE(empty_string); } } while ( (ret=DOS_FindNext()) ); if (optW) { From 3c25b8e28f2e59e28d0289d977b75b17935aa429 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 14 Dec 2009 18:14:23 +0000 Subject: [PATCH 3425/4131] Make Talking parrot happy. (ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3514 --- src/hardware/sblaster.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index a8329028..f80adbe8 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -995,6 +995,8 @@ static void DSP_DoCommand(void) { LOG(LOG_SB,LOG_ERROR)("DSP:Unimplemented auto-init DMA ADPCM command %2X",sb.dsp.cmd); break; case 0x20: + DSP_AddData(0x7f); // fake silent input for Creative parrot + break; case 0x2c: case 0x98: case 0x99: /* Documented only for DSP 2.x and 3.x */ case 0xa0: case 0xa8: /* Documented only for DSP 3.x */ From 526a1b01eeceb2ef74a681476afc728b73491c35 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 14 Dec 2009 18:52:34 +0000 Subject: [PATCH 3426/4131] Add 0xbd to allow table. Fixes offensive (ripsaw). Add some code to prevent stack corruption on long paths Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3515 --- src/dos/dos_files.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 875a189b..867c74e5 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -93,7 +93,7 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { case '!': case '%': case '{': case '}': case '`': case '~': case '_': case '-': case '.': case '*': case '?': case '&': case '\'': case '+': case '^': case 246: case 255: case 0xa0: - case 0xe5: + case 0xe5: case 0xbd: upname[w++]=c; break; default: @@ -175,6 +175,11 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { ext[4] = 0; if((strlen(tempdir) - strlen(ext)) > 8) memmove(tempdir + 8, ext, 5); } else tempdir[8]=0; + + if (strlen(fullname)+strlen(tempdir)>=DOS_PATHLENGTH) { + DOS_SetError(DOSERR_PATH_NOT_FOUND);return false; + } + strcat(fullname,tempdir); tempdir[0]=0; w=0;r++; From cbaa9c8ade8682627f6f9deed0a6c7a4a57c5a02 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Fri, 18 Dec 2009 14:02:32 +0000 Subject: [PATCH 3427/4131] The CGA mode register is actually not part of the video parameter table. Fixes regressions in the 3ktrivia, Hellcat and PCArcade booters. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3516 --- src/ints/int10_modes.cpp | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 1b2666c7..ded71f26 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -439,6 +439,7 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) { if (mode>6) return false; case TANDY_ARCH_CASE: if (mode>0xa) return false; + if (mode==7) mode=0; // PCJR defaults to 0 on illegal mode 7 if (!SetCurMode(ModeList_OTHER,mode)) { LOG(LOG_INT10,LOG_ERROR)("Trying to set illegal mode %X",mode); return false; @@ -448,6 +449,7 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) { // Only init the adapter if the equipment word is set to monochrome (Testdrive) if ((real_readw(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE)&0x30)!=0x30) return false; CurMode=&Hercules_Mode; + mode=7; // in case the video parameter table is modified break; } LOG(LOG_INT10,LOG_NORMAL)("Set Video Mode %X",mode); @@ -594,31 +596,15 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) { if (mode < 2) crtc_block_index = 0; else if (mode < 4) crtc_block_index = 1; else if (mode < 7) crtc_block_index = 2; - else { - if (machine==MCH_PCJR) { - if (mode < 9) crtc_block_index = 2; - else crtc_block_index = 3; - } else { - if (mode == 7) crtc_block_index = 3; - } - } + else if (mode == 7) crtc_block_index = 3; // MDA mono mode; invalid for others + else if (mode < 9) crtc_block_index = 2; + else crtc_block_index = 3; // Tandy/PCjr modes // init CRTC registers for (Bit16u i = 0; i < 16; i++) IO_WriteW(crtc_base, i | (real_readb(RealSeg(vparams), RealOff(vparams) + i + crtc_block_index*16) << 8)); - if (machine==MCH_CGA) { - // mode register - Bit8u mode_control = real_readb(RealSeg(vparams), RealOff(vparams) + 80 + mode); - IO_WriteB(crtc_base + 4, mode_control); - real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR, mode_control); - } - - if (machine==MCH_TANDY) { - E_Exit("INT10 modeset: video parameter table changed"); - } } - FinishSetMode(clearmem); return true; } From f88bda19ded8d3ed7238f7b2144f18c8a2cee399 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 19 Dec 2009 15:35:15 +0000 Subject: [PATCH 3428/4131] Enhance commandline support for long filenames with images. Add support for ISO/CUE. (dank je ronald) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3517 --- src/shell/shell.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index dd5108eb..d25edeac 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -373,6 +373,7 @@ public: /* Check for first command being a directory or file */ char buffer[CROSS_LEN]; + char orig[CROSS_LEN]; char cross_filesplit[2] = {CROSS_FILESPLIT , 0}; /* Combining -securemode and no parameter leaves you with a lovely Z:\. */ if ( !control->cmdline->FindCommand(1,line) ) { @@ -405,21 +406,29 @@ public: if (access(buffer,F_OK)) goto nomount; autoexec[12].Install(std::string("MOUNT C \"") + buffer + "\""); autoexec[13].Install("C:"); + /* Save the non modified filename (so boot and imgmount can use it (long filenames, case sensivitive)*/ + strcpy(orig,name); upcase(name); if(strstr(name,".BAT") != 0) { if(secure) autoexec[14].Install("z:\\config.com -securemode"); /* BATch files are called else exit will not work */ autoexec[15].Install(std::string("CALL ") + name); - } else if((strstr(name,".IMG") != 0) || (strstr(name,".IMA") !=0)) { + if(addexit) autoexec[16].Install("exit"); + } else if((strstr(name,".IMG") != 0) || (strstr(name,".IMA") !=0 )) { //No secure mode here as boot is destructive and enabling securemode disables boot /* Boot image files */ - autoexec[15].Install(std::string("BOOT ") + name); + autoexec[15].Install(std::string("BOOT ") + orig); + } else if((strstr(name,".ISO") != 0) || (strstr(name,".CUE") !=0 )) { + if(secure) autoexec[14].Install("z:\\config.com -securemode"); + /* imgmount CD image files */ + autoexec[15].Install(std::string("IMGMOUNT D \"") + orig + std::string("\" -t iso")); + //autoexec[16].Install("D:"); + /* Makes no sense to exit here */ } else { if(secure) autoexec[14].Install("z:\\config.com -securemode"); autoexec[15].Install(name); + if(addexit) autoexec[16].Install("exit"); } - - if(addexit) autoexec[16].Install("exit"); } } nomount: From c71c0246e9e71ee0002fbe34f160f1dc1bc7a9be Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sat, 26 Dec 2009 15:11:23 +0000 Subject: [PATCH 3429/4131] Add the S3-specific 640x480 256 color mode. Fixes regression in "Wooden Ships and Iron Men" and "I Have No Mouth And I Must Scream". Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3518 --- src/ints/int10_modes.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index ded71f26..e3326118 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -57,6 +57,8 @@ VideoModeBlock ModeList_VGA[]={ { 0x054 ,M_TEXT ,1056,688, 132,43, 8, 16, 1 ,0xB8000 ,0x4000, 192, 800, 132,688, 0 }, { 0x055 ,M_TEXT ,1056,400, 132,25, 8, 16, 1 ,0xB8000 ,0x2000, 192, 449, 132,400, 0 }, +/* Alias of mode 101 */ +{ 0x069 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, /* Alias of mode 102 */ { 0x06A ,M_LIN4 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, From 3cbf1c42e5803bbb86f6f32c5c279a3a5e7d193c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 28 Dec 2009 10:25:30 +0000 Subject: [PATCH 3430/4131] Rename dosprog to dosprogs to suggest more than one game/application can be stored in there Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3519 --- src/dos/dos_programs.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 3a3b8be6..d6c15b67 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1398,9 +1398,9 @@ void DOS_SetupPrograms(void) { "\033[44;1m\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n" - "\xBA \033[32mmount c c:\\dosprog\\\033[37m will create a C drive with c:\\dosprog as contents. \xBA\n" + "\xBA \033[32mmount c c:\\dosprogs\\\033[37m will create a C drive with c:\\dosprog as contents. \xBA\n" "\xBA \xBA\n" - "\xBA \033[32mc:\\dosprog\\\033[37m is an example. Replace it with your own games directory. \033[37m \xBA\n" + "\xBA \033[32mc:\\dosprogs\\\033[37m is an example. Replace it with your own games directory. \033[37m \xBA\n" "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC\033[0m\n" @@ -1409,9 +1409,9 @@ void DOS_SetupPrograms(void) { "\033[44;1m\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n" - "\xBA \033[32mmount c ~/dosprog\033[37m will create a C drive with ~/dosprog as contents. \xBA\n" + "\xBA \033[32mmount c ~/dosprogs\033[37m will create a C drive with ~/dosprog as contents. \xBA\n" "\xBA \xBA\n" - "\xBA \033[32m~/dosprog\033[37m is an example. Replace it with your own games directory. \033[37m \xBA\n" + "\xBA \033[32m~/dosprogs\033[37m is an example. Replace it with your own games directory. \033[37m \xBA\n" "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC\033[0m\n" From 1c5f8442c7e4652639e5d8bf9079e8e36ec3f30a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 29 Dec 2009 13:49:29 +0000 Subject: [PATCH 3431/4131] Fix regression in mount suggestion in imgmount. Thanks ripsaw Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3520 --- src/dos/dos_programs.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index d6c15b67..b5e46b2c 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1105,13 +1105,12 @@ public: WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FILE_NOT_FOUND")); return; } - - if ((test.st_mode & S_IFDIR)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MOUNT")); - return; - } } } + if ((test.st_mode & S_IFDIR)) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MOUNT")); + return; + } paths.push_back(temp_line); } if (paths.size() == 0) { From 8021ebdb6c6e85d344acae2b66529deb14549b34 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Fri, 1 Jan 2010 21:45:12 +0000 Subject: [PATCH 3432/4131] Clear Soundblaster interrupt if needed. Fixes sound detection in Xenoball. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3521 --- src/hardware/sblaster.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index f80adbe8..392a155c 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1368,7 +1368,10 @@ static Bitu read_sb(Bitu port,Bitu /*iolen*/) { return DSP_ReadData(); case DSP_READ_STATUS: //TODO See for high speed dma :) - sb.irq.pending_8bit=false; + if (sb.irq.pending_8bit) { + sb.irq.pending_8bit=false; + PIC_DeActivateIRQ(sb.hw.irq); + } if (sb.dsp.out.used) return 0xff; else return 0x7f; case DSP_ACK_16BIT: From 1d7e48c0dc4aa40a38cafa6a5ad5253ce3ae0196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 6 Jan 2010 19:34:23 +0000 Subject: [PATCH 3433/4131] care for stack wrapping when setting up exec block (ripsaw, fixes gp/gp cycles) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3522 --- src/dos/dos_execute.cpp | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index bf81479a..d660d539 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 @@ -57,11 +57,6 @@ struct EXE_Header { #define MAGIC2 0x4d5a #define MAXENV 32768u #define ENV_KEEPFREE 83 /* keep unallocated by environment variables */ - /* The '65' added to nEnvSize does not cover the additional stuff: - + 2 bytes: number of strings - + 80 bytes: maximum absolute filename - + 1 byte: '\0' - -- 1999/04/21 ska */ #define LOADNGO 0 #define LOAD 1 #define OVERLAY 3 @@ -107,7 +102,7 @@ void DOS_UpdatePSPName(void) { void DOS_Terminate(Bit16u pspseg,bool tsr,Bit8u exitcode) { dos.return_code=exitcode; - dos.return_mode=(tsr)?RETURN_TSR:RETURN_EXIT; + dos.return_mode=(tsr)?(Bit8u)RETURN_TSR:(Bit8u)RETURN_EXIT; DOS_PSP curpsp(pspseg); if (pspseg==curpsp.GetParent()) return; @@ -361,7 +356,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { if (!iscom) { /* Check if requested to load program into upper part of allocated memory */ if ((head.minmemory == 0) && (head.maxmemory == 0)) - loadseg = ((pspseg+memsize)*0x10-imagesize)/0x10; + loadseg = (Bit16u)(((pspseg+memsize)*0x10-imagesize)/0x10); } } else loadseg=block.overlay.loadseg; /* Load the executable */ @@ -416,6 +411,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { } else { csip=RealMake(loadseg+head.initCS,head.initIP); sssp=RealMake(loadseg+head.initSS,head.initSP); + if (head.initSP<4) E_Exit("stack underflow/wrap at EXEC"); } if (flags==LOAD) { @@ -437,6 +433,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { } if (flags==LOADNGO) { + if ((reg_sp>0xfffe) || (reg_sp<18)) E_Exit("stack underflow/wrap at EXEC"); /* Get Caller's program CS:IP of the stack and set termination address to that */ RealSetVec(0x22,RealMake(mem_readw(SegPhys(ss)+reg_sp+2),mem_readw(SegPhys(ss)+reg_sp))); SaveRegisters(); @@ -455,12 +452,10 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { /* Set the stack for new program */ SegSet16(ss,RealSeg(sssp));reg_sp=RealOff(sssp); /* Add some flags and CS:IP on the stack for the IRET */ - reg_sp-=4; - mem_writew(SegPhys(ss)+reg_sp+0,RealOff(csip)); - mem_writew(SegPhys(ss)+reg_sp+2,RealSeg(csip)); - /* Old info, we now jump to a RETF: - * DOS starts programs with a RETF, so our IRET - * should not modify critical flags (IOPL in v86 mode); + CPU_Push16(RealSeg(csip)); + CPU_Push16(RealOff(csip)); + /* DOS starts programs with a RETF, so critical flags + * should not be modified (IOPL in v86 mode); * interrupt flag is set explicitly, test flags cleared */ reg_flags=(reg_flags&(~FMASK_TEST))|FLAG_IF; //Jump to retf so that we only need to store cs:ip on the stack @@ -481,7 +476,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { while (char chr=*name++) { switch (chr) { case ':':case '\\':case '/':index=0;break; - default:if (index<8) stripname[index++]=toupper(chr); + default:if (index<8) stripname[index++]=(char)toupper(chr); } } index=0; From bf5257415d23dd5917ae4b9b1287cf4f420b5f93 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Wed, 6 Jan 2010 19:40:45 +0000 Subject: [PATCH 3434/4131] CMS/Gameblaster: add sbtype=gb, fix base addresses other than 220h, fix lack of sound when starting from autoexec, add autodetection (Thanks robertmo and Cloudschatze) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3523 --- src/dosbox.cpp | 4 +- src/hardware/gameblaster.cpp | 85 ++++++++++++++++++++++++++---------- src/hardware/sblaster.cpp | 19 +++++--- 3 files changed, 75 insertions(+), 33 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index c965186c..672f5546 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -480,10 +480,10 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("sblaster",&SBLASTER_Init,true);//done - const char* sbtypes[] = { "sb1", "sb2", "sbpro1", "sbpro2", "sb16", "none", 0 }; + const char* sbtypes[] = { "sb1", "sb2", "sbpro1", "sbpro2", "sb16", "gb", "none", 0 }; Pstring = secprop->Add_string("sbtype",Property::Changeable::WhenIdle,"sb16"); Pstring->Set_values(sbtypes); - Pstring->Set_help("Type of sblaster to emulate."); + Pstring->Set_help("Type of Soundblaster to emulate. gb is Gameblaster."); Phex = secprop->Add_hex("sbbase",Property::Changeable::WhenIdle,0x220); Phex->Set_values(ios); diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index 628d368b..8488eddc 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -22,6 +22,7 @@ #include "mem.h" #include "hardware.h" #include "setup.h" +#include "support.h" #include "pic.h" #include #include @@ -139,6 +140,7 @@ static Bit16s * cms_buf_point[4] = { cms_buffer[0][0],cms_buffer[0][1],cms_buffer[1][0],cms_buffer[1][1] }; static Bitu last_command; +static Bitu base_port; static void saa1099_envelope(int chip, int ch) @@ -286,6 +288,16 @@ static void saa1099_update(int chip, INT16 **buffer, int length) static void saa1099_write_port_w( int chip, int offset, int data ) { struct SAA1099 *saa = &saa1099[chip]; + if(offset == 1) { + // address port + saa->selected_reg = data & 0x1f; + if (saa->selected_reg == 0x18 || saa->selected_reg == 0x19) { + /* clock the envelope channels */ + if (saa->env_clock[0]) saa1099_envelope(chip,0); + if (saa->env_clock[1]) saa1099_envelope(chip,1); + } + return; + } int reg = saa->selected_reg; int ch; @@ -364,37 +376,26 @@ static void saa1099_write_port_w( int chip, int offset, int data ) } } - -static void write_cms(Bitu port,Bitu val,Bitu iolen) { - if (last_command + 1000 < PIC_Ticks) if(cms_chan) cms_chan->Enable(true); +static void write_cms(Bitu port, Bitu val, Bitu /* iolen */) { + if(cms_chan && (!cms_chan->enabled)) cms_chan->Enable(true); last_command = PIC_Ticks; - switch (port) { - case 0x0220: + switch (port-base_port) { + case 0: + saa1099_write_port_w(0,0,val); + break; + case 1: saa1099_write_port_w(0,1,val); break; - case 0x221: - saa1099[0].selected_reg = val & 0x1f; - if (saa1099[0].selected_reg == 0x18 || saa1099[0].selected_reg == 0x19) { - /* clock the envelope channels */ - if (saa1099[0].env_clock[0]) saa1099_envelope(0,0); - if (saa1099[0].env_clock[1]) saa1099_envelope(0,1); - } + case 2: + saa1099_write_port_w(1,0,val); break; - case 0x0222: + case 3: saa1099_write_port_w(1,1,val); break; - case 0x223: - saa1099[1].selected_reg = val & 0x1f; - if (saa1099[1].selected_reg == 0x18 || saa1099[1].selected_reg == 0x19) { - /* clock the envelope channels */ - if (saa1099[1].env_clock[0]) saa1099_envelope(1,0); - if (saa1099[1].env_clock[1]) saa1099_envelope(1,1); - } - break; } } - static void CMS_CallBack(Bitu len) { +static void CMS_CallBack(Bitu len) { if (len > CMS_BUFFER_SIZE) return; saa1099_update(0, &cms_buf_point[0], (int)len); @@ -421,10 +422,38 @@ static void write_cms(Bitu port,Bitu val,Bitu iolen) { if (last_command + 10000 < PIC_Ticks) if(cms_chan) cms_chan->Enable(false); } +// The Gameblaster detection +static Bit8u cms_detect_register = 0xff; + +static void write_cms_detect(Bitu port, Bitu val, Bitu /* iolen */) { + switch(port-base_port) { + case 0x6: + case 0x7: + cms_detect_register = val; + break; + } +} + +static Bitu read_cms_detect(Bitu port, Bitu /* iolen */) { + Bit8u retval = 0xff; + switch(port-base_port) { + case 0x4: + retval = 0x7f; + break; + case 0xa: + case 0xb: + retval = cms_detect_register; + break; + } + return retval; +} + class CMS:public Module_base { private: IO_WriteHandleObject WriteHandler; + IO_WriteHandleObject DetWriteHandler; + IO_ReadHandleObject DetReadHandler; MixerObject MixerChan; public: @@ -432,8 +461,16 @@ public: Section_prop * section = static_cast(configuration); Bitu sample_rate_temp = section->Get_int("oplrate"); sample_rate = static_cast(sample_rate_temp); - Bitu base = section->Get_hex("sbbase"); - WriteHandler.Install(base,write_cms,IO_MB,4); + base_port = section->Get_hex("sbbase"); + WriteHandler.Install(base_port, write_cms, IO_MB,4); + + // A standalone Gameblaster has a magic chip on it which is + // sometimes used for detection. + const char * sbtype=section->Get_string("sbtype"); + if (!strcasecmp(sbtype,"gb")) { + DetWriteHandler.Install(base_port+4,write_cms_detect,IO_MB,12); + DetReadHandler.Install(base_port,read_cms_detect,IO_MB,16); + } /* Register the Mixer CallBack */ cms_chan = MixerChan.Install(CMS_CallBack,sample_rate_temp,"CMS"); diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 392a155c..f45ca282 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -63,7 +63,7 @@ bool MIDI_Available(void); #define SB_SH_MASK ((1 << SB_SH)-1) enum {DSP_S_RESET,DSP_S_RESET_WAIT,DSP_S_NORMAL,DSP_S_HIGHSPEED}; -enum SB_TYPES {SBT_NONE=0,SBT_1=1,SBT_PRO1=2,SBT_2=3,SBT_PRO2=4,SBT_16=6}; +enum SB_TYPES {SBT_NONE=0,SBT_1=1,SBT_PRO1=2,SBT_2=3,SBT_PRO2=4,SBT_16=6,SBT_GB=7}; enum SB_IRQS {SB_IRQ_8,SB_IRQ_16,SB_IRQ_MPU}; enum DSP_MODES { @@ -1478,6 +1478,7 @@ private: else if (!strcasecmp(sbtype,"sbpro1")) type=SBT_PRO1; else if (!strcasecmp(sbtype,"sbpro2")) type=SBT_PRO2; else if (!strcasecmp(sbtype,"sb16")) type=SBT_16; + else if (!strcasecmp(sbtype,"gb")) type=SBT_GB; else if (!strcasecmp(sbtype,"none")) type=SBT_NONE; else type=SBT_16; @@ -1495,7 +1496,9 @@ private: /* Else assume auto */ else { switch (type) { - case SBT_NONE:opl_mode=OPL_none;break; + case SBT_NONE: + case SBT_GB: + opl_mode=OPL_none;break; case SBT_1:opl_mode=OPL_opl2;break; case SBT_2:opl_mode=OPL_opl2;break; case SBT_PRO1:opl_mode=OPL_dualopl2;break; @@ -1524,23 +1527,25 @@ public: OPL_Mode opl_mode = OPL_none; Find_Type_And_Opl(section,sb.type,opl_mode); + bool do_cms = (sb.type==SBT_GB)? true:false; + switch (opl_mode) { case OPL_none: WriteHandler[0].Install(0x388,adlib_gusforward,IO_MB); break; case OPL_cms: WriteHandler[0].Install(0x388,adlib_gusforward,IO_MB); - CMS_Init(section); + do_cms = true; break; case OPL_opl2: - CMS_Init(section); + do_cms = true; case OPL_dualopl2: case OPL_opl3: OPL_Init(section,opl_mode); break; } - - if (sb.type==SBT_NONE) return; + if (do_cms) CMS_Init(section); + if (sb.type==SBT_NONE || sb.type==SBT_GB) return; sb.chan=MixerChan.Install(&SBLASTER_CallBack,22050,"SB"); sb.dsp.state=DSP_S_NORMAL; @@ -1603,7 +1608,7 @@ public: break; } - if (sb.type==SBT_NONE) return; + if (sb.type==SBT_NONE || sb.type==SBT_GB) return; DSP_Reset();//Stop everything } }; //End of SBLASTER class From 905e6836b3ede90d2d35e88279ab155ece57f510 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 6 Jan 2010 20:08:08 +0000 Subject: [PATCH 3435/4131] Fix echo hello /? Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3524 --- src/shell/shell_cmds.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 89989e0d..621b5209 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -262,7 +262,6 @@ void DOS_Shell::CMD_RENAME(char * args){ } void DOS_Shell::CMD_ECHO(char * args){ - HELP("ECHO"); if (!*args) { if (echo) { WriteOut(MSG_Get("SHELL_CMD_ECHO_ON"));} else { WriteOut(MSG_Get("SHELL_CMD_ECHO_OFF"));} @@ -280,6 +279,8 @@ void DOS_Shell::CMD_ECHO(char * args){ echo=true; return; } + if(strcasecmp(pbuffer,"/?")==0) { HELP("ECHO"); } + args++;//skip first character. either a slash or dot or space size_t len = strlen(args); //TODO check input of else ook nodig is. if(len && args[len - 1] == '\r') { From 07833329aee5e6f9e7cdc1b501f4b1a9ff1391ed Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Thu, 7 Jan 2010 23:43:17 +0000 Subject: [PATCH 3436/4131] Add I/O port console logging. To be activated by #define. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3525 --- src/hardware/iohandler.cpp | 97 +++++++++++++++++++++++++++++++++----- 1 file changed, 86 insertions(+), 11 deletions(-) diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 328c7804..ea170f0e 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -26,6 +26,8 @@ #include "../src/cpu/lazyflags.h" #include "callback.h" +//#define ENABLE_PORTLOG + IO_WriteHandler * io_writehandlers[3][IO_MAX]; IO_ReadHandler * io_readhandlers[3][IO_MAX]; @@ -209,8 +211,74 @@ inline void IO_USEC_write_delay() { CPU_IODelayRemoved += delaycyc; } +#ifdef ENABLE_PORTLOG +static Bit8u crtc_index = 0; +const char* const len_type[] = {" 8","16","32"}; +void log_io(Bitu width, bool write, Bitu port, Bitu val) { + switch(width) { + case 0: + val&=0xff; + break; + case 1: + val&=0xffff; + break; + } + if (write) { + // skip the video cursor position spam + if (port==0x3d4) { + if (width==0) crtc_index = (Bit8u)val; + else if(width==1) crtc_index = (Bit8u)(val>>8); + } + if (crtc_index==0xe || crtc_index==0xf) { + if((width==0 && (port==0x3d4 || port==0x3d5))||(width==1 && port==0x3d4)) + return; + } + + switch(port) { + //case 0x020: // interrupt command + //case 0x040: // timer 0 + //case 0x042: // timer 2 + //case 0x043: // timer control + //case 0x061: // speaker control + case 0x3c8: // VGA palette + case 0x3c9: // VGA palette + // case 0x3d4: // VGA crtc + // case 0x3d5: // VGA crtc + // case 0x3c4: // VGA seq + // case 0x3c5: // VGA seq + break; + default: + LOG_MSG("iow%s % 4x % 4x, cs:ip %04x:%04x", len_type[width], + port, val, SegValue(cs),reg_eip); + break; + } + } else { + switch(port) { + //case 0x021: // interrupt status + //case 0x040: // timer 0 + //case 0x042: // timer 2 + //case 0x061: // speaker control + case 0x201: // joystick status + case 0x3c9: // VGA palette + // case 0x3d4: // VGA crtc index + // case 0x3d5: // VGA crtc + case 0x3da: // display status - a real spammer + // don't log for the above cases + break; + default: + LOG_MSG("ior%s % 4x % 4x,\t\tcs:ip %04x:%04x", len_type[width], + port, val, SegValue(cs),reg_eip); + break; + } + } +} +#else +#define log_io(W, X, Y, Z) +#endif + void IO_WriteB(Bitu port,Bitu val) { + log_io(0, true, port, val); if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,1)))) { LazyFlags old_lflags; memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); @@ -246,6 +314,7 @@ void IO_WriteB(Bitu port,Bitu val) { } void IO_WriteW(Bitu port,Bitu val) { + log_io(1, true, port, val); if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,2)))) { LazyFlags old_lflags; memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); @@ -281,6 +350,7 @@ void IO_WriteW(Bitu port,Bitu val) { } void IO_WriteD(Bitu port,Bitu val) { + log_io(2, true, port, val); if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,4)))) { LazyFlags old_lflags; memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); @@ -313,6 +383,7 @@ void IO_WriteD(Bitu port,Bitu val) { } Bitu IO_ReadB(Bitu port) { + Bitu retval; if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,1)))) { LazyFlags old_lflags; memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); @@ -334,8 +405,7 @@ Bitu IO_ReadB(Bitu port) { DOSBOX_RunMachine(); iof_queue.used--; - Bitu retval = reg_al; - + retval = reg_al; reg_dx = old_dx; memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); cpudecoder=old_cpudecoder; @@ -343,11 +413,14 @@ Bitu IO_ReadB(Bitu port) { } else { IO_USEC_read_delay(); - return io_readhandlers[0][port](port,1); + retval = io_readhandlers[0][port](port,1); } + log_io(0, false, port, retval); + return retval; } Bitu IO_ReadW(Bitu port) { + Bitu retval; if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,2)))) { LazyFlags old_lflags; memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); @@ -369,20 +442,21 @@ Bitu IO_ReadW(Bitu port) { DOSBOX_RunMachine(); iof_queue.used--; - Bitu retval = reg_ax; - + retval = reg_ax; reg_dx = old_dx; memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); cpudecoder=old_cpudecoder; - return retval; } else { IO_USEC_read_delay(); - return io_readhandlers[1][port](port,2); + retval = io_readhandlers[1][port](port,2); } + log_io(1, false, port, retval); + return retval; } Bitu IO_ReadD(Bitu port) { + Bitu retval; if (GCC_UNLIKELY(GETFLAG(VM) && (CPU_IO_Exception(port,4)))) { LazyFlags old_lflags; memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); @@ -404,14 +478,15 @@ Bitu IO_ReadD(Bitu port) { DOSBOX_RunMachine(); iof_queue.used--; - Bitu retval = reg_eax; - + retval = reg_eax; reg_dx = old_dx; memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); cpudecoder=old_cpudecoder; - return retval; + } else { + retval = io_readhandlers[2][port](port,4); } - else return io_readhandlers[2][port](port,4); + log_io(2, false, port, retval); + return retval; } class IO :public Module_base { From 70b2bc9b36aa64edfacc2b5d9126eb504e1564cc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 8 Jan 2010 06:32:06 +0000 Subject: [PATCH 3437/4131] Update address and spaces Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3526 --- src/dos/dos_programs.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index b5e46b2c..931e73f8 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1381,7 +1381,7 @@ void DOS_SetupPrograms(void) { "For information about basic mount type \033[34;1mintro mount\033[0m\n" "For information about CD-ROM support type \033[34;1mintro cdrom\033[0m\n" "For information about special keys type \033[34;1mintro special\033[0m\n" - "For more information about DOSBox, go to \033[34;1mhttp://dosbox.sourceforge.net/wiki\033[0m\n" + "For more information about DOSBox, go to \033[34;1mhttp://www.dosbox.com/wiki\033[0m\n" "\n" "\033[31;1mDOSBox will stop/exit without a warning if an error occured!\033[0m\n" "\n" @@ -1397,9 +1397,9 @@ void DOS_SetupPrograms(void) { "\033[44;1m\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n" - "\xBA \033[32mmount c c:\\dosprogs\\\033[37m will create a C drive with c:\\dosprog as contents. \xBA\n" + "\xBA \033[32mmount c c:\\dosprogs\\\033[37m will create a C drive with c:\\dosprog as contents.\xBA\n" "\xBA \xBA\n" - "\xBA \033[32mc:\\dosprogs\\\033[37m is an example. Replace it with your own games directory. \033[37m \xBA\n" + "\xBA \033[32mc:\\dosprogs\\\033[37m is an example. Replace it with your own games directory. \033[37m \xBA\n" "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC\033[0m\n" @@ -1408,9 +1408,9 @@ void DOS_SetupPrograms(void) { "\033[44;1m\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n" - "\xBA \033[32mmount c ~/dosprogs\033[37m will create a C drive with ~/dosprog as contents. \xBA\n" + "\xBA \033[32mmount c ~/dosprogs\033[37m will create a C drive with ~/dosprog as contents.\xBA\n" "\xBA \xBA\n" - "\xBA \033[32m~/dosprogs\033[37m is an example. Replace it with your own games directory. \033[37m \xBA\n" + "\xBA \033[32m~/dosprogs\033[37m is an example. Replace it with your own games directory.\033[37m \xBA\n" "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC\033[0m\n" From e78454dbb91855d6b8fb413ae03b6952bc814f10 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 8 Jan 2010 18:20:22 +0000 Subject: [PATCH 3438/4131] Some more cosmetic stuff. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3527 --- src/dos/dos_programs.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 931e73f8..0c2d9dcf 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1396,22 +1396,22 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_INTRO_MOUNT_WINDOWS", "\033[44;1m\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n" - "\xBA \033[32mmount c c:\\dosprogs\\\033[37m will create a C drive with c:\\dosprog as contents.\xBA\n" - "\xBA \xBA\n" - "\xBA \033[32mc:\\dosprogs\\\033[37m is an example. Replace it with your own games directory. \033[37m \xBA\n" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n" + "\xBA \033[32mmount c c:\\dosprogs\\\033[37m will create a C drive with c:\\dosprogs as contents.\xBA\n" + "\xBA \xBA\n" + "\xBA \033[32mc:\\dosprogs\\\033[37m is an example. Replace it with your own games directory. \033[37m \xBA\n" "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC\033[0m\n" ); MSG_Add("PROGRAM_INTRO_MOUNT_OTHER", - "\033[44;1m\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\033[44;1m\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n" - "\xBA \033[32mmount c ~/dosprogs\033[37m will create a C drive with ~/dosprog as contents.\xBA\n" - "\xBA \xBA\n" - "\xBA \033[32m~/dosprogs\033[37m is an example. Replace it with your own games directory.\033[37m \xBA\n" - "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xBA \033[32mmount c ~/dosprogs\033[37m will create a C drive with ~/dosprogs as contents.\xBA\n" + "\xBA \xBA\n" + "\xBA \033[32m~/dosprogs\033[37m is an example. Replace it with your own games directory.\033[37m \xBA\n" + "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC\033[0m\n" ); From ad03dd1cb16cac1565bb2701502f5a21141ed592 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 8 Jan 2010 19:03:48 +0000 Subject: [PATCH 3439/4131] To prevent problems in the future and to make things more identical. rename mapper.txt to mapper-version.conf Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3528 --- src/gui/sdlmain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index a7b681ae..d60fe0cc 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1513,7 +1513,7 @@ void Config_Add_SDL() { Pstring = Pmulti->GetSection()->Add_string("inactive",Property::Changeable::Always,"normal"); Pstring->Set_values(inactt); - Pstring = sdl_sec->Add_path("mapperfile",Property::Changeable::Always,"mapper.txt"); + Pstring = sdl_sec->Add_path("mapperfile",Property::Changeable::Always,"mapper-" VERSION ".conf"); Pstring->Set_help("File used to load/save the key/event mappings from."); Pbool = sdl_sec->Add_bool("usescancodes",Property::Changeable::Always,true); From 984e627dd185cbf4505e3e0728aa917898fa369d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Jan 2010 09:35:32 +0000 Subject: [PATCH 3440/4131] Include debian manpage fixes. Improve layout of the config -securemode option Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3529 --- docs/dosbox.1 | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/dosbox.1 b/docs/dosbox.1 index 653e57d3..edef4bce 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -96,17 +96,17 @@ Output version information and exit. Useful for frontends. .TP .BI \-editconf " program" .RI calls " program" " with as first parameter the configuration file." -.R You can specify this command more than once. In this case it will +You can specify this command more than once. In this case it will .RI " move to second " program " if the first one fails to start." .TP .BI \-opencaptures " program" .RI "calls " program " with as first paramater the location of the captures folder." .TP .B \-printconf -.R prints the location of the default configuration file. +prints the location of the default configuration file. .TP .B \-eraseconf -.R removes the default configuration file. +removes the default configuration file. .SH "INTERNAL COMMANDS" .B dosbox supports most of the DOS commands found in command.com. In addition, the @@ -183,11 +183,12 @@ Display the amount of free memory .TP .B CONFIG [\-writeconf] [\-writelang] file .LP -.B CONFIG -securemode +.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 . +.RS .TP .B \-securemode .RB Switches dosbox " to a more secure mode. In this mode the" @@ -196,6 +197,7 @@ 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 .) +.RE .LP The configuration file controls various settings of .BR dosbox ": The amount of emulated memory," @@ -220,7 +222,7 @@ The name of the program which is executed after loadfix eats up its memory. .RB "Parameters given to the " programname " executable." .TP .B \-size -The amount of memory to eat up (in kb). Example -32, -64 or -128 +The amount of memory to eat up (in kb). Example \-32, \-64 or \-128 .TP .B \-f Frees all memory eaten up by loadfix. @@ -234,7 +236,7 @@ this as well!) .TP .B IMGMOUNT .LP -.RB "A utility to mount disk images and CD-ROM images in " dosbox . +.RB "A utility to mount disk images and CD\(hyROM images in " dosbox . .TP .RB "Read the " README " of " dosbox " for the full and correct syntax." .RE @@ -283,7 +285,7 @@ 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 +Swap mounted disk\(hyimage (Only used with imgmount). Update directory cache for all drives! .IP CTRL\-F5 Save a screenshot.(png) From b8dd53b7fc843e42def168e906d21f8b213d75c8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Jan 2010 10:09:46 +0000 Subject: [PATCH 3441/4131] Include debian general spelling suggestions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3530 --- src/dos/dos_misc.cpp | 2 +- src/dos/dos_programs.cpp | 10 +++++----- src/dos/drive_fat.cpp | 8 ++++---- src/dos/drives.h | 2 +- src/hardware/pic.cpp | 2 +- src/shell/shell.cpp | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index c448ac4e..64d4dd7e 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -192,7 +192,7 @@ static bool DOS_MultiplexFunctions(void) { case 0x4a01: /* Query free hma space */ case 0x4a02: /* ALLOCATE HMA SPACE */ LOG(LOG_DOSMISC,LOG_WARN)("INT 2f:4a HMA. DOSBox reports none available."); - reg_bx=0; //number of bytes available in HMA or amount succesfully allocated + reg_bx=0; //number of bytes available in HMA or amount successfully allocated //ESDI=ffff:ffff Location of HMA/Allocated memory SegSet16(es,0xffff); reg_di=0xffff; diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 0c2d9dcf..537553fc 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -90,7 +90,7 @@ public: Drives[i_drive] = 0; if(i_drive == DOS_GetDefaultDrive()) DOS_SetDrive(toupper('Z') - 'A'); - WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCES"),umount[0]); + WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCESS"),umount[0]); break; case 1: WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NO_VIRTUAL")); @@ -990,7 +990,7 @@ public: Drives[i_drive] = 0; if (i_drive == DOS_GetDefaultDrive()) DOS_SetDrive(toupper('Z') - 'A'); - WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCES"),umount[0]); + WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCESS"),umount[0]); break; case 1: WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NO_VIRTUAL")); @@ -1155,7 +1155,7 @@ public: } newdrive=new fatDrive(temp_line.c_str(),sizes[0],sizes[1],sizes[2],sizes[3],0); - if(!(dynamic_cast(newdrive))->created_succesfully) { + if(!(dynamic_cast(newdrive))->created_successfully) { delete newdrive; newdrive = 0; } @@ -1348,7 +1348,7 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_MOUNT_ALREADY_MOUNTED","Drive %c already mounted with %s\n"); MSG_Add("PROGRAM_MOUNT_USAGE","Usage \033[34;1mMOUNT Drive-Letter Local-Directory\033[0m\nSo a MOUNT c c:\\windows mounts windows directory as the c: drive in DOSBox\n"); MSG_Add("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED","Drive %c isn't mounted.\n"); - MSG_Add("PROGRAM_MOUNT_UMOUNT_SUCCES","Drive %c has succesfully been removed.\n"); + MSG_Add("PROGRAM_MOUNT_UMOUNT_SUCCESS","Drive %c has successfully been removed.\n"); MSG_Add("PROGRAM_MOUNT_UMOUNT_NO_VIRTUAL","Virtual Drives can not be unMOUNTed.\n"); MSG_Add("PROGRAM_MOUNT_WARNING_WIN","\033[31;1mMounting c:\\ is NOT recommended. Please mount a (sub)directory next time.\033[0m\n"); MSG_Add("PROGRAM_MOUNT_WARNING_OTHER","\033[31;1mMounting / is NOT recommended. Please mount a (sub)directory next time.\033[0m\n"); @@ -1416,7 +1416,7 @@ void DOS_SetupPrograms(void) { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC\033[0m\n" ); MSG_Add("PROGRAM_INTRO_MOUNT_END", - "When the mount has succesfully completed you can type \033[34;1mc:\033[0m to go to your freshly\n" + "When the mount has successfully completed you can type \033[34;1mc:\033[0m to go to your freshly\n" "mounted C-drive. Typing \033[34;1mdir\033[0m there will show its contents." " \033[34;1mcd\033[0m will allow you to\n" "enter a directory (recognised by the \033[33;1m[]\033[0m in a directory listing).\n" diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 76cf9736..9e9d2453 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -628,7 +628,7 @@ bool fatDrive::allocateCluster(Bit32u useCluster, Bit32u prevCluster) { } fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, Bit32u headscyl, Bit32u cylinders, Bit32u startSector) { - created_succesfully = true; + created_successfully = true; FILE *diskfile; Bit32u filesize; struct partTable mbrData; @@ -640,14 +640,14 @@ fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, } diskfile = fopen(sysFilename, "rb+"); - if(!diskfile) {created_succesfully = false;return;} + if(!diskfile) {created_successfully = false;return;} fseek(diskfile, 0L, SEEK_END); filesize = (Bit32u)ftell(diskfile) / 1024L; /* Load disk image */ loadedDisk = new imageDisk(diskfile, (Bit8u *)sysFilename, filesize, (filesize > 2880)); if(!loadedDisk) { - created_succesfully = false; + created_successfully = false; return; } @@ -686,7 +686,7 @@ fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, if(!bootbuffer.sectorsperfat) { /* FAT32 not implemented yet */ - created_succesfully = false; + created_successfully = false; return; } diff --git a/src/dos/drives.h b/src/dos/drives.h index 86ce3deb..3a544872 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -175,7 +175,7 @@ public: bool directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum); bool directoryChange(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum); imageDisk *loadedDisk; - bool created_succesfully; + bool created_successfully; private: Bit32u getClusterValue(Bit32u clustNum); void setClusterValue(Bit32u clustNum, Bit32u clustValue); diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 5a1df36c..40b1848e 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -315,7 +315,7 @@ void PIC_runIRQs(void) { if (!irqs[i].masked && irqs[i].active) { /* the irq line is active. it's not masked and * the irq is allowed priority wise. So let's start it */ - /* If started succesfully return, else go for the next */ + /* If started successfully return, else go for the next */ if(PIC_startIRQ(i)) return; } } diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index d25edeac..1fccbd51 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -457,7 +457,7 @@ void SHELL_Init() { MSG_Add("SHELL_MISSING_PARAMETER","Required parameter missing.\n"); MSG_Add("SHELL_CMD_CHDIR_ERROR","Unable to change to: %s.\n"); MSG_Add("SHELL_CMD_CHDIR_HINT","To change to different drive type \033[31m%c:\033[0m\n"); - MSG_Add("SHELL_CMD_CHDIR_HINT_2","directoryname is longer than 8 charachters and/or contains spaces.\nTry \033[31mcd %s\033[0m\n"); + MSG_Add("SHELL_CMD_CHDIR_HINT_2","directoryname is longer than 8 characters and/or contains spaces.\nTry \033[31mcd %s\033[0m\n"); MSG_Add("SHELL_CMD_CHDIR_HINT_3","You are still on drive Z:, change to a mounted drive with \033[31mC:\033[0m.\n"); MSG_Add("SHELL_CMD_MKDIR_ERROR","Unable to make: %s.\n"); MSG_Add("SHELL_CMD_RMDIR_ERROR","Unable to remove: %s.\n"); From 79bcdc6c3887a69ca4d4288f52a950c60cebb106 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Jan 2010 12:31:35 +0000 Subject: [PATCH 3442/4131] Fix ANTIGOK1.EXE and other basic programs compiled with the same compiler that use load zero, change sign, write as BCD as template for reading in negative values. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3531 --- src/fpu/fpu_instructions.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index ec2f810d..bfc564ef 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -106,7 +106,7 @@ static Real64 FPU_FLD80(PhysPt addr) { Bit64s sign = (test.begin&0x8000)?1:0; FPU_Reg result; result.ll = (sign <<63)|(exp64final << 52)| mant64; - return result.d; + return result.d; //mant64= test.mant80/2***64 * 2 **53 } @@ -239,7 +239,7 @@ static void FPU_FST_I64(PhysPt addr) { static void FPU_FBST(PhysPt addr) { FPU_Reg val = fpu.regs[TOP]; bool sign = false; - if(val.d<0.0){ //sign + if(fpu.regs[TOP].ll & LONGTYPE(0x8000000000000000)) { //sign sign=true; val.d=-val.d; } @@ -519,7 +519,7 @@ static void FPU_FXTRACT(void) { Bit64s exp80final = (exp80>>52) - BIAS64; Real64 mant = test.d / (pow(2.0,static_cast(exp80final))); fpu.regs[TOP].d = static_cast(exp80final); - FPU_PUSH(mant); + FPU_PUSH(mant); } static void FPU_FCHS(void){ From 3e936332a532c6e338ef8fe4d3060ab713714da8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Jan 2010 14:56:30 +0000 Subject: [PATCH 3443/4131] Don't parse mouse button release and presses with numbers outside the amount of reported buttons. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3532 --- src/ints/mouse.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 06357726..8ea01c71 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -496,18 +496,26 @@ void Mouse_CursorSet(float x,float y) { void Mouse_ButtonPressed(Bit8u button) { switch (button) { +#if (MOUSE_BUTTONS >= 1) case 0: mouse.buttons|=1; Mouse_AddEvent(MOUSE_LEFT_PRESSED); break; +#endif +#if (MOUSE_BUTTONS >= 2) case 1: mouse.buttons|=2; Mouse_AddEvent(MOUSE_RIGHT_PRESSED); break; +#endif +#if (MOUSE_BUTTONS >= 3) case 2: mouse.buttons|=4; Mouse_AddEvent(MOUSE_MIDDLE_PRESSED); break; +#endif + default: + return; } mouse.times_pressed[button]++; mouse.last_pressed_x[button]=POS_X; @@ -516,18 +524,26 @@ void Mouse_ButtonPressed(Bit8u button) { void Mouse_ButtonReleased(Bit8u button) { switch (button) { +#if (MOUSE_BUTTONS >= 1) case 0: mouse.buttons&=~1; Mouse_AddEvent(MOUSE_LEFT_RELEASED); break; +#endif +#if (MOUSE_BUTTONS >= 2) case 1: mouse.buttons&=~2; Mouse_AddEvent(MOUSE_RIGHT_RELEASED); break; +#endif +#if (MOUSE_BUTTONS >= 3) case 2: mouse.buttons&=~4; Mouse_AddEvent(MOUSE_MIDDLE_RELEASED); break; +#endif + default: + return; } mouse.times_released[button]++; mouse.last_released_x[button]=POS_X; From cfbe192e7033c4773d814154f32d7a063b96e97f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 12 Jan 2010 14:13:23 +0000 Subject: [PATCH 3444/4131] Fix ca-cyber with C FPU core. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3533 --- src/fpu/fpu_instructions.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index bfc564ef..8b608249 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -118,12 +118,16 @@ static void FPU_ST80(PhysPt addr,Bitu reg) { } test; Bit64s sign80 = (fpu.regs[reg].ll&LONGTYPE(0x8000000000000000))?1:0; Bit64s exp80 = fpu.regs[reg].ll&LONGTYPE(0x7ff0000000000000); - Bit64s exp80final = (exp80>>52) - BIAS64 + BIAS80; + Bit64s exp80final = (exp80>>52); Bit64s mant80 = fpu.regs[reg].ll&LONGTYPE(0x000fffffffffffff); Bit64s mant80final = (mant80 << 11); - // Elvira wants the 8 and tcalc doesn't - if(fpu.regs[reg].d != 0) mant80final |= LONGTYPE(0x8000000000000000); - test.begin= (static_cast(sign80)<<15)| static_cast(exp80final); + if(fpu.regs[reg].d != 0){ //Zero is a special case + // Elvira wants the 8 and tcalc doesn't + mant80final |= LONGTYPE(0x8000000000000000); + //Ca-cyber doesn't like this when result is zero. + exp80final += (BIAS80 - BIAS64); + } + test.begin = (static_cast(sign80)<<15)| static_cast(exp80final); test.eind.ll = mant80final; mem_writed(addr,test.eind.l.lower); mem_writed(addr+4,test.eind.l.upper); From 1e1dbbff8ccc2409ffb82a87bfbdb1f368d0f639 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 13 Jan 2010 18:26:07 +0000 Subject: [PATCH 3445/4131] Change timer code so it works better when the timing gets off due to the cpu core not stopping at the right moment (patch by h-a-l-9000). Some minor LIKELY stuff Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3534 --- src/hardware/pic.cpp | 37 +++++++++++++++++++++++-------------- src/hardware/timer.cpp | 8 ++------ 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 40b1848e..2d4e7ff4 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -123,7 +123,7 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { irqs[PIC_IRQActive].inservice=false; PIC_IRQActive=PIC_NOIRQ; for (i=0; i<=15; i++){ - if(irqs[IRQ_priority_table[i]].inservice) { + if(GCC_UNLIKELY(irqs[IRQ_priority_table[i]].inservice)) { PIC_IRQActive=IRQ_priority_table[i]; break; } @@ -276,7 +276,7 @@ static inline bool PIC_startIRQ(Bitu i) { if (!pics[pic].auto_eoi) { //irq 0-7 => pic 0 else pic 1 PIC_IRQActive = i; irqs[i].inservice = true; - } else if (pics[pic].rotate_on_auto_eoi) { + } else if (GCC_UNLIKELY(pics[pic].rotate_on_auto_eoi)) { E_Exit("rotate on auto EOI not handled"); } return true; @@ -284,8 +284,8 @@ static inline bool PIC_startIRQ(Bitu i) { void PIC_runIRQs(void) { if (!GETFLAG(IF)) return; - if (!PIC_IRQCheck) return; - if (cpudecoder==CPU_Core_Normal_Trap_Run) return; + if (GCC_UNLIKELY(!PIC_IRQCheck)) return; + if (GCC_UNLIKELY(cpudecoder==CPU_Core_Normal_Trap_Run)) return; static Bitu IRQ_priority_order[16] = { 0,1,2,8,9,10,11,12,13,14,15,3,4,5,6,7 }; @@ -305,7 +305,7 @@ void PIC_runIRQs(void) { for (j = 0; j < Priority_Active_IRQ; j++) { i = IRQ_priority_order[j]; if (!irqs[i].masked && irqs[i].active) { - if(PIC_startIRQ(i)) return; + if(GCC_LIKELY(PIC_startIRQ(i))) return; } } } else { /* Special mode variant */ @@ -355,7 +355,7 @@ void PIC_SetIRQMask(Bitu irq, bool masked) { static void AddEntry(PICEntry * entry) { PICEntry * find_entry=pic_queue.next_entry; - if (!find_entry) { + if (GCC_UNLIKELY(find_entry ==0)) { entry->next=0; pic_queue.next_entry=entry; } else if (find_entry->index>entry->index) { @@ -383,14 +383,18 @@ static void AddEntry(PICEntry * entry) { CPU_Cycles=0; } } +static bool InEventService = false; +static float srv_lag = 0; void PIC_AddEvent(PIC_EventHandler handler,float delay,Bitu val) { - if (!pic_queue.free_entry) { + if (GCC_UNLIKELY(!pic_queue.free_entry)) { LOG(LOG_PIC,LOG_ERROR)("Event queue full"); return; } PICEntry * entry=pic_queue.free_entry; - entry->index=delay+PIC_TickIndex(); + if(InEventService) entry->index = delay + srv_lag; + else entry->index = delay + PIC_TickIndex(); + entry->pic_event=handler; entry->value=val; pic_queue.free_entry=pic_queue.free_entry->next; @@ -402,7 +406,7 @@ void PIC_RemoveSpecificEvents(PIC_EventHandler handler, Bitu val) { PICEntry * prev_entry; prev_entry = 0; while (entry) { - if ((entry->pic_event == handler) && (entry->value == val)) { + if (GCC_UNLIKELY((entry->pic_event == handler)) && (entry->value == val)) { if (prev_entry) { prev_entry->next=entry->next; entry->next=pic_queue.free_entry; @@ -427,7 +431,7 @@ void PIC_RemoveEvents(PIC_EventHandler handler) { PICEntry * prev_entry; prev_entry=0; while (entry) { - if (entry->pic_event==handler) { + if (GCC_UNLIKELY(entry->pic_event==handler)) { if (prev_entry) { prev_entry->next=entry->next; entry->next=pic_queue.free_entry; @@ -457,18 +461,24 @@ bool PIC_RunQueue(void) { } /* Check the queue for an entry */ Bits index_nd=PIC_TickIndexND(); + InEventService = true; while (pic_queue.next_entry && (pic_queue.next_entry->index*CPU_CycleMax<=index_nd)) { PICEntry * entry=pic_queue.next_entry; pic_queue.next_entry=entry->next; - (entry->pic_event)(entry->value); + + srv_lag = entry->index; + (entry->pic_event)(entry->value); // call the event handler + /* Put the entry in the free list */ entry->next=pic_queue.free_entry; pic_queue.free_entry=entry; } + InEventService = false; + /* Check when to set the new cycle end */ if (pic_queue.next_entry) { Bits cycles=(Bits)(pic_queue.next_entry->index*CPU_CycleMax-index_nd); - if (!cycles) cycles=1; + if (GCC_UNLIKELY(!cycles)) cycles=1; if (cyclesindex>=1) entry->index-=1; - else entry->index=0; + entry->index -= 1.0; entry=entry->next; } /* Call our list of ticker handlers */ diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index f94e43c2..c3780a77 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -75,9 +75,7 @@ static void PIT0_Event(Bitu /*val*/) { pit[0].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[0].cntr)); pit[0].update_count=false; } - - double error = pit[0].start - PIC_FullIndex(); - PIC_AddEvent(PIT0_Event,(float)(pit[0].delay + error)); + PIC_AddEvent(PIT0_Event,pit[0].delay); } } @@ -271,9 +269,7 @@ static Bitu read_latch(Bitu port,Bitu /*iolen*/) { break; case 3: /* read LSB followed by MSB */ ret = pit[counter].read_latch & 0xff; - - if (pit[counter].mode & 0x80) pit[counter].mode &= 7; - else pit[counter].read_state = 0; + pit[counter].read_state = 0; break; case 1: /* read LSB */ ret = pit[counter].read_latch & 0xff; From 38c99cbf1238fa20082046558b0687f03ea4f08f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 13 Jan 2010 18:31:21 +0000 Subject: [PATCH 3446/4131] Add more intelligence to the findfirst stored lists cleanup algorithm Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3535 --- include/dos_system.h | 6 +++--- src/dos/drive_cache.cpp | 20 ++++++++++++++------ src/dos/drive_local.cpp | 4 ++-- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index e530cded..6a3fe97e 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -141,8 +141,8 @@ public: char* GetExpandName (const char* path); bool GetShortName (const char* fullname, char* shortname); - bool FindFirst (char* path, Bitu& id); - bool FindNext (Bitu id, char* &result); + bool FindFirst (char* path, Bit16u& id); + bool FindNext (Bit16u id, char* &result); void CacheOut (const char* path, bool ignoreLastDir = false); void AddEntry (const char* path, bool checkExist = false); @@ -205,7 +205,7 @@ private: char dirSearchName [MAX_OPENDIRS]; bool free [MAX_OPENDIRS]; CFileInfo* dirFindFirst [MAX_OPENDIRS]; - Bitu nextFreeFindFirst; + Bit16u nextFreeFindFirst; char label [CROSS_LEN]; bool updatelabel; diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 75f2a2b2..d6800564 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -705,16 +705,24 @@ bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bitu entryNr) } // FindFirst / FindNext -bool DOS_Drive_Cache::FindFirst(char* path, Bitu& id) { +bool DOS_Drive_Cache::FindFirst(char* path, Bit16u& id) { Bit16u dirID; - Bitu dirFindFirstID = this->nextFreeFindFirst; - // Cache directory in if (!OpenDir(path,dirID)) return false; - this->nextFreeFindFirst++; //increase it for the next search + //Find a free slot. + //If the next one isn't free, move on to the next, if none is free => reset and assume the worst + Bit16u local_findcounter = 0; + while ( local_findcounter < MAX_OPENDIRS ) { + if (dirFindFirst[this->nextFreeFindFirst] == 0) break; + if (++this->nextFreeFindFirst >= MAX_OPENDIRS) this->nextFreeFindFirst = 0; //Wrap around + local_findcounter++; + } - if (dirFindFirstID == MAX_OPENDIRS) { + Bit16u dirFindFirstID = this->nextFreeFindFirst++; + if (this->nextFreeFindFirst >= MAX_OPENDIRS) this->nextFreeFindFirst = 0; //Increase and wrap around for the next search. + + if (local_findcounter == MAX_OPENDIRS) { //Here is the reset from above. // no free slot found... LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst/Next: All slots full. Resetting"); // Clear the internal list then. @@ -749,7 +757,7 @@ bool DOS_Drive_Cache::FindFirst(char* path, Bitu& id) { return true; } -bool DOS_Drive_Cache::FindNext(Bitu id, char* &result) { +bool DOS_Drive_Cache::FindNext(Bit16u id, char* &result) { // out of range ? if ((id>=MAX_OPENDIRS) || !dirFindFirst[id]) { LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst/Next failure : ID out of range: %04X",id); diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 15dee47f..dc4fc28b 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -188,7 +188,7 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) { char end[2]={CROSS_FILESPLIT,0}; if (tempDir[strlen(tempDir)-1]!=CROSS_FILESPLIT) strcat(tempDir,end); - Bitu id; + Bit16u id; if (!dirCache.FindFirst(tempDir,id)) { DOS_SetError(DOSERR_PATH_NOT_FOUND); return false; @@ -239,7 +239,7 @@ bool localDrive::FindNext(DOS_DTA & dta) { Bit8u find_attr; dta.GetSearchParams(srch_attr,srch_pattern); - Bitu id = dta.GetDirID(); + Bit16u id = dta.GetDirID(); again: if (!dirCache.FindNext(id,dir_ent)) { From a367caf515501d56874f43978161b3a392046e3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 17 Jan 2010 22:17:50 +0000 Subject: [PATCH 3447/4131] correct some mscdex return codes (thanks to ripsaw for pointing to this; fixes Alpha Storm) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3536 --- src/dos/dos_mscdex.cpp | 101 ++++++++++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 37 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index e8908b1c..65ab123c 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 @@ -39,6 +39,7 @@ #define MSCDEX_MAX_DRIVES 8 // Error Codes +#define MSCDEX_ERROR_INVALID_FUNCTION 1 #define MSCDEX_ERROR_BAD_FORMAT 11 #define MSCDEX_ERROR_UNKNOWN_DRIVE 15 #define MSCDEX_ERROR_DRIVE_NOT_READY 21 @@ -339,7 +340,7 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) // Create Callback Strategy Bit16u off = sizeof(DOS_DeviceHeader::sDeviceHeader); - Bitu call_strategy=CALLBACK_Allocate(); + Bit16u call_strategy=(Bit16u)CALLBACK_Allocate(); CallBack_Handlers[call_strategy]=MSCDEX_Strategy_Handler; real_writeb(seg,off+0,(Bit8u)0xFE); //GRP 4 real_writeb(seg,off+1,(Bit8u)0x38); //Extra Callback instruction @@ -349,7 +350,7 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) // Create Callback Interrupt off += 5; - Bitu call_interrupt=CALLBACK_Allocate(); + Bit16u call_interrupt=(Bit16u)CALLBACK_Allocate(); CallBack_Handlers[call_interrupt]=MSCDEX_Interrupt_Handler; real_writeb(seg,off+0,(Bit8u)0xFE); //GRP 4 real_writeb(seg,off+1,(Bit8u)0x38); //Extra Callback instruction @@ -380,10 +381,10 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) } cdrom[0] = _cdrom; dinfo[0].drive = (Bit8u)_drive; - dinfo[0].physDrive = toupper(physicalPath[0]); + dinfo[0].physDrive = (Bit8u)toupper(physicalPath[0]); } else { dinfo[numDrives].drive = (Bit8u)_drive; - dinfo[numDrives].physDrive = toupper(physicalPath[0]); + dinfo[numDrives].physDrive = (Bit8u)toupper(physicalPath[0]); } numDrives++; // stop audio @@ -541,14 +542,12 @@ bool CMscdex::StopAudio(Bit8u subUnit) return dinfo[subUnit].lastResult; } -bool CMscdex::ResumeAudio(Bit8u subUnit) -{ +bool CMscdex::ResumeAudio(Bit8u subUnit) { if (subUnit>=numDrives) return false; return dinfo[subUnit].lastResult = PlayAudioSector(subUnit,dinfo[subUnit].audioStart,dinfo[subUnit].audioEnd); } -Bit32u CMscdex::GetVolumeSize(Bit8u subUnit) -{ +Bit32u CMscdex::GetVolumeSize(Bit8u subUnit) { if (subUnit>=numDrives) return false; Bit8u tr1,tr2; TMSF leadOut; @@ -557,21 +556,25 @@ Bit32u CMscdex::GetVolumeSize(Bit8u subUnit) return 0; } -bool CMscdex::ReadVTOC(Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error) -{ - if (!ReadSectors(GetSubUnit(drive),false,16+volume,1,data)) { - error=MSCDEX_ERROR_DRIVE_NOT_READY; - return false; - } - char id[5]; - MEM_BlockRead(data + 1, id, 5); - if (strncmp("CD001",id, 5)!=0) { - error = MSCDEX_ERROR_BAD_FORMAT; - return false; - } - Bit8u type = mem_readb(data); - error = (type == 1) ? 1 : (type == 0xFF) ? 0xFF : 0; - return true; +bool CMscdex::ReadVTOC(Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error) { + Bit8u subunit = GetSubUnit(drive); +/* if (subunit>=numDrives) { + error=MSCDEX_ERROR_UNKNOWN_DRIVE; + return false; + } */ + if (!ReadSectors(subunit,false,16+volume,1,data)) { + error=MSCDEX_ERROR_DRIVE_NOT_READY; + return false; + } + char id[5]; + MEM_BlockRead(data + 1, id, 5); + if (strncmp("CD001",id, 5)!=0) { + error = MSCDEX_ERROR_BAD_FORMAT; + return false; + } + Bit8u type = mem_readb(data); + error = (type == 1) ? 1 : (type == 0xFF) ? 0xFF : 0; + return true; } bool CMscdex::GetVolumeName(Bit8u subUnit, char* data) { @@ -1104,7 +1107,7 @@ static bool MSCDEX_Handler(void) { if (mscdex->GetCopyrightName(reg_cx,data)) { CALLBACK_SCF(false); } else { - reg_al = MSCDEX_ERROR_UNKNOWN_DRIVE; + reg_ax = MSCDEX_ERROR_UNKNOWN_DRIVE; CALLBACK_SCF(true); }; return true; @@ -1112,7 +1115,7 @@ static bool MSCDEX_Handler(void) { if (mscdex->GetAbstractName(reg_cx,data)) { CALLBACK_SCF(false); } else { - reg_al = MSCDEX_ERROR_UNKNOWN_DRIVE; + reg_ax = MSCDEX_ERROR_UNKNOWN_DRIVE; CALLBACK_SCF(true); }; return true; @@ -1120,13 +1123,14 @@ static bool MSCDEX_Handler(void) { if (mscdex->GetDocumentationName(reg_cx,data)) { CALLBACK_SCF(false); } else { - reg_al = MSCDEX_ERROR_UNKNOWN_DRIVE; + reg_ax = MSCDEX_ERROR_UNKNOWN_DRIVE; CALLBACK_SCF(true); }; return true; case 0x1505: { // read vtoc Bit16u error = 0; if (mscdex->ReadVTOC(reg_cx,reg_dx,data,error)) { +// reg_ax = error; // return code CALLBACK_SCF(false); } else { reg_ax = error; @@ -1137,19 +1141,21 @@ static bool MSCDEX_Handler(void) { case 0x1508: { // read sectors Bit32u sector = (reg_si<<16)+reg_di; if (mscdex->ReadSectors(reg_cx,sector,reg_dx,data)) { + reg_ax = 0; CALLBACK_SCF(false); } else { - reg_al = MSCDEX_ERROR_UNKNOWN_DRIVE; + // possibly: MSCDEX_ERROR_DRIVE_NOT_READY if sector is beyond total length + reg_ax = MSCDEX_ERROR_UNKNOWN_DRIVE; CALLBACK_SCF(true); }; return true; }; case 0x1509: // write sectors - not supported - reg_al = MSCDEX_ERROR_DRIVE_NOT_READY; + reg_ax = MSCDEX_ERROR_INVALID_FUNCTION; CALLBACK_SCF(true); return true; case 0x150B: /* Valid CDROM drive ? */ - reg_ax = mscdex->IsValidDrive(reg_cx); + reg_ax = (mscdex->IsValidDrive(reg_cx) ? 0x5ad8 : 0x0000); reg_bx = 0xADAD; return true; case 0x150C: /* Get MSCDEX Version */ @@ -1158,6 +1164,30 @@ static bool MSCDEX_Handler(void) { case 0x150D: /* Get drives */ mscdex->GetDrives(data); return true; + case 0x150E: /* Get/Set Volume Descriptor Preference */ + if (mscdex->IsValidDrive(reg_cx)) { + if (reg_bx == 0) { + // get preference + reg_dx = 0x100; // preference? + CALLBACK_SCF(false); + } else if (reg_bx == 1) { + // set preference + if (reg_dh == 1) { + // valid + CALLBACK_SCF(false); + } else { + reg_ax = MSCDEX_ERROR_INVALID_FUNCTION; + CALLBACK_SCF(true); + } + } else { + reg_ax = MSCDEX_ERROR_INVALID_FUNCTION; + CALLBACK_SCF(true); + } + } else { + reg_ax = MSCDEX_ERROR_UNKNOWN_DRIVE; + CALLBACK_SCF(true); + } + return true; case 0x150F: { // Get directory entry Bit16u error; bool success = mscdex->GetDirectoryEntry(reg_cl,reg_ch&1,data,PhysMake(reg_si,reg_di),error); @@ -1168,7 +1198,7 @@ static bool MSCDEX_Handler(void) { if (mscdex->SendDriverRequest(reg_cx,data)) { CALLBACK_SCF(false); } else { - reg_ax = 0x0f; // invalid drive + reg_ax = MSCDEX_ERROR_UNKNOWN_DRIVE; CALLBACK_SCF(true); } return true; @@ -1261,21 +1291,18 @@ bool MSCDEX_HasMediaChanged(Bit8u subUnit) return true; } -void MSCDEX_SetCDInterface(int intNr, int numCD) -{ +void MSCDEX_SetCDInterface(int intNr, int numCD) { useCdromInterface = intNr; forceCD = numCD; } -void MSCDEX_ShutDown(Section* sec) -{ +void MSCDEX_ShutDown(Section* /*sec*/) { delete mscdex; mscdex = 0; curReqheaderPtr = 0; } -void MSCDEX_Init(Section* sec) -{ +void MSCDEX_Init(Section* sec) { // AddDestroy func sec->AddDestroyFunction(&MSCDEX_ShutDown); /* Register the mscdex device */ From 30dbcb9156612495b9448d1df7e1615eff3f1174 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 Jan 2010 10:39:10 +0000 Subject: [PATCH 3448/4131] Remove suggestion to mount windows as directory. Update the message a bit. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3537 --- src/dos/dos_programs.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 537553fc..f61b516f 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -321,7 +321,11 @@ public: } return; showusage: - WriteOut(MSG_Get("PROGRAM_MOUNT_USAGE")); +#if defined (WIN32) || defined(OS2) + WriteOut(MSG_Get("PROGRAM_MOUNT_USAGE"),"d:\\dosprogs","d:\\dosprogs"); +#else + WriteOut(MSG_Get("PROGRAM_MOUNT_USAGE"),"~/dosprogs","~/dosprogs"); +#endif return; } }; @@ -1346,7 +1350,11 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_MOUNT_ERROR_2","%s isn't a directory\n"); MSG_Add("PROGRAM_MOUNT_ILL_TYPE","Illegal type %s\n"); MSG_Add("PROGRAM_MOUNT_ALREADY_MOUNTED","Drive %c already mounted with %s\n"); - MSG_Add("PROGRAM_MOUNT_USAGE","Usage \033[34;1mMOUNT Drive-Letter Local-Directory\033[0m\nSo a MOUNT c c:\\windows mounts windows directory as the c: drive in DOSBox\n"); + MSG_Add("PROGRAM_MOUNT_USAGE", + "Usage \033[34;1mMOUNT Drive-Letter Local-Directory\033[0m\n" + "For example: MOUNT c %s\n" + "This makes the directory %s act as the C: drive inside DOSBox.\n" + "The directory has to exist.\n"); MSG_Add("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED","Drive %c isn't mounted.\n"); MSG_Add("PROGRAM_MOUNT_UMOUNT_SUCCESS","Drive %c has successfully been removed.\n"); MSG_Add("PROGRAM_MOUNT_UMOUNT_NO_VIRTUAL","Virtual Drives can not be unMOUNTed.\n"); From 5135399271eb2716a9665790a83d42d4ccc10de9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 Jan 2010 18:23:09 +0000 Subject: [PATCH 3449/4131] Some userfriendly changes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3538 --- src/shell/shell_cmds.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 621b5209..0dccb9cd 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -32,37 +32,37 @@ #include static SHELL_Cmd cmd_list[]={ +{ "DIR", 0, &DOS_Shell::CMD_DIR, "SHELL_CMD_DIR_HELP"}, { "CHDIR", 1, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"}, +{ "ATTRIB", 1, &DOS_Shell::CMD_ATTRIB, "SHELL_CMD_ATTRIB_HELP"}, +{ "CALL", 1, &DOS_Shell::CMD_CALL, "SHELL_CMD_CALL_HELP"}, { "CD", 0, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"}, +{ "CHOICE", 1, &DOS_Shell::CMD_CHOICE, "SHELL_CMD_CHOICE_HELP"}, { "CLS", 0, &DOS_Shell::CMD_CLS, "SHELL_CMD_CLS_HELP"}, { "COPY", 0, &DOS_Shell::CMD_COPY, "SHELL_CMD_COPY_HELP"}, -{ "DIR", 0, &DOS_Shell::CMD_DIR, "SHELL_CMD_DIR_HELP"}, { "DEL", 0, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, { "DELETE", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, { "ERASE", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, { "ECHO", 1, &DOS_Shell::CMD_ECHO, "SHELL_CMD_ECHO_HELP"}, { "EXIT", 0, &DOS_Shell::CMD_EXIT, "SHELL_CMD_EXIT_HELP"}, +{ "GOTO", 1, &DOS_Shell::CMD_GOTO, "SHELL_CMD_GOTO_HELP"}, { "HELP", 1, &DOS_Shell::CMD_HELP, "SHELL_CMD_HELP_HELP"}, +{ "IF", 1, &DOS_Shell::CMD_IF, "SHELL_CMD_IF_HELP"}, +{ "LOADHIGH", 1, &DOS_Shell::CMD_LOADHIGH, "SHELL_CMD_LOADHIGH_HELP"}, +{ "LH", 1, &DOS_Shell::CMD_LOADHIGH, "SHELL_CMD_LOADHIGH_HELP"}, { "MKDIR", 1, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP"}, { "MD", 0, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP"}, +{ "PATH", 1, &DOS_Shell::CMD_PATH, "SHELL_CMD_PATH_HELP"}, +{ "PAUSE", 1, &DOS_Shell::CMD_PAUSE, "SHELL_CMD_PAUSE_HELP"}, { "RMDIR", 1, &DOS_Shell::CMD_RMDIR, "SHELL_CMD_RMDIR_HELP"}, { "RD", 0, &DOS_Shell::CMD_RMDIR, "SHELL_CMD_RMDIR_HELP"}, -{ "SET", 1, &DOS_Shell::CMD_SET, "SHELL_CMD_SET_HELP"}, -{ "IF", 1, &DOS_Shell::CMD_IF, "SHELL_CMD_IF_HELP"}, -{ "GOTO", 1, &DOS_Shell::CMD_GOTO, "SHELL_CMD_GOTO_HELP"}, -{ "SHIFT", 1, &DOS_Shell::CMD_SHIFT, "SHELL_CMD_SHIFT_HELP"}, -{ "TYPE", 0, &DOS_Shell::CMD_TYPE, "SHELL_CMD_TYPE_HELP"}, { "REM", 1, &DOS_Shell::CMD_REM, "SHELL_CMD_REM_HELP"}, { "RENAME", 1, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP"}, { "REN", 0, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP"}, -{ "PAUSE", 1, &DOS_Shell::CMD_PAUSE, "SHELL_CMD_PAUSE_HELP"}, -{ "CALL", 1, &DOS_Shell::CMD_CALL, "SHELL_CMD_CALL_HELP"}, +{ "SET", 1, &DOS_Shell::CMD_SET, "SHELL_CMD_SET_HELP"}, +{ "SHIFT", 1, &DOS_Shell::CMD_SHIFT, "SHELL_CMD_SHIFT_HELP"}, { "SUBST", 1, &DOS_Shell::CMD_SUBST, "SHELL_CMD_SUBST_HELP"}, -{ "LOADHIGH", 0, &DOS_Shell::CMD_LOADHIGH, "SHELL_CMD_LOADHIGH_HELP"}, -{ "LH", 1, &DOS_Shell::CMD_LOADHIGH, "SHELL_CMD_LOADHIGH_HELP"}, -{ "CHOICE", 0, &DOS_Shell::CMD_CHOICE, "SHELL_CMD_CHOICE_HELP"}, -{ "ATTRIB", 1, &DOS_Shell::CMD_ATTRIB, "SHELL_CMD_ATTRIB_HELP"}, -{ "PATH", 1, &DOS_Shell::CMD_PATH, "SHELL_CMD_PATH_HELP"}, +{ "TYPE", 0, &DOS_Shell::CMD_TYPE, "SHELL_CMD_TYPE_HELP"}, { "VER", 0, &DOS_Shell::CMD_VER, "SHELL_CMD_VER_HELP"}, {0,0,0,0} }; From 91f1754ed9d2cc2d392a91f58186e7ee3c587fa9 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Mon, 25 Jan 2010 19:55:28 +0000 Subject: [PATCH 3450/4131] Clarify that the serial port irq parameter is optional. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3539 --- src/dosbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 672f5546..e385f228 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -610,7 +610,7 @@ void DOSBOX_Init(void) { "set type of device connected to com port.\n" "Can be disabled, dummy, modem, nullmodem, directserial.\n" "Additional parameters must be in the same line in the form of\n" - "parameter:value. Parameter for all types is irq.\n" + "parameter:value. Parameter for all types is irq (optional).\n" "for directserial: realport (required), rxdelay (optional).\n" " (realport:COM1 realport:ttyS0).\n" "for modem: listenport (optional).\n" From fd3cbd10da5b4e6d9f7c430b85fc8a4e9e455f7b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 31 Jan 2010 13:50:42 +0000 Subject: [PATCH 3451/4131] Close filehandle in cas of not enough memory. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3540 --- src/dos/dos_execute.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index d660d539..8db998c3 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -331,6 +331,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { if (dataread<0xf800) minsize=((dataread+0x10)>>4)+0x20; } if (maxfree Date: Sun, 31 Jan 2010 15:02:41 +0000 Subject: [PATCH 3452/4131] Add basic granularity support. (ripsaw, rc1) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3541 --- src/ints/mouse.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 8ea01c71..4cfe2d09 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -51,7 +51,7 @@ struct button_event { #define QUEUE_SIZE 32 #define MOUSE_BUTTONS 3 #define MOUSE_IRQ 12 -#define POS_X (Bit16s)(mouse.x) +#define POS_X ((Bit16s)(mouse.x) & mouse.granMask) #define POS_Y (Bit16s)(mouse.y) #define CURSORX 16 @@ -126,6 +126,7 @@ static struct { bool timer_in_progress; bool in_UIR; Bit8u mode; + Bit16s granMask; } mouse; bool Mouse_SetPS2State(bool use) { @@ -626,6 +627,7 @@ void Mouse_NewVideoMode(void) { mouse.max_x = 639; mouse.min_x = 0; mouse.min_y = 0; + mouse.granMask = (mode == 0x0d || mode == 0x13) ? 0xfffe : 0xffff; mouse.events = 0; mouse.timer_in_progress = false; From 00463f8285ce6186b0e5af5cf1a5585a2e62d5c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 1 Feb 2010 22:28:53 +0000 Subject: [PATCH 3453/4131] fix some error message when loading some unhandled keyboard layout combinations Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3542 --- src/dos/dos_keyboard_layout.cpp | 9 +++++---- src/dos/dos_programs.cpp | 13 ++++++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 661ca88c..950867a1 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -80,7 +80,7 @@ public: // call layout_key to apply the current language layout bool layout_key(Bitu key, Bit8u flags1, Bit8u flags2, Bit8u flags3); - Bitu switch_keyboard_layout(const char* new_layout, keyboard_layout* &created_layout); + Bitu switch_keyboard_layout(const char* new_layout, keyboard_layout* &created_layout, Bit32s& tried_cp); void switch_foreign_layout(); const char* get_layout_name(); const char* main_language_code(); @@ -951,7 +951,7 @@ Bitu keyboard_layout::read_codepage_file(const char* codepage_file_name, Bit32s return KEYB_INVALIDCPFILE; } -Bitu keyboard_layout::switch_keyboard_layout(const char* new_layout, keyboard_layout*& created_layout) { +Bitu keyboard_layout::switch_keyboard_layout(const char* new_layout, keyboard_layout*& created_layout, Bit32s& tried_cp) { if (strncasecmp(new_layout,"US",2)) { // switch to a foreign layout char tbuf[256]; @@ -977,6 +977,7 @@ Bitu keyboard_layout::switch_keyboard_layout(const char* new_layout, keyboard_la } else { keyboard_layout * temp_layout=new keyboard_layout(); Bitu req_codepage=temp_layout->extract_codepage(new_layout); + tried_cp = req_codepage; Bitu kerrcode=temp_layout->read_keyboard_file(new_layout, req_codepage); if (kerrcode) { delete temp_layout; @@ -1059,10 +1060,10 @@ Bitu DOS_LoadKeyboardLayout(const char * layoutname, Bit32s codepage, const char return KEYB_NOERROR; } -Bitu DOS_SwitchKeyboardLayout(const char* new_layout) { +Bitu DOS_SwitchKeyboardLayout(const char* new_layout, Bit32s& tried_cp) { if (loaded_layout) { keyboard_layout* changed_layout=NULL; - Bitu ret_code=loaded_layout->switch_keyboard_layout(new_layout, changed_layout); + Bitu ret_code=loaded_layout->switch_keyboard_layout(new_layout, changed_layout, tried_cp); if (changed_layout) { // Remove old layout, activate new layout delete loaded_layout; diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index f61b516f..816d4f0b 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1270,7 +1270,7 @@ void IMGMOUNT_ProgramStart(Program * * make) { } -Bitu DOS_SwitchKeyboardLayout(const char* new_layout); +Bitu DOS_SwitchKeyboardLayout(const char* new_layout, Bit32s& tried_cp); Bitu DOS_LoadKeyboardLayout(const char * layoutname, Bit32s codepage, const char * codepagefile); const char* DOS_GetLoadedLayout(void); @@ -1287,9 +1287,10 @@ void KEYB::Run(void) { /* first parameter is layout ID */ Bitu keyb_error=0; std::string cp_string; + Bit32s tried_cp = -1; if (cmd->FindCommand(2,cp_string)) { /* second parameter is codepage number */ - Bit32s par_cp=atoi(cp_string.c_str()); + tried_cp=atoi(cp_string.c_str()); char cp_file_name[256]; if (cmd->FindCommand(3,cp_string)) { /* third parameter is codepage file */ @@ -1299,8 +1300,10 @@ void KEYB::Run(void) { strcpy(cp_file_name, "auto"); } - keyb_error=DOS_LoadKeyboardLayout(temp_line.c_str(), par_cp, cp_file_name); - } else keyb_error=DOS_SwitchKeyboardLayout(temp_line.c_str()); + keyb_error=DOS_LoadKeyboardLayout(temp_line.c_str(), tried_cp, cp_file_name); + } else { + keyb_error=DOS_SwitchKeyboardLayout(temp_line.c_str(), tried_cp); + } switch (keyb_error) { case KEYB_NOERROR: WriteOut(MSG_Get("PROGRAM_KEYB_NOERROR"),temp_line.c_str(),dos.loaded_codepage); @@ -1313,7 +1316,7 @@ void KEYB::Run(void) { WriteOut(MSG_Get("PROGRAM_KEYB_INVALIDFILE"),temp_line.c_str()); break; case KEYB_LAYOUTNOTFOUND: - WriteOut(MSG_Get("PROGRAM_KEYB_LAYOUTNOTFOUND"),temp_line.c_str(),dos.loaded_codepage); + WriteOut(MSG_Get("PROGRAM_KEYB_LAYOUTNOTFOUND"),temp_line.c_str(),tried_cp); break; case KEYB_INVALIDCPFILE: WriteOut(MSG_Get("PROGRAM_KEYB_INVCPFILE"),temp_line.c_str()); From 84dbcce5d53242583b9f60e670a305d8fb0459ad Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 5 Feb 2010 08:37:17 +0000 Subject: [PATCH 3454/4131] No . or .. in root dir for isos.(GT Racing 97) (ripsaw,rc1) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3543 --- src/dos/drive_iso.cpp | 10 +++++++--- src/dos/drives.h | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 4135d734..bfcdd6f2 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -246,7 +246,10 @@ bool isoDrive::FindFirst(char *dir, DOS_DTA &dta, bool fcb_findfirst) { } // get a directory iterator and save its id in the dta - dta.SetDirID((Bit16u)GetDirIterator(&de)); + int dirIterator = GetDirIterator(&de); + bool isRoot = (*dir == 0); + dirIterators[dirIterator].root = isRoot; + dta.SetDirID((Bit16u)dirIterator); Bit8u attr; char pattern[ISO_MAXPATHNAME]; @@ -260,7 +263,7 @@ bool isoDrive::FindFirst(char *dir, DOS_DTA &dta, bool fcb_findfirst) { DOS_SetError(DOSERR_NO_MORE_FILES); return false; } - } else if ((attr & DOS_ATTR_VOLUME) && (*dir == 0) && !fcb_findfirst) { + } else if ((attr & DOS_ATTR_VOLUME) && isRoot && !fcb_findfirst) { if (WildFileCmp(discLabel,pattern)) { // Get Volume Label (DOS_ATTR_VOLUME) and only in basedir and if it matches the searchstring dta.SetResult(discLabel, 0, 0, 0, DOS_ATTR_VOLUME); @@ -277,6 +280,7 @@ bool isoDrive::FindNext(DOS_DTA &dta) { dta.GetSearchParams(attr, pattern); int dirIterator = dta.GetDirID(); + bool isRoot = dirIterators[dirIterator].root; isoDirEntry de; while (GetNextDirEntry(dirIterator, &de)) { @@ -285,7 +289,7 @@ bool isoDrive::FindNext(DOS_DTA &dta) { else findAttr |= DOS_ATTR_ARCHIVE; if (IS_HIDDEN(de.fileFlags)) findAttr |= DOS_ATTR_HIDDEN; - if (WildFileCmp((char*)de.ident, pattern) + if (!(isRoot && de.ident[0]=='.') && WildFileCmp((char*)de.ident, pattern) && !(~attr & findAttr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM))) { /* file is okay, setup everything to be copied in DTA Block */ diff --git a/src/dos/drives.h b/src/dos/drives.h index 3a544872..f6198c56 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -345,6 +345,7 @@ private: struct DirIterator { bool valid; + bool root; Bit32u currentSector; Bit32u endSector; Bit32u pos; From d42127638b4f437a0dc65a11bf20083ae9e775f4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 6 Feb 2010 08:35:28 +0000 Subject: [PATCH 3455/4131] Allow redirection of the form what ctemp used in sierra installers. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3544 --- src/shell/shell.cpp | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 1fccbd51..f010c7f5 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -143,6 +143,7 @@ Bitu DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn,bool * append) { char ch; Bitu num=0; bool quote = false; + char* t; while ( (ch=*lr++) ) { if(quote && ch != '"') { /* don't parse redirection within quotes. Not perfect yet. Escaped quotes will mess the count up */ @@ -160,26 +161,30 @@ Bitu DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn,bool * append) { lr=ltrim(lr); if (*ofn) free(*ofn); *ofn=lr; - while (*lr && *lr!=' ') lr++; + while (*lr && *lr!=' ' && *lr!='<' && *lr!='|') lr++; //if it ends on a : => remove it. if((*ofn != lr) && (lr[-1] == ':')) lr[-1] = 0; - if(*lr && *(lr+1)) - *lr++=0; - else - *lr=0; - *ofn=strdup(*ofn); +// if(*lr && *(lr+1)) +// *lr++=0; +// else +// *lr=0; + t = (char*)malloc(lr-*ofn+1); + safe_strncpy(t,*ofn,lr-*ofn+1); + *ofn=t; continue; case '<': if (*ifn) free(*ifn); lr=ltrim(lr); *ifn=lr; - while (*lr && *lr!=' ') lr++; + while (*lr && *lr!=' ' && *lr!='>' && *lr != '|') lr++; if((*ifn != lr) && (lr[-1] == ':')) lr[-1] = 0; - if(*lr && *(lr+1)) - *lr++=0; - else - *lr=0; - *ifn=strdup(*ifn); +// if(*lr && *(lr+1)) +// *lr++=0; +// else +// *lr=0; + t = (char*)malloc(lr-*ifn+1); + safe_strncpy(t,*ifn,lr-*ifn+1); + *ifn=t; continue; case '|': ch=0; From be08175077aaceb5da4de883d203bb6e431894c1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 8 Feb 2010 17:05:14 +0000 Subject: [PATCH 3456/4131] Fix ren dir\source target (we stayed in dir instead of returning). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3545 --- src/shell/shell_cmds.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 0dccb9cd..7f47f2c1 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -248,8 +248,9 @@ void DOS_Shell::CMD_RENAME(char * args){ if((strlen(dir_source) == 2) && (dir_source[1] == ':')) strcat(dir_source,"\\"); //X: add slash - char dir_current[DOS_PATHLENGTH]; - DOS_GetCurrentDir(0,dir_current); + char dir_current[DOS_PATHLENGTH + 1]; + dir_current[0] = '\\'; //Absolute addressing so we can return properly + DOS_GetCurrentDir(0,dir_current + 1); if(!DOS_ChangeDir(dir_source)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); return; From e4666d2bafa14ac3523fa86d1ce8e0e4be1392b6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Feb 2010 20:33:31 +0000 Subject: [PATCH 3457/4131] basic SDL 1.2.14 support.(Still testing) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3546 --- src/gui/sdlmain.cpp | 4 +++- src/ints/bios_keyboard.cpp | 13 +++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index d60fe0cc..b2c0300e 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1717,7 +1717,9 @@ int main(int argc, char* argv[]) { LOG_MSG("---"); /* Init SDL */ - putenv(const_cast("SDL_DISABLE_LOCK_KEYS=1")); //Workaround debian/ubuntu fixes for SDL. +#if SDL_VERSION_ATLEAST(1, 2, 14) + putenv(const_cast("SDL_DISABLE_LOCK_KEYS=1")); +#endif if ( SDL_Init( SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM |SDL_INIT_NOPARACHUTE ) < 0 ) E_Exit("Can't init SDL %s",SDL_GetError()); diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index e26c11a2..ef56885b 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -26,11 +26,14 @@ #include "regs.h" #include "inout.h" #include "dos_inc.h" +#include "SDL.h" /* SDL by default treats numlock and scrolllock different from all other keys. - * Some linux distros disable this bad behaviour. (for example debian) + * In recent versions this can disabled by a environment variable which we set in sdlmain.cpp * Define the following if this is the case */ -//#define CAN_USE_LOCK 1 +#if SDL_VERSION_ATLEAST(1, 2, 14) +#define CAN_USE_LOCK 1 +#endif static Bitu call_int16,call_irq1,call_irq6; @@ -243,6 +246,7 @@ static Bitu IRQ1_Handler(void) { flags2&=~(0x40+0x20);//remove numlock/capslock pressed (hack for sdl only reporting states) #endif if (DOS_LayoutKey(scancode,flags1,flags2,flags3)) return CBRET_NONE; +LOG_MSG("key input %d %d %d %d",scancode,flags1,flags2,flags3); switch (scancode) { /* First the hard ones */ case 0xfa: /* ack. Do nothing for now */ @@ -588,8 +592,9 @@ static void InitBiosSegment(void) { mem_writew(BIOS_KEYBOARD_BUFFER_TAIL,0x1e); Bit8u flag1 = 0; Bit8u leds = 16; /* Ack recieved */ - if(startup_state_capslock) { flag1|=0x40; leds|=0x04;} - if(startup_state_numlock){ flag1|=0x20; leds|=0x02;} +//MAPPER_Init takes care of this now ? +// if(startup_state_capslock) { flag1|=0x40; leds|=0x04;} +// if(startup_state_numlock){ flag1|=0x20; leds|=0x02;} mem_writeb(BIOS_KEYBOARD_FLAGS1,flag1); mem_writeb(BIOS_KEYBOARD_FLAGS2,0); mem_writeb(BIOS_KEYBOARD_FLAGS3,16); /* Enhanced keyboard installed */ From edd52b4b2865457a47a37465dde4e150879c5c14 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Wed, 10 Feb 2010 22:43:01 +0000 Subject: [PATCH 3458/4131] Return the last byte from the serial FIFO buffer in case it is empty, not an unrelated one. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3547 --- include/serialport.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/serialport.h b/include/serialport.h index 5879a444..64476e1b 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -100,8 +100,9 @@ public: Bit8u getb() { if (!used) return data[pos]; Bitu where=pos; - if (++pos>=size) pos-=size; used--; + if(used) pos++; + if (pos>=size) pos-=size; return data[where]; } Bit8u getTop() { From a78b2c4f8b87c89ab7dbf1d53f34b276f77d098e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 11 Feb 2010 13:36:50 +0000 Subject: [PATCH 3459/4131] Update year Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3548 --- acinclude.m4 | 2 +- include/bios.h | 2 +- include/bios_disk.h | 2 +- include/callback.h | 2 +- include/control.h | 2 +- include/cpu.h | 2 +- include/cross.h | 2 +- include/debug.h | 2 +- include/dma.h | 2 +- include/dos_inc.h | 2 +- include/dos_system.h | 2 +- include/dosbox.h | 2 +- include/fpu.h | 2 +- include/hardware.h | 2 +- include/inout.h | 2 +- include/ipx.h | 2 +- include/ipxserver.h | 2 +- include/joystick.h | 2 +- include/keyboard.h | 2 +- include/mapper.h | 2 +- include/mem.h | 2 +- include/mixer.h | 2 +- include/mouse.h | 2 +- include/paging.h | 2 +- include/pic.h | 2 +- include/programs.h | 2 +- include/regs.h | 2 +- include/render.h | 2 +- include/serialport.h | 2 +- include/setup.h | 2 +- include/shell.h | 2 +- include/support.h | 2 +- include/timer.h | 2 +- include/vga.h | 2 +- include/video.h | 2 +- src/cpu/callback.cpp | 2 +- src/cpu/core_dyn_x86.cpp | 2 +- src/cpu/core_dyn_x86/cache.h | 2 +- src/cpu/core_dyn_x86/decoder.h | 2 +- src/cpu/core_dyn_x86/dyn_fpu.h | 2 +- src/cpu/core_dyn_x86/dyn_fpu_dh.h | 2 +- src/cpu/core_dyn_x86/risc_x86.h | 2 +- src/cpu/core_dyn_x86/string.h | 2 +- src/cpu/core_dynrec.cpp | 2 +- src/cpu/core_dynrec/cache.h | 2 +- src/cpu/core_dynrec/decoder.h | 2 +- src/cpu/core_dynrec/decoder_basic.h | 2 +- src/cpu/core_dynrec/decoder_opcodes.h | 2 +- src/cpu/core_dynrec/dyn_fpu.h | 2 +- src/cpu/core_dynrec/operators.h | 2 +- src/cpu/core_dynrec/risc_armv4le-common.h | 2 +- src/cpu/core_dynrec/risc_armv4le-o3.h | 2 +- src/cpu/core_dynrec/risc_armv4le-s3.h | 2 +- src/cpu/core_dynrec/risc_armv4le-thumb-iw.h | 2 +- src/cpu/core_dynrec/risc_armv4le-thumb-niw.h | 2 +- src/cpu/core_dynrec/risc_armv4le-thumb.h | 2 +- src/cpu/core_dynrec/risc_armv4le.h | 2 +- src/cpu/core_dynrec/risc_mipsel32.h | 2 +- src/cpu/core_dynrec/risc_x64.h | 2 +- src/cpu/core_dynrec/risc_x86.h | 2 +- src/cpu/core_full.cpp | 2 +- src/cpu/core_normal.cpp | 2 +- src/cpu/core_normal/helpers.h | 2 +- src/cpu/core_normal/prefix_0f.h | 2 +- src/cpu/core_normal/prefix_66.h | 2 +- src/cpu/core_normal/prefix_66_0f.h | 2 +- src/cpu/core_normal/prefix_none.h | 2 +- src/cpu/core_normal/support.h | 2 +- src/cpu/core_normal/table_ea.h | 2 +- src/cpu/core_prefetch.cpp | 2 +- src/cpu/core_simple.cpp | 2 +- src/cpu/cpu.cpp | 2 +- src/cpu/flags.cpp | 2 +- src/cpu/instructions.h | 2 +- src/cpu/lazyflags.h | 2 +- src/cpu/modrm.cpp | 2 +- src/cpu/modrm.h | 2 +- src/cpu/paging.cpp | 2 +- src/debug/debug.cpp | 2 +- src/debug/debug_gui.cpp | 2 +- src/debug/debug_inc.h | 2 +- src/debug/debug_win32.cpp | 2 +- src/debug/disasm_tables.h | 2 +- src/dos/cdrom.cpp | 2 +- src/dos/cdrom_aspi_win32.cpp | 2 +- src/dos/cdrom_image.cpp | 2 +- src/dos/cdrom_ioctl_linux.cpp | 2 +- src/dos/cdrom_ioctl_os2.cpp | 2 +- src/dos/cdrom_ioctl_win32.cpp | 2 +- src/dos/dev_con.h | 2 +- src/dos/dos.cpp | 2 +- src/dos/dos_classes.cpp | 2 +- src/dos/dos_devices.cpp | 2 +- src/dos/dos_files.cpp | 2 +- src/dos/dos_ioctl.cpp | 2 +- src/dos/dos_keyboard_layout.cpp | 2 +- src/dos/dos_memory.cpp | 2 +- src/dos/dos_misc.cpp | 2 +- src/dos/dos_programs.cpp | 2 +- src/dos/dos_tables.cpp | 2 +- src/dos/drive_cache.cpp | 2 +- src/dos/drive_fat.cpp | 2 +- src/dos/drive_iso.cpp | 2 +- src/dos/drive_local.cpp | 2 +- src/dos/drive_virtual.cpp | 2 +- src/dos/drives.cpp | 2 +- src/dos/drives.h | 2 +- src/dosbox.cpp | 2 +- src/fpu/fpu.cpp | 2 +- src/fpu/fpu_instructions.h | 2 +- src/fpu/fpu_instructions_x86.h | 2 +- src/gui/dosbox_logo.h | 2 +- src/gui/midi.cpp | 2 +- src/gui/midi_alsa.h | 2 +- src/gui/midi_coreaudio.h | 2 +- src/gui/midi_oss.h | 2 +- src/gui/midi_win32.h | 2 +- src/gui/render.cpp | 2 +- src/gui/render_loops.h | 2 +- src/gui/render_scalers.cpp | 2 +- src/gui/render_scalers.h | 2 +- src/gui/render_simple.h | 2 +- src/gui/render_templates.h | 2 +- src/gui/render_templates_hq.h | 2 +- src/gui/render_templates_hq2x.h | 2 +- src/gui/render_templates_hq3x.h | 2 +- src/gui/render_templates_sai.h | 2 +- src/gui/sdl_gui.cpp | 2 +- src/gui/sdl_mapper.cpp | 2 +- src/gui/sdlmain.cpp | 6 +++--- src/hardware/adlib.cpp | 2 +- src/hardware/adlib.h | 2 +- src/hardware/cmos.cpp | 2 +- src/hardware/dbopl.cpp | 2 +- src/hardware/dbopl.h | 2 +- src/hardware/disney.cpp | 2 +- src/hardware/dma.cpp | 2 +- src/hardware/gameblaster.cpp | 2 +- src/hardware/gus.cpp | 2 +- src/hardware/hardware.cpp | 2 +- src/hardware/iohandler.cpp | 2 +- src/hardware/ipx.cpp | 2 +- src/hardware/ipxserver.cpp | 2 +- src/hardware/joystick.cpp | 2 +- src/hardware/keyboard.cpp | 2 +- src/hardware/memory.cpp | 2 +- src/hardware/mixer.cpp | 2 +- src/hardware/mpu401.cpp | 2 +- src/hardware/opl.cpp | 2 +- src/hardware/opl.h | 2 +- src/hardware/pcspeaker.cpp | 2 +- src/hardware/pic.cpp | 2 +- src/hardware/sblaster.cpp | 2 +- src/hardware/serialport/directserial.cpp | 2 +- src/hardware/serialport/directserial.h | 2 +- src/hardware/serialport/libserial.cpp | 2 +- src/hardware/serialport/libserial.h | 2 +- src/hardware/serialport/misc_util.cpp | 2 +- src/hardware/serialport/misc_util.h | 2 +- src/hardware/serialport/nullmodem.cpp | 2 +- src/hardware/serialport/nullmodem.h | 2 +- src/hardware/serialport/serialdummy.cpp | 2 +- src/hardware/serialport/serialdummy.h | 2 +- src/hardware/serialport/serialport.cpp | 2 +- src/hardware/serialport/softmodem.cpp | 2 +- src/hardware/serialport/softmodem.h | 2 +- src/hardware/tandy_sound.cpp | 2 +- src/hardware/timer.cpp | 2 +- src/hardware/vga.cpp | 2 +- src/hardware/vga_attr.cpp | 2 +- src/hardware/vga_crtc.cpp | 2 +- src/hardware/vga_dac.cpp | 2 +- src/hardware/vga_draw.cpp | 2 +- src/hardware/vga_gfx.cpp | 2 +- src/hardware/vga_memory.cpp | 2 +- src/hardware/vga_misc.cpp | 2 +- src/hardware/vga_other.cpp | 2 +- src/hardware/vga_paradise.cpp | 2 +- src/hardware/vga_s3.cpp | 2 +- src/hardware/vga_seq.cpp | 2 +- src/hardware/vga_tseng.cpp | 2 +- src/hardware/vga_xga.cpp | 2 +- src/ints/bios.cpp | 2 +- src/ints/bios_disk.cpp | 2 +- src/ints/bios_keyboard.cpp | 2 +- src/ints/ems.cpp | 2 +- src/ints/int10.cpp | 2 +- src/ints/int10.h | 2 +- src/ints/int10_char.cpp | 2 +- src/ints/int10_memory.cpp | 2 +- src/ints/int10_misc.cpp | 2 +- src/ints/int10_modes.cpp | 2 +- src/ints/int10_pal.cpp | 2 +- src/ints/int10_put_pixel.cpp | 2 +- src/ints/int10_vesa.cpp | 2 +- src/ints/int10_video_state.cpp | 2 +- src/ints/int10_vptable.cpp | 2 +- src/ints/mouse.cpp | 2 +- src/ints/xms.cpp | 2 +- src/ints/xms.h | 2 +- src/libs/zmbv/drvproc.cpp | 2 +- src/libs/zmbv/zmbv.cpp | 2 +- src/libs/zmbv/zmbv.h | 2 +- src/libs/zmbv/zmbv_vfw.cpp | 2 +- src/misc/cross.cpp | 2 +- src/misc/messages.cpp | 2 +- src/misc/programs.cpp | 2 +- src/misc/setup.cpp | 2 +- src/misc/support.cpp | 2 +- src/shell/shell.cpp | 2 +- src/shell/shell_batch.cpp | 2 +- src/shell/shell_cmds.cpp | 2 +- src/shell/shell_misc.cpp | 2 +- 213 files changed, 215 insertions(+), 215 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 1ba54410..61e3d067 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -305,7 +305,7 @@ AC_SUBST(ALSA_LIBS) AH_TOP([ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/bios.h b/include/bios.h index 87696b6a..8f722d6d 100644 --- a/include/bios.h +++ b/include/bios.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/bios_disk.h b/include/bios_disk.h index 3a77ea5c..861d96e3 100644 --- a/include/bios_disk.h +++ b/include/bios_disk.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/callback.h b/include/callback.h index d1240ee2..c4e6fa6e 100644 --- a/include/callback.h +++ b/include/callback.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/control.h b/include/control.h index 427fc6d9..0a688e14 100644 --- a/include/control.h +++ b/include/control.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/cpu.h b/include/cpu.h index a10291b1..d18caa2f 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/cross.h b/include/cross.h index 6a558e6f..8628beb3 100644 --- a/include/cross.h +++ b/include/cross.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/debug.h b/include/debug.h index 89378c74..d0684923 100644 --- a/include/debug.h +++ b/include/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/dma.h b/include/dma.h index 775f9d2a..a12615db 100644 --- a/include/dma.h +++ b/include/dma.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/dos_inc.h b/include/dos_inc.h index c76ba885..290d76b3 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/dos_system.h b/include/dos_system.h index 6a3fe97e..5edb0487 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/dosbox.h b/include/dosbox.h index 743de581..c46cf0a4 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/fpu.h b/include/fpu.h index b5e3b2d7..67f7db41 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/hardware.h b/include/hardware.h index 4a440855..d7da3488 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/inout.h b/include/inout.h index 4943435f..798e9db9 100644 --- a/include/inout.h +++ b/include/inout.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/ipx.h b/include/ipx.h index f8e434dd..27c984ff 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/ipxserver.h b/include/ipxserver.h index 6ed39b75..e31c1754 100644 --- a/include/ipxserver.h +++ b/include/ipxserver.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/joystick.h b/include/joystick.h index 5d4575b7..fe39e5e3 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/keyboard.h b/include/keyboard.h index bb62cab0..0e60f290 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/mapper.h b/include/mapper.h index bf329cb1..932f6563 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/mem.h b/include/mem.h index 8b24762a..73686ae2 100644 --- a/include/mem.h +++ b/include/mem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/mixer.h b/include/mixer.h index a31b5493..b9ca8824 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/mouse.h b/include/mouse.h index 218a4442..74ff0105 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/paging.h b/include/paging.h index f7468545..f7198f8f 100644 --- a/include/paging.h +++ b/include/paging.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/pic.h b/include/pic.h index e104ec4e..8b6e2f4d 100644 --- a/include/pic.h +++ b/include/pic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/programs.h b/include/programs.h index e92fdb33..f8473850 100644 --- a/include/programs.h +++ b/include/programs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/regs.h b/include/regs.h index 2f37b1c1..13da9233 100644 --- a/include/regs.h +++ b/include/regs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/render.h b/include/render.h index ee3db590..bbfd90eb 100644 --- a/include/render.h +++ b/include/render.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/serialport.h b/include/serialport.h index 64476e1b..aa2446a2 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/setup.h b/include/setup.h index b9b68666..db75ada8 100644 --- a/include/setup.h +++ b/include/setup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/shell.h b/include/shell.h index 7bce84df..7d1f3c05 100644 --- a/include/shell.h +++ b/include/shell.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/support.h b/include/support.h index 9b7e7022..32e1e202 100644 --- a/include/support.h +++ b/include/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/timer.h b/include/timer.h index 495381f5..b4be740e 100644 --- a/include/timer.h +++ b/include/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/vga.h b/include/vga.h index 8d8a3bc7..55abf2f8 100644 --- a/include/vga.h +++ b/include/vga.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/include/video.h b/include/video.h index 4b57e0e5..7c7af5e2 100644 --- a/include/video.h +++ b/include/video.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 1d21062e..8cedf927 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index b242e7b6..851a04ed 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index e930c0f0..b5bc7b54 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 3a838f34..0f024541 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dyn_x86/dyn_fpu.h b/src/cpu/core_dyn_x86/dyn_fpu.h index 90e3ba09..ab23152c 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu.h +++ b/src/cpu/core_dyn_x86/dyn_fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dyn_x86/dyn_fpu_dh.h b/src/cpu/core_dyn_x86/dyn_fpu_dh.h index cc49fe55..cc48a02f 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu_dh.h +++ b/src/cpu/core_dyn_x86/dyn_fpu_dh.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 6837d0e3..849b433a 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index 3b90fa16..388422f4 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index df8275c0..79f9e15a 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index 9a38f775..16619cb7 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h index 8d7846c7..0ca887c2 100644 --- a/src/cpu/core_dynrec/decoder.h +++ b/src/cpu/core_dynrec/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index 3a0cd4af..ad3b035a 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index b12733b3..8ce6ad13 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dynrec/dyn_fpu.h b/src/cpu/core_dynrec/dyn_fpu.h index 43ebff4d..d517e2e5 100644 --- a/src/cpu/core_dynrec/dyn_fpu.h +++ b/src/cpu/core_dynrec/dyn_fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dynrec/operators.h b/src/cpu/core_dynrec/operators.h index eae97390..2ce2e17e 100644 --- a/src/cpu/core_dynrec/operators.h +++ b/src/cpu/core_dynrec/operators.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-common.h b/src/cpu/core_dynrec/risc_armv4le-common.h index 9478a4ea..0bfb2819 100644 --- a/src/cpu/core_dynrec/risc_armv4le-common.h +++ b/src/cpu/core_dynrec/risc_armv4le-common.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-o3.h b/src/cpu/core_dynrec/risc_armv4le-o3.h index cbb48232..02bc9f52 100644 --- a/src/cpu/core_dynrec/risc_armv4le-o3.h +++ b/src/cpu/core_dynrec/risc_armv4le-o3.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-s3.h b/src/cpu/core_dynrec/risc_armv4le-s3.h index ae804b1f..86908025 100644 --- a/src/cpu/core_dynrec/risc_armv4le-s3.h +++ b/src/cpu/core_dynrec/risc_armv4le-s3.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h index 57828866..d6b8d46c 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h index 25056e4a..3ca6147e 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb.h b/src/cpu/core_dynrec/risc_armv4le-thumb.h index 49a6e879..9a0bc6ca 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dynrec/risc_armv4le.h b/src/cpu/core_dynrec/risc_armv4le.h index a36af244..e8cc2f27 100644 --- a/src/cpu/core_dynrec/risc_armv4le.h +++ b/src/cpu/core_dynrec/risc_armv4le.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dynrec/risc_mipsel32.h b/src/cpu/core_dynrec/risc_mipsel32.h index 0da567a0..cdc7541a 100644 --- a/src/cpu/core_dynrec/risc_mipsel32.h +++ b/src/cpu/core_dynrec/risc_mipsel32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index 784b46f7..8013785a 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_dynrec/risc_x86.h b/src/cpu/core_dynrec/risc_x86.h index e5aacb92..4ebe906e 100644 --- a/src/cpu/core_dynrec/risc_x86.h +++ b/src/cpu/core_dynrec/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index b8273573..4299dc7f 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 4fd1a785..7f3b25b7 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_normal/helpers.h b/src/cpu/core_normal/helpers.h index 06fc3fbf..f0fb75c2 100644 --- a/src/cpu/core_normal/helpers.h +++ b/src/cpu/core_normal/helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index b2340238..1c191b51 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 39769ce8..b9adacc8 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index b8aee894..eed5bac8 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 043cabdc..5e12ba56 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index 2a849451..9b230816 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_normal/table_ea.h b/src/cpu/core_normal/table_ea.h index 3f9329b9..08d46132 100644 --- a/src/cpu/core_normal/table_ea.h +++ b/src/cpu/core_normal/table_ea.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_prefetch.cpp b/src/cpu/core_prefetch.cpp index 0ea91f0e..d9ec489f 100644 --- a/src/cpu/core_prefetch.cpp +++ b/src/cpu/core_prefetch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp index 1930c3b8..2d026b94 100644 --- a/src/cpu/core_simple.cpp +++ b/src/cpu/core_simple.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 634558c2..7fd5bdc2 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 889f6a4e..2e9532f5 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index cb1df6be..1696997c 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index 96974ec0..a2a031d7 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/modrm.cpp b/src/cpu/modrm.cpp index cd62c629..bbac41e0 100644 --- a/src/cpu/modrm.cpp +++ b/src/cpu/modrm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/modrm.h b/src/cpu/modrm.h index d06aec67..60482bf9 100644 --- a/src/cpu/modrm.h +++ b/src/cpu/modrm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 589c489f..3978083b 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index ed9b2c6e..356ccea8 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 53d19361..fc9f1ca3 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h index f17fa314..1900e949 100644 --- a/src/debug/debug_inc.h +++ b/src/debug/debug_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/debug/debug_win32.cpp b/src/debug/debug_win32.cpp index b33c9004..91147f67 100644 --- a/src/debug/debug_win32.cpp +++ b/src/debug/debug_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/debug/disasm_tables.h b/src/debug/disasm_tables.h index e86e1f86..96531ef1 100644 --- a/src/debug/disasm_tables.h +++ b/src/debug/disasm_tables.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 8e3ec414..2a4b7118 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index d333ef79..4c604544 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index f1dd9792..d7bcfa66 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/cdrom_ioctl_linux.cpp b/src/dos/cdrom_ioctl_linux.cpp index a4a968b7..448fa02d 100644 --- a/src/dos/cdrom_ioctl_linux.cpp +++ b/src/dos/cdrom_ioctl_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/cdrom_ioctl_os2.cpp b/src/dos/cdrom_ioctl_os2.cpp index 30c62721..ec1a7c8d 100644 --- a/src/dos/cdrom_ioctl_os2.cpp +++ b/src/dos/cdrom_ioctl_os2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index 60d9d3c6..9044e543 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 4a3527ea..dfd267a4 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 0ff8f43e..2073a552 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 6057e02a..840f204e 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 47811f65..4e9beb11 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 867c74e5..c720fd9a 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 57c53777..af2e6252 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 950867a1..d6886be2 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 67533716..7bdd514d 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index 64d4dd7e..923e5dab 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 816d4f0b..e01dd1a3 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 7b9152d5..704daefc 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index d6800564..5f155e5d 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 9e9d2453..3fbe33b4 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index bfcdd6f2..5150850b 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index dc4fc28b..f92e666f 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index c2089a8c..95bdf187 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index 018dd52e..c5b502d6 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dos/drives.h b/src/dos/drives.h index f6198c56..aa629fc5 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/dosbox.cpp b/src/dosbox.cpp index e385f228..ed4a4fd2 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index fade5f1e..48c5b964 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 8b608249..9a505a2b 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index 8d5ad728..16d96d66 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/dosbox_logo.h b/src/gui/dosbox_logo.h index 25f2c15e..4895d7d6 100644 --- a/src/gui/dosbox_logo.h +++ b/src/gui/dosbox_logo.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 1ddbd373..61d15e55 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 36f7e967..4c57ffab 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index 4dc50481..82f4c131 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index 0010d8a3..e1d8d97b 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index 7efb7564..a71904bd 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/render.cpp b/src/gui/render.cpp index c25e6cac..c76047c1 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/render_loops.h b/src/gui/render_loops.h index 49867790..4d742499 100644 --- a/src/gui/render_loops.h +++ b/src/gui/render_loops.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index 787e094a..ebcc0777 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index 8e6815d2..9c0de279 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/render_simple.h b/src/gui/render_simple.h index b873acc7..23f40afa 100644 --- a/src/gui/render_simple.h +++ b/src/gui/render_simple.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index 4959d457..39ab2ef3 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/render_templates_hq.h b/src/gui/render_templates_hq.h index 661604e3..3114dc7c 100644 --- a/src/gui/render_templates_hq.h +++ b/src/gui/render_templates_hq.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/render_templates_hq2x.h b/src/gui/render_templates_hq2x.h index 764d2784..5e4072e8 100644 --- a/src/gui/render_templates_hq2x.h +++ b/src/gui/render_templates_hq2x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/render_templates_hq3x.h b/src/gui/render_templates_hq3x.h index 6f72393d..13b68737 100644 --- a/src/gui/render_templates_hq3x.h +++ b/src/gui/render_templates_hq3x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/render_templates_sai.h b/src/gui/render_templates_sai.h index 62da940e..022d3b3c 100644 --- a/src/gui/render_templates_sai.h +++ b/src/gui/render_templates_sai.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index 1cba06d9..d5d746eb 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 480f0e4b..60393cfd 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index b2c0300e..3faddb95 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 @@ -1685,7 +1685,7 @@ int main(int argc, char* argv[]) { #endif //defined(WIN32) && !(C_DEBUG) if (control->cmdline->FindExist("-version") || control->cmdline->FindExist("--version") ) { - printf("\nDOSBox version %s, copyright 2002-2009 DOSBox Team.\n\n",VERSION); + printf("\nDOSBox version %s, copyright 2002-2010 DOSBox Team.\n\n",VERSION); printf("DOSBox is written by the DOSBox Team (See AUTHORS file))\n"); printf("DOSBox comes with ABSOLUTELY NO WARRANTY. This is free software,\n"); printf("and you are welcome to redistribute it under certain conditions;\n"); @@ -1713,7 +1713,7 @@ int main(int argc, char* argv[]) { /* Display Welcometext in the console */ LOG_MSG("DOSBox version %s",VERSION); - LOG_MSG("Copyright 2002-2009 DOSBox Team, published under GNU GPL."); + LOG_MSG("Copyright 2002-2010 DOSBox Team, published under GNU GPL."); LOG_MSG("---"); /* Init SDL */ diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 23311778..7a0a5e61 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/adlib.h b/src/hardware/adlib.h index f82953df..5070d662 100644 --- a/src/hardware/adlib.h +++ b/src/hardware/adlib.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 35f3df88..e6adad51 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index b5ff85e4..df1c7548 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/dbopl.h b/src/hardware/dbopl.h index c0e5367a..c6334e06 100644 --- a/src/hardware/dbopl.h +++ b/src/hardware/dbopl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 89b3ce59..867d32f9 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index c58dc039..542f5962 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index 8488eddc..210817c8 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 727ad07e..aa230dc8 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 378f7185..42570b2b 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index ea170f0e..078d132f 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index e4129d06..7b45c805 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/ipxserver.cpp b/src/hardware/ipxserver.cpp index 9c1d3d2b..937b4e32 100644 --- a/src/hardware/ipxserver.cpp +++ b/src/hardware/ipxserver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index b963cfe8..6aff4c40 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 4b48ef1c..4d25a7bb 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 20b2a924..ba76a8dc 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index d5a29ce7..202f101d 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index a0a82146..333e1060 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/opl.cpp b/src/hardware/opl.cpp index d09a79b6..29cd204f 100644 --- a/src/hardware/opl.cpp +++ b/src/hardware/opl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 The DOSBox Team * OPL2/OPL3 emulation library * * This library is free software; you can redistribute it and/or diff --git a/src/hardware/opl.h b/src/hardware/opl.h index eafb527c..c7f38e01 100644 --- a/src/hardware/opl.h +++ b/src/hardware/opl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 The DOSBox Team * OPL2/OPL3 emulation library * * This library is free software; you can redistribute it and/or diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 94496714..008523b4 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 2d4e7ff4..fde85022 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index f45ca282..0ad028fb 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/serialport/directserial.cpp b/src/hardware/serialport/directserial.cpp index 8d8db430..529c11b1 100644 --- a/src/hardware/serialport/directserial.cpp +++ b/src/hardware/serialport/directserial.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/serialport/directserial.h b/src/hardware/serialport/directserial.h index d8285ea4..e7121e28 100644 --- a/src/hardware/serialport/directserial.h +++ b/src/hardware/serialport/directserial.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/serialport/libserial.cpp b/src/hardware/serialport/libserial.cpp index 0c7ad2a4..5d66851d 100644 --- a/src/hardware/serialport/libserial.cpp +++ b/src/hardware/serialport/libserial.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/serialport/libserial.h b/src/hardware/serialport/libserial.h index f3420c84..fad6d201 100644 --- a/src/hardware/serialport/libserial.h +++ b/src/hardware/serialport/libserial.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/serialport/misc_util.cpp b/src/hardware/serialport/misc_util.cpp index 6f01d9c7..0243c35d 100644 --- a/src/hardware/serialport/misc_util.cpp +++ b/src/hardware/serialport/misc_util.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/serialport/misc_util.h b/src/hardware/serialport/misc_util.h index e4260422..83f3dfab 100644 --- a/src/hardware/serialport/misc_util.h +++ b/src/hardware/serialport/misc_util.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/serialport/nullmodem.cpp b/src/hardware/serialport/nullmodem.cpp index 605d3826..668ebc4c 100644 --- a/src/hardware/serialport/nullmodem.cpp +++ b/src/hardware/serialport/nullmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/serialport/nullmodem.h b/src/hardware/serialport/nullmodem.h index 395af647..012ddaf4 100644 --- a/src/hardware/serialport/nullmodem.h +++ b/src/hardware/serialport/nullmodem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/serialport/serialdummy.cpp b/src/hardware/serialport/serialdummy.cpp index c8aa9492..f4dd904c 100644 --- a/src/hardware/serialport/serialdummy.cpp +++ b/src/hardware/serialport/serialdummy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/serialport/serialdummy.h b/src/hardware/serialport/serialdummy.h index 52087b51..2da38afa 100644 --- a/src/hardware/serialport/serialdummy.h +++ b/src/hardware/serialport/serialdummy.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index b6a310ac..1fd1f2d4 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index 0dd33c25..78029a91 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index 42406c37..f884dde0 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 120ed13e..7ee942f9 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index c3780a77..a4a7c503 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 0f1377bb..74edb830 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 94e320fb..1f1371b0 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 561185d3..aab7b888 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index 74f44762..c2179377 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 6e94013b..3edf56ce 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index 9ce72a7f..a79e9c31 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index c972d516..74f97528 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 4773f936..517166f7 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index bbf059ad..80143d4f 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/vga_paradise.cpp b/src/hardware/vga_paradise.cpp index 596b267d..f05c862d 100644 --- a/src/hardware/vga_paradise.cpp +++ b/src/hardware/vga_paradise.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index 0be0982a..c656a4d0 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 409b2ca8..33a6604d 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/vga_tseng.cpp b/src/hardware/vga_tseng.cpp index c3cded9a..16735577 100644 --- a/src/hardware/vga_tseng.cpp +++ b/src/hardware/vga_tseng.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index 363b9592..b7f927c8 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 50debeec..4190b8a4 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 9b0289e4..f4ae47d4 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index ef56885b..8ad36559 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 64d2593c..a24a4a41 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 62b638ba..018e994a 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/ints/int10.h b/src/ints/int10.h index 4e0fd1ce..8bc7fbcd 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index b51e785e..a3f7764a 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 1c0ee0ab..789d52a3 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 4c91dbe2..b9867d57 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index e3326118..b8eec1b4 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 49e48260..e9ff967d 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 585260c5..63e08681 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 82fc350f..627703fd 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/ints/int10_video_state.cpp b/src/ints/int10_video_state.cpp index 4c697f61..59bfc615 100644 --- a/src/ints/int10_video_state.cpp +++ b/src/ints/int10_video_state.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/ints/int10_vptable.cpp b/src/ints/int10_vptable.cpp index 7b80fb38..4e507bee 100644 --- a/src/ints/int10_vptable.cpp +++ b/src/ints/int10_vptable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 4cfe2d09..e0aa8b66 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index a5d9f669..456fab1f 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/ints/xms.h b/src/ints/xms.h index f41151da..d96d49c9 100644 --- a/src/ints/xms.h +++ b/src/ints/xms.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/libs/zmbv/drvproc.cpp b/src/libs/zmbv/drvproc.cpp index faace585..3f5bc957 100644 --- a/src/libs/zmbv/drvproc.cpp +++ b/src/libs/zmbv/drvproc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/libs/zmbv/zmbv.cpp b/src/libs/zmbv/zmbv.cpp index cb9d761c..d45e56a6 100644 --- a/src/libs/zmbv/zmbv.cpp +++ b/src/libs/zmbv/zmbv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/libs/zmbv/zmbv.h b/src/libs/zmbv/zmbv.h index 8306b962..cc744784 100644 --- a/src/libs/zmbv/zmbv.h +++ b/src/libs/zmbv/zmbv.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/libs/zmbv/zmbv_vfw.cpp b/src/libs/zmbv/zmbv_vfw.cpp index 4181797f..5fd6351a 100644 --- a/src/libs/zmbv/zmbv_vfw.cpp +++ b/src/libs/zmbv/zmbv_vfw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/misc/cross.cpp b/src/misc/cross.cpp index 82b78d19..bc4557e4 100644 --- a/src/misc/cross.cpp +++ b/src/misc/cross.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index b2ce3d9c..b253d792 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index b67aee75..7e5e6db5 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 27bee4b4..f87b8740 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 375923a6..19d037cb 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index f010c7f5..41d98cb0 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 821d188f..b259651e 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 7f47f2c1..49ff8277 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 2b5056af..221ddc4c 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2002-2010 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 From fb848f5af4dd00c90455cdeaaee7d4d1ce6df9f1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 12 Feb 2010 12:14:21 +0000 Subject: [PATCH 3460/4131] Correct line ends Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3549 --- src/hardware/iohandler.cpp | 48 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 078d132f..d53ad704 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -236,41 +236,41 @@ void log_io(Bitu width, bool write, Bitu port, Bitu val) { switch(port) { //case 0x020: // interrupt command - //case 0x040: // timer 0 + //case 0x040: // timer 0 //case 0x042: // timer 2 //case 0x043: // timer control //case 0x061: // speaker control case 0x3c8: // VGA palette case 0x3c9: // VGA palette - // case 0x3d4: // VGA crtc + // case 0x3d4: // VGA crtc // case 0x3d5: // VGA crtc - // case 0x3c4: // VGA seq + // case 0x3c4: // VGA seq // case 0x3c5: // VGA seq break; - default: - LOG_MSG("iow%s % 4x % 4x, cs:ip %04x:%04x", len_type[width], - port, val, SegValue(cs),reg_eip); + default: + LOG_MSG("iow%s % 4x % 4x, cs:ip %04x:%04x", len_type[width], + port, val, SegValue(cs),reg_eip); break; } } else { - switch(port) { - //case 0x021: // interrupt status - //case 0x040: // timer 0 - //case 0x042: // timer 2 - //case 0x061: // speaker control - case 0x201: // joystick status - case 0x3c9: // VGA palette - // case 0x3d4: // VGA crtc index - // case 0x3d5: // VGA crtc - case 0x3da: // display status - a real spammer - // don't log for the above cases - break; - default: - LOG_MSG("ior%s % 4x % 4x,\t\tcs:ip %04x:%04x", len_type[width], - port, val, SegValue(cs),reg_eip); - break; - } - } + switch(port) { + //case 0x021: // interrupt status + //case 0x040: // timer 0 + //case 0x042: // timer 2 + //case 0x061: // speaker control + case 0x201: // joystick status + case 0x3c9: // VGA palette + // case 0x3d4: // VGA crtc index + // case 0x3d5: // VGA crtc + case 0x3da: // display status - a real spammer + // don't log for the above cases + break; + default: + LOG_MSG("ior%s % 4x % 4x,\t\tcs:ip %04x:%04x", len_type[width], + port, val, SegValue(cs),reg_eip); + break; + } + } } #else #define log_io(W, X, Y, Z) From 27714abb4758c25e774eee41e1cea4a9e0981a42 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 13 Feb 2010 11:37:25 +0000 Subject: [PATCH 3461/4131] Convert line ends in the shell. Improves compatibility with the sierra what.exe utility Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3550 --- src/misc/programs.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 7e5e6db5..f88f06ee 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -137,18 +137,38 @@ void Program::WriteOut(const char * format,...) { va_end(msg); Bit16u size = (Bit16u)strlen(buf); - DOS_WriteFile(STDOUT,(Bit8u *)buf,&size); + for(Bit16u i = 0; i < size;i++) { + Bit8u out;Bit16u s=1; + if(buf[i] == 0xA && i > 0 && buf[i-1] !=0xD) { + out = 0xD;DOS_WriteFile(STDOUT,&out,&s); + } + out = buf[i]; + DOS_WriteFile(STDOUT,&out,&s); + } + +// DOS_WriteFile(STDOUT,(Bit8u *)buf,&size); } void Program::WriteOut_NoParsing(const char * format) { Bit16u size = (Bit16u)strlen(format); - DOS_WriteFile(STDOUT,(Bit8u *)format,&size); + char const* buf = format; + for(Bit16u i = 0; i < size;i++) { + Bit8u out;Bit16u s=1; + if(buf[i] == 0xA && i > 0 && buf[i-1] !=0xD) { + out = 0xD;DOS_WriteFile(STDOUT,&out,&s); + } + out = buf[i]; + DOS_WriteFile(STDOUT,&out,&s); + } + +// DOS_WriteFile(STDOUT,(Bit8u *)format,&size); } bool Program::GetEnvStr(const char * entry,std::string & result) { /* Walk through the internal environment and see for a match */ PhysPt env_read=PhysMake(psp->GetEnvironment(),0); + char env_string[1024+1]; result.erase(); if (!entry[0]) return false; From 24c2a091317fc462b4df4648c1cdf98d2e588dc9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 14 Feb 2010 13:47:16 +0000 Subject: [PATCH 3462/4131] New defaults Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3551 --- src/dosbox.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index ed4a4fd2..d550395c 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -317,8 +317,8 @@ void DOSBOX_Init(void) { SDLNetInited = false; // Some frequently used option sets - const char *rates[] = { "22050", "44100", "48000", "32000", "16000", "11025", "8000", "49716", 0 }; - const char *oplrates[] = { "22050", "49716", "44100", "48000", "32000", "16000", "11025", "8000", 0 }; + const char *rates[] = { "44100", "48000", "32000","22050", "16000", "11025", "8000", "49716", 0 }; + const char *oplrates[] = { "44100", "49716", "48000", "32000","22050", "16000", "11025", "8000", 0 }; const char *ios[] = { "220", "240", "260", "280", "2a0", "2c0", "2e0", "300", 0 }; const char *irqssb[] = { "7", "5", "3", "9", "10", "11", "12", 0 }; const char *dmassb[] = { "1", "5", "0", "3", "6", "7", 0 }; @@ -415,7 +415,7 @@ void DOSBOX_Init(void) { " It usually works, but can fail for certain games.\n" " 'fixed #number' will set a fixed amount of cycles. This is what you usually need if 'auto' fails.\n" " (Example: fixed 4000)\n" - " 'max' will allocate as much cycles as your computer is able to handle\n"); + " 'max' will allocate as much cycles as your computer is able to handle.\n"); const char* cyclest[] = { "auto","fixed","max","%u",0 }; Pstring = Pmulti_remain->GetSection()->Add_string("type",Property::Changeable::Always,"auto"); @@ -443,7 +443,7 @@ void DOSBOX_Init(void) { Pbool = secprop->Add_bool("nosound",Property::Changeable::OnlyAtStart,false); Pbool->Set_help("Enable silent mode, sound is still emulated though."); - Pint = secprop->Add_int("rate",Property::Changeable::OnlyAtStart,22050); + Pint = secprop->Add_int("rate",Property::Changeable::OnlyAtStart,44100); Pint->Set_values(rates); Pint->Set_help("Mixer sample rate, setting any device's rate higher than this will probably lower their sound quality."); @@ -514,7 +514,7 @@ void DOSBOX_Init(void) { Pstring->Set_values(oplemus); Pstring->Set_help("Provider for the OPL emulation. compat might provide better quality (see oplrate as well)."); - Pint = secprop->Add_int("oplrate",Property::Changeable::WhenIdle,22050); + Pint = secprop->Add_int("oplrate",Property::Changeable::WhenIdle,44100); Pint->Set_values(oplrates); Pint->Set_help("Sample rate of OPL music emulation. Use 49716 for highest quality (set the mixer rate accordingly)."); @@ -523,7 +523,7 @@ void DOSBOX_Init(void) { Pbool = secprop->Add_bool("gus",Property::Changeable::WhenIdle,false); Pbool->Set_help("Enable the Gravis Ultrasound emulation."); - Pint = secprop->Add_int("gusrate",Property::Changeable::WhenIdle,22050); + Pint = secprop->Add_int("gusrate",Property::Changeable::WhenIdle,44100); Pint->Set_values(rates); Pint->Set_help("Sample rate of Ultrasound emulation."); @@ -550,7 +550,7 @@ void DOSBOX_Init(void) { Pbool = secprop->Add_bool("pcspeaker",Property::Changeable::WhenIdle,true); Pbool->Set_help("Enable PC-Speaker emulation."); - Pint = secprop->Add_int("pcrate",Property::Changeable::WhenIdle,22050); + Pint = secprop->Add_int("pcrate",Property::Changeable::WhenIdle,44100); Pint->Set_values(rates); Pint->Set_help("Sample rate of the PC-Speaker sound generation."); @@ -560,7 +560,7 @@ void DOSBOX_Init(void) { Pstring->Set_values(tandys); Pstring->Set_help("Enable Tandy Sound System emulation. For 'auto', emulation is present only if machine is set to 'tandy'."); - Pint = secprop->Add_int("tandyrate",Property::Changeable::WhenIdle,22050); + Pint = secprop->Add_int("tandyrate",Property::Changeable::WhenIdle,44100); Pint->Set_values(rates); Pint->Set_help("Sample rate of the Tandy 3-Voice generation."); @@ -594,7 +594,7 @@ void DOSBOX_Init(void) { Pbool = secprop->Add_bool("swap34",Property::Changeable::WhenIdle,false); Pbool->Set_help("swap the 3rd and the 4th axis. can be useful for certain joysticks."); - Pbool = secprop->Add_bool("buttonwrap",Property::Changeable::WhenIdle,true); + Pbool = secprop->Add_bool("buttonwrap",Property::Changeable::WhenIdle,false); Pbool->Set_help("enable button wrapping at the number of emulated buttons."); secprop=control->AddSection_prop("serial",&SERIAL_Init,true); From 91f093b9ce986175542cbfe7082fae2b0837d606 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 14 Feb 2010 14:14:54 +0000 Subject: [PATCH 3463/4131] Update changelog. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3552 --- ChangeLog | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/ChangeLog b/ChangeLog index 2310a4f1..270019fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,69 @@ +0.74 + - Several small game specific fixes/hacks/support. (Offensive, + Roadhog, GTA installer, Kingdom O' Magic soundcard detection, + Pirate booter, armored fist installer) + - Add the S3-specific 640x480 256 color mode. Fixes regression in "Wooden + Ships and Iron Men" and "I Have No Mouth And I Must Scream". + - Fix a stack overflow that could crash DOSBox. + - Add fake microphone input. (Fixes Talking Parrot) + - Modify adlib turn off code, so that it doesn't turn off in + cases where the same sound is repeated over and over again. + - Several small fixes to the CDROM audio code. (HOMM2, Redneck + Rampage and others) + - Several improvements to the CDROM emulation code. (fixes Alpha + Storm and GT Racing 97) + - Some small cpu fixes that might fix something. + - Handle opcode 0xff subcode 7 as invalid instruction, fixes dif-2 & others. + - Some hercules fixes (Testdrive) + - Improve support for blanked parts that wrap around to the start of + the screen. (Fixes Magic Circle demo and Sid&Al) + - Remove old opl cores as the new ones seem work very nice. + - Modify movie recording code so that the movies aren't corrupt when + you exit dosbox without stopping the movie. + - Change RGB3x scaler to look more pretty. + - Improve initial register values compatility of the GUS. + - Change render preferences a bit to be more compatible with windows 7. + - Add DOS fixes to terminate program. (Fixes fortune teller) + - Add FFREEP. (Fixes trucks) + - Improve FPU ST80 in C mode when writing zero. (Fixes antigok) + - Add special int10 scanline function. (Fixes mz700 and probably lots + of games that mess with them) + - Fix scrolling in rarely used video modes. (Fixes Orphee) + - Modify game specific hacks a bit so that Kick off 3 works again. + - Lots of fixes to the INT10 video parameter table. (Seven spirits + of ra and others) + - Several small DOS fixes. + - Some UMB related fixes. ( The Legacy without umb) + - Fix version number of DSP for SB 1.5. (fixes a few games) + - Several vga emulation improvements (Allertone football manager) + - Some tandy fixes. (mech warrior) + - Small improvements and fixes to the OPL emulation. + - Add low Level tandy DAC emulation. + - Some EMS fixes. (Fixes Mortal Kombat and others) + - Change SoundBlaster DSP reset mechanism, add sb irq acknowledge logic + (fixes stmik-based applications). + - Some interrupt pointer location modifications. (fixes tinker tales) + - Some fixes to the BOOT code. (fixes last mission) + - Respect write-only. (fixes champions of zulala) + - Some RTC fix. (Fixes Tully Bodine and others) + - Improve mouse emulation to work better with Water World. + - Hopefully fix the translation of the configuration file. + - Speed up and fixes for the recompiler core. (pitfall2 pcjr) + - Change memory start location. (Fixes 7th Guest installer) + - Several fixes to the BAT files handling. (Shift and + use the typed first %0 instead of the parsed %0) + - Improve file redirection and redirected line ends. (Fixes + Phantasmagoria 2 DOS installer) + - Fix compilation with new MAC os X version. + - Add 16C550A FIFO support to the serial port emulation. + - Improve modem emulation to get higher speeds. + - Change default samplerates to 44100, so that hopefully certain + soundcards produce more fluent sound playback. + - Add some rarely used, but for some games critical flags to + the internal commands. + - Improve internal timing with repeatings timers (especially with + the dynamic core). + 0.73 - Add two new opl2+opl3 emulators. (better speed, different implementation approach) From e19e93e5c22dc1461d2486ac33ddad41d1dc252b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 26 Feb 2010 15:18:56 +0000 Subject: [PATCH 3464/4131] Add + document option to remove mapperfile used by a clean configuration. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3553 --- README | 6 +++++- docs/dosbox.1 | 7 ++++++- src/gui/sdlmain.cpp | 15 ++++++++++++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/README b/README index 65b2312e..5a5849d6 100644 --- a/README +++ b/README @@ -313,8 +313,9 @@ dosbox -editconf program dosbox -opencaptures program dosbox -printconf dosbox -eraseconf +dosbox -erasemapper - name + name If "name" is a directory it will mount that as the C: drive. If "name" is an executable it will mount the directory of "name" as the C: drive and execute "name". @@ -391,6 +392,9 @@ dosbox -eraseconf -eraseconf removes the default configuration file. + -erasemapper + removes the mapperfile used by the default clean configuration file. + Note: If a name/command/configfile/languagefile contains a space, put the whole name/command/configfile/languagefile between quotes ("command or file name"). If you need to use quotes within quotes diff --git a/docs/dosbox.1 b/docs/dosbox.1 index edef4bce..1a759440 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -1,5 +1,5 @@ .\" Hey, EMACS: -*- nroff -*- -.TH DOSBOX 1 "May 27, 2009" +.TH DOSBOX 1 "Feb 26, 2010" .\" Please adjust this date whenever revising the manpage. .SH NAME dosbox \- an x86/DOS emulator with sound/graphics @@ -27,6 +27,8 @@ dosbox \- an x86/DOS emulator with sound/graphics .B dosbox \-printconf .LP .B dosbox \-eraseconf +.LP +.B dosbox \-erasemapper .SH DESCRIPTION This manual page briefly documents .BR "dosbox" ", an x86/DOS emulator." @@ -107,6 +109,9 @@ prints the location of the default configuration file. .TP .B \-eraseconf removes the default configuration file. +.TP +.B \-erasemapper +removes the mapperfile configured in the clean default configuration file. .SH "INTERNAL COMMANDS" .B dosbox supports most of the DOS commands found in command.com. In addition, the diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 3faddb95..217caf13 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -51,6 +51,7 @@ #include "cross.h" #include "control.h" +#define MAPPERFILE "mapper-" VERSION ".conf" //#define DISABLE_JOYSTICK #if C_OPENGL @@ -1513,7 +1514,7 @@ void Config_Add_SDL() { Pstring = Pmulti->GetSection()->Add_string("inactive",Property::Changeable::Always,"normal"); Pstring->Set_values(inactt); - Pstring = sdl_sec->Add_path("mapperfile",Property::Changeable::Always,"mapper-" VERSION ".conf"); + Pstring = sdl_sec->Add_path("mapperfile",Property::Changeable::Always,MAPPERFILE); Pstring->Set_help("File used to load/save the key/event mappings from."); Pbool = sdl_sec->Add_bool("usescancodes",Property::Changeable::Always,true); @@ -1644,6 +1645,17 @@ static void eraseconfigfile() { exit(0); } +static void erasemapperfile() { + std::string path,file=MAPPERFILE; + Cross::GetPlatformConfigDir(path); + path += file; + FILE* f = fopen(path.c_str(),"r"); + if(!f) exit(0); + fclose(f); + unlink(path.c_str()); + exit(0); +} + //extern void UI_Init(void); @@ -1660,6 +1672,7 @@ int main(int argc, char* argv[]) { if(control->cmdline->FindString("-editconf",editor,false)) launcheditor(); if(control->cmdline->FindString("-opencaptures",editor,true)) launchcaptures(editor); if(control->cmdline->FindExist("-eraseconf")) eraseconfigfile(); + if(control->cmdline->FindExist("-erasemapper")) erasemapperfile(); /* Can't disable the console with debugger enabled */ #if defined(WIN32) && !(C_DEBUG) From 8d3975cbe1210d91ca88b3cf9d15488ba7584a64 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 28 Feb 2010 19:09:39 +0000 Subject: [PATCH 3465/4131] annoyed by a space. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3554 --- acinclude.m4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 61e3d067..0a9f3101 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -390,9 +390,9 @@ typedef double Real64; #if SIZEOF_INT_P == 4 typedef Bit32u Bitu; typedef Bit32s Bits; - #else +#else typedef Bit64u Bitu; typedef Bit64s Bits; - #endif +#endif ]) From 58431593bb90e6e2ce53dc94c74f8d1445a5d925 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 3 Mar 2010 18:19:03 +0000 Subject: [PATCH 3466/4131] User friendly? DOSBox ? a little ;) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3555 --- src/dosbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index d550395c..672afbdd 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -675,7 +675,7 @@ void DOSBOX_Init(void) { ); MSG_Add("CONFIGFILE_INTRO", "# This is the configurationfile for DOSBox %s.\n" - "# Lines starting with a # are commentlines.\n" + "# Lines starting with a # are commentlines and are ignored by DOSBox.\n" "# They are used to (briefly) document the effect of each option.\n"); MSG_Add("CONFIG_SUGGESTED_VALUES", "Possible values"); From 6864fa295fc6df70e93f8cc27a2dacabd5c12f1b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 6 Mar 2010 10:35:49 +0000 Subject: [PATCH 3467/4131] Why didn't we have this earlier.. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3556 --- src/hardware/mixer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 202f101d..555205f2 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -652,6 +652,8 @@ void MIXER_Init(Section* sec) { mixer.tick_add=((mixer.freq) << MIXER_SHIFT)/1000; TIMER_AddTickHandler(MIXER_Mix_NoSound); } else { + if((mixer.freq != obtained.freq) || (mixer.blocksize != obtained.samples)) + LOG_MSG("MIXER:Got different values from SDL: freq %d, blocksize %d",obtained.freq,obtained.samples); mixer.freq=obtained.freq; mixer.blocksize=obtained.samples; mixer.tick_add=(mixer.freq << MIXER_SHIFT)/1000; From e3823f3393df13c77653d3030e52adb952871fc2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 12 Mar 2010 15:16:14 +0000 Subject: [PATCH 3468/4131] Add Patch 2967317 and 2967316. Improving configure a bit. (modified to work with my cross-compiled version of libpng Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3557 --- configure.in | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/configure.in b/configure.in index a24f9bf2..302d21a4 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ AC_CONFIG_SRCDIR(README) dnl Detect the canonical host and target build environment AC_CANONICAL_HOST -AC_CANONICAL_TARGET +AC_CANONICAL_BUILD dnl Setup for automake AM_INIT_AUTOMAKE @@ -21,7 +21,7 @@ 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 +if test x$build = xi386-pc-os2-emx ; then CXXFLAGS="$CXXFLAGS -Zmt" LDFLAGS="$LDFLAGS -Zomf -Zmt" LIBS="$LIBS -los2me" @@ -231,7 +231,7 @@ AC_ARG_ENABLE(core-inline,AC_HELP_STRING([--enable-core-inline],[Enable inlined 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 +case "$build_cpu" in x86_64 | amd64) AC_DEFINE(C_TARGETCPU,X86_64) AC_MSG_RESULT(x86-64 bit compatible) @@ -343,7 +343,7 @@ 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) +AC_CHECK_LIB(png, png_get_io_ptr, 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) @@ -355,7 +355,7 @@ AH_TEMPLATE(C_MODEM,[Define to 1 to enable internal modem support, requires SDL_ 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 +if test x$build = xi386-pc-os2-emx ; then AC_MSG_CHECKING(for SDLNet_Init in SDL_net); LIBS_BACKUP=$LIBS; LIBS="$LIBS -lSDL_Net"; @@ -393,7 +393,7 @@ 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 +case "$build" in *-*-darwin*) AC_MSG_RESULT(yes) LIBS="$LIBS -framework OpenGL" @@ -448,7 +448,7 @@ int main(int argc,char * argv[]) { dnl Some target detection and actions for them -case "$target" in +case "$build" in *-*-cygwin* | *-*-mingw32*) LIBS="$LIBS -lwinmm" AC_CHECK_HEADERS(ddraw.h) @@ -486,7 +486,7 @@ case "$target" in esac dnl Some stuff for the icon. -case "$target" in +case "$build" in *-*-cygwin* | *-*-mingw32*) dnl Some stuff for the ico AC_CHECK_TOOL(WINDRES, windres, :) From 3689afd77e1a0c45ae735bcd46bfd5787369f5a8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 13 Mar 2010 12:12:22 +0000 Subject: [PATCH 3469/4131] Fix point 3 of bug 2209440. (unparsed format specifier) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3558 --- src/dos/dos_programs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index e01dd1a3..79084292 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1071,7 +1071,7 @@ public: return; } } else { - WriteOut_NoParsing(MSG_Get("PROGRAM_IMGMOUNT_FORMAT_UNSUPPORTED")); + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FORMAT_UNSUPPORTED"),fstype.c_str()); return; } From 3e4f029a490237d281f640c5f41e13135a23c4e7 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sat, 13 Mar 2010 16:24:19 +0000 Subject: [PATCH 3470/4131] Calculate horizontal sync timings. Fixes Titus the Fox with Hercules emulation. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3559 --- src/hardware/vga_draw.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 3edf56ce..f24c5d78 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1098,8 +1098,9 @@ void VGA_SetupDrawing(Bitu /*val*/) { // Start and End of horizontal blanking vga.draw.delay.hblkstart = hbstart*1000.0/clock; //in milliseconds vga.draw.delay.hblkend = hbend*1000.0/clock; - vga.draw.delay.hrstart = 0; - + // Start and End of horizontal retrace + vga.draw.delay.hrstart = hrstart*1000.0/clock; + vga.draw.delay.hrend = hrend*1000.0/clock; // Start and End of vertical blanking vga.draw.delay.vblkstart = vbstart * vga.draw.delay.htotal; vga.draw.delay.vblkend = vbend * vga.draw.delay.htotal; From a76c232be0a1a350f9248b164bf857c34c810b6f Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Mon, 15 Mar 2010 19:49:23 +0000 Subject: [PATCH 3471/4131] Change error message for invalid cdrom image file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3560 --- src/dos/dos_programs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 79084292..7d3d3a7b 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1221,7 +1221,7 @@ public: case 0 : break; case 1 : WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS")); break; case 2 : WriteOut(MSG_Get("MSCDEX_ERROR_NOT_SUPPORTED")); break; - case 3 : WriteOut(MSG_Get("MSCDEX_ERROR_PATH")); break; + case 3 : WriteOut(MSG_Get("MSCDEX_ERROR_OPEN")); break; case 4 : WriteOut(MSG_Get("MSCDEX_TOO_MANY_DRIVES")); break; case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break; case 6 : WriteOut(MSG_Get("MSCDEX_INVALID_FILEFORMAT")); break; @@ -1377,7 +1377,7 @@ void DOS_SetupPrograms(void) { MSG_Add("MSCDEX_SUCCESS","MSCDEX installed.\n"); MSG_Add("MSCDEX_ERROR_MULTIPLE_CDROMS","MSCDEX: Failure: Drive-letters of multiple CDRom-drives have to be continuous.\n"); MSG_Add("MSCDEX_ERROR_NOT_SUPPORTED","MSCDEX: Failure: Not yet supported.\n"); - MSG_Add("MSCDEX_ERROR_PATH","MSCDEX: Failure: Path not valid.\n"); + MSG_Add("MSCDEX_ERROR_OPEN","MSCDEX: Failure: Invalid file or unable to open.\n"); MSG_Add("MSCDEX_TOO_MANY_DRIVES","MSCDEX: Failure: Too many CDRom-drives (max: 5). MSCDEX Installation failed.\n"); MSG_Add("MSCDEX_LIMITED_SUPPORT","MSCDEX: Mounted subdirectory: limited support.\n"); MSG_Add("MSCDEX_INVALID_FILEFORMAT","MSCDEX: Failure: File is either no iso/cue image or contains errors.\n"); From 2c2ddb45d9408dbbd73883cca41f85efda6dd05b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 15 Mar 2010 20:02:04 +0000 Subject: [PATCH 3472/4131] Fix lexical typo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3561 --- src/misc/setup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index f87b8740..6c383366 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -213,7 +213,7 @@ bool Property::CheckValue(Value const& in, bool warn){ return true; } } - if(warn) LOG_MSG("\"%s\" is not a valid value for variable: %s.\nIt might now be reset it to default value: %s",in.ToString().c_str(),propname.c_str(),default_value.ToString().c_str()); + if(warn) LOG_MSG("\"%s\" is not a valid value for variable: %s.\nIt might now be reset to the default value: %s",in.ToString().c_str(),propname.c_str(),default_value.ToString().c_str()); return false; } From f33bd81b57eae91c861e22b84289bdfa8aacee4e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 21 Mar 2010 17:07:33 +0000 Subject: [PATCH 3473/4131] all former target stuf, now build, should be host stuff. (build is machine it is compiled on. Host is machine it will run on) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3562 --- configure.in | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/configure.in b/configure.in index 302d21a4..d5a21e30 100644 --- a/configure.in +++ b/configure.in @@ -21,7 +21,7 @@ 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$build = xi386-pc-os2-emx ; then +if test x$host = xi386-pc-os2-emx ; then CXXFLAGS="$CXXFLAGS -Zmt" LDFLAGS="$LDFLAGS -Zomf -Zmt" LIBS="$LIBS -los2me" @@ -231,7 +231,7 @@ AC_ARG_ENABLE(core-inline,AC_HELP_STRING([--enable-core-inline],[Enable inlined 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 "$build_cpu" in +case "$host_cpu" in x86_64 | amd64) AC_DEFINE(C_TARGETCPU,X86_64) AC_MSG_RESULT(x86-64 bit compatible) @@ -355,7 +355,7 @@ AH_TEMPLATE(C_MODEM,[Define to 1 to enable internal modem support, requires SDL_ 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$build = xi386-pc-os2-emx ; then +if test x$host = xi386-pc-os2-emx ; then AC_MSG_CHECKING(for SDLNet_Init in SDL_net); LIBS_BACKUP=$LIBS; LIBS="$LIBS -lSDL_Net"; @@ -393,7 +393,7 @@ 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 "$build" in +case "$host" in *-*-darwin*) AC_MSG_RESULT(yes) LIBS="$LIBS -framework OpenGL" @@ -448,7 +448,7 @@ int main(int argc,char * argv[]) { dnl Some target detection and actions for them -case "$build" in +case "$host" in *-*-cygwin* | *-*-mingw32*) LIBS="$LIBS -lwinmm" AC_CHECK_HEADERS(ddraw.h) @@ -486,7 +486,7 @@ case "$build" in esac dnl Some stuff for the icon. -case "$build" in +case "$host" in *-*-cygwin* | *-*-mingw32*) dnl Some stuff for the ico AC_CHECK_TOOL(WINDRES, windres, :) From 61fcc1304d9c90a5f90bbc8337d6460c977d1d46 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 3 Apr 2010 15:30:25 +0000 Subject: [PATCH 3474/4131] Provide some feedback. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3563 --- src/ints/bios_disk.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index f4ae47d4..baa8dcf2 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -124,8 +124,9 @@ bool getSwapRequest(void) { void swapInNextDisk(bool pressed) { if (!pressed) return; - /* Hack/feature: rescan all disks as well */ DriveManager::CycleAllDisks(); + /* Hack/feature: rescan all disks as well */ + LOG_MSG("Diskcaching reset for normal mounted drives."); for(Bitu i=0;iEmptyCache(); } From ae1be112a25efeca448790ad7af43edec6061afc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 3 Apr 2010 16:13:51 +0000 Subject: [PATCH 3475/4131] To work or not to work... Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3564 --- src/gui/sdl_mapper.cpp | 6 ++++++ src/ints/bios_keyboard.cpp | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 60393cfd..11b50af9 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -2326,11 +2326,17 @@ void MAPPER_Init(void) { if (SDL_GetModState()&KMOD_CAPS) { for (CBindList_it bit=caps_lock_event->bindlist.begin();bit!=caps_lock_event->bindlist.end();bit++) { (*bit)->ActivateBind(32767,true,true); +#if SDL_VERSION_ATLEAST(1, 2, 14) + (*bit)->DeActivateBind(false); +#endif } } if (SDL_GetModState()&KMOD_NUM) { for (CBindList_it bit=num_lock_event->bindlist.begin();bit!=num_lock_event->bindlist.end();bit++) { (*bit)->ActivateBind(32767,true,true); +#if SDL_VERSION_ATLEAST(1, 2, 14) + (*bit)->DeActivateBind(false); +#endif } } } diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 8ad36559..272e69cc 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -246,7 +246,7 @@ static Bitu IRQ1_Handler(void) { flags2&=~(0x40+0x20);//remove numlock/capslock pressed (hack for sdl only reporting states) #endif if (DOS_LayoutKey(scancode,flags1,flags2,flags3)) return CBRET_NONE; -LOG_MSG("key input %d %d %d %d",scancode,flags1,flags2,flags3); +//LOG_MSG("key input %d %d %d %d",scancode,flags1,flags2,flags3); switch (scancode) { /* First the hard ones */ case 0xfa: /* ack. Do nothing for now */ From 953cf4d31818c8ba79b4ebf3e0ad6ff62de78ff7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 3 Apr 2010 16:16:27 +0000 Subject: [PATCH 3476/4131] Change default name again. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3565 --- src/gui/sdlmain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 217caf13..7aa4aafa 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -51,7 +51,7 @@ #include "cross.h" #include "control.h" -#define MAPPERFILE "mapper-" VERSION ".conf" +#define MAPPERFILE "mapper-" VERSION ".map" //#define DISABLE_JOYSTICK #if C_OPENGL From 461ffb6c4016e21c4da01803ea190c2c7de4d309 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 4 Apr 2010 10:23:16 +0000 Subject: [PATCH 3477/4131] Unload CMS/Gameblaster when sbtype is changed. Add GUS FM forwarding when Gameblaster is selected. Make some CMS tables const. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3566 --- src/hardware/gameblaster.cpp | 4 +-- src/hardware/sblaster.cpp | 53 ++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index 210817c8..84a2ee79 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -80,7 +80,7 @@ struct SAA1099 struct saa1099_noise noise[2]; /* noise generators */ }; -static UINT8 envelope[8][64] = { +static const UINT8 envelope[8][64] = { /* zero amplitude */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -124,7 +124,7 @@ static UINT8 envelope[8][64] = { }; -static int amplitude_lookup[16] = { +static const int amplitude_lookup[16] = { 0*32767/16, 1*32767/16, 2*32767/16, 3*32767/16, 4*32767/16, 5*32767/16, 6*32767/16, 7*32767/16, 8*32767/16, 9*32767/16, 10*32767/16, 11*32767/16, diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 0ad028fb..e0427e94 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1469,6 +1469,7 @@ private: IO_WriteHandleObject WriteHandler[0x10]; AutoexecObject autoexecline; MixerObject MixerChan; + OPL_Mode oplmode; /* Support Functions */ void Find_Type_And_Opl(Section_prop* config,SB_TYPES& type, OPL_Mode& opl_mode){ @@ -1497,14 +1498,22 @@ private: else { switch (type) { case SBT_NONE: + opl_mode=OPL_none; + break; case SBT_GB: - opl_mode=OPL_none;break; - case SBT_1:opl_mode=OPL_opl2;break; - case SBT_2:opl_mode=OPL_opl2;break; - case SBT_PRO1:opl_mode=OPL_dualopl2;break; + opl_mode=OPL_cms; + break; + case SBT_1: + case SBT_2: + opl_mode=OPL_opl2; + break; + case SBT_PRO1: + opl_mode=OPL_dualopl2; + break; case SBT_PRO2: case SBT_16: - opl_mode=OPL_opl3;break; + opl_mode=OPL_opl3; + break; } } } @@ -1524,27 +1533,25 @@ public: sb.mixer.enabled=section->Get_bool("sbmixer"); sb.mixer.stereo=false; - OPL_Mode opl_mode = OPL_none; - Find_Type_And_Opl(section,sb.type,opl_mode); - - bool do_cms = (sb.type==SBT_GB)? true:false; - switch (opl_mode) { + Find_Type_And_Opl(section,sb.type,oplmode); + + switch (oplmode) { case OPL_none: WriteHandler[0].Install(0x388,adlib_gusforward,IO_MB); break; case OPL_cms: WriteHandler[0].Install(0x388,adlib_gusforward,IO_MB); - do_cms = true; + CMS_Init(section); break; case OPL_opl2: - do_cms = true; + CMS_Init(section); + // fall-through case OPL_dualopl2: case OPL_opl3: - OPL_Init(section,opl_mode); + OPL_Init(section,oplmode); break; } - if (do_cms) CMS_Init(section); if (sb.type==SBT_NONE || sb.type==SBT_GB) return; sb.chan=MixerChan.Install(&SBLASTER_CallBack,22050,"SB"); @@ -1588,28 +1595,22 @@ public: } ~SBLASTER() { - Section_prop * section=static_cast(m_configuration); - OPL_Mode opl_mode = OPL_none; - Find_Type_And_Opl(section,sb.type,opl_mode); - - switch (opl_mode) { + switch (oplmode) { case OPL_none: - break; case OPL_cms: - - CMS_ShutDown(m_configuration); + CMS_ShutDown(m_configuration); break; case OPL_opl2: - CMS_ShutDown(m_configuration); + CMS_ShutDown(m_configuration); + // fall-through case OPL_dualopl2: case OPL_opl3: - OPL_ShutDown(m_configuration); + OPL_ShutDown(m_configuration); break; } - if (sb.type==SBT_NONE || sb.type==SBT_GB) return; - DSP_Reset();//Stop everything + DSP_Reset(); // Stop everything } }; //End of SBLASTER class From 13ea835d96f6b8ad2bc333b181121c2660f56526 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 4 Apr 2010 12:29:25 +0000 Subject: [PATCH 3478/4131] Keep the timer value during timer mode changes (undocumented behavior). Fixes Dunkle Schatten with Soundblaster and 3DMania. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3567 --- src/hardware/timer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index a4a7c503..8ceb42d5 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -139,6 +139,7 @@ static void counter_latch(Bitu counter) { //If gate2 is disabled don't update the read_latch if(counter == 2 && !gate2 && p->mode !=1) return; + if(p->new_mode) return; double index=PIC_FullIndex()-p->start; switch (p->mode) { @@ -309,6 +310,7 @@ static void write_p43(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { pit[latch].counterstatus_set=false; latched_timerstatus_locked=false; } + pit[latch].go_read_latch = true; pit[latch].update_count = false; pit[latch].counting = false; pit[latch].read_state = (val >> 4) & 0x03; From 6be8956f463412ae7fb61506ea5e72d0f353cd67 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 4 Apr 2010 18:43:04 +0000 Subject: [PATCH 3479/4131] Add video blanking in vgaonly mode. Used by Alien Carnage and others. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3568 --- include/vga.h | 7 ++++++- src/hardware/vga_attr.cpp | 7 ++++--- src/hardware/vga_draw.cpp | 12 +++++------- src/hardware/vga_other.cpp | 2 +- src/hardware/vga_s3.cpp | 2 +- src/hardware/vga_seq.cpp | 2 ++ 6 files changed, 19 insertions(+), 13 deletions(-) diff --git a/include/vga.h b/include/vga.h index 55abf2f8..1de2b8c9 100644 --- a/include/vga.h +++ b/include/vga.h @@ -262,7 +262,12 @@ typedef struct { Bit8u color_plane_enable; Bit8u color_select; Bit8u index; - Bit8u enabled; + Bit8u disabled; // Used for disabling the screen. + // Bit0: screen disabled by attribute controller index + // Bit1: screen disabled by sequencer index 1 bit 5 + // These are put together in one variable for performance reasons: + // the line drawing function is called maybe 60*480=28800 times/s, + // and we only need to check one variable for zero this way. } VGA_Attr; typedef struct { diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 1f1371b0..9f23b509 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -46,7 +46,7 @@ void VGA_ATTR_SetPalette(Bit8u index,Bit8u val) { Bitu read_p3c0(Bitu /*port*/,Bitu /*iolen*/) { // Wcharts, Win 3.11 & 95 SVGA Bitu retval = attr(index) & 0x1f; - if (attr(enabled)) retval |= 0x20; + if (!(attr(disabled) & 0x1)) retval |= 0x20; return retval; } @@ -54,7 +54,8 @@ void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) { if (!vga.internal.attrindex) { attr(index)=val & 0x1F; vga.internal.attrindex=true; - attr(enabled)=val & 0x20; + if (val & 0x20) attr(disabled) &= ~1; + else attr(disabled) |= 1; /* 0-4 Address of data register to write to port 3C0h or read from port 3C1h 5 If set screen output is enabled and the palette can not be modified, @@ -69,7 +70,7 @@ void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) { case 0x04: case 0x05: case 0x06: case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: - if (!attr(enabled)) VGA_ATTR_SetPalette(attr(index),(Bit8u)val); + if (attr(disabled) & 0x1) VGA_ATTR_SetPalette(attr(index),(Bit8u)val); /* 0-5 Index into the 256 color DAC table. May be modified by 3C0h index 10h and 14h. diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index f24c5d78..a12d9580 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -637,15 +637,13 @@ static void VGA_ProcessSplit() { } static void VGA_DrawSingleLine(Bitu /*blah*/) { - if (vga.attr.enabled) { - Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line ); - RENDER_DrawLine(data); - } else { - // else draw overscan color line - // TODO: black line should be good enough for now - // (DoWhackaDo) + if (GCC_UNLIKELY(vga.attr.disabled)) { + // draw blanked line (DoWhackaDo, Alien Carnage, TV sports Football) memset(TempLine, 0, sizeof(TempLine)); RENDER_DrawLine(TempLine); + } else { + Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line ); + RENDER_DrawLine(data); } vga.draw.address_line++; diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 80143d4f..47b47b14 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -522,7 +522,7 @@ Bitu read_herc_status(Bitu /*port*/,Bitu /*iolen*/) { void VGA_SetupOther(void) { Bitu i; memset( &vga.tandy, 0, sizeof( vga.tandy )); - vga.attr.enabled = true; + vga.attr.disabled = 0; vga.config.bytes_skip=0; //Initialize values common for most machines, can be overwritten diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index c656a4d0..3d428788 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -355,7 +355,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) { switch (reg) { case 0x24: /* attribute controller index (read only) */ case 0x26: - return (vga.attr.enabled?0x20:0x00) | (vga.attr.index&0x1f); + return ((vga.attr.disabled & 1)?0x00:0x20) | (vga.attr.index & 0x1f); case 0x2d: /* Extended Chip ID (high byte of PCI device ID) */ return 0x88; case 0x2e: /* New Chip ID (low byte of PCI device ID) */ diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 33a6604d..edd400a4 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -47,6 +47,8 @@ void write_p3c5(Bitu /*port*/,Bitu val,Bitu iolen) { } else { seq(clocking_mode)=val; } + if (val & 0x20) vga.attr.disabled |= 0x2; + else vga.attr.disabled &= ~0x2; } /* TODO Figure this out :) 0 If set character clocks are 8 dots wide, else 9. From f1be5cbac0fef1e94fc45cad7e54eb8cd687410a Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 4 Apr 2010 18:49:21 +0000 Subject: [PATCH 3480/4131] INT10 support for video blanking Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3569 --- src/ints/int10.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 018e994a..b5b3abe0 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -419,18 +419,24 @@ graphics_chars: LOG(LOG_INT10,LOG_ERROR)("Function 12:Call %2X not handled",reg_bl); reg_al=0x12; break; - case 0x36: /* VGA Refresh control */ + case 0x36: { /* VGA Refresh control */ if (!IS_VGA_ARCH) break; if ((svgaCard==SVGA_S3Trio) && (reg_al>1)) { reg_al=0; break; } - /* - Call disables/enables the vga from outputting video, - don't support it, but fake a success return - */ - reg_al=0x12; + IO_Write(0x3c4,0x1); + Bit8u clocking = IO_Read(0x3c5); + + if (reg_al==0) clocking &= ~0x20; + else clocking |= 0x20; + + IO_Write(0x3c4,0x1); + IO_Write(0x3c5,clocking); + + reg_al=0x12; // success break; + } default: LOG(LOG_INT10,LOG_ERROR)("Function 12:Call %2X not handled",reg_bl); if (machine!=MCH_EGA) reg_al=0; From e8d765b62559e99e48b7165154cab83eb5b043c1 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 4 Apr 2010 18:58:41 +0000 Subject: [PATCH 3481/4131] Add workaround for INT10 text output in ET4000 800x600x4bpp SVGA mode (Gateway 2) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3570 --- src/ints/int10_char.cpp | 13 +++++++++++++ src/ints/int10_put_pixel.cpp | 7 +++++++ 2 files changed, 20 insertions(+) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index a3f7764a..672c0bf9 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -236,6 +236,13 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit EGA16_CopyRow(cul,clr,start,start+nlines,base);break; case M_VGA: VGA_CopyRow(cul,clr,start,start+nlines,base);break; + case M_LIN4: + if ((machine==MCH_VGA) && (svgaCard==SVGA_TsengET4K) && + (CurMode->swidth<=800)) { + // the ET4000 BIOS supports text output in 800x600 SVGA + EGA16_CopyRow(cul,clr,start,start+nlines,base);break; + } + // fall-through default: LOG(LOG_INT10,LOG_ERROR)("Unhandled mode %d for scroll",CurMode->type); } @@ -262,6 +269,12 @@ filling: EGA16_FillRow(cul,clr,start,base,attr);break; case M_VGA: VGA_FillRow(cul,clr,start,base,attr);break; + case M_LIN4: + if ((machine==MCH_VGA) && (svgaCard==SVGA_TsengET4K) && + (CurMode->swidth<=800)) { + EGA16_FillRow(cul,clr,start,base,attr);break; + } + // fall-through default: LOG(LOG_INT10,LOG_ERROR)("Unhandled mode %d for scroll",CurMode->type); } diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 63e08681..0adc4dab 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -94,6 +94,13 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { real_writeb(0xb800,off,old); } break; + case M_LIN4: + if ((machine!=MCH_VGA) || (svgaCard!=SVGA_TsengET4K) || + (CurMode->swidth>800)) { + // the ET4000 BIOS supports text output in 800x600 SVGA (Gateway 2) + // putpixel warining? + break; + } case M_EGA: { /* Set the correct bitmask for the pixel position */ From b055c7a87f91b96e710b707abd39400795e32553 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 4 Apr 2010 21:07:27 +0000 Subject: [PATCH 3482/4131] Fix vsync pulse position for CGA, Hercules, PCJr and Tandy machines. Set the display enable bit for mode 6. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3571 --- src/ints/int10_modes.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index b8eec1b4..e7777e17 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -475,7 +475,7 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) { //Vertical displayed IO_WriteW(crtc_base,0x06 | (CurMode->vdispend) << 8); //Vertical sync position - IO_WriteW(crtc_base,0x07 | (CurMode->vdispend+1) << 8); + IO_WriteW(crtc_base,0x07 | (CurMode->vdispend + ((CurMode->vtotal - CurMode->vdispend)/2)-1) << 8); //Maximum scanline Bit8u scanline,crtpage; scanline=8; @@ -504,7 +504,7 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) { //Setup the special registers for each machine type Bit8u mode_control_list[0xa+1]={ 0x2c,0x28,0x2d,0x29, //0-3 - 0x2a,0x2e,0x16,0x29, //4-7 + 0x2a,0x2e,0x1e,0x29, //4-7 0x2a,0x2b,0x3b //8-a }; Bit8u mode_control_list_pcjr[0xa+1]={ From 8912e7ab6fdfc6cc94208e33f1860828d79d71dd Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 4 Apr 2010 22:39:06 +0000 Subject: [PATCH 3483/4131] -CGA, PCJr, Tandy: Add video blanking, change display start latch timing, sync pulse width correction, -PCJr, Tandy: implement vertical retrace interrupt, -PCJr, CGA: do line-by-line video emulation, -PCJr: support on-screen change of color modes 4medium to 16low (used by Ghostbusters booter), -All machines: only update the video timing when needed (Jungle Hunt, others that synchronize to the video screen might profit), only resize the output window when needed, start up the video more quickly at the beginning. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3572 --- include/vga.h | 12 ++- src/hardware/vga.cpp | 12 ++- src/hardware/vga_draw.cpp | 160 ++++++++++++++++++++++++------------- src/hardware/vga_other.cpp | 20 +++-- src/ints/bios.cpp | 9 --- 5 files changed, 137 insertions(+), 76 deletions(-) diff --git a/include/vga.h b/include/vga.h index 1de2b8c9..af268786 100644 --- a/include/vga.h +++ b/include/vga.h @@ -111,6 +111,12 @@ typedef struct { Bit32u full_enable_and_set_reset; } VGA_Config; +typedef enum { + PART, + LINE, + //EGALINE +} Drawmode; + typedef struct { bool resizing; Bitu width; @@ -144,6 +150,7 @@ typedef struct { double hdend, htotal; double parts; } delay; + Bitu bpp; double aspect_ratio; bool double_scan; bool doublewidth,doubleheight; @@ -156,6 +163,7 @@ typedef struct { Bit8u count,delay; Bit8u enabled; } cursor; + Drawmode mode; bool vret_triggered; } VGA_Draw; @@ -216,7 +224,7 @@ typedef struct { Bit8u htotal; Bit8u hdend; Bit8u hsyncp; - Bit8u syncw; + Bit8u hsyncw; Bit8u vtotal; Bit8u vdend; Bit8u vadjust; @@ -372,8 +380,6 @@ typedef struct { typedef struct { VGAModes mode; /* The mode the vga system is in */ - VGAModes lastmode; - Bits screenflip; Bit8u misc_output; VGA_Draw draw; VGA_Config config; diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 74edb830..c76763dd 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -41,6 +41,12 @@ Bit32u Expand16Table[4][16]; Bit32u FillTable[16]; Bit32u ColorTable[16]; +void VGA_SetModeNow(VGAModes mode) { + if (vga.mode == mode) return; + vga.mode=mode; + VGA_SetupHandlers(); + VGA_StartResize(0); +} void VGA_SetMode(VGAModes mode) { @@ -85,8 +91,10 @@ void VGA_DetermineMode(void) { void VGA_StartResize(Bitu delay /*=50*/) { if (!vga.draw.resizing) { vga.draw.resizing=true; + if (vga.mode==M_ERROR) delay = 5; /* Start a resize after delay (default 50 ms) */ - PIC_AddEvent(VGA_SetupDrawing,(float)delay); + if (delay==0) VGA_SetupDrawing(0); + else PIC_AddEvent(VGA_SetupDrawing,(float)delay); } } @@ -167,8 +175,6 @@ void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3) { void VGA_Init(Section* sec) { // Section_prop * section=static_cast(sec); -// vga.screenflip = section->Get_int("screenflip"); - vga.screenflip = 0; vga.draw.resizing=false; vga.mode=M_ERROR; //For first init SVGA_Setup_Driver(); diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index a12d9580..d08b0677 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -734,6 +734,11 @@ static void VGA_VertInterrupt(Bitu /*val*/) { } } +static void VGA_Other_VertInterrupt(Bitu val) { + if (val) PIC_ActivateIRQ(5); + else PIC_DeActivateIRQ(5); +} + static void VGA_DisplayStartLatch(Bitu /*val*/) { vga.config.real_start=vga.config.display_start & (vga.vmemwrap-1); vga.draw.bytes_skip = vga.config.bytes_skip; @@ -744,43 +749,40 @@ static void VGA_PanningLatch(Bitu /*val*/) { } static void VGA_VerticalTimer(Bitu /*val*/) { - double error = vga.draw.delay.framestart; vga.draw.delay.framestart = PIC_FullIndex(); - error = vga.draw.delay.framestart - error - vga.draw.delay.vtotal; PIC_AddEvent( VGA_VerticalTimer, (float)vga.draw.delay.vtotal ); - //PIC_AddEvent( VGA_VerticalDisplayEnd, (float)vga.draw.delay.vrstart ); - double flip_offset = vga.screenflip/1000.0 + vga.draw.delay.vrstart; - if(flip_offset > vga.draw.delay.vtotal) { + + switch(machine) { + case MCH_PCJR: + case MCH_TANDY: + // PCJr: Vsync is directly connected to the IRQ controller + // Some earlier Tandy models are said to have a vsync interrupt too + PIC_AddEvent(VGA_Other_VertInterrupt, (float)vga.draw.delay.vrstart, 1); + PIC_AddEvent(VGA_Other_VertInterrupt, (float)vga.draw.delay.vrend, 0); + // fall-through + case MCH_CGA: + case MCH_HERC: + // MC6845-powered graphics: Loading the display start latch happens somewhere + // after vsync off and before first visible scanline, so probably here VGA_DisplayStartLatch(0); - } else PIC_AddEvent( VGA_DisplayStartLatch,(float)flip_offset); - PIC_AddEvent(VGA_PanningLatch,(float)vga.draw.delay.vrend); - - // EGA: 82c435 datasheet: interrupt happens at display end - // VGA: checked with scope - // add a little amount of time to make sure the last drawpart has already fired - if (IS_EGAVGA_ARCH) PIC_AddEvent(VGA_VertInterrupt,(float)(vga.draw.delay.vdend + 0.005)); - - if ( GCC_UNLIKELY( vga.draw.parts_left)) { - if (!IS_VGA_ARCH || (svgaCard!=SVGA_None)) { - LOG(LOG_VGAMISC,LOG_NORMAL)( "Parts left: %d", vga.draw.parts_left ); - PIC_RemoveEvents( &VGA_DrawPart ); - RENDER_EndUpdate(); - vga.draw.parts_left = 0; - } + break; + case MCH_VGA: + case MCH_EGA: + PIC_AddEvent(VGA_DisplayStartLatch, (float)vga.draw.delay.vrstart); + PIC_AddEvent(VGA_PanningLatch, (float)vga.draw.delay.vrend); + // EGA: 82c435 datasheet: interrupt happens at display end + // VGA: checked with scope; however disabled by default by jumper on VGA boards + // add a little amount of time to make sure the last drawpart has already fired + PIC_AddEvent(VGA_VertInterrupt,(float)(vga.draw.delay.vdend + 0.005)); + break; + default: + E_Exit("This new machine needs implementation in VGA_VerticalTimer too."); + break; } - //Check if we can actually render, else skip the rest + //Check if we can actually render, else skip the rest (frameskip) if (!RENDER_StartUpdate()) return; - if ( GCC_UNLIKELY( vga.draw.lines_done < vga.draw.lines_total)) { - if (IS_VGA_ARCH && (svgaCard==SVGA_None)) { - while(vga.draw.lines_done < vga.draw.lines_total) - VGA_DrawSingleLine(0); - PIC_RemoveEvents(VGA_DrawSingleLine); - } - } - //TODO Maybe check for an active frame on parts_left and clear that first? - vga.draw.parts_left = vga.draw.parts_total; - vga.draw.lines_done = 0; + vga.draw.address_line = vga.config.hlines_skip; if (IS_EGAVGA_ARCH) { vga.draw.split_line = (Bitu)((vga.config.line_compare+1)/vga.draw.lines_scaled); @@ -862,17 +864,38 @@ static void VGA_VerticalTimer(Bitu /*val*/) { #ifdef VGA_KEEP_CHANGES if (startaddr_changed) VGA_ChangesStart(); #endif + + // check if some lines at the top off the screen are blanked float draw_skip = 0.0; if (GCC_UNLIKELY(vga.draw.vblank_skip)) { draw_skip = (float)(vga.draw.delay.htotal * vga.draw.vblank_skip); vga.draw.address += vga.draw.address_add * (vga.draw.vblank_skip/(vga.draw.address_line_total)); } - if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) PIC_AddEvent(VGA_DrawSingleLine,(float)(vga.draw.delay.htotal/4.0 + draw_skip)); - else PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts + draw_skip,vga.draw.parts_lines); - //VGA_DrawPart( vga.draw.parts_lines ); - //PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts,vga.draw.parts_lines); - //PIC_AddEvent(VGA_DrawPart,(float)(vga.draw.delay.parts/2),vga.draw.parts_lines); //Else tearline in Tyrian and second reality + // add the draw event + switch (vga.draw.mode) { + case PART: + if (GCC_UNLIKELY(vga.draw.parts_left)) { + LOG(LOG_VGAMISC,LOG_NORMAL)( "Parts left: %d", vga.draw.parts_left ); + PIC_RemoveEvents(VGA_DrawPart); + RENDER_EndUpdate(); + } + vga.draw.lines_done = 0; + vga.draw.parts_left = vga.draw.parts_total; + PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts + draw_skip,vga.draw.parts_lines); + break; + case LINE: + if (GCC_UNLIKELY(vga.draw.lines_done < vga.draw.lines_total)) { + LOG(LOG_VGAMISC,LOG_NORMAL)( "Lines left: %d", + vga.draw.lines_total-vga.draw.lines_done); + PIC_RemoveEvents(VGA_DrawSingleLine); + RENDER_EndUpdate(); + } + vga.draw.lines_done = 0; + PIC_AddEvent(VGA_DrawSingleLine,(float)(vga.draw.delay.htotal/4.0 + draw_skip)); + break; + //case EGALINE: + } } void VGA_CheckScanLength(void) { @@ -949,8 +972,25 @@ void VGA_SetupDrawing(Bitu /*val*/) { PIC_RemoveEvents(VGA_DisplayStartLatch); return; } + // set the drawing mode + switch (machine) { + case MCH_CGA: + case MCH_PCJR: + vga.draw.mode = LINE; + break; + case MCH_VGA: + if (svgaCard==SVGA_None) { + vga.draw.mode = LINE; + break; + } + // fall-through + default: + vga.draw.mode = PART; + break; + } + /* Calculate the FPS for this screen */ - float fps; Bitu clock; + double fps; Bitu clock; Bitu htotal, hdend, hbstart, hbend, hrstart, hrend; Bitu vtotal, vdend, vbstart, vbend, vrstart, vrend; Bitu vblank_skip; @@ -1050,17 +1090,13 @@ void VGA_SetupDrawing(Bitu /*val*/) { hbstart = hdend; hbend = htotal; hrstart = vga.other.hsyncp; - hrend = hrstart + (vga.other.syncw & 0xf) ; + hrend = hrstart + vga.other.hsyncw; vga.draw.address_line_total = vga.other.max_scanline + 1; vtotal = vga.draw.address_line_total * (vga.other.vtotal+1)+vga.other.vadjust; vdend = vga.draw.address_line_total * vga.other.vdend; vrstart = vga.draw.address_line_total * vga.other.vsyncp; - vrend = (vga.other.syncw >> 4); - if (!vrend) - vrend = vrstart + 0xf + 1; - else - vrend = vrstart + vrend; + vrend = vrstart + 16; // vsync width is fixed to 16 lines on the MC6845 TODO Tandy vbstart = vdend; vbend = vtotal; vga.draw.double_scan=false; @@ -1088,9 +1124,8 @@ void VGA_SetupDrawing(Bitu /*val*/) { if (!htotal) return; if (!vtotal) return; - fps=(float)clock/(vtotal*htotal); - // The time a complete video frame takes - vga.draw.delay.vtotal = (1000.0 * (double)(vtotal*htotal)) / (double)clock; + // The screen refresh frequency + fps=(double)clock/(vtotal*htotal); // Horizontal total (that's how long a line takes with whistles and bells) vga.draw.delay.htotal = htotal*1000.0/clock; //in milliseconds // Start and End of horizontal blanking @@ -1411,21 +1446,34 @@ void VGA_SetupDrawing(Bitu /*val*/) { } // LOG_MSG("ht %d vt %d ratio %f", htotal, vtotal, aspect_ratio ); - if (( width != vga.draw.width) || (height != vga.draw.height) || - (aspect_ratio != vga.draw.aspect_ratio) || - (vga.mode != vga.lastmode)) { - vga.lastmode = vga.mode; + // need to change the vertical timing? + if (fabs(vga.draw.delay.vtotal - 1000.0 / fps) > 0.0001) { + vga.draw.delay.vtotal = 1000.0 / fps; + VGA_KillDrawing(); + PIC_RemoveEvents(VGA_Other_VertInterrupt); PIC_RemoveEvents(VGA_VerticalTimer); PIC_RemoveEvents(VGA_PanningLatch); PIC_RemoveEvents(VGA_DisplayStartLatch); - PIC_RemoveEvents(VGA_DrawPart); - PIC_RemoveEvents(VGA_DrawSingleLine); + VGA_VerticalTimer(0); + } + + // need to resize the output window? + if ((width != vga.draw.width) || + (height != vga.draw.height) || + (vga.draw.doublewidth != doublewidth) || + (vga.draw.doubleheight != doubleheight) || + (abs(aspect_ratio - vga.draw.aspect_ratio) > 0.0001) || + (vga.draw.bpp != bpp)) { + + VGA_KillDrawing(); + vga.draw.width = width; vga.draw.height = height; vga.draw.doublewidth = doublewidth; vga.draw.doubleheight = doubleheight; vga.draw.aspect_ratio = aspect_ratio; vga.draw.vblank_skip = vblank_skip; + vga.draw.bpp = bpp; if (doubleheight) vga.draw.lines_scaled=2; else vga.draw.lines_scaled=1; #if C_DEBUG @@ -1433,14 +1481,14 @@ void VGA_SetupDrawing(Bitu /*val*/) { LOG(LOG_VGA,LOG_NORMAL)("%s width, %s height aspect %f", doublewidth ? "double":"normal",doubleheight ? "double":"normal",aspect_ratio); #endif - RENDER_SetSize(width,height,bpp,fps,aspect_ratio,doublewidth,doubleheight); - vga.draw.delay.framestart = PIC_FullIndex(); - PIC_AddEvent( VGA_VerticalTimer , (float)vga.draw.delay.vtotal ); - vga.draw.lines_done = 0; + RENDER_SetSize(width,height,bpp,(float)fps,aspect_ratio,doublewidth,doubleheight); } } void VGA_KillDrawing(void) { PIC_RemoveEvents(VGA_DrawPart); PIC_RemoveEvents(VGA_DrawSingleLine); + vga.draw.parts_left = 0; + vga.draw.lines_done = ~0; + RENDER_EndUpdate(); } diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 47b47b14..c4b9b70e 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -49,8 +49,10 @@ static void write_crtc_data_other(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { case 0x02: //Horizontal sync position vga.other.hsyncp=(Bit8u)val; break; - case 0x03: //Horizontal and vertical sync width - vga.other.syncw=(Bit8u)val; + case 0x03: //Horizontal sync width + if (machine==MCH_TANDY) vga.other.vsyncw=(Bit8u)(val >> 4); + else vga.other.vsyncw = 16; // The MC6845 has a fixed v-sync width of 16 lines + vga.other.hsyncw=(Bit8u)(val & 0xf); break; case 0x04: //Vertical total if (vga.other.vtotal ^ val) VGA_StartResize(); @@ -116,7 +118,9 @@ static Bitu read_crtc_data_other(Bitu /*port*/,Bitu /*iolen*/) { case 0x02: //Horizontal sync position return vga.other.hsyncp; case 0x03: //Horizontal and vertical sync width - return vga.other.syncw; + if (machine==MCH_TANDY) + return vga.other.hsyncw | (vga.other.vsyncw << 4); + else return vga.other.hsyncw; case 0x04: //Vertical total return vga.other.vtotal; case 0x05: //Vertical display adjust @@ -278,17 +282,21 @@ static void TANDY_FindMode(void) { } } +void VGA_SetModeNow(VGAModes mode); + static void PCJr_FindMode(void) { if (vga.tandy.mode_control & 0x2) { if (vga.tandy.mode_control & 0x10) { /* bit4 of mode control 1 signals 16 colour graphics mode */ - VGA_SetMode(M_TANDY16); + if (vga.mode==M_TANDY4) VGA_SetModeNow(M_TANDY16); // TODO lowres mode only + else VGA_SetMode(M_TANDY16); } else if (vga.tandy.gfx_control & 0x08) { /* bit3 of mode control 2 signals 2 colour graphics mode */ VGA_SetMode(M_TANDY2); } else { /* otherwise some 4-colour graphics mode */ - VGA_SetMode(M_TANDY4); + if (vga.mode==M_TANDY16) VGA_SetModeNow(M_TANDY4); + else VGA_SetMode(M_TANDY4); } write_color_select(vga.tandy.color_select); } else { @@ -318,6 +326,7 @@ static void write_tandy_reg(Bit8u val) { vga.tandy.mode_control=val; VGA_SetBlinking(val & 0x20); PCJr_FindMode(); + vga.attr.disabled = (val&0x8)? 0: 1; } else { LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index); } @@ -359,6 +368,7 @@ static void write_cga(Bitu port,Bitu val,Bitu /*iolen*/) { switch (port) { case 0x3d8: vga.tandy.mode_control=(Bit8u)val; + vga.attr.disabled = (val&0x8)? 0: 1; if (vga.tandy.mode_control & 0x2) { if (vga.tandy.mode_control & 0x10) { if (!(val & 0x4) && machine==MCH_CGA) { diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 4190b8a4..a61bfe5d 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -826,13 +826,6 @@ void BIOS_ZeroExtendedSize(bool in) { if(other_memsystems < 0) other_memsystems=0; } -#define RAM_REFRESH_DELAY 16.7f - -static void RAMRefresh_Event(Bitu /*val*/) { - PIC_ActivateIRQ(5); - PIC_AddEvent(RAMRefresh_Event,RAM_REFRESH_DELAY); -} - void BIOS_SetupKeyboard(void); void BIOS_SetupDisks(void); @@ -1085,8 +1078,6 @@ public: size_extended=IO_Read(0x71); IO_Write(0x70,0x31); size_extended|=(IO_Read(0x71) << 8); - - if (machine==MCH_PCJR) PIC_AddEvent(RAMRefresh_Event,RAM_REFRESH_DELAY); } ~BIOS(){ /* abort DAC playing */ From 2649b91f6ff8461d205928173bf18703876fa665 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 5 Apr 2010 07:06:57 +0000 Subject: [PATCH 3484/4131] Add include for abs. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3573 --- src/hardware/vga_draw.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index d08b0677..7f9aa51a 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -20,6 +20,7 @@ #include #include +#include #include "dosbox.h" #include "video.h" #include "render.h" From 6080d2c1dd5cd1236b7c1439198f9a1cec432e67 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 5 Apr 2010 10:01:23 +0000 Subject: [PATCH 3485/4131] Change exits to warnings. Improve childpsp a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3574 --- src/dos/dos_execute.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 8db998c3..ca9e5595 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -213,8 +213,12 @@ bool DOS_NewPSP(Bit16u segment, Bit16u size) { bool DOS_ChildPSP(Bit16u segment, Bit16u size) { DOS_PSP psp(segment); psp.MakeNew(size); - DOS_PSP psp_parent(psp.GetParent()); + Bit16u parent_psp_seg = psp.GetParent(); + DOS_PSP psp_parent(parent_psp_seg); psp.CopyFileTable(&psp_parent,true); + psp.SetCommandTail(RealMake(parent_psp_seg,0x80)); + psp.SetFCB1(RealMake(parent_psp_seg,0x5c)); + psp.SetFCB2(RealMake(parent_psp_seg,0x6c)); psp.SetEnvironment(psp_parent.GetEnvironment()); psp.SetSize(size); return true; @@ -412,7 +416,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { } else { csip=RealMake(loadseg+head.initCS,head.initIP); sssp=RealMake(loadseg+head.initSS,head.initSP); - if (head.initSP<4) E_Exit("stack underflow/wrap at EXEC"); + if (head.initSP<4) LOG(LOG_EXEC,LOG_ERROR)("stack underflow/wrap at EXEC"); } if (flags==LOAD) { @@ -434,7 +438,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { } if (flags==LOADNGO) { - if ((reg_sp>0xfffe) || (reg_sp<18)) E_Exit("stack underflow/wrap at EXEC"); + if ((reg_sp>0xfffe) || (reg_sp<18)) LOG(LOG_EXEC,LOG_ERROR)("stack underflow/wrap at EXEC"); /* Get Caller's program CS:IP of the stack and set termination address to that */ RealSetVec(0x22,RealMake(mem_readw(SegPhys(ss)+reg_sp+2),mem_readw(SegPhys(ss)+reg_sp))); SaveRegisters(); From dae804a87f9d09d240beeb53c0b11453454a62d3 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Mon, 5 Apr 2010 10:13:18 +0000 Subject: [PATCH 3486/4131] - Move the video timing debug output so it can display the correct v_total value Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3575 --- src/hardware/vga_draw.cpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 7f9aa51a..16b270eb 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -28,6 +28,10 @@ #include "vga.h" #include "pic.h" +//#undef C_DEBUG +//#define C_DEBUG 1 +//#define LOG(X,Y) LOG_MSG + #define VGA_PARTS 4 typedef Bit8u * (* VGA_Line_Handler)(Bitu vidstart, Bitu line); @@ -1176,17 +1180,6 @@ void VGA_SetupDrawing(Bitu /*val*/) { // Display end vga.draw.delay.vdend = vdend * vga.draw.delay.htotal; -#if C_DEBUG - LOG(LOG_VGA,LOG_NORMAL)("h total %2.5f (%3.2fkHz) blank(%02.5f/%02.5f) retrace(%02.5f/%02.5f)", - vga.draw.delay.htotal,(1.0/vga.draw.delay.htotal), - vga.draw.delay.hblkstart,vga.draw.delay.hblkend, - vga.draw.delay.hrstart,vga.draw.delay.hrend); - LOG(LOG_VGA,LOG_NORMAL)("v total %2.5f (%3.2fHz) blank(%02.5f/%02.5f) retrace(%02.5f/%02.5f)", - vga.draw.delay.vtotal,(1000.0/vga.draw.delay.vtotal), - vga.draw.delay.vblkstart,vga.draw.delay.vblkend, - vga.draw.delay.vrstart,vga.draw.delay.vrend); -#endif - vga.draw.parts_total=VGA_PARTS; /* 6 Horizontal Sync Polarity. Negative if set @@ -1458,6 +1451,17 @@ void VGA_SetupDrawing(Bitu /*val*/) { VGA_VerticalTimer(0); } +#if C_DEBUG + LOG(LOG_VGA,LOG_NORMAL)("h total %2.5f (%3.2fkHz) blank(%02.5f/%02.5f) retrace(%02.5f/%02.5f)", + vga.draw.delay.htotal,(1.0/vga.draw.delay.htotal), + vga.draw.delay.hblkstart,vga.draw.delay.hblkend, + vga.draw.delay.hrstart,vga.draw.delay.hrend); + LOG(LOG_VGA,LOG_NORMAL)("v total %2.5f (%3.2fHz) blank(%02.5f/%02.5f) retrace(%02.5f/%02.5f)", + vga.draw.delay.vtotal,(1000.0/vga.draw.delay.vtotal), + vga.draw.delay.vblkstart,vga.draw.delay.vblkend, + vga.draw.delay.vrstart,vga.draw.delay.vrend); +#endif + // need to resize the output window? if ((width != vga.draw.width) || (height != vga.draw.height) || From 74ddc23daf1400c2560c3bd96bd9f4759e75b5b6 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Wed, 7 Apr 2010 21:07:17 +0000 Subject: [PATCH 3487/4131] Allow the renderer to abort a screen. Fixes crashes occurring with certain output modes, platforms and games. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3576 --- include/render.h | 2 +- src/gui/render.cpp | 4 ++-- src/hardware/vga_draw.cpp | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/render.h b/include/render.h index bbfd90eb..1d703e2e 100644 --- a/include/render.h +++ b/include/render.h @@ -91,7 +91,7 @@ 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_EndUpdate(bool abort); void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue); diff --git a/src/gui/render.cpp b/src/gui/render.cpp index c76047c1..1ba60975 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -201,7 +201,7 @@ static void RENDER_Halt( void ) { } extern Bitu PIC_Ticks; -void RENDER_EndUpdate( void ) { +void RENDER_EndUpdate( bool abort ) { if (GCC_UNLIKELY(!render.updating)) return; RENDER_DrawLine = RENDER_EmptyLineHandler; @@ -220,7 +220,7 @@ void RENDER_EndUpdate( void ) { flags, fps, (Bit8u *)&scalerSourceCache, (Bit8u*)&render.pal.rgb ); } if ( render.scale.outWrite ) { - GFX_EndUpdate( Scaler_ChangedLines ); + GFX_EndUpdate( abort? NULL : Scaler_ChangedLines ); render.frameskip.hadSkip[render.frameskip.index] = 0; } else { #if 0 diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 16b270eb..e981da0e 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -660,7 +660,7 @@ static void VGA_DrawSingleLine(Bitu /*blah*/) { if (vga.draw.split_line==vga.draw.lines_done) VGA_ProcessSplit(); if (vga.draw.lines_done < vga.draw.lines_total) { PIC_AddEvent(VGA_DrawSingleLine,(float)vga.draw.delay.htotal); - } else RENDER_EndUpdate(); + } else RENDER_EndUpdate(false); } static void VGA_DrawPart(Bitu lines) { @@ -690,7 +690,7 @@ static void VGA_DrawPart(Bitu lines) { #ifdef VGA_KEEP_CHANGES VGA_ChangesEnd(); #endif - RENDER_EndUpdate(); + RENDER_EndUpdate(false); } } @@ -883,7 +883,7 @@ static void VGA_VerticalTimer(Bitu /*val*/) { if (GCC_UNLIKELY(vga.draw.parts_left)) { LOG(LOG_VGAMISC,LOG_NORMAL)( "Parts left: %d", vga.draw.parts_left ); PIC_RemoveEvents(VGA_DrawPart); - RENDER_EndUpdate(); + RENDER_EndUpdate(true); } vga.draw.lines_done = 0; vga.draw.parts_left = vga.draw.parts_total; @@ -894,7 +894,7 @@ static void VGA_VerticalTimer(Bitu /*val*/) { LOG(LOG_VGAMISC,LOG_NORMAL)( "Lines left: %d", vga.draw.lines_total-vga.draw.lines_done); PIC_RemoveEvents(VGA_DrawSingleLine); - RENDER_EndUpdate(); + RENDER_EndUpdate(true); } vga.draw.lines_done = 0; PIC_AddEvent(VGA_DrawSingleLine,(float)(vga.draw.delay.htotal/4.0 + draw_skip)); @@ -1495,5 +1495,5 @@ void VGA_KillDrawing(void) { PIC_RemoveEvents(VGA_DrawSingleLine); vga.draw.parts_left = 0; vga.draw.lines_done = ~0; - RENDER_EndUpdate(); + RENDER_EndUpdate(true); } From 2dff0226b9a1a0a15e30677f40900467d1d09e6f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 8 Apr 2010 14:29:55 +0000 Subject: [PATCH 3488/4131] Reverse revision 3567 as it breaks a few games and the new patch could use some more testing. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3577 --- src/hardware/timer.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 8ceb42d5..a4a7c503 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -139,7 +139,6 @@ static void counter_latch(Bitu counter) { //If gate2 is disabled don't update the read_latch if(counter == 2 && !gate2 && p->mode !=1) return; - if(p->new_mode) return; double index=PIC_FullIndex()-p->start; switch (p->mode) { @@ -310,7 +309,6 @@ static void write_p43(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { pit[latch].counterstatus_set=false; latched_timerstatus_locked=false; } - pit[latch].go_read_latch = true; pit[latch].update_count = false; pit[latch].counting = false; pit[latch].read_state = (val >> 4) & 0x03; From d40f71fc4559910c6c4ccecd038db7e344e4afc2 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Mon, 12 Apr 2010 10:37:59 +0000 Subject: [PATCH 3489/4131] Fix warnings (thanks ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3578 --- src/hardware/vga_draw.cpp | 3 +-- src/libs/gui_tk/gui_tk.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index e981da0e..d3970fa3 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -20,7 +20,6 @@ #include #include -#include #include "dosbox.h" #include "video.h" #include "render.h" @@ -1467,7 +1466,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { (height != vga.draw.height) || (vga.draw.doublewidth != doublewidth) || (vga.draw.doubleheight != doubleheight) || - (abs(aspect_ratio - vga.draw.aspect_ratio) > 0.0001) || + (fabs(aspect_ratio - vga.draw.aspect_ratio) > 0.0001) || (vga.draw.bpp != bpp)) { VGA_KillDrawing(); diff --git a/src/libs/gui_tk/gui_tk.cpp b/src/libs/gui_tk/gui_tk.cpp index 0ba88eb6..03b64a9c 100644 --- a/src/libs/gui_tk/gui_tk.cpp +++ b/src/libs/gui_tk/gui_tk.cpp @@ -1704,4 +1704,4 @@ int main(int argc, char *argv[]) } #endif -#endif \ No newline at end of file +#endif From f3c1902dab4e656a6a8eca895f7cb416fe7b458e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 15 Apr 2010 13:22:21 +0000 Subject: [PATCH 3490/4131] Add green/amber hercules mode emulation support. (Thanks ripsaw and h-a-l-9000) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3579 --- include/vga.h | 2 ++ src/hardware/vga_other.cpp | 26 ++++++++++++++++++++++++++ src/ints/int10_modes.cpp | 1 + src/shell/shell.cpp | 4 ++++ 4 files changed, 33 insertions(+) diff --git a/include/vga.h b/include/vga.h index af268786..a3d02c20 100644 --- a/include/vga.h +++ b/include/vga.h @@ -408,6 +408,8 @@ typedef struct { } VGA_Type; +/* Hercules Palette function */ +void Herc_Palette(void); /* Functions for different resolutions */ void VGA_SetMode(VGAModes mode); diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index c4b9b70e..98d29395 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -156,6 +156,7 @@ static Bitu read_crtc_data_other(Bitu /*port*/,Bitu /*iolen*/) { static double hue_offset = 0.0; static Bit8u cga16_val = 0; static void update_cga16_color(void); +static Bit8u herc_pal = 0; static void cga16_color_select(Bit8u val) { cga16_val = val; @@ -456,6 +457,30 @@ static void write_pcjr(Bitu port,Bitu val,Bitu /*iolen*/) { } } +static void CycleHercPal(bool pressed) { + if (!pressed) return; + if (++herc_pal>2) herc_pal=0; + Herc_Palette(); + VGA_DAC_CombineColor(1,7); +} + +void Herc_Palette(void) { + switch (herc_pal) { + case 0: // White + VGA_DAC_SetEntry(0x7,0x2a,0x2a,0x2a); + VGA_DAC_SetEntry(0xf,0x3f,0x3f,0x3f); + break; + case 1: // Amber + VGA_DAC_SetEntry(0x7,0x37,0x28,0x00); + VGA_DAC_SetEntry(0xf,0x3f,0x34,0x00); + break; + case 2: // Green + VGA_DAC_SetEntry(0x7,0x00,0x26,0x00); + VGA_DAC_SetEntry(0xf,0x00,0x3f,0x00); + break; + } +} + static void write_hercules(Bitu port,Bitu val,Bitu /*iolen*/) { switch (port) { case 0x3b8: { @@ -551,6 +576,7 @@ void VGA_SetupOther(void) { extern Bit8u int10_font_14[256 * 14]; for (i=0;i<256;i++) memcpy(&vga.draw.font[i*32],&int10_font_14[i*14],14); vga.draw.font_tables[0]=vga.draw.font_tables[1]=vga.draw.font; + MAPPER_AddHandler(CycleHercPal,MK_f11,0,"hercpal","Herc Pal"); } if (machine==MCH_CGA) { IO_RegisterWriteHandler(0x3d8,write_cga,IO_MB); diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index e7777e17..54fdaccb 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -517,6 +517,7 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) { case MCH_HERC: IO_WriteB(0x3b8,0x28); // TEXT mode and blinking characters + Herc_Palette(); VGA_DAC_CombineColor(0,0); VGA_DAC_CombineColor(1,7); diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 41d98cb0..90649c05 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -302,6 +302,7 @@ void DOS_Shell::Run(void) { WriteOut(MSG_Get("SHELL_STARTUP_DEBUG")); #endif if (machine == MCH_CGA) WriteOut(MSG_Get("SHELL_STARTUP_CGA")); + if (machine == MCH_HERC) WriteOut(MSG_Get("SHELL_STARTUP_HERC")); WriteOut(MSG_Get("SHELL_STARTUP_END")); if (cmd->FindString("/INIT",line,true)) { @@ -508,6 +509,9 @@ void SHELL_Init() { "\xBA Use \033[31m(alt-)F11\033[37m to change the colours when in this mode. \xBA\n" "\xBA \xBA\n" ); + MSG_Add("SHELL_STARTUP_HERC","\xBA Use \033[31mF11\033[37m to cycle through white, amber, and green monochrome color. \xBA\n" + "\xBA \xBA\n" + ); MSG_Add("SHELL_STARTUP_DEBUG", "\xBA Press \033[31malt-Pause\033[37m to enter the debugger or start the exe with \033[33mDEBUG\033[37m. \xBA\n" "\xBA \xBA\n" From ec873a5445375bf2afd0cd20f37169672506cccf Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 15 Apr 2010 18:18:16 +0000 Subject: [PATCH 3491/4131] Clarify alt-f12 a bit. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3580 --- README | 4 ++-- src/dos/dos_programs.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README b/README index 5a5849d6..22e2195e 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -DOSBox v0.73 +DOSBox v0.74 ===== @@ -894,7 +894,7 @@ CTRL-F9 Kill DOSBox. CTRL-F10 Capture/Release the mouse. CTRL-F11 Slow down emulation (Decrease DOSBox Cycles). CTRL-F12 Speed up emulation (Increase DOSBox Cycles). -ALT-F12 Unlock speed (turbo button). +ALT-F12 Unlock speed (turbo button/fast forward). (NOTE: Once you increase your DOSBox cycles beyond your computer's maximum capacity, it will produce the same effect as slowing down the emulation. diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 7d3d3a7b..5f237186 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1478,7 +1478,7 @@ void DOS_SetupPrograms(void) { "\033[33;1mCTRL-F10\033[0m : Capture/Release the mouse.\n" "\033[33;1mCTRL-F11\033[0m : Slow down emulation (Decrease DOSBox Cycles).\n" "\033[33;1mCTRL-F12\033[0m : Speed up emulation (Increase DOSBox Cycles).\n" - "\033[33;1mALT-F12\033[0m : Unlock speed (turbo button).\n" + "\033[33;1mALT-F12\033[0m : Unlock speed (turbo button/fast forward).\n" ); MSG_Add("PROGRAM_BOOT_NOT_EXIST","Bootdisk file does not exist. Failing.\n"); MSG_Add("PROGRAM_BOOT_NOT_OPEN","Cannot open bootdisk file. Failing.\n"); From 8f9bd1b72c7989090da75824faab2b2cd138ab12 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 15 Apr 2010 18:19:21 +0000 Subject: [PATCH 3492/4131] Reduce focus on frameskip, increase focus on control. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3581 --- src/shell/shell.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 90649c05..8f379b2f 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -500,7 +500,7 @@ void SHELL_Init() { "\xBA For a short introduction for new users type: \033[33mINTRO\033[37m \xBA\n" "\xBA For supported shell commands type: \033[33mHELP\033[37m \xBA\n" "\xBA \xBA\n" - "\xBA If you want more speed, try \033[31mctrl-F8\033[37m and \033[31mctrl-F12\033[37m. \xBA\n" + "\xBA To adjust the emulated CPU speed, use \033[31mctrl-F11\033[37m and \033[31mctrl-F12\033[37m. \xBA\n" "\xBA To activate the keymapper \033[31mctrl-F1\033[37m. \xBA\n" "\xBA For more information read the \033[36mREADME\033[37m file in the DOSBox directory. \xBA\n" "\xBA \xBA\n" From e514702c4b8d914ccfbce6a8dc76f48cd974bf69 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 15 Apr 2010 18:30:40 +0000 Subject: [PATCH 3493/4131] Add some changes from the scummvm team Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3582 --- src/hardware/dbopl.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index df1c7548..56153353 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -619,6 +619,7 @@ Operator::Operator() { currentLevel = ENV_MAX; totalLevel = ENV_MAX; volume = ENV_MAX; + releaseAdd = 0; } /* @@ -1176,9 +1177,7 @@ Bit32u Chip::WriteAddr( Bit32u port, Bit8u val ) { void Chip::GenerateBlock2( Bitu total, Bit32s* output ) { while ( total > 0 ) { Bit32u samples = ForwardLFO( total ); - for ( Bitu i = 0; i < samples; i++ ) { - output[i] = 0; - } + memset(output, 0, sizeof(Bit32s) * samples); int count = 0; for( Channel* ch = chan; ch < chan + 9; ) { count++; @@ -1192,10 +1191,7 @@ void Chip::GenerateBlock2( Bitu total, Bit32s* output ) { void Chip::GenerateBlock3( Bitu total, Bit32s* output ) { while ( total > 0 ) { Bit32u samples = ForwardLFO( total ); - for ( Bitu i = 0; i < samples; i++ ) { - output[i * 2 + 0 ] = 0; - output[i * 2 + 1 ] = 0; - } + memset(output, 0, sizeof(Bit32s) * samples *2); int count = 0; for( Channel* ch = chan; ch < chan + 18; ) { count++; From 13e829e8c973217515a82ab3b6f116cf511fd3b5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 15 Apr 2010 18:51:31 +0000 Subject: [PATCH 3494/4131] Updates.... Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3583 --- ChangeLog | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 270019fd..e5d36f97 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,6 +22,7 @@ you exit dosbox without stopping the movie. - Change RGB3x scaler to look more pretty. - Improve initial register values compatility of the GUS. + - Added autodetection for Gameblaster. (games can find it now) - Change render preferences a bit to be more compatible with windows 7. - Add DOS fixes to terminate program. (Fixes fortune teller) - Add FFREEP. (Fixes trucks) @@ -32,6 +33,15 @@ - Modify game specific hacks a bit so that Kick off 3 works again. - Lots of fixes to the INT10 video parameter table. (Seven spirits of ra and others) + - Add vga blanking in machine=vgaonly. (Used by Alien Carnage) + - CGA, PCJr, Tandy: Add video blanking, change display start latch + timing, sync pulse width correction, + - PCJr, Tandy: implement vertical retrace interrupt, + - PCJr, CGA: do line-by-line video emulation, + - PCJr: support on-screen change of color modes 4medium to 16low (used + by Ghostbusters booter), + - All machines: only update the video timing when needed (Jungle Hunt, + others that synchronize to the video screen might profit). - Several small DOS fixes. - Some UMB related fixes. ( The Legacy without umb) - Fix version number of DSP for SB 1.5. (fixes a few games) @@ -57,8 +67,8 @@ - Fix compilation with new MAC os X version. - Add 16C550A FIFO support to the serial port emulation. - Improve modem emulation to get higher speeds. - - Change default samplerates to 44100, so that hopefully certain - soundcards produce more fluent sound playback. + - Change default samplerates to 44100, blocksize to 1024 and prebuffer to 20, + so that hopefully certain soundcards produce more fluent sound playback. - Add some rarely used, but for some games critical flags to the internal commands. - Improve internal timing with repeatings timers (especially with From 66b3f5f76102437d6157cdb922138a3a344c191d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 20 Apr 2010 07:45:34 +0000 Subject: [PATCH 3495/4131] Fix by h-a-l-9000 to repair the blanking functionality. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3584 --- src/hardware/vga_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index d3970fa3..33ee8cdb 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1413,6 +1413,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { } doubleheight=true; } + vga.draw.vblank_skip = vblank_skip; if(!(IS_VGA_ARCH && (svgaCard==SVGA_None) && (vga.mode==M_EGA || vga.mode==M_VGA))) { //Only check for extra double height in vga modes @@ -1476,7 +1477,6 @@ void VGA_SetupDrawing(Bitu /*val*/) { vga.draw.doublewidth = doublewidth; vga.draw.doubleheight = doubleheight; vga.draw.aspect_ratio = aspect_ratio; - vga.draw.vblank_skip = vblank_skip; vga.draw.bpp = bpp; if (doubleheight) vga.draw.lines_scaled=2; else vga.draw.lines_scaled=1; From 1fb9c76ae67d5b5818baf3c6d4aa6179888c6260 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 20 Apr 2010 11:17:31 +0000 Subject: [PATCH 3496/4131] change wording Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3585 --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e5d36f97..1e1fe610 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,7 +17,7 @@ - Some hercules fixes (Testdrive) - Improve support for blanked parts that wrap around to the start of the screen. (Fixes Magic Circle demo and Sid&Al) - - Remove old opl cores as the new ones seem work very nice. + - Remove old opl cores as the new ones seem to work very nicely. - Modify movie recording code so that the movies aren't corrupt when you exit dosbox without stopping the movie. - Change RGB3x scaler to look more pretty. From c38194f08ffcb774c1250faa5fbf7e707e083263 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Tue, 20 Apr 2010 12:51:03 +0000 Subject: [PATCH 3497/4131] Update authors Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3586 --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index c7f46225..eb365e5d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -7,5 +7,6 @@ Ulf Wohlers Tommy Frössman Dean Beeler Sebastian Strohhäcker +Ralf Grillenberger nick_without_<> @ users.sourceforge.net From 5bf92b4017f35f9050350f7f890fe625f00a8b25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 25 Apr 2010 21:02:38 +0000 Subject: [PATCH 3498/4131] small updates, consistency of changelog entries Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3587 --- ChangeLog | 76 +++++++++++++++++++++++++++---------------------------- README | 10 +++----- 2 files changed, 42 insertions(+), 44 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1e1fe610..d2288bfb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,68 +1,68 @@ 0.74 - Several small game specific fixes/hacks/support. (Offensive, Roadhog, GTA installer, Kingdom O' Magic soundcard detection, - Pirate booter, armored fist installer) - - Add the S3-specific 640x480 256 color mode. Fixes regression in "Wooden - Ships and Iron Men" and "I Have No Mouth And I Must Scream". + Pirate booter, Armored Fist installer) + - Add the S3-specific 640x480 256 color mode. (fixes regression in "Wooden + Ships and Iron Men" and "I Have No Mouth And I Must Scream") - Fix a stack overflow that could crash DOSBox. - - Add fake microphone input. (Fixes Talking Parrot) + - Add fake microphone input. (fixes Talking Parrot) - Modify adlib turn off code, so that it doesn't turn off in cases where the same sound is repeated over and over again. - Several small fixes to the CDROM audio code. (HOMM2, Redneck Rampage and others) - Several improvements to the CDROM emulation code. (fixes Alpha Storm and GT Racing 97) - - Some small cpu fixes that might fix something. - - Handle opcode 0xff subcode 7 as invalid instruction, fixes dif-2 & others. - - Some hercules fixes (Testdrive) + - Some small CPU fixes that might fix something. + - Handle opcode 0xff subcode 7 as invalid instruction. (fixes dif-2 & others) + - Some hercules fixes. (Testdrive) - Improve support for blanked parts that wrap around to the start of - the screen. (Fixes Magic Circle demo and Sid&Al) - - Remove old opl cores as the new ones seem to work very nicely. + the screen. (fixes Magic Circle demo and Sid&Al) + - Remove old OPL cores as the new ones seem to work very nicely. - Modify movie recording code so that the movies aren't corrupt when you exit dosbox without stopping the movie. - Change RGB3x scaler to look more pretty. - Improve initial register values compatility of the GUS. - Added autodetection for Gameblaster. (games can find it now) - - Change render preferences a bit to be more compatible with windows 7. - - Add DOS fixes to terminate program. (Fixes fortune teller) - - Add FFREEP. (Fixes trucks) - - Improve FPU ST80 in C mode when writing zero. (Fixes antigok) - - Add special int10 scanline function. (Fixes mz700 and probably lots + - Change render preferences a bit to be more compatible with Windows 7. + - Add DOS fixes to terminate program. (fixes Fortune Teller) + - Add FFREEP. (fixes Trucks) + - Improve FPU ST80 in C mode when writing zero. (fixes Antigok) + - Add special int10 scanline function. (fixes mz700 and probably lots of games that mess with them) - - Fix scrolling in rarely used video modes. (Fixes Orphee) + - Fix scrolling in rarely used video modes. (fixes Orphee) - Modify game specific hacks a bit so that Kick off 3 works again. - Lots of fixes to the INT10 video parameter table. (Seven spirits of ra and others) - - Add vga blanking in machine=vgaonly. (Used by Alien Carnage) + - Add VGA blanking in machine=vgaonly. (used by Alien Carnage) - CGA, PCJr, Tandy: Add video blanking, change display start latch - timing, sync pulse width correction, - - PCJr, Tandy: implement vertical retrace interrupt, - - PCJr, CGA: do line-by-line video emulation, - - PCJr: support on-screen change of color modes 4medium to 16low (used - by Ghostbusters booter), - - All machines: only update the video timing when needed (Jungle Hunt, - others that synchronize to the video screen might profit). + timing, sync pulse width correction. + - PCJr, Tandy: implement vertical retrace interrupt. + - PCJr, CGA: line-by-line video emulation. + - PCJr: support on-screen change of color modes 4medium to 16low. (used + by Ghostbusters booter) + - All machines: only update the video timing when needed. (Jungle Hunt, + others that synchronize to the video screen might profit) - Several small DOS fixes. - - Some UMB related fixes. ( The Legacy without umb) + - Some UMB related fixes. (The Legacy without UMB) - Fix version number of DSP for SB 1.5. (fixes a few games) - - Several vga emulation improvements (Allertone football manager) - - Some tandy fixes. (mech warrior) + - Several VGA emulation improvements. (Allertone football manager) + - Some Tandy fixes. (Mech Warrior) - Small improvements and fixes to the OPL emulation. - - Add low Level tandy DAC emulation. - - Some EMS fixes. (Fixes Mortal Kombat and others) - - Change SoundBlaster DSP reset mechanism, add sb irq acknowledge logic - (fixes stmik-based applications). - - Some interrupt pointer location modifications. (fixes tinker tales) - - Some fixes to the BOOT code. (fixes last mission) - - Respect write-only. (fixes champions of zulala) - - Some RTC fix. (Fixes Tully Bodine and others) + - Add low level Tandy DAC emulation. + - Some EMS fixes. (fixes Mortal Kombat and others) + - Change SoundBlaster DSP reset mechanism, add sb irq acknowledge logic. + (fixes stmik-based applications) + - Some interrupt pointer location modifications. (fixes Tinker Tales) + - Some fixes to the BOOT code. (fixes Last Mission) + - Respect write-only file information. (fixes Champions of Zulala) + - Some RTC fix. (fixes Tully Bodine and others) - Improve mouse emulation to work better with Water World. - Hopefully fix the translation of the configuration file. - Speed up and fixes for the recompiler core. (pitfall2 pcjr) - - Change memory start location. (Fixes 7th Guest installer) - - Several fixes to the BAT files handling. (Shift and + - Change memory start location. (fixes 7th Guest installer) + - Several fixes to the batch file handling. (Shift and use the typed first %0 instead of the parsed %0) - - Improve file redirection and redirected line ends. (Fixes + - Improve file redirection and redirected line ends. (fixes Phantasmagoria 2 DOS installer) - Fix compilation with new MAC os X version. - Add 16C550A FIFO support to the serial port emulation. @@ -71,7 +71,7 @@ so that hopefully certain soundcards produce more fluent sound playback. - Add some rarely used, but for some games critical flags to the internal commands. - - Improve internal timing with repeatings timers (especially with + - Improve internal timing with repeating timers (especially with the dynamic core). 0.73 diff --git a/README b/README index 22e2195e..fcda785f 100644 --- a/README +++ b/README @@ -112,7 +112,7 @@ A: To mount your CD-ROM in DOSBox you have to specify some additional options To enable SDL-support (does not include low-level CD access!): - mount d f:\ -t cdrom -usecd 0 -noioctl To enable ioctl access using digital audio extraction for CD audio - (windows-only, useful for Vista): + (windows-only, useful for Vista and above): - mount d f:\ -t cdrom -ioctl_dx To enable ioctl access using MCI for CD audio (windows-only): - mount d f:\ -t cdrom -ioctl_mci @@ -246,9 +246,7 @@ A: DOSBox emulates several legacy sound devices: the noise channel. The noise channel is not very well documented and as such is only a best guess as to the sound's accuracy. - Tandy DAC - Emulation of the Tandy DAC utilizes the soundblaster emulation, thus - be sure the soundblaster is not disabled in the DOSBox configuration - file. The Tandy DAC is only emulated at the BIOS level. + The Tandy DAC BIOS interface as well as low level access are emulated. - Adlib This emulation is almost perfect and includes the Adlib's ability to almost play digitized sound. @@ -470,8 +468,8 @@ MOUNT -u "Emulated Drive letter" is mounted. It will not be updated !! -aspi - Forces use of the aspi layer. Only valid if mounting a CD-ROM under - Windows systems with an ASPI-Layer. + Forces use of the aspi layer (obsolete). Only valid if mounting a + CD-ROM under Windows systems with an ASPI-Layer. -ioctl (automatic selection of the CD audio interface) -ioctl_dx (digital audio extraction used for CD audio) From 685c25369040d95bc583644276025b586b383aef Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 27 Apr 2010 11:01:42 +0000 Subject: [PATCH 3499/4131] Some more contrast for Amber mode (ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3588 --- src/hardware/vga_other.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 98d29395..710b6c07 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -471,7 +471,7 @@ void Herc_Palette(void) { VGA_DAC_SetEntry(0xf,0x3f,0x3f,0x3f); break; case 1: // Amber - VGA_DAC_SetEntry(0x7,0x37,0x28,0x00); + VGA_DAC_SetEntry(0x7,0x34,0x20,0x00); VGA_DAC_SetEntry(0xf,0x3f,0x34,0x00); break; case 2: // Green From cc6785aceacc12cceb753904623faab389344a58 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 2 May 2010 07:16:15 +0000 Subject: [PATCH 3500/4131] Add basic delay to a few dos games to improve their timing. TSR use global psp. (rc3 changes) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3589 --- src/cpu/callback.cpp | 8 +++++++- src/dos/dos.cpp | 28 +++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 8cedf927..627b548f 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -423,7 +423,13 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ } phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction phys_writeb(physAddress+0x02,(Bit8u)0xCB); //A RETF Instruction - return (use_cb?7:3); + phys_writeb(physAddress+0x03,(Bit8u)0x51); // push cx + phys_writeb(physAddress+0x04,(Bit8u)0xB9); // mov cx, + phys_writew(physAddress+0x05,(Bit16u)0x0140); // 0x140 + phys_writew(physAddress+0x07,(Bit16u)0xFEE2); // loop $-2 + phys_writeb(physAddress+0x09,(Bit8u)0x59); // pop cx + phys_writeb(physAddress+0x0A,(Bit8u)0xCF); //An IRET Instruction + return (use_cb?15:11); default: E_Exit("CALLBACK:Setup:Illegal type %d",type); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 2073a552..35eb73e9 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -44,7 +44,10 @@ void DOS_SetError(Bit16u code) { #define DATA_TRANSFERS_TAKE_CYCLES 1 #ifdef DATA_TRANSFERS_TAKE_CYCLES + +#ifndef DOSBOX_CPU_H #include "cpu.h" +#endif static inline void modify_cycles(Bits value) { if((4*value+5) < CPU_Cycles) { CPU_Cycles -= 4*value; @@ -59,6 +62,20 @@ static inline void modify_cycles(Bits /* value */) { return; } #endif +#define DOS_OVERHEAD 1 +#ifdef DOS_OVERHEAD +#ifndef DOSBOX_CPU_H +#include "cpu.h" +#endif + +static inline void overhead() { + reg_ip += 2; +} +#else +static inline void overhead() { + return; +} +#endif #define DOSNAMEBUF 256 static Bitu DOS_21Handler(void) { @@ -121,6 +138,9 @@ static Bitu DOS_21Handler(void) { switch (reg_dl) { case 0xFF: /* Input */ { + //Simulate DOS overhead for timing sensitive games + //MM1 + overhead(); //TODO Make this better according to standards if (!DOS_GetSTDINStatus()) { reg_al=0; @@ -201,6 +221,9 @@ static Bitu DOS_21Handler(void) { case 0x0b: /* Get STDIN Status */ if (!DOS_GetSTDINStatus()) {reg_al=0x00;} else {reg_al=0xFF;} + //Simulate some overhead for timing issues + //Tankwar menu (needs maybe even more) + overhead(); break; case 0x0c: /* Flush Buffer and read STDIN call */ { @@ -369,6 +392,9 @@ static Bitu DOS_21Handler(void) { reg_dh=(Bit8u)(seconds % 60); reg_dl=(Bit8u)(ticks % 100); } + //Simulate DOS overhead for timing-sensitive games + //Robomaze 2 + overhead(); break; case 0x2d: /* Set System Time */ LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Set System Time not supported"); @@ -1061,7 +1087,7 @@ static Bitu DOS_20Handler(void) { static Bitu DOS_27Handler(void) { // Terminate & stay resident Bit16u para = (reg_dx/16)+((reg_dx % 16)>0); - Bit16u psp = mem_readw(SegPhys(ss)+reg_sp+2); + Bit16u psp = dos.psp(); //mem_readw(SegPhys(ss)+reg_sp+2); if (DOS_ResizeMemory(psp,¶)) DOS_Terminate(psp,true,0); return CBRET_NONE; } From 79f692235acd9c3a94a26a52133cd50953dade7b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 4 May 2010 14:40:11 +0000 Subject: [PATCH 3501/4131] Add some more descriptive texts, add aliases resetconf and resetmapper. Change titlebar to always include percentage. (rc3t2 changes) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3590 --- docs/dosbox.1 | 8 ++++++-- src/gui/sdlmain.cpp | 27 +++++++++++++++------------ 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/docs/dosbox.1 b/docs/dosbox.1 index 1a759440..74fe2cb7 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -28,7 +28,11 @@ dosbox \- an x86/DOS emulator with sound/graphics .LP .B dosbox \-eraseconf .LP +.B dosbox \-resetconf +.LP .B dosbox \-erasemapper +.LP +.B dosbox \-resetmapper .SH DESCRIPTION This manual page briefly documents .BR "dosbox" ", an x86/DOS emulator." @@ -107,10 +111,10 @@ You can specify this command more than once. In this case it will .B \-printconf prints the location of the default configuration file. .TP -.B \-eraseconf +.B \-eraseconf, \-resetconf removes the default configuration file. .TP -.B \-erasemapper +.B \-erasemapper, \-resetmapper removes the mapperfile configured in the clean default configuration file. .SH "INTERNAL COMMANDS" .B dosbox diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 7aa4aafa..7f075182 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -236,12 +236,9 @@ void GFX_SetTitle(Bit32s cycles,Bits frameskip,bool paused){ if(cycles != -1) internal_cycles = cycles; if(frameskip != -1) internal_frameskip = frameskip; if(CPU_CycleAutoAdjust) { - if (internal_cycles>=100) - sprintf(title,"DOSBox %s, Cpu Cycles: max, Frameskip %2d, Program: %8s",VERSION,internal_frameskip,RunningProgram); - else - sprintf(title,"DOSBox %s, Cpu Cycles: [%3d%%], Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram); + sprintf(title,"DOSBox %s, Cpu speed: max %3d%% cycles, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram); } else { - sprintf(title,"DOSBox %s, Cpu Cycles: %8d, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram); + sprintf(title,"DOSBox %s, Cpu speed: %8d cycles, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram); } if(paused) strcat(title," PAUSED"); @@ -1468,16 +1465,19 @@ void Config_Add_SDL() { Prop_multival* Pmulti; Pbool = sdl_sec->Add_bool("fullscreen",Property::Changeable::Always,false); - Pbool->Set_help("Start dosbox directly in fullscreen."); - + Pbool->Set_help("Start dosbox directly in fullscreen. (Press ALT-Enter to go back)"); + Pbool = sdl_sec->Add_bool("fulldouble",Property::Changeable::Always,false); - Pbool->Set_help("Use double buffering in fullscreen."); + Pbool->Set_help("Use double buffering in fullscreen. It can reduce screen flickering, but it can also result in a slow DOSBox."); Pstring = sdl_sec->Add_string("fullresolution",Property::Changeable::Always,"original"); - Pstring->Set_help("What resolution to use for fullscreen: original or fixed size (e.g. 1024x768)."); + Pstring->Set_help("What resolution to use for fullscreen: original or fixed size (e.g. 1024x768).\n" + " Using your monitor's native resolution with aspect=true might give the best results.\n" + " If you end up with small window on a large screen, try an output different from surface."); Pstring = sdl_sec->Add_string("windowresolution",Property::Changeable::Always,"original"); - Pstring->Set_help("Scale the window to this size IF the output device supports hardware scaling."); + Pstring->Set_help("Scale the window to this size IF the output device supports hardware scaling.\n" + " output=surface does not!)"); const char* outputs[] = { "surface", "overlay", @@ -1493,7 +1493,7 @@ void Config_Add_SDL() { Pstring->Set_values(outputs); Pbool = sdl_sec->Add_bool("autolock",Property::Changeable::Always,true); - Pbool->Set_help("Mouse will automatically lock, if you click on the screen."); + Pbool->Set_help("Mouse will automatically lock, if you click on the screen. (Press CTRL-F10 to unlock)"); Pint = sdl_sec->Add_int("sensitivity",Property::Changeable::Always,100); Pint->SetMinMax(1,1000); @@ -1504,7 +1504,8 @@ void Config_Add_SDL() { Pmulti = sdl_sec->Add_multi("priority", Property::Changeable::Always, ","); Pmulti->SetValue("higher,normal"); - Pmulti->Set_help("Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized. (pause is only valid for the second entry)"); + Pmulti->Set_help("Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized.\n" + " pause is only valid for the second entry."); const char* actt[] = { "lowest", "lower", "normal", "higher", "highest", "pause", 0}; Pstring = Pmulti->GetSection()->Add_string("active",Property::Changeable::Always,"higher"); @@ -1672,7 +1673,9 @@ int main(int argc, char* argv[]) { if(control->cmdline->FindString("-editconf",editor,false)) launcheditor(); if(control->cmdline->FindString("-opencaptures",editor,true)) launchcaptures(editor); if(control->cmdline->FindExist("-eraseconf")) eraseconfigfile(); + if(control->cmdline->FindExist("-resetconf")) eraseconfigfile(); if(control->cmdline->FindExist("-erasemapper")) erasemapperfile(); + if(control->cmdline->FindExist("-resetmapper")) erasemapperfile(); /* Can't disable the console with debugger enabled */ #if defined(WIN32) && !(C_DEBUG) From 2e0b34ee0fefe8af8dc71e6612b604c6395d49d3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 4 May 2010 14:43:12 +0000 Subject: [PATCH 3502/4131] More descriptive texts. New defaults for cycleup, prebuffer and blocksize. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3591 --- src/dosbox.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 672afbdd..0ec05ed4 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -374,7 +374,8 @@ void DOSBOX_Init(void) { Pmulti = secprop->Add_multi("scaler",Property::Changeable::Always," "); Pmulti->SetValue("normal2x"); - Pmulti->Set_help("Scaler used to enlarge/enhance low resolution modes. If 'forced' is appended,the scaler will be used even if the result might not be desired."); + Pmulti->Set_help("Scaler used to enlarge/enhance low resolution modes.\n" + " If 'forced' is appended, then the scaler will be used even if the result might not be desired."); Pstring = Pmulti->GetSection()->Add_string("type",Property::Changeable::Always,"normal2x"); const char *scalers[] = { @@ -410,11 +411,13 @@ void DOSBOX_Init(void) { Pmulti_remain = secprop->Add_multiremain("cycles",Property::Changeable::Always," "); Pmulti_remain->Set_help( - "Amount of instructions DOSBox tries to emulate each millisecond. Setting this value too high results in sound dropouts and lags. Cycles can be set in 3 ways:\n" + "Amount of instructions DOSBox tries to emulate each millisecond.\n" + "Setting this value too high results in sound dropouts and lags.\n" + "Cycles can be set in 3 ways:\n" " 'auto' tries to guess what a game needs.\n" " It usually works, but can fail for certain games.\n" " 'fixed #number' will set a fixed amount of cycles. This is what you usually need if 'auto' fails.\n" - " (Example: fixed 4000)\n" + " (Example: fixed 4000).\n" " 'max' will allocate as much cycles as your computer is able to handle.\n"); const char* cyclest[] = { "auto","fixed","max","%u",0 }; @@ -424,9 +427,9 @@ void DOSBOX_Init(void) { Pstring = Pmulti_remain->GetSection()->Add_string("parameters",Property::Changeable::Always,""); - Pint = secprop->Add_int("cycleup",Property::Changeable::Always,500); + Pint = secprop->Add_int("cycleup",Property::Changeable::Always,10); Pint->SetMinMax(1,1000000); - Pint->Set_help("Amount of cycles to increase/decrease with keycombo."); + Pint->Set_help("Amount of cycles to decrease/increase with keycombo.(CTRL-F11/CTRL-F12)"); Pint = secprop->Add_int("cycledown",Property::Changeable::Always,20); Pint->SetMinMax(1,1000000); @@ -448,15 +451,15 @@ void DOSBOX_Init(void) { Pint->Set_help("Mixer sample rate, setting any device's rate higher than this will probably lower their sound quality."); const char *blocksizes[] = { - "2048", "4096", "8192", "1024", "512", "256", 0}; - Pint = secprop->Add_int("blocksize",Property::Changeable::OnlyAtStart,2048); + "1024", "2048", "4096", "8192", "512", "256", 0}; + Pint = secprop->Add_int("blocksize",Property::Changeable::OnlyAtStart,1024); Pint->Set_values(blocksizes); Pint->Set_help("Mixer block size, larger blocks might help sound stuttering but sound will also be more lagged."); - Pint = secprop->Add_int("prebuffer",Property::Changeable::OnlyAtStart,10); + Pint = secprop->Add_int("prebuffer",Property::Changeable::OnlyAtStart,20); Pint->SetMinMax(0,100); Pint->Set_help("How many milliseconds of data to keep on top of the blocksize."); - + secprop=control->AddSection_prop("midi",&MIDI_Init,true);//done secprop->AddInitFunction(&MPU401_Init,true);//done @@ -472,7 +475,8 @@ void DOSBOX_Init(void) { Pstring->Set_help("Device that will receive the MIDI data from MPU-401."); Pstring = secprop->Add_string("midiconfig",Property::Changeable::WhenIdle,""); - Pstring->Set_help("Special configuration options for the device driver. This is usually the id of the device you want to use. See README for details."); + Pstring->Set_help("Special configuration options for the device driver. This is usually the id of the device you want to use.\n" + " See the README/Manual for more details."); #if C_DEBUG secprop=control->AddSection_prop("debug",&DEBUG_Init); @@ -583,10 +587,11 @@ void DOSBOX_Init(void) { "4axis_2 (supports one joystick, second joystick used),\n" "fcs (Thrustmaster), ch (CH Flightstick).\n" "none disables joystick emulation.\n" - "auto chooses emulation depending on real joystick(s)."); + "auto chooses emulation depending on real joystick(s).\n" + "(Remember to reset dosbox's mapperfile if you saved it earlier)"); Pbool = secprop->Add_bool("timed",Property::Changeable::WhenIdle,true); - Pbool->Set_help("enable timed intervals for axis. (false is old style behaviour)."); + Pbool->Set_help("enable timed intervals for axis. Experiment with this option, if your joystick drifts (away)."); Pbool = secprop->Add_bool("autofire",Property::Changeable::WhenIdle,false); Pbool->Set_help("continuously fires as long as you keep the button pressed."); @@ -672,9 +677,10 @@ void DOSBOX_Init(void) { secline=control->AddSection_line("autoexec",&AUTOEXEC_Init); MSG_Add("AUTOEXEC_CONFIGFILE_HELP", "Lines in this section will be run at startup.\n" + "You can put your MOUNT lines here.\n" ); MSG_Add("CONFIGFILE_INTRO", - "# This is the configurationfile for DOSBox %s.\n" + "# This is the configurationfile for DOSBox %s. (Please use the latest version of DOSBox)\n" "# Lines starting with a # are commentlines and are ignored by DOSBox.\n" "# They are used to (briefly) document the effect of each option.\n"); MSG_Add("CONFIG_SUGGESTED_VALUES", "Possible values"); From 3f17468a1f5704196b113c81c74578d484b10efd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 4 May 2010 14:49:08 +0000 Subject: [PATCH 3503/4131] Allow cpu percentage used to be 105%, (which is in reality (90*105)%). Some more descriptive LOG_MSG when changing the cycles. (rc3 changes) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3592 --- src/cpu/cpu.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 7fd5bdc2..9b62338a 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1563,6 +1563,7 @@ void CPU_SET_CRX(Bitu cr,Bitu value) { CPU_Cycles=0; CPU_OldCycleMax=CPU_CycleMax; GFX_SetTitle(CPU_CyclePercUsed,-1,false); + LOG_MSG("DOSBox switched to max cycles, because of the setting: cycles=auto. If the game runs too fast try a fixed cycles amount in DOSBox's options."); } else { GFX_SetTitle(-1,-1,false); } @@ -2095,8 +2096,8 @@ static void CPU_CycleIncrease(bool pressed) { if (!pressed) return; if (CPU_CycleAutoAdjust) { CPU_CyclePercUsed+=5; - if (CPU_CyclePercUsed>100) CPU_CyclePercUsed=100; - LOG_MSG("CPU:%d percent",CPU_CyclePercUsed); + if (CPU_CyclePercUsed>105) CPU_CyclePercUsed=105; + LOG_MSG("CPU speed: max %d percent.",CPU_CyclePercUsed); GFX_SetTitle(CPU_CyclePercUsed,-1,false); } else { Bit32s old_cycles=CPU_CycleMax; @@ -2108,7 +2109,7 @@ static void CPU_CycleIncrease(bool pressed) { CPU_CycleLeft=0;CPU_Cycles=0; if (CPU_CycleMax==old_cycles) CPU_CycleMax++; - LOG_MSG("CPU:%d cycles",CPU_CycleMax); + LOG_MSG("CPU speed: fixed %d cycles. If you need more than 20000, try core=dynamic in DOSBox's options.",CPU_CycleMax); GFX_SetTitle(CPU_CycleMax,-1,false); } } @@ -2118,7 +2119,7 @@ static void CPU_CycleDecrease(bool pressed) { if (CPU_CycleAutoAdjust) { CPU_CyclePercUsed-=5; if (CPU_CyclePercUsed<=0) CPU_CyclePercUsed=1; - LOG_MSG("CPU:%d percent",CPU_CyclePercUsed); + LOG_MSG("CPU speed: max %d percent. If the game runs too fast, try a fixed cycles amount in DOSBox's options.",CPU_CyclePercUsed); GFX_SetTitle(CPU_CyclePercUsed,-1,false); } else { if (CPU_CycleDown < 100) { @@ -2128,7 +2129,7 @@ static void CPU_CycleDecrease(bool pressed) { } CPU_CycleLeft=0;CPU_Cycles=0; if (CPU_CycleMax <= 0) CPU_CycleMax=1; - LOG_MSG("CPU:%d cycles",CPU_CycleMax); + LOG_MSG("CPU speed: fixed %d cycles.",CPU_CycleMax); GFX_SetTitle(CPU_CycleMax,-1,false); } } @@ -2242,7 +2243,7 @@ public: int percval=0; std::istringstream stream(str); stream >> percval; - if ((percval>0) && (percval<=100)) CPU_CyclePercUsed=(Bit32s)percval; + if ((percval>0) && (percval<=105)) CPU_CyclePercUsed=(Bit32s)percval; } else if (str=="limit") { cmdnum++; if (cmd.FindCommand(cmdnum,str)) { @@ -2267,7 +2268,7 @@ public: int percval=0; std::istringstream stream(str); stream >> percval; - if ((percval>0) && (percval<=100)) CPU_CyclePercUsed=(Bit32s)percval; + if ((percval>0) && (percval<=105)) CPU_CyclePercUsed=(Bit32s)percval; } else if (str=="limit") { cmdnum++; if (cmd.FindCommand(cmdnum,str)) { From 1157cbe2a012b81b45daade71ffa7727b5ab2f95 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 5 May 2010 19:12:51 +0000 Subject: [PATCH 3504/4131] Make it a bit more pretty. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3593 --- src/cpu/cpu.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 9b62338a..8d92572c 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -2109,7 +2109,10 @@ static void CPU_CycleIncrease(bool pressed) { CPU_CycleLeft=0;CPU_Cycles=0; if (CPU_CycleMax==old_cycles) CPU_CycleMax++; - LOG_MSG("CPU speed: fixed %d cycles. If you need more than 20000, try core=dynamic in DOSBox's options.",CPU_CycleMax); + if(CPU_CycleMax > 15000 ) + LOG_MSG("CPU speed: fixed %d cycles. If you need more than 20000, try core=dynamic in DOSBox's options.",CPU_CycleMax); + else + LOG_MSG("CPU speed: fixed %d cycles.",CPU_CycleMax); GFX_SetTitle(CPU_CycleMax,-1,false); } } From 3bc49c24e2b3b2174b2372b00da4f5faf0284efd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 5 May 2010 19:22:33 +0000 Subject: [PATCH 3505/4131] More pretty pretty. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3594 --- src/cpu/cpu.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 8d92572c..b49d0656 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -2122,7 +2122,10 @@ static void CPU_CycleDecrease(bool pressed) { if (CPU_CycleAutoAdjust) { CPU_CyclePercUsed-=5; if (CPU_CyclePercUsed<=0) CPU_CyclePercUsed=1; - LOG_MSG("CPU speed: max %d percent. If the game runs too fast, try a fixed cycles amount in DOSBox's options.",CPU_CyclePercUsed); + if(CPU_CyclePercUsed <=70) + LOG_MSG("CPU speed: max %d percent. If the game runs too fast, try a fixed cycles amount in DOSBox's options.",CPU_CyclePercUsed); + else + LOG_MSG("CPU speed: max %d percent.",CPU_CyclePercUsed); GFX_SetTitle(CPU_CyclePercUsed,-1,false); } else { if (CPU_CycleDown < 100) { From a87bb27faa01b69f24dc21c2ef62094d00679901 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 5 May 2010 19:26:23 +0000 Subject: [PATCH 3506/4131] Improved layout designed by tryton. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3595 --- src/gui/sdl_mapper.cpp | 160 +++++++++++++++++++++++++---------------- 1 file changed, 97 insertions(+), 63 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 11b50af9..8bc96a6f 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -1649,7 +1649,7 @@ static void SetActiveEvent(CEvent * event) { mapper.aevent=event; mapper.redraw=true; mapper.addbind=false; - bind_but.event_title->Change("EVENT:%s",event ? event->GetName(): "none"); + bind_but.event_title->Change("Event:%s",event ? event->GetName(): "none"); if (!event) { change_action_text("Select an event to change.",CLR_WHITE); bind_but.add->Enable(false); @@ -1776,7 +1776,7 @@ static void CreateLayout(void) { #define BH 20 #define DX 5 #define PX(_X_) ((_X_)*BW + DX) -#define PY(_Y_) (30+(_Y_)*BH) +#define PY(_Y_) (10+(_Y_)*BH) AddKeyButtonEvent(PX(0),PY(0),BW,BH,"ESC","esc",KBD_esc); for (i=0;i<12;i++) AddKeyButtonEvent(PX(2+i),PY(0),BW,BH,combo_f[i].title,combo_f[i].entry,combo_f[i].key); for (i=0;i<14;i++) AddKeyButtonEvent(PX( i),PY(1),BW,BH,combo_1[i].title,combo_1[i].entry,combo_1[i].key); @@ -1801,62 +1801,71 @@ static void CreateLayout(void) { AddKeyButtonEvent(PX(14),PY(5),BW*2,BH,"CTRL","rctrl",KBD_rightctrl); /* Arrow Keys */ - AddKeyButtonEvent(PX(0),PY(7),BW,BH,"PRT","printscreen",KBD_printscreen); - AddKeyButtonEvent(PX(1),PY(7),BW,BH,"SCL","scrolllock",KBD_scrolllock); - AddKeyButtonEvent(PX(2),PY(7),BW,BH,"PAU","pause",KBD_pause); - AddKeyButtonEvent(PX(0),PY(8),BW,BH,"INS","insert",KBD_insert); - AddKeyButtonEvent(PX(1),PY(8),BW,BH,"HOM","home",KBD_home); - AddKeyButtonEvent(PX(2),PY(8),BW,BH,"PUP","pageup",KBD_pageup); - AddKeyButtonEvent(PX(0),PY(9),BW,BH,"DEL","delete",KBD_delete); - AddKeyButtonEvent(PX(1),PY(9),BW,BH,"END","end",KBD_end); - AddKeyButtonEvent(PX(2),PY(9),BW,BH,"PDN","pagedown",KBD_pagedown); - AddKeyButtonEvent(PX(1),PY(10),BW,BH,"\x18","up",KBD_up); - AddKeyButtonEvent(PX(0),PY(11),BW,BH,"\x1B","left",KBD_left); - AddKeyButtonEvent(PX(1),PY(11),BW,BH,"\x19","down",KBD_down); - AddKeyButtonEvent(PX(2),PY(11),BW,BH,"\x1A","right",KBD_right); +#define XO 17 +#define YO 0 + AddKeyButtonEvent(PX(XO+0),PY(YO),BW,BH,"PRT","printscreen",KBD_printscreen); + AddKeyButtonEvent(PX(XO+1),PY(YO),BW,BH,"SCL","scrolllock",KBD_scrolllock); + AddKeyButtonEvent(PX(XO+2),PY(YO),BW,BH,"PAU","pause",KBD_pause); + AddKeyButtonEvent(PX(XO+0),PY(YO+1),BW,BH,"INS","insert",KBD_insert); + AddKeyButtonEvent(PX(XO+1),PY(YO+1),BW,BH,"HOM","home",KBD_home); + AddKeyButtonEvent(PX(XO+2),PY(YO+1),BW,BH,"PUP","pageup",KBD_pageup); + AddKeyButtonEvent(PX(XO+0),PY(YO+2),BW,BH,"DEL","delete",KBD_delete); + AddKeyButtonEvent(PX(XO+1),PY(YO+2),BW,BH,"END","end",KBD_end); + AddKeyButtonEvent(PX(XO+2),PY(YO+2),BW,BH,"PDN","pagedown",KBD_pagedown); + AddKeyButtonEvent(PX(XO+1),PY(YO+4),BW,BH,"\x18","up",KBD_up); + AddKeyButtonEvent(PX(XO+0),PY(YO+5),BW,BH,"\x1B","left",KBD_left); + AddKeyButtonEvent(PX(XO+1),PY(YO+5),BW,BH,"\x19","down",KBD_down); + AddKeyButtonEvent(PX(XO+2),PY(YO+5),BW,BH,"\x1A","right",KBD_right); +#undef XO +#undef YO +#define XO 0 +#define YO 7 /* Numeric KeyPad */ - num_lock_event=AddKeyButtonEvent(PX(4),PY(7),BW,BH,"NUM","numlock",KBD_numlock); - AddKeyButtonEvent(PX(5),PY(7),BW,BH,"/","kp_divide",KBD_kpdivide); - AddKeyButtonEvent(PX(6),PY(7),BW,BH,"*","kp_multiply",KBD_kpmultiply); - AddKeyButtonEvent(PX(7),PY(7),BW,BH,"-","kp_minus",KBD_kpminus); - AddKeyButtonEvent(PX(4),PY(8),BW,BH,"7","kp_7",KBD_kp7); - AddKeyButtonEvent(PX(5),PY(8),BW,BH,"8","kp_8",KBD_kp8); - AddKeyButtonEvent(PX(6),PY(8),BW,BH,"9","kp_9",KBD_kp9); - AddKeyButtonEvent(PX(7),PY(8),BW,BH*2,"+","kp_plus",KBD_kpplus); - AddKeyButtonEvent(PX(4),PY(9),BW,BH,"4","kp_4",KBD_kp4); - AddKeyButtonEvent(PX(5),PY(9),BW,BH,"5","kp_5",KBD_kp5); - AddKeyButtonEvent(PX(6),PY(9),BW,BH,"6","kp_6",KBD_kp6); - AddKeyButtonEvent(PX(4),PY(10),BW,BH,"1","kp_1",KBD_kp1); - AddKeyButtonEvent(PX(5),PY(10),BW,BH,"2","kp_2",KBD_kp2); - AddKeyButtonEvent(PX(6),PY(10),BW,BH,"3","kp_3",KBD_kp3); - AddKeyButtonEvent(PX(7),PY(10),BW,BH*2,"ENT","kp_enter",KBD_kpenter); - AddKeyButtonEvent(PX(4),PY(11),BW*2,BH,"0","kp_0",KBD_kp0); - AddKeyButtonEvent(PX(6),PY(11),BW,BH,".","kp_period",KBD_kpperiod); - + num_lock_event=AddKeyButtonEvent(PX(XO),PY(YO),BW,BH,"NUM","numlock",KBD_numlock); + AddKeyButtonEvent(PX(XO+1),PY(YO),BW,BH,"/","kp_divide",KBD_kpdivide); + AddKeyButtonEvent(PX(XO+2),PY(YO),BW,BH,"*","kp_multiply",KBD_kpmultiply); + AddKeyButtonEvent(PX(XO+3),PY(YO),BW,BH,"-","kp_minus",KBD_kpminus); + AddKeyButtonEvent(PX(XO+0),PY(YO+1),BW,BH,"7","kp_7",KBD_kp7); + AddKeyButtonEvent(PX(XO+1),PY(YO+1),BW,BH,"8","kp_8",KBD_kp8); + AddKeyButtonEvent(PX(XO+2),PY(YO+1),BW,BH,"9","kp_9",KBD_kp9); + AddKeyButtonEvent(PX(XO+3),PY(YO+1),BW,BH*2,"+","kp_plus",KBD_kpplus); + AddKeyButtonEvent(PX(XO),PY(YO+2),BW,BH,"4","kp_4",KBD_kp4); + AddKeyButtonEvent(PX(XO+1),PY(YO+2),BW,BH,"5","kp_5",KBD_kp5); + AddKeyButtonEvent(PX(XO+2),PY(YO+2),BW,BH,"6","kp_6",KBD_kp6); + AddKeyButtonEvent(PX(XO+0),PY(YO+3),BW,BH,"1","kp_1",KBD_kp1); + AddKeyButtonEvent(PX(XO+1),PY(YO+3),BW,BH,"2","kp_2",KBD_kp2); + AddKeyButtonEvent(PX(XO+2),PY(YO+3),BW,BH,"3","kp_3",KBD_kp3); + AddKeyButtonEvent(PX(XO+3),PY(YO+3),BW,BH*2,"ENT","kp_enter",KBD_kpenter); + AddKeyButtonEvent(PX(XO),PY(YO+4),BW*2,BH,"0","kp_0",KBD_kp0); + AddKeyButtonEvent(PX(XO+2),PY(YO+4),BW,BH,".","kp_period",KBD_kpperiod); +#undef XO +#undef YO +#define XO 10 +#define YO 8 /* Joystick Buttons/Texts */ /* Buttons 1+2 of 1st Joystick */ - AddJButtonButton(PX(18),PY(0),BW,BH,"1" ,0,0); - AddJButtonButton(PX(20),PY(0),BW,BH,"2" ,0,1); + AddJButtonButton(PX(XO),PY(YO),BW,BH,"1" ,0,0); + AddJButtonButton(PX(XO+2),PY(YO),BW,BH,"2" ,0,1); /* Axes 1+2 (X+Y) of 1st Joystick */ - CJAxisEvent * cjaxis=AddJAxisButton(PX(19),PY(0),BW,BH,"Y-",0,1,false,NULL); - AddJAxisButton (PX(19),PY(1),BW,BH,"Y+",0,1,true,cjaxis); - cjaxis=AddJAxisButton (PX(18),PY(1),BW,BH,"X-",0,0,false,NULL); - AddJAxisButton (PX(20),PY(1),BW,BH,"X+",0,0,true,cjaxis); + CJAxisEvent * cjaxis=AddJAxisButton(PX(XO+1),PY(YO),BW,BH,"Y-",0,1,false,NULL); + AddJAxisButton (PX(XO+1),PY(YO+1),BW,BH,"Y+",0,1,true,cjaxis); + cjaxis=AddJAxisButton (PX(XO),PY(YO+1),BW,BH,"X-",0,0,false,NULL); + AddJAxisButton (PX(XO+2),PY(YO+1),BW,BH,"X+",0,0,true,cjaxis); if (joytype==JOY_2AXIS) { /* Buttons 1+2 of 2nd Joystick */ - AddJButtonButton(PX(18),PY(3),BW,BH,"1" ,1,0); - AddJButtonButton(PX(20),PY(3),BW,BH,"2" ,1,1); + AddJButtonButton(PX(XO+4),PY(YO),BW,BH,"1" ,1,0); + AddJButtonButton(PX(XO+4+2),PY(YO),BW,BH,"2" ,1,1); /* Buttons 3+4 of 1st Joystick, not accessible */ AddJButtonButton_hidden(0,2); AddJButtonButton_hidden(0,3); /* Axes 1+2 (X+Y) of 2nd Joystick */ - cjaxis= AddJAxisButton(PX(18),PY(4),BW,BH,"X-",1,0,false,NULL); - AddJAxisButton(PX(20),PY(4),BW,BH,"X+",1,0,true,cjaxis); - cjaxis= AddJAxisButton(PX(19),PY(3),BW,BH,"Y-",1,1,false,NULL); - AddJAxisButton(PX(19),PY(4),BW,BH,"Y+",1,1,true,cjaxis); + cjaxis= AddJAxisButton(PX(XO+4),PY(YO+1),BW,BH,"X-",1,0,false,NULL); + AddJAxisButton(PX(XO+4+2),PY(YO+1),BW,BH,"X+",1,0,true,cjaxis); + cjaxis= AddJAxisButton(PX(XO+4+1),PY(YO+0),BW,BH,"Y-",1,1,false,NULL); + AddJAxisButton(PX(XO+4+1),PY(YO+1),BW,BH,"Y+",1,1,true,cjaxis); /* Axes 3+4 (X+Y) of 1st Joystick, not accessible */ cjaxis= AddJAxisButton_hidden(0,2,false,NULL); AddJAxisButton_hidden(0,2,true,cjaxis); @@ -1864,17 +1873,17 @@ static void CreateLayout(void) { AddJAxisButton_hidden(0,3,true,cjaxis); } else { /* Buttons 3+4 of 1st Joystick */ - AddJButtonButton(PX(18),PY(3),BW,BH,"3" ,0,2); - AddJButtonButton(PX(20),PY(3),BW,BH,"4" ,0,3); + AddJButtonButton(PX(XO+4),PY(YO),BW,BH,"3" ,0,2); + AddJButtonButton(PX(XO+4+2),PY(YO),BW,BH,"4" ,0,3); /* Buttons 1+2 of 2nd Joystick, not accessible */ AddJButtonButton_hidden(1,0); AddJButtonButton_hidden(1,1); /* Axes 3+4 (X+Y) of 1st Joystick */ - cjaxis= AddJAxisButton(PX(18),PY(4),BW,BH,"X-",0,2,false,NULL); - AddJAxisButton(PX(20),PY(4),BW,BH,"X+",0,2,true,cjaxis); - cjaxis= AddJAxisButton(PX(19),PY(3),BW,BH,"Y-",0,3,false,NULL); - AddJAxisButton(PX(19),PY(4),BW,BH,"Y+",0,3,true,cjaxis); + cjaxis= AddJAxisButton(PX(XO+4),PY(YO+1),BW,BH,"X-",0,2,false,NULL); + AddJAxisButton(PX(XO+4+2),PY(YO+1),BW,BH,"X+",0,2,true,cjaxis); + cjaxis= AddJAxisButton(PX(XO+4+1),PY(YO+0),BW,BH,"Y-",0,3,false,NULL); + AddJAxisButton(PX(XO+4+1),PY(YO+1),BW,BH,"Y+",0,3,true,cjaxis); /* Axes 1+2 (X+Y) of 2nd Joystick , not accessible*/ cjaxis= AddJAxisButton_hidden(1,0,false,NULL); AddJAxisButton_hidden(1,0,true,cjaxis); @@ -1884,8 +1893,8 @@ static void CreateLayout(void) { if (joytype==JOY_CH) { /* Buttons 5+6 of 1st Joystick */ - AddJButtonButton(PX(18),PY(6),BW,BH,"5" ,0,4); - AddJButtonButton(PX(20),PY(6),BW,BH,"6" ,0,5); + AddJButtonButton(PX(XO+8),PY(YO),BW,BH,"5" ,0,4); + AddJButtonButton(PX(XO+8+2),PY(YO),BW,BH,"6" ,0,5); } else { /* Buttons 5+6 of 1st Joystick, not accessible */ AddJButtonButton_hidden(0,4); @@ -1893,17 +1902,42 @@ static void CreateLayout(void) { } /* Hat directions up, left, down, right */ - AddJHatButton(PX(19),PY(6),BW,BH,"UP",0,0,0); - AddJHatButton(PX(18),PY(7),BW,BH,"LFT",0,0,3); - AddJHatButton(PX(19),PY(7),BW,BH,"DWN",0,0,2); - AddJHatButton(PX(20),PY(7),BW,BH,"RGT",0,0,1); + AddJHatButton(PX(XO+8+1),PY(YO),BW,BH,"UP",0,0,0); + AddJHatButton(PX(XO+8+0),PY(YO+1),BW,BH,"LFT",0,0,3); + AddJHatButton(PX(XO+8+1),PY(YO+1),BW,BH,"DWN",0,0,2); + AddJHatButton(PX(XO+8+2),PY(YO+1),BW,BH,"RGT",0,0,1); + /* Labels for the joystick */ + if (joytype ==JOY_2AXIS) { + new CTextButton(PX(XO+0),PY(YO-1),3*BW,20,"Joystick 1"); + new CTextButton(PX(XO+4),PY(YO-1),3*BW,20,"Joystick 2"); + new CTextButton(PX(XO+8),PY(YO-1),3*BW,20,"Disabled"); + } else if(joytype ==JOY_4AXIS || joytype == JOY_4AXIS_2) { + new CTextButton(PX(XO+0),PY(YO-1),3*BW,20,"Axis 1/2"); + new CTextButton(PX(XO+4),PY(YO-1),3*BW,20,"Axis 3/4"); + new CTextButton(PX(XO+8),PY(YO-1),3*BW,20,"Disabled"); + } else if(joytype == JOY_CH) { + new CTextButton(PX(XO+0),PY(YO-1),3*BW,20,"Axis 1/2"); + new CTextButton(PX(XO+4),PY(YO-1),3*BW,20,"Axis 3/4"); + new CTextButton(PX(XO+8),PY(YO-1),3*BW,20,"Hat/D-pad"); + } else if ( joytype==JOY_FCS) { + new CTextButton(PX(XO+0),PY(YO-1),3*BW,20,"Axis 1/2"); + new CTextButton(PX(XO+4),PY(YO-1),3*BW,20,"Axis 3"); + new CTextButton(PX(XO+8),PY(YO-1),3*BW,20,"Hat/D-pad"); + } else if(joytype == JOY_NONE) { + new CTextButton(PX(XO+0),PY(YO-1),3*BW,20,"Disabled"); + new CTextButton(PX(XO+4),PY(YO-1),3*BW,20,"Disabled"); + new CTextButton(PX(XO+8),PY(YO-1),3*BW,20,"Disabled"); + } + + + /* The modifier buttons */ - AddModButton(PX(0),PY(13),50,20,"Mod1",1); - AddModButton(PX(2),PY(13),50,20,"Mod2",2); - AddModButton(PX(4),PY(13),50,20,"Mod3",3); + AddModButton(PX(0),PY(14),50,20,"Mod1",1); + AddModButton(PX(2),PY(14),50,20,"Mod2",2); + AddModButton(PX(4),PY(14),50,20,"Mod3",3); /* Create Handler buttons */ - Bitu xpos=3;Bitu ypos=10; + Bitu xpos=3;Bitu ypos=11; for (CHandlerEventVector_it hit=handlergroup.begin();hit!=handlergroup.end();hit++) { new CEventButton(PX(xpos*3),PY(ypos),BW*3,BH,(*hit)->ButtonName(),(*hit)); xpos++; @@ -1912,8 +1946,8 @@ static void CreateLayout(void) { } } /* Create some text buttons */ - new CTextButton(PX(6),0,124,20,"Keyboard Layout"); - new CTextButton(PX(17),0,124,20,"Joystick Layout"); +// new CTextButton(PX(6),0,124,20,"Keyboard Layout"); +// new CTextButton(PX(17),0,124,20,"Joystick Layout"); bind_but.action=new CCaptionButton(180,330,0,0); From 044521630eeb2cf9b02f586077f1f5c6788acbc5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 7 May 2010 18:31:08 +0000 Subject: [PATCH 3507/4131] A missing (. Thanks Tryton. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3596 --- src/gui/sdlmain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 7f075182..2d7535db 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1477,7 +1477,7 @@ void Config_Add_SDL() { Pstring = sdl_sec->Add_string("windowresolution",Property::Changeable::Always,"original"); Pstring->Set_help("Scale the window to this size IF the output device supports hardware scaling.\n" - " output=surface does not!)"); + " (output=surface does not!)"); const char* outputs[] = { "surface", "overlay", From 9d0ef05f8ded155c52f23375f2033bc45db932ba Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 7 May 2010 19:54:17 +0000 Subject: [PATCH 3508/4131] some mapper reset clarifications Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3597 --- src/gui/sdlmain.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 2d7535db..974eed26 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1516,7 +1516,7 @@ void Config_Add_SDL() { Pstring->Set_values(inactt); Pstring = sdl_sec->Add_path("mapperfile",Property::Changeable::Always,MAPPERFILE); - Pstring->Set_help("File used to load/save the key/event mappings from."); + Pstring->Set_help("File used to load/save the key/event mappings from. Resetmapper only works with the defaul value."); Pbool = sdl_sec->Add_bool("usescancodes",Property::Changeable::Always,true); Pbool->Set_help("Avoid usage of symkeys, might not work on all operating systems."); @@ -1561,7 +1561,7 @@ static void show_warning(char const * const message) { SDL_BlitSurface(splash_surf, NULL, sdl.surface, NULL); SDL_Flip(sdl.surface); - SDL_Delay(10000); + SDL_Delay(12000); } static void launcheditor() { @@ -1647,6 +1647,13 @@ static void eraseconfigfile() { } static void erasemapperfile() { + FILE* g = fopen("dosbox.conf","r"); + if(g) { + fclose(g); + show_warning("Warning: dosbox.conf exists in current working directory.\nKeymapping might not be properly reset.\n" + "Please reset configuration as well and delete the dosbox.conf.\n"); + } + std::string path,file=MAPPERFILE; Cross::GetPlatformConfigDir(path); path += file; From 969ab8aeb02995498ee2e2c821ef0cf5e6d541b5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 9 May 2010 07:52:01 +0000 Subject: [PATCH 3509/4131] Add -userconf to force loading of user specific configfile. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3598 --- src/gui/sdlmain.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 974eed26..6bbc24c3 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1791,7 +1791,28 @@ int main(int argc, char* argv[]) { /* Parse configuration files */ std::string config_file,config_path; bool parsed_anyconfigfile = false; - //First Parse -conf switches + //First Parse -userconf + if(control->cmdline->FindExist("-userconf",true)){ + config_file.clear(); + Cross::GetPlatformConfigDir(config_path); + Cross::GetPlatformConfigName(config_file); + config_path += config_file; + if(control->ParseConfigFile(config_path.c_str())) parsed_anyconfigfile = true; + if(!parsed_anyconfigfile) { + //Try to create the userlevel configfile. + config_file.clear(); + Cross::CreatePlatformConfigDir(config_path); + Cross::GetPlatformConfigName(config_file); + config_path += config_file; + if(control->PrintConfig(config_path.c_str())) { + LOG_MSG("CONFIG: Generating default configuration.\nWriting it to %s",config_path.c_str()); + //Load them as well. Makes relative paths much easier + if(control->ParseConfigFile(config_path.c_str())) parsed_anyconfigfile = true; + } + } + } + + //Second parse -conf entries while(control->cmdline->FindString("-conf",config_file,true)) if (control->ParseConfigFile(config_file.c_str())) parsed_anyconfigfile = true; From d52aa407129338cb94454ffa5965db574dbef0e5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 9 May 2010 11:07:51 +0000 Subject: [PATCH 3510/4131] Updated Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3599 --- THANKS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/THANKS b/THANKS index 811f6c87..8b0e5d96 100644 --- a/THANKS +++ b/THANKS @@ -7,7 +7,7 @@ Jarek Burczynski for the new OPL3 emulator. Ken Silverman for his work on an OPL2 emulator. 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. @@ -22,6 +22,7 @@ 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. +ripsaw8080 for his hard debugging work. GOG Team for the splash screen. All the people who submitted a bug. The Beta Testers. From 5d22234acecfb74d52d9dd397bd0701678c90ac4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 9 May 2010 11:08:38 +0000 Subject: [PATCH 3511/4131] bring in line with documentation again. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3600 --- src/gui/sdl_mapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 8bc96a6f..b3d77bbd 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -1649,7 +1649,7 @@ static void SetActiveEvent(CEvent * event) { mapper.aevent=event; mapper.redraw=true; mapper.addbind=false; - bind_but.event_title->Change("Event:%s",event ? event->GetName(): "none"); + bind_but.event_title->Change("EVENT:%s",event ? event->GetName(): "none"); if (!event) { change_action_text("Select an event to change.",CLR_WHITE); bind_but.add->Enable(false); From dd8b5b2772433fec2d69f1963c1788c085646cfd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 9 May 2010 11:54:44 +0000 Subject: [PATCH 3512/4131] Document -userconf Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3601 --- docs/dosbox.1 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/dosbox.1 b/docs/dosbox.1 index 74fe2cb7..9321fed5 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -9,6 +9,7 @@ dosbox \- an x86/DOS emulator with sound/graphics .B [\-startmapper] .B [\-noautoexec] .B [\-securemode] +.B [\-userconf] .BI "[\-scaler " scaler ] .BI "[\-forcescaler " scaler ] .BI "[\-conf " configfile ] @@ -63,6 +64,10 @@ at the end of (which in turn disables any changes to how the drives are mounted .RB "inside " dosbox ) .TP +.B \-userconf +Load the configuration file located in ~/.dosbox. Can be combined with +.RB "the " \-conf " option." +.TP .BI \-scaler " scaler" .RI "Uses the graphical scaler specified by " scaler ". See the configuration" file for the available scalers From bc76927f2fc40330650450002895c34e7f23d2c6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 9 May 2010 12:01:10 +0000 Subject: [PATCH 3513/4131] Update NEWS and Changelog Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3602 --- ChangeLog | 3 +++ NEWS | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/ChangeLog b/ChangeLog index d2288bfb..3e912f86 100644 --- a/ChangeLog +++ b/ChangeLog @@ -40,6 +40,7 @@ - PCJr, CGA: line-by-line video emulation. - PCJr: support on-screen change of color modes 4medium to 16low. (used by Ghostbusters booter) + - Hercules: Add green and amber monochrome support. - All machines: only update the video timing when needed. (Jungle Hunt, others that synchronize to the video screen might profit) - Several small DOS fixes. @@ -71,6 +72,8 @@ so that hopefully certain soundcards produce more fluent sound playback. - Add some rarely used, but for some games critical flags to the internal commands. + - Add -userconf flag, so that the userspecific configuration can + easily be used together with -conf configfile. - Improve internal timing with repeating timers (especially with the dynamic core). diff --git a/NEWS b/NEWS index d303e45d..adc6875e 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,82 @@ +0.74 + - Several small game specific fixes/hacks/support. (Offensive, + Roadhog, GTA installer, Kingdom O' Magic soundcard detection, + Pirate booter, Armored Fist installer) + - Add the S3-specific 640x480 256 color mode. (fixes regression in "Wooden + Ships and Iron Men" and "I Have No Mouth And I Must Scream") + - Fix a stack overflow that could crash DOSBox. + - Add fake microphone input. (fixes Talking Parrot) + - Modify adlib turn off code, so that it doesn't turn off in + cases where the same sound is repeated over and over again. + - Several small fixes to the CDROM audio code. (HOMM2, Redneck + Rampage and others) + - Several improvements to the CDROM emulation code. (fixes Alpha + Storm and GT Racing 97) + - Some small CPU fixes that might fix something. + - Handle opcode 0xff subcode 7 as invalid instruction. (fixes dif-2 & others) + - Some hercules fixes. (Testdrive) + - Improve support for blanked parts that wrap around to the start of + the screen. (fixes Magic Circle demo and Sid&Al) + - Remove old OPL cores as the new ones seem to work very nicely. + - Modify movie recording code so that the movies aren't corrupt when + you exit dosbox without stopping the movie. + - Change RGB3x scaler to look more pretty. + - Improve initial register values compatility of the GUS. + - Added autodetection for Gameblaster. (games can find it now) + - Change render preferences a bit to be more compatible with Windows 7. + - Add DOS fixes to terminate program. (fixes Fortune Teller) + - Add FFREEP. (fixes Trucks) + - Improve FPU ST80 in C mode when writing zero. (fixes Antigok) + - Add special int10 scanline function. (fixes mz700 and probably lots + of games that mess with them) + - Fix scrolling in rarely used video modes. (fixes Orphee) + - Modify game specific hacks a bit so that Kick off 3 works again. + - Lots of fixes to the INT10 video parameter table. (Seven spirits + of ra and others) + - Add VGA blanking in machine=vgaonly. (used by Alien Carnage) + - CGA, PCJr, Tandy: Add video blanking, change display start latch + timing, sync pulse width correction. + - PCJr, Tandy: implement vertical retrace interrupt. + - PCJr, CGA: line-by-line video emulation. + - PCJr: support on-screen change of color modes 4medium to 16low. (used + by Ghostbusters booter) + - Hercules: Add green and amber monochrome support. + - All machines: only update the video timing when needed. (Jungle Hunt, + others that synchronize to the video screen might profit) + - Several small DOS fixes. + - Some UMB related fixes. (The Legacy without UMB) + - Fix version number of DSP for SB 1.5. (fixes a few games) + - Several VGA emulation improvements. (Allertone football manager) + - Some Tandy fixes. (Mech Warrior) + - Small improvements and fixes to the OPL emulation. + - Add low level Tandy DAC emulation. + - Some EMS fixes. (fixes Mortal Kombat and others) + - Change SoundBlaster DSP reset mechanism, add sb irq acknowledge logic. + (fixes stmik-based applications) + - Some interrupt pointer location modifications. (fixes Tinker Tales) + - Some fixes to the BOOT code. (fixes Last Mission) + - Respect write-only file information. (fixes Champions of Zulala) + - Some RTC fix. (fixes Tully Bodine and others) + - Improve mouse emulation to work better with Water World. + - Hopefully fix the translation of the configuration file. + - Speed up and fixes for the recompiler core. (pitfall2 pcjr) + - Change memory start location. (fixes 7th Guest installer) + - Several fixes to the batch file handling. (Shift and + use the typed first %0 instead of the parsed %0) + - Improve file redirection and redirected line ends. (fixes + Phantasmagoria 2 DOS installer) + - Fix compilation with new MAC os X version. + - Add 16C550A FIFO support to the serial port emulation. + - Improve modem emulation to get higher speeds. + - Change default samplerates to 44100, blocksize to 1024 and prebuffer to 20, + so that hopefully certain soundcards produce more fluent sound playback. + - Add some rarely used, but for some games critical flags to + the internal commands. + - Add -userconf flag, so that the userspecific configuration can + easily be used together with -conf configfile. + - Improve internal timing with repeating timers (especially with + the dynamic core). + 0.73 - Add two new opl2+opl3 emulators. (better speed, different implementation approach) From fe401ac46010b0908a45a0edd6f749587779ae9e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 10 May 2010 17:16:03 +0000 Subject: [PATCH 3514/4131] Some feedback on when pressing and releasing fast forward. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3603 --- src/dosbox.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 0ec05ed4..a4bf5649 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -248,6 +248,7 @@ void DOSBOX_RunMachine(void){ static void DOSBOX_UnlockSpeed( bool pressed ) { static bool autoadjust = false; if (pressed) { + LOG_MSG("Fast Forward ON"); ticksLocked = true; if (CPU_CycleAutoAdjust) { autoadjust = true; @@ -255,7 +256,8 @@ static void DOSBOX_UnlockSpeed( bool pressed ) { CPU_CycleMax /= 3; if (CPU_CycleMax<1000) CPU_CycleMax=1000; } - } else { + } else { + LOG_MSG("Fast Forward OFF"); ticksLocked = false; if (autoadjust) { autoadjust = false; From e74f92898290023d256c577aef0548fe7c855cf5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 10 May 2010 18:44:45 +0000 Subject: [PATCH 3515/4131] Readme update by Tryton. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3604 --- README | 1401 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 800 insertions(+), 601 deletions(-) diff --git a/README b/README index fcda785f..e66a72af 100644 --- a/README +++ b/README @@ -1,36 +1,40 @@ -DOSBox v0.74 +DOSBox v0.74 Manual (always use the latest version from www.dosbox.com) + ===== -NOTE: +NOTE: ===== -While we are hoping that one day DOSBox will run all programs ever -made for the PC, we are not there yet. At present, DOSBox running -on a high-end machine will roughly be the equivalent of a 486 PC. -DOSBox can be configured to run a wide range of DOS games, from -CGA/Tandy/PCjr classics up to games from the Quake era. +While we are hoping that one day DOSBox will run all programs ever made for +the PC, we are not there yet. +At present, DOSBox running on a high-end machine will roughly be the equivalent +of a Pentium I PC. DOSBox can be configured to run a wide range of DOS games, +from CGA/Tandy/PCjr classics up to games from the Quake era. ====== INDEX: ====== + 1. Quickstart -2. FAQ -3. Usage +2. Start (FAQ) +3. Command Line Parameters 4. Internal Programs 5. Special Keys -6. Mapper -7. Keyboard Layout -8. Serial Multiplayer feature -9. How to run resource-demanding games -10. Troubleshooting -11. The config file -12. The language file -13. Building your own version of DOSBox -14. Special thanks -15. Contact +6. Joystick/Gamepad +7. KeyMapper +8. Keyboard Layout +9. Serial Multiplayer feature +10. How to speed up/slow down DOSBox +11. Troubleshooting +12. DOSBox Status Window +13. The configuration (options) file +14. The language file +15. Building your own version of DOSBox +16. Special thanks +17. Contact @@ -39,272 +43,298 @@ INDEX: ============== Type INTRO in DOSBox for a quick tour. -It is essential that you get familiar with the idea of mounting, -DOSBox does not automatically make any drive (or a part of it) -accessible to the emulation. -See the FAQ entry "I've got a Z instead of a C at the prompt" as -well as the description of the MOUNT command (section 4). +It is essential that you get familiar with the idea of mounting, DOSBox does not +automatically make any drive (or a part of it) accessible to the emulation. See +the FAQ entry "How to start?" as well as the description of the MOUNT command +(section 4: "Internal Programs"). If you have your game on a cdrom you may try +this guide: http://vogons.zetafleet.com/viewtopic.php?t=8933 -======= -2. FAQ: -======= +=============== +2. Start (FAQ): +=============== -Some Frequently Asked Questions: - -Q: I've got a Z instead of a C at the prompt. -Q: Do I always have to type these commands? Automation? -Q: How do I change to fullscreen? -Q: My CD-ROM doesn't work. -Q: The game/application can't find its CD-ROM. -Q: The mouse doesn't work. -Q: There is no sound. -Q: The sound stutters or sounds stretched/weird. -Q: I can't type \ or : in DOSBox. -Q: The keyboard lags. -Q: The cursor always moves into one direction! -Q: The game/application runs much too slow! -Q: The game/application does not run at all/crashes! -Q: Can DOSBox harm my computer? -Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. -Q: What sound hardware does DOSBox presently emulate? -Q: DOSBox crashes on startup and I'm running arts. -Q: My Build game(Duke3D/Blood/Shadow Warrior) has problems. -Q: Great README, but I still don't get it. +START: How to start? +AUTOMATION: Do I always have to type these "mount" commands? +FULLSCREEN: How do I change to fullscreen? +CD-ROM: My CD-ROM doesn't work. +CD-ROM: The game/application can't find its CD-ROM. +MOUSE: The mouse doesn't work. +SOUND: There is no sound. +SOUND: What sound hardware does DOSBox presently emulate? +SOUND: The sound stutters or sounds stretched/weird. +KEYBOARD: I can't type \ or : in DOSBox. +KEYBOARD: Right Shift and "\" doesn't work in DOSBox. (Windows only) +KEYBOARD: The keyboard lags. +CONTROL: The character/cursor/mouse pointer always moves into one direction! +SPEED: The game/application runs much too slow/too fast! +CRASH: The game/application does not run at all/crashes! +CRASH: DOSBox crashes on startup! +GAME: My Build game(Duke3D/Blood/Shadow Warrior) has problems. +SAFETY: Can DOSBox harm my computer? +OPTIONS: I would like to change DOSBox's options. +HELP: Great Manual, but I still don't get it. - -Q: I've got a Z instead of a C at the prompt. -A: You have to make your directories available as drives in DOSBox by using - the "mount" command. For example, in Windows "mount C D:\GAMES" will give - you a C drive in DOSBox which points to your Windows D:\GAMES directory. - In Linux, "mount c /home/username" will give you a C drive in DOSBox - which points to /home/username in Linux. - To change to the drive mounted like above, type "C:". If everything went - fine, DOSBox will display the prompt "C:\>". +START: How to start? + At the beginning you've got a Z:\> instead of a C:\> at the prompt. + You have to make your directories available as drives in DOSBox by using + the "mount" command. For example, in Windows "mount C D:\GAMES" will give + you a C drive in DOSBox which points to your Windows D:\GAMES directory + (that was created before). In Linux, "mount c /home/username" will give you + a C drive in DOSBox which points to /home/username in Linux. + To change to the drive mounted like above, type "C:". If everything went + fine, DOSBox will display the prompt "C:\>". -Q: Do I always have to type these commands? Automation? -A: In the DOSBox configuration file is an [autoexec] section. The commands - present there are run when DOSBox starts, so you can use this section - for the mounting. +AUTOMATION: Do I always have to type these commands? + In the DOSBox configuration file is an [autoexec] section. The commands + present there are run when DOSBox starts, so you can use this section + for the mounting. Look at Section 13: The configuration (options) file -Q: How do I change to fullscreen? -A: Press alt-enter. Alternatively: Edit the configuration file of DOSBox and - change the option fullscreen=false to fullscreen=true. If fullscreen looks - wrong in your opinion: Play with the option fullresolution in the - configuration file of DOSBox. To get back from fullscreen mode: - Press alt-enter again. +FULLSCREEN: How do I change to fullscreen? + Press alt-enter. Alternatively: Edit the configuration file of DOSBox and + change the option fullscreen=false to fullscreen=true. If fullscreen looks + wrong in your opinion: Play with the options: fullresolution, output and + aspect in the configuration file of DOSBox. To get back from fullscreen + mode: Press alt-enter again. -Q: My CD-ROM doesn't work. -A: To mount your CD-ROM in DOSBox you have to specify some additional options - when mounting the CD-ROM. - To enable CD-ROM support (includes MSCDEX): - - mount d f:\ -t cdrom (windows) - - mount d /media/cdrom -t cdrom (linux) +CD-ROM: My CD-ROM doesn't work. + To mount your CD-ROM in DOSBox you have to specify some additional options + when mounting the CD-ROM. + To enable CD-ROM support (includes MSCDEX) in Windows: + - mount d f:\ -t cdrom + in Linux: + - mount d /media/cdrom -t cdrom - In some cases you might want to use a different CD-ROM interface, - for example if CD audio does not work: - To enable SDL-support (does not include low-level CD access!): - - mount d f:\ -t cdrom -usecd 0 -noioctl - To enable ioctl access using digital audio extraction for CD audio - (windows-only, useful for Vista and above): - - mount d f:\ -t cdrom -ioctl_dx - To enable ioctl access using MCI for CD audio (windows-only): - - mount d f:\ -t cdrom -ioctl_mci - To force ioctl-only access (windows-only): - - mount d f:\ -t cdrom -ioctl_dio - To enable low-level aspi-support (win98 with aspi-layer installed): - - mount d f:\ -t cdrom -aspi - - In the commands: - d driveletter you will get in DOSBox - - f:\ location of CD-ROM on your PC. - - 0 The number of the CD-ROM drive, reported by "mount -cd" + In some cases you might want to use a different CD-ROM interface, + for example if CD audio does not work: + To enable SDL-support (does not include low-level CD access!): + - mount d f:\ -t cdrom -usecd 0 -noioctl + To enable ioctl access using digital audio extraction for CD audio + (windows-only, useful for Vista): + - mount d f:\ -t cdrom -ioctl_dx + To enable ioctl access using MCI for CD audio (windows-only): + - mount d f:\ -t cdrom -ioctl_mci + To force ioctl-only access (windows-only): + - mount d f:\ -t cdrom -ioctl_dio + To enable low-level aspi-support (win98 with aspi-layer installed): + - mount d f:\ -t cdrom -aspi + + explanation: - d driveletter you will get in DOSBox (d is the best, + don't change it!) + - f:\ location of CD-ROM on your PC. In most cases it will + be d:\ or e:\ + - 0 The number of the CD-ROM drive, reported by "mount -cd" (note that this value is only needed when using SDL - for CD audio, otherwise it is ignored) - See also the next question: The game/application can't find its CD-ROM. + for CD audio, otherwise it is ignored) + See also the next question: The game/application can't find its CD-ROM. -Q: The game/application can't find its CD-ROM. -A: Be sure to mount the CD-ROM with -t cdrom switch, this will enable the - MSCDEX interface required by DOS games to interface with CD-ROMs. - Also try adding the correct label (-label LABEL) to the mount command, - where LABEL is the CD-label (volume ID) of the CD-ROM. - Under Windows you can specify -ioctl, -aspi or -noioctl. Look at the - description of the mount command in Section 4 for their meaning and the - additional audio-CD related options -ioctl_dx, ioctl_mci, ioctl_dio. - - Try creating a CD-ROM image (preferably CUE/BIN pair) and use the - DOSBox-internal IMGMOUNT tool to mount the image (the CUE sheet). - This enables very good low-level CD-ROM support on any operating system. +CD-ROM: The game/application can't find its CD-ROM. + Be sure to mount the CD-ROM with -t cdrom switch, this will enable the + MSCDEX interface required by DOS games to interface with CD-ROMs. + Also try adding the correct label (-label LABEL) to the mount command, + where LABEL is the CD-label (volume ID) of the CD-ROM. + Under Windows you can specify -ioctl, -aspi or -noioctl. Look at the + description of the mount command in Section 4: "Internal programs" + for their meaning and the + additional audio-CD related options -ioctl_dx, ioctl_mci, ioctl_dio. + + Try creating a CD-ROM image (preferably CUE/BIN pair) and use the + DOSBox's internal IMGMOUNT tool to mount the image (the CUE sheet). + This enables very good low-level CD-ROM support on any operating system. -Q: The mouse doesn't work. -A: Usually, DOSBox detects when a game uses mouse control. When you click on - the screen it should get locked (confined to the DOSBox window) and work. - With certain games, the DOSBox mouse detection doesn't work. In that case - you will have to lock the mouse manually by pressing CTRL-F10. +MOUSE: The mouse doesn't work. + Usually, DOSBox detects when a game uses mouse control. When you click on + the screen it should get locked (confined to the DOSBox window) and work. + With certain games, the DOSBox mouse detection doesn't work. In that case + you will have to lock the mouse manually by pressing CTRL-F10. -Q: There is no sound. -A: Be sure that the sound is correctly configured in the game. This might be - done during the installation or with a setup/setsound utility that - accompanies the game. First see if an autodetection option is provided. If - there is none try selecting soundblaster or soundblaster16 with the default - settings being "address=220 irq=7 dma=1". You might also want to select - midi at address 330 as music device. - The parameters of the emulated soundcards can be changed in the DOSBox - configuration file. - If you still don't get any sound set the core to normal and use some lower - fixed cycles value (like cycles=2000). Also assure that your host operating - sound does provide sound. - In certain cases it might be useful to use a different emulated sound device - like a soundblaster pro (sbtype=sbpro1 in the DOSBox configuration file) or - the gravis ultrasound (gus=true). +SOUND: There is no sound. + Be sure that the sound is correctly configured in the game. This might be + done during the installation or with a setup/setsound utility that + accompanies the game. First see if an autodetection option is provided. If + there is none try selecting Soundblaster or Soundblaster 16 with the default + settings being "address=220 irq=7 dma=1" (sometimes highdma=5). You might + also want to select Sound Canvas/SCC/MPU-401/General MIDI/Wave Blaster + at "address=330 IRQ=2" as music device. + The parameters of the emulated sound cards can be changed in the DOSBox + configuration file. + If you still don't get any sound set the core to normal in DOSBox + configuration and use some lower fixed cycles value (like cycles=2000). Also + assure that your host operating sound does provide sound. + In certain cases it might be useful to use a different emulated sound device + like a soundblaster pro (sbtype=sbpro1 in the DOSBox configuration file) or + the gravis ultrasound (gus=true). -Q: The sound stutters or sounds stretched/weird. -A: You're using too much CPU power to keep DOSBox running at the current speed. - You can lower the cycles, skip frames, reduce the sampling rate of - the respective sound device (see the DOSBox configuration file) or - the mixer device. You can also increase the prebuffer in the configfile. - If you are using cycles=max or =auto, then make sure that there is no - background processes interfering! (especially if they access the harddisk) +SOUND: What sound hardware does DOSBox presently emulate? + DOSBox emulates several legacy sound devices: + - Internal PC speaker/Buzzer + This emulation includes both the tone generator and several forms of + digital sound output through the internal speaker. + - Creative CMS/Gameblaster + The is the first card released by Creative Labs(R). The default + configuration places it on address 220. It is disabled as default. + - Tandy 3 voice + The emulation of this sound hardware is complete with the exception of + the noise channel. The noise channel is not very well documented and as + such is only a best guess as to the sound's accuracy. It is disabled as + default. + - Tandy DAC + Some games may require turning off sound blaster emulation (sbtype=none) + for better tandy DAC sound support. Don't forget to set the sbtype back to + sb16 if you don't use tandy sound. + - Adlib + This emulation is almost perfect and includes the Adlib's ability to + almost play digitized sound. Placed at address 220 (also on 388). + - SoundBlaster 16 / SoundBlaster Pro I & II / SoundBlaster I & II + By default DOSBox provides Soundblaster 16 level 16-bit stereo sound. + You can select a different SoundBlaster version in the configuration of + DOSBox. AWE32 music is not emulated as you can use MPU-401 instead + (see below). + - Disney Sound Source and Covox Speech Thing + Using the printer port, this sound device outputs digital sound only. + Placed at LPT1 + - Gravis Ultrasound + The emulation of this hardware is nearly complete, though the MIDI + capabilities have been left out, since an MPU-401 has been emulated + in other code. For Gravis music you also have to install Gravis drivers + inside DOSBox. It is disabled as default. + - MPU-401 + A MIDI passthrough interface is also emulated. This method of sound + output will only work when used with external device/emulator. + Every Windows XP/Vista/7 and MAC OS has got a default emulator compatible + with: Sound Canvas/SCC/General Standard/General MIDI/Wave Blaster. + A different device/emulator is needed for Roland LAPC/CM-32L/MT-32 + compatibility. -Q: I can't type \ or : in DOSBox. -A: This can happen in various cases, like your host keyboard layout does not - have a matching DOS layout representation (or it was not correctly detected), - or the key mapping is wrong. - Some possible fixes: - 1. Use / instead, or ALT-58 for : and ALT-92 for \. - 2. Change the DOS keyboard layout (see Section 7: Keyboard Layout). - 3. Add the commands you want to execute to the [autoexec]-section - of the DOSBox configuration file. - 4. Open the DOSBox configuration file and change the usescancodes entry. - 5. Switch the keyboard layout of your operating system. - - Note that if the host layout can not be identified, or keyboardlayout is set - to none in the DOSBox configuration file, the standard US layout is used. - In this configuration try the keys around "enter" for the key \ (backslash), - and for the key : (colon) use shift and the keys between "enter" and "l". +SOUND: The sound stutters or sounds stretched/weird. + You may be using too much CPU power to keep DOSBox running at the current + speed. You can lower the cycles, skip frames, reduce the sampling rate of + the respective sound device, increase the prebuffer. See section 13: "The + configuration (options) file" + If you are using cycles=max or =auto, then make sure that there is no + background processes interfering! (especially if they access the harddisk) + Also look at Section 10. "How to speed up/slow down DOSBox" -Q: The keyboard lags. -A: Lower the priority setting in the DOSBox configuration file, for example - set "priority=normal,normal". You might also want to try lowering the cycles - (use a fixed cycle count to start with, like cycles=10000). +KEYBOARD: I can't type \ or : in DOSBox. + This can happen in various cases, like your host keyboard layout does not + have a matching DOS layout representation (or it was not correctly + detected), or the key mapping is wrong. + Some possible fixes: + 1. Use / instead, or ALT-58 for : and ALT-92 for \. + 2. Change the DOS keyboard layout (see Section 8: Keyboard Layout). + 3. Add the commands you want to execute to the [autoexec] section + of the DOSBox configuration file. + 4. Open the DOSBox configuration file and change the usescancodes entry. + 5. Switch the keyboard layout of your operating system. + + Note that if the host layout can not be identified, or keyboardlayout is + set to none in the DOSBox configuration file, the standard US layout is + used. In this configuration try the keys around "enter" for the key \ + (backslash), and for the key : (colon) use shift and the keys between + "enter" and "L". -Q: The cursor always moves into one direction! -A: See if it still happens if you disable the joystick emulation, - set joysticktype=none in the [joystick] section of your DOSBox - configuration file. Maybe also try unplugging any joystick/gamepad. - If you want to use the joystick in the game, try setting timed=false - and be sure to calibrate the joystick (both in your OS as well as - in the game or the game's setup program). +KEYBOARD: Right Shift and "\" doesn't work in DOSBox. (Windows only) + This may happen if Windows thinks that you have more than one keyboard + connected to your PC when you use some remote control devices. + To verity this problem run cmd.exe, navigate to DOSBox program folder + and type: + set sdl_videodriver=windib + dosbox.exe + check whether keyboard started to work properly. As windib is slower it is + best to use one of the two solutions provided here: + http://vogons.zetafleet.com/viewtopic.php?t=24072 -Q: The game/application runs much too slow! -A: Look at the section "How to run resource-demanding games" for more - information. +KEYBOARD: The keyboard lags. + Lower the priority setting in the DOSBox configuration file, for example + set "priority=normal,normal". You might also want to try lowering the + cycles (use a fixed cycle amount to start with, like cycles=10000). -Q: The game/application does not run at all/crashes! -A: Look at Section 10: Troubleshooting +CONTROL: The character/cursor/mouse pointer always moves into one direction! + See if it still happens if you disable the joystick emulation, + set joysticktype=none in the [joystick] section of your DOSBox + configuration file. Maybe also try unplugging any joystick/gamepad. + If you want to use the joystick in the game, try setting timed=false + and be sure to calibrate the joystick (both in your OS as well as + in the game or the game's setup program). -Q: Can DOSBox harm my computer? -A: DOSBox can not harm your computer more than any other resource demanding - program. Increasing the cycles does not overclock your real CPU. - Setting the cycles too high has a negative performance effect on the - software running inside DOSBox. +SPEED: The game/application runs much too slow/too fast! + Look at the section 10: "How to speed up/slow down DOSBox" for more + information. -Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. -A: This is possible! Just create a config file: config -writeconf configfile. - Start your favourite editor and look through the settings. To start DOSBox - with your new settings: dosbox -conf configfile - See the description of the config command in Section 4 for more details. +CRASH: The game/application does not run at all/crashes! + Look at Section 11: Troubleshooting -Q: What sound hardware does DOSBox presently emulate? -A: DOSBox emulates several legacy sound devices: - - Internal PC speaker - This emulation includes both the tone generator and several forms of - digital sound output through the internal speaker. - - Creative CMS/Gameblaster - The is the first card released by Creative Labs(R). The default - configuration places it on port 0x220. It should be noted that enabling - this with the Adlib emulation may result in conflicts. - - Tandy 3 voice - The emulation of this sound hardware is complete with the exception of - the noise channel. The noise channel is not very well documented and as - such is only a best guess as to the sound's accuracy. - - Tandy DAC - The Tandy DAC BIOS interface as well as low level access are emulated. - - Adlib - This emulation is almost perfect and includes the Adlib's ability to - almost play digitized sound. - - SoundBlaster 16 / SoundBlaster Pro I & II / SoundBlaster I & II - By default DOSBox provides Soundblaster 16 level 16-bit stereo sound. - You can select a different SoundBlaster version in the configfile of - DOSBox (See Internal Commands: CONFIG). - - Disney Soundsource - Using the printer port, this sound device outputs digital sound only. - - Gravis Ultrasound - The emulation of this hardware is nearly complete, though the MIDI - capabilities have been left out, since an MPU-401 has been - emulated in other code. - - MPU-401 - A MIDI passthrough interface is also emulated. This method of sound - output will only work when used with a General Midi or MT-32 device. +CRASH: DOSBox crashes on startup!. + Look at Section 11: Troubleshooting -Q: DOSBox crashes on startup and I'm running arts. -A: This isn't really a DOSBox problem, but the solution is to set the - environment variable SDL_AUDIODRIVER to alsa or oss. +GAME: My Build game(Duke3D/Blood/Shadow Warrior) has problems. + First of all, try to find a port of the game. Those will offer a better + experience. To fix the graphics problem that occurs in DOSBox on higher + resolutions: Open the configuration file of DOSBox and search for + machine=svga_s3. Change svga_s3 to vesa_nolfb + Change memsize=16 to memsize=63 -Q: My Build game(Duke3D/Blood/Shadow Warrior) has problems. -A: First of all, try to find a port of the game. Those will offer a - better experience. To fix the graphics problem that occurs in - DOSBox on higher resolutions. Open the configuration file of - DOSBox and search for machine=svga_s3. Change svga_s3 to vesa_nolfb +SAFETY: Can DOSBox harm my computer? + DOSBox can not harm your computer more than any other resource demanding + program. Increasing the cycles does not overclock your real CPU. + Setting the cycles too high has a negative performance effect on the + software running inside DOSBox. -Q: Great README, but I still don't get it. -A: A look at "The Newbie's pictorial guide to DOSBox" located at - http://vogons.zetafleet.com/viewforum.php?f=39 might help you. - Also try the wiki of DOSBox: - http://www.dosbox.com/wiki/ +OPTIONS: I would like to change DOSBox's options. + Look at Section 13. "The configuration (options) file" -For more questions read the remainder of this README and/or check -the site/forum: -http://www.dosbox.com +HELP: Great Manual, but I still don't get it. + For more questions read the rest of this Manual. You may also look at: + guides located at http://vogons.zetafleet.com/viewforum.php?f=39 + the wiki of DOSBox http://www.dosbox.com/wiki/ + the site/forum: http://www.dosbox.com -========= -3. Usage: -========= +=========================== +3. Command Line Parameters: +=========================== + +An overview of the command line options you can give to DOSBox. Although +in most cases it is easier to use DOSBox's configuration file instead. +See: Section 13. "The configuration (options) file" + +To be able to use Command Line Parameters: +(Windows) open cmd.exe or command.com or edit the shortcut to dosbox.exe +(Linux) use console +(MAC OS X) start terminal.app and navigate to: + /applications/dosbox.app/contents/macos/dosbox -An overview of the command line options you can give to DOSBox. -Windows Users must open cmd.exe or command.com or edit the shortcut to -dosbox.exe for this. The options are valid for all operating systems unless noted in the option description: -dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] - [-lang languagefile] [-machine machinetype] [-noconsole] - [-startmapper] [-noautoexec] [-securemode] - [-scaler scaler | -forcescaler scaler] - [-version] +dosbox [name] [-exit] [-c command] [-fullscreen] [-userconf] + [-conf congfigfilelocation] [-lang languagefilelocation] + [-machine machine type] [-noconsole] [-startmapper] [-noautoexec] + [-securemode] [-scaler scaler | -forcescaler scaler] [-version] + [-socket socket] dosbox -version dosbox -editconf program @@ -315,58 +345,64 @@ dosbox -erasemapper name If "name" is a directory it will mount that as the C: drive. - If "name" is an executable it will mount the directory of "name" + If "name" is an executable it will mount the directory of "name" as the C: drive and execute "name". - - -exit + + -exit DOSBox will close itself when the DOS application "name" ends. -c command Runs the specified command before running "name". Multiple commands can be specified. Each command should start with "-c" though. - A command can be: an Internal Program, a DOS command or an executable + A command can be: an Internal Program, a DOS command or an executable on a mounted drive. -fullscreen Starts DOSBox in fullscreen mode. - -conf configfile - Start DOSBox with the options specified in "configfile". - Multiple -conf options may be present. - See Section 11 for more details. + -userconf + Start DOSBox with the users specific configuration file. Can be used + together with multiple -conf parameters, but -userconf will always be + loaded before them. - -lang languagefile - Start DOSBox using the language specified in "languagefile". + -conf configfilelocation + Start DOSBox with the options specified in "configfilelocation". + Multiple -conf options may be present. + See Section 13 for more details. + + -lang languagefilelocation + Start DOSBox using the language specified in "languagefilelocation". + See Section 14 for more details. -machine machinetype Setup DOSBox to emulate a specific type of machine. Valid choices are: - hercules, cga, pcjr, tandy, svga_s3 (default) as well as the additional - svga chipsets listed in the help of the DOSBox configuration file. + hercules, cga, ega, pcjr, tandy, svga_s3 (default) as well as + the additional svga chipsets listed in the DOSBox configuration file. svga_s3 enables vesa emulation as well. For some special vga effects the machinetype vgaonly can be used, - note that this disables svga capabilites and might be (considerably) - slower due to the much higher emulation precision. - The machinetype affects both the videocard and the available soundcards. + note that this disables svga capabilities and might be slower due to the + higher emulation precision. + The machinetype affects the video card and the available sound cards. -noconsole (Windows Only) - Start DOSBox without showing the console window. Output will - be redirected to stdout.txt and stderr.txt - + Start DOSBox without showing DOSBox Status Window (console). + Output will be redirected to stdout.txt and stderr.txt + -startmapper - Enter the keymapper directly on startup. Useful for people with + Enter the keymapper directly on startup. Useful for people with keyboard problems. -noautoexec Skips the [autoexec] section of the loaded configuration file. -securemode - Same as -noautoexec, but adds config.com -securemode at the + Same as -noautoexec, but adds config.com -securemode at the bottom of AUTOEXEC.BAT (which in turn disables any changes to how the drives are mounted inside DOSBox). -scaler scaler - Uses the scaler specified by "scaler". See the DOSBox configuration - file for the available scalers. + Uses the scaler specified by "scaler". See the DOSBox configuration file + for the available scalers. -forcescaler scaler Similar to the -scaler parameter, but tries to force usage of @@ -381,33 +417,36 @@ dosbox -erasemapper move to second program if the first one fails to start. -opencaptures program - calls program with as first paramater the location of the captures + calls program with as first parameter the location of the captures folder. - + -printconf prints the location of the default configuration file. - -eraseconf + -resetconf removes the default configuration file. - -erasemapper + -resetmapper removes the mapperfile used by the default clean configuration file. -Note: If a name/command/configfile/languagefile contains a space, put - the whole name/command/configfile/languagefile between quotes - ("command or file name"). If you need to use quotes within quotes - (most likely with -c and mount): - Windows and OS/2 users can use single quotes inside the double quotes. - Other people should be able to use escaped double quotes inside the - double quotes. - Windows: -c "mount c 'c:\program files\'" - Linux: -c "mount c \"/tmp/name with space\"" + -socket + passes the socket number to the nullmodem emulation. See Section 9: + "Serial Multiplayer feature." -For example (Windows): +Note: If a name/command/configfilelocation/languagefilelocation contains + a space, put the whole name/command/configfilelocation/languagefilelocation + between quotes ("command or file name"). If you need to use quotes within + quotes (most likely with -c and mount): + Windows and OS/2 users can use single quotes inside the double quotes. + Other people should be able to use escaped double quotes inside the + double quotes. + Windows: -c "mount c 'c:\My folder with DOS games\'" + Linux: -c "mount c \"/tmp/name with space\"" -dosbox c:\atlantis\atlantis.exe -c "MOUNT D C:\SAVES" - This mounts c:\atlantis as c:\ and runs atlantis.exe. - Before it does that it would first mount C:\SAVES as the D drive. +A rather unusual example, just to demonstrate what you can do (Windows): +dosbox D:\folder\file.exe -c "MOUNT Y H:\MyFolder" + This mounts D:\folder as C:\ and runs file.exe. + Before it does that, it will first mount H:\MyFolder as the Y drive. In Windows, you can also drag directories/files onto the DOSBox executable. @@ -420,10 +459,10 @@ In Windows, you can also drag directories/files onto the DOSBox executable. DOSBox supports most of the DOS commands found in command.com. To get a list of the internal commands type "HELP" at the prompt. -In addition, the following commands are available: +In addition, the following commands are available: -MOUNT "Emulated Drive letter" "Real Drive or Directory" - [-t type] [-aspi] [-ioctl] [-noioctl] [-usecd number] [-size drivesize] +MOUNT "Emulated Drive letter" "Real Drive or Directory" + [-t type] [-aspi] [-ioctl] [-noioctl] [-usecd number] [-size drivesize] [-label drivelabel] [-freesize size_in_mb] [-freesize size_in_kb (floppies)] MOUNT -cd @@ -432,16 +471,17 @@ MOUNT -u "Emulated Drive letter" Program to mount local directories as drives inside DOSBox. "Emulated Drive letter" - The driveletter inside DOSBox (eg. C). + The driveletter inside DOSBox (for example C). "Real Drive letter (usually for CD-ROMs in Windows) or Directory" The local directory you want accessible inside DOSBox. -t type - Type of the mounted directory. Supported are: dir (default), - floppy, cdrom. + Type of the mounted directory. + Supported are: dir (default), floppy, cdrom. -size drivesize + (experts only) Sets the size of the drive, where drivesize is of the form "bps,spc,tcl,fcl": bps: bytes per sector, by default 512 for regular drives and @@ -451,16 +491,16 @@ MOUNT -u "Emulated Drive letter" fcl: total free clusters, between 1 and tcl -freesize size_in_mb | size_in_kb - Sets the amount of free space available on a drive in megabytes - (regular drives) or kilobytes (floppy drives). - This is a simpler version of -size. + Sets the amount of free space available on a drive + in megabytes (regular drives) or kilobytes (floppy drives). + This is a simpler version of -size. -label drivelabel - Sets the name of the drive to "drivelabel". Needed on some - systems if the CD-ROM label isn't read correctly (useful when a - program can't find its CD-ROM). If you don't specify a label and no - lowlevel support is selected (that is omitting the -usecd # and/or - -aspi parameters, or specifying -noioctl): + Sets the name of the drive to "drivelabel". Needed on some systems + if the CD-ROM label isn't read correctly (useful when a program + can't find its CD-ROM). If you don't specify a label + and no lowlevel support is selected (that is omitting the -usecd # + and/or -aspi parameters, or specifying -noioctl): For Windows: label is extracted from "Real Drive". For Linux: label is set to NO_LABEL. @@ -468,18 +508,18 @@ MOUNT -u "Emulated Drive letter" is mounted. It will not be updated !! -aspi - Forces use of the aspi layer (obsolete). Only valid if mounting a - CD-ROM under Windows systems with an ASPI-Layer. + Forces use of the aspi layer. Only valid if mounting a CD-ROM under + Windows systems with an ASPI-Layer. -ioctl (automatic selection of the CD audio interface) -ioctl_dx (digital audio extraction used for CD audio) -ioctl_dio (ioctl calls used for CD audio) -ioctl_mci (MCI used for CD audio) - Forces use of ioctl commands. Only valid if mounting a CD-ROM under + Forces use of ioctl commands. Only valid if mounting a CD-ROM under a Windows OS which support them (Win2000/XP/NT). The various choices only differ in the way CD audio is handled, - preferrably -ioctl_dio is used (lowest workload), but this might not - work on all systems so -ioctl_dx (or -ioctl_mci) can be used. + preferably -ioctl_dio is used (lowest workload), but this might not + work on all systems, so -ioctl_dx (or -ioctl_mci) can be used. -noioctl Forces use of the SDL CD-ROM layer. Valid on all systems. @@ -498,48 +538,78 @@ MOUNT -u "Emulated Drive letter" -u Removes the mount. Doesn't work for Z:\. - Note: It's possible to mount a local directory as CD-ROM drive. - Hardware support is then missing. + Note: It's possible to mount a local directory as CD-ROM drive, + but hardware support is then missing. Basically MOUNT allows you to connect real hardware to DOSBox's emulated PC. So MOUNT C C:\GAMES tells DOSBox to use your C:\GAMES directory as drive C: - in DOSBox. It also allows you to change the drive letter identification - for programs that demand specific drive letters. - - For example: Touche: Adventures of The Fifth Musketeer must be run on your C: - drive. Using DOSBox and its mount command, you can trick the game into - believing it is on the C drive, while you can still place it where you - like. For example, if the game is in D:\OLDGAMES\TOUCHE, the command - MOUNT C D:\OLDGAMES will allow you to run Touche from the D drive. + in DOSBox. MOUNT C E:\SomeFolder tells DOSBox to use your E:\SomeFolder + directory as drive C: in DOSBox. Mounting your entire C drive with MOUNT C C:\ is NOT recommended! The same is true for mounting the root of any other drive, except for CD-ROMs (due to - their read-only nature). Otherwise if you or DOSBox make a mistake you may - lose all your files. - It is recommended to put all your applications/games into a subdirectory - and mount that. + their read-only nature). + Otherwise if you or DOSBox make a mistake you may lose all your files. + Also never mount a "Windows" or "Program Files" folders or their subfolders + in Windows Vista/7 as DOSBox may not work correctly, or will stop working + correctly later. It is recommended to keep all your dos applications/games + in a simple folder (for example c:\dosgames) and mount that. - General MOUNT Examples: - 1. To mount c:\DirX as a floppy : - mount a c:\DirX -t floppy - 2. To mount system CD-ROM drive E as CD-ROM drive D in DOSBox: - mount d e:\ -t cdrom - 3. To mount system CD-ROM drive at mountpoint /media/cdrom as CD-ROM drive D - in DOSBox: - mount d /media/cdrom -t cdrom -usecd 0 - 4. To mount a drive with ~870 mb free diskspace (simple version): - mount c d:\ -freesize 870 - 5. To mount a drive with ~870 mb free diskspace (experts only, full control): - mount c d:\ -size 512,127,16513,13500 - 6. To mount /home/user/dirY as drive C in DOSBox: - mount c /home/user/dirY - 7. To mount the directory where DOSBox was started as D in DOSBox: - mount d . - (note the . which represents the directory where DOSBox was started) + You should always install your game inside DOSBox. + So if you have the game on CD you always (even after installation!) + have to mount both: folder as a harddisk drive and a CD-ROM. + HardDisk should always be mounted as c + CD-ROM should always be mounted as d + Floppy should always be mounted as a (or b) + + Basic MOUNT Examples for normal usage (Windows): + + 1. To mount a folder as a harddisk drive: + mount c d:\dosgames + + 3. To mount your CD-ROM drive E as CD-ROM drive D in DOSBox: + mount d e:\ -t cdrom + + 2. To mount your drive a: as a floppy: + mount a a:\ -t floppy + + Advanced MOUNT examples (Windows): + + 4. To mount a hard disk drive with ~870 mb free diskspace (simple version): + mount c d:\dosgames -freesize 870 + + 5. To mount a drive with ~870 mb free diskspace (experts only, full control): + mount c d:\dosgames -size 512,127,16513,13500 + + 1. To mount c:\dosgames\floppy as a floppy: + mount a c:\dosgames\floppy -t floppy + + + Other MOUNT examples: + + 3. To mount system CD-ROM drive at mountpoint /media/cdrom as CD-ROM drive D + in DOSBox: + mount d /media/cdrom -t cdrom -usecd 0 + + 6. To mount /home/user/dosgames as drive C in DOSBox: + mount c /home/user/dosgames + + 7. To mount the directory where DOSBox was started as C in DOSBox: + mount c . + (note the . which represents the directory where DOSBox was started, + on Windows Vista/7 don't use this if you installed DOSBox + to your "Program Files" folder) + + If you want to mount a CD image or floppy image, check IMGMOUNT. + MOUNT also works with images but only if you use external program, + for example (both are free): + - Daemon Tools Lite (for CD images), + - Virtual Floppy Drive (for floppy images). + Although IMGMOUNT can give better compatibility. MEM - Program to display the amount of free memory. + Program to display the amount and type of free memory. VER @@ -547,56 +617,57 @@ VER set major_version [minor_version] Display the current DOSBox version and reported DOS version (parameterless usage). Change the reported DOS version with the "set" parameter, - for example: "VER set 6 22" to have DOSBox report DOS 6.22 - as version number. + for example: "VER set 6 22" to have DOSBox report DOS 6.22 as version number. -CONFIG -writeconf localfile -CONFIG -writelang localfile +CONFIG -writeconf filelocation +CONFIG -writelang filelocation CONFIG -securemode CONFIG -set "section property=value" CONFIG -get "section property" - CONFIG can be used to change or query various settings of DOSBox + CONFIG can be used to change or query various settings of DOSBox during runtime. It can save the current settings and language strings to - disk. Information about all possible sections and properties can - be found in Section 11 (The Config File). + disk. Information about all possible sections and properties can + be found in Section 13: "The configuration (options) file". - -writeconf localfile - Write the current configuration settings to file. "localfile" is - located on the local drive, not a mounted drive in DOSBox. - The configuration file controls various settings of DOSBox: - the amount of emulated memory, the emulated soundcards and many more - things. It allows access to AUTOEXEC.BAT as well. - See Section 11 (The Config File) for more information. + -writeconf filelocation + Write the current configuration settings to a file in a specified location. + "filelocation" is located on the local drive, not a mounted drive in DOSBox. + The configuration file controls various settings of DOSBox: + the amount of emulated memory, the emulated sound cards and many more + things. It allows access to AUTOEXEC.BAT as well. + See Section 13: "The configuration (options) file" for more information. - -writelang localfile - Write the current language settings to file. "localfile" is - located on the local drive, not a mounted drive in DOSBox. - The language file controls all visible output of the internal commands - and the internal DOS. + -writelang filelocation + Write the current language settings to a file in a specified location. + "filelocation" is located on the local drive, not a mounted drive + in DOSBox. The language file controls all visible output of the internal + commands and the internal DOS. + See Section 14: "The Language File" for more information. -securemode - Switches DOSBox to a more secure mode. In this mode the 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 DOSBox.) + Switches DOSBox to a more secure mode. In this mode the 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 DOSBox.) -set "section property=value" - CONFIG will attempt to set the property to new value. Currently - CONFIG can not report whether the command succeeded or not. + CONFIG will attempt to set the property to new value. + Currently CONFIG can not report whether the command succeeded or not. -get "section property" - The current value of the property is reported and stored in the - environment variable %CONFIG%. This can be used to store the value - when using batch files. + The current value of the property is reported and stored in the + environment variable %CONFIG%. This can be used to store the value + when using batch files. Both "-set" and "-get" work from batch files and can be used to set up your - own preferences for each game. - + own preferences for each game. Although it may be easier to use separate + DOSBox's configuration files for each game instead. + Examples: - 1. To create a configfile in your current directory: - config -writeconf dosbox.conf + 1. To create a configuration file in your c:\dosgames directory: + config -writeconf c:\dosgames\dosbox.conf 2. To set the cpu cycles to 10000: config -set "cpu cycles=10000" 3. To turn ems memory emulation off: @@ -608,120 +679,134 @@ CONFIG -get "section property" LOADFIX [-size] [program] [program-parameters] LOADFIX -f Program to reduce the amount of available conventional memory. - Useful for old programs which don't expect much memory to be free. + Useful for old programs which don't expect much memory to be free. - -size + -size number of kilobytes to "eat up", default = 64kb - + -f frees all previously allocated memory - + Examples: - 1. To start mm2.exe and allocate 64kb memory - (mm2 will have 64 kb less available) : + 1. To start mm2.exe and allocate 64kb memory + (mm2 will have 64 kb less available): loadfix mm2 - 2. To start mm2.exe and allocate 32kb memory : + 2. To start mm2.exe and allocate 32kb memory: loadfix -32 mm2 - 3. To free previous allocated memory : + 3. To free previous allocated memory: loadfix -f RESCAN Make DOSBox reread the directory structure. Useful if you changed something on a mounted drive outside of DOSBox. (CTRL - F4 does this as well!) - + MIXER - Makes DOSBox display its current volume settings. + Makes DOSBox display its current volume settings. Here's how you can change them: - + mixer channel left:right [/NOSHOW] [/LISTMIDI] - + channel - Can be one of the following: MASTER, DISNEY, SPKR, GUS, SB, FM [, CDAUDIO]. - CDAUDIO is only available if a CD-ROM interface with volume control is - enabled (CD image, ioctl_dx). - + Can be one of the following: MASTER, DISNEY, SPKR, GUS, SB, FM [, CDAUDIO]. + CDAUDIO is only available if a CD-ROM interface with volume control is + enabled (CD image, ioctl_dx). + left:right - The volume levels in percentages. If you put a D in front it will be - in decibel (Example: mixer gus d-10). - + The volume levels in percentages. If you put a D in front it will be + in decibel (Example: mixer gus d-10). + /NOSHOW - Prevents DOSBox from showing the result if you set one - of the volume levels. + Prevents DOSBox from showing the result if you set one + of the volume levels. /LISTMIDI - Lists the available midi devices on your PC (Windows). To select a - device other than the Windows default midi-mapper, add a line - 'midiconfig=id' to the [midi] section in the configuration file, - where 'id' is the number for the device as listed by LISTMIDI. + In Windows lists the available midi devices on your PC. To select a device + other than the Windows default midi-mapper, change the line 'midiconfig=' + in the [midi] section of the configuration file to 'midiconfig=id', where + 'id' is the number for the device as listed by LISTMIDI. eg. midiconfig=2 + + In Linux this option doesn't work, but you get similar results by using + 'pmidi -l' in console. Then change the line 'midiconfig=' to + 'midiconfig=port', where 'port' is the port for the device as listed by + 'pmidi -l'. eg. midiconfig=128:0 IMGMOUNT A utility to mount disk images and CD-ROM images in DOSBox. - - IMGMOUNT DRIVE [imagefile] -t [image_type] -fs [image_format] + + IMGMOUNT DRIVE [imagefile] -t [image_type] -fs [image_format] -size [sectorsbytesize, sectorsperhead, heads, cylinders] - IMGMOUNT DRIVE [imagefile1, .. ,imagefileN] -t iso -fs iso + IMGMOUNT DRIVE [imagefile1 imagefile2 .. imagefileN] -t cdrom -fs iso imagefile - Location of the image file to mount in DOSBox. The location can - be on a mounted drive inside DOSBox, or on your real disk. It is - possible to mount CD-ROM images (ISOs or CUE/BIN) as well, if you - need CD swapping capabilities specify all images in succession + Location of the image file to mount in DOSBox. The location can be + on a mounted drive inside DOSBox, or on your real disk. It is possible + to mount CD-ROM images (ISOs or CUE/BIN or CUE/IMG) too. + If you need CD swapping capabilities, specify all images in succession (see the next entry). - CUE/BIN pairs are the preferred CD-ROM image type as they can + CUE/BIN pairs and cue/img are the preferred CD-ROM image types as they can store audio tracks compared to ISOs (which are data-only). For the CUE/BIN mounting always specify the CUE sheet. - - imagefile1, .. ,imagefileN + + imagefile1 imagefile2 .. imagefileN Location of the image files to mount in DOSBox. Specifying a number - of image files is only allowed for CD-ROM images. The CD's can be - swapped with CTRL-F4 at any time. This is required for games which - use multiple CD-ROMs and require the CD to be switched during the - gameplay at some point. - - -t + of image files is only allowed for CD-ROM images. + The CD's can be swapped with CTRL-F4 at any time. + This is required for games which use multiple CD-ROMs and require the CD + to be switched during the gameplay at some point. + + -t The following are valid image types: floppy: Specifies a floppy image. DOSBox will automatically identify the disk geometry (360K, 1.2MB, 720K, 1.44MB, etc). - iso: Specifies a CD-ROM iso image. The geometry is automatic and - set for this size. This can be an iso or a cue/bin pair. - hdd: Specifies a harddrive image. The proper CHS geometry - must be set for this to work. + cdrom: Specifies a CD-ROM image. The geometry is automatic and + set for this size. This can be an iso or a cue/bin pair or + a cue/img pair. + hdd: Specifies a harddrive image. The proper CHS geometry must be set + for this to work. - -fs + -fs The following are valid file system formats: iso: Specifies the ISO 9660 CD-ROM format. - fat: Specifies that the image uses the FAT file system. DOSBox will attempt - to mount this image as a drive in DOSBox and make the files - available from inside DOSBox. + fat: Specifies that the image uses the FAT file system. DOSBox will + attempt to mount this image as a drive in DOSBox and make + the files available from inside DOSBox. none: DOSBox will make no attempt to read the file system on the disk. - This is useful if you need to format it or if you want to boot - the disk using the BOOT command. When using the "none" - filesystem, you must specify the drive number (2 or 3, - where 2 = master, 3 = slave) rather than a drive letter. - For example, to mount a 70MB image as the slave drive device, + This is useful if you need to format it or if you want to boot + the disk using the BOOT command. When using the "none" + filesystem, you must specify the drive number (2 or 3, + where 2 = master, 3 = slave) rather than a drive letter. + For example, to mount a 70MB image as the slave drive device, you would type (without the quotes): - "imgmount 3 d:\test.img -size 512,63,16,142 -fs none" + "imgmount 3 d:\test.img -size 512,63,16,142 -fs none" Compare this with a mount to be able to access the drive - within DOSBox, which would read as: + within DOSBox, which would read as: "imgmount e: d:\test.img -size 512,63,16,142" - -size + -size The Cylinders, Heads and Sectors of the drive. Required to mount hard drive images. - - An example how to mount CD-ROM images: - 1a. mount c /tmp - 1b. imgmount d c:\myiso.iso -t iso + + An example how to mount CD-ROM images (in Linux): + 1. imgmount d /tmp/cdimage1.cue /tmp/cdimage2.cue -t cdrom or (which also works): - 2. imgmount d /tmp/myiso.iso -t iso + 2a. mount c /tmp + 2b. imgmount d c:\cdimage1.cue c:\cdimage2.cue -t cdrom + (in Windows): + imgmount d f:\img\CD1.cue f:\img\CD2.cue f:\img\CD3.cue -t cdrom + imgmount d "g:\img\7th Guest CD1.cue" "g:\img\7th Guest CD2.cue" -t cdrom + Don't forget that you can also use MOUNT with images, but only if you use + external program, for example (both are free): + - Daemon Tools Lite (for CD images), + - Virtual Floppy Drive (for floppy images). + Although IMGMOUNT can give better compatibility. BOOT - Boot will start floppy images or hard disk images independent of the - operating system emulation offered by DOSBox. This will allow you to + Boot will start floppy images or hard disk images independent of + the operating system emulation offered by DOSBox. This will allow you to play booter floppies or boot other operating systems inside DOSBox. If the target emulated system is PCjr (machine=pcjr) the boot command can be used to load PCjr cartridges (.jrc). @@ -729,19 +814,19 @@ BOOT BOOT [diskimg1.img diskimg2.img .. diskimgN.img] [-l driveletter] BOOT [cart.jrc] (PCjr only) - diskimgN.img - This can be any number of floppy disk images one wants mounted after + diskimg1.img diskimg2.img .. diskimgN.img + This can be any number of floppy disk images one wants mounted after DOSBox boots the specified drive letter. - To swap between images, hit CTRL-F4 to change from the current disk - to the next disk in the list. The list will loop back from the last + To swap between images, hit CTRL-F4 to change from the current disk + to the next disk in the list. The list will loop back from the last disk image to the beginning. [-l driveletter] - This parameter allows you to specify the drive to boot from. - The default is the A drive, the floppy drive. You can also boot - a hard drive image mounted as master by specifying "-l C" + This parameter allows you to specify the drive to boot from. + The default is the A drive, the floppy drive. You can also boot + a hard drive image mounted as master by specifying "-l C" without the quotes, or the drive as slave by specifying "-l D" - + cart.jrc (PCjr only) When emulation of a PCjr is enabled, cartridges can be loaded with the BOOT command. Support is still limited. @@ -751,50 +836,50 @@ IPX You need to enable IPX networking in the configuration file of DOSBox. - All of the IPX networking is managed through the internal DOSBox program - IPXNET. For help on the IPX networking from inside DOSBox, type - "IPXNET HELP" (without quotes) and the program will list the commands - and relevant documentation. + All of the IPX networking is managed through the internal DOSBox program + IPXNET. For help on the IPX networking from inside DOSBox, type + "IPXNET HELP" (without quotes) and the program will list the commands + and relevant documentation. - With regard to actually setting up a network, one system needs to be + With regard to actually setting up a network, one system needs to be the server. To set this up, type "IPXNET STARTSERVER" (without the quotes) in a DOSBox session. The server DOSBox session will automatically add itself to the virtual IPX network. For every additional computer that should be part of the virtual IPX network, you'll need to type - "IPXNET CONNECT ". + "IPXNET CONNECT ". For example, if your server is at bob.dosbox.com, you would type - "IPXNET CONNECT bob.dosbox.com" on every non-server system. - - To play games that need Netbios a file named NETBIOS.EXE from Novell is - needed. Establish the IPX connection as explained above, then run - "netbios.exe". + "IPXNET CONNECT bob.dosbox.com" on every non-server system. - The following is an IPXNET command reference: + To play games that need Netbios a file named NETBIOS.EXE from Novell is + needed. Establish the IPX connection as explained above, then run + "netbios.exe". - IPXNET CONNECT + The following is an IPXNET command reference: - IPXNET CONNECT opens a connection to an IPX tunnelling server - running on another DOSBox session. The "address" parameter specifies - the IP address or host name of the server computer. You can also - specify the UDP port to use. By default IPXNET uses port 213 - the - assigned IANA port for IPX tunnelling - for its connection. + IPXNET CONNECT - The syntax for IPXNET CONNECT is: - IPXNET CONNECT address + IPXNET CONNECT opens a connection to an IPX tunneling server + running on another DOSBox session. The "address" parameter specifies + the IP address or host name of the server computer. You can also + specify the UDP port to use. By default IPXNET uses port 213 - the + assigned IANA port for IPX tunneling - for its connection. - IPXNET DISCONNECT + The syntax for IPXNET CONNECT is: + IPXNET CONNECT address - IPXNET DISCONNECT closes the connection to the IPX tunnelling server. + IPXNET DISCONNECT - The syntax for IPXNET DISCONNECT is: - IPXNET DISCONNECT + IPXNET DISCONNECT closes the connection to the IPX tunneling server. - IPXNET STARTSERVER + The syntax for IPXNET DISCONNECT is: + IPXNET DISCONNECT - IPXNET STARTSERVER starts an IPX tunnelling server on this DOSBox - session. By default, the server will accept connections on UDP port - 213, though this can be changed. Once the server is started, DOSBox - will automatically start a client connection to the IPX tunnelling server. + IPXNET STARTSERVER + + IPXNET STARTSERVER starts an IPX tunneling server on this DOSBox + session. By default, the server will accept connections on UDP port + 213, though this can be changed. Once the server is started, DOSBox + will automatically start a client connection to the IPX tunneling server. The syntax for IPXNET STARTSERVER is: IPXNET STARTSERVER @@ -807,40 +892,43 @@ IPX IPXNET STOPSERVER - IPXNET STOPSERVER stops the IPX tunnelling server running on this DOSBox - session. Care should be taken to ensure that all other connections have - terminated as well, since stopping the server may cause lockups on other - machines that are still using the IPX tunnelling server. + IPXNET STOPSERVER stops the IPX tunneling server running on this DOSBox + session. Care should be taken to ensure that all other connections have + terminated as well, since stopping the server may cause lockups on other + machines that are still using the IPX tunneling server. - The syntax for IPXNET STOPSERVER is: - IPXNET STOPSERVER + The syntax for IPXNET STOPSERVER is: + IPXNET STOPSERVER IPXNET PING - IPXNET PING broadcasts a ping request through the IPX tunnelled network. - In response, all other connected computers will respond to the ping - and report the time it took to receive and send the ping message. + IPXNET PING broadcasts a ping request through the IPX tunneled network. + In response, all other connected computers will respond to the ping + and report the time it took to receive and send the ping message. - The syntax for IPXNET PING is: + The syntax for IPXNET PING is: IPXNET PING IPXNET STATUS - IPXNET STATUS reports the current state of this DOSBox session's - IPX tunnelling network. For a list of all computers connected to the - network use the IPXNET PING command. + IPXNET STATUS reports the current state of this DOSBox session's + IPX tunneling network. For a list of all computers connected to the + network use the IPXNET PING command. - The syntax for IPXNET STATUS is: - IPXNET STATUS + The syntax for IPXNET STATUS is: + IPXNET STATUS -KEYB [languagecode [codepage [codepagefile]]] - Change the keyboard layout. For detailed information about keyboard - layouts please see Section 7. +KEYB [keyboardlayoutcode [codepage [codepagefile]]] - [languagecode] is a string consisting of two (in special cases more) - characters, examples are GK (Greece) or IT (Italy). It specifies - the keyboard layout to be used. + Change the keyboard layout. For detailed information about keyboard layouts + please see Section 8: "Keyboard Layout" + + [keyboardlayoutcode] is a string consisting of five or less characters, + examples are PL214 (Polish typists) or PL457 (Polish programmers). + It specifies the keyboard layout to be used. + The list of all layouts built into DOSBox is here: + http://vogons.zetafleet.com/viewtopic.php?t=21824 [codepage] is the number of the codepage to be used. The keyboard layout has to provide support for the specified codepage, otherwise the layout @@ -850,17 +938,19 @@ KEYB [languagecode [codepage [codepagefile]]] [codepagefile] can be used to load codepages that are yet not compiled into DOSBox. This is only needed when DOSBox does not find the codepage. - + If no codepagefile is specified, but you place all ten ega.cpx files + (from FreeDOS) in the DOSBox program folder, an appropriate codepagefile + for the requested layout/codepage is chosen automatically. Examples: - 1. To load the german keyboard layout (automatically uses codepage 858): - keyb gr - 2. To load the russian keyboard layout with codepage 866: - keyb ru 866 + 1. To load the polish typist keys layout (automatically uses codepage 852): + keyb pl214 + 2. To load one of russian keyboard layouts with codepage 866: + keyb ru441 866 In order to type russian characters press ALT+RIGHT-SHIFT. - 3. To load the french keyboard layout with codepage 850 (where the + 3. To load one of french keyboard layouts with codepage 850 (where the codepage is defined in EGACPI.DAT): - keyb fr 850 EGACPI.DAT + keyb fr189 850 EGACPI.DAT 4. To load codepage 858 (without a keyboard layout): keyb none 858 This can be used to change the codepage for the FreeDOS keyb2 utility. @@ -880,7 +970,8 @@ For more information use the /? command line switch with the programs. ALT-ENTER Switch to full screen and back. ALT-PAUSE Pause emulation (hit ALT-PAUSE again to continue). CTRL-F1 Start the keymapper. -CTRL-F4 Change between mounted disk-images. Update directory cache for all drives! +CTRL-F4 Change between mounted floppy/CD images. Update directory cache + for all drives. CTRL-ALT-F5 Start/Stop creating a movie of the screen. (avi video capturing) CTRL-F5 Save a screenshot. (PNG format) CTRL-F6 Start/Stop recording sound output to a wave file. @@ -891,31 +982,85 @@ CTRL-F8 Increase frameskip. CTRL-F9 Kill DOSBox. CTRL-F10 Capture/Release the mouse. CTRL-F11 Slow down emulation (Decrease DOSBox Cycles). -CTRL-F12 Speed up emulation (Increase DOSBox Cycles). -ALT-F12 Unlock speed (turbo button/fast forward). +CTRL-F12 Speed up emulation (Increase DOSBox Cycles)*. +ALT-F12 Unlock speed (turbo button/fast forward)**. +F11, ALT-F11 (machine=cga) change tint in NTSC output modes*** +F11 (machine=hercules) cycle through amber, green, white colouring*** -(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.) +*NOTE: Once you increase your DOSBox cycles beyond your computer CPU resources, + it will produce the same effect as slowing down the emulation. + This maximum will vary from computer to computer. +**NOTE: You need free CPU resources for this (the more you have, the faster + it goes), so it won't work at all with cycles=max or a too high amount + of fixed cycles. You have to keep the keys pressed for it to work! + +***NOTE: These keys won't work if you saved a mapper file earlier with + a different machine type. So either reassign them or reset the mapper. These are the default keybindings. They can be changed in the keymapper -(see Section 6: Mapper). +(see Section 7: KeyMapper). -Saved/recorded files can be found in current_directory/capture -(this can be changed in the DOSBox configuration file). -The directory has to exist prior to starting DOSBox, otherwise nothing -gets saved/recorded ! +In MAC OS you can try using cmd(applekey) together with Ctrl if the key doesn't +work eg. cmd-ctrl-F1, but some keys may still need remapping (in Linux too). + +Saved/recorded files can be found in: + (Windows) "Start/WinLogo Menu"->"All Programs"->DOSBox-0.74->Extras + (Linux) ~/.dosbox/capture + (MAC OS X) "~/Library/Preferences/capture" +This can be changed in the DOSBox configuration file. -========== -6. Mapper: -========== +==================== +6. Joystick/Gamepad: +==================== -When you start the DOSBox mapper (either with CTRL-F1 or -startmapper as -a command line argument to the DOSBox executable) you are presented with -a virtual keyboard and a virtual joystick. +The standard joystick port in DOS supports a maximum of 4 axes and 4 buttons. +For more, different modifications of that configuration were used. + +To force DOSBox to use a different type of emulated joystick/gamepad, the entry +"joysticktype" in the [joystick] section of the DOSBox configuration file can +be used. + +none - disables controller support. +auto - (default) autodetects whether you have one or two controllers connected: + if you have one - '4axis' setting is used, + if you have two - '2axis' setting is used. +2axis - If you have two controllers connected, each will emulate a joystick + with 2 axes and 2 buttons. If you have only one controller connected, + it will emulate a joystick with only 2 axis and 2 buttons. +4axis - supports only first controller, emulates a joystick + with 4 axis and 4 buttons or a gamepad with 2axis and 6 buttons. +4axis_2 - supports only second controller. +fcs - supports only first controller, emulates ThrustMaster + Flight Control System, with 3-axes, 4 buttons and 1 hat. +ch - supports only first controller, emulates CH Flightstick, + with 4-axes, 6 buttons and 1 hat, but you cannot press more + than one button at the same time. + +You also have to configure controller properly inside the game. + +It is important to remember that if you saved the mapperfile without joystick + +connected, or with a different joystick setting, your new setting will +not work +properly, +or not work at all, until you reset DOSBox's mapperfile. + + +If controller is working properly outside DOSBox, but doesn't calibrate properly +inside DOSBox, try different 'timed' setting in DOSBox's configuration file. + + + +============= +7. KeyMapper: +============= + +You start the DOSBox mapper either with CTRL-F1 (see section 5. Special Keys) +or -startmapper (see Section 3. Command Line Parameters). +You are presented with a virtual keyboard and a virtual joystick. These virtual devices correspond to the keys and events DOSBox will report to the DOS applications. If you click on a button with your mouse, @@ -923,27 +1068,29 @@ you can see in the lower left corner with which event it is associated (EVENT) and to what events it is currently bound. Event: EVENT -BIND: BIND - Add Del -mod1 hold Next +BIND: BIND (the real key/button/axis you push with your finger/hand) + + Add Del +mod1 hold Next mod2 mod3 EVENT The key or joystick axis/button/hat DOSBox will report to DOS applications. + (the event that will happen during the game, (eg. shooting/jumping/walking) BIND The key on your real keyboard or the axis/button/hat on your real - joystick(s) (as reported by SDL) which is connected to the EVENT. -mod1,2,3 - Modfiers. These are keys you need to have to be pressed while pressing + joystick(s) (as reported by SDL), which is connected to the EVENT. +mod1,2,3 + Modifiers. These are keys you need to have to be pressed while pressing BIND. mod1 = CTRL and mod2 = ALT. These are generally only used when you want to change the special keys of DOSBox. -Add +Add Add a new BIND to this EVENT. Basically add a key from your keyboard or an - event from the joystick (button press, axis/hat movement) which will + event from the joystick (button press, axis/hat movement) which will produce the EVENT in DOSBox. -Del +Del Delete the BIND to this EVENT. If an EVENT has no BINDS, then it is not possible to trigger this event in DOSBox (that is there's no way to type the key or use the respective action of the joystick). @@ -953,18 +1100,18 @@ Next Example: Q1. You want to have the X on your keyboard to type a Z in DOSBox. - A. Click on the Z on the keyboard mapper. Click "Add". - Now press the X key on your keyboard. + A. Click on the Z on the keyboard mapper. Click "Add". + Now press the X key on your keyboard. -Q2. If you click "Next" a couple of times, you will notice that the Z on your +Q2. If you click "Next" a couple of times, you will notice that the Z on your keyboard also produces an Z in DOSBox. - A. Therefore select the Z again, and click "Next" until you have the Z on + A. Therefore select the Z again, and click "Next" until you have the Z on your keyboard. Now click "Del". Q3. If you try it out in DOSBox, you will notice that pressing X makes ZX appear. A. The X on your keyboard is still mapped to the X as well! Click on - the X in the keyboard mapper and search with "Next" until you find the + the X in the keyboard mapper and search with "Next" until you find the mapped key X. Click "Del". @@ -972,8 +1119,7 @@ Examples about remapping the joystick: You have a joystick attached, it is working fine under DOSBox and you want to play some keyboard-only game with the joystick (it is assumed that the game is controlled by the arrows on the keyboard): - 1. Start the mapper, then click on one of the arrows in the middle - of the left part of the screen (right above the Mod1/Mod2 buttons). + 1. Start the mapper, then click on one of the left keyboard arrow. EVENT should be key_left. Now click on Add and move your joystick in the respective direction, this should add an event to the BIND. 2. Repeat the above for the missing three directions, additionally @@ -983,51 +1129,55 @@ Examples about remapping the joystick: You want to swap the y-axis of the joystick because some flightsim uses the up/down joystick movement in a way you don't like, and it is not configurable in the game itself: - 1. Start the mapper and click on Y- in the upper joystick field (this - is for the first joystick if you have two joysticks attached) or the - lower joystick field (second joystick or, if you have only one - joystick attached, the second axes cross). - EVENT should be jaxis_0_1- (or jaxis_1_1-). + 1. Start the mapper and click on Y- in the first joystick field. + EVENT should be jaxis_0_1-. 2. Click on Del to remove the current binding, then click Add and move your joystick downwards. A new bind should be created. 3. Repeat this for Y+, save the layout and finally test it with some game. + If you want to remap anything to your d-pad/hat you will have to change + 'joysticktype=auto' to 'joysticktype=fcs' in configuration file. Maybe this + will be improved in the next dosbox version. If you change the default mapping, you can save your changes by clicking on -"Save". DOSBox will save the mapping to a location specified in the configuration -file (the mapperfile= entry). At startup, DOSBox will load your mapperfile, -if it is present in the DOSBox configuration file. +"Save". DOSBox will save the mapping to a location specified in +the configuration file (the mapperfile= entry). At startup, DOSBox will load +your mapperfile, if it is present in the DOSBox configuration file. =================== -7. Keyboard Layout: +8. Keyboard Layout: =================== To switch to a different keyboard layout, either the entry "keyboardlayout" in the [dos] section of the DOSBox configuration file can be used, or the -internal DOSBox program keyb.com. Both accept DOS conforming language codes -(see below), but only by using keyb.com a custom codepage can be specified. +internal DOSBox program keyb.com (Section 4: Internal Programs) +Both accept DOS conforming language codes (see below), +but only by using keyb.com a custom codepage can be specified. -The default keyboardlayout=auto currently works under windows only, the -layout is chosen according to the OS layout. +The default keyboardlayout=auto currently works under windows only. The language +is chosen according to the OS language, but the keyboard layout is not detected. Layout switching DOSBox supports a number of keyboard layouts and codepages by default, in this case just the layout identifier needs to be specified (like - keyboardlayout=sv in the DOSBox configuration file, or using "keyb sv" - at the DOSBox command prompt). - - Some keyboard layouts (for example layout GK codepage 869 and layout RU - codepage 808) have support for dual layouts that can be activated by - pressing LEFT-ALT+RIGHT-SHIFT and deactivated by LEFT-ALT+LEFT-SHIFT. + keyboardlayout=PL214 in the DOSBox configuration file, or using "keyb PL214" + at the DOSBox command prompt). The list of all layouts built into DOSBox is + here: http://vogons.zetafleet.com/viewtopic.php?t=21824 + + Some keyboard layouts (for example layout GK319 codepage 869 and layout RU441 + codepage 808) have support for dual layouts that can be accessed by pressing + LeftALT+RrightSHIFT for one layout and LeftALT+LeftSHIFT for the other. + Some keyboard layouts (for example layout LT456 codepage 771) have support + for three layouts, third can be accessed by pressing LeftALT+LeftCTRL Supported external files The FreeDOS .kl files are supported (FreeDOS keyb2 keyboard layoutfiles) as well as the FreeDOS keyboard.sys/keybrd2.sys/keybrd3.sys libraries which consist of all available .kl files. - See http://projects.freedos.net/keyb/ for precompiled keyboard layouts if + See http://www.freedos.org/ for precompiled keyboard layouts if the DOSBox-integrated layouts don't work for some reason, or if updated or new layouts become available. @@ -1035,8 +1185,10 @@ Supported external files UPX-compressed codepage files) can be used. Some codepages are compiled into DOSBox, so it is mostly not needed to care about external codepage files. If you need a different (or custom) codepage file, copy it into - the directory of the DOSBox configuration file so it is accessible for - DOSBox. + the directory of the DOSBox so it is accessible for DOSBox. + If you place all ten ega.cpx files (from FreeDOS) in DOSBox folder, + an appropriate codepagefile for the requested layout/codepage is + chosen automatically. Additional layouts can be added by copying the corresponding .kl file into the directory of the DOSBox configuration file and using the first part of @@ -1045,7 +1197,6 @@ Supported external files "keyboardlayout=uz" in the DOSBox configuration file. The integration of keyboard layout packages (like keybrd2.sys) works similar. - Note that the keyboard layout allows foreign characters to be entered, but there is NO support for them in filenames. Try to avoid them both inside DOSBox as well as in files on your host operating system that are accessible @@ -1054,9 +1205,9 @@ by DOSBox. ============================== -8. Serial Multiplayer feature: +9. Serial Multiplayer feature: ============================== - + DOSBox can emulate a serial nullmodem cable over network and internet. It can be configured through the [serialports] section in the DOSBox configuration file. @@ -1100,52 +1251,68 @@ Example: Be a server listening on TCP port 5000. -======================================= -9. How to run resource-demanding games: -======================================= +===================================== +10. How to speed up/slow down DOSBox: +===================================== DOSBox emulates the CPU, the sound and graphic cards, and other peripherals of a PC, all at the same time. The speed of an emulated DOS application depends on how many instructions can be emulated, which is adjustable (number of cycles). -CPU Cycles +CPU Cycles (speed up/slow down) By default (cycles=auto) DOSBox tries to detect whether a game needs to - be run with as many instructions emulated per time interval as possible. - You can force this behaviour by setting cycles=max in the DOSBox - configuration file. The DOSBox window will display a line "Cpu Cyles: max" - at the top then. In this mode you can reduce the amount of cycles on a - percentage-basis (hit CTRL-F11) or raise it again (CTRL-F12). - - Sometimes manually setting the number of cycles achieves better results, - in the DOSBox configuration file specify for example cycles=30000. When - running some DOS application you can raise the cycles with CTRL-F12 even - more, but you will be limited by the power of your actual CPU. You can see - how much free time your real CPU has by looking at the Task Manager in - Windows 2000/XP and the System Monitor in Windows 95/98/ME. Once 100% of - your real CPU time is used there is no further way to speed up DOSBox - unless you reduce the load generated by the non-CPU parts of DOSBox. + be run with as many instructions emulated per time interval as possible + (cycles=max, sometimes this results in game working too fast or unstable), + or whether to use fixed amount of cycles (cycles=3000, sometimes this results + in game working too slow or too fast). But you can always manually force + a different setting in the DOSBox's configuration file. -CPU Cores + You can force the slow or fast behavior by setting a fixed amount of cycles + in the DOSBox's configuration file. If you for example set cycles=10000, then + DOSBox window will display a line "Cpu Speed: fixed 10000 cycles" at the top. + In this mode you can reduce the amount of cycles even more by hitting CTRL-F11 + (you can go as low as you want) or raise it by hitting CTRL-F12 as much as you + want, but you will be limited by the power of one core of your computer's CPU. + You can see how much free time your real CPU's cores have by looking at + the Task Manager in Windows 2000/XP/Vista/7 and the System Monitor + in Windows 95/98/ME. Once 100% of the power of your computer's real CPU's one + core is used, there is no further way to speed up DOSBox (it will actually + start to slow down), unless you reduce the load generated by the non-CPU parts + of DOSBox. DOSBox can use only one core of your CPU, so If you have + for example a CPU with 4 cores, DOSBox will not be able to use the power + of three other cores. + + You can also force the fast behavior by setting cycles=max in the DOSBox + configuration file. The DOSBox window will display a line + "Cpu Speed: max 100% cycles" at the top then. This time you won't have to care + how much free time your real CPU's cores have, because DOSBox will always use + 100% of your real CPU's one core. In this mode you can reduce the amount + of your real CPU's core usage by CTRL-F11 or raise it with CTRL-F12. + +CPU Core (speed up) On x86 architectures you can try to force the usage of a dynamically recompiling core (set core=dynamic in the DOSBox configuration file). This usually gives better results if the auto detection (core=auto) fails. - It is best accompanied by cycles=max. Note that there might be games - that work worse with the dynamic core, or do not work at all! + It is best accompanied by cycles=max. But you may also try using it with + high amounts of cycles (for example 20000 or more). Note that there might be + games that work worse/crash with the dynamic core (so save your game often), + or do not work at all! -Graphics emulation - VGA emulation is a very demanding part of DOSBox in terms of actual CPU - usage. Increase the number of frames skipped (in increments of one) by - pressing CTRL-F8. Your CPU usage should decrease when using a fixed - cycle setting. - Go back one step and repeat this until the game runs fast enough for you. +Graphics emulation (speed up) + VGA emulation is a demanding part of DOSBox in terms of actual CPU usage. + Increase the number of frames skipped (in increments of one) by pressing + CTRL-F8. Your CPU usage should decrease when using a fixed cycle setting, + and you will be able to increase cycles with CTRL-F12. + You can 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. -Sound emulation +Sound emulation (speed up) You can also try to disable the sound through the setup utility of the game - to reduce load on your CPU further. Setting nosound=true does NOT disable - the emulation of sound devices, just the output of sound will be disabled. + to reduce load on your CPU further. Setting nosound=true in DOSBox's + configuration does NOT disable the emulation of sound devices, just + the output of sound will be disabled. Also try to close every program but DOSBox to reserve as much resources as possible for DOSBox. @@ -1154,24 +1321,28 @@ as possible for DOSBox. Advanced cycles configuration: The cycles=auto and cycles=max settings can be parameterized to have different startup defaults. The syntax is - cycles=auto ["realmode default"] ["protected mode default"%] + cycles=auto ["realmode default"] ["protected mode default"%] [limit "cycle limit"] cycles=max ["protected mode default"%] [limit "cycle limit"] Example: - cycles=auto 1000 80% limit 20000 - will use cycles=1000 for real mode games, 80% CPU throttling for + cycles=auto 5000 80% limit 20000 + will use cycles=5000 for real mode games, 80% CPU throttling for protected mode games along with a hard cycle limit of 20000 ==================== -10. Troubleshooting: +11. Troubleshooting: ==================== +General tip: + Check messages in DOSBox Status Window. See section 12. "DOSBox Status Window" + DOSBox crashes right after starting it: - use different values for the output= entry in your DOSBox configuration file - try to update your graphics card driver and DirectX + - (Linux) set the environment variable SDL_AUDIODRIVER to alsa or oss. Running a certain game closes DOSBox, crashes with some message or hangs: - see if it works with a default DOSBox installation @@ -1207,46 +1378,71 @@ The game exits to the DOSBox prompt with some error message: -==================== -11. The Config File: -==================== +========================= +12. DOSBox Status Window: +========================= -A config file can be generated by CONFIG.COM, which can be found on the -internal DOSBox Z: drive when you start up DOSBox. Look in the internal -programs section of the readme for usage of CONFIG.COM. -You can edit the generated configfile to customize DOSBox. +DOSBox's Staus window contains many useful information about your currant +configuration, your actions in DOSBox, errors that happened and more. +Whenever you have any problem with DOSBox check these messages. -The file is divided into several sections (the names have [] around it). -Some sections have options you can set. -# and % indicate comment-lines. -The DOSBox configuration file contains the current settings. You can -alter them and start DOSBox with the -conf switch to load the file and -use these settings. +To start DOSBox Status Window: + (Windows) Status Window is being started together with main DOSBox window. + (Linux) You may have to start DOSBox from a console to see Status Window. + (MAC OS X) Right click on DOSBox.app, choose "Show Package Contents"-> + ->enter "Contents"->enter "MacOS"->run "DOSBox" -DOSBox will parse configuration files that are specified with -conf. If -none were specified it will try to load "dosbox.conf" from the local -directory. If there is none, DOSBox will load the user configuration -file. This file will be created if it doesn't exist. The file can be -found in ~/.dosbox (Linux) or "~/Library/Preferences" (MAC OS X). -Windows users should use the shortcuts in the startmenu to find it. +===================================== +13. The configuration (options) file: +===================================== + +The configuration file is automatically created the first time you run DOSBox. +The file can be found in: + (Windows) "Start/WinLogo Menu"->"All Programs"->DOSBox-0.74->Options + (Linux) ~/.dosbox/dosbox-0.74.conf + (MAC OS X) "~/Library/Preferences/DOSBox 0.74 Preferences" +The file is divided into several sections. Each section starts with a +[section name] line. The settings are the property=value lines where value can +be altered to customize DOSBox. +# and % indicate comment-lines. + + +An extra configuration file can be generated by CONFIG.COM, which can be found +on the internal DOSBox Z: drive when you start up DOSBox. Look in the Section 4: +"Internal programs" for usage of CONFIG.COM. You can start DOSBox with +the -conf switch to load the generated file and use its settings. + +DOSBox will load configuration files that are specified with -conf. If none were +specified, it will try to load "dosbox.conf" from the local directory. +If there is none, DOSBox will load the user configuration file. +This file will be created if it doesn't exist. + +Important!: In Windows Vista/7 the configuration file won't work correctly +if it is located in "Windows" or "Program Files" folder or their subfolders, +or directly on c:\, so the best place for storing extra configuration files is +for example: C:\oldgames + ====================== -12. The Language File: +14. The Language File: ====================== -A language file can be generated by CONFIG.COM (CONFIG -writelang langfile). -Read it, and you will hopefully understand how to change it. +A language file can be generated by CONFIG.COM, which can be found on the +internal DOSBox Z: drive when you start up DOSBox. Look in the Section 4: +"Internal programs" for usage of CONFIG.COM. +Read the language file, and you will hopefully understand how to change it. Start DOSBox with the -lang switch to use your new language file. -Alternatively, you can setup the filename in the config file in the [dosbox] -section. There's a language= entry that can be changed with the filename. +Alternatively, you can setup the filename in the configuration file +in the [dosbox] section. There's a language= entry that can be changed with +the filelocation. ======================================== -13. Building your own version of DOSBox: +15. Building your own version of DOSBox: ======================================== Download the source. @@ -1255,16 +1451,19 @@ Check the INSTALL in the source distribution. =================== -14. Special thanks: +16. Special thanks: =================== See the THANKS file. + ============ -15. Contact: +17. Contact: ============ See the site: http://www.dosbox.com for an email address (The Crew-page). + + From 175b1c2b927bdee378ccf78108030c8bdcc9cb10 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 10 May 2010 18:45:49 +0000 Subject: [PATCH 3516/4131] Nicer line ends on Windows. Might break old mapper files with 0.74, which might actually be good. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3605 --- src/gui/sdl_mapper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index b3d77bbd..c905c052 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -2117,7 +2117,7 @@ void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char const } static void MAPPER_SaveBinds(void) { - FILE * savefile=fopen(mapper.filename.c_str(),"wb+"); + FILE * savefile=fopen(mapper.filename.c_str(),"wt+"); if (!savefile) { LOG_MSG("Can't open %s for saving the mappings",mapper.filename.c_str()); return; @@ -2139,7 +2139,7 @@ static void MAPPER_SaveBinds(void) { } static bool MAPPER_LoadBinds(void) { - FILE * loadfile=fopen(mapper.filename.c_str(),"rb"); + FILE * loadfile=fopen(mapper.filename.c_str(),"rt"); if (!loadfile) return false; char linein[512]; while (fgets(linein,512,loadfile)) { From 328b21c2e0be54f3dc756a1751141a8c06bb6d5f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 12 May 2010 08:11:37 +0000 Subject: [PATCH 3517/4131] Limit message to once per session. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3606 --- src/cpu/cpu.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index b49d0656..363b091b 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1542,7 +1542,7 @@ Bitu CPU_SIDT_limit(void) { return cpu.idt.GetLimit(); } - +static bool printed_cycles_auto_info = false; void CPU_SET_CRX(Bitu cr,Bitu value) { switch (cr) { case 0: @@ -1563,7 +1563,10 @@ void CPU_SET_CRX(Bitu cr,Bitu value) { CPU_Cycles=0; CPU_OldCycleMax=CPU_CycleMax; GFX_SetTitle(CPU_CyclePercUsed,-1,false); - LOG_MSG("DOSBox switched to max cycles, because of the setting: cycles=auto. If the game runs too fast try a fixed cycles amount in DOSBox's options."); + if(!printed_cycles_auto_info) { + printed_cycles_auto_info = true; + LOG_MSG("DOSBox switched to max cycles, because of the setting: cycles=auto. If the game runs too fast try a fixed cycles amount in DOSBox's options."); + } } else { GFX_SetTitle(-1,-1,false); } From 62be0b6ac1e358bf75e2e9009cd4facc8d613514 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 12 May 2010 08:13:46 +0000 Subject: [PATCH 3518/4131] Installer improvements Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3607 --- scripts/captures.bat | 1 + scripts/dosbox-installer.nsi | 117 +++++++++++++++++++++-------------- scripts/editconf.bat | 1 + scripts/resetconf.bat | 1 + scripts/resetmapper.bat | 1 + 5 files changed, 76 insertions(+), 45 deletions(-) create mode 100644 scripts/captures.bat create mode 100644 scripts/editconf.bat create mode 100644 scripts/resetconf.bat create mode 100644 scripts/resetmapper.bat diff --git a/scripts/captures.bat b/scripts/captures.bat new file mode 100644 index 00000000..8eebbc8c --- /dev/null +++ b/scripts/captures.bat @@ -0,0 +1 @@ +DOSBox.exe -opencaptures explorer.exe \ No newline at end of file diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index 629bca5c..31aee2bf 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -1,8 +1,8 @@ !define VER_MAYOR 0 -!define VER_MINOR 73 +!define VER_MINOR 74 !define APP_NAME "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer" !define COMP_NAME "DOSBox Team" -!define COPYRIGHT "Copyright © 2002-2009 DOSBox Team" +!define COPYRIGHT "Copyright © 2002-2010 DOSBox Team" !define DESCRIPTION "DOSBox Installer" VIProductVersion "${VER_MAYOR}.${VER_MINOR}.0.0" @@ -47,44 +47,57 @@ SetShellVarContext all ; Put file there - CreateDirectory "$INSTDIR\zmbv" + CreateDirectory "$INSTDIR\Video Codec" + CreateDirectory "$INSTDIR\Documentation" + SetOutPath "$INSTDIR\Documentation" 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 + SetOutPath "$INSTDIR" + + File "/oname=DOSBox ${VER_MAYOR}.${VER_MINOR} Manual.txt" README + File "/oname=DOSBox.exe" DOSBox.exe 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 + File "/oname=Video Codec\zmbv.dll" zmbv.dll + File "/oname=Video Codec\zmbv.inf" zmbv.inf + File "/oname=Video Codec\Video Instructions.txt" README.video + File "/oname=DOSBox ${VER_MAYOR}.${VER_MINOR} Options.bat" editconf.bat + File "/oname=Reset KeyMapper.bat" resetmapper.bat + File "/oname=Reset Options.bat" resetconf.bat + File "/oname=Screenshots & Recordings.bat" captures.bat CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}" - CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video" - CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration" - 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" "" "$INSTDIR\DOSBox.exe" 0 - CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox (noconsole).lnk" "$INSTDIR\DOSBox.exe" "-noconsole" "$INSTDIR\DOSBox.exe" 0 - CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\README.lnk" "$INSTDIR\README.txt" - CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration\Edit Configuration.lnk" "$INSTDIR\DOSBox.exe" "-editconf notepad.exe -editconf $\"%SystemRoot%\system32\notepad.exe$\" -editconf $\"%WINDIR%\notepad.exe$\"" - CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration\Reset Configuration.lnk" "$INSTDIR\DOSBox.exe" "-eraseconf" - CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Capture folder.lnk" "$INSTDIR\DOSBox.exe" "-opencaptures explorer.exe" - CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Video instructions.lnk" "$INSTDIR\zmbv\README.txt" + CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras" + CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Video" + CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Options" + CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk" "$INSTDIR\DOSBox.exe" "-userconf" "$INSTDIR\DOSBox.exe" 0 + CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox ${VER_MAYOR}.${VER_MINOR} Manual.lnk" "$INSTDIR\Documentation\README.txt" + CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\DOSBox ${VER_MAYOR}.${VER_MINOR} (noconsole).lnk" "$INSTDIR\DOSBox.exe" "-noconsole -userconf" "$INSTDIR\DOSBox.exe" 0 + CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 + CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Screenshots & Recordings.lnk" "$INSTDIR\DOSBox.exe" "-opencaptures explorer.exe" + + CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Options\DOSBox ${VER_MAYOR}.${VER_MINOR} Options.lnk" "$INSTDIR\DOSBox.exe" "-editconf notepad.exe -editconf $\"%SystemRoot%\system32\notepad.exe$\" -editconf $\"%WINDIR%\notepad.exe$\"" + CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Options\Reset Options.lnk" "$INSTDIR\DOSBox.exe" "-eraseconf" + CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Options\Reset KeyMapper.lnk" "$INSTDIR\DOSBox.exe" "-erasemapper" + + CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Video\Video instructions.lnk" "$INSTDIR\Video Codec\Video Instructions.txt" ;change outpath so the working directory gets set to zmbv -SetOutPath "$INSTDIR\zmbv" +SetOutPath "$INSTDIR\Video Codec" ; 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" + CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Video\Install movie codec.lnk" "rundll32" "setupapi,InstallHinfSection DefaultInstall 128 $INSTDIR\Video Codec\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" + CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Video\Install movie codec.lnk" "rundll" "setupx.dll,InstallHinfSection DefaultInstall 128 $INSTDIR\Video Codec\zmbv.inf" end: SetOutPath $INSTDIR WriteUninstaller "uninstall.exe" @@ -102,9 +115,9 @@ SectionEnd ; end the section Section "Desktop Shortcut" SecDesktop SetShellVarContext all -CreateShortCut "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk" "$INSTDIR\DOSBox.exe" "" "$INSTDIR\DOSBox.exe" 0 +CreateShortCut "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk" "$INSTDIR\DOSBox.exe" "-userconf" "$INSTDIR\DOSBox.exe" 0 - SectionEnd ; end the section +SectionEnd ; end the section UninstallText "This will uninstall DOSBox v${VER_MAYOR}.${VER_MINOR}. Hit next to continue." @@ -117,40 +130,54 @@ SetShellVarContext all 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\Documentation\README.txt + Delete $INSTDIR\Documentation\COPYING.txt + Delete $INSTDIR\Documentation\THANKS.txt + Delete $INSTDIR\Documentation\NEWS.txt + Delete $INSTDIR\Documentation\AUTHORS.txt + Delete $INSTDIR\Documentation\INSTALL.txt + Delete "$INSTDIR\DOSBox ${VER_MAYOR}.${VER_MINOR} Manual.txt" + Delete "$INSTDIR\DOSBox.exe" Delete $INSTDIR\SDL.dll Delete $INSTDIR\SDL_net.dll - Delete $INSTDIR\zmbv\zmbv.dll - Delete $INSTDIR\zmbv\zmbv.inf - Delete $INSTDIR\zmbv\README.txt + Delete "$INSTDIR\Video Codec\zmbv.dll" + Delete "$INSTDIR\Video Codec\zmbv.inf" + Delete "$INSTDIR\Video Codec\Video Instructions.txt" ;Files left by sdl taking over the console Delete $INSTDIR\stdout.txt Delete $INSTDIR\stderr.txt + Delete "$INSTDIR\DOSBox ${VER_MAYOR}.${VER_MINOR} Options.bat" + Delete "$INSTDIR\Reset KeyMapper.bat" + Delete "$INSTDIR\Reset Options.bat" + Delete "$INSTDIR\Screenshots & Recordings.bat" ; 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}\Configuration\Edit Configuration.lnk" - Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration\Reset Configuration.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" + + Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk" + Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox ${VER_MAYOR}.${VER_MINOR} Manual.lnk" + Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\DOSBox ${VER_MAYOR}.${VER_MINOR} (noconsole).lnk" + Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Uninstall.lnk" + Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Screenshots & Recordings.lnk" + + Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Options\DOSBox ${VER_MAYOR}.${VER_MINOR} Options.lnk" + Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Options\Reset Options.lnk" + Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Options\Reset KeyMapper.lnk" + + Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Video\Video instructions.lnk" + Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Video\Install movie codec.lnk" + + + +; remove shortcuts, if any. ; remove directories used. - RMDir "$INSTDIR\zmbv" + RMDir "$INSTDIR\Documentation" + RMDir "$INSTDIR\Video Codec" RMDir "$INSTDIR" - RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration" - RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video" + RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Options" + RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Video" + RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras" RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}" SectionEnd diff --git a/scripts/editconf.bat b/scripts/editconf.bat new file mode 100644 index 00000000..a48d102f --- /dev/null +++ b/scripts/editconf.bat @@ -0,0 +1 @@ +DOSBox.exe -editconf notepad.exe -editconf %SystemRoot%\system32\notepad.exe -editconf %WINDIR%\notepad.exe \ No newline at end of file diff --git a/scripts/resetconf.bat b/scripts/resetconf.bat new file mode 100644 index 00000000..0ad3b95b --- /dev/null +++ b/scripts/resetconf.bat @@ -0,0 +1 @@ +DOSBox.exe -resetconf \ No newline at end of file diff --git a/scripts/resetmapper.bat b/scripts/resetmapper.bat new file mode 100644 index 00000000..86299bbc --- /dev/null +++ b/scripts/resetmapper.bat @@ -0,0 +1 @@ +DOSBox.exe -resetmapper \ No newline at end of file From 3fe6afda3d500e451e9fa2a182ecd5fd7f42f425 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 12 May 2010 09:10:46 +0000 Subject: [PATCH 3519/4131] version number updates. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3608 --- VERSION | 2 +- configure.in | 2 +- src/platform/visualc/config.h | 2 +- src/winres.rc | 12 ++++++------ 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/VERSION b/VERSION index 6ab5ccfd..3ea25f59 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.73 +0.74 diff --git a/configure.in b/configure.in index d5a21e30..016ea95f 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Init. -AC_INIT(dosbox,0.73) +AC_INIT(dosbox,0.74) AC_PREREQ(2.50) AC_CONFIG_SRCDIR(README) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index d49f10a7..7d9eecbc 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -1,4 +1,4 @@ -#define VERSION "0.73" +#define VERSION "0.74" /* Define to 1 to enable internal debugger, requires libcurses */ #define C_DEBUG 0 diff --git a/src/winres.rc b/src/winres.rc index 4a071afa..f7e63b4c 100644 --- a/src/winres.rc +++ b/src/winres.rc @@ -7,8 +7,8 @@ dosbox_ico ICON "dosbox.ico" // version resource VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,73,0,0 - PRODUCTVERSION 0,73,0,0 + FILEVERSION 0,74,0,0 + PRODUCTVERSION 0,74,0,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -19,15 +19,15 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "Comments", "© 2002-2009 DOSBox Team, published under GNU GPL" + VALUE "Comments", "© 2002-2010 DOSBox Team, published under GNU GPL" VALUE "CompanyName", "DOSBox Team" VALUE "FileDescription", "DOSBox DOS Emulator" - VALUE "FileVersion", "0, 73, 0, 0" + VALUE "FileVersion", "0, 74, 0, 0" VALUE "InternalName", "DOSBox" - VALUE "LegalCopyright", "Copyright © 2002-2009 DOSBox Team" + VALUE "LegalCopyright", "Copyright © 2002-2010 DOSBox Team" VALUE "OriginalFilename", "dosbox.exe" VALUE "ProductName", "DOSBox DOS Emulator" - VALUE "ProductVersion", "0, 73, 0, 0" + VALUE "ProductVersion", "0, 74, 0, 0" END END BLOCK "VarFileInfo" From 1188f7882d8a30b2f5e4f947d56ba4ad873dbea7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 14 May 2010 07:33:45 +0000 Subject: [PATCH 3520/4131] Tiny fixes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3610 --- README | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/README b/README index e66a72af..a58bac14 100644 --- a/README +++ b/README @@ -143,7 +143,7 @@ CD-ROM: The game/application can't find its CD-ROM. Under Windows you can specify -ioctl, -aspi or -noioctl. Look at the description of the mount command in Section 4: "Internal programs" for their meaning and the - additional audio-CD related options -ioctl_dx, ioctl_mci, ioctl_dio. + additional audio-CD related options -ioctl_dx, -ioctl_mci, -ioctl_dio. Try creating a CD-ROM image (preferably CUE/BIN pair) and use the DOSBox's internal IMGMOUNT tool to mount the image (the CUE sheet). @@ -1040,14 +1040,9 @@ ch - supports only first controller, emulates CH Flightstick, than one button at the same time. You also have to configure controller properly inside the game. - It is important to remember that if you saved the mapperfile without joystick - -connected, or with a different joystick setting, your new setting will -not work -properly, -or not work at all, until you reset DOSBox's mapperfile. - +connected, or with a different joystick setting, your new setting will not work +properly, or not work at all, until you reset DOSBox's mapperfile. If controller is working properly outside DOSBox, but doesn't calibrate properly inside DOSBox, try different 'timed' setting in DOSBox's configuration file. From 23c7394b75d1cc2890e97e6ef078e160d43c5c44 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 16 May 2010 19:02:30 +0000 Subject: [PATCH 3521/4131] Disable blanking if its start value is beyond the total display height. Fixes Ms. Pac-PC and Pac-PC II. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3611 --- src/hardware/vga_draw.cpp | 52 ++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 33ee8cdb..459e768c 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1148,33 +1148,35 @@ void VGA_SetupDrawing(Bitu /*val*/) { // Vertical blanking tricks vblank_skip = 0; if (IS_VGA_ARCH) { // others need more investigation - if (vbend > vtotal) { - // blanking wraps to the start of the screen - vblank_skip = vbend&0x7f; - - // on blanking wrap to 0, the first line is not blanked - // this is used by the S3 BIOS and other S3 drivers in some SVGA modes - if((vbend&0x7f)==1) vblank_skip = 0; - - // it might also cut some lines off the bottom - if(vbstart < vdend) { - vdend = vbstart; - } - LOG(LOG_VGA,LOG_WARN)("Blanking wrap to line %d", vblank_skip); - } else if (vbstart==1) { - // blanking is used to cut lines at the start of the screen - vblank_skip = vbend; - LOG(LOG_VGA,LOG_WARN)("Upper %d lines of the screen blanked", vblank_skip); - } else if (vbstart < vdend) { - if(vbend < vdend) { - // the game wants a black bar somewhere on the screen - LOG(LOG_VGA,LOG_WARN)("Unsupported blanking: line %d-%d",vbstart,vbend); - } else { - // blanking is used to cut off some lines from the bottom - vdend = vbstart; + if (vbstart < vtotal) { // There will be no blanking at all otherwise + if (vbend > vtotal) { + // blanking wraps to the start of the screen + vblank_skip = vbend&0x7f; + + // on blanking wrap to 0, the first line is not blanked + // this is used by the S3 BIOS and other S3 drivers in some SVGA modes + if((vbend&0x7f)==1) vblank_skip = 0; + + // it might also cut some lines off the bottom + if(vbstart < vdend) { + vdend = vbstart; + } + LOG(LOG_VGA,LOG_WARN)("Blanking wrap to line %d", vblank_skip); + } else if (vbstart==1) { + // blanking is used to cut lines at the start of the screen + vblank_skip = vbend; + LOG(LOG_VGA,LOG_WARN)("Upper %d lines of the screen blanked", vblank_skip); + } else if (vbstart < vdend) { + if(vbend < vdend) { + // the game wants a black bar somewhere on the screen + LOG(LOG_VGA,LOG_WARN)("Unsupported blanking: line %d-%d",vbstart,vbend); + } else { + // blanking is used to cut off some lines from the bottom + vdend = vbstart; + } } + vdend -= vblank_skip; } - vdend -= vblank_skip; } // Display end vga.draw.delay.vdend = vdend * vga.draw.delay.htotal; From 6976225474ff58784bbe991bfce29188aae482ab Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 25 May 2010 07:58:13 +0000 Subject: [PATCH 3522/4131] Spelling fix. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3612 --- docs/dosbox.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dosbox.1 b/docs/dosbox.1 index 9321fed5..cf96475f 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -111,7 +111,7 @@ You can specify this command more than once. In this case it will .RI " move to second " program " if the first one fails to start." .TP .BI \-opencaptures " program" -.RI "calls " program " with as first paramater the location of the captures folder." +.RI "calls " program " with as first parameter the location of the captures folder." .TP .B \-printconf prints the location of the default configuration file. From b441536ff47a257fc217602a8d224b41657183ac Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 5 Jun 2010 10:35:20 +0000 Subject: [PATCH 3523/4131] Add history to debugger and cleanup. Patch 2991413 from etillite Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3613 --- src/debug/debug.cpp | 215 +++++++++++++++++++++++++++------------- src/debug/debug_gui.cpp | 8 +- 2 files changed, 151 insertions(+), 72 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 356ccea8..5b165de5 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -76,6 +76,7 @@ static void DrawVariables(void); char* AnalyzeInstruction(char* inst, bool saveSelector); Bit32u GetHexValue(char* str, char*& hex); +#if 0 class DebugPageHandler : public PageHandler { public: Bitu readb(PhysPt /*addr*/) { @@ -90,10 +91,8 @@ public: } void writed(PhysPt /*addr*/,Bitu /*val*/) { } - - - }; +#endif class DEBUG; @@ -123,7 +122,6 @@ static char curSelectorName[3] = { 0,0,0 }; static Segment oldsegs[6]; static Bitu oldflags,oldcpucpl; DBGBlock dbg; -static Bitu input_count; Bitu cycle_count; static bool debugging; @@ -136,23 +134,34 @@ static void SetColor(Bitu test) { } } +#define MAXCMDLEN 254 struct SCodeViewData { - int cursorPos; + int cursorPos; Bit16u firstInstSize; - Bit16u useCS; - Bit32u useEIPlast, useEIPmid; - Bit32u useEIP; + Bit16u useCS; + Bit32u useEIPlast, useEIPmid; + Bit32u useEIP; Bit16u cursorSeg; - Bit32u cursorOfs; - bool inputMode; - char inputStr[255]; - char prevInputStr[255]; - + Bit32u cursorOfs; + bool ovrMode; + char inputStr[MAXCMDLEN+1]; + char suspInputStr[MAXCMDLEN+1]; + int inputPos; } codeViewData; -static Bit16u dataSeg; -static Bit32u dataOfs; -static bool showExtend = true; +static Bit16u dataSeg; +static Bit32u dataOfs; +static bool showExtend = true; + +static void ClearInputLine(void) { + codeViewData.inputStr[0] = 0; + codeViewData.inputPos = 0; +} + +// History stuff +#define MAX_HIST_BUFFER 50 +static list histBuff; +static list::iterator histBuffPos = histBuff.end(); /***********/ /* Helpers */ @@ -775,6 +784,8 @@ static void DrawCode(void) { wattrset(dbg.win_code,COLOR_PAIR(PAIR_GREEN_BLACK)); if (codeViewData.cursorPos==-1) { codeViewData.cursorPos = i; // Set Cursor + } + if (i == codeViewData.cursorPos) { codeViewData.cursorSeg = SegValue(cs); codeViewData.cursorOfs = disEIP; } @@ -837,12 +848,18 @@ static void DrawCode(void) { wattrset(dbg.win_code,0); if (!debugging) { - mvwprintw(dbg.win_code,10,0,"(Running)",codeViewData.inputStr); - } else { - if(!*codeViewData.inputStr) { //Clear old commands - mvwprintw(dbg.win_code,10,0," "); - } - mvwprintw(dbg.win_code,10,0,"-> %s_ ",codeViewData.inputStr); + mvwprintw(dbg.win_code,10,0,"%s","(Running)"); + wclrtoeol(dbg.win_code); + } else { + //TODO long lines + char* dispPtr = codeViewData.inputStr; + char* curPtr = &codeViewData.inputStr[codeViewData.inputPos]; + mvwprintw(dbg.win_code,10,0,"%c-> %s%c", + (codeViewData.ovrMode?'O':'I'),dispPtr,(*curPtr?' ':'_')); + wclrtoeol(dbg.win_code); // not correct in pdcurses if full line + if (*curPtr) { + mvwchgat(dbg.win_code,10,(curPtr-dispPtr+4),1,0,(PAIR_BLACK_GREY),NULL); + } } wrefresh(dbg.win_code); @@ -1121,6 +1138,7 @@ bool ParseCommand(char* str) { DEBUG_ShowMsg("DEBUG: Set code overview to %04X:%04X\n",codeSeg,codeOfs); codeViewData.useCS = codeSeg; codeViewData.useEIP = codeOfs; + codeViewData.cursorPos = 0; return true; }; @@ -1226,6 +1244,7 @@ bool ParseCommand(char* str) { DEBUG_ShowMsg("DEBUG: Set code overview to interrupt handler %X\n",intNr); codeViewData.useCS = mem_readw(intNr*4+2); codeViewData.useEIP = mem_readw(intNr*4); + codeViewData.cursorPos = 0; return true; } }; @@ -1259,7 +1278,8 @@ bool ParseCommand(char* str) { if (command == "HELP" || command == "?") { DEBUG_ShowMsg("Debugger commands (enter all values in hex or as register):\n"); DEBUG_ShowMsg("--------------------------------------------------------------------------\n"); - DEBUG_ShowMsg("F3/F6 - Re-enter previous command.\n"); + DEBUG_ShowMsg("F3/F6 - Previous command in history.\n"); + DEBUG_ShowMsg("F4/F7 - Next command in history.\n"); DEBUG_ShowMsg("F5 - Run.\n"); DEBUG_ShowMsg("F9 - Set/Remove breakpoint.\n"); DEBUG_ShowMsg("F10/F11 - Step over / trace into instruction.\n"); @@ -1476,12 +1496,12 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) { if (jmp) { pos = strchr(instu,'$'); if (pos) { - pos = strchr(instu,'+'); - if (pos) { - strcpy(result,"(down)"); - } else { - strcpy(result,"(up)"); - } + pos = strchr(instu,'+'); + if (pos) { + strcpy(result,"(down)"); + } else { + strcpy(result,"(up)"); + } } } else { sprintf(result,"(no jmp)"); @@ -1497,6 +1517,11 @@ Bit32u DEBUG_CheckKeys(void) { if (key>0) { #if defined(WIN32) && defined(__PDCURSES__) switch (key) { + case PADENTER: key=0x0A; break; + case PADSLASH: key='/'; break; + case PADSTAR: key='*'; break; + case PADMINUS: key='-'; break; + case PADPLUS: key='+'; break; case ALT_D: if (ungetch('D') != ERR) key=27; break; @@ -1518,7 +1543,7 @@ Bit32u DEBUG_CheckKeys(void) { case 27: // escape (a bit slow): Clears line. and processes alt commands. key=getch(); if(key < 0) { //Purely escape Clear line - codeViewData.inputStr[0] = 0; + ClearInputLine(); break; } @@ -1584,23 +1609,54 @@ Bit32u DEBUG_CheckKeys(void) { case KEY_END: // End: scroll log page down DEBUG_RefreshPage(1); break; - case KEY_F(6): // Re-enter previous command (f1-f4 generate rubbish at my place) - case KEY_F(3): // Re-enter previous command - // copy prevInputStr back into inputStr - safe_strncpy(codeViewData.inputStr, codeViewData.prevInputStr, sizeof(codeViewData.inputStr)); + case KEY_IC: // Insert: toggle insert/overwrite + codeViewData.ovrMode = !codeViewData.ovrMode; break; + case KEY_LEFT: // move to the left in command line + if (codeViewData.inputPos > 0) codeViewData.inputPos--; + break; + case KEY_RIGHT: // move to the right in command line + if (codeViewData.inputStr[codeViewData.inputPos]) codeViewData.inputPos++; + break; + case KEY_F(6): // previous command (f1-f4 generate rubbish at my place) + case KEY_F(3): // previous command + if (histBuffPos == histBuff.begin()) break; + if (histBuffPos == histBuff.end()) { + // copy inputStr to suspInputStr so we can restore it + safe_strncpy(codeViewData.suspInputStr, codeViewData.inputStr, sizeof(codeViewData.suspInputStr)); + } + safe_strncpy(codeViewData.inputStr,(*--histBuffPos).c_str(),sizeof(codeViewData.inputStr)); + codeViewData.inputPos = strlen(codeViewData.inputStr); + break; + case KEY_F(7): // next command (f1-f4 generate rubbish at my place) + case KEY_F(4): // next command + if (histBuffPos == histBuff.end()) break; + if (++histBuffPos != histBuff.end()) { + safe_strncpy(codeViewData.inputStr,(*histBuffPos).c_str(),sizeof(codeViewData.inputStr)); + } else { + // copy suspInputStr back into inputStr + safe_strncpy(codeViewData.inputStr, codeViewData.suspInputStr, sizeof(codeViewData.inputStr)); + } + codeViewData.inputPos = strlen(codeViewData.inputStr); + break; case KEY_F(5): // Run Program debugging=false; CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); ignoreAddressOnce = SegPhys(cs)+reg_eip; DOSBOX_SetNormalLoop(); break; - case KEY_F(9): // Set/Remove TBreakpoint + case KEY_F(9): // Set/Remove Breakpoint { PhysPt ptr = GetAddress(codeViewData.cursorSeg,codeViewData.cursorOfs); - if (CBreakpoint::IsBreakpoint(ptr)) CBreakpoint::DeleteBreakpoint(ptr); - else CBreakpoint::AddBreakpoint(codeViewData.cursorSeg, codeViewData.cursorOfs, false); + if (CBreakpoint::IsBreakpoint(ptr)) { + CBreakpoint::DeleteBreakpoint(ptr); + DEBUG_ShowMsg("DEBUG: Breakpoint deletion success.\n"); + } + else { + CBreakpoint::AddBreakpoint(codeViewData.cursorSeg, codeViewData.cursorOfs, false); + DEBUG_ShowMsg("DEBUG: Set breakpoint at %04X:%04X\n",codeViewData.cursorSeg,codeViewData.cursorOfs); + } } - break; + break; case KEY_F(10): // Step over inst if (StepOver()) return 0; else { @@ -1621,28 +1677,54 @@ Bit32u DEBUG_CheckKeys(void) { CBreakpoint::ignoreOnce = 0; break; case 0x0A: //Parse typed Command - codeViewData.inputMode = true; + codeViewData.inputStr[MAXCMDLEN] = '\0'; if(ParseCommand(codeViewData.inputStr)) { - // copy inputStr to prevInputStr so we can restore it if the user hits F3 - safe_strncpy(codeViewData.prevInputStr, codeViewData.inputStr, sizeof(codeViewData.prevInputStr)); - // clear input line ready for next command - codeViewData.inputStr[0] = 0; + char* cmd = ltrim(codeViewData.inputStr); + if (histBuff.empty() || *--histBuff.end()!=cmd) + histBuff.push_back(cmd); + if (histBuff.size() > MAX_HIST_BUFFER) histBuff.pop_front(); + histBuffPos = histBuff.end(); + ClearInputLine(); + } else { + codeViewData.inputPos = strlen(codeViewData.inputStr); + } + break; + case KEY_BACKSPACE: //backspace (linux) + case 0x7f: // backspace in some terminal emulators (linux) + case 0x08: // delete + if (codeViewData.inputPos == 0) break; + codeViewData.inputPos--; + // fallthrough + case KEY_DC: // delete character + if ((codeViewData.inputPos<0) || (codeViewData.inputPos>=MAXCMDLEN)) break; + if (codeViewData.inputStr[codeViewData.inputPos] != 0) { + codeViewData.inputStr[MAXCMDLEN] = '\0'; + for(char* p=&codeViewData.inputStr[codeViewData.inputPos];(*p=*(p+1));p++) {} + } + break; + default: + if ((key>=32) && (key<127)) { + if ((codeViewData.inputPos<0) || (codeViewData.inputPos>=MAXCMDLEN)) break; + codeViewData.inputStr[MAXCMDLEN] = '\0'; + if (codeViewData.inputStr[codeViewData.inputPos] == 0) { + codeViewData.inputStr[codeViewData.inputPos++] = char(key); + codeViewData.inputStr[codeViewData.inputPos] = '\0'; + } else if (!codeViewData.ovrMode) { + int len = (int) strlen(codeViewData.inputStr); + if (len < MAXCMDLEN) { + for(len++;len>codeViewData.inputPos;len--) + codeViewData.inputStr[len]=codeViewData.inputStr[len-1]; + codeViewData.inputStr[codeViewData.inputPos++] = char(key); + } + } else { + codeViewData.inputStr[codeViewData.inputPos++] = char(key); + } + } else if (key==killchar()) { + ClearInputLine(); } break; - case 0x107: //backspace (linux) - case 0x7f: //backspace in some terminal emulators (linux) - case 0x08: // delete - if (strlen(codeViewData.inputStr)>0) codeViewData.inputStr[strlen(codeViewData.inputStr)-1] = 0; - break; - default : if ((key>=32) && (key<=128) && (strlen(codeViewData.inputStr)<253)) { - Bit32u len = strlen(codeViewData.inputStr); - codeViewData.inputStr[len] = char(key); - codeViewData.inputStr[len+1] = 0; - } - break; - } - if (ret<0) return ret; + if (ret<0) return ret; if (ret>0) { ret=(*CallBack_Handlers[ret])(); if (ret) { @@ -1902,7 +1984,7 @@ static void LogInstruction(Bit16u segValue, Bit32u eipValue, ofstream& out) { char ibytes[200]=""; char tmpc[200]; for (Bitu i=0; iFindCommand(i++,temp_line)==true;) { strncat(args,temp_line.c_str(),256); @@ -2027,8 +2108,7 @@ void DEBUG_SetupConsole(void) { #endif memset((void *)&dbg,0,sizeof(dbg)); debugging=false; - dbg.active_win=3; - input_count=0; +// dbg.active_win=3; /* Start the Debug Gui */ DBGUI_StartUp(); } @@ -2037,6 +2117,7 @@ static void DEBUG_ShutDown(Section * /*sec*/) { CBreakpoint::DeleteAll(); CDebugVar::DeleteAll(); curs_set(old_cursor_state); + endwin(); #ifndef WIN32 tcsetattr(0, TCSANOW,&consolesettings); // printf("\e[0m\e[2J"); //Seems to destroy scrolling @@ -2049,11 +2130,11 @@ Bitu debugCallback; void DEBUG_Init(Section* sec) { - MSG_Add("DEBUG_CONFIGFILE_HELP","Debugger related options.\n"); +// MSG_Add("DEBUG_CONFIGFILE_HELP","Debugger related options.\n"); DEBUG_DrawScreen(); /* Add some keyhandlers */ MAPPER_AddHandler(DEBUG_Enable,MK_pause,MMOD2,"debugger","Debugger"); - /* Clear the TBreakpoint list */ + /* Reset code overview and input line */ memset((void*)&codeViewData,0,sizeof(codeViewData)); /* setup debug.com */ PROGRAMS_MakeFile("DEBUG.COM",DEBUG_ProgramStart); @@ -2154,7 +2235,7 @@ static void SaveMemory(Bitu seg, Bitu ofs1, Bit32u num) { sprintf(buffer,"%04X:%04X ",seg,ofs1); for (Bit16u x=0; x<16; x++) { Bit8u value; - if (mem_readb_checked(GetAddress(seg,ofs1+x),&value)) sprintf(temp,"?? ",value); + if (mem_readb_checked(GetAddress(seg,ofs1+x),&value)) sprintf(temp,"%s","?? "); else sprintf(temp,"%02X ",value); strcat(buffer,temp); } @@ -2167,7 +2248,7 @@ static void SaveMemory(Bitu seg, Bitu ofs1, Bit32u num) { sprintf(buffer,"%04X:%04X ",seg,ofs1); for (Bit16u x=0; xGetAdr(),&value)) - snprintf(buffer,DEBUG_VAR_BUF_LEN, "??????", value); + snprintf(buffer,DEBUG_VAR_BUF_LEN, "%s", "??????"); else snprintf(buffer,DEBUG_VAR_BUF_LEN, "0x%04x", value); @@ -2248,8 +2329,6 @@ static void DrawVariables(void) { const Bit32u LOGCPUMAX = 20000; -static Bit16u logCpuCS [LOGCPUMAX]; -static Bit32u logCpuEIP[LOGCPUMAX]; static Bit32u logCount = 0; struct TLogInst { @@ -2287,7 +2366,7 @@ void DEBUG_HeavyLogInstruction(void) { PhysPt start = GetAddress(SegValue(cs),reg_eip); char dline[200]; - Bitu size = DasmI386(dline, start, reg_eip, cpu.code.big); + DasmI386(dline, start, reg_eip, cpu.code.big); char* res = empty; if (showExtend) { res = AnalyzeInstruction(dline,false); diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index fc9f1ca3..936086c7 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -154,7 +154,7 @@ static void DrawBars(void) { /* Show the Variable Overview bar */ mvaddstr(dbg.win_var->_begy-1,0, "---(Variable Overview )---"); /* Show the Output OverView */ - mvaddstr(dbg.win_out->_begy-1,0, "---(OutPut/Input Scroll: home/end )---"); + mvaddstr(dbg.win_out->_begy-1,0, "---(Output Scroll: home/end )---"); attrset(0); } @@ -178,8 +178,8 @@ static void MakeSubWindows(void) { dbg.win_var=subwin(dbg.win_main,4,win_main_maxx,outy,0); outy+=5; /* The Output Window */ - dbg.win_out=subwin(dbg.win_main,win_main_maxy-outy-1,win_main_maxx,outy,0); - dbg.input_y=win_main_maxy-1; + dbg.win_out=subwin(dbg.win_main,win_main_maxy-outy,win_main_maxx,outy,0); +// dbg.input_y=win_main_maxy-1; scrollok(dbg.win_out,TRUE); DrawBars(); Draw_RegisterLayout(); @@ -257,7 +257,7 @@ void LOG_StartUp(void) { Prop_bool* Pbool = sect->Add_bool(buf,Property::Changeable::Always,true); Pbool->Set_help("Enable/Disable logging of this type."); } - MSG_Add("LOG_CONFIGFILE_HELP","Logging related options for the debugger.\n"); +// MSG_Add("LOG_CONFIGFILE_HELP","Logging related options for the debugger.\n"); } From d7404e0ba4df6b8c231c1a2679324d764a364f48 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 9 Jun 2010 19:09:39 +0000 Subject: [PATCH 3524/4131] Detect +/- INF when loading a 80bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3614 --- src/fpu/fpu_instructions.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 9a505a2b..06b97478 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -97,7 +97,7 @@ static Real64 FPU_FLD80(PhysPt addr) { test.eind.l.lower = mem_readd(addr); test.eind.l.upper = mem_readd(addr+4); test.begin = mem_readw(addr+8); - + Bit64s exp64 = (((test.begin&0x7fff) - BIAS80)); Bit64s blah = ((exp64 >0)?exp64:-exp64)&0x3ff; Bit64s exp64final = ((exp64 >0)?blah:-blah) +BIAS64; @@ -106,6 +106,11 @@ static Real64 FPU_FLD80(PhysPt addr) { Bit64s sign = (test.begin&0x8000)?1:0; FPU_Reg result; result.ll = (sign <<63)|(exp64final << 52)| mant64; + + if(test.eind.l.lower == 0 && test.eind.l.upper == 0x80000000 && (test.begin&0x7fff) == 0x7fff) { + //Detect INF and -INF (score 3.11 when drawing a slur.) + result.d = sign?-HUGE_VAL:HUGE_VAL; + } return result.d; //mant64= test.mant80/2***64 * 2 **53 From 9d427201b5ae583f68ebf1f978330ba927af85a5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 12 Jun 2010 08:54:08 +0000 Subject: [PATCH 3525/4131] gcc 4.4 on FreeBSD. (Alex) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3615 --- include/setup.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/setup.h b/include/setup.h index db75ada8..5239cd5d 100644 --- a/include/setup.h +++ b/include/setup.h @@ -42,6 +42,11 @@ #include #endif +#ifndef CH_CSTDIO +#define CH_CSTDIO +#include +#endif + class Hex { private: From c111163bec33125772a4321ac5913cda136c0676 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 26 Jun 2010 11:17:48 +0000 Subject: [PATCH 3526/4131] Fix Dactylus Installer. (thanks ripsaw8080) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3616 --- src/dos/dos_files.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index c720fd9a..1734035e 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -203,6 +203,13 @@ bool DOS_GetCurrentDir(Bit8u drive,char * const buffer) { bool DOS_ChangeDir(char const * const dir) { Bit8u drive;char fulldir[DOS_PATHLENGTH]; + const char * testdir=dir; + if (strlen(testdir) && testdir[1]==':') testdir+=2; + size_t len=strlen(testdir); + if (!len || (len>1 && testdir[len-1]=='\\')) { + DOS_SetError(DOSERR_PATH_NOT_FOUND); + return false; + } if (!DOS_MakeName(dir,fulldir,&drive)) return false; if (Drives[drive]->TestDir(fulldir)) { From ad7695d707e51b98f16fd788f83cc243731ff86f Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Mon, 28 Jun 2010 12:16:15 +0000 Subject: [PATCH 3527/4131] Fix regression in Spacewar with Hercules video. Thanks ripsaw8080 for reporting. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3617 --- src/hardware/vga_other.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 710b6c07..7fd18293 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -516,7 +516,12 @@ static void write_hercules(Bitu port,Bitu val,Bitu /*iolen*/) { break; } case 0x3bf: - vga.herc.enable_bits=(Bit8u)val; + if ( vga.herc.enable_bits ^ val) { + vga.herc.enable_bits=val; + // Bit 1 enables the upper 32k of video memory, + // so update the handlers + VGA_SetupHandlers(); + } break; } } From f30cf339c3a7b057e2b853a64f8543d1bc4f60c3 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Mon, 28 Jun 2010 21:32:43 +0000 Subject: [PATCH 3528/4131] Text mode panning patch for the vgaonly machine Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3618 --- include/vga.h | 2 + src/hardware/vga_attr.cpp | 49 ++++--- src/hardware/vga_draw.cpp | 291 ++++++++++++++++---------------------- 3 files changed, 157 insertions(+), 185 deletions(-) diff --git a/include/vga.h b/include/vga.h index a3d02c20..084f685f 100644 --- a/include/vga.h +++ b/include/vga.h @@ -157,6 +157,8 @@ typedef struct { Bit8u font[64*1024]; Bit8u * font_tables[2]; Bitu blinking; + bool blink; + bool char9dot; struct { Bitu address; Bit8u sline,eline; diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 9f23b509..700fc7c5 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -76,26 +76,33 @@ void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) { 10h and 14h. */ break; - case 0x10: /* Mode Control Register */ + case 0x10: { /* Mode Control Register */ if (!IS_VGA_ARCH) val&=0x1f; // not really correct, but should do it - if ((attr(mode_control) ^ val) & 0x80) { - attr(mode_control)^=0x80; - for (Bit8u i=0;i<0x10;i++) { + Bitu difference = attr(mode_control)^val; + attr(mode_control)=(Bit8u)val; + + if (difference & 0x80) { + for (Bit8u i=0;i<0x10;i++) VGA_ATTR_SetPalette(i,vga.attr.palette[i]); + } + if (difference & 0x08) + VGA_SetBlinking(val & 0x8); + + if (difference & 0x41) + VGA_DetermineMode(); + + if (difference & 0x04) { + // recompute the panning value + if(vga.mode==M_TEXT) { + Bit8u pan_reg = attr(horizontal_pel_panning); + if (pan_reg > 7) + vga.config.pel_panning=0; + else if (val&0x4) // 9-dot wide characters + vga.config.pel_panning=(Bit8u)(pan_reg+1); + else // 8-dot characters + vga.config.pel_panning=(Bit8u)pan_reg; } } - if ((attr(mode_control) ^ val) & 0x08) { - VGA_SetBlinking(val & 0x8); - } - if ((attr(mode_control) ^ val) & 0x04) { - attr(mode_control)=(Bit8u)val; - VGA_DetermineMode(); - if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) VGA_StartResize(); - } else { - attr(mode_control)=(Bit8u)val; - VGA_DetermineMode(); - } - /* 0 Graphics mode if set, Alphanumeric mode else. 1 Monochrome mode if set, color mode else. @@ -113,6 +120,7 @@ void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) { used. */ break; + } case 0x11: /* Overscan Color Register */ attr(overscan_color)=(Bit8u)val; /* 0-5 Color of screen border. Color is defined as in the palette registers. */ @@ -134,9 +142,12 @@ void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) { attr(horizontal_pel_panning)=val & 0xF; switch (vga.mode) { case M_TEXT: - if ((val==0x7) && (svgaCard==SVGA_None)) vga.config.pel_panning=7; - if (val>0x7) vga.config.pel_panning=0; - else vga.config.pel_panning=(Bit8u)(val+1); + if (val > 7) + vga.config.pel_panning=0; + else if (vga.attr.mode_control&0x4) // 9-dot wide characters + vga.config.pel_panning=(Bit8u)(val+1); + else // 8-dot characters + vga.config.pel_panning=(Bit8u)val; break; case M_VGA: case M_LIN8: diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 459e768c..d756ec51 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -197,14 +197,6 @@ static Bit8u * VGA_Draw_Xlat16_Linear_Line(Bitu vidstart, Bitu /*line*/) { temps[i]=vga.dac.xlat16[ret[i]]; } return TempLine; - /* -#if !defined(C_UNALIGNED_MEMORY) - if (GCC_UNLIKELY( ((Bitu)ret) & (sizeof(Bitu)-1)) ) { - memcpy( TempLine, ret, vga.draw.line_length ); - return TempLine; - } -#endif - return ret;*/ } //Test version, might as well keep it @@ -446,167 +438,121 @@ static Bit8u * VGA_TEXT_Herc_Draw_Line(Bitu vidstart, Bitu line) { skip_cursor: return TempLine; } - -static Bit8u * VGA_TEXT_Xlat16_Draw_Line(Bitu vidstart, Bitu line) { - Bits font_addr; - Bit16u * draw=(Bit16u *)TempLine; - const Bit8u* vidmem = VGA_Text_Memwrap(vidstart); - for (Bitu cx=0;cx> 3)&1][chr*32+line]; - Bit32u mask1=TXT_Font_Table[font>>4] & FontMask[col >> 7]; - Bit32u mask2=TXT_Font_Table[font&0xf] & FontMask[col >> 7]; - Bit32u fg=TXT_FG_Table[col&0xf]; - Bit32u bg=TXT_BG_Table[col>>4]; - - mask1=(fg&mask1) | (bg&~mask1); - mask2=(fg&mask2) | (bg&~mask2); - - for(int i = 0; i < 4; i++) { - *draw++ = vga.dac.xlat16[(mask1>>8*i)&0xff]; - } - for(int i = 0; i < 4; i++) { - *draw++ = vga.dac.xlat16[(mask2>>8*i)&0xff]; - } - } - if (!vga.draw.cursor.enabled || !(vga.draw.cursor.count&0x8)) goto skip_cursor; - font_addr = (vga.draw.cursor.address-vidstart) >> 1; - if (font_addr>=0 && font_addr<(Bits)vga.draw.blocks) { - if (linevga.draw.cursor.eline) goto skip_cursor; - draw=(Bit16u *)&TempLine[font_addr*16]; - Bit8u att=(Bit8u)(TXT_FG_Table[vga.tandy.draw_base[vga.draw.cursor.address+1]&0xf]&0xff); - for(int i = 0; i < 8; i++) { - *draw++ = vga.dac.xlat16[att]; - } - } -skip_cursor: - return TempLine; -} - /* -static Bit8u * VGA_TEXT_Draw_Line_9(Bitu vidstart, Bitu line) { - Bits font_addr; - Bit8u * draw=(Bit8u *)TempLine; - bool underline=(Bitu)(vga.crtc.underline_location&0x1f)==line; - Bit8u pel_pan=(Bit8u)vga.draw.panning; - if ((vga.attr.mode_control&0x20) && (vga.draw.lines_done>=vga.draw.split_line)) pel_pan=0; - const Bit8u* vidmem = VGA_Text_Memwrap(vidstart); - Bit8u chr=vidmem[0]; - Bit8u col=vidmem[1]; - Bit8u font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<>4]&0xff); - Bitu draw_blocks=vga.draw.blocks; - draw_blocks++; - for (Bitu cx=1;cx>(8-pel_pan); - else font|=vga.draw.font_tables[(col >> 3)&1][chr*32+line]>>(8-pel_pan); - fg=col&0xf; - bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff); +// combined 8/9-dot wide text mode 8bpp line drawing function +static Bit8u* VGA_TEXT_Draw_Line(Bitu vidstart, Bitu line) { + // keep it aligned: + Bit8u* draw = ((Bit8u*)TempLine) + 16 - vga.draw.panning; + const Bit8u* vidmem = VGA_Text_Memwrap(vidstart); // pointer to chars+attribs + Bitu blocks = vga.draw.blocks; + if (vga.draw.panning) blocks++; // if the text is panned part of an + // additional character becomes visible + while (blocks--) { // for each character in the line + Bitu chr = *vidmem++; + Bitu attr = *vidmem++; + // the font pattern + Bitu font = vga.draw.font_tables[(attr >> 3)&1][(chr<<5)+line]; + + Bitu background = attr >> 4; + // if blinking is enabled bit7 is not mapped to attributes + if (vga.draw.blinking) background &= ~0x8; + // choose foreground color if blinking not set for this cell or blink on + Bitu foreground = (vga.draw.blink || (!(attr&0x80)))? + (attr&0xf):background; + // underline: all foreground [freevga: 0x77, previous 0x7] + if (GCC_UNLIKELY(((attr&0x77) == 0x01) && + (vga.crtc.underline_location&0x1f)==line)) + background = foreground; + if (vga.draw.char9dot) { + font <<=1; // 9 pixels + // extend to the 9th pixel if needed + if ((font&0x2) && (vga.attr.mode_control&0x04) && + (chr>=0xc0) && (chr<=0xdf)) font |= 1; + for (Bitu n = 0; n < 9; n++) { + *draw++ = (font&0x100)? foreground:background; + font <<= 1; + } } else { - chr=vidmem[(cx-1)*2]; - col=vidmem[(cx-1)*2+1]; - if (underline && ((col&0x07) == 0x01)) font=0xff; - else font=vga.draw.font_tables[(col >> 3)&1][chr*32+line]; - fg=col&0xf; - bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff); - } - if (FontMask[col>>7]==0) font=0; - *draw++=(font&0x80)?fg:bg; *draw++=(font&0x40)?fg:bg; - *draw++=(font&0x20)?fg:bg; *draw++=(font&0x10)?fg:bg; - *draw++=(font&0x08)?fg:bg; *draw++=(font&0x04)?fg:bg; - *draw++=(font&0x02)?fg:bg; - Bit8u last=(font&0x01)?fg:bg; - *draw++=last; - *draw++=((vga.attr.mode_control&0x04) && ((chr<0xc0) || (chr>0xdf))) ? bg : last; - if (pel_pan) { - if (underline && ((col&0x07) == 0x01)) font=0xff; - else font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<> 1; - if (font_addr>=0 && font_addr<(Bits)vga.draw.blocks) { - if (linevga.draw.cursor.eline) goto skip_cursor; - draw=&TempLine[font_addr*9]; - Bit8u fg=vga.tandy.draw_base[vga.draw.cursor.address+1]&0xf; - *draw++=fg; *draw++=fg; *draw++=fg; *draw++=fg; - *draw++=fg; *draw++=fg; *draw++=fg; *draw++=fg; + // draw the text mode cursor if needed + if ((vga.draw.cursor.count&0x8) && (line >= vga.draw.cursor.sline) && + (line <= vga.draw.cursor.eline) && vga.draw.cursor.enabled) { + // the adress of the attribute that makes up the cell the cursor is in + Bits attr_addr = (vga.draw.cursor.address-vidstart) >> 1; + if (attr_addr >= 0 && attr_addr < (Bits)vga.draw.blocks) { + Bitu index = attr_addr * (vga.draw.char9dot? 9:8); + draw = (Bit8u*)(&TempLine[index]) + 16 - vga.draw.panning; + + Bitu foreground = vga.tandy.draw_base[vga.draw.cursor.address+1] & 0xf; + for (Bitu i = 0; i < 8; i++) { + *draw++ = foreground; + } + } } -skip_cursor: - return TempLine; + return TempLine+16; } */ - -static Bit8u * VGA_TEXT_Xlat16_Draw_Line_9(Bitu vidstart, Bitu line) { - Bits font_addr; - Bit16u * draw=(Bit16u *)TempLine; - bool underline=(Bitu)(vga.crtc.underline_location&0x1f)==line; - Bit8u pel_pan=(Bit8u)vga.draw.panning; - if ((vga.attr.mode_control&0x20) && (vga.draw.lines_done>=vga.draw.split_line)) pel_pan=0; - const Bit8u* vidmem = VGA_Text_Memwrap(vidstart); - Bit8u chr=vidmem[0]; - Bit8u col=vidmem[1]; - Bit8u font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<>4]&0xff); - Bitu draw_blocks=vga.draw.blocks; - draw_blocks++; - for (Bitu cx=1;cx>(8-pel_pan); - else font|=vga.draw.font_tables[(col >> 3)&1][chr*32+line]>>(8-pel_pan); - fg=col&0xf; - bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff); +// combined 8/9-dot wide text mode 16bpp line drawing function +static Bit8u* VGA_TEXT_Xlat16_Draw_Line(Bitu vidstart, Bitu line) { + // keep it aligned: + Bit16u* draw = ((Bit16u*)TempLine) + 16 - vga.draw.panning; + const Bit8u* vidmem = VGA_Text_Memwrap(vidstart); // pointer to chars+attribs + Bitu blocks = vga.draw.blocks; + if (vga.draw.panning) blocks++; // if the text is panned part of an + // additional character becomes visible + while (blocks--) { // for each character in the line + Bitu chr = *vidmem++; + Bitu attr = *vidmem++; + // the font pattern + Bitu font = vga.draw.font_tables[(attr >> 3)&1][(chr<<5)+line]; + + Bitu background = attr >> 4; + // if blinking is enabled bit7 is not mapped to attributes + if (vga.draw.blinking) background &= ~0x8; + // choose foreground color if blinking not set for this cell or blink on + Bitu foreground = (vga.draw.blink || (!(attr&0x80)))? + (attr&0xf):background; + // underline: all foreground [freevga: 0x77, previous 0x7] + if (GCC_UNLIKELY(((attr&0x77) == 0x01) && + (vga.crtc.underline_location&0x1f)==line)) + background = foreground; + if (vga.draw.char9dot) { + font <<=1; // 9 pixels + // extend to the 9th pixel if needed + if ((font&0x2) && (vga.attr.mode_control&0x04) && + (chr>=0xc0) && (chr<=0xdf)) font |= 1; + for (Bitu n = 0; n < 9; n++) { + *draw++ = vga.dac.xlat16[(font&0x100)? foreground:background]; + font <<= 1; + } } else { - chr=vidmem[(cx-1)*2]; - col=vidmem[(cx-1)*2+1]; - if (underline && ((col&0x07) == 0x01)) font=0xff; - else font=vga.draw.font_tables[(col >> 3)&1][chr*32+line]; - fg=col&0xf; - bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff); - } - if (FontMask[col>>7]==0) font=0; - Bit8u mask=0x80; - for (int i = 0; i < 7; i++) { - *draw++=vga.dac.xlat16[font&mask?fg:bg]; - mask>>=1; - } - Bit16u lastval=vga.dac.xlat16[font&mask?fg:bg]; - *draw++=lastval; - *draw++=(((vga.attr.mode_control&0x04) && ((chr<0xc0) || (chr>0xdf))) && - !(underline && ((col&0x07) == 0x01))) ? - (vga.dac.xlat16[bg]) : lastval; - if (pel_pan) { - if (underline && ((col&0x07) == 0x01)) font=0xff; - else font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<> 1; - if (font_addr>=0 && font_addr<(Bits)vga.draw.blocks) { - if (linevga.draw.cursor.eline) goto skip_cursor; - draw=(Bit16u*)&TempLine[font_addr*18]; - Bit8u fg=vga.tandy.draw_base[vga.draw.cursor.address+1]&0xf; - for(int i = 0; i < 8; i++) { - *draw++ = vga.dac.xlat16[fg]; + // draw the text mode cursor if needed + if ((vga.draw.cursor.count&0x8) && (line >= vga.draw.cursor.sline) && + (line <= vga.draw.cursor.eline) && vga.draw.cursor.enabled) { + // the adress of the attribute that makes up the cell the cursor is in + Bits attr_addr = (vga.draw.cursor.address-vidstart) >> 1; + if (attr_addr >= 0 && attr_addr < (Bits)vga.draw.blocks) { + Bitu index = attr_addr * (vga.draw.char9dot? 18:16); + draw = (Bit16u*)(&TempLine[index]) + 16 - vga.draw.panning; + + Bitu foreground = vga.tandy.draw_base[vga.draw.cursor.address+1] & 0xf; + for (Bitu i = 0; i < 8; i++) { + *draw++ = vga.dac.xlat16[foreground]; + } } - //if(underline && ((col&0x07) == 0x01)) - // *draw = vga.dac.xlat16[fg]; } -skip_cursor: - return TempLine; + return TempLine+32; } #ifdef VGA_KEEP_CHANGES @@ -631,6 +577,10 @@ static void VGA_ProcessSplit() { // On the EGA the address is always reset to 0. if ((vga.attr.mode_control&0x20) || (machine==MCH_EGA)) { vga.draw.address=0; + // reset panning to 0 here so we don't have to check for + // it in the character draw functions. It will be set back + // to its proper value in v-retrace + vga.draw.panning=0; } else { // In text mode only the characters are shifted by panning, not the address; // this is done in the text line draw function. @@ -851,6 +801,10 @@ static void VGA_VerticalTimer(Bitu /*val*/) { /* check for blinking and blinking change delay */ FontMask[1]=(vga.draw.blinking & (vga.draw.cursor.count >> 4)) ? 0 : 0xffffffff; + /* if blinking is enabled, 'blink' will toggle between true + * and false. Otherwise it's true */ + vga.draw.blink = ((vga.draw.blinking & (vga.draw.cursor.count >> 4)) + || !vga.draw.blinking) ? true:false; break; case M_HERC_GFX: break; @@ -1329,17 +1283,22 @@ void VGA_SetupDrawing(Bitu /*val*/) { aspect_ratio=1.0; vga.draw.blocks=width; doublewidth=(vga.seq.clocking_mode & 0x8) > 0; - if ((IS_VGA_ARCH) && (svgaCard==SVGA_None) && !(vga.seq.clocking_mode&0x01)) { - width*=9; /* 9 bit wide text font */ - VGA_DrawLine=VGA_TEXT_Xlat16_Draw_Line_9; + if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) { + // vgaonly: allow 9-pixel wide fonts + if(vga.seq.clocking_mode&0x01) { + vga.draw.char9dot = false; + width*=8; + } else { + vga.draw.char9dot = true; + width*=9; + } + VGA_DrawLine=VGA_TEXT_Xlat16_Draw_Line; bpp=16; -// VGA_DrawLine=VGA_TEXT_Draw_Line_9; } else { - width<<=3; /* 8 bit wide text font */ - if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) { - VGA_DrawLine=VGA_TEXT_Xlat16_Draw_Line; - bpp=16; - } else VGA_DrawLine=VGA_TEXT_Draw_Line; + // not vgaonly: force 8-pixel wide fonts + width*=8; // 8 bit wide text font + vga.draw.char9dot = false; + VGA_DrawLine=VGA_TEXT_Draw_Line; } break; case M_HERC_GFX: From 47281bd3e55c81b64c8c55b75ea94d3d71f15829 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Fri, 9 Jul 2010 20:56:32 +0000 Subject: [PATCH 3529/4131] INT10 EGA: Implement font intensity/blinking switch, fix font height calculation, screen parameters - makes Norton Commander work with machine=ega. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3619 --- src/ints/int10.cpp | 12 +++------ src/ints/int10_memory.cpp | 16 ++++++++++-- src/ints/int10_pal.cpp | 51 ++++++++++++++++++++++++++------------- 3 files changed, 51 insertions(+), 28 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index b5b3abe0..fed4a7d7 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -138,8 +138,7 @@ static Bitu INT10_Handler(void) { reg_ah=(Bit8u)real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); break; case 0x10: /* Palette functions */ - if ((machine==MCH_CGA) || ((!IS_VGA_ARCH) && (reg_al>0x02))) break; - //TODO: subfunction 0x03 for ega + if ((machine==MCH_CGA) || ((!IS_VGA_ARCH) && (reg_al>0x03))) break; switch (reg_al) { case 0x00: /* SET SINGLE PALETTE REGISTER */ INT10_SetSinglePaletteRegister(reg_bl,reg_bh); @@ -302,13 +301,8 @@ graphics_chars: break; } if ((reg_bh<=7) || (svgaCard==SVGA_TsengET4K)) { - if (machine==MCH_EGA) { - reg_cx=0x0e; - reg_dl=0x18; - } else { - reg_cx=real_readw(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); - reg_dl=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS); - } + reg_cx=real_readw(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); + reg_dl=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS); } break; default: diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 789d52a3..646894f5 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -66,9 +66,21 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu Bit16u base=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); IO_Write(base,0x9); IO_Write(base+1,(IO_Read(base+1) & 0xe0)|(height-1)); - //Vertical display end bios says, but should stay the same? + // Vertical display end bios says, but should stay the same? + // Not on EGA. + Bitu rows = CurMode->sheight/height; + if (machine==MCH_EGA) { + Bitu displayend = rows*height - 1; + IO_Write(base,0x12); + IO_Write(base+1,(Bit8u)(displayend & 0xff)); + IO_Write(base,0x7); + // Note: IBM EGA registers can't be read + Bitu v_overflow = IO_Read(base+1) & ~0x2; + if (displayend & 0x100) v_overflow |= 0x2; + IO_Write(base+1,(Bit8u)v_overflow); + } //Rows setting in bios segment - real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,(CurMode->sheight/height)-1); + real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,rows-1); real_writeb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,(Bit8u)height); //TODO Reprogram cursor size? } diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index e9ff967d..266ac263 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -96,25 +96,42 @@ void INT10_SetAllPaletteRegisters(PhysPt data) { } void INT10_ToggleBlinkingBit(Bit8u state) { - Bit8u value; -// state&=0x01; - if ((state>1) && (svgaCard==SVGA_S3Trio)) return; - ResetACTL(); - - IO_Write(VGAREG_ACTL_ADDRESS,0x10); - value=IO_Read(VGAREG_ACTL_READ_DATA); - if (state<=1) { - value&=0xf7; - value|=state<<3; - } + if(IS_VGA_ARCH) { + Bit8u value; + // state&=0x01; + if ((state>1) && (svgaCard==SVGA_S3Trio)) return; + ResetACTL(); + + IO_Write(VGAREG_ACTL_ADDRESS,0x10); + value=IO_Read(VGAREG_ACTL_READ_DATA); + if (state<=1) { + value&=0xf7; + value|=state<<3; + } - ResetACTL(); - IO_Write(VGAREG_ACTL_ADDRESS,0x10); - IO_Write(VGAREG_ACTL_WRITE_DATA,value); - IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette + ResetACTL(); + IO_Write(VGAREG_ACTL_ADDRESS,0x10); + IO_Write(VGAREG_ACTL_WRITE_DATA,value); + IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette - if (state<=1) { - Bit8u msrval=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR)&0xdf; + if (state<=1) { + Bit8u msrval=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR)&0xdf; + if (state) msrval|=0x20; + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,msrval); + } + } else { // EGA + // Usually it reads this from the mode list in ROM + if (CurMode->type!=M_TEXT) return; + + Bit8u value = (CurMode->cwidth==9)? 0x4:0x0; + if (state) value |= 0x8; + + ResetACTL(); + IO_Write(VGAREG_ACTL_ADDRESS,0x10); + IO_Write(VGAREG_ACTL_WRITE_DATA,value); + IO_Write(VGAREG_ACTL_ADDRESS,0x20); + + Bit8u msrval=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR)& ~0x20; if (state) msrval|=0x20; real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,msrval); } From db66fef41911eb26f0f8c2a89c9eb0a554628433 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 10 Jul 2010 11:36:39 +0000 Subject: [PATCH 3530/4131] Extend int29 to include page and colour. Thanks for your input ripsaw8080. Change removesetup to remove the right amount of bytes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3620 --- src/cpu/callback.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 627b548f..3524c2f3 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -351,12 +351,16 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ phys_writew(physAddress+0x02,(Bit16u)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); + phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax + phys_writeb(physAddress+0x01,(Bit8u)0x53); // push bx + phys_writew(physAddress+0x02,(Bit16u)0x0eb4); // mov ah, 0x0e + phys_writeb(physAddress+0x04,(Bit8u)0xbb); // mov bx, + phys_writew(physAddress+0x05,(Bit16u)0x0007); // 0x0007 + phys_writew(physAddress+0x07,(Bit16u)0x10cd); // int 10 + phys_writeb(physAddress+0x09,(Bit8u)0x5b); // pop bx + phys_writeb(physAddress+0x0a,(Bit8u)0x58); // pop ax + phys_writeb(physAddress+0x0b,(Bit8u)0xcf); //An IRET Instruction + return (use_cb?0x10:0x0c); case CB_HOOKABLE: phys_writeb(physAddress+0x00,(Bit8u)0xEB); //jump near phys_writeb(physAddress+0x01,(Bit8u)0x03); //offset @@ -456,7 +460,7 @@ Bitu CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,PhysPt addr } void CALLBACK_RemoveSetup(Bitu callback) { - for (Bitu i = 0;i < 16;i++) { + for (Bitu i = 0;i < CB_SIZE;i++) { phys_writeb(CALLBACK_PhysPointer(callback)+i ,(Bit8u) 0x00); } } From ef95dc160e1b200c45dcbc3f63ccdf27b46ac14f Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Mon, 12 Jul 2010 21:41:20 +0000 Subject: [PATCH 3531/4131] - Fix EGA panning to behave as on real hardware (fixes Beverly Hills Cop, Faery Tale Adv., Secret Agent 1) - EGA splitscreen updates (Megademo, Secret Agent 1) - Change display address latch timing (Beverly Hills Cop) - Code style adoptions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3621 --- include/vga.h | 2 +- src/hardware/vga_attr.cpp | 3 ++ src/hardware/vga_draw.cpp | 76 +++++++++++++++++++++++++++++---------- 3 files changed, 61 insertions(+), 20 deletions(-) diff --git a/include/vga.h b/include/vga.h index 084f685f..65b526fc 100644 --- a/include/vga.h +++ b/include/vga.h @@ -114,7 +114,7 @@ typedef struct { typedef enum { PART, LINE, - //EGALINE + EGALINE } Drawmode; typedef struct { diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 700fc7c5..e6e5ef69 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -157,6 +157,9 @@ void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) { default: vga.config.pel_panning=(val & 0x7); } + if (machine==MCH_EGA) + // On the EGA panning can be programmed for every scanline: + vga.draw.panning = vga.config.pel_panning; /* 0-3 Indicates number of pixels to shift the display left Value 9bit textmode 256color mode Other modes diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index d756ec51..d7bc789f 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -155,7 +155,7 @@ static Bit8u * VGA_Draw_Changes_Line(Bitu vidstart, Bitu line) { for (; start <= end;start++) { if ( map[start] & checkMask ) { Bitu offset = vidstart & vga.draw.linear_mask; - if(vga.draw.linear_mask-offset < vga.draw.line_length) + if (vga.draw.linear_mask-offset < vga.draw.line_length) memcpy(vga.draw.linear_base+vga.draw.linear_mask+1, vga.draw.linear_base, vga.draw.line_length); Bit8u *ret = &vga.draw.linear_base[ offset ]; #if !defined(C_UNALIGNED_MEMORY) @@ -574,8 +574,7 @@ static INLINE void VGA_ChangesEnd(void ) { static void VGA_ProcessSplit() { - // On the EGA the address is always reset to 0. - if ((vga.attr.mode_control&0x20) || (machine==MCH_EGA)) { + if (vga.attr.mode_control&0x20) { vga.draw.address=0; // reset panning to 0 here so we don't have to check for // it in the character draw functions. It will be set back @@ -585,7 +584,7 @@ static void VGA_ProcessSplit() { // In text mode only the characters are shifted by panning, not the address; // this is done in the text line draw function. vga.draw.address = vga.draw.byte_panning_shift*vga.draw.bytes_skip; - if (!(vga.mode==M_TEXT)) vga.draw.address += vga.draw.panning; + if ((vga.mode!=M_TEXT)&&(machine!=MCH_EGA)) vga.draw.address += vga.draw.panning; } vga.draw.address_line=0; } @@ -612,6 +611,29 @@ static void VGA_DrawSingleLine(Bitu /*blah*/) { } else RENDER_EndUpdate(false); } +static void VGA_DrawEGASingleLine(Bitu /*blah*/) { + if (GCC_UNLIKELY(vga.attr.disabled)) { + memset(TempLine, 0, sizeof(TempLine)); + RENDER_DrawLine(TempLine); + } else { + Bitu address = vga.draw.address; + if (vga.mode!=M_TEXT) address += vga.draw.panning; + Bit8u * data=VGA_DrawLine(address, vga.draw.address_line ); + RENDER_DrawLine(data); + } + + vga.draw.address_line++; + if (vga.draw.address_line>=vga.draw.address_line_total) { + vga.draw.address_line=0; + vga.draw.address+=vga.draw.address_add; + } + vga.draw.lines_done++; + if (vga.draw.split_line==vga.draw.lines_done) VGA_ProcessSplit(); + if (vga.draw.lines_done < vga.draw.lines_total) { + PIC_AddEvent(VGA_DrawEGASingleLine,(float)vga.draw.delay.htotal); + } else RENDER_EndUpdate(false); +} + static void VGA_DrawPart(Bitu lines) { while (lines--) { Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line ); @@ -721,7 +743,6 @@ static void VGA_VerticalTimer(Bitu /*val*/) { VGA_DisplayStartLatch(0); break; case MCH_VGA: - case MCH_EGA: PIC_AddEvent(VGA_DisplayStartLatch, (float)vga.draw.delay.vrstart); PIC_AddEvent(VGA_PanningLatch, (float)vga.draw.delay.vrend); // EGA: 82c435 datasheet: interrupt happens at display end @@ -729,6 +750,10 @@ static void VGA_VerticalTimer(Bitu /*val*/) { // add a little amount of time to make sure the last drawpart has already fired PIC_AddEvent(VGA_VertInterrupt,(float)(vga.draw.delay.vdend + 0.005)); break; + case MCH_EGA: + PIC_AddEvent(VGA_DisplayStartLatch, (float)vga.draw.delay.vrend); + PIC_AddEvent(VGA_VertInterrupt,(float)(vga.draw.delay.vdend + 0.005)); + break; default: E_Exit("This new machine needs implementation in VGA_VerticalTimer too."); break; @@ -748,7 +773,11 @@ static void VGA_VerticalTimer(Bitu /*val*/) { vga.draw.address = vga.config.real_start; vga.draw.byte_panning_shift = 0; // go figure... - if (machine==MCH_EGA) vga.draw.split_line*=2; + if (machine==MCH_EGA) { + if (vga.draw.doubleheight) // Spacepigs EGA Megademo + vga.draw.split_line*=2; + vga.draw.split_line++; // EGA adds one buggy scanline + } // if (machine==MCH_EGA) vga.draw.split_line = ((((vga.config.line_compare&0x5ff)+1)*2-1)/vga.draw.lines_scaled); #ifdef VGA_KEEP_CHANGES bool startaddr_changed=false; @@ -761,13 +790,13 @@ static void VGA_VerticalTimer(Bitu /*val*/) { vga.draw.byte_panning_shift = 8; vga.draw.address += vga.draw.bytes_skip; vga.draw.address *= vga.draw.byte_panning_shift; - vga.draw.address += vga.draw.panning; + if (machine!=MCH_EGA) vga.draw.address += vga.draw.panning; #ifdef VGA_KEEP_CHANGES startaddr_changed=true; #endif break; case M_VGA: - if(vga.config.compatible_chain4 && (vga.crtc.underline_location & 0x40)) { + if (vga.config.compatible_chain4 && (vga.crtc.underline_location & 0x40)) { vga.draw.linear_base = vga.fastmem; vga.draw.linear_mask = 0xffff; } else { @@ -843,16 +872,19 @@ static void VGA_VerticalTimer(Bitu /*val*/) { PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts + draw_skip,vga.draw.parts_lines); break; case LINE: + case EGALINE: if (GCC_UNLIKELY(vga.draw.lines_done < vga.draw.lines_total)) { LOG(LOG_VGAMISC,LOG_NORMAL)( "Lines left: %d", vga.draw.lines_total-vga.draw.lines_done); - PIC_RemoveEvents(VGA_DrawSingleLine); + if (vga.draw.mode==EGALINE) PIC_RemoveEvents(VGA_DrawEGASingleLine); + else PIC_RemoveEvents(VGA_DrawSingleLine); RENDER_EndUpdate(true); } vga.draw.lines_done = 0; - PIC_AddEvent(VGA_DrawSingleLine,(float)(vga.draw.delay.htotal/4.0 + draw_skip)); + if (vga.draw.mode==EGALINE) + PIC_AddEvent(VGA_DrawEGASingleLine,(float)(vga.draw.delay.htotal/4.0 + draw_skip)); + else PIC_AddEvent(VGA_DrawSingleLine,(float)(vga.draw.delay.htotal/4.0 + draw_skip)); break; - //case EGALINE: } } @@ -936,6 +968,10 @@ void VGA_SetupDrawing(Bitu /*val*/) { case MCH_PCJR: vga.draw.mode = LINE; break; + case MCH_EGA: + // Note: The Paradise SVGA uses the same panning mechanism as EGA + vga.draw.mode = EGALINE; + break; case MCH_VGA: if (svgaCard==SVGA_None) { vga.draw.mode = LINE; @@ -1031,13 +1067,13 @@ void VGA_SetupDrawing(Bitu /*val*/) { htotal*=2; } vga.draw.address_line_total=(vga.crtc.maximum_scan_line&0x1f)+1; - if(IS_VGA_ARCH && (svgaCard==SVGA_None) && (vga.mode==M_EGA || vga.mode==M_VGA)) { + if (IS_VGA_ARCH && (svgaCard==SVGA_None) && (vga.mode==M_EGA || vga.mode==M_VGA)) { // vgaonly; can't use with CGA because these use address_line for their // own purposes. // Set the low resolution modes to have as many lines as are scanned - // Quite a few demos change the max_scanline register at display time // to get SFX: Majic12 show, Magic circle, Copper, GBU, Party91 - if( vga.crtc.maximum_scan_line&0x80) vga.draw.address_line_total*=2; + if ( vga.crtc.maximum_scan_line&0x80) vga.draw.address_line_total*=2; vga.draw.double_scan=false; } else if (IS_VGA_ARCH) vga.draw.double_scan=(vga.crtc.maximum_scan_line&0x80)>0; @@ -1109,10 +1145,10 @@ void VGA_SetupDrawing(Bitu /*val*/) { // on blanking wrap to 0, the first line is not blanked // this is used by the S3 BIOS and other S3 drivers in some SVGA modes - if((vbend&0x7f)==1) vblank_skip = 0; + if ((vbend&0x7f)==1) vblank_skip = 0; // it might also cut some lines off the bottom - if(vbstart < vdend) { + if (vbstart < vdend) { vdend = vbstart; } LOG(LOG_VGA,LOG_WARN)("Blanking wrap to line %d", vblank_skip); @@ -1121,7 +1157,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { vblank_skip = vbend; LOG(LOG_VGA,LOG_WARN)("Upper %d lines of the screen blanked", vblank_skip); } else if (vbstart < vdend) { - if(vbend < vdend) { + if (vbend < vdend) { // the game wants a black bar somewhere on the screen LOG(LOG_VGA,LOG_WARN)("Unsupported blanking: line %d-%d",vbstart,vbend); } else { @@ -1220,7 +1256,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { case M_LIN8: if (vga.crtc.mode_control & 0x8) width >>=1; - else if(svgaCard == SVGA_S3Trio && !(vga.s3.reg_3a&0x10)) { + else if (svgaCard == SVGA_S3Trio && !(vga.s3.reg_3a&0x10)) { doublewidth=true; width >>=1; } @@ -1254,6 +1290,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { vga.draw.blocks = width; width<<=3; if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) { + // This would also be required for EGA in Spacepigs Megademo bpp=16; VGA_DrawLine = VGA_Draw_Xlat16_Linear_Line; } else VGA_DrawLine=VGA_Draw_Linear_Line; @@ -1285,7 +1322,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { doublewidth=(vga.seq.clocking_mode & 0x8) > 0; if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) { // vgaonly: allow 9-pixel wide fonts - if(vga.seq.clocking_mode&0x01) { + if (vga.seq.clocking_mode&0x01) { vga.draw.char9dot = false; width*=8; } else { @@ -1376,7 +1413,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { } vga.draw.vblank_skip = vblank_skip; - if(!(IS_VGA_ARCH && (svgaCard==SVGA_None) && (vga.mode==M_EGA || vga.mode==M_VGA))) { + if (!(IS_VGA_ARCH && (svgaCard==SVGA_None) && (vga.mode==M_EGA || vga.mode==M_VGA))) { //Only check for extra double height in vga modes //(line multiplying by address_line_total) if (!doubleheight && (vga.mode Date: Thu, 22 Jul 2010 12:36:27 +0000 Subject: [PATCH 3532/4131] Fix some wrong line endings that sneaked it Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3622 --- src/hardware/vga_draw.cpp | 44 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index d7bc789f..55b8c484 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -444,10 +444,10 @@ static Bit8u* VGA_TEXT_Draw_Line(Bitu vidstart, Bitu line) { // keep it aligned: Bit8u* draw = ((Bit8u*)TempLine) + 16 - vga.draw.panning; const Bit8u* vidmem = VGA_Text_Memwrap(vidstart); // pointer to chars+attribs - Bitu blocks = vga.draw.blocks; - if (vga.draw.panning) blocks++; // if the text is panned part of an - // additional character becomes visible - while (blocks--) { // for each character in the line + Bitu blocks = vga.draw.blocks; + if (vga.draw.panning) blocks++; // if the text is panned part of an + // additional character becomes visible + while (blocks--) { // for each character in the line Bitu chr = *vidmem++; Bitu attr = *vidmem++; // the font pattern @@ -485,16 +485,16 @@ static Bit8u* VGA_TEXT_Draw_Line(Bitu vidstart, Bitu line) { // the adress of the attribute that makes up the cell the cursor is in Bits attr_addr = (vga.draw.cursor.address-vidstart) >> 1; if (attr_addr >= 0 && attr_addr < (Bits)vga.draw.blocks) { - Bitu index = attr_addr * (vga.draw.char9dot? 9:8); - draw = (Bit8u*)(&TempLine[index]) + 16 - vga.draw.panning; - - Bitu foreground = vga.tandy.draw_base[vga.draw.cursor.address+1] & 0xf; + Bitu index = attr_addr * (vga.draw.char9dot? 9:8); + draw = (Bit8u*)(&TempLine[index]) + 16 - vga.draw.panning; + + Bitu foreground = vga.tandy.draw_base[vga.draw.cursor.address+1] & 0xf; for (Bitu i = 0; i < 8; i++) { *draw++ = foreground; } } } - return TempLine+16; + return TempLine+16; } */ // combined 8/9-dot wide text mode 16bpp line drawing function @@ -502,10 +502,10 @@ static Bit8u* VGA_TEXT_Xlat16_Draw_Line(Bitu vidstart, Bitu line) { // keep it aligned: Bit16u* draw = ((Bit16u*)TempLine) + 16 - vga.draw.panning; const Bit8u* vidmem = VGA_Text_Memwrap(vidstart); // pointer to chars+attribs - Bitu blocks = vga.draw.blocks; - if (vga.draw.panning) blocks++; // if the text is panned part of an - // additional character becomes visible - while (blocks--) { // for each character in the line + Bitu blocks = vga.draw.blocks; + if (vga.draw.panning) blocks++; // if the text is panned part of an + // additional character becomes visible + while (blocks--) { // for each character in the line Bitu chr = *vidmem++; Bitu attr = *vidmem++; // the font pattern @@ -543,16 +543,16 @@ static Bit8u* VGA_TEXT_Xlat16_Draw_Line(Bitu vidstart, Bitu line) { // the adress of the attribute that makes up the cell the cursor is in Bits attr_addr = (vga.draw.cursor.address-vidstart) >> 1; if (attr_addr >= 0 && attr_addr < (Bits)vga.draw.blocks) { - Bitu index = attr_addr * (vga.draw.char9dot? 18:16); - draw = (Bit16u*)(&TempLine[index]) + 16 - vga.draw.panning; - - Bitu foreground = vga.tandy.draw_base[vga.draw.cursor.address+1] & 0xf; + Bitu index = attr_addr * (vga.draw.char9dot? 18:16); + draw = (Bit16u*)(&TempLine[index]) + 16 - vga.draw.panning; + + Bitu foreground = vga.tandy.draw_base[vga.draw.cursor.address+1] & 0xf; for (Bitu i = 0; i < 8; i++) { *draw++ = vga.dac.xlat16[foreground]; } } } - return TempLine+32; + return TempLine+32; } #ifdef VGA_KEEP_CHANGES @@ -576,10 +576,10 @@ static INLINE void VGA_ChangesEnd(void ) { static void VGA_ProcessSplit() { if (vga.attr.mode_control&0x20) { vga.draw.address=0; - // reset panning to 0 here so we don't have to check for - // it in the character draw functions. It will be set back - // to its proper value in v-retrace - vga.draw.panning=0; + // reset panning to 0 here so we don't have to check for + // it in the character draw functions. It will be set back + // to its proper value in v-retrace + vga.draw.panning=0; } else { // In text mode only the characters are shifted by panning, not the address; // this is done in the text line draw function. From 72bf840408bcd5adbe73427a66b3155a511ff8e7 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Thu, 22 Jul 2010 13:30:14 +0000 Subject: [PATCH 3533/4131] More line endings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3623 --- src/hardware/vga_attr.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index e6e5ef69..e8b89604 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -93,13 +93,13 @@ void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) { if (difference & 0x04) { // recompute the panning value - if(vga.mode==M_TEXT) { - Bit8u pan_reg = attr(horizontal_pel_panning); + if(vga.mode==M_TEXT) { + Bit8u pan_reg = attr(horizontal_pel_panning); if (pan_reg > 7) vga.config.pel_panning=0; - else if (val&0x4) // 9-dot wide characters - vga.config.pel_panning=(Bit8u)(pan_reg+1); - else // 8-dot characters + else if (val&0x4) // 9-dot wide characters + vga.config.pel_panning=(Bit8u)(pan_reg+1); + else // 8-dot characters vga.config.pel_panning=(Bit8u)pan_reg; } } @@ -144,10 +144,10 @@ void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) { case M_TEXT: if (val > 7) vga.config.pel_panning=0; - else if (vga.attr.mode_control&0x4) // 9-dot wide characters - vga.config.pel_panning=(Bit8u)(val+1); - else // 8-dot characters - vga.config.pel_panning=(Bit8u)val; + else if (vga.attr.mode_control&0x4) // 9-dot wide characters + vga.config.pel_panning=(Bit8u)(val+1); + else // 8-dot characters + vga.config.pel_panning=(Bit8u)val; break; case M_VGA: case M_LIN8: From 0af0da678c90112b76fb814911a9a62fe35e9877 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 24 Jul 2010 21:18:11 +0000 Subject: [PATCH 3534/4131] Flush the buffer of handles for the same file. (Betrayal in Antara). Thanks ripsaw Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3624 --- src/dos/drive_local.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index f92e666f..1af3ddc9 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -41,6 +41,7 @@ public: Bit16u GetInformation(void); bool UpdateDateTimeFromHost(void); void FlagReadOnlyMedium(void); + void Flush(void); private: FILE * fhandle; bool read_only_medium; @@ -95,6 +96,22 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { CROSS_FILENAME(newname); dirCache.ExpandName(newname); + //Flush the buffer of handles for the same file. (Betrayal in Antara) + Bit8u i,drive=DOS_DRIVES; + localFile *lfp; + for (i=0;iIsOpen() && Files[i]->GetDrive()==drive && Files[i]->IsName(name)) { + lfp=dynamic_cast(Files[i]); + if (lfp) lfp->Flush(); + } + } + FILE * hand=fopen(newname,type); // Bit32u err=errno; if (!hand) { @@ -541,6 +558,13 @@ bool localFile::UpdateDateTimeFromHost(void) { return true; } +void localFile::Flush(void) { + if (last_action==WRITE) { + fseek(fhandle,ftell(fhandle),SEEK_SET); + last_action=NONE; + } +} + // ******************************************** // CDROM DRIVE From 8d916cfa5a945058370c55042c3554ec1fc72cb7 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Wed, 28 Jul 2010 20:18:04 +0000 Subject: [PATCH 3535/4131] - Fix SB16 16-bit interrupt cause identification (makes games using CT-VOICE.DRV work). - Add SB16 identification bit for an older version of CT-VOICE.DRV Thanks ripsaw8080. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3625 --- src/hardware/sblaster.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index e0427e94..8dbd4799 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -504,6 +504,8 @@ static void GenerateDMASound(Bitu size) { sb.dma.left-=read; if (!sb.dma.left) { PIC_RemoveEvents(END_DMA_Event); + if (sb.dma.mode >= DSP_DMA_16) SB_RaiseIRQ(SB_IRQ_16); + else SB_RaiseIRQ(SB_IRQ_8); if (!sb.dma.autoinit) { LOG(LOG_SB,LOG_NORMAL)("Single cycle transfer ended"); sb.mode=MODE_NONE; @@ -515,8 +517,6 @@ static void GenerateDMASound(Bitu size) { sb.mode=MODE_NONE; } } - if (sb.dma.mode >= DSP_DMA_16) SB_RaiseIRQ(SB_IRQ_16); - else SB_RaiseIRQ(SB_IRQ_8); } } @@ -1345,7 +1345,8 @@ static Bit8u CTMIXER_Read(void) { return ret; case 0x82: /* IRQ Status */ return (sb.irq.pending_8bit ? 0x1 : 0) | - (sb.irq.pending_16bit ? 0x2 : 0); + (sb.irq.pending_16bit ? 0x2 : 0) | + ((sb.type == SBT_16) ? 0x20 : 0); default: if ( ((sb.type == SBT_PRO1 || sb.type == SBT_PRO2) && sb.mixer.index==0x0c) || /* Input control on SBPro */ (sb.type == SBT_16 && sb.mixer.index >= 0x3b && sb.mixer.index <= 0x47)) /* New SB16 registers */ From dc0732f09f7600b45c1a00cc392aa7726a4ab7dc Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Wed, 28 Jul 2010 20:56:12 +0000 Subject: [PATCH 3536/4131] Tandy: Add 16kb of DOS memory. Fixes bad graphics in Mickey's Space Adventure and Chuck Yeager's Air Combat, as well as flickering screens in Ghostbusters. Patch by ripsaw8080 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3626 --- src/dos/dos_memory.cpp | 2 +- src/ints/bios.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 7bdd514d..e4c3627f 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -436,7 +436,7 @@ void DOS_SetupMemory(void) { if (machine==MCH_TANDY) { /* memory up to 608k available, the rest (to 640k) is used by the tandy graphics system's variable mapping of 0xb800 */ - mcb.SetSize(0x97FF - DOS_MEM_START - mcb_sizes); + mcb.SetSize(0x9BFF - DOS_MEM_START - mcb_sizes); } else if (machine==MCH_PCJR) { /* memory from 128k to 640k is available */ mcb_devicedummy.SetPt((Bit16u)0x2000); diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index a61bfe5d..d1e6233b 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -869,7 +869,7 @@ public: if (IS_TANDY_ARCH) { /* reduce reported memory size for the Tandy (32k graphics memory at the end of the conventional 640k) */ - if (machine==MCH_TANDY) mem_writew(BIOS_MEMORY_SIZE,608); + if (machine==MCH_TANDY) mem_writew(BIOS_MEMORY_SIZE,624); else mem_writew(BIOS_MEMORY_SIZE,640); mem_writew(BIOS_TRUE_MEMORY_SIZE,640); } else mem_writew(BIOS_MEMORY_SIZE,640); From 58e87f97177d5b4c08f5dba2a63afa9d6c31b76f Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Wed, 28 Jul 2010 21:58:44 +0000 Subject: [PATCH 3537/4131] Update the rendering output even when only the refresh rate changed. Previously there might have been problems with video recording under some rare circumstances. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3627 --- src/hardware/vga_draw.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 55b8c484..c5330421 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1438,8 +1438,10 @@ void VGA_SetupDrawing(Bitu /*val*/) { } // LOG_MSG("ht %d vt %d ratio %f", htotal, vtotal, aspect_ratio ); + bool fps_changed = false; // need to change the vertical timing? if (fabs(vga.draw.delay.vtotal - 1000.0 / fps) > 0.0001) { + fps_changed = true; vga.draw.delay.vtotal = 1000.0 / fps; VGA_KillDrawing(); PIC_RemoveEvents(VGA_Other_VertInterrupt); @@ -1466,7 +1468,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { (vga.draw.doublewidth != doublewidth) || (vga.draw.doubleheight != doubleheight) || (fabs(aspect_ratio - vga.draw.aspect_ratio) > 0.0001) || - (vga.draw.bpp != bpp)) { + (vga.draw.bpp != bpp) || fps_changed) { VGA_KillDrawing(); From 901e771bfaae33f62d76242f9585348b714daa3b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 7 Aug 2010 18:12:48 +0000 Subject: [PATCH 3538/4131] Add patch 3027944 from ripsaw: Subst /d Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3628 --- src/shell/shell.cpp | 2 +- src/shell/shell_cmds.cpp | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 8f379b2f..8ca34996 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -487,7 +487,7 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_PAUSE_HELP","Waits for 1 keystroke to continue.\n"); MSG_Add("SHELL_CMD_COPY_FAILURE","Copy failure : %s.\n"); MSG_Add("SHELL_CMD_COPY_SUCCESS"," %d File(s) copied.\n"); - MSG_Add("SHELL_CMD_SUBST_NO_REMOVE","Removing drive not supported. Doing nothing.\n"); + MSG_Add("SHELL_CMD_SUBST_NO_REMOVE","Unable to remove, drive not in use.\n"); MSG_Add("SHELL_CMD_SUBST_FAILURE","SUBST failed. You either made an error in your commandline or the target drive is already used.\nIt's only possible to use SUBST on Local drives"); MSG_Add("SHELL_STARTUP_BEGIN", diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 49ff8277..8a0a9c08 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -945,17 +945,22 @@ void DOS_Shell::CMD_SUBST (char * args) { CommandLine command(0,args); if (command.GetCount() != 2) throw 0 ; - command.FindCommand(2,arg); - if((arg=="/D" ) || (arg=="/d")) throw 1; //No removal (one day) command.FindCommand(1,arg); if( (arg.size()>1) && arg[1] !=':') throw(0); temp_str[0]=(char)toupper(args[0]); + command.FindCommand(2,arg); + if((arg=="/D") || (arg=="/d")) { + if(!Drives[temp_str[0]-'A'] ) throw 1; //targetdrive not in use + strcat(mountstring,"-u "); + strcat(mountstring,temp_str); + this->ParseLine(mountstring); + return; + } if(Drives[temp_str[0]-'A'] ) throw 0; //targetdrive in use strcat(mountstring,temp_str); strcat(mountstring," "); - command.FindCommand(2,arg); Bit8u drive;char fulldir[DOS_PATHLENGTH]; if (!DOS_MakeName(const_cast(arg.c_str()),fulldir,&drive)) throw 0; From 8f4d5fce901e4df60a336db0f2f63ab82af3e829 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 7 Aug 2010 18:15:36 +0000 Subject: [PATCH 3539/4131] Improve image shuffling when adding a drive which doesn't end up at the last place, but at the first place. (thanks ripsaw). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3629 --- src/dos/dos_mscdex.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 65ab123c..5800fd1f 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -368,23 +368,27 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) devHeader.SetInterrupt(off+5); } - subUnit = (Bit8u)numDrives; // Set drive DOS_DeviceHeader devHeader(PhysMake(rootDriverHeaderSeg,0)); devHeader.SetNumSubUnits(devHeader.GetNumSubUnits()+1); if (dinfo[0].drive-1==_drive) { CDROM_Interface *_cdrom = cdrom[numDrives]; + CDROM_Interface_Image *_cdimg = CDROM_Interface_Image::images[numDrives]; for (Bit16u i=GetNumDrives(); i>0; i--) { dinfo[i] = dinfo[i-1]; cdrom[i] = cdrom[i-1]; + CDROM_Interface_Image::images[i] = CDROM_Interface_Image::images[i-1]; } cdrom[0] = _cdrom; + CDROM_Interface_Image::images[0] = _cdimg; dinfo[0].drive = (Bit8u)_drive; dinfo[0].physDrive = (Bit8u)toupper(physicalPath[0]); + subUnit = 0; } else { dinfo[numDrives].drive = (Bit8u)_drive; dinfo[numDrives].physDrive = (Bit8u)toupper(physicalPath[0]); + subUnit = (Bit8u)numDrives; } numDrives++; // stop audio From 0438430b24b5ca9959f976e58a360ef79b26e4df Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 7 Aug 2010 18:25:24 +0000 Subject: [PATCH 3540/4131] Add patch 3011706 by bredbored: remove double weirdness with free and dirsearch being 0. More sensible clearing of the directory cache. Fixes skynet crashes related to corrupted drive cache. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3630 --- include/dos_system.h | 7 +++-- src/dos/drive_cache.cpp | 67 ++++++++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 16 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 5edb0487..eab510e7 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -156,8 +156,9 @@ public: public: CFileInfo(void) { orgname[0] = shortname[0] = 0; - nextEntry = shortNr = 0; isDir = false; + id = MAX_OPENDIRS; + nextEntry = shortNr = 0; } ~CFileInfo(void) { for (Bit32u i=0; iid != MAX_OPENDIRS) + return dir->id; + for (Bit16u i=0; iid = i; + return i; + } + } LOG(LOG_FILES,LOG_NORMAL)("DIRCACHE: Too many open directories!"); + dir->id=0; return 0; } @@ -262,7 +269,7 @@ void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) { // delete file objects... for(Bit32u i=0; ifileList.size(); i++) { if (dirSearch[srchNr]==dir->fileList[i]) dirSearch[srchNr] = 0; - delete dir->fileList[i]; dir->fileList[i] = 0; + DeleteFileInfo(dir->fileList[i]); dir->fileList[i] = 0; } // clear lists dir->fileList.clear(); @@ -524,7 +531,10 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* strcpy(buffer,dirPath); ReadDir(id,result); strcpy(dirPath,buffer); - free[id] = true; + if (dirSearch[id]) { + dirSearch[id]->id = MAX_OPENDIRS; + dirSearch[id] = 0; + } }; }; @@ -554,7 +564,10 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* strcpy(buffer,dirPath); ReadDir(id,result); strcpy(dirPath,buffer); - free[id] = true; + if (dirSearch[id]) { + dirSearch[id]->id = MAX_OPENDIRS; + dirSearch[id] = 0; + } }; } }; @@ -598,9 +611,12 @@ bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, const char* expand, Bit16u& id) { // Reset it.. close_directory(dirp); strcpy(dirPath,expandcopy); - free[id] = false; return true; } + if (dirSearch[id]) { + dirSearch[id]->id = MAX_OPENDIRS; + dirSearch[id] = 0; + } }; return false; } @@ -659,7 +675,10 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) { // Try to open directory dir_information* dirp = open_directory(dirPath); if (!dirp) { - free[id] = true; + if (dirSearch[id]) { + dirSearch[id]->id = MAX_OPENDIRS; + dirSearch[id] = 0; + } return false; } // Read complete directory @@ -686,7 +705,10 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) { };*/ }; if (SetResult(dirSearch[id], result, dirSearch[id]->nextEntry)) return true; - free[id] = true; + if (dirSearch[id]) { + dirSearch[id]->id = MAX_OPENDIRS; + dirSearch[id] = 0; + } return false; } @@ -730,7 +752,7 @@ bool DOS_Drive_Cache::FindFirst(char* path, Bit16u& id) { this->nextFreeFindFirst = 1; //the next free one after this search for(Bitu n=0; nnextEntry)) { // free slot - delete dirFindFirst[id]; dirFindFirst[id] = 0; + DeleteFileInfo(dirFindFirst[id]); dirFindFirst[id] = 0; return false; } return true; } + +void DOS_Drive_Cache::ClearFileInfo(CFileInfo *dir) { + for(Bit32u i=0; ifileList.size(); i++) { + if (CFileInfo *info = dir->fileList[i]) + ClearFileInfo(info); + } + if (dir->id != MAX_OPENDIRS) { + dirSearch[dir->id] = 0; + dir->id = MAX_OPENDIRS; + } +} + +void DOS_Drive_Cache::DeleteFileInfo(CFileInfo *dir) { + if (dir) + ClearFileInfo(dir); + delete dir; +} From 8c29440d3946950ad426c5a06a42cbf76bef576f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 7 Aug 2010 18:32:39 +0000 Subject: [PATCH 3541/4131] Add audio volume control for mscdex. Implemented it in images and win32ioctl. Others are still open. Thanks ripsaw. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3631 --- src/dos/cdrom.h | 15 ++++++++++++ src/dos/cdrom_image.cpp | 18 +++++++++++++- src/dos/cdrom_ioctl_win32.cpp | 18 +++++++++++++- src/dos/dos_mscdex.cpp | 44 +++++++++++++++++++++++++++++++++-- 4 files changed, 91 insertions(+), 4 deletions(-) diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index 241839be..6242bc42 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -31,6 +31,11 @@ typedef struct SMSF { unsigned char fr; } TMSF; +typedef struct SCtrl { + Bit8u out[4]; // output channel + Bit8u vol[4]; // channel volume +} TCtrl; + extern int CDROM_GetMountType(char* path, int force); class CDROM_Interface @@ -52,6 +57,7 @@ public: virtual bool PlayAudioSector (unsigned long start,unsigned long len) = 0; virtual bool PauseAudio (bool resume) = 0; virtual bool StopAudio (void) = 0; + virtual void ChannelControl (TCtrl ctrl) = 0; virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0; @@ -76,6 +82,7 @@ public: virtual bool PlayAudioSector (unsigned long start,unsigned long len); virtual bool PauseAudio (bool resume); virtual bool StopAudio (void); + virtual void ChannelControl (TCtrl ctrl) { return; }; virtual bool ReadSectors (PhysPt /*buffer*/, bool /*raw*/, unsigned long /*sector*/, unsigned long /*num*/) { return false; }; virtual bool LoadUnloadMedia (bool unload); @@ -101,6 +108,7 @@ public: bool PlayAudioSector (unsigned long /*start*/,unsigned long /*len*/) { return true; }; bool PauseAudio (bool /*resume*/) { return true; }; bool StopAudio (void) { return true; }; + void ChannelControl (TCtrl ctrl) { return; }; bool ReadSectors (PhysPt /*buffer*/, bool /*raw*/, unsigned long /*sector*/, unsigned long /*num*/) { return true; }; bool LoadUnloadMedia (bool /*unload*/) { return true; }; }; @@ -166,6 +174,7 @@ public: bool PlayAudioSector (unsigned long start,unsigned long len); bool PauseAudio (bool resume); bool StopAudio (void); + void ChannelControl (TCtrl ctrl); bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); bool LoadUnloadMedia (bool unload); bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector); @@ -188,6 +197,8 @@ static struct imagePlayer { int targetFrame; bool isPlaying; bool isPaused; + bool ctrlUsed; + TCtrl ctrlData; } player; void ClearTracks(); @@ -234,6 +245,7 @@ public: bool PlayAudioSector (unsigned long start,unsigned long len); bool PauseAudio (bool resume); bool StopAudio (void); + void ChannelControl (TCtrl ctrl) { return; }; bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); @@ -284,6 +296,7 @@ public: bool PlayAudioSector (unsigned long start,unsigned long len); bool PauseAudio (bool resume); bool StopAudio (void); + void ChannelControl (TCtrl ctrl); bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector); bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); @@ -338,6 +351,8 @@ private: int targetFrame; bool isPlaying; bool isPaused; + bool ctrlUsed; + TCtrl ctrlData; } player; }; diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index d7bcfa66..26375c9a 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -131,7 +131,7 @@ int CDROM_Interface_Image::AudioFile::getLength() int CDROM_Interface_Image::refCount = 0; CDROM_Interface_Image* CDROM_Interface_Image::images[26]; CDROM_Interface_Image::imagePlayer CDROM_Interface_Image::player = { - NULL, NULL, NULL, {0}, 0, 0, 0, false, false }; + NULL, NULL, NULL, {0}, 0, 0, 0, false, false, false, {0} }; CDROM_Interface_Image::CDROM_Interface_Image(Bit8u subUnit) @@ -259,6 +259,12 @@ bool CDROM_Interface_Image::StopAudio(void) return true; } +void CDROM_Interface_Image::ChannelControl(TCtrl ctrl) +{ + player.ctrlUsed = (ctrl.out[0]!=0 || ctrl.out[1]!=1 || ctrl.vol[0]<0xfe || ctrl.vol[1]<0xfe); + player.ctrlData = ctrl; +} + bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) { int sectorSize = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; @@ -336,6 +342,16 @@ void CDROM_Interface_Image::CDAudioCallBack(Bitu len) } } SDL_mutexV(player.mutex); + if (player.ctrlUsed) { + Bit16s sample0,sample1; + Bit16s * samples=(Bit16s *)&player.buffer; + for (Bitu pos=0;posAddSamples_s16_nonnative(len/4,(Bit16s *)player.buffer); #else diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index 9044e543..c12f7526 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -175,7 +175,7 @@ bool CDROM_Interface_Ioctl::mci_CDPosition(int *position) { CDROM_Interface_Ioctl::dxPlayer CDROM_Interface_Ioctl::player = { - NULL, NULL, NULL, 0, 0, 0, 0, 0, false, false }; + NULL, NULL, NULL, {0}, 0, 0, 0, false, false, false, {0} }; CDROM_Interface_Ioctl::CDROM_Interface_Ioctl(cdioctl_cdatype ioctl_cda) { pathname[0] = 0; @@ -462,6 +462,12 @@ bool CDROM_Interface_Ioctl::StopAudio(void) { return bStat>0; } +void CDROM_Interface_Ioctl::ChannelControl(TCtrl ctrl) +{ + player.ctrlUsed = (ctrl.out[0]!=0 || ctrl.out[1]!=1 || ctrl.vol[0]<0xfe || ctrl.vol[1]<0xfe); + player.ctrlData = ctrl; +} + bool CDROM_Interface_Ioctl::LoadUnloadMedia(bool unload) { BOOL bStat; DWORD byteCount; @@ -553,6 +559,16 @@ void CDROM_Interface_Ioctl::dx_CDAudioCallBack(Bitu len) { } } SDL_mutexV(player.mutex); + if (player.ctrlUsed) { + Bit16s sample0,sample1; + Bit16s * samples=(Bit16s *)&player.buffer; + for (Bitu pos=0;posAddSamples_s16(len/4,(Bit16s *)player.buffer); memmove(player.buffer, &player.buffer[len], player.bufLen - len); player.bufLen -= len; diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 5800fd1f..b0f011f6 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -152,6 +152,7 @@ private: bool locked; // drive locked ? bool lastResult; // last operation success ? Bit32u volumeSize; // for media change + TCtrl audioCtrl; // audio channel control } TDriveInfo; Bit16u defaultBufSeg; @@ -160,6 +161,9 @@ private: public: Bit16u rootDriverHeaderSeg; + + bool ChannelControl (Bit8u subUnit, TCtrl ctrl); + bool GetChannelControl (Bit8u subUnit, TCtrl& ctrl); }; CMscdex::CMscdex(void) { @@ -391,6 +395,11 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) subUnit = (Bit8u)numDrives; } numDrives++; + // init channel control + for (Bit8u chan=0;chan<4;chan++) { + dinfo[subUnit].audioCtrl.out[chan]=chan; + dinfo[subUnit].audioCtrl.vol[chan]=0xff; + } // stop audio StopAudio(subUnit); return result; @@ -463,7 +472,7 @@ bool CMscdex::PlayAudioSector(Bit8u subUnit, Bit32u sector, Bit32u length) if (subUnit>=numDrives) return false; // If value from last stop is used, this is meant as a resume // better start using resume command - if (dinfo[subUnit].audioPaused && (sector==dinfo[subUnit].audioStart)) { + if (dinfo[subUnit].audioPaused && (sector==dinfo[subUnit].audioStart) && (dinfo[subUnit].audioEnd!=0)) { dinfo[subUnit].lastResult = cdrom[subUnit]->PauseAudio(true); } else dinfo[subUnit].lastResult = cdrom[subUnit]->PlayAudioSector(sector,length); @@ -800,6 +809,7 @@ Bit32u CMscdex::GetDeviceStatus(Bit8u subUnit) (dinfo[subUnit].locked << 1) | // Drive is locked ? (1<<2) | // raw + cooked sectors (1<<4) | // Can read sudio + (1<<8) | // Can control audio (1<<9) | // Red book & HSG ((!media) << 11); // Drive is empty ? return status; @@ -864,6 +874,22 @@ void CMscdex::InitNewMedia(Bit8u subUnit) { } } +bool CMscdex::ChannelControl(Bit8u subUnit, TCtrl ctrl) { + if (subUnit>=numDrives) return false; + // adjust strange channel mapping + if (ctrl.out[0]>1) ctrl.out[0]=0; + if (ctrl.out[1]>1) ctrl.out[1]=1; + dinfo[subUnit].audioCtrl=ctrl; + cdrom[subUnit]->ChannelControl(ctrl); + return true; +} + +bool CMscdex::GetChannelControl(Bit8u subUnit, TCtrl& ctrl) { + if (subUnit>=numDrives) return false; + ctrl=dinfo[subUnit].audioCtrl; + return true; +} + static CMscdex* mscdex = 0; static PhysPt curReqheaderPtr = 0; @@ -893,6 +919,14 @@ static Bit16u MSCDEX_IOCTL_Input(PhysPt buffer,Bit8u drive_unit) { return 0x03; // invalid function } }break; + case 0x04 : /* Audio Channel control */ + TCtrl ctrl; + if (!mscdex->GetChannelControl(drive_unit,ctrl)) return 0x01; + for (Bit8u chan=0;chan<4;chan++) { + mem_writeb(buffer+chan*2+1,ctrl.out[chan]); + mem_writeb(buffer+chan*2+2,ctrl.vol[chan]); + } + break; case 0x06 : /* Get Device status */ mem_writed(buffer+1,mscdex->GetDeviceStatus(drive_unit)); break; @@ -984,7 +1018,13 @@ static Bit16u MSCDEX_IOCTL_Optput(PhysPt buffer,Bit8u drive_unit) { if (!mscdex->LoadUnloadMedia(drive_unit,true)) return 0x02; break; case 0x03: //Audio Channel control - MSCDEX_LOG("MSCDEX: Audio Channel Control used. Not handled. Faking succes!"); + TCtrl ctrl; + for (Bit8u chan=0;chan<4;chan++) { + ctrl.out[chan]=mem_readb(buffer+chan*2+1); + ctrl.vol[chan]=mem_readb(buffer+chan*2+2); + } + if (!mscdex->ChannelControl(drive_unit,ctrl)) return 0x01; + break; case 0x01 : // (un)Lock door // do nothing -> report as success break; From c77c12be155d2c3ad1a30f900939b08f940fd0ff Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 7 Aug 2010 18:36:17 +0000 Subject: [PATCH 3542/4131] Make it clear to people that they don't use a stable version. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3632 --- configure.in | 2 +- src/platform/visualc/config.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 016ea95f..3e2a8782 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Init. -AC_INIT(dosbox,0.74) +AC_INIT(dosbox,SVN) AC_PREREQ(2.50) AC_CONFIG_SRCDIR(README) diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index 7d9eecbc..fffd256e 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -1,4 +1,4 @@ -#define VERSION "0.74" +#define VERSION "SVN" /* Define to 1 to enable internal debugger, requires libcurses */ #define C_DEBUG 0 From a4087818091576067652428e4a85878db4b40a78 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 7 Aug 2010 18:39:22 +0000 Subject: [PATCH 3543/4131] Hide associated files. Fixes Last Express when installing from an ISO. Thanks ripsaw Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3633 --- src/dos/drive_iso.cpp | 4 ++-- src/dos/drives.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 5150850b..6be88895 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -289,7 +289,7 @@ bool isoDrive::FindNext(DOS_DTA &dta) { else findAttr |= DOS_ATTR_ARCHIVE; if (IS_HIDDEN(de.fileFlags)) findAttr |= DOS_ATTR_HIDDEN; - if (!(isRoot && de.ident[0]=='.') && WildFileCmp((char*)de.ident, pattern) + if (!IS_ASSOC(de.fileFlags) && !(isRoot && de.ident[0]=='.') && WildFileCmp((char*)de.ident, pattern) && !(~attr & findAttr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM))) { /* file is okay, setup everything to be copied in DTA Block */ @@ -541,7 +541,7 @@ bool isoDrive :: lookup(isoDirEntry *de, const char *path) { // look for the current path element int dirIterator = GetDirIterator(de); while (!found && GetNextDirEntry(dirIterator, de)) { - if (0 == strncasecmp((char*) de->ident, name, ISO_MAX_FILENAME_LENGTH)) { + if (!IS_ASSOC(de->fileFlags) && (0 == strncasecmp((char*) de->ident, name, ISO_MAX_FILENAME_LENGTH))) { found = true; } } diff --git a/src/dos/drives.h b/src/dos/drives.h index aa629fc5..431f3f18 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -298,11 +298,13 @@ struct isoDirEntry { #endif #define ISO_FRAMESIZE 2048 +#define ISO_ASSOCIATED 4 #define ISO_DIRECTORY 2 #define ISO_HIDDEN 1 #define ISO_MAX_FILENAME_LENGTH 37 #define ISO_MAXPATHNAME 256 #define ISO_FIRST_VD 16 +#define IS_ASSOC(fileFlags) (fileFlags & ISO_ASSOCIATED) #define IS_DIR(fileFlags) (fileFlags & ISO_DIRECTORY) #define IS_HIDDEN(fileFlags) (fileFlags & ISO_HIDDEN) #define ISO_MAX_HASH_TABLE_SIZE 100 From e7b2ddbedf7d872404db419fc151e7fcc6c23981 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 7 Aug 2010 18:46:48 +0000 Subject: [PATCH 3544/4131] Fix long standing weirdness with LBA: Copying of speech files failed. Don't cut off the next level if we stay in the same (large) directory. Thanks ripsaw Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3634 --- src/dos/dos_mscdex.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index b0f011f6..94239878 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -678,6 +678,7 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph char entryName[256]; bool foundComplete = false; bool foundName; + bool nextPart = true; char* useName = 0; Bitu entryLength,nameLength; // clear error @@ -708,14 +709,15 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph if (!ReadSectors(GetSubUnit(drive),false,dirEntrySector,1,defBuffer)) return false; // Get string part foundName = false; - if (searchPos) { - useName = searchPos; - searchPos = strchr(searchPos,'\\'); + if (nextPart) { + if (searchPos) { + useName = searchPos; + searchPos = strchr(searchPos,'\\'); + } + if (searchPos) { *searchPos = 0; searchPos++; } + else foundComplete = true; } - if (searchPos) { *searchPos = 0; searchPos++; } - else foundComplete = true; - do { entryLength = mem_readb(defBuffer+index); if (entryLength==0) break; @@ -772,10 +774,12 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph // change directory dirEntrySector = mem_readd(defBuffer+index+2); dirSize = mem_readd(defBuffer+index+10); + nextPart = true; } else { // continue search in next sector dirSize -= 2048; dirEntrySector++; + nextPart = false; } }; error = 2; // file not found From b23456007547b6449ca2a5b09c827096cfcbcdbd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 7 Aug 2010 18:49:53 +0000 Subject: [PATCH 3545/4131] Only flush buffer if we are reading from the console. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3635 --- src/dos/dos.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 35eb73e9..a3ec0a70 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -227,10 +227,13 @@ static Bitu DOS_21Handler(void) { break; case 0x0c: /* Flush Buffer and read STDIN call */ { - /* flush STDIN-buffer */ - Bit8u c;Bit16u n; - while (DOS_GetSTDINStatus()) { - n=1; DOS_ReadFile(STDIN,&c,&n); + /* flush buffer if STDIN is CON */ + Bit8u handle=RealHandle(STDIN); + if (handle!=0xFF && Files[handle] && Files[handle]->IsName("CON")) { + Bit8u c;Bit16u n; + while (DOS_GetSTDINStatus()) { + n=1; DOS_ReadFile(STDIN,&c,&n); + } } switch (reg_al) { case 0x1: From da00ef32bb20963054191c60fc922b53b3160db7 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Thu, 12 Aug 2010 14:58:17 +0000 Subject: [PATCH 3546/4131] BIOS serial port interface: Do not misinterpret DCD as timeout. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3636 --- src/ints/bios.cpp | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index d1e6233b..1f1d20ba 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -434,18 +434,16 @@ static Bitu INT17_Handler(void) { return CBRET_NONE; } -static Bit8u INT14_Wait(Bit16u port, Bit8u mask, Bit8u timeout) { +static bool INT14_Wait(Bit16u port, Bit8u mask, Bit8u timeout, Bit8u* retval) { double starttime = PIC_FullIndex(); double timeout_f = timeout * 1000.0; - Bit8u retval; - while (((retval = IO_ReadB(port)) & mask) != mask) { + while (((*retval = IO_ReadB(port)) & mask) != mask) { if (starttime < (PIC_FullIndex() - timeout_f)) { - retval |= 0x80; - break; + return false; } CALLBACK_Idle(); } - return retval; + return true; } static Bitu INT14_Handler(void) { @@ -500,7 +498,7 @@ static Bitu INT14_Handler(void) { CALLBACK_SCF(false); break; } - case 0x01: { // Transmit character + case 0x01: // Transmit character // Parameters: Return: // AL: character AL: unchanged // AH: 0x01 AH: line status from just before the char was sent @@ -510,20 +508,19 @@ static Bitu INT14_Handler(void) { // set DTR & RTS on IO_WriteB(port+4,0x3); - // wait for DSR & CTS - reg_ah = INT14_Wait(port+6, 0x30, timeout); - if (!(reg_ah & 0x80)) { + if (INT14_Wait(port+6, 0x30, timeout, ®_ah)) { // wait for TX buffer empty - reg_ah = INT14_Wait(port+5, 0x20, timeout); - if (!(reg_ah & 0x80)) { + if (INT14_Wait(port+5, 0x20, timeout, ®_ah)) { // fianlly send the character IO_WriteB(port,reg_al); - } - } // else timed out + } else + reg_ah |= 0x80; + } else // timed out + reg_ah |= 0x80; + CALLBACK_SCF(false); break; - } case 0x02: // Read character // Parameters: Return: // AH: 0x02 AL: received character @@ -537,15 +534,16 @@ static Bitu INT14_Handler(void) { IO_WriteB(port+4,0x1); // wait for DSR - reg_ah = INT14_Wait(port+6, 0x20, timeout); - if (!(reg_ah & 0x80)) { + if (INT14_Wait(port+6, 0x20, timeout, ®_ah)) { // wait for character to arrive - reg_ah = INT14_Wait(port+5, 0x01, timeout); - if (!(reg_ah & 0x80)) { + if (INT14_Wait(port+5, 0x01, timeout, ®_ah)) { reg_ah &= 0x1E; reg_al = IO_ReadB(port); - } - } + } else + reg_ah |= 0x80; + } else + reg_ah |= 0x80; + CALLBACK_SCF(false); break; case 0x03: // get status From 65649abbba7d49b04720dd1e089cebcde5c303e5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 27 Aug 2010 12:52:46 +0000 Subject: [PATCH 3547/4131] Fix video capture problems. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3637 --- src/hardware/hardware.cpp | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 42570b2b..e739bef8 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: hardware.cpp,v 1.23 2009-10-11 18:09:22 qbix79 Exp $ */ +/* $Id: hardware.cpp,v 1.22 2009-04-26 18:24:36 qbix79 Exp $ */ #include #include @@ -161,13 +161,17 @@ static void CAPTURE_AddAviChunk(const char * tag, Bit32u size, void * data, Bit3 #endif #if (C_SSHOT) +static void CAPTURE_VideoEvent(bool pressed) { + if (!pressed) + return; + if (CaptureState & CAPTURE_VIDEO) { + /* Close the video */ + CaptureState &= ~CAPTURE_VIDEO; + LOG_MSG("Stopped capturing video."); -static void CAPTURE_VideoHeader() { Bit8u avi_header[AVI_HEADER_SIZE]; Bitu main_list; Bitu header_pos=0; - Bitu save_pos=ftell(capture.video.handle); - #define AVIOUT4(_S_) memcpy(&avi_header[header_pos],_S_,4);header_pos+=4; #define AVIOUTw(_S_) host_writew(&avi_header[header_pos], _S_);header_pos+=2; #define AVIOUTd(_S_) host_writed(&avi_header[header_pos], _S_);header_pos+=4; @@ -284,20 +288,6 @@ static void CAPTURE_VideoHeader() { fwrite( capture.video.index, 1, capture.video.indexused, capture.video.handle); fseek(capture.video.handle, 0, SEEK_SET); fwrite(&avi_header, 1, AVI_HEADER_SIZE, capture.video.handle); - fseek(capture.video.handle, save_pos, SEEK_SET); -} - -static void CAPTURE_VideoEvent(bool pressed) { - if (!pressed) - return; - if (CaptureState & CAPTURE_VIDEO) { - /* Close the video */ - CaptureState &= ~CAPTURE_VIDEO; - LOG_MSG("Stopped capturing video."); - - /* Adds AVI header to the file */ - CAPTURE_VideoHeader(); - fclose( capture.video.handle ); free( capture.video.index ); free( capture.video.buf ); @@ -557,9 +547,6 @@ skip_shot: capture.video.audioused = 0; } - /* Adds AVI header to the file */ - CAPTURE_VideoHeader(); - /* Everything went okay, set flag again for next frame */ CaptureState |= CAPTURE_VIDEO; } @@ -756,6 +743,9 @@ public: #endif } ~HARDWARE(){ +#if (C_SSHOT) + if (capture.video.handle) CAPTURE_VideoEvent(true); +#endif if (capture.wave.handle) CAPTURE_WaveEvent(true); if (capture.midi.handle) CAPTURE_MidiEvent(true); } From 5523df5679a37b53345e9b974d64c9800c5d67c9 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Thu, 9 Sep 2010 18:59:00 +0000 Subject: [PATCH 3548/4131] SF patch 2923483: INT10: Accept the page argument when loading font bitmaps. Thanks makovick. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3638 --- src/ints/int10.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index fed4a7d7..0e1da39f 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -208,11 +208,11 @@ static Bitu INT10_Handler(void) { break; case 0x01: /* Load 8x14 font */ case 0x11: - INT10_LoadFont(Real2Phys(int10.rom.font_14),reg_al==0x11,256,0,0,14); + INT10_LoadFont(Real2Phys(int10.rom.font_14),reg_al==0x11,256,0,reg_bl,14); break; case 0x02: /* Load 8x8 font */ case 0x12: - INT10_LoadFont(Real2Phys(int10.rom.font_8_first),reg_al==0x12,256,0,0,8); + INT10_LoadFont(Real2Phys(int10.rom.font_8_first),reg_al==0x12,256,0,reg_bl,8); break; case 0x03: /* Set Block Specifier */ IO_Write(0x3c4,0x3);IO_Write(0x3c5,reg_bl); @@ -220,7 +220,7 @@ static Bitu INT10_Handler(void) { case 0x04: /* Load 8x16 font */ case 0x14: if (!IS_VGA_ARCH) break; - INT10_LoadFont(Real2Phys(int10.rom.font_16),reg_al==0x14,256,0,0,16); + INT10_LoadFont(Real2Phys(int10.rom.font_16),reg_al==0x14,256,0,reg_bl,16); break; /* Graphics mode calls */ case 0x20: /* Set User 8x8 Graphics characters */ From 7bb29e185c330095fe5a4f742c371d569c6ce669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 25 Sep 2010 17:31:14 +0000 Subject: [PATCH 3549/4131] small VGA grayscale summing fix Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3639 --- src/ints/int10.cpp | 4 ++-- src/ints/int10.h | 4 ++-- src/ints/int10_pal.cpp | 44 ++++++++++++++++++++++++++++++++---------- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 0e1da39f..92c98e1f 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -162,7 +162,7 @@ static Bitu INT10_Handler(void) { INT10_GetAllPaletteRegisters(SegPhys(es)+reg_dx); break; case 0x10: /* SET INDIVIDUAL DAC REGISTER */ - INT10_SetSingleDacRegister(reg_bl,reg_dh,reg_ch,reg_cl); + INT10_SetSingleDACRegister(reg_bl,reg_dh,reg_ch,reg_cl); break; case 0x12: /* SET BLOCK OF DAC REGISTERS */ INT10_SetDACBlock(reg_bx,reg_cx,SegPhys(es)+reg_dx); @@ -171,7 +171,7 @@ static Bitu INT10_Handler(void) { INT10_SelectDACPage(reg_bl,reg_bh); break; case 0x15: /* GET INDIVIDUAL DAC REGISTER */ - INT10_GetSingleDacRegister(reg_bl,®_dh,®_ch,®_cl); + INT10_GetSingleDACRegister(reg_bl,®_dh,®_ch,®_cl); break; case 0x17: /* GET BLOCK OF DAC REGISTER */ INT10_GetDACBlock(reg_bx,reg_cx,SegPhys(es)+reg_dx); diff --git a/src/ints/int10.h b/src/ints/int10.h index 8bc7fbcd..92ea79b8 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -187,8 +187,8 @@ void INT10_ToggleBlinkingBit(Bit8u state); void INT10_GetSinglePaletteRegister(Bit8u reg,Bit8u * val); void INT10_GetOverscanBorderColor(Bit8u * val); void INT10_GetAllPaletteRegisters(PhysPt data); -void INT10_SetSingleDacRegister(Bit8u index,Bit8u red,Bit8u green,Bit8u blue); -void INT10_GetSingleDacRegister(Bit8u index,Bit8u * red,Bit8u * green,Bit8u * blue); +void INT10_SetSingleDACRegister(Bit8u index,Bit8u red,Bit8u green,Bit8u blue); +void INT10_GetSingleDACRegister(Bit8u index,Bit8u * red,Bit8u * green,Bit8u * blue); void INT10_SetDACBlock(Bit16u index,Bit16u count,PhysPt data); void INT10_GetDACBlock(Bit16u index,Bit16u count,PhysPt data); void INT10_SelectDACPage(Bit8u function,Bit8u mode); diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 266ac263..092a647e 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -168,14 +168,23 @@ void INT10_GetAllPaletteRegisters(PhysPt data) { ResetACTL(); } -void INT10_SetSingleDacRegister(Bit8u index,Bit8u red,Bit8u green,Bit8u blue) { +void INT10_SetSingleDACRegister(Bit8u index,Bit8u red,Bit8u green,Bit8u blue) { IO_Write(VGAREG_DAC_WRITE_ADDRESS,(Bit8u)index); - IO_Write(VGAREG_DAC_DATA,red); - IO_Write(VGAREG_DAC_DATA,green); - IO_Write(VGAREG_DAC_DATA,blue); + if ((real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x06)==0) { + IO_Write(VGAREG_DAC_DATA,red); + IO_Write(VGAREG_DAC_DATA,green); + IO_Write(VGAREG_DAC_DATA,blue); + } else { + /* calculate clamped intensity, taken from VGABIOS */ + Bit32u i=(( 77*red + 151*green + 28*blue ) + 0x80) >> 8; + Bit8u ic=(i>0x3f) ? 0x3f : ((Bit8u)(i & 0xff)); + IO_Write(VGAREG_DAC_DATA,ic); + IO_Write(VGAREG_DAC_DATA,ic); + IO_Write(VGAREG_DAC_DATA,ic); + } } -void INT10_GetSingleDacRegister(Bit8u index,Bit8u * red,Bit8u * green,Bit8u * blue) { +void INT10_GetSingleDACRegister(Bit8u index,Bit8u * red,Bit8u * green,Bit8u * blue) { IO_Write(VGAREG_DAC_READ_ADDRESS,index); *red=IO_Read(VGAREG_DAC_DATA); *green=IO_Read(VGAREG_DAC_DATA); @@ -184,10 +193,25 @@ void INT10_GetSingleDacRegister(Bit8u index,Bit8u * red,Bit8u * green,Bit8u * bl void INT10_SetDACBlock(Bit16u index,Bit16u count,PhysPt data) { IO_Write(VGAREG_DAC_WRITE_ADDRESS,(Bit8u)index); - for (;count>0;count--) { - IO_Write(VGAREG_DAC_DATA,mem_readb(data++)); - IO_Write(VGAREG_DAC_DATA,mem_readb(data++)); - IO_Write(VGAREG_DAC_DATA,mem_readb(data++)); + if ((real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x06)==0) { + for (;count>0;count--) { + IO_Write(VGAREG_DAC_DATA,mem_readb(data++)); + IO_Write(VGAREG_DAC_DATA,mem_readb(data++)); + IO_Write(VGAREG_DAC_DATA,mem_readb(data++)); + } + } else { + for (;count>0;count--) { + Bit8u red=mem_readb(data++); + Bit8u green=mem_readb(data++); + Bit8u blue=mem_readb(data++); + + /* calculate clamped intensity, taken from VGABIOS */ + Bit32u i=(( 77*red + 151*green + 28*blue ) + 0x80) >> 8; + Bit8u ic=(i>0x3f) ? 0x3f : ((Bit8u)(i & 0xff)); + IO_Write(VGAREG_DAC_DATA,ic); + IO_Write(VGAREG_DAC_DATA,ic); + IO_Write(VGAREG_DAC_DATA,ic); + } } } @@ -296,6 +320,6 @@ void INT10_PerformGrayScaleSumming(Bit16u start_reg,Bit16u count) { /* calculate clamped intensity, taken from VGABIOS */ Bit32u i=(( 77*red + 151*green + 28*blue ) + 0x80) >> 8; Bit8u ic=(i>0x3f) ? 0x3f : ((Bit8u)(i & 0xff)); - INT10_SetSingleDacRegister(start_reg+ct,ic,ic,ic); + INT10_SetSingleDACRegister(start_reg+ct,ic,ic,ic); } } From 4654193d3a8c5fe77f88a5c6718f3bcf9b712dc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 25 Sep 2010 19:59:37 +0000 Subject: [PATCH 3550/4131] special handling of attribute for write character function in certain monochrome VGA mode (ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3640 --- src/ints/int10.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 92c98e1f..dd86ad85 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -107,7 +107,9 @@ static Bitu INT10_Handler(void) { INT10_ReadCharAttr(®_ax,reg_bh); break; case 0x09: /* Write Character & Attribute at cursor CX times */ - INT10_WriteChar(reg_al,reg_bl,reg_bh,reg_cx,true); + if (real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)==0x11) + INT10_WriteChar(reg_al,(reg_bl&0x80)|0x3f,reg_bh,reg_cx,true); + else INT10_WriteChar(reg_al,reg_bl,reg_bh,reg_cx,true); break; case 0x0A: /* Write Character at cursor CX times */ INT10_WriteChar(reg_al,reg_bl,reg_bh,reg_cx,false); From 03190a56be6deba9ae4a8f88ba41069f7f85fd73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 26 Sep 2010 14:16:40 +0000 Subject: [PATCH 3551/4131] disable forced exit on DMA segment wrapping Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3641 --- src/hardware/dma.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 542f5962..9bc041e6 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -48,7 +48,9 @@ static void DMA_BlockRead(PhysPt spage,PhysPt offset,void * data,Bitu size,Bit8u offset <<= dma16; Bit32u dma_wrap = ((0xffff<(dma_wrapping<(dma_wrapping<> 12); /* care for EMS pageframe etc. */ @@ -67,7 +69,9 @@ static void DMA_BlockWrite(PhysPt spage,PhysPt offset,void * data,Bitu size,Bit8 offset <<= dma16; Bit32u dma_wrap = ((0xffff<(dma_wrapping<(dma_wrapping<> 12); /* care for EMS pageframe etc. */ From 974158842f26aac84605b4e0d5de1a689a302c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 26 Sep 2010 15:26:46 +0000 Subject: [PATCH 3552/4131] different EMS emulation types (ems board style, emm386 extended compatibility), fixes sound crackling in certain emm386-aware games Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3642 --- include/dma.h | 2 + src/dosbox.cpp | 11 +++-- src/ints/ems.cpp | 118 ++++++++++++++++++++++++++++++----------------- src/ints/xms.cpp | 5 +- 4 files changed, 90 insertions(+), 46 deletions(-) diff --git a/include/dma.h b/include/dma.h index a12615db..acf724ee 100644 --- a/include/dma.h +++ b/include/dma.h @@ -114,6 +114,8 @@ DmaChannel * GetDMAChannel(Bit8u chan); void CloseSecondDMAController(void); bool SecondDMAControllerAvailable(void); +void DMA_SetWrapping(Bitu wrap); + static Bit32u dma_wrapping = 0xffff; #endif diff --git a/src/dosbox.cpp b/src/dosbox.cpp index a4bf5649..e12c9b79 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -333,7 +333,7 @@ void DOSBOX_Init(void) { const char* machines[] = { "hercules", "cga", "tandy", "pcjr", "ega", "vgaonly", "svga_s3", "svga_et3000", "svga_et4000", - "svga_paradise", "vesa_nolfb", "vesa_oldvbe", 0 }; + "svga_paradise", "vesa_nolfb", "vesa_oldvbe", 0 }; secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit); Pstring = secprop->Add_path("language",Property::Changeable::Always,""); Pstring->Set_help("Select another language file."); @@ -654,8 +654,13 @@ void DOSBOX_Init(void) { Pbool->Set_help("Enable XMS support."); secprop->AddInitFunction(&EMS_Init,true);//done - Pbool = secprop->Add_bool("ems",Property::Changeable::WhenIdle,true); - Pbool->Set_help("Enable EMS support."); + const char* ems_settings[] = { "true", "emsboard", "emm386", "false", 0}; + Pstring = secprop->Add_string("ems",Property::Changeable::WhenIdle,"true"); + Pstring->Set_values(ems_settings); + Pstring->Set_help("Enable EMS support. The default (=true) provides the best\n" + "compatibility but certain applications may run better with\n" + "other choices, or require EMS support to be disabled (=false)\n" + "to work at all."); Pbool = secprop->Add_bool("umb",Property::Changeable::WhenIdle,true); Pbool->Set_help("Enable UMB support."); diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index a24a4a41..b8f399db 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -32,6 +32,7 @@ #include "setup.h" #include "support.h" #include "cpu.h" +#include "dma.h" #define EMM_PAGEFRAME 0xE000 #define EMM_PAGEFRAME4K ((EMM_PAGEFRAME*16)/4096) @@ -97,7 +98,8 @@ static Bit16u GEMMIS_seg; class device_EMM : public DOS_Device { public: - device_EMM() { + device_EMM(bool is_emm386_avail) { + is_emm386=is_emm386_avail; SetName("EMMXXXX0"); GEMMIS_seg=0; } @@ -113,6 +115,7 @@ public: bool WriteToControlChannel(PhysPt /*bufptr*/,Bit16u /*size*/,Bit16u * /*retcode*/){return true;} private: Bit8u cache; + bool is_emm386; }; bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode) { @@ -125,6 +128,7 @@ bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retco *retcode=6; return true; case 0x01: { + if (!is_emm386) return false; if (size!=6) return false; if (GEMMIS_seg==0) GEMMIS_seg=DOS_GetMemory(0x20); PhysPt GEMMIS_addr=PhysMake(GEMMIS_seg,0); @@ -181,12 +185,14 @@ bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retco return true; } case 0x02: + if (!is_emm386) return false; if (size!=2) return false; mem_writeb(bufptr+0x00,EMM_VERSION>>4); // version 4 mem_writeb(bufptr+0x01,EMM_MINOR_VERSION); *retcode=2; return true; case 0x03: + if (!is_emm386) return false; if (EMM_MINOR_VERSION < 0x2d) return false; if (size!=4) return false; mem_writew(bufptr+0x00,(Bit16u)(MEM_TotalPages()*4)); // max size (kb) @@ -1262,18 +1268,37 @@ static Bitu INT4B_Handler() { return CBRET_NONE; } +Bitu GetEMSType(Section_prop * section) { + Bitu rtype = 0; + std::string emstypestr(section->Get_string("ems")); + if (emstypestr=="true") { + rtype = 1; // mixed mode + } else if (emstypestr=="emsboard") { + rtype = 2; + } else if (emstypestr=="emm386") { + rtype = 3; + } else { + rtype = 0; + } + return rtype; +} + class EMS: public Module_base { private: + DOS_Device * emm_device; /* location in protected unfreeable memory where the ems name and callback are * stored 32 bytes.*/ static Bit16u ems_baseseg; RealPt old4b_pointer,old67_pointer; CALLBACK_HandlerObject call_vdma,call_vcpi,call_v86mon; Bitu call_int67; + Bitu ems_type; public: - EMS(Section* configuration):Module_base(configuration){ + EMS(Section* configuration):Module_base(configuration) { + emm_device=NULL; + ems_type=0; /* Virtual DMA interrupt callback */ call_vdma.Install(&INT4B_Handler,CB_IRET,"Int 4b vdma"); @@ -1283,8 +1308,11 @@ public: GEMMIS_seg=0; Section_prop * section=static_cast(configuration); - if (!section->Get_bool("ems")) return; + ems_type=GetEMSType(section); + if (ems_type<=0) return; + if (machine==MCH_PCJR) { + ems_type=0; LOG_MSG("EMS disabled for PCJr machine"); return; } @@ -1302,8 +1330,8 @@ public: /* Register the ems device */ //TODO MAYBE put it in the class. - DOS_Device * newdev = new device_EMM(); - DOS_AddDevice(newdev); + emm_device = new device_EMM(ems_type!=2); + DOS_AddDevice(emm_device); /* Clear handle and page tables */ Bitu i; @@ -1323,61 +1351,67 @@ public: EMM_AllocateSystemHandle(8); // allocate OS-dedicated handle (ems handle zero, 128kb) + if (ems_type==3) { + DMA_SetWrapping(0xffffffff); // emm386-bug that disables dma wrapping + } if (!ENABLE_VCPI) return; - /* Install a callback that handles VCPI-requests in protected mode requests */ - call_vcpi.Install(&VCPI_PM_Handler,CB_IRETD,"VCPI PM"); - vcpi.pm_interface=(call_vcpi.Get_callback())*CB_SIZE; + if (ems_type!=2) { + /* Install a callback that handles VCPI-requests in protected mode requests */ + call_vcpi.Install(&VCPI_PM_Handler,CB_IRETD,"VCPI PM"); + vcpi.pm_interface=(call_vcpi.Get_callback())*CB_SIZE; - /* Initialize private data area and set up descriptor tables */ - SetupVCPI(); + /* Initialize private data area and set up descriptor tables */ + SetupVCPI(); - if (!vcpi.enabled) return; + if (!vcpi.enabled) return; - /* Install v86-callback that handles interrupts occuring - in v86 mode, including protection fault exceptions */ - call_v86mon.Install(&V86_Monitor,CB_IRET,"V86 Monitor"); + /* Install v86-callback that handles interrupts occuring + in v86 mode, including protection fault exceptions */ + call_v86mon.Install(&V86_Monitor,CB_IRET,"V86 Monitor"); - mem_writeb(vcpi.private_area+0x2e00,(Bit8u)0xFE); //GRP 4 - mem_writeb(vcpi.private_area+0x2e01,(Bit8u)0x38); //Extra Callback instruction - mem_writew(vcpi.private_area+0x2e02,call_v86mon.Get_callback()); //The immediate word - mem_writeb(vcpi.private_area+0x2e04,(Bit8u)0x66); - mem_writeb(vcpi.private_area+0x2e05,(Bit8u)0xCF); //A IRETD Instruction + mem_writeb(vcpi.private_area+0x2e00,(Bit8u)0xFE); //GRP 4 + mem_writeb(vcpi.private_area+0x2e01,(Bit8u)0x38); //Extra Callback instruction + mem_writew(vcpi.private_area+0x2e02,call_v86mon.Get_callback()); //The immediate word + mem_writeb(vcpi.private_area+0x2e04,(Bit8u)0x66); + mem_writeb(vcpi.private_area+0x2e05,(Bit8u)0xCF); //A IRETD Instruction - /* Testcode only, starts up dosbox in v86-mode */ - if (ENABLE_V86_STARTUP) { - /* Prepare V86-task */ - CPU_SET_CRX(0, 1); - CPU_LGDT(0xff, vcpi.private_area+0x0000); - CPU_LIDT(0x7ff, vcpi.private_area+0x2000); - if (CPU_LLDT(0x08)) LOG_MSG("VCPI:Could not load LDT"); - if (CPU_LTR(0x10)) LOG_MSG("VCPI:Could not load TR"); + /* Testcode only, starts up dosbox in v86-mode */ + if (ENABLE_V86_STARTUP) { + /* Prepare V86-task */ + CPU_SET_CRX(0, 1); + CPU_LGDT(0xff, vcpi.private_area+0x0000); + CPU_LIDT(0x7ff, vcpi.private_area+0x2000); + if (CPU_LLDT(0x08)) LOG_MSG("VCPI:Could not load LDT"); + if (CPU_LTR(0x10)) LOG_MSG("VCPI:Could not load TR"); - CPU_Push32(SegValue(gs)); - CPU_Push32(SegValue(fs)); - CPU_Push32(SegValue(ds)); - CPU_Push32(SegValue(es)); - CPU_Push32(SegValue(ss)); - CPU_Push32(0x23002); - CPU_Push32(SegValue(cs)); - CPU_Push32(reg_eip&0xffff); - /* Switch to V86-mode */ - cpu.cpl=0; - CPU_IRET(true,0); + CPU_Push32(SegValue(gs)); + CPU_Push32(SegValue(fs)); + CPU_Push32(SegValue(ds)); + CPU_Push32(SegValue(es)); + CPU_Push32(SegValue(ss)); + CPU_Push32(0x23002); + CPU_Push32(SegValue(cs)); + CPU_Push32(reg_eip&0xffff); + /* Switch to V86-mode */ + cpu.cpl=0; + CPU_IRET(true,0); + } } } ~EMS() { - Section_prop * section=static_cast(m_configuration); - if (!section->Get_bool("ems")) return; + if (ems_type<=0) return; /* Undo Biosclearing */ BIOS_ZeroExtendedSize(false); /* Remove ems device */ - device_EMM newdev; - DOS_DelDevice(&newdev); + if (emm_device!=NULL) { + DOS_DelDevice(emm_device); + emm_device=NULL; + } GEMMIS_seg=0; /* Remove the emsname and callback hack */ diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 456fab1f..a4349e7e 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -412,6 +412,8 @@ Bitu XMS_Handler(void) { return CBRET_NONE; } +Bitu GetEMSType(Section_prop * section); + class XMS: public Module_base { private: CALLBACK_HandlerObject callbackhandler; @@ -445,7 +447,8 @@ public: /* Set up UMB chain */ umb_available=section->Get_bool("umb"); - DOS_BuildUMBChain(section->Get_bool("umb"),section->Get_bool("ems")); + bool ems_available = GetEMSType(section)>0; + DOS_BuildUMBChain(section->Get_bool("umb"),ems_available); } ~XMS(){ From 62bf90957f3a3ab168fa16cde8411ba5db3b1bf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 26 Sep 2010 16:16:13 +0000 Subject: [PATCH 3553/4131] small readme updates Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3643 --- README | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/README b/README index a58bac14..99b4c5cc 100644 --- a/README +++ b/README @@ -46,7 +46,7 @@ Type INTRO in DOSBox for a quick tour. It is essential that you get familiar with the idea of mounting, DOSBox does not automatically make any drive (or a part of it) accessible to the emulation. See the FAQ entry "How to start?" as well as the description of the MOUNT command -(section 4: "Internal Programs"). If you have your game on a cdrom you may try +(Section 4: "Internal Programs"). If you have your game on a cdrom you may try this guide: http://vogons.zetafleet.com/viewtopic.php?t=8933 @@ -92,7 +92,7 @@ START: How to start? AUTOMATION: Do I always have to type these commands? In the DOSBox configuration file is an [autoexec] section. The commands present there are run when DOSBox starts, so you can use this section - for the mounting. Look at Section 13: The configuration (options) file + for the mounting. Look at Section 13: "The configuration (options) file". FULLSCREEN: How do I change to fullscreen? @@ -220,11 +220,12 @@ SOUND: What sound hardware does DOSBox presently emulate? SOUND: The sound stutters or sounds stretched/weird. You may be using too much CPU power to keep DOSBox running at the current speed. You can lower the cycles, skip frames, reduce the sampling rate of - the respective sound device, increase the prebuffer. See section 13: "The - configuration (options) file" - If you are using cycles=max or =auto, then make sure that there is no - background processes interfering! (especially if they access the harddisk) - Also look at Section 10. "How to speed up/slow down DOSBox" + the respective sound device, increase the prebuffer. See Section 13: "The + configuration (options) file". + If you are using 'cycles=max' or 'cycles=auto', then make sure that there is + no background processes interfering! (especially if they access the harddisk) + Also look at Section 10: "How to speed up/slow down DOSBox" as well as + Section 11: "Troubleshooting". KEYBOARD: I can't type \ or : in DOSBox. @@ -233,7 +234,7 @@ KEYBOARD: I can't type \ or : in DOSBox. detected), or the key mapping is wrong. Some possible fixes: 1. Use / instead, or ALT-58 for : and ALT-92 for \. - 2. Change the DOS keyboard layout (see Section 8: Keyboard Layout). + 2. Change the DOS keyboard layout (see Section 8: "Keyboard Layout"). 3. Add the commands you want to execute to the [autoexec] section of the DOSBox configuration file. 4. Open the DOSBox configuration file and change the usescancodes entry. @@ -274,16 +275,16 @@ CONTROL: The character/cursor/mouse pointer always moves into one direction! SPEED: The game/application runs much too slow/too fast! - Look at the section 10: "How to speed up/slow down DOSBox" for more + Look at Section 10: "How to speed up/slow down DOSBox" for more information. CRASH: The game/application does not run at all/crashes! - Look at Section 11: Troubleshooting + Look at Section 11: "Troubleshooting". CRASH: DOSBox crashes on startup!. - Look at Section 11: Troubleshooting + Look at Section 11: "Troubleshooting". GAME: My Build game(Duke3D/Blood/Shadow Warrior) has problems. @@ -302,7 +303,7 @@ SAFETY: Can DOSBox harm my computer? OPTIONS: I would like to change DOSBox's options. - Look at Section 13. "The configuration (options) file" + Look at Section 13: "The configuration (options) file". HELP: Great Manual, but I still don't get it. @@ -319,7 +320,7 @@ HELP: Great Manual, but I still don't get it. An overview of the command line options you can give to DOSBox. Although in most cases it is easier to use DOSBox's configuration file instead. -See: Section 13. "The configuration (options) file" +See Section 13: "The configuration (options) file". To be able to use Command Line Parameters: (Windows) open cmd.exe or command.com or edit the shortcut to dosbox.exe @@ -368,11 +369,11 @@ dosbox -erasemapper -conf configfilelocation Start DOSBox with the options specified in "configfilelocation". Multiple -conf options may be present. - See Section 13 for more details. + See Section 13: "The configuration (options) file" for more details. -lang languagefilelocation Start DOSBox using the language specified in "languagefilelocation". - See Section 14 for more details. + See Section 14: "The Language File" for more details. -machine machinetype Setup DOSBox to emulate a specific type of machine. Valid choices are: @@ -670,8 +671,8 @@ CONFIG -get "section property" config -writeconf c:\dosgames\dosbox.conf 2. To set the cpu cycles to 10000: config -set "cpu cycles=10000" - 3. To turn ems memory emulation off: - config -set "dos ems=off" + 3. To turn EMS memory emulation off: + config -set "dos ems=false" 4. To check which cpu core is being used. config -get "cpu core" @@ -922,7 +923,7 @@ IPX KEYB [keyboardlayoutcode [codepage [codepagefile]]] Change the keyboard layout. For detailed information about keyboard layouts - please see Section 8: "Keyboard Layout" + please see Section 8: "Keyboard Layout". [keyboardlayoutcode] is a string consisting of five or less characters, examples are PL214 (Polish typists) or PL457 (Polish programmers). @@ -999,7 +1000,7 @@ F11 (machine=hercules) cycle through amber, green, white colouring*** a different machine type. So either reassign them or reset the mapper. These are the default keybindings. They can be changed in the keymapper -(see Section 7: KeyMapper). +(see Section 7: "KeyMapper"). In MAC OS you can try using cmd(applekey) together with Ctrl if the key doesn't work eg. cmd-ctrl-F1, but some keys may still need remapping (in Linux too). @@ -1053,8 +1054,8 @@ inside DOSBox, try different 'timed' setting in DOSBox's configuration file. 7. KeyMapper: ============= -You start the DOSBox mapper either with CTRL-F1 (see section 5. Special Keys) -or -startmapper (see Section 3. Command Line Parameters). +You start the DOSBox mapper either with CTRL-F1 (see Section 5: "Special Keys") +or -startmapper (see Section 3: "Command Line Parameters"). You are presented with a virtual keyboard and a virtual joystick. These virtual devices correspond to the keys and events DOSBox will @@ -1148,9 +1149,9 @@ your mapperfile, if it is present in the DOSBox configuration file. To switch to a different keyboard layout, either the entry "keyboardlayout" in the [dos] section of the DOSBox configuration file can be used, or the -internal DOSBox program keyb.com (Section 4: Internal Programs) -Both accept DOS conforming language codes (see below), -but only by using keyb.com a custom codepage can be specified. +internal DOSBox program keyb.com (Section 4: "Internal Programs"). Both accept +DOS conforming language codes (see below), but only by using keyb.com a +custom codepage can be specified. The default keyboardlayout=auto currently works under windows only. The language is chosen according to the OS language, but the keyboard layout is not detected. @@ -1331,7 +1332,7 @@ Example: ==================== General tip: - Check messages in DOSBox Status Window. See section 12. "DOSBox Status Window" + Check messages in DOSBox Status Window. See Section 12: "DOSBox Status Window". DOSBox crashes right after starting it: - use different values for the output= entry in your DOSBox From 380ca5a9a2e277dbda156ef125db8d5fc365df41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 27 Sep 2010 20:32:00 +0000 Subject: [PATCH 3554/4131] allow arbitrary segments to be remapped by the EMM functions (peter ferrie; fixes Airline Simulator 2) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3644 --- src/ints/ems.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index b8f399db..5e2e6134 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -89,6 +89,8 @@ struct EMM_Handle { EMM_Mapping page_map[EMM_MAX_PHYS]; }; +static Bitu ems_type; + static EMM_Handle emm_handles[EMM_MAX_HANDLES]; static EMM_Mapping emm_mappings[EMM_MAX_PHYS]; static EMM_Mapping emm_segmentmappings[0x40]; @@ -329,7 +331,23 @@ static Bit8u EMM_MapPage(Bitu phys_page,Bit16u handle,Bit16u log_page) { static Bit8u EMM_MapSegment(Bitu segment,Bit16u handle,Bit16u log_page) { // LOG_MSG("EMS MapSegment handle %d segment %d log %d",handle,segment,log_page); - if (((segment>=0xa000) && (segment<0xb000)) || ((segment>=EMM_PAGEFRAME-0x1000) && (segment=0xa000) && (segment<0xb000)) { + valid_segment=true; // allow mapping of graphics memory + } + if ((segment>=EMM_PAGEFRAME) && (segment=EMM_PAGEFRAME-0x1000) && (segment Date: Mon, 27 Sep 2010 21:07:54 +0000 Subject: [PATCH 3555/4131] minor typos Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3645 --- README | 8 ++++---- src/gui/sdlmain.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README b/README index 99b4c5cc..7302d250 100644 --- a/README +++ b/README @@ -1265,8 +1265,8 @@ CPU Cycles (speed up/slow down) a different setting in the DOSBox's configuration file. You can force the slow or fast behavior by setting a fixed amount of cycles - in the DOSBox's configuration file. If you for example set cycles=10000, then - DOSBox window will display a line "Cpu Speed: fixed 10000 cycles" at the top. + in the DOSBox's configuration file. If you set for example cycles=10000, the + DOSBox window will display a line "CPU speed: fixed 10000 cycles" at the top. In this mode you can reduce the amount of cycles even more by hitting CTRL-F11 (you can go as low as you want) or raise it by hitting CTRL-F12 as much as you want, but you will be limited by the power of one core of your computer's CPU. @@ -1281,8 +1281,8 @@ CPU Cycles (speed up/slow down) You can also force the fast behavior by setting cycles=max in the DOSBox configuration file. The DOSBox window will display a line - "Cpu Speed: max 100% cycles" at the top then. This time you won't have to care - how much free time your real CPU's cores have, because DOSBox will always use + "CPU speed: max 100% cycles" at the top then. This time you won't have to care + how much free time your real CPU cores have, because DOSBox will always use 100% of your real CPU's one core. In this mode you can reduce the amount of your real CPU's core usage by CTRL-F11 or raise it with CTRL-F12. diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 6bbc24c3..1d004176 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -236,9 +236,9 @@ void GFX_SetTitle(Bit32s cycles,Bits frameskip,bool paused){ if(cycles != -1) internal_cycles = cycles; if(frameskip != -1) internal_frameskip = frameskip; if(CPU_CycleAutoAdjust) { - sprintf(title,"DOSBox %s, Cpu speed: max %3d%% cycles, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram); + sprintf(title,"DOSBox %s, CPU speed: max %3d%% cycles, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram); } else { - sprintf(title,"DOSBox %s, Cpu speed: %8d cycles, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram); + sprintf(title,"DOSBox %s, CPU speed: %8d cycles, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram); } if(paused) strcat(title," PAUSED"); From 959ea1527f85eebc1a441c81126cea4121ed2513 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 28 Sep 2010 18:16:11 +0000 Subject: [PATCH 3556/4131] change EMS driver attribute word (ripsaw, fixes David Leadbetter's Greens) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3646 --- src/ints/ems.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 5e2e6134..68a908c2 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -112,7 +112,7 @@ public: } bool Seek(Bit32u * /*pos*/,Bit32u /*type*/){return false;} bool Close(){return false;} - Bit16u GetInformation(void){return 0xc080;} + Bit16u GetInformation(void){return 0xc0c0;} bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode); bool WriteToControlChannel(PhysPt /*bufptr*/,Bit16u /*size*/,Bit16u * /*retcode*/){return true;} private: From c2622359f9ca7a4bca91fd673ad2d3b84dc508f1 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Fri, 1 Oct 2010 19:39:14 +0000 Subject: [PATCH 3557/4131] - implement Tandy special 4-color palette handling - remove 3d8/3d9 from PCJr mode (PCJr didn't have it) - update INT10 palette functions accordingly - add a level of indirection to Tandy and PCjr palette deconding to fix video recording with on-screen palette changes - enable line-by-line emulation for Tandy too - machine-specific implementation of the color when display is disabled (vgaonly too) - enable the light pen stub on all machines that it is documented for - mask off a bank-selection bit that is not used under a specific circumstance Fixes Alley Cat palette on PCJr, Gauntlet, Ghostbusters, Pirates! on Tandy, Video recording on Tandy/PCJr where the palette is changed on-screen Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3647 --- src/hardware/vga_draw.cpp | 91 ++++++++++--- src/hardware/vga_other.cpp | 268 +++++++++++++++++++++++-------------- src/ints/int10.cpp | 3 +- src/ints/int10_modes.cpp | 9 +- src/ints/int10_pal.cpp | 86 ++++++++++-- 5 files changed, 327 insertions(+), 130 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index c5330421..494a2b34 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -118,30 +118,30 @@ static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart, Bitu line) { static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart, Bitu line) { const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift); - Bit32u * draw=(Bit32u *)TempLine; - for (Bitu x=0;x> 4 | - (val2 & 0x0f) << 24 | - (val2 & 0xf0) << 12; + Bit8u* draw=TempLine; + Bitu end = vga.draw.blocks*2; + while(end) { + Bit8u byte = base[vidstart & vga.tandy.addr_mask]; + *draw++=vga.attr.palette[byte >> 4]; + *draw++=vga.attr.palette[byte & 0x0f]; + vidstart++; + end--; } return TempLine; } static Bit8u * VGA_Draw_4BPP_Line_Double(Bitu vidstart, Bitu line) { const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift); - Bit32u * draw=(Bit32u *)TempLine; - for (Bitu x=0;x> 4 | - (val & 0xf0) << 4 | - (val & 0x0f) << 16 | - (val & 0x0f) << 24; + Bit8u* draw=TempLine; + Bitu end = vga.draw.blocks; + while(end) { + Bit8u byte = base[vidstart & vga.tandy.addr_mask]; + Bit8u data = vga.attr.palette[byte >> 4]; + *draw++ = data; *draw++ = data; + data = vga.attr.palette[byte & 0x0f]; + *draw++ = data; *draw++ = data; + vidstart++; + end--; } return TempLine; } @@ -589,10 +589,60 @@ static void VGA_ProcessSplit() { vga.draw.address_line=0; } +static Bit8u bg_color_index = 0; // screen-off black index static void VGA_DrawSingleLine(Bitu /*blah*/) { if (GCC_UNLIKELY(vga.attr.disabled)) { - // draw blanked line (DoWhackaDo, Alien Carnage, TV sports Football) - memset(TempLine, 0, sizeof(TempLine)); + switch(machine) { + case MCH_PCJR: + // Displays the border color when screen is disabled + bg_color_index = vga.tandy.border_color; + break; + case MCH_TANDY: + // Either the PCJr way or the CGA way + if (vga.tandy.gfx_control& 0x4) { + bg_color_index = vga.tandy.border_color; + } else if (vga.mode==M_TANDY4) + bg_color_index = vga.attr.palette[0]; + else bg_color_index = 0; + break; + case MCH_CGA: + // the background color + bg_color_index = vga.attr.overscan_color; + break; + case MCH_EGA: + case MCH_VGA: + // DoWhackaDo, Alien Carnage, TV sports Football + // when disabled by attribute index bit 5: + // ET3000, ET4000, Paradise display the border color + // S3 displays the content of the currently selected attribute register + // when disabled by sequencer the screen is black "257th color" + + // the DAC table may not match the bits of the overscan register + // so use black for this case too... + //if (vga.attr.disabled& 2) { + if (vga.dac.xlat16[bg_color_index] != 0) { + for(Bitu i = 0; i < 256; i++) + if (vga.dac.xlat16[i] == 0) { + bg_color_index = i; + break; + } + } + //} else + // bg_color_index = vga.attr.overscan_color; + break; + default: + bg_color_index = 0; + break; + } + if (vga.draw.bpp==8) { + memset(TempLine, bg_color_index, sizeof(TempLine)); + } else if (vga.draw.bpp==16) { + Bit16u* wptr = (Bit16u*) TempLine; + Bit16u value = vga.dac.xlat16[bg_color_index]; + for (Bitu i = 0; i < sizeof(TempLine)/2; i++) { + wptr[i] = value; + } + } RENDER_DrawLine(TempLine); } else { Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line ); @@ -966,6 +1016,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { switch (machine) { case MCH_CGA: case MCH_PCJR: + case MCH_TANDY: vga.draw.mode = LINE; break; case MCH_EGA: diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 7fd18293..c6cd613f 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -153,6 +153,27 @@ static Bitu read_crtc_data_other(Bitu /*port*/,Bitu /*iolen*/) { return (Bitu)(~0); } +static void write_lightpen(Bitu port,Bitu val,Bitu) { + switch (port) { + case 0x3db: // Clear lightpen latch + vga.other.lightpen_triggered = false; + break; + case 0x3dc: // Preset lightpen latch + if (!vga.other.lightpen_triggered) { + vga.other.lightpen_triggered = true; // TODO: this shows at port 3ba/3da bit 1 + + double timeInFrame = PIC_FullIndex()-vga.draw.delay.framestart; + double timeInLine = fmod(timeInFrame,vga.draw.delay.htotal); + Bitu current_scanline = (Bitu)(timeInFrame / vga.draw.delay.htotal); + + vga.other.lightpen = (Bit16u)((vga.draw.address_add/2) * (current_scanline/2)); + vga.other.lightpen += (Bit16u)((timeInLine / vga.draw.delay.hdend) * + ((float)(vga.draw.address_add/2))); + } + break; + } +} + static double hue_offset = 0.0; static Bit8u cga16_val = 0; static void update_cga16_color(void); @@ -235,56 +256,139 @@ static void DecreaseHue(bool pressed) { LOG_MSG("Hue at %f",hue_offset); } -static void write_color_select(Bit8u val) { +static void write_cga_color_select(Bitu val) { vga.tandy.color_select=val; - switch (vga.mode) { + switch(vga.mode) { + case M_TANDY4: { + Bit8u base = (val & 0x10) ? 0x08 : 0; + Bit8u bg = val & 0xf; + if (vga.tandy.mode_control & 0x4) // cyan red white + VGA_SetCGA4Table(bg, 3+base, 4+base, 7+base); + else if (val & 0x20) // cyan magenta white + VGA_SetCGA4Table(bg, 3+base, 5+base, 7+base); + else // green red brown + VGA_SetCGA4Table(bg, 2+base, 4+base, 6+base); + vga.tandy.border_color = bg; + vga.attr.overscan_color = bg; + break; + } case M_TANDY2: VGA_SetCGA2Table(0,val & 0xf); - break; - case M_TANDY4: - { - if ((machine==MCH_TANDY && (vga.tandy.gfx_control & 0x8)) || - (machine==MCH_PCJR && (vga.tandy.mode_control==0x0b))) { - VGA_SetCGA4Table(0,1,2,3); - return; - } - Bit8u base=(val & 0x10) ? 0x08 : 0; - /* Check for BW Mode */ - if (vga.tandy.mode_control & 0x4) { - VGA_SetCGA4Table(val & 0xf,3+base,4+base,7+base); - } else { - if (val & 0x20) VGA_SetCGA4Table(val & 0xf,3+base,5+base,7+base); - else VGA_SetCGA4Table(val & 0xf,2+base,4+base,6+base); - } - } + vga.attr.overscan_color = 0; break; case M_CGA16: cga16_color_select(val); break; case M_TEXT: - case M_TANDY16: + vga.tandy.border_color = val & 0xf; + vga.attr.overscan_color = 0; break; } } -static void TANDY_FindMode(void) { - if (vga.tandy.mode_control & 0x2) { - if (vga.tandy.gfx_control & 0x10) - VGA_SetMode(M_TANDY16); - else if (vga.tandy.gfx_control & 0x08) - VGA_SetMode(M_TANDY4); - else if (vga.tandy.mode_control & 0x10) - VGA_SetMode(M_TANDY2); - else - VGA_SetMode(M_TANDY4); - write_color_select(vga.tandy.color_select); +static void write_cga(Bitu port,Bitu val,Bitu /*iolen*/) { + switch (port) { + case 0x3d8: + vga.tandy.mode_control=(Bit8u)val; + vga.attr.disabled = (val&0x8)? 0: 1; + if (vga.tandy.mode_control & 0x2) { // graphics mode + if (vga.tandy.mode_control & 0x10) {// highres mode + if (!(val & 0x4)) { // burst on + VGA_SetMode(M_CGA16); // composite ntsc 160x200 16 color mode + } else { + VGA_SetMode(M_TANDY2); + } + } else VGA_SetMode(M_TANDY4); // lowres mode + + write_cga_color_select(vga.tandy.color_select); + } else { + VGA_SetMode(M_TANDY_TEXT); + } + VGA_SetBlinking(val & 0x20); + break; + case 0x3d9: // color select + write_cga_color_select(val); + break; + } +} + +static void tandy_update_palette() { + // TODO mask off bits if needed + if (machine == MCH_TANDY) { + switch (vga.mode) { + case M_TANDY2: + VGA_SetCGA2Table(vga.attr.palette[0], + //vga.attr.palette[vga.tandy.color_select&0xf]); + vga.attr.palette[0xf]); + //VGA_SetCGA2Table(vga.attr.palette[0xf],vga.attr.palette[0]); + break; + case M_TANDY4: + if (vga.tandy.gfx_control & 0x8) { + // 4-color high resolution - might be an idea to introduce M_TANDY4H + VGA_SetCGA4Table( // function sets both medium and highres 4color tables + vga.attr.palette[0], vga.attr.palette[1], + vga.attr.palette[2], vga.attr.palette[3]); + } else { + Bit8u color_set = 0; + Bit8u r_mask = 0xf; + if (vga.tandy.color_select & 0x10) color_set |= 8; // intensity + if (vga.tandy.color_select & 0x20) color_set |= 1; // Cyan Mag. White + if (vga.tandy.mode_control & 0x04) { // Cyan Red White + color_set |= 1; + r_mask &= ~1; + } + VGA_SetCGA4Table( + vga.attr.palette[0], + vga.attr.palette[(2|color_set)& vga.tandy.palette_mask], + vga.attr.palette[(4|(color_set& r_mask))& vga.tandy.palette_mask], + vga.attr.palette[(6|color_set)& vga.tandy.palette_mask]); + } + break; + default: + break; + } } else { - VGA_SetMode(M_TANDY_TEXT); + // PCJr + switch (vga.mode) { + case M_TANDY2: + VGA_SetCGA2Table(vga.attr.palette[0],vga.attr.palette[1]); + break; + case M_TANDY4: + VGA_SetCGA4Table( + vga.attr.palette[0], vga.attr.palette[1], + vga.attr.palette[2], vga.attr.palette[3]); + break; + default: + break; + } } } void VGA_SetModeNow(VGAModes mode); +static void TANDY_FindMode(void) { + if (vga.tandy.mode_control & 0x2) { + if (vga.tandy.gfx_control & 0x10) { + if (vga.mode==M_TANDY4) { + VGA_SetModeNow(M_TANDY16); + } else VGA_SetMode(M_TANDY16); + } + else if (vga.tandy.gfx_control & 0x08) { + VGA_SetMode(M_TANDY4); + } + else if (vga.tandy.mode_control & 0x10) + VGA_SetMode(M_TANDY2); + else { + if (vga.mode==M_TANDY16) { + VGA_SetModeNow(M_TANDY4); + } else VGA_SetMode(M_TANDY4); + } + tandy_update_palette(); + } else { + VGA_SetMode(M_TANDY_TEXT); + } +} + static void PCJr_FindMode(void) { if (vga.tandy.mode_control & 0x2) { if (vga.tandy.mode_control & 0x10) { @@ -299,7 +403,6 @@ static void PCJr_FindMode(void) { if (vga.mode==M_TANDY16) VGA_SetModeNow(M_TANDY4); else VGA_SetMode(M_TANDY4); } - write_color_select(vga.tandy.color_select); } else { VGA_SetMode(M_TANDY_TEXT); } @@ -327,11 +430,16 @@ static void write_tandy_reg(Bit8u val) { vga.tandy.mode_control=val; VGA_SetBlinking(val & 0x20); PCJr_FindMode(); - vga.attr.disabled = (val&0x8)? 0: 1; + if (val&0x8) vga.attr.disabled &= ~1; + else vga.attr.disabled |= 1; } else { LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index); } break; + case 0x1: /* Palette mask */ + vga.tandy.palette_mask = val; + tandy_update_palette(); + break; case 0x2: /* Border color */ vga.tandy.border_color=val; break; @@ -348,45 +456,12 @@ static void write_tandy_reg(Bit8u val) { TandyCheckLineMask(); VGA_SetupHandlers(); break; - case 0x8: /* Monitor mode seletion */ - //Bit 1 select mode e, for 640x200x16, some double clocking thing? - //Bit 4 select 350 line mode for hercules emulation - LOG(LOG_VGAMISC,LOG_NORMAL)("Write %2X to tandy monitor mode",val ); - break; - /* palette colors */ - case 0x10: case 0x11: case 0x12: case 0x13: - case 0x14: case 0x15: case 0x16: case 0x17: - case 0x18: case 0x19: case 0x1a: case 0x1b: - case 0x1c: case 0x1d: case 0x1e: case 0x1f: - VGA_ATTR_SetPalette(vga.tandy.reg_index-0x10,val & 0xf); - break; - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index); - } -} - -static void write_cga(Bitu port,Bitu val,Bitu /*iolen*/) { - switch (port) { - case 0x3d8: - vga.tandy.mode_control=(Bit8u)val; - vga.attr.disabled = (val&0x8)? 0: 1; - if (vga.tandy.mode_control & 0x2) { - if (vga.tandy.mode_control & 0x10) { - if (!(val & 0x4) && machine==MCH_CGA) { - VGA_SetMode(M_CGA16); //Video burst 16 160x200 color mode - } else { - VGA_SetMode(M_TANDY2); - } - } else VGA_SetMode(M_TANDY4); - write_color_select(vga.tandy.color_select); - } else { - VGA_SetMode(M_TANDY_TEXT); - } - VGA_SetBlinking(val & 0x20); - break; - case 0x3d9: - write_color_select((Bit8u)val); - break; + default: + if ((vga.tandy.reg_index & 0xf0) == 0x10) { // color palette + vga.attr.palette[vga.tandy.reg_index-0x10] = val&0xf; + tandy_update_palette(); + } else + LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index); } } @@ -394,40 +469,32 @@ static void write_tandy(Bitu port,Bitu val,Bitu /*iolen*/) { switch (port) { case 0x3d8: vga.tandy.mode_control=(Bit8u)val; + if (val&0x8) vga.attr.disabled &= ~1; + else vga.attr.disabled |= 1; TandyCheckLineMask(); VGA_SetBlinking(val & 0x20); TANDY_FindMode(); break; case 0x3d9: - write_color_select((Bit8u)val); + vga.tandy.color_select=val; + if (vga.mode==M_TANDY2) vga.attr.palette[0xf] = vga.tandy.color_select&0xf; + else vga.attr.palette[0] = vga.tandy.color_select&0xf; // Pirates! + tandy_update_palette(); break; case 0x3da: vga.tandy.reg_index=(Bit8u)val; - break; - case 0x3db: // Clear lightpen latch - vga.other.lightpen_triggered = false; - break; - case 0x3dc: // Preset lightpen latch - if (!vga.other.lightpen_triggered) { - vga.other.lightpen_triggered = true; // TODO: this shows at port 3ba/3da bit 1 - - double timeInFrame = PIC_FullIndex()-vga.draw.delay.framestart; - double timeInLine = fmod(timeInFrame,vga.draw.delay.htotal); - Bitu current_scanline = (Bitu)(timeInFrame / vga.draw.delay.htotal); - - vga.other.lightpen = (Bit16u)((vga.draw.address_add/2) * (current_scanline/2)); - vga.other.lightpen += (Bit16u)((timeInLine / vga.draw.delay.hdend) * - ((float)(vga.draw.address_add/2))); - } + //if (val&0x10) vga.attr.disabled |= 2; + //else vga.attr.disabled &= ~2; break; // case 0x3dd: //Extended ram page address register: - break; +// break; case 0x3de: write_tandy_reg((Bit8u)val); break; case 0x3df: vga.tandy.line_mask = (Bit8u)(val >> 6); vga.tandy.draw_bank = val & ((vga.tandy.line_mask&2) ? 0x6 : 0x7); + if(vga.tandy.line_mask==3) vga.tandy.draw_bank &= ~1; // LSB unused in 32k modes vga.tandy.mem_bank = (val >> 3) & ((vga.tandy.line_mask&2) ? 0x6 : 0x7); TandyCheckLineMask(); VGA_SetupHandlers(); @@ -437,12 +504,14 @@ static void write_tandy(Bitu port,Bitu val,Bitu /*iolen*/) { static void write_pcjr(Bitu port,Bitu val,Bitu /*iolen*/) { switch (port) { - case 0x3d9: - write_color_select((Bit8u)val); - break; case 0x3da: if (vga.tandy.pcjr_flipflop) write_tandy_reg((Bit8u)val); - else vga.tandy.reg_index=(Bit8u)val; + else { + vga.tandy.reg_index=(Bit8u)val; + if (vga.tandy.reg_index & 0x10) + vga.attr.disabled |= 2; + else vga.attr.disabled &= ~2; + } vga.tandy.pcjr_flipflop=!vga.tandy.pcjr_flipflop; break; case 0x3df: @@ -577,6 +646,10 @@ void VGA_SetupOther(void) { for (i=0;i<256;i++) memcpy(&vga.draw.font[i*32],&int10_font_08[i*8],8); vga.draw.font_tables[0]=vga.draw.font_tables[1]=vga.draw.font; } + if (machine==MCH_CGA || IS_TANDY_ARCH || machine==MCH_HERC) { + IO_RegisterWriteHandler(0x3db,write_lightpen,IO_MB); + IO_RegisterWriteHandler(0x3dc,write_lightpen,IO_MB); + } if (machine==MCH_HERC) { extern Bit8u int10_font_14[256 * 14]; for (i=0;i<256;i++) memcpy(&vga.draw.font[i*32],&int10_font_14[i*14],14); @@ -586,8 +659,6 @@ void VGA_SetupOther(void) { if (machine==MCH_CGA) { IO_RegisterWriteHandler(0x3d8,write_cga,IO_MB); IO_RegisterWriteHandler(0x3d9,write_cga,IO_MB); - IO_RegisterWriteHandler(0x3db,write_tandy,IO_MB); - IO_RegisterWriteHandler(0x3dc,write_tandy,IO_MB); MAPPER_AddHandler(IncreaseHue,MK_f11,MMOD2,"inchue","Inc Hue"); MAPPER_AddHandler(DecreaseHue,MK_f11,0,"dechue","Dec Hue"); } @@ -595,14 +666,13 @@ void VGA_SetupOther(void) { write_tandy( 0x3df, 0x0, 0 ); IO_RegisterWriteHandler(0x3d8,write_tandy,IO_MB); IO_RegisterWriteHandler(0x3d9,write_tandy,IO_MB); + IO_RegisterWriteHandler(0x3da,write_tandy,IO_MB); IO_RegisterWriteHandler(0x3de,write_tandy,IO_MB); IO_RegisterWriteHandler(0x3df,write_tandy,IO_MB); - IO_RegisterWriteHandler(0x3da,write_tandy,IO_MB); } if (machine==MCH_PCJR) { //write_pcjr will setup base address write_pcjr( 0x3df, 0x7 | (0x7 << 3), 0 ); - IO_RegisterWriteHandler(0x3d9,write_pcjr,IO_MB); IO_RegisterWriteHandler(0x3da,write_pcjr,IO_MB); IO_RegisterWriteHandler(0x3df,write_pcjr,IO_MB); } diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index dd86ad85..cc367ea3 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -140,7 +140,8 @@ static Bitu INT10_Handler(void) { reg_ah=(Bit8u)real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); break; case 0x10: /* Palette functions */ - if ((machine==MCH_CGA) || ((!IS_VGA_ARCH) && (reg_al>0x03))) break; + if (!IS_EGAVGA_ARCH && (reg_al>0x02)) break; + else if (!IS_VGA_ARCH && (reg_al>0x03)) break; switch (reg_al) { case 0x00: /* SET SINGLE PALETTE REGISTER */ INT10_SetSinglePaletteRegister(reg_bl,reg_bh); diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 54fdaccb..d3d7099d 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -246,6 +246,7 @@ VideoModeBlock ModeList_OTHER[]={ { 0x008 ,M_TANDY16,160 ,200 ,20 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,56 ,127 ,40 ,100 ,0 }, { 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,113 ,63 ,80 ,50 ,0 }, { 0x00A ,M_CGA4 ,640 ,200 ,80 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,113 ,63 ,80 ,50 ,0 }, +//{ 0x00E ,M_TANDY16,640 ,200 ,80 ,25 ,8 ,8 ,8 ,0xA0000 ,0x10000 ,113 ,256 ,80 ,200 ,0 }, {0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, }; @@ -547,6 +548,11 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) { default: IO_WriteB(0x3de,0x0);break; } + // write palette + for(Bitu i = 0; i < 16; i++) { + IO_WriteB(0x3da,i+0x10); + IO_WriteB(0x3de,i); + } //Clear extended mapping IO_WriteB(0x3da,0x5); IO_WriteB(0x3de,0x0); @@ -587,8 +593,9 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) { if (CurMode->mode == 0x6 || CurMode->mode==0xa) color_select=0x3f; else color_select=0x30; - IO_WriteB(0x3d9,color_select); real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select); + INT10_SetColorSelect(1); + INT10_SetBackgroundBorder(0); break; } diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 092a647e..4a672c09 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -35,9 +35,44 @@ static INLINE void WriteTandyACTL(Bit8u creg,Bit8u val) { void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val) { switch (machine) { - case TANDY_ARCH_CASE: + case MCH_PCJR: + reg&=0xf; IO_Read(VGAREG_TDY_RESET); WriteTandyACTL(reg+0x10,val); + IO_Write(0x3da,0x0); // palette back on + break; + case MCH_TANDY: + // TODO waits for vertical retrace + switch(vga.mode) { + case M_TANDY2: + if (reg >= 0x10) break; + else if (reg==1) reg = 0x1f; + else reg |= 0x10; + WriteTandyACTL(reg+0x10,val); + break; + case M_TANDY4: { + if (CurMode->mode!=0x0a) { + // Palette values are kept constand by the BIOS. + // The four colors are mapped to special palette values by hardware. + // 3D8/3D9 registers influence this mapping. We need to figure out + // which entry is used for the requested color. + if (reg > 3) break; + if (reg != 0) { // 0 is assumed to be at 0 + Bit8u color_select=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL); + reg = reg*2+8; // Green Red Brown + if (color_select& 0x20) reg++; // Cyan Magenta White + } + WriteTandyACTL(reg+0x10,val); + } + // 4-color high resolution mode 0x0a isn't handled specially + else WriteTandyACTL(reg+0x10,val); + break; + } + default: + WriteTandyACTL(reg+0x10,val); + break; + } + IO_Write(0x3da,0x0); // palette back on break; case EGAVGA_ARCH_CASE: if (!IS_VGA_ARCH) reg&=0x1f; @@ -266,14 +301,24 @@ void INT10_SetPelMask(Bit8u mask) { void INT10_GetPelMask(Bit8u & mask) { mask=IO_Read(VGAREG_PEL_MASK); -} +} void INT10_SetBackgroundBorder(Bit8u val) { - Bit8u temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL); - temp=(temp & 0xe0) | (val & 0x1f); - real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp); - if (machine == MCH_CGA || IS_TANDY_ARCH) - IO_Write(0x3d9,temp); + Bit8u color_select=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL); + color_select=(color_select & 0xe0) | (val & 0x1f); + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select); + + if (machine == MCH_CGA || machine == MCH_TANDY) + IO_Write(0x3d9,color_select); + else if (machine == MCH_PCJR) { + IO_Read(VGAREG_TDY_RESET); // reset the flipflop + if (vga.mode!=M_TANDY_TEXT) { + IO_Write(VGAREG_TDY_ADDRESS, 0x10); + IO_Write(VGAREG_PCJR_DATA, color_select&0xf); + } + IO_Write(VGAREG_TDY_ADDRESS, 0x2); // border color + IO_Write(VGAREG_PCJR_DATA, color_select&0xf); + } else if (IS_EGAVGA_ARCH) { val = ((val << 1) & 0x10) | (val & 0x7); /* Aways set the overscan color */ @@ -282,7 +327,7 @@ void INT10_SetBackgroundBorder(Bit8u val) { if (CurMode->mode <= 3) return; INT10_SetSinglePaletteRegister( 0, val ); - val = (temp & 0x10) | 2 | ((temp & 0x20) >> 5); + val = (color_select & 0x10) | 2 | ((color_select & 0x20) >> 5); INT10_SetSinglePaletteRegister( 1, val ); val+=2; INT10_SetSinglePaletteRegister( 2, val ); @@ -295,8 +340,31 @@ void INT10_SetColorSelect(Bit8u val) { Bit8u temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL); temp=(temp & 0xdf) | ((val & 1) ? 0x20 : 0x0); real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp); - if (machine == MCH_CGA || IS_TANDY_ARCH) + if (machine == MCH_CGA || machine==MCH_TANDY) IO_Write(0x3d9,temp); + else if (machine == MCH_PCJR) { + switch(vga.mode) { + case M_TANDY2: + IO_Write(VGAREG_TDY_ADDRESS, 0x11); + IO_Write(VGAREG_PCJR_DATA, val&1? 0xf:0); + break; + case M_TANDY4: + for(Bit8u i = 0x11; i < 0x14; i++) { + const Bit8u t4_table[] = {0,2,4,6, 0,3,5,0xf}; + IO_Write(VGAREG_TDY_ADDRESS, i); + IO_Write(VGAREG_PCJR_DATA, t4_table[(i-0x10)+(val&1? 4:0)]); + } + break; + default: + // 16-color modes: always write the same palette + for(Bit8u i = 0x11; i < 0x20; i++) { + IO_Write(VGAREG_TDY_ADDRESS, i); + IO_Write(VGAREG_PCJR_DATA, i-0x10); + } + break; + } + IO_Write(VGAREG_TDY_ADDRESS, 0); // enable palette + } else if (IS_EGAVGA_ARCH) { if (CurMode->mode <= 3) //Maybe even skip the total function! return; From eff418eaeebfb82dff169af89da355701e704231 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Mon, 4 Oct 2010 21:46:23 +0000 Subject: [PATCH 3558/4131] - Use temporary storage for linear scanline, fixes corruption in Fractint SVGA modes - Implement wrapping on lower-order bit, fixes black line in Titan Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3648 --- src/hardware/vga_draw.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 494a2b34..72c7df35 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -175,12 +175,28 @@ static Bit8u * VGA_Draw_Changes_Line(Bitu vidstart, Bitu line) { #endif static Bit8u * VGA_Draw_Linear_Line(Bitu vidstart, Bitu /*line*/) { -// There is guaranteed extra memory past the wrap boundary. So, instead of using temporary -// storage just copy appropriate chunk from the beginning to the wrap boundary when needed. Bitu offset = vidstart & vga.draw.linear_mask; - if (vga.draw.linear_mask-offset < vga.draw.line_length) - memcpy(vga.draw.linear_base+vga.draw.linear_mask+1, vga.draw.linear_base, vga.draw.line_length); - Bit8u *ret = &vga.draw.linear_base[ offset ]; + Bit8u* ret = &vga.draw.linear_base[offset]; + + // in case (vga.draw.line_length + offset) has bits set that + // are not set in the mask: ((x|y)!=y) equals (x&~y) + if (GCC_UNLIKELY((vga.draw.line_length + offset)& ~vga.draw.linear_mask)) { + // this happens, if at all, only once per frame (1 of 480 lines) + // in some obscure games + Bitu end = (offset + vga.draw.line_length) & vga.draw.linear_mask; + + // assuming lines not longer than 4096 pixels + Bitu wrapped_len = end & 0xFFF; + Bitu unwrapped_len = vga.draw.line_length-wrapped_len; + + // unwrapped chunk: to top of memory block + memcpy(TempLine, &vga.draw.linear_base[offset], unwrapped_len); + // wrapped chunk: from base of memory block + memcpy(&TempLine[unwrapped_len], vga.draw.linear_base, wrapped_len); + + ret = TempLine; + } + #if !defined(C_UNALIGNED_MEMORY) if (GCC_UNLIKELY( ((Bitu)ret) & (sizeof(Bitu)-1)) ) { memcpy( TempLine, ret, vga.draw.line_length ); From 2a8b0b397f4154d400c2c5629cb7106c4ae90276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 9 Oct 2010 13:49:48 +0000 Subject: [PATCH 3559/4131] fix dimul flags calculation for corner cases (thanks to bavi) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3649 --- src/cpu/instructions.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 1696997c..da82ec4a 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -798,7 +798,7 @@ Bits res=((Bit16s)op2) * ((Bit16s)op3); \ save(op1,res & 0xffff); \ FillFlagsNoCFOF(); \ - if ((res> -32768) && (res<32767)) { \ + if ((res>= -32768) && (res<=32767)) { \ SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ } else { \ SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ @@ -810,8 +810,8 @@ Bit64s res=((Bit64s)((Bit32s)op2))*((Bit64s)((Bit32s)op3)); \ save(op1,(Bit32s)res); \ FillFlagsNoCFOF(); \ - if ((res>-((Bit64s)(2147483647)+1)) && \ - (res<(Bit64s)2147483647)) { \ + if ((res>=-((Bit64s)(2147483647)+1)) && \ + (res<=(Bit64s)2147483647)) { \ SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ } else { \ SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ From 0d7b792d05c5b93e672a57d84cdba3866be7481f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 18 Oct 2010 13:49:31 +0000 Subject: [PATCH 3560/4131] Check return code of SDL_LockYUVOverlay. Should fix some rare crashes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3650 --- src/gui/sdlmain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 1d004176..803a12f4 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -727,7 +727,7 @@ bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) { return true; #endif case SCREEN_OVERLAY: - SDL_LockYUVOverlay(sdl.overlay); + if (SDL_LockYUVOverlay(sdl.overlay)) return false; pixels=(Bit8u *)*(sdl.overlay->pixels); pitch=*(sdl.overlay->pitches); sdl.updating=true; From 143beec6b12b947fb983be54f78952144ab7fe6d Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Thu, 28 Oct 2010 17:35:45 +0000 Subject: [PATCH 3561/4131] Add new features to the config command for control of the config file: - manipulate the autoexec section - display information on sections and values - show the used config files and startup command line parameters - restart capability - save config files either in the config or program directory Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3651 --- README | 89 +++++- include/control.h | 9 +- include/cross.h | 1 + include/mapper.h | 2 +- include/programs.h | 2 + include/setup.h | 40 +-- src/debug/debug.cpp | 2 +- src/dosbox.cpp | 18 +- src/gui/sdl_gui.cpp | 2 +- src/gui/sdl_mapper.cpp | 3 + src/gui/sdlmain.cpp | 66 +++-- src/misc/cross.cpp | 13 + src/misc/messages.cpp | 5 +- src/misc/programs.cpp | 627 ++++++++++++++++++++++++++++++++--------- src/misc/setup.cpp | 216 ++++++++++---- 15 files changed, 847 insertions(+), 248 deletions(-) diff --git a/README b/README index 7302d250..b8793b92 100644 --- a/README +++ b/README @@ -622,7 +622,19 @@ VER set major_version [minor_version] CONFIG -writeconf filelocation +CONFIG -writeconf +CONFIG -wcp filelocation +CONFIG -wcd CONFIG -writelang filelocation +CONFIG -axadd +CONFIG -axclear +CONFIG -axtype +CONFIG -r [parameters] +CONFIG -l +CONFIG -help +CONFIG -help sections +CONFIG -help section +CONFIG -help section property CONFIG -securemode CONFIG -set "section property=value" CONFIG -get "section property" @@ -633,20 +645,74 @@ CONFIG -get "section property" be found in Section 13: "The configuration (options) file". -writeconf filelocation - Write the current configuration settings to a file in a specified location. - "filelocation" is located on the local drive, not a mounted drive in DOSBox. + (or -wc filelocation) + Write the current configuration settings to a file in a specified location + relative to the DOSBox config directory. Relative and absolute paths are + possible. "filelocation" is located on the local drive, not a mounted + drive in DOSBox. + The configuration file controls various settings of DOSBox: the amount of emulated memory, the emulated sound cards and many more things. It allows access to AUTOEXEC.BAT as well. See Section 13: "The configuration (options) file" for more information. + -writeconf + (or -wc) + Write the configuration to the primary loaded config file. + + -wcp filelocation + Write the current configuration settings to the specified file in or + relative to the DOSBox program start directory. Realtive and absolute + paths are possible. This is located on a drive on the host, not a mounted + drive in DOSBox. It is useful if you keep DOSBox on a removable media. + If file is omitted, the configuration will be written to dosbox.conf. + + -wcd + Write the current configuration to the default config file. + + -writelang filelocation + (or -wl filelocation) Write the current language settings to a file in a specified location. "filelocation" is located on the local drive, not a mounted drive in DOSBox. The language file controls all visible output of the internal commands and the internal DOS. See Section 14: "The Language File" for more information. + -axadd "line1" "line2" ... + Adds a command line to the autoexec section. + + -axclear + Clears the autoexec section. + + -axtype + Prints the content of the autoexec section. + + -r [parameters] + Restart DOSBox, either with the parameters that were used to start the + current instance or any that are appended. + + -l + lists DOSBox parameters: + - the configuration directory + - the config files that were used when starting this session + - the command line parameters DOSBox was started with + + -h, -help, -? + Displays an overvie of the config commands. + + -h, -help, -? sections + Displays the list of sections in the config file. + + -h, -help, -? section + Displays the list of properties contained in the specified section. + + -h, -help, -? section property + Shows information about the specified property in the specified section: + - purpose of the property + - possible values, current value, default value + - wether it can definitely not be changed at runtime + -securemode Switches DOSBox to a more secure mode. In this mode the internal commands MOUNT, IMGMOUNT and BOOT won't work. It's not possible either @@ -655,7 +721,6 @@ CONFIG -get "section property" -set "section property=value" CONFIG will attempt to set the property to new value. - Currently CONFIG can not report whether the command succeeded or not. -get "section property" The current value of the property is reported and stored in the @@ -675,7 +740,22 @@ CONFIG -get "section property" config -set "dos ems=false" 4. To check which cpu core is being used. config -get "cpu core" - + 5. To view the list of possible cpu cores: + config -help cpu core + 6. To change the machine type and restart: + config -set "machine cga" + config -wc -r + 7. To configure the autoexec section to auto-mount a directory at start: + config -axadd "mount c c:\dosgames" "c:" + config -wc + 8. To create a specific config file in the config directory: + config -set "dos ems=false" + config -set "cpu cycles=10000" + config -set "core dynamic" + config -axadd "mount c c:\dosgames" "c:" "cd my_game" "my_game" + config -wc my_config.conf + 9. To restart DOSBox from a specific config file in the config directory: + config -r -conf my_config.conf LOADFIX [-size] [program] [program-parameters] LOADFIX -f @@ -985,6 +1065,7 @@ CTRL-F10 Capture/Release the mouse. CTRL-F11 Slow down emulation (Decrease DOSBox Cycles). CTRL-F12 Speed up emulation (Increase DOSBox Cycles)*. ALT-F12 Unlock speed (turbo button/fast forward)**. +CTRL-ALT-HOME Restart DOSBox. F11, ALT-F11 (machine=cga) change tint in NTSC output modes*** F11 (machine=hercules) cycle through amber, green, white colouring*** diff --git a/include/control.h b/include/control.h index 0a688e14..2c157277 100644 --- a/include/control.h +++ b/include/control.h @@ -63,7 +63,14 @@ private: void (* _start_function)(void); bool secure_mode; //Sandbox mode public: - Config(CommandLine * cmd):cmdline(cmd),secure_mode(false){} + bool initialised; + std::vector startup_params; + std::vector configfiles; + Config(CommandLine * cmd):cmdline(cmd),secure_mode(false) { + startup_params.push_back(cmdline->GetFileName()); + cmdline->FillVector(startup_params); + initialised=false; + } ~Config(); Section_line * AddSection_line(char const * const _name,void (*_initfunction)(Section*)); diff --git a/include/cross.h b/include/cross.h index 8628beb3..8e2268d1 100644 --- a/include/cross.h +++ b/include/cross.h @@ -74,6 +74,7 @@ public: static void CreatePlatformConfigDir(std::string& in); static void ResolveHomedir(std::string & temp_line); static void CreateDir(std::string const& temp); + static bool Cross::IsPathAbsolute(std::string const& in); }; diff --git a/include/mapper.h b/include/mapper.h index 932f6563..a59322a8 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -21,7 +21,7 @@ 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 + MK_return,MK_kpminus,MK_scrolllock,MK_printscreen,MK_pause,MK_home }; diff --git a/include/programs.h b/include/programs.h index f8473850..96f84b0e 100644 --- a/include/programs.h +++ b/include/programs.h @@ -52,6 +52,8 @@ public: 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); + int GetParameterFromList(const char* const params[], std::vector & output); + void FillVector(std::vector & vector); unsigned int GetCount(void); void Shift(unsigned int amount=1); Bit16u Get_arglength(); diff --git a/include/setup.h b/include/setup.h index 5239cd5d..e79af711 100644 --- a/include/setup.h +++ b/include/setup.h @@ -104,18 +104,18 @@ public: 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); + bool 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); + bool set_hex(std::string const& in); + bool set_int(std::string const&in); + bool set_bool(std::string const& in); void set_string(std::string const& in); - void set_double(std::string const& in); + bool set_double(std::string const& in); }; class Property { @@ -127,7 +127,7 @@ public: 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; + virtual bool 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; @@ -135,10 +135,12 @@ public: //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;} + bool SetVal(Value const& in, bool forced,bool warn=true) { + if(forced || CheckValue(in,warn)) {value = in; return true;} else { value = default_value; return false;}} virtual ~Property(){ } virtual const std::vector& GetValues() const; Value::Etype Get_type(){return default_value.type;} + Changeable::Value getChange() {return change;} protected: Value value; @@ -161,8 +163,10 @@ public: min = _min; max = _max; } + int getMin() { return min;} + int getMax() { return max;} void SetMinMax(Value const& min,Value const& max) {this->min = min; this->max=max;} - void SetValue(std::string const& in); + bool SetValue(std::string const& in); ~Prop_int(){ } virtual bool CheckValue(Value const& in, bool warn); private: @@ -175,7 +179,7 @@ public: :Property(_propname,when){ default_value = value = _value; } - void SetValue(std::string const& input); + bool SetValue(std::string const& input); ~Prop_double(){ } }; @@ -185,7 +189,7 @@ public: :Property(_propname,when) { default_value = value = _value; } - void SetValue(std::string const& in); + bool SetValue(std::string const& in); ~Prop_bool(){ } }; @@ -195,7 +199,7 @@ public: :Property(_propname,when) { default_value = value = _value; } - void SetValue(std::string const& in); + bool SetValue(std::string const& in); virtual bool CheckValue(Value const& in, bool warn); ~Prop_string(){ } }; @@ -207,7 +211,7 @@ public: default_value = value = _value; realpath = _value; } - void SetValue(std::string const& in); + bool SetValue(std::string const& in); ~Prop_path(){ } }; @@ -217,7 +221,7 @@ public: :Property(_propname,when) { default_value = value = _value; } - void SetValue(std::string const& in); + bool SetValue(std::string const& in); ~Prop_hex(){ } }; @@ -248,7 +252,7 @@ public: 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 bool HandleInputline(std::string const& _line)=0; virtual void PrintData(FILE* outfile) const =0; virtual ~Section() { /*Children must call executedestroy ! */} }; @@ -281,7 +285,7 @@ public: 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); + bool 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 @@ -299,7 +303,7 @@ public: } Section_prop *GetSection() { return section; } const Section_prop *GetSection() const { return section; } - virtual void SetValue(std::string const& input); + virtual bool SetValue(std::string const& input); virtual const std::vector& GetValues() const; ~Prop_multival() { delete section; } }; //value bevat totale string. setvalue zet elk van de sub properties en checked die. @@ -308,7 +312,7 @@ 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); + virtual bool SetValue(std::string const& input); }; @@ -316,7 +320,7 @@ class Section_line: public Section{ public: Section_line(std::string const& _sectionname):Section(_sectionname){} ~Section_line(){ExecuteDestroy(true);} - void HandleInputline(std::string const& gegevens); + bool HandleInputline(std::string const& gegevens); void PrintData(FILE* outfile) const; virtual std::string GetPropValue(std::string const& _property) const; std::string data; diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 5b165de5..ae573722 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -2113,7 +2113,7 @@ void DEBUG_SetupConsole(void) { DBGUI_StartUp(); } -static void DEBUG_ShutDown(Section * /*sec*/) { +void DEBUG_ShutDown(Section * /*sec*/) { CBreakpoint::DeleteAll(); CDebugVar::DeleteAll(); curs_set(old_cursor_state); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index e12c9b79..e1b5ed8d 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -340,7 +340,7 @@ void DOSBOX_Init(void) { Pstring = secprop->Add_string("machine",Property::Changeable::OnlyAtStart,"svga_s3"); Pstring->Set_values(machines); - Pstring->Set_help("The type of machine tries to emulate."); + Pstring->Set_help("The type of machine DOSBox tries to emulate."); Pstring = secprop->Add_path("captures",Property::Changeable::Always,"capture"); Pstring->Set_help("Directory where things like wave, midi, screenshot get captured."); @@ -376,8 +376,8 @@ void DOSBOX_Init(void) { Pmulti = secprop->Add_multi("scaler",Property::Changeable::Always," "); Pmulti->SetValue("normal2x"); - Pmulti->Set_help("Scaler used to enlarge/enhance low resolution modes.\n" - " If 'forced' is appended, then the scaler will be used even if the result might not be desired."); + Pmulti->Set_help("Scaler used to enlarge/enhance low resolution modes. If 'forced' is appended,\n" + "then the scaler will be used even if the result might not be desired."); Pstring = Pmulti->GetSection()->Add_string("type",Property::Changeable::Always,"normal2x"); const char *scalers[] = { @@ -403,7 +403,8 @@ void DOSBOX_Init(void) { "normal", "simple",0 }; Pstring = secprop->Add_string("core",Property::Changeable::WhenIdle,"auto"); Pstring->Set_values(cores); - Pstring->Set_help("CPU Core used in emulation. auto will switch to dynamic if available and appropriate."); + Pstring->Set_help("CPU Core used in emulation. auto will switch to dynamic if available and\n" + "appropriate."); const char* cputype_values[] = { "auto", "386", "386_slow", "486_slow", "pentium_slow", "386_prefetch", 0}; Pstring = secprop->Add_string("cputype",Property::Changeable::Always,"auto"); @@ -418,9 +419,10 @@ void DOSBOX_Init(void) { "Cycles can be set in 3 ways:\n" " 'auto' tries to guess what a game needs.\n" " It usually works, but can fail for certain games.\n" - " 'fixed #number' will set a fixed amount of cycles. This is what you usually need if 'auto' fails.\n" - " (Example: fixed 4000).\n" - " 'max' will allocate as much cycles as your computer is able to handle.\n"); + " 'fixed #number' will set a fixed amount of cycles. This is what you usually\n" + " need if 'auto' fails (Example: fixed 4000).\n" + " 'max' will allocate as much cycles as your computer is able to\n" + " handle."); const char* cyclest[] = { "auto","fixed","max","%u",0 }; Pstring = Pmulti_remain->GetSection()->Add_string("type",Property::Changeable::Always,"auto"); @@ -431,7 +433,7 @@ void DOSBOX_Init(void) { Pint = secprop->Add_int("cycleup",Property::Changeable::Always,10); Pint->SetMinMax(1,1000000); - Pint->Set_help("Amount of cycles to decrease/increase with keycombo.(CTRL-F11/CTRL-F12)"); + Pint->Set_help("Amount of cycles to decrease/increase with keycombos.(CTRL-F11/CTRL-F12)"); Pint = secprop->Add_int("cycledown",Property::Changeable::Always,20); Pint->SetMinMax(1,1000000); diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index d5d746eb..6258118a 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -40,7 +40,7 @@ extern Bit8u int10_font_14[256 * 14]; extern Program * first_shell; -extern void MSG_Write(const char *); +extern bool MSG_Write(const char *); extern void GFX_SetTitle(Bit32s cycles, Bits frameskip, bool paused); static int cursor, saved_bpp; diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index c905c052..ea541796 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -1584,6 +1584,9 @@ public: case MK_printscreen: key=SDLK_PRINT; break; + case MK_home: + key=SDLK_HOME; + break; } sprintf(buf,"%s \"key %d%s%s%s\"", entry, diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 803a12f4..b5cdd332 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -989,6 +989,8 @@ static unsigned char logo[32*32*4]= { #include "dosbox_splash.h" //extern void UI_Run(bool); +void Restart(bool pressed); + static void GUI_StartUp(Section * sec) { sec->AddDestroyFunction(&GUI_ShutDown); Section_prop * section=static_cast(sec); @@ -1234,6 +1236,7 @@ static void GUI_StartUp(Section * sec) { MAPPER_AddHandler(KillSwitch,MK_f9,MMOD1,"shutdown","ShutDown"); MAPPER_AddHandler(CaptureMouse,MK_f10,MMOD1,"capmouse","Cap Mouse"); MAPPER_AddHandler(SwitchFullScreen,MK_return,MMOD2,"fullscr","Fullscreen"); + MAPPER_AddHandler(Restart,MK_home,MMOD1|MMOD2,"restart","Restart"); #if C_DEBUG /* Pause binds with activate-debugger */ #else @@ -1586,6 +1589,32 @@ static void launcheditor() { printf("can't find editor(s) specified at the command line.\n"); exit(1); } +#if C_DEBUG +extern void DEBUG_ShutDown(Section * /*sec*/); +#endif + +void restart_program(std::vector & parameters) { + char** newargs = new char* [parameters.size()+1]; + // parameter 0 is the executable path + // contents of the vector follow + // last one is NULL + for(Bitu i = 0; i < parameters.size(); i++) newargs[i]=(char*)parameters[i].c_str(); + newargs[parameters.size()] = NULL; + SDL_CloseAudio(); + SDL_Delay(50); + SDL_Quit(); +#if C_DEBUG + // shutdown curses + DEBUG_ShutDown(NULL); +#endif + + execvp(newargs[0], newargs); + free(newargs); +} +void Restart(bool pressed) { // mapper handler + restart_program(control->startup_params); +} + static void launchcaptures(std::string const& edit) { std::string path,file; Section* t = control->GetSection("dosbox"); @@ -1790,15 +1819,16 @@ int main(int argc, char* argv[]) { /* Parse configuration files */ std::string config_file,config_path; - bool parsed_anyconfigfile = false; - //First Parse -userconf + Cross::GetPlatformConfigDir(config_path); + + //First parse -userconf if(control->cmdline->FindExist("-userconf",true)){ config_file.clear(); Cross::GetPlatformConfigDir(config_path); Cross::GetPlatformConfigName(config_file); config_path += config_file; - if(control->ParseConfigFile(config_path.c_str())) parsed_anyconfigfile = true; - if(!parsed_anyconfigfile) { + control->ParseConfigFile(config_path.c_str()); + if(!control->configfiles.size()) { //Try to create the userlevel configfile. config_file.clear(); Cross::CreatePlatformConfigDir(config_path); @@ -1807,29 +1837,29 @@ int main(int argc, char* argv[]) { if(control->PrintConfig(config_path.c_str())) { LOG_MSG("CONFIG: Generating default configuration.\nWriting it to %s",config_path.c_str()); //Load them as well. Makes relative paths much easier - if(control->ParseConfigFile(config_path.c_str())) parsed_anyconfigfile = true; + control->ParseConfigFile(config_path.c_str()); } } } - //Second parse -conf entries - while(control->cmdline->FindString("-conf",config_file,true)) - if (control->ParseConfigFile(config_file.c_str())) parsed_anyconfigfile = true; + //Second parse -conf switches + while(control->cmdline->FindString("-conf",config_file,true)) { + if(!control->ParseConfigFile(config_file.c_str())) { + // try to load it from the user directory + control->ParseConfigFile((config_path + config_file).c_str()); + } + } + // if none found => parse localdir conf + if(!control->configfiles.size()) control->ParseConfigFile("dosbox.conf"); - //if none found => parse localdir conf - config_file = "dosbox.conf"; - if (!parsed_anyconfigfile && control->ParseConfigFile(config_file.c_str())) parsed_anyconfigfile = true; - - //if none found => parse userlevel conf - if(!parsed_anyconfigfile) { + // if none found => parse userlevel conf + if(!control->configfiles.size()) { config_file.clear(); - Cross::GetPlatformConfigDir(config_path); Cross::GetPlatformConfigName(config_file); - config_path += config_file; - if(control->ParseConfigFile(config_path.c_str())) parsed_anyconfigfile = true; + control->ParseConfigFile((config_path + config_file).c_str()); } - if(!parsed_anyconfigfile) { + if(!control->configfiles.size()) { //Try to create the userlevel configfile. config_file.clear(); Cross::CreatePlatformConfigDir(config_path); diff --git a/src/misc/cross.cpp b/src/misc/cross.cpp index bc4557e4..4d56293a 100644 --- a/src/misc/cross.cpp +++ b/src/misc/cross.cpp @@ -122,6 +122,19 @@ void Cross::CreateDir(std::string const& in) { #endif } +bool Cross::IsPathAbsolute(std::string const& in) { + // Absolute paths +#if defined (WIN32) || defined(OS2) + // drive letter + if (in.size() > 2 && in[1] == ':' ) return true; + // UNC path + else if (in.size() > 2 && in[0]=='\\' && in[1]=='\\') return true; +#else + if (in.size() > 1 && in[0] == '/' ) return true; +#endif + return false; +} + #if defined (WIN32) dir_information* open_directory(const char* dirname) { diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index b253d792..d6d7c6f9 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -124,13 +124,14 @@ const char * MSG_Get(char const * msg) { } -void MSG_Write(const char * location) { +bool MSG_Write(const char * location) { FILE* out=fopen(location,"w+t"); - if(out==NULL) return;//maybe an error? + if(out==NULL) return false;//maybe an error? for(itmb tel=Lang.begin();tel!=Lang.end();tel++){ fprintf(out,":%s\n%s\n.\n",(*tel).name.c_str(),(*tel).val.c_str()); } fclose(out); + return true; } void MSG_Init(Section_prop * section) { diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index f88f06ee..724d6a9b 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -19,6 +19,7 @@ /* $Id: programs.cpp,v 1.37 2009-05-27 09:15:42 qbix79 Exp $ */ #include +#include #include #include #include @@ -78,7 +79,7 @@ static Bitu PROGRAMS_Handler(void) { HostPt writer=(HostPt)&index; for (;size>0;size--) *writer++=mem_readb(reader++); Program * new_program; - if(index > internal_progs.size()) E_Exit("something is messing with the memory"); + if (index > internal_progs.size()) E_Exit("something is messing with the memory"); PROGRAMS_Main * handler = internal_progs[index]; (*handler)(&new_program); new_program->Run(); @@ -120,7 +121,7 @@ void Program::ChangeToLongCmd() { * Length of arguments can be ~120. but switch when above 100 to be sure */ - if(/*control->SecureMode() ||*/ cmd->Get_arglength() > 100) { + if (/*control->SecureMode() ||*/ cmd->Get_arglength() > 100) { CommandLine* temp = new CommandLine(cmd->GetFileName(),full_arguments.c_str()); delete cmd; cmd = temp; @@ -139,7 +140,7 @@ void Program::WriteOut(const char * format,...) { Bit16u size = (Bit16u)strlen(buf); for(Bit16u i = 0; i < size;i++) { Bit8u out;Bit16u s=1; - if(buf[i] == 0xA && i > 0 && buf[i-1] !=0xD) { + if (buf[i] == 0xA && i > 0 && buf[i-1] !=0xD) { out = 0xD;DOS_WriteFile(STDOUT,&out,&s); } out = buf[i]; @@ -154,7 +155,7 @@ void Program::WriteOut_NoParsing(const char * format) { char const* buf = format; for(Bit16u i = 0; i < size;i++) { Bit8u out;Bit16u s=1; - if(buf[i] == 0xA && i > 0 && buf[i-1] !=0xD) { + if (buf[i] == 0xA && i > 0 && buf[i-1] !=0xD) { out = 0xD;DOS_WriteFile(STDOUT,&out,&s); } out = buf[i]; @@ -243,149 +244,457 @@ bool Program::SetEnv(const char * entry,const char * new_string) { return true; } +bool MSG_Write(const char *); +void restart_program(std::vector & parameters); + class CONFIG : public Program { public: void Run(void); -}; - -void MSG_Write(const char *); - -void CONFIG::Run(void) { - FILE * f; - if (cmd->FindString("-writeconf",temp_line,true) - || cmd->FindString("-wc",temp_line,true)) { - /* In secure mode don't allow a new configfile to be created */ - if(control->SecureMode()) { - WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW")); - return; +private: + void restart(const char* useconfig); + + void writeconf(std::string name, bool configdir) { + if (configdir) { + // write file to the default config directory + std::string config_path; + Cross::GetPlatformConfigDir(config_path); + name = config_path + name; } - f=fopen(temp_line.c_str(),"wb+"); - if (!f) { - WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str()); - return; + WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_WHICH"),name.c_str()); + if (!control->PrintConfig(name.c_str())) { + WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),name.c_str()); } - fclose(f); - control->PrintConfig(temp_line.c_str()); return; } - if (cmd->FindString("-writelang",temp_line,true) - ||cmd->FindString("-wl",temp_line,true)) { - /* In secure mode don't allow a new languagefile to be created - * Who knows which kind of file we would overwriting. */ - if(control->SecureMode()) { - WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW")); - return; - } - f=fopen(temp_line.c_str(),"wb+"); - if (!f) { - WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str()); - return; - } - fclose(f); - MSG_Write(temp_line.c_str()); - return; - } - - /* Code for switching to secure mode */ - if(cmd->FindExist("-securemode",true)) { - control->SwitchToSecureMode(); - WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_ON")); - return; - } - - /* Code for getting the current configuration. * - * Official format: config -get "section property" * - * As a bonus it will set %CONFIG% to this value as well */ - if(cmd->FindString("-get",temp_line,true)) { - std::string temp2 = ""; - cmd->GetStringRemain(temp2);//So -get n1 n2= can be used without quotes - if(temp2 != "") temp_line = temp_line + " " + temp2; - - std::string::size_type space = temp_line.find(" "); - if(space == std::string::npos) { - WriteOut(MSG_Get("PROGRAM_CONFIG_GET_SYNTAX")); - return; - } - //Copy the found property to a new string and erase from templine (mind the space) - std::string prop = temp_line.substr(space+1); temp_line.erase(space); - - Section* sec = control->GetSection(temp_line.c_str()); - if(!sec) { - WriteOut(MSG_Get("PROGRAM_CONFIG_SECTION_ERROR"),temp_line.c_str()); - return; - } - std::string val = sec->GetPropValue(prop.c_str()); - if(val == NO_SUCH_PROPERTY) { - WriteOut(MSG_Get("PROGRAM_CONFIG_NO_PROPERTY"),prop.c_str(),temp_line.c_str()); - return; - } - WriteOut("%s",val.c_str()); - first_shell->SetEnv("CONFIG",val.c_str()); - return; - } - - - - /* Code for the configuration changes * - * Official format: config -set "section property=value" * - * Accepted: without quotes and/or without -set and/or without section * - * and/or the "=" replaced by a " " */ - - if (cmd->FindString("-set",temp_line,true)) { //get all arguments - std::string temp2 = ""; - cmd->GetStringRemain(temp2);//So -set n1 n2=n3 can be used without quotes - if(temp2!="") temp_line = temp_line + " " + temp2; - } else if(!cmd->GetStringRemain(temp_line)) {//no set - WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE")); //and no arguments specified - return; - }; - //Wanted input: n1 n2=n3 - char copy[1024]; - strcpy(copy,temp_line.c_str()); - //seperate section from property - const char* temp = strchr(copy,' '); - if((temp && *temp) || (temp=strchr(copy,'=')) ) copy[temp++ - copy]= 0; - else { - WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE")); - return; - } - //if n1 n2 n3 then replace last space with = - const char* sign = strchr(temp,'='); - if(!sign) { - sign = strchr(temp,' '); - if(sign) { - copy[sign - copy] = '='; - } else { - //2 items specified (no space nor = between n2 and n3 - //assume that they posted: property value - //Try to determine the section. - Section* sec=control->GetSectionFromProperty(copy); - if(!sec){ - if(control->GetSectionFromProperty(temp)) return; //Weird situation:ignore - WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR"),copy); - return; - } //Hack to allow config ems true - char buffer[1024];strcpy(buffer,copy);strcat(buffer,"=");strcat(buffer,temp); - sign = strchr(buffer,' '); - if(sign) buffer[sign - buffer] = '='; - strcpy(copy,sec->GetName()); - temp = buffer; - } - } - /* Input processed. Now the real job starts - * copy contains the likely "sectionname" - * temp contains "property=value" - * the section is destroyed and a new input line is given to - * the configuration parser. Then the section is restarted. - */ - char* inputline = const_cast(temp); - Section* sec = 0; - sec = control->GetSection(copy); - if(!sec) { WriteOut(MSG_Get("PROGRAM_CONFIG_SECTION_ERROR"),copy);return;} - sec->ExecuteDestroy(false); - sec->HandleInputline(inputline); - sec->ExecuteInit(false); + bool securemode_check() { + if (control->SecureMode()) { + WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW")); + return true; + } + return false; + } +}; + +void CONFIG::Run(void) { + static const char* const params[] = { + "-r", "-wcp", "-wcd", "-wc", "-writeconf", "-l", "-rmconf", + "-h", "-help", "-?", "-axclear", "-axadd", "-axtype", "-get", "-set", + "-writelang", "-wl", "-securemode", "" }; + enum prs { + P_NOMATCH, P_NOPARAMS, // fixed return values for GetParameterFromList + P_RESTART, + P_WRITECONF_PORTABLE, P_WRITECONF_DEFAULT, P_WRITECONF, P_WRITECONF2, + P_LISTCONF, P_KILLCONF, + P_HELP, P_HELP2, P_HELP3, + P_AUTOEXEC_CLEAR, P_AUTOEXEC_ADD, P_AUTOEXEC_TYPE, + P_GETPROP, P_SETPROP, + P_WRITELANG, P_WRITELANG2, + P_SECURE + } presult = P_NOMATCH; + + bool first = true; + std::vector pvars; + while(presult != P_NOPARAMS) { + presult = (enum prs)cmd->GetParameterFromList(params, pvars); + switch(presult) { + + case P_RESTART: + if (securemode_check()) return; + if (pvars.size() == 0) restart_program(control->startup_params); + else { + std::vector restart_params; + restart_params.push_back(control->cmdline->GetFileName()); + for(size_t i = 0; i < pvars.size(); i++) { + restart_params.push_back(pvars[i]); + if (pvars[i].find(' ') != std::string::npos) { + pvars[i] = "\""+pvars[i]+"\""; // add back spaces + } + } + // the rest on the commandline, too + cmd->FillVector(restart_params); + restart_program(restart_params); + } + return; + + case P_LISTCONF: { + Bitu size = control->configfiles.size(); + std::string config_path; + Cross::GetPlatformConfigDir(config_path); + WriteOut(MSG_Get("PROGRAM_CONFIG_CONFDIR"), VERSION,config_path.c_str()); + if (size==0) WriteOut(MSG_Get("PROGRAM_CONFIG_NOCONFIGFILE")); + else { + WriteOut(MSG_Get("PROGRAM_CONFIG_PRIMARY_CONF"),control->configfiles.front().c_str()); + if (size > 1) { + WriteOut(MSG_Get("PROGRAM_CONFIG_ADDITIONAL_CONF")); + for(Bitu i = 1; i < size; i++) + WriteOut("%s\n",control->configfiles[i].c_str()); + } + } + if (control->startup_params.size() > 0) { + std::string test; + for(size_t k = 0; k < control->startup_params.size(); k++) + test += control->startup_params[k] + " "; + WriteOut(MSG_Get("PROGRAM_CONFIG_PRINT_STARTUP"), test.c_str()); + } + break; + } + case P_WRITECONF: case P_WRITECONF2: + if (securemode_check()) return; + if (pvars.size() > 1) return; + else if (pvars.size() == 1) { + // write config to specific file, except if it is an absolute path + writeconf(pvars[0], !Cross::IsPathAbsolute(pvars[0])); + } else { + // -wc without parameter: write primary config file + if (control->configfiles.size()) writeconf(control->configfiles[0], false); + else WriteOut(MSG_Get("PROGRAM_CONFIG_NOCONFIGFILE")); + } + break; + case P_WRITECONF_DEFAULT: { + // write to /userdir/dosbox0.xx.conf + if (securemode_check()) return; + if (pvars.size() > 0) return; + std::string confname; + Cross::GetPlatformConfigName(confname); + writeconf(confname, true); + break; + } + case P_WRITECONF_PORTABLE: + if (securemode_check()) return; + if (pvars.size() > 1) return; + else if (pvars.size() == 1) { + // write config to startup directory + writeconf(pvars[0], false); + } else { + // -wcp without parameter: write dosbox.conf to startup directory + if (control->configfiles.size()) writeconf(std::string("dosbox.conf"), false); + else WriteOut(MSG_Get("PROGRAM_CONFIG_NOCONFIGFILE")); + } + break; + + case P_NOPARAMS: + if (!first) break; + + case P_HELP: case P_HELP2: case P_HELP3: { + switch(pvars.size()) { + case 0: + WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE")); + return; + case 1: { + if (!strcasecmp("sections",pvars[0].c_str())) { + // list the sections + WriteOut(MSG_Get("PROGRAM_CONFIG_HLP_SECTLIST")); + Bitu i = 0; + while(true) { + Section* sec = control->GetSection(i++); + if (!sec) break; + WriteOut("%s\n",sec->GetName()); + } + return; + } + // if it's a section, leave it as one-param + Section* sec = control->GetSection(pvars[0].c_str()); + if (!sec) { + // could be a property + sec = control->GetSectionFromProperty(pvars[0].c_str()); + if (!sec) { + WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR")); + return; + } + pvars.insert(pvars.begin(),std::string(sec->GetName())); + } + break; + } + case 2: { + // sanity check + Section* sec = control->GetSection(pvars[0].c_str()); + Section* sec2 = control->GetSectionFromProperty(pvars[1].c_str()); + if (sec != sec2) { + WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR")); + } + break; + } + default: + WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE")); + return; + } + // if we have one value in pvars, it's a section + // two values are section + property + Section* sec = control->GetSection(pvars[0].c_str()); + if (sec==NULL) { + WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR")); + return; + } + Section_prop* psec = dynamic_cast (sec); + if (psec==NULL) { + // failed; maybe it's the autoexec section? + Section_line* pline = dynamic_cast (sec); + if (pline==NULL) E_Exit("Section dynamic cast failed."); + + WriteOut(MSG_Get("PROGRAM_CONFIG_HLP_LINEHLP"), + pline->GetName(), + // this is 'unclean' but the autoexec section has no help associated + MSG_Get("AUTOEXEC_CONFIGFILE_HELP"), + pline->data.c_str() ); + return; + } + if (pvars.size()==1) { + size_t i = 0; + WriteOut(MSG_Get("PROGRAM_CONFIG_HLP_SECTHLP"),pvars[0].c_str()); + while(true) { + // list the properties + Property* p = psec->Get_prop(i++); + if (p==NULL) break; + WriteOut("%s\n", p->propname.c_str()); + } + } else { + // find the property by it's name + size_t i = 0; + while (true) { + Property *p = psec->Get_prop(i++); + if (p==NULL) break; + if (!strcasecmp(p->propname.c_str(),pvars[1].c_str())) { + // found it; make the list of possible values + std::string propvalues; + std::vector pv = p->GetValues(); + + if (p->Get_type()==Value::Etype::V_BOOL) { + // possible values for boolean are true, false + propvalues += "true, false"; + } else if (p->Get_type()==Value::Etype::V_INT) { + // print min, max for integer values if used + Prop_int* pint = dynamic_cast (p); + if (pint==NULL) E_Exit("Int property dynamic cast failed."); + if (pint->getMin() != pint->getMax()) { + std::ostringstream oss; + oss << pint->getMin(); + oss << ".."; + oss << pint->getMax(); + propvalues += oss.str(); + } + } + for(Bitu k = 0; k < pv.size(); k++) { + if (pv[k].ToString() =="%u") + propvalues += MSG_Get("PROGRAM_CONFIG_HLP_POSINT"); + else propvalues += pv[k].ToString(); + if ((k+1) < pv.size()) propvalues += ", "; + } + + WriteOut(MSG_Get("PROGRAM_CONFIG_HLP_PROPHLP"), + p->propname.c_str(), + sec->GetName(), + p->Get_help(),propvalues.c_str(), + p->Get_Default_Value().ToString().c_str(), + p->GetValue().ToString().c_str()); + // print 'changability' + if (p->getChange()==Property::Changeable::OnlyAtStart) { + WriteOut(MSG_Get("PROGRAM_CONFIG_HLP_NOCHANGE")); + } + return; + } + } + break; + } + return; + } + case P_AUTOEXEC_CLEAR: { + Section_line* sec = dynamic_cast + (control->GetSection(std::string("autoexec"))); + sec->data.clear(); + break; + } + case P_AUTOEXEC_ADD: { + if (pvars.size() == 0) { + WriteOut(MSG_Get("PROGRAM_CONFIG_MISSINGPARAM")); + return; + } + Section_line* sec = dynamic_cast + (control->GetSection(std::string("autoexec"))); + + for(Bitu i = 0; i < pvars.size(); i++) sec->HandleInputline(pvars[i]); + break; + } + case P_AUTOEXEC_TYPE: { + Section_line* sec = dynamic_cast + (control->GetSection(std::string("autoexec"))); + WriteOut("\n%s",sec->data.c_str()); + break; + } + case P_GETPROP: { + // "section property" + // "property" + // "section" "property" + if (pvars.size()==0) { + WriteOut(MSG_Get("PROGRAM_CONFIG_GET_SYNTAX")); + return; + } + std::string::size_type spcpos = pvars[0].find_first_of(' '); + // split on the ' ' + if (spcpos != std::string::npos) { + pvars.insert(++pvars.begin(),pvars[0].substr(spcpos+1)); + pvars[0].erase(spcpos); + } + switch(pvars.size()) { + case 1: { + // property only + Section* sec = control->GetSectionFromProperty(pvars[0].c_str()); + if (!sec) { + WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR")); + return; + } + std::string val = sec->GetPropValue(pvars[0].c_str()); + WriteOut("%s",val.c_str()); + break; + } + case 2: { + // section + property + Section* sec = control->GetSection(pvars[0].c_str()); + if (!sec) { + WriteOut(MSG_Get("PROGRAM_CONFIG_SECTION_ERROR")); + return; + } + std::string val = sec->GetPropValue(pvars[1].c_str()); + if (val == NO_SUCH_PROPERTY) { + WriteOut(MSG_Get("PROGRAM_CONFIG_NO_PROPERTY"),pvars[1].c_str(),pvars[0].c_str()); + return; + } + WriteOut("%s",val.c_str()); + break; + } + } + return; + } + case P_SETPROP: case P_NOMATCH: { + // Code for the configuration changes + // Official format: config -set "section property=value" + // Accepted: with or without -set, + // "section property value" + // "section property=value" + // "property" "value" + // "section" "property=value" + // "section" "property=value" "value" "value" ... + // "section" "property" "value" "value" ... + // "section property" "value" "value" ... + // "property" "value" "value" ... + // "property=value" "value" "value" ... + + if (pvars.size()==0) { + WriteOut(MSG_Get("PROGRAM_CONFIG_SET_SYNTAX")); + return; + } + + // add rest of command + std::string rest; + if (cmd->GetStringRemain(rest)) pvars.push_back(rest); + + // attempt to split off the first word + std::string::size_type spcpos = pvars[0].find_first_of(' '); + std::string::size_type equpos = pvars[0].find_first_of('='); + + if ((equpos != std::string::npos) && + ((spcpos == std::string::npos) || (equpos < spcpos))) { + // If we have a '=' possibly before a ' ' split on the = + pvars.insert(++pvars.begin(),pvars[0].substr(equpos+1)); + pvars[0].erase(equpos); + // As we had a = the first thing must be a property now + Section* sec=control->GetSectionFromProperty(pvars[0].c_str()); + if (sec) pvars.insert(pvars.begin(),std::string(sec->GetName())); + else { + WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR")); + return; + } + // order in the vector should be ok now + } else { + if ((spcpos != std::string::npos) && + ((equpos == std::string::npos) || (spcpos < equpos))) { + // ' ' before a possible '=', split on the ' ' + pvars.insert(++pvars.begin(),pvars[0].substr(spcpos+1)); + pvars[0].erase(spcpos); + } + // check if the first parameter is a section or property + Section* sec = control->GetSection(pvars[0].c_str()); + if (!sec) { + // not a section: little duplicate from above + Section* sec=control->GetSectionFromProperty(pvars[0].c_str()); + if (sec) pvars.insert(pvars.begin(),std::string(sec->GetName())); + else { + WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR")); + return; + } + } else { + // first of pvars is most likely a section, but could still be gus + // have a look at the second parameter + if (pvars.size() < 2) { + WriteOut(MSG_Get("PROGRAM_CONFIG_SET_SYNTAX")); + return; + } + std::string::size_type spcpos2 = pvars[1].find_first_of(' '); + std::string::size_type equpos2 = pvars[1].find_first_of('='); + if ((equpos2 != std::string::npos) && + ((spcpos2 == std::string::npos) || (equpos2 < spcpos2))) { + // split on the = + pvars.insert(pvars.begin()+2,pvars[1].substr(equpos2+1)); + pvars[1].erase(equpos2); + } else if ((spcpos2 != std::string::npos) && + ((equpos2 == std::string::npos) || (spcpos2 < equpos2))) { + // split on the ' ' + pvars.insert(pvars.begin()+2,pvars[1].substr(spcpos2+1)); + pvars[1].erase(spcpos2); + } + // is this a property? + Section* sec2 = control->GetSectionFromProperty(pvars[1].c_str()); + if (!sec2) { + // not a property, + Section* sec3 = control->GetSectionFromProperty(pvars[0].c_str()); + if (sec3) { + // section and property name are identical + pvars.insert(pvars.begin(),pvars[0]); + } // else has been checked above already + } + } + } + // Input has been parsed (pvar[0]=section, [1]=property, [2]=value + // now execute + Section* tsec = control->GetSection(pvars[0]); + std::string value; + value += pvars[2]; + for(Bitu i = 3; i < pvars.size(); i++) value += (std::string(" ") + pvars[i]); + std::string inputline = pvars[1] + "=" + value; + + tsec->ExecuteDestroy(false); + bool change_success = tsec->HandleInputline(inputline.c_str()); + if (!change_success) WriteOut(MSG_Get("PROGRAM_CONFIG_VALUE_ERROR"), + value.c_str(),pvars[1].c_str()); + tsec->ExecuteInit(false); + return; + } + case P_WRITELANG: case P_WRITELANG2: + // In secure mode don't allow a new languagefile to be created + // Who knows which kind of file we would overwrite. + if (securemode_check()) return; + if (pvars.size() < 1) { + WriteOut(MSG_Get("PROGRAM_CONFIG_MISSINGPARAM")); + return; + } + if (!MSG_Write(pvars[0].c_str())) { + WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),pvars[0].c_str()); + return; + } + break; + + case P_SECURE: + // Code for switching to secure mode + control->SwitchToSecureMode(); + WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_ON")); + return; + + default: + E_Exit("bug"); + break; + } + first = false; + } return; } @@ -401,12 +710,48 @@ void PROGRAMS_Init(Section* /*sec*/) { CALLBACK_Setup(call_program,&PROGRAMS_Handler,CB_RETF,"internal program"); PROGRAMS_MakeFile("CONFIG.COM",CONFIG_ProgramStart); - MSG_Add("PROGRAM_CONFIG_FILE_ERROR","Can't open file %s\n"); - MSG_Add("PROGRAM_CONFIG_USAGE","Config tool:\nUse -writeconf filename to write the current config.\nUse -writelang filename to write the current language strings.\n"); + // listconf + MSG_Add("PROGRAM_CONFIG_NOCONFIGFILE","No config file loaded!\n"); + MSG_Add("PROGRAM_CONFIG_PRIMARY_CONF","Primary config file: \n%s\n"); + MSG_Add("PROGRAM_CONFIG_ADDITIONAL_CONF","Additional config files:\n"); + MSG_Add("PROGRAM_CONFIG_CONFDIR","DOSBox %s configuration directory: \n%s\n\n"); + + // writeconf + MSG_Add("PROGRAM_CONFIG_FILE_ERROR","\nCan't open file %s\n"); + MSG_Add("PROGRAM_CONFIG_FILE_WHICH","Writing config file %s"); + + // help + MSG_Add("PROGRAM_CONFIG_USAGE","Config tool:\n"\ + "-writeconf or -wc without parameter: write to primary loaded config file.\n"\ + "-writeconf or -wc with filename: write file to config directory.\n"\ + "Use -writelang or -wl filename to write the current language strings.\n"\ + "-r [parameters]\n Restart DOSBox, either using the previous parameters or any that are appended.\n"\ + "-wcp [filename]\n Write config file to the program directory, dosbox.conf or the specified \n filename.\n"\ + "-wcd\n Write to the default config file in the config directory.\n"\ + "-l lists configuration parameters.\n"\ + "-h, -help, -? sections / sectionname / propertyname\n"\ + " Without parameters, displays this help screen. Add \"sections\" for a list of\n sections."\ + " For info about a specific section or property add it's name behind.\n"\ + "-axclear clears the autoexec section.\n"\ + "-axadd [line] adds a line to the autoexec section.\n"\ + "-axtype prints the content of the autoexec section.\n"\ + "-securemode switches to secure mode.\n"\ + "-get \"section property\" returns the value of the property.\n"\ + "-set \"section property=value\" sets the value." ); + MSG_Add("PROGRAM_CONFIG_HLP_PROPHLP","Purpose of property \"%s\" (contained in section \"%s\"):\n%s\n\nPossible Values: %s\nDefault value: %s\nCurrent value: %s\n"); + MSG_Add("PROGRAM_CONFIG_HLP_LINEHLP","Purpose of section \"%s\":\n%s\nCurrent value:\n%s\n"); + MSG_Add("PROGRAM_CONFIG_HLP_NOCHANGE","This property cannot be changed at runtime.\n"); + MSG_Add("PROGRAM_CONFIG_HLP_POSINT","positive integer"); + MSG_Add("PROGRAM_CONFIG_HLP_SECTHLP","Section %s contains the following properties:\n"); + MSG_Add("PROGRAM_CONFIG_HLP_SECTLIST","DOSBox configuration contains the following sections:\n\n"); + MSG_Add("PROGRAM_CONFIG_SECURE_ON","Switched to secure mode.\n"); MSG_Add("PROGRAM_CONFIG_SECURE_DISALLOW","This operation is not permitted in secure mode.\n"); MSG_Add("PROGRAM_CONFIG_SECTION_ERROR","Section %s doesn't exist.\n"); + MSG_Add("PROGRAM_CONFIG_VALUE_ERROR","\"%s\" is not a valid value for property %s.\n"); MSG_Add("PROGRAM_CONFIG_PROPERTY_ERROR","No such section or property.\n"); MSG_Add("PROGRAM_CONFIG_NO_PROPERTY","There is no property %s in section %s.\n"); MSG_Add("PROGRAM_CONFIG_GET_SYNTAX","Correct syntax: config -get \"section property\".\n"); + MSG_Add("PROGRAM_CONFIG_PRINT_STARTUP","\nDOSBox was started with the following command line parameters:\n%s"); + MSG_Add("PROGRAM_CONFIG_MISSINGPARAM","Missing parameter."); } diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 6c383366..a0184b49 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -29,6 +29,8 @@ #include #include #include +#include +#include using namespace std; static std::string current_config_dir; // Set by parseconfigfile so Prop_path can use it to construct the realpath @@ -104,7 +106,7 @@ bool Value::operator==(Value const& other) { } return false; } -void Value::SetValue(string const& in,Etype _type) throw(WrongType) { +bool Value::SetValue(string const& in,Etype _type) throw(WrongType) { /* Throw exception if the current type isn't the wanted type * Unless the wanted type is current. */ @@ -113,21 +115,22 @@ void Value::SetValue(string const& in,Etype _type) throw(WrongType) { if(type != V_NONE && type != _type) throw WrongType(); type = _type; } + bool retval = true; switch(type){ case V_HEX: - set_hex(in); + retval = set_hex(in); break; case V_INT: - set_int(in); + retval = set_int(in); break; case V_BOOL: - set_bool(in); + retval = set_bool(in); break; case V_STRING: set_string(in); break; case V_DOUBLE: - set_double(in); + retval = set_double(in); break; case V_NONE: @@ -137,39 +140,51 @@ void Value::SetValue(string const& in,Etype _type) throw(WrongType) { throw WrongType(); break; } + return retval; } -void Value::set_hex(std::string const& in) { +bool Value::set_hex(std::string const& in) { istringstream input(in); input.flags(ios::hex); - int result = 0; + Bits result = INT_MIN; input >> result; + if(result == INT_MIN) return false; _hex = result; + return true; } -void Value::set_int(string const &in) { +bool Value::set_int(string const &in) { istringstream input(in); - int result = 0; + Bits result = INT_MIN; input >> result; + if(result == INT_MIN) return false; _int = result; + return true; } -void Value::set_double(string const &in) { +bool Value::set_double(string const &in) { istringstream input(in); - double result = 0; + double result = std::numeric_limits::infinity(); input >> result; + if(result == std::numeric_limits::infinity()) return false; _double = result; + return true; } -void Value::set_bool(string const &in) { +bool Value::set_bool(string const &in) { istringstream input(in); string result; input >> result; - _bool = true; lowcase(result); - /* valid false entries: 0 ,d*, f*, off everything else gets true */ - if( !result.size() ) return; - if(result[0] == '0' || result[0] == 'd' || result[0] == 'f' || result == "off") + _bool = true; // TODO + if(!result.size()) return false; + + if(result=="0" || result=="disabled" || result=="false" || result=="off") { _bool = false; + } else if(result=="1" || result=="enabled" || result=="true" || result=="on") { + _bool = true; + } else return false; + + return true; } void Value::set_string(string const & in) { @@ -242,27 +257,30 @@ bool Prop_int::CheckValue(Value const& in, bool warn) { return false; } -void Prop_double::SetValue(std::string const& input){ - Value val(input,Value::V_DOUBLE); - SetVal(val,false,true); +bool Prop_double::SetValue(std::string const& input){ + Value val; + if(!val.SetValue(input,Value::V_DOUBLE)) return false; + return SetVal(val,false,true); } //void Property::SetValue(char* input){ // value.SetValue(input, Value::V_CURRENT); //} -void Prop_int::SetValue(std::string const& input){; - Value val(input,Value::V_INT); - SetVal(val,false,true); +bool Prop_int::SetValue(std::string const& input){; + Value val; + if(!val.SetValue(input,Value::V_INT)) return false; + bool retval = SetVal(val,false,true); + return retval; } -void Prop_string::SetValue(std::string const& input){ +bool Prop_string::SetValue(std::string const& input){ //Special version for lowcase stuff std::string temp(input); //suggested values always case insensitive. //If there are none then it can be paths and such which are case sensitive if(!suggested_values.empty()) lowcase(temp); Value val(temp,Value::V_STRING); - SetVal(val,false,true); + return SetVal(val,false,true); } bool Prop_string::CheckValue(Value const& in, bool warn){ if(suggested_values.empty()) return true; @@ -281,15 +299,15 @@ bool Prop_string::CheckValue(Value const& in, bool warn){ return false; } -void Prop_path::SetValue(std::string const& input){ +bool Prop_path::SetValue(std::string const& input){ //Special version to merge realpath with it Value val(input,Value::V_STRING); - SetVal(val,false,true); + bool retval = SetVal(val,false,true); if(input.empty()) { realpath = ""; - return; + return false; } std::string workcopy(input); Cross::ResolveHomedir(workcopy); //Parse ~ and friends @@ -297,20 +315,18 @@ void Prop_path::SetValue(std::string const& input){ if( current_config_dir.empty()) realpath = workcopy; else realpath = current_config_dir + CROSS_FILESPLIT + workcopy; //Absolute paths -#if defined (WIN32) || defined(OS2) - if( workcopy.size() > 2 && workcopy[1] == ':' ) realpath = workcopy; -#else - if( workcopy.size() > 1 && workcopy[0] == '/' ) realpath = workcopy; -#endif + if (Cross::IsPathAbsolute(workcopy)) realpath = workcopy; + return retval; } -void Prop_bool::SetValue(std::string const& input){ - value.SetValue(input,Value::V_BOOL); +bool Prop_bool::SetValue(std::string const& input){ + return value.SetValue(input,Value::V_BOOL); } -void Prop_hex::SetValue(std::string const& input){ - Value val(input,Value::V_HEX); - SetVal(val,false,true); +bool Prop_hex::SetValue(std::string const& input){ + Value val; + val.SetValue(input,Value::V_HEX); + return SetVal(val,false,true); } void Prop_multival::make_default_value(){ @@ -331,15 +347,15 @@ void Prop_multival::make_default_value(){ //TODO checkvalue stuff -void Prop_multival_remain::SetValue(std::string const& input) { +bool Prop_multival_remain::SetValue(std::string const& input) { Value val(input,Value::V_STRING); - SetVal(val,false,true); + bool retval = SetVal(val,false,true); std::string local(input); int i = 0,number_of_properties = 0; Property *p = section->Get_prop(0); //No properties in this section. do nothing - if(!p) return; + if(!p) return false; while( (section->Get_prop(number_of_properties)) ) number_of_properties++; @@ -364,22 +380,23 @@ void Prop_multival_remain::SetValue(std::string const& input) { Value valtest (in,p->Get_type()); if(!p->CheckValue(valtest,true)) { make_default_value(); - return; + return false; } p->SetValue(in); } + return retval; } //TODO checkvalue stuff -void Prop_multival::SetValue(std::string const& input) { +bool Prop_multival::SetValue(std::string const& input) { Value val(input,Value::V_STRING); - SetVal(val,false,true); + bool retval = SetVal(val,false,true); std::string local(input); int i = 0; Property *p = section->Get_prop(0); //No properties in this section. do nothing - if(!p) return; + if(!p) return false; string::size_type loc = string::npos; while( (p = section->Get_prop(i++)) ) { //trim leading seperators @@ -398,11 +415,12 @@ void Prop_multival::SetValue(std::string const& input) { Value valtest (in,p->Get_type()); if(!p->CheckValue(valtest,true)) { make_default_value(); - return; + return false; } p->SetValue(in); } + return retval; } const std::vector& Property::GetValues() const { @@ -563,20 +581,20 @@ void trim(string& in) { } //TODO double c_str -void Section_prop::HandleInputline(string const& gegevens){ +bool Section_prop::HandleInputline(string const& gegevens){ string str1 = gegevens; string::size_type loc = str1.find('='); - if(loc == string::npos) return; + if(loc == string::npos) return false; string name = str1.substr(0,loc); string val = str1.substr(loc + 1); /* trim the results incase there were spaces somewhere */ trim(name);trim(val); for(it tel=properties.begin();tel!=properties.end();tel++){ if(!strcasecmp((*tel)->propname.c_str(),name.c_str())){ - (*tel)->SetValue(val); - return; + return (*tel)->SetValue(val); } } + return false; } void Section_prop::PrintData(FILE* outfile) const { @@ -596,9 +614,10 @@ string Section_prop::GetPropValue(string const& _property) const{ return NO_SUCH_PROPERTY; } -void Section_line::HandleInputline(string const& line){ +bool Section_line::HandleInputline(string const& line){ data+=line; data+="\n"; + return true; } void Section_line::PrintData(FILE* outfile) const { @@ -770,11 +789,13 @@ Section* Config::GetSectionFromProperty(char const * const prop) const{ bool Config::ParseConfigFile(char const * const configfilename){ - static bool first_configfile = true; + //static bool first_configfile = true; ifstream in(configfilename); if (!in) return false; - const char * settings_type = first_configfile?"primary":"additional"; - first_configfile = false; + const char * settings_type; + settings_type = (configfiles.size() == 0)? "primary":"additional"; + configfiles.push_back(configfilename); + LOG_MSG("CONFIG:Loading %s settings from config file %s", settings_type,configfilename); //Get directory from configfilename, used with relative paths. @@ -824,6 +845,10 @@ bool Config::ParseConfigFile(char const * const configfilename){ return true; } +/*const char* Config::GetPrimaryConfigFile() { + return configfile.c_str(); +}*/ + void Config::ParseEnv(char ** envp) { for(char** env=envp; *env;env++) { char copy[1024]; @@ -850,6 +875,7 @@ void Config::SetStartUp(void (*_function)(void)) { void Config::StartUp(void) { + initialised=true; (*_start_function)(); } @@ -946,6 +972,90 @@ unsigned int CommandLine::GetCount(void) { return (unsigned int)cmds.size(); } +void CommandLine::FillVector(std::vector & vector) { + for(cmd_it it=cmds.begin(); it != cmds.end(); it++) { + vector.push_back((*it)); + } + // add back the \" if the parameter contained a space + for(Bitu i = 0; i < vector.size(); i++) { + if(vector[i].find(' ') != std::string::npos) { + vector[i] = "\""+vector[i]+"\""; + } + } +} + +int CommandLine::GetParameterFromList(const char* const params[], std::vector & output) { + // return values: 0 = P_NOMATCH, 1 = P_NOPARAMS + // TODO return nomoreparams + int retval = 1; + output.clear(); + enum { + P_START, P_FIRSTNOMATCH, P_FIRSTMATCH + } parsestate = P_START; + cmd_it it = cmds.begin(); + while(it!=cmds.end()) { + bool found = false; + for(Bitu i = 0; params[i]!=""; i++) { + if (!strcasecmp((*it).c_str(),params[i])) { + // found a parameter + found = true; + switch(parsestate) { + case P_START: + retval = i+2; + parsestate = P_FIRSTMATCH; + break; + case P_FIRSTMATCH: + case P_FIRSTNOMATCH: + return retval; + } + } + } + if(!found) + switch(parsestate) { + case P_START: + retval = 0; // no match + parsestate = P_FIRSTNOMATCH; + output.push_back(*it); + break; + case P_FIRSTMATCH: + case P_FIRSTNOMATCH: + output.push_back(*it); + break; + } + cmd_it itold = it; + it++; + cmds.erase(itold); + + } + + return retval; +/* +bool CommandLine::FindEntry(char const * const name,cmd_it & it,bool neednext) { + for (it=cmds.begin();it!=cmds.end();it++) { + if (!strcasecmp((*it).c_str(),name)) { + cmd_it itnext=it;itnext++; + if (neednext && (itnext==cmds.end())) return false; + return true; + } + } + return false; +*/ + + +/* + cmd_it it=cmds.begin();value=(*it++); + while(it != cmds.end()) { + if(params. + + it++; + } +*/ + // find next parameter + //return -1; + +} + + CommandLine::CommandLine(int argc,char const * const argv[]) { if (argc>0) { file_name=argv[0]; From ec1fbccb4d7b461882aadee167d8a96b2e501c0a Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Fri, 29 Oct 2010 21:18:44 +0000 Subject: [PATCH 3562/4131] GCC compilation and test for empty string fix related to the config patch. Thanks TeaRex and ripsaw8080 for reporting. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3652 --- include/cross.h | 2 +- src/misc/programs.cpp | 4 ++-- src/misc/setup.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/cross.h b/include/cross.h index 8e2268d1..697cb6ee 100644 --- a/include/cross.h +++ b/include/cross.h @@ -74,7 +74,7 @@ public: static void CreatePlatformConfigDir(std::string& in); static void ResolveHomedir(std::string & temp_line); static void CreateDir(std::string const& temp); - static bool Cross::IsPathAbsolute(std::string const& in); + static bool IsPathAbsolute(std::string const& in); }; diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 724d6a9b..21f378f1 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -459,10 +459,10 @@ void CONFIG::Run(void) { std::string propvalues; std::vector pv = p->GetValues(); - if (p->Get_type()==Value::Etype::V_BOOL) { + if (p->Get_type()==Value::V_BOOL) { // possible values for boolean are true, false propvalues += "true, false"; - } else if (p->Get_type()==Value::Etype::V_INT) { + } else if (p->Get_type()==Value::V_INT) { // print min, max for integer values if used Prop_int* pint = dynamic_cast (p); if (pint==NULL) E_Exit("Int property dynamic cast failed."); diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index a0184b49..f62034f0 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -995,7 +995,7 @@ int CommandLine::GetParameterFromList(const char* const params[], std::vector Date: Fri, 29 Oct 2010 21:33:50 +0000 Subject: [PATCH 3563/4131] update svn properties Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3653 --- src/gui/sdl_mapper.cpp | 4 ++-- src/hardware/sblaster.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index ea541796..54ab6da8 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -1584,8 +1584,8 @@ public: case MK_printscreen: key=SDLK_PRINT; break; - case MK_home: - key=SDLK_HOME; + case MK_home: + key=SDLK_HOME; break; } sprintf(buf,"%s \"key %d%s%s%s\"", diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 8dbd4799..63b7c46a 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1345,7 +1345,7 @@ static Bit8u CTMIXER_Read(void) { return ret; case 0x82: /* IRQ Status */ return (sb.irq.pending_8bit ? 0x1 : 0) | - (sb.irq.pending_16bit ? 0x2 : 0) | + (sb.irq.pending_16bit ? 0x2 : 0) | ((sb.type == SBT_16) ? 0x20 : 0); default: if ( ((sb.type == SBT_PRO1 || sb.type == SBT_PRO2) && sb.mixer.index==0x0c) || /* Input control on SBPro */ From c759fb6de181b58acc6ea7139c16e247e0a50b76 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Mon, 1 Nov 2010 22:21:54 +0000 Subject: [PATCH 3564/4131] config: - fix crashes when passing unexpected parameter combinations - config -get 'sectionname' now lists the properties with their values - add missing translation string Thanks robertmo for reporting. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3654 --- src/misc/programs.cpp | 67 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 21f378f1..0bd13a36 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -295,6 +295,7 @@ void CONFIG::Run(void) { bool first = true; std::vector pvars; + // Loop through the passed parameters while(presult != P_NOPARAMS) { presult = (enum prs)cmd->GetParameterFromList(params, pvars); switch(presult) { @@ -376,6 +377,10 @@ void CONFIG::Run(void) { case P_NOPARAMS: if (!first) break; + case P_NOMATCH: + WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE")); + return; + case P_HELP: case P_HELP2: case P_HELP3: { switch(pvars.size()) { case 0: @@ -524,6 +529,7 @@ void CONFIG::Run(void) { case P_GETPROP: { // "section property" // "property" + // "section" // "section" "property" if (pvars.size()==0) { WriteOut(MSG_Get("PROGRAM_CONFIG_GET_SYNTAX")); @@ -537,14 +543,39 @@ void CONFIG::Run(void) { } switch(pvars.size()) { case 1: { - // property only - Section* sec = control->GetSectionFromProperty(pvars[0].c_str()); - if (!sec) { - WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR")); - return; + // property/section only + // is it a section? + Section* sec = control->GetSection(pvars[0].c_str()); + if (sec) { + // list properties in section + Bitu i = 0; + Section_prop* psec = dynamic_cast (sec); + if (psec==NULL) { + // autoexec section + Section_line* pline = dynamic_cast (sec); + if (pline==NULL) E_Exit("Section dynamic cast failed."); + + WriteOut("%s",pline->data.c_str()); + break; + } + while(true) { + // list the properties + Property* p = psec->Get_prop(i++); + if (p==NULL) break; + WriteOut("%s=%s\n", p->propname.c_str(), + p->GetValue().ToString().c_str()); + } + } else { + // no: maybe it's a property? + sec = control->GetSectionFromProperty(pvars[0].c_str()); + if (!sec) { + WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR")); + return; + } + // it's a property name + std::string val = sec->GetPropValue(pvars[0].c_str()); + WriteOut("%s",val.c_str()); } - std::string val = sec->GetPropValue(pvars[0].c_str()); - WriteOut("%s",val.c_str()); break; } case 2: { @@ -556,16 +587,20 @@ void CONFIG::Run(void) { } std::string val = sec->GetPropValue(pvars[1].c_str()); if (val == NO_SUCH_PROPERTY) { - WriteOut(MSG_Get("PROGRAM_CONFIG_NO_PROPERTY"),pvars[1].c_str(),pvars[0].c_str()); + WriteOut(MSG_Get("PROGRAM_CONFIG_NO_PROPERTY"), + pvars[1].c_str(),pvars[0].c_str()); return; } WriteOut("%s",val.c_str()); break; } + default: + WriteOut(MSG_Get("PROGRAM_CONFIG_GET_SYNTAX")); + return; } return; } - case P_SETPROP: case P_NOMATCH: { + case P_SETPROP: { // Code for the configuration changes // Official format: config -set "section property=value" // Accepted: with or without -set, @@ -654,7 +689,18 @@ void CONFIG::Run(void) { } } } - // Input has been parsed (pvar[0]=section, [1]=property, [2]=value + if(pvars.size() < 3) { + WriteOut(MSG_Get("PROGRAM_CONFIG_SET_SYNTAX")); + return; + } + // check if the property actually exists in the section + Section* sec2 = control->GetSectionFromProperty(pvars[1].c_str()); + if (!sec2) { + WriteOut(MSG_Get("PROGRAM_CONFIG_NO_PROPERTY"), + pvars[1].c_str(),pvars[0].c_str()); + return; + } + // Input has been parsed (pvar[0]=section, [1]=property, [2]=value) // now execute Section* tsec = control->GetSection(pvars[0]); std::string value; @@ -751,6 +797,7 @@ void PROGRAMS_Init(Section* /*sec*/) { MSG_Add("PROGRAM_CONFIG_VALUE_ERROR","\"%s\" is not a valid value for property %s.\n"); MSG_Add("PROGRAM_CONFIG_PROPERTY_ERROR","No such section or property.\n"); MSG_Add("PROGRAM_CONFIG_NO_PROPERTY","There is no property %s in section %s.\n"); + MSG_Add("PROGRAM_CONFIG_SET_SYNTAX","Correct syntax: config -set \"section property\".\n"); MSG_Add("PROGRAM_CONFIG_GET_SYNTAX","Correct syntax: config -get \"section property\".\n"); MSG_Add("PROGRAM_CONFIG_PRINT_STARTUP","\nDOSBox was started with the following command line parameters:\n%s"); MSG_Add("PROGRAM_CONFIG_MISSINGPARAM","Missing parameter."); From bf5bd0610d248c01034268a2c18f613626e06f28 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 6 Nov 2010 13:08:51 +0000 Subject: [PATCH 3565/4131] big endian volume control for cd images. Thanks ripsaw Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3655 --- src/dos/cdrom_image.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 26375c9a..12e601ee 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -346,15 +346,21 @@ void CDROM_Interface_Image::CDAudioCallBack(Bitu len) Bit16s sample0,sample1; Bit16s * samples=(Bit16s *)&player.buffer; for (Bitu pos=0;posAddSamples_s16_nonnative(len/4,(Bit16s *)player.buffer); + player.channel->AddSamples_s16(len/4,(Bit16s *)player.buffer); + } else player.channel->AddSamples_s16_nonnative(len/4,(Bit16s *)player.buffer); #else + } player.channel->AddSamples_s16(len/4,(Bit16s *)player.buffer); #endif memmove(player.buffer, &player.buffer[len], player.bufLen - len); From 480bc0377ac01ddfca10044dab2141e2dca49403 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 6 Nov 2010 13:35:32 +0000 Subject: [PATCH 3566/4131] Destroy some registers. Pinball world installer. (thanks ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3656 --- src/dos/dos.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index a3ec0a70..fb490c27 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -362,6 +362,7 @@ static Bitu DOS_21Handler(void) { break; case 0x26: /* Create new PSP */ DOS_NewPSP(reg_dx,DOS_PSP(dos.psp()).GetSize()); + reg_al=0xf0; /* al destroyed */ break; case 0x2a: /* Get System Date */ { @@ -523,6 +524,7 @@ static Bitu DOS_21Handler(void) { case 0x39: /* MKDIR Create directory */ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_MakeDir(name1)) { + reg_ax=0x05; /* ax destroyed */ CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; @@ -532,6 +534,7 @@ static Bitu DOS_21Handler(void) { case 0x3a: /* RMDIR Remove directory */ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_RemoveDir(name1)) { + reg_ax=0x05; /* ax destroyed */ CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; @@ -542,6 +545,7 @@ static Bitu DOS_21Handler(void) { case 0x3b: /* CHDIR Set current directory */ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); if (DOS_ChangeDir(name1)) { + reg_ax=0x00; /* ax destroyed */ CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; @@ -568,6 +572,7 @@ static Bitu DOS_21Handler(void) { break; case 0x3e: /* CLOSE Close file */ if (DOS_CloseFile(reg_bx)) { +// reg_al=0x01; /* al destroyed. Refcount */ CALLBACK_SCF(false); } else { reg_ax=dos.errorcode; @@ -789,6 +794,7 @@ static Bitu DOS_21Handler(void) { case 0x55: /* Create Child PSP*/ DOS_ChildPSP(reg_dx,reg_si); dos.psp(reg_dx); + reg_al=0xf0; /* al destroyed */ break; case 0x56: /* RENAME Rename file */ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); From 90daf1718b1503dc2be33d945994124399c06883 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 6 Nov 2010 13:58:43 +0000 Subject: [PATCH 3567/4131] Close sourcefile if open in FCB_Rename. Fixes ancient dutch version of wordstart Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3657 --- src/dos/dos_files.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 1734035e..6ae2f439 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1166,9 +1166,29 @@ bool DOS_FCBDeleteFile(Bit16u seg,Bit16u offset){ bool DOS_FCBRenameFile(Bit16u seg, Bit16u offset){ DOS_FCB fcbold(seg,offset); DOS_FCB fcbnew(seg,offset+16); + if(!fcbold.Valid()) return false; char oldname[DOS_FCBNAME]; char newname[DOS_FCBNAME]; fcbold.GetName(oldname);fcbnew.GetName(newname); + + /* Check, if sourcefile is still open. This was possible in DOS, but modern oses don't like this */ + Bit8u drive; char fullname[DOS_PATHLENGTH]; + if (!DOS_MakeName(oldname,fullname,&drive)) return false; + + DOS_PSP psp(dos.psp()); + for (Bit8u i=0;iIsOpen() && Files[i]->IsName(fullname)) { + Bit16u handle = psp.FindEntryByHandle(i); + if (handle == 0xFF) { + // This shouldnt happen + LOG(LOG_FILES,LOG_ERROR)("DOS: File %s is opened but has no psp entry.",oldname); + return false; + } + DOS_CloseFile(handle); + } + } + + /* Rename the file */ return DOS_Rename(oldname,newname); } From d7597b8dd86b0e861d17edd9fbd1c6d06b6c4a31 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 6 Nov 2010 14:00:46 +0000 Subject: [PATCH 3568/4131] soundblaster cd audio control (this is not the same as mscdex audio control). Thanks ripsaw. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3658 --- src/hardware/sblaster.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 63b7c46a..0c35000f 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1090,11 +1090,16 @@ static void CTMIXER_UpdateVolumes(void) { chan=MIXER_FindChannel("FM"); if (chan) chan->SetVolume(float(sb.mixer.master[0])/31.0f*CALCVOL(sb.mixer.fm[0]), float(sb.mixer.master[1])/31.0f*CALCVOL(sb.mixer.fm[1])); + chan=MIXER_FindChannel("CDAUDIO"); + if (chan) chan->SetVolume(float(sb.mixer.master[0])/31.0f*CALCVOL(sb.mixer.cda[0]), + float(sb.mixer.master[1])/31.0f*CALCVOL(sb.mixer.cda[1])); } static void CTMIXER_Reset(void) { sb.mixer.fm[0]= sb.mixer.fm[1]= + sb.mixer.cda[0]= + sb.mixer.cda[1]= sb.mixer.dac[0]= sb.mixer.dac[1]=31; sb.mixer.master[0]= @@ -1211,10 +1216,16 @@ static void CTMIXER_Write(Bit8u val) { } break; case 0x36: /* CD Volume Left (SB16) */ - if (sb.type==SBT_16) sb.mixer.cda[0]=val>>3; + if (sb.type==SBT_16) { + sb.mixer.cda[0]=val>>3; + CTMIXER_UpdateVolumes(); + } break; case 0x37: /* CD Volume Right (SB16) */ - if (sb.type==SBT_16) sb.mixer.cda[1]=val>>3; + if (sb.type==SBT_16) { + sb.mixer.cda[1]=val>>3; + CTMIXER_UpdateVolumes(); + } break; case 0x38: /* Line-in Volume Left (SB16) */ if (sb.type==SBT_16) sb.mixer.lin[0]=val>>3; From c85116940e9175243d9d5127071bfd8716bb25c8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 9 Nov 2010 08:35:57 +0000 Subject: [PATCH 3569/4131] ..\ is valid if the result ends up in the root dir. Thanks ripsaw Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3659 --- src/dos/dos_files.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 6ae2f439..9fe36bcb 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -206,11 +206,15 @@ bool DOS_ChangeDir(char const * const dir) { const char * testdir=dir; if (strlen(testdir) && testdir[1]==':') testdir+=2; size_t len=strlen(testdir); - if (!len || (len>1 && testdir[len-1]=='\\')) { + if (!len) { DOS_SetError(DOSERR_PATH_NOT_FOUND); return false; } if (!DOS_MakeName(dir,fulldir,&drive)) return false; + if (strlen(fulldir) && testdir[len-1]=='\\') { + DOS_SetError(DOSERR_PATH_NOT_FOUND); + return false; + } if (Drives[drive]->TestDir(fulldir)) { strcpy(Drives[drive]->curdir,fulldir); From c493a077913b3729873fab8ff9989fa109d00613 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Wed, 10 Nov 2010 13:19:44 +0000 Subject: [PATCH 3570/4131] Make the shortcut to set values of properties from the command line work again (regressed in the previous config-related patch) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3660 --- src/shell/shell_cmds.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 8a0a9c08..01cbec94 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -108,7 +108,7 @@ bool DOS_Shell::CheckConfig(char* cmd_in,char*line) { if(val != NO_SUCH_PROPERTY) WriteOut("%s\n",val.c_str()); return true; } - char newcom[1024]; newcom[0] = 0; strcpy(newcom,"z:\\config "); + char newcom[1024]; newcom[0] = 0; strcpy(newcom,"z:\\config -set "); strcat(newcom,test->GetName()); strcat(newcom," "); strcat(newcom,cmd_in);strcat(newcom,line); DoCommand(newcom); From 15f221d8a1b15275548a5604b4698fcbb13a9f6a Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Wed, 10 Nov 2010 19:58:10 +0000 Subject: [PATCH 3571/4131] Implement special case of vertical blanking register 'usage'. Fixes Threat v1.40. Thanks ripsaw8080 for reporting. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3661 --- src/hardware/vga_draw.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 72c7df35..713d5212 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1092,7 +1092,6 @@ void VGA_SetupDrawing(Bitu /*val*/) { vtotal += 2; hdend += 1; vdend += 1; - vbstart += 1; hbend = hbstart + ((hbend - hbstart) & 0x3F); hrend = vga.crtc.end_horizontal_retrace & 0x1f; @@ -1107,10 +1106,16 @@ void VGA_SetupDrawing(Bitu /*val*/) { if ( !vrend) vrend = vrstart + 0xf + 1; else vrend = vrstart + vrend; - vbend = (vbend - vbstart) & 0x7f; - if ( !vbend) vbend = vbstart + 0x7f + 1; - else vbend = vbstart + vbend; - + // Special case vbstart==0: + // Most graphics cards agree that lines zero to vbend are + // blanked. ET4000 doesn't blank at all if vbstart==vbend. + // ET3000 blanks lines 1 to vbend (255/6 lines). + if (vbstart != 0) { + vbstart += 1; + vbend = (vbend - vbstart) & 0x7f; + if ( !vbend) vbend = vbstart + 0x7f + 1; + else vbend = vbstart + vbend; + } vbend++; if (svga.get_clock) { @@ -1219,7 +1224,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { vdend = vbstart; } LOG(LOG_VGA,LOG_WARN)("Blanking wrap to line %d", vblank_skip); - } else if (vbstart==1) { + } else if (vbstart<=1) { // blanking is used to cut lines at the start of the screen vblank_skip = vbend; LOG(LOG_VGA,LOG_WARN)("Upper %d lines of the screen blanked", vblank_skip); From bf3e6ab0efbb8c4357852583022b719ddfcf1fd9 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Mon, 29 Nov 2010 22:26:32 +0000 Subject: [PATCH 3572/4131] Potentially resize the screen when vertical blanking end changes. Fixes Threat v1.40 Intro. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3662 --- src/hardware/vga_crtc.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index aab7b888..6868f634 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -302,10 +302,14 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { */ break; case 0x16: /* End Vertical Blank Register */ - crtc(end_vertical_blanking)=val; - /* + if (val!=crtc(end_vertical_blanking)) { + crtc(end_vertical_blanking)=val; + VGA_StartResize(); + } + /* 0-6 Vertical blanking stops when the lower 7 bits of the line counter equals this field. Some SVGA chips uses all 8 bits! + IBM actually says bits 0-7. */ break; case 0x17: /* Mode Control Register */ From c56d4404c00731569f299fb029ecfee4c4bd02a7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 4 Dec 2010 14:33:39 +0000 Subject: [PATCH 3573/4131] Fix FileExists on directories. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3663 --- src/dos/drive_local.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 1af3ddc9..f53cc0c4 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -394,9 +394,9 @@ bool localDrive::FileExists(const char* name) { strcat(newname,name); CROSS_FILENAME(newname); dirCache.ExpandName(newname); - FILE* Temp=fopen(newname,"rb"); - if(Temp==NULL) return false; - fclose(Temp); + struct stat temp_stat; + if(stat(newname,&temp_stat)!=0) return false; + if(temp_stat.st_mode & S_IFDIR) return false; return true; } From 56f3bf59e56b8aa6793a6ff1af5592d6ce62b55a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 4 Jan 2011 10:30:05 +0000 Subject: [PATCH 3574/4131] Typo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3664 --- src/misc/programs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 0bd13a36..cdc9bed5 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -777,7 +777,7 @@ void PROGRAMS_Init(Section* /*sec*/) { "-l lists configuration parameters.\n"\ "-h, -help, -? sections / sectionname / propertyname\n"\ " Without parameters, displays this help screen. Add \"sections\" for a list of\n sections."\ - " For info about a specific section or property add it's name behind.\n"\ + " For info about a specific section or property add its name behind.\n"\ "-axclear clears the autoexec section.\n"\ "-axadd [line] adds a line to the autoexec section.\n"\ "-axtype prints the content of the autoexec section.\n"\ From c3a904c56ea81c7d650414baf158d154f5cf19e8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 4 Jan 2011 20:37:54 +0000 Subject: [PATCH 3575/4131] Typo. pic[0] should be pics[0]. Thanks for spotting it Danoon. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3665 --- src/hardware/pic.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index fde85022..412bd467 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -92,9 +92,9 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { else pic->request_issr=false; /* select read interrupt request register */ } if (val&0x40) { // special mask select - if (val&0x20) pic->special=true; - else pic->special=false; - if(pic[0].special || pics[1].special) + if (val&0x20) pic->special = true; + else pic->special = false; + if (pics[0].special || pics[1].special) PIC_Special_Mode = true; else PIC_Special_Mode = false; if (PIC_IRQCheck) { //Recheck irqs From 1589c86ebedef4a9bd6784a52a7d41fa2d5acdf9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 5 Jan 2011 19:48:18 +0000 Subject: [PATCH 3576/4131] Some FCB read/write refinements. Stop exiting on weird int 21 0x33 calls. (ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3666 --- include/dos_inc.h | 4 ++-- src/dos/dos.cpp | 18 +++++++++++++----- src/dos/dos_files.cpp | 26 +++++++++++++------------- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 290d76b3..5199e506 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -176,8 +176,8 @@ 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); +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); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index fb490c27..318095b2 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -319,11 +319,17 @@ static Bitu DOS_21Handler(void) { if (!DOS_GetAllocationInfo(reg_dl,®_cx,®_al,®_dx)) reg_al=0xff; break; case 0x21: /* Read random record from FCB */ - reg_al = DOS_FCBRandomRead(SegValue(ds),reg_dx,1,true); + { + Bit16u toread=1; + reg_al = DOS_FCBRandomRead(SegValue(ds),reg_dx,&toread,true); + } LOG(LOG_FCB,LOG_NORMAL)("DOS:0x21 FCB-Random read used, result:al=%d",reg_al); break; case 0x22: /* Write random record to FCB */ - reg_al=DOS_FCBRandomWrite(SegValue(ds),reg_dx,1,true); + { + Bit16u towrite=1; + reg_al=DOS_FCBRandomWrite(SegValue(ds),reg_dx,&towrite,true); + } LOG(LOG_FCB,LOG_NORMAL)("DOS:0x22 FCB-Random write used, result:al=%d",reg_al); break; case 0x23: /* Get file size for FCB */ @@ -334,11 +340,11 @@ static Bitu DOS_21Handler(void) { DOS_FCBSetRandomRecord(SegValue(ds),reg_dx); break; case 0x27: /* Random block read from FCB */ - reg_al = DOS_FCBRandomRead(SegValue(ds),reg_dx,reg_cx,false); + reg_al = DOS_FCBRandomRead(SegValue(ds),reg_dx,®_cx,false); LOG(LOG_FCB,LOG_NORMAL)("DOS:0x27 FCB-Random(block) read used, result:al=%d",reg_al); break; case 0x28: /* Random Block write to FCB */ - reg_al=DOS_FCBRandomWrite(SegValue(ds),reg_dx,reg_cx,false); + reg_al=DOS_FCBRandomWrite(SegValue(ds),reg_dx,®_cx,false); LOG(LOG_FCB,LOG_NORMAL)("DOS:0x28 FCB-Random(block) write used, result:al=%d",reg_al); break; case 0x29: /* Parse filename into FCB */ @@ -462,7 +468,9 @@ static Bitu DOS_21Handler(void) { reg_dh=0x10; /* Dos in HMA */ break; default: - E_Exit("DOS:Illegal 0x33 Call %2X",reg_al); + LOG(LOG_DOSMISC,LOG_ERROR)("Weird 0x33 call %2X",reg_al); + reg_al =0xff; + break; } break; case 0x34: /* Get INDos Flag */ diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 9fe36bcb..a9c7e12b 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1067,32 +1067,30 @@ Bit8u DOS_FCBIncreaseSize(Bit16u seg,Bit16u offset) { return FCB_SUCCESS; } -Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { +Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u * numRec,bool restore) { /* if restore is true :random read else random blok read. * random read updates old block and old record to reflect the random data * before the read!!!!!!!!! and the random data is not updated! (user must do this) * Random block read updates these fields to reflect the state after the read! */ - -/* BUG: numRec should return the amount of records read! - * Not implemented yet as I'm unsure how to count on error states (partial/failed) - */ - DOS_FCB fcb(seg,offset); Bit32u random; Bit16u old_block=0; Bit8u old_rec=0; Bit8u error=0; + Bit16u count; /* Set the correct record from the random data */ fcb.GetRandom(random); fcb.SetRecord((Bit16u)(random / 128),(Bit8u)(random & 127)); if (restore) fcb.GetRecord(old_block,old_rec);//store this for after the read. // Read records - for (int i=0; i0) { /* Write records */ - for (int i=0; i Date: Sun, 16 Jan 2011 20:49:43 +0000 Subject: [PATCH 3577/4131] Add dummy support for openmode 4. Legend Of the Red Dragon 4.07 uses this. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3667 --- include/dos_system.h | 2 +- src/dos/drive_local.cpp | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index eab510e7..34d99fc2 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -250,7 +250,7 @@ public: 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, OPEN_READ_NO_MOD=4, DOS_NOT_INHERIT=128}; enum { DOS_SEEK_SET=0,DOS_SEEK_CUR=1,DOS_SEEK_END=2}; diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index f53cc0c4..50ae6f1c 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -83,9 +83,10 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u /*attributes*/) bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { const char* type; switch (flags&0xf) { - case OPEN_READ:type="rb"; break; - case OPEN_WRITE:type="rb+"; break; - case OPEN_READWRITE:type="rb+"; break; + case OPEN_READ: type = "rb" ; break; + case OPEN_WRITE: type = "rb+"; break; + case OPEN_READWRITE: type = "rb+"; break; + case OPEN_READ_NO_MOD: type = "rb" ; break; //No modification of dates. LORD4.07 uses this default: DOS_SetError(DOSERR_ACCESS_CODE_INVALID); return false; From dfd22007710243bf7c37b95d7258670a5ffc8733 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Wed, 19 Jan 2011 17:22:13 +0000 Subject: [PATCH 3578/4131] Fix out of bounds access (SF bug 3156587, thanks danoon for reporting). The unused byte in the 32-bit color value of the hardware mouse cursor pixels was affected. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3668 --- include/vga.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/vga.h b/include/vga.h index 65b526fc..dd6f41b9 100644 --- a/include/vga.h +++ b/include/vga.h @@ -173,8 +173,8 @@ typedef struct { Bit8u curmode; Bit16u originx, originy; Bit8u fstackpos, bstackpos; - Bit8u forestack[3]; - Bit8u backstack[3]; + Bit8u forestack[4]; + Bit8u backstack[4]; Bit16u startaddr; Bit8u posx, posy; Bit8u mc[64][64]; From 02b866dc4a7f5c7f76bf25de54f204a78fce9f39 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Wed, 19 Jan 2011 18:26:06 +0000 Subject: [PATCH 3579/4131] Implement video memory access to all text mode planes. Fixes Fasttracker Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3669 --- src/hardware/vga_memory.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 74f97528..8a8b43f7 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -466,12 +466,29 @@ public: } Bitu readb(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; - return vga.draw.font[addr]; + switch(vga.gfx.read_map_select) { + case 0: // character index + return vga.mem.linear[CHECKED3(vga.svga.bank_read_full+addr)]; + case 1: // character attribute + return vga.mem.linear[CHECKED3(vga.svga.bank_read_full+addr+1)]; + case 2: // font map + return vga.draw.font[addr]; + default: // 3=unused, but still RAM that could save values + return 0; + } } void writeb(PhysPt addr,Bitu val){ addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; - if (vga.seq.map_mask & 0x4) { + + if (GCC_LIKELY(vga.seq.map_mask == 0x4)) { vga.draw.font[addr]=(Bit8u)val; + } else { + if (vga.seq.map_mask & 0x4) // font map + vga.draw.font[addr]=(Bit8u)val; + if (vga.seq.map_mask & 0x2) // character attribute + vga.mem.linear[CHECKED3(vga.svga.bank_read_full+addr+1)]=(Bit8u)val; + if (vga.seq.map_mask & 0x1) // character index + vga.mem.linear[CHECKED3(vga.svga.bank_read_full+addr)]=(Bit8u)val; } } }; From fceeb4756cced62f2fc045f932f798c899addc41 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 20 Jan 2011 16:56:43 +0000 Subject: [PATCH 3580/4131] Fix 2 leaks. (unlikely to occur though) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3670 --- src/debug/debug.cpp | 6 +++--- src/hardware/serialport/libserial.cpp | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index ae573722..d85cd832 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -2174,11 +2174,11 @@ CDebugVar* CDebugVar::FindVar(PhysPt pt) return 0; }; -bool CDebugVar::SaveVars(char* name) -{ +bool CDebugVar::SaveVars(char* name) { + if (varList.size()>65535) return false; + FILE* f = fopen(name,"wb+"); if (!f) return false; - if (varList.size()>65535) return false; // write number of vars Bit16u num = (Bit16u)varList.size(); diff --git a/src/hardware/serialport/libserial.cpp b/src/hardware/serialport/libserial.cpp index 5d66851d..d8d6fa58 100644 --- a/src/hardware/serialport/libserial.cpp +++ b/src/hardware/serialport/libserial.cpp @@ -45,6 +45,7 @@ bool SERIAL_open(const char* portname, COMPORT* port) { int len = strlen(portname); if(len > 240) { SetLastError(ERROR_BUFFER_OVERFLOW); + free(cp); return false; } char extended_portname[256] = "\\\\.\\"; From 653e09f16d492a2d2c09e8af4532d844e606c0c7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 20 Jan 2011 17:02:44 +0000 Subject: [PATCH 3581/4131] Explicitly test for the documented return value when failed. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3671 --- src/dos/cdrom_ioctl_linux.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/cdrom_ioctl_linux.cpp b/src/dos/cdrom_ioctl_linux.cpp index 448fa02d..25f7c610 100644 --- a/src/dos/cdrom_ioctl_linux.cpp +++ b/src/dos/cdrom_ioctl_linux.cpp @@ -37,7 +37,7 @@ CDROM_Interface_Ioctl::CDROM_Interface_Ioctl(void) : CDROM_Interface_SDL() bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc) { int cdrom_fd = open(device_name, O_RDONLY | O_NONBLOCK); - if (cdrom_fd <= 0) return false; + if (cdrom_fd == -1) return false; struct cdrom_mcn cdrom_mcn; int ret = ioctl(cdrom_fd, CDROM_GET_MCN, &cdrom_mcn); @@ -55,7 +55,7 @@ bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc) bool CDROM_Interface_Ioctl::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) { int cdrom_fd = open(device_name, O_RDONLY | O_NONBLOCK); - if (cdrom_fd <= 0) return false; + if (cdrom_fd == -1) return false; Bits buflen = raw ? num * CD_FRAMESIZE_RAW : num * CD_FRAMESIZE; Bit8u* buf = new Bit8u[buflen]; From 37a736c910fb0670bc884a751f42ee887bbdd34b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 20 Jan 2011 17:33:03 +0000 Subject: [PATCH 3582/4131] Fix problems with automake 2.68. Inspired by patch 3152173 of Dominus. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3672 --- configure.in | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/configure.in b/configure.in index 3e2a8782..54b5356c 100644 --- a/configure.in +++ b/configure.in @@ -38,7 +38,7 @@ CPPFLAGS="$CPPFLAGS $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([ +AC_COMPILE_IFELSE([AC_LANG_SOURCE([ #include "SDL.h" void blah(){ #if SDL_MINOR_VERSION != 2 @@ -46,7 +46,7 @@ void blah(){ #endif ; } -],AC_MSG_RESULT([yes]),[ +])],AC_MSG_RESULT([yes]),[ AC_MSG_RESULT([no]) AC_MSG_ERROR([Only libSDL 1.2.X supported])]) @@ -82,7 +82,7 @@ AC_CHECK_HEADERS([sys/socket.h netinet/in.h pwd.h], [], [], ]) dnl check for the socklen_t (darwin doesn't always have it) -AC_COMPILE_IFELSE([ +AC_COMPILE_IFELSE([AC_LANG_SOURCE([ #include #ifdef STDC_HEADERS # include @@ -98,7 +98,7 @@ AC_COMPILE_IFELSE([ #ifdef HAVE_SYS_SOCKET_H #include #endif -],[],[AC_DEFINE([socklen_t],[int],[Define to `int` if you don't have socklen_t])]) +])],[],[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([[ @@ -111,13 +111,13 @@ 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([ +AC_COMPILE_IFELSE([AC_LANG_SOURCE([ #include #include 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)) +}])],[AC_MSG_RESULT(yes);AC_DEFINE(DIRENT_HAS_D_TYPE,1,[struct dirent has d_type])],AC_MSG_RESULT(no)) dnl Check for powf @@ -146,13 +146,13 @@ 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)) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([ 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)) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([ void __attribute__((fastcall)) test(){} +])],[ AC_MSG_RESULT(yes);AC_DEFINE(C_ATTRIBUTE_FASTCALL)],AC_MSG_RESULT(no)) CFLAGS="$OLDCFLAGS" @@ -439,12 +439,12 @@ 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([ +AC_LINK_IFELSE([AC_LANG_SOURCE([ #include 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)) +])],AC_MSG_RESULT(yes);AC_DEFINE(C_SET_PRIORITY,1),AC_MSG_RESULT(no)) dnl Some target detection and actions for them From 4101963e2295d801171077a89a389d8a2f1e6717 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Thu, 20 Jan 2011 21:39:17 +0000 Subject: [PATCH 3583/4131] Fix NATIVESOCKETS macro Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3673 --- src/hardware/serialport/nullmodem.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hardware/serialport/nullmodem.cpp b/src/hardware/serialport/nullmodem.cpp index 668ebc4c..c2349249 100644 --- a/src/hardware/serialport/nullmodem.cpp +++ b/src/hardware/serialport/nullmodem.cpp @@ -138,11 +138,13 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) { } } } else { -#endif LOG_MSG("Serial%d: socket inheritance not supported on this platform.", COMNUMBER); return; } +#else + LOG_MSG("Serial%d: socket inheritance not available.", COMNUMBER); +#endif } std::string tmpstring; if(cmd->FindStringBegin("server:",tmpstring,false)) { From fe65a341113ed4d7576df9d9d129e4c404a169e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 22 Jan 2011 16:15:34 +0000 Subject: [PATCH 3584/4131] update 64bit recompiler core to handle OSX (memory addressing, stack alignment) from gulikoza Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3674 --- src/cpu/core_dynrec/risc_x64.h | 128 +++++++++++++++++++++++---------- 1 file changed, 89 insertions(+), 39 deletions(-) diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index 8013785a..43953826 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 @@ -84,7 +84,7 @@ static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { } -static INLINE void gen_memaddr(HostReg reg,void* data) { +static INLINE void gen_reg_memaddr(HostReg reg,void* data) { Bit64s diff = (Bit64s)data-((Bit64s)cache.pos+5); if ((diff<0x80000000LL) && (diff>-0x80000000LL)) { cache_addb(0x05+(reg<<3)); @@ -98,13 +98,28 @@ static INLINE void gen_memaddr(HostReg reg,void* data) { } } +static INLINE void gen_memaddr(Bitu op,void* data,Bitu off) { + Bit64s diff; + diff = (Bit64s)data-((Bit64s)cache.pos+off+5); + if ((diff<0x80000000LL) && (diff>-0x80000000LL)) { + // RIP-relative addressing is offset after the instruction + cache_addb(op+1); + cache_addd((Bit32u)(((Bit64u)diff)&0xffffffffLL)); + } else if ((Bit64u)data<0x100000000LL) { + cache_addb(op); + cache_addb(0x25); + cache_addd((Bit32u)(((Bit64u)data)&0xffffffffLL)); + } else { + E_Exit("DRC64:Unhandled memory reference"); + } +} // move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { if (!dword) cache_addb(0x66); cache_addb(0x8b); // mov reg,[data] - gen_memaddr(dest_reg,data); + gen_reg_memaddr(dest_reg,data); } // move a 16bit constant value into dest_reg @@ -125,7 +140,7 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { if (!dword) cache_addb(0x66); cache_addb(0x89); // mov [data],reg - gen_memaddr(src_reg,dest); + gen_reg_memaddr(src_reg,dest); } // move an 8bit value from memory into dest_reg @@ -134,7 +149,7 @@ static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { // registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { cache_addb(0x8a); // mov reg,[data] - gen_memaddr(dest_reg,data); + gen_reg_memaddr(dest_reg,data); } // move an 8bit value from memory into dest_reg @@ -144,7 +159,7 @@ static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { static void gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { cache_addb(0x66); cache_addb(0x8b); // mov reg,[data] - gen_memaddr(dest_reg,data); + gen_reg_memaddr(dest_reg,data); } // move an 8bit constant value into dest_reg @@ -169,7 +184,7 @@ static void gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { // move the lowest 8bit of a register into memory static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { cache_addb(0x88); // mov [data],reg - gen_memaddr(src_reg,dest); + gen_reg_memaddr(src_reg,dest); } @@ -193,7 +208,7 @@ static void gen_extend_word(bool sign,HostReg reg) { // add a 32bit value from memory to a full register static void gen_add(HostReg reg,void* op) { cache_addb(0x03); // add reg,[data] - gen_memaddr(reg,op); + gen_reg_memaddr(reg,op); } // add a 32bit constant value to a full register @@ -212,9 +227,8 @@ static void gen_and_imm(HostReg reg,Bit32u imm) { // move a 32bit constant value into memory static void gen_mov_direct_dword(void* dest,Bit32u imm) { - cache_addw(0x04c7); // mov [data],imm - cache_addb(0x25); - cache_addd((Bit32u)(((Bit64u)dest)&0xffffffffLL)); + cache_addb(0xc7); // mov [data],imm + gen_memaddr(0x04,dest,4); cache_addd(imm); } @@ -235,9 +249,8 @@ static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { // add an 8bit constant value to a memory value static void gen_add_direct_byte(void* dest,Bit8s imm) { - cache_addw(0x0483); // add [data],imm - cache_addb(0x25); - cache_addd((Bit32u)(((Bit64u)dest)&0xffffffffLL)); + cache_addb(0x83); // add [data],imm + gen_memaddr(0x4,dest,1); cache_addb(imm); } @@ -248,18 +261,20 @@ static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { return; } if (!dword) cache_addb(0x66); - cache_addw(0x0481); // add [data],imm - cache_addb(0x25); - cache_addd((Bit32u)(((Bit64u)dest)&0xffffffffLL)); - if (dword) cache_addd((Bit32u)imm); - else cache_addw((Bit16u)imm); + cache_addb(0x81); // add [data],imm + if (dword) { + gen_memaddr(0x4,dest,4); // size of following immediate value + cache_addd((Bit32u)imm); + } else { + gen_memaddr(0x4,dest,2); // size of following immediate value + cache_addw((Bit16u)imm); + } } // subtract an 8bit constant value from a memory value static void gen_sub_direct_byte(void* dest,Bit8s imm) { - cache_addw(0x2c83); // sub [data],imm - cache_addb(0x25); - cache_addd((Bit32u)(((Bit64u)dest)&0xffffffffLL)); + cache_addb(0x83); // sub [data],imm + gen_memaddr(0x2c,dest,1); cache_addb(imm); } @@ -270,11 +285,14 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { return; } if (!dword) cache_addb(0x66); - cache_addw(0x2c81); // sub [data],imm - cache_addb(0x25); - cache_addd((Bit32u)(((Bit64u)dest)&0xffffffffLL)); - if (dword) cache_addd((Bit32u)imm); - else cache_addw((Bit16u)imm); + cache_addw(0x81); // sub [data],imm + if (dword) { + gen_memaddr(0x2c,dest,4); // size of following immediate value + cache_addd((Bit32u)imm); + } else { + gen_memaddr(0x2c,dest,2); // size of following immediate value + cache_addw((Bit16u)imm); + } } @@ -324,10 +342,18 @@ static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { // generate a call to a parameterless function static void INLINE gen_call_function_raw(void * func) { + cache_addb(0x48); + cache_addw(0xec83); + cache_addb(0x08); // sub rsp,0x08 (align stack to 16 byte boundary) + cache_addb(0x48); cache_addb(0xb8); // mov reg,imm64 cache_addq((Bit64u)func); cache_addw(0xd0ff); + + cache_addb(0x48); + cache_addw(0xc483); + cache_addb(0x08); // add rsp,0x08 (reset alignment) } // generate a call to a function with paramcount parameters @@ -350,9 +376,13 @@ static Bit64u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fa cache_addw(0xc483); // add rsp,0x08 cache_addb(0x08); + // stack is 16 byte aligned now + + cache_addb(0x50); // push rax (==old rsp) - Bit64u proc_addr=(Bit64u)cache.pos; + // returned address relates to where the address is stored in gen_call_function_raw + Bit64u proc_addr=(Bit64u)cache.pos-4; // Do the actual call to the procedure cache_addb(0x48); @@ -596,6 +626,8 @@ static void gen_return_function(void) { #ifdef DRC_FLAGS_INVALIDATION // called when a call to a function can be replaced by a // call to a simpler function +// check gen_call_function_raw and gen_call_function_setup +// for the targeted code static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { #ifdef DRC_FLAGS_INVALIDATION_DCODE // try to avoid function calls but rather directly fill in code @@ -604,36 +636,46 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDw: case t_ADDd: *(Bit32u*)(pos+0)=0xf001f889; // mov eax,edi; add eax,esi - *(Bit32u*)(pos+4)=0x909006eb; // skip + *(Bit32u*)(pos+4)=0x90900eeb; // skip *(Bit32u*)(pos+8)=0x90909090; + *(Bit32u*)(pos+12)=0x90909090; + *(Bit32u*)(pos+16)=0x90909090; break; case t_ORb: case t_ORw: case t_ORd: *(Bit32u*)(pos+0)=0xf009f889; // mov eax,edi; or eax,esi - *(Bit32u*)(pos+4)=0x909006eb; // skip + *(Bit32u*)(pos+4)=0x90900eeb; // skip *(Bit32u*)(pos+8)=0x90909090; + *(Bit32u*)(pos+12)=0x90909090; + *(Bit32u*)(pos+16)=0x90909090; break; case t_ANDb: case t_ANDw: case t_ANDd: *(Bit32u*)(pos+0)=0xf021f889; // mov eax,edi; and eax,esi - *(Bit32u*)(pos+4)=0x909006eb; // skip + *(Bit32u*)(pos+4)=0x90900eeb; // skip *(Bit32u*)(pos+8)=0x90909090; + *(Bit32u*)(pos+12)=0x90909090; + *(Bit32u*)(pos+16)=0x90909090; break; case t_SUBb: case t_SUBw: case t_SUBd: *(Bit32u*)(pos+0)=0xf029f889; // mov eax,edi; sub eax,esi - *(Bit32u*)(pos+4)=0x909006eb; // skip + *(Bit32u*)(pos+4)=0x90900eeb; // skip *(Bit32u*)(pos+8)=0x90909090; + *(Bit32u*)(pos+12)=0x90909090; + *(Bit32u*)(pos+16)=0x90909090; break; case t_XORb: case t_XORw: case t_XORd: *(Bit32u*)(pos+0)=0xf031f889; // mov eax,edi; xor eax,esi - *(Bit32u*)(pos+4)=0x909006eb; // skip + *(Bit32u*)(pos+4)=0x90900eeb; // skip *(Bit32u*)(pos+8)=0x90909090; + *(Bit32u*)(pos+12)=0x90909090; + *(Bit32u*)(pos+16)=0x90909090; break; case t_CMPb: case t_CMPw: @@ -641,37 +683,45 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit32u*)(pos+0)=0x90900aeb; // skip + *(Bit32u*)(pos+0)=0x909012eb; // skip *(Bit32u*)(pos+4)=0x90909090; *(Bit32u*)(pos+8)=0x90909090; + *(Bit32u*)(pos+12)=0x90909090; + *(Bit32u*)(pos+16)=0x90909090; break; case t_INCb: case t_INCw: case t_INCd: *(Bit32u*)(pos+0)=0xc0fff889; // mov eax,edi; inc eax - *(Bit32u*)(pos+4)=0x909006eb; // skip + *(Bit32u*)(pos+4)=0x90900eeb; // skip *(Bit32u*)(pos+8)=0x90909090; + *(Bit32u*)(pos+12)=0x90909090; + *(Bit32u*)(pos+16)=0x90909090; break; case t_DECb: case t_DECw: case t_DECd: *(Bit32u*)(pos+0)=0xc8fff889; // mov eax,edi; dec eax - *(Bit32u*)(pos+4)=0x909006eb; // skip + *(Bit32u*)(pos+4)=0x90900eeb; // skip *(Bit32u*)(pos+8)=0x90909090; + *(Bit32u*)(pos+12)=0x90909090; + *(Bit32u*)(pos+16)=0x90909090; break; case t_NEGb: case t_NEGw: case t_NEGd: *(Bit32u*)(pos+0)=0xd8f7f889; // mov eax,edi; neg eax - *(Bit32u*)(pos+4)=0x909006eb; // skip + *(Bit32u*)(pos+4)=0x90900eeb; // skip *(Bit32u*)(pos+8)=0x90909090; + *(Bit32u*)(pos+12)=0x90909090; + *(Bit32u*)(pos+16)=0x90909090; break; default: - *(Bit64u*)(pos+2)=(Bit64u)fct_ptr; // fill function pointer + *(Bit64u*)(pos+6)=(Bit64u)fct_ptr; // fill function pointer break; } #else - *(Bit64u*)(pos+2)=(Bit64u)fct_ptr; + *(Bit64u*)(pos+6)=(Bit64u)fct_ptr; // fill function pointer #endif } #endif From c6c57b40b56753f4d81dfb1cd9ade54ebe2552b6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 14 Feb 2011 07:42:19 +0000 Subject: [PATCH 3585/4131] No need for the internal values of WINDOW. Improves portability. Thanks for the report John Daniel Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3675 --- src/debug/debug_gui.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 936086c7..76e6dd2b 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -146,16 +146,17 @@ static void DrawBars(void) { attrset(COLOR_PAIR(PAIR_BLACK_BLUE)); } /* Show the Register bar */ - mvaddstr(dbg.win_reg->_begy-1,0, "---(Register Overview )---"); + mvaddstr(1-1,0, "---(Register Overview )---"); /* Show the Data Overview bar perhaps with more special stuff in the end */ - mvaddstr(dbg.win_data->_begy-1,0,"---(Data Overview Scroll: page up/down)---"); + mvaddstr(6-1,0,"---(Data Overview Scroll: page up/down)---"); /* Show the Code Overview perhaps with special stuff in bar too */ - mvaddstr(dbg.win_code->_begy-1,0,"---(Code Overview Scroll: up/down )---"); + mvaddstr(17-1,0,"---(Code Overview Scroll: up/down )---"); /* Show the Variable Overview bar */ - mvaddstr(dbg.win_var->_begy-1,0, "---(Variable Overview )---"); + mvaddstr(29-1,0, "---(Variable Overview )---"); /* Show the Output OverView */ - mvaddstr(dbg.win_out->_begy-1,0, "---(Output Scroll: home/end )---"); + mvaddstr(34-1,0, "---(Output Scroll: home/end )---"); attrset(0); + //Match values with below. So we don't need to touch the internal window structures } @@ -164,19 +165,19 @@ static void MakeSubWindows(void) { /* The Std output win should go in bottem */ /* Make all the subwindows */ int win_main_maxy, win_main_maxx; getmaxyx(dbg.win_main,win_main_maxy,win_main_maxx); - int outy=1; + int outy=1; //Match values with above /* The Register window */ dbg.win_reg=subwin(dbg.win_main,4,win_main_maxx,outy,0); - outy+=5; + outy+=5; // 6 /* The Data Window */ dbg.win_data=subwin(dbg.win_main,10,win_main_maxx,outy,0); - outy+=11; + outy+=11; // 17 /* The Code Window */ dbg.win_code=subwin(dbg.win_main,11,win_main_maxx,outy,0); - outy+=12; + outy+=12; // 29 /* The Variable Window */ dbg.win_var=subwin(dbg.win_main,4,win_main_maxx,outy,0); - outy+=5; + outy+=5; // 34 /* The Output Window */ dbg.win_out=subwin(dbg.win_main,win_main_maxy-outy,win_main_maxx,outy,0); // dbg.input_y=win_main_maxy-1; From f94c0830cee751e2c11a47a99bb2f6193884b679 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 19 Feb 2011 19:44:46 +0000 Subject: [PATCH 3586/4131] Reopen closed fcbs, if they were likely to have been opened before. Fixes Time and Magic. Thanks ripsaw Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3676 --- src/dos/dos_files.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index a9c7e12b..800ababa 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -991,6 +991,11 @@ Bit8u DOS_FCBRead(Bit16u seg,Bit16u offset,Bit16u recno) { DOS_FCB fcb(seg,offset); Bit8u fhandle,cur_rec;Bit16u cur_block,rec_size; fcb.GetSeqData(fhandle,rec_size); + if (fhandle==0xff && rec_size!=0) { + if (!DOS_FCBOpen(seg,offset)) return FCB_READ_NODATA; + LOG(LOG_FCB,LOG_WARN)("Reopened closed FCB"); + fcb.GetSeqData(fhandle,rec_size); + } fcb.GetRecord(cur_block,cur_rec); Bit32u pos=((cur_block*128)+cur_rec)*rec_size; if (!DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET)) return FCB_READ_NODATA; @@ -1013,6 +1018,11 @@ Bit8u DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u recno) { DOS_FCB fcb(seg,offset); Bit8u fhandle,cur_rec;Bit16u cur_block,rec_size; fcb.GetSeqData(fhandle,rec_size); + if (fhandle==0xff && rec_size!=0) { + if (!DOS_FCBOpen(seg,offset)) return FCB_READ_NODATA; + LOG(LOG_FCB,LOG_WARN)("Reopened closed FCB"); + fcb.GetSeqData(fhandle,rec_size); + } fcb.GetRecord(cur_block,cur_rec); Bit32u pos=((cur_block*128)+cur_rec)*rec_size; if (!DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET)) return FCB_ERR_WRITE; From 212f6735689f5d590e1e1f6d46a64bad763a2ee5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 19 Feb 2011 19:57:30 +0000 Subject: [PATCH 3587/4131] Improve XTreeGold support. Thanks ripsaw Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3677 --- include/dos_inc.h | 1 + src/dos/dos_classes.cpp | 4 ++++ src/dos/dos_files.cpp | 7 +++++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 5199e506..4f5ac715 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -506,6 +506,7 @@ public: bool Extended(void); void GetAttr(Bit8u & attr); void SetAttr(Bit8u attr); + void SetResultAttr(Bit8u attr); bool Valid(void); private: bool extended; diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 840f204e..e4dfa871 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -492,6 +492,10 @@ void DOS_FCB::SetAttr(Bit8u attr) { if(extended) mem_writeb(pt - 1,attr); } +void DOS_FCB::SetResultAttr(Bit8u attr) { + mem_writeb(pt + 12,attr); +} + void DOS_SDA::Init() { /* Clear */ for(Bitu i=0;i Date: Tue, 22 Feb 2011 18:02:10 +0000 Subject: [PATCH 3588/4131] Declare E_Exit as noreturn. Makes gcc happy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3678 --- include/dosbox.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/dosbox.h b/include/dosbox.h index c46cf0a4..37f6f702 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -23,10 +23,10 @@ #include "config.h" -void E_Exit(const char * message,...) GCC_ATTRIBUTE( __format__(__printf__, 1, 2)); +GCC_ATTRIBUTE(noreturn) void E_Exit(const char * message,...) GCC_ATTRIBUTE( __format__(__printf__, 1, 2)); -void MSG_Add(const char*,const char*); //add messages to the internal langaugefile -const char* MSG_Get(char const *); //get messages from the internal langaugafile +void MSG_Add(const char*,const char*); //add messages to the internal languagefile +const char* MSG_Get(char const *); //get messages from the internal languagefile class Section; From 4345813b10451de44d581c7d080422c6726703b5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Feb 2011 15:08:05 +0000 Subject: [PATCH 3589/4131] Allow DOS time to be temporary reset. Fixes romantic blue and others (QuickBasic games). Thanks ripsaw. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3679 --- src/dos/dos.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 318095b2..f9230dfd 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -86,6 +86,8 @@ static Bitu DOS_21Handler(void) { char name1[DOSNAMEBUF+2+DOS_NAMELENGTH_ASCII]; char name2[DOSNAMEBUF+2+DOS_NAMELENGTH_ASCII]; + + static Bitu time_start = 0; //For emulating temporary time changes. switch (reg_ah) { case 0x00: /* Terminate Program */ @@ -394,7 +396,7 @@ static Bitu DOS_21Handler(void) { //TODO Get time through bios calls date is fixed { /* Calculate how many miliseconds have passed */ - Bitu ticks=5*mem_readd(BIOS_TIMER); + Bitu ticks=5*(mem_readd(BIOS_TIMER) - time_start); ticks = ((ticks / 59659u) << 16) + ((ticks % 59659u) << 16) / 59659u; Bitu seconds=(ticks/100); reg_ch=(Bit8u)(seconds/3600); @@ -411,7 +413,11 @@ static Bitu DOS_21Handler(void) { //Check input parameters nonetheless if( reg_ch > 23 || reg_cl > 59 || reg_dh > 59 || reg_dl > 99 ) reg_al = 0xff; - else reg_al = 0; + else { //Allow time to be set to zero. Restore the orginal time for all other parameters. (QuickBasic) + if (reg_cx == 0 && reg_dx == 0) {time_start = mem_readd(BIOS_TIMER);LOG_MSG("Warning: game messes with DOS time!");} + else time_start = 0; + reg_al = 0; + } break; case 0x2e: /* Set Verify flag */ dos.verify=(reg_al==1); From 83b41ea628b776e186834eb0f5a44e3cb0306ea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 4 Mar 2011 15:54:11 +0000 Subject: [PATCH 3590/4131] normal core IN AX,Ib should use full 16bit target register (thanks to danoon for spotting this) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3680 --- src/cpu/core_normal/prefix_none.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 5e12ba56..1a6d164f 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -879,7 +879,7 @@ { Bitu port=Fetchb(); if (CPU_IO_Exception(port,2)) RUNEXCEPTION(); - reg_al=IO_ReadW(port); + reg_ax=IO_ReadW(port); break; } CASE_B(0xe6) /* OUT Ib,AL */ From e1ccef0bad99887c3b45b74d8a3a63e2946db0c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 6 Mar 2011 10:38:48 +0000 Subject: [PATCH 3591/4131] keep old key-flags for buggy layout files that redefine/extend already defined keys (fixes caps-lock behaviour of key E for us-layout with codepage 858) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3681 --- src/dos/dos_keyboard_layout.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index d6886be2..36bab926 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 @@ -443,7 +443,14 @@ Bitu keyboard_layout::read_keyboard_file(const char* keyboard_file_name, Bit32s } } - current_layout[scan*layout_pages+layout_pages-1]=read_buf[read_buf_pos-2]; // flags + // calculate max length of entries, taking into account old number of entries + Bit8u new_flags=current_layout[scan*layout_pages+layout_pages-1]&0x7; + if ((read_buf[read_buf_pos-2]&0x7) > new_flags) new_flags = read_buf[read_buf_pos-2]&0x7; + + // merge flag bits in as well + new_flags |= (read_buf[read_buf_pos-2] | current_layout[scan*layout_pages+layout_pages-1]) & 0xf0; + + current_layout[scan*layout_pages+layout_pages-1]=new_flags; if (read_buf[read_buf_pos-2]&0x80) scan_length*=2; // granularity flag (S) } i+=scan_length; // advance pointer From 3610cc82204326b5229187b70cc10d21595ffd4c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 6 Mar 2011 14:52:14 +0000 Subject: [PATCH 3592/4131] Handle files without an extension better. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3682 --- src/dos/drive_iso.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 6be88895..52e19d5e 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -494,13 +494,13 @@ int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) { if (de->ident[tmp - 1] == '.') de->ident[tmp - 1] = 0; } } - const char* dotpos = strchr((char*)de->ident, '.'); + char* dotpos = strchr((char*)de->ident, '.'); if (dotpos!=NULL) { + if (strlen(dotpos)>4) dotpos[4]=0; if (dotpos-(char*)de->ident>8) { strcpy((char*)(&de->ident[8]),dotpos); } - } - if (strlen((char*)de->ident)>12) de->ident[12]=0; + } else if (strlen((char*)de->ident)>8) de->ident[8]=0; return de->length; } From d97aade01af5047795ec759bcdfdaeb120842029 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 6 Mar 2011 16:29:19 +0000 Subject: [PATCH 3593/4131] Keep proper track of halted cycles. h-a-l-9000 and ripsaw. Improves MPXPLAY Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3683 --- src/cpu/cpu.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 363b091b..8e75211b 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -2048,6 +2048,7 @@ static Bits HLT_Decode(void) { if (reg_eip!=cpu.hlt.eip || SegValue(cs) != cpu.hlt.cs) { cpudecoder=cpu.hlt.old_decoder; } else { + CPU_IODelayRemoved += CPU_Cycles; CPU_Cycles=0; } return 0; From 5d865dafc84e6390e6e3d81e0a63bdc9c26bd2af Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 6 Mar 2011 16:34:11 +0000 Subject: [PATCH 3594/4131] VESA patch: - implement text mode support, add modes 108h through 10Ch - adjust the S3 text modes to the values found on real hardware - added defines for VESA return values - rewrite get/set scanlength and set display start for completeness - catch a possible division by zero, part of SF patch 3154782, thanks Daniel Richard G. - align display page sizes to 64k for compatibility Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3684 --- src/ints/int10_modes.cpp | 14 +- src/ints/int10_vesa.cpp | 286 +++++++++++++++++++++++++-------------- 2 files changed, 193 insertions(+), 107 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index d3d7099d..fe649fb5 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -54,8 +54,8 @@ VideoModeBlock ModeList_VGA[]={ { 0x012 ,M_EGA ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, { 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x2000 ,100 ,449 ,80 ,400 ,0 }, -{ 0x054 ,M_TEXT ,1056,688, 132,43, 8, 16, 1 ,0xB8000 ,0x4000, 192, 800, 132,688, 0 }, -{ 0x055 ,M_TEXT ,1056,400, 132,25, 8, 16, 1 ,0xB8000 ,0x2000, 192, 449, 132,400, 0 }, +{ 0x054 ,M_TEXT ,1056,344, 132,43, 8, 8, 1 ,0xB8000 ,0x4000, 160, 449, 132,344, 0 }, +{ 0x055 ,M_TEXT ,1056,400, 132,25, 8, 16, 1 ,0xB8000 ,0x2000, 160, 449, 132,400, 0 }, /* Alias of mode 101 */ { 0x069 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, @@ -72,6 +72,14 @@ VideoModeBlock ModeList_VGA[]={ { 0x106 ,M_LIN4 ,1280,1024,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,212 ,1066,160,1024,0 }, { 0x107 ,M_LIN8 ,1280,1024,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,212 ,1066,160,1024,0 }, +/* VESA text modes */ +{ 0x108 ,M_TEXT ,640 ,480, 80,60, 8, 8 ,2 ,0xB8000 ,0x4000, 100 ,525 ,80 ,480 ,0 }, +{ 0x109 ,M_TEXT ,1056,400, 132,25, 8, 16, 1 ,0xB8000 ,0x2000, 160, 449, 132,400, 0 }, +{ 0x10A ,M_TEXT ,1056,688, 132,43, 8, 8, 1 ,0xB8000 ,0x4000, 160, 449, 132,344, 0 }, +{ 0x10B ,M_TEXT ,1056,400, 132,50, 8, 8, 1 ,0xB8000 ,0x4000, 160, 449, 132,400, 0 }, +{ 0x10C ,M_TEXT ,1056,480, 132,60, 8, 8, 2 ,0xB8000 ,0x4000, 160, 531, 132,480, 0 }, + +/* VESA higher color modes */ { 0x10D ,M_LIN15 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, { 0x10E ,M_LIN16 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, { 0x10F ,M_LIN32 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,50 ,449 ,40 ,400 , _VGA_PIXEL_DOUBLE | _EGA_LINE_DOUBLE }, @@ -81,10 +89,10 @@ VideoModeBlock ModeList_VGA[]={ { 0x113 ,M_LIN15 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,264 ,628 ,200,600 ,0 }, { 0x114 ,M_LIN16 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,264 ,628 ,200,600 ,0 }, { 0x115 ,M_LIN32 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,132 ,628 ,100,600 ,0 }, - { 0x116 ,M_LIN15 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,336 ,806 ,256,768 ,0 }, { 0x117 ,M_LIN16 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,336 ,806 ,256,768 ,0 }, { 0x118 ,M_LIN32 ,1024,768 ,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,168 ,806 ,128,768 ,0 }, + /* those should be interlaced but ok */ //{ 0x119 ,M_LIN15 ,1280,1024,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,424 ,1066,320,1024,0 }, //{ 0x11A ,M_LIN16 ,1280,1024,160,64 ,8 ,16 ,1 ,0xA0000 ,0x10000,424 ,1066,320,1024,0 }, diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 627703fd..e90c641d 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -29,6 +29,13 @@ #include "int10.h" #include "dos_inc.h" +#define VESA_SUCCESS 0x00 +#define VESA_FAIL 0x01 +#define VESA_HW_UNSUPPORTED 0x02 +#define VESA_MODE_UNSUPPORTED 0x03 +// internal definition to pass to the caller +#define VESA_UNIMPLEMENTED 0xFF + static struct { Bitu setwindow; Bitu pmStart; @@ -117,7 +124,7 @@ Bit8u VESA_GetSVGAInformation(Bit16u seg,Bit16u off) { mem_writed(buffer+0x0a,0x0); //Capabilities and flags mem_writed(buffer+0x0e,int10.rom.vesa_modes); //VESA Mode list mem_writew(buffer+0x12,(Bit16u)(vga.vmemsize/(64*1024))); // memory size in 64kb blocks - return 0x00; + return VESA_SUCCESS; } Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off) { @@ -136,14 +143,13 @@ Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off) { while (ModeList_VGA[i].mode!=0xffff) { if (mode==ModeList_VGA[i].mode) goto foundit; else i++; } - return 0x01; + return VESA_FAIL; foundit: if ((int10.vesa_oldvbe) && (ModeList_VGA[i].mode>=0x120)) return 0x01; VideoModeBlock * mblock=&ModeList_VGA[i]; switch (mblock->type) { case M_LIN4: pageSize = mblock->sheight * mblock->swidth/2; - pageSize = (pageSize | 15) & ~ 15; var_write(&minfo.BytesPerScanLine,mblock->swidth/8); var_write(&minfo.NumberOfPlanes,0x4); var_write(&minfo.BitsPerPixel,4); @@ -152,7 +158,6 @@ foundit: break; case M_LIN8: pageSize = mblock->sheight * mblock->swidth; - pageSize = (pageSize | 15) & ~ 15; var_write(&minfo.BytesPerScanLine,mblock->swidth); var_write(&minfo.NumberOfPlanes,0x1); var_write(&minfo.BitsPerPixel,8); @@ -162,7 +167,6 @@ foundit: break; case M_LIN15: pageSize = mblock->sheight * mblock->swidth*2; - pageSize = (pageSize | 15) & ~ 15; var_write(&minfo.BytesPerScanLine,mblock->swidth*2); var_write(&minfo.NumberOfPlanes,0x1); var_write(&minfo.BitsPerPixel,15); @@ -180,7 +184,6 @@ foundit: break; case M_LIN16: pageSize = mblock->sheight * mblock->swidth*2; - pageSize = (pageSize | 15) & ~ 15; var_write(&minfo.BytesPerScanLine,mblock->swidth*2); var_write(&minfo.NumberOfPlanes,0x1); var_write(&minfo.BitsPerPixel,16); @@ -196,7 +199,6 @@ foundit: break; case M_LIN32: pageSize = mblock->sheight * mblock->swidth*4; - pageSize = (pageSize | 15) & ~ 15; var_write(&minfo.BytesPerScanLine,mblock->swidth*4); var_write(&minfo.NumberOfPlanes,0x1); var_write(&minfo.BitsPerPixel,32); @@ -212,36 +214,40 @@ foundit: modeAttributes = 0x1b; // Color, graphics if (!int10.vesa_nolfb) modeAttributes |= 0x80; // linear framebuffer break; -/* case M_TEXT: - pageSize = mblock->sheight/8 * mblock->swidth*2/8; - pageSize = (pageSize | 15) & ~ 15; - var_write(&minfo.BytesPerScanLine,mblock->swidth*2/8); + case M_TEXT: + pageSize = 0; + var_write(&minfo.BytesPerScanLine, mblock->twidth * 2); var_write(&minfo.NumberOfPlanes,0x4); var_write(&minfo.BitsPerPixel,4); - var_write(&minfo.MemoryModel,0); //Text + var_write(&minfo.MemoryModel,0); // text modeAttributes = 0x0f; //Color, text, bios output - break; */ + break; default: - return 0x1; + return VESA_FAIL; } - var_write(&minfo.WinAAttributes,0x7); // Exists/readable/writable - - if(pageSize > vga.vmemsize) { - // Mode not supported by current hardware configuration - var_write(&minfo.ModeAttributes, modeAttributes & ~0x1); - var_write(&minfo.NumberOfImagePages,0); - } else { - var_write(&minfo.ModeAttributes, modeAttributes); - Bitu pages = (vga.vmemsize / pageSize)-1; - var_write(&minfo.NumberOfImagePages,pages); + if (pageSize & 0xFFFF) { + // It is documented that many applications assume 64k-aligned page sizes + // VBETEST is one of them + pageSize += 0x10000; + pageSize &= ~0xFFFF; } + Bitu pages = 0; + if (pageSize > vga.vmemsize) { + // mode not supported by current hardware configuration + modeAttributes &= ~0x1; + } else if (pageSize) { + pages = (vga.vmemsize / pageSize)-1; + } + var_write(&minfo.NumberOfImagePages, pages); + var_write(&minfo.ModeAttributes, modeAttributes); + var_write(&minfo.WinAAttributes, 0x7); // Exists/readable/writable if (mblock->type==M_TEXT) { var_write(&minfo.WinGranularity,32); var_write(&minfo.WinSize,32); var_write(&minfo.WinASegment,0xb800); - var_write(&minfo.XResolution,mblock->swidth/8); - var_write(&minfo.YResolution,mblock->sheight/8); + var_write(&minfo.XResolution,mblock->twidth); + var_write(&minfo.YResolution,mblock->theight); } else { var_write(&minfo.WinGranularity,64); var_write(&minfo.WinSize,64); @@ -257,46 +263,46 @@ foundit: if (!int10.vesa_nolfb) var_write(&minfo.PhysBasePtr,S3_LFB_BASE); MEM_BlockWrite(buf,&minfo,sizeof(MODE_INFO)); - return 0x00; + return VESA_SUCCESS; } Bit8u VESA_SetSVGAMode(Bit16u mode) { if (INT10_SetVideoMode(mode)) { int10.vesa_setmode=mode&0x7fff; - return 0x00; + return VESA_SUCCESS; } - return 0x01; + return VESA_FAIL; } Bit8u VESA_GetSVGAMode(Bit16u & mode) { if (int10.vesa_setmode!=0xffff) mode=int10.vesa_setmode; else mode=CurMode->mode; - return 0x00; + return VESA_SUCCESS; } Bit8u VESA_SetCPUWindow(Bit8u window,Bit8u address) { - if (window) return 0x1; + if (window) return VESA_FAIL; if (((Bit32u)(address)*64*1024255) return 0x1; - if (index+count>256) return 0x1; + if (index>255) return VESA_FAIL; + if (index+count>256) return VESA_FAIL; IO_Write(0x3c8,(Bit8u)index); while (count) { b = mem_readb(data++); @@ -308,14 +314,14 @@ Bit8u VESA_SetPalette(PhysPt data,Bitu index,Bitu count) { IO_Write(0x3c9,b); count--; } - return 0x00; + return VESA_SUCCESS; } Bit8u VESA_GetPalette(PhysPt data,Bitu index,Bitu count) { Bit8u r,g,b; - if (index>255) return 0x1; - if (index+count>256) return 0x1; + if (index>255) return VESA_FAIL; + if (index+count>256) return VESA_FAIL; IO_Write(0x3c7,(Bit8u)index); while (count) { r = IO_Read(0x3c9); @@ -327,114 +333,182 @@ Bit8u VESA_GetPalette(PhysPt data,Bitu index,Bitu count) { data++; count--; } - return 0x00; + return VESA_SUCCESS; } +// maximum offset for the S3 Trio64 is 10 bits +#define S3_MAX_OFFSET 0x3ff Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u val, Bit16u & bytes,Bit16u & pixels,Bit16u & lines) { - Bit8u bpp; + // offset register: virtual scanline length + Bitu pixels_per_offset; + Bitu bytes_per_offset = 8; + Bitu vmemsize = vga.vmemsize; + Bitu new_offset = vga.config.scan_len; + Bitu screen_height = CurMode->sheight; + switch (CurMode->type) { + case M_TEXT: + vmemsize = 0x8000; // we have only the 32kB window here + screen_height = CurMode->theight; + pixels_per_offset = 16; // two characters each 8 pixels wide + bytes_per_offset = 4; // 2 characters + 2 attributes + break; case M_LIN4: - bpp = 1; + pixels_per_offset = 16; break; case M_LIN8: - bpp=1; + pixels_per_offset = 8; break; case M_LIN15: case M_LIN16: - bpp=2; + pixels_per_offset = 4; break; case M_LIN32: - bpp=4; + pixels_per_offset = 2; break; default: - return 0x1; + return VESA_MODE_UNSUPPORTED; } switch (subcall) { - case 0x00: /* Set in pixels */ - if(CurMode->type==M_LIN4) vga.config.scan_len=val/2; - else vga.config.scan_len = (val * bpp); + case 0x00: // set scan length in pixels + new_offset = val / pixels_per_offset; + if (val % pixels_per_offset) new_offset++; + + if (new_offset > S3_MAX_OFFSET) + return VESA_HW_UNSUPPORTED; // scanline too long + vga.config.scan_len = new_offset; + VGA_CheckScanLength(); break; - case 0x02: /* Set in bytes */ - if(CurMode->type==M_LIN4) vga.config.scan_len = val*4; - else vga.config.scan_len = val; + + case 0x01: // get current scanline length + // implemented at the end of this function break; - case 0x03: /* Get maximum */ - bytes=0x400*4; - pixels=bytes/bpp; - lines = (Bit16u)(vga.vmemsize / bytes); - return 0x00; - case 0x01: /* Get lengths */ + + case 0x02: // set scan length in bytes + new_offset = val / bytes_per_offset; + if (val % bytes_per_offset) new_offset++; + + if (new_offset > S3_MAX_OFFSET) + return VESA_HW_UNSUPPORTED; // scanline too long + vga.config.scan_len = new_offset; + VGA_CheckScanLength(); break; + + case 0x03: // get maximum scan line length + // the smaller of either the hardware maximum scanline length or + // the limit to get full y resolution of this mode + new_offset = S3_MAX_OFFSET; + if ((new_offset * bytes_per_offset * screen_height) > vmemsize) + new_offset = vmemsize / (bytes_per_offset * screen_height); + break; + default: - return 0x1; //Illegal call + return VESA_UNIMPLEMENTED; } - if (subcall!=0x01) { - /* Write the scan line to video card the simple way */ - if (vga.config.scan_len & 7) - vga.config.scan_len += 8; - vga.config.scan_len /= 8; - } - if(CurMode->type==M_LIN4) { - pixels=(vga.config.scan_len*16)/bpp; - bytes=vga.config.scan_len*2; - lines = (Bit16u)(vga.vmemsize /( bytes*4)); - } - else { - pixels=(vga.config.scan_len*8)/bpp; - bytes=vga.config.scan_len*8; - lines = (Bit16u)(vga.vmemsize / bytes); - } - VGA_StartResize(); - return 0x0; + + // set up the return values + bytes = (Bit16u)(new_offset * bytes_per_offset); + pixels = (Bit16u)(new_offset * pixels_per_offset); + if (!bytes) + // return failure on division by zero + // some real VESA BIOS implementations may crash here + return VESA_FAIL; + + lines = (Bit16u)(vmemsize / bytes); + + if (CurMode->type==M_TEXT) + lines *= CurMode->cheight; + + return VESA_SUCCESS; } Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y) { - //TODO Maybe do things differently with lowres double line modes? - Bitu start; + // TODO wait for retrace in case bl==0x80 + Bitu pixels_per_offset; + Bitu panning_factor = 1; + switch (CurMode->type) { + case M_TEXT: case M_LIN4: - start=vga.config.scan_len*16*y+x; - vga.config.display_start=start/8; - IO_Read(0x3da); - IO_Write(0x3c0,0x13+32); - IO_Write(0x3c0,start % 8); + pixels_per_offset = 16; break; case M_LIN8: - start=vga.config.scan_len*8*y+x; - vga.config.display_start=start/4; - IO_Read(0x3da); - IO_Write(0x3c0,0x13+32); - IO_Write(0x3c0,(start % 4)*2); + panning_factor = 2; // the panning register ignores bit0 in this mode + pixels_per_offset = 8; break; - case M_LIN16: case M_LIN15: - start=vga.config.scan_len*8*y+x*2; - vga.config.display_start=start/4; + case M_LIN16: + panning_factor = 2; // this may be DOSBox specific + pixels_per_offset = 4; break; case M_LIN32: - start=vga.config.scan_len*8*y+x*4; - vga.config.display_start=start/4; + pixels_per_offset = 2; break; default: - return 0x1; + return VESA_MODE_UNSUPPORTED; } - return 0x00; + // We would have to divide y by the character height for text modes and + // write the remainder to the CRTC preset row scan register, + // but VBE2 BIOSes that actually get that far also don't. + // Only a VBE3 BIOS got it right. + Bitu virtual_screen_width = vga.config.scan_len * pixels_per_offset; + Bitu new_start_pixel = virtual_screen_width * y + x; + Bitu new_crtc_start = new_start_pixel / (pixels_per_offset/2); + Bitu new_panning = new_start_pixel % (pixels_per_offset/2); + new_panning *= panning_factor; + + vga.config.display_start = new_crtc_start; + + // Setting the panning register is nice as it allows for super smooth + // scrolling, but if we hit the retrace pulse there may be flicker as + // panning and display start are latched at different times. + + IO_Read(0x3da); // reset attribute flipflop + IO_Write(0x3c0,0x13 | 0x20); // panning register, screen on + IO_Write(0x3c0,new_panning); + + return VESA_SUCCESS; } Bit8u VESA_GetDisplayStart(Bit16u & x,Bit16u & y) { - Bitu times=(vga.config.display_start*4)/(vga.config.scan_len*8); - Bitu rem=(vga.config.display_start*4) % (vga.config.scan_len*8); - Bitu pan=vga.config.pel_panning; + Bitu pixels_per_offset; + Bitu panning_factor = 1; + switch (CurMode->type) { + case M_TEXT: + pixels_per_offset = 16; + break; + case M_LIN4: + pixels_per_offset = 16; + break; case M_LIN8: - y=(Bit16u)times; - x=(Bit16u)(rem+pan); + panning_factor = 2; + pixels_per_offset = 8; + break; + case M_LIN15: + case M_LIN16: + panning_factor = 2; + pixels_per_offset = 4; + break; + case M_LIN32: + pixels_per_offset = 2; break; default: - return 0x1; + return VESA_MODE_UNSUPPORTED; } - return 0x00; + + IO_Read(0x3da); // reset attribute flipflop + IO_Write(0x3c0,0x13 | 0x20); // panning register, screen on + Bit8u panning = IO_Read(0x3c1); + + Bitu virtual_screen_width = vga.config.scan_len * pixels_per_offset; + Bitu start_pixel = vga.config.display_start * (pixels_per_offset/2) + + panning / panning_factor; + + y = start_pixel / virtual_screen_width; + x = start_pixel % virtual_screen_width; + return VESA_SUCCESS; } static Bitu VESA_SetWindow(void) { @@ -453,6 +527,10 @@ static Bitu VESA_PMSetPalette(void) { return 0; } static Bitu VESA_PMSetStart(void) { + // This function is from VBE2 and directly sets the VGA + // display start address. + + // TODO wait for retrace in case bl==0x80 Bit32u start = (reg_dx << 16) | reg_cx; vga.config.display_start = start; return 0; From b986ab88f766863cd23294c57abd8b45450d8645 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 6 Mar 2011 17:20:32 +0000 Subject: [PATCH 3595/4131] forgot one. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3685 --- src/cpu/cpu.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 8e75211b..238df304 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -2056,6 +2056,7 @@ static Bits HLT_Decode(void) { void CPU_HLT(Bitu oldeip) { reg_eip=oldeip; + CPU_IODelayRemoved += CPU_Cycles; CPU_Cycles=0; cpu.hlt.cs=SegValue(cs); cpu.hlt.eip=reg_eip; From 19517f7ac5ea5757dd5c82fdc0acc05331faf7b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 18 Mar 2011 21:39:12 +0000 Subject: [PATCH 3596/4131] reduce reported sectors per cluster drive (ripsaw; fixes buggy drive geometry calculations in Black Knight (installer) and Tamper) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3686 --- src/dos/dos_programs.cpp | 18 ++++++++++-------- src/dos/drive_local.cpp | 4 +--- src/dos/drive_virtual.cpp | 10 ++++------ 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 5f237186..4b5fa219 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 @@ -126,9 +126,9 @@ public: str_size="512,1,2880,2880";/* All space free */ mediaid=0xF0; /* Floppy 1.44 media */ } else if (type=="dir") { - // 512*127*16383==~1GB total size - // 512*127*4031==~250MB total free size - str_size="512,127,16383,4031"; + // 512*32*65535==~1GB total size + // 512*32*16000==~250MB total free size + str_size="512,32,65535,16000"; mediaid=0xF8; /* Hard Disk */ } else if (type=="cdrom") { str_size="2048,1,65535,0"; @@ -141,11 +141,13 @@ public: std::string mb_size; if(cmd->FindString("-freesize",mb_size,true)) { char teststr[1024]; - Bit16u sizemb = static_cast(atoi(mb_size.c_str())); + Bit16u freesize = static_cast(atoi(mb_size.c_str())); if (type=="floppy") { - sprintf(teststr,"512,1,2880,%d",sizemb*1024/(512*1)); + // freesize in kb + sprintf(teststr,"512,1,2880,%d",freesize*1024/(512*1)); } else { - sprintf(teststr,"512,127,16513,%d",sizemb*1024*1024/(512*127)); + // freesize in mb + sprintf(teststr,"512,32,65535,%d",freesize*1024*1024/(512*32)); } str_size=teststr; } @@ -1026,7 +1028,7 @@ public: if (type=="floppy") { mediaid=0xF0; } else if (type=="iso") { - str_size="650,127,16513,1700"; + str_size=="2048,1,60000,0"; // ignored, see drive_iso.cpp (AllocationInfo) mediaid=0xF8; fstype = "iso"; } diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 50ae6f1c..f07cb2c3 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 @@ -380,8 +380,6 @@ bool localDrive::Rename(char * oldname,char * newname) { } bool localDrive::AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters) { - /* Always report 100 mb free should be enough */ - /* Total size is always 1 gb */ *_bytes_sector=allocation.bytes_sector; *_sectors_cluster=allocation.sectors_cluster; *_total_clusters=allocation.total_clusters; diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 95bdf187..43619616 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 @@ -248,12 +248,10 @@ bool Virtual_Drive::Rename(char * oldname,char * newname) { } bool Virtual_Drive::AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters) { - /* Always report 100 mb free should be enough */ - /* Total size is always 1 gb */ *_bytes_sector=512; - *_sectors_cluster=127; - *_total_clusters=16513; - *_free_clusters=00; + *_sectors_cluster=32; + *_total_clusters=65535; // total size is always 1 gb + *_free_clusters=0; // nothing free here return true; } From 63bcf1d2ed8ff01b5b306d97f1bfa5a39fec5262 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 23 Mar 2011 08:55:07 +0000 Subject: [PATCH 3597/4131] Add option to delay sysex processing for sensitive real midi devices. Patch 3159289 from jczorkmid and rcblanke (slightly modified). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3687 --- src/dosbox.cpp | 2 ++ src/gui/midi.cpp | 43 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index e1b5ed8d..263ff338 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -480,6 +480,8 @@ void DOSBOX_Init(void) { Pstring = secprop->Add_string("midiconfig",Property::Changeable::WhenIdle,""); Pstring->Set_help("Special configuration options for the device driver. This is usually the id of the device you want to use.\n" + " When using a Roland MT-32 rev. 0 as midi output device, some games may require a delay in order to prevent 'buffer overflow' issues.\n" + " In that case, add 'delaysysex', for example: midiconfig=2 delaysysex\n" " See the README/Manual for more details."); #if C_DEBUG diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 61d15e55..4df68063 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -19,6 +19,8 @@ #include #include #include +#include +#include "SDL.h" #include "dosbox.h" #include "cross.h" @@ -107,12 +109,19 @@ static struct { struct { Bit8u buf[SYSEX_SIZE]; Bitu used; + Bitu delay; + Bit32u start; } sysex; bool available; MidiHandler * handler; } midi; void MIDI_RawOutByte(Bit8u data) { + if (midi.sysex.start) { + Bit32u passed_ticks = GetTicks() - midi.sysex.start; + if (passed_ticks < midi.sysex.delay) SDL_Delay(midi.sysex.delay - passed_ticks); + } + /* Test for a realtime MIDI message */ if (data>=0xf8) { midi.rt_buf[0]=data; @@ -122,11 +131,28 @@ void MIDI_RawOutByte(Bit8u data) { /* Test for a active sysex tranfer */ if (midi.status==0xf0) { if (!(data&0x80)) { - if (midi.sysex.used<(SYSEX_SIZE-1)) midi.sysex.buf[midi.sysex.used++]=data; + if (midi.sysex.used<(SYSEX_SIZE-1)) midi.sysex.buf[midi.sysex.used++] = data; return; } else { - midi.sysex.buf[midi.sysex.used++]=0xf7; - midi.handler->PlaySysex(midi.sysex.buf,midi.sysex.used); + midi.sysex.buf[midi.sysex.used++] = 0xf7; + + if ((midi.sysex.start) && (midi.sysex.used >= 4) && (midi.sysex.used <= 9) && (midi.sysex.buf[1] == 0x41) && (midi.sysex.buf[3] == 0x16)) { + LOG(LOG_ALL,LOG_ERROR)("MIDI:Skipping invalid MT-32 SysEx midi message (too short to contain a checksum)"); + } else { +// LOG(LOG_ALL,LOG_NORMAL)("Play sysex; address:%02X %02X %02X, length:%4d, delay:%3d", midi.sysex.buf[5], midi.sysex.buf[6], midi.sysex.buf[7], midi.sysex.used, midi.sysex.delay); + midi.handler->PlaySysex(midi.sysex.buf, midi.sysex.used); + if (midi.sysex.start) { + if (midi.sysex.buf[5] == 0x7F) { + midi.sysex.delay = 290; // All Parameters reset + } else if (midi.sysex.buf[5] == 0x10 && midi.sysex.buf[6] == 0x00 && midi.sysex.buf[7] == 0x04) { + midi.sysex.delay = 145; // Viking Child + } else if (midi.sysex.buf[5] == 0x10 && midi.sysex.buf[6] == 0x00 && midi.sysex.buf[7] == 0x01) { + midi.sysex.delay = 30; // Dark Sun 1 + } else midi.sysex.delay = (Bitu)(((float)(midi.sysex.used) * 1.25f) * 1000.0f / 3125.0f) + 2; + midi.sysex.start = GetTicks(); + } + } + LOG(LOG_ALL,LOG_NORMAL)("Sysex message size %d",midi.sysex.used); if (CaptureState & CAPTURE_MIDI) { CAPTURE_AddMidi( true, midi.sysex.used-1, &midi.sysex.buf[1]); @@ -163,10 +189,19 @@ public: MIDI(Section* configuration):Module_base(configuration){ Section_prop * section=static_cast(configuration); const char * dev=section->Get_string("mididevice"); - const char * conf=section->Get_string("midiconfig"); + std::string fullconf=section->Get_string("midiconfig"); /* If device = "default" go for first handler that works */ MidiHandler * handler; // MAPPER_AddHandler(MIDI_SaveRawEvent,MK_f8,MMOD1|MMOD2,"caprawmidi","Cap MIDI"); + midi.sysex.delay = 0; + midi.sysex.start = 0; + if (fullconf.find("delaysysex") != std::string::npos) { + midi.sysex.start = GetTicks(); + fullconf.erase(fullconf.find("delaysysex")); + LOG_MSG("MIDI:Using delayed SysEx processing"); + } + remove(fullconf.begin(), fullconf.end(), ' '); + const char * conf = fullconf.c_str(); midi.status=0x00; midi.cmd_pos=0; midi.cmd_len=0; From 38a357021ccf3a6fa8c095ef5d9269a4dc64cf5b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 23 Mar 2011 09:50:13 +0000 Subject: [PATCH 3598/4131] Include correct headers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3688 --- src/gui/midi.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 4df68063..8bc75a57 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -19,7 +19,9 @@ #include #include #include -#include +#include +#include + #include "SDL.h" #include "dosbox.h" @@ -29,6 +31,7 @@ #include "mapper.h" #include "pic.h" #include "hardware.h" +#include "timer.h" #define SYSEX_SIZE 1024 #define RAWBUF 1024 @@ -200,7 +203,7 @@ public: fullconf.erase(fullconf.find("delaysysex")); LOG_MSG("MIDI:Using delayed SysEx processing"); } - remove(fullconf.begin(), fullconf.end(), ' '); + std::remove(fullconf.begin(), fullconf.end(), ' '); const char * conf = fullconf.c_str(); midi.status=0x00; midi.cmd_pos=0; From b25d481e660d9c32b76d2a41cd12126742b20f81 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 Mar 2011 10:46:56 +0000 Subject: [PATCH 3599/4131] Fix startup detection of numlock and capslock. Improve behaviour with SDL 1.2.14 with respect to lock keys. What works: - dosbox compiled against SDL < 1.2.14 used with SDL < 1.2.14 - dosbox compiled against SDL < 1.2.14 used with SDL >= 1.2.14 - dosbox compiled against SDL >=1.2.14 used with SDL >= 1.2.14 What doesn't work: - dosbox compiled against SDL >=1.2.14 used with SDL < 1.2.14 - debian/ubuntu SDL < 1.2.14. (Check comment in src/gui/sdlmain.cpp on how to fix it.) Untested: - debian/ubuntu SDL >=1.2.14. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3689 --- src/gui/sdl_mapper.cpp | 8 ++++++-- src/gui/sdlmain.cpp | 4 ++++ src/ints/bios_keyboard.cpp | 13 ++++++++++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 54ab6da8..9d83a770 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -2362,17 +2362,21 @@ void MAPPER_Init(void) { if (!MAPPER_LoadBinds()) CreateDefaultBinds(); if (SDL_GetModState()&KMOD_CAPS) { for (CBindList_it bit=caps_lock_event->bindlist.begin();bit!=caps_lock_event->bindlist.end();bit++) { - (*bit)->ActivateBind(32767,true,true); #if SDL_VERSION_ATLEAST(1, 2, 14) + (*bit)->ActivateBind(32767,true,false); (*bit)->DeActivateBind(false); +#else + (*bit)->ActivateBind(32767,true,true); //Skip the action itself as bios_keyboard.cpp handles the startup state. #endif } } if (SDL_GetModState()&KMOD_NUM) { for (CBindList_it bit=num_lock_event->bindlist.begin();bit!=num_lock_event->bindlist.end();bit++) { - (*bit)->ActivateBind(32767,true,true); #if SDL_VERSION_ATLEAST(1, 2, 14) + (*bit)->ActivateBind(32767,true,false); (*bit)->DeActivateBind(false); +#else + (*bit)->ActivateBind(32767,true,true); #endif } } diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index b5cdd332..33cd4c21 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1770,6 +1770,10 @@ int main(int argc, char* argv[]) { /* Init SDL */ #if SDL_VERSION_ATLEAST(1, 2, 14) + /* Or debian/ubuntu with older libsdl version as they have done this themselves, but then differently. + * with this variable they will work correctly. I've only tested the 1.2.14 behaviour against the windows version + * of libsdl + */ putenv(const_cast("SDL_DISABLE_LOCK_KEYS=1")); #endif if ( SDL_Init( SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 272e69cc..f4e8fc20 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -33,6 +33,8 @@ * Define the following if this is the case */ #if SDL_VERSION_ATLEAST(1, 2, 14) #define CAN_USE_LOCK 1 +/* For lower versions of SDL we also use a slight hack to get the startup states of numclock and capslock right. + * The proper way is in the mapper, but the repeating key is an unwanted side effect for lower versions of SDL */ #endif static Bitu call_int16,call_irq1,call_irq6; @@ -592,9 +594,14 @@ static void InitBiosSegment(void) { mem_writew(BIOS_KEYBOARD_BUFFER_TAIL,0x1e); Bit8u flag1 = 0; Bit8u leds = 16; /* Ack recieved */ -//MAPPER_Init takes care of this now ? -// if(startup_state_capslock) { flag1|=0x40; leds|=0x04;} -// if(startup_state_numlock){ flag1|=0x20; leds|=0x02;} + +#if SDL_VERSION_ATLEAST(1, 2, 14) +//Nothing, mapper handles all. +#else + if (startup_state_capslock) { flag1|=0x40; leds|=0x04;} + if (startup_state_numlock) { flag1|=0x20; leds|=0x02;} +#endif + mem_writeb(BIOS_KEYBOARD_FLAGS1,flag1); mem_writeb(BIOS_KEYBOARD_FLAGS2,0); mem_writeb(BIOS_KEYBOARD_FLAGS3,16); /* Enhanced keyboard installed */ From 7d0d5bd95c81784719e9745f5be411969eeef7af Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 29 Mar 2011 12:44:15 +0000 Subject: [PATCH 3600/4131] Make newer GCCs happy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3690 --- src/cpu/core_dyn_x86.cpp | 7 ++----- src/cpu/core_dyn_x86/decoder.h | 8 ++++++-- src/cpu/core_dynrec.cpp | 8 +++----- src/cpu/core_dynrec/decoder.h | 8 ++++++-- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 851a04ed..ddf36393 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -61,11 +61,8 @@ #define DYN_PAGE_HASH (4096>>DYN_HASH_SHIFT) #define DYN_LINKS (16) -#if 0 -#define DYN_LOG LOG_MSG -#else -#define DYN_LOG -#endif +//#define DYN_LOG 1 //Turn logging on + #if C_FPU #define CPU_FPU 1 //Enable FPU escape instructions diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 0f024541..dcdbcb30 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -2104,7 +2104,9 @@ restart_prefix: case 0xbf:dyn_mov_ev_gw(true);break; default: - DYN_LOG("Unhandled dual opcode 0F%02X",dual_code); +#if DYN_LOG + LOG_MSG("Unhandled dual opcode 0F%02X",dual_code); +#endif goto illegalopcode; } }break; @@ -2670,7 +2672,9 @@ restart_prefix: }} break; default: -// DYN_LOG("Dynamic unhandled opcode %X",opcode); +#if DYN_LOG +// LOG_MSG("Dynamic unhandled opcode %X",opcode); +#endif goto illegalopcode; } } diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index 79f9e15a..aa607653 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -62,11 +62,9 @@ #define DYN_PAGE_HASH (4096>>DYN_HASH_SHIFT) #define DYN_LINKS (16) -#if 0 -#define DYN_LOG LOG_MSG -#else -#define DYN_LOG -#endif + +//#define DYN_LOG 1 //Turn Logging on. + #if C_FPU #define CPU_FPU 1 //Enable FPU escape instructions diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h index 0ca887c2..2d658e4c 100644 --- a/src/cpu/core_dynrec/decoder.h +++ b/src/cpu/core_dynrec/decoder.h @@ -242,7 +242,9 @@ restart_prefix: case 0xbf:dyn_movx_ev_gw(true);break; default: -// DYN_LOG("Unhandled dual opcode 0F%02X",dual_code); +#if DYN_LOG +// LOG_MSG("Unhandled dual opcode 0F%02X",dual_code); +#endif goto illegalopcode; } break; @@ -579,7 +581,9 @@ restart_prefix: break; default: -// DYN_LOG("Dynrec unhandled opcode %X",opcode); +#if DYN_LOG +// LOG_MSG("Dynrec unhandled opcode %X",opcode); +#endif goto illegalopcode; } } From 41d420d47edae82e4b565b3ad4a3b72f5039f62c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 31 Mar 2011 19:31:21 +0000 Subject: [PATCH 3601/4131] Make gcc 4.6 happy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3691 --- include/dos_inc.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/dos_inc.h b/include/dos_inc.h index 4f5ac715..8fa69301 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -28,6 +28,8 @@ #include "mem.h" #endif +#include //for offsetof + #ifdef _MSC_VER #pragma pack (1) #endif From 3059df4278f5f88679f6c45e0afcfe9b1e2f232f Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sat, 2 Apr 2011 20:38:41 +0000 Subject: [PATCH 3602/4131] Timer patch - remember timer value beyond mode switch: Fixes 3DMania, Dunkle Schatten with Soundblaster, glitch in Panic demo - set a defined short interrupt response time for CPU-induced interrupts Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3692 --- src/hardware/pic.cpp | 11 +++++++++++ src/hardware/timer.cpp | 31 +++++++++++++++++++------------ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 412bd467..983d61f8 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -244,6 +244,17 @@ static Bitu read_data(Bitu port,Bitu iolen) { void PIC_ActivateIRQ(Bitu irq) { + if (GCC_UNLIKELY(CPU_Cycles)) { + // CPU_Cycles nonzero means the interrupt was triggered by an I/O + // register write rather than an event. + // Real hardware executes 0 to ~13 NOPs or comparable instructions + // before the processor picks up the interrupt. Let's try with 2 + // cycles here. + // Required by Panic demo (irq0), It came from the desert (MPU401) + // Does it matter if CPU_CycleLeft becomes negative? + CPU_CycleLeft += (CPU_Cycles-2); + CPU_Cycles=2; + } if( irq < 8 ) { irqs[irq].active = true; if (!irqs[irq].masked) { diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index a4a7c503..85f7998e 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -138,8 +138,14 @@ static void counter_latch(Bitu counter) { p->go_read_latch=false; //If gate2 is disabled don't update the read_latch - if(counter == 2 && !gate2 && p->mode !=1) return; - + if (counter == 2 && !gate2 && p->mode !=1) return; + if (GCC_UNLIKELY(p->new_mode)) { + double passed_time = PIC_FullIndex() - p->start; + Bitu ticks_since_then = (Bitu)(passed_time / (1000.0/PIT_TICK_RATE)); + //if (p->mode==3) ticks_since_then /= 2; // TODO figure this out on real hardware + p->read_latch -= ticks_since_then; + return; + } double index=PIC_FullIndex()-p->start; switch (p->mode) { case 4: /* Software Triggered Strobe */ @@ -299,6 +305,10 @@ static void write_p43(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { /* Counter latch command */ counter_latch(latch); } else { + // save output status to be used with timer 0 irq + bool old_output = counter_output(0); + // save the current count value to be re-used in undocumented newmode + counter_latch(latch); pit[latch].bcd = (val&1)>0; if (val & 1) { if(pit[latch].cntr>=9999) pit[latch].cntr=9999; @@ -309,6 +319,8 @@ static void write_p43(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { pit[latch].counterstatus_set=false; latched_timerstatus_locked=false; } + pit[latch].start = PIC_FullIndex(); // for undocumented newmode + pit[latch].go_read_latch = true; pit[latch].update_count = false; pit[latch].counting = false; pit[latch].read_state = (val >> 4) & 0x03; @@ -317,9 +329,7 @@ static void write_p43(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { if (mode > 5) mode -= 4; //6,7 become 2 and 3 - /* Don't set it directly so counter_output uses the old mode */ - /* That's theory. It breaks panic. So set it here again */ - if(!pit[latch].mode) pit[latch].mode = mode; + pit[latch].mode = mode; /* If the line goes from low to up => generate irq. * ( BUT needs to stay up until acknowlegded by the cpu!!! therefore: ) @@ -327,20 +337,17 @@ static void write_p43(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { * Mode 0 starts with a low line. (so always disable irq) * Mode 2,3 start with a high line. * counter_output tells if the current counter is high or low - * So actually a mode 2 timer enables and disables irq al the time. (not handled) */ + * So actually a mode 3 timer enables and disables irq al the time. (not handled) */ if (latch == 0) { PIC_RemoveEvents(PIT0_Event); - if (!counter_output(0) && mode) { + if((mode != 0)&& !old_output) { PIC_ActivateIRQ(0); - //Don't raise instantaniously. (Origamo) - if(CPU_Cycles < 25) CPU_Cycles = 25; - } - if(!mode) + } else { PIC_DeActivateIRQ(0); + } } pit[latch].new_mode = true; - pit[latch].mode = mode; //Set the correct mode (here) } break; case 3: From c5d76925bb9dc844abfc7c7eab8d79b06e8a4ec3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 10 Apr 2011 15:09:00 +0000 Subject: [PATCH 3603/4131] copy file + file improvements; care less about spaces around the +. Thanks ripsaw Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3693 --- src/shell/shell_cmds.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 01cbec94..f4bce54a 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -586,6 +586,14 @@ void DOS_Shell::CMD_COPY(char * args) { while ( (source_p = StripWord(args)) && *source_p ) { do { char* plus = strchr(source_p,'+'); + // If StripWord() previously cut at a space before a plus then + // set concatenate flag on last source and remove leading plus. + if (plus == source_p && sources.size()) { + sources[sources.size()-1].concat = true; + // If spaces also followed plus then item is only a plus. + if (strlen(++source_p)==0) break; + plus = strchr(source_p,'+'); + } if (plus) *plus++ = 0; safe_strncpy(source_x,source_p,CROSS_LEN); bool has_drive_spec = false; From f214d70367bb0d7d683168f6c1dc5f17861fa612 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 16 Apr 2011 12:23:57 +0000 Subject: [PATCH 3604/4131] Update CALLBACK_Idle to use the callback offset. Fixes memory corruption. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3694 --- src/cpu/callback.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 3524c2f3..385a0c8c 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -65,7 +65,7 @@ void CALLBACK_Idle(void) { Bit16u oldcs=SegValue(cs); Bit32u oldeip=reg_eip; SegSet16(cs,CB_SEG); - reg_eip=call_idle*CB_SIZE; + reg_eip=CB_SOFFSET+call_idle*CB_SIZE; DOSBOX_RunMachine(); reg_eip=oldeip; SegSet16(cs,oldcs); From 66e7ddcea5725ca0fbaa07958a023f001b79451f Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sat, 16 Apr 2011 19:24:09 +0000 Subject: [PATCH 3605/4131] Fix I/O exception caused by callbacks (16 and 32-bit accesses) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3695 --- src/hardware/iohandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index d53ad704..f6db8051 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -328,7 +328,7 @@ void IO_WriteW(Bitu port,Bitu val) { CPU_Push16(reg_ip); Bit16u old_ax = reg_ax; Bit16u old_dx = reg_dx; - reg_al = val; + reg_ax = val; reg_dx = port; RealPt icb = CALLBACK_RealPointer(call_priv_io); SegSet16(cs,RealSeg(icb)); @@ -364,7 +364,7 @@ void IO_WriteD(Bitu port,Bitu val) { CPU_Push16(reg_ip); Bit32u old_eax = reg_eax; Bit16u old_dx = reg_dx; - reg_al = val; + reg_eax = val; reg_dx = port; RealPt icb = CALLBACK_RealPointer(call_priv_io); SegSet16(cs,RealSeg(icb)); From 617fd7006dc6f99aea355e40ef126b867d3c8782 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 19 Apr 2011 19:46:02 +0000 Subject: [PATCH 3606/4131] fix sb halt/continue sequence when no transfer in progress (thanks to tcostin, fixes some GameWizard crash) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3696 --- src/hardware/sblaster.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 0c35000f..b6989abf 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 @@ -900,6 +900,9 @@ static void DSP_DoCommand(void) { case 0xd0: /* Halt 8-bit DMA */ // DSP_ChangeMode(MODE_NONE); // Games sometimes already program a new dma before stopping, gives noise + if (sb.mode==MODE_NONE) { + // possibly different code here that does not switch to MODE_DMA_PAUSE + } sb.mode=MODE_DMA_PAUSE; PIC_RemoveEvents(END_DMA_Event); break; @@ -920,7 +923,7 @@ static void DSP_DoCommand(void) { case 0xd4: /* Continue DMA 8-bit*/ if (sb.mode==MODE_DMA_PAUSE) { sb.mode=MODE_DMA_MASKED; - sb.dma.chan->Register_Callback(DSP_DMA_CallBack); + if (sb.dma.chan!=NULL) sb.dma.chan->Register_Callback(DSP_DMA_CallBack); } break; case 0xd9: /* Exit Autoinitialize 16-bit */ From 81d9c369aa54bdbfc95b9988c5035547bd3448f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 19 Apr 2011 20:38:42 +0000 Subject: [PATCH 3607/4131] AC flag toggling depends on emulated CPU type (486+) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3697 --- include/regs.h | 2 +- src/cpu/cpu.cpp | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/regs.h b/include/regs.h index 13da9233..46bb33d8 100644 --- a/include/regs.h +++ b/include/regs.h @@ -41,7 +41,7 @@ #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_NORMAL (FMASK_TEST | FLAG_DF | FLAG_TF | FLAG_IF ) #define FMASK_ALL (FMASK_NORMAL | FLAG_IOPL | FLAG_NT) #define SETFLAGBIT(TYPE,TEST) if (TEST) reg_flags|=FLAG_ ## TYPE; else reg_flags&=~FLAG_ ## TYPE diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 238df304..29baa8b6 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -64,7 +64,7 @@ Bitu CPU_AutoDetermineMode = 0; Bitu CPU_ArchitectureType = CPU_ARCHTYPE_MIXED; -Bitu CPU_flag_id_toggle=0; +Bitu CPU_extflags_toggle=0; // ID and AC flags may be toggled depending on emulated CPU architecture Bitu CPU_PrefetchQueueSize=0; @@ -170,7 +170,7 @@ PhysPt SelBase(Bitu sel) { void CPU_SetFlags(Bitu word,Bitu mask) { - mask|=CPU_flag_id_toggle; // ID-flag can be toggled on cpuid-supporting CPUs + mask|=CPU_extflags_toggle; // ID-flag and AC-flag can be toggled on CPUID-supporting CPUs reg_flags=(reg_flags & ~mask)|(word & mask)|2; cpu.direction=1-((reg_flags & FLAG_DF) >> 9); } @@ -2389,8 +2389,9 @@ public: CPU_ArchitectureType = CPU_ARCHTYPE_PENTIUMSLOW; } - if (CPU_ArchitectureType>=CPU_ARCHTYPE_486NEWSLOW) CPU_flag_id_toggle=FLAG_ID; - else CPU_flag_id_toggle=0; + if (CPU_ArchitectureType>=CPU_ARCHTYPE_486NEWSLOW) CPU_extflags_toggle=(FLAG_ID|FLAG_AC); + else if (CPU_ArchitectureType>=CPU_ARCHTYPE_486OLDSLOW) CPU_extflags_toggle=(FLAG_AC); + else CPU_extflags_toggle=0; if(CPU_CycleMax <= 0) CPU_CycleMax = 3000; From 832f1bf0d4e98465161fdbafccb96a57fa59084a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 22 Apr 2011 14:18:00 +0000 Subject: [PATCH 3608/4131] add compatibility POST chaining, certain game exiting should look better now (ripsaw, sort of fixes a hangup with Astro Dodge) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3698 --- include/bios.h | 3 ++- src/ints/bios.cpp | 14 +++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/include/bios.h b/include/bios.h index 8f722d6d..d03eef54 100644 --- a/include/bios.h +++ b/include/bios.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -106,6 +106,7 @@ #define BIOS_DEFAULT_IRQ0_LOCATION (RealMake(0xf000,0xfea5)) #define BIOS_DEFAULT_IRQ1_LOCATION (RealMake(0xf000,0xe987)) #define BIOS_DEFAULT_IRQ2_LOCATION (RealMake(0xf000,0xff55)) +#define BIOS_DEFAULT_RESET_LOCATION (RealMake(0xf000,0xe05b)) /* maximum of scancodes handled by keyboard bios routines */ #define MAX_SCAN_CODE 0x58 diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 1f1d20ba..bf5eda52 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 @@ -911,10 +911,14 @@ public: callback[10].Set_RealVec(0x18); RealPt rptr = callback[10].Get_RealPointer(); RealSetVec(0x19,rptr); - // set system BIOS entry point too - phys_writeb(0xFFFF0,0xEA); // FARJMP - phys_writew(0xFFFF1,RealOff(rptr)); // offset - phys_writew(0xFFFF3,RealSeg(rptr)); // segment + // power on selftest routine location + phys_writeb(Real2Phys(BIOS_DEFAULT_RESET_LOCATION)+0,0xEA); // FARJMP + phys_writew(Real2Phys(BIOS_DEFAULT_RESET_LOCATION)+1,RealOff(rptr)); // offset + phys_writew(Real2Phys(BIOS_DEFAULT_RESET_LOCATION)+3,RealSeg(rptr)); // segment + // reset jump (directed to POST) + phys_writeb(0xFFFF0,0xEA); // FARJMP + phys_writew(0xFFFF1,RealOff(BIOS_DEFAULT_RESET_LOCATION)); // offset + phys_writew(0xFFFF3,RealSeg(BIOS_DEFAULT_RESET_LOCATION)); // segment /* Irq 2 */ Bitu call_irq2=CALLBACK_Allocate(); From 2375c15de20779d5a6bdaeceeed89f46a1d7fa61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 23 Apr 2011 10:50:38 +0000 Subject: [PATCH 3609/4131] add function to manually trigger the 16bit sb IRQ (ripsaw; fixes sb16 detection for Assault Wing) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3699 --- src/hardware/sblaster.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index b6989abf..82c31c65 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -982,6 +982,10 @@ static void DSP_DoCommand(void) { case 0xf2: /* Trigger 8bit IRQ */ SB_RaiseIRQ(SB_IRQ_8); break; + case 0xf3: /* Trigger 16bit IRQ */ + DSP_SB16_ONLY; + SB_RaiseIRQ(SB_IRQ_16); + break; case 0xf8: /* Undocumented, pre-SB16 only */ DSP_FlushData(); DSP_AddData(0); From 999f33de27f8285c1f31bb17ce564fccdeabe1c3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 26 Apr 2011 09:34:55 +0000 Subject: [PATCH 3610/4131] Update year. Remove CVS tags Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3700 --- acinclude.m4 | 2 +- include/bios_disk.h | 2 +- include/callback.h | 3 +-- include/control.h | 3 +-- include/cpu.h | 3 +-- include/cross.h | 3 +-- include/debug.h | 2 +- include/dma.h | 3 +-- include/dos_inc.h | 3 +-- include/dos_system.h | 3 +-- include/dosbox.h | 3 +-- include/fpu.h | 2 +- include/hardware.h | 3 +-- include/inout.h | 3 +-- include/ipx.h | 3 +-- include/ipxserver.h | 2 +- include/joystick.h | 3 +-- include/keyboard.h | 2 +- include/logging.h | 18 ++++++++++++++++++ include/mapper.h | 2 +- include/mem.h | 2 +- include/mixer.h | 3 +-- include/mouse.h | 3 +-- include/paging.h | 3 +-- include/pic.h | 2 +- include/programs.h | 3 +-- include/regs.h | 2 +- include/render.h | 2 +- include/serialport.h | 3 +-- include/setup.h | 3 +-- include/shell.h | 3 +-- include/support.h | 3 +-- include/timer.h | 2 +- include/vga.h | 3 +-- include/video.h | 3 +-- src/cpu/callback.cpp | 3 +-- src/cpu/core_dyn_x86.cpp | 3 +-- src/cpu/core_dyn_x86/cache.h | 3 +-- src/cpu/core_dyn_x86/decoder.h | 3 +-- src/cpu/core_dyn_x86/dyn_fpu.h | 3 +-- src/cpu/core_dyn_x86/dyn_fpu_dh.h | 3 +-- src/cpu/core_dyn_x86/helpers.h | 18 ++++++++++++++++++ src/cpu/core_dyn_x86/risc_x86.h | 3 +-- src/cpu/core_dyn_x86/string.h | 2 +- src/cpu/core_dynrec.cpp | 3 +-- src/cpu/core_dynrec/cache.h | 2 +- src/cpu/core_dynrec/decoder.h | 3 +-- src/cpu/core_dynrec/decoder_basic.h | 3 +-- src/cpu/core_dynrec/decoder_opcodes.h | 3 +-- src/cpu/core_dynrec/dyn_fpu.h | 3 +-- src/cpu/core_dynrec/operators.h | 3 +-- src/cpu/core_dynrec/risc_armv4le-common.h | 3 +-- src/cpu/core_dynrec/risc_armv4le-o3.h | 3 +-- src/cpu/core_dynrec/risc_armv4le-s3.h | 3 +-- src/cpu/core_dynrec/risc_armv4le-thumb-iw.h | 3 +-- src/cpu/core_dynrec/risc_armv4le-thumb-niw.h | 3 +-- src/cpu/core_dynrec/risc_armv4le-thumb.h | 3 +-- src/cpu/core_dynrec/risc_armv4le.h | 3 +-- src/cpu/core_dynrec/risc_mipsel32.h | 3 +-- src/cpu/core_dynrec/risc_x64.h | 1 - src/cpu/core_dynrec/risc_x86.h | 3 +-- src/cpu/core_full.cpp | 2 +- src/cpu/core_full/ea_lookup.h | 18 ++++++++++++++++++ src/cpu/core_full/load.h | 18 ++++++++++++++++++ src/cpu/core_full/loadwrite.h | 18 ++++++++++++++++++ src/cpu/core_full/op.h | 18 ++++++++++++++++++ src/cpu/core_full/optable.h | 18 ++++++++++++++++++ src/cpu/core_full/save.h | 18 ++++++++++++++++++ src/cpu/core_full/string.h | 18 ++++++++++++++++++ src/cpu/core_full/support.h | 18 ++++++++++++++++++ src/cpu/core_normal.cpp | 2 +- src/cpu/core_normal/helpers.h | 2 +- src/cpu/core_normal/prefix_0f.h | 2 +- src/cpu/core_normal/prefix_66.h | 2 +- src/cpu/core_normal/prefix_66_0f.h | 2 +- src/cpu/core_normal/prefix_none.h | 2 +- src/cpu/core_normal/string.h | 18 ++++++++++++++++++ src/cpu/core_normal/support.h | 2 +- src/cpu/core_normal/table_ea.h | 2 +- src/cpu/core_prefetch.cpp | 3 +-- src/cpu/core_simple.cpp | 2 +- src/cpu/cpu.cpp | 3 +-- src/cpu/flags.cpp | 2 +- src/cpu/instructions.h | 2 +- src/cpu/lazyflags.h | 2 +- src/cpu/modrm.cpp | 2 +- src/cpu/modrm.h | 2 +- src/cpu/paging.cpp | 3 +-- src/debug/debug.cpp | 3 +-- src/debug/debug_gui.cpp | 3 +-- src/debug/debug_inc.h | 3 +-- src/debug/debug_win32.cpp | 2 +- src/debug/disasm_tables.h | 2 +- src/dos/cdrom.cpp | 3 +-- src/dos/cdrom.h | 18 ++++++++++++++++++ src/dos/cdrom_aspi_win32.cpp | 3 +-- src/dos/cdrom_image.cpp | 3 +-- src/dos/cdrom_ioctl_linux.cpp | 2 +- src/dos/cdrom_ioctl_os2.cpp | 3 +-- src/dos/cdrom_ioctl_win32.cpp | 3 +-- src/dos/dev_con.h | 3 +-- src/dos/dos.cpp | 3 +-- src/dos/dos_classes.cpp | 3 +-- src/dos/dos_devices.cpp | 3 +-- src/dos/dos_execute.cpp | 3 +-- src/dos/dos_files.cpp | 3 +-- src/dos/dos_ioctl.cpp | 3 +-- src/dos/dos_keyboard_layout.cpp | 1 - src/dos/dos_memory.cpp | 3 +-- src/dos/dos_misc.cpp | 3 +-- src/dos/dos_mscdex.cpp | 3 +-- src/dos/dos_programs.cpp | 1 - src/dos/dos_tables.cpp | 3 +-- src/dos/drive_cache.cpp | 3 +-- src/dos/drive_fat.cpp | 3 +-- src/dos/drive_iso.cpp | 3 +-- src/dos/drive_local.cpp | 1 - src/dos/drives.cpp | 3 +-- src/dos/drives.h | 3 +-- src/dosbox.cpp | 3 +-- src/fpu/fpu.cpp | 3 +-- src/fpu/fpu_instructions.h | 3 +-- src/fpu/fpu_instructions_x86.h | 3 +-- src/gui/dosbox_logo.h | 3 +-- src/gui/midi.cpp | 2 +- src/gui/midi_alsa.h | 3 +-- src/gui/midi_coreaudio.h | 3 +-- src/gui/midi_oss.h | 2 +- src/gui/midi_win32.h | 3 +-- src/gui/render.cpp | 3 +-- src/gui/render_loops.h | 2 +- src/gui/render_scalers.cpp | 2 +- src/gui/render_scalers.h | 2 +- src/gui/render_simple.h | 3 +-- src/gui/render_templates.h | 2 +- src/gui/render_templates_hq.h | 2 +- src/gui/render_templates_hq2x.h | 2 +- src/gui/render_templates_hq3x.h | 2 +- src/gui/render_templates_sai.h | 2 +- src/gui/sdl_gui.cpp | 3 +-- src/gui/sdl_mapper.cpp | 3 +-- src/gui/sdlmain.cpp | 7 +++---- src/hardware/adlib.cpp | 3 +-- src/hardware/adlib.h | 3 +-- src/hardware/cmos.cpp | 3 +-- src/hardware/dbopl.cpp | 3 +-- src/hardware/dbopl.h | 2 +- src/hardware/disney.cpp | 3 +-- src/hardware/dma.cpp | 3 +-- src/hardware/gameblaster.cpp | 2 +- src/hardware/gus.cpp | 3 +-- src/hardware/hardware.cpp | 3 +-- src/hardware/iohandler.cpp | 3 +-- src/hardware/ipx.cpp | 3 +-- src/hardware/ipxserver.cpp | 3 +-- src/hardware/joystick.cpp | 3 +-- src/hardware/keyboard.cpp | 3 +-- src/hardware/memory.cpp | 3 +-- src/hardware/mixer.cpp | 3 +-- src/hardware/mpu401.cpp | 3 +-- src/hardware/opl.cpp | 2 +- src/hardware/opl.h | 2 +- src/hardware/pcspeaker.cpp | 3 +-- src/hardware/pic.cpp | 3 +-- src/hardware/sblaster.cpp | 1 - src/hardware/serialport/directserial.cpp | 3 +-- src/hardware/serialport/directserial.h | 3 +-- src/hardware/serialport/libserial.cpp | 3 +-- src/hardware/serialport/libserial.h | 3 +-- src/hardware/serialport/misc_util.cpp | 2 +- src/hardware/serialport/misc_util.h | 3 +-- src/hardware/serialport/nullmodem.cpp | 3 +-- src/hardware/serialport/nullmodem.h | 3 +-- src/hardware/serialport/serialdummy.cpp | 3 +-- src/hardware/serialport/serialdummy.h | 3 +-- src/hardware/serialport/serialport.cpp | 3 +-- src/hardware/serialport/softmodem.cpp | 3 +-- src/hardware/serialport/softmodem.h | 3 +-- src/hardware/tandy_sound.cpp | 2 +- src/hardware/timer.cpp | 3 +-- src/hardware/vga.cpp | 3 +-- src/hardware/vga_attr.cpp | 3 +-- src/hardware/vga_crtc.cpp | 3 +-- src/hardware/vga_dac.cpp | 2 +- src/hardware/vga_draw.cpp | 3 +-- src/hardware/vga_gfx.cpp | 3 +-- src/hardware/vga_memory.cpp | 3 +-- src/hardware/vga_misc.cpp | 3 +-- src/hardware/vga_other.cpp | 3 +-- src/hardware/vga_paradise.cpp | 3 +-- src/hardware/vga_s3.cpp | 3 +-- src/hardware/vga_seq.cpp | 3 +-- src/hardware/vga_tseng.cpp | 3 +-- src/hardware/vga_xga.cpp | 3 +-- src/ints/bios.cpp | 1 - src/ints/bios_disk.cpp | 3 +-- src/ints/bios_keyboard.cpp | 3 +-- src/ints/ems.cpp | 3 +-- src/ints/int10.cpp | 3 +-- src/ints/int10.h | 3 +-- src/ints/int10_char.cpp | 3 +-- src/ints/int10_memory.cpp | 3 +-- src/ints/int10_misc.cpp | 3 +-- src/ints/int10_modes.cpp | 3 +-- src/ints/int10_pal.cpp | 2 +- src/ints/int10_put_pixel.cpp | 3 +-- src/ints/int10_vesa.cpp | 3 +-- src/ints/int10_video_state.cpp | 3 +-- src/ints/int10_vptable.cpp | 3 +-- src/ints/mouse.cpp | 3 +-- src/ints/xms.cpp | 3 +-- src/ints/xms.h | 2 +- src/libs/gui_tk/gui_tk.cpp | 1 - src/libs/gui_tk/gui_tk.h | 1 - src/libs/zmbv/drvproc.cpp | 2 +- src/libs/zmbv/zmbv.cpp | 2 +- src/libs/zmbv/zmbv.h | 2 +- src/libs/zmbv/zmbv_vfw.cpp | 2 +- src/misc/cross.cpp | 3 +-- src/misc/messages.cpp | 3 +-- src/misc/programs.cpp | 3 +-- src/misc/setup.cpp | 3 +-- src/misc/support.cpp | 3 +-- src/shell/shell.cpp | 3 +-- src/shell/shell_batch.cpp | 3 +-- src/shell/shell_cmds.cpp | 3 +-- src/shell/shell_misc.cpp | 3 +-- 227 files changed, 425 insertions(+), 369 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 0a9f3101..29474ec4 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -305,7 +305,7 @@ AC_SUBST(ALSA_LIBS) AH_TOP([ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/include/bios_disk.h b/include/bios_disk.h index 861d96e3..ca136735 100644 --- a/include/bios_disk.h +++ b/include/bios_disk.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/include/callback.h b/include/callback.h index c4e6fa6e..ca557652 100644 --- a/include/callback.h +++ b/include/callback.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.h,v 1.26 2009-08-23 17:24:54 c2woody Exp $ */ #ifndef DOSBOX_CALLBACK_H #define DOSBOX_CALLBACK_H diff --git a/include/control.h b/include/control.h index 2c157277..e500db28 100644 --- a/include/control.h +++ b/include/control.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: control.h,v 1.2 2009-05-27 09:15:40 qbix79 Exp $ */ #ifndef DOSBOX_CONTROL_H #define DOSBOX_CONTROL_H diff --git a/include/cpu.h b/include/cpu.h index d18caa2f..0903ffb5 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.h,v 1.57 2009-05-27 09:15:40 qbix79 Exp $ */ #ifndef DOSBOX_CPU_H #define DOSBOX_CPU_H diff --git a/include/cross.h b/include/cross.h index 697cb6ee..73f954ee 100644 --- a/include/cross.h +++ b/include/cross.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * 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 DOSBOX_CROSS_H #define DOSBOX_CROSS_H diff --git a/include/debug.h b/include/debug.h index d0684923..031e6831 100644 --- a/include/debug.h +++ b/include/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/include/dma.h b/include/dma.h index acf724ee..71a40b85 100644 --- a/include/dma.h +++ b/include/dma.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dma.h,v 1.20 2009-07-24 09:56:14 c2woody Exp $ */ #ifndef DOSBOX_DMA_H #define DOSBOX_DMA_H diff --git a/include/dos_inc.h b/include/dos_inc.h index 8fa69301..3091c19a 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.83 2009-10-28 21:45:12 qbix79 Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H diff --git a/include/dos_system.h b/include/dos_system.h index 34d99fc2..d59a7d7f 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * 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 DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H diff --git a/include/dosbox.h b/include/dosbox.h index 37f6f702..a72d954c 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.h,v 1.32 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_DOSBOX_H #define DOSBOX_DOSBOX_H diff --git a/include/fpu.h b/include/fpu.h index 67f7db41..8b89934d 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/include/hardware.h b/include/hardware.h index d7da3488..4b925ab4 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: hardware.h,v 1.17 2009-06-23 17:46:05 c2woody Exp $ */ #ifndef DOSBOX_HARDWARE_H #define DOSBOX_HARDWARE_H diff --git a/include/inout.h b/include/inout.h index 798e9db9..cb0b7e57 100644 --- a/include/inout.h +++ b/include/inout.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: inout.h,v 1.13 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_INOUT_H #define DOSBOX_INOUT_H diff --git a/include/ipx.h b/include/ipx.h index 27c984ff..24a1b421 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.h,v 1.13 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_IPX_H #define DOSBOX_IPX_H diff --git a/include/ipxserver.h b/include/ipxserver.h index e31c1754..c10fc4a9 100644 --- a/include/ipxserver.h +++ b/include/ipxserver.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/include/joystick.h b/include/joystick.h index fe39e5e3..02f00a48 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: joystick.h,v 1.13 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_JOYSTICK_H #define DOSBOX_JOYSTICK_H void JOYSTICK_Enable(Bitu which,bool enabled); diff --git a/include/keyboard.h b/include/keyboard.h index 0e60f290..af754c5f 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/include/logging.h b/include/logging.h index ae3daae9..e645d2ea 100644 --- a/include/logging.h +++ b/include/logging.h @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2011 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_LOGGING_H #define DOSBOX_LOGGING_H enum LOG_TYPES { diff --git a/include/mapper.h b/include/mapper.h index a59322a8..ba565157 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/include/mem.h b/include/mem.h index 73686ae2..1b40c553 100644 --- a/include/mem.h +++ b/include/mem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/include/mixer.h b/include/mixer.h index b9ca8824..ed9669ab 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * 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 diff --git a/include/mouse.h b/include/mouse.h index 74ff0105..3a318ea8 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.h,v 1.15 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_MOUSE_H diff --git a/include/paging.h b/include/paging.h index f7198f8f..13fee9b9 100644 --- a/include/paging.h +++ b/include/paging.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.33 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H diff --git a/include/pic.h b/include/pic.h index 8b6e2f4d..1c8a0a32 100644 --- a/include/pic.h +++ b/include/pic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/include/programs.h b/include/programs.h index 96f84b0e..1006ac83 100644 --- a/include/programs.h +++ b/include/programs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.h,v 1.19 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_PROGRAMS_H #define DOSBOX_PROGRAMS_H diff --git a/include/regs.h b/include/regs.h index 46bb33d8..07a11a65 100644 --- a/include/regs.h +++ b/include/regs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/include/render.h b/include/render.h index 1d703e2e..25fed201 100644 --- a/include/render.h +++ b/include/render.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/include/serialport.h b/include/serialport.h index aa2446a2..9ec75778 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.h,v 1.18 2009-09-25 23:40:48 h-a-l-9000 Exp $ */ #ifndef DOSBOX_SERIALPORT_H #define DOSBOX_SERIALPORT_H diff --git a/include/setup.h b/include/setup.h index e79af711..e14c1cb3 100644 --- a/include/setup.h +++ b/include/setup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.41 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H diff --git a/include/shell.h b/include/shell.h index 7d1f3c05..c131f9e4 100644 --- a/include/shell.h +++ b/include/shell.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.h,v 1.28 2009-07-03 19:36:57 qbix79 Exp $ */ #ifndef DOSBOX_SHELL_H #define DOSBOX_SHELL_H diff --git a/include/support.h b/include/support.h index 32e1e202..93c94ea8 100644 --- a/include/support.h +++ b/include/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.h,v 1.18 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_SUPPORT_H #define DOSBOX_SUPPORT_H diff --git a/include/timer.h b/include/timer.h index b4be740e..f4fb0c52 100644 --- a/include/timer.h +++ b/include/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/include/vga.h b/include/vga.h index dd6f41b9..95aa8f07 100644 --- a/include/vga.h +++ b/include/vga.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga.h,v 1.48 2009-11-03 21:06:59 h-a-l-9000 Exp $ */ #ifndef DOSBOX_VGA_H #define DOSBOX_VGA_H diff --git a/include/video.h b/include/video.h index 7c7af5e2..b7062958 100644 --- a/include/video.h +++ b/include/video.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: video.h,v 1.26 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef DOSBOX_VIDEO_H #define DOSBOX_VIDEO_H diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 385a0c8c..ff5c92d7 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.42 2009-08-23 17:24:54 c2woody Exp $ */ #include #include diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index ddf36393..6450a943 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: core_dyn_x86.cpp,v 1.36 2009-07-20 17:55:52 c2woody Exp $ */ #include "dosbox.h" diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index b5bc7b54..6eeeeae7 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cache.h,v 1.20 2009-07-12 20:13:05 c2woody Exp $ */ class CacheBlock { public: diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index dcdbcb30..80e2299f 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: decoder.h,v 1.59 2009-10-18 17:52:09 c2woody Exp $ */ #define X86_DYNFPU_DH_ENABLED #define X86_INLINED_MEMACCESS diff --git a/src/cpu/core_dyn_x86/dyn_fpu.h b/src/cpu/core_dyn_x86/dyn_fpu.h index ab23152c..067d8493 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu.h +++ b/src/cpu/core_dyn_x86/dyn_fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dyn_fpu.h,v 1.5 2009-09-23 20:55:19 c2woody Exp $ */ #include "dosbox.h" #if C_FPU diff --git a/src/cpu/core_dyn_x86/dyn_fpu_dh.h b/src/cpu/core_dyn_x86/dyn_fpu_dh.h index cc48a02f..47dc7572 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu_dh.h +++ b/src/cpu/core_dyn_x86/dyn_fpu_dh.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dyn_fpu_dh.h,v 1.7 2009-09-23 20:55:19 c2woody Exp $ */ #include "dosbox.h" #if C_FPU diff --git a/src/cpu/core_dyn_x86/helpers.h b/src/cpu/core_dyn_x86/helpers.h index b1e67759..727a9735 100644 --- a/src/cpu/core_dyn_x86/helpers.h +++ b/src/cpu/core_dyn_x86/helpers.h @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2011 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. + */ + static bool dyn_helper_divb(Bit8u val) { if (!val) return CPU_PrepareException(0,0); Bitu quo=reg_ax / val; diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 849b433a..fdde79bd 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_x86.h,v 1.32 2009-05-27 09:15:41 qbix79 Exp $ */ static void gen_init(void); diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index 388422f4..78813323 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index aa607653..e56d8a2c 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: core_dynrec.cpp,v 1.15 2009-08-02 16:52:33 c2woody Exp $ */ #include "dosbox.h" diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index 16619cb7..3b1a5984 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h index 2d658e4c..4c7dc6fe 100644 --- a/src/cpu/core_dynrec/decoder.h +++ b/src/cpu/core_dynrec/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: decoder.h,v 1.8 2009-10-18 17:52:10 c2woody Exp $ */ #include "decoder_basic.h" diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index ad3b035a..d09012c4 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: decoder_basic.h,v 1.16 2009-10-08 20:01:31 c2woody Exp $ */ /* diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index 8ce6ad13..1a4ca6fd 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: decoder_opcodes.h,v 1.10 2009-10-18 17:52:10 c2woody Exp $ */ /* diff --git a/src/cpu/core_dynrec/dyn_fpu.h b/src/cpu/core_dynrec/dyn_fpu.h index d517e2e5..cc22e394 100644 --- a/src/cpu/core_dynrec/dyn_fpu.h +++ b/src/cpu/core_dynrec/dyn_fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dyn_fpu.h,v 1.8 2009-09-23 20:55:19 c2woody Exp $ */ #include "dosbox.h" diff --git a/src/cpu/core_dynrec/operators.h b/src/cpu/core_dynrec/operators.h index 2ce2e17e..52de9681 100644 --- a/src/cpu/core_dynrec/operators.h +++ b/src/cpu/core_dynrec/operators.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: operators.h,v 1.8 2009-06-25 19:31:43 c2woody Exp $ */ static Bit8u DRC_CALL_CONV dynrec_add_byte(Bit8u op1,Bit8u op2) DRC_FC; diff --git a/src/cpu/core_dynrec/risc_armv4le-common.h b/src/cpu/core_dynrec/risc_armv4le-common.h index 0bfb2819..0c2c53e0 100644 --- a/src/cpu/core_dynrec/risc_armv4le-common.h +++ b/src/cpu/core_dynrec/risc_armv4le-common.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-common.h,v 1.3 2009-05-16 21:52:47 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (common data/functions) */ diff --git a/src/cpu/core_dynrec/risc_armv4le-o3.h b/src/cpu/core_dynrec/risc_armv4le-o3.h index 02bc9f52..44cf859f 100644 --- a/src/cpu/core_dynrec/risc_armv4le-o3.h +++ b/src/cpu/core_dynrec/risc_armv4le-o3.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-o3.h,v 1.6 2009-06-27 12:51:10 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (size-tweaked arm version) */ diff --git a/src/cpu/core_dynrec/risc_armv4le-s3.h b/src/cpu/core_dynrec/risc_armv4le-s3.h index 86908025..d4e7800a 100644 --- a/src/cpu/core_dynrec/risc_armv4le-s3.h +++ b/src/cpu/core_dynrec/risc_armv4le-s3.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-s3.h,v 1.6 2009-06-27 12:51:10 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (speed-tweaked arm version) */ diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h index d6b8d46c..f1866fe1 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-thumb-iw.h,v 1.5 2009-06-27 12:51:10 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (thumb version with data pool, requires -mthumb-interwork switch when compiling dosbox) */ diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h index 3ca6147e..4b91f227 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-thumb-niw.h,v 1.5 2009-06-27 12:51:10 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (thumb version with data pool) */ diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb.h b/src/cpu/core_dynrec/risc_armv4le-thumb.h index 9a0bc6ca..ae8b732d 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-thumb.h,v 1.6 2009-06-27 12:51:10 c2woody Exp $ */ /* ARMv4 (little endian) backend by M-HT (thumb version) */ diff --git a/src/cpu/core_dynrec/risc_armv4le.h b/src/cpu/core_dynrec/risc_armv4le.h index e8cc2f27..8723852f 100644 --- a/src/cpu/core_dynrec/risc_armv4le.h +++ b/src/cpu/core_dynrec/risc_armv4le.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le.h,v 1.3 2009-05-27 09:15:41 qbix79 Exp $ */ /* ARMv4 (little endian) backend (switcher) by M-HT */ diff --git a/src/cpu/core_dynrec/risc_mipsel32.h b/src/cpu/core_dynrec/risc_mipsel32.h index cdc7541a..717e5ff8 100644 --- a/src/cpu/core_dynrec/risc_mipsel32.h +++ b/src/cpu/core_dynrec/risc_mipsel32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_mipsel32.h,v 1.6 2009-06-25 19:31:43 c2woody Exp $ */ /* MIPS32 (little endian) backend by crazyc */ diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index 43953826..c710bc6f 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_x64.h,v 1.13 2009-06-25 19:31:43 c2woody Exp $ */ // some configuring defines that specify the capabilities of this architecture diff --git a/src/cpu/core_dynrec/risc_x86.h b/src/cpu/core_dynrec/risc_x86.h index 4ebe906e..99063d2d 100644 --- a/src/cpu/core_dynrec/risc_x86.h +++ b/src/cpu/core_dynrec/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_x86.h,v 1.10 2009-06-25 19:31:43 c2woody Exp $ */ // some configuring defines that specify the capabilities of this architecture diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 4299dc7f..f70f8078 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/cpu/core_full/ea_lookup.h b/src/cpu/core_full/ea_lookup.h index cd8834e0..bf71b122 100644 --- a/src/cpu/core_full/ea_lookup.h +++ b/src/cpu/core_full/ea_lookup.h @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2011 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. + */ + { EAPoint seg_base; Bit16u off; diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index a5e7adeb..c644a1ab 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2011 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. + */ + switch (inst.code.load) { /* General loading */ case L_POPwRM: diff --git a/src/cpu/core_full/loadwrite.h b/src/cpu/core_full/loadwrite.h index aca53c49..22891515 100644 --- a/src/cpu/core_full/loadwrite.h +++ b/src/cpu/core_full/loadwrite.h @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2011 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. + */ + #define SaveIP() reg_eip=(Bit32u)(inst.cseip-SegBase(cs)); #define LoadIP() inst.cseip=SegBase(cs)+reg_eip; #define GetIP() (inst.cseip-SegBase(cs)) diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 6c1ebc4d..ea5f517d 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2011 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. + */ + /* Do the actual opcode */ switch (inst.code.op) { case t_ADDb: case t_ADDw: case t_ADDd: diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index a938a8fe..affeb6ea 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2011 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. + */ + /* Big ass opcode table normal,double, 66 normal, 66 double */ static OpCode OpCodeTable[1024]={ /* 0x00 - 0x07 */ diff --git a/src/cpu/core_full/save.h b/src/cpu/core_full/save.h index 4e10db12..142ec5c4 100644 --- a/src/cpu/core_full/save.h +++ b/src/cpu/core_full/save.h @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2011 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. + */ + /* Write the data from the opcode */ switch (inst.code.save) { /* Byte */ diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index 5da65b10..18a31517 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2011 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. + */ + { EAPoint si_base,di_base; Bitu si_index,di_index; diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 7a0c4dc2..6478a79c 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2011 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 { L_N=0, L_SKIP, diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 7f3b25b7..530e0c62 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/cpu/core_normal/helpers.h b/src/cpu/core_normal/helpers.h index f0fb75c2..20114949 100644 --- a/src/cpu/core_normal/helpers.h +++ b/src/cpu/core_normal/helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 1c191b51..84f1b741 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index b9adacc8..a40bc238 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index eed5bac8..832e8f48 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 1a6d164f..c732d1a6 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/cpu/core_normal/string.h b/src/cpu/core_normal/string.h index 6fdfc7bd..40ebce7d 100644 --- a/src/cpu/core_normal/string.h +++ b/src/cpu/core_normal/string.h @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2011 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 { R_OUTSB,R_OUTSW,R_OUTSD, R_INSB,R_INSW,R_INSD, diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index 9b230816..5752d2a2 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/cpu/core_normal/table_ea.h b/src/cpu/core_normal/table_ea.h index 08d46132..e6ac3f2d 100644 --- a/src/cpu/core_normal/table_ea.h +++ b/src/cpu/core_normal/table_ea.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/cpu/core_prefetch.cpp b/src/cpu/core_prefetch.cpp index d9ec489f..e378968a 100644 --- a/src/cpu/core_prefetch.cpp +++ b/src/cpu/core_prefetch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: core_prefetch.cpp,v 1.3 2009-06-26 16:43:30 c2woody Exp $ */ #include diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp index 2d026b94..e7512270 100644 --- a/src/cpu/core_simple.cpp +++ b/src/cpu/core_simple.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 29baa8b6..b81291eb 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.116 2009-03-16 18:10:08 c2woody Exp $ */ #include #include diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 2e9532f5..cd47f426 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index da82ec4a..620d1700 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index a2a031d7..49855f75 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/cpu/modrm.cpp b/src/cpu/modrm.cpp index bbac41e0..c5e4e923 100644 --- a/src/cpu/modrm.cpp +++ b/src/cpu/modrm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/cpu/modrm.h b/src/cpu/modrm.h index 60482bf9..1f4d6d58 100644 --- a/src/cpu/modrm.h +++ b/src/cpu/modrm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 3978083b..7707554d 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.cpp,v 1.36 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index d85cd832..a73d86c4 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.97 2009-04-11 19:49:52 c2woody Exp $ */ #include "dosbox.h" #if C_DEBUG diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 76e6dd2b..c2fa4576 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug_gui.cpp,v 1.38 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h index 1900e949..873cde2e 100644 --- a/src/debug/debug_inc.h +++ b/src/debug/debug_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 @@ -18,7 +18,6 @@ /* Local Debug Function */ -/* $Id: debug_inc.h,v 1.12 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include "mem.h" diff --git a/src/debug/debug_win32.cpp b/src/debug/debug_win32.cpp index 91147f67..9fd80ead 100644 --- a/src/debug/debug_win32.cpp +++ b/src/debug/debug_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/debug/disasm_tables.h b/src/debug/disasm_tables.h index 96531ef1..55a6bae9 100644 --- a/src/debug/disasm_tables.h +++ b/src/debug/disasm_tables.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 2a4b7118..0e7d38e7 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom.cpp,v 1.27 2009-04-26 18:24:36 qbix79 Exp $ */ // ****************************************************** // SDL CDROM diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index 6242bc42..7199f46d 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2002-2011 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 __CDROM_INTERFACE__ #define __CDROM_INTERFACE__ diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index 4c604544..5ae8daf8 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_aspi_win32.cpp,v 1.21 2009-05-27 09:15:41 qbix79 Exp $ */ #if defined (WIN32) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 12e601ee..76de61da 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.24 2009-03-19 20:45:42 c2woody Exp $ */ #include #include diff --git a/src/dos/cdrom_ioctl_linux.cpp b/src/dos/cdrom_ioctl_linux.cpp index 25f7c610..46122178 100644 --- a/src/dos/cdrom_ioctl_linux.cpp +++ b/src/dos/cdrom_ioctl_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/dos/cdrom_ioctl_os2.cpp b/src/dos/cdrom_ioctl_os2.cpp index ec1a7c8d..6c34b17c 100644 --- a/src/dos/cdrom_ioctl_os2.cpp +++ b/src/dos/cdrom_ioctl_os2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_ioctl_os2.cpp,v 1.4 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index c12f7526..41ff4f97 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_ioctl_win32.cpp,v 1.16 2009-01-07 22:39:18 c2woody Exp $ */ #if defined (WIN32) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index dfd267a4..39002035 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dev_con.h,v 1.35 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dos_inc.h" #include "../ints/int10.h" diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index f9230dfd..17503e2c 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.121 2009-10-28 21:45:12 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index e4dfa871..ba81f796 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.58 2009-07-09 20:06:57 c2woody Exp $ */ #include #include diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 4e9beb11..82ae0592 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_devices.cpp,v 1.22 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index ca9e5595..916a11ef 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.68 2009-10-04 14:28:07 c2woody Exp $ */ #include #include diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 4dceb094..0e627e91 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.113 2009-08-31 18:03:08 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index af2e6252..ac48457c 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_ioctl.cpp,v 1.35 2009-04-16 12:16:52 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 36bab926..33b7d10e 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_keyboard_layout.cpp,v 1.22 2009-09-06 19:25:33 c2woody Exp $ */ #include "dosbox.h" #include "bios.h" diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index e4c3627f..f1f7dcc7 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_memory.cpp,v 1.45 2009-07-15 17:05:07 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index 923e5dab..d658273d 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_misc.cpp,v 1.24 2009-09-25 20:51:21 qbix79 Exp $ */ #include "dosbox.h" #include "callback.h" diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 94239878..51946bce 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.59 2009-04-16 12:28:30 qbix79 Exp $ */ #include #include diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 4b5fa219..9bfeba00 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.94 2009-06-12 20:10:09 c2woody Exp $ */ #include "dosbox.h" #include diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 704daefc..b7efc8ba 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.32 2009-10-28 21:45:12 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 0cfb0781..f0769007 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_cache.cpp,v 1.59 2009-04-16 12:28:30 qbix79 Exp $ */ #include "drives.h" #include "dos_inc.h" diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 3fbe33b4..46e662be 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_fat.cpp,v 1.28 2009-06-19 18:28:10 c2woody Exp $ */ #include #include diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 52e19d5e..73bbad7e 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.27 2009-09-22 21:48:08 c2woody Exp $ */ #include #include diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index f07cb2c3..ba4daf91 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_local.cpp,v 1.82 2009-07-18 18:42:55 c2woody Exp $ */ #include #include diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index c5b502d6..2f55d69c 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.cpp,v 1.15 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" #include "dos_system.h" diff --git a/src/dos/drives.h b/src/dos/drives.h index 431f3f18..ca0f93a1 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.41 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 263ff338..34e848fd 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.150 2009-11-03 20:17:42 qbix79 Exp $ */ #include #include diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 48c5b964..f7ac61d6 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu.cpp,v 1.31 2009-09-16 18:01:53 qbix79 Exp $ */ #include "dosbox.h" #if C_FPU diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 06b97478..a5f7e3ac 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions.h,v 1.33 2009-05-27 09:15:41 qbix79 Exp $ */ static void FPU_FINIT(void) { diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index 16d96d66..7a7402ae 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: fpu_instructions_x86.h,v 1.7 2009-05-27 09:15:41 qbix79 Exp $ */ // #define WEAK_EXCEPTIONS diff --git a/src/gui/dosbox_logo.h b/src/gui/dosbox_logo.h index 4895d7d6..5d99a589 100644 --- a/src/gui/dosbox_logo.h +++ b/src/gui/dosbox_logo.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox_logo.h,v 1.5 2009-05-27 09:15:41 qbix79 Exp $ */ /* DOSBox icon designed by Ido Beeri */ diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 8bc75a57..252cc7d4 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 4c57ffab..6e11afab 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_alsa.h,v 1.20 2009-04-27 17:33:12 qbix79 Exp $ */ #define ALSA_PCM_OLD_HW_PARAMS_API #define ALSA_PCM_OLD_SW_PARAMS_API diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index 82f4c131..0ffc60f1 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_coreaudio.h,v 1.12 2009-10-18 18:06:28 qbix79 Exp $ */ #include #include diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index e1d8d97b..2571daef 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index a71904bd..0535bf10 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: midi_win32.h,v 1.16 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 1ba60975..2bb29cf0 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.60 2009-04-26 19:14:50 harekiet Exp $ */ #include #include diff --git a/src/gui/render_loops.h b/src/gui/render_loops.h index 4d742499..6a4e7b65 100644 --- a/src/gui/render_loops.h +++ b/src/gui/render_loops.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index ebcc0777..a2e4b02b 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index 9c0de279..5b1c4c46 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/gui/render_simple.h b/src/gui/render_simple.h index 23f40afa..063c2a74 100644 --- a/src/gui/render_simple.h +++ b/src/gui/render_simple.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render_simple.h,v 1.7 2009-05-27 09:15:41 qbix79 Exp $ */ #if defined (SCALERLINEAR) static void conc4d(SCALERNAME,SBPP,DBPP,L)(const void *s) { diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index 39ab2ef3..c659b2fc 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/gui/render_templates_hq.h b/src/gui/render_templates_hq.h index 3114dc7c..8153af29 100644 --- a/src/gui/render_templates_hq.h +++ b/src/gui/render_templates_hq.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/gui/render_templates_hq2x.h b/src/gui/render_templates_hq2x.h index 5e4072e8..94879cb2 100644 --- a/src/gui/render_templates_hq2x.h +++ b/src/gui/render_templates_hq2x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/gui/render_templates_hq3x.h b/src/gui/render_templates_hq3x.h index 13b68737..e8fa21d6 100644 --- a/src/gui/render_templates_hq3x.h +++ b/src/gui/render_templates_hq3x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/gui/render_templates_sai.h b/src/gui/render_templates_sai.h index 022d3b3c..78006ccf 100644 --- a/src/gui/render_templates_sai.h +++ b/src/gui/render_templates_sai.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index 6258118a..5e9910f6 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_gui.cpp,v 1.11 2009-02-25 19:58:11 c2woody Exp $ */ #if 0 #include "SDL.h" diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 9d83a770..7615b19a 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.60 2009-06-01 10:25:51 qbix79 Exp $ */ #include #include diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 33cd4c21..353b8247 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.154 2009-06-01 10:25:51 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -1737,7 +1736,7 @@ int main(int argc, char* argv[]) { #endif //defined(WIN32) && !(C_DEBUG) if (control->cmdline->FindExist("-version") || control->cmdline->FindExist("--version") ) { - printf("\nDOSBox version %s, copyright 2002-2010 DOSBox Team.\n\n",VERSION); + printf("\nDOSBox version %s, copyright 2002-2011 DOSBox Team.\n\n",VERSION); printf("DOSBox is written by the DOSBox Team (See AUTHORS file))\n"); printf("DOSBox comes with ABSOLUTELY NO WARRANTY. This is free software,\n"); printf("and you are welcome to redistribute it under certain conditions;\n"); @@ -1765,7 +1764,7 @@ int main(int argc, char* argv[]) { /* Display Welcometext in the console */ LOG_MSG("DOSBox version %s",VERSION); - LOG_MSG("Copyright 2002-2010 DOSBox Team, published under GNU GPL."); + LOG_MSG("Copyright 2002-2011 DOSBox Team, published under GNU GPL."); LOG_MSG("---"); /* Init SDL */ diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 7a0a5e61..dfa603d6 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: adlib.cpp,v 1.42 2009-11-03 20:17:42 qbix79 Exp $ */ #include #include diff --git a/src/hardware/adlib.h b/src/hardware/adlib.h index 5070d662..64bf2e90 100644 --- a/src/hardware/adlib.h +++ b/src/hardware/adlib.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: adlib.h,v 1.5 2009-04-28 21:45:43 c2woody Exp $ */ #ifndef DOSBOX_ADLIB_H #define DOSBOX_ADLIB_H diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index e6adad51..279e97e4 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cmos.cpp,v 1.29 2009-06-16 18:19:18 qbix79 Exp $ */ #include #include diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index 56153353..1723f310 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 @@ -32,7 +32,6 @@ //DUNNO Keyon in 4op, switch to 2op without keyoff. */ -/* $Id: dbopl.cpp,v 1.10 2009-06-10 19:54:51 harekiet Exp $ */ #include diff --git a/src/hardware/dbopl.h b/src/hardware/dbopl.h index c6334e06..624df438 100644 --- a/src/hardware/dbopl.h +++ b/src/hardware/dbopl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 867d32f9..52d7b8c6 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: disney.cpp,v 1.17 2009-05-14 17:04:37 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 9bc041e6..1346e73e 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dma.cpp,v 1.41 2009-07-24 09:56:14 c2woody Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index 84a2ee79..324e2bcc 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index aa230dc8..1ce1e3bd 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: gus.cpp,v 1.37 2009-09-03 16:03:01 c2woody Exp $ */ #include #include diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index e739bef8..ff7881ce 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: hardware.cpp,v 1.22 2009-04-26 18:24:36 qbix79 Exp $ */ #include #include diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index f6db8051..1f16a562 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: iohandler.cpp,v 1.30 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index 7b45c805..d598ce3a 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.cpp,v 1.17 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/ipxserver.cpp b/src/hardware/ipxserver.cpp index 937b4e32..ad77eed8 100644 --- a/src/hardware/ipxserver.cpp +++ b/src/hardware/ipxserver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipxserver.cpp,v 1.10 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index 6aff4c40..e45c222a 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: joystick.cpp,v 1.21 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 4d25a7bb..93bcda0c 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: keyboard.cpp,v 1.41 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" #include "keyboard.h" diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index ba76a8dc..3f56c6e5 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: memory.cpp,v 1.56 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 555205f2..64c18462 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.54 2009-09-05 11:10:04 qbix79 Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 333e1060..cb24d165 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.29 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/opl.cpp b/src/hardware/opl.cpp index 29cd204f..d046306a 100644 --- a/src/hardware/opl.cpp +++ b/src/hardware/opl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * OPL2/OPL3 emulation library * * This library is free software; you can redistribute it and/or diff --git a/src/hardware/opl.h b/src/hardware/opl.h index c7f38e01..8adcdb1a 100644 --- a/src/hardware/opl.h +++ b/src/hardware/opl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * OPL2/OPL3 emulation library * * This library is free software; you can redistribute it and/or diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 008523b4..3dd6be69 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /* $Id: pcspeaker.cpp,v 1.26 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 983d61f8..0b82a8e6 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: pic.cpp,v 1.44 2009-05-27 09:15:41 qbix79 Exp $ */ #include diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 82c31c65..382c3236 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sblaster.cpp,v 1.78 2009-10-25 16:22:22 c2woody Exp $ */ #include #include diff --git a/src/hardware/serialport/directserial.cpp b/src/hardware/serialport/directserial.cpp index 529c11b1..4504d583 100644 --- a/src/hardware/serialport/directserial.cpp +++ b/src/hardware/serialport/directserial.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial.cpp,v 1.2 2009-09-26 09:15:19 h-a-l-9000 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/directserial.h b/src/hardware/serialport/directserial.h index e7121e28..05370ea5 100644 --- a/src/hardware/serialport/directserial.h +++ b/src/hardware/serialport/directserial.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: directserial.h,v 1.2 2009-09-26 09:15:19 h-a-l-9000 Exp $ */ // include guard #ifndef DOSBOX_DIRECTSERIAL_WIN32_H diff --git a/src/hardware/serialport/libserial.cpp b/src/hardware/serialport/libserial.cpp index d8d6fa58..3f2d52f8 100644 --- a/src/hardware/serialport/libserial.cpp +++ b/src/hardware/serialport/libserial.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: libserial.cpp,v 1.4 2009-11-02 09:51:02 h-a-l-9000 Exp $ */ #include "libserial.h" diff --git a/src/hardware/serialport/libserial.h b/src/hardware/serialport/libserial.h index fad6d201..05a674a3 100644 --- a/src/hardware/serialport/libserial.h +++ b/src/hardware/serialport/libserial.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: libserial.h,v 1.2 2009-09-26 09:15:19 h-a-l-9000 Exp $ */ typedef struct _COMPORT *COMPORT; diff --git a/src/hardware/serialport/misc_util.cpp b/src/hardware/serialport/misc_util.cpp index 0243c35d..769da4d9 100644 --- a/src/hardware/serialport/misc_util.cpp +++ b/src/hardware/serialport/misc_util.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/hardware/serialport/misc_util.h b/src/hardware/serialport/misc_util.h index 83f3dfab..a7e805a4 100644 --- a/src/hardware/serialport/misc_util.h +++ b/src/hardware/serialport/misc_util.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: misc_util.h,v 1.5 2009-09-25 23:40:47 h-a-l-9000 Exp $ */ #ifndef SDLNETWRAPPER_H #define SDLNETWRAPPER_H diff --git a/src/hardware/serialport/nullmodem.cpp b/src/hardware/serialport/nullmodem.cpp index c2349249..b107ac9e 100644 --- a/src/hardware/serialport/nullmodem.cpp +++ b/src/hardware/serialport/nullmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: nullmodem.cpp,v 1.8 2009-09-25 23:40:47 h-a-l-9000 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/nullmodem.h b/src/hardware/serialport/nullmodem.h index 012ddaf4..a1f3f054 100644 --- a/src/hardware/serialport/nullmodem.h +++ b/src/hardware/serialport/nullmodem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: nullmodem.h,v 1.4 2009-09-25 23:40:47 h-a-l-9000 Exp $ */ // include guard #ifndef DOSBOX_NULLMODEM_WIN32_H diff --git a/src/hardware/serialport/serialdummy.cpp b/src/hardware/serialport/serialdummy.cpp index f4dd904c..eea35ca7 100644 --- a/src/hardware/serialport/serialdummy.cpp +++ b/src/hardware/serialport/serialdummy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialdummy.cpp,v 1.5 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/serialdummy.h b/src/hardware/serialport/serialdummy.h index 2da38afa..90a950ba 100644 --- a/src/hardware/serialport/serialdummy.h +++ b/src/hardware/serialport/serialdummy.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialdummy.h,v 1.5 2009-05-27 09:15:41 qbix79 Exp $ */ #ifndef INCLUDEGUARD_SERIALDUMMY_H #define INCLUDEGUARD_SERIALDUMMY_H diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index 1fd1f2d4..7694e1ac 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: serialport.cpp,v 1.14 2009-10-01 17:25:28 h-a-l-9000 Exp $ */ #include #include diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index 78029a91..ed9d7a1a 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.cpp,v 1.12 2009-10-04 20:57:40 h-a-l-9000 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index f884dde0..1ce9eff7 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: softmodem.h,v 1.12 2009-10-04 20:57:40 h-a-l-9000 Exp $ */ #ifndef DOSBOX_SERIALMODEM_H #define DOSBOX_SERIALMODEM_H diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 7ee942f9..05e16fc0 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 85f7998e..e6b4db76 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.49 2009-04-10 09:53:04 c2woody Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index c76763dd..da5960c3 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga.cpp,v 1.36 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" //#include "setup.h" diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index e8b89604..f23be28c 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_attr.cpp,v 1.31 2009-06-28 14:56:13 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 6868f634..9906c725 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_crtc.cpp,v 1.34 2009-03-18 18:08:16 c2woody Exp $ */ #include #include "dosbox.h" diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index c2179377..dbc04e10 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 713d5212..563bf180 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.112 2009-11-03 21:06:59 h-a-l-9000 Exp $ */ #include #include diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index a79e9c31..55c7cc15 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_gfx.cpp,v 1.19 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" #include "inout.h" diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 8a8b43f7..0c4428d6 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_memory.cpp,v 1.53 2009-07-04 21:23:35 qbix79 Exp $ */ #include #include diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 517166f7..45d8ea7b 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_misc.cpp,v 1.39 2009-01-25 12:00:49 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index c6cd613f..61f92be4 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_other.cpp,v 1.28 2009-07-11 10:25:24 c2woody Exp $ */ #include #include diff --git a/src/hardware/vga_paradise.cpp b/src/hardware/vga_paradise.cpp index f05c862d..3f6b294e 100644 --- a/src/hardware/vga_paradise.cpp +++ b/src/hardware/vga_paradise.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_paradise.cpp,v 1.4 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" #include "setup.h" diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index 3d428788..1de9599e 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_s3.cpp,v 1.18 2009-03-15 11:28:35 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index edd400a4..3c41bdde 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_seq.cpp,v 1.24 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" #include "inout.h" diff --git a/src/hardware/vga_tseng.cpp b/src/hardware/vga_tseng.cpp index 16735577..0983c233 100644 --- a/src/hardware/vga_tseng.cpp +++ b/src/hardware/vga_tseng.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_tseng.cpp,v 1.5 2009-05-27 09:15:41 qbix79 Exp $ */ #include "dosbox.h" diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index b7f927c8..a8bc4d37 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_xga.cpp,v 1.17 2009-05-27 09:15:41 qbix79 Exp $ */ #include #include "dosbox.h" diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index bf5eda52..57ddb836 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.78 2009-10-10 13:26:46 h-a-l-9000 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index baa8dcf2..53cc7d98 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.40 2009-08-23 17:24:54 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index f4e8fc20..7d91deda 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_keyboard.cpp,v 1.36 2009-06-11 16:05:17 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 68a908c2..ff429c95 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.65 2009-10-11 17:11:52 c2woody Exp $ */ #include #include diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index cc367ea3..32c5033a 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.cpp,v 1.56 2009-09-06 19:25:34 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/ints/int10.h b/src/ints/int10.h index 92ea79b8..41e43748 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10.h,v 1.42 2009-09-06 19:25:34 c2woody Exp $ */ #include "vga.h" diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 672c0bf9..cf1d7049 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.60 2009-10-15 20:36:56 c2woody Exp $ */ /* Character displaying moving functions */ diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 646894f5..7beda20d 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_memory.cpp,v 1.30 2009-09-06 19:25:34 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index b9867d57..9522a6a4 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_misc.cpp,v 1.21 2009-05-27 09:15:42 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index fe649fb5..738b88ce 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_modes.cpp,v 1.91 2009-10-19 16:00:22 h-a-l-9000 Exp $ */ #include diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 4a672c09..87596902 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 0adc4dab..8f759e64 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_put_pixel.cpp,v 1.23 2009-05-27 09:15:42 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index e90c641d..baeb0c42 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.40 2009-07-31 15:36:01 c2woody Exp $ */ #include #include diff --git a/src/ints/int10_video_state.cpp b/src/ints/int10_video_state.cpp index 59bfc615..c33e8220 100644 --- a/src/ints/int10_video_state.cpp +++ b/src/ints/int10_video_state.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_video_state.cpp,v 1.3 2009-05-27 09:15:42 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/ints/int10_vptable.cpp b/src/ints/int10_vptable.cpp index 4e507bee..7d79fbdc 100644 --- a/src/ints/int10_vptable.cpp +++ b/src/ints/int10_vptable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vptable.cpp,v 1.6 2009-08-01 13:39:48 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index e0aa8b66..18a62d43 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mouse.cpp,v 1.80 2009-06-16 19:00:26 qbix79 Exp $ */ #include #include diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index a4349e7e..10b53fc7 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.55 2009-05-27 09:15:42 qbix79 Exp $ */ #include #include diff --git a/src/ints/xms.h b/src/ints/xms.h index d96d49c9..75891dc8 100644 --- a/src/ints/xms.h +++ b/src/ints/xms.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/libs/gui_tk/gui_tk.cpp b/src/libs/gui_tk/gui_tk.cpp index 03b64a9c..8d80cd1e 100644 --- a/src/libs/gui_tk/gui_tk.cpp +++ b/src/libs/gui_tk/gui_tk.cpp @@ -20,7 +20,6 @@ /* TODO: - make menu a bufferedwindow with shadow */ -/* $Id: gui_tk.cpp,v 1.5 2009-02-01 16:06:26 qbix79 Exp $ */ /** \file * \brief Implementation file for gui_tk. diff --git a/src/libs/gui_tk/gui_tk.h b/src/libs/gui_tk/gui_tk.h index ebc90c53..19e5212d 100644 --- a/src/libs/gui_tk/gui_tk.h +++ b/src/libs/gui_tk/gui_tk.h @@ -102,7 +102,6 @@ * along with this program. If not, see */ -/* $Id: gui_tk.h,v 1.6 2009-05-17 15:28:05 c2woody Exp $ */ #ifndef GUI__TOOLKIT_H #define GUI__TOOLKIT_H diff --git a/src/libs/zmbv/drvproc.cpp b/src/libs/zmbv/drvproc.cpp index 3f5bc957..736d7d70 100644 --- a/src/libs/zmbv/drvproc.cpp +++ b/src/libs/zmbv/drvproc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/libs/zmbv/zmbv.cpp b/src/libs/zmbv/zmbv.cpp index d45e56a6..f52176f2 100644 --- a/src/libs/zmbv/zmbv.cpp +++ b/src/libs/zmbv/zmbv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/libs/zmbv/zmbv.h b/src/libs/zmbv/zmbv.h index cc744784..f16d5eda 100644 --- a/src/libs/zmbv/zmbv.h +++ b/src/libs/zmbv/zmbv.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/libs/zmbv/zmbv_vfw.cpp b/src/libs/zmbv/zmbv_vfw.cpp index 5fd6351a..b1d77475 100644 --- a/src/libs/zmbv/zmbv_vfw.cpp +++ b/src/libs/zmbv/zmbv_vfw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 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 diff --git a/src/misc/cross.cpp b/src/misc/cross.cpp index 4d56293a..95245b9b 100644 --- a/src/misc/cross.cpp +++ b/src/misc/cross.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cross.cpp,v 1.7 2009-05-26 17:43:39 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index d6d7c6f9..a1dc1814 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: messages.cpp,v 1.23 2009-06-17 08:52:35 qbix79 Exp $ */ #include #include diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index cdc9bed5..3b1cd147 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: programs.cpp,v 1.37 2009-05-27 09:15:42 qbix79 Exp $ */ #include #include diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index f62034f0..655182a3 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.56 2009-05-27 09:15:42 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 19d037cb..cfcb64f6 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: support.cpp,v 1.37 2009-05-27 09:15:42 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 8ca34996..93aabeda 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.100 2009-07-08 20:05:41 c2woody Exp $ */ #include #include diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index b259651e..1c86ecc5 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_batch.cpp,v 1.36 2009-07-03 19:36:56 qbix79 Exp $ */ #include #include diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index f4bce54a..e34513d4 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.93 2009-09-21 21:04:25 h-a-l-9000 Exp $ */ #include "dosbox.h" #include "shell.h" diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 221ddc4c..509435f9 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2011 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.54 2009-05-27 09:15:42 qbix79 Exp $ */ #include #include From 0ae27e9b4a2cde3f01f630396756b685f421da56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 26 Apr 2011 15:00:36 +0000 Subject: [PATCH 3611/4131] year/info update for some other files as well Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3701 --- INSTALL | 6 +++--- scripts/dosbox-installer.nsi | 2 +- src/dos/scsidefs.h | 5 ----- src/gui/sdl_gui.cpp | 2 +- src/libs/zmbv/zmbv_vfw.rc | 16 ++++++++-------- src/winres.rc | 4 ++-- 6 files changed, 15 insertions(+), 20 deletions(-) diff --git a/INSTALL b/INSTALL index cc48f8e2..f067f4b6 100644 --- a/INSTALL +++ b/INSTALL @@ -43,11 +43,11 @@ ALSA_Headers 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 developer sources (SVN) under a unix system, you'll also need automake (>=1.6), autoconf(>=2.50). Should be available at http://www.gnu.org 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 developer sources run ./autogen.sh first before doing the following. 1. ./configure 2. make @@ -101,4 +101,4 @@ src/ints/bios_keyboard.cpp and go to line 30 and read there how to fix it. Build instructions for VC++6 Don't use VC++ 6: it creates faulty code in core_normal.cpp -Later Visual Studio versions work fine (vs2003/.net, vs2005, vs2008) +Later Visual Studio versions work fine (vs2003/.net up to vs2010) diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index 31aee2bf..470c6783 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -2,7 +2,7 @@ !define VER_MINOR 74 !define APP_NAME "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer" !define COMP_NAME "DOSBox Team" -!define COPYRIGHT "Copyright © 2002-2010 DOSBox Team" +!define COPYRIGHT "Copyright © 2002-2011 DOSBox Team" !define DESCRIPTION "DOSBox Installer" VIProductVersion "${VER_MAYOR}.${VER_MINOR}.0.0" diff --git a/src/dos/scsidefs.h b/src/dos/scsidefs.h index 85ff62a6..a8b996a4 100644 --- a/src/dos/scsidefs.h +++ b/src/dos/scsidefs.h @@ -1,12 +1,7 @@ /* Got it from Bochs */ -///////////////////////////////////////////////////////////////////////// -// $Id: scsidefs.h,v 1.3 2005-07-21 12:49:52 qbix79 Exp $ -///////////////////////////////////////////////////////////////////////// -// // // iodev/scsidefs.h -// $Id: scsidefs.h,v 1.3 2005-07-21 12:49:52 qbix79 Exp $ // // This file was copied from ... ? // diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index 5e9910f6..807d908a 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -569,7 +569,7 @@ public: Section_prop *section = static_cast(sec); new SectionEditor(getScreen(), 50, 30, section); } else if (arg == "About") { - new GUI::MessageBox(getScreen(), 200, 150, 280, "About DOSBox", "\nDOSBox 0.72\nAn emulator for old DOS Games\n\nCopyright 2002-2009\nThe DOSBox Team"); + new GUI::MessageBox(getScreen(), 200, 150, 280, "About DOSBox", "\nDOSBox 0.74\nAn emulator for old DOS Games\n\nCopyright 2002-2011\nThe DOSBox Team"); } else if (arg == "Introduction") { new GUI::MessageBox(getScreen(), 20, 50, 600, "Introduction", MSG_Get("PROGRAM_INTRO")); } else if (arg == "Getting Started") { diff --git a/src/libs/zmbv/zmbv_vfw.rc b/src/libs/zmbv/zmbv_vfw.rc index 41d82294..87fbe8a5 100644 --- a/src/libs/zmbv/zmbv_vfw.rc +++ b/src/libs/zmbv/zmbv_vfw.rc @@ -27,18 +27,18 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // TEXTINCLUDE // -1 TEXTINCLUDE +1 TEXTINCLUDE BEGIN "resource.h\0" END -2 TEXTINCLUDE +2 TEXTINCLUDE BEGIN "#include ""winres.h""\r\n" "\0" END -3 TEXTINCLUDE +3 TEXTINCLUDE BEGIN "\r\n" "\0" @@ -53,20 +53,20 @@ END // IDD_ABOUT DIALOGEX 0, 0, 167, 55 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "DOSBox Video Codec v0.1" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN DEFPUSHBUTTON "OK",IDOK,131,34,29,14 - CTEXT "Zipped Motion Block Video v 0.1\nCopyright 2009, DOSBox Team", + CTEXT "Zipped Motion Block Video v 0.1\nCopyright 2009-2011 DOSBox Team", IDC_STATIC,7,7,153,25,SS_NOPREFIX PUSHBUTTON "Email author",IDC_EMAIL,7,34,50,14 PUSHBUTTON "Visit home page",IDC_HOMEPAGE,59,34,58,14 END IDD_CONFIGURE DIALOGEX 0, 0, 213, 146 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "ZMBV configuration dialog" FONT 8, "MS Sans Serif", 0, 0, 0x0 @@ -75,7 +75,7 @@ BEGIN PUSHBUTTON "Visit home page",IDC_HOMEPAGE,109,87,58,14 DEFPUSHBUTTON "OK",IDOK,44,125,50,14 PUSHBUTTON "Cancel",IDCANCEL,117,125,50,14 - CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH | + CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,57,30,92,18 END @@ -86,7 +86,7 @@ END // #ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO +GUIDELINES DESIGNINFO BEGIN IDD_ABOUT, DIALOG BEGIN diff --git a/src/winres.rc b/src/winres.rc index f7e63b4c..cfcc7015 100644 --- a/src/winres.rc +++ b/src/winres.rc @@ -19,12 +19,12 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "Comments", "© 2002-2010 DOSBox Team, published under GNU GPL" + VALUE "Comments", "© 2002-2011 DOSBox Team, published under GNU GPL" VALUE "CompanyName", "DOSBox Team" VALUE "FileDescription", "DOSBox DOS Emulator" VALUE "FileVersion", "0, 74, 0, 0" VALUE "InternalName", "DOSBox" - VALUE "LegalCopyright", "Copyright © 2002-2010 DOSBox Team" + VALUE "LegalCopyright", "Copyright © 2002-2011 DOSBox Team" VALUE "OriginalFilename", "dosbox.exe" VALUE "ProductName", "DOSBox DOS Emulator" VALUE "ProductVersion", "0, 74, 0, 0" From b080470bcac7bfb652f90060b624495e0348a947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 27 Apr 2011 17:09:22 +0000 Subject: [PATCH 3612/4131] update audio-cd playing status before deciding to pause/resume on mscdex stop request (ripsaw; fixes Shadowcaster playback) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3702 --- src/dos/cdrom_image.cpp | 1 - src/dos/cdrom_ioctl_win32.cpp | 1 - src/dos/dos_mscdex.cpp | 48 +++++++++++++++++++---------------- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 76de61da..b96546d0 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -246,7 +246,6 @@ bool CDROM_Interface_Image::PlayAudioSector(unsigned long start,unsigned long le bool CDROM_Interface_Image::PauseAudio(bool resume) { - if (!player.isPlaying) return false; player.isPaused = !resume; return true; } diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index 41ff4f97..994c5829 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -429,7 +429,6 @@ bool CDROM_Interface_Ioctl::PauseAudio(bool resume) { return false; } if (use_dxplay) { - if (!player.isPlaying) return false; player.isPaused = !resume; return true; } diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 51946bce..5901bb0c 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -438,8 +438,7 @@ void CMscdex::GetDriverInfo (PhysPt data) { }; } -bool CMscdex::GetCDInfo(Bit8u subUnit, Bit8u& tr1, Bit8u& tr2, TMSF& leadOut) -{ +bool CMscdex::GetCDInfo(Bit8u subUnit, Bit8u& tr1, Bit8u& tr2, TMSF& leadOut) { if (subUnit>=numDrives) return false; int tr1i,tr2i; // Assume Media change @@ -455,19 +454,17 @@ bool CMscdex::GetCDInfo(Bit8u subUnit, Bit8u& tr1, Bit8u& tr2, TMSF& leadOut) return dinfo[subUnit].lastResult; } -bool CMscdex::GetTrackInfo(Bit8u subUnit, Bit8u track, Bit8u& attr, TMSF& start) -{ +bool CMscdex::GetTrackInfo(Bit8u subUnit, Bit8u track, Bit8u& attr, TMSF& start) { if (subUnit>=numDrives) return false; dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioTrackInfo(track,start,attr); if (!dinfo[subUnit].lastResult) { attr = 0; memset(&start,0,sizeof(start)); - }; + } return dinfo[subUnit].lastResult; } -bool CMscdex::PlayAudioSector(Bit8u subUnit, Bit32u sector, Bit32u length) -{ +bool CMscdex::PlayAudioSector(Bit8u subUnit, Bit32u sector, Bit32u length) { if (subUnit>=numDrives) return false; // If value from last stop is used, this is meant as a resume // better start using resume command @@ -481,12 +478,11 @@ bool CMscdex::PlayAudioSector(Bit8u subUnit, Bit32u sector, Bit32u length) dinfo[subUnit].audioPaused = false; dinfo[subUnit].audioStart = sector; dinfo[subUnit].audioEnd = length; - }; + } return dinfo[subUnit].lastResult; } -bool CMscdex::PlayAudioMSF(Bit8u subUnit, Bit32u start, Bit32u length) -{ +bool CMscdex::PlayAudioMSF(Bit8u subUnit, Bit32u start, Bit32u length) { if (subUnit>=numDrives) return false; Bit8u min = (Bit8u)(start>>16) & 0xFF; Bit8u sec = (Bit8u)(start>> 8) & 0xFF; @@ -495,20 +491,18 @@ bool CMscdex::PlayAudioMSF(Bit8u subUnit, Bit32u start, Bit32u length) return dinfo[subUnit].lastResult = PlayAudioSector(subUnit,sector,length); } -bool CMscdex::GetSubChannelData(Bit8u subUnit, Bit8u& attr, Bit8u& track, Bit8u &index, TMSF& rel, TMSF& abs) -{ +bool CMscdex::GetSubChannelData(Bit8u subUnit, Bit8u& attr, Bit8u& track, Bit8u &index, TMSF& rel, TMSF& abs) { if (subUnit>=numDrives) return false; dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioSub(attr,track,index,rel,abs); if (!dinfo[subUnit].lastResult) { attr = track = index = 0; memset(&rel,0,sizeof(rel)); memset(&abs,0,sizeof(abs)); - }; + } return dinfo[subUnit].lastResult; } -bool CMscdex::GetAudioStatus(Bit8u subUnit, bool& playing, bool& pause, TMSF& start, TMSF& end) -{ +bool CMscdex::GetAudioStatus(Bit8u subUnit, bool& playing, bool& pause, TMSF& start, TMSF& end) { if (subUnit>=numDrives) return false; dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioStatus(playing,pause); if (dinfo[subUnit].lastResult) { @@ -527,16 +521,26 @@ bool CMscdex::GetAudioStatus(Bit8u subUnit, bool& playing, bool& pause, TMSF& st pause = false; memset(&start,0,sizeof(start)); memset(&end,0,sizeof(end)); - }; + } return dinfo[subUnit].lastResult; } -bool CMscdex::StopAudio(Bit8u subUnit) -{ +bool CMscdex::StopAudio(Bit8u subUnit) { if (subUnit>=numDrives) return false; - if (dinfo[subUnit].audioPlay) dinfo[subUnit].lastResult = cdrom[subUnit]->PauseAudio(false); - else dinfo[subUnit].lastResult = cdrom[subUnit]->StopAudio(); + if (dinfo[subUnit].audioPlay) { + // Check if audio is still playing.... + TMSF start,end; + bool playing,pause; + if (GetAudioStatus(subUnit,playing,pause,start,end)) + dinfo[subUnit].audioPlay = playing; + else + dinfo[subUnit].audioPlay = false; + } + if (dinfo[subUnit].audioPlay) + dinfo[subUnit].lastResult = cdrom[subUnit]->PauseAudio(false); + else + dinfo[subUnit].lastResult = cdrom[subUnit]->StopAudio(); if (dinfo[subUnit].lastResult) { if (dinfo[subUnit].audioPlay) { @@ -548,9 +552,9 @@ bool CMscdex::StopAudio(Bit8u subUnit) dinfo[subUnit].audioPaused = false; dinfo[subUnit].audioStart = 0; dinfo[subUnit].audioEnd = 0; - }; + } dinfo[subUnit].audioPlay = false; - }; + } return dinfo[subUnit].lastResult; } From 0f5b19ac6d75ee2ffb554c616cd8e41f617132a8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 28 Apr 2011 14:07:17 +0000 Subject: [PATCH 3613/4131] Improve wildcard handling with directories in copy for FA CD installer (ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3703 --- src/shell/shell_cmds.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index e34513d4..f6c56246 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -603,7 +603,7 @@ void DOS_Shell::CMD_COPY(char * args) { if (!has_drive_spec) { if (DOS_FindFirst(source_p,0xffff & ~DOS_ATTR_VOLUME)) { dta.GetResult(name,size,date,time,attr); - if (attr & DOS_ATTR_DIRECTORY && !strstr(source_p,"*.*")) + if (attr & DOS_ATTR_DIRECTORY && !strpbrk(source_p,"*?") ) strcat(source_x,"\\*.*"); } } From 545ae4eb8df5f4685f43dd9609e724a895cb6a85 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 28 Apr 2011 20:06:56 +0000 Subject: [PATCH 3614/4131] Tiny speed up Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3704 --- src/shell/shell_cmds.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index f6c56246..19791879 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -600,10 +600,10 @@ void DOS_Shell::CMD_COPY(char * args) { if (source_x_len>0) { if (source_x[source_x_len-1]==':') has_drive_spec = true; } - if (!has_drive_spec) { + if (!has_drive_spec && !strpbrk(source_p,"*?") ) { //doubt that fu*\*.* is valid if (DOS_FindFirst(source_p,0xffff & ~DOS_ATTR_VOLUME)) { dta.GetResult(name,size,date,time,attr); - if (attr & DOS_ATTR_DIRECTORY && !strpbrk(source_p,"*?") ) + if (attr & DOS_ATTR_DIRECTORY) strcat(source_x,"\\*.*"); } } From 9f4a040fd56cbe228c14f7229bdfdf3da03c075b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 2 May 2011 17:15:43 +0000 Subject: [PATCH 3615/4131] fix unintended fall-through for mscdex load medium command (ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3705 --- src/dos/dos_mscdex.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 5901bb0c..ac49a1ae 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -1041,6 +1041,7 @@ static Bit16u MSCDEX_IOCTL_Optput(PhysPt buffer,Bit8u drive_unit) { break; case 0x05 : // load media if (!mscdex->LoadUnloadMedia(drive_unit,false)) return 0x02; + break; default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unsupported IOCTL OUTPUT Subfunction %02X",ioctl_fct); return 0x03; // invalid function } From a0dfb19255237854aed08279d0c80c05dc40f1ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 2 May 2011 18:37:35 +0000 Subject: [PATCH 3616/4131] mscdex device status returns audio-is-playing flag as well (ripsaw; fixes Blood CDDA track looping) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3706 --- src/dos/dos_mscdex.cpp | 51 ++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index ac49a1ae..835bcfc7 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -674,8 +674,7 @@ bool CMscdex::ReadSectors(Bit16u drive, Bit32u sector, Bit16u num, PhysPt data) return ReadSectors(GetSubUnit(drive),false,sector,num,data); } -bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, PhysPt buffer, Bit16u& error) -{ +bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, PhysPt buffer, Bit16u& error) { char volumeID[6] = {0}; char searchName[256]; char entryName[256]; @@ -784,13 +783,12 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph dirEntrySector++; nextPart = false; } - }; + } error = 2; // file not found return false; // not found } -bool CMscdex::GetCurrentPos(Bit8u subUnit, TMSF& pos) -{ +bool CMscdex::GetCurrentPos(Bit8u subUnit, TMSF& pos) { if (subUnit>=numDrives) return false; TMSF rel; Bit8u attr,track,index; @@ -799,31 +797,39 @@ bool CMscdex::GetCurrentPos(Bit8u subUnit, TMSF& pos) return dinfo[subUnit].lastResult; } -bool CMscdex::GetMediaStatus(Bit8u subUnit, bool& media, bool& changed, bool& trayOpen) -{ +bool CMscdex::GetMediaStatus(Bit8u subUnit, bool& media, bool& changed, bool& trayOpen) { if (subUnit>=numDrives) return false; dinfo[subUnit].lastResult = cdrom[subUnit]->GetMediaTrayStatus(media,changed,trayOpen); return dinfo[subUnit].lastResult; } -Bit32u CMscdex::GetDeviceStatus(Bit8u subUnit) -{ +Bit32u CMscdex::GetDeviceStatus(Bit8u subUnit) { if (subUnit>=numDrives) return false; bool media,changed,trayOpen; dinfo[subUnit].lastResult = GetMediaStatus(subUnit,media,changed,trayOpen); - Bit32u status = (trayOpen << 0) | // Drive is open ? - (dinfo[subUnit].locked << 1) | // Drive is locked ? - (1<<2) | // raw + cooked sectors - (1<<4) | // Can read sudio - (1<<8) | // Can control audio - (1<<9) | // Red book & HSG - ((!media) << 11); // Drive is empty ? + if (dinfo[subUnit].audioPlay) { + // Check if audio is still playing.... + TMSF start,end; + bool playing,pause; + if (GetAudioStatus(subUnit,playing,pause,start,end)) + dinfo[subUnit].audioPlay = playing; + else + dinfo[subUnit].audioPlay = false; + } + + Bit32u status = ((trayOpen?1:0) << 0) | // Drive is open ? + ((dinfo[subUnit].locked?1:0) << 1) | // Drive is locked ? + (1<<2) | // raw + cooked sectors + (1<<4) | // Can read sudio + (1<<8) | // Can control audio + (1<<9) | // Red book & HSG + ((dinfo[subUnit].audioPlay?1:0) << 10) | // Audio is playing ? + ((media?0:1) << 11); // Drive is empty ? return status; } -bool CMscdex::GetMediaStatus(Bit8u subUnit, Bit8u& status) -{ +bool CMscdex::GetMediaStatus(Bit8u subUnit, Bit8u& status) { if (subUnit>=numDrives) return false; /* bool media,changed,open,result; result = GetMediaStatus(subUnit,media,changed,open); @@ -833,15 +839,13 @@ bool CMscdex::GetMediaStatus(Bit8u subUnit, Bit8u& status) return true; } -bool CMscdex::LoadUnloadMedia(Bit8u subUnit, bool unload) -{ +bool CMscdex::LoadUnloadMedia(Bit8u subUnit, bool unload) { if (subUnit>=numDrives) return false; dinfo[subUnit].lastResult = cdrom[subUnit]->LoadUnloadMedia(unload); return dinfo[subUnit].lastResult; } -bool CMscdex::SendDriverRequest(Bit16u drive, PhysPt data) -{ +bool CMscdex::SendDriverRequest(Bit16u drive, PhysPt data) { Bit8u subUnit = GetSubUnit(drive); if (subUnit>=numDrives) return false; // Get SubUnit @@ -852,8 +856,7 @@ bool CMscdex::SendDriverRequest(Bit16u drive, PhysPt data) return true; } -Bit16u CMscdex::GetStatusWord(Bit8u subUnit,Bit16u status) -{ +Bit16u CMscdex::GetStatusWord(Bit8u subUnit,Bit16u status) { if (subUnit>=numDrives) return REQUEST_STATUS_ERROR | 0x02; // error : Drive not ready if (dinfo[subUnit].lastResult) status |= REQUEST_STATUS_DONE; // ok From 87cff4ee8678ee09981660da6eb79c4121bb17f2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 5 May 2011 09:30:33 +0000 Subject: [PATCH 3617/4131] less is more Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3707 --- src/shell/shell.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 93aabeda..77a40021 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -493,7 +493,7 @@ void SHELL_Init() { "\033[44;1m\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n" - "\xBA \033[32mWelcome to DOSBox v%-8s\033[37m \xBA\n" + "\xBA \033[32mWelcome to DOSBox %-8s\033[37m \xBA\n" "\xBA \xBA\n" // "\xBA DOSBox runs real and protected mode games. \xBA\n" "\xBA For a short introduction for new users type: \033[33mINTRO\033[37m \xBA\n" From c2ba5b3639d141f963c88efec54ebac06e7aa292 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 5 May 2011 15:40:53 +0000 Subject: [PATCH 3618/4131] Typo. (debian package) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3708 --- docs/dosbox.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dosbox.1 b/docs/dosbox.1 index cf96475f..729ff4b9 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -218,7 +218,7 @@ The configuration file controls various settings of 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 language file controls all visible output of the internal commands and the internal dos. .RB "See the section " FILES " for more information." .TP From 1bf90c16c2aec63f0abc00477ebb2447191d55c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 9 May 2011 16:19:24 +0000 Subject: [PATCH 3619/4131] add rdtsc instruction to full core as well for consistency Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3709 --- src/cpu/core_full/load.h | 7 +++++++ src/cpu/core_full/optable.h | 4 ++-- src/cpu/core_full/support.h | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index c644a1ab..cd620add 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -500,6 +500,13 @@ l_M_Ed: case D_ICEBP: CPU_SW_Interrupt_NoIOPLCheck(1,GetIP()); continue; + case D_RDTSC: { + if (CPU_ArchitectureType>32); + reg_eax=(Bit32u)(tsc&0xffffffff); + break; + } default: LOG(LOG_CPU,LOG_ERROR)("LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry); goto illegalopcode; diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index affeb6ea..81eb94ae 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -234,7 +234,7 @@ static OpCode OpCodeTable[1024]={ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x130 - 0x137 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{D_RDTSC ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, @@ -590,7 +590,7 @@ static OpCode OpCodeTable[1024]={ {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x330 - 0x337 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, +{0 ,0 ,0 ,0 },{D_RDTSC ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 6478a79c..a6b12079 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -64,6 +64,7 @@ enum { D_CPUID, D_HLT,D_CLTS, D_LOCK,D_ICEBP, + D_RDTSC, L_ERROR }; From bf8496c0922d91391fc0856a79e922d438e2d963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 10 May 2011 18:00:03 +0000 Subject: [PATCH 3620/4131] cr0 always signals 386-type FPU present for 486+ target architectures (fixes Biing cdrom version) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3710 --- src/cpu/cpu.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index b81291eb..da74e8ec 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1546,6 +1546,7 @@ void CPU_SET_CRX(Bitu cr,Bitu value) { switch (cr) { case 0: { + value|=CR0_FPUPRESENT; Bitu changed=cpu.cr0 ^ value; if (!changed) return; cpu.cr0=value; From 7f277145579f2b961a3d43af18a35695f9837cee Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 11 May 2011 11:06:36 +0000 Subject: [PATCH 3621/4131] Correct Get Extended Shift States; Int 16 call 12 (thanks ripsaw). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3711 --- src/ints/bios_keyboard.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 7d91deda..cc2dc5fe 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -565,8 +565,10 @@ static Bitu INT16_Handler(void) { else reg_al=1; break; case 0x12: /* GET EXTENDED SHIFT STATES */ - reg_al=mem_readb(BIOS_KEYBOARD_FLAGS1); - reg_ah=mem_readb(BIOS_KEYBOARD_FLAGS2); + reg_al = mem_readb(BIOS_KEYBOARD_FLAGS1); + reg_ah = (mem_readb(BIOS_KEYBOARD_FLAGS2)&0x73) | + ((mem_readb(BIOS_KEYBOARD_FLAGS2)&4)<<5) | // SysReq pressed, bit 7 + (mem_readb(BIOS_KEYBOARD_FLAGS3)&0x0c); // Right Ctrl/Alt pressed, bits 2,3 break; case 0x55: /* Weird call used by some dos apps */ From 8e7cbdda70d771f5a918fcd841019000bcd285e1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 15 May 2011 20:25:28 +0000 Subject: [PATCH 3622/4131] Stay within array limits Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3712 --- src/debug/debug.cpp | 5 ++++- src/dosbox.cpp | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index a73d86c4..992ed4a4 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1725,7 +1725,10 @@ Bit32u DEBUG_CheckKeys(void) { } if (ret<0) return ret; if (ret>0) { - ret=(*CallBack_Handlers[ret])(); + if (GCC_UNLIKELY(ret >= CB_MAX)) + ret = 0; + else + ret = (*CallBack_Handlers[ret])(); if (ret) { exitLoop=true; CPU_Cycles=CPU_CycleLeft=0; diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 34e848fd..d95de3f8 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -128,10 +128,11 @@ static Bitu Normal_Loop(void) { Bits ret; while (1) { if (PIC_RunQueue()) { - ret=(*cpudecoder)(); + ret = (*cpudecoder)(); if (GCC_UNLIKELY(ret<0)) return 1; if (ret>0) { - Bitu blah=(*CallBack_Handlers[ret])(); + if (GCC_UNLIKELY(ret >= CB_MAX)) return 0; + Bitu blah = (*CallBack_Handlers[ret])(); if (GCC_UNLIKELY(blah)) return blah; } #if C_DEBUG From 379727f63d4ad61ac9720f491c399a09b0d89d9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 18 May 2011 21:02:10 +0000 Subject: [PATCH 3623/4131] reduce reported total drive size to avoid certain installer bugs/misbehaviour (ripsaw; fixes Front Page Sports Baseball installer regression) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3713 --- src/dos/dos_programs.cpp | 14 +++++++++----- src/dos/drive_virtual.cpp | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 9bfeba00..902ac3d6 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -125,12 +125,12 @@ public: str_size="512,1,2880,2880";/* All space free */ mediaid=0xF0; /* Floppy 1.44 media */ } else if (type=="dir") { - // 512*32*65535==~1GB total size + // 512*32*32765==~500MB total size // 512*32*16000==~250MB total free size - str_size="512,32,65535,16000"; + str_size="512,32,32765,16000"; mediaid=0xF8; /* Hard Disk */ } else if (type=="cdrom") { - str_size="2048,1,65535,0"; + str_size="2048,1,32765,0"; mediaid=0xF8; /* Hard Disk */ } else { WriteOut(MSG_Get("PROGAM_MOUNT_ILL_TYPE"),type.c_str()); @@ -145,8 +145,12 @@ public: // freesize in kb sprintf(teststr,"512,1,2880,%d",freesize*1024/(512*1)); } else { - // freesize in mb - sprintf(teststr,"512,32,65535,%d",freesize*1024*1024/(512*32)); + Bit32u total_size_cyl=32765; + Bit32u free_size_cyl=(Bit32u)freesize*1024*1024/(512*32); + if (free_size_cyl>65534) free_size_cyl=65534; + if (total_size_cyl65534) total_size_cyl=65534; + sprintf(teststr,"512,32,%d,%d",total_size_cyl,free_size_cyl); } str_size=teststr; } diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 43619616..c119d873 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -250,7 +250,7 @@ bool Virtual_Drive::Rename(char * oldname,char * newname) { bool Virtual_Drive::AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters) { *_bytes_sector=512; *_sectors_cluster=32; - *_total_clusters=65535; // total size is always 1 gb + *_total_clusters=32765; // total size is always 500 mb *_free_clusters=0; // nothing free here return true; } From 1887b2590be20d9410906559c419647d1f778cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 28 May 2011 20:26:12 +0000 Subject: [PATCH 3624/4131] speed up fat drive access Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3714 --- include/bios_disk.h | 1 + src/dos/drive_fat.cpp | 11 ++++++++--- src/dos/drives.h | 2 +- src/ints/bios_disk.cpp | 11 +++++++---- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/include/bios_disk.h b/include/bios_disk.h index ca136735..95c3d345 100644 --- a/include/bios_disk.h +++ b/include/bios_disk.h @@ -65,6 +65,7 @@ public: Bit32u sector_size; Bit32u heads,cylinders,sectors; + Bit32u current_fpos; }; void updateDPT(void); diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 46e662be..052d9769 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -982,11 +982,13 @@ bool fatDrive::GetFileAttr(char *name, Bit16u *attr) { /* Find directory entry in parent directory */ Bit32s fileidx = 2; if (dirClust==0) fileidx = 0; // root directory - while(directoryBrowse(dirClust, &fileEntry, fileidx)) { + Bit32s last_idx=0; + while(directoryBrowse(dirClust, &fileEntry, fileidx, last_idx)) { if(memcmp(&fileEntry.entryname, &pathName[0], 11) == 0) { *attr=fileEntry.attrib; return true; } + last_idx=fileidx; fileidx++; } return false; @@ -994,12 +996,15 @@ bool fatDrive::GetFileAttr(char *name, Bit16u *attr) { return true; } -bool fatDrive::directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum) { +bool fatDrive::directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum, Bit32s start/*=0*/) { direntry sectbuf[16]; /* 16 directory entries per sector */ Bit32u logentsector; /* Logical entry sector */ Bit32u entryoffset = 0; /* Index offset within sector */ Bit32u tmpsector; - Bit16u dirPos = 0; + if ((start<0) || (start>65535)) return false; + Bit16u dirPos = (Bit16u)start; + if (entNum=0) { diff --git a/src/dos/drives.h b/src/dos/drives.h index ca0f93a1..d3c47bdb 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -171,7 +171,7 @@ public: Bit32u appendCluster(Bit32u startCluster); void deleteClustChain(Bit32u startCluster); Bit32u getFirstFreeClust(void); - bool directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum); + bool directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum, Bit32s start=0); bool directoryChange(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum); imageDisk *loadedDisk; bool created_successfully; diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 53cc7d98..556b5743 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -149,8 +149,9 @@ Bit8u imageDisk::Read_AbsoluteSector(Bit32u sectnum, void * data) { bytenum = sectnum * sector_size; - fseek(diskimg,bytenum,SEEK_SET); - fread(data, 1, sector_size, diskimg); + if (bytenum!=current_fpos) fseek(diskimg,bytenum,SEEK_SET); + size_t ret=fread(data, 1, sector_size, diskimg); + current_fpos=bytenum+ret; return 0x00; } @@ -161,7 +162,6 @@ Bit8u imageDisk::Write_Sector(Bit32u head,Bit32u cylinder,Bit32u sector,void * d sectnum = ( (cylinder * heads + head) * sectors ) + sector - 1L; return Write_AbsoluteSector(sectnum, data); - } @@ -172,8 +172,9 @@ Bit8u imageDisk::Write_AbsoluteSector(Bit32u sectnum, void *data) { //LOG_MSG("Writing sectors to %ld at bytenum %d", sectnum, bytenum); - fseek(diskimg,bytenum,SEEK_SET); + if (bytenum!=current_fpos) fseek(diskimg,bytenum,SEEK_SET); size_t ret=fwrite(data, sector_size, 1, diskimg); + current_fpos=bytenum+ret; return ((ret>0)?0x00:0x05); @@ -184,7 +185,9 @@ imageDisk::imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHard cylinders = 0; sectors = 0; sector_size = 512; + current_fpos = 0; diskimg = imgFile; + fseek(diskimg,0,SEEK_SET); memset(diskname,0,512); if(strlen((const char *)imgName) > 511) { From a5ee6145038bd04377a96aed133eaa440f14b7d3 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 5 Jun 2011 18:28:00 +0000 Subject: [PATCH 3625/4131] - Add midnight/next day increment - Add date and time commands (functionality limited) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3715 --- include/shell.h | 2 + src/dos/dos.cpp | 79 +++++++++++++++++++---------- src/ints/bios.cpp | 42 +++++++++++++++- src/shell/shell.cpp | 17 +++++++ src/shell/shell_cmds.cpp | 104 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 218 insertions(+), 26 deletions(-) diff --git a/include/shell.h b/include/shell.h index c131f9e4..ec7d7d05 100644 --- a/include/shell.h +++ b/include/shell.h @@ -87,6 +87,8 @@ public: void CMD_HELP(char * args); void CMD_CLS(char * args); void CMD_COPY(char * args); + void CMD_DATE(char * args); + void CMD_TIME(char * args); void CMD_DIR(char * args); void CMD_DELETE(char * args); void CMD_ECHO(char * args); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 17503e2c..e05922bf 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include "dosbox.h" #include "bios.h" #include "mem.h" @@ -41,6 +40,34 @@ void DOS_SetError(Bit16u code) { dos.errorcode=code; } +const Bit8u DOS_DATE_months[] = { + 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +static void DOS_AddDays(Bitu days) { + dos.date.day += days; + Bit8u monthlimit = DOS_DATE_months[dos.date.month]; + + if(dos.date.day > monthlimit) { + if((dos.date.year %4 == 0) && (dos.date.month==2)) { + // leap year + if(dos.date.day > 29) { + dos.date.month++; + dos.date.day -= 29; + } + } else { + //not leap year + dos.date.month++; + dos.date.day -= monthlimit; + } + if(dos.date.month > 12) { + // year over + dos.date.month = 1; + dos.date.year++; + } + } +} + #define DATA_TRANSFERS_TAKE_CYCLES 1 #ifdef DATA_TRANSFERS_TAKE_CYCLES @@ -373,6 +400,9 @@ static Bitu DOS_21Handler(void) { break; case 0x2a: /* Get System Date */ { + reg_ax=0; // get time + CALLBACK_RunRealInt(0x1a); + if(reg_al) DOS_AddDays(reg_al); int a = (14 - dos.date.month)/12; int y = dos.date.year - a; int m = dos.date.month + 12*a - 2; @@ -385,28 +415,37 @@ static Bitu DOS_21Handler(void) { case 0x2b: /* Set System Date */ if (reg_cx<1980) { reg_al=0xff;break;} if ((reg_dh>12) || (reg_dh==0)) { reg_al=0xff;break;} - if ((reg_dl>31) || (reg_dl==0)) { reg_al=0xff;break;} + if (reg_dl==0) { reg_al=0xff;break;} + if (reg_dl>DOS_DATE_months[reg_dh]) { + if(!((reg_dh==2)&&(reg_cx%4 == 0)&&(reg_dl==29))) // february pass + { reg_al=0xff;break; } + } dos.date.year=reg_cx; dos.date.month=reg_dh; dos.date.day=reg_dl; reg_al=0; break; - case 0x2c: /* Get System Time */ -//TODO Get time through bios calls date is fixed - { -/* Calculate how many miliseconds have passed */ - Bitu ticks=5*(mem_readd(BIOS_TIMER) - time_start); - ticks = ((ticks / 59659u) << 16) + ((ticks % 59659u) << 16) / 59659u; - Bitu seconds=(ticks/100); - reg_ch=(Bit8u)(seconds/3600); - reg_cl=(Bit8u)((seconds % 3600)/60); - reg_dh=(Bit8u)(seconds % 60); - reg_dl=(Bit8u)(ticks % 100); - } + case 0x2c: { /* Get System Time */ + reg_ax=0; // get time + CALLBACK_RunRealInt(0x1a); + if(reg_al) DOS_AddDays(reg_al); + + Bitu time=((Bitu)reg_cx<<16)|reg_dx; + Bitu ticks=(Bitu)(5.49254945 * (double)time); + + reg_dl=(Bit8u)((Bitu)ticks % 100); // 1/100 seconds + ticks/=100; + reg_dh=(Bit8u)((Bitu)ticks % 60); // seconds + ticks/=60; + reg_cl=(Bit8u)((Bitu)ticks % 60); // minutes + ticks/=60; + reg_ch=(Bit8u)((Bitu)ticks % 24); // hours + //Simulate DOS overhead for timing-sensitive games - //Robomaze 2 + //Robomaze 2 overhead(); break; + } case 0x2d: /* Set System Time */ LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Set System Time not supported"); //Check input parameters nonetheless @@ -1188,16 +1227,6 @@ public: dos.version.major=5; dos.version.minor=0; - - /* Setup time and date */ - time_t curtime;struct tm *loctime; - curtime = time (NULL);loctime = localtime (&curtime); - - dos.date.day=(Bit8u)loctime->tm_mday; - dos.date.month=(Bit8u)loctime->tm_mon+1; - dos.date.year=(Bit16u)loctime->tm_year+1900; - Bit32u ticks=(Bit32u)((loctime->tm_hour*3600+loctime->tm_min*60+loctime->tm_sec)*(float)PIT_TICK_RATE/65536.0); - mem_writed(BIOS_TIMER,ticks); } ~DOS(){ for (Bit16u i=0;i +#include /* if mem_systems 0 then size_extended is reported as the real size else @@ -311,7 +313,8 @@ static Bitu INT1A_Handler(void) { case 0x00: /* Get System time */ { Bit32u ticks=mem_readd(BIOS_TIMER); - reg_al=0; /* Midnight never passes :) */ + reg_al=mem_readb(BIOS_24_HOURS_FLAG); + mem_writeb(BIOS_24_HOURS_FLAG,0); // reset the "flag" reg_cx=(Bit16u)(ticks >> 16); reg_dx=(Bit16u)(ticks & 0xffff); break; @@ -371,9 +374,45 @@ static Bitu INT11_Handler(void) { #ifndef DOSBOX_CLOCKSYNC #define DOSBOX_CLOCKSYNC 0 #endif + +static void BIOS_HostTimeSync() { + /* Setup time and date */ + struct timeb timebuffer; + ftime(&timebuffer); + + struct tm *loctime; + loctime = localtime (&timebuffer.time); + + /* + loctime->tm_hour = 23; + loctime->tm_min = 59; + loctime->tm_sec = 45; + loctime->tm_mday = 28; + loctime->tm_mon = 2-1; + loctime->tm_year = 2007 - 1900; + */ + + dos.date.day=(Bit8u)loctime->tm_mday; + dos.date.month=(Bit8u)loctime->tm_mon+1; + dos.date.year=(Bit16u)loctime->tm_year+1900; + + Bit32u ticks=(Bit32u)(((double)( + loctime->tm_hour*3600*1000+ + loctime->tm_min*60*1000+ + loctime->tm_sec*1000+ + timebuffer.millitm))*(((double)PIT_TICK_RATE/65536.0)/1000.0)); + mem_writed(BIOS_TIMER,ticks); +} + static Bitu INT8_Handler(void) { /* Increase the bios tick counter */ Bit32u value = mem_readd(BIOS_TIMER) + 1; + if(value >= 0x1800B0) { + // time wrap at midnight + mem_writeb(BIOS_24_HOURS_FLAG,mem_readb(BIOS_24_HOURS_FLAG)+1); + value=0; + } + #if DOSBOX_CLOCKSYNC static bool check = false; if((value %50)==0) { @@ -1079,6 +1118,7 @@ public: size_extended=IO_Read(0x71); IO_Write(0x70,0x31); size_extended|=(IO_Read(0x71) << 8); + BIOS_HostTimeSync(); } ~BIOS(){ /* abort DAC playing */ diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 77a40021..b4384725 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -464,6 +464,23 @@ void SHELL_Init() { MSG_Add("SHELL_CMD_CHDIR_HINT","To change to different drive type \033[31m%c:\033[0m\n"); MSG_Add("SHELL_CMD_CHDIR_HINT_2","directoryname is longer than 8 characters and/or contains spaces.\nTry \033[31mcd %s\033[0m\n"); MSG_Add("SHELL_CMD_CHDIR_HINT_3","You are still on drive Z:, change to a mounted drive with \033[31mC:\033[0m.\n"); + MSG_Add("SHELL_CMD_DATE_HELP","Displays or changes the internal date.\n"); + MSG_Add("SHELL_CMD_DATE_ERROR","The specified date is not correct.\n"); + MSG_Add("SHELL_CMD_DATE_DAYS","3SunMonTueWedThuFriSat"); // "2SoMoDiMiDoFrSa" + MSG_Add("SHELL_CMD_DATE_NOW","Current date: "); + MSG_Add("SHELL_CMD_DATE_SETHLP","Type 'date MM-DD-YYYY' to change.\n"); + MSG_Add("SHELL_CMD_DATE_FORMAT","M/D/Y"); + MSG_Add("SHELL_CMD_DATE_HELP_LONG","DATE [[/T] [/H] [/S] | MM-DD-YYYY]\n"\ + " MM-DD-YYYY: new date to set\n"\ + " /S: Permanently use host time and date as DOS time\n"\ + " /F: Switch back to DOSBox internal time (opposite of /S)\n"\ + " /T: Only display date\n"\ + " /H: Synchronize with host\n"); + MSG_Add("SHELL_CMD_TIME_HELP","Displays the internal time.\n"); + MSG_Add("SHELL_CMD_TIME_NOW","Current time: "); + MSG_Add("SHELL_CMD_TIME_HELP_LONG","TIME [/T] [/H]\n"\ + " /T: Display simple time\n"\ + " /H: Synchronize with host\n"); MSG_Add("SHELL_CMD_MKDIR_ERROR","Unable to make: %s.\n"); MSG_Add("SHELL_CMD_RMDIR_ERROR","Unable to remove: %s.\n"); MSG_Add("SHELL_CMD_DEL_ERROR","Unable to delete: %s.\n"); diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 19791879..e2af8415 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -29,6 +29,7 @@ #include #include #include +#include static SHELL_Cmd cmd_list[]={ { "DIR", 0, &DOS_Shell::CMD_DIR, "SHELL_CMD_DIR_HELP"}, @@ -39,6 +40,7 @@ static SHELL_Cmd cmd_list[]={ { "CHOICE", 1, &DOS_Shell::CMD_CHOICE, "SHELL_CMD_CHOICE_HELP"}, { "CLS", 0, &DOS_Shell::CMD_CLS, "SHELL_CMD_CLS_HELP"}, { "COPY", 0, &DOS_Shell::CMD_COPY, "SHELL_CMD_COPY_HELP"}, +{ "DATE", 0, &DOS_Shell::CMD_DATE, "SHELL_CMD_DATE_HELP"}, { "DEL", 0, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, { "DELETE", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, { "ERASE", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"}, @@ -61,6 +63,7 @@ static SHELL_Cmd cmd_list[]={ { "SET", 1, &DOS_Shell::CMD_SET, "SHELL_CMD_SET_HELP"}, { "SHIFT", 1, &DOS_Shell::CMD_SHIFT, "SHELL_CMD_SHIFT_HELP"}, { "SUBST", 1, &DOS_Shell::CMD_SUBST, "SHELL_CMD_SUBST_HELP"}, +{ "TIME", 0, &DOS_Shell::CMD_TIME, "SHELL_CMD_TIME_HELP"}, { "TYPE", 0, &DOS_Shell::CMD_TYPE, "SHELL_CMD_TYPE_HELP"}, { "VER", 0, &DOS_Shell::CMD_VER, "SHELL_CMD_VER_HELP"}, {0,0,0,0} @@ -937,6 +940,107 @@ void DOS_Shell::CMD_CALL(char * args){ this->call=false; } +void DOS_Shell::CMD_DATE(char * args) { + HELP("DATE"); + if(ScanCMDBool(args,"h")) { + // synchronize date with host parameter + time_t curtime; + struct tm *loctime; + curtime = time (NULL); + loctime = localtime (&curtime); + + reg_cx = loctime->tm_year+1900; + reg_dh = loctime->tm_mon+1; + reg_dl = loctime->tm_mday; + + reg_ah=0x2b; // set system date + CALLBACK_RunRealInt(0x21); + return; + } + // check if a date was passed in command line + Bitu newday,newmonth,newyear; + if(sscanf(args,"%u-%u-%u",&newmonth,&newday,&newyear)==3) { + reg_cx = newyear; + reg_dh = newmonth; + reg_dl = newday; + + reg_ah=0x2b; // set system date + CALLBACK_RunRealInt(0x21); + if(reg_al==0xff) WriteOut(MSG_Get("SHELL_CMD_DATE_ERROR")); + return; + } + // display the current date + reg_ah=0x2a; // get system date + CALLBACK_RunRealInt(0x21); + + const char* datestring = MSG_Get("SHELL_CMD_DATE_DAYS"); + Bit8u length; + char day[6] = {0}; + if(sscanf(datestring,"%u",&length) && (length<5) && (strlen(datestring)==(length*7+1))) { + // date string appears valid + for(int i = 0; i < length; i++) day[i] = datestring[reg_al*length+1+i]; + } + bool dateonly = ScanCMDBool(args,"t"); + if(!dateonly) WriteOut(MSG_Get("SHELL_CMD_DATE_NOW")); + + const char* formatstring = MSG_Get("SHELL_CMD_DATE_FORMAT"); + if(strlen(formatstring)!=5) return; + char buffer[15] = {0}; + Bitu bufferptr=0; + for(Bitu i = 0; i < 5; i++) { + if(i==1 || i==3) { + buffer[bufferptr] = formatstring[i]; + bufferptr++; + } else { + if(formatstring[i]=='M') bufferptr += sprintf(buffer+bufferptr,"%02u",(Bitu)reg_dh); + if(formatstring[i]=='D') bufferptr += sprintf(buffer+bufferptr,"%02u",(Bitu)reg_dl); + if(formatstring[i]=='Y') bufferptr += sprintf(buffer+bufferptr,"%04u",(Bitu)reg_cx); + } + } + WriteOut("%s %s\n",day, buffer); + if(!dateonly) WriteOut(MSG_Get("SHELL_CMD_DATE_SETHLP")); +}; + +void DOS_Shell::CMD_TIME(char * args) { + HELP("TIME"); + if(ScanCMDBool(args,"h")) { + // synchronize time with host parameter + time_t curtime; + struct tm *loctime; + curtime = time (NULL); + loctime = localtime (&curtime); + + //reg_cx = loctime->; + //reg_dh = loctime->; + //reg_dl = loctime->; + + // reg_ah=0x2d; // set system time TODO + // CALLBACK_RunRealInt(0x21); + + Bit32u ticks=(Bit32u)(((double)(loctime->tm_hour*3600+ + loctime->tm_min*60+ + loctime->tm_sec))*18.206481481); + mem_writed(BIOS_TIMER,ticks); + return; + } + bool timeonly = ScanCMDBool(args,"t"); + + reg_ah=0x2c; // get system time + CALLBACK_RunRealInt(0x21); +/* + reg_dl= // 1/100 seconds + reg_dh= // seconds + reg_cl= // minutes + reg_ch= // hours +*/ + if(timeonly) { + WriteOut("%2u:%02u\n",reg_ch,reg_cl); + } else { + WriteOut(MSG_Get("SHELL_CMD_TIME_NOW")); + WriteOut("%2u:%02u:%02u,%02u\n",reg_ch,reg_cl,reg_dh,reg_dl); + } +}; + void DOS_Shell::CMD_SUBST (char * args) { /* If more that one type can be substed think of something else * E.g. make basedir member dos_drive instead of localdrive From 480fafcecbc0821a5b2fd7592996be2f91a7b00d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 7 Jun 2011 20:04:13 +0000 Subject: [PATCH 3626/4131] Add 0x9d for Duke3d caribbean launcher. (ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3716 --- src/dos/dos_files.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 0e627e91..618e6e65 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -92,7 +92,7 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { case '!': case '%': case '{': case '}': case '`': case '~': case '_': case '-': case '.': case '*': case '?': case '&': case '\'': case '+': case '^': case 246: case 255: case 0xa0: - case 0xe5: case 0xbd: + case 0xe5: case 0xbd: case 0x9d: upname[w++]=c; break; default: From cca9bb077abb7605cef2c52de4a9981371c82d2a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 11 Jun 2011 13:49:14 +0000 Subject: [PATCH 3627/4131] Typo alreadu=>already Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3717 --- src/hardware/ipx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index d598ce3a..14f55fb2 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -935,7 +935,7 @@ public: if(strcasecmp("startserver", temp_line.c_str()) == 0) { if(!isIpxServer) { if(incomingPacket.connected) { - WriteOut("IPX Tunneling Client alreadu connected to another server. Disconnect first.\n"); + WriteOut("IPX Tunneling Client already connected to another server. Disconnect first.\n"); return; } bool startsuccess; From de75bc83f68ba786665cf132c07ff1fa8e24f7d3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 12 Jun 2011 13:56:44 +0000 Subject: [PATCH 3628/4131] Enforce call order of the functions used in the bitshift. Fixes visual C /O2 builds. Thanks h-a-l-9000 and wjp. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3718 --- configure.in | 5 +-- src/cpu/paging.cpp | 16 ++++----- src/hardware/memory.cpp | 14 ++++---- src/hardware/vga_memory.cpp | 72 ++++++++++++++++++------------------- 4 files changed, 55 insertions(+), 52 deletions(-) diff --git a/configure.in b/configure.in index 54b5356c..4c0315cd 100644 --- a/configure.in +++ b/configure.in @@ -367,7 +367,7 @@ 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" +LIBS="$LIBS -lSDL_net /home/pveenstra/qbix/cross3/usr/lib/libvorbisfile.a /home/pveenstra/qbix/cross3/usr/lib/libvorbis.a /home/pveenstra/qbix/cross3/usr/lib/libogg.a" AC_DEFINE(C_MODEM,1) AC_DEFINE(C_IPX,1) else @@ -499,7 +499,8 @@ esac AC_SUBST(WINDRES) -AC_CONFIG_FILES([ + +AC_CONFIG_FILES([ Makefile src/Makefile src/cpu/Makefile diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 7707554d..7dbff72f 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -43,16 +43,16 @@ Bitu PageHandler::readb(PhysPt addr) { return 0; } Bitu PageHandler::readw(PhysPt addr) { - return - (readb(addr+0) << 0) | - (readb(addr+1) << 8); + Bitu ret = (readb(addr+0) << 0); + ret |= (readb(addr+1) << 8); + return ret; } Bitu PageHandler::readd(PhysPt addr) { - return - (readb(addr+0) << 0) | - (readb(addr+1) << 8) | - (readb(addr+2) << 16) | - (readb(addr+3) << 24); + Bitu ret = (readb(addr+0) << 0); + ret |= (readb(addr+1) << 8); + ret |= (readb(addr+2) << 16); + ret |= (readb(addr+3) << 24); + return ret; } void PageHandler::writeb(PhysPt addr,Bitu /*val*/) { diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 3f56c6e5..a347c918 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -427,15 +427,17 @@ void MEM_A20_Enable(bool enabled) { /* Memory access functions */ Bit16u mem_unalignedreadw(PhysPt address) { - return mem_readb_inline(address) | - mem_readb_inline(address+1) << 8; + Bit16u ret = mem_readb_inline(address); + ret |= mem_readb_inline(address+1) << 8; + return ret; } Bit32u mem_unalignedreadd(PhysPt address) { - return mem_readb_inline(address) | - (mem_readb_inline(address+1) << 8) | - (mem_readb_inline(address+2) << 16) | - (mem_readb_inline(address+3) << 24); + Bit32u ret = mem_readb_inline(address); + ret |= mem_readb_inline(address+1) << 8; + ret |= mem_readb_inline(address+2) << 16; + ret |= mem_readb_inline(address+3) << 24; + return ret; } diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 0c4428d6..9a3167ae 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -160,19 +160,19 @@ public: addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_read_full; addr = CHECKED2(addr); - return - (readHandler(addr+0) << 0) | - (readHandler(addr+1) << 8); + Bitu ret = (readHandler(addr+0) << 0); + ret |= (readHandler(addr+1) << 8); + return ret; } Bitu readd(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_read_full; addr = CHECKED2(addr); - return - (readHandler(addr+0) << 0) | - (readHandler(addr+1) << 8) | - (readHandler(addr+2) << 16) | - (readHandler(addr+3) << 24); + Bitu ret = (readHandler(addr+0) << 0); + ret |= (readHandler(addr+1) << 8); + ret |= (readHandler(addr+2) << 16); + ret |= (readHandler(addr+3) << 24); + return ret; } }; @@ -246,19 +246,19 @@ public: addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_read_full; addr = CHECKED(addr); - return - (readHandler(addr+0) << 0) | - (readHandler(addr+1) << 8); + Bitu ret = (readHandler(addr+0) << 0); + ret |= (readHandler(addr+1) << 8); + return ret; } Bitu readd(PhysPt addr) { addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_read_full; addr = CHECKED(addr); - return - (readHandler(addr+0) << 0) | - (readHandler(addr+1) << 8) | - (readHandler(addr+2) << 16) | - (readHandler(addr+3) << 24); + Bitu ret = (readHandler(addr+0) << 0); + ret |= (readHandler(addr+1) << 8); + ret |= (readHandler(addr+2) << 16); + ret |= (readHandler(addr+3) << 24); + return ret; } }; @@ -355,24 +355,24 @@ public: addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_read_full; addr = CHECKED(addr); - if (GCC_UNLIKELY(addr & 1)) - return - (readHandler( addr+0 ) << 0 ) | - (readHandler( addr+1 ) << 8 ); - else + if (GCC_UNLIKELY(addr & 1)) { + Bitu ret = (readHandler( addr+0 ) << 0 ); + ret |= (readHandler( addr+1 ) << 8 ); + return ret; + } else return readHandler( addr ); } Bitu readd(PhysPt addr ) { addr = PAGING_GetPhysicalAddress(addr) & vgapages.mask; addr += vga.svga.bank_read_full; addr = CHECKED(addr); - if (GCC_UNLIKELY(addr & 3)) - return - (readHandler( addr+0 ) << 0 ) | - (readHandler( addr+1 ) << 8 ) | - (readHandler( addr+2 ) << 16 ) | - (readHandler( addr+3 ) << 24 ); - else + if (GCC_UNLIKELY(addr & 3)) { + Bitu ret = (readHandler( addr+0 ) << 0 ); + ret |= (readHandler( addr+1 ) << 8 ); + ret |= (readHandler( addr+2 ) << 16 ); + ret |= (readHandler( addr+3 ) << 24 ); + return ret; + } else return readHandler( addr ); } void writeb(PhysPt addr, Bitu val ) { @@ -588,18 +588,18 @@ public: Bitu readw(PhysPt addr) { addr = vga.svga.bank_read_full + (PAGING_GetPhysicalAddress(addr) & 0xffff); addr = CHECKED4(addr); - return - (readHandler(addr+0) << 0) | - (readHandler(addr+1) << 8); + Bitu ret = (readHandler(addr+0) << 0); + ret |= (readHandler(addr+1) << 8); + return ret; } Bitu readd(PhysPt addr) { addr = vga.svga.bank_read_full + (PAGING_GetPhysicalAddress(addr) & 0xffff); addr = CHECKED4(addr); - return - (readHandler(addr+0) << 0) | - (readHandler(addr+1) << 8) | - (readHandler(addr+2) << 16) | - (readHandler(addr+3) << 24); + Bitu ret = (readHandler(addr+0) << 0); + ret |= (readHandler(addr+1) << 8); + ret |= (readHandler(addr+2) << 16); + ret |= (readHandler(addr+3) << 24); + return ret; } }; From 73cc716621be7bf1d200235ee1a67334358bd048 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 12 Jun 2011 13:58:27 +0000 Subject: [PATCH 3629/4131] Wrong file commited Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3719 --- configure.in | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/configure.in b/configure.in index 4c0315cd..54b5356c 100644 --- a/configure.in +++ b/configure.in @@ -367,7 +367,7 @@ 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 /home/pveenstra/qbix/cross3/usr/lib/libvorbisfile.a /home/pveenstra/qbix/cross3/usr/lib/libvorbis.a /home/pveenstra/qbix/cross3/usr/lib/libogg.a" + LIBS="$LIBS -lSDL_net" AC_DEFINE(C_MODEM,1) AC_DEFINE(C_IPX,1) else @@ -499,8 +499,7 @@ esac AC_SUBST(WINDRES) - -AC_CONFIG_FILES([ +AC_CONFIG_FILES([ Makefile src/Makefile src/cpu/Makefile From 039e32658a161a0cb119b0c190cb4d762c8c1a72 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 12 Jun 2011 16:58:14 +0000 Subject: [PATCH 3630/4131] Patch: - Fix regression with Romantic Blue caused by the midnight overflow patch - Preserve AH - Derive conversion value from known constants instead of using a magic number Thanks to ripsaw8080. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3720 --- src/dos/dos.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index e05922bf..83007e15 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -429,17 +429,19 @@ static Bitu DOS_21Handler(void) { reg_ax=0; // get time CALLBACK_RunRealInt(0x1a); if(reg_al) DOS_AddDays(reg_al); + reg_ah=0x2c; - Bitu time=((Bitu)reg_cx<<16)|reg_dx; - Bitu ticks=(Bitu)(5.49254945 * (double)time); + Bitu ticks=((Bitu)reg_cx<<16)|reg_dx; + if(time_start<=ticks) ticks-=time_start; + Bitu time=(Bitu)((100.0/((double)PIT_TICK_RATE/65536.0)) * (double)ticks); - reg_dl=(Bit8u)((Bitu)ticks % 100); // 1/100 seconds - ticks/=100; - reg_dh=(Bit8u)((Bitu)ticks % 60); // seconds - ticks/=60; - reg_cl=(Bit8u)((Bitu)ticks % 60); // minutes - ticks/=60; - reg_ch=(Bit8u)((Bitu)ticks % 24); // hours + reg_dl=(Bit8u)((Bitu)time % 100); // 1/100 seconds + time/=100; + reg_dh=(Bit8u)((Bitu)time % 60); // seconds + time/=60; + reg_cl=(Bit8u)((Bitu)time % 60); // minutes + time/=60; + reg_ch=(Bit8u)((Bitu)time % 24); // hours //Simulate DOS overhead for timing-sensitive games //Robomaze 2 From f1d85a3739b8d855e712aa07a8d9346a5eecfd54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 17 Jun 2011 14:28:00 +0000 Subject: [PATCH 3631/4131] add manual uninstall functions for callback/io-handler objects Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3721 --- include/callback.h | 2 ++ include/inout.h | 2 ++ src/cpu/callback.cpp | 6 +++++- src/hardware/iohandler.cpp | 12 ++++++++++-- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/include/callback.h b/include/callback.h index ca557652..382efc56 100644 --- a/include/callback.h +++ b/include/callback.h @@ -95,6 +95,8 @@ public: void Install(CallBack_Handler handler,Bitu type,const char* description); void Install(CallBack_Handler handler,Bitu type,PhysPt addr,const char* description); + void Uninstall(); + //Only allocate a callback number void Allocate(CallBack_Handler handler,const char* description=0); Bit16u Get_callback() { diff --git a/include/inout.h b/include/inout.h index cb0b7e57..a49f639b 100644 --- a/include/inout.h +++ b/include/inout.h @@ -59,11 +59,13 @@ public: class IO_ReadHandleObject: private IO_Base{ public: void Install(Bitu port,IO_ReadHandler * handler,Bitu mask,Bitu range=1); + void Uninstall(); ~IO_ReadHandleObject(); }; class IO_WriteHandleObject: private IO_Base{ public: void Install(Bitu port,IO_WriteHandler * handler,Bitu mask,Bitu range=1); + void Uninstall(); ~IO_WriteHandleObject(); }; diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index ff5c92d7..c4ae982c 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -464,7 +464,7 @@ void CALLBACK_RemoveSetup(Bitu callback) { } } -CALLBACK_HandlerObject::~CALLBACK_HandlerObject(){ +void CALLBACK_HandlerObject::Uninstall(){ if(!installed) return; if(m_type == CALLBACK_HandlerObject::SETUP) { if(vectorhandler.installed){ @@ -485,6 +485,10 @@ CALLBACK_HandlerObject::~CALLBACK_HandlerObject(){ CALLBACK_DeAllocate(m_callback); } +CALLBACK_HandlerObject::~CALLBACK_HandlerObject(){ + Uninstall(); +} + void CALLBACK_HandlerObject::Install(CallBack_Handler handler,Bitu type,const char* description){ if(!installed) { installed=true; diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 1f16a562..84cb21ea 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -118,11 +118,15 @@ void IO_ReadHandleObject::Install(Bitu port,IO_ReadHandler * handler,Bitu mask,B } else E_Exit("IO_readHandler allready installed port %x",port); } -IO_ReadHandleObject::~IO_ReadHandleObject(){ +void IO_ReadHandleObject::Uninstall(){ if(!installed) return; IO_FreeReadHandler(m_port,m_mask,m_range); } +IO_ReadHandleObject::~IO_ReadHandleObject(){ + Uninstall(); +} + void IO_WriteHandleObject::Install(Bitu port,IO_WriteHandler * handler,Bitu mask,Bitu range) { if(!installed) { installed=true; @@ -133,9 +137,13 @@ void IO_WriteHandleObject::Install(Bitu port,IO_WriteHandler * handler,Bitu mask } else E_Exit("IO_writeHandler allready installed port %x",port); } -IO_WriteHandleObject::~IO_WriteHandleObject(){ +void IO_WriteHandleObject::Uninstall() { if(!installed) return; IO_FreeWriteHandler(m_port,m_mask,m_range); +} + +IO_WriteHandleObject::~IO_WriteHandleObject(){ + Uninstall(); //LOG_MSG("FreeWritehandler called with port %X",m_port); } From 1828977d5cf269a19f6979794815221562ce92b1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 17 Jun 2011 22:00:10 +0000 Subject: [PATCH 3632/4131] Refinement of default case. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3722 --- src/dos/dos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 83007e15..150dde99 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1119,7 +1119,7 @@ static Bitu DOS_21Handler(void) { case 0x71: /* Unknown probably 4dos detection */ reg_ax=0x7100; - CALLBACK_SCF(true); + CALLBACK_SCF(true); //Check this! What needs this ? See default case LOG(LOG_DOSMISC,LOG_NORMAL)("DOS:Windows long file name support call %2X",reg_al); break; @@ -1133,7 +1133,7 @@ static Bitu DOS_21Handler(void) { case 0xEF: /* Used in Ancient Art Of War CGA */ case 0x5e: /* More Network Functions */ default: - LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Unhandled call %02X al=%02X. Set al to default of 0",reg_ah,reg_al); + if (reg_ah < 0x6d) LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Unhandled call %02X al=%02X. Set al to default of 0",reg_ah,reg_al); //Less errors. above 0x6c the functions are simply always skipped, only al is zeroed, all other registers untouched reg_al=0x00; /* default value */ break; }; From 6bc4e41458c55625ccbea0ccd95ddf12ef5cac0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 18 Jun 2011 13:39:31 +0000 Subject: [PATCH 3633/4131] add PCI framework Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3723 --- include/Makefile.am | 1 + include/logging.h | 7 +- include/pci_bus.h | 85 +++++++ src/debug/debug_gui.cpp | 1 + src/dosbox.cpp | 11 + src/hardware/Makefile.am | 4 +- src/hardware/pci_bus.cpp | 438 +++++++++++++++++++++++++++++++++++++ src/hardware/pci_devices.h | 18 ++ src/ints/bios.cpp | 115 +++++++++- visualc_net/dosbox.vcproj | 6 + 10 files changed, 682 insertions(+), 4 deletions(-) create mode 100644 include/pci_bus.h create mode 100644 src/hardware/pci_bus.cpp create mode 100644 src/hardware/pci_devices.h diff --git a/include/Makefile.am b/include/Makefile.am index b37389c8..2e7808f6 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -24,6 +24,7 @@ mixer.h \ modules.h \ mouse.h \ paging.h \ +pci_bus.h \ pic.h \ programs.h \ render.h \ diff --git a/include/logging.h b/include/logging.h index e645d2ea..7faf84cd 100644 --- a/include/logging.h +++ b/include/logging.h @@ -27,6 +27,7 @@ enum LOG_TYPES { LOG_PIT,LOG_KEYBOARD,LOG_PIC, LOG_MOUSE,LOG_BIOS,LOG_GUI,LOG_MISC, LOG_IO, + LOG_PCI, LOG_MAX }; @@ -65,6 +66,10 @@ struct LOG 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* , double , double , double , double , double , double ) { } + void operator()(char const* , double , double , double , double , double , double , double) { } + + void operator()(char const* , char const* ) { } void operator()(char const* , char const* , double ) { } @@ -73,7 +78,7 @@ struct LOG void operator()(char const* , double , double, char const* ) { } void operator()(char const* , char const*, char const*) { } - + void operator()(char const* , double , double , double , 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)); diff --git a/include/pci_bus.h b/include/pci_bus.h new file mode 100644 index 00000000..470114ff --- /dev/null +++ b/include/pci_bus.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2002-2011 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_PCI_H +#define DOSBOX_PCI_H + +//#define PCI_FUNCTIONALITY_ENABLED 0 + +#if defined PCI_FUNCTIONALITY_ENABLED + +#define PCI_MAX_PCIDEVICES 10 +#define PCI_MAX_PCIFUNCTIONS 8 + + +class PCI_Device { +private: + Bits pci_id, pci_subfunction; + Bit16u vendor_id, device_id; + + // subdevices declarations, they will respond to pci functions 1 to 7 + // (main device is attached to function 0) + Bitu num_subdevices; + PCI_Device* subdevices[PCI_MAX_PCIFUNCTIONS-1]; + +public: + PCI_Device(Bit16u vendor, Bit16u device); + + Bits PCIId(void) { + return pci_id; + } + Bits PCISubfunction(void) { + return pci_subfunction; + } + Bit16u VendorID(void) { + return vendor_id; + } + Bit16u DeviceID(void) { + return device_id; + } + + void SetPCIId(Bitu number, Bits subfct); + + bool AddSubdevice(PCI_Device* dev); + void RemoveSubdevice(Bits subfct); + + PCI_Device* GetSubdevice(Bits subfct); + + Bit16u NumSubdevices(void) { + if (num_subdevices>PCI_MAX_PCIFUNCTIONS-1) return PCI_MAX_PCIFUNCTIONS-1; + return num_subdevices; + } + + Bits GetNextSubdeviceNumber(void) { + if (num_subdevices>=PCI_MAX_PCIFUNCTIONS-1) return -1; + return num_subdevices+1; + } + + virtual Bits ParseReadRegister(Bit8u regnum)=0; + virtual Bits ParseWriteRegister(Bit8u regnum,Bit8u value)=0; + virtual bool InitializeRegisters(Bit8u registers[256])=0; + +}; + +bool PCI_IsInitialized(); + +RealPt PCI_GetPModeInterface(void); + +#endif + +#endif diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index c2fa4576..c57872fb 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -245,6 +245,7 @@ void LOG_StartUp(void) { loggrp[LOG_MISC].front="MISC"; loggrp[LOG_IO].front="IO"; + loggrp[LOG_PCI].front="PCI"; /* Register the log section */ Section_prop * sect=control->AddSection_prop("log",LOG_Init); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index d95de3f8..79fb5db8 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -41,6 +41,7 @@ #include "mapper.h" #include "ints/int10.h" #include "render.h" +#include "pci_bus.h" Config * control; MachineType machine; @@ -73,6 +74,10 @@ void MIXER_Init(Section*); void MIDI_Init(Section*); void HARDWARE_Init(Section*); +#if defined(PCI_FUNCTIONALITY_ENABLED) +void PCI_Init(Section*); +#endif + void KEYBOARD_Init(Section*); //TODO This should setup INT 16 too but ok ;) void JOYSTICK_Init(Section*); @@ -446,6 +451,12 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&VGA_Init); secprop->AddInitFunction(&KEYBOARD_Init); + +#if defined(PCI_FUNCTIONALITY_ENABLED) + secprop=control->AddSection_prop("pci",&PCI_Init,false); //PCI bus +#endif + + secprop=control->AddSection_prop("mixer",&MIXER_Init); Pbool = secprop->Add_bool("nosound",Property::Changeable::OnlyAtStart,false); Pbool->Set_help("Enable silent mode, sound is still emulated though."); diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index 5631a06d..1ec7e67d 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -2,12 +2,12 @@ AM_CPPFLAGS = -I$(top_srcdir)/include SUBDIRS = serialport -EXTRA_DIST = opl.cpp opl.h adlib.h dbopl.h +EXTRA_DIST = opl.cpp opl.h adlib.h dbopl.h pci_devices.h noinst_LIBRARIES = libhardware.a libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler.cpp joystick.cpp keyboard.cpp \ - memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ + memory.cpp mixer.cpp pcspeaker.cpp pci_bus.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp vga_other.cpp \ vga_memory.cpp vga_misc.cpp vga_seq.cpp vga_xga.cpp vga_s3.cpp vga_tseng.cpp vga_paradise.cpp \ cmos.cpp disney.cpp gus.cpp mpu401.cpp ipx.cpp ipxserver.cpp dbopl.cpp diff --git a/src/hardware/pci_bus.cpp b/src/hardware/pci_bus.cpp new file mode 100644 index 00000000..f958cda2 --- /dev/null +++ b/src/hardware/pci_bus.cpp @@ -0,0 +1,438 @@ +/* + * Copyright (C) 2002-2011 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" +#include "inout.h" +#include "mem.h" +#include "pci_bus.h" +#include "setup.h" +#include "debug.h" +#include "callback.h" +#include "regs.h" + + +#if defined(PCI_FUNCTIONALITY_ENABLED) + +static Bit32u pci_caddress=0; // current PCI addressing +static Bitu pci_devices_installed=0; // number of registered PCI devices + +static Bit8u pci_cfg_data[PCI_MAX_PCIDEVICES][PCI_MAX_PCIFUNCTIONS][256]; // PCI configuration data +static PCI_Device* pci_devices[PCI_MAX_PCIDEVICES]; // registered PCI devices + + +// PCI address +// 31 - set for a PCI access +// 30-24 - 0 +// 23-16 - bus number (0x00ff0000) +// 15-11 - device number (slot) (0x0000f800) +// 10- 8 - subfunction number (0x00000700) +// 7- 2 - config register # (0x000000fc) + +static void write_pci_addr(Bitu port,Bitu val,Bitu iolen) { + LOG(LOG_PCI,LOG_NORMAL)("Write PCI address :=%x",val); + pci_caddress=val; +} + +static void write_pci_register(PCI_Device* dev,Bit8u regnum,Bit8u value) { + // vendor/device/class IDs/header type/etc. are read-only + if ((regnum<0x04) || ((regnum>=0x06) && (regnum<0x0c)) || (regnum==0x0e)) return; + if (dev==NULL) return; + switch (pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][0x0e]&0x7f) { // header-type specific handling + case 0x00: + if ((regnum>=0x28) && (regnum<0x30)) return; // subsystem information is read-only + break; + case 0x01: + case 0x02: + default: + break; + } + + // call device routine for special actions and the + // possibility to discard/replace the value that is to be written + Bits parsed_register=dev->ParseWriteRegister(regnum,value); + if (parsed_register>=0) + pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][regnum]=(Bit8u)(parsed_register&0xff); +} + +static void write_pci(Bitu port,Bitu val,Bitu iolen) { + LOG(LOG_PCI,LOG_NORMAL)("Write PCI data :=%x (len %d)",port,val,iolen); + + // check for enabled/bus 0 + if ((pci_caddress & 0x80ff0000) == 0x80000000) { + Bit8u devnum = (Bit8u)((pci_caddress >> 11) & 0x1f); + Bit8u fctnum = (Bit8u)((pci_caddress >> 8) & 0x7); + Bit8u regnum = (Bit8u)((pci_caddress & 0xfc) + (port & 0x03)); + LOG(LOG_PCI,LOG_NORMAL)(" Write to device %x register %x (function %x) (:=%x)",devnum,regnum,fctnum,val); + + if (devnum>=pci_devices_installed) return; + PCI_Device* masterdev=pci_devices[devnum]; + if (masterdev==NULL) return; + if (fctnum>masterdev->NumSubdevices()) return; + + PCI_Device* dev=masterdev->GetSubdevice(fctnum); + if (dev==NULL) return; + + // write data to PCI device/configuration + switch (iolen) { + case 1: write_pci_register(dev,regnum+0,(Bit8u)(val&0xff)); break; + case 2: write_pci_register(dev,regnum+0,(Bit8u)(val&0xff)); + write_pci_register(dev,regnum+1,(Bit8u)((val>>8)&0xff)); break; + case 4: write_pci_register(dev,regnum+0,(Bit8u)(val&0xff)); + write_pci_register(dev,regnum+1,(Bit8u)((val>>8)&0xff)); + write_pci_register(dev,regnum+2,(Bit8u)((val>>16)&0xff)); + write_pci_register(dev,regnum+3,(Bit8u)((val>>24)&0xff)); break; + } + } +} + + +static Bitu read_pci_addr(Bitu port,Bitu iolen) { + LOG(LOG_PCI,LOG_NORMAL)("Read PCI address -> %x",pci_caddress); + return pci_caddress; +} + +// read single 8bit value from register file (special register treatment included) +static Bit8u read_pci_register(PCI_Device* dev,Bit8u regnum) { + switch (regnum) { + case 0x00: + return (Bit8u)(dev->VendorID()&0xff); + case 0x01: + return (Bit8u)((dev->VendorID()>>8)&0xff); + case 0x02: + return (Bit8u)(dev->DeviceID()&0xff); + case 0x03: + return (Bit8u)((dev->DeviceID()>>8)&0xff); + + case 0x0e: + return (pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][regnum]&0x7f) | + ((dev->NumSubdevices()>0)?0x80:0x00); + default: + break; + } + + // call device routine for special actions and possibility to discard/remap register + Bits parsed_regnum=dev->ParseReadRegister(regnum); + if ((parsed_regnum>=0) && (parsed_regnum<256)) + return pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][parsed_regnum]; + + return 0xff; +} + +static Bitu read_pci(Bitu port,Bitu iolen) { + LOG(LOG_PCI,LOG_NORMAL)("Read PCI data -> %x",pci_caddress); + + if ((pci_caddress & 0x80ff0000) == 0x80000000) { + Bit8u devnum = (Bit8u)((pci_caddress >> 11) & 0x1f); + Bit8u fctnum = (Bit8u)((pci_caddress >> 8) & 0x7); + Bit8u regnum = (Bit8u)((pci_caddress & 0xfc) + (port & 0x03)); + if (devnum>=pci_devices_installed) return 0xffffffff; + LOG(LOG_PCI,LOG_NORMAL)(" Read from device %x register %x (function %x); addr %x", + devnum,regnum,fctnum,pci_caddress); + + PCI_Device* masterdev=pci_devices[devnum]; + if (masterdev==NULL) return 0xffffffff; + if (fctnum>masterdev->NumSubdevices()) return 0xffffffff; + + PCI_Device* dev=masterdev->GetSubdevice(fctnum); + + if (dev!=NULL) { + switch (iolen) { + case 1: + { + Bit8u val8=read_pci_register(dev,regnum); + return val8; + } + case 2: + { + Bit16u val16=read_pci_register(dev,regnum); + val16|=(read_pci_register(dev,regnum+1)<<8); + return val16; + } + case 4: + { + Bit32u val32=read_pci_register(dev,regnum); + val32|=(read_pci_register(dev,regnum+1)<<8); + val32|=(read_pci_register(dev,regnum+2)<<16); + val32|=(read_pci_register(dev,regnum+3)<<24); + return val32; + } + default: + break; + } + } + } + return 0xffffffff; +} + + +static Bitu PCI_PM_Handler() { + LOG_MSG("PCI PMode handler, function %x",reg_ax); + return CBRET_NONE; +} + + +PCI_Device::PCI_Device(Bit16u vendor, Bit16u device) { + pci_id=-1; + pci_subfunction=-1; + vendor_id=vendor; + device_id=device; + num_subdevices=0; + for (Bitu dct=0;dct=0) && (number=0) && (subfct0) && (subfctNumSubdevices()) { + delete subdevices[subfct-1]; + subdevices[subfct-1]=NULL; + // should adjust things like num_subdevices as well... + } + } +} + +PCI_Device* PCI_Device::GetSubdevice(Bits subfct) { + if (subfct>=PCI_MAX_PCIFUNCTIONS) return NULL; + if (subfct>0) { + if (subfct<=this->NumSubdevices()) return subdevices[subfct-1]; + } else if (subfct==0) { + return this; + } + return NULL; +} + + +// queued devices (PCI device registering requested before the PCI framework was initialized) +static const Bitu max_rqueued_devices=16; +static Bitu num_rqueued_devices=0; +static PCI_Device* rqueued_devices[max_rqueued_devices]; + + +#include "pci_devices.h" + +class PCI:public Module_base{ +private: + bool initialized; + +protected: + IO_WriteHandleObject PCI_WriteHandler[5]; + IO_ReadHandleObject PCI_ReadHandler[5]; + + CALLBACK_HandlerObject callback_pci; + +public: + + PhysPt GetPModeCallbackPointer(void) { + return Real2Phys(callback_pci.Get_RealPointer()); + } + + bool IsInitialized(void) { + return initialized; + } + + // set up port handlers and configuration data + void InitializePCI(void) { + // install PCI-addressing ports + PCI_WriteHandler[0].Install(0xcf8,write_pci_addr,IO_MD); + PCI_ReadHandler[0].Install(0xcf8,read_pci_addr,IO_MD); + // install PCI-register read/write handlers + for (Bitu ct=0;ct<4;ct++) { + PCI_WriteHandler[1+ct].Install(0xcfc+ct,write_pci,IO_MB); + PCI_ReadHandler[1+ct].Install(0xcfc+ct,read_pci,IO_MB); + } + + for (Bitu dev=0; dev=0) { + // specific slot specified, basic check for validity + if (slot>=PCI_MAX_PCIDEVICES) return -1; + } else { + // auto-add to new slot, check if one is still free + if (pci_devices_installed>=PCI_MAX_PCIDEVICES) return -1; + } + + if (!initialized) InitializePCI(); + + if (slot<0) slot=pci_devices_installed; // use next slot + Bits subfunction=0; // main device unless specific already-occupied slot is requested + if (pci_devices[slot]!=NULL) { + subfunction=pci_devices[slot]->GetNextSubdeviceNumber(); + if (subfunction<0) E_Exit("Too many PCI subdevices!"); + } + + if (device->InitializeRegisters(pci_cfg_data[slot][subfunction])) { + device->SetPCIId(slot, subfunction); + if (pci_devices[slot]==NULL) { + pci_devices[slot]=device; + pci_devices_installed++; + } else { + pci_devices[slot]->AddSubdevice(device); + } + + return slot; + } + + return -1; + } + + void Deinitialize(void) { + initialized=false; + pci_devices_installed=0; + num_rqueued_devices=0; + pci_caddress=0; + + for (Bitu dev=0; devNumSubdevices()>0) { + for (Bitu sct=1;sctGetSubdevice(sct); + if (sdev!=NULL) { + if ((sdev->VendorID()==vendor_id) && (sdev->DeviceID()==device_id)) { + pci_devices[dct]->RemoveSubdevice(sct); + } + } + } + } + + if ((pci_devices[dct]->VendorID()==vendor_id) && (pci_devices[dct]->DeviceID()==device_id)) { + delete pci_devices[dct]; + pci_devices[dct]=NULL; + } + } + } + + // check if all devices have been removed + bool any_device_left=false; + for (Bitu dct=0;dct=pci_devices_installed) break; + if (pci_devices[dct]!=NULL) { + any_device_left=true; + break; + } + } + if (!any_device_left) Deinitialize(); + + Bitu last_active_device=PCI_MAX_PCIDEVICES; + for (Bitu dct=0;dct0) { + // register all devices that have been added before the PCI bus was instantiated + for (Bitu dct=0;dctRegisterPCIDevice(rqueued_devices[dct]); + } + num_rqueued_devices=0; + } + } + + ~PCI(){ + initialized=false; + pci_devices_installed=0; + num_rqueued_devices=0; + } + +}; + +static PCI* pci_interface=NULL; + + +PhysPt PCI_GetPModeInterface(void) { + if (pci_interface) { + return pci_interface->GetPModeCallbackPointer(); + } + return 0; +} + +bool PCI_IsInitialized() { + if (pci_interface) return pci_interface->IsInitialized(); + return false; +} + + +void PCI_ShutDown(Section* sec){ + delete pci_interface; + pci_interface=NULL; +} + +void PCI_Init(Section* sec) { + pci_interface = new PCI(sec); + sec->AddDestroyFunction(&PCI_ShutDown,false); +} + +#endif diff --git a/src/hardware/pci_devices.h b/src/hardware/pci_devices.h new file mode 100644 index 00000000..9a026807 --- /dev/null +++ b/src/hardware/pci_devices.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2002-2011 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. + */ + diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index cf3c6438..d3564c52 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -26,6 +26,7 @@ #include "inout.h" #include "pic.h" #include "hardware.h" +#include "pci_bus.h" #include "joystick.h" #include "mouse.h" #include "setup.h" @@ -354,8 +355,120 @@ static Bitu INT1A_Handler(void) { TandyDAC_Handler(reg_ah); break; case 0xb1: /* PCI Bios Calls */ - LOG(LOG_BIOS,LOG_ERROR)("INT1A:PCI bios call %2X",reg_al); + LOG(LOG_BIOS,LOG_WARN)("INT1A:PCI bios call %2X",reg_al); +#if defined(PCI_FUNCTIONALITY_ENABLED) + switch (reg_al) { + case 0x01: // installation check + if (PCI_IsInitialized()) { + reg_ah=0x00; + reg_al=0x01; // cfg space mechanism 1 supported + reg_bx=0x0210; // ver 2.10 + reg_cx=0x0000; // only one PCI bus + reg_edx=0x20494350; + reg_edi=PCI_GetPModeInterface(); + CALLBACK_SCF(false); + } else { + CALLBACK_SCF(true); + } + break; + case 0x02: { // find device + Bitu devnr=0; + Bitu count=0x100; + Bit32u devicetag=(reg_cx<<16)|reg_dx; + Bits found=-1; + for (Bitu i=0; i<=count; i++) { + IO_WriteD(0xcf8,0x80000000|(i<<8)); // query unique device/subdevice entries + if (IO_ReadD(0xcfc)==devicetag) { + if (devnr==reg_si) { + found=i; + break; + } else { + // device found, but not the SIth device + devnr++; + } + } + } + if (found>=0) { + reg_ah=0x00; + reg_bh=0x00; // bus 0 + reg_bl=(Bit8u)(found&0xff); + CALLBACK_SCF(false); + } else { + reg_ah=0x86; // device not found + CALLBACK_SCF(true); + } + } + break; + case 0x03: { // find device by class code + Bitu devnr=0; + Bitu count=0x100; + Bit32u classtag=reg_ecx&0xffffff; + Bits found=-1; + for (Bitu i=0; i<=count; i++) { + IO_WriteD(0xcf8,0x80000000|(i<<8)); // query unique device/subdevice entries + if (IO_ReadD(0xcfc)!=0xffffffff) { + IO_WriteD(0xcf8,0x80000000|(i<<8)|0x08); + if ((IO_ReadD(0xcfc)>>8)==classtag) { + if (devnr==reg_si) { + found=i; + break; + } else { + // device found, but not the SIth device + devnr++; + } + } + } + } + if (found>=0) { + reg_ah=0x00; + reg_bh=0x00; // bus 0 + reg_bl=(Bit8u)(found&0xff); + CALLBACK_SCF(false); + } else { + reg_ah=0x86; // device not found + CALLBACK_SCF(true); + } + } + break; + case 0x08: // read configuration byte + IO_WriteD(0xcf8,0x80000000|(reg_bx<<8)|(reg_di&0xfc)); + reg_cl=IO_ReadB(0xcfc+(reg_di&3)); + CALLBACK_SCF(false); + break; + case 0x09: // read configuration word + IO_WriteD(0xcf8,0x80000000|(reg_bx<<8)|(reg_di&0xfc)); + reg_cx=IO_ReadW(0xcfc+(reg_di&2)); + CALLBACK_SCF(false); + break; + case 0x0a: // read configuration dword + IO_WriteD(0xcf8,0x80000000|(reg_bx<<8)|(reg_di&0xfc)); + reg_ecx=IO_ReadD(0xcfc+(reg_di&3)); + CALLBACK_SCF(false); + break; + case 0x0b: // write configuration byte + IO_WriteD(0xcf8,0x80000000|(reg_bx<<8)|(reg_di&0xfc)); + IO_WriteB(0xcfc+(reg_di&3),reg_cl); + CALLBACK_SCF(false); + break; + case 0x0c: // write configuration word + IO_WriteD(0xcf8,0x80000000|(reg_bx<<8)|(reg_di&0xfc)); + IO_WriteW(0xcfc+(reg_di&2),reg_cx); + CALLBACK_SCF(false); + break; + case 0x0d: // write configuration dword + IO_WriteD(0xcf8,0x80000000|(reg_bx<<8)|(reg_di&0xfc)); + IO_WriteD(0xcfc+(reg_di&3),reg_ecx); + CALLBACK_SCF(false); + break; + default: + LOG(LOG_BIOS,LOG_ERROR)("INT1A:PCI BIOS: unknown function %x (%x %x %x)", + reg_ax,reg_bx,reg_cx,reg_dx); + CALLBACK_SCF(true); + break; + } +#else CALLBACK_SCF(true); +#endif break; default: LOG(LOG_BIOS,LOG_ERROR)("INT1A:Undefined call %2X",reg_ah); diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 5a36f2ef..596a464e 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -480,6 +480,9 @@ + + @@ -831,6 +834,9 @@ + + From 34f49734f383335cd0397b9e29f757f88f8f22bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 18 Jun 2011 14:02:53 +0000 Subject: [PATCH 3634/4131] keep strangeness out of this Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3724 --- visualc_net/dosbox.vcproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 596a464e..876bd306 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -835,7 +835,7 @@ RelativePath="..\include\paging.h"> + RelativePath="..\include\pci_bus.h"> From df67bd2afb292bece5514553cbe8cb63d2b46654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 19 Jun 2011 13:21:11 +0000 Subject: [PATCH 3635/4131] fix manual uninstall functions for callback/io-handler objects; cleanup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3725 --- src/cpu/callback.cpp | 43 +++++++++++++++++++------------------- src/hardware/iohandler.cpp | 22 ++++++++++--------- 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index c4ae982c..0c3f3c25 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -45,7 +45,7 @@ Bitu CALLBACK_Allocate(void) { for (Bitu i=1;(i0) + if (!CPU_CycleAutoAdjust && CPU_Cycles>0) CPU_Cycles=0; } @@ -108,24 +108,24 @@ void CALLBACK_RunRealInt(Bit8u intnum) { } void CALLBACK_SZF(bool val) { - Bit16u tempf = mem_readw(SegPhys(ss)+reg_sp+4); - if (val) tempf |= FLAG_ZF; - else tempf &= ~FLAG_ZF; - mem_writew(SegPhys(ss)+reg_sp+4,tempf); + Bit16u tempf = mem_readw(SegPhys(ss)+reg_sp+4); + if (val) tempf |= FLAG_ZF; + else tempf &= ~FLAG_ZF; + mem_writew(SegPhys(ss)+reg_sp+4,tempf); } void CALLBACK_SCF(bool val) { - Bit16u tempf = mem_readw(SegPhys(ss)+reg_sp+4); - if (val) tempf |= FLAG_CF; - else tempf &= ~FLAG_CF; - mem_writew(SegPhys(ss)+reg_sp+4,tempf); + Bit16u tempf = mem_readw(SegPhys(ss)+reg_sp+4); + if (val) tempf |= FLAG_CF; + else tempf &= ~FLAG_CF; + mem_writew(SegPhys(ss)+reg_sp+4,tempf); } void CALLBACK_SIF(bool val) { - Bit16u tempf = mem_readw(SegPhys(ss)+reg_sp+4); - if (val) tempf |= FLAG_IF; - else tempf &= ~FLAG_IF; - mem_writew(SegPhys(ss)+reg_sp+4,tempf); + Bit16u tempf = mem_readw(SegPhys(ss)+reg_sp+4); + if (val) tempf |= FLAG_IF; + else tempf &= ~FLAG_IF; + mem_writew(SegPhys(ss)+reg_sp+4,tempf); } void CALLBACK_SetDescription(Bitu nr, const char* descr) { @@ -142,7 +142,7 @@ const char* CALLBACK_GetDescription(Bitu nr) { } Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_cb=true) { - if (callback>=CB_MAX) + if (callback>=CB_MAX) return 0; switch (type) { case CB_RETN: @@ -471,7 +471,7 @@ void CALLBACK_HandlerObject::Uninstall(){ //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 + } else LOG(LOG_MISC,LOG_WARN)("Interrupt vector changed on %X %s",vectorhandler.interrupt,CALLBACK_GetDescription(m_callback)); } CALLBACK_RemoveSetup(m_callback); @@ -483,6 +483,7 @@ void CALLBACK_HandlerObject::Uninstall(){ if(CallBack_Description[m_callback]) delete [] CallBack_Description[m_callback]; CallBack_Description[m_callback] = 0; CALLBACK_DeAllocate(m_callback); + installed=false; } CALLBACK_HandlerObject::~CALLBACK_HandlerObject(){ @@ -495,7 +496,7 @@ void CALLBACK_HandlerObject::Install(CallBack_Handler handler,Bitu type,const ch m_type=SETUP; m_callback=CALLBACK_Allocate(); CALLBACK_Setup(m_callback,handler,type,description); - } else E_Exit("Allready installed"); + } else E_Exit("Callback handler object already installed"); } void CALLBACK_HandlerObject::Install(CallBack_Handler handler,Bitu type,PhysPt addr,const char* description){ if(!installed) { @@ -503,7 +504,7 @@ void CALLBACK_HandlerObject::Install(CallBack_Handler handler,Bitu type,PhysPt a m_type=SETUP; m_callback=CALLBACK_Allocate(); CALLBACK_Setup(m_callback,handler,type,addr,description); - } else E_Exit("Allready installed"); + } else E_Exit("Callback handler object already installed"); } void CALLBACK_HandlerObject::Allocate(CallBack_Handler handler,const char* description) { @@ -513,7 +514,7 @@ void CALLBACK_HandlerObject::Allocate(CallBack_Handler handler,const char* descr m_callback=CALLBACK_Allocate(); CALLBACK_SetDescription(m_callback,description); CallBack_Handlers[m_callback]=handler; - } else E_Exit("Allready installed"); + } else E_Exit("Callback handler object already installed"); } void CALLBACK_HandlerObject::Set_RealVec(Bit8u vec){ @@ -552,7 +553,7 @@ void CALLBACK_Init(Section* /*sec*/) { CALLBACK_Setup(call_default,&default_handler,CB_IRET,"default"); call_default2=CALLBACK_Allocate(); CALLBACK_Setup(call_default2,&default_handler,CB_IRET,"default"); - + /* Only setup default handler for first part of interrupt table */ for (Bit16u ct=0;ct<0x60;ct++) { real_writed(0,ct*4,CALLBACK_RealPointer(call_default)); diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 84cb21ea..80c7091d 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -44,7 +44,7 @@ static Bitu IO_ReadDefault(Bitu port,Bitu iolen) { io_readhandlers[0][port]=IO_ReadBlocked; return 0xff; case 2: - return + return (io_readhandlers[0][port+0](port+0,1) << 0) | (io_readhandlers[0][port+1](port+1,1) << 8); case 4: @@ -58,7 +58,7 @@ static Bitu IO_ReadDefault(Bitu port,Bitu iolen) { void IO_WriteDefault(Bitu port,Bitu val,Bitu iolen) { switch (iolen) { case 1: - LOG(LOG_IO,LOG_WARN)("Writing %02X to port %04X",val,port); + LOG(LOG_IO,LOG_WARN)("Writing %02X to port %04X",val,port); io_writehandlers[0][port]=IO_WriteBlocked; break; case 2: @@ -115,12 +115,13 @@ void IO_ReadHandleObject::Install(Bitu port,IO_ReadHandler * handler,Bitu mask,B m_mask=mask; m_range=range; IO_RegisterReadHandler(port,handler,mask,range); - } else E_Exit("IO_readHandler allready installed port %x",port); + } else E_Exit("IO_readHandler already installed port %x",port); } void IO_ReadHandleObject::Uninstall(){ if(!installed) return; IO_FreeReadHandler(m_port,m_mask,m_range); + installed=false; } IO_ReadHandleObject::~IO_ReadHandleObject(){ @@ -134,12 +135,13 @@ void IO_WriteHandleObject::Install(Bitu port,IO_WriteHandler * handler,Bitu mask m_mask=mask; m_range=range; IO_RegisterWriteHandler(port,handler,mask,range); - } else E_Exit("IO_writeHandler allready installed port %x",port); + } else E_Exit("IO_writeHandler already installed port %x",port); } void IO_WriteHandleObject::Uninstall() { if(!installed) return; IO_FreeWriteHandler(m_port,m_mask,m_range); + installed=false; } IO_WriteHandleObject::~IO_WriteHandleObject(){ @@ -164,7 +166,7 @@ static Bits IOFaultCore(void) { Bits ret=CPU_Core_Full_Run(); CPU_CycleLeft+=CPU_Cycles; if (ret<0) E_Exit("Got a dosbox close machine in IO-fault core?"); - if (ret) + if (ret) return ret; if (!iof_queue.used) E_Exit("IO-faul Core without IO-faul"); IOF_Entry * entry=&iof_queue.entries[iof_queue.used-1]; @@ -194,7 +196,7 @@ inline void IO_USEC_read_delay_old() { inline void IO_USEC_write_delay_old() { if(CPU_CycleMax > static_cast((IODELAY_WRITE_MICROS*1000.0))) { // this could be calculated whenever CPU_CycleMax changes - Bits delaycyc = static_cast((CPU_CycleMax/1000)*IODELAY_WRITE_MICROS); + Bits delaycyc = static_cast((CPU_CycleMax/1000)*IODELAY_WRITE_MICROS); if(CPU_Cycles > delaycyc) CPU_Cycles -= delaycyc; else CPU_Cycles = 0; } @@ -212,7 +214,7 @@ inline void IO_USEC_read_delay() { } inline void IO_USEC_write_delay() { - Bits delaycyc = CPU_CycleMax/IODELAY_WRITE_MICROSk; + Bits delaycyc = CPU_CycleMax/IODELAY_WRITE_MICROSk; if(GCC_UNLIKELY(CPU_Cycles < 3*delaycyc)) delaycyc=0; CPU_Cycles -= delaycyc; CPU_IODelayRemoved += delaycyc; @@ -413,7 +415,7 @@ Bitu IO_ReadB(Bitu port) { iof_queue.used--; retval = reg_al; - reg_dx = old_dx; + reg_dx = old_dx; memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); cpudecoder=old_cpudecoder; return retval; @@ -450,7 +452,7 @@ Bitu IO_ReadW(Bitu port) { iof_queue.used--; retval = reg_ax; - reg_dx = old_dx; + reg_dx = old_dx; memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); cpudecoder=old_cpudecoder; } @@ -486,7 +488,7 @@ Bitu IO_ReadD(Bitu port) { iof_queue.used--; retval = reg_eax; - reg_dx = old_dx; + reg_dx = old_dx; memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); cpudecoder=old_cpudecoder; } else { From cc5f9e2810fe9b6a99e5228b73b3df2650847d32 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 19 Jun 2011 16:27:28 +0000 Subject: [PATCH 3636/4131] Update comments on reboot-shutdown functionality Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3726 --- src/ints/bios.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index d3564c52..0d596f93 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1058,19 +1058,30 @@ public: callback[9].Set_RealVec(0x71); /* Reboot */ + // This handler is an exit for more than only reboots, since we + // don't handle these cases callback[10].Install(&Reboot_Handler,CB_IRET,"reboot"); + + // INT 18h: Enter BASIC + // Non-IBM BIOS would display "NO ROM BASIC" here callback[10].Set_RealVec(0x18); RealPt rptr = callback[10].Get_RealPointer(); + + // INT 19h: Boot function + // This is not a complete reboot as it happens after the POST + // We don't handle it, so use the reboot function as exit. RealSetVec(0x19,rptr); - // power on selftest routine location - phys_writeb(Real2Phys(BIOS_DEFAULT_RESET_LOCATION)+0,0xEA); // FARJMP - phys_writew(Real2Phys(BIOS_DEFAULT_RESET_LOCATION)+1,RealOff(rptr)); // offset - phys_writew(Real2Phys(BIOS_DEFAULT_RESET_LOCATION)+3,RealSeg(rptr)); // segment - // reset jump (directed to POST) + + // The farjump at the processor reset entry point (jumps to POST routine) phys_writeb(0xFFFF0,0xEA); // FARJMP phys_writew(0xFFFF1,RealOff(BIOS_DEFAULT_RESET_LOCATION)); // offset phys_writew(0xFFFF3,RealSeg(BIOS_DEFAULT_RESET_LOCATION)); // segment + // Compatible POST routine location: jump to the callback + phys_writeb(Real2Phys(BIOS_DEFAULT_RESET_LOCATION)+0,0xEA); // FARJMP + phys_writew(Real2Phys(BIOS_DEFAULT_RESET_LOCATION)+1,RealOff(rptr)); // offset + phys_writew(Real2Phys(BIOS_DEFAULT_RESET_LOCATION)+3,RealSeg(rptr)); // segment + /* Irq 2 */ Bitu call_irq2=CALLBACK_Allocate(); CALLBACK_Setup(call_irq2,NULL,CB_IRET_EOI_PIC1,Real2Phys(BIOS_DEFAULT_IRQ2_LOCATION),"irq 2 bios"); From 8abf23aa8d2f00554aabfccaed8c31dfb1611c35 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 20 Jun 2011 19:25:08 +0000 Subject: [PATCH 3637/4131] GUS pantable fix Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3727 --- src/hardware/gus.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 1ce1e3bd..fb0d6c0a 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -769,7 +769,7 @@ static void MakeTables(void) { vol16bit[i]=(Bit16s)out; out/=1.002709201; /* 0.0235 dB Steps */ } - pantable[0]=0; + pantable[0] = 4095 << RAMP_FRACT; for (i=1;i<16;i++) { pantable[i]=(Bit32u)(-128.0*(log((double)i/15.0)/log(2.0))*(double)(1 << RAMP_FRACT)); } From 6fc206193e5002901d8d422382a3f8beb16a16ba Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 24 Jun 2011 21:02:05 +0000 Subject: [PATCH 3638/4131] Allow command /Cdir Fix quoting so that command /c mount d "/tmp/a b" works This breaks command /c "dir", but this doesn't work on real DOS either. Let's hope everything still works. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3728 --- include/programs.h | 1 + src/misc/setup.cpp | 33 +++++++++++++++++++++++++++++++++ src/shell/shell.cpp | 2 +- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/include/programs.h b/include/programs.h index 1006ac83..8815fa04 100644 --- a/include/programs.h +++ b/include/programs.h @@ -50,6 +50,7 @@ public: 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 FindStringRemainBegin(char const * const name,std::string & value); bool GetStringRemain(std::string & value); int GetParameterFromList(const char* const params[], std::vector & output); void FillVector(std::vector & vector); diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 655182a3..25bd5a4e 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -955,6 +955,39 @@ bool CommandLine::FindStringRemain(char const * const name,std::string & value) return true; } +/* Only used for parsing command.com /C + * Allowing /C dir and /Cdir + * Restoring quotes back into the commands so command /C mount d "/tmp/a b" works as intended + */ +bool CommandLine::FindStringRemainBegin(char const * const name,std::string & value) { + cmd_it it;value=""; + if (!FindEntry(name,it)) { + size_t len = strlen(name); + for (it=cmds.begin();it!=cmds.end();it++) { + if (strncasecmp(name,(*it).c_str(),len)==0) { + std::string temp = ((*it).c_str() + len); + //Restore quotes for correct parsing in later stages + if(temp.find(" ") != std::string::npos) + value = std::string("\"") + temp + std::string("\""); + else + value = temp; + break; + } + } + if( it == cmds.end()) return false; + } + it++; + for (;it!=cmds.end();it++) { + value += " "; + std::string temp = (*it); + if(temp.find(" ") != std::string::npos) + value += std::string("\"") + temp + std::string("\""); + else + value += temp; + } + return true; +} + bool CommandLine::GetStringRemain(std::string & value) { if(!cmds.size()) return false; diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index b4384725..a7464a19 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -285,7 +285,7 @@ void DOS_Shell::RunInternal(void) void DOS_Shell::Run(void) { char input_line[CMD_MAXLINE] = {0}; std::string line; - if (cmd->FindStringRemain("/C",line)) { + if (cmd->FindStringRemainBegin("/C",line)) { strcpy(input_line,line.c_str()); char* sep = strpbrk(input_line,"\r\n"); //GTA installer if (sep) *sep = 0; From 2b0081cf596eff671fa62dd0ea0f88e392901613 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 16 Jul 2011 12:24:46 +0000 Subject: [PATCH 3639/4131] Increase number of floppies when using non-disk images as well. Maybe decrease the number on unmount in the future. Thanks ripsaw Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3729 --- include/bios_disk.h | 1 + src/dos/dos_programs.cpp | 1 + src/ints/bios_disk.cpp | 24 ++++++++++++++---------- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/include/bios_disk.h b/include/bios_disk.h index 95c3d345..ef4ad36f 100644 --- a/include/bios_disk.h +++ b/include/bios_disk.h @@ -69,6 +69,7 @@ public: }; void updateDPT(void); +void incrementFDD(void); #define MAX_HDD_IMAGES 2 diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 902ac3d6..1e8a02e0 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -324,6 +324,7 @@ public: label = drive; label += "_FLOPPY"; newdrive->dirCache.SetLabel(label.c_str(),iscdrom,true); } + if(type == "floppy") incrementFDD(); return; showusage: #if defined (WIN32) || defined(OS2) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 556b5743..a5514467 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -85,6 +85,19 @@ void updateDPT(void) { } } +void incrementFDD(void) { + Bit16u equipment=mem_readw(BIOS_CONFIGURATION); + if(equipment&1) { + Bitu numofdisks = (equipment>>6)&3; + numofdisks++; + if(numofdisks > 1) numofdisks=1;//max 2 floppies at the moment + equipment&=~0x00C0; + equipment|=(numofdisks<<6); + } else equipment|=1; + mem_writew(BIOS_CONFIGURATION,equipment); + CMOS_SetRegister(0x14, (Bit8u)(equipment&0xff)); +} + void swapInDisks(void) { bool allNull = true; Bits diskcount = 0; @@ -219,16 +232,7 @@ imageDisk::imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHard if(!founddisk) { active = false; } else { - Bit16u equipment=mem_readw(BIOS_CONFIGURATION); - if(equipment&1) { - Bitu numofdisks = (equipment>>6)&3; - numofdisks++; - if(numofdisks > 1) numofdisks=1;//max 2 floppies at the moment - equipment&=~0x00C0; - equipment|=(numofdisks<<6); - } else equipment|=1; - mem_writew(BIOS_CONFIGURATION,equipment); - CMOS_SetRegister(0x14, (Bit8u)(equipment&0xff)); + incrementFDD(); } } } From 21292f48b58beaef090a79348e2acc6800488294 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 16 Jul 2011 12:26:37 +0000 Subject: [PATCH 3640/4131] Handle floppies differently in ioctl calls. Makes windows 3.x happy. Thanks ripsaw Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3730 --- src/dos/dos_ioctl.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index ac48457c..2eeddb0f 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -40,7 +40,7 @@ bool DOS_IOCTL(void) { } else if (reg_al<0x12) { /* those use a diskdrive except 0x0b */ if (reg_al!=0x0b) { drive=reg_bl;if (!drive) drive = DOS_GetDefaultDrive();else drive--; - if( !(( drive < DOS_DRIVES ) && Drives[drive]) ) { + if( (drive >= 2) && !(( drive < DOS_DRIVES ) && Drives[drive]) ) { DOS_SetError(DOSERR_INVALID_DRIVE); return false; } @@ -133,7 +133,7 @@ bool DOS_IOCTL(void) { } return true; case 0x09: /* Check if block device remote */ - if (Drives[drive]->isRemote()) { + if ((drive >= 2) && Drives[drive]->isRemote()) { reg_dx=0x1000; // device is remote // undocumented bits always clear } else { @@ -151,7 +151,7 @@ bool DOS_IOCTL(void) { return true; case 0x0D: /* Generic block device request */ { - if (Drives[drive]->isRemovable()) { + if ((drive < 2) || Drives[drive]->isRemovable()) { DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); return false; } @@ -202,11 +202,14 @@ bool DOS_IOCTL(void) { return true; } case 0x0E: /* Get Logical Drive Map */ - if (Drives[drive]->isRemovable()) { + if (drive < 2) { + if (Drives[drive]) reg_al=drive+1; + else reg_al=1; + } else if (Drives[drive]->isRemovable()) { DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); return false; - } - reg_al = 0; /* Only 1 logical drive assigned */ + } else reg_al=0; /* Only 1 logical drive assigned */ + reg_ah=0x07; return true; default: LOG(LOG_DOSMISC,LOG_ERROR)("DOS:IOCTL Call %2X unhandled",reg_al); From 95de46cc9577ee27432ed49f52fde735f1fb3b5f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 20 Jul 2011 20:50:32 +0000 Subject: [PATCH 3641/4131] Let's not copy extended memory when we finish waiting. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3731 --- src/ints/bios.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 0d596f93..8fc37c40 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -827,6 +827,7 @@ static Bitu INT15_Handler(void) { CALLBACK_Idle(); } CALLBACK_SCF(false); + break; } case 0x87: /* Copy extended memory */ { From 7318abd114a256c964aa3158a88a73a93c976cdb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 21 Jul 2011 13:57:59 +0000 Subject: [PATCH 3642/4131] Add patch 3324624 from ano. Some fixes with respect to mixing normal and extended fcbs. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3732 --- src/dos/dos_files.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 618e6e65..b9c8ae4e 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -924,7 +924,9 @@ bool DOS_FCBCreate(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); char shortname[DOS_FCBNAME];Bit16u handle; fcb.GetName(shortname); - if (!DOS_CreateFile(shortname,DOS_ATTR_ARCHIVE,&handle)) return false; + Bit8u attr = DOS_ATTR_ARCHIVE; + fcb.GetAttr(attr); + if (!DOS_CreateFile(shortname,attr,&handle)) return false; fcb.FileOpen((Bit8u)handle); return true; } @@ -1164,10 +1166,11 @@ bool DOS_FCBDeleteFile(Bit16u seg,Bit16u offset){ * stored. This can not be the tempdta as that one is used by fcbfindfirst */ RealPt old_dta=dos.dta();dos.dta(dos.tables.tempdta_fcbdelete); - DOS_FCB fcb(RealSeg(dos.dta()),RealOff(dos.dta())); + RealPt new_dta=dos.dta(); bool nextfile = false; bool return_value = false; nextfile = DOS_FCBFindFirst(seg,offset); + DOS_FCB fcb(RealSeg(new_dta),RealOff(new_dta)); while(nextfile) { char shortname[DOS_FCBNAME] = { 0 }; fcb.GetName(shortname); From b29e06c00624660e6a297d9516e360b9aeec3c3e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 21 Jul 2011 14:26:16 +0000 Subject: [PATCH 3643/4131] Add patch 3161987 from Jason C. Penney: Add (optional) SoundFont support to midi_coreaudio synth. Added some extra info to dosbox.conf to describe this Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3733 --- src/dosbox.cpp | 1 + src/gui/midi_coreaudio.h | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 79fb5db8..40be085c 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -491,6 +491,7 @@ void DOSBOX_Init(void) { Pstring = secprop->Add_string("midiconfig",Property::Changeable::WhenIdle,""); Pstring->Set_help("Special configuration options for the device driver. This is usually the id of the device you want to use.\n" + " or in the case of coreaudio, you can specify a soundfont here.\n" " When using a Roland MT-32 rev. 0 as midi output device, some games may require a delay in order to prevent 'buffer overflow' issues.\n" " In that case, add 'delaysysex', for example: midiconfig=2 delaysysex\n" " See the README/Manual for more details."); diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index 0ffc60f1..ee6c752f 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -32,6 +32,7 @@ class MidiHandler_coreaudio : public MidiHandler { private: AUGraph m_auGraph; AudioUnit m_synth; + const char *soundfont; public: MidiHandler_coreaudio() : m_auGraph(0), m_synth(0) {} const char * GetName(void) { return "coreaudio"; } @@ -71,6 +72,22 @@ public: // Get the music device from the graph. RequireNoErr(AUGraphGetNodeInfo(m_auGraph, synthNode, NULL, NULL, NULL, &m_synth)); + // Optionally load a soundfont + if (conf && conf[0]) { + soundfont = conf; + FSRef soundfontRef; + RequireNoErr(FSPathMakeRef((const UInt8*)soundfont, &soundfontRef, NULL)); + RequireNoErr(AudioUnitSetProperty( + m_synth, + kMusicDeviceProperty_SoundBankFSRef, + kAudioUnitScope_Global, + 0, + &soundfontRef, + sizeof(soundfontRef) + )); + LOG_MSG("MIDI:coreaudio: loaded soundfont: %s",soundfont); + } + // Finally: Start the graph! RequireNoErr(AUGraphStart(m_auGraph)); From 8d7b65e0e01e4cf00aa192e8d9a4828f806ccdc9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 22 Jul 2011 17:53:05 +0000 Subject: [PATCH 3644/4131] Some tiny protection against weird values Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3734 --- src/dos/dos_files.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index b9c8ae4e..4a3b26c8 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -926,6 +926,7 @@ bool DOS_FCBCreate(Bit16u seg,Bit16u offset) { fcb.GetName(shortname); Bit8u attr = DOS_ATTR_ARCHIVE; fcb.GetAttr(attr); + if (!attr) attr = DOS_ATTR_ARCHIVE; //Better safe than sorry if (!DOS_CreateFile(shortname,attr,&handle)) return false; fcb.FileOpen((Bit8u)handle); return true; From 57c2a4221087e78bbe2e2df556e005124876143b Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sat, 23 Jul 2011 19:02:01 +0000 Subject: [PATCH 3645/4131] - Fix for Scuba Venture (PCJR booter) - Added comments for PCJR and Tandy CRT/Processor page register - Add documented CRTC 3D0/1 access for PCJR Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3735 --- src/hardware/vga_memory.cpp | 7 +++--- src/hardware/vga_other.cpp | 50 ++++++++++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 9a3167ae..ecb2f5cd 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -700,6 +700,7 @@ public: // |PFLAG_NOCODE; } HostPt GetHostReadPt(Bitu phys_page) { + // Odd banks are limited to 16kB and repeated if (vga.tandy.mem_bank & 1) phys_page&=0x03; else @@ -719,9 +720,9 @@ public: } HostPt GetHostReadPt(Bitu phys_page) { phys_page-=0xb8; - //test for a unaliged bank, then replicate 2x16kb - if (vga.tandy.mem_bank & 1) - phys_page&=0x03; + // The 16kB map area is repeated in the 32kB range + // On CGA CPU A14 is not decoded so it repeats there too + phys_page&=0x03; return vga.tandy.mem_base + (phys_page * 4096); } HostPt GetHostWritePt(Bitu phys_page) { diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 61f92be4..51b98ed3 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -83,7 +83,9 @@ static void write_crtc_data_other(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { vga.draw.cursor.eline = (Bit8u)(val&0x1f); break; case 0x0C: /* Start Address High Register */ - vga.config.display_start=(vga.config.display_start & 0x00FF) | (val << 8); + // Bit 12 (depending on video mode) and 13 are actually masked too, + // but so far no need to implement it. + vga.config.display_start=(vga.config.display_start & 0x00FF) | ((val&0x3F) << 8); break; case 0x0D: /* Start Address Low Register */ vga.config.display_start=(vga.config.display_start & 0xFF00) | val; @@ -491,10 +493,18 @@ static void write_tandy(Bitu port,Bitu val,Bitu /*iolen*/) { write_tandy_reg((Bit8u)val); break; case 0x3df: + // CRT/processor page register + // See the comments on the PCJr version of this register. + // A difference to it is: + // Bit 3-5: Processor page CPU_PG + // The remapped range is 32kB instead of 16. Therefore CPU_PG bit 0 + // appears to be ORed with CPU A14 (to preserve some sort of + // backwards compatibility?), resulting in odd pages being mapped + // as 2x16kB. Implemeted in vga_memory.cpp Tandy handler. + vga.tandy.line_mask = (Bit8u)(val >> 6); vga.tandy.draw_bank = val & ((vga.tandy.line_mask&2) ? 0x6 : 0x7); - if(vga.tandy.line_mask==3) vga.tandy.draw_bank &= ~1; // LSB unused in 32k modes - vga.tandy.mem_bank = (val >> 3) & ((vga.tandy.line_mask&2) ? 0x6 : 0x7); + vga.tandy.mem_bank = (val >> 3) & 7; TandyCheckLineMask(); VGA_SetupHandlers(); break; @@ -514,9 +524,38 @@ static void write_pcjr(Bitu port,Bitu val,Bitu /*iolen*/) { vga.tandy.pcjr_flipflop=!vga.tandy.pcjr_flipflop; break; case 0x3df: + // CRT/processor page register + + // Bit 0-2: CRT page PG0-2 + // In one- and two bank modes, bit 0-2 select the 16kB memory + // area of system RAM that is displayed on the screen. + // In 4-banked modes, bit 1-2 select the 32kB memory area. + // Bit 2 only has effect when the PCJR upgrade to 128k is installed. + + // Bit 3-5: Processor page CPU_PG + // Selects the 16kB area of system RAM that is mapped to + // the B8000h IBM PC video memory window. Since A14-A16 of the + // processor are unconditionally replaced with these bits when + // B8000h is accessed, the 16kB area is mapped to the 32kB + // range twice in a row. (Scuba Venture writes across the boundary) + + // Bit 6-7: Video Address mode + // 0: CRTC addresses A0-12 directly, accessing 8k characters + // (+8k attributes). Used in text modes (one bank). + // PG0-2 in effect. 16k range. + // 1: CRTC A12 is replaced with CRTC RA0 (see max_scanline). + // This results in the even/odd scanline two bank system. + // PG0-2 in effect. 16k range. + // 2: Documented as unused. CRTC addresses A0-12, PG0 is replaced + // with RA1. Looks like nonsense. + // PG1-2 in effect. 32k range which cannot be used completely. + // 3: CRTC A12 is replaced with CRTC RA0, PG0 is replaced with + // CRTC RA1. This results in the 4-bank mode. + // PG1-2 in effect. 32k range. + vga.tandy.line_mask = (Bit8u)(val >> 6); vga.tandy.draw_bank = val & ((vga.tandy.line_mask&2) ? 0x6 : 0x7); - vga.tandy.mem_bank = (val >> 3) & ((vga.tandy.line_mask&2) ? 0x6 : 0x7); + vga.tandy.mem_bank = (val >> 3) & 7; vga.tandy.draw_base = &MemBase[vga.tandy.draw_bank * 16 * 1024]; vga.tandy.mem_base = &MemBase[vga.tandy.mem_bank * 16 * 1024]; TandyCheckLineMask(); @@ -674,6 +713,9 @@ void VGA_SetupOther(void) { write_pcjr( 0x3df, 0x7 | (0x7 << 3), 0 ); IO_RegisterWriteHandler(0x3da,write_pcjr,IO_MB); IO_RegisterWriteHandler(0x3df,write_pcjr,IO_MB); + // additional CRTC access documented + IO_RegisterWriteHandler(0x3d0,write_crtc_index_other,IO_MB); + IO_RegisterWriteHandler(0x3d1,write_crtc_data_other,IO_MB); } if (machine==MCH_HERC) { Bitu base=0x3b0; From 965fccbe819932e8245685e43c30f92f4f4dd1f2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 23 Jul 2011 20:23:17 +0000 Subject: [PATCH 3646/4131] Rewrite mount without arguments to display volume label as well. Some refactoring of the code. Add mount -z X, where X is the new virtual drive for the Wine Team. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3736 --- src/dos/dos_programs.cpp | 95 ++++++++++++++++++++++++++++++++++------ 1 file changed, 81 insertions(+), 14 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 1e8a02e0..e59c908a 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -48,27 +48,55 @@ Bitu DEBUG_EnableDebugger(void); #endif void MSCDEX_SetCDInterface(int intNr, int forceCD); - +static Bitu ZDRIVE_NUM = 25; class MOUNT : public Program { public: - void Run(void) - { + void ListMounts(void) { + char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr; + /* Command uses dta so set it to our internal dta */ + RealPt save_dta = dos.dta(); + dos.dta(dos.tables.tempdta); + DOS_DTA dta(dos.dta()); + + WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_1")); + WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_FORMAT"),"Drive","Type","Label"); + for(int p = 0;p < 8;p++) WriteOut("----------"); + + for (int d = 0;d < DOS_DRIVES;d++) { + if (!Drives[d]) continue; + + char root[4] = {'A'+d,':','\\',0}; + bool ret = DOS_FindFirst(root,DOS_ATTR_VOLUME); + if (ret) { + dta.GetResult(name,size,date,time,attr); + DOS_FindNext(); //Mark entry as invalid + } else name[0] = 0; + + /* Change 8.3 to 11.0 */ + char* dot = strchr(name,'.'); + if(dot && (dot - name == 8) ) { + name[8] = name[9];name[9] = name[10];name[10] = name[11];name[11] = 0; + } + + root[1] = 0; //This way, the format string can be reused. + WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_FORMAT"),root, Drives[d]->GetInfo(),name); + } + dos.dta(save_dta); + } + + void Run(void) { DOS_Drive * newdrive;char drive; std::string label; std::string umount; + std::string newz; //Hack To allow long commandlines ChangeToLongCmd(); /* Parse the command line */ /* if the command line is empty show current mounts */ if (!cmd->GetCount()) { - WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_1")); - for (int d=0;dGetInfo()); - } - } + ListMounts(); return; } @@ -83,12 +111,12 @@ public: if (cmd->FindString("-u",umount,false)) { umount[0] = toupper(umount[0]); int i_drive = umount[0]-'A'; - if(i_drive < DOS_DRIVES && i_drive >= 0 && Drives[i_drive]) { + if (i_drive < DOS_DRIVES && i_drive >= 0 && Drives[i_drive]) { switch (DriveManager::UnmountDrive(i_drive)) { case 0: Drives[i_drive] = 0; if(i_drive == DOS_GetDefaultDrive()) - DOS_SetDrive(toupper('Z') - 'A'); + DOS_SetDrive(ZDRIVE_NUM); WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCESS"),umount[0]); break; case 1: @@ -103,8 +131,46 @@ public: } return; } - - // Show list of cdroms + + /* Check for moving Z: */ + /* Only allowing moving it once. It is merely a convenience added for the wine team */ + if (ZDRIVE_NUM == 25 && cmd->FindString("-z", newz,false)) { + newz[0] = toupper(newz[0]); + int i_newz = newz[0] - 'A'; + if (i_newz >= 0 && i_newz < DOS_DRIVES-1 && !Drives[i_newz]) { + ZDRIVE_NUM = i_newz; + /* remap drives */ + Drives[i_newz] = Drives[25]; + Drives[25] = 0; + DOS_Shell *fs = static_cast(first_shell); //dynamic ? + /* Update environment */ + std::string line = ""; + char ppp[2] = {newz[0],0}; + std::string tempenv = ppp; tempenv += ":\\"; + if (fs->GetEnvStr("PATH",line)){ + std::string::size_type idx = line.find('='); + std::string value = line.substr(idx +1 , std::string::npos); + while ( (idx = value.find("Z:\\")) != std::string::npos || + (idx = value.find("z:\\")) != std::string::npos ) + value.replace(idx,3,tempenv); + line = value; + } + if (!line.size()) line = tempenv; + fs->SetEnv("PATH",line.c_str()); + tempenv += "COMMAND.COM"; + fs->SetEnv("COMSPEC",tempenv.c_str()); + + /* Update batch file if running from Z: (very likely: autoexec) */ + if(fs->bf) { + std::string &name = fs->bf->filename; + if(name.length() >2 && name[0] == 'Z' && name[1] == ':') name[0] = newz[0]; + } + /* Change the active drive */ + if (DOS_GetDefaultDrive() == 25) DOS_SetDrive(i_newz); + } + return; + } + /* Show list of cdroms */ if (cmd->FindExist("-cd",false)) { int num = SDL_CDNumDrives(); WriteOut(MSG_Get("PROGRAM_MOUNT_CDROMS_FOUND"),num); @@ -1353,8 +1419,9 @@ void DOS_SetupPrograms(void) { /*Add Messages */ MSG_Add("PROGRAM_MOUNT_CDROMS_FOUND","CDROMs found: %d\n"); + MSG_Add("PROGRAM_MOUNT_STATUS_FORMAT","%-5s %-58s %-12s\n"); MSG_Add("PROGRAM_MOUNT_STATUS_2","Drive %c is mounted as %s\n"); - MSG_Add("PROGRAM_MOUNT_STATUS_1","Current mounted drives are:\n"); + MSG_Add("PROGRAM_MOUNT_STATUS_1","The currently mounted drives are:\n"); MSG_Add("PROGRAM_MOUNT_ERROR_1","Directory %s doesn't exist.\n"); MSG_Add("PROGRAM_MOUNT_ERROR_2","%s isn't a directory\n"); MSG_Add("PROGRAM_MOUNT_ILL_TYPE","Illegal type %s\n"); From 361da0de98b40e2fc793bec0e5561d01da8640f2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 29 Jul 2011 19:14:33 +0000 Subject: [PATCH 3647/4131] Xor numlock and shift for numpad. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3737 --- src/ints/bios_keyboard.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index cc2dc5fe..705702e0 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -382,7 +382,7 @@ static Bitu IRQ1_Handler(void) { add_key(scan_to_scanascii[scancode].normal+0x5000); } else if (flags1 &0x04) { add_key((scan_to_scanascii[scancode].control&0xff00)|0xe0); - } else if( ((flags1 &0x3) != 0) || ((flags1 &0x20) != 0) ) { + } else if( ((flags1 &0x3) != 0) || ((flags1 &0x20) != 0) ) { //Due to |0xe0 results are identical. add_key((scan_to_scanascii[scancode].shift&0xff00)|0xe0); } else add_key((scan_to_scanascii[scancode].normal&0xff00)|0xe0); break; @@ -393,7 +393,7 @@ static Bitu IRQ1_Handler(void) { mem_writeb(BIOS_KEYBOARD_TOKEN,token); } else if (flags1 &0x04) { add_key(scan_to_scanascii[scancode].control); - } else if( ((flags1 &0x3) != 0) || ((flags1 &0x20) != 0) ) { + } else if( ((flags1 &0x3) != 0) ^ ((flags1 &0x20) != 0) ) { //Xor shift and numlock (both means off) add_key(scan_to_scanascii[scancode].shift); } else add_key(scan_to_scanascii[scancode].normal); break; From d3136d14de0a8aa32db7ea2db016727ba8728689 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sat, 30 Jul 2011 15:36:56 +0000 Subject: [PATCH 3648/4131] - fix the socket inheritance feature - usedtr will now, if the connection was lost in between, attempt to connect again if there is a rising edge on DTR - code improvements - handling of some unused handshake lines was changed a bit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3738 --- src/hardware/serialport/nullmodem.cpp | 333 +++++++++++++------------- src/hardware/serialport/nullmodem.h | 26 +- 2 files changed, 183 insertions(+), 176 deletions(-) diff --git a/src/hardware/serialport/nullmodem.cpp b/src/hardware/serialport/nullmodem.cpp index b107ac9e..4f91f9dd 100644 --- a/src/hardware/serialport/nullmodem.cpp +++ b/src/hardware/serialport/nullmodem.cpp @@ -52,87 +52,59 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) { // 1) when it is client connect to the server not immediately but // as soon as a modem-aware application is started (DTR is switched on). // 2) only receive data when DTR is on. - if(getBituSubstring("usedtr:", &bool_temp, cmd)) { - if(bool_temp==1) { + if (getBituSubstring("usedtr:", &bool_temp, cmd)) { + if (bool_temp==1) { dtrrespect=true; transparent=true; + DTR_delta=false; // connect immediately when DTR is already 1 } } // transparent: don't add additional handshake control. - if(getBituSubstring("transparent:", &bool_temp, cmd)) { - if(bool_temp==1) transparent=true; + if (getBituSubstring("transparent:", &bool_temp, cmd)) { + if (bool_temp==1) transparent=true; else transparent=false; } // telnet: interpret telnet commands. - if(getBituSubstring("telnet:", &bool_temp, cmd)) { - if(bool_temp==1) { + if (getBituSubstring("telnet:", &bool_temp, cmd)) { + if (bool_temp==1) { transparent=true; telnet=true; } } // rxdelay: How many milliseconds to wait before causing an // overflow when the application is unresponsive. - if(getBituSubstring("rxdelay:", &rx_retry_max, cmd)) { - if(!(rx_retry_max<=10000)) { + if (getBituSubstring("rxdelay:", &rx_retry_max, cmd)) { + if (!(rx_retry_max<=10000)) { rx_retry_max=50; } } // txdelay: How many milliseconds to wait before sending data. // This reduces network overhead quite a lot. - if(getBituSubstring("txdelay:", &tx_gather, cmd)) { - if(!(tx_gather<=500)) { + if (getBituSubstring("txdelay:", &tx_gather, cmd)) { + if (!(tx_gather<=500)) { tx_gather=12; } } // port is for both server and client - if(getBituSubstring("port:", &temptcpport, cmd)) { - if(!(temptcpport>0&&temptcpport<65536)) { + if (getBituSubstring("port:", &temptcpport, cmd)) { + if (!(temptcpport>0&&temptcpport<65536)) { temptcpport=23; } } - // socket inheritance - if(getBituSubstring("inhsocket:", &bool_temp, cmd)) { + // socket inheritance (client-alike) + if (getBituSubstring("inhsocket:", &bool_temp, cmd)) { #ifdef NATIVESOCKETS - if(Netwrapper_GetCapabilities()&NETWRAPPER_TCP_NATIVESOCKET) { - if(bool_temp==1) { + if (Netwrapper_GetCapabilities()&NETWRAPPER_TCP_NATIVESOCKET) { + if (bool_temp==1) { int sock; if (control->cmdline->FindInt("-socket",sock,true)) { dtrrespect=false; transparent=true; - // custom connect - Bit8u peernamebuf[16]; - LOG_MSG("inheritance port: %d",sock); - clientsocket = new TCPClientSocket(sock); - if(!clientsocket->isopen) { - LOG_MSG("Serial%d: Connection failed.",COMNUMBER); -#if SERIAL_DEBUG - log_ser(dbg_aux,"Nullmodem: Connection failed."); -#endif - delete clientsocket; - clientsocket=0; + LOG_MSG("Inheritance socket handle: %d",sock); + if (!ClientConnect(new TCPClientSocket(sock))) return; - } - clientsocket->SetSendBufferSize(256); - clientsocket->GetRemoteAddressString(peernamebuf); - // transmit the line status - if(!transparent) setRTSDTR(getRTS(), getDTR()); - - LOG_MSG("Serial%d: Connected to %s",COMNUMBER,peernamebuf); -#if SERIAL_DEBUG - log_ser(dbg_aux,"Nullmodem: Connected to %s",peernamebuf); -#endif - setEvent(SERIAL_POLLING_EVENT, 1); - - CSerial::Init_Registers (); - InstallationSuccessful = true; - - setCTS(true); - setDSR(true); - setRI (false); - setCD (true); - return; } else { - LOG_MSG("Serial%d: -socket start parameter missing.",COMNUMBER); + LOG_MSG("Serial%d: -socket parameter missing.",COMNUMBER); return; } } @@ -144,47 +116,44 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) { #else LOG_MSG("Serial%d: socket inheritance not available.", COMNUMBER); #endif - } - std::string tmpstring; - if(cmd->FindStringBegin("server:",tmpstring,false)) { - // we are a client - const char* hostnamechar=tmpstring.c_str(); - size_t hostlen=strlen(hostnamechar)+1; - if(hostlen>sizeof(hostnamebuffer)) { - hostlen=sizeof(hostnamebuffer); - hostnamebuffer[sizeof(hostnamebuffer)-1]=0; - } - memcpy(hostnamebuffer,hostnamechar,hostlen); - clientport=(Bit16u)temptcpport; - if(dtrrespect) { - // we connect as soon as DTR is switched on - setEvent(SERIAL_NULLMODEM_DTR_EVENT, 50); - LOG_MSG("Serial%d: Waiting for DTR...",COMNUMBER); - } else ClientConnect(); } else { - // we are a server - serverport = (Bit16u)temptcpport; - serversocket = new TCPServerSocket(serverport); - if(!serversocket->isopen) return; - LOG_MSG("Serial%d: Nullmodem server waiting for connection on port %d...", - COMNUMBER,serverport); - setEvent(SERIAL_SERVER_POLLING_EVENT, 50); + // normal server/client + std::string tmpstring; + if (cmd->FindStringBegin("server:",tmpstring,false)) { + // we are a client + const char* hostnamechar=tmpstring.c_str(); + size_t hostlen=strlen(hostnamechar)+1; + if (hostlen>sizeof(hostnamebuffer)) { + hostlen=sizeof(hostnamebuffer); + hostnamebuffer[sizeof(hostnamebuffer)-1]=0; + } + memcpy(hostnamebuffer,hostnamechar,hostlen); + clientport=(Bit16u)temptcpport; + if (dtrrespect) { + // we connect as soon as DTR is switched on + setEvent(SERIAL_NULLMODEM_DTR_EVENT, 50); + LOG_MSG("Serial%d: Waiting for DTR...",COMNUMBER); + } else if (!ClientConnect( + new TCPClientSocket((char*)hostnamebuffer,(Bit16u)clientport))) + return; + } else { + // we are a server + serverport = (Bit16u)temptcpport; + if (!ServerListen()) return; + } } - - // .... - - CSerial::Init_Registers (); + CSerial::Init_Registers(); InstallationSuccessful = true; setCTS(dtrrespect||transparent); setDSR(dtrrespect||transparent); - setRI (false); - setCD (dtrrespect); + setRI(false); + setCD(clientsocket > 0); // CD on if connection established } -CNullModem::~CNullModem () { - if(serversocket) delete serversocket; - if(clientsocket) delete clientsocket; +CNullModem::~CNullModem() { + if (serversocket) delete serversocket; + if (clientsocket) delete clientsocket; // remove events for(Bit16u i = SERIAL_BASE_EVENT_COUNT+1; i <= SERIAL_NULLMODEM_EVENT_COUNT; i++) { @@ -193,9 +162,8 @@ CNullModem::~CNullModem () { } void CNullModem::WriteChar(Bit8u data) { - - if(clientsocket)clientsocket->SendByteBuffered(data); - if(!tx_block) { + if (clientsocket)clientsocket->SendByteBuffered(data); + if (!tx_block) { //LOG_MSG("setevreduct"); setEvent(SERIAL_TX_REDUCTION, (float)tx_gather); tx_block=true; @@ -203,37 +171,75 @@ void CNullModem::WriteChar(Bit8u data) { } Bits CNullModem::readChar() { - Bits rxchar = clientsocket->GetcharNonBlock(); - if(telnet && rxchar>=0) return TelnetEmulation((Bit8u)rxchar); - else if(rxchar==0xff && !transparent) {// escape char + if (telnet && rxchar>=0) return TelnetEmulation((Bit8u)rxchar); + else if (rxchar==0xff && !transparent) {// escape char // get the next char Bits rxchar = clientsocket->GetcharNonBlock(); - if(rxchar==0xff) return rxchar; // 0xff 0xff -> 0xff was meant + if (rxchar==0xff) return rxchar; // 0xff 0xff -> 0xff was meant rxchar&0x1? setCTS(true) : setCTS(false); rxchar&0x2? setDSR(true) : setDSR(false); - if(rxchar&0x4) receiveByteEx(0x0,0x10); + if (rxchar&0x4) receiveByteEx(0x0,0x10); return -1; // no "payload" received } else return rxchar; } -void CNullModem::ClientConnect(){ +bool CNullModem::ClientConnect(TCPClientSocket* newsocket) { Bit8u peernamebuf[16]; - clientsocket = new TCPClientSocket((char*)hostnamebuffer, - (Bit16u)clientport); - if(!clientsocket->isopen) { - LOG_MSG("Serial%d: Connection failed.",idnumber+1); + clientsocket = newsocket; + + if (!clientsocket->isopen) { + LOG_MSG("Serial%d: Connection failed.",COMNUMBER); delete clientsocket; clientsocket=0; - return; + setCD(false); + return false; } clientsocket->SetSendBufferSize(256); clientsocket->GetRemoteAddressString(peernamebuf); // transmit the line status - if(!transparent) setRTSDTR(getRTS(), getDTR()); + if (!transparent) setRTSDTR(getRTS(), getDTR()); rx_state=N_RX_IDLE; - LOG_MSG("Serial%d: Connected to %s",idnumber+1,peernamebuf); + LOG_MSG("Serial%d: Connected to %s",COMNUMBER,peernamebuf); setEvent(SERIAL_POLLING_EVENT, 1); + setCD(true); + return true; +} + +bool CNullModem::ServerListen() { + // Start the server listen port. + serversocket = new TCPServerSocket(serverport); + if (!serversocket->isopen) return false; + LOG_MSG("Serial%d: Nullmodem server waiting for connection on port %d...", + COMNUMBER,serverport); + setEvent(SERIAL_SERVER_POLLING_EVENT, 50); + setCD(false); + return true; +} + +bool CNullModem::ServerConnect() { + // check if a connection is available. + clientsocket=serversocket->Accept(); + if (!clientsocket) return false; + + Bit8u peeripbuf[16]; + clientsocket->GetRemoteAddressString(peeripbuf); + LOG_MSG("Serial%d: A client (%s) has connected.",COMNUMBER,peeripbuf); +#if SERIAL_DEBUG + log_ser(dbg_aux,"Nullmodem: A client (%s) has connected.", peeripbuf); +#endif + clientsocket->SetSendBufferSize(256); + rx_state=N_RX_IDLE; + setEvent(SERIAL_POLLING_EVENT, 1); + + // we don't accept further connections + delete serversocket; + serversocket=0; + + // transmit the line status + setRTSDTR(getRTS(), getDTR()); + if (transparent) setCD(true); + return true; } void CNullModem::Disconnect() { @@ -245,11 +251,16 @@ void CNullModem::Disconnect() { clientsocket=0; setDSR(false); setCTS(false); - if(serverport) { + setCD(false); + + if (serverport) { serversocket = new TCPServerSocket(serverport); - if(serversocket->isopen) + if (serversocket->isopen) setEvent(SERIAL_SERVER_POLLING_EVENT, 50); else delete serversocket; + } else if (dtrrespect) { + setEvent(SERIAL_NULLMODEM_DTR_EVENT,50); + DTR_delta = getDTR(); // try to reconnect the next time DTR is set } } @@ -264,8 +275,8 @@ void CNullModem::handleUpperEvent(Bit16u type) { updateMSR(); switch(rx_state) { case N_RX_IDLE: - if(CanReceiveByte()) { - if(doReceive()) { + if (CanReceiveByte()) { + if (doReceive()) { // a byte was received rx_state=N_RX_WAIT; setEvent(SERIAL_RX_EVENT, bytetime*0.9f); @@ -281,13 +292,13 @@ void CNullModem::handleUpperEvent(Bit16u type) { break; case N_RX_BLOCKED: // one timeout tick - if(!CanReceiveByte()) { + if (!CanReceiveByte()) { rx_retry++; - if(rx_retry>=rx_retry_max) { + if (rx_retry>=rx_retry_max) { // it has timed out: rx_retry=0; removeEvent(SERIAL_RX_EVENT); - if(doReceive()) { + if (doReceive()) { // read away everything while(doReceive()); rx_state=N_RX_WAIT; @@ -304,7 +315,7 @@ void CNullModem::handleUpperEvent(Bit16u type) { // good: we can receive again removeEvent(SERIAL_RX_EVENT); rx_retry=0; - if(doReceive()) { + if (doReceive()) { rx_state=N_RX_FASTWAIT; setEvent(SERIAL_RX_EVENT, bytetime*0.65f); } else { @@ -329,11 +340,11 @@ void CNullModem::handleUpperEvent(Bit16u type) { case N_RX_BLOCKED: // try to receive case N_RX_WAIT: case N_RX_FASTWAIT: - if(CanReceiveByte()) { + if (CanReceiveByte()) { // just works or unblocked - if(doReceive()) { + if (doReceive()) { rx_retry=0; // not waiting anymore - if(rx_state==N_RX_WAIT) setEvent(SERIAL_RX_EVENT, bytetime*0.9f); + if (rx_state==N_RX_WAIT) setEvent(SERIAL_RX_EVENT, bytetime*0.9f); else { // maybe unblocked rx_state=N_RX_FASTWAIT; @@ -347,7 +358,7 @@ void CNullModem::handleUpperEvent(Bit16u type) { } else { // blocking now or still blocked #if SERIAL_DEBUG - if(rx_state==N_RX_BLOCKED) + if (rx_state==N_RX_BLOCKED) log_ser(dbg_aux,"Nullmodem: rx still blocked (retry=%d)",rx_retry); else log_ser(dbg_aux,"Nullmodem: block on continued rx (retry=%d).",rx_retry); #endif @@ -361,8 +372,8 @@ void CNullModem::handleUpperEvent(Bit16u type) { } case SERIAL_TX_EVENT: { // Maybe echo cirquit works a bit better this way - if(rx_state==N_RX_IDLE && CanReceiveByte() && clientsocket) { - if(doReceive()) { + if (rx_state==N_RX_IDLE && CanReceiveByte() && clientsocket) { + if (doReceive()) { // a byte was received rx_state=N_RX_WAIT; setEvent(SERIAL_RX_EVENT, bytetime*0.9f); @@ -380,25 +391,7 @@ void CNullModem::handleUpperEvent(Bit16u type) { case SERIAL_SERVER_POLLING_EVENT: { // As long as nothing is connected to our server poll the // connection. - clientsocket=serversocket->Accept(); - if(clientsocket) { - Bit8u peeripbuf[16]; - clientsocket->GetRemoteAddressString(peeripbuf); - LOG_MSG("Serial%d: A client (%s) has connected.",COMNUMBER,peeripbuf); -#if SERIAL_DEBUG - log_ser(dbg_aux,"Nullmodem: A client (%s) has connected.", peeripbuf); -#endif// new socket found... - clientsocket->SetSendBufferSize(256); - rx_state=N_RX_IDLE; - setEvent(SERIAL_POLLING_EVENT, 1); - - // we don't accept further connections - delete serversocket; - serversocket=0; - - // transmit the line status - setRTSDTR(getRTS(), getDTR()); - } else { + if (!ServerConnect()) { // continue looking setEvent(SERIAL_SERVER_POLLING_EVENT, 50); } @@ -406,13 +399,19 @@ void CNullModem::handleUpperEvent(Bit16u type) { } case SERIAL_TX_REDUCTION: { // Flush the data in the transmitting buffer. - if(clientsocket) clientsocket->FlushBuffer(); + if (clientsocket) clientsocket->FlushBuffer(); tx_block=false; break; } case SERIAL_NULLMODEM_DTR_EVENT: { - if(getDTR()) ClientConnect(); - else setEvent(SERIAL_NULLMODEM_DTR_EVENT,50); + if ((!DTR_delta) && getDTR()) { + // DTR went positive. Try to connect. + if (ClientConnect(new TCPClientSocket((char*)hostnamebuffer, + (Bit16u)clientport))) + break; // no more DTR wait event when connected + } + DTR_delta = getDTR(); + setEvent(SERIAL_NULLMODEM_DTR_EVENT,50); break; } } @@ -432,11 +431,11 @@ void CNullModem::updateMSR () { bool CNullModem::doReceive () { Bits rxchar = readChar(); - if(rxchar>=0) { + if (rxchar>=0) { receiveByteEx((Bit8u)rxchar,0); return true; } - else if(rxchar==-2) { + else if (rxchar==-2) { Disconnect(); } return false; @@ -444,7 +443,7 @@ bool CNullModem::doReceive () { void CNullModem::transmitByte (Bit8u val, bool first) { // transmit it later in THR_Event - if(first) setEvent(SERIAL_THR_EVENT, bytetime/8); + if (first) setEvent(SERIAL_THR_EVENT, bytetime/8); else setEvent(SERIAL_TX_EVENT, bytetime); // disable 0xff escaping when transparent mode is enabled @@ -455,73 +454,73 @@ void CNullModem::transmitByte (Bit8u val, bool first) { Bits CNullModem::TelnetEmulation(Bit8u data) { Bit8u response[3]; - if(telClient.inIAC) { - if(telClient.recCommand) { - if((data != 0) && (data != 1) && (data != 3)) { + if (telClient.inIAC) { + if (telClient.recCommand) { + if ((data != 0) && (data != 1) && (data != 3)) { LOG_MSG("Serial%d: Unrecognized telnet option %d",COMNUMBER, data); - if(telClient.command>250) { + if (telClient.command>250) { /* Reject anything we don't recognize */ response[0]=0xff; response[1]=252; response[2]=data; /* We won't do crap! */ - if(clientsocket) clientsocket->SendArray(response, 3); + if (clientsocket) clientsocket->SendArray(response, 3); } } switch(telClient.command) { case 251: /* Will */ - if(data == 0) telClient.binary[TEL_SERVER] = true; - if(data == 1) telClient.echo[TEL_SERVER] = true; - if(data == 3) telClient.supressGA[TEL_SERVER] = true; + if (data == 0) telClient.binary[TEL_SERVER] = true; + if (data == 1) telClient.echo[TEL_SERVER] = true; + if (data == 3) telClient.supressGA[TEL_SERVER] = true; break; case 252: /* Won't */ - if(data == 0) telClient.binary[TEL_SERVER] = false; - if(data == 1) telClient.echo[TEL_SERVER] = false; - if(data == 3) telClient.supressGA[TEL_SERVER] = false; + if (data == 0) telClient.binary[TEL_SERVER] = false; + if (data == 1) telClient.echo[TEL_SERVER] = false; + if (data == 3) telClient.supressGA[TEL_SERVER] = false; break; case 253: /* Do */ - if(data == 0) { + if (data == 0) { telClient.binary[TEL_CLIENT] = true; response[0]=0xff; response[1]=251; response[2]=0; /* Will do binary transfer */ - if(clientsocket) clientsocket->SendArray(response, 3); + if (clientsocket) clientsocket->SendArray(response, 3); } - if(data == 1) { + if (data == 1) { telClient.echo[TEL_CLIENT] = false; response[0]=0xff; response[1]=252; response[2]=1; /* Won't echo (too lazy) */ - if(clientsocket) clientsocket->SendArray(response, 3); + if (clientsocket) clientsocket->SendArray(response, 3); } - if(data == 3) { + if (data == 3) { telClient.supressGA[TEL_CLIENT] = true; response[0]=0xff; response[1]=251; response[2]=3; /* Will Suppress GA */ - if(clientsocket) clientsocket->SendArray(response, 3); + if (clientsocket) clientsocket->SendArray(response, 3); } break; case 254: /* Don't */ - if(data == 0) { + if (data == 0) { telClient.binary[TEL_CLIENT] = false; response[0]=0xff; response[1]=252; response[2]=0; /* Won't do binary transfer */ - if(clientsocket) clientsocket->SendArray(response, 3); + if (clientsocket) clientsocket->SendArray(response, 3); } - if(data == 1) { + if (data == 1) { telClient.echo[TEL_CLIENT] = false; response[0]=0xff; response[1]=252; response[2]=1; /* Won't echo (fine by me) */ - if(clientsocket) clientsocket->SendArray(response, 3); + if (clientsocket) clientsocket->SendArray(response, 3); } - if(data == 3) { + if (data == 3) { telClient.supressGA[TEL_CLIENT] = true; response[0]=0xff; response[1]=251; response[2]=3; /* Will Suppress GA (too lazy) */ - if(clientsocket) clientsocket->SendArray(response, 3); + if (clientsocket) clientsocket->SendArray(response, 3); } break; default: @@ -532,7 +531,7 @@ Bits CNullModem::TelnetEmulation(Bit8u data) { telClient.recCommand = false; return -1; //continue; } else { - if(data==249) { + if (data==249) { /* Go Ahead received */ telClient.inIAC = false; return -1; //continue; @@ -540,7 +539,7 @@ Bits CNullModem::TelnetEmulation(Bit8u data) { telClient.command = data; telClient.recCommand = true; - if((telClient.binary[TEL_SERVER]) && (data == 0xff)) { + if ((telClient.binary[TEL_SERVER]) && (data == 0xff)) { /* Binary data with value of 255 */ telClient.inIAC = false; telClient.recCommand = false; @@ -548,7 +547,7 @@ Bits CNullModem::TelnetEmulation(Bit8u data) { } } } else { - if(data == 0xff) { + if (data == 0xff) { telClient.inIAC = true; return -1; } @@ -570,14 +569,14 @@ void CNullModem::setBreak (bool /*value*/) { /* updateModemControlLines(mcr) sets DTR and RTS. **/ /*****************************************************************************/ void CNullModem::setRTSDTR(bool xrts, bool xdtr) { - if(!transparent) { + if (!transparent) { Bit8u control[2]; control[0]=0xff; control[1]=0x0; - if(xrts) control[1]|=1; - if(xdtr) control[1]|=2; - if(LCR&LCR_BREAK_MASK) control[1]|=4; - if(clientsocket) clientsocket->SendArray(control, 2); + if (xrts) control[1]|=1; + if (xdtr) control[1]|=2; + if (LCR&LCR_BREAK_MASK) control[1]|=4; + if (clientsocket) clientsocket->SendArray(control, 2); } } void CNullModem::setRTS(bool val) { diff --git a/src/hardware/serialport/nullmodem.h b/src/hardware/serialport/nullmodem.h index a1f3f054..5bf7df44 100644 --- a/src/hardware/serialport/nullmodem.h +++ b/src/hardware/serialport/nullmodem.h @@ -35,16 +35,8 @@ class CNullModem : public CSerial { public: - TCPServerSocket* serversocket; - TCPClientSocket* clientsocket; - CNullModem(Bitu id, CommandLine* cmd); ~CNullModem(); - bool receiveblock; // It's not a block of data it rather blocks - Bit16u serverport; // we are a server if this is nonzero - Bit16u clientport; - - Bit8u hostnamebuffer[128]; // the name passed to us by the user void updatePortConfig(Bit16u divider, Bit8u lcr); void updateMSR(); @@ -56,6 +48,16 @@ public: void setDTR(bool val); void handleUpperEvent(Bit16u type); +private: + TCPServerSocket* serversocket; + TCPClientSocket* clientsocket; + + bool receiveblock; // It's not a block of data it rather blocks + Bit16u serverport; // we are a server if this is nonzero + Bit16u clientport; + + Bit8u hostnamebuffer[128]; // the name passed to us by the user + Bitu rx_state; #define N_RX_IDLE 0 #define N_RX_WAIT 1 @@ -64,11 +66,17 @@ public: #define N_RX_DISC 4 bool doReceive(); - void ClientConnect(); + bool ClientConnect(TCPClientSocket* newsocket); + bool ServerListen(); + bool ServerConnect(); void Disconnect(); Bits readChar(); void WriteChar(Bit8u data); + bool DTR_delta; // with dtrrespect, we try to establish a connection + // whenever DTR switches to 1. This variable is + // used to remember the old state. + bool tx_block; // true while the SERIAL_TX_REDUCTION event // is pending From f7016981a753e652e5949726d8fe9ef8664050b8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 15 Aug 2011 11:29:02 +0000 Subject: [PATCH 3649/4131] Make shift-tab walk through the completion list in reverse order. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3739 --- src/shell/shell_misc.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 509435f9..faca8a63 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -56,7 +56,7 @@ void DOS_Shell::InputCommand(char * line) { Bit16u dummy; DOS_CloseFile(input_handle); DOS_OpenFile("con",2,&dummy); - LOG(LOG_MISC,LOG_ERROR)("Reopening the input handle.This is a bug!"); + LOG(LOG_MISC,LOG_ERROR)("Reopening the input handle. This is a bug!"); } if (!n) { size=0; //Kill the while loop @@ -174,6 +174,24 @@ void DOS_Shell::InputCommand(char * line) { size++; } break; + case 15: /* Shift-Tab */ + if (l_completion.size()) { + if (it_completion == l_completion.begin()) it_completion = l_completion.end (); + it_completion--; + + if (it_completion->length()) { + for (;str_index > completion_index; str_index--) { + // removes all characters + outc(8); outc(' '); outc(8); + } + + strcpy(&line[completion_index], it_completion->c_str()); + len = (Bit16u)it_completion->length(); + str_len = str_index = completion_index + len; + size = CMD_MAXLINE - str_index - 2; + DOS_WriteFile(STDOUT, (Bit8u *)it_completion->c_str(), &len); + } + } default: break; } From aad564340349c5ae1580e0863d36c29936f81615 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 15 Aug 2011 12:21:36 +0000 Subject: [PATCH 3650/4131] Keep repeating a pressed key if another key is released. Thanks jazztickets and robertmo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3740 --- src/hardware/keyboard.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 93bcda0c..f68d2b09 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -347,15 +347,18 @@ void KEYBOARD_AddKey(KBD_KEYS keytype,bool pressed) { } /* Add the actual key in the keyboard queue */ if (pressed) { - if (keyb.repeat.key==keytype) keyb.repeat.wait=keyb.repeat.rate; - else keyb.repeat.wait=keyb.repeat.pause; - keyb.repeat.key=keytype; + if (keyb.repeat.key == keytype) keyb.repeat.wait = keyb.repeat.rate; + else keyb.repeat.wait = keyb.repeat.pause; + keyb.repeat.key = keytype; } else { - keyb.repeat.key=KBD_NONE; - keyb.repeat.wait=0; - ret+=128; + if (keyb.repeat.key == keytype) { + /* repeated key being released */ + keyb.repeat.key = KBD_NONE; + keyb.repeat.wait = 0; + } + ret += 128; } - if (extend) KEYBOARD_AddBuffer(0xe0); + if (extend) KEYBOARD_AddBuffer(0xe0); KEYBOARD_AddBuffer(ret); } @@ -381,7 +384,7 @@ void KEYBOARD_Init(Section* sec) { keyb.command=CMD_NONE; keyb.p60changed=false; keyb.repeat.key=KBD_NONE; - keyb.repeat.pause=500; + keyb.repeat.pause=200; keyb.repeat.rate=33; keyb.repeat.wait=0; KEYBOARD_ClrBuffer(); From 817651144b8b1d5406fa0aaf6d322afabbb630f2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 15 Aug 2011 17:02:29 +0000 Subject: [PATCH 3651/4131] Restore old delay. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3741 --- src/hardware/keyboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index f68d2b09..1604e339 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -384,7 +384,7 @@ void KEYBOARD_Init(Section* sec) { keyb.command=CMD_NONE; keyb.p60changed=false; keyb.repeat.key=KBD_NONE; - keyb.repeat.pause=200; + keyb.repeat.pause=500; keyb.repeat.rate=33; keyb.repeat.wait=0; KEYBOARD_ClrBuffer(); From 9df334048f7faeb4bc4f8895c3bda69dbecfd2e5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 16 Aug 2011 10:41:59 +0000 Subject: [PATCH 3652/4131] Enchance RESCAN with drive paramater and -All flag Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3742 --- README | 11 ++++++++++- docs/dosbox.1 | 14 ++++++++++++-- src/dos/dos_programs.cpp | 24 +++++++++++++++++++++--- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/README b/README index b8793b92..3fd7d416 100644 --- a/README +++ b/README @@ -778,10 +778,19 @@ LOADFIX -f loadfix -f -RESCAN +RESCAN [Drive:] [-All] Make DOSBox reread the directory structure. Useful if you changed something on a mounted drive outside of DOSBox. (CTRL - F4 does this as well!) + + Drive: + Drive to refresh. + -All + Refresh all drives. + + if both a Drive: and -All are missing, then the current drive will be + refreshed. + MIXER Makes DOSBox display its current volume settings. diff --git a/docs/dosbox.1 b/docs/dosbox.1 index 729ff4b9..407fc23d 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -205,7 +205,7 @@ which is located on the local filesystem. Not a mounted drive in .RS .TP .B \-securemode -.RB Switches dosbox " to a more secure mode. In this mode the" +.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. @@ -242,11 +242,21 @@ The amount of memory to eat up (in kb). Example \-32, \-64 or \-128 Frees all memory eaten up by loadfix. .RE .TP -.B RESCAN +.B RESCAN [\-All] [Drive:] .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!) +.RS +.TP +.B \-All +.R Reread directory structure for all drives. +.TP +.B Drive: +.RB "Reread directory structure for drive " Drive: +.RE +.LP +.RB "If both " \-All " and " Drive: " are missing, then the current drive is used. .TP .B IMGMOUNT .LP diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index e59c908a..856825a5 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -980,11 +980,29 @@ public: void RESCAN::Run(void) { - // Get current drive + bool all = false; + Bit8u drive = DOS_GetDefaultDrive(); - if (Drives[drive]) { - Drives[drive]->EmptyCache(); + + if(cmd->FindCommand(1,temp_line)) { + //-A -All /A /All + if(temp_line.size() >= 2 && (temp_line[0] == '-' ||temp_line[0] =='/')&& (temp_line[1] == 'a' || temp_line[1] =='A') ) all = true; + else if(temp_line.size() == 2 && temp_line[1] == ':') { + lowcase(temp_line); + drive = temp_line[0] - 'a'; + } + } + // Get current drive + if (all) { + for(Bitu i =0; iEmptyCache(); + } WriteOut(MSG_Get("PROGRAM_RESCAN_SUCCESS")); + } else { + if (drive < DOS_DRIVES && Drives[drive]) { + Drives[drive]->EmptyCache(); + WriteOut(MSG_Get("PROGRAM_RESCAN_SUCCESS")); + } } } From b40ab65dcb614f3c097592203324c065fd5f1ac5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Aug 2011 07:59:47 +0000 Subject: [PATCH 3653/4131] Be friendly for other open source projects: work with WINE style namemangling. Patch 3382938 from Andre_H (modified). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3743 --- src/dos/drive_cache.cpp | 68 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index f0769007..2c59c2a5 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -376,6 +376,60 @@ bool DOS_Drive_Cache::RemoveTrailingDot(char* shortname) { return false; } +#define WINE_DRIVE_SUPPORT 1 +#if WINE_DRIVE_SUPPORT +//Changes to interact with WINE by supporting their namemangling. +//The code is rather slow, because orglist is unordered, so it needs to be avoided if possible. +//Hence the tests in GetLongFileName + + +// From the Wine project +static Bits wine_hash_short_file_name( char* name, char* buffer ) +{ + static const char hash_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"; + static const char invalid_chars[] = { '*','?','<','>','|','"','+','=',',',';','[',']',' ','\345','~','.',0 }; + char* p; + char* ext; + char* end = name + strlen(name); + char* dst; + unsigned short hash; + int i; + + // Compute the hash code of the file name + for (p = name, hash = 0xbeef; p < end - 1; p++) + hash = (hash<<3) ^ (hash>>5) ^ tolower(*p) ^ (tolower(p[1]) << 8); + hash = (hash<<3) ^ (hash>>5) ^ tolower(*p); // Last character + + + // Find last dot for start of the extension + for (p = name + 1, ext = NULL; p < end - 1; p++) if (*p == '.') ext = p; + + // Copy first 4 chars, replacing invalid chars with '_' + for (i = 4, p = name, dst = buffer; i > 0; i--, p++) + { + if (p == end || p == ext) break; + *dst++ = (*p < 0 || strchr( invalid_chars, *p ) != NULL) ? '_' : toupper(*p); + } + // Pad to 5 chars with '~' + while (i-- >= 0) *dst++ = '~'; + + // Insert hash code converted to 3 ASCII chars + *dst++ = hash_chars[(hash >> 10) & 0x1f]; + *dst++ = hash_chars[(hash >> 5) & 0x1f]; + *dst++ = hash_chars[hash & 0x1f]; + + // Copy the first 3 chars of the extension (if any) + if (ext) + { + *dst++ = '.'; + for (i = 3, ext++; (i > 0) && ext < end; i--, ext++) + *dst++ = (*ext < 0 || strchr( invalid_chars, *ext ) != NULL) ? '_' : toupper(*ext); + } + + return dst - buffer; +} +#endif + Bits DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) { std::vector::size_type filelist_size = curDir->fileList.size(); if (GCC_UNLIKELY(filelist_size<=0)) return -1; @@ -396,6 +450,20 @@ Bits DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) { return mid; }; } +#ifdef WINE_DRIVE_SUPPORT + if (strlen(shortName) < 8 || shortName[4] != '~' || shortName[5] == '.' || shortName[6] == '.' || shortName[7] == '.') return -1; // not available + // else it's most likely a Wine style short name ABCD~###, # = not dot (length at least 8) + // The above test is rather strict as the following loop can be really slow if filelist_size is large. + char buff[CROSS_LEN]; + for (Bits i = 0; i < filelist_size; i++) { + res = wine_hash_short_file_name(curDir->fileList[i]->orgname,buff); + if (!strncmp(shortName,buff,res)) + { // Found + strcpy(shortName,curDir->fileList[i]->orgname); + return i; + }; + } +#endif // not available return -1; } From 770732bef76d2d1acf7ec5dc1031d445615afb8d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Aug 2011 08:30:40 +0000 Subject: [PATCH 3654/4131] Fix supersaxxon. Regression from line based updates. Thanks h-a-l-9000 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3744 --- src/hardware/vga_draw.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 563bf180..37dce8ac 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -77,20 +77,20 @@ static Bitu temp[643]={0}; static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart, Bitu line) { const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift); - const Bit8u *reader = base + vidstart; +#define CGA16_READER(OFF) (base[(vidstart +(OFF))& (8*1024 -1)]) Bit32u * draw=(Bit32u *)TempLine; //Generate a temporary bitline to calculate the avarage //over bit-2 bit-1 bit bit+1. //Combine this number with the current colour to get - //an unigue index in the pallete. Or it with bit 7 as they are stored + //an unique index in the pallete. Or it with bit 7 as they are stored //in the upperpart to keep them from interfering the regular cga stuff for(Bitu x = 0; x < 640; x++) - temp[x+2] = (( reader[(x>>3)] >> (7-(x&7)) )&1) << 4; + temp[x+2] = (( CGA16_READER(x>>3)>> (7-(x&7)) )&1) << 4; //shift 4 as that is for the index. Bitu i = 0,temp1,temp2,temp3,temp4; for (Bitu x=0;x>= 4; @@ -113,6 +113,7 @@ static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart, Bitu line) { ((temp4|val2) <<24); } return TempLine; +#undef CGA16_READER } static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart, Bitu line) { From d7d6ac163398aaeba272281c0e4fcac6c941639e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Aug 2011 08:59:28 +0000 Subject: [PATCH 3655/4131] Ignore verify with copy. Fixes Grand Prix Unlimited CD installer. Thanks ripsaw and rcblanke Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3745 --- src/shell/shell_cmds.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index e2af8415..4840c834 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -573,6 +573,7 @@ void DOS_Shell::CMD_COPY(char * args) { while(ScanCMDBool(args,"A")) ; ScanCMDBool(args,"Y"); ScanCMDBool(args,"-Y"); + ScanCMDBool(args,"V"); char * rem=ScanCMDRemain(args); if (rem) { From 1b74652bab8c23d08e1d098846455104e9edc361 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Aug 2011 12:29:24 +0000 Subject: [PATCH 3656/4131] Update volume for cda mixer changes as well. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3746 --- src/hardware/sblaster.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 382c3236..8e379133 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1158,10 +1158,15 @@ static void CTMIXER_Write(Bit8u val) { break; case 0x08: /* CDA Volume (SB2 Only) */ SETPROVOL(sb.mixer.cda,(val&0xf)|(val<<4)); + CTMIXER_UpdateVolumes(); break; case 0x0a: /* Mic Level (SBPRO) or DAC Volume (SB2): 2-bit, 3-bit on SB16 */ - if (sb.type==SBT_2) sb.mixer.dac[0]=sb.mixer.dac[1]=((val & 0x6) << 2)|3; - else sb.mixer.mic=((val & 0x7) << 2)|(sb.type==SBT_16?1:3); + if (sb.type==SBT_2) { + sb.mixer.dac[0]=sb.mixer.dac[1]=((val & 0x6) << 2)|3; + CTMIXER_UpdateVolumes(); + } else { + sb.mixer.mic=((val & 0x7) << 2)|(sb.type==SBT_16?1:3); + } break; case 0x0e: /* Output/Stereo Select */ sb.mixer.stereo=(val & 0x2) > 0; @@ -1179,6 +1184,7 @@ static void CTMIXER_Write(Bit8u val) { break; case 0x28: /* CD Audio Volume (SBPRO) */ SETPROVOL(sb.mixer.cda,val); + CTMIXER_UpdateVolumes(); break; case 0x2e: /* Line-in Volume (SBPRO) */ SETPROVOL(sb.mixer.lin,val); From 173fb5510ef277ff63a964183e8466accba644cc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Aug 2011 13:14:25 +0000 Subject: [PATCH 3657/4131] Decode RDTSC as well. Thanks ripsaw. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3747 --- src/debug/debug_disasm.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/debug/debug_disasm.cpp b/src/debug/debug_disasm.cpp index 5b642962..f1e2deed 100644 --- a/src/debug/debug_disasm.cpp +++ b/src/debug/debug_disasm.cpp @@ -283,8 +283,10 @@ static char const *second[] = { 0, 0, 0, 0, 0, 0, 0, 0, /* 3 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, + 0, "rdtsc", 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, /* 4 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, From ee982d5754b68e28d9b355ec1f8cb9f38c85260d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Aug 2011 13:15:36 +0000 Subject: [PATCH 3658/4131] Use a fixed cycle rate in auto cycles mode when calculating RDTSC. Improves Tie break Tennis 98 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3748 --- src/cpu/core_full/load.h | 2 +- src/cpu/core_normal/prefix_0f.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index cd620add..0a3f1ae0 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -502,7 +502,7 @@ l_M_Ed: continue; case D_RDTSC: { if (CPU_ArchitectureType>32); reg_eax=(Bit32u)(tsc&0xffffffff); break; diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 84f1b741..38004f1f 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -228,7 +228,8 @@ CASE_0F_B(0x31) /* RDTSC */ { if (CPU_ArchitectureType>32); reg_eax=(Bit32u)(tsc&0xffffffff); } From 68a1725e0f2dcce5922d17825a21cb3df71f4250 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 31 Aug 2011 09:19:59 +0000 Subject: [PATCH 3659/4131] Some refinements. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3749 --- src/dos/drive_cache.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 2c59c2a5..16e1d7c3 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -457,11 +457,12 @@ Bits DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) { char buff[CROSS_LEN]; for (Bits i = 0; i < filelist_size; i++) { res = wine_hash_short_file_name(curDir->fileList[i]->orgname,buff); - if (!strncmp(shortName,buff,res)) - { // Found + buff[res] = 0; + if (!strcmp(shortName,buff)) { + // Found strcpy(shortName,curDir->fileList[i]->orgname); return i; - }; + } } #endif // not available From 81085e036e17b9cfd69a67fb8b078025964dff16 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 1 Sep 2011 12:08:35 +0000 Subject: [PATCH 3660/4131] Keep track of last written character instead of previous character in buffer. This allow handling of leading and single newlines. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3750 --- src/misc/programs.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 3b1cd147..6ba02c27 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -128,6 +128,7 @@ void Program::ChangeToLongCmd() { full_arguments.assign(""); //Clear so it gets even more save } +static char last_written_character = 0;//For 0xA to OxD 0xA expansion void Program::WriteOut(const char * format,...) { char buf[2048]; va_list msg; @@ -139,10 +140,10 @@ void Program::WriteOut(const char * format,...) { Bit16u size = (Bit16u)strlen(buf); for(Bit16u i = 0; i < size;i++) { Bit8u out;Bit16u s=1; - if (buf[i] == 0xA && i > 0 && buf[i-1] !=0xD) { + if (buf[i] == 0xA && last_written_character != 0xD) { out = 0xD;DOS_WriteFile(STDOUT,&out,&s); } - out = buf[i]; + last_written_character = out = buf[i]; DOS_WriteFile(STDOUT,&out,&s); } @@ -154,10 +155,10 @@ void Program::WriteOut_NoParsing(const char * format) { char const* buf = format; for(Bit16u i = 0; i < size;i++) { Bit8u out;Bit16u s=1; - if (buf[i] == 0xA && i > 0 && buf[i-1] !=0xD) { + if (buf[i] == 0xA && last_written_character != 0xD) { out = 0xD;DOS_WriteFile(STDOUT,&out,&s); } - out = buf[i]; + last_written_character = out = buf[i]; DOS_WriteFile(STDOUT,&out,&s); } From 6dfe1d9dcf07b6ecaadd8868d0beda3fc7d32b0f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 1 Sep 2011 12:19:52 +0000 Subject: [PATCH 3661/4131] Call int 0xe when resetting a disk. Fixes a keydisk workaround algorithm. (thanks ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3751 --- include/callback.h | 2 +- src/cpu/callback.cpp | 13 ++++++++++++- src/ints/bios_disk.cpp | 4 +++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/include/callback.h b/include/callback.h index 382efc56..ff7ebfac 100644 --- a/include/callback.h +++ b/include/callback.h @@ -30,7 +30,7 @@ extern CallBack_Handler CallBack_Handlers[]; enum { CB_RETN,CB_RETF,CB_RETF8,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1, 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 }; + CB_INT21,CB_INT13 }; #define CB_MAX 128 #define CB_SIZE 32 diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 0c3f3c25..31761e00 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -433,7 +433,18 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ phys_writeb(physAddress+0x09,(Bit8u)0x59); // pop cx phys_writeb(physAddress+0x0A,(Bit8u)0xCF); //An IRET Instruction return (use_cb?15:11); - + case CB_INT13: + 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,(Bit16u)callback); //The immediate word + physAddress+=4; + } + phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction + phys_writew(physAddress+0x02,(Bit16u)0x0ECD); // int 0e + phys_writeb(physAddress+0x04,(Bit8u)0xCF); //An IRET Instruction + return (use_cb?9:5); default: E_Exit("CALLBACK:Setup:Illegal type %d",type); } diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index a5514467..f3486045 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -333,12 +333,14 @@ static Bitu INT13_DiskHandler(void) { if ((machine==MCH_CGA) || (machine==MCH_PCJR)) { /* those bioses call floppy drive reset for invalid drive values */ if (((imageDiskList[0]) && (imageDiskList[0]->active)) || ((imageDiskList[1]) && (imageDiskList[1]->active))) { + if (reg_dl<0x80) reg_ip++; last_status = 0x00; CALLBACK_SCF(false); } } return CBRET_NONE; } + if (reg_dl<0x80) reg_ip++; last_status = 0x00; CALLBACK_SCF(false); } @@ -500,7 +502,7 @@ static Bitu INT13_DiskHandler(void) { void BIOS_SetupDisks(void) { /* TODO Start the time correctly */ call_int13=CALLBACK_Allocate(); - CALLBACK_Setup(call_int13,&INT13_DiskHandler,CB_IRET,"Int 13 Bios disk"); + CALLBACK_Setup(call_int13,&INT13_DiskHandler,CB_INT13,"Int 13 Bios disk"); RealSetVec(0x13,CALLBACK_RealPointer(call_int13)); int i; for(i=0;i<4;i++) { From eb395f5add52c27f8c0bf9bf8bc37b40d8e553ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 7 Sep 2011 18:43:03 +0000 Subject: [PATCH 3662/4131] small recompiler fixes (missing host fpu usage check; assembler output update) and enhancements Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3752 --- src/cpu/core_dyn_x86.cpp | 63 +++++++++++++++++++++++++++++-- src/cpu/core_dyn_x86/cache.h | 72 ++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 6450a943..f63d9158 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -247,8 +247,8 @@ static void dyn_restoreregister(DynReg * src_reg, DynReg * dst_reg) { { \ __asm__ volatile ( \ "fnsave %0 \n" \ + : "=m" (dyn_dh_fpu.state[0]) \ : \ - : "m" (dyn_dh_fpu.state[0]) \ : "memory" \ ); \ dyn_dh_fpu.state_used=false; \ @@ -303,7 +303,10 @@ run_block: } #endif if (!GETFLAG(TF)) { - if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; + if (GETFLAG(IF) && PIC_IRQCheck) { + if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT + return CBRET_NONE; + } goto restart_core; } cpudecoder=CPU_Core_Dyn_X86_Trap_Run; @@ -450,8 +453,8 @@ void CPU_Core_Dyn_X86_Init(void) { "finit \n" "fsave %0 \n" "fstcw %1 \n" + : "=m" (dyn_dh_fpu.state[0]), "=m" (dyn_dh_fpu.host_cw) : - : "m" (dyn_dh_fpu.state[0]), "m" (dyn_dh_fpu.host_cw) : "memory" ); #endif @@ -468,8 +471,62 @@ void CPU_Core_Dyn_X86_Cache_Close(void) { cache_close(); } +void CPU_Core_Dyn_X86_Cache_Reset(void) { + cache_reset(); +} + void CPU_Core_Dyn_X86_SetFPUMode(bool dh_fpu) { dyn_dh_fpu.dh_fpu_enabled=dh_fpu; } +Bit32u fpu_state[32]; + +void CPU_Core_Dyn_X86_SaveDHFPUState(void) { + if (dyn_dh_fpu.dh_fpu_enabled) { + if (dyn_dh_fpu.state_used!=0) { +#if defined (_MSC_VER) + __asm { + __asm fsave fpu_state[0] + __asm finit + } +#else + __asm__ volatile ( + "fsave %0 \n" + "finit \n" + : "=m" (fpu_state[0]) + : + : "memory" + ); +#endif + } + } +} + +void CPU_Core_Dyn_X86_RestoreDHFPUState(void) { + if (dyn_dh_fpu.dh_fpu_enabled) { + if (dyn_dh_fpu.state_used!=0) { +#if defined (_MSC_VER) + __asm { + __asm frstor fpu_state[0] + } +#else + __asm__ volatile ( + "frstor %0 \n" + : + : "m" (fpu_state[0]) + : + ); +#endif + } + } +} + +#else + +void CPU_Core_Dyn_X86_SaveDHFPUState(void) { +} + +void CPU_Core_Dyn_X86_RestoreDHFPUState(void) { +} + #endif diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 6eeeeae7..2bda44cd 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -569,3 +569,75 @@ static void cache_close(void) { cache_code_link_blocks = NULL; cache_initialized = false; */ } + +static void cache_reset(void) { + if (cache_initialized) { + 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) { + 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 (Bits i=0;icache.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 (Bitu i=0;inext=cache.free_pages; + cache.free_pages=newpage; + } + } +} From 1a8afec751884c2f3c5231768509ba79ea571268 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 30 Oct 2011 15:06:40 +0000 Subject: [PATCH 3663/4131] Disable sticky keys in fullscreen mode. (pressing shift 5 times gives a menu) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3753 --- src/gui/sdlmain.cpp | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 353b8247..e2285968 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -677,12 +677,40 @@ static void CaptureMouse(bool pressed) { GFX_CaptureMouse(); } +#if defined (WIN32) +STICKYKEYS stick_keys = {sizeof(STICKYKEYS), 0}; +void sticky_keys(bool restore){ + static bool inited = false; + if (!inited){ + inited = true; + SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(STICKYKEYS), &stick_keys, 0); + } + if (restore) { + SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &stick_keys, 0); + return; + } + //Get current sticky keys layout: + STICKYKEYS s = {sizeof(STICKYKEYS), 0}; + SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(STICKYKEYS), &s, 0); + if ( !(s.dwFlags & SKF_STICKYKEYSON)) { //Not on already + s.dwFlags &= ~SKF_HOTKEYACTIVE; + SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &s, 0); + } +} +#endif + void GFX_SwitchFullScreen(void) { sdl.desktop.fullscreen=!sdl.desktop.fullscreen; if (sdl.desktop.fullscreen) { if (!sdl.mouse.locked) GFX_CaptureMouse(); +#if defined (WIN32) + sticky_keys(false); //disable sticky keys in fullscreen mode +#endif } else { if (sdl.mouse.locked) GFX_CaptureMouse(); +#if defined (WIN32) + sticky_keys(true); //restore sticky keys to default state in windowed mode. +#endif } GFX_ResetScreen(); } @@ -1693,7 +1721,6 @@ static void erasemapperfile() { } - //extern void UI_Init(void); int main(int argc, char* argv[]) { try { @@ -1711,7 +1738,7 @@ int main(int argc, char* argv[]) { if(control->cmdline->FindExist("-resetconf")) eraseconfigfile(); if(control->cmdline->FindExist("-erasemapper")) erasemapperfile(); if(control->cmdline->FindExist("-resetmapper")) erasemapperfile(); - + /* Can't disable the console with debugger enabled */ #if defined(WIN32) && !(C_DEBUG) if (control->cmdline->FindExist("-noconsole")) { @@ -1901,6 +1928,7 @@ int main(int argc, char* argv[]) { control->StartUp(); /* Shutdown everything */ } catch (char * error) { + sticky_keys(true); GFX_ShowMsg("Exit to error: %s",error); fflush(NULL); if(sdl.wait_on_error) { @@ -1919,11 +1947,17 @@ int main(int argc, char* argv[]) { ;//nothing pressed killswitch } catch(...){ +#if defined (WIN32) + sticky_keys(true); +#endif //Force visible mouse to end user. Somehow this sometimes doesn't happen SDL_WM_GrabInput(SDL_GRAB_OFF); SDL_ShowCursor(SDL_ENABLE); throw;//dunno what happened. rethrow for sdl to catch } +#if defined (WIN32) + sticky_keys(true); //Might not be needed if the shutdown function switches to windowed mode, but it doesn't hurt +#endif //Force visible mouse to end user. Somehow this sometimes doesn't happen SDL_WM_GrabInput(SDL_GRAB_OFF); SDL_ShowCursor(SDL_ENABLE); From 2bca1b7ecba3f1cd2f335588f1b9109250fc616f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 1 Nov 2011 16:31:30 +0000 Subject: [PATCH 3664/4131] Fix compilation on linux. Thank salty Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3754 --- src/gui/sdlmain.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index e2285968..d495042e 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1928,7 +1928,9 @@ int main(int argc, char* argv[]) { control->StartUp(); /* Shutdown everything */ } catch (char * error) { +#if defined (WIN32) sticky_keys(true); +#endif GFX_ShowMsg("Exit to error: %s",error); fflush(NULL); if(sdl.wait_on_error) { From 7603b90e45bc97630adffa5881e39562122aa191 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 1 Nov 2011 17:00:19 +0000 Subject: [PATCH 3665/4131] Some small typos Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3755 --- src/dosbox.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 40be085c..9e31162b 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -703,8 +703,8 @@ void DOSBOX_Init(void) { "You can put your MOUNT lines here.\n" ); MSG_Add("CONFIGFILE_INTRO", - "# This is the configurationfile for DOSBox %s. (Please use the latest version of DOSBox)\n" - "# Lines starting with a # are commentlines and are ignored by DOSBox.\n" + "# This is the configuration file for DOSBox %s. (Please use the latest version of DOSBox)\n" + "# Lines starting with a # are comment lines and are ignored by DOSBox.\n" "# They are used to (briefly) document the effect of each option.\n"); MSG_Add("CONFIG_SUGGESTED_VALUES", "Possible values"); From 421e19255936458cac325f73edf4cb7db6ad6e68 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sat, 5 Nov 2011 17:24:01 +0000 Subject: [PATCH 3666/4131] Consider parity when calculating the duration of a serial frame. E-mail report by MB. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3756 --- src/hardware/serialport/serialport.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index 7694e1ac..884038b4 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -223,7 +223,8 @@ void CSerial::changeLineProperties() { else bitlen = (1000.0f/115200.0f)*(float)baud_divider; bytetime=bitlen*(float)(1+5+1); // startbit + minimum length + stopbit bytetime+= bitlen*(float)(LCR&0x3); // databits - if(LCR&0x4) bytetime+=bitlen; // stopbit + if(LCR&0x4) bytetime+=bitlen; // 2nd stopbit + if(LCR&0x8) bytetime+=bitlen; // parity #if SERIAL_DEBUG const char* const dbgtext[]={"none","odd","none","even","none","mark","none","space"}; From 333da22de66f67eba9d718655e176ec7c376f0b1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 12 Nov 2011 22:14:51 +0000 Subject: [PATCH 3667/4131] Add textmode granulity. Fix cursor handling in mode 0 and 1. Fixes DOOM-IT (thanks ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3757 --- src/ints/mouse.cpp | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 18a62d43..f73ed862 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -50,8 +50,8 @@ struct button_event { #define QUEUE_SIZE 32 #define MOUSE_BUTTONS 3 #define MOUSE_IRQ 12 -#define POS_X ((Bit16s)(mouse.x) & mouse.granMask) -#define POS_Y (Bit16s)(mouse.y) +#define POS_X ((Bit16s)(mouse.x) & mouse.gran_x) +#define POS_Y ((Bit16s)(mouse.y) & mouse.gran_y) #define CURSORX 16 #define CURSORY 16 @@ -125,7 +125,7 @@ static struct { bool timer_in_progress; bool in_UIR; Bit8u mode; - Bit16s granMask; + Bit16s gran_x,gran_y; } mouse; bool Mouse_SetPS2State(bool use) { @@ -255,6 +255,7 @@ void DrawCursorText() { // Save Background mouse.backposx = POS_X>>3; mouse.backposy = POS_Y>>3; + if (mouse.mode < 2) mouse.backposx >>= 1; //use current page (CV program) Bit8u page = real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); @@ -582,43 +583,47 @@ static void Mouse_ResetHardware(void){ //Does way to much. Many things should be moved to mouse reset one day void Mouse_NewVideoMode(void) { - mouse.inhibit_draw=false; + mouse.inhibit_draw = false; /* Get the correct resolution from the current video mode */ - Bit8u mode=mem_readb(BIOS_VIDEO_MODE); + Bit8u mode = mem_readb(BIOS_VIDEO_MODE); if(mode == mouse.mode) {LOG(LOG_MOUSE,LOG_NORMAL)("New video is the same as the old"); /*return;*/} + mouse.gran_x = mouse.gran_y = 0xffff; switch (mode) { case 0x00: case 0x01: case 0x02: - case 0x03: { - Bitu rows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS); - if ((rows==0) || (rows>250)) rows=25-1; - mouse.max_y=8*(rows+1)-1; + case 0x03: + case 0x07: { + mouse.gran_x = (mode<2)?0xfff0:0xfff8; + mouse.gran_y = 0xfff8; + Bitu rows = real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS); + if ((rows == 0) || (rows > 250)) rows = 25 - 1; + mouse.max_y = 8*(rows+1) - 1; break; } case 0x04: case 0x05: case 0x06: - case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0d: case 0x0e: case 0x13: - mouse.max_y=199; + if (mode == 0x0d || mode == 0x13) mouse.gran_x = 0xfffe; + mouse.max_y = 199; break; case 0x0f: case 0x10: - mouse.max_y=349; + mouse.max_y = 349; break; case 0x11: case 0x12: - mouse.max_y=479; + mouse.max_y = 479; break; default: LOG(LOG_MOUSE,LOG_ERROR)("Unhandled videomode %X on reset",mode); - mouse.inhibit_draw=true; + mouse.inhibit_draw = true; return; } mouse.mode = mode; @@ -626,7 +631,6 @@ void Mouse_NewVideoMode(void) { mouse.max_x = 639; mouse.min_x = 0; mouse.min_y = 0; - mouse.granMask = (mode == 0x0d || mode == 0x13) ? 0xfffe : 0xffff; mouse.events = 0; mouse.timer_in_progress = false; From 6f5930ee92037b883be864eb5fc6a236218095df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 17 Nov 2011 23:04:05 +0000 Subject: [PATCH 3668/4131] some warning fixes (fear the msvc) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3758 --- src/dos/drive_cache.cpp | 4 ++-- src/ints/mouse.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 16e1d7c3..24d239ef 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -455,13 +455,13 @@ Bits DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) { // else it's most likely a Wine style short name ABCD~###, # = not dot (length at least 8) // The above test is rather strict as the following loop can be really slow if filelist_size is large. char buff[CROSS_LEN]; - for (Bits i = 0; i < filelist_size; i++) { + for (Bitu i = 0; i < filelist_size; i++) { res = wine_hash_short_file_name(curDir->fileList[i]->orgname,buff); buff[res] = 0; if (!strcmp(shortName,buff)) { // Found strcpy(shortName,curDir->fileList[i]->orgname); - return i; + return (Bits)i; } } #endif diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index f73ed862..21cd651f 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -587,7 +587,8 @@ void Mouse_NewVideoMode(void) { /* Get the correct resolution from the current video mode */ Bit8u mode = mem_readb(BIOS_VIDEO_MODE); if(mode == mouse.mode) {LOG(LOG_MOUSE,LOG_NORMAL)("New video is the same as the old"); /*return;*/} - mouse.gran_x = mouse.gran_y = 0xffff; + mouse.gran_x = (Bit16s)0xffff; + mouse.gran_y = (Bit16s)0xffff; switch (mode) { case 0x00: case 0x01: @@ -595,7 +596,7 @@ void Mouse_NewVideoMode(void) { case 0x03: case 0x07: { mouse.gran_x = (mode<2)?0xfff0:0xfff8; - mouse.gran_y = 0xfff8; + mouse.gran_y = (Bit16s)0xfff8; Bitu rows = real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS); if ((rows == 0) || (rows > 250)) rows = 25 - 1; mouse.max_y = 8*(rows+1) - 1; @@ -610,7 +611,7 @@ void Mouse_NewVideoMode(void) { case 0x0d: case 0x0e: case 0x13: - if (mode == 0x0d || mode == 0x13) mouse.gran_x = 0xfffe; + if (mode == 0x0d || mode == 0x13) mouse.gran_x = (Bit16s)0xfffe; mouse.max_y = 199; break; case 0x0f: From 58920953015b0ae5f1cedfb244ea1dffae98ea51 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 20 Nov 2011 17:32:09 +0000 Subject: [PATCH 3669/4131] Include stddef for offsetof here as well instead of relying on dos_inc.h through programs.h.cpu.cpp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3759 --- src/cpu/cpu.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index da74e8ec..9c9d5668 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -19,6 +19,7 @@ #include #include +#include #include "dosbox.h" #include "cpu.h" #include "memory.h" From f51d4e5b67d91bbcf8163c078cdcbdadaa2fc411 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 20 Nov 2011 17:33:16 +0000 Subject: [PATCH 3670/4131] Include stddef for offsetof here as well instead of relying on dos_inc. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3760 --- src/ints/xms.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 10b53fc7..1d9d2af2 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -19,6 +19,7 @@ #include #include +#include #include "dosbox.h" #include "callback.h" #include "mem.h" From f7ad3ece4e06d52ddcc4d44f075cf200b466ee53 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 23 Nov 2011 12:18:58 +0000 Subject: [PATCH 3671/4131] Improve behavior when reaching the end of the buffer. (thanks ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3761 --- src/dos/dos.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 150dde99..baba3c3b 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -220,6 +220,7 @@ static Bitu DOS_21Handler(void) { Bit8u free=mem_readb(data); Bit8u read=0;Bit8u c;Bit16u n=1; if (!free) break; + free--; for(;;) { DOS_ReadFile(STDIN,&c,&n); if (c == 8) { // Backspace @@ -232,7 +233,7 @@ static Bitu DOS_21Handler(void) { } continue; } - if (read >= free) { // Keyboard buffer full + if (read == free && c != 13) { // Keyboard buffer full Bit8u bell = 7; DOS_WriteFile(STDOUT, &bell, &n); continue; From fd65f6f897933ae501c625295c10bcfe2a847708 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 27 Nov 2011 15:22:00 +0000 Subject: [PATCH 3672/4131] Typos reported by debian project Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3762 --- docs/dosbox.1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dosbox.1 b/docs/dosbox.1 index 407fc23d..73ce2e72 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -216,7 +216,7 @@ either to create a new configfile or languagefile in this mode. 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 . +.RI "more things. It further allows access to " AUTOEXEC.BAT . .LP The language file controls all visible output of the internal commands and the internal dos. @@ -345,7 +345,7 @@ gets saved/recorded ! 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 +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 From fc1ffcc528815c33a24d44b770beaaca87f54ec0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 29 Nov 2011 16:45:45 +0000 Subject: [PATCH 3673/4131] Some typo corrections of the comments. (jomalin) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3763 --- src/cpu/core_dyn_x86/decoder.h | 2 +- src/cpu/core_dynrec.cpp | 2 +- src/cpu/core_dynrec/cache.h | 2 +- src/cpu/core_dynrec/decoder.h | 4 ++-- src/cpu/paging.cpp | 2 +- src/debug/debug.cpp | 8 ++++---- src/debug/debug_gui.cpp | 2 +- src/dos/dev_con.h | 4 ++-- src/dos/dos_files.cpp | 2 +- src/dos/drive_virtual.cpp | 2 +- src/ints/int10_memory.cpp | 2 +- 11 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 80e2299f..a9f90d07 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -2677,7 +2677,7 @@ restart_prefix: goto illegalopcode; } } - // link to next block because the maximal number of opcodes has been reached + // link to next block because the maximum number of opcodes has been reached dyn_set_eip_end(); dyn_reduce_cycles(); dyn_save_critical_regs(); diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index e56d8a2c..ed975f56 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -246,7 +246,7 @@ run_block: // 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 + // or the maximum number of instructions to translate was reached #if C_HEAVY_DEBUG if (DEBUG_HeavyIsBreakpoint()) return debugCallback; #endif diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index 3b1a5984..5c814360 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -53,7 +53,7 @@ public: 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) + } link[2]; // maximum two links (conditional jumps) CacheBlockDynRec * crossblock; }; diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h index 4c7dc6fe..08b52441 100644 --- a/src/cpu/core_dynrec/decoder.h +++ b/src/cpu/core_dynrec/decoder.h @@ -26,7 +26,7 @@ /* The function CreateCacheBlock translates the instruction stream - until either an unhandled instruction is found, the maximal + until either an unhandled instruction is found, the maximum number of translated instructions is reached or some critical instruction is encountered. */ @@ -586,7 +586,7 @@ restart_prefix: goto illegalopcode; } } - // link to next block because the maximal number of opcodes has been reached + // link to next block because the maximum number of opcodes has been reached dyn_set_eip_end(); dyn_reduce_cycles(); gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlockDynRec,cache.start)); diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 7dbff72f..6ac9b664 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -849,7 +849,7 @@ void PAGING_SetDirBase(Bitu cr3) { } void PAGING_Enable(bool enabled) { - /* If paging is disable we work from a default paging table */ + /* If paging is disabled, we work from a default paging table */ if (paging.enabled==enabled) return; paging.enabled=enabled; if (enabled) { diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 992ed4a4..44dc221f 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -412,7 +412,7 @@ void CBreakpoint::ActivateBreakpoints(PhysPt adr, bool activate) }; bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off) -// Checks if breakpoint is valid an should stop execution +// Checks if breakpoint is valid and should stop execution { if ((ignoreAddressOnce!=0) && (GetAddress(seg,off)==ignoreAddressOnce)) { ignoreAddressOnce = 0; @@ -476,7 +476,7 @@ bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off) }; bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue) -// Checks if interrupt breakpoint is valid an should stop execution +// Checks if interrupt breakpoint is valid and should stop execution { if ((ignoreAddressOnce!=0) && (adr==ignoreAddressOnce)) { ignoreAddressOnce = 0; @@ -491,7 +491,7 @@ bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue) bp = (*i); if ((bp->GetType()==BKPNT_INTERRUPT) && bp->IsActive() && (bp->GetIntNr()==intNr)) { if ((bp->GetValue()==BPINT_ALL) || (bp->GetValue()==ahValue)) { - // Ignoie it once ? + // Ignore it once ? if (ignoreOnce==bp) { ignoreOnce=0; bp->Activate(true); @@ -1402,7 +1402,7 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) { // Variable found ? CDebugVar* var = CDebugVar::FindVar(address); if (var) { - // Replace occurance + // Replace occurence char* pos1 = strchr(inst,'['); char* pos2 = strchr(inst,']'); if (pos1 && pos2) { diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index c57872fb..60166d91 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -161,7 +161,7 @@ static void DrawBars(void) { static void MakeSubWindows(void) { - /* The Std output win should go in bottem */ + /* The Std output win should go at the bottom */ /* Make all the subwindows */ int win_main_maxy, win_main_maxx; getmaxyx(dbg.win_main,win_main_maxy,win_main_maxx); int outy=1; //Match values with above diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 39002035..79a6e42c 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -37,7 +37,7 @@ public: private: Bit8u readcache; Bit8u lastwrite; - struct ansi { /* should create a constructor which fills them with the appriorate values */ + struct ansi { /* should create a constructor, which would fill them with the appropriate values */ bool esc; bool sci; bool enabled; @@ -128,7 +128,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { count++; continue; } else { - /* Some sort of "hack" now that \n doesn't set col to 0 (int10_char.cpp old chessgame) */ + /* Some sort of "hack" now that '\n' doesn't set col to 0 (int10_char.cpp old chessgame) */ if((data[count] == '\n') && (lastwrite != '\r')) INT10_TeletypeOutputAttr('\r',ansi.attr,ansi.enabled); /* pass attribute only if ansi is enabled */ INT10_TeletypeOutputAttr(data[count],ansi.attr,ansi.enabled); diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 4a3b26c8..c1574f17 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -299,7 +299,7 @@ bool DOS_Rename(char const * const oldname,char const * const newname) { } if (Drives[drivenew]->Rename(fullold,fullnew)) return true; - /* If it still fails. which error should we give ? PATH NOT FOUND or EACCESS */ + /* If it still fails, which error should we give ? PATH NOT FOUND or EACCESS */ LOG(LOG_FILES,LOG_NORMAL)("Rename fails for %s to %s, no proper errorcode returned.",oldname,newname); DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index c119d873..43bfe8d1 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -101,7 +101,7 @@ bool Virtual_File::Read(Bit8u * data,Bit16u * size) { } bool Virtual_File::Write(Bit8u * data,Bit16u * size){ -/* Not really writeable */ + /* Not really writable */ return false; } diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 7beda20d..47b1afe7 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -154,7 +154,7 @@ void INT10_SetupRomMemory(void) { int10.rom.video_dcc_table=RealMake(0xC000,int10.rom.used); phys_writeb(rom_base+int10.rom.used++,0x10); // number of entries phys_writeb(rom_base+int10.rom.used++,1); // version number - phys_writeb(rom_base+int10.rom.used++,8); // maximal display code + phys_writeb(rom_base+int10.rom.used++,8); // maximum display code phys_writeb(rom_base+int10.rom.used++,0); // reserved // display combination codes phys_writew(rom_base+int10.rom.used,0x0000); int10.rom.used+=2; From a7af902f2f7358681456d068a299e25c3689d09d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 8 Dec 2011 12:47:04 +0000 Subject: [PATCH 3674/4131] Even our comments and status messages have less bugs now (jomalin) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3764 --- src/debug/debug.cpp | 6 +++--- src/gui/sdl_mapper.cpp | 2 +- src/gui/sdlmain.cpp | 2 +- src/hardware/hardware.cpp | 2 +- src/hardware/mixer.cpp | 2 +- src/hardware/serialport/libserial.cpp | 4 ++-- src/hardware/vga_draw.cpp | 2 +- src/hardware/vga_s3.cpp | 2 +- src/ints/bios_disk.cpp | 2 +- src/ints/bios_keyboard.cpp | 4 ++-- src/ints/ems.cpp | 2 +- src/ints/int10.cpp | 2 +- src/ints/int10_memory.cpp | 4 ++-- src/ints/int10_modes.cpp | 2 +- src/ints/int10_pal.cpp | 2 +- src/misc/messages.cpp | 2 +- src/shell/shell.cpp | 6 +++--- src/shell/shell_cmds.cpp | 2 +- src/shell/shell_misc.cpp | 2 +- 19 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 44dc221f..7b76d573 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -402,7 +402,7 @@ void CBreakpoint::ActivateBreakpoints(PhysPt adr, bool activate) CBreakpoint* bp; for(i=BPoints.begin(); i != BPoints.end(); i++) { bp = (*i); - // Do not activate, when bp is an actual adress + // Do not activate, when bp is an actual address if (activate && (bp->GetType()==BKPNT_PHYSICAL) && (bp->GetLocation()==adr)) { // Do not activate :) continue; @@ -681,7 +681,7 @@ static void DrawData(void) { Bit32u address; /* Data win */ for (int y=0; y<8; y++) { - // Adress + // Address if (add<0x10000) mvwprintw (dbg.win_data,1+y,0,"%04X:%04X ",dataSeg,add); else mvwprintw (dbg.win_data,1+y,0,"%04X:%08X ",dataSeg,add); for (int x=0; x<16; x++) { @@ -2424,7 +2424,7 @@ void DEBUG_HeavyWriteLogInstruction(void) { out << hex << noshowbase << setfill('0') << uppercase; Bit32u startLog = logCount; do { - // Write Intructions + // Write Instructions TLogInst & inst = logInst[startLog]; out << setw(4) << inst.s_cs << ":" << setw(8) << inst.eip << " " << inst.dline << " " << inst.res << " EAX:" << setw(8)<< inst.eax diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 7615b19a..82d1baa6 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -2107,7 +2107,7 @@ static void CreateDefaultBinds(void) { } void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char const * const eventname,char const * const buttonname) { - //Check if it allready exists=> if so return. + //Check if it already exists=> if so return. for(CHandlerEventVector_it it=handlergroup.begin();it!=handlergroup.end();it++) if(strcmp((*it)->buttonname,buttonname) == 0) return; diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index d495042e..31a5e458 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1916,7 +1916,7 @@ int main(int argc, char* argv[]) { Section_prop * sdl_sec=static_cast(control->GetSection("sdl")); if (control->cmdline->FindExist("-fullscreen") || sdl_sec->Get_bool("fullscreen")) { - if(!sdl.desktop.fullscreen) { //only switch if not allready in fullscreen + if(!sdl.desktop.fullscreen) { //only switch if not already in fullscreen GFX_SwitchFullScreen(); } } diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index ff7881ce..dcacb089 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -323,7 +323,7 @@ void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags, /* Open the actual file */ FILE * fp=OpenCaptureFile("Screenshot",".png"); if (!fp) goto skip_shot; - /* First try to alloacte the png structures */ + /* First try to allocate the png structures */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL, NULL); if (!png_ptr) goto skip_shot; info_ptr = png_create_info_struct(png_ptr); diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 64c18462..829d99a8 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -601,7 +601,7 @@ MixerChannel* MixerObject::Install(MIXER_Handler handler,Bitu freq,const char * installed = true; return MIXER_AddChannel(handler,freq,name); } else { - E_Exit("allready added mixer channel."); + E_Exit("already added mixer channel."); return 0; //Compiler happy } } diff --git a/src/hardware/serialport/libserial.cpp b/src/hardware/serialport/libserial.cpp index 3f2d52f8..c780e9d1 100644 --- a/src/hardware/serialport/libserial.cpp +++ b/src/hardware/serialport/libserial.cpp @@ -197,7 +197,7 @@ int SERIAL_getextchar(COMPORT port) { char chRead; int retval = 0; - // receive a byte; TODO communicate faliure + // receive a byte; TODO communicate failure if (ReadFile (port->porthandle, &chRead, 1, &dwRead, NULL)) { if (dwRead) { // check for errors @@ -580,7 +580,7 @@ int SERIAL_getextchar(COMPORT port) { char chRead; int retval = 0; - // receive a byte; TODO communicate faliure + // receive a byte; TODO communicate failure if (DosRead(port->porthandle, &chRead, 1, &dwRead) == NO_ERROR) { if (dwRead) { // check for errors; will OS/2 clear the error on reading its data? diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 37dce8ac..e2089371 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -82,7 +82,7 @@ static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart, Bitu line) { //Generate a temporary bitline to calculate the avarage //over bit-2 bit-1 bit bit+1. //Combine this number with the current colour to get - //an unique index in the pallete. Or it with bit 7 as they are stored + //an unique index in the pallette. Or it with bit 7 as they are stored //in the upperpart to keep them from interfering the regular cga stuff for(Bitu x = 0; x < 640; x++) diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index 1de9599e..d79b42bb 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -341,7 +341,7 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) { vga.svga.bank_write = vga.svga.bank_read; VGA_SetupHandlers(); break; - case 0x6b: // BIOS scratchpad: LFB adress + case 0x6b: // BIOS scratchpad: LFB address vga.s3.reg_6b=(Bit8u)val; break; default: diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index f3486045..952987ed 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -104,7 +104,7 @@ void swapInDisks(void) { Bits swapPos = swapPosition; int i; - /* Check to make sure there's atleast one setup image */ + /* Check to make sure that there is at least one setup image */ for(i=0;imode <= 3) diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index a1dc1814..b266ace6 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -98,7 +98,7 @@ static void LoadMessageFile(const char * fname) { strcpy(name,linein+1); /* End of string marker */ } else if (linein[0]=='.') { - /* Replace/Add the string to the internal langaugefile */ + /* Replace/Add the string to the internal languagefile */ /* Remove last newline (marker is \n.\n) */ size_t ll = strlen(string); if(ll && string[ll - 1] == '\n') string[ll - 1] = 0; //Second if should not be needed, but better be safe. diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index a7464a19..62d44aac 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -49,14 +49,14 @@ typedef std::list::iterator auto_it; void VFILE_Remove(const char *name); void AutoexecObject::Install(const std::string &in) { - if(GCC_UNLIKELY(installed)) E_Exit("autoexec: allready created %s",buf.c_str()); + if(GCC_UNLIKELY(installed)) E_Exit("autoexec: already created %s",buf.c_str()); installed = true; buf = in; autoexec_strings.push_back(buf); this->CreateAutoexec(); //autoexec.bat is normally created AUTOEXEC_Init. - //But if we are allready running (first_shell) + //But if we are already running (first_shell) //we have to update the envirionment to display changes if(first_shell) { @@ -77,7 +77,7 @@ void AutoexecObject::Install(const std::string &in) { } void AutoexecObject::InstallBefore(const std::string &in) { - if(GCC_UNLIKELY(installed)) E_Exit("autoexec: allready created %s",buf.c_str()); + if(GCC_UNLIKELY(installed)) E_Exit("autoexec: already created %s",buf.c_str()); installed = true; buf = in; autoexec_strings.push_front(buf); diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 4840c834..5146be19 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -287,7 +287,7 @@ void DOS_Shell::CMD_ECHO(char * args){ args++;//skip first character. either a slash or dot or space size_t len = strlen(args); //TODO check input of else ook nodig is. if(len && args[len - 1] == '\r') { - LOG(LOG_MISC,LOG_WARN)("Hu ? carriage return allready present. Is this possible?"); + LOG(LOG_MISC,LOG_WARN)("Hu ? carriage return already present. Is this possible?"); WriteOut("%s\n",args); } else WriteOut("%s\r\n",args); } diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index faca8a63..a4e528da 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -299,7 +299,7 @@ void DOS_Shell::InputCommand(char * line) { } res=DOS_FindNext(); } - /* Add excutable list to front of completion list. */ + /* Add executable list to front of completion list. */ std::copy(executable.begin(),executable.end(),std::front_inserter(l_completion)); it_completion = l_completion.begin(); dos.dta(save_dta); From 837396cc218f4fedf8408fd0621f072ec210e308 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 8 Dec 2011 12:59:51 +0000 Subject: [PATCH 3675/4131] apply granularity only for stuff reported to the clientmou Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3765 --- src/ints/mouse.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 21cd651f..c74613c2 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -50,8 +50,8 @@ struct button_event { #define QUEUE_SIZE 32 #define MOUSE_BUTTONS 3 #define MOUSE_IRQ 12 -#define POS_X ((Bit16s)(mouse.x) & mouse.gran_x) -#define POS_Y ((Bit16s)(mouse.y) & mouse.gran_y) +#define POS_X (static_cast(mouse.x) & mouse.gran_x) +#define POS_Y (static_cast(mouse.y) & mouse.gran_y) #define CURSORX 16 #define CURSORY 16 @@ -1012,7 +1012,7 @@ static Bitu INT74_Handler(void) { } else if (useps2callback) { CPU_Push16(RealSeg(CALLBACK_RealPointer(int74_ret_callback))); CPU_Push16(RealOff(CALLBACK_RealPointer(int74_ret_callback))); - DoPS2Callback(mouse.event_queue[mouse.events].buttons, POS_X, POS_Y); + DoPS2Callback(mouse.event_queue[mouse.events].buttons, static_cast(mouse.x), static_cast(mouse.y)); } else { SegSet16(cs, RealSeg(CALLBACK_RealPointer(int74_ret_callback))); reg_ip = RealOff(CALLBACK_RealPointer(int74_ret_callback)); From 1b12a9c1a5f63f5aa9cba9230dc3fe9fe8f2251d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 8 Dec 2011 13:06:31 +0000 Subject: [PATCH 3676/4131] be less restrictive. Hope nothing breaks. Fixes AS2. (peterferrie) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3766 --- src/ints/ems.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index bc3fe9c1..f87ecce1 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -489,7 +489,7 @@ static Bit8u EMM_PartialPageMapping(void) { mem_writew(data,segment);data+=2; MEM_BlockWrite(data,&emm_mappings[page],sizeof(EMM_Mapping)); data+=sizeof(EMM_Mapping); - } else if (((segment>=EMM_PAGEFRAME-0x1000) && (segment=0xa000) && (segment<0xb000))) { + } else if ((ems_type==1) || (ems_type==3) || ((segment>=EMM_PAGEFRAME-0x1000) && (segment=0xa000) && (segment<0xb000))) { mem_writew(data,segment);data+=2; MEM_BlockWrite(data,&emm_segmentmappings[segment>>10],sizeof(EMM_Mapping)); data+=sizeof(EMM_Mapping); @@ -506,7 +506,7 @@ static Bit8u EMM_PartialPageMapping(void) { if ((segment>=EMM_PAGEFRAME) && (segment>4); MEM_BlockRead(data,&emm_mappings[page],sizeof(EMM_Mapping)); - } else if (((segment>=EMM_PAGEFRAME-0x1000) && (segment=0xa000) && (segment<0xb000))) { + } else if ((ems_type==1) || (ems_type==3) || ((segment>=EMM_PAGEFRAME-0x1000) && (segment=0xa000) && (segment<0xb000))) { MEM_BlockRead(data,&emm_segmentmappings[segment>>10],sizeof(EMM_Mapping)); } else { return EMM_ILL_PHYS; From 41d307292bef0ec6eb70044e36cd93a1d233b8ec Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 8 Dec 2011 13:08:58 +0000 Subject: [PATCH 3677/4131] Implement 0x7d. Fixed death by dark shadows (ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3767 --- src/hardware/sblaster.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 8e379133..60f6e674 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -871,6 +871,11 @@ static void DSP_DoCommand(void) { case 0x76: /* 074h : Single Cycle 3-bit(2.6bit) ADPCM */ DSP_PrepareDMA_Old(DSP_DMA_3,false,false); break; + case 0x7d: /* Auto Init 4-bit ADPCM Reference */ + DSP_SB2_ABOVE; + sb.adpcm.haveref=true; + DSP_PrepareDMA_Old(DSP_DMA_4,true,false); + break; case 0x17: /* 017h : Single Cycle 2-bit ADPCM Reference*/ sb.adpcm.haveref=true; case 0x16: /* 074h : Single Cycle 2-bit ADPCM */ @@ -996,7 +1001,7 @@ static void DSP_DoCommand(void) { DSP_SB2_ABOVE; LOG(LOG_SB,LOG_ERROR)("DSP:Unimplemented MIDI UART command %2X",sb.dsp.cmd); break; - case 0x7d: case 0x7f: case 0x1f: + case 0x7f: case 0x1f: DSP_SB2_ABOVE; LOG(LOG_SB,LOG_ERROR)("DSP:Unimplemented auto-init DMA ADPCM command %2X",sb.dsp.cmd); break; From 77970d28cdcdeae77caa29a8c49d5188e4477cd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 11 Dec 2011 17:30:50 +0000 Subject: [PATCH 3678/4131] small additions: vga override, lazy fullscreen switching, pci read override Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3768 --- include/pci_bus.h | 7 ++-- include/vga.h | 3 ++ src/gui/sdlmain.cpp | 71 +++++++++++++++++++++++++++++++++++++-- src/hardware/pci_bus.cpp | 6 ++++ src/hardware/vga_draw.cpp | 22 ++++++++++-- 5 files changed, 100 insertions(+), 9 deletions(-) diff --git a/include/pci_bus.h b/include/pci_bus.h index 470114ff..adec2d9b 100644 --- a/include/pci_bus.h +++ b/include/pci_bus.h @@ -61,16 +61,17 @@ public: PCI_Device* GetSubdevice(Bits subfct); Bit16u NumSubdevices(void) { - if (num_subdevices>PCI_MAX_PCIFUNCTIONS-1) return PCI_MAX_PCIFUNCTIONS-1; - return num_subdevices; + if (num_subdevices>PCI_MAX_PCIFUNCTIONS-1) return (Bit16u)(PCI_MAX_PCIFUNCTIONS-1); + return (Bit16u)num_subdevices; } Bits GetNextSubdeviceNumber(void) { if (num_subdevices>=PCI_MAX_PCIFUNCTIONS-1) return -1; - return num_subdevices+1; + return (Bits)num_subdevices+1; } virtual Bits ParseReadRegister(Bit8u regnum)=0; + virtual bool OverrideReadRegister(Bit8u regnum, Bit8u* rval, Bit8u* rval_mask)=0; virtual Bits ParseWriteRegister(Bit8u regnum,Bit8u value)=0; virtual bool InitializeRegisters(Bit8u registers[256])=0; diff --git a/include/vga.h b/include/vga.h index 95aa8f07..6b19e6eb 100644 --- a/include/vga.h +++ b/include/vga.h @@ -166,6 +166,7 @@ typedef struct { } cursor; Drawmode mode; bool vret_triggered; + bool vga_override; } VGA_Draw; typedef struct { @@ -448,6 +449,8 @@ void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3); void VGA_ActivateHardwareCursor(void); void VGA_KillDrawing(void); +void VGA_SetOverride(bool vga_override); + extern VGA_Type vga; /* Support for modular SVGA implementation */ diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 31a5e458..5c5d89b3 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -171,6 +171,8 @@ struct SDL_Block { } window; Bit8u bpp; bool fullscreen; + bool lazy_fullscreen; + bool lazy_fullscreen_req; bool doublebuf; SCREEN_TYPES type; SCREEN_TYPES want_type; @@ -353,6 +355,16 @@ void GFX_ResetScreen(void) { CPU_Reset_AutoAdjust(); } +void GFX_ForceFullscreenExit(void) { + if (sdl.desktop.lazy_fullscreen) { +// sdl.desktop.lazy_fullscreen_req=true; + LOG_MSG("GFX LF: invalid screen change"); + } else { + sdl.desktop.fullscreen=false; + GFX_ResetScreen(); + } +} + static int int_log2 (int val) { int log = 0; while ((val >>= 1) != 0) @@ -405,6 +417,16 @@ static SDL_Surface * GFX_SetupSurfaceScaled(Bit32u sdl_flags, Bit32u bpp) { } } +void GFX_TearDown(void) { + if (sdl.updating) + GFX_EndUpdate( 0 ); + + if (sdl.blit.surface) { + SDL_FreeSurface(sdl.blit.surface); + sdl.blit.surface=0; + } +} + Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_CallBack_t callback) { if (sdl.updating) GFX_EndUpdate( 0 ); @@ -670,6 +692,18 @@ void GFX_CaptureMouse(void) { mouselocked=sdl.mouse.locked; } +void GFX_UpdateSDLCaptureState(void) { + if (sdl.mouse.locked) { + SDL_WM_GrabInput(SDL_GRAB_ON); + SDL_ShowCursor(SDL_DISABLE); + } else { + SDL_WM_GrabInput(SDL_GRAB_OFF); + if (sdl.mouse.autoenable || !sdl.mouse.autolock) SDL_ShowCursor(SDL_ENABLE); + } + CPU_Reset_AutoAdjust(); + GFX_SetTitle(-1,-1,false); +} + bool mouselocked; //Global variable for mapper static void CaptureMouse(bool pressed) { if (!pressed) @@ -718,7 +752,32 @@ void GFX_SwitchFullScreen(void) { static void SwitchFullScreen(bool pressed) { if (!pressed) return; - GFX_SwitchFullScreen(); + + if (sdl.desktop.lazy_fullscreen) { +// sdl.desktop.lazy_fullscreen_req=true; + LOG_MSG("GFX LF: fullscreen switching not supported"); + } else { + GFX_SwitchFullScreen(); + } +} + +void GFX_SwitchLazyFullscreen(bool lazy) { + sdl.desktop.lazy_fullscreen=lazy; + sdl.desktop.lazy_fullscreen_req=false; +} + +void GFX_SwitchFullscreenNoReset(void) { + sdl.desktop.fullscreen=!sdl.desktop.fullscreen; +} + +bool GFX_LazyFullscreenRequested(void) { + if (sdl.desktop.lazy_fullscreen) return sdl.desktop.lazy_fullscreen_req; + return false; +} + +void GFX_RestoreMode(void) { + GFX_SetSize(sdl.draw.width,sdl.draw.height,sdl.draw.flags,sdl.draw.scalex,sdl.draw.scaley,sdl.draw.callback); + GFX_UpdateSDLCaptureState(); } @@ -1035,6 +1094,9 @@ static void GUI_StartUp(Section * sec) { SDL_WM_SetIcon(logos,NULL); #endif + sdl.desktop.lazy_fullscreen=false; + sdl.desktop.lazy_fullscreen_req=false; + sdl.desktop.fullscreen=section->Get_bool("fullscreen"); sdl.wait_on_error=section->Get_bool("waitonerror"); @@ -1339,6 +1401,10 @@ void GFX_LosingFocus(void) { MAPPER_LosingFocus(); } +bool GFX_IsFullscreen(void) { + return sdl.desktop.fullscreen; +} + void GFX_Events() { SDL_Event event; #if defined (REDUCE_JOYSTICK_POLLING) @@ -1364,8 +1430,7 @@ void GFX_Events() { #ifdef WIN32 if (sdl.desktop.fullscreen) { VGA_KillDrawing(); - sdl.desktop.fullscreen=false; - GFX_ResetScreen(); + GFX_ForceFullscreenExit(); } #endif GFX_CaptureMouse(); diff --git a/src/hardware/pci_bus.cpp b/src/hardware/pci_bus.cpp index f958cda2..43634ff9 100644 --- a/src/hardware/pci_bus.cpp +++ b/src/hardware/pci_bus.cpp @@ -131,6 +131,12 @@ static Bit8u read_pci_register(PCI_Device* dev,Bit8u regnum) { if ((parsed_regnum>=0) && (parsed_regnum<256)) return pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][parsed_regnum]; + Bit8u newval, mask; + if (dev->OverrideReadRegister(regnum, &newval, &mask)) { + Bit8u oldval=pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][regnum] & (~mask); + return oldval | (newval & mask); + } + return 0xff; } diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index e2089371..e4a57ef4 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -825,7 +825,7 @@ static void VGA_VerticalTimer(Bitu /*val*/) { break; } //Check if we can actually render, else skip the rest (frameskip) - if (!RENDER_StartUpdate()) + if (vga.draw.vga_override || !RENDER_StartUpdate()) return; vga.draw.address_line = vga.config.hlines_skip; @@ -1557,7 +1557,9 @@ void VGA_SetupDrawing(Bitu /*val*/) { LOG(LOG_VGA,LOG_NORMAL)("%s width, %s height aspect %f", doublewidth ? "double":"normal",doubleheight ? "double":"normal",aspect_ratio); #endif - RENDER_SetSize(width,height,bpp,(float)fps,aspect_ratio,doublewidth,doubleheight); + if (!vga.draw.vga_override) + RENDER_SetSize(width, height, bpp, (float)fps, aspect_ratio, + doublewidth, doubleheight); } } @@ -1567,5 +1569,19 @@ void VGA_KillDrawing(void) { PIC_RemoveEvents(VGA_DrawEGASingleLine); vga.draw.parts_left = 0; vga.draw.lines_done = ~0; - RENDER_EndUpdate(true); + if (!vga.draw.vga_override) RENDER_EndUpdate(true); +} + +void VGA_SetOverride(bool vga_override) { + if (vga.draw.vga_override!=vga_override) { + + if (vga_override) { + VGA_KillDrawing(); + vga.draw.vga_override=true; + } else { + vga.draw.vga_override=false; + vga.draw.width=0; // change it so the output window gets updated + VGA_SetupDrawing(0); + } + } } From b148583132cbbbb91bdd9f282a396e2cb36afd33 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 18 Dec 2011 19:23:56 +0000 Subject: [PATCH 3679/4131] Add properties Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3769 --- include/pci_bus.h | 172 +++---- src/hardware/pci_bus.cpp | 888 ++++++++++++++++++------------------- src/hardware/pci_devices.h | 36 +- 3 files changed, 548 insertions(+), 548 deletions(-) diff --git a/include/pci_bus.h b/include/pci_bus.h index adec2d9b..2dadfa06 100644 --- a/include/pci_bus.h +++ b/include/pci_bus.h @@ -1,86 +1,86 @@ -/* - * Copyright (C) 2002-2011 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_PCI_H -#define DOSBOX_PCI_H - -//#define PCI_FUNCTIONALITY_ENABLED 0 - -#if defined PCI_FUNCTIONALITY_ENABLED - -#define PCI_MAX_PCIDEVICES 10 -#define PCI_MAX_PCIFUNCTIONS 8 - - -class PCI_Device { -private: - Bits pci_id, pci_subfunction; - Bit16u vendor_id, device_id; - - // subdevices declarations, they will respond to pci functions 1 to 7 - // (main device is attached to function 0) - Bitu num_subdevices; - PCI_Device* subdevices[PCI_MAX_PCIFUNCTIONS-1]; - -public: - PCI_Device(Bit16u vendor, Bit16u device); - - Bits PCIId(void) { - return pci_id; - } - Bits PCISubfunction(void) { - return pci_subfunction; - } - Bit16u VendorID(void) { - return vendor_id; - } - Bit16u DeviceID(void) { - return device_id; - } - - void SetPCIId(Bitu number, Bits subfct); - - bool AddSubdevice(PCI_Device* dev); - void RemoveSubdevice(Bits subfct); - - PCI_Device* GetSubdevice(Bits subfct); - - Bit16u NumSubdevices(void) { - if (num_subdevices>PCI_MAX_PCIFUNCTIONS-1) return (Bit16u)(PCI_MAX_PCIFUNCTIONS-1); - return (Bit16u)num_subdevices; - } - - Bits GetNextSubdeviceNumber(void) { - if (num_subdevices>=PCI_MAX_PCIFUNCTIONS-1) return -1; - return (Bits)num_subdevices+1; - } - - virtual Bits ParseReadRegister(Bit8u regnum)=0; - virtual bool OverrideReadRegister(Bit8u regnum, Bit8u* rval, Bit8u* rval_mask)=0; - virtual Bits ParseWriteRegister(Bit8u regnum,Bit8u value)=0; - virtual bool InitializeRegisters(Bit8u registers[256])=0; - -}; - -bool PCI_IsInitialized(); - -RealPt PCI_GetPModeInterface(void); - -#endif - -#endif +/* + * Copyright (C) 2002-2011 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_PCI_H +#define DOSBOX_PCI_H + +//#define PCI_FUNCTIONALITY_ENABLED 0 + +#if defined PCI_FUNCTIONALITY_ENABLED + +#define PCI_MAX_PCIDEVICES 10 +#define PCI_MAX_PCIFUNCTIONS 8 + + +class PCI_Device { +private: + Bits pci_id, pci_subfunction; + Bit16u vendor_id, device_id; + + // subdevices declarations, they will respond to pci functions 1 to 7 + // (main device is attached to function 0) + Bitu num_subdevices; + PCI_Device* subdevices[PCI_MAX_PCIFUNCTIONS-1]; + +public: + PCI_Device(Bit16u vendor, Bit16u device); + + Bits PCIId(void) { + return pci_id; + } + Bits PCISubfunction(void) { + return pci_subfunction; + } + Bit16u VendorID(void) { + return vendor_id; + } + Bit16u DeviceID(void) { + return device_id; + } + + void SetPCIId(Bitu number, Bits subfct); + + bool AddSubdevice(PCI_Device* dev); + void RemoveSubdevice(Bits subfct); + + PCI_Device* GetSubdevice(Bits subfct); + + Bit16u NumSubdevices(void) { + if (num_subdevices>PCI_MAX_PCIFUNCTIONS-1) return (Bit16u)(PCI_MAX_PCIFUNCTIONS-1); + return (Bit16u)num_subdevices; + } + + Bits GetNextSubdeviceNumber(void) { + if (num_subdevices>=PCI_MAX_PCIFUNCTIONS-1) return -1; + return (Bits)num_subdevices+1; + } + + virtual Bits ParseReadRegister(Bit8u regnum)=0; + virtual bool OverrideReadRegister(Bit8u regnum, Bit8u* rval, Bit8u* rval_mask)=0; + virtual Bits ParseWriteRegister(Bit8u regnum,Bit8u value)=0; + virtual bool InitializeRegisters(Bit8u registers[256])=0; + +}; + +bool PCI_IsInitialized(); + +RealPt PCI_GetPModeInterface(void); + +#endif + +#endif diff --git a/src/hardware/pci_bus.cpp b/src/hardware/pci_bus.cpp index 43634ff9..88c402a4 100644 --- a/src/hardware/pci_bus.cpp +++ b/src/hardware/pci_bus.cpp @@ -1,444 +1,444 @@ -/* - * Copyright (C) 2002-2011 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" -#include "inout.h" -#include "mem.h" -#include "pci_bus.h" -#include "setup.h" -#include "debug.h" -#include "callback.h" -#include "regs.h" - - -#if defined(PCI_FUNCTIONALITY_ENABLED) - -static Bit32u pci_caddress=0; // current PCI addressing -static Bitu pci_devices_installed=0; // number of registered PCI devices - -static Bit8u pci_cfg_data[PCI_MAX_PCIDEVICES][PCI_MAX_PCIFUNCTIONS][256]; // PCI configuration data -static PCI_Device* pci_devices[PCI_MAX_PCIDEVICES]; // registered PCI devices - - -// PCI address -// 31 - set for a PCI access -// 30-24 - 0 -// 23-16 - bus number (0x00ff0000) -// 15-11 - device number (slot) (0x0000f800) -// 10- 8 - subfunction number (0x00000700) -// 7- 2 - config register # (0x000000fc) - -static void write_pci_addr(Bitu port,Bitu val,Bitu iolen) { - LOG(LOG_PCI,LOG_NORMAL)("Write PCI address :=%x",val); - pci_caddress=val; -} - -static void write_pci_register(PCI_Device* dev,Bit8u regnum,Bit8u value) { - // vendor/device/class IDs/header type/etc. are read-only - if ((regnum<0x04) || ((regnum>=0x06) && (regnum<0x0c)) || (regnum==0x0e)) return; - if (dev==NULL) return; - switch (pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][0x0e]&0x7f) { // header-type specific handling - case 0x00: - if ((regnum>=0x28) && (regnum<0x30)) return; // subsystem information is read-only - break; - case 0x01: - case 0x02: - default: - break; - } - - // call device routine for special actions and the - // possibility to discard/replace the value that is to be written - Bits parsed_register=dev->ParseWriteRegister(regnum,value); - if (parsed_register>=0) - pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][regnum]=(Bit8u)(parsed_register&0xff); -} - -static void write_pci(Bitu port,Bitu val,Bitu iolen) { - LOG(LOG_PCI,LOG_NORMAL)("Write PCI data :=%x (len %d)",port,val,iolen); - - // check for enabled/bus 0 - if ((pci_caddress & 0x80ff0000) == 0x80000000) { - Bit8u devnum = (Bit8u)((pci_caddress >> 11) & 0x1f); - Bit8u fctnum = (Bit8u)((pci_caddress >> 8) & 0x7); - Bit8u regnum = (Bit8u)((pci_caddress & 0xfc) + (port & 0x03)); - LOG(LOG_PCI,LOG_NORMAL)(" Write to device %x register %x (function %x) (:=%x)",devnum,regnum,fctnum,val); - - if (devnum>=pci_devices_installed) return; - PCI_Device* masterdev=pci_devices[devnum]; - if (masterdev==NULL) return; - if (fctnum>masterdev->NumSubdevices()) return; - - PCI_Device* dev=masterdev->GetSubdevice(fctnum); - if (dev==NULL) return; - - // write data to PCI device/configuration - switch (iolen) { - case 1: write_pci_register(dev,regnum+0,(Bit8u)(val&0xff)); break; - case 2: write_pci_register(dev,regnum+0,(Bit8u)(val&0xff)); - write_pci_register(dev,regnum+1,(Bit8u)((val>>8)&0xff)); break; - case 4: write_pci_register(dev,regnum+0,(Bit8u)(val&0xff)); - write_pci_register(dev,regnum+1,(Bit8u)((val>>8)&0xff)); - write_pci_register(dev,regnum+2,(Bit8u)((val>>16)&0xff)); - write_pci_register(dev,regnum+3,(Bit8u)((val>>24)&0xff)); break; - } - } -} - - -static Bitu read_pci_addr(Bitu port,Bitu iolen) { - LOG(LOG_PCI,LOG_NORMAL)("Read PCI address -> %x",pci_caddress); - return pci_caddress; -} - -// read single 8bit value from register file (special register treatment included) -static Bit8u read_pci_register(PCI_Device* dev,Bit8u regnum) { - switch (regnum) { - case 0x00: - return (Bit8u)(dev->VendorID()&0xff); - case 0x01: - return (Bit8u)((dev->VendorID()>>8)&0xff); - case 0x02: - return (Bit8u)(dev->DeviceID()&0xff); - case 0x03: - return (Bit8u)((dev->DeviceID()>>8)&0xff); - - case 0x0e: - return (pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][regnum]&0x7f) | - ((dev->NumSubdevices()>0)?0x80:0x00); - default: - break; - } - - // call device routine for special actions and possibility to discard/remap register - Bits parsed_regnum=dev->ParseReadRegister(regnum); - if ((parsed_regnum>=0) && (parsed_regnum<256)) - return pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][parsed_regnum]; - - Bit8u newval, mask; - if (dev->OverrideReadRegister(regnum, &newval, &mask)) { - Bit8u oldval=pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][regnum] & (~mask); - return oldval | (newval & mask); - } - - return 0xff; -} - -static Bitu read_pci(Bitu port,Bitu iolen) { - LOG(LOG_PCI,LOG_NORMAL)("Read PCI data -> %x",pci_caddress); - - if ((pci_caddress & 0x80ff0000) == 0x80000000) { - Bit8u devnum = (Bit8u)((pci_caddress >> 11) & 0x1f); - Bit8u fctnum = (Bit8u)((pci_caddress >> 8) & 0x7); - Bit8u regnum = (Bit8u)((pci_caddress & 0xfc) + (port & 0x03)); - if (devnum>=pci_devices_installed) return 0xffffffff; - LOG(LOG_PCI,LOG_NORMAL)(" Read from device %x register %x (function %x); addr %x", - devnum,regnum,fctnum,pci_caddress); - - PCI_Device* masterdev=pci_devices[devnum]; - if (masterdev==NULL) return 0xffffffff; - if (fctnum>masterdev->NumSubdevices()) return 0xffffffff; - - PCI_Device* dev=masterdev->GetSubdevice(fctnum); - - if (dev!=NULL) { - switch (iolen) { - case 1: - { - Bit8u val8=read_pci_register(dev,regnum); - return val8; - } - case 2: - { - Bit16u val16=read_pci_register(dev,regnum); - val16|=(read_pci_register(dev,regnum+1)<<8); - return val16; - } - case 4: - { - Bit32u val32=read_pci_register(dev,regnum); - val32|=(read_pci_register(dev,regnum+1)<<8); - val32|=(read_pci_register(dev,regnum+2)<<16); - val32|=(read_pci_register(dev,regnum+3)<<24); - return val32; - } - default: - break; - } - } - } - return 0xffffffff; -} - - -static Bitu PCI_PM_Handler() { - LOG_MSG("PCI PMode handler, function %x",reg_ax); - return CBRET_NONE; -} - - -PCI_Device::PCI_Device(Bit16u vendor, Bit16u device) { - pci_id=-1; - pci_subfunction=-1; - vendor_id=vendor; - device_id=device; - num_subdevices=0; - for (Bitu dct=0;dct=0) && (number=0) && (subfct0) && (subfctNumSubdevices()) { - delete subdevices[subfct-1]; - subdevices[subfct-1]=NULL; - // should adjust things like num_subdevices as well... - } - } -} - -PCI_Device* PCI_Device::GetSubdevice(Bits subfct) { - if (subfct>=PCI_MAX_PCIFUNCTIONS) return NULL; - if (subfct>0) { - if (subfct<=this->NumSubdevices()) return subdevices[subfct-1]; - } else if (subfct==0) { - return this; - } - return NULL; -} - - -// queued devices (PCI device registering requested before the PCI framework was initialized) -static const Bitu max_rqueued_devices=16; -static Bitu num_rqueued_devices=0; -static PCI_Device* rqueued_devices[max_rqueued_devices]; - - -#include "pci_devices.h" - -class PCI:public Module_base{ -private: - bool initialized; - -protected: - IO_WriteHandleObject PCI_WriteHandler[5]; - IO_ReadHandleObject PCI_ReadHandler[5]; - - CALLBACK_HandlerObject callback_pci; - -public: - - PhysPt GetPModeCallbackPointer(void) { - return Real2Phys(callback_pci.Get_RealPointer()); - } - - bool IsInitialized(void) { - return initialized; - } - - // set up port handlers and configuration data - void InitializePCI(void) { - // install PCI-addressing ports - PCI_WriteHandler[0].Install(0xcf8,write_pci_addr,IO_MD); - PCI_ReadHandler[0].Install(0xcf8,read_pci_addr,IO_MD); - // install PCI-register read/write handlers - for (Bitu ct=0;ct<4;ct++) { - PCI_WriteHandler[1+ct].Install(0xcfc+ct,write_pci,IO_MB); - PCI_ReadHandler[1+ct].Install(0xcfc+ct,read_pci,IO_MB); - } - - for (Bitu dev=0; dev=0) { - // specific slot specified, basic check for validity - if (slot>=PCI_MAX_PCIDEVICES) return -1; - } else { - // auto-add to new slot, check if one is still free - if (pci_devices_installed>=PCI_MAX_PCIDEVICES) return -1; - } - - if (!initialized) InitializePCI(); - - if (slot<0) slot=pci_devices_installed; // use next slot - Bits subfunction=0; // main device unless specific already-occupied slot is requested - if (pci_devices[slot]!=NULL) { - subfunction=pci_devices[slot]->GetNextSubdeviceNumber(); - if (subfunction<0) E_Exit("Too many PCI subdevices!"); - } - - if (device->InitializeRegisters(pci_cfg_data[slot][subfunction])) { - device->SetPCIId(slot, subfunction); - if (pci_devices[slot]==NULL) { - pci_devices[slot]=device; - pci_devices_installed++; - } else { - pci_devices[slot]->AddSubdevice(device); - } - - return slot; - } - - return -1; - } - - void Deinitialize(void) { - initialized=false; - pci_devices_installed=0; - num_rqueued_devices=0; - pci_caddress=0; - - for (Bitu dev=0; devNumSubdevices()>0) { - for (Bitu sct=1;sctGetSubdevice(sct); - if (sdev!=NULL) { - if ((sdev->VendorID()==vendor_id) && (sdev->DeviceID()==device_id)) { - pci_devices[dct]->RemoveSubdevice(sct); - } - } - } - } - - if ((pci_devices[dct]->VendorID()==vendor_id) && (pci_devices[dct]->DeviceID()==device_id)) { - delete pci_devices[dct]; - pci_devices[dct]=NULL; - } - } - } - - // check if all devices have been removed - bool any_device_left=false; - for (Bitu dct=0;dct=pci_devices_installed) break; - if (pci_devices[dct]!=NULL) { - any_device_left=true; - break; - } - } - if (!any_device_left) Deinitialize(); - - Bitu last_active_device=PCI_MAX_PCIDEVICES; - for (Bitu dct=0;dct0) { - // register all devices that have been added before the PCI bus was instantiated - for (Bitu dct=0;dctRegisterPCIDevice(rqueued_devices[dct]); - } - num_rqueued_devices=0; - } - } - - ~PCI(){ - initialized=false; - pci_devices_installed=0; - num_rqueued_devices=0; - } - -}; - -static PCI* pci_interface=NULL; - - -PhysPt PCI_GetPModeInterface(void) { - if (pci_interface) { - return pci_interface->GetPModeCallbackPointer(); - } - return 0; -} - -bool PCI_IsInitialized() { - if (pci_interface) return pci_interface->IsInitialized(); - return false; -} - - -void PCI_ShutDown(Section* sec){ - delete pci_interface; - pci_interface=NULL; -} - -void PCI_Init(Section* sec) { - pci_interface = new PCI(sec); - sec->AddDestroyFunction(&PCI_ShutDown,false); -} - -#endif +/* + * Copyright (C) 2002-2011 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" +#include "inout.h" +#include "mem.h" +#include "pci_bus.h" +#include "setup.h" +#include "debug.h" +#include "callback.h" +#include "regs.h" + + +#if defined(PCI_FUNCTIONALITY_ENABLED) + +static Bit32u pci_caddress=0; // current PCI addressing +static Bitu pci_devices_installed=0; // number of registered PCI devices + +static Bit8u pci_cfg_data[PCI_MAX_PCIDEVICES][PCI_MAX_PCIFUNCTIONS][256]; // PCI configuration data +static PCI_Device* pci_devices[PCI_MAX_PCIDEVICES]; // registered PCI devices + + +// PCI address +// 31 - set for a PCI access +// 30-24 - 0 +// 23-16 - bus number (0x00ff0000) +// 15-11 - device number (slot) (0x0000f800) +// 10- 8 - subfunction number (0x00000700) +// 7- 2 - config register # (0x000000fc) + +static void write_pci_addr(Bitu port,Bitu val,Bitu iolen) { + LOG(LOG_PCI,LOG_NORMAL)("Write PCI address :=%x",val); + pci_caddress=val; +} + +static void write_pci_register(PCI_Device* dev,Bit8u regnum,Bit8u value) { + // vendor/device/class IDs/header type/etc. are read-only + if ((regnum<0x04) || ((regnum>=0x06) && (regnum<0x0c)) || (regnum==0x0e)) return; + if (dev==NULL) return; + switch (pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][0x0e]&0x7f) { // header-type specific handling + case 0x00: + if ((regnum>=0x28) && (regnum<0x30)) return; // subsystem information is read-only + break; + case 0x01: + case 0x02: + default: + break; + } + + // call device routine for special actions and the + // possibility to discard/replace the value that is to be written + Bits parsed_register=dev->ParseWriteRegister(regnum,value); + if (parsed_register>=0) + pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][regnum]=(Bit8u)(parsed_register&0xff); +} + +static void write_pci(Bitu port,Bitu val,Bitu iolen) { + LOG(LOG_PCI,LOG_NORMAL)("Write PCI data :=%x (len %d)",port,val,iolen); + + // check for enabled/bus 0 + if ((pci_caddress & 0x80ff0000) == 0x80000000) { + Bit8u devnum = (Bit8u)((pci_caddress >> 11) & 0x1f); + Bit8u fctnum = (Bit8u)((pci_caddress >> 8) & 0x7); + Bit8u regnum = (Bit8u)((pci_caddress & 0xfc) + (port & 0x03)); + LOG(LOG_PCI,LOG_NORMAL)(" Write to device %x register %x (function %x) (:=%x)",devnum,regnum,fctnum,val); + + if (devnum>=pci_devices_installed) return; + PCI_Device* masterdev=pci_devices[devnum]; + if (masterdev==NULL) return; + if (fctnum>masterdev->NumSubdevices()) return; + + PCI_Device* dev=masterdev->GetSubdevice(fctnum); + if (dev==NULL) return; + + // write data to PCI device/configuration + switch (iolen) { + case 1: write_pci_register(dev,regnum+0,(Bit8u)(val&0xff)); break; + case 2: write_pci_register(dev,regnum+0,(Bit8u)(val&0xff)); + write_pci_register(dev,regnum+1,(Bit8u)((val>>8)&0xff)); break; + case 4: write_pci_register(dev,regnum+0,(Bit8u)(val&0xff)); + write_pci_register(dev,regnum+1,(Bit8u)((val>>8)&0xff)); + write_pci_register(dev,regnum+2,(Bit8u)((val>>16)&0xff)); + write_pci_register(dev,regnum+3,(Bit8u)((val>>24)&0xff)); break; + } + } +} + + +static Bitu read_pci_addr(Bitu port,Bitu iolen) { + LOG(LOG_PCI,LOG_NORMAL)("Read PCI address -> %x",pci_caddress); + return pci_caddress; +} + +// read single 8bit value from register file (special register treatment included) +static Bit8u read_pci_register(PCI_Device* dev,Bit8u regnum) { + switch (regnum) { + case 0x00: + return (Bit8u)(dev->VendorID()&0xff); + case 0x01: + return (Bit8u)((dev->VendorID()>>8)&0xff); + case 0x02: + return (Bit8u)(dev->DeviceID()&0xff); + case 0x03: + return (Bit8u)((dev->DeviceID()>>8)&0xff); + + case 0x0e: + return (pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][regnum]&0x7f) | + ((dev->NumSubdevices()>0)?0x80:0x00); + default: + break; + } + + // call device routine for special actions and possibility to discard/remap register + Bits parsed_regnum=dev->ParseReadRegister(regnum); + if ((parsed_regnum>=0) && (parsed_regnum<256)) + return pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][parsed_regnum]; + + Bit8u newval, mask; + if (dev->OverrideReadRegister(regnum, &newval, &mask)) { + Bit8u oldval=pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][regnum] & (~mask); + return oldval | (newval & mask); + } + + return 0xff; +} + +static Bitu read_pci(Bitu port,Bitu iolen) { + LOG(LOG_PCI,LOG_NORMAL)("Read PCI data -> %x",pci_caddress); + + if ((pci_caddress & 0x80ff0000) == 0x80000000) { + Bit8u devnum = (Bit8u)((pci_caddress >> 11) & 0x1f); + Bit8u fctnum = (Bit8u)((pci_caddress >> 8) & 0x7); + Bit8u regnum = (Bit8u)((pci_caddress & 0xfc) + (port & 0x03)); + if (devnum>=pci_devices_installed) return 0xffffffff; + LOG(LOG_PCI,LOG_NORMAL)(" Read from device %x register %x (function %x); addr %x", + devnum,regnum,fctnum,pci_caddress); + + PCI_Device* masterdev=pci_devices[devnum]; + if (masterdev==NULL) return 0xffffffff; + if (fctnum>masterdev->NumSubdevices()) return 0xffffffff; + + PCI_Device* dev=masterdev->GetSubdevice(fctnum); + + if (dev!=NULL) { + switch (iolen) { + case 1: + { + Bit8u val8=read_pci_register(dev,regnum); + return val8; + } + case 2: + { + Bit16u val16=read_pci_register(dev,regnum); + val16|=(read_pci_register(dev,regnum+1)<<8); + return val16; + } + case 4: + { + Bit32u val32=read_pci_register(dev,regnum); + val32|=(read_pci_register(dev,regnum+1)<<8); + val32|=(read_pci_register(dev,regnum+2)<<16); + val32|=(read_pci_register(dev,regnum+3)<<24); + return val32; + } + default: + break; + } + } + } + return 0xffffffff; +} + + +static Bitu PCI_PM_Handler() { + LOG_MSG("PCI PMode handler, function %x",reg_ax); + return CBRET_NONE; +} + + +PCI_Device::PCI_Device(Bit16u vendor, Bit16u device) { + pci_id=-1; + pci_subfunction=-1; + vendor_id=vendor; + device_id=device; + num_subdevices=0; + for (Bitu dct=0;dct=0) && (number=0) && (subfct0) && (subfctNumSubdevices()) { + delete subdevices[subfct-1]; + subdevices[subfct-1]=NULL; + // should adjust things like num_subdevices as well... + } + } +} + +PCI_Device* PCI_Device::GetSubdevice(Bits subfct) { + if (subfct>=PCI_MAX_PCIFUNCTIONS) return NULL; + if (subfct>0) { + if (subfct<=this->NumSubdevices()) return subdevices[subfct-1]; + } else if (subfct==0) { + return this; + } + return NULL; +} + + +// queued devices (PCI device registering requested before the PCI framework was initialized) +static const Bitu max_rqueued_devices=16; +static Bitu num_rqueued_devices=0; +static PCI_Device* rqueued_devices[max_rqueued_devices]; + + +#include "pci_devices.h" + +class PCI:public Module_base{ +private: + bool initialized; + +protected: + IO_WriteHandleObject PCI_WriteHandler[5]; + IO_ReadHandleObject PCI_ReadHandler[5]; + + CALLBACK_HandlerObject callback_pci; + +public: + + PhysPt GetPModeCallbackPointer(void) { + return Real2Phys(callback_pci.Get_RealPointer()); + } + + bool IsInitialized(void) { + return initialized; + } + + // set up port handlers and configuration data + void InitializePCI(void) { + // install PCI-addressing ports + PCI_WriteHandler[0].Install(0xcf8,write_pci_addr,IO_MD); + PCI_ReadHandler[0].Install(0xcf8,read_pci_addr,IO_MD); + // install PCI-register read/write handlers + for (Bitu ct=0;ct<4;ct++) { + PCI_WriteHandler[1+ct].Install(0xcfc+ct,write_pci,IO_MB); + PCI_ReadHandler[1+ct].Install(0xcfc+ct,read_pci,IO_MB); + } + + for (Bitu dev=0; dev=0) { + // specific slot specified, basic check for validity + if (slot>=PCI_MAX_PCIDEVICES) return -1; + } else { + // auto-add to new slot, check if one is still free + if (pci_devices_installed>=PCI_MAX_PCIDEVICES) return -1; + } + + if (!initialized) InitializePCI(); + + if (slot<0) slot=pci_devices_installed; // use next slot + Bits subfunction=0; // main device unless specific already-occupied slot is requested + if (pci_devices[slot]!=NULL) { + subfunction=pci_devices[slot]->GetNextSubdeviceNumber(); + if (subfunction<0) E_Exit("Too many PCI subdevices!"); + } + + if (device->InitializeRegisters(pci_cfg_data[slot][subfunction])) { + device->SetPCIId(slot, subfunction); + if (pci_devices[slot]==NULL) { + pci_devices[slot]=device; + pci_devices_installed++; + } else { + pci_devices[slot]->AddSubdevice(device); + } + + return slot; + } + + return -1; + } + + void Deinitialize(void) { + initialized=false; + pci_devices_installed=0; + num_rqueued_devices=0; + pci_caddress=0; + + for (Bitu dev=0; devNumSubdevices()>0) { + for (Bitu sct=1;sctGetSubdevice(sct); + if (sdev!=NULL) { + if ((sdev->VendorID()==vendor_id) && (sdev->DeviceID()==device_id)) { + pci_devices[dct]->RemoveSubdevice(sct); + } + } + } + } + + if ((pci_devices[dct]->VendorID()==vendor_id) && (pci_devices[dct]->DeviceID()==device_id)) { + delete pci_devices[dct]; + pci_devices[dct]=NULL; + } + } + } + + // check if all devices have been removed + bool any_device_left=false; + for (Bitu dct=0;dct=pci_devices_installed) break; + if (pci_devices[dct]!=NULL) { + any_device_left=true; + break; + } + } + if (!any_device_left) Deinitialize(); + + Bitu last_active_device=PCI_MAX_PCIDEVICES; + for (Bitu dct=0;dct0) { + // register all devices that have been added before the PCI bus was instantiated + for (Bitu dct=0;dctRegisterPCIDevice(rqueued_devices[dct]); + } + num_rqueued_devices=0; + } + } + + ~PCI(){ + initialized=false; + pci_devices_installed=0; + num_rqueued_devices=0; + } + +}; + +static PCI* pci_interface=NULL; + + +PhysPt PCI_GetPModeInterface(void) { + if (pci_interface) { + return pci_interface->GetPModeCallbackPointer(); + } + return 0; +} + +bool PCI_IsInitialized() { + if (pci_interface) return pci_interface->IsInitialized(); + return false; +} + + +void PCI_ShutDown(Section* sec){ + delete pci_interface; + pci_interface=NULL; +} + +void PCI_Init(Section* sec) { + pci_interface = new PCI(sec); + sec->AddDestroyFunction(&PCI_ShutDown,false); +} + +#endif diff --git a/src/hardware/pci_devices.h b/src/hardware/pci_devices.h index 9a026807..72a73fc4 100644 --- a/src/hardware/pci_devices.h +++ b/src/hardware/pci_devices.h @@ -1,18 +1,18 @@ -/* - * Copyright (C) 2002-2011 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. - */ - +/* + * Copyright (C) 2002-2011 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. + */ + From 5062d2f4ad35ae550765e978721254ebd97656aa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 28 Dec 2011 11:36:44 +0000 Subject: [PATCH 3680/4131] Improve handling of prefix 0xf in the debugger. Thanks ripsaw Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3770 --- src/debug/debug_disasm.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/debug/debug_disasm.cpp b/src/debug/debug_disasm.cpp index f1e2deed..6d8d5bc8 100644 --- a/src/debug/debug_disasm.cpp +++ b/src/debug/debug_disasm.cpp @@ -949,7 +949,9 @@ static void percent(char type, char subtype) break; case '2': /* old [pop cs]! now indexes */ - ua_str(second[getbyte()]); /* instructions in 386/486 */ + c = getbyte(); + wordop = c & 1; + ua_str(second[c]); /* instructions in 386/486 */ break; case 'g': /* modrm group `subtype' (0--7) */ From 8749c42829cfdbdd9b52cfff4b4c99aa77c54264 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 2 Jan 2012 11:14:55 +0000 Subject: [PATCH 3681/4131] Treat : as seperater (for goto:label) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3771 --- src/shell/shell_cmds.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 5146be19..6f013ed7 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -123,11 +123,12 @@ void DOS_Shell::DoCommand(char * line) { char cmd_buffer[CMD_MAXLINE]; char * cmd_write=cmd_buffer; while (*line) { - if (*line==32) break; - if (*line=='/') break; - if (*line=='\t') break; - if (*line=='=') break; - if ((*line=='.') ||(*line =='\\')) { //allow stuff like cd.. and dir.exe cd\kees + if (*line == 32) break; + if (*line == '/') break; + if (*line == '\t') break; + if (*line == '=') break; + if (*line == ':') break; + if ((*line == '.') ||(*line == '\\')) { //allow stuff like cd.. and dir.exe cd\kees *cmd_write=0; Bit32u cmd_index=0; while (cmd_list[cmd_index].name) { From b30d51f8f8345fc1f7926812a2baf80bef1a5204 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 3 Jan 2012 16:21:23 +0000 Subject: [PATCH 3682/4131] Should make DOSBox usage easier to spot. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3772 --- src/hardware/hardware.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index dcacb089..143d8b90 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -359,6 +359,20 @@ void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); } +#ifdef PNG_TEXT_SUPPORTED + int fields = 1; + png_text text[1]; + const char* text_s = "DOSBox " VERSION; + size_t strl = strlen(text_s); + char* ptext_s = new char[strl + 1]; + strcpy(ptext_s, text_s); + char software[9] = { 'S','o','f','t','w','a','r','e',0}; + text[0].compression = PNG_TEXT_COMPRESSION_NONE; + text[0].key = software; + text[0].text = ptext_s; + png_set_text(png_ptr, info_ptr, text, fields); + delete [] ptext_s; +#endif png_write_info(png_ptr, info_ptr); for (i=0;i Date: Tue, 3 Jan 2012 16:36:27 +0000 Subject: [PATCH 3683/4131] Pointers must stay valid till after the png_write_info call. Thanks wjp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3773 --- src/hardware/hardware.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 143d8b90..8f818e89 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -371,9 +371,11 @@ void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags, text[0].key = software; text[0].text = ptext_s; png_set_text(png_ptr, info_ptr, text, fields); - delete [] ptext_s; #endif png_write_info(png_ptr, info_ptr); +#ifdef PNG_TEXT_SUPPORTED + delete [] ptext_s; +#endif for (i=0;i Date: Tue, 3 Jan 2012 17:57:15 +0000 Subject: [PATCH 3684/4131] Undo goto:label code. breaks drive switching. Maybe change drive shouldn't be handled in shell:execute Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3774 --- src/shell/shell_cmds.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 6f013ed7..1e42d103 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -127,7 +127,7 @@ void DOS_Shell::DoCommand(char * line) { if (*line == '/') break; if (*line == '\t') break; if (*line == '=') break; - if (*line == ':') break; +// if (*line == ':') break; //This breaks drive switching as that is handled at a later stage. if ((*line == '.') ||(*line == '\\')) { //allow stuff like cd.. and dir.exe cd\kees *cmd_write=0; Bit32u cmd_index=0; From 0540ecdca5477d72a6122707e8dcd79acf23eee5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 5 Jan 2012 12:03:11 +0000 Subject: [PATCH 3685/4131] Copy all fields in copy constructor (wjp and valgrind) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3775 --- src/dos/dos_devices.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 82ae0592..9c4263a2 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -97,6 +97,7 @@ DOS_File::DOS_File(const DOS_File& orig) { attr=orig.attr; refCtr=orig.refCtr; open=orig.open; + hdrive=orig.hdrive; name=0; if(orig.name) { name=new char [strlen(orig.name) + 1];strcpy(name,orig.name); @@ -110,6 +111,7 @@ DOS_File & DOS_File::operator= (const DOS_File & orig) { attr=orig.attr; refCtr=orig.refCtr; open=orig.open; + hdrive=orig.hdrive; if(name) { delete [] name; name=0; } From cadeada0eef6a26b9a5bf52ef93002fa0006d9aa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 27 Jan 2012 12:00:17 +0000 Subject: [PATCH 3686/4131] Fix bug 3477126. Don't put junk chars in the title bar. Mac OS X will crash on it Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3776 --- src/dos/dos_execute.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 916a11ef..da43a405 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -93,8 +93,13 @@ void DOS_UpdatePSPName(void) { DOS_MCB mcb(dos.psp()-1); static char name[9]; mcb.GetFileName(name); + name[8] = 0; if (!strlen(name)) strcpy(name,"DOSBOX"); - RunningProgram=name; + for(Bitu i = 0;i < 8;i++) { //Don't put garbage in the title bar. Mac OS X doesn't like it + if (name[i] == 0) break; + if ( !isprint(*reinterpret_cast(&name[i])) ) name[i] = '?'; + } + RunningProgram = name; GFX_SetTitle(-1,-1,false); } From 84b8100dbb51fcc3f2b12358d2b0d18ed783d9bc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 27 Jan 2012 18:38:49 +0000 Subject: [PATCH 3687/4131] Add cmd-q => exit for Mac OS X Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3777 --- src/gui/sdlmain.cpp | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 5c5d89b3..58cd8e4c 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -246,6 +246,12 @@ void GFX_SetTitle(Bit32s cycles,Bits frameskip,bool paused){ SDL_WM_SetCaption(title,VERSION); } +static void KillSwitch(bool pressed) { + if (!pressed) + return; + throw 1; +} + static void PauseDOSBox(bool pressed) { if (!pressed) return; @@ -262,15 +268,22 @@ static void PauseDOSBox(bool pressed) { SDL_WaitEvent(&event); // since we're not polling, cpu usage drops to 0. switch (event.type) { - case SDL_QUIT: throw(0); break; + case SDL_QUIT: KillSwitch(true); break; case SDL_KEYDOWN: // Must use Pause/Break Key to resume. case SDL_KEYUP: - if(event.key.keysym.sym==SDLK_PAUSE) { + if(event.key.keysym.sym == SDLK_PAUSE) { - paused=false; + paused = false; GFX_SetTitle(-1,-1,false); break; } +#if defined (MACOSX) + if (event.key.keysym.sym == SDLK_q && (event.key.keysym.mod == KMOD_RMETA || event.key.keysym.mod == KMOD_LMETA) ) { + /* On macs, all aps exit when pressing cmd-q */ + KillSwitch(true); + break; + } +#endif } } } @@ -991,11 +1004,6 @@ static void GUI_ShutDown(Section * /*sec*/) { if (sdl.desktop.fullscreen) GFX_SwitchFullScreen(); } -static void KillSwitch(bool pressed) { - if (!pressed) - return; - throw 1; -} static void SetPriority(PRIORITY_LEVELS level) { @@ -1512,6 +1520,15 @@ void GFX_Events() { if (event.key.keysym.sym==SDLK_RALT) sdl.raltstate = event.key.type; if (((event.key.keysym.sym==SDLK_TAB)) && ((sdl.laltstate==SDL_KEYDOWN) || (sdl.raltstate==SDL_KEYDOWN))) break; +#endif +#if defined (MACOSX) + case SDL_KEYDOWN: + case SDL_KEYUP: + /* On macs CMD-Q is the default key to close an application */ + if (event.key.keysym.sym == SDLK_q && (event.key.keysym.mod == KMOD_RMETA || event.key.keysym.mod == KMOD_LMETA) ) { + KillSwitch(true); + break; + } #endif default: void MAPPER_CheckEvent(SDL_Event * event); From eb0a3dffc228fa5d7ba4fa803015eb5aa5d4195c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 27 Jan 2012 19:09:37 +0000 Subject: [PATCH 3688/4131] Add patch 3461824: Readme fixes by clem Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3778 --- README | 95 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/README b/README index 3fd7d416..96d6dd21 100644 --- a/README +++ b/README @@ -116,11 +116,11 @@ CD-ROM: My CD-ROM doesn't work. To enable SDL-support (does not include low-level CD access!): - mount d f:\ -t cdrom -usecd 0 -noioctl To enable ioctl access using digital audio extraction for CD audio - (windows-only, useful for Vista): + (Windows-only, useful for Vista): - mount d f:\ -t cdrom -ioctl_dx - To enable ioctl access using MCI for CD audio (windows-only): + To enable ioctl access using MCI for CD audio (Windows-only): - mount d f:\ -t cdrom -ioctl_mci - To force ioctl-only access (windows-only): + To force ioctl-only access (Windows-only): - mount d f:\ -t cdrom -ioctl_dio To enable low-level aspi-support (win98 with aspi-layer installed): - mount d f:\ -t cdrom -aspi @@ -161,7 +161,7 @@ SOUND: There is no sound. Be sure that the sound is correctly configured in the game. This might be done during the installation or with a setup/setsound utility that accompanies the game. First see if an autodetection option is provided. If - there is none try selecting Soundblaster or Soundblaster 16 with the default + there is none try selecting SoundBlaster or SoundBlaster 16 with the default settings being "address=220 irq=7 dma=1" (sometimes highdma=5). You might also want to select Sound Canvas/SCC/MPU-401/General MIDI/Wave Blaster at "address=330 IRQ=2" as music device. @@ -171,8 +171,8 @@ SOUND: There is no sound. configuration and use some lower fixed cycles value (like cycles=2000). Also assure that your host operating sound does provide sound. In certain cases it might be useful to use a different emulated sound device - like a soundblaster pro (sbtype=sbpro1 in the DOSBox configuration file) or - the gravis ultrasound (gus=true). + like a SoundBlaster Pro (sbtype=sbpro1 in the DOSBox configuration file) or + the Gravis Ultrasound (gus=true). SOUND: What sound hardware does DOSBox presently emulate? @@ -182,21 +182,21 @@ SOUND: What sound hardware does DOSBox presently emulate? digital sound output through the internal speaker. - Creative CMS/Gameblaster The is the first card released by Creative Labs(R). The default - configuration places it on address 220. It is disabled as default. + configuration places it on address 220. It is disabled by default. - Tandy 3 voice The emulation of this sound hardware is complete with the exception of the noise channel. The noise channel is not very well documented and as such is only a best guess as to the sound's accuracy. It is disabled as default. - Tandy DAC - Some games may require turning off sound blaster emulation (sbtype=none) - for better tandy DAC sound support. Don't forget to set the sbtype back to - sb16 if you don't use tandy sound. + Some games may require turning off SoundBlaster emulation (sbtype=none) + for better Tandy DAC sound support. Don't forget to set the sbtype back to + sb16 if you don't use Tandy sound. - Adlib This emulation is almost perfect and includes the Adlib's ability to almost play digitized sound. Placed at address 220 (also on 388). - SoundBlaster 16 / SoundBlaster Pro I & II / SoundBlaster I & II - By default DOSBox provides Soundblaster 16 level 16-bit stereo sound. + By default DOSBox provides SoundBlaster 16 level 16-bit stereo sound. You can select a different SoundBlaster version in the configuration of DOSBox. AWE32 music is not emulated as you can use MPU-401 instead (see below). @@ -207,14 +207,14 @@ SOUND: What sound hardware does DOSBox presently emulate? The emulation of this hardware is nearly complete, though the MIDI capabilities have been left out, since an MPU-401 has been emulated in other code. For Gravis music you also have to install Gravis drivers - inside DOSBox. It is disabled as default. + inside DOSBox. It is disabled by default. - MPU-401 A MIDI passthrough interface is also emulated. This method of sound output will only work when used with external device/emulator. - Every Windows XP/Vista/7 and MAC OS has got a default emulator compatible - with: Sound Canvas/SCC/General Standard/General MIDI/Wave Blaster. - A different device/emulator is needed for Roland LAPC/CM-32L/MT-32 - compatibility. + Every Windows XP/Vista/7 and Mac OS X has got a default emulator + compatible with: Sound Canvas/SCC/General Standard/General MIDI/Wave + Blaster. A different device/emulator is needed for + Roland LAPC/CM-32L/MT-32 compatibility. SOUND: The sound stutters or sounds stretched/weird. @@ -283,7 +283,7 @@ CRASH: The game/application does not run at all/crashes! Look at Section 11: "Troubleshooting". -CRASH: DOSBox crashes on startup!. +CRASH: DOSBox crashes on startup! Look at Section 11: "Troubleshooting". @@ -325,7 +325,7 @@ See Section 13: "The configuration (options) file". To be able to use Command Line Parameters: (Windows) open cmd.exe or command.com or edit the shortcut to dosbox.exe (Linux) use console -(MAC OS X) start terminal.app and navigate to: +(Mac OS X) start terminal.app and navigate to: /applications/dosbox.app/contents/macos/dosbox The options are valid for all operating systems unless noted in the option @@ -378,15 +378,15 @@ dosbox -erasemapper -machine machinetype Setup DOSBox to emulate a specific type of machine. Valid choices are: hercules, cga, ega, pcjr, tandy, svga_s3 (default) as well as - the additional svga chipsets listed in the DOSBox configuration file. - svga_s3 enables vesa emulation as well. - For some special vga effects the machinetype vgaonly can be used, - note that this disables svga capabilities and might be slower due to the + the additional SVGA chipsets listed in the DOSBox configuration file. + svga_s3 enables VESA emulation as well. + For some special VGA effects the machinetype vgaonly can be used, + note that this disables SVGA capabilities and might be slower due to the higher emulation precision. The machinetype affects the video card and the available sound cards. -noconsole (Windows Only) - Start DOSBox without showing DOSBox Status Window (console). + Start DOSBox without showing the DOSBox status window (console). Output will be redirected to stdout.txt and stderr.txt -startmapper @@ -526,7 +526,7 @@ MOUNT -u "Emulated Drive letter" Forces use of the SDL CD-ROM layer. Valid on all systems. -usecd number - Valid on all systems, under windows the -noioctl switch has to be + Valid on all systems, under Windows the -noioctl switch has to be present to make use of the -usecd switch. Enables to select the drive that should be used by SDL. Use this if the wrong or no CD-ROM drive is mounted while using the SDL CD-ROM @@ -1075,8 +1075,8 @@ CTRL-F11 Slow down emulation (Decrease DOSBox Cycles). CTRL-F12 Speed up emulation (Increase DOSBox Cycles)*. ALT-F12 Unlock speed (turbo button/fast forward)**. CTRL-ALT-HOME Restart DOSBox. -F11, ALT-F11 (machine=cga) change tint in NTSC output modes*** -F11 (machine=hercules) cycle through amber, green, white colouring*** +F11, ALT-F11 (machine=cga) change tint in NTSC output modes***. +F11 (machine=hercules) cycle through amber, green, white colouring***. *NOTE: Once you increase your DOSBox cycles beyond your computer CPU resources, it will produce the same effect as slowing down the emulation. @@ -1092,13 +1092,14 @@ F11 (machine=hercules) cycle through amber, green, white colouring*** These are the default keybindings. They can be changed in the keymapper (see Section 7: "KeyMapper"). -In MAC OS you can try using cmd(applekey) together with Ctrl if the key doesn't -work eg. cmd-ctrl-F1, but some keys may still need remapping (in Linux too). +In Mac OS X you can try using cmd(applekey) together with Ctrl (and/or ) Fn, +if the key doesn't work i.e. fn-cmd-ctrl-F1, but some keys may still need +remapping (in Linux too). Saved/recorded files can be found in: (Windows) "Start/WinLogo Menu"->"All Programs"->DOSBox-0.74->Extras (Linux) ~/.dosbox/capture - (MAC OS X) "~/Library/Preferences/capture" + (Mac OS X) "~/Library/Preferences/capture" This can be changed in the DOSBox configuration file. @@ -1136,7 +1137,7 @@ connected, or with a different joystick setting, your new setting will not work properly, or not work at all, until you reset DOSBox's mapperfile. If controller is working properly outside DOSBox, but doesn't calibrate properly -inside DOSBox, try different 'timed' setting in DOSBox's configuration file. +inside DOSBox, try a different 'timed' setting in DOSBox's configuration file. @@ -1144,8 +1145,8 @@ inside DOSBox, try different 'timed' setting in DOSBox's configuration file. 7. KeyMapper: ============= -You start the DOSBox mapper either with CTRL-F1 (see Section 5: "Special Keys") -or -startmapper (see Section 3: "Command Line Parameters"). +Start the DOSBox mapper either with CTRL-F1 (see Section 5: "Special Keys") or +-startmapper (see Section 3: "Command Line Parameters"). You are presented with a virtual keyboard and a virtual joystick. These virtual devices correspond to the keys and events DOSBox will @@ -1201,7 +1202,7 @@ Q3. If you try it out in DOSBox, you will notice that pressing X makes ZX mapped key X. Click "Del". -Examples about remapping the joystick: +Examples of remapping the joystick: You have a joystick attached, it is working fine under DOSBox and you want to play some keyboard-only game with the joystick (it is assumed that the game is controlled by the arrows on the keyboard): @@ -1223,7 +1224,7 @@ Examples about remapping the joystick: If you want to remap anything to your d-pad/hat you will have to change 'joysticktype=auto' to 'joysticktype=fcs' in configuration file. Maybe this - will be improved in the next dosbox version. + will be improved in the next DOSBox version. If you change the default mapping, you can save your changes by clicking on @@ -1238,12 +1239,12 @@ your mapperfile, if it is present in the DOSBox configuration file. =================== To switch to a different keyboard layout, either the entry "keyboardlayout" -in the [dos] section of the DOSBox configuration file can be used, or the -internal DOSBox program keyb.com (Section 4: "Internal Programs"). Both accept +in the [dos] section of the DOSBox configuration file or the internal DOSBox +program keyb.com (Section 4: "Internal Programs") can be used. Both accept DOS conforming language codes (see below), but only by using keyb.com a custom codepage can be specified. -The default keyboardlayout=auto currently works under windows only. The language +The default keyboardlayout=auto currently works under Windows only. The language is chosen according to the OS language, but the keyboard layout is not detected. Layout switching @@ -1316,7 +1317,7 @@ of the nullmodem connection. These are all parameters: * port: - TCP port number. Default: 23 * rxdelay: - how long (milliseconds) to delay received data if the interface is not ready. Increase this value if you encounter - overrun errors in the DOSBox Status Window. Default: 100 + overrun errors in the DOSBox status window. Default: 100 * txdelay: - how long to gather data before sending a packet. Default: 12 (reduces Network overhead) * server: - This nullmodem will be a client connecting to the specified @@ -1422,7 +1423,7 @@ Example: ==================== General tip: - Check messages in DOSBox Status Window. See Section 12: "DOSBox Status Window". + Check messages in the DOSBox status window. See Section 12: "DOSBox Status Window". DOSBox crashes right after starting it: - use different values for the output= entry in your DOSBox @@ -1468,14 +1469,14 @@ The game exits to the DOSBox prompt with some error message: 12. DOSBox Status Window: ========================= -DOSBox's Staus window contains many useful information about your currant -configuration, your actions in DOSBox, errors that happened and more. -Whenever you have any problem with DOSBox check these messages. +DOSBox's status window contains useful information about your current +configuration, your actions in DOSBox, errors which occurred and more. +Check these messages in case you encounter any problems with DOSBox. -To start DOSBox Status Window: - (Windows) Status Window is being started together with main DOSBox window. - (Linux) You may have to start DOSBox from a console to see Status Window. - (MAC OS X) Right click on DOSBox.app, choose "Show Package Contents"-> +To display the DOSBox status window: + (Windows) The status window is being started together with main DOSBox window. + (Linux) You may have to start DOSBox from a console to see the status window. + (Mac OS X) Right click on DOSBox.app, choose "Show Package Contents"-> ->enter "Contents"->enter "MacOS"->run "DOSBox" @@ -1488,7 +1489,7 @@ The configuration file is automatically created the first time you run DOSBox. The file can be found in: (Windows) "Start/WinLogo Menu"->"All Programs"->DOSBox-0.74->Options (Linux) ~/.dosbox/dosbox-0.74.conf - (MAC OS X) "~/Library/Preferences/DOSBox 0.74 Preferences" + (Mac OS X) "~/Library/Preferences/DOSBox 0.74 Preferences" The file is divided into several sections. Each section starts with a [section name] line. The settings are the property=value lines where value can be altered to customize DOSBox. From ff538caa62494d2e36a22b867faba0b3cfdb6307 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 28 Mar 2012 15:26:29 +0000 Subject: [PATCH 3689/4131] Fix handling of a CDROM image command line option with respect to the -securemode flag Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3779 --- src/shell/shell.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 62d44aac..af04125c 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -411,7 +411,7 @@ public: if (access(buffer,F_OK)) goto nomount; autoexec[12].Install(std::string("MOUNT C \"") + buffer + "\""); autoexec[13].Install("C:"); - /* Save the non modified filename (so boot and imgmount can use it (long filenames, case sensivitive)*/ + /* Save the non-modified filename (so boot and imgmount can use it (long filenames, case sensivitive)) */ strcpy(orig,name); upcase(name); if(strstr(name,".BAT") != 0) { @@ -424,10 +424,11 @@ public: /* Boot image files */ autoexec[15].Install(std::string("BOOT ") + orig); } else if((strstr(name,".ISO") != 0) || (strstr(name,".CUE") !=0 )) { - if(secure) autoexec[14].Install("z:\\config.com -securemode"); /* imgmount CD image files */ - autoexec[15].Install(std::string("IMGMOUNT D \"") + orig + std::string("\" -t iso")); + /* securemode gets a different number from the previous branches! */ + autoexec[14].Install(std::string("IMGMOUNT D \"") + orig + std::string("\" -t iso")); //autoexec[16].Install("D:"); + if(secure) autoexec[15].Install("z:\\config.com -securemode"); /* Makes no sense to exit here */ } else { if(secure) autoexec[14].Install("z:\\config.com -securemode"); From 98d04262ec5a83217f054640d6abde328bfe9216 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 20 May 2012 18:41:04 +0000 Subject: [PATCH 3690/4131] Fix bug 3528238: Name clash with compile option -DPIC Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3780 --- src/hardware/pic.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 0b82a8e6..14e36ff2 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -550,13 +550,13 @@ void TIMER_AddTick(void) { } } - -class PIC:public Module_base{ +/* Use full name to avoid name clash with compile option for position-independent code */ +class PIC_8259A: public Module_base { private: IO_ReadHandleObject ReadHandler[4]; IO_WriteHandleObject WriteHandler[4]; public: - PIC(Section* configuration):Module_base(configuration){ + PIC_8259A(Section* configuration):Module_base(configuration){ /* Setup pic0 and pic1 with initial values like DOS has normally */ PIC_IRQCheck=0; PIC_IRQActive=PIC_NOIRQ; @@ -606,17 +606,17 @@ public: pic_queue.free_entry=&pic_queue.entries[0]; pic_queue.next_entry=0; } - ~PIC(){ + ~PIC_8259A(){ } }; -static PIC* test; +static PIC_8259A* test; void PIC_Destroy(Section* sec){ delete test; } void PIC_Init(Section* sec) { - test = new PIC(sec); + test = new PIC_8259A(sec); sec->AddDestroyFunction(&PIC_Destroy); } From 498e5832519ef38d40c932a435a2a3474b545cf8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 8 Jun 2012 14:23:55 +0000 Subject: [PATCH 3691/4131] Model irq 0 stack layout in a more compatible way. Fixes M.U.L.E. booter. (ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3781 --- src/cpu/callback.cpp | 29 +++++++++++++++-------------- src/ints/bios.cpp | 6 +++--- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 31761e00..de64bf59 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -218,24 +218,25 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ phys_writeb(physAddress+0x06,(Bit8u)0xcf); //An IRET Instruction return (use_cb?0x0b:0x07); case CB_IRQ0: // timer int8 + phys_writeb(physAddress+0x00,(Bit8u)0xFB); //STI if (use_cb) { - phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4 - phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction - phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word + phys_writeb(physAddress+0x01,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x02,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x03,(Bit16u)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+0x01,(Bit8u)0x1e); // push ds + phys_writeb(physAddress+0x02,(Bit8u)0x50); // push ax + phys_writeb(physAddress+0x03,(Bit8u)0x52); // push dx + phys_writew(physAddress+0x04,(Bit16u)0x1ccd); // int 1c + 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)0x5a); // pop dx phys_writeb(physAddress+0x0c,(Bit8u)0x58); // pop ax - phys_writeb(physAddress+0x0d,(Bit8u)0xcf); //An IRET Instruction - return (use_cb?0x12:0x0e); + phys_writeb(physAddress+0x0d,(Bit8u)0x1f); // pop ds + phys_writeb(physAddress+0x0e,(Bit8u)0xcf); //An IRET Instruction + return (use_cb?0x13:0x0f); case CB_IRQ1: // keyboard int9 phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax phys_writew(physAddress+0x01,(Bit16u)0x60e4); // in al, 0x60 diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 8fc37c40..470a290e 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -997,14 +997,14 @@ public: CALLBACK_Setup(call_irq0,INT8_Handler,CB_IRQ0,Real2Phys(BIOS_DEFAULT_IRQ0_LOCATION),"IRQ 0 Clock"); RealSetVec(0x08,BIOS_DEFAULT_IRQ0_LOCATION); // pseudocode for CB_IRQ0: + // sti // callback INT8_Handler - // push ax,dx,ds + // push ds,ax,dx // int 0x1c // cli - // pop ds,dx // mov al, 0x20 // out 0x20, al - // pop ax + // pop dx,ax,ds // iret mem_writed(BIOS_TIMER,0); //Calculate the correct time From 21bbbec1cc9cd02cfb9e769a2972219fd7925d11 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 8 Jun 2012 21:01:43 +0000 Subject: [PATCH 3692/4131] Update mickeys directly instead of when reporting them to the application. Apply improved handling of sign switching. Improves Settlers 2(ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3782 --- src/ints/mouse.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index c74613c2..5f8c7ba4 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -454,8 +454,12 @@ void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate) { if((fabs(yrel) > 1.0) || (mouse.senv_y < 1.0)) dy *= mouse.senv_y; if (useps2callback) dy *= 2; - mouse.mickey_x += dx; - mouse.mickey_y += dy; + mouse.mickey_x += (dx * mouse.mickeysPerPixel_x); + mouse.mickey_y += (dy * mouse.mickeysPerPixel_y); + if (mouse.mickey_x >= 32768.0) mouse.mickey_x -= 65536.0; + else if (mouse.mickey_x <= -32769.0) mouse.mickey_x += 65536.0; + if (mouse.mickey_y >= 32768.0) mouse.mickey_y -= 65536.0; + else if (mouse.mickey_y <= -32769.0) mouse.mickey_y += 65536.0; if (emulate) { mouse.x += dx; mouse.y += dy; @@ -484,6 +488,11 @@ void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate) { if (mouse.x < mouse.min_x) mouse.x = mouse.min_x; if (mouse.y > mouse.max_y) mouse.y = mouse.max_y; if (mouse.y < mouse.min_y) mouse.y = mouse.min_y; + } else { + if (mouse.x >= 32768.0) mouse.x -= 65536.0; + else if (mouse.x <= -32769.0) mouse.x += 65536.0; + if (mouse.y >= 32768.0) mouse.y -= 65536.0; + else if (mouse.y <= -32769.0) mouse.y += 65536.0; } Mouse_AddEvent(MOUSE_HAS_MOVED); DrawCursor(); @@ -797,8 +806,8 @@ static Bitu INT33_Handler(void) { mouse.textXorMask = reg_dx; break; case 0x0b: /* Read Motion Data */ - reg_cx=(Bit16s)(mouse.mickey_x*mouse.mickeysPerPixel_x); - reg_dx=(Bit16s)(mouse.mickey_y*mouse.mickeysPerPixel_y); + reg_cx=static_cast(mouse.mickey_x); + reg_dx=static_cast(mouse.mickey_y); mouse.mickey_x=0; mouse.mickey_y=0; break; @@ -1001,8 +1010,8 @@ static Bitu INT74_Handler(void) { reg_bx=mouse.event_queue[mouse.events].buttons; reg_cx=POS_X; reg_dx=POS_Y; - reg_si=(Bit16s)(mouse.mickey_x*mouse.mickeysPerPixel_x); - reg_di=(Bit16s)(mouse.mickey_y*mouse.mickeysPerPixel_y); + reg_si=static_cast(mouse.mickey_x); + reg_di=static_cast(mouse.mickey_y); CPU_Push16(RealSeg(CALLBACK_RealPointer(int74_ret_callback))); CPU_Push16(RealOff(CALLBACK_RealPointer(int74_ret_callback))); SegSet16(cs, mouse.sub_seg); From 30577ca9906f13bb6677dd98a3a8684d5c2c6ff5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 26 Jun 2012 12:38:44 +0000 Subject: [PATCH 3693/4131] Restore Icon and title after restarting the graphics subsystem. (tested on a pc with broken directx surface support) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3783 --- src/gui/sdlmain.cpp | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 58cd8e4c..e3a32a6e 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -230,6 +230,7 @@ extern bool CPU_CycleAutoAdjust; //Globals for keyboard initialisation bool startup_state_numlock=false; bool startup_state_capslock=false; + void GFX_SetTitle(Bit32s cycles,Bits frameskip,bool paused){ char title[200]={0}; static Bit32s internal_cycles=0; @@ -246,6 +247,24 @@ void GFX_SetTitle(Bit32s cycles,Bits frameskip,bool paused){ SDL_WM_SetCaption(title,VERSION); } +static unsigned char logo[32*32*4]= { +#include "dosbox_logo.h" +}; +static void GFX_SetIcon() { +#if !defined(MACOSX) + /* Set Icon (must be done before any sdl_setvideomode call) */ + /* But don't set it on OS X, as we use a nicer external icon there. */ + /* Made into a separate call, so it can be called again when we restart the graphics output on win32 */ +#if WORDS_BIGENDIAN + SDL_Surface* logos= SDL_CreateRGBSurfaceFrom((void*)logo,32,32,32,128,0xff000000,0x00ff0000,0x0000ff00,0); +#else + SDL_Surface* logos= SDL_CreateRGBSurfaceFrom((void*)logo,32,32,32,128,0x000000ff,0x0000ff00,0x00ff0000,0); +#endif + SDL_WM_SetIcon(logos,NULL); +#endif +} + + static void KillSwitch(bool pressed) { if (!pressed) return; @@ -499,7 +518,9 @@ dosurface: sdl.using_windib=false; } SDL_InitSubSystem(SDL_INIT_VIDEO); + GFX_SetIcon(); //Set Icon again sdl.surface = SDL_SetVideoMode(width,height,bpp,SDL_HWSURFACE); + if(sdl.surface) GFX_SetTitle(-1,-1,false); //refresh title. } #endif if (sdl.surface == NULL) @@ -1077,9 +1098,6 @@ static void OutputString(Bitu x,Bitu y,const char * text,Bit32u color,Bit32u col } } -static unsigned char logo[32*32*4]= { -#include "dosbox_logo.h" -}; #include "dosbox_splash.h" //extern void UI_Run(bool); @@ -1091,16 +1109,7 @@ static void GUI_StartUp(Section * sec) { sdl.active=false; sdl.updating=false; -#if !defined(MACOSX) - /* Set Icon (must be done before any sdl_setvideomode call) */ - /* But don't set it on OS X, as we use a nicer external icon there. */ -#if WORDS_BIGENDIAN - SDL_Surface* logos= SDL_CreateRGBSurfaceFrom((void*)logo,32,32,32,128,0xff000000,0x00ff0000,0x0000ff00,0); -#else - SDL_Surface* logos= SDL_CreateRGBSurfaceFrom((void*)logo,32,32,32,128,0x000000ff,0x0000ff00,0x00ff0000,0); -#endif - SDL_WM_SetIcon(logos,NULL); -#endif + GFX_SetIcon(); sdl.desktop.lazy_fullscreen=false; sdl.desktop.lazy_fullscreen_req=false; From b216a9835e8a9b7398b690e39feed8058067eb1f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 30 Jun 2012 11:44:40 +0000 Subject: [PATCH 3694/4131] black gold installer (ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3784 --- src/dos/dos_files.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index c1574f17..5726f4f5 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1229,7 +1229,10 @@ bool DOS_FileExists(char const * const name) { bool DOS_GetAllocationInfo(Bit8u drive,Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters) { if (!drive) drive = DOS_GetDefaultDrive(); else drive--; - if (drive >= DOS_DRIVES || !Drives[drive]) return false; + if (drive >= DOS_DRIVES || !Drives[drive]) { + DOS_SetError(DOSERR_INVALID_DRIVE); + return false; + } Bit16u _free_clusters; Drives[drive]->AllocationInfo(_bytes_sector,_sectors_cluster,_total_clusters,&_free_clusters); SegSet16(ds,RealSeg(dos.tables.mediaid)); From 82f2c0b442f2da8918c7d7c89b42a3d1f7cd63a6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 21 Jul 2012 18:22:17 +0000 Subject: [PATCH 3695/4131] Add INSD Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3785 --- src/cpu/core_full/string.h | 7 +++++++ src/cpu/core_normal/string.h | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index 18a31517..bc8f2360 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -88,6 +88,13 @@ di_index=(di_index+add_index) & add_mask; } break; + case R_INSD: + add_index<<=2; + for (;count>0;count--) { + SaveMd(di_base+di_index,IO_ReadD(reg_dx)); + di_index=(di_index+add_index) & add_mask; + } + break; case R_STOSB: for (;count>0;count--) { SaveMb(di_base+di_index,reg_al); diff --git a/src/cpu/core_normal/string.h b/src/cpu/core_normal/string.h index 40ebce7d..88540822 100644 --- a/src/cpu/core_normal/string.h +++ b/src/cpu/core_normal/string.h @@ -93,6 +93,13 @@ static void DoString(STRING_OP type) { di_index=(di_index+add_index) & add_mask; } break; + case R_INSD: + add_index<<=2; + for (;count>0;count--) { + SaveMd(di_base+di_index,IO_ReadD(reg_dx)); + di_index=(di_index+add_index) & add_mask; + } + break; case R_STOSB: for (;count>0;count--) { SaveMb(di_base+di_index,reg_al); From 82e8442fd91acfce3144db1245f02cee71583c51 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 21 Jul 2012 20:05:34 +0000 Subject: [PATCH 3696/4131] variable not used externally. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3786 --- include/pic.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/pic.h b/include/pic.h index 1c8a0a32..287840de 100644 --- a/include/pic.h +++ b/include/pic.h @@ -33,7 +33,6 @@ typedef void (* PIC_EventHandler)(Bitu val); #define PIC_NOIRQ 0xFF extern Bitu PIC_IRQCheck; -extern Bitu PIC_IRQActive; extern Bitu PIC_Ticks; static INLINE float PIC_TickIndex(void) { From 5caa85d19ef851a015bcf63920e6911a441e4b1d Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 29 Jul 2012 17:35:29 +0000 Subject: [PATCH 3697/4131] Use channel->SetFreq instead of creating and destroying the channel every time. Thus the mixer volume control for the Disney/Covox device remains available. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3787 --- src/hardware/disney.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 52d7b8c6..3a9c48ac 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -69,11 +69,9 @@ static void DISNEY_disable(Bitu) { if(disney.mo) { disney.chan->AddSilence(); disney.chan->Enable(false); - delete disney.mo; } disney.leader = 0; disney.last_used = 0; - disney.mo = 0; disney.state = DS_IDLE; disney.interface_det = 0; disney.interface_det_ext = 0; @@ -90,8 +88,7 @@ static void DISNEY_enable(Bitu freq) { if(disney.stereo) LOG(LOG_MISC,LOG_NORMAL)("disney enable %d Hz, stereo",freq); else LOG(LOG_MISC,LOG_NORMAL)("disney enable %d Hz, mono",freq); #endif - disney.mo = new MixerObject(); - disney.chan=disney.mo->Install(&DISNEY_CallBack,freq,"DISNEY"); + disney.chan->SetFreq(freq); disney.chan->Enable(true); disney.state = DS_RUNNING; } @@ -377,11 +374,16 @@ public: disney.control=0; disney.last_used=0; - disney.mo=0; + disney.mo = new MixerObject(); + disney.chan=disney.mo->Install(&DISNEY_CallBack,10000,"DISNEY"); DISNEY_disable(0); + + } ~DISNEY(){ DISNEY_disable(0); + if (disney.mo) + delete disney.mo; } }; From be2b9c2db783223fd4de0528195c75579fc47659 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 29 Jul 2012 17:46:51 +0000 Subject: [PATCH 3698/4131] Prepare the PCJR video palette chip before writing data. Thanks ripsaw. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3788 --- src/ints/int10_pal.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 716296cf..c7fee18a 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -343,6 +343,7 @@ void INT10_SetColorSelect(Bit8u val) { if (machine == MCH_CGA || machine==MCH_TANDY) IO_Write(0x3d9,temp); else if (machine == MCH_PCJR) { + IO_Read(VGAREG_TDY_RESET); // reset the flipflop switch(vga.mode) { case M_TANDY2: IO_Write(VGAREG_TDY_ADDRESS, 0x11); From f2887664faea83952f3a9c3bba37fc1aedbfb77a Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 29 Jul 2012 19:29:46 +0000 Subject: [PATCH 3699/4131] Fix BIOS text output in 320x200 16 color and 640x200 4 color modes on the PCJr (it maps only 16kB at 0xB800 and thus access has to go to the actual address in main memory) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3789 --- src/ints/int10_char.cpp | 12 ++++ src/ints/int10_put_pixel.cpp | 120 ++++++++++++++++++++++------------- 2 files changed, 89 insertions(+), 43 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index cf1d7049..e952dba9 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -204,6 +204,18 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit /* Get the correct page */ if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); PhysPt base=CurMode->pstart+page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); + + if (GCC_UNLIKELY(machine==MCH_PCJR)) { + if (real_readb(BIOSMEM_SEG, BIOSMEM_CURRENT_MODE) >= 9) { + // PCJr cannot handle these modes at 0xb800 + // See INT10_PutPixel M_TANDY16 + Bitu cpupage = + (real_readb(BIOSMEM_SEG, BIOSMEM_CRTCPU_PAGE) >> 3) & 0x7; + + base = cpupage << 14; + base += page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); + } + } /* See how much lines need to be copied */ Bit8u start,end;Bits next; diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 8f759e64..47f3a430 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -30,34 +30,44 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { switch (CurMode->type) { case M_CGA4: - { - if (real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)<=5) { - Bit16u off=(y>>1)*80+(x>>2); - if (y&1) off+=8*1024; + { + if (real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)<=5) { + // this is a 16k mode + Bit16u off=(y>>1)*80+(x>>2); + if (y&1) off+=8*1024; - Bit8u old=real_readb(0xb800,off); - if (color & 0x80) { - color&=3; - old^=color << (2*(3-(x&3))); - } else { - old=(old&cga_masks[x&3])|((color&3) << (2*(3-(x&3)))); - } - real_writeb(0xb800,off,old); - } else { - Bit16u off=(y>>2)*160+((x>>2)&(~1)); - off+=(8*1024) * (y & 3); + Bit8u old=real_readb(0xb800,off); + if (color & 0x80) { + color&=3; + old^=color << (2*(3-(x&3))); + } else { + old=(old&cga_masks[x&3])|((color&3) << (2*(3-(x&3)))); + } + real_writeb(0xb800,off,old); + } else { + // a 32k mode: PCJr special case (see M_TANDY16) + Bit16u seg; + if (machine==MCH_PCJR) { + Bitu cpupage = + (real_readb(BIOSMEM_SEG, BIOSMEM_CRTCPU_PAGE) >> 3) & 0x7; + seg = cpupage << 10; // A14-16 to addr bits 14-16 + } else + seg = 0xb800; - Bit16u old=real_readw(0xb800,off); - if (color & 0x80) { - old^=(color&1) << (7-(x&7)); - old^=((color&2)>>1) << ((7-(x&7))+8); - } else { - old=(old&(~(0x101<<(7-(x&7))))) | ((color&1) << (7-(x&7))) | (((color&2)>>1) << ((7-(x&7))+8)); - } - real_writew(0xb800,off,old); - } + Bit16u off=(y>>2)*160+((x>>2)&(~1)); + off+=(8*1024) * (y & 3); + + Bit16u old=real_readw(seg,off); + if (color & 0x80) { + old^=(color&1) << (7-(x&7)); + old^=((color&2)>>1) << ((7-(x&7))+8); + } else { + old=(old&(~(0x101<<(7-(x&7))))) | ((color&1) << (7-(x&7))) | (((color&2)>>1) << ((7-(x&7))+8)); + } + real_writew(seg,off,old); } - break; + } + break; case M_CGA2: { Bit16u off=(y>>1)*80+(x>>3); @@ -73,26 +83,50 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { } break; case M_TANDY16: - { - IO_Write(0x3d4,0x09); - Bit8u scanlines_m1=IO_Read(0x3d5); - Bit16u off=(y>>((scanlines_m1==1)?1:2))*(CurMode->swidth>>1)+(x>>1); - off+=(8*1024) * (y & scanlines_m1); - Bit8u old=real_readb(0xb800,off); - Bit8u p[2]; - p[1] = (old >> 4) & 0xf; - p[0] = old & 0xf; - Bitu ind = 1-(x & 0x1); + { + // find out if we are in a 32k mode (0x9 or 0xa) + // This requires special handling on the PCJR + // because only 16k are mapped at 0xB800 + bool is_32k = (real_readb(BIOSMEM_SEG, BIOSMEM_CURRENT_MODE) >= 9)? + true:false; - if (color & 0x80) { - p[ind]^=(color & 0x7f); - } else { - p[ind]=color; - } - old = (p[1] << 4) | p[0]; - real_writeb(0xb800,off,old); + Bit16u segment, offset; + if (is_32k) { + if (machine==MCH_PCJR) { + Bitu cpupage = + (real_readb(BIOSMEM_SEG, BIOSMEM_CRTCPU_PAGE) >> 3) & 0x7; + segment = cpupage << 10; // A14-16 to addr bits 14-16 + } else + segment = 0xb800; + // bits 1 and 0 of y select the bank + // two pixels per byte (thus x>>1) + offset = (y >> 2) * (CurMode->swidth >> 1) + (x>>1); + // select the scanline bank + offset += (8*1024) * (y & 3); + } else { + segment = 0xb800; + // bit 0 of y selects the bank + offset = (y >> 1) * (CurMode->swidth >> 1) + (x>>1); + offset += (8*1024) * (y & 1); } - break; + + // update the pixel + Bit8u old=real_readb(segment, offset); + Bit8u p[2]; + p[1] = (old >> 4) & 0xf; + p[0] = old & 0xf; + Bitu ind = 1-(x & 0x1); + + if (color & 0x80) { + // color is to be XORed + p[ind]^=(color & 0x7f); + } else { + p[ind]=color; + } + old = (p[1] << 4) | p[0]; + real_writeb(segment,offset, old); + } + break; case M_LIN4: if ((machine!=MCH_VGA) || (svgaCard!=SVGA_TsengET4K) || (CurMode->swidth>800)) { From 41729e0ca5124e8bedeea75d41a9d002185821be Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 3 Aug 2012 07:59:15 +0000 Subject: [PATCH 3700/4131] don't go lower than 20 files. Makes little sense and it is incompatible with a clipper program. (thanks ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3790 --- src/dos/dos_classes.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index ba81f796..629d8112 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -300,6 +300,9 @@ void DOS_PSP::SetFCB2(RealPt src) { } bool DOS_PSP::SetNumFiles(Bit16u fileNum) { + //20 minimum. clipper program. + if (fileNum < 20) fileNum = 20; + if (fileNum>20) { // Allocate needed paragraphs fileNum+=2; // Add a few more files for safety From d95950242d2f347a053604add71b9e4e8a50d323 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 11 Aug 2012 17:40:32 +0000 Subject: [PATCH 3701/4131] Several fixes for regressions (Innocent until caught and curse of enchantia), Add fix for mechwarrior.) lowered eoi timeout to 0.06f. (ripsaw, Srecko and h-a-l-9000) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3791 --- src/hardware/mpu401.cpp | 55 +++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index cb24d165..8d3cdf4f 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2012 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,12 +30,15 @@ bool MIDI_Available(void); static void MPU401_Event(Bitu); static void MPU401_Reset(void); -static void MPU401_EOIHandler(void); +static void MPU401_ResetDone(Bitu); +static void MPU401_EOIHandler(Bitu val=0); +static void MPU401_EOIHandlerDispatch(void); #define MPU401_VERSION 0x15 #define MPU401_REVISION 0x01 #define MPU401_QUEUE 32 #define MPU401_TIMECONSTANT (60000000/1000.0f) +#define MPU401_RESETBUSY 27.0f enum MpuMode { M_UART,M_INTELLIGENT }; enum MpuDataType {T_OVERFLOW,T_MARK,T_MIDI_SYS,T_MIDI_NORM,T_COMMAND}; @@ -72,8 +75,9 @@ static struct { bool wsd,wsm,wsd_start; bool run_irq,irq_pending; bool send_now; + bool eoi_scheduled; Bits data_onoff; - Bitu command_byte; + Bitu command_byte,cmd_pending; Bit8u tmask,cmask,amask; Bit16u midi_mask; Bit16u req_mask; @@ -112,12 +116,13 @@ static void ClrQueue(void) { static Bitu MPU401_ReadStatus(Bitu port,Bitu iolen) { Bit8u ret=0x3f; /* Bits 6 and 7 clear */ + if (mpu.state.cmd_pending) ret|=0x40; if (!mpu.queue_used) ret|=0x80; return ret; } static void MPU401_WriteCommand(Bitu port,Bitu val,Bitu iolen) { - mpu.state.reset=0; + if (mpu.state.reset) {mpu.state.cmd_pending=val+1;return;} if (val<=0x2f) { switch (val&3) { /* MIDI stop, start, continue */ case 1: {MIDI_RawOutByte(0xfc);break;} @@ -239,12 +244,10 @@ static void MPU401_WriteCommand(Bitu port,Bitu val,Bitu iolen) { break; case 0xff: /* Reset MPU-401 */ LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Reset %X",val); - mpu.state.reset=1; - if (CPU_Cycles > 5) { //It came from the desert wants a fast irq - CPU_CycleLeft += CPU_Cycles; - CPU_Cycles = 5; - } + PIC_AddEvent(MPU401_ResetDone,MPU401_RESETBUSY); + mpu.state.reset=true; MPU401_Reset(); + if (mpu.mode==M_UART) return;//do not send ack in UART mode break; case 0x3f: /* UART mode */ LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Set UART mode %X",val); @@ -284,7 +287,7 @@ static Bitu MPU401_ReadData(Bitu port,Bitu iolen) { } if (ret==MSG_MPU_END || ret==MSG_MPU_CLOCK || ret==MSG_MPU_ACK) { mpu.state.data_onoff=-1; - MPU401_EOIHandler(); + MPU401_EOIHandlerDispatch(); } return ret; } @@ -390,7 +393,7 @@ static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) { if (val<0xf0) mpu.state.data_onoff++; else { mpu.state.data_onoff=-1; - MPU401_EOIHandler(); + MPU401_EOIHandlerDispatch(); return; } if (val==0) mpu.state.send_now=true; @@ -402,13 +405,13 @@ static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) { if (val==0xf8 || val==0xf9) mpu.condbuf.type=T_OVERFLOW; mpu.condbuf.value[mpu.condbuf.vlength]=val; mpu.condbuf.vlength++; - if ((val&0xf0)!=0xe0) MPU401_EOIHandler(); + if ((val&0xf0)!=0xe0) MPU401_EOIHandlerDispatch(); else mpu.state.data_onoff++; break; case 2:/* Command byte #2 */ mpu.condbuf.value[mpu.condbuf.vlength]=val; mpu.condbuf.vlength++; - MPU401_EOIHandler(); + MPU401_EOIHandlerDispatch(); break; } return; @@ -420,7 +423,7 @@ static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) { if (val<0xf0) mpu.state.data_onoff=1; else { mpu.state.data_onoff=-1; - MPU401_EOIHandler(); + MPU401_EOIHandlerDispatch(); return; } if (val==0) mpu.state.send_now=true; @@ -461,7 +464,7 @@ static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) { } } if (!(posd==1 && val>=0xf0)) mpu.playbuf[mpu.state.channel].value[posd-1]=val; - if (posd==length) MPU401_EOIHandler(); + if (posd==length) MPU401_EOIHandlerDispatch(); } } @@ -540,7 +543,18 @@ next_event: PIC_AddEvent(MPU401_Event,MPU401_TIMECONSTANT/new_time); } -static void MPU401_EOIHandler(void) { + +static void MPU401_EOIHandlerDispatch(void) { + if (mpu.state.send_now) { + mpu.state.eoi_scheduled=true; + PIC_AddEvent(MPU401_EOIHandler,0.06f); //Possible a bit longer + } + else if (!mpu.state.eoi_scheduled) MPU401_EOIHandler(); +} + +//Updates counters and requests new data on "End of Input" +static void MPU401_EOIHandler(Bitu val) { + mpu.state.eoi_scheduled=false; if (mpu.state.send_now) { mpu.state.send_now=false; if (mpu.state.cond_req) UpdateConductor(); @@ -558,9 +572,18 @@ static void MPU401_EOIHandler(void) { } while ((i++)<16); } +static void MPU401_ResetDone(Bitu) { + mpu.state.reset=false; + if (mpu.state.cmd_pending) { + MPU401_WriteCommand(0x331,mpu.state.cmd_pending-1,1); + mpu.state.cmd_pending=0; + } +} static void MPU401_Reset(void) { PIC_DeActivateIRQ(mpu.irq); mpu.mode=(mpu.intelligent ? M_INTELLIGENT : M_UART); + PIC_RemoveEvents(MPU401_EOIHandler); + mpu.state.eoi_scheduled=false; mpu.state.wsd=false; mpu.state.wsm=false; mpu.state.conductor=false; From 0157fcf8fa3063642fe2d0d548cfcd0559183007 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 11 Aug 2012 17:46:32 +0000 Subject: [PATCH 3702/4131] Total rewrite. The PIC is now split up in 2 units, like the real thing. There are now less hacks in the code in order to deal with the irq 2 being active/inservice. IRQ 2 now needs to be acknowledged by the interrupt handler for IRQs that happen on the slave PIC. Fixes Pyl sound effects with low cycles and hopefully others. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3792 --- src/hardware/pic.cpp | 434 ++++++++++++++++++++++--------------------- 1 file changed, 218 insertions(+), 216 deletions(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 14e36ff2..4e67e663 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2012 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,9 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include - #include "dosbox.h" #include "inout.h" #include "cpu.h" @@ -29,35 +26,144 @@ #define PIC_QUEUESIZE 512 -struct IRQ_Block { - bool masked; - bool active; - bool inservice; - Bitu vector; -}; - struct PIC_Controller { Bitu icw_words; Bitu icw_index; - Bitu masked; - bool special; bool auto_eoi; bool rotate_on_auto_eoi; bool single; bool request_issr; Bit8u vector_base; + + Bit8u irr; // request register + Bit8u imr; // mask register + Bit8u imrr; // mask register reversed (makes bit tests simpler) + Bit8u isr; // in service register + Bit8u isrr; // in service register reversed (makes bit tests simpler) + Bit8u active_irq; //currently active irq + + + void set_imr(Bit8u val); + + void check_after_EOI(){ + //Update the active_irq as an EOI is likely to change that. + update_active_irq(); + if((irr&imrr)&isrr) check_for_irq(); + } + + void update_active_irq() { + if(isr == 0) {active_irq = 8; return;} + for(Bit8u i = 0, s = 1; i < 8;i++, s<<=1){ + if( isr & s){ + active_irq = i; + return; + } + } + } + + void check_for_irq(){ + const Bit8u possible_irq = (irr&imrr)&isrr; + if (possible_irq) { + const Bit8u a_irq = special?8:active_irq; + for(Bit8u i = 0, s = 1; i < a_irq;i++, s<<=1){ + if ( possible_irq & s ) { + //There is an irq ready to be served => signal master and/or cpu + activate(); + return; + } + } + } + deactivate(); //No irq, remove signal to master and/or cpu + } + + //Signals master/cpu that there is an irq ready. + void activate(); + + //Removes signal to master/cpu that there is an irq ready. + void deactivate(); + + void raise_irq(Bit8u val){ + Bit8u bit = 1 << (val); + if((irr & bit)==0) { //value changed (as it is currently not active) + irr|=bit; + if((bit&imrr)&isrr) { //not masked and not in service + if(special || val < active_irq) activate(); + } + } + } + + void lower_irq(Bit8u val){ + Bit8u bit = 1 << ( val); + if(irr & bit) { //value will change (as it is currently active) + irr&=~bit; + if((bit&imrr)&isrr) { //not masked and not in service + //This irq might have toggled PIC_IRQCheck/caused irq 2 on master, when it was raised. + //If it is active, then recheck it, we can't just deactivate as there might be more IRQS raised. + if(special || val < active_irq) check_for_irq(); + } + } + } + + //handles all bits and logic related to starting this IRQ, it does NOT start the interrupt on the CPU. + void start_irq(Bit8u val); }; -Bitu PIC_Ticks=0; -Bitu PIC_IRQCheck; -Bitu PIC_IRQOnSecondPicActive; -Bitu PIC_IRQActive; - - -static IRQ_Block irqs[16]; static PIC_Controller pics[2]; -static bool PIC_Special_Mode = false; //Saves one compare in the pic_run_irqloop +static PIC_Controller& master = pics[0]; +static PIC_Controller& slave = pics[1]; +Bitu PIC_Ticks = 0; +Bitu PIC_IRQCheck = 0; //Maybe make it a bool and/or ensure 32bit size (x86 dynamic core seems to assume 32 bit variable size) + + +void PIC_Controller::set_imr(Bit8u val) { + if (GCC_UNLIKELY(machine==MCH_PCJR)) { + //irq 6 is a NMI on the PCJR + if (this == &master) val &= ~(1 <<(6)); + } + Bit8u change = (imr) ^ (val); //Bits that have changed become 1. + imr = val; + imrr = ~val; + + //Test if changed bits are set in irr and are not being served at the moment + //Those bits have impact on whether the cpu emulation should be paused or not. + if((irr & change)&isrr) check_for_irq(); +} + +void PIC_Controller::activate() { + //Stops CPU if master, signals master if slave + if(this == &master) { + PIC_IRQCheck = 1; + //cycles 0, take care of the port IO stuff added in raise_irq base caller. + CPU_CycleLeft += CPU_Cycles; + CPU_Cycles = 0; + //maybe when coming from a EOI, give a tiny delay. (for the cpu to pick it up) (see PIC_Activate_IRQ) + } else { + master.raise_irq(2); + } +} + +void PIC_Controller::deactivate() { + //removes irq check value if master, signals master if slave + if(this == &master) { + PIC_IRQCheck = 0; + } else { + master.lower_irq(2); + } +} + +void PIC_Controller::start_irq(Bit8u val){ + irr&=~(1<<(val)); + if (!auto_eoi) { + active_irq = val; + isr |= 1<<(val); + isrr = ~isr; + } else if (GCC_UNLIKELY(rotate_on_auto_eoi)) { + E_Exit("rotate on auto EOI not handled"); + } +} + + struct PICEntry { float index; Bitu value; @@ -73,10 +179,7 @@ static struct { static void write_command(Bitu port,Bitu val,Bitu iolen) { PIC_Controller * pic=&pics[port==0x20 ? 0 : 1]; - Bitu irq_base=port==0x20 ? 0 : 8; - Bitu i; - static Bit16u IRQ_priority_table[16] = - { 0,1,2,8,9,10,11,12,13,14,15,3,4,5,6,7 }; + if (GCC_UNLIKELY(val&0x10)) { // ICW1 issued if (val&0x04) E_Exit("PIC: 4 byte interval not handled"); if (val&0x08) E_Exit("PIC: level triggered mode not handled"); @@ -93,40 +196,24 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { if (val&0x40) { // special mask select if (val&0x20) pic->special = true; else pic->special = false; - if (pics[0].special || pics[1].special) - PIC_Special_Mode = true; else - PIC_Special_Mode = false; - if (PIC_IRQCheck) { //Recheck irqs - CPU_CycleLeft += CPU_Cycles; - CPU_Cycles = 0; - } + //Check if there are irqs ready to run, as the priority system has possibly been changed. + pic->check_for_irq(); LOG(LOG_PIC,LOG_NORMAL)("port %X : special mask %s",port,(pic->special)?"ON":"OFF"); } } else { // OCW2 issued if (val&0x20) { // EOI commands if (GCC_UNLIKELY(val&0x80)) E_Exit("rotate mode not supported"); if (val&0x40) { // specific EOI - if (PIC_IRQActive==(irq_base+val-0x60U)) { - irqs[PIC_IRQActive].inservice=false; - PIC_IRQActive=PIC_NOIRQ; - for (i=0; i<=15; i++) { - if (irqs[IRQ_priority_table[i]].inservice) { - PIC_IRQActive=IRQ_priority_table[i]; - break; - } - } - } + pic->isr &= ~(1<< ((val-0x60))); + pic->isrr = ~pic->isr; + pic->check_after_EOI(); // if (val&0x80); // perform rotation } else { // nonspecific EOI - if (PIC_IRQActive<(irq_base+8)) { - irqs[PIC_IRQActive].inservice=false; - PIC_IRQActive=PIC_NOIRQ; - for (i=0; i<=15; i++){ - if(GCC_UNLIKELY(irqs[IRQ_priority_table[i]].inservice)) { - PIC_IRQActive=IRQ_priority_table[i]; - break; - } - } + if (pic->active_irq != 8) { + //If there is no irq in service, ignore the call, some games send an eoi to both pics when a sound irq happens (regardless of the irq). + pic->isr &= ~(1 << (pic->active_irq)); + pic->isrr = ~pic->isr; + pic->check_after_EOI(); } // if (val&0x80); // perform rotation } @@ -143,43 +230,13 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { static void write_data(Bitu port,Bitu val,Bitu iolen) { PIC_Controller * pic=&pics[port==0x21 ? 0 : 1]; - Bitu irq_base=(port==0x21) ? 0 : 8; - Bitu i; - bool old_irq2_mask = irqs[2].masked; switch(pic->icw_index) { case 0: /* mask register */ - LOG(LOG_PIC,LOG_NORMAL)("%d mask %X",port==0x21 ? 0 : 1,val); - for (i=0;i<=7;i++) { - irqs[i+irq_base].masked=(val&(1<0; - if(port==0x21) { - if (irqs[i+irq_base].active && !irqs[i+irq_base].masked) PIC_IRQCheck|=(1 << (i+irq_base)); - else PIC_IRQCheck&=~(1 << (i+irq_base)); - } else { - if (irqs[i+irq_base].active && !irqs[i+irq_base].masked && !irqs[2].masked) PIC_IRQCheck|=(1 << (i+irq_base)); - else PIC_IRQCheck&=~(1 << (i+irq_base)); - } - } - if (machine==MCH_PCJR) { - /* irq6 cannot be disabled as it serves as pseudo-NMI */ - irqs[6].masked=false; - } - if(irqs[2].masked != old_irq2_mask) { - /* Irq 2 mask has changed recheck second pic */ - for(i=8;i<=15;i++) { - if (irqs[i].active && !irqs[i].masked && !irqs[2].masked) PIC_IRQCheck|=(1 << (i)); - else PIC_IRQCheck&=~(1 << (i)); - } - } - if (PIC_IRQCheck) { - CPU_CycleLeft+=CPU_Cycles; - CPU_Cycles=0; - } + pic->set_imr(val); break; case 1: /* icw2 */ LOG(LOG_PIC,LOG_NORMAL)("%d:Base vector %X",port==0x21 ? 0 : 1,val); - for (i=0;i<=7;i++) { - irqs[i+irq_base].vector=(val&0xf8)+i; - }; + pic->vector_base = val&0xf8; if(pic->icw_index++ >= pic->icw_words) pic->icw_index=0; else if(pic->single) pic->icw_index=3; /* skip ICW3 in single mode */ break; @@ -214,82 +271,70 @@ static void write_data(Bitu port,Bitu val,Bitu iolen) { static Bitu read_command(Bitu port,Bitu iolen) { PIC_Controller * pic=&pics[port==0x20 ? 0 : 1]; - Bitu irq_base=(port==0x20) ? 0 : 8; - Bitu i;Bit8u ret=0;Bit8u b=1; - if (pic->request_issr) { - for (i=irq_base;irequest_issr){ + return pic->isr; + } else { + return pic->irr; } - return ret; } + static Bitu read_data(Bitu port,Bitu iolen) { - Bitu irq_base=(port==0x21) ? 0 : 8; - Bitu i;Bit8u ret=0;Bit8u b=1; - for (i=irq_base;i<=irq_base+7;i++) { - if (irqs[i].masked) ret|=b; - b <<= 1; - } - return ret; + PIC_Controller * pic=&pics[port==0x21 ? 0 : 1]; + return pic->imr; } - void PIC_ActivateIRQ(Bitu irq) { - if (GCC_UNLIKELY(CPU_Cycles)) { - // CPU_Cycles nonzero means the interrupt was triggered by an I/O + Bitu t = irq>7 ? (irq - 8): irq; + PIC_Controller * pic=&pics[irq>7 ? 1 : 0]; + + Bit32s OldCycles = CPU_Cycles; + pic->raise_irq(t); //Will set the CPU_Cycles to zero if this IRQ will be handled directly + + if (GCC_UNLIKELY(OldCycles != CPU_Cycles)) { + // if CPU_Cycles have changed, this means that the interrupt was triggered by an I/O // register write rather than an event. // Real hardware executes 0 to ~13 NOPs or comparable instructions // before the processor picks up the interrupt. Let's try with 2 // cycles here. // Required by Panic demo (irq0), It came from the desert (MPU401) // Does it matter if CPU_CycleLeft becomes negative? - CPU_CycleLeft += (CPU_Cycles-2); - CPU_Cycles=2; - } - if( irq < 8 ) { - irqs[irq].active = true; - if (!irqs[irq].masked) { - PIC_IRQCheck|=(1 << irq); - } - } else if (irq < 16) { - irqs[irq].active = true; - PIC_IRQOnSecondPicActive|=(1 << irq); - if (!irqs[irq].masked && !irqs[2].masked) { - PIC_IRQCheck|=(1 << irq); - } + + // It might be an idea to do this always in order to simulate this + // So on write mask and EOI as well. (so inside the activate function) +// CPU_CycleLeft += (CPU_Cycles-2); + CPU_CycleLeft -= 2; + CPU_Cycles = 2; } } void PIC_DeActivateIRQ(Bitu irq) { - if (irq<16) { - irqs[irq].active=false; - PIC_IRQCheck&=~(1 << irq); - PIC_IRQOnSecondPicActive&=~(1 << irq); - } + Bitu t = irq>7 ? (irq - 8): irq; + PIC_Controller * pic=&pics[irq>7 ? 1 : 0]; + pic->lower_irq(t); } -static inline bool PIC_startIRQ(Bitu i) { - /* irqs on second pic only if irq 2 isn't masked */ - if( i > 7 && irqs[2].masked) return false; - irqs[i].active = false; - PIC_IRQCheck&= ~(1 << i); - PIC_IRQOnSecondPicActive&= ~(1 << i); - CPU_HW_Interrupt(irqs[i].vector); - Bitu pic=(i&8)>>3; - if (!pics[pic].auto_eoi) { //irq 0-7 => pic 0 else pic 1 - PIC_IRQActive = i; - irqs[i].inservice = true; - } else if (GCC_UNLIKELY(pics[pic].rotate_on_auto_eoi)) { - E_Exit("rotate on auto EOI not handled"); + +static void slave_startIRQ(){ + Bit8u pic1_irq = 8; + const Bit8u p = (slave.irr & slave.imrr)&slave.isrr; + const Bit8u max = slave.special?8:slave.active_irq; + for(Bit8u i = 0,s = 1;i < max;i++, s<<=1){ + if (p&s){ + pic1_irq = i; + break; + } } - return true; + // Maybe change the E_Exit to a return + if (GCC_UNLIKELY(pic1_irq == 8)) E_Exit("irq 2 is active, but no irq active on the slave PIC."); + + slave.start_irq(pic1_irq); + master.start_irq(2); + CPU_HW_Interrupt(slave.vector_base + pic1_irq); +} + +static void inline master_startIRQ(Bitu i){ + master.start_irq(i); + CPU_HW_Interrupt(master.vector_base + i); } void PIC_runIRQs(void) { @@ -297,70 +342,31 @@ void PIC_runIRQs(void) { if (GCC_UNLIKELY(!PIC_IRQCheck)) return; if (GCC_UNLIKELY(cpudecoder==CPU_Core_Normal_Trap_Run)) return; - static Bitu IRQ_priority_order[16] = - { 0,1,2,8,9,10,11,12,13,14,15,3,4,5,6,7 }; - static Bit16u IRQ_priority_lookup[17] = - { 0,1,2,11,12,13,14,15,3,4,5,6,7,8,9,10,16 }; - Bit16u activeIRQ = PIC_IRQActive; - if (activeIRQ == PIC_NOIRQ) activeIRQ = 16; - /* Get the priority of the active irq */ - Bit16u Priority_Active_IRQ = IRQ_priority_lookup[activeIRQ]; - - Bitu i,j; - /* j is the priority (walker) - * i is the irq at the current priority */ - - /* If one of the pics is in special mode use a check that cares for that. */ - if(!PIC_Special_Mode) { - for (j = 0; j < Priority_Active_IRQ; j++) { - i = IRQ_priority_order[j]; - if (!irqs[i].masked && irqs[i].active) { - if(GCC_LIKELY(PIC_startIRQ(i))) return; - } - } - } else { /* Special mode variant */ - for (j = 0; j<= 15; j++) { - i = IRQ_priority_order[j]; - if ( (j < Priority_Active_IRQ) || (pics[ ((i&8)>>3) ].special) ) { - if (!irqs[i].masked && irqs[i].active) { - /* the irq line is active. it's not masked and - * the irq is allowed priority wise. So let's start it */ - /* If started successfully return, else go for the next */ - if(PIC_startIRQ(i)) return; - } + const Bit8u p = (master.irr & master.imrr)&master.isrr; + const Bit8u max = master.special?8:master.active_irq; + for(Bit8u i = 0,s = 1;i < max;i++, s<<=1){ + if (p&s){ + if (i==2) { //second pic + slave_startIRQ(); + } else { + master_startIRQ(i); } + break; } } + //Disable check variable. + PIC_IRQCheck = 0; } void PIC_SetIRQMask(Bitu irq, bool masked) { - if(irqs[irq].masked == masked) return; /* Do nothing if mask doesn't change */ - bool old_irq2_mask = irqs[2].masked; - irqs[irq].masked=masked; - if(irq < 8) { - if (irqs[irq].active && !irqs[irq].masked) { - PIC_IRQCheck|=(1 << (irq)); - } else { - PIC_IRQCheck&=~(1 << (irq)); - } - } else { - if (irqs[irq].active && !irqs[irq].masked && !irqs[2].masked) { - PIC_IRQCheck|=(1 << (irq)); - } else { - PIC_IRQCheck&=~(1 << (irq)); - } - } - if(irqs[2].masked != old_irq2_mask) { - /* Irq 2 mask has changed recheck second pic */ - for(Bitu i=8;i<=15;i++) { - if (irqs[i].active && !irqs[i].masked && !irqs[2].masked) PIC_IRQCheck|=(1 << (i)); - else PIC_IRQCheck&=~(1 << (i)); - } - } - if (PIC_IRQCheck) { - CPU_CycleLeft+=CPU_Cycles; - CPU_Cycles=0; - } + Bitu t = irq>7 ? (irq - 8): irq; + PIC_Controller * pic=&pics[irq>7 ? 1 : 0]; + //clear bit + Bit8u bit = 1 <<(t); + Bit8u newmask = pic->imr; + newmask &= ~bit; + if (masked) newmask |= bit; + pic->set_imr(newmask); } static void AddEntry(PICEntry * entry) { @@ -463,7 +469,7 @@ void PIC_RemoveEvents(PIC_EventHandler handler) { bool PIC_RunQueue(void) { - /* Check to see if a new milisecond needs to be started */ + /* Check to see if a new millisecond needs to be started */ CPU_CycleLeft+=CPU_Cycles; CPU_Cycles=0; if (CPU_CycleLeft<=0) { @@ -559,11 +565,9 @@ public: PIC_8259A(Section* configuration):Module_base(configuration){ /* Setup pic0 and pic1 with initial values like DOS has normally */ PIC_IRQCheck=0; - PIC_IRQActive=PIC_NOIRQ; PIC_Ticks=0; Bitu i; for (i=0;i<2;i++) { - pics[i].masked=0xff; pics[i].auto_eoi=false; pics[i].rotate_on_auto_eoi=false; pics[i].request_issr=false; @@ -571,24 +575,21 @@ public: pics[i].single=false; pics[i].icw_index=0; pics[i].icw_words=0; + pics[i].irr = pics[i].isr = pics[i].imrr = 0; + pics[i].isrr = pics[i].imr = 0xff; + pics[i].active_irq = 8; } - for (i=0;i<=7;i++) { - irqs[i].active=false; - irqs[i].masked=true; - irqs[i].inservice=false; - irqs[i+8].active=false; - irqs[i+8].masked=true; - irqs[i+8].inservice=false; - irqs[i].vector=0x8+i; - irqs[i+8].vector=0x70+i; - } - irqs[0].masked=false; /* Enable system timer */ - irqs[1].masked=false; /* Enable Keyboard IRQ */ - irqs[2].masked=false; /* Enable second pic */ - irqs[8].masked=false; /* Enable RTC IRQ */ + master.vector_base = 0x08; + slave.vector_base = 0x70; + + PIC_SetIRQMask(0,false); /* Enable system timer */ + PIC_SetIRQMask(1,false); /* Enable system timer */ + PIC_SetIRQMask(2,false); /* Enable second pic */ + PIC_SetIRQMask(8,false); /* Enable RTC IRQ */ + if (machine==MCH_PCJR) { /* Enable IRQ6 (replacement for the NMI for PCJr) */ - irqs[6].masked=false; + PIC_SetIRQMask(6,false); } ReadHandler[0].Install(0x20,read_command,IO_MB); ReadHandler[1].Install(0x21,read_data,IO_MB); @@ -606,6 +607,7 @@ public: pic_queue.free_entry=&pic_queue.entries[0]; pic_queue.next_entry=0; } + ~PIC_8259A(){ } }; From 0adea40353754dd0c33206246c3e4be10ac7025f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 11 Aug 2012 17:47:08 +0000 Subject: [PATCH 3703/4131] remove unused defines Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3793 --- include/pic.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/pic.h b/include/pic.h index 287840de..e311467d 100644 --- a/include/pic.h +++ b/include/pic.h @@ -29,9 +29,6 @@ typedef void (PIC_EOIHandler) (void); typedef void (* PIC_EventHandler)(Bitu val); -#define PIC_MAXIRQ 15 -#define PIC_NOIRQ 0xFF - extern Bitu PIC_IRQCheck; extern Bitu PIC_Ticks; From ad12df4c259342843314cb521de6b9770451d034 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 23 Aug 2012 04:26:32 +0000 Subject: [PATCH 3704/4131] CDROMs are handled differently with no label supplied (see findfirst in drive_local.cpp). Improves College Slam. (thanks ripsaw for spotting this) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3794 --- src/dos/drive_iso.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 73bbad7e..00e120d6 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -255,13 +255,8 @@ bool isoDrive::FindFirst(char *dir, DOS_DTA &dta, bool fcb_findfirst) { dta.GetSearchParams(attr, pattern); if (attr == DOS_ATTR_VOLUME) { - if (strlen(discLabel) != 0) { - dta.SetResult(discLabel, 0, 0, 0, DOS_ATTR_VOLUME); - return true; - } else { - DOS_SetError(DOSERR_NO_MORE_FILES); - return false; - } + dta.SetResult(discLabel, 0, 0, 0, DOS_ATTR_VOLUME); + return true; } else if ((attr & DOS_ATTR_VOLUME) && isRoot && !fcb_findfirst) { if (WildFileCmp(discLabel,pattern)) { // Get Volume Label (DOS_ATTR_VOLUME) and only in basedir and if it matches the searchstring From 361df4799c47ad6b60777557a4953ef565c86ac7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 23 Aug 2012 04:28:34 +0000 Subject: [PATCH 3705/4131] Only copy the parts that have actually data to the requesting client for VTOC and friends. Fixes kickOff 98 (thanks ripsaw). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3795 --- src/dos/dos_mscdex.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 835bcfc7..125c30e9 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -616,8 +616,13 @@ bool CMscdex::GetCopyrightName(Bit16u drive, PhysPt data) { PhysPt ptoc = GetTempBuffer(); success = ReadVTOC(drive,0x00,ptoc,error); if (success) { - MEM_BlockCopy(data,ptoc+702,37); - mem_writeb(data+37,0); + Bitu len; + for (len=0;len<37;len++) { + Bit8u c=mem_readb(ptoc+702+len); + if (c==0 || c==0x20) break; + } + MEM_BlockCopy(data,ptoc+702,len); + mem_writeb(data+len,0); }; return success; } @@ -628,8 +633,13 @@ bool CMscdex::GetAbstractName(Bit16u drive, PhysPt data) { PhysPt ptoc = GetTempBuffer(); success = ReadVTOC(drive,0x00,ptoc,error); if (success) { - MEM_BlockCopy(data,ptoc+739,37); - mem_writeb(data+37,0); + Bitu len; + for (len=0;len<37;len++) { + Bit8u c=mem_readb(ptoc+739+len); + if (c==0 || c==0x20) break; + } + MEM_BlockCopy(data,ptoc+739,len); + mem_writeb(data+len,0); }; return success; } @@ -640,8 +650,13 @@ bool CMscdex::GetDocumentationName(Bit16u drive, PhysPt data) { PhysPt ptoc = GetTempBuffer(); success = ReadVTOC(drive,0x00,ptoc,error); if (success) { - MEM_BlockCopy(data,ptoc+776,37); - mem_writeb(data+37,0); + Bitu len; + for (len=0;len<37;len++) { + Bit8u c=mem_readb(ptoc+776+len); + if (c==0 || c==0x20) break; + } + MEM_BlockCopy(data,ptoc+776,len); + mem_writeb(data+len,0); }; return success; } From 36f2cb29f4d5c1ff2f0438744cc2ad0d7aa6d327 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 2 Sep 2012 13:45:31 +0000 Subject: [PATCH 3706/4131] Fix Maagi (finnish game) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3796 --- src/dos/dos_files.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 5726f4f5..326eb77a 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -92,7 +92,7 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { case '!': case '%': case '{': case '}': case '`': case '~': case '_': case '-': case '.': case '*': case '?': case '&': case '\'': case '+': case '^': case 246: case 255: case 0xa0: - case 0xe5: case 0xbd: case 0x9d: + case 0x84: case 0xe5: case 0xbd: case 0x9d: upname[w++]=c; break; default: From 2ea5727f6a5d4649d09338ab879b11886e52ed43 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 2 Sep 2012 14:33:23 +0000 Subject: [PATCH 3707/4131] undo fix for maagi. it doesn't work correctly afterall Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3797 --- src/dos/dos_files.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 326eb77a..5726f4f5 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -92,7 +92,7 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { case '!': case '%': case '{': case '}': case '`': case '~': case '_': case '-': case '.': case '*': case '?': case '&': case '\'': case '+': case '^': case 246: case 255: case 0xa0: - case 0x84: case 0xe5: case 0xbd: case 0x9d: + case 0xe5: case 0xbd: case 0x9d: upname[w++]=c; break; default: From 6cdc27910a667cae42f498d7cc2f507a45efbbae Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 25 Sep 2012 20:17:26 +0000 Subject: [PATCH 3708/4131] Fix oversight in r3666. (danoon) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3798 --- src/dos/dos_files.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 5726f4f5..51e89210 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1127,7 +1127,7 @@ Bit8u DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u * numRec,bool restore) fcb.GetRandom(random); fcb.SetRecord((Bit16u)(random / 128),(Bit8u)(random & 127)); if (restore) fcb.GetRecord(old_block,old_rec); - if (numRec>0) { + if (*numRec > 0) { /* Write records */ for (count=0; count<*numRec; count++) { error = DOS_FCBWrite(seg,offset,count);// dos_fcbwrite return 0 false when true... @@ -1141,7 +1141,7 @@ Bit8u DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u * numRec,bool restore) fcb.GetRecord(new_block,new_rec); if (restore) fcb.SetRecord(old_block,old_rec); /* Update the random record pointer with new position only when restore is false */ - if(!restore) fcb.SetRandom(new_block*128+new_rec); + if (!restore) fcb.SetRandom(new_block*128+new_rec); return error; } From b3fed43584e5a94acdb193e654986e6818602795 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Oct 2012 11:14:44 +0000 Subject: [PATCH 3709/4131] use local labels in defines so that -lto works with gcc Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3799 --- src/fpu/fpu_instructions_x86.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index 7a7402ae..489d8509 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -660,9 +660,9 @@ "fstpt (%2, %%eax) \n" \ "movw %0, %%ax \n" \ "sahf \n" \ - "jp argument_too_large1 \n" \ + "jp 1f \n" \ "fstpt (%2, %1) \n" \ - "argument_too_large1: " \ + "1: " \ : "=m" (new_sw) \ : "r" (TOP), "r" (fpu.p_regs) \ : "eax", "cc", "memory" \ @@ -686,9 +686,9 @@ "fstpt (%2, %%eax) \n" \ "movw %0, %%ax \n" \ "sahf \n" \ - "jp argument_too_large2 \n" \ + "jp 1f \n" \ "fstpt (%2, %1) \n" \ - "argument_too_large2: " \ + "1: " \ : "=m" (new_sw) \ : "r" (TOP), "r" (fpu.p_regs) \ : "eax", "cc", "memory" \ From 49fe397b0d4d175c1a8bcfdad85a05660b029596 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 12 Nov 2012 18:32:27 +0000 Subject: [PATCH 3710/4131] Fix some 64 bit warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3800 --- src/shell/shell_cmds.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 1e42d103..ab23be37 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -369,8 +369,8 @@ void DOS_Shell::CMD_RMDIR(char * args) { } } -static void FormatNumber(Bitu num,char * buf) { - Bitu numm,numk,numb,numg; +static void FormatNumber(Bit32u num,char * buf) { + Bit32u numm,numk,numb,numg; numb=num % 1000; num/=1000; numk=num % 1000; @@ -960,7 +960,7 @@ void DOS_Shell::CMD_DATE(char * args) { return; } // check if a date was passed in command line - Bitu newday,newmonth,newyear; + Bit32u newday,newmonth,newyear; if(sscanf(args,"%u-%u-%u",&newmonth,&newday,&newyear)==3) { reg_cx = newyear; reg_dh = newmonth; @@ -976,7 +976,7 @@ void DOS_Shell::CMD_DATE(char * args) { CALLBACK_RunRealInt(0x21); const char* datestring = MSG_Get("SHELL_CMD_DATE_DAYS"); - Bit8u length; + Bit32u length; char day[6] = {0}; if(sscanf(datestring,"%u",&length) && (length<5) && (strlen(datestring)==(length*7+1))) { // date string appears valid @@ -994,9 +994,9 @@ void DOS_Shell::CMD_DATE(char * args) { buffer[bufferptr] = formatstring[i]; bufferptr++; } else { - if(formatstring[i]=='M') bufferptr += sprintf(buffer+bufferptr,"%02u",(Bitu)reg_dh); - if(formatstring[i]=='D') bufferptr += sprintf(buffer+bufferptr,"%02u",(Bitu)reg_dl); - if(formatstring[i]=='Y') bufferptr += sprintf(buffer+bufferptr,"%04u",(Bitu)reg_cx); + if(formatstring[i]=='M') bufferptr += sprintf(buffer+bufferptr,"%02u",(Bit8u) reg_dh); + if(formatstring[i]=='D') bufferptr += sprintf(buffer+bufferptr,"%02u",(Bit8u) reg_dl); + if(formatstring[i]=='Y') bufferptr += sprintf(buffer+bufferptr,"%04u",(Bit16u) reg_cx); } } WriteOut("%s %s\n",day, buffer); From 23323c97ef85017237b9a100aa124ab204d24899 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 12 Nov 2012 18:39:58 +0000 Subject: [PATCH 3711/4131] some tiny sanity checks Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3801 --- src/debug/debug_gui.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 60166d91..44adfd4a 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -86,6 +86,7 @@ void DEBUG_RefreshPage(char scroll) { list::iterator i = logBuffPos; int maxy, maxx; getmaxyx(dbg.win_out,maxy,maxx); int rem_lines = maxy; + if(rem_lines == -1) return; wclear(dbg.win_out); @@ -109,7 +110,7 @@ void LOG::operator() (char const* format, ...){ if (d_type>=LOG_MAX) return; if ((d_severity!=LOG_ERROR) && (!loggrp[d_type].enabled)) return; - DEBUG_ShowMsg("%10u: %s:%s\n",cycle_count,loggrp[d_type].front,buf); + DEBUG_ShowMsg("%10u: %s:%s\n",static_cast(cycle_count),loggrp[d_type].front,buf); } @@ -179,6 +180,7 @@ static void MakeSubWindows(void) { outy+=5; // 34 /* The Output Window */ dbg.win_out=subwin(dbg.win_main,win_main_maxy-outy,win_main_maxx,outy,0); + if(!dbg.win_reg ||!dbg.win_data || !dbg.win_code || !dbg.win_var || !dbg.win_out) E_Exit("Setting up windows failed"); // dbg.input_y=win_main_maxy-1; scrollok(dbg.win_out,TRUE); DrawBars(); From e93bc1e55825312e1a12173fe6312b7b502a86d4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 14 Nov 2012 13:22:04 +0000 Subject: [PATCH 3712/4131] Enable interrupt flag after call 0x11 as well. Thanks ripsaw. Fixes a Korean game Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3802 --- src/ints/bios_keyboard.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index b17328e7..0ad09c36 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -514,7 +514,7 @@ static Bitu INT16_Handler(void) { break; case 0x01: /* CHECK FOR KEYSTROKE */ // enable interrupt-flag after IRET of this int16 - mem_writew(SegPhys(ss)+reg_sp+4,(mem_readw(SegPhys(ss)+reg_sp+4) | FLAG_IF)); + CALLBACK_SIF(true); for (;;) { if (check_key(temp)) { if (!IsEnhancedKey(temp)) { @@ -535,6 +535,8 @@ static Bitu INT16_Handler(void) { } break; case 0x11: /* CHECK FOR KEYSTROKE (enhanced keyboards only) */ + // enable interrupt-flag after IRET of this int16 + CALLBACK_SIF(true); if (!check_key(temp)) { CALLBACK_SZF(true); } else { From a6a7f4b82d093d74c211c479830bf6d99e35bfaf Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 28 Nov 2012 17:28:38 +0000 Subject: [PATCH 3713/4131] Make Visual Studio happy as well. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3803 --- src/shell/shell_cmds.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index ab23be37..222c090c 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -962,9 +962,9 @@ void DOS_Shell::CMD_DATE(char * args) { // check if a date was passed in command line Bit32u newday,newmonth,newyear; if(sscanf(args,"%u-%u-%u",&newmonth,&newday,&newyear)==3) { - reg_cx = newyear; - reg_dh = newmonth; - reg_dl = newday; + reg_cx = static_cast(newyear); + reg_dh = static_cast(newmonth); + reg_dl = static_cast(newday); reg_ah=0x2b; // set system date CALLBACK_RunRealInt(0x21); @@ -980,7 +980,7 @@ void DOS_Shell::CMD_DATE(char * args) { char day[6] = {0}; if(sscanf(datestring,"%u",&length) && (length<5) && (strlen(datestring)==(length*7+1))) { // date string appears valid - for(int i = 0; i < length; i++) day[i] = datestring[reg_al*length+1+i]; + for(Bit32u i = 0; i < length; i++) day[i] = datestring[reg_al*length+1+i]; } bool dateonly = ScanCMDBool(args,"t"); if(!dateonly) WriteOut(MSG_Get("SHELL_CMD_DATE_NOW")); From e60a44755a07dd855344244f10ac907a2880e4da Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 28 Nov 2012 18:35:35 +0000 Subject: [PATCH 3714/4131] Add composite lite patch by VileRancour/reenigne. Thanks to everybody who participated in the discussion on the subject. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3804 --- src/hardware/vga_draw.cpp | 50 ++++----- src/hardware/vga_other.cpp | 211 +++++++++++++++++++++++++++++-------- src/shell/shell.cpp | 3 +- 3 files changed, 188 insertions(+), 76 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index e4a57ef4..5659b289 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -79,38 +79,28 @@ static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart, Bitu line) { const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift); #define CGA16_READER(OFF) (base[(vidstart +(OFF))& (8*1024 -1)]) Bit32u * draw=(Bit32u *)TempLine; - //Generate a temporary bitline to calculate the avarage - //over bit-2 bit-1 bit bit+1. - //Combine this number with the current colour to get - //an unique index in the pallette. Or it with bit 7 as they are stored - //in the upperpart to keep them from interfering the regular cga stuff + //There are 640 hdots in each line of the screen. + //The color of an even hdot always depends on only 4 bits of video RAM. + //The color of an odd hdot depends on 4 bits of video RAM in + //1-hdot-per-pixel modes and 6 bits of video RAM in 2-hdot-per-pixel + //modes. We always assume 6 and use duplicate palette entries in + //1-hdot-per-pixel modes so that we can use the same routine for all + //composite modes. + temp[1] = (CGA16_READER(0) >> 6) & 3; + for(Bitu x = 2; x < 640; x+=2) { + temp[x] = (temp[x-1] & 0xf); + temp[x+1] = (temp[x] << 2) | ((( CGA16_READER(x>>3)) >> (6-(x&6)) )&3); + } + temp[640] = temp[639] & 0xf; + temp[641] = temp[640] << 2; + temp[642] = temp[641] & 0xf; - for(Bitu x = 0; x < 640; x++) - temp[x+2] = (( CGA16_READER(x>>3)>> (7-(x&7)) )&1) << 4; - //shift 4 as that is for the index. - Bitu i = 0,temp1,temp2,temp3,temp4; + Bitu i = 2; for (Bitu x=0;x>= 4; - - temp1 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; - temp2 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; - temp3 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; - temp4 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; - - *draw++ = 0x80808080|(temp1|val1) | - ((temp2|val1) << 8) | - ((temp3|val1) <<16) | - ((temp4|val1) <<24); - temp1 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; - temp2 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; - temp3 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; - temp4 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; - *draw++ = 0x80808080|(temp1|val2) | - ((temp2|val2) << 8) | - ((temp3|val2) <<16) | - ((temp4|val2) <<24); + *draw++ = 0xc0708030 | temp[i] | (temp[i+1] << 8) | (temp[i+2] << 16) | (temp[i+3] << 24); + i += 4; + *draw++ = 0xc0708030 | temp[i] | (temp[i+1] << 8) | (temp[i+2] << 16) | (temp[i+3] << 24); + i += 4; } return TempLine; #undef CGA16_READER diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 51b98ed3..34b09336 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -176,6 +176,9 @@ static void write_lightpen(Bitu port,Bitu val,Bitu) { } static double hue_offset = 0.0; +static Bit8u cga_comp = 0; +static bool new_cga = 0; + static Bit8u cga16_val = 0; static void update_cga16_color(void); static Bit8u herc_pal = 0; @@ -186,57 +189,151 @@ static void cga16_color_select(Bit8u val) { } static void update_cga16_color(void) { -// Algorithm provided by NewRisingSun -// His/Her algorithm is more complex and gives better results than the one below -// However that algorithm doesn't fit in our vga pallette. -// Therefore a simple variant is used, but the colours are bit lighter. +// New algorithm based on code by reenigne +// Works in all CGA graphics modes/color settings and can simulate older and newer CGA revisions + static const double tau = 6.28318531; // == 2*pi + static const double ns = 567.0/440; // degrees of hue shift per nanosecond -// It uses an avarage over the bits to give smooth transitions from colour to colour -// This is represented by the j variable. The i variable gives the 16 colours -// The draw handler calculates the needed avarage and combines this with the colour -// to match an entry that is generated here. + double tv_brightness = 0.0; // hardcoded for simpler implementation + double tv_saturation = (new_cga ? 0.7 : 0.6); - int baseR=0, baseG=0, baseB=0; - double sinhue,coshue,hue,basehue = 50.0; - double I,Q,Y,pixelI,pixelQ,R,G,B; - Bitu colorBit1,colorBit2,colorBit3,colorBit4,index; + bool bw = (vga.tandy.mode_control&4) != 0; + bool color_sel = (cga16_val&0x20) != 0; + bool background_i = (cga16_val&0x10) != 0; // Really foreground intensity, but this is what the CGA schematic calls it. + bool bpp1 = (vga.tandy.mode_control&0x10) != 0; + Bit8u overscan = cga16_val&0x0f; // aka foreground colour in 1bpp mode - if (cga16_val & 0x01) baseB += 0xa8; - if (cga16_val & 0x02) baseG += 0xa8; - if (cga16_val & 0x04) baseR += 0xa8; - if (cga16_val & 0x08) { baseR += 0x57; baseG += 0x57; baseB += 0x57; } - if (cga16_val & 0x20) basehue = 35.0; + double chroma_coefficient = new_cga ? 0.29 : 0.72; + double b_coefficient = new_cga ? 0.07 : 0; + double g_coefficient = new_cga ? 0.22 : 0; + double r_coefficient = new_cga ? 0.1 : 0; + double i_coefficient = new_cga ? 0.32 : 0.28; + double rgbi_coefficients[0x10]; + for (int c = 0; c < 0x10; c++) { + double v = 0; + if ((c & 1) != 0) + v += b_coefficient; + if ((c & 2) != 0) + v += g_coefficient; + if ((c & 4) != 0) + v += r_coefficient; + if ((c & 8) != 0) + v += i_coefficient; + rgbi_coefficients[c] = v; + } - hue = (basehue + hue_offset)*0.017453239; - sinhue = sin(hue); - coshue = cos(hue); + // The pixel clock delay calculation is not accurate for 2bpp, but the difference is small and a more accurate calculation would be too slow. + static const double rgbi_pixel_delay = 15.5*ns; + static const double chroma_pixel_delays[8] = { + 0, // Black: no chroma + 35*ns, // Blue: no XORs + 44.5*ns, // Green: XOR on rising and falling edges + 39.5*ns, // Cyan: XOR on falling but not rising edge + 44.5*ns, // Red: XOR on rising and falling edges + 39.5*ns, // Magenta: XOR on falling but not rising edge + 44.5*ns, // Yellow: XOR on rising and falling edges + 39.5*ns}; // White: XOR on falling but not rising edge + double pixel_clock_delay; + int o = overscan == 0 ? 15 : overscan; + if (overscan == 8) + pixel_clock_delay = rgbi_pixel_delay; + else { + double d = rgbi_coefficients[o]; + pixel_clock_delay = (chroma_pixel_delays[o & 7]*chroma_coefficient + rgbi_pixel_delay*d)/(chroma_coefficient + d); + } + pixel_clock_delay -= 21.5*ns; // correct for delay of color burst - for(Bitu i = 0; i < 16;i++) { - for(Bitu j = 0;j < 5;j++) { - index = 0x80|(j << 4)|i; //use upperpart of vga pallette - colorBit4 = (i&1)>>0; - colorBit3 = (i&2)>>1; - colorBit2 = (i&4)>>2; - colorBit1 = (i&8)>>3; + double hue_adjust = (-(90-33)-hue_offset+pixel_clock_delay)*tau/360.0; + double chroma_signals[8][4]; + for (Bit8u i=0; i<4; i++) { + chroma_signals[0][i] = 0; + chroma_signals[7][i] = 1; + for (Bit8u j=0; j<6; j++) { + static const double phases[6] = { + 270 - 21.5*ns, // blue + 135 - 29.5*ns, // green + 180 - 21.5*ns, // cyan + 0 - 21.5*ns, // red + 315 - 29.5*ns, // magenta + 90 - 21.5*ns}; // yellow/burst + // All the duty cycle fractions are the same, just under 0.5 as the rising edge is delayed 2ns more than the falling edge. + static const double duty = 0.5 - 2*ns/360.0; - //calculate lookup table - I = 0; Q = 0; - I += (double) colorBit1; - Q += (double) colorBit2; - I -= (double) colorBit3; - Q -= (double) colorBit4; - Y = (double) j / 4.0; //calculated avarage is over 4 bits + // We have a rectangle wave with period 1 (in units of the reciprocal of the color burst frequency) and duty + // cycle fraction "duty" and phase "phase". We band-limit this wave to frequency 2 and sample it at intervals of 1/4. + // We model our band-limited wave with 4 frequency components: + // f(x) = a + b*sin(x*tau) + c*cos(x*tau) + d*sin(x*2*tau) + // Then: + // a = integral(0, 1, f(x)*dx) = duty + // b = 2*integral(0, 1, f(x)*sin(x*tau)*dx) = 2*integral(0, duty, sin(x*tau)*dx) = 2*(1-cos(x*tau))/tau + // c = 2*integral(0, 1, f(x)*cos(x*tau)*dx) = 2*integral(0, duty, cos(x*tau)*dx) = 2*sin(duty*tau)/tau + // d = 2*integral(0, 1, f(x)*sin(x*2*tau)*dx) = 2*integral(0, duty, sin(x*4*pi)*dx) = 2*(1-cos(2*tau*duty))/(2*tau) + double a = duty; + double b = 2.0*(1.0-cos(duty*tau))/tau; + double c = 2.0*sin(duty*tau)/tau; + double d = 2.0*(1.0-cos(duty*2*tau))/(2*tau); - pixelI = I * 1.0 / 3.0; //I* tvSaturnation / 3.0 - pixelQ = Q * 1.0 / 3.0; //Q* tvSaturnation / 3.0 - I = pixelI*coshue + pixelQ*sinhue; - Q = pixelQ*coshue - pixelI*sinhue; + double x = (phases[j] + 21.5*ns + pixel_clock_delay)/360.0 + i/4.0; - R = Y + 0.956*I + 0.621*Q; if (R < 0.0) R = 0.0; if (R > 1.0) R = 1.0; - G = Y - 0.272*I - 0.647*Q; if (G < 0.0) G = 0.0; if (G > 1.0) G = 1.0; - B = Y - 1.105*I + 1.702*Q; if (B < 0.0) B = 0.0; if (B > 1.0) B = 1.0; + chroma_signals[j+1][i] = a + b*sin(x*tau) + c*cos(x*tau) + d*sin(x*2*tau); + } + } + Bitu CGApal[4] = { + overscan, + 2 + (color_sel||bw ? 1 : 0) + (background_i ? 8 : 0), + 4 + (color_sel&&!bw? 1 : 0) + (background_i ? 8 : 0), + 6 + (color_sel||bw ? 1 : 0) + (background_i ? 8 : 0) + }; + for (Bit8u x=0; x<4; x++) { // Position of pixel in question + bool even = (x & 1) == 0; + for (Bit8u bits=0; bits<(even ? 0x10 : 0x40); ++bits) { + double Y=0, I=0, Q=0; + for (Bit8u p=0; p<4; p++) { // Position within color carrier cycle + // generate pixel pattern. + Bit8u rgbi; + if (bpp1) + rgbi = ((bits >> (3-p)) & (even ? 1 : 2)) != 0 ? overscan : 0; + else + if (even) + rgbi = CGApal[(bits >> (2-(p&2)))&3]; + else + rgbi = CGApal[(bits >> (4-((p+1)&6)))&3]; + Bit8u c = rgbi & 7; + if (bw && c != 0) + c = 7; - RENDER_SetPal((Bit8u)index,static_cast(R*baseR),static_cast(G*baseG),static_cast(B*baseB)); + // calculate composite output + double chroma = chroma_signals[c][(p+x)&3]*chroma_coefficient; + double composite = chroma + rgbi_coefficients[rgbi]; + + Y+=composite; + if (!bw) { // burst on + I+=composite*2*cos(hue_adjust + (p+x)*tau/4.0); + Q+=composite*2*sin(hue_adjust + (p+x)*tau/4.0); + } + } + + double contrast = 1 - tv_brightness; + + Y = (contrast*Y/4.0) + tv_brightness; if (Y>1.0) Y=1.0; if (Y<0.0) Y=0.0; + I = (contrast*I/4.0) * tv_saturation; if (I>0.5957) I=0.5957; if (I<-0.5957) I=-0.5957; + Q = (contrast*Q/4.0) * tv_saturation; if (Q>0.5226) Q=0.5226; if (Q<-0.5226) Q=-0.5226; + + static const double gamma = 2.2; + + double R = Y + 0.9563*I + 0.6210*Q; R = (R - 0.075) / (1-0.075); if (R<0) R=0; if (R>1) R=1; + double G = Y - 0.2721*I - 0.6474*Q; G = (G - 0.075) / (1-0.075); if (G<0) G=0; if (G>1) G=1; + double B = Y - 1.1069*I + 1.7046*Q; B = (B - 0.075) / (1-0.075); if (B<0) B=0; if (B>1) B=1; + R = pow(R, gamma); + G = pow(G, gamma); + B = pow(B, gamma); + + int r = static_cast(255*pow( 1.5073*R -0.3725*G -0.0832*B, 1/gamma)); if (r<0) r=0; if (r>255) r=255; + int g = static_cast(255*pow(-0.0275*R +0.9350*G +0.0670*B, 1/gamma)); if (g<0) g=0; if (g>255) g=255; + int b = static_cast(255*pow(-0.0272*R -0.0401*G +1.1677*B, 1/gamma)); if (b<0) b=0; if (b>255) b=255; + + Bit8u index = bits | ((x & 1) == 0 ? 0x30 : 0x80) | ((x & 2) == 0 ? 0x40 : 0); + RENDER_SetPal(index,r,g,b); } } } @@ -294,12 +391,18 @@ static void write_cga(Bitu port,Bitu val,Bitu /*iolen*/) { vga.attr.disabled = (val&0x8)? 0: 1; if (vga.tandy.mode_control & 0x2) { // graphics mode if (vga.tandy.mode_control & 0x10) {// highres mode - if (!(val & 0x4)) { // burst on - VGA_SetMode(M_CGA16); // composite ntsc 160x200 16 color mode + if (cga_comp==1 || (cga_comp==0 && !(val&0x4))) { // composite display + VGA_SetMode(M_CGA16); // composite ntsc 640x200 16 color mode } else { VGA_SetMode(M_TANDY2); } - } else VGA_SetMode(M_TANDY4); // lowres mode + } else { // lowres mode + if (cga_comp==1) { // composite display + VGA_SetMode(M_CGA16); // composite ntsc 640x200 16 color mode + } else { + VGA_SetMode(M_TANDY4); + } + } write_cga_color_select(vga.tandy.color_select); } else { @@ -313,6 +416,22 @@ static void write_cga(Bitu port,Bitu val,Bitu /*iolen*/) { } } +static void CGAModel(bool pressed) { + if (!pressed) return; + new_cga = !new_cga; + update_cga16_color(); + LOG_MSG("%s model CGA selected", new_cga ? "Late" : "Early"); +} + +static void Composite(bool pressed) { + if (!pressed) return; + if (++cga_comp>2) cga_comp=0; + LOG_MSG("Composite output: %s",(cga_comp==0)?"auto":((cga_comp==1)?"on":"off")); + // switch RGB and Composite if in graphics mode + if (vga.tandy.mode_control & 0x2) + write_cga(0x3d8,vga.tandy.mode_control,1); +} + static void tandy_update_palette() { // TODO mask off bits if needed if (machine == MCH_TANDY) { @@ -699,6 +818,8 @@ void VGA_SetupOther(void) { IO_RegisterWriteHandler(0x3d9,write_cga,IO_MB); MAPPER_AddHandler(IncreaseHue,MK_f11,MMOD2,"inchue","Inc Hue"); MAPPER_AddHandler(DecreaseHue,MK_f11,0,"dechue","Dec Hue"); + MAPPER_AddHandler(CGAModel,MK_f11,MMOD1|MMOD2,"cgamodel","CGA Model"); + MAPPER_AddHandler(Composite,MK_f12,0,"cgacomp","CGA Comp"); } if (machine==MCH_TANDY) { write_tandy( 0x3df, 0x0, 0 ); diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index af04125c..8342bd2a 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -523,7 +523,8 @@ void SHELL_Init() { "\xBA \xBA\n" ); MSG_Add("SHELL_STARTUP_CGA","\xBA DOSBox supports Composite CGA mode. \xBA\n" - "\xBA Use \033[31m(alt-)F11\033[37m to change the colours when in this mode. \xBA\n" + "\xBA Use \033[31mF12\033[37m to set composite output ON, OFF, or AUTO (default). \xBA\n" + "\xBA \033[31m(Alt-)F11\033[37m changes hue; \033[31mctrl-alt-F11\033[37m selects early/late CGA model. \xBA\n" "\xBA \xBA\n" ); MSG_Add("SHELL_STARTUP_HERC","\xBA Use \033[31mF11\033[37m to cycle through white, amber, and green monochrome color. \xBA\n" From 7e8381037eb7f689ccb0457052f8f32aeb018301 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 7 Dec 2012 20:40:30 +0000 Subject: [PATCH 3715/4131] Fix crash on exit on gnome-terminal 3.4.1.1 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3805 --- src/debug/debug.cpp | 9 +++++---- src/debug/debug_gui.cpp | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 7b76d573..8a3846c6 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -2105,8 +2105,9 @@ void DEBUG_SetupConsole(void) { WIN32_Console(); #else tcgetattr(0,&consolesettings); - printf("\e[8;50;80t"); //resize terminal - fflush(NULL); + //curses must be inited first in order to catch the resize (is an event) +// printf("\e[8;50;80t"); //resize terminal +// fflush(NULL); #endif memset((void *)&dbg,0,sizeof(dbg)); debugging=false; @@ -2123,8 +2124,8 @@ void DEBUG_ShutDown(Section * /*sec*/) { #ifndef WIN32 tcsetattr(0, TCSANOW,&consolesettings); // printf("\e[0m\e[2J"); //Seems to destroy scrolling - printf("\ec"); - fflush(NULL); +// printf("\ec"); //Doesn't seem to be needed anymore +// fflush(NULL); #endif } diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 44adfd4a..d1b8bbc4 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -274,6 +274,8 @@ void DBGUI_StartUp(void) { nodelay(dbg.win_main,true); keypad(dbg.win_main,true); #ifndef WIN32 + printf("\e[8;50;80t"); + fflush(NULL); resizeterm(50,80); touchwin(dbg.win_main); #endif From 5eb1217cb41a4967897636a0c1fd8109a5b334f2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 26 Dec 2012 16:14:19 +0000 Subject: [PATCH 3716/4131] Move buffer to class for upcomming multiple floppy support (rcblanke). Remove heavy bios_disk dependency from drives.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3806 --- src/dos/dos_programs.cpp | 1 + src/dos/drive_fat.cpp | 4 +--- src/dos/drives.h | 7 +++++-- src/ints/bios_disk.cpp | 1 + src/shell/shell_cmds.cpp | 1 + 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 856825a5..632efac1 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -33,6 +33,7 @@ #include "dos_system.h" #include "dos_inc.h" #include "bios.h" +#include "bios_disk.h" #include "setup.h" #include "control.h" diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 052d9769..44d23ada 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -27,6 +27,7 @@ #include "support.h" #include "cross.h" #include "bios.h" +#include "bios_disk.h" #define IMGTYPE_FLOPPY 0 #define IMGTYPE_ISO 1 @@ -36,9 +37,6 @@ #define FAT16 1 #define FAT32 2 -Bit8u fatSectBuffer[1024]; -Bit32u curFatSect; - class fatFile : public DOS_File { public: fatFile(const char* name, Bit32u startCluster, Bit32u fileLen, fatDrive *useDrive); diff --git a/src/dos/drives.h b/src/dos/drives.h index d3c47bdb..18ff21d0 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -24,7 +24,6 @@ #include #include "dos_system.h" #include "shell.h" /* for DOS_Shell */ -#include "bios_disk.h" /* for fatDrive */ bool WildFileCmp(const char * file, const char * wild); void Set_Label(char const * const input, char * const output, bool cdrom); @@ -142,7 +141,8 @@ struct partTable { #ifdef _MSC_VER #pragma pack () #endif - +//Forward +class imageDisk; class fatDrive : public DOS_Drive { public: fatDrive(const char * sysFilename, Bit32u bytesector, Bit32u cylsector, Bit32u headscyl, Bit32u cylinders, Bit32u startSector); @@ -207,6 +207,9 @@ private: Bit32u cwdDirCluster; Bit32u dirPosition; /* Position in directory search */ + + Bit8u fatSectBuffer[1024]; + Bit32u curFatSect; }; diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 952987ed..f3d3e9ae 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -20,6 +20,7 @@ #include "dosbox.h" #include "callback.h" #include "bios.h" +#include "bios_disk.h" #include "regs.h" #include "mem.h" #include "dos_inc.h" /* for Drives[] */ diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 222c090c..314cf25e 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -21,6 +21,7 @@ #include "shell.h" #include "callback.h" #include "regs.h" +#include "bios.h" #include "../dos/drives.h" #include "support.h" #include "control.h" From 0997973e0d680420f9c7fd16f22b243885cdf39d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 27 Dec 2012 21:24:46 +0000 Subject: [PATCH 3717/4131] Add some way to search for the volume label on a fatDrive. Merged the patch of ripsaw and rcblanke together.. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3807 --- src/dos/drive_fat.cpp | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 44d23ada..59caf294 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -526,6 +526,10 @@ Bit32u fatDrive::getAbsoluteSectFromChain(Bit32u startClustNum, Bit32u logicalSe } if((isEOF) && (skipClust>=1)) { //LOG_MSG("End of cluster chain reached before end of logical sector seek!"); + if (skipClust == 1 && fattype == FAT12) { + //break; + LOG(LOG_DOSMISC,LOG_ERROR)("End of cluster chain reached, but maybe good afterall ?"); + } return 0; } currentClust = testvalue; @@ -722,6 +726,9 @@ fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, memset(fatSectBuffer,0,1024); curFatSect = 0xffffffff; + + strcpy(info, "fatDrive "); + strcat(info, sysFilename); } bool fatDrive::AllocationInfo(Bit16u *_bytes_sector, Bit8u *_sectors_cluster, Bit16u *_total_clusters, Bit16u *_free_clusters) { @@ -853,6 +860,7 @@ bool fatDrive::FileUnlink(char * name) { bool fatDrive::FindFirst(char *_dir, DOS_DTA &dta,bool /*fcb_findfirst*/) { direntry dummyClust; +#if 0 Bit8u attr;char pattern[DOS_NAMELENGTH_ASCII]; dta.GetSearchParams(attr,pattern); if(attr==DOS_ATTR_VOLUME) { @@ -865,6 +873,7 @@ bool fatDrive::FindFirst(char *_dir, DOS_DTA &dta,bool /*fcb_findfirst*/) { } if(attr & DOS_ATTR_VOLUME) //check for root dir or fcb_findfirst LOG(LOG_DOSMISC,LOG_WARN)("findfirst for volumelabel used on fatDrive. Unhandled!!!!!"); +#endif if(!getDirClustNum(_dir, &cwdDirCluster, false)) { DOS_SetError(DOSERR_PATH_NOT_FOUND); return false; @@ -932,23 +941,31 @@ nextfile: DOS_SetError(DOSERR_NO_MORE_FILES); return false; } - memset(find_name,0,DOS_NAMELENGTH_ASCII); memset(extension,0,4); memcpy(find_name,§buf[entryoffset].entryname[0],8); memcpy(extension,§buf[entryoffset].entryname[8],3); trimString(&find_name[0]); trimString(&extension[0]); - if(!(sectbuf[entryoffset].attrib & DOS_ATTR_DIRECTORY) || extension[0]!=0) { + + //if(!(sectbuf[entryoffset].attrib & DOS_ATTR_DIRECTORY)) + if (extension[0]!=0) { strcat(find_name, "."); strcat(find_name, extension); } - /* Ignore files with volume label. FindFirst should search for those. (return the first one found) */ - if(sectbuf[entryoffset].attrib & 0x8) goto nextfile; - - /* Always find ARCHIVES even if bit is not set Perhaps test is not the best test */ - if(~attrs & sectbuf[entryoffset].attrib & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM) ) goto nextfile; + /* Compare attributes to search attributes */ + + //TODO What about attrs = DOS_ATTR_VOLUME|DOS_ATTR_DIRECTORY ? + if (attrs == DOS_ATTR_VOLUME) { + if (!(sectbuf[entryoffset].attrib & DOS_ATTR_VOLUME)) goto nextfile; + dirCache.SetLabel(find_name, false, true); + } else { + if (~attrs & sectbuf[entryoffset].attrib & (DOS_ATTR_DIRECTORY | DOS_ATTR_VOLUME | DOS_ATTR_SYSTEM | DOS_ATTR_HIDDEN) ) goto nextfile; + } + + + /* Compare name to search pattern */ if(!WildFileCmp(find_name,srch_pattern)) goto nextfile; dta.SetResult(find_name, sectbuf[entryoffset].entrysize, sectbuf[entryoffset].crtDate, sectbuf[entryoffset].crtTime, sectbuf[entryoffset].attrib); From 5e5fac479e2a3522147d61fa430ce5e6422a8e6f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 30 Dec 2012 17:47:28 +0000 Subject: [PATCH 3718/4131] Last part of multi floppy patch by rcblanke. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3808 --- src/dos/dos_programs.cpp | 199 ++++++++++++++++++++++----------------- 1 file changed, 115 insertions(+), 84 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 632efac1..2754ed1a 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1214,10 +1214,6 @@ public: } if (paths.size() == 1) temp_line = paths[0]; - if (paths.size() > 1 && fstype != "iso") { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MULTIPLE_NON_CUEISO_FILES")); - return; - } if(fstype=="fat") { if (imgsizedetect) { @@ -1249,12 +1245,122 @@ public: LOG_MSG("autosized image file: %d:%d:%d:%d",sizes[0],sizes[1],sizes[2],sizes[3]); } - newdrive=new fatDrive(temp_line.c_str(),sizes[0],sizes[1],sizes[2],sizes[3],0); - if(!(dynamic_cast(newdrive))->created_successfully) { - delete newdrive; - newdrive = 0; + if (Drives[drive-'A']) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_ALREADY_MOUNTED")); + return; + } + + std::vector imgDisks; + std::vector::size_type i; + std::vector::size_type ct; + + for (i = 0; i < paths.size(); i++) { + DOS_Drive* newDrive = new fatDrive(paths[i].c_str(),sizes[0],sizes[1],sizes[2],sizes[3],0); + imgDisks.push_back(newDrive); + if(!(dynamic_cast(newDrive))->created_successfully) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_CANT_CREATE")); + for(ct = 0; ct < imgDisks.size(); ct++) { + delete imgDisks[ct]; + } + return; + } + } + + // Update DriveManager + for(ct = 0; ct < imgDisks.size(); ct++) { + DriveManager::AppendDisk(drive - 'A', imgDisks[ct]); + } + DriveManager::InitializeDrive(drive - 'A'); + + // Set the correct media byte in the table + mem_writeb(Real2Phys(dos.tables.mediaid) + (drive - 'A') * 2, mediaid); + + /* Command uses dta so set it to our internal dta */ + RealPt save_dta = dos.dta(); + dos.dta(dos.tables.tempdta); + + for(ct = 0; ct < imgDisks.size(); ct++) { + DriveManager::CycleAllDisks(); + + char root[4] = {drive, ':', '\\', 0}; + DOS_FindFirst(root, DOS_ATTR_VOLUME); // force obtaining the label and saving it in dirCache + } + dos.dta(save_dta); + + std::string tmp(paths[0]); + for (i = 1; i < paths.size(); i++) { + tmp += "; " + paths[i]; + } + WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"), drive, tmp.c_str()); + + if (paths.size() == 1) { + newdrive = imgDisks[0]; + if(((fatDrive *)newdrive)->loadedDisk->hardDrive) { + if(imageDiskList[2] == NULL) { + imageDiskList[2] = ((fatDrive *)newdrive)->loadedDisk; + updateDPT(); + return; + } + if(imageDiskList[3] == NULL) { + imageDiskList[3] = ((fatDrive *)newdrive)->loadedDisk; + updateDPT(); + return; + } + } + if(!((fatDrive *)newdrive)->loadedDisk->hardDrive) { + imageDiskList[0] = ((fatDrive *)newdrive)->loadedDisk; + } } } else if (fstype=="iso") { + + if (Drives[drive-'A']) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_ALREADY_MOUNTED")); + return; + } + MSCDEX_SetCDInterface(CDROM_USE_SDL, -1); + // create new drives for all images + std::vector isoDisks; + std::vector::size_type i; + std::vector::size_type ct; + for (i = 0; i < paths.size(); i++) { + int error = -1; + DOS_Drive* newDrive = new isoDrive(drive, paths[i].c_str(), mediaid, error); + isoDisks.push_back(newDrive); + switch (error) { + case 0 : break; + case 1 : WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS")); break; + case 2 : WriteOut(MSG_Get("MSCDEX_ERROR_NOT_SUPPORTED")); break; + case 3 : WriteOut(MSG_Get("MSCDEX_ERROR_OPEN")); break; + case 4 : WriteOut(MSG_Get("MSCDEX_TOO_MANY_DRIVES")); break; + case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break; + case 6 : WriteOut(MSG_Get("MSCDEX_INVALID_FILEFORMAT")); break; + default : WriteOut(MSG_Get("MSCDEX_UNKNOWN_ERROR")); break; + } + // error: clean up and leave + if (error) { + for(ct = 0; ct < isoDisks.size(); ct++) { + delete isoDisks[ct]; + } + return; + } + } + // Update DriveManager + for(ct = 0; ct < isoDisks.size(); ct++) { + DriveManager::AppendDisk(drive - 'A', isoDisks[ct]); + } + DriveManager::InitializeDrive(drive - 'A'); + + // Set the correct media byte in the table + mem_writeb(Real2Phys(dos.tables.mediaid) + (drive - 'A') * 2, mediaid); + + // Print status message (success) + WriteOut(MSG_Get("MSCDEX_SUCCESS")); + std::string tmp(paths[0]); + for (i = 1; i < paths.size(); i++) { + tmp += "; " + paths[i]; + } + WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"), drive, tmp.c_str()); + } else { FILE *newDisk = fopen(temp_line.c_str(), "rb+"); fseek(newDisk,0L, SEEK_END); @@ -1268,82 +1374,7 @@ public: return; } - if(fstype=="fat") { - if (Drives[drive-'A']) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_ALREADY_MOUNTED")); - if (newdrive) delete newdrive; - return; - } - if (!newdrive) {WriteOut(MSG_Get("PROGRAM_IMGMOUNT_CANT_CREATE"));return;} - Drives[drive-'A']=newdrive; - // Set the correct media byte in the table - mem_writeb(Real2Phys(dos.tables.mediaid)+(drive-'A')*2,mediaid); - WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,temp_line.c_str()); - if(((fatDrive *)newdrive)->loadedDisk->hardDrive) { - if(imageDiskList[2] == NULL) { - imageDiskList[2] = ((fatDrive *)newdrive)->loadedDisk; - updateDPT(); - return; - } - if(imageDiskList[3] == NULL) { - imageDiskList[3] = ((fatDrive *)newdrive)->loadedDisk; - updateDPT(); - return; - } - } - if(!((fatDrive *)newdrive)->loadedDisk->hardDrive) { - imageDiskList[0] = ((fatDrive *)newdrive)->loadedDisk; - } - } else if (fstype=="iso") { - if (Drives[drive-'A']) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_ALREADY_MOUNTED")); - return; - } - MSCDEX_SetCDInterface(CDROM_USE_SDL, -1); - // create new drives for all images - std::vector isoDisks; - std::vector::size_type i; - std::vector::size_type ct; - for (i = 0; i < paths.size(); i++) { - int error = -1; - DOS_Drive* newDrive = new isoDrive(drive, paths[i].c_str(), mediaid, error); - isoDisks.push_back(newDrive); - switch (error) { - case 0 : break; - case 1 : WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS")); break; - case 2 : WriteOut(MSG_Get("MSCDEX_ERROR_NOT_SUPPORTED")); break; - case 3 : WriteOut(MSG_Get("MSCDEX_ERROR_OPEN")); break; - case 4 : WriteOut(MSG_Get("MSCDEX_TOO_MANY_DRIVES")); break; - case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break; - case 6 : WriteOut(MSG_Get("MSCDEX_INVALID_FILEFORMAT")); break; - default : WriteOut(MSG_Get("MSCDEX_UNKNOWN_ERROR")); break; - } - // error: clean up and leave - if (error) { - for(ct = 0; ct < isoDisks.size(); ct++) { - delete isoDisks[ct]; - } - return; - } - } - // Update DriveManager - for(ct = 0; ct < isoDisks.size(); ct++) { - DriveManager::AppendDisk(drive - 'A', isoDisks[ct]); - } - DriveManager::InitializeDrive(drive - 'A'); - - // Set the correct media byte in the table - mem_writeb(Real2Phys(dos.tables.mediaid) + (drive - 'A') * 2, mediaid); - - // Print status message (success) - WriteOut(MSG_Get("MSCDEX_SUCCESS")); - std::string tmp(paths[0]); - for (i = 1; i < paths.size(); i++) { - tmp += "; " + paths[i]; - } - WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"), drive, tmp.c_str()); - - } else if (fstype=="none") { + if (fstype=="none") { if(imageDiskList[drive-'0'] != NULL) delete imageDiskList[drive-'0']; imageDiskList[drive-'0'] = newImage; updateDPT(); From 613c8fb9d42efe9360c12e92e47fe9ea7bfa9d1b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 1 Jan 2013 12:53:00 +0000 Subject: [PATCH 3719/4131] Use modification instead of creation date.(rcblanke) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3809 --- src/dos/drive_fat.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 59caf294..d5be63f7 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -968,7 +968,10 @@ nextfile: /* Compare name to search pattern */ if(!WildFileCmp(find_name,srch_pattern)) goto nextfile; - dta.SetResult(find_name, sectbuf[entryoffset].entrysize, sectbuf[entryoffset].crtDate, sectbuf[entryoffset].crtTime, sectbuf[entryoffset].attrib); + //dta.SetResult(find_name, sectbuf[entryoffset].entrysize, sectbuf[entryoffset].crtDate, sectbuf[entryoffset].crtTime, sectbuf[entryoffset].attrib); + + dta.SetResult(find_name, sectbuf[entryoffset].entrysize, sectbuf[entryoffset].modDate, sectbuf[entryoffset].modTime, sectbuf[entryoffset].attrib); + memcpy(foundEntry, §buf[entryoffset], sizeof(direntry)); return true; From c87ba3ab3447f405902facd946fa868ec41d23eb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 14 Jan 2013 10:10:22 +0000 Subject: [PATCH 3720/4131] autotools people...(1.13.1) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3810 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 54b5356c..87e44523 100644 --- a/configure.in +++ b/configure.in @@ -9,7 +9,7 @@ AC_CANONICAL_BUILD dnl Setup for automake AM_INIT_AUTOMAKE -AM_CONFIG_HEADER(config.h) +AC_CONFIG_HEADER(config.h) dnl Checks for programs. AC_PROG_MAKE_SET From 889602e170adbbb010db145ba65d7f2285f392f9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 14 Jan 2013 10:22:20 +0000 Subject: [PATCH 3721/4131] rename configure.in to configure.ac . autotools people again..... Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3811 --- configure.in => configure.ac | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename configure.in => configure.ac (100%) diff --git a/configure.in b/configure.ac similarity index 100% rename from configure.in rename to configure.ac From 2fea508f7fd8f5ce2e3cc33a902603f336e5805c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 15 Jan 2013 09:03:13 +0000 Subject: [PATCH 3722/4131] Year update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3812 --- acinclude.m4 | 2 +- include/bios.h | 2 +- include/bios_disk.h | 2 +- include/callback.h | 2 +- include/control.h | 2 +- include/cpu.h | 2 +- include/cross.h | 2 +- include/debug.h | 2 +- include/dma.h | 2 +- include/dos_inc.h | 2 +- include/dos_system.h | 2 +- include/dosbox.h | 2 +- include/fpu.h | 2 +- include/hardware.h | 2 +- include/inout.h | 2 +- include/ipx.h | 2 +- include/ipxserver.h | 2 +- include/joystick.h | 2 +- include/keyboard.h | 2 +- include/logging.h | 2 +- include/mapper.h | 2 +- include/mem.h | 2 +- include/mixer.h | 2 +- include/mouse.h | 2 +- include/paging.h | 2 +- include/pci_bus.h | 2 +- include/pic.h | 2 +- include/programs.h | 2 +- include/regs.h | 2 +- include/render.h | 2 +- include/serialport.h | 2 +- include/setup.h | 2 +- include/shell.h | 2 +- include/support.h | 2 +- include/timer.h | 2 +- include/vga.h | 2 +- include/video.h | 2 +- scripts/dosbox-installer.nsi | 2 +- src/cpu/callback.cpp | 2 +- src/cpu/core_dyn_x86.cpp | 2 +- src/cpu/core_dyn_x86/cache.h | 2 +- src/cpu/core_dyn_x86/decoder.h | 2 +- src/cpu/core_dyn_x86/dyn_fpu.h | 2 +- src/cpu/core_dyn_x86/dyn_fpu_dh.h | 2 +- src/cpu/core_dyn_x86/helpers.h | 2 +- src/cpu/core_dyn_x86/risc_x86.h | 2 +- src/cpu/core_dyn_x86/string.h | 2 +- src/cpu/core_dynrec.cpp | 2 +- src/cpu/core_dynrec/cache.h | 2 +- src/cpu/core_dynrec/decoder.h | 2 +- src/cpu/core_dynrec/decoder_basic.h | 2 +- src/cpu/core_dynrec/decoder_opcodes.h | 2 +- src/cpu/core_dynrec/dyn_fpu.h | 2 +- src/cpu/core_dynrec/operators.h | 2 +- src/cpu/core_dynrec/risc_armv4le-common.h | 2 +- src/cpu/core_dynrec/risc_armv4le-o3.h | 2 +- src/cpu/core_dynrec/risc_armv4le-s3.h | 2 +- src/cpu/core_dynrec/risc_armv4le-thumb-iw.h | 2 +- src/cpu/core_dynrec/risc_armv4le-thumb-niw.h | 2 +- src/cpu/core_dynrec/risc_armv4le-thumb.h | 2 +- src/cpu/core_dynrec/risc_armv4le.h | 2 +- src/cpu/core_dynrec/risc_mipsel32.h | 2 +- src/cpu/core_dynrec/risc_x64.h | 2 +- src/cpu/core_dynrec/risc_x86.h | 2 +- src/cpu/core_full.cpp | 2 +- src/cpu/core_full/ea_lookup.h | 2 +- src/cpu/core_full/load.h | 2 +- src/cpu/core_full/loadwrite.h | 2 +- src/cpu/core_full/op.h | 2 +- src/cpu/core_full/optable.h | 2 +- src/cpu/core_full/save.h | 2 +- src/cpu/core_full/string.h | 2 +- src/cpu/core_full/support.h | 2 +- src/cpu/core_normal.cpp | 2 +- src/cpu/core_normal/helpers.h | 2 +- src/cpu/core_normal/prefix_0f.h | 2 +- src/cpu/core_normal/prefix_66.h | 2 +- src/cpu/core_normal/prefix_66_0f.h | 2 +- src/cpu/core_normal/prefix_none.h | 2 +- src/cpu/core_normal/string.h | 2 +- src/cpu/core_normal/support.h | 2 +- src/cpu/core_normal/table_ea.h | 2 +- src/cpu/core_prefetch.cpp | 2 +- src/cpu/core_simple.cpp | 2 +- src/cpu/cpu.cpp | 2 +- src/cpu/flags.cpp | 2 +- src/cpu/instructions.h | 2 +- src/cpu/lazyflags.h | 2 +- src/cpu/modrm.cpp | 2 +- src/cpu/modrm.h | 2 +- src/cpu/paging.cpp | 2 +- src/debug/debug.cpp | 2 +- src/debug/debug_gui.cpp | 2 +- src/debug/debug_inc.h | 2 +- src/debug/debug_win32.cpp | 2 +- src/debug/disasm_tables.h | 2 +- src/dos/cdrom.cpp | 2 +- src/dos/cdrom.h | 2 +- src/dos/cdrom_aspi_win32.cpp | 2 +- src/dos/cdrom_image.cpp | 2 +- src/dos/cdrom_ioctl_linux.cpp | 2 +- src/dos/cdrom_ioctl_os2.cpp | 2 +- src/dos/cdrom_ioctl_win32.cpp | 2 +- src/dos/dev_con.h | 2 +- src/dos/dos.cpp | 2 +- src/dos/dos_classes.cpp | 2 +- src/dos/dos_devices.cpp | 2 +- src/dos/dos_execute.cpp | 2 +- src/dos/dos_files.cpp | 2 +- src/dos/dos_ioctl.cpp | 2 +- src/dos/dos_keyboard_layout.cpp | 2 +- src/dos/dos_memory.cpp | 2 +- src/dos/dos_misc.cpp | 2 +- src/dos/dos_mscdex.cpp | 2 +- src/dos/dos_programs.cpp | 2 +- src/dos/dos_tables.cpp | 2 +- src/dos/drive_cache.cpp | 2 +- src/dos/drive_fat.cpp | 2 +- src/dos/drive_iso.cpp | 2 +- src/dos/drive_local.cpp | 2 +- src/dos/drive_virtual.cpp | 2 +- src/dos/drives.cpp | 2 +- src/dos/drives.h | 2 +- src/dosbox.cpp | 2 +- src/fpu/fpu.cpp | 2 +- src/fpu/fpu_instructions.h | 2 +- src/fpu/fpu_instructions_x86.h | 2 +- src/gui/dosbox_logo.h | 2 +- src/gui/midi.cpp | 2 +- src/gui/midi_alsa.h | 2 +- src/gui/midi_coreaudio.h | 2 +- src/gui/midi_oss.h | 2 +- src/gui/midi_win32.h | 2 +- src/gui/render.cpp | 2 +- src/gui/render_loops.h | 2 +- src/gui/render_scalers.cpp | 2 +- src/gui/render_scalers.h | 2 +- src/gui/render_simple.h | 2 +- src/gui/render_templates.h | 2 +- src/gui/render_templates_hq.h | 2 +- src/gui/render_templates_hq2x.h | 2 +- src/gui/render_templates_hq3x.h | 2 +- src/gui/render_templates_sai.h | 2 +- src/gui/sdl_gui.cpp | 4 ++-- src/gui/sdl_mapper.cpp | 2 +- src/gui/sdlmain.cpp | 6 +++--- src/hardware/adlib.cpp | 2 +- src/hardware/adlib.h | 2 +- src/hardware/cmos.cpp | 2 +- src/hardware/dbopl.cpp | 2 +- src/hardware/dbopl.h | 2 +- src/hardware/disney.cpp | 2 +- src/hardware/dma.cpp | 2 +- src/hardware/gameblaster.cpp | 2 +- src/hardware/gus.cpp | 2 +- src/hardware/hardware.cpp | 2 +- src/hardware/iohandler.cpp | 2 +- src/hardware/ipx.cpp | 2 +- src/hardware/ipxserver.cpp | 2 +- src/hardware/joystick.cpp | 2 +- src/hardware/keyboard.cpp | 2 +- src/hardware/memory.cpp | 2 +- src/hardware/mixer.cpp | 2 +- src/hardware/opl.cpp | 2 +- src/hardware/opl.h | 2 +- src/hardware/pci_bus.cpp | 2 +- src/hardware/pci_devices.h | 2 +- src/hardware/pcspeaker.cpp | 2 +- src/hardware/sblaster.cpp | 2 +- src/hardware/serialport/directserial.cpp | 2 +- src/hardware/serialport/directserial.h | 2 +- src/hardware/serialport/libserial.cpp | 2 +- src/hardware/serialport/libserial.h | 2 +- src/hardware/serialport/misc_util.cpp | 2 +- src/hardware/serialport/misc_util.h | 2 +- src/hardware/serialport/nullmodem.cpp | 2 +- src/hardware/serialport/nullmodem.h | 2 +- src/hardware/serialport/serialdummy.cpp | 2 +- src/hardware/serialport/serialdummy.h | 2 +- src/hardware/serialport/serialport.cpp | 2 +- src/hardware/serialport/softmodem.cpp | 2 +- src/hardware/serialport/softmodem.h | 2 +- src/hardware/tandy_sound.cpp | 2 +- src/hardware/timer.cpp | 2 +- src/hardware/vga.cpp | 2 +- src/hardware/vga_attr.cpp | 2 +- src/hardware/vga_crtc.cpp | 2 +- src/hardware/vga_dac.cpp | 2 +- src/hardware/vga_draw.cpp | 2 +- src/hardware/vga_gfx.cpp | 2 +- src/hardware/vga_memory.cpp | 2 +- src/hardware/vga_misc.cpp | 2 +- src/hardware/vga_other.cpp | 2 +- src/hardware/vga_paradise.cpp | 2 +- src/hardware/vga_s3.cpp | 2 +- src/hardware/vga_seq.cpp | 2 +- src/hardware/vga_tseng.cpp | 2 +- src/hardware/vga_xga.cpp | 2 +- src/ints/bios.cpp | 2 +- src/ints/bios_disk.cpp | 2 +- src/ints/bios_keyboard.cpp | 2 +- src/ints/ems.cpp | 2 +- src/ints/int10.cpp | 2 +- src/ints/int10.h | 2 +- src/ints/int10_char.cpp | 2 +- src/ints/int10_memory.cpp | 2 +- src/ints/int10_misc.cpp | 2 +- src/ints/int10_modes.cpp | 2 +- src/ints/int10_pal.cpp | 2 +- src/ints/int10_put_pixel.cpp | 2 +- src/ints/int10_vesa.cpp | 2 +- src/ints/int10_video_state.cpp | 2 +- src/ints/int10_vptable.cpp | 2 +- src/ints/mouse.cpp | 2 +- src/ints/xms.cpp | 2 +- src/ints/xms.h | 2 +- src/libs/zmbv/drvproc.cpp | 2 +- src/libs/zmbv/zmbv.cpp | 2 +- src/libs/zmbv/zmbv.h | 2 +- src/libs/zmbv/zmbv_vfw.cpp | 2 +- src/libs/zmbv/zmbv_vfw.rc | 2 +- src/misc/cross.cpp | 2 +- src/misc/messages.cpp | 2 +- src/misc/programs.cpp | 2 +- src/misc/setup.cpp | 2 +- src/misc/support.cpp | 2 +- src/shell/shell.cpp | 2 +- src/shell/shell_batch.cpp | 2 +- src/shell/shell_cmds.cpp | 2 +- src/shell/shell_misc.cpp | 2 +- src/winres.rc | 4 ++-- 231 files changed, 235 insertions(+), 235 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 29474ec4..51fd4154 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -305,7 +305,7 @@ AC_SUBST(ALSA_LIBS) AH_TOP([ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/bios.h b/include/bios.h index d03eef54..a1e4e4cf 100644 --- a/include/bios.h +++ b/include/bios.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/bios_disk.h b/include/bios_disk.h index ef4ad36f..c21577f9 100644 --- a/include/bios_disk.h +++ b/include/bios_disk.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/callback.h b/include/callback.h index ff7ebfac..daa103db 100644 --- a/include/callback.h +++ b/include/callback.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/control.h b/include/control.h index e500db28..9155fa30 100644 --- a/include/control.h +++ b/include/control.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/cpu.h b/include/cpu.h index 0903ffb5..b02c95bf 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/cross.h b/include/cross.h index 73f954ee..395fbf30 100644 --- a/include/cross.h +++ b/include/cross.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/debug.h b/include/debug.h index 031e6831..f2ea6995 100644 --- a/include/debug.h +++ b/include/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/dma.h b/include/dma.h index 71a40b85..d0e4fc79 100644 --- a/include/dma.h +++ b/include/dma.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/dos_inc.h b/include/dos_inc.h index 3091c19a..f32b3185 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/dos_system.h b/include/dos_system.h index d59a7d7f..d62470f1 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/dosbox.h b/include/dosbox.h index a72d954c..2576b577 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/fpu.h b/include/fpu.h index 8b89934d..cea691bd 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/hardware.h b/include/hardware.h index 4b925ab4..6378d232 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/inout.h b/include/inout.h index a49f639b..578a1137 100644 --- a/include/inout.h +++ b/include/inout.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/ipx.h b/include/ipx.h index 24a1b421..afd8e7d7 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/ipxserver.h b/include/ipxserver.h index c10fc4a9..1d448755 100644 --- a/include/ipxserver.h +++ b/include/ipxserver.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/joystick.h b/include/joystick.h index 02f00a48..812bc0e5 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/keyboard.h b/include/keyboard.h index af754c5f..08277b60 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/logging.h b/include/logging.h index 7faf84cd..5ad4c27c 100644 --- a/include/logging.h +++ b/include/logging.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/mapper.h b/include/mapper.h index ba565157..acac5d2b 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/mem.h b/include/mem.h index 1b40c553..8c65380e 100644 --- a/include/mem.h +++ b/include/mem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/mixer.h b/include/mixer.h index ed9669ab..055ccabd 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/mouse.h b/include/mouse.h index 3a318ea8..0ee82259 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/paging.h b/include/paging.h index 13fee9b9..b13f52d6 100644 --- a/include/paging.h +++ b/include/paging.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/pci_bus.h b/include/pci_bus.h index 2dadfa06..635a356d 100644 --- a/include/pci_bus.h +++ b/include/pci_bus.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/pic.h b/include/pic.h index e311467d..d1b4e02d 100644 --- a/include/pic.h +++ b/include/pic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/programs.h b/include/programs.h index 8815fa04..5830a4c9 100644 --- a/include/programs.h +++ b/include/programs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/regs.h b/include/regs.h index 07a11a65..b96268c3 100644 --- a/include/regs.h +++ b/include/regs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/render.h b/include/render.h index 25fed201..3bb9cf3a 100644 --- a/include/render.h +++ b/include/render.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/serialport.h b/include/serialport.h index 9ec75778..6dfbc10f 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/setup.h b/include/setup.h index e14c1cb3..e3991833 100644 --- a/include/setup.h +++ b/include/setup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/shell.h b/include/shell.h index ec7d7d05..e619841a 100644 --- a/include/shell.h +++ b/include/shell.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/support.h b/include/support.h index 93c94ea8..cbeb9162 100644 --- a/include/support.h +++ b/include/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/timer.h b/include/timer.h index f4fb0c52..9b008951 100644 --- a/include/timer.h +++ b/include/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/vga.h b/include/vga.h index 6b19e6eb..b45a82fa 100644 --- a/include/vga.h +++ b/include/vga.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/include/video.h b/include/video.h index b7062958..b6c157bf 100644 --- a/include/video.h +++ b/include/video.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index 470c6783..492b2895 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -2,7 +2,7 @@ !define VER_MINOR 74 !define APP_NAME "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer" !define COMP_NAME "DOSBox Team" -!define COPYRIGHT "Copyright © 2002-2011 DOSBox Team" +!define COPYRIGHT "Copyright © 2002-2013 DOSBox Team" !define DESCRIPTION "DOSBox Installer" VIProductVersion "${VER_MAYOR}.${VER_MINOR}.0.0" diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index de64bf59..d92d429a 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index f63d9158..3338791d 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 2bda44cd..2b817f16 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index a9f90d07..61b1ca55 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dyn_x86/dyn_fpu.h b/src/cpu/core_dyn_x86/dyn_fpu.h index 067d8493..f5ff2509 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu.h +++ b/src/cpu/core_dyn_x86/dyn_fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dyn_x86/dyn_fpu_dh.h b/src/cpu/core_dyn_x86/dyn_fpu_dh.h index 47dc7572..e17e5d87 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu_dh.h +++ b/src/cpu/core_dyn_x86/dyn_fpu_dh.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dyn_x86/helpers.h b/src/cpu/core_dyn_x86/helpers.h index 727a9735..84206f43 100644 --- a/src/cpu/core_dyn_x86/helpers.h +++ b/src/cpu/core_dyn_x86/helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index fdde79bd..558f3cfe 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index 78813323..1625e5d4 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index ed975f56..35151780 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index 5c814360..cb46274b 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h index 08b52441..9c3fbcf2 100644 --- a/src/cpu/core_dynrec/decoder.h +++ b/src/cpu/core_dynrec/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index d09012c4..89cd49a0 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index 1a4ca6fd..43e15a09 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dynrec/dyn_fpu.h b/src/cpu/core_dynrec/dyn_fpu.h index cc22e394..36600106 100644 --- a/src/cpu/core_dynrec/dyn_fpu.h +++ b/src/cpu/core_dynrec/dyn_fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dynrec/operators.h b/src/cpu/core_dynrec/operators.h index 52de9681..78dfb670 100644 --- a/src/cpu/core_dynrec/operators.h +++ b/src/cpu/core_dynrec/operators.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-common.h b/src/cpu/core_dynrec/risc_armv4le-common.h index 0c2c53e0..87c7c591 100644 --- a/src/cpu/core_dynrec/risc_armv4le-common.h +++ b/src/cpu/core_dynrec/risc_armv4le-common.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-o3.h b/src/cpu/core_dynrec/risc_armv4le-o3.h index 44cf859f..f1100bb6 100644 --- a/src/cpu/core_dynrec/risc_armv4le-o3.h +++ b/src/cpu/core_dynrec/risc_armv4le-o3.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-s3.h b/src/cpu/core_dynrec/risc_armv4le-s3.h index d4e7800a..358c04d3 100644 --- a/src/cpu/core_dynrec/risc_armv4le-s3.h +++ b/src/cpu/core_dynrec/risc_armv4le-s3.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h index f1866fe1..6ead4b79 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h index 4b91f227..2f49865c 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb.h b/src/cpu/core_dynrec/risc_armv4le-thumb.h index ae8b732d..33409edd 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dynrec/risc_armv4le.h b/src/cpu/core_dynrec/risc_armv4le.h index 8723852f..a4d74d42 100644 --- a/src/cpu/core_dynrec/risc_armv4le.h +++ b/src/cpu/core_dynrec/risc_armv4le.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dynrec/risc_mipsel32.h b/src/cpu/core_dynrec/risc_mipsel32.h index 717e5ff8..83f164c8 100644 --- a/src/cpu/core_dynrec/risc_mipsel32.h +++ b/src/cpu/core_dynrec/risc_mipsel32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index c710bc6f..6ad073ca 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_dynrec/risc_x86.h b/src/cpu/core_dynrec/risc_x86.h index 99063d2d..260ffc74 100644 --- a/src/cpu/core_dynrec/risc_x86.h +++ b/src/cpu/core_dynrec/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index f70f8078..35720af1 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_full/ea_lookup.h b/src/cpu/core_full/ea_lookup.h index bf71b122..16cf2ad9 100644 --- a/src/cpu/core_full/ea_lookup.h +++ b/src/cpu/core_full/ea_lookup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 0a3f1ae0..64946e14 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_full/loadwrite.h b/src/cpu/core_full/loadwrite.h index 22891515..e88153f8 100644 --- a/src/cpu/core_full/loadwrite.h +++ b/src/cpu/core_full/loadwrite.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index ea5f517d..b38f7368 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 81eb94ae..0b09d4c6 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_full/save.h b/src/cpu/core_full/save.h index 142ec5c4..68280796 100644 --- a/src/cpu/core_full/save.h +++ b/src/cpu/core_full/save.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index bc8f2360..741e4d35 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index a6b12079..c4d1d8ea 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 530e0c62..ef7682e3 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_normal/helpers.h b/src/cpu/core_normal/helpers.h index 20114949..abde2bfd 100644 --- a/src/cpu/core_normal/helpers.h +++ b/src/cpu/core_normal/helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 38004f1f..699d4c91 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index a40bc238..decfc8f8 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 832e8f48..7a4eb31f 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index c732d1a6..11c95134 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_normal/string.h b/src/cpu/core_normal/string.h index 88540822..027b59b6 100644 --- a/src/cpu/core_normal/string.h +++ b/src/cpu/core_normal/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index 5752d2a2..fa545245 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_normal/table_ea.h b/src/cpu/core_normal/table_ea.h index e6ac3f2d..74ee150b 100644 --- a/src/cpu/core_normal/table_ea.h +++ b/src/cpu/core_normal/table_ea.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_prefetch.cpp b/src/cpu/core_prefetch.cpp index e378968a..1cd1403b 100644 --- a/src/cpu/core_prefetch.cpp +++ b/src/cpu/core_prefetch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp index e7512270..7ac7a55a 100644 --- a/src/cpu/core_simple.cpp +++ b/src/cpu/core_simple.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 9c9d5668..47b6f658 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index cd47f426..29b8ddd5 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 620d1700..57e7dbc6 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index 49855f75..75701ef4 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/modrm.cpp b/src/cpu/modrm.cpp index c5e4e923..dce156af 100644 --- a/src/cpu/modrm.cpp +++ b/src/cpu/modrm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/modrm.h b/src/cpu/modrm.h index 1f4d6d58..f8ea48ee 100644 --- a/src/cpu/modrm.h +++ b/src/cpu/modrm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 6ac9b664..3a7b539e 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 8a3846c6..6973cc21 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index d1b8bbc4..3db7e50b 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h index 873cde2e..e6ea2b05 100644 --- a/src/debug/debug_inc.h +++ b/src/debug/debug_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/debug/debug_win32.cpp b/src/debug/debug_win32.cpp index 9fd80ead..e485da2e 100644 --- a/src/debug/debug_win32.cpp +++ b/src/debug/debug_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/debug/disasm_tables.h b/src/debug/disasm_tables.h index 55a6bae9..ad743938 100644 --- a/src/debug/disasm_tables.h +++ b/src/debug/disasm_tables.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 0e7d38e7..47ee05cf 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index 7199f46d..18445333 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index 5ae8daf8..d1d5a930 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index b96546d0..f98c6f2b 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/cdrom_ioctl_linux.cpp b/src/dos/cdrom_ioctl_linux.cpp index 46122178..7064c3e7 100644 --- a/src/dos/cdrom_ioctl_linux.cpp +++ b/src/dos/cdrom_ioctl_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/cdrom_ioctl_os2.cpp b/src/dos/cdrom_ioctl_os2.cpp index 6c34b17c..dc5d45e3 100644 --- a/src/dos/cdrom_ioctl_os2.cpp +++ b/src/dos/cdrom_ioctl_os2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index 994c5829..0158d386 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 79a6e42c..8a90860f 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index baba3c3b..86041334 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 629d8112..da4099b8 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 9c4263a2..b6659816 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index da43a405..d2ac101e 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 51e89210..b2886220 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 2eeddb0f..ca6e246a 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 33b7d10e..c41109d3 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index f1f7dcc7..ccf2392a 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index d658273d..f7b595ba 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 125c30e9..688751d8 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 2754ed1a..e9337721 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index b7efc8ba..a08e58c7 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 24d239ef..057c3b25 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index d5be63f7..323072b7 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 00e120d6..af4bd691 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index ba4daf91..7e9ee18e 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 43bfe8d1..70fb97b5 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index 2f55d69c..25f7e45e 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dos/drives.h b/src/dos/drives.h index 18ff21d0..509af18f 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 9e31162b..f074549c 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index f7ac61d6..2f5778cf 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index a5f7e3ac..0789d497 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index 489d8509..998730fc 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/gui/dosbox_logo.h b/src/gui/dosbox_logo.h index 5d99a589..fa1e2a32 100644 --- a/src/gui/dosbox_logo.h +++ b/src/gui/dosbox_logo.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 252cc7d4..989912ba 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 6e11afab..fe051839 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index ee6c752f..1fe3e386 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index 2571daef..3b34d24a 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index 0535bf10..47c97e17 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 2bb29cf0..67435218 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/gui/render_loops.h b/src/gui/render_loops.h index 6a4e7b65..a781742a 100644 --- a/src/gui/render_loops.h +++ b/src/gui/render_loops.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index a2e4b02b..dea60230 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index 5b1c4c46..bb5b5fc1 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/gui/render_simple.h b/src/gui/render_simple.h index 063c2a74..204a84e8 100644 --- a/src/gui/render_simple.h +++ b/src/gui/render_simple.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index c659b2fc..cdaba9e3 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/gui/render_templates_hq.h b/src/gui/render_templates_hq.h index 8153af29..bd4ad824 100644 --- a/src/gui/render_templates_hq.h +++ b/src/gui/render_templates_hq.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/gui/render_templates_hq2x.h b/src/gui/render_templates_hq2x.h index 94879cb2..15a6dcb8 100644 --- a/src/gui/render_templates_hq2x.h +++ b/src/gui/render_templates_hq2x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/gui/render_templates_hq3x.h b/src/gui/render_templates_hq3x.h index e8fa21d6..4e23b4fb 100644 --- a/src/gui/render_templates_hq3x.h +++ b/src/gui/render_templates_hq3x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/gui/render_templates_sai.h b/src/gui/render_templates_sai.h index 78006ccf..13e86e94 100644 --- a/src/gui/render_templates_sai.h +++ b/src/gui/render_templates_sai.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index 807d908a..a291b049 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 @@ -569,7 +569,7 @@ public: Section_prop *section = static_cast(sec); new SectionEditor(getScreen(), 50, 30, section); } else if (arg == "About") { - new GUI::MessageBox(getScreen(), 200, 150, 280, "About DOSBox", "\nDOSBox 0.74\nAn emulator for old DOS Games\n\nCopyright 2002-2011\nThe DOSBox Team"); + new GUI::MessageBox(getScreen(), 200, 150, 280, "About DOSBox", "\nDOSBox 0.74\nAn emulator for old DOS Games\n\nCopyright 2002-2013\nThe DOSBox Team"); } else if (arg == "Introduction") { new GUI::MessageBox(getScreen(), 20, 50, 600, "Introduction", MSG_Get("PROGRAM_INTRO")); } else if (arg == "Getting Started") { diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 82d1baa6..1c6b700a 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index e3a32a6e..fd4c10fd 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 @@ -1854,7 +1854,7 @@ int main(int argc, char* argv[]) { #endif //defined(WIN32) && !(C_DEBUG) if (control->cmdline->FindExist("-version") || control->cmdline->FindExist("--version") ) { - printf("\nDOSBox version %s, copyright 2002-2011 DOSBox Team.\n\n",VERSION); + printf("\nDOSBox version %s, copyright 2002-2013 DOSBox Team.\n\n",VERSION); printf("DOSBox is written by the DOSBox Team (See AUTHORS file))\n"); printf("DOSBox comes with ABSOLUTELY NO WARRANTY. This is free software,\n"); printf("and you are welcome to redistribute it under certain conditions;\n"); @@ -1882,7 +1882,7 @@ int main(int argc, char* argv[]) { /* Display Welcometext in the console */ LOG_MSG("DOSBox version %s",VERSION); - LOG_MSG("Copyright 2002-2011 DOSBox Team, published under GNU GPL."); + LOG_MSG("Copyright 2002-2013 DOSBox Team, published under GNU GPL."); LOG_MSG("---"); /* Init SDL */ diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index dfa603d6..c127ff09 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/adlib.h b/src/hardware/adlib.h index 64bf2e90..d6c4d39d 100644 --- a/src/hardware/adlib.h +++ b/src/hardware/adlib.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 279e97e4..c3977043 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index 1723f310..34547665 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/dbopl.h b/src/hardware/dbopl.h index 624df438..8a82e184 100644 --- a/src/hardware/dbopl.h +++ b/src/hardware/dbopl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 3a9c48ac..d556fe15 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 1346e73e..6d1bb9b0 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index 324e2bcc..a1b61a77 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index fb0d6c0a..af642990 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 8f818e89..af7c411a 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 80c7091d..7c807402 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index 14f55fb2..c0e12af9 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/ipxserver.cpp b/src/hardware/ipxserver.cpp index ad77eed8..672f3fea 100644 --- a/src/hardware/ipxserver.cpp +++ b/src/hardware/ipxserver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index e45c222a..3d52b3af 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 1604e339..21546ece 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index a347c918..02827a1b 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 829d99a8..d611d4fb 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/opl.cpp b/src/hardware/opl.cpp index d046306a..7149b93c 100644 --- a/src/hardware/opl.cpp +++ b/src/hardware/opl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 The DOSBox Team * OPL2/OPL3 emulation library * * This library is free software; you can redistribute it and/or diff --git a/src/hardware/opl.h b/src/hardware/opl.h index 8adcdb1a..c704b3a4 100644 --- a/src/hardware/opl.h +++ b/src/hardware/opl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 The DOSBox Team * OPL2/OPL3 emulation library * * This library is free software; you can redistribute it and/or diff --git a/src/hardware/pci_bus.cpp b/src/hardware/pci_bus.cpp index 88c402a4..16b0bcd0 100644 --- a/src/hardware/pci_bus.cpp +++ b/src/hardware/pci_bus.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/pci_devices.h b/src/hardware/pci_devices.h index 72a73fc4..7a9c2428 100644 --- a/src/hardware/pci_devices.h +++ b/src/hardware/pci_devices.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 3dd6be69..04a32916 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 60f6e674..49fbea22 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/serialport/directserial.cpp b/src/hardware/serialport/directserial.cpp index 4504d583..20e48387 100644 --- a/src/hardware/serialport/directserial.cpp +++ b/src/hardware/serialport/directserial.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/serialport/directserial.h b/src/hardware/serialport/directserial.h index 05370ea5..e910187c 100644 --- a/src/hardware/serialport/directserial.h +++ b/src/hardware/serialport/directserial.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/serialport/libserial.cpp b/src/hardware/serialport/libserial.cpp index c780e9d1..090ff2f7 100644 --- a/src/hardware/serialport/libserial.cpp +++ b/src/hardware/serialport/libserial.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/serialport/libserial.h b/src/hardware/serialport/libserial.h index 05a674a3..60d6b085 100644 --- a/src/hardware/serialport/libserial.h +++ b/src/hardware/serialport/libserial.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/serialport/misc_util.cpp b/src/hardware/serialport/misc_util.cpp index 769da4d9..831c37f1 100644 --- a/src/hardware/serialport/misc_util.cpp +++ b/src/hardware/serialport/misc_util.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/serialport/misc_util.h b/src/hardware/serialport/misc_util.h index a7e805a4..f62ab151 100644 --- a/src/hardware/serialport/misc_util.h +++ b/src/hardware/serialport/misc_util.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/serialport/nullmodem.cpp b/src/hardware/serialport/nullmodem.cpp index 4f91f9dd..62e7f976 100644 --- a/src/hardware/serialport/nullmodem.cpp +++ b/src/hardware/serialport/nullmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/serialport/nullmodem.h b/src/hardware/serialport/nullmodem.h index 5bf7df44..0b467f44 100644 --- a/src/hardware/serialport/nullmodem.h +++ b/src/hardware/serialport/nullmodem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/serialport/serialdummy.cpp b/src/hardware/serialport/serialdummy.cpp index eea35ca7..ccbdc3f3 100644 --- a/src/hardware/serialport/serialdummy.cpp +++ b/src/hardware/serialport/serialdummy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/serialport/serialdummy.h b/src/hardware/serialport/serialdummy.h index 90a950ba..d6621f4f 100644 --- a/src/hardware/serialport/serialdummy.h +++ b/src/hardware/serialport/serialdummy.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index 884038b4..ee184542 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index ed9d7a1a..10f0dac8 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index 1ce9eff7..a625929e 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 05e16fc0..73f86f57 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index e6b4db76..8982fbb9 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index da5960c3..b0cb2c03 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index f23be28c..4df8bf64 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 9906c725..7404313e 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index dbc04e10..b575ebb2 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 5659b289..ad38ada7 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index 55c7cc15..760ebd1d 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index ecb2f5cd..ac6f8536 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 45d8ea7b..a8b568c7 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 34b09336..98f28e75 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/vga_paradise.cpp b/src/hardware/vga_paradise.cpp index 3f6b294e..5eb96062 100644 --- a/src/hardware/vga_paradise.cpp +++ b/src/hardware/vga_paradise.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index d79b42bb..9b813490 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 3c41bdde..fdf1628e 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/vga_tseng.cpp b/src/hardware/vga_tseng.cpp index 0983c233..a18b8bab 100644 --- a/src/hardware/vga_tseng.cpp +++ b/src/hardware/vga_tseng.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index a8bc4d37..dfdfc5d4 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 470a290e..5657ca6a 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index f3d3e9ae..1bacde48 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 0ad09c36..9a524aa4 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index f87ecce1..4ac6f846 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 0aa96707..86af6f84 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/ints/int10.h b/src/ints/int10.h index 41e43748..597c9fc6 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index e952dba9..f619f00f 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index c70ab178..54e78375 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 9522a6a4..bd35bda4 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 2a8a9e10..2b4efb30 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index c7fee18a..a580220f 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 47f3a430..13aa8596 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index baeb0c42..941e2f34 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/ints/int10_video_state.cpp b/src/ints/int10_video_state.cpp index c33e8220..7983abbd 100644 --- a/src/ints/int10_video_state.cpp +++ b/src/ints/int10_video_state.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/ints/int10_vptable.cpp b/src/ints/int10_vptable.cpp index 7d79fbdc..ed0084cc 100644 --- a/src/ints/int10_vptable.cpp +++ b/src/ints/int10_vptable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 5f8c7ba4..1fb2cf8a 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 1d9d2af2..c9bffb95 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/ints/xms.h b/src/ints/xms.h index 75891dc8..94e0e624 100644 --- a/src/ints/xms.h +++ b/src/ints/xms.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/libs/zmbv/drvproc.cpp b/src/libs/zmbv/drvproc.cpp index 736d7d70..3559a0f9 100644 --- a/src/libs/zmbv/drvproc.cpp +++ b/src/libs/zmbv/drvproc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/libs/zmbv/zmbv.cpp b/src/libs/zmbv/zmbv.cpp index f52176f2..bcf5ca55 100644 --- a/src/libs/zmbv/zmbv.cpp +++ b/src/libs/zmbv/zmbv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/libs/zmbv/zmbv.h b/src/libs/zmbv/zmbv.h index f16d5eda..3a29d47b 100644 --- a/src/libs/zmbv/zmbv.h +++ b/src/libs/zmbv/zmbv.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/libs/zmbv/zmbv_vfw.cpp b/src/libs/zmbv/zmbv_vfw.cpp index b1d77475..2ea0d512 100644 --- a/src/libs/zmbv/zmbv_vfw.cpp +++ b/src/libs/zmbv/zmbv_vfw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/libs/zmbv/zmbv_vfw.rc b/src/libs/zmbv/zmbv_vfw.rc index 87fbe8a5..18af28ac 100644 --- a/src/libs/zmbv/zmbv_vfw.rc +++ b/src/libs/zmbv/zmbv_vfw.rc @@ -59,7 +59,7 @@ CAPTION "DOSBox Video Codec v0.1" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN DEFPUSHBUTTON "OK",IDOK,131,34,29,14 - CTEXT "Zipped Motion Block Video v 0.1\nCopyright 2009-2011 DOSBox Team", + CTEXT "Zipped Motion Block Video v 0.1\nCopyright 2009-2013 DOSBox Team", IDC_STATIC,7,7,153,25,SS_NOPREFIX PUSHBUTTON "Email author",IDC_EMAIL,7,34,50,14 PUSHBUTTON "Visit home page",IDC_HOMEPAGE,59,34,58,14 diff --git a/src/misc/cross.cpp b/src/misc/cross.cpp index 95245b9b..709fac66 100644 --- a/src/misc/cross.cpp +++ b/src/misc/cross.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index b266ace6..c89d4b2f 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 6ba02c27..1930b995 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 25bd5a4e..6b5a4ebb 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/misc/support.cpp b/src/misc/support.cpp index cfcb64f6..744976a2 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 8342bd2a..9cce9285 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 1c86ecc5..20e692a1 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 314cf25e..b794c64e 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index a4e528da..e4ebf0d7 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2011 The DOSBox Team + * Copyright (C) 2002-2013 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 diff --git a/src/winres.rc b/src/winres.rc index cfcc7015..5c6edaa5 100644 --- a/src/winres.rc +++ b/src/winres.rc @@ -19,12 +19,12 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "Comments", "© 2002-2011 DOSBox Team, published under GNU GPL" + VALUE "Comments", "© 2002-2013 DOSBox Team, published under GNU GPL" VALUE "CompanyName", "DOSBox Team" VALUE "FileDescription", "DOSBox DOS Emulator" VALUE "FileVersion", "0, 74, 0, 0" VALUE "InternalName", "DOSBox" - VALUE "LegalCopyright", "Copyright © 2002-2011 DOSBox Team" + VALUE "LegalCopyright", "Copyright © 2002-2013 DOSBox Team" VALUE "OriginalFilename", "dosbox.exe" VALUE "ProductName", "DOSBox DOS Emulator" VALUE "ProductVersion", "0, 74, 0, 0" From 81226995de1659a531cc9fff0bb31239b815ae26 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sat, 26 Jan 2013 22:01:32 +0000 Subject: [PATCH 3723/4131] Add support for monochrome mode: - EGA and VGA mode 0x0F (implement plane masking in the attribute controller) - re-factor EGA monitor emulation (attribute controller bit is used to detect monochrome mode, horizontal frequency to choose 16/64 colors) Hardware blinking in graphics mode is still not supported. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3813 --- include/vga.h | 4 ++ src/hardware/vga_attr.cpp | 88 +++++++++++++++++++++++++++++++-------- src/hardware/vga_dac.cpp | 14 ------- src/hardware/vga_draw.cpp | 23 ++++++++++ src/ints/int10_modes.cpp | 16 ++++--- 5 files changed, 108 insertions(+), 37 deletions(-) diff --git a/include/vga.h b/include/vga.h index b45a82fa..ab79466c 100644 --- a/include/vga.h +++ b/include/vga.h @@ -427,6 +427,10 @@ 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); +typedef enum {CGA, EGA, MONO} EGAMonitorMode; + +void VGA_ATTR_SetEGAMonitorPalette(EGAMonitorMode m); + /* The VGA Subfunction startups */ void VGA_SetupAttr(void); void VGA_SetupMemory(Section* sec); diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 4df8bf64..df61a7f8 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -23,22 +23,70 @@ #define attr(blah) vga.attr.blah -void VGA_ATTR_SetPalette(Bit8u index,Bit8u val) { - vga.attr.palette[index] = val; - if (vga.attr.mode_control & 0x80) val = (val&0xf) | (vga.attr.color_select << 4); - val &= 63; - val |= (vga.attr.color_select & 0xc) << 4; - if (GCC_UNLIKELY(machine==MCH_EGA)) { - if ((vga.crtc.vertical_total | ((vga.crtc.overflow & 1) << 8)) == 260) { - // check for intensity bit - if (val&0x10) val|=0x38; - else { - val&=0x7; - // check for special brown - if (val==6) val=0x14; +void VGA_ATTR_SetEGAMonitorPalette(EGAMonitorMode m) { + // palette bit assignment: + // bit | pin | EGA | CGA | monochrome + // ----+-----+------------+-----------+------------ + // 0 | 5 | blue | blue | nc + // 1 | 4 | green | green* | nc + // 2 | 3 | red | red* | nc + // 3 | 7 | blue sec. | nc | video + // 4 | 6 | green sec. | intensity | intensity + // 5 | 2 | red sec. | nc | nc + // 6-7 | not used + // * additive color brown instead of yellow + switch(m) { + case CGA: + //LOG_MSG("Monitor CGA"); + for (Bitu i=0;i<64;i++) { + vga.dac.rgb[i].red=((i & 0x4)? 0x2a:0) + ((i & 0x10)? 0x15:0); + vga.dac.rgb[i].blue=((i & 0x1)? 0x2a:0) + ((i & 0x10)? 0x15:0); + + // replace yellow with brown + if ((i & 0x17) == 0x6) vga.dac.rgb[i].green = 0x15; + else vga.dac.rgb[i].green = + ((i & 0x2)? 0x2a:0) + ((i & 0x10)? 0x15:0); } - } + break; + case EGA: + //LOG_MSG("Monitor EGA"); + for (Bitu i=0;i<64;i++) { + vga.dac.rgb[i].red=((i & 0x4)? 0x2a:0) + ((i & 0x20)? 0x15:0); + vga.dac.rgb[i].green=((i & 0x2)? 0x2a:0) + ((i & 0x10)? 0x15:0); + vga.dac.rgb[i].blue=((i & 0x1)? 0x2a:0) + ((i & 0x8)? 0x15:0); + } + break; + case MONO: + //LOG_MSG("Monitor MONO"); + for (Bitu i=0;i<64;i++) { + Bit8u value = ((i & 0x8)? 0x2a:0) + ((i & 0x10)? 0x15:0); + vga.dac.rgb[i].red = vga.dac.rgb[i].green = + vga.dac.rgb[i].blue = value; + } + break; } + + // update the mappings + for (Bit8u i=0;i<0x10;i++) + VGA_ATTR_SetPalette(i,vga.attr.palette[i]); +} + +void VGA_ATTR_SetPalette(Bit8u index, Bit8u val) { + // the attribute table stores only 6 bits + val &= 63; + vga.attr.palette[index] = val; + + // apply the plane mask + val = vga.attr.palette[index & vga.attr.color_plane_enable]; + + // replace bits 4-5 if configured + if (vga.attr.mode_control & 0x80) + val = (val&0xf) | (vga.attr.color_select << 4); + + // set bits 6 and 7 (not relevant for EGA) + val |= (vga.attr.color_select & 0xc) << 4; + + // apply VGA_DAC_CombineColor(index,val); } @@ -126,7 +174,14 @@ void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) { break; case 0x12: /* Color Plane Enable Register */ /* Why disable colour planes? */ - attr(color_plane_enable)=(Bit8u)val; + /* To support weird modes. */ + if ((attr(color_plane_enable)^val) & 0xf) { + // in case the plane enable bits change... + attr(color_plane_enable)=(Bit8u)val; + for (Bit8u i=0;i<0x10;i++) + VGA_ATTR_SetPalette(i,vga.attr.palette[i]); + } else + attr(color_plane_enable)=(Bit8u)val; /* 0 Bit plane 0 is enabled if set. 1 Bit plane 1 is enabled if set. @@ -180,9 +235,8 @@ void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) { } if (attr(color_select) ^ val) { attr(color_select)=(Bit8u)val; - for (Bit8u i=0;i<0x10;i++) { + for (Bit8u i=0;i<0x10;i++) VGA_ATTR_SetPalette(i,vga.attr.palette[i]); - } } /* 0-1 If 3C0h index 10h bit 7 is set these 2 bits are used as bits 4-5 of diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index b575ebb2..ae305e03 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -213,19 +213,5 @@ void VGA_SetupDAC(void) { IO_RegisterReadHandler(0x3c8,read_p3c8,IO_MB); IO_RegisterWriteHandler(0x3c9,write_p3c9,IO_MB); IO_RegisterReadHandler(0x3c9,read_p3c9,IO_MB); - } else if (machine==MCH_EGA) { - for (Bitu i=0;i<64;i++) { - if ((i&4)>0) vga.dac.rgb[i].red=0x2a; - else vga.dac.rgb[i].red=0; - if ((i&32)>0) vga.dac.rgb[i].red+=0x15; - - if ((i&2)>0) vga.dac.rgb[i].green=0x2a; - else vga.dac.rgb[i].green=0; - if ((i&16)>0) vga.dac.rgb[i].green+=0x15; - - if ((i&1)>0) vga.dac.rgb[i].blue=0x2a; - else vga.dac.rgb[i].blue=0; - if ((i&8)>0) vga.dac.rgb[i].blue+=0x15; - } } } diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index ad38ada7..ce56a52a 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1233,6 +1233,29 @@ void VGA_SetupDrawing(Bitu /*val*/) { // Display end vga.draw.delay.vdend = vdend * vga.draw.delay.htotal; + // EGA frequency dependent monitor palette + if (machine == MCH_EGA) { + if (vga.misc_output & 1) { + // EGA card is in color mode + if ((1.0f/vga.draw.delay.htotal) > 19.0f) { + // 64 color EGA mode + VGA_ATTR_SetEGAMonitorPalette(EGA); + } else { + // 16 color CGA mode compatibility + VGA_ATTR_SetEGAMonitorPalette(CGA); + } + } else { + // EGA card in monochrome mode + // It is not meant to be autodetected that way, you either + // have a monochrome or color monitor connected and + // the EGA switches configured appropriately. + // But this would only be a problem if a program sets + // the adapter to monochrome mode and still expects color output. + // Such a program should be shot to the moon... + VGA_ATTR_SetEGAMonitorPalette(MONO); + } + } + vga.draw.parts_total=VGA_PARTS; /* 6 Horizontal Sync Polarity. Negative if set diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 2b4efb30..efc46eec 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1046,6 +1046,8 @@ bool INT10_SetVideoMode(Bit16u mode) { break; case M_LIN4: case M_EGA: + if (CurMode->mode == 0x0f) + gfx_data[0x7]=0x05; // only planes 0 and 2 are used gfx_data[0x6]|=0x05; //graphics mode at 0xa000-affff break; case M_CGA4: @@ -1075,12 +1077,14 @@ bool INT10_SetVideoMode(Bit16u mode) { att_data[0x10]=0x01; //Color Graphics switch (CurMode->mode) { case 0x0f: - att_data[0x10]|=0x0a; //Monochrome - att_data[0x01]=0x08; - att_data[0x04]=0x18; - att_data[0x05]=0x18; - att_data[0x09]=0x08; - att_data[0x0d]=0x18; + att_data[0x12]=0x05; // planes 0 and 2 enabled + att_data[0x10]|=0x0a; // monochrome and blinking + + att_data[0x01]=0x08; // low-intensity + att_data[0x04]=0x18; // blink-on case + att_data[0x05]=0x18; // high-intensity + att_data[0x09]=0x08; // low-intensity in blink-off case + att_data[0x0d]=0x18; // high-intensity in blink-off break; case 0x11: for (i=1;i<16;i++) att_data[i]=0x3f; From 556ff13f878a79686f45615e79614737d98fcb17 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 27 Jan 2013 16:54:22 +0000 Subject: [PATCH 3724/4131] make RealHandle inline to silence some unused warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3814 --- include/dos_inc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index f32b3185..07a2bef6 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -638,7 +638,7 @@ struct DOS_Block { extern DOS_Block dos; -static Bit8u RealHandle(Bit16u handle) { +static INLINE Bit8u RealHandle(Bit16u handle) { DOS_PSP psp(dos.psp()); return psp.GetFileHandle(handle); } From 2c8adb2660b1b4b148fc600976543ec88ddd79f9 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 27 Jan 2013 18:27:36 +0000 Subject: [PATCH 3725/4131] Use current address instead of (current page * page size) for the scroll window base. This is the implementation in S3 and IBM VGA. Tseng BIOSes have the previous, incompatible implementation. Fixes an advertisement program and possibly others I don't remember. Patch by ripsaw. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3815 --- src/ints/int10_char.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index f619f00f..9915b787 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -201,9 +201,11 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit if(clr>=ncols) clr=(Bit8u)ncols-1; clr++; - /* Get the correct page */ - if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); - PhysPt base=CurMode->pstart+page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); + /* Get the correct page: current start address for current page (0xFF), + otherwise calculate from page number and page size */ + PhysPt base=CurMode->pstart; + if (page==0xff) base+=real_readw(BIOSMEM_SEG,BIOSMEM_CURRENT_START); + else base+=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); if (GCC_UNLIKELY(machine==MCH_PCJR)) { if (real_readb(BIOSMEM_SEG, BIOSMEM_CURRENT_MODE) >= 9) { From 68317303e6e5c1c953ea7978271d80751d2fd6f8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 7 Feb 2013 19:25:58 +0000 Subject: [PATCH 3726/4131] max cycles code now uses averaging as well when stepping down Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3816 --- src/dosbox.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index f074549c..6aad4192 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -179,7 +179,7 @@ increaseticks: Bit32s new_cmax = CPU_CycleMax; Bit64s cproc = (Bit64s)CPU_CycleMax * (Bit64s)ticksScheduled; if (cproc > 0) { - /* ignore the cycles added due to the io delay code in order + /* ignore the cycles added due to the IO delay code in order to have smoother auto cycle adjustments */ double ratioremoved = (double) CPU_IODelayRemoved / (double) cproc; if (ratioremoved < 1.0) { @@ -189,10 +189,13 @@ increaseticks: if (ticksScheduled >= 250 && ticksDone < 10 && ratio > 20480) ratio = 20480; Bit64s cmax_scaled = (Bit64s)CPU_CycleMax * (Bit64s)ratio; + /* The auto cycle code seems reliable enough to disable the fast cut back code. + * This should improve the fluency of complex games. if (ratio <= 1024) new_cmax = (Bit32s)(cmax_scaled / (Bit64s)1024); else - new_cmax = (Bit32s)(1 + (CPU_CycleMax >> 1) + cmax_scaled / (Bit64s)2048); + */ + new_cmax = (Bit32s)(1 + (CPU_CycleMax >> 1) + cmax_scaled / (Bit64s)2048); } } From d60d8b899519631766b49cc4e845c93b266dcd58 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 9 Feb 2013 21:11:32 +0000 Subject: [PATCH 3727/4131] Add int 33 0x2a for speed manager 96. (ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3817 --- src/ints/mouse.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 1fb2cf8a..3b2f963f 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -929,6 +929,12 @@ static Bitu INT33_Handler(void) { reg_cx=(Bit16u)mouse.max_x; reg_dx=(Bit16u)mouse.max_y; break; + case 0x2a: /* Get cursor hot spot */ + reg_al=(Bit8u)-mouse.hidden; // Microsoft uses a negative byte counter for cursor visibility + reg_bx=(Bit16u)mouse.hotx; + reg_cx=(Bit16u)mouse.hoty; + reg_dx=0x04; // PS/2 mouse type + break; case 0x31: /* Get Current Minimum/Maximum virtual coordinates */ reg_ax=(Bit16u)mouse.min_x; reg_bx=(Bit16u)mouse.min_y; From 967524cd760bd2778fbba6b702489a7f0f957bfd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 14 Feb 2013 15:00:55 +0000 Subject: [PATCH 3728/4131] Clean up Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3818 --- include/dma.h | 2 -- src/hardware/dma.cpp | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dma.h b/include/dma.h index d0e4fc79..3f2915cb 100644 --- a/include/dma.h +++ b/include/dma.h @@ -115,6 +115,4 @@ bool SecondDMAControllerAvailable(void); void DMA_SetWrapping(Bitu wrap); -static Bit32u dma_wrapping = 0xffff; - #endif diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 6d1bb9b0..830aa58d 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -31,6 +31,8 @@ DmaController *DmaControllers[2]; #define EMM_PAGEFRAME4K ((0xE000*16)/4096) Bit32u ems_board_mapping[LINK_START]; +static Bit32u dma_wrapping = 0xffff; + static void UpdateEMSMapping(void) { /* if EMS is not present, this will result in a 1:1 mapping */ Bitu i; From 16696af9b66229e04e329cacecbb768c19a1a18e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 26 Feb 2013 20:22:15 +0000 Subject: [PATCH 3729/4131] A cdrom has always 65535 clusters on a drive. Fixes regression with titus CD with mount, fixes usage with an image as well. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3819 --- src/dos/dos_programs.cpp | 2 +- src/dos/drive_iso.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index e9337721..7d74f1c9 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -197,7 +197,7 @@ public: str_size="512,32,32765,16000"; mediaid=0xF8; /* Hard Disk */ } else if (type=="cdrom") { - str_size="2048,1,32765,0"; + str_size="2048,1,65535,0"; mediaid=0xF8; /* Hard Disk */ } else { WriteOut(MSG_Get("PROGAM_MOUNT_ILL_TYPE"),type.c_str()); diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index af4bd691..86a96fbe 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -327,7 +327,7 @@ bool isoDrive::GetFileAttr(char *name, Bit16u *attr) { bool isoDrive::AllocationInfo(Bit16u *bytes_sector, Bit8u *sectors_cluster, Bit16u *total_clusters, Bit16u *free_clusters) { *bytes_sector = 2048; *sectors_cluster = 1; // cluster size for cdroms ? - *total_clusters = 60000; + *total_clusters = 65535; *free_clusters = 0; return true; } From 28fe87edce1e5b9a317e64927ae6aeeb43dd624d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 28 Feb 2013 10:30:26 +0000 Subject: [PATCH 3730/4131] Make system handler 24 pages, Fixes Mega Blast and maybe others. Thanks ripsaw Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3820 --- src/ints/ems.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 4ac6f846..6b930b33 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -1365,7 +1365,7 @@ public: emm_segmentmappings[i].handle=NULL_HANDLE; } - EMM_AllocateSystemHandle(8); // allocate OS-dedicated handle (ems handle zero, 128kb) + EMM_AllocateSystemHandle(24); // allocate OS-dedicated handle (ems handle zero, 384kb) if (ems_type==3) { DMA_SetWrapping(0xffffffff); // emm386-bug that disables dma wrapping From 15c1bb607f303f894ad31025d9898530809aea61 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Mar 2013 08:20:39 +0000 Subject: [PATCH 3731/4131] Refinements of an earlier fix. Thanks ripsaw Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3821 --- src/ints/bios_disk.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 1bacde48..1da9f294 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -334,14 +334,14 @@ static Bitu INT13_DiskHandler(void) { if ((machine==MCH_CGA) || (machine==MCH_PCJR)) { /* those bioses call floppy drive reset for invalid drive values */ if (((imageDiskList[0]) && (imageDiskList[0]->active)) || ((imageDiskList[1]) && (imageDiskList[1]->active))) { - if (reg_dl<0x80) reg_ip++; + if (machine!=MCH_PCJR && reg_dl<0x80) reg_ip++; last_status = 0x00; CALLBACK_SCF(false); } } return CBRET_NONE; } - if (reg_dl<0x80) reg_ip++; + if (machine!=MCH_PCJR && reg_dl<0x80) reg_ip++; last_status = 0x00; CALLBACK_SCF(false); } From ffd5cf861e7720bb1e4f97fbe0ef650f8acd2160 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 18 Mar 2013 12:34:13 +0000 Subject: [PATCH 3732/4131] Enable interupts after running INT 25 and 26, fixes Eol-ui Moheom installer (ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3822 --- src/dos/dos.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 86041334..a2fc2021 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1157,27 +1157,29 @@ static Bitu DOS_27Handler(void) { } static Bitu DOS_25Handler(void) { - if(Drives[reg_al]==0){ - reg_ax=0x8002; + if (Drives[reg_al] == 0){ + reg_ax = 0x8002; SETFLAGBIT(CF,true); - }else{ + } else { SETFLAGBIT(CF,false); - if((reg_cx != 1) ||(reg_dx != 1)) + if ((reg_cx != 1) ||(reg_dx != 1)) LOG(LOG_DOSMISC,LOG_NORMAL)("int 25 called but not as diskdetection drive %X",reg_al); - reg_ax=0; + reg_ax = 0; } + SETFLAGBIT(IF,true); return CBRET_NONE; } static Bitu DOS_26Handler(void) { LOG(LOG_DOSMISC,LOG_NORMAL)("int 26 called: hope for the best!"); - if(Drives[reg_al]==0){ - reg_ax=0x8002; + if (Drives[reg_al] == 0){ + reg_ax = 0x8002; SETFLAGBIT(CF,true); - }else{ + } else { SETFLAGBIT(CF,false); - reg_ax=0; + reg_ax = 0; } + SETFLAGBIT(IF,true); return CBRET_NONE; } From 6005315b208855e7f193268a331a3e1bec4f1cf3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 18 Mar 2013 12:35:53 +0000 Subject: [PATCH 3733/4131] Uniform warning message Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3823 --- src/misc/setup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 6b5a4ebb..7adc02b9 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -294,7 +294,7 @@ bool Prop_string::CheckValue(Value const& in, bool warn){ } } } - if(warn) LOG_MSG("\"%s\" is not a valid value for variable: %s.\nIt might now be reset it to default value: %s",in.ToString().c_str(),propname.c_str(),default_value.ToString().c_str()); + if(warn) LOG_MSG("\"%s\" is not a valid value for variable: %s.\nIt might now be reset to the default value: %s",in.ToString().c_str(),propname.c_str(),default_value.ToString().c_str()); return false; } From 2cd140bed26f232dc5e97864d15e51262e4e0213 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 18 Mar 2013 19:52:41 +0000 Subject: [PATCH 3734/4131] Replace NV_PixelDataRange with ARB_PixelBufferObject extension. Thanks gulikoza Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3824 --- src/gui/sdlmain.cpp | 116 +++++++++++++++++++++----------------------- 1 file changed, 54 insertions(+), 62 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index fd4c10fd..0fd6f9c4 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -63,34 +63,30 @@ #define APIENTRYP APIENTRY * #endif -#ifdef __WIN32__ -#define NVIDIA_PixelDataRange 1 - -#ifndef WGL_NV_allocate_memory -#define WGL_NV_allocate_memory 1 -typedef void * (APIENTRY * PFNWGLALLOCATEMEMORYNVPROC) (int size, float readfreq, float writefreq, float priority); -typedef void (APIENTRY * PFNWGLFREEMEMORYNVPROC) (void *pointer); +#ifndef GL_ARB_pixel_buffer_object +#define GL_ARB_pixel_buffer_object 1 +#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF #endif -PFNWGLALLOCATEMEMORYNVPROC db_glAllocateMemoryNV = NULL; -PFNWGLFREEMEMORYNVPROC db_glFreeMemoryNV = NULL; - -#else - +#ifndef GL_ARB_vertex_buffer_object +#define GL_ARB_vertex_buffer_object 1 +typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); +typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); +typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); +typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); +typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); +typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target); #endif -#if defined(NVIDIA_PixelDataRange) - -#ifndef GL_NV_pixel_data_range -#define GL_NV_pixel_data_range 1 -#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 -typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer); -typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); -#endif - -PFNGLPIXELDATARANGENVPROC glPixelDataRangeNV = NULL; - -#endif +PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL; +PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL; +PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL; +PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL; +PFNGLMAPBUFFERARBPROC glMapBufferARB = NULL; +PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = NULL; #endif //C_OPENGL @@ -181,15 +177,14 @@ struct SDL_Block { struct { Bitu pitch; void * framebuf; + GLuint buffer; GLuint texture; GLuint displaylist; GLint max_texsize; bool bilinear; bool packed_pixel; bool paletted_texture; -#if defined(NVIDIA_PixelDataRange) - bool pixel_data_range; -#endif + bool pixel_buffer_object; } opengl; #endif struct { @@ -611,11 +606,10 @@ dosurface: #if C_OPENGL case SCREEN_OPENGL: { - if (sdl.opengl.framebuf) { -#if defined(NVIDIA_PixelDataRange) - if (sdl.opengl.pixel_data_range) db_glFreeMemoryNV(sdl.opengl.framebuf); - else -#endif + if (sdl.opengl.pixel_buffer_object) { + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + if (sdl.opengl.buffer) glDeleteBuffersARB(1, &sdl.opengl.buffer); + } else if (sdl.opengl.framebuf) { free(sdl.opengl.framebuf); } sdl.opengl.framebuf=0; @@ -635,15 +629,12 @@ dosurface: goto dosurface; } /* Create the texture and display list */ -#if defined(NVIDIA_PixelDataRange) - if (sdl.opengl.pixel_data_range) { - sdl.opengl.framebuf=db_glAllocateMemoryNV(width*height*4,0.0,1.0,1.0); - glPixelDataRangeNV(GL_WRITE_PIXEL_DATA_RANGE_NV,width*height*4,sdl.opengl.framebuf); - glEnableClientState(GL_WRITE_PIXEL_DATA_RANGE_NV); + if (sdl.opengl.pixel_buffer_object) { + glGenBuffersARB(1, &sdl.opengl.buffer); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, sdl.opengl.buffer); + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, width*height*4, NULL, GL_STREAM_DRAW_ARB); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); } else { -#else - { -#endif sdl.opengl.framebuf=malloc(width*height*4); //32 bit color } sdl.opengl.pitch=width*4; @@ -697,10 +688,8 @@ dosurface: glEndList(); sdl.desktop.type=SCREEN_OPENGL; retFlags = GFX_CAN_32 | GFX_SCALING; -#if defined(NVIDIA_PixelDataRange) - if (sdl.opengl.pixel_data_range) + if (sdl.opengl.pixel_buffer_object) retFlags |= GFX_HARDWARE; -#endif break; }//OPENGL #endif //C_OPENGL @@ -854,7 +843,11 @@ bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) { return true; #if C_OPENGL case SCREEN_OPENGL: - pixels=(Bit8u *)sdl.opengl.framebuf; + if(sdl.opengl.pixel_buffer_object) { + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, sdl.opengl.buffer); + pixels=(Bit8u *)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY); + } else + pixels=(Bit8u *)sdl.opengl.framebuf; pitch=sdl.opengl.pitch; sdl.updating=true; return true; @@ -934,19 +927,18 @@ void GFX_EndUpdate( const Bit16u *changedLines ) { break; #if C_OPENGL case SCREEN_OPENGL: -#if defined(NVIDIA_PixelDataRange) - if (sdl.opengl.pixel_data_range) { - glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture); + if (sdl.opengl.pixel_buffer_object) { + glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); + glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, sdl.draw.width, sdl.draw.height, GL_BGRA_EXT, - GL_UNSIGNED_INT_8_8_8_8_REV, sdl.opengl.framebuf); + GL_UNSIGNED_INT_8_8_8_8_REV, 0); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); glCallList(sdl.opengl.displaylist); SDL_GL_SwapBuffers(); - } else -#endif - if (changedLines) { + } else if (changedLines) { Bitu y = 0, index = 0; - glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture); + glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture); while (y < sdl.draw.height) { if (!(index & 1)) { y += changedLines[index]; @@ -1231,24 +1223,24 @@ static void GUI_StartUp(Section * sec) { LOG_MSG("Could not initialize OpenGL, switching back to surface"); sdl.desktop.want_type=SCREEN_SURFACE; } else { + sdl.opengl.buffer=0; sdl.opengl.framebuf=0; sdl.opengl.texture=0; sdl.opengl.displaylist=0; glGetIntegerv (GL_MAX_TEXTURE_SIZE, &sdl.opengl.max_texsize); -#if defined(__WIN32__) && defined(NVIDIA_PixelDataRange) - glPixelDataRangeNV = (PFNGLPIXELDATARANGENVPROC) wglGetProcAddress("glPixelDataRangeNV"); - db_glAllocateMemoryNV = (PFNWGLALLOCATEMEMORYNVPROC) wglGetProcAddress("wglAllocateMemoryNV"); - db_glFreeMemoryNV = (PFNWGLFREEMEMORYNVPROC) wglGetProcAddress("wglFreeMemoryNV"); -#endif + glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)SDL_GL_GetProcAddress("glGenBuffersARB"); + glBindBufferARB = (PFNGLBINDBUFFERARBPROC)SDL_GL_GetProcAddress("glBindBufferARB"); + glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)SDL_GL_GetProcAddress("glDeleteBuffersARB"); + glBufferDataARB = (PFNGLBUFFERDATAARBPROC)SDL_GL_GetProcAddress("glBufferDataARB"); + glMapBufferARB = (PFNGLMAPBUFFERARBPROC)SDL_GL_GetProcAddress("glMapBufferARB"); + glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)SDL_GL_GetProcAddress("glUnmapBufferARB"); const char * gl_ext = (const char *)glGetString (GL_EXTENSIONS); if(gl_ext && *gl_ext){ sdl.opengl.packed_pixel=(strstr(gl_ext,"EXT_packed_pixels") > 0); sdl.opengl.paletted_texture=(strstr(gl_ext,"EXT_paletted_texture") > 0); -#if defined(NVIDIA_PixelDataRange) - sdl.opengl.pixel_data_range=(strstr(gl_ext,"GL_NV_pixel_data_range") >0 ) && - glPixelDataRangeNV && db_glAllocateMemoryNV && db_glFreeMemoryNV; - sdl.opengl.pixel_data_range = 0; -#endif + sdl.opengl.pixel_buffer_object=(strstr(gl_ext,"GL_ARB_pixel_buffer_object") >0 ) && + glGenBuffersARB && glBindBufferARB && glDeleteBuffersARB && glBufferDataARB && + glMapBufferARB && glUnmapBufferARB; } else { sdl.opengl.packed_pixel=sdl.opengl.paletted_texture=false; } From ca660c0cbf3ffb0e0f725ac6a44e049e56b9cac1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 20 Mar 2013 14:38:53 +0000 Subject: [PATCH 3735/4131] Use uppercase characters for ScanCMDBool. Explicitly disallow Set/P Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3825 --- src/shell/shell_cmds.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index b794c64e..661c6b5c 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -742,6 +742,8 @@ void DOS_Shell::CMD_COPY(char * args) { void DOS_Shell::CMD_SET(char * args) { HELP("SET"); + if (ScanCMDBool(args,"P")) + E_Exit("Set /P is not supported. Use Choice!"); StripSpaces(args); std::string line; if (!*args) { @@ -945,7 +947,7 @@ void DOS_Shell::CMD_CALL(char * args){ void DOS_Shell::CMD_DATE(char * args) { HELP("DATE"); - if(ScanCMDBool(args,"h")) { + if(ScanCMDBool(args,"H")) { // synchronize date with host parameter time_t curtime; struct tm *loctime; @@ -983,7 +985,7 @@ void DOS_Shell::CMD_DATE(char * args) { // date string appears valid for(Bit32u i = 0; i < length; i++) day[i] = datestring[reg_al*length+1+i]; } - bool dateonly = ScanCMDBool(args,"t"); + bool dateonly = ScanCMDBool(args,"T"); if(!dateonly) WriteOut(MSG_Get("SHELL_CMD_DATE_NOW")); const char* formatstring = MSG_Get("SHELL_CMD_DATE_FORMAT"); @@ -1006,7 +1008,7 @@ void DOS_Shell::CMD_DATE(char * args) { void DOS_Shell::CMD_TIME(char * args) { HELP("TIME"); - if(ScanCMDBool(args,"h")) { + if(ScanCMDBool(args,"H")) { // synchronize time with host parameter time_t curtime; struct tm *loctime; @@ -1026,7 +1028,7 @@ void DOS_Shell::CMD_TIME(char * args) { mem_writed(BIOS_TIMER,ticks); return; } - bool timeonly = ScanCMDBool(args,"t"); + bool timeonly = ScanCMDBool(args,"T"); reg_ah=0x2c; // get system time CALLBACK_RunRealInt(0x21); From 4344bb19847ac4f6c05c36e8127f43be852b2fdc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 24 Mar 2013 21:12:43 +0000 Subject: [PATCH 3736/4131] Silence some warnings in the misc directory Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3826 --- src/misc/setup.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 7adc02b9..6aa7b917 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -288,7 +288,7 @@ bool Prop_string::CheckValue(Value const& in, bool warn){ return true; } if((*it).ToString() == "%u") { - Bitu value; + Bit32u value; if(sscanf(in.ToString().c_str(),"%u",&value) == 1) { return true; } @@ -651,7 +651,7 @@ bool Config::PrintConfig(char const * const configfilename) const { } i=0; char prefix[80]; - snprintf(prefix,80, "\n# %*s ", maxwidth, ""); + snprintf(prefix,80, "\n# %*s ", (int)maxwidth, ""); while ((p = sec->Get_prop(i++))) { std::string help = p->Get_help(); std::string::size_type pos = std::string::npos; @@ -659,7 +659,7 @@ bool Config::PrintConfig(char const * const configfilename) const { help.replace(pos, 1, prefix); } - fprintf(outfile, "# %*s: %s", maxwidth, p->propname.c_str(), help.c_str()); + fprintf(outfile, "# %*s: %s", (int)maxwidth, p->propname.c_str(), help.c_str()); std::vector values = p->GetValues(); if (!values.empty()) { From 8582cfb2e96b7521b93b5b86c461b0f60092466c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 Mar 2013 20:07:42 +0000 Subject: [PATCH 3737/4131] Extend fullresolution=0x0 to more OSes. Tested on Windows, Linux and Mac OS X. Thanks for the hint about SDL_GetVideoInfo ny00123 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3827 --- src/gui/sdlmain.cpp | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 0fd6f9c4..1c8f1783 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1143,13 +1143,15 @@ static void GUI_StartUp(Section * sec) { char res[100]; strncpy( res, fullresolution, sizeof( res )); fullresolution = lowcase (res);//so x and X are allowed - if(strcmp(fullresolution,"original")) { + if (strcmp(fullresolution,"original")) { sdl.desktop.full.fixed = true; - char* height = const_cast(strchr(fullresolution,'x')); - if(height && * height) { - *height = 0; - sdl.desktop.full.height = (Bit16u)atoi(height+1); - sdl.desktop.full.width = (Bit16u)atoi(res); + if (strcmp(fullresolution,"desktop")) { //desktop = 0x0 + char* height = const_cast(strchr(fullresolution,'x')); + if (height && * height) { + *height = 0; + sdl.desktop.full.height = (Bit16u)atoi(height+1); + sdl.desktop.full.width = (Bit16u)atoi(res); + } } } } @@ -1171,10 +1173,22 @@ static void GUI_StartUp(Section * sec) { } } sdl.desktop.doublebuf=section->Get_bool("fulldouble"); +#if SDL_VERSION_ATLEAST(1, 2, 10) + if (!sdl.desktop.full.width || !sdl.desktop.full.height){ + //Can only be done on the very first call! Not restartable. + const SDL_VideoInfo* vidinfo = SDL_GetVideoInfo(); + if (vidinfo) { + sdl.desktop.full.width = vidinfo->current_w; + sdl.desktop.full.height = vidinfo->current_h; + } + } +#endif + if (!sdl.desktop.full.width) { #ifdef WIN32 sdl.desktop.full.width=(Bit16u)GetSystemMetrics(SM_CXSCREEN); #else + LOG_MSG("Your fullscreen resolution can NOT be determined, it's assumed to be 1024x768.\nPlease edit the configuration file if this value is wrong."); sdl.desktop.full.width=1024; #endif } @@ -1584,7 +1598,7 @@ void Config_Add_SDL() { Pbool->Set_help("Use double buffering in fullscreen. It can reduce screen flickering, but it can also result in a slow DOSBox."); Pstring = sdl_sec->Add_string("fullresolution",Property::Changeable::Always,"original"); - Pstring->Set_help("What resolution to use for fullscreen: original or fixed size (e.g. 1024x768).\n" + Pstring->Set_help("What resolution to use for fullscreen: original, desktop or a fixed size (e.g. 1024x768).\n" " Using your monitor's native resolution with aspect=true might give the best results.\n" " If you end up with small window on a large screen, try an output different from surface."); @@ -1629,7 +1643,7 @@ void Config_Add_SDL() { Pstring->Set_values(inactt); Pstring = sdl_sec->Add_path("mapperfile",Property::Changeable::Always,MAPPERFILE); - Pstring->Set_help("File used to load/save the key/event mappings from. Resetmapper only works with the defaul value."); + Pstring->Set_help("File used to load/save the key/event mappings from. Resetmapper only works with the default value."); Pbool = sdl_sec->Add_bool("usescancodes",Property::Changeable::Always,true); Pbool->Set_help("Avoid usage of symkeys, might not work on all operating systems."); From ebe309d51318c6e129678adb3657796e4d042fe6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 9 May 2013 14:05:39 +0000 Subject: [PATCH 3738/4131] Fix an out of bounds write error. Some more protection when reading in data and finally fix a few type casts warnings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3828 --- src/debug/debug.cpp | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 6973cc21..a6aae3f9 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -61,8 +61,8 @@ int old_cursor_state; // Forwards static void DrawCode(void); static void DEBUG_RaiseTimerIrq(void); -static void SaveMemory(Bitu seg, Bitu ofs1, Bit32u num); -static void SaveMemoryBin(Bitu seg, Bitu ofs1, Bit32u num); +static void SaveMemory(Bit16u seg, Bit32u ofs1, Bit32u num); +static void SaveMemoryBin(Bit16u seg, Bit32u ofs1, Bit32u num); static void LogMCBS(void); static void LogGDT(void); static void LogLDT(void); @@ -1856,9 +1856,9 @@ static void LogGDT(void) while (address %04Xxxx flags [uw] %x:%x::%x:%x [d=%x|a=%x]", i,entry.block.base,entry.block.us,table.block.us, entry.block.wr,table.block.wr,entry.block.d,entry.block.a); - LOG(LOG_MISC,LOG_ERROR)(out1); + LOG(LOG_MISC,LOG_ERROR)("%s",out1); } } } @@ -1926,10 +1926,10 @@ void LogPages(char* selname) { Bitu entry_addr=(table.block.base<<12)+(sel & 0x3ff)*4; entry.load=phys_readd(entry_addr); sprintf(out1,"page %05Xxxx -> %04Xxxx flags [puw] %x:%x::%x:%x::%x:%x",sel,entry.block.base,entry.block.p,table.block.p,entry.block.us,table.block.us,entry.block.wr,table.block.wr); - LOG(LOG_MISC,LOG_ERROR)(out1); + LOG(LOG_MISC,LOG_ERROR)("%s",out1); } else { sprintf(out1,"pagetable %03X not present, flags [puw] %x::%x::%x",(sel >> 10),table.block.p,table.block.us,table.block.wr); - LOG(LOG_MISC,LOG_ERROR)(out1); + LOG(LOG_MISC,LOG_ERROR)("%s",out1); } } } @@ -1938,24 +1938,24 @@ void LogPages(char* selname) { static void LogCPUInfo(void) { char out1[512]; sprintf(out1,"cr0:%08X cr2:%08X cr3:%08X cpl=%x",cpu.cr0,paging.cr2,paging.cr3,cpu.cpl); - LOG(LOG_MISC,LOG_ERROR)(out1); + LOG(LOG_MISC,LOG_ERROR)("%s",out1); sprintf(out1,"eflags:%08X [vm=%x iopl=%x nt=%x]",reg_flags,GETFLAG(VM)>>17,GETFLAG(IOPL)>>12,GETFLAG(NT)>>14); - LOG(LOG_MISC,LOG_ERROR)(out1); + LOG(LOG_MISC,LOG_ERROR)("%s",out1); sprintf(out1,"GDT base=%08X limit=%08X",cpu.gdt.GetBase(),cpu.gdt.GetLimit()); - LOG(LOG_MISC,LOG_ERROR)(out1); + LOG(LOG_MISC,LOG_ERROR)("%s",out1); sprintf(out1,"IDT base=%08X limit=%08X",cpu.idt.GetBase(),cpu.idt.GetLimit()); - LOG(LOG_MISC,LOG_ERROR)(out1); + LOG(LOG_MISC,LOG_ERROR)("%s",out1); Bitu sel=CPU_STR(); Descriptor desc; if (cpu.gdt.GetDescriptor(sel,desc)) { sprintf(out1,"TR selector=%04X, base=%08X limit=%08X*%X",sel,desc.GetBase(),desc.GetLimit(),desc.saved.seg.g?0x4000:1); - LOG(LOG_MISC,LOG_ERROR)(out1); + LOG(LOG_MISC,LOG_ERROR)("%s",out1); } sel=CPU_SLDT(); if (cpu.gdt.GetDescriptor(sel,desc)) { sprintf(out1,"LDT selector=%04X, base=%08X limit=%08X*%X",sel,desc.GetBase(),desc.GetLimit(),desc.saved.seg.g?0x4000:1); - LOG(LOG_MISC,LOG_ERROR)(out1); + LOG(LOG_MISC,LOG_ERROR)("%s",out1); } }; @@ -2036,7 +2036,7 @@ public: } char filename[128]; - char args[256]; + char args[256+1]; cmd->FindCommand(1,temp_line); safe_strncpy(filename,temp_line.c_str(),128); @@ -2208,15 +2208,15 @@ bool CDebugVar::LoadVars(char* name) // read number of vars Bit16u num; - fread(&num,1,sizeof(num),f); + if (fread(&num,sizeof(num),1,f) != 1) return false; for (Bit16u i=0; i Date: Thu, 9 May 2013 14:07:04 +0000 Subject: [PATCH 3739/4131] Fix bug 391 by relaxing the SET /P check. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3829 --- src/shell/shell_cmds.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 661c6b5c..cb398e65 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -742,8 +742,6 @@ void DOS_Shell::CMD_COPY(char * args) { void DOS_Shell::CMD_SET(char * args) { HELP("SET"); - if (ScanCMDBool(args,"P")) - E_Exit("Set /P is not supported. Use Choice!"); StripSpaces(args); std::string line; if (!*args) { @@ -754,6 +752,11 @@ void DOS_Shell::CMD_SET(char * args) { } return; } + //There are args: + char * pcheck = args; + while ( *pcheck && (*pcheck == ' ' || *pcheck == '\t')) pcheck++; + if (*pcheck && strlen(pcheck) >3 && (strncasecmp(pcheck,"/p ",3) == 0)) E_Exit("Set /P is not supported. Use Choice!"); + char * p=strpbrk(args, "="); if (!p) { if (!GetEnvStr(args,line)) WriteOut(MSG_Get("SHELL_CMD_SET_NOT_SET"),args); From 8e017c87c314a190854150fc1e2719ee7a3d176c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 21 May 2013 18:15:15 +0000 Subject: [PATCH 3740/4131] Workaround for using (windows) directories insides cue files on Linux. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3830 --- src/dos/cdrom_image.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index f98c6f2b..f636a7e5 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -658,7 +658,30 @@ bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) return true; } } - +#if defined (WIN32) || defined(OS2) + //Nothing +#else + //Consider the possibility that the filename has a windows directory seperator (inside the CUE file) + //which is common for some commercial rereleases of DOS games using DOSBox + + string copy = filename; + size_t l = copy.size(); + for (size_t i = 0; i < l;i++) { + if(copy[i] == '\\') copy[i] = '/'; + } + + if (stat(copy.c_str(), &test) == 0) { + filename = copy; + return true; + } + + tmpstr = pathname + "/" + copy; + if (stat(tmpstr.c_str(), &test) == 0) { + filename = tmpstr; + return true; + } + +#endif return false; } From f6864ba395cf8ed293bdc2aad44e40af7409c3ce Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sun, 26 May 2013 01:03:33 +0000 Subject: [PATCH 3741/4131] Initialize last byte of command tail. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3831 --- src/shell/shell_misc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index e4ebf0d7..136cba43 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -473,7 +473,7 @@ bool DOS_Shell::Execute(char * name,char * args) { /* Fill the command line */ CommandTail cmdtail; cmdtail.count = 0; - memset(&cmdtail.buffer,0,126); //Else some part of the string is unitialized (valgrind) + memset(&cmdtail.buffer,0,127); //Else some part of the string is unitialized (valgrind) if (strlen(line)>126) line[126]=0; cmdtail.count=(Bit8u)strlen(line); memcpy(cmdtail.buffer,line,strlen(line)); From 56d19f4f8d19a854f645a41c89e933be8342f48e Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 16 Jun 2013 20:42:27 +0000 Subject: [PATCH 3742/4131] By implementing Tandy special handling of the palette: - fix Starflight background color (reported by HunterZ) - keep Pirates! map background correct Also fix the palette after mode switch on the PCJr. Fixes Frogger II composite mode color attributes (reported by VileRancour). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3832 --- src/hardware/vga_other.cpp | 25 +++++++++++++------------ src/ints/int10_pal.cpp | 38 ++++++++++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 98f28e75..cb8508f7 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -438,9 +438,7 @@ static void tandy_update_palette() { switch (vga.mode) { case M_TANDY2: VGA_SetCGA2Table(vga.attr.palette[0], - //vga.attr.palette[vga.tandy.color_select&0xf]); - vga.attr.palette[0xf]); - //VGA_SetCGA2Table(vga.attr.palette[0xf],vga.attr.palette[0]); + vga.attr.palette[vga.tandy.color_select&0xf]); break; case M_TANDY4: if (vga.tandy.gfx_control & 0x8) { @@ -458,7 +456,7 @@ static void tandy_update_palette() { r_mask &= ~1; } VGA_SetCGA4Table( - vga.attr.palette[0], + vga.attr.palette[vga.tandy.color_select&0xf], vga.attr.palette[(2|color_set)& vga.tandy.palette_mask], vga.attr.palette[(4|(color_set& r_mask))& vga.tandy.palette_mask], vga.attr.palette[(6|color_set)& vga.tandy.palette_mask]); @@ -523,6 +521,7 @@ static void PCJr_FindMode(void) { if (vga.mode==M_TANDY16) VGA_SetModeNow(M_TANDY4); else VGA_SetMode(M_TANDY4); } + tandy_update_palette(); } else { VGA_SetMode(M_TANDY_TEXT); } @@ -588,17 +587,19 @@ static void write_tandy_reg(Bit8u val) { static void write_tandy(Bitu port,Bitu val,Bitu /*iolen*/) { switch (port) { case 0x3d8: - vga.tandy.mode_control=(Bit8u)val; - if (val&0x8) vga.attr.disabled &= ~1; - else vga.attr.disabled |= 1; - TandyCheckLineMask(); - VGA_SetBlinking(val & 0x20); - TANDY_FindMode(); + val &= 0x3f; // only bits 0-6 are used + if (vga.tandy.mode_control ^ val) { + vga.tandy.mode_control=(Bit8u)val; + if (val&0x8) vga.attr.disabled &= ~1; + else vga.attr.disabled |= 1; + TandyCheckLineMask(); + VGA_SetBlinking(val & 0x20); + TANDY_FindMode(); + VGA_StartResize(); + } break; case 0x3d9: vga.tandy.color_select=val; - if (vga.mode==M_TANDY2) vga.attr.palette[0xf] = vga.tandy.color_select&0xf; - else vga.attr.palette[0] = vga.tandy.color_select&0xf; // Pirates! tandy_update_palette(); break; case 0x3da: diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index a580220f..f6889a48 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -92,6 +92,7 @@ void INT10_SetOverscanBorderColor(Bit8u val) { case TANDY_ARCH_CASE: IO_Read(VGAREG_TDY_RESET); WriteTandyACTL(0x02,val); + IO_Write(VGAREG_TDY_ADDRESS, 0); // enable the screen break; case EGAVGA_ARCH_CASE: ResetACTL(); @@ -308,9 +309,37 @@ void INT10_SetBackgroundBorder(Bit8u val) { color_select=(color_select & 0xe0) | (val & 0x1f); real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select); - if (machine == MCH_CGA || machine == MCH_TANDY) + switch (machine) { + case MCH_CGA: + // only write the color select register IO_Write(0x3d9,color_select); - else if (machine == MCH_PCJR) { + break; + case MCH_TANDY: + // TODO handle val == 0x1x, wait for retrace + switch(CurMode->mode) { + default: // modes 0-5: write to color select and border + INT10_SetOverscanBorderColor(val); + IO_Write(0x3d9, color_select); + break; + case 0x06: // 2-color: only write the color select register + IO_Write(0x3d9, color_select); + break; + case 0x07: // Tandy monochrome not implemented + break; + case 0x08: + case 0x09: // 16-color: write to color select, border and pal. index 0 + INT10_SetOverscanBorderColor(val); + INT10_SetSinglePaletteRegister(0, val); + IO_Write(0x3d9, color_select); + break; + case 0x0a: // 4-color highres: + // write zero to color select, write palette to indexes 1-3 + // TODO palette + IO_Write(0x3d9, 0); + break; + } + break; + case MCH_PCJR: IO_Read(VGAREG_TDY_RESET); // reset the flipflop if (vga.mode!=M_TANDY_TEXT) { IO_Write(VGAREG_TDY_ADDRESS, 0x10); @@ -318,8 +347,8 @@ void INT10_SetBackgroundBorder(Bit8u val) { } IO_Write(VGAREG_TDY_ADDRESS, 0x2); // border color IO_Write(VGAREG_PCJR_DATA, color_select&0xf); - } - else if (IS_EGAVGA_ARCH) { + break; + case EGAVGA_ARCH_CASE: val = ((val << 1) & 0x10) | (val & 0x7); /* Always set the overscan color */ INT10_SetSinglePaletteRegister( 0x11, val ); @@ -333,6 +362,7 @@ void INT10_SetBackgroundBorder(Bit8u val) { INT10_SetSinglePaletteRegister( 2, val ); val+=2; INT10_SetSinglePaletteRegister( 3, val ); + break; } } From 18a0eb019062004dc09502b696a957fc90aa8cae Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 16 Jun 2013 20:46:36 +0000 Subject: [PATCH 3743/4131] Fix Hexsider display in Hercules mode. The game changes the CRTC base address to scroll in the buffer. Reported by VileRancour. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3833 --- src/hardware/vga_draw.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index ce56a52a..1970c063 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -892,7 +892,6 @@ static void VGA_VerticalTimer(Bitu /*val*/) { || !vga.draw.blinking) ? true:false; break; case M_HERC_GFX: - break; case M_CGA4:case M_CGA2: vga.draw.address=(vga.draw.address*2)&0x1fff; break; From 04d3d4db696d72d83e907e6e41bfaffe154970ff Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 18 Oct 2013 11:48:01 +0000 Subject: [PATCH 3744/4131] typos and warnings Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3834 --- src/debug/debug.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index a6aae3f9..f091d93b 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -365,7 +365,7 @@ void CBreakpoint::Activate(bool _active) // Statics std::list CBreakpoint::BPoints; CBreakpoint* CBreakpoint::ignoreOnce = 0; -Bitu ignoreAddressOnce = 0; +PhysPt ignoreAddressOnce = 0; CBreakpoint* CBreakpoint::AddBreakpoint(Bit16u seg, Bit32u off, bool once) { @@ -621,7 +621,7 @@ void CBreakpoint::ShowList(void) bool DEBUG_Breakpoint(void) { - /* First get the phyiscal address and check for a set Breakpoint */ + /* First get the physical address and check for a set Breakpoint */ if (!CBreakpoint::CheckBreakpoint(SegValue(cs),reg_eip)) return false; // Found. Breakpoint is valid PhysPt where=GetAddress(SegValue(cs),reg_eip); @@ -631,7 +631,7 @@ bool DEBUG_Breakpoint(void) bool DEBUG_IntBreakpoint(Bit8u intNum) { - /* First get the phyiscal address and check for a set Breakpoint */ + /* First get the physical address and check for a set Breakpoint */ PhysPt where=GetAddress(SegValue(cs),reg_eip); if (!CBreakpoint::CheckIntBreakpoint(where,intNum,reg_ah)) return false; // Found. Breakpoint is valid @@ -989,7 +989,7 @@ bool ParseCommand(char* str) { return true; }; - if (command == "MEMDUMPBIN") { // Dump memory to file bineary + if (command == "MEMDUMPBIN") { // Dump memory to file binary Bit16u seg = (Bit16u)GetHexValue(found,found); found++; Bit32u ofs = GetHexValue(found,found); found++; Bit32u num = GetHexValue(found,found); found++; @@ -1402,7 +1402,7 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) { // Variable found ? CDebugVar* var = CDebugVar::FindVar(address); if (var) { - // Replace occurence + // Replace occurrence char* pos1 = strchr(inst,'['); char* pos2 = strchr(inst,']'); if (pos1 && pos2) { @@ -1790,7 +1790,8 @@ static void LogMCBChain(Bit16u mcb_segment) { DOS_MCB mcb(mcb_segment); char filename[9]; // 8 characters plus a terminating NUL const char *psp_seg_note; - PhysPt dataAddr = PhysMake(dataSeg,dataOfs);// location being viewed in the "Data Overview" + Bit16u DOS_dataOfs = static_cast(dataOfs); //Realmode addressing only + PhysPt dataAddr = PhysMake(dataSeg,DOS_dataOfs);// location being viewed in the "Data Overview" // loop forever, breaking out of the loop once we've processed the last MCB while (true) { @@ -1820,7 +1821,7 @@ static void LogMCBChain(Bit16u mcb_segment) { PhysPt mcbStartAddr = PhysMake(mcb_segment+1,0); PhysPt mcbEndAddr = PhysMake(mcb_segment+1+mcb.GetSize(),0); if (dataAddr >= mcbStartAddr && dataAddr < mcbEndAddr) { - LOG(LOG_MISC,LOG_ERROR)(" (data addr %04hX:%04X is %u bytes past this MCB)",dataSeg,dataOfs,dataAddr - mcbStartAddr); + LOG(LOG_MISC,LOG_ERROR)(" (data addr %04hX:%04X is %u bytes past this MCB)",dataSeg,DOS_dataOfs,dataAddr - mcbStartAddr); } // if we've just processed the last MCB in the chain, break out of the loop From 3701512a164120ca4d6b1a4055fefdae90db3ffc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 18 Oct 2013 11:53:11 +0000 Subject: [PATCH 3745/4131] Rework ListMidi so it can be more easily added to more backends. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3835 --- include/Makefile.am | 1 + include/midi.h | 60 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 include/midi.h diff --git a/include/Makefile.am b/include/Makefile.am index 2e7808f6..5c89f480 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -20,6 +20,7 @@ keyboard.h \ logging.h \ mapper.h \ mem.h \ +midi.h \ mixer.h \ modules.h \ mouse.h \ diff --git a/include/midi.h b/include/midi.h new file mode 100644 index 00000000..f1106c2d --- /dev/null +++ b/include/midi.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2002-2013 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_MIDI_H +#define DOSBOX_MIDI_H + +#ifndef DOSBOX_PROGRAMS_H +#include "programs.h" +#endif + +class MidiHandler { +public: + MidiHandler(); + virtual bool Open(const char * /*conf*/) { return true; }; + virtual void Close(void) {}; + virtual void PlayMsg(Bit8u * /*msg*/) {}; + virtual void PlaySysex(Bit8u * /*sysex*/,Bitu /*len*/) {}; + virtual const char * GetName(void) { return "none"; }; + virtual void ListAll(Program * base) {}; + virtual ~MidiHandler() { }; + MidiHandler * next; +}; + + +#define SYSEX_SIZE 1024 +struct DB_Midi { + Bitu status; + Bitu cmd_len; + Bitu cmd_pos; + Bit8u cmd_buf[8]; + Bit8u rt_buf[8]; + struct { + Bit8u buf[SYSEX_SIZE]; + Bitu used; + Bitu delay; + Bit32u start; + } sysex; + bool available; + MidiHandler * handler; +}; + +extern DB_Midi midi; + +#endif From ffb8cec4d65cd32eba1d850ebcc5571c94d25134 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 18 Oct 2013 11:55:02 +0000 Subject: [PATCH 3746/4131] Rework ListMidi so it can be more easily added to more backends. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3836 --- src/gui/midi.cpp | 38 ++++++-------------------------------- src/gui/midi_win32.h | 8 ++++++++ src/hardware/mixer.cpp | 11 ++--------- 3 files changed, 16 insertions(+), 41 deletions(-) diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 989912ba..ce4647fb 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -25,6 +25,7 @@ #include "SDL.h" #include "dosbox.h" +#include "midi.h" #include "cross.h" #include "support.h" #include "setup.h" @@ -33,7 +34,6 @@ #include "hardware.h" #include "timer.h" -#define SYSEX_SIZE 1024 #define RAWBUF 1024 Bit8u MIDI_evt_len[256] = { @@ -59,23 +59,11 @@ Bit8u MIDI_evt_len[256] = { 0,2,3,2, 0,0,1,0, 1,0,1,1, 1,0,1,0 // 0xf0 }; -class MidiHandler; +MidiHandler * handler_list = 0; -MidiHandler * handler_list=0; - -class MidiHandler { -public: - MidiHandler() { - next=handler_list; - handler_list=this; - }; - virtual bool Open(const char * /*conf*/) { return true; }; - virtual void Close(void) {}; - virtual void PlayMsg(Bit8u * /*msg*/) {}; - virtual void PlaySysex(Bit8u * /*sysex*/,Bitu /*len*/) {}; - virtual const char * GetName(void) { return "none"; }; - virtual ~MidiHandler() { }; - MidiHandler * next; +MidiHandler::MidiHandler(){ + next = handler_list; + handler_list = this; }; MidiHandler Midi_none; @@ -103,21 +91,7 @@ MidiHandler Midi_none; #endif -static struct { - Bitu status; - Bitu cmd_len; - Bitu cmd_pos; - Bit8u cmd_buf[8]; - Bit8u rt_buf[8]; - struct { - Bit8u buf[SYSEX_SIZE]; - Bitu used; - Bitu delay; - Bit32u start; - } sysex; - bool available; - MidiHandler * handler; -} midi; +DB_Midi midi; void MIDI_RawOutByte(Bit8u data) { if (midi.sysex.start) { diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index 47c97e17..44cefd79 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -87,6 +87,14 @@ public: return; } } + void ListAll(Program* base) { + unsigned int total = midiOutGetNumDevs(); + for(unsigned int i = 0;i < total;i++) { + MIDIOUTCAPS mididev; + midiOutGetDevCaps(i, &mididev, sizeof(MIDIOUTCAPS)); + base->WriteOut("%2d\t \"%s\"\n",i,mididev.szPname); + } + } }; MidiHandler_win32 Midi_win32; diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index d611d4fb..c708f874 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -47,6 +47,7 @@ #include "mapper.h" #include "hardware.h" #include "programs.h" +#include "midi.h" #define MIXER_SSIZE 4 #define MIXER_SHIFT 14 @@ -577,15 +578,7 @@ private: } void ListMidi(){ -#if defined (WIN32) - unsigned int total = midiOutGetNumDevs(); - for(unsigned int i=0;iListAll(this); }; }; From 83ae2b4ff9113683a3de1dd0419acaaac1b0e8da Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 18 Oct 2013 11:57:45 +0000 Subject: [PATCH 3747/4131] Add midi.h to project file Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3837 --- visualc_net/dosbox.vcproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 876bd306..ae885531 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -822,6 +822,9 @@ + + From ec9de6ff360fe919411f5812a3c9faaf087222f1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 21 Oct 2013 20:54:22 +0000 Subject: [PATCH 3748/4131] Implement mixer /listmidi for coremidi. Thanks for the assistance Dominus Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3838 --- src/gui/midi_coremidi.h | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/gui/midi_coremidi.h b/src/gui/midi_coremidi.h index 460b44fd..01f8592a 100644 --- a/src/gui/midi_coremidi.h +++ b/src/gui/midi_coremidi.h @@ -25,14 +25,14 @@ private: public: MidiHandler_coremidi() {m_pCurPacket = 0;} const char * GetName(void) { return "coremidi"; } - bool Open(const char * conf) { - + bool Open(const char * conf) { // Get the MIDIEndPoint m_endpoint = 0; OSStatus result; Bitu numDests = MIDIGetNumberOfDestinations(); - Bitu destId = 0; - if(conf && conf[0]) destId = atoi(conf); + Bitu destId = 0; + if(conf && conf[0]) destId = atoi(conf); + if (destId < numDests) { m_endpoint = MIDIGetDestination(destId); @@ -67,7 +67,8 @@ public: MIDIClientDispose(m_client); // Dispose the endpoint - MIDIEndpointDispose(m_endpoint); + // Not, as it is for Endpoints created by us +// MIDIEndpointDispose(m_endpoint); } void PlayMsg(Bit8u * msg) { @@ -99,6 +100,21 @@ public: // Send the MIDIPacketList MIDISend(m_port,m_endpoint,packetList); } + void ListAll(Program* base) { + Bitu numDests = MIDIGetNumberOfDestinations(); + for(Bitu i = 0; i < numDests; i++){ + MIDIEndpointRef dest = MIDIGetDestination(i); + if(!dest) continue; + CFStringRef midiname = 0; + if(MIDIObjectGetStringProperty(dest, kMIDIPropertyDisplayName, &midiname) == noErr) { + const char * s = CFStringGetCStringPtr(midiname, kCFStringEncodingMacRoman); + if(s) base->WriteOut("%02d\t%s\n",i,s); + } + //This is for EndPoints created by us. + //MIDIEndpointDispose(dest); + } + + } }; MidiHandler_coremidi Midi_coremidi; From 49875ee505d1b889d284d932cd9605b3c3a4c547 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 22 Oct 2013 17:40:41 +0000 Subject: [PATCH 3749/4131] CD audio status returns zero start and end times when no track is playing. Fixes The Manhole. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3839 --- src/dos/dos_mscdex.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 688751d8..36ef3066 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -506,16 +506,21 @@ bool CMscdex::GetAudioStatus(Bit8u subUnit, bool& playing, bool& pause, TMSF& st if (subUnit>=numDrives) return false; dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioStatus(playing,pause); if (dinfo[subUnit].lastResult) { - // Start - Bit32u addr = dinfo[subUnit].audioStart + 150; - start.fr = (Bit8u)(addr%75); addr/=75; - start.sec = (Bit8u)(addr%60); - start.min = (Bit8u)(addr/60); - // End - addr = dinfo[subUnit].audioEnd + 150; - end.fr = (Bit8u)(addr%75); addr/=75; - end.sec = (Bit8u)(addr%60); - end.min = (Bit8u)(addr/60); + if (playing) { + // Start + Bit32u addr = dinfo[subUnit].audioStart + 150; + start.fr = (Bit8u)(addr%75); addr/=75; + start.sec = (Bit8u)(addr%60); + start.min = (Bit8u)(addr/60); + // End + addr = dinfo[subUnit].audioEnd + 150; + end.fr = (Bit8u)(addr%75); addr/=75; + end.sec = (Bit8u)(addr%60); + end.min = (Bit8u)(addr/60); + } else { + memset(&start,0,sizeof(start)); + memset(&end,0,sizeof(end)); + } } else { playing = false; pause = false; From 5e07c501b6f26e8a8569469de79846da0abf21a8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 26 Oct 2013 19:27:47 +0000 Subject: [PATCH 3750/4131] Add ADDLOG, which adds a message to the logfile. Convenient when debugging and retracing the resulting log afterwards. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3840 --- src/debug/debug.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index f091d93b..3cb7f184 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1037,6 +1037,11 @@ bool ParseCommand(char* str) { return true; }; + if (command == "ADDLOG") { + if(found && *found) DEBUG_ShowMsg("NOTICE: %s\n",found); + return true; + }; + if (command == "SR") { // Set register value DEBUG_ShowMsg("DEBUG: Set Register %s.\n",(ChangeRegister(found)?"success":"failure")); return true; @@ -1304,7 +1309,7 @@ bool ParseCommand(char* str) { DEBUG_ShowMsg("LOG [num] - Write cpu log file.\n"); DEBUG_ShowMsg("LOGS/LOGL [num] - Write short/long cpu log file.\n"); DEBUG_ShowMsg("HEAVYLOG - Enable/Disable automatic cpu log when dosbox exits.\n"); - DEBUG_ShowMsg("ZEROPROTECT - Enable/Disable zero code execution detecion.\n"); + DEBUG_ShowMsg("ZEROPROTECT - Enable/Disable zero code execution detection.\n"); #endif DEBUG_ShowMsg("SR [reg] [value] - Set register value.\n"); DEBUG_ShowMsg("SM [seg]:[off] [val] [.]..- Set memory with following values.\n"); @@ -1313,6 +1318,8 @@ bool ParseCommand(char* str) { DEBUG_ShowMsg("SV [filename] - Save var list in file.\n"); DEBUG_ShowMsg("LV [filename] - Load var list from file.\n"); + DEBUG_ShowMsg("ADDLOG [message] - Add message to the log file.\n"); + DEBUG_ShowMsg("MEMDUMP [seg]:[off] [len] - Write memory to file memdump.txt.\n"); DEBUG_ShowMsg("MEMDUMPBIN [s]:[o] [len] - Write memory to file memdump.bin.\n"); DEBUG_ShowMsg("SELINFO [segName] - Show selector info.\n"); From babf6195f53c744bc3d0be32b5d3b706764eb4fd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 4 Nov 2013 20:49:58 +0000 Subject: [PATCH 3751/4131] make clang happy. Thanks wjp Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3841 --- src/fpu/fpu_instructions_x86.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index 998730fc..24d61e36 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -1161,12 +1161,12 @@ static void FPU_FLD_F80(PhysPt addr) { static void FPU_FLD_I16(PhysPt addr,Bitu store_to) { fpu.p_regs[8].m1 = (Bit32u)mem_readw(addr); - FPUD_LOAD(fild,WORD,) + FPUD_LOAD(fild,WORD,s) } static void FPU_FLD_I16_EA(PhysPt addr) { fpu.p_regs[8].m1 = (Bit32u)mem_readw(addr); - FPUD_LOAD_EA(fild,WORD,) + FPUD_LOAD_EA(fild,WORD,s) } static void FPU_FLD_I32(PhysPt addr,Bitu store_to) { @@ -1211,7 +1211,7 @@ static void FPU_FST_F80(PhysPt addr) { } static void FPU_FST_I16(PhysPt addr) { - FPUD_STORE(fistp,WORD,) + FPUD_STORE(fistp,WORD,s) mem_writew(addr,(Bit16u)fpu.p_regs[8].m1); } From 2a8cf58b9982c48676019859293a9770e8593f38 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 5 Nov 2013 22:12:59 +0000 Subject: [PATCH 3752/4131] Reenable the setting of the %CONFIG% variable when doing a CONFIG -get command (reported in forum) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3842 --- src/misc/programs.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 1930b995..6c96b42d 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -575,6 +575,7 @@ void CONFIG::Run(void) { // it's a property name std::string val = sec->GetPropValue(pvars[0].c_str()); WriteOut("%s",val.c_str()); + first_shell->SetEnv("CONFIG",val.c_str()); } break; } @@ -592,6 +593,7 @@ void CONFIG::Run(void) { return; } WriteOut("%s",val.c_str()); + first_shell->SetEnv("CONFIG",val.c_str()); break; } default: From f8bbc2b54d440789a6a37cce8ada565465710576 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Nov 2013 12:54:53 +0000 Subject: [PATCH 3753/4131] Strip of leading zeroes from the IP. Thanks Zorix Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3843 --- src/hardware/serialport/softmodem.cpp | 30 +++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index 10f0dac8..a22e03de 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -362,18 +362,23 @@ void CSerialModem::DoCommand() { helper[0]=0; helper--; } + + //Large enough scope, so the buffers are still valid when reaching Dail. + char buffer[128]; + char obuffer[128]; if (strlen(foundstr) >= 12) { // Check if supplied parameter only consists of digits bool isNum = true; - for (Bitu i=0; i '9') isNum = false; if (isNum) { // Parameter is a number with at least 12 digits => this cannot // be a valid IP/name // Transform by adding dots - char buffer[128]; - Bitu j = 0; - for (Bitu i=0; i Date: Mon, 11 Nov 2013 12:56:19 +0000 Subject: [PATCH 3754/4131] Missed a year somehow. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3844 --- src/hardware/pic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 4e67e663..000b6b92 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2012 The DOSBox Team + * Copyright (C) 2002-2013 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 From a5c6f014ccb4780502d7555401452b48ab705b8d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Nov 2013 12:59:54 +0000 Subject: [PATCH 3755/4131] Add small delay when raising IRQ, fixes Llamatron 2012 and Lemmings 3D. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3845 --- src/hardware/sblaster.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 49fbea22..b3104696 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -984,7 +984,8 @@ static void DSP_DoCommand(void) { DSP_AddData(sb.dsp.test_register);; break; case 0xf2: /* Trigger 8bit IRQ */ - SB_RaiseIRQ(SB_IRQ_8); + //Small delay in order to emulate the slowness of the DSP, fixes Llamatron 2012 and Lemmings 3D + PIC_AddEvent(&DSP_RaiseIRQEvent,0.01f); break; case 0xf3: /* Trigger 16bit IRQ */ DSP_SB16_ONLY; From 80df53942c715ea18cf65a91d6f325d17e0db883 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Nov 2013 13:25:50 +0000 Subject: [PATCH 3756/4131] Update Arm dynrec core. Most important change: use ARMv7 instructions. Thanks a lot M-HT Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3846 --- src/cpu/core_dynrec.cpp | 9 +- src/cpu/core_dynrec/Makefile.am | 2 +- src/cpu/core_dynrec/risc_armv4le-o3.h | 870 +++++++++++------- src/cpu/core_dynrec/risc_armv4le-s3.h | 918 ------------------- src/cpu/core_dynrec/risc_armv4le-thumb-iw.h | 476 +++++++--- src/cpu/core_dynrec/risc_armv4le-thumb-niw.h | 476 +++++++--- src/cpu/core_dynrec/risc_armv4le-thumb.h | 454 ++++++--- src/cpu/core_dynrec/risc_armv4le.h | 18 +- 8 files changed, 1575 insertions(+), 1648 deletions(-) delete mode 100644 src/cpu/core_dynrec/risc_armv4le-s3.h diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index 35151780..16dd73c2 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -137,6 +137,7 @@ static struct { #define X86_64 0x02 #define MIPSEL 0x03 #define ARMV4LE 0x04 +#define ARMV7LE 0x05 #define POWERPC 0x04 #if C_TARGETCPU == X86_64 @@ -145,7 +146,7 @@ static struct { #include "core_dynrec/risc_x86.h" #elif C_TARGETCPU == MIPSEL #include "core_dynrec/risc_mipsel32.h" -#elif C_TARGETCPU == ARMV4LE +#elif (C_TARGETCPU == ARMV4LE) || (C_TARGETCPU == ARMV7LE) #include "core_dynrec/risc_armv4le.h" #elif C_TARGETCPU == POWERPC #include "core_dynrec/risc_ppc.h" @@ -163,7 +164,7 @@ CacheBlockDynRec * LinkBlocks(BlockReturn ret) { block=temp_handler->FindCacheBlock(temp_ip & 4095); if (!block) return NULL; - // found it, link the current block to + // found it, link the current block to cache.block.running->LinkTo(ret==BR_Link2,block); return block; } @@ -219,7 +220,7 @@ Bits CPU_Core_Dynrec_Run(void) { continue; } CPU_CycleLeft+=old_cycles; - return nc_retcode; + return nc_retcode; } } @@ -255,7 +256,7 @@ run_block: case BR_Cycles: // cycles went negative, return from the core to handle // external events, schedule the pic... -#if C_HEAVY_DEBUG +#if C_HEAVY_DEBUG if (DEBUG_HeavyIsBreakpoint()) return debugCallback; #endif return CBRET_NONE; diff --git a/src/cpu/core_dynrec/Makefile.am b/src/cpu/core_dynrec/Makefile.am index 2bc15bbc..288b9154 100644 --- a/src/cpu/core_dynrec/Makefile.am +++ b/src/cpu/core_dynrec/Makefile.am @@ -1,5 +1,5 @@ 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-o3.h risc_armv4le-thumb.h \ risc_armv4le-thumb-iw.h risc_armv4le-thumb-niw.h diff --git a/src/cpu/core_dynrec/risc_armv4le-o3.h b/src/cpu/core_dynrec/risc_armv4le-o3.h index f1100bb6..e95edee7 100644 --- a/src/cpu/core_dynrec/risc_armv4le-o3.h +++ b/src/cpu/core_dynrec/risc_armv4le-o3.h @@ -18,7 +18,7 @@ -/* ARMv4 (little endian) backend by M-HT (size-tweaked arm version) */ +/* ARMv4/ARMv7 (little endian) backend by M-HT (arm version) */ // temporary registers @@ -50,15 +50,14 @@ // temporary register for LEA #define TEMP_REG_DRC HOST_v2 -#ifdef DRC_USE_REGS_ADDR // used to hold the address of "cpu_regs" - preferably filled in function gen_run_code #define FC_REGS_ADDR HOST_v7 -#endif -#ifdef DRC_USE_SEGS_ADDR // used to hold the address of "Segs" - preferably filled in function gen_run_code #define FC_SEGS_ADDR HOST_v8 -#endif + +// used to hold the address of "core_dynrec.readdata" - filled in function gen_run_code +#define readdata_addr HOST_v5 // helper macro @@ -88,6 +87,12 @@ #define MOV_REG_ROR_REG(dst, src, rreg) (0xe1a00070 + ((dst) << 12) + (src) + ((rreg) << 8) ) // mvn dst, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 #define MVN_IMM(dst, imm, rimm) (0xe3e00000 + ((dst) << 12) + (imm) + ((rimm) << 7) ) +#if C_TARGETCPU == ARMV7LE +// movw dst, #imm @ 0 <= imm <= 65535 +#define MOVW(dst, imm) (0xe3000000 + ((dst) << 12) + (((imm) & 0xf000) << 4) + ((imm) & 0x0fff) ) +// movt dst, #imm @ 0 <= imm <= 65535 +#define MOVT(dst, imm) (0xe3400000 + ((dst) << 12) + (((imm) & 0xf000) << 4) + ((imm) & 0x0fff) ) +#endif // arithmetic // add dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 @@ -103,7 +108,11 @@ // cmp src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 #define CMP_IMM(src, imm, rimm) (0xe3500000 + ((src) << 16) + (imm) + ((rimm) << 7) ) // nop +#if C_TARGETCPU == ARMV7LE +#define NOP (0xe320f000) +#else #define NOP MOV_REG_LSL_IMM(HOST_r0, HOST_r0, 0) +#endif // logical // tst src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 @@ -122,34 +131,70 @@ #define EOR_REG_LSL_IMM(dst, src1, src2, imm) (0xe0200000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) // bic dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 #define BIC_IMM(dst, src, imm, rimm) (0xe3c00000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) +// bic dst, src1, src2, lsl #imm @ 0 <= imm <= 31 +#define BIC_REG_LSL_IMM(dst, src1, src2, imm) (0xe1c00000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) // load // ldr reg, [addr, #imm] @ 0 <= imm < 4096 #define LDR_IMM(reg, addr, imm) (0xe5900000 + ((reg) << 12) + ((addr) << 16) + (imm) ) +// ldr reg, [addr, #-(imm)] @ 0 <= imm < 4096 +#define LDR_IMM_M(reg, addr, imm) (0xe5100000 + ((reg) << 12) + ((addr) << 16) + (imm) ) // ldrh reg, [addr, #imm] @ 0 <= imm < 256 #define LDRH_IMM(reg, addr, imm) (0xe1d000b0 + ((reg) << 12) + ((addr) << 16) + (((imm) & 0xf0) << 4) + ((imm) & 0x0f) ) +// ldrh reg, [addr, #-(imm)] @ 0 <= imm < 256 +#define LDRH_IMM_M(reg, addr, imm) (0xe15000b0 + ((reg) << 12) + ((addr) << 16) + (((imm) & 0xf0) << 4) + ((imm) & 0x0f) ) // ldrb reg, [addr, #imm] @ 0 <= imm < 4096 #define LDRB_IMM(reg, addr, imm) (0xe5d00000 + ((reg) << 12) + ((addr) << 16) + (imm) ) +// ldrb reg, [addr, #-(imm)] @ 0 <= imm < 4096 +#define LDRB_IMM_M(reg, addr, imm) (0xe5500000 + ((reg) << 12) + ((addr) << 16) + (imm) ) +// ldr reg, [addr1, addr2, lsl #imm] @ 0 <= imm < 31 +#define LDR_REG_LSL_IMM(reg, addr1, addr2, imm) (0xe7900000 + ((reg) << 12) + ((addr1) << 16) + (addr2) + ((imm) << 7) ) // store // str reg, [addr, #imm] @ 0 <= imm < 4096 #define STR_IMM(reg, addr, imm) (0xe5800000 + ((reg) << 12) + ((addr) << 16) + (imm) ) +// str reg, [addr, #-(imm)] @ 0 <= imm < 4096 +#define STR_IMM_M(reg, addr, imm) (0xe5000000 + ((reg) << 12) + ((addr) << 16) + (imm) ) // strh reg, [addr, #imm] @ 0 <= imm < 256 #define STRH_IMM(reg, addr, imm) (0xe1c000b0 + ((reg) << 12) + ((addr) << 16) + (((imm) & 0xf0) << 4) + ((imm) & 0x0f) ) +// strh reg, [addr, #-(imm)] @ 0 <= imm < 256 +#define STRH_IMM_M(reg, addr, imm) (0xe14000b0 + ((reg) << 12) + ((addr) << 16) + (((imm) & 0xf0) << 4) + ((imm) & 0x0f) ) // strb reg, [addr, #imm] @ 0 <= imm < 4096 #define STRB_IMM(reg, addr, imm) (0xe5c00000 + ((reg) << 12) + ((addr) << 16) + (imm) ) +// strb reg, [addr, #-(imm)] @ 0 <= imm < 4096 +#define STRB_IMM_M(reg, addr, imm) (0xe5400000 + ((reg) << 12) + ((addr) << 16) + (imm) ) // branch // beq pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 #define BEQ_FWD(imm) (0x0a000000 + ((imm) >> 2) ) // bne pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 #define BNE_FWD(imm) (0x1a000000 + ((imm) >> 2) ) -// bgt pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 -#define BGT_FWD(imm) (0xca000000 + ((imm) >> 2) ) +// ble pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 +#define BLE_FWD(imm) (0xda000000 + ((imm) >> 2) ) // b pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 #define B_FWD(imm) (0xea000000 + ((imm) >> 2) ) // bx reg #define BX(reg) (0xe12fff10 + (reg) ) +#if C_TARGETCPU == ARMV7LE +// blx reg +#define BLX_REG(reg) (0xe12fff30 + (reg) ) + +// extend +// sxth dst, src, ror #rimm @ rimm = 0 | 8 | 16 | 24 +#define SXTH(dst, src, rimm) (0xe6bf0070 + ((dst) << 12) + (src) + (((rimm) & 24) << 7) ) +// sxtb dst, src, ror #rimm @ rimm = 0 | 8 | 16 | 24 +#define SXTB(dst, src, rimm) (0xe6af0070 + ((dst) << 12) + (src) + (((rimm) & 24) << 7) ) +// uxth dst, src, ror #rimm @ rimm = 0 | 8 | 16 | 24 +#define UXTH(dst, src, rimm) (0xe6ff0070 + ((dst) << 12) + (src) + (((rimm) & 24) << 7) ) +// uxtb dst, src, ror #rimm @ rimm = 0 | 8 | 16 | 24 +#define UXTB(dst, src, rimm) (0xe6ef0070 + ((dst) << 12) + (src) + (((rimm) & 24) << 7) ) + +// bit field +// bfi dst, src, #lsb, #width @ lsb >= 0, width >= 1, lsb+width <= 32 +#define BFI(dst, src, lsb, width) (0xe7c00010 + ((dst) << 12) + (src) + ((lsb) << 7) + (((lsb) + (width) - 1) << 16) ) +// bfc dst, #lsb, #width @ lsb >= 0, width >= 1, lsb+width <= 32 +#define BFC(dst, lsb, width) (0xe7c0001f + ((dst) << 12) + ((lsb) << 7) + (((lsb) + (width) - 1) << 16) ) +#endif // move a full register from reg_src to reg_dst @@ -158,6 +203,28 @@ static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { cache_addd( MOV_REG_LSL_IMM(reg_dst, reg_src, 0) ); // mov reg_dst, reg_src } +// helper function +static bool val_is_operand2(Bit32u value, Bit32u *val_shift) { + Bit32u shift; + + if (GCC_UNLIKELY(value == 0)) { + *val_shift = 0; + return true; + } + + shift = 0; + while ((value & 3) == 0) { + value>>=2; + shift+=2; + } + + if ((value >> 8) != 0) return false; + + *val_shift = shift; + return true; +} + +#if C_TARGETCPU != ARMV7LE // helper function static Bits get_imm_gen_len(Bit32u imm) { Bits ret; @@ -177,79 +244,44 @@ static Bits get_imm_gen_len(Bit32u imm) { } // helper function -static Bits get_method_imm_gen_len(Bit32u imm, Bits preffer00, Bits *num) { - Bits num00, num15, numadd, numsub, numret, ret; - num00 = get_imm_gen_len(imm); - num15 = get_imm_gen_len(~imm); - numadd = get_imm_gen_len(imm - ((Bit32u)cache.pos+8)); - numsub = get_imm_gen_len(((Bit32u)cache.pos+8) - imm); - if (numsub < numadd && numsub < num00 && numsub < num15) { - ret = 0; - numret = numsub; - } else if (numadd < num00 && numadd < num15) { - ret = 1; - numret = numadd; - } else if (num00 < num15 || (num00 == num15 && preffer00)) { - ret = 2; - numret = num00; - } else { - ret = 3; - numret = num15; - } - if (num != NULL) *num = numret; - return ret; +static Bits get_min_imm_gen_len(Bit32u imm) { + Bits num1, num2; + + num1 = get_imm_gen_len(imm); + num2 = get_imm_gen_len(~imm); + + return (num1 <= num2)?num1:num2; } +#endif // move a 32bit constant value into dest_reg static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { - Bits first, method, scale; - Bit32u imm2, dist; - if (imm == 0) { - cache_addd( MOV_IMM(dest_reg, 0, 0) ); // mov dest_reg, #0 - } else if (imm == 0xffffffff) { - cache_addd( MVN_IMM(dest_reg, 0, 0) ); // mvn dest_reg, #0 - } else { - method = get_method_imm_gen_len(imm, 1, NULL); +#if C_TARGETCPU == ARMV7LE + Bit32u scale; - scale = 0; - first = 1; - if (method == 0) { - dist = ((Bit32u)cache.pos+8) - imm; - while (dist) { - while ((dist & 3) == 0) { - dist>>=2; - scale+=2; - } - if (first) { - cache_addd( SUB_IMM(dest_reg, HOST_pc, dist & 0xff, ROTATE_SCALE(scale)) ); // sub dest_reg, pc, #((dist & 0xff) << scale) - first = 0; - } else { - cache_addd( SUB_IMM(dest_reg, dest_reg, dist & 0xff, ROTATE_SCALE(scale)) ); // sub dest_reg, dest_reg, #((dist & 0xff) << scale) - } - dist>>=8; - scale+=8; - } - } else if (method == 1) { - dist = imm - ((Bit32u)cache.pos+8); - if (dist == 0) { - cache_addd( MOV_REG_LSL_IMM(dest_reg, HOST_pc, 0) ); // mov dest_reg, pc - } else { - while (dist) { - while ((dist & 3) == 0) { - dist>>=2; - scale+=2; - } - if (first) { - cache_addd( ADD_IMM(dest_reg, HOST_pc, dist & 0xff, ROTATE_SCALE(scale)) ); // add dest_reg, pc, #((dist & 0xff) << scale) - first = 0; - } else { - cache_addd( ADD_IMM(dest_reg, dest_reg, dist & 0xff, ROTATE_SCALE(scale)) ); // add dest_reg, dest_reg, #((dist & 0xff) << scale) - } - dist>>=8; - scale+=8; - } - } - } else if (method == 2) { + if ( val_is_operand2(imm, &scale) ) { + cache_addd( MOV_IMM(dest_reg, imm >> scale, ROTATE_SCALE(scale)) ); // mov dest_reg, #imm + } else if ( val_is_operand2(~imm, &scale) ) { + cache_addd( MVN_IMM(dest_reg, (~imm) >> scale, ROTATE_SCALE(scale)) ); // mvn dest_reg, #~imm + } else { + cache_addd( MOVW(dest_reg, imm & 0xffff) ); // movw dest_reg, #(imm & 0xffff) + + if (imm >= 0x10000) + { + cache_addd( MOVT(dest_reg, imm >> 16) ); // movt dest_reg, #(imm >> 16) + } + } +#else + Bit32u imm2, first, scale; + + scale = 0; + first = 1; + imm2 = ~imm; + + if (get_imm_gen_len(imm) <= get_imm_gen_len(imm2)) { + if (imm == 0) { + cache_addd( MOV_IMM(dest_reg, 0, 0) ); // mov dest_reg, #0 + } else { while (imm) { while ((imm & 3) == 0) { imm>>=2; @@ -264,8 +296,11 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { imm>>=8; scale+=8; } + } + } else { + if (imm2 == 0) { + cache_addd( MVN_IMM(dest_reg, 0, 0) ); // mvn dest_reg, #0 } else { - imm2 = ~imm; while (imm2) { while ((imm2 & 3) == 0) { imm2>>=2; @@ -282,12 +317,67 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { } } } +#endif +} + +// helper function +static bool gen_mov_memval_to_reg_helper(HostReg dest_reg, Bit32u data, Bitu size, HostReg addr_reg, Bit32u addr_data) { + switch (size) { + case 4: +#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) + if ((data & 3) == 0) +#endif + { + if ((data >= addr_data) && (data < addr_data + 4096)) { + cache_addd( LDR_IMM(dest_reg, addr_reg, data - addr_data) ); // ldr dest_reg, [addr_reg, #(data - addr_data)] + return true; + } else if ((data < addr_data) && (data > addr_data - 4096)) { + cache_addd( LDR_IMM_M(dest_reg, addr_reg, addr_data - data) ); // ldr dest_reg, [addr_reg, #-(addr_data - data)] + return true; + } + } + break; + case 2: +#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) + if ((data & 1) == 0) +#endif + { + if ((data >= addr_data) && (data < addr_data + 256)) { + cache_addd( LDRH_IMM(dest_reg, addr_reg, data - addr_data) ); // ldrh dest_reg, [addr_reg, #(data - addr_data)] + return true; + } else if ((data < addr_data) && (data > addr_data - 256)) { + cache_addd( LDRH_IMM_M(dest_reg, addr_reg, addr_data - data) ); // ldrh dest_reg, [addr_reg, #-(addr_data - data)] + return true; + } + } + break; + case 1: + if ((data >= addr_data) && (data < addr_data + 4096)) { + cache_addd( LDRB_IMM(dest_reg, addr_reg, data - addr_data) ); // ldrb dest_reg, [addr_reg, #(data - addr_data)] + return true; + } else if ((data < addr_data) && (data > addr_data - 4096)) { + cache_addd( LDRB_IMM_M(dest_reg, addr_reg, addr_data - data) ); // ldrb dest_reg, [addr_reg, #-(addr_data - data)] + return true; + } + default: + break; + } + return false; +} + +// helper function +static bool gen_mov_memval_to_reg(HostReg dest_reg, void *data, Bitu size) { + if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, FC_REGS_ADDR, (Bit32u)&cpu_regs)) return true; + if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, readdata_addr, (Bit32u)&core_dynrec.readdata)) return true; + if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, FC_SEGS_ADDR, (Bit32u)&Segs)) return true; + return false; } // helper function for gen_mov_word_to_reg static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,HostReg data_reg) { // alignment.... if (dword) { +#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) if ((Bit32u)data & 3) { if ( ((Bit32u)data & 3) == 2 ) { cache_addd( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] @@ -300,15 +390,20 @@ static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,Ho cache_addd( LDRB_IMM(temp2, data_reg, 3) ); // ldrb temp2, [data_reg, #3] cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 24) ); // orr dest_reg, dest_reg, temp2, lsl #24 } - } else { + } else +#endif + { cache_addd( LDR_IMM(dest_reg, data_reg, 0) ); // ldr dest_reg, [data_reg] } } else { +#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) if ((Bit32u)data & 1) { cache_addd( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] cache_addd( LDRB_IMM(temp2, data_reg, 1) ); // ldrb temp2, [data_reg, #1] cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 8) ); // orr dest_reg, dest_reg, temp2, lsl #8 - } else { + } else +#endif + { cache_addd( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] } } @@ -317,42 +412,76 @@ static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,Ho // move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { - gen_mov_dword_to_reg_imm(temp1, (Bit32u)data); - gen_mov_word_to_reg_helper(dest_reg, data, dword, temp1); + if (!gen_mov_memval_to_reg(dest_reg, data, (dword)?4:2)) { + gen_mov_dword_to_reg_imm(temp1, (Bit32u)data); + gen_mov_word_to_reg_helper(dest_reg, data, dword, temp1); + } } // move a 16bit constant value into dest_reg // the upper 16bit of the destination register may be destroyed -static void gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { - Bits first, scale; - Bit32u imm2; - if (imm == 0) { - cache_addd( MOV_IMM(dest_reg, 0, 0) ); // mov dest_reg, #0 - } else { - scale = 0; - first = 1; - imm2 = (Bit32u)imm; - while (imm2) { - while ((imm2 & 3) == 0) { - imm2>>=2; - scale+=2; +static void INLINE gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { + gen_mov_dword_to_reg_imm(dest_reg, (Bit32u)imm); +} + +// helper function +static bool gen_mov_memval_from_reg_helper(HostReg src_reg, Bit32u data, Bitu size, HostReg addr_reg, Bit32u addr_data) { + switch (size) { + case 4: +#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) + if ((data & 3) == 0) +#endif + { + if ((data >= addr_data) && (data < addr_data + 4096)) { + cache_addd( STR_IMM(src_reg, addr_reg, data - addr_data) ); // str src_reg, [addr_reg, #(data - addr_data)] + return true; + } else if ((data < addr_data) && (data > addr_data - 4096)) { + cache_addd( STR_IMM_M(src_reg, addr_reg, addr_data - data) ); // str src_reg, [addr_reg, #-(addr_data - data)] + return true; + } } - if (first) { - cache_addd( MOV_IMM(dest_reg, imm2 & 0xff, ROTATE_SCALE(scale)) ); // mov dest_reg, #((imm2 & 0xff) << scale) - first = 0; - } else { - cache_addd( ORR_IMM(dest_reg, dest_reg, imm2 & 0xff, ROTATE_SCALE(scale)) ); // orr dest_reg, dest_reg, #((imm2 & 0xff) << scale) + break; + case 2: +#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) + if ((data & 1) == 0) +#endif + { + if ((data >= addr_data) && (data < addr_data + 256)) { + cache_addd( STRH_IMM(src_reg, addr_reg, data - addr_data) ); // strh src_reg, [addr_reg, #(data - addr_data)] + return true; + } else if ((data < addr_data) && (data > addr_data - 256)) { + cache_addd( STRH_IMM_M(src_reg, addr_reg, addr_data - data) ); // strh src_reg, [addr_reg, #-(addr_data - data)] + return true; + } } - imm2>>=8; - scale+=8; - } + break; + case 1: + if ((data >= addr_data) && (data < addr_data + 4096)) { + cache_addd( STRB_IMM(src_reg, addr_reg, data - addr_data) ); // strb src_reg, [addr_reg, #(data - addr_data)] + return true; + } else if ((data < addr_data) && (data > addr_data - 4096)) { + cache_addd( STRB_IMM_M(src_reg, addr_reg, addr_data - data) ); // strb src_reg, [addr_reg, #-(addr_data - data)] + return true; + } + default: + break; } + return false; +} + +// helper function +static bool gen_mov_memval_from_reg(HostReg src_reg, void *dest, Bitu size) { + if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, FC_REGS_ADDR, (Bit32u)&cpu_regs)) return true; + if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, readdata_addr, (Bit32u)&core_dynrec.readdata)) return true; + if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, FC_SEGS_ADDR, (Bit32u)&Segs)) return true; + return false; } // helper function for gen_mov_word_from_reg static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, HostReg data_reg) { // alignment.... if (dword) { +#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) if ((Bit32u)dest & 3) { if ( ((Bit32u)dest & 3) == 2 ) { cache_addd( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] @@ -365,15 +494,20 @@ static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, cache_addd( MOV_REG_LSR_IMM(temp2, temp2, 16) ); // mov temp2, temp2, lsr #16 cache_addd( STRB_IMM(temp2, data_reg, 3) ); // strb temp2, [data_reg, #3] } - } else { + } else +#endif + { cache_addd( STR_IMM(src_reg, data_reg, 0) ); // str src_reg, [data_reg] } } else { +#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) if ((Bit32u)dest & 1) { cache_addd( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] cache_addd( MOV_REG_LSR_IMM(temp2, src_reg, 8) ); // mov temp2, src_reg, lsr #8 cache_addd( STRB_IMM(temp2, data_reg, 1) ); // strb temp2, [data_reg, #1] - } else { + } else +#endif + { cache_addd( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] } } @@ -381,8 +515,10 @@ static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, // move 32bit (dword==true) or 16bit (dword==false) of a register into memory static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - gen_mov_word_from_reg_helper(src_reg, dest, dword, temp1); + if (!gen_mov_memval_from_reg(src_reg, dest, (dword)?4:2)) { + gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); + gen_mov_word_from_reg_helper(src_reg, dest, dword, temp1); + } } // move an 8bit value from memory into dest_reg @@ -390,8 +526,10 @@ static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { // this function does not use FC_OP1/FC_OP2 as dest_reg as these // registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { - gen_mov_dword_to_reg_imm(temp1, (Bit32u)data); - cache_addd( LDRB_IMM(dest_reg, temp1, 0) ); // ldrb dest_reg, [temp1] + if (!gen_mov_memval_to_reg(dest_reg, data, 1)) { + gen_mov_dword_to_reg_imm(temp1, (Bit32u)data); + cache_addd( LDRB_IMM(dest_reg, temp1, 0) ); // ldrb dest_reg, [temp1] + } } // move an 8bit value from memory into dest_reg @@ -420,8 +558,10 @@ static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u // move the lowest 8bit of a register into memory static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - cache_addd( STRB_IMM(src_reg, temp1, 0) ); // strb src_reg, [temp1] + if (!gen_mov_memval_from_reg(src_reg, dest, 1)) { + gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); + cache_addd( STRB_IMM(src_reg, temp1, 0) ); // strb src_reg, [temp1] + } } @@ -430,10 +570,18 @@ static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { // the register is zero-extended (sign==false) or sign-extended (sign==true) static void gen_extend_byte(bool sign,HostReg reg) { if (sign) { +#if C_TARGETCPU == ARMV7LE + cache_addd( SXTB(reg, reg, 0) ); // sxtb reg, reg +#else cache_addd( MOV_REG_LSL_IMM(reg, reg, 24) ); // mov reg, reg, lsl #24 cache_addd( MOV_REG_ASR_IMM(reg, reg, 24) ); // mov reg, reg, asr #24 +#endif } else { +#if C_TARGETCPU == ARMV7LE + cache_addd( UXTB(reg, reg, 0) ); // uxtb reg, reg +#else cache_addd( AND_IMM(reg, reg, 0xff, 0) ); // and reg, reg, #0xff +#endif } } @@ -441,11 +589,19 @@ static void gen_extend_byte(bool sign,HostReg reg) { // the register is zero-extended (sign==false) or sign-extended (sign==true) static void gen_extend_word(bool sign,HostReg reg) { if (sign) { +#if C_TARGETCPU == ARMV7LE + cache_addd( SXTH(reg, reg, 0) ); // sxth reg, reg +#else cache_addd( MOV_REG_LSL_IMM(reg, reg, 16) ); // mov reg, reg, lsl #16 cache_addd( MOV_REG_ASR_IMM(reg, reg, 16) ); // mov reg, reg, asr #16 +#endif } else { +#if C_TARGETCPU == ARMV7LE + cache_addd( UXTH(reg, reg, 0) ); // uxth reg, reg +#else cache_addd( MOV_REG_LSL_IMM(reg, reg, 16) ); // mov reg, reg, lsl #16 cache_addd( MOV_REG_LSR_IMM(reg, reg, 16) ); // mov reg, reg, lsr #16 +#endif } } @@ -457,72 +613,57 @@ static void gen_add(HostReg reg,void* op) { // add a 32bit constant value to a full register static void gen_add_imm(HostReg reg,Bit32u imm) { - Bits method1, method2, num1, num2, scale, sub; - if(!imm) return; - if (imm == 1) { - cache_addd( ADD_IMM(reg, reg, 1, 0) ); // add reg, reg, #1 - } else if (imm == 0xffffffff) { - cache_addd( SUB_IMM(reg, reg, 1, 0) ); // sub reg, reg, #1 - } else { - method1 = get_method_imm_gen_len(imm, 1, &num1); - method2 = get_method_imm_gen_len(-((Bit32s)imm), 1, &num2); - if (num2 < num1) { - method1 = method2; - imm = (Bit32u)(-((Bit32s)imm)); - sub = 1; - } else sub = 0; + Bit32u imm2, scale; - if (method1 != 2) { - gen_mov_dword_to_reg_imm(temp3, imm); - if (sub) { - cache_addd( SUB_REG_LSL_IMM(reg, reg, temp3, 0) ); // sub reg, reg, temp3 - } else { - cache_addd( ADD_REG_LSL_IMM(reg, reg, temp3, 0) ); // add reg, reg, temp3 - } + if(!imm) return; + + imm2 = (Bit32u) (-((Bit32s)imm)); + + if ( val_is_operand2(imm, &scale) ) { + cache_addd( ADD_IMM(reg, reg, imm >> scale, ROTATE_SCALE(scale)) ); // add reg, reg, #imm + } else if ( val_is_operand2(imm2, &scale) ) { + cache_addd( SUB_IMM(reg, reg, imm2 >> scale, ROTATE_SCALE(scale)) ); // sub reg, reg, #(-imm) +#if C_TARGETCPU == ARMV7LE + } else if (imm2 < 0x10000) { + cache_addd( MOVW(temp2, imm2) ); // movw temp2, #(-imm) + cache_addd( SUB_REG_LSL_IMM(reg, reg, temp2, 0) ); // sub reg, reg, temp2 +#endif + } else { +#if C_TARGETCPU != ARMV7LE + if (get_min_imm_gen_len(imm) <= get_min_imm_gen_len(imm2)) { +#endif + gen_mov_dword_to_reg_imm(temp2, imm); + cache_addd( ADD_REG_LSL_IMM(reg, reg, temp2, 0) ); // add reg, reg, temp2 +#if C_TARGETCPU != ARMV7LE } else { - scale = 0; - while (imm) { - while ((imm & 3) == 0) { - imm>>=2; - scale+=2; - } - if (sub) { - cache_addd( SUB_IMM(reg, reg, imm & 0xff, ROTATE_SCALE(scale)) ); // sub reg, reg, #((imm & 0xff) << scale) - } else { - cache_addd( ADD_IMM(reg, reg, imm & 0xff, ROTATE_SCALE(scale)) ); // add reg, reg, #((imm & 0xff) << scale) - } - imm>>=8; - scale+=8; - } + gen_mov_dword_to_reg_imm(temp2, imm2); + cache_addd( SUB_REG_LSL_IMM(reg, reg, temp2, 0) ); // sub reg, reg, temp2 } +#endif } } // and a 32bit constant value with a full register static void gen_and_imm(HostReg reg,Bit32u imm) { - Bits method, scale; - Bit32u imm2; + Bit32u imm2, scale; + imm2 = ~imm; if(!imm2) return; + if (!imm) { cache_addd( MOV_IMM(reg, 0, 0) ); // mov reg, #0 + } else if ( val_is_operand2(imm, &scale) ) { + cache_addd( AND_IMM(reg, reg, imm >> scale, ROTATE_SCALE(scale)) ); // and reg, reg, #imm + } else if ( val_is_operand2(imm2, &scale) ) { + cache_addd( BIC_IMM(reg, reg, imm2 >> scale, ROTATE_SCALE(scale)) ); // bic reg, reg, #(~imm) +#if C_TARGETCPU == ARMV7LE + } else if (imm2 < 0x10000) { + cache_addd( MOVW(temp2, imm2) ); // movw temp2, #(~imm) + cache_addd( BIC_REG_LSL_IMM(reg, reg, temp2, 0) ); // bic reg, reg, temp2 +#endif } else { - method = get_method_imm_gen_len(imm, 0, NULL); - if (method != 3) { - gen_mov_dword_to_reg_imm(temp3, imm); - cache_addd( AND_REG_LSL_IMM(reg, reg, temp3, 0) ); // and reg, reg, temp3 - } else { - scale = 0; - while (imm2) { - while ((imm2 & 3) == 0) { - imm2>>=2; - scale+=2; - } - cache_addd( BIC_IMM(reg, reg, imm2 & 0xff, ROTATE_SCALE(scale)) ); // bic reg, reg, #((imm2 & 0xff) << scale) - imm2>>=8; - scale+=8; - } - } + gen_mov_dword_to_reg_imm(temp2, imm); + cache_addd( AND_REG_LSL_IMM(reg, reg, temp2, 0) ); // and reg, reg, temp2 } } @@ -538,68 +679,71 @@ static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { gen_mov_direct_dword(dest,(Bit32u)imm); } -// add an 8bit constant value to a dword memory value -static void gen_add_direct_byte(void* dest,Bit8s imm) { - if(!imm) return; - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - gen_mov_word_to_reg_helper(temp3, dest, 1, temp1); - if (imm >= 0) { - cache_addd( ADD_IMM(temp3, temp3, (Bit32s)imm, 0) ); // add temp3, temp3, #(imm) - } else { - cache_addd( SUB_IMM(temp3, temp3, -((Bit32s)imm), 0) ); // sub temp3, temp3, #(-imm) - } - gen_mov_word_from_reg_helper(temp3, dest, 1, temp1); -} - // add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { + if (!dword) imm &= 0xffff; if(!imm) return; - if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { - gen_add_direct_byte(dest,(Bit8s)imm); - return; + + if (!gen_mov_memval_to_reg(temp3, dest, (dword)?4:2)) { + gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); + gen_mov_word_to_reg_helper(temp3, dest, dword, temp1); } - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - gen_mov_word_to_reg_helper(temp3, dest, dword, temp1); - // maybe use function gen_add_imm - if (dword) { - gen_mov_dword_to_reg_imm(temp2, imm); - } else { - gen_mov_word_to_reg_imm(temp2, (Bit16u)imm); + gen_add_imm(temp3, imm); + if (!gen_mov_memval_from_reg(temp3, dest, (dword)?4:2)) { + gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); } - cache_addd( ADD_REG_LSL_IMM(temp3, temp3, temp2, 0) ); // add temp3, temp3, temp2 - gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); } -// subtract an 8bit constant value from a dword memory value -static void gen_sub_direct_byte(void* dest,Bit8s imm) { - if(!imm) return; - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - gen_mov_word_to_reg_helper(temp3, dest, 1, temp1); - if (imm >= 0) { - cache_addd( SUB_IMM(temp3, temp3, (Bit32s)imm, 0) ); // sub temp3, temp3, #(imm) - } else { - cache_addd( ADD_IMM(temp3, temp3, -((Bit32s)imm), 0) ); // add temp3, temp3, #(-imm) - } - gen_mov_word_from_reg_helper(temp3, dest, 1, temp1); +// add an 8bit constant value to a dword memory value +static void gen_add_direct_byte(void* dest,Bit8s imm) { + gen_add_direct_word(dest, (Bit32s)imm, 1); } // subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { + Bit32u imm2, scale; + + if (!dword) imm &= 0xffff; if(!imm) return; - if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { - gen_sub_direct_byte(dest,(Bit8s)imm); - return; + + if (!gen_mov_memval_to_reg(temp3, dest, (dword)?4:2)) { + gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); + gen_mov_word_to_reg_helper(temp3, dest, dword, temp1); } - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - gen_mov_word_to_reg_helper(temp3, dest, dword, temp1); - // maybe use function gen_add_imm/gen_sub_imm - if (dword) { - gen_mov_dword_to_reg_imm(temp2, imm); + + imm2 = (Bit32u) (-((Bit32s)imm)); + + if ( val_is_operand2(imm, &scale) ) { + cache_addd( SUB_IMM(temp3, temp3, imm >> scale, ROTATE_SCALE(scale)) ); // sub temp3, temp3, #imm + } else if ( val_is_operand2(imm2, &scale) ) { + cache_addd( ADD_IMM(temp3, temp3, imm2 >> scale, ROTATE_SCALE(scale)) ); // add temp3, temp3, #(-imm) +#if C_TARGETCPU == ARMV7LE + } else if (imm2 < 0x10000) { + cache_addd( MOVW(temp2, imm2) ); // movw temp2, #(-imm) + cache_addd( ADD_REG_LSL_IMM(temp3, temp3, temp2, 0) ); // add temp3, temp3, temp2 +#endif } else { - gen_mov_word_to_reg_imm(temp2, (Bit16u)imm); +#if C_TARGETCPU != ARMV7LE + if (get_min_imm_gen_len(imm) <= get_min_imm_gen_len(imm2)) { +#endif + gen_mov_dword_to_reg_imm(temp2, imm); + cache_addd( SUB_REG_LSL_IMM(temp3, temp3, temp2, 0) ); // sub temp3, temp3, temp2 +#if C_TARGETCPU != ARMV7LE + } else { + gen_mov_dword_to_reg_imm(temp2, imm2); + cache_addd( ADD_REG_LSL_IMM(temp3, temp3, temp2, 0) ); // add temp3, temp3, temp2 + } +#endif } - cache_addd( SUB_REG_LSL_IMM(temp3, temp3, temp2, 0) ); // sub temp3, temp3, temp2 - gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); + + if (!gen_mov_memval_from_reg(temp3, dest, (dword)?4:2)) { + gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); + } +} + +// subtract an 8bit constant value from a dword memory value +static void gen_sub_direct_byte(void* dest,Bit8s imm) { + gen_sub_direct_word(dest, (Bit32s)imm, 1); } // effective address calculation, destination is dest_reg @@ -622,10 +766,16 @@ static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { // generate a call to a parameterless function static void INLINE gen_call_function_raw(void * func) { +#if C_TARGETCPU == ARMV7LE + cache_addd( MOVW(temp1, ((Bit32u)func) & 0xffff) ); // movw temp1, #(func & 0xffff) + cache_addd( MOVT(temp1, ((Bit32u)func) >> 16) ); // movt temp1, #(func >> 16) + cache_addd( BLX_REG(temp1) ); // blx temp1 +#else cache_addd( LDR_IMM(temp1, HOST_pc, 4) ); // ldr temp1, [pc, #4] cache_addd( ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 cache_addd( BX(temp1) ); // bx temp1 cache_addd((Bit32u)func); // .int func +#endif } // generate a call to a function with paramcount parameters @@ -665,43 +815,24 @@ static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { // jump to an address pointed at by ptr, offset is in imm static void gen_jmp_ptr(void * ptr,Bits imm=0) { - Bits num1, num2, scale, sub; - Bitu imm2; + Bit32u scale; + gen_mov_word_to_reg(temp3, ptr, 1); - if (imm) { - num1 = get_imm_gen_len(imm); - num2 = get_imm_gen_len(-imm); - - if (num2 < num1) { - imm = -imm; - sub = 1; - } else sub = 0; - - scale = 0; - imm2 = (Bitu)imm; - while (imm2) { - while ((imm2 & 3) == 0) { - imm2>>=2; - scale+=2; - } - if (sub) { - cache_addd( SUB_IMM(temp3, temp3, imm2 & 0xff, ROTATE_SCALE(scale)) ); // sub temp3, temp3, #((imm2 & 0xff) << scale) - } else { - cache_addd( ADD_IMM(temp3, temp3, imm2 & 0xff, ROTATE_SCALE(scale)) ); // add temp3, temp3, #((imm2 & 0xff) << scale) - } - imm2>>=8; - scale+=8; - } - } - -#if (1) -// (*ptr) should be word aligned +#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) +// (*ptr) should be word aligned if ((imm & 0x03) == 0) { - cache_addd( LDR_IMM(temp1, temp3, 0) ); // ldr temp1, [temp3] - } else #endif - { + if ((imm >= 0) && (imm < 4096)) { + cache_addd( LDR_IMM(temp1, temp3, imm) ); // ldr temp1, [temp3, #imm] + } else { + gen_mov_dword_to_reg_imm(temp2, imm); + cache_addd( LDR_REG_LSL_IMM(temp1, temp3, temp2, 0) ); // ldr temp1, [temp3, temp2] + } +#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) + } else { + gen_add_imm(temp3, imm); + cache_addd( LDRB_IMM(temp1, temp3, 0) ); // ldrb temp1, [temp3] cache_addd( LDRB_IMM(temp2, temp3, 1) ); // ldrb temp2, [temp3, #1] cache_addd( ORR_REG_LSL_IMM(temp1, temp1, temp2, 8) ); // orr temp1, temp1, temp2, lsl #8 @@ -710,6 +841,7 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { cache_addd( LDRB_IMM(temp2, temp3, 3) ); // ldrb temp2, [temp3, #3] cache_addd( ORR_REG_LSL_IMM(temp1, temp1, temp2, 24) ); // orr temp1, temp1, temp2, lsl #24 } +#endif cache_addd( BX(temp1) ); // bx temp1 } @@ -757,67 +889,74 @@ static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { } else { cache_addd( TST_IMM(reg, 0xff, 0) ); // tst reg, #0xff } - cache_addd( BEQ_FWD(8) ); // beq nobranch (pc +8) - cache_addd( LDR_IMM(temp1, HOST_pc, 0) ); // ldr temp1, [pc, #0] - cache_addd( BX(temp1) ); // bx temp1 - cache_addd(0); // fill j - // nobranch: + cache_addd( BNE_FWD(0) ); // bne j return ((Bit32u)cache.pos-4); } // compare 32bit-register against zero and jump if value less/equal than zero static Bit32u gen_create_branch_long_leqzero(HostReg reg) { cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 - cache_addd( BGT_FWD(8) ); // bgt nobranch (pc+8) - cache_addd( LDR_IMM(temp1, HOST_pc, 0) ); // ldr temp1, [pc, #0] - cache_addd( BX(temp1) ); // bx temp1 - cache_addd(0); // fill j - // nobranch: + cache_addd( BLE_FWD(0) ); // ble j return ((Bit32u)cache.pos-4); } // calculate long relative offset and fill it into the location pointed to by data static void INLINE gen_fill_branch_long(Bit32u data) { - // this is an absolute branch - *(Bit32u*)data=(Bit32u)cache.pos; + *(Bit32u*)data=( (*(Bit32u*)data) & 0xff000000 ) | ( ( ((Bit32u)cache.pos - (data+8)) >> 2 ) & 0x00ffffff ); } static void gen_run_code(void) { - cache_addd(0xe92d4000); // stmfd sp!, {lr} - cache_addd(0xe92d0cf0); // stmfd sp!, {v1-v4,v7,v8} +#if C_TARGETCPU == ARMV7LE + cache_addd(0xe92d4df0); // stmfd sp!, {v1-v5,v7,v8,lr} - // adr: 8 - cache_addd( LDR_IMM(FC_SEGS_ADDR, HOST_pc, 64 - (8 + 8)) ); // ldr FC_SEGS_ADDR, [pc, #(&Segs)] - // adr: 12 - cache_addd( LDR_IMM(FC_REGS_ADDR, HOST_pc, 68 - (12 + 8)) ); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)] + cache_addd( MOVW(FC_SEGS_ADDR, ((Bit32u)&Segs) & 0xffff) ); // movw FC_SEGS_ADDR, #(&Segs & 0xffff) + cache_addd( MOVT(FC_SEGS_ADDR, ((Bit32u)&Segs) >> 16) ); // movt FC_SEGS_ADDR, #(&Segs >> 16) - cache_addd( ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 - cache_addd(0xe92d4000); // stmfd sp!, {lr} - cache_addd( BX(HOST_r0) ); // bx r0 + cache_addd( MOVW(FC_REGS_ADDR, ((Bit32u)&cpu_regs) & 0xffff) ); // movw FC_REGS_ADDR, #(&cpu_regs & 0xffff) + cache_addd( MOVT(FC_REGS_ADDR, ((Bit32u)&cpu_regs) >> 16) ); // movt FC_REGS_ADDR, #(&cpu_regs >> 16) - cache_addd(0xe8bd0cf0); // ldmfd sp!, {v1-v4,v7,v8} + cache_addd( MOVW(readdata_addr, ((Bitu)&core_dynrec.readdata) & 0xffff) ); // movw readdata_addr, #(&core_dynrec.readdata & 0xffff) + cache_addd( MOVT(readdata_addr, ((Bitu)&core_dynrec.readdata) >> 16) ); // movt readdata_addr, #(&core_dynrec.readdata >> 16) - cache_addd(0xe8bd4000); // ldmfd sp!, {lr} - cache_addd( BX(HOST_lr) ); // bx lr + cache_addd( BX(HOST_r0) ); // bx r0 +#else + Bit8u *pos1, *pos2, *pos3; - // fill up to 64 bytes - cache_addd( NOP ); // nop - cache_addd( NOP ); // nop - cache_addd( NOP ); // nop - cache_addd( NOP ); // nop - cache_addd( NOP ); // nop - cache_addd( NOP ); // nop + cache_addd(0xe92d4df0); // stmfd sp!, {v1-v5,v7,v8,lr} - // adr: 64 + pos1 = cache.pos; + cache_addd( 0 ); + pos2 = cache.pos; + cache_addd( 0 ); + pos3 = cache.pos; + cache_addd( 0 ); + + cache_addd( BX(HOST_r0) ); // bx r0 + + // align cache.pos to 32 bytes + if ((((Bitu)cache.pos) & 0x1f) != 0) { + cache.pos = cache.pos + (32 - (((Bitu)cache.pos) & 0x1f)); + } + + *(Bit32u*)pos1 = LDR_IMM(FC_SEGS_ADDR, HOST_pc, cache.pos - (pos1 + 8)); // ldr FC_SEGS_ADDR, [pc, #(&Segs)] cache_addd((Bit32u)&Segs); // address of "Segs" - // adr: 68 + + *(Bit32u*)pos2 = LDR_IMM(FC_REGS_ADDR, HOST_pc, cache.pos - (pos2 + 8)); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)] cache_addd((Bit32u)&cpu_regs); // address of "cpu_regs" + + *(Bit32u*)pos3 = LDR_IMM(readdata_addr, HOST_pc, cache.pos - (pos3 + 8)); // ldr readdata_addr, [pc, #(&core_dynrec.readdata)] + cache_addd((Bit32u)&core_dynrec.readdata); // address of "core_dynrec.readdata" + + // align cache.pos to 32 bytes + if ((((Bitu)cache.pos) & 0x1f) != 0) { + cache.pos = cache.pos + (32 - (((Bitu)cache.pos) & 0x1f)); + } +#endif } // return from a function static void gen_return_function(void) { - cache_addd(0xe8bd4000); // ldmfd sp!, {lr} - cache_addd( BX(HOST_lr) ); // bx lr + cache_addd(0xe8bd8df0); // ldmfd sp!, {v1-v5,v7,v8,pc} } #ifdef DRC_FLAGS_INVALIDATION @@ -831,42 +970,52 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: - *(Bit32u*)pos=ADD_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // add FC_RETOP, a1, a2 + *(Bit32u*)pos=NOP; // nop *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+8)=ADD_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // add FC_RETOP, a1, a2 +#if C_TARGETCPU != ARMV7LE *(Bit32u*)(pos+12)=NOP; // nop +#endif break; case t_ORb: case t_ORw: case t_ORd: - *(Bit32u*)pos=ORR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // orr FC_RETOP, a1, a2 + *(Bit32u*)pos=NOP; // nop *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+8)=ORR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // orr FC_RETOP, a1, a2 +#if C_TARGETCPU != ARMV7LE *(Bit32u*)(pos+12)=NOP; // nop +#endif break; case t_ANDb: case t_ANDw: case t_ANDd: - *(Bit32u*)pos=AND_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // and FC_RETOP, a1, a2 + *(Bit32u*)pos=NOP; // nop *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+8)=AND_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // and FC_RETOP, a1, a2 +#if C_TARGETCPU != ARMV7LE *(Bit32u*)(pos+12)=NOP; // nop +#endif break; case t_SUBb: case t_SUBw: case t_SUBd: - *(Bit32u*)pos=SUB_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // sub FC_RETOP, a1, a2 + *(Bit32u*)pos=NOP; // nop *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+8)=SUB_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // sub FC_RETOP, a1, a2 +#if C_TARGETCPU != ARMV7LE *(Bit32u*)(pos+12)=NOP; // nop +#endif break; case t_XORb: case t_XORw: case t_XORd: - *(Bit32u*)pos=EOR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // eor FC_RETOP, a1, a2 + *(Bit32u*)pos=NOP; // nop *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+8)=EOR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // eor FC_RETOP, a1, a2 +#if C_TARGETCPU != ARMV7LE *(Bit32u*)(pos+12)=NOP; // nop +#endif break; case t_CMPb: case t_CMPw: @@ -874,114 +1023,185 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit32u*)pos=B_FWD(8); // b (pc+2*4) + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop +#if C_TARGETCPU != ARMV7LE + *(Bit32u*)(pos+12)=NOP; // nop +#endif break; case t_INCb: case t_INCw: case t_INCd: - *(Bit32u*)pos=ADD_IMM(FC_RETOP, HOST_a1, 1, 0); // add FC_RETOP, a1, #1 + *(Bit32u*)pos=NOP; // nop *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+8)=ADD_IMM(FC_RETOP, HOST_a1, 1, 0); // add FC_RETOP, a1, #1 +#if C_TARGETCPU != ARMV7LE *(Bit32u*)(pos+12)=NOP; // nop +#endif break; case t_DECb: case t_DECw: case t_DECd: - *(Bit32u*)pos=SUB_IMM(FC_RETOP, HOST_a1, 1, 0); // sub FC_RETOP, a1, #1 + *(Bit32u*)pos=NOP; // nop *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+8)=SUB_IMM(FC_RETOP, HOST_a1, 1, 0); // sub FC_RETOP, a1, #1 +#if C_TARGETCPU != ARMV7LE *(Bit32u*)(pos+12)=NOP; // nop +#endif break; case t_SHLb: case t_SHLw: case t_SHLd: - *(Bit32u*)pos=MOV_REG_LSL_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsl a2 + *(Bit32u*)pos=NOP; // nop *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+8)=MOV_REG_LSL_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsl a2 +#if C_TARGETCPU != ARMV7LE *(Bit32u*)(pos+12)=NOP; // nop +#endif break; case t_SHRb: - *(Bit32u*)pos=AND_IMM(FC_RETOP, HOST_a1, 0xff, 0); // and FC_RETOP, a1, #0xff - *(Bit32u*)(pos+4)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2 - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)pos=NOP; // nop +#if C_TARGETCPU == ARMV7LE + *(Bit32u*)(pos+4)=BFC(HOST_a1, 8, 24); // bfc a1, 8, 24 + *(Bit32u*)(pos+8)=MOV_REG_LSR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsr a2 +#else + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=AND_IMM(FC_RETOP, HOST_a1, 0xff, 0); // and FC_RETOP, a1, #0xff + *(Bit32u*)(pos+12)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2 +#endif break; case t_SHRw: - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=MOV_REG_LSR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+8)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2 - *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)pos=NOP; // nop +#if C_TARGETCPU == ARMV7LE + *(Bit32u*)(pos+4)=BFC(HOST_a1, 16, 16); // bfc a1, 16, 16 + *(Bit32u*)(pos+8)=MOV_REG_LSR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsr a2 +#else + *(Bit32u*)(pos+4)=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+8)=MOV_REG_LSR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+12)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2 +#endif break; case t_SHRd: - *(Bit32u*)pos=MOV_REG_LSR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsr a2 + *(Bit32u*)pos=NOP; // nop *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+8)=MOV_REG_LSR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsr a2 +#if C_TARGETCPU != ARMV7LE *(Bit32u*)(pos+12)=NOP; // nop +#endif break; case t_SARb: - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 - *(Bit32u*)(pos+4)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 24); // mov FC_RETOP, FC_RETOP, asr #24 + *(Bit32u*)pos=NOP; // nop +#if C_TARGETCPU == ARMV7LE + *(Bit32u*)(pos+4)=SXTB(FC_RETOP, HOST_a1, 0); // sxtb FC_RETOP, a1 *(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 - *(Bit32u*)(pos+12)=NOP; // nop +#else + *(Bit32u*)(pos+4)=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 + *(Bit32u*)(pos+8)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 24); // mov FC_RETOP, FC_RETOP, asr #24 + *(Bit32u*)(pos+12)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 +#endif break; case t_SARw: - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, asr #16 + *(Bit32u*)pos=NOP; // nop +#if C_TARGETCPU == ARMV7LE + *(Bit32u*)(pos+4)=SXTH(FC_RETOP, HOST_a1, 0); // sxth FC_RETOP, a1 *(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 - *(Bit32u*)(pos+12)=NOP; // nop +#else + *(Bit32u*)(pos+4)=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+8)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, asr #16 + *(Bit32u*)(pos+12)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 +#endif break; case t_SARd: - *(Bit32u*)pos=MOV_REG_ASR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, asr a2 + *(Bit32u*)pos=NOP; // nop *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, asr a2 +#if C_TARGETCPU != ARMV7LE *(Bit32u*)(pos+12)=NOP; // nop +#endif break; case t_RORb: +#if C_TARGETCPU == ARMV7LE + *(Bit32u*)pos=BFI(HOST_a1, HOST_a1, 8, 8); // bfi a1, a1, 8, 8 + *(Bit32u*)(pos+4)=BFI(HOST_a1, HOST_a1, 16, 16); // bfi a1, a1, 16, 16 + *(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 +#else *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 *(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 8); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 +#endif break; case t_RORw: - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 - *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)pos=NOP; // nop +#if C_TARGETCPU == ARMV7LE + *(Bit32u*)(pos+4)=BFI(HOST_a1, HOST_a1, 16, 16); // bfi a1, a1, 16, 16 + *(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 +#else + *(Bit32u*)(pos+4)=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 + *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 + *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 +#endif break; case t_RORd: - *(Bit32u*)pos=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 + *(Bit32u*)pos=NOP; // nop *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 +#if C_TARGETCPU != ARMV7LE *(Bit32u*)(pos+12)=NOP; // nop +#endif break; case t_ROLw: +#if C_TARGETCPU == ARMV7LE + *(Bit32u*)pos=BFI(HOST_a1, HOST_a1, 16, 16); // bfi a1, a1, 16, 16 + *(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 + *(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 +#else *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 *(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 +#endif break; case t_ROLd: - *(Bit32u*)pos=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 - *(Bit32u*)(pos+4)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)pos=NOP; // nop +#if C_TARGETCPU == ARMV7LE + *(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 + *(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 +#else + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 + *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 +#endif break; case t_NEGb: case t_NEGw: case t_NEGd: - *(Bit32u*)pos=RSB_IMM(FC_RETOP, HOST_a1, 0, 0); // rsb FC_RETOP, a1, #0 + *(Bit32u*)pos=NOP; // nop *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+8)=RSB_IMM(FC_RETOP, HOST_a1, 0, 0); // rsb FC_RETOP, a1, #0 +#if C_TARGETCPU != ARMV7LE *(Bit32u*)(pos+12)=NOP; // nop +#endif break; default: +#if C_TARGETCPU == ARMV7LE + *(Bit32u*)pos=MOVW(temp1, ((Bit32u)fct_ptr) & 0xffff); // movw temp1, #(fct_ptr & 0xffff) + *(Bit32u*)(pos+4)=MOVT(temp1, ((Bit32u)fct_ptr) >> 16); // movt temp1, #(fct_ptr >> 16) +#else *(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func +#endif break; } +#else +#if C_TARGETCPU == ARMV7LE + *(Bit32u*)pos=MOVW(temp1, ((Bit32u)fct_ptr) & 0xffff); // movw temp1, #(fct_ptr & 0xffff) + *(Bit32u*)(pos+4)=MOVT(temp1, ((Bit32u)fct_ptr) >> 16); // movt temp1, #(fct_ptr >> 16) #else *(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func #endif +#endif } #endif @@ -1043,7 +1263,7 @@ static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { // the upper 24bit of the destination register can be destroyed // this function can use FC_OP1/FC_OP2 as dest_reg which are // not directly byte-accessible on some architectures -static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { +static void gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { cache_addd( LDRB_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrb dest_reg, [FC_REGS_ADDR, #index] } diff --git a/src/cpu/core_dynrec/risc_armv4le-s3.h b/src/cpu/core_dynrec/risc_armv4le-s3.h deleted file mode 100644 index 358c04d3..00000000 --- a/src/cpu/core_dynrec/risc_armv4le-s3.h +++ /dev/null @@ -1,918 +0,0 @@ -/* - * Copyright (C) 2002-2013 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. - */ - - - -/* ARMv4 (little endian) backend by M-HT (speed-tweaked arm version) */ - - -// temporary registers -#define temp1 HOST_ip -#define temp2 HOST_v3 -#define temp3 HOST_v4 - -// register that holds function return values -#define FC_RETOP HOST_a1 - -// register used for address calculations, -#define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG - -// register that holds the first parameter -#define FC_OP1 HOST_a1 - -// register that holds the second parameter -#define FC_OP2 HOST_a2 - -// special register that holds the third parameter for _R3 calls (byte accessible) -#define FC_OP3 HOST_v2 - -// register that holds byte-accessible temporary values -#define FC_TMP_BA1 HOST_a1 - -// register that holds byte-accessible temporary values -#define FC_TMP_BA2 HOST_a2 - -// temporary register for LEA -#define TEMP_REG_DRC HOST_v2 - -#ifdef DRC_USE_REGS_ADDR -// used to hold the address of "cpu_regs" - preferably filled in function gen_run_code -#define FC_REGS_ADDR HOST_v7 -#endif - -#ifdef DRC_USE_SEGS_ADDR -// used to hold the address of "Segs" - preferably filled in function gen_run_code -#define FC_SEGS_ADDR HOST_v8 -#endif - - -// helper macro -#define ROTATE_SCALE(x) ( (x)?(32 - x):(0) ) - - -// instruction encodings - -// move -// mov dst, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define MOV_IMM(dst, imm, rimm) (0xe3a00000 + ((dst) << 12) + (imm) + ((rimm) << 7) ) -// mov dst, src, lsl #imm -#define MOV_REG_LSL_IMM(dst, src, imm) (0xe1a00000 + ((dst) << 12) + (src) + ((imm) << 7) ) -// movs dst, src, lsl #imm -#define MOVS_REG_LSL_IMM(dst, src, imm) (0xe1b00000 + ((dst) << 12) + (src) + ((imm) << 7) ) -// mov dst, src, lsr #imm -#define MOV_REG_LSR_IMM(dst, src, imm) (0xe1a00020 + ((dst) << 12) + (src) + ((imm) << 7) ) -// mov dst, src, asr #imm -#define MOV_REG_ASR_IMM(dst, src, imm) (0xe1a00040 + ((dst) << 12) + (src) + ((imm) << 7) ) -// mov dst, src, lsl rreg -#define MOV_REG_LSL_REG(dst, src, rreg) (0xe1a00010 + ((dst) << 12) + (src) + ((rreg) << 8) ) -// mov dst, src, lsr rreg -#define MOV_REG_LSR_REG(dst, src, rreg) (0xe1a00030 + ((dst) << 12) + (src) + ((rreg) << 8) ) -// mov dst, src, asr rreg -#define MOV_REG_ASR_REG(dst, src, rreg) (0xe1a00050 + ((dst) << 12) + (src) + ((rreg) << 8) ) -// mov dst, src, ror rreg -#define MOV_REG_ROR_REG(dst, src, rreg) (0xe1a00070 + ((dst) << 12) + (src) + ((rreg) << 8) ) -// mvn dst, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define MVN_IMM(dst, imm, rimm) (0xe3e00000 + ((dst) << 12) + (imm) + ((rimm) << 7) ) - -// arithmetic -// add dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define ADD_IMM(dst, src, imm, rimm) (0xe2800000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) -// add dst, src1, src2, lsl #imm -#define ADD_REG_LSL_IMM(dst, src1, src2, imm) (0xe0800000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) -// sub dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define SUB_IMM(dst, src, imm, rimm) (0xe2400000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) -// sub dst, src1, src2, lsl #imm -#define SUB_REG_LSL_IMM(dst, src1, src2, imm) (0xe0400000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) -// rsb dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define RSB_IMM(dst, src, imm, rimm) (0xe2600000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) -// cmp src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define CMP_IMM(src, imm, rimm) (0xe3500000 + ((src) << 16) + (imm) + ((rimm) << 7) ) -// nop -#define NOP MOV_REG_LSL_IMM(HOST_r0, HOST_r0, 0) - -// logical -// tst src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define TST_IMM(src, imm, rimm) (0xe3100000 + ((src) << 16) + (imm) + ((rimm) << 7) ) -// and dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define AND_IMM(dst, src, imm, rimm) (0xe2000000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) -// and dst, src1, src2, lsl #imm -#define AND_REG_LSL_IMM(dst, src1, src2, imm) (0xe0000000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) -// orr dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define ORR_IMM(dst, src, imm, rimm) (0xe3800000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) -// orr dst, src1, src2, lsl #imm -#define ORR_REG_LSL_IMM(dst, src1, src2, imm) (0xe1800000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) -// orr dst, src1, src2, lsr #imm -#define ORR_REG_LSR_IMM(dst, src1, src2, imm) (0xe1800020 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) -// eor dst, src1, src2, lsl #imm -#define EOR_REG_LSL_IMM(dst, src1, src2, imm) (0xe0200000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) -// bic dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define BIC_IMM(dst, src, imm, rimm) (0xe3c00000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) - -// load -// ldr reg, [addr, #imm] @ 0 <= imm < 4096 -#define LDR_IMM(reg, addr, imm) (0xe5900000 + ((reg) << 12) + ((addr) << 16) + (imm) ) -// ldrh reg, [addr, #imm] @ 0 <= imm < 256 -#define LDRH_IMM(reg, addr, imm) (0xe1d000b0 + ((reg) << 12) + ((addr) << 16) + (((imm) & 0xf0) << 4) + ((imm) & 0x0f) ) -// ldrb reg, [addr, #imm] @ 0 <= imm < 4096 -#define LDRB_IMM(reg, addr, imm) (0xe5d00000 + ((reg) << 12) + ((addr) << 16) + (imm) ) - -// store -// str reg, [addr, #imm] @ 0 <= imm < 4096 -#define STR_IMM(reg, addr, imm) (0xe5800000 + ((reg) << 12) + ((addr) << 16) + (imm) ) -// strh reg, [addr, #imm] @ 0 <= imm < 256 -#define STRH_IMM(reg, addr, imm) (0xe1c000b0 + ((reg) << 12) + ((addr) << 16) + (((imm) & 0xf0) << 4) + ((imm) & 0x0f) ) -// strb reg, [addr, #imm] @ 0 <= imm < 4096 -#define STRB_IMM(reg, addr, imm) (0xe5c00000 + ((reg) << 12) + ((addr) << 16) + (imm) ) - -// branch -// beq pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 -#define BEQ_FWD(imm) (0x0a000000 + ((imm) >> 2) ) -// bne pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 -#define BNE_FWD(imm) (0x1a000000 + ((imm) >> 2) ) -// bgt pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 -#define BGT_FWD(imm) (0xca000000 + ((imm) >> 2) ) -// b pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 -#define B_FWD(imm) (0xea000000 + ((imm) >> 2) ) -// bx reg -#define BX(reg) (0xe12fff10 + (reg) ) - - -// move a full register from reg_src to reg_dst -static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { - if(reg_src == reg_dst) return; - cache_addd( MOV_REG_LSL_IMM(reg_dst, reg_src, 0) ); // mov reg_dst, reg_src -} - -// move a 32bit constant value into dest_reg -static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { - Bits first, scale; - if (imm == 0) { - cache_addd( MOV_IMM(dest_reg, 0, 0) ); // mov dest_reg, #0 - } else { - scale = 0; - first = 1; - while (imm) { - while ((imm & 3) == 0) { - imm>>=2; - scale+=2; - } - if (first) { - cache_addd( MOV_IMM(dest_reg, imm & 0xff, ROTATE_SCALE(scale)) ); // mov dest_reg, #((imm & 0xff) << scale) - first = 0; - } else { - cache_addd( ORR_IMM(dest_reg, dest_reg, imm & 0xff, ROTATE_SCALE(scale)) ); // orr dest_reg, dest_reg, #((imm & 0xff) << scale) - } - imm>>=8; - scale+=8; - } - } -} - -// helper function for gen_mov_word_to_reg -static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,HostReg data_reg) { - // alignment.... - if (dword) { - if ((Bit32u)data & 3) { - if ( ((Bit32u)data & 3) == 2 ) { - cache_addd( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] - cache_addd( LDRH_IMM(temp2, data_reg, 2) ); // ldrh temp2, [data_reg, #2] - cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 16) ); // orr dest_reg, dest_reg, temp2, lsl #16 - } else { - cache_addd( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] - cache_addd( LDRH_IMM(temp2, data_reg, 1) ); // ldrh temp2, [data_reg, #1] - cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 8) ); // orr dest_reg, dest_reg, temp2, lsl #8 - cache_addd( LDRB_IMM(temp2, data_reg, 3) ); // ldrb temp2, [data_reg, #3] - cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 24) ); // orr dest_reg, dest_reg, temp2, lsl #24 - } - } else { - cache_addd( LDR_IMM(dest_reg, data_reg, 0) ); // ldr dest_reg, [data_reg] - } - } else { - if ((Bit32u)data & 1) { - cache_addd( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] - cache_addd( LDRB_IMM(temp2, data_reg, 1) ); // ldrb temp2, [data_reg, #1] - cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 8) ); // orr dest_reg, dest_reg, temp2, lsl #8 - } else { - cache_addd( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] - } - } -} - -// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { - gen_mov_dword_to_reg_imm(temp1, (Bit32u)data); - gen_mov_word_to_reg_helper(dest_reg, data, dword, temp1); -} - -// move a 16bit constant value into dest_reg -// the upper 16bit of the destination register may be destroyed -static void INLINE gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { - gen_mov_dword_to_reg_imm(dest_reg, (Bit32u)imm); -} - -// helper function for gen_mov_word_from_reg -static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, HostReg data_reg) { - // alignment.... - if (dword) { - if ((Bit32u)dest & 3) { - if ( ((Bit32u)dest & 3) == 2 ) { - cache_addd( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] - cache_addd( MOV_REG_LSR_IMM(temp2, src_reg, 16) ); // mov temp2, src_reg, lsr #16 - cache_addd( STRH_IMM(temp2, data_reg, 2) ); // strh temp2, [data_reg, #2] - } else { - cache_addd( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] - cache_addd( MOV_REG_LSR_IMM(temp2, src_reg, 8) ); // mov temp2, src_reg, lsr #8 - cache_addd( STRH_IMM(temp2, data_reg, 1) ); // strh temp2, [data_reg, #1] - cache_addd( MOV_REG_LSR_IMM(temp2, temp2, 16) ); // mov temp2, temp2, lsr #16 - cache_addd( STRB_IMM(temp2, data_reg, 3) ); // strb temp2, [data_reg, #3] - } - } else { - cache_addd( STR_IMM(src_reg, data_reg, 0) ); // str src_reg, [data_reg] - } - } else { - if ((Bit32u)dest & 1) { - cache_addd( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] - cache_addd( MOV_REG_LSR_IMM(temp2, src_reg, 8) ); // mov temp2, src_reg, lsr #8 - cache_addd( STRB_IMM(temp2, data_reg, 1) ); // strb temp2, [data_reg, #1] - } else { - cache_addd( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] - } - } -} - -// move 32bit (dword==true) or 16bit (dword==false) of a register into memory -static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - gen_mov_word_from_reg_helper(src_reg, dest, dword, temp1); -} - -// move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { - gen_mov_dword_to_reg_imm(temp1, (Bit32u)data); - cache_addd( LDRB_IMM(dest_reg, temp1, 0) ); // ldrb dest_reg, [temp1] -} - -// move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { - gen_mov_byte_to_reg_low(dest_reg, data); -} - -// move an 8bit constant value into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { - cache_addd( MOV_IMM(dest_reg, imm, 0) ); // mov dest_reg, #(imm) -} - -// move an 8bit constant value into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { - gen_mov_byte_to_reg_low_imm(dest_reg, imm); -} - -// move the lowest 8bit of a register into memory -static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - cache_addd( STRB_IMM(src_reg, temp1, 0) ); // strb src_reg, [temp1] -} - - - -// convert an 8bit word to a 32bit dword -// the register is zero-extended (sign==false) or sign-extended (sign==true) -static void gen_extend_byte(bool sign,HostReg reg) { - if (sign) { - cache_addd( MOV_REG_LSL_IMM(reg, reg, 24) ); // mov reg, reg, lsl #24 - cache_addd( MOV_REG_ASR_IMM(reg, reg, 24) ); // mov reg, reg, asr #24 - } else { - cache_addd( AND_IMM(reg, reg, 0xff, 0) ); // and reg, reg, #0xff - } -} - -// convert a 16bit word to a 32bit dword -// the register is zero-extended (sign==false) or sign-extended (sign==true) -static void gen_extend_word(bool sign,HostReg reg) { - if (sign) { - cache_addd( MOV_REG_LSL_IMM(reg, reg, 16) ); // mov reg, reg, lsl #16 - cache_addd( MOV_REG_ASR_IMM(reg, reg, 16) ); // mov reg, reg, asr #16 - } else { - cache_addd( MOV_REG_LSL_IMM(reg, reg, 16) ); // mov reg, reg, lsl #16 - cache_addd( MOV_REG_LSR_IMM(reg, reg, 16) ); // mov reg, reg, lsr #16 - } -} - -// add a 32bit value from memory to a full register -static void gen_add(HostReg reg,void* op) { - gen_mov_word_to_reg(temp3, op, 1); - cache_addd( ADD_REG_LSL_IMM(reg, reg, temp3, 0) ); // add reg, reg, temp3 -} - -// add a 32bit constant value to a full register -static void gen_add_imm(HostReg reg,Bit32u imm) { - Bits scale; - if(!imm) return; - if (imm == 0xffffffff) { - cache_addd( SUB_IMM(reg, reg, 1, 0) ); // sub reg, reg, #1 - } else { - scale = 0; - while (imm) { - while ((imm & 3) == 0) { - imm>>=2; - scale+=2; - } - cache_addd( ADD_IMM(reg, reg, imm & 0xff, ROTATE_SCALE(scale)) ); // add reg, reg, #((imm & 0xff) << scale) - imm>>=8; - scale+=8; - } - } -} - -// and a 32bit constant value with a full register -static void gen_and_imm(HostReg reg,Bit32u imm) { - Bits scale; - Bit32u imm2; - imm2 = ~imm; - if(!imm2) return; - if (!imm) { - cache_addd( MOV_IMM(reg, 0, 0) ); // mov reg, #0 - } else { - scale = 0; - while (imm2) { - while ((imm2 & 3) == 0) { - imm2>>=2; - scale+=2; - } - cache_addd( BIC_IMM(reg, reg, imm2 & 0xff, ROTATE_SCALE(scale)) ); // bic reg, reg, #((imm2 & 0xff) << scale) - imm2>>=8; - scale+=8; - } - } -} - - -// move a 32bit constant value into memory -static void gen_mov_direct_dword(void* dest,Bit32u imm) { - gen_mov_dword_to_reg_imm(temp3, imm); - gen_mov_word_from_reg(temp3, dest, 1); -} - -// move an address into memory -static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { - gen_mov_direct_dword(dest,(Bit32u)imm); -} - -// add an 8bit constant value to a dword memory value -static void gen_add_direct_byte(void* dest,Bit8s imm) { - if(!imm) return; - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - gen_mov_word_to_reg_helper(temp3, dest, 1, temp1); - if (imm >= 0) { - cache_addd( ADD_IMM(temp3, temp3, (Bit32s)imm, 0) ); // add temp3, temp3, #(imm) - } else { - cache_addd( SUB_IMM(temp3, temp3, -((Bit32s)imm), 0) ); // sub temp3, temp3, #(-imm) - } - gen_mov_word_from_reg_helper(temp3, dest, 1, temp1); -} - -// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value -static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { - if(!imm) return; - if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { - gen_add_direct_byte(dest,(Bit8s)imm); - return; - } - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - gen_mov_word_to_reg_helper(temp3, dest, dword, temp1); - // maybe use function gen_add_imm - if (dword) { - gen_mov_dword_to_reg_imm(temp2, imm); - } else { - gen_mov_word_to_reg_imm(temp2, (Bit16u)imm); - } - cache_addd( ADD_REG_LSL_IMM(temp3, temp3, temp2, 0) ); // add temp3, temp3, temp2 - gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); -} - -// subtract an 8bit constant value from a dword memory value -static void gen_sub_direct_byte(void* dest,Bit8s imm) { - if(!imm) return; - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - gen_mov_word_to_reg_helper(temp3, dest, 1, temp1); - if (imm >= 0) { - cache_addd( SUB_IMM(temp3, temp3, (Bit32s)imm, 0) ); // sub temp3, temp3, #(imm) - } else { - cache_addd( ADD_IMM(temp3, temp3, -((Bit32s)imm), 0) ); // add temp3, temp3, #(-imm) - } - gen_mov_word_from_reg_helper(temp3, dest, 1, temp1); -} - -// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value -static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { - if(!imm) return; - if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { - gen_sub_direct_byte(dest,(Bit8s)imm); - return; - } - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - gen_mov_word_to_reg_helper(temp3, dest, dword, temp1); - // maybe use function gen_add_imm/gen_sub_imm - if (dword) { - gen_mov_dword_to_reg_imm(temp2, imm); - } else { - gen_mov_word_to_reg_imm(temp2, (Bit16u)imm); - } - cache_addd( SUB_REG_LSL_IMM(temp3, temp3, temp2, 0) ); // sub temp3, temp3, temp2 - gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); -} - -// effective address calculation, destination is dest_reg -// scale_reg is scaled by scale (scale_reg*(2^scale)) and -// added to dest_reg, then the immediate value is added -static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { - cache_addd( ADD_REG_LSL_IMM(dest_reg, dest_reg, scale_reg, scale) ); // add dest_reg, dest_reg, scale_reg, lsl #(scale) - gen_add_imm(dest_reg, imm); -} - -// effective address calculation, destination is dest_reg -// dest_reg is scaled by scale (dest_reg*(2^scale)), -// then the immediate value is added -static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { - if (scale) { - cache_addd( MOV_REG_LSL_IMM(dest_reg, dest_reg, scale) ); // mov dest_reg, dest_reg, lsl #(scale) - } - gen_add_imm(dest_reg, imm); -} - -// generate a call to a parameterless function -static void INLINE gen_call_function_raw(void * func) { - cache_addd( LDR_IMM(temp1, HOST_pc, 4) ); // ldr temp1, [pc, #4] - cache_addd( ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 - cache_addd( BX(temp1) ); // bx temp1 - cache_addd((Bit32u)func); // .int func -} - -// generate a call to a function with paramcount parameters -// note: the parameters are loaded in the architecture specific way -// using the gen_load_param_ functions below -static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { - Bit32u proc_addr = (Bit32u)cache.pos; - gen_call_function_raw(func); - return proc_addr; -} - -#if (1) -// max of 4 parameters in a1-a4 - -// load an immediate value as param'th function parameter -static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { - gen_mov_dword_to_reg_imm(param, imm); -} - -// load an address as param'th function parameter -static void INLINE gen_load_param_addr(Bitu addr,Bitu param) { - gen_mov_dword_to_reg_imm(param, addr); -} - -// load a host-register as param'th function parameter -static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { - gen_mov_regs(param, reg); -} - -// load a value from memory as param'th function parameter -static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { - gen_mov_word_to_reg(param, (void *)mem, 1); -} -#else - other arm abis -#endif - -// jump to an address pointed at by ptr, offset is in imm -static void gen_jmp_ptr(void * ptr,Bits imm=0) { - Bits scale; - Bitu imm2; - gen_mov_word_to_reg(temp3, ptr, 1); - - if (imm) { - scale = 0; - imm2 = (Bitu)imm; - while (imm2) { - while ((imm2 & 3) == 0) { - imm2>>=2; - scale+=2; - } - cache_addd( ADD_IMM(temp3, temp3, imm2 & 0xff, ROTATE_SCALE(scale)) ); // add temp3, temp3, #((imm2 & 0xff) << scale) - imm2>>=8; - scale+=8; - } - } - -#if (1) -// (*ptr) should be word aligned - if ((imm & 0x03) == 0) { - cache_addd( LDR_IMM(temp1, temp3, 0) ); // ldr temp1, [temp3] - } else -#endif - { - cache_addd( LDRB_IMM(temp1, temp3, 0) ); // ldrb temp1, [temp3] - cache_addd( LDRB_IMM(temp2, temp3, 1) ); // ldrb temp2, [temp3, #1] - cache_addd( ORR_REG_LSL_IMM(temp1, temp1, temp2, 8) ); // orr temp1, temp1, temp2, lsl #8 - cache_addd( LDRB_IMM(temp2, temp3, 2) ); // ldrb temp2, [temp3, #2] - cache_addd( ORR_REG_LSL_IMM(temp1, temp1, temp2, 16) ); // orr temp1, temp1, temp2, lsl #16 - cache_addd( LDRB_IMM(temp2, temp3, 3) ); // ldrb temp2, [temp3, #3] - cache_addd( ORR_REG_LSL_IMM(temp1, temp1, temp2, 24) ); // orr temp1, temp1, temp2, lsl #24 - } - - cache_addd( BX(temp1) ); // bx temp1 -} - -// short conditional jump (+-127 bytes) if register is zero -// the destination is set by gen_fill_branch() later -static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { - if (dword) { - cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 - } else { - cache_addd( MOVS_REG_LSL_IMM(temp1, reg, 16) ); // movs temp1, reg, lsl #16 - } - cache_addd( BEQ_FWD(0) ); // beq j - return ((Bit32u)cache.pos-4); -} - -// short conditional jump (+-127 bytes) if register is nonzero -// the destination is set by gen_fill_branch() later -static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { - if (dword) { - cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 - } else { - cache_addd( MOVS_REG_LSL_IMM(temp1, reg, 16) ); // movs temp1, reg, lsl #16 - } - cache_addd( BNE_FWD(0) ); // bne j - return ((Bit32u)cache.pos-4); -} - -// calculate relative offset and fill it into the location pointed to by data -static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) { -#if C_DEBUG - Bits len=(Bit32u)cache.pos-(data+8); - if (len<0) len=-len; - if (len>0x02000000) LOG_MSG("Big jump %d",len); -#endif - *(Bit32u*)data=( (*(Bit32u*)data) & 0xff000000 ) | ( ( ((Bit32u)cache.pos - (data+8)) >> 2 ) & 0x00ffffff ); -} - -// conditional jump if register is nonzero -// for isdword==true the 32bit of the register are tested -// for isdword==false the lowest 8bit of the register are tested -static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { - if (isdword) { - cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 - } else { - cache_addd( TST_IMM(reg, 0xff, 0) ); // tst reg, #0xff - } - cache_addd( BEQ_FWD(8) ); // beq nobranch (pc +8) - cache_addd( LDR_IMM(temp1, HOST_pc, 0) ); // ldr temp1, [pc, #0] - cache_addd( BX(temp1) ); // bx temp1 - cache_addd(0); // fill j - // nobranch: - return ((Bit32u)cache.pos-4); -} - -// compare 32bit-register against zero and jump if value less/equal than zero -static Bit32u gen_create_branch_long_leqzero(HostReg reg) { - cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 - cache_addd( BGT_FWD(8) ); // bgt nobranch (pc+8) - cache_addd( LDR_IMM(temp1, HOST_pc, 0) ); // ldr temp1, [pc, #0] - cache_addd( BX(temp1) ); // bx temp1 - cache_addd(0); // fill j - // nobranch: - return ((Bit32u)cache.pos-4); -} - -// calculate long relative offset and fill it into the location pointed to by data -static void INLINE gen_fill_branch_long(Bit32u data) { - // this is an absolute branch - *(Bit32u*)data=(Bit32u)cache.pos; -} - -static void gen_run_code(void) { - cache_addd(0xe92d4000); // stmfd sp!, {lr} - cache_addd(0xe92d0cf0); // stmfd sp!, {v1-v4,v7,v8} - - // adr: 8 - cache_addd( LDR_IMM(FC_SEGS_ADDR, HOST_pc, 64 - (8 + 8)) ); // ldr FC_SEGS_ADDR, [pc, #(&Segs)] - // adr: 12 - cache_addd( LDR_IMM(FC_REGS_ADDR, HOST_pc, 68 - (12 + 8)) ); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)] - - cache_addd( ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 - cache_addd(0xe92d4000); // stmfd sp!, {lr} - cache_addd( BX(HOST_r0) ); // bx r0 - - cache_addd(0xe8bd0cf0); // ldmfd sp!, {v1-v4,v7,v8} - - cache_addd(0xe8bd4000); // ldmfd sp!, {lr} - cache_addd( BX(HOST_lr) ); // bx lr - - // fill up to 64 bytes - cache_addd( NOP ); // nop - cache_addd( NOP ); // nop - cache_addd( NOP ); // nop - cache_addd( NOP ); // nop - cache_addd( NOP ); // nop - cache_addd( NOP ); // nop - - // adr: 64 - cache_addd((Bit32u)&Segs); // address of "Segs" - // adr: 68 - cache_addd((Bit32u)&cpu_regs); // address of "cpu_regs" -} - -// return from a function -static void gen_return_function(void) { - cache_addd(0xe8bd4000); // ldmfd sp!, {lr} - cache_addd( BX(HOST_lr) ); // bx lr -} - -#ifdef DRC_FLAGS_INVALIDATION - -// called when a call to a function can be replaced by a -// call to a simpler function -static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { -#ifdef DRC_FLAGS_INVALIDATION_DCODE - // try to avoid function calls but rather directly fill in code - switch (flags_type) { - case t_ADDb: - case t_ADDw: - case t_ADDd: - *(Bit32u*)pos=ADD_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // add FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_ORb: - case t_ORw: - case t_ORd: - *(Bit32u*)pos=ORR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // orr FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_ANDb: - case t_ANDw: - case t_ANDd: - *(Bit32u*)pos=AND_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // and FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_SUBb: - case t_SUBw: - case t_SUBd: - *(Bit32u*)pos=SUB_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // sub FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_XORb: - case t_XORw: - case t_XORd: - *(Bit32u*)pos=EOR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // eor FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_CMPb: - case t_CMPw: - case t_CMPd: - case t_TESTb: - case t_TESTw: - case t_TESTd: - *(Bit32u*)pos=B_FWD(8); // b (pc+2*4) - break; - case t_INCb: - case t_INCw: - case t_INCd: - *(Bit32u*)pos=ADD_IMM(FC_RETOP, HOST_a1, 1, 0); // add FC_RETOP, a1, #1 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_DECb: - case t_DECw: - case t_DECd: - *(Bit32u*)pos=SUB_IMM(FC_RETOP, HOST_a1, 1, 0); // sub FC_RETOP, a1, #1 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_SHLb: - case t_SHLw: - case t_SHLd: - *(Bit32u*)pos=MOV_REG_LSL_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsl a2 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_SHRb: - *(Bit32u*)pos=AND_IMM(FC_RETOP, HOST_a1, 0xff, 0); // and FC_RETOP, a1, #0xff - *(Bit32u*)(pos+4)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2 - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_SHRw: - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=MOV_REG_LSR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+8)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2 - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_SHRd: - *(Bit32u*)pos=MOV_REG_LSR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsr a2 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_SARb: - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 - *(Bit32u*)(pos+4)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 24); // mov FC_RETOP, FC_RETOP, asr #24 - *(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_SARw: - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, asr #16 - *(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_SARd: - *(Bit32u*)pos=MOV_REG_ASR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, asr a2 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_RORb: - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 - *(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 8); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 - *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 - break; - case t_RORw: - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_RORd: - *(Bit32u*)pos=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_ROLw: - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 - *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 - break; - case t_ROLd: - *(Bit32u*)pos=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 - *(Bit32u*)(pos+4)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_NEGb: - case t_NEGw: - case t_NEGd: - *(Bit32u*)pos=RSB_IMM(FC_RETOP, HOST_a1, 0, 0); // rsb FC_RETOP, a1, #0 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - default: - *(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func - break; - - } -#else - *(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func -#endif -} -#endif - -static void cache_block_before_close(void) { } - -#ifdef DRC_USE_SEGS_ADDR - -// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { - cache_addd( LDRH_IMM(dest_reg, FC_SEGS_ADDR, index) ); // ldrh dest_reg, [FC_SEGS_ADDR, #index] -} - -// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) -static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { - cache_addd( LDR_IMM(dest_reg, FC_SEGS_ADDR, index) ); // ldr dest_reg, [FC_SEGS_ADDR, #index] -} - -// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) -static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { - cache_addd( LDR_IMM(temp1, FC_SEGS_ADDR, index) ); // ldr temp1, [FC_SEGS_ADDR, #index] - cache_addd( ADD_REG_LSL_IMM(reg, reg, temp1, 0) ); // add reg, reg, temp1 -} - -#endif - -#ifdef DRC_USE_REGS_ADDR - -// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { - cache_addd( LDRH_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrh dest_reg, [FC_REGS_ADDR, #index] -} - -// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { - cache_addd( LDR_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldr dest_reg, [FC_REGS_ADDR, #index] -} - -// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { - if (dword) { - cache_addd( LDR_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldr dest_reg, [FC_REGS_ADDR, #index] - } else { - cache_addd( LDRH_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrh dest_reg, [FC_REGS_ADDR, #index] - } -} - -// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { - cache_addd( LDRB_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrb dest_reg, [FC_REGS_ADDR, #index] -} - -// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { - cache_addd( LDRB_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrb dest_reg, [FC_REGS_ADDR, #index] -} - - -// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { - cache_addd( LDR_IMM(temp2, FC_REGS_ADDR, index) ); // ldr temp2, [FC_REGS_ADDR, #index] - cache_addd( ADD_REG_LSL_IMM(reg, reg, temp2, 0) ); // add reg, reg, temp2 -} - - -// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) -static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { - cache_addd( STRH_IMM(src_reg, FC_REGS_ADDR, index) ); // strh src_reg, [FC_REGS_ADDR, #index] -} - -// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { - cache_addd( STR_IMM(src_reg, FC_REGS_ADDR, index) ); // str src_reg, [FC_REGS_ADDR, #index] -} - -// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) -static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { - if (dword) { - cache_addd( STR_IMM(src_reg, FC_REGS_ADDR, index) ); // str src_reg, [FC_REGS_ADDR, #index] - } else { - cache_addd( STRH_IMM(src_reg, FC_REGS_ADDR, index) ); // strh src_reg, [FC_REGS_ADDR, #index] - } -} - -// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR -static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { - cache_addd( STRB_IMM(src_reg, FC_REGS_ADDR, index) ); // strb src_reg, [FC_REGS_ADDR, #index] -} - -#endif diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h index 6ead4b79..f962c5bf 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h @@ -50,15 +50,14 @@ // temporary register for LEA #define TEMP_REG_DRC HOST_a4 -#ifdef DRC_USE_REGS_ADDR // used to hold the address of "cpu_regs" - preferably filled in function gen_run_code #define FC_REGS_ADDR HOST_v7 -#endif -#ifdef DRC_USE_SEGS_ADDR // used to hold the address of "Segs" - preferably filled in function gen_run_code #define FC_SEGS_ADDR HOST_v8 -#endif + +// used to hold the address of "core_dynrec.readdata" - filled in function gen_run_code +#define readdata_addr HOST_v5 // instruction encodings @@ -98,10 +97,14 @@ // logical // and dst, src #define AND(dst, src) (0x4000 + (dst) + ((src) << 3) ) +// bic dst, src +#define BIC(dst, src) (0x4380 + (dst) + ((src) << 3) ) // eor dst, src #define EOR(dst, src) (0x4040 + (dst) + ((src) << 3) ) // orr dst, src #define ORR(dst, src) (0x4300 + (dst) + ((src) << 3) ) +// mvn dst, src +#define MVN(dst, src) (0x43c0 + (dst) + ((src) << 3) ) // shift/rotate // lsl dst, src, #imm @@ -128,6 +131,8 @@ #define LDRB_IMM(reg, addr, imm) (0x7800 + (reg) + ((addr) << 3) + ((imm) << 6) ) // ldr reg, [pc, #imm] @ 0 <= imm < 1024 & imm mod 4 = 0 #define LDR_PC_IMM(reg, imm) (0x4800 + ((reg) << 8) + ((imm) >> 2) ) +// ldr reg, [addr1, addr2] +#define LDR_REG(reg, addr1, addr2) (0x5800 + (reg) + ((addr1) << 3) + ((addr2) << 6) ) // store // str reg, [addr, #imm] @ 0 <= imm < 128 & imm mod 4 = 0 @@ -150,6 +155,25 @@ #define BX(reg) (0x4700 + ((reg) << 3) ) +// arm instructions + +// arithmetic +// add dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define ARM_ADD_IMM(dst, src, imm, rimm) (0xe2800000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) + +// load +// ldr reg, [addr, #imm] @ 0 <= imm < 4096 +#define ARM_LDR_IMM(reg, addr, imm) (0xe5900000 + ((reg) << 12) + ((addr) << 16) + (imm) ) + +// store +// str reg, [addr, #-(imm)]! @ 0 <= imm < 4096 +#define ARM_STR_IMM_M_W(reg, addr, imm) (0xe5200000 + ((reg) << 12) + ((addr) << 16) + (imm) ) + +// branch +// bx reg +#define ARM_BX(reg) (0xe12fff10 + (reg) ) + + // data pool defines #define CACHE_DATA_JUMP (2) #define CACHE_DATA_ALIGN (32) @@ -193,7 +217,7 @@ static void cache_checkinstr(Bit32u size) { cache_datapos = (Bit8u *) (((Bitu)cache.block.active->cache.start + cache.block.active->cache.size - CACHE_DATA_ALIGN) & ~(CACHE_DATA_ALIGN - 1)); } else { register Bit32u cachemodsize; - + cachemodsize = (cache.pos - cache.block.active->cache.start) & (CACHE_MAXSIZE - 1); if (cachemodsize + CACHE_DATA_MAX + CACHE_DATA_ALIGN <= CACHE_MAXSIZE || @@ -275,30 +299,49 @@ static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { cache_addw( MOV_REG(reg_dst, reg_src) ); // mov reg_dst, reg_src } +// helper function +static bool val_single_shift(Bit32u value, Bit32u *val_shift) { + Bit32u shift; + + if (GCC_UNLIKELY(value == 0)) { + *val_shift = 0; + return true; + } + + shift = 0; + while ((value & 1) == 0) { + value>>=1; + shift+=1; + } + + if ((value >> 8) != 0) return false; + + *val_shift = shift; + return true; +} + // move a 32bit constant value into dest_reg static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { - if ((imm & 0xffffff00) == 0) { + Bit32u scale; + + if (imm < 256) { cache_checkinstr(2); cache_addw( MOV_IMM(dest_reg, imm) ); // mov dest_reg, #(imm) - } else if ((imm & 0xffff00ff) == 0) { + } else if ((~imm) < 256) { cache_checkinstr(4); - cache_addw( MOV_IMM(dest_reg, imm >> 8) ); // mov dest_reg, #(imm >> 8) - cache_addw( LSL_IMM(dest_reg, dest_reg, 8) ); // lsl dest_reg, dest_reg, #8 - } else if ((imm & 0xff00ffff) == 0) { + cache_addw( MOV_IMM(dest_reg, ~imm) ); // mov dest_reg, #(~imm) + cache_addw( MVN(dest_reg, dest_reg) ); // mvn dest_reg, dest_reg + } else if (val_single_shift(imm, &scale)) { cache_checkinstr(4); - cache_addw( MOV_IMM(dest_reg, imm >> 16) ); // mov dest_reg, #(imm >> 16) - cache_addw( LSL_IMM(dest_reg, dest_reg, 16) ); // lsl dest_reg, dest_reg, #16 - } else if ((imm & 0x00ffffff) == 0) { - cache_checkinstr(4); - cache_addw( MOV_IMM(dest_reg, imm >> 24) ); // mov dest_reg, #(imm >> 24) - cache_addw( LSL_IMM(dest_reg, dest_reg, 24) ); // lsl dest_reg, dest_reg, #24 + cache_addw( MOV_IMM(dest_reg, imm >> scale) ); // mov dest_reg, #(imm >> scale) + cache_addw( LSL_IMM(dest_reg, dest_reg, scale) ); // lsl dest_reg, dest_reg, #scale } else { Bit32u diff; cache_checkinstr(4); diff = imm - ((Bit32u)cache.pos+4); - + if ((diff < 1024) && ((imm & 0x03) == 0)) { if (((Bit32u)cache.pos & 0x03) == 0) { cache_addw( ADD_LO_PC_IMM(dest_reg, diff >> 2) ); // add dest_reg, pc, #(diff >> 2) @@ -321,10 +364,61 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { } } +// helper function +static bool gen_mov_memval_to_reg_helper(HostReg dest_reg, Bit32u data, Bitu size, HostReg addr_reg, Bit32u addr_data) { + switch (size) { + case 4: +#if !defined(C_UNALIGNED_MEMORY) + if ((data & 3) == 0) +#endif + { + if ((data >= addr_data) && (data < addr_data + 128) && (((data - addr_data) & 3) == 0)) { + cache_checkinstr(4); + cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg + cache_addw( LDR_IMM(dest_reg, templo2, data - addr_data) ); // ldr dest_reg, [templo2, #(data - addr_data)] + return true; + } + } + break; + case 2: +#if !defined(C_UNALIGNED_MEMORY) + if ((data & 1) == 0) +#endif + { + if ((data >= addr_data) && (data < addr_data + 64) && (((data - addr_data) & 1) == 0)) { + cache_checkinstr(4); + cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg + cache_addw( LDRH_IMM(dest_reg, templo2, data - addr_data) ); // ldrh dest_reg, [templo2, #(data - addr_data)] + return true; + } + } + break; + case 1: + if ((data >= addr_data) && (data < addr_data + 32)) { + cache_checkinstr(4); + cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg + cache_addw( LDRB_IMM(dest_reg, templo2, data - addr_data) ); // ldrb dest_reg, [templo2, #(data - addr_data)] + return true; + } + default: + break; + } + return false; +} + +// helper function +static bool gen_mov_memval_to_reg(HostReg dest_reg, void *data, Bitu size) { + if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, FC_REGS_ADDR, (Bit32u)&cpu_regs)) return true; + if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, readdata_addr, (Bit32u)&core_dynrec.readdata)) return true; + if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, FC_SEGS_ADDR, (Bit32u)&Segs)) return true; + return false; +} + // helper function for gen_mov_word_to_reg static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,HostReg data_reg) { // alignment.... if (dword) { +#if !defined(C_UNALIGNED_MEMORY) if ((Bit32u)data & 3) { if ( ((Bit32u)data & 3) == 2 ) { cache_checkinstr(8); @@ -343,18 +437,23 @@ static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,Ho cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 } - } else { + } else +#endif + { cache_checkinstr(2); cache_addw( LDR_IMM(dest_reg, data_reg, 0) ); // ldr dest_reg, [data_reg] } } else { +#if !defined(C_UNALIGNED_MEMORY) if ((Bit32u)data & 1) { cache_checkinstr(8); cache_addw( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] cache_addw( LDRB_IMM(templo1, data_reg, 1) ); // ldrb templo1, [data_reg, #1] cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 - } else { + } else +#endif + { cache_checkinstr(2); cache_addw( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] } @@ -364,8 +463,10 @@ static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,Ho // move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { - gen_mov_dword_to_reg_imm(templo2, (Bit32u)data); - gen_mov_word_to_reg_helper(dest_reg, data, dword, templo2); + if (!gen_mov_memval_to_reg(dest_reg, data, (dword)?4:2)) { + gen_mov_dword_to_reg_imm(templo2, (Bit32u)data); + gen_mov_word_to_reg_helper(dest_reg, data, dword, templo2); + } } // move a 16bit constant value into dest_reg @@ -374,10 +475,61 @@ static void INLINE gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { gen_mov_dword_to_reg_imm(dest_reg, (Bit32u)imm); } +// helper function +static bool gen_mov_memval_from_reg_helper(HostReg src_reg, Bit32u data, Bitu size, HostReg addr_reg, Bit32u addr_data) { + switch (size) { + case 4: +#if !defined(C_UNALIGNED_MEMORY) + if ((data & 3) == 0) +#endif + { + if ((data >= addr_data) && (data < addr_data + 128) && (((data - addr_data) & 3) == 0)) { + cache_checkinstr(4); + cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg + cache_addw( STR_IMM(src_reg, templo2, data - addr_data) ); // str src_reg, [templo2, #(data - addr_data)] + return true; + } + } + break; + case 2: +#if !defined(C_UNALIGNED_MEMORY) + if ((data & 1) == 0) +#endif + { + if ((data >= addr_data) && (data < addr_data + 64) && (((data - addr_data) & 1) == 0)) { + cache_checkinstr(4); + cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg + cache_addw( STRH_IMM(src_reg, templo2, data - addr_data) ); // strh src_reg, [templo2, #(data - addr_data)] + return true; + } + } + break; + case 1: + if ((data >= addr_data) && (data < addr_data + 32)) { + cache_checkinstr(4); + cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg + cache_addw( STRB_IMM(src_reg, templo2, data - addr_data) ); // strb src_reg, [templo2, #(data - addr_data)] + return true; + } + default: + break; + } + return false; +} + +// helper function +static bool gen_mov_memval_from_reg(HostReg src_reg, void *dest, Bitu size) { + if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, FC_REGS_ADDR, (Bit32u)&cpu_regs)) return true; + if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, readdata_addr, (Bit32u)&core_dynrec.readdata)) return true; + if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, FC_SEGS_ADDR, (Bit32u)&Segs)) return true; + return false; +} + // helper function for gen_mov_word_from_reg static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, HostReg data_reg) { // alignment.... if (dword) { +#if !defined(C_UNALIGNED_MEMORY) if ((Bit32u)dest & 3) { if ( ((Bit32u)dest & 3) == 2 ) { cache_checkinstr(8); @@ -398,18 +550,23 @@ static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, cache_addw( LSR_IMM(templo1, templo1, 24) ); // lsr templo1, templo1, #24 cache_addw( STRB_IMM(templo1, data_reg, 3) ); // strb templo1, [data_reg, #3] } - } else { + } else +#endif + { cache_checkinstr(2); cache_addw( STR_IMM(src_reg, data_reg, 0) ); // str src_reg, [data_reg] } } else { +#if !defined(C_UNALIGNED_MEMORY) if ((Bit32u)dest & 1) { cache_checkinstr(8); cache_addw( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg cache_addw( LSR_IMM(templo1, templo1, 8) ); // lsr templo1, templo1, #8 cache_addw( STRB_IMM(templo1, data_reg, 1) ); // strb templo1, [data_reg, #1] - } else { + } else +#endif + { cache_checkinstr(2); cache_addw( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] } @@ -418,8 +575,10 @@ static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, // move 32bit (dword==true) or 16bit (dword==false) of a register into memory static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_from_reg_helper(src_reg, dest, dword, templo2); + if (!gen_mov_memval_from_reg(src_reg, dest, (dword)?4:2)) { + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_from_reg_helper(src_reg, dest, dword, templo2); + } } // move an 8bit value from memory into dest_reg @@ -427,9 +586,11 @@ static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { // this function does not use FC_OP1/FC_OP2 as dest_reg as these // registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { - gen_mov_dword_to_reg_imm(templo1, (Bit32u)data); - cache_checkinstr(2); - cache_addw( LDRB_IMM(dest_reg, templo1, 0) ); // ldrb dest_reg, [templo1] + if (!gen_mov_memval_to_reg(dest_reg, data, 1)) { + gen_mov_dword_to_reg_imm(templo1, (Bit32u)data); + cache_checkinstr(2); + cache_addw( LDRB_IMM(dest_reg, templo1, 0) ); // ldrb dest_reg, [templo1] + } } // move an 8bit value from memory into dest_reg @@ -459,9 +620,11 @@ static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u // move the lowest 8bit of a register into memory static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { - gen_mov_dword_to_reg_imm(templo1, (Bit32u)dest); - cache_checkinstr(2); - cache_addw( STRB_IMM(src_reg, templo1, 0) ); // strb src_reg, [templo1] + if (!gen_mov_memval_from_reg(src_reg, dest, 1)) { + gen_mov_dword_to_reg_imm(templo1, (Bit32u)dest); + cache_checkinstr(2); + cache_addw( STRB_IMM(src_reg, templo1, 0) ); // strb src_reg, [templo1] + } } @@ -501,18 +664,58 @@ static void gen_add(HostReg reg,void* op) { // add a 32bit constant value to a full register static void gen_add_imm(HostReg reg,Bit32u imm) { + Bit32u imm2, scale; + if(!imm) return; - gen_mov_dword_to_reg_imm(templo1, imm); - cache_checkinstr(2); - cache_addw( ADD_REG(reg, reg, templo1) ); // add reg, reg, templo1 + + imm2 = (Bit32u) (-((Bit32s)imm)); + + if (imm <= 255) { + cache_checkinstr(2); + cache_addw( ADD_IMM8(reg, imm) ); // add reg, #imm + } else if (imm2 <= 255) { + cache_checkinstr(2); + cache_addw( SUB_IMM8(reg, imm2) ); // sub reg, #(-imm) + } else { + if (val_single_shift(imm2, &scale)) { + cache_checkinstr((scale)?6:4); + cache_addw( MOV_IMM(templo1, imm2 >> scale) ); // mov templo1, #(~imm >> scale) + if (scale) { + cache_addw( LSL_IMM(templo1, templo1, scale) ); // lsl templo1, templo1, #scale + } + cache_addw( SUB_REG(reg, reg, templo1) ); // sub reg, reg, templo1 + } else { + gen_mov_dword_to_reg_imm(templo1, imm); + cache_checkinstr(2); + cache_addw( ADD_REG(reg, reg, templo1) ); // add reg, reg, templo1 + } + } } // and a 32bit constant value with a full register static void gen_and_imm(HostReg reg,Bit32u imm) { - if(imm == 0xffffffff) return; - gen_mov_dword_to_reg_imm(templo1, imm); - cache_checkinstr(2); - cache_addw( AND(reg, templo1) ); // and reg, templo1 + Bit32u imm2, scale; + + imm2 = ~imm; + if(!imm2) return; + + if (!imm) { + cache_checkinstr(2); + cache_addw( MOV_IMM(reg, 0) ); // mov reg, #0 + } else { + if (val_single_shift(imm2, &scale)) { + cache_checkinstr((scale)?6:4); + cache_addw( MOV_IMM(templo1, imm2 >> scale) ); // mov templo1, #(~imm >> scale) + if (scale) { + cache_addw( LSL_IMM(templo1, templo1, scale) ); // lsl templo1, templo1, #scale + } + cache_addw( BIC(reg, templo1) ); // bic reg, templo1 + } else { + gen_mov_dword_to_reg_imm(templo1, imm); + cache_checkinstr(2); + cache_addw( AND(reg, templo1) ); // and reg, templo1 + } + } } @@ -527,70 +730,69 @@ static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { gen_mov_direct_dword(dest,(Bit32u)imm); } -// add an 8bit constant value to a dword memory value -static void gen_add_direct_byte(void* dest,Bit8s imm) { - if(!imm) return; - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templo3, dest, 1, templo2); - cache_checkinstr(2); - if (imm >= 0) { - cache_addw( ADD_IMM8(templo3, (Bit32s)imm) ); // add templo3, #(imm) - } else { - cache_addw( SUB_IMM8(templo3, -((Bit32s)imm)) ); // sub templo3, #(-imm) - } - gen_mov_word_from_reg_helper(templo3, dest, 1, templo2); -} - // add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { + if (!dword) imm &= 0xffff; if(!imm) return; - if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { - gen_add_direct_byte(dest,(Bit8s)imm); - return; + + if (!gen_mov_memval_to_reg(templo3, dest, (dword)?4:2)) { + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); } - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); - if (dword) { - gen_mov_dword_to_reg_imm(templo1, imm); - } else { - gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); + gen_add_imm(templo3, imm); + if (!gen_mov_memval_from_reg(templo3, dest, (dword)?4:2)) { + gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); } - cache_checkinstr(2); - cache_addw( ADD_REG(templo3, templo3, templo1) ); // add templo3, templo3, templo1 - gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); } -// subtract an 8bit constant value from a dword memory value -static void gen_sub_direct_byte(void* dest,Bit8s imm) { - if(!imm) return; - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templo3, dest, 1, templo2); - cache_checkinstr(2); - if (imm >= 0) { - cache_addw( SUB_IMM8(templo3, (Bit32s)imm) ); // sub templo3, #(imm) - } else { - cache_addw( ADD_IMM8(templo3, -((Bit32s)imm)) ); // add templo3, #(-imm) - } - gen_mov_word_from_reg_helper(templo3, dest, 1, templo2); +// add an 8bit constant value to a dword memory value +static void gen_add_direct_byte(void* dest,Bit8s imm) { + gen_add_direct_word(dest, (Bit32s)imm, 1); } // subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { + Bit32u imm2, scale; + + if (!dword) imm &= 0xffff; if(!imm) return; - if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { - gen_sub_direct_byte(dest,(Bit8s)imm); - return; + + if (!gen_mov_memval_to_reg(templo3, dest, (dword)?4:2)) { + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); } - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); - if (dword) { - gen_mov_dword_to_reg_imm(templo1, imm); + + imm2 = (Bit32u) (-((Bit32s)imm)); + + if (imm <= 255) { + cache_checkinstr(2); + cache_addw( SUB_IMM8(templo3, imm) ); // sub templo3, #imm + } else if (imm2 <= 255) { + cache_checkinstr(2); + cache_addw( ADD_IMM8(templo3, imm2) ); // add templo3, #(-imm) } else { - gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); + if (val_single_shift(imm2, &scale)) { + cache_checkinstr((scale)?6:4); + cache_addw( MOV_IMM(templo1, imm2 >> scale) ); // mov templo1, #(~imm >> scale) + if (scale) { + cache_addw( LSL_IMM(templo1, templo1, scale) ); // lsl templo1, templo1, #scale + } + cache_addw( ADD_REG(templo3, templo3, templo1) ); // add templo3, templo3, templo1 + } else { + gen_mov_dword_to_reg_imm(templo1, imm); + cache_checkinstr(2); + cache_addw( SUB_REG(templo3, templo3, templo1) ); // sub templo3, templo3, templo1 + } } - cache_checkinstr(2); - cache_addw( SUB_REG(templo3, templo3, templo1) ); // sub templo3, templo3, templo1 - gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); + + if (!gen_mov_memval_from_reg(templo3, dest, (dword)?4:2)) { + gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); + } +} + +// subtract an 8bit constant value from a dword memory value +static void gen_sub_direct_byte(void* dest,Bit8s imm) { + gen_sub_direct_word(dest, (Bit32s)imm, 1); } // effective address calculation, destination is dest_reg @@ -694,20 +896,22 @@ static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { static void gen_jmp_ptr(void * ptr,Bits imm=0) { gen_mov_word_to_reg(templo3, ptr, 1); - if (imm) { - gen_mov_dword_to_reg_imm(templo2, imm); - cache_checkinstr(2); - cache_addw( ADD_REG(templo3, templo3, templo2) ); // add templo3, templo3, templo2 - } - -#if (1) -// (*ptr) should be word aligned +#if !defined(C_UNALIGNED_MEMORY) +// (*ptr) should be word aligned if ((imm & 0x03) == 0) { - cache_checkinstr(6); - cache_addw( LDR_IMM(templo2, templo3, 0) ); // ldr templo2, [templo3] - } else #endif - { + if ((imm >= 0) && (imm < 128) && ((imm & 3) == 0)) { + cache_checkinstr(6); + cache_addw( LDR_IMM(templo2, templo3, imm) ); // ldr templo2, [templo3, #imm] + } else { + gen_mov_dword_to_reg_imm(templo2, imm); + cache_checkinstr(6); + cache_addw( LDR_REG(templo2, templo3, templo2) ); // ldr templo2, [templo3, templo2] + } +#if !defined(C_UNALIGNED_MEMORY) + } else { + gen_add_imm(templo3, imm); + cache_checkinstr(24); cache_addw( LDRB_IMM(templo2, templo3, 0) ); // ldrb templo2, [templo3] cache_addw( LDRB_IMM(templo1, templo3, 1) ); // ldrb templo1, [templo3, #1] @@ -720,6 +924,7 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 } +#endif // increase jmp address to keep thumb state cache_addw( ADD_IMM3(templo2, templo2, 1) ); // add templo2, templo2, #1 @@ -815,50 +1020,53 @@ static void INLINE gen_fill_branch_long(Bit32u data) { } static void gen_run_code(void) { - // switch from arm to thumb state - cache_addd(0xe2800000 + (HOST_r3 << 12) + (HOST_pc << 16) + (1)); // add r3, pc, #1 - cache_addd(0xe12fff10 + (HOST_r3)); // bx r3 + Bit8u *pos1, *pos2, *pos3; - // thumb state from now on - cache_addw(0xb500); // push {lr} - cache_addw( MOV_LO_HI(HOST_r3, FC_SEGS_ADDR) ); // mov r3, FC_SEGS_ADDR - cache_addw( MOV_LO_HI(HOST_r2, FC_REGS_ADDR) ); // mov r2, FC_REGS_ADDR - cache_addw(0xb4fc); // push {r2,r3,v1-v4} +#if (__ARM_EABI__) + // 8-byte stack alignment + cache_addd(0xe92d4ff0); // stmfd sp!, {v1-v8,lr} +#else + cache_addd(0xe92d4df0); // stmfd sp!, {v1-v5,v7,v8,lr} +#endif - // adr: 16 - cache_addw( LDR_PC_IMM(HOST_r3, 64 - (16 + 4)) ); // ldr r3, [pc, #(&Segs)] - // adr: 18 - cache_addw( LDR_PC_IMM(HOST_r2, 68 - (18 + 2)) ); // ldr r2, [pc, #(&cpu_regs)] - cache_addw( MOV_HI_LO(FC_SEGS_ADDR, HOST_r3) ); // mov FC_SEGS_ADDR, r3 - cache_addw( MOV_HI_LO(FC_REGS_ADDR, HOST_r2) ); // mov FC_REGS_ADDR, r2 + cache_addd( ARM_ADD_IMM(HOST_r0, HOST_r0, 1, 0) ); // add r0, r0, #1 - // align 4 - cache_addw( ADD_LO_PC_IMM(HOST_r3, 8) ); // add r3, pc, #8 - cache_addw( ADD_IMM8(HOST_r0, 1) ); // add r0, #1 - cache_addw( ADD_IMM8(HOST_r3, 1) ); // add r3, #1 - cache_addw(0xb408); // push {r3} - cache_addw( BX(HOST_r0) ); // bx r0 - cache_addw( NOP ); // nop + pos1 = cache.pos; + cache_addd( 0 ); + pos2 = cache.pos; + cache_addd( 0 ); + pos3 = cache.pos; + cache_addd( 0 ); - // align 4 - cache_addw(0xbcfc); // pop {r2,r3,v1-v4} - cache_addw( MOV_HI_LO(FC_SEGS_ADDR, HOST_r3) ); // mov FC_SEGS_ADDR, r3 - cache_addw( MOV_HI_LO(FC_REGS_ADDR, HOST_r2) ); // mov FC_REGS_ADDR, r2 + cache_addd( ARM_ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 + cache_addd( ARM_STR_IMM_M_W(HOST_lr, HOST_sp, 4) ); // str lr, [sp, #-4]! + cache_addd( ARM_BX(HOST_r0) ); // bx r0 - cache_addw(0xbc08); // pop {r3} - cache_addw( BX(HOST_r3) ); // bx r3 +#if (__ARM_EABI__) + cache_addd(0xe8bd4ff0); // ldmfd sp!, {v1-v8,lr} +#else + cache_addd(0xe8bd4df0); // ldmfd sp!, {v1-v5,v7,v8,lr} +#endif + cache_addd( ARM_BX(HOST_lr) ); // bx lr - // fill up to 64 bytes - cache_addw( NOP ); // nop - cache_addd( NOP | (NOP << 16) ); // nop, nop - cache_addd( NOP | (NOP << 16) ); // nop, nop - cache_addd( NOP | (NOP << 16) ); // nop, nop - cache_addd( NOP | (NOP << 16) ); // nop, nop + // align cache.pos to 32 bytes + if ((((Bitu)cache.pos) & 0x1f) != 0) { + cache.pos = cache.pos + (32 - (((Bitu)cache.pos) & 0x1f)); + } - // adr: 64 + *(Bit32u*)pos1 = ARM_LDR_IMM(FC_SEGS_ADDR, HOST_pc, cache.pos - (pos1 + 8)); // ldr FC_SEGS_ADDR, [pc, #(&Segs)] cache_addd((Bit32u)&Segs); // address of "Segs" - // adr: 68 + + *(Bit32u*)pos2 = ARM_LDR_IMM(FC_REGS_ADDR, HOST_pc, cache.pos - (pos2 + 8)); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)] cache_addd((Bit32u)&cpu_regs); // address of "cpu_regs" + + *(Bit32u*)pos3 = ARM_LDR_IMM(readdata_addr, HOST_pc, cache.pos - (pos3 + 8)); // ldr readdata_addr, [pc, #(&core_dynrec.readdata)] + cache_addd((Bit32u)&core_dynrec.readdata); // address of "core_dynrec.readdata" + + // align cache.pos to 32 bytes + if ((((Bitu)cache.pos) & 0x1f) != 0) { + cache.pos = cache.pos + (32 - (((Bitu)cache.pos) & 0x1f)); + } } // return from a function diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h index 2f49865c..2a6b24be 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h @@ -50,15 +50,14 @@ // temporary register for LEA #define TEMP_REG_DRC HOST_a4 -#ifdef DRC_USE_REGS_ADDR // used to hold the address of "cpu_regs" - preferably filled in function gen_run_code #define FC_REGS_ADDR HOST_v7 -#endif -#ifdef DRC_USE_SEGS_ADDR // used to hold the address of "Segs" - preferably filled in function gen_run_code #define FC_SEGS_ADDR HOST_v8 -#endif + +// used to hold the address of "core_dynrec.readdata" - filled in function gen_run_code +#define readdata_addr HOST_v5 // instruction encodings @@ -98,10 +97,14 @@ // logical // and dst, src #define AND(dst, src) (0x4000 + (dst) + ((src) << 3) ) +// bic dst, src +#define BIC(dst, src) (0x4380 + (dst) + ((src) << 3) ) // eor dst, src #define EOR(dst, src) (0x4040 + (dst) + ((src) << 3) ) // orr dst, src #define ORR(dst, src) (0x4300 + (dst) + ((src) << 3) ) +// mvn dst, src +#define MVN(dst, src) (0x43c0 + (dst) + ((src) << 3) ) // shift/rotate // lsl dst, src, #imm @@ -128,6 +131,8 @@ #define LDRB_IMM(reg, addr, imm) (0x7800 + (reg) + ((addr) << 3) + ((imm) << 6) ) // ldr reg, [pc, #imm] @ 0 <= imm < 1024 & imm mod 4 = 0 #define LDR_PC_IMM(reg, imm) (0x4800 + ((reg) << 8) + ((imm) >> 2) ) +// ldr reg, [addr1, addr2] +#define LDR_REG(reg, addr1, addr2) (0x5800 + (reg) + ((addr1) << 3) + ((addr2) << 6) ) // store // str reg, [addr, #imm] @ 0 <= imm < 128 & imm mod 4 = 0 @@ -150,6 +155,25 @@ #define BX(reg) (0x4700 + ((reg) << 3) ) +// arm instructions + +// arithmetic +// add dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define ARM_ADD_IMM(dst, src, imm, rimm) (0xe2800000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) + +// load +// ldr reg, [addr, #imm] @ 0 <= imm < 4096 +#define ARM_LDR_IMM(reg, addr, imm) (0xe5900000 + ((reg) << 12) + ((addr) << 16) + (imm) ) + +// store +// str reg, [addr, #-(imm)]! @ 0 <= imm < 4096 +#define ARM_STR_IMM_M_W(reg, addr, imm) (0xe5200000 + ((reg) << 12) + ((addr) << 16) + (imm) ) + +// branch +// bx reg +#define ARM_BX(reg) (0xe12fff10 + (reg) ) + + // data pool defines #define CACHE_DATA_JUMP (2) #define CACHE_DATA_ALIGN (32) @@ -193,7 +217,7 @@ static void cache_checkinstr(Bit32u size) { cache_datapos = (Bit8u *) (((Bitu)cache.block.active->cache.start + cache.block.active->cache.size - CACHE_DATA_ALIGN) & ~(CACHE_DATA_ALIGN - 1)); } else { register Bit32u cachemodsize; - + cachemodsize = (cache.pos - cache.block.active->cache.start) & (CACHE_MAXSIZE - 1); if (cachemodsize + CACHE_DATA_MAX + CACHE_DATA_ALIGN <= CACHE_MAXSIZE || @@ -275,30 +299,49 @@ static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { cache_addw( MOV_REG(reg_dst, reg_src) ); // mov reg_dst, reg_src } +// helper function +static bool val_single_shift(Bit32u value, Bit32u *val_shift) { + Bit32u shift; + + if (GCC_UNLIKELY(value == 0)) { + *val_shift = 0; + return true; + } + + shift = 0; + while ((value & 1) == 0) { + value>>=1; + shift+=1; + } + + if ((value >> 8) != 0) return false; + + *val_shift = shift; + return true; +} + // move a 32bit constant value into dest_reg static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { - if ((imm & 0xffffff00) == 0) { + Bit32u scale; + + if (imm < 256) { cache_checkinstr(2); cache_addw( MOV_IMM(dest_reg, imm) ); // mov dest_reg, #(imm) - } else if ((imm & 0xffff00ff) == 0) { + } else if ((~imm) < 256) { cache_checkinstr(4); - cache_addw( MOV_IMM(dest_reg, imm >> 8) ); // mov dest_reg, #(imm >> 8) - cache_addw( LSL_IMM(dest_reg, dest_reg, 8) ); // lsl dest_reg, dest_reg, #8 - } else if ((imm & 0xff00ffff) == 0) { + cache_addw( MOV_IMM(dest_reg, ~imm) ); // mov dest_reg, #(~imm) + cache_addw( MVN(dest_reg, dest_reg) ); // mvn dest_reg, dest_reg + } else if (val_single_shift(imm, &scale)) { cache_checkinstr(4); - cache_addw( MOV_IMM(dest_reg, imm >> 16) ); // mov dest_reg, #(imm >> 16) - cache_addw( LSL_IMM(dest_reg, dest_reg, 16) ); // lsl dest_reg, dest_reg, #16 - } else if ((imm & 0x00ffffff) == 0) { - cache_checkinstr(4); - cache_addw( MOV_IMM(dest_reg, imm >> 24) ); // mov dest_reg, #(imm >> 24) - cache_addw( LSL_IMM(dest_reg, dest_reg, 24) ); // lsl dest_reg, dest_reg, #24 + cache_addw( MOV_IMM(dest_reg, imm >> scale) ); // mov dest_reg, #(imm >> scale) + cache_addw( LSL_IMM(dest_reg, dest_reg, scale) ); // lsl dest_reg, dest_reg, #scale } else { Bit32u diff; cache_checkinstr(4); diff = imm - ((Bit32u)cache.pos+4); - + if ((diff < 1024) && ((imm & 0x03) == 0)) { if (((Bit32u)cache.pos & 0x03) == 0) { cache_addw( ADD_LO_PC_IMM(dest_reg, diff >> 2) ); // add dest_reg, pc, #(diff >> 2) @@ -321,10 +364,61 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { } } +// helper function +static bool gen_mov_memval_to_reg_helper(HostReg dest_reg, Bit32u data, Bitu size, HostReg addr_reg, Bit32u addr_data) { + switch (size) { + case 4: +#if !defined(C_UNALIGNED_MEMORY) + if ((data & 3) == 0) +#endif + { + if ((data >= addr_data) && (data < addr_data + 128) && (((data - addr_data) & 3) == 0)) { + cache_checkinstr(4); + cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg + cache_addw( LDR_IMM(dest_reg, templo2, data - addr_data) ); // ldr dest_reg, [templo2, #(data - addr_data)] + return true; + } + } + break; + case 2: +#if !defined(C_UNALIGNED_MEMORY) + if ((data & 1) == 0) +#endif + { + if ((data >= addr_data) && (data < addr_data + 64) && (((data - addr_data) & 1) == 0)) { + cache_checkinstr(4); + cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg + cache_addw( LDRH_IMM(dest_reg, templo2, data - addr_data) ); // ldrh dest_reg, [templo2, #(data - addr_data)] + return true; + } + } + break; + case 1: + if ((data >= addr_data) && (data < addr_data + 32)) { + cache_checkinstr(4); + cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg + cache_addw( LDRB_IMM(dest_reg, templo2, data - addr_data) ); // ldrb dest_reg, [templo2, #(data - addr_data)] + return true; + } + default: + break; + } + return false; +} + +// helper function +static bool gen_mov_memval_to_reg(HostReg dest_reg, void *data, Bitu size) { + if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, FC_REGS_ADDR, (Bit32u)&cpu_regs)) return true; + if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, readdata_addr, (Bit32u)&core_dynrec.readdata)) return true; + if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, FC_SEGS_ADDR, (Bit32u)&Segs)) return true; + return false; +} + // helper function for gen_mov_word_to_reg static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,HostReg data_reg) { // alignment.... if (dword) { +#if !defined(C_UNALIGNED_MEMORY) if ((Bit32u)data & 3) { if ( ((Bit32u)data & 3) == 2 ) { cache_checkinstr(8); @@ -343,18 +437,23 @@ static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,Ho cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 } - } else { + } else +#endif + { cache_checkinstr(2); cache_addw( LDR_IMM(dest_reg, data_reg, 0) ); // ldr dest_reg, [data_reg] } } else { +#if !defined(C_UNALIGNED_MEMORY) if ((Bit32u)data & 1) { cache_checkinstr(8); cache_addw( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] cache_addw( LDRB_IMM(templo1, data_reg, 1) ); // ldrb templo1, [data_reg, #1] cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 - } else { + } else +#endif + { cache_checkinstr(2); cache_addw( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] } @@ -364,8 +463,10 @@ static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,Ho // move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { - gen_mov_dword_to_reg_imm(templo2, (Bit32u)data); - gen_mov_word_to_reg_helper(dest_reg, data, dword, templo2); + if (!gen_mov_memval_to_reg(dest_reg, data, (dword)?4:2)) { + gen_mov_dword_to_reg_imm(templo2, (Bit32u)data); + gen_mov_word_to_reg_helper(dest_reg, data, dword, templo2); + } } // move a 16bit constant value into dest_reg @@ -374,10 +475,61 @@ static void INLINE gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { gen_mov_dword_to_reg_imm(dest_reg, (Bit32u)imm); } +// helper function +static bool gen_mov_memval_from_reg_helper(HostReg src_reg, Bit32u data, Bitu size, HostReg addr_reg, Bit32u addr_data) { + switch (size) { + case 4: +#if !defined(C_UNALIGNED_MEMORY) + if ((data & 3) == 0) +#endif + { + if ((data >= addr_data) && (data < addr_data + 128) && (((data - addr_data) & 3) == 0)) { + cache_checkinstr(4); + cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg + cache_addw( STR_IMM(src_reg, templo2, data - addr_data) ); // str src_reg, [templo2, #(data - addr_data)] + return true; + } + } + break; + case 2: +#if !defined(C_UNALIGNED_MEMORY) + if ((data & 1) == 0) +#endif + { + if ((data >= addr_data) && (data < addr_data + 64) && (((data - addr_data) & 1) == 0)) { + cache_checkinstr(4); + cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg + cache_addw( STRH_IMM(src_reg, templo2, data - addr_data) ); // strh src_reg, [templo2, #(data - addr_data)] + return true; + } + } + break; + case 1: + if ((data >= addr_data) && (data < addr_data + 32)) { + cache_checkinstr(4); + cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg + cache_addw( STRB_IMM(src_reg, templo2, data - addr_data) ); // strb src_reg, [templo2, #(data - addr_data)] + return true; + } + default: + break; + } + return false; +} + +// helper function +static bool gen_mov_memval_from_reg(HostReg src_reg, void *dest, Bitu size) { + if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, FC_REGS_ADDR, (Bit32u)&cpu_regs)) return true; + if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, readdata_addr, (Bit32u)&core_dynrec.readdata)) return true; + if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, FC_SEGS_ADDR, (Bit32u)&Segs)) return true; + return false; +} + // helper function for gen_mov_word_from_reg static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, HostReg data_reg) { // alignment.... if (dword) { +#if !defined(C_UNALIGNED_MEMORY) if ((Bit32u)dest & 3) { if ( ((Bit32u)dest & 3) == 2 ) { cache_checkinstr(8); @@ -398,18 +550,23 @@ static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, cache_addw( LSR_IMM(templo1, templo1, 24) ); // lsr templo1, templo1, #24 cache_addw( STRB_IMM(templo1, data_reg, 3) ); // strb templo1, [data_reg, #3] } - } else { + } else +#endif + { cache_checkinstr(2); cache_addw( STR_IMM(src_reg, data_reg, 0) ); // str src_reg, [data_reg] } } else { +#if !defined(C_UNALIGNED_MEMORY) if ((Bit32u)dest & 1) { cache_checkinstr(8); cache_addw( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg cache_addw( LSR_IMM(templo1, templo1, 8) ); // lsr templo1, templo1, #8 cache_addw( STRB_IMM(templo1, data_reg, 1) ); // strb templo1, [data_reg, #1] - } else { + } else +#endif + { cache_checkinstr(2); cache_addw( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] } @@ -418,8 +575,10 @@ static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, // move 32bit (dword==true) or 16bit (dword==false) of a register into memory static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_from_reg_helper(src_reg, dest, dword, templo2); + if (!gen_mov_memval_from_reg(src_reg, dest, (dword)?4:2)) { + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_from_reg_helper(src_reg, dest, dword, templo2); + } } // move an 8bit value from memory into dest_reg @@ -427,9 +586,11 @@ static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { // this function does not use FC_OP1/FC_OP2 as dest_reg as these // registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { - gen_mov_dword_to_reg_imm(templo1, (Bit32u)data); - cache_checkinstr(2); - cache_addw( LDRB_IMM(dest_reg, templo1, 0) ); // ldrb dest_reg, [templo1] + if (!gen_mov_memval_to_reg(dest_reg, data, 1)) { + gen_mov_dword_to_reg_imm(templo1, (Bit32u)data); + cache_checkinstr(2); + cache_addw( LDRB_IMM(dest_reg, templo1, 0) ); // ldrb dest_reg, [templo1] + } } // move an 8bit value from memory into dest_reg @@ -459,9 +620,11 @@ static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u // move the lowest 8bit of a register into memory static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { - gen_mov_dword_to_reg_imm(templo1, (Bit32u)dest); - cache_checkinstr(2); - cache_addw( STRB_IMM(src_reg, templo1, 0) ); // strb src_reg, [templo1] + if (!gen_mov_memval_from_reg(src_reg, dest, 1)) { + gen_mov_dword_to_reg_imm(templo1, (Bit32u)dest); + cache_checkinstr(2); + cache_addw( STRB_IMM(src_reg, templo1, 0) ); // strb src_reg, [templo1] + } } @@ -501,18 +664,58 @@ static void gen_add(HostReg reg,void* op) { // add a 32bit constant value to a full register static void gen_add_imm(HostReg reg,Bit32u imm) { + Bit32u imm2, scale; + if(!imm) return; - gen_mov_dword_to_reg_imm(templo1, imm); - cache_checkinstr(2); - cache_addw( ADD_REG(reg, reg, templo1) ); // add reg, reg, templo1 + + imm2 = (Bit32u) (-((Bit32s)imm)); + + if (imm <= 255) { + cache_checkinstr(2); + cache_addw( ADD_IMM8(reg, imm) ); // add reg, #imm + } else if (imm2 <= 255) { + cache_checkinstr(2); + cache_addw( SUB_IMM8(reg, imm2) ); // sub reg, #(-imm) + } else { + if (val_single_shift(imm2, &scale)) { + cache_checkinstr((scale)?6:4); + cache_addw( MOV_IMM(templo1, imm2 >> scale) ); // mov templo1, #(~imm >> scale) + if (scale) { + cache_addw( LSL_IMM(templo1, templo1, scale) ); // lsl templo1, templo1, #scale + } + cache_addw( SUB_REG(reg, reg, templo1) ); // sub reg, reg, templo1 + } else { + gen_mov_dword_to_reg_imm(templo1, imm); + cache_checkinstr(2); + cache_addw( ADD_REG(reg, reg, templo1) ); // add reg, reg, templo1 + } + } } // and a 32bit constant value with a full register static void gen_and_imm(HostReg reg,Bit32u imm) { - if(imm == 0xffffffff) return; - gen_mov_dword_to_reg_imm(templo1, imm); - cache_checkinstr(2); - cache_addw( AND(reg, templo1) ); // and reg, templo1 + Bit32u imm2, scale; + + imm2 = ~imm; + if(!imm2) return; + + if (!imm) { + cache_checkinstr(2); + cache_addw( MOV_IMM(reg, 0) ); // mov reg, #0 + } else { + if (val_single_shift(imm2, &scale)) { + cache_checkinstr((scale)?6:4); + cache_addw( MOV_IMM(templo1, imm2 >> scale) ); // mov templo1, #(~imm >> scale) + if (scale) { + cache_addw( LSL_IMM(templo1, templo1, scale) ); // lsl templo1, templo1, #scale + } + cache_addw( BIC(reg, templo1) ); // bic reg, templo1 + } else { + gen_mov_dword_to_reg_imm(templo1, imm); + cache_checkinstr(2); + cache_addw( AND(reg, templo1) ); // and reg, templo1 + } + } } @@ -527,70 +730,69 @@ static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { gen_mov_direct_dword(dest,(Bit32u)imm); } -// add an 8bit constant value to a dword memory value -static void gen_add_direct_byte(void* dest,Bit8s imm) { - if(!imm) return; - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templo3, dest, 1, templo2); - cache_checkinstr(2); - if (imm >= 0) { - cache_addw( ADD_IMM8(templo3, (Bit32s)imm) ); // add templo3, #(imm) - } else { - cache_addw( SUB_IMM8(templo3, -((Bit32s)imm)) ); // sub templo3, #(-imm) - } - gen_mov_word_from_reg_helper(templo3, dest, 1, templo2); -} - // add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { + if (!dword) imm &= 0xffff; if(!imm) return; - if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { - gen_add_direct_byte(dest,(Bit8s)imm); - return; + + if (!gen_mov_memval_to_reg(templo3, dest, (dword)?4:2)) { + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); } - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); - if (dword) { - gen_mov_dword_to_reg_imm(templo1, imm); - } else { - gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); + gen_add_imm(templo3, imm); + if (!gen_mov_memval_from_reg(templo3, dest, (dword)?4:2)) { + gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); } - cache_checkinstr(2); - cache_addw( ADD_REG(templo3, templo3, templo1) ); // add templo3, templo3, templo1 - gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); } -// subtract an 8bit constant value from a dword memory value -static void gen_sub_direct_byte(void* dest,Bit8s imm) { - if(!imm) return; - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templo3, dest, 1, templo2); - cache_checkinstr(2); - if (imm >= 0) { - cache_addw( SUB_IMM8(templo3, (Bit32s)imm) ); // sub templo3, #(imm) - } else { - cache_addw( ADD_IMM8(templo3, -((Bit32s)imm)) ); // add templo3, #(-imm) - } - gen_mov_word_from_reg_helper(templo3, dest, 1, templo2); +// add an 8bit constant value to a dword memory value +static void gen_add_direct_byte(void* dest,Bit8s imm) { + gen_add_direct_word(dest, (Bit32s)imm, 1); } // subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { + Bit32u imm2, scale; + + if (!dword) imm &= 0xffff; if(!imm) return; - if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { - gen_sub_direct_byte(dest,(Bit8s)imm); - return; + + if (!gen_mov_memval_to_reg(templo3, dest, (dword)?4:2)) { + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); } - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); - if (dword) { - gen_mov_dword_to_reg_imm(templo1, imm); + + imm2 = (Bit32u) (-((Bit32s)imm)); + + if (imm <= 255) { + cache_checkinstr(2); + cache_addw( SUB_IMM8(templo3, imm) ); // sub templo3, #imm + } else if (imm2 <= 255) { + cache_checkinstr(2); + cache_addw( ADD_IMM8(templo3, imm2) ); // add templo3, #(-imm) } else { - gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); + if (val_single_shift(imm2, &scale)) { + cache_checkinstr((scale)?6:4); + cache_addw( MOV_IMM(templo1, imm2 >> scale) ); // mov templo1, #(~imm >> scale) + if (scale) { + cache_addw( LSL_IMM(templo1, templo1, scale) ); // lsl templo1, templo1, #scale + } + cache_addw( ADD_REG(templo3, templo3, templo1) ); // add templo3, templo3, templo1 + } else { + gen_mov_dword_to_reg_imm(templo1, imm); + cache_checkinstr(2); + cache_addw( SUB_REG(templo3, templo3, templo1) ); // sub templo3, templo3, templo1 + } } - cache_checkinstr(2); - cache_addw( SUB_REG(templo3, templo3, templo1) ); // sub templo3, templo3, templo1 - gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); + + if (!gen_mov_memval_from_reg(templo3, dest, (dword)?4:2)) { + gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); + } +} + +// subtract an 8bit constant value from a dword memory value +static void gen_sub_direct_byte(void* dest,Bit8s imm) { + gen_sub_direct_word(dest, (Bit32s)imm, 1); } // effective address calculation, destination is dest_reg @@ -696,20 +898,22 @@ static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { static void gen_jmp_ptr(void * ptr,Bits imm=0) { gen_mov_word_to_reg(templo3, ptr, 1); - if (imm) { - gen_mov_dword_to_reg_imm(templo2, imm); - cache_checkinstr(2); - cache_addw( ADD_REG(templo3, templo3, templo2) ); // add templo3, templo3, templo2 - } - -#if (1) -// (*ptr) should be word aligned +#if !defined(C_UNALIGNED_MEMORY) +// (*ptr) should be word aligned if ((imm & 0x03) == 0) { - cache_checkinstr(6); - cache_addw( LDR_IMM(templo2, templo3, 0) ); // ldr templo2, [templo3] - } else #endif - { + if ((imm >= 0) && (imm < 128) && ((imm & 3) == 0)) { + cache_checkinstr(6); + cache_addw( LDR_IMM(templo2, templo3, imm) ); // ldr templo2, [templo3, #imm] + } else { + gen_mov_dword_to_reg_imm(templo2, imm); + cache_checkinstr(6); + cache_addw( LDR_REG(templo2, templo3, templo2) ); // ldr templo2, [templo3, templo2] + } +#if !defined(C_UNALIGNED_MEMORY) + } else { + gen_add_imm(templo3, imm); + cache_checkinstr(24); cache_addw( LDRB_IMM(templo2, templo3, 0) ); // ldrb templo2, [templo3] cache_addw( LDRB_IMM(templo1, templo3, 1) ); // ldrb templo1, [templo3, #1] @@ -722,6 +926,7 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 } +#endif // increase jmp address to keep thumb state cache_addw( ADD_IMM3(templo2, templo2, 1) ); // add templo2, templo2, #1 @@ -817,50 +1022,53 @@ static void INLINE gen_fill_branch_long(Bit32u data) { } static void gen_run_code(void) { - // switch from arm to thumb state - cache_addd(0xe2800000 + (HOST_r3 << 12) + (HOST_pc << 16) + (1)); // add r3, pc, #1 - cache_addd(0xe12fff10 + (HOST_r3)); // bx r3 + Bit8u *pos1, *pos2, *pos3; - // thumb state from now on - cache_addw(0xb500); // push {lr} - cache_addw( MOV_LO_HI(HOST_r3, FC_SEGS_ADDR) ); // mov r3, FC_SEGS_ADDR - cache_addw( MOV_LO_HI(HOST_r2, FC_REGS_ADDR) ); // mov r2, FC_REGS_ADDR - cache_addw(0xb4fc); // push {r2,r3,v1-v4} +#if (__ARM_EABI__) + // 8-byte stack alignment + cache_addd(0xe92d4ff0); // stmfd sp!, {v1-v8,lr} +#else + cache_addd(0xe92d4df0); // stmfd sp!, {v1-v5,v7,v8,lr} +#endif - // adr: 16 - cache_addw( LDR_PC_IMM(HOST_r3, 64 - (16 + 4)) ); // ldr r3, [pc, #(&Segs)] - // adr: 18 - cache_addw( LDR_PC_IMM(HOST_r2, 68 - (18 + 2)) ); // ldr r2, [pc, #(&cpu_regs)] - cache_addw( MOV_HI_LO(FC_SEGS_ADDR, HOST_r3) ); // mov FC_SEGS_ADDR, r3 - cache_addw( MOV_HI_LO(FC_REGS_ADDR, HOST_r2) ); // mov FC_REGS_ADDR, r2 + cache_addd( ARM_ADD_IMM(HOST_r0, HOST_r0, 1, 0) ); // add r0, r0, #1 - // align 4 - cache_addw( ADD_LO_PC_IMM(HOST_r3, 8) ); // add r3, pc, #8 - cache_addw( ADD_IMM8(HOST_r0, 1) ); // add r0, #1 - cache_addw( ADD_IMM8(HOST_r3, 1) ); // add r3, #1 - cache_addw(0xb408); // push {r3} - cache_addw( BX(HOST_r0) ); // bx r0 - cache_addw( NOP ); // nop + pos1 = cache.pos; + cache_addd( 0 ); + pos2 = cache.pos; + cache_addd( 0 ); + pos3 = cache.pos; + cache_addd( 0 ); - // align 4 - cache_addw(0xbcfc); // pop {r2,r3,v1-v4} - cache_addw( MOV_HI_LO(FC_SEGS_ADDR, HOST_r3) ); // mov FC_SEGS_ADDR, r3 - cache_addw( MOV_HI_LO(FC_REGS_ADDR, HOST_r2) ); // mov FC_REGS_ADDR, r2 + cache_addd( ARM_ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 + cache_addd( ARM_STR_IMM_M_W(HOST_lr, HOST_sp, 4) ); // str lr, [sp, #-4]! + cache_addd( ARM_BX(HOST_r0) ); // bx r0 - cache_addw(0xbc08); // pop {r3} - cache_addw( BX(HOST_r3) ); // bx r3 +#if (__ARM_EABI__) + cache_addd(0xe8bd4ff0); // ldmfd sp!, {v1-v8,lr} +#else + cache_addd(0xe8bd4df0); // ldmfd sp!, {v1-v5,v7,v8,lr} +#endif + cache_addd( ARM_BX(HOST_lr) ); // bx lr - // fill up to 64 bytes - cache_addw( NOP ); // nop - cache_addd( NOP | (NOP << 16) ); // nop, nop - cache_addd( NOP | (NOP << 16) ); // nop, nop - cache_addd( NOP | (NOP << 16) ); // nop, nop - cache_addd( NOP | (NOP << 16) ); // nop, nop + // align cache.pos to 32 bytes + if ((((Bitu)cache.pos) & 0x1f) != 0) { + cache.pos = cache.pos + (32 - (((Bitu)cache.pos) & 0x1f)); + } - // adr: 64 + *(Bit32u*)pos1 = ARM_LDR_IMM(FC_SEGS_ADDR, HOST_pc, cache.pos - (pos1 + 8)); // ldr FC_SEGS_ADDR, [pc, #(&Segs)] cache_addd((Bit32u)&Segs); // address of "Segs" - // adr: 68 + + *(Bit32u*)pos2 = ARM_LDR_IMM(FC_REGS_ADDR, HOST_pc, cache.pos - (pos2 + 8)); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)] cache_addd((Bit32u)&cpu_regs); // address of "cpu_regs" + + *(Bit32u*)pos3 = ARM_LDR_IMM(readdata_addr, HOST_pc, cache.pos - (pos3 + 8)); // ldr readdata_addr, [pc, #(&core_dynrec.readdata)] + cache_addd((Bit32u)&core_dynrec.readdata); // address of "core_dynrec.readdata" + + // align cache.pos to 32 bytes + if ((((Bitu)cache.pos) & 0x1f) != 0) { + cache.pos = cache.pos + (32 - (((Bitu)cache.pos) & 0x1f)); + } } // return from a function diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb.h b/src/cpu/core_dynrec/risc_armv4le-thumb.h index 33409edd..829cb554 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb.h @@ -50,15 +50,14 @@ // temporary register for LEA #define TEMP_REG_DRC HOST_a4 -#ifdef DRC_USE_REGS_ADDR // used to hold the address of "cpu_regs" - preferably filled in function gen_run_code #define FC_REGS_ADDR HOST_v7 -#endif -#ifdef DRC_USE_SEGS_ADDR // used to hold the address of "Segs" - preferably filled in function gen_run_code #define FC_SEGS_ADDR HOST_v8 -#endif + +// used to hold the address of "core_dynrec.readdata" - filled in function gen_run_code +#define readdata_addr HOST_v5 // instruction encodings @@ -98,10 +97,14 @@ // logical // and dst, src #define AND(dst, src) (0x4000 + (dst) + ((src) << 3) ) +// bic dst, src +#define BIC(dst, src) (0x4380 + (dst) + ((src) << 3) ) // eor dst, src #define EOR(dst, src) (0x4040 + (dst) + ((src) << 3) ) // orr dst, src #define ORR(dst, src) (0x4300 + (dst) + ((src) << 3) ) +// mvn dst, src +#define MVN(dst, src) (0x43c0 + (dst) + ((src) << 3) ) // shift/rotate // lsl dst, src, #imm @@ -128,6 +131,8 @@ #define LDRB_IMM(reg, addr, imm) (0x7800 + (reg) + ((addr) << 3) + ((imm) << 6) ) // ldr reg, [pc, #imm] @ 0 <= imm < 1024 & imm mod 4 = 0 #define LDR_PC_IMM(reg, imm) (0x4800 + ((reg) << 8) + ((imm) >> 2) ) +// ldr reg, [addr1, addr2] +#define LDR_REG(reg, addr1, addr2) (0x5800 + (reg) + ((addr1) << 3) + ((addr2) << 6) ) // store // str reg, [addr, #imm] @ 0 <= imm < 128 & imm mod 4 = 0 @@ -150,30 +155,69 @@ #define BX(reg) (0x4700 + ((reg) << 3) ) +// arm instructions + +// arithmetic +// add dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 +#define ARM_ADD_IMM(dst, src, imm, rimm) (0xe2800000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) + +// load +// ldr reg, [addr, #imm] @ 0 <= imm < 4096 +#define ARM_LDR_IMM(reg, addr, imm) (0xe5900000 + ((reg) << 12) + ((addr) << 16) + (imm) ) + +// store +// str reg, [addr, #-(imm)]! @ 0 <= imm < 4096 +#define ARM_STR_IMM_M_W(reg, addr, imm) (0xe5200000 + ((reg) << 12) + ((addr) << 16) + (imm) ) + +// branch +// bx reg +#define ARM_BX(reg) (0xe12fff10 + (reg) ) + + // move a full register from reg_src to reg_dst static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { if(reg_src == reg_dst) return; cache_addw( MOV_REG(reg_dst, reg_src) ); // mov reg_dst, reg_src } +// helper function +static bool val_single_shift(Bit32u value, Bit32u *val_shift) { + Bit32u shift; + + if (GCC_UNLIKELY(value == 0)) { + *val_shift = 0; + return true; + } + + shift = 0; + while ((value & 1) == 0) { + value>>=1; + shift+=1; + } + + if ((value >> 8) != 0) return false; + + *val_shift = shift; + return true; +} + // move a 32bit constant value into dest_reg static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { - if ((imm & 0xffffff00) == 0) { - cache_addw( MOV_IMM(dest_reg, imm) ); // mov dest_reg, #(imm) - } else if ((imm & 0xffff00ff) == 0) { - cache_addw( MOV_IMM(dest_reg, imm >> 8) ); // mov dest_reg, #(imm >> 8) - cache_addw( LSL_IMM(dest_reg, dest_reg, 8) ); // lsl dest_reg, dest_reg, #8 - } else if ((imm & 0xff00ffff) == 0) { - cache_addw( MOV_IMM(dest_reg, imm >> 16) ); // mov dest_reg, #(imm >> 16) - cache_addw( LSL_IMM(dest_reg, dest_reg, 16) ); // lsl dest_reg, dest_reg, #16 - } else if ((imm & 0x00ffffff) == 0) { - cache_addw( MOV_IMM(dest_reg, imm >> 24) ); // mov dest_reg, #(imm >> 24) - cache_addw( LSL_IMM(dest_reg, dest_reg, 24) ); // lsl dest_reg, dest_reg, #24 + Bit32u scale; + + if (imm < 256) { + cache_addw( MOV_IMM(dest_reg, imm) ); // mov dest_reg, #imm + } else if ((~imm) < 256) { + cache_addw( MOV_IMM(dest_reg, ~imm) ); // mov dest_reg, #(~imm) + cache_addw( MVN(dest_reg, dest_reg) ); // mvn dest_reg, dest_reg + } else if (val_single_shift(imm, &scale)) { + cache_addw( MOV_IMM(dest_reg, imm >> scale) ); // mov dest_reg, #(imm >> scale) + cache_addw( LSL_IMM(dest_reg, dest_reg, scale) ); // lsl dest_reg, dest_reg, #scale } else { Bit32u diff; - + diff = imm - ((Bit32u)cache.pos+4); - + if ((diff < 1024) && ((imm & 0x03) == 0)) { if (((Bit32u)cache.pos & 0x03) == 0) { cache_addw( ADD_LO_PC_IMM(dest_reg, diff) ); // add dest_reg, pc, #(diff >> 2) @@ -198,10 +242,58 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { } } +// helper function +static bool gen_mov_memval_to_reg_helper(HostReg dest_reg, Bit32u data, Bitu size, HostReg addr_reg, Bit32u addr_data) { + switch (size) { + case 4: +#if !defined(C_UNALIGNED_MEMORY) + if ((data & 3) == 0) +#endif + { + if ((data >= addr_data) && (data < addr_data + 128) && (((data - addr_data) & 3) == 0)) { + cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg + cache_addw( LDR_IMM(dest_reg, templo2, data - addr_data) ); // ldr dest_reg, [templo2, #(data - addr_data)] + return true; + } + } + break; + case 2: +#if !defined(C_UNALIGNED_MEMORY) + if ((data & 1) == 0) +#endif + { + if ((data >= addr_data) && (data < addr_data + 64) && (((data - addr_data) & 1) == 0)) { + cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg + cache_addw( LDRH_IMM(dest_reg, templo2, data - addr_data) ); // ldrh dest_reg, [templo2, #(data - addr_data)] + return true; + } + } + break; + case 1: + if ((data >= addr_data) && (data < addr_data + 32)) { + cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg + cache_addw( LDRB_IMM(dest_reg, templo2, data - addr_data) ); // ldrb dest_reg, [templo2, #(data - addr_data)] + return true; + } + default: + break; + } + return false; +} + +// helper function +static bool gen_mov_memval_to_reg(HostReg dest_reg, void *data, Bitu size) { + if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, FC_REGS_ADDR, (Bit32u)&cpu_regs)) return true; + if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, readdata_addr, (Bit32u)&core_dynrec.readdata)) return true; + if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, FC_SEGS_ADDR, (Bit32u)&Segs)) return true; + return false; +} + // helper function for gen_mov_word_to_reg static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,HostReg data_reg) { // alignment.... if (dword) { +#if !defined(C_UNALIGNED_MEMORY) if ((Bit32u)data & 3) { if ( ((Bit32u)data & 3) == 2 ) { cache_addw( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] @@ -218,16 +310,21 @@ static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,Ho cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 } - } else { + } else +#endif + { cache_addw( LDR_IMM(dest_reg, data_reg, 0) ); // ldr dest_reg, [data_reg] } } else { +#if !defined(C_UNALIGNED_MEMORY) if ((Bit32u)data & 1) { cache_addw( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] cache_addw( LDRB_IMM(templo1, data_reg, 1) ); // ldrb templo1, [data_reg, #1] cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 - } else { + } else +#endif + { cache_addw( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] } } @@ -236,8 +333,10 @@ static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,Ho // move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { - gen_mov_dword_to_reg_imm(templo2, (Bit32u)data); - gen_mov_word_to_reg_helper(dest_reg, data, dword, templo2); + if (!gen_mov_memval_to_reg(dest_reg, data, (dword)?4:2)) { + gen_mov_dword_to_reg_imm(templo2, (Bit32u)data); + gen_mov_word_to_reg_helper(dest_reg, data, dword, templo2); + } } // move a 16bit constant value into dest_reg @@ -246,10 +345,58 @@ static void INLINE gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { gen_mov_dword_to_reg_imm(dest_reg, (Bit32u)imm); } +// helper function +static bool gen_mov_memval_from_reg_helper(HostReg src_reg, Bit32u data, Bitu size, HostReg addr_reg, Bit32u addr_data) { + switch (size) { + case 4: +#if !defined(C_UNALIGNED_MEMORY) + if ((data & 3) == 0) +#endif + { + if ((data >= addr_data) && (data < addr_data + 128) && (((data - addr_data) & 3) == 0)) { + cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg + cache_addw( STR_IMM(src_reg, templo2, data - addr_data) ); // str src_reg, [templo2, #(data - addr_data)] + return true; + } + } + break; + case 2: +#if !defined(C_UNALIGNED_MEMORY) + if ((data & 1) == 0) +#endif + { + if ((data >= addr_data) && (data < addr_data + 64) && (((data - addr_data) & 1) == 0)) { + cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg + cache_addw( STRH_IMM(src_reg, templo2, data - addr_data) ); // strh src_reg, [templo2, #(data - addr_data)] + return true; + } + } + break; + case 1: + if ((data >= addr_data) && (data < addr_data + 32)) { + cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg + cache_addw( STRB_IMM(src_reg, templo2, data - addr_data) ); // strb src_reg, [templo2, #(data - addr_data)] + return true; + } + default: + break; + } + return false; +} + +// helper function +static bool gen_mov_memval_from_reg(HostReg src_reg, void *dest, Bitu size) { + if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, FC_REGS_ADDR, (Bit32u)&cpu_regs)) return true; + if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, readdata_addr, (Bit32u)&core_dynrec.readdata)) return true; + if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, FC_SEGS_ADDR, (Bit32u)&Segs)) return true; + return false; +} + // helper function for gen_mov_word_from_reg static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, HostReg data_reg) { // alignment.... if (dword) { +#if !defined(C_UNALIGNED_MEMORY) if ((Bit32u)dest & 3) { if ( ((Bit32u)dest & 3) == 2 ) { cache_addw( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] @@ -268,16 +415,21 @@ static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, cache_addw( LSR_IMM(templo1, templo1, 24) ); // lsr templo1, templo1, #24 cache_addw( STRB_IMM(templo1, data_reg, 3) ); // strb templo1, [data_reg, #3] } - } else { + } else +#endif + { cache_addw( STR_IMM(src_reg, data_reg, 0) ); // str src_reg, [data_reg] } } else { +#if !defined(C_UNALIGNED_MEMORY) if ((Bit32u)dest & 1) { cache_addw( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg cache_addw( LSR_IMM(templo1, templo1, 8) ); // lsr templo1, templo1, #8 cache_addw( STRB_IMM(templo1, data_reg, 1) ); // strb templo1, [data_reg, #1] - } else { + } else +#endif + { cache_addw( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] } } @@ -285,8 +437,10 @@ static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, // move 32bit (dword==true) or 16bit (dword==false) of a register into memory static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_from_reg_helper(src_reg, dest, dword, templo2); + if (!gen_mov_memval_from_reg(src_reg, dest, (dword)?4:2)) { + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_from_reg_helper(src_reg, dest, dword, templo2); + } } // move an 8bit value from memory into dest_reg @@ -294,8 +448,10 @@ static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { // this function does not use FC_OP1/FC_OP2 as dest_reg as these // registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { - gen_mov_dword_to_reg_imm(templo1, (Bit32u)data); - cache_addw( LDRB_IMM(dest_reg, templo1, 0) ); // ldrb dest_reg, [templo1] + if (!gen_mov_memval_to_reg(dest_reg, data, 1)) { + gen_mov_dword_to_reg_imm(templo1, (Bit32u)data); + cache_addw( LDRB_IMM(dest_reg, templo1, 0) ); // ldrb dest_reg, [templo1] + } } // move an 8bit value from memory into dest_reg @@ -324,8 +480,10 @@ static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u // move the lowest 8bit of a register into memory static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { - gen_mov_dword_to_reg_imm(templo1, (Bit32u)dest); - cache_addw( STRB_IMM(src_reg, templo1, 0) ); // strb src_reg, [templo1] + if (!gen_mov_memval_from_reg(src_reg, dest, 1)) { + gen_mov_dword_to_reg_imm(templo1, (Bit32u)dest); + cache_addw( STRB_IMM(src_reg, templo1, 0) ); // strb src_reg, [templo1] + } } @@ -362,16 +520,51 @@ static void gen_add(HostReg reg,void* op) { // add a 32bit constant value to a full register static void gen_add_imm(HostReg reg,Bit32u imm) { + Bit32u imm2, scale; + if(!imm) return; - gen_mov_dword_to_reg_imm(templo1, imm); - cache_addw( ADD_REG(reg, reg, templo1) ); // add reg, reg, templo1 + + imm2 = (Bit32u) (-((Bit32s)imm)); + + if (imm <= 255) { + cache_addw( ADD_IMM8(reg, imm) ); // add reg, #imm + } else if (imm2 <= 255) { + cache_addw( SUB_IMM8(reg, imm2) ); // sub reg, #(-imm) + } else { + if (val_single_shift(imm2, &scale)) { + cache_addw( MOV_IMM(templo1, imm2 >> scale) ); // mov templo1, #(~imm >> scale) + if (scale) { + cache_addw( LSL_IMM(templo1, templo1, scale) ); // lsl templo1, templo1, #scale + } + cache_addw( SUB_REG(reg, reg, templo1) ); // sub reg, reg, templo1 + } else { + gen_mov_dword_to_reg_imm(templo1, imm); + cache_addw( ADD_REG(reg, reg, templo1) ); // add reg, reg, templo1 + } + } } // and a 32bit constant value with a full register static void gen_and_imm(HostReg reg,Bit32u imm) { - if(imm == 0xffffffff) return; - gen_mov_dword_to_reg_imm(templo1, imm); - cache_addw( AND(reg, templo1) ); // and reg, templo1 + Bit32u imm2, scale; + + imm2 = ~imm; + if(!imm2) return; + + if (!imm) { + cache_addw( MOV_IMM(reg, 0) ); // mov reg, #0 + } else { + if (val_single_shift(imm2, &scale)) { + cache_addw( MOV_IMM(templo1, imm2 >> scale) ); // mov templo1, #(~imm >> scale) + if (scale) { + cache_addw( LSL_IMM(templo1, templo1, scale) ); // lsl templo1, templo1, #scale + } + cache_addw( BIC(reg, templo1) ); // bic reg, templo1 + } else { + gen_mov_dword_to_reg_imm(templo1, imm); + cache_addw( AND(reg, templo1) ); // and reg, templo1 + } + } } @@ -386,66 +579,65 @@ static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { gen_mov_direct_dword(dest,(Bit32u)imm); } -// add an 8bit constant value to a dword memory value -static void gen_add_direct_byte(void* dest,Bit8s imm) { - if(!imm) return; - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templo3, dest, 1, templo2); - if (imm >= 0) { - cache_addw( ADD_IMM8(templo3, (Bit32s)imm) ); // add templo3, #(imm) - } else { - cache_addw( SUB_IMM8(templo3, -((Bit32s)imm)) ); // sub templo3, #(-imm) - } - gen_mov_word_from_reg_helper(templo3, dest, 1, templo2); -} - // add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { + if (!dword) imm &= 0xffff; if(!imm) return; - if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { - gen_add_direct_byte(dest,(Bit8s)imm); - return; + + if (!gen_mov_memval_to_reg(templo3, dest, (dword)?4:2)) { + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); } - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); - if (dword) { - gen_mov_dword_to_reg_imm(templo1, imm); - } else { - gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); + gen_add_imm(templo3, imm); + if (!gen_mov_memval_from_reg(templo3, dest, (dword)?4:2)) { + gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); } - cache_addw( ADD_REG(templo3, templo3, templo1) ); // add templo3, templo3, templo1 - gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); } -// subtract an 8bit constant value from a dword memory value -static void gen_sub_direct_byte(void* dest,Bit8s imm) { - if(!imm) return; - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templo3, dest, 1, templo2); - if (imm >= 0) { - cache_addw( SUB_IMM8(templo3, (Bit32s)imm) ); // sub templo3, #(imm) - } else { - cache_addw( ADD_IMM8(templo3, -((Bit32s)imm)) ); // add templo3, #(-imm) - } - gen_mov_word_from_reg_helper(templo3, dest, 1, templo2); +// add an 8bit constant value to a dword memory value +static void gen_add_direct_byte(void* dest,Bit8s imm) { + gen_add_direct_word(dest, (Bit32s)imm, 1); } // subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { + Bit32u imm2, scale; + + if (!dword) imm &= 0xffff; if(!imm) return; - if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { - gen_sub_direct_byte(dest,(Bit8s)imm); - return; + + if (!gen_mov_memval_to_reg(templo3, dest, (dword)?4:2)) { + gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); + gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); } - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); - if (dword) { - gen_mov_dword_to_reg_imm(templo1, imm); + + imm2 = (Bit32u) (-((Bit32s)imm)); + + if (imm <= 255) { + cache_addw( SUB_IMM8(templo3, imm) ); // sub templo3, #imm + } else if (imm2 <= 255) { + cache_addw( ADD_IMM8(templo3, imm2) ); // add templo3, #(-imm) } else { - gen_mov_word_to_reg_imm(templo1, (Bit16u)imm); + if (val_single_shift(imm2, &scale)) { + cache_addw( MOV_IMM(templo1, imm2 >> scale) ); // mov templo1, #(~imm >> scale) + if (scale) { + cache_addw( LSL_IMM(templo1, templo1, scale) ); // lsl templo1, templo1, #scale + } + cache_addw( ADD_REG(templo3, templo3, templo1) ); // add templo3, templo3, templo1 + } else { + gen_mov_dword_to_reg_imm(templo1, imm); + cache_addw( SUB_REG(templo3, templo3, templo1) ); // sub templo3, templo3, templo1 + } } - cache_addw( SUB_REG(templo3, templo3, templo1) ); // sub templo3, templo3, templo1 - gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); + + if (!gen_mov_memval_from_reg(templo3, dest, (dword)?4:2)) { + gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); + } +} + +// subtract an 8bit constant value from a dword memory value +static void gen_sub_direct_byte(void* dest,Bit8s imm) { + gen_sub_direct_word(dest, (Bit32s)imm, 1); } // effective address calculation, destination is dest_reg @@ -491,7 +683,7 @@ static void INLINE gen_call_function_raw(void * func) { // switch from arm to thumb state cache_addd(0xe2800000 + (templo1 << 12) + (HOST_pc << 16) + (1)); // add templo1, pc, #1 cache_addd(0xe12fff10 + (templo1)); // bx templo1 - + // thumb state from now on } @@ -537,18 +729,20 @@ static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { static void gen_jmp_ptr(void * ptr,Bits imm=0) { gen_mov_word_to_reg(templo3, ptr, 1); - if (imm) { - gen_mov_dword_to_reg_imm(templo2, imm); - cache_addw( ADD_REG(templo3, templo3, templo2) ); // add templo3, templo3, templo2 - } - -#if (1) -// (*ptr) should be word aligned +#if !defined(C_UNALIGNED_MEMORY) +// (*ptr) should be word aligned if ((imm & 0x03) == 0) { - cache_addw( LDR_IMM(templo2, templo3, 0) ); // ldr templo2, [templo3] - } else #endif - { + if ((imm >= 0) && (imm < 128) && ((imm & 3) == 0)) { + cache_addw( LDR_IMM(templo2, templo3, imm) ); // ldr templo2, [templo3, #imm] + } else { + gen_mov_dword_to_reg_imm(templo2, imm); + cache_addw( LDR_REG(templo2, templo3, templo2) ); // ldr templo2, [templo3, templo2] + } +#if !defined(C_UNALIGNED_MEMORY) + } else { + gen_add_imm(templo3, imm); + cache_addw( LDRB_IMM(templo2, templo3, 0) ); // ldrb templo2, [templo3] cache_addw( LDRB_IMM(templo1, templo3, 1) ); // ldrb templo1, [templo3, #1] cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 @@ -560,6 +754,7 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 } +#endif // increase jmp address to keep thumb state cache_addw( ADD_IMM3(templo2, templo2, 1) ); // add templo2, templo2, #1 @@ -650,50 +845,53 @@ static void INLINE gen_fill_branch_long(Bit32u data) { } static void gen_run_code(void) { - // switch from arm to thumb state - cache_addd(0xe2800000 + (HOST_r3 << 12) + (HOST_pc << 16) + (1)); // add r3, pc, #1 - cache_addd(0xe12fff10 + (HOST_r3)); // bx r3 + Bit8u *pos1, *pos2, *pos3; - // thumb state from now on - cache_addw(0xb500); // push {lr} - cache_addw( MOV_LO_HI(HOST_r3, FC_SEGS_ADDR) ); // mov r3, FC_SEGS_ADDR - cache_addw( MOV_LO_HI(HOST_r2, FC_REGS_ADDR) ); // mov r2, FC_REGS_ADDR - cache_addw(0xb4fc); // push {r2,r3,v1-v4} +#if (__ARM_EABI__) + // 8-byte stack alignment + cache_addd(0xe92d4ff0); // stmfd sp!, {v1-v8,lr} +#else + cache_addd(0xe92d4df0); // stmfd sp!, {v1-v5,v7,v8,lr} +#endif - // adr: 16 - cache_addw( LDR_PC_IMM(HOST_r3, 64 - (16 + 4)) ); // ldr r3, [pc, #(&Segs)] - // adr: 18 - cache_addw( LDR_PC_IMM(HOST_r2, 68 - (18 + 2)) ); // ldr r2, [pc, #(&cpu_regs)] - cache_addw( MOV_HI_LO(FC_SEGS_ADDR, HOST_r3) ); // mov FC_SEGS_ADDR, r3 - cache_addw( MOV_HI_LO(FC_REGS_ADDR, HOST_r2) ); // mov FC_REGS_ADDR, r2 + cache_addd( ARM_ADD_IMM(HOST_r0, HOST_r0, 1, 0) ); // add r0, r0, #1 - // align 4 - cache_addw( ADD_LO_PC_IMM(HOST_r3, 8) ); // add r3, pc, #8 - cache_addw( ADD_IMM8(HOST_r0, 1) ); // add r0, #1 - cache_addw( ADD_IMM8(HOST_r3, 1) ); // add r3, #1 - cache_addw(0xb408); // push {r3} - cache_addw( BX(HOST_r0) ); // bx r0 - cache_addw( NOP ); // nop + pos1 = cache.pos; + cache_addd( 0 ); + pos2 = cache.pos; + cache_addd( 0 ); + pos3 = cache.pos; + cache_addd( 0 ); - // align 4 - cache_addw(0xbcfc); // pop {r2,r3,v1-v4} - cache_addw( MOV_HI_LO(FC_SEGS_ADDR, HOST_r3) ); // mov FC_SEGS_ADDR, r3 - cache_addw( MOV_HI_LO(FC_REGS_ADDR, HOST_r2) ); // mov FC_REGS_ADDR, r2 + cache_addd( ARM_ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 + cache_addd( ARM_STR_IMM_M_W(HOST_lr, HOST_sp, 4) ); // str lr, [sp, #-4]! + cache_addd( ARM_BX(HOST_r0) ); // bx r0 - cache_addw(0xbc08); // pop {r3} - cache_addw( BX(HOST_r3) ); // bx r3 +#if (__ARM_EABI__) + cache_addd(0xe8bd4ff0); // ldmfd sp!, {v1-v8,lr} +#else + cache_addd(0xe8bd4df0); // ldmfd sp!, {v1-v5,v7,v8,lr} +#endif + cache_addd( ARM_BX(HOST_lr) ); // bx lr - // fill up to 64 bytes - cache_addw( NOP ); // nop - cache_addd( NOP | (NOP << 16) ); // nop, nop - cache_addd( NOP | (NOP << 16) ); // nop, nop - cache_addd( NOP | (NOP << 16) ); // nop, nop - cache_addd( NOP | (NOP << 16) ); // nop, nop + // align cache.pos to 32 bytes + if ((((Bitu)cache.pos) & 0x1f) != 0) { + cache.pos = cache.pos + (32 - (((Bitu)cache.pos) & 0x1f)); + } - // adr: 64 + *(Bit32u*)pos1 = ARM_LDR_IMM(FC_SEGS_ADDR, HOST_pc, cache.pos - (pos1 + 8)); // ldr FC_SEGS_ADDR, [pc, #(&Segs)] cache_addd((Bit32u)&Segs); // address of "Segs" - // adr: 68 + + *(Bit32u*)pos2 = ARM_LDR_IMM(FC_REGS_ADDR, HOST_pc, cache.pos - (pos2 + 8)); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)] cache_addd((Bit32u)&cpu_regs); // address of "cpu_regs" + + *(Bit32u*)pos3 = ARM_LDR_IMM(readdata_addr, HOST_pc, cache.pos - (pos3 + 8)); // ldr readdata_addr, [pc, #(&core_dynrec.readdata)] + cache_addd((Bit32u)&core_dynrec.readdata); // address of "core_dynrec.readdata" + + // align cache.pos to 32 bytes + if ((((Bitu)cache.pos) & 0x1f) != 0) { + cache.pos = cache.pos + (32 - (((Bitu)cache.pos) & 0x1f)); + } } // return from a function @@ -1023,7 +1221,11 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { } #endif -static void cache_block_before_close(void) { } +static void cache_block_before_close(void) { + if ((((Bit32u)cache.pos) & 3) != 0) { + cache_addw( NOP ); // nop + } +} #ifdef DRC_USE_SEGS_ADDR diff --git a/src/cpu/core_dynrec/risc_armv4le.h b/src/cpu/core_dynrec/risc_armv4le.h index a4d74d42..7a38d8f2 100644 --- a/src/cpu/core_dynrec/risc_armv4le.h +++ b/src/cpu/core_dynrec/risc_armv4le.h @@ -18,13 +18,19 @@ -/* ARMv4 (little endian) backend (switcher) by M-HT */ +/* ARMv4/ARMv7 (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" +#if C_TARGETCPU == ARMV7LE + #include "risc_armv4le-o3.h" +#else + #if defined(__THUMB_INTERWORK__) + #include "risc_armv4le-thumb-iw.h" + #else + #include "risc_armv4le-o3.h" +// #include "risc_armv4le-thumb-niw.h" +// #include "risc_armv4le-thumb.h" + #endif +#endif From 0d65d2956c9f240f3e5dac8d2d6c618f2a514a5c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 12 Nov 2013 21:39:18 +0000 Subject: [PATCH 3757/4131] Correct the parameter type for 64 bit. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3847 --- src/gui/midi_win32.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index 44cefd79..162bf2e0 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -47,10 +47,10 @@ public: MIDIOUTCAPS mididev; midiOutGetDevCaps(nummer, &mididev, sizeof(MIDIOUTCAPS)); LOG_MSG("MIDI:win32 selected %s",mididev.szPname); - res = midiOutOpen(&m_out, nummer, (DWORD)m_event, 0, CALLBACK_EVENT); + res = midiOutOpen(&m_out, nummer, (DWORD_PTR)m_event, 0, CALLBACK_EVENT); } } else { - res = midiOutOpen(&m_out, MIDI_MAPPER, (DWORD)m_event, 0, CALLBACK_EVENT); + res = midiOutOpen(&m_out, MIDI_MAPPER, (DWORD_PTR)m_event, 0, CALLBACK_EVENT); } if (res != MMSYSERR_NOERROR) return false; isOpen=true; From 625dcb3c28a3667c5a8004cd3f20345980404125 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 12 Nov 2013 21:43:23 +0000 Subject: [PATCH 3758/4131] Cast it to a variable that has the same size as a pointer (64 bit) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3848 --- src/cpu/core_dynrec/cache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index cb46274b..e1a3d88c 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -596,7 +596,7 @@ static void cache_init(bool enable) { 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=(Bit8u*)(((Bitu)cache_code_start_ptr + PAGESIZE_TEMP-1) & ~(PAGESIZE_TEMP-1));//Bitu is same size as a pointer. cache_code_link_blocks=cache_code; cache_code=cache_code+PAGESIZE_TEMP; From 40c32b040cbcd281833946bddb0a598f6fea1ace Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sun, 17 Nov 2013 13:42:33 +0000 Subject: [PATCH 3759/4131] Add AL value to debugger interrupt breakpoints. Useful for breaking on specific sub-functions, and for function numbers in AX such as the mouse driver INT 33h. Faster breakpoint checking with some redundant conditions removed. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3849 --- src/debug/debug.cpp | 56 +++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 3cb7f184..85096a15 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -281,32 +281,34 @@ class CBreakpoint public: CBreakpoint(void); - void SetAddress (Bit16u seg, Bit32u off) { location = GetAddress(seg,off); type = BKPNT_PHYSICAL; segment = seg; offset = off; }; - void SetAddress (PhysPt adr) { location = adr; type = BKPNT_PHYSICAL; }; - void SetInt (Bit8u _intNr, Bit16u ah) { intNr = _intNr, ahValue = ah; type = BKPNT_INTERRUPT; }; + void SetAddress (Bit16u seg, Bit32u off) { location = GetAddress(seg,off); type = BKPNT_PHYSICAL; segment = seg; offset = off; }; + void SetAddress (PhysPt adr) { location = adr; type = BKPNT_PHYSICAL; }; + void SetInt (Bit8u _intNr, Bit16u ah, Bit16u al) { intNr = _intNr, ahValue = ah; alValue = al; type = BKPNT_INTERRUPT; }; void SetOnce (bool _once) { once = _once; }; void SetType (EBreakpoint _type) { type = _type; }; void SetValue (Bit8u value) { ahValue = value; }; + void SetOther (Bit8u other) { alValue = other; }; bool IsActive (void) { return active; }; void Activate (bool _active); EBreakpoint GetType (void) { return type; }; bool GetOnce (void) { return once; }; - PhysPt GetLocation (void) { if (GetType()!=BKPNT_INTERRUPT) return location; else return 0; }; + PhysPt GetLocation (void) { return location; }; Bit16u GetSegment (void) { return segment; }; Bit32u GetOffset (void) { return offset; }; - Bit8u GetIntNr (void) { if (GetType()==BKPNT_INTERRUPT) return intNr; else return 0; }; - Bit16u GetValue (void) { if (GetType()!=BKPNT_PHYSICAL) return ahValue; else return 0; }; + Bit8u GetIntNr (void) { return intNr; }; + Bit16u GetValue (void) { return ahValue; }; + Bit16u GetOther (void) { return alValue; }; // statics static CBreakpoint* AddBreakpoint (Bit16u seg, Bit32u off, bool once); - static CBreakpoint* AddIntBreakpoint (Bit8u intNum, Bit16u ah, bool once); + static CBreakpoint* AddIntBreakpoint (Bit8u intNum, Bit16u ah, Bit16u al, bool once); static CBreakpoint* AddMemBreakpoint (Bit16u seg, Bit32u off); static void ActivateBreakpoints (PhysPt adr, bool activate); static bool CheckBreakpoint (PhysPt adr); static bool CheckBreakpoint (Bitu seg, Bitu off); - static bool CheckIntBreakpoint (PhysPt adr, Bit8u intNr, Bit16u ahValue); + static bool CheckIntBreakpoint (PhysPt adr, Bit8u intNr, Bit16u ahValue, Bit16u alValue); static bool IsBreakpoint (PhysPt where); static bool IsBreakpointDrawn (PhysPt where); static bool DeleteBreakpoint (PhysPt where); @@ -325,6 +327,7 @@ private: // Int Bit8u intNr; Bit16u ahValue; + Bit16u alValue; // Shared bool active; bool once; @@ -337,7 +340,7 @@ public: CBreakpoint::CBreakpoint(void): location(0), active(false),once(false), -segment(0),offset(0),intNr(0),ahValue(0), +segment(0),offset(0),intNr(0),ahValue(0),alValue(0), type(BKPNT_UNKNOWN) { }; void CBreakpoint::Activate(bool _active) @@ -376,10 +379,10 @@ CBreakpoint* CBreakpoint::AddBreakpoint(Bit16u seg, Bit32u off, bool once) return bp; }; -CBreakpoint* CBreakpoint::AddIntBreakpoint(Bit8u intNum, Bit16u ah, bool once) +CBreakpoint* CBreakpoint::AddIntBreakpoint(Bit8u intNum, Bit16u ah, Bit16u al, bool once) { CBreakpoint* bp = new CBreakpoint(); - bp->SetInt (intNum,ah); + bp->SetInt (intNum,ah,al); bp->SetOnce (once); BPoints.push_front (bp); return bp; @@ -475,7 +478,7 @@ bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off) return false; }; -bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue) +bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue, Bit16u alValue) // Checks if interrupt breakpoint is valid and should stop execution { if ((ignoreAddressOnce!=0) && (adr==ignoreAddressOnce)) { @@ -490,7 +493,7 @@ bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue) for(i=BPoints.begin(); i != BPoints.end(); i++) { bp = (*i); if ((bp->GetType()==BKPNT_INTERRUPT) && bp->IsActive() && (bp->GetIntNr()==intNr)) { - if ((bp->GetValue()==BPINT_ALL) || (bp->GetValue()==ahValue)) { + if (((bp->GetValue()==BPINT_ALL) || (bp->GetValue()==ahValue)) && ((bp->GetOther()==BPINT_ALL) || (bp->GetOther()==alValue))) { // Ignore it once ? if (ignoreOnce==bp) { ignoreOnce=0; @@ -606,8 +609,9 @@ void CBreakpoint::ShowList(void) if (bp->GetType()==BKPNT_PHYSICAL) { DEBUG_ShowMsg("%02X. BP %04X:%04X\n",nr,bp->GetSegment(),bp->GetOffset()); } else if (bp->GetType()==BKPNT_INTERRUPT) { - if (bp->GetValue()==BPINT_ALL) DEBUG_ShowMsg("%02X. BPINT %02X\n",nr,bp->GetIntNr()); - else DEBUG_ShowMsg("%02X. BPINT %02X AH=%02X\n",nr,bp->GetIntNr(),bp->GetValue()); + if (bp->GetValue()==BPINT_ALL) DEBUG_ShowMsg("%02X. BPINT %02X\n",nr,bp->GetIntNr()); + else if (bp->GetOther()==BPINT_ALL) DEBUG_ShowMsg("%02X. BPINT %02X AH=%02X\n",nr,bp->GetIntNr(),bp->GetValue()); + else DEBUG_ShowMsg("%02X. BPINT %02X AH=%02X AL=%02X\n",nr,bp->GetIntNr(),bp->GetValue(),bp->GetOther()); } else if (bp->GetType()==BKPNT_MEMORY) { DEBUG_ShowMsg("%02X. BPMEM %04X:%04X (%02X)\n",nr,bp->GetSegment(),bp->GetOffset(),bp->GetValue()); } else if (bp->GetType()==BKPNT_MEMORY_PROT) { @@ -633,7 +637,7 @@ bool DEBUG_IntBreakpoint(Bit8u intNum) { /* First get the physical address and check for a set Breakpoint */ PhysPt where=GetAddress(SegValue(cs),reg_eip); - if (!CBreakpoint::CheckIntBreakpoint(where,intNum,reg_ah)) return false; + if (!CBreakpoint::CheckIntBreakpoint(where,intNum,reg_ah,reg_al)) return false; // Found. Breakpoint is valid CBreakpoint::ActivateBreakpoints(where,false); // Deactivate all breakpoints return true; @@ -1105,14 +1109,21 @@ bool ParseCommand(char* str) { if (command == "BPINT") { // Add Interrupt Breakpoint Bit8u intNr = (Bit8u)GetHexValue(found,found); - bool all = !(*found);found++; - Bit8u valAH = (Bit8u)GetHexValue(found,found); + bool all = !(*found); + Bit8u valAH = (Bit8u)GetHexValue(found,found); if ((valAH==0x00) && (*found=='*' || all)) { - CBreakpoint::AddIntBreakpoint(intNr,BPINT_ALL,false); + CBreakpoint::AddIntBreakpoint(intNr,BPINT_ALL,BPINT_ALL,false); DEBUG_ShowMsg("DEBUG: Set interrupt breakpoint at INT %02X\n",intNr); } else { - CBreakpoint::AddIntBreakpoint(intNr,valAH,false); - DEBUG_ShowMsg("DEBUG: Set interrupt breakpoint at INT %02X AH=%02X\n",intNr,valAH); + all = !(*found); + Bit8u valAL = (Bit8u)GetHexValue(found,found); + if ((valAL==0x00) && (*found=='*' || all)) { + CBreakpoint::AddIntBreakpoint(intNr,valAH,BPINT_ALL,false); + DEBUG_ShowMsg("DEBUG: Set interrupt breakpoint at INT %02X AH=%02X\n",intNr,valAH); + } else { + CBreakpoint::AddIntBreakpoint(intNr,valAH,valAL,false); + DEBUG_ShowMsg("DEBUG: Set interrupt breakpoint at INT %02X AH=%02X AL=%02X\n",intNr,valAH,valAL); + } } return true; }; @@ -1294,7 +1305,8 @@ bool ParseCommand(char* str) { DEBUG_ShowMsg("Home/End - Scroll log messages.\n"); DEBUG_ShowMsg("BP [segment]:[offset] - Set breakpoint.\n"); DEBUG_ShowMsg("BPINT [intNr] * - Set interrupt breakpoint.\n"); - DEBUG_ShowMsg("BPINT [intNr] [ah] - Set interrupt breakpoint with ah.\n"); + DEBUG_ShowMsg("BPINT [intNr] [ah] * - Set interrupt breakpoint with ah.\n"); + DEBUG_ShowMsg("BPINT [intNr] [ah] [al] - Set interrupt breakpoint with ah and al.\n"); #if C_HEAVY_DEBUG DEBUG_ShowMsg("BPM [segment]:[offset] - Set memory breakpoint (memory change).\n"); DEBUG_ShowMsg("BPPM [selector]:[offset]- Set pmode-memory breakpoint (memory change).\n"); From 3b2adeccbf29bdd92019a0e82e0f7f0195e91d2f Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 19 Nov 2013 13:43:40 +0000 Subject: [PATCH 3760/4131] The SB DMA callback ignores previously selected, but not currently selected, DMA channels. Fixes Visual Player 2 with SB16. Bits 0 and 4 of the SBPro mixer volume registers are always set. Fixes SBPro detection in Wolfenstein 3D, Alone in the Dark (European versions), Visual Player 2, and possibly others. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3850 --- src/hardware/sblaster.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index b3104696..daf8c0cc 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -274,7 +274,7 @@ static INLINE void DSP_FlushData(void) { } static void DSP_DMA_CallBack(DmaChannel * chan, DMAEvent event) { - if (event==DMA_REACHED_TC) return; + if (chan!=sb.dma.chan || event==DMA_REACHED_TC) return; else if (event==DMA_MASKED) { if (sb.mode==MODE_DMA) { GenerateDMASound(sb.dma.min); @@ -1123,8 +1123,9 @@ static void CTMIXER_Reset(void) { _WHICH_[0]= ((((_VAL_) & 0xf0) >> 3)|(sb.type==SBT_16 ? 1:3)); \ _WHICH_[1]= ((((_VAL_) & 0x0f) << 1)|(sb.type==SBT_16 ? 1:3)); \ -#define MAKEPROVOL(_WHICH_) \ - ((((_WHICH_[0] & 0x1e) << 3) | ((_WHICH_[1] & 0x1e) >> 1)) & (sb.type==SBT_16 ? 0xff:0xee)) +#define MAKEPROVOL(_WHICH_) \ + ((((_WHICH_[0] & 0x1e) << 3) | ((_WHICH_[1] & 0x1e) >> 1)) | \ + ((sb.type==SBT_PRO1 || sb.type==SBT_PRO2) ? 0x11:0)) static void DSP_ChangeStereo(bool stereo) { if (!sb.dma.stereo && stereo) { From 3074cbbc59ab1e250619f3638cb17f9063048a36 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 5 Dec 2013 18:56:20 +0000 Subject: [PATCH 3761/4131] Let compiler generate offset arithmetic to make fpu-x86 portable to x86_64.(thanks wjp) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3851 --- configure.ac | 2 +- src/fpu/fpu_instructions_x86.h | 467 +++++++++++---------------------- 2 files changed, 152 insertions(+), 317 deletions(-) diff --git a/configure.ac b/configure.ac index 87e44523..a683bfda 100644 --- a/configure.ac +++ b/configure.ac @@ -320,7 +320,7 @@ 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 + if test x$c_targetcpu = xx86 -o x$c_targetcpu = xx86_64; then AC_DEFINE(C_FPU_X86,1) AC_MSG_RESULT(yes) else diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index 24d61e36..1d51e26e 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -312,23 +312,7 @@ #endif // handles fdiv,fdivr -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH3(op) \ - Bit16u save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm mov eax, op1 \ - __asm shl eax, 4 \ - __asm fldcw fpu.cw_mask_all \ - __asm mov ebx, op2 \ - __asm shl ebx, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm op st(1), st(0) \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } -#else +// (This is identical to FPUD_ARITH1 but without a WEAK_EXCEPTIONS variant) #define FPUD_ARITH3(op) \ Bit16u new_sw,save_cw; \ __asm { \ @@ -347,24 +331,9 @@ __asm fldcw save_cw \ } \ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); -#endif // handles fdiv,fdivr -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH3_EA(op) \ - Bit16u save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm mov eax, op1 \ - __asm fldcw fpu.cw_mask_all \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fxch \ - __asm op st(1), st(0) \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } -#else +// (This is identical to FPUD_ARITH1_EA but without a WEAK_EXCEPTIONS variant) #define FPUD_ARITH3_EA(op) \ Bit16u new_sw,save_cw; \ __asm { \ @@ -381,10 +350,9 @@ __asm fldcw save_cw \ } \ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); -#endif // handles fprem,fprem1,fscale -#define FPUD_REMINDER(op) \ +#define FPUD_REMAINDER(op) \ Bit16u new_sw; \ __asm { \ __asm mov eax, TOP \ @@ -532,6 +500,8 @@ #else +// !defined _MSC_VER + #ifdef WEAK_EXCEPTIONS #define clx #else @@ -541,55 +511,44 @@ #ifdef WEAK_EXCEPTIONS #define FPUD_LOAD(op,szI,szA) \ __asm__ volatile ( \ - "movl $128, %%eax \n" \ - "shl $4, %0 \n" \ - #op #szA " (%1, %%eax) \n" \ - "fstpt (%1, %0) " \ - : \ - : "r" (store_to), "r" (fpu.p_regs) \ - : "eax", "memory" \ + #op #szA " %1 \n" \ + "fstpt %0 " \ + : "=m" (fpu.p_regs[store_to]) \ + : "m" (fpu.p_regs[8]) \ ); #else #define FPUD_LOAD(op,szI,szA) \ Bit16u new_sw; \ __asm__ volatile ( \ - "movl $8, %%eax \n" \ - "shl $4, %%eax \n" \ - "shl $4, %1 \n" \ "fclex \n" \ - #op #szA " (%2, %%eax) \n" \ + #op #szA " %2 \n" \ "fnstsw %0 \n" \ - "fstpt (%2, %1) " \ - : "=m" (new_sw) \ - : "r" (store_to), "r" (fpu.p_regs) \ - : "eax", "memory" \ + "fstpt %1 " \ + : "=&am" (new_sw), "=m" (fpu.p_regs[store_to]) \ + : "m" (fpu.p_regs[8]) \ ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); #endif #ifdef WEAK_EXCEPTIONS #define FPUD_LOAD_EA(op,szI,szA) \ __asm__ volatile ( \ - "movl $128, %%eax \n" \ - #op #szA " (%0, %%eax) \n" \ + #op #szA " %0 \n" \ : \ - : "r" (fpu.p_regs) \ - : "eax", "memory" \ + : "m" (fpu.p_regs[8]) \ ); #else #define FPUD_LOAD_EA(op,szI,szA) \ Bit16u new_sw; \ __asm__ volatile ( \ - "movl $8, %%eax \n" \ - "shl $4, %%eax \n" \ "fclex \n" \ - #op #szA " (%1, %%eax) \n" \ + #op #szA " %1 \n" \ "fnstsw %0 \n" \ - : "=m" (new_sw) \ - : "r" (fpu.p_regs) \ - : "eax", "memory" \ + : "=&am" (new_sw) \ + : "m" (fpu.p_regs[8]) \ + : \ ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); #endif #ifdef WEAK_EXCEPTIONS @@ -597,15 +556,12 @@ Bit16u save_cw; \ __asm__ volatile ( \ "fnstcw %0 \n" \ - "shll $4, %1 \n" \ "fldcw %3 \n" \ - "movl $128, %%eax \n" \ - "fldt (%2, %1) \n" \ - #op #szA " (%2, %%eax) \n" \ + "fldt %2 \n" \ + #op #szA " %1 \n" \ "fldcw %0 " \ - : "=m" (save_cw) \ - : "r" (TOP), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "eax", "memory" \ + : "=m" (save_cw), "=m" (fpu.p_regs[8]) \ + : "m" (fpu.p_regs[TOP]), "m" (fpu.cw_mask_all) \ ); #else #define FPUD_STORE(op,szI,szA) \ @@ -613,18 +569,14 @@ __asm__ volatile ( \ "fnstcw %1 \n" \ "fldcw %4 \n" \ - "shll $4, %2 \n" \ - "movl $8, %%eax \n" \ - "shl $4, %%eax \n" \ - "fldt (%3, %2) \n" \ - clx" \n" \ - #op #szA " (%3, %%eax) \n" \ + "fldt %3 \n" \ + "fclex \n" \ + #op #szA " %2 \n" \ "fnstsw %0 \n" \ "fldcw %1 " \ - : "=m" (new_sw), "=m" (save_cw) \ - : "r" (TOP), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "eax", "memory" \ - ); \ + : "=&am" (new_sw), "=m" (save_cw), "=m" (fpu.p_regs[8]) \ + : "m" (fpu.p_regs[TOP]), "m" (fpu.cw_mask_all) \ + ); \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); #endif @@ -632,15 +584,12 @@ #define FPUD_TRIG(op) \ Bit16u new_sw; \ __asm__ volatile ( \ - "shll $4, %1 \n" \ - "fldt (%2, %1) \n" \ + "fldt %1 \n" \ clx" \n" \ #op" \n" \ "fnstsw %0 \n" \ - "fstpt (%2, %1) " \ - : "=m" (new_sw) \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "memory" \ + "fstpt %1 " \ + : "=&am" (new_sw), "+m" (fpu.p_regs[TOP]) \ ); \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); @@ -648,24 +597,20 @@ #define FPUD_SINCOS() \ Bit16u new_sw; \ __asm__ volatile ( \ - "movl %1, %%eax \n" \ - "shll $4, %1 \n" \ - "decl %%eax \n" \ - "andl $7, %%eax \n" \ - "shll $4, %%eax \n" \ - "fldt (%2, %1) \n" \ + "fldt %1 \n" \ clx" \n" \ "fsincos \n" \ "fnstsw %0 \n" \ - "fstpt (%2, %%eax) \n" \ + "fstpt %2 \n" \ "movw %0, %%ax \n" \ "sahf \n" \ "jp 1f \n" \ - "fstpt (%2, %1) \n" \ + "fstpt %1 \n" \ "1: " \ - : "=m" (new_sw) \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "eax", "cc", "memory" \ + : "=m" (new_sw), "+m" (fpu.p_regs[TOP]), \ + "=m" (fpu.p_regs[(TOP-1)&7]) \ + : \ + : "ax", "cc" \ ); \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ if ((new_sw&0x0400)==0) FPU_PREP_PUSH(); @@ -674,24 +619,20 @@ #define FPUD_PTAN() \ Bit16u new_sw; \ __asm__ volatile ( \ - "movl %1, %%eax \n" \ - "shll $4, %1 \n" \ - "decl %%eax \n" \ - "andl $7, %%eax \n" \ - "shll $4, %%eax \n" \ - "fldt (%2, %1) \n" \ + "fldt %1 \n" \ clx" \n" \ "fptan \n" \ "fnstsw %0 \n" \ - "fstpt (%2, %%eax) \n" \ + "fstpt %2 \n" \ "movw %0, %%ax \n" \ "sahf \n" \ "jp 1f \n" \ - "fstpt (%2, %1) \n" \ + "fstpt %1 \n" \ "1: " \ - : "=m" (new_sw) \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "eax", "cc", "memory" \ + : "=m" (new_sw), "+m" (fpu.p_regs[TOP]), \ + "=m" (fpu.p_regs[(TOP-1)&7]) \ + : \ + : "ax", "cc" \ ); \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ if ((new_sw&0x0400)==0) FPU_PREP_PUSH(); @@ -700,40 +641,27 @@ #ifdef WEAK_EXCEPTIONS #define FPUD_XTRACT \ __asm__ volatile ( \ - "movl %0, %%eax \n" \ - "shll $4, %0 \n" \ - "decl %%eax \n" \ - "andl $7, %%eax \n" \ - "shll $4, %%eax \n" \ - "fldt (%1, %0) \n" \ + "fldt %0 \n" \ "fxtract \n" \ - "fstpt (%1, %%eax) \n" \ - "fstpt (%1, %0) " \ - : \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "eax", "memory" \ + "fstpt %1 \n" \ + "fstpt %0 " \ + : "+m" (fpu.p_regs[TOP]), "=m" (fpu.p_regs[(TOP-1)&7]) \ ); \ FPU_PREP_PUSH(); #else #define FPUD_XTRACT \ Bit16u new_sw; \ __asm__ volatile ( \ - "movl %1, %%eax \n" \ - "shll $4, %1 \n" \ - "decl %%eax \n" \ - "andl $7, %%eax \n" \ - "shll $4, %%eax \n" \ - "fldt (%2, %1) \n" \ + "fldt %1 \n" \ "fclex \n" \ "fxtract \n" \ "fnstsw %0 \n" \ - "fstpt (%2, %%eax) \n" \ - "fstpt (%2, %1) " \ - : "=m" (new_sw) \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "eax", "memory" \ + "fstpt %2 \n" \ + "fstpt %1 " \ + : "=&am" (new_sw), "+m" (fpu.p_regs[TOP]), \ + "=m" (fpu.p_regs[(TOP-1)&7]) \ ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ FPU_PREP_PUSH(); #endif @@ -743,36 +671,30 @@ Bit16u save_cw; \ __asm__ volatile ( \ "fnstcw %0 \n" \ - "fldcw %4 \n" \ - "shll $4, %2 \n" \ - "shll $4, %1 \n" \ - "fldt (%3, %2) \n" \ - "fldt (%3, %1) \n" \ + "fldcw %3 \n" \ + "fldt %2 \n" \ + "fldt %1 \n" \ #op" \n" \ - "fstpt (%3, %1) \n" \ + "fstpt %1 \n" \ "fldcw %0 " \ - : "=m" (save_cw) \ - : "r" (op1), "r" (op2), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ + : "=m" (save_cw), "+m" (fpu.p_regs[op1]) \ + : "m" (fpu.p_regs[op2]), "m" (fpu.cw_mask_all) \ ); #else #define FPUD_ARITH1(op) \ Bit16u new_sw,save_cw; \ __asm__ volatile ( \ "fnstcw %1 \n" \ - "fldcw %5 \n" \ - "shll $4, %3 \n" \ - "shll $4, %2 \n" \ - "fldt (%4, %3) \n" \ - "fldt (%4, %2) \n" \ - clx" \n" \ + "fldcw %4 \n" \ + "fldt %3 \n" \ + "fldt %2 \n" \ + "fclex \n" \ #op" \n" \ "fnstsw %0 \n" \ - "fstpt (%4, %2) \n" \ + "fstpt %2 \n" \ "fldcw %1 " \ - : "=m" (new_sw), "=m" (save_cw) \ - : "r" (op1), "r" (op2), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ + : "=&am" (new_sw), "=m" (save_cw), "+m" (fpu.p_regs[op1]) \ + : "m" (fpu.p_regs[op2]), "m" (fpu.cw_mask_all) \ ); \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); #endif @@ -783,32 +705,28 @@ Bit16u save_cw; \ __asm__ volatile ( \ "fnstcw %0 \n" \ - "fldcw %3 \n" \ - "shll $4, %1 \n" \ - "fldt (%2, %1) \n" \ + "fldcw %2 \n" \ + "fldt %1 \n" \ #op" \n" \ - "fstpt (%2, %1) \n" \ + "fstpt %1 \n" \ "fldcw %0 " \ - : "=m" (save_cw) \ - : "r" (op1), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ + : "=m" (save_cw), "+m" (fpu.p_regs[op1]) \ + : "m" (fpu.cw_mask_all) \ ); #else #define FPUD_ARITH1_EA(op) \ Bit16u new_sw,save_cw; \ __asm__ volatile ( \ "fnstcw %1 \n" \ - "fldcw %4 \n" \ - "shll $4, %2 \n" \ - "fldt (%3, %2) \n" \ - clx" \n" \ + "fldcw %3 \n" \ + "fldt %2 \n" \ + "fclex \n" \ #op" \n" \ "fnstsw %0 \n" \ - "fstpt (%3, %2) \n" \ + "fstpt %2 \n" \ "fldcw %1 " \ - : "=m" (new_sw), "=m" (save_cw) \ - : "r" (op1), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ + : "=&am" (new_sw), "=m" (save_cw), "+m" (fpu.p_regs[op1]) \ + : "m" (fpu.cw_mask_all) \ ); \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); #endif @@ -819,131 +737,82 @@ Bit16u save_cw; \ __asm__ volatile ( \ "fnstcw %0 \n" \ - "fldcw %3 \n" \ - "shll $4, %1 \n" \ - "fldt (%2, %1) \n" \ + "fldcw %2 \n" \ + "fldt %1 \n" \ #op" \n" \ - "fstpt (%2, %1) \n" \ + "fstpt %1 \n" \ "fldcw %0 " \ - : "=m" (save_cw) \ - : "r" (TOP), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ + : "=m" (save_cw), "+m" (fpu.p_regs[TOP]) \ + : "m" (fpu.cw_mask_all) \ ); #else #define FPUD_ARITH2(op) \ Bit16u new_sw,save_cw; \ __asm__ volatile ( \ "fnstcw %1 \n" \ - "fldcw %4 \n" \ - "shll $4, %2 \n" \ - "fldt (%3, %2) \n" \ - clx" \n" \ + "fldcw %3 \n" \ + "fldt %2 \n" \ + "fclex \n" \ #op" \n" \ "fnstsw %0 \n" \ - "fstpt (%3, %2) \n" \ + "fstpt %2 \n" \ "fldcw %1 " \ - : "=m" (new_sw), "=m" (save_cw) \ - : "r" (TOP), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ + : "=&am" (new_sw), "=m" (save_cw), "+m" (fpu.p_regs[TOP]) \ + : "m" (fpu.cw_mask_all) \ ); \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); #endif // handles fdiv,fdivr -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH3(op) \ - Bit16u save_cw; \ - __asm__ volatile ( \ - "fnstcw %0 \n" \ - "fldcw %4 \n" \ - "shll $4, %2 \n" \ - "shll $4, %1 \n" \ - "fldt (%3, %2) \n" \ - "fldt (%3, %1) \n" \ - #op" \n" \ - "fstpt (%3, %1) \n" \ - "fldcw %0 " \ - : "=m" (save_cw) \ - : "r" (op1), "r" (op2), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ - ); -#else +// (This is identical to FPUD_ARITH1 but without a WEAK_EXCEPTIONS variant) #define FPUD_ARITH3(op) \ Bit16u new_sw,save_cw; \ __asm__ volatile ( \ "fnstcw %1 \n" \ - "fldcw %5 \n" \ - "shll $4, %3 \n" \ - "shll $4, %2 \n" \ - "fldt (%4, %3) \n" \ - "fldt (%4, %2) \n" \ - "fclex \n" \ + "fldcw %4 \n" \ + "fldt %3 \n" \ + "fldt %2 \n" \ + "fclex \n" \ #op" \n" \ "fnstsw %0 \n" \ - "fstpt (%4, %2) \n" \ + "fstpt %2 \n" \ "fldcw %1 " \ - : "=m" (new_sw), "=m" (save_cw) \ - : "r" (op1), "r" (op2), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ + : "=&am" (new_sw), "=m" (save_cw), "+m" (fpu.p_regs[op1]) \ + : "m" (fpu.p_regs[op2]), "m" (fpu.cw_mask_all) \ ); \ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); -#endif // handles fdiv,fdivr -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH3_EA(op) \ - Bit16u save_cw; \ - __asm__ volatile ( \ - "fnstcw %0 \n" \ - "fldcw %3 \n" \ - "shll $4, %1 \n" \ - "fldt (%2, %1) \n" \ - #op" \n" \ - "fstpt (%2, %1) \n" \ - "fldcw %0 " \ - : "=m" (save_cw) \ - : "r" (op1), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ - ); -#else +// (This is identical to FPUD_ARITH1_EA but without a WEAK_EXCEPTIONS variant) #define FPUD_ARITH3_EA(op) \ Bit16u new_sw,save_cw; \ __asm__ volatile ( \ "fnstcw %1 \n" \ - "fldcw %4 \n" \ - "shll $4, %2 \n" \ - "fldt (%3, %2) \n" \ - "fclex \n" \ + "fldcw %3 \n" \ + "fldt %2 \n" \ + "fclex \n" \ #op" \n" \ "fnstsw %0 \n" \ - "fstpt (%3, %2) \n" \ + "fstpt %2 \n" \ "fldcw %1 " \ - : "=m" (new_sw), "=m" (save_cw) \ - : "r" (op1), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ + : "=&am" (new_sw), "=m" (save_cw), "+m" (fpu.p_regs[op1]) \ + : "m" (fpu.cw_mask_all) \ ); \ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); -#endif // handles fprem,fprem1,fscale -#define FPUD_REMINDER(op) \ +#define FPUD_REMAINDER(op) \ Bit16u new_sw; \ __asm__ volatile ( \ - "movl %1, %%eax \n" \ - "incl %%eax \n" \ - "andl $7, %%eax \n" \ - "shll $4, %%eax \n" \ - "shll $4, %1 \n" \ - "fldt (%2, %%eax) \n" \ - "fldt (%2, %1) \n" \ + "fldt %2 \n" \ + "fldt %1 \n" \ "fclex \n" \ #op" \n" \ "fnstsw %0 \n" \ - "fstpt (%2, %1) \n" \ + "fstpt %1 \n" \ "fstp %%st(0) " \ - : "=m" (new_sw) \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "eax", "memory" \ + : "=&am" (new_sw), "+m" (fpu.p_regs[TOP]) \ + : "m" (fpu.p_regs[(TOP+1)&7]) \ ); \ fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); @@ -951,16 +820,13 @@ #define FPUD_COMPARE(op) \ Bit16u new_sw; \ __asm__ volatile ( \ - "shll $4, %2 \n" \ - "shll $4, %1 \n" \ - "fldt (%3, %2) \n" \ - "fldt (%3, %1) \n" \ + "fldt %2 \n" \ + "fldt %1 \n" \ clx" \n" \ #op" \n" \ "fnstsw %0 " \ - : "=m" (new_sw) \ - : "r" (op1), "r" (op2), "r" (fpu.p_regs) \ - : "memory" \ + : "=&am" (new_sw) \ + : "m" (fpu.p_regs[op1]), "m" (fpu.p_regs[op2]) \ ); \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); @@ -968,14 +834,12 @@ #define FPUD_COMPARE_EA(op) \ Bit16u new_sw; \ __asm__ volatile ( \ - "shll $4, %1 \n" \ - "fldt (%2, %1) \n" \ + "fldt %1 \n" \ clx" \n" \ #op" \n" \ "fnstsw %0 " \ - : "=m" (new_sw) \ - : "r" (op1), "r" (fpu.p_regs) \ - : "memory" \ + : "=&am" (new_sw) \ + : "m" (fpu.p_regs[op1]) \ ); \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); @@ -983,15 +847,13 @@ #define FPUD_EXAMINE(op) \ Bit16u new_sw; \ __asm__ volatile ( \ - "shll $4, %1 \n" \ - "fldt (%2, %1) \n" \ + "fldt %1 \n" \ clx" \n" \ #op" \n" \ "fnstsw %0 \n" \ "fstp %%st(0) " \ - : "=m" (new_sw) \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "memory" \ + : "=&am" (new_sw) \ + : "m" (fpu.p_regs[TOP]) \ ); \ fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); @@ -999,40 +861,28 @@ #ifdef WEAK_EXCEPTIONS #define FPUD_WITH_POP(op) \ __asm__ volatile ( \ - "movl %0, %%eax \n" \ - "incl %%eax \n" \ - "andl $7, %%eax \n" \ - "shll $4, %%eax \n" \ - "shll $4, %0 \n" \ - "fldt (%1, %%eax) \n" \ - "fldt (%1, %0) \n" \ + "fldt %0 \n" \ + "fldt %1 \n" \ #op" \n" \ - "fstpt (%1, %%eax) \n" \ - : \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "eax", "memory" \ + "fstpt %0 \n" \ + : "+m" (fpu.p_regs[(TOP+1)&7]) \ + : "m" (fpu.p_regs[TOP]) \ ); \ FPU_FPOP(); #else #define FPUD_WITH_POP(op) \ Bit16u new_sw; \ __asm__ volatile ( \ - "movl %1, %%eax \n" \ - "incl %%eax \n" \ - "andl $7, %%eax \n" \ - "shll $4, %%eax \n" \ - "shll $4, %1 \n" \ - "fldt (%2, %%eax) \n" \ - "fldt (%2, %1) \n" \ + "fldt %1 \n" \ + "fldt %2 \n" \ "fclex \n" \ #op" \n" \ "fnstsw %0 \n" \ - "fstpt (%2, %%eax) \n" \ - : "=m" (new_sw) \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "eax", "memory" \ + "fstpt %1 \n" \ + : "=&am" (new_sw), "+m" (fpu.p_regs[(TOP+1)&7]) \ + : "m" (fpu.p_regs[TOP]) \ ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ FPU_FPOP(); #endif @@ -1040,40 +890,28 @@ #ifdef WEAK_EXCEPTIONS #define FPUD_FYL2X(op) \ __asm__ volatile ( \ - "movl %0, %%eax \n" \ - "incl %%eax \n" \ - "andl $7, %%eax \n" \ - "shll $4, %%eax \n" \ - "shll $4, %0 \n" \ - "fldt (%1, %%eax) \n" \ - "fldt (%1, %0) \n" \ + "fldt %0 \n" \ + "fldt %1 \n" \ #op" \n" \ - "fstpt (%1, %%eax) \n" \ - : \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "eax", "memory" \ + "fstpt %0 \n" \ + : "+m" (fpu.p_regs[(TOP+1)&7]) \ + : "m" (fpu.p_regs[TOP]) \ ); \ FPU_FPOP(); #else #define FPUD_FYL2X(op) \ Bit16u new_sw; \ __asm__ volatile ( \ - "movl %1, %%eax \n" \ - "incl %%eax \n" \ - "andl $7, %%eax \n" \ - "shll $4, %%eax \n" \ - "shll $4, %1 \n" \ - "fldt (%2, %%eax) \n" \ - "fldt (%2, %1) \n" \ + "fldt %1 \n" \ + "fldt %2 \n" \ "fclex \n" \ #op" \n" \ "fnstsw %0 \n" \ - "fstpt (%2, %%eax) \n" \ - : "=m" (new_sw) \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "eax", "memory" \ + "fstpt %1 \n" \ + : "=&am" (new_sw), "+m" (fpu.p_regs[(TOP+1)&7]) \ + : "m" (fpu.p_regs[TOP]) \ ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ + fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ FPU_FPOP(); #endif @@ -1081,13 +919,10 @@ #define FPUD_LOAD_CONST(op) \ FPU_PREP_PUSH(); \ __asm__ volatile ( \ - "shll $4, %0 \n" \ clx" \n" \ #op" \n" \ - "fstpt (%1, %0) \n" \ - : \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "memory" \ + "fstpt %0 \n" \ + : "=m" (fpu.p_regs[TOP]) \ ); #endif @@ -1353,11 +1188,11 @@ static void FPU_FRNDINT(void){ } static void FPU_FPREM(void){ - FPUD_REMINDER(fprem) + FPUD_REMAINDER(fprem) } static void FPU_FPREM1(void){ - FPUD_REMINDER(fprem1) + FPUD_REMAINDER(fprem1) } static void FPU_FXAM(void){ @@ -1382,7 +1217,7 @@ static void FPU_FYL2XP1(void){ } static void FPU_FSCALE(void){ - FPUD_REMINDER(fscale) + FPUD_REMAINDER(fscale) } From a8d8f7818a40025934c96162287dbf22267e4536 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Wed, 11 Dec 2013 13:59:24 +0000 Subject: [PATCH 3762/4131] There are only 248 default colors in the 256-color mode palette, and the remaining 8 colors are not altered by mode changes. Fixes font and mouse pointer colors in Voyages of Discovery. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3852 --- src/ints/int10.cpp | 17 ++++++++++++----- src/ints/int10_modes.cpp | 10 ++++++---- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 86af6f84..ccbb5097 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -712,11 +712,18 @@ static void INT10_Seg40Init(void) { static void INT10_InitVGA(void) { -/* switch to color mode and enable CPU access 480 lines */ - IO_Write(0x3c2,0xc3); - /* More than 64k */ - IO_Write(0x3c4,0x04); - IO_Write(0x3c5,0x02); + if (IS_EGAVGA_ARCH) { + /* switch to color mode and enable CPU access 480 lines */ + IO_Write(0x3c2,0xc3); + /* More than 64k */ + IO_Write(0x3c4,0x04); + IO_Write(0x3c5,0x02); + if (IS_VGA_ARCH) { + /* Initialize DAC */ + IO_Write(0x3c8,0); + for (Bitu i=0;i<3*256;i++) IO_Write(0x3c9,0); + } + } } static void SetupTandyBios(void) { diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index efc46eec..4c8d4609 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -326,7 +326,7 @@ static Bit8u cga_palette_2[64][3]= {0x15,0x15,0x15}, {0x15,0x15,0x3f}, {0x15,0x3f,0x15}, {0x15,0x3f,0x3f}, {0x3f,0x15,0x15}, {0x3f,0x15,0x3f}, {0x3f,0x3f,0x15}, {0x3f,0x3f,0x3f}, }; -static Bit8u vga_palette[256][3]= +static Bit8u vga_palette[248][3]= { {0x00,0x00,0x00},{0x00,0x00,0x2a},{0x00,0x2a,0x00},{0x00,0x2a,0x2a},{0x2a,0x00,0x00},{0x2a,0x00,0x2a},{0x2a,0x15,0x00},{0x2a,0x2a,0x2a}, {0x15,0x15,0x15},{0x15,0x15,0x3f},{0x15,0x3f,0x15},{0x15,0x3f,0x3f},{0x3f,0x15,0x15},{0x3f,0x15,0x3f},{0x3f,0x3f,0x15},{0x3f,0x3f,0x3f}, @@ -361,8 +361,7 @@ static Bit8u vga_palette[256][3]= {0x08,0x10,0x08},{0x08,0x10,0x0a},{0x08,0x10,0x0c},{0x08,0x10,0x0e},{0x08,0x10,0x10},{0x08,0x0e,0x10},{0x08,0x0c,0x10},{0x08,0x0a,0x10}, {0x0b,0x0b,0x10},{0x0c,0x0b,0x10},{0x0d,0x0b,0x10},{0x0f,0x0b,0x10},{0x10,0x0b,0x10},{0x10,0x0b,0x0f},{0x10,0x0b,0x0d},{0x10,0x0b,0x0c}, {0x10,0x0b,0x0b},{0x10,0x0c,0x0b},{0x10,0x0d,0x0b},{0x10,0x0f,0x0b},{0x10,0x10,0x0b},{0x0f,0x10,0x0b},{0x0d,0x10,0x0b},{0x0c,0x10,0x0b}, - {0x0b,0x10,0x0b},{0x0b,0x10,0x0c},{0x0b,0x10,0x0d},{0x0b,0x10,0x0f},{0x0b,0x10,0x10},{0x0b,0x0f,0x10},{0x0b,0x0d,0x10},{0x0b,0x0c,0x10}, - {0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00},{0x00,0x00,0x00} + {0x0b,0x10,0x0b},{0x0b,0x10,0x0c},{0x0b,0x10,0x0d},{0x0b,0x10,0x0f},{0x0b,0x10,0x10},{0x0b,0x0f,0x10},{0x0b,0x0d,0x10},{0x0b,0x0c,0x10} }; VideoModeBlock * CurMode; @@ -1229,7 +1228,10 @@ dac_text16: case M_LIN15: case M_LIN16: case M_LIN32: - for (i=0;i<256;i++) { + // IBM and clones use 248 default colors in the palette for 256-color mode. + // The last 8 colors of the palette are only initialized to 0 at BIOS init. + // Palette index is left at 0xf8 as on most clones, IBM leaves it at 0x10. + for (i=0;i<248;i++) { IO_Write(0x3c9,vga_palette[i][0]); IO_Write(0x3c9,vga_palette[i][1]); IO_Write(0x3c9,vga_palette[i][2]); From 5a3e91643da50c0847b5190c814d8d355b3ae1a3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 5 Jan 2014 12:19:25 +0000 Subject: [PATCH 3763/4131] Some corrections. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3853 --- src/gui/sdl_mapper.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 1c6b700a..958c7a28 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -520,11 +520,12 @@ protected: }; #define MAX_VJOY_BUTTONS 8 - +#define MAX_VJOY_HAT 16 +#define MAX_VJOY_AXIS 8 static struct { bool button_pressed[MAX_VJOY_BUTTONS]; - Bit16s axis_pos[8]; - bool hat_pressed[16]; + Bit16s axis_pos[MAX_VJOY_AXIS]; + bool hat_pressed[MAX_VJOY_HAT]; } virtual_joysticks[2]; @@ -2390,15 +2391,17 @@ void MAPPER_StartUp(Section * sec) { mapper.sticks.num=0; mapper.sticks.num_groups=0; Bitu i; - for (i=0; i<16; i++) { + for (i=0; i Date: Sun, 12 Jan 2014 12:36:13 +0000 Subject: [PATCH 3764/4131] TOP is used as 32 bit in dynrec core Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3854 --- include/fpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fpu.h b/include/fpu.h index cea691bd..7fdb3de2 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -86,7 +86,7 @@ typedef struct { FPU_Tag tags[9]; Bit16u cw,cw_mask_all; Bit16u sw; - Bitu top; + Bit32u top; FPU_Round round; } FPU_rec; From 3ddbfe949a1320fd0f88f6466540ac3274a0a0d3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 12 Jan 2014 12:38:31 +0000 Subject: [PATCH 3765/4131] fpu.sw is 16 bit(jmarsh) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3855 --- src/cpu/core_dynrec/dyn_fpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_dynrec/dyn_fpu.h b/src/cpu/core_dynrec/dyn_fpu.h index 36600106..81498c6a 100644 --- a/src/cpu/core_dynrec/dyn_fpu.h +++ b/src/cpu/core_dynrec/dyn_fpu.h @@ -534,7 +534,7 @@ static void dyn_fpu_esc5(){ 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_mov_word_to_reg(FC_OP2,(void*)(&fpu.sw),false); gen_call_function_RR((void*)&mem_writew,FC_OP1,FC_OP2); break; default: From 7c25fb468470dff701900749dd769941a083c802 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 12 Jan 2014 12:54:58 +0000 Subject: [PATCH 3766/4131] reg_eip is 32 bit(jmarsh) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3856 --- src/cpu/core_dynrec/decoder_basic.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index 89cd49a0..079383bc 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -490,7 +490,8 @@ static INLINE void dyn_set_eip_end(void) { // set reg_eip to the start of the next instruction plus an offset (imm) static INLINE void dyn_set_eip_end(HostReg reg,Bit32u imm=0) { - gen_mov_word_to_reg(reg,®_eip,decode.big_op); + gen_mov_word_to_reg(reg,®_eip,true); //get_extend_word will mask off the upper bits + //gen_mov_word_to_reg(reg,®_eip,decode.big_op); gen_add_imm(reg,(Bit32u)(decode.code-decode.code_start+imm)); if (!decode.big_op) gen_extend_word(false,reg); } From 14ac0f241f3127d9b7db320d15e6edf0c03e1d89 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 12 Jan 2014 13:41:01 +0000 Subject: [PATCH 3767/4131] Stop rethrowing the error, as SDL doesn't know what to do with it anyways. Fix a couple of formatting related warnings/errors. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3857 --- src/gui/sdlmain.cpp | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 1c8f1783..8741f502 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -229,7 +229,7 @@ bool startup_state_capslock=false; void GFX_SetTitle(Bit32s cycles,Bits frameskip,bool paused){ char title[200]={0}; static Bit32s internal_cycles=0; - static Bits internal_frameskip=0; + static Bit32s internal_frameskip=0; if(cycles != -1) internal_cycles = cycles; if(frameskip != -1) internal_frameskip = frameskip; if(CPU_CycleAutoAdjust) { @@ -464,7 +464,7 @@ Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,G sdl.draw.scalex=scalex; sdl.draw.scaley=scaley; - Bitu bpp=0; + int bpp=0; Bitu retFlags = 0; if (sdl.blit.surface) { @@ -495,7 +495,7 @@ dosurface: SDL_FULLSCREEN | ((flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE) | (sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0)|SDL_HWPALETTE); if (sdl.surface == NULL) - E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",width,height,bpp,SDL_GetError()); + E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",(int)width,(int)height,bpp,SDL_GetError()); } } else { sdl.clip.x=0;sdl.clip.y=0; @@ -519,7 +519,7 @@ dosurface: } #endif if (sdl.surface == NULL) - E_Exit("Could not set windowed video mode %ix%i-%i: %s",width,height,bpp,SDL_GetError()); + E_Exit("Could not set windowed video mode %ix%i-%i: %s",(int)width,(int)height,bpp,SDL_GetError()); } if (sdl.surface) { switch (sdl.surface->format->BitsPerPixel) { @@ -1656,7 +1656,7 @@ static void show_warning(char const * const message) { if ( !sdl.inited && SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE) < 0 ) textonly = true; sdl.inited = true; #endif - printf(message); + printf("%s",message); if(textonly) return; if(!sdl.surface) sdl.surface = SDL_SetVideoMode(640,400,0,0); if(!sdl.surface) return; @@ -2043,16 +2043,10 @@ int main(int argc, char* argv[]) { } catch (int){ - ;//nothing pressed killswitch + ; //nothing, pressed killswitch } catch(...){ -#if defined (WIN32) - sticky_keys(true); -#endif - //Force visible mouse to end user. Somehow this sometimes doesn't happen - SDL_WM_GrabInput(SDL_GRAB_OFF); - SDL_ShowCursor(SDL_ENABLE); - throw;//dunno what happened. rethrow for sdl to catch + ; // Unknown error, let's just exit. } #if defined (WIN32) sticky_keys(true); //Might not be needed if the shutdown function switches to windowed mode, but it doesn't hurt From ee0367653bc28640cef7509f35d99e8dcf0a4b82 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 12 Jan 2014 13:43:47 +0000 Subject: [PATCH 3768/4131] stdprn is now really prn and you can't read from it. Fixes a weird runtime that reads the PRN handle. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3858 --- src/dos/dos_devices.cpp | 4 ++++ src/shell/shell.cpp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index b6659816..79d00eae 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -60,6 +60,10 @@ class device_LPT1 : public device_NUL { public: device_LPT1() { SetName("LPT1");} Bit16u GetInformation(void) { return 0x80A0; } + bool Read(Bit8u* data,Bit16u * size){ + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; + } }; bool DOS_Device::Read(Bit8u * data,Bit16u * size) { diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 9cce9285..7bbcd143 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -651,7 +651,7 @@ void SHELL_Init() { DOS_ForceDuplicateEntry(1,0); /* "new" STDIN */ DOS_ForceDuplicateEntry(1,2); /* STDERR */ DOS_OpenFile("CON",OPEN_READWRITE,&dummy); /* STDAUX */ - DOS_OpenFile("CON",OPEN_READWRITE,&dummy); /* STDPRN */ + DOS_OpenFile("PRN",OPEN_READWRITE,&dummy); /* STDPRN */ psp.SetParent(psp_seg); /* Set the environment */ From 7f00bd4b34602575f754bd2e6369cd1c44c8cfbd Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Sun, 8 Jun 2014 00:00:53 +0000 Subject: [PATCH 3769/4131] Implement VGA memory wrapping for the wrapping line also in vgaonly rendering. Fixes black line in Keen. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3859 --- src/hardware/vga_draw.cpp | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 1970c063..e73296f7 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -197,10 +197,30 @@ static Bit8u * VGA_Draw_Linear_Line(Bitu vidstart, Bitu /*line*/) { } static Bit8u * VGA_Draw_Xlat16_Linear_Line(Bitu vidstart, Bitu /*line*/) { - Bit8u *ret = &vga.draw.linear_base[ vidstart & vga.draw.linear_mask ]; + Bitu offset = vidstart & vga.draw.linear_mask; + Bit8u *ret = &vga.draw.linear_base[offset]; Bit16u* temps = (Bit16u*) TempLine; - for(Bitu i = 0; i < vga.draw.line_length; i++) { - temps[i]=vga.dac.xlat16[ret[i]]; + + // see VGA_Draw_Linear_Line + if (GCC_UNLIKELY((vga.draw.line_length + offset)& ~vga.draw.linear_mask)) { + Bitu end = (offset + vga.draw.line_length) & vga.draw.linear_mask; + + // assuming lines not longer than 4096 pixels + Bitu wrapped_len = end & 0xFFF; + Bitu unwrapped_len = vga.draw.line_length-wrapped_len; + + // unwrapped chunk: to top of memory block + for(Bitu i = 0; i < unwrapped_len; i++) + temps[i]=vga.dac.xlat16[ret[i]]; + + // wrapped chunk: from base of memory block + for(Bitu i = 0; i < wrapped_len; i++) + temps[i + unwrapped_len]=vga.dac.xlat16[vga.draw.linear_base[i]]; + + } else { + for(Bitu i = 0; i < vga.draw.line_length; i++) { + temps[i]=vga.dac.xlat16[ret[i]]; + } } return TempLine; } From bb807af8c7e69e58afeff831594c35f2a86d5646 Mon Sep 17 00:00:00 2001 From: Ralf Grillenberger Date: Mon, 9 Jun 2014 19:07:14 +0000 Subject: [PATCH 3770/4131] Use PCJr specific method to clear the video RAM. Also don't scroll at unspecified video page. Fixes issues with KQ1 and KQ2. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3860 --- src/ints/int10_char.cpp | 3 ++- src/ints/int10_modes.cpp | 11 ++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 9915b787..415a0589 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -215,7 +215,8 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit (real_readb(BIOSMEM_SEG, BIOSMEM_CRTCPU_PAGE) >> 3) & 0x7; base = cpupage << 14; - base += page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); + if (page!=0xff) + base += page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); } } diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 4c8d4609..e27a4e31 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -385,9 +385,18 @@ static void FinishSetMode(bool clearmem) { /* Clear video memory if needs be */ if (clearmem) { switch (CurMode->type) { + case M_TANDY16: + if ((machine==MCH_PCJR) && (CurMode->mode >= 9)) { + // PCJR cannot access the full 32k at 0xb800 + for (Bit16u ct=0;ct<16*1024;ct++) { + // 0x1800 is the last 32k block in 128k, as set in the CRTCPU_PAGE register + real_writew(0x1800,ct*2,0x0000); + } + break; + } + // fall-through case M_CGA4: case M_CGA2: - case M_TANDY16: for (Bit16u ct=0;ct<16*1024;ct++) { real_writew( 0xb800,ct*2,0x0000); } From a59544bf7d825cbf275ddf2b673d7c4cf83966a5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 18 Jun 2014 14:32:40 +0000 Subject: [PATCH 3771/4131] Add Exit conditions for stack over/underflows It's bad to continue when these states happen. Let's see if a game triggers it. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3861 --- src/fpu/fpu_instructions.h | 8 ++++---- src/fpu/fpu_instructions_x86.h | 8 +++++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 0789d497..fa59e4ca 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2014 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,9 +42,7 @@ static void FPU_FNOP(void){ } static void FPU_PUSH(double in){ - TOP = (TOP - 1) &7; - //actually check if empty - fpu.tags[TOP] = TAG_Valid; + FPU_PREP_PUSH(); fpu.regs[TOP].d = in; // LOG(LOG_FPU,LOG_ERROR)("Pushed at %d %g to the stack",newtop,in); return; @@ -52,10 +50,12 @@ static void FPU_PUSH(double in){ static void FPU_PREP_PUSH(void){ TOP = (TOP - 1) &7; + if (GCC_UNLIKELY(fpu.tags[TOP] != TAG_Empty)) E_Exit("FPU stack overflow"); fpu.tags[TOP] = TAG_Valid; } static void FPU_FPOP(void){ + if (GCC_UNLIKELY(fpu.tags[TOP] == TAG_Empty)) E_Exit("FPU stack underflow"); fpu.tags[TOP]=TAG_Empty; //maybe set zero in it as well TOP = ((TOP+1)&7); diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index 1d51e26e..21b2f93d 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2014 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 @@ -957,11 +957,13 @@ static void FPU_FNOP(void){ static void FPU_PREP_PUSH(void){ TOP = (TOP - 1) &7; - fpu.tags[TOP]=TAG_Valid; + if (GCC_UNLIKELY(fpu.tags[TOP] != TAG_Empty)) E_Exit("FPU stack overflow"); + fpu.tags[TOP] = TAG_Valid; } static void FPU_FPOP(void){ - fpu.tags[TOP]=TAG_Empty; + if (GCC_UNLIKELY(fpu.tags[TOP] == TAG_Empty)) E_Exit("FPU stack underflow"); + fpu.tags[TOP] = TAG_Empty; TOP = ((TOP+1)&7); } From 37fac15aea596c42ed2ae4184243b42db83a4be3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 18 Jun 2014 14:34:33 +0000 Subject: [PATCH 3772/4131] lower the influence of the aspect table correction trick when using high scale factors (320x200 =>2000x1200) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3862 --- src/gui/render.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 67435218..66cf22cc 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -519,7 +519,7 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool return; } if ( ratio > 1 ) { - double target = height * ratio + 0.1; + double target = height * ratio + 0.025; ratio = target / height; } else { //This would alter the width of the screen, we don't care about rounding errors here From 01a09d7086e312e06e7108d6c97b4e59cf0012f1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 18 Jun 2014 14:39:49 +0000 Subject: [PATCH 3773/4131] Improve the results of the windowed resolution calculation so that the one off errors are gone. Create a small wrapper function around SDL_SetVideoMode, so that we don't set the same mode twice. Both changes benefit people who record footage with external recording software and it speeds up mode video mode changes. (especially with aspect=true) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3863 --- src/gui/sdlmain.cpp | 69 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 15 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 8741f502..92ef1993 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2014 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 @@ -220,6 +220,41 @@ struct SDL_Block { static SDL_Block sdl; +#define SETMODE_SAVES 1 //Don't set Video Mode if nothing changes. +#define SETMODE_SAVES_CLEAR 0 //Clear the screen, when the Video Mode is reused +SDL_Surface* SDL_SetVideoMode_Wrap(int width,int height,int bpp,Bit32u flags){ +#if SETMODE_SAVES + static int i_height = 0; + static int i_width = 0; + static int i_bpp = 0; + static Bit32u i_flags = 0; + if (sdl.surface != NULL && height == i_height && width == i_width && bpp == i_bpp && flags == i_flags) { + // I don't see a difference, so disabled for now, as the code isn't finished either +#if SETMODE_SAVES_CLEAR + //TODO clear it. + if ((flags & SDL_OPENGL)==0) + SDL_FillRect(sdl.surface,NULL,SDL_MapRGB(sdl.surface->format,0,0,0)); + else { + glClearColor (0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + SDL_GL_SwapBuffers(); + } +#endif + return sdl.surface; + } + +#endif + SDL_Surface* s = SDL_SetVideoMode(width,height,bpp,flags); +#if SETMODE_SAVES + if (s == NULL) return s; //Only store when successful + i_height = height; + i_width = width; + i_bpp = bpp; + i_flags = flags; +#endif + return s; +} + extern const char* RunningProgram; extern bool CPU_CycleAutoAdjust; //Globals for keyboard initialisation @@ -418,15 +453,19 @@ static SDL_Surface * GFX_SetupSurfaceScaled(Bit32u sdl_flags, Bit32u bpp) { double ratio_h=(double)fixedHeight/(sdl.draw.height*sdl.draw.scaley); if ( ratio_w < ratio_h) { sdl.clip.w=fixedWidth; - sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley*ratio_w); - } else { - sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex*ratio_h); - sdl.clip.h=(Bit16u)fixedHeight; + sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley*ratio_w + 0.1); //possible rounding issues + } else { + /* + * The 0.4 is there to correct for rounding issues. + * (partly caused by the rounding issues fix in RENDER_SetSize) + */ + sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex*ratio_h + 0.4); + sdl.clip.h=(Bit16u)fixedHeight; } if (sdl.desktop.fullscreen) - sdl.surface = SDL_SetVideoMode(fixedWidth,fixedHeight,bpp,sdl_flags); + sdl.surface = SDL_SetVideoMode_Wrap(fixedWidth,fixedHeight,bpp,sdl_flags); else - sdl.surface = SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags); + sdl.surface = SDL_SetVideoMode_Wrap(sdl.clip.w,sdl.clip.h,bpp,sdl_flags); if (sdl.surface && sdl.surface->flags & SDL_FULLSCREEN) { sdl.clip.x=(Sint16)((sdl.surface->w-sdl.clip.w)/2); sdl.clip.y=(Sint16)((sdl.surface->h-sdl.clip.h)/2); @@ -439,7 +478,7 @@ static SDL_Surface * GFX_SetupSurfaceScaled(Bit32u sdl_flags, Bit32u bpp) { sdl.clip.x=0;sdl.clip.y=0; sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex); sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley); - sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags); + sdl.surface=SDL_SetVideoMode_Wrap(sdl.clip.w,sdl.clip.h,bpp,sdl_flags); return sdl.surface; } } @@ -485,13 +524,13 @@ dosurface: if (sdl.desktop.full.fixed) { sdl.clip.x=(Sint16)((sdl.desktop.full.width-width)/2); sdl.clip.y=(Sint16)((sdl.desktop.full.height-height)/2); - sdl.surface=SDL_SetVideoMode(sdl.desktop.full.width,sdl.desktop.full.height,bpp, + sdl.surface=SDL_SetVideoMode_Wrap(sdl.desktop.full.width,sdl.desktop.full.height,bpp, SDL_FULLSCREEN | ((flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE) | (sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0) | SDL_HWPALETTE); if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",sdl.desktop.full.width,sdl.desktop.full.height,bpp,SDL_GetError()); } else { sdl.clip.x=0;sdl.clip.y=0; - sdl.surface=SDL_SetVideoMode(width,height,bpp, + sdl.surface=SDL_SetVideoMode_Wrap(width,height,bpp, SDL_FULLSCREEN | ((flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE) | (sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0)|SDL_HWPALETTE); if (sdl.surface == NULL) @@ -499,7 +538,7 @@ dosurface: } } else { sdl.clip.x=0;sdl.clip.y=0; - sdl.surface=SDL_SetVideoMode(width,height,bpp,(flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE); + sdl.surface=SDL_SetVideoMode_Wrap(width,height,bpp,(flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE); #ifdef WIN32 if (sdl.surface == NULL) { SDL_QuitSubSystem(SDL_INIT_VIDEO); @@ -514,7 +553,7 @@ dosurface: } SDL_InitSubSystem(SDL_INIT_VIDEO); GFX_SetIcon(); //Set Icon again - sdl.surface = SDL_SetVideoMode(width,height,bpp,SDL_HWSURFACE); + sdl.surface = SDL_SetVideoMode_Wrap(width,height,bpp,SDL_HWSURFACE); if(sdl.surface) GFX_SetTitle(-1,-1,false); //refresh title. } #endif @@ -1232,7 +1271,7 @@ static void GUI_StartUp(Section * sec) { sdl.overlay=0; #if C_OPENGL if(sdl.desktop.want_type==SCREEN_OPENGL){ /* OPENGL is requested */ - sdl.surface=SDL_SetVideoMode(640,400,0,SDL_OPENGL); + sdl.surface=SDL_SetVideoMode_Wrap(640,400,0,SDL_OPENGL); if (sdl.surface == NULL) { LOG_MSG("Could not initialize OpenGL, switching back to surface"); sdl.desktop.want_type=SCREEN_SURFACE; @@ -1263,7 +1302,7 @@ static void GUI_StartUp(Section * sec) { #endif //OPENGL /* Initialize screen for first time */ - sdl.surface=SDL_SetVideoMode(640,400,0,0); + sdl.surface=SDL_SetVideoMode_Wrap(640,400,0,0); if (sdl.surface == NULL) E_Exit("Could not initialize video: %s",SDL_GetError()); sdl.desktop.bpp=sdl.surface->format->BitsPerPixel; if (sdl.desktop.bpp==24) { @@ -1658,7 +1697,7 @@ static void show_warning(char const * const message) { #endif printf("%s",message); if(textonly) return; - if(!sdl.surface) sdl.surface = SDL_SetVideoMode(640,400,0,0); + if(!sdl.surface) sdl.surface = SDL_SetVideoMode_Wrap(640,400,0,0); if(!sdl.surface) return; #if SDL_BYTEORDER == SDL_BIG_ENDIAN Bit32u rmask = 0xff000000; From 9cbce79ce3668b3eed64636f30dd3b6a62e5c27b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 18 Jun 2014 14:52:23 +0000 Subject: [PATCH 3774/4131] reordering. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3864 --- src/fpu/fpu_instructions.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index fa59e4ca..1b8329ce 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -41,6 +41,12 @@ static void FPU_FNOP(void){ return; } +static void FPU_PREP_PUSH(void){ + TOP = (TOP - 1) &7; + if (GCC_UNLIKELY(fpu.tags[TOP] != TAG_Empty)) E_Exit("FPU stack overflow"); + fpu.tags[TOP] = TAG_Valid; +} + static void FPU_PUSH(double in){ FPU_PREP_PUSH(); fpu.regs[TOP].d = in; @@ -48,11 +54,6 @@ static void FPU_PUSH(double in){ return; } -static void FPU_PREP_PUSH(void){ - TOP = (TOP - 1) &7; - if (GCC_UNLIKELY(fpu.tags[TOP] != TAG_Empty)) E_Exit("FPU stack overflow"); - fpu.tags[TOP] = TAG_Valid; -} static void FPU_FPOP(void){ if (GCC_UNLIKELY(fpu.tags[TOP] == TAG_Empty)) E_Exit("FPU stack underflow"); From fb71bc6ca89d048f3618a0f606c2c025ee6a6f72 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 18 Jun 2014 15:51:02 +0000 Subject: [PATCH 3775/4131] Aspect correct text modes as well. I hope I got the ratios right. Let me know if I messed up. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3865 --- src/hardware/vga_draw.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index e73296f7..0f10096e 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1421,7 +1421,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { VGA_DrawLine=VGA_Draw_1BPP_Line; break; case M_TEXT: - aspect_ratio=1.0; + aspect_ratio=1.2; vga.draw.blocks=width; doublewidth=(vga.seq.clocking_mode & 0x8) > 0; if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) { @@ -1432,6 +1432,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { } else { vga.draw.char9dot = true; width*=9; + aspect_ratio*=1.125; } VGA_DrawLine=VGA_TEXT_Xlat16_Draw_Line; bpp=16; @@ -1491,14 +1492,14 @@ void VGA_SetupDrawing(Bitu /*val*/) { break; case M_TANDY_TEXT: doublewidth=(vga.tandy.mode_control & 0x1)==0; - aspect_ratio=1; + aspect_ratio=1.2; doubleheight=true; vga.draw.blocks=width; width<<=3; VGA_DrawLine=VGA_TEXT_Draw_Line; break; case M_HERC_TEXT: - aspect_ratio=1; + aspect_ratio=((double)480)/((double)350); vga.draw.blocks=width; width<<=3; VGA_DrawLine=VGA_TEXT_Herc_Draw_Line; From 56dfdb8f9e0e4f521684149f3848984e3941568d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 18 Jun 2014 15:53:05 +0000 Subject: [PATCH 3776/4131] 25*14=350 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3866 --- src/ints/int10_modes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index e27a4e31..e8609756 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -258,7 +258,7 @@ VideoModeBlock ModeList_OTHER[]={ }; VideoModeBlock Hercules_Mode= -{ 0x007 ,M_TEXT ,640 ,400 ,80 ,25 ,8 ,14 ,1 ,0xB0000 ,0x1000 ,97 ,25 ,80 ,25 ,0 }; +{ 0x007 ,M_TEXT ,640 ,350 ,80 ,25 ,8 ,14 ,1 ,0xB0000 ,0x1000 ,97 ,25 ,80 ,25 ,0 }; static Bit8u text_palette[64][3]= { From d815845c60ee37cb237e2dff02cfbb29af8c1493 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 18 Jun 2014 18:49:42 +0000 Subject: [PATCH 3777/4131] the mapper needs to use the wrapper as well. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3867 --- src/gui/sdl_mapper.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 958c7a28..8563f15b 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2014 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 @@ -2312,6 +2312,8 @@ void MAPPER_Run(bool pressed) { MAPPER_RunInternal(); } +SDL_Surface* SDL_SetVideoMode_Wrap(int width,int height,int bpp,Bit32u flags); + void MAPPER_RunInternal() { int cursor = SDL_ShowCursor(SDL_QUERY); SDL_ShowCursor(SDL_ENABLE); @@ -2323,7 +2325,7 @@ void MAPPER_RunInternal() { /* Be sure that there is no update in progress */ GFX_EndUpdate( 0 ); - mapper.surface=SDL_SetVideoMode(640,480,8,0); + mapper.surface=SDL_SetVideoMode_Wrap(640,480,8,0); if (mapper.surface == NULL) E_Exit("Could not initialize video mode for mapper: %s",SDL_GetError()); /* Set some palette entries */ From 544c1a2fe51223450580395f6e90f4ab2686abe2 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Thu, 19 Jun 2014 18:51:42 +0000 Subject: [PATCH 3778/4131] Illegal memory reads have all bits set. Fixes early (and buggy) shareware versions of Shadow Warrior. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3868 --- src/hardware/memory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 02827a1b..5b115193 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -73,7 +73,7 @@ public: LOG_MSG("Illegal read from %x, CS:IP %8x:%8x",addr,SegValue(cs),reg_eip); } #endif - return 0; + return 0xff; } void writeb(PhysPt addr,Bitu val) { #if C_DEBUG From 730c2d3cd98280694b32b80d0cb0f138dcf37638 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 27 Jun 2014 09:02:08 +0000 Subject: [PATCH 3779/4131] Run with -mno-ms-bitfields if the compiler supports it as the ms-bitfields are turned on by default on some hosts, but they are broken https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3869 --- configure.ac | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/configure.ac b/configure.ac index a683bfda..8cf01bdf 100644 --- a/configure.ac +++ b/configure.ac @@ -169,6 +169,21 @@ int x=10;if( __builtin_expect ((x==1),0) ) ; #switch language back AC_LANG_POP(C++) +dnl test if compiler supports -mno-ms-bitfields as it is bugged +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991 +BACKUP_CFLAGS="$CFLAGS" +CFLAGS="-mno-ms-bitfields" +AC_MSG_CHECKING(if compiler supports -mno-ms-bitfields) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([ +void blah(){ +; +} +])],[ +AC_MSG_RESULT([yes]) +CXXFLAGS="$CXXFLAGS -mno-ms-bitfields" +],[AC_MSG_RESULT([no])]) +CFLAGS="$BACKUP_CFLAGS" + 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)]), From 2077da8e29ad1708a64de73c655c8d67ff6ef6a8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 14 Oct 2014 14:34:48 +0000 Subject: [PATCH 3780/4131] Allow the windows and menu keys to be mappable on Linux and Windows. Fixes bug 406 on sf.net and topic 380510 on vogons. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3870 --- src/gui/sdl_mapper.cpp | 44 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 8563f15b..47ce677d 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -361,7 +361,7 @@ typedef char assert_right_size [MAX_SCANCODES == (sizeof(sdlkey_map)/sizeof(sdlk #else // !MACOSX -#define MAX_SCANCODES 212 +#define MAX_SCANCODES 0xdf static SDLKey sdlkey_map[MAX_SCANCODES]={SDLK_UNKNOWN,SDLK_ESCAPE, SDLK_1,SDLK_2,SDLK_3,SDLK_4,SDLK_5,SDLK_6,SDLK_7,SDLK_8,SDLK_9,SDLK_0, /* 0x0c: */ @@ -380,13 +380,28 @@ static SDLKey sdlkey_map[MAX_SCANCODES]={SDLK_UNKNOWN,SDLK_ESCAPE, SDLK_KP7,SDLK_KP8,SDLK_KP9,SDLK_KP_MINUS,SDLK_KP4,SDLK_KP5,SDLK_KP6,SDLK_KP_PLUS, SDLK_KP1,SDLK_KP2,SDLK_KP3,SDLK_KP0,SDLK_KP_PERIOD, SDLK_UNKNOWN,SDLK_UNKNOWN, - SDLK_LESS,SDLK_F11,SDLK_F12, - Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z, - Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z, - Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z, - /* 0xb7: */ - Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z - /* 0xd4: ... */ + SDLK_LESS,SDLK_F11,SDLK_F12, Z, Z, Z, Z, Z, Z, Z, + /* 0x60: */ + Z,Z,Z,Z, Z,Z,Z,Z, Z,Z,Z,Z, Z,Z,Z,Z, + /* 0x70: */ + Z,Z,Z,Z, Z,Z,Z,Z, Z,Z,Z,Z, Z,Z,Z,Z, + /* 0x80: */ + Z,Z,Z,Z, Z,Z,Z,Z, Z,Z,Z,Z, Z,Z,Z,Z, + /* 0x90: */ + Z,Z,Z,Z, Z,Z,Z,Z, Z,Z,Z,Z, Z,Z,Z,Z, + /* 0xA0: */ + Z,Z,Z,Z, Z,Z,Z,Z, Z,Z,Z,Z, Z,Z,Z,Z, + /* 0xB0: */ + Z,Z,Z,Z, Z,Z,Z,Z, Z,Z,Z,Z, Z,Z,Z,Z, + /* 0xC0: */ + Z,Z,Z,Z, Z,Z,Z,Z, Z,Z,Z,Z, Z,Z,Z,Z, + /* 0xD0: */ + Z,Z,Z,Z, Z,Z,Z,Z, Z,Z,Z,Z, Z,Z//,Z,Z, + /* 0xE0: */ + //Z,Z,Z,Z, Z,Z,Z,Z, Z,Z,Z,Z, Z,Z,Z,Z, + /* 0xF0: */ +// Z,Z,Z,Z, Z,Z,Z,Z, Z,Z,Z,Z, Z,Z//,Z,Z + }; #endif @@ -394,6 +409,7 @@ static SDLKey sdlkey_map[MAX_SCANCODES]={SDLK_UNKNOWN,SDLK_ESCAPE, SDLKey MapSDLCode(Bitu skey) { +// LOG_MSG("MapSDLCode %d %X",skey,skey); if (usescancodes) { if (skey Date: Tue, 14 Oct 2014 14:54:41 +0000 Subject: [PATCH 3781/4131] Workaround 2 issues, when starting the keymapper with output=opengl,aspect=true on windows. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3871 --- src/gui/sdlmain.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 92ef1993..2fab4928 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -243,6 +243,23 @@ SDL_Surface* SDL_SetVideoMode_Wrap(int width,int height,int bpp,Bit32u flags){ return sdl.surface; } +#endif +#ifdef WIN32 + //SDL seems to crash if we are in OpenGL mode currently and change to exactly the same size without OpenGL. + //This happens when DOSBox is in textmode with aspect=true and output=opengl and the mapper is started. + //The easiest solution is to change the size. The mapper doesn't care. (PART PXX) + + //Also we have to switch back to windowed mode first, as else it may crash as well. + //Bug: we end up with a locked mouse cursor, but at least that beats crashing. (output=opengl,aspect=true,fullscreen=true) + if((i_flags&SDL_OPENGL) && !(flags&SDL_OPENGL) && (i_flags&SDL_FULLSCREEN) && !(flags&SDL_FULLSCREEN)){ + GFX_SwitchFullScreen(); + return SDL_SetVideoMode_Wrap(width,height,bpp,flags); + } + + //PXX + if ((i_flags&SDL_OPENGL) && !(flags&SDL_OPENGL) && height==i_height && width==i_width && height==480) { + height++; + } #endif SDL_Surface* s = SDL_SetVideoMode(width,height,bpp,flags); #if SETMODE_SAVES @@ -1944,7 +1961,7 @@ int main(int argc, char* argv[]) { sdl.inited = true; #ifndef DISABLE_JOYSTICK - //Initialise Joystick seperately. This way we can warn when it fails instead + //Initialise Joystick separately. This way we can warn when it fails instead //of exiting the application if( SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0 ) LOG_MSG("Failed to init joystick support"); #endif From 952c48c5cf6fed5c49a44a197e1a0ab4fa5bee9e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 6 Nov 2014 18:58:14 +0000 Subject: [PATCH 3782/4131] This seems to make i686-MinGW-w64 happy. Combination of patch 261 on SF.net and input on IRC Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3872 --- src/dos/cdrom_aspi_win32.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index d1d5a930..9482a1e1 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -33,6 +33,9 @@ #include #include // Ioctl stuff #else +#ifdef __MINGW64_VERSION_MAJOR +#include +#endif #include "ddk/ntddcdrm.h" // Ioctl stuff #include "ddk/ntddscsi.h" #endif From 767a95380b8b7a68a80bbf333b66c4060c77b109 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 21 Nov 2014 09:38:36 +0000 Subject: [PATCH 3783/4131] mirror cache handling with dynrec core with allocation stuff for 64 bit things Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3873 --- src/cpu/core_dyn_x86/cache.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 2b817f16..ec78aeba 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -510,7 +510,7 @@ static void cache_init(bool enable) { #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=(Bit8u*)(((Bitu)cache_code_start_ptr + PAGESIZE_TEMP-1) & ~(PAGESIZE_TEMP-1)); //Bitu is same size as a pointer. cache_code_link_blocks=cache_code; cache_code+=PAGESIZE_TEMP; @@ -605,7 +605,7 @@ static void cache_reset(void) { #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=(Bit8u*)(((Bitu)cache_code_start_ptr + PAGESIZE_TEMP-1) & ~(PAGESIZE_TEMP-1)); //Bitu is same size as a pointer. cache_code_link_blocks=cache_code; cache_code+=PAGESIZE_TEMP; From 144aa917e31149936ec7ad5a609b37c5a3ef8bd5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 12 Dec 2014 18:59:36 +0000 Subject: [PATCH 3784/4131] Small improvement to copy when dealing with a device (fixes a warning from the drive_cache on the findnext). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3874 --- src/shell/shell_cmds.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index cb398e65..e8b6aa24 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -583,8 +583,8 @@ void DOS_Shell::CMD_COPY(char * args) { dos.dta(save_dta); return; } - // Gather all sources (extension to copy more then 1 file specified at commandline) - // Concatating files go as follows: All parts except for the last bear the concat flag. + // Gather all sources (extension to copy more then 1 file specified at command line) + // Concatenating files go as follows: All parts except for the last bear the concat flag. // This construction allows them to be counted (only the non concat set) char* source_p = NULL; char source_x[DOS_PATHLENGTH+CROSS_LEN]; @@ -670,7 +670,7 @@ void DOS_Shell::CMD_COPY(char * args) { char* temp = strstr(pathTarget,"*.*"); if(temp) *temp = 0;//strip off *.* from target - // add '\\' if target is a directoy + // add '\\' if target is a directory if (pathTarget[strlen(pathTarget)-1]!='\\') { if (DOS_FindFirst(pathTarget,0xffff & ~DOS_ATTR_VOLUME)) { dta.GetResult(name,size,date,time,attr); @@ -703,7 +703,7 @@ void DOS_Shell::CMD_COPY(char * args) { strcpy(nameTarget,pathTarget); if (nameTarget[strlen(nameTarget)-1]=='\\') strcat(nameTarget,name); - //Don't create a newfile when in concat mode + //Don't create a new file when in concat mode if (oldsource.concat || DOS_CreateFile(nameTarget,0,&targetHandle)) { Bit32u dummy=0; //In concat mode. Open the target and seek to the eof @@ -731,8 +731,9 @@ void DOS_Shell::CMD_COPY(char * args) { } } else WriteOut(MSG_Get("SHELL_CMD_COPY_FAILURE"),const_cast(source.filename.c_str())); }; - //On the next file - ret = DOS_FindNext(); + //On to the next file if the previous one wasn't a device + if ((attr&DOS_ATTR_DEVICE) == 0) ret = DOS_FindNext(); + else ret = false; }; } From b2a68600327265221a1dc8fcda70f1cb0a2de508 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 12 Dec 2014 19:02:37 +0000 Subject: [PATCH 3785/4131] Reading from NUL changed to report 0 bytes read. Prevents infinite read loops on NUL. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3875 --- src/dos/dos_devices.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 79d00eae..1936fe10 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -37,8 +37,7 @@ class device_NUL : public DOS_Device { public: device_NUL() { SetName("NUL"); }; virtual bool Read(Bit8u * data,Bit16u * size) { - for(Bitu i = 0; i < *size;i++) - data[i]=0; + *size = 0; //Return success and no data read. LOG(LOG_IOCTL,LOG_NORMAL)("%s:READ",GetName()); return true; } From f06067e1016195a3a32ba158c10b98e4686017aa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 12 Dec 2014 19:04:40 +0000 Subject: [PATCH 3786/4131] Add missing error message. Rewrite CDRom to CD-ROM for consistency. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3876 --- src/dos/dos_programs.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 7d74f1c9..3e00f572 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1498,12 +1498,13 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_LOADFIX_ERROR","Memory allocation error.\n"); MSG_Add("MSCDEX_SUCCESS","MSCDEX installed.\n"); - MSG_Add("MSCDEX_ERROR_MULTIPLE_CDROMS","MSCDEX: Failure: Drive-letters of multiple CDRom-drives have to be continuous.\n"); + MSG_Add("MSCDEX_ERROR_MULTIPLE_CDROMS","MSCDEX: Failure: Drive-letters of multiple CD-ROM drives have to be continuous.\n"); MSG_Add("MSCDEX_ERROR_NOT_SUPPORTED","MSCDEX: Failure: Not yet supported.\n"); + MSG_Add("MSCDEX_ERROR_PATH","MSCDEX: Specified location is not a CD-ROM drive.\n"); MSG_Add("MSCDEX_ERROR_OPEN","MSCDEX: Failure: Invalid file or unable to open.\n"); - MSG_Add("MSCDEX_TOO_MANY_DRIVES","MSCDEX: Failure: Too many CDRom-drives (max: 5). MSCDEX Installation failed.\n"); + MSG_Add("MSCDEX_TOO_MANY_DRIVES","MSCDEX: Failure: Too many CD-ROM drives (max: 5). MSCDEX Installation failed.\n"); MSG_Add("MSCDEX_LIMITED_SUPPORT","MSCDEX: Mounted subdirectory: limited support.\n"); - MSG_Add("MSCDEX_INVALID_FILEFORMAT","MSCDEX: Failure: File is either no iso/cue image or contains errors.\n"); + MSG_Add("MSCDEX_INVALID_FILEFORMAT","MSCDEX: Failure: File is either no ISO/CUE image or contains errors.\n"); MSG_Add("MSCDEX_UNKNOWN_ERROR","MSCDEX: Failure: Unknown error.\n"); MSG_Add("PROGRAM_RESCAN_SUCCESS","Drive cache cleared.\n"); @@ -1517,7 +1518,7 @@ void DOS_SetupPrograms(void) { "For information about special keys type \033[34;1mintro special\033[0m\n" "For more information about DOSBox, go to \033[34;1mhttp://www.dosbox.com/wiki\033[0m\n" "\n" - "\033[31;1mDOSBox will stop/exit without a warning if an error occured!\033[0m\n" + "\033[31;1mDOSBox will stop/exit without a warning if an error occurred!\033[0m\n" "\n" "\n" ); @@ -1531,9 +1532,9 @@ void DOS_SetupPrograms(void) { "\033[44;1m\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n" - "\xBA \033[32mmount c c:\\dosprogs\\\033[37m will create a C drive with c:\\dosprogs as contents.\xBA\n" + "\xBA \033[32mmount c c:\\dosgames\\\033[37m will create a C drive with c:\\dosgames as contents.\xBA\n" "\xBA \xBA\n" - "\xBA \033[32mc:\\dosprogs\\\033[37m is an example. Replace it with your own games directory. \033[37m \xBA\n" + "\xBA \033[32mc:\\dosgames\\\033[37m is an example. Replace it with your own games directory. \033[37m \xBA\n" "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC\033[0m\n" @@ -1542,9 +1543,9 @@ void DOS_SetupPrograms(void) { "\033[44;1m\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n" - "\xBA \033[32mmount c ~/dosprogs\033[37m will create a C drive with ~/dosprogs as contents.\xBA\n" + "\xBA \033[32mmount c ~/dosgames\033[37m will create a C drive with ~/dosgames as contents.\xBA\n" "\xBA \xBA\n" - "\xBA \033[32m~/dosprogs\033[37m is an example. Replace it with your own games directory.\033[37m \xBA\n" + "\xBA \033[32m~/dosgames\033[37m is an example. Replace it with your own games directory.\033[37m \xBA\n" "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC\033[0m\n" From 89f844c7b8f4a4d5c526d1ade0a8c361f55a4435 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 6 Jan 2015 14:10:23 +0000 Subject: [PATCH 3787/4131] Need this quite often. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3877 --- src/dosbox.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 6aad4192..11762bc2 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -202,6 +202,14 @@ increaseticks: if (new_cmax10) { From 0f4c92ca3267dc2bfb0cdca5491e691e99954eb0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 6 Jan 2015 14:40:32 +0000 Subject: [PATCH 3788/4131] Year update. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3878 --- acinclude.m4 | 2 +- include/bios.h | 2 +- include/bios_disk.h | 2 +- include/callback.h | 2 +- include/control.h | 2 +- include/cpu.h | 2 +- include/cross.h | 2 +- include/debug.h | 2 +- include/dma.h | 2 +- include/dos_inc.h | 2 +- include/dos_system.h | 2 +- include/dosbox.h | 2 +- include/fpu.h | 2 +- include/hardware.h | 2 +- include/inout.h | 2 +- include/ipx.h | 2 +- include/ipxserver.h | 2 +- include/joystick.h | 2 +- include/keyboard.h | 2 +- include/logging.h | 2 +- include/mapper.h | 2 +- include/mem.h | 2 +- include/midi.h | 2 +- include/mixer.h | 2 +- include/mouse.h | 2 +- include/paging.h | 2 +- include/pci_bus.h | 2 +- include/pic.h | 2 +- include/programs.h | 2 +- include/regs.h | 2 +- include/render.h | 2 +- include/serialport.h | 2 +- include/setup.h | 2 +- include/shell.h | 2 +- include/support.h | 2 +- include/timer.h | 2 +- include/vga.h | 2 +- include/video.h | 2 +- src/cpu/callback.cpp | 2 +- src/cpu/core_dyn_x86.cpp | 2 +- src/cpu/core_dyn_x86/cache.h | 2 +- src/cpu/core_dyn_x86/decoder.h | 2 +- src/cpu/core_dyn_x86/dyn_fpu.h | 2 +- src/cpu/core_dyn_x86/dyn_fpu_dh.h | 2 +- src/cpu/core_dyn_x86/helpers.h | 2 +- src/cpu/core_dyn_x86/risc_x86.h | 2 +- src/cpu/core_dyn_x86/string.h | 2 +- src/cpu/core_dynrec.cpp | 2 +- src/cpu/core_dynrec/cache.h | 2 +- src/cpu/core_dynrec/decoder.h | 2 +- src/cpu/core_dynrec/decoder_basic.h | 2 +- src/cpu/core_dynrec/decoder_opcodes.h | 2 +- src/cpu/core_dynrec/dyn_fpu.h | 2 +- src/cpu/core_dynrec/operators.h | 2 +- src/cpu/core_dynrec/risc_armv4le-common.h | 2 +- src/cpu/core_dynrec/risc_armv4le-o3.h | 2 +- src/cpu/core_dynrec/risc_armv4le-thumb-iw.h | 2 +- src/cpu/core_dynrec/risc_armv4le-thumb-niw.h | 2 +- src/cpu/core_dynrec/risc_armv4le-thumb.h | 2 +- src/cpu/core_dynrec/risc_armv4le.h | 2 +- src/cpu/core_dynrec/risc_mipsel32.h | 2 +- src/cpu/core_dynrec/risc_x64.h | 2 +- src/cpu/core_dynrec/risc_x86.h | 2 +- src/cpu/core_full.cpp | 2 +- src/cpu/core_full/ea_lookup.h | 2 +- src/cpu/core_full/load.h | 2 +- src/cpu/core_full/loadwrite.h | 2 +- src/cpu/core_full/op.h | 2 +- src/cpu/core_full/optable.h | 2 +- src/cpu/core_full/save.h | 2 +- src/cpu/core_full/string.h | 2 +- src/cpu/core_full/support.h | 2 +- src/cpu/core_normal.cpp | 2 +- src/cpu/core_normal/helpers.h | 2 +- src/cpu/core_normal/prefix_0f.h | 2 +- src/cpu/core_normal/prefix_66.h | 2 +- src/cpu/core_normal/prefix_66_0f.h | 2 +- src/cpu/core_normal/prefix_none.h | 2 +- src/cpu/core_normal/string.h | 2 +- src/cpu/core_normal/support.h | 2 +- src/cpu/core_normal/table_ea.h | 2 +- src/cpu/core_prefetch.cpp | 2 +- src/cpu/core_simple.cpp | 2 +- src/cpu/cpu.cpp | 2 +- src/cpu/flags.cpp | 2 +- src/cpu/instructions.h | 2 +- src/cpu/lazyflags.h | 2 +- src/cpu/modrm.cpp | 2 +- src/cpu/modrm.h | 2 +- src/cpu/paging.cpp | 2 +- src/debug/debug.cpp | 2 +- src/debug/debug_gui.cpp | 2 +- src/debug/debug_inc.h | 2 +- src/debug/debug_win32.cpp | 2 +- src/debug/disasm_tables.h | 2 +- src/dos/cdrom.cpp | 2 +- src/dos/cdrom.h | 2 +- src/dos/cdrom_aspi_win32.cpp | 2 +- src/dos/cdrom_image.cpp | 2 +- src/dos/cdrom_ioctl_linux.cpp | 2 +- src/dos/cdrom_ioctl_os2.cpp | 2 +- src/dos/cdrom_ioctl_win32.cpp | 2 +- src/dos/dev_con.h | 2 +- src/dos/dos.cpp | 2 +- src/dos/dos_classes.cpp | 2 +- src/dos/dos_devices.cpp | 2 +- src/dos/dos_execute.cpp | 2 +- src/dos/dos_files.cpp | 2 +- src/dos/dos_ioctl.cpp | 2 +- src/dos/dos_keyboard_layout.cpp | 2 +- src/dos/dos_memory.cpp | 2 +- src/dos/dos_misc.cpp | 2 +- src/dos/dos_mscdex.cpp | 2 +- src/dos/dos_programs.cpp | 2 +- src/dos/dos_tables.cpp | 2 +- src/dos/drive_cache.cpp | 2 +- src/dos/drive_fat.cpp | 2 +- src/dos/drive_iso.cpp | 2 +- src/dos/drive_local.cpp | 2 +- src/dos/drive_virtual.cpp | 2 +- src/dos/drives.cpp | 2 +- src/dos/drives.h | 2 +- src/dosbox.cpp | 2 +- src/fpu/fpu.cpp | 2 +- src/fpu/fpu_instructions.h | 2 +- src/fpu/fpu_instructions_x86.h | 2 +- src/gui/dosbox_logo.h | 2 +- src/gui/midi.cpp | 2 +- src/gui/midi_alsa.h | 2 +- src/gui/midi_coreaudio.h | 2 +- src/gui/midi_oss.h | 2 +- src/gui/midi_win32.h | 2 +- src/gui/render.cpp | 2 +- src/gui/render_loops.h | 2 +- src/gui/render_scalers.cpp | 2 +- src/gui/render_scalers.h | 2 +- src/gui/render_simple.h | 2 +- src/gui/render_templates.h | 2 +- src/gui/render_templates_hq.h | 2 +- src/gui/render_templates_hq2x.h | 2 +- src/gui/render_templates_hq3x.h | 2 +- src/gui/render_templates_sai.h | 2 +- src/gui/sdl_gui.cpp | 4 ++-- src/gui/sdl_mapper.cpp | 2 +- src/gui/sdlmain.cpp | 6 +++--- src/hardware/adlib.cpp | 2 +- src/hardware/adlib.h | 2 +- src/hardware/cmos.cpp | 2 +- src/hardware/dbopl.cpp | 2 +- src/hardware/dbopl.h | 2 +- src/hardware/disney.cpp | 2 +- src/hardware/dma.cpp | 2 +- src/hardware/gameblaster.cpp | 2 +- src/hardware/gus.cpp | 2 +- src/hardware/hardware.cpp | 2 +- src/hardware/iohandler.cpp | 2 +- src/hardware/ipx.cpp | 2 +- src/hardware/ipxserver.cpp | 2 +- src/hardware/joystick.cpp | 2 +- src/hardware/keyboard.cpp | 2 +- src/hardware/memory.cpp | 2 +- src/hardware/mixer.cpp | 2 +- src/hardware/opl.cpp | 2 +- src/hardware/opl.h | 2 +- src/hardware/pci_bus.cpp | 2 +- src/hardware/pci_devices.h | 2 +- src/hardware/pcspeaker.cpp | 2 +- src/hardware/pic.cpp | 2 +- src/hardware/sblaster.cpp | 2 +- src/hardware/serialport/directserial.cpp | 2 +- src/hardware/serialport/directserial.h | 2 +- src/hardware/serialport/libserial.cpp | 2 +- src/hardware/serialport/libserial.h | 2 +- src/hardware/serialport/misc_util.cpp | 2 +- src/hardware/serialport/misc_util.h | 2 +- src/hardware/serialport/nullmodem.cpp | 2 +- src/hardware/serialport/nullmodem.h | 2 +- src/hardware/serialport/serialdummy.cpp | 2 +- src/hardware/serialport/serialdummy.h | 2 +- src/hardware/serialport/serialport.cpp | 2 +- src/hardware/serialport/softmodem.cpp | 2 +- src/hardware/serialport/softmodem.h | 2 +- src/hardware/tandy_sound.cpp | 2 +- src/hardware/timer.cpp | 2 +- src/hardware/vga.cpp | 2 +- src/hardware/vga_attr.cpp | 2 +- src/hardware/vga_crtc.cpp | 2 +- src/hardware/vga_dac.cpp | 2 +- src/hardware/vga_draw.cpp | 2 +- src/hardware/vga_gfx.cpp | 2 +- src/hardware/vga_memory.cpp | 2 +- src/hardware/vga_misc.cpp | 2 +- src/hardware/vga_other.cpp | 2 +- src/hardware/vga_paradise.cpp | 2 +- src/hardware/vga_s3.cpp | 2 +- src/hardware/vga_seq.cpp | 2 +- src/hardware/vga_tseng.cpp | 2 +- src/hardware/vga_xga.cpp | 2 +- src/ints/bios.cpp | 2 +- src/ints/bios_disk.cpp | 2 +- src/ints/bios_keyboard.cpp | 2 +- src/ints/ems.cpp | 2 +- src/ints/int10.cpp | 2 +- src/ints/int10.h | 2 +- src/ints/int10_char.cpp | 2 +- src/ints/int10_memory.cpp | 2 +- src/ints/int10_misc.cpp | 2 +- src/ints/int10_modes.cpp | 2 +- src/ints/int10_pal.cpp | 2 +- src/ints/int10_put_pixel.cpp | 2 +- src/ints/int10_vesa.cpp | 2 +- src/ints/int10_video_state.cpp | 2 +- src/ints/int10_vptable.cpp | 2 +- src/ints/mouse.cpp | 2 +- src/ints/xms.cpp | 2 +- src/ints/xms.h | 2 +- src/libs/zmbv/drvproc.cpp | 2 +- src/libs/zmbv/zmbv.cpp | 2 +- src/libs/zmbv/zmbv.h | 2 +- src/libs/zmbv/zmbv_vfw.cpp | 2 +- src/libs/zmbv/zmbv_vfw.rc | 2 +- src/misc/cross.cpp | 2 +- src/misc/messages.cpp | 2 +- src/misc/programs.cpp | 2 +- src/misc/setup.cpp | 2 +- src/misc/support.cpp | 2 +- src/shell/shell.cpp | 2 +- src/shell/shell_batch.cpp | 2 +- src/shell/shell_cmds.cpp | 2 +- src/shell/shell_misc.cpp | 2 +- src/winres.rc | 4 ++-- 231 files changed, 235 insertions(+), 235 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 51fd4154..936496e7 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -305,7 +305,7 @@ AC_SUBST(ALSA_LIBS) AH_TOP([ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/bios.h b/include/bios.h index a1e4e4cf..213c73d6 100644 --- a/include/bios.h +++ b/include/bios.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/bios_disk.h b/include/bios_disk.h index c21577f9..8d91acfe 100644 --- a/include/bios_disk.h +++ b/include/bios_disk.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/callback.h b/include/callback.h index daa103db..f1cfef7c 100644 --- a/include/callback.h +++ b/include/callback.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/control.h b/include/control.h index 9155fa30..4666a277 100644 --- a/include/control.h +++ b/include/control.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/cpu.h b/include/cpu.h index b02c95bf..0e2ea7f1 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/cross.h b/include/cross.h index 395fbf30..93501849 100644 --- a/include/cross.h +++ b/include/cross.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/debug.h b/include/debug.h index f2ea6995..9e214629 100644 --- a/include/debug.h +++ b/include/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/dma.h b/include/dma.h index 3f2915cb..38531811 100644 --- a/include/dma.h +++ b/include/dma.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/dos_inc.h b/include/dos_inc.h index 07a2bef6..98e76547 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/dos_system.h b/include/dos_system.h index d62470f1..baf7591e 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/dosbox.h b/include/dosbox.h index 2576b577..6684faff 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/fpu.h b/include/fpu.h index 7fdb3de2..67e10210 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/hardware.h b/include/hardware.h index 6378d232..5f5e4c74 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/inout.h b/include/inout.h index 578a1137..dd0dc172 100644 --- a/include/inout.h +++ b/include/inout.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/ipx.h b/include/ipx.h index afd8e7d7..6e87b1e9 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/ipxserver.h b/include/ipxserver.h index 1d448755..1c6a294d 100644 --- a/include/ipxserver.h +++ b/include/ipxserver.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/joystick.h b/include/joystick.h index 812bc0e5..a5139584 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/keyboard.h b/include/keyboard.h index 08277b60..fcecc308 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/logging.h b/include/logging.h index 5ad4c27c..049e504b 100644 --- a/include/logging.h +++ b/include/logging.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/mapper.h b/include/mapper.h index acac5d2b..3ba648c4 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/mem.h b/include/mem.h index 8c65380e..d362cb03 100644 --- a/include/mem.h +++ b/include/mem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/midi.h b/include/midi.h index f1106c2d..9da6f180 100644 --- a/include/midi.h +++ b/include/midi.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/mixer.h b/include/mixer.h index 055ccabd..94b806be 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/mouse.h b/include/mouse.h index 0ee82259..2756d0d0 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/paging.h b/include/paging.h index b13f52d6..712214c6 100644 --- a/include/paging.h +++ b/include/paging.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/pci_bus.h b/include/pci_bus.h index 635a356d..f8b729e8 100644 --- a/include/pci_bus.h +++ b/include/pci_bus.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/pic.h b/include/pic.h index d1b4e02d..77691f2a 100644 --- a/include/pic.h +++ b/include/pic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/programs.h b/include/programs.h index 5830a4c9..04db83c1 100644 --- a/include/programs.h +++ b/include/programs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/regs.h b/include/regs.h index b96268c3..4ecab980 100644 --- a/include/regs.h +++ b/include/regs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/render.h b/include/render.h index 3bb9cf3a..f2c53475 100644 --- a/include/render.h +++ b/include/render.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/serialport.h b/include/serialport.h index 6dfbc10f..b4641ccc 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/setup.h b/include/setup.h index e3991833..b17d9e01 100644 --- a/include/setup.h +++ b/include/setup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/shell.h b/include/shell.h index e619841a..74e21059 100644 --- a/include/shell.h +++ b/include/shell.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/support.h b/include/support.h index cbeb9162..62330060 100644 --- a/include/support.h +++ b/include/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/timer.h b/include/timer.h index 9b008951..e8abf323 100644 --- a/include/timer.h +++ b/include/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/vga.h b/include/vga.h index ab79466c..0bbeb567 100644 --- a/include/vga.h +++ b/include/vga.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/include/video.h b/include/video.h index b6c157bf..11539aee 100644 --- a/include/video.h +++ b/include/video.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index d92d429a..53f86933 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 3338791d..ac05a569 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index ec78aeba..23b6a53e 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 61b1ca55..18bf1e11 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dyn_x86/dyn_fpu.h b/src/cpu/core_dyn_x86/dyn_fpu.h index f5ff2509..6534b70b 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu.h +++ b/src/cpu/core_dyn_x86/dyn_fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dyn_x86/dyn_fpu_dh.h b/src/cpu/core_dyn_x86/dyn_fpu_dh.h index e17e5d87..23870452 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu_dh.h +++ b/src/cpu/core_dyn_x86/dyn_fpu_dh.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dyn_x86/helpers.h b/src/cpu/core_dyn_x86/helpers.h index 84206f43..022e6780 100644 --- a/src/cpu/core_dyn_x86/helpers.h +++ b/src/cpu/core_dyn_x86/helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 558f3cfe..74c85366 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index 1625e5d4..93f69e4e 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index 16dd73c2..f1d68d67 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index e1a3d88c..7d7a6efd 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h index 9c3fbcf2..9c1fe499 100644 --- a/src/cpu/core_dynrec/decoder.h +++ b/src/cpu/core_dynrec/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index 079383bc..61edc64b 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index 43e15a09..d08ae43b 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dynrec/dyn_fpu.h b/src/cpu/core_dynrec/dyn_fpu.h index 81498c6a..c410ebde 100644 --- a/src/cpu/core_dynrec/dyn_fpu.h +++ b/src/cpu/core_dynrec/dyn_fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dynrec/operators.h b/src/cpu/core_dynrec/operators.h index 78dfb670..18d17430 100644 --- a/src/cpu/core_dynrec/operators.h +++ b/src/cpu/core_dynrec/operators.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-common.h b/src/cpu/core_dynrec/risc_armv4le-common.h index 87c7c591..c6ab612f 100644 --- a/src/cpu/core_dynrec/risc_armv4le-common.h +++ b/src/cpu/core_dynrec/risc_armv4le-common.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-o3.h b/src/cpu/core_dynrec/risc_armv4le-o3.h index e95edee7..3596c48e 100644 --- a/src/cpu/core_dynrec/risc_armv4le-o3.h +++ b/src/cpu/core_dynrec/risc_armv4le-o3.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h index f962c5bf..5d8f8b52 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h index 2a6b24be..e4890c1b 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb.h b/src/cpu/core_dynrec/risc_armv4le-thumb.h index 829cb554..126cdd11 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dynrec/risc_armv4le.h b/src/cpu/core_dynrec/risc_armv4le.h index 7a38d8f2..8a3b343b 100644 --- a/src/cpu/core_dynrec/risc_armv4le.h +++ b/src/cpu/core_dynrec/risc_armv4le.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dynrec/risc_mipsel32.h b/src/cpu/core_dynrec/risc_mipsel32.h index 83f164c8..0e7d4745 100644 --- a/src/cpu/core_dynrec/risc_mipsel32.h +++ b/src/cpu/core_dynrec/risc_mipsel32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index 6ad073ca..58f9d2e9 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_dynrec/risc_x86.h b/src/cpu/core_dynrec/risc_x86.h index 260ffc74..81cb03bc 100644 --- a/src/cpu/core_dynrec/risc_x86.h +++ b/src/cpu/core_dynrec/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 35720af1..7fd14695 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_full/ea_lookup.h b/src/cpu/core_full/ea_lookup.h index 16cf2ad9..6048a430 100644 --- a/src/cpu/core_full/ea_lookup.h +++ b/src/cpu/core_full/ea_lookup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 64946e14..699803ca 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_full/loadwrite.h b/src/cpu/core_full/loadwrite.h index e88153f8..b00ffb6c 100644 --- a/src/cpu/core_full/loadwrite.h +++ b/src/cpu/core_full/loadwrite.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index b38f7368..14786b1f 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 0b09d4c6..b5680e5d 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_full/save.h b/src/cpu/core_full/save.h index 68280796..408ed6d8 100644 --- a/src/cpu/core_full/save.h +++ b/src/cpu/core_full/save.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index 741e4d35..8cb6ec03 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index c4d1d8ea..bdbe452a 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index ef7682e3..1c034743 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_normal/helpers.h b/src/cpu/core_normal/helpers.h index abde2bfd..13526f8b 100644 --- a/src/cpu/core_normal/helpers.h +++ b/src/cpu/core_normal/helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 699d4c91..0fcf6b68 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index decfc8f8..29f2a188 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 7a4eb31f..8f41f9a8 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 11c95134..63f81ff8 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_normal/string.h b/src/cpu/core_normal/string.h index 027b59b6..992ed42c 100644 --- a/src/cpu/core_normal/string.h +++ b/src/cpu/core_normal/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index fa545245..6fe9a17c 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_normal/table_ea.h b/src/cpu/core_normal/table_ea.h index 74ee150b..920f5ce8 100644 --- a/src/cpu/core_normal/table_ea.h +++ b/src/cpu/core_normal/table_ea.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_prefetch.cpp b/src/cpu/core_prefetch.cpp index 1cd1403b..47db2c11 100644 --- a/src/cpu/core_prefetch.cpp +++ b/src/cpu/core_prefetch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp index 7ac7a55a..d8fdb9ea 100644 --- a/src/cpu/core_simple.cpp +++ b/src/cpu/core_simple.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 47b6f658..2398fafa 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 29b8ddd5..1559af1e 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 57e7dbc6..28af3314 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index 75701ef4..726d36bb 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/modrm.cpp b/src/cpu/modrm.cpp index dce156af..028e4d71 100644 --- a/src/cpu/modrm.cpp +++ b/src/cpu/modrm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/modrm.h b/src/cpu/modrm.h index f8ea48ee..29656bfc 100644 --- a/src/cpu/modrm.h +++ b/src/cpu/modrm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 3a7b539e..7be15e1a 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 85096a15..b215c301 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index 3db7e50b..ca9e202b 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h index e6ea2b05..a94d3a8f 100644 --- a/src/debug/debug_inc.h +++ b/src/debug/debug_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/debug/debug_win32.cpp b/src/debug/debug_win32.cpp index e485da2e..469bec89 100644 --- a/src/debug/debug_win32.cpp +++ b/src/debug/debug_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/debug/disasm_tables.h b/src/debug/disasm_tables.h index ad743938..e3d12433 100644 --- a/src/debug/disasm_tables.h +++ b/src/debug/disasm_tables.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 47ee05cf..ab98912c 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index 18445333..79bb1a03 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index 9482a1e1..35c891ff 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index f636a7e5..2a31d224 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/cdrom_ioctl_linux.cpp b/src/dos/cdrom_ioctl_linux.cpp index 7064c3e7..8fa0f235 100644 --- a/src/dos/cdrom_ioctl_linux.cpp +++ b/src/dos/cdrom_ioctl_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/cdrom_ioctl_os2.cpp b/src/dos/cdrom_ioctl_os2.cpp index dc5d45e3..d96b45de 100644 --- a/src/dos/cdrom_ioctl_os2.cpp +++ b/src/dos/cdrom_ioctl_os2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index 0158d386..615750e1 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 8a90860f..ad3b31d9 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index a2fc2021..28e5663b 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index da4099b8..b88895ec 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 1936fe10..03d3f66a 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index d2ac101e..5538d721 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index b2886220..11294937 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index ca6e246a..2df136f5 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index c41109d3..3214fe5e 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index ccf2392a..7a86a0ea 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index f7b595ba..2c9b6c46 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 36ef3066..b0f1d187 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 3e00f572..8c1e3111 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index a08e58c7..1c00171e 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 057c3b25..eb4d5f8b 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 323072b7..86b7dba0 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 86a96fbe..8e4d96d0 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 7e9ee18e..94a30a56 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 70fb97b5..afb55fc1 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index 25f7e45e..0429d007 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dos/drives.h b/src/dos/drives.h index 509af18f..0138163b 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 11762bc2..83e6f434 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 2f5778cf..1e561143 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 1b8329ce..54d0143c 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2014 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index 21b2f93d..d837850d 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2014 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/gui/dosbox_logo.h b/src/gui/dosbox_logo.h index fa1e2a32..7ba4ce20 100644 --- a/src/gui/dosbox_logo.h +++ b/src/gui/dosbox_logo.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index ce4647fb..e7cc6d42 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index fe051839..6cc21d87 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index 1fe3e386..9c675742 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index 3b34d24a..6f7c4123 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index 162bf2e0..a34451cb 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 66cf22cc..af3b6b20 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/gui/render_loops.h b/src/gui/render_loops.h index a781742a..99d44066 100644 --- a/src/gui/render_loops.h +++ b/src/gui/render_loops.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index dea60230..2f8d2ed3 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index bb5b5fc1..0e5265e3 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/gui/render_simple.h b/src/gui/render_simple.h index 204a84e8..647bbb99 100644 --- a/src/gui/render_simple.h +++ b/src/gui/render_simple.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index cdaba9e3..dadfe528 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/gui/render_templates_hq.h b/src/gui/render_templates_hq.h index bd4ad824..3eecb73e 100644 --- a/src/gui/render_templates_hq.h +++ b/src/gui/render_templates_hq.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/gui/render_templates_hq2x.h b/src/gui/render_templates_hq2x.h index 15a6dcb8..eed48357 100644 --- a/src/gui/render_templates_hq2x.h +++ b/src/gui/render_templates_hq2x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/gui/render_templates_hq3x.h b/src/gui/render_templates_hq3x.h index 4e23b4fb..1788be23 100644 --- a/src/gui/render_templates_hq3x.h +++ b/src/gui/render_templates_hq3x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/gui/render_templates_sai.h b/src/gui/render_templates_sai.h index 13e86e94..72a28285 100644 --- a/src/gui/render_templates_sai.h +++ b/src/gui/render_templates_sai.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index a291b049..01fe6b7a 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 @@ -569,7 +569,7 @@ public: Section_prop *section = static_cast(sec); new SectionEditor(getScreen(), 50, 30, section); } else if (arg == "About") { - new GUI::MessageBox(getScreen(), 200, 150, 280, "About DOSBox", "\nDOSBox 0.74\nAn emulator for old DOS Games\n\nCopyright 2002-2013\nThe DOSBox Team"); + new GUI::MessageBox(getScreen(), 200, 150, 280, "About DOSBox", "\nDOSBox 0.74\nAn emulator for old DOS Games\n\nCopyright 2002-2015\nThe DOSBox Team"); } else if (arg == "Introduction") { new GUI::MessageBox(getScreen(), 20, 50, 600, "Introduction", MSG_Get("PROGRAM_INTRO")); } else if (arg == "Getting Started") { diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 47ce677d..923eb2ec 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2014 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 2fab4928..ec1c382d 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2014 The DOSBox Team + * Copyright (C) 2002-2015 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 @@ -1916,7 +1916,7 @@ int main(int argc, char* argv[]) { #endif //defined(WIN32) && !(C_DEBUG) if (control->cmdline->FindExist("-version") || control->cmdline->FindExist("--version") ) { - printf("\nDOSBox version %s, copyright 2002-2013 DOSBox Team.\n\n",VERSION); + printf("\nDOSBox version %s, copyright 2002-2015 DOSBox Team.\n\n",VERSION); printf("DOSBox is written by the DOSBox Team (See AUTHORS file))\n"); printf("DOSBox comes with ABSOLUTELY NO WARRANTY. This is free software,\n"); printf("and you are welcome to redistribute it under certain conditions;\n"); @@ -1944,7 +1944,7 @@ int main(int argc, char* argv[]) { /* Display Welcometext in the console */ LOG_MSG("DOSBox version %s",VERSION); - LOG_MSG("Copyright 2002-2013 DOSBox Team, published under GNU GPL."); + LOG_MSG("Copyright 2002-2015 DOSBox Team, published under GNU GPL."); LOG_MSG("---"); /* Init SDL */ diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index c127ff09..89e512bf 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/adlib.h b/src/hardware/adlib.h index d6c4d39d..681fd491 100644 --- a/src/hardware/adlib.h +++ b/src/hardware/adlib.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index c3977043..0628a042 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index 34547665..eda3ca6e 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/dbopl.h b/src/hardware/dbopl.h index 8a82e184..1a255fd8 100644 --- a/src/hardware/dbopl.h +++ b/src/hardware/dbopl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index d556fe15..44fd7e3c 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 830aa58d..1b738e57 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index a1b61a77..267ada73 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index af642990..8b20b954 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index af7c411a..baeeb1db 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 7c807402..1fd19ccb 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index c0e12af9..3369aad7 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/ipxserver.cpp b/src/hardware/ipxserver.cpp index 672f3fea..a233c484 100644 --- a/src/hardware/ipxserver.cpp +++ b/src/hardware/ipxserver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index 3d52b3af..ca6161b6 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 21546ece..f3ef7e53 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 5b115193..73d5c8e0 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index c708f874..e49ccd57 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/opl.cpp b/src/hardware/opl.cpp index 7149b93c..deff8dd8 100644 --- a/src/hardware/opl.cpp +++ b/src/hardware/opl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 The DOSBox Team * OPL2/OPL3 emulation library * * This library is free software; you can redistribute it and/or diff --git a/src/hardware/opl.h b/src/hardware/opl.h index c704b3a4..41132c3a 100644 --- a/src/hardware/opl.h +++ b/src/hardware/opl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 The DOSBox Team * OPL2/OPL3 emulation library * * This library is free software; you can redistribute it and/or diff --git a/src/hardware/pci_bus.cpp b/src/hardware/pci_bus.cpp index 16b0bcd0..de3bd677 100644 --- a/src/hardware/pci_bus.cpp +++ b/src/hardware/pci_bus.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/pci_devices.h b/src/hardware/pci_devices.h index 7a9c2428..29d4d362 100644 --- a/src/hardware/pci_devices.h +++ b/src/hardware/pci_devices.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 04a32916..2f22d35a 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 000b6b92..ce2c7df4 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index daf8c0cc..875c75c8 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/serialport/directserial.cpp b/src/hardware/serialport/directserial.cpp index 20e48387..00f2340f 100644 --- a/src/hardware/serialport/directserial.cpp +++ b/src/hardware/serialport/directserial.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/serialport/directserial.h b/src/hardware/serialport/directserial.h index e910187c..429e6f83 100644 --- a/src/hardware/serialport/directserial.h +++ b/src/hardware/serialport/directserial.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/serialport/libserial.cpp b/src/hardware/serialport/libserial.cpp index 090ff2f7..b55e1778 100644 --- a/src/hardware/serialport/libserial.cpp +++ b/src/hardware/serialport/libserial.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/serialport/libserial.h b/src/hardware/serialport/libserial.h index 60d6b085..a0143b90 100644 --- a/src/hardware/serialport/libserial.h +++ b/src/hardware/serialport/libserial.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/serialport/misc_util.cpp b/src/hardware/serialport/misc_util.cpp index 831c37f1..302dfb7d 100644 --- a/src/hardware/serialport/misc_util.cpp +++ b/src/hardware/serialport/misc_util.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/serialport/misc_util.h b/src/hardware/serialport/misc_util.h index f62ab151..31cd1d2f 100644 --- a/src/hardware/serialport/misc_util.h +++ b/src/hardware/serialport/misc_util.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/serialport/nullmodem.cpp b/src/hardware/serialport/nullmodem.cpp index 62e7f976..2865073a 100644 --- a/src/hardware/serialport/nullmodem.cpp +++ b/src/hardware/serialport/nullmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/serialport/nullmodem.h b/src/hardware/serialport/nullmodem.h index 0b467f44..b70d2940 100644 --- a/src/hardware/serialport/nullmodem.h +++ b/src/hardware/serialport/nullmodem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/serialport/serialdummy.cpp b/src/hardware/serialport/serialdummy.cpp index ccbdc3f3..b2019cde 100644 --- a/src/hardware/serialport/serialdummy.cpp +++ b/src/hardware/serialport/serialdummy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/serialport/serialdummy.h b/src/hardware/serialport/serialdummy.h index d6621f4f..88e44b3b 100644 --- a/src/hardware/serialport/serialdummy.h +++ b/src/hardware/serialport/serialdummy.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index ee184542..7bc16b4c 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index a22e03de..d135b8f4 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index a625929e..72b80f44 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 73f86f57..9e2dfb84 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 8982fbb9..eacd5769 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index b0cb2c03..9be527ff 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index df61a7f8..ba5ed16c 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 7404313e..dbaf26b3 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index ae305e03..ccad2290 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 0f10096e..254e826e 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index 760ebd1d..1281aadb 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index ac6f8536..974527c0 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index a8b568c7..3c7e0bd9 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index cb8508f7..373d7bcf 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/vga_paradise.cpp b/src/hardware/vga_paradise.cpp index 5eb96062..d0929a5e 100644 --- a/src/hardware/vga_paradise.cpp +++ b/src/hardware/vga_paradise.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index 9b813490..abdab61f 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index fdf1628e..f7b96b0e 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/vga_tseng.cpp b/src/hardware/vga_tseng.cpp index a18b8bab..4fae1771 100644 --- a/src/hardware/vga_tseng.cpp +++ b/src/hardware/vga_tseng.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index dfdfc5d4..922a102d 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 5657ca6a..5e1f306c 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 1da9f294..880e7da5 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 9a524aa4..8590b43a 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 6b930b33..3d2e1d74 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index ccbb5097..288854b6 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/ints/int10.h b/src/ints/int10.h index 597c9fc6..2a40e915 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 415a0589..9c4efb42 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 54e78375..c0fadaaf 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index bd35bda4..0d57017d 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index e8609756..a2be2915 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index f6889a48..4633ffaa 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 13aa8596..a3207d34 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 941e2f34..ef3fcb34 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/ints/int10_video_state.cpp b/src/ints/int10_video_state.cpp index 7983abbd..4a8e6cdf 100644 --- a/src/ints/int10_video_state.cpp +++ b/src/ints/int10_video_state.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/ints/int10_vptable.cpp b/src/ints/int10_vptable.cpp index ed0084cc..41693182 100644 --- a/src/ints/int10_vptable.cpp +++ b/src/ints/int10_vptable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 3b2f963f..7d5cf59c 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index c9bffb95..da5725ac 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/ints/xms.h b/src/ints/xms.h index 94e0e624..409bbac8 100644 --- a/src/ints/xms.h +++ b/src/ints/xms.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/libs/zmbv/drvproc.cpp b/src/libs/zmbv/drvproc.cpp index 3559a0f9..6ceeece3 100644 --- a/src/libs/zmbv/drvproc.cpp +++ b/src/libs/zmbv/drvproc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/libs/zmbv/zmbv.cpp b/src/libs/zmbv/zmbv.cpp index bcf5ca55..af554530 100644 --- a/src/libs/zmbv/zmbv.cpp +++ b/src/libs/zmbv/zmbv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/libs/zmbv/zmbv.h b/src/libs/zmbv/zmbv.h index 3a29d47b..558ef9ea 100644 --- a/src/libs/zmbv/zmbv.h +++ b/src/libs/zmbv/zmbv.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/libs/zmbv/zmbv_vfw.cpp b/src/libs/zmbv/zmbv_vfw.cpp index 2ea0d512..9b4c284d 100644 --- a/src/libs/zmbv/zmbv_vfw.cpp +++ b/src/libs/zmbv/zmbv_vfw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/libs/zmbv/zmbv_vfw.rc b/src/libs/zmbv/zmbv_vfw.rc index 18af28ac..3f29bfe2 100644 --- a/src/libs/zmbv/zmbv_vfw.rc +++ b/src/libs/zmbv/zmbv_vfw.rc @@ -59,7 +59,7 @@ CAPTION "DOSBox Video Codec v0.1" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN DEFPUSHBUTTON "OK",IDOK,131,34,29,14 - CTEXT "Zipped Motion Block Video v 0.1\nCopyright 2009-2013 DOSBox Team", + CTEXT "Zipped Motion Block Video v 0.1\nCopyright 2009-2015 DOSBox Team", IDC_STATIC,7,7,153,25,SS_NOPREFIX PUSHBUTTON "Email author",IDC_EMAIL,7,34,50,14 PUSHBUTTON "Visit home page",IDC_HOMEPAGE,59,34,58,14 diff --git a/src/misc/cross.cpp b/src/misc/cross.cpp index 709fac66..60a13b21 100644 --- a/src/misc/cross.cpp +++ b/src/misc/cross.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index c89d4b2f..d6799af6 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 6c96b42d..f21b63ec 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 6aa7b917..8e10c2c4 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 744976a2..b84c4b84 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 7bbcd143..76cdd404 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 20e692a1..3474d618 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index e8b6aa24..2fbfa618 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 136cba43..e51bba67 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2013 The DOSBox Team + * Copyright (C) 2002-2015 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 diff --git a/src/winres.rc b/src/winres.rc index 5c6edaa5..67309841 100644 --- a/src/winres.rc +++ b/src/winres.rc @@ -19,12 +19,12 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "Comments", "© 2002-2013 DOSBox Team, published under GNU GPL" + VALUE "Comments", "© 2002-2015 DOSBox Team, published under GNU GPL" VALUE "CompanyName", "DOSBox Team" VALUE "FileDescription", "DOSBox DOS Emulator" VALUE "FileVersion", "0, 74, 0, 0" VALUE "InternalName", "DOSBox" - VALUE "LegalCopyright", "Copyright © 2002-2013 DOSBox Team" + VALUE "LegalCopyright", "Copyright © 2002-2015 DOSBox Team" VALUE "OriginalFilename", "dosbox.exe" VALUE "ProductName", "DOSBox DOS Emulator" VALUE "ProductVersion", "0, 74, 0, 0" From 92ca5488b922d12e306c73db361cf623308a6b10 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 6 Jan 2015 16:51:22 +0000 Subject: [PATCH 3789/4131] The emulated floppy drive does not use DMA, but make it look like it does when booting. Fixes CGA graphics in the Demon's Forge booter. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3879 --- src/dos/dos_programs.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 8c1e3111..2a9e8fcb 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -36,6 +36,8 @@ #include "bios_disk.h" #include "setup.h" #include "control.h" +#include "inout.h" +#include "dma.h" #if defined(OS2) @@ -590,7 +592,7 @@ public: FILE *usefile_1=NULL; FILE *usefile_2=NULL; Bitu i=0; - Bit32u floppysize; + Bit32u floppysize=0; Bit32u rombytesize_1=0; Bit32u rombytesize_2=0; Bit8u drive = 'A'; @@ -825,6 +827,9 @@ public: WriteOut(MSG_Get("PROGRAM_BOOT_BOOT"), drive); for(i=0;i<512;i++) real_writeb(0, 0x7c00 + i, bootarea.rawdata[i]); + /* create appearance of floppy drive DMA usage (Demon's Forge) */ + if (!IS_TANDY_ARCH && floppysize!=0) GetDMAChannel(2)->tcount=true; + /* revector some dos-allocated interrupts */ real_writed(0,0x01*4,0xf000ff53); real_writed(0,0x03*4,0xf000ff53); From d2209e10b5d9b4a62feb75e9dc18d81e0d7a9630 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 6 Jan 2015 17:16:00 +0000 Subject: [PATCH 3790/4131] Change the console device to use the DOS default attribute of 7 when ANSI is not active. Fixes glitched text in Space Pilot, and generally improves compatibility of console text output in graphics modes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3880 --- src/dos/dev_con.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index ad3b31d9..372af3c8 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -130,8 +130,8 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { } else { /* Some sort of "hack" now that '\n' doesn't set col to 0 (int10_char.cpp old chessgame) */ if((data[count] == '\n') && (lastwrite != '\r')) INT10_TeletypeOutputAttr('\r',ansi.attr,ansi.enabled); - /* pass attribute only if ansi is enabled */ - INT10_TeletypeOutputAttr(data[count],ansi.attr,ansi.enabled); + /* use ansi attribute if ansi is enabled, otherwise use DOS default attribute*/ + INT10_TeletypeOutputAttr(data[count],ansi.enabled?ansi.attr:7,true); lastwrite = data[count++]; continue; } From 58a149deec7179e914c2d6788a3f388f752e910d Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 6 Jan 2015 17:33:39 +0000 Subject: [PATCH 3791/4131] Don't count trailing spaces when checking if path is too long. Enable all write planes in the EGA FillRow function. Fixes crash and glitched graphics in Quest Maker 2 and derived adventure games (House of No Doors, Hot Rod Harry, et al). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3881 --- src/dos/dos_files.cpp | 1 + src/ints/int10_char.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 11294937..c5bfa0a9 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -101,6 +101,7 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { break; } } + while (r>0 && name_int[r-1]==' ') r--; if (r>=DOS_PATHLENGTH) { DOS_SetError(DOSERR_PATH_NOT_FOUND);return false; } upname[w]=0; /* Now parse the new file name to make the final filename */ diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 9c4efb42..a672d2ba 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -155,6 +155,8 @@ static void EGA16_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,Bit8u a IO_Write(0x3ce,0x8);IO_Write(0x3cf,0xff); IO_Write(0x3ce,0x0);IO_Write(0x3cf,attr); IO_Write(0x3ce,0x1);IO_Write(0x3cf,0xf); + /* Enable all Write planes */ + IO_Write(0x3c4,2);IO_Write(0x3c5,0xf); /* Write some bytes */ Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); PhysPt dest=base+(CurMode->twidth*row)*cheight+cleft; From 5fef7164a5edf42cf2d74089212be5316c937541 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 6 Jan 2015 17:48:07 +0000 Subject: [PATCH 3792/4131] Coalesce free memory blocks after resizing a block rather than before. Fixes some MicroProse games on the Tandy machine type. Also add error exits in case of a corrupt MCB chain instead of hanging in an infinite loop. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3882 --- src/dos/dos_memory.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 7a86a0ea..7ab32bdb 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -33,7 +33,8 @@ static void DOS_CompressMemory(void) { while (mcb.GetType()!=0x5a) { mcb_next.SetPt((Bit16u)(mcb_segment+mcb.GetSize()+1)); - if ((mcb.GetPSPSeg()==0) && (mcb_next.GetPSPSeg()==0)) { + if (GCC_UNLIKELY((mcb_next.GetType()!=0x4d) && (mcb_next.GetType()!=0x5a))) E_Exit("Corrupt MCB chain"); + if ((mcb.GetPSPSeg()==MCB_FREE) && (mcb_next.GetPSPSeg()==MCB_FREE)) { mcb.SetSize(mcb.GetSize()+mcb_next.GetSize()+1); mcb.SetType(mcb_next.GetType()); } else { @@ -58,6 +59,7 @@ void DOS_FreeProcessMemory(Bit16u pspseg) { mcb.SetType(0x4d); } else break; } + if (GCC_UNLIKELY(mcb.GetType()!=0x4d)) E_Exit("Corrupt MCB chain"); mcb_segment+=mcb.GetSize()+1; mcb.SetPt(mcb_segment); } @@ -111,7 +113,7 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) { Bit16u found_seg=0,found_seg_size=0; for (;;) { mcb.SetPt(mcb_segment); - if (mcb.GetPSPSeg()==0) { + if (mcb.GetPSPSeg()==MCB_FREE) { /* Check for enough free memory in current block */ Bit16u block_size=mcb.GetSize(); if (block_size<(*blocks)) { @@ -225,12 +227,12 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { return false; } - DOS_CompressMemory(); Bit16u total=mcb.GetSize(); DOS_MCB mcb_next(segment+total); if (*blocks<=total) { if (GCC_UNLIKELY(*blocks==total)) { /* Nothing to do */ + DOS_CompressMemory(); return true; } /* Shrinking MCB */ @@ -245,6 +247,7 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { mcb_new_next.SetSize(total-*blocks-1); mcb_new_next.SetPSPSeg(MCB_FREE); mcb.SetPSPSeg(dos.psp()); + DOS_CompressMemory(); return true; } /* MCB will grow, try to join with following MCB */ @@ -265,6 +268,7 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { mcb_next.SetPSPSeg(MCB_FREE); mcb.SetType(0x4d); mcb.SetPSPSeg(dos.psp()); + DOS_CompressMemory(); return true; } @@ -277,6 +281,7 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { } mcb.SetSize(total); mcb.SetPSPSeg(dos.psp()); + DOS_CompressMemory(); if (*blocks==total) return true; /* block fit exactly */ *blocks=total; /* return maximum */ From 7acd7802448a259cee1f75ae67dac4a8d28414f9 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 6 Jan 2015 17:54:58 +0000 Subject: [PATCH 3793/4131] Add support for M_TANDY16 to GetPixel(). Fixes text and mouse pointer drawing in Tandy graphics modes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3883 --- src/ints/int10_put_pixel.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index a3207d34..145288cc 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -200,6 +200,26 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) { *color=(val>>(((7-(x&7))))) & 1 ; } break; + case M_TANDY16: + { + bool is_32k = (real_readb(BIOSMEM_SEG, BIOSMEM_CURRENT_MODE) >= 9)?true:false; + Bit16u segment, offset; + if (is_32k) { + if (machine==MCH_PCJR) { + Bitu cpupage = (real_readb(BIOSMEM_SEG, BIOSMEM_CRTCPU_PAGE) >> 3) & 0x7; + segment = cpupage << 10; + } else segment = 0xb800; + offset = (y >> 2) * (CurMode->swidth >> 1) + (x>>1); + offset += (8*1024) * (y & 3); + } else { + segment = 0xb800; + offset = (y >> 1) * (CurMode->swidth >> 1) + (x>>1); + offset += (8*1024) * (y & 1); + } + Bit8u val=real_readb(segment,offset); + *color=(val>>((x&1)?0:4)) & 0xf; + } + break; case M_EGA: { /* Calculate where the pixel is in video memory */ From 1acc1a459a2323a4b2f552f28f8c35939bacfd2a Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 6 Jan 2015 18:02:28 +0000 Subject: [PATCH 3794/4131] Improve compatibility of the PCjr keyboard NMI handler by setting DS to the BIOS data segment before calling INT 9. Fixes crashes in Shamus on the PCjr machine type. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3884 --- src/cpu/callback.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 53f86933..716608aa 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -304,22 +304,26 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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_writew(physAddress+0x05,(Bit16u)0x0b74); // je skip phys_writeb(physAddress+0x07,(Bit8u)0xFE); //GRP 4 phys_writeb(physAddress+0x08,(Bit8u)0x38); //Extra Callback instruction phys_writew(physAddress+0x09,(Bit16u)callback); //The immediate word physAddress+=4; } else { - phys_writew(physAddress+0x05,(Bit16u)0x0274); // je skip + phys_writew(physAddress+0x05,(Bit16u)0x0774); // je skip } - phys_writew(physAddress+0x07,(Bit16u)0x09cd); // int 9 + phys_writeb(physAddress+0x07,(Bit8u)0x1e); // push ds + phys_writew(physAddress+0x08,(Bit16u)0x406a); // push 0x0040 + phys_writeb(physAddress+0x0a,(Bit8u)0x1f); // pop ds + phys_writew(physAddress+0x0b,(Bit16u)0x09cd); // int 9 + phys_writeb(physAddress+0x0d,(Bit8u)0x1f); // pop ds // 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); + phys_writeb(physAddress+0x0e,(Bit8u)0xfa); // cli + phys_writew(physAddress+0x0f,(Bit16u)0x20b0); // mov al, 0x20 + phys_writew(physAddress+0x11,(Bit16u)0x20e6); // out 0x20, al + phys_writeb(physAddress+0x13,(Bit8u)0x58); // pop ax + phys_writeb(physAddress+0x14,(Bit8u)0xcf); //An IRET Instruction + return (use_cb?0x19:0x15); case CB_MOUSE: phys_writew(physAddress+0x00,(Bit16u)0x07eb); // jmp i33hd physAddress+=9; From 56c3a4be9ce2c4cdff03d77b4cf276a230e29b8e Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 6 Jan 2015 18:32:47 +0000 Subject: [PATCH 3795/4131] Make the shell's internal run loop more like the command prompt run loop. Fixes CALLed batch files when executed in subshells, such as with Norton/Volkov Commander. Reference SourceForge bug #394. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3885 --- src/shell/shell.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 76cdd404..997c8e11 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -265,21 +265,21 @@ void DOS_Shell::ParseLine(char * line) { -void DOS_Shell::RunInternal(void) -{ +void DOS_Shell::RunInternal(void) { char input_line[CMD_MAXLINE] = {0}; - while(bf && bf->ReadLine(input_line)) - { - if (echo) { + while (bf) { + if (bf->ReadLine(input_line)) { + if (echo) { if (input_line[0] != '@') { ShowPrompt(); WriteOut_NoParsing(input_line); WriteOut_NoParsing("\n"); - }; - }; - ParseLine(input_line); + } + } + ParseLine(input_line); + if (echo) WriteOut_NoParsing("\n"); + } } - return; } void DOS_Shell::Run(void) { From 933174fb3e8aefc88c5b2ed4da991bb128401f65 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Thu, 8 Jan 2015 17:23:15 +0000 Subject: [PATCH 3796/4131] Add support for High Sierra format cdrom images. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3886 --- src/dos/cdrom_image.cpp | 5 +-- src/dos/dos_mscdex.cpp | 67 +++++++++++++++++++++++------------------ src/dos/drive_iso.cpp | 38 +++++++++++++---------- src/dos/drives.h | 1 + 4 files changed, 64 insertions(+), 47 deletions(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 2a31d224..bd4cb411 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -416,8 +416,9 @@ bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mod if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16; if (mode2) seek += 24; file->read(pvd, seek, COOKED_SECTOR_SIZE); - // pvd[0] = descriptor type, pvd[1..5] = standard identifier, pvd[6] = iso version - return (pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1); + // pvd[0] = descriptor type, pvd[1..5] = standard identifier, pvd[6] = iso version (+8 for High Sierra) + return ((pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1) || + (pvd[8] == 1 && !strncmp((char*)(&pvd[9]), "CDROM", 5) && pvd[14] == 1)); } #if defined(WIN32) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index b0f1d187..ca406d71 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -117,7 +117,7 @@ public: bool GetAbstractName (Bit16u drive, PhysPt data); bool GetDocumentationName(Bit16u drive, PhysPt data); bool GetDirectoryEntry (Bit16u drive, bool copyFlag, PhysPt pathname, PhysPt buffer, Bit16u& error); - bool ReadVTOC (Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error); + bool ReadVTOC (Bit16u drive, Bit16u volume, PhysPt data, Bit16u& offset, Bit16u& error); bool ReadSectors (Bit16u drive, Bit32u sector, Bit16u num, PhysPt data); bool ReadSectors (Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data); bool ReadSectorsMSF (Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data); @@ -577,7 +577,7 @@ Bit32u CMscdex::GetVolumeSize(Bit8u subUnit) { return 0; } -bool CMscdex::ReadVTOC(Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error) { +bool CMscdex::ReadVTOC(Bit16u drive, Bit16u volume, PhysPt data, Bit16u& offset, Bit16u& error) { Bit8u subunit = GetSubUnit(drive); /* if (subunit>=numDrives) { error=MSCDEX_ERROR_UNKNOWN_DRIVE; @@ -589,11 +589,16 @@ bool CMscdex::ReadVTOC(Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error) } char id[5]; MEM_BlockRead(data + 1, id, 5); - if (strncmp("CD001",id, 5)!=0) { - error = MSCDEX_ERROR_BAD_FORMAT; - return false; + if (strncmp("CD001", id, 5)==0) offset = 0; + else { + MEM_BlockRead(data + 9, id, 5); + if (strncmp("CDROM", id, 5)==0) offset = 8; + else { + error = MSCDEX_ERROR_BAD_FORMAT; + return false; + } } - Bit8u type = mem_readb(data); + Bit8u type = mem_readb(data + offset); error = (type == 1) ? 1 : (type == 0xFF) ? 0xFF : 0; return true; } @@ -602,12 +607,12 @@ bool CMscdex::GetVolumeName(Bit8u subUnit, char* data) { if (subUnit>=numDrives) return false; Bit16u drive = dinfo[subUnit].drive; - Bit16u error; + Bit16u offset = 0, error; bool success = false; PhysPt ptoc = GetTempBuffer(); - success = ReadVTOC(drive,0x00,ptoc,error); + success = ReadVTOC(drive,0x00,ptoc,offset,error); if (success) { - MEM_StrCopy(ptoc+40,data,31); + MEM_StrCopy(ptoc+offset+40,data,31); data[31] = 0; rtrim(data); }; @@ -616,51 +621,51 @@ bool CMscdex::GetVolumeName(Bit8u subUnit, char* data) { } bool CMscdex::GetCopyrightName(Bit16u drive, PhysPt data) { - Bit16u error; + Bit16u offset = 0, error; bool success = false; PhysPt ptoc = GetTempBuffer(); - success = ReadVTOC(drive,0x00,ptoc,error); + success = ReadVTOC(drive,0x00,ptoc,offset,error); if (success) { Bitu len; for (len=0;len<37;len++) { - Bit8u c=mem_readb(ptoc+702+len); + Bit8u c=mem_readb(ptoc+offset+702+len); if (c==0 || c==0x20) break; } - MEM_BlockCopy(data,ptoc+702,len); + MEM_BlockCopy(data,ptoc+offset+702,len); mem_writeb(data+len,0); }; return success; } bool CMscdex::GetAbstractName(Bit16u drive, PhysPt data) { - Bit16u error; + Bit16u offset = 0, error; bool success = false; PhysPt ptoc = GetTempBuffer(); - success = ReadVTOC(drive,0x00,ptoc,error); + success = ReadVTOC(drive,0x00,ptoc,offset,error); if (success) { Bitu len; for (len=0;len<37;len++) { - Bit8u c=mem_readb(ptoc+739+len); + Bit8u c=mem_readb(ptoc+offset+739+len); if (c==0 || c==0x20) break; } - MEM_BlockCopy(data,ptoc+739,len); + MEM_BlockCopy(data,ptoc+offset+739,len); mem_writeb(data+len,0); }; return success; } bool CMscdex::GetDocumentationName(Bit16u drive, PhysPt data) { - Bit16u error; + Bit16u offset = 0, error; bool success = false; PhysPt ptoc = GetTempBuffer(); - success = ReadVTOC(drive,0x00,ptoc,error); + success = ReadVTOC(drive,0x00,ptoc,offset,error); if (success) { Bitu len; for (len=0;len<37;len++) { - Bit8u c=mem_readb(ptoc+776+len); + Bit8u c=mem_readb(ptoc+offset+776+len); if (c==0 || c==0x20) break; } - MEM_BlockCopy(data,ptoc+776,len); + MEM_BlockCopy(data,ptoc+offset+776,len); mem_writeb(data+len,0); }; return success; @@ -718,13 +723,17 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph // read vtoc PhysPt defBuffer = GetDefaultBuffer(); if (!ReadSectors(GetSubUnit(drive),false,16,1,defBuffer)) return false; - // TODO: has to be iso 9960 MEM_StrCopy(defBuffer+1,volumeID,5); volumeID[5] = 0; - bool iso = (strcmp("CD001",volumeID)==0); - if (!iso) E_Exit("MSCDEX: GetDirEntry: Not an ISO 9960 CD."); + Bit16u offset; + if (strcmp("CD001",volumeID)==0) offset = 156; + else { + MEM_StrCopy(defBuffer+9,volumeID,5); + if (strcmp("CDROM",volumeID)==0) offset = 180; + else E_Exit("MSCDEX: GetDirEntry: Not an ISO 9660 or High Sierra CD."); + } // get directory position - Bitu dirEntrySector = mem_readd(defBuffer+156+2); - Bits dirSize = mem_readd(defBuffer+156+10); + Bitu dirEntrySector = mem_readd(defBuffer+offset+2); + Bits dirSize = mem_readd(defBuffer+offset+10); Bitu index; while (dirSize>0) { index = 0; @@ -790,7 +799,7 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph // Direct copy MEM_BlockCopy(buffer,defBuffer+index,entryLength); } - error = iso ? 1:0; + error = 1; return true; } // change directory @@ -1203,8 +1212,8 @@ static bool MSCDEX_Handler(void) { }; return true; case 0x1505: { // read vtoc - Bit16u error = 0; - if (mscdex->ReadVTOC(reg_cx,reg_dx,data,error)) { + Bit16u offset = 0, error = 0; + if (mscdex->ReadVTOC(reg_cx,reg_dx,data,offset,error)) { // reg_ax = error; // return code CALLBACK_SCF(false); } else { diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 8e4d96d0..6be44bd8 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -25,6 +25,9 @@ #include "support.h" #include "drives.h" +#define FLAGS1 ((iso) ? de.fileFlags : de.timeZone) +#define FLAGS2 ((iso) ? de->fileFlags : de->timeZone) + using namespace std; class isoFile : public DOS_File { @@ -198,7 +201,7 @@ bool isoDrive::FileOpen(DOS_File **file, char *name, Bit32u flags) { } isoDirEntry de; - bool success = lookup(&de, name) && !IS_DIR(de.fileFlags); + bool success = lookup(&de, name) && !IS_DIR(FLAGS1); if (success) { FileStat_Block file_stat; @@ -234,7 +237,7 @@ bool isoDrive::MakeDir(char* /*dir*/) { bool isoDrive::TestDir(char *dir) { isoDirEntry de; - return (lookup(&de, dir) && IS_DIR(de.fileFlags)); + return (lookup(&de, dir) && IS_DIR(FLAGS1)); } bool isoDrive::FindFirst(char *dir, DOS_DTA &dta, bool fcb_findfirst) { @@ -279,11 +282,11 @@ bool isoDrive::FindNext(DOS_DTA &dta) { isoDirEntry de; while (GetNextDirEntry(dirIterator, &de)) { Bit8u findAttr = 0; - if (IS_DIR(de.fileFlags)) findAttr |= DOS_ATTR_DIRECTORY; + if (IS_DIR(FLAGS1)) findAttr |= DOS_ATTR_DIRECTORY; else findAttr |= DOS_ATTR_ARCHIVE; - if (IS_HIDDEN(de.fileFlags)) findAttr |= DOS_ATTR_HIDDEN; + if (IS_HIDDEN(FLAGS1)) findAttr |= DOS_ATTR_HIDDEN; - if (!IS_ASSOC(de.fileFlags) && !(isRoot && de.ident[0]=='.') && WildFileCmp((char*)de.ident, pattern) + if (!IS_ASSOC(FLAGS1) && !(isRoot && de.ident[0]=='.') && WildFileCmp((char*)de.ident, pattern) && !(~attr & findAttr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM))) { /* file is okay, setup everything to be copied in DTA Block */ @@ -318,8 +321,8 @@ bool isoDrive::GetFileAttr(char *name, Bit16u *attr) { bool success = lookup(&de, name); if (success) { *attr = DOS_ATTR_ARCHIVE | DOS_ATTR_READ_ONLY; - if (IS_HIDDEN(de.fileFlags)) *attr |= DOS_ATTR_HIDDEN; - if (IS_DIR(de.fileFlags)) *attr |= DOS_ATTR_DIRECTORY; + if (IS_HIDDEN(FLAGS1)) *attr |= DOS_ATTR_HIDDEN; + if (IS_DIR(FLAGS1)) *attr |= DOS_ATTR_DIRECTORY; } return success; } @@ -334,7 +337,7 @@ bool isoDrive::AllocationInfo(Bit16u *bytes_sector, Bit8u *sectors_cluster, Bit1 bool isoDrive::FileExists(const char *name) { isoDirEntry de; - return (lookup(&de, name) && !IS_DIR(de.fileFlags)); + return (lookup(&de, name) && !IS_DIR(FLAGS1)); } bool isoDrive::FileStat(const char *name, FileStat_Block *const stat_block) { @@ -346,7 +349,7 @@ bool isoDrive::FileStat(const char *name, FileStat_Block *const stat_block) { stat_block->time = DOS_PackTime(de.timeHour, de.timeMin, de.timeSec); stat_block->size = DATA_LENGTH(de); stat_block->attr = DOS_ATTR_ARCHIVE | DOS_ATTR_READ_ONLY; - if (IS_DIR(de.fileFlags)) stat_block->attr |= DOS_ATTR_DIRECTORY; + if (IS_DIR(FLAGS1)) stat_block->attr |= DOS_ATTR_DIRECTORY; } return success; @@ -470,7 +473,7 @@ int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) { // modify file identifier for use with dosbox if ((de->length < 33 + de->fileIdentLength)) return -1; - if (IS_DIR(de->fileFlags)) { + if (IS_DIR(FLAGS2)) { if (de->fileIdentLength == 1 && de->ident[0] == 0) strcpy((char*)de->ident, "."); else if (de->fileIdentLength == 1 && de->ident[0] == 1) strcpy((char*)de->ident, ".."); else { @@ -499,11 +502,14 @@ int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) { } bool isoDrive :: loadImage() { - isoPVD pvd; + Bit8u pvd[COOKED_SECTOR_SIZE]; dataCD = false; - readSector((Bit8u*)(&pvd), ISO_FIRST_VD); - if (pvd.type != 1 || strncmp((char*)pvd.standardIdent, "CD001", 5) || pvd.version != 1) return false; - if (readDirEntry(&this->rootEntry, pvd.rootEntry)>0) { + readSector(pvd, ISO_FIRST_VD); + if (pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1) iso = true; + else if (pvd[8] == 1 && !strncmp((char*)(&pvd[9]), "CDROM", 5) && pvd[14] == 1) iso = false; + else return false; + Bit16u offset = iso ? 156 : 180; + if (readDirEntry(&this->rootEntry, &pvd[offset])>0) { dataCD = true; return true; } @@ -524,7 +530,7 @@ bool isoDrive :: lookup(isoDirEntry *de, const char *path) { bool found = false; // current entry must be a directory, abort otherwise - if (IS_DIR(de->fileFlags)) { + if (IS_DIR(FLAGS2)) { // remove the trailing dot if present size_t nameLength = strlen(name); @@ -535,7 +541,7 @@ bool isoDrive :: lookup(isoDirEntry *de, const char *path) { // look for the current path element int dirIterator = GetDirIterator(de); while (!found && GetNextDirEntry(dirIterator, de)) { - if (!IS_ASSOC(de->fileFlags) && (0 == strncasecmp((char*) de->ident, name, ISO_MAX_FILENAME_LENGTH))) { + if (!IS_ASSOC(FLAGS2) && (0 == strncasecmp((char*) de->ident, name, ISO_MAX_FILENAME_LENGTH))) { found = true; } } diff --git a/src/dos/drives.h b/src/dos/drives.h index 0138163b..9d22da8c 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -363,6 +363,7 @@ private: Bit8u data[ISO_FRAMESIZE]; } sectorHashEntries[ISO_MAX_HASH_TABLE_SIZE]; + bool iso; bool dataCD; isoDirEntry rootEntry; Bit8u mediaid; From 401d1296942f22cfa60097389ce74c76851308c0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 9 Jan 2015 08:57:43 +0000 Subject: [PATCH 3797/4131] Fix bug 392. '\0' check at the wrong place. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3887 --- src/shell/shell_misc.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index e51bba67..02ae2450 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -550,13 +550,13 @@ char * DOS_Shell::Which(char * name) { if (!GetEnvStr("PATH",temp)) return 0; const char * pathenv=temp.c_str(); if (!pathenv) return 0; - pathenv=strchr(pathenv,'='); + pathenv = strchr(pathenv,'='); if (!pathenv) return 0; pathenv++; Bitu i_path = 0; while (*pathenv) { /* remove ; and ;; at the beginning. (and from the second entry etc) */ - while(*pathenv && (*pathenv ==';')) + while(*pathenv == ';') pathenv++; /* get next entry */ @@ -566,7 +566,7 @@ char * DOS_Shell::Which(char * name) { if(i_path == DOS_PATHLENGTH) { /* If max size. move till next ; and terminate path */ - while(*pathenv != ';') + while(*pathenv && (*pathenv != ';')) pathenv++; path[DOS_PATHLENGTH - 1] = 0; } else path[i_path] = 0; From 017fda9ba0c455de13be725f79481788a4908e36 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 9 Jan 2015 10:50:17 +0000 Subject: [PATCH 3798/4131] Give some hints when we are on Z:\, but not on other drives. Always return the directory for the drive if the drive exists. Fixes/improves bug 390. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3888 --- src/shell/shell.cpp | 2 +- src/shell/shell_cmds.cpp | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 997c8e11..f7f8a4b5 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -462,7 +462,7 @@ void SHELL_Init() { MSG_Add("SHELL_ILLEGAL_SWITCH","Illegal switch: %s.\n"); MSG_Add("SHELL_MISSING_PARAMETER","Required parameter missing.\n"); MSG_Add("SHELL_CMD_CHDIR_ERROR","Unable to change to: %s.\n"); - MSG_Add("SHELL_CMD_CHDIR_HINT","To change to different drive type \033[31m%c:\033[0m\n"); + MSG_Add("SHELL_CMD_CHDIR_HINT","Hint: To change to different drive type \033[31m%c:\033[0m\n"); MSG_Add("SHELL_CMD_CHDIR_HINT_2","directoryname is longer than 8 characters and/or contains spaces.\nTry \033[31mcd %s\033[0m\n"); MSG_Add("SHELL_CMD_CHDIR_HINT_3","You are still on drive Z:, change to a mounted drive with \033[31mC:\033[0m.\n"); MSG_Add("SHELL_CMD_DATE_HELP","Displays or changes the internal date.\n"); diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 2fbfa618..731c3bc1 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -303,13 +303,25 @@ void DOS_Shell::CMD_EXIT(char * args) { void DOS_Shell::CMD_CHDIR(char * args) { HELP("CHDIR"); StripSpaces(args); + Bit8u drive = DOS_GetDefaultDrive()+'A'; + char dir[DOS_PATHLENGTH]; if (!*args) { - Bit8u drive=DOS_GetDefaultDrive()+'A'; - char dir[DOS_PATHLENGTH]; DOS_GetCurrentDir(0,dir); WriteOut("%c:\\%s\n",drive,dir); } else if(strlen(args) == 2 && args[1]==':') { - WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT"),toupper(*reinterpret_cast(&args[0]))); + Bit8u targetdrive = (args[0] | 0x20)-'a' + 1; + unsigned char targetdisplay = *reinterpret_cast(&args[0]); + if(!DOS_GetCurrentDir(targetdrive,dir)) { + if(drive == 'Z') { + WriteOut(MSG_Get("SHELL_EXECUTE_DRIVE_NOT_FOUND"),toupper(targetdisplay)); + } else { + WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); + } + return; + } + WriteOut("%c:\\%s\n",toupper(targetdisplay),dir); + if(drive == 'Z') + WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT"),toupper(targetdisplay)); } else if (!DOS_ChangeDir(args)) { /* Changedir failed. Check if the filename is longer then 8 and/or contains spaces */ @@ -334,8 +346,7 @@ void DOS_Shell::CMD_CHDIR(char * args) { temps += "~1"; WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_2"),temps.insert(0,slashpart).c_str()); } else { - Bit8u drive=DOS_GetDefaultDrive()+'A'; - if (drive=='Z') { + if (drive == 'Z') { WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_3")); } else { WriteOut(MSG_Get("SHELL_CMD_CHDIR_ERROR"),args); From 85667fbe0fa186965829ce865a16ce8e69bc3314 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 9 Jan 2015 14:58:45 +0000 Subject: [PATCH 3799/4131] Fix the possible/suggested values for integer properties. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3889 --- src/misc/setup.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 8e10c2c4..7251d2f8 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -245,7 +245,9 @@ char const* Property::Get_help() { bool Prop_int::CheckValue(Value const& in, bool warn) { - if(suggested_values.empty() && Property::CheckValue(in,warn)) return true; +// if(!suggested_values.empty() && Property::CheckValue(in,warn)) return true; + if(!suggested_values.empty()) return Property::CheckValue(in,warn); + //No >= and <= in Value type and == is ambigious int mi = min; int ma = max; @@ -409,7 +411,7 @@ bool Prop_multival::SetValue(std::string const& input) { } else if(local.size()) { //last argument in = local; local = ""; - } + } //Test Value. If it fails set default Value valtest (in,p->Get_type()); if(!p->CheckValue(valtest,true)) { From b81c813b8744cfec79befe7a14420e78bb3e5f88 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 9 Jan 2015 15:00:18 +0000 Subject: [PATCH 3800/4131] Initialise all fields when constructing, fixes unintentional value reuse with Prop_multival. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3890 --- include/setup.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/setup.h b/include/setup.h index b17d9e01..7c8ad3dc 100644 --- a/include/setup.h +++ b/include/setup.h @@ -86,7 +86,7 @@ public: 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);} + Value(std::string const& in,Etype _t) :_hex(0),_bool(false),_int(0),_string(0),_double(0),type(V_NONE) {SetValue(in,_t);} /* Assigment operators */ Value& operator= (Hex in) throw(WrongType) { return copy(Value(in));} From 3e5241947ccd5b4736ff09ab302b5b79000f4e21 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sat, 10 Jan 2015 13:16:22 +0000 Subject: [PATCH 3801/4131] Mapper enhancements: Run mapper through an event to prevent crash on exit when mapper key is deleted. Display disabled items or events with no binding in grey color. Simplify joystick array init with a memset. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3891 --- src/gui/sdl_mapper.cpp | 111 ++++++++++++++++++++++------------------- 1 file changed, 59 insertions(+), 52 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 923eb2ec..aa861cd7 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -36,13 +36,15 @@ #include "support.h" #include "mapper.h" #include "setup.h" +#include "pic.h" enum { CLR_BLACK=0, - CLR_WHITE=1, - CLR_RED=2, - CLR_BLUE=3, - CLR_GREEN=4 + CLR_GREY=1, + CLR_WHITE=2, + CLR_RED=3, + CLR_BLUE=4, + CLR_GREEN=5 }; enum BB_Types { @@ -1263,7 +1265,6 @@ void CBindGroup::ActivateBindList(CBindList * list,Bits value,bool ev_trigger) { } } for (it=list->begin();it!=list->end();it++) { - /*BUG:CRASH if keymapper key is removed*/ if (validmod==(*it)->mods) (*it)->ActivateBind(value,ev_trigger); } } @@ -1317,6 +1318,7 @@ public: virtual bool OnTop(Bitu _x,Bitu _y) { return ( enabled && (_x>=x) && (_x=y) && (_ySetColor(event->bindlist.begin()==event->bindlist.end() ? CLR_GREY : CLR_WHITE); + } void Click(void) { - if (last_clicked) last_clicked->SetColor(CLR_WHITE); + if (last_clicked) last_clicked->BindColor(); this->SetColor(CLR_GREEN); SetActiveEvent(event); last_clicked=this; @@ -1748,7 +1753,7 @@ struct KeyBlock { KBD_KEYS key; }; static KeyBlock combo_f[12]={ - {"F1","f1",KBD_f1}, {"F2","f2",KBD_f2}, {"F3","f3",KBD_f3}, + {"F1","f1",KBD_f1}, {"F2","f2",KBD_f2}, {"F3","f3",KBD_f3}, {"F4","f4",KBD_f4}, {"F5","f5",KBD_f5}, {"F6","f6",KBD_f6}, {"F7","f7",KBD_f7}, {"F8","f8",KBD_f8}, {"F9","f9",KBD_f9}, {"F10","f10",KBD_f10}, {"F11","f11",KBD_f11}, {"F12","f12",KBD_f12}, @@ -1758,32 +1763,32 @@ static KeyBlock combo_1[14]={ {"`~","grave",KBD_grave}, {"1!","1",KBD_1}, {"2@","2",KBD_2}, {"3#","3",KBD_3}, {"4$","4",KBD_4}, {"5%","5",KBD_5}, {"6^","6",KBD_6}, {"7&","7",KBD_7}, {"8*","8",KBD_8}, - {"9(","9",KBD_9}, {"0)","0",KBD_0}, {"-_","minus",KBD_minus}, + {"9(","9",KBD_9}, {"0)","0",KBD_0}, {"-_","minus",KBD_minus}, {"=+","equals",KBD_equals}, {"\x1B","bspace",KBD_backspace}, }; static KeyBlock combo_2[12]={ - {"q","q",KBD_q}, {"w","w",KBD_w}, {"e","e",KBD_e}, - {"r","r",KBD_r}, {"t","t",KBD_t}, {"y","y",KBD_y}, - {"u","u",KBD_u}, {"i","i",KBD_i}, {"o","o",KBD_o}, - {"p","p",KBD_p}, {"[","lbracket",KBD_leftbracket}, - {"]","rbracket",KBD_rightbracket}, + {"Q","q",KBD_q}, {"W","w",KBD_w}, {"E","e",KBD_e}, + {"R","r",KBD_r}, {"T","t",KBD_t}, {"Y","y",KBD_y}, + {"U","u",KBD_u}, {"I","i",KBD_i}, {"O","o",KBD_o}, + {"P","p",KBD_p}, {"[{","lbracket",KBD_leftbracket}, + {"]}","rbracket",KBD_rightbracket}, }; static KeyBlock combo_3[12]={ - {"a","a",KBD_a}, {"s","s",KBD_s}, {"d","d",KBD_d}, - {"f","f",KBD_f}, {"g","g",KBD_g}, {"h","h",KBD_h}, - {"j","j",KBD_j}, {"k","k",KBD_k}, {"l","l",KBD_l}, - {";","semicolon",KBD_semicolon}, {"'","quote",KBD_quote}, - {"\\","backslash",KBD_backslash}, + {"A","a",KBD_a}, {"S","s",KBD_s}, {"D","d",KBD_d}, + {"F","f",KBD_f}, {"G","g",KBD_g}, {"H","h",KBD_h}, + {"J","j",KBD_j}, {"K","k",KBD_k}, {"L","l",KBD_l}, + {";:","semicolon",KBD_semicolon}, {"'\"","quote",KBD_quote}, + {"\\|","backslash",KBD_backslash}, }; static KeyBlock combo_4[11]={ - {"<","lessthan",KBD_extra_lt_gt}, - {"z","z",KBD_z}, {"x","x",KBD_x}, {"c","c",KBD_c}, - {"v","v",KBD_v}, {"b","b",KBD_b}, {"n","n",KBD_n}, - {"m","m",KBD_m}, {",","comma",KBD_comma}, - {".","period",KBD_period}, {"/","slash",KBD_slash}, + {"<>","lessthan",KBD_extra_lt_gt}, + {"Z","z",KBD_z}, {"X","x",KBD_x}, {"C","c",KBD_c}, + {"V","v",KBD_v}, {"B","b",KBD_b}, {"N","n",KBD_n}, + {"M","m",KBD_m}, {",<","comma",KBD_comma}, + {".>","period",KBD_period}, {"/?","slash",KBD_slash}, }; static CKeyEvent * caps_lock_event=NULL; @@ -1928,14 +1933,17 @@ static void CreateLayout(void) { AddJHatButton(PX(XO+8+2),PY(YO+1),BW,BH,"RGT",0,0,1); /* Labels for the joystick */ + CTextButton * btn; if (joytype ==JOY_2AXIS) { new CTextButton(PX(XO+0),PY(YO-1),3*BW,20,"Joystick 1"); new CTextButton(PX(XO+4),PY(YO-1),3*BW,20,"Joystick 2"); - new CTextButton(PX(XO+8),PY(YO-1),3*BW,20,"Disabled"); + btn=new CTextButton(PX(XO+8),PY(YO-1),3*BW,20,"Disabled"); + btn->SetColor(CLR_GREY); } else if(joytype ==JOY_4AXIS || joytype == JOY_4AXIS_2) { new CTextButton(PX(XO+0),PY(YO-1),3*BW,20,"Axis 1/2"); new CTextButton(PX(XO+4),PY(YO-1),3*BW,20,"Axis 3/4"); - new CTextButton(PX(XO+8),PY(YO-1),3*BW,20,"Disabled"); + btn=new CTextButton(PX(XO+8),PY(YO-1),3*BW,20,"Disabled"); + btn->SetColor(CLR_GREY); } else if(joytype == JOY_CH) { new CTextButton(PX(XO+0),PY(YO-1),3*BW,20,"Axis 1/2"); new CTextButton(PX(XO+4),PY(YO-1),3*BW,20,"Axis 3/4"); @@ -1945,9 +1953,12 @@ static void CreateLayout(void) { new CTextButton(PX(XO+4),PY(YO-1),3*BW,20,"Axis 3"); new CTextButton(PX(XO+8),PY(YO-1),3*BW,20,"Hat/D-pad"); } else if(joytype == JOY_NONE) { - new CTextButton(PX(XO+0),PY(YO-1),3*BW,20,"Disabled"); - new CTextButton(PX(XO+4),PY(YO-1),3*BW,20,"Disabled"); - new CTextButton(PX(XO+8),PY(YO-1),3*BW,20,"Disabled"); + btn=new CTextButton(PX(XO+0),PY(YO-1),3*BW,20,"Disabled"); + btn->SetColor(CLR_GREY); + btn=new CTextButton(PX(XO+4),PY(YO-1),3*BW,20,"Disabled"); + btn->SetColor(CLR_GREY); + btn=new CTextButton(PX(XO+8),PY(YO-1),3*BW,20,"Disabled"); + btn->SetColor(CLR_GREY); } @@ -1969,7 +1980,7 @@ static void CreateLayout(void) { // new CTextButton(PX(6),0,124,20,"Keyboard Layout"); // new CTextButton(PX(17),0,124,20,"Joystick Layout"); - bind_but.action=new CCaptionButton(180,330,0,0); + bind_but.action=new CCaptionButton(180,350,0,0); bind_but.event_title=new CCaptionButton(0,350,0,0); bind_but.bind_title=new CCaptionButton(0,365,0,0); @@ -1992,12 +2003,13 @@ static void CreateLayout(void) { bind_but.bind_title->Change("Bind Title"); } -static SDL_Color map_pal[5]={ +static SDL_Color map_pal[6]={ {0x00,0x00,0x00,0x00}, //0=black - {0xff,0xff,0xff,0x00}, //1=white - {0xff,0x00,0x00,0x00}, //2=red - {0x10,0x30,0xff,0x00}, //3=blue - {0x00,0xff,0x20,0x00} //4=green + {0x7f,0x7f,0x7f,0x00}, //1=grey + {0xff,0xff,0xff,0x00}, //2=white + {0xff,0x00,0x00,0x00}, //3=red + {0x10,0x30,0xff,0x00}, //4=blue + {0x00,0xff,0x20,0x00} //5=green }; static void CreateStringBind(char * line) { @@ -2321,14 +2333,18 @@ void MAPPER_LosingFocus(void) { } } -void MAPPER_Run(bool pressed) { - if (pressed) - return; +void MAPPER_RunEvent(Bitu /*val*/) { KEYBOARD_ClrBuffer(); //Clear buffer GFX_LosingFocus(); //Release any keys pressed (buffer gets filled again). MAPPER_RunInternal(); } +void MAPPER_Run(bool pressed) { + if (pressed) + return; + PIC_AddEvent(MAPPER_RunEvent,0); //In case mapper deletes the key object that ran it +} + SDL_Surface* SDL_SetVideoMode_Wrap(int width,int height,int bpp,Bit32u flags); void MAPPER_RunInternal() { @@ -2346,9 +2362,9 @@ void MAPPER_RunInternal() { if (mapper.surface == NULL) E_Exit("Could not initialize video mode for mapper: %s",SDL_GetError()); /* Set some palette entries */ - SDL_SetPalette(mapper.surface, SDL_LOGPAL|SDL_PHYSPAL, map_pal, 0, 5); + SDL_SetPalette(mapper.surface, SDL_LOGPAL|SDL_PHYSPAL, map_pal, 0, 6); if (last_clicked) { - last_clicked->SetColor(CLR_WHITE); + last_clicked->BindColor(); last_clicked=NULL; } /* Go in the event loop */ @@ -2379,6 +2395,9 @@ void MAPPER_Init(void) { CreateLayout(); CreateBindGroups(); if (!MAPPER_LoadBinds()) CreateDefaultBinds(); + for (CButton_it but_it = buttons.begin();but_it!=buttons.end();but_it++) { + (*but_it)->BindColor(); + } if (SDL_GetModState()&KMOD_CAPS) { for (CBindList_it bit=caps_lock_event->bindlist.begin();bit!=caps_lock_event->bindlist.end();bit++) { #if SDL_VERSION_ATLEAST(1, 2, 14) @@ -2409,19 +2428,7 @@ void MAPPER_StartUp(Section * sec) { Section_prop * section=static_cast(sec); mapper.sticks.num=0; mapper.sticks.num_groups=0; - Bitu i; - for (i=0; i Date: Sat, 10 Jan 2015 13:47:31 +0000 Subject: [PATCH 3802/4131] Arrange stack to restore registers when a child PSP is terminated. Fixes crashes in some demos (Blashphemy by Fatal Justice, Dreamwar by Elfsong, Mystic by Xenogenesis, et al). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3892 --- src/dos/dos_execute.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 5538d721..78572309 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -225,6 +225,10 @@ bool DOS_ChildPSP(Bit16u segment, Bit16u size) { psp.SetFCB2(RealMake(parent_psp_seg,0x6c)); psp.SetEnvironment(psp_parent.GetEnvironment()); psp.SetSize(size); + // push registers in case child PSP is terminated + SaveRegisters(); + psp.SetStack(RealMakeSeg(ss,reg_sp)); + reg_sp+=18; return true; } From 85c11c6fefd69fe9db60cf3bdcd706ef71d2173d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 14 Jan 2015 12:31:01 +0000 Subject: [PATCH 3803/4131] Add C_DEBUG checks around C_HEAVY_DEBUG, so you can leave C_HEAVY_DEBUG defined. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3893 --- src/cpu/core_dyn_x86.cpp | 12 ++++++++++-- src/cpu/core_dynrec.cpp | 6 ++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index ac05a569..0045394a 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -261,9 +261,11 @@ 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 C_DEBUG +#if C_HEAVY_DEBUG if (DEBUG_HeavyIsBreakpoint()) return debugCallback; - #endif +#endif +#endif CodePageHandler * chandler=0; if (GCC_UNLIKELY(MakeCodePage(ip_point,chandler))) { CPU_Exception(cpu.exception.which,cpu.exception.error); @@ -296,11 +298,13 @@ run_block: BlockReturn ret=gen_runcode(block->cache.start); switch (ret) { case BR_Iret: +#if C_DEBUG #if C_HEAVY_DEBUG if (DEBUG_HeavyIsBreakpoint()) { if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT return debugCallback; } +#endif #endif if (!GETFLAG(TF)) { if (GETFLAG(IF) && PIC_IRQCheck) { @@ -315,13 +319,17 @@ run_block: return CBRET_NONE; case BR_Normal: /* Maybe check if we staying in the same page? */ +#if C_DEBUG #if C_HEAVY_DEBUG if (DEBUG_HeavyIsBreakpoint()) return debugCallback; +#endif #endif goto restart_core; case BR_Cycles: +#if C_DEBUG #if C_HEAVY_DEBUG if (DEBUG_HeavyIsBreakpoint()) return debugCallback; +#endif #endif if (!dyn_dh_fpu.state_used) return CBRET_NONE; DH_FPU_SAVE_REINIT diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index f1d68d67..1571fb43 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -232,8 +232,10 @@ run_block: switch (ret) { case BR_Iret: +#if C_DEBUG #if C_HEAVY_DEBUG if (DEBUG_HeavyIsBreakpoint()) return debugCallback; +#endif #endif if (!GETFLAG(TF)) { if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; @@ -248,16 +250,20 @@ run_block: // modifying instruction (like ret) or some nontrivial cpu state // changing instruction (for example switch to/from pmode), // or the maximum number of instructions to translate was reached +#if C_DEBUG #if C_HEAVY_DEBUG if (DEBUG_HeavyIsBreakpoint()) return debugCallback; +#endif #endif break; case BR_Cycles: // cycles went negative, return from the core to handle // external events, schedule the pic... +#if C_DEBUG #if C_HEAVY_DEBUG if (DEBUG_HeavyIsBreakpoint()) return debugCallback; +#endif #endif return CBRET_NONE; From f9c67101c78e166fc31d6b52f4cc600ca2a031ba Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 21 Jan 2015 20:50:40 +0000 Subject: [PATCH 3804/4131] Workaround clang confusing itself (compile error), results in a small speed up in general (thanks for helping wjp). clang compiled x64 dynrec core appears to be unstable though. (-O0 seems to help) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3894 --- src/cpu/core_dynrec/risc_x64.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index 58f9d2e9..0f1d9490 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -85,7 +85,8 @@ static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { static INLINE void gen_reg_memaddr(HostReg reg,void* data) { Bit64s diff = (Bit64s)data-((Bit64s)cache.pos+5); - if ((diff<0x80000000LL) && (diff>-0x80000000LL)) { +// if ((diff<0x80000000LL) && (diff>-0x80000000LL)) { //clang messes itself up on this... + if ( (diff>>63) == (diff>>31) ) { //signed bit extend, test to see if value fits in a Bit32s cache_addb(0x05+(reg<<3)); // RIP-relative addressing is offset after the instruction cache_addd((Bit32u)(((Bit64u)diff)&0xffffffffLL)); @@ -100,7 +101,8 @@ static INLINE void gen_reg_memaddr(HostReg reg,void* data) { static INLINE void gen_memaddr(Bitu op,void* data,Bitu off) { Bit64s diff; diff = (Bit64s)data-((Bit64s)cache.pos+off+5); - if ((diff<0x80000000LL) && (diff>-0x80000000LL)) { +// if ((diff<0x80000000LL) && (diff>-0x80000000LL)) { + if ( (diff>>63) == (diff>>31) ) { // RIP-relative addressing is offset after the instruction cache_addb(op+1); cache_addd((Bit32u)(((Bit64u)diff)&0xffffffffLL)); From 3c8a5bdc958bf80d157f6a1e836d43a9d8611a7c Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Wed, 28 Jan 2015 22:19:20 +0000 Subject: [PATCH 3805/4131] Scan for illegal characters in directory and file names after trimming to 8.3 rather than before. Fixes Hexx and maybe others that neglect the Z in ASCIIZ. Coalesce free memory blocks before resizing a block in case it grows; coalesce after after resizing only if the block shrinks. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3895 --- src/dos/dos_files.cpp | 46 ++++++++++++++++++++++-------------------- src/dos/dos_memory.cpp | 4 +--- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index c5bfa0a9..2e0e5a79 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -66,6 +66,7 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { char tempdir[DOS_PATHLENGTH]; char upname[DOS_PATHLENGTH]; Bitu r,w; + Bit8u c; *drive = DOS_GetDefaultDrive(); /* First get the drive */ if (name_int[1]==':') { @@ -78,28 +79,11 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { } r=0;w=0; while (name_int[r]!=0 && (r='a') && (c<='z')) {upname[w++]=c-32;continue;} - if ((c>='A') && (c<='Z')) {upname[w++]=c;continue;} - if ((c>='0') && (c<='9')) {upname[w++]=c;continue;} - switch (c) { - case '/': - upname[w++]='\\'; - break; - case ' ': /* should be seperator */ - break; - case '\\': case '$': case '#': case '@': case '(': case ')': - case '!': case '%': case '{': case '}': case '`': case '~': - case '_': case '-': case '.': case '*': case '?': case '&': - case '\'': case '+': case '^': case 246: case 255: case 0xa0: - case 0xe5: case 0xbd: case 0x9d: - upname[w++]=c; - break; - default: - LOG(LOG_FILES,LOG_NORMAL)("Makename encountered an illegal char %c hex:%X in %s!",c,c,name); - DOS_SetError(DOSERR_PATH_NOT_FOUND);return false; - break; - } + c=name_int[r++]; + if ((c>='a') && (c<='z')) c-=32; + else if (c==' ') continue; /* should be separator */ + else if (c=='/') c='\\'; + upname[w++]=c; } while (r>0 && name_int[r-1]==' ') r--; if (r>=DOS_PATHLENGTH) { DOS_SetError(DOSERR_PATH_NOT_FOUND);return false; } @@ -176,6 +160,24 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) { if((strlen(tempdir) - strlen(ext)) > 8) memmove(tempdir + 8, ext, 5); } else tempdir[8]=0; + for (Bitu i=0;i='A') && (c<='Z')) continue; + if ((c>='0') && (c<='9')) continue; + switch (c) { + case '$': case '#': case '@': case '(': case ')': + case '!': case '%': case '{': case '}': case '`': case '~': + case '_': case '-': case '.': case '*': case '?': case '&': + case '\'': case '+': case '^': case 246: case 255: case 0xa0: + case 0xe5: case 0xbd: case 0x9d: + break; + default: + LOG(LOG_FILES,LOG_NORMAL)("Makename encountered an illegal char %c hex:%X in %s!",c,c,name); + DOS_SetError(DOSERR_PATH_NOT_FOUND);return false; + break; + } + } + if (strlen(fullname)+strlen(tempdir)>=DOS_PATHLENGTH) { DOS_SetError(DOSERR_PATH_NOT_FOUND);return false; } diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 7ab32bdb..f59870fe 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -227,12 +227,12 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { return false; } + DOS_CompressMemory(); Bit16u total=mcb.GetSize(); DOS_MCB mcb_next(segment+total); if (*blocks<=total) { if (GCC_UNLIKELY(*blocks==total)) { /* Nothing to do */ - DOS_CompressMemory(); return true; } /* Shrinking MCB */ @@ -268,7 +268,6 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { mcb_next.SetPSPSeg(MCB_FREE); mcb.SetType(0x4d); mcb.SetPSPSeg(dos.psp()); - DOS_CompressMemory(); return true; } @@ -281,7 +280,6 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) { } mcb.SetSize(total); mcb.SetPSPSeg(dos.psp()); - DOS_CompressMemory(); if (*blocks==total) return true; /* block fit exactly */ *blocks=total; /* return maximum */ From 6cec6d144bc32069a51d77e2155c32ec8f7ecce3 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Wed, 28 Jan 2015 22:20:49 +0000 Subject: [PATCH 3806/4131] Do less to update the frequency of an active SB DMA transfer, and include DSP command 0x41 (fixes SB16 sound in Tempest 2000). Handle DSP command 0x42 as unimplemented, because it is. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3896 --- src/hardware/sblaster.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 875c75c8..d5da7e52 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -758,6 +758,16 @@ static void DSP_ADC_CallBack(DmaChannel * /*chan*/, DMAEvent event) { ch->Register_Callback(0); } +static void DSP_ChangeRate(Bitu freq) { + if (sb.freq!=freq && sb.dma.mode!=DSP_DMA_NONE) { + sb.chan->FillUp(); + sb.chan->SetFreq(freq / (sb.mixer.stereo ? 2 : 1)); + sb.dma.rate=(freq*sb.dma.mul) >> SB_SH; + sb.dma.min=(sb.dma.rate*3)/1000; + } + sb.freq=freq; +} + Bitu DEBUG_EnableDebugger(void); #define DSP_SB16_ONLY if (sb.type != SBT_16) { LOG(LOG_SB,LOG_ERROR)("DSP:Command %2X requires SB16",sb.dsp.cmd); break; } @@ -845,16 +855,14 @@ static void DSP_DoCommand(void) { if (sb.midi == true) MIDI_RawOutByte(sb.dsp.in.data[0]); break; case 0x40: /* Set Timeconstant */ - sb.freq=(1000000 / (256 - sb.dsp.in.data[0])); - /* Nasty kind of hack to allow runtime changing of frequency */ - if (sb.dma.mode != DSP_DMA_NONE && sb.dma.autoinit) { - DSP_PrepareDMA_Old(sb.dma.mode,sb.dma.autoinit,sb.dma.sign); - } + DSP_ChangeRate(1000000 / (256 - sb.dsp.in.data[0])); break; case 0x41: /* Set Output Samplerate */ - case 0x42: /* Set Input Samplerate */ DSP_SB16_ONLY; - sb.freq=(sb.dsp.in.data[0] << 8) | sb.dsp.in.data[1]; + DSP_ChangeRate((sb.dsp.in.data[0] << 8) | sb.dsp.in.data[1]); + break; + case 0x42: /* Set Input Samplerate */ + LOG(LOG_SB,LOG_ERROR)("DSP:Unimplemented input sample rate command"); break; case 0x48: /* Set DMA Block Size */ DSP_SB2_ABOVE; From f458d079833150a130fb006d060a92f9ab9dcb6c Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Wed, 11 Feb 2015 17:46:12 +0000 Subject: [PATCH 3807/4131] No response from MSCDEX when it's not installed/active. Allows install programs from the V for Victory series of games to work provided no cdrom drives are mounted. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3897 --- src/dos/dos_mscdex.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index ca406d71..ab166b47 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -1158,12 +1158,14 @@ static Bitu MSCDEX_Interrupt_Handler(void) { static bool MSCDEX_Handler(void) { if(reg_ah == 0x11) { if(reg_al == 0x00) { - PhysPt check = PhysMake(SegValue(ss),reg_sp); - if(mem_readw(check+6) == 0xDADA) { - //MSCDEX sets word on stack to ADAD if it DADA on entry. - mem_writew(check+6,0xADAD); + if (mscdex->GetNumDrives()>0) { + PhysPt check = PhysMake(SegValue(ss),reg_sp); + if(mem_readw(check+6) == 0xDADA) { + //MSCDEX sets word on stack to ADAD if it DADA on entry. + mem_writew(check+6,0xADAD); + } + reg_al = 0xff; } - reg_al = 0xff; return true; } else { LOG(LOG_MISC,LOG_ERROR)("NETWORK REDIRECTOR USED!!!"); @@ -1174,6 +1176,7 @@ static bool MSCDEX_Handler(void) { } if (reg_ah!=0x15) return false; // not handled here, continue chain + if (mscdex->GetNumDrives()==0) return true; // do nothing if MSCDEX not active PhysPt data = PhysMake(SegValue(es),reg_bx); MSCDEX_LOG("MSCDEX: INT 2F %04X BX= %04X CX=%04X",reg_ax,reg_bx,reg_cx); @@ -1181,7 +1184,7 @@ static bool MSCDEX_Handler(void) { case 0x1500: /* Install check */ reg_bx = mscdex->GetNumDrives(); - if (reg_bx>0) reg_cx = mscdex->GetFirstDrive(); + reg_cx = mscdex->GetFirstDrive(); reg_al = 0xff; return true; case 0x1501: /* Get cdrom driver info */ @@ -1287,7 +1290,7 @@ static bool MSCDEX_Handler(void) { } return true; }; - LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unknwon call : %04X",reg_ax); + LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unknown call : %04X",reg_ax); return true; } From 81ae7277e829e36c1afe16c73a44be59ad9e66fa Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 11 Feb 2015 18:12:36 +0000 Subject: [PATCH 3808/4131] Add --disable-fpu-x64 which is the same as --disable-fpu-x86 for clarity reasons Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3898 --- INSTALL | 3 ++- configure.ac | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/INSTALL b/INSTALL index f067f4b6..3fa05e9d 100644 --- a/INSTALL +++ b/INSTALL @@ -67,7 +67,8 @@ In step 1 you could add the following switches: 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 +--disable-fpu-x64 + disables the assembly fpu core. Although relatively new, the x86/x64 fpu core has more accuracy then the regular fpu core. --disable-dynamic-x86 diff --git a/configure.ac b/configure.ac index 8cf01bdf..847d6d33 100644 --- a/configure.ac +++ b/configure.ac @@ -328,10 +328,11 @@ else AC_MSG_RESULT(no) fi -AH_TEMPLATE(C_FPU_X86,[Define to 1 to use a x86 assembly fpu core]) +AH_TEMPLATE(C_FPU_X86,[Define to 1 to use a x86/x64 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_ARG_ENABLE(fpu-x64,AC_HELP_STRING([--disable-fpu-x64],[Disable x64 assembly fpu core]),,enable_fpu_x64=yes) +AC_MSG_CHECKING(whether the x86/x64 assembly fpu core will be enabled) +if test x$enable_fpu_x86 = xno -o x$enable_fpu_x64 = xno; then AC_MSG_RESULT(no) else if test x$enable_fpu = xyes; then From ef7ddd1504cd1a520f1bfd3a9e5d12d9e3c525e5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 11 Feb 2015 19:11:31 +0000 Subject: [PATCH 3809/4131] Use clock_gettime when available instead of the obsolete ftime. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3899 --- configure.ac | 6 ++++++ src/ints/bios.cpp | 19 ++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 847d6d33..0ff1bf87 100644 --- a/configure.ac +++ b/configure.ac @@ -129,6 +129,12 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]],[[ ]])], [AC_MSG_RESULT(yes)], [AC_DEFINE([DB_HAVE_NO_POWF],[1],[libm doesn't include powf])]) LIBS=$LIBS_BACKUP +dnl Look for clock_gettime, a DB_HAVE_CLOCK_GETTIME is set when present +AH_TEMPLATE([DB_HAVE_CLOCK_GETTIME],[Determines if the function clock_gettime is available.]) +AC_SEARCH_LIBS([clock_gettime], [rt] , [found_clock_gettime=yes], [found_clock_gettime=no]) +if test x$found_clock_gettime = xyes; then + AC_DEFINE(DB_HAVE_CLOCK_GETTIME) +fi dnl Checks for libraries. diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 5e1f306c..67cf8e5f 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -32,8 +32,11 @@ #include "setup.h" #include "serialport.h" #include +#ifdef DB_HAVE_CLOCK_GETTIME +//time.h is already included +#else #include - +#endif /* if mem_systems 0 then size_extended is reported as the real size else * zero is reported. ems and xms can increase or decrease the other_memsystems @@ -489,13 +492,23 @@ static Bitu INT11_Handler(void) { #endif static void BIOS_HostTimeSync() { + Bit32u milli = 0; +#ifdef DB_HAVE_CLOCK_GETTIME + struct timespec tp; + clock_gettime(CLOCK_REALTIME,&tp); + + struct tm *loctime; + loctime = localtime(&tp.tv_sec); + milli = (Bit32u) (tp.tv_nsec / 1000000); +#else /* Setup time and date */ struct timeb timebuffer; ftime(&timebuffer); struct tm *loctime; loctime = localtime (&timebuffer.time); - + milli = (Bit32u) timebuffer.millitm; +#endif /* loctime->tm_hour = 23; loctime->tm_min = 59; @@ -513,7 +526,7 @@ static void BIOS_HostTimeSync() { loctime->tm_hour*3600*1000+ loctime->tm_min*60*1000+ loctime->tm_sec*1000+ - timebuffer.millitm))*(((double)PIT_TICK_RATE/65536.0)/1000.0)); + milli))*(((double)PIT_TICK_RATE/65536.0)/1000.0)); mem_writed(BIOS_TIMER,ticks); } From c0a3903ec0712de78b381ad46cf4d66343dc5153 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Wed, 11 Feb 2015 20:45:29 +0000 Subject: [PATCH 3810/4131] Map a single 4kB page of video memory that repeats in the 32kB range when in Hercules text mode, making it compatible with MDA. Fixes Future Wars and Operation Stealth install programs on the Hercules machine type. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3900 --- src/hardware/vga_memory.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 974527c0..0a538801 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -730,6 +730,20 @@ public: } }; +class VGA_HERC_Handler : public PageHandler { +public: + VGA_HERC_Handler() { + flags=PFLAG_READABLE|PFLAG_WRITEABLE; + } + HostPt GetHostReadPt(Bitu phys_page) { + // The 4kB map area is repeated in the 32kB range + return &vga.mem.linear[0]; + } + HostPt GetHostWritePt(Bitu phys_page) { + return GetHostReadPt( phys_page ); + } +}; + class VGA_Empty_Handler : public PageHandler { public: VGA_Empty_Handler() { @@ -754,6 +768,7 @@ static struct vg { VGA_UnchainedEGA_Handler uega; VGA_UnchainedVGA_Handler uvga; VGA_PCJR_Handler pcjr; + VGA_HERC_Handler herc; VGA_LIN4_Handler lin4; VGA_LFB_Handler lfb; VGA_LFBChanges_Handler lfbchanges; @@ -789,7 +804,7 @@ void VGA_SetupHandlers(void) { } else { vgapages.mask=0x7fff; /* With hercules in 32kb mode it leaves a memory hole on 0xb800 */ - MEM_SetPageHandler(VGA_PAGE_B0,8,&vgaph.map); + MEM_SetPageHandler(VGA_PAGE_B0,8,&vgaph.herc); MEM_SetPageHandler(VGA_PAGE_B8,8,&vgaph.empty); } goto range_done; From 0b568ebbd0a74d0cc50f8525d9cc1fadfe194dea Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 24 Feb 2015 13:54:43 +0000 Subject: [PATCH 3811/4131] correct typo in the includeguards Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3901 --- src/cpu/lazyflags.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index 726d36bb..c5e599f5 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -16,8 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#if !defined __LAZYFLAGS_H -#define __LAZYFLAG_H +#ifndef DOSBOX_LAZYFLAGS_H +#define DOSBOX_LAZYFLAGS_H //Flag Handling Bit32u get_CF(void); @@ -31,7 +31,9 @@ Bitu FillFlags(void); void FillFlagsNoCFOF(void); void DestroyConditionFlags(void); +#ifndef DOSBOX_REGS_H #include "regs.h" +#endif struct LazyFlags { GenReg32 var1,var2,res; From bd6e01565dbec72a1062838645659b86c353756b Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Fri, 13 Mar 2015 12:35:30 +0000 Subject: [PATCH 3812/4131] Amend previous MSCDEX change to use presence of cdrom device to determine the installed condition, which means unmounting will not revert to the uninstalled condition. Pass unhandled functions back to the multiplex handler, which if nothing else will generate log messages about them being unhandled. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3902 --- src/dos/dos_mscdex.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index ab166b47..d33af13d 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -1158,14 +1158,13 @@ static Bitu MSCDEX_Interrupt_Handler(void) { static bool MSCDEX_Handler(void) { if(reg_ah == 0x11) { if(reg_al == 0x00) { - if (mscdex->GetNumDrives()>0) { - PhysPt check = PhysMake(SegValue(ss),reg_sp); - if(mem_readw(check+6) == 0xDADA) { - //MSCDEX sets word on stack to ADAD if it DADA on entry. - mem_writew(check+6,0xADAD); - } - reg_al = 0xff; + if (mscdex->rootDriverHeaderSeg==0) return false; + PhysPt check = PhysMake(SegValue(ss),reg_sp); + if(mem_readw(check+6) == 0xDADA) { + //MSCDEX sets word on stack to ADAD if it DADA on entry. + mem_writew(check+6,0xADAD); } + reg_al = 0xff; return true; } else { LOG(LOG_MISC,LOG_ERROR)("NETWORK REDIRECTOR USED!!!"); @@ -1176,7 +1175,7 @@ static bool MSCDEX_Handler(void) { } if (reg_ah!=0x15) return false; // not handled here, continue chain - if (mscdex->GetNumDrives()==0) return true; // do nothing if MSCDEX not active + if (mscdex->rootDriverHeaderSeg==0) return false; // not handled if MSCDEX not installed PhysPt data = PhysMake(SegValue(es),reg_bx); MSCDEX_LOG("MSCDEX: INT 2F %04X BX= %04X CX=%04X",reg_ax,reg_bx,reg_cx); @@ -1184,7 +1183,7 @@ static bool MSCDEX_Handler(void) { case 0x1500: /* Install check */ reg_bx = mscdex->GetNumDrives(); - reg_cx = mscdex->GetFirstDrive(); + if (reg_bx>0) reg_cx = mscdex->GetFirstDrive(); reg_al = 0xff; return true; case 0x1501: /* Get cdrom driver info */ From 8a464fb31251820fef866e72e65299462d03e265 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Fri, 13 Mar 2015 12:42:12 +0000 Subject: [PATCH 3813/4131] Amend previous Hercules change so the MDA-compatible address wrapping is used only when graphics are disabled, but still only in 32kB mode. Thanks TheGreatCodeholio, and thanks Great Hierophant for testing on a real Hercules card. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3903 --- src/hardware/vga_memory.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 0a538801..39d4d8fc 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -803,8 +803,12 @@ void VGA_SetupHandlers(void) { MEM_SetPageHandler(VGA_PAGE_B0,16,&vgaph.map); } else { vgapages.mask=0x7fff; - /* With hercules in 32kb mode it leaves a memory hole on 0xb800 */ - MEM_SetPageHandler(VGA_PAGE_B0,8,&vgaph.herc); + // With hercules in 32kB mode it leaves a memory hole on 0xb800 + // and has MDA-compatible address wrapping when graphics are disabled + if (vga.herc.enable_bits & 0x1) + MEM_SetPageHandler(VGA_PAGE_B0,8,&vgaph.map); + else + MEM_SetPageHandler(VGA_PAGE_B0,8,&vgaph.herc); MEM_SetPageHandler(VGA_PAGE_B8,8,&vgaph.empty); } goto range_done; From 4a221045be9a01367d167cb7db9f3e167f84ebc8 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Fri, 13 Mar 2015 13:05:18 +0000 Subject: [PATCH 3814/4131] Allow CRTC read/write access on all mirror ports for non-VGA machine types. Fixes Tandy and EGA display in International Hockey booter. Thanks Great Hierophant for testing on real systems. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3904 --- src/hardware/vga_misc.cpp | 42 +++++++++++++++----------------------- src/hardware/vga_other.cpp | 13 +----------- 2 files changed, 18 insertions(+), 37 deletions(-) diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 3c7e0bd9..0271f265 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -57,34 +57,26 @@ Bitu vga_read_p3da(Bitu port,Bitu iolen) { static void write_p3c2(Bitu port,Bitu val,Bitu iolen) { vga.misc_output=val; - if (val & 0x1) { - IO_RegisterWriteHandler(0x3d4,vga_write_p3d4,IO_MB); - IO_RegisterReadHandler(0x3d4,vga_read_p3d4,IO_MB); - IO_RegisterReadHandler(0x3da,vga_read_p3da,IO_MB); - IO_RegisterWriteHandler(0x3d5,vga_write_p3d5,IO_MB); - IO_RegisterReadHandler(0x3d5,vga_read_p3d5,IO_MB); + Bitu base=(val & 0x1) ? 0x3d0 : 0x3b0; + Bitu free=(val & 0x1) ? 0x3b0 : 0x3d0; + Bitu first=2, last=2; + if (machine==MCH_EGA) {first=0; last=3;} - IO_FreeWriteHandler(0x3b4,IO_MB); - IO_FreeReadHandler(0x3b4,IO_MB); - IO_FreeWriteHandler(0x3b5,IO_MB); - IO_FreeReadHandler(0x3b5,IO_MB); - IO_FreeReadHandler(0x3ba,IO_MB); - } else { - IO_RegisterWriteHandler(0x3b4,vga_write_p3d4,IO_MB); - IO_RegisterReadHandler(0x3b4,vga_read_p3d4,IO_MB); - IO_RegisterReadHandler(0x3ba,vga_read_p3da,IO_MB); - - IO_RegisterWriteHandler(0x3b5,vga_write_p3d5,IO_MB); - IO_RegisterReadHandler(0x3b5,vga_read_p3d5,IO_MB); - - - IO_FreeWriteHandler(0x3d4,IO_MB); - IO_FreeReadHandler(0x3d4,IO_MB); - IO_FreeWriteHandler(0x3d5,IO_MB); - IO_FreeReadHandler(0x3d5,IO_MB); - IO_FreeReadHandler(0x3da,IO_MB); + for (Bitu i=first; i<=last; i++) { + IO_RegisterWriteHandler(base+i*2,vga_write_p3d4,IO_MB); + IO_RegisterReadHandler(base+i*2,vga_read_p3d4,IO_MB); + IO_RegisterWriteHandler(base+i*2+1,vga_write_p3d5,IO_MB); + IO_RegisterReadHandler(base+i*2+1,vga_read_p3d5,IO_MB); + IO_FreeWriteHandler(free+i*2,IO_MB); + IO_FreeReadHandler(free+i*2,IO_MB); + IO_FreeWriteHandler(free+i*2+1,IO_MB); + IO_FreeReadHandler(free+i*2+1,IO_MB); } + + IO_RegisterReadHandler(base+0xa,vga_read_p3da,IO_MB); + IO_FreeReadHandler(free+0xa,IO_MB); + /* 0 If set Color Emulation. Base Address=3Dxh else Mono Emulation. Base Address=3Bxh. 2-3 Clock Select. 0: 25MHz, 1: 28MHz diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 373d7bcf..b91fe562 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -835,9 +835,6 @@ void VGA_SetupOther(void) { write_pcjr( 0x3df, 0x7 | (0x7 << 3), 0 ); IO_RegisterWriteHandler(0x3da,write_pcjr,IO_MB); IO_RegisterWriteHandler(0x3df,write_pcjr,IO_MB); - // additional CRTC access documented - IO_RegisterWriteHandler(0x3d0,write_crtc_index_other,IO_MB); - IO_RegisterWriteHandler(0x3d1,write_crtc_data_other,IO_MB); } if (machine==MCH_HERC) { Bitu base=0x3b0; @@ -855,8 +852,7 @@ void VGA_SetupOther(void) { IO_RegisterWriteHandler(0x3b8,write_hercules,IO_MB); IO_RegisterWriteHandler(0x3bf,write_hercules,IO_MB); IO_RegisterReadHandler(0x3ba,read_herc_status,IO_MB); - } - if (machine==MCH_CGA) { + } else if (!IS_EGAVGA_ARCH) { Bitu base=0x3d0; for (Bitu port_ct=0; port_ct<4; port_ct++) { IO_RegisterWriteHandler(base+port_ct*2,write_crtc_index_other,IO_MB); @@ -865,12 +861,5 @@ void VGA_SetupOther(void) { IO_RegisterReadHandler(base+port_ct*2+1,read_crtc_data_other,IO_MB); } } - if (IS_TANDY_ARCH) { - Bitu base=0x3d4; - IO_RegisterWriteHandler(base,write_crtc_index_other,IO_MB); - IO_RegisterWriteHandler(base+1,write_crtc_data_other,IO_MB); - IO_RegisterReadHandler(base,read_crtc_index_other,IO_MB); - IO_RegisterReadHandler(base+1,read_crtc_data_other,IO_MB); - } } From 235939e277edf5a01aeada1162191a82f10a03d3 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Fri, 13 Mar 2015 13:47:26 +0000 Subject: [PATCH 3815/4131] Attempting to unlink (delete) an existing device name returns an access denied error. Fixes EMM device driver detection, and thus SoundBlaster sound, in the Striker soccer game. Also add a log message for FindFirst. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3905 --- src/dos/dos_files.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 2e0e5a79..a37b4cf8 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -309,6 +309,7 @@ bool DOS_Rename(char const * const oldname,char const * const newname) { } bool DOS_FindFirst(char * search,Bit16u attr,bool fcb_findfirst) { + LOG(LOG_FILES,LOG_NORMAL)("file search attributes %X name %s",attr,search); DOS_DTA dta(dos.dta()); Bit8u drive;char fullsearch[DOS_PATHLENGTH]; char dir[DOS_PATHLENGTH];char pattern[DOS_PATHLENGTH]; @@ -633,6 +634,11 @@ bool DOS_OpenFileExtended(char const * name, Bit16u flags, Bit16u createAttr, Bi bool DOS_UnlinkFile(char const * const name) { char fullname[DOS_PATHLENGTH];Bit8u drive; + // An existing device returns an access denied error + if (DOS_FindDevice(name) != DOS_DEVICES) { + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; + } if (!DOS_MakeName(name,fullname,&drive)) return false; if(Drives[drive]->FileUnlink(fullname)){ return true; From 1363f5ed68a4ed67d166ee7778ed738c3eca896b Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Fri, 13 Mar 2015 13:52:48 +0000 Subject: [PATCH 3816/4131] Add support for DOS 1.x floppy images. Also a small fix to the FAT drive FindNext so it doesn't require a terminating entry in the root directory. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3906 --- src/dos/drive_fat.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 86b7dba0..efca156c 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -680,6 +680,49 @@ fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, } loadedDisk->Read_AbsoluteSector(0+partSectOff,&bootbuffer); + + /* Check for DOS 1.x format floppy */ + if ((bootbuffer.mediadescriptor & 0xf0) != 0xf0 && filesize <= 360) { + + Bit8u sectorBuffer[512]; + loadedDisk->Read_AbsoluteSector(1,§orBuffer); + Bit8u mdesc = sectorBuffer[0]; + + /* Allowed if media descriptor in FAT matches image size */ + if ((mdesc == 0xfc && filesize == 180) || + (mdesc == 0xfd && filesize == 360) || + (mdesc == 0xfe && filesize == 160) || + (mdesc == 0xff && filesize == 320)) { + + /* Create parameters for a 160kB floppy */ + bootbuffer.bytespersector = 512; + bootbuffer.sectorspercluster = 1; + bootbuffer.reservedsectors = 1; + bootbuffer.fatcopies = 2; + bootbuffer.rootdirentries = 64; + bootbuffer.totalsectorcount = 320; + bootbuffer.mediadescriptor = mdesc; + bootbuffer.sectorsperfat = 1; + bootbuffer.sectorspertrack = 8; + bootbuffer.headcount = 1; + bootbuffer.magic1 = 0x55; // to silence warning + bootbuffer.magic2 = 0xaa; + if (!(mdesc & 0x2)) { + /* Adjust for 9 sectors per track */ + bootbuffer.totalsectorcount = 360; + bootbuffer.sectorsperfat = 2; + bootbuffer.sectorspertrack = 9; + } + if (mdesc & 0x1) { + /* Adjust for 2 sides */ + bootbuffer.sectorspercluster = 2; + bootbuffer.rootdirentries = 112; + bootbuffer.totalsectorcount *= 2; + bootbuffer.headcount = 2; + } + } + } + if ((bootbuffer.magic1 != 0x55) || (bootbuffer.magic2 != 0xaa)) { /* Not a FAT filesystem */ LOG_MSG("Loaded image has no valid magicnumbers at the end!"); @@ -920,6 +963,10 @@ nextfile: entryoffset = dirPos % 16; if(dirClustNumber==0) { + if(dirPos >= bootbuffer.rootdirentries) { + DOS_SetError(DOSERR_NO_MORE_FILES); + return false; + } loadedDisk->Read_AbsoluteSector(firstRootDirSect+logentsector,sectbuf); } else { tmpsector = getAbsoluteSectFromChain(dirClustNumber, logentsector); From e4b97eb62e82a4d75a9c7c4c985d9ca83160208b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 18 Mar 2015 14:38:24 +0000 Subject: [PATCH 3817/4131] Handle "copy H*.txt file.txt" correctly Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3907 --- src/shell/shell_cmds.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 731c3bc1..f4ef6840 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -682,13 +682,16 @@ void DOS_Shell::CMD_COPY(char * args) { if(temp) *temp = 0;//strip off *.* from target // add '\\' if target is a directory + bool target_is_file = true; if (pathTarget[strlen(pathTarget)-1]!='\\') { if (DOS_FindFirst(pathTarget,0xffff & ~DOS_ATTR_VOLUME)) { dta.GetResult(name,size,date,time,attr); - if (attr & DOS_ATTR_DIRECTORY) + if (attr & DOS_ATTR_DIRECTORY) { strcat(pathTarget,"\\"); + target_is_file = false; + } } - }; + } else target_is_file = false; //Find first sourcefile bool ret = DOS_FindFirst(const_cast(source.filename.c_str()),0xffff & ~DOS_ATTR_VOLUME); @@ -701,7 +704,8 @@ void DOS_Shell::CMD_COPY(char * args) { Bit16u sourceHandle,targetHandle; char nameTarget[DOS_PATHLENGTH]; char nameSource[DOS_PATHLENGTH]; - + + bool second_file_of_current_source = false; while (ret) { dta.GetResult(name,size,date,time,attr); @@ -714,6 +718,10 @@ void DOS_Shell::CMD_COPY(char * args) { strcpy(nameTarget,pathTarget); if (nameTarget[strlen(nameTarget)-1]=='\\') strcat(nameTarget,name); + //Special variable to ensure that copy * a_file, where a_file is not a directory concats. + bool special = second_file_of_current_source && target_is_file; + second_file_of_current_source = true; + if (special) oldsource.concat = true; //Don't create a new file when in concat mode if (oldsource.concat || DOS_CreateFile(nameTarget,0,&targetHandle)) { Bit32u dummy=0; @@ -731,7 +739,7 @@ void DOS_Shell::CMD_COPY(char * args) { failed |= DOS_CloseFile(sourceHandle); failed |= DOS_CloseFile(targetHandle); WriteOut(" %s\n",name); - if(!source.concat) count++; //Only count concat files once + if(!source.concat && !special) count++; //Only count concat files once } else { DOS_CloseFile(sourceHandle); WriteOut(MSG_Get("SHELL_CMD_COPY_FAILURE"),const_cast(target.filename.c_str())); From 08db52896df521788dc01fef1dca74e6c700387d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 28 Mar 2015 18:54:09 +0000 Subject: [PATCH 3818/4131] Fix compilation on mingw systems. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3908 --- src/ints/bios.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 67cf8e5f..47f02987 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -32,7 +32,8 @@ #include "setup.h" #include "serialport.h" #include -#ifdef DB_HAVE_CLOCK_GETTIME + +#if defined(DB_HAVE_CLOCK_GETTIME) && ! defined(WIN32) //time.h is already included #else #include @@ -493,7 +494,7 @@ static Bitu INT11_Handler(void) { static void BIOS_HostTimeSync() { Bit32u milli = 0; -#ifdef DB_HAVE_CLOCK_GETTIME +#if defined(DB_HAVE_CLOCK_GETTIME) && ! defined(WIN32) struct timespec tp; clock_gettime(CLOCK_REALTIME,&tp); From 557f663ec9d9201af569e898c4bd2d1dcf0c1c02 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 28 Mar 2015 18:55:42 +0000 Subject: [PATCH 3819/4131] Fix detection of always_inline attribute with mingw 4.9.2 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3909 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 0ff1bf87..455997e1 100644 --- a/configure.ac +++ b/configure.ac @@ -152,7 +152,7 @@ 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([AC_LANG_SOURCE([ void __attribute__((always_inline)) test(){} +AC_COMPILE_IFELSE([AC_LANG_SOURCE([ inline 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.]) From f51d23bcab1f30d2ce38caa3585315661812fafc Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Fri, 3 Apr 2015 09:36:16 +0000 Subject: [PATCH 3820/4131] Correct an oversight in mode table flags, which at least fixes aspect correction of mode 6 on VGA machine types. Thanks superfury for noticing. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3910 --- src/ints/int10_modes.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index a2be2915..1e8c6d62 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -42,7 +42,7 @@ VideoModeBlock ModeList_VGA[]={ { 0x003 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, { 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, { 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, -{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE}, { 0x007 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, { 0x00D ,M_EGA ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, @@ -157,7 +157,7 @@ VideoModeBlock ModeList_VGA_Tseng[]={ { 0x003 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, { 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, { 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, -{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE}, { 0x007 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, { 0x00D ,M_EGA ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, @@ -198,7 +198,7 @@ VideoModeBlock ModeList_VGA_Paradise[]={ { 0x003 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, { 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, { 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, -{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE}, { 0x007 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, { 0x00D ,M_EGA ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, From 5a7b43f7044c2c47e695b7f8a81a1b071c169a30 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 1 May 2015 12:48:27 +0000 Subject: [PATCH 3821/4131] Introduce mount -pr to mount paths relative to last loaded configuration file. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3911 --- src/dos/dos_programs.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 2a9e8fcb..69ffd827 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -109,6 +109,8 @@ public: WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW")); return; } + bool path_relative_to_last_config = false; + if (cmd->FindExist("-pr",true)) path_relative_to_last_config = true; /* Check for unmounting */ if (cmd->FindString("-u",umount,false)) { @@ -245,10 +247,17 @@ public: if (!cmd->FindCommand(2,temp_line)) goto showusage; if (!temp_line.size()) goto showusage; + if(path_relative_to_last_config && control->configfiles.size() && !Cross::IsPathAbsolute(temp_line)) { + std::string lastconfigdir(control->configfiles[control->configfiles.size()-1]); + std::string::size_type pos = lastconfigdir.rfind(CROSS_FILESPLIT); + if(pos == std::string::npos) pos = 0; //No directory then erase string + lastconfigdir.erase(pos); + if (lastconfigdir.length()) temp_line = lastconfigdir + CROSS_FILESPLIT + temp_line; + } struct stat test; //Win32 : strip tailing backslashes //os2: some special drive check - //rest: substiture ~ for home + //rest: substitute ~ for home bool failed = false; #if defined (WIN32) || defined(OS2) /* Removing trailing backslash if not root dir so stat will succeed */ From 937dcdb1eedbbf44154201503f4b83787cfba557 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Wed, 13 May 2015 01:24:56 +0000 Subject: [PATCH 3822/4131] Use normal teletype function for non-ANSI output so the default attribute 7 applies only to graphics modes and existing attributes are not changed in text modes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3912 --- src/dos/dev_con.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 372af3c8..ef397730 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -129,9 +129,13 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { continue; } else { /* Some sort of "hack" now that '\n' doesn't set col to 0 (int10_char.cpp old chessgame) */ - if((data[count] == '\n') && (lastwrite != '\r')) INT10_TeletypeOutputAttr('\r',ansi.attr,ansi.enabled); + if((data[count] == '\n') && (lastwrite != '\r')) { + if(ansi.enabled) INT10_TeletypeOutputAttr('\r',ansi.attr,true); + else INT10_TeletypeOutput('\r',7); + } /* use ansi attribute if ansi is enabled, otherwise use DOS default attribute*/ - INT10_TeletypeOutputAttr(data[count],ansi.enabled?ansi.attr:7,true); + if(ansi.enabled) INT10_TeletypeOutputAttr(data[count],ansi.attr,true); + else INT10_TeletypeOutput(data[count],7); lastwrite = data[count++]; continue; } From ba3110ca07808d5e6e1ec08c70479ccf59de4bc3 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Wed, 13 May 2015 01:35:39 +0000 Subject: [PATCH 3823/4131] Aspect correction fixes for CGA composite, Hercules graphics, 350-line text modes, 400-line VESA modes, and VGA ModeX (God of Thunder, Lost Vikings, Wrath of Earth, etc.) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3913 --- src/hardware/vga_draw.cpp | 8 +++++--- src/ints/int10_modes.cpp | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 254e826e..bd1cadc8 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1310,7 +1310,9 @@ void VGA_SetupDrawing(Bitu /*val*/) { break; case 3: //480 line mode, filled with 525 total default: - pheight = (480.0 / 480.0) * ( 525.0 / vtotal ); + //Allow 527 total ModeX to have exact 1:1 aspect + target_total = (vga.mode==M_VGA && vtotal==527) ? 527.0 : 525.0; + pheight = (480.0 / 480.0) * ( target_total / vtotal ); break; } @@ -1403,6 +1405,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { vga.draw.linear_mask = (vga.vmemwrap<<1) - 1; break; case M_CGA16: + aspect_ratio=1.2; doubleheight=true; vga.draw.blocks=width*2; width<<=4; @@ -1421,7 +1424,6 @@ void VGA_SetupDrawing(Bitu /*val*/) { VGA_DrawLine=VGA_Draw_1BPP_Line; break; case M_TEXT: - aspect_ratio=1.2; vga.draw.blocks=width; doublewidth=(vga.seq.clocking_mode & 0x8) > 0; if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) { @@ -1444,9 +1446,9 @@ void VGA_SetupDrawing(Bitu /*val*/) { } break; case M_HERC_GFX: - aspect_ratio=1.5; vga.draw.blocks=width*2; width*=16; + aspect_ratio=((double)width/(double)height)*(3.0/4.0); VGA_DrawLine=VGA_Draw_1BPP_Line; break; case M_TANDY2: diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 1e8c6d62..f68a7fc9 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1006,7 +1006,9 @@ bool INT10_SetVideoMode(Bit16u mode) { if (svgaCard == SVGA_S3Trio) { /* Setup the correct clock */ if (CurMode->mode>=0x100) { - misc_output|=0xef; //Select clock 3 + if (CurMode->vdispend>480) + misc_output|=0xc0; //480-line sync + misc_output|=0x0c; //Select clock 3 Bitu clock=CurMode->vtotal*8*CurMode->htotal*70; VGA_SetClock(3,clock/1000); } From b293cfa04483ab879aa9744af03732b750e88a2d Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Wed, 13 May 2015 02:26:37 +0000 Subject: [PATCH 3824/4131] Improve compatibility of internal mouse driver with respect to video mode changes and hiding the pointer, and handle font reloading as a kind of mode change. Also fix unlocked mouse pointer to recognize the full range of tweaked/fontloaded text modes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3914 --- include/mouse.h | 3 ++- src/ints/int10.cpp | 13 ++++++++++--- src/ints/int10_modes.cpp | 3 --- src/ints/mouse.cpp | 27 ++++++++++++++------------- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/include/mouse.h b/include/mouse.h index 2756d0d0..0a1000a6 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -36,6 +36,7 @@ void Mouse_ButtonPressed(Bit8u button); void Mouse_ButtonReleased(Bit8u button); void Mouse_AutoLock(bool enable); -void Mouse_NewVideoMode(void); +void Mouse_BeforeNewVideoMode(bool setmode); +void Mouse_AfterNewVideoMode(bool setmode); #endif diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 288854b6..fe17a142 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -23,6 +23,7 @@ #include "regs.h" #include "inout.h" #include "int10.h" +#include "mouse.h" #include "setup.h" Int10Data int10; @@ -50,7 +51,9 @@ static Bitu INT10_Handler(void) { switch (reg_ah) { case 0x00: /* Set VideoMode */ - INT10_SetVideoMode(reg_al); + Mouse_BeforeNewVideoMode(true); + INT10_SetVideoMode(reg_al); + Mouse_AfterNewVideoMode(true); break; case 0x01: /* Set TextMode Cursor Shape */ INT10_SetCursorShape(reg_ch,reg_cl); @@ -202,6 +205,7 @@ static Bitu INT10_Handler(void) { case 0x11: /* Character generator functions */ if (!IS_EGAVGA_ARCH) break; + if ((reg_al&0xf0)==0x10) Mouse_BeforeNewVideoMode(false); switch (reg_al) { /* Textmode calls */ case 0x00: /* Load user font */ @@ -311,6 +315,7 @@ graphics_chars: LOG(LOG_INT10,LOG_ERROR)("Function 11:Unsupported character generator call %2X",reg_al); break; } + if ((reg_al&0xf0)==0x10) Mouse_AfterNewVideoMode(false); break; case 0x12: /* alternate function select */ if (!IS_EGAVGA_ARCH) @@ -536,8 +541,10 @@ graphics_chars: reg_ah=VESA_GetSVGAModeInformation(reg_cx,SegValue(es),reg_di); break; case 0x02: /* Set videomode */ - reg_al=0x4f; - reg_ah=VESA_SetSVGAMode(reg_bx); + Mouse_BeforeNewVideoMode(true); + reg_al=0x4f; + reg_ah=VESA_SetSVGAMode(reg_bx); + Mouse_AfterNewVideoMode(true); break; case 0x03: /* Get videomode */ reg_al=0x4f; diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index f68a7fc9..06a825f9 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -23,7 +23,6 @@ #include "mem.h" #include "inout.h" #include "int10.h" -#include "mouse.h" #include "vga.h" #define _EGA_HALF_CLOCK 0x0001 @@ -447,8 +446,6 @@ static void FinishSetMode(bool clearmem) { case 14:RealSetVec(0x43,int10.rom.font_14);break; case 16:RealSetVec(0x43,int10.rom.font_16);break; } - /* Tell mouse resolution change */ - Mouse_NewVideoMode(); } bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) { diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 7d5cf59c..f4065b1b 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -465,8 +465,8 @@ void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate) { mouse.y += dy; } else { if (CurMode->type == M_TEXT) { - mouse.x = x*CurMode->swidth; - mouse.y = y*CurMode->sheight * 8 / CurMode->cheight; + mouse.x = x*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8; + mouse.y = y*(real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1)*8; } else if ((mouse.max_x < 2048) || (mouse.max_y < 2048) || (mouse.max_x != mouse.max_y)) { if ((mouse.max_x > 0) && (mouse.max_y > 0)) { mouse.x = x*mouse.max_x; @@ -590,12 +590,20 @@ static void Mouse_ResetHardware(void){ PIC_SetIRQMask(MOUSE_IRQ,false); } +void Mouse_BeforeNewVideoMode(bool setmode) { + if (CurMode->type!=M_TEXT) RestoreCursorBackground(); + else RestoreCursorBackgroundText(); + mouse.hidden = 1; + mouse.oldhidden = 1; + mouse.background = false; +} + //Does way to much. Many things should be moved to mouse reset one day -void Mouse_NewVideoMode(void) { +void Mouse_AfterNewVideoMode(bool setmode) { mouse.inhibit_draw = false; /* Get the correct resolution from the current video mode */ Bit8u mode = mem_readb(BIOS_VIDEO_MODE); - if(mode == mouse.mode) {LOG(LOG_MOUSE,LOG_NORMAL)("New video is the same as the old"); /*return;*/} + if (setmode && mode == mouse.mode) LOG(LOG_MOUSE,LOG_NORMAL)("New video mode is the same as the old"); mouse.gran_x = (Bit16s)0xffff; mouse.gran_y = (Bit16s)0xffff; switch (mode) { @@ -637,7 +645,6 @@ void Mouse_NewVideoMode(void) { return; } mouse.mode = mode; - mouse.hidden = 1; mouse.max_x = 639; mouse.min_x = 0; mouse.min_y = 0; @@ -648,7 +655,6 @@ void Mouse_NewVideoMode(void) { mouse.hotx = 0; mouse.hoty = 0; - mouse.background = false; mouse.screenMask = defaultScreenMask; mouse.cursorMask = defaultCursorMask; mouse.textAndMask= defaultTextAndMask; @@ -662,7 +668,6 @@ void Mouse_NewVideoMode(void) { mouse.updateRegion_y[1] = 1; mouse.cursorType = 0; mouse.enabled=true; - mouse.oldhidden=1; oldmouseX = static_cast(mouse.x); oldmouseY = static_cast(mouse.y); @@ -672,12 +677,8 @@ void Mouse_NewVideoMode(void) { //Much too empty, Mouse_NewVideoMode contains stuff that should be in here static void Mouse_Reset(void) { - /* Remove drawn mouse Legends of Valor */ - if (CurMode->type!=M_TEXT) RestoreCursorBackground(); - else RestoreCursorBackgroundText(); - mouse.hidden = 1; - - Mouse_NewVideoMode(); + Mouse_BeforeNewVideoMode(false); + Mouse_AfterNewVideoMode(false); Mouse_SetMickeyPixelRate(8,16); mouse.mickey_x = 0; From fefe419a2781703bd33dcb43e094dd34eba46c26 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 5 Jun 2015 13:19:09 +0000 Subject: [PATCH 3825/4131] Fix (accidental) compare, fix values and removed the whole line as it wasn't used (see comment) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3915 --- src/dos/dos_programs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 69ffd827..3b2aed61 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1131,7 +1131,7 @@ public: if (type=="floppy") { mediaid=0xF0; } else if (type=="iso") { - str_size=="2048,1,60000,0"; // ignored, see drive_iso.cpp (AllocationInfo) + //str_size="2048,1,65535,0"; // ignored, see drive_iso.cpp (AllocationInfo) mediaid=0xF8; fstype = "iso"; } From 084342cf83bf776d6ac3f75630ace23a1315567a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 5 Jun 2015 13:20:03 +0000 Subject: [PATCH 3826/4131] typo Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3916 --- src/misc/messages.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index d6799af6..313129d3 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -89,7 +89,7 @@ static void LoadMessageFile(const char * fname) { if (*parser!=10 && *parser!=13) { *writer++=*parser; } - *parser++; + parser++; } *writer=0; /* New string name */ From 7e22a0f0c00656ed3720c56cb95a7392b94d8738 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 5 Jun 2015 13:22:37 +0000 Subject: [PATCH 3827/4131] make variable types used in swapping consistent and use Bit8u for drives. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3917 --- include/bios_disk.h | 2 +- src/ints/bios_disk.cpp | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/bios_disk.h b/include/bios_disk.h index 8d91acfe..51cf6ff1 100644 --- a/include/bios_disk.h +++ b/include/bios_disk.h @@ -75,7 +75,7 @@ void incrementFDD(void); extern imageDisk *imageDiskList[2 + MAX_HDD_IMAGES]; extern imageDisk *diskSwap[20]; -extern Bits swapPosition; +extern Bit32s 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; diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 880e7da5..6f70b0a1 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -58,7 +58,7 @@ void CMOS_SetRegister(Bitu regNr, Bit8u val); //For setting equipment word /* 2 floppys and 2 harddrives, max */ imageDisk *imageDiskList[MAX_DISK_IMAGES]; imageDisk *diskSwap[MAX_SWAPPABLE_DISKS]; -Bits swapPosition; +Bit32s swapPosition; void updateDPT(void) { Bit32u tmpheads, tmpcyl, tmpsect, tmpsize; @@ -101,9 +101,9 @@ void incrementFDD(void) { void swapInDisks(void) { bool allNull = true; - Bits diskcount = 0; - Bits swapPos = swapPosition; - int i; + Bit32s diskcount = 0; + Bit32s swapPos = swapPosition; + Bit32s i; /* Check to make sure that there is at least one setup image */ for(i=0;i=(2 + MAX_HDD_IMAGES)) { LOG(LOG_BIOS,LOG_ERROR)("Disk %d non-existant", driveNum); last_status = 0x01; @@ -308,7 +308,7 @@ static bool driveInactive(Bitu driveNum) { static Bitu INT13_DiskHandler(void) { Bit16u segat, bufptr; Bit8u sectbuf[512]; - Bitu drivenum; + Bit8u drivenum; Bitu i,t; last_drive = reg_dl; drivenum = GetDosDriveNumber(reg_dl); From 5c10edabb8d04aa46314b4db976b158dc92068a5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 5 Jun 2015 13:31:45 +0000 Subject: [PATCH 3828/4131] readb returns 8 bit value. (fixes some logging warnings later on) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3918 --- src/dos/dos_mscdex.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index d33af13d..c1c96c24 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -933,7 +933,7 @@ static CMscdex* mscdex = 0; static PhysPt curReqheaderPtr = 0; static Bit16u MSCDEX_IOCTL_Input(PhysPt buffer,Bit8u drive_unit) { - Bitu ioctl_fct = mem_readb(buffer); + Bit8u ioctl_fct = mem_readb(buffer); MSCDEX_LOG("MSCDEX: IOCTL INPUT Subfunction %02X",ioctl_fct); switch (ioctl_fct) { case 0x00 : /* Get Device Header address */ @@ -1050,7 +1050,7 @@ static Bit16u MSCDEX_IOCTL_Input(PhysPt buffer,Bit8u drive_unit) { } static Bit16u MSCDEX_IOCTL_Optput(PhysPt buffer,Bit8u drive_unit) { - Bitu ioctl_fct = mem_readb(buffer); + Bit8u ioctl_fct = mem_readb(buffer); // MSCDEX_LOG("MSCDEX: IOCTL OUTPUT Subfunction %02X",ioctl_fct); switch (ioctl_fct) { case 0x00 : // Unload /eject media From a26c21df3525615ae0de5b015963ed84cc5145b9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 5 Jun 2015 13:53:21 +0000 Subject: [PATCH 3829/4131] some type cleanups (warnings and making sense). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3919 --- src/ints/int10_misc.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 0d57017d..31462394 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -154,7 +154,7 @@ RealPt INT10_EGA_RIL_GetVersionPt(void) { return RealMake(0xc000,0x30); } -static void EGA_RIL(Bit16u dx, Bitu& port, Bitu& regs) { +static void EGA_RIL(Bit16u dx, Bit16u& port, Bit16u& regs) { port = 0; regs = 0; //if nul is returned it's a single register port switch(dx) { @@ -193,8 +193,8 @@ static void EGA_RIL(Bit16u dx, Bitu& port, Bitu& regs) { } void INT10_EGA_RIL_ReadRegister(Bit8u & bl, Bit16u dx) { - Bitu port = 0; - Bitu regs = 0; + Bit16u port = 0; + Bit16u regs = 0; EGA_RIL(dx,port,regs); if(regs == 0) { if(port) bl = IO_Read(port); @@ -208,8 +208,8 @@ void INT10_EGA_RIL_ReadRegister(Bit8u & bl, Bit16u dx) { } void INT10_EGA_RIL_WriteRegister(Bit8u & bl, Bit8u bh, Bit16u dx) { - Bitu port = 0; - Bitu regs = 0; + Bit16u port = 0; + Bit16u regs = 0; EGA_RIL(dx,port,regs); if(regs == 0) { if(port) IO_Write(port,bl); @@ -228,8 +228,8 @@ void INT10_EGA_RIL_WriteRegister(Bit8u & bl, Bit8u bh, Bit16u dx) { } void INT10_EGA_RIL_ReadRegisterRange(Bit8u ch, Bit8u cl, Bit16u dx, PhysPt dst) { - Bitu port = 0; - Bitu regs = 0; + Bit16u port = 0; + Bit16u regs = 0; EGA_RIL(dx,port,regs); if(regs == 0) { LOG(LOG_INT10,LOG_ERROR)("EGA RIL range read with port %x called",port); @@ -247,8 +247,8 @@ void INT10_EGA_RIL_ReadRegisterRange(Bit8u ch, Bit8u cl, Bit16u dx, PhysPt dst) } void INT10_EGA_RIL_WriteRegisterRange(Bit8u ch, Bit8u cl, Bit16u dx, PhysPt src) { - Bitu port = 0; - Bitu regs = 0; + Bit16u port = 0; + Bit16u regs = 0; EGA_RIL(dx,port,regs); if(regs == 0) { LOG(LOG_INT10,LOG_ERROR)("EGA RIL range write called with port %x",port); @@ -278,7 +278,7 @@ void INT10_EGA_RIL_WriteRegisterRange(Bit8u ch, Bit8u cl, Bit16u dx, PhysPt src) */ void INT10_EGA_RIL_ReadRegisterSet(Bit16u cx, PhysPt tbl) { /* read cx register sets */ - for (Bitu i=0; i Date: Sat, 4 Jul 2015 18:24:54 +0000 Subject: [PATCH 3830/4131] some stl implementations fake the interators... Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3920 --- src/misc/programs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index f21b63ec..f4e34f7f 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -538,7 +538,7 @@ void CONFIG::Run(void) { std::string::size_type spcpos = pvars[0].find_first_of(' '); // split on the ' ' if (spcpos != std::string::npos) { - pvars.insert(++pvars.begin(),pvars[0].substr(spcpos+1)); + pvars.insert(pvars.begin()+1,pvars[0].substr(spcpos+1)); pvars[0].erase(spcpos); } switch(pvars.size()) { From db0a72cd4d8b73f0d855dc4f2d2e668235150e88 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 4 Jul 2015 18:37:14 +0000 Subject: [PATCH 3831/4131] and a few more. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3921 --- src/misc/programs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index f4e34f7f..15449644 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -632,7 +632,7 @@ void CONFIG::Run(void) { if ((equpos != std::string::npos) && ((spcpos == std::string::npos) || (equpos < spcpos))) { // If we have a '=' possibly before a ' ' split on the = - pvars.insert(++pvars.begin(),pvars[0].substr(equpos+1)); + pvars.insert(pvars.begin()+1,pvars[0].substr(equpos+1)); pvars[0].erase(equpos); // As we had a = the first thing must be a property now Section* sec=control->GetSectionFromProperty(pvars[0].c_str()); @@ -646,7 +646,7 @@ void CONFIG::Run(void) { if ((spcpos != std::string::npos) && ((equpos == std::string::npos) || (spcpos < equpos))) { // ' ' before a possible '=', split on the ' ' - pvars.insert(++pvars.begin(),pvars[0].substr(spcpos+1)); + pvars.insert(pvars.begin()+1,pvars[0].substr(spcpos+1)); pvars[0].erase(spcpos); } // check if the first parameter is a section or property From b0c72903e4e97e5be5c79df593b09aa97708f30c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 7 Jul 2015 11:06:27 +0000 Subject: [PATCH 3832/4131] Enable SETMODE_SAVES_CLEAR for now. Fix compilation with SETMODE_SAVES set to 0. Use safe_strncpy for resolution lines. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3922 --- src/gui/sdlmain.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index ec1c382d..bb11162a 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -221,7 +221,7 @@ struct SDL_Block { static SDL_Block sdl; #define SETMODE_SAVES 1 //Don't set Video Mode if nothing changes. -#define SETMODE_SAVES_CLEAR 0 //Clear the screen, when the Video Mode is reused +#define SETMODE_SAVES_CLEAR 1 //Clear the screen, when the Video Mode is reused SDL_Surface* SDL_SetVideoMode_Wrap(int width,int height,int bpp,Bit32u flags){ #if SETMODE_SAVES static int i_height = 0; @@ -243,7 +243,7 @@ SDL_Surface* SDL_SetVideoMode_Wrap(int width,int height,int bpp,Bit32u flags){ return sdl.surface; } -#endif + #ifdef WIN32 //SDL seems to crash if we are in OpenGL mode currently and change to exactly the same size without OpenGL. //This happens when DOSBox is in textmode with aspect=true and output=opengl and the mapper is started. @@ -260,7 +260,8 @@ SDL_Surface* SDL_SetVideoMode_Wrap(int width,int height,int bpp,Bit32u flags){ if ((i_flags&SDL_OPENGL) && !(flags&SDL_OPENGL) && height==i_height && width==i_width && height==480) { height++; } -#endif +#endif //WIN32 +#endif //SETMODE_SAVES SDL_Surface* s = SDL_SetVideoMode(width,height,bpp,flags); #if SETMODE_SAVES if (s == NULL) return s; //Only store when successful @@ -1197,7 +1198,7 @@ static void GUI_StartUp(Section * sec) { sdl.desktop.full.height = 0; if(fullresolution && *fullresolution) { char res[100]; - strncpy( res, fullresolution, sizeof( res )); + safe_strncpy( res, fullresolution, sizeof( res )); fullresolution = lowcase (res);//so x and X are allowed if (strcmp(fullresolution,"original")) { sdl.desktop.full.fixed = true; @@ -1217,7 +1218,7 @@ static void GUI_StartUp(Section * sec) { const char* windowresolution=section->Get_string("windowresolution"); if(windowresolution && *windowresolution) { char res[100]; - strncpy( res,windowresolution, sizeof( res )); + safe_strncpy( res,windowresolution, sizeof( res )); windowresolution = lowcase (res);//so x and X are allowed if(strcmp(windowresolution,"original")) { char* height = const_cast(strchr(windowresolution,'x')); From 79419f1f534c4c32d100784bc29b4a954ae1c198 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 8 Jul 2015 12:01:33 +0000 Subject: [PATCH 3833/4131] Bring OS2 port up to date. Thanks Jochen Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3923 --- configure.ac | 1 - include/vga.h | 2 +- src/hardware/mixer.cpp | 5 ++++- src/hardware/serialport/libserial.cpp | 31 +++++++++++++-------------- src/hardware/serialport/misc_util.cpp | 4 ++++ src/hardware/vga_draw.cpp | 6 +++--- 6 files changed, 27 insertions(+), 22 deletions(-) diff --git a/configure.ac b/configure.ac index 455997e1..dc2aa0ff 100644 --- a/configure.ac +++ b/configure.ac @@ -24,7 +24,6 @@ dnl perharps join this with the other target depended checks. move them upwards if test x$host = xi386-pc-os2-emx ; then CXXFLAGS="$CXXFLAGS -Zmt" LDFLAGS="$LDFLAGS -Zomf -Zmt" - LIBS="$LIBS -los2me" fi dnl Check for SDL diff --git a/include/vga.h b/include/vga.h index 0bbeb567..aa570ec4 100644 --- a/include/vga.h +++ b/include/vga.h @@ -112,7 +112,7 @@ typedef struct { typedef enum { PART, - LINE, + DRAWLINE, EGALINE } Drawmode; diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index e49ccd57..0e74a0ce 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -410,8 +410,11 @@ static void MIXER_Mix_NoSound(void) { mixer.tick_remain&=MIXER_REMAIN; mixer.done=0; } - +#ifdef OS2 +static void SDL_CALL MIXER_CallBack(void * userdata, Uint8 *stream, int len) { +#else static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { +#endif Bitu need=(Bitu)len/MIXER_SSIZE; Bit16s * output=(Bit16s *)stream; Bitu reduce; diff --git a/src/hardware/serialport/libserial.cpp b/src/hardware/serialport/libserial.cpp index b55e1778..aa65571a 100644 --- a/src/hardware/serialport/libserial.cpp +++ b/src/hardware/serialport/libserial.cpp @@ -482,11 +482,13 @@ void SERIAL_setRTS(COMPORT port, bool value) { #define INCL_DOSDEVIOCTL #define INCL_DOSPROCESS #include +#include +#include +#include struct _COMPORT { HFILE porthandle; - bool breakstatus; - DCBINFO backup; + DCBINFO orig_dcb; }; // TODO: THIS IS INCOMPLETE and UNTESTED. @@ -495,18 +497,18 @@ bool SERIAL_open(const char* portname, COMPORT* port) { COMPORT cp = (_COMPORT*)malloc(sizeof(_COMPORT)); if(cp == NULL) return false; cp->porthandle=0; - cp->breakstatus=false; + USHORT errors = 0; ULONG ulAction = 0; - APIRET rc = DosOpen(portname, &cp->porthandle, + ULONG ulParmLen = sizeof(DCBINFO); + APIRET rc = DosOpen((PSZ)portname, &cp->porthandle, &ulAction, 0L, FILE_NORMAL, FILE_OPEN, OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | OPEN_FLAGS_SEQUENTIAL, 0L); if (rc != NO_ERROR) { goto cleanup_error; } - ULONG ulParmLen = sizeof(DCBINFO); - rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, + rc = DosDevIOCtl(cp->porthandle, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &cp->orig_dcb, ulParmLen, &ulParmLen); if ( rc != NO_ERROR) { goto cleanup_error; @@ -517,18 +519,17 @@ bool SERIAL_open(const char* portname, COMPORT* port) { newdcb.usWriteTimeout = 0; newdcb.usReadTimeout = 0; //65535; - newdcb.fbCtlHndShake = dcb.fbFlowReplace = 0; + newdcb.fbCtlHndShake = cp->orig_dcb.fbFlowReplace = 0; newdcb.fbTimeout = 6; - rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, + rc = DosDevIOCtl(cp->porthandle, IOCTL_ASYNC, ASYNC_SETDCBINFO, &newdcb, ulParmLen, &ulParmLen, 0, 0, 0); if ( rc != NO_ERROR) { goto cleanup_error; } - USHORT errors = 0; ulParmLen = sizeof(errors); - rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMERROR, + rc = DosDevIOCtl(cp->porthandle, IOCTL_ASYNC, ASYNC_GETCOMMERROR, 0, 0, 0, &errors, ulParmLen, &ulParmLen); if ( rc != NO_ERROR) { goto cleanup_error; @@ -539,7 +540,7 @@ bool SERIAL_open(const char* portname, COMPORT* port) { cleanup_error: // TODO error string - rc value - if (cp->porthandle != 0) CloseHandle(cp->porthandle); + if (cp->porthandle != 0) DosClose(cp->porthandle); free(cp); return false; } @@ -553,14 +554,12 @@ void SERIAL_close(COMPORT port) { if (port->porthandle != 0) { DosDevIOCtl(port->porthandle, IOCTL_ASYNC, ASYNC_SETDCBINFO, &port->orig_dcb, ulParmLen, &ulParmLen, 0, 0, 0); - SetCmmState(port->porthandle, &port->orig_dcb); DosClose (port->porthandle); } free(port); } bool SERIAL_sendchar(COMPORT port, char data) { ULONG bytesWritten = 0; - if(port->breakstatus) return true; // does OS/2 need this? APIRET rc = DosWrite(port->porthandle, &data, 1, &bytesWritten); if (rc == NO_ERROR && bytesWritten > 0) return true; @@ -571,7 +570,7 @@ void SERIAL_setBREAK(COMPORT port, bool value) { USHORT error; ULONG ulParmLen = sizeof(error); DosDevIOCtl(port->porthandle, IOCTL_ASYNC, - value? ASYNC_SETBREAKON:ASYNC_SETBREAKOFF, + value ? ASYNC_SETBREAKON : ASYNC_SETBREAKOFF, 0,0,0, &error, ulParmLen, &ulParmLen); } @@ -656,7 +655,7 @@ bool SERIAL_setCommParameters(COMPORT port, setbaud.baud = baudrate; setbaud.fraction = 0; ULONG ulParmLen = sizeof(setbaud); - APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_EXTSETBAUDRATE, + APIRET rc = DosDevIOCtl(port->porthandle, IOCTL_ASYNC, ASYNC_EXTSETBAUDRATE, &setbaud, ulParmLen, &ulParmLen, 0, 0, 0); if (rc != NO_ERROR) { return false; @@ -697,7 +696,7 @@ bool SERIAL_setCommParameters(COMPORT port, } // set it ulParmLen = sizeof(paramline); - rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETLINECTRL, + rc = DosDevIOCtl(port->porthandle, IOCTL_ASYNC, ASYNC_SETLINECTRL, ¶mline, ulParmLen, &ulParmLen, 0, 0, 0); if ( rc != NO_ERROR) return false; diff --git a/src/hardware/serialport/misc_util.cpp b/src/hardware/serialport/misc_util.cpp index 302dfb7d..147ef2fe 100644 --- a/src/hardware/serialport/misc_util.cpp +++ b/src/hardware/serialport/misc_util.cpp @@ -64,7 +64,11 @@ TCPClientSocket::TCPClientSocket(int platformsocket) { ((struct _TCPsocketX*)nativetcpstruct)->sflag=0; ((struct _TCPsocketX*)nativetcpstruct)->channel=(SOCKET) platformsocket; sockaddr_in sa; +#ifdef OS2 + int sz; +#else socklen_t sz; +#endif sz=sizeof(sa); if(getpeername(platformsocket, (sockaddr *)(&sa), &sz)==0) { ((struct _TCPsocketX*)nativetcpstruct)-> diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index bd1cadc8..470f5e61 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -946,7 +946,7 @@ static void VGA_VerticalTimer(Bitu /*val*/) { vga.draw.parts_left = vga.draw.parts_total; PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts + draw_skip,vga.draw.parts_lines); break; - case LINE: + case DRAWLINE: case EGALINE: if (GCC_UNLIKELY(vga.draw.lines_done < vga.draw.lines_total)) { LOG(LOG_VGAMISC,LOG_NORMAL)( "Lines left: %d", @@ -1042,7 +1042,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { case MCH_CGA: case MCH_PCJR: case MCH_TANDY: - vga.draw.mode = LINE; + vga.draw.mode = DRAWLINE; break; case MCH_EGA: // Note: The Paradise SVGA uses the same panning mechanism as EGA @@ -1050,7 +1050,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { break; case MCH_VGA: if (svgaCard==SVGA_None) { - vga.draw.mode = LINE; + vga.draw.mode = DRAWLINE; break; } // fall-through From 0316809ac980a556aed8e8724207e620543ae3f5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 9 Jul 2015 06:25:46 +0000 Subject: [PATCH 3834/4131] Some more changes by Jochen Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3924 --- src/gui/sdlmain.cpp | 6 +++++- src/hardware/mixer.cpp | 7 ++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index bb11162a..5c063057 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -232,6 +232,7 @@ SDL_Surface* SDL_SetVideoMode_Wrap(int width,int height,int bpp,Bit32u flags){ // I don't see a difference, so disabled for now, as the code isn't finished either #if SETMODE_SAVES_CLEAR //TODO clear it. +#ifdef C_OPENGL if ((flags & SDL_OPENGL)==0) SDL_FillRect(sdl.surface,NULL,SDL_MapRGB(sdl.surface->format,0,0,0)); else { @@ -239,7 +240,10 @@ SDL_Surface* SDL_SetVideoMode_Wrap(int width,int height,int bpp,Bit32u flags){ glClear(GL_COLOR_BUFFER_BIT); SDL_GL_SwapBuffers(); } -#endif +#else //C_OPENGL + SDL_FillRect(sdl.surface,NULL,SDL_MapRGB(sdl.surface->format,0,0,0)); +#endif //C_OPENGL +#endif //SETMODE_SAVES_CLEAR return sdl.surface; } diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 0e74a0ce..41ebcc2b 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -410,11 +410,8 @@ static void MIXER_Mix_NoSound(void) { mixer.tick_remain&=MIXER_REMAIN; mixer.done=0; } -#ifdef OS2 -static void SDL_CALL MIXER_CallBack(void * userdata, Uint8 *stream, int len) { -#else -static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { -#endif + +static void SDLCALL MIXER_CallBack(void * userdata, Uint8 *stream, int len) { Bitu need=(Bitu)len/MIXER_SSIZE; Bit16s * output=(Bit16s *)stream; Bitu reduce; From acd7b73c8ae12c5c4692d37d1f63ae37d44cac5c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 15 Jul 2015 16:31:35 +0000 Subject: [PATCH 3835/4131] Ignore/remove single % in batchfiles. (Fixes B13Demo batchfiles on pcgamer coverdisc 1995-08) Remove magic constants. Add some boundary checks. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3925 --- src/shell/shell_batch.cpp | 65 ++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 3474d618..3df12ef2 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -34,7 +34,7 @@ BatchFile::BatchFile(DOS_Shell * host,char const * const resolved_name,char cons filename = totalname; //Test if file is openable - if (!DOS_OpenFile(totalname,128,&file_handle)) { + if (!DOS_OpenFile(totalname,(DOS_NOT_INHERIT|OPEN_READ),&file_handle)) { //TODO Come up with something better E_Exit("SHELL:Can't open BatchFile %s",totalname); } @@ -49,7 +49,7 @@ BatchFile::~BatchFile() { bool BatchFile::ReadLine(char * line) { //Open the batchfile and seek to stored postion - if (!DOS_OpenFile(filename.c_str(),128,&file_handle)) { + if (!DOS_OpenFile(filename.c_str(),(DOS_NOT_INHERIT|OPEN_READ),&file_handle)) { LOG(LOG_MISC,LOG_ERROR)("ReadLine Can't open BatchFile %s",filename.c_str()); delete this; return false; @@ -68,8 +68,12 @@ emptyline: * Exclusion list: tab for batch files * escape for ansi * backspace for alien odyssey */ - if (c>31 || c==0x1b || c=='\t' || c==8) - *cmd_write++=c; + if (c>31 || c==0x1b || c=='\t' || c==8) { + //Only add it if room for it (and trailing zero) in the buffer, but do the check here instead at the end + //So we continue reading till EOL/EOF + if (((cmd_write - temp) + 1) < (CMD_MAXLINE - 1)) + *cmd_write++ = c; + } } } while (c!='\n' && n); *cmd_write=0; @@ -85,55 +89,64 @@ emptyline: /* Now parse the line read from the bat file for % stuff */ cmd_write=line; char * cmd_read=temp; - char env_name[256];char * env_write; while (*cmd_read) { - env_write=env_name; - if (*cmd_read=='%') { + if (*cmd_read == '%') { cmd_read++; if (cmd_read[0] == '%') { cmd_read++; - *cmd_write++='%'; + if (((cmd_write - line) + 1) < (CMD_MAXLINE - 1)) + *cmd_write++ = '%'; continue; } if (cmd_read[0] == '0') { /* Handle %0 */ const char *file_name = cmd->GetFileName(); cmd_read++; - strcpy(cmd_write,file_name); - cmd_write+=strlen(file_name); + size_t name_len = strlen(file_name); + if (((cmd_write - line) + name_len) < (CMD_MAXLINE - 1)) { + strcpy(cmd_write,file_name); + cmd_write += name_len; + } continue; } char next = cmd_read[0]; - if(next > '0' && next <= '9') { + if(next > '0' && next <= '9') { /* Handle %1 %2 .. %9 */ cmd_read++; //Progress reader next -= '0'; if (cmd->GetCount()<(unsigned int)next) continue; std::string word; if (!cmd->FindCommand(next,word)) continue; - strcpy(cmd_write,word.c_str()); - cmd_write+=strlen(word.c_str()); + size_t name_len = strlen(word.c_str()); + if (((cmd_write - line) + name_len) < (CMD_MAXLINE - 1)) { + strcpy(cmd_write,word.c_str()); + cmd_write += name_len; + } continue; } else { /* Not a command line number has to be an environment */ - char * first=strchr(cmd_read,'%'); - /* No env afterall.Somewhat of a hack though as %% and % aren't handled consistent in dosbox. Maybe echo needs to parse % and %% as well. */ - if (!first) {*cmd_write++ = '%';continue;} + char * first = strchr(cmd_read,'%'); + /* No env afterall. Ignore a single % */ + if (!first) {/* *cmd_write++ = '%';*/continue;} *first++ = 0; std::string env; if (shell->GetEnvStr(cmd_read,env)) { - const char * equals=strchr(env.c_str(),'='); + const char* equals = strchr(env.c_str(),'='); if (!equals) continue; equals++; - strcpy(cmd_write,equals); - cmd_write+=strlen(equals); + size_t name_len = strlen(equals); + if (((cmd_write - line) + name_len) < (CMD_MAXLINE - 1)) { + strcpy(cmd_write,equals); + cmd_write += name_len; + } } - cmd_read=first; + cmd_read = first; } } else { - *cmd_write++=*cmd_read++; + if (((cmd_write - line) + 1) < (CMD_MAXLINE - 1)) + *cmd_write++ = *cmd_read++; } } - *cmd_write=0; + *cmd_write = 0; //Store current location and close bat file this->location = 0; DOS_SeekFile(file_handle,&(this->location),DOS_SEEK_CUR); @@ -143,7 +156,7 @@ emptyline: bool BatchFile::Goto(char * where) { //Open bat file and search for the where string - if (!DOS_OpenFile(filename.c_str(),128,&file_handle)) { + if (!DOS_OpenFile(filename.c_str(),(DOS_NOT_INHERIT|OPEN_READ),&file_handle)) { LOG(LOG_MISC,LOG_ERROR)("SHELL:Goto Can't open BatchFile %s",filename.c_str()); delete this; return false; @@ -160,8 +173,10 @@ again: n=1; DOS_ReadFile(file_handle,&c,&n); if (n>0) { - if (c>31) - *cmd_write++=c; + if (c>31) { + if (((cmd_write - cmd_buffer) + 1) < (CMD_MAXLINE - 1)) + *cmd_write++ = c; + } } } while (c!='\n' && n); *cmd_write++ = 0; From b9cb003a627b0db354e047d758ad5ec2afe84219 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Wed, 5 Aug 2015 14:40:51 +0000 Subject: [PATCH 3836/4131] Setting SB input rate sets output rate, fixes Fasttracker II. Clear incomplete DSP command at reset, fixes Romancing Prince. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3926 --- src/hardware/sblaster.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index d5da7e52..d72066bb 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -699,6 +699,7 @@ static void DSP_Reset(void) { DSP_ChangeMode(MODE_NONE); DSP_FlushData(); + sb.dsp.cmd=DSP_NO_COMMAND; sb.dsp.cmd_len=0; sb.dsp.in.pos=0; sb.dsp.write_busy=0; @@ -858,12 +859,11 @@ static void DSP_DoCommand(void) { DSP_ChangeRate(1000000 / (256 - sb.dsp.in.data[0])); break; case 0x41: /* Set Output Samplerate */ + case 0x42: /* Set Input Samplerate */ + /* Note: 0x42 is handled like 0x41, needed by Fasttracker II */ DSP_SB16_ONLY; DSP_ChangeRate((sb.dsp.in.data[0] << 8) | sb.dsp.in.data[1]); break; - case 0x42: /* Set Input Samplerate */ - LOG(LOG_SB,LOG_ERROR)("DSP:Unimplemented input sample rate command"); - break; case 0x48: /* Set DMA Block Size */ DSP_SB2_ABOVE; //TODO Maybe check limit for new irq? From 59c9ae1d602c45b4fabe2300fe1a56a34c1b2b0f Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Wed, 5 Aug 2015 14:56:36 +0000 Subject: [PATCH 3837/4131] Fix shell PAUSE command when reading extended keys, and make TYPE command more compatible by stopping at EOF byte. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3927 --- src/shell/shell_cmds.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index f4ef6840..e63ea6c5 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -944,6 +944,7 @@ nextfile: do { n=1; DOS_ReadFile(handle,&c,&n); + if (c==0x1a) break; // stop at EOF DOS_WriteFile(STDOUT,&c,&n); } while (n); DOS_CloseFile(handle); @@ -958,7 +959,8 @@ void DOS_Shell::CMD_PAUSE(char * args){ HELP("PAUSE"); WriteOut(MSG_Get("SHELL_CMD_PAUSE")); Bit8u c;Bit16u n=1; - DOS_ReadFile (STDIN,&c,&n); + DOS_ReadFile(STDIN,&c,&n); + if (c==0) DOS_ReadFile(STDIN,&c,&n); // read extended key } void DOS_Shell::CMD_CALL(char * args){ From 64ad48ee52dc349f2387ab6d4ed1c0428d5f6a40 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 17 Aug 2015 14:00:40 +0000 Subject: [PATCH 3838/4131] Slight compression, so that we have more space at the bottom for height restricted screens. Add some colours to the prompt, so it is more visible. General improvements to the section parsing Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3928 --- src/debug/debug.cpp | 13 +++++++----- src/debug/debug_gui.cpp | 45 +++++++++++++++++++++-------------------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index b215c301..a9816ad5 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -686,14 +686,14 @@ static void DrawData(void) { /* Data win */ for (int y=0; y<8; y++) { // Address - if (add<0x10000) mvwprintw (dbg.win_data,1+y,0,"%04X:%04X ",dataSeg,add); - else mvwprintw (dbg.win_data,1+y,0,"%04X:%08X ",dataSeg,add); + if (add<0x10000) mvwprintw (dbg.win_data,y,0,"%04X:%04X ",dataSeg,add); + else mvwprintw (dbg.win_data,y,0,"%04X:%08X ",dataSeg,add); for (int x=0; x<16; x++) { address = GetAddress(dataSeg,add); if (mem_readb_checked(address,&ch)) ch=0; - mvwprintw (dbg.win_data,1+y,14+3*x,"%02X",ch); + mvwprintw (dbg.win_data,y,14+3*x,"%02X",ch); if (ch<32 || !isprint(*reinterpret_cast(&ch))) ch='.'; - mvwprintw (dbg.win_data,1+y,63+x,"%c",ch); + mvwprintw (dbg.win_data,y,63+x,"%c",ch); add++; }; } @@ -849,8 +849,9 @@ static void DrawCode(void) { codeViewData.useEIPlast = disEIP; - wattrset(dbg.win_code,0); + wattrset(dbg.win_code,0); if (!debugging) { + if (has_colors()) wattrset(dbg.win_code,COLOR_PAIR(PAIR_GREEN_BLACK)); mvwprintw(dbg.win_code,10,0,"%s","(Running)"); wclrtoeol(dbg.win_code); } else { @@ -860,11 +861,13 @@ static void DrawCode(void) { mvwprintw(dbg.win_code,10,0,"%c-> %s%c", (codeViewData.ovrMode?'O':'I'),dispPtr,(*curPtr?' ':'_')); wclrtoeol(dbg.win_code); // not correct in pdcurses if full line + mvwchgat(dbg.win_code,10,0,3,0,(PAIR_BLACK_GREY),NULL); if (*curPtr) { mvwchgat(dbg.win_code,10,(curPtr-dispPtr+4),1,0,(PAIR_BLACK_GREY),NULL); } } + wattrset(dbg.win_code,0); wrefresh(dbg.win_code); } diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index ca9e202b..be122582 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -146,15 +146,15 @@ static void DrawBars(void) { attrset(COLOR_PAIR(PAIR_BLACK_BLUE)); } /* Show the Register bar */ - mvaddstr(1-1,0, "---(Register Overview )---"); + mvaddstr(1-1,0, "-----(Register Overview )----- "); /* Show the Data Overview bar perhaps with more special stuff in the end */ - mvaddstr(6-1,0,"---(Data Overview Scroll: page up/down)---"); - /* Show the Code Overview perhaps with special stuff in bar too */ - mvaddstr(17-1,0,"---(Code Overview Scroll: up/down )---"); + mvaddstr(6-1,0, "-----(Data Overview Scroll: page up/down)----- "); + /* Show the Code Overview perhaps with special stuff in bar too */ + mvaddstr(15-1,0,"-----(Code Overview Scroll: up/down )----- "); /* Show the Variable Overview bar */ - mvaddstr(29-1,0, "---(Variable Overview )---"); + mvaddstr(27-1,0,"-----(Variable Overview )----- "); /* Show the Output OverView */ - mvaddstr(34-1,0, "---(Output Scroll: home/end )---"); + mvaddstr(32-1,0,"-----(Output Scroll: home/end )----- "); attrset(0); //Match values with below. So we don't need to touch the internal window structures } @@ -170,14 +170,14 @@ static void MakeSubWindows(void) { dbg.win_reg=subwin(dbg.win_main,4,win_main_maxx,outy,0); outy+=5; // 6 /* The Data Window */ - dbg.win_data=subwin(dbg.win_main,10,win_main_maxx,outy,0); - outy+=11; // 17 + dbg.win_data=subwin(dbg.win_main,8,win_main_maxx,outy,0); + outy+=9; // 15 /* The Code Window */ dbg.win_code=subwin(dbg.win_main,11,win_main_maxx,outy,0); - outy+=12; // 29 + outy+=12; // 27 /* The Variable Window */ dbg.win_var=subwin(dbg.win_main,4,win_main_maxx,outy,0); - outy+=5; // 34 + outy+=5; // 32 /* The Output Window */ dbg.win_out=subwin(dbg.win_main,win_main_maxy-outy,win_main_maxx,outy,0); if(!dbg.win_reg ||!dbg.win_data || !dbg.win_code || !dbg.win_var || !dbg.win_out) E_Exit("Setting up windows failed"); @@ -197,20 +197,21 @@ static void MakePairs(void) { } static void LOG_Destroy(Section*) { if(debuglog) fclose(debuglog); + debuglog = 0; } static void LOG_Init(Section * sec) { - Section_prop * sect=static_cast(sec); - const char * blah=sect->Get_string("logfile"); - if(blah && blah[0] &&(debuglog = fopen(blah,"wt+"))){ - }else{ - debuglog=0; + Section_prop * sect = static_cast(sec); + const char * blah = sect->Get_string("logfile"); + if(blah && blah[0] && (debuglog = fopen(blah,"wt+"))){ + ; + } else { + debuglog = 0; } sect->AddDestroyFunction(&LOG_Destroy); - char buf[1024]; - for (Bitu i=1;iGet_bool(buf); } @@ -253,9 +254,9 @@ void LOG_StartUp(void) { Section_prop * sect=control->AddSection_prop("log",LOG_Init); Prop_string* Pstring = sect->Add_string("logfile",Property::Changeable::Always,""); Pstring->Set_help("file where the log messages will be saved to"); - char buf[1024]; - for (Bitu i=1;iAdd_bool(buf,Property::Changeable::Always,true); Pbool->Set_help("Enable/Disable logging of this type."); From a03d9faf91e24832059074da393c986e4706a094 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 17 Aug 2015 14:07:01 +0000 Subject: [PATCH 3839/4131] Add some more cases to the Alt-tab detection. It can still mess up, but this should help with a lot of cases. Thanks for testing eightbitbubsy. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3929 --- src/gui/sdlmain.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 5c063057..43df32fb 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -212,6 +212,8 @@ struct SDL_Block { Bitu num_joysticks; #if defined (WIN32) bool using_windib; + // Time when sdl regains focus (alt-tab) in windowed mode + Bit32u focus_ticks; #endif // state of alt-keys for certain special handlings Bit8u laltstate; @@ -1505,6 +1507,9 @@ void GFX_Events() { case SDL_ACTIVEEVENT: if (event.active.state & SDL_APPINPUTFOCUS) { if (event.active.gain) { +#ifdef WIN32 + if (!sdl.desktop.fullscreen) sdl.focus_ticks = GetTicks(); +#endif if (sdl.desktop.fullscreen && !sdl.mouse.locked) GFX_CaptureMouse(); SetPriority(sdl.priority.focus); @@ -1596,6 +1601,10 @@ void GFX_Events() { if (event.key.keysym.sym==SDLK_RALT) sdl.raltstate = event.key.type; if (((event.key.keysym.sym==SDLK_TAB)) && ((sdl.laltstate==SDL_KEYDOWN) || (sdl.raltstate==SDL_KEYDOWN))) break; + // This can happen as well. + if (((event.key.keysym.sym == SDLK_TAB )) && (event.key.keysym.mod & KMOD_ALT)) break; + // ignore tab events that arrive just after regaining focus. (likely the result of alt-tab) + if ((event.key.keysym.sym == SDLK_TAB) && (GetTicks() - sdl.focus_ticks < 2)) break; #endif #if defined (MACOSX) case SDL_KEYDOWN: From 5a748e5cbba23b4ef884c6aeb16b175beb03dff9 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Mon, 17 Aug 2015 15:06:28 +0000 Subject: [PATCH 3840/4131] Display a simple startup message for sub-shells instead of the welcome banner. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3930 --- src/shell/shell.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index f7f8a4b5..2502b333 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -296,18 +296,20 @@ void DOS_Shell::Run(void) { return; } /* Start a normal shell and check for a first command init */ - WriteOut(MSG_Get("SHELL_STARTUP_BEGIN"),VERSION); -#if C_DEBUG - WriteOut(MSG_Get("SHELL_STARTUP_DEBUG")); -#endif - if (machine == MCH_CGA) WriteOut(MSG_Get("SHELL_STARTUP_CGA")); - if (machine == MCH_HERC) WriteOut(MSG_Get("SHELL_STARTUP_HERC")); - WriteOut(MSG_Get("SHELL_STARTUP_END")); - if (cmd->FindString("/INIT",line,true)) { + WriteOut(MSG_Get("SHELL_STARTUP_BEGIN"),VERSION); +#if C_DEBUG + WriteOut(MSG_Get("SHELL_STARTUP_DEBUG")); +#endif + if (machine == MCH_CGA) WriteOut(MSG_Get("SHELL_STARTUP_CGA")); + if (machine == MCH_HERC) WriteOut(MSG_Get("SHELL_STARTUP_HERC")); + WriteOut(MSG_Get("SHELL_STARTUP_END")); + strcpy(input_line,line.c_str()); line.erase(); ParseLine(input_line); + } else { + WriteOut(MSG_Get("SHELL_STARTUP_SUB"),VERSION); } do { if (bf){ @@ -542,6 +544,7 @@ void SHELL_Init() { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC\033[0m\n" //"\n" //Breaks the startup message if you type a mount and a drive change. ); + MSG_Add("SHELL_STARTUP_SUB","\n\n\033[32;1mDOSBox %s Command Shell\033[0m\n\n"); MSG_Add("SHELL_CMD_CHDIR_HELP","Displays/changes the current directory.\n"); MSG_Add("SHELL_CMD_CHDIR_HELP_LONG","CHDIR [drive:][path]\n" "CHDIR [..]\n" From f66ff6e3d7401a5038b2578deab3f8af4dd74ffd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 19 Aug 2015 18:26:04 +0000 Subject: [PATCH 3841/4131] Only compile when in debug mode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3931 --- src/debug/debug_win32.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/debug/debug_win32.cpp b/src/debug/debug_win32.cpp index 469bec89..0e0d48b5 100644 --- a/src/debug/debug_win32.cpp +++ b/src/debug/debug_win32.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "dosbox.h" +#if C_DEBUG #ifdef WIN32 #include @@ -77,3 +79,4 @@ void WIN32_Console() { ResizeConsole(GetStdHandle(STD_OUTPUT_HANDLE),80,50); } #endif +#endif From 1b7b92ed8a676ab3619ff05dbf5b178fbe2ffee6 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Fri, 28 Aug 2015 14:37:25 +0000 Subject: [PATCH 3842/4131] Add alternate font tables and associated loading logic in video BIOS, allowing correct gaps between "wide" characters (e.g. m,w,M,W,T,Z,0) in all VGA machine types. Update all related BIOS memory values and CRTC registers when loading fonts, fixing quirks in some textmode programs like Inertia Player. Based in part on a patch by h-a-l-9000. Improve support for MDA emulation in the vgaonly machine type, as it is the only way the video BIOS can make use of the 14-line alternate symbols. Be compatible by setting the INT 43h vector to the first half of the 8-line font table for standard text modes. Fixes a few obscure games and demos that rely on this BIOS behavior. Move VESA mode table and OEM string before font tables in the video ROM, which is a more compatible ordering and gives the data low address offsets that work around a bug in some programs such as the Abuse game and Molejo demo. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3932 --- src/dos/dos_keyboard_layout.cpp | 4 + src/ints/int10.cpp | 17 +- src/ints/int10.h | 2 + src/ints/int10_memory.cpp | 286 +++++++++++++++++++++++++------- src/ints/int10_modes.cpp | 25 ++- 5 files changed, 254 insertions(+), 80 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 3214fe5e..056b752c 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -911,6 +911,8 @@ Bitu keyboard_layout::read_codepage_file(const char* codepage_file_name, Bit32s for (Bitu i=0;i<256*16;i++) { phys_writeb(font16pt+i,cpi_buf[font_data_start+i]); } + // terminate alternate list to prevent loading + phys_writeb(Real2Phys(int10.rom.font_16_alternate),0); font_changed=true; } else if (font_height==0x0e) { // 14x8 font @@ -918,6 +920,8 @@ Bitu keyboard_layout::read_codepage_file(const char* codepage_file_name, Bit32s for (Bitu i=0;i<256*14;i++) { phys_writeb(font14pt+i,cpi_buf[font_data_start+i]); } + // terminate alternate list to prevent loading + phys_writeb(Real2Phys(int10.rom.font_14_alternate),0); font_changed=true; } else if (font_height==0x08) { // 8x8 fonts diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index fe17a142..38bf5c00 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -52,7 +52,7 @@ static Bitu INT10_Handler(void) { switch (reg_ah) { case 0x00: /* Set VideoMode */ Mouse_BeforeNewVideoMode(true); - INT10_SetVideoMode(reg_al); + INT10_SetVideoMode(reg_al); Mouse_AfterNewVideoMode(true); break; case 0x01: /* Set TextMode Cursor Shape */ @@ -210,15 +210,15 @@ static Bitu INT10_Handler(void) { /* Textmode calls */ case 0x00: /* Load user font */ case 0x10: - INT10_LoadFont(SegPhys(es)+reg_bp,reg_al==0x10,reg_cx,reg_dx,reg_bl,reg_bh); + INT10_LoadFont(SegPhys(es)+reg_bp,reg_al==0x10,reg_cx,reg_dx,reg_bl&0x7f,reg_bh); break; case 0x01: /* Load 8x14 font */ case 0x11: - INT10_LoadFont(Real2Phys(int10.rom.font_14),reg_al==0x11,256,0,reg_bl,14); + INT10_LoadFont(Real2Phys(int10.rom.font_14),reg_al==0x11,256,0,reg_bl&0x7f,14); break; case 0x02: /* Load 8x8 font */ case 0x12: - INT10_LoadFont(Real2Phys(int10.rom.font_8_first),reg_al==0x12,256,0,reg_bl,8); + INT10_LoadFont(Real2Phys(int10.rom.font_8_first),reg_al==0x12,256,0,reg_bl&0x7f,8); break; case 0x03: /* Set Block Specifier */ IO_Write(0x3c4,0x3);IO_Write(0x3c5,reg_bl); @@ -226,7 +226,7 @@ static Bitu INT10_Handler(void) { case 0x04: /* Load 8x16 font */ case 0x14: if (!IS_VGA_ARCH) break; - INT10_LoadFont(Real2Phys(int10.rom.font_16),reg_al==0x14,256,0,reg_bl,16); + INT10_LoadFont(Real2Phys(int10.rom.font_16),reg_al==0x14,256,0,reg_bl&0x7f,16); break; /* Graphics mode calls */ case 0x20: /* Set User 8x8 Graphics characters */ @@ -288,7 +288,6 @@ graphics_chars: reg_bp=RealOff(int10.rom.font_8_second); break; case 0x05: /* alpha alternate 9x14 */ - if (!IS_VGA_ARCH) break; SegSet16(es,RealSeg(int10.rom.font_14_alternate)); reg_bp=RealOff(int10.rom.font_14_alternate); break; @@ -542,8 +541,8 @@ graphics_chars: break; case 0x02: /* Set videomode */ Mouse_BeforeNewVideoMode(true); - reg_al=0x4f; - reg_ah=VESA_SetSVGAMode(reg_bx); + reg_al=0x4f; + reg_ah=VESA_SetSVGAMode(reg_bx); Mouse_AfterNewVideoMode(true); break; case 0x03: /* Get videomode */ @@ -764,7 +763,5 @@ void INT10_Init(Section* /*sec*/) { //Init the 0x40 segment and init the datastructures in the the video rom area INT10_SetupRomMemory(); INT10_Seg40Init(); - INT10_SetupVESA(); - INT10_SetupRomMemoryChecksum();//SetupVesa modifies the rom as well. INT10_SetVideoMode(0x3); } diff --git a/src/ints/int10.h b/src/ints/int10.h index 2a40e915..4fdbdc0b 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -99,6 +99,8 @@ extern Bit8u int10_font_08[256 * 8]; extern Bit8u int10_font_14[256 * 14]; extern Bit8u int10_font_16[256 * 16]; +extern Bit8u int10_font_14_alternate[20 * 15 + 1]; +extern Bit8u int10_font_16_alternate[19 * 17 + 1]; struct VideoModeBlock { Bit16u mode; diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index c0fadaaf..df16cc04 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -47,55 +47,78 @@ static Bit16u map_offset[8]={ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu height) { PhysPt ftwhere=PhysMake(0xa000,map_offset[map & 0x7]+(Bit16u)(offset*32)); - IO_Write(0x3c4,0x2);IO_Write(0x3c5,0x4); //Enable plane 2 - IO_Write(0x3ce,0x6);Bitu old_6=IO_Read(0x3cf); - IO_Write(0x3cf,0x0); //Disable odd/even and a0000 addressing + Bit16u base=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + bool mono=(base==VGAREG_MDA_CRTC_ADDRESS); + + //Put video adapter in planar mode + IO_Write(0x3c4,0x02);IO_Write(0x3c5,0x04); // select plane 2 for writing + IO_Write(0x3c4,0x04);IO_Write(0x3c5,0x07); // odd/even off in SEQ + IO_Write(0x3ce,0x04);IO_Write(0x3cf,0x02); // select plane 2 for reading + IO_Write(0x3ce,0x05);IO_Write(0x3cf,0x00); // write mode 0, odd/even off in GFX + IO_Write(0x3ce,0x06);IO_Write(0x3cf,0x04); // CPU memory window A0000-AFFFF + + //Load character patterns for (Bitu i=0;isheight/height; - if (machine==MCH_EGA) { - Bitu displayend = rows*height - 1; - IO_Write(base,0x12); - IO_Write(base+1,(Bit8u)(displayend & 0xff)); - IO_Write(base,0x7); - // Note: IBM EGA registers can't be read - Bitu v_overflow = IO_Read(base+1) & ~0x2; - if (displayend & 0x100) v_overflow |= 0x2; - IO_Write(base+1,(Bit8u)v_overflow); + //Vertical display end + Bitu rows=CurMode->sheight/height; + Bitu vdend=rows*height*((CurMode->sheight==200)?2:1)-1; + IO_Write(base,0x12); + IO_Write(base+1,(Bit8u)vdend); + //Underline location + if (CurMode->mode==7) { + IO_Write(base,0x14); + IO_Write(base+1,(IO_Read(base+1) & ~0x1f)|(height-1)); } //Rows setting in bios segment real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,rows-1); real_writeb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,(Bit8u)height); - //TODO Reprogram cursor size? + //Page size + Bitu pagesize=rows*real_readb(BIOSMEM_SEG,BIOSMEM_NB_COLS)*2; + pagesize+=0x100; // bios adds extra on reload + real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,pagesize); + //Cursor shape + if (height>=14) height--; // move up one line on 14+ line fonts + INT10_SetCursorShape(height-2,height-1); } } void INT10_ReloadFont(void) { + Bitu map=0; switch(CurMode->cheight) { case 8: - INT10_LoadFont(Real2Phys(int10.rom.font_8_first),true,256,0,0,8); + INT10_LoadFont(Real2Phys(int10.rom.font_8_first),false,256,0,map,8); break; case 14: - INT10_LoadFont(Real2Phys(int10.rom.font_14),true,256,0,0,14); + if (IS_VGA_ARCH && svgaCard==SVGA_None && CurMode->mode==7) map=0x80; + INT10_LoadFont(Real2Phys(int10.rom.font_14),false,256,0,map,14); break; case 16: default: - INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); + if (IS_VGA_ARCH && svgaCard==SVGA_None) map=0x80; + INT10_LoadFont(Real2Phys(int10.rom.font_16),false,256,0,map,16); break; } } @@ -118,6 +141,9 @@ void INT10_SetupRomMemory(void) { } int10.rom.used=0x100; } + + if (IS_VGA_ARCH && svgaCard==SVGA_S3Trio) INT10_SetupVESA(); + int10.rom.font_8_first=RealMake(0xC000,int10.rom.used); for (i=0;i<128*8;i++) { phys_writeb(rom_base+int10.rom.used++,int10_font_08[i]); @@ -130,10 +156,18 @@ void INT10_SetupRomMemory(void) { for (i=0;i<256*14;i++) { phys_writeb(rom_base+int10.rom.used++,int10_font_14[i]); } + int10.rom.font_14_alternate=RealMake(0xC000,int10.rom.used); + for (i=0;i<20*15+1;i++) { + phys_writeb(rom_base+int10.rom.used++,int10_font_14_alternate[i]); + } int10.rom.font_16=RealMake(0xC000,int10.rom.used); for (i=0;i<256*16;i++) { phys_writeb(rom_base+int10.rom.used++,int10_font_16[i]); } + int10.rom.font_16_alternate=RealMake(0xC000,int10.rom.used); + for (i=0;i<19*17+1;i++) { + phys_writeb(rom_base+int10.rom.used++,int10_font_16_alternate[i]); + } int10.rom.static_state=RealMake(0xC000,int10.rom.used); for (i=0;i<0x10;i++) { phys_writeb(rom_base+int10.rom.used++,static_functionality[i]); @@ -142,9 +176,6 @@ void INT10_SetupRomMemory(void) { phys_writeb(PhysMake(0xf000,0xfa6e)+i,int10_font_08[i]); } RealSetVec(0x1F,int10.rom.font_8_second); - int10.rom.font_14_alternate=RealMake(0xC000,int10.rom.used); - int10.rom.font_16_alternate=RealMake(0xC000,int10.rom.used); - phys_writeb(rom_base+int10.rom.used++,0x00); // end of table (empty) if (IS_EGAVGA_ARCH) { int10.rom.video_parameter_table=RealMake(0xC000,int10.rom.used); @@ -208,6 +239,7 @@ void INT10_SetupRomMemory(void) { } INT10_SetupBasicVideoParameterTable(); + INT10_SetupRomMemoryChecksum(); if (IS_TANDY_ARCH) { RealSetVec(0x44,int10.rom.font_8_first); @@ -220,11 +252,13 @@ void INT10_ReloadRomFonts(void) { for (Bitu i=0;i<256*16;i++) { phys_writeb(font16pt+i,int10_font_16[i]); } + phys_writeb(Real2Phys(int10.rom.font_16_alternate),0x1d); // 14x8 font PhysPt font14pt=Real2Phys(int10.rom.font_14); for (Bitu i=0;i<256*14;i++) { phys_writeb(font14pt+i,int10_font_14[i]); } + phys_writeb(Real2Phys(int10.rom.font_14_alternate),0x1d); // 8x8 fonts PhysPt font8pt=Real2Phys(int10.rom.font_8_first); for (Bitu i=0;i<128*8;i++) { @@ -234,6 +268,7 @@ void INT10_ReloadRomFonts(void) { for (Bitu i=0;i<128*8;i++) { phys_writeb(font8pt+i,int10_font_08[i+128*8]); } + INT10_SetupRomMemoryChecksum(); } void INT10_SetupRomMemoryChecksum(void) { @@ -1019,8 +1054,8 @@ Bit8u int10_font_16[256 * 16] = { 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, - 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, + 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, @@ -1057,8 +1092,8 @@ Bit8u int10_font_16[256 * 16] = { 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, - 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, + 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, @@ -1115,8 +1150,8 @@ Bit8u int10_font_16[256 * 16] = { 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, - 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, @@ -1129,20 +1164,20 @@ Bit8u int10_font_16[256 * 16] = { 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, - 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, - 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, - 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, + 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, + 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, - 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, + 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, @@ -1179,8 +1214,8 @@ Bit8u int10_font_16[256 * 16] = { 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, - 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, + 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, @@ -1197,12 +1232,12 @@ Bit8u int10_font_16[256 * 16] = { 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, - 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, - 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, - 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, + 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, + 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, @@ -1251,8 +1286,8 @@ Bit8u int10_font_16[256 * 16] = { 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, - 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, + 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, @@ -1271,14 +1306,14 @@ Bit8u int10_font_16[256 * 16] = { 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, - 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x60, + 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, - 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, - 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, + 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, + 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, @@ -1304,9 +1339,9 @@ Bit8u int10_font_16[256 * 16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, - 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00, + 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, - 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, + 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, @@ -1474,3 +1509,128 @@ Bit8u int10_font_16[256 * 16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +Bit8u int10_font_14_alternate[20 * 15 + 1] = { + 0x1d, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, + 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x22, + 0x00, 0x63, 0x63, 0x63, 0x22, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2b, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0xff, + 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x2d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4d, + 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xdb, 0xc3, + 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, + 0x54, + 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x56, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, + 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, + 0x57, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, + 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, + 0x58, + 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, + 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, + 0x59, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x5a, + 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, + 0x30, 0x61, 0xc3, 0xff, 0x00, 0x00, 0x00, + 0x6d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, + 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, + 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, + 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, + 0x77, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, + 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, + 0x91, + 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, + 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, + 0x9b, + 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, + 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x9d, + 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, + 0x18, 0xff, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x9e, + 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, + 0x6f, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, + 0xf1, + 0x00, 0x00, 0x18, 0x18, 0x18, 0xff, 0x18, + 0x18, 0x18, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xf6, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00 +}; + +Bit8u int10_font_16_alternate[19 * 17 + 1] = { + 0x1d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, + 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, + 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, + 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x4d, + 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, + 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x54, + 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x56, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, + 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x57, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, + 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x58, + 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, + 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x59, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x5a, + 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, + 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x6d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, + 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, + 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, + 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x77, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, + 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, + 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x91, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, + 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, + 0x9b, + 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, + 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x9d, + 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, + 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x9e, + 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, + 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, + 0xab, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, + 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00, + 0xac, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, + 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, + 0x00 +}; diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 06a825f9..79ef2772 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -145,7 +145,8 @@ VideoModeBlock ModeList_VGA_Text_350lines[]={ { 0x000 ,M_TEXT ,320 ,350 ,40 ,25 ,8 ,14 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,350 ,_EGA_HALF_CLOCK }, { 0x001 ,M_TEXT ,320 ,350 ,40 ,25 ,8 ,14 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,350 ,_EGA_HALF_CLOCK }, { 0x002 ,M_TEXT ,640 ,350 ,80 ,25 ,8 ,14 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,350 ,0 }, -{ 0x003 ,M_TEXT ,640 ,350 ,80 ,25 ,8 ,14 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,350 ,0 } +{ 0x003 ,M_TEXT ,640 ,350 ,80 ,25 ,8 ,14 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,350 ,0 }, +{ 0x007 ,M_TEXT ,720 ,350 ,80 ,25 ,9 ,14 ,8 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,350 ,0 } }; VideoModeBlock ModeList_VGA_Tseng[]={ @@ -441,10 +442,14 @@ static void FinishSetMode(bool clearmem) { // Set active page 0 INT10_SetActivePage(0); /* Set some interrupt vectors */ - switch (CurMode->cheight) { - case 8:RealSetVec(0x43,int10.rom.font_8_first);break; - case 14:RealSetVec(0x43,int10.rom.font_14);break; - case 16:RealSetVec(0x43,int10.rom.font_16);break; + if (CurMode->mode<=3 || CurMode->mode==7) + RealSetVec(0x43,int10.rom.font_8_first); + else { + switch (CurMode->cheight) { + case 8:RealSetVec(0x43,int10.rom.font_8_first);break; + case 14:RealSetVec(0x43,int10.rom.font_14);break; + case 16:RealSetVec(0x43,int10.rom.font_16);break; + } } } @@ -682,10 +687,14 @@ bool INT10_SetVideoMode(Bit16u mode) { if ((modeset_ctl&0x90)==0x80) { // 200 lines emulation if (CurMode->mode <= 3) { CurMode = &ModeList_VGA_Text_200lines[CurMode->mode]; + } else if (CurMode->mode == 7) { + CurMode = &ModeList_VGA_Text_350lines[4]; } } else if ((modeset_ctl&0x90)==0x00) { // 350 lines emulation if (CurMode->mode <= 3) { CurMode = &ModeList_VGA_Text_350lines[CurMode->mode]; + } else if (CurMode->mode == 7) { + CurMode = &ModeList_VGA_Text_350lines[4]; } } } @@ -897,7 +906,7 @@ bool INT10_SetVideoMode(Bit16u mode) { switch (CurMode->type) { case M_TEXT: max_scanline|=CurMode->cheight-1; - underline=mono_mode ? 0x0f : 0x1f; // mode 7 uses a diff underline position + underline=mono_mode ? CurMode->cheight-1 : 0x1f; // mode 7 uses underline position break; case M_VGA: underline=0x40; @@ -913,8 +922,10 @@ bool INT10_SetVideoMode(Bit16u mode) { case M_CGA4: max_scanline|=1; break; + default: + if (CurMode->vdispend==350) underline=0x0f; + break; } - if (CurMode->vdispend==350) underline=0x0f; IO_Write(crtc_base,0x09);IO_Write(crtc_base+1,max_scanline); IO_Write(crtc_base,0x14);IO_Write(crtc_base+1,underline); From 96fb43a208b0c55881ea4392327f6b952d632b2f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 8 Sep 2015 13:44:34 +0000 Subject: [PATCH 3843/4131] Slight reordering of the arguments. Add -socket Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3933 --- docs/dosbox.1 | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/docs/dosbox.1 b/docs/dosbox.1 index 73ce2e72..72c2459b 100644 --- a/docs/dosbox.1 +++ b/docs/dosbox.1 @@ -1,5 +1,5 @@ .\" Hey, EMACS: -*- nroff -*- -.TH DOSBOX 1 "Feb 26, 2010" +.TH DOSBOX 1 "Sep 08, 2015" .\" Please adjust this date whenever revising the manpage. .SH NAME dosbox \- an x86/DOS emulator with sound/graphics @@ -14,10 +14,11 @@ dosbox \- an x86/DOS emulator with sound/graphics .BI "[\-forcescaler " scaler ] .BI "[\-conf " configfile ] .BI "[\-lang " langfile ] -.B [file] +.BI "[\-machine " machinetype ] +.BI "[\-socket " socketnumber ] .BI "[\-c " command ] .B [\-exit] -.BI "[\-machine " machinetype ] +.B [file] .LP .B dosbox \-version .LP @@ -76,6 +77,25 @@ file for the available scalers .RB "Similar to the " \-scaler " parameter, but tries to force usage of" the specified scaler even if it might not fit. .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 +.BI \-machine " machinetype" +.RB "Setup " dosbox " to emulate a specific type of machine." +.RI "Valid choices are: " "hercules, cga, tandy, pcjr, ega, vgaonly, svga_s3(default), svga_et3000, svga_et4000, svga_paradise, vesa_nolfb, vesa_oldvbe". +The machinetype has influence on both the videocard and the available +soundcards. +.TP +.BI \-socket " socketnumber" +.RI "Passes the socket number " socketnumber " to the nullmodem emulation. See README for details." +.TP .BI \-c " command" .RI "Runs the specified " command " before running " .BR file . @@ -83,25 +103,9 @@ the specified scaler even if it might not fit. .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, tandy, pcjr, ega, vgaonly, svga_s3(default), svga_et3000, svga_et4000, svga_paradise, vesa_nolfb, vesa_oldvbe". -The machinetype has influence on both the videocard and the available -soundcards. -.TP .B \-version Output version information and exit. Useful for frontends. .TP From cb28976df6ce8b922fbc8e4da0328bf141066770 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 8 Sep 2015 13:46:26 +0000 Subject: [PATCH 3844/4131] More robust parsing, so that dosbox -fullscreen A.EXE works Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3934 --- src/shell/shell.cpp | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 2502b333..2aa174b0 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -379,38 +379,42 @@ public: bool addexit = control->cmdline->FindExist("-exit",true); /* Check for first command being a directory or file */ - char buffer[CROSS_LEN]; - char orig[CROSS_LEN]; + char buffer[CROSS_LEN+1]; + char orig[CROSS_LEN+1]; char cross_filesplit[2] = {CROSS_FILESPLIT , 0}; - /* Combining -securemode and no parameter leaves you with a lovely Z:\. */ - if ( !control->cmdline->FindCommand(1,line) ) { - if ( secure ) autoexec[12].Install("z:\\config.com -securemode"); - } else { + + Bitu dummy = 1; + bool command_found = false; + while (control->cmdline->FindCommand(dummy++,line) && !command_found) { struct stat test; + if (line.length() > CROSS_LEN) continue; strcpy(buffer,line.c_str()); - if (stat(buffer,&test)){ - getcwd(buffer,CROSS_LEN); + if (stat(buffer,&test)) { + if (getcwd(buffer,CROSS_LEN) == NULL) continue; + if (strlen(buffer) + line.length() + 1 > CROSS_LEN) continue; strcat(buffer,cross_filesplit); strcat(buffer,line.c_str()); - if (stat(buffer,&test)) goto nomount; + if (stat(buffer,&test)) continue; } if (test.st_mode & S_IFDIR) { autoexec[12].Install(std::string("MOUNT C \"") + buffer + "\""); autoexec[13].Install("C:"); if(secure) autoexec[14].Install("z:\\config.com -securemode"); + command_found = true; } else { char* name = strrchr(buffer,CROSS_FILESPLIT); if (!name) { //Only a filename line = buffer; - getcwd(buffer,CROSS_LEN); + if (getcwd(buffer,CROSS_LEN) == NULL) continue; + if (strlen(buffer) + line.length() + 1 > CROSS_LEN) continue; strcat(buffer,cross_filesplit); strcat(buffer,line.c_str()); - if(stat(buffer,&test)) goto nomount; + if(stat(buffer,&test)) continue; name = strrchr(buffer,CROSS_FILESPLIT); - if(!name) goto nomount; + if(!name) continue; } *name++ = 0; - if (access(buffer,F_OK)) goto nomount; + if (access(buffer,F_OK)) continue; autoexec[12].Install(std::string("MOUNT C \"") + buffer + "\""); autoexec[13].Install("C:"); /* Save the non-modified filename (so boot and imgmount can use it (long filenames, case sensivitive)) */ @@ -437,9 +441,14 @@ public: autoexec[15].Install(name); if(addexit) autoexec[16].Install("exit"); } + command_found = true; } } -nomount: + + /* Combining -securemode, noautoexec and no parameters leaves you with a lovely Z:\. */ + if ( !command_found ) { + if ( secure ) autoexec[12].Install("z:\\config.com -securemode"); + } VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,(Bit32u)strlen(autoexec_data)); } }; From 0c979d54a56a9e6c583425f6cd507cd6af3ab997 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 9 Sep 2015 13:23:23 +0000 Subject: [PATCH 3845/4131] VS2015 wants it this way Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3935 --- src/ints/int10_vesa.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index ef3fcb34..3f3c59ec 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -45,7 +45,7 @@ static struct { static char string_oem[]="S3 Incorporated. Trio64"; static char string_vendorname[]="DOSBox Development Team"; static char string_productname[]="DOSBox - The DOS Emulator"; -static char string_productrev[]="DOSBox "VERSION; +static char string_productrev[]="DOSBox " VERSION; #ifdef _MSC_VER #pragma pack (1) From babb297c600562cb3cb7da21d6fb2a00aa79f688 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sun, 20 Sep 2015 23:39:55 +0000 Subject: [PATCH 3846/4131] Add opl3gold option to oplmode setting. With this option the AdLib Gold music can be selected in Dune. Only FM music without effects (reverb, stereo enhancement, surround sound, etc.) is supported; and FM volume control, used in the CD-ROM version of Dune, does work. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3936 --- include/hardware.h | 2 +- src/dosbox.cpp | 2 +- src/hardware/adlib.cpp | 70 +++++++++++++++++++++++++++++++++++++++ src/hardware/adlib.h | 12 ++++++- src/hardware/sblaster.cpp | 3 ++ 5 files changed, 86 insertions(+), 3 deletions(-) diff --git a/include/hardware.h b/include/hardware.h index 5f5e4c74..26d3fde8 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -24,7 +24,7 @@ class Section; enum OPL_Mode { - OPL_none,OPL_cms,OPL_opl2,OPL_dualopl2,OPL_opl3 + OPL_none,OPL_cms,OPL_opl2,OPL_dualopl2,OPL_opl3,OPL_opl3gold }; #define CAPTURE_WAVE 0x01 #define CAPTURE_OPL 0x02 diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 83e6f434..1462fae3 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -537,7 +537,7 @@ void DOSBOX_Init(void) { Pbool = secprop->Add_bool("sbmixer",Property::Changeable::WhenIdle,true); Pbool->Set_help("Allow the soundblaster mixer to modify the DOSBox mixer."); - const char* oplmodes[]={ "auto", "cms", "opl2", "dualopl2", "opl3", "none", 0}; + const char* oplmodes[]={ "auto", "cms", "opl2", "dualopl2", "opl3", "opl3gold", "none", 0}; Pstring = secprop->Add_string("oplmode",Property::Changeable::WhenIdle,"auto"); Pstring->Set_values(oplmodes); Pstring->Set_help("Type of OPL emulation. On 'auto' the mode is determined by sblaster type. All OPL modes are Adlib-compatible, except for 'cms'."); diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 89e512bf..6c4b3983 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -440,6 +440,36 @@ void Module::DualWrite( Bit8u index, Bit8u reg, Bit8u val ) { CacheWrite( fullReg, val ); } +void Module::CtrlWrite( Bit8u val ) { + switch ( ctrl.index ) { + case 0x09: /* Left FM Volume */ + ctrl.lvol = val; + goto setvol; + case 0x0a: /* Right FM Volume */ + ctrl.rvol = val; +setvol: + if ( ctrl.mixer ) { + //Dune cdrom uses 32 volume steps in an apparent mistake, should be 128 + mixerChan->SetVolume( (float)(ctrl.lvol&0x1f)/31.0f, (float)(ctrl.rvol&0x1f)/31.0f ); + } + break; + } +} + +Bitu Module::CtrlRead( void ) { + switch ( ctrl.index ) { + case 0x00: /* Board Options */ + return 0x70; //No options installed + case 0x09: /* Left FM Volume */ + return ctrl.lvol; + case 0x0a: /* Right FM Volume */ + return ctrl.rvol; + case 0x15: /* Audio Relocation */ + return 0x388 >> 3; //Cryo installer detection + } + return 0xff; +} + void Module::PortWrite( Bitu port, Bitu val, Bitu iolen ) { //Keep track of last write time @@ -450,6 +480,14 @@ void Module::PortWrite( Bitu port, Bitu val, Bitu iolen ) { } if ( port&1 ) { switch ( mode ) { + case MODE_OPL3GOLD: + if ( port == 0x38b ) { + if ( ctrl.active ) { + CtrlWrite( val ); + break; + } + } + //Fall-through if not handled by control chip case MODE_OPL2: case MODE_OPL3: if ( !chip[0].Write( reg.normal, val ) ) { @@ -476,6 +514,20 @@ void Module::PortWrite( Bitu port, Bitu val, Bitu iolen ) { case MODE_OPL2: reg.normal = handler->WriteAddr( port, val ) & 0xff; break; + case MODE_OPL3GOLD: + if ( port == 0x38a ) { + if ( val == 0xff ) { + ctrl.active = true; + break; + } else if ( val == 0xfe ) { + ctrl.active = false; + break; + } else if ( ctrl.active ) { + ctrl.index = val & 0xff; + break; + } + } + //Fall-through if not handled by control chip case MODE_OPL3: reg.normal = handler->WriteAddr( port, val ) & 0x1ff; break; @@ -504,6 +556,15 @@ Bitu Module::PortRead( Bitu port, Bitu iolen ) { } else { return 0xff; } + case MODE_OPL3GOLD: + if ( ctrl.active ) { + if ( port == 0x38a ) { + return 0; //Control status, not busy + } else if ( port == 0x38b ) { + return CtrlRead(); + } + } + //Fall-through if not handled by control chip case MODE_OPL3: //We allocated 4 ports, so just return -1 for the higher ones if ( !(port & 3 ) ) { @@ -527,6 +588,7 @@ void Module::Init( Mode m ) { mode = m; switch ( mode ) { case MODE_OPL3: + case MODE_OPL3GOLD: case MODE_OPL2: break; case MODE_DUALOPL2: @@ -627,6 +689,10 @@ Module::Module( Section* configuration ) : Module_base(configuration) { reg.dual[0] = 0; reg.dual[1] = 0; reg.normal = 0; + ctrl.active = false; + ctrl.index = 0; + ctrl.lvol = 0xff; + ctrl.rvol = 0xff; handler = 0; capture = 0; @@ -637,6 +703,7 @@ Module::Module( Section* configuration ) : Module_base(configuration) { if ( rate < 8000 ) rate = 8000; std::string oplemu( section->Get_string( "oplemu" ) ); + ctrl.mixer = section->Get_bool("sbmixer"); mixerChan = mixerObject.Install(OPL_CallBack,rate,"FM"); mixerChan->SetScale( 2.0 ); @@ -664,6 +731,9 @@ Module::Module( Section* configuration ) : Module_base(configuration) { case OPL_opl3: Init( Adlib::MODE_OPL3 ); break; + case OPL_opl3gold: + Init( Adlib::MODE_OPL3GOLD ); + break; } //0x388 range WriteHandler[0].Install(0x388,OPL_Write,IO_MB, 4 ); diff --git a/src/hardware/adlib.h b/src/hardware/adlib.h index 681fd491..26114c2c 100644 --- a/src/hardware/adlib.h +++ b/src/hardware/adlib.h @@ -90,7 +90,8 @@ struct Chip { typedef enum { MODE_OPL2, MODE_DUALOPL2, - MODE_OPL3 + MODE_OPL3, + MODE_OPL3GOLD } Mode; class Handler { @@ -125,8 +126,17 @@ class Module: public Module_base { Bit32u normal; Bit8u dual[2]; } reg; + struct { + bool active; + Bit8u index; + Bit8u lvol; + Bit8u rvol; + bool mixer; + } ctrl; void CacheWrite( Bit32u reg, Bit8u val ); void DualWrite( Bit8u index, Bit8u reg, Bit8u val ); + void CtrlWrite( Bit8u val ); + Bitu CtrlRead( void ); public: static OPL_Mode oplmode; MixerChannel* mixerChan; diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index d72066bb..80376a67 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1533,6 +1533,7 @@ private: else if (!strcasecmp(omode,"opl2")) opl_mode=OPL_opl2; else if (!strcasecmp(omode,"dualopl2")) opl_mode=OPL_dualopl2; else if (!strcasecmp(omode,"opl3")) opl_mode=OPL_opl3; + else if (!strcasecmp(omode,"opl3gold")) opl_mode=OPL_opl3gold; /* Else assume auto */ else { switch (type) { @@ -1588,6 +1589,7 @@ public: // fall-through case OPL_dualopl2: case OPL_opl3: + case OPL_opl3gold: OPL_Init(section,oplmode); break; } @@ -1645,6 +1647,7 @@ public: // fall-through case OPL_dualopl2: case OPL_opl3: + case OPL_opl3gold: OPL_ShutDown(m_configuration); break; } From b0a3ca8259a7a8b2a002725d193d2627dcd408d0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 30 Sep 2015 12:25:13 +0000 Subject: [PATCH 3847/4131] Add hardware text mode cursor support. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3937 --- src/ints/mouse.cpp | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index f4065b1b..b56be405 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -259,15 +259,26 @@ void DrawCursorText() { //use current page (CV program) Bit8u page = real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); - Bit16u result; - - ReadCharAttr(mouse.backposx,mouse.backposy,page,&result); - mouse.backData[0] = (Bit8u)(result & 0xFF); - mouse.backData[1] = (Bit8u)(result>>8); - mouse.background = true; - // Write Cursor - result = (result & mouse.textAndMask) ^ mouse.textXorMask; - WriteChar(mouse.backposx,mouse.backposy,page,(Bit8u)(result&0xFF),(Bit8u)(result>>8),true); + + if (mouse.cursorType == 0) { + Bit16u result; + ReadCharAttr(mouse.backposx,mouse.backposy,page,&result); + mouse.backData[0] = (Bit8u)(result & 0xFF); + mouse.backData[1] = (Bit8u)(result>>8); + mouse.background = true; + // Write Cursor + result = (result & mouse.textAndMask) ^ mouse.textXorMask; + WriteChar(mouse.backposx,mouse.backposy,page,(Bit8u)(result&0xFF),(Bit8u)(result>>8),true); + } else { + Bit16u address=page * real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); + address += (mouse.backposy * real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS) + mouse.backposx) * 2; + address /= 2; + Bit16u cr = real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + IO_Write(cr , 0xe); + IO_Write(cr + 1, (address>>8) & 0xff); + IO_Write(cr , 0xf); + IO_Write(cr + 1, address & 0xff); + } } // *************************************************************************** @@ -666,7 +677,7 @@ void Mouse_AfterNewVideoMode(bool setmode) { mouse.updateRegion_y[0] = 1; mouse.updateRegion_x[1] = 1; mouse.updateRegion_y[1] = 1; - mouse.cursorType = 0; + mouse.cursorType = 0; //Test mouse.enabled=true; oldmouseX = static_cast(mouse.x); @@ -802,9 +813,14 @@ static Bitu INT33_Handler(void) { } break; case 0x0a: /* Define Text Cursor */ - mouse.cursorType = reg_bx; + mouse.cursorType = (reg_bx?1:0); mouse.textAndMask = reg_cx; mouse.textXorMask = reg_dx; + if (reg_bx) { + INT10_SetCursorShape(reg_cl,reg_dl); + LOG(LOG_MOUSE,LOG_NORMAL)("Hardware Text cursor selected"); + } + DrawCursor(); break; case 0x0b: /* Read Motion Data */ reg_cx=static_cast(mouse.mickey_x); @@ -1025,6 +1041,7 @@ static Bitu INT74_Handler(void) { reg_ip = mouse.sub_ofs; if(mouse.in_UIR) LOG(LOG_MOUSE,LOG_ERROR)("Already in UIR!"); mouse.in_UIR = true; + //LOG(LOG_MOUSE,LOG_ERROR)("INT 74 %X",mouse.event_queue[mouse.events].type ); } else if (useps2callback) { CPU_Push16(RealSeg(CALLBACK_RealPointer(int74_ret_callback))); CPU_Push16(RealOff(CALLBACK_RealPointer(int74_ret_callback))); @@ -1032,10 +1049,12 @@ static Bitu INT74_Handler(void) { } else { SegSet16(cs, RealSeg(CALLBACK_RealPointer(int74_ret_callback))); reg_ip = RealOff(CALLBACK_RealPointer(int74_ret_callback)); + //LOG(LOG_MOUSE,LOG_ERROR)("INT 74 not interested"); } } else { SegSet16(cs, RealSeg(CALLBACK_RealPointer(int74_ret_callback))); reg_ip = RealOff(CALLBACK_RealPointer(int74_ret_callback)); + //LOG(LOG_MOUSE,LOG_ERROR)("INT 74 no events"); } return CBRET_NONE; } From 39875d92dab412987ee28e619f5a9b536c6f3c64 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 30 Sep 2015 14:24:49 +0000 Subject: [PATCH 3848/4131] Add call to clear out some more fields, needed for fcb name parsing. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3938 --- include/dos_inc.h | 1 + src/dos/dos_classes.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/include/dos_inc.h b/include/dos_inc.h index 98e76547..070bb3b2 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -509,6 +509,7 @@ public: void SetAttr(Bit8u attr); void SetResultAttr(Bit8u attr); bool Valid(void); + void ClearBlockRecsize(void); private: bool extended; PhysPt real_pt; diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index b88895ec..73c895b3 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -444,6 +444,10 @@ void DOS_FCB::SetRandom(Bit32u _random) { sSave(sFCB,rndm,_random); } +void DOS_FCB::ClearBlockRecsize(void) { + sSave(sFCB,cur_block,0); + sSave(sFCB,rec_size,0); +} void DOS_FCB::FileOpen(Bit8u _fhandle) { sSave(sFCB,drive,GetDrive()+1); sSave(sFCB,file_handle,_fhandle); From 57ff3dfc95bd5163825b47283f0d6e6b79944ec7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 Oct 2015 20:02:55 +0000 Subject: [PATCH 3849/4131] Added commented out log message, to save some work Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3939 --- src/dos/dos_ioctl.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 2df136f5..13e436b6 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -25,6 +25,7 @@ #include "dos_inc.h" bool DOS_IOCTL(void) { +// LOG(LOG_IOCTL,LOG_WARN)("%X %X %X %X",reg_ax,reg_bx,reg_cx,reg_dx); Bitu handle=0;Bit8u drive=0; /* calls 0-4,6,7,10,12,16 use a file handle */ if ((reg_al<4) || (reg_al==0x06) || (reg_al==0x07) || (reg_al==0x0a) || (reg_al==0x0c) || (reg_al==0x10)) { From cf9f8b2d3e53a770325a1be230515e0a705ba570 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 Oct 2015 20:13:57 +0000 Subject: [PATCH 3850/4131] -Add DOS_ToUpper which seems closer than just toupper, we might need to use it at more places than just the driveletter, but it is a big change. -Rework FCB_ParseName: -- Remove special code for . and .. as it was wrong -- Continue reading the input string, when the max length of the field has been reached (123456789.12345 is read and returned as 12345678.123) -- strip spaces before and after reading the separators. -- The drive is always parsed (if present), it doesn't depend on the existence of said drive. -- Fix parsing of .EXE and other extension only names -- Always clear out current block and record size. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3940 --- src/dos/dos_files.cpp | 120 +++++++++++++++++++++++++----------------- 1 file changed, 72 insertions(+), 48 deletions(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index a37b4cf8..3cdac4bf 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -774,7 +774,21 @@ bool DOS_CreateTempFile(char * const name,Bit16u * entry) { return true; } -#define FCB_SEP ":.;,=+" +char DOS_ToUpper(char c) { + unsigned char uc = *reinterpret_cast(&c); + if (uc > 0x60 && uc < 0x7B) uc -= 0x20; + else if (uc > 0x7F && uc < 0xA5) { + const unsigned char t[0x25] = { + 0x00, 0x9a, 0x45, 0x41, 0x8E, 0x41, 0x8F, 0x80, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x4F, 0x99, 0x4F, 0x55, 0x55, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x41, 0x49, 0x4F, 0x55, 0xA5}; + if (t[uc - 0x80]) uc = t[uc-0x80]; + } + char sc = *reinterpret_cast(&uc); + return sc; +} + +#define FCB_SEP ":;,=+" #define ILLEGAL ":.;,=+ \t/\"[]<>|" static bool isvalid(const char in){ @@ -822,77 +836,87 @@ Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u * fcb.GetName(fcb_name.full); fcb_name.part.drive[0]-='A'-1;fcb_name.part.drive[1]=0; fcb_name.part.name[8]=0;fcb_name.part.ext[3]=0; - /* Strip of the leading sepetaror */ - if((parser & PARSE_SEP_STOP) && *string) { //ignore leading seperator - char sep[] = FCB_SEP;char a[2]; - a[0]= *string;a[1]='\0'; - if (strcspn(a,sep)==0) string++; - } /* strip leading spaces */ while((*string==' ')||(*string=='\t')) string++; + + /* Strip of the leading separator */ + if((parser & PARSE_SEP_STOP) && *string) { + char sep[] = FCB_SEP;char a[2]; + a[0] = *string;a[1] = '\0'; + if (strcspn(a,sep) == 0) string++; + } + + /* Skip following spaces as well */ + while((*string==' ')||(*string=='\t')) string++; + /* Check for a drive */ if (string[1]==':') { + unsigned char d = *reinterpret_cast(&string[0]); + if (!isvalid(toupper(d))) {string += 2; goto savefcb;} //TODO check (for ret value) fcb_name.part.drive[0]=0; hasdrive=true; - if (isalpha(string[0]) && Drives[toupper(string[0])-'A']) { - fcb_name.part.drive[0]=(char)(toupper(string[0])-'A'+1); + if (isalpha(d) && Drives[toupper(d)-'A']) { //Floppies under dos always exist, but don't bother with that at this level + ; //THIS* was here } else ret=0xff; + fcb_name.part.drive[0]=DOS_ToUpper(string[0])-'A'+1; //Always do THIS* and continue parsing, just return the right code string+=2; } - /* Special checks for . and .. */ - if (string[0]=='.') { - string++; - if (!string[0]) { - hasname=true; - ret=PARSE_RET_NOWILD; - strcpy(fcb_name.part.name,". "); - goto savefcb; - } - if (string[1]=='.' && !string[1]) { - string++; - hasname=true; - ret=PARSE_RET_NOWILD; - strcpy(fcb_name.part.name,".. "); - goto savefcb; - } - goto checkext; - } - /* Copy the name */ + + /* Check for extension only file names */ + if (string[0] == '.') {string++;goto checkext;} + + /* do nothing if not a valid name */ + if(!isvalid(string[0])) goto savefcb; + hasname=true;finished=false;fill=' ';index=0; - while (index<8) { - if (!finished) { - if (string[0]=='*') {fill='?';fcb_name.part.name[index]='?';if (!ret) ret=1;finished=true;} - else if (string[0]=='?') {fcb_name.part.name[index]='?';if (!ret) ret=1;} - else if (isvalid(string[0])) {fcb_name.part.name[index]=(char)(toupper(string[0]));} - else { finished=true;continue; } - string++; - } else { - fcb_name.part.name[index]=fill; + /* Copy the name */ + while (true) { + unsigned char nc = *reinterpret_cast(&string[0]); + char ncs = (char)toupper(nc); //Should use DOS_ToUpper, but then more calls need to be changed. + if (ncs == '*') { //Handle * + fill = '?'; + ncs = '?'; } - index++; + if (ncs == '?' && !ret && index < 8) ret = 1; //Don't override bad drive + if (!isvalid(ncs)) { //Fill up the name. + while(index < 8) + fcb_name.part.name[index++] = fill; + break; + } + if (index < 8) { + fcb_name.part.name[index++] = (fill == '?')?fill:ncs; + } + string++; } if (!(string[0]=='.')) goto savefcb; string++; checkext: /* Copy the extension */ hasext=true;finished=false;fill=' ';index=0; - while (index<3) { - if (!finished) { - if (string[0]=='*') {fill='?';fcb_name.part.ext[index]='?';finished=true;} - else if (string[0]=='?') {fcb_name.part.ext[index]='?';if (!ret) ret=1;} - else if (isvalid(string[0])) {fcb_name.part.ext[index]=(char)(toupper(string[0]));} - else { finished=true;continue; } - string++; - } else { - fcb_name.part.ext[index]=fill; + while (true) { + unsigned char nc = *reinterpret_cast(&string[0]); + char ncs = (char)toupper(nc); + if (ncs == '*') { //Handle * + fill = '?'; + ncs = '?'; } - index++; + if (ncs == '?' && !ret && index < 3) ret = 1; + if (!isvalid(ncs)) { //Fill up the name. + while(index < 3) + fcb_name.part.ext[index++] = fill; + break; + } + if (index < 3) { + fcb_name.part.ext[index++] = (fill=='?')?fill:ncs; + } + string++; } savefcb: if (!hasdrive & !(parser & PARSE_DFLT_DRIVE)) fcb_name.part.drive[0] = 0; if (!hasname & !(parser & PARSE_BLNK_FNAME)) strcpy(fcb_name.part.name," "); if (!hasext & !(parser & PARSE_BLNK_FEXT)) strcpy(fcb_name.part.ext," "); fcb.SetName(fcb_name.part.drive[0],fcb_name.part.name,fcb_name.part.ext); + fcb.ClearBlockRecsize(); //Undocumented bonus work. *change=(Bit8u)(string-string_begin); return ret; } From 34cc2d642801eba0f1cf958fd71e6ea9520e651e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 Oct 2015 20:16:28 +0000 Subject: [PATCH 3851/4131] correct AX and BX, they contain information on the existence of the drives specified in the FCBs in the execute block. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3941 --- src/dos/dos_execute.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 78572309..0037b8c5 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -462,6 +462,16 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { /* copy fcbs */ newpsp.SetFCB1(block.exec.fcb1); newpsp.SetFCB2(block.exec.fcb2); + + /* Setup ax and bx, they contain a 0xff in al and ah if the drive in the fcb is not valid */ + DOS_FCB fcb1(RealSeg(block.exec.fcb1),RealOff(block.exec.fcb1)); + DOS_FCB fcb2(RealSeg(block.exec.fcb2),RealOff(block.exec.fcb2)); + Bit8u d1 = fcb1.GetDrive(); //depends on 0 giving the dos.default drive + if ( (d1>=DOS_DRIVES) || !Drives[d1] ) reg_bl = 0xFF; else reg_bl = 0; + Bit8u d2 = fcb2.GetDrive(); + if ( (d2>=DOS_DRIVES) || !Drives[d2] ) reg_bh = 0xFF; else reg_bh = 0; + reg_ax = reg_bx; + /* Set the stack for new program */ SegSet16(ss,RealSeg(sssp));reg_sp=RealOff(sssp); /* Add some flags and CS:IP on the stack for the IRET */ @@ -474,7 +484,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { //Jump to retf so that we only need to store cs:ip on the stack reg_ip++; /* Setup the rest of the registers */ - reg_ax=reg_bx=0;reg_cx=0xff; + reg_cx=0xff; reg_dx=pspseg; reg_si=RealOff(csip); reg_di=RealOff(sssp); From c8a128d733ca732547360ca946a4ef35dbf738e0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 Oct 2015 20:23:14 +0000 Subject: [PATCH 3852/4131] Rework the parsing of arguments into the FCBs: - We now first split the line into arguments using space,tab,;,=,',' as separators. - Next we convert /Hello into H ello - Lastly we feed the arguments 1 and 2 to the FCB_Parsename function (- It got messy, but the results are better ) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3942 --- src/shell/shell_misc.cpp | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 02ae2450..d131e7a8 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -480,10 +480,44 @@ bool DOS_Shell::Execute(char * name,char * args) { cmdtail.buffer[strlen(line)]=0xd; /* Copy command line in stack block too */ MEM_BlockWrite(SegPhys(ss)+reg_sp+0x100,&cmdtail,128); + + + /* Split input line up into parameters, using a few special rules, most notable the one for /AAA => A\0AA + * Qbix: It is extremly messy, but this was the only way I could get things like /:aa and :/aa to work correctly */ + + //Prepare string first + char parseline[258] = { 0 }; + for(char *pl = line,*q = parseline; *pl ;pl++,q++) { + if (*pl == '=' || *pl == ';' || *pl ==',' || *pl == '\t' || *pl == ' ') *q = 0; else *q = *pl; //Replace command seperators with 0. + } //No end of string \0 needed as parseline is larger than line + + for(char* p = parseline; (p-parseline) < 250 ;p++) { //Stay relaxed within boundaries as we have plenty of room + if (*p == '/') { //Transform /Hello into H\0ello + *p = 0; + p++; + while ( *p == 0 && (p-parseline) < 250) p++; //Skip empty fields + if ((p-parseline) < 250) { //Found something. Lets get the first letter and break it up + p++; + memmove(static_cast(p + 1),static_cast(p),(250-(p-parseline))); + if ((p-parseline) < 250) *p = 0; + } + } + } + parseline[255] = parseline[256] = parseline[257] = 0; //Just to be safe. + /* Parse FCB (first two parameters) and put them into the current DOS_PSP */ Bit8u add; - FCB_Parsename(dos.psp(),0x5C,0x00,cmdtail.buffer,&add); - FCB_Parsename(dos.psp(),0x6C,0x00,&cmdtail.buffer[add],&add); + Bit16u skip = 0; + //find first argument, we end up at parseline[256] if there is only one argument (similar for the second), which exists and is 0. + while(skip < 256 && parseline[skip] == 0) skip++; + FCB_Parsename(dos.psp(),0x5C,0x01,parseline + skip,&add); + skip += add; + + //Move to next argument if it exists + while(parseline[skip] != 0) skip++; //This is safe as there is always a 0 in parseline at the end. + while(skip < 256 && parseline[skip] == 0) skip++; //Which is higher than 256 + FCB_Parsename(dos.psp(),0x6C,0x01,parseline + skip,&add); + block.exec.fcb1=RealMake(dos.psp(),0x5C); block.exec.fcb2=RealMake(dos.psp(),0x6C); /* Set the command line in the block and save it */ From c4177a33c63485d3b2bef7d0e4d3572a5f2ec76b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 2 Oct 2015 20:40:41 +0000 Subject: [PATCH 3853/4131] Add patch 256 from Dominus: OS X - CoreAudio deprecated warnings eliminated Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3943 --- src/gui/midi_coreaudio.h | 103 +++++++++++++++++++++++++++++++++------ 1 file changed, 87 insertions(+), 16 deletions(-) diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index 9c675742..05aa3e18 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -28,6 +28,31 @@ do { \ goto bail; \ } while (false) +// With the release of Mac OS X 10.5 in October 2007, Apple deprecated the +// AUGraphNewNode & AUGraphGetNodeInfo APIs in favor of the new AUGraphAddNode & +// AUGraphNodeInfo APIs. While it is easy to switch to those, it breaks +// compatibility with all pre-10.5 systems. +// +// Since 10.5 was the last system to support PowerPC, we use the old, deprecated +// APIs on PowerPC based systems by default. On all other systems (such as Mac +// OS X running on Intel hardware, or iOS running on ARM), we use the new API by +// default. +// +// This leaves Mac OS X 10.4 running on x86 processors as the only system +// combination that this code will not support by default. It seems quite +// reasonable to assume that anybody with an Intel system has since then moved +// on to a newer Mac OS X release. But if for some reason you absolutely need to +// build an x86 version of this code using the old, deprecated API, you can +// simply do so by manually enable the USE_DEPRECATED_COREAUDIO_API switch (e.g. +// by adding setting it suitably in CPPFLAGS). +#if !defined(USE_DEPRECATED_COREAUDIO_API) +# if TARGET_CPU_PPC || TARGET_CPU_PPC64 +# define USE_DEPRECATED_COREAUDIO_API 1 +# else +# define USE_DEPRECATED_COREAUDIO_API 0 +# endif +#endif + class MidiHandler_coreaudio : public MidiHandler { private: AUGraph m_auGraph; @@ -46,7 +71,12 @@ public: RequireNoErr(NewAUGraph(&m_auGraph)); AUNode outputNode, synthNode; + // OS X 10.5 SDK doesn't know AudioComponentDescription desc; +#if USE_DEPRECATED_COREAUDIO_API || (MAC_OS_X_VERSION_MAX_ALLOWED <= 1050) ComponentDescription desc; +#else + AudioComponentDescription desc; +#endif // The default output device desc.componentType = kAudioUnitType_Output; @@ -54,13 +84,21 @@ public: desc.componentManufacturer = kAudioUnitManufacturer_Apple; desc.componentFlags = 0; desc.componentFlagsMask = 0; +#if USE_DEPRECATED_COREAUDIO_API RequireNoErr(AUGraphNewNode(m_auGraph, &desc, 0, NULL, &outputNode)); +#else + RequireNoErr(AUGraphAddNode(m_auGraph, &desc, &outputNode)); +#endif // The built-in default (softsynth) music device desc.componentType = kAudioUnitType_MusicDevice; desc.componentSubType = kAudioUnitSubType_DLSSynth; desc.componentManufacturer = kAudioUnitManufacturer_Apple; +#if USE_DEPRECATED_COREAUDIO_API RequireNoErr(AUGraphNewNode(m_auGraph, &desc, 0, NULL, &synthNode)); +#else + RequireNoErr(AUGraphAddNode(m_auGraph, &desc, &synthNode)); +#endif // Connect the softsynth to the default output RequireNoErr(AUGraphConnectNodeInput(m_auGraph, synthNode, 0, outputNode, 0)); @@ -70,24 +108,57 @@ public: RequireNoErr(AUGraphInitialize(m_auGraph)); // Get the music device from the graph. +#if USE_DEPRECATED_COREAUDIO_API RequireNoErr(AUGraphGetNodeInfo(m_auGraph, synthNode, NULL, NULL, NULL, &m_synth)); +#else + RequireNoErr(AUGraphNodeInfo(m_auGraph, synthNode, NULL, &m_synth)); +#endif - // Optionally load a soundfont - if (conf && conf[0]) { - soundfont = conf; - FSRef soundfontRef; - RequireNoErr(FSPathMakeRef((const UInt8*)soundfont, &soundfontRef, NULL)); - RequireNoErr(AudioUnitSetProperty( - m_synth, - kMusicDeviceProperty_SoundBankFSRef, - kAudioUnitScope_Global, - 0, - &soundfontRef, - sizeof(soundfontRef) - )); - LOG_MSG("MIDI:coreaudio: loaded soundfont: %s",soundfont); - } - + // Optionally load a soundfont + if (conf && conf[0]) { + soundfont = conf; + OSErr err; +#if USE_DEPRECATED_COREAUDIO_API + FSRef soundfontRef; + err = FSPathMakeRef((const UInt8*)soundfont, &soundfontRef, NULL); + if (!err) { + err = AudioUnitSetProperty( + m_synth, + kMusicDeviceProperty_SoundBankFSRef, + kAudioUnitScope_Global, + 0, + &soundfontRef, + sizeof(soundfontRef) + ); + } +#else + // kMusicDeviceProperty_SoundBankFSRef is present on 10.6+, but + // kMusicDeviceProperty_SoundBankURL was added in 10.5 as a future prooof replacement + CFURLRef url = CFURLCreateFromFileSystemRepresentation( + kCFAllocatorDefault, + (const UInt8*)soundfont, + strlen(soundfont), false + ); + if (url) { + err = AudioUnitSetProperty( + m_synth, kMusicDeviceProperty_SoundBankURL, + kAudioUnitScope_Global, 0, &url, sizeof(url) + ); + CFRelease(url); + } else { + LOG_MSG("Failed to allocate CFURLRef from %s",soundfont); + } +#endif + if (!err) { + LOG_MSG("MIDI:coreaudio: loaded soundfont: %s",soundfont); + } else { + LOG_MSG("Error loading CoreAudio SoundFont %s",soundfont); + // after trying and failing to load a soundfont it's better + // to fail initializing the CoreAudio driver or it might crash + return false; + } + } + // Finally: Start the graph! RequireNoErr(AUGraphStart(m_auGraph)); From 1eecef3f33c795f06812cc7399120109621ab068 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sat, 3 Oct 2015 08:59:45 +0000 Subject: [PATCH 3854/4131] Use full mask; fixes label search on FAT drives. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3944 --- src/dos/dos_programs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 3b2aed61..82fc324c 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -69,7 +69,7 @@ public: for (int d = 0;d < DOS_DRIVES;d++) { if (!Drives[d]) continue; - char root[4] = {'A'+d,':','\\',0}; + char root[7] = {'A'+d,':','\\','*','.','*',0}; bool ret = DOS_FindFirst(root,DOS_ATTR_VOLUME); if (ret) { dta.GetResult(name,size,date,time,attr); @@ -1296,7 +1296,7 @@ public: for(ct = 0; ct < imgDisks.size(); ct++) { DriveManager::CycleAllDisks(); - char root[4] = {drive, ':', '\\', 0}; + char root[7] = {drive,':','\\','*','.','*',0}; DOS_FindFirst(root, DOS_ATTR_VOLUME); // force obtaining the label and saving it in dirCache } dos.dta(save_dta); From 6c0cca18782fe157cf40fde90b22f5b742826eeb Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sat, 3 Oct 2015 09:21:56 +0000 Subject: [PATCH 3855/4131] Don't write past the terminator in the DTA name field when setting search results. This is what DOS does, and writing junk after the terminator was not good in any case. Fixes file listing in the 16-bit version of Galaxy Player. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3945 --- src/dos/dos_classes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 73c895b3..27658b42 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -340,7 +340,7 @@ void DOS_DTA::SetupSearch(Bit8u _sdrive,Bit8u _sattr,char * pattern) { } void DOS_DTA::SetResult(const char * _name,Bit32u _size,Bit16u _date,Bit16u _time,Bit8u _attr) { - MEM_BlockWrite(pt+offsetof(sDTA,name),(void *)_name,DOS_NAMELENGTH_ASCII); + MEM_BlockWrite(pt+offsetof(sDTA,name),(void *)_name,strlen(_name)+1); sSave(sDTA,size,_size); sSave(sDTA,date,_date); sSave(sDTA,time,_time); From 4aaa632bd969b22b76a5385963133d1cc97cd857 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 5 Oct 2015 08:11:45 +0000 Subject: [PATCH 3856/4131] touch up cdrom stuff for mingw64 once again (ny00123) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3946 --- src/dos/cdrom_aspi_win32.cpp | 9 +++++---- src/dos/cdrom_ioctl_win32.cpp | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index 35c891ff..abc48ed1 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -32,10 +32,11 @@ #include // Ioctl stuff #include #include // Ioctl stuff -#else -#ifdef __MINGW64_VERSION_MAJOR -#include -#endif +#elif (defined __MINGW64_VERSION_MAJOR) +#include // Ioctl stuff +#include // Ioctl stuff +#include +#else #include "ddk/ntddcdrm.h" // Ioctl stuff #include "ddk/ntddscsi.h" #endif diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index 615750e1..84e15e97 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -26,7 +26,7 @@ #include #include -#if defined (_MSC_VER) +#if (defined (_MSC_VER)) || (defined __MINGW64_VERSION_MAJOR) #include // Ioctl stuff #include // Ioctl stuff #else From 2a1ae6fb9ce5d405fa59decab96010ab53530165 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 8 Oct 2015 19:51:01 +0000 Subject: [PATCH 3857/4131] Improve rename support for when renaming files (in a folder) on a drive different from the current one. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3947 --- src/shell/shell_cmds.cpp | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index e63ea6c5..a8cf22bd 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -233,34 +233,38 @@ void DOS_Shell::CMD_HELP(char * args){ void DOS_Shell::CMD_RENAME(char * args){ HELP("RENAME"); StripSpaces(args); - if(!*args) {SyntaxError();return;} - if((strchr(args,'*')!=NULL) || (strchr(args,'?')!=NULL) ) { WriteOut(MSG_Get("SHELL_CMD_NO_WILD"));return;} + if (!*args) {SyntaxError();return;} + if ((strchr(args,'*')!=NULL) || (strchr(args,'?')!=NULL) ) { WriteOut(MSG_Get("SHELL_CMD_NO_WILD"));return;} char * arg1=StripWord(args); + StripSpaces(args); + if (!*args) {SyntaxError();return;} char* slash = strrchr(arg1,'\\'); - if(slash) { - slash++; + if (slash) { /* If directory specified (crystal caves installer) * rename from c:\X : rename c:\abc.exe abc.shr. - * File must appear in C:\ */ + * File must appear in C:\ + * Ren X:\A\B C => ren X:\A\B X:\A\C */ - char dir_source[DOS_PATHLENGTH]={0}; + char dir_source[DOS_PATHLENGTH + 4] = {0}; //not sure if drive portion is included in pathlength //Copy first and then modify, makes GCC happy - strcpy(dir_source,arg1); + safe_strncpy(dir_source,arg1,DOS_PATHLENGTH + 4); char* dummy = strrchr(dir_source,'\\'); - *dummy=0; - - if((strlen(dir_source) == 2) && (dir_source[1] == ':')) - strcat(dir_source,"\\"); //X: add slash - - char dir_current[DOS_PATHLENGTH + 1]; - dir_current[0] = '\\'; //Absolute addressing so we can return properly - DOS_GetCurrentDir(0,dir_current + 1); - if(!DOS_ChangeDir(dir_source)) { + if (!dummy) { //Possible due to length WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); return; } - DOS_Rename(slash,args); - DOS_ChangeDir(dir_current); + dummy++; + *dummy = 0; + + //Maybe check args for directory, as I think that isn't allowed + + //dir_source and target are introduced for when we support multiple files being renamed. + char target[DOS_PATHLENGTH+CROSS_LEN + 5] = {0}; + strcpy(target,dir_source); + strncat(target,args,CROSS_LEN); + + DOS_Rename(arg1,target); + } else { DOS_Rename(arg1,args); } From 53a38b773a5610c012b8f9a1c99f0ef414234a44 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Mon, 19 Oct 2015 23:37:06 +0000 Subject: [PATCH 3858/4131] Improve internal ANSI support to adapt to currently displayed columns and rows. Fixes original Infocom interpreters when using something other than 80x25. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3948 --- src/dos/dev_con.h | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index ef397730..05af1d0a 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -44,8 +44,6 @@ private: Bit8u attr; Bit8u data[NUMBER_ANSI_DATA]; Bit8u numberofarg; - Bit16u nrows; - Bit16u ncols; Bit8s savecol; Bit8s saverow; bool warned; @@ -117,6 +115,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { Bit16u count=0; Bitu i; Bit8u col,row; + Bit16u ncols,nrows; Bit8u tempdata; while (*size>count) { if (!ansi.esc){ @@ -273,11 +272,13 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { ansi.warned = true; LOG(LOG_IOCTL,LOG_WARN)("ANSI SEQUENCES USED"); } + ncols = real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); + nrows = real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS) + 1; /* Turn them into positions that are on the screen */ if(ansi.data[0] == 0) ansi.data[0] = 1; if(ansi.data[1] == 0) ansi.data[1] = 1; - if(ansi.data[0] > ansi.nrows) ansi.data[0] = (Bit8u)ansi.nrows; - if(ansi.data[1] > ansi.ncols) ansi.data[1] = (Bit8u)ansi.ncols; + if(ansi.data[0] > nrows) ansi.data[0] = (Bit8u)nrows; + if(ansi.data[1] > ncols) ansi.data[1] = (Bit8u)ncols; INT10_SetCursorPos(--(ansi.data[0]),--(ansi.data[1]),page); /*ansi=1 based, int10 is 0 based */ ClearAnsi(); break; @@ -294,9 +295,10 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { case 'B': /*cursor Down */ col=CURSOR_POS_COL(page) ; row=CURSOR_POS_ROW(page) ; + nrows = real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS) + 1; tempdata = (ansi.data[0]? ansi.data[0] : 1); - if(tempdata + static_cast(row) >= ansi.nrows) - { row = ansi.nrows - 1;} + if(tempdata + static_cast(row) >= nrows) + { row = nrows - 1;} else { row += tempdata; } INT10_SetCursorPos(row,col,page); ClearAnsi(); @@ -304,9 +306,10 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { case 'C': /*cursor forward */ col=CURSOR_POS_COL(page); row=CURSOR_POS_ROW(page); + ncols = real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); tempdata=(ansi.data[0]? ansi.data[0] : 1); - if(tempdata + static_cast(col) >= ansi.ncols) - { col = ansi.ncols - 1;} + if(tempdata + static_cast(col) >= ncols) + { col = ncols - 1;} else { col += tempdata;} INT10_SetCursorPos(row,col,page); ClearAnsi(); @@ -346,15 +349,17 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { case 'K': /* erase till end of line (don't touch cursor) */ col = CURSOR_POS_COL(page); row = CURSOR_POS_ROW(page); - INT10_WriteChar(' ',ansi.attr,page,ansi.ncols-col,true); //Use this one to prevent scrolling when end of screen is reached - //for(i = col;i<(Bitu) ansi.ncols; i++) INT10_TeletypeOutputAttr(' ',ansi.attr,true); + ncols = real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); + INT10_WriteChar(' ',ansi.attr,page,ncols-col,true); //Use this one to prevent scrolling when end of screen is reached + //for(i = col;i<(Bitu) ncols; i++) INT10_TeletypeOutputAttr(' ',ansi.attr,true); INT10_SetCursorPos(row,col,page); ClearAnsi(); break; case 'M': /* delete line (NANSI) */ - col = CURSOR_POS_COL(page); row = CURSOR_POS_ROW(page); - INT10_ScrollWindow(row,0,ansi.nrows-1,ansi.ncols-1,ansi.data[0]? -ansi.data[0] : -1,ansi.attr,0xFF); + ncols = real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); + nrows = real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS) + 1; + INT10_ScrollWindow(row,0,nrows-1,ncols-1,ansi.data[0]? -ansi.data[0] : -1,ansi.attr,0xFF); ClearAnsi(); break; case 'l':/* (if code =7) disable linewrap */ @@ -403,8 +408,6 @@ device_CON::device_CON() { lastwrite=0; ansi.enabled=false; ansi.attr=0x7; - ansi.ncols=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); //should be updated once set/reset mode is implemented - ansi.nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS) + 1; ansi.saverow=0; ansi.savecol=0; ansi.warned=false; From b2bcdaf1effb0ea5ba29ab9c0d476ca66f1293bd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 20 Oct 2015 16:19:45 +0000 Subject: [PATCH 3859/4131] Fix bug #349 dynrec endianness unsafe access to Segs.val[x] Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3949 --- include/regs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/regs.h b/include/regs.h index 4ecab980..259ab695 100644 --- a/include/regs.h +++ b/include/regs.h @@ -59,7 +59,7 @@ struct Segment { enum SegNames { es=0,cs,ss,ds,fs,gs}; struct Segments { - Bitu val[8]; + Bit16u val[8]; PhysPt phys[8]; }; From 76a04f0807d5550c31dcaf6ea15cf05d923c890b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 20 Oct 2015 17:06:29 +0000 Subject: [PATCH 3860/4131] Fix bug #395 DOSBox can't handle double-quoted values in dosbox.conf files. Extend the fix to include single quoted values. Fix a common typo: Separator => Separator Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3950 --- include/setup.h | 4 ++-- src/misc/setup.cpp | 28 ++++++++++++++++++---------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/include/setup.h b/include/setup.h index 7c8ad3dc..006cef67 100644 --- a/include/setup.h +++ b/include/setup.h @@ -294,10 +294,10 @@ public: class Prop_multival:public Property{ protected: Section_prop* section; - std::string seperator; + std::string separator; 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) { + Prop_multival(std::string const& _propname, Changeable::Value when,std::string const& sep):Property(_propname,when), section(new Section_prop("")),separator(sep) { default_value = value = ""; } Section_prop *GetSection() { return section; } diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 7251d2f8..eea76a20 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -339,7 +339,7 @@ void Prop_multival::make_default_value(){ while( (p = section->Get_prop(i++)) ) { std::string props = p->Get_Default_Value().ToString(); if(props == "") continue; - result += seperator; result += props; + result += separator; result += props; } Value val(result,Value::V_STRING); SetVal(val,false,true); @@ -363,14 +363,14 @@ bool Prop_multival_remain::SetValue(std::string const& input) { string::size_type loc = string::npos; while( (p = section->Get_prop(i++)) ) { - //trim leading seperators - loc = local.find_first_not_of(seperator); + //trim leading separators + loc = local.find_first_not_of(separator); if(loc != string::npos) local.erase(0,loc); - loc = local.find_first_of(seperator); + loc = local.find_first_of(separator); string in = "";//default value /* when i == number_of_properties add the total line. (makes more then * one string argument possible for parameters of cpu) */ - if(loc != string::npos && i < number_of_properties) { //seperator found + if(loc != string::npos && i < number_of_properties) { //separator found in = local.substr(0,loc); local.erase(0,loc+1); } else if(local.size()) { //last argument or last property @@ -400,12 +400,12 @@ bool Prop_multival::SetValue(std::string const& input) { if(!p) return false; string::size_type loc = string::npos; while( (p = section->Get_prop(i++)) ) { - //trim leading seperators - loc = local.find_first_not_of(seperator); + //trim leading separators + loc = local.find_first_not_of(separator); if(loc != string::npos) local.erase(0,loc); - loc = local.find_first_of(seperator); + loc = local.find_first_of(separator); string in = "";//default value - if(loc != string::npos) { //seperator found + if(loc != string::npos) { //separator found in = local.substr(0,loc); local.erase(0,loc+1); } else if(local.size()) { //last argument @@ -588,9 +588,17 @@ bool Section_prop::HandleInputline(string const& gegevens){ if(loc == string::npos) return false; string name = str1.substr(0,loc); string val = str1.substr(loc + 1); + + /* Remove quotes around value */ + trim(val); + string::size_type length = val.length(); + if (length > 1 && + ((val[0] == '"' && val[length - 1] == '"' ) || + (val[0] == '\'' && val[length - 1] == '\'')) + ) val = val.substr(1,length - 2); /* trim the results incase there were spaces somewhere */ trim(name);trim(val); - for(it tel=properties.begin();tel!=properties.end();tel++){ + for(it tel = properties.begin();tel != properties.end();tel++){ if(!strcasecmp((*tel)->propname.c_str(),name.c_str())){ return (*tel)->SetValue(val); } From 2c554e48dd2afdc512dc1ab7da1d55a9ff1db468 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 2 Nov 2015 18:09:06 +0000 Subject: [PATCH 3861/4131] Apply patch by gulikoza to add support for absolute 64 addresssing. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3951 --- src/cpu/core_dynrec/risc_x64.h | 147 ++++++++++++++++++--------------- 1 file changed, 81 insertions(+), 66 deletions(-) diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index 0f1d9490..44ccf5a3 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -82,45 +82,98 @@ static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { cache_addb(0xc0+(reg_dst<<3)+reg_src); } +// move a 64bit constant value into a full register +static void gen_mov_reg_qword(HostReg dest_reg,Bit64u imm) { + cache_addb(0x48); + cache_addb(0xb8+dest_reg); // mov dest_reg,imm + cache_addq(imm); +} -static INLINE void gen_reg_memaddr(HostReg reg,void* data) { - Bit64s diff = (Bit64s)data-((Bit64s)cache.pos+5); + +// This function generates an instruction with register addressing and a memory location +static INLINE void gen_reg_memaddr(HostReg reg,void* data,Bit8u op,Bit8u prefix=0) { + Bit64s diff = (Bit64s)data-((Bit64s)cache.pos+(prefix?7:6)); // if ((diff<0x80000000LL) && (diff>-0x80000000LL)) { //clang messes itself up on this... if ( (diff>>63) == (diff>>31) ) { //signed bit extend, test to see if value fits in a Bit32s + // mov reg,[rip+diff] (or similar, depending on the op) to fetch *data + if(prefix) cache_addb(prefix); + cache_addb(op); cache_addb(0x05+(reg<<3)); // RIP-relative addressing is offset after the instruction cache_addd((Bit32u)(((Bit64u)diff)&0xffffffffLL)); } else if ((Bit64u)data<0x100000000LL) { + // mov reg,[data] (or similar, depending on the op) when absolute address of data is <4GB + if(prefix) cache_addb(prefix); + cache_addb(op); cache_addw(0x2504+(reg<<3)); cache_addd((Bit32u)(((Bit64u)data)&0xffffffffLL)); } else { - E_Exit("DRC64:Unhandled memory reference"); + // load 64-bit data into tmp_reg and do mov reg,[tmp_reg] (or similar, depending on the op) + HostReg tmp_reg = HOST_EAX; + if(reg == HOST_EAX) tmp_reg = HOST_ECX; + + cache_addb(0x50+tmp_reg); // push rax/rcx + gen_mov_reg_qword(tmp_reg,(Bit64u)data); + + if(prefix) cache_addb(prefix); + cache_addb(op); + cache_addb(tmp_reg+(reg<<3)); + + cache_addb(0x58+tmp_reg); // pop rax/rcx } } -static INLINE void gen_memaddr(Bitu op,void* data,Bitu off) { - Bit64s diff; - diff = (Bit64s)data-((Bit64s)cache.pos+off+5); +// Same as above, but with immediate addressing and a memory location +static INLINE void gen_memaddr(Bitu modreg,void* data,Bitu off,Bitu imm,Bit8u op,Bit8u prefix=0) { + Bit64s diff = (Bit64s)data-((Bit64s)cache.pos+off+(prefix?7:6)); // if ((diff<0x80000000LL) && (diff>-0x80000000LL)) { if ( (diff>>63) == (diff>>31) ) { // RIP-relative addressing is offset after the instruction - cache_addb(op+1); - cache_addd((Bit32u)(((Bit64u)diff)&0xffffffffLL)); + if(prefix) cache_addb(prefix); + cache_addw(op+((modreg+1)<<8)); + cache_addd((Bit32u)(((Bit64u)diff)&0xffffffffLL)); + + switch(off) { + case 1: cache_addb(((Bit8u)imm&0xff)); break; + case 2: cache_addw(((Bit16u)imm&0xffff)); break; + case 4: cache_addd(((Bit32u)imm&0xffffffff)); break; + } + } else if ((Bit64u)data<0x100000000LL) { - cache_addb(op); + if(prefix) cache_addb(prefix); + cache_addw(op+(modreg<<8)); cache_addb(0x25); cache_addd((Bit32u)(((Bit64u)data)&0xffffffffLL)); + + switch(off) { + case 1: cache_addb(((Bit8u)imm&0xff)); break; + case 2: cache_addw(((Bit16u)imm&0xffff)); break; + case 4: cache_addd(((Bit32u)imm&0xffffffff)); break; + } + } else { - E_Exit("DRC64:Unhandled memory reference"); + HostReg tmp_reg = HOST_EAX; + + cache_addb(0x50+tmp_reg); // push rax + gen_mov_reg_qword(tmp_reg,(Bit64u)data); + + if(prefix) cache_addb(prefix); + cache_addw(op+((modreg-4+tmp_reg)<<8)); + + switch(off) { + case 1: cache_addb(((Bit8u)imm&0xff)); break; + case 2: cache_addw(((Bit16u)imm&0xffff)); break; + case 4: cache_addd(((Bit32u)imm&0xffffffff)); break; + } + + cache_addb(0x58+tmp_reg); // pop rax } } // move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg // 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { - if (!dword) cache_addb(0x66); - cache_addb(0x8b); // mov reg,[data] - gen_reg_memaddr(dest_reg,data); +static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword,Bit8u prefix=0) { + gen_reg_memaddr(dest_reg,data,0x8b,(dword?prefix:0x66)); // mov reg,[data] } // move a 16bit constant value into dest_reg @@ -138,10 +191,8 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { } // move 32bit (dword==true) or 16bit (dword==false) of a register into memory -static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { - if (!dword) cache_addb(0x66); - cache_addb(0x89); // mov [data],reg - gen_reg_memaddr(src_reg,dest); +static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword,Bit8u prefix=0) { + gen_reg_memaddr(src_reg,dest,0x89,(dword?prefix:0x66)); // mov [data],reg } // move an 8bit value from memory into dest_reg @@ -149,8 +200,7 @@ static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { // this function does not use FC_OP1/FC_OP2 as dest_reg as these // registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { - cache_addb(0x8a); // mov reg,[data] - gen_reg_memaddr(dest_reg,data); + gen_reg_memaddr(dest_reg,data,0x8a); // mov reg, byte [data] } // move an 8bit value from memory into dest_reg @@ -158,9 +208,7 @@ static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { // this function can use FC_OP1/FC_OP2 as dest_reg which are // not directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { - cache_addb(0x66); - cache_addb(0x8b); // mov reg,[data] - gen_reg_memaddr(dest_reg,data); + gen_reg_memaddr(dest_reg,data,0x8b,0x66); // mov reg, word [data] } // move an 8bit constant value into dest_reg @@ -184,8 +232,7 @@ static void gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { // move the lowest 8bit of a register into memory static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { - cache_addb(0x88); // mov [data],reg - gen_reg_memaddr(src_reg,dest); + gen_reg_memaddr(src_reg,dest,0x88); // mov byte [data],reg } @@ -208,8 +255,7 @@ static void gen_extend_word(bool sign,HostReg reg) { // add a 32bit value from memory to a full register static void gen_add(HostReg reg,void* op) { - cache_addb(0x03); // add reg,[data] - gen_reg_memaddr(reg,op); + gen_reg_memaddr(reg,op,0x03); // add reg,[data] } // add a 32bit constant value to a full register @@ -228,31 +274,20 @@ static void gen_and_imm(HostReg reg,Bit32u imm) { // move a 32bit constant value into memory static void gen_mov_direct_dword(void* dest,Bit32u imm) { - cache_addb(0xc7); // mov [data],imm - gen_memaddr(0x04,dest,4); - cache_addd(imm); + gen_memaddr(0x4,dest,4,imm,0xc7); // mov [data],imm } -// move a 64bit constant value into a full register -static void gen_mov_reg_qword(HostReg dest_reg,Bit64u imm) { - cache_addb(0x48); - cache_addb(0xb8+dest_reg); // mov dest_reg,imm - cache_addq(imm); -} // move an address into memory static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { gen_mov_reg_qword(HOST_EAX,imm); - cache_addb(0x48); - gen_mov_word_from_reg(HOST_EAX,dest,true); + gen_mov_word_from_reg(HOST_EAX,dest,true,0x48); // 0x48 prefixes full 64-bit mov } // add an 8bit constant value to a memory value static void gen_add_direct_byte(void* dest,Bit8s imm) { - cache_addb(0x83); // add [data],imm - gen_memaddr(0x4,dest,1); - cache_addb(imm); + gen_memaddr(0x4,dest,1,imm,0x83); // add [data],imm } // add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value @@ -261,22 +296,12 @@ static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { gen_add_direct_byte(dest,(Bit8s)imm); return; } - if (!dword) cache_addb(0x66); - cache_addb(0x81); // add [data],imm - if (dword) { - gen_memaddr(0x4,dest,4); // size of following immediate value - cache_addd((Bit32u)imm); - } else { - gen_memaddr(0x4,dest,2); // size of following immediate value - cache_addw((Bit16u)imm); - } + gen_memaddr(0x4,dest,(dword?4:2),imm,0x81,(dword?0:0x66)); // add [data],imm } // subtract an 8bit constant value from a memory value static void gen_sub_direct_byte(void* dest,Bit8s imm) { - cache_addb(0x83); // sub [data],imm - gen_memaddr(0x2c,dest,1); - cache_addb(imm); + gen_memaddr(0x2c,dest,1,imm,0x83); } // subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value @@ -285,15 +310,7 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { gen_sub_direct_byte(dest,(Bit8s)imm); return; } - if (!dword) cache_addb(0x66); - cache_addw(0x81); // sub [data],imm - if (dword) { - gen_memaddr(0x2c,dest,4); // size of following immediate value - cache_addd((Bit32u)imm); - } else { - gen_memaddr(0x2c,dest,2); // size of following immediate value - cache_addw((Bit16u)imm); - } + gen_memaddr(0x2c,dest,(dword?4:2),imm,0x81,(dword?0:0x66)); // sub [data],imm } @@ -510,12 +527,10 @@ static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { break; #if defined (_MSC_VER) case 2: // mov r8,[mem] - cache_addb(0x49); - gen_mov_word_to_reg(0,(void*)mem,true); + gen_mov_word_to_reg(0,(void*)mem,true,0x49); // 0x49, use x64 rX regs break; case 3: // mov r9,[mem] - cache_addb(0x49); - gen_mov_word_to_reg(1,(void*)mem,true); + gen_mov_word_to_reg(1,(void*)mem,true,0x49); // 0x49, use x64 rX regs break; #else case 2: // mov rdx,[mem] From da7fdf8919f4f57235d6150bb57b23e95d253d20 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 12 Nov 2015 16:51:25 +0000 Subject: [PATCH 3862/4131] Speed up GetHexValue. Restore 1,2,3,4,5 as run 5,500,1000,5000,10000 instructions. It doesn't work flawless, but it is usable as is. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3952 --- src/debug/debug.cpp | 70 ++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index a9816ad5..651de0ae 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -895,38 +895,38 @@ Bit32u GetHexValue(char* str, char*& hex) Bit32u regval = 0; hex = str; while (*hex==' ') hex++; - if (strstr(hex,"EAX")==hex) { hex+=3; regval = reg_eax; }; - if (strstr(hex,"EBX")==hex) { hex+=3; regval = reg_ebx; }; - if (strstr(hex,"ECX")==hex) { hex+=3; regval = reg_ecx; }; - if (strstr(hex,"EDX")==hex) { hex+=3; regval = reg_edx; }; - if (strstr(hex,"ESI")==hex) { hex+=3; regval = reg_esi; }; - if (strstr(hex,"EDI")==hex) { hex+=3; regval = reg_edi; }; - if (strstr(hex,"EBP")==hex) { hex+=3; regval = reg_ebp; }; - if (strstr(hex,"ESP")==hex) { hex+=3; regval = reg_esp; }; - if (strstr(hex,"EIP")==hex) { hex+=3; regval = reg_eip; }; - if (strstr(hex,"AX")==hex) { hex+=2; regval = reg_ax; }; - if (strstr(hex,"BX")==hex) { hex+=2; regval = reg_bx; }; - if (strstr(hex,"CX")==hex) { hex+=2; regval = reg_cx; }; - if (strstr(hex,"DX")==hex) { hex+=2; regval = reg_dx; }; - if (strstr(hex,"SI")==hex) { hex+=2; regval = reg_si; }; - if (strstr(hex,"DI")==hex) { hex+=2; regval = reg_di; }; - if (strstr(hex,"BP")==hex) { hex+=2; regval = reg_bp; }; - if (strstr(hex,"SP")==hex) { hex+=2; regval = reg_sp; }; - if (strstr(hex,"IP")==hex) { hex+=2; regval = reg_ip; }; - if (strstr(hex,"CS")==hex) { hex+=2; regval = SegValue(cs); }; - if (strstr(hex,"DS")==hex) { hex+=2; regval = SegValue(ds); }; - if (strstr(hex,"ES")==hex) { hex+=2; regval = SegValue(es); }; - if (strstr(hex,"FS")==hex) { hex+=2; regval = SegValue(fs); }; - if (strstr(hex,"GS")==hex) { hex+=2; regval = SegValue(gs); }; + if (strstr(hex,"EAX")==hex) { hex+=3; regval = reg_eax; } else + if (strstr(hex,"EBX")==hex) { hex+=3; regval = reg_ebx; } else + if (strstr(hex,"ECX")==hex) { hex+=3; regval = reg_ecx; } else + if (strstr(hex,"EDX")==hex) { hex+=3; regval = reg_edx; } else + if (strstr(hex,"ESI")==hex) { hex+=3; regval = reg_esi; } else + if (strstr(hex,"EDI")==hex) { hex+=3; regval = reg_edi; } else + if (strstr(hex,"EBP")==hex) { hex+=3; regval = reg_ebp; } else + if (strstr(hex,"ESP")==hex) { hex+=3; regval = reg_esp; } else + if (strstr(hex,"EIP")==hex) { hex+=3; regval = reg_eip; } else + if (strstr(hex,"AX")==hex) { hex+=2; regval = reg_ax; } else + if (strstr(hex,"BX")==hex) { hex+=2; regval = reg_bx; } else + if (strstr(hex,"CX")==hex) { hex+=2; regval = reg_cx; } else + if (strstr(hex,"DX")==hex) { hex+=2; regval = reg_dx; } else + if (strstr(hex,"SI")==hex) { hex+=2; regval = reg_si; } else + if (strstr(hex,"DI")==hex) { hex+=2; regval = reg_di; } else + if (strstr(hex,"BP")==hex) { hex+=2; regval = reg_bp; } else + if (strstr(hex,"SP")==hex) { hex+=2; regval = reg_sp; } else + if (strstr(hex,"IP")==hex) { hex+=2; regval = reg_ip; } else + if (strstr(hex,"CS")==hex) { hex+=2; regval = SegValue(cs); } else + if (strstr(hex,"DS")==hex) { hex+=2; regval = SegValue(ds); } else + if (strstr(hex,"ES")==hex) { hex+=2; regval = SegValue(es); } else + if (strstr(hex,"FS")==hex) { hex+=2; regval = SegValue(fs); } else + if (strstr(hex,"GS")==hex) { hex+=2; regval = SegValue(gs); } else if (strstr(hex,"SS")==hex) { hex+=2; regval = SegValue(ss); }; while (*hex) { if ((*hex>='0') && (*hex<='9')) value = (value<<4)+*hex-'0'; else if ((*hex>='A') && (*hex<='F')) value = (value<<4)+*hex-'A'+10; else { - if(*hex == '+') {hex++;return regval + value + GetHexValue(hex,hex); }; - if(*hex == '-') {hex++;return regval + value - GetHexValue(hex,hex); }; - break; // No valid char + if (*hex == '+') {hex++;return regval + value + GetHexValue(hex,hex); } else + if (*hex == '-') {hex++;return regval + value - GetHexValue(hex,hex); } + else break; // No valid char } hex++; }; @@ -1534,8 +1534,23 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) { Bit32u DEBUG_CheckKeys(void) { Bits ret=0; + bool numberrun = false; int key=getch(); - if (key>0) { + + if (key >='1' && key <='5' && strlen(codeViewData.inputStr) == 0) { + const Bit32s v[] ={5,500,1000,5000,10000}; + CPU_Cycles= v[key - '1']; + + ret = (*cpudecoder)(); + SetCodeWinStart(); + CBreakpoint::ignoreOnce = 0; + + /* Setup variables so we end up at the proper ret processing */ + numberrun = true; + key = -1; + } + + if (key>0 || numberrun) { #if defined(WIN32) && defined(__PDCURSES__) switch (key) { case PADENTER: key=0x0A; break; @@ -2481,6 +2496,7 @@ bool DEBUG_HeavyIsBreakpoint(void) { cpuLogCounter--; } if (cpuLogCounter<=0) { + cpuLogFile.flush(); cpuLogFile.close(); DEBUG_ShowMsg("DEBUG: cpu log LOGCPU.TXT created\n"); cpuLog = false; From 966c3763025ef8a0e1c2addfd1b5bab53d1fbdcd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 12 Nov 2015 17:40:11 +0000 Subject: [PATCH 3863/4131] strstr is a bit too much. Pretty it up! Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3953 --- src/debug/debug.cpp | 118 ++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 651de0ae..b66d7c1e 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -894,35 +894,35 @@ Bit32u GetHexValue(char* str, char*& hex) Bit32u value = 0; Bit32u regval = 0; hex = str; - while (*hex==' ') hex++; - if (strstr(hex,"EAX")==hex) { hex+=3; regval = reg_eax; } else - if (strstr(hex,"EBX")==hex) { hex+=3; regval = reg_ebx; } else - if (strstr(hex,"ECX")==hex) { hex+=3; regval = reg_ecx; } else - if (strstr(hex,"EDX")==hex) { hex+=3; regval = reg_edx; } else - if (strstr(hex,"ESI")==hex) { hex+=3; regval = reg_esi; } else - if (strstr(hex,"EDI")==hex) { hex+=3; regval = reg_edi; } else - if (strstr(hex,"EBP")==hex) { hex+=3; regval = reg_ebp; } else - if (strstr(hex,"ESP")==hex) { hex+=3; regval = reg_esp; } else - if (strstr(hex,"EIP")==hex) { hex+=3; regval = reg_eip; } else - if (strstr(hex,"AX")==hex) { hex+=2; regval = reg_ax; } else - if (strstr(hex,"BX")==hex) { hex+=2; regval = reg_bx; } else - if (strstr(hex,"CX")==hex) { hex+=2; regval = reg_cx; } else - if (strstr(hex,"DX")==hex) { hex+=2; regval = reg_dx; } else - if (strstr(hex,"SI")==hex) { hex+=2; regval = reg_si; } else - if (strstr(hex,"DI")==hex) { hex+=2; regval = reg_di; } else - if (strstr(hex,"BP")==hex) { hex+=2; regval = reg_bp; } else - if (strstr(hex,"SP")==hex) { hex+=2; regval = reg_sp; } else - if (strstr(hex,"IP")==hex) { hex+=2; regval = reg_ip; } else - if (strstr(hex,"CS")==hex) { hex+=2; regval = SegValue(cs); } else - if (strstr(hex,"DS")==hex) { hex+=2; regval = SegValue(ds); } else - if (strstr(hex,"ES")==hex) { hex+=2; regval = SegValue(es); } else - if (strstr(hex,"FS")==hex) { hex+=2; regval = SegValue(fs); } else - if (strstr(hex,"GS")==hex) { hex+=2; regval = SegValue(gs); } else - if (strstr(hex,"SS")==hex) { hex+=2; regval = SegValue(ss); }; + while (*hex == ' ') hex++; + if (strncmp(hex,"EAX",3) == 0) { hex+=3; regval = reg_eax; } else + if (strncmp(hex,"EBX",3) == 0) { hex+=3; regval = reg_ebx; } else + if (strncmp(hex,"ECX",3) == 0) { hex+=3; regval = reg_ecx; } else + if (strncmp(hex,"EDX",3) == 0) { hex+=3; regval = reg_edx; } else + if (strncmp(hex,"ESI",3) == 0) { hex+=3; regval = reg_esi; } else + if (strncmp(hex,"EDI",3) == 0) { hex+=3; regval = reg_edi; } else + if (strncmp(hex,"EBP",3) == 0) { hex+=3; regval = reg_ebp; } else + if (strncmp(hex,"ESP",3) == 0) { hex+=3; regval = reg_esp; } else + if (strncmp(hex,"EIP",3) == 0) { hex+=3; regval = reg_eip; } else + if (strncmp(hex,"AX",2) == 0) { hex+=2; regval = reg_ax; } else + if (strncmp(hex,"BX",2) == 0) { hex+=2; regval = reg_bx; } else + if (strncmp(hex,"CX",2) == 0) { hex+=2; regval = reg_cx; } else + if (strncmp(hex,"DX",2) == 0) { hex+=2; regval = reg_dx; } else + if (strncmp(hex,"SI",2) == 0) { hex+=2; regval = reg_si; } else + if (strncmp(hex,"DI",2) == 0) { hex+=2; regval = reg_di; } else + if (strncmp(hex,"BP",2) == 0) { hex+=2; regval = reg_bp; } else + if (strncmp(hex,"SP",2) == 0) { hex+=2; regval = reg_sp; } else + if (strncmp(hex,"IP",2) == 0) { hex+=2; regval = reg_ip; } else + if (strncmp(hex,"CS",2) == 0) { hex+=2; regval = SegValue(cs); } else + if (strncmp(hex,"DS",2) == 0) { hex+=2; regval = SegValue(ds); } else + if (strncmp(hex,"ES",2) == 0) { hex+=2; regval = SegValue(es); } else + if (strncmp(hex,"FS",2) == 0) { hex+=2; regval = SegValue(fs); } else + if (strncmp(hex,"GS",2) == 0) { hex+=2; regval = SegValue(gs); } else + if (strncmp(hex,"SS",2) == 0) { hex+=2; regval = SegValue(ss); }; while (*hex) { - if ((*hex>='0') && (*hex<='9')) value = (value<<4)+*hex-'0'; - else if ((*hex>='A') && (*hex<='F')) value = (value<<4)+*hex-'A'+10; + if ((*hex >= '0') && (*hex <= '9')) value = (value<<4) + *hex - '0'; + else if ((*hex >= 'A') && (*hex <= 'F')) value = (value<<4) + *hex - 'A' + 10; else { if (*hex == '+') {hex++;return regval + value + GetHexValue(hex,hex); } else if (*hex == '-') {hex++;return regval + value - GetHexValue(hex,hex); } @@ -937,38 +937,38 @@ bool ChangeRegister(char* str) { char* hex = str; while (*hex==' ') hex++; - if (strstr(hex,"EAX")==hex) { hex+=3; reg_eax = GetHexValue(hex,hex); } else - if (strstr(hex,"EBX")==hex) { hex+=3; reg_ebx = GetHexValue(hex,hex); } else - if (strstr(hex,"ECX")==hex) { hex+=3; reg_ecx = GetHexValue(hex,hex); } else - if (strstr(hex,"EDX")==hex) { hex+=3; reg_edx = GetHexValue(hex,hex); } else - if (strstr(hex,"ESI")==hex) { hex+=3; reg_esi = GetHexValue(hex,hex); } else - if (strstr(hex,"EDI")==hex) { hex+=3; reg_edi = GetHexValue(hex,hex); } else - if (strstr(hex,"EBP")==hex) { hex+=3; reg_ebp = GetHexValue(hex,hex); } else - if (strstr(hex,"ESP")==hex) { hex+=3; reg_esp = GetHexValue(hex,hex); } else - if (strstr(hex,"EIP")==hex) { hex+=3; reg_eip = GetHexValue(hex,hex); } else - if (strstr(hex,"AX")==hex) { hex+=2; reg_ax = (Bit16u)GetHexValue(hex,hex); } else - if (strstr(hex,"BX")==hex) { hex+=2; reg_bx = (Bit16u)GetHexValue(hex,hex); } else - if (strstr(hex,"CX")==hex) { hex+=2; reg_cx = (Bit16u)GetHexValue(hex,hex); } else - if (strstr(hex,"DX")==hex) { hex+=2; reg_dx = (Bit16u)GetHexValue(hex,hex); } else - if (strstr(hex,"SI")==hex) { hex+=2; reg_si = (Bit16u)GetHexValue(hex,hex); } else - if (strstr(hex,"DI")==hex) { hex+=2; reg_di = (Bit16u)GetHexValue(hex,hex); } else - if (strstr(hex,"BP")==hex) { hex+=2; reg_bp = (Bit16u)GetHexValue(hex,hex); } else - if (strstr(hex,"SP")==hex) { hex+=2; reg_sp = (Bit16u)GetHexValue(hex,hex); } else - if (strstr(hex,"IP")==hex) { hex+=2; reg_ip = (Bit16u)GetHexValue(hex,hex); } else - if (strstr(hex,"CS")==hex) { hex+=2; SegSet16(cs,(Bit16u)GetHexValue(hex,hex)); } else - if (strstr(hex,"DS")==hex) { hex+=2; SegSet16(ds,(Bit16u)GetHexValue(hex,hex)); } else - if (strstr(hex,"ES")==hex) { hex+=2; SegSet16(es,(Bit16u)GetHexValue(hex,hex)); } else - if (strstr(hex,"FS")==hex) { hex+=2; SegSet16(fs,(Bit16u)GetHexValue(hex,hex)); } else - if (strstr(hex,"GS")==hex) { hex+=2; SegSet16(gs,(Bit16u)GetHexValue(hex,hex)); } else - if (strstr(hex,"SS")==hex) { hex+=2; SegSet16(ss,(Bit16u)GetHexValue(hex,hex)); } else - if (strstr(hex,"AF")==hex) { hex+=2; SETFLAGBIT(AF,GetHexValue(hex,hex)); } else - if (strstr(hex,"CF")==hex) { hex+=2; SETFLAGBIT(CF,GetHexValue(hex,hex)); } else - if (strstr(hex,"DF")==hex) { hex+=2; SETFLAGBIT(DF,GetHexValue(hex,hex)); } else - if (strstr(hex,"IF")==hex) { hex+=2; SETFLAGBIT(IF,GetHexValue(hex,hex)); } else - if (strstr(hex,"OF")==hex) { hex+=2; SETFLAGBIT(OF,GetHexValue(hex,hex)); } else - if (strstr(hex,"ZF")==hex) { hex+=2; SETFLAGBIT(ZF,GetHexValue(hex,hex)); } else - if (strstr(hex,"PF")==hex) { hex+=2; SETFLAGBIT(PF,GetHexValue(hex,hex)); } else - if (strstr(hex,"SF")==hex) { hex+=2; SETFLAGBIT(SF,GetHexValue(hex,hex)); } else + if (strncmp(hex,"EAX",3) == 0) { hex+=3; reg_eax = GetHexValue(hex,hex); } else + if (strncmp(hex,"EBX",3) == 0) { hex+=3; reg_ebx = GetHexValue(hex,hex); } else + if (strncmp(hex,"ECX",3) == 0) { hex+=3; reg_ecx = GetHexValue(hex,hex); } else + if (strncmp(hex,"EDX",3) == 0) { hex+=3; reg_edx = GetHexValue(hex,hex); } else + if (strncmp(hex,"ESI",3) == 0) { hex+=3; reg_esi = GetHexValue(hex,hex); } else + if (strncmp(hex,"EDI",3) == 0) { hex+=3; reg_edi = GetHexValue(hex,hex); } else + if (strncmp(hex,"EBP",3) == 0) { hex+=3; reg_ebp = GetHexValue(hex,hex); } else + if (strncmp(hex,"ESP",3) == 0) { hex+=3; reg_esp = GetHexValue(hex,hex); } else + if (strncmp(hex,"EIP",3) == 0) { hex+=3; reg_eip = GetHexValue(hex,hex); } else + if (strncmp(hex,"AX",2) == 0) { hex+=2; reg_ax = (Bit16u)GetHexValue(hex,hex); } else + if (strncmp(hex,"BX",2) == 0) { hex+=2; reg_bx = (Bit16u)GetHexValue(hex,hex); } else + if (strncmp(hex,"CX",2) == 0) { hex+=2; reg_cx = (Bit16u)GetHexValue(hex,hex); } else + if (strncmp(hex,"DX",2) == 0) { hex+=2; reg_dx = (Bit16u)GetHexValue(hex,hex); } else + if (strncmp(hex,"SI",2) == 0) { hex+=2; reg_si = (Bit16u)GetHexValue(hex,hex); } else + if (strncmp(hex,"DI",2) == 0) { hex+=2; reg_di = (Bit16u)GetHexValue(hex,hex); } else + if (strncmp(hex,"BP",2) == 0) { hex+=2; reg_bp = (Bit16u)GetHexValue(hex,hex); } else + if (strncmp(hex,"SP",2) == 0) { hex+=2; reg_sp = (Bit16u)GetHexValue(hex,hex); } else + if (strncmp(hex,"IP",2) == 0) { hex+=2; reg_ip = (Bit16u)GetHexValue(hex,hex); } else + if (strncmp(hex,"CS",2) == 0) { hex+=2; SegSet16(cs,(Bit16u)GetHexValue(hex,hex)); } else + if (strncmp(hex,"DS",2) == 0) { hex+=2; SegSet16(ds,(Bit16u)GetHexValue(hex,hex)); } else + if (strncmp(hex,"ES",2) == 0) { hex+=2; SegSet16(es,(Bit16u)GetHexValue(hex,hex)); } else + if (strncmp(hex,"FS",2) == 0) { hex+=2; SegSet16(fs,(Bit16u)GetHexValue(hex,hex)); } else + if (strncmp(hex,"GS",2) == 0) { hex+=2; SegSet16(gs,(Bit16u)GetHexValue(hex,hex)); } else + if (strncmp(hex,"SS",2) == 0) { hex+=2; SegSet16(ss,(Bit16u)GetHexValue(hex,hex)); } else + if (strncmp(hex,"AF",2) == 0) { hex+=2; SETFLAGBIT(AF,GetHexValue(hex,hex)); } else + if (strncmp(hex,"CF",2) == 0) { hex+=2; SETFLAGBIT(CF,GetHexValue(hex,hex)); } else + if (strncmp(hex,"DF",2) == 0) { hex+=2; SETFLAGBIT(DF,GetHexValue(hex,hex)); } else + if (strncmp(hex,"IF",2) == 0) { hex+=2; SETFLAGBIT(IF,GetHexValue(hex,hex)); } else + if (strncmp(hex,"OF",2) == 0) { hex+=2; SETFLAGBIT(OF,GetHexValue(hex,hex)); } else + if (strncmp(hex,"ZF",2) == 0) { hex+=2; SETFLAGBIT(ZF,GetHexValue(hex,hex)); } else + if (strncmp(hex,"PF",2) == 0) { hex+=2; SETFLAGBIT(PF,GetHexValue(hex,hex)); } else + if (strncmp(hex,"SF",2) == 0) { hex+=2; SETFLAGBIT(SF,GetHexValue(hex,hex)); } else { return false; }; return true; }; From bfd180f5ae2c1a1752dcf9b97b4f93636bce16dd Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sat, 14 Nov 2015 13:42:16 +0000 Subject: [PATCH 3864/4131] Change BIOS equipment list to indicate DMA not supported on PCjr machine type, which fixes PCjr detection in old versions of Ancient Art of War, although DMA hardware emulation is actually still present. Set PC speaker initial state in BIOS init, fixing beeps when the speaker is turned on and off without first programming the timer, such as in Koei's Ghengis Khan. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3954 --- src/ints/bios.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 47f02987..c2b087ae 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1248,10 +1248,16 @@ public: } // PS2 mouse config |= 0x04; + // DMA *not* supported - Ancient Art of War CGA uses this to identify PCjr + if (machine==MCH_PCJR) config |= 0x100; // Gameport config |= 0x1000; mem_writew(BIOS_CONFIGURATION,config); CMOS_SetRegister(0x14,(Bit8u)(config&0xff)); //Should be updated on changes + /* Setup PC speaker initial state - real BIOS does this for POST beeps */ + IO_Write(0x43,0xb6); // PIT 2 mode 3 + IO_Write(0x42,0x28); // counter 1320 + IO_Write(0x42,0x05); /* Setup extended memory size */ IO_Write(0x70,0x30); size_extended=IO_Read(0x71); From dc4aabb403ec0b27f135a2221e7804aadeec04bc Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Mon, 21 Dec 2015 17:14:42 +0000 Subject: [PATCH 3865/4131] Correct some offsets in the DTA for FCB-based search results. Fixes DIR listing in COMMAND.COM from MS-DOS and file info in XTree Gold. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3955 --- include/dos_inc.h | 2 +- src/dos/dos_classes.cpp | 7 +++++-- src/dos/dos_files.cpp | 3 +-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 070bb3b2..1919684a 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -507,7 +507,7 @@ public: bool Extended(void); void GetAttr(Bit8u & attr); void SetAttr(Bit8u attr); - void SetResultAttr(Bit8u attr); + void SetResult(Bit32u size,Bit16u date,Bit16u time,Bit8u attr); bool Valid(void); void ClearBlockRecsize(void); private: diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 27658b42..ac2d622d 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -498,8 +498,11 @@ void DOS_FCB::SetAttr(Bit8u attr) { if(extended) mem_writeb(pt - 1,attr); } -void DOS_FCB::SetResultAttr(Bit8u attr) { - mem_writeb(pt + 12,attr); +void DOS_FCB::SetResult(Bit32u size,Bit16u date,Bit16u time,Bit8u attr) { + mem_writed(pt + 0x1d,size); + mem_writew(pt + 0x19,date); + mem_writew(pt + 0x17,time); + mem_writeb(pt + 0x0c,attr); } void DOS_SDA::Init() { diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 3cdac4bf..614cdb90 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -949,8 +949,7 @@ static void SaveFindResult(DOS_FCB & find_fcb) { fcb.Create(find_fcb.Extended()); fcb.SetName(drive,file_name,ext); fcb.SetAttr(find_attr); /* Only adds attribute if fcb is extended */ - fcb.SetResultAttr(attr); - fcb.SetSizeDateTime(size,date,time); + fcb.SetResult(size,date,time,attr); } bool DOS_FCBCreate(Bit16u seg,Bit16u offset) { From 0d868c990f75686dd4203726b1a43339f4ba4b32 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 30 Jan 2016 16:09:04 +0000 Subject: [PATCH 3866/4131] Prevent a multiplication overflow and more accuracy by using floats for attack rate loop Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3956 --- src/hardware/dbopl.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index eda3ca6e..dee31958 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -1237,6 +1237,7 @@ void Chip::Setup( Bit32u rate ) { EnvelopeSelect( i, index, shift ); linearRates[i] = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH + ENV_EXTRA - shift - 3 ))); } + Bit32s attackDiffs[62]; //Generate the best matching attack rate for ( Bit8u i = 0; i < 62; i++ ) { Bit8u index, shift; @@ -1267,22 +1268,23 @@ void Chip::Setup( Bit32u rate ) { if ( lDiff < bestDiff ) { bestDiff = lDiff; bestAdd = guessAdd; + //We hit an exactly matching sample count if ( !bestDiff ) break; } + //Linear correction factor, not exactly perfect but seems to work + double correct = (original - diff) / (double)original; + guessAdd = (Bit32u)(guessAdd * correct); //Below our target if ( diff < 0 ) { - //Better than the last time - Bit32s mul = ((original - diff) << 12) / original; - guessAdd = ((guessAdd * mul) >> 12); + //Always add one here for rounding, an overshoot will get corrected by another pass decreasing guessAdd++; } else if ( diff > 0 ) { - Bit32s mul = ((original - diff) << 12) / original; - guessAdd = (guessAdd * mul) >> 12; - guessAdd--; } } attackRates[i] = bestAdd; + //Keep track of the diffs for some debugging + attackDiffs[i] = bestDiff; } for ( Bit8u i = 62; i < 76; i++ ) { //This should provide instant volume maximizing From 19264794cb011a77a1e81999c7df13c4841e397d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 30 Jan 2016 16:39:35 +0000 Subject: [PATCH 3867/4131] minor cleanup Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3957 --- src/hardware/dbopl.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index dee31958..4ec4aaed 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -1237,7 +1237,7 @@ void Chip::Setup( Bit32u rate ) { EnvelopeSelect( i, index, shift ); linearRates[i] = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH + ENV_EXTRA - shift - 3 ))); } - Bit32s attackDiffs[62]; +// Bit32s attackDiffs[62]; //Generate the best matching attack rate for ( Bit8u i = 0; i < 62; i++ ) { Bit8u index, shift; @@ -1279,12 +1279,11 @@ void Chip::Setup( Bit32u rate ) { if ( diff < 0 ) { //Always add one here for rounding, an overshoot will get corrected by another pass decreasing guessAdd++; - } else if ( diff > 0 ) { } } attackRates[i] = bestAdd; //Keep track of the diffs for some debugging - attackDiffs[i] = bestDiff; +// attackDiffs[i] = bestDiff; } for ( Bit8u i = 62; i < 76; i++ ) { //This should provide instant volume maximizing From 81e4f773f544ecc9660fafd51bb5b4783720fb6a Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Fri, 5 Feb 2016 13:26:23 +0000 Subject: [PATCH 3868/4131] Comment out unused counter var inside a busy loop. Compilers might be smart enough to drop it, but this way is certain. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3958 --- src/hardware/dbopl.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index 4ec4aaed..44b8a34e 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -1177,9 +1177,9 @@ void Chip::GenerateBlock2( Bitu total, Bit32s* output ) { while ( total > 0 ) { Bit32u samples = ForwardLFO( total ); memset(output, 0, sizeof(Bit32s) * samples); - int count = 0; +// int count = 0; for( Channel* ch = chan; ch < chan + 9; ) { - count++; +// count++; ch = (ch->*(ch->synthHandler))( this, samples, output ); } total -= samples; @@ -1191,9 +1191,9 @@ void Chip::GenerateBlock3( Bitu total, Bit32s* output ) { while ( total > 0 ) { Bit32u samples = ForwardLFO( total ); memset(output, 0, sizeof(Bit32s) * samples *2); - int count = 0; +// int count = 0; for( Channel* ch = chan; ch < chan + 18; ) { - count++; +// count++; ch = (ch->*(ch->synthHandler))( this, samples, output ); } total -= samples; From fe46abe6ff042dc45aba4c8d4c12c7ecfb217552 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Fri, 5 Feb 2016 13:29:17 +0000 Subject: [PATCH 3869/4131] Speaker init in BIOS causes samples to be generated at startup, so for now move it to hardware. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3959 --- src/hardware/pcspeaker.cpp | 3 ++- src/ints/bios.cpp | 4 ---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 2f22d35a..d426a66c 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -332,7 +332,8 @@ public: spkr.last_ticks=0; spkr.last_index=0; spkr.rate=section->Get_int("pcrate"); - spkr.pit_max=(1000.0f/PIT_TICK_RATE)*65535; + spkr.pit_mode=3; + spkr.pit_max=(1000.0f/PIT_TICK_RATE)*1320; spkr.pit_half=spkr.pit_max/2; spkr.pit_new_max=spkr.pit_max; spkr.pit_new_half=spkr.pit_half; diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index c2b087ae..77e92ae9 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1254,10 +1254,6 @@ public: config |= 0x1000; mem_writew(BIOS_CONFIGURATION,config); CMOS_SetRegister(0x14,(Bit8u)(config&0xff)); //Should be updated on changes - /* Setup PC speaker initial state - real BIOS does this for POST beeps */ - IO_Write(0x43,0xb6); // PIT 2 mode 3 - IO_Write(0x42,0x28); // counter 1320 - IO_Write(0x42,0x05); /* Setup extended memory size */ IO_Write(0x70,0x30); size_extended=IO_Read(0x71); From 18f5c4c5652ebcda38aadd11030a7981fc10fbf9 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Fri, 5 Feb 2016 13:32:48 +0000 Subject: [PATCH 3870/4131] Stop speaker output after command write, pending counter write. The hacky implementation will serve until timer/speaker is improved. Fixes constant speaker tone in Arnie 2 and Chopper Duel when using SB sound, also Titus The Fox title screen when using speaker sound. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3960 --- src/hardware/timer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index eacd5769..454324ad 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -345,6 +345,8 @@ static void write_p43(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { } else { PIC_DeActivateIRQ(0); } + } else if (latch == 2) { + PCSPEAKER_SetCounter(0,3); } pit[latch].new_mode = true; } From 26dd1635b5ab4f479e2f526e4bfeda6c4dd97bf5 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Fri, 5 Feb 2016 13:41:22 +0000 Subject: [PATCH 3871/4131] Add support for Print Screen key and interrupt. The keypress allows Descent 1 and 2 ingame screenshot feature to be used, the keypress and interrupt allow the Horror Hotel (TSR text adventure) hotkey to work, and the compatible interrupt handler location fixes a game bug in The Forgotten Land. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3961 --- include/bios.h | 1 + src/cpu/callback.cpp | 10 +++++++++- src/hardware/keyboard.cpp | 5 ++++- src/ints/bios.cpp | 5 +++++ src/ints/bios_keyboard.cpp | 20 ++++++++++++++++++++ 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/include/bios.h b/include/bios.h index 213c73d6..4915a52a 100644 --- a/include/bios.h +++ b/include/bios.h @@ -103,6 +103,7 @@ #define BIOS_DEFAULT_HANDLER_LOCATION (RealMake(0xf000,0xff53)) +#define BIOS_DEFAULT_INT5_LOCATION (RealMake(0xf000,0xff54)) #define BIOS_DEFAULT_IRQ0_LOCATION (RealMake(0xf000,0xfea5)) #define BIOS_DEFAULT_IRQ1_LOCATION (RealMake(0xf000,0xe987)) #define BIOS_DEFAULT_IRQ2_LOCATION (RealMake(0xf000,0xff55)) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 716608aa..609db80b 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -256,7 +256,15 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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); + phys_writeb(physAddress+0x0f,(Bit8u)0xfa); // cli + phys_writew(physAddress+0x10,(Bit16u)0x20b0); // mov al, 0x20 + phys_writew(physAddress+0x12,(Bit16u)0x20e6); // out 0x20, al + phys_writeb(physAddress+0x14,(Bit8u)0x55); // push bp + phys_writew(physAddress+0x15,(Bit16u)0x05cd); // int 5 + phys_writeb(physAddress+0x17,(Bit8u)0x5d); // pop bp + phys_writeb(physAddress+0x18,(Bit8u)0x58); // pop ax + phys_writeb(physAddress+0x19,(Bit8u)0xcf); //An IRET Instruction + return (use_cb?0x20:0x1a); case CB_IRQ9: // pic cascade interrupt if (use_cb) { phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4 diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index f3ef7e53..f85f5ab4 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -339,7 +339,10 @@ void KEYBOARD_AddKey(KBD_KEYS keytype,bool pressed) { KEYBOARD_AddBuffer(69|(pressed?0:0x80)); return; case KBD_printscreen: - /* Not handled yet. But usuable in mapper for special events */ + KEYBOARD_AddBuffer(0xe0); + KEYBOARD_AddBuffer(42|(pressed?0:0x80)); + KEYBOARD_AddBuffer(0xe0); + KEYBOARD_AddBuffer(55|(pressed?0:0x80)); return; default: E_Exit("Unsupported key press"); diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 77e92ae9..34679eb3 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1102,6 +1102,11 @@ public: CALLBACK_Setup(call_irq2,NULL,CB_IRET_EOI_PIC1,Real2Phys(BIOS_DEFAULT_IRQ2_LOCATION),"irq 2 bios"); RealSetVec(0x0a,BIOS_DEFAULT_IRQ2_LOCATION); + // INT 05h: Print Screen + // IRQ1 handler calls it when PrtSc key is pressed; does nothing unless hooked + phys_writeb(Real2Phys(BIOS_DEFAULT_INT5_LOCATION),0xcf); + RealSetVec(0x05,BIOS_DEFAULT_INT5_LOCATION); + /* Some hardcoded vectors */ phys_writeb(Real2Phys(BIOS_DEFAULT_HANDLER_LOCATION),0xcf); /* bios default interrupt vector location -> IRET */ phys_writew(Real2Phys(RealGetVec(0x12))+0x12,0x20); //Hack for Jurresic diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 8590b43a..7628a22a 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -284,6 +284,13 @@ static Bitu IRQ1_Handler(void) { case 0xb6: /* Right Shift Released */ flags1 &=~0x01; break; + case 0x37: /* Keypad * or PrtSc Pressed */ + if (!(flags3 &0x02)) goto normal_key; + reg_ip+=7; // call int 5 + break; + case 0xb7: /* Keypad * or PrtSc Released */ + if (!(flags3 &0x02)) goto normal_key; + break; case 0x38: /* Alt Pressed */ flags1 |=0x08; if (flags3 &0x02) flags3 |=0x08; @@ -399,6 +406,7 @@ static Bitu IRQ1_Handler(void) { break; default: /* Normal Key */ +normal_key: Bit16u asciiscan; /* Now Handle the releasing of keys and see if they match up for a code */ /* Handle the actual scancode */ @@ -638,6 +646,14 @@ void BIOS_SetupKeyboard(void) { // out 0x20, al // pop ax // iret + // cli + // mov al, 0x20 + // out 0x20, al + // push bp + // int 0x05 + // pop bp + // pop ax + // iret if (machine==MCH_PCJR) { call_irq6=CALLBACK_Allocate(); @@ -648,7 +664,11 @@ void BIOS_SetupKeyboard(void) { // in al, 0x60 // cmp al, 0xe0 // je skip + // push ds + // push 0x40 + // pop ds // int 0x09 + // pop ds // label skip: // cli // mov al, 0x20 From 59805112d9320d69ba85d2b75f8941e0782c4477 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 9 Feb 2016 14:12:05 +0000 Subject: [PATCH 3872/4131] Use record size of 128 if it is 0 in the FCB when calling INT 21 AH=23 (fixes bug #433). Set record size to 128 if it is 0 in the FCB when calling any FCB read/write function (ripsaw). Fixes for acad 10: - Add missing reference counting when the file is already open when calling FCB_Open, so that acad which uses FCBs and normal handles on the same file works better. - Remove FCBs being added to the PSP filetable and rewrite most functions to support this change. This way acad won't run out of temporary (fcb) files when low on memory. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3962 --- include/dos_inc.h | 15 +++--- src/dos/dos_classes.cpp | 13 +++-- src/dos/dos_files.cpp | 104 +++++++++++++++++++++------------------- 3 files changed, 72 insertions(+), 60 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 1919684a..a3729e26 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -110,19 +110,19 @@ enum { HAND_NONE=0,HAND_FILE,HAND_DEVICE}; /* Routines for File Class */ void DOS_SetupFiles (void); -bool DOS_ReadFile(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_CloseFile(Bit16u handle); +bool DOS_ReadFile(Bit16u handle,Bit8u * data,Bit16u * amount, bool fcb = false); +bool DOS_WriteFile(Bit16u handle,Bit8u * data,Bit16u * amount,bool fcb = false); +bool DOS_SeekFile(Bit16u handle,Bit32u * pos,Bit32u type,bool fcb = false); +bool DOS_CloseFile(Bit16u handle,bool fcb = false); bool DOS_FlushFile(Bit16u handle); 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 */ -bool DOS_OpenFile(char const * name,Bit8u flags,Bit16u * entry); +bool DOS_OpenFile(char const * name,Bit8u flags,Bit16u * entry,bool fcb = false); bool DOS_OpenFileExtended(char const * name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status); -bool DOS_CreateFile(char const * name,Bit16u attribute,Bit16u * entry); +bool DOS_CreateFile(char const * name,Bit16u attribute,Bit16u * entry, bool fcb = false); bool DOS_UnlinkFile(char const * const name); bool DOS_FindFirst(char *search,Bit16u attr,bool fcb_findfirst=false); bool DOS_FindNext(void); @@ -501,6 +501,7 @@ public: void GetRecord(Bit16u & _cur_block,Bit8u & _cur_rec); void SetRecord(Bit16u _cur_block,Bit8u _cur_rec); void GetSeqData(Bit8u & _fhandle,Bit16u & _rec_size); + void SetSeqData(Bit8u _fhandle,Bit16u _rec_size); void GetRandom(Bit32u & _random); void SetRandom(Bit32u _random); Bit8u GetDrive(void); @@ -529,6 +530,8 @@ private: Bit8u sft_entries; Bit8u share_attributes; Bit8u extra_info; + /* Maybe swap file_handle and sft_entries now that fcbs + * aren't stored in the psp filetable anymore */ Bit8u file_handle; Bit8u reserved[4]; /* end */ diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index ac2d622d..5f59e839 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -435,6 +435,10 @@ void DOS_FCB::GetSeqData(Bit8u & _fhandle,Bit16u & _rec_size) { _rec_size=(Bit16u)sGet(sFCB,rec_size); } +void DOS_FCB::SetSeqData(Bit8u _fhandle,Bit16u _rec_size) { + sSave(sFCB,file_handle,_fhandle); + sSave(sFCB,rec_size,_rec_size); +} void DOS_FCB::GetRandom(Bit32u & _random) { _random=sGet(sFCB,rndm); @@ -454,14 +458,13 @@ void DOS_FCB::FileOpen(Bit8u _fhandle) { sSave(sFCB,cur_block,0); sSave(sFCB,rec_size,128); // sSave(sFCB,rndm,0); // breaks Jewels of darkness. - Bit8u temp = RealHandle(_fhandle); Bit32u size = 0; - Files[temp]->Seek(&size,DOS_SEEK_END); + Files[_fhandle]->Seek(&size,DOS_SEEK_END); sSave(sFCB,filesize,size); size = 0; - Files[temp]->Seek(&size,DOS_SEEK_SET); - sSave(sFCB,time,Files[temp]->time); - sSave(sFCB,date,Files[temp]->date); + Files[_fhandle]->Seek(&size,DOS_SEEK_SET); + sSave(sFCB,time,Files[_fhandle]->time); + sSave(sFCB,date,Files[_fhandle]->date); } bool DOS_FCB::Valid() { diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 614cdb90..38853bf0 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -365,8 +365,8 @@ bool DOS_FindNext(void) { } -bool DOS_ReadFile(Bit16u entry,Bit8u * data,Bit16u * amount) { - Bit32u handle=RealHandle(entry); +bool DOS_ReadFile(Bit16u entry,Bit8u * data,Bit16u * amount,bool fcb) { + Bit32u handle = fcb?entry:RealHandle(entry); if (handle>=DOS_FILES) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; @@ -387,8 +387,8 @@ bool DOS_ReadFile(Bit16u entry,Bit8u * data,Bit16u * amount) { return ret; } -bool DOS_WriteFile(Bit16u entry,Bit8u * data,Bit16u * amount) { - Bit32u handle=RealHandle(entry); +bool DOS_WriteFile(Bit16u entry,Bit8u * data,Bit16u * amount,bool fcb) { + Bit32u handle = fcb?entry:RealHandle(entry); if (handle>=DOS_FILES) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; @@ -409,8 +409,8 @@ bool DOS_WriteFile(Bit16u entry,Bit8u * data,Bit16u * amount) { return ret; } -bool DOS_SeekFile(Bit16u entry,Bit32u * pos,Bit32u type) { - Bit32u handle=RealHandle(entry); +bool DOS_SeekFile(Bit16u entry,Bit32u * pos,Bit32u type,bool fcb) { + Bit32u handle = fcb?entry:RealHandle(entry); if (handle>=DOS_FILES) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; @@ -422,8 +422,8 @@ bool DOS_SeekFile(Bit16u entry,Bit32u * pos,Bit32u type) { return Files[handle]->Seek(pos,type); } -bool DOS_CloseFile(Bit16u entry) { - Bit32u handle=RealHandle(entry); +bool DOS_CloseFile(Bit16u entry, bool fcb) { + Bit32u handle = fcb?entry:RealHandle(entry); if (handle>=DOS_FILES) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; @@ -435,8 +435,10 @@ bool DOS_CloseFile(Bit16u entry) { if (Files[handle]->IsOpen()) { Files[handle]->Close(); } + DOS_PSP psp(dos.psp()); - psp.SetFileHandle(entry,0xff); + if (!fcb) psp.SetFileHandle(entry,0xff); + if (Files[handle]->RemoveRef()<=0) { delete Files[handle]; Files[handle]=0; @@ -473,7 +475,7 @@ static bool PathExists(char const * const name) { } -bool DOS_CreateFile(char const * name,Bit16u attributes,Bit16u * entry) { +bool DOS_CreateFile(char const * name,Bit16u attributes,Bit16u * entry,bool fcb) { // Creation of a device is the same as opening it // Tc201 installer if (DOS_FindDevice(name) != DOS_DEVICES) @@ -496,7 +498,7 @@ bool DOS_CreateFile(char const * name,Bit16u attributes,Bit16u * entry) { return false; } /* We have a position in the main table now find one in the psp table */ - *entry = psp.FindFreeFileEntry(); + *entry = fcb?handle:psp.FindFreeFileEntry(); if (*entry==0xff) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); return false; @@ -510,7 +512,7 @@ bool DOS_CreateFile(char const * name,Bit16u attributes,Bit16u * entry) { if (foundit) { Files[handle]->SetDrive(drive); Files[handle]->AddRef(); - psp.SetFileHandle(*entry,handle); + if (!fcb) psp.SetFileHandle(*entry,handle); return true; } else { if(!PathExists(name)) DOS_SetError(DOSERR_PATH_NOT_FOUND); @@ -519,7 +521,7 @@ bool DOS_CreateFile(char const * name,Bit16u attributes,Bit16u * entry) { } } -bool DOS_OpenFile(char const * name,Bit8u flags,Bit16u * entry) { +bool DOS_OpenFile(char const * name,Bit8u flags,Bit16u * entry,bool fcb) { /* First check for devices */ if (flags>2) LOG(LOG_FILES,LOG_ERROR)("Special file open command %X file %s",flags,name); else LOG(LOG_FILES,LOG_NORMAL)("file open command %X file %s",flags,name); @@ -552,7 +554,7 @@ bool DOS_OpenFile(char const * name,Bit8u flags,Bit16u * entry) { return false; } /* We have a position in the main table now find one in the psp table */ - *entry = psp.FindFreeFileEntry(); + *entry = fcb?handle:psp.FindFreeFileEntry(); if (*entry==0xff) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); @@ -567,7 +569,7 @@ bool DOS_OpenFile(char const * name,Bit8u flags,Bit16u * entry) { } if (exists || device ) { Files[handle]->AddRef(); - psp.SetFileHandle(*entry,handle); + if (!fcb) psp.SetFileHandle(*entry,handle); return true; } else { //Test if file exists, but opened in read-write mode (and writeprotected) @@ -959,7 +961,7 @@ bool DOS_FCBCreate(Bit16u seg,Bit16u offset) { Bit8u attr = DOS_ATTR_ARCHIVE; fcb.GetAttr(attr); if (!attr) attr = DOS_ATTR_ARCHIVE; //Better safe than sorry - if (!DOS_CreateFile(shortname,attr,&handle)) return false; + if (!DOS_CreateFile(shortname,attr,&handle,true)) return false; fcb.FileOpen((Bit8u)handle); return true; } @@ -975,21 +977,15 @@ bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { if (!DOS_MakeName(shortname,fullname,&drive)) return false; /* Check, if file is already opened */ - for (Bit8u i=0;iIsOpen() && Files[i]->IsName(fullname)) { - handle = psp.FindEntryByHandle(i); - if (handle==0xFF) { - // This shouldnt happen - LOG(LOG_FILES,LOG_ERROR)("DOS: File %s is opened but has no psp entry.",shortname); - return false; - } - fcb.FileOpen((Bit8u)handle); + Files[i]->AddRef(); + fcb.FileOpen(i); return true; } } - if (!DOS_OpenFile(shortname,OPEN_READWRITE,&handle)) return false; + if (!DOS_OpenFile(shortname,OPEN_READWRITE,&handle,true)) return false; fcb.FileOpen((Bit8u)handle); return true; } @@ -999,7 +995,7 @@ bool DOS_FCBClose(Bit16u seg,Bit16u offset) { if(!fcb.Valid()) return false; Bit8u fhandle; fcb.FileClose(fhandle); - DOS_CloseFile(fhandle); + DOS_CloseFile(fhandle,true); return true; } @@ -1033,11 +1029,15 @@ Bit8u DOS_FCBRead(Bit16u seg,Bit16u offset,Bit16u recno) { LOG(LOG_FCB,LOG_WARN)("Reopened closed FCB"); fcb.GetSeqData(fhandle,rec_size); } + if (rec_size == 0) { + rec_size = 128; + fcb.SetSeqData(fhandle,rec_size); + } fcb.GetRecord(cur_block,cur_rec); Bit32u pos=((cur_block*128)+cur_rec)*rec_size; - if (!DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET)) return FCB_READ_NODATA; + if (!DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET,true)) return FCB_READ_NODATA; Bit16u toread=rec_size; - if (!DOS_ReadFile(fhandle,dos_copybuf,&toread)) return FCB_READ_NODATA; + if (!DOS_ReadFile(fhandle,dos_copybuf,&toread,true)) return FCB_READ_NODATA; if (toread==0) return FCB_READ_NODATA; if (toread < rec_size) { //Zero pad copybuffer to rec_size Bitu i = toread; @@ -1060,12 +1060,16 @@ Bit8u DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u recno) { LOG(LOG_FCB,LOG_WARN)("Reopened closed FCB"); fcb.GetSeqData(fhandle,rec_size); } + if (rec_size == 0) { + rec_size = 128; + fcb.SetSeqData(fhandle,rec_size); + } fcb.GetRecord(cur_block,cur_rec); Bit32u pos=((cur_block*128)+cur_rec)*rec_size; - if (!DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET)) return FCB_ERR_WRITE; + if (!DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET,true)) return FCB_ERR_WRITE; MEM_BlockRead(Real2Phys(dos.dta())+recno*rec_size,dos_copybuf,rec_size); Bit16u towrite=rec_size; - if (!DOS_WriteFile(fhandle,dos_copybuf,&towrite)) return FCB_ERR_WRITE; + if (!DOS_WriteFile(fhandle,dos_copybuf,&towrite,true)) return FCB_ERR_WRITE; Bit32u size;Bit16u date,time; fcb.GetSizeDateTime(size,date,time); if (pos+towrite>size) size=pos+towrite; @@ -1077,9 +1081,8 @@ Bit8u DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u recno) { Bit16u min = (Bit16u)((seconds % 3600)/60); Bit16u sec = (Bit16u)(seconds % 60); time = DOS_PackTime(hour,min,sec); - Bit8u temp=RealHandle(fhandle); - Files[temp]->time=time; - Files[temp]->date=date; + Files[fhandle]->time = time; + Files[fhandle]->date = date; fcb.SetSizeDateTime(size,date,time); if (++cur_rec>127) { cur_block++;cur_rec=0; } fcb.SetRecord(cur_block,cur_rec); @@ -1092,9 +1095,9 @@ Bit8u DOS_FCBIncreaseSize(Bit16u seg,Bit16u offset) { fcb.GetSeqData(fhandle,rec_size); fcb.GetRecord(cur_block,cur_rec); Bit32u pos=((cur_block*128)+cur_rec)*rec_size; - if (!DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET)) return FCB_ERR_WRITE; + if (!DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET,true)) return FCB_ERR_WRITE; Bit16u towrite=0; - if (!DOS_WriteFile(fhandle,dos_copybuf,&towrite)) return FCB_ERR_WRITE; + if (!DOS_WriteFile(fhandle,dos_copybuf,&towrite,true)) return FCB_ERR_WRITE; Bit32u size;Bit16u date,time; fcb.GetSizeDateTime(size,date,time); if (pos+towrite>size) size=pos+towrite; @@ -1106,9 +1109,8 @@ Bit8u DOS_FCBIncreaseSize(Bit16u seg,Bit16u offset) { Bit16u min = (Bit16u)((seconds % 3600)/60); Bit16u sec = (Bit16u)(seconds % 60); time = DOS_PackTime(hour,min,sec); - Bit8u temp=RealHandle(fhandle); - Files[temp]->time=time; - Files[temp]->date=date; + Files[fhandle]->time = time; + Files[fhandle]->date = date; fcb.SetSizeDateTime(size,date,time); fcb.SetRecord(cur_block,cur_rec); return FCB_SUCCESS; @@ -1178,14 +1180,18 @@ Bit8u DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u * numRec,bool restore) } bool DOS_FCBGetFileSize(Bit16u seg,Bit16u offset) { - char shortname[DOS_PATHLENGTH];Bit16u entry;Bit8u handle;Bit16u rec_size; + char shortname[DOS_PATHLENGTH];Bit16u entry; DOS_FCB fcb(seg,offset); fcb.GetName(shortname); - if (!DOS_OpenFile(shortname,OPEN_READ,&entry)) return false; - handle = RealHandle(entry); + if (!DOS_OpenFile(shortname,OPEN_READ,&entry,true)) return false; Bit32u size = 0; - Files[handle]->Seek(&size,DOS_SEEK_END); - DOS_CloseFile(entry);fcb.GetSeqData(handle,rec_size); + Files[entry]->Seek(&size,DOS_SEEK_END); + DOS_CloseFile(entry,true); + + Bit8u handle; Bit16u rec_size; + fcb.GetSeqData(handle,rec_size); + if (rec_size == 0) rec_size = 128; //Use default if missing. + Bit32u random=(size/rec_size); if (size % rec_size) random++; fcb.SetRandom(random); @@ -1212,7 +1218,7 @@ bool DOS_FCBDeleteFile(Bit16u seg,Bit16u offset){ nextfile = DOS_FCBFindNext(seg,offset); } dos.dta(old_dta); /*Restore dta */ - return return_value; + return return_value; } bool DOS_FCBRenameFile(Bit16u seg, Bit16u offset){ @@ -1231,12 +1237,12 @@ bool DOS_FCBRenameFile(Bit16u seg, Bit16u offset){ for (Bit8u i=0;iIsOpen() && Files[i]->IsName(fullname)) { Bit16u handle = psp.FindEntryByHandle(i); + //(more than once maybe) if (handle == 0xFF) { - // This shouldnt happen - LOG(LOG_FILES,LOG_ERROR)("DOS: File %s is opened but has no psp entry.",oldname); - return false; + DOS_CloseFile(i,true); + } else { + DOS_CloseFile(handle); } - DOS_CloseFile(handle); } } From 7de4631055faf2c4b62f24b98e2a4e5e3bc154f6 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 9 Feb 2016 18:19:45 +0000 Subject: [PATCH 3873/4131] Increase size of SysEx buffer to support Sierra's Yamaha FB-01 driver. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3963 --- include/midi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/midi.h b/include/midi.h index 9da6f180..86431dc8 100644 --- a/include/midi.h +++ b/include/midi.h @@ -38,7 +38,7 @@ public: }; -#define SYSEX_SIZE 1024 +#define SYSEX_SIZE 8192 struct DB_Midi { Bitu status; Bitu cmd_len; From 3000bd2febb8b26960da6f5a4602a4c33bb21a7a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Feb 2016 09:42:32 +0000 Subject: [PATCH 3874/4131] Be a bit more flexible. Parse ver set 3.2 correctly as well. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3964 --- src/shell/shell_cmds.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index a8cf22bd..3cfb13c6 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -1235,7 +1235,16 @@ void DOS_Shell::CMD_VER(char *args) { char* word = StripWord(args); if(strcasecmp(word,"set")) return; word = StripWord(args); - dos.version.major = (Bit8u)(atoi(word)); - dos.version.minor = (Bit8u)(atoi(args)); + if (!*args && !*word) { //Reset + dos.version.major = 5; + dos.version.minor = 0; + } else if (*args == 0 && *word && (strchr(word,'.') != 0)) { //Allow: ver set 5.1 + const char * p = strchr(word,'.'); + dos.version.major = (Bit8u)(atoi(word)); + dos.version.minor = (Bit8u)(atoi(p+1)); + } else { //Official syntax: ver set 5 2 + dos.version.major = (Bit8u)(atoi(word)); + dos.version.minor = (Bit8u)(atoi(args)); + } } else WriteOut(MSG_Get("SHELL_CMD_VER_VER"),VERSION,dos.version.major,dos.version.minor); } From c96a19e3d97bfac20788e86013cf0efd881d18a6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 11 Feb 2016 15:47:15 +0000 Subject: [PATCH 3875/4131] Test using Macro instead of &. Check for failure to open an image. Thanks Malvineous Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3965 --- src/dos/dos_programs.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 82fc324c..4086b167 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -298,7 +298,7 @@ public: return; } /* Not a switch so a normal directory/file */ - if (!(test.st_mode & S_IFDIR)) { + if (!S_ISDIR(test.st_mode)) { #ifdef OS2 HFILE cdrom_fd = 0; ULONG ulAction = 0; @@ -1216,7 +1216,7 @@ public: } } } - if ((test.st_mode & S_IFDIR)) { + if (S_ISDIR(test.st_mode)) { WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MOUNT")); return; } @@ -1232,7 +1232,7 @@ public: if(fstype=="fat") { if (imgsizedetect) { FILE * diskfile = fopen(temp_line.c_str(), "rb+"); - if(!diskfile) { + if (!diskfile) { WriteOut(MSG_Get("PROGRAM_IMGMOUNT_INVALID_IMAGE")); return; } @@ -1377,6 +1377,10 @@ public: } else { FILE *newDisk = fopen(temp_line.c_str(), "rb+"); + if (!newDisk) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_INVALID_IMAGE")); + return; + } fseek(newDisk,0L, SEEK_END); imagesize = (ftell(newDisk) / 1024); From 30db525521038c9ad8a141277d635be84f19bfba Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 12 Feb 2016 08:06:04 +0000 Subject: [PATCH 3876/4131] Fix compilation on visual studio Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3966 --- src/dos/dos_programs.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 4086b167..0b9efbe0 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -46,6 +46,12 @@ #include "os2.h" #endif +#if defined(WIN32) +#ifndef S_ISDIR +#define S_ISDIR(m) (((m)&S_IFMT)==S_IFDIR) +#endif +#endif + #if C_DEBUG Bitu DEBUG_EnableDebugger(void); #endif From 9035510f06bd48ceac6e911e84e265d424c97f4b Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sun, 14 Feb 2016 03:59:17 +0000 Subject: [PATCH 3877/4131] Take into account that speaker might be disabled in settings. Fixes bug #434. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3967 --- src/hardware/pcspeaker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index d426a66c..3e166fc6 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -192,7 +192,7 @@ void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode) { spkr.pit_max=(1000.0f/PIT_TICK_RATE)*cntr; break; case 3: /* Square wave generator */ - if (cntr Date: Sun, 14 Feb 2016 04:02:09 +0000 Subject: [PATCH 3878/4131] Implement BIOS beep sound for ASCII character 7. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3968 --- src/ints/int10_char.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index a672d2ba..daf9c8ab 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -589,9 +589,21 @@ static void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr,Bit8u pag Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); switch (chr) { - case 7: - //TODO BEEP - break; + case 7: /* Beep */ + // Prepare PIT counter 2 for ~900 Hz square wave + IO_Write(0x43,0xb6); + IO_Write(0x42,0x28); + IO_Write(0x42,0x05); + // Speaker on + IO_Write(0x61,IO_Read(0x61)|3); + // Idle for 1/3rd of a second + double start; + start=PIC_FullIndex(); + while ((PIC_FullIndex()-start)<333.0) CALLBACK_Idle(); + // Speaker off + IO_Write(0x61,IO_Read(0x61)&~3); + // No change in position + return; case 8: if(cur_col>0) cur_col--; break; From 3dc6d7115e3aed47c2ce55ba743221d4a527bf76 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sun, 14 Feb 2016 04:15:05 +0000 Subject: [PATCH 3879/4131] Add some defines for r3968. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3969 --- src/ints/int10_char.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index daf9c8ab..6a610f31 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -24,6 +24,8 @@ #include "mem.h" #include "inout.h" #include "int10.h" +#include "pic.h" +#include "callback.h" static void CGA2_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); From 663c86378fffe543e4737a210f922a657c5314e4 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sun, 6 Mar 2016 13:04:58 +0000 Subject: [PATCH 3880/4131] Fix screen clearing when setting mode 0xA on PCjr machine type. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3970 --- src/ints/int10_modes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 79ef2772..65b80c48 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -386,6 +386,7 @@ static void FinishSetMode(bool clearmem) { if (clearmem) { switch (CurMode->type) { case M_TANDY16: + case M_CGA4: if ((machine==MCH_PCJR) && (CurMode->mode >= 9)) { // PCJR cannot access the full 32k at 0xb800 for (Bit16u ct=0;ct<16*1024;ct++) { @@ -395,7 +396,6 @@ static void FinishSetMode(bool clearmem) { break; } // fall-through - case M_CGA4: case M_CGA2: for (Bit16u ct=0;ct<16*1024;ct++) { real_writew( 0xb800,ct*2,0x0000); From f59ebfd30340964fc27f7486c55512beb83b28b8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 18 Mar 2016 16:48:25 +0000 Subject: [PATCH 3881/4131] Fix creation of devices using FCB_Create. Fixes MS Object linker 1.10 and thus bug #435. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3971 --- src/dos/dos_files.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 38853bf0..fa053a4f 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -479,7 +479,7 @@ bool DOS_CreateFile(char const * name,Bit16u attributes,Bit16u * entry,bool fcb) // Creation of a device is the same as opening it // Tc201 installer if (DOS_FindDevice(name) != DOS_DEVICES) - return DOS_OpenFile(name, OPEN_READ, entry); + return DOS_OpenFile(name, OPEN_READ, entry, fcb); LOG(LOG_FILES,LOG_NORMAL)("file create attributes %X file %s",attributes,name); char fullname[DOS_PATHLENGTH];Bit8u drive; From 58c495998a0cbafd3f05d9f532e0a7a32d55fa44 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Wed, 23 Mar 2016 21:24:41 +0000 Subject: [PATCH 3882/4131] Fill DTA for FCB search results more like real DOS. Fixes bug #436. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3972 --- src/dos/dos_classes.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 5f59e839..1aec59fb 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -389,8 +389,8 @@ bool DOS_FCB::Extended(void) { void DOS_FCB::Create(bool _extended) { Bitu fill; - if (_extended) fill=36+7; - else fill=36; + if (_extended) fill=33+7; + else fill=33; Bitu i; for (i=0;i Date: Tue, 29 Mar 2016 21:08:40 +0000 Subject: [PATCH 3883/4131] Add support for mode 8 row copy/fill. Fixes Tandy GW-BASIC interpreter SCREEN 3 scrolling/clearing. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3973 --- src/ints/int10_char.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 6a610f31..478fa1da 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -54,14 +54,12 @@ static void CGA4_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt b static void TANDY16_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysPt base) { Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); - PhysPt dest=base+((CurMode->twidth*rnew)*(cheight/4)+cleft)*4; - PhysPt src=base+((CurMode->twidth*rold)*(cheight/4)+cleft)*4; + Bit8u banks=CurMode->twidth/10; + PhysPt dest=base+((CurMode->twidth*rnew)*(cheight/banks)+cleft)*4; + PhysPt src=base+((CurMode->twidth*rold)*(cheight/banks)+cleft)*4; Bitu copy=(cright-cleft)*4;Bitu nextline=CurMode->twidth*4; - for (Bitu i=0;itwidth*row)*(cheight/4)+cleft)*4; + Bit8u banks=CurMode->twidth/10; + PhysPt dest=base+((CurMode->twidth*row)*(cheight/banks)+cleft)*4; Bitu copy=(cright-cleft)*4;Bitu nextline=CurMode->twidth*4; attr=(attr & 0xf) | (attr & 0xf) << 4; - for (Bitu i=0;i Date: Tue, 5 Apr 2016 05:19:06 +0000 Subject: [PATCH 3884/4131] Map inactive video memory regions as empty rather than filled with RAM. Fixes later version of Sargon 3 on color machine types. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3974 --- src/hardware/vga_memory.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 39d4d8fc..619f81b3 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -794,9 +794,12 @@ void VGA_SetupHandlers(void) { switch (machine) { case MCH_CGA: case MCH_PCJR: + MEM_SetPageHandler( VGA_PAGE_A0, 16, &vgaph.empty ); + MEM_SetPageHandler( VGA_PAGE_B0, 8, &vgaph.empty ); MEM_SetPageHandler( VGA_PAGE_B8, 8, &vgaph.pcjr ); goto range_done; case MCH_HERC: + MEM_SetPageHandler( VGA_PAGE_A0, 16, &vgaph.empty ); vgapages.base=VGA_PAGE_B0; if (vga.herc.enable_bits & 0x2) { vgapages.mask=0xffff; @@ -825,7 +828,7 @@ void VGA_SetupHandlers(void) { } else { vga.tandy.draw_base = TANDY_VIDBASE( vga.tandy.draw_bank * 16 * 1024); vga.tandy.mem_base = TANDY_VIDBASE( vga.tandy.mem_bank * 16 * 1024); - MEM_SetPageHandler( 0xb8, 8, &vgaph.tandy ); + MEM_SetPageHandler( VGA_PAGE_B8, 8, &vgaph.tandy ); } goto range_done; // MEM_SetPageHandler(vga.tandy.mem_bank<<2,vga.tandy.is_32k_mode ? 0x08 : 0x04,range_handler); @@ -903,21 +906,21 @@ void VGA_SetupHandlers(void) { vgapages.base = VGA_PAGE_A0; vgapages.mask = 0xffff; MEM_SetPageHandler( VGA_PAGE_A0, 16, newHandler ); - MEM_ResetPageHandler( VGA_PAGE_B0, 16); + MEM_SetPageHandler( VGA_PAGE_B0, 16, &vgaph.empty ); break; case 2: vgapages.base = VGA_PAGE_B0; vgapages.mask = 0x7fff; MEM_SetPageHandler( VGA_PAGE_B0, 8, newHandler ); - MEM_ResetPageHandler( VGA_PAGE_A0, 16 ); - MEM_ResetPageHandler( VGA_PAGE_B8, 8 ); + MEM_SetPageHandler( VGA_PAGE_A0, 16, &vgaph.empty ); + MEM_SetPageHandler( VGA_PAGE_B8, 8, &vgaph.empty ); break; case 3: vgapages.base = VGA_PAGE_B8; vgapages.mask = 0x7fff; MEM_SetPageHandler( VGA_PAGE_B8, 8, newHandler ); - MEM_ResetPageHandler( VGA_PAGE_A0, 16 ); - MEM_ResetPageHandler( VGA_PAGE_B0, 8 ); + MEM_SetPageHandler( VGA_PAGE_A0, 16, &vgaph.empty ); + MEM_SetPageHandler( VGA_PAGE_B0, 8, &vgaph.empty ); break; } if(svgaCard == SVGA_S3Trio && (vga.s3.ext_mem_ctrl & 0x10)) From 77bb9df6a62e4ffd3ff9dcc5ea360cbdeb0898a5 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 5 Apr 2016 05:29:05 +0000 Subject: [PATCH 3885/4131] Reset CurMode object when detecting that the video mode number in BIOS memory was modified directly instead of through the INT 10h mode set function. Fixes cases where BIOS behavior is influenced with the mode number, such as the status line in Bruce Lee. Set color modes (to the extent that they can be) on the Hercules machine type if the BIOS equipment list is not set to monochrome. Fixes missing text in Victory Road. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3975 --- src/dos/dev_con.h | 2 + src/ints/int10.cpp | 1 + src/ints/int10.h | 1 + src/ints/int10_modes.cpp | 85 +++++++++++++++++++++++++++++++--------- src/ints/mouse.cpp | 1 + 5 files changed, 72 insertions(+), 18 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 05af1d0a..9368c49c 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -53,6 +53,7 @@ private: bool device_CON::Read(Bit8u * data,Bit16u * size) { Bit16u oldax=reg_ax; Bit16u count=0; + INT10_SetCurMode(); if ((readcache) && (*size)) { data[count++]=readcache; if(dos.echo) INT10_TeletypeOutput(readcache,7); @@ -117,6 +118,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { Bit8u col,row; Bit16u ncols,nrows; Bit8u tempdata; + INT10_SetCurMode(); while (*size>count) { if (!ansi.esc){ if(data[count]=='\033') { diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 38bf5c00..1ec16b5c 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -48,6 +48,7 @@ static Bitu INT10_Handler(void) { break; } #endif + INT10_SetCurMode(); switch (reg_ah) { case 0x00: /* Set VideoMode */ diff --git a/src/ints/int10.h b/src/ints/int10.h index 4fdbdc0b..d53065da 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -156,6 +156,7 @@ static Bit8u CURSOR_POS_ROW(Bit8u page) { } bool INT10_SetVideoMode(Bit16u mode); +void INT10_SetCurMode(void); void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit8u attr,Bit8u page); diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 65b80c48..f7f2735a 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -380,6 +380,66 @@ static bool SetCurMode(VideoModeBlock modeblock[],Bit16u mode) { return false; } +static void SetTextLines(void) { + // check for scanline backwards compatibility (VESA text modes??) + switch (real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x90) { + case 0x80: // 200 lines emulation + if (CurMode->mode <= 3) { + CurMode = &ModeList_VGA_Text_200lines[CurMode->mode]; + } else if (CurMode->mode == 7) { + CurMode = &ModeList_VGA_Text_350lines[4]; + } + break; + case 0x00: // 350 lines emulation + if (CurMode->mode <= 3) { + CurMode = &ModeList_VGA_Text_350lines[CurMode->mode]; + } else if (CurMode->mode == 7) { + CurMode = &ModeList_VGA_Text_350lines[4]; + } + break; + } +} + +void INT10_SetCurMode(void) { + Bit16u bios_mode=(Bit16u)real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); + if (GCC_UNLIKELY(CurMode->mode!=bios_mode)) { + bool mode_changed=false; + switch (machine) { + case MCH_CGA: + if (bios_mode<7) mode_changed=SetCurMode(ModeList_OTHER,bios_mode); + break; + case TANDY_ARCH_CASE: + if (bios_mode!=7 && bios_mode<=0xa) mode_changed=SetCurMode(ModeList_OTHER,bios_mode); + break; + case MCH_HERC: + if (bios_mode<7) mode_changed=SetCurMode(ModeList_OTHER,bios_mode); + else if (bios_mode==7) {mode_changed=true;CurMode=&Hercules_Mode;} + break; + case MCH_EGA: + mode_changed=SetCurMode(ModeList_EGA,bios_mode); + break; + case VGA_ARCH_CASE: + switch (svgaCard) { + case SVGA_TsengET4K: + case SVGA_TsengET3K: + mode_changed=SetCurMode(ModeList_VGA_Tseng,bios_mode); + break; + case SVGA_ParadisePVGA1A: + mode_changed=SetCurMode(ModeList_VGA_Paradise,bios_mode); + break; + case SVGA_S3Trio: + if (bios_mode>=0x68 && CurMode->mode==(bios_mode+0x98)) break; + // fall-through + default: + mode_changed=SetCurMode(ModeList_VGA,bios_mode); + break; + } + if (mode_changed && CurMode->type==M_TEXT) SetTextLines(); + break; + } + if (mode_changed) LOG(LOG_INT10,LOG_WARN)("BIOS video mode changed to %X",bios_mode); + } +} static void FinishSetMode(bool clearmem) { /* Clear video memory if needs be */ @@ -466,8 +526,12 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) { } break; case MCH_HERC: - // Only init the adapter if the equipment word is set to monochrome (Testdrive) - if ((real_readw(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE)&0x30)!=0x30) return false; + // Allow standard color modes if equipment word is not set to mono (Victory Road) + if ((real_readw(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE)&0x30)!=0x30 && mode<7) { + SetCurMode(ModeList_OTHER,mode); + FinishSetMode(clearmem); + return true; + } CurMode=&Hercules_Mode; mode=7; // in case the video parameter table is modified break; @@ -682,22 +746,7 @@ bool INT10_SetVideoMode(Bit16u mode) { return false; } } - // check for scanline backwards compatibility (VESA text modes??) - if (CurMode->type==M_TEXT) { - if ((modeset_ctl&0x90)==0x80) { // 200 lines emulation - if (CurMode->mode <= 3) { - CurMode = &ModeList_VGA_Text_200lines[CurMode->mode]; - } else if (CurMode->mode == 7) { - CurMode = &ModeList_VGA_Text_350lines[4]; - } - } else if ((modeset_ctl&0x90)==0x00) { // 350 lines emulation - if (CurMode->mode <= 3) { - CurMode = &ModeList_VGA_Text_350lines[CurMode->mode]; - } else if (CurMode->mode == 7) { - CurMode = &ModeList_VGA_Text_350lines[4]; - } - } - } + if (CurMode->type==M_TEXT) SetTextLines(); } else { if (!SetCurMode(ModeList_EGA,mode)){ LOG(LOG_INT10,LOG_ERROR)("EGA:Trying to set illegal mode %X",mode); diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index b56be405..3b337e50 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -375,6 +375,7 @@ void RestoreCursorBackground() { void DrawCursor() { if (mouse.hidden || mouse.inhibit_draw) return; + INT10_SetCurMode(); // In Textmode ? if (CurMode->type==M_TEXT) { DrawCursorText(); From 6f0506ec425a81c056e6f722e1f3139dec751838 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 5 Apr 2016 05:38:52 +0000 Subject: [PATCH 3886/4131] Graphics mode text drawing improvements: font source according to machine type, background color in 256-color modes, row wrapping. Use compatible method of determining fill attribute for textmode screen scrolling in teletype function. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3976 --- src/ints/int10_char.cpp | 190 ++++++++++++++++++++++++-------------- src/ints/int10_memory.cpp | 2 +- 2 files changed, 122 insertions(+), 70 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 478fa1da..3d0a64d6 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -405,7 +405,7 @@ void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page) { void ReadCharAttr(Bit16u col,Bit16u row,Bit8u page,Bit16u * result) { /* Externally used by the mouse routine */ PhysPt fontdata; - Bitu x,y; + Bitu x,y,pos = row*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)+col; Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); bool split_chr = false; switch (CurMode->type) { @@ -413,7 +413,7 @@ void ReadCharAttr(Bit16u col,Bit16u row,Bit8u page,Bit16u * result) { { // Compute the address Bit16u address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); - address+=(row*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)+col)*2; + address+=pos*2; // read the char PhysPt where = CurMode->pstart+address; *result=mem_readw(where); @@ -423,45 +423,62 @@ void ReadCharAttr(Bit16u col,Bit16u row,Bit8u page,Bit16u * result) { case M_CGA2: case M_TANDY16: split_chr = true; - /* Fallthrough */ - default: /* EGA/VGA don't have a split font-table */ - for(Bit16u chr=0;chr <= 255 ;chr++) { - if (!split_chr || (chr<128)) fontdata = Real2Phys(RealGetVec(0x43))+chr*cheight; - else fontdata = Real2Phys(RealGetVec(0x1F))+(chr-128)*cheight; - - x=8*col; - y=cheight*row; - bool error=false; - for (Bit8u h=0;h>=1; - } - y++; - if(bitline != vidline){ - /* It's not character 'chr', move on to the next */ - error = true; - break; - } - } - if(!error){ - /* We found it */ - *result = chr; - return; - } + switch (machine) { + case MCH_CGA: + case MCH_HERC: + fontdata=PhysMake(0xf000,0xfa6e); + break; + case TANDY_ARCH_CASE: + fontdata=Real2Phys(RealGetVec(0x44)); + break; + default: + fontdata=Real2Phys(RealGetVec(0x43)); + break; } - LOG(LOG_INT10,LOG_ERROR)("ReadChar didn't find character"); - *result = 0; + break; + default: + fontdata=Real2Phys(RealGetVec(0x43)); break; } + + x=(pos%CurMode->twidth)*8; + y=(pos/CurMode->twidth)*cheight; + + for (Bit16u chr=0;chr<256;chr++) { + + if (chr==128 && split_chr) fontdata=Real2Phys(RealGetVec(0x1f)); + + bool error=false; + Bit16u ty=(Bit16u)y; + for (Bit8u h=0;h>=1; + } + ty++; + if(bitline != vidline){ + /* It's not character 'chr', move on to the next */ + fontdata+=(cheight-h-1); + error = true; + break; + } + } + if(!error){ + /* We found it */ + *result = chr; + return; + } + } + LOG(LOG_INT10,LOG_ERROR)("ReadChar didn't find character"); + *result = 0; } void INT10_ReadCharAttr(Bit16u * result,Bit8u page) { if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); @@ -471,39 +488,47 @@ void INT10_ReadCharAttr(Bit16u * result,Bit8u page) { } void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useattr) { /* Externally used by the mouse routine */ - RealPt fontdata; - Bitu x,y; - Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); + PhysPt fontdata; + Bitu x,y,pos = row*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)+col; + Bit8u back,cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); switch (CurMode->type) { case M_TEXT: { // Compute the address Bit16u address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); - address+=(row*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)+col)*2; + address+=pos*2; // Write the char PhysPt where = CurMode->pstart+address; mem_writeb(where,chr); - if (useattr) { - mem_writeb(where+1,attr); - } + if (useattr) mem_writeb(where+1,attr); } return; case M_CGA4: case M_CGA2: case M_TANDY16: - if (chr<128) - fontdata=RealGetVec(0x43); - else { + if (chr>=128) { chr-=128; - fontdata=RealGetVec(0x1f); + fontdata=Real2Phys(RealGetVec(0x1f)); + break; + } + switch (machine) { + case MCH_CGA: + case MCH_HERC: + fontdata=PhysMake(0xf000,0xfa6e); + break; + case TANDY_ARCH_CASE: + fontdata=Real2Phys(RealGetVec(0x44)); + break; + default: + fontdata=Real2Phys(RealGetVec(0x43)); + break; } - fontdata=RealMake(RealSeg(fontdata), RealOff(fontdata) + chr*cheight); break; default: - fontdata=RealGetVec(0x43); - fontdata=RealMake(RealSeg(fontdata), RealOff(fontdata) + chr*cheight); + fontdata=Real2Phys(RealGetVec(0x43)); break; } + fontdata+=chr*cheight; if(GCC_UNLIKELY(!useattr)) { //Set attribute(color) to a sensible value static bool warned_use = false; @@ -526,50 +551,72 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt } } - //Some weird behavior of mode 6 (and 11) - if ((CurMode->mode == 0x6)/* || (CurMode->mode==0x11)*/) attr = (attr&0x80)|1; - //(same fix for 11 fixes vgatest2, but it's not entirely correct according to wd) + //Attribute behavior of mode 6; mode 11 does something similar but + //it is in INT 10h handler because it only applies to function 09h + if (CurMode->mode==0x06) attr=(attr&0x80)|1; - x=8*col; - y=cheight*row;Bit8u xor_mask=(CurMode->type == M_VGA) ? 0x0 : 0x80; - //TODO Check for out of bounds - if (CurMode->type==M_EGA) { + switch (CurMode->type) { + case M_VGA: + case M_LIN8: + // 256-color modes have background color instead of page + back=page; + page=0; + break; + case M_EGA: /* enable all planes for EGA modes (Ultima 1 colour bug) */ /* might be put into INT10_PutPixel but different vga bios implementations have different opinions about this */ IO_Write(0x3c4,0x2);IO_Write(0x3c5,0xf); + // fall-through + default: + back=attr&0x80; + break; } + + x=(pos%CurMode->twidth)*8; + y=(pos/CurMode->twidth)*cheight; + + Bit16u ty=(Bit16u)y; for (Bit8u h=0;h>=1; } - y++; + ty++; } } void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) { + Bit8u pospage=page; if (CurMode->type!=M_TEXT) { showattr=true; //Use attr in graphics mode always switch (machine) { case EGAVGA_ARCH_CASE: - page%=CurMode->ptotal; + switch (CurMode->type) { + case M_VGA: + case M_LIN8: + pospage=0; + break; + default: + page%=CurMode->ptotal; + pospage=page; + break; + } break; case MCH_CGA: case MCH_PCJR: page=0; + pospage=0; break; } } - Bit8u cur_row=CURSOR_POS_ROW(page); - Bit8u cur_col=CURSOR_POS_COL(page); + Bit8u cur_row=CURSOR_POS_ROW(pospage); + Bit8u cur_col=CURSOR_POS_COL(pospage); BIOS_NCOLS; while (count>0) { WriteChar(cur_col,cur_row,page,chr,attr,showattr); @@ -630,8 +677,13 @@ static void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr,Bit8u pag } // Do we need to scroll ? if(cur_row==nrows) { - //Fill with black on non-text modes and with 0x7 on textmode - Bit8u fill = (CurMode->type == M_TEXT)?0x7:0; + //Fill with black on non-text modes and with attribute at cursor on textmode + Bit8u fill=0; + if (CurMode->type==M_TEXT) { + Bit16u chat; + INT10_ReadCharAttr(&chat,page); + fill=(Bit8u)(chat>>8); + } INT10_ScrollWindow(0,0,(Bit8u)(nrows-1),(Bit8u)(ncols-1),-1,fill,page); cur_row--; } diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index df16cc04..5c2f9528 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -242,7 +242,7 @@ void INT10_SetupRomMemory(void) { INT10_SetupRomMemoryChecksum(); if (IS_TANDY_ARCH) { - RealSetVec(0x44,int10.rom.font_8_first); + RealSetVec(0x44,RealMake(0xf000,0xfa6e)); } } From f0cf2bc6b0af6e49bad88f0243717fb13b5ef5cc Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 5 Apr 2016 05:40:48 +0000 Subject: [PATCH 3887/4131] Prevent DOS buffered input function from hanging in an infinite loop when redirected input reads a linefeed or reaches EOF. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3977 --- src/dos/dos.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 28e5663b..a421fe07 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -223,6 +223,10 @@ static Bitu DOS_21Handler(void) { free--; for(;;) { DOS_ReadFile(STDIN,&c,&n); + if (n == 0) // End of file + E_Exit("DOS:0x0a:Redirected input reached EOF"); + if (c == 10) // Line feed + continue; if (c == 8) { // Backspace if (read) { //Something to backspace. // STDOUT treats backspace as non-destructive. From 3c95f17d95d8b250dd6a91f83ad169f7632ea9cd Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 5 Apr 2016 05:44:43 +0000 Subject: [PATCH 3888/4131] EXEC improvements, mostly for the load-but-do-not-execute function. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3978 --- src/dos/dos_execute.cpp | 92 +++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 45 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 0037b8c5..80faeb82 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -427,26 +427,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { if (head.initSP<4) LOG(LOG_EXEC,LOG_ERROR)("stack underflow/wrap at EXEC"); } - if (flags==LOAD) { - SaveRegisters(); - DOS_PSP callpsp(dos.psp()); - /* Save the SS:SP on the PSP of calling program */ - callpsp.SetStack(RealMakeSeg(ss,reg_sp)); - reg_sp+=18; - /* Switch the psp's */ - dos.psp(pspseg); - DOS_PSP newpsp(dos.psp()); - dos.dta(RealMake(newpsp.GetSegment(),0x80)); - /* First word on the stack is the value ax should contain on startup */ - real_writew(RealSeg(sssp-2),RealOff(sssp-2),0xffff); - block.exec.initsssp = sssp-2; - block.exec.initcsip = csip; - block.SaveData(); - return true; - } - - if (flags==LOADNGO) { - if ((reg_sp>0xfffe) || (reg_sp<18)) LOG(LOG_EXEC,LOG_ERROR)("stack underflow/wrap at EXEC"); + if ((flags==LOAD) || (flags==LOADNGO)) { /* Get Caller's program CS:IP of the stack and set termination address to that */ RealSetVec(0x22,RealMake(mem_readw(SegPhys(ss)+reg_sp+2),mem_readw(SegPhys(ss)+reg_sp))); SaveRegisters(); @@ -462,39 +443,18 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { /* copy fcbs */ newpsp.SetFCB1(block.exec.fcb1); newpsp.SetFCB2(block.exec.fcb2); + /* Save the SS:SP on the PSP of new program */ + newpsp.SetStack(RealMakeSeg(ss,reg_sp)); - /* Setup ax and bx, they contain a 0xff in al and ah if the drive in the fcb is not valid */ + /* Setup bx, contains a 0xff in bl and bh if the drive in the fcb is not valid */ DOS_FCB fcb1(RealSeg(block.exec.fcb1),RealOff(block.exec.fcb1)); DOS_FCB fcb2(RealSeg(block.exec.fcb2),RealOff(block.exec.fcb2)); Bit8u d1 = fcb1.GetDrive(); //depends on 0 giving the dos.default drive if ( (d1>=DOS_DRIVES) || !Drives[d1] ) reg_bl = 0xFF; else reg_bl = 0; Bit8u d2 = fcb2.GetDrive(); if ( (d2>=DOS_DRIVES) || !Drives[d2] ) reg_bh = 0xFF; else reg_bh = 0; - reg_ax = reg_bx; - /* Set the stack for new program */ - SegSet16(ss,RealSeg(sssp));reg_sp=RealOff(sssp); - /* Add some flags and CS:IP on the stack for the IRET */ - CPU_Push16(RealSeg(csip)); - CPU_Push16(RealOff(csip)); - /* DOS starts programs with a RETF, so critical flags - * should not be modified (IOPL in v86 mode); - * interrupt flag is set explicitly, test flags cleared */ - reg_flags=(reg_flags&(~FMASK_TEST))|FLAG_IF; - //Jump to retf so that we only need to store cs:ip on the stack - reg_ip++; - /* Setup the rest of the registers */ - reg_cx=0xff; - reg_dx=pspseg; - reg_si=RealOff(csip); - reg_di=RealOff(sssp); - reg_bp=0x91c; /* DOS internal stack begin relict */ - SegSet16(ds,pspseg);SegSet16(es,pspseg); -#if C_DEBUG - /* Started from debug.com, then set breakpoint at start */ - DEBUG_CheckExecuteBreakpoint(RealSeg(csip),RealOff(csip)); -#endif - /* Add the filename to PSP and environment MCB's */ + /* Write filename in new program MCB */ char stripname[8]= { 0 };Bitu index=0; while (char chr=*name++) { switch (chr) { @@ -512,6 +472,48 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { DOS_MCB pspmcb(dos.psp()-1); pspmcb.SetFileName(stripname); DOS_UpdatePSPName(); + } + + if (flags==LOAD) { + /* First word on the stack is the value ax should contain on startup */ + real_writew(RealSeg(sssp-2),RealOff(sssp-2),reg_bx); + /* Write initial CS:IP and SS:SP in param block */ + block.exec.initsssp = sssp-2; + block.exec.initcsip = csip; + block.SaveData(); + /* Changed registers */ + reg_sp+=18; + reg_ax=RealOff(csip); + reg_bx=memsize; + reg_dx=0; + return true; + } + + if (flags==LOADNGO) { + if ((reg_sp>0xfffe) || (reg_sp<18)) LOG(LOG_EXEC,LOG_ERROR)("stack underflow/wrap at EXEC"); + /* Set the stack for new program */ + SegSet16(ss,RealSeg(sssp));reg_sp=RealOff(sssp); + /* Add some flags and CS:IP on the stack for the IRET */ + CPU_Push16(RealSeg(csip)); + CPU_Push16(RealOff(csip)); + /* DOS starts programs with a RETF, so critical flags + * should not be modified (IOPL in v86 mode); + * interrupt flag is set explicitly, test flags cleared */ + reg_flags=(reg_flags&(~FMASK_TEST))|FLAG_IF; + //Jump to retf so that we only need to store cs:ip on the stack + reg_ip++; + /* Setup the rest of the registers */ + reg_ax=reg_bx; + reg_cx=0xff; + reg_dx=pspseg; + reg_si=RealOff(csip); + reg_di=RealOff(sssp); + reg_bp=0x91c; /* DOS internal stack begin relict */ + SegSet16(ds,pspseg);SegSet16(es,pspseg); +#if C_DEBUG + /* Started from debug.com, then set breakpoint at start */ + DEBUG_CheckExecuteBreakpoint(RealSeg(csip),RealOff(csip)); +#endif return true; } return false; From 4555aa279d09e3e95b60e327f4c0609ca65c3e6c Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 5 Apr 2016 05:48:00 +0000 Subject: [PATCH 3889/4131] Implement INT 2E -- fixes Gold of the Aztecs and a few other games. Also, stop writing uninitialized junk into first shell's command tail at startup. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3979 --- src/shell/shell.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 2aa174b0..c8d4cfa2 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -459,6 +459,41 @@ void AUTOEXEC_Init(Section * sec) { test = new AUTOEXEC(sec); } +static Bitu INT2E_Handler(void) { + /* Save return address and current process */ + RealPt save_ret=real_readd(SegValue(ss),reg_sp); + Bit16u save_psp=dos.psp(); + + /* Set first shell as process and copy command */ + dos.psp(DOS_FIRST_SHELL); + DOS_PSP psp(DOS_FIRST_SHELL); + psp.SetCommandTail(RealMakeSeg(ds,reg_si)); + SegSet16(ss,RealSeg(psp.GetStack())); + reg_sp=2046; + + /* Read and fix up command string */ + CommandTail tail; + MEM_BlockRead(PhysMake(dos.psp(),128),&tail,128); + if (tail.count<127) tail.buffer[tail.count]=0; + else tail.buffer[126]=0; + char* crlf=strpbrk(tail.buffer,"\r\n"); + if (crlf) *crlf=0; + + /* Execute command */ + if (strlen(tail.buffer)) { + DOS_Shell temp; + temp.ParseLine(tail.buffer); + temp.RunInternal(); + } + + /* Restore process and "return" to caller */ + dos.psp(save_psp); + SegSet16(cs,RealSeg(save_ret)); + reg_ip=RealOff(save_ret); + reg_ax=0; + return CBRET_NONE; +} + static char const * const path_string="PATH=Z:\\"; static char const * const comspec_string="COMSPEC=Z:\\COMMAND.COM"; static char const * const full_name="Z:\\COMMAND.COM"; @@ -627,6 +662,12 @@ void SHELL_Init() { /* Set up int 23 to "int 20" in the psp. Fixes what.exe */ real_writed(0,0x23*4,((Bit32u)psp_seg<<16)); + /* Set up int 2e handler */ + Bitu call_int2e=CALLBACK_Allocate(); + RealPt addr_int2e=RealMake(psp_seg+16+1,8); + CALLBACK_Setup(call_int2e,&INT2E_Handler,CB_IRET_STI,Real2Phys(addr_int2e),"Shell Int 2e"); + RealSetVec(0x2e,addr_int2e); + /* Setup MCBs */ DOS_MCB pspmcb((Bit16u)(psp_seg-1)); pspmcb.SetPSPSeg(psp_seg); // MCB of the command shell psp @@ -671,6 +712,7 @@ void SHELL_Init() { /* Set the command line for the shell start up */ CommandTail tail; tail.count=(Bit8u)strlen(init_line); + memset(&tail.buffer,0,127); strcpy(tail.buffer,init_line); MEM_BlockWrite(PhysMake(psp_seg,128),&tail,128); From 2b32f2bfa950c461d4e0f4f5fc57900b9af7bfdf Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Mon, 18 Apr 2016 13:07:18 +0000 Subject: [PATCH 3890/4131] Prevent problems related to I/O buffering with disk images. Return a fake success result for INT 13/05. Helps older games (Sierra On-Line booters, Mickey's Space Adventure, Zyll, et al.) that insist on low-level formatting a floppy disk to be used for saving games. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3980 --- include/bios_disk.h | 2 ++ src/ints/bios_disk.cpp | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/include/bios_disk.h b/include/bios_disk.h index 51cf6ff1..0670ce05 100644 --- a/include/bios_disk.h +++ b/include/bios_disk.h @@ -65,7 +65,9 @@ public: Bit32u sector_size; Bit32u heads,cylinders,sectors; +private: Bit32u current_fpos; + enum { NONE,READ,WRITE } last_action; }; void updateDPT(void); diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 6f70b0a1..32d93e7c 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -163,9 +163,10 @@ Bit8u imageDisk::Read_AbsoluteSector(Bit32u sectnum, void * data) { bytenum = sectnum * sector_size; - if (bytenum!=current_fpos) fseek(diskimg,bytenum,SEEK_SET); + if (last_action==WRITE || bytenum!=current_fpos) fseek(diskimg,bytenum,SEEK_SET); size_t ret=fread(data, 1, sector_size, diskimg); current_fpos=bytenum+ret; + last_action=READ; return 0x00; } @@ -186,9 +187,10 @@ Bit8u imageDisk::Write_AbsoluteSector(Bit32u sectnum, void *data) { //LOG_MSG("Writing sectors to %ld at bytenum %d", sectnum, bytenum); - if (bytenum!=current_fpos) fseek(diskimg,bytenum,SEEK_SET); - size_t ret=fwrite(data, sector_size, 1, diskimg); + if (last_action==READ || bytenum!=current_fpos) fseek(diskimg,bytenum,SEEK_SET); + size_t ret=fwrite(data, 1, sector_size, diskimg); current_fpos=bytenum+ret; + last_action=WRITE; return ((ret>0)?0x00:0x05); @@ -200,6 +202,7 @@ imageDisk::imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHard sectors = 0; sector_size = 512; current_fpos = 0; + last_action = NONE; diskimg = imgFile; fseek(diskimg,0,SEEK_SET); @@ -450,6 +453,15 @@ static Bitu INT13_DiskHandler(void) { //reg_al = 0x00; /* CRC verify succeeded */ CALLBACK_SCF(false); + break; + case 0x05: /* Format track */ + if (driveInactive(drivenum)) { + reg_ah = 0xff; + CALLBACK_SCF(true); + return CBRET_NONE; + } + reg_ah = 0x00; + CALLBACK_SCF(false); break; case 0x08: /* Get drive parameters */ if(driveInactive(drivenum)) { From 36f12b567099196901456b0b723c5327a9ef2111 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 3 May 2016 17:58:44 +0000 Subject: [PATCH 3891/4131] Fix restarting when in folder with spaces. Quotes aren't allowed on my system. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3981 --- src/gui/sdlmain.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 43df32fb..33c07b21 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1802,7 +1802,18 @@ void restart_program(std::vector & parameters) { DEBUG_ShutDown(NULL); #endif - execvp(newargs[0], newargs); + if(execvp(newargs[0], newargs) == -1) { +#ifdef WIN32 + if(newargs[0][0] == '\"') { + //everything specifies quotes around it if it contains a space, however my system disagrees + std::string edit = parameters[0]; + edit.erase(0,1);edit.erase(edit.length() - 1,1); + //However keep the first argument of the passed argv (newargs) with quotes, as else repeated restarts go wrong. + if(execvp(edit.c_str(), newargs) == -1) E_Exit("Restarting failed"); + } +#endif + E_Exit("Restarting failed"); + } free(newargs); } void Restart(bool pressed) { // mapper handler From 9fc2c31a97019828a7404013a3229029878c3e1c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 10 May 2016 14:38:39 +0000 Subject: [PATCH 3892/4131] Support writing palette register data to dynamic save area if pointer is non-zero on mode changes. Fixes CV 2.2 (thanks for the help ripsaw) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3982 --- src/ints/int10.cpp | 2 ++ src/ints/int10_modes.cpp | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 1ec16b5c..1ca92ea9 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -715,6 +715,8 @@ static void INT10_Seg40Init(void) { real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,0x51); // Set the default MSR real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x09); + // Set the pointer to video save pointer table + real_writed(BIOSMEM_SEG,BIOSMEM_VS_POINTER,int10.rom.video_save_pointers); } diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index f7f2735a..2202a9a8 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -491,7 +491,6 @@ static void FinishSetMode(bool clearmem) { // this is an index into the dcc table: if (IS_VGA_ARCH) real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x0b); - real_writed(BIOSMEM_SEG,BIOSMEM_VS_POINTER,int10.rom.video_save_pointers); // Set cursor shape if (CurMode->type==M_TEXT) { @@ -1321,6 +1320,15 @@ dac_text16: vga.config.pel_panning = 0; IO_Write(0x3c0,0x20); //Disable palette access } + /* Write palette register data to dynamic save area if pointer is non-zero */ + RealPt vsavept=real_readd(BIOSMEM_SEG,BIOSMEM_VS_POINTER); + RealPt dsapt=real_readd(RealSeg(vsavept),RealOff(vsavept)+4); + if (dsapt) { + for (Bit8u ct=0;ct<0x10;ct++) { + real_writeb(RealSeg(dsapt),RealOff(dsapt)+ct,att_data[ct]); + } + real_writeb(RealSeg(dsapt),RealOff(dsapt)+0x10,0); // overscan + } /* Setup some special stuff for different modes */ Bit8u feature=real_readb(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE); switch (CurMode->type) { From 64a04b99853ed12137d6fa2ee0349e68bcd7a749 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Mon, 23 May 2016 11:33:09 +0000 Subject: [PATCH 3893/4131] Be more compatible by converting tabs to spaces in the DOS console device rather than in the video BIOS teletype function. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3983 --- include/dos_inc.h | 1 + src/dos/dev_con.h | 14 ++++++++++++-- src/dos/dos.cpp | 8 ++++++-- src/ints/int10_char.cpp | 7 ------- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index a3729e26..3782d34e 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -626,6 +626,7 @@ struct DOS_Block { bool verify; bool breakcheck; bool echo; // if set to true dev_con::read will echo input + bool direct_output; struct { RealPt mediaid; RealPt tempdta; diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 9368c49c..3cf0cb13 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -115,7 +115,7 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) { bool device_CON::Write(Bit8u * data,Bit16u * size) { Bit16u count=0; Bitu i; - Bit8u col,row; + Bit8u col,row,page; Bit16u ncols,nrows; Bit8u tempdata; INT10_SetCurMode(); @@ -128,6 +128,16 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { ansi.esc=true; count++; continue; + } else if(data[count] == '\t' && !dos.direct_output) { + /* expand tab if not direct output */ + page = real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); + do { + if(ansi.enabled) INT10_TeletypeOutputAttr(' ',ansi.attr,true); + else INT10_TeletypeOutput(' ',7); + col=CURSOR_POS_COL(page); + } while(col%8); + lastwrite = data[count++]; + continue; } else { /* Some sort of "hack" now that '\n' doesn't set col to 0 (int10_char.cpp old chessgame) */ if((data[count] == '\n') && (lastwrite != '\r')) { @@ -161,7 +171,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { continue; } /*ansi.esc and ansi.sci are true */ - Bit8u page = real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); + page = real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); switch(data[count]){ case '0': case '1': diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index a421fe07..c35f6edf 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -133,7 +133,7 @@ static Bitu DOS_21Handler(void) { Bit8u c=reg_dl;Bit16u n=1; DOS_WriteFile(STDOUT,&c,&n); //Not in the official specs, but happens nonetheless. (last written character) - reg_al = c;// reg_al=(c==9)?0x20:c; //Officially: tab to spaces + reg_al=(c==9)?0x20:c; //strangely, tab conversion to spaces is reflected here } break; case 0x03: /* Read character from STDAUX */ @@ -184,8 +184,10 @@ static Bitu DOS_21Handler(void) { default: { Bit8u c = reg_dl;Bit16u n = 1; + dos.direct_output=true; DOS_WriteFile(STDOUT,&c,&n); - reg_al = reg_dl; + dos.direct_output=false; + reg_al=c; } break; }; @@ -211,6 +213,7 @@ static Bitu DOS_21Handler(void) { while ((c=mem_readb(buf++))!='$') { DOS_WriteFile(STDOUT,&c,&n); } + reg_al=c; } break; case 0x0a: /* Buffered Input */ @@ -1236,6 +1239,7 @@ public: dos.version.major=5; dos.version.minor=0; + dos.direct_output=false; } ~DOS(){ for (Bit16u i=0;i Date: Mon, 23 May 2016 11:37:39 +0000 Subject: [PATCH 3894/4131] Make the internal program for loading ROM images a bit smarter about what it can/will load. Also provide for BASIC in ROM to support IBM BASIC interpreters. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3984 --- src/dos/dos_programs.cpp | 82 ++++++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 28 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 0b9efbe0..9b1312e5 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -871,60 +871,81 @@ static void BOOT_ProgramStart(Program * * make) { } -#if C_DEBUG -class LDGFXROM : public Program { +class LOADROM : public Program { public: void Run(void) { - if (!(cmd->FindCommand(1, temp_line))) return; + if (!(cmd->FindCommand(1, temp_line))) { + WriteOut(MSG_Get("PROGRAM_LOADROM_SPECIFY_FILE")); + return; + } Bit8u drive; char fullname[DOS_PATHLENGTH]; - localDrive* ldp=0; if (!DOS_MakeName((char *)temp_line.c_str(),fullname,&drive)) return; - try { + try { + /* try to read ROM file into buffer */ ldp=dynamic_cast(Drives[drive]); if(!ldp) return; FILE *tmpfile = ldp->GetSystemFilePtr(fullname, "rb"); if(tmpfile == NULL) { - LOG_MSG("BIOS file not accessible."); + WriteOut(MSG_Get("PROGRAM_LOADROM_CANT_OPEN")); return; } fseek(tmpfile, 0L, SEEK_END); - if (ftell(tmpfile)>0x10000) { - LOG_MSG("BIOS file too large."); + if (ftell(tmpfile)>0x8000) { + WriteOut(MSG_Get("PROGRAM_LOADROM_TOO_LARGE")); + fclose(tmpfile); return; } fseek(tmpfile, 0L, SEEK_SET); - - PhysPt rom_base=PhysMake(0xc000,0); - - Bit8u vga_buffer[0x10000]; - Bitu data_written=0; - Bitu data_read=fread(vga_buffer, 1, 0x10000, tmpfile); - for (Bitu ct=0; ct= 0x4000 && rom_buffer[0] == 0x55 && rom_buffer[1] == 0xaa && + rom_buffer[3] == 0xeb && strncmp((char*)(&rom_buffer[0x1e]), "IBM", 3) == 0) { + + if (!IS_EGAVGA_ARCH) { + WriteOut(MSG_Get("PROGRAM_LOADROM_INCOMPATIBLE")); + return; + } + rom_base = PhysMake(0xc000, 0); // video BIOS + } + else if (data_read == 0x8000 && rom_buffer[0] == 0xe9 && rom_buffer[1] == 0x8f && + rom_buffer[2] == 0x7e && strncmp((char*)(&rom_buffer[0x4cd4]), "IBM", 3) == 0) { + + rom_base = PhysMake(0xf600, 0); // BASIC + } + + if (rom_base) { + /* write buffer into ROM */ + for (Bitu i=0; i Date: Mon, 23 May 2016 11:39:01 +0000 Subject: [PATCH 3895/4131] Fix the debug launcher internal program's tendency to cause crashes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3985 --- src/debug/debug.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index b66d7c1e..2a54c3b5 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -2093,17 +2093,10 @@ public: Bit16u oldss = SegValue(ss); Bit32u oldesp = reg_esp; - // Workaround : Allocate Stack Space - Bit16u segment; - Bit16u size = 0x200 / 0x10; - if (DOS_AllocateMemory(&segment,&size)) { - SegSet16(ss,segment); - reg_sp = 0x200; - // Start shell - DOS_Shell shell; - shell.Execute(filename,args); - DOS_FreeMemory(segment); - } + // Start shell + DOS_Shell shell; + shell.Execute(filename,args); + // set old reg values SegSet16(ss,oldss); reg_esp = oldesp; From 7cda75c8556b543559c3bc8c221da05ba413a17c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 30 May 2016 11:59:21 +0000 Subject: [PATCH 3896/4131] Allow 64 as input value, so it gets translated to 63 mb, instead of 16 as it currently does, to provide compatibility with 0.74 setups. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3986 --- src/dosbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 1462fae3..675e90da 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -370,7 +370,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&MEM_Init);//done secprop->AddInitFunction(&HARDWARE_Init);//done Pint = secprop->Add_int("memsize", Property::Changeable::WhenIdle,16); - Pint->SetMinMax(1,63); + Pint->SetMinMax(1,64); Pint->Set_help( "Amount of memory DOSBox has in megabytes.\n" " This value is best left at its default to avoid problems with some games,\n" From c898d143519b0225d7398a6d09bacc1523fd1ae6 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Wed, 22 Jun 2016 16:24:16 +0000 Subject: [PATCH 3897/4131] Correct page count/size for CGA graphics modes. Fixes RS-2 on the CGA machine type. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3987 --- src/ints/int10_modes.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 2202a9a8..d47c0b23 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -247,9 +247,9 @@ VideoModeBlock ModeList_OTHER[]={ { 0x001 ,M_TEXT ,320 ,400 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x0800 ,56 ,31 ,40 ,25 ,0 }, { 0x002 ,M_TEXT ,640 ,400 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x1000 ,113 ,31 ,80 ,25 ,0 }, { 0x003 ,M_TEXT ,640 ,400 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x1000 ,113 ,31 ,80 ,25 ,0 }, -{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,56 ,127 ,40 ,100 ,0 }, -{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,56 ,127 ,40 ,100 ,0 }, -{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,56 ,127 ,40 ,100 ,0 }, +{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,56 ,127 ,40 ,100 ,0 }, +{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,56 ,127 ,40 ,100 ,0 }, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,56 ,127 ,40 ,100 ,0 }, { 0x008 ,M_TANDY16,160 ,200 ,20 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,56 ,127 ,40 ,100 ,0 }, { 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,113 ,63 ,80 ,50 ,0 }, { 0x00A ,M_CGA4 ,640 ,200 ,80 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,113 ,63 ,80 ,50 ,0 }, From 2b837cf6fbfb8b12421f33ca6fb43c3c776b7c65 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Wed, 22 Jun 2016 16:29:13 +0000 Subject: [PATCH 3898/4131] Correct stack pointer for COM format programs when there is less than 64K of memory available. Fixes Corncob 3D issue reported in bug #443. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3988 --- src/dos/dos_execute.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 80faeb82..4b27cab0 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -419,8 +419,11 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { RealPt csip,sssp; if (iscom) { csip=RealMake(pspseg,0x100); - sssp=RealMake(pspseg,0xfffe); - mem_writew(PhysMake(pspseg,0xfffe),0); + if (memsize<0x1000) { + LOG(LOG_EXEC,LOG_WARN)("COM format with only %X paragraphs available",memsize); + sssp=RealMake(pspseg,(memsize<<4)-2); + } else sssp=RealMake(pspseg,0xfffe); + mem_writew(Real2Phys(sssp),0); } else { csip=RealMake(loadseg+head.initCS,head.initIP); sssp=RealMake(loadseg+head.initSS,head.initSP); From 9dc8581f4a994959f0b22cee28273c7b0fb35fea Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 24 Jun 2016 21:21:36 +0000 Subject: [PATCH 3899/4131] Change name of the pause DOSBox key to avoid confusion. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3989 --- src/gui/sdlmain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 33c07b21..fa4e96d4 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1415,7 +1415,7 @@ static void GUI_StartUp(Section * sec) { #if C_DEBUG /* Pause binds with activate-debugger */ #else - MAPPER_AddHandler(&PauseDOSBox, MK_pause, MMOD2, "pause", "Pause"); + MAPPER_AddHandler(&PauseDOSBox, MK_pause, MMOD2, "pause", "Pause DBox"); #endif /* Get Keyboard state of numlock and capslock */ SDLMod keystate = SDL_GetModState(); From d94dc4834ec9817668df85844cfcf1f182620301 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 23 Jul 2016 20:31:25 +0000 Subject: [PATCH 3900/4131] zero extend data, fixes LLVM compile where the called function does not extend the parameters. Thanks guiikoza. Fixes at least vesatest.exe of lsl7 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3990 --- src/cpu/core_dynrec/risc_x64.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index 44ccf5a3..e293e95b 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -173,15 +173,15 @@ static INLINE void gen_memaddr(Bitu modreg,void* data,Bitu off,Bitu imm,Bit8u op // move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg // 16bit moves may destroy the upper 16bit of the destination register static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword,Bit8u prefix=0) { - gen_reg_memaddr(dest_reg,data,0x8b,(dword?prefix:0x66)); // mov reg,[data] + if (!dword) gen_reg_memaddr(dest_reg,data,0xb7,0x0f); // movzx reg,[data] - zero extend data, fixes LLVM compile where the called function does not extend the parameters + else gen_reg_memaddr(dest_reg,data,0x8b,prefix); // mov reg,[data] } // move a 16bit constant value into dest_reg // the upper 16bit of the destination register may be destroyed static void gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { - cache_addb(0x66); cache_addb(0xb8+dest_reg); // mov reg,imm - cache_addw(imm); + cache_addd((Bit32u)imm); } // move a 32bit constant value into dest_reg @@ -200,7 +200,7 @@ static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword,Bit8u pr // this function does not use FC_OP1/FC_OP2 as dest_reg as these // registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { - gen_reg_memaddr(dest_reg,data,0x8a); // mov reg, byte [data] + gen_reg_memaddr(dest_reg,data,0xb6,0x0f); // movzx reg,[data] } // move an 8bit value from memory into dest_reg @@ -208,7 +208,7 @@ static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { // this function can use FC_OP1/FC_OP2 as dest_reg which are // not directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { - gen_reg_memaddr(dest_reg,data,0x8b,0x66); // mov reg, word [data] + gen_reg_memaddr(dest_reg,data,0xb6,0x0f); // movzx reg,[data] } // move an 8bit constant value into dest_reg @@ -216,8 +216,8 @@ static void gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { // this function does not use FC_OP1/FC_OP2 as dest_reg as these // registers might not be directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { - cache_addb(0xb0+dest_reg); // mov reg,imm - cache_addb(imm); + cache_addb(0xb8+dest_reg); // mov reg,imm + cache_addd((Bit32u)imm); } // move an 8bit constant value into dest_reg @@ -225,9 +225,8 @@ static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { // this function can use FC_OP1/FC_OP2 as dest_reg which are // not directly byte-accessible on some architectures static void gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { - cache_addb(0x66); cache_addb(0xb8+dest_reg); // mov reg,imm - cache_addw(imm); + cache_addd((Bit32u)imm); } // move the lowest 8bit of a register into memory From 5e4b1c82842b193271eac364e0b7b3478503b49f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Aug 2016 12:07:43 +0000 Subject: [PATCH 3901/4131] Raise lower limit of cycles in autodetermine mode to improve stability. (lsl7) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3991 --- include/cpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cpu.h b/include/cpu.h index 0e2ea7f1..2f27f2c0 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -37,7 +37,7 @@ #define CPU_AUTODETERMINE_SHIFT 0x02 #define CPU_AUTODETERMINE_MASK 0x03 -#define CPU_CYCLES_LOWER_LIMIT 100 +#define CPU_CYCLES_LOWER_LIMIT 200 #define CPU_ARCHTYPE_MIXED 0xff From 4c4f2324736afc69381a37bda3c94a0882efdaf5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 4 Sep 2016 18:47:39 +0000 Subject: [PATCH 3902/4131] XGA_DrawLineBresenham() does not properly sign extend values https://sourceforge.net/p/dosbox/patches/269/ patch by Tom B Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3992 --- src/hardware/vga_xga.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index 922a102d..2cd85059 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -352,11 +352,11 @@ void XGA_DrawLineBresenham(Bitu val) { // Probably a lot easier way to do this, but this works. dminor = (Bits)((Bit16s)xga.desty); - if(xga.desty&0x2000) dminor |= 0xffffe000; + if(xga.desty&0x2000) dminor |= ~0x1fff; dminor >>= 1; destxtmp=(Bits)((Bit16s)xga.destx); - if(xga.destx&0x2000) destxtmp |= 0xffffe000; + if(xga.destx&0x2000) destxtmp |= ~0x1fff; dmajor = -(destxtmp - (dminor << 1)) >> 1; @@ -374,7 +374,7 @@ void XGA_DrawLineBresenham(Bitu val) { sy = -1; } e = (Bits)((Bit16s)xga.ErrTerm); - if(xga.ErrTerm&0x2000) e |= 0xffffe000; + if(xga.ErrTerm&0x2000) e |= ~0x1fff; xat = xga.curx; yat = xga.cury; From 169ca61f9e8b084cf5e54bf4bccd96782c66c854 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 4 Sep 2016 19:04:02 +0000 Subject: [PATCH 3903/4131] fix for 256 color encoding in zmbv.dll codec patch by Avery Lee Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3993 --- src/libs/zmbv/zmbv_vfw.cpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/libs/zmbv/zmbv_vfw.cpp b/src/libs/zmbv/zmbv_vfw.cpp index 9b4c284d..1964546b 100644 --- a/src/libs/zmbv/zmbv_vfw.cpp +++ b/src/libs/zmbv/zmbv_vfw.cpp @@ -300,7 +300,29 @@ DWORD CodecInst::Compress(ICCOMPRESS* icinfo, DWORD dwSize) { if (icinfo->dwFlags & ICCOMPRESS_KEYFRAME) flags |= 1; - codec->PrepareCompressFrame( flags, format, 0, icinfo->lpOutput, 99999999); + char palette[256 * 4]; + char *pal = NULL; + + if (lpbiIn->biBitCount == 8) { + const int entries = icinfo->lpbiInput->biClrUsed ? icinfo->lpbiInput->biClrUsed : 256; + const char* srcpal = (char *)icinfo->lpbiInput + icinfo->lpbiInput->biSize; + char* dstpal = palette; + + memset(palette, 0, sizeof palette); + + for(int i=0; iPrepareCompressFrame( flags, format, pal, icinfo->lpOutput, 99999999); char *readPt = (char *)icinfo->lpInput + pitch*(lpbiIn->biHeight - 1); for(i = 0;ibiHeight;i++) { codec->CompressLines(1, (void **)&readPt ); From eefd825fa1af58ed2af91193b68b6c10f392884f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 7 Sep 2016 20:35:10 +0000 Subject: [PATCH 3904/4131] Add wjp's improved breakpoint handling to the debugger Rewrite the order of the debug help list so the keys come last Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3994 --- src/debug/debug.cpp | 299 +++++++++++++++++++++++++------------------- 1 file changed, 170 insertions(+), 129 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 2a54c3b5..20c39429 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -305,13 +305,16 @@ public: static CBreakpoint* AddBreakpoint (Bit16u seg, Bit32u off, bool once); static CBreakpoint* AddIntBreakpoint (Bit8u intNum, Bit16u ah, Bit16u al, bool once); static CBreakpoint* AddMemBreakpoint (Bit16u seg, Bit32u off); - static void ActivateBreakpoints (PhysPt adr, bool activate); + static void DeactivateBreakpoints(); + static void ActivateBreakpoints (); + static void ActivateBreakpointsExceptAt(PhysPt adr); static bool CheckBreakpoint (PhysPt adr); static bool CheckBreakpoint (Bitu seg, Bitu off); static bool CheckIntBreakpoint (PhysPt adr, Bit8u intNr, Bit16u ahValue, Bit16u alValue); - static bool IsBreakpoint (PhysPt where); - static bool IsBreakpointDrawn (PhysPt where); - static bool DeleteBreakpoint (PhysPt where); + static CBreakpoint* FindPhysBreakpoint (Bit16u seg, Bit32u off, bool once); + static CBreakpoint* FindOtherActiveBreakpoint(PhysPt adr, CBreakpoint* skip); + static bool IsBreakpoint (Bit16u seg, Bit32u off); + static bool DeleteBreakpoint (Bit16u seg, Bit32u off); static bool DeleteByIndex (Bit16u index); static void DeleteAll (void); static void ShowList (void); @@ -333,12 +336,10 @@ private: bool once; static std::list BPoints; -public: - static CBreakpoint* ignoreOnce; }; CBreakpoint::CBreakpoint(void): -location(0), +location(0),oldData(0xCC), active(false),once(false), segment(0),offset(0),intNr(0),ahValue(0),alValue(0), type(BKPNT_UNKNOWN) { }; @@ -346,18 +347,36 @@ type(BKPNT_UNKNOWN) { }; void CBreakpoint::Activate(bool _active) { #if !C_HEAVY_DEBUG - if (GetType()==BKPNT_PHYSICAL) { + if (GetType() == BKPNT_PHYSICAL) { if (_active) { // Set 0xCC and save old value Bit8u data = mem_readb(location); - if (data!=0xCC) { + if (data != 0xCC) { oldData = data; mem_writeb(location,0xCC); + } else if (!active) { + // Another activate breakpoint is already here. + // Find it, and copy its oldData value + CBreakpoint *bp = FindOtherActiveBreakpoint(location, this); + + if (!bp || bp->oldData == 0xCC) { + // This might also happen if there is a real 0xCC instruction here + DEBUG_ShowMsg("DEBUG: Internal error while activating breakpoint.\n"); + oldData = 0xCC; + } else + oldData = bp->oldData; }; } else { - // Remove 0xCC and set old value - if (mem_readb (location)==0xCC) { - mem_writeb(location,oldData); + if (mem_readb(location) == 0xCC) { + if (oldData == 0xCC) + DEBUG_ShowMsg("DEBUG: Internal error while deactivating breakpoint.\n"); + + // Check if we are the last active breakpoint at this location + bool otherActive = (FindOtherActiveBreakpoint(location, this) != 0); + + // If so, remove 0xCC and set old value + if (!otherActive) + mem_writeb(location, oldData); }; } } @@ -367,8 +386,6 @@ void CBreakpoint::Activate(bool _active) // Statics std::list CBreakpoint::BPoints; -CBreakpoint* CBreakpoint::ignoreOnce = 0; -PhysPt ignoreAddressOnce = 0; CBreakpoint* CBreakpoint::AddBreakpoint(Bit16u seg, Bit32u off, bool once) { @@ -398,43 +415,44 @@ CBreakpoint* CBreakpoint::AddMemBreakpoint(Bit16u seg, Bit32u off) return bp; }; -void CBreakpoint::ActivateBreakpoints(PhysPt adr, bool activate) +void CBreakpoint::ActivateBreakpoints() { // activate all breakpoints std::list::iterator i; - CBreakpoint* bp; - for(i=BPoints.begin(); i != BPoints.end(); i++) { - bp = (*i); - // Do not activate, when bp is an actual address - if (activate && (bp->GetType()==BKPNT_PHYSICAL) && (bp->GetLocation()==adr)) { - // Do not activate :) + for (i = BPoints.begin(); i != BPoints.end(); i++) + (*i)->Activate(true); +} + +void CBreakpoint::DeactivateBreakpoints() +{ + // deactivate all breakpoints + std::list::iterator i; + for (i = BPoints.begin(); i != BPoints.end(); i++) + (*i)->Activate(false); +} + +void CBreakpoint::ActivateBreakpointsExceptAt(PhysPt adr) +{ + // activate all breakpoints, except those at adr + std::list::iterator i; + for (i = BPoints.begin(); i != BPoints.end(); i++) { + CBreakpoint* bp = (*i); + // Do not activate breakpoints at adr + if (bp->GetType() == BKPNT_PHYSICAL && bp->GetLocation() == adr) continue; - } - bp->Activate(activate); + bp->Activate(true); }; }; bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off) // Checks if breakpoint is valid and should stop execution { - if ((ignoreAddressOnce!=0) && (GetAddress(seg,off)==ignoreAddressOnce)) { - ignoreAddressOnce = 0; - return false; - } else - ignoreAddressOnce = 0; - // Search matching breakpoint std::list::iterator i; CBreakpoint* bp; for(i=BPoints.begin(); i != BPoints.end(); i++) { bp = (*i); if ((bp->GetType()==BKPNT_PHYSICAL) && bp->IsActive() && (bp->GetSegment()==seg) && (bp->GetOffset()==off)) { - // Ignore Once ? - if (ignoreOnce==bp) { - ignoreOnce=0; - bp->Activate(true); - return false; - }; // Found, if (bp->GetOnce()) { // delete it, if it should only be used once @@ -442,8 +460,14 @@ bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off) bp->Activate(false); delete bp; } else { - ignoreOnce = bp; - }; + // Also look for once-only breakpoints at this address + bp = FindPhysBreakpoint(seg, off, true); + if (bp) { + BPoints.remove(bp); + bp->Activate(false); + delete bp; + } + } return true; } #if C_HEAVY_DEBUG @@ -481,12 +505,6 @@ bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off) bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue, Bit16u alValue) // Checks if interrupt breakpoint is valid and should stop execution { - if ((ignoreAddressOnce!=0) && (adr==ignoreAddressOnce)) { - ignoreAddressOnce = 0; - return false; - } else - ignoreAddressOnce = 0; - // Search matching breakpoint std::list::iterator i; CBreakpoint* bp; @@ -495,19 +513,12 @@ bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue, Bi if ((bp->GetType()==BKPNT_INTERRUPT) && bp->IsActive() && (bp->GetIntNr()==intNr)) { if (((bp->GetValue()==BPINT_ALL) || (bp->GetValue()==ahValue)) && ((bp->GetOther()==BPINT_ALL) || (bp->GetOther()==alValue))) { // Ignore it once ? - if (ignoreOnce==bp) { - ignoreOnce=0; - bp->Activate(true); - return false; - }; // Found if (bp->GetOnce()) { // delete it, if it should only be used once (BPoints.erase)(i); bp->Activate(false); delete bp; - } else { - ignoreOnce = bp; } return true; } @@ -548,56 +559,60 @@ bool CBreakpoint::DeleteByIndex(Bit16u index) return false; }; -bool CBreakpoint::DeleteBreakpoint(PhysPt where) +CBreakpoint* CBreakpoint::FindPhysBreakpoint(Bit16u seg, Bit32u off, bool once) { - // Search matching breakpoint +#if !C_HEAVY_DEBUG + PhysPt adr = GetAddress(seg, off); +#endif + // Search for matching breakpoint std::list::iterator i; CBreakpoint* bp; for(i=BPoints.begin(); i != BPoints.end(); i++) { bp = (*i); - if ((bp->GetType()==BKPNT_PHYSICAL) && (bp->GetLocation()==where)) { - (BPoints.erase)(i); - bp->Activate(false); - delete bp; - return true; - } - }; - return false; -}; +#if C_HEAVY_DEBUG + // Heavy debugging breakpoints are triggered by matching seg:off + bool atLocation = bp->GetSegment() == seg && bp->GetOffset() == off; +#else + // Normal debugging breakpoints are triggered at an address + bool atLocation = bp->GetLocation() == adr; +#endif -bool CBreakpoint::IsBreakpoint(PhysPt adr) -// is there a breakpoint at address ? -{ - // Search matching breakpoint - std::list::iterator i; - CBreakpoint* bp; - for(i=BPoints.begin(); i != BPoints.end(); i++) { - bp = (*i); - if ((bp->GetType()==BKPNT_PHYSICAL) && (bp->GetSegment()==adr)) { - return true; - }; - if ((bp->GetType()==BKPNT_PHYSICAL) && (bp->GetLocation()==adr)) { - return true; - }; - }; - return false; -}; + if (bp->GetType() == BKPNT_PHYSICAL && atLocation && bp->GetOnce() == once) + return bp; + } -bool CBreakpoint::IsBreakpointDrawn(PhysPt adr) -// valid breakpoint, that should be drawn ? + return 0; +} + +CBreakpoint* CBreakpoint::FindOtherActiveBreakpoint(PhysPt adr, CBreakpoint* skip) { - // Search matching breakpoint std::list::iterator i; - CBreakpoint* bp; - for(i=BPoints.begin(); i != BPoints.end(); i++) { - bp = (*i); - if ((bp->GetType()==BKPNT_PHYSICAL) && (bp->GetLocation()==adr)) { - // Only draw, if breakpoint is not only once, - return !bp->GetOnce(); - }; - }; + for (i = BPoints.begin(); i != BPoints.end(); i++) { + CBreakpoint* bp = (*i); + if (bp != skip && bp->GetType() == BKPNT_PHYSICAL && bp->GetLocation() == adr && bp->IsActive()) + return bp; + } + return 0; +} + +// is there a permanent breakpoint at address ? +bool CBreakpoint::IsBreakpoint(Bit16u seg, Bit32u off) +{ + return FindPhysBreakpoint(seg, off, false) != 0; +} + +bool CBreakpoint::DeleteBreakpoint(Bit16u seg, Bit32u off) +{ + CBreakpoint* bp = FindPhysBreakpoint(seg, off, false); + if (bp) { + BPoints.remove(bp); + delete bp; + return true; + } + return false; -}; +} + void CBreakpoint::ShowList(void) { @@ -629,7 +644,7 @@ bool DEBUG_Breakpoint(void) if (!CBreakpoint::CheckBreakpoint(SegValue(cs),reg_eip)) return false; // Found. Breakpoint is valid PhysPt where=GetAddress(SegValue(cs),reg_eip); - CBreakpoint::ActivateBreakpoints(where,false); // Deactivate all breakpoints + CBreakpoint::DeactivateBreakpoints(); // Deactivate all breakpoints return true; }; @@ -639,7 +654,7 @@ bool DEBUG_IntBreakpoint(Bit8u intNum) PhysPt where=GetAddress(SegValue(cs),reg_eip); if (!CBreakpoint::CheckIntBreakpoint(where,intNum,reg_ah,reg_al)) return false; // Found. Breakpoint is valid - CBreakpoint::ActivateBreakpoints(where,false); // Deactivate all breakpoints + CBreakpoint::DeactivateBreakpoints(); // Deactivate all breakpoints return true; }; @@ -651,11 +666,12 @@ static bool StepOver() size=DasmI386(dline, start, reg_eip, cpu.code.big); if (strstr(dline,"call") || strstr(dline,"int") || strstr(dline,"loop") || strstr(dline,"rep")) { - CBreakpoint::AddBreakpoint (SegValue(cs),reg_eip+size, true); - CBreakpoint::ActivateBreakpoints(start, true); + // Don't add a temporary breakpoint if there's already one here + if (!CBreakpoint::FindPhysBreakpoint(SegValue(cs), reg_eip+size, true)) + CBreakpoint::AddBreakpoint(SegValue(cs),reg_eip+size, true); + CBreakpoint::ActivateBreakpointsExceptAt(start); debugging=false; DrawCode(); - DOSBOX_SetNormalLoop(); return true; } return false; @@ -798,7 +814,7 @@ static void DrawCode(void) { codeViewData.cursorSeg = codeViewData.useCS; codeViewData.cursorOfs = disEIP; saveSel = true; - } else if (CBreakpoint::IsBreakpointDrawn(start)) { + } else if (CBreakpoint::IsBreakpoint(codeViewData.useCS, disEIP)) { wattrset(dbg.win_code,COLOR_PAIR(PAIR_GREY_RED)); } else { wattrset(dbg.win_code,0); @@ -1197,8 +1213,7 @@ bool ParseCommand(char* str) { cpuLogCounter = GetHexValue(found,found); debugging = false; - CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); - ignoreAddressOnce = SegPhys(cs)+reg_eip; + CBreakpoint::ActivateBreakpointsExceptAt(SegPhys(cs)+reg_eip); DOSBOX_SetNormalLoop(); return true; }; @@ -1217,7 +1232,7 @@ bool ParseCommand(char* str) { Bit8u intNr = (Bit8u)GetHexValue(found,found); DEBUG_ShowMsg("DEBUG: Starting INT %02X\n",intNr); CBreakpoint::AddBreakpoint(SegValue(cs),reg_eip, true); - CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip-1,true); + CBreakpoint::ActivateBreakpointsExceptAt(SegPhys(cs)+reg_eip-1); debugging = false; DrawCode(); DOSBOX_SetNormalLoop(); @@ -1295,17 +1310,7 @@ bool ParseCommand(char* str) { #endif if (command == "HELP" || command == "?") { DEBUG_ShowMsg("Debugger commands (enter all values in hex or as register):\n"); - DEBUG_ShowMsg("--------------------------------------------------------------------------\n"); - DEBUG_ShowMsg("F3/F6 - Previous command in history.\n"); - DEBUG_ShowMsg("F4/F7 - Next command in history.\n"); - DEBUG_ShowMsg("F5 - Run.\n"); - DEBUG_ShowMsg("F9 - Set/Remove breakpoint.\n"); - DEBUG_ShowMsg("F10/F11 - Step over / trace into instruction.\n"); - DEBUG_ShowMsg("ALT + D/E/S/X/B - Set data view to DS:SI/ES:DI/SS:SP/DS:DX/ES:BX.\n"); - DEBUG_ShowMsg("Escape - Clear input line."); - DEBUG_ShowMsg("Up/Down - Move code view cursor.\n"); - DEBUG_ShowMsg("Page Up/Down - Scroll data view.\n"); - DEBUG_ShowMsg("Home/End - Scroll log messages.\n"); + DEBUG_ShowMsg("Commands------------------------------------------------\n"); DEBUG_ShowMsg("BP [segment]:[offset] - Set breakpoint.\n"); DEBUG_ShowMsg("BPINT [intNr] * - Set interrupt breakpoint.\n"); DEBUG_ShowMsg("BPINT [intNr] [ah] * - Set interrupt breakpoint with ah.\n"); @@ -1351,6 +1356,17 @@ bool ParseCommand(char* str) { DEBUG_ShowMsg("TIMERIRQ - Run the system timer.\n"); DEBUG_ShowMsg("HELP - Help\n"); + DEBUG_ShowMsg("Keys------------------------------------------------\n"); + DEBUG_ShowMsg("F3/F6 - Previous command in history.\n"); + DEBUG_ShowMsg("F4/F7 - Next command in history.\n"); + DEBUG_ShowMsg("F5 - Run.\n"); + DEBUG_ShowMsg("F9 - Set/Remove breakpoint.\n"); + DEBUG_ShowMsg("F10/F11 - Step over / trace into instruction.\n"); + DEBUG_ShowMsg("ALT + D/E/S/X/B - Set data view to DS:SI/ES:DI/SS:SP/DS:DX/ES:BX.\n"); + DEBUG_ShowMsg("Escape - Clear input line."); + DEBUG_ShowMsg("Up/Down - Move code view cursor.\n"); + DEBUG_ShowMsg("Page Up/Down - Scroll data view.\n"); + DEBUG_ShowMsg("Home/End - Scroll log messages.\n"); return true; }; @@ -1535,18 +1551,25 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) { Bit32u DEBUG_CheckKeys(void) { Bits ret=0; bool numberrun = false; + bool skipDraw = false; int key=getch(); if (key >='1' && key <='5' && strlen(codeViewData.inputStr) == 0) { const Bit32s v[] ={5,500,1000,5000,10000}; CPU_Cycles= v[key - '1']; + skipFirstInstruction = true; + ret = (*cpudecoder)(); SetCodeWinStart(); - CBreakpoint::ignoreOnce = 0; /* Setup variables so we end up at the proper ret processing */ numberrun = true; + + // Don't redraw the screen if it's going to get redrawn immediately + // afterwards, to avoid resetting oldregs. + if (ret == debugCallback) + skipDraw = true; key = -1; } @@ -1677,31 +1700,49 @@ Bit32u DEBUG_CheckKeys(void) { break; case KEY_F(5): // Run Program debugging=false; - CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); - ignoreAddressOnce = SegPhys(cs)+reg_eip; - DOSBOX_SetNormalLoop(); + CBreakpoint::ActivateBreakpointsExceptAt(SegPhys(cs)+reg_eip); + + skipFirstInstruction = true; // for heavy debugger + CPU_Cycles = 1; + ret=(*cpudecoder)(); + + // ensure all breakpoints are activated + CBreakpoint::ActivateBreakpoints(); + + skipDraw = true; // don't update screen after this instruction + + DOSBOX_SetNormalLoop(); break; case KEY_F(9): // Set/Remove Breakpoint - { PhysPt ptr = GetAddress(codeViewData.cursorSeg,codeViewData.cursorOfs); - if (CBreakpoint::IsBreakpoint(ptr)) { - CBreakpoint::DeleteBreakpoint(ptr); + if (CBreakpoint::IsBreakpoint(codeViewData.cursorSeg, codeViewData.cursorOfs)) { + if (CBreakpoint::DeleteBreakpoint(codeViewData.cursorSeg, codeViewData.cursorOfs)) DEBUG_ShowMsg("DEBUG: Breakpoint deletion success.\n"); - } - else { - CBreakpoint::AddBreakpoint(codeViewData.cursorSeg, codeViewData.cursorOfs, false); - DEBUG_ShowMsg("DEBUG: Set breakpoint at %04X:%04X\n",codeViewData.cursorSeg,codeViewData.cursorOfs); - } + else + DEBUG_ShowMsg("DEBUG: Failed to delete breakpoint.\n"); + } + else { + CBreakpoint::AddBreakpoint(codeViewData.cursorSeg, codeViewData.cursorOfs, false); + DEBUG_ShowMsg("DEBUG: Set breakpoint at %04X:%04X\n",codeViewData.cursorSeg,codeViewData.cursorOfs); } break; case KEY_F(10): // Step over inst - if (StepOver()) return 0; - else { + if (StepOver()) { + skipFirstInstruction = true; // for heavy debugger + CPU_Cycles = 1; + ret=(*cpudecoder)(); + + DOSBOX_SetNormalLoop(); + + // ensure all breakpoints are activated + CBreakpoint::ActivateBreakpoints(); + + return 0; + } else { exitLoop = false; skipFirstInstruction = true; // for heavy debugger CPU_Cycles = 1; ret=(*cpudecoder)(); SetCodeWinStart(); - CBreakpoint::ignoreOnce = 0; } break; case KEY_F(11): // trace into @@ -1710,7 +1751,6 @@ Bit32u DEBUG_CheckKeys(void) { CPU_Cycles = 1; ret = (*cpudecoder)(); SetCodeWinStart(); - CBreakpoint::ignoreOnce = 0; break; case 0x0A: //Parse typed Command codeViewData.inputStr[MAXCMDLEN] = '\0'; @@ -1773,7 +1813,8 @@ Bit32u DEBUG_CheckKeys(void) { } } ret=0; - DEBUG_DrawScreen(); + if (!skipDraw) + DEBUG_DrawScreen(); } return ret; }; @@ -1788,7 +1829,7 @@ Bitu DEBUG_Loop(void) { SDL_Delay(1); if ((oldCS!=SegValue(cs)) || (oldEIP!=reg_eip)) { CBreakpoint::AddBreakpoint(oldCS,oldEIP,true); - CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); + CBreakpoint::ActivateBreakpointsExceptAt(SegPhys(cs)+reg_eip); debugging=false; DOSBOX_SetNormalLoop(); return 0; @@ -2112,7 +2153,7 @@ void DEBUG_CheckExecuteBreakpoint(Bit16u seg, Bit32u off) { if (pDebugcom && pDebugcom->IsActive()) { CBreakpoint::AddBreakpoint(seg,off,true); - CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true); + CBreakpoint::ActivateBreakpointsExceptAt(SegPhys(cs)+reg_eip); pDebugcom = 0; }; }; From cadf69ac32155303b2a885ab0abd1026cf54c1df Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Thu, 8 Sep 2016 15:37:59 +0000 Subject: [PATCH 3905/4131] Fix debugger "running" status message when resuming emulation with F5. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3995 --- src/debug/debug.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 20c39429..4dabbfcc 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1700,6 +1700,7 @@ Bit32u DEBUG_CheckKeys(void) { break; case KEY_F(5): // Run Program debugging=false; + DrawCode(); // update code window to show "running" status CBreakpoint::ActivateBreakpointsExceptAt(SegPhys(cs)+reg_eip); skipFirstInstruction = true; // for heavy debugger From 07f461da7ecc4504165bb0a208900d1c7041882b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 20 Sep 2016 14:57:46 +0000 Subject: [PATCH 3906/4131] Clip to boundaries when there are no suggested values for Prop_int. Revert r3986 as this commit fixes the problem in a different way. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3996 --- include/setup.h | 18 ++++++++++++---- src/dosbox.cpp | 2 +- src/misc/setup.cpp | 51 +++++++++++++++++++++++++++++++++++++--------- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/include/setup.h b/include/setup.h index 006cef67..7dc9f401 100644 --- a/include/setup.h +++ b/include/setup.h @@ -129,19 +129,26 @@ public: virtual bool 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; + //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. - bool SetVal(Value const& in, bool forced,bool warn=true) { - if(forced || CheckValue(in,warn)) {value = in; return true;} else { value = default_value; return false;}} +public: virtual ~Property(){ } virtual const std::vector& GetValues() const; Value::Etype Get_type(){return default_value.type;} Changeable::Value getChange() {return change;} protected: + //Set interval value to in or default if in is invalid. force always sets the value. + //Can be overriden to set a different value if invalid. + virtual bool SetVal(Value const& in, bool forced,bool warn=true) { + if(forced || CheckValue(in,warn)) { + value = in; return true; + } else { + value = default_value; return false; + } + } Value value; std::vector suggested_values; typedef std::vector::iterator iter; @@ -168,6 +175,9 @@ public: bool SetValue(std::string const& in); ~Prop_int(){ } virtual bool CheckValue(Value const& in, bool warn); + // Override SetVal, so it takes min,max in account when there are no suggested values + virtual bool SetVal(Value const& in, bool forced,bool warn=true); + private: Value min,max; }; diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 675e90da..1462fae3 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -370,7 +370,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&MEM_Init);//done secprop->AddInitFunction(&HARDWARE_Init);//done Pint = secprop->Add_int("memsize", Property::Changeable::WhenIdle,16); - Pint->SetMinMax(1,64); + Pint->SetMinMax(1,63); Pint->Set_help( "Amount of memory DOSBox has in megabytes.\n" " This value is best left at its default to avoid problems with some games,\n" diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index eea76a20..9ea232ba 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -227,7 +227,7 @@ bool Property::CheckValue(Value const& in, bool warn){ return true; } } - if(warn) LOG_MSG("\"%s\" is not a valid value for variable: %s.\nIt might now be reset to the default value: %s",in.ToString().c_str(),propname.c_str(),default_value.ToString().c_str()); + if (warn) LOG_MSG("\"%s\" is not a valid value for variable: %s.\nIt might now be reset to the default value: %s",in.ToString().c_str(),propname.c_str(),default_value.ToString().c_str()); return false; } @@ -243,18 +243,51 @@ char const* Property::Get_help() { return MSG_Get(result.c_str()); } +bool Prop_int::SetVal(Value const& in, bool forced, bool warn) { + if (forced) { + value = in; + return true; + } else if (!suggested_values.empty()){ + if ( CheckValue(in,warn) ) { + value = in; + return true; + } else { + value = default_value; + return false; + } + } else { + //Handle ranges if specified + int mi = min; + int ma = max; + int va = static_cast(Value(in)); + + //No ranges + if (mi == -1 && ma == -1) { value = in; return true;} + //Inside range + if (va >= mi && va <= ma) { value = in; return true;} + + //Outside range, set it to the closest boundary + if (va > ma ) va = ma; else va = mi; + + if (warn) LOG_MSG("%s is outside the allowed range %s-%s for variable: %s.\nIt has been set to the closest boundary: %d.",in.ToString().c_str(),min.ToString().c_str(),max.ToString().c_str(),propname.c_str(),va); + + value = va; + return true; + } +} bool Prop_int::CheckValue(Value const& in, bool warn) { // if(!suggested_values.empty() && Property::CheckValue(in,warn)) return true; if(!suggested_values.empty()) return Property::CheckValue(in,warn); - + LOG_MSG("still used ?"); //No >= and <= in Value type and == is ambigious int mi = min; int ma = max; int va = static_cast(Value(in)); - if(mi == -1 && ma == -1) return true; + if (mi == -1 && ma == -1) return true; if (va >= mi && va <= ma) return true; - if(warn) LOG_MSG("%s lies outside the range %s-%s for variable: %s.\nIt might now be reset to the default value: %s",in.ToString().c_str(),min.ToString().c_str(),max.ToString().c_str(),propname.c_str(),default_value.ToString().c_str()); + + if (warn) LOG_MSG("%s lies outside the range %s-%s for variable: %s.\nIt might now be reset to the default value: %s",in.ToString().c_str(),min.ToString().c_str(),max.ToString().c_str(),propname.c_str(),default_value.ToString().c_str()); return false; } @@ -581,7 +614,6 @@ void trim(string& in) { if(loc != string::npos) in.erase(loc+1); } -//TODO double c_str bool Section_prop::HandleInputline(string const& gegevens){ string str1 = gegevens; string::size_type loc = str1.find('='); @@ -613,7 +645,6 @@ void Section_prop::PrintData(FILE* outfile) const { } } -//TODO geen noodzaak voor 2 keer c_str string Section_prop::GetPropValue(string const& _property) const{ for(const_it tel=properties.begin();tel!=properties.end();tel++){ if(!strcasecmp((*tel)->propname.c_str(),_property.c_str())){ @@ -642,16 +673,16 @@ bool Config::PrintConfig(char const * const configfilename) const { FILE* outfile=fopen(configfilename,"w+t"); if(outfile==NULL) return false; - /* Print start of configfile and add an return to improve readibility. */ + /* Print start of configfile and add a return to improve readibility. */ fprintf(outfile,MSG_Get("CONFIGFILE_INTRO"),VERSION); fprintf(outfile,"\n"); for (const_it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ /* Print out the Section header */ - Section_prop *sec = dynamic_cast(*tel); strcpy(temp,(*tel)->GetName()); lowcase(temp); fprintf(outfile,"[%s]\n",temp); + Section_prop *sec = dynamic_cast(*tel); if (sec) { Property *p; size_t i = 0, maxwidth = 0; @@ -719,7 +750,7 @@ Section_prop* Config::AddSection_prop(char const * const _name,void (*_initfunct } Section_prop::~Section_prop() { -//ExecuteDestroy should be here else the destroy functions use destroyed properties + //ExecuteDestroy should be here else the destroy functions use destroyed properties ExecuteDestroy(true); /* Delete properties themself (properties stores the pointer of a prop */ for(it prop = properties.begin(); prop != properties.end(); prop++) @@ -781,7 +812,7 @@ Section* Config::GetSection(int index){ } return NULL; } -//c_str() 2x + Section* Config::GetSection(string const& _sectionname) const{ for (const_it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ if (!strcasecmp((*tel)->GetName(),_sectionname.c_str())) return (*tel); From 397e38a73a7e98874f5bac1115c93ed333ce49ee Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 20 Sep 2016 14:59:06 +0000 Subject: [PATCH 3907/4131] Improve readability of auto cycles information bit. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3997 --- src/cpu/cpu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 2398fafa..29149972 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1566,7 +1566,7 @@ void CPU_SET_CRX(Bitu cr,Bitu value) { GFX_SetTitle(CPU_CyclePercUsed,-1,false); if(!printed_cycles_auto_info) { printed_cycles_auto_info = true; - LOG_MSG("DOSBox switched to max cycles, because of the setting: cycles=auto. If the game runs too fast try a fixed cycles amount in DOSBox's options."); + LOG_MSG("DOSBox has switched to max cycles, because of the setting: cycles=auto.\nIf the game runs too fast, try a fixed cycles amount in DOSBox's options."); } } else { GFX_SetTitle(-1,-1,false); From b9b9e2c7d10af6ec6140d445039be2d708ac86db Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 21 Sep 2016 18:11:04 +0000 Subject: [PATCH 3908/4131] Fix some issues with debugger after last patch Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3998 --- src/debug/debug.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 4dabbfcc..73e40ab0 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -669,7 +669,6 @@ static bool StepOver() // Don't add a temporary breakpoint if there's already one here if (!CBreakpoint::FindPhysBreakpoint(SegValue(cs), reg_eip+size, true)) CBreakpoint::AddBreakpoint(SegValue(cs),reg_eip+size, true); - CBreakpoint::ActivateBreakpointsExceptAt(start); debugging=false; DrawCode(); return true; @@ -1701,7 +1700,6 @@ Bit32u DEBUG_CheckKeys(void) { case KEY_F(5): // Run Program debugging=false; DrawCode(); // update code window to show "running" status - CBreakpoint::ActivateBreakpointsExceptAt(SegPhys(cs)+reg_eip); skipFirstInstruction = true; // for heavy debugger CPU_Cycles = 1; @@ -1738,14 +1736,9 @@ Bit32u DEBUG_CheckKeys(void) { CBreakpoint::ActivateBreakpoints(); return 0; - } else { - exitLoop = false; - skipFirstInstruction = true; // for heavy debugger - CPU_Cycles = 1; - ret=(*cpudecoder)(); - SetCodeWinStart(); } - break; + // If we aren't stepping over something, do a normal step. + // NB: Fall-through case KEY_F(11): // trace into exitLoop = false; skipFirstInstruction = true; // for heavy debugger From a3345eed2430c18dc4c1b5ec1fcebe874424c9e3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 2 Oct 2016 14:12:32 +0000 Subject: [PATCH 3909/4131] Spaces in LOG_MSG and some at the end of the line. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3999 --- src/gui/midi.cpp | 20 ++++++++-------- src/gui/midi_win32.h | 10 ++++---- src/gui/sdlmain.cpp | 54 +++++++++++++++++++++--------------------- src/hardware/mixer.cpp | 20 ++++++++-------- src/ints/ems.cpp | 52 ++++++++++++++++++++-------------------- src/shell/shell.cpp | 50 +++++++++++++++++++------------------- 6 files changed, 103 insertions(+), 103 deletions(-) diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index e7cc6d42..57181e00 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -104,10 +104,10 @@ void MIDI_RawOutByte(Bit8u data) { midi.rt_buf[0]=data; midi.handler->PlayMsg(midi.rt_buf); return; - } + } /* Test for a active sysex tranfer */ if (midi.status==0xf0) { - if (!(data&0x80)) { + if (!(data&0x80)) { if (midi.sysex.used<(SYSEX_SIZE-1)) midi.sysex.buf[midi.sysex.used++] = data; return; } else { @@ -175,7 +175,7 @@ public: if (fullconf.find("delaysysex") != std::string::npos) { midi.sysex.start = GetTicks(); fullconf.erase(fullconf.find("delaysysex")); - LOG_MSG("MIDI:Using delayed SysEx processing"); + LOG_MSG("MIDI: Using delayed SysEx processing"); } std::remove(fullconf.begin(), fullconf.end(), ' '); const char * conf = fullconf.c_str(); @@ -187,24 +187,24 @@ public: while (handler) { if (!strcasecmp(dev,handler->GetName())) { if (!handler->Open(conf)) { - LOG_MSG("MIDI:Can't open device:%s with config:%s.",dev,conf); + LOG_MSG("MIDI: Can't open device:%s with config:%s.",dev,conf); goto getdefault; } midi.handler=handler; - midi.available=true; - LOG_MSG("MIDI:Opened device:%s",handler->GetName()); + midi.available=true; + LOG_MSG("MIDI: Opened device:%s",handler->GetName()); return; } handler=handler->next; } - LOG_MSG("MIDI:Can't find device:%s, finding default handler.",dev); -getdefault: + LOG_MSG("MIDI: Can't find device:%s, finding default handler.",dev); +getdefault: handler=handler_list; while (handler) { if (handler->Open(conf)) { - midi.available=true; + midi.available=true; midi.handler=handler; - LOG_MSG("MIDI:Opened device:%s",handler->GetName()); + LOG_MSG("MIDI: Opened device:%s",handler->GetName()); return; } handler=handler->next; diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index a34451cb..670027ee 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -46,7 +46,7 @@ public: if(nummer < midiOutGetNumDevs()){ MIDIOUTCAPS mididev; midiOutGetDevCaps(nummer, &mididev, sizeof(MIDIOUTCAPS)); - LOG_MSG("MIDI:win32 selected %s",mididev.szPname); + LOG_MSG("MIDI: win32 selected %s",mididev.szPname); res = midiOutOpen(&m_out, nummer, (DWORD_PTR)m_event, 0, CALLBACK_EVENT); } } else { @@ -70,9 +70,9 @@ public: if (WaitForSingleObject (m_event, 2000) == WAIT_TIMEOUT) { LOG(LOG_MISC,LOG_ERROR)("Can't send midi message"); return; - } + } midiOutUnprepareHeader (m_out, &m_hdr, sizeof (m_hdr)); - + m_hdr.lpData = (char *) sysex; m_hdr.dwBufferLength = len ; m_hdr.dwBytesRecorded = len ; @@ -88,7 +88,7 @@ public: } } void ListAll(Program* base) { - unsigned int total = midiOutGetNumDevs(); + unsigned int total = midiOutGetNumDevs(); for(unsigned int i = 0;i < total;i++) { MIDIOUTCAPS mididev; midiOutGetDevCaps(i, &mididev, sizeof(MIDIOUTCAPS)); @@ -97,6 +97,6 @@ public: } }; -MidiHandler_win32 Midi_win32; +MidiHandler_win32 Midi_win32; diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index fa4e96d4..ad1d427b 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -235,7 +235,7 @@ SDL_Surface* SDL_SetVideoMode_Wrap(int width,int height,int bpp,Bit32u flags){ #if SETMODE_SAVES_CLEAR //TODO clear it. #ifdef C_OPENGL - if ((flags & SDL_OPENGL)==0) + if ((flags & SDL_OPENGL)==0) SDL_FillRect(sdl.surface,NULL,SDL_MapRGB(sdl.surface->format,0,0,0)); else { glClearColor (0.0, 0.0, 0.0, 1.0); @@ -355,7 +355,7 @@ static void PauseDOSBox(bool pressed) { /* On macs, all aps exit when pressing cmd-q */ KillSwitch(true); break; - } + } #endif } } @@ -478,13 +478,13 @@ static SDL_Surface * GFX_SetupSurfaceScaled(Bit32u sdl_flags, Bit32u bpp) { if ( ratio_w < ratio_h) { sdl.clip.w=fixedWidth; sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley*ratio_w + 0.1); //possible rounding issues - } else { - /* + } else { + /* * The 0.4 is there to correct for rounding issues. - * (partly caused by the rounding issues fix in RENDER_SetSize) - */ + * (partly caused by the rounding issues fix in RENDER_SetSize) + */ sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex*ratio_h + 0.4); - sdl.clip.h=(Bit16u)fixedHeight; + sdl.clip.h=(Bit16u)fixedHeight; } if (sdl.desktop.fullscreen) sdl.surface = SDL_SetVideoMode_Wrap(fixedWidth,fixedHeight,bpp,sdl_flags); @@ -660,7 +660,7 @@ dosurface: if (!GFX_SetupSurfaceScaled(0,0)) goto dosurface; sdl.overlay=SDL_CreateYUVOverlay(width*2,height,SDL_UYVY_OVERLAY,sdl.surface); if (!sdl.overlay) { - LOG_MSG("SDL:Failed to create overlay, switching back to surface"); + LOG_MSG("SDL: Failed to create overlay, switching back to surface"); goto dosurface; } sdl.desktop.type=SCREEN_OVERLAY; @@ -679,7 +679,7 @@ dosurface: if (!(flags&GFX_CAN_32) || (flags & GFX_RGBONLY)) goto dosurface; int texsize=2 << int_log2(width > height ? width : height); if (texsize>sdl.opengl.max_texsize) { - LOG_MSG("SDL:OPENGL:No support for texturesize of %d, falling back to surface",texsize); + LOG_MSG("SDL:OPENGL: No support for texturesize of %d, falling back to surface",texsize); goto dosurface; } SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); @@ -688,7 +688,7 @@ dosurface: #endif GFX_SetupSurfaceScaled(SDL_OPENGL,0); if (!sdl.surface || sdl.surface->format->BitsPerPixel<15) { - LOG_MSG("SDL:OPENGL:Can't open drawing surface, are you running in 16bpp(or higher) mode?"); + LOG_MSG("SDL:OPENGL: Can't open drawing surface, are you running in 16bpp (or higher) mode?"); goto dosurface; } /* Create the texture and display list */ @@ -804,7 +804,7 @@ void sticky_keys(bool restore){ if (!inited){ inited = true; SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(STICKYKEYS), &stick_keys, 0); - } + } if (restore) { SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &stick_keys, 0); return; @@ -828,7 +828,7 @@ void GFX_SwitchFullScreen(void) { #endif } else { if (sdl.mouse.locked) GFX_CaptureMouse(); -#if defined (WIN32) +#if defined (WIN32) sticky_keys(true); //restore sticky keys to default state in windowed mode. #endif } @@ -979,7 +979,7 @@ void GFX_EndUpdate( const Bit16u *changedLines ) { IDirectDrawSurface3_Restore(sdl.surface->hwdata->dd_surface); break; default: - LOG_MSG("DDRAW:Failed to blit, error %X",ret); + LOG_MSG("DDRAW: Failed to blit, error %X",ret); } SDL_Flip(sdl.surface); break; @@ -1288,7 +1288,7 @@ static void GUI_StartUp(Section * sec) { sdl.opengl.bilinear=false; #endif } else { - LOG_MSG("SDL:Unsupported output device %s, switching back to surface",output.c_str()); + LOG_MSG("SDL: Unsupported output device %s, switching back to surface",output.c_str()); sdl.desktop.want_type=SCREEN_SURFACE;//SHOULDN'T BE POSSIBLE anymore } @@ -1330,7 +1330,7 @@ static void GUI_StartUp(Section * sec) { if (sdl.surface == NULL) E_Exit("Could not initialize video: %s",SDL_GetError()); sdl.desktop.bpp=sdl.surface->format->BitsPerPixel; if (sdl.desktop.bpp==24) { - LOG_MSG("SDL:You are running in 24 bpp mode, this will slow down things!"); + LOG_MSG("SDL: You are running in 24 bpp mode, this will slow down things!"); } GFX_Stop(); SDL_WM_SetCaption("DOSBox",VERSION); @@ -1606,14 +1606,14 @@ void GFX_Events() { // ignore tab events that arrive just after regaining focus. (likely the result of alt-tab) if ((event.key.keysym.sym == SDLK_TAB) && (GetTicks() - sdl.focus_ticks < 2)) break; #endif -#if defined (MACOSX) +#if defined (MACOSX) case SDL_KEYDOWN: case SDL_KEYUP: /* On macs CMD-Q is the default key to close an application */ if (event.key.keysym.sym == SDLK_q && (event.key.keysym.mod == KMOD_RMETA || event.key.keysym.mod == KMOD_LMETA) ) { KillSwitch(true); break; - } + } #endif default: void MAPPER_CheckEvent(SDL_Event * event); @@ -1663,7 +1663,7 @@ void Config_Add_SDL() { Pbool = sdl_sec->Add_bool("fullscreen",Property::Changeable::Always,false); Pbool->Set_help("Start dosbox directly in fullscreen. (Press ALT-Enter to go back)"); - + Pbool = sdl_sec->Add_bool("fulldouble",Property::Changeable::Always,false); Pbool->Set_help("Use double buffering in fullscreen. It can reduce screen flickering, but it can also result in a slow DOSBox."); @@ -1736,7 +1736,7 @@ static void show_warning(char const * const message) { Bit32u bmask = 0x0000ff00; #else Bit32u rmask = 0x000000ff; - Bit32u gmask = 0x0000ff00; + Bit32u gmask = 0x0000ff00; Bit32u bmask = 0x00ff0000; #endif SDL_Surface* splash_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, 640, 400, 32, rmask, gmask, bmask, 0); @@ -1745,22 +1745,22 @@ static void show_warning(char const * const message) { int x = 120,y = 20; std::string m(message),m2; std::string::size_type a,b,c,d; - + while(m.size()) { //Max 50 characters. break on space before or on a newline c = m.find('\n'); d = m.rfind(' ',50); if(c>d) a=b=d; else a=b=c; - if( a != std::string::npos) b++; + if( a != std::string::npos) b++; m2 = m.substr(0,a); m.erase(0,b); OutputString(x,y,m2.c_str(),0xffffffff,0,splash_surf); y += 20; } - + SDL_BlitSurface(splash_surf, NULL, sdl.surface, NULL); SDL_Flip(sdl.surface); SDL_Delay(12000); } - + static void launcheditor() { std::string path,file; Cross::CreatePlatformConfigDir(path); @@ -1852,7 +1852,7 @@ static void printconfiglocation() { Cross::CreatePlatformConfigDir(path); Cross::GetPlatformConfigName(file); path += file; - + FILE* f = fopen(path.c_str(),"r"); if(!f && !control->PrintConfig(path.c_str())) { printf("tried creating %s. but failed",path.c_str()); @@ -1916,7 +1916,7 @@ int main(int argc, char* argv[]) { if(control->cmdline->FindExist("-resetconf")) eraseconfigfile(); if(control->cmdline->FindExist("-erasemapper")) erasemapperfile(); if(control->cmdline->FindExist("-resetmapper")) erasemapperfile(); - + /* Can't disable the console with debugger enabled */ #if defined(WIN32) && !(C_DEBUG) if (control->cmdline->FindExist("-noconsole")) { @@ -2028,7 +2028,7 @@ int main(int argc, char* argv[]) { /* Parse configuration files */ std::string config_file,config_path; Cross::GetPlatformConfigDir(config_path); - + //First parse -userconf if(control->cmdline->FindExist("-userconf",true)){ config_file.clear(); @@ -2131,7 +2131,7 @@ int main(int argc, char* argv[]) { } #if defined (WIN32) sticky_keys(true); //Might not be needed if the shutdown function switches to windowed mode, but it doesn't hurt -#endif +#endif //Force visible mouse to end user. Somehow this sometimes doesn't happen SDL_WM_GrabInput(SDL_GRAB_OFF); SDL_ShowCursor(SDL_ENABLE); diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 41ebcc2b..9a6ffcdd 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -17,7 +17,7 @@ */ -/* +/* Remove the sdl code from here and have it handeld in the sdlmain. That should call the mixer start from there or something. */ @@ -261,7 +261,7 @@ thestart: void MixerChannel::AddStretched(Bitu len,Bit16s * data) { if (done>=needed) { - LOG_MSG("Can't add, buffer full"); + LOG_MSG("Can't add, buffer full"); return; } Bitu outlen=needed-done;Bits diff; @@ -349,7 +349,7 @@ void MixerChannel::FillUp(void) { extern bool ticksLocked; static inline bool Mixer_irq_important(void) { - /* In some states correct timing of the irqs is more important then + /* In some states correct timing of the irqs is more important then * non stuttering audo */ return (ticksLocked || (CaptureState & (CAPTURE_WAVE|CAPTURE_VIDEO))); } @@ -364,7 +364,7 @@ static void MIXER_MixData(Bitu needed) { if (CaptureState & (CAPTURE_WAVE|CAPTURE_VIDEO)) { Bit16s convert[1024][2]; Bitu added=needed-mixer.done; - if (added>1024) + if (added>1024) added=1024; Bitu readpos=(mixer.pos+mixer.done)&MIXER_BUFMASK; for (Bitu i=0;i MIXER_BUFSIZE) index_add = MIXER_BUFSIZE - 2*mixer.min_needed; - else + else index_add = mixer.done - 2*mixer.min_needed; index_add = (index_add << MIXER_SHIFT) / need; reduce = mixer.done - 2* mixer.min_needed; @@ -476,7 +476,7 @@ static void SDLCALL MIXER_CallBack(void * userdata, Uint8 *stream, int len) { if (chan->done>reduce) chan->done-=reduce; else chan->done=0; } - + // Reset mixer.tick_add when irqs are important if( Mixer_irq_important() ) mixer.tick_add=(mixer.freq<< MIXER_SHIFT)/1000; @@ -566,7 +566,7 @@ public: chan=mixer.channels; WriteOut("Channel Main Main(dB)\n"); ShowVolume("MASTER",mixer.mastervol[0],mixer.mastervol[1]); - for (chan=mixer.channels;chan;chan=chan->next) + for (chan=mixer.channels;chan;chan=chan->next) ShowVolume(chan->name,chan->volmain[0],chan->volmain[1]); } private: @@ -635,17 +635,17 @@ void MIXER_Init(Section* sec) { mixer.tick_remain=0; if (mixer.nosound) { - LOG_MSG("MIXER:No Sound Mode Selected."); + LOG_MSG("MIXER: No Sound Mode Selected."); mixer.tick_add=((mixer.freq) << MIXER_SHIFT)/1000; TIMER_AddTickHandler(MIXER_Mix_NoSound); } else if (SDL_OpenAudio(&spec, &obtained) <0 ) { mixer.nosound = true; - LOG_MSG("MIXER:Can't open audio: %s , running in nosound mode.",SDL_GetError()); + LOG_MSG("MIXER: Can't open audio: %s , running in nosound mode.",SDL_GetError()); mixer.tick_add=((mixer.freq) << MIXER_SHIFT)/1000; TIMER_AddTickHandler(MIXER_Mix_NoSound); } else { if((mixer.freq != obtained.freq) || (mixer.blocksize != obtained.samples)) - LOG_MSG("MIXER:Got different values from SDL: freq %d, blocksize %d",obtained.freq,obtained.samples); + LOG_MSG("MIXER: Got different values from SDL: freq %d, blocksize %d",obtained.freq,obtained.samples); mixer.freq=obtained.freq; mixer.blocksize=obtained.samples; mixer.tick_add=(mixer.freq << MIXER_SHIFT)/1000; diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 3d2e1d74..2b70e828 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -95,7 +95,7 @@ static EMM_Mapping emm_mappings[EMM_MAX_PHYS]; static EMM_Mapping emm_segmentmappings[0x40]; -static Bit16u GEMMIS_seg; +static Bit16u GEMMIS_seg; class device_EMM : public DOS_Device { public: @@ -105,8 +105,8 @@ public: GEMMIS_seg=0; } bool Read(Bit8u * /*data*/,Bit16u * /*size*/) { return false;} - bool Write(Bit8u * /*data*/,Bit16u * /*size*/){ - LOG(LOG_IOCTL,LOG_NORMAL)("EMS:Write to device"); + bool Write(Bit8u * /*data*/,Bit16u * /*size*/){ + LOG(LOG_IOCTL,LOG_NORMAL)("EMS:Write to device"); return false; } bool Seek(Bit32u * /*pos*/,Bit32u /*type*/){return false;} @@ -119,7 +119,7 @@ private: bool is_emm386; }; -bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode) { +bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode) { Bitu subfct=mem_readb(bufptr); switch (subfct) { case 0x00: @@ -301,19 +301,19 @@ static Bit8u EMM_MapPage(Bitu phys_page,Bit16u handle,Bit16u log_page) { /* Unmapping */ emm_mappings[phys_page].handle=NULL_HANDLE; emm_mappings[phys_page].page=NULL_PAGE; - for (Bitu i=0;i<4;i++) + for (Bitu i=0;i<4;i++) PAGING_MapPage(EMM_PAGEFRAME4K+phys_page*4+i,EMM_PAGEFRAME4K+phys_page*4+i); PAGING_ClearTLB(); return EMM_NO_ERROR; } /* Check for valid handle */ if (!ValidHandle(handle)) return EMM_INVALID_HANDLE; - + if (log_page>10].handle=NULL_HANDLE; emm_segmentmappings[segment>>10].page=NULL_PAGE; } - for (Bitu i=0;i<4;i++) + for (Bitu i=0;i<4;i++) PAGING_MapPage(segment*16/4096+i,segment*16/4096+i); PAGING_ClearTLB(); return EMM_NO_ERROR; } /* Check for valid handle */ if (!ValidHandle(handle)) return EMM_INVALID_HANDLE; - + if (log_page=0) && (tphysPage>10].handle=handle; emm_segmentmappings[segment>>10].page=log_page; } - + MemHandle memh=MEM_NextHandleAt(emm_handles[handle].mem,log_page*4);; for (Bitu i=0;i<4;i++) { PAGING_MapPage(segment*16/4096+i,memh); @@ -697,7 +697,7 @@ static Bitu INT67_Handler(void) { Bitu i; switch (reg_ah) { case 0x40: /* Get Status */ - reg_ah=EMM_NO_ERROR; + reg_ah=EMM_NO_ERROR; break; case 0x41: /* Get PageFrame Segment */ reg_bx=EMM_PAGEFRAME; @@ -754,7 +754,7 @@ static Bitu INT67_Handler(void) { MEM_BlockWrite(SegPhys(es)+reg_di,emm_mappings,sizeof(emm_mappings)); MEM_BlockRead(SegPhys(ds)+reg_si,emm_mappings,sizeof(emm_mappings)); reg_ah=EMM_RestoreMappingTable(); - break; + break; case 0x03: /* Get Page Map Array Size */ reg_al=sizeof(emm_mappings); reg_ah=EMM_NO_ERROR; @@ -780,7 +780,7 @@ static Bitu INT67_Handler(void) { if (reg_ah!=EMM_NO_ERROR) break; }; } break; - case 0x01: // use segment address + case 0x01: // use segment address { PhysPt data = SegPhys(ds)+reg_si; for (int i=0; i>16; @@ -981,8 +981,8 @@ static Bitu INT67_Handler(void) { /* Load tables and initialize segment registers */ CPU_LGDT(new_gdt_limit, new_gdt_base); CPU_LIDT(new_idt_limit, new_idt_base); - if (CPU_LLDT(new_ldt)) LOG_MSG("VCPI:Could not load LDT with %x",new_ldt); - if (CPU_LTR(new_tr)) LOG_MSG("VCPI:Could not load TR with %x",new_tr); + if (CPU_LLDT(new_ldt)) LOG_MSG("VCPI: Could not load LDT with %x",new_ldt); + if (CPU_LTR(new_tr)) LOG_MSG("VCPI: Could not load TR with %x",new_tr); CPU_SetSegGeneral(ds,0); CPU_SetSegGeneral(es,0); @@ -1050,8 +1050,8 @@ static Bitu VCPI_PM_Handler() { /* Load descriptor table registers */ CPU_LGDT(0xff, vcpi.private_area+0x0000); CPU_LIDT(0x7ff, vcpi.private_area+0x2000); - if (CPU_LLDT(0x08)) LOG_MSG("VCPI:Could not load LDT"); - if (CPU_LTR(0x10)) LOG_MSG("VCPI:Could not load TR"); + if (CPU_LLDT(0x08)) LOG_MSG("VCPI: Could not load LDT"); + if (CPU_LTR(0x10)) LOG_MSG("VCPI: Could not load TR"); reg_flags&=(~FLAG_NT); reg_esp+=8; // skip interrupt return information @@ -1322,7 +1322,7 @@ public: vcpi.enabled=false; GEMMIS_seg=0; - + Section_prop * section=static_cast(configuration); ems_type=GetEMSType(section); if (ems_type<=0) return; @@ -1399,8 +1399,8 @@ public: CPU_SET_CRX(0, 1); CPU_LGDT(0xff, vcpi.private_area+0x0000); CPU_LIDT(0x7ff, vcpi.private_area+0x2000); - if (CPU_LLDT(0x08)) LOG_MSG("VCPI:Could not load LDT"); - if (CPU_LTR(0x10)) LOG_MSG("VCPI:Could not load TR"); + if (CPU_LLDT(0x08)) LOG_MSG("VCPI: Could not load LDT"); + if (CPU_LTR(0x10)) LOG_MSG("VCPI: Could not load TR"); CPU_Push32(SegValue(gs)); CPU_Push32(SegValue(fs)); @@ -1416,13 +1416,13 @@ public: } } } - + ~EMS() { if (ems_type<=0) return; /* Undo Biosclearing */ BIOS_ZeroExtendedSize(false); - + /* Remove ems device */ if (emm_device!=NULL) { DOS_DelDevice(emm_device); @@ -1455,11 +1455,11 @@ public: } } }; - + static EMS* test; void EMS_ShutDown(Section* /*sec*/) { - delete test; + delete test; } void EMS_Init(Section* sec) { diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index c8d4cfa2..a8dde5fb 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -31,7 +31,7 @@ Bitu call_shellstop; /* Larger scope so shell_del autoexec can use it to * remove things from the environment */ -Program * first_shell = 0; +Program * first_shell = 0; static Bitu shellstop_handler(void) { return CBRET_STOP; @@ -163,9 +163,9 @@ Bitu DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn,bool * append) { while (*lr && *lr!=' ' && *lr!='<' && *lr!='|') lr++; //if it ends on a : => remove it. if((*ofn != lr) && (lr[-1] == ':')) lr[-1] = 0; -// if(*lr && *(lr+1)) -// *lr++=0; -// else +// if(*lr && *(lr+1)) +// *lr++=0; +// else // *lr=0; t = (char*)malloc(lr-*ofn+1); safe_strncpy(t,*ofn,lr-*ofn+1); @@ -177,9 +177,9 @@ Bitu DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn,bool * append) { *ifn=lr; while (*lr && *lr!=' ' && *lr!='>' && *lr != '|') lr++; if((*ifn != lr) && (lr[-1] == ':')) lr[-1] = 0; -// if(*lr && *(lr+1)) -// *lr++=0; -// else +// if(*lr && *(lr+1)) +// *lr++=0; +// else // *lr=0; t = (char*)malloc(lr-*ifn+1); safe_strncpy(t,*ifn,lr-*ifn+1); @@ -193,7 +193,7 @@ Bitu DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn,bool * append) { } *lw=0; return num; -} +} void DOS_Shell::ParseLine(char * line) { LOG(LOG_EXEC,LOG_ERROR)("Parsing command line: %s",line); @@ -202,7 +202,7 @@ void DOS_Shell::ParseLine(char * line) { line = trim(line); /* Do redirection and pipe checks */ - + char * in = 0; char * out = 0; @@ -212,23 +212,23 @@ void DOS_Shell::ParseLine(char * line) { bool append; bool normalstdin = false; /* wether stdin/out are open on start. */ bool normalstdout = false; /* Bug: Assumed is they are "con" */ - + num = GetRedirection(line,&in, &out,&append); - if (num>1) LOG_MSG("SHELL:Multiple command on 1 line not supported"); + if (num>1) LOG_MSG("SHELL: Multiple command on 1 line not supported"); if (in || out) { - normalstdin = (psp->GetFileHandle(0) != 0xff); - normalstdout = (psp->GetFileHandle(1) != 0xff); + normalstdin = (psp->GetFileHandle(0) != 0xff); + normalstdout = (psp->GetFileHandle(1) != 0xff); } if (in) { if(DOS_OpenFile(in,OPEN_READ,&dummy)) { //Test if file exists DOS_CloseFile(dummy); - LOG_MSG("SHELL:Redirect input from %s",in); + LOG_MSG("SHELL: Redirect input from %s",in); if(normalstdin) DOS_CloseFile(0); //Close stdin DOS_OpenFile(in,OPEN_READ,&dummy); //Open new stdin } } if (out){ - LOG_MSG("SHELL:Redirect output to %s",out); + LOG_MSG("SHELL: Redirect output to %s",out); if(normalstdout) DOS_CloseFile(1); if(!normalstdin && !in) DOS_OpenFile("con",OPEN_READWRITE,&dummy); bool status = true; @@ -242,7 +242,7 @@ void DOS_Shell::ParseLine(char * line) { } else { status = DOS_OpenFileExtended(out,OPEN_READWRITE,DOS_ATTR_ARCHIVE,0x12,&dummy,&dummy2); } - + if(!status && normalstdout) DOS_OpenFile("con",OPEN_READWRITE,&dummy); //Read only file, open con again if(!normalstdin && !in) DOS_CloseFile(0); } @@ -309,7 +309,7 @@ void DOS_Shell::Run(void) { line.erase(); ParseLine(input_line); } else { - WriteOut(MSG_Get("SHELL_STARTUP_SUB"),VERSION); + WriteOut(MSG_Get("SHELL_STARTUP_SUB"),VERSION); } do { if (bf){ @@ -387,7 +387,7 @@ public: bool command_found = false; while (control->cmdline->FindCommand(dummy++,line) && !command_found) { struct stat test; - if (line.length() > CROSS_LEN) continue; + if (line.length() > CROSS_LEN) continue; strcpy(buffer,line.c_str()); if (stat(buffer,&test)) { if (getcwd(buffer,CROSS_LEN) == NULL) continue; @@ -396,14 +396,14 @@ public: strcat(buffer,line.c_str()); if (stat(buffer,&test)) continue; } - if (test.st_mode & S_IFDIR) { + if (test.st_mode & S_IFDIR) { autoexec[12].Install(std::string("MOUNT C \"") + buffer + "\""); autoexec[13].Install("C:"); if(secure) autoexec[14].Install("z:\\config.com -securemode"); command_found = true; } else { char* name = strrchr(buffer,CROSS_FILESPLIT); - if (!name) { //Only a filename + if (!name) { //Only a filename line = buffer; if (getcwd(buffer,CROSS_LEN) == NULL) continue; if (strlen(buffer) + line.length() + 1 > CROSS_LEN) continue; @@ -446,7 +446,7 @@ public: } /* Combining -securemode, noautoexec and no parameters leaves you with a lovely Z:\. */ - if ( !command_found ) { + if ( !command_found ) { if ( secure ) autoexec[12].Install("z:\\config.com -securemode"); } VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,(Bit32u)strlen(autoexec_data)); @@ -677,7 +677,7 @@ void SHELL_Init() { envmcb.SetPSPSeg(psp_seg); // MCB of the command shell environment envmcb.SetSize(DOS_MEM_START-env_seg); envmcb.SetType(0x4d); - + /* Setup environment */ PhysPt env_write=PhysMake(env_seg,0); MEM_BlockWrite(env_write,path_string,(Bitu)(strlen(path_string)+1)); @@ -692,7 +692,7 @@ void SHELL_Init() { DOS_PSP psp(psp_seg); psp.MakeNew(0); dos.psp(psp_seg); - + /* The start of the filetable in the psp must look like this: * 01 01 01 00 02 * In order to achieve this: First open 2 files. Close the first and @@ -715,12 +715,12 @@ void SHELL_Init() { memset(&tail.buffer,0,127); strcpy(tail.buffer,init_line); MEM_BlockWrite(PhysMake(psp_seg,128),&tail,128); - + /* Setup internal DOS Variables */ dos.dta(RealMake(psp_seg,0x80)); dos.psp(psp_seg); - + SHELL_ProgramStart(&first_shell); first_shell->Run(); delete first_shell; From 7cd00b3d845df5790fa2b83e6b90ef3bbad0c22c Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Mon, 3 Oct 2016 09:49:59 +0000 Subject: [PATCH 3910/4131] Implement an obscure behavior of the VGA DAC, similar to what was done for Star Control 2. Fixes wrong colors in Planet Soccer/Football. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4000 --- src/hardware/vga_dac.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index ccad2290..fb3bce3b 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -96,6 +96,7 @@ static void write_p3c8(Bitu port,Bitu val,Bitu iolen) { vga.dac.write_index=val; vga.dac.pel_index=0; vga.dac.state=DAC_WRITE; + vga.dac.read_index= val - 1; } static Bitu read_p3c8(Bitu port, Bitu iolen){ From 22fff8379073e3bb28b2112f6fa38bb779ee1e3a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 3 Jan 2017 21:32:31 +0000 Subject: [PATCH 3911/4131] Rewrite gus emulation a bit to make things a bit clearer Remove the automatic amplification Slight rounding offset in the panning tables to match original gus tables Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4001 --- src/hardware/gus.cpp | 227 ++++++++++++++++++++++++------------------- 1 file changed, 126 insertions(+), 101 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 8b20b954..c60f4bb9 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -32,10 +32,9 @@ using namespace std; //Extra bits of precision over normal gus -#define WAVE_BITS 2 -#define WAVE_FRACT (9+WAVE_BITS) +#define WAVE_FRACT 9 #define WAVE_FRACT_MASK ((1 << WAVE_FRACT)-1) -#define WAVE_MSWMASK ((1 << (16+WAVE_BITS))-1) +#define WAVE_MSWMASK ((1 << 16)-1) #define WAVE_LSWMASK (0xffffffff ^ WAVE_MSWMASK) //Amount of precision the volume has @@ -44,14 +43,24 @@ using namespace std; #define GUS_BASE myGUS.portbase #define GUS_RATE myGUS.rate -#define LOG_GUS 0 +#define LOG_GUS 1 + +#define VOL_SHIFT 14 + +#define WCTRL_STOPPED 0x01 +#define WCTRL_STOP 0x02 +#define WCTRL_16BIT 0x04 +#define WCTRL_LOOP 0x08 +#define WCTRL_BIDIRECTIONAL 0x10 +#define WCTRL_IRQENABLED 0x20 +#define WCTRL_DECREASING 0x40 +#define WCTRL_IRQPENDING 0x80 Bit8u adlib_commandreg; static MixerChannel * gus_chan; static Bit8u irqtable[8] = { 0, 2, 5, 3, 7, 11, 12, 15 }; static Bit8u dmatable[8] = { 0, 1, 3, 5, 6, 7, 0, 0 }; static Bit8u GUSRam[1024*1024]; // 1024K of GUS Ram -static Bit32s AutoAmp = 512; static Bit16u vol16bit[4096]; static Bit32u pantable[16]; @@ -102,41 +111,6 @@ Bitu DEBUG_EnableDebugger(void); static void GUS_DMA_Callback(DmaChannel * chan,DMAEvent event); -// Returns a single 16-bit sample from the Gravis's RAM -static INLINE Bit32s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit) { - Bit32u useAddr; - Bit32u holdAddr; - useAddr = CurAddr >> WAVE_FRACT; - if (eightbit) { - if (Delta >= (1 << WAVE_FRACT)) { - Bit32s tmpsmall = (Bit8s)GUSRam[useAddr]; - return tmpsmall << 8; - } else { - // Interpolate - Bit32s w1 = ((Bit8s)GUSRam[useAddr+0]) << 8; - Bit32s w2 = ((Bit8s)GUSRam[useAddr+1]) << 8; - Bit32s diff = w2 - w1; - return (w1+((diff*(Bit32s)(CurAddr&WAVE_FRACT_MASK ))>>WAVE_FRACT)); - } - } else { - // Formula used to convert addresses for use with 16-bit samples - holdAddr = useAddr & 0xc0000L; - useAddr = useAddr & 0x1ffffL; - useAddr = useAddr << 1; - useAddr = (holdAddr | useAddr); - - if(Delta >= (1 << WAVE_FRACT)) { - return (GUSRam[useAddr+0] | (((Bit8s)GUSRam[useAddr+1]) << 8)); - } else { - // Interpolate - Bit32s w1 = (GUSRam[useAddr+0] | (((Bit8s)GUSRam[useAddr+1]) << 8)); - Bit32s w2 = (GUSRam[useAddr+2] | (((Bit8s)GUSRam[useAddr+3]) << 8)); - Bit32s diff = w2 - w1; - return (w1+((diff*(Bit32s)(CurAddr&WAVE_FRACT_MASK ))>>WAVE_FRACT)); - } - } -} - class GUSChannels { public: Bit32u WaveStart; @@ -183,7 +157,46 @@ public: PanLeft = 0; PanRight = 0; PanPot = 0x7; - }; + } + + // Returns a single 16-bit sample from the Gravis's RAM + + INLINE Bit32s GetSample8() const { + Bit32u useAddr = WaveAddr >> WAVE_FRACT; + if (WaveAdd >= (1 << WAVE_FRACT)) { + Bit32s tmpsmall = (Bit8s)GUSRam[useAddr]; + return tmpsmall << 8; + } + else { + Bit32u nextAddr = (useAddr + 1) & ( 1024 * 1024 - 1 ); + // Interpolate + Bit32s w1 = ((Bit8s)GUSRam[useAddr]) << 8; + Bit32s w2 = ((Bit8s)GUSRam[nextAddr]) << 8; + Bit32s diff = w2 - w1; + Bit32s scale = (Bit32s)(WaveAddr&WAVE_FRACT_MASK); + return (w1 + ((diff*scale) >> WAVE_FRACT)); + } + } + + INLINE Bit32s GetSample16() const { + // Formula used to convert addresses for use with 16-bit samples + Bit32u holdAddr = WaveAddr & 0xc0000L; + Bit32u useAddr = WaveAddr & 0x1ffffL; + useAddr = useAddr << 1; + useAddr = (holdAddr | useAddr); + if (WaveAdd >= (1 << WAVE_FRACT)) { + return (GUSRam[useAddr + 0] | (((Bit8s)GUSRam[useAddr + 1]) << 8)); + } + else { + // Interpolate + Bit32s w1 = (GUSRam[useAddr + 0] | (((Bit8s)GUSRam[useAddr + 1]) << 8)); + Bit32s w2 = (GUSRam[useAddr + 2] | (((Bit8s)GUSRam[useAddr + 3]) << 8)); + Bit32s diff = w2 - w1; + Bit32s scale = (Bit32s)(WaveAddr&WAVE_FRACT_MASK); + return (w1 + ((diff*scale) >> WAVE_FRACT)); + } + } + void WriteWaveFreq(Bit16u val) { WaveFreq = val; double frameadd = double(val >> 1)/512.0; //Samples / original gus frame @@ -219,13 +232,17 @@ public: void WriteRampCtrl(Bit8u val) { Bit32u old=myGUS.RampIRQ; RampCtrl = val & 0x7f; - if ((val & 0xa0)==0xa0) myGUS.RampIRQ|=irqmask; - else myGUS.RampIRQ&=~irqmask; - if (old != myGUS.RampIRQ) CheckVoiceIrq(); + //Manually set the irq + if ((val & 0xa0)==0xa0) + myGUS.RampIRQ|=irqmask; + else + myGUS.RampIRQ&=~irqmask; + if (old != myGUS.RampIRQ) + CheckVoiceIrq(); } INLINE Bit8u ReadRampCtrl(void) { Bit8u ret=RampCtrl; - if (myGUS.RampIRQ & irqmask) ret|=0x80; + if (myGUS.RampIRQ & irqmask) ret |= 0x80; return ret; } void WriteRampRate(Bit8u val) { @@ -235,16 +252,18 @@ public: RampAdd = (Bit32u)realadd; } INLINE void WaveUpdate(void) { - if (WaveCtrl & 0x3) return; + if (WaveCtrl & ( WCTRL_STOP | WCTRL_STOPPED)) return; Bit32s WaveLeft; - if (WaveCtrl & 0x40) { - WaveAddr-=WaveAdd; - WaveLeft=WaveStart-WaveAddr; + if (WaveCtrl & WCTRL_DECREASING) { + WaveAddr -= WaveAdd; + WaveLeft = WaveStart-WaveAddr; } else { - WaveAddr+=WaveAdd; - WaveLeft=WaveAddr-WaveEnd; + WaveAddr += WaveAdd; + WaveLeft = WaveAddr-WaveEnd; } - if (WaveLeft<0) return; + //Not yet reaching a boundary + if (WaveLeft<0) + return; /* Generate an IRQ if needed */ if (WaveCtrl & 0x20) { myGUS.WaveIRQ|=irqmask; @@ -252,13 +271,13 @@ public: /* Check for not being in PCM operation */ if (RampCtrl & 0x04) return; /* Check for looping */ - if (WaveCtrl & 0x08) { + if (WaveCtrl & WCTRL_LOOP) { /* Bi-directional looping */ - if (WaveCtrl & 0x10) WaveCtrl^=0x40; - WaveAddr = (WaveCtrl & 0x40) ? (WaveEnd-WaveLeft) : (WaveStart+WaveLeft); + if (WaveCtrl & WCTRL_BIDIRECTIONAL) WaveCtrl^= WCTRL_DECREASING; + WaveAddr = (WaveCtrl & WCTRL_DECREASING) ? (WaveEnd-WaveLeft) : (WaveStart+WaveLeft); } else { WaveCtrl|=1; //Stop the channel - WaveAddr = (WaveCtrl & 0x40) ? WaveStart : WaveEnd; + WaveAddr = (WaveCtrl & WCTRL_DECREASING) ? WaveStart : WaveEnd; } } INLINE void UpdateVolumes(void) { @@ -299,21 +318,32 @@ public: } UpdateVolumes(); } - void generateSamples(Bit32s * stream,Bit32u len) { - int i; - Bit32s tmpsamp; - bool eightbit; - if (RampCtrl & WaveCtrl & 3) return; - eightbit = ((WaveCtrl & 0x4) == 0); - for(i=0;i<(int)len;i++) { - // Get sample - tmpsamp = GetSample(WaveAdd, WaveAddr, eightbit); - // Output stereo sample - stream[i<<1]+= tmpsamp * VolLeft; - stream[(i<<1)+1]+= tmpsamp * VolRight; - WaveUpdate(); - RampUpdate(); + void generateSamples(Bit32s * stream,Bit32u len) { + //Disabled channel + if (RampCtrl & WaveCtrl & 3) return; + + if (WaveCtrl & WCTRL_16BIT) { + for (int i = 0; i < (int)len; i++) { + // Get sample + Bit32s tmpsamp = GetSample16(); + // Output stereo sample + stream[i << 1] += tmpsamp * VolLeft; + stream[(i << 1) + 1] += tmpsamp * VolRight; + WaveUpdate(); + RampUpdate(); + } + } + else { + for (int i = 0; i < (int)len; i++) { + // Get sample + Bit32s tmpsamp = GetSample8(); + // Output stereo sample + stream[i << 1] += tmpsamp * VolLeft; + stream[(i << 1) + 1] += tmpsamp * VolRight; + WaveUpdate(); + RampUpdate(); + } } } }; @@ -401,20 +431,20 @@ static Bit16u ExecuteReadRegister(void) { else return 0x0300; case 0x82: // Channel MSB start address register - if (curchan) return (Bit16u)(curchan->WaveStart >> (WAVE_BITS+16)); + if (curchan) return (Bit16u)(curchan->WaveStart >> 16); else return 0x0000; case 0x83: // Channel LSW start address register - if (curchan) return (Bit16u)(curchan->WaveStart >> WAVE_BITS); + if (curchan) return (Bit16u)(curchan->WaveStart ); else return 0x0000; case 0x89: // Channel volume register if (curchan) return (Bit16u)((curchan->RampVol >> RAMP_FRACT) << 4); else return 0x0000; case 0x8a: // Channel MSB current address register - if (curchan) return (Bit16u)(curchan->WaveAddr >> (WAVE_BITS+16)); + if (curchan) return (Bit16u)(curchan->WaveAddr >> 16); else return 0x0000; case 0x8b: // Channel LSW current address register - if (curchan) return (Bit16u)(curchan->WaveAddr >> WAVE_BITS); + if (curchan) return (Bit16u)(curchan->WaveAddr ); else return 0x0000; case 0x8d: // Channel volume control register @@ -461,25 +491,25 @@ static void ExecuteGlobRegister(void) { break; case 0x2: // Channel MSW start address register if (curchan) { - Bit32u tmpaddr = (Bit32u)(myGUS.gRegData & 0x1fff) << (16+WAVE_BITS); + Bit32u tmpaddr = (Bit32u)((myGUS.gRegData & 0x1fff) << 16); curchan->WaveStart = (curchan->WaveStart & WAVE_MSWMASK) | tmpaddr; } break; case 0x3: // Channel LSW start address register if(curchan != NULL) { - Bit32u tmpaddr = (Bit32u)(myGUS.gRegData) << WAVE_BITS; + Bit32u tmpaddr = (Bit32u)(myGUS.gRegData); curchan->WaveStart = (curchan->WaveStart & WAVE_LSWMASK) | tmpaddr; } break; case 0x4: // Channel MSW end address register if(curchan != NULL) { - Bit32u tmpaddr = (Bit32u)(myGUS.gRegData & 0x1fff) << (16+WAVE_BITS); + Bit32u tmpaddr = (Bit32u)(myGUS.gRegData & 0x1fff) << 16; curchan->WaveEnd = (curchan->WaveEnd & WAVE_MSWMASK) | tmpaddr; } break; case 0x5: // Channel MSW end address register if(curchan != NULL) { - Bit32u tmpaddr = (Bit32u)(myGUS.gRegData) << WAVE_BITS; + Bit32u tmpaddr = (Bit32u)(myGUS.gRegData); curchan->WaveEnd = (curchan->WaveEnd & WAVE_LSWMASK) | tmpaddr; } break; @@ -510,13 +540,13 @@ static void ExecuteGlobRegister(void) { break; case 0xA: // Channel MSW current address register if(curchan != NULL) { - Bit32u tmpaddr = (Bit32u)(myGUS.gRegData & 0x1fff) << (16+WAVE_BITS); + Bit32u tmpaddr = (Bit32u)(myGUS.gRegData & 0x1fff) << 16; curchan->WaveAddr = (curchan->WaveAddr & WAVE_MSWMASK) | tmpaddr; } break; case 0xB: // Channel LSW current address register if(curchan != NULL) { - Bit32u tmpaddr = (Bit32u)(myGUS.gRegData) << (WAVE_BITS); + Bit32u tmpaddr = (Bit32u)(myGUS.gRegData); curchan->WaveAddr = (curchan->WaveAddr & WAVE_LSWMASK) | tmpaddr; } break; @@ -533,9 +563,9 @@ static void ExecuteGlobRegister(void) { if(myGUS.ActiveChannels > 32) myGUS.ActiveChannels = 32; myGUS.ActiveMask=0xffffffffU >> (32-myGUS.ActiveChannels); gus_chan->Enable(true); - myGUS.basefreq = (Bit32u)((float)1000000/(1.619695497*(float)(myGUS.ActiveChannels))); + myGUS.basefreq = (Bit32u)(0.5 + 1000000.0/(1.619695497*(double)(myGUS.ActiveChannels))); #if LOG_GUS - LOG_MSG("GUS set to %d channels", myGUS.ActiveChannels); + LOG_MSG("GUS set to %d channels, freq %d", myGUS.ActiveChannels, myGUS.basefreq); #endif for (i=0;iUpdateWaveRamp(); break; @@ -740,24 +770,17 @@ static void GUS_DMA_Callback(DmaChannel * chan,DMAEvent event) { } static void GUS_CallBack(Bitu len) { - memset(&MixTemp,0,len*8); - Bitu i; - Bit16s * buf16 = (Bit16s *)MixTemp; - Bit32s * buf32 = (Bit32s *)MixTemp; - for(i=0;igenerateSamples(buf32,len); - for(i=0;i> 13)*AutoAmp)>>9; - if (sample>32767) { - sample=32767; - AutoAmp--; - } else if (sample<-32768) { - sample=-32768; - AutoAmp--; - } - buf16[i] = (Bit16s)(sample); + Bit32s buffer[MIXER_BUFSIZE][2]; + memset(buffer, 0, len * sizeof(buffer[0])); + + for (Bitu i = 0; i < myGUS.ActiveChannels; i++) { + guschan[i]->generateSamples(buffer[0], len); } - gus_chan->AddSamples_s16(len,buf16); + for (Bitu i = 0; i < len; i++) { + buffer[i][0] >>= VOL_SHIFT; + buffer[i][1] >>= VOL_SHIFT; + } + gus_chan->AddSamples_s32(len, buffer[0]); CheckVoiceIrq(); } @@ -768,10 +791,12 @@ static void MakeTables(void) { for (i=4095;i>=0;i--) { vol16bit[i]=(Bit16s)out; out/=1.002709201; /* 0.0235 dB Steps */ + //Original amplification routine in the hardware + //vol16bit[i] = ((256 + i & 0xff) << VOL_SHIFT) / (1 << (24 - (i >> 8))); } pantable[0] = 4095 << RAMP_FRACT; for (i=1;i<16;i++) { - pantable[i]=(Bit32u)(-128.0*(log((double)i/15.0)/log(2.0))*(double)(1 << RAMP_FRACT)); + pantable[i]=(Bit32u)(0.5-128.0*(log((double)i/15.0)/log(2.0))*(double)(1 << RAMP_FRACT)); } } @@ -874,7 +899,7 @@ public: memset(&myGUS,0,sizeof(myGUS)); memset(GUSRam,0,1024*1024); - } + } }; static GUS* test; From a60b9837127209be632dabe4fb1d580360cc02bb Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 3 Jan 2017 21:36:37 +0000 Subject: [PATCH 3912/4131] Rewrite some mixing code to fix issue with equal rates having aliasing issues Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4002 --- src/hardware/mixer.cpp | 236 ++++++++++++++++++++++++----------------- 1 file changed, 140 insertions(+), 96 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 9a6ffcdd..d351c149 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -50,10 +50,21 @@ #include "midi.h" #define MIXER_SSIZE 4 -#define MIXER_SHIFT 14 -#define MIXER_REMAIN ((1< MIN_AUDIO) @@ -64,9 +75,12 @@ static INLINE Bit16s MIXER_CLIP(Bits SAMP) { static struct { Bit32s work[MIXER_BUFSIZE][2]; + //Write/Read pointers for the buffer Bitu pos,done; Bitu needed, min_needed, max_needed; - Bit32u tick_add,tick_remain; + //For every millisecond tick how many samples need to be generated + Bit32u tick_add; + Bit32u tick_counter; float mastervol[2]; MixerChannel * channels; bool nosound; @@ -85,6 +99,7 @@ MixerChannel * MIXER_AddChannel(MIXER_Handler handler,Bitu freq,const char * nam chan->next=mixer.channels; chan->SetVolume(1,1); chan->enabled=false; + chan->interpolate = false; mixer.channels=chan; return chan; } @@ -132,65 +147,75 @@ void MixerChannel::Enable(bool _yesno) { if (_yesno==enabled) return; enabled=_yesno; if (enabled) { - freq_index=MIXER_REMAIN; + freq_counter = 0; SDL_LockAudio(); if (donedone) { - Bitu todo=needed-done; - todo *= freq_add; - todo = (todo >> MIXER_SHIFT) + ((todo & MIXER_REMAIN)!=0); - handler(todo); + Bitu left = (needed - done); + handler(left); } } void MixerChannel::AddSilence(void) { if (done inline void MixerChannel::AddSamples(Bitu len, const Type* data) { - Bits diff[2]; - Bitu mixpos=mixer.pos+done; - freq_index&=MIXER_REMAIN; - Bitu pos=0;Bitu new_pos; - - goto thestart; - for (;;) { - new_pos=freq_index >> MIXER_SHIFT; - if (pos=len) return; + //Position where to write the data + Bitu mixpos = mixer.pos + done; + //Position in the incoming data + Bitu pos = 0; + //Mix and data for the full length + while (1) { + //Does new data need to get read? + while (freq_counter >= FREQ_NEXT) { + //Would this overflow the source data, then it's time to leave + if (pos >= len) + return; + freq_counter -= FREQ_NEXT; + prevSample[0] = nextSample[0]; + if (stereo) { + prevSample[1] = nextSample[1]; + } if ( sizeof( Type) == 1) { if (!signeddata) { if (stereo) { - diff[0]=(((Bit8s)(data[pos*2+0] ^ 0x80)) << 8)-last[0]; - diff[1]=(((Bit8s)(data[pos*2+1] ^ 0x80)) << 8)-last[1]; + nextSample[0]=(((Bit8s)(data[pos*2+0] ^ 0x80)) << 8); + nextSample[1]=(((Bit8s)(data[pos*2+1] ^ 0x80)) << 8); } else { - diff[0]=(((Bit8s)(data[pos] ^ 0x80)) << 8)-last[0]; + nextSample[0]=(((Bit8s)(data[pos] ^ 0x80)) << 8); } } else { if (stereo) { - diff[0]=(data[pos*2+0] << 8)-last[0]; - diff[1]=(data[pos*2+1] << 8)-last[1]; + nextSample[0]=(data[pos*2+0] << 8); + nextSample[1]=(data[pos*2+1] << 8); } else { - diff[0]=(data[pos] << 8)-last[0]; + nextSample[0]=(data[pos] << 8); } } //16bit and 32bit both contain 16bit data internally @@ -198,64 +223,78 @@ thestart: if (signeddata) { if (stereo) { if (nativeorder) { - diff[0]=data[pos*2+0]-last[0]; - diff[1]=data[pos*2+1]-last[1]; + nextSample[0]=data[pos*2+0]; + nextSample[1]=data[pos*2+1]; } else { if ( sizeof( Type) == 2) { - diff[0]=(Bit16s)host_readw((HostPt)&data[pos*2+0])-last[0]; - diff[1]=(Bit16s)host_readw((HostPt)&data[pos*2+1])-last[1]; + nextSample[0]=(Bit16s)host_readw((HostPt)&data[pos*2+0]); + nextSample[1]=(Bit16s)host_readw((HostPt)&data[pos*2+1]); } else { - diff[0]=(Bit32s)host_readd((HostPt)&data[pos*2+0])-last[0]; - diff[1]=(Bit32s)host_readd((HostPt)&data[pos*2+1])-last[1]; + nextSample[0]=(Bit32s)host_readd((HostPt)&data[pos*2+0]); + nextSample[1]=(Bit32s)host_readd((HostPt)&data[pos*2+1]); } } } else { if (nativeorder) { - diff[0]=data[pos]-last[0]; + nextSample[0] = data[pos]; } else { if ( sizeof( Type) == 2) { - diff[0]=(Bit16s)host_readw((HostPt)&data[pos])-last[0]; + nextSample[0]=(Bit16s)host_readw((HostPt)&data[pos]); } else { - diff[0]=(Bit32s)host_readd((HostPt)&data[pos])-last[0]; + nextSample[0]=(Bit32s)host_readd((HostPt)&data[pos]); } } } } else { if (stereo) { if (nativeorder) { - diff[0]=(Bits)data[pos*2+0]-32768-last[0]; - diff[1]=(Bits)data[pos*2+1]-32768-last[1]; + nextSample[0]=(Bits)data[pos*2+0]-32768; + nextSample[1]=(Bits)data[pos*2+1]-32768; } else { if ( sizeof( Type) == 2) { - diff[0]=(Bits)host_readw((HostPt)&data[pos*2+0])-32768-last[0]; - diff[1]=(Bits)host_readw((HostPt)&data[pos*2+1])-32768-last[1]; + nextSample[0]=(Bits)host_readw((HostPt)&data[pos*2+0])-32768; + nextSample[1]=(Bits)host_readw((HostPt)&data[pos*2+1])-32768; } else { - diff[0]=(Bits)host_readd((HostPt)&data[pos*2+0])-32768-last[0]; - diff[1]=(Bits)host_readd((HostPt)&data[pos*2+1])-32768-last[1]; + nextSample[0]=(Bits)host_readd((HostPt)&data[pos*2+0])-32768; + nextSample[1]=(Bits)host_readd((HostPt)&data[pos*2+1])-32768; } } } else { if (nativeorder) { - diff[0]=(Bits)data[pos]-32768-last[0]; + nextSample[0]=(Bits)data[pos]-32768; } else { if ( sizeof( Type) == 2) { - diff[0]=(Bits)host_readw((HostPt)&data[pos])-32768-last[0]; + nextSample[0]=(Bits)host_readw((HostPt)&data[pos])-32768; } else { - diff[0]=(Bits)host_readd((HostPt)&data[pos])-32768-last[0]; + nextSample[0]=(Bits)host_readd((HostPt)&data[pos])-32768; } } } } } + //This sample has been handled now, increase position + pos++; } - Bits diff_mul=freq_index & MIXER_REMAIN; - freq_index+=freq_add; - mixpos&=MIXER_BUFMASK; - Bits sample=last[0]+((diff[0]*diff_mul) >> MIXER_SHIFT); - mixer.work[mixpos][0]+=sample*volmul[0]; - if (stereo) sample=last[1]+((diff[1]*diff_mul) >> MIXER_SHIFT); - mixer.work[mixpos][1]+=sample*volmul[1]; - mixpos++;done++; + //Where to write + mixpos &= MIXER_BUFMASK; + Bit32s* write = mixer.work[mixpos]; + if (!interpolate) { + write[0] += prevSample[0] * volmul[0]; + write[1] += (stereo ? prevSample[1] : prevSample[0]) * volmul[1]; + } + else { + Bits diff_mul = freq_counter & FREQ_MASK; + Bits sample = prevSample[0] + (((nextSample[0] - prevSample[0]) * diff_mul) >> FREQ_SHIFT); + write[0] += sample*volmul[0]; + if (stereo) { + sample = prevSample[1] + (((nextSample[1] - prevSample[1]) * diff_mul) >> FREQ_SHIFT); + } + write[1] += sample*volmul[1]; + } + //Prepare for next sample + freq_counter += freq_add; + mixpos++; + done++; } } @@ -264,23 +303,26 @@ void MixerChannel::AddStretched(Bitu len,Bit16s * data) { LOG_MSG("Can't add, buffer full"); return; } - Bitu outlen=needed-done;Bits diff; - freq_index=0; - Bitu temp_add=(len << MIXER_SHIFT)/outlen; - Bitu mixpos=mixer.pos+done;done=needed; + //Target samples this inputs gets stretched into + Bitu outlen=needed-done; + Bitu index = 0; + Bitu index_add = (len << FREQ_SHIFT)/outlen; + Bitu mixpos=mixer.pos+done; + done=needed; Bitu pos=0; - diff=data[0]-last[0]; + while (outlen--) { - Bitu new_pos=freq_index >> MIXER_SHIFT; - if (pos> FREQ_SHIFT; + if (pos != new_pos) { + //Forward the previous sample + prevSample[0] = data[0]; + data++; } - Bits diff_mul=freq_index & MIXER_REMAIN; - freq_index+=temp_add; - mixpos&=MIXER_BUFMASK; - Bits sample=last[0]+((diff*diff_mul) >> MIXER_SHIFT); + Bits diff = data[0] - prevSample[0]; + Bits diff_mul = index & FREQ_MASK; + index += index_add; + mixpos &= MIXER_BUFMASK; + Bits sample = prevSample[0]+((diff*diff_mul) >> FREQ_SHIFT); mixer.work[mixpos][0]+=sample*volmul[0]; mixer.work[mixpos][1]+=sample*volmul[1]; mixpos++; @@ -378,16 +420,16 @@ static void MIXER_MixData(Bitu needed) { } //Reset the the tick_add for constant speed if( Mixer_irq_important() ) - mixer.tick_add = ((mixer.freq) << MIXER_SHIFT)/1000; + mixer.tick_add = ((mixer.freq) << TICK_SHIFT)/1000; mixer.done = needed; } static void MIXER_Mix(void) { SDL_LockAudio(); MIXER_MixData(mixer.needed); - mixer.tick_remain+=mixer.tick_add; - mixer.needed+=(mixer.tick_remain>>MIXER_SHIFT); - mixer.tick_remain&=MIXER_REMAIN; + mixer.tick_counter += mixer.tick_add; + mixer.needed+=(mixer.tick_counter >> TICK_SHIFT); + mixer.tick_counter &= TICK_MASK; SDL_UnlockAudio(); } @@ -405,9 +447,9 @@ static void MIXER_Mix_NoSound(void) { else chan->done=0; } /* Set values for next tick */ - mixer.tick_remain+=mixer.tick_add; - mixer.needed=mixer.tick_remain>>MIXER_SHIFT; - mixer.tick_remain&=MIXER_REMAIN; + mixer.tick_counter += mixer.tick_add; + mixer.needed += (mixer.tick_counter >> TICK_SHIFT); + mixer.tick_counter &= TICK_MASK; mixer.done=0; } @@ -415,7 +457,9 @@ static void SDLCALL MIXER_CallBack(void * userdata, Uint8 *stream, int len) { Bitu need=(Bitu)len/MIXER_SSIZE; Bit16s * output=(Bit16s *)stream; Bitu reduce; - Bitu pos, index, index_add; + Bitu pos; + //Local resampling counter to manipulate the data when sending it off to the callback + Bitu index, index_add; Bits sample; /* Enough room in the buffer ? */ if (mixer.done < need) { @@ -423,15 +467,15 @@ static void SDLCALL MIXER_CallBack(void * userdata, Uint8 *stream, int len) { if((need - mixer.done) > (need >>7) ) //Max 1 procent stretch. return; reduce = mixer.done; - index_add = (reduce << MIXER_SHIFT) / need; - mixer.tick_add = ((mixer.freq+mixer.min_needed) << MIXER_SHIFT)/1000; + index_add = (reduce << TICK_SHIFT) / need; + mixer.tick_add = ((mixer.freq+mixer.min_needed) << TICK_SHIFT)/1000; } else if (mixer.done < mixer.max_needed) { Bitu left = mixer.done - need; if (left < mixer.min_needed) { if( !Mixer_irq_important() ) { Bitu needed = mixer.needed - need; Bitu diff = (mixer.min_needed>needed?mixer.min_needed:needed) - left; - mixer.tick_add = ((mixer.freq+(diff*3)) << MIXER_SHIFT)/1000; + mixer.tick_add = ((mixer.freq+(diff*3)) << TICK_SHIFT)/1000; left = 0; //No stretching as we compensate with the tick_add value } else { left = (mixer.min_needed - left); @@ -439,10 +483,10 @@ static void SDLCALL MIXER_CallBack(void * userdata, Uint8 *stream, int len) { } // LOG_MSG("needed underrun need %d, have %d, min %d, left %d", need, mixer.done, mixer.min_needed, left); reduce = need - left; - index_add = (reduce << MIXER_SHIFT) / need; + index_add = (reduce << TICK_SHIFT) / need; } else { reduce = need; - index_add = (1 << MIXER_SHIFT); + index_add = (1 << TICK_SHIFT); // LOG_MSG("regular run need %d, have %d, min %d, left %d", need, mixer.done, mixer.min_needed, left); /* Mixer tick value being updated: @@ -454,11 +498,11 @@ static void SDLCALL MIXER_CallBack(void * userdata, Uint8 *stream, int len) { Bitu diff = left - mixer.min_needed; if(diff > (mixer.min_needed<<1)) diff = mixer.min_needed<<1; if(diff > (mixer.min_needed>>1)) - mixer.tick_add = ((mixer.freq-(diff/5)) << MIXER_SHIFT)/1000; + mixer.tick_add = ((mixer.freq-(diff/5)) << TICK_SHIFT)/1000; else if (diff > (mixer.min_needed>>4)) - mixer.tick_add = ((mixer.freq-(diff>>3)) << MIXER_SHIFT)/1000; + mixer.tick_add = ((mixer.freq-(diff>>3)) << TICK_SHIFT)/1000; else - mixer.tick_add = (mixer.freq<< MIXER_SHIFT)/1000; + mixer.tick_add = (mixer.freq<< TICK_SHIFT)/1000; } } else { /* There is way too much data in the buffer */ @@ -467,9 +511,9 @@ static void SDLCALL MIXER_CallBack(void * userdata, Uint8 *stream, int len) { index_add = MIXER_BUFSIZE - 2*mixer.min_needed; else index_add = mixer.done - 2*mixer.min_needed; - index_add = (index_add << MIXER_SHIFT) / need; + index_add = (index_add << TICK_SHIFT) / need; reduce = mixer.done - 2* mixer.min_needed; - mixer.tick_add = ((mixer.freq-(mixer.min_needed/5)) << MIXER_SHIFT)/1000; + mixer.tick_add = ((mixer.freq-(mixer.min_needed/5)) << TICK_SHIFT)/1000; } /* Reduce done count in all channels */ for (MixerChannel * chan=mixer.channels;chan;chan=chan->next) { @@ -479,7 +523,7 @@ static void SDLCALL MIXER_CallBack(void * userdata, Uint8 *stream, int len) { // Reset mixer.tick_add when irqs are important if( Mixer_irq_important() ) - mixer.tick_add=(mixer.freq<< MIXER_SHIFT)/1000; + mixer.tick_add=(mixer.freq<< TICK_SHIFT)/1000; mixer.done -= reduce; mixer.needed -= reduce; @@ -488,7 +532,7 @@ static void SDLCALL MIXER_CallBack(void * userdata, Uint8 *stream, int len) { index = 0; if(need != reduce) { while (need--) { - Bitu i = (pos + (index >> MIXER_SHIFT )) & MIXER_BUFMASK; + Bitu i = (pos + (index >> TICK_SHIFT )) & MIXER_BUFMASK; index += index_add; sample=mixer.work[i][0]>>MIXER_VOLSHIFT; *output++=MIXER_CLIP(sample); @@ -633,22 +677,22 @@ void MIXER_Init(Section* sec) { spec.userdata=NULL; spec.samples=(Uint16)mixer.blocksize; - mixer.tick_remain=0; + mixer.tick_counter=0; if (mixer.nosound) { LOG_MSG("MIXER: No Sound Mode Selected."); - mixer.tick_add=((mixer.freq) << MIXER_SHIFT)/1000; + mixer.tick_add=((mixer.freq) << TICK_SHIFT)/1000; TIMER_AddTickHandler(MIXER_Mix_NoSound); } else if (SDL_OpenAudio(&spec, &obtained) <0 ) { mixer.nosound = true; LOG_MSG("MIXER: Can't open audio: %s , running in nosound mode.",SDL_GetError()); - mixer.tick_add=((mixer.freq) << MIXER_SHIFT)/1000; + mixer.tick_add=((mixer.freq) << TICK_SHIFT)/1000; TIMER_AddTickHandler(MIXER_Mix_NoSound); } else { if((mixer.freq != obtained.freq) || (mixer.blocksize != obtained.samples)) LOG_MSG("MIXER: Got different values from SDL: freq %d, blocksize %d",obtained.freq,obtained.samples); mixer.freq=obtained.freq; mixer.blocksize=obtained.samples; - mixer.tick_add=(mixer.freq << MIXER_SHIFT)/1000; + mixer.tick_add=(mixer.freq << TICK_SHIFT)/1000; TIMER_AddTickHandler(MIXER_Mix); SDL_PauseAudio(0); } From 271d8cffa6985b49d6d84c495d72f0b95b63cf2b Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 4 Jan 2017 08:35:10 +0000 Subject: [PATCH 3913/4131] Updated header for mixer changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4003 --- include/mixer.h | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/include/mixer.h b/include/mixer.h index 94b806be..5cea3c83 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -72,18 +72,27 @@ public: 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]; + + //This gets added the frequency counter each mixer step + Bitu freq_add; + //When this flows over a new sample needs to be read from the device + Bitu freq_counter; + //Timing on how many samples have been done and were needed by th emixer + Bitu done, needed; + //Previous and next samples + Bits prevSample[2]; + Bits nextSample[2]; const char * name; + bool interpolate; bool enabled; MixerChannel * next; }; From c4ed80ca35b15d126766e58085730cc167b7680a Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 13 Jan 2017 17:38:46 +0000 Subject: [PATCH 3914/4131] Fix 16bit sample reading from gus memory Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4004 --- src/hardware/gus.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index c60f4bb9..6fd325d0 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -179,9 +179,10 @@ public: } INLINE Bit32s GetSample16() const { + Bit32u useAddr = WaveAddr >> WAVE_FRACT; // Formula used to convert addresses for use with 16-bit samples - Bit32u holdAddr = WaveAddr & 0xc0000L; - Bit32u useAddr = WaveAddr & 0x1ffffL; + Bit32u holdAddr = useAddr & 0xc0000L; + useAddr = useAddr & 0x1ffffL; useAddr = useAddr << 1; useAddr = (holdAddr | useAddr); if (WaveAdd >= (1 << WAVE_FRACT)) { From d16a138ac79b4f87d677f2d82f48e9879dfca231 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sun, 15 Jan 2017 16:01:34 +0000 Subject: [PATCH 3915/4131] Use default attribute behavior of ANSI.SYS in the console device. Fixes scrolling issues. Anything that wants non-ANSI behavior may not display as intended with the internal DOS, same as real DOS when ANSI.SYS is loaded. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4005 --- src/dos/dev_con.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 3cf0cb13..10fb6747 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -132,8 +132,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { /* expand tab if not direct output */ page = real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); do { - if(ansi.enabled) INT10_TeletypeOutputAttr(' ',ansi.attr,true); - else INT10_TeletypeOutput(' ',7); + INT10_TeletypeOutputAttr(' ',ansi.enabled?ansi.attr:7,true); col=CURSOR_POS_COL(page); } while(col%8); lastwrite = data[count++]; @@ -141,12 +140,10 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { } else { /* Some sort of "hack" now that '\n' doesn't set col to 0 (int10_char.cpp old chessgame) */ if((data[count] == '\n') && (lastwrite != '\r')) { - if(ansi.enabled) INT10_TeletypeOutputAttr('\r',ansi.attr,true); - else INT10_TeletypeOutput('\r',7); + INT10_TeletypeOutputAttr('\r',ansi.enabled?ansi.attr:7,true); } /* use ansi attribute if ansi is enabled, otherwise use DOS default attribute*/ - if(ansi.enabled) INT10_TeletypeOutputAttr(data[count],ansi.attr,true); - else INT10_TeletypeOutput(data[count],7); + INT10_TeletypeOutputAttr(data[count],ansi.enabled?ansi.attr:7,true); lastwrite = data[count++]; continue; } From 7af6c79dbba0e6b1a01fea959ae5f3011c35ea05 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sun, 15 Jan 2017 16:33:06 +0000 Subject: [PATCH 3916/4131] Fix regression related to row-wrapping in some versions of Sierra Championship Boxing; status line in Bruce Lee remains correct. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4006 --- src/ints/int10_char.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index d91a6fd1..259d8a56 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -405,7 +405,7 @@ void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page) { void ReadCharAttr(Bit16u col,Bit16u row,Bit8u page,Bit16u * result) { /* Externally used by the mouse routine */ PhysPt fontdata; - Bitu x,y,pos = row*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)+col; + Bit16u cols = real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); bool split_chr = false; switch (CurMode->type) { @@ -413,7 +413,7 @@ void ReadCharAttr(Bit16u col,Bit16u row,Bit8u page,Bit16u * result) { { // Compute the address Bit16u address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); - address+=pos*2; + address+=(row*cols+col)*2; // read the char PhysPt where = CurMode->pstart+address; *result=mem_readw(where); @@ -441,8 +441,7 @@ void ReadCharAttr(Bit16u col,Bit16u row,Bit8u page,Bit16u * result) { break; } - x=(pos%CurMode->twidth)*8; - y=(pos/CurMode->twidth)*cheight; + Bitu x=col*8,y=row*cheight*(cols/CurMode->twidth); for (Bit16u chr=0;chr<256;chr++) { @@ -489,14 +488,14 @@ void INT10_ReadCharAttr(Bit16u * result,Bit8u page) { void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useattr) { /* Externally used by the mouse routine */ PhysPt fontdata; - Bitu x,y,pos = row*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)+col; + Bit16u cols = real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); Bit8u back,cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); switch (CurMode->type) { case M_TEXT: { // Compute the address Bit16u address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); - address+=pos*2; + address+=(row*cols+col)*2; // Write the char PhysPt where = CurMode->pstart+address; mem_writeb(where,chr); @@ -573,8 +572,7 @@ void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useatt break; } - x=(pos%CurMode->twidth)*8; - y=(pos/CurMode->twidth)*cheight; + Bitu x=col*8,y=row*cheight*(cols/CurMode->twidth); Bit16u ty=(Bit16u)y; for (Bit8u h=0;h Date: Mon, 6 Mar 2017 16:25:39 +0000 Subject: [PATCH 3917/4131] Frisbee compilation fix. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4007 --- src/gui/sdlmain.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index ad1d427b..84b8be4f 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1313,9 +1313,9 @@ static void GUI_StartUp(Section * sec) { glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)SDL_GL_GetProcAddress("glUnmapBufferARB"); const char * gl_ext = (const char *)glGetString (GL_EXTENSIONS); if(gl_ext && *gl_ext){ - sdl.opengl.packed_pixel=(strstr(gl_ext,"EXT_packed_pixels") > 0); - sdl.opengl.paletted_texture=(strstr(gl_ext,"EXT_paletted_texture") > 0); - sdl.opengl.pixel_buffer_object=(strstr(gl_ext,"GL_ARB_pixel_buffer_object") >0 ) && + sdl.opengl.packed_pixel=(strstr(gl_ext,"EXT_packed_pixels") != NULL); + sdl.opengl.paletted_texture=(strstr(gl_ext,"EXT_paletted_texture") != NULL); + sdl.opengl.pixel_buffer_object=(strstr(gl_ext,"GL_ARB_pixel_buffer_object") != NULL ) && glGenBuffersARB && glBindBufferARB && glDeleteBuffersARB && glBufferDataARB && glMapBufferARB && glUnmapBufferARB; } else { From 97bb6e41279886de82870aaa17c23a3f2d45064c Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Fri, 14 Apr 2017 23:03:07 +0000 Subject: [PATCH 3918/4131] Correct INT 15h function 6 to return error. Prevents Cyrus Chess from erroneously detecting an Amstrad system. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4008 --- src/ints/bios.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 34679eb3..40d6ce9e 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -724,9 +724,6 @@ static Bitu INT14_Handler(void) { static Bitu INT15_Handler(void) { static Bit16u biosConfigSeg=0; switch (reg_ah) { - case 0x06: - LOG(LOG_BIOS,LOG_NORMAL)("INT15 Unkown Function 6"); - break; case 0xC0: /* Get Configuration*/ { if (biosConfigSeg==0) biosConfigSeg = DOS_GetMemory(1); //We have 16 bytes From d6e983b08da60e90c434da6d8efadbc2f1fcc932 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Mon, 1 May 2017 15:32:29 +0000 Subject: [PATCH 3919/4131] Handle errant IRQs as a real BIOS does. Fixes Tandy DAC in Chuck Yeager's Air Combat. Also remove r3263 workaround, as it's no longer needed. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4009 --- include/bios.h | 1 + src/cpu/callback.cpp | 5 +---- src/ints/bios.cpp | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/include/bios.h b/include/bios.h index 4915a52a..08c8fc43 100644 --- a/include/bios.h +++ b/include/bios.h @@ -61,6 +61,7 @@ #define BIOS_VDU_CONTROL 0x465 #define BIOS_VDU_COLOR_REGISTER 0x466 /* 0x467-0x468 is reserved */ +#define BIOS_LAST_UNEXPECTED_IRQ 0x46b #define BIOS_TIMER 0x46c #define BIOS_24_HOURS_FLAG 0x470 #define BIOS_KEYBOARD_FLAGS 0x471 diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 609db80b..e1e3d949 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -33,7 +33,7 @@ CallBack_Handler CallBack_Handlers[CB_MAX]; char* CallBack_Description[CB_MAX]; -static Bitu call_stop,call_idle,call_default,call_default2; +static Bitu call_stop,call_idle,call_default; Bitu call_priv_io; static Bitu illegal_handler(void) { @@ -575,8 +575,6 @@ void CALLBACK_Init(Section* /*sec*/) { /* Default handlers for unhandled interrupts that have to be non-null */ call_default=CALLBACK_Allocate(); CALLBACK_Setup(call_default,&default_handler,CB_IRET,"default"); - call_default2=CALLBACK_Allocate(); - CALLBACK_Setup(call_default2,&default_handler,CB_IRET,"default"); /* Only setup default handler for first part of interrupt table */ for (Bit16u ct=0;ct<0x60;ct++) { @@ -597,7 +595,6 @@ void CALLBACK_Init(Section* /*sec*/) { } // 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)); diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 40d6ce9e..2cf70a54 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -963,6 +963,28 @@ static Bitu INT15_Handler(void) { return CBRET_NONE; } +static Bitu Default_IRQ_Handler(void) { + IO_WriteB(0x20,0x0b); + Bit8u master_isr=IO_ReadB(0x20); + if (master_isr) { + IO_WriteB(0xa0,0x0b); + Bit8u slave_isr=IO_ReadB(0xa0); + if (slave_isr) { + IO_WriteB(0xa1,IO_ReadB(0xa1)|slave_isr); + IO_WriteB(0xa0,0x20); + } else IO_WriteB(0x21,IO_ReadB(0x21)|(master_isr&~4)); + IO_WriteB(0x20,0x20); +#if C_DEBUG + Bit16u irq=0,isr=master_isr; + if (slave_isr) isr=slave_isr<<8; + while (isr>>=1) irq++; + LOG(LOG_BIOS,LOG_WARN)("Unexpected IRQ %u",irq); +#endif + } else master_isr=0xff; + mem_writeb(BIOS_LAST_UNEXPECTED_IRQ,master_isr); + return CBRET_NONE; +} + static Bitu Reboot_Handler(void) { // switch to text mode, notify user (let's hope INT10 still works) const char* const text = "\n\n Reboot requested, quitting now."; @@ -1099,6 +1121,16 @@ public: CALLBACK_Setup(call_irq2,NULL,CB_IRET_EOI_PIC1,Real2Phys(BIOS_DEFAULT_IRQ2_LOCATION),"irq 2 bios"); RealSetVec(0x0a,BIOS_DEFAULT_IRQ2_LOCATION); + /* Default IRQ handler */ + Bitu call_irq_default=CALLBACK_Allocate(); + CALLBACK_Setup(call_irq_default,&Default_IRQ_Handler,CB_IRET,"irq default"); + RealSetVec(0x0b,CALLBACK_RealPointer(call_irq_default)); // IRQ 3 + RealSetVec(0x0c,CALLBACK_RealPointer(call_irq_default)); // IRQ 4 + RealSetVec(0x0d,CALLBACK_RealPointer(call_irq_default)); // IRQ 5 + RealSetVec(0x0f,CALLBACK_RealPointer(call_irq_default)); // IRQ 7 + RealSetVec(0x72,CALLBACK_RealPointer(call_irq_default)); // IRQ 10 + RealSetVec(0x73,CALLBACK_RealPointer(call_irq_default)); // IRQ 11 + // INT 05h: Print Screen // IRQ1 handler calls it when PrtSc key is pressed; does nothing unless hooked phys_writeb(Real2Phys(BIOS_DEFAULT_INT5_LOCATION),0xcf); From 1c786cccde17a39b680f71d2f4f0fc96d3174395 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 2 May 2017 14:14:46 +0000 Subject: [PATCH 3920/4131] Correct oscillator frequency used in the gameblaster. Thanks OPLx, Great Hierophant and NewRisingSun. Reported on VOGONS: 38350. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4010 --- src/hardware/gameblaster.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index 267ada73..dffda0d0 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -32,6 +32,8 @@ #define RIGHT 0x01 #define CMS_BUFFER_SIZE 128 #define CMS_RATE 22050 +/*#define MASTER_CLOCK 14318180/2 */ +#define MASTER_CLOCK 7159090 typedef Bit8u UINT8; @@ -205,9 +207,9 @@ static void saa1099_update(int chip, INT16 **buffer, int length) { switch (saa->noise_params[ch]) { - case 0: saa->noise[ch].freq = 31250.0 * 2; break; - case 1: saa->noise[ch].freq = 15625.0 * 2; break; - case 2: saa->noise[ch].freq = 7812.5 * 2; break; + case 0: saa->noise[ch].freq = MASTER_CLOCK/256 * 2; break; + case 1: saa->noise[ch].freq = MASTER_CLOCK/512 * 2; break; + case 2: saa->noise[ch].freq = MASTER_CLOCK/1024 * 2; break; case 3: saa->noise[ch].freq = saa->channels[ch * 3].freq; break; } } @@ -221,7 +223,7 @@ static void saa1099_update(int chip, INT16 **buffer, int length) for (ch = 0; ch < 6; ch++) { if (saa->channels[ch].freq == 0.0) - saa->channels[ch].freq = (double)((2 * 15625) << saa->channels[ch].octave) / + saa->channels[ch].freq = (double)((2 * MASTER_CLOCK/512) << saa->channels[ch].octave) / (511.0 - (double)saa->channels[ch].frequency); /* check the actual position in the square wave */ @@ -229,7 +231,7 @@ static void saa1099_update(int chip, INT16 **buffer, int length) while (saa->channels[ch].counter < 0) { /* calculate new frequency now after the half wave is updated */ - saa->channels[ch].freq = (double)((2 * 15625) << saa->channels[ch].octave) / + saa->channels[ch].freq = (double)((2 * MASTER_CLOCK/512) << saa->channels[ch].octave) / (511.0 - (double)saa->channels[ch].frequency); saa->channels[ch].counter += sample_rate; From c82dcf6c67c87d00941d53bd408cb58253bde6c2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 8 May 2017 16:29:51 +0000 Subject: [PATCH 3921/4131] Not sure how that ended up there. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4011 --- src/hardware/mixer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index d351c149..64d5707c 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -9,7 +9,7 @@ * 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. + * 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 From 6bc004c3112ecb974d4246be3f69cea0730cf617 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 8 May 2017 17:20:37 +0000 Subject: [PATCH 3922/4131] Lower default adlib volume with 2.5dB after measurements by James-F. ( https://www.vogons.org/viewtopic.php?f=46&t=49683 ) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4012 --- src/hardware/adlib.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 6c4b3983..8168e2cf 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -706,7 +706,9 @@ Module::Module( Section* configuration ) : Module_base(configuration) { ctrl.mixer = section->Get_bool("sbmixer"); mixerChan = mixerObject.Install(OPL_CallBack,rate,"FM"); - mixerChan->SetScale( 2.0 ); + //Used to be 2.0, which was measured to be too high. Exact value depends on card/clone. + mixerChan->SetScale( 1.5f ); + if (oplemu == "fast") { handler = new DBOPL::Handler(); } else if (oplemu == "compat") { From 7f15ccffb2cb74c493de8e20ec6a16cc350a1840 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 May 2017 09:03:17 +0000 Subject: [PATCH 3923/4131] Add some spaces for readability and update the position after forwarding to hopefully improve sound in GOB2. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4013 --- src/hardware/mixer.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 64d5707c..82e98a3e 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -299,21 +299,22 @@ inline void MixerChannel::AddSamples(Bitu len, const Type* data) { } void MixerChannel::AddStretched(Bitu len,Bit16s * data) { - if (done>=needed) { + if (done >= needed) { LOG_MSG("Can't add, buffer full"); return; } //Target samples this inputs gets stretched into - Bitu outlen=needed-done; + Bitu outlen = needed - done; Bitu index = 0; Bitu index_add = (len << FREQ_SHIFT)/outlen; - Bitu mixpos=mixer.pos+done; - done=needed; - Bitu pos=0; + Bitu mixpos = mixer.pos + done; + done = needed; + Bitu pos = 0; while (outlen--) { Bitu new_pos = index >> FREQ_SHIFT; if (pos != new_pos) { + pos = new_pos; //Forward the previous sample prevSample[0] = data[0]; data++; @@ -322,9 +323,9 @@ void MixerChannel::AddStretched(Bitu len,Bit16s * data) { Bits diff_mul = index & FREQ_MASK; index += index_add; mixpos &= MIXER_BUFMASK; - Bits sample = prevSample[0]+((diff*diff_mul) >> FREQ_SHIFT); - mixer.work[mixpos][0]+=sample*volmul[0]; - mixer.work[mixpos][1]+=sample*volmul[1]; + Bits sample = prevSample[0] + ((diff * diff_mul) >> FREQ_SHIFT); + mixer.work[mixpos][0] += sample * volmul[0]; + mixer.work[mixpos][1] += sample * volmul[1]; mixpos++; } } From b944c50d1077f9302f530d268497cdb0df7ff68d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 May 2017 09:29:02 +0000 Subject: [PATCH 3924/4131] Turn logging off again. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4014 --- src/hardware/gus.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 6fd325d0..7512a48f 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -43,7 +43,7 @@ using namespace std; #define GUS_BASE myGUS.portbase #define GUS_RATE myGUS.rate -#define LOG_GUS 1 +#define LOG_GUS 0 #define VOL_SHIFT 14 From f5c26251c792e6745e39dfc2029a957e7f2c71ff Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 May 2017 18:32:02 +0000 Subject: [PATCH 3925/4131] Silence a warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4015 --- src/gui/midi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 57181e00..d7a0c472 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -130,7 +130,7 @@ void MIDI_RawOutByte(Bit8u data) { } } - LOG(LOG_ALL,LOG_NORMAL)("Sysex message size %d",midi.sysex.used); + LOG(LOG_ALL,LOG_NORMAL)("Sysex message size %d", static_cast(midi.sysex.used)); if (CaptureState & CAPTURE_MIDI) { CAPTURE_AddMidi( true, midi.sysex.used-1, &midi.sysex.buf[1]); } From 00ae500d59e75a257ecb0a27c13f60c7e86226a7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 May 2017 18:32:53 +0000 Subject: [PATCH 3926/4131] Add experimental name support to configmidi for coremidi Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4016 --- src/gui/midi_coremidi.h | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/src/gui/midi_coremidi.h b/src/gui/midi_coremidi.h index 01f8592a..057d67fb 100644 --- a/src/gui/midi_coremidi.h +++ b/src/gui/midi_coremidi.h @@ -15,6 +15,8 @@ */ #include +#include +#include class MidiHandler_coremidi : public MidiHandler { private: @@ -30,9 +32,32 @@ public: m_endpoint = 0; OSStatus result; Bitu numDests = MIDIGetNumberOfDestinations(); - Bitu destId = 0; - if(conf && conf[0]) destId = atoi(conf); - + Bitu destId = numDests; + if(conf && *conf) { + std::string strconf(conf); + std::istringstream configmidi(strconf); + configmidi >> destId; + if (configmidi.fail() && numDests) { + lowcase(strconf); + for(Bitu i = 0; i= numDests) destId = 0; if (destId < numDests) { m_endpoint = MIDIGetDestination(destId); @@ -104,11 +129,11 @@ public: Bitu numDests = MIDIGetNumberOfDestinations(); for(Bitu i = 0; i < numDests; i++){ MIDIEndpointRef dest = MIDIGetDestination(i); - if(!dest) continue; + if (!dest) continue; CFStringRef midiname = 0; if(MIDIObjectGetStringProperty(dest, kMIDIPropertyDisplayName, &midiname) == noErr) { const char * s = CFStringGetCStringPtr(midiname, kCFStringEncodingMacRoman); - if(s) base->WriteOut("%02d\t%s\n",i,s); + if (s) base->WriteOut("%02d\t%s\n",i,s); } //This is for EndPoints created by us. //MIDIEndpointDispose(dest); From d93ef7f826a065fd2c320d7de7fee9a07eaf342e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 May 2017 18:35:36 +0000 Subject: [PATCH 3927/4131] Add support for selecting midi devices by name to win32 midi. Rewritten patch of rcblanke. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4017 --- src/gui/midi_win32.h | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index 670027ee..b1163838 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -41,9 +41,24 @@ public: if(conf && *conf) { std::string strconf(conf); std::istringstream configmidi(strconf); - unsigned int nummer = midiOutGetNumDevs(); + unsigned int total = midiOutGetNumDevs(); + unsigned int nummer = total; configmidi >> nummer; - if(nummer < midiOutGetNumDevs()){ + if (configmidi.fail() && total) { + lowcase(strconf); + for(unsigned int i = 0; i< total;i++) { + MIDIOUTCAPS mididev; + midiOutGetDevCaps(i, &mididev, sizeof(MIDIOUTCAPS)); + std::string devname(mididev.szPname); + lowcase(devname); + if (devname.find(strconf) != std::string::npos) { + nummer = i; + break; + } + } + } + + if (nummer < total) { MIDIOUTCAPS mididev; midiOutGetDevCaps(nummer, &mididev, sizeof(MIDIOUTCAPS)); LOG_MSG("MIDI: win32 selected %s",mididev.szPname); From cbfeb1fdc36952292b74c3a7b669803ca86b9973 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 May 2017 18:47:37 +0000 Subject: [PATCH 3928/4131] update midconfig helplines to reflect namesupport. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4018 --- src/dosbox.cpp | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 1462fae3..a1e18dc3 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -88,7 +88,7 @@ void MPU401_Init(Section*); void PCSPEAKER_Init(Section*); void TANDYSOUND_Init(Section*); void DISNEY_Init(Section*); -void SERIAL_Init(Section*); +void SERIAL_Init(Section*); #if C_IPX @@ -186,14 +186,14 @@ increaseticks: ratio = (Bit32s)((double)ratio * (1 - ratioremoved)); /* Don't allow very high ratio which can cause us to lock as we don't scale down * for very low ratios. High ratio might result because of timing resolution */ - if (ticksScheduled >= 250 && ticksDone < 10 && ratio > 20480) + if (ticksScheduled >= 250 && ticksDone < 10 && ratio > 20480) ratio = 20480; Bit64s cmax_scaled = (Bit64s)CPU_CycleMax * (Bit64s)ratio; /* The auto cycle code seems reliable enough to disable the fast cut back code. * This should improve the fluency of complex games. - if (ratio <= 1024) + if (ratio <= 1024) new_cmax = (Bit32s)(cmax_scaled / (Bit64s)1024); - else + else */ new_cmax = (Bit32s)(1 + (CPU_CycleMax >> 1) + cmax_scaled / (Bit64s)2048); } @@ -209,7 +209,7 @@ increaseticks: ratio, ticksDone, ticksScheduled); - */ + */ /* ratios below 1% are considered to be dropouts due to temporary load imbalance, the cycles adjusting is skipped */ if (ratio>10) { @@ -300,7 +300,7 @@ static void DOSBOX_RealInit(Section * sec) { } std::string mtype(section->Get_string("machine")); - svgaCard = SVGA_None; + svgaCard = SVGA_None; machine = MCH_VGA; int10.vesa_nolfb = false; int10.vesa_oldvbe = false; @@ -361,10 +361,10 @@ void DOSBOX_Init(void) { Pstring = secprop->Add_path("captures",Property::Changeable::Always,"capture"); Pstring->Set_help("Directory where things like wave, midi, screenshot get captured."); -#if C_DEBUG +#if C_DEBUG LOG_StartUp(); #endif - + secprop->AddInitFunction(&IO_Init);//done secprop->AddInitFunction(&PAGING_Init);//done secprop->AddInitFunction(&MEM_Init);//done @@ -396,7 +396,7 @@ void DOSBOX_Init(void) { "then the scaler will be used even if the result might not be desired."); Pstring = Pmulti->GetSection()->Add_string("type",Property::Changeable::Always,"normal2x"); - const char *scalers[] = { + const char *scalers[] = { "none", "normal2x", "normal3x", #if RENDER_USE_ADVANCED_SCALERS>2 "advmame2x", "advmame3x", "advinterp2x", "advinterp3x", "hq2x", "hq3x", "2xsai", "super2xsai", "supereagle", @@ -446,7 +446,7 @@ void DOSBOX_Init(void) { Pstring->Set_values(cyclest); Pstring = Pmulti_remain->GetSection()->Add_string("parameters",Property::Changeable::Always,""); - + Pint = secprop->Add_int("cycleup",Property::Changeable::Always,10); Pint->SetMinMax(1,1000000); Pint->Set_help("Amount of cycles to decrease/increase with keycombos.(CTRL-F11/CTRL-F12)"); @@ -454,7 +454,7 @@ void DOSBOX_Init(void) { Pint = secprop->Add_int("cycledown",Property::Changeable::Always,20); Pint->SetMinMax(1,1000000); Pint->Set_help("Setting it lower than 100 will be a percentage."); - + #if C_FPU secprop->AddInitFunction(&FPU_Init); #endif @@ -488,7 +488,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("midi",&MIDI_Init,true);//done secprop->AddInitFunction(&MPU401_Init,true);//done - + const char* mputypes[] = { "intelligent", "uart", "none",0}; // FIXME: add some way to offer the actually available choices. const char *devices[] = { "default", "win32", "alsa", "oss", "coreaudio", "coremidi","none", 0}; @@ -501,8 +501,8 @@ void DOSBOX_Init(void) { Pstring->Set_help("Device that will receive the MIDI data from MPU-401."); Pstring = secprop->Add_string("midiconfig",Property::Changeable::WhenIdle,""); - Pstring->Set_help("Special configuration options for the device driver. This is usually the id of the device you want to use.\n" - " or in the case of coreaudio, you can specify a soundfont here.\n" + Pstring->Set_help("Special configuration options for the device driver. This is usually the id or part of the name of the device you want to use (find the id/name with mixer/listmidi).\n" + " Or in the case of coreaudio, you can specify a soundfont here.\n" " When using a Roland MT-32 rev. 0 as midi output device, some games may require a delay in order to prevent 'buffer overflow' issues.\n" " In that case, add 'delaysysex', for example: midiconfig=2 delaysysex\n" " See the README/Manual for more details."); @@ -512,7 +512,7 @@ void DOSBOX_Init(void) { #endif secprop=control->AddSection_prop("sblaster",&SBLASTER_Init,true);//done - + const char* sbtypes[] = { "sb1", "sb2", "sbpro1", "sbpro2", "sb16", "gb", "none", 0 }; Pstring = secprop->Add_string("sbtype",Property::Changeable::WhenIdle,"sb16"); Pstring->Set_values(sbtypes); @@ -553,7 +553,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("gus",&GUS_Init,true); //done - Pbool = secprop->Add_bool("gus",Property::Changeable::WhenIdle,false); + Pbool = secprop->Add_bool("gus",Property::Changeable::WhenIdle,false); Pbool->Set_help("Enable the Gravis Ultrasound emulation."); Pint = secprop->Add_int("gusrate",Property::Changeable::WhenIdle,44100); @@ -592,13 +592,13 @@ void DOSBOX_Init(void) { Pstring = secprop->Add_string("tandy",Property::Changeable::WhenIdle,"auto"); Pstring->Set_values(tandys); Pstring->Set_help("Enable Tandy Sound System emulation. For 'auto', emulation is present only if machine is set to 'tandy'."); - + Pint = secprop->Add_int("tandyrate",Property::Changeable::WhenIdle,44100); Pint->Set_values(rates); Pint->Set_help("Sample rate of the Tandy 3-Voice generation."); secprop->AddInitFunction(&DISNEY_Init,true);//done - + Pbool = secprop->Add_bool("disney",Property::Changeable::WhenIdle,true); Pbool->Set_help("Enable Disney Sound Source emulation. (Covox Voice Master and Speech Thing compatible)."); @@ -624,7 +624,7 @@ void DOSBOX_Init(void) { Pbool = secprop->Add_bool("autofire",Property::Changeable::WhenIdle,false); Pbool->Set_help("continuously fires as long as you keep the button pressed."); - + Pbool = secprop->Add_bool("swap34",Property::Changeable::WhenIdle,false); Pbool->Set_help("swap the 3rd and the 4th axis. can be useful for certain joysticks."); @@ -634,7 +634,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("serial",&SERIAL_Init,true); const char* serials[] = { "dummy", "disabled", "modem", "nullmodem", "directserial",0 }; - + Pmulti_remain = secprop->Add_multiremain("serial1",Property::Changeable::WhenIdle," "); Pstring = Pmulti_remain->GetSection()->Add_string("type",Property::Changeable::WhenIdle,"dummy"); Pmulti_remain->SetValue("dummy"); From e4d868f93d6f6eb21b60c0e969f9a0a505c72953 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 15 May 2017 17:37:05 +0000 Subject: [PATCH 3929/4131] Revert mixer to request data in the device rate instead of the mixer rate. Fixes bug #457. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4019 --- src/hardware/mixer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 82e98a3e..b846e0e4 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -169,6 +169,8 @@ void MixerChannel::Mix(Bitu _needed) { needed=_needed; while (enabled && needed>done) { Bitu left = (needed - done); + left *= freq_add; + left = (left >> FREQ_SHIFT) + ((left & FREQ_MASK)!=0); handler(left); } } From c2b7030e8e7aff7aaf40e655eb7a12e984a4d47b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 27 May 2017 14:31:09 +0000 Subject: [PATCH 3930/4131] Make IRQ generation in Write_MCR consistent with ComputeInterrupts, when op2 changes. Rename variables for clarity. Thanks for the report Arrigo (vogons: 54049) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4020 --- src/hardware/serialport/serialport.cpp | 82 ++++++++++++++------------ 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index 7bc16b4c..f640866c 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -719,82 +719,86 @@ Bitu CSerial::Read_MCR () { void CSerial::Write_MCR (Bit8u data) { // WARNING: At the time setRTSDTR is called rts and dsr members are still wrong. - if(data&FIFO_FLOWCONTROL) LOG_MSG("Warning: tried to activate hardware handshake."); - bool temp_dtr = data & MCR_DTR_MASK? true:false; - bool temp_rts = data & MCR_RTS_MASK? true:false; - bool temp_op1 = data & MCR_OP1_MASK? true:false; - bool temp_op2 = data & MCR_OP2_MASK? true:false; - bool temp_loopback = data & MCR_LOOPBACK_Enable_MASK? true:false; - if(loopback!=temp_loopback) { - if(temp_loopback) setRTSDTR(false,false); - else setRTSDTR(temp_rts,temp_dtr); + if (data&FIFO_FLOWCONTROL) LOG_MSG("Warning: tried to activate hardware handshake."); + bool new_dtr = data & MCR_DTR_MASK? true:false; + bool new_rts = data & MCR_RTS_MASK? true:false; + bool new_op1 = data & MCR_OP1_MASK? true:false; + bool new_op2 = data & MCR_OP2_MASK? true:false; + bool new_loopback = data & MCR_LOOPBACK_Enable_MASK? true:false; + if (loopback != new_loopback) { + if (new_loopback) setRTSDTR(false,false); + else setRTSDTR(new_rts,new_dtr); } - if (temp_loopback) { // is on: + if (new_loopback) { // is on: // DTR->DSR // RTS->CTS // OP1->RI // OP2->CD - if(temp_dtr!=dtr && !d_dsr) { - d_dsr=true; + if (new_dtr != dtr && !d_dsr) { + d_dsr = true; rise (MSR_PRIORITY); } - if(temp_rts!=rts && !d_cts) { - d_cts=true; + if (new_rts != rts && !d_cts) { + d_cts = true; rise (MSR_PRIORITY); } - if(temp_op1!=op1 && !d_ri) { + if (new_op1 != op1 && !d_ri) { // interrupt only at trailing edge - if(!temp_op1) { - d_ri=true; + if (!new_op1) { + d_ri = true; rise (MSR_PRIORITY); } } - if(temp_op2!=op2 && !d_cd) { - d_cd=true; + if (new_op2 != op2 && !d_cd) { + d_cd = true; rise (MSR_PRIORITY); } } else { // loopback is off - if(temp_rts!=rts) { + if (new_rts != rts) { // RTS difference - if(temp_dtr!=dtr) { + if (new_dtr != dtr) { // both difference #if SERIAL_DEBUG - log_ser(dbg_modemcontrol,"RTS %x.",temp_rts); - log_ser(dbg_modemcontrol,"DTR %x.",temp_dtr); + log_ser(dbg_modemcontrol,"RTS %x.",new_rts); + log_ser(dbg_modemcontrol,"DTR %x.",new_dtr); #endif - setRTSDTR(temp_rts, temp_dtr); + setRTSDTR(new_rts, new_dtr); } else { // only RTS #if SERIAL_DEBUG - log_ser(dbg_modemcontrol,"RTS %x.",temp_rts); + log_ser(dbg_modemcontrol,"RTS %x.",new_rts); #endif - setRTS(temp_rts); + setRTS(new_rts); } - } else if(temp_dtr!=dtr) { + } else if (new_dtr != dtr) { // only DTR #if SERIAL_DEBUG - log_ser(dbg_modemcontrol,"%DTR %x.",temp_dtr); + log_ser(dbg_modemcontrol,"%DTR %x.",new_dtr); #endif - setDTR(temp_dtr); + setDTR(new_dtr); } } - // interrupt logic: if OP2 is 0, the IRQ line is tristated (pulled high) - if((!op2) && temp_op2) { + // interrupt logic: if new_OP2 is 0, the IRQ line is tristated (pulled high) + // which turns off the IRQ generation. + if ((!op2) && new_op2) { // irq has been enabled (tristate high -> irq level) - if(!irq_active) PIC_DeActivateIRQ(irq); - } else if(op2 && (!temp_op2)) { - if(!irq_active) PIC_ActivateIRQ(irq); + // Generate one if ComputeInterrupts has set irq_active to true + if (irq_active) PIC_ActivateIRQ(irq); + } else if (op2 && (!new_op2)) { + // irq has been disabled (irq level -> tristate) + // Remove the IRQ signal if the irq was being generated before + if (irq_active) PIC_DeActivateIRQ(irq); } - dtr=temp_dtr; - rts=temp_rts; - op1=temp_op1; - op2=temp_op2; - loopback=temp_loopback; + dtr=new_dtr; + rts=new_rts; + op1=new_op1; + op2=new_op2; + loopback=new_loopback; } /*****************************************************************************/ From 6cf39c1fc614e0232fc1629179cfa4603098ed38 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 May 2017 11:35:08 +0000 Subject: [PATCH 3931/4131] Years update Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4021 --- acinclude.m4 | 2 +- include/bios.h | 2 +- include/bios_disk.h | 2 +- include/callback.h | 2 +- include/control.h | 2 +- include/cpu.h | 2 +- include/cross.h | 2 +- include/debug.h | 2 +- include/dma.h | 2 +- include/dos_inc.h | 2 +- include/dos_system.h | 2 +- include/dosbox.h | 2 +- include/fpu.h | 2 +- include/hardware.h | 2 +- include/inout.h | 2 +- include/ipx.h | 2 +- include/ipxserver.h | 2 +- include/joystick.h | 2 +- include/keyboard.h | 2 +- include/logging.h | 2 +- include/mapper.h | 2 +- include/mem.h | 2 +- include/midi.h | 2 +- include/mixer.h | 2 +- include/mouse.h | 2 +- include/paging.h | 2 +- include/pci_bus.h | 2 +- include/pic.h | 2 +- include/programs.h | 2 +- include/regs.h | 2 +- include/render.h | 2 +- include/serialport.h | 2 +- include/setup.h | 2 +- include/shell.h | 2 +- include/support.h | 2 +- include/timer.h | 2 +- include/vga.h | 2 +- include/video.h | 2 +- scripts/dosbox-installer.nsi | 2 +- src/cpu/callback.cpp | 2 +- src/cpu/core_dyn_x86.cpp | 2 +- src/cpu/core_dyn_x86/cache.h | 2 +- src/cpu/core_dyn_x86/decoder.h | 2 +- src/cpu/core_dyn_x86/dyn_fpu.h | 2 +- src/cpu/core_dyn_x86/dyn_fpu_dh.h | 2 +- src/cpu/core_dyn_x86/helpers.h | 2 +- src/cpu/core_dyn_x86/risc_x86.h | 2 +- src/cpu/core_dyn_x86/string.h | 2 +- src/cpu/core_dynrec.cpp | 2 +- src/cpu/core_dynrec/cache.h | 2 +- src/cpu/core_dynrec/decoder.h | 2 +- src/cpu/core_dynrec/decoder_basic.h | 2 +- src/cpu/core_dynrec/decoder_opcodes.h | 2 +- src/cpu/core_dynrec/dyn_fpu.h | 2 +- src/cpu/core_dynrec/operators.h | 2 +- src/cpu/core_dynrec/risc_armv4le-common.h | 2 +- src/cpu/core_dynrec/risc_armv4le-o3.h | 2 +- src/cpu/core_dynrec/risc_armv4le-thumb-iw.h | 2 +- src/cpu/core_dynrec/risc_armv4le-thumb-niw.h | 2 +- src/cpu/core_dynrec/risc_armv4le-thumb.h | 2 +- src/cpu/core_dynrec/risc_armv4le.h | 2 +- src/cpu/core_dynrec/risc_mipsel32.h | 2 +- src/cpu/core_dynrec/risc_x64.h | 2 +- src/cpu/core_dynrec/risc_x86.h | 2 +- src/cpu/core_full.cpp | 2 +- src/cpu/core_full/ea_lookup.h | 2 +- src/cpu/core_full/load.h | 2 +- src/cpu/core_full/loadwrite.h | 2 +- src/cpu/core_full/op.h | 2 +- src/cpu/core_full/optable.h | 2 +- src/cpu/core_full/save.h | 2 +- src/cpu/core_full/string.h | 2 +- src/cpu/core_full/support.h | 2 +- src/cpu/core_normal.cpp | 2 +- src/cpu/core_normal/helpers.h | 2 +- src/cpu/core_normal/prefix_0f.h | 2 +- src/cpu/core_normal/prefix_66.h | 2 +- src/cpu/core_normal/prefix_66_0f.h | 2 +- src/cpu/core_normal/prefix_none.h | 2 +- src/cpu/core_normal/string.h | 2 +- src/cpu/core_normal/support.h | 2 +- src/cpu/core_normal/table_ea.h | 2 +- src/cpu/core_prefetch.cpp | 2 +- src/cpu/core_simple.cpp | 2 +- src/cpu/cpu.cpp | 2 +- src/cpu/flags.cpp | 2 +- src/cpu/instructions.h | 2 +- src/cpu/lazyflags.h | 2 +- src/cpu/modrm.cpp | 2 +- src/cpu/modrm.h | 2 +- src/cpu/paging.cpp | 2 +- src/debug/debug.cpp | 2 +- src/debug/debug_gui.cpp | 2 +- src/debug/debug_inc.h | 2 +- src/debug/debug_win32.cpp | 2 +- src/debug/disasm_tables.h | 2 +- src/dos/cdrom.cpp | 2 +- src/dos/cdrom.h | 2 +- src/dos/cdrom_aspi_win32.cpp | 2 +- src/dos/cdrom_image.cpp | 2 +- src/dos/cdrom_ioctl_linux.cpp | 2 +- src/dos/cdrom_ioctl_os2.cpp | 2 +- src/dos/cdrom_ioctl_win32.cpp | 2 +- src/dos/dev_con.h | 2 +- src/dos/dos.cpp | 2 +- src/dos/dos_classes.cpp | 2 +- src/dos/dos_devices.cpp | 2 +- src/dos/dos_execute.cpp | 2 +- src/dos/dos_files.cpp | 2 +- src/dos/dos_ioctl.cpp | 2 +- src/dos/dos_keyboard_layout.cpp | 2 +- src/dos/dos_memory.cpp | 2 +- src/dos/dos_misc.cpp | 2 +- src/dos/dos_mscdex.cpp | 2 +- src/dos/dos_programs.cpp | 2 +- src/dos/dos_tables.cpp | 2 +- src/dos/drive_cache.cpp | 2 +- src/dos/drive_fat.cpp | 2 +- src/dos/drive_iso.cpp | 2 +- src/dos/drive_local.cpp | 2 +- src/dos/drive_virtual.cpp | 2 +- src/dos/drives.cpp | 2 +- src/dos/drives.h | 2 +- src/dosbox.cpp | 2 +- src/fpu/fpu.cpp | 2 +- src/fpu/fpu_instructions.h | 2 +- src/fpu/fpu_instructions_x86.h | 2 +- src/gui/dosbox_logo.h | 2 +- src/gui/midi.cpp | 2 +- src/gui/midi_alsa.h | 2 +- src/gui/midi_coreaudio.h | 2 +- src/gui/midi_oss.h | 2 +- src/gui/midi_win32.h | 2 +- src/gui/render.cpp | 2 +- src/gui/render_loops.h | 2 +- src/gui/render_scalers.cpp | 2 +- src/gui/render_scalers.h | 2 +- src/gui/render_simple.h | 2 +- src/gui/render_templates.h | 2 +- src/gui/render_templates_hq.h | 2 +- src/gui/render_templates_hq2x.h | 2 +- src/gui/render_templates_hq3x.h | 2 +- src/gui/render_templates_sai.h | 2 +- src/gui/sdl_gui.cpp | 4 ++-- src/gui/sdl_mapper.cpp | 2 +- src/gui/sdlmain.cpp | 6 +++--- src/hardware/adlib.cpp | 2 +- src/hardware/adlib.h | 2 +- src/hardware/cmos.cpp | 2 +- src/hardware/dbopl.cpp | 2 +- src/hardware/dbopl.h | 2 +- src/hardware/disney.cpp | 2 +- src/hardware/dma.cpp | 2 +- src/hardware/gameblaster.cpp | 2 +- src/hardware/gus.cpp | 2 +- src/hardware/hardware.cpp | 2 +- src/hardware/iohandler.cpp | 2 +- src/hardware/ipx.cpp | 2 +- src/hardware/ipxserver.cpp | 2 +- src/hardware/joystick.cpp | 2 +- src/hardware/keyboard.cpp | 2 +- src/hardware/memory.cpp | 2 +- src/hardware/mixer.cpp | 2 +- src/hardware/mpu401.cpp | 12 ++++++------ src/hardware/opl.cpp | 2 +- src/hardware/opl.h | 2 +- src/hardware/pci_bus.cpp | 2 +- src/hardware/pci_devices.h | 2 +- src/hardware/pcspeaker.cpp | 2 +- src/hardware/pic.cpp | 2 +- src/hardware/sblaster.cpp | 2 +- src/hardware/serialport/directserial.cpp | 2 +- src/hardware/serialport/directserial.h | 2 +- src/hardware/serialport/libserial.cpp | 2 +- src/hardware/serialport/libserial.h | 2 +- src/hardware/serialport/misc_util.cpp | 2 +- src/hardware/serialport/misc_util.h | 2 +- src/hardware/serialport/nullmodem.cpp | 2 +- src/hardware/serialport/nullmodem.h | 2 +- src/hardware/serialport/serialdummy.cpp | 2 +- src/hardware/serialport/serialdummy.h | 2 +- src/hardware/serialport/serialport.cpp | 2 +- src/hardware/serialport/softmodem.cpp | 2 +- src/hardware/serialport/softmodem.h | 2 +- src/hardware/tandy_sound.cpp | 2 +- src/hardware/timer.cpp | 2 +- src/hardware/vga.cpp | 2 +- src/hardware/vga_attr.cpp | 2 +- src/hardware/vga_crtc.cpp | 2 +- src/hardware/vga_dac.cpp | 2 +- src/hardware/vga_draw.cpp | 2 +- src/hardware/vga_gfx.cpp | 2 +- src/hardware/vga_memory.cpp | 2 +- src/hardware/vga_misc.cpp | 2 +- src/hardware/vga_other.cpp | 2 +- src/hardware/vga_paradise.cpp | 2 +- src/hardware/vga_s3.cpp | 2 +- src/hardware/vga_seq.cpp | 2 +- src/hardware/vga_tseng.cpp | 2 +- src/hardware/vga_xga.cpp | 2 +- src/ints/bios.cpp | 2 +- src/ints/bios_disk.cpp | 2 +- src/ints/bios_keyboard.cpp | 2 +- src/ints/ems.cpp | 2 +- src/ints/int10.cpp | 2 +- src/ints/int10.h | 2 +- src/ints/int10_char.cpp | 2 +- src/ints/int10_memory.cpp | 2 +- src/ints/int10_misc.cpp | 2 +- src/ints/int10_modes.cpp | 2 +- src/ints/int10_pal.cpp | 2 +- src/ints/int10_put_pixel.cpp | 2 +- src/ints/int10_vesa.cpp | 2 +- src/ints/int10_video_state.cpp | 2 +- src/ints/int10_vptable.cpp | 2 +- src/ints/mouse.cpp | 2 +- src/ints/xms.cpp | 2 +- src/ints/xms.h | 2 +- src/libs/zmbv/drvproc.cpp | 2 +- src/libs/zmbv/zmbv.cpp | 2 +- src/libs/zmbv/zmbv.h | 2 +- src/libs/zmbv/zmbv_vfw.cpp | 2 +- src/libs/zmbv/zmbv_vfw.rc | 2 +- src/misc/cross.cpp | 2 +- src/misc/messages.cpp | 2 +- src/misc/programs.cpp | 2 +- src/misc/setup.cpp | 2 +- src/misc/support.cpp | 2 +- src/shell/shell.cpp | 2 +- src/shell/shell_batch.cpp | 2 +- src/shell/shell_cmds.cpp | 2 +- src/shell/shell_misc.cpp | 2 +- src/winres.rc | 4 ++-- 233 files changed, 242 insertions(+), 242 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 936496e7..8b910206 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -305,7 +305,7 @@ AC_SUBST(ALSA_LIBS) AH_TOP([ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/bios.h b/include/bios.h index 08c8fc43..5b2de5de 100644 --- a/include/bios.h +++ b/include/bios.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/bios_disk.h b/include/bios_disk.h index 0670ce05..79dd094f 100644 --- a/include/bios_disk.h +++ b/include/bios_disk.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/callback.h b/include/callback.h index f1cfef7c..b09a3822 100644 --- a/include/callback.h +++ b/include/callback.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/control.h b/include/control.h index 4666a277..95a555e9 100644 --- a/include/control.h +++ b/include/control.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/cpu.h b/include/cpu.h index 2f27f2c0..ae26064a 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/cross.h b/include/cross.h index 93501849..e651bca3 100644 --- a/include/cross.h +++ b/include/cross.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/debug.h b/include/debug.h index 9e214629..e8ab2b98 100644 --- a/include/debug.h +++ b/include/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/dma.h b/include/dma.h index 38531811..075ceab8 100644 --- a/include/dma.h +++ b/include/dma.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/dos_inc.h b/include/dos_inc.h index 3782d34e..277387c9 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/dos_system.h b/include/dos_system.h index baf7591e..152fee3f 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/dosbox.h b/include/dosbox.h index 6684faff..6447c120 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/fpu.h b/include/fpu.h index 67e10210..53e6b341 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/hardware.h b/include/hardware.h index 26d3fde8..00c4939d 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/inout.h b/include/inout.h index dd0dc172..c5215f49 100644 --- a/include/inout.h +++ b/include/inout.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/ipx.h b/include/ipx.h index 6e87b1e9..b3fdba54 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/ipxserver.h b/include/ipxserver.h index 1c6a294d..39d1935c 100644 --- a/include/ipxserver.h +++ b/include/ipxserver.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/joystick.h b/include/joystick.h index a5139584..a9d53955 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/keyboard.h b/include/keyboard.h index fcecc308..76e252e4 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/logging.h b/include/logging.h index 049e504b..2d7cb709 100644 --- a/include/logging.h +++ b/include/logging.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/mapper.h b/include/mapper.h index 3ba648c4..17320cb9 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/mem.h b/include/mem.h index d362cb03..d5d069cb 100644 --- a/include/mem.h +++ b/include/mem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/midi.h b/include/midi.h index 86431dc8..d12aebe9 100644 --- a/include/midi.h +++ b/include/midi.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/mixer.h b/include/mixer.h index 5cea3c83..b9aecd8d 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/mouse.h b/include/mouse.h index 0a1000a6..f727594c 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/paging.h b/include/paging.h index 712214c6..5ab0fb50 100644 --- a/include/paging.h +++ b/include/paging.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/pci_bus.h b/include/pci_bus.h index f8b729e8..0368e1b2 100644 --- a/include/pci_bus.h +++ b/include/pci_bus.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/pic.h b/include/pic.h index 77691f2a..841fe791 100644 --- a/include/pic.h +++ b/include/pic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/programs.h b/include/programs.h index 04db83c1..8c5077af 100644 --- a/include/programs.h +++ b/include/programs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/regs.h b/include/regs.h index 259ab695..4a13ae7d 100644 --- a/include/regs.h +++ b/include/regs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/render.h b/include/render.h index f2c53475..ba438225 100644 --- a/include/render.h +++ b/include/render.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/serialport.h b/include/serialport.h index b4641ccc..24b00048 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/setup.h b/include/setup.h index 7dc9f401..15fc3b8c 100644 --- a/include/setup.h +++ b/include/setup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/shell.h b/include/shell.h index 74e21059..5e2cab0b 100644 --- a/include/shell.h +++ b/include/shell.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/support.h b/include/support.h index 62330060..f20822be 100644 --- a/include/support.h +++ b/include/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/timer.h b/include/timer.h index e8abf323..14c609a7 100644 --- a/include/timer.h +++ b/include/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/vga.h b/include/vga.h index aa570ec4..85a9c228 100644 --- a/include/vga.h +++ b/include/vga.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/include/video.h b/include/video.h index 11539aee..20ad8378 100644 --- a/include/video.h +++ b/include/video.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index 492b2895..1abc0b1c 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -2,7 +2,7 @@ !define VER_MINOR 74 !define APP_NAME "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer" !define COMP_NAME "DOSBox Team" -!define COPYRIGHT "Copyright © 2002-2013 DOSBox Team" +!define COPYRIGHT "Copyright © 2002-2017 DOSBox Team" !define DESCRIPTION "DOSBox Installer" VIProductVersion "${VER_MAYOR}.${VER_MINOR}.0.0" diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index e1e3d949..a503e944 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 0045394a..66b3fb97 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 23b6a53e..dc42ebab 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 18bf1e11..dd1dae8c 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dyn_x86/dyn_fpu.h b/src/cpu/core_dyn_x86/dyn_fpu.h index 6534b70b..62f085d4 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu.h +++ b/src/cpu/core_dyn_x86/dyn_fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dyn_x86/dyn_fpu_dh.h b/src/cpu/core_dyn_x86/dyn_fpu_dh.h index 23870452..f633ff5c 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu_dh.h +++ b/src/cpu/core_dyn_x86/dyn_fpu_dh.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dyn_x86/helpers.h b/src/cpu/core_dyn_x86/helpers.h index 022e6780..bb97f080 100644 --- a/src/cpu/core_dyn_x86/helpers.h +++ b/src/cpu/core_dyn_x86/helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 74c85366..b8079143 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index 93f69e4e..2c87adf3 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index 1571fb43..ba24b2e4 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index 7d7a6efd..fbe0a001 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h index 9c1fe499..0460d508 100644 --- a/src/cpu/core_dynrec/decoder.h +++ b/src/cpu/core_dynrec/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index 61edc64b..bcc1b8d1 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index d08ae43b..ceecb763 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dynrec/dyn_fpu.h b/src/cpu/core_dynrec/dyn_fpu.h index c410ebde..eae703e6 100644 --- a/src/cpu/core_dynrec/dyn_fpu.h +++ b/src/cpu/core_dynrec/dyn_fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dynrec/operators.h b/src/cpu/core_dynrec/operators.h index 18d17430..9754d5de 100644 --- a/src/cpu/core_dynrec/operators.h +++ b/src/cpu/core_dynrec/operators.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-common.h b/src/cpu/core_dynrec/risc_armv4le-common.h index c6ab612f..89832d86 100644 --- a/src/cpu/core_dynrec/risc_armv4le-common.h +++ b/src/cpu/core_dynrec/risc_armv4le-common.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-o3.h b/src/cpu/core_dynrec/risc_armv4le-o3.h index 3596c48e..974ac3bd 100644 --- a/src/cpu/core_dynrec/risc_armv4le-o3.h +++ b/src/cpu/core_dynrec/risc_armv4le-o3.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h index 5d8f8b52..574eb2b8 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h index e4890c1b..c1696dd0 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb.h b/src/cpu/core_dynrec/risc_armv4le-thumb.h index 126cdd11..f4f36482 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dynrec/risc_armv4le.h b/src/cpu/core_dynrec/risc_armv4le.h index 8a3b343b..e6ed1c71 100644 --- a/src/cpu/core_dynrec/risc_armv4le.h +++ b/src/cpu/core_dynrec/risc_armv4le.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dynrec/risc_mipsel32.h b/src/cpu/core_dynrec/risc_mipsel32.h index 0e7d4745..a9aed644 100644 --- a/src/cpu/core_dynrec/risc_mipsel32.h +++ b/src/cpu/core_dynrec/risc_mipsel32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index e293e95b..35a3455a 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_dynrec/risc_x86.h b/src/cpu/core_dynrec/risc_x86.h index 81cb03bc..6b275ff8 100644 --- a/src/cpu/core_dynrec/risc_x86.h +++ b/src/cpu/core_dynrec/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 7fd14695..1d4ab155 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_full/ea_lookup.h b/src/cpu/core_full/ea_lookup.h index 6048a430..71e639dd 100644 --- a/src/cpu/core_full/ea_lookup.h +++ b/src/cpu/core_full/ea_lookup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 699803ca..7854d837 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_full/loadwrite.h b/src/cpu/core_full/loadwrite.h index b00ffb6c..86323577 100644 --- a/src/cpu/core_full/loadwrite.h +++ b/src/cpu/core_full/loadwrite.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 14786b1f..7e1a083a 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index b5680e5d..6494de00 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_full/save.h b/src/cpu/core_full/save.h index 408ed6d8..f587215a 100644 --- a/src/cpu/core_full/save.h +++ b/src/cpu/core_full/save.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index 8cb6ec03..64fc38cf 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index bdbe452a..cca7f4c5 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 1c034743..dc659fcd 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_normal/helpers.h b/src/cpu/core_normal/helpers.h index 13526f8b..dd0465f0 100644 --- a/src/cpu/core_normal/helpers.h +++ b/src/cpu/core_normal/helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 0fcf6b68..dc6ba3e1 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 29f2a188..87527d20 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 8f41f9a8..b23fb4d5 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 63f81ff8..deaed2c3 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_normal/string.h b/src/cpu/core_normal/string.h index 992ed42c..d1459072 100644 --- a/src/cpu/core_normal/string.h +++ b/src/cpu/core_normal/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index 6fe9a17c..02286fff 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_normal/table_ea.h b/src/cpu/core_normal/table_ea.h index 920f5ce8..28b73ff1 100644 --- a/src/cpu/core_normal/table_ea.h +++ b/src/cpu/core_normal/table_ea.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_prefetch.cpp b/src/cpu/core_prefetch.cpp index 47db2c11..de518167 100644 --- a/src/cpu/core_prefetch.cpp +++ b/src/cpu/core_prefetch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp index d8fdb9ea..98c35546 100644 --- a/src/cpu/core_simple.cpp +++ b/src/cpu/core_simple.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 29149972..7d28e7eb 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 1559af1e..3ceaa9e8 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 28af3314..ed6e46bc 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index c5e599f5..6cb688ed 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/modrm.cpp b/src/cpu/modrm.cpp index 028e4d71..6582c552 100644 --- a/src/cpu/modrm.cpp +++ b/src/cpu/modrm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/modrm.h b/src/cpu/modrm.h index 29656bfc..c854e579 100644 --- a/src/cpu/modrm.h +++ b/src/cpu/modrm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 7be15e1a..20aa225c 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 73e40ab0..2db3a41b 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index be122582..ae86ac21 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h index a94d3a8f..7dc736ab 100644 --- a/src/debug/debug_inc.h +++ b/src/debug/debug_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/debug/debug_win32.cpp b/src/debug/debug_win32.cpp index 0e0d48b5..38af8a33 100644 --- a/src/debug/debug_win32.cpp +++ b/src/debug/debug_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/debug/disasm_tables.h b/src/debug/disasm_tables.h index e3d12433..2c738c42 100644 --- a/src/debug/disasm_tables.h +++ b/src/debug/disasm_tables.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index ab98912c..87e8ae43 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index 79bb1a03..90e1334e 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index abc48ed1..5ea97b04 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index bd4cb411..a2bcc06a 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/cdrom_ioctl_linux.cpp b/src/dos/cdrom_ioctl_linux.cpp index 8fa0f235..a6f7b7f9 100644 --- a/src/dos/cdrom_ioctl_linux.cpp +++ b/src/dos/cdrom_ioctl_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/cdrom_ioctl_os2.cpp b/src/dos/cdrom_ioctl_os2.cpp index d96b45de..9cf4981a 100644 --- a/src/dos/cdrom_ioctl_os2.cpp +++ b/src/dos/cdrom_ioctl_os2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index 84e15e97..dd7cc0eb 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 10fb6747..5f762d1c 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index c35f6edf..19cf3187 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 1aec59fb..6c2e36d4 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 03d3f66a..fd3ec476 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 4b27cab0..2a9608ef 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index fa053a4f..e3a0cd0f 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 13e436b6..52e5d37d 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 056b752c..b22f9b2a 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index f59870fe..67761a3d 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index 2c9b6c46..400405ec 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index c1c96c24..46b8f590 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 9b1312e5..e905783d 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 1c00171e..5587f252 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index eb4d5f8b..c3418399 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index efca156c..07825b2d 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 6be44bd8..0efa15d5 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 94a30a56..396cc098 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index afb55fc1..28678cbf 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index 0429d007..92f9d830 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dos/drives.h b/src/dos/drives.h index 9d22da8c..6b7ef865 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/dosbox.cpp b/src/dosbox.cpp index a1e18dc3..2f3b4119 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 1e561143..25225ee6 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 54d0143c..37c08688 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index d837850d..fe49fd1b 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/gui/dosbox_logo.h b/src/gui/dosbox_logo.h index 7ba4ce20..f7592387 100644 --- a/src/gui/dosbox_logo.h +++ b/src/gui/dosbox_logo.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index d7a0c472..f1d3e2f2 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 6cc21d87..7a51e34d 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index 05aa3e18..66b4a28f 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index 6f7c4123..4b8ad101 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index b1163838..3bb9a45c 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/gui/render.cpp b/src/gui/render.cpp index af3b6b20..89a8334c 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/gui/render_loops.h b/src/gui/render_loops.h index 99d44066..0cfe5132 100644 --- a/src/gui/render_loops.h +++ b/src/gui/render_loops.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index 2f8d2ed3..eaf6bf34 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index 0e5265e3..b302664f 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/gui/render_simple.h b/src/gui/render_simple.h index 647bbb99..1b24e931 100644 --- a/src/gui/render_simple.h +++ b/src/gui/render_simple.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index dadfe528..ce1ca495 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/gui/render_templates_hq.h b/src/gui/render_templates_hq.h index 3eecb73e..843cdca0 100644 --- a/src/gui/render_templates_hq.h +++ b/src/gui/render_templates_hq.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/gui/render_templates_hq2x.h b/src/gui/render_templates_hq2x.h index eed48357..3b3a40a3 100644 --- a/src/gui/render_templates_hq2x.h +++ b/src/gui/render_templates_hq2x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/gui/render_templates_hq3x.h b/src/gui/render_templates_hq3x.h index 1788be23..0ec55839 100644 --- a/src/gui/render_templates_hq3x.h +++ b/src/gui/render_templates_hq3x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/gui/render_templates_sai.h b/src/gui/render_templates_sai.h index 72a28285..484ad9e8 100644 --- a/src/gui/render_templates_sai.h +++ b/src/gui/render_templates_sai.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index 01fe6b7a..229176ea 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 @@ -569,7 +569,7 @@ public: Section_prop *section = static_cast(sec); new SectionEditor(getScreen(), 50, 30, section); } else if (arg == "About") { - new GUI::MessageBox(getScreen(), 200, 150, 280, "About DOSBox", "\nDOSBox 0.74\nAn emulator for old DOS Games\n\nCopyright 2002-2015\nThe DOSBox Team"); + new GUI::MessageBox(getScreen(), 200, 150, 280, "About DOSBox", "\nDOSBox 0.74\nAn emulator for old DOS Games\n\nCopyright 2002-2017\nThe DOSBox Team"); } else if (arg == "Introduction") { new GUI::MessageBox(getScreen(), 20, 50, 600, "Introduction", MSG_Get("PROGRAM_INTRO")); } else if (arg == "Getting Started") { diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index aa861cd7..c583cdf8 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 84b8be4f..c59815dc 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 @@ -1941,7 +1941,7 @@ int main(int argc, char* argv[]) { #endif //defined(WIN32) && !(C_DEBUG) if (control->cmdline->FindExist("-version") || control->cmdline->FindExist("--version") ) { - printf("\nDOSBox version %s, copyright 2002-2015 DOSBox Team.\n\n",VERSION); + printf("\nDOSBox version %s, copyright 2002-2017 DOSBox Team.\n\n",VERSION); printf("DOSBox is written by the DOSBox Team (See AUTHORS file))\n"); printf("DOSBox comes with ABSOLUTELY NO WARRANTY. This is free software,\n"); printf("and you are welcome to redistribute it under certain conditions;\n"); @@ -1969,7 +1969,7 @@ int main(int argc, char* argv[]) { /* Display Welcometext in the console */ LOG_MSG("DOSBox version %s",VERSION); - LOG_MSG("Copyright 2002-2015 DOSBox Team, published under GNU GPL."); + LOG_MSG("Copyright 2002-2017 DOSBox Team, published under GNU GPL."); LOG_MSG("---"); /* Init SDL */ diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 8168e2cf..836a3e21 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/adlib.h b/src/hardware/adlib.h index 26114c2c..eafbaaf0 100644 --- a/src/hardware/adlib.h +++ b/src/hardware/adlib.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 0628a042..68390b34 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index 44b8a34e..c7d61ca3 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/dbopl.h b/src/hardware/dbopl.h index 1a255fd8..c3c4d428 100644 --- a/src/hardware/dbopl.h +++ b/src/hardware/dbopl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 44fd7e3c..12cc020d 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 1b738e57..5eb69498 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index dffda0d0..a3906054 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 7512a48f..2786e442 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index baeeb1db..26fdfe85 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 1fd19ccb..88448fdc 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index 3369aad7..7d8dd5d3 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/ipxserver.cpp b/src/hardware/ipxserver.cpp index a233c484..1f478121 100644 --- a/src/hardware/ipxserver.cpp +++ b/src/hardware/ipxserver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index ca6161b6..d30d234c 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index f85f5ab4..7872b2ba 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 73d5c8e0..972f9dd7 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index b846e0e4..5673e714 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 8d3cdf4f..1eff7ec3 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2012 The DOSBox Team + * Copyright (C) 2002-2017 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 @@ -200,7 +200,7 @@ static void MPU401_WriteCommand(Bitu port,Bitu val,Bitu iolen) { mpu.clock.timebase=192; break; /* Commands with data byte */ - case 0xe0: case 0xe1: case 0xe2: case 0xe4: case 0xe6: + case 0xe0: case 0xe1: case 0xe2: case 0xe4: case 0xe6: case 0xe7: case 0xec: case 0xed: case 0xee: case 0xef: mpu.state.command_byte=val; break; @@ -451,7 +451,7 @@ static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) { mpu.playbuf[mpu.state.channel].type=T_MIDI_NORM; length=mpu.playbuf[mpu.state.channel].length=2; break; - case 0x80: case 0x90: case 0xa0: case 0xb0: case 0xe0: + case 0x80: case 0x90: case 0xa0: case 0xb0: case 0xe0: mpu.playbuf[mpu.state.channel].type=T_MIDI_NORM; length=mpu.playbuf[mpu.state.channel].length=3; break; @@ -523,7 +523,7 @@ static void MPU401_Event(Bitu val) { mpu.playbuf[i].counter--; if (mpu.playbuf[i].counter<=0) UpdateTrack(i); } - } + } if (mpu.state.conductor) { mpu.condbuf.counter--; if (mpu.condbuf.counter<=0) UpdateConductor(); @@ -628,12 +628,12 @@ public: if (!MIDI_Available()) return; /*Enabled and there is a Midi */ installed = true; - + WriteHandler[0].Install(0x330,&MPU401_WriteData,IO_MB); WriteHandler[1].Install(0x331,&MPU401_WriteCommand,IO_MB); ReadHandler[0].Install(0x330,&MPU401_ReadData,IO_MB); ReadHandler[1].Install(0x331,&MPU401_ReadStatus,IO_MB); - + mpu.queue_used=0; mpu.queue_pos=0; mpu.mode=M_UART; diff --git a/src/hardware/opl.cpp b/src/hardware/opl.cpp index deff8dd8..af7afb33 100644 --- a/src/hardware/opl.cpp +++ b/src/hardware/opl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 The DOSBox Team * OPL2/OPL3 emulation library * * This library is free software; you can redistribute it and/or diff --git a/src/hardware/opl.h b/src/hardware/opl.h index 41132c3a..497b97ef 100644 --- a/src/hardware/opl.h +++ b/src/hardware/opl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 The DOSBox Team * OPL2/OPL3 emulation library * * This library is free software; you can redistribute it and/or diff --git a/src/hardware/pci_bus.cpp b/src/hardware/pci_bus.cpp index de3bd677..1a9f962b 100644 --- a/src/hardware/pci_bus.cpp +++ b/src/hardware/pci_bus.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/pci_devices.h b/src/hardware/pci_devices.h index 29d4d362..a61c7634 100644 --- a/src/hardware/pci_devices.h +++ b/src/hardware/pci_devices.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 3e166fc6..5a0069ec 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index ce2c7df4..4f37a09d 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 80376a67..15f87e7b 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/serialport/directserial.cpp b/src/hardware/serialport/directserial.cpp index 00f2340f..88c2bc99 100644 --- a/src/hardware/serialport/directserial.cpp +++ b/src/hardware/serialport/directserial.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/serialport/directserial.h b/src/hardware/serialport/directserial.h index 429e6f83..e60a88f2 100644 --- a/src/hardware/serialport/directserial.h +++ b/src/hardware/serialport/directserial.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/serialport/libserial.cpp b/src/hardware/serialport/libserial.cpp index aa65571a..aa5e9168 100644 --- a/src/hardware/serialport/libserial.cpp +++ b/src/hardware/serialport/libserial.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/serialport/libserial.h b/src/hardware/serialport/libserial.h index a0143b90..f951e4dc 100644 --- a/src/hardware/serialport/libserial.h +++ b/src/hardware/serialport/libserial.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/serialport/misc_util.cpp b/src/hardware/serialport/misc_util.cpp index 147ef2fe..8d1ae2e6 100644 --- a/src/hardware/serialport/misc_util.cpp +++ b/src/hardware/serialport/misc_util.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/serialport/misc_util.h b/src/hardware/serialport/misc_util.h index 31cd1d2f..989c6dd3 100644 --- a/src/hardware/serialport/misc_util.h +++ b/src/hardware/serialport/misc_util.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/serialport/nullmodem.cpp b/src/hardware/serialport/nullmodem.cpp index 2865073a..69182db7 100644 --- a/src/hardware/serialport/nullmodem.cpp +++ b/src/hardware/serialport/nullmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/serialport/nullmodem.h b/src/hardware/serialport/nullmodem.h index b70d2940..d1aff414 100644 --- a/src/hardware/serialport/nullmodem.h +++ b/src/hardware/serialport/nullmodem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/serialport/serialdummy.cpp b/src/hardware/serialport/serialdummy.cpp index b2019cde..790237d5 100644 --- a/src/hardware/serialport/serialdummy.cpp +++ b/src/hardware/serialport/serialdummy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/serialport/serialdummy.h b/src/hardware/serialport/serialdummy.h index 88e44b3b..bb4b5fb2 100644 --- a/src/hardware/serialport/serialdummy.h +++ b/src/hardware/serialport/serialdummy.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index f640866c..6ce00c19 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index d135b8f4..0cd87105 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index 72b80f44..c50f8d48 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 9e2dfb84..5d3ef2ea 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 454324ad..da562b48 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 9be527ff..dd25069e 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index ba5ed16c..dd914db7 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index dbaf26b3..baceb8f9 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index fb3bce3b..96833d20 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 470f5e61..0ec12738 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index 1281aadb..76247fd6 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 619f81b3..d354f472 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 0271f265..122c1455 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index b91fe562..e8115eed 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/vga_paradise.cpp b/src/hardware/vga_paradise.cpp index d0929a5e..345054a8 100644 --- a/src/hardware/vga_paradise.cpp +++ b/src/hardware/vga_paradise.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index abdab61f..a0e7204a 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index f7b96b0e..74f3c425 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/vga_tseng.cpp b/src/hardware/vga_tseng.cpp index 4fae1771..cf8482fd 100644 --- a/src/hardware/vga_tseng.cpp +++ b/src/hardware/vga_tseng.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index 2cd85059..a5398a52 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 2cf70a54..bcfbfb10 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 32d93e7c..67694677 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 7628a22a..ca0c75af 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 2b70e828..b3dd104b 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 1ca92ea9..1a8d614d 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/ints/int10.h b/src/ints/int10.h index d53065da..93f985b9 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 259d8a56..45dfee71 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 5c2f9528..383f972b 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 31462394..23c91639 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index d47c0b23..333f0bcb 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 4633ffaa..77696267 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 145288cc..f89dd0d8 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 3f3c59ec..32559e23 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/ints/int10_video_state.cpp b/src/ints/int10_video_state.cpp index 4a8e6cdf..2a6c2613 100644 --- a/src/ints/int10_video_state.cpp +++ b/src/ints/int10_video_state.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/ints/int10_vptable.cpp b/src/ints/int10_vptable.cpp index 41693182..165ac320 100644 --- a/src/ints/int10_vptable.cpp +++ b/src/ints/int10_vptable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 3b337e50..4eee708e 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index da5725ac..05286028 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/ints/xms.h b/src/ints/xms.h index 409bbac8..81eb8d36 100644 --- a/src/ints/xms.h +++ b/src/ints/xms.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/libs/zmbv/drvproc.cpp b/src/libs/zmbv/drvproc.cpp index 6ceeece3..7007c8d3 100644 --- a/src/libs/zmbv/drvproc.cpp +++ b/src/libs/zmbv/drvproc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/libs/zmbv/zmbv.cpp b/src/libs/zmbv/zmbv.cpp index af554530..0318a777 100644 --- a/src/libs/zmbv/zmbv.cpp +++ b/src/libs/zmbv/zmbv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/libs/zmbv/zmbv.h b/src/libs/zmbv/zmbv.h index 558ef9ea..1826e56e 100644 --- a/src/libs/zmbv/zmbv.h +++ b/src/libs/zmbv/zmbv.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/libs/zmbv/zmbv_vfw.cpp b/src/libs/zmbv/zmbv_vfw.cpp index 1964546b..a5cbc4e8 100644 --- a/src/libs/zmbv/zmbv_vfw.cpp +++ b/src/libs/zmbv/zmbv_vfw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/libs/zmbv/zmbv_vfw.rc b/src/libs/zmbv/zmbv_vfw.rc index 3f29bfe2..8929ab1b 100644 --- a/src/libs/zmbv/zmbv_vfw.rc +++ b/src/libs/zmbv/zmbv_vfw.rc @@ -59,7 +59,7 @@ CAPTION "DOSBox Video Codec v0.1" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN DEFPUSHBUTTON "OK",IDOK,131,34,29,14 - CTEXT "Zipped Motion Block Video v 0.1\nCopyright 2009-2015 DOSBox Team", + CTEXT "Zipped Motion Block Video v 0.1\nCopyright 2009-2017 DOSBox Team", IDC_STATIC,7,7,153,25,SS_NOPREFIX PUSHBUTTON "Email author",IDC_EMAIL,7,34,50,14 PUSHBUTTON "Visit home page",IDC_HOMEPAGE,59,34,58,14 diff --git a/src/misc/cross.cpp b/src/misc/cross.cpp index 60a13b21..09290c56 100644 --- a/src/misc/cross.cpp +++ b/src/misc/cross.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 313129d3..6f4c7586 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 15449644..2f8e6c7f 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 9ea232ba..c79ae665 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/misc/support.cpp b/src/misc/support.cpp index b84c4b84..67bbe11d 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index a8dde5fb..01f8a41f 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 3df12ef2..e76866fc 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 3cfb13c6..09654ec7 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index d131e7a8..1fdb5d7e 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2015 The DOSBox Team + * Copyright (C) 2002-2017 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 diff --git a/src/winres.rc b/src/winres.rc index 67309841..0ab415f5 100644 --- a/src/winres.rc +++ b/src/winres.rc @@ -19,12 +19,12 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "Comments", "© 2002-2015 DOSBox Team, published under GNU GPL" + VALUE "Comments", "© 2002-2017 DOSBox Team, published under GNU GPL" VALUE "CompanyName", "DOSBox Team" VALUE "FileDescription", "DOSBox DOS Emulator" VALUE "FileVersion", "0, 74, 0, 0" VALUE "InternalName", "DOSBox" - VALUE "LegalCopyright", "Copyright © 2002-2015 DOSBox Team" + VALUE "LegalCopyright", "Copyright © 2002-2017 DOSBox Team" VALUE "OriginalFilename", "dosbox.exe" VALUE "ProductName", "DOSBox DOS Emulator" VALUE "ProductVersion", "0, 74, 0, 0" From 085c7a2f18c94e656c73e9f93651e1b9e63da522 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 8 Jun 2017 17:32:17 +0000 Subject: [PATCH 3932/4131] Update mixer volume calculations for the SBPRO1,2 and SB16. Thanks for the measurements James-F. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4022 --- src/hardware/sblaster.cpp | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 15f87e7b..836f5c81 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1098,21 +1098,33 @@ static Bit8u DSP_ReadData(void) { return sb.dsp.out.lastval; } -//The soundblaster manual says 2.0 Db steps but we'll go for a bit less -#define CALCVOL(_VAL) (float)pow(10.0f,((float)(31-_VAL)*-1.3f)/20) +static float calc_vol(Bit8u amount) { + Bit8u count = 31 - amount; + float db = static_cast(count); + if (sb.type == SBT_PRO1 || sb.type == SBT_PRO2) { + if (count) { + if (count < 16) db -= 1.0f; + else if (count > 16) db += 1.0f; + if (count == 24) db += 2.0f; + if (count > 27) return 0.0f; //turn it off. + } + } else { //Give the rest, the SB16 scale, as we don't have data. + db *= 2.0f; + if (count > 20) db -= 1.0f; + } + return (float) pow (10.0f,-0.05f * db); +} static void CTMIXER_UpdateVolumes(void) { if (!sb.mixer.enabled) return; MixerChannel * chan; - //adjust to get linear master volume slider in trackers - chan=MIXER_FindChannel("SB"); - if (chan) chan->SetVolume(float(sb.mixer.master[0])/31.0f*CALCVOL(sb.mixer.dac[0]), - float(sb.mixer.master[1])/31.0f*CALCVOL(sb.mixer.dac[1])); - chan=MIXER_FindChannel("FM"); - if (chan) chan->SetVolume(float(sb.mixer.master[0])/31.0f*CALCVOL(sb.mixer.fm[0]), - float(sb.mixer.master[1])/31.0f*CALCVOL(sb.mixer.fm[1])); - chan=MIXER_FindChannel("CDAUDIO"); - if (chan) chan->SetVolume(float(sb.mixer.master[0])/31.0f*CALCVOL(sb.mixer.cda[0]), - float(sb.mixer.master[1])/31.0f*CALCVOL(sb.mixer.cda[1])); + float m0 = calc_vol(sb.mixer.master[0]); + float m1 = calc_vol(sb.mixer.master[1]); + chan = MIXER_FindChannel("SB"); + if (chan) chan->SetVolume(m0 * calc_vol(sb.mixer.dac[0]), m1 * calc_vol(sb.mixer.dac[1])); + chan = MIXER_FindChannel("FM"); + if (chan) chan->SetVolume(m0 * calc_vol(sb.mixer.fm[0]) , m1 * calc_vol(sb.mixer.fm[1]) ); + chan = MIXER_FindChannel("CDAUDIO"); + if (chan) chan->SetVolume(m0 * calc_vol(sb.mixer.cda[0]), m1 * calc_vol(sb.mixer.cda[1])); } static void CTMIXER_Reset(void) { From df0fa99d8851767220f6232ae78f4c726e5e7a5a Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Thu, 15 Jun 2017 16:04:44 +0000 Subject: [PATCH 3933/4131] Correct an oversight in I/O exceptions. Fixes bug #460. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4023 --- src/hardware/iohandler.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 88448fdc..619808ec 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -404,6 +404,7 @@ Bitu IO_ReadB(Bitu port) { entry->eip=reg_eip; CPU_Push16(SegValue(cs)); CPU_Push16(reg_ip); + Bit8u old_al = reg_al; Bit16u old_dx = reg_dx; reg_dx = port; RealPt icb = CALLBACK_RealPointer(call_priv_io); @@ -415,6 +416,7 @@ Bitu IO_ReadB(Bitu port) { iof_queue.used--; retval = reg_al; + reg_al = old_al; reg_dx = old_dx; memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); cpudecoder=old_cpudecoder; @@ -441,6 +443,7 @@ Bitu IO_ReadW(Bitu port) { entry->eip=reg_eip; CPU_Push16(SegValue(cs)); CPU_Push16(reg_ip); + Bit16u old_ax = reg_ax; Bit16u old_dx = reg_dx; reg_dx = port; RealPt icb = CALLBACK_RealPointer(call_priv_io); @@ -452,6 +455,7 @@ Bitu IO_ReadW(Bitu port) { iof_queue.used--; retval = reg_ax; + reg_ax = old_ax; reg_dx = old_dx; memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); cpudecoder=old_cpudecoder; @@ -477,6 +481,7 @@ Bitu IO_ReadD(Bitu port) { entry->eip=reg_eip; CPU_Push16(SegValue(cs)); CPU_Push16(reg_ip); + Bit32u old_eax = reg_eax; Bit16u old_dx = reg_dx; reg_dx = port; RealPt icb = CALLBACK_RealPointer(call_priv_io); @@ -488,6 +493,7 @@ Bitu IO_ReadD(Bitu port) { iof_queue.used--; retval = reg_eax; + reg_eax = old_eax; reg_dx = old_dx; memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); cpudecoder=old_cpudecoder; From dc5b586c2823f0658add0fa1474bbfbd42ae0498 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 19 Jun 2017 09:09:59 +0000 Subject: [PATCH 3934/4131] Forgot to initiliaze a field. Thanks Mok Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4024 --- src/hardware/hardware.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 26fdfe85..14958c3a 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -361,7 +361,7 @@ void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags, } #ifdef PNG_TEXT_SUPPORTED int fields = 1; - png_text text[1]; + png_text text[1] = {}; const char* text_s = "DOSBox " VERSION; size_t strl = strlen(text_s); char* ptext_s = new char[strl + 1]; From cbab462c971445c17a0141865f1618de992f0813 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 2 Jul 2017 08:23:47 +0000 Subject: [PATCH 3935/4131] Fix issue with debugger not executing dosbox callbacks in stepover Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4025 --- src/debug/debug.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 2db3a41b..d7320bd7 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1734,8 +1734,8 @@ Bit32u DEBUG_CheckKeys(void) { // ensure all breakpoints are activated CBreakpoint::ActivateBreakpoints(); - - return 0; + skipDraw = true; + break; } // If we aren't stepping over something, do a normal step. // NB: Fall-through From df166ff0a4eae0126f0875a8271c62818b8e03fb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 6 Aug 2017 14:21:03 +0000 Subject: [PATCH 3936/4131] As we zero out the memory on startup for a long time now. This should not exit anymore. Leaving the warning for now. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4026 --- src/cpu/cpu.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 7d28e7eb..832e000c 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -551,8 +551,8 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { case 0xcd: #if C_HEAVY_DEBUG LOG(LOG_CPU,LOG_ERROR)("Call to interrupt 0xCD this is BAD"); - DEBUG_HeavyWriteLogInstruction(); - E_Exit("Call to interrupt 0xCD this is BAD"); +// DEBUG_HeavyWriteLogInstruction(); +// E_Exit("Call to interrupt 0xCD this is BAD"); #endif break; case 0x03: From 1e72be6a96e1bafd18ae13a30d7f952ff32f8787 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 6 Aug 2017 14:22:01 +0000 Subject: [PATCH 3937/4131] Otherwise debugging makes no sense. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4027 --- src/cpu/core_dyn_x86.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 66b3fb97..aae65cb4 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -296,6 +296,9 @@ restart_core: run_block: cache.block.running=0; BlockReturn ret=gen_runcode(block->cache.start); +#if C_DEBUG + cycle_count += 32; +#endif switch (ret) { case BR_Iret: #if C_DEBUG From 2719d869a049e4b92530f4d3868baa0311b01b0b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 8 Aug 2017 16:58:36 +0000 Subject: [PATCH 3938/4131] make increaseticks a separate function and rewrite it for easier reading. The behaviour is identical. No fixes! Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4028 --- src/dosbox.cpp | 181 +++++++++++++++++++++++++++---------------------- 1 file changed, 99 insertions(+), 82 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 2f3b4119..d1c5c253 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -128,6 +128,7 @@ static Bit32u ticksAdded; Bit32s ticksDone; Bit32u ticksScheduled; bool ticksLocked; +void increaseticks(); static Bitu Normal_Loop(void) { Bits ret; @@ -148,102 +149,118 @@ static Bitu Normal_Loop(void) { if (ticksRemain>0) { TIMER_AddTick(); ticksRemain--; - } else goto increaseticks; + } else {increaseticks();return 0;} } } -increaseticks: - if (GCC_UNLIKELY(ticksLocked)) { +} + +void increaseticks() { //Make it return ticksRemain and set it in the function above to remove the global variable. + if (GCC_UNLIKELY(ticksLocked)) { // For Fast Forward Mode ticksRemain=5; /* Reset any auto cycle guessing for this frame */ ticksLast = GetTicks(); ticksAdded = 0; ticksDone = 0; ticksScheduled = 0; - } else { - Bit32u ticksNew; - ticksNew=GetTicks(); - ticksScheduled += ticksAdded; - if (ticksNew > ticksLast) { - ticksRemain = ticksNew-ticksLast; - ticksLast = ticksNew; - ticksDone += ticksRemain; - if ( ticksRemain > 20 ) { - ticksRemain = 20; + return; + } + + Bit32u ticksNew; + ticksNew = GetTicks(); + ticksScheduled += ticksAdded; + if (ticksNew <= ticksLast) { //lower should not be possible, only equal. + ticksAdded = 0; + SDL_Delay(1); + ticksDone -= GetTicks() - ticksNew; + if (ticksDone < 0) + ticksDone = 0; + return; //0 + + // If we do work this tick and sleep till the next tick, then ticksDone is decreased, + // despite the fact that work was done as well in this tick. Maybe make it depend on an extra parameter. + // What do we know: ticksRemain = 0 (condition to enter this function) + // ticksNew = time before sleeping + + // maybe keep track of sleeped time in this frame, and use sleeped and done as indicators. (and take care of the fact there + // are frames that have both. + } + + //TicksNew > ticksLast + ticksRemain = ticksNew-ticksLast; + ticksLast = ticksNew; + ticksDone += ticksRemain; + if ( ticksRemain > 20 ) { +// LOG(LOG_MISC,LOG_ERROR)("large remain %d",ticksRemain); + ticksRemain = 20; + } + ticksAdded = ticksRemain; + + // Is the system in auto cycle mode guessing ? If not just exit. (It can be temporary disabled) + if (!CPU_CycleAutoAdjust || CPU_SkipCycleAutoAdjust) return; + + if (ticksScheduled >= 250 || ticksDone >= 250 || (ticksAdded > 15 && ticksScheduled >= 5) ) { + if(ticksDone < 1) ticksDone = 1; // Protect against div by zero + /* ratio we are aiming for is around 90% usage*/ + Bit32s ratio = (ticksScheduled * (CPU_CyclePercUsed*90*1024/100/100)) / ticksDone; + Bit32s new_cmax = CPU_CycleMax; + Bit64s cproc = (Bit64s)CPU_CycleMax * (Bit64s)ticksScheduled; + if (cproc > 0) { + /* ignore the cycles added due to the IO delay code in order + to have smoother auto cycle adjustments */ + double ratioremoved = (double) CPU_IODelayRemoved / (double) cproc; + if (ratioremoved < 1.0) { + ratio = (Bit32s)((double)ratio * (1 - ratioremoved)); + /* Don't allow very high ratio which can cause us to lock as we don't scale down + * for very low ratios. High ratio might result because of timing resolution */ + if (ticksScheduled >= 250 && ticksDone < 10 && ratio > 20480) + ratio = 20480; + Bit64s cmax_scaled = (Bit64s)CPU_CycleMax * (Bit64s)ratio; + /* The auto cycle code seems reliable enough to disable the fast cut back code. + * This should improve the fluency of complex games. + if (ratio <= 1024) + new_cmax = (Bit32s)(cmax_scaled / (Bit64s)1024); + else + */ + new_cmax = (Bit32s)(1 + (CPU_CycleMax >> 1) + cmax_scaled / (Bit64s)2048); } - ticksAdded = ticksRemain; - if (CPU_CycleAutoAdjust && !CPU_SkipCycleAutoAdjust) { - if (ticksScheduled >= 250 || ticksDone >= 250 || (ticksAdded > 15 && ticksScheduled >= 5) ) { - if(ticksDone < 1) ticksDone = 1; // Protect against div by zero - /* ratio we are aiming for is around 90% usage*/ - Bit32s ratio = (ticksScheduled * (CPU_CyclePercUsed*90*1024/100/100)) / ticksDone; - Bit32s new_cmax = CPU_CycleMax; - Bit64s cproc = (Bit64s)CPU_CycleMax * (Bit64s)ticksScheduled; - if (cproc > 0) { - /* ignore the cycles added due to the IO delay code in order - to have smoother auto cycle adjustments */ - double ratioremoved = (double) CPU_IODelayRemoved / (double) cproc; - if (ratioremoved < 1.0) { - ratio = (Bit32s)((double)ratio * (1 - ratioremoved)); - /* Don't allow very high ratio which can cause us to lock as we don't scale down - * for very low ratios. High ratio might result because of timing resolution */ - if (ticksScheduled >= 250 && ticksDone < 10 && ratio > 20480) - ratio = 20480; - Bit64s cmax_scaled = (Bit64s)CPU_CycleMax * (Bit64s)ratio; - /* The auto cycle code seems reliable enough to disable the fast cut back code. - * This should improve the fluency of complex games. - if (ratio <= 1024) - new_cmax = (Bit32s)(cmax_scaled / (Bit64s)1024); - else - */ - new_cmax = (Bit32s)(1 + (CPU_CycleMax >> 1) + cmax_scaled / (Bit64s)2048); - } - } + } - if (new_cmax10) { - /* ratios below 12% along with a large time since the last update - has taken place are most likely caused by heavy load through a - different application, the cycles adjusting is skipped as well */ - if ((ratio>120) || (ticksDone<700)) { - CPU_CycleMax = new_cmax; - if (CPU_CycleLimit > 0) { - if (CPU_CycleMax>CPU_CycleLimit) CPU_CycleMax = CPU_CycleLimit; - } - } - } - CPU_IODelayRemoved = 0; - ticksDone = 0; - ticksScheduled = 0; - } else if (ticksAdded > 15) { - /* ticksAdded > 15 but ticksScheduled < 5, lower the cycles - but do not reset the scheduled/done ticks to take them into - account during the next auto cycle adjustment */ - CPU_CycleMax /= 3; - if (CPU_CycleMax < CPU_CYCLES_LOWER_LIMIT) - CPU_CycleMax = CPU_CYCLES_LOWER_LIMIT; + /* ratios below 1% are considered to be dropouts due to + temporary load imbalance, the cycles adjusting is skipped */ + if (ratio > 10) { + /* ratios below 12% along with a large time since the last update + has taken place are most likely caused by heavy load through a + different application, the cycles adjusting is skipped as well */ + if ((ratio > 120) || (ticksDone < 700)) { + CPU_CycleMax = new_cmax; + if (CPU_CycleLimit > 0) { + if (CPU_CycleMax > CPU_CycleLimit) CPU_CycleMax = CPU_CycleLimit; } } - } else { - ticksAdded = 0; - SDL_Delay(1); - ticksDone -= GetTicks() - ticksNew; - if (ticksDone < 0) - ticksDone = 0; } - } - return 0; + CPU_IODelayRemoved = 0; + ticksDone = 0; + ticksScheduled = 0; + } else if (ticksAdded > 15) { + /* ticksAdded > 15 but ticksScheduled < 5, lower the cycles + but do not reset the scheduled/done ticks to take them into + account during the next auto cycle adjustment */ + CPU_CycleMax /= 3; + if (CPU_CycleMax < CPU_CYCLES_LOWER_LIMIT) + CPU_CycleMax = CPU_CYCLES_LOWER_LIMIT; + } //if (ticksScheduled >= 250 || ticksDone >= 250 || (ticksAdded > 15 && ticksScheduled >= 5) ) } void DOSBOX_SetLoop(LoopHandler * handler) { From 286818762da063f43a355600bf763b04938dd97f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 8 Aug 2017 17:34:08 +0000 Subject: [PATCH 3939/4131] Repair a logic error introduced in r3816. Now both cases use an appropriate average. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4029 --- src/dosbox.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index d1c5c253..7308d8c5 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -214,14 +214,13 @@ void increaseticks() { //Make it return ticksRemain and set it in the function a * for very low ratios. High ratio might result because of timing resolution */ if (ticksScheduled >= 250 && ticksDone < 10 && ratio > 20480) ratio = 20480; - Bit64s cmax_scaled = (Bit64s)CPU_CycleMax * (Bit64s)ratio; - /* The auto cycle code seems reliable enough to disable the fast cut back code. - * This should improve the fluency of complex games. - if (ratio <= 1024) - new_cmax = (Bit32s)(cmax_scaled / (Bit64s)1024); - else - */ - new_cmax = (Bit32s)(1 + (CPU_CycleMax >> 1) + cmax_scaled / (Bit64s)2048); + if (ratio <= 1024) { + double r = 2.0 /(1.0 + 1024.0/(static_cast(ratio))); + new_cmax = 1 + static_cast(CPU_CycleMax * r); + } else { + Bit64s cmax_scaled = (Bit64s)CPU_CycleMax * (Bit64s)ratio; + new_cmax = (Bit32s)(1 + (CPU_CycleMax >> 1) + cmax_scaled / (Bit64s)2048); + } } } From a6cae1a8f5fa24e6afe53c27112f674b8fbd03d4 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 12 Aug 2017 08:58:26 +0000 Subject: [PATCH 3940/4131] Try latest mame sound cores Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/branches/mamesound@4030 From 6c796f4162eb6855c7dd6041f58493e7b99a6815 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 12 Aug 2017 09:11:40 +0000 Subject: [PATCH 3941/4131] Clean mame versions from 10 August 2017 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/branches/mamesound@4031 --- src/hardware/mame/fmopl.cpp | 2572 +++++++++++++++++++++++++++++ src/hardware/mame/fmopl.h | 109 ++ src/hardware/mame/saa1099.cpp | 458 ++++++ src/hardware/mame/saa1099.h | 96 ++ src/hardware/mame/sn76496.cpp | 474 ++++++ src/hardware/mame/sn76496.h | 155 ++ src/hardware/mame/ymdeltat.cpp | 650 ++++++++ src/hardware/mame/ymdeltat.h | 85 + src/hardware/mame/ymf262.cpp | 2788 ++++++++++++++++++++++++++++++++ src/hardware/mame/ymf262.h | 40 + 10 files changed, 7427 insertions(+) create mode 100644 src/hardware/mame/fmopl.cpp create mode 100644 src/hardware/mame/fmopl.h create mode 100644 src/hardware/mame/saa1099.cpp create mode 100644 src/hardware/mame/saa1099.h create mode 100644 src/hardware/mame/sn76496.cpp create mode 100644 src/hardware/mame/sn76496.h create mode 100644 src/hardware/mame/ymdeltat.cpp create mode 100644 src/hardware/mame/ymdeltat.h create mode 100644 src/hardware/mame/ymf262.cpp create mode 100644 src/hardware/mame/ymf262.h diff --git a/src/hardware/mame/fmopl.cpp b/src/hardware/mame/fmopl.cpp new file mode 100644 index 00000000..a9c15478 --- /dev/null +++ b/src/hardware/mame/fmopl.cpp @@ -0,0 +1,2572 @@ +// license:GPL-2.0+ +// copyright-holders:Jarek Burczynski,Tatsuyuki Satoh +/* +** +** File: fmopl.c - software implementation of FM sound generator +** types OPL and OPL2 +** +** Copyright Jarek Burczynski (bujar at mame dot net) +** Copyright Tatsuyuki Satoh , MultiArcadeMachineEmulator development +** +** Version 0.72 +** + +Revision History: + +04-08-2003 Jarek Burczynski: + - removed BFRDY hack. BFRDY is busy flag, and it should be 0 only when the chip + handles memory read/write or during the adpcm synthesis when the chip + requests another byte of ADPCM data. + +24-07-2003 Jarek Burczynski: + - added a small hack for Y8950 status BFRDY flag (bit 3 should be set after + some (unknown) delay). Right now it's always set. + +14-06-2003 Jarek Burczynski: + - implemented all of the status register flags in Y8950 emulation + - renamed y8950_set_delta_t_memory() parameters from _rom_ to _mem_ since + they can be either RAM or ROM + +08-10-2002 Jarek Burczynski (thanks to Dox for the YM3526 chip) + - corrected ym3526_read() to always set bit 2 and bit 1 + to HIGH state - identical to ym3812_read (verified on real YM3526) + +04-28-2002 Jarek Burczynski: + - binary exact Envelope Generator (verified on real YM3812); + compared to YM2151: the EG clock is equal to internal_clock, + rates are 2 times slower and volume resolution is one bit less + - modified interface functions (they no longer return pointer - + that's internal to the emulator now): + - new wrapper functions for OPLCreate: ym3526_init(), ym3812_init() and y8950_init() + - corrected 'off by one' error in feedback calculations (when feedback is off) + - enabled waveform usage (credit goes to Vlad Romascanu and zazzal22) + - speeded up noise generator calculations (Nicola Salmoria) + +03-24-2002 Jarek Burczynski (thanks to Dox for the YM3812 chip) + Complete rewrite (all verified on real YM3812): + - corrected sin_tab and tl_tab data + - corrected operator output calculations + - corrected waveform_select_enable register; + simply: ignore all writes to waveform_select register when + waveform_select_enable == 0 and do not change the waveform previously selected. + - corrected KSR handling + - corrected Envelope Generator: attack shape, Sustain mode and + Percussive/Non-percussive modes handling + - Envelope Generator rates are two times slower now + - LFO amplitude (tremolo) and phase modulation (vibrato) + - rhythm sounds phase generation + - white noise generator (big thanks to Olivier Galibert for mentioning Berlekamp-Massey algorithm) + - corrected key on/off handling (the 'key' signal is ORed from three sources: FM, rhythm and CSM) + - funky details (like ignoring output of operator 1 in BD rhythm sound when connect == 1) + +12-28-2001 Acho A. Tang + - reflected Delta-T EOS status on Y8950 status port. + - fixed subscription range of attack/decay tables + + + To do: + add delay before key off in CSM mode (see CSMKeyControll) + verify volume of the FM part on the Y8950 +*/ + +#include "emu.h" +#include "ymdeltat.h" +#include "fmopl.h" + + + +/* output final shift */ +#if (OPL_SAMPLE_BITS==16) + #define FINAL_SH (0) + #define MAXOUT (+32767) + #define MINOUT (-32768) +#else + #define FINAL_SH (8) + #define MAXOUT (+127) + #define MINOUT (-128) +#endif + + +#define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */ +#define EG_SH 16 /* 16.16 fixed point (EG timing) */ +#define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */ +#define TIMER_SH 16 /* 16.16 fixed point (timers calculations) */ + +#define FREQ_MASK ((1<=0) + { + if (value < 0x0200) + return (value & ~0); + if (value < 0x0400) + return (value & ~1); + if (value < 0x0800) + return (value & ~3); + if (value < 0x1000) + return (value & ~7); + if (value < 0x2000) + return (value & ~15); + if (value < 0x4000) + return (value & ~31); + return (value & ~63); + } + /*else value < 0*/ + if (value > -0x0200) + return (~abs(value) & ~0); + if (value > -0x0400) + return (~abs(value) & ~1); + if (value > -0x0800) + return (~abs(value) & ~3); + if (value > -0x1000) + return (~abs(value) & ~7); + if (value > -0x2000) + return (~abs(value) & ~15); + if (value > -0x4000) + return (~abs(value) & ~31); + return (~abs(value) & ~63); +} + + +static FILE *sample[1]; + #if 1 /*save to MONO file */ + #define SAVE_ALL_CHANNELS \ + { signed int pom = acc_calc(lt); \ + fputc((unsigned short)pom&0xff,sample[0]); \ + fputc(((unsigned short)pom>>8)&0xff,sample[0]); \ + } + #else /*save to STEREO file */ + #define SAVE_ALL_CHANNELS \ + { signed int pom = lt; \ + fputc((unsigned short)pom&0xff,sample[0]); \ + fputc(((unsigned short)pom>>8)&0xff,sample[0]); \ + pom = rt; \ + fputc((unsigned short)pom&0xff,sample[0]); \ + fputc(((unsigned short)pom>>8)&0xff,sample[0]); \ + } + #endif +#endif + +#define OPL_TYPE_WAVESEL 0x01 /* waveform select */ +#define OPL_TYPE_ADPCM 0x02 /* DELTA-T ADPCM unit */ +#define OPL_TYPE_KEYBOARD 0x04 /* keyboard interface */ +#define OPL_TYPE_IO 0x08 /* I/O port */ + +/* ---------- Generic interface section ---------- */ +#define OPL_TYPE_YM3526 (0) +#define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL) +#define OPL_TYPE_Y8950 (OPL_TYPE_ADPCM|OPL_TYPE_KEYBOARD|OPL_TYPE_IO) + + +namespace { + +// TODO: make these static members + +#define RATE_STEPS (8) +extern const unsigned char eg_rate_shift[16+64+16]; +extern const unsigned char eg_rate_select[16+64+16]; + + +struct OPL_SLOT +{ + uint32_t ar; /* attack rate: AR<<2 */ + uint32_t dr; /* decay rate: DR<<2 */ + uint32_t rr; /* release rate:RR<<2 */ + uint8_t KSR; /* key scale rate */ + uint8_t ksl; /* keyscale level */ + uint8_t ksr; /* key scale rate: kcode>>KSR */ + uint8_t mul; /* multiple: mul_tab[ML] */ + + /* Phase Generator */ + uint32_t Cnt; /* frequency counter */ + uint32_t Incr; /* frequency counter step */ + uint8_t FB; /* feedback shift value */ + int32_t *connect1; /* slot1 output pointer */ + int32_t op1_out[2]; /* slot1 output for feedback */ + uint8_t CON; /* connection (algorithm) type */ + + /* Envelope Generator */ + uint8_t eg_type; /* percussive/non-percussive mode */ + uint8_t state; /* phase type */ + uint32_t TL; /* total level: TL << 2 */ + int32_t TLL; /* adjusted now TL */ + int32_t volume; /* envelope counter */ + uint32_t sl; /* sustain level: sl_tab[SL] */ + uint8_t eg_sh_ar; /* (attack state) */ + uint8_t eg_sel_ar; /* (attack state) */ + uint8_t eg_sh_dr; /* (decay state) */ + uint8_t eg_sel_dr; /* (decay state) */ + uint8_t eg_sh_rr; /* (release state) */ + uint8_t eg_sel_rr; /* (release state) */ + uint32_t key; /* 0 = KEY OFF, >0 = KEY ON */ + + /* LFO */ + uint32_t AMmask; /* LFO Amplitude Modulation enable mask */ + uint8_t vib; /* LFO Phase Modulation enable flag (active high)*/ + + /* waveform select */ + uint16_t wavetable; + + void KEYON(uint32_t key_set) + { + if( !key ) + { + /* restart Phase Generator */ + Cnt = 0; + /* phase -> Attack */ + state = EG_ATT; + } + key |= key_set; + } + + void KEYOFF(uint32_t key_clr) + { + if( key ) + { + key &= key_clr; + + if( !key ) + { + /* phase -> Release */ + if (state>EG_REL) + state = EG_REL; + } + } + } +}; + +struct OPL_CH +{ + OPL_SLOT SLOT[2]; + /* phase generator state */ + uint32_t block_fnum; /* block+fnum */ + uint32_t fc; /* Freq. Increment base */ + uint32_t ksl_base; /* KeyScaleLevel Base step */ + uint8_t kcode; /* key code (for key scaling) */ + + + /* update phase increment counter of operator (also update the EG rates if necessary) */ + void CALC_FCSLOT(OPL_SLOT &SLOT) + { + /* (frequency) phase increment counter */ + SLOT.Incr = fc * SLOT.mul; + int const ksr = kcode >> SLOT.KSR; + + if( SLOT.ksr != ksr ) + { + SLOT.ksr = ksr; + + /* calculate envelope generator rates */ + if ((SLOT.ar + SLOT.ksr) < 16+62) + { + SLOT.eg_sh_ar = eg_rate_shift [SLOT.ar + SLOT.ksr ]; + SLOT.eg_sel_ar = eg_rate_select[SLOT.ar + SLOT.ksr ]; + } + else + { + SLOT.eg_sh_ar = 0; + SLOT.eg_sel_ar = 13*RATE_STEPS; + } + SLOT.eg_sh_dr = eg_rate_shift [SLOT.dr + SLOT.ksr ]; + SLOT.eg_sel_dr = eg_rate_select[SLOT.dr + SLOT.ksr ]; + SLOT.eg_sh_rr = eg_rate_shift [SLOT.rr + SLOT.ksr ]; + SLOT.eg_sel_rr = eg_rate_select[SLOT.rr + SLOT.ksr ]; + } + } +}; + +/* OPL state */ +struct FM_OPL +{ + /* FM channel slots */ + OPL_CH P_CH[9]; /* OPL/OPL2 chips have 9 channels*/ + + uint32_t eg_cnt; /* global envelope generator counter */ + uint32_t eg_timer; /* global envelope generator counter works at frequency = chipclock/72 */ + uint32_t eg_timer_add; /* step of eg_timer */ + uint32_t eg_timer_overflow; /* envelope generator timer overflows every 1 sample (on real chip) */ + + uint8_t rhythm; /* Rhythm mode */ + + uint32_t fn_tab[1024]; /* fnumber->increment counter */ + + /* LFO */ + uint32_t LFO_AM; + int32_t LFO_PM; + + uint8_t lfo_am_depth; + uint8_t lfo_pm_depth_range; + uint32_t lfo_am_cnt; + uint32_t lfo_am_inc; + uint32_t lfo_pm_cnt; + uint32_t lfo_pm_inc; + + uint32_t noise_rng; /* 23 bit noise shift register */ + uint32_t noise_p; /* current noise 'phase' */ + uint32_t noise_f; /* current noise period */ + + uint8_t wavesel; /* waveform select enable flag */ + + uint32_t T[2]; /* timer counters */ + uint8_t st[2]; /* timer enable */ + +#if BUILD_Y8950 + /* Delta-T ADPCM unit (Y8950) */ + + YM_DELTAT *deltat; + + /* Keyboard and I/O ports interface */ + uint8_t portDirection; + uint8_t portLatch; + OPL_PORTHANDLER_R porthandler_r; + OPL_PORTHANDLER_W porthandler_w; + device_t * port_param; + OPL_PORTHANDLER_R keyboardhandler_r; + OPL_PORTHANDLER_W keyboardhandler_w; + device_t * keyboard_param; +#endif + + /* external event callback handlers */ + OPL_TIMERHANDLER timer_handler; /* TIMER handler */ + device_t *TimerParam; /* TIMER parameter */ + OPL_IRQHANDLER IRQHandler; /* IRQ handler */ + device_t *IRQParam; /* IRQ parameter */ + OPL_UPDATEHANDLER UpdateHandler;/* stream update handler */ + device_t *UpdateParam; /* stream update parameter */ + + uint8_t type; /* chip type */ + uint8_t address; /* address register */ + uint8_t status; /* status flag */ + uint8_t statusmask; /* status mask */ + uint8_t mode; /* Reg.08 : CSM,notesel,etc. */ + + uint32_t clock; /* master clock (Hz) */ + uint32_t rate; /* sampling rate (Hz) */ + double freqbase; /* frequency base */ + attotime TimerBase; /* Timer base time (==sampling time)*/ + device_t *device; + + signed int phase_modulation; /* phase modulation input (SLOT 2) */ + signed int output[1]; +#if BUILD_Y8950 + int32_t output_deltat[4]; /* for Y8950 DELTA-T, chip is mono, that 4 here is just for safety */ +#endif + + + /* status set and IRQ handling */ + void STATUS_SET(int flag) + { + /* set status flag */ + status |= flag; + if(!(status & 0x80)) + { + if(status & statusmask) + { /* IRQ on */ + status |= 0x80; + /* callback user interrupt handler (IRQ is OFF to ON) */ + if(IRQHandler) (IRQHandler)(IRQParam,1); + } + } + } + + /* status reset and IRQ handling */ + void STATUS_RESET(int flag) + { + /* reset status flag */ + status &=~flag; + if(status & 0x80) + { + if (!(status & statusmask) ) + { + status &= 0x7f; + /* callback user interrupt handler (IRQ is ON to OFF) */ + if(IRQHandler) (IRQHandler)(IRQParam,0); + } + } + } + + /* IRQ mask set */ + void STATUSMASK_SET(int flag) + { + statusmask = flag; + /* IRQ handling check */ + STATUS_SET(0); + STATUS_RESET(0); + } + + + /* advance LFO to next sample */ + void advance_lfo() + { + /* LFO */ + lfo_am_cnt += lfo_am_inc; + if (lfo_am_cnt >= (uint32_t(LFO_AM_TAB_ELEMENTS) << LFO_SH)) /* lfo_am_table is 210 elements long */ + lfo_am_cnt -= (uint32_t(LFO_AM_TAB_ELEMENTS) << LFO_SH); + + uint8_t const tmp = lfo_am_table[ lfo_am_cnt >> LFO_SH ]; + + LFO_AM = lfo_am_depth ? tmp : tmp >> 2; + + lfo_pm_cnt += lfo_pm_inc; + LFO_PM = (lfo_pm_cnt>>LFO_SH & 7) | lfo_pm_depth_range; + } + + /* advance to next sample */ + void advance() + { + eg_timer += eg_timer_add; + + while (eg_timer >= eg_timer_overflow) + { + eg_timer -= eg_timer_overflow; + + eg_cnt++; + + for (int i=0; i<9*2; i++) + { + OPL_CH &CH = P_CH[i/2]; + OPL_SLOT &op = CH.SLOT[i&1]; + + /* Envelope Generator */ + switch(op.state) + { + case EG_ATT: /* attack phase */ + if ( !(eg_cnt & ((1<>op.eg_sh_ar)&7)]) + ) >>3; + + if (op.volume <= MIN_ATT_INDEX) + { + op.volume = MIN_ATT_INDEX; + op.state = EG_DEC; + } + + } + break; + + case EG_DEC: /* decay phase */ + if ( !(eg_cnt & ((1<>op.eg_sh_dr)&7)]; + + if ( op.volume >= op.sl ) + op.state = EG_SUS; + + } + break; + + case EG_SUS: /* sustain phase */ + + /* this is important behaviour: + one can change percusive/non-percussive modes on the fly and + the chip will remain in sustain phase - verified on real YM3812 */ + + if(op.eg_type) /* non-percussive mode */ + { + /* do nothing */ + } + else /* percussive mode */ + { + /* during sustain phase chip adds Release Rate (in percussive mode) */ + if ( !(eg_cnt & ((1<>op.eg_sh_rr)&7)]; + + if ( op.volume >= MAX_ATT_INDEX ) + op.volume = MAX_ATT_INDEX; + } + /* else do nothing in sustain phase */ + } + break; + + case EG_REL: /* release phase */ + if ( !(eg_cnt & ((1<>op.eg_sh_rr)&7)]; + + if ( op.volume >= MAX_ATT_INDEX ) + { + op.volume = MAX_ATT_INDEX; + op.state = EG_OFF; + } + + } + break; + + default: + break; + } + } + } + + for (int i=0; i<9*2; i++) + { + OPL_CH &CH = P_CH[i/2]; + OPL_SLOT &op = CH.SLOT[i&1]; + + /* Phase Generator */ + if(op.vib) + { + unsigned int block_fnum = CH.block_fnum; + unsigned int const fnum_lfo = (block_fnum&0x0380) >> 7; + + signed int const lfo_fn_table_index_offset = lfo_pm_table[LFO_PM + 16*fnum_lfo ]; + + if (lfo_fn_table_index_offset) /* LFO phase modulation active */ + { + block_fnum += lfo_fn_table_index_offset; + uint8_t const block = (block_fnum&0x1c00) >> 10; + op.Cnt += (fn_tab[block_fnum&0x03ff] >> (7-block)) * op.mul; + } + else /* LFO phase modulation = zero */ + { + op.Cnt += op.Incr; + } + } + else /* LFO phase modulation disabled for this operator */ + { + op.Cnt += op.Incr; + } + } + + /* The Noise Generator of the YM3812 is 23-bit shift register. + * Period is equal to 2^23-2 samples. + * Register works at sampling frequency of the chip, so output + * can change on every sample. + * + * Output of the register and input to the bit 22 is: + * bit0 XOR bit14 XOR bit15 XOR bit22 + * + * Simply use bit 22 as the noise output. + */ + + noise_p += noise_f; + int i = noise_p >> FREQ_SH; /* number of events (shifts of the shift register) */ + noise_p &= FREQ_MASK; + while (i) + { + /* + uint32_t j; + j = ( (noise_rng) ^ (noise_rng>>14) ^ (noise_rng>>15) ^ (noise_rng>>22) ) & 1; + noise_rng = (j<<22) | (noise_rng>>1); + */ + + /* + Instead of doing all the logic operations above, we + use a trick here (and use bit 0 as the noise output). + The difference is only that the noise bit changes one + step ahead. This doesn't matter since we don't know + what is real state of the noise_rng after the reset. + */ + + if (noise_rng & 1) noise_rng ^= 0x800302; + noise_rng >>= 1; + + i--; + } + } + + /* calculate output */ + void CALC_CH(OPL_CH &CH) + { + OPL_SLOT *SLOT; + unsigned int env; + signed int out; + + phase_modulation = 0; + + /* SLOT 1 */ + SLOT = &CH.SLOT[SLOT1]; + env = volume_calc(*SLOT); + out = SLOT->op1_out[0] + SLOT->op1_out[1]; + SLOT->op1_out[0] = SLOT->op1_out[1]; + *SLOT->connect1 += SLOT->op1_out[0]; + SLOT->op1_out[1] = 0; + if( env < ENV_QUIET ) + { + if (!SLOT->FB) + out = 0; + SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB), SLOT->wavetable ); + } + + /* SLOT 2 */ + SLOT++; + env = volume_calc(*SLOT); + if( env < ENV_QUIET ) + output[0] += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable); + } + + /* + operators used in the rhythm sounds generation process: + + Envelope Generator: + + channel operator register number Bass High Snare Tom Top + / slot number TL ARDR SLRR Wave Drum Hat Drum Tom Cymbal + 6 / 0 12 50 70 90 f0 + + 6 / 1 15 53 73 93 f3 + + 7 / 0 13 51 71 91 f1 + + 7 / 1 16 54 74 94 f4 + + 8 / 0 14 52 72 92 f2 + + 8 / 1 17 55 75 95 f5 + + + Phase Generator: + + channel operator register number Bass High Snare Tom Top + / slot number MULTIPLE Drum Hat Drum Tom Cymbal + 6 / 0 12 30 + + 6 / 1 15 33 + + 7 / 0 13 31 + + + + 7 / 1 16 34 ----- n o t u s e d ----- + 8 / 0 14 32 + + 8 / 1 17 35 + + + + channel operator register number Bass High Snare Tom Top + number number BLK/FNUM2 FNUM Drum Hat Drum Tom Cymbal + 6 12,15 B6 A6 + + + 7 13,16 B7 A7 + + + + + 8 14,17 B8 A8 + + + + + */ + + /* calculate rhythm */ + + void CALC_RH() + { + unsigned int const noise = BIT(noise_rng, 0); + + OPL_SLOT *SLOT; + signed int out; + unsigned int env; + + + /* Bass Drum (verified on real YM3812): + - depends on the channel 6 'connect' register: + when connect = 0 it works the same as in normal (non-rhythm) mode (op1->op2->out) + when connect = 1 _only_ operator 2 is present on output (op2->out), operator 1 is ignored + - output sample always is multiplied by 2 + */ + + phase_modulation = 0; + /* SLOT 1 */ + SLOT = &P_CH[6].SLOT[SLOT1]; + env = volume_calc(*SLOT); + + out = SLOT->op1_out[0] + SLOT->op1_out[1]; + SLOT->op1_out[0] = SLOT->op1_out[1]; + + if (!SLOT->CON) + phase_modulation = SLOT->op1_out[0]; + /* else ignore output of operator 1 */ + + SLOT->op1_out[1] = 0; + if( env < ENV_QUIET ) + { + if (!SLOT->FB) + out = 0; + SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB), SLOT->wavetable ); + } + + /* SLOT 2 */ + SLOT++; + env = volume_calc(*SLOT); + if( env < ENV_QUIET ) + output[0] += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable) * 2; + + + /* Phase generation is based on: */ + /* HH (13) channel 7->slot 1 combined with channel 8->slot 2 (same combination as TOP CYMBAL but different output phases) */ + /* SD (16) channel 7->slot 1 */ + /* TOM (14) channel 8->slot 1 */ + /* TOP (17) channel 7->slot 1 combined with channel 8->slot 2 (same combination as HIGH HAT but different output phases) */ + + /* Envelope generation based on: */ + /* HH channel 7->slot1 */ + /* SD channel 7->slot2 */ + /* TOM channel 8->slot1 */ + /* TOP channel 8->slot2 */ + + + /* The following formulas can be well optimized. + I leave them in direct form for now (in case I've missed something). + */ + + /* High Hat (verified on real YM3812) */ + OPL_SLOT const &SLOT7_1 = P_CH[7].SLOT[SLOT1]; + OPL_SLOT const &SLOT8_2 = P_CH[8].SLOT[SLOT2]; + env = volume_calc(SLOT7_1); + if( env < ENV_QUIET ) + { + /* high hat phase generation: + phase = d0 or 234 (based on frequency only) + phase = 34 or 2d0 (based on noise) + */ + + /* base frequency derived from operator 1 in channel 7 */ + unsigned char const bit7 = BIT(SLOT7_1.Cnt >> FREQ_SH, 7); + unsigned char const bit3 = BIT(SLOT7_1.Cnt >> FREQ_SH, 3); + unsigned char const bit2 = BIT(SLOT7_1.Cnt >> FREQ_SH, 2); + + unsigned char const res1 = (bit2 ^ bit7) | bit3; + + /* when res1 = 0 phase = 0x000 | 0xd0; */ + /* when res1 = 1 phase = 0x200 | (0xd0>>2); */ + uint32_t phase = res1 ? (0x200|(0xd0>>2)) : 0xd0; + + /* enable gate based on frequency of operator 2 in channel 8 */ + unsigned char const bit5e= BIT(SLOT8_2.Cnt >> FREQ_SH, 5); + unsigned char const bit3e= BIT(SLOT8_2.Cnt >> FREQ_SH, 3); + + unsigned char const res2 = bit3e ^ bit5e; + + /* when res2 = 0 pass the phase from calculation above (res1); */ + /* when res2 = 1 phase = 0x200 | (0xd0>>2); */ + if (res2) + phase = (0x200|(0xd0>>2)); + + + /* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */ + /* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */ + if (phase&0x200) + { + if (noise) + phase = 0x200|0xd0; + } + else + /* when phase & 0x200 is clear and noise=1 then phase = 0xd0>>2 */ + /* when phase & 0x200 is clear and noise=0 then phase = 0xd0, ie no change */ + { + if (noise) + phase = 0xd0>>2; + } + + output[0] += op_calc(phase<> FREQ_SH, 8); + + /* when bit8 = 0 phase = 0x100; */ + /* when bit8 = 1 phase = 0x200; */ + uint32_t phase = bit8 ? 0x200 : 0x100; + + /* Noise bit XOR'es phase by 0x100 */ + /* when noisebit = 0 pass the phase from calculation above */ + /* when noisebit = 1 phase ^= 0x100; */ + /* in other words: phase ^= (noisebit<<8); */ + if (noise) + phase ^= 0x100; + + output[0] += op_calc(phase<> FREQ_SH, 7); + unsigned char const bit3 = BIT(SLOT7_1.Cnt >> FREQ_SH, 3); + unsigned char const bit2 = BIT(SLOT7_1.Cnt >> FREQ_SH, 2); + + unsigned char const res1 = (bit2 ^ bit7) | bit3; + + /* when res1 = 0 phase = 0x000 | 0x100; */ + /* when res1 = 1 phase = 0x200 | 0x100; */ + uint32_t phase = res1 ? 0x300 : 0x100; + + /* enable gate based on frequency of operator 2 in channel 8 */ + unsigned char const bit5e= BIT(SLOT8_2.Cnt >> FREQ_SH, 5); + unsigned char const bit3e= BIT(SLOT8_2.Cnt >> FREQ_SH, 3); + + unsigned char const res2 = bit3e ^ bit5e; + /* when res2 = 0 pass the phase from calculation above (res1); */ + /* when res2 = 1 phase = 0x200 | 0x100; */ + if (res2) + phase = 0x300; + + output[0] += op_calc(phase<> 6]; + SLOT.TL = (v&0x3f)<<(ENV_BITS-1-7); /* 7 bits TL (bit 6 = always 0) */ + + SLOT.TLL = SLOT.TL + (CH.ksl_base >> SLOT.ksl); + } + + /* set attack rate & decay rate */ + void set_ar_dr(int slot, int v) + { + OPL_CH &CH = P_CH[slot/2]; + OPL_SLOT &SLOT = CH.SLOT[slot&1]; + + SLOT.ar = (v>>4) ? 16 + ((v>>4) <<2) : 0; + + if ((SLOT.ar + SLOT.ksr) < 16+62) + { + SLOT.eg_sh_ar = eg_rate_shift [SLOT.ar + SLOT.ksr ]; + SLOT.eg_sel_ar = eg_rate_select[SLOT.ar + SLOT.ksr ]; + } + else + { + SLOT.eg_sh_ar = 0; + SLOT.eg_sel_ar = 13*RATE_STEPS; + } + + SLOT.dr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; + SLOT.eg_sh_dr = eg_rate_shift [SLOT.dr + SLOT.ksr ]; + SLOT.eg_sel_dr = eg_rate_select[SLOT.dr + SLOT.ksr ]; + } + + /* set sustain level & release rate */ + void set_sl_rr(int slot, int v) + { + OPL_CH &CH = P_CH[slot/2]; + OPL_SLOT &SLOT = CH.SLOT[slot&1]; + + SLOT.sl = sl_tab[ v>>4 ]; + + SLOT.rr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; + SLOT.eg_sh_rr = eg_rate_shift [SLOT.rr + SLOT.ksr ]; + SLOT.eg_sel_rr = eg_rate_select[SLOT.rr + SLOT.ksr ]; + } + + + void WriteReg(int r, int v); + void ResetChip(); + void postload(); + + + /* lock/unlock for common table */ + static int LockTable(device_t *device) + { + num_lock++; + if(num_lock>1) return 0; + + /* first time */ + + /* allocate total level table (128kb space) */ + if( !init_tables() ) + { + num_lock--; + return -1; + } + + return 0; + } + + static void UnLockTable() + { + if(num_lock) num_lock--; + if(num_lock) return; + + /* last time */ + CloseTable(); + } + +private: + uint32_t volume_calc(OPL_SLOT const &OP) const + { + return OP.TLL + uint32_t(OP.volume) + (LFO_AM & OP.AMmask); + } + + static inline signed int op_calc(uint32_t phase, unsigned int env, signed int pm, unsigned int wave_tab) + { + uint32_t const p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + (pm<<16))) >> FREQ_SH ) & SIN_MASK) ]; + + return (p >= TL_TAB_LEN) ? 0 : tl_tab[p]; + } + + static inline signed int op_calc1(uint32_t phase, unsigned int env, signed int pm, unsigned int wave_tab) + { + uint32_t const p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + pm )) >> FREQ_SH ) & SIN_MASK) ]; + + return (p >= TL_TAB_LEN) ? 0 : tl_tab[p]; + } + + + static int init_tables(); + + static void CloseTable() + { +#ifdef SAVE_SAMPLE + fclose(sample[0]); +#endif + } + + + static constexpr uint32_t SC(uint32_t db) { return uint32_t(db * (2.0 / ENV_STEP)); } + + + static constexpr double DV = 0.1875 / 2.0; + + + /* TL_TAB_LEN is calculated as: + * 12 - sinus amplitude bits (Y axis) + * 2 - sinus sign bit (Y axis) + * TL_RES_LEN - sinus resolution (X axis) + */ + static constexpr unsigned TL_TAB_LEN = 12 * 2 * TL_RES_LEN; + static constexpr unsigned ENV_QUIET = TL_TAB_LEN >> 4; + + static constexpr unsigned LFO_AM_TAB_ELEMENTS = 210; + + static const double ksl_tab[8*16]; + static const uint32_t ksl_shift[4]; + static const uint32_t sl_tab[16]; + static const unsigned char eg_inc[15 * RATE_STEPS]; + + static const uint8_t mul_tab[16]; + static signed int tl_tab[TL_TAB_LEN]; + static unsigned int sin_tab[SIN_LEN * 4]; + + static const uint8_t lfo_am_table[LFO_AM_TAB_ELEMENTS]; + static const int8_t lfo_pm_table[8 * 8 * 2]; + + static int num_lock; +}; + + + +/* mapping of register number (offset) to slot number used by the emulator */ +static const int slot_array[32]= +{ + 0, 2, 4, 1, 3, 5,-1,-1, + 6, 8,10, 7, 9,11,-1,-1, + 12,14,16,13,15,17,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1 +}; + +/* key scale level */ +/* table is 3dB/octave , DV converts this into 6dB/octave */ +/* 0.1875 is bit 0 weight of the envelope counter (volume) expressed in the 'decibel' scale */ +const double FM_OPL::ksl_tab[8*16]= +{ + /* OCT 0 */ + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + /* OCT 1 */ + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.750/DV, 1.125/DV, 1.500/DV, + 1.875/DV, 2.250/DV, 2.625/DV, 3.000/DV, + /* OCT 2 */ + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 1.125/DV, 1.875/DV, 2.625/DV, + 3.000/DV, 3.750/DV, 4.125/DV, 4.500/DV, + 4.875/DV, 5.250/DV, 5.625/DV, 6.000/DV, + /* OCT 3 */ + 0.000/DV, 0.000/DV, 0.000/DV, 1.875/DV, + 3.000/DV, 4.125/DV, 4.875/DV, 5.625/DV, + 6.000/DV, 6.750/DV, 7.125/DV, 7.500/DV, + 7.875/DV, 8.250/DV, 8.625/DV, 9.000/DV, + /* OCT 4 */ + 0.000/DV, 0.000/DV, 3.000/DV, 4.875/DV, + 6.000/DV, 7.125/DV, 7.875/DV, 8.625/DV, + 9.000/DV, 9.750/DV,10.125/DV,10.500/DV, + 10.875/DV,11.250/DV,11.625/DV,12.000/DV, + /* OCT 5 */ + 0.000/DV, 3.000/DV, 6.000/DV, 7.875/DV, + 9.000/DV,10.125/DV,10.875/DV,11.625/DV, + 12.000/DV,12.750/DV,13.125/DV,13.500/DV, + 13.875/DV,14.250/DV,14.625/DV,15.000/DV, + /* OCT 6 */ + 0.000/DV, 6.000/DV, 9.000/DV,10.875/DV, + 12.000/DV,13.125/DV,13.875/DV,14.625/DV, + 15.000/DV,15.750/DV,16.125/DV,16.500/DV, + 16.875/DV,17.250/DV,17.625/DV,18.000/DV, + /* OCT 7 */ + 0.000/DV, 9.000/DV,12.000/DV,13.875/DV, + 15.000/DV,16.125/DV,16.875/DV,17.625/DV, + 18.000/DV,18.750/DV,19.125/DV,19.500/DV, + 19.875/DV,20.250/DV,20.625/DV,21.000/DV +}; + +/* 0 / 3.0 / 1.5 / 6.0 dB/OCT */ +const uint32_t FM_OPL::ksl_shift[4] = { 31, 1, 2, 0 }; + + +/* sustain level table (3dB per step) */ +/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ +const uint32_t FM_OPL::sl_tab[16]={ + SC( 0),SC( 1),SC( 2),SC( 3),SC( 4),SC( 5),SC( 6),SC( 7), + SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31) +}; + + +const unsigned char FM_OPL::eg_inc[15*RATE_STEPS]={ +/*cycle:0 1 2 3 4 5 6 7*/ + +/* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..12 0 (increment by 0 or 1) */ +/* 1 */ 0,1, 0,1, 1,1, 0,1, /* rates 00..12 1 */ +/* 2 */ 0,1, 1,1, 0,1, 1,1, /* rates 00..12 2 */ +/* 3 */ 0,1, 1,1, 1,1, 1,1, /* rates 00..12 3 */ + +/* 4 */ 1,1, 1,1, 1,1, 1,1, /* rate 13 0 (increment by 1) */ +/* 5 */ 1,1, 1,2, 1,1, 1,2, /* rate 13 1 */ +/* 6 */ 1,2, 1,2, 1,2, 1,2, /* rate 13 2 */ +/* 7 */ 1,2, 2,2, 1,2, 2,2, /* rate 13 3 */ + +/* 8 */ 2,2, 2,2, 2,2, 2,2, /* rate 14 0 (increment by 2) */ +/* 9 */ 2,2, 2,4, 2,2, 2,4, /* rate 14 1 */ +/*10 */ 2,4, 2,4, 2,4, 2,4, /* rate 14 2 */ +/*11 */ 2,4, 4,4, 2,4, 4,4, /* rate 14 3 */ + +/*12 */ 4,4, 4,4, 4,4, 4,4, /* rates 15 0, 15 1, 15 2, 15 3 (increment by 4) */ +/*13 */ 8,8, 8,8, 8,8, 8,8, /* rates 15 2, 15 3 for attack */ +/*14 */ 0,0, 0,0, 0,0, 0,0, /* infinity rates for attack and decay(s) */ +}; + + +#define O(a) (a*RATE_STEPS) + +/*note that there is no O(13) in this table - it's directly in the code */ +const unsigned char eg_rate_select[16+64+16]={ /* Envelope Generator rates (16 + 64 rates + 16 RKS) */ +/* 16 infinite time rates */ +O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), +O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), + +/* rates 00-12 */ +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), + +/* rate 13 */ +O( 4),O( 5),O( 6),O( 7), + +/* rate 14 */ +O( 8),O( 9),O(10),O(11), + +/* rate 15 */ +O(12),O(12),O(12),O(12), + +/* 16 dummy rates (same as 15 3) */ +O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12), +O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12), + +}; +#undef O + +/*rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 */ +/*shift 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0 */ +/*mask 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0, 0 */ + +#define O(a) (a*1) +const unsigned char eg_rate_shift[16+64+16]={ /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */ +/* 16 infinite time rates */ +O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), +O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), + +/* rates 00-12 */ +O(12),O(12),O(12),O(12), +O(11),O(11),O(11),O(11), +O(10),O(10),O(10),O(10), +O( 9),O( 9),O( 9),O( 9), +O( 8),O( 8),O( 8),O( 8), +O( 7),O( 7),O( 7),O( 7), +O( 6),O( 6),O( 6),O( 6), +O( 5),O( 5),O( 5),O( 5), +O( 4),O( 4),O( 4),O( 4), +O( 3),O( 3),O( 3),O( 3), +O( 2),O( 2),O( 2),O( 2), +O( 1),O( 1),O( 1),O( 1), +O( 0),O( 0),O( 0),O( 0), + +/* rate 13 */ +O( 0),O( 0),O( 0),O( 0), + +/* rate 14 */ +O( 0),O( 0),O( 0),O( 0), + +/* rate 15 */ +O( 0),O( 0),O( 0),O( 0), + +/* 16 dummy rates (same as 15 3) */ +O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), +O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), + +}; +#undef O + + +/* multiple table */ +#define ML 2 +const uint8_t FM_OPL::mul_tab[16]= { +/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,10,12,12,15,15 */ + ML/2, 1*ML, 2*ML, 3*ML, 4*ML, 5*ML, 6*ML, 7*ML, + 8*ML, 9*ML,10*ML,10*ML,12*ML,12*ML,15*ML,15*ML +}; +#undef ML + +signed int FM_OPL::tl_tab[TL_TAB_LEN]; + +/* sin waveform table in 'decibel' scale */ +/* four waveforms on OPL2 type chips */ +unsigned int FM_OPL::sin_tab[SIN_LEN * 4]; + + +/* LFO Amplitude Modulation table (verified on real YM3812) + 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples + + Length: 210 elements. + + Each of the elements has to be repeated + exactly 64 times (on 64 consecutive samples). + The whole table takes: 64 * 210 = 13440 samples. + + When AM = 1 data is used directly + When AM = 0 data is divided by 4 before being used (losing precision is important) +*/ + +const uint8_t FM_OPL::lfo_am_table[LFO_AM_TAB_ELEMENTS] = { +0,0,0,0,0,0,0, +1,1,1,1, +2,2,2,2, +3,3,3,3, +4,4,4,4, +5,5,5,5, +6,6,6,6, +7,7,7,7, +8,8,8,8, +9,9,9,9, +10,10,10,10, +11,11,11,11, +12,12,12,12, +13,13,13,13, +14,14,14,14, +15,15,15,15, +16,16,16,16, +17,17,17,17, +18,18,18,18, +19,19,19,19, +20,20,20,20, +21,21,21,21, +22,22,22,22, +23,23,23,23, +24,24,24,24, +25,25,25,25, +26,26,26, +25,25,25,25, +24,24,24,24, +23,23,23,23, +22,22,22,22, +21,21,21,21, +20,20,20,20, +19,19,19,19, +18,18,18,18, +17,17,17,17, +16,16,16,16, +15,15,15,15, +14,14,14,14, +13,13,13,13, +12,12,12,12, +11,11,11,11, +10,10,10,10, +9,9,9,9, +8,8,8,8, +7,7,7,7, +6,6,6,6, +5,5,5,5, +4,4,4,4, +3,3,3,3, +2,2,2,2, +1,1,1,1 +}; + +/* LFO Phase Modulation table (verified on real YM3812) */ +const int8_t FM_OPL::lfo_pm_table[8*8*2] = { +/* FNUM2/FNUM = 00 0xxxxxxx (0x0000) */ +0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/ +0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 00 1xxxxxxx (0x0080) */ +0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/ +1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 01 0xxxxxxx (0x0100) */ +1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/ +2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 01 1xxxxxxx (0x0180) */ +1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/ +3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 10 0xxxxxxx (0x0200) */ +2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/ +4, 2, 0,-2,-4,-2, 0, 2, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 10 1xxxxxxx (0x0280) */ +2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/ +5, 2, 0,-2,-5,-2, 0, 2, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 11 0xxxxxxx (0x0300) */ +3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/ +6, 3, 0,-3,-6,-3, 0, 3, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 11 1xxxxxxx (0x0380) */ +3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/ +7, 3, 0,-3,-7,-3, 0, 3 /*LFO PM depth = 1*/ +}; + + +/* lock level of common table */ +int FM_OPL::num_lock = 0; + + + +static inline int limit( int val, int max, int min ) { + if ( val > max ) + val = max; + else if ( val < min ) + val = min; + + return val; +} + + +/* generic table initialize */ +int FM_OPL::init_tables() +{ + signed int i,x; + signed int n; + double o,m; + + + for (x=0; x>= 4; /* 12 bits here */ + if (n&1) /* round to nearest */ + n = (n>>1)+1; + else + n = n>>1; + /* 11 bits here (rounded) */ + n <<= 1; /* 12 bits here (as in real chip) */ + tl_tab[ x*2 + 0 ] = n; + tl_tab[ x*2 + 1 ] = -tl_tab[ x*2 + 0 ]; + + for (i=1; i<12; i++) + { + tl_tab[ x*2+0 + i*2*TL_RES_LEN ] = tl_tab[ x*2+0 ]>>i; + tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = -tl_tab[ x*2+0 + i*2*TL_RES_LEN ]; + } + #if 0 + logerror("tl %04i", x*2); + for (i=0; i<12; i++) + logerror(", [%02i] %5i", i*2, tl_tab[ x*2 /*+1*/ + i*2*TL_RES_LEN ] ); + logerror("\n"); + #endif + } + /*logerror("FMOPL.C: TL_TAB_LEN = %i elements (%i bytes)\n",TL_TAB_LEN, (int)sizeof(tl_tab));*/ + + + for (i=0; i0.0) + o = 8*log(1.0/m)/log(2.0); /* convert to 'decibels' */ + else + o = 8*log(-1.0/m)/log(2.0); /* convert to 'decibels' */ + + o = o / (ENV_STEP/4); + + n = (int)(2.0*o); + if (n&1) /* round to nearest */ + n = (n>>1)+1; + else + n = n>>1; + + sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 ); + + /*logerror("FMOPL.C: sin [%4i (hex=%03x)]= %4i (tl_tab value=%5i)\n", i, i, sin_tab[i], tl_tab[sin_tab[i]] );*/ + } + + for (i=0; i>1) ]; + + /* waveform 3: _ _ _ _ */ + /* / |_/ |_/ |_/ |_*/ + /* abs(output only first quarter of the sinus waveform) */ + + if (i & (1<<(SIN_BITS-2)) ) + sin_tab[3*SIN_LEN+i] = TL_TAB_LEN; + else + sin_tab[3*SIN_LEN+i] = sin_tab[i & (SIN_MASK>>2)]; + + /*logerror("FMOPL.C: sin1[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[1*SIN_LEN+i], tl_tab[sin_tab[1*SIN_LEN+i]] ); + logerror("FMOPL.C: sin2[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[2*SIN_LEN+i], tl_tab[sin_tab[2*SIN_LEN+i]] ); + logerror("FMOPL.C: sin3[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[3*SIN_LEN+i], tl_tab[sin_tab[3*SIN_LEN+i]] );*/ + } + /*logerror("FMOPL.C: ENV_QUIET= %08x (dec*8=%i)\n", ENV_QUIET, ENV_QUIET*8 );*/ + + +#ifdef SAVE_SAMPLE + sample[0]=fopen("sampsum.pcm","wb"); +#endif + + return 1; +} + + +void FM_OPL::initialize() +{ + int i; + + /* frequency base */ + freqbase = (rate) ? ((double)clock / 72.0) / rate : 0; +#if 0 + rate = (double)clock / 72.0; + freqbase = 1.0; +#endif + + /*logerror("freqbase=%f\n", freqbase);*/ + + /* Timer base time */ + TimerBase = attotime::from_hz(clock) * 72; + + /* make fnumber -> increment counter table */ + for( i=0 ; i < 1024 ; i++ ) + { + /* opn phase increment counter = 20bit */ + fn_tab[i] = (uint32_t)( (double)i * 64 * freqbase * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */ +#if 0 + logerror("FMOPL.C: fn_tab[%4i] = %08x (dec=%8i)\n", + i, fn_tab[i]>>6, fn_tab[i]>>6 ); +#endif + } + +#if 0 + for( i=0 ; i < 16 ; i++ ) + { + logerror("FMOPL.C: sl_tab[%i] = %08x\n", + i, sl_tab[i] ); + } + for( i=0 ; i < 8 ; i++ ) + { + int j; + logerror("FMOPL.C: ksl_tab[oct=%2i] =",i); + for (j=0; j<16; j++) + { + logerror("%08x ", static_cast(ksl_tab[i*16+j]) ); + } + logerror("\n"); + } +#endif + + + /* Amplitude modulation: 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */ + /* One entry from LFO_AM_TABLE lasts for 64 samples */ + lfo_am_inc = (1.0 / 64.0 ) * (1<>1)&1; + + /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */ + STATUS_RESET(v & (0x78-0x08)); + STATUSMASK_SET((~v) & 0x78); + + /* timer 2 */ + if(st[1] != st2) + { + attotime period = st2 ? (TimerBase * T[1]) : attotime::zero; + st[1] = st2; + if (timer_handler) (timer_handler)(TimerParam,1,period); + } + /* timer 1 */ + if(st[0] != st1) + { + attotime period = st1 ? (TimerBase * T[0]) : attotime::zero; + st[0] = st1; + if (timer_handler) (timer_handler)(TimerParam,0,period); + } + } + break; +#if BUILD_Y8950 + case 0x06: /* Key Board OUT */ + if(type&OPL_TYPE_KEYBOARD) + { + if(keyboardhandler_w) + keyboardhandler_w(keyboard_param,v); + else + device->logerror("Y8950: write unmapped KEYBOARD port\n"); + } + break; + case 0x07: /* DELTA-T control 1 : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */ + if(type&OPL_TYPE_ADPCM) + deltat->ADPCM_Write(r-0x07,v); + break; +#endif + case 0x08: /* MODE,DELTA-T control 2 : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */ + mode = v; +#if BUILD_Y8950 + if(type&OPL_TYPE_ADPCM) + deltat->ADPCM_Write(r-0x07,v&0x0f); /* mask 4 LSBs in register 08 for DELTA-T unit */ +#endif + break; + +#if BUILD_Y8950 + case 0x09: /* START ADD */ + case 0x0a: + case 0x0b: /* STOP ADD */ + case 0x0c: + case 0x0d: /* PRESCALE */ + case 0x0e: + case 0x0f: /* ADPCM data write */ + case 0x10: /* DELTA-N */ + case 0x11: /* DELTA-N */ + case 0x12: /* ADPCM volume */ + if(type&OPL_TYPE_ADPCM) + deltat->ADPCM_Write(r-0x07,v); + break; + + case 0x15: /* DAC data high 8 bits (F7,F6...F2) */ + case 0x16: /* DAC data low 2 bits (F1, F0 in bits 7,6) */ + case 0x17: /* DAC data shift (S2,S1,S0 in bits 2,1,0) */ + device->logerror("FMOPL.C: DAC data register written, but not implemented reg=%02x val=%02x\n",r,v); + break; + + case 0x18: /* I/O CTRL (Direction) */ + if(type&OPL_TYPE_IO) + portDirection = v&0x0f; + break; + case 0x19: /* I/O DATA */ + if(type&OPL_TYPE_IO) + { + portLatch = v; + if(porthandler_w) + porthandler_w(port_param,v&portDirection); + } + break; +#endif + default: + device->logerror("FMOPL.C: write to unknown register: %02x\n",r); + break; + } + break; + case 0x20: /* am ON, vib ON, ksr, eg_type, mul */ + slot = slot_array[r&0x1f]; + if(slot < 0) return; + set_mul(slot,v); + break; + case 0x40: + slot = slot_array[r&0x1f]; + if(slot < 0) return; + set_ksl_tl(slot,v); + break; + case 0x60: + slot = slot_array[r&0x1f]; + if(slot < 0) return; + set_ar_dr(slot,v); + break; + case 0x80: + slot = slot_array[r&0x1f]; + if(slot < 0) return; + set_sl_rr(slot,v); + break; + case 0xa0: + if (r == 0xbd) /* am depth, vibrato depth, r,bd,sd,tom,tc,hh */ + { + lfo_am_depth = v & 0x80; + lfo_pm_depth_range = (v&0x40) ? 8 : 0; + + rhythm = v&0x3f; + + if(rhythm&0x20) + { + /* BD key on/off */ + if(v&0x10) + { + P_CH[6].SLOT[SLOT1].KEYON(2); + P_CH[6].SLOT[SLOT2].KEYON(2); + } + else + { + P_CH[6].SLOT[SLOT1].KEYOFF(~2); + P_CH[6].SLOT[SLOT2].KEYOFF(~2); + } + /* HH key on/off */ + if(v&0x01) P_CH[7].SLOT[SLOT1].KEYON ( 2); + else P_CH[7].SLOT[SLOT1].KEYOFF(~2); + /* SD key on/off */ + if(v&0x08) P_CH[7].SLOT[SLOT2].KEYON ( 2); + else P_CH[7].SLOT[SLOT2].KEYOFF(~2); + /* TOM key on/off */ + if(v&0x04) P_CH[8].SLOT[SLOT1].KEYON ( 2); + else P_CH[8].SLOT[SLOT1].KEYOFF(~2); + /* TOP-CY key on/off */ + if(v&0x02) P_CH[8].SLOT[SLOT2].KEYON ( 2); + else P_CH[8].SLOT[SLOT2].KEYOFF(~2); + } + else + { + /* BD key off */ + P_CH[6].SLOT[SLOT1].KEYOFF(~2); + P_CH[6].SLOT[SLOT2].KEYOFF(~2); + /* HH key off */ + P_CH[7].SLOT[SLOT1].KEYOFF(~2); + /* SD key off */ + P_CH[7].SLOT[SLOT2].KEYOFF(~2); + /* TOM key off */ + P_CH[8].SLOT[SLOT1].KEYOFF(~2); + /* TOP-CY off */ + P_CH[8].SLOT[SLOT2].KEYOFF(~2); + } + return; + } + /* keyon,block,fnum */ + if( (r&0x0f) > 8) return; + CH = &P_CH[r&0x0f]; + if(!(r&0x10)) + { /* a0-a8 */ + block_fnum = (CH->block_fnum&0x1f00) | v; + } + else + { /* b0-b8 */ + block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff); + + if(v&0x20) + { + CH->SLOT[SLOT1].KEYON ( 1); + CH->SLOT[SLOT2].KEYON ( 1); + } + else + { + CH->SLOT[SLOT1].KEYOFF(~1); + CH->SLOT[SLOT2].KEYOFF(~1); + } + } + /* update */ + if(CH->block_fnum != block_fnum) + { + uint8_t block = block_fnum >> 10; + + CH->block_fnum = block_fnum; + + CH->ksl_base = static_cast(ksl_tab[block_fnum>>6]); + CH->fc = fn_tab[block_fnum&0x03ff] >> (7-block); + + /* BLK 2,1,0 bits -> bits 3,2,1 of kcode */ + CH->kcode = (CH->block_fnum&0x1c00)>>9; + + /* the info below is actually opposite to what is stated in the Manuals (verifed on real YM3812) */ + /* if notesel == 0 -> lsb of kcode is bit 10 (MSB) of fnum */ + /* if notesel == 1 -> lsb of kcode is bit 9 (MSB-1) of fnum */ + if (mode&0x40) + CH->kcode |= (CH->block_fnum&0x100)>>8; /* notesel == 1 */ + else + CH->kcode |= (CH->block_fnum&0x200)>>9; /* notesel == 0 */ + + /* refresh Total Level in both SLOTs of this channel */ + CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); + CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); + + /* refresh frequency counter in both SLOTs of this channel */ + CH->CALC_FCSLOT(CH->SLOT[SLOT1]); + CH->CALC_FCSLOT(CH->SLOT[SLOT2]); + } + break; + case 0xc0: + /* FB,C */ + if( (r&0x0f) > 8) return; + CH = &P_CH[r&0x0f]; + CH->SLOT[SLOT1].FB = (v>>1)&7 ? ((v>>1)&7) + 7 : 0; + CH->SLOT[SLOT1].CON = v&1; + CH->SLOT[SLOT1].connect1 = CH->SLOT[SLOT1].CON ? &output[0] : &phase_modulation; + break; + case 0xe0: /* waveform select */ + /* simply ignore write to the waveform select register if selecting not enabled in test register */ + if(wavesel) + { + slot = slot_array[r&0x1f]; + if(slot < 0) return; + CH = &P_CH[slot/2]; + + CH->SLOT[slot&1].wavetable = (v&0x03)*SIN_LEN; + } + break; + } +} + + +void FM_OPL::ResetChip() +{ + eg_timer = 0; + eg_cnt = 0; + + noise_rng = 1; /* noise shift register */ + mode = 0; /* normal mode */ + STATUS_RESET(0x7f); + + /* reset with register write */ + WriteReg(0x01,0); /* wavesel disable */ + WriteReg(0x02,0); /* Timer1 */ + WriteReg(0x03,0); /* Timer2 */ + WriteReg(0x04,0); /* IRQ mask clear */ + for(int i = 0xff ; i >= 0x20 ; i-- ) WriteReg(i,0); + + /* reset operator parameters */ + for(OPL_CH &CH : P_CH) + { + for(OPL_SLOT &SLOT : CH.SLOT) + { + /* wave table */ + SLOT.wavetable = 0; + SLOT.state = EG_OFF; + SLOT.volume = MAX_ATT_INDEX; + } + } +#if BUILD_Y8950 + if(type&OPL_TYPE_ADPCM) + { + YM_DELTAT *DELTAT = deltat; + + DELTAT->freqbase = freqbase; + DELTAT->output_pointer = &output_deltat[0]; + DELTAT->portshift = 5; + DELTAT->output_range = 1<<23; + DELTAT->ADPCM_Reset(0,YM_DELTAT::EMULATION_MODE_NORMAL,device); + } +#endif +} + + +void FM_OPL::postload() +{ + for(OPL_CH &CH : P_CH) + { + /* Look up key scale level */ + uint32_t const block_fnum = CH.block_fnum; + CH.ksl_base = static_cast(ksl_tab[block_fnum >> 6]); + CH.fc = fn_tab[block_fnum & 0x03ff] >> (7 - (block_fnum >> 10)); + + for(OPL_SLOT &SLOT : CH.SLOT) + { + /* Calculate key scale rate */ + SLOT.ksr = CH.kcode >> SLOT.KSR; + + /* Calculate attack, decay and release rates */ + if ((SLOT.ar + SLOT.ksr) < 16+62) + { + SLOT.eg_sh_ar = eg_rate_shift [SLOT.ar + SLOT.ksr ]; + SLOT.eg_sel_ar = eg_rate_select[SLOT.ar + SLOT.ksr ]; + } + else + { + SLOT.eg_sh_ar = 0; + SLOT.eg_sel_ar = 13*RATE_STEPS; + } + SLOT.eg_sh_dr = eg_rate_shift [SLOT.dr + SLOT.ksr ]; + SLOT.eg_sel_dr = eg_rate_select[SLOT.dr + SLOT.ksr ]; + SLOT.eg_sh_rr = eg_rate_shift [SLOT.rr + SLOT.ksr ]; + SLOT.eg_sel_rr = eg_rate_select[SLOT.rr + SLOT.ksr ]; + + /* Calculate phase increment */ + SLOT.Incr = CH.fc * SLOT.mul; + + /* Total level */ + SLOT.TLL = SLOT.TL + (CH.ksl_base >> SLOT.ksl); + + /* Connect output */ + SLOT.connect1 = SLOT.CON ? &output[0] : &phase_modulation; + } + } +#if BUILD_Y8950 + if ( (type & OPL_TYPE_ADPCM) && (deltat) ) + { + // We really should call the postlod function for the YM_DELTAT, but it's hard without registers + // (see the way the YM2610 does it) + //deltat->postload(REGS); + } +#endif +} + +} // anonymous namespace + + +static void OPLsave_state_channel(device_t *device, OPL_CH *CH) +{ + int slot, ch; + + for( ch=0 ; ch < 9 ; ch++, CH++ ) + { + /* channel */ + device->save_item(NAME(CH->block_fnum), ch); + device->save_item(NAME(CH->kcode), ch); + /* slots */ + for( slot=0 ; slot < 2 ; slot++ ) + { + OPL_SLOT *SLOT = &CH->SLOT[slot]; + + device->save_item(NAME(SLOT->ar), ch * 2 + slot); + device->save_item(NAME(SLOT->dr), ch * 2 + slot); + device->save_item(NAME(SLOT->rr), ch * 2 + slot); + device->save_item(NAME(SLOT->KSR), ch * 2 + slot); + device->save_item(NAME(SLOT->ksl), ch * 2 + slot); + device->save_item(NAME(SLOT->mul), ch * 2 + slot); + + device->save_item(NAME(SLOT->Cnt), ch * 2 + slot); + device->save_item(NAME(SLOT->FB), ch * 2 + slot); + device->save_item(NAME(SLOT->op1_out), ch * 2 + slot); + device->save_item(NAME(SLOT->CON), ch * 2 + slot); + + device->save_item(NAME(SLOT->eg_type), ch * 2 + slot); + device->save_item(NAME(SLOT->state), ch * 2 + slot); + device->save_item(NAME(SLOT->TL), ch * 2 + slot); + device->save_item(NAME(SLOT->volume), ch * 2 + slot); + device->save_item(NAME(SLOT->sl), ch * 2 + slot); + device->save_item(NAME(SLOT->key), ch * 2 + slot); + + device->save_item(NAME(SLOT->AMmask), ch * 2 + slot); + device->save_item(NAME(SLOT->vib), ch * 2 + slot); + + device->save_item(NAME(SLOT->wavetable), ch * 2 + slot); + } + } +} + + +/* Register savestate for a virtual YM3812/YM3526Y8950 */ + +static void OPL_save_state(FM_OPL *OPL, device_t *device) +{ + OPLsave_state_channel(device, OPL->P_CH); + + device->save_item(NAME(OPL->eg_cnt)); + device->save_item(NAME(OPL->eg_timer)); + + device->save_item(NAME(OPL->rhythm)); + + device->save_item(NAME(OPL->lfo_am_depth)); + device->save_item(NAME(OPL->lfo_pm_depth_range)); + device->save_item(NAME(OPL->lfo_am_cnt)); + device->save_item(NAME(OPL->lfo_pm_cnt)); + + device->save_item(NAME(OPL->noise_rng)); + device->save_item(NAME(OPL->noise_p)); + + if( OPL->type & OPL_TYPE_WAVESEL ) + { + device->save_item(NAME(OPL->wavesel)); + } + + device->save_item(NAME(OPL->T)); + device->save_item(NAME(OPL->st)); + +#if BUILD_Y8950 + if ( (OPL->type & OPL_TYPE_ADPCM) && (OPL->deltat) ) + { + OPL->deltat->savestate(device); + } + + if ( OPL->type & OPL_TYPE_IO ) + { + device->save_item(NAME(OPL->portDirection)); + device->save_item(NAME(OPL->portLatch)); + } +#endif + + device->save_item(NAME(OPL->address)); + device->save_item(NAME(OPL->status)); + device->save_item(NAME(OPL->statusmask)); + device->save_item(NAME(OPL->mode)); + + device->machine().save().register_postload(save_prepost_delegate(FUNC(FM_OPL::postload), OPL)); +} + +static void OPL_clock_changed(FM_OPL *OPL, uint32_t clock, uint32_t rate) +{ + OPL->clock = clock; + OPL->rate = rate; + + /* init global tables */ + OPL->initialize(); +} + + +/* Create one of virtual YM3812/YM3526/Y8950 */ +/* 'clock' is chip clock in Hz */ +/* 'rate' is sampling rate */ +static FM_OPL *OPLCreate(device_t *device, uint32_t clock, uint32_t rate, int type) +{ + char *ptr; + FM_OPL *OPL; + int state_size; + + if (FM_OPL::LockTable(device) == -1) return nullptr; + + /* calculate OPL state size */ + state_size = sizeof(FM_OPL); + +#if BUILD_Y8950 + if (type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT); +#endif + + /* allocate memory block */ + ptr = (char *)auto_alloc_array_clear(device->machine(), uint8_t, state_size); + + OPL = (FM_OPL *)ptr; + + ptr += sizeof(FM_OPL); + +#if BUILD_Y8950 + if (type&OPL_TYPE_ADPCM) + { + OPL->deltat = (YM_DELTAT *)ptr; + } + ptr += sizeof(YM_DELTAT); +#endif + + OPL->device = device; + OPL->type = type; + OPL_clock_changed(OPL, clock, rate); + + return OPL; +} + +/* Destroy one of virtual YM3812 */ +static void OPLDestroy(FM_OPL *OPL) +{ + FM_OPL::UnLockTable(); + auto_free(OPL->device->machine(), OPL); +} + +/* Optional handlers */ + +static void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER timer_handler,device_t *device) +{ + OPL->timer_handler = timer_handler; + OPL->TimerParam = device; +} +static void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,device_t *device) +{ + OPL->IRQHandler = IRQHandler; + OPL->IRQParam = device; +} +static void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,device_t *device) +{ + OPL->UpdateHandler = UpdateHandler; + OPL->UpdateParam = device; +} + +static int OPLWrite(FM_OPL *OPL,int a,int v) +{ + if( !(a&1) ) + { /* address port */ + OPL->address = v & 0xff; + } + else + { /* data port */ + if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); + OPL->WriteReg(OPL->address,v); + } + return OPL->status>>7; +} + +static unsigned char OPLRead(FM_OPL *OPL,int a) +{ + if( !(a&1) ) + { + /* status port */ + + #if BUILD_Y8950 + + if(OPL->type&OPL_TYPE_ADPCM) /* Y8950 */ + { + return (OPL->status & (OPL->statusmask|0x80)) | (OPL->deltat->PCM_BSY&1); + } + + #endif + + /* OPL and OPL2 */ + return OPL->status & (OPL->statusmask|0x80); + } + +#if BUILD_Y8950 + /* data port */ + switch(OPL->address) + { + case 0x05: /* KeyBoard IN */ + if(OPL->type&OPL_TYPE_KEYBOARD) + { + if(OPL->keyboardhandler_r) + return OPL->keyboardhandler_r(OPL->keyboard_param); + else + OPL->device->logerror("Y8950: read unmapped KEYBOARD port\n"); + } + return 0; + + case 0x0f: /* ADPCM-DATA */ + if(OPL->type&OPL_TYPE_ADPCM) + { + uint8_t val; + + val = OPL->deltat->ADPCM_Read(); + /*logerror("Y8950: read ADPCM value read=%02x\n",val);*/ + return val; + } + return 0; + + case 0x19: /* I/O DATA */ + if(OPL->type&OPL_TYPE_IO) + { + if(OPL->porthandler_r) + return OPL->porthandler_r(OPL->port_param); + else + OPL->device->logerror("Y8950:read unmapped I/O port\n"); + } + return 0; + case 0x1a: /* PCM-DATA */ + if(OPL->type&OPL_TYPE_ADPCM) + { + OPL->device->logerror("Y8950 A/D conversion is accessed but not implemented !\n"); + return 0x80; /* 2's complement PCM data - result from A/D conversion */ + } + return 0; + } +#endif + + return 0xff; +} + +/* CSM Key Controll */ +static inline void CSMKeyControll(OPL_CH *CH) +{ + CH->SLOT[SLOT1].KEYON(4); + CH->SLOT[SLOT2].KEYON(4); + + /* The key off should happen exactly one sample later - not implemented correctly yet */ + + CH->SLOT[SLOT1].KEYOFF(~4); + CH->SLOT[SLOT2].KEYOFF(~4); +} + + +static int OPLTimerOver(FM_OPL *OPL,int c) +{ + if( c ) + { /* Timer B */ + OPL->STATUS_SET(0x20); + } + else + { /* Timer A */ + OPL->STATUS_SET(0x40); + /* CSM mode key,TL controll */ + if( OPL->mode & 0x80 ) + { /* CSM mode total level latch and auto key on */ + int ch; + if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); + for(ch=0; ch<9; ch++) + CSMKeyControll( &OPL->P_CH[ch] ); + } + } + /* reload timer */ + if (OPL->timer_handler) (OPL->timer_handler)(OPL->TimerParam,c,OPL->TimerBase * OPL->T[c]); + return OPL->status>>7; +} + + +#define MAX_OPL_CHIPS 2 + + +#if (BUILD_YM3812) + +void ym3812_clock_changed(void *chip, uint32_t clock, uint32_t rate) +{ + OPL_clock_changed((FM_OPL *)chip, clock, rate); +} + +void * ym3812_init(device_t *device, uint32_t clock, uint32_t rate) +{ + /* emulator create */ + FM_OPL *YM3812 = OPLCreate(device,clock,rate,OPL_TYPE_YM3812); + if (YM3812) + { + OPL_save_state(YM3812, device); + ym3812_reset_chip(YM3812); + } + return YM3812; +} + +void ym3812_shutdown(void *chip) +{ + FM_OPL *YM3812 = (FM_OPL *)chip; + + /* emulator shutdown */ + OPLDestroy(YM3812); +} +void ym3812_reset_chip(void *chip) +{ + FM_OPL *YM3812 = (FM_OPL *)chip; + YM3812->ResetChip(); +} + +int ym3812_write(void *chip, int a, int v) +{ + FM_OPL *YM3812 = (FM_OPL *)chip; + return OPLWrite(YM3812, a, v); +} + +unsigned char ym3812_read(void *chip, int a) +{ + FM_OPL *YM3812 = (FM_OPL *)chip; + /* YM3812 always returns bit2 and bit1 in HIGH state */ + return OPLRead(YM3812, a) | 0x06 ; +} +int ym3812_timer_over(void *chip, int c) +{ + FM_OPL *YM3812 = (FM_OPL *)chip; + return OPLTimerOver(YM3812, c); +} + +void ym3812_set_timer_handler(void *chip, OPL_TIMERHANDLER timer_handler, device_t *device) +{ + FM_OPL *YM3812 = (FM_OPL *)chip; + OPLSetTimerHandler(YM3812, timer_handler, device); +} +void ym3812_set_irq_handler(void *chip,OPL_IRQHANDLER IRQHandler,device_t *device) +{ + FM_OPL *YM3812 = (FM_OPL *)chip; + OPLSetIRQHandler(YM3812, IRQHandler, device); +} +void ym3812_set_update_handler(void *chip,OPL_UPDATEHANDLER UpdateHandler,device_t *device) +{ + FM_OPL *YM3812 = (FM_OPL *)chip; + OPLSetUpdateHandler(YM3812, UpdateHandler, device); +} + + +/* +** Generate samples for one of the YM3812's +** +** 'which' is the virtual YM3812 number +** '*buffer' is the output buffer pointer +** 'length' is the number of samples that should be generated +*/ +void ym3812_update_one(void *chip, OPLSAMPLE *buffer, int length) +{ + FM_OPL *OPL = (FM_OPL *)chip; + uint8_t rhythm = OPL->rhythm&0x20; + OPLSAMPLE *buf = buffer; + int i; + + for( i=0; i < length ; i++ ) + { + int lt; + + OPL->output[0] = 0; + + OPL->advance_lfo(); + + /* FM part */ + OPL->CALC_CH(OPL->P_CH[0]); + OPL->CALC_CH(OPL->P_CH[1]); + OPL->CALC_CH(OPL->P_CH[2]); + OPL->CALC_CH(OPL->P_CH[3]); + OPL->CALC_CH(OPL->P_CH[4]); + OPL->CALC_CH(OPL->P_CH[5]); + + if(!rhythm) + { + OPL->CALC_CH(OPL->P_CH[6]); + OPL->CALC_CH(OPL->P_CH[7]); + OPL->CALC_CH(OPL->P_CH[8]); + } + else /* Rhythm part */ + { + OPL->CALC_RH(); + } + + lt = OPL->output[0]; + + lt >>= FINAL_SH; + + /* limit check */ + lt = limit( lt , MAXOUT, MINOUT ); + + #ifdef SAVE_SAMPLE + if (which==0) + { + SAVE_ALL_CHANNELS + } + #endif + + /* store to sound buffer */ + buf[i] = lt; + + OPL->advance(); + } + +} +#endif /* BUILD_YM3812 */ + + + +#if (BUILD_YM3526) + +void ym3526_clock_changed(void *chip, uint32_t clock, uint32_t rate) +{ + OPL_clock_changed((FM_OPL *)chip, clock, rate); +} + +void *ym3526_init(device_t *device, uint32_t clock, uint32_t rate) +{ + /* emulator create */ + FM_OPL *YM3526 = OPLCreate(device,clock,rate,OPL_TYPE_YM3526); + if (YM3526) + { + OPL_save_state(YM3526, device); + ym3526_reset_chip(YM3526); + } + return YM3526; +} + +void ym3526_shutdown(void *chip) +{ + FM_OPL *YM3526 = (FM_OPL *)chip; + /* emulator shutdown */ + OPLDestroy(YM3526); +} +void ym3526_reset_chip(void *chip) +{ + FM_OPL *YM3526 = (FM_OPL *)chip; + YM3526->ResetChip(); +} + +int ym3526_write(void *chip, int a, int v) +{ + FM_OPL *YM3526 = (FM_OPL *)chip; + return OPLWrite(YM3526, a, v); +} + +unsigned char ym3526_read(void *chip, int a) +{ + FM_OPL *YM3526 = (FM_OPL *)chip; + /* YM3526 always returns bit2 and bit1 in HIGH state */ + return OPLRead(YM3526, a) | 0x06 ; +} +int ym3526_timer_over(void *chip, int c) +{ + FM_OPL *YM3526 = (FM_OPL *)chip; + return OPLTimerOver(YM3526, c); +} + +void ym3526_set_timer_handler(void *chip, OPL_TIMERHANDLER timer_handler, device_t *device) +{ + FM_OPL *YM3526 = (FM_OPL *)chip; + OPLSetTimerHandler(YM3526, timer_handler, device); +} +void ym3526_set_irq_handler(void *chip,OPL_IRQHANDLER IRQHandler,device_t *device) +{ + FM_OPL *YM3526 = (FM_OPL *)chip; + OPLSetIRQHandler(YM3526, IRQHandler, device); +} +void ym3526_set_update_handler(void *chip,OPL_UPDATEHANDLER UpdateHandler,device_t *device) +{ + FM_OPL *YM3526 = (FM_OPL *)chip; + OPLSetUpdateHandler(YM3526, UpdateHandler, device); +} + + +/* +** Generate samples for one of the YM3526's +** +** 'which' is the virtual YM3526 number +** '*buffer' is the output buffer pointer +** 'length' is the number of samples that should be generated +*/ +void ym3526_update_one(void *chip, OPLSAMPLE *buffer, int length) +{ + FM_OPL *OPL = (FM_OPL *)chip; + uint8_t rhythm = OPL->rhythm&0x20; + OPLSAMPLE *buf = buffer; + int i; + + for( i=0; i < length ; i++ ) + { + int lt; + + OPL->output[0] = 0; + + OPL->advance_lfo(); + + /* FM part */ + OPL->CALC_CH(OPL->P_CH[0]); + OPL->CALC_CH(OPL->P_CH[1]); + OPL->CALC_CH(OPL->P_CH[2]); + OPL->CALC_CH(OPL->P_CH[3]); + OPL->CALC_CH(OPL->P_CH[4]); + OPL->CALC_CH(OPL->P_CH[5]); + + if(!rhythm) + { + OPL->CALC_CH(OPL->P_CH[6]); + OPL->CALC_CH(OPL->P_CH[7]); + OPL->CALC_CH(OPL->P_CH[8]); + } + else /* Rhythm part */ + { + OPL->CALC_RH(); + } + + lt = OPL->output[0]; + + lt >>= FINAL_SH; + + /* limit check */ + lt = limit( lt , MAXOUT, MINOUT ); + + #ifdef SAVE_SAMPLE + if (which==0) + { + SAVE_ALL_CHANNELS + } + #endif + + /* store to sound buffer */ + buf[i] = lt; + + OPL->advance(); + } + +} +#endif /* BUILD_YM3526 */ + + + + +#if BUILD_Y8950 + +static void Y8950_deltat_status_set(void *chip, uint8_t changebits) +{ + FM_OPL *Y8950 = (FM_OPL *)chip; + Y8950->STATUS_SET(changebits); +} +static void Y8950_deltat_status_reset(void *chip, uint8_t changebits) +{ + FM_OPL *Y8950 = (FM_OPL *)chip; + Y8950->STATUS_RESET(changebits); +} + +void *y8950_init(device_t *device, uint32_t clock, uint32_t rate) +{ + /* emulator create */ + FM_OPL *Y8950 = OPLCreate(device,clock,rate,OPL_TYPE_Y8950); + if (Y8950) + { + Y8950->deltat->status_set_handler = Y8950_deltat_status_set; + Y8950->deltat->status_reset_handler = Y8950_deltat_status_reset; + Y8950->deltat->status_change_which_chip = Y8950; + Y8950->deltat->status_change_EOS_bit = 0x10; /* status flag: set bit4 on End Of Sample */ + Y8950->deltat->status_change_BRDY_bit = 0x08; /* status flag: set bit3 on BRDY (End Of: ADPCM analysis/synthesis, memory reading/writing) */ + + /*Y8950->deltat->write_time = 10.0 / clock;*/ /* a single byte write takes 10 cycles of main clock */ + /*Y8950->deltat->read_time = 8.0 / clock;*/ /* a single byte read takes 8 cycles of main clock */ + /* reset */ + OPL_save_state(Y8950, device); + y8950_reset_chip(Y8950); + } + + return Y8950; +} + +void y8950_shutdown(void *chip) +{ + FM_OPL *Y8950 = (FM_OPL *)chip; + /* emulator shutdown */ + OPLDestroy(Y8950); +} +void y8950_reset_chip(void *chip) +{ + FM_OPL *Y8950 = (FM_OPL *)chip; + Y8950->ResetChip(); +} + +int y8950_write(void *chip, int a, int v) +{ + FM_OPL *Y8950 = (FM_OPL *)chip; + return OPLWrite(Y8950, a, v); +} + +unsigned char y8950_read(void *chip, int a) +{ + FM_OPL *Y8950 = (FM_OPL *)chip; + return OPLRead(Y8950, a); +} +int y8950_timer_over(void *chip, int c) +{ + FM_OPL *Y8950 = (FM_OPL *)chip; + return OPLTimerOver(Y8950, c); +} + +void y8950_set_timer_handler(void *chip, OPL_TIMERHANDLER timer_handler, device_t *device) +{ + FM_OPL *Y8950 = (FM_OPL *)chip; + OPLSetTimerHandler(Y8950, timer_handler, device); +} +void y8950_set_irq_handler(void *chip,OPL_IRQHANDLER IRQHandler,device_t *device) +{ + FM_OPL *Y8950 = (FM_OPL *)chip; + OPLSetIRQHandler(Y8950, IRQHandler, device); +} +void y8950_set_update_handler(void *chip,OPL_UPDATEHANDLER UpdateHandler,device_t *device) +{ + FM_OPL *Y8950 = (FM_OPL *)chip; + OPLSetUpdateHandler(Y8950, UpdateHandler, device); +} + +void y8950_set_delta_t_memory(void *chip, void * deltat_mem_ptr, int deltat_mem_size ) +{ + FM_OPL *OPL = (FM_OPL *)chip; + OPL->deltat->memory = (uint8_t *)(deltat_mem_ptr); + OPL->deltat->memory_size = deltat_mem_size; +} + +/* +** Generate samples for one of the Y8950's +** +** 'which' is the virtual Y8950 number +** '*buffer' is the output buffer pointer +** 'length' is the number of samples that should be generated +*/ +void y8950_update_one(void *chip, OPLSAMPLE *buffer, int length) +{ + int i; + FM_OPL *OPL = (FM_OPL *)chip; + uint8_t rhythm = OPL->rhythm&0x20; + YM_DELTAT *DELTAT = OPL->deltat; + OPLSAMPLE *buf = buffer; + + for( i=0; i < length ; i++ ) + { + int lt; + + OPL->output[0] = 0; + OPL->output_deltat[0] = 0; + + OPL->advance_lfo(); + + /* deltaT ADPCM */ + if( DELTAT->portstate&0x80 ) + DELTAT->ADPCM_CALC(); + + /* FM part */ + OPL->CALC_CH(OPL->P_CH[0]); + OPL->CALC_CH(OPL->P_CH[1]); + OPL->CALC_CH(OPL->P_CH[2]); + OPL->CALC_CH(OPL->P_CH[3]); + OPL->CALC_CH(OPL->P_CH[4]); + OPL->CALC_CH(OPL->P_CH[5]); + + if(!rhythm) + { + OPL->CALC_CH(OPL->P_CH[6]); + OPL->CALC_CH(OPL->P_CH[7]); + OPL->CALC_CH(OPL->P_CH[8]); + } + else /* Rhythm part */ + { + OPL->CALC_RH(); + } + + lt = OPL->output[0] + (OPL->output_deltat[0]>>11); + + lt >>= FINAL_SH; + + /* limit check */ + lt = limit( lt , MAXOUT, MINOUT ); + + #ifdef SAVE_SAMPLE + if (which==0) + { + SAVE_ALL_CHANNELS + } + #endif + + /* store to sound buffer */ + buf[i] = lt; + + OPL->advance(); + } + +} + +void y8950_set_port_handler(void *chip,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,device_t *device) +{ + FM_OPL *OPL = (FM_OPL *)chip; + OPL->porthandler_w = PortHandler_w; + OPL->porthandler_r = PortHandler_r; + OPL->port_param = device; +} + +void y8950_set_keyboard_handler(void *chip,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,device_t *device) +{ + FM_OPL *OPL = (FM_OPL *)chip; + OPL->keyboardhandler_w = KeyboardHandler_w; + OPL->keyboardhandler_r = KeyboardHandler_r; + OPL->keyboard_param = device; +} + +#endif diff --git a/src/hardware/mame/fmopl.h b/src/hardware/mame/fmopl.h new file mode 100644 index 00000000..c5366d7b --- /dev/null +++ b/src/hardware/mame/fmopl.h @@ -0,0 +1,109 @@ +// license:GPL-2.0+ +// copyright-holders:Jarek Burczynski,Tatsuyuki Satoh +#ifndef MAME_SOUND_FMOPL_H +#define MAME_SOUND_FMOPL_H + +#pragma once + +#include + + +/* --- select emulation chips --- */ +#define BUILD_YM3812 (1) +#define BUILD_YM3526 (1) +#define BUILD_Y8950 (1) + +/* select output bits size of output : 8 or 16 */ +#define OPL_SAMPLE_BITS 16 + +typedef stream_sample_t OPLSAMPLE; +/* +#if (OPL_SAMPLE_BITS==16) +typedef int16_t OPLSAMPLE; +#endif +#if (OPL_SAMPLE_BITS==8) +typedef int8_t OPLSAMPLE; +#endif +*/ + +typedef void (*OPL_TIMERHANDLER)(device_t *device,int timer,const attotime &period); +typedef void (*OPL_IRQHANDLER)(device_t *device,int irq); +typedef void (*OPL_UPDATEHANDLER)(device_t *device,int min_interval_us); +typedef void (*OPL_PORTHANDLER_W)(device_t *device,unsigned char data); +typedef unsigned char (*OPL_PORTHANDLER_R)(device_t *device); + + +#if BUILD_YM3812 + +void *ym3812_init(device_t *device, uint32_t clock, uint32_t rate); +void ym3812_clock_changed(void *chip, uint32_t clock, uint32_t rate); +void ym3812_shutdown(void *chip); +void ym3812_reset_chip(void *chip); +int ym3812_write(void *chip, int a, int v); +unsigned char ym3812_read(void *chip, int a); +int ym3812_timer_over(void *chip, int c); +void ym3812_update_one(void *chip, OPLSAMPLE *buffer, int length); + +void ym3812_set_timer_handler(void *chip, OPL_TIMERHANDLER TimerHandler, device_t *device); +void ym3812_set_irq_handler(void *chip, OPL_IRQHANDLER IRQHandler, device_t *device); +void ym3812_set_update_handler(void *chip, OPL_UPDATEHANDLER UpdateHandler, device_t *device); + +#endif /* BUILD_YM3812 */ + + +#if BUILD_YM3526 + +/* +** Initialize YM3526 emulator(s). +** +** 'num' is the number of virtual YM3526's to allocate +** 'clock' is the chip clock in Hz +** 'rate' is sampling rate +*/ +void *ym3526_init(device_t *device, uint32_t clock, uint32_t rate); +void ym3526_clock_changed(void *chip, uint32_t clock, uint32_t rate); +/* shutdown the YM3526 emulators*/ +void ym3526_shutdown(void *chip); +void ym3526_reset_chip(void *chip); +int ym3526_write(void *chip, int a, int v); +unsigned char ym3526_read(void *chip, int a); +int ym3526_timer_over(void *chip, int c); +/* +** Generate samples for one of the YM3526's +** +** 'which' is the virtual YM3526 number +** '*buffer' is the output buffer pointer +** 'length' is the number of samples that should be generated +*/ +void ym3526_update_one(void *chip, OPLSAMPLE *buffer, int length); + +void ym3526_set_timer_handler(void *chip, OPL_TIMERHANDLER TimerHandler, device_t *device); +void ym3526_set_irq_handler(void *chip, OPL_IRQHANDLER IRQHandler, device_t *device); +void ym3526_set_update_handler(void *chip, OPL_UPDATEHANDLER UpdateHandler, device_t *device); + +#endif /* BUILD_YM3526 */ + + +#if BUILD_Y8950 + +/* Y8950 port handlers */ +void y8950_set_port_handler(void *chip, OPL_PORTHANDLER_W PortHandler_w, OPL_PORTHANDLER_R PortHandler_r, device_t *device); +void y8950_set_keyboard_handler(void *chip, OPL_PORTHANDLER_W KeyboardHandler_w, OPL_PORTHANDLER_R KeyboardHandler_r, device_t *device); +void y8950_set_delta_t_memory(void *chip, void * deltat_mem_ptr, int deltat_mem_size ); + +void * y8950_init(device_t *device, uint32_t clock, uint32_t rate); +void y8950_shutdown(void *chip); +void y8950_reset_chip(void *chip); +int y8950_write(void *chip, int a, int v); +unsigned char y8950_read (void *chip, int a); +int y8950_timer_over(void *chip, int c); +void y8950_update_one(void *chip, OPLSAMPLE *buffer, int length); + +void y8950_set_timer_handler(void *chip, OPL_TIMERHANDLER TimerHandler, device_t *device); +void y8950_set_irq_handler(void *chip, OPL_IRQHANDLER IRQHandler, device_t *device); +void y8950_set_update_handler(void *chip, OPL_UPDATEHANDLER UpdateHandler, device_t *device); + +#endif /* BUILD_Y8950 */ + + +#endif // MAME_SOUND_FMOPL_H diff --git a/src/hardware/mame/saa1099.cpp b/src/hardware/mame/saa1099.cpp new file mode 100644 index 00000000..3c9b334b --- /dev/null +++ b/src/hardware/mame/saa1099.cpp @@ -0,0 +1,458 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller, Manuel Abadia +/*************************************************************************** + + Philips SAA1099 Sound driver + + By Juergen Buchmueller and Manuel Abadia + + SAA1099 register layout: + ======================== + + offs | 7654 3210 | description + -----+-----------+--------------------------- + 0x00 | ---- xxxx | Amplitude channel 0 (left) + 0x00 | xxxx ---- | Amplitude channel 0 (right) + 0x01 | ---- xxxx | Amplitude channel 1 (left) + 0x01 | xxxx ---- | Amplitude channel 1 (right) + 0x02 | ---- xxxx | Amplitude channel 2 (left) + 0x02 | xxxx ---- | Amplitude channel 2 (right) + 0x03 | ---- xxxx | Amplitude channel 3 (left) + 0x03 | xxxx ---- | Amplitude channel 3 (right) + 0x04 | ---- xxxx | Amplitude channel 4 (left) + 0x04 | xxxx ---- | Amplitude channel 4 (right) + 0x05 | ---- xxxx | Amplitude channel 5 (left) + 0x05 | xxxx ---- | Amplitude channel 5 (right) + | | + 0x08 | xxxx xxxx | Frequency channel 0 + 0x09 | xxxx xxxx | Frequency channel 1 + 0x0a | xxxx xxxx | Frequency channel 2 + 0x0b | xxxx xxxx | Frequency channel 3 + 0x0c | xxxx xxxx | Frequency channel 4 + 0x0d | xxxx xxxx | Frequency channel 5 + | | + 0x10 | ---- -xxx | Channel 0 octave select + 0x10 | -xxx ---- | Channel 1 octave select + 0x11 | ---- -xxx | Channel 2 octave select + 0x11 | -xxx ---- | Channel 3 octave select + 0x12 | ---- -xxx | Channel 4 octave select + 0x12 | -xxx ---- | Channel 5 octave select + | | + 0x14 | ---- ---x | Channel 0 frequency enable (0 = off, 1 = on) + 0x14 | ---- --x- | Channel 1 frequency enable (0 = off, 1 = on) + 0x14 | ---- -x-- | Channel 2 frequency enable (0 = off, 1 = on) + 0x14 | ---- x--- | Channel 3 frequency enable (0 = off, 1 = on) + 0x14 | ---x ---- | Channel 4 frequency enable (0 = off, 1 = on) + 0x14 | --x- ---- | Channel 5 frequency enable (0 = off, 1 = on) + | | + 0x15 | ---- ---x | Channel 0 noise enable (0 = off, 1 = on) + 0x15 | ---- --x- | Channel 1 noise enable (0 = off, 1 = on) + 0x15 | ---- -x-- | Channel 2 noise enable (0 = off, 1 = on) + 0x15 | ---- x--- | Channel 3 noise enable (0 = off, 1 = on) + 0x15 | ---x ---- | Channel 4 noise enable (0 = off, 1 = on) + 0x15 | --x- ---- | Channel 5 noise enable (0 = off, 1 = on) + | | + 0x16 | ---- --xx | Noise generator parameters 0 + 0x16 | --xx ---- | Noise generator parameters 1 + | | + 0x18 | --xx xxxx | Envelope generator 0 parameters + 0x18 | x--- ---- | Envelope generator 0 control enable (0 = off, 1 = on) + 0x19 | --xx xxxx | Envelope generator 1 parameters + 0x19 | x--- ---- | Envelope generator 1 control enable (0 = off, 1 = on) + | | + 0x1c | ---- ---x | All channels enable (0 = off, 1 = on) + 0x1c | ---- --x- | Synch & Reset generators + + Unspecified bits should be written as zero. + +***************************************************************************/ + +#include "emu.h" +#include "saa1099.h" + +#define LEFT 0x00 +#define RIGHT 0x01 + +static constexpr int amplitude_lookup[16] = { + 0*32767/16, 1*32767/16, 2*32767/16, 3*32767/16, + 4*32767/16, 5*32767/16, 6*32767/16, 7*32767/16, + 8*32767/16, 9*32767/16, 10*32767/16, 11*32767/16, + 12*32767/16, 13*32767/16, 14*32767/16, 15*32767/16 +}; + +static constexpr uint8_t envelope[8][64] = { + /* zero amplitude */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* maximum amplitude */ + {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, }, + /* single decay */ + {15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* repetitive decay */ + {15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, + 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, + 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, + 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, + /* single triangular */ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* repetitive triangular */ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, + /* single attack */ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* repetitive attack */ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 } +}; + + +// device type definition +DEFINE_DEVICE_TYPE(SAA1099, saa1099_device, "saa1099", "Philips SAA1099") + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// saa1099_device - constructor +//------------------------------------------------- + +saa1099_device::saa1099_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, SAA1099, tag, owner, clock) + , device_sound_interface(mconfig, *this) + , m_stream(nullptr) + , m_noise_params{ 0, 0 } + , m_env_enable{ 0, 0 } + , m_env_reverse_right{ 0, 0 } + , m_env_mode{ 0, 0 } + , m_env_bits{ 0, 0 } + , m_env_clock{ 0, 0 } + , m_env_step{ 0, 0 } + , m_all_ch_enable(0) + , m_sync_state(0) + , m_selected_reg(0) + , m_sample_rate(0.0) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void saa1099_device::device_start() +{ + /* copy global parameters */ + m_master_clock = clock(); + m_sample_rate = clock() / 256; + + /* for each chip allocate one stream */ + m_stream = stream_alloc(0, 2, m_sample_rate); + + save_item(NAME(m_noise_params)); + save_item(NAME(m_env_enable)); + save_item(NAME(m_env_reverse_right)); + save_item(NAME(m_env_mode)); + save_item(NAME(m_env_bits)); + save_item(NAME(m_env_clock)); + save_item(NAME(m_env_step)); + save_item(NAME(m_all_ch_enable)); + save_item(NAME(m_sync_state)); + save_item(NAME(m_selected_reg)); + + for (int i = 0; i < 6; i++) + { + save_item(NAME(m_channels[i].frequency), i); + save_item(NAME(m_channels[i].freq_enable), i); + save_item(NAME(m_channels[i].noise_enable), i); + save_item(NAME(m_channels[i].octave), i); + save_item(NAME(m_channels[i].amplitude), i); + save_item(NAME(m_channels[i].envelope), i); + save_item(NAME(m_channels[i].counter), i); + save_item(NAME(m_channels[i].freq), i); + save_item(NAME(m_channels[i].level), i); + } + + for (int i = 0; i < 2; i++) + { + save_item(NAME(m_noise[i].counter), i); + save_item(NAME(m_noise[i].freq), i); + save_item(NAME(m_noise[i].level), i); + } +} + + +//------------------------------------------------- +// sound_stream_update - handle a stream update +//------------------------------------------------- + +void saa1099_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +{ + int j, ch; + /* if the channels are disabled we're done */ + if (!m_all_ch_enable) + { + /* init output data */ + memset(outputs[LEFT],0,samples*sizeof(*outputs[LEFT])); + memset(outputs[RIGHT],0,samples*sizeof(*outputs[RIGHT])); + return; + } + + for (ch = 0; ch < 2; ch++) + { + switch (m_noise_params[ch]) + { + case 0: m_noise[ch].freq = m_master_clock/256.0 * 2; break; + case 1: m_noise[ch].freq = m_master_clock/512.0 * 2; break; + case 2: m_noise[ch].freq = m_master_clock/1024.0 * 2; break; + case 3: m_noise[ch].freq = m_channels[ch * 3].freq; break; // todo: this case will be m_master_clock/[ch*3's octave divisor, 0 is = 256*2, higher numbers are higher] * 2 if the tone generator phase reset bit (0x1c bit 1) is set. + } + } + + /* fill all data needed */ + for( j = 0; j < samples; j++ ) + { + int output_l = 0, output_r = 0; + + /* for each channel */ + for (ch = 0; ch < 6; ch++) + { + if (m_channels[ch].freq == 0.0) + m_channels[ch].freq = (double)((2 * m_master_clock / 512) << m_channels[ch].octave) / + (511.0 - (double)m_channels[ch].frequency); + + /* check the actual position in the square wave */ + m_channels[ch].counter -= m_channels[ch].freq; + while (m_channels[ch].counter < 0) + { + /* calculate new frequency now after the half wave is updated */ + m_channels[ch].freq = (double)((2 * m_master_clock / 512) << m_channels[ch].octave) / + (511.0 - (double)m_channels[ch].frequency); + + m_channels[ch].counter += m_sample_rate; + m_channels[ch].level ^= 1; + + /* eventually clock the envelope counters */ + if (ch == 1 && m_env_clock[0] == 0) + envelope_w(0); + if (ch == 4 && m_env_clock[1] == 0) + envelope_w(1); + } + + // if the noise is enabled + if (m_channels[ch].noise_enable) + { + // if the noise level is high (noise 0: chan 0-2, noise 1: chan 3-5) + if (m_noise[ch/3].level & 1) + { + // subtract to avoid overflows, also use only half amplitude + output_l -= m_channels[ch].amplitude[ LEFT] * m_channels[ch].envelope[ LEFT] / 16 / 2; + output_r -= m_channels[ch].amplitude[RIGHT] * m_channels[ch].envelope[RIGHT] / 16 / 2; + } + } + // if the square wave is enabled + if (m_channels[ch].freq_enable) + { + // if the channel level is high + if (m_channels[ch].level & 1) + { + output_l += m_channels[ch].amplitude[ LEFT] * m_channels[ch].envelope[ LEFT] / 16; + output_r += m_channels[ch].amplitude[RIGHT] * m_channels[ch].envelope[RIGHT] / 16; + } + } + } + + for (ch = 0; ch < 2; ch++) + { + /* update the state of the noise generator + * polynomial is x^18 + x^11 + x (i.e. 0x20400) and is a plain XOR, initial state is probably all 1s + * see http://www.vogons.org/viewtopic.php?f=9&t=51695 */ + m_noise[ch].counter -= m_noise[ch].freq; + while (m_noise[ch].counter < 0) + { + m_noise[ch].counter += m_sample_rate; + if( ((m_noise[ch].level & 0x20000) == 0) != ((m_noise[ch].level & 0x0400) == 0) ) + m_noise[ch].level = (m_noise[ch].level << 1) | 1; + else + m_noise[ch].level <<= 1; + } + } + /* write sound data to the buffer */ + outputs[LEFT][j] = output_l / 6; + outputs[RIGHT][j] = output_r / 6; + } +} + + +void saa1099_device::envelope_w(int ch) +{ + if (m_env_enable[ch]) + { + int step, mode, mask; + mode = m_env_mode[ch]; + /* step from 0..63 and then loop in steps 32..63 */ + step = m_env_step[ch] = + ((m_env_step[ch] + 1) & 0x3f) | (m_env_step[ch] & 0x20); + + mask = 15; + if (m_env_bits[ch]) + mask &= ~1; /* 3 bit resolution, mask LSB */ + + m_channels[ch*3+0].envelope[ LEFT] = + m_channels[ch*3+1].envelope[ LEFT] = + m_channels[ch*3+2].envelope[ LEFT] = envelope[mode][step] & mask; + if (m_env_reverse_right[ch] & 0x01) + { + m_channels[ch*3+0].envelope[RIGHT] = + m_channels[ch*3+1].envelope[RIGHT] = + m_channels[ch*3+2].envelope[RIGHT] = (15 - envelope[mode][step]) & mask; + } + else + { + m_channels[ch*3+0].envelope[RIGHT] = + m_channels[ch*3+1].envelope[RIGHT] = + m_channels[ch*3+2].envelope[RIGHT] = envelope[mode][step] & mask; + } + } + else + { + /* envelope mode off, set all envelope factors to 16 */ + m_channels[ch*3+0].envelope[ LEFT] = + m_channels[ch*3+1].envelope[ LEFT] = + m_channels[ch*3+2].envelope[ LEFT] = + m_channels[ch*3+0].envelope[RIGHT] = + m_channels[ch*3+1].envelope[RIGHT] = + m_channels[ch*3+2].envelope[RIGHT] = 16; + } +} + + +WRITE8_MEMBER( saa1099_device::control_w ) +{ + if ((data & 0xff) > 0x1c) + { + /* Error! */ + logerror("%s: (SAA1099 '%s') Unknown register selected\n", machine().describe_context(), tag()); + } + + m_selected_reg = data & 0x1f; + if (m_selected_reg == 0x18 || m_selected_reg == 0x19) + { + /* clock the envelope channels */ + if (m_env_clock[0]) + envelope_w(0); + if (m_env_clock[1]) + envelope_w(1); + } +} + + +WRITE8_MEMBER( saa1099_device::data_w ) +{ + int reg = m_selected_reg; + int ch; + + /* first update the stream to this point in time */ + m_stream->update(); + + switch (reg) + { + /* channel i amplitude */ + case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: + ch = reg & 7; + m_channels[ch].amplitude[LEFT] = amplitude_lookup[data & 0x0f]; + m_channels[ch].amplitude[RIGHT] = amplitude_lookup[(data >> 4) & 0x0f]; + break; + /* channel i frequency */ + case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: + ch = reg & 7; + m_channels[ch].frequency = data & 0xff; + break; + /* channel i octave */ + case 0x10: case 0x11: case 0x12: + ch = (reg - 0x10) << 1; + m_channels[ch + 0].octave = data & 0x07; + m_channels[ch + 1].octave = (data >> 4) & 0x07; + break; + /* channel i frequency enable */ + case 0x14: + m_channels[0].freq_enable = data & 0x01; + m_channels[1].freq_enable = data & 0x02; + m_channels[2].freq_enable = data & 0x04; + m_channels[3].freq_enable = data & 0x08; + m_channels[4].freq_enable = data & 0x10; + m_channels[5].freq_enable = data & 0x20; + break; + /* channel i noise enable */ + case 0x15: + m_channels[0].noise_enable = data & 0x01; + m_channels[1].noise_enable = data & 0x02; + m_channels[2].noise_enable = data & 0x04; + m_channels[3].noise_enable = data & 0x08; + m_channels[4].noise_enable = data & 0x10; + m_channels[5].noise_enable = data & 0x20; + break; + /* noise generators parameters */ + case 0x16: + m_noise_params[0] = data & 0x03; + m_noise_params[1] = (data >> 4) & 0x03; + break; + /* envelope generators parameters */ + case 0x18: case 0x19: + ch = reg - 0x18; + m_env_reverse_right[ch] = data & 0x01; + m_env_mode[ch] = (data >> 1) & 0x07; + m_env_bits[ch] = data & 0x10; + m_env_clock[ch] = data & 0x20; + m_env_enable[ch] = data & 0x80; + /* reset the envelope */ + m_env_step[ch] = 0; + break; + /* channels enable & reset generators */ + case 0x1c: + m_all_ch_enable = data & 0x01; + m_sync_state = data & 0x02; + if (data & 0x02) + { + int i; + + /* Synch & Reset generators */ + logerror("%s: (SAA1099 '%s') -reg 0x1c- Chip reset\n", machine().describe_context(), tag()); + for (i = 0; i < 6; i++) + { + m_channels[i].level = 0; + m_channels[i].counter = 0.0; + } + } + break; + default: /* Error! */ + if (data != 0) + logerror("%s: (SAA1099 '%s') Unknown operation (reg:%02x, data:%02x)\n", machine().describe_context(), tag(), reg, data); + } +} + +WRITE8_MEMBER(saa1099_device::write) +{ + if (offset & 1) + control_w(space, 0, data); + else + data_w(space, 0, data); +} diff --git a/src/hardware/mame/saa1099.h b/src/hardware/mame/saa1099.h new file mode 100644 index 00000000..061f39ec --- /dev/null +++ b/src/hardware/mame/saa1099.h @@ -0,0 +1,96 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller, Manuel Abadia +/********************************************** + Philips SAA1099 Sound driver +**********************************************/ + +#ifndef MAME_SOUND_SAA1099_H +#define MAME_SOUND_SAA1099_H + +#pragma once + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_SAA1099_ADD(_tag, _clock) \ + MCFG_DEVICE_ADD(_tag, SAA1099, _clock) +#define MCFG_SAA1099_REPLACE(_tag, _clock) \ + MCFG_DEVICE_REPLACE(_tag, SAA1099, _clock) + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + + +// ======================> saa1099_device + +class saa1099_device : public device_t, + public device_sound_interface +{ +public: + saa1099_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_WRITE8_MEMBER( control_w ); + DECLARE_WRITE8_MEMBER( data_w ); + + DECLARE_WRITE8_MEMBER( write ); + +protected: + // device-level overrides + virtual void device_start() override; + + // sound stream update overrides + virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + +private: + struct saa1099_channel + { + saa1099_channel() : amplitude{ 0, 0 }, envelope{ 0, 0 } { } + + int frequency = 0; /* frequency (0x00..0xff) */ + int freq_enable = 0; /* frequency enable */ + int noise_enable = 0; /* noise enable */ + int octave = 0; /* octave (0x00..0x07) */ + int amplitude[2]; /* amplitude (0x00..0x0f) */ + int envelope[2]; /* envelope (0x00..0x0f or 0x10 == off) */ + + /* vars to simulate the square wave */ + double counter = 0.0; + double freq = 0.0; + int level = 0; + }; + + struct saa1099_noise + { + saa1099_noise() { } + + /* vars to simulate the noise generator output */ + double counter = 0.0; + double freq = 0.0; + uint32_t level = 0xFFFFFFFF; /* noise polynomial shifter */ + }; + + void envelope_w(int ch); + + sound_stream *m_stream; /* our stream */ + int m_noise_params[2]; /* noise generators parameters */ + int m_env_enable[2]; /* envelope generators enable */ + int m_env_reverse_right[2]; /* envelope reversed for right channel */ + int m_env_mode[2]; /* envelope generators mode */ + int m_env_bits[2]; /* non zero = 3 bits resolution */ + int m_env_clock[2]; /* envelope clock mode (non-zero external) */ + int m_env_step[2]; /* current envelope step */ + int m_all_ch_enable; /* all channels enable */ + int m_sync_state; /* sync all channels */ + int m_selected_reg; /* selected register */ + saa1099_channel m_channels[6]; /* channels */ + saa1099_noise m_noise[2]; /* noise generators */ + double m_sample_rate; + int m_master_clock; +}; + +DECLARE_DEVICE_TYPE(SAA1099, saa1099_device) + +#endif // MAME_SOUND_SAA1099_H diff --git a/src/hardware/mame/sn76496.cpp b/src/hardware/mame/sn76496.cpp new file mode 100644 index 00000000..bccb53c2 --- /dev/null +++ b/src/hardware/mame/sn76496.cpp @@ -0,0 +1,474 @@ +// license:BSD-3-Clause +// copyright-holders:Nicola Salmoria +/*************************************************************************** + + sn76496.c + by Nicola Salmoria + with contributions by others + + Routines to emulate the: + Texas Instruments SN76489, SN76489A, SN76494/SN76496 + ( Also known as, or at least compatible with, the TMS9919 and SN94624.) + and the Sega 'PSG' used on the Master System, Game Gear, and Megadrive/Genesis + This chip is known as the Programmable Sound Generator, or PSG, and is a 4 + channel sound generator, with three squarewave channels and a noise/arbitrary + duty cycle channel. + + Noise emulation for all verified chips should be accurate: + + ** SN76489 uses a 15-bit shift register with taps on bits D and E, output on E, + XOR function. + It uses a 15-bit ring buffer for periodic noise/arbitrary duty cycle. + Its output is inverted. + ** SN94624 is the same as SN76489 but lacks the /8 divider on its clock input. + ** SN76489A uses a 15-bit shift register with taps on bits D and E, output on F, + XOR function. + It uses a 15-bit ring buffer for periodic noise/arbitrary duty cycle. + Its output is not inverted. + ** SN76494 is the same as SN76489A but lacks the /8 divider on its clock input. + ** SN76496 is identical in operation to the SN76489A, but the audio input on pin 9 is + documented. + All the TI-made PSG chips have an audio input line which is mixed with the 4 channels + of output. (It is undocumented and may not function properly on the sn76489, 76489a + and 76494; the sn76489a input is mentioned in datasheets for the tms5200) + All the TI-made PSG chips act as if the frequency was set to 0x400 if 0 is + written to the frequency register. + ** Sega Master System III/MD/Genesis PSG uses a 16-bit shift register with taps + on bits C and F, output on F + It uses a 16-bit ring buffer for periodic noise/arbitrary duty cycle. + (whether it uses an XOR or XNOR needs to be verified, assumed XOR) + (whether output is inverted or not needs to be verified, assumed to be inverted) + ** Sega Game Gear PSG is identical to the SMS3/MD/Genesis one except it has an + extra register for mapping which channels go to which speaker. + The register, connected to a z80 port, means: + for bits 7 6 5 4 3 2 1 0 + L3 L2 L1 L0 R3 R2 R1 R0 + Noise is an XOR function, and audio output is negated before being output. + All the Sega-made PSG chips act as if the frequency was set to 0 if 0 is written + to the frequency register. + ** NCR7496 (as used on the Tandy 1000) is similar to the SN76489 but with a + different noise LFSR patttern: taps on bits A and E, output on E + It uses a 15-bit ring buffer for periodic noise/arbitrary duty cycle. + (all this chip's info needs to be verified) + + 28/03/2005 : Sebastien Chevalier + Update th SN76496Write func, according to SN76489 doc found on SMSPower. + - On write with 0x80 set to 0, when LastRegister is other then TONE, + the function is similar than update with 0x80 set to 1 + + 23/04/2007 : Lord Nightmare + Major update, implement all three different noise generation algorithms and a + set_variant call to discern among them. + + 28/04/2009 : Lord Nightmare + Add READY line readback; cleaned up struct a bit. Cleaned up comments. + Add more TODOs. Fixed some unsaved savestate related stuff. + + 04/11/2009 : Lord Nightmare + Changed the way that the invert works (it now selects between XOR and XNOR + for the taps), and added R->OldNoise to simulate the extra 0 that is always + output before the noise LFSR contents are after an LFSR reset. + This fixes SN76489/A to match chips. Added SN94624. + + 14/11/2009 : Lord Nightmare + Removed STEP mess, vastly simplifying the code. Made output bipolar rather + than always above the 0 line, but disabled that code due to pending issues. + + 16/11/2009 : Lord Nightmare + Fix screeching in regulus: When summing together four equal channels, the + size of the max amplitude per channel should be 1/4 of the max range, not + 1/3. Added NCR7496. + + 18/11/2009 : Lord Nightmare + Modify Init functions to support negating the audio output. The gamegear + psg does this. Change gamegear and sega psgs to use XOR rather than XNOR + based on testing. Got rid of R->OldNoise and fixed taps accordingly. + Added stereo support for game gear. + + 15/01/2010 : Lord Nightmare + Fix an issue with SN76489 and SN76489A having the wrong periodic noise periods. + Note that properly emulating the noise cycle bit timing accurately may require + extensive rewriting. + + 24/01/2010: Lord Nightmare + Implement periodic noise as forcing one of the XNOR or XOR taps to 1 or 0 respectively. + Thanks to PlgDavid for providing samples which helped immensely here. + Added true clock divider emulation, so sn94624 and sn76494 run 8x faster than + the others, as in real life. + + 15/02/2010: Lord Nightmare & Michael Zapf (additional testing by PlgDavid) + Fix noise period when set to mirror channel 3 and channel 3 period is set to 0 (tested on hardware for noise, wave needs tests) - MZ + Fix phase of noise on sn94624 and sn76489; all chips use a standard XOR, the only inversion is the output itself - LN, Plgdavid + Thanks to PlgDavid and Michael Zapf for providing samples which helped immensely here. + + 23/02/2011: Lord Nightmare & Enik + Made it so the Sega PSG chips have a frequency of 0 if 0 is written to the + frequency register, while the others have 0x400 as before. Should fix a bug + or two on sega games, particularly Vigilante on Sega Master System. Verified + on SMS hardware. + + 27/06/2012: Michael Zapf + Converted to modern device, legacy devices were gradually removed afterwards. + + 16/09/2015: Lord Nightmare + Fix PSG chips to have volume reg inited on reset to 0x0 based on tests by + ValleyBell. Made Sega PSG chips start up with register 0x3 selected (volume + for channel 2) based on hardware tests by Nemesis. + + TODO: * Implement the TMS9919 - any difference to sn94624? + * Implement the T6W28; has registers in a weird order, needs writes + to be 'sanitized' first. Also is stereo, similar to game gear. + * Test the NCR7496; Smspower says the whitenoise taps are A and E, + but this needs verification on real hardware. + * Factor out common code so that the SAA1099 can share some code. + +***************************************************************************/ + +#include "emu.h" +#include "sn76496.h" + +#define MAX_OUTPUT 0x7fff + + +sn76496_base_device::sn76496_base_device( + const machine_config &mconfig, + device_type type, + const char *tag, + int feedbackmask, + int noisetap1, + int noisetap2, + bool negate, + bool stereo, + int clockdivider, + bool sega, + device_t *owner, + uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) + , device_sound_interface(mconfig, *this) + , m_ready_handler(*this) + , m_feedback_mask(feedbackmask) + , m_whitenoise_tap1(noisetap1) + , m_whitenoise_tap2(noisetap2) + , m_negate(negate) + , m_stereo(stereo) + , m_clock_divider(clockdivider) + , m_sega_style_psg(sega) +{ +} + +sn76496_device::sn76496_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sn76496_base_device(mconfig, SN76496, tag, 0x10000, 0x04, 0x08, false, false, 8, true, owner, clock) +{ +} + +u8106_device::u8106_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sn76496_base_device(mconfig, U8106, tag, 0x4000, 0x01, 0x02, true, false, 8, true, owner, clock) +{ +} + +y2404_device::y2404_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sn76496_base_device(mconfig, Y2404, tag, 0x10000, 0x04, 0x08, false, false, 8, true, owner, clock) +{ +} + +sn76489_device::sn76489_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sn76496_base_device(mconfig, SN76489, tag, 0x4000, 0x01, 0x02, true, false, 8, true, owner, clock) +{ +} + +sn76489a_device::sn76489a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sn76496_base_device(mconfig, SN76489A, tag, 0x10000, 0x04, 0x08, false, false, 8, true, owner, clock) +{ +} + +sn76494_device::sn76494_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sn76496_base_device(mconfig, SN76494, tag, 0x10000, 0x04, 0x08, false, false, 1, true, owner, clock) +{ +} + +sn94624_device::sn94624_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sn76496_base_device(mconfig, SN94624, tag, 0x4000, 0x01, 0x02, true, false, 1, true, owner, clock) +{ +} + +ncr7496_device::ncr7496_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sn76496_base_device(mconfig, NCR7496, tag, 0x8000, 0x02, 0x20, false, false, 8, true, owner, clock) +{ +} + +gamegear_device::gamegear_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sn76496_base_device(mconfig, GAMEGEAR, tag, 0x8000, 0x01, 0x08, true, true, 8, false, owner, clock) +{ +} + +segapsg_device::segapsg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sn76496_base_device(mconfig, SEGAPSG, tag, 0x8000, 0x01, 0x08, true, false, 8, false, owner, clock) +{ +} + + +void sn76496_base_device::device_start() +{ + int sample_rate = clock()/2; + int i; + double out; + int gain; + + m_ready_handler.resolve_safe(); + + m_sound = machine().sound().stream_alloc(*this, 0, (m_stereo? 2:1), sample_rate); + + for (i = 0; i < 4; i++) m_volume[i] = 0; + + m_last_register = m_sega_style_psg?3:0; // Sega VDP PSG defaults to selected period reg for 2nd channel + for (i = 0; i < 8; i+=2) + { + m_register[i] = 0; + m_register[i + 1] = 0x0; // volume = 0x0 (max volume) on reset; this needs testing on chips other than SN76489A and Sega VDP PSG + } + + for (i = 0; i < 4; i++) + { + m_output[i] = 0; + m_period[i] = 0; + m_count[i] = 0; + } + + m_RNG = m_feedback_mask; + m_output[3] = m_RNG & 1; + + m_cycles_to_ready = 1; // assume ready is not active immediately on init. is this correct? + m_stereo_mask = 0xFF; // all channels enabled + m_current_clock = m_clock_divider-1; + + // set gain + gain = 0; + + gain &= 0xff; + + // increase max output basing on gain (0.2 dB per step) + out = MAX_OUTPUT / 4; // four channels, each gets 1/4 of the total range + while (gain-- > 0) + out *= 1.023292992; // = (10 ^ (0.2/20)) + + // build volume table (2dB per step) + for (i = 0; i < 15; i++) + { + // limit volume to avoid clipping + if (out > MAX_OUTPUT / 4) m_vol_table[i] = MAX_OUTPUT / 4; + else m_vol_table[i] = out; + + out /= 1.258925412; /* = 10 ^ (2/20) = 2dB */ + } + m_vol_table[15] = 0; + + m_ready_state = true; + + register_for_save_states(); +} + +WRITE8_MEMBER( sn76496_base_device::stereo_w ) +{ + m_sound->update(); + if (m_stereo) m_stereo_mask = data; + else fatalerror("sn76496_base_device: Call to stereo write with mono chip!\n"); +} + +void sn76496_base_device::write(uint8_t data) +{ + int n, r, c; + + // update the output buffer before changing the registers + m_sound->update(); + + // set number of cycles until READY is active; this is always one + // 'sample', i.e. it equals the clock divider exactly + m_cycles_to_ready = 1; + + if (data & 0x80) + { + r = (data & 0x70) >> 4; + m_last_register = r; + m_register[r] = (m_register[r] & 0x3f0) | (data & 0x0f); + } + else + { + r = m_last_register; + } + + c = r >> 1; + switch (r) + { + case 0: // tone 0: frequency + case 2: // tone 1: frequency + case 4: // tone 2: frequency + if ((data & 0x80) == 0) m_register[r] = (m_register[r] & 0x0f) | ((data & 0x3f) << 4); + if ((m_register[r] != 0) || (!m_sega_style_psg)) m_period[c] = m_register[r]; + else m_period[c] = 0x400; + + if (r == 4) + { + // update noise shift frequency + if ((m_register[6] & 0x03) == 0x03) m_period[3] = m_period[2]<<1; + } + break; + case 1: // tone 0: volume + case 3: // tone 1: volume + case 5: // tone 2: volume + case 7: // noise: volume + m_volume[c] = m_vol_table[data & 0x0f]; + if ((data & 0x80) == 0) m_register[r] = (m_register[r] & 0x3f0) | (data & 0x0f); + break; + case 6: // noise: frequency, mode + { + if ((data & 0x80) == 0) logerror("sn76496_base_device: write to reg 6 with bit 7 clear; data was %03x, new write is %02x! report this to LN!\n", m_register[6], data); + if ((data & 0x80) == 0) m_register[r] = (m_register[r] & 0x3f0) | (data & 0x0f); + n = m_register[6]; + // N/512,N/1024,N/2048,Tone #3 output + m_period[3] = ((n&3) == 3)? (m_period[2]<<1) : (1 << (5+(n&3))); + m_RNG = m_feedback_mask; + } + break; + } +} + +WRITE8_MEMBER( sn76496_base_device::write ) +{ + write(data); +} + +inline bool sn76496_base_device::in_noise_mode() +{ + return ((m_register[6] & 4)!=0); +} + +void sn76496_base_device::countdown_cycles() +{ + if (m_cycles_to_ready > 0) + { + m_cycles_to_ready--; + if (m_ready_state==true) m_ready_handler(CLEAR_LINE); + m_ready_state = false; + } + else + { + if (m_ready_state==false) m_ready_handler(ASSERT_LINE); + m_ready_state = true; + } +} + +void sn76496_base_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +{ + int i; + stream_sample_t *lbuffer = outputs[0]; + stream_sample_t *rbuffer = (m_stereo)? outputs[1] : nullptr; + + int16_t out; + int16_t out2 = 0; + + while (samples > 0) + { + // clock chip once + if (m_current_clock > 0) // not ready for new divided clock + { + m_current_clock--; + } + else // ready for new divided clock, make a new sample + { + m_current_clock = m_clock_divider-1; + // decrement Cycles to READY by one + countdown_cycles(); + + // handle channels 0,1,2 + for (i = 0; i < 3; i++) + { + m_count[i]--; + if (m_count[i] <= 0) + { + m_output[i] ^= 1; + m_count[i] = m_period[i]; + } + } + + // handle channel 3 + m_count[3]--; + if (m_count[3] <= 0) + { + // if noisemode is 1, both taps are enabled + // if noisemode is 0, the lower tap, whitenoisetap2, is held at 0 + // The != was a bit-XOR (^) before + if (((m_RNG & m_whitenoise_tap1)!=0) != (((m_RNG & m_whitenoise_tap2)!=0) && in_noise_mode())) + { + m_RNG >>= 1; + m_RNG |= m_feedback_mask; + } + else + { + m_RNG >>= 1; + } + m_output[3] = m_RNG & 1; + + m_count[3] = m_period[3]; + } + } + + if (m_stereo) + { + out = ((((m_stereo_mask & 0x10)!=0) && (m_output[0]!=0))? m_volume[0] : 0) + + ((((m_stereo_mask & 0x20)!=0) && (m_output[1]!=0))? m_volume[1] : 0) + + ((((m_stereo_mask & 0x40)!=0) && (m_output[2]!=0))? m_volume[2] : 0) + + ((((m_stereo_mask & 0x80)!=0) && (m_output[3]!=0))? m_volume[3] : 0); + + out2= ((((m_stereo_mask & 0x1)!=0) && (m_output[0]!=0))? m_volume[0] : 0) + + ((((m_stereo_mask & 0x2)!=0) && (m_output[1]!=0))? m_volume[1] : 0) + + ((((m_stereo_mask & 0x4)!=0) && (m_output[2]!=0))? m_volume[2] : 0) + + ((((m_stereo_mask & 0x8)!=0) && (m_output[3]!=0))? m_volume[3] : 0); + } + else + { + out= ((m_output[0]!=0)? m_volume[0]:0) + +((m_output[1]!=0)? m_volume[1]:0) + +((m_output[2]!=0)? m_volume[2]:0) + +((m_output[3]!=0)? m_volume[3]:0); + } + + if (m_negate) { out = -out; out2 = -out2; } + + *(lbuffer++) = out; + if (m_stereo) *(rbuffer++) = out2; + samples--; + } +} + +void sn76496_base_device::register_for_save_states() +{ + save_item(NAME(m_vol_table)); + save_item(NAME(m_register)); + save_item(NAME(m_last_register)); + save_item(NAME(m_volume)); + save_item(NAME(m_RNG)); +// save_item(NAME(m_clock_divider)); + save_item(NAME(m_current_clock)); +// save_item(NAME(m_feedback_mask)); +// save_item(NAME(m_whitenoise_tap1)); +// save_item(NAME(m_whitenoise_tap2)); +// save_item(NAME(m_negate)); +// save_item(NAME(m_stereo)); + save_item(NAME(m_stereo_mask)); + save_item(NAME(m_period)); + save_item(NAME(m_count)); + save_item(NAME(m_output)); + save_item(NAME(m_cycles_to_ready)); +// save_item(NAME(m_sega_style_psg)); +} + +DEFINE_DEVICE_TYPE(SN76496, sn76496_device, "sn76496", "SN76496") +DEFINE_DEVICE_TYPE(U8106, u8106_device, "u8106", "U8106") +DEFINE_DEVICE_TYPE(Y2404, y2404_device, "y2404", "Y2404") +DEFINE_DEVICE_TYPE(SN76489, sn76489_device, "sn76489", "SN76489") +DEFINE_DEVICE_TYPE(SN76489A, sn76489a_device, "sn76489a", "SN76489A") +DEFINE_DEVICE_TYPE(SN76494, sn76494_device, "sn76494", "SN76494") +DEFINE_DEVICE_TYPE(SN94624, sn94624_device, "sn94624", "SN94624") +DEFINE_DEVICE_TYPE(NCR7496, ncr7496_device, "ncr7496", "NCR7496") +DEFINE_DEVICE_TYPE(GAMEGEAR, gamegear_device, "gamegear_psg", "Game Gear PSG") +DEFINE_DEVICE_TYPE(SEGAPSG, segapsg_device, "segapsg", "Sega VDP PSG") diff --git a/src/hardware/mame/sn76496.h b/src/hardware/mame/sn76496.h new file mode 100644 index 00000000..22ad524e --- /dev/null +++ b/src/hardware/mame/sn76496.h @@ -0,0 +1,155 @@ +// license:BSD-3-Clause +// copyright-holders:Nicola Salmoria +#ifndef MAME_SOUND_SN76496_H +#define MAME_SOUND_SN76496_H + +#pragma once + + +DECLARE_DEVICE_TYPE(SN76496, sn76496_device) +DECLARE_DEVICE_TYPE(U8106, u8106_device) +DECLARE_DEVICE_TYPE(Y2404, y2404_device) +DECLARE_DEVICE_TYPE(SN76489, sn76489_device) +DECLARE_DEVICE_TYPE(SN76489A, sn76489a_device) +DECLARE_DEVICE_TYPE(SN76494, sn76494_device) +DECLARE_DEVICE_TYPE(SN94624, sn94624_device) +DECLARE_DEVICE_TYPE(NCR7496, ncr7496_device) +DECLARE_DEVICE_TYPE(GAMEGEAR, gamegear_device) +DECLARE_DEVICE_TYPE(SEGAPSG, segapsg_device) + + +#define MCFG_SN76496_READY_HANDLER(cb) \ + devcb = &sn76496_base_device::set_ready_handler(*device, (DEVCB_##cb)); + +class sn76496_base_device : public device_t, public device_sound_interface +{ +public: + // static configuration helpers + template static devcb_base &set_ready_handler(device_t &device, Object &&cb) { return downcast(device).m_ready_handler.set_callback(std::forward(cb)); } + + DECLARE_WRITE8_MEMBER( stereo_w ); + void write(uint8_t data); + DECLARE_WRITE8_MEMBER( write ); + DECLARE_READ_LINE_MEMBER( ready_r ) { return m_ready_state ? 1 : 0; } + +protected: + sn76496_base_device( + const machine_config &mconfig, + device_type type, + const char *tag, + int feedbackmask, + int noisetap1, + int noisetap2, + bool negate, + bool stereo, + int clockdivider, + bool sega, + device_t *owner, + uint32_t clock); + + virtual void device_start() override; + virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + +private: + inline bool in_noise_mode(); + void register_for_save_states(); + void countdown_cycles(); + + bool m_ready_state; + + devcb_write_line m_ready_handler; + + sound_stream* m_sound; + + const int32_t m_feedback_mask; // mask for feedback + const int32_t m_whitenoise_tap1; // mask for white noise tap 1 (higher one, usually bit 14) + const int32_t m_whitenoise_tap2; // mask for white noise tap 2 (lower one, usually bit 13) + const bool m_negate; // output negate flag + const bool m_stereo; // whether we're dealing with stereo or not + const int32_t m_clock_divider; // clock divider + const bool m_sega_style_psg; // flag for if frequency zero acts as if it is one more than max (0x3ff+1) or if it acts like 0; AND if the initial register is pointing to 0x3 instead of 0x0 AND if the volume reg is preloaded with 0xF instead of 0x0 + + int32_t m_vol_table[16]; // volume table (for 4-bit to db conversion) + int32_t m_register[8]; // registers + int32_t m_last_register; // last register written + int32_t m_volume[4]; // db volume of voice 0-2 and noise + uint32_t m_RNG; // noise generator LFSR + int32_t m_current_clock; + int32_t m_stereo_mask; // the stereo output mask + int32_t m_period[4]; // Length of 1/2 of waveform + int32_t m_count[4]; // Position within the waveform + int32_t m_output[4]; // 1-bit output of each channel, pre-volume + int32_t m_cycles_to_ready; // number of cycles until the READY line goes active +}; + +// SN76496: Whitenoise verified, phase verified, periodic verified (by Michael Zapf) +class sn76496_device : public sn76496_base_device +{ +public: + sn76496_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + +// U8106 not verified yet. todo: verify; (a custom marked sn76489? only used on mr. do and maybe other universal games) +class u8106_device : public sn76496_base_device +{ +public: + u8106_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + +// Y2404 not verified yet. todo: verify; (don't be fooled by the Y, it's a TI chip, not Yamaha) +class y2404_device : public sn76496_base_device +{ +public: + y2404_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + +// SN76489 not verified yet. todo: verify; +class sn76489_device : public sn76496_base_device +{ +public: + sn76489_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + +// SN76489A: whitenoise verified, phase verified, periodic verified (by plgdavid) +class sn76489a_device : public sn76496_base_device +{ +public: + sn76489a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + +// SN76494 not verified, (according to datasheet: same as sn76489a but without the /8 divider) +class sn76494_device : public sn76496_base_device +{ +public: + sn76494_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + +// SN94624 whitenoise verified, phase verified, period verified; verified by PlgDavid +class sn94624_device : public sn76496_base_device +{ +public: + sn94624_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + +// NCR7496 not verified; info from smspower wiki +class ncr7496_device : public sn76496_base_device +{ +public: + ncr7496_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + +// Verified by Justin Kerk +class gamegear_device : public sn76496_base_device +{ +public: + gamegear_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + +// todo: verify; from smspower wiki, assumed to have same invert as gamegear +class segapsg_device : public sn76496_base_device +{ +public: + segapsg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + +#endif // MAME_SOUND_SN76496_H diff --git a/src/hardware/mame/ymdeltat.cpp b/src/hardware/mame/ymdeltat.cpp new file mode 100644 index 00000000..29e05b4e --- /dev/null +++ b/src/hardware/mame/ymdeltat.cpp @@ -0,0 +1,650 @@ +// license:GPL-2.0+ +// copyright-holders:Jarek Burczynski +/* +** +** File: ymdeltat.c +** +** YAMAHA DELTA-T adpcm sound emulation subroutine +** used by fmopl.c (Y8950) and fm.c (YM2608 and YM2610/B) +** +** Base program is YM2610 emulator by Hiromitsu Shioya. +** Written by Tatsuyuki Satoh +** Improvements by Jarek Burczynski (bujar at mame dot net) +** +** +** History: +** +** 03-08-2003 Jarek Burczynski: +** - fixed BRDY flag implementation. +** +** 24-07-2003 Jarek Burczynski, Frits Hilderink: +** - fixed delault value for control2 in YM_DELTAT_ADPCM_Reset +** +** 22-07-2003 Jarek Burczynski, Frits Hilderink: +** - fixed external memory support +** +** 15-06-2003 Jarek Burczynski: +** - implemented CPU -> AUDIO ADPCM synthesis (via writes to the ADPCM data reg $08) +** - implemented support for the Limit address register +** - supported two bits from the control register 2 ($01): RAM TYPE (x1 bit/x8 bit), ROM/RAM +** - implemented external memory access (read/write) via the ADPCM data reg reads/writes +** Thanks go to Frits Hilderink for the example code. +** +** 14-06-2003 Jarek Burczynski: +** - various fixes to enable proper support for status register flags: BSRDY, PCM BSY, ZERO +** - modified EOS handling +** +** 05-04-2003 Jarek Burczynski: +** - implemented partial support for external/processor memory on sample replay +** +** 01-12-2002 Jarek Burczynski: +** - fixed first missing sound in gigandes thanks to previous fix (interpolator) by ElSemi +** - renamed/removed some YM_DELTAT struct fields +** +** 28-12-2001 Acho A. Tang +** - added EOS status report on ADPCM playback. +** +** 05-08-2001 Jarek Burczynski: +** - now_step is initialized with 0 at the start of play. +** +** 12-06-2001 Jarek Burczynski: +** - corrected end of sample bug in YM_DELTAT_ADPCM_CALC. +** Checked on real YM2610 chip - address register is 24 bits wide. +** Thanks go to Stefan Jokisch (stefan.jokisch@gmx.de) for tracking down the problem. +** +** TO DO: +** Check size of the address register on the other chips.... +** +** Version 0.72 +** +** sound chips that have this unit: +** YM2608 OPNA +** YM2610/B OPNB +** Y8950 MSX AUDIO +** +*/ + +#include "emu.h" +#include "ymdeltat.h" + +#define YM_DELTAT_SHIFT (16) + +#define YM_DELTAT_DELTA_MAX (24576) +#define YM_DELTAT_DELTA_MIN (127) +#define YM_DELTAT_DELTA_DEF (127) + +#define YM_DELTAT_DECODE_RANGE 32768 +#define YM_DELTAT_DECODE_MIN (-(YM_DELTAT_DECODE_RANGE)) +#define YM_DELTAT_DECODE_MAX ((YM_DELTAT_DECODE_RANGE)-1) + + +/* Forecast to next Forecast (rate = *8) */ +/* 1/8 , 3/8 , 5/8 , 7/8 , 9/8 , 11/8 , 13/8 , 15/8 */ +static constexpr int32_t ym_deltat_decode_tableB1[16] = { + 1, 3, 5, 7, 9, 11, 13, 15, + -1, -3, -5, -7, -9, -11, -13, -15, +}; +/* delta to next delta (rate= *64) */ +/* 0.9 , 0.9 , 0.9 , 0.9 , 1.2 , 1.6 , 2.0 , 2.4 */ +static constexpr int32_t ym_deltat_decode_tableB2[16] = { + 57, 57, 57, 57, 77, 102, 128, 153, + 57, 57, 57, 57, 77, 102, 128, 153 +}; + +#if 0 +void YM_DELTAT::BRDY_callback() +{ + logerror("BRDY_callback reached (flag set) !\n"); + + /* set BRDY bit in status register */ + if(status_set_handler) + if(status_change_BRDY_bit) + (status_set_handler)(status_change_which_chip, status_change_BRDY_bit); +} +#endif + +uint8_t YM_DELTAT::ADPCM_Read() +{ + uint8_t v = 0; + + /* external memory read */ + if ((portstate & 0xe0) == 0x20) + { + /* two dummy reads */ + if (memread) + { + now_addr = start << 1; + memread--; + return 0; + } + + + if (now_addr != (end << 1)) + { + v = memory[now_addr>>1]; + + /*logerror("YM Delta-T memory read $%08x, v=$%02x\n", now_addr >> 1, v);*/ + + now_addr += 2; /* two nibbles at a time */ + + /* reset BRDY bit in status register, which means we are reading the memory now */ + if (status_reset_handler && status_change_BRDY_bit) + (status_reset_handler)(status_change_which_chip, status_change_BRDY_bit); + + /* setup a timer that will callback us in 10 master clock cycles for Y8950 + * in the callback set the BRDY flag to 1 , which means we have another data ready. + * For now, we don't really do this; we simply reset and set the flag in zero time, so that the IRQ will work. + */ + /* set BRDY bit in status register */ + if (status_set_handler && status_change_BRDY_bit) + (status_set_handler)(status_change_which_chip, status_change_BRDY_bit); + } + else + { + /* set EOS bit in status register */ + if (status_set_handler && status_change_EOS_bit) + (status_set_handler)(status_change_which_chip, status_change_EOS_bit); + } + } + + return v; +} + + +/* 0-DRAM x1, 1-ROM, 2-DRAM x8, 3-ROM (3 is bad setting - not allowed by the manual) */ +static constexpr uint8_t dram_rightshift[4]={3,0,0,0}; + +/* DELTA-T ADPCM write register */ +void YM_DELTAT::ADPCM_Write(int r, int v) +{ + if (r >= 0x10) return; + reg[r] = v; /* stock data */ + + switch (r) + { + case 0x00: +/* +START: + Accessing *external* memory is started when START bit (D7) is set to "1", so + you must set all conditions needed for recording/playback before starting. + If you access *CPU-managed* memory, recording/playback starts after + read/write of ADPCM data register $08. + +REC: + 0 = ADPCM synthesis (playback) + 1 = ADPCM analysis (record) + +MEMDATA: + 0 = processor (*CPU-managed*) memory (means: using register $08) + 1 = external memory (using start/end/limit registers to access memory: RAM or ROM) + + +SPOFF: + controls output pin that should disable the speaker while ADPCM analysis + +RESET and REPEAT only work with external memory. + + +some examples: +value: START, REC, MEMDAT, REPEAT, SPOFF, x,x,RESET meaning: + C8 1 1 0 0 1 0 0 0 Analysis (recording) from AUDIO to CPU (to reg $08), sample rate in PRESCALER register + E8 1 1 1 0 1 0 0 0 Analysis (recording) from AUDIO to EXT.MEMORY, sample rate in PRESCALER register + 80 1 0 0 0 0 0 0 0 Synthesis (playing) from CPU (from reg $08) to AUDIO,sample rate in DELTA-N register + a0 1 0 1 0 0 0 0 0 Synthesis (playing) from EXT.MEMORY to AUDIO, sample rate in DELTA-N register + + 60 0 1 1 0 0 0 0 0 External memory write via ADPCM data register $08 + 20 0 0 1 0 0 0 0 0 External memory read via ADPCM data register $08 + +*/ + /* handle emulation mode */ + if (emulation_mode == EMULATION_MODE_YM2610) + { + v |= 0x20; /* YM2610 always uses external memory and doesn't even have memory flag bit. */ + } + + portstate = v & (0x80|0x40|0x20|0x10|0x01); /* start, rec, memory mode, repeat flag copy, reset(bit0) */ + + if (portstate & 0x80)/* START,REC,MEMDATA,REPEAT,SPOFF,--,--,RESET */ + { + /* set PCM BUSY bit */ + PCM_BSY = 1; + + /* start ADPCM */ + now_step = 0; + acc = 0; + prev_acc = 0; + adpcml = 0; + adpcmd = YM_DELTAT_DELTA_DEF; + now_data = 0; + + } + + if (portstate & 0x20) /* do we access external memory? */ + { + now_addr = start << 1; + memread = 2; /* two dummy reads needed before accesing external memory via register $08*/ + + /* if yes, then let's check if ADPCM memory is mapped and big enough */ + if (!memory) + { + device->logerror("YM Delta-T ADPCM rom not mapped\n"); + portstate = 0x00; + PCM_BSY = 0; + } + else + { + if (end >= memory_size) /* Check End in Range */ + { + device->logerror("YM Delta-T ADPCM end out of range: $%08x\n", end); + end = memory_size - 1; + } + if (start >= memory_size) /* Check Start in Range */ + { + device->logerror("YM Delta-T ADPCM start out of range: $%08x\n", start); + portstate = 0x00; + PCM_BSY = 0; + } + } + } + else /* we access CPU memory (ADPCM data register $08) so we only reset now_addr here */ + { + now_addr = 0; + } + + if (portstate & 0x01) + { + portstate = 0x00; + + /* clear PCM BUSY bit (in status register) */ + PCM_BSY = 0; + + /* set BRDY flag */ + if (status_set_handler && status_change_BRDY_bit) + (status_set_handler)(status_change_which_chip, status_change_BRDY_bit); + } + break; + + case 0x01: /* L,R,-,-,SAMPLE,DA/AD,RAMTYPE,ROM */ + /* handle emulation mode */ + if (emulation_mode == EMULATION_MODE_YM2610) + { + v |= 0x01; /* YM2610 always uses ROM as an external memory and doesn't tave ROM/RAM memory flag bit. */ + } + + pan = &output_pointer[(v >> 6) & 0x03]; + if ((control2 & 3) != (v & 3)) + { + /*0-DRAM x1, 1-ROM, 2-DRAM x8, 3-ROM (3 is bad setting - not allowed by the manual) */ + if (DRAMportshift != dram_rightshift[v & 3]) + { + DRAMportshift = dram_rightshift[v & 3]; + + /* final shift value depends on chip type and memory type selected: + 8 for YM2610 (ROM only), + 5 for ROM for Y8950 and YM2608, + 5 for x8bit DRAMs for Y8950 and YM2608, + 2 for x1bit DRAMs for Y8950 and YM2608. + */ + + /* refresh addresses */ + start = (reg[0x3] * 0x0100 | reg[0x2]) << (portshift - DRAMportshift); + end = (reg[0x5] * 0x0100 | reg[0x4]) << (portshift - DRAMportshift); + end += (1 << (portshift - DRAMportshift)) - 1; + limit = (reg[0xd]*0x0100 | reg[0xc]) << (portshift - DRAMportshift); + } + } + control2 = v; + break; + + case 0x02: /* Start Address L */ + case 0x03: /* Start Address H */ + start = (reg[0x3] * 0x0100 | reg[0x2]) << (portshift - DRAMportshift); + /*logerror("DELTAT start: 02=%2x 03=%2x addr=%8x\n",reg[0x2], reg[0x3],start );*/ + break; + + case 0x04: /* Stop Address L */ + case 0x05: /* Stop Address H */ + end = (reg[0x5]*0x0100 | reg[0x4]) << (portshift - DRAMportshift); + end += (1 << (portshift - DRAMportshift)) - 1; + /*logerror("DELTAT end : 04=%2x 05=%2x addr=%8x\n",reg[0x4], reg[0x5],end );*/ + break; + + case 0x06: /* Prescale L (ADPCM and Record frq) */ + case 0x07: /* Prescale H */ + break; + + case 0x08: /* ADPCM data */ +/* +some examples: +value: START, REC, MEMDAT, REPEAT, SPOFF, x,x,RESET meaning: + C8 1 1 0 0 1 0 0 0 Analysis (recording) from AUDIO to CPU (to reg $08), sample rate in PRESCALER register + E8 1 1 1 0 1 0 0 0 Analysis (recording) from AUDIO to EXT.MEMORY, sample rate in PRESCALER register + 80 1 0 0 0 0 0 0 0 Synthesis (playing) from CPU (from reg $08) to AUDIO,sample rate in DELTA-N register + a0 1 0 1 0 0 0 0 0 Synthesis (playing) from EXT.MEMORY to AUDIO, sample rate in DELTA-N register + + 60 0 1 1 0 0 0 0 0 External memory write via ADPCM data register $08 + 20 0 0 1 0 0 0 0 0 External memory read via ADPCM data register $08 + +*/ + + /* external memory write */ + if ((portstate & 0xe0) == 0x60) + { + if (memread) + { + now_addr = start << 1; + memread = 0; + } + + /*logerror("YM Delta-T memory write $%08x, v=$%02x\n", now_addr >> 1, v);*/ + + if (now_addr != (end << 1)) + { + memory[now_addr >> 1] = v; + now_addr += 2; /* two nybbles at a time */ + + /* reset BRDY bit in status register, which means we are processing the write */ + if (status_reset_handler && status_change_BRDY_bit) + (status_reset_handler)(status_change_which_chip, status_change_BRDY_bit); + + /* setup a timer that will callback us in 10 master clock cycles for Y8950 + * in the callback set the BRDY flag to 1 , which means we have written the data. + * For now, we don't really do this; we simply reset and set the flag in zero time, so that the IRQ will work. + */ + /* set BRDY bit in status register */ + if (status_set_handler && status_change_BRDY_bit) + (status_set_handler)(status_change_which_chip, status_change_BRDY_bit); + + } + else + { + /* set EOS bit in status register */ + if (status_set_handler && status_change_EOS_bit) + (status_set_handler)(status_change_which_chip, status_change_EOS_bit); + } + + return; + } + + /* ADPCM synthesis from CPU */ + if ((portstate & 0xe0) == 0x80) + { + CPU_data = v; + + /* Reset BRDY bit in status register, which means we are full of data */ + if (status_reset_handler && status_change_BRDY_bit) + (status_reset_handler)(status_change_which_chip, status_change_BRDY_bit); + return; + } + + break; + + case 0x09: /* DELTA-N L (ADPCM Playback Prescaler) */ + case 0x0a: /* DELTA-N H */ + delta = (reg[0xa] * 0x0100 | reg[0x9]); + step = uint32_t(double(delta /* *(1<<(YM_DELTAT_SHIFT-16)) */) * freqbase); + /*logerror("DELTAT deltan:09=%2x 0a=%2x\n",reg[0x9], reg[0xa]);*/ + break; + + case 0x0b: /* Output level control (volume, linear) */ + { + const int32_t oldvol = volume; + volume = (v & 0xff) * (output_range / 256) / YM_DELTAT_DECODE_RANGE; +/* v * ((1<<16)>>8) >> 15; +* thus: v * (1<<8) >> 15; +* thus: output_range must be (1 << (15+8)) at least +* v * ((1<<23)>>8) >> 15; +* v * (1<<15) >> 15; +*/ + /*logerror("DELTAT vol = %2x\n",v&0xff);*/ + if (oldvol != 0) + { + adpcml = int(double(adpcml) / double(oldvol) * double(volume)); + } + } + break; + + case 0x0c: /* Limit Address L */ + case 0x0d: /* Limit Address H */ + limit = (reg[0xd] * 0x0100 | reg[0xc]) << (portshift - DRAMportshift); + /*logerror("DELTAT limit: 0c=%2x 0d=%2x addr=%8x\n",reg[0xc], reg[0xd],limit );*/ + break; + } +} + +void YM_DELTAT::ADPCM_Reset(int panidx, int mode, device_t *dev) +{ + device = dev; + now_addr = 0; + now_step = 0; + step = 0; + start = 0; + end = 0; + limit = ~0; /* this way YM2610 and Y8950 (both of which don't have limit address reg) will still work */ + volume = 0; + pan = &output_pointer[panidx]; + acc = 0; + prev_acc = 0; + adpcmd = 127; + adpcml = 0; + emulation_mode = uint8_t(mode); + portstate = (emulation_mode == EMULATION_MODE_YM2610) ? 0x20 : 0; + control2 = (emulation_mode == EMULATION_MODE_YM2610) ? 0x01 : 0; /* default setting depends on the emulation mode. MSX demo called "facdemo_4" doesn't setup control2 register at all and still works */ + DRAMportshift = dram_rightshift[control2 & 3]; + + /* The flag mask register disables the BRDY after the reset, however + ** as soon as the mask is enabled the flag needs to be set. */ + + /* set BRDY bit in status register */ + if (status_set_handler && status_change_BRDY_bit) + (status_set_handler)(status_change_which_chip, status_change_BRDY_bit); +} + +void YM_DELTAT::postload(uint8_t *regs) +{ + /* to keep adpcml */ + volume = 0; + /* update */ + for (int r = 1; r < 16; r++) + ADPCM_Write(r, regs[r]); + reg[0] = regs[0]; + + /* current rom data */ + if (memory) + now_data = *(memory + (now_addr >> 1)); + +} +void YM_DELTAT::savestate(device_t *device) +{ +#ifdef MAME_EMU_SAVE_H + YM_DELTAT *const DELTAT = this; // makes the save name sensible + device->save_item(NAME(DELTAT->portstate)); + device->save_item(NAME(DELTAT->now_addr)); + device->save_item(NAME(DELTAT->now_step)); + device->save_item(NAME(DELTAT->acc)); + device->save_item(NAME(DELTAT->prev_acc)); + device->save_item(NAME(DELTAT->adpcmd)); + device->save_item(NAME(DELTAT->adpcml)); +#endif +} + + +#define YM_DELTAT_Limit(val,max,min) \ +{ \ + if ( val > max ) val = max; \ + else if ( val < min ) val = min; \ +} + +static inline void YM_DELTAT_synthesis_from_external_memory(YM_DELTAT *DELTAT) +{ + uint32_t step; + int data; + + DELTAT->now_step += DELTAT->step; + if ( DELTAT->now_step >= (1<now_step >> YM_DELTAT_SHIFT; + DELTAT->now_step &= (1<now_addr == (DELTAT->limit<<1) ) + DELTAT->now_addr = 0; + + if ( DELTAT->now_addr == (DELTAT->end<<1) ) { /* 12-06-2001 JB: corrected comparison. Was > instead of == */ + if( DELTAT->portstate&0x10 ){ + /* repeat start */ + DELTAT->now_addr = DELTAT->start<<1; + DELTAT->acc = 0; + DELTAT->adpcmd = YM_DELTAT_DELTA_DEF; + DELTAT->prev_acc = 0; + }else{ + /* set EOS bit in status register */ + if(DELTAT->status_set_handler) + if(DELTAT->status_change_EOS_bit) + (DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_EOS_bit); + + /* clear PCM BUSY bit (reflected in status register) */ + DELTAT->PCM_BSY = 0; + + DELTAT->portstate = 0; + DELTAT->adpcml = 0; + DELTAT->prev_acc = 0; + return; + } + } + + if( DELTAT->now_addr&1 ) data = DELTAT->now_data & 0x0f; + else + { + DELTAT->now_data = *(DELTAT->memory + (DELTAT->now_addr>>1)); + data = DELTAT->now_data >> 4; + } + + DELTAT->now_addr++; + /* 12-06-2001 JB: */ + /* YM2610 address register is 24 bits wide.*/ + /* The "+1" is there because we use 1 bit more for nibble calculations.*/ + /* WARNING: */ + /* Side effect: we should take the size of the mapped ROM into account */ + DELTAT->now_addr &= ( (1<<(24+1))-1); + + /* store accumulator value */ + DELTAT->prev_acc = DELTAT->acc; + + /* Forecast to next Forecast */ + DELTAT->acc += (ym_deltat_decode_tableB1[data] * DELTAT->adpcmd / 8); + YM_DELTAT_Limit(DELTAT->acc,YM_DELTAT_DECODE_MAX, YM_DELTAT_DECODE_MIN); + + /* delta to next delta */ + DELTAT->adpcmd = (DELTAT->adpcmd * ym_deltat_decode_tableB2[data] ) / 64; + YM_DELTAT_Limit(DELTAT->adpcmd,YM_DELTAT_DELTA_MAX, YM_DELTAT_DELTA_MIN ); + + /* ElSemi: Fix interpolator. */ + /*DELTAT->prev_acc = prev_acc + ((DELTAT->acc - prev_acc) / 2 );*/ + + }while(--step); + + } + + /* ElSemi: Fix interpolator. */ + DELTAT->adpcml = DELTAT->prev_acc * (int)((1<now_step); + DELTAT->adpcml += (DELTAT->acc * (int)DELTAT->now_step); + DELTAT->adpcml = (DELTAT->adpcml>>YM_DELTAT_SHIFT) * (int)DELTAT->volume; + + /* output for work of output channels (outd[OPNxxxx])*/ + *(DELTAT->pan) += DELTAT->adpcml; +} + + + +static inline void YM_DELTAT_synthesis_from_CPU_memory(YM_DELTAT *DELTAT) +{ + uint32_t step; + int data; + + DELTAT->now_step += DELTAT->step; + if ( DELTAT->now_step >= (1<now_step >> YM_DELTAT_SHIFT; + DELTAT->now_step &= (1<now_addr&1 ) + { + data = DELTAT->now_data & 0x0f; + + DELTAT->now_data = DELTAT->CPU_data; + + /* after we used CPU_data, we set BRDY bit in status register, + * which means we are ready to accept another byte of data */ + if(DELTAT->status_set_handler) + if(DELTAT->status_change_BRDY_bit) + (DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit); + } + else + { + data = DELTAT->now_data >> 4; + } + + DELTAT->now_addr++; + + /* store accumulator value */ + DELTAT->prev_acc = DELTAT->acc; + + /* Forecast to next Forecast */ + DELTAT->acc += (ym_deltat_decode_tableB1[data] * DELTAT->adpcmd / 8); + YM_DELTAT_Limit(DELTAT->acc,YM_DELTAT_DECODE_MAX, YM_DELTAT_DECODE_MIN); + + /* delta to next delta */ + DELTAT->adpcmd = (DELTAT->adpcmd * ym_deltat_decode_tableB2[data] ) / 64; + YM_DELTAT_Limit(DELTAT->adpcmd,YM_DELTAT_DELTA_MAX, YM_DELTAT_DELTA_MIN ); + + + }while(--step); + + } + + /* ElSemi: Fix interpolator. */ + DELTAT->adpcml = DELTAT->prev_acc * (int)((1<now_step); + DELTAT->adpcml += (DELTAT->acc * (int)DELTAT->now_step); + DELTAT->adpcml = (DELTAT->adpcml>>YM_DELTAT_SHIFT) * (int)DELTAT->volume; + + /* output for work of output channels (outd[OPNxxxx])*/ + *(DELTAT->pan) += DELTAT->adpcml; +} + + + +/* ADPCM B (Delta-T control type) */ +void YM_DELTAT::ADPCM_CALC() +{ +/* +some examples: +value: START, REC, MEMDAT, REPEAT, SPOFF, x,x,RESET meaning: + 80 1 0 0 0 0 0 0 0 Synthesis (playing) from CPU (from reg $08) to AUDIO,sample rate in DELTA-N register + a0 1 0 1 0 0 0 0 0 Synthesis (playing) from EXT.MEMORY to AUDIO, sample rate in DELTA-N register + C8 1 1 0 0 1 0 0 0 Analysis (recording) from AUDIO to CPU (to reg $08), sample rate in PRESCALER register + E8 1 1 1 0 1 0 0 0 Analysis (recording) from AUDIO to EXT.MEMORY, sample rate in PRESCALER register + + 60 0 1 1 0 0 0 0 0 External memory write via ADPCM data register $08 + 20 0 0 1 0 0 0 0 0 External memory read via ADPCM data register $08 + +*/ + + if ( (portstate & 0xe0)==0xa0 ) + { + YM_DELTAT_synthesis_from_external_memory(this); + return; + } + + if ( (portstate & 0xe0)==0x80 ) + { + /* ADPCM synthesis from CPU-managed memory (from reg $08) */ + YM_DELTAT_synthesis_from_CPU_memory(this); /* change output based on data in ADPCM data reg ($08) */ + return; + } + +//todo: ADPCM analysis +// if ( (portstate & 0xe0)==0xc0 ) +// if ( (portstate & 0xe0)==0xe0 ) + + return; +} diff --git a/src/hardware/mame/ymdeltat.h b/src/hardware/mame/ymdeltat.h new file mode 100644 index 00000000..f52bd46f --- /dev/null +++ b/src/hardware/mame/ymdeltat.h @@ -0,0 +1,85 @@ +// license:GPL-2.0+ +// copyright-holders:Jarek Burczynski +#ifndef MAME_SOUND_YMDELTAT_H +#define MAME_SOUND_YMDELTAT_H + +#pragma once + + +typedef void (*STATUS_CHANGE_HANDLER)(void *chip, uint8_t status_bits); + + +/* DELTA-T (adpcm type B) struct */ +struct YM_DELTAT { /* AT: rearranged and tightened structure */ + static constexpr int EMULATION_MODE_NORMAL = 0; + static constexpr int EMULATION_MODE_YM2610 = 1; + + uint8_t *memory; + int32_t *output_pointer;/* pointer of output pointers */ + int32_t *pan; /* pan : &output_pointer[pan] */ + double freqbase; +#if 0 + double write_time; /* Y8950: 10 cycles of main clock; YM2608: 20 cycles of main clock */ + double read_time; /* Y8950: 8 cycles of main clock; YM2608: 18 cycles of main clock */ +#endif + uint32_t memory_size; + int output_range; + uint32_t now_addr; /* current address */ + uint32_t now_step; /* correct step */ + uint32_t step; /* step */ + uint32_t start; /* start address */ + uint32_t limit; /* limit address */ + uint32_t end; /* end address */ + uint32_t delta; /* delta scale */ + int32_t volume; /* current volume */ + int32_t acc; /* shift Measurement value*/ + int32_t adpcmd; /* next Forecast */ + int32_t adpcml; /* current value */ + int32_t prev_acc; /* leveling value */ + uint8_t now_data; /* current rom data */ + uint8_t CPU_data; /* current data from reg 08 */ + uint8_t portstate; /* port status */ + uint8_t control2; /* control reg: SAMPLE, DA/AD, RAM TYPE (x8bit / x1bit), ROM/RAM */ + uint8_t portshift; /* address bits shift-left: + ** 8 for YM2610, + ** 5 for Y8950 and YM2608 */ + + uint8_t DRAMportshift; /* address bits shift-right: + ** 0 for ROM and x8bit DRAMs, + ** 3 for x1 DRAMs */ + + uint8_t memread; /* needed for reading/writing external memory */ + + /* handlers and parameters for the status flags support */ + STATUS_CHANGE_HANDLER status_set_handler; + STATUS_CHANGE_HANDLER status_reset_handler; + + /* note that different chips have these flags on different + ** bits of the status register + */ + void * status_change_which_chip; /* this chip id */ + uint8_t status_change_EOS_bit; /* 1 on End Of Sample (record/playback/cycle time of AD/DA converting has passed)*/ + uint8_t status_change_BRDY_bit; /* 1 after recording 2 datas (2x4bits) or after reading/writing 1 data */ + uint8_t status_change_ZERO_bit; /* 1 if silence lasts for more than 290 milliseconds on ADPCM recording */ + + /* neither Y8950 nor YM2608 can generate IRQ when PCMBSY bit changes, so instead of above, + ** the statusflag gets ORed with PCM_BSY (below) (on each read of statusflag of Y8950 and YM2608) + */ + uint8_t PCM_BSY; /* 1 when ADPCM is playing; Y8950/YM2608 only */ + + uint8_t reg[16]; /* adpcm registers */ + uint8_t emulation_mode; /* which chip we're emulating */ + device_t *device; + + /*void BRDY_callback();*/ + + uint8_t ADPCM_Read(); + void ADPCM_Write(int r, int v); + void ADPCM_Reset(int panidx, int mode, device_t *dev); + void ADPCM_CALC(); + + void postload(uint8_t *regs); + void savestate(device_t *device); +}; + +#endif // MAME_SOUND_YMDELTAT_H diff --git a/src/hardware/mame/ymf262.cpp b/src/hardware/mame/ymf262.cpp new file mode 100644 index 00000000..f69c15da --- /dev/null +++ b/src/hardware/mame/ymf262.cpp @@ -0,0 +1,2788 @@ +// license:GPL-2.0+ +// copyright-holders:Jarek Burczynski +/* +** +** File: ymf262.c - software implementation of YMF262 +** FM sound generator type OPL3 +** +** Copyright Jarek Burczynski +** +** Version 0.2 +** + +Revision History: + +03-03-2003: initial release + - thanks to Olivier Galibert and Chris Hardy for YMF262 and YAC512 chips + - thanks to Stiletto for the datasheets + + Features as listed in 4MF262A6 data sheet: + 1. Registers are compatible with YM3812 (OPL2) FM sound source. + 2. Up to six sounds can be used as four-operator melody sounds for variety. + 3. 18 simultaneous melody sounds, or 15 melody sounds with 5 rhythm sounds (with two operators). + 4. 6 four-operator melody sounds and 6 two-operator melody sounds, or 6 four-operator melody + sounds, 3 two-operator melody sounds and 5 rhythm sounds (with four operators). + 5. 8 selectable waveforms. + 6. 4-channel sound output. + 7. YMF262 compabile DAC (YAC512) is available. + 8. LFO for vibrato and tremolo effedts. + 9. 2 programable timers. + 10. Shorter register access time compared with YM3812. + 11. 5V single supply silicon gate CMOS process. + 12. 24 Pin SOP Package (YMF262-M), 48 Pin SQFP Package (YMF262-S). + + +differences between OPL2 and OPL3 not documented in Yamaha datahasheets: +- sinus table is a little different: the negative part is off by one... + +- in order to enable selection of four different waveforms on OPL2 + one must set bit 5 in register 0x01(test). + on OPL3 this bit is ignored and 4-waveform select works *always*. + (Don't confuse this with OPL3's 8-waveform select.) + +- Envelope Generator: all 15 x rates take zero time on OPL3 + (on OPL2 15 0 and 15 1 rates take some time while 15 2 and 15 3 rates + take zero time) + +- channel calculations: output of operator 1 is in perfect sync with + output of operator 2 on OPL3; on OPL and OPL2 output of operator 1 + is always delayed by one sample compared to output of operator 2 + + +differences between OPL2 and OPL3 shown in datasheets: +- YMF262 does not support CSM mode + + +*/ + +#include "emu.h" +#include "ymf262.h" + + +/* output final shift */ +#if (OPL3_SAMPLE_BITS==16) + #define FINAL_SH (0) + #define MAXOUT (+32767) + #define MINOUT (-32768) +#else + #define FINAL_SH (8) + #define MAXOUT (+127) + #define MINOUT (-128) +#endif + + +#define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */ +#define EG_SH 16 /* 16.16 fixed point (EG timing) */ +#define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */ +#define TIMER_SH 16 /* 16.16 fixed point (timers calculations) */ + +#define FREQ_MASK ((1<>8)&0xff,sample[0]); \ + } + #else /*save to STEREO file */ + #define SAVE_ALL_CHANNELS \ + { signed int pom = a; \ + fputc((unsigned short)pom&0xff,sample[0]); \ + fputc(((unsigned short)pom>>8)&0xff,sample[0]); \ + pom = b; \ + fputc((unsigned short)pom&0xff,sample[0]); \ + fputc(((unsigned short)pom>>8)&0xff,sample[0]); \ + } + #endif +#endif + + +#define OPL3_TYPE_YMF262 (0) /* 36 operators, 8 waveforms */ + + +struct OPL3_SLOT +{ + uint32_t ar; /* attack rate: AR<<2 */ + uint32_t dr; /* decay rate: DR<<2 */ + uint32_t rr; /* release rate:RR<<2 */ + uint8_t KSR; /* key scale rate */ + uint8_t ksl; /* keyscale level */ + uint8_t ksr; /* key scale rate: kcode>>KSR */ + uint8_t mul; /* multiple: mul_tab[ML] */ + + /* Phase Generator */ + uint32_t Cnt; /* frequency counter */ + uint32_t Incr; /* frequency counter step */ + uint8_t FB; /* feedback shift value */ + uint8_t conn_enum; /* slot output route */ + int32_t *connect; /* slot output pointer */ + int32_t op1_out[2]; /* slot1 output for feedback */ + uint8_t CON; /* connection (algorithm) type */ + + /* Envelope Generator */ + uint8_t eg_type; /* percussive/non-percussive mode */ + uint8_t state; /* phase type */ + uint32_t TL; /* total level: TL << 2 */ + int32_t TLL; /* adjusted now TL */ + int32_t volume; /* envelope counter */ + uint32_t sl; /* sustain level: sl_tab[SL] */ + + uint32_t eg_m_ar; /* (attack state) */ + uint8_t eg_sh_ar; /* (attack state) */ + uint8_t eg_sel_ar; /* (attack state) */ + uint32_t eg_m_dr; /* (decay state) */ + uint8_t eg_sh_dr; /* (decay state) */ + uint8_t eg_sel_dr; /* (decay state) */ + uint32_t eg_m_rr; /* (release state) */ + uint8_t eg_sh_rr; /* (release state) */ + uint8_t eg_sel_rr; /* (release state) */ + + uint32_t key; /* 0 = KEY OFF, >0 = KEY ON */ + + /* LFO */ + uint32_t AMmask; /* LFO Amplitude Modulation enable mask */ + uint8_t vib; /* LFO Phase Modulation enable flag (active high)*/ + + /* waveform select */ + uint8_t waveform_number; + unsigned int wavetable; + + //unsigned char reserved[128-84];//speedup: pump up the struct size to power of 2 + unsigned char reserved[128-100];//speedup: pump up the struct size to power of 2 + +}; + +struct OPL3_CH +{ + OPL3_SLOT SLOT[2]; + + uint32_t block_fnum; /* block+fnum */ + uint32_t fc; /* Freq. Increment base */ + uint32_t ksl_base; /* KeyScaleLevel Base step */ + uint8_t kcode; /* key code (for key scaling) */ + + /* + there are 12 2-operator channels which can be combined in pairs + to form six 4-operator channel, they are: + 0 and 3, + 1 and 4, + 2 and 5, + 9 and 12, + 10 and 13, + 11 and 14 + */ + uint8_t extended; /* set to 1 if this channel forms up a 4op channel with another channel(only used by first of pair of channels, ie 0,1,2 and 9,10,11) */ + + unsigned char reserved[512-272];//speedup:pump up the struct size to power of 2 + +}; + +/* OPL3 state */ +struct OPL3 +{ + OPL3_CH P_CH[18]; /* OPL3 chips have 18 channels */ + + uint32_t pan[18*4]; /* channels output masks (0xffffffff = enable); 4 masks per one channel */ + uint32_t pan_ctrl_value[18]; /* output control values 1 per one channel (1 value contains 4 masks) */ + + signed int chanout[18]; + signed int phase_modulation; /* phase modulation input (SLOT 2) */ + signed int phase_modulation2; /* phase modulation input (SLOT 3 in 4 operator channels) */ + + uint32_t eg_cnt; /* global envelope generator counter */ + uint32_t eg_timer; /* global envelope generator counter works at frequency = chipclock/288 (288=8*36) */ + uint32_t eg_timer_add; /* step of eg_timer */ + uint32_t eg_timer_overflow; /* envelope generator timer overflows every 1 sample (on real chip) */ + + uint32_t fn_tab[1024]; /* fnumber->increment counter */ + + /* LFO */ + uint32_t LFO_AM; + int32_t LFO_PM; + + uint8_t lfo_am_depth; + uint8_t lfo_pm_depth_range; + uint32_t lfo_am_cnt; + uint32_t lfo_am_inc; + uint32_t lfo_pm_cnt; + uint32_t lfo_pm_inc; + + uint32_t noise_rng; /* 23 bit noise shift register */ + uint32_t noise_p; /* current noise 'phase' */ + uint32_t noise_f; /* current noise period */ + + uint8_t OPL3_mode; /* OPL3 extension enable flag */ + + uint8_t rhythm; /* Rhythm mode */ + + int T[2]; /* timer counters */ + uint8_t st[2]; /* timer enable */ + + uint32_t address; /* address register */ + uint8_t status; /* status flag */ + uint8_t statusmask; /* status mask */ + + uint8_t nts; /* NTS (note select) */ + + /* external event callback handlers */ + OPL3_TIMERHANDLER timer_handler; + device_t *TimerParam; + OPL3_IRQHANDLER IRQHandler; + device_t *IRQParam; + OPL3_UPDATEHANDLER UpdateHandler; + device_t *UpdateParam; + + uint8_t type; /* chip type */ + int clock; /* master clock (Hz) */ + int rate; /* sampling rate (Hz) */ + double freqbase; /* frequency base */ + attotime TimerBase; /* Timer base time (==sampling time)*/ + device_t *device; + + /* Optional handlers */ + void SetTimerHandler(OPL3_TIMERHANDLER handler, device_t *device) + { + timer_handler = handler; + TimerParam = device; + } + void SetIRQHandler(OPL3_IRQHANDLER handler, device_t *device) + { + IRQHandler = handler; + IRQParam = device; + } + void SetUpdateHandler(OPL3_UPDATEHANDLER handler, device_t *device) + { + UpdateHandler = handler; + UpdateParam = device; + } +}; + +} // anonymous namespace + + + +/* mapping of register number (offset) to slot number used by the emulator */ +static const int slot_array[32]= +{ + 0, 2, 4, 1, 3, 5,-1,-1, + 6, 8,10, 7, 9,11,-1,-1, + 12,14,16,13,15,17,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1 +}; + +/* key scale level */ +/* table is 3dB/octave , DV converts this into 6dB/octave */ +/* 0.1875 is bit 0 weight of the envelope counter (volume) expressed in the 'decibel' scale */ +#define DV (0.1875/2.0) +static const double ksl_tab[8*16]= +{ + /* OCT 0 */ + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + /* OCT 1 */ + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.750/DV, 1.125/DV, 1.500/DV, + 1.875/DV, 2.250/DV, 2.625/DV, 3.000/DV, + /* OCT 2 */ + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 1.125/DV, 1.875/DV, 2.625/DV, + 3.000/DV, 3.750/DV, 4.125/DV, 4.500/DV, + 4.875/DV, 5.250/DV, 5.625/DV, 6.000/DV, + /* OCT 3 */ + 0.000/DV, 0.000/DV, 0.000/DV, 1.875/DV, + 3.000/DV, 4.125/DV, 4.875/DV, 5.625/DV, + 6.000/DV, 6.750/DV, 7.125/DV, 7.500/DV, + 7.875/DV, 8.250/DV, 8.625/DV, 9.000/DV, + /* OCT 4 */ + 0.000/DV, 0.000/DV, 3.000/DV, 4.875/DV, + 6.000/DV, 7.125/DV, 7.875/DV, 8.625/DV, + 9.000/DV, 9.750/DV,10.125/DV,10.500/DV, + 10.875/DV,11.250/DV,11.625/DV,12.000/DV, + /* OCT 5 */ + 0.000/DV, 3.000/DV, 6.000/DV, 7.875/DV, + 9.000/DV,10.125/DV,10.875/DV,11.625/DV, + 12.000/DV,12.750/DV,13.125/DV,13.500/DV, + 13.875/DV,14.250/DV,14.625/DV,15.000/DV, + /* OCT 6 */ + 0.000/DV, 6.000/DV, 9.000/DV,10.875/DV, + 12.000/DV,13.125/DV,13.875/DV,14.625/DV, + 15.000/DV,15.750/DV,16.125/DV,16.500/DV, + 16.875/DV,17.250/DV,17.625/DV,18.000/DV, + /* OCT 7 */ + 0.000/DV, 9.000/DV,12.000/DV,13.875/DV, + 15.000/DV,16.125/DV,16.875/DV,17.625/DV, + 18.000/DV,18.750/DV,19.125/DV,19.500/DV, + 19.875/DV,20.250/DV,20.625/DV,21.000/DV +}; +#undef DV + +/* 0 / 3.0 / 1.5 / 6.0 dB/OCT */ +static const uint32_t ksl_shift[4] = { 31, 1, 2, 0 }; + + +/* sustain level table (3dB per step) */ +/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ +#define SC(db) (uint32_t) ( db * (2.0/ENV_STEP) ) +static const uint32_t sl_tab[16]={ + SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7), + SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31) +}; +#undef SC + + +#define RATE_STEPS (8) +static const unsigned char eg_inc[15*RATE_STEPS]={ +/*cycle:0 1 2 3 4 5 6 7*/ + +/* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..12 0 (increment by 0 or 1) */ +/* 1 */ 0,1, 0,1, 1,1, 0,1, /* rates 00..12 1 */ +/* 2 */ 0,1, 1,1, 0,1, 1,1, /* rates 00..12 2 */ +/* 3 */ 0,1, 1,1, 1,1, 1,1, /* rates 00..12 3 */ + +/* 4 */ 1,1, 1,1, 1,1, 1,1, /* rate 13 0 (increment by 1) */ +/* 5 */ 1,1, 1,2, 1,1, 1,2, /* rate 13 1 */ +/* 6 */ 1,2, 1,2, 1,2, 1,2, /* rate 13 2 */ +/* 7 */ 1,2, 2,2, 1,2, 2,2, /* rate 13 3 */ + +/* 8 */ 2,2, 2,2, 2,2, 2,2, /* rate 14 0 (increment by 2) */ +/* 9 */ 2,2, 2,4, 2,2, 2,4, /* rate 14 1 */ +/*10 */ 2,4, 2,4, 2,4, 2,4, /* rate 14 2 */ +/*11 */ 2,4, 4,4, 2,4, 4,4, /* rate 14 3 */ + +/*12 */ 4,4, 4,4, 4,4, 4,4, /* rates 15 0, 15 1, 15 2, 15 3 for decay */ +/*13 */ 8,8, 8,8, 8,8, 8,8, /* rates 15 0, 15 1, 15 2, 15 3 for attack (zero time) */ +/*14 */ 0,0, 0,0, 0,0, 0,0, /* infinity rates for attack and decay(s) */ +}; + + +#define O(a) (a*RATE_STEPS) + +/* note that there is no O(13) in this table - it's directly in the code */ +static const unsigned char eg_rate_select[16+64+16]={ /* Envelope Generator rates (16 + 64 rates + 16 RKS) */ +/* 16 infinite time rates */ +O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), +O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), + +/* rates 00-12 */ +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), + +/* rate 13 */ +O( 4),O( 5),O( 6),O( 7), + +/* rate 14 */ +O( 8),O( 9),O(10),O(11), + +/* rate 15 */ +O(12),O(12),O(12),O(12), + +/* 16 dummy rates (same as 15 3) */ +O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12), +O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12), + +}; +#undef O + +/*rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 */ +/*shift 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0 */ +/*mask 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0, 0 */ + +#define O(a) (a*1) +static const unsigned char eg_rate_shift[16+64+16]={ /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */ +/* 16 infinite time rates */ +O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), +O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), + +/* rates 00-12 */ +O(12),O(12),O(12),O(12), +O(11),O(11),O(11),O(11), +O(10),O(10),O(10),O(10), +O( 9),O( 9),O( 9),O( 9), +O( 8),O( 8),O( 8),O( 8), +O( 7),O( 7),O( 7),O( 7), +O( 6),O( 6),O( 6),O( 6), +O( 5),O( 5),O( 5),O( 5), +O( 4),O( 4),O( 4),O( 4), +O( 3),O( 3),O( 3),O( 3), +O( 2),O( 2),O( 2),O( 2), +O( 1),O( 1),O( 1),O( 1), +O( 0),O( 0),O( 0),O( 0), + +/* rate 13 */ +O( 0),O( 0),O( 0),O( 0), + +/* rate 14 */ +O( 0),O( 0),O( 0),O( 0), + +/* rate 15 */ +O( 0),O( 0),O( 0),O( 0), + +/* 16 dummy rates (same as 15 3) */ +O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), +O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), + +}; +#undef O + + +/* multiple table */ +#define ML 2 +static const uint8_t mul_tab[16]= { +/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,10,12,12,15,15 */ + ML/2, 1*ML, 2*ML, 3*ML, 4*ML, 5*ML, 6*ML, 7*ML, + 8*ML, 9*ML,10*ML,10*ML,12*ML,12*ML,15*ML,15*ML +}; +#undef ML + +/* TL_TAB_LEN is calculated as: + +* (12+1)=13 - sinus amplitude bits (Y axis) +* additional 1: to compensate for calculations of negative part of waveform +* (if we don't add it then the greatest possible _negative_ value would be -2 +* and we really need -1 for waveform #7) +* 2 - sinus sign bit (Y axis) +* TL_RES_LEN - sinus resolution (X axis) +*/ +#define TL_TAB_LEN (13*2*TL_RES_LEN) +static signed int tl_tab[TL_TAB_LEN]; + +#define ENV_QUIET (TL_TAB_LEN>>4) + +/* sin waveform table in 'decibel' scale */ +/* there are eight waveforms on OPL3 chips */ +static unsigned int sin_tab[SIN_LEN * 8]; + + +/* LFO Amplitude Modulation table (verified on real YM3812) + 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples + + Length: 210 elements. + + Each of the elements has to be repeated + exactly 64 times (on 64 consecutive samples). + The whole table takes: 64 * 210 = 13440 samples. + + When AM = 1 data is used directly + When AM = 0 data is divided by 4 before being used (losing precision is important) +*/ + +#define LFO_AM_TAB_ELEMENTS 210 + +static const uint8_t lfo_am_table[LFO_AM_TAB_ELEMENTS] = { +0,0,0,0,0,0,0, +1,1,1,1, +2,2,2,2, +3,3,3,3, +4,4,4,4, +5,5,5,5, +6,6,6,6, +7,7,7,7, +8,8,8,8, +9,9,9,9, +10,10,10,10, +11,11,11,11, +12,12,12,12, +13,13,13,13, +14,14,14,14, +15,15,15,15, +16,16,16,16, +17,17,17,17, +18,18,18,18, +19,19,19,19, +20,20,20,20, +21,21,21,21, +22,22,22,22, +23,23,23,23, +24,24,24,24, +25,25,25,25, +26,26,26, +25,25,25,25, +24,24,24,24, +23,23,23,23, +22,22,22,22, +21,21,21,21, +20,20,20,20, +19,19,19,19, +18,18,18,18, +17,17,17,17, +16,16,16,16, +15,15,15,15, +14,14,14,14, +13,13,13,13, +12,12,12,12, +11,11,11,11, +10,10,10,10, +9,9,9,9, +8,8,8,8, +7,7,7,7, +6,6,6,6, +5,5,5,5, +4,4,4,4, +3,3,3,3, +2,2,2,2, +1,1,1,1 +}; + +/* LFO Phase Modulation table (verified on real YM3812) */ +static const int8_t lfo_pm_table[8*8*2] = { +/* FNUM2/FNUM = 00 0xxxxxxx (0x0000) */ +0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/ +0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 00 1xxxxxxx (0x0080) */ +0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/ +1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 01 0xxxxxxx (0x0100) */ +1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/ +2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 01 1xxxxxxx (0x0180) */ +1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/ +3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 10 0xxxxxxx (0x0200) */ +2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/ +4, 2, 0,-2,-4,-2, 0, 2, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 10 1xxxxxxx (0x0280) */ +2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/ +5, 2, 0,-2,-5,-2, 0, 2, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 11 0xxxxxxx (0x0300) */ +3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/ +6, 3, 0,-3,-6,-3, 0, 3, /*LFO PM depth = 1*/ + +/* FNUM2/FNUM = 11 1xxxxxxx (0x0380) */ +3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/ +7, 3, 0,-3,-7,-3, 0, 3 /*LFO PM depth = 1*/ +}; + + +/* lock level of common table */ +static int num_lock = 0; + +/* work table */ +#define SLOT7_1 (&chip->P_CH[7].SLOT[SLOT1]) +#define SLOT7_2 (&chip->P_CH[7].SLOT[SLOT2]) +#define SLOT8_1 (&chip->P_CH[8].SLOT[SLOT1]) +#define SLOT8_2 (&chip->P_CH[8].SLOT[SLOT2]) + + +static inline void OPL3_SLOT_CONNECT(OPL3 *chip, OPL3_SLOT *slot) { + if (slot->conn_enum == CONN_NULL) { + slot->connect = nullptr; + } else if (slot->conn_enum >= CONN_CHAN0 && slot->conn_enum < CONN_PHASEMOD) { + slot->connect = &chip->chanout[slot->conn_enum]; + } else if (slot->conn_enum == CONN_PHASEMOD) { + slot->connect = &chip->phase_modulation; + } else if (slot->conn_enum == CONN_PHASEMOD2) { + slot->connect = &chip->phase_modulation2; + } +} + +static inline int limit( int val, int max, int min ) { + if ( val > max ) + val = max; + else if ( val < min ) + val = min; + + return val; +} + + +/* status set and IRQ handling */ +static inline void OPL3_STATUS_SET(OPL3 *chip,int flag) +{ + /* set status flag masking out disabled IRQs */ + chip->status |= (flag & chip->statusmask); + if(!(chip->status & 0x80)) + { + if(chip->status & 0x7f) + { /* IRQ on */ + chip->status |= 0x80; + /* callback user interrupt handler (IRQ is OFF to ON) */ + if(chip->IRQHandler) (chip->IRQHandler)(chip->IRQParam,1); + } + } +} + +/* status reset and IRQ handling */ +static inline void OPL3_STATUS_RESET(OPL3 *chip,int flag) +{ + /* reset status flag */ + chip->status &= ~flag; + if(chip->status & 0x80) + { + if (!(chip->status & 0x7f)) + { + chip->status &= 0x7f; + /* callback user interrupt handler (IRQ is ON to OFF) */ + if(chip->IRQHandler) (chip->IRQHandler)(chip->IRQParam,0); + } + } +} + +/* IRQ mask set */ +static inline void OPL3_STATUSMASK_SET(OPL3 *chip,int flag) +{ + chip->statusmask = flag; + /* IRQ handling check */ + OPL3_STATUS_SET(chip,0); + OPL3_STATUS_RESET(chip,0); +} + + +/* advance LFO to next sample */ +static inline void advance_lfo(OPL3 *chip) +{ + uint8_t tmp; + + /* LFO */ + chip->lfo_am_cnt += chip->lfo_am_inc; + if (chip->lfo_am_cnt >= ((uint32_t)LFO_AM_TAB_ELEMENTS<lfo_am_cnt -= ((uint32_t)LFO_AM_TAB_ELEMENTS<lfo_am_cnt >> LFO_SH ]; + + if (chip->lfo_am_depth) + chip->LFO_AM = tmp; + else + chip->LFO_AM = tmp>>2; + + chip->lfo_pm_cnt += chip->lfo_pm_inc; + chip->LFO_PM = ((chip->lfo_pm_cnt>>LFO_SH) & 7) | chip->lfo_pm_depth_range; +} + +/* advance to next sample */ +static inline void advance(OPL3 *chip) +{ + OPL3_CH *CH; + OPL3_SLOT *op; + int i; + + chip->eg_timer += chip->eg_timer_add; + + while (chip->eg_timer >= chip->eg_timer_overflow) + { + chip->eg_timer -= chip->eg_timer_overflow; + + chip->eg_cnt++; + + for (i=0; i<9*2*2; i++) + { + CH = &chip->P_CH[i/2]; + op = &CH->SLOT[i&1]; +#if 1 + /* Envelope Generator */ + switch(op->state) + { + case EG_ATT: /* attack phase */ +// if ( !(chip->eg_cnt & ((1<eg_sh_ar)-1) ) ) + if ( !(chip->eg_cnt & op->eg_m_ar) ) + { + op->volume += (~op->volume * + (eg_inc[op->eg_sel_ar + ((chip->eg_cnt>>op->eg_sh_ar)&7)]) + ) >>3; + + if (op->volume <= MIN_ATT_INDEX) + { + op->volume = MIN_ATT_INDEX; + op->state = EG_DEC; + } + + } + break; + + case EG_DEC: /* decay phase */ +// if ( !(chip->eg_cnt & ((1<eg_sh_dr)-1) ) ) + if ( !(chip->eg_cnt & op->eg_m_dr) ) + { + op->volume += eg_inc[op->eg_sel_dr + ((chip->eg_cnt>>op->eg_sh_dr)&7)]; + + if ( op->volume >= op->sl ) + op->state = EG_SUS; + + } + break; + + case EG_SUS: /* sustain phase */ + + /* this is important behaviour: + one can change percusive/non-percussive modes on the fly and + the chip will remain in sustain phase - verified on real YM3812 */ + + if(op->eg_type) /* non-percussive mode */ + { + /* do nothing */ + } + else /* percussive mode */ + { + /* during sustain phase chip adds Release Rate (in percussive mode) */ +// if ( !(chip->eg_cnt & ((1<eg_sh_rr)-1) ) ) + if ( !(chip->eg_cnt & op->eg_m_rr) ) + { + op->volume += eg_inc[op->eg_sel_rr + ((chip->eg_cnt>>op->eg_sh_rr)&7)]; + + if ( op->volume >= MAX_ATT_INDEX ) + op->volume = MAX_ATT_INDEX; + } + /* else do nothing in sustain phase */ + } + break; + + case EG_REL: /* release phase */ +// if ( !(chip->eg_cnt & ((1<eg_sh_rr)-1) ) ) + if ( !(chip->eg_cnt & op->eg_m_rr) ) + { + op->volume += eg_inc[op->eg_sel_rr + ((chip->eg_cnt>>op->eg_sh_rr)&7)]; + + if ( op->volume >= MAX_ATT_INDEX ) + { + op->volume = MAX_ATT_INDEX; + op->state = EG_OFF; + } + + } + break; + + default: + break; + } +#endif + } + } + + for (i=0; i<9*2*2; i++) + { + CH = &chip->P_CH[i/2]; + op = &CH->SLOT[i&1]; + + /* Phase Generator */ + if(op->vib) + { + uint8_t block; + unsigned int block_fnum = CH->block_fnum; + + unsigned int fnum_lfo = (block_fnum&0x0380) >> 7; + + signed int lfo_fn_table_index_offset = lfo_pm_table[chip->LFO_PM + 16*fnum_lfo ]; + + if (lfo_fn_table_index_offset) /* LFO phase modulation active */ + { + block_fnum += lfo_fn_table_index_offset; + block = (block_fnum&0x1c00) >> 10; + op->Cnt += (chip->fn_tab[block_fnum&0x03ff] >> (7-block)) * op->mul; + } + else /* LFO phase modulation = zero */ + { + op->Cnt += op->Incr; + } + } + else /* LFO phase modulation disabled for this operator */ + { + op->Cnt += op->Incr; + } + } + + /* The Noise Generator of the YM3812 is 23-bit shift register. + * Period is equal to 2^23-2 samples. + * Register works at sampling frequency of the chip, so output + * can change on every sample. + * + * Output of the register and input to the bit 22 is: + * bit0 XOR bit14 XOR bit15 XOR bit22 + * + * Simply use bit 22 as the noise output. + */ + + chip->noise_p += chip->noise_f; + i = chip->noise_p >> FREQ_SH; /* number of events (shifts of the shift register) */ + chip->noise_p &= FREQ_MASK; + while (i) + { + /* + uint32_t j; + j = ( (chip->noise_rng) ^ (chip->noise_rng>>14) ^ (chip->noise_rng>>15) ^ (chip->noise_rng>>22) ) & 1; + chip->noise_rng = (j<<22) | (chip->noise_rng>>1); + */ + + /* + Instead of doing all the logic operations above, we + use a trick here (and use bit 0 as the noise output). + The difference is only that the noise bit changes one + step ahead. This doesn't matter since we don't know + what is real state of the noise_rng after the reset. + */ + + if (chip->noise_rng & 1) chip->noise_rng ^= 0x800302; + chip->noise_rng >>= 1; + + i--; + } +} + + +static inline signed int op_calc(uint32_t phase, unsigned int env, signed int pm, unsigned int wave_tab) +{ + uint32_t p; + + p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + (pm<<16))) >> FREQ_SH ) & SIN_MASK) ]; + + if (p >= TL_TAB_LEN) + return 0; + return tl_tab[p]; +} + +static inline signed int op_calc1(uint32_t phase, unsigned int env, signed int pm, unsigned int wave_tab) +{ + uint32_t p; + + p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + pm))>>FREQ_SH) & SIN_MASK)]; + + if (p >= TL_TAB_LEN) + return 0; + return tl_tab[p]; +} + + +#define volume_calc(OP) ((OP)->TLL + ((uint32_t)(OP)->volume) + (chip->LFO_AM & (OP)->AMmask)) + +/* calculate output of a standard 2 operator channel + (or 1st part of a 4-op channel) */ +static inline void chan_calc( OPL3 *chip, OPL3_CH *CH ) +{ + OPL3_SLOT *SLOT; + unsigned int env; + signed int out; + + chip->phase_modulation = 0; + chip->phase_modulation2= 0; + + /* SLOT 1 */ + SLOT = &CH->SLOT[SLOT1]; + env = volume_calc(SLOT); + out = SLOT->op1_out[0] + SLOT->op1_out[1]; + SLOT->op1_out[0] = SLOT->op1_out[1]; + SLOT->op1_out[1] = 0; + if (env < ENV_QUIET) + { + if (!SLOT->FB) + out = 0; + SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB), SLOT->wavetable ); + } + if (SLOT->connect) { + *SLOT->connect += SLOT->op1_out[1]; + } +//logerror("out0=%5i vol0=%4i ", SLOT->op1_out[1], env ); + + /* SLOT 2 */ + SLOT++; + env = volume_calc(SLOT); + if ((env < ENV_QUIET) && SLOT->connect) + *SLOT->connect += op_calc(SLOT->Cnt, env, chip->phase_modulation, SLOT->wavetable); + +//logerror("out1=%5i vol1=%4i\n", op_calc(SLOT->Cnt, env, chip->phase_modulation, SLOT->wavetable), env ); + +} + +/* calculate output of a 2nd part of 4-op channel */ +static inline void chan_calc_ext( OPL3 *chip, OPL3_CH *CH ) +{ + OPL3_SLOT *SLOT; + unsigned int env; + + chip->phase_modulation = 0; + + /* SLOT 1 */ + SLOT = &CH->SLOT[SLOT1]; + env = volume_calc(SLOT); + if (env < ENV_QUIET && SLOT->connect) + *SLOT->connect += op_calc(SLOT->Cnt, env, chip->phase_modulation2, SLOT->wavetable ); + + /* SLOT 2 */ + SLOT++; + env = volume_calc(SLOT); + if (env < ENV_QUIET && SLOT->connect) + *SLOT->connect += op_calc(SLOT->Cnt, env, chip->phase_modulation, SLOT->wavetable); + +} + +/* + operators used in the rhythm sounds generation process: + + Envelope Generator: + +channel operator register number Bass High Snare Tom Top +/ slot number TL ARDR SLRR Wave Drum Hat Drum Tom Cymbal + 6 / 0 12 50 70 90 f0 + + 6 / 1 15 53 73 93 f3 + + 7 / 0 13 51 71 91 f1 + + 7 / 1 16 54 74 94 f4 + + 8 / 0 14 52 72 92 f2 + + 8 / 1 17 55 75 95 f5 + + + Phase Generator: + +channel operator register number Bass High Snare Tom Top +/ slot number MULTIPLE Drum Hat Drum Tom Cymbal + 6 / 0 12 30 + + 6 / 1 15 33 + + 7 / 0 13 31 + + + + 7 / 1 16 34 ----- n o t u s e d ----- + 8 / 0 14 32 + + 8 / 1 17 35 + + + +channel operator register number Bass High Snare Tom Top +number number BLK/FNUM2 FNUM Drum Hat Drum Tom Cymbal + 6 12,15 B6 A6 + + + 7 13,16 B7 A7 + + + + + 8 14,17 B8 A8 + + + + +*/ + +/* calculate rhythm */ + +static inline void chan_calc_rhythm( OPL3 *chip, OPL3_CH *CH, unsigned int noise ) +{ + OPL3_SLOT *SLOT; + signed int *chanout = chip->chanout; + signed int out; + unsigned int env; + + + /* Bass Drum (verified on real YM3812): + - depends on the channel 6 'connect' register: + when connect = 0 it works the same as in normal (non-rhythm) mode (op1->op2->out) + when connect = 1 _only_ operator 2 is present on output (op2->out), operator 1 is ignored + - output sample always is multiplied by 2 + */ + + chip->phase_modulation = 0; + + /* SLOT 1 */ + SLOT = &CH[6].SLOT[SLOT1]; + env = volume_calc(SLOT); + + out = SLOT->op1_out[0] + SLOT->op1_out[1]; + SLOT->op1_out[0] = SLOT->op1_out[1]; + + if (!SLOT->CON) + chip->phase_modulation = SLOT->op1_out[0]; + //else ignore output of operator 1 + + SLOT->op1_out[1] = 0; + if( env < ENV_QUIET ) + { + if (!SLOT->FB) + out = 0; + SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB), SLOT->wavetable ); + } + + /* SLOT 2 */ + SLOT++; + env = volume_calc(SLOT); + if( env < ENV_QUIET ) + chanout[6] += op_calc(SLOT->Cnt, env, chip->phase_modulation, SLOT->wavetable) * 2; + + + /* Phase generation is based on: */ + // HH (13) channel 7->slot 1 combined with channel 8->slot 2 (same combination as TOP CYMBAL but different output phases) + // SD (16) channel 7->slot 1 + // TOM (14) channel 8->slot 1 + // TOP (17) channel 7->slot 1 combined with channel 8->slot 2 (same combination as HIGH HAT but different output phases) + + /* Envelope generation based on: */ + // HH channel 7->slot1 + // SD channel 7->slot2 + // TOM channel 8->slot1 + // TOP channel 8->slot2 + + + /* The following formulas can be well optimized. + I leave them in direct form for now (in case I've missed something). + */ + + /* High Hat (verified on real YM3812) */ + env = volume_calc(SLOT7_1); + if( env < ENV_QUIET ) + { + /* high hat phase generation: + phase = d0 or 234 (based on frequency only) + phase = 34 or 2d0 (based on noise) + */ + + /* base frequency derived from operator 1 in channel 7 */ + unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1; + unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1; + unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1; + + unsigned char res1 = (bit2 ^ bit7) | bit3; + + /* when res1 = 0 phase = 0x000 | 0xd0; */ + /* when res1 = 1 phase = 0x200 | (0xd0>>2); */ + uint32_t phase = res1 ? (0x200|(0xd0>>2)) : 0xd0; + + /* enable gate based on frequency of operator 2 in channel 8 */ + unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1; + unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1; + + unsigned char res2 = (bit3e ^ bit5e); + + /* when res2 = 0 pass the phase from calculation above (res1); */ + /* when res2 = 1 phase = 0x200 | (0xd0>>2); */ + if (res2) + phase = (0x200|(0xd0>>2)); + + + /* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */ + /* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */ + if (phase&0x200) + { + if (noise) + phase = 0x200|0xd0; + } + else + /* when phase & 0x200 is clear and noise=1 then phase = 0xd0>>2 */ + /* when phase & 0x200 is clear and noise=0 then phase = 0xd0, ie no change */ + { + if (noise) + phase = 0xd0>>2; + } + + chanout[7] += op_calc(phase<wavetable) * 2; + } + + /* Snare Drum (verified on real YM3812) */ + env = volume_calc(SLOT7_2); + if( env < ENV_QUIET ) + { + /* base frequency derived from operator 1 in channel 7 */ + unsigned char bit8 = ((SLOT7_1->Cnt>>FREQ_SH)>>8)&1; + + /* when bit8 = 0 phase = 0x100; */ + /* when bit8 = 1 phase = 0x200; */ + uint32_t phase = bit8 ? 0x200 : 0x100; + + /* Noise bit XOR'es phase by 0x100 */ + /* when noisebit = 0 pass the phase from calculation above */ + /* when noisebit = 1 phase ^= 0x100; */ + /* in other words: phase ^= (noisebit<<8); */ + if (noise) + phase ^= 0x100; + + chanout[7] += op_calc(phase<wavetable) * 2; + } + + /* Tom Tom (verified on real YM3812) */ + env = volume_calc(SLOT8_1); + if( env < ENV_QUIET ) + chanout[8] += op_calc(SLOT8_1->Cnt, env, 0, SLOT8_1->wavetable) * 2; + + /* Top Cymbal (verified on real YM3812) */ + env = volume_calc(SLOT8_2); + if( env < ENV_QUIET ) + { + /* base frequency derived from operator 1 in channel 7 */ + unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1; + unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1; + unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1; + + unsigned char res1 = (bit2 ^ bit7) | bit3; + + /* when res1 = 0 phase = 0x000 | 0x100; */ + /* when res1 = 1 phase = 0x200 | 0x100; */ + uint32_t phase = res1 ? 0x300 : 0x100; + + /* enable gate based on frequency of operator 2 in channel 8 */ + unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1; + unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1; + + unsigned char res2 = (bit3e ^ bit5e); + /* when res2 = 0 pass the phase from calculation above (res1); */ + /* when res2 = 1 phase = 0x200 | 0x100; */ + if (res2) + phase = 0x300; + + chanout[8] += op_calc(phase<wavetable) * 2; + } + +} + + +/* generic table initialize */ +static int init_tables(void) +{ + signed int i,x; + signed int n; + double o,m; + + + for (x=0; x>= 4; /* 12 bits here */ + if (n&1) /* round to nearest */ + n = (n>>1)+1; + else + n = n>>1; + /* 11 bits here (rounded) */ + n <<= 1; /* 12 bits here (as in real chip) */ + tl_tab[ x*2 + 0 ] = n; + tl_tab[ x*2 + 1 ] = ~tl_tab[ x*2 + 0 ]; /* this *is* different from OPL2 (verified on real YMF262) */ + + for (i=1; i<13; i++) + { + tl_tab[ x*2+0 + i*2*TL_RES_LEN ] = tl_tab[ x*2+0 ]>>i; + tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = ~tl_tab[ x*2+0 + i*2*TL_RES_LEN ]; /* this *is* different from OPL2 (verified on real YMF262) */ + } + #if 0 + logerror("tl %04i", x*2); + for (i=0; i<13; i++) + logerror(", [%02i] %5i", i*2, tl_tab[ x*2 +0 + i*2*TL_RES_LEN ] ); /* positive */ + logerror("\n"); + + logerror("tl %04i", x*2); + for (i=0; i<13; i++) + logerror(", [%02i] %5i", i*2, tl_tab[ x*2 +1 + i*2*TL_RES_LEN ] ); /* negative */ + logerror("\n"); + #endif + } + + for (i=0; i0.0) + o = 8*log(1.0/m)/log(2.0); /* convert to 'decibels' */ + else + o = 8*log(-1.0/m)/log(2.0); /* convert to 'decibels' */ + + o = o / (ENV_STEP/4); + + n = (int)(2.0*o); + if (n&1) /* round to nearest */ + n = (n>>1)+1; + else + n = n>>1; + + sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 ); + + /*logerror("YMF262.C: sin [%4i (hex=%03x)]= %4i (tl_tab value=%5i)\n", i, i, sin_tab[i], tl_tab[sin_tab[i]] );*/ + } + + for (i=0; i>1) ]; + + /* waveform 3: _ _ _ _ */ + /* / |_/ |_/ |_/ |_*/ + /* abs(output only first quarter of the sinus waveform) */ + + if (i & (1<<(SIN_BITS-2)) ) + sin_tab[3*SIN_LEN+i] = TL_TAB_LEN; + else + sin_tab[3*SIN_LEN+i] = sin_tab[i & (SIN_MASK>>2)]; + + /* waveform 4: */ + /* /\ ____/\ ____*/ + /* \/ \/ */ + /* output whole sinus waveform in half the cycle(step=2) and output 0 on the other half of cycle */ + + if (i & (1<<(SIN_BITS-1)) ) + sin_tab[4*SIN_LEN+i] = TL_TAB_LEN; + else + sin_tab[4*SIN_LEN+i] = sin_tab[i*2]; + + /* waveform 5: */ + /* /\/\____/\/\____*/ + /* */ + /* output abs(whole sinus) waveform in half the cycle(step=2) and output 0 on the other half of cycle */ + + if (i & (1<<(SIN_BITS-1)) ) + sin_tab[5*SIN_LEN+i] = TL_TAB_LEN; + else + sin_tab[5*SIN_LEN+i] = sin_tab[(i*2) & (SIN_MASK>>1) ]; + + /* waveform 6: ____ ____ */ + /* */ + /* ____ ____*/ + /* output maximum in half the cycle and output minimum on the other half of cycle */ + + if (i & (1<<(SIN_BITS-1)) ) + sin_tab[6*SIN_LEN+i] = 1; /* negative */ + else + sin_tab[6*SIN_LEN+i] = 0; /* positive */ + + /* waveform 7: */ + /* |\____ |\____ */ + /* \| \|*/ + /* output sawtooth waveform */ + + if (i & (1<<(SIN_BITS-1)) ) + x = ((SIN_LEN-1)-i)*16 + 1; /* negative: from 8177 to 1 */ + else + x = i*16; /*positive: from 0 to 8176 */ + + if (x > TL_TAB_LEN) + x = TL_TAB_LEN; /* clip to the allowed range */ + + sin_tab[7*SIN_LEN+i] = x; + + //logerror("YMF262.C: sin1[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[1*SIN_LEN+i], tl_tab[sin_tab[1*SIN_LEN+i]] ); + //logerror("YMF262.C: sin2[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[2*SIN_LEN+i], tl_tab[sin_tab[2*SIN_LEN+i]] ); + //logerror("YMF262.C: sin3[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[3*SIN_LEN+i], tl_tab[sin_tab[3*SIN_LEN+i]] ); + //logerror("YMF262.C: sin4[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[4*SIN_LEN+i], tl_tab[sin_tab[4*SIN_LEN+i]] ); + //logerror("YMF262.C: sin5[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[5*SIN_LEN+i], tl_tab[sin_tab[5*SIN_LEN+i]] ); + //logerror("YMF262.C: sin6[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[6*SIN_LEN+i], tl_tab[sin_tab[6*SIN_LEN+i]] ); + //logerror("YMF262.C: sin7[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[7*SIN_LEN+i], tl_tab[sin_tab[7*SIN_LEN+i]] ); + } + /*logerror("YMF262.C: ENV_QUIET= %08x (dec*8=%i)\n", ENV_QUIET, ENV_QUIET*8 );*/ + +#ifdef SAVE_SAMPLE + sample[0]=fopen("sampsum.pcm","wb"); +#endif + + return 1; +} + +static void OPLCloseTable( void ) +{ +#ifdef SAVE_SAMPLE + fclose(sample[0]); +#endif +} + + + +static void OPL3_initalize(OPL3 *chip) +{ + int i; + + /* frequency base */ + chip->freqbase = (chip->rate) ? ((double)chip->clock / (8.0*36)) / chip->rate : 0; +#if 0 + chip->rate = (double)chip->clock / (8.0*36); + chip->freqbase = 1.0; +#endif + + /* logerror("YMF262: freqbase=%f\n", chip->freqbase); */ + + /* Timer base time */ + chip->TimerBase = attotime::from_hz(chip->clock) * (8*36); + + /* make fnumber -> increment counter table */ + for( i=0 ; i < 1024 ; i++ ) + { + /* opn phase increment counter = 20bit */ + chip->fn_tab[i] = (uint32_t)( (double)i * 64 * chip->freqbase * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */ +#if 0 + logerror("YMF262.C: fn_tab[%4i] = %08x (dec=%8i)\n", + i, chip->fn_tab[i]>>6, chip->fn_tab[i]>>6 ); +#endif + } + +#if 0 + for( i=0 ; i < 16 ; i++ ) + { + logerror("YMF262.C: sl_tab[%i] = %08x\n", + i, sl_tab[i] ); + } + for( i=0 ; i < 8 ; i++ ) + { + int j; + logerror("YMF262.C: ksl_tab[oct=%2i] =",i); + for (j=0; j<16; j++) + { + logerror("%08x ", static_cast(ksl_tab[i*16+j]) ); + } + logerror("\n"); + } +#endif + + + /* Amplitude modulation: 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */ + /* One entry from LFO_AM_TABLE lasts for 64 samples */ + chip->lfo_am_inc = (1.0 / 64.0 ) * (1<freqbase; + + /* Vibrato: 8 output levels (triangle waveform); 1 level takes 1024 samples */ + chip->lfo_pm_inc = (1.0 / 1024.0) * (1<freqbase; + + /*logerror ("chip->lfo_am_inc = %8x ; chip->lfo_pm_inc = %8x\n", chip->lfo_am_inc, chip->lfo_pm_inc);*/ + + /* Noise generator: a step takes 1 sample */ + chip->noise_f = (1.0 / 1.0) * (1<freqbase; + + chip->eg_timer_add = (1<freqbase; + chip->eg_timer_overflow = ( 1 ) * (1<eg_timer_add, chip->eg_timer_overflow);*/ + +} + +static inline void FM_KEYON(OPL3_SLOT *SLOT, uint32_t key_set) +{ + if( !SLOT->key ) + { + /* restart Phase Generator */ + SLOT->Cnt = 0; + /* phase -> Attack */ + SLOT->state = EG_ATT; + } + SLOT->key |= key_set; +} + +static inline void FM_KEYOFF(OPL3_SLOT *SLOT, uint32_t key_clr) +{ + if( SLOT->key ) + { + SLOT->key &= key_clr; + + if( !SLOT->key ) + { + /* phase -> Release */ + if (SLOT->state>EG_REL) + SLOT->state = EG_REL; + } + } +} + +/* update phase increment counter of operator (also update the EG rates if necessary) */ +static inline void CALC_FCSLOT(OPL3_CH *CH,OPL3_SLOT *SLOT) +{ + int ksr; + + /* (frequency) phase increment counter */ + SLOT->Incr = CH->fc * SLOT->mul; + ksr = CH->kcode >> SLOT->KSR; + + if( SLOT->ksr != ksr ) + { + SLOT->ksr = ksr; + + /* calculate envelope generator rates */ + if ((SLOT->ar + SLOT->ksr) < 16+60) + { + SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; + SLOT->eg_m_ar = (1<eg_sh_ar)-1; + SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; + } + else + { + SLOT->eg_sh_ar = 0; + SLOT->eg_m_ar = (1<eg_sh_ar)-1; + SLOT->eg_sel_ar = 13*RATE_STEPS; + } + SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; + SLOT->eg_m_dr = (1<eg_sh_dr)-1; + SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; + SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; + SLOT->eg_m_rr = (1<eg_sh_rr)-1; + SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; + } +} + +/* set multi,am,vib,EG-TYP,KSR,mul */ +static inline void set_mul(OPL3 *chip,int slot,int v) +{ + OPL3_CH *CH = &chip->P_CH[slot/2]; + OPL3_SLOT *SLOT = &CH->SLOT[slot&1]; + + SLOT->mul = mul_tab[v&0x0f]; + SLOT->KSR = (v&0x10) ? 0 : 2; + SLOT->eg_type = (v&0x20); + SLOT->vib = (v&0x40); + SLOT->AMmask = (v&0x80) ? ~0 : 0; + + if (chip->OPL3_mode & 1) + { + int chan_no = slot/2; + + /* in OPL3 mode */ + //DO THIS: + //if this is one of the slots of 1st channel forming up a 4-op channel + //do normal operation + //else normal 2 operator function + //OR THIS: + //if this is one of the slots of 2nd channel forming up a 4-op channel + //update it using channel data of 1st channel of a pair + //else normal 2 operator function + switch(chan_no) + { + case 0: case 1: case 2: + case 9: case 10: case 11: + if (CH->extended) + { + /* normal */ + CALC_FCSLOT(CH,SLOT); + } + else + { + /* normal */ + CALC_FCSLOT(CH,SLOT); + } + break; + case 3: case 4: case 5: + case 12: case 13: case 14: + if ((CH-3)->extended) + { + /* update this SLOT using frequency data for 1st channel of a pair */ + CALC_FCSLOT(CH-3,SLOT); + } + else + { + /* normal */ + CALC_FCSLOT(CH,SLOT); + } + break; + default: + /* normal */ + CALC_FCSLOT(CH,SLOT); + break; + } + } + else + { + /* in OPL2 mode */ + CALC_FCSLOT(CH,SLOT); + } +} + +/* set ksl & tl */ +static inline void set_ksl_tl(OPL3 *chip,int slot,int v) +{ + OPL3_CH *CH = &chip->P_CH[slot/2]; + OPL3_SLOT *SLOT = &CH->SLOT[slot&1]; + + SLOT->ksl = ksl_shift[v >> 6]; + SLOT->TL = (v&0x3f)<<(ENV_BITS-1-7); /* 7 bits TL (bit 6 = always 0) */ + + if (chip->OPL3_mode & 1) + { + int chan_no = slot/2; + + /* in OPL3 mode */ + //DO THIS: + //if this is one of the slots of 1st channel forming up a 4-op channel + //do normal operation + //else normal 2 operator function + //OR THIS: + //if this is one of the slots of 2nd channel forming up a 4-op channel + //update it using channel data of 1st channel of a pair + //else normal 2 operator function + switch(chan_no) + { + case 0: case 1: case 2: + case 9: case 10: case 11: + if (CH->extended) + { + /* normal */ + SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); + } + else + { + /* normal */ + SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); + } + break; + case 3: case 4: case 5: + case 12: case 13: case 14: + if ((CH-3)->extended) + { + /* update this SLOT using frequency data for 1st channel of a pair */ + SLOT->TLL = SLOT->TL + ((CH-3)->ksl_base>>SLOT->ksl); + } + else + { + /* normal */ + SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); + } + break; + default: + /* normal */ + SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); + break; + } + } + else + { + /* in OPL2 mode */ + SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); + } + +} + +/* set attack rate & decay rate */ +static inline void set_ar_dr(OPL3 *chip,int slot,int v) +{ + OPL3_CH *CH = &chip->P_CH[slot/2]; + OPL3_SLOT *SLOT = &CH->SLOT[slot&1]; + + SLOT->ar = (v>>4) ? 16 + ((v>>4) <<2) : 0; + + if ((SLOT->ar + SLOT->ksr) < 16+60) /* verified on real YMF262 - all 15 x rates take "zero" time */ + { + SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; + SLOT->eg_m_ar = (1<eg_sh_ar)-1; + SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; + } + else + { + SLOT->eg_sh_ar = 0; + SLOT->eg_m_ar = (1<eg_sh_ar)-1; + SLOT->eg_sel_ar = 13*RATE_STEPS; + } + + SLOT->dr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; + SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; + SLOT->eg_m_dr = (1<eg_sh_dr)-1; + SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; +} + +/* set sustain level & release rate */ +static inline void set_sl_rr(OPL3 *chip,int slot,int v) +{ + OPL3_CH *CH = &chip->P_CH[slot/2]; + OPL3_SLOT *SLOT = &CH->SLOT[slot&1]; + + SLOT->sl = sl_tab[ v>>4 ]; + + SLOT->rr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; + SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; + SLOT->eg_m_rr = (1<eg_sh_rr)-1; + SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; +} + + +static void update_channels(OPL3 *chip, OPL3_CH *CH) +{ + /* update channel passed as a parameter and a channel at CH+=3; */ + if (CH->extended) + { /* we've just switched to combined 4 operator mode */ + + } + else + { /* we've just switched to normal 2 operator mode */ + + } + +} + +/* write a value v to register r on OPL chip */ +static void OPL3WriteReg(OPL3 *chip, int r, int v) +{ + OPL3_CH *CH; + unsigned int ch_offset = 0; + int slot; + int block_fnum; + + if(r&0x100) + { + switch(r) + { + case 0x101: /* test register */ + return; + + case 0x104: /* 6 channels enable */ + { + uint8_t prev; + + CH = &chip->P_CH[0]; /* channel 0 */ + prev = CH->extended; + CH->extended = (v>>0) & 1; + if(prev != CH->extended) + update_channels(chip, CH); + CH++; /* channel 1 */ + prev = CH->extended; + CH->extended = (v>>1) & 1; + if(prev != CH->extended) + update_channels(chip, CH); + CH++; /* channel 2 */ + prev = CH->extended; + CH->extended = (v>>2) & 1; + if(prev != CH->extended) + update_channels(chip, CH); + + + CH = &chip->P_CH[9]; /* channel 9 */ + prev = CH->extended; + CH->extended = (v>>3) & 1; + if(prev != CH->extended) + update_channels(chip, CH); + CH++; /* channel 10 */ + prev = CH->extended; + CH->extended = (v>>4) & 1; + if(prev != CH->extended) + update_channels(chip, CH); + CH++; /* channel 11 */ + prev = CH->extended; + CH->extended = (v>>5) & 1; + if(prev != CH->extended) + update_channels(chip, CH); + + } + return; + + case 0x105: /* OPL3 extensions enable register */ + + chip->OPL3_mode = v&0x01; /* OPL3 mode when bit0=1 otherwise it is OPL2 mode */ + + /* following behaviour was tested on real YMF262, + switching OPL3/OPL2 modes on the fly: + - does not change the waveform previously selected (unless when ....) + - does not update CH.A, CH.B, CH.C and CH.D output selectors (registers c0-c8) (unless when ....) + - does not disable channels 9-17 on OPL3->OPL2 switch + - does not switch 4 operator channels back to 2 operator channels + */ + + return; + + default: + if (r < 0x120) + chip->device->logerror("YMF262: write to unknown register (set#2): %03x value=%02x\n",r,v); + break; + } + + ch_offset = 9; /* register page #2 starts from channel 9 (counting from 0) */ + } + + /* adjust bus to 8 bits */ + r &= 0xff; + v &= 0xff; + + + switch(r&0xe0) + { + case 0x00: /* 00-1f:control */ + switch(r&0x1f) + { + case 0x01: /* test register */ + break; + case 0x02: /* Timer 1 */ + chip->T[0] = (256-v)*4; + break; + case 0x03: /* Timer 2 */ + chip->T[1] = (256-v)*16; + break; + case 0x04: /* IRQ clear / mask and Timer enable */ + if(v&0x80) + { /* IRQ flags clear */ + OPL3_STATUS_RESET(chip,0x60); + } + else + { /* set IRQ mask ,timer enable */ + uint8_t st1 = v & 1; + uint8_t st2 = (v>>1) & 1; + + /* IRQRST,T1MSK,t2MSK,x,x,x,ST2,ST1 */ + OPL3_STATUS_RESET(chip, v & 0x60); + OPL3_STATUSMASK_SET(chip, (~v) & 0x60 ); + + /* timer 2 */ + if(chip->st[1] != st2) + { + attotime period = st2 ? chip->TimerBase * chip->T[1] : attotime::zero; + chip->st[1] = st2; + if (chip->timer_handler) (chip->timer_handler)(chip->TimerParam,1,period); + } + /* timer 1 */ + if(chip->st[0] != st1) + { + attotime period = st1 ? chip->TimerBase * chip->T[0] : attotime::zero; + chip->st[0] = st1; + if (chip->timer_handler) (chip->timer_handler)(chip->TimerParam,0,period); + } + } + break; + case 0x08: /* x,NTS,x,x, x,x,x,x */ + chip->nts = v; + break; + + default: + chip->device->logerror("YMF262: write to unknown register: %02x value=%02x\n",r,v); + break; + } + break; + case 0x20: /* am ON, vib ON, ksr, eg_type, mul */ + slot = slot_array[r&0x1f]; + if(slot < 0) return; + set_mul(chip, slot + ch_offset*2, v); + break; + case 0x40: + slot = slot_array[r&0x1f]; + if(slot < 0) return; + set_ksl_tl(chip, slot + ch_offset*2, v); + break; + case 0x60: + slot = slot_array[r&0x1f]; + if(slot < 0) return; + set_ar_dr(chip, slot + ch_offset*2, v); + break; + case 0x80: + slot = slot_array[r&0x1f]; + if(slot < 0) return; + set_sl_rr(chip, slot + ch_offset*2, v); + break; + case 0xa0: + if (r == 0xbd) /* am depth, vibrato depth, r,bd,sd,tom,tc,hh */ + { + if (ch_offset != 0) /* 0xbd register is present in set #1 only */ + return; + + chip->lfo_am_depth = v & 0x80; + chip->lfo_pm_depth_range = (v&0x40) ? 8 : 0; + + chip->rhythm = v&0x3f; + + if(chip->rhythm&0x20) + { + /* BD key on/off */ + if(v&0x10) + { + FM_KEYON (&chip->P_CH[6].SLOT[SLOT1], 2); + FM_KEYON (&chip->P_CH[6].SLOT[SLOT2], 2); + } + else + { + FM_KEYOFF(&chip->P_CH[6].SLOT[SLOT1],~2); + FM_KEYOFF(&chip->P_CH[6].SLOT[SLOT2],~2); + } + /* HH key on/off */ + if(v&0x01) FM_KEYON (&chip->P_CH[7].SLOT[SLOT1], 2); + else FM_KEYOFF(&chip->P_CH[7].SLOT[SLOT1],~2); + /* SD key on/off */ + if(v&0x08) FM_KEYON (&chip->P_CH[7].SLOT[SLOT2], 2); + else FM_KEYOFF(&chip->P_CH[7].SLOT[SLOT2],~2); + /* TOM key on/off */ + if(v&0x04) FM_KEYON (&chip->P_CH[8].SLOT[SLOT1], 2); + else FM_KEYOFF(&chip->P_CH[8].SLOT[SLOT1],~2); + /* TOP-CY key on/off */ + if(v&0x02) FM_KEYON (&chip->P_CH[8].SLOT[SLOT2], 2); + else FM_KEYOFF(&chip->P_CH[8].SLOT[SLOT2],~2); + } + else + { + /* BD key off */ + FM_KEYOFF(&chip->P_CH[6].SLOT[SLOT1],~2); + FM_KEYOFF(&chip->P_CH[6].SLOT[SLOT2],~2); + /* HH key off */ + FM_KEYOFF(&chip->P_CH[7].SLOT[SLOT1],~2); + /* SD key off */ + FM_KEYOFF(&chip->P_CH[7].SLOT[SLOT2],~2); + /* TOM key off */ + FM_KEYOFF(&chip->P_CH[8].SLOT[SLOT1],~2); + /* TOP-CY off */ + FM_KEYOFF(&chip->P_CH[8].SLOT[SLOT2],~2); + } + return; + } + + /* keyon,block,fnum */ + if( (r&0x0f) > 8) return; + CH = &chip->P_CH[(r&0x0f) + ch_offset]; + + if(!(r&0x10)) + { /* a0-a8 */ + block_fnum = (CH->block_fnum&0x1f00) | v; + } + else + { /* b0-b8 */ + block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff); + + if (chip->OPL3_mode & 1) + { + int chan_no = (r&0x0f) + ch_offset; + + /* in OPL3 mode */ + //DO THIS: + //if this is 1st channel forming up a 4-op channel + //ALSO keyon/off slots of 2nd channel forming up 4-op channel + //else normal 2 operator function keyon/off + //OR THIS: + //if this is 2nd channel forming up 4-op channel just do nothing + //else normal 2 operator function keyon/off + switch(chan_no) + { + case 0: case 1: case 2: + case 9: case 10: case 11: + if (CH->extended) + { + //if this is 1st channel forming up a 4-op channel + //ALSO keyon/off slots of 2nd channel forming up 4-op channel + if(v&0x20) + { + FM_KEYON (&CH->SLOT[SLOT1], 1); + FM_KEYON (&CH->SLOT[SLOT2], 1); + FM_KEYON (&(CH+3)->SLOT[SLOT1], 1); + FM_KEYON (&(CH+3)->SLOT[SLOT2], 1); + } + else + { + FM_KEYOFF(&CH->SLOT[SLOT1],~1); + FM_KEYOFF(&CH->SLOT[SLOT2],~1); + FM_KEYOFF(&(CH+3)->SLOT[SLOT1],~1); + FM_KEYOFF(&(CH+3)->SLOT[SLOT2],~1); + } + } + else + { + //else normal 2 operator function keyon/off + if(v&0x20) + { + FM_KEYON (&CH->SLOT[SLOT1], 1); + FM_KEYON (&CH->SLOT[SLOT2], 1); + } + else + { + FM_KEYOFF(&CH->SLOT[SLOT1],~1); + FM_KEYOFF(&CH->SLOT[SLOT2],~1); + } + } + break; + + case 3: case 4: case 5: + case 12: case 13: case 14: + if ((CH-3)->extended) + { + //if this is 2nd channel forming up 4-op channel just do nothing + } + else + { + //else normal 2 operator function keyon/off + if(v&0x20) + { + FM_KEYON (&CH->SLOT[SLOT1], 1); + FM_KEYON (&CH->SLOT[SLOT2], 1); + } + else + { + FM_KEYOFF(&CH->SLOT[SLOT1],~1); + FM_KEYOFF(&CH->SLOT[SLOT2],~1); + } + } + break; + + default: + if(v&0x20) + { + FM_KEYON (&CH->SLOT[SLOT1], 1); + FM_KEYON (&CH->SLOT[SLOT2], 1); + } + else + { + FM_KEYOFF(&CH->SLOT[SLOT1],~1); + FM_KEYOFF(&CH->SLOT[SLOT2],~1); + } + break; + } + } + else + { + if(v&0x20) + { + FM_KEYON (&CH->SLOT[SLOT1], 1); + FM_KEYON (&CH->SLOT[SLOT2], 1); + } + else + { + FM_KEYOFF(&CH->SLOT[SLOT1],~1); + FM_KEYOFF(&CH->SLOT[SLOT2],~1); + } + } + } + /* update */ + if(CH->block_fnum != block_fnum) + { + uint8_t block = block_fnum >> 10; + + CH->block_fnum = block_fnum; + + CH->ksl_base = static_cast(ksl_tab[block_fnum>>6]); + CH->fc = chip->fn_tab[block_fnum&0x03ff] >> (7-block); + + /* BLK 2,1,0 bits -> bits 3,2,1 of kcode */ + CH->kcode = (CH->block_fnum&0x1c00)>>9; + + /* the info below is actually opposite to what is stated in the Manuals (verifed on real YMF262) */ + /* if notesel == 0 -> lsb of kcode is bit 10 (MSB) of fnum */ + /* if notesel == 1 -> lsb of kcode is bit 9 (MSB-1) of fnum */ + if (chip->nts&0x40) + CH->kcode |= (CH->block_fnum&0x100)>>8; /* notesel == 1 */ + else + CH->kcode |= (CH->block_fnum&0x200)>>9; /* notesel == 0 */ + + if (chip->OPL3_mode & 1) + { + int chan_no = (r&0x0f) + ch_offset; + /* in OPL3 mode */ + //DO THIS: + //if this is 1st channel forming up a 4-op channel + //ALSO update slots of 2nd channel forming up 4-op channel + //else normal 2 operator function keyon/off + //OR THIS: + //if this is 2nd channel forming up 4-op channel just do nothing + //else normal 2 operator function keyon/off + switch(chan_no) + { + case 0: case 1: case 2: + case 9: case 10: case 11: + if (CH->extended) + { + //if this is 1st channel forming up a 4-op channel + //ALSO update slots of 2nd channel forming up 4-op channel + + /* refresh Total Level in FOUR SLOTs of this channel and channel+3 using data from THIS channel */ + CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); + CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); + (CH+3)->SLOT[SLOT1].TLL = (CH+3)->SLOT[SLOT1].TL + (CH->ksl_base>>(CH+3)->SLOT[SLOT1].ksl); + (CH+3)->SLOT[SLOT2].TLL = (CH+3)->SLOT[SLOT2].TL + (CH->ksl_base>>(CH+3)->SLOT[SLOT2].ksl); + + /* refresh frequency counter in FOUR SLOTs of this channel and channel+3 using data from THIS channel */ + CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); + CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); + CALC_FCSLOT(CH,&(CH+3)->SLOT[SLOT1]); + CALC_FCSLOT(CH,&(CH+3)->SLOT[SLOT2]); + } + else + { + //else normal 2 operator function + /* refresh Total Level in both SLOTs of this channel */ + CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); + CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); + + /* refresh frequency counter in both SLOTs of this channel */ + CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); + CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); + } + break; + + case 3: case 4: case 5: + case 12: case 13: case 14: + if ((CH-3)->extended) + { + //if this is 2nd channel forming up 4-op channel just do nothing + } + else + { + //else normal 2 operator function + /* refresh Total Level in both SLOTs of this channel */ + CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); + CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); + + /* refresh frequency counter in both SLOTs of this channel */ + CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); + CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); + } + break; + + default: + /* refresh Total Level in both SLOTs of this channel */ + CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); + CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); + + /* refresh frequency counter in both SLOTs of this channel */ + CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); + CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); + break; + } + } + else + { + /* in OPL2 mode */ + + /* refresh Total Level in both SLOTs of this channel */ + CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); + CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); + + /* refresh frequency counter in both SLOTs of this channel */ + CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); + CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); + } + } + break; + + case 0xc0: + /* CH.D, CH.C, CH.B, CH.A, FB(3bits), C */ + if( (r&0xf) > 8) return; + + CH = &chip->P_CH[(r&0xf) + ch_offset]; + + if( chip->OPL3_mode & 1 ) + { + int base = ((r&0xf) + ch_offset) * 4; + + /* OPL3 mode */ + chip->pan[ base ] = (v & 0x10) ? ~0 : 0; /* ch.A */ + chip->pan[ base +1 ] = (v & 0x20) ? ~0 : 0; /* ch.B */ + chip->pan[ base +2 ] = (v & 0x40) ? ~0 : 0; /* ch.C */ + chip->pan[ base +3 ] = (v & 0x80) ? ~0 : 0; /* ch.D */ + } + else + { + int base = ((r&0xf) + ch_offset) * 4; + + /* OPL2 mode - always enabled */ + chip->pan[ base ] = ~0; /* ch.A */ + chip->pan[ base +1 ] = ~0; /* ch.B */ + chip->pan[ base +2 ] = ~0; /* ch.C */ + chip->pan[ base +3 ] = ~0; /* ch.D */ + } + + chip->pan_ctrl_value[ (r&0xf) + ch_offset ] = v; /* store control value for OPL3/OPL2 mode switching on the fly */ + + CH->SLOT[SLOT1].FB = (v>>1)&7 ? ((v>>1)&7) + 7 : 0; + CH->SLOT[SLOT1].CON = v&1; + + if( chip->OPL3_mode & 1 ) + { + int chan_no = (r&0x0f) + ch_offset; + + switch(chan_no) + { + case 0: case 1: case 2: + case 9: case 10: case 11: + if (CH->extended) + { + uint8_t conn = (CH->SLOT[SLOT1].CON<<1) | ((CH+3)->SLOT[SLOT1].CON<<0); + switch(conn) + { + case 0: + /* 1 -> 2 -> 3 -> 4 - out */ + + CH->SLOT[SLOT1].conn_enum = CONN_PHASEMOD; + CH->SLOT[SLOT2].conn_enum = CONN_PHASEMOD2; + (CH+3)->SLOT[SLOT1].conn_enum = CONN_PHASEMOD; + (CH+3)->SLOT[SLOT2].conn_enum = CONN_CHAN0 + chan_no + 3; + break; + case 1: + /* 1 -> 2 -\ + 3 -> 4 -+- out */ + + CH->SLOT[SLOT1].conn_enum = CONN_PHASEMOD; + CH->SLOT[SLOT2].conn_enum = CONN_CHAN0 + chan_no; + (CH+3)->SLOT[SLOT1].conn_enum = CONN_PHASEMOD; + (CH+3)->SLOT[SLOT2].conn_enum = CONN_CHAN0 + chan_no + 3; + break; + case 2: + /* 1 -----------\ + 2 -> 3 -> 4 -+- out */ + + CH->SLOT[SLOT1].conn_enum = CONN_CHAN0 + chan_no; + CH->SLOT[SLOT2].conn_enum = CONN_PHASEMOD2; + (CH+3)->SLOT[SLOT1].conn_enum = CONN_PHASEMOD; + (CH+3)->SLOT[SLOT2].conn_enum = CONN_CHAN0 + chan_no + 3; + break; + case 3: + /* 1 ------\ + 2 -> 3 -+- out + 4 ------/ */ + CH->SLOT[SLOT1].conn_enum = CONN_CHAN0 + chan_no; + CH->SLOT[SLOT2].conn_enum = CONN_PHASEMOD2; + (CH+3)->SLOT[SLOT1].conn_enum = CONN_CHAN0 + chan_no + 3; + (CH+3)->SLOT[SLOT2].conn_enum = CONN_CHAN0 + chan_no + 3; + break; + } + OPL3_SLOT_CONNECT(chip, &CH->SLOT[SLOT1]); + OPL3_SLOT_CONNECT(chip, &CH->SLOT[SLOT2]); + OPL3_SLOT_CONNECT(chip, &(CH+3)->SLOT[SLOT1]); + OPL3_SLOT_CONNECT(chip, &(CH+3)->SLOT[SLOT2]); + } + else + { + /* 2 operators mode */ + CH->SLOT[SLOT1].conn_enum = CH->SLOT[SLOT1].CON ? CONN_CHAN0 + (r&0xf)+ch_offset : CONN_PHASEMOD; + CH->SLOT[SLOT2].conn_enum = CONN_CHAN0 + (r&0xf)+ch_offset; + OPL3_SLOT_CONNECT(chip, &CH->SLOT[SLOT1]); + OPL3_SLOT_CONNECT(chip, &CH->SLOT[SLOT2]); + } + break; + + case 3: case 4: case 5: + case 12: case 13: case 14: + if ((CH-3)->extended) + { + uint8_t conn = ((CH-3)->SLOT[SLOT1].CON<<1) | (CH->SLOT[SLOT1].CON<<0); + switch(conn) + { + case 0: + /* 1 -> 2 -> 3 -> 4 - out */ + + (CH-3)->SLOT[SLOT1].conn_enum = CONN_PHASEMOD; + (CH-3)->SLOT[SLOT2].conn_enum = CONN_PHASEMOD2; + CH->SLOT[SLOT1].conn_enum = CONN_PHASEMOD; + CH->SLOT[SLOT2].conn_enum = CONN_CHAN0 + chan_no; + break; + case 1: + /* 1 -> 2 -\ + 3 -> 4 -+- out */ + + (CH-3)->SLOT[SLOT1].conn_enum = CONN_PHASEMOD; + (CH-3)->SLOT[SLOT2].conn_enum = CONN_CHAN0 + chan_no - 3; + CH->SLOT[SLOT1].conn_enum = CONN_PHASEMOD; + CH->SLOT[SLOT2].conn_enum = CONN_CHAN0 + chan_no; + break; + case 2: + /* 1 -----------\ + 2 -> 3 -> 4 -+- out */ + + (CH-3)->SLOT[SLOT1].conn_enum = CONN_CHAN0 + chan_no - 3; + (CH-3)->SLOT[SLOT2].conn_enum = CONN_PHASEMOD2; + CH->SLOT[SLOT1].conn_enum = CONN_PHASEMOD; + CH->SLOT[SLOT2].conn_enum = CONN_CHAN0 + chan_no; + break; + case 3: + /* 1 ------\ + 2 -> 3 -+- out + 4 ------/ */ + (CH-3)->SLOT[SLOT1].conn_enum = CONN_CHAN0 + chan_no - 3; + (CH-3)->SLOT[SLOT2].conn_enum = CONN_PHASEMOD2; + CH->SLOT[SLOT1].conn_enum = CONN_CHAN0 + chan_no; + CH->SLOT[SLOT2].conn_enum = CONN_CHAN0 + chan_no; + break; + } + OPL3_SLOT_CONNECT(chip, &(CH-3)->SLOT[SLOT1]); + OPL3_SLOT_CONNECT(chip, &(CH-3)->SLOT[SLOT2]); + OPL3_SLOT_CONNECT(chip, &CH->SLOT[SLOT1]); + OPL3_SLOT_CONNECT(chip, &CH->SLOT[SLOT2]); + } + else + { + /* 2 operators mode */ + CH->SLOT[SLOT1].conn_enum = CH->SLOT[SLOT1].CON ? CONN_CHAN0 + (r&0xf)+ch_offset : CONN_PHASEMOD; + CH->SLOT[SLOT2].conn_enum = CONN_CHAN0 + (r&0xf)+ch_offset; + OPL3_SLOT_CONNECT(chip, &CH->SLOT[SLOT1]); + OPL3_SLOT_CONNECT(chip, &CH->SLOT[SLOT2]); + } + break; + + default: + /* 2 operators mode */ + CH->SLOT[SLOT1].conn_enum = CH->SLOT[SLOT1].CON ? CONN_CHAN0 + (r&0xf)+ch_offset : CONN_PHASEMOD; + CH->SLOT[SLOT2].conn_enum = CONN_CHAN0 + (r&0xf)+ch_offset; + OPL3_SLOT_CONNECT(chip, &CH->SLOT[SLOT1]); + OPL3_SLOT_CONNECT(chip, &CH->SLOT[SLOT2]); + break; + } + } + else + { + /* OPL2 mode - always 2 operators mode */ + CH->SLOT[SLOT1].conn_enum = CH->SLOT[SLOT1].CON ? CONN_CHAN0 + (r&0xf)+ch_offset : CONN_PHASEMOD; + CH->SLOT[SLOT2].conn_enum = CONN_CHAN0 + (r&0xf)+ch_offset; + OPL3_SLOT_CONNECT(chip, &CH->SLOT[SLOT1]); + OPL3_SLOT_CONNECT(chip, &CH->SLOT[SLOT2]); + } + break; + + case 0xe0: /* waveform select */ + slot = slot_array[r&0x1f]; + if(slot < 0) return; + + slot += ch_offset*2; + + CH = &chip->P_CH[slot/2]; + + + /* store 3-bit value written regardless of current OPL2 or OPL3 mode... (verified on real YMF262) */ + v &= 7; + CH->SLOT[slot&1].waveform_number = v; + + /* ... but select only waveforms 0-3 in OPL2 mode */ + if( !(chip->OPL3_mode & 1) ) + { + v &= 3; /* we're in OPL2 mode */ + } + CH->SLOT[slot&1].wavetable = v * SIN_LEN; + break; + } +} + +/* lock/unlock for common table */ +static int OPL3_LockTable(device_t *device) +{ + num_lock++; + if(num_lock>1) return 0; + + /* first time */ + + if( !init_tables() ) + { + num_lock--; + return -1; + } + + return 0; +} + +static void OPL3_UnLockTable(void) +{ + if(num_lock) num_lock--; + if(num_lock) return; + + /* last time */ + OPLCloseTable(); +} + +static void OPL3ResetChip(OPL3 *chip) +{ + int c,s; + + chip->eg_timer = 0; + chip->eg_cnt = 0; + + chip->noise_rng = 1; /* noise shift register */ + chip->nts = 0; /* note split */ + OPL3_STATUS_RESET(chip,0x60); + + /* reset with register write */ + OPL3WriteReg(chip,0x01,0); /* test register */ + OPL3WriteReg(chip,0x02,0); /* Timer1 */ + OPL3WriteReg(chip,0x03,0); /* Timer2 */ + OPL3WriteReg(chip,0x04,0); /* IRQ mask clear */ + + +//FIX IT registers 101, 104 and 105 + + +//FIX IT (dont change CH.D, CH.C, CH.B and CH.A in C0-C8 registers) + for(c = 0xff ; c >= 0x20 ; c-- ) + OPL3WriteReg(chip,c,0); +//FIX IT (dont change CH.D, CH.C, CH.B and CH.A in C0-C8 registers) + for(c = 0x1ff ; c >= 0x120 ; c-- ) + OPL3WriteReg(chip,c,0); + + + + /* reset operator parameters */ + for( c = 0 ; c < 9*2 ; c++ ) + { + OPL3_CH *CH = &chip->P_CH[c]; + for(s = 0 ; s < 2 ; s++ ) + { + CH->SLOT[s].state = EG_OFF; + CH->SLOT[s].volume = MAX_ATT_INDEX; + } + } +} + +/* Create one of virtual YMF262 */ +/* 'clock' is chip clock in Hz */ +/* 'rate' is sampling rate */ +static OPL3 *OPL3Create(device_t *device, int clock, int rate, int type) +{ + OPL3 *chip; + + if (OPL3_LockTable(device) == -1) return nullptr; + + /* allocate memory block */ + chip = auto_alloc_clear(device->machine(), ()); + + chip->device = device; + chip->type = type; + chip->clock = clock; + chip->rate = rate; + + /* init global tables */ + OPL3_initalize(chip); + + /* reset chip */ + OPL3ResetChip(chip); + return chip; +} + +/* Destroy one of virtual YMF262 */ +static void OPL3Destroy(OPL3 *chip) +{ + OPL3_UnLockTable(); + auto_free(chip->device->machine(), chip); +} + + +/* YMF262 I/O interface */ +static int OPL3Write(OPL3 *chip, int a, int v) +{ + /* data bus is 8 bits */ + v &= 0xff; + + + switch(a&3) + { + case 0: /* address port 0 (register set #1) */ + chip->address = v; + break; + + case 1: /* data port - ignore A1 */ + case 3: /* data port - ignore A1 */ + if(chip->UpdateHandler) chip->UpdateHandler(chip->UpdateParam,0); + OPL3WriteReg(chip,chip->address,v); + break; + + case 2: /* address port 1 (register set #2) */ + + /* verified on real YMF262: + in OPL3 mode: + address line A1 is stored during *address* write and ignored during *data* write. + + in OPL2 mode: + register set#2 writes go to register set#1 (ignoring A1) + verified on registers from set#2: 0x01, 0x04, 0x20-0xef + The only exception is register 0x05. + */ + if( chip->OPL3_mode & 1 ) + { + /* OPL3 mode */ + chip->address = v | 0x100; + } + else + { + /* in OPL2 mode the only accessible in set #2 is register 0x05 */ + if( v==5 ) + chip->address = v | 0x100; + else + chip->address = v; /* verified range: 0x01, 0x04, 0x20-0xef(set #2 becomes set #1 in opl2 mode) */ + } + break; + } + + return chip->status>>7; +} + +static unsigned char OPL3Read(OPL3 *chip,int a) +{ + if( a==0 ) + { + /* status port */ + return chip->status; + } + + return 0x00; /* verified on real YMF262 */ +} + + + +static int OPL3TimerOver(OPL3 *chip,int c) +{ + if( c ) + { /* Timer B */ + OPL3_STATUS_SET(chip,0x20); + } + else + { /* Timer A */ + OPL3_STATUS_SET(chip,0x40); + } + /* reload timer */ + if (chip->timer_handler) (chip->timer_handler)(chip->TimerParam,c,chip->TimerBase * chip->T[c]); + return chip->status>>7; +} + +static void OPL3_save_state(OPL3 *chip, device_t *device) { + for (int ch=0; ch<18; ch++) { + OPL3_CH *channel = &chip->P_CH[ch]; + device->save_item(NAME(channel->block_fnum), ch); + device->save_item(NAME(channel->fc), ch); + device->save_item(NAME(channel->ksl_base), ch); + device->save_item(NAME(channel->kcode), ch); + device->save_item(NAME(channel->extended), ch); + + for (int sl=0; sl<2; sl++) { + OPL3_SLOT *slot = &channel->SLOT[sl]; + device->save_item(NAME(slot->ar), ch*2+sl); + device->save_item(NAME(slot->dr), ch*2+sl); + device->save_item(NAME(slot->rr), ch*2+sl); + device->save_item(NAME(slot->KSR), ch*2+sl); + device->save_item(NAME(slot->ksl), ch*2+sl); + device->save_item(NAME(slot->ksr), ch*2+sl); + device->save_item(NAME(slot->mul), ch*2+sl); + + device->save_item(NAME(slot->Cnt), ch*2+sl); + device->save_item(NAME(slot->Incr), ch*2+sl); + device->save_item(NAME(slot->FB), ch*2+sl); + device->save_item(NAME(slot->conn_enum), ch*2+sl); + device->save_item(NAME(slot->op1_out), ch*2+sl); + device->save_item(NAME(slot->CON), ch*2+sl); + + device->save_item(NAME(slot->eg_type), ch*2+sl); + device->save_item(NAME(slot->state), ch*2+sl); + device->save_item(NAME(slot->TL), ch*2+sl); + device->save_item(NAME(slot->TLL), ch*2+sl); + device->save_item(NAME(slot->volume), ch*2+sl); + device->save_item(NAME(slot->sl), ch*2+sl); + + device->save_item(NAME(slot->eg_m_ar), ch*2+sl); + device->save_item(NAME(slot->eg_sh_ar), ch*2+sl); + device->save_item(NAME(slot->eg_sel_ar), ch*2+sl); + device->save_item(NAME(slot->eg_m_dr), ch*2+sl); + device->save_item(NAME(slot->eg_sh_dr), ch*2+sl); + device->save_item(NAME(slot->eg_sel_dr), ch*2+sl); + device->save_item(NAME(slot->eg_m_rr), ch*2+sl); + device->save_item(NAME(slot->eg_sh_rr), ch*2+sl); + device->save_item(NAME(slot->eg_sel_rr), ch*2+sl); + + device->save_item(NAME(slot->key), ch*2+sl); + + device->save_item(NAME(slot->AMmask), ch*2+sl); + device->save_item(NAME(slot->vib), ch*2+sl); + + device->save_item(NAME(slot->waveform_number), ch*2+sl); + device->save_item(NAME(slot->wavetable), ch*2+sl); + } + } + + device->save_item(NAME(chip->pan)); + device->save_item(NAME(chip->pan_ctrl_value)); + + device->save_item(NAME(chip->lfo_am_depth)); + device->save_item(NAME(chip->lfo_pm_depth_range)); + + device->save_item(NAME(chip->OPL3_mode)); + device->save_item(NAME(chip->rhythm)); + + device->save_item(NAME(chip->address)); + device->save_item(NAME(chip->status)); + device->save_item(NAME(chip->statusmask)); +} + +void * ymf262_init(device_t *device, int clock, int rate) +{ + void *chip = OPL3Create(device,clock,rate,OPL3_TYPE_YMF262); + OPL3_save_state((OPL3 *)chip, device); + + return chip; +} + +void ymf262_post_load(void *chip) { + OPL3 *opl3 = (OPL3 *)chip; + for (int ch=0; ch<18; ch++) { + for (int sl=0; sl<2; sl++) { + OPL3_SLOT_CONNECT(opl3, &(opl3->P_CH[ch].SLOT[sl])); + } + } +} + +void ymf262_shutdown(void *chip) +{ + OPL3Destroy((OPL3 *)chip); +} +void ymf262_reset_chip(void *chip) +{ + OPL3ResetChip((OPL3 *)chip); +} + +int ymf262_write(void *chip, int a, int v) +{ + return OPL3Write((OPL3 *)chip, a, v); +} + +unsigned char ymf262_read(void *chip, int a) +{ + /* Note on status register: */ + + /* YM3526(OPL) and YM3812(OPL2) return bit2 and bit1 in HIGH state */ + + /* YMF262(OPL3) always returns bit2 and bit1 in LOW state */ + /* which can be used to identify the chip */ + + /* YMF278(OPL4) returns bit2 in LOW and bit1 in HIGH state ??? info from manual - not verified */ + + return OPL3Read((OPL3 *)chip, a); +} +int ymf262_timer_over(void *chip, int c) +{ + return OPL3TimerOver((OPL3 *)chip, c); +} + +void ymf262_set_timer_handler(void *chip, OPL3_TIMERHANDLER timer_handler, device_t *device) +{ + reinterpret_cast(chip)->SetTimerHandler(timer_handler, device); +} +void ymf262_set_irq_handler(void *chip, OPL3_IRQHANDLER IRQHandler, device_t *device) +{ + reinterpret_cast(chip)->SetIRQHandler(IRQHandler, device); +} +void ymf262_set_update_handler(void *chip, OPL3_UPDATEHANDLER UpdateHandler, device_t *device) +{ + reinterpret_cast(chip)->SetUpdateHandler(UpdateHandler, device); +} + + +/* +** Generate samples for one of the YMF262's +** +** 'which' is the virtual YMF262 number +** '**buffers' is table of 4 pointers to the buffers: CH.A, CH.B, CH.C and CH.D +** 'length' is the number of samples that should be generated +*/ +void ymf262_update_one(void *_chip, OPL3SAMPLE **buffers, int length) +{ + int i; + OPL3 *chip = (OPL3 *)_chip; + signed int *chanout = chip->chanout; + uint8_t rhythm = chip->rhythm&0x20; + + OPL3SAMPLE *ch_a = buffers[0]; + OPL3SAMPLE *ch_b = buffers[1]; + OPL3SAMPLE *ch_c = buffers[2]; + OPL3SAMPLE *ch_d = buffers[3]; + + for( i=0; i < length ; i++ ) + { + int a,b,c,d; + + + advance_lfo(chip); + + /* clear channel outputs */ + memset(chip->chanout, 0, sizeof(chip->chanout)); + +#if 1 + /* register set #1 */ + chan_calc(chip, &chip->P_CH[0]); /* extended 4op ch#0 part 1 or 2op ch#0 */ + if (chip->P_CH[0].extended) + chan_calc_ext(chip, &chip->P_CH[3]); /* extended 4op ch#0 part 2 */ + else + chan_calc(chip, &chip->P_CH[3]); /* standard 2op ch#3 */ + + + chan_calc(chip, &chip->P_CH[1]); /* extended 4op ch#1 part 1 or 2op ch#1 */ + if (chip->P_CH[1].extended) + chan_calc_ext(chip, &chip->P_CH[4]); /* extended 4op ch#1 part 2 */ + else + chan_calc(chip, &chip->P_CH[4]); /* standard 2op ch#4 */ + + + chan_calc(chip, &chip->P_CH[2]); /* extended 4op ch#2 part 1 or 2op ch#2 */ + if (chip->P_CH[2].extended) + chan_calc_ext(chip, &chip->P_CH[5]); /* extended 4op ch#2 part 2 */ + else + chan_calc(chip, &chip->P_CH[5]); /* standard 2op ch#5 */ + + + if(!rhythm) + { + chan_calc(chip, &chip->P_CH[6]); + chan_calc(chip, &chip->P_CH[7]); + chan_calc(chip, &chip->P_CH[8]); + } + else /* Rhythm part */ + { + chan_calc_rhythm(chip, &chip->P_CH[0], (chip->noise_rng>>0)&1 ); + } + + /* register set #2 */ + chan_calc(chip, &chip->P_CH[ 9]); + if (chip->P_CH[9].extended) + chan_calc_ext(chip, &chip->P_CH[12]); + else + chan_calc(chip, &chip->P_CH[12]); + + + chan_calc(chip, &chip->P_CH[10]); + if (chip->P_CH[10].extended) + chan_calc_ext(chip, &chip->P_CH[13]); + else + chan_calc(chip, &chip->P_CH[13]); + + + chan_calc(chip, &chip->P_CH[11]); + if (chip->P_CH[11].extended) + chan_calc_ext(chip, &chip->P_CH[14]); + else + chan_calc(chip, &chip->P_CH[14]); + + + /* channels 15,16,17 are fixed 2-operator channels only */ + chan_calc(chip, &chip->P_CH[15]); + chan_calc(chip, &chip->P_CH[16]); + chan_calc(chip, &chip->P_CH[17]); +#endif + + /* accumulator register set #1 */ + a = chanout[0] & chip->pan[0]; + b = chanout[0] & chip->pan[1]; + c = chanout[0] & chip->pan[2]; + d = chanout[0] & chip->pan[3]; +#if 1 + a += chanout[1] & chip->pan[4]; + b += chanout[1] & chip->pan[5]; + c += chanout[1] & chip->pan[6]; + d += chanout[1] & chip->pan[7]; + a += chanout[2] & chip->pan[8]; + b += chanout[2] & chip->pan[9]; + c += chanout[2] & chip->pan[10]; + d += chanout[2] & chip->pan[11]; + + a += chanout[3] & chip->pan[12]; + b += chanout[3] & chip->pan[13]; + c += chanout[3] & chip->pan[14]; + d += chanout[3] & chip->pan[15]; + a += chanout[4] & chip->pan[16]; + b += chanout[4] & chip->pan[17]; + c += chanout[4] & chip->pan[18]; + d += chanout[4] & chip->pan[19]; + a += chanout[5] & chip->pan[20]; + b += chanout[5] & chip->pan[21]; + c += chanout[5] & chip->pan[22]; + d += chanout[5] & chip->pan[23]; + + a += chanout[6] & chip->pan[24]; + b += chanout[6] & chip->pan[25]; + c += chanout[6] & chip->pan[26]; + d += chanout[6] & chip->pan[27]; + a += chanout[7] & chip->pan[28]; + b += chanout[7] & chip->pan[29]; + c += chanout[7] & chip->pan[30]; + d += chanout[7] & chip->pan[31]; + a += chanout[8] & chip->pan[32]; + b += chanout[8] & chip->pan[33]; + c += chanout[8] & chip->pan[34]; + d += chanout[8] & chip->pan[35]; + + /* accumulator register set #2 */ + a += chanout[9] & chip->pan[36]; + b += chanout[9] & chip->pan[37]; + c += chanout[9] & chip->pan[38]; + d += chanout[9] & chip->pan[39]; + a += chanout[10] & chip->pan[40]; + b += chanout[10] & chip->pan[41]; + c += chanout[10] & chip->pan[42]; + d += chanout[10] & chip->pan[43]; + a += chanout[11] & chip->pan[44]; + b += chanout[11] & chip->pan[45]; + c += chanout[11] & chip->pan[46]; + d += chanout[11] & chip->pan[47]; + + a += chanout[12] & chip->pan[48]; + b += chanout[12] & chip->pan[49]; + c += chanout[12] & chip->pan[50]; + d += chanout[12] & chip->pan[51]; + a += chanout[13] & chip->pan[52]; + b += chanout[13] & chip->pan[53]; + c += chanout[13] & chip->pan[54]; + d += chanout[13] & chip->pan[55]; + a += chanout[14] & chip->pan[56]; + b += chanout[14] & chip->pan[57]; + c += chanout[14] & chip->pan[58]; + d += chanout[14] & chip->pan[59]; + + a += chanout[15] & chip->pan[60]; + b += chanout[15] & chip->pan[61]; + c += chanout[15] & chip->pan[62]; + d += chanout[15] & chip->pan[63]; + a += chanout[16] & chip->pan[64]; + b += chanout[16] & chip->pan[65]; + c += chanout[16] & chip->pan[66]; + d += chanout[16] & chip->pan[67]; + a += chanout[17] & chip->pan[68]; + b += chanout[17] & chip->pan[69]; + c += chanout[17] & chip->pan[70]; + d += chanout[17] & chip->pan[71]; +#endif + a >>= FINAL_SH; + b >>= FINAL_SH; + c >>= FINAL_SH; + d >>= FINAL_SH; + + /* limit check */ + a = limit( a , MAXOUT, MINOUT ); + b = limit( b , MAXOUT, MINOUT ); + c = limit( c , MAXOUT, MINOUT ); + d = limit( d , MAXOUT, MINOUT ); + + #ifdef SAVE_SAMPLE + if (which==0) + { + SAVE_ALL_CHANNELS + } + #endif + + /* store to sound buffer */ + ch_a[i] = a; + ch_b[i] = b; + ch_c[i] = c; + ch_d[i] = d; + + advance(chip); + } + +} diff --git a/src/hardware/mame/ymf262.h b/src/hardware/mame/ymf262.h new file mode 100644 index 00000000..b82a89b9 --- /dev/null +++ b/src/hardware/mame/ymf262.h @@ -0,0 +1,40 @@ +// license:GPL-2.0+ +// copyright-holders:Jarek Burczynski +#ifndef MAME_SOUND_YMF262_H +#define MAME_SOUND_YMF262_H + +#pragma once + +/* select number of output bits: 8 or 16 */ +#define OPL3_SAMPLE_BITS 16 + +typedef stream_sample_t OPL3SAMPLE; +/* +#if (OPL3_SAMPLE_BITS==16) +typedef int16_t OPL3SAMPLE; +#endif +#if (OPL3_SAMPLE_BITS==8) +typedef int8_t OPL3SAMPLE; +#endif +*/ + +typedef void (*OPL3_TIMERHANDLER)(device_t *device,int timer,const attotime &period); +typedef void (*OPL3_IRQHANDLER)(device_t *device,int irq); +typedef void (*OPL3_UPDATEHANDLER)(device_t *device,int min_interval_us); + + +void *ymf262_init(device_t *device, int clock, int rate); +void ymf262_post_load(void *chip); +void ymf262_shutdown(void *chip); +void ymf262_reset_chip(void *chip); +int ymf262_write(void *chip, int a, int v); +unsigned char ymf262_read(void *chip, int a); +int ymf262_timer_over(void *chip, int c); +void ymf262_update_one(void *chip, OPL3SAMPLE **buffers, int length); + +void ymf262_set_timer_handler(void *chip, OPL3_TIMERHANDLER TimerHandler, device_t *device); +void ymf262_set_irq_handler(void *chip, OPL3_IRQHANDLER IRQHandler, device_t *device); +void ymf262_set_update_handler(void *chip, OPL3_UPDATEHANDLER UpdateHandler, device_t *device); + + +#endif // MAME_SOUND_YMF262_H From 051c0f3afda628fd535000a486f1daf92652fed6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 12 Aug 2017 09:17:33 +0000 Subject: [PATCH 3942/4131] Add emu.h header to make the mame files work without too many changes Small changes to remove or disable timer and update handlers Add cheap sample rate conversion to the sn76496 emulation Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/branches/mamesound@4032 --- src/hardware/mame/emu.h | 123 ++++++++++++++++++++++++++++++++++ src/hardware/mame/fmopl.cpp | 24 ++++--- src/hardware/mame/fmopl.h | 6 +- src/hardware/mame/saa1099.cpp | 3 +- src/hardware/mame/saa1099.h | 2 +- src/hardware/mame/sn76496.cpp | 45 +++++++++---- src/hardware/mame/sn76496.h | 20 ++++-- src/hardware/mame/ymf262.cpp | 12 ++-- 8 files changed, 197 insertions(+), 38 deletions(-) create mode 100644 src/hardware/mame/emu.h diff --git a/src/hardware/mame/emu.h b/src/hardware/mame/emu.h new file mode 100644 index 00000000..ace02d29 --- /dev/null +++ b/src/hardware/mame/emu.h @@ -0,0 +1,123 @@ +#ifndef DOSBOX_EMU_H +#define DOSBOX_EMU_H + + +#include "dosbox.h" +#include +#include +#include +#include +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +typedef Bit16s stream_sample_t; + +typedef Bit8u u8; +typedef Bit32u u32; + +class device_t; +struct machine_config; + +#define NAME( _ASDF_ ) 0 +#define BIT( _INPUT_, _BIT_ ) ( ( _INPUT_) >> (_BIT_)) & 1 + +#define ATTR_UNUSED +#define DECLARE_READ8_MEMBER(name) u8 name( int, int) +#define DECLARE_WRITE8_MEMBER(name) void name( int, int, u8 data) +#define READ8_MEMBER(name) u8 name( int, int) +#define WRITE8_MEMBER(name) void name( int offset, int space, u8 data) + +#define DECLARE_DEVICE_TYPE(Type, Class) \ + extern const device_type Type; \ + class Class; + +#define DEFINE_DEVICE_TYPE(Type, Class, ShortName, FullName) \ + const device_type Type = 0; + + +class device_sound_interface { +public: + struct sound_stream { + void update() { + } + }; + sound_stream temp; + + sound_stream* stream_alloc(int whatever, int channels, int size) { + return &temp; + }; + + + virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) = 0; + + device_sound_interface(const machine_config &mconfig, device_t& _device) { + } + +}; + +struct attotime { + int whatever; + + static attotime from_hz(int hz) { + return attotime(); + } +}; + +struct machine_config { +}; + +typedef int device_type; + +class device_t { + u32 clockRate; +public: + struct machine_t { + int describe_context() const { + return 0; + } + }; + + machine_t machine() const { + return machine_t(); + } + + //int offset, space; + + u32 clock() const { + return clockRate; + } + + void logerror(const char* msg, ...) { + } + + static int tag() { + return 0; + } + + virtual void device_start() { + } + + void save_item(int wtf, int blah= 0) { + } + + device_t(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 _clock) : clockRate( _clock ) { + } + +}; + + + +static void auto_free(const device_t::machine_t& machine, void * buffer) { + free(buffer); +} + +#define auto_alloc_array_clear(m, t, c) calloc(c, sizeof(t) ) +#define auto_alloc_clear(m, t) static_cast( calloc(1, sizeof(t) ) ) + + + + +#endif \ No newline at end of file diff --git a/src/hardware/mame/fmopl.cpp b/src/hardware/mame/fmopl.cpp index a9c15478..36414cb7 100644 --- a/src/hardware/mame/fmopl.cpp +++ b/src/hardware/mame/fmopl.cpp @@ -379,7 +379,7 @@ struct FM_OPL uint32_t clock; /* master clock (Hz) */ uint32_t rate; /* sampling rate (Hz) */ double freqbase; /* frequency base */ - attotime TimerBase; /* Timer base time (==sampling time)*/ + //attotime TimerBase; /* Timer base time (==sampling time)*/ device_t *device; signed int phase_modulation; /* phase modulation input (SLOT 2) */ @@ -1434,7 +1434,7 @@ void FM_OPL::initialize() /*logerror("freqbase=%f\n", freqbase);*/ /* Timer base time */ - TimerBase = attotime::from_hz(clock) * 72; + //TimerBase = attotime::from_hz(clock) * 72; /* make fnumber -> increment counter table */ for( i=0 ; i < 1024 ; i++ ) @@ -1514,6 +1514,7 @@ void FM_OPL::WriteReg(int r, int v) case 0x03: /* Timer 2 */ T[1] = (256-v)*16; break; +#if 0 case 0x04: /* IRQ clear / mask and Timer enable */ if(v&0x80) { /* IRQ flag clear */ @@ -1544,6 +1545,7 @@ void FM_OPL::WriteReg(int r, int v) } } break; +#endif #if BUILD_Y8950 case 0x06: /* Key Board OUT */ if(type&OPL_TYPE_KEYBOARD) @@ -1846,6 +1848,7 @@ void FM_OPL::postload() } // anonymous namespace +#if 0 static void OPLsave_state_channel(device_t *device, OPL_CH *CH) { int slot, ch; @@ -1887,7 +1890,6 @@ static void OPLsave_state_channel(device_t *device, OPL_CH *CH) } } - /* Register savestate for a virtual YM3812/YM3526Y8950 */ static void OPL_save_state(FM_OPL *OPL, device_t *device) @@ -1936,6 +1938,8 @@ static void OPL_save_state(FM_OPL *OPL, device_t *device) device->machine().save().register_postload(save_prepost_delegate(FUNC(FM_OPL::postload), OPL)); } +#endif + static void OPL_clock_changed(FM_OPL *OPL, uint32_t clock, uint32_t rate) { OPL->clock = clock; @@ -2103,7 +2107,6 @@ static inline void CSMKeyControll(OPL_CH *CH) CH->SLOT[SLOT2].KEYOFF(~4); } - static int OPLTimerOver(FM_OPL *OPL,int c) { if( c ) @@ -2123,15 +2126,14 @@ static int OPLTimerOver(FM_OPL *OPL,int c) } } /* reload timer */ - if (OPL->timer_handler) (OPL->timer_handler)(OPL->TimerParam,c,OPL->TimerBase * OPL->T[c]); + //if (OPL->timer_handler) (OPL->timer_handler)(OPL->TimerParam,c,OPL->TimerBase * OPL->T[c]); return OPL->status>>7; } - #define MAX_OPL_CHIPS 2 -#if (BUILD_YM3812) +#if BUILD_YM3812 void ym3812_clock_changed(void *chip, uint32_t clock, uint32_t rate) { @@ -2144,7 +2146,7 @@ void * ym3812_init(device_t *device, uint32_t clock, uint32_t rate) FM_OPL *YM3812 = OPLCreate(device,clock,rate,OPL_TYPE_YM3812); if (YM3812) { - OPL_save_state(YM3812, device); + //OPL_save_state(YM3812, device); ym3812_reset_chip(YM3812); } return YM3812; @@ -2197,7 +2199,6 @@ void ym3812_set_update_handler(void *chip,OPL_UPDATEHANDLER UpdateHandler,device OPLSetUpdateHandler(YM3812, UpdateHandler, device); } - /* ** Generate samples for one of the YM3812's ** @@ -2277,7 +2278,7 @@ void *ym3526_init(device_t *device, uint32_t clock, uint32_t rate) FM_OPL *YM3526 = OPLCreate(device,clock,rate,OPL_TYPE_YM3526); if (YM3526) { - OPL_save_state(YM3526, device); + //OPL_save_state(YM3526, device); ym3526_reset_chip(YM3526); } return YM3526; @@ -2425,7 +2426,7 @@ void *y8950_init(device_t *device, uint32_t clock, uint32_t rate) /*Y8950->deltat->write_time = 10.0 / clock;*/ /* a single byte write takes 10 cycles of main clock */ /*Y8950->deltat->read_time = 8.0 / clock;*/ /* a single byte read takes 8 cycles of main clock */ /* reset */ - OPL_save_state(Y8950, device); + //OPL_save_state(Y8950, device); y8950_reset_chip(Y8950); } @@ -2569,4 +2570,5 @@ void y8950_set_keyboard_handler(void *chip,OPL_PORTHANDLER_W KeyboardHandler_w,O OPL->keyboard_param = device; } + #endif diff --git a/src/hardware/mame/fmopl.h b/src/hardware/mame/fmopl.h index c5366d7b..c64a59c9 100644 --- a/src/hardware/mame/fmopl.h +++ b/src/hardware/mame/fmopl.h @@ -9,9 +9,9 @@ /* --- select emulation chips --- */ -#define BUILD_YM3812 (1) -#define BUILD_YM3526 (1) -#define BUILD_Y8950 (1) +#define BUILD_YM3812 1 +#define BUILD_YM3526 (0) +#define BUILD_Y8950 (0) /* select output bits size of output : 8 or 16 */ #define OPL_SAMPLE_BITS 16 diff --git a/src/hardware/mame/saa1099.cpp b/src/hardware/mame/saa1099.cpp index 3c9b334b..f588358a 100644 --- a/src/hardware/mame/saa1099.cpp +++ b/src/hardware/mame/saa1099.cpp @@ -125,7 +125,8 @@ static constexpr uint8_t envelope[8][64] = { // device type definition -DEFINE_DEVICE_TYPE(SAA1099, saa1099_device, "saa1099", "Philips SAA1099") +//DEFINE_DEVICE_TYPE(SAA1099, saa1099_device, "saa1099", "Philips SAA1099") +#define SAA1099 1 //************************************************************************** // LIVE DEVICE diff --git a/src/hardware/mame/saa1099.h b/src/hardware/mame/saa1099.h index 061f39ec..ee763454 100644 --- a/src/hardware/mame/saa1099.h +++ b/src/hardware/mame/saa1099.h @@ -37,7 +37,7 @@ public: DECLARE_WRITE8_MEMBER( write ); -protected: +//protected: // device-level overrides virtual void device_start() override; diff --git a/src/hardware/mame/sn76496.cpp b/src/hardware/mame/sn76496.cpp index bccb53c2..3f010380 100644 --- a/src/hardware/mame/sn76496.cpp +++ b/src/hardware/mame/sn76496.cpp @@ -128,7 +128,8 @@ #include "sn76496.h" #define MAX_OUTPUT 0x7fff - +//When you go over this create sample +#define RATE_MAX ( 1 << 30) sn76496_base_device::sn76496_base_device( const machine_config &mconfig, @@ -145,7 +146,7 @@ sn76496_base_device::sn76496_base_device( uint32_t clock) : device_t(mconfig, type, tag, owner, clock) , device_sound_interface(mconfig, *this) - , m_ready_handler(*this) +// , m_ready_handler(*this) , m_feedback_mask(feedbackmask) , m_whitenoise_tap1(noisetap1) , m_whitenoise_tap2(noisetap2) @@ -156,6 +157,7 @@ sn76496_base_device::sn76496_base_device( { } + sn76496_device::sn76496_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : sn76496_base_device(mconfig, SN76496, tag, 0x10000, 0x04, 0x08, false, false, 8, true, owner, clock) { @@ -206,17 +208,19 @@ segapsg_device::segapsg_device(const machine_config &mconfig, const char *tag, d { } - void sn76496_base_device::device_start() { - int sample_rate = clock()/2; + sample_rate = clock()/2; + rate_add = RATE_MAX; + rate_counter = 0; + int i; double out; int gain; - m_ready_handler.resolve_safe(); + //m_ready_handler.resolve_safe(); - m_sound = machine().sound().stream_alloc(*this, 0, (m_stereo? 2:1), sample_rate); + //m_sound = machine().sound().stream_alloc(*this, 0, (m_stereo? 2:1), sample_rate); for (i = 0; i < 4; i++) m_volume[i] = 0; @@ -264,14 +268,14 @@ void sn76496_base_device::device_start() m_ready_state = true; - register_for_save_states(); + //register_for_save_states(); } WRITE8_MEMBER( sn76496_base_device::stereo_w ) { - m_sound->update(); - if (m_stereo) m_stereo_mask = data; - else fatalerror("sn76496_base_device: Call to stereo write with mono chip!\n"); +// m_sound->update(); +// if (m_stereo) m_stereo_mask = data; +// else fatalerror("sn76496_base_device: Call to stereo write with mono chip!\n"); } void sn76496_base_device::write(uint8_t data) @@ -279,7 +283,7 @@ void sn76496_base_device::write(uint8_t data) int n, r, c; // update the output buffer before changing the registers - m_sound->update(); +// m_sound->update(); // set number of cycles until READY is active; this is always one // 'sample', i.e. it equals the clock divider exactly @@ -347,12 +351,12 @@ void sn76496_base_device::countdown_cycles() if (m_cycles_to_ready > 0) { m_cycles_to_ready--; - if (m_ready_state==true) m_ready_handler(CLEAR_LINE); + //if (m_ready_state==true) m_ready_handler(CLEAR_LINE); m_ready_state = false; } else { - if (m_ready_state==false) m_ready_handler(ASSERT_LINE); + //if (m_ready_state==false) m_ready_handler(ASSERT_LINE); m_ready_state = true; } } @@ -412,6 +416,12 @@ void sn76496_base_device::sound_stream_update(sound_stream &stream, stream_sampl } } + //Skip final generation if you don't need an actual sample + rate_counter += rate_add; + if (rate_counter < RATE_MAX) + continue; + rate_counter -= RATE_MAX; + if (m_stereo) { out = ((((m_stereo_mask & 0x10)!=0) && (m_output[0]!=0))? m_volume[0] : 0) @@ -433,13 +443,19 @@ void sn76496_base_device::sound_stream_update(sound_stream &stream, stream_sampl } if (m_negate) { out = -out; out2 = -out2; } - *(lbuffer++) = out; if (m_stereo) *(rbuffer++) = out2; samples--; } } + +void sn76496_base_device::convert_samplerate(int32_t target_rate) { + //Simple 10 bit shift for samplerate conversion + rate_add = (int32_t)( RATE_MAX * (target_rate / (double)sample_rate) ); + rate_counter = 0; +} + void sn76496_base_device::register_for_save_states() { save_item(NAME(m_vol_table)); @@ -472,3 +488,4 @@ DEFINE_DEVICE_TYPE(SN94624, sn94624_device, "sn94624", "SN94624") DEFINE_DEVICE_TYPE(NCR7496, ncr7496_device, "ncr7496", "NCR7496") DEFINE_DEVICE_TYPE(GAMEGEAR, gamegear_device, "gamegear_psg", "Game Gear PSG") DEFINE_DEVICE_TYPE(SEGAPSG, segapsg_device, "segapsg", "Sega VDP PSG") + diff --git a/src/hardware/mame/sn76496.h b/src/hardware/mame/sn76496.h index 22ad524e..0632aaad 100644 --- a/src/hardware/mame/sn76496.h +++ b/src/hardware/mame/sn76496.h @@ -17,21 +17,26 @@ DECLARE_DEVICE_TYPE(NCR7496, ncr7496_device) DECLARE_DEVICE_TYPE(GAMEGEAR, gamegear_device) DECLARE_DEVICE_TYPE(SEGAPSG, segapsg_device) +#if 0 + #define MCFG_SN76496_READY_HANDLER(cb) \ devcb = &sn76496_base_device::set_ready_handler(*device, (DEVCB_##cb)); +#endif + class sn76496_base_device : public device_t, public device_sound_interface { public: // static configuration helpers - template static devcb_base &set_ready_handler(device_t &device, Object &&cb) { return downcast(device).m_ready_handler.set_callback(std::forward(cb)); } +// template static devcb_base &set_ready_handler(device_t &device, Object &&cb) { return downcast(device).m_ready_handler.set_callback(std::forward(cb)); } DECLARE_WRITE8_MEMBER( stereo_w ); void write(uint8_t data); DECLARE_WRITE8_MEMBER( write ); - DECLARE_READ_LINE_MEMBER( ready_r ) { return m_ready_state ? 1 : 0; } +// DECLARE_READ_LINE_MEMBER( ready_r ) { return m_ready_state ? 1 : 0; } + void convert_samplerate(int32_t target_rate); protected: sn76496_base_device( const machine_config &mconfig, @@ -55,11 +60,13 @@ private: void register_for_save_states(); void countdown_cycles(); + + bool m_ready_state; - devcb_write_line m_ready_handler; + //devcb_write_line m_ready_handler; - sound_stream* m_sound; + //sound_stream* m_sound; const int32_t m_feedback_mask; // mask for feedback const int32_t m_whitenoise_tap1; // mask for white noise tap 1 (higher one, usually bit 14) @@ -80,6 +87,11 @@ private: int32_t m_count[4]; // Position within the waveform int32_t m_output[4]; // 1-bit output of each channel, pre-volume int32_t m_cycles_to_ready; // number of cycles until the READY line goes active + //Modifications for easier sample conversion + int32_t sample_rate; + //Sample rate conversion + int32_t rate_add; + int32_t rate_counter; }; // SN76496: Whitenoise verified, phase verified, periodic verified (by Michael Zapf) diff --git a/src/hardware/mame/ymf262.cpp b/src/hardware/mame/ymf262.cpp index f69c15da..1fc77a92 100644 --- a/src/hardware/mame/ymf262.cpp +++ b/src/hardware/mame/ymf262.cpp @@ -279,7 +279,7 @@ struct OPL3 int clock; /* master clock (Hz) */ int rate; /* sampling rate (Hz) */ double freqbase; /* frequency base */ - attotime TimerBase; /* Timer base time (==sampling time)*/ + //attotime TimerBase; /* Timer base time (==sampling time)*/ device_t *device; /* Optional handlers */ @@ -1351,7 +1351,7 @@ static void OPL3_initalize(OPL3 *chip) /* logerror("YMF262: freqbase=%f\n", chip->freqbase); */ /* Timer base time */ - chip->TimerBase = attotime::from_hz(chip->clock) * (8*36); + //chip->TimerBase = attotime::from_hz(chip->clock) * (8*36); /* make fnumber -> increment counter table */ for( i=0 ; i < 1024 ; i++ ) @@ -1745,6 +1745,7 @@ static void OPL3WriteReg(OPL3 *chip, int r, int v) case 0x03: /* Timer 2 */ chip->T[1] = (256-v)*16; break; +#if 0 case 0x04: /* IRQ clear / mask and Timer enable */ if(v&0x80) { /* IRQ flags clear */ @@ -1774,6 +1775,7 @@ static void OPL3WriteReg(OPL3 *chip, int r, int v) if (chip->timer_handler) (chip->timer_handler)(chip->TimerParam,0,period); } } +#endif break; case 0x08: /* x,NTS,x,x, x,x,x,x */ chip->nts = v; @@ -2356,7 +2358,7 @@ static OPL3 *OPL3Create(device_t *device, int clock, int rate, int type) if (OPL3_LockTable(device) == -1) return nullptr; /* allocate memory block */ - chip = auto_alloc_clear(device->machine(), ()); + chip = auto_alloc_clear(device->machine(), OPL3 ); chip->device = device; chip->type = type; @@ -2452,11 +2454,12 @@ static int OPL3TimerOver(OPL3 *chip,int c) OPL3_STATUS_SET(chip,0x40); } /* reload timer */ - if (chip->timer_handler) (chip->timer_handler)(chip->TimerParam,c,chip->TimerBase * chip->T[c]); +// if (chip->timer_handler) (chip->timer_handler)(chip->TimerParam,c,chip->TimerBase * chip->T[c]); return chip->status>>7; } static void OPL3_save_state(OPL3 *chip, device_t *device) { +#if 0 for (int ch=0; ch<18; ch++) { OPL3_CH *channel = &chip->P_CH[ch]; device->save_item(NAME(channel->block_fnum), ch); @@ -2521,6 +2524,7 @@ static void OPL3_save_state(OPL3 *chip, device_t *device) { device->save_item(NAME(chip->address)); device->save_item(NAME(chip->status)); device->save_item(NAME(chip->statusmask)); +#endif } void * ymf262_init(device_t *device, int clock, int rate) From 7ef98ed1bf73c127b327967cecc3453155b725f1 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 12 Aug 2017 09:26:38 +0000 Subject: [PATCH 3943/4131] Make the dosbox sound card implementations use the mame files directly Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/branches/mamesound@4033 --- src/dosbox.cpp | 2 +- src/hardware/adlib.cpp | 89 +++++++ src/hardware/gameblaster.cpp | 453 +++++------------------------------ src/hardware/tandy_sound.cpp | 276 ++------------------- 4 files changed, 172 insertions(+), 648 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 7308d8c5..d9a81612 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -558,7 +558,7 @@ void DOSBOX_Init(void) { Pstring->Set_values(oplmodes); Pstring->Set_help("Type of OPL emulation. On 'auto' the mode is determined by sblaster type. All OPL modes are Adlib-compatible, except for 'cms'."); - const char* oplemus[]={ "default", "compat", "fast", 0}; + const char* oplemus[]={ "default", "compat", "fast", "mame", 0}; Pstring = secprop->Add_string("oplemu",Property::Changeable::WhenIdle,"default"); Pstring->Set_values(oplemus); Pstring->Set_help("Provider for the OPL emulation. compat might provide better quality (see oplrate as well)."); diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 836a3e21..de56dcc6 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -28,6 +28,13 @@ #include "mem.h" #include "dbopl.h" +#include "mame/emu.h" +#include "mame/fmopl.h" +#include "mame/ymf262.h" + +#define OPL2_INTERNAL_FREQ 3600000 // The OPL2 operates at 3.6MHz +#define OPL3_INTERNAL_FREQ 14400000 // The OPL3 operates at 14.4MHz + namespace OPL2 { #include "opl.cpp" @@ -85,6 +92,80 @@ namespace OPL3 { }; } +namespace MAMEOPL2 { + +struct Handler : public Adlib::Handler { + void* chip; + + virtual void WriteReg(Bit32u reg, Bit8u val) { + ym3812_write(chip, 0, reg); + ym3812_write(chip, 1, val); + } + virtual Bit32u WriteAddr(Bit32u port, Bit8u val) { + return val; + } + virtual void Generate(MixerChannel* chan, Bitu samples) { + Bit16s buf[1024 * 2]; + while (samples > 0) { + Bitu todo = samples > 1024 ? 1024 : samples; + samples -= todo; + ym3812_update_one(chip, buf, todo); + chan->AddSamples_m16(todo, buf); + } + } + virtual void Init(Bitu rate) { + chip = ym3812_init(0, OPL2_INTERNAL_FREQ, rate); + } + ~Handler() { + ym3812_shutdown(chip); + } +}; + +} + + +namespace MAMEOPL3 { + +struct Handler : public Adlib::Handler { + void* chip; + + virtual void WriteReg(Bit32u reg, Bit8u val) { + ymf262_write(chip, 0, reg); + ymf262_write(chip, 1, val); + } + virtual Bit32u WriteAddr(Bit32u port, Bit8u val) { + return val; + } + virtual void Generate(MixerChannel* chan, Bitu samples) { + //We generate data for 4 channels, but only the first 2 are connected on a pc + Bit16s buf[4][1024]; + Bit16s result[1024][2]; + Bit16s* buffers[4] = { buf[0], buf[1], buf[2], buf[3] }; + + while (samples > 0) { + Bitu todo = samples > 1024 ? 1024 : samples; + samples -= todo; + ymf262_update_one(chip, buffers, todo); + //Interleave the samples before mixing + for (Bitu i = 0; i < todo; i++) { + result[i][0] = buf[0][i]; + result[i][1] = buf[1][i]; + } + chan->AddSamples_s16(todo, result[0]); + } + } + virtual void Init(Bitu rate) { + chip = ymf262_init(0, OPL3_INTERNAL_FREQ, rate); + } + ~Handler() { + ymf262_shutdown(chip); + } +}; + +} + + + #define RAW_SIZE 1024 @@ -717,6 +798,14 @@ Module::Module( Section* configuration ) : Module_base(configuration) { } else { handler = new OPL3::Handler(); } + } + else if (oplemu == "mame") { + if (oplmode == OPL_opl2) { + handler = new MAMEOPL2::Handler(); + } + else { + handler = new MAMEOPL3::Handler(); + } } else { handler = new DBOPL::Handler(); } diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index a3906054..dbe3b093 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -27,408 +27,75 @@ #include #include +#include "mame/emu.h" +#include "mame/saa1099.h" -#define LEFT 0x00 -#define RIGHT 0x01 -#define CMS_BUFFER_SIZE 128 -#define CMS_RATE 22050 -/*#define MASTER_CLOCK 14318180/2 */ #define MASTER_CLOCK 7159090 - -typedef Bit8u UINT8; -typedef Bit16s INT16; - -/* this structure defines a channel */ -struct saa1099_channel -{ - int frequency; /* frequency (0x00..0xff) */ - int freq_enable; /* frequency enable */ - int noise_enable; /* noise enable */ - int octave; /* octave (0x00..0x07) */ - int amplitude[2]; /* amplitude (0x00..0x0f) */ - int envelope[2]; /* envelope (0x00..0x0f or 0x10 == off) */ - - /* vars to simulate the square wave */ - double counter; - double freq; - int level; -}; - -/* this structure defines a noise channel */ -struct saa1099_noise -{ - /* vars to simulate the noise generator output */ - double counter; - double freq; - int level; /* noise polynomal shifter */ -}; - -/* this structure defines a SAA1099 chip */ -struct SAA1099 -{ - int stream; /* our stream */ - int noise_params[2]; /* noise generators parameters */ - int env_enable[2]; /* envelope generators enable */ - int env_reverse_right[2]; /* envelope reversed for right channel */ - int env_mode[2]; /* envelope generators mode */ - int env_bits[2]; /* non zero = 3 bits resolution */ - int env_clock[2]; /* envelope clock mode (non-zero external) */ - int env_step[2]; /* current envelope step */ - int all_ch_enable; /* all channels enable */ - int sync_state; /* sync all channels */ - int selected_reg; /* selected register */ - struct saa1099_channel channels[6]; /* channels */ - struct saa1099_noise noise[2]; /* noise generators */ -}; - -static const UINT8 envelope[8][64] = { - /* zero amplitude */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* maximum amplitude */ - {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, - 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, - 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, - 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, }, - /* single decay */ - {15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* repetitive decay */ - {15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, - 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, - 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, - 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, - /* single triangular */ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, - 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* repetitive triangular */ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, - 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, - 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, - /* single attack */ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* repetitive attack */ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 } -}; - - -static const int amplitude_lookup[16] = { - 0*32767/16, 1*32767/16, 2*32767/16, 3*32767/16, - 4*32767/16, 5*32767/16, 6*32767/16, 7*32767/16, - 8*32767/16, 9*32767/16, 10*32767/16, 11*32767/16, - 12*32767/16, 13*32767/16, 14*32767/16, 15*32767/16 -}; - -/* global parameters */ -static double sample_rate; -static SAA1099 saa1099[2]; +//My mixer channel static MixerChannel * cms_chan; -static Bit16s cms_buffer[2][2][CMS_BUFFER_SIZE]; -static Bit16s * cms_buf_point[4] = { - cms_buffer[0][0],cms_buffer[0][1],cms_buffer[1][0],cms_buffer[1][1] }; - -static Bitu last_command; -static Bitu base_port; - - -static void saa1099_envelope(int chip, int ch) -{ - struct SAA1099 *saa = &saa1099[chip]; - if (saa->env_enable[ch]) - { - int step, mode, mask; - mode = saa->env_mode[ch]; - /* step from 0..63 and then loop in steps 32..63 */ - step = saa->env_step[ch] = - ((saa->env_step[ch] + 1) & 0x3f) | (saa->env_step[ch] & 0x20); - - mask = 15; - if (saa->env_bits[ch]) - mask &= ~1; /* 3 bit resolution, mask LSB */ - - saa->channels[ch*3+0].envelope[ LEFT] = - saa->channels[ch*3+1].envelope[ LEFT] = - saa->channels[ch*3+2].envelope[ LEFT] = envelope[mode][step] & mask; - if (saa->env_reverse_right[ch] & 0x01) - { - saa->channels[ch*3+0].envelope[RIGHT] = - saa->channels[ch*3+1].envelope[RIGHT] = - saa->channels[ch*3+2].envelope[RIGHT] = (15 - envelope[mode][step]) & mask; - } - else - { - saa->channels[ch*3+0].envelope[RIGHT] = - saa->channels[ch*3+1].envelope[RIGHT] = - saa->channels[ch*3+2].envelope[RIGHT] = envelope[mode][step] & mask; - } - } - else - { - /* envelope mode off, set all envelope factors to 16 */ - saa->channels[ch*3+0].envelope[ LEFT] = - saa->channels[ch*3+1].envelope[ LEFT] = - saa->channels[ch*3+2].envelope[ LEFT] = - saa->channels[ch*3+0].envelope[RIGHT] = - saa->channels[ch*3+1].envelope[RIGHT] = - saa->channels[ch*3+2].envelope[RIGHT] = 16; - } -} - - -static void saa1099_update(int chip, INT16 **buffer, int length) -{ - struct SAA1099 *saa = &saa1099[chip]; - int j, ch; - - /* if the channels are disabled we're done */ - if (!saa->all_ch_enable) - { - /* init output data */ - memset(buffer[LEFT],0,length*sizeof(INT16)); - memset(buffer[RIGHT],0,length*sizeof(INT16)); - return; - } - - for (ch = 0; ch < 2; ch++) - { - switch (saa->noise_params[ch]) - { - case 0: saa->noise[ch].freq = MASTER_CLOCK/256 * 2; break; - case 1: saa->noise[ch].freq = MASTER_CLOCK/512 * 2; break; - case 2: saa->noise[ch].freq = MASTER_CLOCK/1024 * 2; break; - case 3: saa->noise[ch].freq = saa->channels[ch * 3].freq; break; - } - } - - /* fill all data needed */ - for( j = 0; j < length; j++ ) - { - int output_l = 0, output_r = 0; - - /* for each channel */ - for (ch = 0; ch < 6; ch++) - { - if (saa->channels[ch].freq == 0.0) - saa->channels[ch].freq = (double)((2 * MASTER_CLOCK/512) << saa->channels[ch].octave) / - (511.0 - (double)saa->channels[ch].frequency); - - /* check the actual position in the square wave */ - saa->channels[ch].counter -= saa->channels[ch].freq; - while (saa->channels[ch].counter < 0) - { - /* calculate new frequency now after the half wave is updated */ - saa->channels[ch].freq = (double)((2 * MASTER_CLOCK/512) << saa->channels[ch].octave) / - (511.0 - (double)saa->channels[ch].frequency); - - saa->channels[ch].counter += sample_rate; - saa->channels[ch].level ^= 1; - - /* eventually clock the envelope counters */ - if (ch == 1 && saa->env_clock[0] == 0) - saa1099_envelope(chip, 0); - if (ch == 4 && saa->env_clock[1] == 0) - saa1099_envelope(chip, 1); - } - - /* if the noise is enabled */ - if (saa->channels[ch].noise_enable) - { - /* if the noise level is high (noise 0: chan 0-2, noise 1: chan 3-5) */ - if (saa->noise[ch/3].level & 1) - { - /* subtract to avoid overflows, also use only half amplitude */ - output_l -= saa->channels[ch].amplitude[ LEFT] * saa->channels[ch].envelope[ LEFT] / 16 / 2; - output_r -= saa->channels[ch].amplitude[RIGHT] * saa->channels[ch].envelope[RIGHT] / 16 / 2; - } - } - - /* if the square wave is enabled */ - if (saa->channels[ch].freq_enable) - { - /* if the channel level is high */ - if (saa->channels[ch].level & 1) - { - output_l += saa->channels[ch].amplitude[ LEFT] * saa->channels[ch].envelope[ LEFT] / 16; - output_r += saa->channels[ch].amplitude[RIGHT] * saa->channels[ch].envelope[RIGHT] / 16; - } - } - } - - for (ch = 0; ch < 2; ch++) - { - /* check the actual position in noise generator */ - saa->noise[ch].counter -= saa->noise[ch].freq; - while (saa->noise[ch].counter < 0) - { - saa->noise[ch].counter += sample_rate; - if( ((saa->noise[ch].level & 0x4000) == 0) == ((saa->noise[ch].level & 0x0040) == 0) ) - saa->noise[ch].level = (saa->noise[ch].level << 1) | 1; - else - saa->noise[ch].level <<= 1; - } - } - /* write sound data to the buffer */ - buffer[LEFT][j] = output_l / 6; - buffer[RIGHT][j] = output_r / 6; - } -} - -static void saa1099_write_port_w( int chip, int offset, int data ) -{ - struct SAA1099 *saa = &saa1099[chip]; - if(offset == 1) { - // address port - saa->selected_reg = data & 0x1f; - if (saa->selected_reg == 0x18 || saa->selected_reg == 0x19) { - /* clock the envelope channels */ - if (saa->env_clock[0]) saa1099_envelope(chip,0); - if (saa->env_clock[1]) saa1099_envelope(chip,1); - } - return; - } - int reg = saa->selected_reg; - int ch; - - switch (reg) - { - /* channel i amplitude */ - case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: - ch = reg & 7; - saa->channels[ch].amplitude[LEFT] = amplitude_lookup[data & 0x0f]; - saa->channels[ch].amplitude[RIGHT] = amplitude_lookup[(data >> 4) & 0x0f]; - break; - /* channel i frequency */ - case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: - ch = reg & 7; - saa->channels[ch].frequency = data & 0xff; - break; - /* channel i octave */ - case 0x10: case 0x11: case 0x12: - ch = (reg - 0x10) << 1; - saa->channels[ch + 0].octave = data & 0x07; - saa->channels[ch + 1].octave = (data >> 4) & 0x07; - break; - /* channel i frequency enable */ - case 0x14: - saa->channels[0].freq_enable = data & 0x01; - saa->channels[1].freq_enable = data & 0x02; - saa->channels[2].freq_enable = data & 0x04; - saa->channels[3].freq_enable = data & 0x08; - saa->channels[4].freq_enable = data & 0x10; - saa->channels[5].freq_enable = data & 0x20; - break; - /* channel i noise enable */ - case 0x15: - saa->channels[0].noise_enable = data & 0x01; - saa->channels[1].noise_enable = data & 0x02; - saa->channels[2].noise_enable = data & 0x04; - saa->channels[3].noise_enable = data & 0x08; - saa->channels[4].noise_enable = data & 0x10; - saa->channels[5].noise_enable = data & 0x20; - break; - /* noise generators parameters */ - case 0x16: - saa->noise_params[0] = data & 0x03; - saa->noise_params[1] = (data >> 4) & 0x03; - break; - /* envelope generators parameters */ - case 0x18: case 0x19: - ch = reg - 0x18; - saa->env_reverse_right[ch] = data & 0x01; - saa->env_mode[ch] = (data >> 1) & 0x07; - saa->env_bits[ch] = data & 0x10; - saa->env_clock[ch] = data & 0x20; - saa->env_enable[ch] = data & 0x80; - /* reset the envelope */ - saa->env_step[ch] = 0; - break; - /* channels enable & reset generators */ - case 0x1c: - saa->all_ch_enable = data & 0x01; - saa->sync_state = data & 0x02; - if (data & 0x02) - { - int i; -// logerror("%04x: (SAA1099 #%d) -reg 0x1c- Chip reset\n",activecpu_get_pc(), chip); - /* Synch & Reset generators */ - for (i = 0; i < 6; i++) - { - saa->channels[i].level = 0; - saa->channels[i].counter = 0.0; - } - } - break; - default: /* Error! */ -// logerror("%04x: (SAA1099 #%d) Unknown operation (reg:%02x, data:%02x)\n",activecpu_get_pc(), chip, reg, data); - LOG(LOG_MISC,LOG_ERROR)("CMS Unkown write to reg %x with %x",reg, data); - } -} +//Timer to disable the channel after a while +static Bit32u lastWriteTicks; +static Bit32u cmsBase; +static saa1099_device* device[2]; static void write_cms(Bitu port, Bitu val, Bitu /* iolen */) { if(cms_chan && (!cms_chan->enabled)) cms_chan->Enable(true); - last_command = PIC_Ticks; - switch (port-base_port) { - case 0: - saa1099_write_port_w(0,0,val); - break; + lastWriteTicks = PIC_Ticks; + switch ( port - cmsBase ) { case 1: - saa1099_write_port_w(0,1,val); + device[0]->control_w(0, 0, val); break; - case 2: - saa1099_write_port_w(1,0,val); + case 0: + device[0]->data_w(0, 0, val); break; case 3: - saa1099_write_port_w(1,1,val); + device[1]->control_w(0, 0, val); + break; + case 2: + device[1]->data_w(0, 0, val); break; } } static void CMS_CallBack(Bitu len) { - if (len > CMS_BUFFER_SIZE) return; + enum { + BUFFER_SIZE = 2048 + }; - saa1099_update(0, &cms_buf_point[0], (int)len); - saa1099_update(1, &cms_buf_point[2], (int)len); + if ( len > BUFFER_SIZE ) + return; - Bit16s * stream=(Bit16s *) MixTemp; - /* Mix chip outputs */ - for (Bitu l=0;lMAX_AUDIO) *stream=MAX_AUDIO; - else if (leftMAX_AUDIO) *stream=MAX_AUDIO; - else if (rightEnable( false ); + return; + } + Bit32s result[BUFFER_SIZE][2]; + Bit16s work[2][BUFFER_SIZE]; + Bit16s* buffers[2] = { work[0], work[1] }; + device_sound_interface::sound_stream stream; + device[0]->sound_stream_update(stream, 0, buffers, len); + for (Bitu i = 0; i < len; i++) { + result[i][0] = work[0][i]; + result[i][1] = work[1][i]; + } + device[1]->sound_stream_update(stream, 0, buffers, len); + for (Bitu i = 0; i < len; i++) { + result[i][0] += work[0][i]; + result[i][1] += work[1][i]; + } + cms_chan->AddSamples_s32( len, result[0] ); } - if(cms_chan) cms_chan->AddSamples_s16(len,(Bit16s *)MixTemp); - if (last_command + 10000 < PIC_Ticks) if(cms_chan) cms_chan->Enable(false); } // The Gameblaster detection static Bit8u cms_detect_register = 0xff; static void write_cms_detect(Bitu port, Bitu val, Bitu /* iolen */) { - switch(port-base_port) { + switch ( port - cmsBase ) { case 0x6: case 0x7: cms_detect_register = val; @@ -438,7 +105,7 @@ static void write_cms_detect(Bitu port, Bitu val, Bitu /* iolen */) { static Bitu read_cms_detect(Bitu port, Bitu /* iolen */) { Bit8u retval = 0xff; - switch(port-base_port) { + switch ( port - cmsBase ) { case 0x4: retval = 0x7f; break; @@ -461,31 +128,37 @@ private: public: CMS(Section* configuration):Module_base(configuration) { Section_prop * section = static_cast(configuration); - Bitu sample_rate_temp = section->Get_int("oplrate"); - sample_rate = static_cast(sample_rate_temp); - base_port = section->Get_hex("sbbase"); - WriteHandler.Install(base_port, write_cms, IO_MB,4); + Bitu sampleRate = section->Get_int( "oplrate" ); + cmsBase = section->Get_hex("sbbase"); + WriteHandler.Install( cmsBase, write_cms, IO_MB, 4 ); // A standalone Gameblaster has a magic chip on it which is // sometimes used for detection. const char * sbtype=section->Get_string("sbtype"); if (!strcasecmp(sbtype,"gb")) { - DetWriteHandler.Install(base_port+4,write_cms_detect,IO_MB,12); - DetReadHandler.Install(base_port,read_cms_detect,IO_MB,16); + DetWriteHandler.Install( cmsBase + 4, write_cms_detect, IO_MB, 12 ); + DetReadHandler.Install(cmsBase,read_cms_detect,IO_MB,16); } /* Register the Mixer CallBack */ - cms_chan = MixerChan.Install(CMS_CallBack,sample_rate_temp,"CMS"); + cms_chan = MixerChan.Install(CMS_CallBack,sampleRate,"CMS"); - last_command = PIC_Ticks; - - for (int s=0;s<2;s++) { - struct SAA1099 *saa = &saa1099[s]; - memset(saa, 0, sizeof(struct SAA1099)); - } + lastWriteTicks = PIC_Ticks; + + Bit32u freq = 7159000; //14318180 isa clock / 2 + + machine_config config; + device[0] = new saa1099_device(config, "", 0, 7159090); + device[1] = new saa1099_device(config, "", 0, 7159090); + + device[0]->device_start(); + device[1]->device_start(); } + ~CMS() { cms_chan = 0; + delete device[0]; + delete device[1]; } }; diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 5d3ef2ea..3aef0ba7 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -30,47 +30,11 @@ #include "hardware.h" #include #include - -#define MAX_OUTPUT 0x7fff -#define STEP 0x10000 - -/* Formulas for noise generator */ -/* bit0 = output */ - -/* noise feedback for white noise mode (verified on real SN76489 by John Kortink) */ -#define FB_WNOISE 0x14002 /* (16bits) bit16 = bit0(out) ^ bit2 ^ bit15 */ - -/* noise feedback for periodic noise mode */ -//#define FB_PNOISE 0x10000 /* 16bit rorate */ -#define FB_PNOISE 0x08000 /* JH 981127 - fixes Do Run Run */ - -/* -0x08000 is definitely wrong. The Master System conversion of Marble Madness -uses periodic noise as a baseline. With a 15-bit rotate, the bassline is -out of tune. -The 16-bit rotate has been confirmed against a real PAL Sega Master System 2. -Hope that helps the System E stuff, more news on the PSG as and when! -*/ - -/* noise generator start preset (for periodic noise) */ -#define NG_PRESET 0x0f35 +#include "mame/emu.h" +#include "mame/sn76496.h" -struct SN76496 { - int SampleRate; - unsigned int UpdateStep; - int VolTable[16]; /* volume table */ - int Register[8]; /* registers */ - int LastRegister; /* last register written */ - int Volume[4]; /* volume of voice 0-2 and noise */ - unsigned int RNG; /* noise generator */ - int NoiseFB; /* noise feedback mask */ - int Period[4]; - int Count[4]; - int Output[4]; -}; - -static struct SN76496 sn; +#define SOUND_CLOCK (14318180 / 4) #define TDAC_DMA_BUFSIZE 1024 @@ -99,221 +63,36 @@ static struct { } dac; } tandy; +static sn76496_device device(machine_config(), 0, 0, SOUND_CLOCK ); + static void SN76496Write(Bitu /*port*/,Bitu data,Bitu /*iolen*/) { - struct SN76496 *R = &sn; - tandy.last_write=PIC_Ticks; if (!tandy.enabled) { tandy.chan->Enable(true); tandy.enabled=true; } - - /* update the output buffer before changing the registers */ - - if (data & 0x80) - { - int r = (data & 0x70) >> 4; - int c = r/2; - - R->LastRegister = r; - R->Register[r] = (R->Register[r] & 0x3f0) | (data & 0x0f); - switch (r) - { - case 0: /* tone 0 : frequency */ - case 2: /* tone 1 : frequency */ - case 4: /* tone 2 : frequency */ - R->Period[c] = R->UpdateStep * R->Register[r]; - if (R->Period[c] == 0) R->Period[c] = 0x3fe; - if (r == 4) - { - /* update noise shift frequency */ - if ((R->Register[6] & 0x03) == 0x03) - R->Period[3] = 2 * R->Period[2]; - } - break; - case 1: /* tone 0 : volume */ - case 3: /* tone 1 : volume */ - case 5: /* tone 2 : volume */ - case 7: /* noise : volume */ - R->Volume[c] = R->VolTable[data & 0x0f]; - break; - case 6: /* noise : frequency, mode */ - { - int n = R->Register[6]; - R->NoiseFB = (n & 4) ? FB_WNOISE : FB_PNOISE; - n &= 3; - /* N/512,N/1024,N/2048,Tone #3 output */ - R->Period[3] = (n == 3) ? 2 * R->Period[2] : (R->UpdateStep << (5+n)); - - /* reset noise shifter */ -// R->RNG = NG_PRESET; -// R->Output[3] = R->RNG & 1; - } - break; - } - } - else - { - int r = R->LastRegister; - int c = r/2; - - switch (r) - { - case 0: /* tone 0 : frequency */ - case 2: /* tone 1 : frequency */ - case 4: /* tone 2 : frequency */ - R->Register[r] = (R->Register[r] & 0x0f) | ((data & 0x3f) << 4); - R->Period[c] = R->UpdateStep * R->Register[r]; - if (R->Period[c] == 0) R->Period[c] = 0x3fe; - if (r == 4) - { - /* update noise shift frequency */ - if ((R->Register[6] & 0x03) == 0x03) - R->Period[3] = 2 * R->Period[2]; - } - break; - } - } + device.write(data); } static void SN76496Update(Bitu length) { + //Disable the channel if it's been quiet for a while if ((tandy.last_write+5000)Enable(false); + return; } - int i; - struct SN76496 *R = &sn; - Bit16s * buffer=(Bit16s *)MixTemp; + const Bitu MAX_SAMPLES = 2048; + if (length > MAX_SAMPLES) + return; + Bit16s buffer[MAX_SAMPLES]; + Bit16s* outputs = buffer; - /* If the volume is 0, increase the counter */ - for (i = 0;i < 4;i++) - { - if (R->Volume[i] == 0) - { - /* note that I do count += length, NOT count = length + 1. You might think */ - /* it's the same since the volume is 0, but doing the latter could cause */ - /* interferencies when the program is rapidly modulating the volume. */ - if (R->Count[i] <= (int)length*STEP) R->Count[i] += length*STEP; - } - } - - Bitu count=length; - while (count) - { - int vol[4]; - unsigned int out; - int left; - - - /* vol[] keeps track of how long each square wave stays */ - /* in the 1 position during the sample period. */ - vol[0] = vol[1] = vol[2] = vol[3] = 0; - - for (i = 0;i < 3;i++) - { - if (R->Output[i]) vol[i] += R->Count[i]; - R->Count[i] -= STEP; - /* Period[i] is the half period of the square wave. Here, in each */ - /* loop I add Period[i] twice, so that at the end of the loop the */ - /* square wave is in the same status (0 or 1) it was at the start. */ - /* vol[i] is also incremented by Period[i], since the wave has been 1 */ - /* exactly half of the time, regardless of the initial position. */ - /* If we exit the loop in the middle, Output[i] has to be inverted */ - /* and vol[i] incremented only if the exit status of the square */ - /* wave is 1. */ - while (R->Count[i] <= 0) - { - R->Count[i] += R->Period[i]; - if (R->Count[i] > 0) - { - R->Output[i] ^= 1; - if (R->Output[i]) vol[i] += R->Period[i]; - break; - } - R->Count[i] += R->Period[i]; - vol[i] += R->Period[i]; - } - if (R->Output[i]) vol[i] -= R->Count[i]; - } - - left = STEP; - do - { - int nextevent; - - - if (R->Count[3] < left) nextevent = R->Count[3]; - else nextevent = left; - - if (R->Output[3]) vol[3] += R->Count[3]; - R->Count[3] -= nextevent; - if (R->Count[3] <= 0) - { - if (R->RNG & 1) R->RNG ^= R->NoiseFB; - R->RNG >>= 1; - R->Output[3] = R->RNG & 1; - R->Count[3] += R->Period[3]; - if (R->Output[3]) vol[3] += R->Period[3]; - } - if (R->Output[3]) vol[3] -= R->Count[3]; - - left -= nextevent; - } while (left > 0); - - out = vol[0] * R->Volume[0] + vol[1] * R->Volume[1] + - vol[2] * R->Volume[2] + vol[3] * R->Volume[3]; - - if (out > MAX_OUTPUT * STEP) out = MAX_OUTPUT * STEP; - - *(buffer++) = (Bit16s)(out / STEP); - - count--; - } - tandy.chan->AddSamples_m16(length,(Bit16s *)MixTemp); + device_sound_interface::sound_stream stream; + static_cast(device).sound_stream_update(stream, 0, &outputs, length); + tandy.chan->AddSamples_m16(length, buffer); } - - -static void SN76496_set_clock(int clock) { - struct SN76496 *R = &sn; - - /* the base clock for the tone generators is the chip clock divided by 16; */ - /* for the noise generator, it is clock / 256. */ - /* Here we calculate the number of steps which happen during one sample */ - /* at the given sample rate. No. of events = sample rate / (clock/16). */ - /* STEP is a multiplier used to turn the fraction into a fixed point */ - /* number. */ - R->UpdateStep = (unsigned int)(((double)STEP * R->SampleRate * 16) / clock); -} - - -static void SN76496_set_gain(int gain) { - struct SN76496 *R = &sn; - int i; - double out; - - gain &= 0xff; - - /* increase max output basing on gain (0.2 dB per step) */ - out = MAX_OUTPUT / 3; - while (gain-- > 0) - out *= 1.023292992; /* = (10 ^ (0.2/20)) */ - - /* build volume table (2dB per step) */ - for (i = 0;i < 15;i++) - { - /* limit volume to avoid clipping */ - if (out > MAX_OUTPUT / 3) R->VolTable[i] = MAX_OUTPUT / 3; - else R->VolTable[i] = (int)out; - - out /= 1.258925412; /* = 10 ^ (2/20) = 2dB */ - } - R->VolTable[15] = 0; -} - - - bool TS_Get_Address(Bitu& tsaddr, Bitu& tsirq, Bitu& tsdma) { tsaddr=0; tsirq =0; @@ -548,26 +327,9 @@ public: tandy.enabled=false; real_writeb(0x40,0xd4,0xff); /* BIOS Tandy DAC initialization value */ - Bitu i; - struct SN76496 *R = &sn; - R->SampleRate = sample_rate; - SN76496_set_clock(3579545); - for (i = 0;i < 4;i++) R->Volume[i] = 0; - R->LastRegister = 0; - for (i = 0;i < 8;i+=2) - { - R->Register[i] = 0; - R->Register[i + 1] = 0x0f; /* volume = 0 */ - } - - for (i = 0;i < 4;i++) - { - R->Output[i] = 0; - R->Period[i] = R->Count[i] = R->UpdateStep; - } - R->RNG = NG_PRESET; - R->Output[3] = R->RNG & 1; - SN76496_set_gain(0x1); + ((device_t&)device).device_start(); + device.convert_samplerate(sample_rate); + } ~TANDYSOUND(){ } }; From 5845ca5592799c258c46933400620d32cc8f0ea4 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 13 Aug 2017 10:38:28 +0000 Subject: [PATCH 3944/4131] Remove some unneeded c++11 that's not even compiling properly Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/branches/mamesound@4034 --- src/hardware/mame/fmopl.cpp | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/src/hardware/mame/fmopl.cpp b/src/hardware/mame/fmopl.cpp index 36414cb7..53154e43 100644 --- a/src/hardware/mame/fmopl.cpp +++ b/src/hardware/mame/fmopl.cpp @@ -106,8 +106,20 @@ Revision History: #define SIN_BITS 10 #define SIN_LEN (1<> 4 ) +#define LFO_AM_TAB_ELEMENTS 210 @@ -227,7 +239,7 @@ struct OPL_SLOT uint32_t TL; /* total level: TL << 2 */ int32_t TLL; /* adjusted now TL */ int32_t volume; /* envelope counter */ - uint32_t sl; /* sustain level: sl_tab[SL] */ + int32_t sl; /* sustain level: sl_tab[SL] */ uint8_t eg_sh_ar; /* (attack state) */ uint8_t eg_sel_ar; /* (attack state) */ uint8_t eg_sh_dr; /* (decay state) */ @@ -970,26 +982,9 @@ private: #endif } - - static constexpr uint32_t SC(uint32_t db) { return uint32_t(db * (2.0 / ENV_STEP)); } - - - static constexpr double DV = 0.1875 / 2.0; - - - /* TL_TAB_LEN is calculated as: - * 12 - sinus amplitude bits (Y axis) - * 2 - sinus sign bit (Y axis) - * TL_RES_LEN - sinus resolution (X axis) - */ - static constexpr unsigned TL_TAB_LEN = 12 * 2 * TL_RES_LEN; - static constexpr unsigned ENV_QUIET = TL_TAB_LEN >> 4; - - static constexpr unsigned LFO_AM_TAB_ELEMENTS = 210; - static const double ksl_tab[8*16]; static const uint32_t ksl_shift[4]; - static const uint32_t sl_tab[16]; + static const int32_t sl_tab[16]; static const unsigned char eg_inc[15 * RATE_STEPS]; static const uint8_t mul_tab[16]; @@ -1066,7 +1061,8 @@ const uint32_t FM_OPL::ksl_shift[4] = { 31, 1, 2, 0 }; /* sustain level table (3dB per step) */ /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ -const uint32_t FM_OPL::sl_tab[16]={ +#define SC(db) int32_t(db * (2.0 / ENV_STEP)) +const int32_t FM_OPL::sl_tab[16]={ SC( 0),SC( 1),SC( 2),SC( 3),SC( 4),SC( 5),SC( 6),SC( 7), SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31) }; From 06b5f723b0d584a780ec28ff93a94c16d517e22d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 24 Aug 2017 13:01:15 +0000 Subject: [PATCH 3945/4131] Update automake files for mame files Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/branches/mamesound@4035 --- configure.ac | 1 + src/Makefile.am | 3 ++- src/hardware/Makefile.am | 2 +- src/hardware/mame/Makefile.am | 9 +++++++++ 4 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 src/hardware/mame/Makefile.am diff --git a/configure.ac b/configure.ac index dc2aa0ff..4f67fc32 100644 --- a/configure.ac +++ b/configure.ac @@ -533,6 +533,7 @@ src/dos/Makefile src/fpu/Makefile src/gui/Makefile src/hardware/Makefile +src/hardware/mame/Makefile src/hardware/serialport/Makefile src/ints/Makefile src/libs/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index 184469e0..a4029e83 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,7 +13,8 @@ endif 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 \ - 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 hardware/mame/libmame.a \ + hardware/serialport/libserial.a libs/gui_tk/libgui_tk.a EXTRA_DIST = winres.rc dosbox.ico diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index 1ec7e67d..2d739482 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -1,6 +1,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -SUBDIRS = serialport +SUBDIRS = serialport mame EXTRA_DIST = opl.cpp opl.h adlib.h dbopl.h pci_devices.h diff --git a/src/hardware/mame/Makefile.am b/src/hardware/mame/Makefile.am new file mode 100644 index 00000000..52f7f000 --- /dev/null +++ b/src/hardware/mame/Makefile.am @@ -0,0 +1,9 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include + +noinst_LIBRARIES = libmame.a +libmame_a_SOURCES = emu.h \ + fmopl.cpp fmopl.h \ + saa1099.cpp saa1099.h \ + sn76496.cpp sn76496.cpp \ + ymdeltat.cpp ymdeltat.h \ + ymf262.cpp ymf262.h From c4da3879ace9f0bc137eeaa0f061d3fa03e86ad0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sat, 26 Aug 2017 05:49:40 +0000 Subject: [PATCH 3946/4131] Remove come c++11 stuff and hope I don't break anything Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/branches/mamesound@4036 --- src/hardware/mame/fmopl.cpp | 17 +++++++---- src/hardware/mame/saa1099.cpp | 18 ++++++++++-- src/hardware/mame/saa1099.h | 52 +++++++++++++++++++++++++--------- src/hardware/mame/sn76496.cpp | 2 +- src/hardware/mame/sn76496.h | 4 +-- src/hardware/mame/ymdeltat.cpp | 6 ++-- src/hardware/mame/ymdeltat.h | 6 ++-- src/hardware/mame/ymf262.cpp | 4 +-- 8 files changed, 77 insertions(+), 32 deletions(-) diff --git a/src/hardware/mame/fmopl.cpp b/src/hardware/mame/fmopl.cpp index 53154e43..90b88345 100644 --- a/src/hardware/mame/fmopl.cpp +++ b/src/hardware/mame/fmopl.cpp @@ -1766,10 +1766,15 @@ void FM_OPL::ResetChip() for(int i = 0xff ; i >= 0x20 ; i-- ) WriteReg(i,0); /* reset operator parameters */ - for(OPL_CH &CH : P_CH) +// for(OPL_CH &CH : P_CH) + for(int ch = 0; ch < sizeof( P_CH )/ sizeof(P_CH[0]); ch++) { - for(OPL_SLOT &SLOT : CH.SLOT) + OPL_CH &CH = P_CH[ch]; +// for(OPL_SLOT &SLOT : CH.SLOT) + for(int slot = 0; slot < sizeof( CH.SLOT ) / sizeof( CH.SLOT[0]); slot++) { + + OPL_SLOT &SLOT = CH.SLOT[slot]; /* wave table */ SLOT.wavetable = 0; SLOT.state = EG_OFF; @@ -1793,15 +1798,17 @@ void FM_OPL::ResetChip() void FM_OPL::postload() { - for(OPL_CH &CH : P_CH) + for(int ch = 0; ch < sizeof( P_CH )/ sizeof(P_CH[0]); ch++) { + OPL_CH &CH = P_CH[ch]; /* Look up key scale level */ uint32_t const block_fnum = CH.block_fnum; CH.ksl_base = static_cast(ksl_tab[block_fnum >> 6]); CH.fc = fn_tab[block_fnum & 0x03ff] >> (7 - (block_fnum >> 10)); - for(OPL_SLOT &SLOT : CH.SLOT) + for(int slot = 0; slot < sizeof( CH.SLOT ) / sizeof( CH.SLOT[0]); slot++) { + OPL_SLOT &SLOT = CH.SLOT[slot]; /* Calculate key scale rate */ SLOT.ksr = CH.kcode >> SLOT.KSR; @@ -1955,7 +1962,7 @@ static FM_OPL *OPLCreate(device_t *device, uint32_t clock, uint32_t rate, int ty FM_OPL *OPL; int state_size; - if (FM_OPL::LockTable(device) == -1) return nullptr; + if (FM_OPL::LockTable(device) == -1) return 0; /* calculate OPL state size */ state_size = sizeof(FM_OPL); diff --git a/src/hardware/mame/saa1099.cpp b/src/hardware/mame/saa1099.cpp index f588358a..7f9823e9 100644 --- a/src/hardware/mame/saa1099.cpp +++ b/src/hardware/mame/saa1099.cpp @@ -73,14 +73,14 @@ #define LEFT 0x00 #define RIGHT 0x01 -static constexpr int amplitude_lookup[16] = { +static const int amplitude_lookup[16] = { 0*32767/16, 1*32767/16, 2*32767/16, 3*32767/16, 4*32767/16, 5*32767/16, 6*32767/16, 7*32767/16, 8*32767/16, 9*32767/16, 10*32767/16, 11*32767/16, 12*32767/16, 13*32767/16, 14*32767/16, 15*32767/16 }; -static constexpr uint8_t envelope[8][64] = { +static const uint8_t envelope[8][64] = { /* zero amplitude */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -136,10 +136,13 @@ static constexpr uint8_t envelope[8][64] = { // saa1099_device - constructor //------------------------------------------------- +#define FILL_ARRAY( _FILL_ ) memset( _FILL_, 0, sizeof( _FILL_ ) ) + saa1099_device::saa1099_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, SAA1099, tag, owner, clock) , device_sound_interface(mconfig, *this) - , m_stream(nullptr) + , m_stream(0) +#if 0 , m_noise_params{ 0, 0 } , m_env_enable{ 0, 0 } , m_env_reverse_right{ 0, 0 } @@ -147,11 +150,20 @@ saa1099_device::saa1099_device(const machine_config &mconfig, const char *tag, d , m_env_bits{ 0, 0 } , m_env_clock{ 0, 0 } , m_env_step{ 0, 0 } +#endif , m_all_ch_enable(0) , m_sync_state(0) , m_selected_reg(0) , m_sample_rate(0.0) { + FILL_ARRAY( m_noise_params ); + FILL_ARRAY( m_env_enable ); + FILL_ARRAY( m_env_reverse_right ); + FILL_ARRAY( m_env_mode ); + FILL_ARRAY( m_env_bits ); + FILL_ARRAY( m_env_clock ); + FILL_ARRAY( m_env_step ); + } diff --git a/src/hardware/mame/saa1099.h b/src/hardware/mame/saa1099.h index ee763454..cce4fb55 100644 --- a/src/hardware/mame/saa1099.h +++ b/src/hardware/mame/saa1099.h @@ -23,6 +23,22 @@ // TYPE DEFINITIONS //************************************************************************** +//Container class for int that just initalizes to 0 +class NullInt { + int value; +public: + operator int& () { + return value; + } + + int& operator= ( int set ) { + value = set; + return value; + } + + NullInt( int set = 0 ) : value( set ) { + } +}; // ======================> saa1099_device @@ -39,37 +55,45 @@ public: //protected: // device-level overrides - virtual void device_start() override; + virtual void device_start(); // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); private: struct saa1099_channel { - saa1099_channel() : amplitude{ 0, 0 }, envelope{ 0, 0 } { } + saa1099_channel() { + //Quite hacky, but let's see how it goes + memset( this, 0, sizeof( *this ) ); + } - int frequency = 0; /* frequency (0x00..0xff) */ - int freq_enable = 0; /* frequency enable */ - int noise_enable = 0; /* noise enable */ - int octave = 0; /* octave (0x00..0x07) */ + int frequency ; /* frequency (0x00..0xff) */ + int freq_enable ; /* frequency enable */ + int noise_enable ; /* noise enable */ + int octave ; /* octave (0x00..0x07) */ int amplitude[2]; /* amplitude (0x00..0x0f) */ int envelope[2]; /* envelope (0x00..0x0f or 0x10 == off) */ /* vars to simulate the square wave */ - double counter = 0.0; - double freq = 0.0; - int level = 0; + double counter ; + double freq ; + int level ; + }; struct saa1099_noise { - saa1099_noise() { } + saa1099_noise() { + counter = 0; + freq = 0; + level = 0xFFFFFFFF; + } /* vars to simulate the noise generator output */ - double counter = 0.0; - double freq = 0.0; - uint32_t level = 0xFFFFFFFF; /* noise polynomial shifter */ + double counter; + double freq; + uint32_t level; /* noise polynomial shifter */ }; void envelope_w(int ch); diff --git a/src/hardware/mame/sn76496.cpp b/src/hardware/mame/sn76496.cpp index 3f010380..b2e3be6a 100644 --- a/src/hardware/mame/sn76496.cpp +++ b/src/hardware/mame/sn76496.cpp @@ -365,7 +365,7 @@ void sn76496_base_device::sound_stream_update(sound_stream &stream, stream_sampl { int i; stream_sample_t *lbuffer = outputs[0]; - stream_sample_t *rbuffer = (m_stereo)? outputs[1] : nullptr; + stream_sample_t *rbuffer = (m_stereo)? outputs[1] : 0; int16_t out; int16_t out2 = 0; diff --git a/src/hardware/mame/sn76496.h b/src/hardware/mame/sn76496.h index 0632aaad..a2bdb993 100644 --- a/src/hardware/mame/sn76496.h +++ b/src/hardware/mame/sn76496.h @@ -52,8 +52,8 @@ protected: device_t *owner, uint32_t clock); - virtual void device_start() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void device_start(); + virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); private: inline bool in_noise_mode(); diff --git a/src/hardware/mame/ymdeltat.cpp b/src/hardware/mame/ymdeltat.cpp index 29e05b4e..e5170138 100644 --- a/src/hardware/mame/ymdeltat.cpp +++ b/src/hardware/mame/ymdeltat.cpp @@ -80,13 +80,13 @@ /* Forecast to next Forecast (rate = *8) */ /* 1/8 , 3/8 , 5/8 , 7/8 , 9/8 , 11/8 , 13/8 , 15/8 */ -static constexpr int32_t ym_deltat_decode_tableB1[16] = { +static const int32_t ym_deltat_decode_tableB1[16] = { 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, }; /* delta to next delta (rate= *64) */ /* 0.9 , 0.9 , 0.9 , 0.9 , 1.2 , 1.6 , 2.0 , 2.4 */ -static constexpr int32_t ym_deltat_decode_tableB2[16] = { +static const int32_t ym_deltat_decode_tableB2[16] = { 57, 57, 57, 57, 77, 102, 128, 153, 57, 57, 57, 57, 77, 102, 128, 153 }; @@ -152,7 +152,7 @@ uint8_t YM_DELTAT::ADPCM_Read() /* 0-DRAM x1, 1-ROM, 2-DRAM x8, 3-ROM (3 is bad setting - not allowed by the manual) */ -static constexpr uint8_t dram_rightshift[4]={3,0,0,0}; +static const uint8_t dram_rightshift[4]={3,0,0,0}; /* DELTA-T ADPCM write register */ void YM_DELTAT::ADPCM_Write(int r, int v) diff --git a/src/hardware/mame/ymdeltat.h b/src/hardware/mame/ymdeltat.h index f52bd46f..ad9e92ee 100644 --- a/src/hardware/mame/ymdeltat.h +++ b/src/hardware/mame/ymdeltat.h @@ -11,8 +11,10 @@ typedef void (*STATUS_CHANGE_HANDLER)(void *chip, uint8_t status_bits); /* DELTA-T (adpcm type B) struct */ struct YM_DELTAT { /* AT: rearranged and tightened structure */ - static constexpr int EMULATION_MODE_NORMAL = 0; - static constexpr int EMULATION_MODE_YM2610 = 1; + enum { + EMULATION_MODE_NORMAL = 0, + EMULATION_MODE_YM2610 = 1, + }; uint8_t *memory; int32_t *output_pointer;/* pointer of output pointers */ diff --git a/src/hardware/mame/ymf262.cpp b/src/hardware/mame/ymf262.cpp index 1fc77a92..98056c5d 100644 --- a/src/hardware/mame/ymf262.cpp +++ b/src/hardware/mame/ymf262.cpp @@ -628,7 +628,7 @@ static int num_lock = 0; static inline void OPL3_SLOT_CONNECT(OPL3 *chip, OPL3_SLOT *slot) { if (slot->conn_enum == CONN_NULL) { - slot->connect = nullptr; + slot->connect = 0; } else if (slot->conn_enum >= CONN_CHAN0 && slot->conn_enum < CONN_PHASEMOD) { slot->connect = &chip->chanout[slot->conn_enum]; } else if (slot->conn_enum == CONN_PHASEMOD) { @@ -2355,7 +2355,7 @@ static OPL3 *OPL3Create(device_t *device, int clock, int rate, int type) { OPL3 *chip; - if (OPL3_LockTable(device) == -1) return nullptr; + if (OPL3_LockTable(device) == -1) return 0; /* allocate memory block */ chip = auto_alloc_clear(device->machine(), OPL3 ); From 616784c385feb32a8c7ffb7b99a856d983281525 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 2 Sep 2017 08:13:13 +0000 Subject: [PATCH 3947/4131] Increase prebuffer slightly, as certain things (create new surfaces) take a longer time nowadays. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4037 --- src/dosbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 7308d8c5..2fd3d336 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -498,7 +498,7 @@ void DOSBOX_Init(void) { Pint->Set_values(blocksizes); Pint->Set_help("Mixer block size, larger blocks might help sound stuttering but sound will also be more lagged."); - Pint = secprop->Add_int("prebuffer",Property::Changeable::OnlyAtStart,20); + Pint = secprop->Add_int("prebuffer",Property::Changeable::OnlyAtStart,25); Pint->SetMinMax(0,100); Pint->Set_help("How many milliseconds of data to keep on top of the blocksize."); From 33da572d9e4cd5fbf9d63d79de93dc174724c451 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 2 Sep 2017 08:13:49 +0000 Subject: [PATCH 3948/4131] Change adaptive rate parameters slightly, so that is a less jumpy Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4038 --- src/hardware/mixer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 5673e714..c3a5c40c 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -502,7 +502,7 @@ static void SDLCALL MIXER_CallBack(void * userdata, Uint8 *stream, int len) { if(diff > (mixer.min_needed<<1)) diff = mixer.min_needed<<1; if(diff > (mixer.min_needed>>1)) mixer.tick_add = ((mixer.freq-(diff/5)) << TICK_SHIFT)/1000; - else if (diff > (mixer.min_needed>>4)) + else if (diff > (mixer.min_needed>>2)) mixer.tick_add = ((mixer.freq-(diff>>3)) << TICK_SHIFT)/1000; else mixer.tick_add = (mixer.freq<< TICK_SHIFT)/1000; From 8d5d05846bfba09ce6db8eff608dc2cedca676e5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 2 Sep 2017 09:49:19 +0000 Subject: [PATCH 3949/4131] Introduce a random sleep period, which activates after 3 short sleeps in one frame. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4039 --- src/dosbox.cpp | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 2fd3d336..c00a6b8a 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -154,6 +154,9 @@ static Bitu Normal_Loop(void) { } } +//For trying other delays +#define wrap_delay(a) SDL_Delay(a) + void increaseticks() { //Make it return ticksRemain and set it in the function above to remove the global variable. if (GCC_UNLIKELY(ticksLocked)) { // For Fast Forward Mode ticksRemain=5; @@ -164,14 +167,36 @@ void increaseticks() { //Make it return ticksRemain and set it in the function a ticksScheduled = 0; return; } + + static Bit32s lastsleepDone = -1; + static Bitu sleep1count = 0; Bit32u ticksNew; ticksNew = GetTicks(); ticksScheduled += ticksAdded; if (ticksNew <= ticksLast) { //lower should not be possible, only equal. ticksAdded = 0; - SDL_Delay(1); - ticksDone -= GetTicks() - ticksNew; + + if (!CPU_CycleAutoAdjust || CPU_SkipCycleAutoAdjust || sleep1count < 3) { + wrap_delay(1); + } else { + /* Certain configurations always give an exact sleepingtime of 1, this causes problems due to the fact that + dosbox keeps track of full blocks. + This code introduces some randomness to the time slept, which improves stability on those configurations + */ + static const Bit32u sleeppattern[] = { 2, 2, 3, 2, 2, 4, 2}; + static Bit32u sleepindex = 0; + if (ticksDone != lastsleepDone) sleepindex = 0; + wrap_delay(sleeppattern[sleepindex++]); + sleepindex %= sizeof(sleeppattern) / sizeof(sleeppattern[0]); + } + Bit32s timeslept = GetTicks() - ticksNew; + // Count how many times in the current block (of 250 ms) the time slept was 1 ms + if (CPU_CycleAutoAdjust && !CPU_SkipCycleAutoAdjust && timeslept == 1) sleep1count++; + lastsleepDone = ticksDone; + + // Update ticksDone with the time spent sleeping + ticksDone -= timeslept; if (ticksDone < 0) ticksDone = 0; return; //0 @@ -249,9 +274,13 @@ void increaseticks() { //Make it return ticksRemain and set it in the function a } } } + + //Reset cycleguessing parameters. CPU_IODelayRemoved = 0; ticksDone = 0; ticksScheduled = 0; + lastsleepDone = -1; + sleep1count = 0; } else if (ticksAdded > 15) { /* ticksAdded > 15 but ticksScheduled < 5, lower the cycles but do not reset the scheduled/done ticks to take them into From cfe3bd2ebcd62af231d2248330c319e2d7da0390 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 2 Sep 2017 10:12:20 +0000 Subject: [PATCH 3950/4131] Lower the max ratio limit slightly. Add a new ratio limit when the cycles are sufficiently high. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4040 --- src/dosbox.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index c00a6b8a..82b2d1fa 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -235,10 +235,16 @@ void increaseticks() { //Make it return ticksRemain and set it in the function a double ratioremoved = (double) CPU_IODelayRemoved / (double) cproc; if (ratioremoved < 1.0) { ratio = (Bit32s)((double)ratio * (1 - ratioremoved)); + /* Don't allow very high ratio which can cause us to lock as we don't scale down * for very low ratios. High ratio might result because of timing resolution */ - if (ticksScheduled >= 250 && ticksDone < 10 && ratio > 20480) - ratio = 20480; + if (ticksScheduled >= 250 && ticksDone < 10 && ratio > 16384) + ratio = 16384; + + // Limit the ratio even more when the cycles are already way above the realmode default. + if (ticksScheduled >= 250 && ticksDone < 10 && ratio > 5120 && CPU_CycleMax > 50000) + ratio = 5120; + if (ratio <= 1024) { double r = 2.0 /(1.0 + 1024.0/(static_cast(ratio))); new_cmax = 1 + static_cast(CPU_CycleMax * r); From 9be90ad5871565f62bc769d6e77642d3acb9428f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 2 Sep 2017 10:23:38 +0000 Subject: [PATCH 3951/4131] When downscaling multiple times in a raw, ensure a minimum amount of strength Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4041 --- src/dosbox.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 82b2d1fa..2415f850 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -245,6 +245,10 @@ void increaseticks() { //Make it return ticksRemain and set it in the function a if (ticksScheduled >= 250 && ticksDone < 10 && ratio > 5120 && CPU_CycleMax > 50000) ratio = 5120; + // When downscaling multiple times in a row, ensure a minimum amount of downscaling + if (ticksAdded > 15 && ticksScheduled >= 5 && ticksScheduled <= 20 && ratio > 800) + ratio = 800; + if (ratio <= 1024) { double r = 2.0 /(1.0 + 1024.0/(static_cast(ratio))); new_cmax = 1 + static_cast(CPU_CycleMax * r); From a2d1450246805d85e0887b98b35fb017501a0b7f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 2 Sep 2017 10:52:53 +0000 Subject: [PATCH 3952/4131] Introduce a penalty for a lot of idling, which changes the up and downscale algorithm, as the chance of having errors in the input data is a lot larger when there is a lot of idling. The upscale has its strength reduced and the downscale has it increased. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4042 --- src/dosbox.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 2415f850..7f461963 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -234,7 +234,8 @@ void increaseticks() { //Make it return ticksRemain and set it in the function a to have smoother auto cycle adjustments */ double ratioremoved = (double) CPU_IODelayRemoved / (double) cproc; if (ratioremoved < 1.0) { - ratio = (Bit32s)((double)ratio * (1 - ratioremoved)); + double ratio_not_removed = 1 - ratioremoved; + ratio = (Bit32s)((double)ratio * ratio_not_removed); /* Don't allow very high ratio which can cause us to lock as we don't scale down * for very low ratios. High ratio might result because of timing resolution */ @@ -250,10 +251,12 @@ void increaseticks() { //Make it return ticksRemain and set it in the function a ratio = 800; if (ratio <= 1024) { - double r = 2.0 /(1.0 + 1024.0/(static_cast(ratio))); + // ratio_not_removed = 1.0; //enabling this restores the old formula + double r = (1.0 + ratio_not_removed) /(ratio_not_removed + 1024.0/(static_cast(ratio))); new_cmax = 1 + static_cast(CPU_CycleMax * r); } else { - Bit64s cmax_scaled = (Bit64s)CPU_CycleMax * (Bit64s)ratio; + Bit64s ratio_with_removed = (Bit64s) ((((double)ratio - 1024.0) * ratio_not_removed) + 1024.0); + Bit64s cmax_scaled = (Bit64s)CPU_CycleMax * ratio_with_removed; new_cmax = (Bit32s)(1 + (CPU_CycleMax >> 1) + cmax_scaled / (Bit64s)2048); } } From da7ecfd83a8e9331e0bb94215d563b7743a320c1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 2 Sep 2017 11:05:10 +0000 Subject: [PATCH 3953/4131] Change scope of ratioremoved for logging. Introduce a hardcoded limit of 2000000, if no limit was specified in the options file. Thanks for all the help with loggging: leileilol, James-F, sndwv, BBP and P4R4D0X. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4043 --- src/dosbox.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 7f461963..95fa429e 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -229,10 +229,11 @@ void increaseticks() { //Make it return ticksRemain and set it in the function a Bit32s ratio = (ticksScheduled * (CPU_CyclePercUsed*90*1024/100/100)) / ticksDone; Bit32s new_cmax = CPU_CycleMax; Bit64s cproc = (Bit64s)CPU_CycleMax * (Bit64s)ticksScheduled; + double ratioremoved = 0.0; //increase scope for logging if (cproc > 0) { /* ignore the cycles added due to the IO delay code in order to have smoother auto cycle adjustments */ - double ratioremoved = (double) CPU_IODelayRemoved / (double) cproc; + ratioremoved = (double) CPU_IODelayRemoved / (double) cproc; if (ratioremoved < 1.0) { double ratio_not_removed = 1 - ratioremoved; ratio = (Bit32s)((double)ratio * ratio_not_removed); @@ -265,13 +266,14 @@ void increaseticks() { //Make it return ticksRemain and set it in the function a if (new_cmax < CPU_CYCLES_LOWER_LIMIT) new_cmax = CPU_CYCLES_LOWER_LIMIT; /* - LOG(LOG_MISC,LOG_ERROR)("cyclelog: current %06d cmax %06d ratio %05d done %03d sched %03d Add %d", + LOG(LOG_MISC,LOG_ERROR)("cyclelog: current %06d cmax %06d ratio %05d done %03d sched %03d Add %d rr %4.2f", CPU_CycleMax, new_cmax, ratio, ticksDone, ticksScheduled, - ticksAdded); + ticksAdded, + ratioremoved); */ /* ratios below 1% are considered to be dropouts due to @@ -284,7 +286,7 @@ void increaseticks() { //Make it return ticksRemain and set it in the function a CPU_CycleMax = new_cmax; if (CPU_CycleLimit > 0) { if (CPU_CycleMax > CPU_CycleLimit) CPU_CycleMax = CPU_CycleLimit; - } + } else if (CPU_CycleMax > 2000000) CPU_CycleMax = 2000000; //Hardcoded limit, if no limit was specified. } } From ed8c16e69a874dee1a516c6bc57577872121dc2e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 3 Sep 2017 18:33:14 +0000 Subject: [PATCH 3954/4131] Add patch 272 as this is how all commandline options are handled. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4044 --- src/gui/render.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 89a8334c..f852767c 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -581,9 +581,9 @@ void RENDER_Init(Section * sec) { std::string cline; std::string scaler; //Check for commandline paramters and parse them through the configclass so they get checked against allowed values - if (control->cmdline->FindString("-scaler",cline,false)) { + if (control->cmdline->FindString("-scaler",cline,true)) { section->HandleInputline(std::string("scaler=") + cline); - } else if (control->cmdline->FindString("-forcescaler",cline,false)) { + } else if (control->cmdline->FindString("-forcescaler",cline,true)) { section->HandleInputline(std::string("scaler=") + cline + " forced"); } From 42a0b61a650f14cadfe0e797ba22e0ba803c677d Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sun, 10 Sep 2017 11:20:35 +0000 Subject: [PATCH 3955/4131] Remove error exit for unknown functions of INT 17h. Fixes a DOS shell program. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4045 --- src/ints/bios.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index bcfbfb10..5d1a746d 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -591,10 +591,6 @@ static Bitu INT17_Handler(void) { case 0x02: /* PRINTER: Get Status */ reg_ah=0; break; - case 0x20: /* Some sort of printerdriver install check*/ - break; - default: - E_Exit("Unhandled INT 17 call %2X",reg_ah); }; return CBRET_NONE; } From 451d07d8da9ce8177d3ce25a90c86f534fd19174 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sun, 10 Sep 2017 11:22:52 +0000 Subject: [PATCH 3956/4131] Point DOS redirected interrupts at a plain IRET as in real DOS. Prevents erroneous detection of an active debugger, which for example fixes sound in Microleague Football 2. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4046 --- src/dos/dos_memory.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 67761a3d..ced851d3 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -400,15 +400,12 @@ void DOS_SetupMemory(void) { callbackhandler.Allocate(&DOS_default_handler,"DOS default int"); Bit16u ihseg = 0x70; Bit16u ihofs = 0x08; - real_writeb(ihseg,ihofs+0x00,(Bit8u)0xFE); //GRP 4 - real_writeb(ihseg,ihofs+0x01,(Bit8u)0x38); //Extra Callback instruction - real_writew(ihseg,ihofs+0x02,callbackhandler.Get_callback()); //The immediate word - real_writeb(ihseg,ihofs+0x04,(Bit8u)0xCF); //An IRET Instruction + real_writeb(ihseg,ihofs,(Bit8u)0xCF); //An IRET Instruction RealSetVec(0x01,RealMake(ihseg,ihofs)); //BioMenace (offset!=4) RealSetVec(0x02,RealMake(ihseg,ihofs)); //BioMenace (segment<0x8000) RealSetVec(0x03,RealMake(ihseg,ihofs)); //Alien Incident (offset!=0) RealSetVec(0x04,RealMake(ihseg,ihofs)); //Shadow President (lower byte of segment!=0) -// RealSetVec(0x0f,RealMake(ihseg,ihofs)); //Always a tricky one (soundblaster irq) + RealSetVec(0x0f,RealMake(ihseg,ihofs)); //Always a tricky one (soundblaster irq) // Create a dummy device MCB with PSPSeg=0x0008 DOS_MCB mcb_devicedummy((Bit16u)DOS_MEM_START); From 5c0b03c10c59ebcd522bb1e8afdd2674101b6772 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sun, 10 Sep 2017 11:25:45 +0000 Subject: [PATCH 3957/4131] Process repeated reset commands without delay. Fixes MPU detection in several games. Correct ACK for reset: entirely absent with dumb setting (mpu401=uart), and also absent when returning to intelligent mode from UART mode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4047 --- src/hardware/mpu401.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 1eff7ec3..a5aec2a6 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -122,7 +122,15 @@ static Bitu MPU401_ReadStatus(Bitu port,Bitu iolen) { } static void MPU401_WriteCommand(Bitu port,Bitu val,Bitu iolen) { - if (mpu.state.reset) {mpu.state.cmd_pending=val+1;return;} + if (mpu.mode==M_UART && val!=0xff) return; + if (mpu.state.reset) { + if (mpu.state.cmd_pending || (val!=0x3f && val!=0xff)) { + mpu.state.cmd_pending=val+1; + return; + } + PIC_RemoveEvents(MPU401_ResetDone); + mpu.state.reset=false; + } if (val<=0x2f) { switch (val&3) { /* MIDI stop, start, continue */ case 1: {MIDI_RawOutByte(0xfc);break;} @@ -246,8 +254,11 @@ static void MPU401_WriteCommand(Bitu port,Bitu val,Bitu iolen) { LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Reset %X",val); PIC_AddEvent(MPU401_ResetDone,MPU401_RESETBUSY); mpu.state.reset=true; + if (mpu.mode==M_UART) { + MPU401_Reset(); + return; //do not send ack in UART mode + } MPU401_Reset(); - if (mpu.mode==M_UART) return;//do not send ack in UART mode break; case 0x3f: /* UART mode */ LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Set UART mode %X",val); @@ -537,7 +548,6 @@ static void MPU401_Event(Bitu val) { } if (!mpu.state.irq_pending && mpu.state.req_mask) MPU401_EOIHandler(); next_event: - PIC_RemoveEvents(MPU401_Event); Bitu new_time; if ((new_time=mpu.clock.tempo*mpu.clock.timebase)==0) return; PIC_AddEvent(MPU401_Event,MPU401_TIMECONSTANT/new_time); From 4aa821d0e6fa373fce3b09dcb39ac1994d563381 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sun, 10 Sep 2017 11:29:34 +0000 Subject: [PATCH 3958/4131] Implement waiting for retrace in VBE functions. Remove range checks in protected mode functions, consistent with UniVBE and other VBE implementations. Fixes hang and graphics glitches in Jack Orlando. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4048 --- include/callback.h | 2 +- src/cpu/callback.cpp | 42 ++++++++++++++++++++++++++++++++ src/ints/int10.cpp | 21 ++++++++-------- src/ints/int10.h | 6 +++-- src/ints/int10_vesa.cpp | 54 ++++++++++++++++++++++++++--------------- 5 files changed, 91 insertions(+), 34 deletions(-) diff --git a/include/callback.h b/include/callback.h index b09a3822..5b557460 100644 --- a/include/callback.h +++ b/include/callback.h @@ -30,7 +30,7 @@ extern CallBack_Handler CallBack_Handlers[]; enum { CB_RETN,CB_RETF,CB_RETF8,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1, 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,CB_INT13 }; + CB_INT21,CB_INT13,CB_VESA_WAIT,CB_VESA_PM }; #define CB_MAX 128 #define CB_SIZE 32 diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index a503e944..1200dd27 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -458,6 +458,48 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ phys_writew(physAddress+0x02,(Bit16u)0x0ECD); // int 0e phys_writeb(physAddress+0x04,(Bit8u)0xCF); //An IRET Instruction return (use_cb?9:5); + case CB_VESA_WAIT: + if (use_cb) E_Exit("VESA wait must not implement a callback handler!"); + phys_writeb(physAddress+0x00,(Bit8u)0xFB); // sti + phys_writeb(physAddress+0x01,(Bit8u)0x50); // push ax + phys_writeb(physAddress+0x02,(Bit8u)0x52); // push dx + phys_writeb(physAddress+0x03,(Bit8u)0xBA); // mov dx, + phys_writew(physAddress+0x04,(Bit16u)0x03DA); // 0x3da + phys_writeb(physAddress+0x06,(Bit8u)0xEC); // in al,dx + phys_writew(physAddress+0x07,(Bit16u)0x08A8); // test al,8 + phys_writew(physAddress+0x09,(Bit16u)0xFB75); // jne $-5 + phys_writeb(physAddress+0x0B,(Bit8u)0xEC); // in al,dx + phys_writew(physAddress+0x0C,(Bit16u)0x08A8); // test al,8 + phys_writew(physAddress+0x0E,(Bit16u)0xFB74); // je $-5 + phys_writeb(physAddress+0x10,(Bit8u)0x5A); // pop dx + phys_writeb(physAddress+0x11,(Bit8u)0x58); // pop ax + phys_writeb(physAddress+0x12,(Bit8u)0xCB); //A RETF Instruction + return 19; + case CB_VESA_PM: + if (use_cb) { + phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word + physAddress+=4; + } + phys_writew(physAddress+0x00,(Bit16u)0xC3F6); // test bl, + phys_writeb(physAddress+0x02,(Bit8u)0x80); // 0x80 + phys_writew(physAddress+0x03,(Bit16u)0x1674); // je $+22 + phys_writew(physAddress+0x05,(Bit16u)0x5066); // push ax + phys_writew(physAddress+0x07,(Bit16u)0x5266); // push dx + phys_writew(physAddress+0x09,(Bit16u)0xBA66); // mov dx, + phys_writew(physAddress+0x0B,(Bit16u)0x03DA); // 0x3da + phys_writeb(physAddress+0x0D,(Bit8u)0xEC); // in al,dx + phys_writew(physAddress+0x0E,(Bit16u)0x08A8); // test al,8 + phys_writew(physAddress+0x10,(Bit16u)0xFB75); // jne $-5 + phys_writeb(physAddress+0x12,(Bit8u)0xEC); // in al,dx + phys_writew(physAddress+0x13,(Bit16u)0x08A8); // test al,8 + phys_writew(physAddress+0x15,(Bit16u)0xFB74); // je $-5 + phys_writew(physAddress+0x17,(Bit16u)0x5A66); // pop dx + phys_writew(physAddress+0x19,(Bit16u)0x5866); // pop ax + if (use_cb) + phys_writeb(physAddress+0x1B,(Bit8u)0xC3); //A RETN Instruction + return (use_cb?32:27); default: E_Exit("CALLBACK:Setup:Illegal type %d",type); } diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 1a8d614d..a9cfda2b 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -592,10 +592,10 @@ graphics_chars: break; case 0x07: switch (reg_bl) { - case 0x80: /* Set Display Start during retrace ?? */ + case 0x80: /* Set Display Start during retrace */ case 0x00: /* Set display Start */ reg_al=0x4f; - reg_ah=VESA_SetDisplayStart(reg_cx,reg_dx); + reg_ah=VESA_SetDisplayStart(reg_cx,reg_dx,reg_bl==0x80); break; case 0x01: reg_al=0x4f; @@ -611,9 +611,8 @@ graphics_chars: case 0x09: switch (reg_bl) { case 0x80: /* Set Palette during retrace */ - //TODO case 0x00: /* Set Palette */ - reg_ah=VESA_SetPalette(SegPhys(es)+reg_di,reg_dx,reg_cx); + reg_ah=VESA_SetPalette(SegPhys(es)+reg_di,reg_dx,reg_cx,reg_bl==0x80); reg_al=0x4f; break; case 0x01: /* Get Palette */ @@ -633,27 +632,27 @@ graphics_chars: } switch (reg_bl) { case 0x00: - reg_edi=RealOff(int10.rom.pmode_interface); SegSet16(es,RealSeg(int10.rom.pmode_interface)); + reg_di=RealOff(int10.rom.pmode_interface); reg_cx=int10.rom.pmode_interface_size; reg_ax=0x004f; break; case 0x01: /* Get code for "set window" */ - reg_edi=RealOff(int10.rom.pmode_interface)+int10.rom.pmode_interface_window; SegSet16(es,RealSeg(int10.rom.pmode_interface)); - reg_cx=0x10; //0x10 should be enough for the callbacks + reg_di=RealOff(int10.rom.pmode_interface)+int10.rom.pmode_interface_window; + reg_cx=int10.rom.pmode_interface_start-int10.rom.pmode_interface_window; reg_ax=0x004f; break; case 0x02: /* Get code for "set display start" */ - reg_edi=RealOff(int10.rom.pmode_interface)+int10.rom.pmode_interface_start; SegSet16(es,RealSeg(int10.rom.pmode_interface)); - reg_cx=0x10; //0x10 should be enough for the callbacks + reg_di=RealOff(int10.rom.pmode_interface)+int10.rom.pmode_interface_start; + reg_cx=int10.rom.pmode_interface_palette-int10.rom.pmode_interface_start; reg_ax=0x004f; break; case 0x03: /* Get code for "set palette" */ - reg_edi=RealOff(int10.rom.pmode_interface)+int10.rom.pmode_interface_palette; SegSet16(es,RealSeg(int10.rom.pmode_interface)); - reg_cx=0x10; //0x10 should be enough for the callbacks + reg_di=RealOff(int10.rom.pmode_interface)+int10.rom.pmode_interface_palette; + reg_cx=int10.rom.pmode_interface_size-int10.rom.pmode_interface_palette; reg_ax=0x004f; break; default: diff --git a/src/ints/int10.h b/src/ints/int10.h index 93f985b9..e9b622b0 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -133,6 +133,8 @@ typedef struct { RealPt video_dcc_table; RealPt oemstring; RealPt vesa_modes; + RealPt wait_retrace; + RealPt set_window; RealPt pmode_interface; Bit16u pmode_interface_size; Bit16u pmode_interface_start; @@ -208,9 +210,9 @@ Bit8u VESA_GetSVGAMode(Bit16u & mode); Bit8u VESA_SetCPUWindow(Bit8u window,Bit8u address); Bit8u VESA_GetCPUWindow(Bit8u window,Bit16u & address); Bit8u VESA_ScanLineLength(Bit8u subcall, Bit16u val, Bit16u & bytes,Bit16u & pixels,Bit16u & lines); -Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y); +Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y,bool wait); Bit8u VESA_GetDisplayStart(Bit16u & x,Bit16u & y); -Bit8u VESA_SetPalette(PhysPt data,Bitu index,Bitu count); +Bit8u VESA_SetPalette(PhysPt data,Bitu index,Bitu count,bool wait); Bit8u VESA_GetPalette(PhysPt data,Bitu index,Bitu count); /* Sub Groups */ diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 32559e23..e17ea4f2 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -36,7 +36,7 @@ #define VESA_UNIMPLEMENTED 0xFF static struct { - Bitu setwindow; + Bitu rmWindow; Bitu pmStart; Bitu pmWindow; Bitu pmPalette; @@ -254,7 +254,7 @@ foundit: var_write(&minfo.XResolution,mblock->swidth); var_write(&minfo.YResolution,mblock->sheight); } - var_write(&minfo.WinFuncPtr,CALLBACK_RealPointer(callback.setwindow)); + var_write(&minfo.WinFuncPtr,int10.rom.set_window); var_write(&minfo.NumberOfBanks,0x1); var_write(&minfo.Reserved_page,0x1); var_write(&minfo.XCharSize,mblock->cwidth); @@ -297,11 +297,15 @@ Bit8u VESA_GetCPUWindow(Bit8u window,Bit16u & address) { } -Bit8u VESA_SetPalette(PhysPt data,Bitu index,Bitu count) { +Bit8u VESA_SetPalette(PhysPt data,Bitu index,Bitu count,bool wait) { //Structure is (vesa 3.0 doc): blue,green,red,alignment Bit8u r,g,b; if (index>255) return VESA_FAIL; if (index+count>256) return VESA_FAIL; + + // Wait for retrace if requested + if (wait) CALLBACK_RunRealFar(RealSeg(int10.rom.wait_retrace),RealOff(int10.rom.wait_retrace)); + IO_Write(0x3c8,(Bit8u)index); while (count) { b = mem_readb(data++); @@ -422,8 +426,7 @@ Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u val, Bit16u & bytes,Bit16u & pixe return VESA_SUCCESS; } -Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y) { - // TODO wait for retrace in case bl==0x80 +Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y,bool wait) { Bitu pixels_per_offset; Bitu panning_factor = 1; @@ -467,6 +470,9 @@ Bit8u VESA_SetDisplayStart(Bit16u x,Bit16u y) { IO_Write(0x3c0,0x13 | 0x20); // panning register, screen on IO_Write(0x3c0,new_panning); + // Wait for retrace if requested + if (wait) CALLBACK_RunRealFar(RealSeg(int10.rom.wait_retrace),RealOff(int10.rom.wait_retrace)); + return VESA_SUCCESS; } @@ -514,25 +520,30 @@ static Bitu VESA_SetWindow(void) { if (reg_bh) reg_ah=VESA_GetCPUWindow(reg_bl,reg_dx); else reg_ah=VESA_SetCPUWindow(reg_bl,(Bit8u)reg_dx); reg_al=0x4f; - return 0; + return CBRET_NONE; } static Bitu VESA_PMSetWindow(void) { - VESA_SetCPUWindow(0,(Bit8u)reg_dx); - return 0; + IO_Write(0x3d4,0x6a); + IO_Write(0x3d5,reg_dl); + return CBRET_NONE; } static Bitu VESA_PMSetPalette(void) { - VESA_SetPalette(SegPhys(es) + reg_edi, reg_dx, reg_cx ); - return 0; + PhysPt data=SegPhys(es)+reg_edi; + Bit32u count=reg_cx; + IO_Write(0x3c8,reg_dl); + do { + IO_Write(0x3c9,mem_readb(data+2)); + IO_Write(0x3c9,mem_readb(data+1)); + IO_Write(0x3c9,mem_readb(data)); + data+=4; + } while (--count); + return CBRET_NONE; } static Bitu VESA_PMSetStart(void) { - // This function is from VBE2 and directly sets the VGA - // display start address. - - // TODO wait for retrace in case bl==0x80 Bit32u start = (reg_dx << 16) | reg_cx; vga.config.display_start = start; - return 0; + return CBRET_NONE; } @@ -569,10 +580,12 @@ void INT10_SetupVESA(void) { case SVGA_S3Trio: break; } - callback.setwindow=CALLBACK_Allocate(); - callback.pmPalette=CALLBACK_Allocate(); - callback.pmStart=CALLBACK_Allocate(); - CALLBACK_Setup(callback.setwindow,VESA_SetWindow,CB_RETF, "VESA Real Set Window"); + /* Prepare the real mode interface */ + int10.rom.wait_retrace=RealMake(0xc000,int10.rom.used); + int10.rom.used += (Bit16u)CALLBACK_Setup(0, NULL, CB_VESA_WAIT, PhysMake(0xc000,int10.rom.used), ""); + callback.rmWindow=CALLBACK_Allocate(); + int10.rom.set_window=RealMake(0xc000,int10.rom.used); + int10.rom.used += (Bit16u)CALLBACK_Setup(callback.rmWindow, VESA_SetWindow, CB_RETF, PhysMake(0xc000,int10.rom.used), "VESA Real Set Window"); /* Prepare the pmode interface */ int10.rom.pmode_interface=RealMake(0xc000,int10.rom.used); int10.rom.used += 8; //Skip the byte later used for offsets @@ -585,11 +598,12 @@ void INT10_SetupVESA(void) { int10.rom.pmode_interface_start = int10.rom.used - RealOff( int10.rom.pmode_interface ); phys_writew( Real2Phys(int10.rom.pmode_interface) + 2, int10.rom.pmode_interface_start); callback.pmStart=CALLBACK_Allocate(); - int10.rom.used += (Bit16u)CALLBACK_Setup(callback.pmStart, VESA_PMSetStart, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Start"); + int10.rom.used += (Bit16u)CALLBACK_Setup(callback.pmStart, VESA_PMSetStart, CB_VESA_PM, PhysMake(0xc000,int10.rom.used), "VESA PM Set Start"); /* PM Set Palette call */ int10.rom.pmode_interface_palette = int10.rom.used - RealOff( int10.rom.pmode_interface ); phys_writew( Real2Phys(int10.rom.pmode_interface) + 4, int10.rom.pmode_interface_palette); callback.pmPalette=CALLBACK_Allocate(); + int10.rom.used += (Bit16u)CALLBACK_Setup(0, NULL, CB_VESA_PM, PhysMake(0xc000,int10.rom.used), ""); int10.rom.used += (Bit16u)CALLBACK_Setup(callback.pmPalette, VESA_PMSetPalette, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Palette"); /* Finalize the size and clear the required ports pointer */ phys_writew( Real2Phys(int10.rom.pmode_interface) + 6, 0); From ba9c9e1ad65ac4518e6378e7f75498c62e2e6e4a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Sep 2017 10:00:00 +0000 Subject: [PATCH 3959/4131] Fix bug 467. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4049 --- src/hardware/mixer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index c3a5c40c..25dc0c6a 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -451,7 +451,7 @@ static void MIXER_Mix_NoSound(void) { } /* Set values for next tick */ mixer.tick_counter += mixer.tick_add; - mixer.needed += (mixer.tick_counter >> TICK_SHIFT); + mixer.needed = (mixer.tick_counter >> TICK_SHIFT); mixer.tick_counter &= TICK_MASK; mixer.done=0; } From 1fb8141175433eb1a7b736f6394164029f29270d Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Mon, 11 Sep 2017 18:03:24 +0000 Subject: [PATCH 3960/4131] Zero INT 68h vector on CGA machine type. Helps default speed of Popcorn game. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4050 --- src/cpu/callback.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 1200dd27..37183bf4 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -639,7 +639,7 @@ void CALLBACK_Init(Section* /*sec*/) { // setup a few interrupt handlers that point to bios IRETs by default 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)); + if (machine==MCH_CGA) real_writed(0,0x68*4,0); //Popcorn real_writed(0,0x5c*4,CALLBACK_RealPointer(call_default)); //Network stuff //real_writed(0,0xf*4,0); some games don't like it From 254ee02ae015d51a6adb8fffdce6b95cbfa7cf32 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 14 Sep 2017 20:36:15 +0000 Subject: [PATCH 3961/4131] We don't use MFC, maybe this helps the compilation guides of DosFreak. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4051 --- src/winres.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/winres.rc b/src/winres.rc index 0ab415f5..f675e152 100644 --- a/src/winres.rc +++ b/src/winres.rc @@ -1,5 +1,5 @@ -#include "afxres.h" +#include "winresrc.h" // icon resource dosbox_ico ICON "dosbox.ico" From aa7334503a9dfc200db38ed35cb12ac86d0fcae6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 20 Sep 2017 19:06:19 +0000 Subject: [PATCH 3962/4131] Remove dangling comma. (Thanks for spotting it hail-to-the-ryzen) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4052 --- src/gui/sdl_mapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index c583cdf8..136e979a 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -354,7 +354,7 @@ static SDLKey sdlkey_map[]={ /* 4 extra keys that don't really exist, but are needed for * round-trip mapping (dosbox uses RMETA only for hotkeys, it's * not really mapped to an emulated key) */ - SDLK_RMETA, SDLK_RSHIFT, SDLK_RALT, SDLK_RCTRL, + SDLK_RMETA, SDLK_RSHIFT, SDLK_RALT, SDLK_RCTRL }; #define MAX_SCANCODES (0x80+4) /* Make sure that the table above has the expected size. This From 32f00494089792c65680ad1e67226131a58bbbe7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 Sep 2017 15:53:20 +0000 Subject: [PATCH 3963/4131] Add trivial speed up to debugger. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4053 --- src/debug/debug.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index d7320bd7..b6cbc61b 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -447,6 +447,9 @@ void CBreakpoint::ActivateBreakpointsExceptAt(PhysPt adr) bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off) // Checks if breakpoint is valid and should stop execution { + // Quick exit if there are no breakpoints + if (BPoints.size() == 0) return false; + // Search matching breakpoint std::list::iterator i; CBreakpoint* bp; From c27b446d6731140f74109692ed93b86278e898a2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 26 Sep 2017 07:50:31 +0000 Subject: [PATCH 3964/4131] empty is always constant, while size can be linear on older gcc versions. (wjp) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4054 --- src/debug/debug.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index b6cbc61b..f93b2985 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -448,7 +448,7 @@ bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off) // Checks if breakpoint is valid and should stop execution { // Quick exit if there are no breakpoints - if (BPoints.size() == 0) return false; + if (BPoints.empty()) return false; // Search matching breakpoint std::list::iterator i; @@ -508,6 +508,8 @@ bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off) bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue, Bit16u alValue) // Checks if interrupt breakpoint is valid and should stop execution { + if (BPoints.empty()) return false; + // Search matching breakpoint std::list::iterator i; CBreakpoint* bp; From 339fb9f8080a68f35f14ebc28f33edbaf5f629c5 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 3 Oct 2017 19:49:52 +0000 Subject: [PATCH 3965/4131] Fix address calculation for 16bit DMA transfers on GUS Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4055 --- src/hardware/gus.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 2786e442..68c90988 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -742,7 +742,15 @@ static void write_gus(Bitu port,Bitu val,Bitu iolen) { static void GUS_DMA_Callback(DmaChannel * chan,DMAEvent event) { if (event!=DMA_UNMASKED) return; - Bitu dmaaddr = myGUS.dmaAddr << 4; + Bitu dmaaddr; + //Calculate the dma address + //DMA transfers can't cross 256k boundaries, so you should be safe to just determine the start once and go from there + //Bit 2 - 0 = if DMA channel is an 8 bit channel(0 - 3). + if (myGUS.DMAControl & 0x4) + dmaaddr = (((myGUS.dmaAddr & 0x1fff) << 1) | (myGUS.dmaAddr & 0xc000)) << 4; + else + dmaaddr = myGUS.dmaAddr << 4; + //Reading from dma? if((myGUS.DMAControl & 0x2) == 0) { Bitu read=chan->Read(chan->currcnt+1,&GUSRam[dmaaddr]); //Check for 16 or 8bit channel @@ -758,8 +766,8 @@ static void GUS_DMA_Callback(DmaChannel * chan,DMAEvent event) { for(i=dmaaddr+1;i<(dmaaddr+read);i+=2) GUSRam[i] ^= 0x80; } } + //Writing to dma } else { - //Read data out of UltraSound chan->Write(chan->currcnt+1,&GUSRam[dmaaddr]); } /* Raise the TC irq if needed */ From ee8d976ebc33524067c69c4c540d9e81df3cc653 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 10 Oct 2017 13:51:13 +0000 Subject: [PATCH 3966/4131] Move dddraw detection to a configure option. Requested by DosFreak. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4056 --- configure.ac | 27 +++++++++++++++++++++++---- src/gui/sdlmain.cpp | 20 ++++++++++---------- src/platform/visualc/config.h | 8 ++++---- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/configure.ac b/configure.ac index dc2aa0ff..9c0b807c 100644 --- a/configure.ac +++ b/configure.ac @@ -138,7 +138,7 @@ fi dnl Checks for libraries. #Check if the compiler support attributes -AH_TEMPLATE([C_HAS_ATTRIBUTE],[Determines if the compilers supports attributes for structures.]) +AH_TEMPLATE([C_HAS_ATTRIBUTE],[Determines if the compiler supports attributes for structures.]) AC_MSG_CHECKING(if compiler allows __attribute__) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ typedef struct { } __attribute__((packed)) junk;]], @@ -149,12 +149,12 @@ typedef struct { } __attribute__((packed)) junk;]], OLDCFLAGS="$CFLAGS" CFLAGS="-Werror" -AH_TEMPLATE([C_ATTRIBUTE_ALWAYS_INLINE],[Determines if the compilers supports always_inline attribute.]) +AH_TEMPLATE([C_ATTRIBUTE_ALWAYS_INLINE],[Determines if the compiler supports always_inline attribute.]) AC_MSG_CHECKING(if compiler allows __attribute__((always_inline)) ) AC_COMPILE_IFELSE([AC_LANG_SOURCE([ inline 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.]) +AH_TEMPLATE([C_ATTRIBUTE_FASTCALL],[Determines if the compiler supports fastcall attribute.]) AC_MSG_CHECKING(if compiler allows __attribute__((fastcall)) ) AC_COMPILE_IFELSE([AC_LANG_SOURCE([ void __attribute__((fastcall)) test(){} ])],[ AC_MSG_RESULT(yes);AC_DEFINE(C_ATTRIBUTE_FASTCALL)],AC_MSG_RESULT(no)) @@ -436,6 +436,26 @@ case "$host" in esac fi +AH_TEMPLATE(C_DDRAW,[Define to 1 to enable output=ddraw (Win32)]) +AC_ARG_ENABLE(ddraw,AC_HELP_STRING([--disable-ddraw],[Disable ddraw support]),enable_ddraw=yes) +AC_CHECK_HEADER(ddraw.h, have_ddraw_h=yes , have_ddraw_h=no , ) +AC_MSG_CHECKING(whether ddraw display output will be enabled) +if test x$enable_opengl = xyes; then +case "$host" in + *-*-cygwin* | *-*-mingw32*) + if test x$have_ddraw_h = xyes ; then + AC_MSG_RESULT(yes) + AC_DEFINE(C_DDRAW,1) + else + AC_MSG_RESULT(no) + fi + ;; + *) + AC_MSG_RESULT(no) + ;; +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,,) @@ -472,7 +492,6 @@ dnl Some target detection and actions for them case "$host" 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" diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index c59815dc..db0a828f 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -99,7 +99,7 @@ extern char** environ; #define WIN32_LEAN_AND_MEAN #endif #include -#if (HAVE_DDRAW_H) +#if C_DDRAW #include struct private_hwdata { LPDIRECTDRAWSURFACE3 dd_surface; @@ -189,7 +189,7 @@ struct SDL_Block { #endif struct { SDL_Surface * surface; -#if (HAVE_DDRAW_H) && defined(WIN32) +#if C_DDRAW RECT rect; #endif } blit; @@ -380,7 +380,7 @@ check_surface: else if (flags & GFX_LOVE_16) testbpp=16; else if (flags & GFX_LOVE_32) testbpp=32; else testbpp=0; -#if (HAVE_DDRAW_H) && defined(WIN32) +#if C_DDRAW check_gotbpp: #endif if (sdl.desktop.fullscreen) gotbpp=SDL_VideoModeOK(640,480,testbpp,SDL_FULLSCREEN|SDL_HWSURFACE|SDL_HWPALETTE); @@ -403,7 +403,7 @@ check_gotbpp: } flags |= GFX_CAN_RANDOM; break; -#if (HAVE_DDRAW_H) && defined(WIN32) +#if C_DDRAW case SCREEN_SURFACE_DDRAW: if (!(flags&(GFX_CAN_15|GFX_CAN_16|GFX_CAN_32))) goto check_surface; if (flags & GFX_LOVE_15) testbpp=15; @@ -613,7 +613,7 @@ dosurface: } } break; -#if (HAVE_DDRAW_H) && defined(WIN32) +#if C_DDRAW case SCREEN_SURFACE_DDRAW: if (flags & GFX_CAN_15) bpp=15; if (flags & GFX_CAN_16) bpp=16; @@ -887,7 +887,7 @@ bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) { } sdl.updating=true; return true; -#if (HAVE_DDRAW_H) && defined(WIN32) +#if C_DDRAW case SCREEN_SURFACE_DDRAW: if (SDL_LockSurface(sdl.blit.surface)) { // LOG_MSG("SDL Lock failed"); @@ -923,7 +923,7 @@ bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) { void GFX_EndUpdate( const Bit16u *changedLines ) { -#if (HAVE_DDRAW_H) && defined(WIN32) +#if C_DDRAW int ret; #endif if (!sdl.updating) @@ -964,7 +964,7 @@ void GFX_EndUpdate( const Bit16u *changedLines ) { SDL_UpdateRects( sdl.surface, rectCount, sdl.updateRects ); } break; -#if (HAVE_DDRAW_H) && defined(WIN32) +#if C_DDRAW case SCREEN_SURFACE_DDRAW: SDL_UnlockSurface(sdl.blit.surface); ret=IDirectDrawSurface3_Blt( @@ -1273,7 +1273,7 @@ static void GUI_StartUp(Section * sec) { if (output == "surface") { sdl.desktop.want_type=SCREEN_SURFACE; -#if (HAVE_DDRAW_H) && defined(WIN32) +#if C_DDRAW } else if (output == "ddraw") { sdl.desktop.want_type=SCREEN_SURFACE_DDRAW; #endif @@ -1681,7 +1681,7 @@ void Config_Add_SDL() { #if C_OPENGL "opengl", "openglnb", #endif -#if (HAVE_DDRAW_H) && defined(WIN32) +#if C_DDRAW "ddraw", #endif 0 }; diff --git a/src/platform/visualc/config.h b/src/platform/visualc/config.h index fffd256e..8b7bab26 100644 --- a/src/platform/visualc/config.h +++ b/src/platform/visualc/config.h @@ -3,6 +3,9 @@ /* Define to 1 to enable internal debugger, requires libcurses */ #define C_DEBUG 0 +/* Define to 1 to enable output=ddraw */ +#define C_DDRAW 1 + /* Define to 1 to enable screenshots, requires libpng */ #define C_SSHOT 1 @@ -46,10 +49,7 @@ /* environ can be linked */ #define ENVIRON_LINKED 1 -/* Define to 1 if you have the header file. */ -#define HAVE_DDRAW_H 1 - -/* Define to 1 if you want serial passthrough support (Win32 only). */ +/* Define to 1 if you want serial passthrough support. */ #define C_DIRECTSERIAL 1 #define GCC_ATTRIBUTE(x) /* attribute not supported */ From 7391ee7c25b95355cf27ee4a0a5c68471cda582c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 10 Oct 2017 14:03:42 +0000 Subject: [PATCH 3967/4131] Fix some issues with the detection of the configure option Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4057 --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 9c0b807c..4800454b 100644 --- a/configure.ac +++ b/configure.ac @@ -437,10 +437,10 @@ esac fi AH_TEMPLATE(C_DDRAW,[Define to 1 to enable output=ddraw (Win32)]) -AC_ARG_ENABLE(ddraw,AC_HELP_STRING([--disable-ddraw],[Disable ddraw support]),enable_ddraw=yes) +AC_ARG_ENABLE(ddraw,AC_HELP_STRING([--disable-ddraw],[Disable ddraw support]),,enable_ddraw=yes) AC_CHECK_HEADER(ddraw.h, have_ddraw_h=yes , have_ddraw_h=no , ) AC_MSG_CHECKING(whether ddraw display output will be enabled) -if test x$enable_opengl = xyes; then +if test x$enable_ddraw = xyes; then case "$host" in *-*-cygwin* | *-*-mingw32*) if test x$have_ddraw_h = xyes ; then From 21a0040650e8f61e137c1d5df8bd545f59f18cc9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 10 Oct 2017 14:21:31 +0000 Subject: [PATCH 3968/4131] Move definition of LocalFile to header file, requested by bruenor41, makes sense to make it available at a larger scope. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4058 --- include/dos_system.h | 17 +++++++++++++++++ src/dos/drive_local.cpp | 17 ----------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 152fee3f..b8133960 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -117,6 +117,23 @@ private: Bitu devnum; }; +class localFile : public DOS_File { +public: + localFile(const char* name, FILE * handle); + bool Read(Bit8u * data,Bit16u * size); + bool Write(Bit8u * data,Bit16u * size); + bool Seek(Bit32u * pos,Bit32u type); + bool Close(); + Bit16u GetInformation(void); + bool UpdateDateTimeFromHost(void); + void FlagReadOnlyMedium(void); + void Flush(void); +private: + FILE * fhandle; + bool read_only_medium; + enum { NONE,READ,WRITE } last_action; +}; + /* 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. */ diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 396cc098..562ebee4 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -30,23 +30,6 @@ #include "cross.h" #include "inout.h" -class localFile : public DOS_File { -public: - localFile(const char* name, FILE * handle); - bool Read(Bit8u * data,Bit16u * size); - bool Write(Bit8u * data,Bit16u * size); - bool Seek(Bit32u * pos,Bit32u type); - bool Close(); - Bit16u GetInformation(void); - bool UpdateDateTimeFromHost(void); - void FlagReadOnlyMedium(void); - void Flush(void); -private: - FILE * fhandle; - bool read_only_medium; - enum { NONE,READ,WRITE } last_action; -}; - bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u /*attributes*/) { //TODO Maybe care for attributes but not likely From eca070fce98f19824509104567807f9ee91001ea Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 10 Oct 2017 15:07:25 +0000 Subject: [PATCH 3969/4131] silence warning 4018, unsigned char/unsigned char => (signed) int (thanks wjp) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4059 --- src/ints/int10_char.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 45dfee71..f6153b30 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -58,7 +58,7 @@ static void TANDY16_CopyRow(Bit8u cleft,Bit8u cright,Bit8u rold,Bit8u rnew,PhysP PhysPt dest=base+((CurMode->twidth*rnew)*(cheight/banks)+cleft)*4; PhysPt src=base+((CurMode->twidth*rold)*(cheight/banks)+cleft)*4; Bitu copy=(cright-cleft)*4;Bitu nextline=CurMode->twidth*4; - for (Bitu i=0;i(cheight/banks);i++) { for (Bitu b=0;btwidth*row)*(cheight/banks)+cleft)*4; Bitu copy=(cright-cleft)*4;Bitu nextline=CurMode->twidth*4; attr=(attr & 0xf) | (attr & 0xf) << 4; - for (Bitu i=0;i(cheight/banks);i++) { for (Bitu x=0;x Date: Sat, 28 Oct 2017 19:47:09 +0000 Subject: [PATCH 3970/4131] Improve MSCDEX GetDirectoryEntry function: skip associated files, and handle HSF differences in canonicalized structure. Also combine Copyright, Abstract, and Documentation filename functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4060 --- src/dos/dos_mscdex.cpp | 81 ++++++++++-------------------------------- 1 file changed, 18 insertions(+), 63 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 46b8f590..321c1ea6 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -113,9 +113,7 @@ public: void GetDrives (PhysPt data); void GetDriverInfo (PhysPt data); bool GetVolumeName (Bit8u subUnit, char* name); - bool GetCopyrightName (Bit16u drive, PhysPt data); - bool GetAbstractName (Bit16u drive, PhysPt data); - bool GetDocumentationName(Bit16u drive, PhysPt data); + bool GetFileName (Bit16u drive, Bit16u pos, PhysPt data); bool GetDirectoryEntry (Bit16u drive, bool copyFlag, PhysPt pathname, PhysPt buffer, Bit16u& error); bool ReadVTOC (Bit16u drive, Bit16u volume, PhysPt data, Bit16u& offset, Bit16u& error); bool ReadSectors (Bit16u drive, Bit32u sector, Bit16u num, PhysPt data); @@ -620,7 +618,7 @@ bool CMscdex::GetVolumeName(Bit8u subUnit, char* data) { return success; } -bool CMscdex::GetCopyrightName(Bit16u drive, PhysPt data) { +bool CMscdex::GetFileName(Bit16u drive, Bit16u pos, PhysPt data) { Bit16u offset = 0, error; bool success = false; PhysPt ptoc = GetTempBuffer(); @@ -628,44 +626,10 @@ bool CMscdex::GetCopyrightName(Bit16u drive, PhysPt data) { if (success) { Bitu len; for (len=0;len<37;len++) { - Bit8u c=mem_readb(ptoc+offset+702+len); + Bit8u c=mem_readb(ptoc+offset+pos+len); if (c==0 || c==0x20) break; } - MEM_BlockCopy(data,ptoc+offset+702,len); - mem_writeb(data+len,0); - }; - return success; -} - -bool CMscdex::GetAbstractName(Bit16u drive, PhysPt data) { - Bit16u offset = 0, error; - bool success = false; - PhysPt ptoc = GetTempBuffer(); - success = ReadVTOC(drive,0x00,ptoc,offset,error); - if (success) { - Bitu len; - for (len=0;len<37;len++) { - Bit8u c=mem_readb(ptoc+offset+739+len); - if (c==0 || c==0x20) break; - } - MEM_BlockCopy(data,ptoc+offset+739,len); - mem_writeb(data+len,0); - }; - return success; -} - -bool CMscdex::GetDocumentationName(Bit16u drive, PhysPt data) { - Bit16u offset = 0, error; - bool success = false; - PhysPt ptoc = GetTempBuffer(); - success = ReadVTOC(drive,0x00,ptoc,offset,error); - if (success) { - Bitu len; - for (len=0;len<37;len++) { - Bit8u c=mem_readb(ptoc+offset+776+len); - if (c==0 || c==0x20) break; - } - MEM_BlockCopy(data,ptoc+offset+776,len); + MEM_BlockCopy(data,ptoc+offset+pos,len); mem_writeb(data+len,0); }; return success; @@ -724,13 +688,12 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph PhysPt defBuffer = GetDefaultBuffer(); if (!ReadSectors(GetSubUnit(drive),false,16,1,defBuffer)) return false; MEM_StrCopy(defBuffer+1,volumeID,5); volumeID[5] = 0; - Bit16u offset; - if (strcmp("CD001",volumeID)==0) offset = 156; - else { + bool iso = (strcmp("CD001",volumeID)==0); + if (!iso) { MEM_StrCopy(defBuffer+9,volumeID,5); - if (strcmp("CDROM",volumeID)==0) offset = 180; - else E_Exit("MSCDEX: GetDirEntry: Not an ISO 9660 or High Sierra CD."); + if (strcmp("CDROM",volumeID)!=0) E_Exit("MSCDEX: GetDirEntry: Not an ISO 9660 or HSF CD."); } + Bit16u offset = iso ? 156:180; // get directory position Bitu dirEntrySector = mem_readd(defBuffer+offset+2); Bits dirSize = mem_readd(defBuffer+offset+10); @@ -752,6 +715,11 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph do { entryLength = mem_readb(defBuffer+index); if (entryLength==0) break; + if (mem_readb(defBuffer+index+iso ? 0x19:0x18) & 4) { + // skip associated files + index += entryLength; + continue; + } nameLength = mem_readb(defBuffer+index+32); MEM_StrCopy(defBuffer+index+33,entryName,nameLength); if (strcmp(entryName,useName)==0) { @@ -787,8 +755,9 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph memcpy( &writeBuf[1], &readBuf[0x2], 4); // 01h DWORD Logical Block Number of file start writeBuf[5] = 0;writeBuf[6] = 8; // 05h WORD size of disk in logical blocks memcpy( &writeBuf[7], &readBuf[0xa], 4); // 07h DWORD file length in bytes - memcpy( &writeBuf[0xb], &readBuf[0x12], 7); // 0bh DWORD date and time - writeBuf[0x12] = readBuf[0x19]; // 12h BYTE bit flags + memcpy( &writeBuf[0xb], &readBuf[0x12], 6); // 0bh BYTEs date and time + writeBuf[0x11] = iso ? readBuf[0x18]:0; // 11h BYTE time zone + writeBuf[0x12] = readBuf[iso ? 0x19:0x18]; // 12h BYTE bit flags writeBuf[0x13] = readBuf[0x1a]; // 13h BYTE interleave size writeBuf[0x14] = readBuf[0x1b]; // 14h BYTE interleave skip factor memcpy( &writeBuf[0x15], &readBuf[0x1c], 2); // 15h WORD volume set sequence number @@ -799,7 +768,7 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph // Direct copy MEM_BlockCopy(buffer,defBuffer+index,entryLength); } - error = 1; + error = iso ? 1:0; return true; } // change directory @@ -1190,23 +1159,9 @@ static bool MSCDEX_Handler(void) { mscdex->GetDriverInfo(data); return true; case 0x1502: /* Get Copyright filename */ - if (mscdex->GetCopyrightName(reg_cx,data)) { - CALLBACK_SCF(false); - } else { - reg_ax = MSCDEX_ERROR_UNKNOWN_DRIVE; - CALLBACK_SCF(true); - }; - return true; case 0x1503: /* Get Abstract filename */ - if (mscdex->GetAbstractName(reg_cx,data)) { - CALLBACK_SCF(false); - } else { - reg_ax = MSCDEX_ERROR_UNKNOWN_DRIVE; - CALLBACK_SCF(true); - }; - return true; case 0x1504: /* Get Documentation filename */ - if (mscdex->GetDocumentationName(reg_cx,data)) { + if (mscdex->GetFileName(reg_cx,702+(reg_al-2)*37,data)) { CALLBACK_SCF(false); } else { reg_ax = MSCDEX_ERROR_UNKNOWN_DRIVE; From e24b034d20a049c3595eba8d990081e1714aef79 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sat, 28 Oct 2017 19:48:26 +0000 Subject: [PATCH 3971/4131] Add patch #265 to correct parameters and clock rate for some EGA modes. Also apply the yellow->brown fix to EGA text modes as well. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4061 --- src/ints/int10_modes.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 333f0bcb..72719d5a 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -230,12 +230,12 @@ VideoModeBlock ModeList_EGA[]={ { 0x003 ,M_TEXT ,640 ,350 ,80 ,25 ,8 ,14 ,8 ,0xB8000 ,0x1000 ,96 ,366 ,80 ,350 ,0 }, { 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,60 ,262 ,40 ,200 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, { 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,60 ,262 ,40 ,200 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE}, -{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,120 ,262 ,80 ,200 ,_EGA_LINE_DOUBLE}, -{ 0x007 ,M_TEXT ,720 ,350 ,80 ,25 ,9 ,14 ,8 ,0xB0000 ,0x1000 ,120 ,440 ,80 ,350 ,0 }, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,117 ,262 ,80 ,200 ,_EGA_LINE_DOUBLE}, +{ 0x007 ,M_TEXT ,720 ,350 ,80 ,25 ,9 ,14 ,8 ,0xB0000 ,0x1000 ,101 ,370 ,80 ,350 ,0 }, { 0x00D ,M_EGA ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,60 ,262 ,40 ,200 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, -{ 0x00E ,M_EGA ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,120 ,262 ,80 ,200 ,_EGA_LINE_DOUBLE }, -{ 0x00F ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,96 ,366 ,80 ,350 ,0 },/*was EGA_2*/ +{ 0x00E ,M_EGA ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,117 ,262 ,80 ,200 ,_EGA_LINE_DOUBLE }, +{ 0x00F ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,101 ,370 ,80 ,350 ,0 },/*was EGA_2*/ { 0x010 ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,96 ,366 ,80 ,350 ,0 }, {0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, @@ -769,9 +769,12 @@ bool INT10_SetVideoMode(Bit16u mode) { /* Setup MISC Output Register */ Bit8u misc_output=0x2 | (mono_mode ? 0x0 : 0x1); - if ((CurMode->type==M_TEXT) && (CurMode->cwidth==9)) { - // 28MHz (16MHz EGA) clock for 9-pixel wide chars - misc_output|=0x4; + if (machine==MCH_EGA) { + // 16MHz clock for 350-line EGA modes except mode F + if ((CurMode->vdispend==350) && (mode!=0xf)) misc_output|=0x4; + } else { + // 28MHz clock for 9-pixel wide chars + if ((CurMode->type==M_TEXT) && (CurMode->cwidth==9)) misc_output|=0x4; } switch (CurMode->vdispend) { @@ -1194,7 +1197,7 @@ att_text16: att_data[ct]=ct; att_data[ct+8]=ct+0x38; } - if (IS_VGA_ARCH) att_data[0x06]=0x14; //Odd Color 6 yellow/brown. + if (IS_EGAVGA_ARCH) att_data[0x06]=0x14; //Odd Color 6 yellow/brown. } break; case M_CGA2: From 29bb526d20c8067d6a102edccb80bcd5ef50c01a Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sat, 28 Oct 2017 19:49:11 +0000 Subject: [PATCH 3972/4131] Implement update region in mouse driver; only text modes for now. Fixes mouse pointer problems in Microsoft Programmer's Library. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4062 --- src/ints/mouse.cpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 4eee708e..7b6676ca 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -113,8 +113,8 @@ static struct { Bit16u dspeed_val; float senv_x; float senv_y; - Bit16u updateRegion_x[2]; - Bit16u updateRegion_y[2]; + Bit16s updateRegion_x[2]; + Bit16s updateRegion_y[2]; Bit16u doubleSpeedThreshold; Bit16u language; Bit16u cursorType; @@ -251,6 +251,11 @@ void DrawCursorText() { // Restore Background RestoreCursorBackgroundText(); + // Check if cursor in update region + if ((POS_Y <= mouse.updateRegion_y[1]) && (POS_Y >= mouse.updateRegion_y[0]) && + (POS_X <= mouse.updateRegion_x[1]) && (POS_X >= mouse.updateRegion_x[0])) { + return; + } // Save Background mouse.backposx = POS_X>>3; @@ -674,10 +679,7 @@ void Mouse_AfterNewVideoMode(bool setmode) { mouse.language = 0; mouse.page = 0; mouse.doubleSpeedThreshold = 64; - mouse.updateRegion_x[0] = 1; - mouse.updateRegion_y[0] = 1; - mouse.updateRegion_x[1] = 1; - mouse.updateRegion_y[1] = 1; + mouse.updateRegion_y[1] = -1; //offscreen mouse.cursorType = 0; //Test mouse.enabled=true; @@ -716,6 +718,7 @@ static Bitu INT33_Handler(void) { break; case 0x01: /* Show Mouse */ if(mouse.hidden) mouse.hidden--; + mouse.updateRegion_y[1] = -1; //offscreen Mouse_AutoLock(true); DrawCursor(); break; @@ -838,11 +841,12 @@ static Bitu INT33_Handler(void) { case 0x0f: /* Define mickey/pixel rate */ Mouse_SetMickeyPixelRate(reg_cx,reg_dx); break; - case 0x10: /* Define screen region for updating */ - mouse.updateRegion_x[0]=reg_cx; - mouse.updateRegion_y[0]=reg_dx; - mouse.updateRegion_x[1]=reg_si; - mouse.updateRegion_y[1]=reg_di; + case 0x10: /* Define screen region for updating */ + mouse.updateRegion_x[0]=(Bit16s)reg_cx; + mouse.updateRegion_y[0]=(Bit16s)reg_dx; + mouse.updateRegion_x[1]=(Bit16s)reg_si; + mouse.updateRegion_y[1]=(Bit16s)reg_di; + DrawCursor(); break; case 0x11: /* Get number of buttons */ reg_ax=0xffff; From 34f99e926171f49fe11a0e45b47c57822bf40a9b Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sat, 28 Oct 2017 20:30:41 +0000 Subject: [PATCH 3973/4131] Remove some unnecessary things from prior commits; oops. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4063 --- src/dos/dos_memory.cpp | 8 -------- src/ints/int10_modes.cpp | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index ced851d3..00593a85 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -20,7 +20,6 @@ #include "dosbox.h" #include "mem.h" #include "dos_inc.h" -#include "callback.h" #define UMB_START_SEG 0x9fff @@ -387,17 +386,10 @@ bool DOS_LinkUMBsToMemChain(Bit16u linkstate) { } -static Bitu DOS_default_handler(void) { - LOG(LOG_CPU,LOG_ERROR)("DOS rerouted Interrupt Called %X",lastint); - return CBRET_NONE; -} - -static CALLBACK_HandlerObject callbackhandler; void DOS_SetupMemory(void) { /* Let dos claim a few bios interrupts. Makes DOSBox more compatible with * buggy games, which compare against the interrupt table. (probably a * broken linked list implementation) */ - callbackhandler.Allocate(&DOS_default_handler,"DOS default int"); Bit16u ihseg = 0x70; Bit16u ihofs = 0x08; real_writeb(ihseg,ihofs,(Bit8u)0xCF); //An IRET Instruction diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 72719d5a..d583b71c 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1197,7 +1197,7 @@ att_text16: att_data[ct]=ct; att_data[ct+8]=ct+0x38; } - if (IS_EGAVGA_ARCH) att_data[0x06]=0x14; //Odd Color 6 yellow/brown. + att_data[0x06]=0x14; //Odd Color 6 yellow/brown. } break; case M_CGA2: From 82567c0bd6ab981c92b2134bf426db0fd643315d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 20 Nov 2017 17:27:53 +0000 Subject: [PATCH 3974/4131] Allow for direct changing of 4op chaining without having to rewrite the algorithm mode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4064 --- src/hardware/dbopl.cpp | 49 +++++++++++++++++++++++++----------------- src/hardware/dbopl.h | 4 +++- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index c7d61ca3..8b6df319 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -716,18 +716,23 @@ void Channel::WriteB0( const Chip* chip, Bit8u val ) { } } -void Channel::WriteC0( const Chip* chip, Bit8u val ) { +void Channel::WriteC0(const Chip* chip, Bit8u val) { Bit8u change = val ^ regC0; - if ( !change ) + if (!change) return; regC0 = val; - feedback = ( val >> 1 ) & 7; - if ( feedback ) { + feedback = (regC0 >> 1) & 7; + if (feedback) { //We shift the input to the right 10 bit wave index value feedback = 9 - feedback; - } else { + } + else { feedback = 31; } + UpdateSynth(chip); +} + +void Channel::UpdateSynth( const Chip* chip ) { //Select the new synth mode if ( chip->opl3Active ) { //4-op mode enabled for this channel @@ -761,20 +766,20 @@ void Channel::WriteC0( const Chip* chip, Bit8u val ) { } else if ((fourMask & 0x40) && ( chip->regBD & 0x20) ) { //Regular dual op, am or fm - } else if ( val & 1 ) { + } else if (regC0 & 1 ) { synthHandler = &Channel::BlockTemplate< sm3AM >; } else { synthHandler = &Channel::BlockTemplate< sm3FM >; } - maskLeft = ( val & 0x10 ) ? -1 : 0; - maskRight = ( val & 0x20 ) ? -1 : 0; + maskLeft = (regC0 & 0x10 ) ? -1 : 0; + maskRight = (regC0 & 0x20 ) ? -1 : 0; //opl2 active } else { //Disable updating percussion channels if ( (fourMask & 0x40) && ( chip->regBD & 0x20 ) ) { //Regular dual op, am or fm - } else if ( val & 1 ) { + } else if (regC0 & 1 ) { synthHandler = &Channel::BlockTemplate< sm2AM >; } else { synthHandler = &Channel::BlockTemplate< sm2FM >; @@ -782,12 +787,6 @@ void Channel::WriteC0( const Chip* chip, Bit8u val ) { } } -void Channel::ResetC0( const Chip* chip ) { - Bit8u val = regC0; - regC0 ^= 0xff; - WriteC0( chip, val ); -}; - template< bool opl3Mode> INLINE void Channel::GeneratePercussion( Chip* chip, Bit32s* output ) { Channel* chan = this; @@ -1071,7 +1070,8 @@ void Chip::WriteBD( Bit8u val ) { //Toggle keyoffs when we turn off the percussion } else if ( change & 0x20 ) { //Trigger a reset to setup the original synth handler - chan[6].ResetC0( this ); + //This makes it call + chan[6].UpdateSynth( this ); chan[6].op[0].KeyOff( 0x2 ); chan[6].op[1].KeyOff( 0x2 ); chan[7].op[0].KeyOff( 0x2 ); @@ -1096,6 +1096,14 @@ void Chip::WriteBD( Bit8u val ) { regChan->_FUNC_( this, val ); \ } +//Update the 0xc0 register for all channels to signal the switch to mono/stereo handlers +void Chip::UpdateSynths() { + for (int i = 0; i < 18; i++) { + chan[i].UpdateSynth(this); + } +} + + void Chip::WriteReg( Bit32u reg, Bit8u val ) { Bitu index; switch ( (reg & 0xf0) >> 4 ) { @@ -1108,15 +1116,16 @@ void Chip::WriteReg( Bit32u reg, Bit8u val ) { return; //Always keep the highest bit enabled, for checking > 0x80 reg104 = 0x80 | ( val & 0x3f ); + //Switch synths when changing the 4op combinations + UpdateSynths(); } else if ( reg == 0x105 ) { //MAME says the real opl3 doesn't reset anything on opl3 disable/enable till the next write in another register if ( !((opl3Active ^ val) & 1 ) ) return; opl3Active = ( val & 1 ) ? 0xff : 0; - //Update the 0xc0 register for all channels to signal the switch to mono/stereo handlers - for ( int i = 0; i < 18;i++ ) { - chan[i].ResetC0( this ); - } + //Just tupdate the synths now that opl3 most have been enabled + //This isn't how the real card handles it but need to switch to stereo generating handlers + UpdateSynths(); } else if ( reg == 0x08 ) { reg08 = val; } diff --git a/src/hardware/dbopl.h b/src/hardware/dbopl.h index c3c4d428..e33d7e35 100644 --- a/src/hardware/dbopl.h +++ b/src/hardware/dbopl.h @@ -176,10 +176,10 @@ struct Channel { void SetChanData( const Chip* chip, Bit32u data ); //Change in the chandata, check for new values and if we have to forward to operators void UpdateFrequency( const Chip* chip, Bit8u fourOp ); + void UpdateSynth(const Chip* chip); void WriteA0( const Chip* chip, Bit8u val ); void WriteB0( const Chip* chip, Bit8u val ); void WriteC0( const Chip* chip, Bit8u val ); - void ResetC0( const Chip* chip ); //call this for the first channel template< bool opl3Mode > @@ -239,6 +239,8 @@ struct Chip { void GenerateBlock2( Bitu samples, Bit32s* output ); void GenerateBlock3( Bitu samples, Bit32s* output ); + //Update the synth handlers in all channels + void UpdateSynths(); void Generate( Bit32u samples ); void Setup( Bit32u r ); From 75568f7d90b54737025f5e30549fbdcb1db859c8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 4 Dec 2017 19:27:31 +0000 Subject: [PATCH 3975/4131] Fix bug where joysticks got disabled after a section restart (when changing parameters while running). Add code to map circularly restricted analogue input to be mapped to squares. Add deadzone support in both square and circular mode. Add deadzone=100 as fake digital device (idea by Hidden Asbestos) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4065 --- src/dosbox.cpp | 10 ++- src/hardware/joystick.cpp | 175 ++++++++++++++++++++++++++++++-------- 2 files changed, 150 insertions(+), 35 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 95fa429e..e78fa007 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -686,10 +686,18 @@ void DOSBOX_Init(void) { Pbool->Set_help("continuously fires as long as you keep the button pressed."); Pbool = secprop->Add_bool("swap34",Property::Changeable::WhenIdle,false); - Pbool->Set_help("swap the 3rd and the 4th axis. can be useful for certain joysticks."); + Pbool->Set_help("swap the 3rd and the 4th axis. Can be useful for certain joysticks."); Pbool = secprop->Add_bool("buttonwrap",Property::Changeable::WhenIdle,false); Pbool->Set_help("enable button wrapping at the number of emulated buttons."); + + Pbool = secprop->Add_bool("circularinput",Property::Changeable::WhenIdle,false); + Pbool->Set_help("enable translation of circular input to square output.\n" + "Try enabling this if your left analog stick can only move in a circle."); + + Pint = secprop->Add_int("deadzone",Property::Changeable::WhenIdle,10); + Pint->SetMinMax(0,100); + Pint->Set_help("the percentage of motion to ignore. 100 turns the stick into a digital one."); secprop=control->AddSection_prop("serial",&SERIAL_Init,true); const char* serials[] = { "dummy", "disabled", "modem", "nullmodem", diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index d30d234c..a9ae2321 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -18,6 +18,7 @@ #include +#include #include "dosbox.h" #include "inout.h" #include "setup.h" @@ -25,6 +26,12 @@ #include "pic.h" #include "support.h" + +//TODO: higher axis can't be mapped. Find out why again + +//Set to true, to enable automated switching back to square on circle mode if the inputs are outside the cirle. +#define SUPPORT_MAP_AUTO 0 + #define RANGE 64 #define TIMEOUT 10 @@ -33,17 +40,104 @@ #define S_PER_OHM 0.000000011 struct JoyStick { + enum {JOYMAP_SQUARE,JOYMAP_CIRCLE,JOYMAP_INBETWEEN} mapstate; bool enabled; - float xpos,ypos; - double xtick,ytick; - Bitu xcount,ycount; + float xpos, ypos; //position as set by SDL. + double xtick, ytick; + Bitu xcount, ycount; bool button[2]; + int deadzone; //Deadzone (value between 0 and 100) interpreted as percentage. + bool transformed; //Whether xpos,ypos have been converted to xfinal and yfinal. Cleared when new xpos orypos have been set + float xfinal, yfinal; //position returned to the game for stick 0. + + void clip() { + if (xfinal > 1.0) xfinal = 1.0; + else if (xfinal < -1.0) xfinal = -1.0; + if (yfinal > 1.0) yfinal = 1.0; + else if (yfinal < -1.0) yfinal = -1.0; + } + + void fake_digital() { + if (xpos > 0.5f) xfinal = 1.0f; + else if (xpos < -0.5f) xfinal = -1.0f; + else xfinal = 0.0f; + if (ypos > 0.5f) yfinal = 1.0f; + else if (ypos < -0.5f) yfinal = -1.0f; + else yfinal = 0.0f; + } + + void transform_circular(){ + float r = sqrt(xpos * xpos + ypos * ypos); + if (r == 0.0) {xfinal = xpos; yfinal = ypos; return;} + float deadzone_f = deadzone / 100.0f; + float s = 1.0f - deadzone_f; + if (r < deadzone_f) { + xfinal = yfinal = 0.0f; + return; + } + + float deadzonescale = (r - deadzone_f) / s; //r if deadzone=0; + float xa = fabs(xpos); + float ya = fabs(ypos); + float maxpos = (ya>xa?ya:xa); + xfinal = xpos * deadzonescale/maxpos; + yfinal = ypos * deadzonescale/maxpos; + } + + void transform_square() { + float deadzone_f = deadzone / 100.0f; + float s = 1.0f - deadzone_f; + + if (xpos > deadzone_f) { + xfinal = (xpos - deadzone_f)/ s; + } else if ( xpos < -deadzone_f) { + xfinal = (xpos + deadzone_f) / s; + } else xfinal = 0.0f; + if (ypos > deadzone_f) { + yfinal = (ypos - deadzone_f)/ s; + } else if ( ypos < - deadzone_f) { + yfinal = (ypos + deadzone_f) / s; + } else yfinal = 0.0f; + } + +#if SUPPORT_MAP_AUTO + void transform_inbetween(){ + //First transform to a circle and crop the values to -1.0 -> 1.0 + //then keep on doing this in future calls until it is safe to switch square mapping + // safe = 0.95 as ratio for both axis, or in deadzone + transform_circular(); + clip(); + + + float xrate = xpos / xfinal; + float yrate = ypos / yfinal; + if (xrate > 0.95 && yrate > 0.95) { + mapstate = JOYMAP_SQUARE; //TODO misschien xfinal=xpos... + //LOG_MSG("switched to square %f %f",xrate,yrate); + } + } +#endif + void transform_input(){ + if (transformed) return; + transformed = true; + if (deadzone == 100) fake_digital(); + else { + if (mapstate == JOYMAP_SQUARE) transform_square(); + else if (mapstate == JOYMAP_CIRCLE) transform_circular(); +#if SUPPORT_MAP_AUTO + if (mapstate == JOYMAP_INBETWEEN) transform_inbetween(); //No else here +#endif + clip(); + } + } + + }; JoystickType joytype; static JoyStick stick[2]; -static Bit32u last_write = 0; +static Bitu last_write = 0; static bool write_active = false; static bool swap34 = false; bool button_wrapping_enabled = true; @@ -114,8 +208,9 @@ static void write_p201(Bitu port,Bitu val,Bitu iolen) { write_active = true; last_write = PIC_Ticks; if (stick[0].enabled) { - stick[0].xcount=(Bitu)((stick[0].xpos*RANGE)+RANGE); - stick[0].ycount=(Bitu)((stick[0].ypos*RANGE)+RANGE); + stick[0].transform_input(); + stick[0].xcount=(Bitu)((stick[0].xfinal*RANGE)+RANGE); + stick[0].ycount=(Bitu)((stick[0].yfinal*RANGE)+RANGE); } if (stick[1].enabled) { stick[1].xcount=(Bitu)(((swap34? stick[1].ypos : stick[1].xpos)*RANGE)+RANGE); @@ -124,16 +219,16 @@ static void write_p201(Bitu port,Bitu val,Bitu iolen) { } static void write_p201_timed(Bitu port,Bitu val,Bitu iolen) { - // Store writetime index // Axes take time = 24.2 microseconds + ( 0.011 microsecons/ohm * resistance ) // to reset to 0 - // Precalculate the time at which each axis hits 0 here + // Pre-calculate the time at which each axis hits 0 here double currentTick = PIC_FullIndex(); if (stick[0].enabled) { + stick[0].transform_input(); stick[0].xtick = currentTick + 1000.0*( JOY_S_CONSTANT + S_PER_OHM * - (double)(((stick[0].xpos+1.0)* OHMS)) ); + (double)(((stick[0].xfinal+1.0)* OHMS)) ); stick[0].ytick = currentTick + 1000.0*( JOY_S_CONSTANT + S_PER_OHM * - (double)(((stick[0].ypos+1.0)* OHMS)) ); + (double)(((stick[0].yfinal+1.0)* OHMS)) ); } if (stick[1].enabled) { stick[1].xtick = currentTick + 1000.0*( JOY_S_CONSTANT + S_PER_OHM * @@ -144,23 +239,27 @@ static void write_p201_timed(Bitu port,Bitu val,Bitu iolen) { } void JOYSTICK_Enable(Bitu which,bool enabled) { - if (which<2) stick[which].enabled=enabled; + if (which<2) stick[which].enabled = enabled; } void JOYSTICK_Button(Bitu which,Bitu num,bool pressed) { - if ((which<2) && (num<2)) stick[which].button[num]=pressed; + if ((which<2) && (num<2)) stick[which].button[num] = pressed; } void JOYSTICK_Move_X(Bitu which,float x) { - if (which<2) { - stick[which].xpos=x; - } + if(which > 2) return; + if (stick[which].xpos == x) return; + stick[which].xpos = x; + stick[which].transformed = false; +// if( which == 0 || joytype != JOY_FCS) +// stick[which].applied_conversion; //todo } void JOYSTICK_Move_Y(Bitu which,float y) { - if (which<2) { - stick[which].ypos=y; - } + if(which > 2) return; + if (stick[which].ypos == y) return; + stick[which].ypos = y; + stick[which].transformed = false; } bool JOYSTICK_IsEnabled(Bitu which) { @@ -174,13 +273,15 @@ bool JOYSTICK_GetButton(Bitu which, Bitu num) { } float JOYSTICK_GetMove_X(Bitu which) { - if (which<2) return stick[which].xpos; - return 0.0f; + if (which > 1) return 0.0f; + if (which == 0) { stick[0].transform_input(); return stick[0].xfinal;} + return stick[1].xpos; } float JOYSTICK_GetMove_Y(Bitu which) { - if (which<2) return stick[which].ypos; - return 0.0f; + if (which > 1) return 0.0f; + if (which == 0) { stick[0].transform_input(); return stick[0].yfinal;} + return stick[1].ypos; } class JOYSTICK:public Module_base{ @@ -189,20 +290,20 @@ private: IO_WriteHandleObject WriteHandler; public: JOYSTICK(Section* configuration):Module_base(configuration){ - Section_prop * section=static_cast(configuration); - const char * type=section->Get_string("joysticktype"); - if (!strcasecmp(type,"none")) joytype = JOY_NONE; - else if (!strcasecmp(type,"false")) joytype = JOY_NONE; - else if (!strcasecmp(type,"auto")) joytype = JOY_AUTO; - else if (!strcasecmp(type,"2axis")) joytype = JOY_2AXIS; - else if (!strcasecmp(type,"4axis")) joytype = JOY_4AXIS; + Section_prop * section = static_cast(configuration); + const char * type = section->Get_string("joysticktype"); + if (!strcasecmp(type,"none")) joytype = JOY_NONE; + else if (!strcasecmp(type,"false")) joytype = JOY_NONE; + else if (!strcasecmp(type,"auto")) joytype = JOY_AUTO; + else if (!strcasecmp(type,"2axis")) joytype = JOY_2AXIS; + else if (!strcasecmp(type,"4axis")) joytype = JOY_4AXIS; else if (!strcasecmp(type,"4axis_2")) joytype = JOY_4AXIS_2; - else if (!strcasecmp(type,"fcs")) joytype = JOY_FCS; - else if (!strcasecmp(type,"ch")) joytype = JOY_CH; + else if (!strcasecmp(type,"fcs")) joytype = JOY_FCS; + else if (!strcasecmp(type,"ch")) joytype = JOY_CH; else joytype = JOY_AUTO; bool timed = section->Get_bool("timed"); - if(timed) { + if (timed) { ReadHandler.Install(0x201,read_p201_timed,IO_MB); WriteHandler.Install(0x201,write_p201_timed,IO_MB); } else { @@ -212,10 +313,16 @@ public: autofire = section->Get_bool("autofire"); swap34 = section->Get_bool("swap34"); button_wrapping_enabled = section->Get_bool("buttonwrap"); - stick[0].enabled = false; - stick[1].enabled = false; stick[0].xtick = stick[0].ytick = stick[1].xtick = stick[1].ytick = PIC_FullIndex(); + stick[0].xpos = stick[0].ypos = stick[1].xpos = stick[1].ypos = 0.0f; + stick[0].transformed = false; + + + stick[0].mapstate = JoyStick::JOYMAP_SQUARE; + bool circ = section->Get_bool("circularinput"); + if (circ) stick[0].mapstate = JoyStick::JOYMAP_CIRCLE; + stick[0].deadzone = section->Get_int("deadzone"); } }; static JOYSTICK* test; From d949fee410d4facc0f52a40f22f429e7df4b187f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Fri, 8 Dec 2017 15:31:59 +0000 Subject: [PATCH 3976/4131] Allow an autoinit transfer to go over into a single cycle transfer Fixes Paddlers. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4066 --- src/hardware/sblaster.cpp | 56 ++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 836f5c81..f9ef28fd 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -396,8 +396,10 @@ static void GenerateDMASound(Bitu size) { Bitu read=0;Bitu done=0;Bitu i=0; if(sb.dma.autoinit) { - if (sb.dma.left <= size) size = sb.dma.left; - } else if (sb.dma.left <= sb.dma.min) size = sb.dma.left; + if (sb.dma.left <= size) + size = sb.dma.left; + } else if (sb.dma.left <= sb.dma.min) + size = sb.dma.left; switch (sb.dma.mode) { case DSP_DMA_2: @@ -503,14 +505,22 @@ static void GenerateDMASound(Bitu size) { sb.dma.left-=read; if (!sb.dma.left) { PIC_RemoveEvents(END_DMA_Event); - if (sb.dma.mode >= DSP_DMA_16) SB_RaiseIRQ(SB_IRQ_16); - else SB_RaiseIRQ(SB_IRQ_8); + if (sb.dma.mode >= DSP_DMA_16) + SB_RaiseIRQ(SB_IRQ_16); + else + SB_RaiseIRQ(SB_IRQ_8); + //Copy the new size + sb.dma.left = sb.dma.total; if (!sb.dma.autoinit) { - LOG(LOG_SB,LOG_NORMAL)("Single cycle transfer ended"); - sb.mode=MODE_NONE; - sb.dma.mode=DSP_DMA_NONE; + if (!sb.dma.left) { + LOG(LOG_SB, LOG_NORMAL)("Single cycle transfer ended"); + sb.mode = MODE_NONE; + sb.dma.mode = DSP_DMA_NONE; + } + else { + LOG(LOG_SB, LOG_NORMAL)("Switch to Single cycle transfer begun"); + } } else { - sb.dma.left=sb.dma.total; if (!sb.dma.left) { LOG(LOG_SB,LOG_NORMAL)("Auto-init transfer with 0 size"); sb.mode=MODE_NONE; @@ -544,7 +554,8 @@ static void DMA_Silent_Event(Bitu val) { if (!sb.dma.left) { if (sb.dma.mode >= DSP_DMA_16) SB_RaiseIRQ(SB_IRQ_16); else SB_RaiseIRQ(SB_IRQ_8); - if (sb.dma.autoinit) sb.dma.left=sb.dma.total; + if (sb.dma.autoinit) + sb.dma.left=sb.dma.total; else { sb.mode=MODE_NONE; sb.dma.mode=DSP_DMA_NONE; @@ -586,15 +597,26 @@ static void DSP_RaiseIRQEvent(Bitu /*val*/) { SB_RaiseIRQ(SB_IRQ_8); } -static void DSP_DoDMATransfer(DMA_MODES mode,Bitu freq,bool stereo) { +static void DSP_DoDMATransfer(DMA_MODES mode,Bitu freq,bool autoinit, bool stereo) { char const * type; - sb.mode=MODE_DMA_MASKED; + //Fill up before changing state? sb.chan->FillUp(); - sb.dma.left=sb.dma.total; + //No active autoinit transfer then just assume it's a completely new one + if (sb.mode != MODE_DMA || !sb.dma.autoinit) { + sb.dma.left = sb.dma.total; + //The new transfer won't be autoinit so can clear the total now + if (!autoinit) { + sb.dma.total = 0; + } + //Starting a new transfer might as well clear the irq's + sb.irq.pending_8bit = false; + sb.irq.pending_16bit = false; + } + sb.mode = MODE_DMA_MASKED; sb.dma.mode=mode; sb.dma.stereo=stereo; - sb.irq.pending_8bit=false; - sb.irq.pending_16bit=false; + sb.dma.autoinit = autoinit; + switch (mode) { case DSP_DMA_2: type="2-bits ADPCM"; @@ -642,18 +664,16 @@ static void DSP_DoDMATransfer(DMA_MODES mode,Bitu freq,bool stereo) { } static void DSP_PrepareDMA_Old(DMA_MODES mode,bool autoinit,bool sign) { - sb.dma.autoinit=autoinit; sb.dma.sign=sign; if (!autoinit) sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); sb.dma.chan=GetDMAChannel(sb.hw.dma8); - DSP_DoDMATransfer(mode,sb.freq / (sb.mixer.stereo ? 2 : 1),sb.mixer.stereo); + DSP_DoDMATransfer(mode,sb.freq / (sb.mixer.stereo ? 2 : 1), autoinit, sb.mixer.stereo); } static void DSP_PrepareDMA_New(DMA_MODES mode,Bitu length,bool autoinit,bool stereo) { Bitu freq=sb.freq; //equal length if data format and dma channel are both 16-bit or 8-bit sb.dma.total=length; - sb.dma.autoinit=autoinit; if (mode==DSP_DMA_16) { if (sb.hw.dma16!=0xff) { sb.dma.chan=GetDMAChannel(sb.hw.dma16); @@ -671,7 +691,7 @@ static void DSP_PrepareDMA_New(DMA_MODES mode,Bitu length,bool autoinit,bool ste sb.dma.total<<=1; } } else sb.dma.chan=GetDMAChannel(sb.hw.dma8); - DSP_DoDMATransfer(mode,freq,stereo); + DSP_DoDMATransfer(mode,freq,autoinit,stereo); } From 85b0c547efff1c8418b754f00a112d620bc3b76a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 13 Dec 2017 15:50:55 +0000 Subject: [PATCH 3977/4131] Fix output of configure when --disable-opengl is used Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4067 --- configure.ac | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure.ac b/configure.ac index 4800454b..78c92e44 100644 --- a/configure.ac +++ b/configure.ac @@ -434,6 +434,8 @@ case "$host" in fi ;; esac +else + AC_MSG_RESULT(no) fi AH_TEMPLATE(C_DDRAW,[Define to 1 to enable output=ddraw (Win32)]) From 542e068f97857d52a2055267223ea033d1718ed6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 26 Dec 2017 19:03:44 +0000 Subject: [PATCH 3978/4131] Fix compilation on current clang++ Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4068 --- src/hardware/serialport/nullmodem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/serialport/nullmodem.cpp b/src/hardware/serialport/nullmodem.cpp index 69182db7..bbb35fb5 100644 --- a/src/hardware/serialport/nullmodem.cpp +++ b/src/hardware/serialport/nullmodem.cpp @@ -148,7 +148,7 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) { setCTS(dtrrespect||transparent); setDSR(dtrrespect||transparent); setRI(false); - setCD(clientsocket > 0); // CD on if connection established + setCD(clientsocket != 0); // CD on if connection established } CNullModem::~CNullModem() { From 06c91d8d0bed3ee62413092c6001649c9deb0640 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Jan 2018 15:56:33 +0000 Subject: [PATCH 3979/4131] Beautify CPU_CheckSegments in order to silence a warning (if (A) B; break (which get a misleading warning as break is not part of the if)) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4069 --- src/cpu/cpu.cpp | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 832e000c..473d69c9 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -228,44 +228,48 @@ bool CPU_PUSHF(Bitu use32) { } void CPU_CheckSegments(void) { - bool needs_invalidation=false; + bool needs_invalidation = false; Descriptor desc; - if (!cpu.gdt.GetDescriptor(SegValue(es),desc)) needs_invalidation=true; + if (!cpu.gdt.GetDescriptor(SegValue(es),desc)) needs_invalidation = true; else switch (desc.Type()) { case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) needs_invalidation=true; break; + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl > desc.DPL()) needs_invalidation = true; + break; default: break; } if (needs_invalidation) CPU_SetSegGeneral(es,0); - needs_invalidation=false; - if (!cpu.gdt.GetDescriptor(SegValue(ds),desc)) needs_invalidation=true; + needs_invalidation = false; + if (!cpu.gdt.GetDescriptor(SegValue(ds),desc)) needs_invalidation = true; else switch (desc.Type()) { case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) needs_invalidation=true; break; + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl > desc.DPL()) needs_invalidation = true; + break; default: break; } if (needs_invalidation) CPU_SetSegGeneral(ds,0); - needs_invalidation=false; - if (!cpu.gdt.GetDescriptor(SegValue(fs),desc)) needs_invalidation=true; + needs_invalidation = false; + if (!cpu.gdt.GetDescriptor(SegValue(fs),desc)) needs_invalidation = true; else switch (desc.Type()) { case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) needs_invalidation=true; break; + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl > desc.DPL()) needs_invalidation = true; + break; default: break; } if (needs_invalidation) CPU_SetSegGeneral(fs,0); - needs_invalidation=false; - if (!cpu.gdt.GetDescriptor(SegValue(gs),desc)) needs_invalidation=true; + needs_invalidation = false; + if (!cpu.gdt.GetDescriptor(SegValue(gs),desc)) needs_invalidation = true; else switch (desc.Type()) { case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) needs_invalidation=true; break; + case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: + if (cpu.cpl > desc.DPL()) needs_invalidation = true; + break; default: break; } if (needs_invalidation) CPU_SetSegGeneral(gs,0); } From 6485a8010218dd12304bec0635bd8fdb966bf887 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Jan 2018 15:57:27 +0000 Subject: [PATCH 3980/4131] Silence a warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4070 --- src/shell/shell_cmds.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 09654ec7..978dab59 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -796,7 +796,8 @@ void DOS_Shell::CMD_SET(char * args) { *p_parsed++ = '%'; p += 2; //%% => % } else { char * second = strchr(++p,'%'); - if(!second) continue; *second++ = 0; + if (!second) continue; + *second++ = 0; std::string temp; if (GetEnvStr(p,temp)) { std::string::size_type equals = temp.find('='); From aa8bf6041ea972b1bc533561310b1245b11436c0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 30 Jan 2018 15:58:28 +0000 Subject: [PATCH 3981/4131] Declare static functions in header file as static inline, as that reduces warnings quite a bit. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4071 --- src/ints/int10.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ints/int10.h b/src/ints/int10.h index e9b622b0..bc599125 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -149,11 +149,11 @@ typedef struct { extern Int10Data int10; -static Bit8u CURSOR_POS_COL(Bit8u page) { +static inline Bit8u CURSOR_POS_COL(Bit8u page) { return real_readb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2); } -static Bit8u CURSOR_POS_ROW(Bit8u page) { +static inline Bit8u CURSOR_POS_ROW(Bit8u page) { return real_readb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2+1); } From f7ae7a1dbe266df7a4e03ba9edad7da016c4f933 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 31 Jan 2018 10:21:41 +0000 Subject: [PATCH 3982/4131] Fix narrowing warnings (errors on clang/freebsd) and an unhandled value in switch. (Part of patch #275 from strageqargo) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4072 --- src/dos/dos_programs.cpp | 2 +- src/hardware/vga_other.cpp | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index e905783d..51bf01b1 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -75,7 +75,7 @@ public: for (int d = 0;d < DOS_DRIVES;d++) { if (!Drives[d]) continue; - char root[7] = {'A'+d,':','\\','*','.','*',0}; + char root[7] = {static_cast('A'+d),':','\\','*','.','*',0}; bool ret = DOS_FindFirst(root,DOS_ATTR_VOLUME); if (ret) { dta.GetResult(name,size,date,time,attr); diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index e8115eed..068a8f42 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -280,9 +280,9 @@ static void update_cga16_color(void) { } Bitu CGApal[4] = { overscan, - 2 + (color_sel||bw ? 1 : 0) + (background_i ? 8 : 0), - 4 + (color_sel&&!bw? 1 : 0) + (background_i ? 8 : 0), - 6 + (color_sel||bw ? 1 : 0) + (background_i ? 8 : 0) + static_cast(2 + (color_sel||bw ? 1 : 0) + (background_i ? 8 : 0)), + static_cast(4 + (color_sel&&!bw? 1 : 0) + (background_i ? 8 : 0)), + static_cast(6 + (color_sel||bw ? 1 : 0) + (background_i ? 8 : 0)) }; for (Bit8u x=0; x<4; x++) { // Position of pixel in question bool even = (x & 1) == 0; @@ -381,6 +381,8 @@ static void write_cga_color_select(Bitu val) { vga.tandy.border_color = val & 0xf; vga.attr.overscan_color = 0; break; + default: //Else unhandled values warning + break; } } From 5cb34a071d89d1f57de3e57bab8ee9f0f75c480a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 31 Jan 2018 18:21:54 +0000 Subject: [PATCH 3983/4131] Correct small error/warning. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4073 --- src/dos/dos_mscdex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 321c1ea6..d6369d39 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -715,7 +715,7 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph do { entryLength = mem_readb(defBuffer+index); if (entryLength==0) break; - if (mem_readb(defBuffer+index+iso ? 0x19:0x18) & 4) { + if (mem_readb(defBuffer + index + (iso?0x19:0x18) ) & 4) { // skip associated files index += entryLength; continue; From 6283b6b5b8d51c090ce5c39a6e2648e92a5bccff Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 31 Jan 2018 19:03:49 +0000 Subject: [PATCH 3984/4131] Another non-format warning fixed Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4074 --- src/hardware/tandy_sound.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 5d3ef2ea..8153e7be 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -405,7 +405,7 @@ static void TandyDACWrite(Bitu port,Bitu data,Bitu /*iolen*/) { } break; case 0xc6: - tandy.dac.frequency = tandy.dac.frequency & 0xf00 | (Bit8u)(data&0xff); + tandy.dac.frequency = (tandy.dac.frequency & 0xf00) | (Bit8u)(data & 0xff); switch (tandy.dac.mode&3) { case 0: // joystick mode @@ -418,7 +418,7 @@ static void TandyDACWrite(Bitu port,Bitu data,Bitu /*iolen*/) { } break; case 0xc7: - tandy.dac.frequency = tandy.dac.frequency & 0x00ff | (((Bit8u)(data&0xf))<<8); + tandy.dac.frequency = (tandy.dac.frequency & 0x00ff) | (((Bit8u)(data & 0xf)) << 8); tandy.dac.amplitude = (Bit8u)(data>>5); switch (tandy.dac.mode&3) { case 0: From 06337c9b132d62e640cf442ce2137362862ec019 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 8 Feb 2018 13:53:13 +0000 Subject: [PATCH 3985/4131] Declare the init function of the joystick as restartable, so some of the dynamic settings work. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4076 --- src/dosbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 8f017c60..df040f09 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -665,7 +665,7 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("joystick",&BIOS_Init,false);//done secprop->AddInitFunction(&INT10_Init); secprop->AddInitFunction(&MOUSE_Init); //Must be after int10 as it uses CurMode - secprop->AddInitFunction(&JOYSTICK_Init); + secprop->AddInitFunction(&JOYSTICK_Init,true); const char* joytypes[] = { "auto", "2axis", "4axis", "4axis_2", "fcs", "ch", "none",0}; Pstring = secprop->Add_string("joysticktype",Property::Changeable::WhenIdle,"auto"); Pstring->Set_values(joytypes); From eb2448316b20a621c91b231f7e292c56e5671a93 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 13 Feb 2018 22:07:41 +0000 Subject: [PATCH 3986/4131] Fix SBlaster issue with counter not being restarted with an autoinit transfer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4077 --- src/hardware/sblaster.cpp | 63 +++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index f9ef28fd..a2916fc8 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -73,7 +73,7 @@ enum DSP_MODES { MODE_DMA_MASKED }; - + enum DMA_MODES { DSP_DMA_NONE, DSP_DMA_2,DSP_DMA_3,DSP_DMA_4,DSP_DMA_8, @@ -601,21 +601,11 @@ static void DSP_DoDMATransfer(DMA_MODES mode,Bitu freq,bool autoinit, bool stere char const * type; //Fill up before changing state? sb.chan->FillUp(); - //No active autoinit transfer then just assume it's a completely new one - if (sb.mode != MODE_DMA || !sb.dma.autoinit) { - sb.dma.left = sb.dma.total; - //The new transfer won't be autoinit so can clear the total now - if (!autoinit) { - sb.dma.total = 0; - } - //Starting a new transfer might as well clear the irq's - sb.irq.pending_8bit = false; - sb.irq.pending_16bit = false; - } - sb.mode = MODE_DMA_MASKED; - sb.dma.mode=mode; - sb.dma.stereo=stereo; - sb.dma.autoinit = autoinit; + + //Starting a new transfer will clear any active irqs? + sb.irq.pending_8bit = false; + sb.irq.pending_16bit = false; + PIC_DeActivateIRQ(sb.hw.irq); switch (mode) { case DSP_DMA_2: @@ -646,21 +636,42 @@ static void DSP_DoDMATransfer(DMA_MODES mode,Bitu freq,bool autoinit, bool stere LOG(LOG_SB,LOG_ERROR)("DSP:Illegal transfer mode %d",mode); return; } - if (sb.dma.stereo) sb.dma.mul*=2; + +#if (C_DEBUG) + LOG(LOG_SB, LOG_NORMAL)("DMA Transfer:%s %s %s freq %d rate %d size %d", + type, + stereo ? "Stereo" : "Mono", + autoinit ? "Auto-Init" : "Single-Cycle", + freq, sb.dma.rate, sb.dma.total + ); +#endif + //Going from an active autoinit into a single cycle + if (sb.mode >= MODE_DMA && sb.dma.autoinit && !autoinit) { + //Don't do anything, the total will flip over on the next transfer + } + //Just a normal single cycle transfer + else if (!autoinit) { + sb.dma.left = sb.dma.total; + sb.dma.total = 0; + } + //Going into an autoinit transfer + else { + //Transfer full cycle again + sb.dma.left = sb.dma.total; + } + //Double the reading speed for stereo mode + if (sb.dma.stereo) + sb.dma.mul*=2; sb.dma.rate=(sb.freq*sb.dma.mul) >> SB_SH; sb.dma.min=(sb.dma.rate*3)/1000; sb.chan->SetFreq(freq); - sb.dma.mode=mode; + sb.dma.mode = mode; + sb.dma.stereo = stereo; + sb.dma.autoinit = autoinit; PIC_RemoveEvents(END_DMA_Event); + //Set to be masked, the dma call can change this again. + sb.mode = MODE_DMA_MASKED; sb.dma.chan->Register_Callback(DSP_DMA_CallBack); -#if (C_DEBUG) - LOG(LOG_SB,LOG_NORMAL)("DMA Transfer:%s %s %s freq %d rate %d size %d", - type, - sb.dma.stereo ? "Stereo" : "Mono", - sb.dma.autoinit ? "Auto-Init" : "Single-Cycle", - freq,sb.dma.rate,sb.dma.total - ); -#endif } static void DSP_PrepareDMA_Old(DMA_MODES mode,bool autoinit,bool sign) { From 618950d13a50e2b631f69f6780a26d64072d4192 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 16 Feb 2018 08:57:21 +0000 Subject: [PATCH 3987/4131] Enable core inlining by default on configure/make build system Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4078 --- configure.ac | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 477ab5b8..89320741 100644 --- a/configure.ac +++ b/configure.ac @@ -240,13 +240,14 @@ AC_ARG_ENABLE(debug,AC_HELP_STRING([--enable-debug],[Enable debug mode]),[ ],) AH_TEMPLATE(C_CORE_INLINE,[Define to 1 to use inlined memory functions in cpu core]) -AC_ARG_ENABLE(core-inline,AC_HELP_STRING([--enable-core-inline],[Enable inlined memory handling in CPU Core]),[ - if test x$enable_core_inline = xyes ; then - AC_MSG_RESULT([enabling inlined memory handling in CPU Core]) +AC_ARG_ENABLE(core-inline,AC_HELP_STRING([--disable-core-inline],[Disable inlined memory handling in CPU Core]),,enable_core_inline=yes) +AC_MSG_CHECKING(whether memory handling in the CPU Core will be inlined) +if test x$enable_core_inline = xyes ; then + AC_MSG_RESULT(yes) AC_DEFINE(C_CORE_INLINE,1) - fi -],) - +else + AC_MSG_RESULT(no) +fi dnl The target cpu checks for dynamic cores AH_TEMPLATE(C_TARGETCPU,[The type of cpu this target has]) From ae683cd7944768f5b88c85a75627da3aacbdb941 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 17 Feb 2018 15:16:44 +0000 Subject: [PATCH 3988/4131] Remove exception specifiers as they are depreciated. Remove some trailing spaces and add some spaces for readability. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4079 --- include/setup.h | 57 +++++++------- src/misc/setup.cpp | 186 ++++++++++++++++++++++----------------------- 2 files changed, 121 insertions(+), 122 deletions(-) diff --git a/include/setup.h b/include/setup.h index 15fc3b8c..345d027e 100644 --- a/include/setup.h +++ b/include/setup.h @@ -55,7 +55,6 @@ public: Hex():_hex(0) { }; bool operator==(Hex const& other) {return _hex == other._hex;} operator int () const { return _hex; } - }; class Value { @@ -75,7 +74,7 @@ private: 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) { }; @@ -87,28 +86,28 @@ public: Value(Value const& in):_string(0) {plaincopy(in);} ~Value() { destroy();}; Value(std::string const& in,Etype _t) :_hex(0),_bool(false),_int(0),_string(0),_double(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));} + Value& operator= (Hex in) { return copy(Value(in));} + Value& operator= (int in) { return copy(Value(in));} + Value& operator= (bool in) { return copy(Value(in));} + Value& operator= (double in) { return copy(Value(in));} + Value& operator= (std::string const& in) { return copy(Value(in));} + Value& operator= (char const * const in) { return copy(Value(in));} + Value& operator= (Value const& in) { 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); - bool SetValue(std::string const& in,Etype _type = V_CURRENT) throw(WrongType); + operator bool () const; + operator Hex () const; + operator int () const; + operator double () const; + operator char const* () const; + bool SetValue(std::string const& in,Etype _type = V_CURRENT); std::string ToString() const; private: void destroy() throw(); - Value& copy(Value const& in) throw(WrongType); + Value& copy(Value const& in); void plaincopy(Value const& in) throw(); bool set_hex(std::string const& in); bool set_int(std::string const&in); @@ -134,7 +133,7 @@ public: //specific features. virtual bool CheckValue(Value const& in, bool warn); public: - virtual ~Property(){ } + virtual ~Property(){ } virtual const std::vector& GetValues() const; Value::Etype Get_type(){return default_value.type;} Changeable::Value getChange() {return change;} @@ -143,9 +142,9 @@ protected: //Set interval value to in or default if in is invalid. force always sets the value. //Can be overriden to set a different value if invalid. virtual bool SetVal(Value const& in, bool forced,bool warn=true) { - if(forced || CheckValue(in,warn)) { + if(forced || CheckValue(in,warn)) { value = in; return true; - } else { + } else { value = default_value; return false; } } @@ -159,12 +158,12 @@ protected: class Prop_int:public Property { public: Prop_int(std::string const& _propname,Changeable::Value when, int _value) - :Property(_propname,when) { + :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) { + :Property(_propname,when) { default_value = value = _value; min = _min; max = _max; @@ -177,7 +176,7 @@ public: virtual bool CheckValue(Value const& in, bool warn); // Override SetVal, so it takes min,max in account when there are no suggested values virtual bool SetVal(Value const& in, bool forced,bool warn=true); - + private: Value min,max; }; @@ -195,7 +194,7 @@ public: class Prop_bool:public Property { public: Prop_bool(std::string const& _propname, Changeable::Value when, bool _value) - :Property(_propname,when) { + :Property(_propname,when) { default_value = value = _value; } bool SetValue(std::string const& in); @@ -205,7 +204,7 @@ public: class Prop_string:public Property{ public: Prop_string(std::string const& _propname, Changeable::Value when, char const * const _value) - :Property(_propname,when) { + :Property(_propname,when) { default_value = value = _value; } bool SetValue(std::string const& in); @@ -216,7 +215,7 @@ 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) { + :Prop_string(_propname,when,_value) { default_value = value = _value; realpath = _value; } @@ -227,7 +226,7 @@ public: class Prop_hex:public Property { public: Prop_hex(std::string const& _propname, Changeable::Value when, Hex _value) - :Property(_propname,when) { + :Property(_propname,when) { default_value = value = _value; } bool SetValue(std::string const& in); @@ -281,7 +280,7 @@ public: 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); +// 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); @@ -324,7 +323,7 @@ public: virtual bool SetValue(std::string const& input); }; - + class Section_line: public Section{ public: Section_line(std::string const& _sectionname):Section(_sectionname){} diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index c79ae665..a15c289c 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -37,7 +37,7 @@ void Value::destroy() throw(){ if (type == V_STRING) delete _string; } -Value& Value::copy(Value const& in) throw(WrongType) { +Value& Value::copy(Value const& in) { if (this != &in) { //Selfassigment! if(type != V_NONE && type != in.type) throw WrongType(); destroy(); @@ -55,27 +55,27 @@ void Value::plaincopy(Value const& in) throw(){ if(type == V_STRING) _string = new string(*in._string); } -Value::operator bool () const throw(WrongType) { +Value::operator bool () const { if(type != V_BOOL) throw WrongType(); return _bool; } -Value::operator Hex () const throw(WrongType) { +Value::operator Hex () const { if(type != V_HEX) throw WrongType(); return _hex; } -Value::operator int () const throw(WrongType) { +Value::operator int () const { if(type != V_INT) throw WrongType(); return _int; } -Value::operator double () const throw(WrongType) { +Value::operator double () const { if(type != V_DOUBLE) throw WrongType(); return _double; } -Value::operator char const* () const throw(WrongType) { +Value::operator char const* () const { if(type != V_STRING) throw WrongType(); return _string->c_str(); } @@ -105,7 +105,7 @@ bool Value::operator==(Value const& other) { } return false; } -bool Value::SetValue(string const& in,Etype _type) throw(WrongType) { +bool Value::SetValue(string const& in,Etype _type) { /* Throw exception if the current type isn't the wanted type * Unless the wanted type is current. */ @@ -176,13 +176,13 @@ bool Value::set_bool(string const &in) { lowcase(result); _bool = true; // TODO if(!result.size()) return false; - + if(result=="0" || result=="disabled" || result=="false" || result=="off") { _bool = false; } else if(result=="1" || result=="enabled" || result=="true" || result=="on") { _bool = true; } else return false; - + return true; } @@ -260,7 +260,7 @@ bool Prop_int::SetVal(Value const& in, bool forced, bool warn) { int mi = min; int ma = max; int va = static_cast(Value(in)); - + //No ranges if (mi == -1 && ma == -1) { value = in; return true;} @@ -271,7 +271,7 @@ bool Prop_int::SetVal(Value const& in, bool forced, bool warn) { if (va > ma ) va = ma; else va = mi; if (warn) LOG_MSG("%s is outside the allowed range %s-%s for variable: %s.\nIt has been set to the closest boundary: %d.",in.ToString().c_str(),min.ToString().c_str(),max.ToString().c_str(),propname.c_str(),va); - + value = va; return true; } @@ -286,100 +286,98 @@ bool Prop_int::CheckValue(Value const& in, bool warn) { int va = static_cast(Value(in)); if (mi == -1 && ma == -1) return true; if (va >= mi && va <= ma) return true; - + if (warn) LOG_MSG("%s lies outside the range %s-%s for variable: %s.\nIt might now be reset to the default value: %s",in.ToString().c_str(),min.ToString().c_str(),max.ToString().c_str(),propname.c_str(),default_value.ToString().c_str()); return false; } -bool Prop_double::SetValue(std::string const& input){ +bool Prop_double::SetValue(std::string const& input) { Value val; if(!val.SetValue(input,Value::V_DOUBLE)) return false; return SetVal(val,false,true); } -//void Property::SetValue(char* input){ +//void Property::SetValue(char* input){ // value.SetValue(input, Value::V_CURRENT); //} -bool Prop_int::SetValue(std::string const& input){; +bool Prop_int::SetValue(std::string const& input) { Value val; - if(!val.SetValue(input,Value::V_INT)) return false; + if (!val.SetValue(input,Value::V_INT)) return false; bool retval = SetVal(val,false,true); return retval; } -bool Prop_string::SetValue(std::string const& input){ +bool Prop_string::SetValue(std::string const& input) { //Special version for lowcase stuff std::string temp(input); - //suggested values always case insensitive. + //suggested values always case insensitive. //If there are none then it can be paths and such which are case sensitive - if(!suggested_values.empty()) lowcase(temp); + if (!suggested_values.empty()) lowcase(temp); Value val(temp,Value::V_STRING); return SetVal(val,false,true); } -bool Prop_string::CheckValue(Value const& in, bool warn){ - if(suggested_values.empty()) return true; +bool Prop_string::CheckValue(Value const& in, bool warn) { + if (suggested_values.empty()) return true; for(iter it = suggested_values.begin();it != suggested_values.end();it++) { if ( (*it) == in) { //Match! return true; } - if((*it).ToString() == "%u") { + if ((*it).ToString() == "%u") { Bit32u value; if(sscanf(in.ToString().c_str(),"%u",&value) == 1) { return true; } } } - if(warn) LOG_MSG("\"%s\" is not a valid value for variable: %s.\nIt might now be reset to the default value: %s",in.ToString().c_str(),propname.c_str(),default_value.ToString().c_str()); + if (warn) LOG_MSG("\"%s\" is not a valid value for variable: %s.\nIt might now be reset to the default value: %s",in.ToString().c_str(),propname.c_str(),default_value.ToString().c_str()); return false; } -bool Prop_path::SetValue(std::string const& input){ +bool Prop_path::SetValue(std::string const& input) { //Special version to merge realpath with it Value val(input,Value::V_STRING); bool retval = SetVal(val,false,true); - if(input.empty()) { + if (input.empty()) { realpath = ""; return false; } std::string workcopy(input); Cross::ResolveHomedir(workcopy); //Parse ~ and friends //Prepend config directory in it exists. Check for absolute paths later - if( current_config_dir.empty()) realpath = workcopy; + if ( current_config_dir.empty()) realpath = workcopy; else realpath = current_config_dir + CROSS_FILESPLIT + workcopy; //Absolute paths if (Cross::IsPathAbsolute(workcopy)) realpath = workcopy; return retval; } - -bool Prop_bool::SetValue(std::string const& input){ + +bool Prop_bool::SetValue(std::string const& input) { return value.SetValue(input,Value::V_BOOL); } -bool Prop_hex::SetValue(std::string const& input){ +bool Prop_hex::SetValue(std::string const& input) { Value val; val.SetValue(input,Value::V_HEX); return SetVal(val,false,true); } -void Prop_multival::make_default_value(){ +void Prop_multival::make_default_value() { Bitu i = 1; Property *p = section->Get_prop(0); - if(!p) return; + if (!p) return; std::string result = p->Get_Default_Value().ToString(); while( (p = section->Get_prop(i++)) ) { std::string props = p->Get_Default_Value().ToString(); - if(props == "") continue; + if (props == "") continue; result += separator; result += props; } Value val(result,Value::V_STRING); SetVal(val,false,true); } - - //TODO checkvalue stuff bool Prop_multival_remain::SetValue(std::string const& input) { Value val(input,Value::V_STRING); @@ -389,30 +387,30 @@ bool Prop_multival_remain::SetValue(std::string const& input) { int i = 0,number_of_properties = 0; Property *p = section->Get_prop(0); //No properties in this section. do nothing - if(!p) return false; - + if (!p) return false; + while( (section->Get_prop(number_of_properties)) ) number_of_properties++; - + string::size_type loc = string::npos; while( (p = section->Get_prop(i++)) ) { //trim leading separators loc = local.find_first_not_of(separator); - if(loc != string::npos) local.erase(0,loc); + if (loc != string::npos) local.erase(0,loc); loc = local.find_first_of(separator); string in = "";//default value - /* when i == number_of_properties add the total line. (makes more then + /* when i == number_of_properties add the total line. (makes more then * one string argument possible for parameters of cpu) */ - if(loc != string::npos && i < number_of_properties) { //separator found + if (loc != string::npos && i < number_of_properties) { //separator found in = local.substr(0,loc); local.erase(0,loc+1); - } else if(local.size()) { //last argument or last property + } else if (local.size()) { //last argument or last property in = local; local = ""; } //Test Value. If it fails set default Value valtest (in,p->Get_type()); - if(!p->CheckValue(valtest,true)) { + if (!p->CheckValue(valtest,true)) { make_default_value(); return false; } @@ -430,24 +428,24 @@ bool Prop_multival::SetValue(std::string const& input) { int i = 0; Property *p = section->Get_prop(0); //No properties in this section. do nothing - if(!p) return false; + if (!p) return false; string::size_type loc = string::npos; while( (p = section->Get_prop(i++)) ) { //trim leading separators loc = local.find_first_not_of(separator); - if(loc != string::npos) local.erase(0,loc); + if (loc != string::npos) local.erase(0,loc); loc = local.find_first_of(separator); string in = "";//default value - if(loc != string::npos) { //separator found + if (loc != string::npos) { //separator found in = local.substr(0,loc); local.erase(0,loc+1); - } else if(local.size()) { //last argument + } else if (local.size()) { //last argument in = local; local = ""; - } + } //Test Value. If it fails set default Value valtest (in,p->Get_type()); - if(!p->CheckValue(valtest,true)) { + if (!p->CheckValue(valtest,true)) { make_default_value(); return false; } @@ -460,11 +458,10 @@ bool Prop_multival::SetValue(std::string const& input) { const std::vector& Property::GetValues() const { return suggested_values; } -const std::vector& Prop_multival::GetValues() const -{ +const std::vector& Prop_multival::GetValues() const { Property *p = section->Get_prop(0); //No properties in this section. do nothing - if(!p) return suggested_values; + if (!p) return suggested_values; int i =0; while( (p = section->Get_prop(i++)) ) { std::vector v = p->GetValues(); @@ -512,16 +509,19 @@ Prop_bool* Section_prop::Add_bool(string const& _propname, Property::Changeable: properties.push_back(test); return test; } + Prop_hex* Section_prop::Add_hex(string const& _propname, Property::Changeable::Value when, Hex _value) { Prop_hex* test=new Prop_hex(_propname,when,_value); properties.push_back(test); return test; } + Prop_multival* Section_prop::Add_multi(std::string const& _propname, Property::Changeable::Value when,std::string const& sep) { Prop_multival* test = new Prop_multival(_propname,when,sep); properties.push_back(test); return test; } + Prop_multival_remain* Section_prop::Add_multiremain(std::string const& _propname, Property::Changeable::Value when,std::string const& sep) { Prop_multival_remain* test = new Prop_multival_remain(_propname,when,sep); properties.push_back(test); @@ -530,7 +530,7 @@ Prop_multival_remain* Section_prop::Add_multiremain(std::string const& _propname int Section_prop::Get_int(string const&_propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ - if((*tel)->propname==_propname){ + if ((*tel)->propname==_propname){ return ((*tel)->GetValue()); } } @@ -539,15 +539,16 @@ int Section_prop::Get_int(string const&_propname) const { bool Section_prop::Get_bool(string const& _propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ - if((*tel)->propname==_propname){ + if ((*tel)->propname==_propname){ return ((*tel)->GetValue()); } } return false; } + double Section_prop::Get_double(string const& _propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ - if((*tel)->propname==_propname){ + if ((*tel)->propname==_propname){ return ((*tel)->GetValue()); } } @@ -556,9 +557,9 @@ double Section_prop::Get_double(string const& _propname) const { Prop_path* Section_prop::Get_path(string const& _propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ - if((*tel)->propname==_propname){ + if ((*tel)->propname==_propname){ Prop_path* val = dynamic_cast((*tel)); - if(val) return val; else return NULL; + if (val) return val; else return NULL; } } return NULL; @@ -576,16 +577,16 @@ Prop_multival* Section_prop::Get_multival(string const& _propname) const { Prop_multival_remain* Section_prop::Get_multivalremain(string const& _propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ - if((*tel)->propname==_propname){ + if ((*tel)->propname==_propname){ Prop_multival_remain* val = dynamic_cast((*tel)); - if(val) return val; else return NULL; + if (val) return val; else return NULL; } } return NULL; } Property* Section_prop::Get_prop(int index){ for(it tel=properties.begin();tel!=properties.end();tel++){ - if(!index--) return (*tel); + if (!index--) return (*tel); } return NULL; } @@ -609,15 +610,15 @@ Hex Section_prop::Get_hex(string const& _propname) const { void trim(string& in) { string::size_type loc = in.find_first_not_of(" \r\t\f\n"); - if(loc != string::npos) in.erase(0,loc); + if (loc != string::npos) in.erase(0,loc); loc = in.find_last_not_of(" \r\t\f\n"); - if(loc != string::npos) in.erase(loc+1); + if (loc != string::npos) in.erase(loc+1); } bool Section_prop::HandleInputline(string const& gegevens){ string str1 = gegevens; string::size_type loc = str1.find('='); - if(loc == string::npos) return false; + if (loc == string::npos) return false; string name = str1.substr(0,loc); string val = str1.substr(loc + 1); @@ -625,9 +626,9 @@ bool Section_prop::HandleInputline(string const& gegevens){ trim(val); string::size_type length = val.length(); if (length > 1 && - ((val[0] == '"' && val[length - 1] == '"' ) || + ((val[0] == '\"' && val[length - 1] == '\"' ) || (val[0] == '\'' && val[length - 1] == '\'')) - ) val = val.substr(1,length - 2); + ) val = val.substr(1,length - 2); /* trim the results incase there were spaces somewhere */ trim(name);trim(val); for(it tel = properties.begin();tel != properties.end();tel++){ @@ -645,16 +646,16 @@ void Section_prop::PrintData(FILE* outfile) const { } } -string Section_prop::GetPropValue(string const& _property) const{ +string Section_prop::GetPropValue(string const& _property) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ - if(!strcasecmp((*tel)->propname.c_str(),_property.c_str())){ + if (!strcasecmp((*tel)->propname.c_str(),_property.c_str())){ return (*tel)->GetValue().ToString(); } } return NO_SUCH_PROPERTY; } -bool Section_line::HandleInputline(string const& line){ +bool Section_line::HandleInputline(string const& line) { data+=line; data+="\n"; return true; @@ -693,13 +694,13 @@ bool Config::PrintConfig(char const * const configfilename) const { i=0; char prefix[80]; snprintf(prefix,80, "\n# %*s ", (int)maxwidth, ""); - while ((p = sec->Get_prop(i++))) { + while ((p = sec->Get_prop(i++))) { std::string help = p->Get_help(); std::string::size_type pos = std::string::npos; while ((pos = help.find("\n", pos+1)) != std::string::npos) { help.replace(pos, 1, prefix); } - + fprintf(outfile, "# %*s: %s", (int)maxwidth, p->propname.c_str(), help.c_str()); std::vector values = p->GetValues(); @@ -732,7 +733,7 @@ bool Config::PrintConfig(char const * const configfilename) const { helpstr++; } } - + fprintf(outfile,"\n"); (*tel)->PrintData(outfile); fprintf(outfile,"\n"); /* Always an empty line between sections */ @@ -740,9 +741,9 @@ bool Config::PrintConfig(char const * const configfilename) const { fclose(outfile); return true; } - -Section_prop* Config::AddSection_prop(char const * const _name,void (*_initfunction)(Section*),bool canchange){ + +Section_prop* Config::AddSection_prop(char const * const _name,void (*_initfunction)(Section*),bool canchange) { Section_prop* blah = new Section_prop(_name); blah->AddInitFunction(_initfunction,canchange); sectionlist.push_back(blah); @@ -758,7 +759,7 @@ Section_prop::~Section_prop() { } -Section_line* Config::AddSection_line(char const * const _name,void (*_initfunction)(Section*)){ +Section_line* Config::AddSection_line(char const * const _name,void (*_initfunction)(Section*)) { Section_line* blah = new Section_line(_name); blah->AddInitFunction(_initfunction); sectionlist.push_back(blah); @@ -767,7 +768,7 @@ Section_line* Config::AddSection_line(char const * const _name,void (*_initfunct void Config::Init() { - for (const_it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ + for (const_it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++) { (*tel)->ExecuteInit(); } } @@ -806,36 +807,35 @@ Config::~Config() { } } -Section* Config::GetSection(int index){ +Section* Config::GetSection(int index) { for (it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ if (!index--) return (*tel); } return NULL; } -Section* Config::GetSection(string const& _sectionname) const{ +Section* Config::GetSection(string const& _sectionname) const { for (const_it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ if (!strcasecmp((*tel)->GetName(),_sectionname.c_str())) return (*tel); } return NULL; } -Section* Config::GetSectionFromProperty(char const * const prop) const{ +Section* Config::GetSectionFromProperty(char const * const prop) const { for (const_it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ if ((*tel)->GetPropValue(prop) != NO_SUCH_PROPERTY) return (*tel); } return NULL; } - -bool Config::ParseConfigFile(char const * const configfilename){ +bool Config::ParseConfigFile(char const * const configfilename) { //static bool first_configfile = true; ifstream in(configfilename); if (!in) return false; const char * settings_type; settings_type = (configfiles.size() == 0)? "primary":"additional"; configfiles.push_back(configfilename); - + LOG_MSG("CONFIG:Loading %s settings from config file %s", settings_type,configfilename); //Get directory from configfilename, used with relative paths. @@ -848,7 +848,7 @@ bool Config::ParseConfigFile(char const * const configfilename){ Section* currentsection = NULL; Section* testsec = NULL; while (getline(in,gegevens)) { - + /* strip leading/trailing whitespace */ trim(gegevens); if(!gegevens.size()) continue; @@ -909,7 +909,7 @@ void Config::ParseEnv(char ** envp) { } } -void Config::SetStartUp(void (*_function)(void)) { +void Config::SetStartUp(void (*_function)(void)) { _start_function=_function; } @@ -996,7 +996,7 @@ bool CommandLine::FindStringRemain(char const * const name,std::string & value) return true; } -/* Only used for parsing command.com /C +/* Only used for parsing command.com /C * Allowing /C dir and /Cdir * Restoring quotes back into the commands so command /C mount d "/tmp/a b" works as intended */ @@ -1030,8 +1030,8 @@ bool CommandLine::FindStringRemainBegin(char const * const name,std::string & va } bool CommandLine::GetStringRemain(std::string & value) { - if(!cmds.size()) return false; - + if (!cmds.size()) return false; + cmd_it it=cmds.begin();value=(*it++); for(;it != cmds.end();it++) { value+=" "; @@ -1039,7 +1039,7 @@ bool CommandLine::GetStringRemain(std::string & value) { } return true; } - + unsigned int CommandLine::GetCount(void) { return (unsigned int)cmds.size(); @@ -1083,7 +1083,7 @@ int CommandLine::GetParameterFromList(const char* const params[], std::vector Date: Sat, 17 Feb 2018 15:25:55 +0000 Subject: [PATCH 3989/4131] use correct datatype with scanf Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4080 --- src/hardware/serialport/serialport.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index 6ce00c19..2fb1ea89 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -1130,7 +1130,7 @@ CSerial::CSerial(Bitu id, CommandLine* cmd) { txOverrunErrors=0; overrunIF0=0; breakErrors=0; - + for (Bitu i = 0; i <= 7; i++) { WriteHandler[i].Install (i + base, SERIAL_Write, IO_MB); ReadHandler[i].Install (i + base, SERIAL_Read, IO_MB); @@ -1140,8 +1140,10 @@ CSerial::CSerial(Bitu id, CommandLine* cmd) { bool CSerial::getBituSubstring(const char* name,Bitu* data, CommandLine* cmd) { std::string tmpstring; if(!(cmd->FindStringBegin(name,tmpstring,false))) return false; - const char* tmpchar=tmpstring.c_str(); - if(sscanf(tmpchar,"%u",data)!=1) return false; + const char* tmpchar = tmpstring.c_str(); + unsigned int d = 0; + if(sscanf(tmpchar,"%u",&d) != 1) return false; + *data = static_cast(d); return true; } From 7b3864290b686f9a615be145c0dee1ba80716e89 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 17 Feb 2018 20:32:49 +0000 Subject: [PATCH 3990/4131] This looks more logical to me Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4081 --- src/hardware/vga_tseng.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hardware/vga_tseng.cpp b/src/hardware/vga_tseng.cpp index cf8482fd..9e66c9f5 100644 --- a/src/hardware/vga_tseng.cpp +++ b/src/hardware/vga_tseng.cpp @@ -701,8 +701,10 @@ void FinishSetMode_ET3K(Bitu crtc_base, VGA_ModeExtraData* modeData) { IO_Write(crtc_base,0x25);IO_Write(crtc_base+1,et4k_ver_overflow); // Clear remaining ext CRTC registers - for (Bitu i=0x16; i<=0x21; i++) - IO_Write(crtc_base,i);IO_Write(crtc_base+1,0); + for (Bitu i=0x16; i<=0x21; i++) { + IO_Write(crtc_base,i); + IO_Write(crtc_base+1,0); + } IO_Write(crtc_base,0x23);IO_Write(crtc_base+1,0); IO_Write(crtc_base,0x24);IO_Write(crtc_base+1,0); // Clear ext SEQ From 5ab2d4cb197c46d0c2a50b7ac00bbeba4397d9b3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 21 Feb 2018 18:50:52 +0000 Subject: [PATCH 3991/4131] upgrade visual studio file to add MAME sound stuff Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4082 --- visualc_net/dosbox.vcproj | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index ae885531..dcfe14fd 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -565,6 +565,40 @@ + + + + + + + + + + + + + + + + + + + + + + Date: Wed, 21 Feb 2018 18:58:47 +0000 Subject: [PATCH 3992/4131] Make it compile on VS 2008,as that one does not support the C99 standard library. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4083 --- src/hardware/mame/emu.h | 4 ++++ src/hardware/mame/fmopl.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/hardware/mame/emu.h b/src/hardware/mame/emu.h index ace02d29..834d375d 100644 --- a/src/hardware/mame/emu.h +++ b/src/hardware/mame/emu.h @@ -3,7 +3,11 @@ #include "dosbox.h" +#if defined(_MSC_VER) && (_MSC_VER <= 1500) +#include +#else #include +#endif #include #include #include diff --git a/src/hardware/mame/fmopl.h b/src/hardware/mame/fmopl.h index c64a59c9..677df505 100644 --- a/src/hardware/mame/fmopl.h +++ b/src/hardware/mame/fmopl.h @@ -5,7 +5,11 @@ #pragma once +#if defined(_MSC_VER) && (_MSC_VER <= 1500) +#include +#else #include +#endif /* --- select emulation chips --- */ From 1862964f7700b343258ab7ea0591d974759abb6b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 21 Feb 2018 19:18:53 +0000 Subject: [PATCH 3993/4131] Correct line ends in emu.h and setting correct svn properties Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4084 --- src/hardware/mame/emu.h | 254 +++++++++++++++++++------------------- src/hardware/mame/fmopl.h | 2 +- 2 files changed, 128 insertions(+), 128 deletions(-) diff --git a/src/hardware/mame/emu.h b/src/hardware/mame/emu.h index 834d375d..ab0fae59 100644 --- a/src/hardware/mame/emu.h +++ b/src/hardware/mame/emu.h @@ -1,127 +1,127 @@ -#ifndef DOSBOX_EMU_H -#define DOSBOX_EMU_H - - -#include "dosbox.h" -#if defined(_MSC_VER) && (_MSC_VER <= 1500) -#include -#else -#include -#endif -#include -#include -#include -#include - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -typedef Bit16s stream_sample_t; - -typedef Bit8u u8; -typedef Bit32u u32; - -class device_t; -struct machine_config; - -#define NAME( _ASDF_ ) 0 -#define BIT( _INPUT_, _BIT_ ) ( ( _INPUT_) >> (_BIT_)) & 1 - -#define ATTR_UNUSED -#define DECLARE_READ8_MEMBER(name) u8 name( int, int) -#define DECLARE_WRITE8_MEMBER(name) void name( int, int, u8 data) -#define READ8_MEMBER(name) u8 name( int, int) -#define WRITE8_MEMBER(name) void name( int offset, int space, u8 data) - -#define DECLARE_DEVICE_TYPE(Type, Class) \ - extern const device_type Type; \ - class Class; - -#define DEFINE_DEVICE_TYPE(Type, Class, ShortName, FullName) \ - const device_type Type = 0; - - -class device_sound_interface { -public: - struct sound_stream { - void update() { - } - }; - sound_stream temp; - - sound_stream* stream_alloc(int whatever, int channels, int size) { - return &temp; - }; - - - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) = 0; - - device_sound_interface(const machine_config &mconfig, device_t& _device) { - } - -}; - -struct attotime { - int whatever; - - static attotime from_hz(int hz) { - return attotime(); - } -}; - -struct machine_config { -}; - -typedef int device_type; - -class device_t { - u32 clockRate; -public: - struct machine_t { - int describe_context() const { - return 0; - } - }; - - machine_t machine() const { - return machine_t(); - } - - //int offset, space; - - u32 clock() const { - return clockRate; - } - - void logerror(const char* msg, ...) { - } - - static int tag() { - return 0; - } - - virtual void device_start() { - } - - void save_item(int wtf, int blah= 0) { - } - - device_t(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 _clock) : clockRate( _clock ) { - } - -}; - - - -static void auto_free(const device_t::machine_t& machine, void * buffer) { - free(buffer); -} - -#define auto_alloc_array_clear(m, t, c) calloc(c, sizeof(t) ) -#define auto_alloc_clear(m, t) static_cast( calloc(1, sizeof(t) ) ) - - - - -#endif \ No newline at end of file +#ifndef DOSBOX_EMU_H +#define DOSBOX_EMU_H + + +#include "dosbox.h" +#if defined(_MSC_VER) && (_MSC_VER <= 1500) +#include +#else +#include +#endif +#include +#include +#include +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +typedef Bit16s stream_sample_t; + +typedef Bit8u u8; +typedef Bit32u u32; + +class device_t; +struct machine_config; + +#define NAME( _ASDF_ ) 0 +#define BIT( _INPUT_, _BIT_ ) ( ( _INPUT_) >> (_BIT_)) & 1 + +#define ATTR_UNUSED +#define DECLARE_READ8_MEMBER(name) u8 name( int, int) +#define DECLARE_WRITE8_MEMBER(name) void name( int, int, u8 data) +#define READ8_MEMBER(name) u8 name( int, int) +#define WRITE8_MEMBER(name) void name( int offset, int space, u8 data) + +#define DECLARE_DEVICE_TYPE(Type, Class) \ + extern const device_type Type; \ + class Class; + +#define DEFINE_DEVICE_TYPE(Type, Class, ShortName, FullName) \ + const device_type Type = 0; + + +class device_sound_interface { +public: + struct sound_stream { + void update() { + } + }; + sound_stream temp; + + sound_stream* stream_alloc(int whatever, int channels, int size) { + return &temp; + }; + + + virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) = 0; + + device_sound_interface(const machine_config &mconfig, device_t& _device) { + } + +}; + +struct attotime { + int whatever; + + static attotime from_hz(int hz) { + return attotime(); + } +}; + +struct machine_config { +}; + +typedef int device_type; + +class device_t { + u32 clockRate; +public: + struct machine_t { + int describe_context() const { + return 0; + } + }; + + machine_t machine() const { + return machine_t(); + } + + //int offset, space; + + u32 clock() const { + return clockRate; + } + + void logerror(const char* msg, ...) { + } + + static int tag() { + return 0; + } + + virtual void device_start() { + } + + void save_item(int wtf, int blah= 0) { + } + + device_t(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 _clock) : clockRate( _clock ) { + } + +}; + + + +static void auto_free(const device_t::machine_t& machine, void * buffer) { + free(buffer); +} + +#define auto_alloc_array_clear(m, t, c) calloc(c, sizeof(t) ) +#define auto_alloc_clear(m, t) static_cast( calloc(1, sizeof(t) ) ) + + + + +#endif diff --git a/src/hardware/mame/fmopl.h b/src/hardware/mame/fmopl.h index 677df505..3ea60ada 100644 --- a/src/hardware/mame/fmopl.h +++ b/src/hardware/mame/fmopl.h @@ -5,7 +5,7 @@ #pragma once -#if defined(_MSC_VER) && (_MSC_VER <= 1500) +#if defined(_MSC_VER) && (_MSC_VER <= 1500) #include #else #include From 99c5b63b3b643b4099f35d469e250ca04dc283a4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 21 Feb 2018 19:25:42 +0000 Subject: [PATCH 3994/4131] Add ignores for mame folder Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4085 From 2f982daf9292bc2ce7e84a244db211be38a280dc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Mar 2018 15:05:31 +0000 Subject: [PATCH 3995/4131] Add some basic arm detection to configure for the raspberry and chromebook users Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4086 --- configure.ac | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 89320741..3ecdddbc 100644 --- a/configure.ac +++ b/configure.ac @@ -277,6 +277,18 @@ case "$host_cpu" in c_targetcpu="m68k" c_unalignedmemory=yes ;; + armv7l) + AC_DEFINE(C_TARGETCPU,ARMV7LE) + AC_MSG_RESULT(ARMv7 Little Endian) + c_targetcpu="arm" + c_unalignedmemory=yes + ;; + armv6l) + AC_DEFINE(C_TARGETCPU,ARMV4LE) + AC_MSG_RESULT(ARMv6 Little Endian) + c_targetcpu="arm" + dnl c_unalignedmemory=yes + ;; *) AC_DEFINE(C_TARGETCPU,UNKNOWN) AC_MSG_RESULT(unknown) @@ -318,8 +330,13 @@ dnl x86 only enable it if dynamic-x86 is disabled. if test x$c_targetcpu = xx86_64 ; then AC_DEFINE(C_DYNREC,1) AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) + else + if test x$c_targetcpu = xarm ; then + AC_DEFINE(C_DYNREC,1) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi fi fi fi From b681d85d5f0531582f4ec22e67840ead78e845e6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 23 Mar 2018 08:54:24 +0000 Subject: [PATCH 3996/4131] fix compilation on machines that have X11 libraries installed, but use an sdl without X11. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4087 --- src/gui/sdl_mapper.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 136e979a..360c36bf 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -2459,6 +2459,8 @@ void MAPPER_StartUp(Section * sec) { sdlkey_map[0x41]=SDLK_KP6; #elif !defined (WIN32) /* => Linux & BSDs */ bool evdev_input = false; +#ifdef SDL_VIDEO_DRIVER_X11 +//SDL needs to be compiled to use it, else the next makes no sense. #ifdef C_X11_XKB SDL_SysWMinfo info; SDL_VERSION(&info.version); @@ -2477,6 +2479,7 @@ void MAPPER_StartUp(Section * sec) { XkbFreeClientMap(desc,0,True); } } +#endif #endif if (evdev_input) { sdlkey_map[0x67]=SDLK_UP; From 908b9ec03d9ceafd4b58fcf616ddda107d1099cb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 26 Mar 2018 17:50:37 +0000 Subject: [PATCH 3997/4131] Convert variable stuff to vector (breakpoints one day as well) Keep track of whether the variable did actually change and skip expensive draw calls if nothing changed. Skip generation of temporary copy by switching to ++i instead of i++ for non basic data. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4088 --- src/debug/debug.cpp | 106 ++++++++++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 42 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index f93b2985..99aa12ab 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -244,26 +245,31 @@ bool GetDescriptorInfo(char* selname, char* out1, char* out2) class CDebugVar { public: - CDebugVar(char* _name, PhysPt _adr) { adr=_adr; safe_strncpy(name,_name,16); }; + CDebugVar(char* _name, PhysPt _adr) { adr=_adr; safe_strncpy(name,_name,16); hasvalue = false; value = 0; }; - char* GetName(void) { return name; }; - PhysPt GetAdr (void) { return adr; }; + char* GetName (void) { return name; }; + PhysPt GetAdr (void) { return adr; }; + void SetValue(bool has, Bit16u val) { hasvalue = has; value=val; }; + Bit16u GetValue(void) { return value; }; + bool HasValue(void) { return hasvalue; }; private: PhysPt adr; - char name[16]; + char name[16]; + bool hasvalue; + Bit16u value; public: - static void InsertVariable (char* name, PhysPt adr); - static CDebugVar* FindVar (PhysPt adr); - static void DeleteAll (); - static bool SaveVars (char* name); - static bool LoadVars (char* name); + static void InsertVariable(char* name, PhysPt adr); + static CDebugVar* FindVar (PhysPt adr); + static void DeleteAll (); + static bool SaveVars (char* name); + static bool LoadVars (char* name); - static std::list varList; + static std::vector varList; }; -std::list CDebugVar::varList; +std::vector CDebugVar::varList; /********************/ @@ -419,7 +425,7 @@ void CBreakpoint::ActivateBreakpoints() { // activate all breakpoints std::list::iterator i; - for (i = BPoints.begin(); i != BPoints.end(); i++) + for (i = BPoints.begin(); i != BPoints.end(); ++i) (*i)->Activate(true); } @@ -427,7 +433,7 @@ void CBreakpoint::DeactivateBreakpoints() { // deactivate all breakpoints std::list::iterator i; - for (i = BPoints.begin(); i != BPoints.end(); i++) + for (i = BPoints.begin(); i != BPoints.end(); ++i) (*i)->Activate(false); } @@ -435,7 +441,7 @@ void CBreakpoint::ActivateBreakpointsExceptAt(PhysPt adr) { // activate all breakpoints, except those at adr std::list::iterator i; - for (i = BPoints.begin(); i != BPoints.end(); i++) { + for (i = BPoints.begin(); i != BPoints.end(); ++i) { CBreakpoint* bp = (*i); // Do not activate breakpoints at adr if (bp->GetType() == BKPNT_PHYSICAL && bp->GetLocation() == adr) @@ -453,7 +459,7 @@ bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off) // Search matching breakpoint std::list::iterator i; CBreakpoint* bp; - for(i=BPoints.begin(); i != BPoints.end(); i++) { + for(i=BPoints.begin(); i != BPoints.end(); ++i) { bp = (*i); if ((bp->GetType()==BKPNT_PHYSICAL) && bp->IsActive() && (bp->GetSegment()==seg) && (bp->GetOffset()==off)) { // Found, @@ -513,7 +519,7 @@ bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue, Bi // Search matching breakpoint std::list::iterator i; CBreakpoint* bp; - for(i=BPoints.begin(); i != BPoints.end(); i++) { + for(i=BPoints.begin(); i != BPoints.end(); ++i) { bp = (*i); if ((bp->GetType()==BKPNT_INTERRUPT) && bp->IsActive() && (bp->GetIntNr()==intNr)) { if (((bp->GetValue()==BPINT_ALL) || (bp->GetValue()==ahValue)) && ((bp->GetOther()==BPINT_ALL) || (bp->GetOther()==alValue))) { @@ -536,7 +542,7 @@ void CBreakpoint::DeleteAll() { std::list::iterator i; CBreakpoint* bp; - for(i=BPoints.begin(); i != BPoints.end(); i++) { + for(i=BPoints.begin(); i != BPoints.end(); ++i) { bp = (*i); bp->Activate(false); delete bp; @@ -551,7 +557,7 @@ bool CBreakpoint::DeleteByIndex(Bit16u index) int nr = 0; std::list::iterator i; CBreakpoint* bp; - for(i=BPoints.begin(); i != BPoints.end(); i++) { + for(i=BPoints.begin(); i != BPoints.end(); ++i) { if (nr==index) { bp = (*i); (BPoints.erase)(i); @@ -566,13 +572,14 @@ bool CBreakpoint::DeleteByIndex(Bit16u index) CBreakpoint* CBreakpoint::FindPhysBreakpoint(Bit16u seg, Bit32u off, bool once) { + if (BPoints.empty()) return 0; #if !C_HEAVY_DEBUG PhysPt adr = GetAddress(seg, off); #endif // Search for matching breakpoint std::list::iterator i; CBreakpoint* bp; - for(i=BPoints.begin(); i != BPoints.end(); i++) { + for(i=BPoints.begin(); i != BPoints.end(); ++i) { bp = (*i); #if C_HEAVY_DEBUG // Heavy debugging breakpoints are triggered by matching seg:off @@ -592,7 +599,7 @@ CBreakpoint* CBreakpoint::FindPhysBreakpoint(Bit16u seg, Bit32u off, bool once) CBreakpoint* CBreakpoint::FindOtherActiveBreakpoint(PhysPt adr, CBreakpoint* skip) { std::list::iterator i; - for (i = BPoints.begin(); i != BPoints.end(); i++) { + for (i = BPoints.begin(); i != BPoints.end(); ++i) { CBreakpoint* bp = (*i); if (bp != skip && bp->GetType() == BKPNT_PHYSICAL && bp->GetLocation() == adr && bp->IsActive()) return bp; @@ -624,7 +631,7 @@ void CBreakpoint::ShowList(void) // iterate list int nr = 0; std::list::iterator i; - for(i=BPoints.begin(); i != BPoints.end(); i++) { + for(i=BPoints.begin(); i != BPoints.end(); ++i) { CBreakpoint* bp = (*i); if (bp->GetType()==BKPNT_PHYSICAL) { DEBUG_ShowMsg("%02X. BP %04X:%04X\n",nr,bp->GetSegment(),bp->GetOffset()); @@ -2228,7 +2235,7 @@ void CDebugVar::InsertVariable(char* name, PhysPt adr) void CDebugVar::DeleteAll(void) { - std::list::iterator i; + std::vector::iterator i; CDebugVar* bp; for(i=varList.begin(); i != varList.end(); i++) { bp = static_cast(*i); @@ -2239,17 +2246,19 @@ void CDebugVar::DeleteAll(void) CDebugVar* CDebugVar::FindVar(PhysPt pt) { - std::list::iterator i; + if (varList.empty()) return 0; + + std::vector::size_type s = varList.size(); CDebugVar* bp; - for(i=varList.begin(); i != varList.end(); i++) { - bp = static_cast(*i); - if (bp->GetAdr()==pt) return bp; + for(std::vector::size_type i = 0; i != s; i++) { + bp = static_cast(varList[i]); + if (bp->GetAdr() == pt) return bp; }; return 0; }; bool CDebugVar::SaveVars(char* name) { - if (varList.size()>65535) return false; + if (varList.size() > 65535) return false; FILE* f = fopen(name,"wb+"); if (!f) return false; @@ -2258,7 +2267,7 @@ bool CDebugVar::SaveVars(char* name) { Bit16u num = (Bit16u)varList.size(); fwrite(&num,1,sizeof(num),f); - std::list::iterator i; + std::vector::iterator i; CDebugVar* bp; for(i=varList.begin(); i != varList.end(); i++) { bp = static_cast(*i); @@ -2368,33 +2377,46 @@ static void OutputVecTable(char* filename) { static void DrawVariables(void) { if (CDebugVar::varList.empty()) return; - std::list::iterator i; CDebugVar *dv; char buffer[DEBUG_VAR_BUF_LEN]; + std::vector::size_type s = CDebugVar::varList.size(); + bool windowchanges = false; - int idx = 0; - for(i=CDebugVar::varList.begin(); i != CDebugVar::varList.end(); i++, idx++) { + for(std::vector::size_type i = 0; i != s; i++) { - if (idx == 4*3) { + if (i == 4*3) { /* too many variables */ break; } - dv = static_cast(*i); - + dv = static_cast(CDebugVar::varList[i]); Bit16u value; - if (mem_readw_checked(dv->GetAdr(),&value)) + bool varchanges = false; + bool has_no_value = mem_readw_checked(dv->GetAdr(),&value); + if (has_no_value) { snprintf(buffer,DEBUG_VAR_BUF_LEN, "%s", "??????"); - else - snprintf(buffer,DEBUG_VAR_BUF_LEN, "0x%04x", value); + dv->SetValue(false,0); + varchanges = true; + } else { + if ( dv->HasValue() && dv->GetValue() == value) { + ; //It already had a value and it didn't change (most likely case) + } else { + dv->SetValue(true,value); + snprintf(buffer,DEBUG_VAR_BUF_LEN, "0x%04x", value); + varchanges = true; + } + } - int y = idx / 3; - int x = (idx % 3) * 26; - mvwprintw(dbg.win_var, y, x, dv->GetName()); - mvwprintw(dbg.win_var, y, (x + DEBUG_VAR_BUF_LEN + 1) , buffer); + if (varchanges) { + int y = i / 3; + int x = (i % 3) * 26; + mvwprintw(dbg.win_var, y, x, dv->GetName()); + mvwprintw(dbg.win_var, y, (x + DEBUG_VAR_BUF_LEN + 1) , buffer); + windowchanges = true; //Something has changed in this window + } } - wrefresh(dbg.win_var); + if (windowchanges) wrefresh(dbg.win_var); }; #undef DEBUG_VAR_BUF_LEN // HEAVY DEBUGGING STUFF From 81202c7dd3bbc2e96eac124d2d21aa1ccff19de7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 4 Apr 2018 09:47:29 +0000 Subject: [PATCH 3998/4131] Limit amount of polls per second a bit on MAC OS X, as it was quite high otherwise. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4089 --- src/gui/sdlmain.cpp | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index db0a828f..b102d040 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1491,14 +1491,32 @@ bool GFX_IsFullscreen(void) { return sdl.desktop.fullscreen; } +#if defined(MACOSX) +#define DB_POLLSKIP 3 +#else +//Not used yet, see comment below +#define DB_POLLSKIP 1 +#endif + void GFX_Events() { + //Don't poll too often. This can be heavy on the OS, especially Macs. + //In idle mode 3000-4000 polls are done per second without this check. + //Macs, with this code, max 250 polls per second. (non-macs unused default max 500) + //Currently not implemented for all platforms, given the ALT-TAB stuff for WIN32. +#if defined (MACOSX) + static int last_check = 0; + int current_check = GetTicks(); + if (current_check - last_check <= DB_POLLSKIP) return; + last_check = current_check; +#endif + SDL_Event event; #if defined (REDUCE_JOYSTICK_POLLING) - static int poll_delay=0; - int time=GetTicks(); - if (time-poll_delay>20) { - poll_delay=time; - if (sdl.num_joysticks>0) SDL_JoystickUpdate(); + static int poll_delay = 0; + int time = GetTicks(); + if (time - poll_delay > 20) { + poll_delay = time; + if (sdl.num_joysticks > 0) SDL_JoystickUpdate(); MAPPER_UpdateJoysticks(); } #endif From 48611d614135dd5041d3e0a1220779b3e76068e3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 4 Apr 2018 10:05:50 +0000 Subject: [PATCH 3999/4131] Do we even use those timers ? Ticks are initted regardless. Please report problems! (helps with cpu usage on Macs) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4090 --- src/gui/sdlmain.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index b102d040..8a4fe325 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1998,7 +1998,9 @@ int main(int argc, char* argv[]) { */ putenv(const_cast("SDL_DISABLE_LOCK_KEYS=1")); #endif - if ( SDL_Init( SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM + // Don't init timers, GetTicks seems to work fine and they can use a fair amount of power (Macs again) + // Please report problems with audio and other things. + if ( SDL_Init( SDL_INIT_AUDIO|SDL_INIT_VIDEO | /*SDL_INIT_TIMER |*/ SDL_INIT_CDROM |SDL_INIT_NOPARACHUTE ) < 0 ) E_Exit("Can't init SDL %s",SDL_GetError()); sdl.inited = true; From a4373c0995d960cf8664c85ae841c03fee42c6a8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 4 Apr 2018 11:14:03 +0000 Subject: [PATCH 4000/4131] Add basic support for INT 13 call 15. Used by korean powerdolls to detect harddrive. SF bug #477 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4091 --- src/ints/bios_disk.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 67694677..87e1abfc 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -497,6 +497,46 @@ static Bitu INT13_DiskHandler(void) { reg_ah = 0x00; CALLBACK_SCF(false); break; + case 0x15: /* Get disk type */ + /* Korean Powerdolls uses this to detect harddrives */ + LOG(LOG_BIOS,LOG_WARN)("INT13: Get disktype used!"); + if (any_images) { + if(driveInactive(drivenum)) { + last_status = 0x07; + reg_ah = last_status; + CALLBACK_SCF(true); + return CBRET_NONE; + } + Bit32u tmpheads, tmpcyl, tmpsect, tmpsize; + imageDiskList[drivenum]->Get_Geometry(&tmpheads, &tmpcyl, &tmpsect, &tmpsize); + Bit64u largesize = tmpheads*tmpcyl*tmpsect*tmpsize; + largesize/=512; + Bit32u ts = static_cast(largesize); + reg_ah = (drivenum <2)?2:3; + reg_cx = static_cast(ts >>16); + reg_dx = static_cast(ts & 0xffff); + CALLBACK_SCF(false); + } else { + if (drivenum Date: Wed, 4 Apr 2018 16:25:53 +0000 Subject: [PATCH 4001/4131] Add 0xA0 (probably ;) ) and improve unhandled message reporting a bit. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4092 --- src/gui/midi_alsa.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 7a51e34d..6f87dca6 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -94,6 +94,10 @@ public: snd_seq_ev_set_noteon(&ev, chanID, msg[1], msg[2]); send_event(1); break; + case 0xA0: + snd_seq_ev_set_keypress(&ev, chanID, msg[1], msg[2]); + send_event(1); + break; case 0xB0: snd_seq_ev_set_controller(&ev, chanID, msg[1], msg[2]); send_event(1); @@ -113,7 +117,8 @@ public: } break; default: - LOG(LOG_MISC,LOG_WARN)("ALSA:Unknown Command: %08lx", (long)msg); + //Maybe filter out FC as it leads for at least one user to crash, but the entire midi stream has not yet been checked. + LOG(LOG_MISC,LOG_WARN)("ALSA:Unknown Command: %02X %02X %02X", msg[0],msg[1],msg[2]); send_event(1); break; } From fd7f929f9e7e1142d70716d6563503cc08de87ae Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 9 Apr 2018 10:47:34 +0000 Subject: [PATCH 4002/4131] Updated stereo before using it. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4093 --- src/hardware/sblaster.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index a2916fc8..49d0bfe3 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -659,15 +659,17 @@ static void DSP_DoDMATransfer(DMA_MODES mode,Bitu freq,bool autoinit, bool stere //Transfer full cycle again sb.dma.left = sb.dma.total; } + + sb.dma.autoinit = autoinit; + sb.dma.mode = mode; + sb.dma.stereo = stereo; //Double the reading speed for stereo mode if (sb.dma.stereo) sb.dma.mul*=2; sb.dma.rate=(sb.freq*sb.dma.mul) >> SB_SH; sb.dma.min=(sb.dma.rate*3)/1000; sb.chan->SetFreq(freq); - sb.dma.mode = mode; - sb.dma.stereo = stereo; - sb.dma.autoinit = autoinit; + PIC_RemoveEvents(END_DMA_Event); //Set to be masked, the dma call can change this again. sb.mode = MODE_DMA_MASKED; From 84eaccc5173fb98371333cc1234e181c79f87e9a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 16 Apr 2018 12:52:49 +0000 Subject: [PATCH 4003/4131] slight refactoring, so that it is easier to correctly increase TICK_SHIFT above 16. Maybe 24 will be a nice value, judging from the tests. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4094 --- src/hardware/mixer.cpp | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 25dc0c6a..5780b4e5 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -399,6 +399,17 @@ static inline bool Mixer_irq_important(void) { return (ticksLocked || (CaptureState & (CAPTURE_WAVE|CAPTURE_VIDEO))); } +static Bit32u calc_tickadd(Bit32u freq) { +#if TICK_SHIFT >16 + Bit64u freq64 = static_cast(freq); + freq64 = (freq64<(freq64); + return r; +#else + return (freq<needed?mixer.min_needed:needed) - left; - mixer.tick_add = ((mixer.freq+(diff*3)) << TICK_SHIFT)/1000; + mixer.tick_add = calc_tickadd(mixer.freq+(diff*3)); left = 0; //No stretching as we compensate with the tick_add value } else { left = (mixer.min_needed - left); @@ -501,11 +512,11 @@ static void SDLCALL MIXER_CallBack(void * userdata, Uint8 *stream, int len) { Bitu diff = left - mixer.min_needed; if(diff > (mixer.min_needed<<1)) diff = mixer.min_needed<<1; if(diff > (mixer.min_needed>>1)) - mixer.tick_add = ((mixer.freq-(diff/5)) << TICK_SHIFT)/1000; + mixer.tick_add = calc_tickadd(mixer.freq-(diff/5)); else if (diff > (mixer.min_needed>>2)) - mixer.tick_add = ((mixer.freq-(diff>>3)) << TICK_SHIFT)/1000; + mixer.tick_add = calc_tickadd(mixer.freq-(diff>>3)); else - mixer.tick_add = (mixer.freq<< TICK_SHIFT)/1000; + mixer.tick_add = calc_tickadd(mixer.freq); } } else { /* There is way too much data in the buffer */ @@ -516,7 +527,7 @@ static void SDLCALL MIXER_CallBack(void * userdata, Uint8 *stream, int len) { index_add = mixer.done - 2*mixer.min_needed; index_add = (index_add << TICK_SHIFT) / need; reduce = mixer.done - 2* mixer.min_needed; - mixer.tick_add = ((mixer.freq-(mixer.min_needed/5)) << TICK_SHIFT)/1000; + mixer.tick_add = calc_tickadd(mixer.freq-(mixer.min_needed/5)); } /* Reduce done count in all channels */ for (MixerChannel * chan=mixer.channels;chan;chan=chan->next) { @@ -526,7 +537,7 @@ static void SDLCALL MIXER_CallBack(void * userdata, Uint8 *stream, int len) { // Reset mixer.tick_add when irqs are important if( Mixer_irq_important() ) - mixer.tick_add=(mixer.freq<< TICK_SHIFT)/1000; + mixer.tick_add = calc_tickadd(mixer.freq); mixer.done -= reduce; mixer.needed -= reduce; @@ -683,19 +694,19 @@ void MIXER_Init(Section* sec) { mixer.tick_counter=0; if (mixer.nosound) { LOG_MSG("MIXER: No Sound Mode Selected."); - mixer.tick_add=((mixer.freq) << TICK_SHIFT)/1000; + mixer.tick_add=calc_tickadd(mixer.freq); TIMER_AddTickHandler(MIXER_Mix_NoSound); } else if (SDL_OpenAudio(&spec, &obtained) <0 ) { mixer.nosound = true; LOG_MSG("MIXER: Can't open audio: %s , running in nosound mode.",SDL_GetError()); - mixer.tick_add=((mixer.freq) << TICK_SHIFT)/1000; + mixer.tick_add=calc_tickadd(mixer.freq); TIMER_AddTickHandler(MIXER_Mix_NoSound); } else { if((mixer.freq != obtained.freq) || (mixer.blocksize != obtained.samples)) LOG_MSG("MIXER: Got different values from SDL: freq %d, blocksize %d",obtained.freq,obtained.samples); mixer.freq=obtained.freq; mixer.blocksize=obtained.samples; - mixer.tick_add=(mixer.freq << TICK_SHIFT)/1000; + mixer.tick_add=calc_tickadd(mixer.freq); TIMER_AddTickHandler(MIXER_Mix); SDL_PauseAudio(0); } From a315f740744e7c1aebb436464a6039531d25a4e0 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 16 Apr 2018 20:24:30 +0000 Subject: [PATCH 4004/4131] Allow 15/16/32 bpp inputs to the opengl output Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4095 --- src/gui/sdlmain.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 8a4fe325..8062239b 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -414,13 +414,16 @@ check_gotbpp: goto check_gotbpp; #endif case SCREEN_OVERLAY: + //We only accept 32bit output from the scalers here + //Can't handle true color inputs if (flags & GFX_RGBONLY || !(flags&GFX_CAN_32)) goto check_surface; flags|=GFX_SCALING; flags&=~(GFX_CAN_8|GFX_CAN_15|GFX_CAN_16); break; #if C_OPENGL case SCREEN_OPENGL: - if (flags & GFX_RGBONLY || !(flags&GFX_CAN_32)) goto check_surface; + //We only accept 32bit output from the scalers here + if (!(flags&GFX_CAN_32)) goto check_surface; flags|=GFX_SCALING; flags&=~(GFX_CAN_8|GFX_CAN_15|GFX_CAN_16); break; @@ -676,7 +679,7 @@ dosurface: free(sdl.opengl.framebuf); } sdl.opengl.framebuf=0; - if (!(flags&GFX_CAN_32) || (flags & GFX_RGBONLY)) goto dosurface; + if (!(flags&GFX_CAN_32)) goto dosurface; int texsize=2 << int_log2(width > height ? width : height); if (texsize>sdl.opengl.max_texsize) { LOG_MSG("SDL:OPENGL: No support for texturesize of %d, falling back to surface",texsize); From c7ced14d563876a6062be3a2a6b7d7c2ea5f1d6a Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Thu, 3 May 2018 16:08:53 +0000 Subject: [PATCH 4005/4131] Support rarely used FCB feature: open file with search mask. Fixes Buckaroo Banzai. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4096 --- src/dos/dos_files.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index e3a0cd0f..b7cf1ca4 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -971,6 +971,20 @@ bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { char shortname[DOS_FCBNAME];Bit16u handle; fcb.GetName(shortname); + /* Search for file if name has wildcards */ + if (strpbrk(shortname,"*?")) { + LOG(LOG_FCB,LOG_WARN)("Wildcards in filename"); + if (!DOS_FCBFindFirst(seg,offset)) return false; + DOS_DTA find_dta(dos.tables.tempdta); + DOS_FCB find_fcb(RealSeg(dos.tables.tempdta),RealOff(dos.tables.tempdta)); + char name[DOS_NAMELENGTH_ASCII],file_name[9],ext[4]; + Bit32u size;Bit16u date,time;Bit8u attr; + find_dta.GetResult(name,size,date,time,attr); + DTAExtendName(name,file_name,ext); + find_fcb.SetName(fcb.GetDrive()+1,file_name,ext); + find_fcb.GetName(shortname); + } + /* First check if the name is correct */ Bit8u drive; char fullname[DOS_PATHLENGTH]; From 630b9befb54a19a07b5027d8d296d0b805d9240e Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Thu, 3 May 2018 16:49:48 +0000 Subject: [PATCH 4006/4131] ANSI emulation is activated for the session when an escape sequence is encountered other than those used by internal messages. Fixes LucasArts setup programs (Bug #458) provided that ANSI emulation is not activated. Compatible scroll fill for ANSI emulation. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4097 --- include/dos_inc.h | 1 + src/dos/dev_con.h | 31 ++++++++++++++++++++++--------- src/dos/dos.cpp | 1 + src/misc/programs.cpp | 4 ++++ 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 277387c9..9f8590e2 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -627,6 +627,7 @@ struct DOS_Block { bool breakcheck; bool echo; // if set to true dev_con::read will echo input bool direct_output; + bool internal_output; struct { RealPt mediaid; RealPt tempdta; diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 5f762d1c..26c4dd63 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -30,11 +30,12 @@ public: bool Write(Bit8u * data,Bit16u * size); bool Seek(Bit32u * pos,Bit32u type); bool Close(); - void ClearAnsi(void); Bit16u GetInformation(void); bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return false;} bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return false;} private: + void ClearAnsi(void); + void Output(Bit8u chr); Bit8u readcache; Bit8u lastwrite; struct ansi { /* should create a constructor, which would fill them with the appropriate values */ @@ -132,18 +133,15 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { /* expand tab if not direct output */ page = real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); do { - INT10_TeletypeOutputAttr(' ',ansi.enabled?ansi.attr:7,true); + Output(' '); col=CURSOR_POS_COL(page); } while(col%8); lastwrite = data[count++]; continue; } else { /* Some sort of "hack" now that '\n' doesn't set col to 0 (int10_char.cpp old chessgame) */ - if((data[count] == '\n') && (lastwrite != '\r')) { - INT10_TeletypeOutputAttr('\r',ansi.enabled?ansi.attr:7,true); - } - /* use ansi attribute if ansi is enabled, otherwise use DOS default attribute*/ - INT10_TeletypeOutputAttr(data[count],ansi.enabled?ansi.attr:7,true); + if((data[count] == '\n') && (lastwrite != '\r')) Output('\r'); + Output(data[count]); lastwrite = data[count++]; continue; } @@ -168,6 +166,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { continue; } /*ansi.esc and ansi.sci are true */ + if (!dos.internal_output) ansi.enabled=true; page = real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); switch(data[count]){ case '0': @@ -187,11 +186,9 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { break; case 'm': /* SGR */ for(i=0;i<=ansi.numberofarg;i++){ - ansi.enabled=true; switch(ansi.data[i]){ case 0: /* normal */ ansi.attr=0x07;//Real ansi does this as well. (should do current defaults) - ansi.enabled=false; break; case 1: /* bold mode on*/ ansi.attr|=0x08; @@ -429,3 +426,19 @@ void device_CON::ClearAnsi(void){ ansi.sci=false; ansi.numberofarg=0; } + +void device_CON::Output(Bit8u chr) { + if (dos.internal_output || ansi.enabled) { + if (CurMode->type==M_TEXT) { + Bit8u page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); + Bit8u col=CURSOR_POS_COL(page); + Bit8u row=CURSOR_POS_ROW(page); + BIOS_NCOLS;BIOS_NROWS; + if (nrows==row+1 && (chr=='\n' || (ncols==col+1 && chr!='\r' && chr!=8 && chr!=7))) { + INT10_ScrollWindow(0,0,(Bit8u)(nrows-1),(Bit8u)(ncols-1),-1,ansi.attr,page); + INT10_SetCursorPos(row-1,col,page); + } + } + INT10_TeletypeOutputAttr(chr,ansi.attr,true); + } else INT10_TeletypeOutput(chr,7); + } diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 19cf3187..e4826165 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1240,6 +1240,7 @@ public: dos.version.major=5; dos.version.minor=0; dos.direct_output=false; + dos.internal_output=false; } ~DOS(){ for (Bit16u i=0;i Date: Thu, 3 May 2018 17:11:36 +0000 Subject: [PATCH 4007/4131] Flag handling (mostly undocumented behavior) for normal core: overflow flag for divide instructions, zero and sign flags for integer multiply instructions. Fixes A320 Airbus and Perfect General. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4098 --- src/cpu/instructions.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index ed6e46bc..f4abed86 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -679,6 +679,7 @@ if (quo>0xff) EXCEPTION(0); \ reg_ah=rem; \ reg_al=quo8; \ + SETFLAGBIT(OF,false); \ } @@ -693,6 +694,7 @@ if (quo!=(Bit32u)quo16) EXCEPTION(0); \ reg_dx=rem; \ reg_ax=quo16; \ + SETFLAGBIT(OF,false); \ } #define DIVD(op1,load,save) \ @@ -706,6 +708,7 @@ if (quo!=(Bit64u)quo32) EXCEPTION(0); \ reg_edx=rem; \ reg_eax=quo32; \ + SETFLAGBIT(OF,false); \ } @@ -719,6 +722,7 @@ if (quo!=(Bit16s)quo8s) EXCEPTION(0); \ reg_ah=rem; \ reg_al=quo8s; \ + SETFLAGBIT(OF,false); \ } @@ -733,6 +737,7 @@ if (quo!=(Bit32s)quo16s) EXCEPTION(0); \ reg_dx=rem; \ reg_ax=quo16s; \ + SETFLAGBIT(OF,false); \ } #define IDIVD(op1,load,save) \ @@ -746,12 +751,15 @@ if (quo!=(Bit64s)quo32s) EXCEPTION(0); \ reg_edx=rem; \ reg_eax=quo32s; \ + SETFLAGBIT(OF,false); \ } #define IMULB(op1,load,save) \ { \ reg_ax=((Bit8s)reg_al) * ((Bit8s)(load(op1))); \ FillFlagsNoCFOF(); \ + SETFLAGBIT(ZF,reg_al == 0); \ + SETFLAGBIT(SF,reg_al & 0x80); \ if ((reg_ax & 0xff80)==0xff80 || \ (reg_ax & 0xff80)==0x0000) { \ SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ @@ -767,6 +775,8 @@ reg_ax=(Bit16s)(temps); \ reg_dx=(Bit16s)(temps >> 16); \ FillFlagsNoCFOF(); \ + SETFLAGBIT(ZF,reg_ax == 0); \ + SETFLAGBIT(SF,reg_ax & 0x8000); \ if (((temps & 0xffff8000)==0xffff8000 || \ (temps & 0xffff8000)==0x0000)) { \ SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ @@ -782,6 +792,8 @@ reg_eax=(Bit32u)(temps); \ reg_edx=(Bit32u)(temps >> 32); \ FillFlagsNoCFOF(); \ + SETFLAGBIT(ZF,reg_eax == 0); \ + SETFLAGBIT(SF,reg_eax & 0x80000000); \ if ((reg_edx==0xffffffff) && \ (reg_eax & 0x80000000) ) { \ SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ From 129613c419f6dc87a4843265dae188fc75b03d43 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 6 May 2018 18:31:09 +0000 Subject: [PATCH 4008/4131] Correct extension, so that the .h file is part of the source package as well Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4099 --- src/hardware/mame/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/mame/Makefile.am b/src/hardware/mame/Makefile.am index 52f7f000..3d551b1f 100644 --- a/src/hardware/mame/Makefile.am +++ b/src/hardware/mame/Makefile.am @@ -4,6 +4,6 @@ noinst_LIBRARIES = libmame.a libmame_a_SOURCES = emu.h \ fmopl.cpp fmopl.h \ saa1099.cpp saa1099.h \ - sn76496.cpp sn76496.cpp \ + sn76496.cpp sn76496.h \ ymdeltat.cpp ymdeltat.h \ ymf262.cpp ymf262.h From 54c993669aa4f734f6f0604d075bde6bf78007f1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 6 May 2018 19:34:22 +0000 Subject: [PATCH 4009/4131] Strip spaces properly. Fixes bug #480 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4100 --- include/support.h | 1 + src/gui/midi.cpp | 2 +- src/misc/setup.cpp | 7 ------- src/misc/support.cpp | 8 +++++++- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/support.h b/include/support.h index f20822be..91643fb1 100644 --- a/include/support.h +++ b/include/support.h @@ -53,6 +53,7 @@ bool IsHexWord(char * word); Bits ConvDecWord(char * word); Bits ConvHexWord(char * word); +void trim(std::string& str); void upcase(std::string &str); void lowcase(std::string &str); diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index f1d3e2f2..88196c2e 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -177,7 +177,7 @@ public: fullconf.erase(fullconf.find("delaysysex")); LOG_MSG("MIDI: Using delayed SysEx processing"); } - std::remove(fullconf.begin(), fullconf.end(), ' '); + trim(fullconf); const char * conf = fullconf.c_str(); midi.status=0x00; midi.cmd_pos=0; diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index a15c289c..957ef08f 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -608,13 +608,6 @@ Hex Section_prop::Get_hex(string const& _propname) const { return 0; } -void trim(string& in) { - string::size_type loc = in.find_first_not_of(" \r\t\f\n"); - if (loc != string::npos) in.erase(0,loc); - loc = in.find_last_not_of(" \r\t\f\n"); - if (loc != string::npos) in.erase(loc+1); -} - bool Section_prop::HandleInputline(string const& gegevens){ string str1 = gegevens; string::size_type loc = str1.find('='); diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 67bbe11d..9b766a64 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -43,7 +43,13 @@ void lowcase(std::string &str) { int (*tf)(int) = std::tolower; std::transform(str.begin(), str.end(), str.begin(), tf); } - + +void trim(std::string &str) { + std::string::size_type loc = str.find_first_not_of(" \r\t\f\n"); + if (loc != std::string::npos) str.erase(0,loc); + loc = str.find_last_not_of(" \r\t\f\n"); + if (loc != std::string::npos) str.erase(loc+1); +} /* Ripped some source from freedos for this one. From a8633eff6acaff4ff8377a359f19b26e843d0fc2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 9 May 2018 18:41:47 +0000 Subject: [PATCH 4010/4131] Slight corrections to r4091, CX and DX should not be changed for floppies. Changing reported floppy type to one without changeline as we don't support that call. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4101 --- src/ints/bios_disk.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 87e1abfc..363c02ed 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -512,17 +512,19 @@ static Bitu INT13_DiskHandler(void) { Bit64u largesize = tmpheads*tmpcyl*tmpsect*tmpsize; largesize/=512; Bit32u ts = static_cast(largesize); - reg_ah = (drivenum <2)?2:3; - reg_cx = static_cast(ts >>16); - reg_dx = static_cast(ts & 0xffff); + reg_ah = (drivenum <2)?1:3; //With 2 for floppy MSDOS starts calling int 13 ah 16 + if(reg_ah == 3) { + reg_cx = static_cast(ts >>16); + reg_dx = static_cast(ts & 0xffff); + } CALLBACK_SCF(false); } else { if (drivenum Date: Tue, 22 May 2018 15:07:38 +0000 Subject: [PATCH 4011/4131] Improve disk serial number DOS functions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4102 --- src/dos/dos.cpp | 21 +++++++++++++++++---- src/dos/dos_ioctl.cpp | 15 ++++++++------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index e4826165..b7735526 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1103,16 +1103,29 @@ static Bitu DOS_21Handler(void) { break; case 0x69: /* Get/Set disk serial number */ { + Bit16u old_cx=reg_cx; switch(reg_al) { case 0x00: /* Get */ - LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Get Disk serial number"); - CALLBACK_SCF(true); + LOG(LOG_DOSMISC,LOG_WARN)("DOS:Get Disk serial number"); + reg_cl=0x66;// IOCTL function + break; + case 0x01: /* Set */ + LOG(LOG_DOSMISC,LOG_WARN)("DOS:Set Disk serial number"); + reg_cl=0x46;// IOCTL function break; - case 0x01: - LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Set Disk serial number"); default: E_Exit("DOS:Illegal Get Serial Number call %2X",reg_al); } + reg_ch=0x08; // IOCTL category: disk drive + reg_ax=0x440d; // Generic block device request + if (DOS_IOCTL()) { + reg_ax=0; // AX destroyed + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + reg_cx=old_cx; break; } case 0x6c: /* Extended Open/Create */ diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 52e5d37d..992e6b2b 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -152,7 +152,7 @@ bool DOS_IOCTL(void) { return true; case 0x0D: /* Generic block device request */ { - if ((drive < 2) || Drives[drive]->isRemovable()) { + if (Drives[drive]->isRemovable()) { DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); return false; } @@ -169,11 +169,12 @@ bool DOS_IOCTL(void) { mem_writeb(ptr+8,0x00); // unit number mem_writed(ptr+0x1f,0xffffffff); // next parameter block break; - case 0x46: - case 0x66: /* Volume label */ + case 0x46: /* Set volume serial number */ + break; + case 0x66: /* Get volume serial number */ { char const* bufin=Drives[drive]->GetLabel(); - char buffer[11] ={' '}; + char buffer[11];memset(buffer,' ',11); char const* find_ext=strchr(bufin,'.'); if (find_ext) { @@ -181,7 +182,7 @@ bool DOS_IOCTL(void) { if (size>8) size=8; memcpy(buffer,bufin,size); find_ext++; - memcpy(buffer+size,find_ext,(strlen(find_ext)>3) ? 3 : strlen(find_ext)); + memcpy(buffer+8,find_ext,(strlen(find_ext)>3) ? 3 : strlen(find_ext)); } else { memcpy(buffer,bufin,(strlen(bufin) > 8) ? 8 : strlen(bufin)); } @@ -189,10 +190,10 @@ bool DOS_IOCTL(void) { char buf2[8]={ 'F','A','T','1','6',' ',' ',' '}; if(drive<2) buf2[4] = '2'; //FAT12 for floppies - mem_writew(ptr+0,0); // 0 + //mem_writew(ptr+0,0); //Info level (call value) mem_writed(ptr+2,0x1234); //Serial number MEM_BlockWrite(ptr+6,buffer,11);//volumename - if(reg_cl == 0x66) MEM_BlockWrite(ptr+0x11, buf2,8);//filesystem + MEM_BlockWrite(ptr+0x11,buf2,8);//filesystem } break; default : From dc5c83eb60f88934e4b99dec6b41aa248481d543 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 22 May 2018 15:11:58 +0000 Subject: [PATCH 4012/4131] Only add return to buffer if it already contains data, which fixes extra return in generated autoexec.bat. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4103 --- src/misc/setup.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 957ef08f..1c44ef7e 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -649,8 +649,8 @@ string Section_prop::GetPropValue(string const& _property) const { } bool Section_line::HandleInputline(string const& line) { - data+=line; - data+="\n"; + if (!data.empty()) data += "\n"; //Add return to previous line in buffer + data += line; return true; } From ee8103cc23efe6207df32811126e861456f8ff04 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 22 May 2018 15:18:00 +0000 Subject: [PATCH 4013/4131] Lock default label of HDD local drive mounts. Fixes label changing to the host drive label when resetting cache on the Windows platform. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4104 --- src/dos/dos_programs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 51bf01b1..63b4c79d 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -403,7 +403,7 @@ public: * This way every drive except cdroms should get a label.*/ else if(type == "dir") { label = drive; label += "_DRIVE"; - newdrive->dirCache.SetLabel(label.c_str(),iscdrom,true); + newdrive->dirCache.SetLabel(label.c_str(),iscdrom,false); } else if(type == "floppy") { label = drive; label += "_FLOPPY"; newdrive->dirCache.SetLabel(label.c_str(),iscdrom,true); From 85789a06da1a0f3051bd729098b4a13a0b92c600 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 22 May 2018 15:18:45 +0000 Subject: [PATCH 4014/4131] Fix echo off being written twice. Attempt to make the line endings in the generated autoexec.bat all DOS style line endings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4105 --- src/shell/shell.cpp | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 01f8a41f..b802844b 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -91,14 +91,28 @@ void AutoexecObject::CreateAutoexec(void) { //Create a new autoexec.bat autoexec_data[0] = 0; size_t auto_len; - for(auto_it it= autoexec_strings.begin(); it != autoexec_strings.end(); it++) { + for(auto_it it = autoexec_strings.begin(); it != autoexec_strings.end(); it++) { + + std::string linecopy = (*it); + std::string::size_type offset = 0; + //Lets have \r\n as line ends in autoexec.bat. + while(offset < linecopy.length()) { + std::string::size_type n = linecopy.find("\n",offset); + if ( n == std::string::npos ) break; + std::string::size_type rn = linecopy.find("\r\n",offset); + if ( rn != std::string::npos && rn + 1 == n) {offset = n + 1; continue;} + // \n found without matching \r + linecopy.replace(n,1,"\r\n"); + offset = n + 2; + } + auto_len = strlen(autoexec_data); - if ((auto_len+(*it).length()+3)>AUTOEXEC_SIZE) { + if ((auto_len+linecopy.length() + 3) > AUTOEXEC_SIZE) { E_Exit("SYSTEM:Autoexec.bat file overflow"); } - sprintf((autoexec_data+auto_len),"%s\r\n",(*it).c_str()); + sprintf((autoexec_data + auto_len),"%s\r\n",linecopy.c_str()); } - if(first_shell) VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,(Bit32u)strlen(autoexec_data)); + if (first_shell) VFILE_Register("AUTOEXEC.BAT",(Bit8u *)autoexec_data,(Bit32u)strlen(autoexec_data)); } AutoexecObject::~AutoexecObject(){ @@ -355,13 +369,22 @@ public: if (extra && !secure && !control->cmdline->FindExist("-noautoexec",true)) { /* detect if "echo off" is the first line */ bool echo_off = !strncasecmp(extra,"echo off",8); - if (!echo_off) echo_off = !strncasecmp(extra,"@echo off",9); + if (echo_off) extra += 8; + else { + echo_off = !strncasecmp(extra,"@echo off",9); + if (echo_off) extra += 9; + } - /* if "echo off" add it to the front of autoexec.bat */ - if(echo_off) autoexec_echo.InstallBefore("@echo off"); + /* if "echo off" move it to the front of autoexec.bat */ + if (echo_off) { + autoexec_echo.InstallBefore("@echo off"); + if (*extra == '\r') extra++; //It can point to \0 + if (*extra == '\n') extra++; //same + } - /* Install the stuff from the configfile */ - autoexec[0].Install(section->data); + /* Install the stuff from the configfile if anything left after moving echo off */ + + if (*extra) autoexec[0].Install(std::string(extra)); } /* Check to see for extra command line options to be added (before the command specified on commandline) */ From 80740117b9ab81aca4bd4864f3824fcedb8767a4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 24 May 2018 18:09:21 +0000 Subject: [PATCH 4015/4131] Take length in consideration before moving the echo off upwards. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4106 --- src/shell/shell.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index b802844b..faad912d 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -368,11 +368,13 @@ public: char * extra = const_cast(section->data.c_str()); if (extra && !secure && !control->cmdline->FindExist("-noautoexec",true)) { /* detect if "echo off" is the first line */ + size_t firstline_length = strcspn(extra,"\r\n"); bool echo_off = !strncasecmp(extra,"echo off",8); - if (echo_off) extra += 8; + if (echo_off && firstline_length == 8) extra += 8; else { echo_off = !strncasecmp(extra,"@echo off",9); - if (echo_off) extra += 9; + if (echo_off && firstline_length == 9) extra += 9; + else echo_off = false; } /* if "echo off" move it to the front of autoexec.bat */ From 671ba9915e8935c368059a24f377cd7b0007cd0f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 29 May 2018 08:59:49 +0000 Subject: [PATCH 4016/4131] Fix comparison and a warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4107 --- src/hardware/serialport/libserial.cpp | 9 ++++++--- src/hardware/serialport/softmodem.cpp | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/hardware/serialport/libserial.cpp b/src/hardware/serialport/libserial.cpp index aa5e9168..761049d4 100644 --- a/src/hardware/serialport/libserial.cpp +++ b/src/hardware/serialport/libserial.cpp @@ -151,10 +151,13 @@ void SERIAL_getErrorString(char* buffer, int length) { sysmsg_offset = strlen(err2text); memcpy(buffer,err2text,sysmsg_offset); } - - if((length - sysmsg_offset - strlen((const char*)sysmessagebuffer)) >= 0) + + // Go for length > so there will be bytes left afterwards. + // (which are 0 due to memset, thus the buffer is 0 terminated + if ( length > (sysmsg_offset + strlen((const char*)sysmessagebuffer)) ) { memcpy(buffer + sysmsg_offset, sysmessagebuffer, - strlen((const char*)sysmessagebuffer)); + strlen((const char*)sysmessagebuffer)); + } LocalFree(sysmessagebuffer); } diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index 0cd87105..58531d59 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -270,7 +270,7 @@ void CSerialModem::EnterIdleState(void){ } // get rid of everything if(serversocket) { - while(waitingclientsocket=serversocket->Accept()) + while( (waitingclientsocket=serversocket->Accept()) ) delete waitingclientsocket; } else if (listenport) { From 4bcbd35104c1b696494ca71ff3ebae10b5d3a49f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 29 May 2018 09:27:16 +0000 Subject: [PATCH 4017/4131] Fix ExpandDot not caring about the size of the buffer. (vogons topic 59658) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4108 --- src/shell/shell_cmds.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 978dab59..1a196df2 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -83,21 +83,21 @@ static void StripSpaces(char*&args,char also) { args++; } -static char* ExpandDot(char*args, char* buffer) { +static char* ExpandDot(char*args, char* buffer , size_t bufsize) { if(*args == '.') { if(*(args+1) == 0){ - strcpy(buffer,"*.*"); + safe_strncpy(buffer, "*.*", bufsize); return buffer; } if( (*(args+1) != '.') && (*(args+1) != '\\') ) { buffer[0] = '*'; buffer[1] = 0; - strcat(buffer,args); + if (bufsize > 2) strncat(buffer,args,bufsize - 1 /*used buffer portion*/ - 1 /*trailing zero*/ ); return buffer; } else - strcpy (buffer, args); + safe_strncpy (buffer, args, bufsize); } - else strcpy(buffer,args); + else safe_strncpy(buffer,args, bufsize); return buffer; } @@ -190,7 +190,7 @@ void DOS_Shell::CMD_DELETE(char * args) { char full[DOS_PATHLENGTH]; char buffer[CROSS_LEN]; - args = ExpandDot(args,buffer); + args = ExpandDot(args,buffer, CROSS_LEN); StripSpaces(args); if (!DOS_Canonicalize(args,full)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH"));return; } //TODO Maybe support confirmation for *.* like dos does. @@ -457,7 +457,7 @@ void DOS_Shell::CMD_DIR(char * args) { break; } } - args = ExpandDot(args,buffer); + args = ExpandDot(args,buffer,CROSS_LEN); if (!strrchr(args,'*') && !strrchr(args,'?')) { Bit16u attribute=0; From 5bb10db88bb32bea54aef17836a61e4a04d226a5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 29 May 2018 12:58:58 +0000 Subject: [PATCH 4018/4131] Time keeps on ticking Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4109 --- acinclude.m4 | 2 +- include/bios.h | 2 +- include/bios_disk.h | 2 +- include/callback.h | 2 +- include/control.h | 2 +- include/cpu.h | 2 +- include/cross.h | 2 +- include/debug.h | 2 +- include/dma.h | 2 +- include/dos_inc.h | 2 +- include/dos_system.h | 2 +- include/dosbox.h | 2 +- include/fpu.h | 2 +- include/hardware.h | 2 +- include/inout.h | 2 +- include/ipx.h | 2 +- include/ipxserver.h | 2 +- include/joystick.h | 2 +- include/keyboard.h | 2 +- include/logging.h | 2 +- include/mapper.h | 2 +- include/mem.h | 2 +- include/midi.h | 2 +- include/mixer.h | 2 +- include/mouse.h | 2 +- include/paging.h | 2 +- include/pci_bus.h | 2 +- include/pic.h | 2 +- include/programs.h | 2 +- include/regs.h | 2 +- include/render.h | 2 +- include/serialport.h | 2 +- include/setup.h | 2 +- include/shell.h | 2 +- include/support.h | 2 +- include/timer.h | 2 +- include/vga.h | 2 +- include/video.h | 2 +- scripts/dosbox-installer.nsi | 2 +- src/cpu/callback.cpp | 2 +- src/cpu/core_dyn_x86.cpp | 2 +- src/cpu/core_dyn_x86/cache.h | 2 +- src/cpu/core_dyn_x86/decoder.h | 2 +- src/cpu/core_dyn_x86/dyn_fpu.h | 2 +- src/cpu/core_dyn_x86/dyn_fpu_dh.h | 2 +- src/cpu/core_dyn_x86/helpers.h | 2 +- src/cpu/core_dyn_x86/risc_x86.h | 2 +- src/cpu/core_dyn_x86/string.h | 2 +- src/cpu/core_dynrec.cpp | 2 +- src/cpu/core_dynrec/cache.h | 2 +- src/cpu/core_dynrec/decoder.h | 2 +- src/cpu/core_dynrec/decoder_basic.h | 2 +- src/cpu/core_dynrec/decoder_opcodes.h | 2 +- src/cpu/core_dynrec/dyn_fpu.h | 2 +- src/cpu/core_dynrec/operators.h | 2 +- src/cpu/core_dynrec/risc_armv4le-common.h | 2 +- src/cpu/core_dynrec/risc_armv4le-o3.h | 2 +- src/cpu/core_dynrec/risc_armv4le-thumb-iw.h | 2 +- src/cpu/core_dynrec/risc_armv4le-thumb-niw.h | 2 +- src/cpu/core_dynrec/risc_armv4le-thumb.h | 2 +- src/cpu/core_dynrec/risc_armv4le.h | 2 +- src/cpu/core_dynrec/risc_mipsel32.h | 2 +- src/cpu/core_dynrec/risc_x64.h | 2 +- src/cpu/core_dynrec/risc_x86.h | 2 +- src/cpu/core_full.cpp | 2 +- src/cpu/core_full/ea_lookup.h | 2 +- src/cpu/core_full/load.h | 2 +- src/cpu/core_full/loadwrite.h | 2 +- src/cpu/core_full/op.h | 2 +- src/cpu/core_full/optable.h | 2 +- src/cpu/core_full/save.h | 2 +- src/cpu/core_full/string.h | 2 +- src/cpu/core_full/support.h | 2 +- src/cpu/core_normal.cpp | 2 +- src/cpu/core_normal/helpers.h | 2 +- src/cpu/core_normal/prefix_0f.h | 2 +- src/cpu/core_normal/prefix_66.h | 2 +- src/cpu/core_normal/prefix_66_0f.h | 2 +- src/cpu/core_normal/prefix_none.h | 2 +- src/cpu/core_normal/string.h | 2 +- src/cpu/core_normal/support.h | 2 +- src/cpu/core_normal/table_ea.h | 2 +- src/cpu/core_prefetch.cpp | 2 +- src/cpu/core_simple.cpp | 2 +- src/cpu/cpu.cpp | 2 +- src/cpu/flags.cpp | 2 +- src/cpu/instructions.h | 2 +- src/cpu/lazyflags.h | 2 +- src/cpu/modrm.cpp | 2 +- src/cpu/modrm.h | 2 +- src/cpu/paging.cpp | 2 +- src/debug/debug.cpp | 2 +- src/debug/debug_gui.cpp | 2 +- src/debug/debug_inc.h | 2 +- src/debug/debug_win32.cpp | 2 +- src/debug/disasm_tables.h | 2 +- src/dos/cdrom.cpp | 2 +- src/dos/cdrom.h | 2 +- src/dos/cdrom_aspi_win32.cpp | 2 +- src/dos/cdrom_image.cpp | 2 +- src/dos/cdrom_ioctl_linux.cpp | 2 +- src/dos/cdrom_ioctl_os2.cpp | 2 +- src/dos/cdrom_ioctl_win32.cpp | 2 +- src/dos/dev_con.h | 2 +- src/dos/dos.cpp | 2 +- src/dos/dos_classes.cpp | 2 +- src/dos/dos_devices.cpp | 2 +- src/dos/dos_execute.cpp | 2 +- src/dos/dos_files.cpp | 2 +- src/dos/dos_ioctl.cpp | 2 +- src/dos/dos_keyboard_layout.cpp | 2 +- src/dos/dos_memory.cpp | 2 +- src/dos/dos_misc.cpp | 2 +- src/dos/dos_mscdex.cpp | 2 +- src/dos/dos_programs.cpp | 2 +- src/dos/dos_tables.cpp | 2 +- src/dos/drive_cache.cpp | 2 +- src/dos/drive_fat.cpp | 2 +- src/dos/drive_iso.cpp | 2 +- src/dos/drive_local.cpp | 2 +- src/dos/drive_virtual.cpp | 2 +- src/dos/drives.cpp | 2 +- src/dos/drives.h | 2 +- src/dosbox.cpp | 2 +- src/fpu/fpu.cpp | 2 +- src/fpu/fpu_instructions.h | 2 +- src/fpu/fpu_instructions_x86.h | 2 +- src/gui/dosbox_logo.h | 2 +- src/gui/midi.cpp | 2 +- src/gui/midi_alsa.h | 2 +- src/gui/midi_coreaudio.h | 2 +- src/gui/midi_oss.h | 2 +- src/gui/midi_win32.h | 2 +- src/gui/render.cpp | 2 +- src/gui/render_loops.h | 2 +- src/gui/render_scalers.cpp | 2 +- src/gui/render_scalers.h | 2 +- src/gui/render_simple.h | 2 +- src/gui/render_templates.h | 2 +- src/gui/render_templates_hq.h | 2 +- src/gui/render_templates_hq2x.h | 2 +- src/gui/render_templates_hq3x.h | 2 +- src/gui/render_templates_sai.h | 2 +- src/gui/sdl_gui.cpp | 4 ++-- src/gui/sdl_mapper.cpp | 2 +- src/gui/sdlmain.cpp | 6 +++--- src/hardware/adlib.cpp | 2 +- src/hardware/adlib.h | 2 +- src/hardware/cmos.cpp | 2 +- src/hardware/dbopl.cpp | 2 +- src/hardware/dbopl.h | 2 +- src/hardware/disney.cpp | 2 +- src/hardware/dma.cpp | 2 +- src/hardware/gameblaster.cpp | 2 +- src/hardware/gus.cpp | 2 +- src/hardware/hardware.cpp | 2 +- src/hardware/iohandler.cpp | 2 +- src/hardware/ipx.cpp | 2 +- src/hardware/ipxserver.cpp | 2 +- src/hardware/joystick.cpp | 2 +- src/hardware/keyboard.cpp | 2 +- src/hardware/memory.cpp | 2 +- src/hardware/mixer.cpp | 2 +- src/hardware/mpu401.cpp | 2 +- src/hardware/opl.cpp | 2 +- src/hardware/opl.h | 2 +- src/hardware/pci_bus.cpp | 2 +- src/hardware/pci_devices.h | 2 +- src/hardware/pcspeaker.cpp | 2 +- src/hardware/pic.cpp | 2 +- src/hardware/sblaster.cpp | 2 +- src/hardware/serialport/directserial.cpp | 2 +- src/hardware/serialport/directserial.h | 2 +- src/hardware/serialport/libserial.cpp | 2 +- src/hardware/serialport/libserial.h | 2 +- src/hardware/serialport/misc_util.cpp | 2 +- src/hardware/serialport/misc_util.h | 2 +- src/hardware/serialport/nullmodem.cpp | 2 +- src/hardware/serialport/nullmodem.h | 2 +- src/hardware/serialport/serialdummy.cpp | 2 +- src/hardware/serialport/serialdummy.h | 2 +- src/hardware/serialport/serialport.cpp | 2 +- src/hardware/serialport/softmodem.cpp | 2 +- src/hardware/serialport/softmodem.h | 2 +- src/hardware/tandy_sound.cpp | 2 +- src/hardware/timer.cpp | 2 +- src/hardware/vga.cpp | 2 +- src/hardware/vga_attr.cpp | 2 +- src/hardware/vga_crtc.cpp | 2 +- src/hardware/vga_dac.cpp | 2 +- src/hardware/vga_draw.cpp | 2 +- src/hardware/vga_gfx.cpp | 2 +- src/hardware/vga_memory.cpp | 2 +- src/hardware/vga_misc.cpp | 2 +- src/hardware/vga_other.cpp | 2 +- src/hardware/vga_paradise.cpp | 2 +- src/hardware/vga_s3.cpp | 2 +- src/hardware/vga_seq.cpp | 2 +- src/hardware/vga_tseng.cpp | 2 +- src/hardware/vga_xga.cpp | 2 +- src/ints/bios.cpp | 2 +- src/ints/bios_disk.cpp | 2 +- src/ints/bios_keyboard.cpp | 2 +- src/ints/ems.cpp | 2 +- src/ints/int10.cpp | 2 +- src/ints/int10.h | 2 +- src/ints/int10_char.cpp | 2 +- src/ints/int10_memory.cpp | 2 +- src/ints/int10_misc.cpp | 2 +- src/ints/int10_modes.cpp | 2 +- src/ints/int10_pal.cpp | 2 +- src/ints/int10_put_pixel.cpp | 2 +- src/ints/int10_vesa.cpp | 2 +- src/ints/int10_video_state.cpp | 2 +- src/ints/int10_vptable.cpp | 2 +- src/ints/mouse.cpp | 2 +- src/ints/xms.cpp | 2 +- src/ints/xms.h | 2 +- src/libs/zmbv/drvproc.cpp | 2 +- src/libs/zmbv/zmbv.cpp | 2 +- src/libs/zmbv/zmbv.h | 2 +- src/libs/zmbv/zmbv_vfw.cpp | 2 +- src/libs/zmbv/zmbv_vfw.rc | 2 +- src/misc/cross.cpp | 2 +- src/misc/messages.cpp | 2 +- src/misc/programs.cpp | 2 +- src/misc/setup.cpp | 2 +- src/misc/support.cpp | 2 +- src/shell/shell.cpp | 2 +- src/shell/shell_batch.cpp | 2 +- src/shell/shell_cmds.cpp | 2 +- src/shell/shell_misc.cpp | 2 +- src/winres.rc | 4 ++-- 233 files changed, 237 insertions(+), 237 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 8b910206..3daa102e 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -305,7 +305,7 @@ AC_SUBST(ALSA_LIBS) AH_TOP([ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/bios.h b/include/bios.h index 5b2de5de..af1545bb 100644 --- a/include/bios.h +++ b/include/bios.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/bios_disk.h b/include/bios_disk.h index 79dd094f..2d175187 100644 --- a/include/bios_disk.h +++ b/include/bios_disk.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/callback.h b/include/callback.h index 5b557460..01632063 100644 --- a/include/callback.h +++ b/include/callback.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/control.h b/include/control.h index 95a555e9..ff1f8052 100644 --- a/include/control.h +++ b/include/control.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/cpu.h b/include/cpu.h index ae26064a..69557d08 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/cross.h b/include/cross.h index e651bca3..5e65ebb0 100644 --- a/include/cross.h +++ b/include/cross.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/debug.h b/include/debug.h index e8ab2b98..cf1d8991 100644 --- a/include/debug.h +++ b/include/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/dma.h b/include/dma.h index 075ceab8..a0624329 100644 --- a/include/dma.h +++ b/include/dma.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/dos_inc.h b/include/dos_inc.h index 9f8590e2..40ecb195 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/dos_system.h b/include/dos_system.h index b8133960..0147cbda 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/dosbox.h b/include/dosbox.h index 6447c120..db9c5114 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/fpu.h b/include/fpu.h index 53e6b341..3611545b 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/hardware.h b/include/hardware.h index 00c4939d..8a474250 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/inout.h b/include/inout.h index c5215f49..8db839c1 100644 --- a/include/inout.h +++ b/include/inout.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/ipx.h b/include/ipx.h index b3fdba54..258c598c 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/ipxserver.h b/include/ipxserver.h index 39d1935c..48420f3e 100644 --- a/include/ipxserver.h +++ b/include/ipxserver.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/joystick.h b/include/joystick.h index a9d53955..b3c302e3 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/keyboard.h b/include/keyboard.h index 76e252e4..058b2ac9 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/logging.h b/include/logging.h index 2d7cb709..a6b7f8f5 100644 --- a/include/logging.h +++ b/include/logging.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/mapper.h b/include/mapper.h index 17320cb9..b69159ae 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/mem.h b/include/mem.h index d5d069cb..40b269a7 100644 --- a/include/mem.h +++ b/include/mem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/midi.h b/include/midi.h index d12aebe9..fc2a5e9d 100644 --- a/include/midi.h +++ b/include/midi.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/mixer.h b/include/mixer.h index b9aecd8d..a8e1aaa8 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/mouse.h b/include/mouse.h index f727594c..880794e6 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/paging.h b/include/paging.h index 5ab0fb50..b39f74ec 100644 --- a/include/paging.h +++ b/include/paging.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/pci_bus.h b/include/pci_bus.h index 0368e1b2..97da4d35 100644 --- a/include/pci_bus.h +++ b/include/pci_bus.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/pic.h b/include/pic.h index 841fe791..e865f768 100644 --- a/include/pic.h +++ b/include/pic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/programs.h b/include/programs.h index 8c5077af..34039a81 100644 --- a/include/programs.h +++ b/include/programs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/regs.h b/include/regs.h index 4a13ae7d..94737d38 100644 --- a/include/regs.h +++ b/include/regs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/render.h b/include/render.h index ba438225..c25ed82c 100644 --- a/include/render.h +++ b/include/render.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/serialport.h b/include/serialport.h index 24b00048..c9aa091f 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/setup.h b/include/setup.h index 345d027e..30e6503c 100644 --- a/include/setup.h +++ b/include/setup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/shell.h b/include/shell.h index 5e2cab0b..d585f3e8 100644 --- a/include/shell.h +++ b/include/shell.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/support.h b/include/support.h index 91643fb1..7ec5f117 100644 --- a/include/support.h +++ b/include/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/timer.h b/include/timer.h index 14c609a7..bddedc08 100644 --- a/include/timer.h +++ b/include/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/vga.h b/include/vga.h index 85a9c228..34e08e4e 100644 --- a/include/vga.h +++ b/include/vga.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/include/video.h b/include/video.h index 20ad8378..5a7a4ae8 100644 --- a/include/video.h +++ b/include/video.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index 1abc0b1c..27b527bf 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -2,7 +2,7 @@ !define VER_MINOR 74 !define APP_NAME "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer" !define COMP_NAME "DOSBox Team" -!define COPYRIGHT "Copyright © 2002-2017 DOSBox Team" +!define COPYRIGHT "Copyright © 2002-2018 DOSBox Team" !define DESCRIPTION "DOSBox Installer" VIProductVersion "${VER_MAYOR}.${VER_MINOR}.0.0" diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 37183bf4..25c91aeb 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index aae65cb4..70c0091d 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index dc42ebab..ca96bef8 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index dd1dae8c..c34052f2 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dyn_x86/dyn_fpu.h b/src/cpu/core_dyn_x86/dyn_fpu.h index 62f085d4..49f1fef8 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu.h +++ b/src/cpu/core_dyn_x86/dyn_fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dyn_x86/dyn_fpu_dh.h b/src/cpu/core_dyn_x86/dyn_fpu_dh.h index f633ff5c..f68d69b0 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu_dh.h +++ b/src/cpu/core_dyn_x86/dyn_fpu_dh.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dyn_x86/helpers.h b/src/cpu/core_dyn_x86/helpers.h index bb97f080..c2b0de9f 100644 --- a/src/cpu/core_dyn_x86/helpers.h +++ b/src/cpu/core_dyn_x86/helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index b8079143..379906f9 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index 2c87adf3..ea540ab4 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index ba24b2e4..ff2881f8 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index fbe0a001..b1f705c7 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h index 0460d508..c34e9a79 100644 --- a/src/cpu/core_dynrec/decoder.h +++ b/src/cpu/core_dynrec/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index bcc1b8d1..363c1df0 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index ceecb763..cd460b9b 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dynrec/dyn_fpu.h b/src/cpu/core_dynrec/dyn_fpu.h index eae703e6..cdb3e721 100644 --- a/src/cpu/core_dynrec/dyn_fpu.h +++ b/src/cpu/core_dynrec/dyn_fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dynrec/operators.h b/src/cpu/core_dynrec/operators.h index 9754d5de..756eed9b 100644 --- a/src/cpu/core_dynrec/operators.h +++ b/src/cpu/core_dynrec/operators.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-common.h b/src/cpu/core_dynrec/risc_armv4le-common.h index 89832d86..6d86c7ee 100644 --- a/src/cpu/core_dynrec/risc_armv4le-common.h +++ b/src/cpu/core_dynrec/risc_armv4le-common.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-o3.h b/src/cpu/core_dynrec/risc_armv4le-o3.h index 974ac3bd..5eaafcf6 100644 --- a/src/cpu/core_dynrec/risc_armv4le-o3.h +++ b/src/cpu/core_dynrec/risc_armv4le-o3.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h index 574eb2b8..9f24bb90 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h index c1696dd0..f49ffe6e 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb.h b/src/cpu/core_dynrec/risc_armv4le-thumb.h index f4f36482..18e87541 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dynrec/risc_armv4le.h b/src/cpu/core_dynrec/risc_armv4le.h index e6ed1c71..a93a8652 100644 --- a/src/cpu/core_dynrec/risc_armv4le.h +++ b/src/cpu/core_dynrec/risc_armv4le.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dynrec/risc_mipsel32.h b/src/cpu/core_dynrec/risc_mipsel32.h index a9aed644..9aa40efc 100644 --- a/src/cpu/core_dynrec/risc_mipsel32.h +++ b/src/cpu/core_dynrec/risc_mipsel32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index 35a3455a..5c7e59dc 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_dynrec/risc_x86.h b/src/cpu/core_dynrec/risc_x86.h index 6b275ff8..e5e46f46 100644 --- a/src/cpu/core_dynrec/risc_x86.h +++ b/src/cpu/core_dynrec/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 1d4ab155..4e5e3909 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_full/ea_lookup.h b/src/cpu/core_full/ea_lookup.h index 71e639dd..b01a684b 100644 --- a/src/cpu/core_full/ea_lookup.h +++ b/src/cpu/core_full/ea_lookup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 7854d837..e9b60fe0 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_full/loadwrite.h b/src/cpu/core_full/loadwrite.h index 86323577..985a6443 100644 --- a/src/cpu/core_full/loadwrite.h +++ b/src/cpu/core_full/loadwrite.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 7e1a083a..81ce577a 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 6494de00..be66c12d 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_full/save.h b/src/cpu/core_full/save.h index f587215a..5862bb74 100644 --- a/src/cpu/core_full/save.h +++ b/src/cpu/core_full/save.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index 64fc38cf..f760683f 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index cca7f4c5..7a9e036a 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index dc659fcd..103657bf 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_normal/helpers.h b/src/cpu/core_normal/helpers.h index dd0465f0..58205aec 100644 --- a/src/cpu/core_normal/helpers.h +++ b/src/cpu/core_normal/helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index dc6ba3e1..33d8cf6c 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 87527d20..9c199374 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index b23fb4d5..dbae2985 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index deaed2c3..9221392e 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_normal/string.h b/src/cpu/core_normal/string.h index d1459072..a5e90611 100644 --- a/src/cpu/core_normal/string.h +++ b/src/cpu/core_normal/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index 02286fff..87d79726 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_normal/table_ea.h b/src/cpu/core_normal/table_ea.h index 28b73ff1..9ca2b0c7 100644 --- a/src/cpu/core_normal/table_ea.h +++ b/src/cpu/core_normal/table_ea.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_prefetch.cpp b/src/cpu/core_prefetch.cpp index de518167..036c6a92 100644 --- a/src/cpu/core_prefetch.cpp +++ b/src/cpu/core_prefetch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp index 98c35546..19f13436 100644 --- a/src/cpu/core_simple.cpp +++ b/src/cpu/core_simple.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 473d69c9..659d4a80 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 3ceaa9e8..63b7b45b 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index f4abed86..17bddb72 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index 6cb688ed..39994707 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/modrm.cpp b/src/cpu/modrm.cpp index 6582c552..0004825e 100644 --- a/src/cpu/modrm.cpp +++ b/src/cpu/modrm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/modrm.h b/src/cpu/modrm.h index c854e579..c639c374 100644 --- a/src/cpu/modrm.h +++ b/src/cpu/modrm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 20aa225c..57d8898b 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 99aa12ab..a6e4b7c7 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index ae86ac21..d1fa5c46 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h index 7dc736ab..28517ce0 100644 --- a/src/debug/debug_inc.h +++ b/src/debug/debug_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/debug/debug_win32.cpp b/src/debug/debug_win32.cpp index 38af8a33..23826fc1 100644 --- a/src/debug/debug_win32.cpp +++ b/src/debug/debug_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/debug/disasm_tables.h b/src/debug/disasm_tables.h index 2c738c42..93d1bcb7 100644 --- a/src/debug/disasm_tables.h +++ b/src/debug/disasm_tables.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 87e8ae43..9608e87d 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index 90e1334e..803c7aa2 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index 5ea97b04..cc8de4e3 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index a2bcc06a..0e81a83d 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/cdrom_ioctl_linux.cpp b/src/dos/cdrom_ioctl_linux.cpp index a6f7b7f9..fb73986e 100644 --- a/src/dos/cdrom_ioctl_linux.cpp +++ b/src/dos/cdrom_ioctl_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/cdrom_ioctl_os2.cpp b/src/dos/cdrom_ioctl_os2.cpp index 9cf4981a..6e32af55 100644 --- a/src/dos/cdrom_ioctl_os2.cpp +++ b/src/dos/cdrom_ioctl_os2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index dd7cc0eb..465e6bd6 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index 26c4dd63..ce31eca2 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index b7735526..6338086c 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 6c2e36d4..3df73f2e 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index fd3ec476..89fe3531 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 2a9608ef..ba02cc51 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index b7cf1ca4..fb4992bb 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 992e6b2b..a8cc9fa0 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index b22f9b2a..f27ddb9a 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 00593a85..8cdd810f 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index 400405ec..182cf239 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index d6369d39..73fbabd3 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 63b4c79d..f09b55dc 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 5587f252..4943593a 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index c3418399..00ef06de 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 07825b2d..3c1b7f89 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 0efa15d5..2faa8aca 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 562ebee4..46ebb7df 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 28678cbf..f17ad533 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index 92f9d830..46c91291 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dos/drives.h b/src/dos/drives.h index 6b7ef865..b06f1861 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/dosbox.cpp b/src/dosbox.cpp index df040f09..a5012665 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 25225ee6..86131b5c 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 37c08688..2e792d1d 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index fe49fd1b..fd245220 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/gui/dosbox_logo.h b/src/gui/dosbox_logo.h index f7592387..1d1053e4 100644 --- a/src/gui/dosbox_logo.h +++ b/src/gui/dosbox_logo.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index 88196c2e..d17963e4 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 6f87dca6..9041fd7e 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index 66b4a28f..b92e649d 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index 4b8ad101..f4269ead 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index 3bb9a45c..d970860e 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/gui/render.cpp b/src/gui/render.cpp index f852767c..d6be555d 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/gui/render_loops.h b/src/gui/render_loops.h index 0cfe5132..f67a5069 100644 --- a/src/gui/render_loops.h +++ b/src/gui/render_loops.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index eaf6bf34..a84a27e4 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index b302664f..82fd43f5 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/gui/render_simple.h b/src/gui/render_simple.h index 1b24e931..07b0b120 100644 --- a/src/gui/render_simple.h +++ b/src/gui/render_simple.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index ce1ca495..59c08874 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/gui/render_templates_hq.h b/src/gui/render_templates_hq.h index 843cdca0..9f676152 100644 --- a/src/gui/render_templates_hq.h +++ b/src/gui/render_templates_hq.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/gui/render_templates_hq2x.h b/src/gui/render_templates_hq2x.h index 3b3a40a3..28c6c429 100644 --- a/src/gui/render_templates_hq2x.h +++ b/src/gui/render_templates_hq2x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/gui/render_templates_hq3x.h b/src/gui/render_templates_hq3x.h index 0ec55839..33c5ab35 100644 --- a/src/gui/render_templates_hq3x.h +++ b/src/gui/render_templates_hq3x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/gui/render_templates_sai.h b/src/gui/render_templates_sai.h index 484ad9e8..cf7b5e8b 100644 --- a/src/gui/render_templates_sai.h +++ b/src/gui/render_templates_sai.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index 229176ea..3986d399 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 @@ -569,7 +569,7 @@ public: Section_prop *section = static_cast(sec); new SectionEditor(getScreen(), 50, 30, section); } else if (arg == "About") { - new GUI::MessageBox(getScreen(), 200, 150, 280, "About DOSBox", "\nDOSBox 0.74\nAn emulator for old DOS Games\n\nCopyright 2002-2017\nThe DOSBox Team"); + new GUI::MessageBox(getScreen(), 200, 150, 280, "About DOSBox", "\nDOSBox 0.74\nAn emulator for old DOS Games\n\nCopyright 2002-2018\nThe DOSBox Team"); } else if (arg == "Introduction") { new GUI::MessageBox(getScreen(), 20, 50, 600, "Introduction", MSG_Get("PROGRAM_INTRO")); } else if (arg == "Getting Started") { diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 360c36bf..2e6f7def 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 8062239b..f99ce60b 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 @@ -1962,7 +1962,7 @@ int main(int argc, char* argv[]) { #endif //defined(WIN32) && !(C_DEBUG) if (control->cmdline->FindExist("-version") || control->cmdline->FindExist("--version") ) { - printf("\nDOSBox version %s, copyright 2002-2017 DOSBox Team.\n\n",VERSION); + printf("\nDOSBox version %s, copyright 2002-2018 DOSBox Team.\n\n",VERSION); printf("DOSBox is written by the DOSBox Team (See AUTHORS file))\n"); printf("DOSBox comes with ABSOLUTELY NO WARRANTY. This is free software,\n"); printf("and you are welcome to redistribute it under certain conditions;\n"); @@ -1990,7 +1990,7 @@ int main(int argc, char* argv[]) { /* Display Welcometext in the console */ LOG_MSG("DOSBox version %s",VERSION); - LOG_MSG("Copyright 2002-2017 DOSBox Team, published under GNU GPL."); + LOG_MSG("Copyright 2002-2018 DOSBox Team, published under GNU GPL."); LOG_MSG("---"); /* Init SDL */ diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index de56dcc6..e0b4c598 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/adlib.h b/src/hardware/adlib.h index eafbaaf0..5d5065ad 100644 --- a/src/hardware/adlib.h +++ b/src/hardware/adlib.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 68390b34..362aa54b 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index 8b6df319..4416c50a 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/dbopl.h b/src/hardware/dbopl.h index e33d7e35..4e61b118 100644 --- a/src/hardware/dbopl.h +++ b/src/hardware/dbopl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 12cc020d..671487c9 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 5eb69498..f310c582 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index dbe3b093..0047962a 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 68c90988..a539b135 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 14958c3a..d66143f9 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 619808ec..816e3c4a 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index 7d8dd5d3..58317cdb 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/ipxserver.cpp b/src/hardware/ipxserver.cpp index 1f478121..1f4554e4 100644 --- a/src/hardware/ipxserver.cpp +++ b/src/hardware/ipxserver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index a9ae2321..e2318bff 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 7872b2ba..0a0a5c18 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index 972f9dd7..a8357b15 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 5780b4e5..1fbe4443 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index a5aec2a6..4f9e4f30 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/opl.cpp b/src/hardware/opl.cpp index af7afb33..54155c5d 100644 --- a/src/hardware/opl.cpp +++ b/src/hardware/opl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 The DOSBox Team * OPL2/OPL3 emulation library * * This library is free software; you can redistribute it and/or diff --git a/src/hardware/opl.h b/src/hardware/opl.h index 497b97ef..fd7d7584 100644 --- a/src/hardware/opl.h +++ b/src/hardware/opl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 The DOSBox Team * OPL2/OPL3 emulation library * * This library is free software; you can redistribute it and/or diff --git a/src/hardware/pci_bus.cpp b/src/hardware/pci_bus.cpp index 1a9f962b..dddb6468 100644 --- a/src/hardware/pci_bus.cpp +++ b/src/hardware/pci_bus.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/pci_devices.h b/src/hardware/pci_devices.h index a61c7634..69730055 100644 --- a/src/hardware/pci_devices.h +++ b/src/hardware/pci_devices.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 5a0069ec..39ee957c 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 4f37a09d..0bdba54a 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 49d0bfe3..d6d2a9da 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/serialport/directserial.cpp b/src/hardware/serialport/directserial.cpp index 88c2bc99..d4c26977 100644 --- a/src/hardware/serialport/directserial.cpp +++ b/src/hardware/serialport/directserial.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/serialport/directserial.h b/src/hardware/serialport/directserial.h index e60a88f2..9955bf09 100644 --- a/src/hardware/serialport/directserial.h +++ b/src/hardware/serialport/directserial.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/serialport/libserial.cpp b/src/hardware/serialport/libserial.cpp index 761049d4..07860319 100644 --- a/src/hardware/serialport/libserial.cpp +++ b/src/hardware/serialport/libserial.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/serialport/libserial.h b/src/hardware/serialport/libserial.h index f951e4dc..417ff83a 100644 --- a/src/hardware/serialport/libserial.h +++ b/src/hardware/serialport/libserial.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/serialport/misc_util.cpp b/src/hardware/serialport/misc_util.cpp index 8d1ae2e6..e21ddb19 100644 --- a/src/hardware/serialport/misc_util.cpp +++ b/src/hardware/serialport/misc_util.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/serialport/misc_util.h b/src/hardware/serialport/misc_util.h index 989c6dd3..b866669d 100644 --- a/src/hardware/serialport/misc_util.h +++ b/src/hardware/serialport/misc_util.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/serialport/nullmodem.cpp b/src/hardware/serialport/nullmodem.cpp index bbb35fb5..3663ab75 100644 --- a/src/hardware/serialport/nullmodem.cpp +++ b/src/hardware/serialport/nullmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/serialport/nullmodem.h b/src/hardware/serialport/nullmodem.h index d1aff414..c5f648e1 100644 --- a/src/hardware/serialport/nullmodem.h +++ b/src/hardware/serialport/nullmodem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/serialport/serialdummy.cpp b/src/hardware/serialport/serialdummy.cpp index 790237d5..ce3ff19a 100644 --- a/src/hardware/serialport/serialdummy.cpp +++ b/src/hardware/serialport/serialdummy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/serialport/serialdummy.h b/src/hardware/serialport/serialdummy.h index bb4b5fb2..d5c00328 100644 --- a/src/hardware/serialport/serialdummy.h +++ b/src/hardware/serialport/serialdummy.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index 2fb1ea89..e74bfccd 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index 58531d59..ef109f6c 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index c50f8d48..81e49d71 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 6017219a..99cc79b6 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index da562b48..0173f99a 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index dd25069e..3d453846 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index dd914db7..3d48d8ed 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index baceb8f9..991d6eaa 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index 96833d20..f5cd529f 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 0ec12738..9a939975 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index 76247fd6..40e04203 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index d354f472..dcd5e47d 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 122c1455..6ca9a8ad 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 068a8f42..1e0f91d2 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/vga_paradise.cpp b/src/hardware/vga_paradise.cpp index 345054a8..59b56420 100644 --- a/src/hardware/vga_paradise.cpp +++ b/src/hardware/vga_paradise.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index a0e7204a..87bbbedb 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 74f3c425..7cd711c4 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/vga_tseng.cpp b/src/hardware/vga_tseng.cpp index 9e66c9f5..81e4c2c1 100644 --- a/src/hardware/vga_tseng.cpp +++ b/src/hardware/vga_tseng.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index a5398a52..def606d9 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 5d1a746d..9364aec0 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 363c02ed..863b88ad 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index ca0c75af..8c234c7a 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index b3dd104b..c8357069 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index a9cfda2b..2a8f9967 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/ints/int10.h b/src/ints/int10.h index bc599125..fa3d6f7c 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index f6153b30..d8c5aaa9 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 383f972b..1d1e2cd3 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 23c91639..572da17f 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index d583b71c..b10f233b 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 77696267..8b3b596c 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index f89dd0d8..ec7cd967 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index e17ea4f2..fde8ce9c 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/ints/int10_video_state.cpp b/src/ints/int10_video_state.cpp index 2a6c2613..37888bb3 100644 --- a/src/ints/int10_video_state.cpp +++ b/src/ints/int10_video_state.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/ints/int10_vptable.cpp b/src/ints/int10_vptable.cpp index 165ac320..aca7a7d3 100644 --- a/src/ints/int10_vptable.cpp +++ b/src/ints/int10_vptable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 7b6676ca..2d0d5d77 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 05286028..60b84a1b 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/ints/xms.h b/src/ints/xms.h index 81eb8d36..cca119bb 100644 --- a/src/ints/xms.h +++ b/src/ints/xms.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/libs/zmbv/drvproc.cpp b/src/libs/zmbv/drvproc.cpp index 7007c8d3..ffbfe4f3 100644 --- a/src/libs/zmbv/drvproc.cpp +++ b/src/libs/zmbv/drvproc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/libs/zmbv/zmbv.cpp b/src/libs/zmbv/zmbv.cpp index 0318a777..22044d28 100644 --- a/src/libs/zmbv/zmbv.cpp +++ b/src/libs/zmbv/zmbv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/libs/zmbv/zmbv.h b/src/libs/zmbv/zmbv.h index 1826e56e..782832b1 100644 --- a/src/libs/zmbv/zmbv.h +++ b/src/libs/zmbv/zmbv.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/libs/zmbv/zmbv_vfw.cpp b/src/libs/zmbv/zmbv_vfw.cpp index a5cbc4e8..0dfae332 100644 --- a/src/libs/zmbv/zmbv_vfw.cpp +++ b/src/libs/zmbv/zmbv_vfw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/libs/zmbv/zmbv_vfw.rc b/src/libs/zmbv/zmbv_vfw.rc index 8929ab1b..bd5ac62d 100644 --- a/src/libs/zmbv/zmbv_vfw.rc +++ b/src/libs/zmbv/zmbv_vfw.rc @@ -59,7 +59,7 @@ CAPTION "DOSBox Video Codec v0.1" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN DEFPUSHBUTTON "OK",IDOK,131,34,29,14 - CTEXT "Zipped Motion Block Video v 0.1\nCopyright 2009-2017 DOSBox Team", + CTEXT "Zipped Motion Block Video v 0.1\nCopyright 2009-2018 DOSBox Team", IDC_STATIC,7,7,153,25,SS_NOPREFIX PUSHBUTTON "Email author",IDC_EMAIL,7,34,50,14 PUSHBUTTON "Visit home page",IDC_HOMEPAGE,59,34,58,14 diff --git a/src/misc/cross.cpp b/src/misc/cross.cpp index 09290c56..5820e981 100644 --- a/src/misc/cross.cpp +++ b/src/misc/cross.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 6f4c7586..0ab465de 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 309bb9c0..cd265c5d 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 1c44ef7e..2843652b 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 9b766a64..339a6196 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index faad912d..a04135c9 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index e76866fc..9d92df38 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 1a196df2..9762cfc6 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 1fdb5d7e..dd441bbf 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2017 The DOSBox Team + * Copyright (C) 2002-2018 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 diff --git a/src/winres.rc b/src/winres.rc index f675e152..99292c2e 100644 --- a/src/winres.rc +++ b/src/winres.rc @@ -19,12 +19,12 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "Comments", "© 2002-2017 DOSBox Team, published under GNU GPL" + VALUE "Comments", "© 2002-2018 DOSBox Team, published under GNU GPL" VALUE "CompanyName", "DOSBox Team" VALUE "FileDescription", "DOSBox DOS Emulator" VALUE "FileVersion", "0, 74, 0, 0" VALUE "InternalName", "DOSBox" - VALUE "LegalCopyright", "Copyright © 2002-2017 DOSBox Team" + VALUE "LegalCopyright", "Copyright © 2002-2018 DOSBox Team" VALUE "OriginalFilename", "dosbox.exe" VALUE "ProductName", "DOSBox DOS Emulator" VALUE "ProductVersion", "0, 74, 0, 0" From f9ac735c985ad0e35914e629397f3e070d0230a4 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Wed, 30 May 2018 12:52:17 +0000 Subject: [PATCH 4019/4131] Be less specific about the jump instruction when identifying a video BIOS. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4110 --- src/dos/dos_programs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index f09b55dc..bb442481 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -908,7 +908,7 @@ public: /* try to identify ROM type */ PhysPt rom_base = 0; if (data_read >= 0x4000 && rom_buffer[0] == 0x55 && rom_buffer[1] == 0xaa && - rom_buffer[3] == 0xeb && strncmp((char*)(&rom_buffer[0x1e]), "IBM", 3) == 0) { + (rom_buffer[3] & 0xfc) == 0xe8 && strncmp((char*)(&rom_buffer[0x1e]), "IBM", 3) == 0) { if (!IS_EGAVGA_ARCH) { WriteOut(MSG_Get("PROGRAM_LOADROM_INCOMPATIBLE")); From 825999f3b8a365b483f0ab622bf4c00fda51d04f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 30 May 2018 17:54:50 +0000 Subject: [PATCH 4020/4131] Ensure stat receives the correct path when base_path misses filesplit. Remove duplicate code. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4111 --- src/misc/cross.cpp | 38 +++++++------------------------------- 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/src/misc/cross.cpp b/src/misc/cross.cpp index 5820e981..021d8f35 100644 --- a/src/misc/cross.cpp +++ b/src/misc/cross.cpp @@ -197,34 +197,7 @@ dir_information* open_directory(const char* dirname) { } bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory) { - struct dirent* dentry = readdir(dirp->dir); - if (dentry==NULL) { - return false; - } - -// safe_strncpy(entry_name,dentry->d_name,(FILENAME_MAXd_name,CROSS_LEN); - -#ifdef DIRENT_HAS_D_TYPE - if(dentry->d_type == DT_DIR) { - is_directory = true; - return true; - } else if(dentry->d_type == DT_REG) { - is_directory = false; - return true; - } -#endif - - // probably use d_type here instead of a full stat() - static char buffer[2*CROSS_LEN] = { 0 }; - buffer[0] = 0; - strcpy(buffer,dirp->base_path); - strcat(buffer,entry_name); - struct stat status; - if (stat(buffer,&status)==0) is_directory = (S_ISDIR(status.st_mode)>0); - else is_directory = false; - - return true; + return read_directory_next(dirp,entry_name,is_directory); } bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) { @@ -246,14 +219,17 @@ bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_direc } #endif - // probably use d_type here instead of a full stat() - static char buffer[2*CROSS_LEN] = { 0 }; + //Maybe only for DT_UNKNOWN if DIRENT_HAD_D_TYPE.. + static char buffer[2 * CROSS_LEN + 1] = { 0 }; + static char split[2] = { CROSS_FILESPLIT , 0 }; buffer[0] = 0; strcpy(buffer,dirp->base_path); + size_t buflen = strlen(buffer); + if (buflen && buffer[buflen - 1] != CROSS_FILESPLIT ) strcat(buffer, split); strcat(buffer,entry_name); struct stat status; - if (stat(buffer,&status)==0) is_directory = (S_ISDIR(status.st_mode)>0); + if (stat(buffer,&status) == 0) is_directory = (S_ISDIR(status.st_mode)>0); else is_directory = false; return true; From cb8bf9f8f6d24d40e0b6eb64b687b9033f6cbdcb Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sat, 2 Jun 2018 18:21:21 +0000 Subject: [PATCH 4021/4131] Return an error for generic block device request on unmounted floppy drives. Fixes bug #481. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4112 --- src/dos/dos_ioctl.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index a8cc9fa0..1357bd72 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -152,6 +152,10 @@ bool DOS_IOCTL(void) { return true; case 0x0D: /* Generic block device request */ { + if (drive < 2 && !Drives[drive]) { + DOS_SetError(DOSERR_ACCESS_DENIED); + return false; + } if (Drives[drive]->isRemovable()) { DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); return false; From fdc5a0620031e3f049b121479d62d69005e3c1ab Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Jun 2018 14:51:22 +0000 Subject: [PATCH 4022/4131] No irq generating when masking the IRQ channel. Fixes later sci games and bug #482. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4113 --- src/hardware/sblaster.cpp | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index d6d2a9da..9058df08 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -273,11 +273,27 @@ static INLINE void DSP_FlushData(void) { sb.dsp.out.pos=0; } +static double last_dma_callback = 0.0f; + static void DSP_DMA_CallBack(DmaChannel * chan, DMAEvent event) { if (chan!=sb.dma.chan || event==DMA_REACHED_TC) return; else if (event==DMA_MASKED) { if (sb.mode==MODE_DMA) { - GenerateDMASound(sb.dma.min); + //Catch up to current time, but don't generate an IRQ! + //Fixes problems with later sci games. + double t = PIC_FullIndex() - last_dma_callback; + Bitu s = static_cast(sb.dma.rate * t / 1000.0f); + if (s > sb.dma.min) { + LOG(LOG_SB,LOG_NORMAL)("limiting amount masked to sb.dma.min"); + s = sb.dma.min; + } + Bitu min_size = sb.dma.mul >> SB_SH; + if (!min_size) min_size = 1; + min_size *= 2; + if (sb.dma.left > min_size) { + if (s > (sb.dma.left-min_size)) s = sb.dma.left - min_size; + GenerateDMASound(s); + } sb.mode=MODE_DMA_MASKED; // DSP_ChangeMode(MODE_DMA_MASKED); LOG(LOG_SB,LOG_NORMAL)("DMA masked,stopping output, left %d",chan->currcnt); @@ -394,12 +410,15 @@ INLINE Bit8u decode_ADPCM_3_sample(Bit8u sample,Bit8u & reference,Bits& scale) { static void GenerateDMASound(Bitu size) { Bitu read=0;Bitu done=0;Bitu i=0; + last_dma_callback = PIC_FullIndex(); if(sb.dma.autoinit) { if (sb.dma.left <= size) size = sb.dma.left; - } else if (sb.dma.left <= sb.dma.min) - size = sb.dma.left; + } else { + if (sb.dma.left <= sb.dma.min) + size = sb.dma.left; + } switch (sb.dma.mode) { case DSP_DMA_2: From 31d7e74eacd4957cf6e6c63804d94b572dc0943c Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 12 Jun 2018 20:04:10 +0000 Subject: [PATCH 4023/4131] It is more compatible with DOS to not insert carriage returns in the console device. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4114 --- src/dos/dev_con.h | 8 ++------ src/shell/shell_misc.cpp | 2 ++ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index ce31eca2..c18b84cb 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -37,7 +37,6 @@ private: void ClearAnsi(void); void Output(Bit8u chr); Bit8u readcache; - Bit8u lastwrite; struct ansi { /* should create a constructor, which would fill them with the appropriate values */ bool esc; bool sci; @@ -136,13 +135,11 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) { Output(' '); col=CURSOR_POS_COL(page); } while(col%8); - lastwrite = data[count++]; + count++; continue; } else { - /* Some sort of "hack" now that '\n' doesn't set col to 0 (int10_char.cpp old chessgame) */ - if((data[count] == '\n') && (lastwrite != '\r')) Output('\r'); Output(data[count]); - lastwrite = data[count++]; + count++; continue; } } @@ -411,7 +408,6 @@ Bit16u device_CON::GetInformation(void) { device_CON::device_CON() { SetName("CON"); readcache=0; - lastwrite=0; ansi.enabled=false; ansi.attr=0x7; ansi.saverow=0; diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index dd441bbf..99f44865 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -223,6 +223,7 @@ void DOS_Shell::InputCommand(char * line) { /* Don't care */ break; case 0x0d: /* Return */ + outc('\r'); outc('\n'); size=0; //Kill the while loop break; @@ -322,6 +323,7 @@ void DOS_Shell::InputCommand(char * line) { case 0x1b: /* ESC */ //write a backslash and return to the next line outc('\\'); + outc('\r'); outc('\n'); *line = 0; // reset the line. if (l_completion.size()) l_completion.clear(); //reset the completion list. From ff8d4f287fb443b3880bcebb2823505b37207600 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 12 Jun 2018 20:18:42 +0000 Subject: [PATCH 4024/4131] More improvements for IOCTL generic block device request Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4115 --- src/dos/dos.cpp | 8 +------- src/dos/dos_ioctl.cpp | 15 +++++++-------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 6338086c..2864fb02 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1118,13 +1118,7 @@ static Bitu DOS_21Handler(void) { } reg_ch=0x08; // IOCTL category: disk drive reg_ax=0x440d; // Generic block device request - if (DOS_IOCTL()) { - reg_ax=0; // AX destroyed - CALLBACK_SCF(false); - } else { - reg_ax=dos.errorcode; - CALLBACK_SCF(true); - } + DOS_21Handler(); reg_cx=old_cx; break; } diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index 1357bd72..ad8ebe42 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -156,22 +156,20 @@ bool DOS_IOCTL(void) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } - if (Drives[drive]->isRemovable()) { + if (reg_ch != 0x08 || Drives[drive]->isRemovable()) { DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); return false; } PhysPt ptr = SegPhys(ds)+reg_dx; switch (reg_cl) { case 0x60: /* Get Device parameters */ - mem_writeb(ptr ,0x03); // special function - mem_writeb(ptr+1,(drive>=2)?0x05:0x14); // fixed disc(5), 1.44 floppy(14) - mem_writew(ptr+2,drive>=2); // nonremovable ? + //mem_writeb(ptr+0,0); // special functions (call value) + mem_writeb(ptr+1,(drive>=2)?0x05:0x07); // type: hard disk(5), 1.44 floppy(7) + mem_writew(ptr+2,(drive>=2)?0x01:0x00); // attributes: bit 0 set for nonremovable mem_writew(ptr+4,0x0000); // num of cylinders mem_writeb(ptr+6,0x00); // media type (00=other type) - // drive parameter block following - mem_writeb(ptr+7,drive); // drive - mem_writeb(ptr+8,0x00); // unit number - mem_writed(ptr+0x1f,0xffffffff); // next parameter block + // bios parameter block following + mem_writew(ptr+7,0x0200); // bytes per sector (Win3 File Mgr. uses it) break; case 0x46: /* Set volume serial number */ break; @@ -205,6 +203,7 @@ bool DOS_IOCTL(void) { DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); return false; } + reg_ax=0; return true; } case 0x0E: /* Get Logical Drive Map */ From 1afaf2892107501e25e6d4ef58c0d863cb5b8b51 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 12 Jun 2018 20:52:08 +0000 Subject: [PATCH 4025/4131] Make Media ID table relative to DPB table. Fixes Hattrick by Ikarion. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4116 --- src/dos/dos.cpp | 4 ++-- src/dos/dos_files.cpp | 4 ++-- src/dos/dos_misc.cpp | 2 +- src/dos/dos_programs.cpp | 7 ++++--- src/dos/dos_tables.cpp | 10 ++++++---- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 2864fb02..897b6880 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -494,10 +494,10 @@ static Bitu DOS_21Handler(void) { Bit8u drive=reg_dl; if (!drive || reg_ah==0x1f) drive = DOS_GetDefaultDrive(); else drive--; - if (Drives[drive]) { + if (drive < DOS_DRIVES && Drives[drive] && !Drives[drive]->isRemovable()) { reg_al = 0x00; SegSet16(ds,dos.tables.dpb); - reg_bx = drive;//Faking only the first entry (that is the driveletter) + reg_bx = drive*5;//Faking the first entry (drive number) and media id LOG(LOG_DOSMISC,LOG_ERROR)("Get drive parameter block."); } else { reg_al=0xff; diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index fb4992bb..49d7eeea 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1281,14 +1281,14 @@ bool DOS_FileExists(char const * const name) { bool DOS_GetAllocationInfo(Bit8u drive,Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters) { if (!drive) drive = DOS_GetDefaultDrive(); else drive--; - if (drive >= DOS_DRIVES || !Drives[drive]) { + if (drive >= DOS_DRIVES || !Drives[drive] || Drives[drive]->isRemovable()) { DOS_SetError(DOSERR_INVALID_DRIVE); return false; } Bit16u _free_clusters; Drives[drive]->AllocationInfo(_bytes_sector,_sectors_cluster,_total_clusters,&_free_clusters); SegSet16(ds,RealSeg(dos.tables.mediaid)); - reg_bx=RealOff(dos.tables.mediaid+drive*2); + reg_bx=RealOff(dos.tables.mediaid+drive*5); return true; } diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index 182cf239..ed180b3a 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -90,7 +90,7 @@ static bool DOS_MultiplexFunctions(void) { mem_writew(sftptr+sftofs+0x02,(Bit16u)(Files[reg_bx]->flags&3)); // file open mode mem_writeb(sftptr+sftofs+0x04,(Bit8u)(Files[reg_bx]->attr)); // file attribute mem_writew(sftptr+sftofs+0x05,0x40|drive); // device info word - mem_writed(sftptr+sftofs+0x07,RealMake(dos.tables.dpb,drive)); // dpb of the drive + mem_writed(sftptr+sftofs+0x07,RealMake(dos.tables.dpb,drive*5)); // dpb of the drive mem_writew(sftptr+sftofs+0x0d,Files[reg_bx]->time); // packed file time mem_writew(sftptr+sftofs+0x0f,Files[reg_bx]->date); // packed file date Bit32u curpos=0; diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index bb442481..55a9d7fe 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -126,6 +126,7 @@ public: switch (DriveManager::UnmountDrive(i_drive)) { case 0: Drives[i_drive] = 0; + mem_writeb(Real2Phys(dos.tables.mediaid)+i_drive*5,0); if(i_drive == DOS_GetDefaultDrive()) DOS_SetDrive(ZDRIVE_NUM); WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCESS"),umount[0]); @@ -394,7 +395,7 @@ public: if (!newdrive) E_Exit("DOS:Can't create drive"); Drives[drive-'A']=newdrive; /* Set the correct media byte in the table */ - mem_writeb(Real2Phys(dos.tables.mediaid)+(drive-'A')*2,newdrive->GetMediaByte()); + mem_writeb(Real2Phys(dos.tables.mediaid)+(drive-'A')*5,newdrive->GetMediaByte()); WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,newdrive->GetInfo()); /* check if volume label is given and don't allow it to updated in the future */ if (cmd->FindString("-label",label,true)) newdrive->dirCache.SetLabel(label.c_str(),iscdrom,false); @@ -1314,7 +1315,7 @@ public: DriveManager::InitializeDrive(drive - 'A'); // Set the correct media byte in the table - mem_writeb(Real2Phys(dos.tables.mediaid) + (drive - 'A') * 2, mediaid); + mem_writeb(Real2Phys(dos.tables.mediaid) + (drive - 'A') * 5, mediaid); /* Command uses dta so set it to our internal dta */ RealPt save_dta = dos.dta(); @@ -1392,7 +1393,7 @@ public: DriveManager::InitializeDrive(drive - 'A'); // Set the correct media byte in the table - mem_writeb(Real2Phys(dos.tables.mediaid) + (drive - 'A') * 2, mediaid); + mem_writeb(Real2Phys(dos.tables.mediaid) + (drive - 'A') * 5, mediaid); // Print status message (success) WriteOut(MSG_Get("MSCDEX_SUCCESS")); diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 4943593a..5579da44 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -73,10 +73,8 @@ static Bit8u country_info[0x22] = { void DOS_SetupTables(void) { Bit16u seg;Bitu i; - dos.tables.mediaid=RealMake(DOS_GetMemory(4),0); dos.tables.tempdta=RealMake(DOS_GetMemory(4),0); dos.tables.tempdta_fcbdelete=RealMake(DOS_GetMemory(4),0); - for (i=0;i Date: Wed, 13 Jun 2018 09:24:01 +0000 Subject: [PATCH 4026/4131] Add 64-bit ARM (ARMv8, little endian) by M-HT. Thanks M-HT! Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4117 --- configure.ac | 6 + src/cpu/core_dynrec.cpp | 3 + src/cpu/core_dynrec/Makefile.am | 2 +- src/cpu/core_dynrec/risc_armv8le.h | 1237 ++++++++++++++++++++++++++++ 4 files changed, 1247 insertions(+), 1 deletion(-) create mode 100644 src/cpu/core_dynrec/risc_armv8le.h diff --git a/configure.ac b/configure.ac index 3ecdddbc..230114eb 100644 --- a/configure.ac +++ b/configure.ac @@ -289,6 +289,12 @@ case "$host_cpu" in c_targetcpu="arm" dnl c_unalignedmemory=yes ;; + aarch64) + AC_DEFINE(C_TARGETCPU,ARMV8LE) + AC_MSG_RESULT(ARMv8 Little Endian 64-bit) + c_targetcpu="arm" + c_unalignedmemory=yes + ;; *) AC_DEFINE(C_TARGETCPU,UNKNOWN) AC_MSG_RESULT(unknown) diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index ff2881f8..22b9cff1 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -139,6 +139,7 @@ static struct { #define ARMV4LE 0x04 #define ARMV7LE 0x05 #define POWERPC 0x04 +#define ARMV8LE 0x07 #if C_TARGETCPU == X86_64 #include "core_dynrec/risc_x64.h" @@ -150,6 +151,8 @@ static struct { #include "core_dynrec/risc_armv4le.h" #elif C_TARGETCPU == POWERPC #include "core_dynrec/risc_ppc.h" +#elif C_TARGETCPU == ARMV8LE +#include "core_dynrec/risc_armv8le.h" #endif #include "core_dynrec/decoder.h" diff --git a/src/cpu/core_dynrec/Makefile.am b/src/cpu/core_dynrec/Makefile.am index 288b9154..f135543e 100644 --- a/src/cpu/core_dynrec/Makefile.am +++ b/src/cpu/core_dynrec/Makefile.am @@ -2,4 +2,4 @@ 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-o3.h risc_armv4le-thumb.h \ - risc_armv4le-thumb-iw.h risc_armv4le-thumb-niw.h + risc_armv4le-thumb-iw.h risc_armv4le-thumb-niw.h risc_armv8le.h diff --git a/src/cpu/core_dynrec/risc_armv8le.h b/src/cpu/core_dynrec/risc_armv8le.h new file mode 100644 index 00000000..62f3a60a --- /dev/null +++ b/src/cpu/core_dynrec/risc_armv8le.h @@ -0,0 +1,1237 @@ +/* + * Copyright (C) 2002-2018 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. + */ + + + +/* ARMv8 (little endian, 64-bit) backend by M-HT */ + + +// some configuring defines that specify the capabilities of this architecture +// or aspects of the recompiling + +// protect FC_ADDR over function calls if necessaray +// #define DRC_PROTECT_ADDR_REG + +// try to use non-flags generating functions if possible +#define DRC_FLAGS_INVALIDATION +// try to replace _simple functions by code +#define DRC_FLAGS_INVALIDATION_DCODE + +// type with the same size as a pointer +#define DRC_PTR_SIZE_IM Bit64u + +// calling convention modifier +#define DRC_CALL_CONV /* nothing */ +#define DRC_FC /* nothing */ + +// use FC_REGS_ADDR to hold the address of "cpu_regs" and to access it using FC_REGS_ADDR +#define DRC_USE_REGS_ADDR +// use FC_SEGS_ADDR to hold the address of "Segs" and to access it using FC_SEGS_ADDR +#define DRC_USE_SEGS_ADDR + +// register mapping +typedef Bit8u HostReg; + +// registers +#define HOST_r0 0 +#define HOST_r1 1 +#define HOST_r2 2 +#define HOST_r3 3 +#define HOST_r4 4 +#define HOST_r5 5 +#define HOST_r6 6 +#define HOST_r7 7 +#define HOST_r8 8 +#define HOST_r9 9 +#define HOST_r10 10 +#define HOST_r11 11 +#define HOST_r12 12 +#define HOST_r13 13 +#define HOST_r14 14 +#define HOST_r15 15 +#define HOST_r16 16 +#define HOST_r17 17 +#define HOST_r18 18 +#define HOST_r19 19 +#define HOST_r20 20 +#define HOST_r21 21 +#define HOST_r22 22 +#define HOST_r23 23 +#define HOST_r24 24 +#define HOST_r25 25 +#define HOST_r26 26 +#define HOST_r27 27 +#define HOST_r28 28 +#define HOST_r29 29 +#define HOST_r30 30 +// special registers +#define HOST_sp 31 +#define HOST_zr 31 + +// register aliases +// 32-bit registers +#define HOST_w0 HOST_r0 +#define HOST_w1 HOST_r1 +#define HOST_w2 HOST_r2 +#define HOST_w3 HOST_r3 +#define HOST_w4 HOST_r4 +#define HOST_w5 HOST_r5 +#define HOST_w6 HOST_r6 +#define HOST_w7 HOST_r7 +#define HOST_w8 HOST_r8 +#define HOST_w9 HOST_r9 +#define HOST_w10 HOST_r10 +#define HOST_w11 HOST_r11 +#define HOST_w12 HOST_r12 +#define HOST_w13 HOST_r13 +#define HOST_w14 HOST_r14 +#define HOST_w15 HOST_r15 +#define HOST_w16 HOST_r16 +#define HOST_w17 HOST_r17 +#define HOST_w18 HOST_r18 +#define HOST_w19 HOST_r19 +#define HOST_w20 HOST_r20 +#define HOST_w21 HOST_r21 +#define HOST_w22 HOST_r22 +#define HOST_w23 HOST_r23 +#define HOST_w24 HOST_r24 +#define HOST_w25 HOST_r25 +#define HOST_w26 HOST_r26 +#define HOST_w27 HOST_r27 +#define HOST_w28 HOST_r28 +#define HOST_w29 HOST_r29 +#define HOST_w30 HOST_r30 +#define HOST_wsp HOST_sp +#define HOST_wzr HOST_zr +// 64-bit registers +#define HOST_x0 HOST_r0 +#define HOST_x1 HOST_r1 +#define HOST_x2 HOST_r2 +#define HOST_x3 HOST_r3 +#define HOST_x4 HOST_r4 +#define HOST_x5 HOST_r5 +#define HOST_x6 HOST_r6 +#define HOST_x7 HOST_r7 +#define HOST_x8 HOST_r8 +#define HOST_x9 HOST_r9 +#define HOST_x10 HOST_r10 +#define HOST_x11 HOST_r11 +#define HOST_x12 HOST_r12 +#define HOST_x13 HOST_r13 +#define HOST_x14 HOST_r14 +#define HOST_x15 HOST_r15 +#define HOST_x16 HOST_r16 +#define HOST_x17 HOST_r17 +#define HOST_x18 HOST_r18 +#define HOST_x19 HOST_r19 +#define HOST_x20 HOST_r20 +#define HOST_x21 HOST_r21 +#define HOST_x22 HOST_r22 +#define HOST_x23 HOST_r23 +#define HOST_x24 HOST_r24 +#define HOST_x25 HOST_r25 +#define HOST_x26 HOST_r26 +#define HOST_x27 HOST_r27 +#define HOST_x28 HOST_r28 +#define HOST_x29 HOST_r29 +#define HOST_x30 HOST_r30 +#define HOST_xzr HOST_zr +#define HOST_ip0 HOST_r16 +#define HOST_ip1 HOST_r17 +#define HOST_fp HOST_r29 +#define HOST_lr HOST_r30 + + +// temporary registers +#define temp1 HOST_r10 +#define temp2 HOST_r11 +#define temp3 HOST_r12 + +// register that holds function return values +#define FC_RETOP HOST_r0 + +// register used for address calculations, +#define FC_ADDR HOST_r19 // has to be saved across calls, see DRC_PROTECT_ADDR_REG + +// register that holds the first parameter +#define FC_OP1 HOST_r0 + +// register that holds the second parameter +#define FC_OP2 HOST_r1 + +// special register that holds the third parameter for _R3 calls (byte accessible) +#define FC_OP3 HOST_r2 + +// register that holds byte-accessible temporary values +#define FC_TMP_BA1 HOST_r0 + +// register that holds byte-accessible temporary values +#define FC_TMP_BA2 HOST_r1 + +// temporary register for LEA +#define TEMP_REG_DRC HOST_r9 + +// used to hold the address of "cpu_regs" - preferably filled in function gen_run_code +#define FC_REGS_ADDR HOST_r20 + +// used to hold the address of "Segs" - preferably filled in function gen_run_code +#define FC_SEGS_ADDR HOST_r21 + +// used to hold the address of "core_dynrec.readdata" - filled in function gen_run_code +#define readdata_addr HOST_r22 + + +// instruction encodings + +// move +// mov dst, src, lsl #imm +#define MOV_REG_LSL_IMM(dst, src, imm) ORR_REG_LSL_IMM(dst, HOST_wzr, src, imm) +// movz dst, #(imm lsl simm) @ 0 <= imm <= 65535 & simm = 0/16 +#define MOVZ(dst, imm, simm) (0x52800000 + (dst) + ((imm) << 5) + ((simm)?0x00200000:0) ) +// movn dst, #(imm lsl simm) @ 0 <= imm <= 65535 & simm = 0/16 +#define MOVN(dst, imm, simm) (0x12800000 + (dst) + ((imm) << 5) + ((simm)?0x00200000:0) ) +// movk dst, #(imm lsl simm) @ 0 <= imm <= 65535 & simm = 0/16 +#define MOVK(dst, imm, simm) (0x72800000 + (dst) + ((imm) << 5) + ((simm)?0x00200000:0) ) +// movz dst, #(imm lsl simm) @ 0 <= imm <= 65535 & simm = 0/16/32/48 +#define MOVZ64(dst, imm, simm) (0xd2800000 + (dst) + ((imm) << 5) + (((simm) >> 4) << 21) ) +// movk dst, #(imm lsl simm) @ 0 <= imm <= 65535 & simm = 0/16/32/48 +#define MOVK64(dst, imm, simm) (0xf2800000 + (dst) + ((imm) << 5) + (((simm) >> 4) << 21) ) +// lslv dst, src, rreg +#define LSLV(dst, src, rreg) (0x1ac02000 + (dst) + ((src) << 5) + ((rreg) << 16) ) +// lsrv dst, src, rreg +#define LSRV(dst, src, rreg) (0x1ac02400 + (dst) + ((src) << 5) + ((rreg) << 16) ) +// asrv dst, src, rreg +#define ASRV(dst, src, rreg) (0x1ac02800 + (dst) + ((src) << 5) + ((rreg) << 16) ) +// rorv dst, src, rreg +#define RORV(dst, src, rreg) (0x1ac02c00 + (dst) + ((src) << 5) + ((rreg) << 16) ) +// lslv dst, src, rreg +#define LSLV64(dst, src, rreg) (0x9ac02000 + (dst) + ((src) << 5) + ((rreg) << 16) ) +// lsrv dst, src, rreg +#define LSRV64(dst, src, rreg) (0x9ac02400 + (dst) + ((src) << 5) + ((rreg) << 16) ) +// lsr dst, src, #imm +#define LSR64_IMM(dst, src, imm) UBFM64(dst, src, imm, 63) + +// arithmetic +// add dst, src, #(imm lsl simm) @ 0 <= imm <= 4095 & simm = 0/12 +#define ADD_IMM(dst, src, imm, simm) (0x11000000 + (dst) + ((src) << 5) + ((imm) << 10) + ((simm)?0x00400000:0) ) +// add dst, src1, src2, lsl #imm +#define ADD_REG_LSL_IMM(dst, src1, src2, imm) (0x0b000000 + (dst) + ((src1) << 5) + ((src2) << 16) + ((imm) << 10) ) +// sub dst, src, #(imm lsl simm) @ 0 <= imm <= 4095 & simm = 0/12 +#define SUB_IMM(dst, src, imm, simm) (0x51000000 + (dst) + ((src) << 5) + ((imm) << 10) + ((simm)?0x00400000:0) ) +// sub dst, src1, src2, lsl #imm +#define SUB_REG_LSL_IMM(dst, src1, src2, imm) (0x4b000000 + (dst) + ((src1) << 5) + ((src2) << 16) + ((imm) << 10) ) +// cmp src, #(imm lsl simm) @ 0 <= imm <= 4095 & simm = 0/12 +#define CMP_IMM(src, imm, simm) (0x7100001f + ((src) << 5) + ((imm) << 10) + ((simm)?0x00400000:0) ) +// nop +#define NOP (0xd503201f) + +// logical +// and dst, src1, src2, lsl #imm @ 0 <= imm <= 31 +#define AND_REG_LSL_IMM(dst, src1, src2, imm) (0x0a000000 + (dst) + ((src1) << 5) + ((src2) << 16) + ((imm) << 10) ) +// orr dst, src1, src2, lsl #imm @ 0 <= imm <= 31 +#define ORR_REG_LSL_IMM(dst, src1, src2, imm) (0x2a000000 + (dst) + ((src1) << 5) + ((src2) << 16) + ((imm) << 10) ) +// eor dst, src1, src2, lsl #imm @ 0 <= imm <= 31 +#define EOR_REG_LSL_IMM(dst, src1, src2, imm) (0x4a000000 + (dst) + ((src1) << 5) + ((src2) << 16) + ((imm) << 10) ) +// bic dst, src1, src2, lsl #imm @ 0 <= imm <= 31 +#define BIC_REG_LSL_IMM(dst, src1, src2, imm) (0x0a200000 + (dst) + ((src1) << 5) + ((src2) << 16) + ((imm) << 10) ) +// and dst, src1, src2, lsl #imm @ 0 <= imm <= 63 +#define AND64_REG_LSL_IMM(dst, src1, src2, imm) (0x8a000000 + (dst) + ((src1) << 5) + ((src2) << 16) + ((imm) << 10) ) + +// load +// ldr reg, [pc, #imm] @ -1M <= imm < 1M & imm mod 4 = 0 +#define LDR64_PC(reg, imm) (0x58000000 + (reg) + (((imm) << 3) & 0x00ffffe0) ) +// ldp reg1, reg2 [addr, #imm] @ -512 <= imm < 512 & imm mod 8 = 0 +#define LDP64_IMM(reg1, reg2, addr, imm) (0xa9400000 + (reg1) + ((reg2) << 10) + ((addr) << 5) + ((imm) << 12) ) +// ldr reg, [addr, #imm] @ 0 <= imm < 32768 & imm mod 8 = 0 +#define LDR64_IMM(reg, addr, imm) (0xf9400000 + (reg) + ((addr) << 5) + ((imm) << 7) ) +// ldr reg, [addr, #imm] @ 0 <= imm < 16384 & imm mod 4 = 0 +#define LDR_IMM(reg, addr, imm) (0xb9400000 + (reg) + ((addr) << 5) + ((imm) << 8) ) +// ldrh reg, [addr, #imm] @ 0 <= imm < 8192 & imm mod 2 = 0 +#define LDRH_IMM(reg, addr, imm) (0x79400000 + (reg) + ((addr) << 5) + ((imm) << 9) ) +// ldrb reg, [addr, #imm] @ 0 <= imm < 4096 +#define LDRB_IMM(reg, addr, imm) (0x39400000 + (reg) + ((addr) << 5) + ((imm) << 10) ) +// ldr reg, [addr1, addr2, lsl #imm] @ imm = 0/2 +#define LDR64_REG_LSL_IMM(reg, addr1, addr2, imm) (0xf8606800 + (reg) + ((addr1) << 5) + ((addr2) << 16) + ((imm)?0x00001000:0) ) +// ldur reg, [addr, #imm] @ -256 <= imm < 256 +#define LDUR64_IMM(reg, addr, imm) (0xf8400000 + (reg) + ((addr) << 5) + (((imm) << 12) & 0x001ff000) ) +// ldur reg, [addr, #imm] @ -256 <= imm < 256 +#define LDUR_IMM(reg, addr, imm) (0xb8400000 + (reg) + ((addr) << 5) + (((imm) << 12) & 0x001ff000) ) +// ldurh reg, [addr, #imm] @ -256 <= imm < 256 +#define LDURH_IMM(reg, addr, imm) (0x78400000 + (reg) + ((addr) << 5) + (((imm) << 12) & 0x001ff000) ) +// ldurb reg, [addr, #imm] @ -256 <= imm < 256 +#define LDURB_IMM(reg, addr, imm) (0x38400000 + (reg) + ((addr) << 5) + (((imm) << 12) & 0x001ff000) ) + +// store +// stp reg1, reg2 [addr, #imm] @ -512 <= imm < 512 & imm mod 8 = 0 +#define STP64_IMM(reg1, reg2, addr, imm) (0xa9000000 + (reg1) + ((reg2) << 10) + ((addr) << 5) + ((imm) << 12) ) +// str reg, [addr, #imm] @ 0 <= imm < 32768 & imm mod 8 = 0 +#define STR64_IMM(reg, addr, imm) (0xf9000000 + (reg) + ((addr) << 5) + ((imm) << 7) ) +// str reg, [addr, #imm] @ 0 <= imm < 16384 & imm mod 4 = 0 +#define STR_IMM(reg, addr, imm) (0xb9000000 + (reg) + ((addr) << 5) + ((imm) << 8) ) +// strh reg, [addr, #imm] @ 0 <= imm < 8192 & imm mod 2 = 0 +#define STRH_IMM(reg, addr, imm) (0x79000000 + (reg) + ((addr) << 5) + ((imm) << 9) ) +// strb reg, [addr, #imm] @ 0 <= imm < 4096 +#define STRB_IMM(reg, addr, imm) (0x39000000 + (reg) + ((addr) << 5) + ((imm) << 10) ) +// stur reg, [addr, #imm] @ -256 <= imm < 256 +#define STUR64_IMM(reg, addr, imm) (0xf8000000 + (reg) + ((addr) << 5) + (((imm) << 12) & 0x001ff000) ) +// stur reg, [addr, #imm] @ -256 <= imm < 256 +#define STUR_IMM(reg, addr, imm) (0xb8000000 + (reg) + ((addr) << 5) + (((imm) << 12) & 0x001ff000) ) +// sturh reg, [addr, #imm] @ -256 <= imm < 256 +#define STURH_IMM(reg, addr, imm) (0x78000000 + (reg) + ((addr) << 5) + (((imm) << 12) & 0x001ff000) ) +// sturb reg, [addr, #imm] @ -256 <= imm < 256 +#define STURB_IMM(reg, addr, imm) (0x38000000 + (reg) + ((addr) << 5) + (((imm) << 12) & 0x001ff000) ) + +// branch +// bgt pc+imm @ 0 <= imm < 1M & imm mod 4 = 0 +#define BGT_FWD(imm) (0x5400000c + ((imm) << 3) ) +// b pc+imm @ 0 <= imm < 128M & imm mod 4 = 0 +#define B_FWD(imm) (0x14000000 + ((imm) >> 2) ) +// br reg +#define BR(reg) (0xd61f0000 + ((reg) << 5) ) +// blr reg +#define BLR_REG(reg) (0xd63f0000 + ((reg) << 5) ) +// cbz reg, pc+imm @ 0 <= imm < 1M & imm mod 4 = 0 +#define CBZ_FWD(reg, imm) (0x34000000 + (reg) + ((imm) << 3) ) +// cbnz reg, pc+imm @ 0 <= imm < 1M & imm mod 4 = 0 +#define CBNZ_FWD(reg, imm) (0x35000000 + (reg) + ((imm) << 3) ) +// ret reg +#define RET_REG(reg) (0xd65f0000 + ((reg) << 5) ) +// ret +#define RET RET_REG(HOST_x30) + +// extend +// sxth dst, src +#define SXTH(dst, src) SBFM(dst, src, 0, 15) +// sxtb dst, src +#define SXTB(dst, src) SBFM(dst, src, 0, 7) +// uxth dst, src +#define UXTH(dst, src) UBFM(dst, src, 0, 15) +// uxtb dst, src +#define UXTB(dst, src) UBFM(dst, src, 0, 7) + +// bit field +// bfi dst, src, #lsb, #width @ lsb >= 0, width >= 1, lsb+width <= 32 +#define BFI(dst, src, lsb, width) BFM(dst, src, (32 - (lsb)) & 0x1f, (width) - 1) +// bfm dst, src, #rimm, #simm @ 0 <= rimm < 32, 0 <= simm < 32 +#define BFM(dst, src, rimm, simm) (0x33000000 + (dst) + ((src) << 5) + ((rimm) << 16) + ((simm) << 10) ) +// sbfm dst, src, #rimm, #simm @ 0 <= rimm < 32, 0 <= simm < 32 +#define SBFM(dst, src, rimm, simm) (0x13000000 + (dst) + ((src) << 5) + ((rimm) << 16) + ((simm) << 10) ) +// ubfm dst, src, #rimm, #simm @ 0 <= rimm < 32, 0 <= simm < 32 +#define UBFM(dst, src, rimm, simm) (0x53000000 + (dst) + ((src) << 5) + ((rimm) << 16) + ((simm) << 10) ) +// bfi dst, src, #lsb, #width @ lsb >= 0, width >= 1, lsb+width <= 64 +#define BFI64(dst, src, lsb, width) BFM64(dst, src, (64 - (lsb)) & 0x3f, (width) - 1) +// bfm dst, src, #rimm, #simm @ 0 <= rimm < 64, 0 <= simm < 64 +#define BFM64(dst, src, rimm, simm) (0xb3400000 + (dst) + ((src) << 5) + ((rimm) << 16) + ((simm) << 10) ) +// ubfm dst, src, #rimm, #simm @ 0 <= rimm < 64, 0 <= simm < 64 +#define UBFM64(dst, src, rimm, simm) (0xd3400000 + (dst) + ((src) << 5) + ((rimm) << 16) + ((simm) << 10) ) + + +// move a full register from reg_src to reg_dst +static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { + if(reg_src == reg_dst) return; + cache_addd( MOV_REG_LSL_IMM(reg_dst, reg_src, 0) ); // mov reg_dst, reg_src +} + +// move a 32bit constant value into dest_reg +static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { + if ( (imm & 0xffff0000) == 0 ) { + cache_addd( MOVZ(dest_reg, imm, 0) ); // movz dest_reg, #imm + } else if ( (imm & 0x0000ffff) == 0 ) { + cache_addd( MOVZ(dest_reg, imm >> 16, 16) ); // movz dest_reg, #(imm >> 16), lsl #16 + } else if ( ((~imm) & 0xffff0000) == 0 ) { + cache_addd( MOVN(dest_reg, ~imm, 0) ); // movn dest_reg, #(~imm) + } else if ( ((~imm) & 0x0000ffff) == 0 ) { + cache_addd( MOVN(dest_reg, (~imm) >> 16, 16) ); // movn dest_reg, #(~imm >> 16), lsl #16 + } else { + cache_addd( MOVZ(dest_reg, imm & 0xffff, 0) ); // movz dest_reg, #(imm & 0xffff) + cache_addd( MOVK(dest_reg, imm >> 16, 16) ); // movk dest_reg, #(imm >> 16), lsl #16 + } +} + +// helper function +static bool gen_mov_memval_to_reg_helper(HostReg dest_reg, Bit64u data, Bitu size, HostReg addr_reg, Bit64u addr_data) { + switch (size) { + case 8: + if (((data & 7) == 0) && (data >= addr_data) && (data < addr_data + 32768)) { + cache_addd( LDR64_IMM(dest_reg, addr_reg, data - addr_data) ); // ldr dest_reg, [addr_reg, #(data - addr_data)] + return true; + } else if ((data < addr_data + 256) && (data >= addr_data - 256)) { + cache_addd( LDUR64_IMM(dest_reg, addr_reg, data - addr_data) ); // ldur dest_reg, [addr_reg, #(data - addr_data)] + return true; + } + break; + case 4: + if (((data & 3) == 0) && (data >= addr_data) && (data < addr_data + 16384)) { + cache_addd( LDR_IMM(dest_reg, addr_reg, data - addr_data) ); // ldr dest_reg, [addr_reg, #(data - addr_data)] + return true; + } else if ((data < addr_data + 256) && (data >= addr_data - 256)) { + cache_addd( LDUR_IMM(dest_reg, addr_reg, data - addr_data) ); // ldur dest_reg, [addr_reg, #(data - addr_data)] + return true; + } + break; + case 2: + if (((data & 1) == 0) && (data >= addr_data) && (data < addr_data + 8192)) { + cache_addd( LDRH_IMM(dest_reg, addr_reg, data - addr_data) ); // ldrh dest_reg, [addr_reg, #(data - addr_data)] + return true; + } else if ((data < addr_data + 256) && (data >= addr_data - 256)) { + cache_addd( LDURH_IMM(dest_reg, addr_reg, data - addr_data) ); // ldurh dest_reg, [addr_reg, #(data - addr_data)] + return true; + } + break; + case 1: + if ((data >= addr_data) && (data < addr_data + 4096)) { + cache_addd( LDRB_IMM(dest_reg, addr_reg, data - addr_data) ); // ldrb dest_reg, [addr_reg, #(data - addr_data)] + return true; + } else if ((data < addr_data) && (data >= addr_data - 256)) { + cache_addd( LDURB_IMM(dest_reg, addr_reg, data - addr_data) ); // ldurb dest_reg, [addr_reg, #(data - addr_data)] + return true; + } + default: + break; + } + return false; +} + +// helper function +static bool gen_mov_memval_to_reg(HostReg dest_reg, void *data, Bitu size) { + if (gen_mov_memval_to_reg_helper(dest_reg, (Bit64u)data, size, FC_REGS_ADDR, (Bit64u)&cpu_regs)) return true; + if (gen_mov_memval_to_reg_helper(dest_reg, (Bit64u)data, size, readdata_addr, (Bit64u)&core_dynrec.readdata)) return true; + if (gen_mov_memval_to_reg_helper(dest_reg, (Bit64u)data, size, FC_SEGS_ADDR, (Bit64u)&Segs)) return true; + return false; +} + +// helper function - move a 64bit constant value into dest_reg +static void gen_mov_qword_to_reg_imm(HostReg dest_reg,Bit64u imm) { + bool isfirst = true; + + if ( (imm & 0xffff) != 0 ) { + cache_addd( MOVZ64(dest_reg, imm & 0xffff, 0) ); // movz dest_reg, #(imm & 0xffff) + isfirst = false; + } + if ( ((imm >> 16) & 0xffff) != 0 ) { + if (isfirst) { + isfirst = false; + cache_addd( MOVZ64(dest_reg, (imm >> 16) & 0xffff, 16) ); // movz dest_reg, #((imm >> 16) & 0xffff), lsl #16 + } else { + cache_addd( MOVK64(dest_reg, (imm >> 16) & 0xffff, 16) ); // movk dest_reg, #((imm >> 16) & 0xffff), lsl #16 + } + } + if ( ((imm >> 32) & 0xffff) != 0 ) { + if (isfirst) { + isfirst = false; + cache_addd( MOVZ64(dest_reg, (imm >> 32) & 0xffff, 32) ); // movz dest_reg, #((imm >> 32) & 0xffff), lsl #32 + } else { + cache_addd( MOVK64(dest_reg, (imm >> 32) & 0xffff, 32) ); // movk dest_reg, #((imm >> 32) & 0xffff), lsl #32 + } + } + if ( ((imm >> 48) & 0xffff) != 0 ) { + if (isfirst) { + isfirst = false; + cache_addd( MOVZ64(dest_reg, (imm >> 48) & 0xffff, 48) ); // movz dest_reg, #((imm >> 48) & 0xffff), lsl #48 + } else { + cache_addd( MOVK64(dest_reg, (imm >> 48) & 0xffff, 48) ); // movk dest_reg, #((imm >> 48) & 0xffff), lsl #48 + } + } + if (isfirst) { + cache_addd( MOVZ64(dest_reg, 0, 0) ); // movz dest_reg, #0 + } +} + +// helper function for gen_mov_word_to_reg +static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,HostReg data_reg) { + if (dword) { + cache_addd( LDR_IMM(dest_reg, data_reg, 0) ); // ldr dest_reg, [data_reg] + } else { + cache_addd( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] + } +} + +// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { + if (!gen_mov_memval_to_reg(dest_reg, data, (dword)?4:2)) { + gen_mov_qword_to_reg_imm(temp1, (Bit64u)data); + gen_mov_word_to_reg_helper(dest_reg, data, dword, temp1); + } +} + +// move a 16bit constant value into dest_reg +// the upper 16bit of the destination register may be destroyed +static void INLINE gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { + cache_addd( MOVZ(dest_reg, imm, 0) ); // movz dest_reg, #imm +} + +// helper function +static bool gen_mov_memval_from_reg_helper(HostReg src_reg, Bit64u data, Bitu size, HostReg addr_reg, Bit64u addr_data) { + switch (size) { + case 8: + if (((data & 7) == 0) && (data >= addr_data) && (data < addr_data + 32768)) { + cache_addd( STR64_IMM(src_reg, addr_reg, data - addr_data) ); // str src_reg, [addr_reg, #(data - addr_data)] + return true; + } else if ((data < addr_data + 256) && (data >= addr_data - 256)) { + cache_addd( STUR64_IMM(src_reg, addr_reg, data - addr_data) ); // stur src_reg, [addr_reg, #(data - addr_data)] + return true; + } + break; + case 4: + if (((data & 3) == 0) && (data >= addr_data) && (data < addr_data + 16384)) { + cache_addd( STR_IMM(src_reg, addr_reg, data - addr_data) ); // str src_reg, [addr_reg, #(data - addr_data)] + return true; + } else if ((data < addr_data + 256) && (data >= addr_data - 256)) { + cache_addd( STUR_IMM(src_reg, addr_reg, data - addr_data) ); // stur src_reg, [addr_reg, #(data - addr_data)] + return true; + } + break; + case 2: + if (((data & 1) == 0) && (data >= addr_data) && (data < addr_data + 8192)) { + cache_addd( STRH_IMM(src_reg, addr_reg, data - addr_data) ); // strh src_reg, [addr_reg, #(data - addr_data)] + return true; + } else if ((data < addr_data + 256) && (data >= addr_data - 256)) { + cache_addd( STURH_IMM(src_reg, addr_reg, data - addr_data) ); // sturh src_reg, [addr_reg, #(data - addr_data)] + return true; + } + break; + case 1: + if ((data >= addr_data) && (data < addr_data + 4096)) { + cache_addd( STRB_IMM(src_reg, addr_reg, data - addr_data) ); // strb src_reg, [addr_reg, #(data - addr_data)] + return true; + } else if ((data < addr_data) && (data >= addr_data - 256)) { + cache_addd( STURB_IMM(src_reg, addr_reg, data - addr_data) ); // sturb src_reg, [addr_reg, #(data - addr_data)] + return true; + } + default: + break; + } + return false; +} + +// helper function +static bool gen_mov_memval_from_reg(HostReg src_reg, void *dest, Bitu size) { + if (gen_mov_memval_from_reg_helper(src_reg, (Bit64u)dest, size, FC_REGS_ADDR, (Bit64u)&cpu_regs)) return true; + if (gen_mov_memval_from_reg_helper(src_reg, (Bit64u)dest, size, readdata_addr, (Bit64u)&core_dynrec.readdata)) return true; + if (gen_mov_memval_from_reg_helper(src_reg, (Bit64u)dest, size, FC_SEGS_ADDR, (Bit64u)&Segs)) return true; + return false; +} + +// helper function for gen_mov_word_from_reg +static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, HostReg data_reg) { + if (dword) { + cache_addd( STR_IMM(src_reg, data_reg, 0) ); // str src_reg, [data_reg] + } else { + cache_addd( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] + } +} + +// move 32bit (dword==true) or 16bit (dword==false) of a register into memory +static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { + if (!gen_mov_memval_from_reg(src_reg, dest, (dword)?4:2)) { + gen_mov_qword_to_reg_imm(temp1, (Bit64u)dest); + gen_mov_word_from_reg_helper(src_reg, dest, dword, temp1); + } +} + +// move an 8bit value from memory into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { + if (!gen_mov_memval_to_reg(dest_reg, data, 1)) { + gen_mov_qword_to_reg_imm(temp1, (Bit64u)data); + cache_addd( LDRB_IMM(dest_reg, temp1, 0) ); // ldrb dest_reg, [temp1] + } +} + +// move an 8bit value from memory into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { + gen_mov_byte_to_reg_low(dest_reg, data); +} + +// move an 8bit constant value into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { + cache_addd( MOVZ(dest_reg, imm, 0) ); // movz dest_reg, #imm +} + +// move an 8bit constant value into dest_reg +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { + gen_mov_byte_to_reg_low_imm(dest_reg, imm); +} + +// move the lowest 8bit of a register into memory +static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { + if (!gen_mov_memval_from_reg(src_reg, dest, 1)) { + gen_mov_qword_to_reg_imm(temp1, (Bit64u)dest); + cache_addd( STRB_IMM(src_reg, temp1, 0) ); // strb src_reg, [temp1] + } +} + + + +// convert an 8bit word to a 32bit dword +// the register is zero-extended (sign==false) or sign-extended (sign==true) +static void gen_extend_byte(bool sign,HostReg reg) { + if (sign) { + cache_addd( SXTB(reg, reg) ); // sxtb reg, reg + } else { + cache_addd( UXTB(reg, reg) ); // uxtb reg, reg + } +} + +// convert a 16bit word to a 32bit dword +// the register is zero-extended (sign==false) or sign-extended (sign==true) +static void gen_extend_word(bool sign,HostReg reg) { + if (sign) { + cache_addd( SXTH(reg, reg) ); // sxth reg, reg + } else { + cache_addd( UXTH(reg, reg) ); // uxth reg, reg + } +} + +// add a 32bit value from memory to a full register +static void gen_add(HostReg reg,void* op) { + gen_mov_word_to_reg(temp3, op, 1); + cache_addd( ADD_REG_LSL_IMM(reg, reg, temp3, 0) ); // add reg, reg, temp3 +} + +// add a 32bit constant value to a full register +static void gen_add_imm(HostReg reg,Bit32u imm) { + Bit32u imm2; + + if(!imm) return; + + imm2 = (Bit32u) (-((Bit32s)imm)); + + if (imm < 4096) { + cache_addd( ADD_IMM(reg, reg, imm, 0) ); // add reg, reg, #imm + } else if ((imm & 0xff000fff) == 0) { + cache_addd( ADD_IMM(reg, reg, imm >> 12, 12) ); // add reg, reg, #(imm >> 12), lsl #12 + } else if (imm2 < 4096) { + cache_addd( SUB_IMM(reg, reg, imm2, 0) ); // sub reg, reg, #(-imm) + } else if ((imm2 & 0xff000fff) == 0) { + cache_addd( SUB_IMM(reg, reg, imm2 >> 12, 12) ); // sub reg, reg, #(-imm >> 12), lsl #12 + } else if (imm2 < 0x10000) { + cache_addd( MOVZ(temp2, imm2, 0) ); // movz temp2, #(-imm) + cache_addd( SUB_REG_LSL_IMM(reg, reg, temp2, 0) ); // sub reg, reg, temp2 + } else { + gen_mov_dword_to_reg_imm(temp2, imm); + cache_addd( ADD_REG_LSL_IMM(reg, reg, temp2, 0) ); // add reg, reg, temp2 + } +} + +// and a 32bit constant value with a full register +static void gen_and_imm(HostReg reg,Bit32u imm) { + Bit32u imm2, scale; + + imm2 = ~imm; + if(!imm2) return; + + if (!imm) { + cache_addd( MOVZ(reg, 0, 0) ); // movz reg, #0 + } else if (imm2 < 0x10000) { + cache_addd( MOVZ(temp2, imm2, 0) ); // movz temp2, #(~imm) + cache_addd( BIC_REG_LSL_IMM(reg, reg, temp2, 0) ); // bic reg, reg, temp2 + } else if ((imm2 & 0xffff) == 0) { + cache_addd( MOVZ(temp2, imm2 >> 16, 16) ); // movz temp2, #(~imm >> 16), lsl #16 + cache_addd( BIC_REG_LSL_IMM(reg, reg, temp2, 0) ); // bic reg, reg, temp2 + } else { + gen_mov_dword_to_reg_imm(temp2, imm); + cache_addd( AND_REG_LSL_IMM(reg, reg, temp2, 0) ); // and reg, reg, temp2 + } +} + + +// move a 32bit constant value into memory +static void gen_mov_direct_dword(void* dest,Bit32u imm) { + gen_mov_dword_to_reg_imm(temp3, imm); + gen_mov_word_from_reg(temp3, dest, 1); +} + +// move an address into memory +static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { + gen_mov_qword_to_reg_imm(temp3, imm); + if (!gen_mov_memval_from_reg(temp3, dest, 8)) { + gen_mov_qword_to_reg_imm(temp1, (Bit64u)dest); + cache_addd( STR64_IMM(temp3, temp1, 0) ); // str temp3, [temp1] + } +} + +// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value +static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { + if (!dword) imm &= 0xffff; + if(!imm) return; + + if (!gen_mov_memval_to_reg(temp3, dest, (dword)?4:2)) { + gen_mov_qword_to_reg_imm(temp1, (Bit64u)dest); + gen_mov_word_to_reg_helper(temp3, dest, dword, temp1); + } + gen_add_imm(temp3, imm); + if (!gen_mov_memval_from_reg(temp3, dest, (dword)?4:2)) { + gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); + } +} + +// add an 8bit constant value to a dword memory value +static void gen_add_direct_byte(void* dest,Bit8s imm) { + gen_add_direct_word(dest, (Bit32s)imm, 1); +} + +// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value +static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { + Bit32u imm2; + + if (!dword) imm &= 0xffff; + if(!imm) return; + + if (!gen_mov_memval_to_reg(temp3, dest, (dword)?4:2)) { + gen_mov_qword_to_reg_imm(temp1, (Bit64u)dest); + gen_mov_word_to_reg_helper(temp3, dest, dword, temp1); + } + + imm2 = (Bit32u) (-((Bit32s)imm)); + + if (imm < 4096) { + cache_addd( SUB_IMM(temp3, temp3, imm, 0) ); // sub temp3, temp3, #imm + } else if ((imm & 0xff000fff) == 0) { + cache_addd( SUB_IMM(temp3, temp3, imm >> 12, 12) ); // sub temp3, temp3, #(imm >> 12), lsl #12 + } else if (imm2 < 4096) { + cache_addd( ADD_IMM(temp3, temp3, imm2, 0) ); // add temp3, temp3, #(-imm) + } else if ((imm2 & 0xff000fff) == 0) { + cache_addd( ADD_IMM(temp3, temp3, imm2 >> 12, 12) ); // add temp3, temp3, #(-imm >> 12), lsl #12 + } else if (imm2 < 0x10000) { + cache_addd( MOVZ(temp2, imm2, 0) ); // movz temp2, #(-imm) + cache_addd( ADD_REG_LSL_IMM(temp3, temp3, temp2, 0) ); // add temp3, temp3, temp2 + } else { + gen_mov_dword_to_reg_imm(temp2, imm); + cache_addd( SUB_REG_LSL_IMM(temp3, temp3, temp2, 0) ); // sub temp3, temp3, temp2 + } + + if (!gen_mov_memval_from_reg(temp3, dest, (dword)?4:2)) { + gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); + } +} + +// subtract an 8bit constant value from a dword memory value +static void gen_sub_direct_byte(void* dest,Bit8s imm) { + gen_sub_direct_word(dest, (Bit32s)imm, 1); +} + +// effective address calculation, destination is dest_reg +// scale_reg is scaled by scale (scale_reg*(2^scale)) and +// added to dest_reg, then the immediate value is added +static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { + cache_addd( ADD_REG_LSL_IMM(dest_reg, dest_reg, scale_reg, scale) ); // add dest_reg, dest_reg, scale_reg, lsl #scale + gen_add_imm(dest_reg, imm); +} + +// effective address calculation, destination is dest_reg +// dest_reg is scaled by scale (dest_reg*(2^scale)), +// then the immediate value is added +static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { + if (scale) { + cache_addd( MOV_REG_LSL_IMM(dest_reg, dest_reg, scale) ); // mov dest_reg, dest_reg, lsl #scale + } + gen_add_imm(dest_reg, imm); +} + +// generate a call to a parameterless function +static void INLINE gen_call_function_raw(void * func) { + cache_addd( MOVZ64(temp1, ((Bit64u)func) & 0xffff, 0) ); // movz dest_reg, #(func & 0xffff) + cache_addd( MOVK64(temp1, (((Bit64u)func) >> 16) & 0xffff, 16) ); // movk dest_reg, #((func >> 16) & 0xffff), lsl #16 + cache_addd( MOVK64(temp1, (((Bit64u)func) >> 32) & 0xffff, 32) ); // movk dest_reg, #((func >> 32) & 0xffff), lsl #32 + cache_addd( MOVK64(temp1, (((Bit64u)func) >> 48) & 0xffff, 48) ); // movk dest_reg, #((func >> 48) & 0xffff), lsl #48 + cache_addd( BLR_REG(temp1) ); // blr temp1 +} + +// generate a call to a function with paramcount parameters +// note: the parameters are loaded in the architecture specific way +// using the gen_load_param_ functions below +static DRC_PTR_SIZE_IM INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { + DRC_PTR_SIZE_IM proc_addr = (DRC_PTR_SIZE_IM)cache.pos; + gen_call_function_raw(func); + return proc_addr; +} + +// load an immediate value as param'th function parameter +static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { + gen_mov_qword_to_reg_imm(param, imm); +} + +// load an address as param'th function parameter +static void INLINE gen_load_param_addr(DRC_PTR_SIZE_IM addr,Bitu param) { + gen_mov_qword_to_reg_imm(param, addr); +} + +// load a host-register as param'th function parameter +static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { + gen_mov_regs(param, reg); +} + +// load a value from memory as param'th function parameter +static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { + gen_mov_word_to_reg(param, (void *)mem, 1); +} + +// jump to an address pointed at by ptr, offset is in imm +static void gen_jmp_ptr(void * ptr,Bits imm=0) { + if (!gen_mov_memval_to_reg(temp3, ptr, 8)) { + gen_mov_qword_to_reg_imm(temp1, (Bit64u)ptr); + cache_addd( LDR64_IMM(temp3, temp1, 0) ); // ldr temp3, [temp1] + } + + if (((imm & 7) == 0) && (imm >= 0) && (imm < 32768)) { + cache_addd( LDR64_IMM(temp1, temp3, imm) ); // ldr temp1, [temp3, #imm] + } else if ((imm < 256) && (imm >= -256)) { + cache_addd( LDUR64_IMM(temp1, temp3, imm) ); // ldur temp1, [temp3, #imm] + } else { + gen_mov_qword_to_reg_imm(temp2, imm); + cache_addd( LDR64_REG_LSL_IMM(temp1, temp3, temp2, 0) ); // ldr temp1, [temp3, temp2] + } + + cache_addd( BR(temp1) ); // br temp1 +} + +// short conditional jump (+-127 bytes) if register is zero +// the destination is set by gen_fill_branch() later +static DRC_PTR_SIZE_IM gen_create_branch_on_zero(HostReg reg,bool dword) { + if (dword) { + cache_addd( CBZ_FWD(reg, 0) ); // cbz reg, j + } else { + cache_addd( UXTH(temp1, reg) ); // uxth temp1, reg + cache_addd( CBZ_FWD(temp1, 0) ); // cbz temp1, j + } + return ((DRC_PTR_SIZE_IM)cache.pos-4); +} + +// short conditional jump (+-127 bytes) if register is nonzero +// the destination is set by gen_fill_branch() later +static DRC_PTR_SIZE_IM gen_create_branch_on_nonzero(HostReg reg,bool dword) { + if (dword) { + cache_addd( CBNZ_FWD(reg, 0) ); // cbnz reg, j + } else { + cache_addd( UXTH(temp1, reg) ); // uxth temp1, reg + cache_addd( CBNZ_FWD(temp1, 0) ); // cbnz temp1, j + } + return ((DRC_PTR_SIZE_IM)cache.pos-4); +} + +// calculate relative offset and fill it into the location pointed to by data +static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) { +#if C_DEBUG + Bits len=(Bit64u)cache.pos-data; + if (len<0) len=-len; + if (len>=0x00100000) LOG_MSG("Big jump %d",len); +#endif + *(Bit32u*)data=( (*(Bit32u*)data) & 0xff00001f ) | ( ( ((Bit64u)cache.pos - data) << 3 ) & 0x00ffffe0 ); +} + +// conditional jump if register is nonzero +// for isdword==true the 32bit of the register are tested +// for isdword==false the lowest 8bit of the register are tested +static DRC_PTR_SIZE_IM gen_create_branch_long_nonzero(HostReg reg,bool isdword) { + if (isdword) { + cache_addd( CBZ_FWD(reg, 8) ); // cbz reg, pc+8 // skip next instruction + } else { + cache_addd( UXTB(temp1, reg) ); // uxtb temp1, reg + cache_addd( CBZ_FWD(temp1, 8) ); // cbz temp1, pc+8 // skip next instruction + } + cache_addd( B_FWD(0) ); // b j + return ((DRC_PTR_SIZE_IM)cache.pos-4); +} + +// compare 32bit-register against zero and jump if value less/equal than zero +static DRC_PTR_SIZE_IM gen_create_branch_long_leqzero(HostReg reg) { + cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 + cache_addd( BGT_FWD(8) ); // bgt pc+8 // skip next instruction + cache_addd( B_FWD(0) ); // b j + return ((DRC_PTR_SIZE_IM)cache.pos-4); +} + +// calculate long relative offset and fill it into the location pointed to by data +static void INLINE gen_fill_branch_long(DRC_PTR_SIZE_IM data) { + // optimize for shorter branches ? + *(Bit32u*)data=( (*(Bit32u*)data) & 0xfc000000 ) | ( ( ((Bit64u)cache.pos - data) >> 2 ) & 0x03ffffff ); +} + +static void gen_run_code(void) { + Bit8u *pos1, *pos2, *pos3; + + cache_addd( 0xa9bd7bfd ); // stp fp, lr, [sp, #-48]! + cache_addd( 0x910003fd ); // mov fp, sp + cache_addd( STP64_IMM(FC_ADDR, FC_REGS_ADDR, HOST_sp, 16) ); // stp FC_ADDR, FC_REGS_ADDR, [sp, #16] + cache_addd( STP64_IMM(FC_SEGS_ADDR, readdata_addr, HOST_sp, 32) ); // stp FC_SEGS_ADDR, readdata_addr, [sp, #32] + + pos1 = cache.pos; + cache_addd( 0 ); + pos2 = cache.pos; + cache_addd( 0 ); + pos3 = cache.pos; + cache_addd( 0 ); + + cache_addd( BR(HOST_x0) ); // br x0 + + // align cache.pos to 32 bytes + if ((((Bitu)cache.pos) & 0x1f) != 0) { + cache.pos = cache.pos + (32 - (((Bitu)cache.pos) & 0x1f)); + } + + *(Bit32u *)pos1 = LDR64_PC(FC_SEGS_ADDR, cache.pos - pos1); // ldr FC_SEGS_ADDR, [pc, #(&Segs)] + cache_addq((Bit64u)&Segs); // address of "Segs" + + *(Bit32u *)pos2 = LDR64_PC(FC_REGS_ADDR, cache.pos - pos2); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)] + cache_addq((Bit64u)&cpu_regs); // address of "cpu_regs" + + *(Bit32u *)pos3 = LDR64_PC(readdata_addr, cache.pos - pos3); // ldr readdata_addr, [pc, #(&core_dynrec.readdata)] + cache_addq((Bit64u)&core_dynrec.readdata); // address of "core_dynrec.readdata" + + // align cache.pos to 32 bytes + if ((((Bitu)cache.pos) & 0x1f) != 0) { + cache.pos = cache.pos + (32 - (((Bitu)cache.pos) & 0x1f)); + } +} + +// return from a function +static void gen_return_function(void) { + cache_addd( LDP64_IMM(FC_ADDR, FC_REGS_ADDR, HOST_sp, 16) ); // ldp FC_ADDR, FC_REGS_ADDR, [sp, #16] + cache_addd( LDP64_IMM(FC_SEGS_ADDR, readdata_addr, HOST_sp, 32) ); // ldp FC_SEGS_ADDR, readdata_addr, [sp, #32] + cache_addd( 0xa8c37bfd ); // ldp fp, lr, [sp], #48 + cache_addd( RET ); // ret +} + +#ifdef DRC_FLAGS_INVALIDATION + +// called when a call to a function can be replaced by a +// call to a simpler function +static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { +#ifdef DRC_FLAGS_INVALIDATION_DCODE + // try to avoid function calls but rather directly fill in code + switch (flags_type) { + case t_ADDb: + case t_ADDw: + case t_ADDd: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=ADD_REG_LSL_IMM(FC_RETOP, HOST_w0, HOST_w1, 0); // add FC_RETOP, w0, w1 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_ORb: + case t_ORw: + case t_ORd: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=ORR_REG_LSL_IMM(FC_RETOP, HOST_w0, HOST_w1, 0); // orr FC_RETOP, w0, w1 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_ANDb: + case t_ANDw: + case t_ANDd: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=AND_REG_LSL_IMM(FC_RETOP, HOST_w0, HOST_w1, 0); // and FC_RETOP, w0, w1 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_SUBb: + case t_SUBw: + case t_SUBd: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=SUB_REG_LSL_IMM(FC_RETOP, HOST_w0, HOST_w1, 0); // sub FC_RETOP, w0, w1 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_XORb: + case t_XORw: + case t_XORd: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=EOR_REG_LSL_IMM(FC_RETOP, HOST_w0, HOST_w1, 0); // eor FC_RETOP, w0, w1 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_CMPb: + case t_CMPw: + case t_CMPd: + case t_TESTb: + case t_TESTw: + case t_TESTd: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_INCb: + case t_INCw: + case t_INCd: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=ADD_IMM(FC_RETOP, HOST_w0, 1, 0); // add FC_RETOP, w0, #1 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_DECb: + case t_DECw: + case t_DECd: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=SUB_IMM(FC_RETOP, HOST_w0, 1, 0); // sub FC_RETOP, w0, #1 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_SHLb: + case t_SHLw: + case t_SHLd: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=LSLV(FC_RETOP, HOST_w0, HOST_w1); // lslv FC_RETOP, w0, w1 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_SHRb: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=UXTB(FC_RETOP, HOST_w0); // uxtb FC_RETOP, w0 + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=LSRV(FC_RETOP, FC_RETOP, HOST_w1); // lsrv FC_RETOP, FC_RETOP, w1 + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_SHRw: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=UXTH(FC_RETOP, HOST_w0); // uxth FC_RETOP, w0 + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=LSRV(FC_RETOP, FC_RETOP, HOST_w1); // lsrv FC_RETOP, FC_RETOP, w1 + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_SHRd: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=LSRV(FC_RETOP, HOST_w0, HOST_w1); // lsrv FC_RETOP, w0, w1 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_SARb: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=SXTB(FC_RETOP, HOST_w0); // sxtb FC_RETOP, w0 + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=ASRV(FC_RETOP, FC_RETOP, HOST_w1); // asrv FC_RETOP, FC_RETOP, w1 + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_SARw: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=SXTH(FC_RETOP, HOST_w0); // sxth FC_RETOP, w0 + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=ASRV(FC_RETOP, FC_RETOP, HOST_w1); // asrv FC_RETOP, FC_RETOP, w1 + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_SARd: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=ASRV(FC_RETOP, HOST_w0, HOST_w1); // asrv FC_RETOP, w0, w1 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_RORb: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=BFI(HOST_w0, HOST_w0, 8, 8); // bfi w0, w0, 8, 8 + *(Bit32u*)(pos+8)=BFI(HOST_w0, HOST_w0, 16, 16); // bfi w0, w0, 16, 16 + *(Bit32u*)(pos+12)=RORV(FC_RETOP, HOST_w0, HOST_w1); // rorv FC_RETOP, w0, w1 + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_RORw: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=BFI(HOST_w0, HOST_w0, 16, 16); // bfi w0, w0, 16, 16 + *(Bit32u*)(pos+8)=NOP; // nop + *(Bit32u*)(pos+12)=RORV(FC_RETOP, HOST_w0, HOST_w1); // rorv FC_RETOP, w0, w1 + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_RORd: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=RORV(FC_RETOP, HOST_w0, HOST_w1); // rorv FC_RETOP, w0, w1 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_ROLb: + *(Bit32u*)pos=MOVZ(HOST_w2, 32, 0); // movz w2, #32 + *(Bit32u*)(pos+4)=BFI(HOST_w0, HOST_w0, 8, 8); // bfi w0, w0, 8, 8 + *(Bit32u*)(pos+8)=SUB_REG_LSL_IMM(HOST_w2, HOST_w2, HOST_w1, 0); // sub w2, w2, w1 + *(Bit32u*)(pos+12)=BFI(HOST_w0, HOST_w0, 16, 16); // bfi w0, w0, 16, 16 + *(Bit32u*)(pos+16)=RORV(FC_RETOP, HOST_w0, HOST_w2); // rorv FC_RETOP, w0, w2 + case t_ROLw: + *(Bit32u*)pos=MOVZ(HOST_w2, 32, 0); // movz w2, #32 + *(Bit32u*)(pos+4)=BFI(HOST_w0, HOST_w0, 16, 16); // bfi w0, w0, 16, 16 + *(Bit32u*)(pos+8)=SUB_REG_LSL_IMM(HOST_w2, HOST_w2, HOST_w1, 0); // sub w2, w2, w1 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=RORV(FC_RETOP, HOST_w0, HOST_w2); // rorv FC_RETOP, w0, w2 + break; + case t_ROLd: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=MOVZ(HOST_w2, 32, 0); // movz w2, #32 + *(Bit32u*)(pos+8)=SUB_REG_LSL_IMM(HOST_w2, HOST_w2, HOST_w1, 0); // sub w2, w2, w1 + *(Bit32u*)(pos+12)=RORV(FC_RETOP, HOST_w0, HOST_w2); // rorv FC_RETOP, w0, w2 + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_NEGb: + case t_NEGw: + case t_NEGd: + *(Bit32u*)pos=NOP; // nop + *(Bit32u*)(pos+4)=NOP; // nop + *(Bit32u*)(pos+8)=SUB_REG_LSL_IMM(FC_RETOP, HOST_wzr, HOST_w0, 0); // sub FC_RETOP, wzr, w0 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=NOP; // nop + break; + case t_DSHLd: + *(Bit32u*)pos=MOVZ64(HOST_x3, 0x1f, 0); // movz x3, #0x1f + *(Bit32u*)(pos+4)=BFI64(HOST_x1, HOST_x0, 32, 32); // bfi x1, x0, 32, 32 + *(Bit32u*)(pos+8)=AND64_REG_LSL_IMM(HOST_x2, HOST_x2, HOST_x3, 0); // and x2, x2, x3 + *(Bit32u*)(pos+12)=LSLV64(FC_RETOP, HOST_x1, HOST_x2); // lslv FC_RETOP, x1, x2 + *(Bit32u*)(pos+16)=LSR64_IMM(FC_RETOP, FC_RETOP, 32); // lsr FC_RETOP, FC_RETOP, #32 + break; + case t_DSHRd: + *(Bit32u*)pos=MOVZ64(HOST_x3, 0x1f, 0); // movz x3, #0x1f + *(Bit32u*)(pos+4)=BFI64(HOST_x0, HOST_x1, 32, 32); // bfi x0, x1, 32, 32 + *(Bit32u*)(pos+8)=AND64_REG_LSL_IMM(HOST_x2, HOST_x2, HOST_x3, 0); // and x2, x2, x3 + *(Bit32u*)(pos+12)=NOP; // nop + *(Bit32u*)(pos+16)=LSRV64(FC_RETOP, HOST_x0, HOST_x2); // lsrv FC_RETOP, x0, x2 + break; + default: + *(Bit32u*)pos=MOVZ64(temp1, ((Bit64u)fct_ptr) & 0xffff, 0); // movz temp1, #(fct_ptr & 0xffff) + *(Bit32u*)(pos+4)=MOVK64(temp1, (((Bit64u)fct_ptr) >> 16) & 0xffff, 16); // movk temp1, #((fct_ptr >> 16) & 0xffff), lsl #16 + *(Bit32u*)(pos+8)=MOVK64(temp1, (((Bit64u)fct_ptr) >> 32) & 0xffff, 32); // movk temp1, #((fct_ptr >> 32) & 0xffff), lsl #32 + *(Bit32u*)(pos+12)=MOVK64(temp1, (((Bit64u)fct_ptr) >> 48) & 0xffff, 48); // movk temp1, #((fct_ptr >> 48) & 0xffff), lsl #48 + break; + + } +#else + *(Bit32u*)pos=MOVZ64(temp1, ((Bit64u)fct_ptr) & 0xffff, 0); // movz temp1, #(fct_ptr & 0xffff) + *(Bit32u*)(pos+4)=MOVK64(temp1, (((Bit64u)fct_ptr) >> 16) & 0xffff, 16); // movk temp1, #((fct_ptr >> 16) & 0xffff), lsl #16 + *(Bit32u*)(pos+8)=MOVK64(temp1, (((Bit64u)fct_ptr) >> 32) & 0xffff, 32); // movk temp1, #((fct_ptr >> 32) & 0xffff), lsl #32 + *(Bit32u*)(pos+12)=MOVK64(temp1, (((Bit64u)fct_ptr) >> 48) & 0xffff, 48); // movk temp1, #((fct_ptr >> 48) & 0xffff), lsl #48 +#endif +} +#endif + +static void cache_block_closing(Bit8u* block_start,Bitu block_size) { + //flush cache - GCC/LLVM builtin + __builtin___clear_cache((char *)block_start, (char *)(block_start+block_size)); +} + +static void cache_block_before_close(void) { } + +#ifdef DRC_USE_SEGS_ADDR + +// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { + cache_addd( LDRH_IMM(dest_reg, FC_SEGS_ADDR, index) ); // ldrh dest_reg, [FC_SEGS_ADDR, #index] +} + +// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) +static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { + cache_addd( LDR_IMM(dest_reg, FC_SEGS_ADDR, index) ); // ldr dest_reg, [FC_SEGS_ADDR, #index] +} + +// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) +static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { + cache_addd( LDR_IMM(temp1, FC_SEGS_ADDR, index) ); // ldr temp1, [FC_SEGS_ADDR, #index] + cache_addd( ADD_REG_LSL_IMM(reg, reg, temp1, 0) ); // add reg, reg, temp1 +} + +#endif + +#ifdef DRC_USE_REGS_ADDR + +// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { + cache_addd( LDRH_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrh dest_reg, [FC_REGS_ADDR, #index] +} + +// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { + cache_addd( LDR_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldr dest_reg, [FC_REGS_ADDR, #index] +} + +// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { + if (dword) { + cache_addd( LDR_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldr dest_reg, [FC_REGS_ADDR, #index] + } else { + cache_addd( LDRH_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrh dest_reg, [FC_REGS_ADDR, #index] + } +} + +// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { + cache_addd( LDRB_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrb dest_reg, [FC_REGS_ADDR, #index] +} + +// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { + cache_addd( LDRB_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrb dest_reg, [FC_REGS_ADDR, #index] +} + + +// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { + cache_addd( LDR_IMM(temp2, FC_REGS_ADDR, index) ); // ldr temp2, [FC_REGS_ADDR, #index] + cache_addd( ADD_REG_LSL_IMM(reg, reg, temp2, 0) ); // add reg, reg, temp2 +} + + +// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) +static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { + cache_addd( STRH_IMM(src_reg, FC_REGS_ADDR, index) ); // strh src_reg, [FC_REGS_ADDR, #index] +} + +// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { + cache_addd( STR_IMM(src_reg, FC_REGS_ADDR, index) ); // str src_reg, [FC_REGS_ADDR, #index] +} + +// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) +static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { + if (dword) { + cache_addd( STR_IMM(src_reg, FC_REGS_ADDR, index) ); // str src_reg, [FC_REGS_ADDR, #index] + } else { + cache_addd( STRH_IMM(src_reg, FC_REGS_ADDR, index) ); // strh src_reg, [FC_REGS_ADDR, #index] + } +} + +// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR +static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { + cache_addd( STRB_IMM(src_reg, FC_REGS_ADDR, index) ); // strb src_reg, [FC_REGS_ADDR, #index] +} + +#endif From 89eddef2f71bff3fb37dac06e699e92111a3dd65 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 13 Jun 2018 09:26:06 +0000 Subject: [PATCH 4027/4131] cleanup unfinished and unworking core stub Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4118 --- src/cpu/core_dynrec.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index 22b9cff1..e0e32be6 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -138,7 +138,6 @@ static struct { #define MIPSEL 0x03 #define ARMV4LE 0x04 #define ARMV7LE 0x05 -#define POWERPC 0x04 #define ARMV8LE 0x07 #if C_TARGETCPU == X86_64 @@ -149,8 +148,6 @@ static struct { #include "core_dynrec/risc_mipsel32.h" #elif (C_TARGETCPU == ARMV4LE) || (C_TARGETCPU == ARMV7LE) #include "core_dynrec/risc_armv4le.h" -#elif C_TARGETCPU == POWERPC -#include "core_dynrec/risc_ppc.h" #elif C_TARGETCPU == ARMV8LE #include "core_dynrec/risc_armv8le.h" #endif From 823242560cd9a98588d2ce2f4e0873b364d2e12b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 14 Jun 2018 21:06:50 +0000 Subject: [PATCH 4028/4131] Commit fix by M-HT. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4119 --- src/cpu/core_dynrec/risc_armv8le.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu/core_dynrec/risc_armv8le.h b/src/cpu/core_dynrec/risc_armv8le.h index 62f3a60a..fe4ecc53 100644 --- a/src/cpu/core_dynrec/risc_armv8le.h +++ b/src/cpu/core_dynrec/risc_armv8le.h @@ -1081,6 +1081,7 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { *(Bit32u*)(pos+8)=SUB_REG_LSL_IMM(HOST_w2, HOST_w2, HOST_w1, 0); // sub w2, w2, w1 *(Bit32u*)(pos+12)=BFI(HOST_w0, HOST_w0, 16, 16); // bfi w0, w0, 16, 16 *(Bit32u*)(pos+16)=RORV(FC_RETOP, HOST_w0, HOST_w2); // rorv FC_RETOP, w0, w2 + break; case t_ROLw: *(Bit32u*)pos=MOVZ(HOST_w2, 32, 0); // movz w2, #32 *(Bit32u*)(pos+4)=BFI(HOST_w0, HOST_w0, 16, 16); // bfi w0, w0, 16, 16 From 66b813ef9c150eabcca5240a45c7f0ad0c37eed2 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Thu, 21 Jun 2018 17:46:52 +0000 Subject: [PATCH 4029/4131] Support some installer disk detection methods: block device count, and specific MBR/boot sector contents. Fixes (original) SimCity, Amberstar, and later MicroProse installers. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4120 --- include/dos_inc.h | 1 + src/dos/dos.cpp | 21 +++++++++++++++------ src/dos/dos_classes.cpp | 4 ++++ src/ints/bios_disk.cpp | 13 ++++++++++++- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/include/dos_inc.h b/include/dos_inc.h index 40ecb195..753af672 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -386,6 +386,7 @@ public: void SetDiskBufferHeadPt(Bit32u _dbheadpt); void SetStartOfUMBChain(Bit16u _umbstartseg); void SetUMBChainState(Bit8u _umbchaining); + void SetBlockDevices(Bit8u _count); Bit16u GetStartOfUMBChain(void); Bit8u GetUMBChainState(void); RealPt GetPointer(void); diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 897b6880..d5cb2b8b 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -840,6 +840,9 @@ static Bitu DOS_21Handler(void) { reg_bx=dos.psp(); break; case 0x52: { /* Get list of lists */ + Bit8u count=2; // floppy drives always counted + while (countisRemovable()) count++; + dos_infoblock.SetBlockDevices(count); RealPt addr=dos_infoblock.GetPointer(); SegSet16(es,RealSeg(addr)); reg_bx=RealOff(addr); @@ -1171,22 +1174,28 @@ static Bitu DOS_27Handler(void) { } static Bitu DOS_25Handler(void) { - if (Drives[reg_al] == 0){ + if (reg_al >= DOS_DRIVES || !Drives[reg_al] || Drives[reg_al]->isRemovable()) { reg_ax = 0x8002; SETFLAGBIT(CF,true); } else { + if (reg_cx == 1 && reg_dx == 0) { + if (reg_al >= 2) { + PhysPt ptr = PhysMake(SegValue(ds),reg_bx); + // write some BPB data into buffer for MicroProse installers + mem_writew(ptr+0x1c,0x3f); // hidden sectors + } + } else { + LOG(LOG_DOSMISC,LOG_NORMAL)("int 25 called but not as disk detection drive %u",reg_al); + } SETFLAGBIT(CF,false); - if ((reg_cx != 1) ||(reg_dx != 1)) - LOG(LOG_DOSMISC,LOG_NORMAL)("int 25 called but not as diskdetection drive %X",reg_al); - - reg_ax = 0; + reg_ax = 0; } SETFLAGBIT(IF,true); return CBRET_NONE; } static Bitu DOS_26Handler(void) { LOG(LOG_DOSMISC,LOG_NORMAL)("int 26 called: hope for the best!"); - if (Drives[reg_al] == 0){ + if (reg_al >= DOS_DRIVES || !Drives[reg_al] || Drives[reg_al]->isRemovable()) { reg_ax = 0x8002; SETFLAGBIT(CF,true); } else { diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 3df73f2e..d407b04d 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -157,6 +157,10 @@ void DOS_InfoBlock::SetUMBChainState(Bit8u _umbchaining) { sSave(sDIB,chainingUMB,_umbchaining); } +void DOS_InfoBlock::SetBlockDevices(Bit8u _count) { + sSave(sDIB,blockDevices,_count); +} + RealPt DOS_InfoBlock::GetPointer(void) { return RealMake(seg,offsetof(sDIB,firstDPB)); } diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 863b88ad..c3683db4 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -366,8 +366,19 @@ static Bitu INT13_DiskHandler(void) { return CBRET_NONE; } if (!any_images) { - // Inherit the Earth cdrom (uses it as disk test) + if (drivenum >= DOS_DRIVES || !Drives[drivenum] || Drives[drivenum]->isRemovable()) { + reg_ah = 0x01; + CALLBACK_SCF(true); + return CBRET_NONE; + } + // Inherit the Earth cdrom and Amberstar use it as a disk test if (((reg_dl&0x80)==0x80) && (reg_dh==0) && ((reg_cl&0x3f)==1)) { + if (reg_ch==0) { + PhysPt ptr = PhysMake(SegValue(es),reg_bx); + // write some MBR data into buffer for Amberstar installer + mem_writeb(ptr+0x1be,0x80); // first partition is active + mem_writeb(ptr+0x1c2,0x06); // first partition is FAT16B + } reg_ah = 0; CALLBACK_SCF(false); return CBRET_NONE; From 3ddf3056e833affbde37e348691249453aea9641 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 Jun 2018 15:27:39 +0000 Subject: [PATCH 4030/4131] Work with ints when dealing with abs. Fixes a warning. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4121 --- src/hardware/vga_tseng.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hardware/vga_tseng.cpp b/src/hardware/vga_tseng.cpp index 81e4c2c1..576346a0 100644 --- a/src/hardware/vga_tseng.cpp +++ b/src/hardware/vga_tseng.cpp @@ -352,11 +352,11 @@ void FinishSetMode_ET4K(Bitu crtc_base, VGA_ModeExtraData* modeData) { // Select SVGA clock to get close to 60Hz (not particularly clean implementation) if (modeData->modeNo > 0x13) { - Bitu target = modeData->vtotal*8*modeData->htotal*60; + Bits target = static_cast(modeData->vtotal * 8 * modeData->htotal * 60); Bitu best = 1; - Bits dist = 100000000; - for (Bitu i=0; i<16; i++) { - Bits cdiff=abs((Bits)(target-et4k.clockFreq[i])); + int dist = 100000000; + for (Bitu i = 0; i < 16; i++) { + int cdiff = abs( static_cast(target - static_cast(et4k.clockFreq[i])) ); if (cdiff < dist) { best = i; dist = cdiff; @@ -716,11 +716,11 @@ void FinishSetMode_ET3K(Bitu crtc_base, VGA_ModeExtraData* modeData) { // Select SVGA clock to get close to 60Hz (not particularly clean implementation) if (modeData->modeNo > 0x13) { - Bitu target = modeData->vtotal*8*modeData->htotal*60; + Bits target = static_cast(modeData->vtotal * 8 * modeData->htotal * 60); Bitu best = 1; - Bits dist = 100000000; - for (Bitu i=0; i<8; i++) { - Bits cdiff = abs((Bits)(target-et3k.clockFreq[i])); + int dist = 100000000; + for (Bitu i = 0; i < 8; i++) { + int cdiff = abs( static_cast(target - static_cast(et3k.clockFreq[i])) ); if (cdiff < dist) { best = i; dist = cdiff; From 50d6368b14f5c3117b1a55923cd02b35480daff5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 Jun 2018 15:30:44 +0000 Subject: [PATCH 4031/4131] Work with ints when dealing with abs. Fixes a warning. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4122 --- src/hardware/vga_crtc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 991d6eaa..47e2368c 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -242,7 +242,7 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { break; case 0x12: /* Vertical Display End Register */ if (val!=crtc(vertical_display_end)) { - if (abs((Bits)val-(Bits)crtc(vertical_display_end))<3) { + if (abs(static_cast((Bits)val-(Bits)crtc(vertical_display_end)))<3) { // delay small vde changes a bit to avoid screen resizing // if they are reverted in a short timeframe PIC_RemoveEvents(VGA_SetupDrawing); From 30ef5aefe94ff04c919e0296667d658373e1b163 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 10 Jul 2018 15:38:55 +0000 Subject: [PATCH 4032/4131] Fix GetLabel() for the virtual drive. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4128 --- src/dos/drive_virtual.cpp | 9 ++++++--- src/dos/drives.h | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index f17ad533..0b42bcbd 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -205,11 +205,11 @@ bool Virtual_Drive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) { Bit8u attr;char pattern[DOS_NAMELENGTH_ASCII]; dta.GetSearchParams(attr,pattern); if (attr == DOS_ATTR_VOLUME) { - dta.SetResult("DOSBOX",0,0,0,DOS_ATTR_VOLUME); + dta.SetResult(GetLabel(),0,0,0,DOS_ATTR_VOLUME); return true; } else if ((attr & DOS_ATTR_VOLUME) && !fcb_findfirst) { - if (WildFileCmp("DOSBOX",pattern)) { - dta.SetResult("DOSBOX",0,0,0,DOS_ATTR_VOLUME); + if (WildFileCmp(GetLabel(),pattern)) { + dta.SetResult(GetLabel(),0,0,0,DOS_ATTR_VOLUME); return true; } } @@ -271,3 +271,6 @@ Bits Virtual_Drive::UnMount(void) { return 1; } +char const* Virtual_Drive::GetLabel(void) { + return "DOSBOX"; +} diff --git a/src/dos/drives.h b/src/dos/drives.h index b06f1861..4a3cd65f 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -396,6 +396,7 @@ public: bool isRemote(void); virtual bool isRemovable(void); virtual Bits UnMount(void); + virtual char const* GetLabel(void); private: VFILE_Block * search_file; }; From be146f5c440b75b2e0886701cb032894b0c0161a Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 10 Jul 2018 15:51:16 +0000 Subject: [PATCH 4033/4131] Improve disk image mounting: cycle disks only for the drive being mounted, make B: drive usable for BIOS access, and be insensitive to the order that drive letters are mounted. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4129 --- src/dos/dos_programs.cpp | 26 ++++++++++++++------------ src/dos/drives.cpp | 36 +++++++++++++++++++----------------- src/dos/drives.h | 1 + 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 55a9d7fe..41853a30 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1322,7 +1322,7 @@ public: dos.dta(dos.tables.tempdta); for(ct = 0; ct < imgDisks.size(); ct++) { - DriveManager::CycleAllDisks(); + DriveManager::CycleDisks(drive - 'A', (ct == (imgDisks.size() - 1))); char root[7] = {drive,':','\\','*','.','*',0}; DOS_FindFirst(root, DOS_ATTR_VOLUME); // force obtaining the label and saving it in dirCache @@ -1337,20 +1337,22 @@ public: if (paths.size() == 1) { newdrive = imgDisks[0]; - if(((fatDrive *)newdrive)->loadedDisk->hardDrive) { - if(imageDiskList[2] == NULL) { - imageDiskList[2] = ((fatDrive *)newdrive)->loadedDisk; - updateDPT(); - return; + switch (drive - 'A') { + case 0: + case 1: + if(!((fatDrive *)newdrive)->loadedDisk->hardDrive) { + if(imageDiskList[drive - 'A'] != NULL) delete imageDiskList[drive - 'A']; + imageDiskList[drive - 'A'] = ((fatDrive *)newdrive)->loadedDisk; } - if(imageDiskList[3] == NULL) { - imageDiskList[3] = ((fatDrive *)newdrive)->loadedDisk; + break; + case 2: + case 3: + if(((fatDrive *)newdrive)->loadedDisk->hardDrive) { + if(imageDiskList[drive - 'A'] != NULL) delete imageDiskList[drive - 'A']; + imageDiskList[drive - 'A'] = ((fatDrive *)newdrive)->loadedDisk; updateDPT(); - return; } - } - if(!((fatDrive *)newdrive)->loadedDisk->hardDrive) { - imageDiskList[0] = ((fatDrive *)newdrive)->loadedDisk; + break; } } } else if (fstype=="iso") { diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index 46c91291..832eb91f 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -169,26 +169,28 @@ void DriveManager::CycleDisk(bool pressed) { } */ -void DriveManager::CycleAllDisks(void) { - for (int idrive=0; idrive 1) { - // cycle disk - int currentDisk = driveInfos[idrive].currentDisk; - DOS_Drive* oldDisk = driveInfos[idrive].disks[currentDisk]; - currentDisk = (currentDisk + 1) % numDisks; - DOS_Drive* newDisk = driveInfos[idrive].disks[currentDisk]; - driveInfos[idrive].currentDisk = currentDisk; - - // copy working directory, acquire system resources and finally switch to next drive - strcpy(newDisk->curdir, oldDisk->curdir); - newDisk->Activate(); - Drives[idrive] = newDisk; - LOG_MSG("Drive %c: disk %d of %d now active", 'A'+idrive, currentDisk+1, numDisks); - } +void DriveManager::CycleDisks(int drive, bool notify) { + int numDisks = (int)driveInfos[drive].disks.size(); + if (numDisks > 1) { + // cycle disk + int currentDisk = driveInfos[drive].currentDisk; + DOS_Drive* oldDisk = driveInfos[drive].disks[currentDisk]; + currentDisk = (currentDisk + 1) % numDisks; + DOS_Drive* newDisk = driveInfos[drive].disks[currentDisk]; + driveInfos[drive].currentDisk = currentDisk; + + // copy working directory, acquire system resources and finally switch to next drive + strcpy(newDisk->curdir, oldDisk->curdir); + newDisk->Activate(); + Drives[drive] = newDisk; + if (notify) LOG_MSG("Drive %c: disk %d of %d now active", 'A'+drive, currentDisk+1, numDisks); } } +void DriveManager::CycleAllDisks(void) { + for (int idrive=0; idrive Date: Tue, 10 Jul 2018 16:05:17 +0000 Subject: [PATCH 4034/4131] FAT drive fixes and improvements. Identify floppy format, and support filesystems that use only part of the disk. Fixes Make Your Own Murder Party and Music/Pinball Construction Set. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4130 --- src/dos/drive_fat.cpp | 259 +++++++++++++++++++++++++++++------------- src/dos/drives.h | 6 +- 2 files changed, 182 insertions(+), 83 deletions(-) diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 3c1b7f89..a58ae1e7 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -96,8 +96,6 @@ fatFile::fatFile(const char* /*name*/, Bit32u startCluster, Bit32u fileLen, fatD if(filelength > 0) { Seek(&seekto, DOS_SEEK_SET); - myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); - loadedSector = true; } } @@ -120,8 +118,8 @@ bool fatFile::Read(Bit8u * data, Bit16u *size) { loadedSector = false; return true; } - curSectOff = 0; - myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); + curSectOff = seekpos % myDrive->getSectorSize(); + myDrive->readSector(currentSector, sectorBuffer); loadedSector = true; } @@ -144,7 +142,7 @@ bool fatFile::Read(Bit8u * data, Bit16u *size) { return true; } curSectOff = 0; - myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); + myDrive->readSector(currentSector, sectorBuffer); loadedSector = true; //LOG_MSG("Reading absolute sector at %d for seekpos %d", currentSector, seekpos); } @@ -155,8 +153,6 @@ bool fatFile::Read(Bit8u * data, Bit16u *size) { } bool fatFile::Write(Bit8u * data, Bit16u *size) { - /* TODO: Check for read-only bit */ - if ((this->flags & 0xf) == OPEN_READ) { // check if file opened in read-only mode DOS_SetError(DOSERR_ACCESS_DENIED); return false; @@ -167,17 +163,42 @@ bool fatFile::Write(Bit8u * data, Bit16u *size) { sizedec = *size; sizecount = 0; + if(seekpos < filelength && *size == 0) { + /* Truncate file to current position */ + myDrive->deleteClustChain(firstCluster, seekpos); + filelength = seekpos; + goto finalizeWrite; + } + + if(seekpos > filelength) { + /* Extend file to current position */ + Bit32u clustSize = myDrive->getClusterSize(); + if(filelength == 0) { + firstCluster = myDrive->getFirstFreeClust(); + if(firstCluster == 0) goto finalizeWrite; // out of space + myDrive->allocateCluster(firstCluster, 0); + filelength = clustSize; + } + filelength = ((filelength - 1) / clustSize + 1) * clustSize; + while(filelength < seekpos) { + if(myDrive->appendCluster(firstCluster) == 0) goto finalizeWrite; // out of space + filelength += clustSize; + } + if(filelength > seekpos) filelength = seekpos; + if(*size == 0) goto finalizeWrite; + } + while(sizedec != 0) { /* Increase filesize if necessary */ if(seekpos >= filelength) { if(filelength == 0) { firstCluster = myDrive->getFirstFreeClust(); + if(firstCluster == 0) goto finalizeWrite; // out of space myDrive->allocateCluster(firstCluster, 0); currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); - myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); + myDrive->readSector(currentSector, sectorBuffer); loadedSector = true; } - filelength = seekpos+1; if (!loadedSector) { currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); if(currentSector == 0) { @@ -190,16 +211,16 @@ bool fatFile::Write(Bit8u * data, Bit16u *size) { goto finalizeWrite; } } - curSectOff = 0; - myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); - + curSectOff = seekpos % myDrive->getSectorSize(); + myDrive->readSector(currentSector, sectorBuffer); loadedSector = true; } + filelength = seekpos+1; } sectorBuffer[curSectOff++] = data[sizecount++]; seekpos++; if(curSectOff >= myDrive->getSectorSize()) { - if(loadedSector) myDrive->loadedDisk->Write_AbsoluteSector(currentSector, sectorBuffer); + if(loadedSector) myDrive->writeSector(currentSector, sectorBuffer); currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); if(currentSector == 0) { @@ -214,13 +235,12 @@ bool fatFile::Write(Bit8u * data, Bit16u *size) { } } curSectOff = 0; - myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); - + myDrive->readSector(currentSector, sectorBuffer); loadedSector = true; } --sizedec; } - if(curSectOff>0 && loadedSector) myDrive->loadedDisk->Write_AbsoluteSector(currentSector, sectorBuffer); + if(curSectOff>0 && loadedSector) myDrive->writeSector(currentSector, sectorBuffer); finalizeWrite: myDrive->directoryBrowse(dirCluster, &tmpentry, dirIndex); @@ -249,7 +269,6 @@ bool fatFile::Seek(Bit32u *pos, Bit32u type) { } // LOG_MSG("Seek to %d with type %d (absolute value %d)", *pos, type, seekto); - if((Bit32u)seekto > filelength) seekto = (Bit32s)filelength; if(seekto<0) seekto = 0; seekpos = (Bit32u)seekto; currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); @@ -258,7 +277,8 @@ bool fatFile::Seek(Bit32u *pos, Bit32u type) { loadedSector = false; } else { curSectOff = seekpos % myDrive->getSectorSize(); - myDrive->loadedDisk->Read_AbsoluteSector(currentSector, sectorBuffer); + myDrive->readSector(currentSector, sectorBuffer); + loadedSector = true; } *pos = seekpos; return true; @@ -266,7 +286,7 @@ bool fatFile::Seek(Bit32u *pos, Bit32u type) { bool fatFile::Close() { /* Flush buffer */ - if (loadedSector) myDrive->loadedDisk->Write_AbsoluteSector(currentSector, sectorBuffer); + if (loadedSector) myDrive->writeSector(currentSector, sectorBuffer); return false; } @@ -305,9 +325,9 @@ Bit32u fatDrive::getClusterValue(Bit32u clustNum) { if(curFatSect != fatsectnum) { /* Load two sectors at once for FAT12 */ - loadedDisk->Read_AbsoluteSector(fatsectnum, &fatSectBuffer[0]); + readSector(fatsectnum, &fatSectBuffer[0]); if (fattype==FAT12) - loadedDisk->Read_AbsoluteSector(fatsectnum+1, &fatSectBuffer[512]); + readSector(fatsectnum+1, &fatSectBuffer[512]); curFatSect = fatsectnum; } @@ -352,9 +372,9 @@ void fatDrive::setClusterValue(Bit32u clustNum, Bit32u clustValue) { if(curFatSect != fatsectnum) { /* Load two sectors at once for FAT12 */ - loadedDisk->Read_AbsoluteSector(fatsectnum, &fatSectBuffer[0]); + readSector(fatsectnum, &fatSectBuffer[0]); if (fattype==FAT12) - loadedDisk->Read_AbsoluteSector(fatsectnum+1, &fatSectBuffer[512]); + readSector(fatsectnum+1, &fatSectBuffer[512]); curFatSect = fatsectnum; } @@ -383,10 +403,10 @@ void fatDrive::setClusterValue(Bit32u clustNum, Bit32u clustValue) { break; } for(int fc=0;fcWrite_AbsoluteSector(fatsectnum + (fc * bootbuffer.sectorsperfat), &fatSectBuffer[0]); + writeSector(fatsectnum + (fc * bootbuffer.sectorsperfat), &fatSectBuffer[0]); if (fattype==FAT12) { if (fatentoff>=511) - loadedDisk->Write_AbsoluteSector(fatsectnum+1+(fc * bootbuffer.sectorsperfat), &fatSectBuffer[512]); + writeSector(fatsectnum+1+(fc * bootbuffer.sectorsperfat), &fatSectBuffer[512]); } } } @@ -495,10 +515,34 @@ bool fatDrive::getDirClustNum(char *dir, Bit32u *clustNum, bool parDir) { return true; } +Bit8u fatDrive::readSector(Bit32u sectnum, void * data) { + if (absolute) return loadedDisk->Read_AbsoluteSector(sectnum, data); + Bit32u cylindersize = bootbuffer.headcount * bootbuffer.sectorspertrack; + Bit32u cylinder = sectnum / cylindersize; + sectnum %= cylindersize; + Bit32u head = sectnum / bootbuffer.sectorspertrack; + Bit32u sector = sectnum % bootbuffer.sectorspertrack + 1L; + return loadedDisk->Read_Sector(head, cylinder, sector, data); +} + +Bit8u fatDrive::writeSector(Bit32u sectnum, void * data) { + if (absolute) return loadedDisk->Write_AbsoluteSector(sectnum, data); + Bit32u cylindersize = bootbuffer.headcount * bootbuffer.sectorspertrack; + Bit32u cylinder = sectnum / cylindersize; + sectnum %= cylindersize; + Bit32u head = sectnum / bootbuffer.sectorspertrack; + Bit32u sector = sectnum % bootbuffer.sectorspertrack + 1L; + return loadedDisk->Write_Sector(head, cylinder, sector, data); +} + Bit32u fatDrive::getSectorSize(void) { return bootbuffer.bytespersector; } +Bit32u fatDrive::getClusterSize(void) { + return bootbuffer.sectorspercluster * bootbuffer.bytespersector; +} + Bit32u fatDrive::getAbsoluteSectFromBytePos(Bit32u startClustNum, Bit32u bytePos) { return getAbsoluteSectFromChain(startClustNum, bytePos / bootbuffer.bytespersector); } @@ -539,7 +583,11 @@ Bit32u fatDrive::getAbsoluteSectFromChain(Bit32u startClustNum, Bit32u logicalSe return (getClustFirstSect(currentClust) + sectClust); } -void fatDrive::deleteClustChain(Bit32u startCluster) { +void fatDrive::deleteClustChain(Bit32u startCluster, Bit32u bytePos) { + Bit32u clustSize = getClusterSize(); + Bit32u endClust = (bytePos + clustSize - 1) / clustSize; + Bit32u countClust = 1; + Bit32u testvalue; Bit32u currentClust = startCluster; bool isEOF = false; @@ -549,8 +597,6 @@ void fatDrive::deleteClustChain(Bit32u startCluster) { /* What the crap? Cluster is already empty - BAIL! */ break; } - /* Mark cluster as empty */ - setClusterValue(currentClust, 0); switch(fattype) { case FAT12: if(testvalue >= 0xff8) isEOF = true; @@ -562,8 +608,26 @@ void fatDrive::deleteClustChain(Bit32u startCluster) { if(testvalue >= 0xfffffff8) isEOF = true; break; } + if(countClust == endClust && !isEOF) { + /* Mark cluster as end */ + switch(fattype) { + case FAT12: + setClusterValue(currentClust, 0xfff); + break; + case FAT16: + setClusterValue(currentClust, 0xffff); + break; + case FAT32: + setClusterValue(currentClust, 0xffffffff); + break; + } + } else if(countClust > endClust) { + /* Mark cluster as empty */ + setClusterValue(currentClust, 0); + } if(isEOF) break; currentClust = testvalue; + countClust++; } } @@ -632,6 +696,7 @@ fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, created_successfully = true; FILE *diskfile; Bit32u filesize; + bool is_hdd; struct partTable mbrData; if(imgDTASeg == 0) { @@ -644,15 +709,16 @@ fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, if(!diskfile) {created_successfully = false;return;} fseek(diskfile, 0L, SEEK_END); filesize = (Bit32u)ftell(diskfile) / 1024L; + is_hdd = (filesize > 2880); /* Load disk image */ - loadedDisk = new imageDisk(diskfile, (Bit8u *)sysFilename, filesize, (filesize > 2880)); + loadedDisk = new imageDisk(diskfile, (Bit8u *)sysFilename, filesize, is_hdd); if(!loadedDisk) { created_successfully = false; return; } - if(filesize > 2880) { + if(is_hdd) { /* Set user specified harddrive parameters */ loadedDisk->Set_Geometry(headscyl, cylinders,cylsector, bytesector); @@ -675,50 +741,69 @@ fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, partSectOff = startSector; } else { + /* Get floppy disk parameters based on image size */ + loadedDisk->Get_Geometry(&headscyl, &cylinders, &cylsector, &bytesector); /* Floppy disks don't have partitions */ partSectOff = 0; } + if (bytesector != 512) { + /* Non-standard sector sizes not implemented */ + created_successfully = false; + return; + } + loadedDisk->Read_AbsoluteSector(0+partSectOff,&bootbuffer); - /* Check for DOS 1.x format floppy */ - if ((bootbuffer.mediadescriptor & 0xf0) != 0xf0 && filesize <= 360) { + if (!is_hdd) { + /* Identify floppy format */ + if ((bootbuffer.nearjmp[0] == 0x69 || bootbuffer.nearjmp[0] == 0xe9 || + (bootbuffer.nearjmp[0] == 0xeb && bootbuffer.nearjmp[2] == 0x90)) && + (bootbuffer.mediadescriptor & 0xf0) == 0xf0) { + /* DOS 2.x or later format, BPB assumed valid */ - Bit8u sectorBuffer[512]; - loadedDisk->Read_AbsoluteSector(1,§orBuffer); - Bit8u mdesc = sectorBuffer[0]; - - /* Allowed if media descriptor in FAT matches image size */ - if ((mdesc == 0xfc && filesize == 180) || - (mdesc == 0xfd && filesize == 360) || - (mdesc == 0xfe && filesize == 160) || - (mdesc == 0xff && filesize == 320)) { - - /* Create parameters for a 160kB floppy */ - bootbuffer.bytespersector = 512; - bootbuffer.sectorspercluster = 1; - bootbuffer.reservedsectors = 1; - bootbuffer.fatcopies = 2; - bootbuffer.rootdirentries = 64; - bootbuffer.totalsectorcount = 320; - bootbuffer.mediadescriptor = mdesc; - bootbuffer.sectorsperfat = 1; - bootbuffer.sectorspertrack = 8; - bootbuffer.headcount = 1; - bootbuffer.magic1 = 0x55; // to silence warning - bootbuffer.magic2 = 0xaa; - if (!(mdesc & 0x2)) { - /* Adjust for 9 sectors per track */ - bootbuffer.totalsectorcount = 360; - bootbuffer.sectorsperfat = 2; - bootbuffer.sectorspertrack = 9; + if ((bootbuffer.mediadescriptor != 0xf0 && !(bootbuffer.mediadescriptor & 0x1)) && + (bootbuffer.oemname[5] != '3' || bootbuffer.oemname[6] != '.' || bootbuffer.oemname[7] < '2')) { + /* Fix pre-DOS 3.2 single-sided floppy */ + bootbuffer.sectorspercluster = 1; } - if (mdesc & 0x1) { - /* Adjust for 2 sides */ - bootbuffer.sectorspercluster = 2; - bootbuffer.rootdirentries = 112; - bootbuffer.totalsectorcount *= 2; - bootbuffer.headcount = 2; + } else { + /* Read media descriptor in FAT */ + Bit8u sectorBuffer[512]; + loadedDisk->Read_AbsoluteSector(1,§orBuffer); + Bit8u mdesc = sectorBuffer[0]; + + if (mdesc >= 0xf8) { + /* DOS 1.x format, create BPB for 160kB floppy */ + bootbuffer.bytespersector = 512; + bootbuffer.sectorspercluster = 1; + bootbuffer.reservedsectors = 1; + bootbuffer.fatcopies = 2; + bootbuffer.rootdirentries = 64; + bootbuffer.totalsectorcount = 320; + bootbuffer.mediadescriptor = mdesc; + bootbuffer.sectorsperfat = 1; + bootbuffer.sectorspertrack = 8; + bootbuffer.headcount = 1; + bootbuffer.magic1 = 0x55; // to silence warning + bootbuffer.magic2 = 0xaa; + if (!(mdesc & 0x2)) { + /* Adjust for 9 sectors per track */ + bootbuffer.totalsectorcount = 360; + bootbuffer.sectorsperfat = 2; + bootbuffer.sectorspertrack = 9; + } + if (mdesc & 0x1) { + /* Adjust for 2 sides */ + bootbuffer.sectorspercluster = 2; + bootbuffer.rootdirentries = 112; + bootbuffer.totalsectorcount *= 2; + bootbuffer.headcount = 2; + } + } else { + /* Unknown format */ + created_successfully = false; + return; } } } @@ -728,17 +813,26 @@ fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, LOG_MSG("Loaded image has no valid magicnumbers at the end!"); } - if(!bootbuffer.sectorsperfat) { - /* FAT32 not implemented yet */ + /* Sanity checks */ + if ((bootbuffer.sectorsperfat == 0) || // FAT32 not implemented yet + (bootbuffer.bytespersector != 512) || // non-standard sector sizes not implemented + (bootbuffer.sectorspercluster == 0) || + (bootbuffer.rootdirentries == 0) || + (bootbuffer.fatcopies == 0) || + (bootbuffer.headcount == 0) || + (bootbuffer.headcount > headscyl) || + (bootbuffer.sectorspertrack == 0) || + (bootbuffer.sectorspertrack > cylsector)) { created_successfully = false; return; } + /* Filesystem must be contiguous to use absolute sectors, otherwise CHS will be used */ + absolute = ((bootbuffer.headcount == headscyl) && (bootbuffer.sectorspertrack == cylsector)); /* Determine FAT format, 12, 16 or 32 */ /* Get size of root dir in sectors */ - /* TODO: Get 32-bit total sector count if needed */ Bit32u RootDirSectors = ((bootbuffer.rootdirentries * 32) + (bootbuffer.bytespersector - 1)) / bootbuffer.bytespersector; Bit32u DataSectors; if(bootbuffer.totalsectorcount != 0) { @@ -830,6 +924,7 @@ bool fatDrive::FileCreate(DOS_File **file, char *name, Bit16u attributes) { /* Truncate file */ fileEntry.entrysize=0; directoryChange(dirClust, &fileEntry, subEntry); + if(fileEntry.loFirstClust != 0) deleteClustChain(fileEntry.loFirstClust, 0); } else { /* Can we even get the name of the file itself? */ if(!getEntryName(name, &dirName[0])) return false; @@ -896,7 +991,7 @@ bool fatDrive::FileUnlink(char * name) { fileEntry.entryname[0] = 0xe5; directoryChange(dirClust, &fileEntry, subEntry); - if(fileEntry.loFirstClust != 0) deleteClustChain(fileEntry.loFirstClust); + if(fileEntry.loFirstClust != 0) deleteClustChain(fileEntry.loFirstClust, 0); return true; } @@ -967,7 +1062,7 @@ nextfile: DOS_SetError(DOSERR_NO_MORE_FILES); return false; } - loadedDisk->Read_AbsoluteSector(firstRootDirSect+logentsector,sectbuf); + readSector(firstRootDirSect+logentsector,sectbuf); } else { tmpsector = getAbsoluteSectFromChain(dirClustNumber, logentsector); /* A zero sector number can't happen */ @@ -975,7 +1070,7 @@ nextfile: DOS_SetError(DOSERR_NO_MORE_FILES); return false; } - loadedDisk->Read_AbsoluteSector(tmpsector,sectbuf); + readSector(tmpsector,sectbuf); } dirPos++; dta.SetDirID(dirPos); @@ -1079,12 +1174,12 @@ bool fatDrive::directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s if(dirClustNumber==0) { if(dirPos >= bootbuffer.rootdirentries) return false; tmpsector = firstRootDirSect+logentsector; - loadedDisk->Read_AbsoluteSector(tmpsector,sectbuf); + readSector(tmpsector,sectbuf); } else { tmpsector = getAbsoluteSectFromChain(dirClustNumber, logentsector); /* A zero sector number can't happen */ if(tmpsector == 0) return false; - loadedDisk->Read_AbsoluteSector(tmpsector,sectbuf); + readSector(tmpsector,sectbuf); } dirPos++; @@ -1113,12 +1208,12 @@ bool fatDrive::directoryChange(Bit32u dirClustNumber, direntry *useEntry, Bit32s if(dirClustNumber==0) { if(dirPos >= bootbuffer.rootdirentries) return false; tmpsector = firstRootDirSect+logentsector; - loadedDisk->Read_AbsoluteSector(tmpsector,sectbuf); + readSector(tmpsector,sectbuf); } else { tmpsector = getAbsoluteSectFromChain(dirClustNumber, logentsector); /* A zero sector number can't happen */ if(tmpsector == 0) return false; - loadedDisk->Read_AbsoluteSector(tmpsector,sectbuf); + readSector(tmpsector,sectbuf); } dirPos++; @@ -1129,7 +1224,7 @@ bool fatDrive::directoryChange(Bit32u dirClustNumber, direntry *useEntry, Bit32s } if(tmpsector != 0) { memcpy(§buf[entryoffset], useEntry, sizeof(direntry)); - loadedDisk->Write_AbsoluteSector(tmpsector, sectbuf); + writeSector(tmpsector, sectbuf); return true; } else { return false; @@ -1151,7 +1246,7 @@ bool fatDrive::addDirectoryEntry(Bit32u dirClustNumber, direntry useEntry) { if(dirClustNumber==0) { if(dirPos >= bootbuffer.rootdirentries) return false; tmpsector = firstRootDirSect+logentsector; - loadedDisk->Read_AbsoluteSector(tmpsector,sectbuf); + readSector(tmpsector,sectbuf); } else { tmpsector = getAbsoluteSectFromChain(dirClustNumber, logentsector); /* A zero sector number can't happen - we need to allocate more room for this directory*/ @@ -1163,14 +1258,14 @@ bool fatDrive::addDirectoryEntry(Bit32u dirClustNumber, direntry useEntry) { tmpsector = getAbsoluteSectFromChain(dirClustNumber, logentsector); if(tmpsector == 0) return false; /* Give up if still can't get more room for directory */ } - loadedDisk->Read_AbsoluteSector(tmpsector,sectbuf); + readSector(tmpsector,sectbuf); } dirPos++; /* Deleted file entry or end of directory list */ if ((sectbuf[entryoffset].entryname[0] == 0xe5) || (sectbuf[entryoffset].entryname[0] == 0x00)) { sectbuf[entryoffset] = useEntry; - loadedDisk->Write_AbsoluteSector(tmpsector,sectbuf); + writeSector(tmpsector,sectbuf); break; } } @@ -1185,7 +1280,7 @@ void fatDrive::zeroOutCluster(Bit32u clustNumber) { int i; for(i=0;iWrite_AbsoluteSector(getAbsoluteSectFromChain(clustNumber,i), &secBuffer[0]); + writeSector(getAbsoluteSectFromChain(clustNumber,i), &secBuffer[0]); } } @@ -1282,7 +1377,7 @@ bool fatDrive::RemoveDir(char *dir) { found = true; tmpentry.entryname[0] = 0xe5; directoryChange(dirClust, &tmpentry, fileidx); - deleteClustChain(dummyClust); + deleteClustChain(dummyClust, 0); break; } diff --git a/src/dos/drives.h b/src/dos/drives.h index 4fa9aa62..14f38315 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -165,12 +165,15 @@ public: virtual bool isRemovable(void); virtual Bits UnMount(void); public: + Bit8u readSector(Bit32u sectnum, void * data); + Bit8u writeSector(Bit32u sectnum, void * data); Bit32u getAbsoluteSectFromBytePos(Bit32u startClustNum, Bit32u bytePos); Bit32u getSectorSize(void); + Bit32u getClusterSize(void); Bit32u getAbsoluteSectFromChain(Bit32u startClustNum, Bit32u logicalSector); bool allocateCluster(Bit32u useCluster, Bit32u prevCluster); Bit32u appendCluster(Bit32u startCluster); - void deleteClustChain(Bit32u startCluster); + void deleteClustChain(Bit32u startCluster, Bit32u bytePos); Bit32u getFirstFreeClust(void); bool directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum, Bit32s start=0); bool directoryChange(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum); @@ -200,6 +203,7 @@ private: } allocation; bootstrap bootbuffer; + bool absolute; Bit8u fattype; Bit32u CountOfClusters; Bit32u partSectOff; From 31063f868ad8ee55402862249fd4233cc441922d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 13 Jul 2018 12:11:35 +0000 Subject: [PATCH 4035/4131] disable swap control on all platforms and not just win32. Thanks for testing ny00123 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4132 --- src/gui/sdlmain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index f99ce60b..3213f1c7 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -686,7 +686,7 @@ dosurface: goto dosurface; } SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); -#if defined (WIN32) && SDL_VERSION_ATLEAST(1, 2, 11) +#if SDL_VERSION_ATLEAST(1, 2, 11) SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 0 ); #endif GFX_SetupSurfaceScaled(SDL_OPENGL,0); From 01e3789c49cd69e1f87c9d027692d770c2970111 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sun, 5 Aug 2018 13:28:29 +0000 Subject: [PATCH 4036/4131] Leave attribute controller in index state after a mode change. Some video BIOS do this, some don't, but it works around a flaw in the Kukoo2 demo. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4134 --- src/ints/int10_modes.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index b10f233b..795013e7 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1458,6 +1458,7 @@ dac_text16: /* Set vga attrib register into defined state */ IO_Read(mono_mode ? 0x3ba : 0x3da); IO_Write(0x3c0,0x20); + IO_Read(mono_mode ? 0x3ba : 0x3da); // Kukoo2 demo /* Load text mode font */ if (CurMode->type==M_TEXT) { From dd304cbef1ab9f8ebbdd69b175b02cd45cdf687d Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Fri, 17 Aug 2018 14:28:56 +0000 Subject: [PATCH 4037/4131] Return correct error code for verify sectors function when an invalid drive is specified. Fixes Hugo Troll game installers. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4137 --- src/ints/bios_disk.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index c3683db4..d2afcaa8 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -325,6 +325,8 @@ static Bitu INT13_DiskHandler(void) { //drivenum = 0; //LOG_MSG("INT13: Function %x called on drive %x (dos drive %d)", reg_ah, reg_dl, drivenum); + + // NOTE: the 0xff error code returned in some cases is questionable; 0x01 seems more correct switch(reg_ah) { case 0x0: /* Reset disk */ { @@ -440,7 +442,10 @@ static Bitu INT13_DiskHandler(void) { CALLBACK_SCF(true); return CBRET_NONE; } - if(driveInactive(drivenum)) return CBRET_NONE; + if(driveInactive(drivenum)) { + reg_ah = last_status; + return CBRET_NONE; + } /* TODO: Finish coding this section */ /* From 66fdd8f1de2c135f3f2a90af01597a2d8223c6e4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 21 Aug 2018 11:57:32 +0000 Subject: [PATCH 4038/4131] add a bit of hack to make building a 32 bit binary for Apple a bit easier Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4138 --- configure.ac | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/configure.ac b/configure.ac index 230114eb..09591039 100644 --- a/configure.ac +++ b/configure.ac @@ -302,6 +302,36 @@ case "$host_cpu" in ;; esac +dnl check for size of pointer being 4 +AC_COMPILE_IFELSE([AC_LANG_SOURCE([ +#if SIZEOF_INT_P != 4 +#error size intp is not 4, this not something to worry about +#endif +void blah() { +; +} +])],[c_sizep=4],[c_sizep=0]) + + +dnl automake 1.14 and upwards rewrite the host to have always 64 bit unless i386 as host is passed +dnl this can make building a 32 bit executable a bit tricky, as dosbox relies on the host to select the +dnl dynamic/dynrec core +AC_MSG_CHECKING([whether Apple user wants to override the build process to produce a 32 bit binary]) +case "$host" in + *-*-darwin*) + if test x$c_targetcpu = xx86_64 -a x$c_sizep = x4 ; then + AC_MSG_RESULT(yes) + AC_DEFINE(C_TARGETCPU,X86) + c_targetcpu="x86" + else + AC_MSG_RESULT(no) + fi + ;; + *) + AC_MSG_RESULT([no, not on Apple]) + ;; +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]) From b83172cc6156e8e1dafe60220efbfbeed053dd2e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 23 Aug 2018 15:52:27 +0000 Subject: [PATCH 4039/4131] prefer ncurses above curses (on some systems, these are still different packages) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4139 --- configure.ac | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 09591039..8f3e64bf 100644 --- a/configure.ac +++ b/configure.ac @@ -216,14 +216,14 @@ AC_ARG_ENABLE(debug,AC_HELP_STRING([--enable-debug],[Enable debug mode]),[ 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" + 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_ncurses_lib = xyes -a x$have_curses_h = xyes ; then - LIBS="$LIBS -lncurses" + 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) From 35a46909b5aff9ceb5810795fa99e993e3a4a21e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 Aug 2018 11:50:37 +0000 Subject: [PATCH 4040/4131] forgot to add emu.h Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4140 --- visualc_net/dosbox.vcproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index dcfe14fd..7d62ff31 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -568,6 +568,9 @@ + + From 0463a8b9078bf2dadd877408772200dcb1c9696e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Aug 2018 09:49:07 +0000 Subject: [PATCH 4041/4131] Update tandy sound core to latest (unmerged) mame version. Update tandy sound selection to use the ncr8496 for normal usage and the sn76496 in PCjr mode. Correct noise algorithm. Ignore writes to certain registers if highest bit is not set for ncr8496 mode. Don't reset the noise producing register on all writes, only when changing the type of noise (ncr8496). Fixes intro sound of KQ2, waves in KQ2 and sound on the title screen of sentinel. Thanks for the help Lord_Nightmare. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4141 --- src/hardware/mame/sn76496.cpp | 69 ++++++++++++++++++++++++----------- src/hardware/mame/sn76496.h | 34 ++++++++++++----- src/hardware/tandy_sound.cpp | 11 +++++- 3 files changed, 82 insertions(+), 32 deletions(-) diff --git a/src/hardware/mame/sn76496.cpp b/src/hardware/mame/sn76496.cpp index b2e3be6a..d11f0eaf 100644 --- a/src/hardware/mame/sn76496.cpp +++ b/src/hardware/mame/sn76496.cpp @@ -46,10 +46,12 @@ Noise is an XOR function, and audio output is negated before being output. All the Sega-made PSG chips act as if the frequency was set to 0 if 0 is written to the frequency register. - ** NCR7496 (as used on the Tandy 1000) is similar to the SN76489 but with a - different noise LFSR patttern: taps on bits A and E, output on E + ** NCR8496 (as used on the Tandy 1000) is similar to the SN76489 but with a + different noise LFSR pattern: taps on bits A and E, output on E, XNOR function It uses a 15-bit ring buffer for periodic noise/arbitrary duty cycle. - (all this chip's info needs to be verified) + Its output is inverted. + ** PSSJ-3 (as used on the later Tandy 1000 series computers) is the same as the + NCR8496 with the exception that its output is not inverted. 28/03/2005 : Sebastien Chevalier Update th SN76496Write func, according to SN76489 doc found on SMSPower. @@ -77,7 +79,7 @@ 16/11/2009 : Lord Nightmare Fix screeching in regulus: When summing together four equal channels, the size of the max amplitude per channel should be 1/4 of the max range, not - 1/3. Added NCR7496. + 1/3. Added NCR8496. 18/11/2009 : Lord Nightmare Modify Init functions to support negating the audio output. The gamegear @@ -115,11 +117,21 @@ ValleyBell. Made Sega PSG chips start up with register 0x3 selected (volume for channel 2) based on hardware tests by Nemesis. + 26/08/2018: Lord Nightmare, Qbix, ValleyBell, NewRisingSun + * renamed the NCR8496 to its correct name, based on chip pictures on VGMPF + * fixed NCR8496 behavior on write to mirrored registers; unlike any of the + other variants, the NCR8496 seems to ignore writes to regs 1,3,5,6,7 if 0x80 + is not set. +***TODO: the above is NOT verified yet!*** + * fixed NCR8496's noise lfsr behavior so it is only reset if the mode bit in + register 6 is changed. + * NCR8496's LFSR feedback function is an XNOR, which is now supported + * NCR8496's output is inverted (though PSSJ-3's output is not) + * add PSSJ-3 support for the later Tandy computers. + TODO: * Implement the TMS9919 - any difference to sn94624? * Implement the T6W28; has registers in a weird order, needs writes to be 'sanitized' first. Also is stereo, similar to game gear. - * Test the NCR7496; Smspower says the whitenoise taps are A and E, - but this needs verification on real hardware. * Factor out common code so that the SAA1099 can share some code. ***************************************************************************/ @@ -141,6 +153,7 @@ sn76496_base_device::sn76496_base_device( bool negate, bool stereo, int clockdivider, + bool ncr, bool sega, device_t *owner, uint32_t clock) @@ -153,58 +166,64 @@ sn76496_base_device::sn76496_base_device( , m_negate(negate) , m_stereo(stereo) , m_clock_divider(clockdivider) + , m_ncr_style_psg(ncr) , m_sega_style_psg(sega) { } sn76496_device::sn76496_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : sn76496_base_device(mconfig, SN76496, tag, 0x10000, 0x04, 0x08, false, false, 8, true, owner, clock) + : sn76496_base_device(mconfig, SN76496, tag, 0x10000, 0x04, 0x08, false, false, 8, false, true, owner, clock) { } u8106_device::u8106_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : sn76496_base_device(mconfig, U8106, tag, 0x4000, 0x01, 0x02, true, false, 8, true, owner, clock) + : sn76496_base_device(mconfig, U8106, tag, 0x4000, 0x01, 0x02, true, false, 8, false, true, owner, clock) { } y2404_device::y2404_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : sn76496_base_device(mconfig, Y2404, tag, 0x10000, 0x04, 0x08, false, false, 8, true, owner, clock) + : sn76496_base_device(mconfig, Y2404, tag, 0x10000, 0x04, 0x08, false, false, 8, false, true, owner, clock) { } sn76489_device::sn76489_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : sn76496_base_device(mconfig, SN76489, tag, 0x4000, 0x01, 0x02, true, false, 8, true, owner, clock) + : sn76496_base_device(mconfig, SN76489, tag, 0x4000, 0x01, 0x02, true, false, 8, false, true, owner, clock) { } sn76489a_device::sn76489a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : sn76496_base_device(mconfig, SN76489A, tag, 0x10000, 0x04, 0x08, false, false, 8, true, owner, clock) + : sn76496_base_device(mconfig, SN76489A, tag, 0x10000, 0x04, 0x08, false, false, 8, false, true, owner, clock) { } sn76494_device::sn76494_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : sn76496_base_device(mconfig, SN76494, tag, 0x10000, 0x04, 0x08, false, false, 1, true, owner, clock) + : sn76496_base_device(mconfig, SN76494, tag, 0x10000, 0x04, 0x08, false, false, 1, false, true, owner, clock) { } sn94624_device::sn94624_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : sn76496_base_device(mconfig, SN94624, tag, 0x4000, 0x01, 0x02, true, false, 1, true, owner, clock) + : sn76496_base_device(mconfig, SN94624, tag, 0x4000, 0x01, 0x02, true, false, 1, false, true, owner, clock) { } -ncr7496_device::ncr7496_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : sn76496_base_device(mconfig, NCR7496, tag, 0x8000, 0x02, 0x20, false, false, 8, true, owner, clock) +ncr8496_device::ncr8496_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sn76496_base_device(mconfig, NCR8496, tag, 0x8000, 0x02, 0x20, true, false, 8, true, true, owner, clock) +{ +} + +pssj3_device::pssj3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sn76496_base_device(mconfig, PSSJ3, tag, 0x8000, 0x02, 0x20, false, false, 8, true, true, owner, clock) { } gamegear_device::gamegear_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : sn76496_base_device(mconfig, GAMEGEAR, tag, 0x8000, 0x01, 0x08, true, true, 8, false, owner, clock) + : sn76496_base_device(mconfig, GAMEGEAR, tag, 0x8000, 0x01, 0x08, true, true, 8, false, false, owner, clock) { } segapsg_device::segapsg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : sn76496_base_device(mconfig, SEGAPSG, tag, 0x8000, 0x01, 0x08, true, false, 8, false, owner, clock) + : sn76496_base_device(mconfig, SEGAPSG, tag, 0x8000, 0x01, 0x08, true, false, 8, false, false, owner, clock) { } @@ -271,6 +290,11 @@ void sn76496_base_device::device_start() //register_for_save_states(); } +void sn76496_base_device::device_clock_changed() +{ +// m_sound->set_sample_rate(clock()/2); +} + WRITE8_MEMBER( sn76496_base_device::stereo_w ) { // m_sound->update(); @@ -293,11 +317,13 @@ void sn76496_base_device::write(uint8_t data) { r = (data & 0x70) >> 4; m_last_register = r; + if (((m_ncr_style_psg) && (r == 6)) && ((data&0x04) != (m_register[6]&0x04))) m_RNG = m_feedback_mask; m_register[r] = (m_register[r] & 0x3f0) | (data & 0x0f); } else { r = m_last_register; + if ((m_ncr_style_psg) && ((r & 1) || (r == 6))) return; // NCR8496 ignores writes to regs 1, 3, 5, 6 and 7 with bit 7 clear } c = r >> 1; @@ -330,7 +356,7 @@ void sn76496_base_device::write(uint8_t data) n = m_register[6]; // N/512,N/1024,N/2048,Tone #3 output m_period[3] = ((n&3) == 3)? (m_period[2]<<1) : (1 << (5+(n&3))); - m_RNG = m_feedback_mask; + if (!(m_ncr_style_psg)) m_RNG = m_feedback_mask; } break; } @@ -365,7 +391,7 @@ void sn76496_base_device::sound_stream_update(sound_stream &stream, stream_sampl { int i; stream_sample_t *lbuffer = outputs[0]; - stream_sample_t *rbuffer = (m_stereo)? outputs[1] : 0; + stream_sample_t *rbuffer = (m_stereo)? outputs[1] : 0;//nullptr; int16_t out; int16_t out2 = 0; @@ -401,7 +427,7 @@ void sn76496_base_device::sound_stream_update(sound_stream &stream, stream_sampl // if noisemode is 1, both taps are enabled // if noisemode is 0, the lower tap, whitenoisetap2, is held at 0 // The != was a bit-XOR (^) before - if (((m_RNG & m_whitenoise_tap1)!=0) != (((m_RNG & m_whitenoise_tap2)!=0) && in_noise_mode())) + if (((m_RNG & m_whitenoise_tap1)!=0) != (((m_RNG & m_whitenoise_tap2)!=(m_ncr_style_psg?m_whitenoise_tap2:0)) && in_noise_mode())) { m_RNG >>= 1; m_RNG |= m_feedback_mask; @@ -485,7 +511,8 @@ DEFINE_DEVICE_TYPE(SN76489, sn76489_device, "sn76489", "SN76489") DEFINE_DEVICE_TYPE(SN76489A, sn76489a_device, "sn76489a", "SN76489A") DEFINE_DEVICE_TYPE(SN76494, sn76494_device, "sn76494", "SN76494") DEFINE_DEVICE_TYPE(SN94624, sn94624_device, "sn94624", "SN94624") -DEFINE_DEVICE_TYPE(NCR7496, ncr7496_device, "ncr7496", "NCR7496") +DEFINE_DEVICE_TYPE(NCR8496, ncr8496_device, "ncr8496", "NCR8496") +DEFINE_DEVICE_TYPE(PSSJ3, pssj3_device, "pssj3", "PSSJ-3") DEFINE_DEVICE_TYPE(GAMEGEAR, gamegear_device, "gamegear_psg", "Game Gear PSG") DEFINE_DEVICE_TYPE(SEGAPSG, segapsg_device, "segapsg", "Sega VDP PSG") diff --git a/src/hardware/mame/sn76496.h b/src/hardware/mame/sn76496.h index a2bdb993..b464ba78 100644 --- a/src/hardware/mame/sn76496.h +++ b/src/hardware/mame/sn76496.h @@ -13,7 +13,8 @@ DECLARE_DEVICE_TYPE(SN76489, sn76489_device) DECLARE_DEVICE_TYPE(SN76489A, sn76489a_device) DECLARE_DEVICE_TYPE(SN76494, sn76494_device) DECLARE_DEVICE_TYPE(SN94624, sn94624_device) -DECLARE_DEVICE_TYPE(NCR7496, ncr7496_device) +DECLARE_DEVICE_TYPE(NCR8496, ncr8496_device) +DECLARE_DEVICE_TYPE(PSSJ3, pssj3_device) DECLARE_DEVICE_TYPE(GAMEGEAR, gamegear_device) DECLARE_DEVICE_TYPE(SEGAPSG, segapsg_device) @@ -21,22 +22,23 @@ DECLARE_DEVICE_TYPE(SEGAPSG, segapsg_device) #define MCFG_SN76496_READY_HANDLER(cb) \ - devcb = &sn76496_base_device::set_ready_handler(*device, (DEVCB_##cb)); + downcast(*device).set_ready_handler((DEVCB_##cb)); #endif class sn76496_base_device : public device_t, public device_sound_interface { public: - // static configuration helpers -// template static devcb_base &set_ready_handler(device_t &device, Object &&cb) { return downcast(device).m_ready_handler.set_callback(std::forward(cb)); } + // configuration helpers +// template devcb_base &set_ready_handler(Object &&cb) { return m_ready_handler.set_callback(std::forward(cb)); } DECLARE_WRITE8_MEMBER( stereo_w ); void write(uint8_t data); DECLARE_WRITE8_MEMBER( write ); // DECLARE_READ_LINE_MEMBER( ready_r ) { return m_ready_state ? 1 : 0; } +// auto ready_cb() { return m_ready_handler.bind(); } - void convert_samplerate(int32_t target_rate); + void convert_samplerate(int32_t target_rate); protected: sn76496_base_device( const machine_config &mconfig, @@ -48,11 +50,13 @@ protected: bool negate, bool stereo, int clockdivider, + bool ncr, bool sega, device_t *owner, uint32_t clock); virtual void device_start(); + virtual void device_clock_changed(); virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); private: @@ -74,7 +78,8 @@ private: const bool m_negate; // output negate flag const bool m_stereo; // whether we're dealing with stereo or not const int32_t m_clock_divider; // clock divider - const bool m_sega_style_psg; // flag for if frequency zero acts as if it is one more than max (0x3ff+1) or if it acts like 0; AND if the initial register is pointing to 0x3 instead of 0x0 AND if the volume reg is preloaded with 0xF instead of 0x0 + const bool m_ncr_style_psg; // flag to ignore writes to regs 1,3,5,6,7 with bit 7 low + const bool m_sega_style_psg; // flag to make frequency zero acts as if it is one more than max (0x3ff+1) or if it acts like 0; the initial register is pointing to 0x3 instead of 0x0; the volume reg is preloaded with 0xF instead of 0x0 int32_t m_vol_table[16]; // volume table (for 4-bit to db conversion) int32_t m_register[8]; // registers @@ -87,6 +92,7 @@ private: int32_t m_count[4]; // Position within the waveform int32_t m_output[4]; // 1-bit output of each channel, pre-volume int32_t m_cycles_to_ready; // number of cycles until the READY line goes active + //Modifications for easier sample conversion int32_t sample_rate; //Sample rate conversion @@ -115,13 +121,21 @@ public: y2404_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; -// SN76489 not verified yet. todo: verify; +// NCR8496 whitenoise verified, phase verified; verified by ValleyBell & NewRisingSun class sn76489_device : public sn76496_base_device { public: sn76489_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; +// PSSJ-3 whitenoise verified, phase verified; verified by ValleyBell & NewRisingSun +class pssj3_device : public sn76496_base_device +{ +public: + pssj3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + + // SN76489A: whitenoise verified, phase verified, periodic verified (by plgdavid) class sn76489a_device : public sn76496_base_device { @@ -143,11 +157,11 @@ public: sn94624_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; -// NCR7496 not verified; info from smspower wiki -class ncr7496_device : public sn76496_base_device +// NCR8496 not verified; info from smspower wiki and vgmpf wiki +class ncr8496_device : public sn76496_base_device { public: - ncr7496_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + ncr8496_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; // Verified by Justin Kerk diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 99cc79b6..7e29739e 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -63,8 +63,11 @@ static struct { } dac; } tandy; -static sn76496_device device(machine_config(), 0, 0, SOUND_CLOCK ); +static sn76496_device device_sn76496(machine_config(), 0, 0, SOUND_CLOCK ); +static ncr8496_device device_ncr8496(machine_config(), 0, 0, SOUND_CLOCK); +static sn76496_base_device* activeDevice = &device_ncr8496; +#define device (*activeDevice) static void SN76496Write(Bitu /*port*/,Bitu data,Bitu /*iolen*/) { tandy.last_write=PIC_Ticks; @@ -73,6 +76,8 @@ static void SN76496Write(Bitu /*port*/,Bitu data,Bitu /*iolen*/) { tandy.enabled=true; } device.write(data); + +// LOG_MSG("3voice write %X at time %7.3f",data,PIC_FullIndex()); } static void SN76496Update(Bitu length) { @@ -271,6 +276,10 @@ public: enable_hw_tandy_dac=false; } + //Select the correct tandy chip implementation + if (machine == MCH_PCJR) activeDevice = &device_sn76496; + else activeDevice = &device_ncr8496; + real_writeb(0x40,0xd4,0x00); if (IS_TANDY_ARCH) { /* enable tandy sound if tandy=true/auto */ From 53b67e88710bb4c550e698dfba1183488691fe36 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Aug 2018 11:08:37 +0000 Subject: [PATCH 4042/4131] Update logging function to log in debug mode Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4142 --- src/hardware/mame/emu.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/hardware/mame/emu.h b/src/hardware/mame/emu.h index ab0fae59..6f154995 100644 --- a/src/hardware/mame/emu.h +++ b/src/hardware/mame/emu.h @@ -94,7 +94,15 @@ public: return clockRate; } - void logerror(const char* msg, ...) { + void logerror(const char* format, ...) { +#if C_DEBUG + char buf[512*2]; + va_list msg; + va_start(msg,format); + vsprintf(buf,format,msg); + va_end(msg); + LOG(LOG_MISC,LOG_NORMAL)("%s",buf); +#endif } static int tag() { From 97ac94d222add46a4bd1bed7301a0fb5d581b434 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Aug 2018 15:40:02 +0000 Subject: [PATCH 4043/4131] document suggestion to change scaler or fullresolution if you don't like the black bars or border Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4144 --- src/dosbox.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index a5012665..8f379422 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -448,12 +448,14 @@ void DOSBOX_Init(void) { Pint->Set_help("How many frames DOSBox skips before drawing one."); Pbool = secprop->Add_bool("aspect",Property::Changeable::Always,false); - Pbool->Set_help("Do aspect correction, if your output method doesn't support scaling this can slow things down!."); + Pbool->Set_help("Do aspect correction, if your output method doesn't support scaling this can slow things down!"); Pmulti = secprop->Add_multi("scaler",Property::Changeable::Always," "); Pmulti->SetValue("normal2x"); Pmulti->Set_help("Scaler used to enlarge/enhance low resolution modes. If 'forced' is appended,\n" - "then the scaler will be used even if the result might not be desired."); + "then the scaler will be used even if the result might not be desired.\n" + "To fit a scaler in the resolution used at full screen may require a border or side bars,\n" + "to fill the screen entirely, depending on your hardware, a different scaler/fullresolution might work."); Pstring = Pmulti->GetSection()->Add_string("type",Property::Changeable::Always,"normal2x"); const char *scalers[] = { From 01e0a45694aaeb6ac72c587166ee9b775b5a2861 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Aug 2018 08:30:44 +0000 Subject: [PATCH 4044/4131] Use old style call to get window resolution on windows, fixes part of fullscreen being too large with no manifest and dpiscaling active. Can still go wrong though. dpiscaling is just bad news for dosbox overall. disabling it gives bad results as well for big screens..... Add opengl window centering for fullresolution=original.. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4147 --- src/gui/sdlmain.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 3213f1c7..be5fcd0c 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -704,7 +704,14 @@ dosurface: sdl.opengl.framebuf=malloc(width*height*4); //32 bit color } sdl.opengl.pitch=width*4; - glViewport(sdl.clip.x,sdl.clip.y,sdl.clip.w,sdl.clip.h); + + if(sdl.clip.x ==0 && sdl.clip.y ==0 && sdl.desktop.fullscreen && !sdl.desktop.full.fixed && (sdl.clip.w != sdl.surface->w || sdl.clip.h != sdl.surface->h)) { +// LOG_MSG("attempting to fix the centering to %d %d %d %d",(sdl.surface->w-sdl.clip.w)/2,(sdl.surface->h-sdl.clip.h)/2,sdl.clip.w,sdl.clip.h); + glViewport((sdl.surface->w-sdl.clip.w)/2,(sdl.surface->h-sdl.clip.h)/2,sdl.clip.w,sdl.clip.h); + } else { + glViewport(sdl.clip.x,sdl.clip.y,sdl.clip.w,sdl.clip.h); + } + glMatrixMode (GL_PROJECTION); glDeleteTextures(1,&sdl.opengl.texture); glGenTextures(1,&sdl.opengl.texture); @@ -1239,7 +1246,7 @@ static void GUI_StartUp(Section * sec) { } } sdl.desktop.doublebuf=section->Get_bool("fulldouble"); -#if SDL_VERSION_ATLEAST(1, 2, 10) +#if SDL_VERSION_ATLEAST(1, 2, 10) && !defined(WIN32) if (!sdl.desktop.full.width || !sdl.desktop.full.height){ //Can only be done on the very first call! Not restartable. const SDL_VideoInfo* vidinfo = SDL_GetVideoInfo(); From b24425dfa48e06c9c1f99de6a940e0a865f1be0f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Aug 2018 11:48:53 +0000 Subject: [PATCH 4045/4131] Give a warning at startup if dpi scaling is detected. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4149 --- src/gui/sdlmain.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index be5fcd0c..bec728de 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1246,9 +1246,22 @@ static void GUI_StartUp(Section * sec) { } } sdl.desktop.doublebuf=section->Get_bool("fulldouble"); -#if SDL_VERSION_ATLEAST(1, 2, 10) && !defined(WIN32) +#if SDL_VERSION_ATLEAST(1, 2, 10) +#ifdef WIN32 + const SDL_VideoInfo* vidinfo = SDL_GetVideoInfo(); + if (vidinfo) { + int sdl_w = vidinfo->current_w; + int sdl_h = vidinfo->current_h; + int win_w = GetSystemMetrics(SM_CXSCREEN); + int win_h = GetSystemMetrics(SM_CYSCREEN); + if (sdl_w != win_w && sdl_h != win_h) + LOG_MSG("Windows dpi/blurry apps scaling detected! The screen might be too large or not show properly,\n" + "please see the DOSBox Manual/README for details.\n"); + } +#else if (!sdl.desktop.full.width || !sdl.desktop.full.height){ //Can only be done on the very first call! Not restartable. + //On windows don't use it as SDL returns the values without taking in account the dpi scaling const SDL_VideoInfo* vidinfo = SDL_GetVideoInfo(); if (vidinfo) { sdl.desktop.full.width = vidinfo->current_w; From 3f7c70b2ad74db8c15915e3af5436f0508546a85 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 28 Aug 2018 11:59:41 +0000 Subject: [PATCH 4046/4131] Keep it compiling. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4150 --- src/gui/sdlmain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index bec728de..4aa4fd4b 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1268,6 +1268,7 @@ static void GUI_StartUp(Section * sec) { sdl.desktop.full.height = vidinfo->current_h; } } +#endif #endif if (!sdl.desktop.full.width) { From e524d0f1c2ec4f0a701a80bffdab41e8444c5fe0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 31 Aug 2018 17:43:09 +0000 Subject: [PATCH 4047/4131] "All Programs"->DOSBox-0.74->Extras + (Windows) "Start/WinLogo Menu"->"All Programs"->"DOSBox-0.74-2"->Extras (Linux) ~/.dosbox/capture (Mac OS X) "~/Library/Preferences/capture" This can be changed in the DOSBox configuration file. @@ -1252,7 +1273,7 @@ Layout switching in this case just the layout identifier needs to be specified (like keyboardlayout=PL214 in the DOSBox configuration file, or using "keyb PL214" at the DOSBox command prompt). The list of all layouts built into DOSBox is - here: http://vogons.zetafleet.com/viewtopic.php?t=21824 + here: https://www.vogons.org/viewtopic.php?t=21824 Some keyboard layouts (for example layout GK319 codepage 869 and layout RU441 codepage 808) have support for dual layouts that can be accessed by pressing @@ -1487,9 +1508,9 @@ To display the DOSBox status window: The configuration file is automatically created the first time you run DOSBox. The file can be found in: - (Windows) "Start/WinLogo Menu"->"All Programs"->DOSBox-0.74->Options - (Linux) ~/.dosbox/dosbox-0.74.conf - (Mac OS X) "~/Library/Preferences/DOSBox 0.74 Preferences" + (Windows) "Start/WinLogo Menu"->"All Programs"->"DOSBox-0.74-2"->Options + (Linux) ~/.dosbox/dosbox-0.74-2.conf + (Mac OS X) "~/Library/Preferences/DOSBox 0.74-2 Preferences" The file is divided into several sections. Each section starts with a [section name] line. The settings are the property=value lines where value can be altered to customize DOSBox. @@ -1550,7 +1571,7 @@ See the THANKS file. ============ See the site: -http://www.dosbox.com +https://www.dosbox.com for an email address (The Crew-page). diff --git a/VERSION b/VERSION index 3ea25f59..a6e956f0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.74 +0.74-2 diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 4aa4fd4b..c4f65e27 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1255,8 +1255,8 @@ static void GUI_StartUp(Section * sec) { int win_w = GetSystemMetrics(SM_CXSCREEN); int win_h = GetSystemMetrics(SM_CYSCREEN); if (sdl_w != win_w && sdl_h != win_h) - LOG_MSG("Windows dpi/blurry apps scaling detected! The screen might be too large or not show properly,\n" - "please see the DOSBox Manual/README for details.\n"); + LOG_MSG("Windows dpi/blurry apps scaling detected! The screen might be too large or not\n" + "show properly, please see the DOSBox options file (fullresolution) for details.\n"); } #else if (!sdl.desktop.full.width || !sdl.desktop.full.height){ @@ -1712,7 +1712,9 @@ void Config_Add_SDL() { Pstring = sdl_sec->Add_string("fullresolution",Property::Changeable::Always,"original"); Pstring->Set_help("What resolution to use for fullscreen: original, desktop or a fixed size (e.g. 1024x768).\n" " Using your monitor's native resolution with aspect=true might give the best results.\n" - " If you end up with small window on a large screen, try an output different from surface."); + " If you end up with small window on a large screen, try an output different from surface." + " On Windows 10 with display scaling (Scale and layout) set to a value above 100%, it is recommended\n" + " to use a lower full/windowresolution, in order to avoid window size problems."); Pstring = sdl_sec->Add_string("windowresolution",Property::Changeable::Always,"original"); Pstring->Set_help("Scale the window to this size IF the output device supports hardware scaling.\n" From bece575aff3c07fc1725fcd8f86d62bf424fbfd7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 4 Sep 2018 09:43:50 +0000 Subject: [PATCH 4048/4131] Fix compilation Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4158 --- src/hardware/mame/emu.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/hardware/mame/emu.h b/src/hardware/mame/emu.h index 6f154995..85a9dd86 100644 --- a/src/hardware/mame/emu.h +++ b/src/hardware/mame/emu.h @@ -13,6 +13,11 @@ #include #include +#if C_DEBUG +#include +#include +#endif + #ifndef M_PI #define M_PI 3.14159265358979323846 #endif From 5dfa75399eded2aaa23ec485618dfa435c55c482 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 4 Sep 2018 12:58:09 +0000 Subject: [PATCH 4049/4131] Show segment override on XLAT instruction. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4159 --- src/debug/debug_disasm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debug/debug_disasm.cpp b/src/debug/debug_disasm.cpp index 6d8d5bc8..51155ed9 100644 --- a/src/debug/debug_disasm.cpp +++ b/src/debug/debug_disasm.cpp @@ -246,7 +246,7 @@ static char const * op386map1[256] = { "int 03", "int %Ib", "into", "iret", /* d */ "%g1 %Eb,1", "%g1 %Ev,1", "%g1 %Eb,cl", "%g1 %Ev,cl", - "aam ; %Ib", "aad ; %Ib", "setalc", "xlat", + "aam ; %Ib", "aad ; %Ib", "setalc", "%P xlat", #if 0 "esc 0,%Ib", "esc 1,%Ib", "esc 2,%Ib", "esc 3,%Ib", "esc 4,%Ib", "esc 5,%Ib", "esc 6,%Ib", "esc 7,%Ib", From 1ff6911b3cf02c46f74431a89db4281d0728614b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 4 Sep 2018 13:51:09 +0000 Subject: [PATCH 4050/4131] Let all multiline comments jump in. Pretty up value blocks Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4160 --- src/dosbox.cpp | 14 +++++++------- src/gui/sdlmain.cpp | 12 ++++++------ src/misc/setup.cpp | 13 ++++++++++--- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 8f379422..966b0b42 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -433,9 +433,9 @@ void DOSBOX_Init(void) { Pint->SetMinMax(1,63); Pint->Set_help( "Amount of memory DOSBox has in megabytes.\n" - " This value is best left at its default to avoid problems with some games,\n" - " though few games might require a higher value.\n" - " There is generally no speed advantage when raising this value."); + "This value is best left at its default to avoid problems with some games,\n" + "though few games might require a higher value.\n" + "There is generally no speed advantage when raising this value."); secprop->AddInitFunction(&CALLBACK_Init); secprop->AddInitFunction(&PIC_Init);//done secprop->AddInitFunction(&PROGRAMS_Init); @@ -564,10 +564,10 @@ void DOSBOX_Init(void) { Pstring = secprop->Add_string("midiconfig",Property::Changeable::WhenIdle,""); Pstring->Set_help("Special configuration options for the device driver. This is usually the id or part of the name of the device you want to use (find the id/name with mixer/listmidi).\n" - " Or in the case of coreaudio, you can specify a soundfont here.\n" - " When using a Roland MT-32 rev. 0 as midi output device, some games may require a delay in order to prevent 'buffer overflow' issues.\n" - " In that case, add 'delaysysex', for example: midiconfig=2 delaysysex\n" - " See the README/Manual for more details."); + "Or in the case of coreaudio, you can specify a soundfont here.\n" + "When using a Roland MT-32 rev. 0 as midi output device, some games may require a delay in order to prevent 'buffer overflow' issues.\n" + "In that case, add 'delaysysex', for example: midiconfig=2 delaysysex\n" + "See the README/Manual for more details."); #if C_DEBUG secprop=control->AddSection_prop("debug",&DEBUG_Init); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index c4f65e27..f64f8910 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1711,14 +1711,14 @@ void Config_Add_SDL() { Pstring = sdl_sec->Add_string("fullresolution",Property::Changeable::Always,"original"); Pstring->Set_help("What resolution to use for fullscreen: original, desktop or a fixed size (e.g. 1024x768).\n" - " Using your monitor's native resolution with aspect=true might give the best results.\n" - " If you end up with small window on a large screen, try an output different from surface." - " On Windows 10 with display scaling (Scale and layout) set to a value above 100%, it is recommended\n" - " to use a lower full/windowresolution, in order to avoid window size problems."); + "Using your monitor's native resolution with aspect=true might give the best results.\n" + "If you end up with small window on a large screen, try an output different from surface." + "On Windows 10 with display scaling (Scale and layout) set to a value above 100%, it is recommended\n" + "to use a lower full/windowresolution, in order to avoid window size problems."); Pstring = sdl_sec->Add_string("windowresolution",Property::Changeable::Always,"original"); Pstring->Set_help("Scale the window to this size IF the output device supports hardware scaling.\n" - " (output=surface does not!)"); + "(output=surface does not!)"); const char* outputs[] = { "surface", "overlay", @@ -1746,7 +1746,7 @@ void Config_Add_SDL() { Pmulti = sdl_sec->Add_multi("priority", Property::Changeable::Always, ","); Pmulti->SetValue("higher,normal"); Pmulti->Set_help("Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized.\n" - " pause is only valid for the second entry."); + "pause is only valid for the second entry."); const char* actt[] = { "lowest", "lower", "normal", "higher", "highest", "pause", 0}; Pstring = Pmulti->GetSection()->Add_string("active",Property::Changeable::Always,"higher"); diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 2843652b..3df23b83 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -634,8 +634,15 @@ bool Section_prop::HandleInputline(string const& gegevens){ void Section_prop::PrintData(FILE* outfile) const { /* Now print out the individual section entries */ - for(const_it tel=properties.begin();tel!=properties.end();tel++){ - fprintf(outfile,"%s=%s\n",(*tel)->propname.c_str(),(*tel)->GetValue().ToString().c_str()); + size_t len = 0; + // Determine maximum length of the props in this section + for(const_it tel = properties.begin();tel != properties.end();tel++) { + if ((*tel)->propname.length() > len) + len = (*tel)->propname.length(); + } + + for(const_it tel = properties.begin();tel != properties.end();tel++) { + fprintf(outfile,"%-*s = %s\n", len, (*tel)->propname.c_str(), (*tel)->GetValue().ToString().c_str()); } } @@ -686,7 +693,7 @@ bool Config::PrintConfig(char const * const configfilename) const { } i=0; char prefix[80]; - snprintf(prefix,80, "\n# %*s ", (int)maxwidth, ""); + snprintf(prefix,80, "\n# %*s ", (int)maxwidth, ""); while ((p = sec->Get_prop(i++))) { std::string help = p->Get_help(); std::string::size_type pos = std::string::npos; From 2f09b52de8ba053443a884fd940f6d17f0eb19f5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 14 Sep 2018 19:53:55 +0000 Subject: [PATCH 4051/4131] Fix typos reported by lintian and change DosBox to DOSBox. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4161 --- acinclude.m4 | 2 +- src/cpu/core_dyn_x86/cache.h | 4 ++-- src/cpu/core_dynrec/cache.h | 2 +- src/dos/drive_fat.cpp | 2 +- src/hardware/ipx.cpp | 16 ++++++++-------- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 3daa102e..69adc0f0 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -144,7 +144,7 @@ int main (int argc, char *argv[]) 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 "*** exact error that occurred. 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" diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index ca96bef8..71a6513d 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -517,7 +517,7 @@ static void cache_init(bool enable) { #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!"); + LOG_MSG("Setting execute permission on the code cache has failed!"); #endif CacheBlock * block=cache_getblock(); cache.block.first=block; @@ -612,7 +612,7 @@ static void cache_reset(void) { #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!"); + LOG_MSG("Setting execute permission on the code cache has failed!"); #endif } diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index b1f705c7..4158ff31 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -603,7 +603,7 @@ static void cache_init(bool enable) { #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"); + LOG_MSG("Setting execute permission on the code cache has failed"); #endif CacheBlockDynRec * block=cache_getblock(); cache.block.first=block; diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index a58ae1e7..1332285f 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -737,7 +737,7 @@ fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, } } - if(m==4) LOG_MSG("No good partiton found in image."); + if(m==4) LOG_MSG("No good partition found in image."); partSectOff = startSector; } else { diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index 58317cdb..d9379557 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -854,7 +854,7 @@ public: // Help on connect command if(strcasecmp("connect", helpStr) == 0) { WriteOut("IPXNET CONNECT opens a connection to an IPX tunneling server running on another\n"); - WriteOut("DosBox session. The \"address\" parameter specifies the IP address or host name\n"); + WriteOut("DOSBox session. The \"address\" parameter specifies the IP address or host name\n"); WriteOut("of the server computer. One can also specify the UDP port to use. By default\n"); WriteOut("IPXNET uses port 213, the assigned IANA port for IPX tunneling, for its\nconnection.\n\n"); WriteOut("The syntax for IPXNET CONNECT is:\n\n"); @@ -870,9 +870,9 @@ public: } // Help on the startserver command if(strcasecmp("startserver", helpStr) == 0) { - WriteOut("IPXNET STARTSERVER starts and IPX tunneling server on this DosBox session. By\n"); + WriteOut("IPXNET STARTSERVER starts and IPX tunneling server on this DOSBox session. By\n"); WriteOut("default, the server will accept connections on UDP port 213, though this can be\n"); - WriteOut("changed. Once the server is started, DosBox will automatically start a client\n"); + WriteOut("changed. Once the server is started, DOSBox will automatically start a client\n"); WriteOut("connection to the IPX tunneling server.\n\n"); WriteOut("The syntax for IPXNET STARTSERVER is:\n\n"); WriteOut("IPXNET STARTSERVER \n\n"); @@ -880,9 +880,9 @@ public: } // Help on the stop server command if(strcasecmp("stopserver", helpStr) == 0) { - WriteOut("IPXNET STOPSERVER stops the IPX tunneling server running on this DosBox\nsession."); + WriteOut("IPXNET STOPSERVER stops the IPX tunneling server running on this DOSBox\nsession."); WriteOut(" Care should be taken to ensure that all other connections have\nterminated "); - WriteOut("as well sinnce stoping the server may cause lockups on other\nmachines still using "); + WriteOut("as well since stopping the server may cause lockups on other\nmachines still using "); WriteOut("the IPX tunneling server.\n\n"); WriteOut("The syntax for IPXNET STOPSERVER is:\n\n"); WriteOut("IPXNET STOPSERVER\n\n"); @@ -899,7 +899,7 @@ public: } // Help on the status command if(strcasecmp("status", helpStr) == 0) { - WriteOut("IPXNET STATUS reports the current state of this DosBox's sessions IPX tunneling\n"); + WriteOut("IPXNET STATUS reports the current state of this DOSBox's sessions IPX tunneling\n"); WriteOut("network. For a list of the computers connected to the network use the IPXNET \n"); WriteOut("PING command.\n\n"); WriteOut("The syntax for IPXNET STATUS is:\n\n"); @@ -910,7 +910,7 @@ public: void Run(void) { - WriteOut("IPX Tunneling utility for DosBox\n\n"); + WriteOut("IPX Tunneling utility for DOSBox\n\n"); if(!cmd->GetCount()) { WriteOut("The syntax of this command is:\n\n"); WriteOut("IPXNET [ CONNECT | DISCONNECT | STARTSERVER | STOPSERVER | PING | HELP |\n STATUS ]\n\n"); @@ -960,7 +960,7 @@ public: } if(strcasecmp("stopserver", temp_line.c_str()) == 0) { if(!isIpxServer) { - WriteOut("IPX Tunneling Server not running in this DosBox session.\n"); + WriteOut("IPX Tunneling Server not running in this DOSBox session.\n"); } else { isIpxServer = false; DisconnectFromServer(false); From c0d49b28e593f81babd7b90b36b8fedf7a71b141 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 14 Sep 2018 19:59:05 +0000 Subject: [PATCH 4052/4131] Change scan3x to be LINE LINE DARK instead of LINE DARK DARK. This matches pictures of scanlines better and doubles the brightness as the old implementation was rather dark. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4162 --- src/gui/render_templates.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index 59c08874..e1c1ddbd 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -382,9 +382,9 @@ static void conc3d(Cache,SBPP,DBPP) (const void * s) { line0[0]=P; \ line0[1]=P; \ line0[2]=P; \ - line1[0]=0; \ - line1[1]=0; \ - line1[2]=0; \ + line1[0]=P; \ + line1[1]=P; \ + line1[2]=P; \ line2[0]=0; \ line2[1]=0; \ line2[2]=0; From bfd322cff7aee206374d809ce1857575c5a05130 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 21 Sep 2018 08:53:03 +0000 Subject: [PATCH 4053/4131] Make it possible to compile without png support. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4163 --- configure.ac | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 8f3e64bf..fb8d28fb 100644 --- a/configure.ac +++ b/configure.ac @@ -417,13 +417,20 @@ else fi AH_TEMPLATE(C_SSHOT,[Define to 1 to enable screenshots, requires libpng]) +AC_ARG_ENABLE(screenshots,AC_HELP_STRING([--disable-screenshots],[Disable screenshots and movie recording]),,enable_screenshots=yes) AC_CHECK_HEADER(png.h,have_png_h=yes,) AC_CHECK_LIB(png, png_get_io_ptr, 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) +AC_MSG_CHECKING([whether screenshots will be enabled]) +if test x$enable_screenshots = xyes; then + if test x$have_png_lib = xyes -a x$have_png_h = xyes ; then + LIBS="$LIBS -lpng -lz" + AC_DEFINE(C_SSHOT,1) + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no, can't find libpng.]) + fi else - AC_MSG_WARN([Can't find libpng, screenshot support disabled]) + AC_MSG_RESULT([no]) fi AH_TEMPLATE(C_MODEM,[Define to 1 to enable internal modem support, requires SDL_net]) From 52d5501842652c56faa1ab3e4a0901ae1e30e1a3 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Thu, 27 Sep 2018 20:07:06 +0000 Subject: [PATCH 4054/4131] Disable UMB on PCjr machine type; fixes broken MCB chain. Remove 128k PCjr faking from r2417 that was effectively disabled by r3420. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4164 --- src/dos/dos_execute.cpp | 8 -------- src/dos/dos_memory.cpp | 13 +++---------- src/dos/dos_programs.cpp | 4 +--- 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index ba02cc51..b27decdb 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -356,14 +356,6 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { maxsize=0xffff; /* resize to full extent of memory block */ DOS_ResizeMemory(pspseg,&maxsize); - /* now try to lock out memory above segment 0x2000 */ - if ((real_readb(0x2000,0)==0x5a) && (real_readw(0x2000,1)==0) && (real_readw(0x2000,3)==0x7ffe)) { - /* MCB after PCJr graphics memory region is still free */ - if (pspseg+maxsize==0x17ff) { - DOS_MCB cmcb((Bit16u)(pspseg-1)); - cmcb.SetType(0x5a); // last block - } - } } loadseg=pspseg+16; if (!iscom) { diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index 8cdd810f..b8d6a33f 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -50,14 +50,7 @@ void DOS_FreeProcessMemory(Bit16u pspseg) { if (mcb.GetPSPSeg()==pspseg) { mcb.SetPSPSeg(MCB_FREE); } - if (mcb.GetType()==0x5a) { - /* check if currently last block reaches up to the PCJr graphics memory */ - if ((machine==MCH_PCJR) && (mcb_segment+mcb.GetSize()==0x17fe) && - (real_readb(0x17ff,0)==0x4d) && (real_readw(0x17ff,1)==8)) { - /* re-enable the memory past segment 0x2000 */ - mcb.SetType(0x4d); - } else break; - } + if (mcb.GetType()==0x5a) break; if (GCC_UNLIKELY(mcb.GetType()!=0x4d)) E_Exit("Corrupt MCB chain"); mcb_segment+=mcb.GetSize()+1; mcb.SetPt(mcb_segment); @@ -307,10 +300,10 @@ bool DOS_FreeMemory(Bit16u segment) { void DOS_BuildUMBChain(bool umb_active,bool ems_active) { - if (umb_active && (machine!=MCH_TANDY)) { + if (umb_active && (!IS_TANDY_ARCH)) { Bit16u first_umb_seg = 0xd000; Bit16u first_umb_size = 0x2000; - if(ems_active || (machine == MCH_PCJR)) first_umb_size = 0x1000; + if(ems_active) first_umb_size = 0x1000; dos_infoblock.SetStartOfUMBChain(UMB_START_SEG); dos_infoblock.SetUMBChainState(0); // UMBs not linked yet diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 41853a30..f2231815 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -441,9 +441,7 @@ public: Bit16u seg,blocks;blocks=0xffff; DOS_AllocateMemory(&seg,&blocks); - if ((machine==MCH_PCJR) && (real_readb(0x2000,0)==0x5a) && (real_readw(0x2000,1)==0) && (real_readw(0x2000,3)==0x7ffe)) { - WriteOut(MSG_Get("PROGRAM_MEM_CONVEN"),0x7ffe*16/1024); - } else WriteOut(MSG_Get("PROGRAM_MEM_CONVEN"),blocks*16/1024); + WriteOut(MSG_Get("PROGRAM_MEM_CONVEN"),blocks*16/1024); if (umb_start!=0xffff) { DOS_LinkUMBsToMemChain(1); From f522e81d326470a24cb974f67975930b45c21e14 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 29 Sep 2018 16:17:36 +0000 Subject: [PATCH 4055/4131] Quick fix for dma channel 0 having no page porthandler. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4165 --- include/dma.h | 4 ++-- src/hardware/dma.cpp | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/include/dma.h b/include/dma.h index a0624329..196e4b4a 100644 --- a/include/dma.h +++ b/include/dma.h @@ -86,8 +86,8 @@ private: bool flipflop; DmaChannel *DmaChannels[4]; public: - IO_ReadHandleObject DMA_ReadHandler[0x11]; - IO_WriteHandleObject DMA_WriteHandler[0x11]; + IO_ReadHandleObject DMA_ReadHandler[0x12]; + IO_WriteHandleObject DMA_WriteHandler[0x12]; DmaController(Bit8u num) { flipflop = false; ctrlnum = num; /* first or second DMA controller */ diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index f310c582..4ab4277f 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -109,6 +109,7 @@ bool SecondDMAControllerAvailable(void) { } static void DMA_Write_Port(Bitu port,Bitu val,Bitu /*iolen*/) { + //LOG(LOG_DMACONTROL,LOG_ERROR)("Write %X %X",port,val); if (port<0x10) { /* write to the first DMA controller (channels 0-3) */ DmaControllers[0]->WriteControllerReg(port,val,1); @@ -122,6 +123,7 @@ static void DMA_Write_Port(Bitu port,Bitu val,Bitu /*iolen*/) { case 0x81:GetDMAChannel(2)->SetPage((Bit8u)val);break; case 0x82:GetDMAChannel(3)->SetPage((Bit8u)val);break; case 0x83:GetDMAChannel(1)->SetPage((Bit8u)val);break; + case 0x87:GetDMAChannel(0)->SetPage((Bit8u)val);break; case 0x89:GetDMAChannel(6)->SetPage((Bit8u)val);break; case 0x8a:GetDMAChannel(7)->SetPage((Bit8u)val);break; case 0x8b:GetDMAChannel(5)->SetPage((Bit8u)val);break; @@ -130,6 +132,7 @@ static void DMA_Write_Port(Bitu port,Bitu val,Bitu /*iolen*/) { } static Bitu DMA_Read_Port(Bitu port,Bitu iolen) { + //LOG(LOG_DMACONTROL,LOG_ERROR)("Read %X",port); if (port<0x10) { /* read from the first DMA controller (channels 0-3) */ return DmaControllers[0]->ReadControllerReg(port,iolen); @@ -141,6 +144,7 @@ static Bitu DMA_Read_Port(Bitu port,Bitu iolen) { case 0x81:return GetDMAChannel(2)->pagenum; case 0x82:return GetDMAChannel(3)->pagenum; case 0x83:return GetDMAChannel(1)->pagenum; + case 0x87:return GetDMAChannel(0)->pagenum; case 0x89:return GetDMAChannel(6)->pagenum; case 0x8a:return GetDMAChannel(7)->pagenum; case 0x8b:return GetDMAChannel(5)->pagenum; @@ -365,9 +369,11 @@ public: /* install handlers for ports 0x81-0x83 (on the first DMA controller) */ DmaControllers[0]->DMA_WriteHandler[0x10].Install(0x81,DMA_Write_Port,IO_MB,3); DmaControllers[0]->DMA_ReadHandler[0x10].Install(0x81,DMA_Read_Port,IO_MB,3); + DmaControllers[0]->DMA_WriteHandler[0x11].Install(0x87,DMA_Write_Port,IO_MB,1); + DmaControllers[0]->DMA_ReadHandler[0x11].Install(0x87,DMA_Read_Port,IO_MB,1); if (IS_EGAVGA_ARCH) { - /* install handlers for ports 0x81-0x83 (on the second DMA controller) */ + /* install handlers for ports 0x89-0x8B (on the second DMA controller) */ DmaControllers[1]->DMA_WriteHandler[0x10].Install(0x89,DMA_Write_Port,IO_MB,3); DmaControllers[1]->DMA_ReadHandler[0x10].Install(0x89,DMA_Read_Port,IO_MB,3); } From c7e6b3ca864cc126a32afeb4344e1da5a33eb657 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 10 Oct 2018 07:00:53 +0000 Subject: [PATCH 4056/4131] Report when a -conf file can not be loaded. Make spacing similar between messages. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4166 --- src/gui/sdlmain.cpp | 6 ++++-- src/misc/setup.cpp | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index f64f8910..251bdb12 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -2098,9 +2098,11 @@ int main(int argc, char* argv[]) { //Second parse -conf switches while(control->cmdline->FindString("-conf",config_file,true)) { - if(!control->ParseConfigFile(config_file.c_str())) { + if (!control->ParseConfigFile(config_file.c_str())) { // try to load it from the user directory - control->ParseConfigFile((config_path + config_file).c_str()); + if (!control->ParseConfigFile((config_path + config_file).c_str())) { + LOG_MSG("CONFIG: Can't open specified config file: %s",config_file.c_str()); + } } } // if none found => parse localdir conf diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 3df23b83..56d836de 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -836,7 +836,7 @@ bool Config::ParseConfigFile(char const * const configfilename) { settings_type = (configfiles.size() == 0)? "primary":"additional"; configfiles.push_back(configfilename); - LOG_MSG("CONFIG:Loading %s settings from config file %s", settings_type,configfilename); + LOG_MSG("CONFIG: Loading %s settings from config file %s", settings_type,configfilename); //Get directory from configfilename, used with relative paths. current_config_dir=configfilename; From c3aca8dc4410e506f0287d0f1ae2ac2e9bf8df93 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Thu, 11 Oct 2018 14:58:18 +0000 Subject: [PATCH 4057/4131] When searching CD-ROM directory entries, strip trailing period of extension-less filenames after stripping file version number and separator. Fixes disc check in Air Power. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4167 --- src/dos/dos_mscdex.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 73fbabd3..a6d1b9c3 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -722,23 +722,18 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph } nameLength = mem_readb(defBuffer+index+32); MEM_StrCopy(defBuffer+index+33,entryName,nameLength); + // strip separator and file version number + char* separator = strchr(entryName,';'); + if (separator) *separator = 0; + // strip trailing period + size_t entrylen = strlen(entryName); + if (entrylen>0 && entryName[entrylen-1]=='.') entryName[entrylen-1] = 0; + if (strcmp(entryName,useName)==0) { //LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Get DirEntry : Found : %s",useName); foundName = true; break; } - /* Xcom Apocalipse searches for MUSIC. and expects to find MUSIC;1 - * All Files on the CDROM are of the kind blah;1 - */ - char* longername = strchr(entryName,';'); - if(longername) { - *longername = 0; - if (strcmp(entryName,useName)==0) { - //LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Get DirEntry : Found : %s",useName); - foundName = true; - break; - } - } index += entryLength; } while (index+33<=2048); From 07c2d06ae59f19ecdba54b726d6ceb23e3a425a6 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Thu, 11 Oct 2018 15:05:28 +0000 Subject: [PATCH 4058/4131] Add Unit Number and Bytes Per Sector fields for DPB entries. Fixes Air Power installer and Windows 3 Virtual Memory dialog. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4168 --- src/dos/dos.cpp | 2 +- src/dos/dos_files.cpp | 2 +- src/dos/dos_misc.cpp | 2 +- src/dos/dos_programs.cpp | 8 ++++---- src/dos/dos_tables.cpp | 8 +++++--- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index d5cb2b8b..5981df01 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -497,7 +497,7 @@ static Bitu DOS_21Handler(void) { if (drive < DOS_DRIVES && Drives[drive] && !Drives[drive]->isRemovable()) { reg_al = 0x00; SegSet16(ds,dos.tables.dpb); - reg_bx = drive*5;//Faking the first entry (drive number) and media id + reg_bx = drive*9; LOG(LOG_DOSMISC,LOG_ERROR)("Get drive parameter block."); } else { reg_al=0xff; diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 49d7eeea..0be27974 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1288,7 +1288,7 @@ bool DOS_GetAllocationInfo(Bit8u drive,Bit16u * _bytes_sector,Bit8u * _sectors_c Bit16u _free_clusters; Drives[drive]->AllocationInfo(_bytes_sector,_sectors_cluster,_total_clusters,&_free_clusters); SegSet16(ds,RealSeg(dos.tables.mediaid)); - reg_bx=RealOff(dos.tables.mediaid+drive*5); + reg_bx=RealOff(dos.tables.mediaid+drive*9); return true; } diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index ed180b3a..163883c4 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -90,7 +90,7 @@ static bool DOS_MultiplexFunctions(void) { mem_writew(sftptr+sftofs+0x02,(Bit16u)(Files[reg_bx]->flags&3)); // file open mode mem_writeb(sftptr+sftofs+0x04,(Bit8u)(Files[reg_bx]->attr)); // file attribute mem_writew(sftptr+sftofs+0x05,0x40|drive); // device info word - mem_writed(sftptr+sftofs+0x07,RealMake(dos.tables.dpb,drive*5)); // dpb of the drive + mem_writed(sftptr+sftofs+0x07,RealMake(dos.tables.dpb,drive*9)); // dpb of the drive mem_writew(sftptr+sftofs+0x0d,Files[reg_bx]->time); // packed file time mem_writew(sftptr+sftofs+0x0f,Files[reg_bx]->date); // packed file date Bit32u curpos=0; diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index f2231815..cdea5d7b 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -126,7 +126,7 @@ public: switch (DriveManager::UnmountDrive(i_drive)) { case 0: Drives[i_drive] = 0; - mem_writeb(Real2Phys(dos.tables.mediaid)+i_drive*5,0); + mem_writeb(Real2Phys(dos.tables.mediaid)+i_drive*9,0); if(i_drive == DOS_GetDefaultDrive()) DOS_SetDrive(ZDRIVE_NUM); WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCESS"),umount[0]); @@ -395,7 +395,7 @@ public: if (!newdrive) E_Exit("DOS:Can't create drive"); Drives[drive-'A']=newdrive; /* Set the correct media byte in the table */ - mem_writeb(Real2Phys(dos.tables.mediaid)+(drive-'A')*5,newdrive->GetMediaByte()); + mem_writeb(Real2Phys(dos.tables.mediaid)+(drive-'A')*9,newdrive->GetMediaByte()); WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,newdrive->GetInfo()); /* check if volume label is given and don't allow it to updated in the future */ if (cmd->FindString("-label",label,true)) newdrive->dirCache.SetLabel(label.c_str(),iscdrom,false); @@ -1313,7 +1313,7 @@ public: DriveManager::InitializeDrive(drive - 'A'); // Set the correct media byte in the table - mem_writeb(Real2Phys(dos.tables.mediaid) + (drive - 'A') * 5, mediaid); + mem_writeb(Real2Phys(dos.tables.mediaid) + (drive - 'A') * 9, mediaid); /* Command uses dta so set it to our internal dta */ RealPt save_dta = dos.dta(); @@ -1393,7 +1393,7 @@ public: DriveManager::InitializeDrive(drive - 'A'); // Set the correct media byte in the table - mem_writeb(Real2Phys(dos.tables.mediaid) + (drive - 'A') * 5, mediaid); + mem_writeb(Real2Phys(dos.tables.mediaid) + (drive - 'A') * 9, mediaid); // Print status message (success) WriteOut(MSG_Get("MSCDEX_SUCCESS")); diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 5579da44..b7687d6d 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -148,11 +148,13 @@ void DOS_SetupTables(void) { dos_infoblock.SetFCBTable(RealMake(seg,0)); /* Create a fake DPB */ - dos.tables.dpb=DOS_GetMemory(10); + dos.tables.dpb=DOS_GetMemory(16); dos.tables.mediaid=RealMake(dos.tables.dpb,0x17); //Media ID offset in DPB for (i=0;i Date: Mon, 12 Nov 2018 16:39:49 +0000 Subject: [PATCH 4059/4131] Reset write ops after drawing text in EGA graphics modes, consistent with EGA/VGA BIOS. Fixes Fun School 3. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4169 --- src/ints/int10_char.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index d8c5aaa9..4acf8cf1 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -625,6 +625,11 @@ void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) cur_row++; } } + + if (CurMode->type==M_EGA) { + // Reset write ops for EGA graphics modes + IO_Write(0x3ce,0x3);IO_Write(0x3cf,0x0); + } } static void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr,Bit8u page) { From 80342e104e969b8d1c8bb18cc24b632dd735cb48 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Mon, 12 Nov 2018 16:41:00 +0000 Subject: [PATCH 4060/4131] Correct response for keyboard echo command. Fixes Steel Shot. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4170 --- src/hardware/keyboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 0a0a5c18..4991730c 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -115,7 +115,7 @@ static void write_p60(Bitu port,Bitu val,Bitu iolen) { KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ break; case 0xee: /* Echo */ - KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ + KEYBOARD_AddBuffer(0xee); /* Echo */ break; case 0xf2: /* Identify keyboard */ /* AT's just send acknowledge */ From 1960a815e1e3571ac51ca2f5e2c5d0b9ebeecd9b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 16 Nov 2018 12:40:37 +0000 Subject: [PATCH 4061/4131] Improvements for compiling dynrec core in 64 bit mode on windows. Thanks for the help PgrAm and kjliew. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4171 --- src/cpu/core_dynrec/risc_x64.h | 132 +++++++++++++++++++++++++-------- 1 file changed, 103 insertions(+), 29 deletions(-) diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index 5c7e59dc..d6617697 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -56,11 +56,16 @@ typedef Bit8u HostReg; // then define DRC_PROTECT_ADDR_REG above #define FC_ADDR HOST_EBX +#if defined (_WIN64) +#define FC_OP1 HOST_ECX +#define FC_OP2 HOST_EDX +#else // register that holds the first parameter #define FC_OP1 HOST_EDI // register that holds the second parameter #define FC_OP2 HOST_ESI +#endif // special register that holds the third parameter for _R3 calls (byte accessible) #define FC_OP3 HOST_EAX @@ -359,18 +364,31 @@ static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { // generate a call to a parameterless function static void INLINE gen_call_function_raw(void * func) { - cache_addb(0x48); - cache_addw(0xec83); - cache_addb(0x08); // sub rsp,0x08 (align stack to 16 byte boundary) +// cache_addb(0x48); +// cache_addw(0xec83); +#if defined (_WIN64) +// cache_addb(0x28); // allocate windows shadow space + cache_addd(0x28ec8348); +#else +// cache_addb(0x08); // sub rsp,0x08 (align stack to 16 byte boundary) + cache_addd(0x08ec8348); +#endif - cache_addb(0x48); - cache_addb(0xb8); // mov reg,imm64 +// cache_addb(0x48); +// cache_addb(0xb8); // mov reg,imm64 + cache_addw(0xb848); cache_addq((Bit64u)func); cache_addw(0xd0ff); - cache_addb(0x48); - cache_addw(0xc483); - cache_addb(0x08); // add rsp,0x08 (reset alignment) +// cache_addb(0x48); +// cache_addw(0xc483); +#if defined (_WIN64) +// cache_addb(0x28); // deallocate windows shadow space + cache_addd(0x28c48348); +#else +// cache_addb(0x08); // add rsp,0x08 (reset alignment) + cache_addd(0x08c48348); +#endif } // generate a call to a function with paramcount parameters @@ -381,33 +399,51 @@ static Bit64u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fa cache_addb(0x48); cache_addw(0xc48b); // mov rax,rsp - cache_addb(0x48); - cache_addw(0xec83); // sub rsp,0x08 - cache_addb(0x08); // 0x08==return address pushed onto stack by call +// cache_addb(0x48); +// cache_addw(0xec83); // sub rsp,0x08 +// cache_addb(0x08); // 0x08==return address pushed onto stack by call + cache_addd(0x08ec8348); - cache_addb(0x48); - cache_addw(0xe483); // and esp,0xfffffffffffffff0 - cache_addb(0xf0); +// cache_addb(0x48); +// cache_addw(0xe483); // and esp,0xfffffffffffffff0 +// cache_addb(0xf0); + cache_addd(0xf0e48348); - cache_addb(0x48); - cache_addw(0xc483); // add rsp,0x08 - cache_addb(0x08); +// cache_addb(0x48); +// cache_addw(0xc483); // add rsp,0x08 +// cache_addb(0x08); + cache_addd(0x08c48348); // stack is 16 byte aligned now cache_addb(0x50); // push rax (==old rsp) +#if defined (_WIN64) +// cache_addb(0x48); +// cache_addw(0xec83); // sub rsp,0x20 +// cache_addb(0x20); // allocate windows shadow space + cache_addd(0x20ec8348); +#endif + // returned address relates to where the address is stored in gen_call_function_raw Bit64u proc_addr=(Bit64u)cache.pos-4; // Do the actual call to the procedure - cache_addb(0x48); - cache_addb(0xb8); // mov reg,imm64 +// cache_addb(0x48); +// cache_addb(0xb8); // mov reg,imm64 + cache_addw(0xb848); cache_addq((Bit64u)func); cache_addw(0xd0ff); +#if defined (_WIN64) +// cache_addb(0x48); +// cache_addw(0xc483); // add rsp,0x20 +// cache_addb(0x20); // deallocate windows shadow space + cache_addd(0x20c48348); +#endif + // restore stack cache_addb(0x5c); // pop rsp @@ -425,7 +461,7 @@ static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { case 1: // mov param2,imm32 gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)imm); break; -#if defined (_MSC_VER) +#if defined (_WIN64) case 2: // mov r8,imm32 cache_addw(0xb849); cache_addq((Bit32u)imm); @@ -458,7 +494,7 @@ static void INLINE gen_load_param_addr(DRC_PTR_SIZE_IM addr,Bitu param) { case 1: // mov param2,addr64 gen_mov_reg_qword(FC_OP2,addr); break; -#if defined (_MSC_VER) +#if defined (_WIN64) case 2: // mov r8,addr64 cache_addw(0xb849); cache_addq(addr); @@ -491,14 +527,14 @@ static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { case 1: // mov param2,reg&7 gen_mov_regs(FC_OP2,reg&7); break; -#if defined (_MSC_VER) +#if defined (_WIN64) case 2: // mov r8,reg&7 - cache_addb(0x49); - gen_mov_regs(0,reg&7); + cache_addw(0x8949); + cache_addb(0xc0 + ((reg & 7) << 3)); break; case 3: // mov r9,reg&7 - cache_addb(0x49); - gen_mov_regs(1,reg&7); + cache_addw(0x8949); + cache_addb(0xc1 + ((reg & 7) << 3)); break; #else case 2: // mov rdx,reg&7 @@ -524,12 +560,12 @@ static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { case 1: // mov param2,[mem] gen_mov_word_to_reg(FC_OP2,(void*)mem,true); break; -#if defined (_MSC_VER) +#if defined (_WIN64) case 2: // mov r8,[mem] - gen_mov_word_to_reg(0,(void*)mem,true,0x49); // 0x49, use x64 rX regs + gen_mov_word_to_reg(0,(void*)mem,true,0x4c); // 0x4c, use x64 rX regs break; case 3: // mov r9,[mem] - gen_mov_word_to_reg(1,(void*)mem,true,0x49); // 0x49, use x64 rX regs + gen_mov_word_to_reg(1,(void*)mem,true,0x4c); // 0x4c, use x64 rX regs break; #else case 2: // mov rdx,[mem] @@ -629,7 +665,13 @@ static void gen_fill_branch_long(Bit64u data) { static void gen_run_code(void) { cache_addb(0x53); // push rbx +#if defined (_WIN64) + cache_addw(0x5657); // push rdi; push rsi +#endif cache_addw(0xd0ff+(FC_OP1<<8)); // call rdi +#if defined (_WIN64) + cache_addw(0x5f5e); // pop rsi; pop rdi +#endif cache_addb(0x5b); // pop rbx } @@ -650,7 +692,11 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: +#if defined (_WIN64) + *(Bit32u*)(pos+0)=0xd001c889; // mov eax, ecx; add eax, edx +#else *(Bit32u*)(pos+0)=0xf001f889; // mov eax,edi; add eax,esi +#endif *(Bit32u*)(pos+4)=0x90900eeb; // skip *(Bit32u*)(pos+8)=0x90909090; *(Bit32u*)(pos+12)=0x90909090; @@ -659,7 +705,11 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ORb: case t_ORw: case t_ORd: +#if defined (_WIN64) + *(Bit32u*)(pos+0)=0xd009c889; // mov eax, ecx; or eax, edx +#else *(Bit32u*)(pos+0)=0xf009f889; // mov eax,edi; or eax,esi +#endif *(Bit32u*)(pos+4)=0x90900eeb; // skip *(Bit32u*)(pos+8)=0x90909090; *(Bit32u*)(pos+12)=0x90909090; @@ -668,7 +718,11 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ANDb: case t_ANDw: case t_ANDd: +#if defined (_WIN64) + *(Bit32u*)(pos+0)=0xd021c889; // mov eax, ecx; and eax, edx +#else *(Bit32u*)(pos+0)=0xf021f889; // mov eax,edi; and eax,esi +#endif *(Bit32u*)(pos+4)=0x90900eeb; // skip *(Bit32u*)(pos+8)=0x90909090; *(Bit32u*)(pos+12)=0x90909090; @@ -677,7 +731,11 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_SUBb: case t_SUBw: case t_SUBd: +#if defined (_WIN64) + *(Bit32u*)(pos+0)=0xd029c889; // mov eax, ecx; sub eax, edx +#else *(Bit32u*)(pos+0)=0xf029f889; // mov eax,edi; sub eax,esi +#endif *(Bit32u*)(pos+4)=0x90900eeb; // skip *(Bit32u*)(pos+8)=0x90909090; *(Bit32u*)(pos+12)=0x90909090; @@ -686,7 +744,11 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_XORb: case t_XORw: case t_XORd: +#if defined (_WIN64) + *(Bit32u*)(pos+0)=0xd031c889; // mov eax, ecx; xor eax, edx +#else *(Bit32u*)(pos+0)=0xf031f889; // mov eax,edi; xor eax,esi +#endif *(Bit32u*)(pos+4)=0x90900eeb; // skip *(Bit32u*)(pos+8)=0x90909090; *(Bit32u*)(pos+12)=0x90909090; @@ -707,7 +769,11 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_INCb: case t_INCw: case t_INCd: +#if defined (_WIN64) + *(Bit32u*)(pos+0)=0xc0ffc889; // mov eax, ecx; inc eax +#else *(Bit32u*)(pos+0)=0xc0fff889; // mov eax,edi; inc eax +#endif *(Bit32u*)(pos+4)=0x90900eeb; // skip *(Bit32u*)(pos+8)=0x90909090; *(Bit32u*)(pos+12)=0x90909090; @@ -716,7 +782,11 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_DECb: case t_DECw: case t_DECd: +#if defined (_WIN64) + *(Bit32u*)(pos+0)=0xc8ffc889; // mov eax, ecx; dec eax +#else *(Bit32u*)(pos+0)=0xc8fff889; // mov eax,edi; dec eax +#endif *(Bit32u*)(pos+4)=0x90900eeb; // skip *(Bit32u*)(pos+8)=0x90909090; *(Bit32u*)(pos+12)=0x90909090; @@ -725,7 +795,11 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_NEGb: case t_NEGw: case t_NEGd: +#if defined (_WIN64) + *(Bit32u*)(pos+0)=0xd8f7c889; // mov eax, ecx; neg eax +#else *(Bit32u*)(pos+0)=0xd8f7f889; // mov eax,edi; neg eax +#endif *(Bit32u*)(pos+4)=0x90900eeb; // skip *(Bit32u*)(pos+8)=0x90909090; *(Bit32u*)(pos+12)=0x90909090; From d0ecdf85b2e1f20a2edffa0d7e0f9024b5532b9a Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Fri, 16 Nov 2018 22:39:24 +0000 Subject: [PATCH 4062/4131] Allocation Info works for CD-ROM drives. Fixes Bureau 13 installer. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4172 --- src/dos/dos_files.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 0be27974..a9175c29 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1281,7 +1281,7 @@ bool DOS_FileExists(char const * const name) { bool DOS_GetAllocationInfo(Bit8u drive,Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters) { if (!drive) drive = DOS_GetDefaultDrive(); else drive--; - if (drive >= DOS_DRIVES || !Drives[drive] || Drives[drive]->isRemovable()) { + if (drive >= DOS_DRIVES || !Drives[drive]) { DOS_SetError(DOSERR_INVALID_DRIVE); return false; } From 9ffb5627aaa05679fb759444be39cef7856b7f91 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 17 Nov 2018 13:29:02 +0000 Subject: [PATCH 4063/4131] Add ripsaws one line patch to fix bug 488 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4173 --- src/dos/drives.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index 832eb91f..62e281ac 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -132,7 +132,7 @@ void DriveManager::InitializeDrive(int drive) { driveInfo.currentDisk = 0; DOS_Drive* disk = driveInfo.disks[driveInfo.currentDisk]; Drives[currentDrive] = disk; - disk->Activate(); + if (driveInfo.disks.size() > 1) disk->Activate(); } } From 72f854472370bee22337aba6bbdbfe0937b7c057 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Nov 2018 18:34:49 +0000 Subject: [PATCH 4064/4131] Make autoinit exit work and prevent double single cycle transfers when quitting autoinit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4174 --- src/hardware/sblaster.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 9058df08..4b68d63f 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -537,6 +537,8 @@ static void GenerateDMASound(Bitu size) { sb.dma.mode = DSP_DMA_NONE; } else { + //Copied this value as the count for the final single cycle + sb.dma.total = 0; LOG(LOG_SB, LOG_NORMAL)("Switch to Single cycle transfer begun"); } } else { @@ -996,6 +998,8 @@ static void DSP_DoCommand(void) { DSP_SB2_ABOVE; /* Set mode to single transfer so it ends with current block */ sb.dma.autoinit=false; //Should stop itself + sb.dma.total = 0; //This will cancel the switch to single cycle mode + //Should really have some sb.dma.autoexit variable since we don't support continue autoinit dsp commands break; case 0xe0: /* DSP Identification - SB2.0+ */ DSP_FlushData(); From 3bde40bc91cc241997101f78998dffd0ebbf75c2 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 19 Nov 2018 22:02:13 +0000 Subject: [PATCH 4065/4131] Make a dma channel go masked when it reaches end of count without autoinit Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4175 --- include/dma.h | 2 +- src/hardware/dma.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/dma.h b/include/dma.h index 196e4b4a..e2179345 100644 --- a/include/dma.h +++ b/include/dma.h @@ -24,7 +24,7 @@ enum DMAEvent { DMA_REACHED_TC, DMA_MASKED, DMA_UNMASKED, - DMA_TRANSFEREND +// DMA_TRANSFEREND, this shouldn't really be a signal }; class DmaChannel; diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 4ab4277f..3b2f26d1 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -308,7 +308,7 @@ again: currcnt=0xffff; masked=true; UpdateEMSMapping(); - DoCallBack(DMA_TRANSFEREND); + DoCallBack(DMA_MASKED); } } return done; @@ -340,7 +340,7 @@ again: currcnt=0xffff; masked=true; UpdateEMSMapping(); - DoCallBack(DMA_TRANSFEREND); + DoCallBack(DMA_MASKED); } } return done; From e0a7ede03703c8fa2347ccb23ec3e4b441c7ff2c Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Fri, 23 Nov 2018 21:55:12 +0000 Subject: [PATCH 4066/4131] Don't generate sound after DMA is masked at end of single-cycle transfer. Prevents issues with some games. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4176 --- include/dma.h | 2 +- src/hardware/dma.cpp | 4 ++-- src/hardware/sblaster.cpp | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/dma.h b/include/dma.h index e2179345..196e4b4a 100644 --- a/include/dma.h +++ b/include/dma.h @@ -24,7 +24,7 @@ enum DMAEvent { DMA_REACHED_TC, DMA_MASKED, DMA_UNMASKED, -// DMA_TRANSFEREND, this shouldn't really be a signal + DMA_TRANSFEREND }; class DmaChannel; diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 3b2f26d1..4ab4277f 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -308,7 +308,7 @@ again: currcnt=0xffff; masked=true; UpdateEMSMapping(); - DoCallBack(DMA_MASKED); + DoCallBack(DMA_TRANSFEREND); } } return done; @@ -340,7 +340,7 @@ again: currcnt=0xffff; masked=true; UpdateEMSMapping(); - DoCallBack(DMA_MASKED); + DoCallBack(DMA_TRANSFEREND); } } return done; diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 4b68d63f..0c0a1c32 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -298,6 +298,8 @@ static void DSP_DMA_CallBack(DmaChannel * chan, DMAEvent event) { // DSP_ChangeMode(MODE_DMA_MASKED); LOG(LOG_SB,LOG_NORMAL)("DMA masked,stopping output, left %d",chan->currcnt); } + } else if (event==DMA_TRANSFEREND) { + if (sb.mode==MODE_DMA) sb.mode=MODE_DMA_MASKED; } else if (event==DMA_UNMASKED) { if (sb.mode==MODE_DMA_MASKED && sb.dma.mode!=DSP_DMA_NONE) { DSP_ChangeMode(MODE_DMA); From f5e4b9205fbd77329b418073296b1cecbd1d3ee2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 11 Dec 2018 15:45:37 +0000 Subject: [PATCH 4067/4131] Add workaround for the problem of locking the mouse in windowed mode with X.org 1.20.1. (thanks to DosFreak and ny00123 for their help with testing and debugging) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4177 --- src/gui/sdlmain.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 251bdb12..05eecfbb 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1522,6 +1522,12 @@ bool GFX_IsFullscreen(void) { #define DB_POLLSKIP 1 #endif +#if defined(LINUX) +#define SDL_XORG_FIX 1 +#else +#define SDL_XORG_FIX 0 +#endif + void GFX_Events() { //Don't poll too often. This can be heavy on the OS, especially Macs. //In idle mode 3000-4000 polls are done per second without this check. @@ -1545,6 +1551,19 @@ void GFX_Events() { } #endif while (SDL_PollEvent(&event)) { +#if SDL_XORG_FIX + // Special code for broken SDL with Xorg 1.20.1, where pairs of inputfocus gain and loss events are generated + // when locking the mouse in windowed mode. + if (event.type == SDL_ACTIVEEVENT && event.active.state == SDL_APPINPUTFOCUS && event.active.gain == 0) { + SDL_Event test; //Check if the next event would undo this one. + if (SDL_PeepEvents(&test,1,SDL_PEEKEVENT,SDL_ACTIVEEVENTMASK) == 1 && test.active.state == SDL_APPINPUTFOCUS && test.active.gain == 1) { + // Skip both events. + SDL_PeepEvents(&test,1,SDL_GETEVENT,SDL_ACTIVEEVENTMASK); + continue; + } + } +#endif + switch (event.type) { case SDL_ACTIVEEVENT: if (event.active.state & SDL_APPINPUTFOCUS) { From c9f79add62a16d9b4a43346bf5e13ef5b4c1150b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 17 Dec 2018 19:22:30 +0000 Subject: [PATCH 4068/4131] no bilinearing filtering on exact multiples Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4178 --- src/gui/sdlmain.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 05eecfbb..9dde5dcb 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -719,12 +719,12 @@ dosurface: // No borders glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - if (sdl.opengl.bilinear) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } else { + if (!sdl.opengl.bilinear || ( (sdl.clip.h % height) == 0 && (sdl.clip.w % width) == 0) ) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texsize, texsize, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, 0); From b899da315d7c0c81a4f1f51deb52c6ac1748f7c8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 28 Dec 2018 12:18:12 +0000 Subject: [PATCH 4069/4131] use right field when dealing with joysticks. use enum instead of magic value (ny00123) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4179 --- src/gui/sdl_mapper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 2e6f7def..db8a4ea9 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -712,7 +712,7 @@ public: if (abs(event->jaxis.value)<25000) return 0; return CreateAxisBind(event->jaxis.axis,event->jaxis.value>0); } else if (event->type==SDL_JOYBUTTONDOWN) { - if (event->button.which!=stick) return 0; + if (event->jbutton.which!=stick) return 0; #if defined (REDUCE_JOYSTICK_POLLING) return CreateButtonBind(event->jbutton.button%button_wrap); #else @@ -1690,7 +1690,7 @@ static void SetActiveEvent(CEvent * event) { } static void DrawButtons(void) { - SDL_FillRect(mapper.surface,0,0); + SDL_FillRect(mapper.surface,0,CLR_BLACK); SDL_LockSurface(mapper.surface); for (CButton_it but_it = buttons.begin();but_it!=buttons.end();but_it++) { (*but_it)->Draw(); From d55c6a03ed56dc1506cb408ac5ac1a14634900b4 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 28 Dec 2018 12:19:13 +0000 Subject: [PATCH 4070/4131] This order works better for when other headers change. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4180 --- src/dos/cdrom_ioctl_win32.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index 465e6bd6..0974c5e7 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -27,8 +27,8 @@ #include #if (defined (_MSC_VER)) || (defined __MINGW64_VERSION_MAJOR) -#include // Ioctl stuff #include // Ioctl stuff +#include // Ioctl stuff #else #include "ddk/ntddcdrm.h" // Ioctl stuff #endif From cf85eb0d9b7260689e08fe400ad921059c977683 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Jan 2019 09:31:50 +0000 Subject: [PATCH 4071/4131] Remove file that has not been used in a long time Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4181 --- include/Makefile.am | 1 - include/modules.h | 180 -------------------------------------------- 2 files changed, 181 deletions(-) delete mode 100644 include/modules.h diff --git a/include/Makefile.am b/include/Makefile.am index 5c89f480..570d78c6 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -22,7 +22,6 @@ mapper.h \ mem.h \ midi.h \ mixer.h \ -modules.h \ mouse.h \ paging.h \ pci_bus.h \ diff --git a/include/modules.h b/include/modules.h deleted file mode 100644 index 6bbeffca..00000000 --- a/include/modules.h +++ /dev/null @@ -1,180 +0,0 @@ -/* Standard data types used */ - -typedef unsigned char Bit8u; -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 - - - -/* Setting up pointers to all subfunctions */ -#ifdef MODULE_WANT_IO_READ -typedef Bit8u (* IO_ReadHandler)(Bit32u port); -static void (* IO_RegisterReadHandler)(Bit32u port,IO_ReadHandler handler,char * name); -static void (* IO_FreeReadHandler)(Bit32u port); -#endif - -#ifdef MODULE_WANT_IO_WRITE -typedef void (* IO_WriteHandler)(Bit32u port,Bit8u value); -static void (* IO_RegisterWriteHandler)(Bit32u port,IO_WriteHandler handler,char * name); -static void (* IO_FreeWriteHandler)(Bit32u port); -#endif - -#ifdef MODULE_WANT_IRQ_EOI -typedef void (* IRQ_EOIHandler)(void); -static void (* IRQ_RegisterEOIHandler)(Bit32u irq,IRQ_EOIHandler handler,char * name); -static void (* IRQ_FreeEOIHandler)(Bit32u irq); -#endif - -#ifdef MODULE_WANT_IRQ -static void (* IRQ_Activate)(Bit32u irq); -static void (* IRQ_Deactivate)(Bit32u irq); -#endif - -#ifdef MODULE_WANT_TIMER -typedef void (* TIMER_MicroHandler)(void); -static void (* TIMER_RegisterMicroHandler)(TIMER_MicroHandler handler,Bit32u micro); -#endif - -#ifdef MODULE_WANT_TIMER_TICK -typedef void (* TIMER_TickHandler)(Bit32u ticks); -static void (* TIMER_RegisterTickHandler)(TIMER_TickHandler handler); -#endif - -/* - 4 8-bit and 4 16-bit channels you can read data from - 16-bit reads are word sized -*/ - -#ifdef MODULE_WANT_DMA_READ -static void (* DMA_8_Read)(Bit32u chan,Bit8u * data,Bit16u size); -static void (* DMA_16_Read)(Bit32u chan,Bit8u * data,Bit16u size); -#endif - -/* - 4 8-bit and 4 16-bit channels you can write data from - 16-bit writes are word sized -*/ - -#ifdef MODULE_WANT_DMA_READ -static void (* DMA_8_Write)(Bit32u chan,Bit8u * data,Bit16u size); -static void (* DMA_16_Write)(Bit32u chan,Bit8u * data,Bit16u size); -#endif - - -#ifdef MODULE_WANT_MIXER -/* The len here means the amount of samples needed not the buffersize it needed to fill */ -typedef void (* MIXER_MixHandler)(Bit8u * sampdate,Bit32u len); - -/* Different types if modes a mixer channel can work in */ -#define MIXER_8MONO 0 -#define MIXER_8STEREO 1 -#define MIXER_16MONO 2 -#define MIXER_16STEREO 3 -struct MIXER_Channel; - -#define MAX_AUDIO ((1<<(16-1))-1) -#define MIN_AUDIO -(1<<(16-1)) - -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); -#endif - -typedef bool (* MODULE_FindHandler)(char * name,void * * function); -typedef char *(* MODULE_StartHandler)(MODULE_FindHandler find_handler); - -#define MODULE_START_PROC "ModuleStart" - -#ifdef MODULE_START_FUNCTION -#include - -#define GET_FUNCTION(a) \ - if (!find_handler(#a ,(void * *) &a)) { \ - return "Can't find requested function"; \ - }; - - -#if defined (WIN32) -#include -BOOL APIENTRY DllMain( HANDLE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) -{ - return TRUE; -} - -extern "C" { -__declspec(dllexport) -#endif -char * ModuleStart (MODULE_FindHandler find_handler) { - -#ifdef MODULE_WANT_IRQ_EOI -GET_FUNCTION(IRQ_RegisterEOIHandler); -GET_FUNCTION(IRQ_FreeEOIHandler); -#endif - -#ifdef MODULE_WANT_IRQ -GET_FUNCTION(IRQ_Activate); -GET_FUNCTION(IRQ_Deactivate); -#endif - -#ifdef MODULE_WANT_IO_READ -GET_FUNCTION(IO_RegisterReadHandler); -GET_FUNCTION(IO_FreeReadHandler); -#endif - -#ifdef MODULE_WANT_IO_WRITE -GET_FUNCTION(IO_RegisterWriteHandler); -GET_FUNCTION(IO_FreeWriteHandler); -#endif - -#ifdef MODULE_WANT_TIMER -GET_FUNCTION(TIMER_RegisterMicroHandler); -#endif - -#ifdef MODULE_WANT_TIMER_TICKS -GET_FUNCTION(TIMER_RegisterTickHandler); -#endif - -#ifdef MODULE_WANT_DMA_READ -GET_FUNCTION(DMA_8_Read); -GET_FUNCTION(DMA_16_Read); -#endif - -#ifdef MODULE_WANT_DMA_WRITE -GET_FUNCTION(DMA_8_Write); -GET_FUNCTION(DMA_16_Write); -#endif - -#ifdef MODULE_WANT_MIXER -GET_FUNCTION(MIXER_AddChannel); -GET_FUNCTION(MIXER_SetVolume); -GET_FUNCTION(MIXER_SetFreq); -GET_FUNCTION(MIXER_SetMode); -GET_FUNCTION(MIXER_Enable); -#endif - -return MODULE_START_FUNCTION; - -} -#if defined (WIN32) -} -#endif - - - -#endif - From 2327f92db9ce81b0a58c2b620da518ceea431016 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Jan 2019 10:08:06 +0000 Subject: [PATCH 4072/4131] Here as well Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4182 --- visualc_net/dosbox.vcproj | 3 --- 1 file changed, 3 deletions(-) diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 7d62ff31..36c30833 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -865,9 +865,6 @@ - - From 1fbaff47fc54267a865790048213bcc10abfb17c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Jan 2019 14:09:58 +0000 Subject: [PATCH 4073/4131] Update year and address of FSF Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4183 --- COPYING | 11 +++++------ acinclude.m4 | 8 ++++---- include/bios.h | 8 ++++---- include/bios_disk.h | 8 ++++---- include/callback.h | 8 ++++---- include/control.h | 8 ++++---- include/cpu.h | 8 ++++---- include/cross.h | 8 ++++---- include/debug.h | 8 ++++---- include/dma.h | 8 ++++---- include/dos_inc.h | 8 ++++---- include/dos_system.h | 8 ++++---- include/dosbox.h | 8 ++++---- include/fpu.h | 8 ++++---- include/hardware.h | 8 ++++---- include/inout.h | 8 ++++---- include/ipx.h | 8 ++++---- include/ipxserver.h | 8 ++++---- include/joystick.h | 8 ++++---- include/keyboard.h | 8 ++++---- include/logging.h | 8 ++++---- include/mapper.h | 10 +++++----- include/mem.h | 8 ++++---- include/midi.h | 8 ++++---- include/mixer.h | 8 ++++---- include/mouse.h | 8 ++++---- include/paging.h | 8 ++++---- include/pci_bus.h | 8 ++++---- include/pic.h | 8 ++++---- include/programs.h | 8 ++++---- include/regs.h | 8 ++++---- include/render.h | 8 ++++---- include/serialport.h | 8 ++++---- include/setup.h | 8 ++++---- include/shell.h | 8 ++++---- include/support.h | 8 ++++---- include/timer.h | 8 ++++---- include/vga.h | 10 +++++----- include/video.h | 8 ++++---- scripts/dosbox-installer.nsi | 2 +- src/cpu/callback.cpp | 8 ++++---- src/cpu/core_dyn_x86.cpp | 8 ++++---- src/cpu/core_dyn_x86/cache.h | 8 ++++---- src/cpu/core_dyn_x86/decoder.h | 8 ++++---- src/cpu/core_dyn_x86/dyn_fpu.h | 8 ++++---- src/cpu/core_dyn_x86/dyn_fpu_dh.h | 8 ++++---- src/cpu/core_dyn_x86/helpers.h | 8 ++++---- src/cpu/core_dyn_x86/risc_x86.h | 8 ++++---- src/cpu/core_dyn_x86/string.h | 8 ++++---- src/cpu/core_dynrec.cpp | 8 ++++---- src/cpu/core_dynrec/cache.h | 8 ++++---- src/cpu/core_dynrec/decoder.h | 8 ++++---- src/cpu/core_dynrec/decoder_basic.h | 8 ++++---- src/cpu/core_dynrec/decoder_opcodes.h | 8 ++++---- src/cpu/core_dynrec/dyn_fpu.h | 8 ++++---- src/cpu/core_dynrec/operators.h | 8 ++++---- src/cpu/core_dynrec/risc_armv4le-common.h | 8 ++++---- src/cpu/core_dynrec/risc_armv4le-o3.h | 8 ++++---- src/cpu/core_dynrec/risc_armv4le-thumb-iw.h | 8 ++++---- src/cpu/core_dynrec/risc_armv4le-thumb-niw.h | 8 ++++---- src/cpu/core_dynrec/risc_armv4le-thumb.h | 8 ++++---- src/cpu/core_dynrec/risc_armv4le.h | 8 ++++---- src/cpu/core_dynrec/risc_armv8le.h | 8 ++++---- src/cpu/core_dynrec/risc_mipsel32.h | 8 ++++---- src/cpu/core_dynrec/risc_x64.h | 8 ++++---- src/cpu/core_dynrec/risc_x86.h | 8 ++++---- src/cpu/core_full.cpp | 8 ++++---- src/cpu/core_full/ea_lookup.h | 8 ++++---- src/cpu/core_full/load.h | 8 ++++---- src/cpu/core_full/loadwrite.h | 8 ++++---- src/cpu/core_full/op.h | 8 ++++---- src/cpu/core_full/optable.h | 8 ++++---- src/cpu/core_full/save.h | 8 ++++---- src/cpu/core_full/string.h | 8 ++++---- src/cpu/core_full/support.h | 8 ++++---- src/cpu/core_normal.cpp | 8 ++++---- src/cpu/core_normal/helpers.h | 8 ++++---- src/cpu/core_normal/prefix_0f.h | 8 ++++---- src/cpu/core_normal/prefix_66.h | 8 ++++---- src/cpu/core_normal/prefix_66_0f.h | 8 ++++---- src/cpu/core_normal/prefix_none.h | 8 ++++---- src/cpu/core_normal/string.h | 8 ++++---- src/cpu/core_normal/support.h | 8 ++++---- src/cpu/core_normal/table_ea.h | 8 ++++---- src/cpu/core_prefetch.cpp | 8 ++++---- src/cpu/core_simple.cpp | 8 ++++---- src/cpu/cpu.cpp | 8 ++++---- src/cpu/flags.cpp | 8 ++++---- src/cpu/instructions.h | 8 ++++---- src/cpu/lazyflags.h | 8 ++++---- src/cpu/modrm.cpp | 8 ++++---- src/cpu/modrm.h | 8 ++++---- src/cpu/paging.cpp | 8 ++++---- src/debug/debug.cpp | 8 ++++---- src/debug/debug_gui.cpp | 8 ++++---- src/debug/debug_inc.h | 8 ++++---- src/debug/debug_win32.cpp | 8 ++++---- src/debug/disasm_tables.h | 8 ++++---- src/dos/cdrom.cpp | 8 ++++---- src/dos/cdrom.h | 8 ++++---- src/dos/cdrom_aspi_win32.cpp | 8 ++++---- src/dos/cdrom_image.cpp | 8 ++++---- src/dos/cdrom_ioctl_linux.cpp | 8 ++++---- src/dos/cdrom_ioctl_os2.cpp | 8 ++++---- src/dos/cdrom_ioctl_win32.cpp | 8 ++++---- src/dos/dev_con.h | 8 ++++---- src/dos/dos.cpp | 8 ++++---- src/dos/dos_classes.cpp | 8 ++++---- src/dos/dos_codepages.h | 6 +++--- src/dos/dos_devices.cpp | 8 ++++---- src/dos/dos_execute.cpp | 8 ++++---- src/dos/dos_files.cpp | 8 ++++---- src/dos/dos_ioctl.cpp | 8 ++++---- src/dos/dos_keyboard_layout.cpp | 8 ++++---- src/dos/dos_keyboard_layout_data.h | 6 +++--- src/dos/dos_memory.cpp | 8 ++++---- src/dos/dos_misc.cpp | 8 ++++---- src/dos/dos_mscdex.cpp | 8 ++++---- src/dos/dos_programs.cpp | 8 ++++---- src/dos/dos_tables.cpp | 8 ++++---- src/dos/drive_cache.cpp | 8 ++++---- src/dos/drive_fat.cpp | 8 ++++---- src/dos/drive_iso.cpp | 8 ++++---- src/dos/drive_local.cpp | 8 ++++---- src/dos/drive_virtual.cpp | 8 ++++---- src/dos/drives.cpp | 8 ++++---- src/dos/drives.h | 8 ++++---- src/dosbox.cpp | 8 ++++---- src/fpu/fpu.cpp | 8 ++++---- src/fpu/fpu_instructions.h | 8 ++++---- src/fpu/fpu_instructions_x86.h | 8 ++++---- src/gui/dosbox_logo.h | 8 ++++---- src/gui/midi.cpp | 8 ++++---- src/gui/midi_alsa.h | 8 ++++---- src/gui/midi_coreaudio.h | 8 ++++---- src/gui/midi_coremidi.h | 6 +++--- src/gui/midi_oss.h | 8 ++++---- src/gui/midi_win32.h | 8 ++++---- src/gui/render.cpp | 8 ++++---- src/gui/render_loops.h | 8 ++++---- src/gui/render_scalers.cpp | 8 ++++---- src/gui/render_scalers.h | 8 ++++---- src/gui/render_simple.h | 8 ++++---- src/gui/render_templates.h | 8 ++++---- src/gui/render_templates_hq.h | 8 ++++---- src/gui/render_templates_hq2x.h | 8 ++++---- src/gui/render_templates_hq3x.h | 8 ++++---- src/gui/render_templates_sai.h | 8 ++++---- src/gui/sdl_gui.cpp | 10 +++++----- src/gui/sdl_mapper.cpp | 8 ++++---- src/gui/sdlmain.cpp | 12 ++++++------ src/hardware/adlib.cpp | 8 ++++---- src/hardware/adlib.h | 8 ++++---- src/hardware/cmos.cpp | 8 ++++---- src/hardware/dbopl.cpp | 8 ++++---- src/hardware/dbopl.h | 8 ++++---- src/hardware/disney.cpp | 8 ++++---- src/hardware/dma.cpp | 8 ++++---- src/hardware/gameblaster.cpp | 8 ++++---- src/hardware/gus.cpp | 8 ++++---- src/hardware/hardware.cpp | 8 ++++---- src/hardware/iohandler.cpp | 8 ++++---- src/hardware/ipx.cpp | 8 ++++---- src/hardware/ipxserver.cpp | 8 ++++---- src/hardware/joystick.cpp | 8 ++++---- src/hardware/keyboard.cpp | 8 ++++---- src/hardware/memory.cpp | 8 ++++---- src/hardware/mixer.cpp | 8 ++++---- src/hardware/mpu401.cpp | 8 ++++---- src/hardware/opl.cpp | 2 +- src/hardware/opl.h | 2 +- src/hardware/pci_bus.cpp | 8 ++++---- src/hardware/pci_devices.h | 8 ++++---- src/hardware/pcspeaker.cpp | 8 ++++---- src/hardware/pic.cpp | 8 ++++---- src/hardware/sblaster.cpp | 8 ++++---- src/hardware/serialport/directserial.cpp | 8 ++++---- src/hardware/serialport/directserial.h | 8 ++++---- src/hardware/serialport/libserial.cpp | 8 ++++---- src/hardware/serialport/libserial.h | 8 ++++---- src/hardware/serialport/misc_util.cpp | 8 ++++---- src/hardware/serialport/misc_util.h | 8 ++++---- src/hardware/serialport/nullmodem.cpp | 8 ++++---- src/hardware/serialport/nullmodem.h | 8 ++++---- src/hardware/serialport/serialdummy.cpp | 8 ++++---- src/hardware/serialport/serialdummy.h | 8 ++++---- src/hardware/serialport/serialport.cpp | 8 ++++---- src/hardware/serialport/softmodem.cpp | 8 ++++---- src/hardware/serialport/softmodem.h | 8 ++++---- src/hardware/tandy_sound.cpp | 8 ++++---- src/hardware/timer.cpp | 8 ++++---- src/hardware/vga.cpp | 8 ++++---- src/hardware/vga_attr.cpp | 8 ++++---- src/hardware/vga_crtc.cpp | 8 ++++---- src/hardware/vga_dac.cpp | 8 ++++---- src/hardware/vga_draw.cpp | 8 ++++---- src/hardware/vga_gfx.cpp | 8 ++++---- src/hardware/vga_memory.cpp | 8 ++++---- src/hardware/vga_misc.cpp | 8 ++++---- src/hardware/vga_other.cpp | 8 ++++---- src/hardware/vga_paradise.cpp | 8 ++++---- src/hardware/vga_s3.cpp | 8 ++++---- src/hardware/vga_seq.cpp | 8 ++++---- src/hardware/vga_tseng.cpp | 8 ++++---- src/hardware/vga_xga.cpp | 8 ++++---- src/ints/bios.cpp | 8 ++++---- src/ints/bios_disk.cpp | 8 ++++---- src/ints/bios_keyboard.cpp | 8 ++++---- src/ints/ems.cpp | 8 ++++---- src/ints/int10.cpp | 8 ++++---- src/ints/int10.h | 8 ++++---- src/ints/int10_char.cpp | 8 ++++---- src/ints/int10_memory.cpp | 8 ++++---- src/ints/int10_misc.cpp | 8 ++++---- src/ints/int10_modes.cpp | 8 ++++---- src/ints/int10_pal.cpp | 8 ++++---- src/ints/int10_put_pixel.cpp | 8 ++++---- src/ints/int10_vesa.cpp | 8 ++++---- src/ints/int10_video_state.cpp | 8 ++++---- src/ints/int10_vptable.cpp | 8 ++++---- src/ints/mouse.cpp | 8 ++++---- src/ints/xms.cpp | 8 ++++---- src/ints/xms.h | 8 ++++---- src/libs/zmbv/drvproc.cpp | 8 ++++---- src/libs/zmbv/zmbv.cpp | 8 ++++---- src/libs/zmbv/zmbv.h | 8 ++++---- src/libs/zmbv/zmbv_vfw.cpp | 8 ++++---- src/libs/zmbv/zmbv_vfw.rc | 2 +- src/misc/cross.cpp | 8 ++++---- src/misc/messages.cpp | 8 ++++---- src/misc/programs.cpp | 8 ++++---- src/misc/setup.cpp | 8 ++++---- src/misc/support.cpp | 8 ++++---- src/shell/shell.cpp | 8 ++++---- src/shell/shell_batch.cpp | 8 ++++---- src/shell/shell_cmds.cpp | 8 ++++---- src/shell/shell_misc.cpp | 8 ++++---- src/winres.rc | 4 ++-- 238 files changed, 941 insertions(+), 942 deletions(-) diff --git a/COPYING b/COPYING index d60c31a9..6b29640c 100644 --- a/COPYING +++ b/COPYING @@ -1,8 +1,8 @@ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -303,10 +303,9 @@ the "copyright" line and a pointer to where the full notice is found. 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 - + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA Also add information on how to contact you by electronic and paper mail. diff --git a/acinclude.m4 b/acinclude.m4 index 69adc0f0..9f299355 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -305,7 +305,7 @@ AC_SUBST(ALSA_LIBS) AH_TOP([ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -317,9 +317,9 @@ AH_TOP([ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ]) diff --git a/include/bios.h b/include/bios.h index af1545bb..2a7787a3 100644 --- a/include/bios.h +++ b/include/bios.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DOSBOX_BIOS_H diff --git a/include/bios_disk.h b/include/bios_disk.h index 2d175187..25c0abf9 100644 --- a/include/bios_disk.h +++ b/include/bios_disk.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DOSBOX_BIOS_DISK_H diff --git a/include/callback.h b/include/callback.h index 01632063..e7231640 100644 --- a/include/callback.h +++ b/include/callback.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/control.h b/include/control.h index ff1f8052..6d1dffbd 100644 --- a/include/control.h +++ b/include/control.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/cpu.h b/include/cpu.h index 69557d08..7478f4ca 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/cross.h b/include/cross.h index 5e65ebb0..1a81ebe0 100644 --- a/include/cross.h +++ b/include/cross.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/debug.h b/include/debug.h index cf1d8991..7871d638 100644 --- a/include/debug.h +++ b/include/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ void DEBUG_SetupConsole(void); diff --git a/include/dma.h b/include/dma.h index 196e4b4a..eea35f5b 100644 --- a/include/dma.h +++ b/include/dma.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/dos_inc.h b/include/dos_inc.h index 753af672..67f83571 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/dos_system.h b/include/dos_system.h index 0147cbda..8ab25d16 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/dosbox.h b/include/dosbox.h index db9c5114..b5e091b9 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/fpu.h b/include/fpu.h index 3611545b..da29096f 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DOSBOX_FPU_H diff --git a/include/hardware.h b/include/hardware.h index 8a474250..3a960868 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/inout.h b/include/inout.h index 8db839c1..3cd1b563 100644 --- a/include/inout.h +++ b/include/inout.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/ipx.h b/include/ipx.h index 258c598c..fb88c0d9 100644 --- a/include/ipx.h +++ b/include/ipx.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/ipxserver.h b/include/ipxserver.h index 48420f3e..b4fa9fe8 100644 --- a/include/ipxserver.h +++ b/include/ipxserver.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DOSBOX_IPXSERVER_H_ diff --git a/include/joystick.h b/include/joystick.h index b3c302e3..c3782c98 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DOSBOX_JOYSTICK_H diff --git a/include/keyboard.h b/include/keyboard.h index 058b2ac9..125c9cab 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DOSBOX_KEYBOARD_H diff --git a/include/logging.h b/include/logging.h index a6b7f8f5..0e9c40ea 100644 --- a/include/logging.h +++ b/include/logging.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DOSBOX_LOGGING_H diff --git a/include/mapper.h b/include/mapper.h index b69159ae..0fd953e4 100644 --- a/include/mapper.h +++ b/include/mapper.h @@ -1,5 +1,5 @@ - /* - * Copyright (C) 2002-2018 The DOSBox Team +/* + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DOSBOX_MAPPER_H diff --git a/include/mem.h b/include/mem.h index 40b269a7..99b082e8 100644 --- a/include/mem.h +++ b/include/mem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DOSBOX_MEM_H diff --git a/include/midi.h b/include/midi.h index fc2a5e9d..ea9afdad 100644 --- a/include/midi.h +++ b/include/midi.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/mixer.h b/include/mixer.h index a8e1aaa8..3c817537 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/mouse.h b/include/mouse.h index 880794e6..f161463b 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/paging.h b/include/paging.h index b39f74ec..168a038f 100644 --- a/include/paging.h +++ b/include/paging.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/pci_bus.h b/include/pci_bus.h index 97da4d35..3b8e332e 100644 --- a/include/pci_bus.h +++ b/include/pci_bus.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DOSBOX_PCI_H diff --git a/include/pic.h b/include/pic.h index e865f768..5022c7c9 100644 --- a/include/pic.h +++ b/include/pic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DOSBOX_PIC_H diff --git a/include/programs.h b/include/programs.h index 34039a81..ac48bd89 100644 --- a/include/programs.h +++ b/include/programs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/regs.h b/include/regs.h index 94737d38..a25ff80c 100644 --- a/include/regs.h +++ b/include/regs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DOSBOX_REGS_H diff --git a/include/render.h b/include/render.h index c25ed82c..6c8df98a 100644 --- a/include/render.h +++ b/include/render.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DOSBOX_RENDER_H diff --git a/include/serialport.h b/include/serialport.h index c9aa091f..e9bbc543 100644 --- a/include/serialport.h +++ b/include/serialport.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/setup.h b/include/setup.h index 30e6503c..3622d0f8 100644 --- a/include/setup.h +++ b/include/setup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/shell.h b/include/shell.h index d585f3e8..7835e4b3 100644 --- a/include/shell.h +++ b/include/shell.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/support.h b/include/support.h index 7ec5f117..bd21e654 100644 --- a/include/support.h +++ b/include/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/timer.h b/include/timer.h index bddedc08..d723e013 100644 --- a/include/timer.h +++ b/include/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DOSBOX_TIMER_H diff --git a/include/vga.h b/include/vga.h index 34e08e4e..e204105b 100644 --- a/include/vga.h +++ b/include/vga.h @@ -1,5 +1,5 @@ - /* - * Copyright (C) 2002-2018 The DOSBox Team +/* + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/include/video.h b/include/video.h index 5a7a4ae8..3696ced7 100644 --- a/include/video.h +++ b/include/video.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/scripts/dosbox-installer.nsi b/scripts/dosbox-installer.nsi index 27b527bf..debbb369 100644 --- a/scripts/dosbox-installer.nsi +++ b/scripts/dosbox-installer.nsi @@ -2,7 +2,7 @@ !define VER_MINOR 74 !define APP_NAME "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer" !define COMP_NAME "DOSBox Team" -!define COPYRIGHT "Copyright © 2002-2018 DOSBox Team" +!define COPYRIGHT "Copyright © 2002-2019 DOSBox Team" !define DESCRIPTION "DOSBox Installer" VIProductVersion "${VER_MAYOR}.${VER_MINOR}.0.0" diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 25c91aeb..2e5e63cd 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 70c0091d..0d354291 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 71a6513d..8a42d0d5 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index c34052f2..7b0f6411 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dyn_x86/dyn_fpu.h b/src/cpu/core_dyn_x86/dyn_fpu.h index 49f1fef8..ec4afc68 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu.h +++ b/src/cpu/core_dyn_x86/dyn_fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dyn_x86/dyn_fpu_dh.h b/src/cpu/core_dyn_x86/dyn_fpu_dh.h index f68d69b0..03b6bd5d 100644 --- a/src/cpu/core_dyn_x86/dyn_fpu_dh.h +++ b/src/cpu/core_dyn_x86/dyn_fpu_dh.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dyn_x86/helpers.h b/src/cpu/core_dyn_x86/helpers.h index c2b0de9f..0cea15cd 100644 --- a/src/cpu/core_dyn_x86/helpers.h +++ b/src/cpu/core_dyn_x86/helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static bool dyn_helper_divb(Bit8u val) { diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index 379906f9..f0f06502 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dyn_x86/string.h b/src/cpu/core_dyn_x86/string.h index ea540ab4..60cfc8e0 100644 --- a/src/cpu/core_dyn_x86/string.h +++ b/src/cpu/core_dyn_x86/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ enum STRING_OP { diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index e0e32be6..2c80bb7e 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index 4158ff31..61ac83b4 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h index c34e9a79..384185ad 100644 --- a/src/cpu/core_dynrec/decoder.h +++ b/src/cpu/core_dynrec/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index 363c1df0..b91c2665 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index cd460b9b..09e35631 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dynrec/dyn_fpu.h b/src/cpu/core_dynrec/dyn_fpu.h index cdb3e721..a32ad1bd 100644 --- a/src/cpu/core_dynrec/dyn_fpu.h +++ b/src/cpu/core_dynrec/dyn_fpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dynrec/operators.h b/src/cpu/core_dynrec/operators.h index 756eed9b..5f628350 100644 --- a/src/cpu/core_dynrec/operators.h +++ b/src/cpu/core_dynrec/operators.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dynrec/risc_armv4le-common.h b/src/cpu/core_dynrec/risc_armv4le-common.h index 6d86c7ee..9b0cae61 100644 --- a/src/cpu/core_dynrec/risc_armv4le-common.h +++ b/src/cpu/core_dynrec/risc_armv4le-common.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dynrec/risc_armv4le-o3.h b/src/cpu/core_dynrec/risc_armv4le-o3.h index 5eaafcf6..88a1f069 100644 --- a/src/cpu/core_dynrec/risc_armv4le-o3.h +++ b/src/cpu/core_dynrec/risc_armv4le-o3.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h index 9f24bb90..400ae9be 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-iw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h index f49ffe6e..c6e0c9f2 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb.h b/src/cpu/core_dynrec/risc_armv4le-thumb.h index 18e87541..8db5f1ea 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dynrec/risc_armv4le.h b/src/cpu/core_dynrec/risc_armv4le.h index a93a8652..80f10604 100644 --- a/src/cpu/core_dynrec/risc_armv4le.h +++ b/src/cpu/core_dynrec/risc_armv4le.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dynrec/risc_armv8le.h b/src/cpu/core_dynrec/risc_armv8le.h index fe4ecc53..3e455adf 100644 --- a/src/cpu/core_dynrec/risc_armv8le.h +++ b/src/cpu/core_dynrec/risc_armv8le.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dynrec/risc_mipsel32.h b/src/cpu/core_dynrec/risc_mipsel32.h index 9aa40efc..a36e451c 100644 --- a/src/cpu/core_dynrec/risc_mipsel32.h +++ b/src/cpu/core_dynrec/risc_mipsel32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index d6617697..036cd2de 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_dynrec/risc_x86.h b/src/cpu/core_dynrec/risc_x86.h index e5e46f46..82b0013f 100644 --- a/src/cpu/core_dynrec/risc_x86.h +++ b/src/cpu/core_dynrec/risc_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_full.cpp b/src/cpu/core_full.cpp index 4e5e3909..20a62d1b 100644 --- a/src/cpu/core_full.cpp +++ b/src/cpu/core_full.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "dosbox.h" diff --git a/src/cpu/core_full/ea_lookup.h b/src/cpu/core_full/ea_lookup.h index b01a684b..b7c146a1 100644 --- a/src/cpu/core_full/ea_lookup.h +++ b/src/cpu/core_full/ea_lookup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index e9b60fe0..6645860c 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ switch (inst.code.load) { diff --git a/src/cpu/core_full/loadwrite.h b/src/cpu/core_full/loadwrite.h index 985a6443..e432a1f0 100644 --- a/src/cpu/core_full/loadwrite.h +++ b/src/cpu/core_full/loadwrite.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define SaveIP() reg_eip=(Bit32u)(inst.cseip-SegBase(cs)); diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 81ce577a..cbbf19a8 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Do the actual opcode */ diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index be66c12d..7a0ac82f 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Big ass opcode table normal,double, 66 normal, 66 double */ diff --git a/src/cpu/core_full/save.h b/src/cpu/core_full/save.h index 5862bb74..c494f4ba 100644 --- a/src/cpu/core_full/save.h +++ b/src/cpu/core_full/save.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Write the data from the opcode */ diff --git a/src/cpu/core_full/string.h b/src/cpu/core_full/string.h index f760683f..943c7f75 100644 --- a/src/cpu/core_full/string.h +++ b/src/cpu/core_full/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 7a9e036a..6ac7711e 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ enum { diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 103657bf..0049c2c2 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include diff --git a/src/cpu/core_normal/helpers.h b/src/cpu/core_normal/helpers.h index 58205aec..bd4d72e5 100644 --- a/src/cpu/core_normal/helpers.h +++ b/src/cpu/core_normal/helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 33d8cf6c..c19ac755 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ CASE_0F_W(0x00) /* GRP 6 Exxx */ diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 9c199374..baa295e5 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ CASE_D(0x01) /* ADD Ed,Gd */ diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index dbae2985..38966aa7 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ CASE_0F_D(0x00) /* GRP 6 Exxx */ diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 9221392e..525c4b9b 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ CASE_B(0x00) /* ADD Eb,Gb */ diff --git a/src/cpu/core_normal/string.h b/src/cpu/core_normal/string.h index a5e90611..5fdbe107 100644 --- a/src/cpu/core_normal/string.h +++ b/src/cpu/core_normal/string.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ enum STRING_OP { diff --git a/src/cpu/core_normal/support.h b/src/cpu/core_normal/support.h index 87d79726..9b94b783 100644 --- a/src/cpu/core_normal/support.h +++ b/src/cpu/core_normal/support.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_normal/table_ea.h b/src/cpu/core_normal/table_ea.h index 9ca2b0c7..f4a764a7 100644 --- a/src/cpu/core_normal/table_ea.h +++ b/src/cpu/core_normal/table_ea.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ typedef PhysPt (*EA_LookupHandler)(void); diff --git a/src/cpu/core_prefetch.cpp b/src/cpu/core_prefetch.cpp index 036c6a92..58e2df76 100644 --- a/src/cpu/core_prefetch.cpp +++ b/src/cpu/core_prefetch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp index 19f13436..96748190 100644 --- a/src/cpu/core_simple.cpp +++ b/src/cpu/core_simple.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 659d4a80..95cd2839 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 63b7b45b..55c6fa86 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 17bddb72..9265f6cd 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Jumps */ diff --git a/src/cpu/lazyflags.h b/src/cpu/lazyflags.h index 39994707..c110681f 100644 --- a/src/cpu/lazyflags.h +++ b/src/cpu/lazyflags.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DOSBOX_LAZYFLAGS_H diff --git a/src/cpu/modrm.cpp b/src/cpu/modrm.cpp index 0004825e..79538bca 100644 --- a/src/cpu/modrm.cpp +++ b/src/cpu/modrm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "cpu.h" diff --git a/src/cpu/modrm.h b/src/cpu/modrm.h index c639c374..f6d1a2a5 100644 --- a/src/cpu/modrm.h +++ b/src/cpu/modrm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ extern Bit8u * lookupRMregb[]; diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 57d8898b..b91cdfaf 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index a6e4b7c7..dcf0b800 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index d1fa5c46..a9ab9da9 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/debug/debug_inc.h b/src/debug/debug_inc.h index 28517ce0..0c8f638d 100644 --- a/src/debug/debug_inc.h +++ b/src/debug/debug_inc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Local Debug Function */ diff --git a/src/debug/debug_win32.cpp b/src/debug/debug_win32.cpp index 23826fc1..090ab693 100644 --- a/src/debug/debug_win32.cpp +++ b/src/debug/debug_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "dosbox.h" diff --git a/src/debug/disasm_tables.h b/src/debug/disasm_tables.h index 93d1bcb7..25453a31 100644 --- a/src/debug/disasm_tables.h +++ b/src/debug/disasm_tables.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ char * RegTable_16[8]= {"ax","cx","dx","bx","sp","bp","si","di"}; diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index 9608e87d..06d47de1 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index 803c7aa2..c1219c7a 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/cdrom_aspi_win32.cpp b/src/dos/cdrom_aspi_win32.cpp index cc8de4e3..aeed5ea3 100644 --- a/src/dos/cdrom_aspi_win32.cpp +++ b/src/dos/cdrom_aspi_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 0e81a83d..b1fc1c59 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/cdrom_ioctl_linux.cpp b/src/dos/cdrom_ioctl_linux.cpp index fb73986e..846db8b7 100644 --- a/src/dos/cdrom_ioctl_linux.cpp +++ b/src/dos/cdrom_ioctl_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/cdrom_ioctl_os2.cpp b/src/dos/cdrom_ioctl_os2.cpp index 6e32af55..926a85a3 100644 --- a/src/dos/cdrom_ioctl_os2.cpp +++ b/src/dos/cdrom_ioctl_os2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index 0974c5e7..74b568b1 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/dev_con.h b/src/dos/dev_con.h index c18b84cb..330b56f2 100644 --- a/src/dos/dev_con.h +++ b/src/dos/dev_con.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 5981df01..7f12f102 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index d407b04d..fd45eda4 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/dos_codepages.h b/src/dos/dos_codepages.h index 9b69f61c..d5b1bbed 100644 --- a/src/dos/dos_codepages.h +++ b/src/dos/dos_codepages.h @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/dos_devices.cpp b/src/dos/dos_devices.cpp index 89fe3531..9beb4305 100644 --- a/src/dos/dos_devices.cpp +++ b/src/dos/dos_devices.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index b27decdb..bf180268 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index a9175c29..b78325ae 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/dos_ioctl.cpp b/src/dos/dos_ioctl.cpp index ad8ebe42..90ef826f 100644 --- a/src/dos/dos_ioctl.cpp +++ b/src/dos/dos_ioctl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index f27ddb9a..f600fc63 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/dos_keyboard_layout_data.h b/src/dos/dos_keyboard_layout_data.h index 8e601115..e850a6c3 100644 --- a/src/dos/dos_keyboard_layout_data.h +++ b/src/dos/dos_keyboard_layout_data.h @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index b8d6a33f..fa78e73e 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/dos_misc.cpp b/src/dos/dos_misc.cpp index 163883c4..c1a7d2e9 100644 --- a/src/dos/dos_misc.cpp +++ b/src/dos/dos_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index a6d1b9c3..23e60b31 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index cdea5d7b..4ca3ada2 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index b7687d6d..6ed87c46 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 00ef06de..a07bc119 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 1332285f..63bfc155 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 2faa8aca..937a8a3a 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 46ebb7df..c6d82d26 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/drive_virtual.cpp b/src/dos/drive_virtual.cpp index 0b42bcbd..b0261289 100644 --- a/src/dos/drive_virtual.cpp +++ b/src/dos/drive_virtual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index 62e281ac..6b312bd6 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dos/drives.h b/src/dos/drives.h index 14f38315..589b6da4 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 966b0b42..1e48915c 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 86131b5c..aa8f062f 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 2e792d1d..c0c3d090 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index fd245220..5b62177d 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/gui/dosbox_logo.h b/src/gui/dosbox_logo.h index 1d1053e4..73925ffa 100644 --- a/src/gui/dosbox_logo.h +++ b/src/gui/dosbox_logo.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp index d17963e4..b5361051 100644 --- a/src/gui/midi.cpp +++ b/src/gui/midi.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include diff --git a/src/gui/midi_alsa.h b/src/gui/midi_alsa.h index 9041fd7e..9bf4b4f9 100644 --- a/src/gui/midi_alsa.h +++ b/src/gui/midi_alsa.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/gui/midi_coreaudio.h b/src/gui/midi_coreaudio.h index b92e649d..95d39027 100644 --- a/src/gui/midi_coreaudio.h +++ b/src/gui/midi_coreaudio.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/gui/midi_coremidi.h b/src/gui/midi_coremidi.h index 057d67fb..9ad046b2 100644 --- a/src/gui/midi_coremidi.h +++ b/src/gui/midi_coremidi.h @@ -9,9 +9,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h index f4269ead..00c1cad7 100644 --- a/src/gui/midi_oss.h +++ b/src/gui/midi_oss.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h index d970860e..b7180f6d 100644 --- a/src/gui/midi_win32.h +++ b/src/gui/midi_win32.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/gui/render.cpp b/src/gui/render.cpp index d6be555d..941fe76f 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/gui/render_loops.h b/src/gui/render_loops.h index f67a5069..635da6bf 100644 --- a/src/gui/render_loops.h +++ b/src/gui/render_loops.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #if defined (SCALERLINEAR) diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index a84a27e4..6a0f3df2 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index 82fd43f5..f4351cb6 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _RENDER_SCALERS_H diff --git a/src/gui/render_simple.h b/src/gui/render_simple.h index 07b0b120..f6e587d7 100644 --- a/src/gui/render_simple.h +++ b/src/gui/render_simple.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index e1c1ddbd..30643937 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #if DBPP == 8 diff --git a/src/gui/render_templates_hq.h b/src/gui/render_templates_hq.h index 9f676152..002f1fff 100644 --- a/src/gui/render_templates_hq.h +++ b/src/gui/render_templates_hq.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* diff --git a/src/gui/render_templates_hq2x.h b/src/gui/render_templates_hq2x.h index 28c6c429..bcec3575 100644 --- a/src/gui/render_templates_hq2x.h +++ b/src/gui/render_templates_hq2x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* diff --git a/src/gui/render_templates_hq3x.h b/src/gui/render_templates_hq3x.h index 33c5ab35..e067cb86 100644 --- a/src/gui/render_templates_hq3x.h +++ b/src/gui/render_templates_hq3x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* diff --git a/src/gui/render_templates_sai.h b/src/gui/render_templates_sai.h index cf7b5e8b..95103367 100644 --- a/src/gui/render_templates_sai.h +++ b/src/gui/render_templates_sai.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static inline int conc2d(GetResult,SBPP)(PTYPE A, PTYPE B, PTYPE C, PTYPE D) { diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index 3986d399..3318af20 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ @@ -569,7 +569,7 @@ public: Section_prop *section = static_cast(sec); new SectionEditor(getScreen(), 50, 30, section); } else if (arg == "About") { - new GUI::MessageBox(getScreen(), 200, 150, 280, "About DOSBox", "\nDOSBox 0.74\nAn emulator for old DOS Games\n\nCopyright 2002-2018\nThe DOSBox Team"); + new GUI::MessageBox(getScreen(), 200, 150, 280, "About DOSBox", "\nDOSBox 0.74\nAn emulator for old DOS Games\n\nCopyright 2002-2019\nThe DOSBox Team"); } else if (arg == "Introduction") { new GUI::MessageBox(getScreen(), 20, 50, 600, "Introduction", MSG_Get("PROGRAM_INTRO")); } else if (arg == "Getting Started") { diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index db8a4ea9..471777ca 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 9dde5dcb..c05821bf 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ @@ -2004,7 +2004,7 @@ int main(int argc, char* argv[]) { #endif //defined(WIN32) && !(C_DEBUG) if (control->cmdline->FindExist("-version") || control->cmdline->FindExist("--version") ) { - printf("\nDOSBox version %s, copyright 2002-2018 DOSBox Team.\n\n",VERSION); + printf("\nDOSBox version %s, copyright 2002-2019 DOSBox Team.\n\n",VERSION); printf("DOSBox is written by the DOSBox Team (See AUTHORS file))\n"); printf("DOSBox comes with ABSOLUTELY NO WARRANTY. This is free software,\n"); printf("and you are welcome to redistribute it under certain conditions;\n"); @@ -2032,7 +2032,7 @@ int main(int argc, char* argv[]) { /* Display Welcometext in the console */ LOG_MSG("DOSBox version %s",VERSION); - LOG_MSG("Copyright 2002-2018 DOSBox Team, published under GNU GPL."); + LOG_MSG("Copyright 2002-2019 DOSBox Team, published under GNU GPL."); LOG_MSG("---"); /* Init SDL */ diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index e0b4c598..e0b082f9 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/adlib.h b/src/hardware/adlib.h index 5d5065ad..e22d49ea 100644 --- a/src/hardware/adlib.h +++ b/src/hardware/adlib.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 362aa54b..e909d382 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index 4416c50a..acbf2b8f 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* diff --git a/src/hardware/dbopl.h b/src/hardware/dbopl.h index 4e61b118..addaed77 100644 --- a/src/hardware/dbopl.h +++ b/src/hardware/dbopl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "adlib.h" diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 671487c9..629d94ba 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 4ab4277f..f9f26deb 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index 0047962a..c602c0a0 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "dosbox.h" diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index a539b135..d1d7e424 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index d66143f9..b0dc7bd6 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 816e3c4a..4954ae98 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index d9379557..8b410dae 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/ipxserver.cpp b/src/hardware/ipxserver.cpp index 1f4554e4..d22ac775 100644 --- a/src/hardware/ipxserver.cpp +++ b/src/hardware/ipxserver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index e2318bff..b6fe5c8c 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 4991730c..b70995c0 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index a8357b15..5069b8a5 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 1fbe4443..41f291f1 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 4f9e4f30..c79338a1 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/opl.cpp b/src/hardware/opl.cpp index 54155c5d..ea42d656 100644 --- a/src/hardware/opl.cpp +++ b/src/hardware/opl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 The DOSBox Team * OPL2/OPL3 emulation library * * This library is free software; you can redistribute it and/or diff --git a/src/hardware/opl.h b/src/hardware/opl.h index fd7d7584..50291c52 100644 --- a/src/hardware/opl.h +++ b/src/hardware/opl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 The DOSBox Team * OPL2/OPL3 emulation library * * This library is free software; you can redistribute it and/or diff --git a/src/hardware/pci_bus.cpp b/src/hardware/pci_bus.cpp index dddb6468..05e5d677 100644 --- a/src/hardware/pci_bus.cpp +++ b/src/hardware/pci_bus.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/pci_devices.h b/src/hardware/pci_devices.h index 69730055..86f5f2dc 100644 --- a/src/hardware/pci_devices.h +++ b/src/hardware/pci_devices.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,8 +11,8 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 39ee957c..bde5ba02 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/pic.cpp b/src/hardware/pic.cpp index 0bdba54a..9a681d51 100644 --- a/src/hardware/pic.cpp +++ b/src/hardware/pic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "dosbox.h" diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 0c0a1c32..e4a9b029 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/serialport/directserial.cpp b/src/hardware/serialport/directserial.cpp index d4c26977..c6ef6e49 100644 --- a/src/hardware/serialport/directserial.cpp +++ b/src/hardware/serialport/directserial.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/serialport/directserial.h b/src/hardware/serialport/directserial.h index 9955bf09..8c252357 100644 --- a/src/hardware/serialport/directserial.h +++ b/src/hardware/serialport/directserial.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/serialport/libserial.cpp b/src/hardware/serialport/libserial.cpp index 07860319..35eaddc6 100644 --- a/src/hardware/serialport/libserial.cpp +++ b/src/hardware/serialport/libserial.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/serialport/libserial.h b/src/hardware/serialport/libserial.h index 417ff83a..92077772 100644 --- a/src/hardware/serialport/libserial.h +++ b/src/hardware/serialport/libserial.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/serialport/misc_util.cpp b/src/hardware/serialport/misc_util.cpp index e21ddb19..b0eed831 100644 --- a/src/hardware/serialport/misc_util.cpp +++ b/src/hardware/serialport/misc_util.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id $ */ diff --git a/src/hardware/serialport/misc_util.h b/src/hardware/serialport/misc_util.h index b866669d..a15c6937 100644 --- a/src/hardware/serialport/misc_util.h +++ b/src/hardware/serialport/misc_util.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/serialport/nullmodem.cpp b/src/hardware/serialport/nullmodem.cpp index 3663ab75..95fc232c 100644 --- a/src/hardware/serialport/nullmodem.cpp +++ b/src/hardware/serialport/nullmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/serialport/nullmodem.h b/src/hardware/serialport/nullmodem.h index c5f648e1..15859e52 100644 --- a/src/hardware/serialport/nullmodem.h +++ b/src/hardware/serialport/nullmodem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/serialport/serialdummy.cpp b/src/hardware/serialport/serialdummy.cpp index ce3ff19a..a3aaf9e0 100644 --- a/src/hardware/serialport/serialdummy.cpp +++ b/src/hardware/serialport/serialdummy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/serialport/serialdummy.h b/src/hardware/serialport/serialdummy.h index d5c00328..9df7c2c4 100644 --- a/src/hardware/serialport/serialdummy.h +++ b/src/hardware/serialport/serialdummy.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/serialport/serialport.cpp b/src/hardware/serialport/serialport.cpp index e74bfccd..7f862799 100644 --- a/src/hardware/serialport/serialport.cpp +++ b/src/hardware/serialport/serialport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index ef109f6c..63625b3d 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index 81e49d71..63b0a124 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 7e29739e..fe9101f6 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 0173f99a..dce8d4ac 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 3d453846..386faeed 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index 3d48d8ed..ea7b17ca 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 47e2368c..541ea13f 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index f5cd529f..80f6f361 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "dosbox.h" diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 9a939975..80217750 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index 40e04203..86d3520b 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index dcd5e47d..e52bff04 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 6ca9a8ad..3218fc14 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 1e0f91d2..63be10a6 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/vga_paradise.cpp b/src/hardware/vga_paradise.cpp index 59b56420..f2f1334f 100644 --- a/src/hardware/vga_paradise.cpp +++ b/src/hardware/vga_paradise.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/vga_s3.cpp b/src/hardware/vga_s3.cpp index 87bbbedb..b0347ea8 100644 --- a/src/hardware/vga_s3.cpp +++ b/src/hardware/vga_s3.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 7cd711c4..7ce5ab2a 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/vga_tseng.cpp b/src/hardware/vga_tseng.cpp index 576346a0..14f38e72 100644 --- a/src/hardware/vga_tseng.cpp +++ b/src/hardware/vga_tseng.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp index def606d9..58470ab0 100644 --- a/src/hardware/vga_xga.cpp +++ b/src/hardware/vga_xga.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 9364aec0..ce9b90b0 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index d2afcaa8..f3eaab78 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 8c234c7a..ef14570f 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index c8357069..94aed6ae 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 2a8f9967..a5cfa797 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/ints/int10.h b/src/ints/int10.h index fa3d6f7c..2ba402e0 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 4acf8cf1..084f2507 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 1d1e2cd3..2bfd42fc 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 572da17f..cc4673d8 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index 795013e7..a3ad0aec 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 8b3b596c..39d6c8fa 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "dosbox.h" diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index ec7cd967..1e052cd9 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index fde8ce9c..6e3801b7 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/ints/int10_video_state.cpp b/src/ints/int10_video_state.cpp index 37888bb3..0dbc34e6 100644 --- a/src/ints/int10_video_state.cpp +++ b/src/ints/int10_video_state.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/ints/int10_vptable.cpp b/src/ints/int10_vptable.cpp index aca7a7d3..3ec451d3 100644 --- a/src/ints/int10_vptable.cpp +++ b/src/ints/int10_vptable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index 2d0d5d77..c61dfdf8 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index 60b84a1b..1e0bf899 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/ints/xms.h b/src/ints/xms.h index cca119bb..d397c498 100644 --- a/src/ints/xms.h +++ b/src/ints/xms.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __XMS_H__ diff --git a/src/libs/zmbv/drvproc.cpp b/src/libs/zmbv/drvproc.cpp index ffbfe4f3..44b6ab61 100644 --- a/src/libs/zmbv/drvproc.cpp +++ b/src/libs/zmbv/drvproc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // // Zipped Motion Block Video diff --git a/src/libs/zmbv/zmbv.cpp b/src/libs/zmbv/zmbv.cpp index 22044d28..dc2c0478 100644 --- a/src/libs/zmbv/zmbv.cpp +++ b/src/libs/zmbv/zmbv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include diff --git a/src/libs/zmbv/zmbv.h b/src/libs/zmbv/zmbv.h index 782832b1..7a6705c0 100644 --- a/src/libs/zmbv/zmbv.h +++ b/src/libs/zmbv/zmbv.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DOSBOX_DOSBOX_H diff --git a/src/libs/zmbv/zmbv_vfw.cpp b/src/libs/zmbv/zmbv_vfw.cpp index 0dfae332..eedb92d6 100644 --- a/src/libs/zmbv/zmbv_vfw.cpp +++ b/src/libs/zmbv/zmbv_vfw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // // Zipped Motion Block Video diff --git a/src/libs/zmbv/zmbv_vfw.rc b/src/libs/zmbv/zmbv_vfw.rc index bd5ac62d..643418af 100644 --- a/src/libs/zmbv/zmbv_vfw.rc +++ b/src/libs/zmbv/zmbv_vfw.rc @@ -59,7 +59,7 @@ CAPTION "DOSBox Video Codec v0.1" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN DEFPUSHBUTTON "OK",IDOK,131,34,29,14 - CTEXT "Zipped Motion Block Video v 0.1\nCopyright 2009-2018 DOSBox Team", + CTEXT "Zipped Motion Block Video v 0.1\nCopyright 2009-2019 DOSBox Team", IDC_STATIC,7,7,153,25,SS_NOPREFIX PUSHBUTTON "Email author",IDC_EMAIL,7,34,50,14 PUSHBUTTON "Visit home page",IDC_HOMEPAGE,59,34,58,14 diff --git a/src/misc/cross.cpp b/src/misc/cross.cpp index 021d8f35..80b2324b 100644 --- a/src/misc/cross.cpp +++ b/src/misc/cross.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 0ab465de..b0e65941 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index cd265c5d..ed1d3c96 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 56d836de..cfac48f4 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 339a6196..89f7802a 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index a04135c9..51141cb9 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 9d92df38..033def6f 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 9762cfc6..e1d688c3 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 99f44865..8575eb12 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2018 The DOSBox Team + * Copyright (C) 2002-2019 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 @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/src/winres.rc b/src/winres.rc index 99292c2e..176cf8b4 100644 --- a/src/winres.rc +++ b/src/winres.rc @@ -19,12 +19,12 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "Comments", "© 2002-2018 DOSBox Team, published under GNU GPL" + VALUE "Comments", "© 2002-2019 DOSBox Team, published under GNU GPL" VALUE "CompanyName", "DOSBox Team" VALUE "FileDescription", "DOSBox DOS Emulator" VALUE "FileVersion", "0, 74, 0, 0" VALUE "InternalName", "DOSBox" - VALUE "LegalCopyright", "Copyright © 2002-2018 DOSBox Team" + VALUE "LegalCopyright", "Copyright © 2002-2019 DOSBox Team" VALUE "OriginalFilename", "dosbox.exe" VALUE "ProductName", "DOSBox DOS Emulator" VALUE "ProductVersion", "0, 74, 0, 0" From 4e88b1eb2c45f4a4acac92d724444900885d3d6c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Jan 2019 14:34:47 +0000 Subject: [PATCH 4074/4131] Do it for both read-only modi Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4184 --- src/dos/drive_local.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index c6d82d26..d2ba17d1 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -450,7 +450,8 @@ bool localFile::Read(Bit8u * data,Bit16u * size) { } bool localFile::Write(Bit8u * data,Bit16u * size) { - if ((this->flags & 0xf) == OPEN_READ) { // check if file opened in read-only mode + Bit32u lastflags = this->flags & 0xf; + if (lastflags == OPEN_READ || lastflags == OPEN_READ_NO_MOD) { // check if file opened in read-only mode DOS_SetError(DOSERR_ACCESS_DENIED); return false; } From fdd8358de7cdc149ad8d9fdbc87bc28dd6bc2853 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 28 Jan 2019 14:26:19 +0000 Subject: [PATCH 4075/4131] Make feature checks consistent, include right header for memset, correct one off error in paging table size compare for when not using USE_FULL_TLB (jmarsh) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4185 --- include/paging.h | 2 +- src/gui/sdlmain.cpp | 4 ++-- src/hardware/opl.cpp | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/paging.h b/include/paging.h index 168a038f..7126e26b 100644 --- a/include/paging.h +++ b/include/paging.h @@ -224,7 +224,7 @@ 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)) { + if (TLB_BANKS && (index >= TLB_SIZE)) { Bitu bank=(address>>BANK_SHIFT) - 1; if (!paging.tlbh_banks[bank]) PAGING_InitTLBBank(&paging.tlbh_banks[bank]); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index c05821bf..282e100e 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -234,7 +234,7 @@ SDL_Surface* SDL_SetVideoMode_Wrap(int width,int height,int bpp,Bit32u flags){ // I don't see a difference, so disabled for now, as the code isn't finished either #if SETMODE_SAVES_CLEAR //TODO clear it. -#ifdef C_OPENGL +#if C_OPENGL if ((flags & SDL_OPENGL)==0) SDL_FillRect(sdl.surface,NULL,SDL_MapRGB(sdl.surface->format,0,0,0)); else { @@ -309,7 +309,7 @@ static void GFX_SetIcon() { /* Set Icon (must be done before any sdl_setvideomode call) */ /* But don't set it on OS X, as we use a nicer external icon there. */ /* Made into a separate call, so it can be called again when we restart the graphics output on win32 */ -#if WORDS_BIGENDIAN +#ifdef WORDS_BIGENDIAN SDL_Surface* logos= SDL_CreateRGBSurfaceFrom((void*)logo,32,32,32,128,0xff000000,0x00ff0000,0x0000ff00,0); #else SDL_Surface* logos= SDL_CreateRGBSurfaceFrom((void*)logo,32,32,32,128,0x000000ff,0x0000ff00,0x00ff0000,0); diff --git a/src/hardware/opl.cpp b/src/hardware/opl.cpp index ea42d656..a8f21f71 100644 --- a/src/hardware/opl.cpp +++ b/src/hardware/opl.cpp @@ -27,6 +27,7 @@ #include #include // rand() +#include // memset() #include "dosbox.h" #include "opl.h" From 014326476f5285ada5d3d8fbcdd98846dbf28243 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Mon, 4 Feb 2019 15:09:56 +0000 Subject: [PATCH 4076/4131] CMOS equipment list startup display mode bits differ from BIOS on EGA/VGA; fixes Sauro. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4186 --- src/ints/bios.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index ce9b90b0..ef906283 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1283,6 +1283,7 @@ public: // Gameport config |= 0x1000; mem_writew(BIOS_CONFIGURATION,config); + if (IS_EGAVGA_ARCH) config &= ~0x30; //EGA/VGA startup display mode differs in CMOS CMOS_SetRegister(0x14,(Bit8u)(config&0xff)); //Should be updated on changes /* Setup extended memory size */ IO_Write(0x70,0x30); @@ -1337,6 +1338,7 @@ void BIOS_SetComPorts(Bit16u baseaddr[]) { equipmentword &= (~0x0E00); equipmentword |= (portcount << 9); mem_writew(BIOS_CONFIGURATION,equipmentword); + if (IS_EGAVGA_ARCH) equipmentword &= ~0x30; //EGA/VGA startup display mode differs in CMOS CMOS_SetRegister(0x14,(Bit8u)(equipmentword&0xff)); //Should be updated on changes } From d4c38121c9032e86ecb952772b9dbcc30a777a17 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Mon, 4 Feb 2019 15:11:50 +0000 Subject: [PATCH 4077/4131] Implement timer 2 output on port 61h; fixes SB detection in Abaron. Also implement port 62h with timer 2 output for CGA and Hercules machine types; fixes Frank Bruno's Boxing and Math Maze. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4187 --- src/hardware/keyboard.cpp | 11 ++++++++++- src/hardware/timer.cpp | 4 ++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index b70995c0..97fbd86c 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -170,9 +170,11 @@ static void write_p60(Bitu port,Bitu val,Bitu iolen) { } } +extern bool TIMER_GetOutput2(void); static Bit8u port_61_data = 0; static Bitu read_p61(Bitu port,Bitu iolen) { - port_61_data^=0x20; + if (TIMER_GetOutput2()) port_61_data|=0x20; + else port_61_data&=~0x20; port_61_data^=0x10; return port_61_data; } @@ -186,6 +188,12 @@ static void write_p61(Bitu port,Bitu val,Bitu iolen) { port_61_data = val; } +static Bitu read_p62(Bitu port,Bitu iolen) { + Bit8u ret=~0x20; + if (TIMER_GetOutput2()) ret|=0x20; + return ret; +} + static void write_p64(Bitu port,Bitu val,Bitu iolen) { switch (val) { case 0xae: /* Activate keyboard */ @@ -377,6 +385,7 @@ void KEYBOARD_Init(Section* sec) { IO_RegisterReadHandler(0x60,read_p60,IO_MB); IO_RegisterWriteHandler(0x61,write_p61,IO_MB); IO_RegisterReadHandler(0x61,read_p61,IO_MB); + if (machine==MCH_CGA || machine==MCH_HERC) IO_RegisterReadHandler(0x62,read_p62,IO_MB); IO_RegisterWriteHandler(0x64,write_p64,IO_MB); IO_RegisterReadHandler(0x64,read_p64,IO_MB); TIMER_AddTickHandler(&KEYBOARD_TickHandler); diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index dce8d4ac..ac07064f 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -402,6 +402,10 @@ void TIMER_SetGate2(bool in) { gate2 = in; //Set it here so the counter_latch above works } +bool TIMER_GetOutput2(void) { + return counter_output(2); +} + class TIMER:public Module_base{ private: IO_ReadHandleObject ReadHandler[4]; From 64d25c4be4d518ffa25f9f2c4e079617cf4f2ffc Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Mon, 4 Feb 2019 15:15:58 +0000 Subject: [PATCH 4078/4131] Acknowledge mouse interrupt before entering user routine; fixes sound stutter during mouse movement in Eye of the Beholder III and Casino Tournament of Champions. Clear button counters in the mouse driver reset function; prevents unintended skipping of intro in MechWarrior and others. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4188 --- include/callback.h | 3 ++- src/cpu/callback.cpp | 56 ++++++++++++++++++++++++++++++++------------ src/dos/dos.cpp | 6 ++--- src/ints/mouse.cpp | 54 +++++++++++++++++++++++++++++++----------- 4 files changed, 85 insertions(+), 34 deletions(-) diff --git a/include/callback.h b/include/callback.h index e7231640..03008e45 100644 --- a/include/callback.h +++ b/include/callback.h @@ -27,7 +27,8 @@ typedef Bitu (*CallBack_Handler)(void); 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_RETN,CB_RETF,CB_RETF8,CB_RETF_STI,CB_RETF_CLI, + CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1, 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,CB_INT13,CB_VESA_WAIT,CB_VESA_PM }; diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 2e5e63cd..136888a6 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -173,6 +173,26 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ phys_writeb(physAddress+0x00,(Bit8u)0xCA); //A RETF 8 Instruction phys_writew(physAddress+0x01,(Bit16u)0x0008); return (use_cb?7:3); + case CB_RETF_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,(Bit16u)callback); //The immediate word + physAddress+=4; + } + phys_writeb(physAddress+0x01,(Bit8u)0xCB); //A RETF Instruction + return (use_cb?6:2); + case CB_RETF_CLI: + phys_writeb(physAddress+0x00,(Bit8u)0xFA); //CLI + if (use_cb) { + phys_writeb(physAddress+0x01,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x02,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x03,(Bit16u)callback); //The immediate word + physAddress+=4; + } + phys_writeb(physAddress+0x01,(Bit8u)0xCB); //A RETF Instruction + return (use_cb?6:2); case CB_IRET: if (use_cb) { phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4 @@ -282,26 +302,32 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ 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,(Bit16u)callback); //The immediate word - return 0x0a; + phys_writeb(physAddress+0x00,(Bit8u)0xfb); // sti + phys_writeb(physAddress+0x01,(Bit8u)0x1e); // push ds + phys_writeb(physAddress+0x02,(Bit8u)0x06); // push es + phys_writew(physAddress+0x03,(Bit16u)0x6066); // pushad + phys_writeb(physAddress+0x05,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x06,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x07,(Bit16u)callback); //The immediate word + phys_writeb(physAddress+0x09,(Bit8u)0x50); // push ax + phys_writew(physAddress+0x0a,(Bit16u)0x20b0); // mov al, 0x20 + phys_writew(physAddress+0x0c,(Bit16u)0xa0e6); // out 0xa0, al + phys_writew(physAddress+0x0e,(Bit16u)0x20e6); // out 0x20, al + phys_writeb(physAddress+0x10,(Bit8u)0x58); // pop ax + phys_writeb(physAddress+0x11,(Bit8u)0xfc); // cld + phys_writeb(physAddress+0x12,(Bit8u)0xCB); //A RETF Instruction + return 0x13; 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,(Bit16u)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 + if (use_cb) { + phys_writeb(physAddress+0x07,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x08,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x09,(Bit16u)callback); //The immediate word + physAddress+=4; + } phys_writew(physAddress+0x07,(Bit16u)0x6166); // popad phys_writeb(physAddress+0x09,(Bit8u)0x07); // pop es phys_writeb(physAddress+0x0a,(Bit8u)0x1f); // pop ds diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 7f12f102..07e39f1d 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1190,7 +1190,6 @@ static Bitu DOS_25Handler(void) { SETFLAGBIT(CF,false); reg_ax = 0; } - SETFLAGBIT(IF,true); return CBRET_NONE; } static Bitu DOS_26Handler(void) { @@ -1202,7 +1201,6 @@ static Bitu DOS_26Handler(void) { SETFLAGBIT(CF,false); reg_ax = 0; } - SETFLAGBIT(IF,true); return CBRET_NONE; } @@ -1223,10 +1221,10 @@ public: // iret // retf <- int 21 4c jumps here to mimic a retf Cyber - callback[2].Install(DOS_25Handler,CB_RETF,"DOS Int 25"); + callback[2].Install(DOS_25Handler,CB_RETF_STI,"DOS Int 25"); callback[2].Set_RealVec(0x25); - callback[3].Install(DOS_26Handler,CB_RETF,"DOS Int 26"); + callback[3].Install(DOS_26Handler,CB_RETF_STI,"DOS Int 26"); callback[3].Set_RealVec(0x26); callback[4].Install(DOS_27Handler,CB_IRET,"DOS Int 27"); diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index c61dfdf8..c312fb5e 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -36,8 +36,8 @@ static Bitu call_int33,call_int74,int74_ret_callback,call_mouse_bd; static Bit16u ps2cbseg,ps2cbofs; static bool useps2callback,ps2callbackinit; -static Bitu call_ps2; -static RealPt ps2_callback; +static Bitu call_ps2,call_uir; +static RealPt ps2_callback,uir_callback; static Bit16s oldmouseX, oldmouseY; // forward void WriteMouseIntVector(void); @@ -698,6 +698,15 @@ static void Mouse_Reset(void) { mouse.mickey_x = 0; mouse.mickey_y = 0; + for (Bit16u but=0; but((mouse.max_x + 1)/ 2); mouse.y = static_cast((mouse.max_y + 1)/ 2); @@ -1030,7 +1039,7 @@ static Bitu MOUSE_BD_Handler(void) { } static Bitu INT74_Handler(void) { - if (mouse.events>0) { + if (mouse.events>0 && !mouse.in_UIR) { mouse.events--; /* Check for an active Interrupt Handler that will get called */ if (mouse.sub_mask & mouse.event_queue[mouse.events].type) { @@ -1041,10 +1050,11 @@ static Bitu INT74_Handler(void) { reg_si=static_cast(mouse.mickey_x); reg_di=static_cast(mouse.mickey_y); CPU_Push16(RealSeg(CALLBACK_RealPointer(int74_ret_callback))); - CPU_Push16(RealOff(CALLBACK_RealPointer(int74_ret_callback))); - SegSet16(cs, mouse.sub_seg); - reg_ip = mouse.sub_ofs; - if(mouse.in_UIR) LOG(LOG_MOUSE,LOG_ERROR)("Already in UIR!"); + CPU_Push16(RealOff(CALLBACK_RealPointer(int74_ret_callback))+7); + CPU_Push16(RealSeg(uir_callback)); + CPU_Push16(RealOff(uir_callback)); + CPU_Push16(mouse.sub_seg); + CPU_Push16(mouse.sub_ofs); mouse.in_UIR = true; //LOG(LOG_MOUSE,LOG_ERROR)("INT 74 %X",mouse.event_queue[mouse.events].type ); } else if (useps2callback) { @@ -1064,8 +1074,7 @@ static Bitu INT74_Handler(void) { return CBRET_NONE; } -Bitu MOUSE_UserInt_CB_Handler(void) { - mouse.in_UIR = false; +Bitu INT74_Ret_Handler(void) { if (mouse.events) { if (!mouse.timer_in_progress) { mouse.timer_in_progress = true; @@ -1075,6 +1084,11 @@ Bitu MOUSE_UserInt_CB_Handler(void) { return CBRET_NONE; } +Bitu UIR_Handler(void) { + mouse.in_UIR = false; + return CBRET_NONE; +} + void MOUSE_Init(Section* /*sec*/) { // Callback for mouse interrupt 0x33 call_int33=CALLBACK_Allocate(); @@ -1100,22 +1114,29 @@ void MOUSE_Init(Section* /*sec*/) { call_int74=CALLBACK_Allocate(); CALLBACK_Setup(call_int74,&INT74_Handler,CB_IRQ12,"int 74"); // pseudocode for CB_IRQ12: + // sti // push ds // push es // pushad - // sti // callback INT74_Handler - // doesn't return here, but rather to CB_IRQ12_RET - // (ps2 callback/user callback inbetween if requested) + // ps2 or user callback if requested + // otherwise jumps to CB_IRQ12_RET + // push ax + // mov al, 0x20 + // out 0xa0, al + // out 0x20, al + // pop ax + // cld + // retf int74_ret_callback=CALLBACK_Allocate(); - CALLBACK_Setup(int74_ret_callback,&MOUSE_UserInt_CB_Handler,CB_IRQ12_RET,"int 74 ret"); + CALLBACK_Setup(int74_ret_callback,&INT74_Ret_Handler,CB_IRQ12_RET,"int 74 ret"); // pseudocode for CB_IRQ12_RET: - // callback MOUSE_UserInt_CB_Handler // cli // mov al, 0x20 // out 0xa0, al // out 0x20, al + // callback INT74_Ret_Handler // popad // pop es // pop ds @@ -1130,6 +1151,11 @@ void MOUSE_Init(Section* /*sec*/) { CALLBACK_Setup(call_ps2,&PS2_Handler,CB_RETF,"ps2 bios callback"); ps2_callback=CALLBACK_RealPointer(call_ps2); + // Callback for mouse user routine return + call_uir=CALLBACK_Allocate(); + CALLBACK_Setup(call_uir,&UIR_Handler,CB_RETF_CLI,"mouse uir ret"); + uir_callback=CALLBACK_RealPointer(call_uir); + memset(&mouse,0,sizeof(mouse)); mouse.hidden = 1; //Hide mouse on startup mouse.timer_in_progress = false; From 4d35f0ef27d290a7f1d0582f4f10e67c393eabb6 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Mon, 4 Feb 2019 15:16:55 +0000 Subject: [PATCH 4079/4131] Correct relative track length in subchannel data for CD-ROM images; fixes speech audio cutting off too soon in Casino Tournament of Champions. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4189 --- src/dos/cdrom_image.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index b1fc1c59..25a7783a 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -205,7 +205,7 @@ bool CDROM_Interface_Image::GetAudioSub(unsigned char& attr, unsigned char& trac attr = tracks[track - 1].attr; index = 1; FRAMES_TO_MSF(player.currFrame + 150, &absPos.min, &absPos.sec, &absPos.fr); - FRAMES_TO_MSF(player.currFrame - tracks[track - 1].start + 150, &relPos.min, &relPos.sec, &relPos.fr); + FRAMES_TO_MSF(player.currFrame - tracks[track - 1].start, &relPos.min, &relPos.sec, &relPos.fr); return true; } From 88bc1944e8da9f494d3bb625f9e27ee582ac66b1 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Mon, 4 Feb 2019 15:18:49 +0000 Subject: [PATCH 4080/4131] Reset followed by switch to UART mode should take some time; fixes MPU detection in F29 Retaliator and Hover Force. Also minimize reset delay, which helps with MPU detection at higher cycles in games that prefer less delay, such as Bureau 13. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4190 --- src/hardware/mpu401.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index c79338a1..c5a2a77f 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -38,7 +38,7 @@ static void MPU401_EOIHandlerDispatch(void); #define MPU401_REVISION 0x01 #define MPU401_QUEUE 32 #define MPU401_TIMECONSTANT (60000000/1000.0f) -#define MPU401_RESETBUSY 27.0f +#define MPU401_RESETBUSY 14.0f enum MpuMode { M_UART,M_INTELLIGENT }; enum MpuDataType {T_OVERFLOW,T_MARK,T_MIDI_SYS,T_MIDI_NORM,T_COMMAND}; @@ -124,7 +124,7 @@ static Bitu MPU401_ReadStatus(Bitu port,Bitu iolen) { static void MPU401_WriteCommand(Bitu port,Bitu val,Bitu iolen) { if (mpu.mode==M_UART && val!=0xff) return; if (mpu.state.reset) { - if (mpu.state.cmd_pending || (val!=0x3f && val!=0xff)) { + if (mpu.state.cmd_pending || val!=0xff) { mpu.state.cmd_pending=val+1; return; } From 45f28b12bd71042d3fb6f9efae75f84d5b682b6a Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Mon, 4 Feb 2019 15:27:26 +0000 Subject: [PATCH 4081/4131] Only standard 3-byte mouse data packets are supported, so return an error for other packet sizes. MS Mouse driver versions 9.X and later use 1-byte packets for some obscure reason, and now they won't load instead of messing up. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4191 --- src/ints/bios.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index ef906283..dfeb0a15 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -905,6 +905,12 @@ static Bitu INT15_Handler(void) { reg_bx=0x00aa; // mouse // fall through case 0x05: // initialize + if ((reg_al==0x05) && (reg_bh!=0x03)) { + // non-standard data packet sizes not supported + CALLBACK_SCF(true); + reg_ah=2; + break; + } Mouse_SetPS2State(false); CALLBACK_SCF(false); reg_ah=0; From 7f7e5f34acc7f4f2cd79798f8a7f9313c04ad2d5 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Thu, 21 Feb 2019 14:53:31 +0000 Subject: [PATCH 4082/4131] Ignore unrequested data in intelligent mode; fixes Roland sound in Krusty's Fun House. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4192 --- src/hardware/mpu401.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index c5a2a77f..4afa5691 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -605,7 +605,7 @@ static void MPU401_Reset(void) { mpu.state.cmask=0xff; mpu.state.amask=mpu.state.tmask=0; mpu.state.midi_mask=0xffff; - mpu.state.data_onoff=0; + mpu.state.data_onoff=-1; mpu.state.command_byte=0; mpu.state.block_ack=false; mpu.clock.tempo=mpu.clock.old_tempo=100; From a3635e22af63ac4c0f87c7be5ed0a332b3886936 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 28 Feb 2019 13:03:22 +0000 Subject: [PATCH 4083/4131] Repair double slash in configfile location on Macs. Add some protection against a NULL dirp. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4193 --- src/misc/cross.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/misc/cross.cpp b/src/misc/cross.cpp index 80b2324b..8fbefbfc 100644 --- a/src/misc/cross.cpp +++ b/src/misc/cross.cpp @@ -85,7 +85,7 @@ void Cross::CreatePlatformConfigDir(std::string& in) { in += "\\DOSBox"; mkdir(in.c_str()); #elif defined(MACOSX) - in = "~/Library/Preferences/"; + in = "~/Library/Preferences"; ResolveHomedir(in); //Don't create it. Assume it exists #else @@ -155,6 +155,7 @@ dir_information* open_directory(const char* dirname) { } bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory) { + if (!dirp) return false; dirp->handle = FindFirstFile(dirp->base_path, &dirp->search_data); if (INVALID_HANDLE_VALUE == dirp->handle) { return false; @@ -169,6 +170,7 @@ bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_dire } bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) { + if (!dirp) return false; int result = FindNextFile(dirp->handle, &dirp->search_data); if (result==0) return false; @@ -181,7 +183,7 @@ bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_direc } void close_directory(dir_information* dirp) { - if (dirp->handle != INVALID_HANDLE_VALUE) { + if (dirp && dirp->handle != INVALID_HANDLE_VALUE) { FindClose(dirp->handle); dirp->handle = INVALID_HANDLE_VALUE; } @@ -197,10 +199,12 @@ dir_information* open_directory(const char* dirname) { } bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory) { + if (!dirp) return false; return read_directory_next(dirp,entry_name,is_directory); } bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) { + if (!dirp) return false; struct dirent* dentry = readdir(dirp->dir); if (dentry==NULL) { return false; @@ -236,7 +240,7 @@ bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_direc } void close_directory(dir_information* dirp) { - closedir(dirp->dir); + if (dirp) closedir(dirp->dir); } #endif From 8d1c5b31e1cdaf922799a512fce892e6cb748ed8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 28 Feb 2019 13:14:21 +0000 Subject: [PATCH 4084/4131] fix loading of configfiles specified with -conf but present in the userdir with -userconf present. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4194 --- src/gui/sdlmain.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 282e100e..4fd943f7 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -2091,7 +2091,7 @@ int main(int argc, char* argv[]) { sdl.num_joysticks=SDL_NumJoysticks(); /* Parse configuration files */ - std::string config_file,config_path; + std::string config_file, config_path, config_combined; Cross::GetPlatformConfigDir(config_path); //First parse -userconf @@ -2099,18 +2099,18 @@ int main(int argc, char* argv[]) { config_file.clear(); Cross::GetPlatformConfigDir(config_path); Cross::GetPlatformConfigName(config_file); - config_path += config_file; - control->ParseConfigFile(config_path.c_str()); + config_combined = config_path + config_file; + control->ParseConfigFile(config_combined.c_str()); if(!control->configfiles.size()) { //Try to create the userlevel configfile. config_file.clear(); Cross::CreatePlatformConfigDir(config_path); Cross::GetPlatformConfigName(config_file); - config_path += config_file; - if(control->PrintConfig(config_path.c_str())) { - LOG_MSG("CONFIG: Generating default configuration.\nWriting it to %s",config_path.c_str()); + config_combined = config_path + config_file; + if(control->PrintConfig(config_combined.c_str())) { + LOG_MSG("CONFIG: Generating default configuration.\nWriting it to %s",config_combined.c_str()); //Load them as well. Makes relative paths much easier - control->ParseConfigFile(config_path.c_str()); + control->ParseConfigFile(config_combined.c_str()); } } } @@ -2139,11 +2139,11 @@ int main(int argc, char* argv[]) { config_file.clear(); Cross::CreatePlatformConfigDir(config_path); Cross::GetPlatformConfigName(config_file); - config_path += config_file; - if(control->PrintConfig(config_path.c_str())) { - LOG_MSG("CONFIG: Generating default configuration.\nWriting it to %s",config_path.c_str()); + config_combined = config_path + config_file; + if(control->PrintConfig(config_combined.c_str())) { + LOG_MSG("CONFIG: Generating default configuration.\nWriting it to %s",config_combined.c_str()); //Load them as well. Makes relative paths much easier - control->ParseConfigFile(config_path.c_str()); + control->ParseConfigFile(config_combined.c_str()); } else { LOG_MSG("CONFIG: Using default settings. Create a configfile to change them"); } From d137ec5c0d1e8652b30aa1d37ef9137a3adf2411 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 21 Mar 2019 15:56:15 +0000 Subject: [PATCH 4085/4131] Fix up DOS_Drive_Cache::GetShortName, used by overlay drive. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4195 --- src/dos/drive_cache.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index a07bc119..d3c50ce5 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -266,6 +266,7 @@ void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) { // LOG_DEBUG("DIR: Caching out %s : dir %s",expand,dir->orgname); // delete file objects... + //Maybe check if it is a file and then only delete the file and possibly the long name. instead of all objects in the dir. for(Bit32u i=0; ifileList.size(); i++) { if (dirSearch[srchNr]==dir->fileList[i]) dirSearch[srchNr] = 0; DeleteFileInfo(dir->fileList[i]); dir->fileList[i] = 0; @@ -286,22 +287,22 @@ bool DOS_Drive_Cache::GetShortName(const char* fullname, char* shortname) { char expand[CROSS_LEN] = {0}; CFileInfo* curDir = FindDirInfo(fullname,expand); + const char* pos = strrchr(fullname,CROSS_FILESPLIT); + if (pos) pos++; else return false; + std::vector::size_type filelist_size = curDir->longNameList.size(); if (GCC_UNLIKELY(filelist_size<=0)) return false; - Bits low = 0; - Bits high = (Bits)(filelist_size-1); - Bits mid, res; - - while (low<=high) { - mid = (low+high)/2; - res = strcmp(fullname,curDir->longNameList[mid]->orgname); - if (res>0) low = mid+1; else - if (res<0) high = mid-1; - else { - strcpy(shortname,curDir->longNameList[mid]->shortname); + // The orgname part of the list is not sorted (shortname is)! So we can only walk through it. + for(Bitu i = 0; i < filelist_size; i++) { +#if defined (WIN32) || defined (OS2) /* Win 32 & OS/2*/ + if (strcasecmp(pos,curDir->longNameList[i]->orgname) == 0) { +#else + if (strcmp(pos,curDir->longNameList[i]->orgname) == 0) { +#endif + strcpy(shortname,curDir->longNameList[i]->shortname); return true; - }; + } } return false; } From 202bfa1155885fff4a5134423ca8b6b0b30769f5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 25 Mar 2019 13:49:25 +0000 Subject: [PATCH 4086/4131] New Drive type: overlay. When active, this drive redirects new and changed files to a different location. The files in the overlay and normal drive are merged on startup and kept up to date when the game changes something. Files in the overlay are priotizedi, if they exists, above the normal files. The drive will switch to an overlayed version of the file on the first write! (Not when opening the file in write-mode). The overlay is capable of creating missing directories. With the help of DBOVERLAY files, the drive keeps track of files that are present in the normal directory but deleted by the game. All changes are preserved between sessions. Current design principles/limitations/requirements: 1) All directories that can be used for saving, must exist already in the base before mounting. (they will be created by DOSBox if missing in the overlay) 2) All filenames inside the overlay directories are UPPERCASE and conform to the 8.3 standard except for the special DBOVERLAY files. 3) To keep point 1 valid at all times, support for creating/renaming/removing directories has been disabled. Thanks for the help GOG. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4196 --- include/dos_system.h | 2 +- src/dos/Makefile.am | 2 +- src/dos/dos_programs.cpp | 43 +- src/dos/drive_overlay.cpp | 1039 +++++++++++++++++++++++++++++++++++++ src/dos/drives.h | 54 +- visualc_net/dosbox.vcproj | 3 + 6 files changed, 1134 insertions(+), 9 deletions(-) create mode 100644 src/dos/drive_overlay.cpp diff --git a/include/dos_system.h b/include/dos_system.h index 8ab25d16..631c5cbf 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -128,8 +128,8 @@ public: bool UpdateDateTimeFromHost(void); void FlagReadOnlyMedium(void); void Flush(void); + FILE * fhandle; //todo handle this properly private: - FILE * fhandle; bool read_only_medium; enum { NONE,READ,WRITE } last_action; }; diff --git a/src/dos/Makefile.am b/src/dos/Makefile.am index 3bdfbf51..36a2d99b 100644 --- a/src/dos/Makefile.am +++ b/src/dos/Makefile.am @@ -7,4 +7,4 @@ libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioc drives.cpp drives.h drive_virtual.cpp drive_local.cpp drive_cache.cpp drive_fat.cpp \ drive_iso.cpp dev_con.h dos_mscdex.cpp dos_keyboard_layout.cpp \ cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp cdrom_ioctl_linux.cpp cdrom_image.cpp \ - cdrom_ioctl_os2.cpp + cdrom_ioctl_os2.cpp drive_overlay.cpp diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 4ca3ada2..38cda889 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -195,14 +195,14 @@ public: std::string type="dir"; cmd->FindString("-t",type,true); bool iscdrom = (type =="cdrom"); //Used for mscdex bug cdrom label name emulation - if (type=="floppy" || type=="dir" || type=="cdrom") { + if (type=="floppy" || type=="dir" || type=="cdrom" || type =="overlay") { Bit16u sizes[4]; Bit8u mediaid; std::string str_size; if (type=="floppy") { str_size="512,1,2880,2880";/* All space free */ mediaid=0xF0; /* Floppy 1.44 media */ - } else if (type=="dir") { + } else if (type=="dir" || type == "overlay") { // 512*32*32765==~500MB total size // 512*32*16000==~250MB total free size str_size="512,32,32765,16000"; @@ -381,7 +381,39 @@ public: #else if(temp_line == "/") WriteOut(MSG_Get("PROGRAM_MOUNT_WARNING_OTHER")); #endif - newdrive=new localDrive(temp_line.c_str(),sizes[0],bit8size,sizes[2],sizes[3],mediaid); + if(type == "overlay") { + //Ensure that the base drive exists: + if (!Drives[drive-'A']) { + WriteOut("No basedrive mounted yet!"); + return; + } + localDrive* ldp = dynamic_cast(Drives[drive-'A']); + cdromDrive* cdp = dynamic_cast(Drives[drive-'A']); + if (!ldp || cdp) { + WriteOut("Basedrive not compatible"); + return; + } + std::string base = ldp->getBasedir(); + Bit8u o_error = 0; + newdrive = new Overlay_Drive(base.c_str(),temp_line.c_str(),sizes[0],bit8size,sizes[2],sizes[3],mediaid,o_error); + //Erase old drive on succes + if (newdrive) { + if (o_error) { + if (o_error == 1) WriteOut("No mixing of relative and absolute paths. Overlay failed."); + else if (o_error == 2) WriteOut("overlay directory can not be the same as underlying filesystem."); + else WriteOut("Something went wrong"); + delete newdrive; + return; + } + delete Drives[drive-'A']; + Drives[drive-'A'] = 0; + } else { + WriteOut("overlaydrive construction failed."); + return; + } + } else { + newdrive=new localDrive(temp_line.c_str(),sizes[0],bit8size,sizes[2],sizes[3],mediaid); + } } } else { WriteOut(MSG_Get("PROGRAM_MOUNT_ILL_TYPE"),type.c_str()); @@ -396,13 +428,14 @@ public: Drives[drive-'A']=newdrive; /* Set the correct media byte in the table */ mem_writeb(Real2Phys(dos.tables.mediaid)+(drive-'A')*9,newdrive->GetMediaByte()); - WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,newdrive->GetInfo()); + if (type != "overlay") WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,newdrive->GetInfo()); + else WriteOut("Overlay %s on drive %c mounted.\n",temp_line.c_str(),drive); /* check if volume label is given and don't allow it to updated in the future */ if (cmd->FindString("-label",label,true)) newdrive->dirCache.SetLabel(label.c_str(),iscdrom,false); /* For hard drives set the label to DRIVELETTER_Drive. * For floppy drives set the label to DRIVELETTER_Floppy. * This way every drive except cdroms should get a label.*/ - else if(type == "dir") { + else if(type == "dir" || type == "overlay") { label = drive; label += "_DRIVE"; newdrive->dirCache.SetLabel(label.c_str(),iscdrom,false); } else if(type == "floppy") { diff --git a/src/dos/drive_overlay.cpp b/src/dos/drive_overlay.cpp new file mode 100644 index 00000000..46f9ee93 --- /dev/null +++ b/src/dos/drive_overlay.cpp @@ -0,0 +1,1039 @@ +/* + * Copyright (C) 2002-2019 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" +#include "dos_inc.h" +#include "drives.h" +#include "support.h" +#include "cross.h" +#include "inout.h" +#include "timer.h" + +#include +#include + +#include +#include +#include +#include +#include + +bool logoverlay = false; +using namespace std; + +#if defined (WIN32) || defined (OS2) /* Win 32 & OS/2*/ +#define CROSS_DOSFILENAME(blah) +#else +//Convert back to DOS PATH +#define CROSS_DOSFILENAME(blah) strreplace(blah,'/','\\') +#endif + + +/* + * design principles/limitations/requirements: + * 1) All directories that can be used for saving, must exist already in the base before mounting. (they will be created by DOSBox if missing in the overlay) + * 2) All filenames inside the overlay directories are UPPERCASE and conform to the 8.3 standard except for the special DBOVERLAY files. + * 3) To keep point 1 valid at all times, support for creating/renaming/removing directories has been disabled. + * + * Points 1 and 3 are still being worked on, so these limitations can be removed. + */ + + +//TODO recheck directories under linux with the filename_cache (as one adds the dos name (and runs cross_filename on the other)) + + +//TODO Check: Maybe handle file redirection in ccc (opening the new file), (call update datetime host there ?) + + +/* For rename/delete(unlink)/makedir/removedir we need to rebuild the cache. (shouldn't be needed, + * but cacheout/delete entry currently throw away the cached folder and rebuild it on read. + * so we have to ensure the rebuilding is controlled through the overlay. + * In order to not reread the overlay directory contents, the information in there is cached and updated when + * it changes (when deleting a file or adding one) + */ + + +//directories that exist only in overlay can not be added to the drive_cache currently. +//Either upgrade addentry to support directories. (without actually caching stuff in! (code in testing)) +//Or create an empty directory in local drive base. + +bool Overlay_Drive::RemoveDir(char * dir) { + //DOS_RemoveDir checks if directory exists. + E_Exit("Overlay: trying to remove directory: %s",dir); + /* Overlay: Check if folder is empty (findfirst/next ?), if so, then it is not too tricky. */ + char newdir[CROSS_LEN]; + strcpy(newdir,basedir); + strcat(newdir,dir); + CROSS_FILENAME(newdir); + int temp=rmdir(dirCache.GetExpandName(newdir)); + if (temp==0) dirCache.DeleteEntry(newdir,true); + return (temp==0); +} + +bool Overlay_Drive::MakeDir(char * dir) { + //DOS_MakeDir tries first, before checking if the directory already exists, so doing it here as well, so that case is handled. + if (TestDir(dir)) return false; + E_Exit("Overlay trying to make directory: %s",dir); + /* Overlay: Create in Overlay only and add it to drive_cache + some entries else the drive_cache will try to access it. Needs an AddEntry for directories. */ + + char newdir[CROSS_LEN]; + strcpy(newdir,basedir); + strcat(newdir,dir); + CROSS_FILENAME(newdir); +#if defined (WIN32) /* MS Visual C++ */ + int temp=mkdir(dirCache.GetExpandName(newdir)); +#else + int temp=mkdir(dirCache.GetExpandName(newdir),0700); +#endif + if (temp==0) dirCache.CacheOut(newdir,true); + + return (temp==0);// || ((temp!=0) && (errno==EEXIST)); +} + +bool Overlay_Drive::TestDir(char * dir) { + //Check if the directory is marked as deleted or one of its leading directories is. + + //Directories are stored without a trailing backslash + char tempdir[CROSS_LEN]; + strcpy(tempdir,dir); + size_t templen = strlen(dir); + if (templen && tempdir[templen-1] == '\\') tempdir[templen-1] = 0; + if (is_deleted_path(tempdir)) return false; + + // Rely on the localDrive directories. + // Directory is good according to the overlay, pass on to LocalDrive + return localDrive::TestDir(dir); +} + + +class OverlayFile: public localFile { +public: + OverlayFile(const char* name, FILE * handle):localFile(name,handle){ + if (logoverlay) LOG_MSG("constructing OverlayFile: %s",name); + } + bool Write(Bit8u * data,Bit16u * size) { + Bit32u f = real_flags&0xf; + if (!overlay_active && (f == OPEN_READWRITE || f == OPEN_WRITE)) { + if (logoverlay) LOG_MSG("write detected, switching file for %s",GetName()); + if (*data == 0) { + if (logoverlay) LOG_MSG("OPTIMISE: truncate on switch!!!!"); + } + Bitu a = GetTicks(); + bool r = create_copy(); + if (GetTicks()-a >2) { + if (logoverlay) LOG_MSG("OPTIMISE: switching took %d",GetTicks()-a); + } + if (!r) return false; + overlay_active = true; + flags = real_flags; + + } + return localFile::Write(data,size); + } + bool create_copy(); +//private: + Bit32u real_flags; + bool overlay_active; +}; + +//Create leading directories of a file being overlayed if they exist in the original (localDrive). +//This function is used to create copies of existing files, so all leading directories exist in the original. + +FILE* Overlay_Drive::create_file_in_overlay(char* dos_filename, char const* mode) { + + if (logoverlay) LOG_MSG("create_file_in_overlay called %s %s",dos_filename,mode); + char newname[CROSS_LEN]; + strcpy(newname,overlaydir); //TODO GOG make part of class and join in + strcat(newname,dos_filename); //HERE we need to convert it to Linux TODO + CROSS_FILENAME(newname); + + FILE* f = fopen(newname,mode); + //Check if a directories are part of the name: + char* dir = strrchr(dos_filename,'\\'); + if (!f && dir && *dir) { + if (logoverlay) LOG_MSG("Overlay: warning creating a file inside a directory %s",dos_filename); + //ensure they exist, else make them in the overlay if they exist in the original.... + Sync_leading_dirs(dos_filename); + //try again + f = fopen(newname,mode); + } + + return f; +} + +#ifndef BUFSIZ +#define BUFSIZ 2048 +#endif + +//bool OverlayFile::create_copy(DOS_File * file, char* newname) +bool OverlayFile::create_copy() { + //test if open/valid/etc + //ensure file position + if (logoverlay) LOG_MSG("create_copy called %s",GetName()); + + FILE* lhandle = this->fhandle; + fseek(lhandle,ftell(lhandle),SEEK_SET); + int location_in_old_file = ftell(lhandle); + fseek(lhandle,0L,SEEK_SET); + + FILE* newhandle = NULL; + Bit8u drive_set = GetDrive(); + if (drive_set != 0xff && drive_set < DOS_DRIVES && Drives[drive_set]){ + Overlay_Drive* od = dynamic_cast(Drives[drive_set]); + if (od) { + newhandle = od->create_file_in_overlay(GetName(),"wb+"); //todo check wb+ + } + } +// newhandle = create_file(newname,"wb+"); + if (!newhandle) return false; + char buffer[BUFSIZ]; + size_t s; + while ( (s = fread(buffer,1,BUFSIZ,lhandle)) ) fwrite(buffer, 1, s, newhandle); + fclose(lhandle); + //Set copied file handle to position of the old one + fseek(newhandle,location_in_old_file,SEEK_SET); + this->fhandle = newhandle; + //Flags ? + if (logoverlay) LOG_MSG("success"); + return true; +} + + + +static OverlayFile* ccc(DOS_File* file) { + localFile* l = dynamic_cast(file); + if (!l) E_Exit("overlay input file is not a localFile"); + //Create an overlayFile + OverlayFile* ret = new OverlayFile(l->GetName(),l->fhandle); + ret->flags = l->flags; + delete l; + return ret; +} + +Overlay_Drive::Overlay_Drive(const char * startdir,const char* overlay, Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid,Bit8u &error) +:localDrive(startdir,_bytes_sector,_sectors_cluster,_total_clusters,_free_clusters,_mediaid),special_prefix("DBOVERLAY") { + optimize_cache_v1 = true; //Try to not reread overlay files on deletes. Ideally drive_cache should be improved to handle deletes properly. + //Currently this flag does nothing, as the current behavior is to not reread due to caching everything. +#if defined (WIN32) + if (strcasecmp(startdir,overlay) == 0) { +#else + if (strcmp(startdir,overlay) == 0) { +#endif + //overlay directory can not be the base directory + error = 2; + return; + } + + std::string s(startdir); + std::string o(overlay); + bool s_absolute = Cross::IsPathAbsolute(s); + bool o_absolute = Cross::IsPathAbsolute(o); + error = 0; + if (s_absolute != o_absolute) { + error = 1; + return; + } + strcpy(overlaydir,overlay); + char dirname[CROSS_LEN] = { 0 }; + //Determine if overlaydir is part of the startdir. + convert_overlay_to_DOSname_in_base(dirname); + + + if(strlen(dirname) && dirname[strlen(dirname)-1] == '\\') dirname[strlen(dirname)-1] = 0; + + //add_deleted_path(dirname); //update_cache will add the overlap_folder + overlap_folder = dirname; + + update_cache(true); +} + +void Overlay_Drive::convert_overlay_to_DOSname_in_base(char* dirname ) +{ + dirname[0] = 0;//ensure good return string + if (strlen(overlaydir) >= strlen(basedir) ) { + //Needs to be longer at least. +#if defined (WIN32) +//OS2 ? + if (strncasecmp(overlaydir,basedir,strlen(basedir)) == 0) { +#else + if (strncmp(overlaydir,basedir,strlen(basedir)) == 0) { +#endif + //Beginning is the same. + char t[CROSS_LEN]; + strcpy(t,overlaydir+strlen(basedir)); + + char* p = t; + char* b = t; + + while ( (p =strchr(p,CROSS_FILESPLIT)) ) { + char directoryname[CROSS_LEN]={0}; + char dosboxdirname[CROSS_LEN]={0}; + strcpy(directoryname,dirname); + strncat(directoryname,b,p-b); + + char d[CROSS_LEN]; + strcpy(d,basedir); + strcat(d,directoryname); + CROSS_FILENAME(d); + //Try to find the corresponding directoryname in DOSBox. + if(!dirCache.GetShortName(d,dosboxdirname) ) { + //Not a long name, assume it is a short name instead + strncpy(dosboxdirname,b,p-b); + upcase(dosboxdirname); + } + + + strcat(dirname,dosboxdirname); + strcat(dirname,"\\"); + + if (logoverlay) LOG_MSG("HIDE directory: %s",dirname); + + + b=++p; + + } + } + } +} + +bool Overlay_Drive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { + const char* type; + switch (flags&0xf) { + case OPEN_READ: type = "rb" ; break; + case OPEN_WRITE: type = "rb+"; break; + case OPEN_READWRITE: type = "rb+"; break; +// case OPEN_READ_NO_MOD: type = "rb" ; break; //No modification of dates. LORD4.07 uses this + default: + DOS_SetError(DOSERR_ACCESS_CODE_INVALID); + return false; + } + +#if 0 + //Flush the buffer of handles for the same file. (Betrayal in Antara) + Bit8u i,drive=DOS_DRIVES; + localFile *lfp; + for (i=0;iIsOpen() && Files[i]->GetDrive()==drive && Files[i]->IsName(name)) { + lfp=dynamic_cast(Files[i]); + if (lfp) lfp->Flush(); + } + } +#endif + + + //Todo check name first against local tree + //if name exists, use that one instead! + //overlay file. + char newname[CROSS_LEN]; + strcpy(newname,overlaydir); + strcat(newname,name); + CROSS_FILENAME(newname); + + FILE * hand = fopen(newname,type); + bool fileopened = false; + if (hand) { + if (logoverlay) LOG_MSG("overlay file opened %s",newname); + *file=new localFile(name,hand); + (*file)->flags=flags; + fileopened = true; + } else { + ; //TODO error handling!!!! (maybe check if it exists and read only (should not happen with overlays) + } + bool overlayed = fileopened; + + //File not present in overlay, try normal drive + //TODO take care of file being marked deleted. + + if (!fileopened && !is_deleted_file(name)) fileopened = localDrive::FileOpen(file,name, OPEN_READ); + + + if (fileopened) { + if (logoverlay) LOG_MSG("file opened %s",name); + //Convert file to OverlayFile + OverlayFile* f = ccc(*file); + //Store original flags, as with overlay the files are opened read only and they switch on write + f->real_flags = flags; + f->overlay_active = overlayed; //No need to switch if already in overlayed. + *file = f; + } + return fileopened; +} + + +bool Overlay_Drive::FileCreate(DOS_File * * file,char * name,Bit16u /*attributes*/) { + + //TODO Check if it exists in the dirCache ? // fix addentry ? or just double check (ld and overlay) + //AddEntry looks sound to me.. + + FILE* f = create_file_in_overlay(name,"wb+"); + if(!f) { + if (logoverlay) LOG_MSG("File creation in overlay system failed %s",name); + return false; + } + *file = new localFile(name,f); + (*file)->flags = OPEN_READWRITE; + OverlayFile* of = ccc(*file); + of->overlay_active = true; + of->real_flags = OPEN_READWRITE; + *file = of; + //create fake name for the drive cache + char fakename[CROSS_LEN]; + strcpy(fakename,basedir); + strcat(fakename,name); + CROSS_FILENAME(fakename); + dirCache.AddEntry(fakename,true); //add it. + add_DOSname_to_cache(name); + remove_deleted_file(name,true); + return true; +} +void Overlay_Drive::add_DOSname_to_cache(const char* name) { + for (std::vector::const_iterator itc = DOSnames_cache.begin(); itc != DOSnames_cache.end();itc++){ + if (name == (*itc)) return; + } + DOSnames_cache.push_back(name); +} +void Overlay_Drive::remove_DOSname_from_cache(const char* name) { + for (std::vector::iterator it = DOSnames_cache.begin(); it != DOSnames_cache.end();it++) { + if (name == (*it)) { DOSnames_cache.erase(it); return;} + } + +} + +bool Overlay_Drive::Sync_leading_dirs(const char* dos_filename){ + const char* lastdir = strrchr(dos_filename,'\\'); + //If there are no directories, return success. + if (!lastdir) return true; + + const char* leaddir = dos_filename; + while ( (leaddir=strchr(leaddir,'\\')) != 0) { + char dirname[CROSS_LEN] = {0}; + strncpy(dirname,dos_filename,leaddir-dos_filename); + + if (logoverlay) LOG_MSG("syncdir: %s",dirname); + //Test if directory exist in base. + char dirnamebase[CROSS_LEN] ={0}; + strcpy(dirnamebase,basedir); + strcat(dirnamebase,dirname); + CROSS_FILENAME(dirnamebase); + struct stat basetest; + if (stat(dirCache.GetExpandName(dirnamebase),&basetest) == 0 && basetest.st_mode & S_IFDIR) { + if (logoverlay) LOG_MSG("base exists: %s",dirnamebase); + //Directory exists in base folder. + //Ensure it exists in overlay as well + + struct stat overlaytest; + char dirnameoverlay[CROSS_LEN] ={0}; + strcpy(dirnameoverlay,overlaydir); + strcat(dirnameoverlay,dirname); + CROSS_FILENAME(dirnameoverlay); + if (stat(dirnameoverlay,&overlaytest) == 0 ) { + //item exist. Check if it is a folder, if not a folder =>fail! + if ((overlaytest.st_mode & S_IFDIR) ==0) return false; + } else { + //folder does not exist, make it + if (logoverlay) LOG_MSG("creating %s",dirnameoverlay); +#if defined (WIN32) /* MS Visual C++ */ + int temp = mkdir(dirnameoverlay); +#else + int temp = mkdir(dirnameoverlay,0700); +#endif + if (temp != 0) return false; + } + } + leaddir = leaddir + 1; //Move to next + } + + return true; +} +void Overlay_Drive::update_cache(bool read_directory_contents) { + Bitu a = GetTicks(); + std::vector specials; + std::vector dirnames; + std::vector filenames; + if (read_directory_contents) { + //Clear all lists + DOSnames_cache.clear(); + deleted_files_in_base.clear(); + deleted_paths_in_base.clear(); + //Ensure hiding of the folder that contains the overlay, if it is part of the base folder. + add_deleted_path(overlap_folder.c_str()); + } + + + //What about sequences were a base file gets copied to a working save game and then removed/renamed... + //copy should be safe as then the link with the original doesn't exist. + //however the working safe can be rather complicated after a rename and delete.. + + //Currently directories existing only in the overlay can not be added to drive cache: + //1. possible workaround create empty directory in base. Drawback would break the no-touching-of-base. + //2. double up Addentry to support directories, (and adding . and .. to the newly directory so it counts as cachedin.. and won't be recached, as otherwise + // cache will realize we are faking it. + //Working on solution 2. + + //Random TODO: Does the root drive under DOS have . and .. ? + + //This function needs to be called after any localDrive function calling cacheout/deleteentry, as those throw away directories. + //either do this with a parameter stating the part that needs to be rebuild,(directory) or clear the cache by default and do it all. + + std::vector::iterator i; + std::string::size_type const prefix_lengh = special_prefix.length(); + if (read_directory_contents) { + dir_information* dirp = open_directory(overlaydir); + if (dirp == NULL) return; + // Read complete directory + char dir_name[CROSS_LEN]; + bool is_directory; + if (read_directory_first(dirp, dir_name, is_directory)) { + if ((strlen(dir_name) > prefix_lengh+5) && strncmp(dir_name,special_prefix.c_str(),prefix_lengh) == 0) specials.push_back(dir_name); + else if (is_directory) dirnames.push_back(dir_name); + else filenames.push_back(dir_name); + while (read_directory_next(dirp, dir_name, is_directory)) { + if ((strlen(dir_name) > prefix_lengh+5) && strncmp(dir_name,special_prefix.c_str(),prefix_lengh) == 0) specials.push_back(dir_name); + else if (is_directory) dirnames.push_back(dir_name); + else filenames.push_back(dir_name); + } + } + close_directory(dirp); + //parse directories to add them. + + + + for (i = dirnames.begin(); i != dirnames.end();i++) { + if ((*i) == ".") continue; + if ((*i) == "..") continue; + std::string testi(*i); + std::string::size_type ll = testi.length(); + //TODO: Use the dirname\. and dirname\.. for creating fake directories in the driveCache. + if( ll >2 && testi[ll-1] == '.' && testi[ll-2] == CROSS_FILESPLIT) continue; + if( ll >3 && testi[ll-1] == '.' && testi[ll-2] == '.' && testi[ll-3] == CROSS_FILESPLIT) continue; + + char dir[CROSS_LEN]; + strcpy(dir,overlaydir); + strcat(dir,(*i).c_str()); + char dirpush[CROSS_LEN]; + strcpy(dirpush,(*i).c_str()); + static char end[2] = {CROSS_FILESPLIT,0}; + strcat(dirpush,end); //Linux ? + dir_information* dirp = open_directory(dir); + if (dirp == NULL) continue; + std::string backupi(*i); + // Read complete directory + char dir_name[CROSS_LEN]; + bool is_directory; + if (read_directory_first(dirp, dir_name, is_directory)) { + if ((strlen(dir_name) > prefix_lengh+5) && strncmp(dir_name,special_prefix.c_str(),prefix_lengh) == 0) specials.push_back(string(dirpush)+dir_name); + else if (is_directory) dirnames.push_back(string(dirpush)+dir_name); + else filenames.push_back(string(dirpush)+dir_name); + while (read_directory_next(dirp, dir_name, is_directory)) { + if ((strlen(dir_name) > prefix_lengh+5) && strncmp(dir_name,special_prefix.c_str(),prefix_lengh) == 0) specials.push_back(string(dirpush)+dir_name); + else if (is_directory) dirnames.push_back(string(dirpush)+dir_name); + else filenames.push_back(string(dirpush)+dir_name); + } + } + close_directory(dirp); + for(i = dirnames.begin(); i != dirnames.end();i++) { + if ( (*i) == backupi) break; //find current directory again, for the next round. + } + } + } + + + if (read_directory_contents) { + for( i = filenames.begin(); i != filenames.end(); i++) { + char dosname[CROSS_LEN]; + strcpy(dosname,(*i).c_str()); + upcase(dosname); //Should not be really needed, as uppercase in the overlay is a requirement... + CROSS_DOSFILENAME(dosname); + if (logoverlay) LOG_MSG("update cache add dosname %s",dosname); + DOSnames_cache.push_back(dosname); + } + } + + for (i = DOSnames_cache.begin(); i != DOSnames_cache.end(); i++) { + char fakename[CROSS_LEN]; + strcpy(fakename,basedir); + strcat(fakename,(*i).c_str()); + CROSS_FILENAME(fakename); + dirCache.AddEntry(fakename,true); + } + + if (read_directory_contents) { + for (i = specials.begin(); i != specials.end();i++) { + //Specials look like this DBOVERLAY_YYY_FILENAME.EXT or DIRNAME[\/]DBOVERLAY_YYY_FILENAME.EXT where + //YYY is the operation involved. Currently only DEL is supported. + //DEL = file marked as deleted, (but exists in localDrive!) + std::string name(*i); + std::string special_dir(""); + std::string special_file(""); + std::string special_operation(""); + std::string::size_type s = name.find(special_prefix); + if (s == std::string::npos) continue; + if (s) { + special_dir = name.substr(0,s); + name.erase(0,s); + } + name.erase(0,special_prefix.length()+1); //Erase DBOVERLAY_ + s = name.find("_"); + if (s == std::string::npos ||s == 0) continue; + special_operation = name.substr(0,s); + name.erase(0,s + 1); + special_file = name; + if (special_file.length() == 0) continue; + if (special_operation == "DEL") { + name = special_dir + special_file; + //CROSS_DOSFILENAME for strings: + while ( (s = name.find('/')) != std::string::npos) name.replace(s,1,"\\"); + + add_deleted_file(name.c_str(),false); + } else { + if (logoverlay) LOG_MSG("unsupported operation %s on %s",special_operation.c_str(),(*i).c_str()); + } + + } + } + if (logoverlay) LOG_MSG("OPTIMISE: update cache took %d",GetTicks()-a); +} + +bool Overlay_Drive::FindNext(DOS_DTA & dta) { + + char * dir_ent; + struct stat stat_block; + char full_name[CROSS_LEN]; + char dir_entcopy[CROSS_LEN]; + + Bit8u srch_attr;char srch_pattern[DOS_NAMELENGTH_ASCII]; + Bit8u find_attr; + + dta.GetSearchParams(srch_attr,srch_pattern); + Bit16u id = dta.GetDirID(); + +again: + if (!dirCache.FindNext(id,dir_ent)) { + DOS_SetError(DOSERR_NO_MORE_FILES); + return false; + } + if(!WildFileCmp(dir_ent,srch_pattern)) goto again; + + strcpy(full_name,srchInfo[id].srch_dir); + strcat(full_name,dir_ent); + + //GetExpandName might indirectly destroy dir_ent (by caching in a new directory + //and due to its design dir_ent might be lost.) + //Copying dir_ent first + strcpy(dir_entcopy,dir_ent); + + //First try overlay: + char ovname[CROSS_LEN]; + char relativename[CROSS_LEN]; + strcpy(relativename,srchInfo[id].srch_dir); + //strip off basedir: //TODO cleanup + char* prel = relativename+strlen(basedir); + strcpy(ovname,overlaydir); + prel =full_name+strlen(basedir); + + + +#if 0 + //Check hidden/deleted directories first. TODO is this really needed. If the directory exist in the overlay things are weird anyway. + //the deleted paths are added to the deleted_files list. + if (is_deleted_dir(prel)) { + LOG_MSG("skipping early out deleted dir %s",prel); + goto again; + } +#endif + + strcat(ovname,full_name+strlen(basedir)); + bool statok = ( stat(ovname,&stat_block)==0); + + if (logoverlay) LOG_MSG("listing %s",dir_entcopy); + if (statok) { + if (logoverlay) LOG_MSG("using overlay data for %s : %s",full_name, ovname); + } else { + char preldos[CROSS_LEN]; + strcpy(preldos,prel); + CROSS_DOSFILENAME(preldos); + if (is_deleted_file(preldos)) { + if (logoverlay) LOG_MSG("skipping deleted file %s %s %s",preldos,full_name,ovname); + goto again; + } + if (stat(dirCache.GetExpandName(full_name),&stat_block)!=0) { + if (logoverlay) LOG_MSG("stat failed for %s . This should not happen.",dirCache.GetExpandName(full_name)); + goto again;//No symlinks and such + } + } + + if(stat_block.st_mode & S_IFDIR) find_attr=DOS_ATTR_DIRECTORY; + else find_attr=DOS_ATTR_ARCHIVE; + if (~srch_attr & find_attr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM)) goto again; + + /*file is okay, setup everything to be copied in DTA Block */ + char find_name[DOS_NAMELENGTH_ASCII];Bit16u find_date,find_time;Bit32u find_size; + + if(strlen(dir_entcopy)tm_year+1900),(Bit16u)(time->tm_mon+1),(Bit16u)time->tm_mday); + find_time=DOS_PackTime((Bit16u)time->tm_hour,(Bit16u)time->tm_min,(Bit16u)time->tm_sec); + } else { + find_time=6; + find_date=4; + } + dta.SetResult(find_name,find_size,find_date,find_time,find_attr); + return true; +} + + + +bool Overlay_Drive::FileUnlink(char * name) { + Bitu a = GetTicks(); + if (logoverlay) LOG_MSG("calling unlink on %s",name); + char basename[CROSS_LEN]; + strcpy(basename,basedir); + strcat(basename,name); + CROSS_FILENAME(basename); + + + char overlayname[CROSS_LEN]; + strcpy(overlayname,overlaydir); + strcat(overlayname,name); + CROSS_FILENAME(overlayname); +// char *fullname = dirCache.GetExpandName(newname); + if (unlink(overlayname)) { + //Unlink failed for some reason try finding it. + struct stat buffer; + if(stat(overlayname,&buffer)) { + //file not found in overlay, check the basedrive + //Check if file not already deleted + if (is_deleted_file(name)) return false; + + + char *fullname = dirCache.GetExpandName(basename); + if (stat(fullname,&buffer)) return false; // File not found in either, return file false. + //File does exist in normal drive. + //Maybe do something with the drive_cache. + add_deleted_file(name,true); + return true; +// E_Exit("trying to remove existing non-overlay file %s",name); + } + FILE* file_writable = fopen(overlayname,"rb+"); + if(!file_writable) return false; //No access ? ERROR MESSAGE NOT SET. FIXME ? + fclose(file_writable); + + //File exists and can technically be deleted, nevertheless it failed. + //This means that the file is probably open by some process. + //See if We have it open. + bool found_file = false; + for(Bitu i = 0;i < DOS_FILES;i++){ + if(Files[i] && Files[i]->IsName(name)) { + Bitu max = DOS_FILES; + while(Files[i]->IsOpen() && max--) { + Files[i]->Close(); + if (Files[i]->RemoveRef()<=0) break; + } + found_file=true; + } + } + if(!found_file) return false; + if (unlink(overlayname) == 0) { //Overlay file removed + //Mark basefile as deleted if it exists: + if (localDrive::FileExists(name)) add_deleted_file(name,true); + remove_DOSname_from_cache(name); + //Handle this better + dirCache.DeleteEntry(basename); + update_cache(false); + //Check if it exists in the base dir as well + + return true; + } + return false; + } else { //Removed from overlay. + //TODO IF it exists in the basedir: and more locations above. + if (localDrive::FileExists(name)) add_deleted_file(name,true); + remove_DOSname_from_cache(name); + //TODODO remove from the update_cache cache as well + //Handle this better + //Check if it exists in the base dir as well + dirCache.DeleteEntry(basename); + + update_cache(false); + if (logoverlay) LOG_MSG("OPTIMISE: unlink took %d",GetTicks()-a); + return true; + } +} + + +bool Overlay_Drive::GetFileAttr(char * name,Bit16u * attr) { + char overlayname[CROSS_LEN]; + strcpy(overlayname,overlaydir); + strcat(overlayname,name); + CROSS_FILENAME(overlayname); + + struct stat status; + if (stat(overlayname,&status)==0) { + *attr=DOS_ATTR_ARCHIVE; + if(status.st_mode & S_IFDIR) *attr|=DOS_ATTR_DIRECTORY; + return true; + } + //Maybe check for deleted path as well + if (is_deleted_file(name)) { + *attr = 0; + return false; + } + return localDrive::GetFileAttr(name,attr); + +} + + +void Overlay_Drive::add_deleted_file(const char* name,bool create_on_disk) { + if (logoverlay) LOG_MSG("add del file %s",name); + if (!is_deleted_file(name)) { + deleted_files_in_base.push_back(name); + if (create_on_disk) add_deleted_file_to_disk(name); + + } +} + +void Overlay_Drive::add_deleted_file_to_disk(const char* dosname) { + std::string name = create_filename_of_special_operation(dosname,"DEL"); + char overlayname[CROSS_LEN]; + strcpy(overlayname,overlaydir); + strcat(overlayname,name.c_str()); + CROSS_FILENAME(overlayname); + FILE* f = fopen(overlayname,"wb+"); + if (!f) { + Sync_leading_dirs(dosname); + f = fopen(overlayname,"wb+"); + } + if (!f) E_Exit("Failed creation of %s",overlayname); + char buf[5] = {'e','m','p','t','y'}; + fwrite(buf,5,1,f); + fclose(f); + +} +void Overlay_Drive::remove_deleted_file_from_disk(const char* dosname) { + std::string name = create_filename_of_special_operation(dosname,"DEL"); + char overlayname[CROSS_LEN]; + strcpy(overlayname,overlaydir); + strcat(overlayname,name.c_str()); + CROSS_FILENAME(overlayname); + if(unlink(overlayname) != 0) E_Exit("Failed removal of %s",overlayname); +} + +std::string Overlay_Drive::create_filename_of_special_operation(const char* dosname, const char* operation) { + + std::string res(dosname); + std::string::size_type s = res.rfind("\\"); //CHECK DOS or host endings.... on update_cache + if (s == std::string::npos) s = 0; else s++; + std::string oper = special_prefix +"_" +operation +"_"; + res.insert(s,oper); + return res; + + +} + +bool Overlay_Drive::is_deleted_file(const char* name) { + if (!name || !*name) return false; + if (deleted_files_in_base.empty()) return false; + for(std::vector::iterator it = deleted_files_in_base.begin(); it != deleted_files_in_base.end(); it++) { + if (*it == name) return true; + } + return false; +} + +void Overlay_Drive::remove_deleted_file(const char* name,bool create_on_disk) { + for(std::vector::iterator it = deleted_files_in_base.begin(); it != deleted_files_in_base.end(); it++) { + if (*it == name) { + deleted_files_in_base.erase(it); + if (create_on_disk) remove_deleted_file_from_disk(name); + break; + } + } +} +void Overlay_Drive::add_deleted_path(const char* name) { + if (!name || !*name ) return; //Skip empty file. + if (logoverlay) LOG_MSG("add del path %s",name); + if (!is_deleted_path(name)) { + deleted_paths_in_base.push_back(name); + //Add it to deleted files as well, so it gets skipped in FindNext. + //Maybe revise that. + add_deleted_file(name,false); + } +} +bool Overlay_Drive::is_deleted_path(const char* name) { + if (!name || !*name) return false; + if (deleted_paths_in_base.empty()) return false; + std::string sname(name); + std::string::size_type namelen = sname.length();; + for(std::vector::iterator it = deleted_paths_in_base.begin(); it != deleted_paths_in_base.end(); it++) { + std::string::size_type blockedlen = (*it).length(); + if (namelen < blockedlen) continue; + //See if input starts with name. + std::string::size_type n = sname.find(*it); + if (n == 0 && (namelen == blockedlen) || *(name+blockedlen) =='\\' ) return true; + } + return false; +} + +void Overlay_Drive::remove_deleted_path(const char* name) { + for(std::vector::iterator it = deleted_paths_in_base.begin(); it != deleted_paths_in_base.end(); it++) { + if (*it == name) { + deleted_paths_in_base.erase(it); + break; + } + } +} + +bool Overlay_Drive::FileExists(const char* name) { + char overlayname[CROSS_LEN]; + strcpy(overlayname,overlaydir); + strcat(overlayname,name); + CROSS_FILENAME(overlayname); + struct stat temp_stat; + if(stat(overlayname,&temp_stat)==0 && (temp_stat.st_mode & S_IFDIR)==0) return true; + + if (is_deleted_file(name)) return false; + + return localDrive::FileExists(name); +} + +#if 1 +bool Overlay_Drive::Rename(char * oldname,char * newname) { + //TODO with cache function! +//Tricky function. +//Renaming directories is currently not supported, due the drive_cache not handling that smoothly. +//So oldname is directory => Exit! +//If oldname is on overlay => simple rename. +//if oldname is on base => copy file to overlay with new name and mark old file as deleted. +//More advanced version. keep track of the file being renamed in order to detect that the file is being renamed back. + Bit16u attr=0; + if (!GetFileAttr(oldname,&attr)) E_Exit("rename, but source doesn't exist, should not happen %s",oldname); + if (attr&DOS_ATTR_DIRECTORY) E_Exit("renaming directory %s to %s . Not yet supported in Overlay",oldname,newname); + Bitu a = GetTicks(); + //First generate overlay names. + char overlaynameold[CROSS_LEN]; + strcpy(overlaynameold,overlaydir); + strcat(overlaynameold,oldname); + CROSS_FILENAME(overlaynameold); + + char overlaynamenew[CROSS_LEN]; + strcpy(overlaynamenew,overlaydir); + strcat(overlaynamenew,newname); + CROSS_FILENAME(overlaynamenew); + + //No need to check if the original is marked as deleted, as GetFileAttr would fail if it did. + + //Check if overlay source file exists + struct stat tempstat; + int temp = -1; + if (stat(overlaynameold,&tempstat) ==0) { + //Simple rename + temp = rename(overlaynameold,overlaynamenew); + //TODO CHECK if base has a file with same oldname!!!!! if it does mark it as deleted!! + if (localDrive::FileExists(oldname)) add_deleted_file(oldname,true); + } else { + Bitu aa = GetTicks(); + //File exists in the basedrive. Make a copy and mark old one as deleted. + char newold[CROSS_LEN]; + strcpy(newold,basedir); + strcat(newold,oldname); + CROSS_FILENAME(newold); + dirCache.ExpandName(newold); + FILE* o = fopen(newold,"rb"); + if (!o) return false; + FILE* n = create_file_in_overlay(newname,"wb+"); + if (!n) {fclose(o); return false;} + char buffer[BUFSIZ]; + size_t s; + while ( (s = fread(buffer,1,BUFSIZ,o)) ) fwrite(buffer, 1, s, n); + fclose(o); fclose(n); + + //File copied. + //Mark old file as deleted + add_deleted_file(oldname,true); + temp =0; //success + if (logoverlay) LOG_MSG("OPTIMISE: update rename with copy took %d",GetTicks()-aa); + + } + if (temp ==0) { + //handle the drive_cache (a bit better) + //Ensure that the file is not marked as deleted anymore. + if (is_deleted_file(newname)) remove_deleted_file(newname,true); + dirCache.EmptyCache(); + update_cache(true); + if (logoverlay) LOG_MSG("OPTIMISE: rename took %d",GetTicks()-a); + + } + return (temp==0); + +} +#endif + +bool Overlay_Drive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) { + if (logoverlay) LOG_MSG("FindFirst in %s",_dir); + + if (is_deleted_path(_dir)) { + //No accidental listing of files in there. + DOS_SetError(DOSERR_PATH_NOT_FOUND); + return false; + } + + return localDrive::FindFirst(_dir,dta,fcb_findfirst); +} + +bool Overlay_Drive::FileStat(const char* name, FileStat_Block * const stat_block) { + char overlayname[CROSS_LEN]; + strcpy(overlayname,overlaydir); + strcat(overlayname,name); + CROSS_FILENAME(overlayname); + struct stat temp_stat; + if(stat(overlayname,&temp_stat) != 0) { + if (is_deleted_file(name)) return false; + return localDrive::FileStat(name,stat_block); + } + /* Convert the stat to a FileStat */ + struct tm *time; + if((time=localtime(&temp_stat.st_mtime))!=0) { + stat_block->time=DOS_PackTime((Bit16u)time->tm_hour,(Bit16u)time->tm_min,(Bit16u)time->tm_sec); + stat_block->date=DOS_PackDate((Bit16u)(time->tm_year+1900),(Bit16u)(time->tm_mon+1),(Bit16u)time->tm_mday); + } else { + // ... But this function is not used at the moment. + } + stat_block->size=(Bit32u)temp_stat.st_size; + return true; +} + +Bits Overlay_Drive::UnMount(void) { + delete this; + return 0; +} +void Overlay_Drive::EmptyCache(void){ + localDrive::EmptyCache(); + update_cache(true);//lets rebuild it. +} + diff --git a/src/dos/drives.h b/src/dos/drives.h index 589b6da4..e53ef9d4 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -21,6 +21,7 @@ #define _DRIVES_H__ #include +#include #include #include "dos_system.h" #include "shell.h" /* for DOS_Shell */ @@ -70,13 +71,17 @@ public: virtual bool isRemote(void); virtual bool isRemovable(void); virtual Bits UnMount(void); -private: + const char* getBasedir() {return basedir;}; +protected: char basedir[CROSS_LEN]; - friend void DOS_Shell::CMD_SUBST(char* args); +private: + friend void DOS_Shell::CMD_SUBST(char* args); +protected: struct { char srch_dir[CROSS_LEN]; } srchInfo[MAX_OPENDIRS]; +private: struct { Bit16u bytes_sector; Bit8u sectors_cluster; @@ -406,6 +411,51 @@ private: VFILE_Block * search_file; }; +class Overlay_Drive: public localDrive { +public: + Overlay_Drive(const char * startdir,const char* overlay, Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid,Bit8u &error); + virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags); + virtual bool FileCreate(DOS_File * * file,char * name,Bit16u /*attributes*/); + virtual bool FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst); + virtual bool FindNext(DOS_DTA & dta); + virtual bool FileUnlink(char * name); + virtual bool GetFileAttr(char * name,Bit16u * attr); + virtual bool FileExists(const char* name); + virtual bool Rename(char * oldname,char * newname); + virtual bool FileStat(const char* name, FileStat_Block * const stat_block); + virtual void EmptyCache(void); + + bool Sync_leading_dirs(const char* dos_filename); + FILE* create_file_in_overlay(char* dos_filename, char const* mode); + virtual Bits UnMount(void); + virtual bool TestDir(char * dir); + virtual bool RemoveDir(char * dir); + virtual bool MakeDir(char * dir); +private: + char overlaydir[CROSS_LEN]; + bool optimize_cache_v1; + void add_DOSname_to_cache(const char* name); + void remove_DOSname_from_cache(const char* name); + void update_cache(bool read_directory_contents = false); + + std::vector deleted_files_in_base; //Set is probably better, or some other solution (involving the disk). + std::vector deleted_paths_in_base; //Currently used to hide the overlay folder. + std::string overlap_folder; + void add_deleted_file(const char* name, bool create_on_disk=true); + void remove_deleted_file(const char* name, bool create_on_disk=true); + bool is_deleted_file(const char* name); + void add_deleted_path(const char* name); + void remove_deleted_path(const char* name); + bool is_deleted_path(const char* name); + + void remove_deleted_file_from_disk(const char* dosname); + void add_deleted_file_to_disk(const char* dosname); + std::string create_filename_of_special_operation(const char* dosname, const char* operation); + void convert_overlay_to_DOSname_in_base(char* dirname ); + //For caching the update_cache routine. + std::vector DOSnames_cache; //Also set is probably better. + const std::string special_prefix; +}; #endif diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 36c30833..5a1bac18 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -436,6 +436,9 @@ + + From 94113a7362c62809f6eae4dfb61a38fe67edca06 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 29 Mar 2019 20:47:57 +0000 Subject: [PATCH 4087/4131] Change multi_remain to repeat last parsed value for non-string types if the next value is empty and of the same type as the last. Use this to add an optional parameter to sensitivity which controls the y axis. When optional parameter is missing, x and y axis have the same value. Change limits on sensitivity to allow for negative values so the Mouse Y-axis can be inversed. Similar to patch #276. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4197 --- src/gui/sdlmain.cpp | 28 ++++++++++++++++++---------- src/misc/setup.cpp | 34 ++++++++++++++++++++++++++++------ 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 4fd943f7..7df007fc 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -206,7 +206,8 @@ struct SDL_Block { bool autoenable; bool requestlock; bool locked; - Bitu sensitivity; + int xsensitivity; + int ysensitivity; } mouse; SDL_Rect updateRects[1024]; Bitu num_joysticks; @@ -1289,7 +1290,10 @@ static void GUI_StartUp(Section * sec) { sdl.mouse.autoenable=section->Get_bool("autolock"); if (!sdl.mouse.autoenable) SDL_ShowCursor(SDL_DISABLE); sdl.mouse.autolock=false; - sdl.mouse.sensitivity=section->Get_int("sensitivity"); + + Prop_multival* p3 = section->Get_multival("sensitivity"); + sdl.mouse.xsensitivity = p3->GetSection()->Get_int("xsens"); + sdl.mouse.ysensitivity = p3->GetSection()->Get_int("ysens"); std::string output=section->Get_string("output"); /* Setup Mouse correctly if fullscreen */ @@ -1458,10 +1462,10 @@ void Mouse_AutoLock(bool enable) { static void HandleMouseMotion(SDL_MouseMotionEvent * motion) { if (sdl.mouse.locked || !sdl.mouse.autoenable) - Mouse_CursorMoved((float)motion->xrel*sdl.mouse.sensitivity/100.0f, - (float)motion->yrel*sdl.mouse.sensitivity/100.0f, - (float)(motion->x-sdl.clip.x)/(sdl.clip.w-1)*sdl.mouse.sensitivity/100.0f, - (float)(motion->y-sdl.clip.y)/(sdl.clip.h-1)*sdl.mouse.sensitivity/100.0f, + Mouse_CursorMoved((float)motion->xrel*sdl.mouse.xsensitivity/100.0f, + (float)motion->yrel*sdl.mouse.ysensitivity/100.0f, + (float)(motion->x-sdl.clip.x)/(sdl.clip.w-1)*sdl.mouse.xsensitivity/100.0f, + (float)(motion->y-sdl.clip.y)/(sdl.clip.h-1)*sdl.mouse.ysensitivity/100.0f, sdl.mouse.locked); } @@ -1470,7 +1474,7 @@ static void HandleMouseButton(SDL_MouseButtonEvent * button) { case SDL_PRESSED: if (sdl.mouse.requestlock && !sdl.mouse.locked) { GFX_CaptureMouse(); - // Dont pass klick to mouse handler + // Don't pass click to mouse handler break; } if (!sdl.mouse.autoenable && sdl.mouse.autolock && button->button == SDL_BUTTON_MIDDLE) { @@ -1755,9 +1759,13 @@ void Config_Add_SDL() { Pbool = sdl_sec->Add_bool("autolock",Property::Changeable::Always,true); Pbool->Set_help("Mouse will automatically lock, if you click on the screen. (Press CTRL-F10 to unlock)"); - Pint = sdl_sec->Add_int("sensitivity",Property::Changeable::Always,100); - Pint->SetMinMax(1,1000); - Pint->Set_help("Mouse sensitivity."); + Pmulti = sdl_sec->Add_multi("sensitivity",Property::Changeable::Always, ","); + Pmulti->Set_help("Mouse sensitivity. The optional second parameter specifies vertical sensitivity (e.g. 100,-50)."); + Pmulti->SetValue("100"); + Pint = Pmulti->GetSection()->Add_int("xsens",Property::Changeable::Always,100); + Pint->SetMinMax(-1000,1000); + Pint = Pmulti->GetSection()->Add_int("ysens",Property::Changeable::Always,100); + Pint->SetMinMax(-1000,1000); Pbool = sdl_sec->Add_bool("waitonerror",Property::Changeable::Always, true); Pbool->Set_help("Wait before closing the console if dosbox has an error."); diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index cfac48f4..47946284 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -429,6 +429,9 @@ bool Prop_multival::SetValue(std::string const& input) { Property *p = section->Get_prop(0); //No properties in this section. do nothing if (!p) return false; + Value::Etype prevtype = Value::V_NONE; + string prevargument = ""; + string::size_type loc = string::npos; while( (p = section->Get_prop(i++)) ) { //trim leading separators @@ -443,13 +446,32 @@ bool Prop_multival::SetValue(std::string const& input) { in = local; local = ""; } - //Test Value. If it fails set default - Value valtest (in,p->Get_type()); - if (!p->CheckValue(valtest,true)) { - make_default_value(); - return false; + + if (p->Get_type() == Value::V_STRING) { + //Strings are only checked against the suggested values list. + //Test Value. If it fails set default + Value valtest (in,p->Get_type()); + if (!p->CheckValue(valtest,true)) { + make_default_value(); + return false; + } + p->SetValue(in); + } else { + //Non-strings can have more things, conversion alone is not enough (as invalid values as converted to 0) + bool r = p->SetValue(in); + if (!r) { + if (in.empty() && p->Get_type() == prevtype ) { + //Nothing there, but same type of variable, so repeat it (sensitivity) + in = prevargument; + p->SetValue(in); + } else { + //Something was there to be parsed or not the same type. Invalidate entire property. + make_default_value(); + } + } } - p->SetValue(in); + prevtype = p->Get_type(); + prevargument = in; } return retval; From c9c97f13afd36dcbdde4e0acaacc8559bdce5ee9 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 31 Mar 2019 18:06:27 +0000 Subject: [PATCH 4088/4131] Correct bug related to signedness (M-HT). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4198 --- src/gui/render_templates_hq.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/render_templates_hq.h b/src/gui/render_templates_hq.h index 002f1fff..3bfd65e3 100644 --- a/src/gui/render_templates_hq.h +++ b/src/gui/render_templates_hq.h @@ -41,17 +41,17 @@ static inline bool diffYUV(Bit32u yuv1, Bit32u yuv2) Bit32u mask; diff = ((yuv1 & Ymask) - (yuv2 & Ymask)); - mask = diff >> 31; // -1 if value < 0, 0 otherwise + mask = ((Bit32s)diff) >> 31; // ~1/-1 if value < 0, 0 otherwise diff = (diff ^ mask) - mask; //-1: ~value + 1; 0: value if (diff > trY) return true; diff = ((yuv1 & Umask) - (yuv2 & Umask)); - mask = diff >> 31; // -1 if value < 0, 0 otherwise + mask = ((Bit32s)diff)>> 31; // ~1/-1 if value < 0, 0 otherwise diff = (diff ^ mask) - mask; //-1: ~value + 1; 0: value if (diff > trU) return true; diff = ((yuv1 & Vmask) - (yuv2 & Vmask)); - mask = diff >> 31; // -1 if value < 0, 0 otherwise + mask = ((Bit32s)diff) >> 31; // ~1/-1 if value < 0, 0 otherwise diff = (diff ^ mask) - mask; //-1: ~value + 1; 0: value if (diff > trV) return true; From 4a1ef4d3d71454812176240e5c9e8770ca214e94 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 1 Apr 2019 14:32:18 +0000 Subject: [PATCH 4089/4131] Refine stack overflow and underflow for the fpu a bit. Overflow is still treated as Exit. Underflow is ignored in release mode as it happens every now and then and doesn't seem to cause issues if ignored, thus restoring 0.74 behaviour. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4199 --- include/fpu.h | 22 +++++++++++++++++++ src/fpu/fpu_instructions.h | 39 +++++++++++++++++++++++++++++++-- src/fpu/fpu_instructions_x86.h | 40 +++++++++++++++++++++++++++++++--- 3 files changed, 96 insertions(+), 5 deletions(-) diff --git a/include/fpu.h b/include/fpu.h index da29096f..44acd31b 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -19,6 +19,11 @@ #ifndef DOSBOX_FPU_H #define DOSBOX_FPU_H +#ifndef DOSBOX_DOSBOX_H +//So the right config.h gets included for C_DEBUG +#include "dosbox.h" +#endif + #ifndef DOSBOX_MEM_H #include "mem.h" #endif @@ -150,5 +155,22 @@ static INLINE void FPU_SET_C3(Bitu C){ if(C) fpu.sw |= 0x4000; } +#define DB_FPU_STACK_CHECK_NONE 0 +#define DB_FPU_STACK_CHECK_LOG 1 +#define DB_FPU_STACK_CHECK_EXIT 2 +//NONE is 0.74 behavior: not care about stack overflow/underflow +//Overflow is always logged/exited on. +//Underflow can be controlled with by this. +//LOG is giving a message when encountered +//EXIT is to hard exit. +//Currently pop is ignored in release mode and overflow is exit. +//in debug mode: pop will log and overflow is exit. +#if C_DEBUG +#define DB_FPU_STACK_CHECK_POP DB_FPU_STACK_CHECK_LOG +#define DB_FPU_STACK_CHECK_PUSH DB_FPU_STACK_CHECK_EXIT +#else +#define DB_FPU_STACK_CHECK_POP DB_FPU_STACK_CHECK_NONE +#define DB_FPU_STACK_CHECK_PUSH DB_FPU_STACK_CHECK_EXIT +#endif #endif diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index c0c3d090..9dc97c76 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,6 +16,9 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#ifndef DOSBOX_FPU_H +#include "fpu.h" +#endif static void FPU_FINIT(void) { @@ -43,7 +46,23 @@ static void FPU_FNOP(void){ static void FPU_PREP_PUSH(void){ TOP = (TOP - 1) &7; - if (GCC_UNLIKELY(fpu.tags[TOP] != TAG_Empty)) E_Exit("FPU stack overflow"); +#if DB_FPU_STACK_CHECK_PUSH > DB_FPU_STACK_CHECK_NONE + if (GCC_UNLIKELY(fpu.tags[TOP] != TAG_Empty)) { +#if DB_FPU_STACK_CHECK_PUSH == DB_FPU_STACK_CHECK_EXIT + E_Exit("FPU stack overflow"); +#else + if (fpu.cw&1) { // Masked ? + fpu.sw &= 0x1; //Invalid Operation + fpu.sw &= 0x40; //Stack Fault + FPU_SET_C1(1); //Register is used. + //No need to set 0x80 as the exception is masked. + LOG(LOG_FPU,LOG_ERROR)("Masked stack overflow encountered!"); + } else { + E_Exit("FPU stack overflow"); //Exit as this is bad + } +#endif + } +#endif fpu.tags[TOP] = TAG_Valid; } @@ -56,7 +75,23 @@ static void FPU_PUSH(double in){ static void FPU_FPOP(void){ - if (GCC_UNLIKELY(fpu.tags[TOP] == TAG_Empty)) E_Exit("FPU stack underflow"); +#if DB_FPU_STACK_CHECK_POP > DB_FPU_STACK_CHECK_NONE + if (GCC_UNLIKELY(fpu.tags[TOP] != TAG_Empty)) { +#if DB_FPU_STACK_CHECK_POP == DB_FPU_STACK_CHECK_EXIT + E_Exit("FPU stack underflow"); +#else + if (fpu.cw&1) { // Masked ? + fpu.sw &= 0x1; //Invalid Operation + fpu.sw &= 0x40; //Stack Fault + FPU_SET_C1(0); //Register is free. + //No need to set 0x80 as the exception is masked. + LOG(LOG_FPU,LOG_ERROR)("Masked stack underflow encountered!"); + } else { + LOG_MSG("Unmasked Stack underflow!"); //Also log in release mode + } +#endif + } +#endif fpu.tags[TOP]=TAG_Empty; //maybe set zero in it as well TOP = ((TOP+1)&7); diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index 5b62177d..31e51fc4 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -16,7 +16,9 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - +#ifndef DOSBOX_FPU_H +#include "fpu.h" +#endif // #define WEAK_EXCEPTIONS @@ -957,12 +959,44 @@ static void FPU_FNOP(void){ static void FPU_PREP_PUSH(void){ TOP = (TOP - 1) &7; - if (GCC_UNLIKELY(fpu.tags[TOP] != TAG_Empty)) E_Exit("FPU stack overflow"); +#if DB_FPU_STACK_CHECK_PUSH > DB_FPU_STACK_CHECK_NONE + if (GCC_UNLIKELY(fpu.tags[TOP] != TAG_Empty)) { +#if DB_FPU_STACK_CHECK_PUSH == DB_FPU_STACK_CHECK_EXIT + E_Exit("FPU stack overflow"); +#else + if (fpu.cw&1) { // Masked ? + fpu.sw &= 0x1; //Invalid Operation + fpu.sw &= 0x40; //Stack Fault + FPU_SET_C1(1); //Register is used. + //No need to set 0x80 as the exception is masked. + LOG(LOG_FPU,LOG_ERROR)("Masked stack overflow encountered!"); + } else { + E_Exit("FPU stack overflow"); //Exit as this is bad + } +#endif + } +#endif fpu.tags[TOP] = TAG_Valid; } static void FPU_FPOP(void){ - if (GCC_UNLIKELY(fpu.tags[TOP] == TAG_Empty)) E_Exit("FPU stack underflow"); +#if DB_FPU_STACK_CHECK_POP > DB_FPU_STACK_CHECK_NONE + if (GCC_UNLIKELY(fpu.tags[TOP] == TAG_Empty)) { +#if DB_FPU_STACK_CHECK_POP == DB_FPU_STACK_CHECK_EXIT + E_Exit("FPU stack underflow"); +#else + if (fpu.cw&1) { // Masked ? + fpu.sw &= 0x1; //Invalid Operation + fpu.sw &= 0x40; //Stack Fault + FPU_SET_C1(0); //Register is free. + //No need to set 0x80 as the exception is masked. + LOG(LOG_FPU,LOG_ERROR)("Masked stack underflow encountered!"); + } else { + LOG_MSG("Unmasked Stack underflow!"); + } +#endif + } +#endif fpu.tags[TOP] = TAG_Empty; TOP = ((TOP+1)&7); } From 687e3cf058fd5d13bc11075bbb45a3b69a232983 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 1 Apr 2019 16:50:49 +0000 Subject: [PATCH 4090/4131] Ensure room before adding environment variable using set. Noted when running a subshell under NC. Bug left: we don't have a lot of environment space in that case (not the 160 minimum). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4200 --- src/misc/programs.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index ed1d3c96..12ffcb86 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -220,9 +220,16 @@ Bitu Program::GetEnvCount(void) { } bool Program::SetEnv(const char * entry,const char * new_string) { - PhysPt env_read=PhysMake(psp->GetEnvironment(),0); - PhysPt env_write=env_read; - char env_string[1024+1]; + PhysPt env_read = PhysMake(psp->GetEnvironment(),0); + + //Get size of environment. + DOS_MCB mcb(psp->GetEnvironment()-1); + Bit16u envsize = mcb.GetSize()*16; + + + PhysPt env_write = env_read; + PhysPt env_write_start = env_read; + char env_string[1024+1] = { 0 }; do { MEM_StrCopy(env_read,env_string,1024); if (!env_string[0]) break; @@ -235,11 +242,14 @@ bool Program::SetEnv(const char * entry,const char * new_string) { } while (1); /* TODO Maybe save the program name sometime. not really needed though */ /* Save the new entry */ + + //ensure room + if (envsize <= (env_write-env_write_start) + strlen(entry) + 1 + strlen(new_string) + 2) return false; + if (new_string[0]) { std::string bigentry(entry); for (std::string::iterator it = bigentry.begin(); it != bigentry.end(); ++it) *it = toupper(*it); - sprintf(env_string,"%s=%s",bigentry.c_str(),new_string); -// sprintf(env_string,"%s=%s",entry,new_string); //oldcode + snprintf(env_string,1024+1,"%s=%s",bigentry.c_str(),new_string); MEM_BlockWrite(env_write,env_string,(Bitu)(strlen(env_string)+1)); env_write += (PhysPt)(strlen(env_string)+1); } From 3978e059090494534f9b7b936ce7f5e69b0ac7bc Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Mon, 1 Apr 2019 22:06:11 +0000 Subject: [PATCH 4091/4131] Improve prefetch and simple cores to not switch to normal core on trap execution. Fixes the demo version of Prehistorik 2 and similar cases that use the trap flag and prefetch tricks. Thanks NewRisingSun. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4201 --- include/cpu.h | 1 + src/cpu/core_normal.cpp | 2 ++ src/cpu/core_normal/prefix_66.h | 12 ++++++------ src/cpu/core_normal/prefix_none.h | 12 ++++++------ src/cpu/core_prefetch.cpp | 2 ++ src/cpu/core_simple.cpp | 5 +++-- 6 files changed, 20 insertions(+), 14 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 7478f4ca..ecbabd7c 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -71,6 +71,7 @@ extern CPU_Decoder * cpudecoder; Bits CPU_Core_Normal_Run(void); Bits CPU_Core_Normal_Trap_Run(void); Bits CPU_Core_Simple_Run(void); +Bits CPU_Core_Simple_Trap_Run(void); Bits CPU_Core_Full_Run(void); Bits CPU_Core_Dyn_X86_Run(void); Bits CPU_Core_Dyn_X86_Trap_Run(void); diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 0049c2c2..0d9cfc39 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -58,6 +58,8 @@ extern Bitu cycle_count; #define CPU_PIC_CHECK 1 #define CPU_TRAP_CHECK 1 +#define CPU_TRAP_DECODER CPU_Core_Normal_Trap_Run + #define OPCODE_NONE 0x000 #define OPCODE_0F 0x100 #define OPCODE_SIZE 0x200 diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index baa295e5..0c9218c7 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -390,7 +390,7 @@ CPU_CALL(true,newcs,newip,GETIP); #if CPU_TRAP_CHECK if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; + cpudecoder=CPU_TRAP_DECODER; return CBRET_NONE; } #endif @@ -403,7 +403,7 @@ if (CPU_POPF(true)) RUNEXCEPTION(); #if CPU_TRAP_CHECK if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; + cpudecoder=CPU_TRAP_DECODER; goto decode_end; } #endif @@ -515,7 +515,7 @@ CPU_IRET(true,GETIP); #if CPU_TRAP_CHECK if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; + cpudecoder=CPU_TRAP_DECODER; return CBRET_NONE; } #endif @@ -589,7 +589,7 @@ CPU_JMP(true,newcs,newip,GETIP); #if CPU_TRAP_CHECK if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; + cpudecoder=CPU_TRAP_DECODER; return CBRET_NONE; } #endif @@ -677,7 +677,7 @@ CPU_CALL(true,newcs,newip,GETIP); #if CPU_TRAP_CHECK if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; + cpudecoder=CPU_TRAP_DECODER; return CBRET_NONE; } #endif @@ -697,7 +697,7 @@ CPU_JMP(true,newcs,newip,GETIP); #if CPU_TRAP_CHECK if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; + cpudecoder=CPU_TRAP_DECODER; return CBRET_NONE; } #endif diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 525c4b9b..5d59e80c 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -564,7 +564,7 @@ CPU_CALL(false,newcs,newip,GETIP); #if CPU_TRAP_CHECK if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; + cpudecoder=CPU_TRAP_DECODER; return CBRET_NONE; } #endif @@ -579,7 +579,7 @@ if (CPU_POPF(false)) RUNEXCEPTION(); #if CPU_TRAP_CHECK if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; + cpudecoder=CPU_TRAP_DECODER; goto decode_end; } #endif @@ -780,7 +780,7 @@ CPU_IRET(false,GETIP); #if CPU_TRAP_CHECK if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; + cpudecoder=CPU_TRAP_DECODER; return CBRET_NONE; } #endif @@ -919,7 +919,7 @@ CPU_JMP(false,newcs,newip,GETIP); #if CPU_TRAP_CHECK if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; + cpudecoder=CPU_TRAP_DECODER; return CBRET_NONE; } #endif @@ -1132,7 +1132,7 @@ CPU_CALL(false,newcs,newip,GETIP); #if CPU_TRAP_CHECK if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; + cpudecoder=CPU_TRAP_DECODER; return CBRET_NONE; } #endif @@ -1153,7 +1153,7 @@ CPU_JMP(false,newcs,newip,GETIP); #if CPU_TRAP_CHECK if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; + cpudecoder=CPU_TRAP_DECODER; return CBRET_NONE; } #endif diff --git a/src/cpu/core_prefetch.cpp b/src/cpu/core_prefetch.cpp index 58e2df76..f718cd56 100644 --- a/src/cpu/core_prefetch.cpp +++ b/src/cpu/core_prefetch.cpp @@ -59,6 +59,8 @@ extern Bitu cycle_count; #define CPU_PIC_CHECK 1 #define CPU_TRAP_CHECK 1 +#define CPU_TRAP_DECODER CPU_Core_Prefetch_Trap_Run + #define OPCODE_NONE 0x000 #define OPCODE_0F 0x100 #define OPCODE_SIZE 0x200 diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp index 96748190..9f18c3bc 100644 --- a/src/cpu/core_simple.cpp +++ b/src/cpu/core_simple.cpp @@ -50,6 +50,8 @@ extern Bitu cycle_count; #define CPU_PIC_CHECK 1 #define CPU_TRAP_CHECK 1 +#define CPU_TRAP_DECODER CPU_Core_Simple_Trap_Run + #define OPCODE_NONE 0x000 #define OPCODE_0F 0x100 #define OPCODE_SIZE 0x200 @@ -185,13 +187,12 @@ decode_end: return CBRET_NONE; } -// not really used Bits CPU_Core_Simple_Trap_Run(void) { Bits oldCycles = CPU_Cycles; CPU_Cycles = 1; cpu.trap_skip = false; - Bits ret=CPU_Core_Normal_Run(); + Bits ret=CPU_Core_Simple_Run(); if (!cpu.trap_skip) CPU_HW_Interrupt(1); CPU_Cycles = oldCycles-1; cpudecoder = &CPU_Core_Simple_Run; From 111fa1d45b345b062ff0d25f008c4f08d8b4f51b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 3 Apr 2019 10:31:52 +0000 Subject: [PATCH 4092/4131] Check lengths before adding C style strings together. Fixes #498 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4202 --- src/shell/shell_misc.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index 8575eb12..8723014e 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -253,17 +253,21 @@ void DOS_Shell::InputCommand(char * line) { if ((path = strrchr(line+completion_index,'/'))) completion_index = (Bit16u)(path-line+1); // build the completion list - char mask[DOS_PATHLENGTH]; + char mask[DOS_PATHLENGTH] = {0}; + if (strlen(p_completion_start) + 3 >= DOS_PATHLENGTH) { + //Beep; + break; + } if (p_completion_start) { - strcpy(mask, p_completion_start); + safe_strncpy(mask, p_completion_start,DOS_PATHLENGTH); char* dot_pos=strrchr(mask,'.'); char* bs_pos=strrchr(mask,'\\'); char* fs_pos=strrchr(mask,'/'); char* cl_pos=strrchr(mask,':'); // not perfect when line already contains wildcards, but works if ((dot_pos-bs_pos>0) && (dot_pos-fs_pos>0) && (dot_pos-cl_pos>0)) - strcat(mask, "*"); - else strcat(mask, "*.*"); + strncat(mask, "*",DOS_PATHLENGTH - 1); + else strncat(mask, "*.*",DOS_PATHLENGTH - 1); } else { strcpy(mask, "*.*"); } From c03a6f497c4c6a3304ad0befb390886f8ce6baac Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 6 Apr 2019 17:02:40 +0000 Subject: [PATCH 4093/4131] We use the old style headers in other places and use the functions/types without std:: Should help compilation on FreeBSD. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4203 --- include/setup.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/setup.h b/include/setup.h index 3622d0f8..27c91776 100644 --- a/include/setup.h +++ b/include/setup.h @@ -43,7 +43,7 @@ #ifndef CH_CSTDIO #define CH_CSTDIO -#include +#include #endif From 8688dc9702a005b25079ca9e45cf0eb871dd0bb6 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Mon, 8 Apr 2019 21:13:00 +0000 Subject: [PATCH 4094/4131] Add IBM signature in EGA video BIOS for compatibility. Fixes EGA detection in 221 B Baker Street. Also include trailing space in signature in case it is checked with word values. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4204 --- src/ints/int10_memory.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index 2bfd42fc..e3c40e2a 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -133,12 +133,10 @@ void INT10_SetupRomMemory(void) { // set up the start of the ROM phys_writew(rom_base+0,0xaa55); phys_writeb(rom_base+2,0x40); // Size of ROM: 64 512-blocks = 32KB - if (IS_VGA_ARCH) { - phys_writeb(rom_base+0x1e,0x49); // IBM string - phys_writeb(rom_base+0x1f,0x42); - phys_writeb(rom_base+0x20,0x4d); - phys_writeb(rom_base+0x21,0x00); - } + phys_writeb(rom_base+0x1e,0x49); // IBM string + phys_writeb(rom_base+0x1f,0x42); + phys_writeb(rom_base+0x20,0x4d); + phys_writeb(rom_base+0x21,0x20); int10.rom.used=0x100; } From ee2d3e73ce348a7f6dc31638a3cb909db05891e6 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 11 Apr 2019 15:48:04 +0000 Subject: [PATCH 4095/4131] Unify unmounting code. Fix unmounting of complex drives where parts were left and file pointers were kept open. (thanks jmarsh) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4205 --- src/dos/dos_programs.cpp | 74 ++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 41 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 38cda889..3b202c26 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -59,6 +59,37 @@ Bitu DEBUG_EnableDebugger(void); void MSCDEX_SetCDInterface(int intNr, int forceCD); static Bitu ZDRIVE_NUM = 25; +static const char* UnmountHelper(char umount) { + int i_drive; + if (umount < '0' || umount > 3+'0') + i_drive = toupper(umount) - 'A'; + else + i_drive = umount - '0'; + + if (i_drive >= DOS_DRIVES || i_drive < 0 || (Drives[i_drive] == NULL && imageDiskList[i_drive] == NULL)) + return MSG_Get("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED"); + + if (Drives[i_drive]) { + switch (DriveManager::UnmountDrive(i_drive)) { + case 1: return MSG_Get("PROGRAM_MOUNT_UMOUNT_NO_VIRTUAL"); + case 2: return MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS"); + } + Drives[i_drive] = 0; + mem_writeb(Real2Phys(dos.tables.mediaid)+i_drive*9,0); + if (i_drive == DOS_GetDefaultDrive()) { + DOS_SetDrive(ZDRIVE_NUM); + } + + } + + if (imageDiskList[i_drive]) { + delete imageDiskList[i_drive]; + imageDiskList[i_drive] = NULL; + } + + return MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCESS"); +} + class MOUNT : public Program { public: void ListMounts(void) { @@ -120,27 +151,7 @@ public: /* Check for unmounting */ if (cmd->FindString("-u",umount,false)) { - umount[0] = toupper(umount[0]); - int i_drive = umount[0]-'A'; - if (i_drive < DOS_DRIVES && i_drive >= 0 && Drives[i_drive]) { - switch (DriveManager::UnmountDrive(i_drive)) { - case 0: - Drives[i_drive] = 0; - mem_writeb(Real2Phys(dos.tables.mediaid)+i_drive*9,0); - if(i_drive == DOS_GetDefaultDrive()) - DOS_SetDrive(ZDRIVE_NUM); - WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCESS"),umount[0]); - break; - case 1: - WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NO_VIRTUAL")); - break; - case 2: - WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS")); - break; - } - } else { - WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED"),umount[0]); - } + WriteOut(UnmountHelper(umount[0]), toupper(umount[0])); return; } @@ -1150,26 +1161,7 @@ public: std::string umount; /* Check for unmounting */ if (cmd->FindString("-u",umount,false)) { - umount[0] = toupper(umount[0]); - int i_drive = umount[0]-'A'; - if (i_drive < DOS_DRIVES && i_drive >= 0 && Drives[i_drive]) { - switch (DriveManager::UnmountDrive(i_drive)) { - case 0: - Drives[i_drive] = 0; - if (i_drive == DOS_GetDefaultDrive()) - DOS_SetDrive(toupper('Z') - 'A'); - WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCESS"),umount[0]); - break; - case 1: - WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NO_VIRTUAL")); - break; - case 2: - WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS")); - break; - } - } else { - WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED"),umount[0]); - } + WriteOut(UnmountHelper(umount[0]), toupper(umount[0])); return; } From dc6a76d3541129b73ffbf19cd892cafe52e80c3e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 19 Apr 2019 12:16:14 +0000 Subject: [PATCH 4096/4131] Store whether generated code is 16 or 32 bit, so this information can be used when checking for self modifying code. Some code is identical except for being 32 or 16 bit. Fixes some hard to reproduce problems (with small codeblocks). Thanks jmarsh! Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4206 --- include/paging.h | 4 +++- src/cpu/core_dyn_x86.cpp | 2 +- src/cpu/core_dyn_x86/cache.h | 2 +- src/cpu/core_dyn_x86/decoder.h | 11 +++++++++-- src/cpu/core_dynrec.cpp | 12 +++++------- src/cpu/core_dynrec/cache.h | 2 +- src/cpu/core_dynrec/decoder_basic.h | 15 ++++++++++++--- 7 files changed, 32 insertions(+), 16 deletions(-) diff --git a/include/paging.h b/include/paging.h index 7126e26b..4fc68214 100644 --- a/include/paging.h +++ b/include/paging.h @@ -48,9 +48,11 @@ class PageDirectory; #define PFLAG_READABLE 0x1 #define PFLAG_WRITEABLE 0x2 #define PFLAG_HASROM 0x4 -#define PFLAG_HASCODE 0x8 //Page contains dynamic code +#define PFLAG_HASCODE32 0x8 //Page contains 32-bit 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 PFLAG_HASCODE16 0x40 //Page contains 16-bit dynamic code +#define PFLAG_HASCODE (PFLAG_HASCODE32|PFLAG_HASCODE16) #define LINK_START ((1024+64)/4) //Start right after the HMA diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 0d354291..17e84221 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -362,7 +362,7 @@ run_block: { Bitu temp_ip=SegPhys(cs)+reg_eip; CodePageHandler * temp_handler=(CodePageHandler *)get_tlb_readhandler(temp_ip); - if (temp_handler->flags & PFLAG_HASCODE) { + if (temp_handler->flags & (cpu.code.big ? PFLAG_HASCODE32:PFLAG_HASCODE16)) { block=temp_handler->FindCacheBlock(temp_ip & 4095); if (!block) goto restart_core; cache.block.running->LinkTo(ret==BR_Link2,block); diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 8a42d0d5..08a3526b 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -73,7 +73,7 @@ public: void SetupAt(Bitu _phys_page,PageHandler * _old_pagehandler) { phys_page=_phys_page; old_pagehandler=_old_pagehandler; - flags=old_pagehandler->flags|PFLAG_HASCODE; + flags=old_pagehandler->flags|(cpu.code.big ? PFLAG_HASCODE32:PFLAG_HASCODE16); flags&=~PFLAG_WRITEABLE; active_blocks=0; active_count=16; diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 7b0f6411..33186f6a 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -53,19 +53,26 @@ static struct DynDecode { static bool MakeCodePage(Bitu lin_addr,CodePageHandler * &cph) { Bit8u rdval; + const Bitu cflag = cpu.code.big ? PFLAG_HASCODE32:PFLAG_HASCODE16; //Ensure page contains memory: if (GCC_UNLIKELY(mem_readb_checked(lin_addr,&rdval))) return true; PageHandler * handler=get_tlb_readhandler(lin_addr); if (handler->flags & PFLAG_HASCODE) { cph=( CodePageHandler *)handler; - return false; + if (handler->flags & cflag) return false; + cph->ClearRelease(); + cph=0; + handler=get_tlb_readhandler(lin_addr); } if (handler->flags & PFLAG_NOCODE) { if (PAGING_ForcePageInit(lin_addr)) { handler=get_tlb_readhandler(lin_addr); if (handler->flags & PFLAG_HASCODE) { cph=( CodePageHandler *)handler; - return false; + if (handler->flags & cflag) return false; + cph->ClearRelease(); + cph=0; + handler=get_tlb_readhandler(lin_addr); } } if (handler->flags & PFLAG_NOCODE) { diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index 2c80bb7e..9e232916 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -159,16 +159,14 @@ CacheBlockDynRec * LinkBlocks(BlockReturn ret) { // 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) { + if (temp_handler->flags & (cpu.code.big ? PFLAG_HASCODE32:PFLAG_HASCODE16)) { // 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; + if (block) { // found it, link the current block to + cache.block.running->LinkTo(ret==BR_Link2,block); + } } - return NULL; + return block; } /* diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index 61ac83b4..9ae81eb3 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -96,7 +96,7 @@ public: old_pagehandler=_old_pagehandler; // adjust flags - flags=old_pagehandler->flags|PFLAG_HASCODE; + flags=old_pagehandler->flags|(cpu.code.big ? PFLAG_HASCODE32:PFLAG_HASCODE16); flags&=~PFLAG_WRITEABLE; active_blocks=0; diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index b91c2665..e466e96b 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -130,21 +130,30 @@ static struct DynDecode { static bool MakeCodePage(Bitu lin_addr,CodePageHandlerDynRec * &cph) { Bit8u rdval; + const Bitu cflag = cpu.code.big ? PFLAG_HASCODE32:PFLAG_HASCODE16; //Ensure page contains memory: if (GCC_UNLIKELY(mem_readb_checked(lin_addr,&rdval))) return true; PageHandler * handler=get_tlb_readhandler(lin_addr); if (handler->flags & PFLAG_HASCODE) { - // this is a codepage handler, and the one that we're looking for + // this is a codepage handler, make sure it matches current code size cph=(CodePageHandlerDynRec *)handler; - return false; + if (handler->flags & cflag) return false; + // wrong code size/stale dynamic code, drop it + cph->ClearRelease(); + cph=0; + // handler was changed, refresh + handler=get_tlb_readhandler(lin_addr); } if (handler->flags & PFLAG_NOCODE) { if (PAGING_ForcePageInit(lin_addr)) { handler=get_tlb_readhandler(lin_addr); if (handler->flags & PFLAG_HASCODE) { cph=(CodePageHandlerDynRec *)handler; - return false; + if (handler->flags & cflag) return false; + cph->ClearRelease(); + cph=0; + handler=get_tlb_readhandler(lin_addr); } } if (handler->flags & PFLAG_NOCODE) { From ea4dd721b5c0c47401c936f25eb761a58fc276bd Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 19 Apr 2019 17:05:47 +0000 Subject: [PATCH 4097/4131] use decoded modrm instead of raw value. so we don't need to store it. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4207 --- src/cpu/core_dynrec/dyn_fpu.h | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/cpu/core_dynrec/dyn_fpu.h b/src/cpu/core_dynrec/dyn_fpu.h index a32ad1bd..739b4bb9 100644 --- a/src/cpu/core_dynrec/dyn_fpu.h +++ b/src/cpu/core_dynrec/dyn_fpu.h @@ -68,7 +68,8 @@ static INLINE void dyn_fpu_top_swapped() { } static void dyn_eatree() { - Bitu group=(decode.modrm.val >> 3) & 7; +// Bitu group = (decode.modrm.val >> 3) & 7; + Bitu group = decode.modrm.reg&7; //It is already that, but compilers. switch (group){ case 0x00: // FADD ST,STi gen_call_function_R((void*)&FPU_FADD_EA,FC_OP1); @@ -102,7 +103,8 @@ static void dyn_eatree() { static void dyn_fpu_esc0(){ dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { +// if (decode.modrm.val >= 0xc0) { + if (decode.modrm.mod == 3) { dyn_fpu_top(); switch (decode.modrm.reg){ case 0x00: //FADD ST,STi @@ -144,7 +146,8 @@ static void dyn_fpu_esc0(){ static void dyn_fpu_esc1(){ dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { +// if (decode.modrm.val >= 0xc0) { + if (decode.modrm.mod == 3) { switch (decode.modrm.reg){ case 0x00: /* FLD STi */ gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true); @@ -331,7 +334,8 @@ static void dyn_fpu_esc1(){ static void dyn_fpu_esc2(){ dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { +// if (decode.modrm.val >= 0xc0) { + if (decode.modrm.mod == 3) { switch(decode.modrm.reg){ case 0x05: switch(decode.modrm.rm){ @@ -363,7 +367,8 @@ static void dyn_fpu_esc2(){ static void dyn_fpu_esc3(){ dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { +// if (decode.modrm.val >= 0xc0) { + if (decode.modrm.mod == 3) { switch (decode.modrm.reg) { case 0x04: switch (decode.modrm.rm) { @@ -427,7 +432,8 @@ static void dyn_fpu_esc3(){ static void dyn_fpu_esc4(){ dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { +// if (decode.modrm.val >= 0xc0) { + if (decode.modrm.mod == 3) { switch(decode.modrm.reg){ case 0x00: /* FADD STi,ST*/ dyn_fpu_top_swapped(); @@ -475,7 +481,8 @@ static void dyn_fpu_esc4(){ static void dyn_fpu_esc5(){ dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { +// if (decode.modrm.val >= 0xc0) { + if (decode.modrm.mod == 3) { dyn_fpu_top(); switch(decode.modrm.reg){ case 0x00: /* FFREE STi */ @@ -545,7 +552,8 @@ static void dyn_fpu_esc5(){ static void dyn_fpu_esc6(){ dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { +// if (decode.modrm.val >= 0xc0) { + if (decode.modrm.mod == 3) { switch(decode.modrm.reg){ case 0x00: /*FADDP STi,ST*/ dyn_fpu_top_swapped(); @@ -601,7 +609,8 @@ static void dyn_fpu_esc6(){ static void dyn_fpu_esc7(){ dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { +// if (decode.modrm.val >= 0xc0) { + if (decode.modrm.mod == 3) { switch (decode.modrm.reg){ case 0x00: /* FFREEP STi */ dyn_fpu_top(); From 5c8e9264d1696d515434f290fd15204f9aaf9fb3 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 19 Apr 2019 17:07:26 +0000 Subject: [PATCH 4098/4131] stop storing raw modrm value, as it isn't used any more. Should save an instruction on each get_modrm call. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4208 --- src/cpu/core_dynrec/decoder_basic.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index e466e96b..c8e2a8ef 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -120,7 +120,7 @@ static struct DynDecode { // modrm state of the current instruction (if used) struct { - Bitu val; +// Bitu val; Bitu mod; Bitu rm; Bitu reg; @@ -381,10 +381,10 @@ static bool decode_fetchd_imm(Bitu & val) { // modrm decoding helper static void INLINE dyn_get_modrm(void) { - decode.modrm.val=decode_fetchb(); - decode.modrm.mod=(decode.modrm.val >> 6) & 3; - decode.modrm.reg=(decode.modrm.val >> 3) & 7; - decode.modrm.rm=(decode.modrm.val & 7); + Bitu val=decode_fetchb(); + decode.modrm.mod=(val >> 6) & 3; + decode.modrm.reg=(val >> 3) & 7; + decode.modrm.rm=(val & 7); } From 6b0f8d6833e611b7816975e10e0d26e57596bbfc Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 19 Apr 2019 19:28:55 +0000 Subject: [PATCH 4099/4131] Strip leading = from value. Can happen if you execute "irq =5". Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4209 --- src/misc/programs.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index 12ffcb86..df65122c 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -719,9 +719,14 @@ void CONFIG::Run(void) { // Input has been parsed (pvar[0]=section, [1]=property, [2]=value) // now execute Section* tsec = control->GetSection(pvars[0]); - std::string value; - value += pvars[2]; + std::string value(pvars[2]); + //Due to parsing there can be a = at the start of value. + while (value.size() && (value.at(0) ==' ' ||value.at(0) =='=') ) value.erase(0,1); for(Bitu i = 3; i < pvars.size(); i++) value += (std::string(" ") + pvars[i]); + if (value.empty() ) { + WriteOut(MSG_Get("PROGRAM_CONFIG_SET_SYNTAX")); + return; + } std::string inputline = pvars[1] + "=" + value; tsec->ExecuteDestroy(false); From 8a156f17d8c4064c99d183c6ab515e115ed9e40b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 20 Apr 2019 11:49:59 +0000 Subject: [PATCH 4100/4131] fix limit check Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4210 --- src/misc/programs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index df65122c..dbcbabc4 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -78,7 +78,7 @@ static Bitu PROGRAMS_Handler(void) { HostPt writer=(HostPt)&index; for (;size>0;size--) *writer++=mem_readb(reader++); Program * new_program; - if (index > internal_progs.size()) E_Exit("something is messing with the memory"); + if (index >= internal_progs.size()) E_Exit("something is messing with the memory"); PROGRAMS_Main * handler = internal_progs[index]; (*handler)(&new_program); new_program->Run(); From eb26b9a58e8213a2d30398e7ea2e0a1de58bab6d Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 20 Apr 2019 13:48:55 +0000 Subject: [PATCH 4101/4131] Change first_shell to be DOS_Shell instead of Program. Makes future manipulations easier. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4211 --- include/shell.h | 5 +++-- src/dos/dos_programs.cpp | 12 ++++++------ src/gui/sdl_gui.cpp | 6 ++---- src/shell/shell.cpp | 9 +++++++-- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/include/shell.h b/include/shell.h index 7835e4b3..fc472856 100644 --- a/include/shell.h +++ b/include/shell.h @@ -35,11 +35,12 @@ #define CMD_MAXCMDS 20 #define CMD_OLDSIZE 4096 extern Bitu call_shellstop; +class DOS_Shell; + /* first_shell is used to add and delete stuff from the shell env * by "external" programs. (config) */ -extern Program * first_shell; +extern DOS_Shell * first_shell; -class DOS_Shell; class BatchFile { public: diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 3b202c26..93b8a83c 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -165,12 +165,12 @@ public: /* remap drives */ Drives[i_newz] = Drives[25]; Drives[25] = 0; - DOS_Shell *fs = static_cast(first_shell); //dynamic ? + if (!first_shell) return; //Should not be possible /* Update environment */ std::string line = ""; char ppp[2] = {newz[0],0}; std::string tempenv = ppp; tempenv += ":\\"; - if (fs->GetEnvStr("PATH",line)){ + if (first_shell->GetEnvStr("PATH",line)){ std::string::size_type idx = line.find('='); std::string value = line.substr(idx +1 , std::string::npos); while ( (idx = value.find("Z:\\")) != std::string::npos || @@ -179,13 +179,13 @@ public: line = value; } if (!line.size()) line = tempenv; - fs->SetEnv("PATH",line.c_str()); + first_shell->SetEnv("PATH",line.c_str()); tempenv += "COMMAND.COM"; - fs->SetEnv("COMSPEC",tempenv.c_str()); + first_shell->SetEnv("COMSPEC",tempenv.c_str()); /* Update batch file if running from Z: (very likely: autoexec) */ - if(fs->bf) { - std::string &name = fs->bf->filename; + if(first_shell->bf) { + std::string &name = first_shell->bf->filename; if(name.length() >2 && name[0] == 'Z' && name[1] == ':') name[0] = newz[0]; } /* Change the active drive */ diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index 3318af20..9640b065 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -38,7 +38,6 @@ #include extern Bit8u int10_font_14[256 * 14]; -extern Program * first_shell; extern bool MSG_Write(const char *); extern void GFX_SetTitle(Bit32s cycles, Bits frameskip, bool paused); @@ -454,10 +453,9 @@ public: if (arg == "OK") section->data = *(std::string*)content->getText(); if (arg == "OK" || arg == "Cancel") close(); else if (arg == "Append Shell Commands") { - DOS_Shell *s = static_cast(first_shell); - std::list::reverse_iterator i = s->l_history.rbegin(); + std::list::reverse_iterator i = first_shell->l_history.rbegin(); std::string lines = *(std::string*)content->getText(); - while (i != s->l_history.rend()) { + while (i != first_shell->l_history.rend()) { lines += "\n"; lines += *i; ++i; diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 51141cb9..aff8045e 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -31,7 +31,7 @@ Bitu call_shellstop; /* Larger scope so shell_del autoexec can use it to * remove things from the environment */ -Program * first_shell = 0; +DOS_Shell * first_shell = 0; static Bitu shellstop_handler(void) { return CBRET_STOP; @@ -40,6 +40,11 @@ static Bitu shellstop_handler(void) { static void SHELL_ProgramStart(Program * * make) { *make = new DOS_Shell; } +//Repeat it with the correct type, could do it in the function below, but this way it should be +//clear that if the above function is changed, this function might need a change as well. +static void SHELL_ProgramStart_First_shell(DOS_Shell * * make) { + *make = new DOS_Shell; +} #define AUTOEXEC_SIZE 4096 static char autoexec_data[AUTOEXEC_SIZE] = { 0 }; @@ -746,7 +751,7 @@ void SHELL_Init() { dos.psp(psp_seg); - SHELL_ProgramStart(&first_shell); + SHELL_ProgramStart_First_shell(&first_shell); first_shell->Run(); delete first_shell; first_shell = 0;//Make clear that it shouldn't be used anymore From bec0e798901bd86168d39a8f62c32a41cbcc3a5e Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 20 Apr 2019 13:55:35 +0000 Subject: [PATCH 4102/4131] Don't remove bytes from autoexec.bat when changing settings from autoexec.bat, but replace them instead. This way the location stays valid. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4212 --- src/shell/shell.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index aff8045e..88691abb 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -125,21 +125,29 @@ AutoexecObject::~AutoexecObject(){ // Remove the line from the autoexecbuffer and update environment for(auto_it it = autoexec_strings.begin(); it != autoexec_strings.end(); ) { - if((*it) == buf) { - it = autoexec_strings.erase(it); + if ((*it) == buf) { std::string::size_type n = buf.size(); char* buf2 = new char[n + 1]; safe_strncpy(buf2, buf.c_str(), n + 1); + bool stringset = false; // If it's a environment variable remove it from there as well - if((strncasecmp(buf2,"set ",4) == 0) && (strlen(buf2) > 4)){ + if ((strncasecmp(buf2,"set ",4) == 0) && (strlen(buf2) > 4)){ char* after_set = buf2 + 4;//move to variable that is being set char* test = strpbrk(after_set,"="); - if(!test) continue; + if (!test) continue; *test = 0; + stringset = true; //If the shell is running/exists update the environment - if(first_shell) first_shell->SetEnv(after_set,""); + if (first_shell) first_shell->SetEnv(after_set,""); } delete [] buf2; + if (stringset && first_shell && first_shell->bf && first_shell->bf->filename.find("AUTOEXEC.BAT") != std::string::npos) { + //Replace entry with spaces if it is a set and from autoexec.bat, as else the location counter will be off. + *it = buf.assign(buf.size(),' '); + it++; + } else { + it = autoexec_strings.erase(it); + } } else it++; } this->CreateAutoexec(); From bbea47d5418a0fa531e29320c6760768002bffff Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sat, 20 Apr 2019 22:43:36 +0000 Subject: [PATCH 4103/4131] Let dynamic core recompile interrupt instructions in non-debug builds. Can help software with many INTs, such as compiled BASIC, run faster. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4213 --- src/cpu/core_dyn_x86/decoder.h | 4 +++- src/cpu/core_dynrec/decoder.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 33186f6a..416f10b2 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -2377,7 +2377,9 @@ restart_prefix: case 0xca:dyn_ret_far(decode_fetchw());goto finish_block; case 0xcb:dyn_ret_far(0);goto finish_block; /* Interrupt */ -// case 0xcd:dyn_interrupt(decode_fetchb());goto finish_block; +#if !(C_DEBUG) + case 0xcd:dyn_interrupt(decode_fetchb());goto finish_block; +#endif /* IRET */ case 0xcf:dyn_iret();goto finish_block; diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h index 384185ad..b0bd8dbc 100644 --- a/src/cpu/core_dynrec/decoder.h +++ b/src/cpu/core_dynrec/decoder.h @@ -446,7 +446,9 @@ restart_prefix: case 0xcb:dyn_ret_far(0);goto finish_block; // int/iret +#if !(C_DEBUG) case 0xcd:dyn_interrupt(decode_fetchb());goto finish_block; +#endif case 0xcf:dyn_iret();goto finish_block; // case 0xd4: AAM missing From 911cc38865c4c3d4c20efac4e71de8eb822eb00e Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Sat, 20 Apr 2019 22:50:31 +0000 Subject: [PATCH 4104/4131] Add logic in mouse driver to ignore button events that are out of sequence. Fixes International Rugby Challenge when clicking to lock the mouse. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4214 --- src/ints/mouse.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ints/mouse.cpp b/src/ints/mouse.cpp index c312fb5e..b463a60f 100644 --- a/src/ints/mouse.cpp +++ b/src/ints/mouse.cpp @@ -525,18 +525,21 @@ void Mouse_ButtonPressed(Bit8u button) { switch (button) { #if (MOUSE_BUTTONS >= 1) case 0: + if (mouse.buttons&1) return; mouse.buttons|=1; Mouse_AddEvent(MOUSE_LEFT_PRESSED); break; #endif #if (MOUSE_BUTTONS >= 2) case 1: + if (mouse.buttons&2) return; mouse.buttons|=2; Mouse_AddEvent(MOUSE_RIGHT_PRESSED); break; #endif #if (MOUSE_BUTTONS >= 3) case 2: + if (mouse.buttons&4) return; mouse.buttons|=4; Mouse_AddEvent(MOUSE_MIDDLE_PRESSED); break; @@ -553,18 +556,21 @@ void Mouse_ButtonReleased(Bit8u button) { switch (button) { #if (MOUSE_BUTTONS >= 1) case 0: + if (!(mouse.buttons&1)) return; mouse.buttons&=~1; Mouse_AddEvent(MOUSE_LEFT_RELEASED); break; #endif #if (MOUSE_BUTTONS >= 2) case 1: + if (!(mouse.buttons&2)) return; mouse.buttons&=~2; Mouse_AddEvent(MOUSE_RIGHT_RELEASED); break; #endif #if (MOUSE_BUTTONS >= 3) case 2: + if (!(mouse.buttons&4)) return; mouse.buttons&=~4; Mouse_AddEvent(MOUSE_MIDDLE_RELEASED); break; @@ -698,6 +704,8 @@ static void Mouse_Reset(void) { mouse.mickey_x = 0; mouse.mickey_y = 0; + mouse.buttons = 0; + for (Bit16u but=0; but Date: Sat, 20 Apr 2019 22:59:42 +0000 Subject: [PATCH 4105/4131] Make effect of I/O delay more consistent as cycles run out. Prevents flickering in NBA Jam Tournament Edition at higher cycles, and also improves automatic speed limiting in Quake. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4215 --- src/hardware/iohandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 4954ae98..af1d0109 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -208,14 +208,14 @@ inline void IO_USEC_write_delay_old() { inline void IO_USEC_read_delay() { Bits delaycyc = CPU_CycleMax/IODELAY_READ_MICROSk; - if(GCC_UNLIKELY(CPU_Cycles < 3*delaycyc)) delaycyc = 0; //Else port acces will set cycles to 0. which might trigger problem with games which read 16 bit values + if(GCC_UNLIKELY(delaycyc > CPU_Cycles)) delaycyc = CPU_Cycles; CPU_Cycles -= delaycyc; CPU_IODelayRemoved += delaycyc; } inline void IO_USEC_write_delay() { Bits delaycyc = CPU_CycleMax/IODELAY_WRITE_MICROSk; - if(GCC_UNLIKELY(CPU_Cycles < 3*delaycyc)) delaycyc=0; + if(GCC_UNLIKELY(delaycyc > CPU_Cycles)) delaycyc = CPU_Cycles; CPU_Cycles -= delaycyc; CPU_IODelayRemoved += delaycyc; } From f8dd3db095dfe3aabe854052cef5d593a902b660 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 22 Apr 2019 14:21:53 +0000 Subject: [PATCH 4106/4131] Add functionality to add overlay directories to drive_cache. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4216 --- include/dos_system.h | 7 ++-- src/dos/drive_cache.cpp | 73 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 75 insertions(+), 5 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 631c5cbf..1c3289b3 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -162,6 +162,8 @@ public: void CacheOut (const char* path, bool ignoreLastDir = false); void AddEntry (const char* path, bool checkExist = false); + void AddEntryDirOverlay (const char* path, bool checkExist = false); + void DeleteEntry (const char* path, bool ignoreLastDir = false); void EmptyCache (void); @@ -172,7 +174,7 @@ public: public: CFileInfo(void) { orgname[0] = shortname[0] = 0; - isDir = false; + isOverlayDir = isDir = false; id = MAX_OPENDIRS; nextEntry = shortNr = 0; } @@ -183,6 +185,7 @@ public: }; char orgname [CROSS_LEN]; char shortname [DOS_NAMELENGTH_ASCII]; + bool isOverlayDir; bool isDir; Bit16u id; Bitu nextEntry; @@ -206,7 +209,7 @@ private: 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 CreateEntry (CFileInfo* dir, const char* name, bool is_directory); void CopyEntry (CFileInfo* dir, CFileInfo* from); Bit16u GetFreeID (CFileInfo* dir); void Clear (void); diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index d3c50ce5..e0500d30 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -187,6 +187,7 @@ char* DOS_Drive_Cache::GetExpandName(const char* path) { if (*work) { size_t len = strlen(work); #if defined (WIN32) + //What about OS/2 if((work[len-1] == CROSS_FILESPLIT ) && (len >= 2) && (work[len-2] != ':')) { #else if((len > 1) && (work[len-1] == CROSS_FILESPLIT )) { @@ -228,6 +229,72 @@ void DOS_Drive_Cache::AddEntry(const char* path, bool checkExists) { // LOG_DEBUG("DIR: Error: Failed to add %s",path); } } +void DOS_Drive_Cache::AddEntryDirOverlay(const char* path, bool checkExists) { + // Get Last part... + char file [CROSS_LEN]; + char expand [CROSS_LEN]; + char dironly[CROSS_LEN + 1]; + + //When adding a directory, the directory we want to operate inside in is the above it. (which can go wrong if the directory already exists.) + strcpy(dironly,path); + char* post = strrchr(dironly,CROSS_FILESPLIT); + + if (post) { +#if defined (WIN32) + //OS2 ? + if (post > dironly && *(post - 1) == ':' && (post - dironly) == 2) + post++; //move away from X: as need to end up with x:\ +#else + //Lets hope this is not really used.. (root folder specified as overlay) + if (post == dironly) + post++; //move away from / +#endif + *post = 0; //TODO take care of AddEntryDIR D:\\piet) (so mount d d:\ as base) + *(post + 1) = 0; //As FindDirInfo is skipping over the base directory + } + CFileInfo* dir = FindDirInfo(dironly,expand); + const char* pos = strrchr(path,CROSS_FILESPLIT); + + if (pos) { + strcpy(file,pos + 1); + // Check if directory already exists, then don't add new entry... + if (checkExists) { + Bits index = GetLongName(dir,file); + if (index >= 0) { + //directory already exists, but most likely empty. + dir = dir->fileList[index]; + if (dir->isOverlayDir && dir->fileList.empty()) { + //maybe care about searches ? but this function should only run on cache inits/refreshes. + //add dot entries + CreateEntry(dir,".",true); + CreateEntry(dir,"..",true); + } + return; + } + } + + CreateEntry(dir,file,true); + + + Bits index = GetLongName(dir,file); + if (index>=0) { + Bit32u i; + // Check if there are any open search dir that are affected by this... + if (dir) for (i=0; inextEntry)) + dirSearch[i]->nextEntry++; + } + + dir = dir->fileList[index]; + dir->isOverlayDir = true; + CreateEntry(dir,".",true); + CreateEntry(dir,"..",true); + } + // LOG_DEBUG("DIR: Added Entry %s",path); + } else { + // LOG_DEBUG("DIR: Error: Failed to add %s",path); + } +} void DOS_Drive_Cache::DeleteEntry(const char* path, bool ignoreLastDir) { CacheOut(path,ignoreLastDir); @@ -278,7 +345,7 @@ void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) { } bool DOS_Drive_Cache::IsCachedIn(CFileInfo* curDir) { - return (curDir->fileList.size()>0); + return (curDir->isOverlayDir || curDir->fileList.size()>0); } @@ -676,9 +743,9 @@ bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, const char* expand, Bit16u& id) { if (dirSearch[id]) { // open dir dir_information* dirp = open_directory(expandcopy); - if (dirp) { + if (dirp || dir->isOverlayDir) { // Reset it.. - close_directory(dirp); + if (dirp) close_directory(dirp); strcpy(dirPath,expandcopy); return true; } From 1d01c8d1514a8fc6fa04714fbed6511ec8a2ca11 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 22 Apr 2019 14:57:24 +0000 Subject: [PATCH 4107/4131] Add experimental code to have overlay only directories. Add ability to remove directories and create them while in overlay mode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4217 --- src/dos/drive_overlay.cpp | 224 +++++++++++++++++++++++++++++++------- src/dos/drives.h | 20 ++-- 2 files changed, 196 insertions(+), 48 deletions(-) diff --git a/src/dos/drive_overlay.cpp b/src/dos/drive_overlay.cpp index 46f9ee93..fea5cc92 100644 --- a/src/dos/drive_overlay.cpp +++ b/src/dos/drive_overlay.cpp @@ -11,9 +11,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "dosbox.h" @@ -33,6 +33,7 @@ #include #include +#define OVERLAY_DIR 1 bool logoverlay = false; using namespace std; @@ -46,13 +47,16 @@ using namespace std; /* * design principles/limitations/requirements: - * 1) All directories that can be used for saving, must exist already in the base before mounting. (they will be created by DOSBox if missing in the overlay) - * 2) All filenames inside the overlay directories are UPPERCASE and conform to the 8.3 standard except for the special DBOVERLAY files. - * 3) To keep point 1 valid at all times, support for creating/renaming/removing directories has been disabled. + * 1) All filenames inside the overlay directories are UPPERCASE and conform to the 8.3 standard except for the special DBOVERLAY files. + * 2) Renaming directories is currently not supported. * - * Points 1 and 3 are still being worked on, so these limitations can be removed. + * Point 2 is still being worked on. */ +/* New rename for base directories: + * Alter shortname in the drive_cache: take care of order and long names. + * update stored deleted files list in overlay. + */ //TODO recheck directories under linux with the filename_cache (as one adds the dos name (and runs cross_filename on the other)) @@ -74,49 +78,117 @@ using namespace std; bool Overlay_Drive::RemoveDir(char * dir) { //DOS_RemoveDir checks if directory exists. +#if OVERLAY_DIR + if (logoverlay) LOG_MSG("Overlay: trying to remove directory: %s",dir); +#else E_Exit("Overlay: trying to remove directory: %s",dir); - /* Overlay: Check if folder is empty (findfirst/next ?), if so, then it is not too tricky. */ - char newdir[CROSS_LEN]; - strcpy(newdir,basedir); - strcat(newdir,dir); - CROSS_FILENAME(newdir); - int temp=rmdir(dirCache.GetExpandName(newdir)); - if (temp==0) dirCache.DeleteEntry(newdir,true); - return (temp==0); +#endif + /* Overlay: Check if folder is empty (findfirst/next, skipping . and .. and breaking on first file found ?), if so, then it is not too tricky. */ + if (is_dir_only_in_overlay(dir)) { + //The simple case + char odir[CROSS_LEN]; + strcpy(odir,overlaydir); + strcat(odir,dir); + CROSS_FILENAME(odir); + int temp=rmdir(odir); + if (temp==0) { + remove_DOSdir_from_cache(dir); + char newdir[CROSS_LEN]; + strcpy(newdir,basedir); + strcat(newdir,dir); + CROSS_FILENAME(newdir); + dirCache.DeleteEntry(newdir,true); + update_cache(false); + } + return (temp==0); + } else { + Bit16u olderror = dos.errorcode; //FindFirst/Next always set an errorcode, while RemoveDir itself shouldn't touch it if successful + DOS_DTA dta(dos.tables.tempdta); + dta.SetupSearch(0,(0xff & ~DOS_ATTR_VOLUME),"*.*"); //Fake drive as we don't use it. + bool ret = this->FindFirst(dir,dta,false);// DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME); + if (!ret) { + //Path not found. Should not be possible due to removedir doing a testdir, but lets be correct + DOS_SetError(DOSERR_PATH_NOT_FOUND); + return false; + } + bool empty = true; + do { + char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr; + dta.GetResult(name,size,date,time,attr); + if (logoverlay) LOG_MSG("RemoveDir found %s",name); + if (empty && strcmp(".",name ) && strcmp("..",name)) + empty = false; //Neither . or .. so directory not empty. + } while ( (ret=this->FindNext(dta)) ); + //Always exhaust list, so drive_cache entry gets invalidated/reused. + //FindNext is done, restore error code to old value. DOS_RemoveDir will set the right one if needed. + dos.errorcode = olderror; + + if (!empty) return false; + if (logoverlay) LOG_MSG("directory empty! Hide it."); + //Directory is empty, mark it as deleted and create DBOVERLAY file. + //Ensure that overlap folder can not be created. + add_deleted_path(dir,true); + return true; + } } bool Overlay_Drive::MakeDir(char * dir) { //DOS_MakeDir tries first, before checking if the directory already exists, so doing it here as well, so that case is handled. if (TestDir(dir)) return false; + if (overlap_folder == dir) return false; //TODO Test +#if OVERLAY_DIR + if (logoverlay) LOG_MSG("Overlay trying to make directory: %s",dir); +#else E_Exit("Overlay trying to make directory: %s",dir); +#endif /* Overlay: Create in Overlay only and add it to drive_cache + some entries else the drive_cache will try to access it. Needs an AddEntry for directories. */ + if (is_deleted_path(dir) && localDrive::TestDir(dir)) { + //Was deleted before and exists (last one is safety check) + remove_deleted_path(dir,true); + return true; + } char newdir[CROSS_LEN]; - strcpy(newdir,basedir); + strcpy(newdir,overlaydir); strcat(newdir,dir); CROSS_FILENAME(newdir); #if defined (WIN32) /* MS Visual C++ */ - int temp=mkdir(dirCache.GetExpandName(newdir)); + int temp=mkdir(newdir); #else - int temp=mkdir(dirCache.GetExpandName(newdir),0700); + int temp=mkdir(newdir,0700); #endif - if (temp==0) dirCache.CacheOut(newdir,true); + if (temp==0) { + char fakename[CROSS_LEN]; + strcpy(fakename,basedir); + strcat(fakename,dir); + CROSS_FILENAME(fakename); + dirCache.AddEntryDirOverlay(fakename,true); + add_DOSdir_to_cache(dir); + } return (temp==0);// || ((temp!=0) && (errno==EEXIST)); } bool Overlay_Drive::TestDir(char * dir) { - //Check if the directory is marked as deleted or one of its leading directories is. + //First check if directory exist exclusively in the overlay. + //Currently using the update_cache cache, alternatively access the directory itself. //Directories are stored without a trailing backslash char tempdir[CROSS_LEN]; strcpy(tempdir,dir); size_t templen = strlen(dir); if (templen && tempdir[templen-1] == '\\') tempdir[templen-1] = 0; + +#if OVERLAY_DIR + if (is_dir_only_in_overlay(tempdir)) return true; +#endif + + //Next Check if the directory is marked as deleted or one of its leading directories is. + //(it still might exists in the localDrive) + if (is_deleted_path(tempdir)) return false; - // Rely on the localDrive directories. - // Directory is good according to the overlay, pass on to LocalDrive + // Not exclusive to overlay nor marked as deleted. Pass on to LocalDrive return localDrive::TestDir(dir); } @@ -317,13 +389,12 @@ bool Overlay_Drive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { case OPEN_READ: type = "rb" ; break; case OPEN_WRITE: type = "rb+"; break; case OPEN_READWRITE: type = "rb+"; break; -// case OPEN_READ_NO_MOD: type = "rb" ; break; //No modification of dates. LORD4.07 uses this + case OPEN_READ_NO_MOD: type = "rb" ; break; //No modification of dates. LORD4.07 uses this default: DOS_SetError(DOSERR_ACCESS_CODE_INVALID); return false; } -#if 0 //Flush the buffer of handles for the same file. (Betrayal in Antara) Bit8u i,drive=DOS_DRIVES; localFile *lfp; @@ -339,7 +410,6 @@ bool Overlay_Drive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { if (lfp) lfp->Flush(); } } -#endif //Todo check name first against local tree @@ -474,14 +544,18 @@ void Overlay_Drive::update_cache(bool read_directory_contents) { if (read_directory_contents) { //Clear all lists DOSnames_cache.clear(); + DOSdirs_cache.clear(); deleted_files_in_base.clear(); deleted_paths_in_base.clear(); //Ensure hiding of the folder that contains the overlay, if it is part of the base folder. - add_deleted_path(overlap_folder.c_str()); + add_deleted_path(overlap_folder.c_str(), false); } - - //What about sequences were a base file gets copied to a working save game and then removed/renamed... + //Needs later to support stored renames and removals of files existing in the localDrive plane. + //and by taking in account if the file names are actually already renamed. + //and taking in account that a file could have gotten an overlay version and then both need to be removed. + // + //Also what about sequences were a base file gets copied to a working save game and then removed/renamed... //copy should be safe as then the link with the original doesn't exist. //however the working safe can be rather complicated after a rename and delete.. @@ -528,6 +602,13 @@ void Overlay_Drive::update_cache(bool read_directory_contents) { if( ll >2 && testi[ll-1] == '.' && testi[ll-2] == CROSS_FILESPLIT) continue; if( ll >3 && testi[ll-1] == '.' && testi[ll-2] == '.' && testi[ll-3] == CROSS_FILESPLIT) continue; +#if OVERLAY_DIR + char tdir[CROSS_LEN]; + strcpy(tdir,(*i).c_str()); + CROSS_DOSFILENAME(tdir); + bool dir_exists_in_base = localDrive::TestDir(tdir); +#endif + char dir[CROSS_LEN]; strcpy(dir,overlaydir); strcat(dir,(*i).c_str()); @@ -537,6 +618,12 @@ void Overlay_Drive::update_cache(bool read_directory_contents) { strcat(dirpush,end); //Linux ? dir_information* dirp = open_directory(dir); if (dirp == NULL) continue; + +#if OVERLAY_DIR + //Good directory, add to DOSdirs_cache if not existing in localDrive. tested earlier to prevent problems with opendir + if (!dir_exists_in_base) add_DOSdir_to_cache(tdir); +#endif + std::string backupi(*i); // Read complete directory char dir_name[CROSS_LEN]; @@ -570,6 +657,16 @@ void Overlay_Drive::update_cache(bool read_directory_contents) { } } +#if OVERLAY_DIR + for (i = DOSdirs_cache.begin(); i !=DOSdirs_cache.end(); i++) { + char fakename[CROSS_LEN]; + strcpy(fakename,basedir); + strcat(fakename,(*i).c_str()); + CROSS_FILENAME(fakename); + dirCache.AddEntryDirOverlay(fakename,true); + } +#endif + for (i = DOSnames_cache.begin(); i != DOSnames_cache.end(); i++) { char fakename[CROSS_LEN]; strcpy(fakename,basedir); @@ -606,6 +703,12 @@ void Overlay_Drive::update_cache(bool read_directory_contents) { while ( (s = name.find('/')) != std::string::npos) name.replace(s,1,"\\"); add_deleted_file(name.c_str(),false); + } else if (special_operation == "RMD") { + name = special_dir + special_file; + //CROSS_DOSFILENAME for strings: + while ( (s = name.find('/')) != std::string::npos) name.replace(s,1,"\\"); + add_deleted_path(name.c_str(),false); + } else { if (logoverlay) LOG_MSG("unsupported operation %s on %s",special_operation.c_str(),(*i).c_str()); } @@ -673,7 +776,7 @@ again: char preldos[CROSS_LEN]; strcpy(preldos,prel); CROSS_DOSFILENAME(preldos); - if (is_deleted_file(preldos)) { + if (is_deleted_file(preldos)) { //dir.. maybe lower or keep it as is TODO if (logoverlay) LOG_MSG("skipping deleted file %s %s %s",preldos,full_name,ovname); goto again; } @@ -686,8 +789,9 @@ again: if(stat_block.st_mode & S_IFDIR) find_attr=DOS_ATTR_DIRECTORY; else find_attr=DOS_ATTR_ARCHIVE; if (~srch_attr & find_attr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM)) goto again; + - /*file is okay, setup everything to be copied in DTA Block */ + /* file is okay, setup everything to be copied in DTA Block */ char find_name[DOS_NAMELENGTH_ASCII];Bit16u find_date,find_time;Bit32u find_size; if(strlen(dir_entcopy)::iterator it = DOSdirs_cache.begin(); it != DOSdirs_cache.end(); it++) { + if (*it == name) return true; + } + return false; +} + bool Overlay_Drive::is_deleted_file(const char* name) { if (!name || !*name) return false; if (deleted_files_in_base.empty()) return false; @@ -866,22 +981,40 @@ bool Overlay_Drive::is_deleted_file(const char* name) { return false; } +void Overlay_Drive::add_DOSdir_to_cache(const char* name) { + if (!name || !*name ) return; //Skip empty file. + LOG_MSG("Adding name to overlay_only_dir_cache %s",name); + if (!is_dir_only_in_overlay(name)) { + DOSdirs_cache.push_back(name); + } +} + +void Overlay_Drive::remove_DOSdir_from_cache(const char* name) { + for(std::vector::iterator it = DOSdirs_cache.begin(); it != DOSdirs_cache.end(); it++) { + if ( *it == name) { + DOSdirs_cache.erase(it); + return; + } + } +} + void Overlay_Drive::remove_deleted_file(const char* name,bool create_on_disk) { for(std::vector::iterator it = deleted_files_in_base.begin(); it != deleted_files_in_base.end(); it++) { if (*it == name) { deleted_files_in_base.erase(it); - if (create_on_disk) remove_deleted_file_from_disk(name); - break; + if (create_on_disk) remove_special_file_from_disk(name, "DEL"); + return; } } } -void Overlay_Drive::add_deleted_path(const char* name) { +void Overlay_Drive::add_deleted_path(const char* name, bool create_on_disk) { if (!name || !*name ) return; //Skip empty file. if (logoverlay) LOG_MSG("add del path %s",name); if (!is_deleted_path(name)) { deleted_paths_in_base.push_back(name); //Add it to deleted files as well, so it gets skipped in FindNext. //Maybe revise that. + if (create_on_disk) add_special_file_to_disk(name,"RMD"); add_deleted_file(name,false); } } @@ -900,10 +1033,12 @@ bool Overlay_Drive::is_deleted_path(const char* name) { return false; } -void Overlay_Drive::remove_deleted_path(const char* name) { +void Overlay_Drive::remove_deleted_path(const char* name, bool create_on_disk) { for(std::vector::iterator it = deleted_paths_in_base.begin(); it != deleted_paths_in_base.end(); it++) { if (*it == name) { deleted_paths_in_base.erase(it); + remove_deleted_file(name,false); //Rethink maybe. + if (create_on_disk) remove_special_file_from_disk(name,"RMD"); break; } } @@ -933,7 +1068,14 @@ bool Overlay_Drive::Rename(char * oldname,char * newname) { //More advanced version. keep track of the file being renamed in order to detect that the file is being renamed back. Bit16u attr=0; if (!GetFileAttr(oldname,&attr)) E_Exit("rename, but source doesn't exist, should not happen %s",oldname); - if (attr&DOS_ATTR_DIRECTORY) E_Exit("renaming directory %s to %s . Not yet supported in Overlay",oldname,newname); + if (attr&DOS_ATTR_DIRECTORY) { + //See if the directory exists only in the overlay, then it should be possible. +#if OVERLAY_DIR + if (localDrive::TestDir(oldname)) E_Exit("Overlay: renaming base directory %s to %s not yet supported", oldname,newname); +#endif + E_Exit("renaming directory %s to %s . Not yet supported in Overlay",oldname,newname); //TODO + } + Bitu a = GetTicks(); //First generate overlay names. char overlaynameold[CROSS_LEN]; diff --git a/src/dos/drives.h b/src/dos/drives.h index e53ef9d4..1bf665cd 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -437,24 +437,30 @@ private: bool optimize_cache_v1; void add_DOSname_to_cache(const char* name); void remove_DOSname_from_cache(const char* name); + void add_DOSdir_to_cache(const char* name); + void remove_DOSdir_from_cache(const char* name); void update_cache(bool read_directory_contents = false); std::vector deleted_files_in_base; //Set is probably better, or some other solution (involving the disk). - std::vector deleted_paths_in_base; //Currently used to hide the overlay folder. + std::vector deleted_paths_in_base; //Currently only used to hide the overlay folder. std::string overlap_folder; - void add_deleted_file(const char* name, bool create_on_disk=true); - void remove_deleted_file(const char* name, bool create_on_disk=true); + void add_deleted_file(const char* name, bool create_on_disk); + void remove_deleted_file(const char* name, bool create_on_disk); bool is_deleted_file(const char* name); - void add_deleted_path(const char* name); - void remove_deleted_path(const char* name); + void add_deleted_path(const char* name, bool create_on_disk); + void remove_deleted_path(const char* name, bool create_on_disk); bool is_deleted_path(const char* name); - void remove_deleted_file_from_disk(const char* dosname); - void add_deleted_file_to_disk(const char* dosname); + bool is_dir_only_in_overlay(const char* name); //cached + + + void remove_special_file_from_disk(const char* dosname, const char* operation); + void add_special_file_to_disk(const char* dosname, const char* operation); std::string create_filename_of_special_operation(const char* dosname, const char* operation); void convert_overlay_to_DOSname_in_base(char* dirname ); //For caching the update_cache routine. std::vector DOSnames_cache; //Also set is probably better. + std::vector DOSdirs_cache; //Can not blindly change its type. it is important that subdirs come after the parent directory. const std::string special_prefix; }; From 701663b574bbfc218d598a85f57b480770c668f4 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Tue, 23 Apr 2019 09:50:56 +0000 Subject: [PATCH 4108/4131] Use a more compatible offset for DOS redirected interrupt vector. Works around a null pointer bug in the notes dropdown list of Jack the Ripper. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4218 --- src/dos/dos_memory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_memory.cpp b/src/dos/dos_memory.cpp index fa78e73e..6037eec0 100644 --- a/src/dos/dos_memory.cpp +++ b/src/dos/dos_memory.cpp @@ -384,7 +384,7 @@ void DOS_SetupMemory(void) { * buggy games, which compare against the interrupt table. (probably a * broken linked list implementation) */ Bit16u ihseg = 0x70; - Bit16u ihofs = 0x08; + Bit16u ihofs = 0xF4; real_writeb(ihseg,ihofs,(Bit8u)0xCF); //An IRET Instruction RealSetVec(0x01,RealMake(ihseg,ihofs)); //BioMenace (offset!=4) RealSetVec(0x02,RealMake(ihseg,ihofs)); //BioMenace (segment<0x8000) From 2aaa951fd4c6a869a9c8b40ab5d2b8da9ed2a186 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 26 Apr 2019 14:06:11 +0000 Subject: [PATCH 4109/4131] Rewrite pop_ev so it can trigger pagefaults again. Fixes win3.11. (jmarsh) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4219 --- src/cpu/core_dynrec/decoder_opcodes.h | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index 09e35631..67eaee2c 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -444,14 +444,23 @@ static void dyn_push_word_imm(Bitu imm) { static void dyn_pop_ev(void) { dyn_get_modrm(); if (decode.modrm.mod<3) { -/* dyn_fill_ea(FC_ADDR); - gen_protect_addr_reg(); - dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); // dummy read to trigger possible page faults */ + // save original ESP + MOV_REG_WORD32_TO_HOST_REG(FC_OP2,DRC_REG_ESP); + gen_protect_reg(FC_OP2); if (decode.big_op) gen_call_function_raw((void*)&dynrec_pop_dword); else gen_call_function_raw((void*)&dynrec_pop_word); dyn_fill_ea(FC_ADDR); -// gen_restore_addr_reg(); - dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); + gen_mov_regs(FC_OP2,FC_RETOP); + gen_mov_regs(FC_OP1,FC_ADDR); + if (decode.big_op) gen_call_function_raw((void *)&mem_writed_checked_drc); + else gen_call_function_raw((void *)&mem_writew_checked_drc); + gen_extend_byte(false,FC_RETOP); // bool -> dword + DRC_PTR_SIZE_IM no_fault = gen_create_branch_on_zero(FC_RETOP, true); + // restore original ESP + gen_restore_reg(FC_OP2); + MOV_REG_WORD32_FROM_HOST_REG(FC_OP2,DRC_REG_ESP); + dyn_check_exception(FC_RETOP); + gen_fill_branch(no_fault); } else { if (decode.big_op) gen_call_function_raw((void*)&dynrec_pop_dword); else gen_call_function_raw((void*)&dynrec_pop_word); From dfce234cfb2e664b2ba0907cf164873c48517cd5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 6 May 2019 08:37:53 +0000 Subject: [PATCH 4110/4131] Fix unitialized access to some isoDrive fields. Pause audio before switching. Use right subunit with multiple CDs on one driveletter. (krcroft, jmarsh and qbix) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4223 --- src/dos/cdrom_image.cpp | 6 +++++- src/dos/dos_mscdex.cpp | 11 +++++++++-- src/dos/drive_iso.cpp | 22 ++++++++++++++++------ src/dos/drive_local.cpp | 5 ++++- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 25a7783a..68d1806d 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -52,6 +52,7 @@ CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) CDROM_Interface_Image::BinaryFile::~BinaryFile() { delete file; + file = NULL; } bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count) @@ -128,12 +129,13 @@ int CDROM_Interface_Image::AudioFile::getLength() // initialize static members int CDROM_Interface_Image::refCount = 0; -CDROM_Interface_Image* CDROM_Interface_Image::images[26]; +CDROM_Interface_Image* CDROM_Interface_Image::images[26] = {}; CDROM_Interface_Image::imagePlayer CDROM_Interface_Image::player = { NULL, NULL, NULL, {0}, 0, 0, 0, false, false, false, {0} }; CDROM_Interface_Image::CDROM_Interface_Image(Bit8u subUnit) + :subUnit(subUnit) { images[subUnit] = this; if (refCount == 0) { @@ -375,6 +377,7 @@ bool CDROM_Interface_Image::LoadIsoFile(char* filename) track.file = new BinaryFile(filename, error); if (error) { delete track.file; + track.file = NULL; return false; } track.number = 1; @@ -544,6 +547,7 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) #endif if (error) { delete track.file; + track.file = NULL; success = false; } } diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 23e60b31..c211bcc6 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -407,9 +407,11 @@ bool CMscdex::HasDrive(Bit16u drive) { } void CMscdex::ReplaceDrive(CDROM_Interface* newCdrom, Bit8u subUnit) { - delete cdrom[subUnit]; + if (cdrom[subUnit] != NULL) { + StopAudio(subUnit); + delete cdrom[subUnit]; + } cdrom[subUnit] = newCdrom; - StopAudio(subUnit); } PhysPt CMscdex::GetDefaultBuffer(void) { @@ -1298,6 +1300,11 @@ void MSCDEX_ReplaceDrive(CDROM_Interface* cdrom, Bit8u subUnit) mscdex->ReplaceDrive(cdrom, subUnit); } +Bit8u MSCDEX_GetSubUnit(char driveLetter) +{ + return mscdex->GetSubUnit(driveLetter-'A'); +} + bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name) { return mscdex->GetVolumeName(subUnit,name); diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 937a8a3a..9b3333d9 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -133,13 +133,22 @@ Bit16u isoFile::GetInformation(void) { return 0x40; // read-only drive } -int MSCDEX_RemoveDrive(char driveLetter); -int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit); -void MSCDEX_ReplaceDrive(CDROM_Interface* cdrom, Bit8u subUnit); -bool MSCDEX_HasDrive(char driveLetter); -bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name); +int MSCDEX_RemoveDrive(char driveLetter); +int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit); +void MSCDEX_ReplaceDrive(CDROM_Interface* cdrom, Bit8u subUnit); +bool MSCDEX_HasDrive(char driveLetter); +bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name); +Bit8u MSCDEX_GetSubUnit(char driveLetter); -isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &error) { +isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &error) + :iso(false), + dataCD(false), + mediaid(0), + fileName{'\0'}, + subUnit(0), + driveLetter('\0'), + discLabel{'\0'} + { nextFreeDirIterator = 0; memset(dirIterators, 0, sizeof(dirIterators)); memset(sectorHashEntries, 0, sizeof(sectorHashEntries)); @@ -174,6 +183,7 @@ isoDrive::~isoDrive() { } int isoDrive::UpdateMscdex(char driveLetter, const char* path, Bit8u& subUnit) { if (MSCDEX_HasDrive(driveLetter)) { + subUnit = MSCDEX_GetSubUnit(driveLetter); CDROM_Interface_Image* oldCdrom = CDROM_Interface_Image::images[subUnit]; CDROM_Interface* cdrom = new CDROM_Interface_Image(subUnit); char pathCopy[CROSS_LEN]; diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index d2ba17d1..da8d6e59 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -559,7 +559,10 @@ bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name); cdromDrive::cdromDrive(const char driveLetter, const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid, int& error) - :localDrive(startdir,_bytes_sector,_sectors_cluster,_total_clusters,_free_clusters,_mediaid) { + :localDrive(startdir,_bytes_sector,_sectors_cluster,_total_clusters,_free_clusters,_mediaid), + subUnit(0), + driveLetter('\0') +{ // Init mscdex error = MSCDEX_AddDrive(driveLetter,startdir,subUnit); strcpy(info, "CDRom "); From b326adff06655ac775e2f4654cd9c02e13d48371 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 6 May 2019 10:23:11 +0000 Subject: [PATCH 4111/4131] Remove c++ 11 isms Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4224 --- src/dos/drive_iso.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 9b3333d9..64e95ef3 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -144,11 +144,11 @@ isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &e :iso(false), dataCD(false), mediaid(0), - fileName{'\0'}, subUnit(0), - driveLetter('\0'), - discLabel{'\0'} + driveLetter('\0') { + this->fileName[0] = '\0'; + this->discLabel[0] = '\0'; nextFreeDirIterator = 0; memset(dirIterators, 0, sizeof(dirIterators)); memset(sectorHashEntries, 0, sizeof(sectorHashEntries)); From e723355b9277204ee97b2684bb17e06fc423858c Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 6 May 2019 10:27:11 +0000 Subject: [PATCH 4112/4131] Silence a warning Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4225 --- src/dos/drive_overlay.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dos/drive_overlay.cpp b/src/dos/drive_overlay.cpp index fea5cc92..2c911b19 100644 --- a/src/dos/drive_overlay.cpp +++ b/src/dos/drive_overlay.cpp @@ -104,7 +104,8 @@ bool Overlay_Drive::RemoveDir(char * dir) { } else { Bit16u olderror = dos.errorcode; //FindFirst/Next always set an errorcode, while RemoveDir itself shouldn't touch it if successful DOS_DTA dta(dos.tables.tempdta); - dta.SetupSearch(0,(0xff & ~DOS_ATTR_VOLUME),"*.*"); //Fake drive as we don't use it. + char stardotstar[4] = {'*', '.', '*', 0}; + dta.SetupSearch(0,(0xff & ~DOS_ATTR_VOLUME),stardotstar); //Fake drive as we don't use it. bool ret = this->FindFirst(dir,dta,false);// DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME); if (!ret) { //Path not found. Should not be possible due to removedir doing a testdir, but lets be correct From fa8b4c5d009c0e540f9953bb7a640a3f98d6bd60 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 20 May 2019 19:10:56 +0000 Subject: [PATCH 4113/4131] Move all stack alignment operations into one place and some optimalisations (thanks jmarsh) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4226 --- src/cpu/core_dynrec/risc_x64.h | 257 +++++++++------------------------ 1 file changed, 72 insertions(+), 185 deletions(-) diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index 036cd2de..f00e56f9 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -83,17 +83,12 @@ typedef Bit8u HostReg; // move a full register from reg_src to reg_dst static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { + if (reg_dst==reg_src) return; cache_addb(0x8b); // mov reg_dst,reg_src cache_addb(0xc0+(reg_dst<<3)+reg_src); } -// move a 64bit constant value into a full register -static void gen_mov_reg_qword(HostReg dest_reg,Bit64u imm) { - cache_addb(0x48); - cache_addb(0xb8+dest_reg); // mov dest_reg,imm - cache_addq(imm); -} - +static void gen_mov_reg_qword(HostReg dest_reg,Bit64u imm); // This function generates an instruction with register addressing and a memory location static INLINE void gen_reg_memaddr(HostReg reg,void* data,Bit8u op,Bit8u prefix=0) { @@ -195,6 +190,17 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { cache_addd(imm); } +// move a 64bit constant value into a full register +static void gen_mov_reg_qword(HostReg dest_reg,Bit64u imm) { + if (imm==(Bit32u)imm) { + gen_mov_dword_to_reg_imm(dest_reg, (Bit32u)imm); + return; + } + cache_addb(0x48); + cache_addb(0xb8+dest_reg); // mov dest_reg,imm + cache_addq(imm); +} + // move 32bit (dword==true) or 16bit (dword==false) of a register into memory static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword,Bit8u prefix=0) { gen_reg_memaddr(src_reg,dest,0x89,(dword?prefix:0x66)); // mov [data],reg @@ -264,6 +270,7 @@ static void gen_add(HostReg reg,void* op) { // add a 32bit constant value to a full register static void gen_add_imm(HostReg reg,Bit32u imm) { + if (!imm) return; cache_addw(0xc081+(reg<<8)); // add reg,imm cache_addd(imm); } @@ -291,11 +298,13 @@ static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { // add an 8bit constant value to a memory value static void gen_add_direct_byte(void* dest,Bit8s imm) { + if (!imm) return; gen_memaddr(0x4,dest,1,imm,0x83); // add [data],imm } // add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { + if (!imm) return; if ((imm<128) && dword) { gen_add_direct_byte(dest,(Bit8s)imm); return; @@ -305,11 +314,13 @@ static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { // subtract an 8bit constant value from a memory value static void gen_sub_direct_byte(void* dest,Bit8s imm) { + if (!imm) return; gen_memaddr(0x2c,dest,1,imm,0x83); } // subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { + if (!imm) return; if ((imm<128) && dword) { gen_sub_direct_byte(dest,(Bit8s)imm); return; @@ -364,89 +375,17 @@ static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { // generate a call to a parameterless function static void INLINE gen_call_function_raw(void * func) { -// cache_addb(0x48); -// cache_addw(0xec83); -#if defined (_WIN64) -// cache_addb(0x28); // allocate windows shadow space - cache_addd(0x28ec8348); -#else -// cache_addb(0x08); // sub rsp,0x08 (align stack to 16 byte boundary) - cache_addd(0x08ec8348); -#endif - -// cache_addb(0x48); -// cache_addb(0xb8); // mov reg,imm64 cache_addw(0xb848); cache_addq((Bit64u)func); cache_addw(0xd0ff); - -// cache_addb(0x48); -// cache_addw(0xc483); -#if defined (_WIN64) -// cache_addb(0x28); // deallocate windows shadow space - cache_addd(0x28c48348); -#else -// cache_addb(0x08); // add rsp,0x08 (reset alignment) - cache_addd(0x08c48348); -#endif } // generate a call to a function with paramcount parameters // note: the parameters are loaded in the architecture specific way // using the gen_load_param_ functions below static Bit64u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { - // align the stack - cache_addb(0x48); - cache_addw(0xc48b); // mov rax,rsp - -// cache_addb(0x48); -// cache_addw(0xec83); // sub rsp,0x08 -// cache_addb(0x08); // 0x08==return address pushed onto stack by call - cache_addd(0x08ec8348); - -// cache_addb(0x48); -// cache_addw(0xe483); // and esp,0xfffffffffffffff0 -// cache_addb(0xf0); - cache_addd(0xf0e48348); - -// cache_addb(0x48); -// cache_addw(0xc483); // add rsp,0x08 -// cache_addb(0x08); - cache_addd(0x08c48348); - - // stack is 16 byte aligned now - - - cache_addb(0x50); // push rax (==old rsp) - -#if defined (_WIN64) -// cache_addb(0x48); -// cache_addw(0xec83); // sub rsp,0x20 -// cache_addb(0x20); // allocate windows shadow space - cache_addd(0x20ec8348); -#endif - - // returned address relates to where the address is stored in gen_call_function_raw - Bit64u proc_addr=(Bit64u)cache.pos-4; - - // Do the actual call to the procedure -// cache_addb(0x48); -// cache_addb(0xb8); // mov reg,imm64 - cache_addw(0xb848); - cache_addq((Bit64u)func); - - cache_addw(0xd0ff); - -#if defined (_WIN64) -// cache_addb(0x48); -// cache_addw(0xc483); // add rsp,0x20 -// cache_addb(0x20); // deallocate windows shadow space - cache_addd(0x20c48348); -#endif - - // restore stack - cache_addb(0x5c); // pop rsp - + Bit64u proc_addr = (Bit64u)cache.pos; + gen_call_function_raw(func); return proc_addr; } @@ -462,13 +401,13 @@ static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)imm); break; #if defined (_WIN64) - case 2: // mov r8,imm32 - cache_addw(0xb849); - cache_addq((Bit32u)imm); + case 2: // mov r8d,imm32 + cache_addw(0xb841); + cache_addd((Bit32u)imm); break; - case 3: // mov r9,imm32 - cache_addw(0xb949); - cache_addq((Bit32u)imm); + case 3: // mov r9d,imm32 + cache_addw(0xb941); + cache_addd((Bit32u)imm); break; #else case 2: // mov rdx,imm32 @@ -561,17 +500,17 @@ static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { gen_mov_word_to_reg(FC_OP2,(void*)mem,true); break; #if defined (_WIN64) - case 2: // mov r8,[mem] - gen_mov_word_to_reg(0,(void*)mem,true,0x4c); // 0x4c, use x64 rX regs + case 2: // mov r8d,[mem] + gen_mov_word_to_reg(0,(void*)mem,true,0x44); // 0x44, use x64 rXd regs break; - case 3: // mov r9,[mem] - gen_mov_word_to_reg(1,(void*)mem,true,0x4c); // 0x4c, use x64 rX regs + case 3: // mov r9d,[mem] + gen_mov_word_to_reg(1,(void*)mem,true,0x44); // 0x44, use x64 rXd regs break; #else - case 2: // mov rdx,[mem] + case 2: // mov edx,[mem] gen_mov_word_to_reg(HOST_EDX,(void*)mem,true); break; - case 3: // mov rcx,[mem] + case 3: // mov ecx,[mem] gen_mov_word_to_reg(HOST_ECX,(void*)mem,true); break; #endif @@ -662,22 +601,19 @@ static void gen_fill_branch_long(Bit64u data) { *(Bit32u*)data=(Bit32u)((Bit64u)cache.pos-data-4); } - static void gen_run_code(void) { - cache_addb(0x53); // push rbx -#if defined (_WIN64) - cache_addw(0x5657); // push rdi; push rsi -#endif - cache_addw(0xd0ff+(FC_OP1<<8)); // call rdi -#if defined (_WIN64) - cache_addw(0x5f5e); // pop rsi; pop rdi -#endif - cache_addb(0x5b); // pop rbx + cache_addw(0x5355); // push rbp,rbx + cache_addb(0x56); // push rsi + cache_addd(0x20EC8348); // sub rsp, 32 + cache_addb(0x48);cache_addw(0x2D8D);cache_addd(2); // lea rbp, [rip+2] + cache_addw(0xE0FF+(FC_OP1<<8)); // jmp FC_OP1 + cache_addd(0x20C48348); // add rsp, 32 + cache_addd(0xC35D5B5E); // pop rsi,rbx,rbp;ret } // return from a function static void gen_return_function(void) { - cache_addb(0xc3); // ret + cache_addw(0xE5FF); // jmp rbp } #ifdef DRC_FLAGS_INVALIDATION @@ -692,126 +628,77 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { case t_ADDb: case t_ADDw: case t_ADDd: -#if defined (_WIN64) - *(Bit32u*)(pos+0)=0xd001c889; // mov eax, ecx; add eax, edx -#else - *(Bit32u*)(pos+0)=0xf001f889; // mov eax,edi; add eax,esi -#endif - *(Bit32u*)(pos+4)=0x90900eeb; // skip + // mov eax,FC_OP1; add eax,FC_OP2 + *(Bit32u*)(pos+0)=0xc001c089+(FC_OP1<<11)+(FC_OP2<<27); + *(Bit32u*)(pos+4)=0x909006eb; // skip *(Bit32u*)(pos+8)=0x90909090; - *(Bit32u*)(pos+12)=0x90909090; - *(Bit32u*)(pos+16)=0x90909090; - break; + return; case t_ORb: case t_ORw: case t_ORd: -#if defined (_WIN64) - *(Bit32u*)(pos+0)=0xd009c889; // mov eax, ecx; or eax, edx -#else - *(Bit32u*)(pos+0)=0xf009f889; // mov eax,edi; or eax,esi -#endif - *(Bit32u*)(pos+4)=0x90900eeb; // skip + // mov eax,FC_OP1; or eax,FC_OP2 + *(Bit32u*)(pos+0)=0xc009c089+(FC_OP1<<11)+(FC_OP2<<27); + *(Bit32u*)(pos+4)=0x909006eb; // skip *(Bit32u*)(pos+8)=0x90909090; - *(Bit32u*)(pos+12)=0x90909090; - *(Bit32u*)(pos+16)=0x90909090; - break; + return; case t_ANDb: case t_ANDw: case t_ANDd: -#if defined (_WIN64) - *(Bit32u*)(pos+0)=0xd021c889; // mov eax, ecx; and eax, edx -#else - *(Bit32u*)(pos+0)=0xf021f889; // mov eax,edi; and eax,esi -#endif - *(Bit32u*)(pos+4)=0x90900eeb; // skip + // mov eax,FC_OP1; and eax,FC_OP2 + *(Bit32u*)(pos+0)=0xc021c089+(FC_OP1<<11)+(FC_OP2<<27); + *(Bit32u*)(pos+4)=0x909006eb; // skip *(Bit32u*)(pos+8)=0x90909090; - *(Bit32u*)(pos+12)=0x90909090; - *(Bit32u*)(pos+16)=0x90909090; - break; + return; case t_SUBb: case t_SUBw: case t_SUBd: -#if defined (_WIN64) - *(Bit32u*)(pos+0)=0xd029c889; // mov eax, ecx; sub eax, edx -#else - *(Bit32u*)(pos+0)=0xf029f889; // mov eax,edi; sub eax,esi -#endif - *(Bit32u*)(pos+4)=0x90900eeb; // skip + // mov eax,FC_OP1; sub eax,FC_OP2 + *(Bit32u*)(pos+0)=0xc029c089+(FC_OP1<<11)+(FC_OP2<<27); + *(Bit32u*)(pos+4)=0x909006eb; // skip *(Bit32u*)(pos+8)=0x90909090; - *(Bit32u*)(pos+12)=0x90909090; - *(Bit32u*)(pos+16)=0x90909090; - break; + return; case t_XORb: case t_XORw: case t_XORd: -#if defined (_WIN64) - *(Bit32u*)(pos+0)=0xd031c889; // mov eax, ecx; xor eax, edx -#else - *(Bit32u*)(pos+0)=0xf031f889; // mov eax,edi; xor eax,esi -#endif - *(Bit32u*)(pos+4)=0x90900eeb; // skip + // mov eax,FC_OP1; xor eax,FC_OP2 + *(Bit32u*)(pos+0)=0xc031c089+(FC_OP1<<11)+(FC_OP2<<27); + *(Bit32u*)(pos+4)=0x909006eb; // skip *(Bit32u*)(pos+8)=0x90909090; - *(Bit32u*)(pos+12)=0x90909090; - *(Bit32u*)(pos+16)=0x90909090; - break; + return; case t_CMPb: case t_CMPw: case t_CMPd: case t_TESTb: case t_TESTw: case t_TESTd: - *(Bit32u*)(pos+0)=0x909012eb; // skip + *(Bit32u*)(pos+0)=0x90900aeb; // skip *(Bit32u*)(pos+4)=0x90909090; *(Bit32u*)(pos+8)=0x90909090; - *(Bit32u*)(pos+12)=0x90909090; - *(Bit32u*)(pos+16)=0x90909090; - break; + return; case t_INCb: case t_INCw: case t_INCd: -#if defined (_WIN64) - *(Bit32u*)(pos+0)=0xc0ffc889; // mov eax, ecx; inc eax -#else - *(Bit32u*)(pos+0)=0xc0fff889; // mov eax,edi; inc eax -#endif - *(Bit32u*)(pos+4)=0x90900eeb; // skip + *(Bit32u*)(pos+0)=0xc0ffc089+(FC_OP1<<11); // mov eax,ecx; inc eax + *(Bit32u*)(pos+4)=0x909006eb; // skip *(Bit32u*)(pos+8)=0x90909090; - *(Bit32u*)(pos+12)=0x90909090; - *(Bit32u*)(pos+16)=0x90909090; - break; + return; case t_DECb: case t_DECw: case t_DECd: -#if defined (_WIN64) - *(Bit32u*)(pos+0)=0xc8ffc889; // mov eax, ecx; dec eax -#else - *(Bit32u*)(pos+0)=0xc8fff889; // mov eax,edi; dec eax -#endif - *(Bit32u*)(pos+4)=0x90900eeb; // skip + *(Bit32u*)(pos+0)=0xc8ffc089+(FC_OP1<<11); // mov eax, FC_OP1; dec eax + *(Bit32u*)(pos+4)=0x909006eb; // skip *(Bit32u*)(pos+8)=0x90909090; - *(Bit32u*)(pos+12)=0x90909090; - *(Bit32u*)(pos+16)=0x90909090; - break; + return; case t_NEGb: case t_NEGw: case t_NEGd: -#if defined (_WIN64) - *(Bit32u*)(pos+0)=0xd8f7c889; // mov eax, ecx; neg eax -#else - *(Bit32u*)(pos+0)=0xd8f7f889; // mov eax,edi; neg eax -#endif - *(Bit32u*)(pos+4)=0x90900eeb; // skip + *(Bit32u*)(pos+0)=0xd8f7c089+(FC_OP1<<11); // mov eax, FC_OP1; neg eax + *(Bit32u*)(pos+4)=0x909006eb; // skip *(Bit32u*)(pos+8)=0x90909090; - *(Bit32u*)(pos+12)=0x90909090; - *(Bit32u*)(pos+16)=0x90909090; - break; - default: - *(Bit64u*)(pos+6)=(Bit64u)fct_ptr; // fill function pointer - break; + return; } -#else - *(Bit64u*)(pos+6)=(Bit64u)fct_ptr; // fill function pointer #endif + *(Bit64u*)(pos+2)=(Bit64u)fct_ptr; // fill function pointer } #endif From 5888c05dd1e6d395fafcc8c4debdabec8f608ea2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 23 May 2019 12:51:10 +0000 Subject: [PATCH 4114/4131] Add some missing va_ends. Reported by jmarsh Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4227 --- src/cpu/core_dyn_x86/risc_x86.h | 1 + src/debug/debug_disasm.cpp | 1 + src/libs/zmbv/zmbv_vfw.cpp | 1 + 3 files changed, 3 insertions(+) diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index f0f06502..ca502d8f 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -769,6 +769,7 @@ static void gen_call_function(void * func,char const* ops,...) { } ops++; } + va_end(params); #if defined (MACOSX) /* align stack */ diff --git a/src/debug/debug_disasm.cpp b/src/debug/debug_disasm.cpp index 51155ed9..9b905f8a 100644 --- a/src/debug/debug_disasm.cpp +++ b/src/debug/debug_disasm.cpp @@ -490,6 +490,7 @@ static void uprintf(char const *s, ...) va_list arg_ptr; va_start (arg_ptr, s); vsprintf(ubufp, s, arg_ptr); + va_end(arg_ptr); while (*ubufp) ubufp++; } diff --git a/src/libs/zmbv/zmbv_vfw.cpp b/src/libs/zmbv/zmbv_vfw.cpp index eedb92d6..dec8dc6f 100644 --- a/src/libs/zmbv/zmbv_vfw.cpp +++ b/src/libs/zmbv/zmbv_vfw.cpp @@ -50,6 +50,7 @@ void Msg(const char fmt[], ...) { va_start(val, fmt); wvsprintf(buf, fmt, val); + va_end(val); const COORD _80x50 = {80,50}; static BOOL startup = (AllocConsole(), SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), _80x50)); From ee236a7e5a07935b773835f256895c7211e242ce Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 26 May 2019 09:07:07 +0000 Subject: [PATCH 4115/4131] Init texture with zeroes. Should fix the red border with pixel_buffer and nvidia cards on Mac OS X and Linux. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4228 --- src/gui/sdlmain.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 7df007fc..24807125 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -728,7 +728,10 @@ dosurface: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texsize, texsize, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, 0); + Bit8u* emptytex = new Bit8u[texsize * texsize * 4]; + memset((void*) emptytex, 0, texsize * texsize * 4); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texsize, texsize, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, (const GLvoid*)emptytex); + delete [] emptytex; glClearColor (0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); From ffdcc16af513555773b19020f7bef3c1a7cf1c46 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 2 Jun 2019 19:40:59 +0000 Subject: [PATCH 4116/4131] Always clear drawing area. Should fix certain linux instalations that use triple buffering Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4229 --- src/gui/sdlmain.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 24807125..b0635487 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -1004,6 +1004,10 @@ void GFX_EndUpdate( const Bit16u *changedLines ) { break; #if C_OPENGL case SCREEN_OPENGL: + // Clear drawing area. Some drivers (on Linux) have more than 2 buffers and the screen might + // be dirty because of other programs. + glClearColor (0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); if (sdl.opengl.pixel_buffer_object) { glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture); From 747190b04ee97ce317674b43497ae9e24c28d010 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 13 Jun 2019 17:53:10 +0000 Subject: [PATCH 4117/4131] Add check for realpath Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4230 --- configure.ac | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure.ac b/configure.ac index fb8d28fb..a084e926 100644 --- a/configure.ac +++ b/configure.ac @@ -540,6 +540,9 @@ AC_CHECK_HEADER([sys/mman.h], [ AC_CHECK_FUNC([mprotect],[AC_DEFINE(C_HAVE_MPROTECT,1)]) ]) +dnl Check for realpath. Used on Linux +AC_CHECK_FUNCS([realpath]) + dnl Setpriority AH_TEMPLATE(C_SET_PRIORITY,[Define to 1 if you have setpriority support]) AC_MSG_CHECKING(for setpriority support) From f74067c2b018b37e14e76ce89bd1f54eb07b0bcb Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 19 Jun 2019 08:11:01 +0000 Subject: [PATCH 4118/4131] Use size_t when dealing with strings and strlen. (Alexandre) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4232 --- src/hardware/serialport/libserial.cpp | 16 ++++++++-------- src/hardware/serialport/libserial.h | 3 ++- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/hardware/serialport/libserial.cpp b/src/hardware/serialport/libserial.cpp index 35eaddc6..3b0a4520 100644 --- a/src/hardware/serialport/libserial.cpp +++ b/src/hardware/serialport/libserial.cpp @@ -41,7 +41,7 @@ bool SERIAL_open(const char* portname, COMPORT* port) { // open the port in NT object space (recommended by Microsoft) // allows the user to open COM10+ and custom port names. - int len = strlen(portname); + size_t len = strlen(portname); if(len > 240) { SetLastError(ERROR_BUFFER_OVERFLOW); free(cp); @@ -125,7 +125,7 @@ void SERIAL_close(COMPORT port) { free(port); } -void SERIAL_getErrorString(char* buffer, int length) { +void SERIAL_getErrorString(char* buffer, size_t length) { int error = GetLastError(); if(length < 50) return; memset(buffer,0,length); @@ -141,7 +141,7 @@ void SERIAL_getErrorString(char* buffer, int length) { const char* err5text = "The specified port is already in use.\n"; const char* err2text = "The specified port does not exist.\n"; - int sysmsg_offset = 0; + size_t sysmsg_offset = 0; if(error == 5) { sysmsg_offset = strlen(err5text); @@ -287,7 +287,7 @@ bool SERIAL_open(const char* portname, COMPORT* port) { cp->breakstatus=false; - int len = strlen(portname); + size_t len = strlen(portname); if(len > 240) { ///////////////////////////////////SetLastError(ERROR_BUFFER_OVERFLOW); return false; @@ -299,7 +299,7 @@ bool SERIAL_open(const char* portname, COMPORT* port) { if (cp->porthandle < 0) goto cleanup_error; result = tcgetattr(cp->porthandle,&cp->backup); - if (result==-1) goto cleanup_error; + if (result == -1) goto cleanup_error; // get port settings termios termInfo; @@ -334,7 +334,7 @@ void SERIAL_close(COMPORT port) { free(port); } -void SERIAL_getErrorString(char* buffer, int length) { +void SERIAL_getErrorString(char* buffer, size_t length) { int error = errno; if(length < 50) return; memset(buffer,0,length); @@ -344,7 +344,7 @@ void SERIAL_getErrorString(char* buffer, int length) { const char* err5text = "The specified port is already in use.\n"; const char* err2text = "The specified port does not exist.\n"; - int sysmsg_offset = 0; + size_t sysmsg_offset = 0; if(error == EBUSY) { sysmsg_offset = strlen(err5text); @@ -548,7 +548,7 @@ cleanup_error: return false; } -void SERIAL_getErrorString(char* buffer, int length) { +void SERIAL_getErrorString(char* buffer, size_t length) { sprintf(buffer, "TODO: error handling is not fun"); } void SERIAL_close(COMPORT port) { diff --git a/src/hardware/serialport/libserial.h b/src/hardware/serialport/libserial.h index 92077772..e3e5a296 100644 --- a/src/hardware/serialport/libserial.h +++ b/src/hardware/serialport/libserial.h @@ -16,12 +16,13 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include typedef struct _COMPORT *COMPORT; bool SERIAL_open(const char* portname, COMPORT* port); void SERIAL_close(COMPORT port); -void SERIAL_getErrorString(char* buffer, int length); +void SERIAL_getErrorString(char* buffer, size_t length); #define SERIAL_1STOP 1 #define SERIAL_2STOP 2 From 46babe56668f699b4ba5f46982ef069875db4b20 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 20 Jun 2019 09:22:17 +0000 Subject: [PATCH 4119/4131] End of environment is a bit shorter. Very old code, lets see what breaks. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4235 --- src/misc/programs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index dbcbabc4..ea33b0c6 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -254,7 +254,7 @@ bool Program::SetEnv(const char * entry,const char * new_string) { env_write += (PhysPt)(strlen(env_string)+1); } /* Clear out the final piece of the environment */ - mem_writed(env_write,0); + mem_writeb(env_write,0); return true; } From e90de61263ae014423b5b7b066290873b63ccd23 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 24 Jun 2019 20:09:59 +0000 Subject: [PATCH 4120/4131] Create fopen_wrapper so we can filter out specific directories, which DOS games should have no access to Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4238 --- include/cross.h | 1 + src/misc/cross.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/include/cross.h b/include/cross.h index 1a81ebe0..90b65315 100644 --- a/include/cross.h +++ b/include/cross.h @@ -105,4 +105,5 @@ bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_dire bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory); void close_directory(dir_information* dirp); +FILE *fopen_wrap(const char *path, const char *mode); #endif diff --git a/src/misc/cross.cpp b/src/misc/cross.cpp index 8fbefbfc..49c20aa8 100644 --- a/src/misc/cross.cpp +++ b/src/misc/cross.cpp @@ -21,6 +21,7 @@ #include "cross.h" #include "support.h" #include +#include #include #ifdef WIN32 @@ -244,3 +245,60 @@ void close_directory(dir_information* dirp) { } #endif + +FILE *fopen_wrap(const char *path, const char *mode) { +#if defined(WIN32) || defined(OS2) + ; +#elif defined (MACOSX) + ; +#else +#if defined (HAVE_REALPATH) + char work[CROSS_LEN] = {0}; + strncpy(work,path,CROSS_LEN-1); + char* last = strrchr(work,'/'); + + if (last) { + if (last != work) { + *last = 0; + //If this compare fails, then we are dealing with files in / + //Which is outside the scope, but test anyway. + //However as realpath only works for exising files. The testing is + //in that case not done against new files. + } + char* check = realpath(work,NULL); + if (check) { + if ( ( strlen(check) == 5 && strcmp(check,"/proc") == 0) || strncmp(check,"/proc/",6) == 0) { +// LOG_MSG("lst hit %s blocking!",path); + free(check); + return NULL; + } + free(check); + } + } + +#if 0 +//Lightweight version, but then existing files can still be read, which is not ideal + if (strpbrk(mode,"aw+") != NULL) { + LOG_MSG("pbrk ok"); + char* check = realpath(path,NULL); + //Will be null if file doesn't exist.... ENOENT + //TODO What about unlink /proc/self/mem and then create it ? + //Should be safe for what we want.. + if (check) { + if (strncmp(check,"/proc/",6) == 0) { + free(check); + return NULL; + } + free(check); + } + } +*/ +#endif //0 + +#endif //HAVE_REALPATH +#endif + + return fopen(path,mode); +} + + From ad88f982c095c12092cdecc3be8dd1e27387ea03 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 25 Jun 2019 06:12:13 +0000 Subject: [PATCH 4121/4131] Add some size checks when accessing Drives[], mostly needed when DOS_DRIVES is not set to 26, make size parsing not go outside the target array. Let's not try to assign a drive in the switchlist to a too high number. Don't access imagelist for drives >D when unmounting. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4239 --- include/bios_disk.h | 6 ++-- src/dos/dos_files.cpp | 2 +- src/dos/dos_programs.cpp | 73 +++++++++++++++++++++++++--------------- src/ints/bios_disk.cpp | 2 +- 4 files changed, 52 insertions(+), 31 deletions(-) diff --git a/include/bios_disk.h b/include/bios_disk.h index 25c0abf9..31537269 100644 --- a/include/bios_disk.h +++ b/include/bios_disk.h @@ -75,8 +75,10 @@ void incrementFDD(void); #define MAX_HDD_IMAGES 2 -extern imageDisk *imageDiskList[2 + MAX_HDD_IMAGES]; -extern imageDisk *diskSwap[20]; +#define MAX_DISK_IMAGES (2 + MAX_HDD_IMAGES) + +extern imageDisk *imageDiskList[MAX_DISK_IMAGES]; +extern imageDisk *diskSwap[MAX_SWAPPABLE_DISKS]; extern Bit32s 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 */ diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index b78325ae..8d88361d 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -52,7 +52,7 @@ Bit8u DOS_GetDefaultDrive(void) { void DOS_SetDefaultDrive(Bit8u drive) { // if (drive<=DOS_DRIVES && ((drive<2) || Drives[drive])) DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetDrive(drive); - if (drive<=DOS_DRIVES && ((drive<2) || Drives[drive])) {dos.current_drive = drive; DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetDrive(drive);} + if (drive= DOS_DRIVES || i_drive < 0 || (Drives[i_drive] == NULL && imageDiskList[i_drive] == NULL)) + if (i_drive >= DOS_DRIVES || i_drive < 0) + return MSG_Get("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED"); + + if (i_drive < MAX_DISK_IMAGES && Drives[i_drive] == NULL && imageDiskList[i_drive] == NULL) + return MSG_Get("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED"); + + if (i_drive >= MAX_DISK_IMAGES && Drives[i_drive] == NULL) return MSG_Get("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED"); if (Drives[i_drive]) { @@ -82,7 +88,7 @@ static const char* UnmountHelper(char umount) { } - if (imageDiskList[i_drive]) { + if (i_drive < MAX_DISK_IMAGES && imageDiskList[i_drive]) { delete imageDiskList[i_drive]; imageDiskList[i_drive] = NULL; } @@ -245,23 +251,29 @@ public: } cmd->FindString("-size",str_size,true); - char number[20];const char * scan=str_size.c_str(); - Bitu index=0;Bitu count=0; + char number[21] = { 0 };const char * scan = str_size.c_str(); + Bitu index = 0;Bitu count = 0; /* Parse the str_size string */ - while (*scan) { + while (*scan && index < 20 && count < 4) { if (*scan==',') { - number[index]=0;sizes[count++]=atoi(number); - index=0; - } else number[index++]=*scan; + number[index] = 0; + sizes[count++] = atoi(number); + index = 0; + } else number[index++] = *scan; scan++; } - number[index]=0;sizes[count++]=atoi(number); + if (count < 4) { + number[index] = 0; //always goes correct as index is max 20 at this point. + sizes[count] = atoi(number); + } // get the drive letter cmd->FindCommand(1,temp_line); if ((temp_line.size() > 2) || ((temp_line.size()>1) && (temp_line[1]!=':'))) goto showusage; - drive=toupper(temp_line[0]); - if (!isalpha(drive)) goto showusage; + int i_drive = toupper(temp_line[0]); + if (!isalpha(i_drive)) goto showusage; + if ((i_drive - 'A') >= DOS_DRIVES || (i_drive-'A') < 0 ) goto showusage; + drive = static_cast(i_drive); if (!cmd->FindCommand(2,temp_line)) goto showusage; if (!temp_line.size()) goto showusage; @@ -407,11 +419,11 @@ public: std::string base = ldp->getBasedir(); Bit8u o_error = 0; newdrive = new Overlay_Drive(base.c_str(),temp_line.c_str(),sizes[0],bit8size,sizes[2],sizes[3],mediaid,o_error); - //Erase old drive on succes + //Erase old drive on success if (newdrive) { if (o_error) { if (o_error == 1) WriteOut("No mixing of relative and absolute paths. Overlay failed."); - else if (o_error == 2) WriteOut("overlay directory can not be the same as underlying filesystem."); + else if (o_error == 2) WriteOut("overlay directory can not be the same as underlying file system."); else WriteOut("Something went wrong"); delete newdrive; return; @@ -693,7 +705,10 @@ public: i++; continue; } - + + if ( i >= MAX_SWAPPABLE_DISKS ) { + return; //TODO give a warning. + } WriteOut(MSG_Get("PROGRAM_BOOT_IMAGE_OPEN"), temp_line.c_str()); Bit32u rombytesize; FILE *usefile = getFSFile(temp_line.c_str(), &floppysize, &rombytesize); @@ -1190,18 +1205,21 @@ public: if ((type=="hdd") && (str_size.size()==0)) { imgsizedetect=true; } else { - char number[20]; - const char * scan=str_size.c_str(); - Bitu index=0;Bitu count=0; - - while (*scan) { + char number[21] = { 0 };const char * scan = str_size.c_str(); + Bitu index = 0;Bitu count = 0; + /* Parse the str_size string */ + while (*scan && index < 20 && count < 4) { if (*scan==',') { - number[index]=0;sizes[count++]=atoi(number); - index=0; - } else number[index++]=*scan; + number[index] = 0; + sizes[count++] = atoi(number); + index = 0; + } else number[index++] = *scan; scan++; } - number[index]=0;sizes[count++]=atoi(number); + if (count < 4) { + number[index] = 0; //always goes correct as index is max 20 at this point. + sizes[count] = atoi(number); + } } if(fstype=="fat" || fstype=="iso") { @@ -1210,11 +1228,12 @@ public: WriteOut_NoParsing(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_DRIVE")); return; } - drive=toupper(temp_line[0]); - if (!isalpha(drive)) { + int i_drive = toupper(temp_line[0]); + if (!isalpha(drive) || (i_drive - 'A') >= DOS_DRIVES || (i_drive - 'A') <0) { WriteOut_NoParsing(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_DRIVE")); return; } + drive = static_cast(i_drive); } else if (fstype=="none") { cmd->FindCommand(1,temp_line); if ((temp_line.size() > 1) || (!isdigit(temp_line[0]))) { @@ -1222,7 +1241,7 @@ public: return; } drive=temp_line[0]; - if ((drive<'0') || (drive>3+'0')) { + if ((drive<'0') || (drive>=(MAX_DISK_IMAGES+'0'))) { WriteOut_NoParsing(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY2")); return; } @@ -1452,7 +1471,7 @@ public: WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MOUNT_NUMBER"),drive-'0',temp_line.c_str()); } - // check if volume label is given. becareful for cdrom + // check if volume label is given. be careful for cdrom //if (cmd->FindString("-label",label,true)) newdrive->dirCache.SetLabel(label.c_str()); return; } diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index f3eaab78..7edc771c 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -27,7 +27,7 @@ #include "../dos/drives.h" #include "mapper.h" -#define MAX_DISK_IMAGES 4 + diskGeo DiskGeometryList[] = { { 160, 8, 1, 40, 0}, From 551ee5b2fdf73cefb2a1e83278fb62850d1b8b3f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 25 Jun 2019 14:51:25 +0000 Subject: [PATCH 4122/4131] drive => i_drive Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4242 --- src/dos/dos_programs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 4f0fad77..034e5605 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1229,7 +1229,7 @@ public: return; } int i_drive = toupper(temp_line[0]); - if (!isalpha(drive) || (i_drive - 'A') >= DOS_DRIVES || (i_drive - 'A') <0) { + if (!isalpha(i_drive) || (i_drive - 'A') >= DOS_DRIVES || (i_drive - 'A') <0) { WriteOut_NoParsing(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_DRIVE")); return; } From 0abb5731679eb677e345b1fe975325b4971d698f Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 25 Jun 2019 17:53:05 +0000 Subject: [PATCH 4123/4131] Implement simple access control for reading and writing files that are accessable from within DOSBox. Overlay not yet tested, hence not part of this commit. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4245 --- src/dos/dos_programs.cpp | 8 ++++---- src/dos/drive_fat.cpp | 2 +- src/dos/drive_local.cpp | 14 +++++++------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 034e5605..621b9bfc 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -607,9 +607,9 @@ private: //File not found on mounted filesystem. Try regular filesystem std::string filename_s(filename); Cross::ResolveHomedir(filename_s); - tmpfile = fopen(filename_s.c_str(),"rb+"); + tmpfile = fopen_wrap(filename_s.c_str(),"rb+"); if(!tmpfile) { - if( (tmpfile = fopen(filename_s.c_str(),"rb")) ) { + if( (tmpfile = fopen_wrap(filename_s.c_str(),"rb")) ) { //File exists; So can't be opened in correct mode => error 2 // fclose(tmpfile); // if(tryload) error = 2; @@ -1301,7 +1301,7 @@ public: if(fstype=="fat") { if (imgsizedetect) { - FILE * diskfile = fopen(temp_line.c_str(), "rb+"); + FILE * diskfile = fopen_wrap(temp_line.c_str(), "rb+"); if (!diskfile) { WriteOut(MSG_Get("PROGRAM_IMGMOUNT_INVALID_IMAGE")); return; @@ -1448,7 +1448,7 @@ public: WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"), drive, tmp.c_str()); } else { - FILE *newDisk = fopen(temp_line.c_str(), "rb+"); + FILE *newDisk = fopen_wrap(temp_line.c_str(), "rb+"); if (!newDisk) { WriteOut(MSG_Get("PROGRAM_IMGMOUNT_INVALID_IMAGE")); return; diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 63bfc155..e7ffdb70 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -705,7 +705,7 @@ fatDrive::fatDrive(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, imgDTA = new DOS_DTA(imgDTAPtr); } - diskfile = fopen(sysFilename, "rb+"); + diskfile = fopen_wrap(sysFilename, "rb+"); if(!diskfile) {created_successfully = false;return;} fseek(diskfile, 0L, SEEK_END); filesize = (Bit32u)ftell(diskfile) / 1024L; diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index da8d6e59..4b9013b2 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -39,16 +39,16 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u /*attributes*/) CROSS_FILENAME(newname); char* temp_name = dirCache.GetExpandName(newname); //Can only be used in till a new drive_cache action is preformed */ /* Test if file exists (so we need to truncate it). don't add to dirCache then */ - bool existing_file=false; + bool existing_file = false; - FILE * test=fopen(temp_name,"rb+"); + FILE * test = fopen_wrap(temp_name,"rb+"); if(test) { fclose(test); existing_file=true; } - FILE * hand=fopen(temp_name,"wb+"); + FILE * hand = fopen_wrap(temp_name,"wb+"); if (!hand){ LOG_MSG("Warning: file creation failed: %s",newname); return false; @@ -95,11 +95,11 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { } } - FILE * hand=fopen(newname,type); + FILE * hand = fopen_wrap(newname,type); // Bit32u err=errno; if (!hand) { if((flags&0xf) != OPEN_READ) { - FILE * hmm=fopen(newname,"rb"); + FILE * hmm = fopen_wrap(newname,"rb"); if (hmm) { fclose(hmm); LOG_MSG("Warning: file %s exists and failed to open in write mode.\nPlease Remove write-protection",newname); @@ -122,7 +122,7 @@ FILE * localDrive::GetSystemFilePtr(char const * const name, char const * const CROSS_FILENAME(newname); dirCache.ExpandName(newname); - return fopen(newname,type); + return fopen_wrap(newname,type); } bool localDrive::GetSystemFilename(char *sysName, char const * const dosName) { @@ -145,7 +145,7 @@ bool localDrive::FileUnlink(char * name) { struct stat buffer; if(stat(fullname,&buffer)) return false; // File not found. - FILE* file_writable = fopen(fullname,"rb+"); + FILE* file_writable = fopen_wrap(fullname,"rb+"); if(!file_writable) return false; //No acces ? ERROR MESSAGE NOT SET. FIXME ? fclose(file_writable); From e48149278e73901c248136807300f7ad88eec740 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 25 Jun 2019 20:44:00 +0000 Subject: [PATCH 4124/4131] Changes to allow for mingw i686 to compile a new zmbv.dll Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4247 --- src/libs/zmbv/drvproc.cpp | 2 +- src/libs/zmbv/makedll.mk | 17 +++++++++++++++ src/libs/zmbv/resource.h | 15 +------------- src/libs/zmbv/resource.rc | 40 ++++++++++++++++++++++++++++++++++++ src/libs/zmbv/zmbv_mingw.def | 2 ++ src/libs/zmbv/zmbv_vfw.cpp | 22 ++++++++++++-------- 6 files changed, 75 insertions(+), 23 deletions(-) create mode 100644 src/libs/zmbv/makedll.mk create mode 100644 src/libs/zmbv/resource.rc create mode 100644 src/libs/zmbv/zmbv_mingw.def diff --git a/src/libs/zmbv/drvproc.cpp b/src/libs/zmbv/drvproc.cpp index 44b6ab61..299e5e67 100644 --- a/src/libs/zmbv/drvproc.cpp +++ b/src/libs/zmbv/drvproc.cpp @@ -68,7 +68,7 @@ * Defined separately for each message. * ***************************************************************************/ -LRESULT PASCAL DriverProc(DWORD dwDriverID, HDRVR hDriver, UINT uiMessage, LPARAM lParam1, LPARAM lParam2) { +extern "C" LRESULT PASCAL __declspec(dllexport) DriverProc(DWORD dwDriverID, HDRVR hDriver, UINT uiMessage, LPARAM lParam1, LPARAM lParam2) { CodecInst* pi = (CodecInst*)dwDriverID; switch (uiMessage) { diff --git a/src/libs/zmbv/makedll.mk b/src/libs/zmbv/makedll.mk new file mode 100644 index 00000000..c2b0b024 --- /dev/null +++ b/src/libs/zmbv/makedll.mk @@ -0,0 +1,17 @@ +CPP=g++ +CPPFLAGS=-O3 +LIBS=-static -lz -lwinmm -static-libgcc -static-libstdc++ + +OBJ = resource.o zmbv.o drvproc.o zmbv_vfw.o + +default: zmbv.dll + + +resource.o: resource.rc + windres -i resource.rc -o resource.o + +%.o: %.cpp + $(CPP) -c -o $@ $< $(CPPFLAGS) + +zmbv.dll: $(OBJ) + $(CPP) -shared -o $@ $^ $(CPPFLAGS) $(LIBS) zmbv_mingw.def \ No newline at end of file diff --git a/src/libs/zmbv/resource.h b/src/libs/zmbv/resource.h index f4830af1..0d6f72a0 100644 --- a/src/libs/zmbv/resource.h +++ b/src/libs/zmbv/resource.h @@ -1,21 +1,8 @@ //{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by zmbv_vfw.rc -// + #define IDD_ABOUT 101 #define IDD_CONFIGURE 102 #define IDC_HOMEPAGE 1000 #define IDC_EMAIL 1001 #define IDC_SLIDER1 1008 -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 103 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1009 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/src/libs/zmbv/resource.rc b/src/libs/zmbv/resource.rc new file mode 100644 index 00000000..5e4e3a48 --- /dev/null +++ b/src/libs/zmbv/resource.rc @@ -0,0 +1,40 @@ +#include "resource.h" +#include "windows.h" + +#ifndef IDC_STATIC +#define IDC_STATIC -1 +#endif + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUT DIALOGEX 0, 0, 167, 55 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "DOSBox Video Codec v0.1a" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + DEFPUSHBUTTON "OK",IDOK,131,34,29,14 + CTEXT "Zipped Motion Block Video v 0.1\nCopyright 2009-2019 DOSBox Team", + IDC_STATIC,7,7,153,25,SS_NOPREFIX + PUSHBUTTON "Email author",IDC_EMAIL,7,34,50,14 + PUSHBUTTON "Visit home page",IDC_HOMEPAGE,59,34,58,14 +END + +IDD_CONFIGURE DIALOGEX 0, 0, 213, 146 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "ZMBV configuration dialog" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + PUSHBUTTON "Email author",IDC_EMAIL,44,86,50,14 + PUSHBUTTON "Visit home page",IDC_HOMEPAGE,109,87,58,14 + DEFPUSHBUTTON "OK",IDOK,44,125,50,14 + PUSHBUTTON "Cancel",IDCANCEL,117,125,50,14 + CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH | + TBS_NOTICKS | WS_TABSTOP,57,30,92,18 +END + + diff --git a/src/libs/zmbv/zmbv_mingw.def b/src/libs/zmbv/zmbv_mingw.def new file mode 100644 index 00000000..04142744 --- /dev/null +++ b/src/libs/zmbv/zmbv_mingw.def @@ -0,0 +1,2 @@ +EXPORTS + DriverProc = DriverProc@20 @1 diff --git a/src/libs/zmbv/zmbv_vfw.cpp b/src/libs/zmbv/zmbv_vfw.cpp index dec8dc6f..3be8459e 100644 --- a/src/libs/zmbv/zmbv_vfw.cpp +++ b/src/libs/zmbv/zmbv_vfw.cpp @@ -30,10 +30,10 @@ #include #include -TCHAR szDescription[] = TEXT("Zipped Motion Block Video v0.1"); +TCHAR szDescription[] = TEXT("Zipped Motion Block Video v0.1a"); TCHAR szName[] = TEXT(CODEC_4CC); -#define VERSION 0x00000001 // 0.1 +#define VERSION 0x00000002 // newer version /******************************************************************** ********************************************************************/ @@ -90,7 +90,7 @@ DWORD Close(CodecInst* pinst) { BOOL CodecInst::QueryAbout() { return TRUE; } -static BOOL CALLBACK AboutDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { +static INT_PTR CALLBACK AboutDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_COMMAND) { switch (LOWORD(wParam)) { case IDOK: @@ -111,7 +111,7 @@ DWORD CodecInst::About(HWND hwnd) { return ICERR_OK; } -static BOOL CALLBACK ConfigureDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { +static INT_PTR CALLBACK ConfigureDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_INITDIALOG) { @@ -175,6 +175,7 @@ DWORD CodecInst::GetInfo(ICINFO* icinfo, DWORD dwSize) { ****************************************************************/ static int GetInputBitDepth(const BITMAPINFOHEADER *lpbiIn) { + //Msg( "Get input depth compression %d bitcount %d\n", lpbiIn->biCompression, lpbiIn->biBitCount ); if (lpbiIn->biCompression == BI_RGB) { if (lpbiIn->biPlanes != 1) return -1; @@ -214,11 +215,14 @@ static bool CanCompress(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, b if (lpbiIn) { if (GetInputBitDepth(lpbiIn) < 0) return false; - } else return false; + } else + return false; if (lpbiOut) { + //Needs to match our 4cc format if (memcmp(&lpbiOut->biCompression,CODEC_4CC, 4)) return false; - } else return !requireOutput; + } else + return !requireOutput; return true; } @@ -226,7 +230,8 @@ static bool CanCompress(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, b ****************************************************************/ DWORD CodecInst::CompressQuery(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) { - if (CanCompress(lpbiIn,lpbiOut,false)) return ICERR_OK; + if (CanCompress(lpbiIn,lpbiOut,false)) + return ICERR_OK; return ICERR_BADFORMAT; } @@ -373,7 +378,8 @@ DWORD CodecInst::DecompressQuery(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER l DWORD CodecInst::DecompressGetFormat(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) { if (memcmp(&lpbiIn->biCompression,CODEC_4CC,4)) return ICERR_BADFORMAT; - if (!lpbiOut) return sizeof(BITMAPINFOHEADER); + if (!lpbiOut) + return sizeof(BITMAPINFOHEADER); *lpbiOut = *lpbiIn; lpbiOut->biPlanes = 1; lpbiOut->biSize = sizeof(BITMAPINFOHEADER); From 4ffc75be3c1f889c1c998a96843f99b8a15615b5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 27 Jun 2019 09:12:41 +0000 Subject: [PATCH 4125/4131] Add wrapping here as well. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4251 --- src/dos/drive_overlay.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/dos/drive_overlay.cpp b/src/dos/drive_overlay.cpp index 2c911b19..73f2f2d7 100644 --- a/src/dos/drive_overlay.cpp +++ b/src/dos/drive_overlay.cpp @@ -235,7 +235,7 @@ FILE* Overlay_Drive::create_file_in_overlay(char* dos_filename, char const* mode strcat(newname,dos_filename); //HERE we need to convert it to Linux TODO CROSS_FILENAME(newname); - FILE* f = fopen(newname,mode); + FILE* f = fopen_wrap(newname,mode); //Check if a directories are part of the name: char* dir = strrchr(dos_filename,'\\'); if (!f && dir && *dir) { @@ -243,7 +243,7 @@ FILE* Overlay_Drive::create_file_in_overlay(char* dos_filename, char const* mode //ensure they exist, else make them in the overlay if they exist in the original.... Sync_leading_dirs(dos_filename); //try again - f = fopen(newname,mode); + f = fopen_wrap(newname,mode); } return f; @@ -421,7 +421,7 @@ bool Overlay_Drive::FileOpen(DOS_File * * file,char * name,Bit32u flags) { strcat(newname,name); CROSS_FILENAME(newname); - FILE * hand = fopen(newname,type); + FILE * hand = fopen_wrap(newname,type); bool fileopened = false; if (hand) { if (logoverlay) LOG_MSG("overlay file opened %s",newname); @@ -847,7 +847,7 @@ bool Overlay_Drive::FileUnlink(char * name) { return true; // E_Exit("trying to remove existing non-overlay file %s",name); } - FILE* file_writable = fopen(overlayname,"rb+"); + FILE* file_writable = fopen_wrap(overlayname,"rb+"); if(!file_writable) return false; //No access ? ERROR MESSAGE NOT SET. FIXME ? fclose(file_writable); @@ -931,10 +931,10 @@ void Overlay_Drive::add_special_file_to_disk(const char* dosname, const char* op strcpy(overlayname,overlaydir); strcat(overlayname,name.c_str()); CROSS_FILENAME(overlayname); - FILE* f = fopen(overlayname,"wb+"); + FILE* f = fopen_wrap(overlayname,"wb+"); if (!f) { Sync_leading_dirs(dosname); - f = fopen(overlayname,"wb+"); + f = fopen_wrap(overlayname,"wb+"); } if (!f) E_Exit("Failed creation of %s",overlayname); char buf[5] = {'e','m','p','t','y'}; @@ -1107,7 +1107,7 @@ bool Overlay_Drive::Rename(char * oldname,char * newname) { strcat(newold,oldname); CROSS_FILENAME(newold); dirCache.ExpandName(newold); - FILE* o = fopen(newold,"rb"); + FILE* o = fopen_wrap(newold,"rb"); if (!o) return false; FILE* n = create_file_in_overlay(newname,"wb+"); if (!n) {fclose(o); return false;} From 05f15ac4c0199110204b801984c3747e976ea048 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 30 Jun 2019 11:31:09 +0000 Subject: [PATCH 4126/4131] Correct a little bug that caused graphics corruption in win95 with s3 driver. (jmarsh) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4252 --- src/cpu/core_dyn_x86/risc_x86.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/core_dyn_x86/risc_x86.h b/src/cpu/core_dyn_x86/risc_x86.h index ca502d8f..5bf626ee 100644 --- a/src/cpu/core_dyn_x86/risc_x86.h +++ b/src/cpu/core_dyn_x86/risc_x86.h @@ -388,7 +388,7 @@ static void gen_dop_byte_imm_mem(DualOps op,DynReg * dr1,Bit8u di1,void* data) { case DOP_AND: tmp=0x0522; break; case DOP_OR: tmp=0x050a; break; case DOP_TEST: tmp=0x0584; goto nochange; //Doesn't change - case DOP_MOV: tmp=0x0585; break; + case DOP_MOV: tmp=0x058A; break; default: IllegalOption("gen_dop_byte_imm_mem"); } From 25e01bd0428c6fc45b51c52bb79cfe5634b4b4d2 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 2 Sep 2019 16:50:30 +0000 Subject: [PATCH 4127/4131] Fix bug 512, reported by philipp. (checking wrong variable to see if malloc was a success) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4254 --- src/hardware/hardware.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index b0dc7bd6..2f800b75 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -490,7 +490,7 @@ skip_shot: if (!capture.video.buf) goto skip_video; capture.video.index = (Bit8u*)malloc( 16*4096 ); - if (!capture.video.buf) + if (!capture.video.index) goto skip_video; capture.video.indexsize = 16*4096; capture.video.indexused = 8; From 53666d5f27719468408d6463789757ddd6a5b759 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 8 Sep 2019 12:25:41 +0000 Subject: [PATCH 4128/4131] Extra DIR sorting options patch by Saga Musix Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4255 --- src/shell/shell_cmds.cpp | 100 +++++++++++++++++++++++++++++++++++---- 1 file changed, 91 insertions(+), 9 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index e1d688c3..88cb072c 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -25,6 +25,7 @@ #include "../dos/drives.h" #include "support.h" #include "control.h" +#include #include #include #include @@ -407,7 +408,31 @@ static void FormatNumber(Bit32u num,char * buf) { return; }; sprintf(buf,"%d",numb); -} +} + +struct DtaResult { + char name[DOS_NAMELENGTH_ASCII]; + Bit32u size; + Bit16u date; + Bit16u time; + Bit8u attr; + + static bool compareName(const DtaResult &lhs, const DtaResult &rhs) { return strcmp(lhs.name, rhs.name) < 0; } + static bool compareExt(const DtaResult &lhs, const DtaResult &rhs) { return strcmp(lhs.getExtension(), rhs.getExtension()) < 0; } + static bool compareSize(const DtaResult &lhs, const DtaResult &rhs) { return lhs.size < rhs.size; } + static bool compareDate(const DtaResult &lhs, const DtaResult &rhs) { return lhs.date < rhs.date || (lhs.date == rhs.date && lhs.time < rhs.time); } + + const char * getExtension() const { + const char * ext = empty_string; + if (name[0] != '.') { + ext = strrchr(name, '.'); + if (!ext) ext = empty_string; + } + return ext; + } + +}; + void DOS_Shell::CMD_DIR(char * args) { HELP("DIR"); @@ -421,7 +446,7 @@ void DOS_Shell::CMD_DIR(char * args) { line = std::string(args) + " " + value; args=const_cast(line.c_str()); } - + bool optW=ScanCMDBool(args,"W"); ScanCMDBool(args,"S"); bool optP=ScanCMDBool(args,"P"); @@ -430,6 +455,29 @@ void DOS_Shell::CMD_DIR(char * args) { } bool optB=ScanCMDBool(args,"B"); bool optAD=ScanCMDBool(args,"AD"); + bool optAminusD=ScanCMDBool(args,"A-D"); + // Sorting flags + bool reverseSort = false; + bool optON=ScanCMDBool(args,"ON"); + if (ScanCMDBool(args,"O-N")) { + optON = true; + reverseSort = true; + } + bool optOD=ScanCMDBool(args,"OD"); + if (ScanCMDBool(args,"O-D")) { + optOD = true; + reverseSort = true; + } + bool optOE=ScanCMDBool(args,"OE"); + if (ScanCMDBool(args,"O-E")) { + optOE = true; + reverseSort = true; + } + bool optOS=ScanCMDBool(args,"OS"); + if (ScanCMDBool(args,"O-S")) { + optOS = true; + reverseSort = true; + } char * rem=ScanCMDRemain(args); if (rem) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); @@ -488,13 +536,45 @@ void DOS_Shell::CMD_DIR(char * args) { return; } - do { /* File name and extension */ - char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr; - dta.GetResult(name,size,date,time,attr); + std::vector results; + + do { /* File name and extension */ + DtaResult result; + dta.GetResult(result.name,result.size,result.date,result.time,result.attr); + + /* Skip non-directories if option AD is present, or skip dirs in case of A-D */ + if(optAD && !(result.attr&DOS_ATTR_DIRECTORY) ) continue; + else if(optAminusD && (result.attr&DOS_ATTR_DIRECTORY) ) continue; + + results.push_back(result); + + } while ( (ret=DOS_FindNext()) ); + + if (optON) { + // Sort by name + std::sort(results.begin(), results.end(), DtaResult::compareName); + } else if (optOE) { + // Sort by extension + std::sort(results.begin(), results.end(), DtaResult::compareExt); + } else if (optOD) { + // Sort by date + std::sort(results.begin(), results.end(), DtaResult::compareDate); + } else if (optOS) { + // Sort by size + std::sort(results.begin(), results.end(), DtaResult::compareSize); + } + if (reverseSort) { + std::reverse(results.begin(), results.end()); + } + + for (std::vector::iterator iter = results.begin(); iter != results.end(); iter++) { + + char * name = iter->name; + Bit32u size = iter->size; + Bit16u date = iter->date; + Bit16u time = iter->time; + Bit8u attr = iter->attr; - /* Skip non-directories if option AD is present */ - if(optAD && !(attr&DOS_ATTR_DIRECTORY) ) continue; - /* output the file */ if (optB) { // this overrides pretty much everything @@ -542,7 +622,9 @@ void DOS_Shell::CMD_DIR(char * args) { if (optP && !(++p_count%(22*w_size))) { CMD_PAUSE(empty_string); } - } while ( (ret=DOS_FindNext()) ); + } + + if (optW) { if (w_count%5) WriteOut("\n"); } From bca40f55612046866f106f8f967608d3b0ba0648 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 8 Sep 2019 12:42:21 +0000 Subject: [PATCH 4129/4131] Fix flag behaviour of several shift/rotate instructions, cause exceptions and fix potention 'pop ss' problems Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4256 --- src/cpu/core_full/load.h | 14 ++++++---- src/cpu/core_full/optable.h | 12 ++++----- src/cpu/core_full/support.h | 3 ++- src/cpu/cpu.cpp | 18 +++++++------ src/cpu/instructions.h | 51 +++++-------------------------------- 5 files changed, 33 insertions(+), 65 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 6645860c..d029def4 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -186,15 +186,19 @@ l_M_Ed: case M_GRP: inst.code=Groups[inst.code.op][inst.rm_index]; goto l_MODRMswitch; - case M_GRP_Ib: - inst_op2_d=Fetchb(); + case M_SHIFT_Ib: + inst_op2_d=Fetchb() & 0x1f; + if (!inst_op2_d) + break; inst.code=Groups[inst.code.op][inst.rm_index]; goto l_MODRMswitch; - case M_GRP_CL: - inst_op2_d=reg_cl; + case M_SHIFT_CL: + inst_op2_d=reg_cl & 0x1f; + if (!inst_op2_d) + break; inst.code=Groups[inst.code.op][inst.rm_index]; goto l_MODRMswitch; - case M_GRP_1: + case M_SHIFT_1: inst_op2_d=1; inst.code=Groups[inst.code.op][inst.rm_index]; goto l_MODRMswitch; diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 7a0ac82f..1ea95db4 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -155,7 +155,7 @@ static OpCode OpCodeTable[1024]={ {L_Iw ,0 ,S_REGw ,REGI_SI},{L_Iw ,0 ,S_REGw ,REGI_DI}, /* 0xc0 - 0xc7 */ -{L_MODRM ,5 ,0 ,M_GRP_Ib },{L_MODRM ,6 ,0 ,M_GRP_Ib }, +{L_MODRM ,5 ,0 ,M_SHIFT_Ib },{L_MODRM ,6 ,0 ,M_SHIFT_Ib }, {L_POPw ,0 ,S_IPIw ,0 },{L_POPw ,0 ,S_IP ,0 }, {L_MODRM ,O_SEGES ,S_SEGGw,M_Efw },{L_MODRM ,O_SEGDS ,S_SEGGw,M_Efw }, {L_MODRM ,0 ,S_Eb ,M_Ib },{L_MODRM ,0 ,S_Ew ,M_Iw }, @@ -166,8 +166,8 @@ static OpCode OpCodeTable[1024]={ {L_INTO ,O_INT ,0 ,0 },{D_IRETw ,0 ,0 ,0 }, /* 0xd0 - 0xd7 */ -{L_MODRM ,5 ,0 ,M_GRP_1 },{L_MODRM ,6 ,0 ,M_GRP_1 }, -{L_MODRM ,5 ,0 ,M_GRP_CL },{L_MODRM ,6 ,0 ,M_GRP_CL }, +{L_MODRM ,5 ,0 ,M_SHIFT_1 },{L_MODRM ,6 ,0 ,M_SHIFT_1 }, +{L_MODRM ,5 ,0 ,M_SHIFT_CL },{L_MODRM ,6 ,0 ,M_SHIFT_CL }, {L_Ib ,O_AAM ,0 ,0 },{L_Ib ,O_AAD ,0 ,0 }, {D_SETALC ,0 ,0 ,0 },{D_XLAT ,0 ,0 ,0 }, //TODO FPU @@ -511,7 +511,7 @@ static OpCode OpCodeTable[1024]={ {L_Id ,0 ,S_REGd ,REGI_SI},{L_Id ,0 ,S_REGd ,REGI_DI}, /* 0x2c0 - 0x2c7 */ -{L_MODRM ,5 ,0 ,M_GRP_Ib },{L_MODRM ,7 ,0 ,M_GRP_Ib }, +{L_MODRM ,5 ,0 ,M_SHIFT_Ib },{L_MODRM ,7 ,0 ,M_SHIFT_Ib }, {L_POPd ,0 ,S_IPIw ,0 },{L_POPd ,0 ,S_IP ,0 }, {L_MODRM ,O_SEGES ,S_SEGGd,M_Efd },{L_MODRM ,O_SEGDS ,S_SEGGd,M_Efd }, {L_MODRM ,0 ,S_Eb ,M_Ib },{L_MODRM ,0 ,S_Ed ,M_Id }, @@ -522,8 +522,8 @@ static OpCode OpCodeTable[1024]={ {L_INTO ,O_INT ,0 ,0 },{D_IRETd ,0 ,0 ,0 }, /* 0x2d0 - 0x2d7 */ -{L_MODRM ,5 ,0 ,M_GRP_1 },{L_MODRM ,7 ,0 ,M_GRP_1 }, -{L_MODRM ,5 ,0 ,M_GRP_CL },{L_MODRM ,7 ,0 ,M_GRP_CL }, +{L_MODRM ,5 ,0 ,M_SHIFT_1 },{L_MODRM ,7 ,0 ,M_SHIFT_1 }, +{L_MODRM ,5 ,0 ,M_SHIFT_CL },{L_MODRM ,7 ,0 ,M_SHIFT_CL }, {L_Ib ,O_AAM ,0 ,0 },{L_Ib ,O_AAD ,0 ,0 }, {D_SETALC ,0 ,0 ,0 },{D_XLAT ,0 ,0 ,0 }, /* 0x2d8 - 0x2df */ diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 6ac7711e..f8d8b332 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -167,7 +167,8 @@ enum { M_SEG,M_EA, M_GRP, - M_GRP_Ib,M_GRP_CL,M_GRP_1, + //Special shift groups + M_SHIFT_1, M_SHIFT_Ib,M_SHIFT_CL, M_POPw,M_POPd }; diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 95cd2839..bc1c576e 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1925,17 +1925,17 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) { if (seg==ss) { // Stack needs to be non-zero if ((value & 0xfffc)==0) { - E_Exit("CPU_SetSegGeneral: Stack segment zero"); -// return CPU_PrepareException(EXCEPTION_GP,0); +// E_Exit("CPU_SetSegGeneral: Stack segment zero"); + return CPU_PrepareException(EXCEPTION_GP,0); } Descriptor desc; if (!cpu.gdt.GetDescriptor(value,desc)) { - E_Exit("CPU_SetSegGeneral: Stack segment beyond limits"); -// return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); +// E_Exit("CPU_SetSegGeneral: Stack segment beyond limits"); + return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); } if (((value & 3)!=cpu.cpl) || (desc.DPL()!=cpu.cpl)) { - E_Exit("CPU_SetSegGeneral: Stack segment with invalid privileges"); -// return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); +// E_Exit("CPU_SetSegGeneral: Stack segment with invalid privileges"); + return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); } switch (desc.Type()) { @@ -2006,9 +2006,11 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) { bool CPU_PopSeg(SegNames seg,bool use32) { Bitu val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); + Bitu addsp = use32 ? 0x04 : 0x02; + //Calcullate this beforehande since the stack mask might change + Bit32u new_esp = (reg_esp&cpu.stack.notmask) | ((reg_esp + addsp)&cpu.stack.mask); if (CPU_SetSegGeneral(seg,val)) return true; - Bitu addsp=use32?0x04:0x02; - reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+addsp)&cpu.stack.mask); + reg_esp = new_esp; return false; } diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 9265f6cd..404ab68b 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -228,14 +228,6 @@ #define ROLB(op1,op2,load,save) \ - if (!(op2&0x7)) { \ - if (op2&0x18) { \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(CF,op1 & 1); \ - SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 7)); \ - } \ - break; \ - } \ FillFlagsNoCFOF(); \ lf_var1b=load(op1); \ lf_var2b=op2&0x07; \ @@ -246,14 +238,6 @@ SETFLAGBIT(OF,(lf_resb & 1) ^ (lf_resb >> 7)); #define ROLW(op1,op2,load,save) \ - if (!(op2&0xf)) { \ - if (op2&0x10) { \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(CF,op1 & 1); \ - SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 15)); \ - } \ - break; \ - } \ FillFlagsNoCFOF(); \ lf_var1w=load(op1); \ lf_var2b=op2&0xf; \ @@ -264,7 +248,6 @@ SETFLAGBIT(OF,(lf_resw & 1) ^ (lf_resw >> 15)); #define ROLD(op1,op2,load,save) \ - if (!op2) break; \ FillFlagsNoCFOF(); \ lf_var1d=load(op1); \ lf_var2b=op2; \ @@ -276,14 +259,6 @@ #define RORB(op1,op2,load,save) \ - if (!(op2&0x7)) { \ - if (op2&0x18) { \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(CF,op1>>7); \ - SETFLAGBIT(OF,(op1>>7) ^ ((op1>>6) & 1)); \ - } \ - break; \ - } \ FillFlagsNoCFOF(); \ lf_var1b=load(op1); \ lf_var2b=op2&0x07; \ @@ -294,14 +269,6 @@ SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80); #define RORW(op1,op2,load,save) \ - if (!(op2&0xf)) { \ - if (op2&0x10) { \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(CF,op1>>15); \ - SETFLAGBIT(OF,(op1>>15) ^ ((op1>>14) & 1)); \ - } \ - break; \ - } \ FillFlagsNoCFOF(); \ lf_var1w=load(op1); \ lf_var2b=op2&0xf; \ @@ -312,7 +279,6 @@ SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000); #define RORD(op1,op2,load,save) \ - if (!op2) break; \ FillFlagsNoCFOF(); \ lf_var1d=load(op1); \ lf_var2b=op2; \ @@ -366,8 +332,6 @@ SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resd >> 31)); \ } - - #define RCRB(op1,op2,load,save) \ if (op2%9) { \ Bit8u cf=(Bit8u)FillFlags()&0x1; \ @@ -413,21 +377,18 @@ #define SHLB(op1,op2,load,save) \ - if (!op2) break; \ lf_var1b=load(op1);lf_var2b=op2; \ lf_resb=lf_var1b << lf_var2b; \ save(op1,lf_resb); \ lflags.type=t_SHLb; #define SHLW(op1,op2,load,save) \ - if (!op2) break; \ lf_var1w=load(op1);lf_var2b=op2 ; \ lf_resw=lf_var1w << lf_var2b; \ save(op1,lf_resw); \ lflags.type=t_SHLw; #define SHLD(op1,op2,load,save) \ - if (!op2) break; \ lf_var1d=load(op1);lf_var2b=op2; \ lf_resd=lf_var1d << lf_var2b; \ save(op1,lf_resd); \ @@ -435,21 +396,18 @@ #define SHRB(op1,op2,load,save) \ - if (!op2) break; \ lf_var1b=load(op1);lf_var2b=op2; \ lf_resb=lf_var1b >> lf_var2b; \ save(op1,lf_resb); \ lflags.type=t_SHRb; #define SHRW(op1,op2,load,save) \ - if (!op2) break; \ lf_var1w=load(op1);lf_var2b=op2; \ lf_resw=lf_var1w >> lf_var2b; \ save(op1,lf_resw); \ lflags.type=t_SHRw; #define SHRD(op1,op2,load,save) \ - if (!op2) break; \ lf_var1d=load(op1);lf_var2b=op2; \ lf_resd=lf_var1d >> lf_var2b; \ save(op1,lf_resd); \ @@ -457,7 +415,6 @@ #define SARB(op1,op2,load,save) \ - if (!op2) break; \ lf_var1b=load(op1);lf_var2b=op2; \ if (lf_var2b>8) lf_var2b=8; \ if (lf_var1b & 0x80) { \ @@ -470,7 +427,6 @@ lflags.type=t_SARb; #define SARW(op1,op2,load,save) \ - if (!op2) break; \ lf_var1w=load(op1);lf_var2b=op2; \ if (lf_var2b>16) lf_var2b=16; \ if (lf_var1w & 0x8000) { \ @@ -483,7 +439,6 @@ lflags.type=t_SARw; #define SARD(op1,op2,load,save) \ - if (!op2) break; \ lf_var2b=op2;lf_var1d=load(op1); \ if (lf_var1d & 0x80000000) { \ lf_resd=(lf_var1d >> lf_var2b)| \ @@ -836,6 +791,7 @@ if (rm >= 0xc0) { \ GetEArb; \ Bit8u val=blah & 0x1f; \ + if (!val) break; \ switch (which) { \ case 0x00:ROLB(*earb,val,LoadRb,SaveRb);break; \ case 0x01:RORB(*earb,val,LoadRb,SaveRb);break; \ @@ -849,6 +805,7 @@ } else { \ GetEAa; \ Bit8u val=blah & 0x1f; \ + if (!val) break; \ switch (which) { \ case 0x00:ROLB(eaa,val,LoadMb,SaveMb);break; \ case 0x01:RORB(eaa,val,LoadMb,SaveMb);break; \ @@ -870,6 +827,7 @@ if (rm >= 0xc0) { \ GetEArw; \ Bit8u val=blah & 0x1f; \ + if (!val) break; \ switch (which) { \ case 0x00:ROLW(*earw,val,LoadRw,SaveRw);break; \ case 0x01:RORW(*earw,val,LoadRw,SaveRw);break; \ @@ -883,6 +841,7 @@ } else { \ GetEAa; \ Bit8u val=blah & 0x1f; \ + if (!val) break; \ switch (which) { \ case 0x00:ROLW(eaa,val,LoadMw,SaveMw);break; \ case 0x01:RORW(eaa,val,LoadMw,SaveMw);break; \ @@ -903,6 +862,7 @@ if (rm >= 0xc0) { \ GetEArd; \ Bit8u val=blah & 0x1f; \ + if (!val) break; \ switch (which) { \ case 0x00:ROLD(*eard,val,LoadRd,SaveRd);break; \ case 0x01:RORD(*eard,val,LoadRd,SaveRd);break; \ @@ -916,6 +876,7 @@ } else { \ GetEAa; \ Bit8u val=blah & 0x1f; \ + if (!val) break; \ switch (which) { \ case 0x00:ROLD(eaa,val,LoadMd,SaveMd);break; \ case 0x01:RORD(eaa,val,LoadMd,SaveMd);break; \ From 766a63ac334e425255a5627dc95ee1bd5b419d9f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 8 Sep 2019 12:48:57 +0000 Subject: [PATCH 4130/4131] Add simple program that allows you to boot into a bios image for running cpu tester bios Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4257 --- src/dos/dos_programs.cpp | 57 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 621b9bfc..feba30e3 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1005,6 +1005,61 @@ static void LOADROM_ProgramStart(Program * * make) { *make=new LOADROM; } +class BIOS : public Program { +public: + void Run(void) { + if (!(cmd->FindCommand(1, temp_line))) { + WriteOut("Must specify BIOS file to load.\n"); + return; + } + + Bit8u drive; + char fullname[DOS_PATHLENGTH]; + localDrive* ldp = 0; + if (!DOS_MakeName((char *)temp_line.c_str(), fullname, &drive)) return; + + try { + /* try to read ROM file into buffer */ + ldp = dynamic_cast(Drives[drive]); + if (!ldp) return; + + FILE *tmpfile = ldp->GetSystemFilePtr(fullname, "rb"); + if (tmpfile == NULL) { + WriteOut("Can't open a file"); + return; + } + fseek(tmpfile, 0L, SEEK_END); + if (ftell(tmpfile) > 64 * 1024) { + WriteOut("BIOS File too large"); + fclose(tmpfile); + return; + } + fseek(tmpfile, 0L, SEEK_SET); + Bit8u buffer[64*1024]; + Bitu data_read = fread(buffer, 1, sizeof( buffer), tmpfile); + fclose(tmpfile); + + Bit32u rom_base = PhysMake(0xf000, 0); // override regular dosbox bios + /* write buffer into ROM */ + for (Bitu i = 0; i < data_read; i++) phys_writeb(rom_base + i, buffer[i]); + + //Start executing this bios + memset(&cpu_regs, 0, sizeof(cpu_regs)); + memset(&Segs, 0, sizeof(Segs)); + + + SegSet16(cs, 0xf000); + reg_eip = 0xfff0; + } + catch (...) { + return; + } + } +}; + +static void BIOS_ProgramStart(Program * * make) { + *make = new BIOS; +} // LOADFIX @@ -1767,7 +1822,9 @@ void DOS_SetupPrograms(void) { PROGRAMS_MakeFile("RESCAN.COM",RESCAN_ProgramStart); PROGRAMS_MakeFile("INTRO.COM",INTRO_ProgramStart); PROGRAMS_MakeFile("BOOT.COM",BOOT_ProgramStart); + PROGRAMS_MakeFile("BIOS.COM", BIOS_ProgramStart); PROGRAMS_MakeFile("LOADROM.COM", LOADROM_ProgramStart); PROGRAMS_MakeFile("IMGMOUNT.COM", IMGMOUNT_ProgramStart); PROGRAMS_MakeFile("KEYB.COM", KEYB_ProgramStart); + } From dda3b2a51f6dbc61d08be82dd47e18b784cb2158 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 10 Sep 2019 11:16:20 +0000 Subject: [PATCH 4131/4131] Rename bios tester to biostest and make it debug only to avoid people trying to load real bioses. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4258 --- src/dos/dos_programs.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index feba30e3..7e17f11e 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -1005,7 +1005,8 @@ static void LOADROM_ProgramStart(Program * * make) { *make=new LOADROM; } -class BIOS : public Program { +#if C_DEBUG +class BIOSTEST : public Program { public: void Run(void) { if (!(cmd->FindCommand(1, temp_line))) { @@ -1057,10 +1058,12 @@ public: } }; -static void BIOS_ProgramStart(Program * * make) { - *make = new BIOS; +static void BIOSTEST_ProgramStart(Program * * make) { + *make = new BIOSTEST; } +#endif + // LOADFIX class LOADFIX : public Program { @@ -1822,7 +1825,9 @@ void DOS_SetupPrograms(void) { PROGRAMS_MakeFile("RESCAN.COM",RESCAN_ProgramStart); PROGRAMS_MakeFile("INTRO.COM",INTRO_ProgramStart); PROGRAMS_MakeFile("BOOT.COM",BOOT_ProgramStart); - PROGRAMS_MakeFile("BIOS.COM", BIOS_ProgramStart); +#if C_DEBUG + PROGRAMS_MakeFile("BIOSTEST.COM", BIOSTEST_ProgramStart); +#endif PROGRAMS_MakeFile("LOADROM.COM", LOADROM_ProgramStart); PROGRAMS_MakeFile("IMGMOUNT.COM", IMGMOUNT_ProgramStart); PROGRAMS_MakeFile("KEYB.COM", KEYB_ProgramStart);